[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{yml,yaml}]\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n\n*.blade.php diff=html\n*.css diff=css\n*.html diff=html\n*.md diff=markdown\n*.php diff=php\n\n*.stub linguist-language=php\n*.neon.dist linguist-language=neon\n\n/.github export-ignore\n/bin export-ignore\n/tests export-ignore\n/types export-ignore\n.editorconfig export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n.styleci.yml export-ignore\nCHANGELOG.md export-ignore\nCODE_OF_CONDUCT.md export-ignore\nCONTRIBUTING.md export-ignore\ndocker-compose.yml export-ignore\nphpstan.src.neon.dist export-ignore\nphpstan.types.neon.dist export-ignore\nphpunit.xml.dist export-ignore\nRELEASE.md export-ignore\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nThe Laravel Code of Conduct can be found in the [Laravel documentation](https://laravel.com/docs/contributions#code-of-conduct).\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Laravel Contribution Guide\n\nThe Laravel contributing guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_report.yml",
    "content": "name: Bug Report\ndescription: \"Report something that's broken.\"\nbody:\n  - type: markdown\n    attributes:\n      value: \"Please read [our full contribution guide](https://laravel.com/docs/contributions#bug-reports) before submitting bug reports. If you notice improper DocBlock, PHPStan, or IDE warnings while using Laravel, do not create a GitHub issue. Instead, please submit a pull request to fix the problem.\"\n  - type: input\n    attributes:\n      label: Laravel Version\n      description: Provide the Laravel version that you are using. [Please ensure it is still supported.](https://laravel.com/docs/releases#support-policy)\n      placeholder: 10.4.1\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: PHP Version\n      description: Provide the PHP version that you are using.\n      placeholder: 8.1.4\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: Database Driver & Version\n      description: If applicable, provide the database driver and version you are using.\n      placeholder: \"MySQL 8.0.31 for macOS 13.0 on arm64 (Homebrew)\"\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Description\n      description: Provide a detailed description of the issue you are facing.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Steps To Reproduce\n      description: Provide detailed steps to reproduce your issue. If necessary, please provide a GitHub repository to demonstrate your issue using `laravel new bug-report --github=\"--public\"`.\n    validations:\n      required: true\n      \n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Feature request\n    url: https://github.com/laravel/framework/discussions\n    about: 'For ideas or feature requests, start a new discussion'\n  - name: Support Questions & Other\n    url: https://laravel.com/docs/contributions#support-questions\n    about: 'This repository is only for reporting bugs. If you have a question or need help using the library, click:'\n  - name: Documentation issue\n    url: https://github.com/laravel/docs\n    about: For documentation issues, open a pull request at the laravel/docs repository\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nPlease only send a pull request to branches that are currently supported: https://laravel.com/docs/releases#support-policy \n\nIf you are unsure which branch your pull request should be sent to, please read: https://laravel.com/docs/contributions#which-branch\n\nPull requests without a descriptive title, thorough description, or tests will be closed.\n\nIn addition, please describe the benefit to end users; the reasons it does not break any existing features; how it makes building web applications easier, etc.\n-->\n"
  },
  {
    "path": ".github/SECURITY.md",
    "content": "# Security Policy\n\n**PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).**\n\n## Supported Versions\n\nPlease see [our support policy](https://laravel.com/docs/releases#support-policy) for information on supported versions for security releases.\n\n## Reporting a Vulnerability\n\nIf you discover a security vulnerability within Laravel, please send an email to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.\n\n### Public PGP Key\n\n```\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmDMEaS69PhYJKwYBBAHaRw8BAQdA3/xgVRmWBa1Yq0k6JuQ2Jvkc2ZawodehIGGF\nvJAgdAa0LExhcmF2ZWwgU2VjdXJpdHkgVGVhbSA8c2VjdXJpdHlAbGFyYXZlbC5j\nb20+iJMEExYKADsWIQS2WnBWqu9MGPeidwe5jM+KJWQ6/wUCaS69PgIbAwULCQgH\nAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRC5jM+KJWQ6/+VPAP0e//4i0lKqrNXR\nLdW/MXedoZCvIwao/lnHCmm383ay8wEAyspAIS96viKhaKZgBJBe+vEKTpWSsM51\nLKK18SphzQC4OARpLr0+EgorBgEEAZdVAQUBAQdARmUVYbaF4YrQQe3GsjIXDmL0\n3ziw2TMjy6ZP/MHW7SsDAQgHiHgEGBYKACAWIQS2WnBWqu9MGPeidwe5jM+KJWQ6\n/wUCaS69PgIbDAAKCRC5jM+KJWQ6/3i2AP9ECN03ww6FmgMEJpiQFRm700MPIPTZ\nPi2DQHzZcCjbDQEA09HhWaJoKu2GkKAChJ0GXI5hPcSw1avMP6fFL+iA/Qk=\n=e7l8\n-----END PGP PUBLIC KEY BLOCK-----\n```\n"
  },
  {
    "path": ".github/SUPPORT.md",
    "content": "# Support Questions\n\nThe Laravel support guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions#support-questions).\n"
  },
  {
    "path": ".github/workflows/databases-nightly.yml",
    "content": "name: databases-nightly\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n\njobs:\n  mysql_9:\n    runs-on: ubuntu-24.04\n\n    services:\n      mysql:\n        image: mysql:9\n        env:\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n          MYSQL_DATABASE: laravel\n        ports:\n          - 3306:3306\n        options: --health-cmd=\"mysqladmin ping\" --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: MySQL 9\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: mysql\n\n  mariadb:\n    runs-on: ubuntu-24.04\n    continue-on-error: true\n\n    services:\n      mariadb:\n        image: quay.io/mariadb-foundation/mariadb-devel:verylatest\n        env:\n          MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes\n          MARIADB_DATABASE: laravel\n        ports:\n          - 3306:3306\n        options: --health-cmd=\"healthcheck.sh --connect --innodb_initialized\" --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: MariaDB Very Latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: mariadb\n"
  },
  {
    "path": ".github/workflows/databases.yml",
    "content": "name: databases\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  pull_request:\n\njobs:\n  mysql_57:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      mysql:\n        image: mysql:5.7\n        env:\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n          MYSQL_DATABASE: laravel\n        ports:\n          - 3306:3306\n        options: --health-cmd=\"mysqladmin ping\" --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: MySQL 5.7\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: mysql\n          DB_COLLATION: utf8mb4_unicode_ci\n\n  mysql_8:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      mysql:\n        image: mysql:8\n        env:\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n          MYSQL_DATABASE: laravel\n        ports:\n          - 3306:3306\n        options: --health-cmd=\"mysqladmin ping\" --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: MySQL 8\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: mysql\n\n  mariadb:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      mariadb:\n        image: mariadb:10\n        env:\n          MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes\n          MARIADB_DATABASE: laravel\n        ports:\n          - 3306:3306\n        options: --health-cmd=\"healthcheck.sh --connect --innodb_initialized\" --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: MariaDB 10\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: mariadb\n\n  pgsql_18:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      postgresql:\n        image: postgres:18\n        env:\n          POSTGRES_DB: laravel\n          POSTGRES_USER: forge\n          POSTGRES_PASSWORD: password\n        ports:\n          - 5432:5432\n        options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: PostgreSQL 18\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_pgsql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: pgsql\n          DB_USERNAME: forge\n          DB_PASSWORD: password\n\n  pgsql_14:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      postgresql:\n        image: postgres:14\n        env:\n          POSTGRES_DB: laravel\n          POSTGRES_USER: forge\n          POSTGRES_PASSWORD: password\n        ports:\n          - 5432:5432\n        options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: PostgreSQL 14\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_pgsql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: pgsql\n          DB_USERNAME: forge\n          DB_PASSWORD: password\n\n  pgsql_10:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    services:\n      postgresql:\n        image: postgres:10\n        env:\n          POSTGRES_DB: laravel\n          POSTGRES_USER: forge\n          POSTGRES_PASSWORD: password\n        ports:\n          - 5432:5432\n        options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3\n\n    strategy:\n      fail-fast: true\n\n    name: PostgreSQL 10\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_pgsql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: pgsql\n          DB_USERNAME: forge\n          DB_PASSWORD: password\n\n  mssql_2019:\n    runs-on: ubuntu-22.04\n    timeout-minutes: 5\n\n    services:\n      sqlsrv:\n        image: mcr.microsoft.com/mssql/server:2019-latest\n        env:\n          ACCEPT_EULA: Y\n          SA_PASSWORD: Forge123\n        ports:\n          - 1433:1433\n\n    strategy:\n      fail-fast: true\n\n    name: SQL Server 2019\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, sqlsrv, pdo, pdo_sqlsrv, odbc, pdo_odbc, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: sqlsrv\n          DB_DATABASE: master\n          DB_USERNAME: SA\n          DB_PASSWORD: Forge123\n\n  mssql_2017:\n    runs-on: ubuntu-22.04\n    timeout-minutes: 5\n\n    services:\n      sqlsrv:\n        image: mcr.microsoft.com/mssql/server:2017-latest\n        env:\n          ACCEPT_EULA: Y\n          SA_PASSWORD: Forge123\n        ports:\n          - 1433:1433\n\n    strategy:\n      fail-fast: true\n\n    name: SQL Server 2017\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, sqlsrv, pdo, pdo_sqlsrv, odbc, pdo_odbc, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database\n        env:\n          DB_CONNECTION: sqlsrv\n          DB_DATABASE: master\n          DB_USERNAME: SA\n          DB_PASSWORD: Forge123\n\n  sqlite:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 5\n\n    strategy:\n      fail-fast: true\n\n    name: SQLite\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, sqlsrv, pdo, pdo_sqlsrv, odbc, pdo_odbc, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Setup SQLite Database\n        run: php vendor/bin/testbench package:create-sqlite-db\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Database/Sqlite\n        env:\n          DB_CONNECTION: sqlite\n"
  },
  {
    "path": ".github/workflows/facades.yml",
    "content": "name: facades\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  workflow_dispatch:\n\npermissions:\n  contents: write\n\njobs:\n  update:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n\n    name: Facade DocBlocks\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: |\n            composer config repositories.facade-documenter vcs git@github.com:laravel/facade-documenter.git\n            composer require --dev laravel/facade-documenter:dev-main --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Update facade docblocks\n        run: |\n          php -f vendor/bin/facade.php -- \\\n            Illuminate\\\\Support\\\\Facades\\\\App \\\n            Illuminate\\\\Support\\\\Facades\\\\Artisan \\\n            Illuminate\\\\Support\\\\Facades\\\\Auth \\\n            Illuminate\\\\Support\\\\Facades\\\\Blade \\\n            Illuminate\\\\Support\\\\Facades\\\\Broadcast \\\n            Illuminate\\\\Support\\\\Facades\\\\Bus \\\n            Illuminate\\\\Support\\\\Facades\\\\Cache \\\n            Illuminate\\\\Support\\\\Facades\\\\Concurrency \\\n            Illuminate\\\\Support\\\\Facades\\\\Config \\\n            Illuminate\\\\Support\\\\Facades\\\\Context \\\n            Illuminate\\\\Support\\\\Facades\\\\Cookie \\\n            Illuminate\\\\Support\\\\Facades\\\\Crypt \\\n            Illuminate\\\\Support\\\\Facades\\\\Date \\\n            Illuminate\\\\Support\\\\Facades\\\\DB \\\n            Illuminate\\\\Support\\\\Facades\\\\Event \\\n            Illuminate\\\\Support\\\\Facades\\\\Exceptions \\\n            Illuminate\\\\Support\\\\Facades\\\\File \\\n            Illuminate\\\\Support\\\\Facades\\\\Gate \\\n            Illuminate\\\\Support\\\\Facades\\\\Hash \\\n            Illuminate\\\\Support\\\\Facades\\\\Http \\\n            Illuminate\\\\Support\\\\Facades\\\\Lang \\\n            Illuminate\\\\Support\\\\Facades\\\\Log \\\n            Illuminate\\\\Support\\\\Facades\\\\Mail \\\n            Illuminate\\\\Support\\\\Facades\\\\MaintenanceMode \\\n            Illuminate\\\\Support\\\\Facades\\\\Notification \\\n            Illuminate\\\\Support\\\\Facades\\\\ParallelTesting \\\n            Illuminate\\\\Support\\\\Facades\\\\Password \\\n            Illuminate\\\\Support\\\\Facades\\\\Pipeline \\\n            Illuminate\\\\Support\\\\Facades\\\\Process \\\n            Illuminate\\\\Support\\\\Facades\\\\Queue \\\n            Illuminate\\\\Support\\\\Facades\\\\RateLimiter \\\n            Illuminate\\\\Support\\\\Facades\\\\Redirect \\\n            Illuminate\\\\Support\\\\Facades\\\\Redis \\\n            Illuminate\\\\Support\\\\Facades\\\\Request \\\n            Illuminate\\\\Support\\\\Facades\\\\Response \\\n            Illuminate\\\\Support\\\\Facades\\\\Route \\\n            Illuminate\\\\Support\\\\Facades\\\\Schedule \\\n            Illuminate\\\\Support\\\\Facades\\\\Schema \\\n            Illuminate\\\\Support\\\\Facades\\\\Session \\\n            Illuminate\\\\Support\\\\Facades\\\\Storage \\\n            Illuminate\\\\Support\\\\Facades\\\\URL \\\n            Illuminate\\\\Support\\\\Facades\\\\Validator \\\n            Illuminate\\\\Support\\\\Facades\\\\View \\\n            Illuminate\\\\Support\\\\Facades\\\\Vite\n\n      - name: Commit facade docblocks\n        uses: stefanzweifel/git-auto-commit-action@v7\n        with:\n          commit_message: Update facade docblocks\n          file_pattern: src/\n"
  },
  {
    "path": ".github/workflows/issues.yml",
    "content": "name: issues\n\non:\n  issues:\n    types: [labeled]\n\npermissions:\n  issues: write\n\njobs:\n  help-wanted:\n    uses: laravel/.github/.github/workflows/issues.yml@main\n"
  },
  {
    "path": ".github/workflows/pull-requests.yml",
    "content": "name: pull requests\n\non:\n  pull_request_target:\n    types: [opened]\n\npermissions:\n  pull-requests: write\n\njobs:\n  pull-requests:\n    uses: laravel/.github/.github/workflows/pull-requests.yml@main\n"
  },
  {
    "path": ".github/workflows/queues.yml",
    "content": "name: queues\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  pull_request:\n\njobs:\n  sync:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n\n    name: Sync Driver\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Queue\n        env:\n          QUEUE_CONNECTION: sync\n\n  database:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n\n    name: Database Driver\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Setup SQLite Database\n        run: php vendor/bin/testbench package:create-sqlite-db\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Queue\n        env:\n          DB_CONNECTION: sqlite\n          QUEUE_CONNECTION: database\n\n  beanstalkd:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n      matrix:\n        include:\n          - php: 8.3\n            pheanstalk: 7\n          - php: 8.4\n            pheanstalk: 8\n\n    name: Beanstalkd Driver (pda/pheanstalk:^${{ matrix.pheanstalk }})\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Download & Extract beanstalkd\n        run: curl -L https://github.com/beanstalkd/beanstalkd/archive/refs/tags/v1.13.tar.gz | tar xz\n\n      - name: Make beanstalkd\n        run: make\n        working-directory: beanstalkd-1.13\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress --with=\"pda/pheanstalk:^${{ matrix.pheanstalk }}\"\n\n      - name: Daemonize beanstalkd\n        run: ./beanstalkd-1.13/beanstalkd &\n\n      - name: Execute tests\n        run: vendor/bin/phpunit tests/Integration/Queue\n        env:\n          QUEUE_CONNECTION: beanstalkd\n"
  },
  {
    "path": ".github/workflows/redis.yml",
    "content": "name: Redis and Redis Cluster\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  pull_request:\n\njobs:\n  redis:\n    runs-on: ubuntu-24.04\n\n    services:\n      redis:\n        image: redis:7.0\n        ports:\n          - 6379:6379\n        options: --entrypoint redis-server\n\n    strategy:\n      fail-fast: true\n      matrix:\n        client: ['phpredis', 'predis']\n\n    name: Redis (${{ matrix.client}}) Driver\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute Cache tests\n        run: vendor/bin/phpunit tests/Integration/Cache\n        env:\n          CACHE_STORE: redis\n          REDIS_CACHE_CONNECTION: cache\n          REDIS_CACHE_LOCK_CONNECTION: cache\n          REDIS_CLIENT: ${{ matrix.client }}\n\n      - name: Execute Queue tests\n        run: vendor/bin/phpunit tests/Integration/Queue\n        env:\n          REDIS_CLIENT: ${{ matrix.client }}\n          QUEUE_CONNECTION: redis\n\n  redis-cluster:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n      matrix:\n        client: ['phpredis', 'predis']\n\n    name: Redis Cluster (${{ matrix.client}}) Driver\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Create Redis Cluster\n        run: |\n          sudo apt update\n          sudo apt-get install -y --fix-missing redis-server\n          sudo service redis-server stop\n          redis-server --daemonize yes --port 7000 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7000.conf\n          redis-server --daemonize yes --port 7001 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7001.conf\n          redis-server --daemonize yes --port 7002 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7002.conf\n          redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-replicas 0 --cluster-yes\n\n      - name: Check Redis Cluster is ready\n        uses: nick-fields/retry@v3\n        with:\n          timeout_seconds: 5\n          max_attempts: 5\n          retry_wait_seconds: 5\n          retry_on: error\n          command: |\n            redis-cli -c -h 127.0.0.1 -p 7000 cluster info | grep \"cluster_state:ok\"\n            redis-cli -c -h 127.0.0.1 -p 7001 cluster info | grep \"cluster_state:ok\"\n            redis-cli -c -h 127.0.0.1 -p 7002 cluster info | grep \"cluster_state:ok\"\n\n      - name: Execute Cache tests\n        run: vendor/bin/phpunit tests/Integration/Cache\n        env:\n          CACHE_STORE: redis\n          REDIS_CACHE_CONNECTION: default\n          REDIS_CACHE_LOCK_CONNECTION: default\n          REDIS_CLIENT: ${{ matrix.client }}\n          REDIS_CLUSTER_HOSTS_AND_PORTS: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002\n\n      - name: Execute Queue Tests\n        run: vendor/bin/phpunit tests/Integration/Queue\n        env:\n          REDIS_CLIENT: ${{ matrix.client }}\n          REDIS_CLUSTER_HOSTS_AND_PORTS: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002\n          REDIS_QUEUE: '{default}'\n          QUEUE_CONNECTION: redis\n\n"
  },
  {
    "path": ".github/workflows/releases.yml",
    "content": "name: manual release\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: 'Version to release'\n        required: true\n\npermissions:\n  contents: write\n\njobs:\n  release:\n    runs-on: ubuntu-24.04\n\n    name: Release ${{ inputs.version }}\n\n    outputs:\n      version: ${{ steps.version.outputs.version }}\n      notes: ${{ steps.cleaned-notes.outputs.notes }}\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n\n      - name: Remove optional \"v\" prefix\n        id: version\n        run: |\n          echo \"version=${VERSION#v}\" >> \"$GITHUB_OUTPUT\"\n        env:\n          VERSION: ${{ inputs.version }}\n\n      - name: Check if branch and version match\n        id: guard\n        run: |\n          MAJOR_VERSION=\"${NUMERIC_VERSION%%.*}\"\n          BRANCH_MAJOR_VERSION=\"${BRANCH%%.*}\"\n\n          if [ \"$MAJOR_VERSION\" != \"$BRANCH_MAJOR_VERSION\" ]; then\n            echo \"Mismatched versions! Aborting.\"\n            VERSION_MISMATCH='true';\n          else\n            echo \"Versions match! Proceeding.\"\n            VERSION_MISMATCH='false';\n          fi\n\n          echo \"VERSION_MISMATCH=$(echo $VERSION_MISMATCH)\" >> \"$GITHUB_OUTPUT\";\n        env:\n          BRANCH: ${{ github.ref_name }}\n          NUMERIC_VERSION: ${{ steps.version.outputs.version }}\n\n      - name: Fail if branch and release tag do not match\n        if: ${{ steps.guard.outputs.VERSION_MISMATCH == 'true' }}\n        uses: actions/github-script@v7\n        with:\n          script: |\n              core.setFailed('Workflow failed. Release version does not match with selected target branch. Did you select the correct branch?')\n\n      - name: Update Application.php version\n        run: sed -i \"s/const VERSION = '.*';/const VERSION = '${{ steps.version.outputs.version }}';/g\" src/Illuminate/Foundation/Application.php\n\n      - name: Commit version change\n        uses: stefanzweifel/git-auto-commit-action@v7\n        with:\n          commit_message: \"Update version to v${{ steps.version.outputs.version }}\"\n\n      - name: SSH into splitter server\n        uses: appleboy/ssh-action@master\n        with:\n          host: 104.248.56.26\n          username: forge\n          key: ${{ secrets.SSH_PRIVATE_KEY_SPLITTER }}\n          script: |\n            cd laravel-${{ github.ref_name }}\n            git pull origin ${{ github.ref_name }}\n            bash ./bin/release.sh v${{ steps.version.outputs.version }}\n          script_stop: true\n\n      - name: Generate release notes\n        id: generated-notes\n        uses: RedCrafter07/release-notes-action@main\n        with:\n          tag-name: v${{ steps.version.outputs.version }}\n          token: ${{ secrets.GITHUB_TOKEN }}\n          branch: ${{ github.ref_name }}\n\n      - name: Cleanup release notes\n        id: cleaned-notes\n        run: |\n          START_FROM=$(echo -n \"$RELEASE_NOTES\" | awk \"/What's Changed/{ print NR; exit }\" -)\n          DROP_FROM_CONTRIBUTORS=$(echo -n \"$RELEASE_NOTES\" | awk \"/New Contributors/{ print NR; exit }\" -)\n          DROP_FROM_FULL_CHANGELOG=$(echo -n \"$RELEASE_NOTES\" | awk \"/Full Changelog/{ print NR; exit }\" -)\n\n          # Drop everything starting from \"Full Changelog\"\n          if [ ! -z \"$DROP_FROM_FULL_CHANGELOG\" ]; then\n              RELEASE_NOTES=$(echo -n \"$RELEASE_NOTES\" | sed \"${DROP_FROM_FULL_CHANGELOG},$ d\")\n          fi\n\n          # Drop everything starting from \"New Contributors\"\n          if [ ! -z \"$DROP_FROM_CONTRIBUTORS\" ]; then\n              RELEASE_NOTES=$(echo -n \"$RELEASE_NOTES\" | sed \"${DROP_FROM_CONTRIBUTORS},$ d\")\n          fi\n\n          # Drop the line \"What's Changed\"\n          if [ ! -z \"$START_FROM\" ]; then\n              RELEASE_NOTES=$(echo -n \"$RELEASE_NOTES\" | sed \"${START_FROM}d\")\n          fi\n\n          {\n            echo 'notes<<EOF'\n            echo \"$RELEASE_NOTES\"\n            echo EOF\n          } >> \"$GITHUB_OUTPUT\";\n        env:\n          RELEASE_NOTES: ${{ steps.generated-notes.outputs.release-notes }}\n\n      - name: Create release\n        uses: softprops/action-gh-release@v2\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          tag_name: v${{ steps.version.outputs.version }}\n          name: v${{ steps.version.outputs.version }}\n          body: ${{ steps.cleaned-notes.outputs.notes }}\n          target_commitish: ${{ github.ref_name }}\n          make_latest: \"${{ github.ref_name == github.event.repository.default_branch }}\"\n\n  update-changelog:\n    needs: release\n\n    name: Update changelog\n\n    uses: laravel/.github/.github/workflows/update-changelog.yml@main\n    with:\n      branch: ${{ github.ref_name }}\n      version: \"v${{ needs.release.outputs.version }}\"\n      notes: ${{ needs.release.outputs.notes }}\n"
  },
  {
    "path": ".github/workflows/static-analysis.yml",
    "content": "name: static analysis\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  pull_request:\n\njobs:\n  types:\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: true\n      matrix:\n        directory: [src, types]\n\n    name: ${{ matrix.directory == 'src' && 'Source Code' || 'Types' }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: 8.3\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress\n\n      - name: Execute type checking\n        run: vendor/bin/phpstan --configuration=\"phpstan.${{ matrix.directory }}.neon.dist\" --no-progress\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: tests\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n  pull_request:\n  schedule:\n    - cron: '0 0 * * *'\n\njobs:\n  linux_tests:\n    runs-on: ubuntu-24.04\n\n    services:\n      memcached:\n        image: memcached:1.6-alpine\n        ports:\n          - 11211:11211\n      mysql:\n        image: mysql:8\n        env:\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n          MYSQL_DATABASE: forge\n        ports:\n          - 3306\n        options: --health-cmd=\"mysqladmin ping\" --health-interval=10s --health-timeout=5s --health-retries=3\n      redis:\n        image: redis:7.0\n        ports:\n          - 6379:6379\n        options: --entrypoint redis-server\n      dynamodb:\n        image: amazon/dynamodb-local:2.0.0\n        ports:\n          - 8888:8000\n\n    strategy:\n      fail-fast: true\n      matrix:\n        php: [8.3, 8.4, 8.5]\n        phpunit: ['11.5.50', '12.5.8', '13.0.3']\n        stability: [prefer-lowest, prefer-stable]\n        exclude:\n          - php: 8.3\n            phpunit: '13.0.3'\n\n    name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - ${{ matrix.stability }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, redis, igbinary, msgpack, memcached, gmp, :php-psr\n          ini-values: error_reporting=E_ALL\n          tools: composer:v2\n          coverage: none\n        env:\n          REDIS_CONFIGURE_OPTS: --enable-redis --enable-redis-igbinary --enable-redis-msgpack --enable-redis-lzf --with-liblzf --enable-redis-zstd --with-libzstd --enable-redis-lz4 --with-liblz4\n          REDIS_LIBS: liblz4-dev, liblzf-dev, libzstd-dev\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --with=\"phpunit/phpunit:~${{ matrix.phpunit }}\"\n\n      - name: Execute tests\n        run: vendor/bin/phpunit --display-deprecation ${{ matrix.stability == 'prefer-stable' && '--fail-on-deprecation' || '' }} --no-coverage\n        env:\n          DB_PORT: ${{ job.services.mysql.ports[3306] }}\n          DB_USERNAME: root\n          DYNAMODB_CACHE_TABLE: laravel_dynamodb_test\n          DYNAMODB_ENDPOINT: \"http://localhost:8888\"\n          AWS_ACCESS_KEY_ID: randomKey\n          AWS_SECRET_ACCESS_KEY: randomSecret\n\n      - name: Store artifacts\n        uses: actions/upload-artifact@v6\n        with:\n          name: linux-logs-${{ matrix.php }}-${{ matrix.phpunit }}-${{ matrix.stability }}\n          path: |\n            vendor/orchestra/testbench-core/laravel/storage/logs\n            !vendor/**/.gitignore\n\n  windows_tests:\n    runs-on: windows-2022\n\n    strategy:\n      fail-fast: true\n      matrix:\n        php: [8.3, 8.4, 8.5]\n        phpunit: ['11.5.50', '12.5.8', '13.0.3']\n        stability: [prefer-lowest, prefer-stable]\n        exclude:\n          - php: 8.3\n            phpunit: '13.0.3'\n\n    name: PHP ${{ matrix.php }} - PHPUnit ${{ matrix.phpunit }} - ${{ matrix.stability }} - Windows\n\n    steps:\n      - name: Set git to use LF\n        run: |\n          git config --global core.autocrlf false\n          git config --global core.eol lf\n\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, gd, pdo_mysql, fileinfo, ftp, redis, memcached, gmp, intl, :php-psr\n          tools: composer:v2\n          coverage: none\n\n      - name: Set Framework version\n        run: composer config version \"13.x-dev\"\n\n      - name: Install dependencies\n        uses: nick-fields/retry@v3\n        with:\n          timeout_minutes: 5\n          max_attempts: 5\n          command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --with=\"phpunit/phpunit:~${{ matrix.phpunit }}\"\n\n      - name: Execute tests\n        run: vendor/bin/phpunit --no-coverage\n        env:\n          AWS_ACCESS_KEY_ID: random_key\n          AWS_SECRET_ACCESS_KEY: random_secret\n\n      - name: Store artifacts\n        uses: actions/upload-artifact@v6\n        with:\n          name: windows-logs-${{ matrix.php }}-${{ matrix.phpunit }}-${{ matrix.stability }}\n          path: |\n            vendor/orchestra/testbench-core/laravel/storage/logs\n            !vendor/**/.gitignore\n"
  },
  {
    "path": ".github/workflows/update-assets.yml",
    "content": "name: 'update assets'\n\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n    paths:\n      - 'src/Illuminate/Foundation/resources/exceptions/renderer/**'\n      - '!src/Illuminate/Foundation/resources/exceptions/renderer/dist/**'\n  pull_request:\n    paths:\n      - 'src/Illuminate/Foundation/resources/exceptions/renderer/**'\n      - '!src/Illuminate/Foundation/resources/exceptions/renderer/dist/**'\n\npermissions:\n  contents: write\n\njobs:\n  update:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Code\n        uses: actions/checkout@v6\n\n      - uses: actions/setup-node@v6\n        with:\n          node-version: 22\n\n      - name: Update Exception Renderer Assets\n        run: |\n          npm ci --prefix \"./src/Illuminate/Foundation/resources/exceptions/renderer\"\n          npm run build --prefix \"./src/Illuminate/Foundation/resources/exceptions/renderer\"\n\n      - name: Commit Compiled Files\n        uses: stefanzweifel/git-auto-commit-action@v7\n        with:\n          commit_message: Update Assets\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.phpunit.result.cache\n/tests/*.coverage\n/tests/**/*.coverage\n/.fleet\n/.idea\n/.phpunit.cache\n/phpunit.xml\n/.vscode\n/vendor\ncomposer.phar\ncomposer.lock\nThumbs.db\n"
  },
  {
    "path": ".styleci.yml",
    "content": "php:\n  preset: laravel\n  version: 8.2\n  finder:\n    not-name:\n      - bad-syntax-strategy.php\njs:\n  finder:\n    exclude:\n      - src/Illuminate/Foundation/resources/exceptions/renderer/dist\n    not-name:\n      - webpack.mix.js\ncss:\n  finder:\n    exclude:\n      - src/Illuminate/Foundation/resources/exceptions/renderer/dist\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Release Notes for 12.x\n\n## [Unreleased](https://github.com/laravel/framework/compare/v13.1.1...13.x)\n\n## [v13.1.1](https://github.com/laravel/framework/compare/v13.1.0...v13.1.1) - 2026-03-18\n\n* Break queue dependency by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/59275\n\n## [v13.1.0](https://github.com/laravel/framework/compare/v13.0.0...v13.1.0) - 2026-03-18\n\n* [12.x] Correct truncate exceptions at by [@bretto36](https://github.com/bretto36) in https://github.com/laravel/framework/pull/59239\n* [13.x] Remove useless \\Mockery::close() by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/59253\n* Fix: Batch::add() wipes queue assignment on first job in array chains by [@ProjektGopher](https://github.com/ProjektGopher) in https://github.com/laravel/framework/pull/59233\n* Improvements for asserting HTML in text by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/59161\n* [13.x] Use Carbon::now() instead of now() helper by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/59252\n* [13.x] Fix null broadcaster deprecation warning in PHP 8.5 by [@mortenscheel](https://github.com/mortenscheel) in https://github.com/laravel/framework/pull/59269\n* [12.x] Fix float pluralization in trans_choice() by [@JulianGlueck](https://github.com/JulianGlueck) in https://github.com/laravel/framework/pull/59268\n* [12.x] Fix tests on PHP 8.5 by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59251\n* [13.x] Add toString to Uri by [@dwightwatson](https://github.com/dwightwatson) in https://github.com/laravel/framework/pull/59259\n\n## [v13.0.0](https://github.com/laravel/framework/compare/v12.54.1...v13.0.0) - 2026-03-17\n\n* Revert \"[12.x] Query builder PDO fetch modes\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/54709\n* [13.x] Prepare branch alias for Laravel 13 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54701\n* [12.x] Query builder PDO fetch modes + columns fix by [@bert-w](https://github.com/bert-w) in https://github.com/laravel/framework/pull/54734\n* [13.x] Fix Tests/CI environments by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54760\n* [13.x] Requires PHP 8.3 as minimum version by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54763\n* [13.x] Add missing parameters to `Response` methods `throw()` and `throwIf()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54798\n* [13.x] Fix scope removal in nested where conditions by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/54816\n* [13.x] Remove function existence checks by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/54876\n* [13.x] Removed unneeded default argument by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/54900\n* [13.x] Fix unresolved merge conflict in Concurrency composer.json by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/55233\n* [13.x] Fixes merge conflict by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55294\n* [13.x] Error exit code for clear command by [@mbardelmeijer](https://github.com/mbardelmeijer) in https://github.com/laravel/framework/pull/55355\n* [13.x] Add #[\\Override] to the BatchFake class methods by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55358\n* [13.x] PDO Fetch modes by [@bert-w](https://github.com/bert-w) in https://github.com/laravel/framework/pull/55394\n* Allow Listeners to dynamically specify deleteWhenMissingModels by [@L3o-pold](https://github.com/L3o-pold) in https://github.com/laravel/framework/pull/55508\n* [13.x] Do not allow new model instances to be created during boot by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/55685\n* Fix typo in `Blueprint`: `datetime` => `dateTime` by [@TheJoeSchr](https://github.com/TheJoeSchr) in https://github.com/laravel/framework/pull/55859\n* Feature: add support straight join in mysql by [@jferdi24](https://github.com/jferdi24) in https://github.com/laravel/framework/pull/55786\n* [13.x] Register subdomain routes before routes that are not linked to a domain by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55921\n* [13.x] Supports Symfony 7.4 & 8.0 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56029\n* [13.x] Change to hyphenate prefixes by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/framework/pull/56172\n* [13.x] Use exception object in JobAttempted event by [@bert-w](https://github.com/bert-w) in https://github.com/laravel/framework/pull/56148\n* [13.x] remove superfluous element by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56303\n* Add eventStream signature to ResponseFactory contract by [@csfh](https://github.com/csfh) in https://github.com/laravel/framework/pull/56306\n* fix: align ResponseFactory::eventStream signature with interface by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/56484\n* [13.x] `Cache::touch()` & `Store::touch()` for TTL Extension by [@yitzwillroth](https://github.com/yitzwillroth) in https://github.com/laravel/framework/pull/55954\n* [13.x] Make QueueBusy event consistent with other queue events by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56673\n* [13.x] use clearer pagination view names by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56307\n* [13.x] Update `countBy` docblock in `Enumerable` interface to allow for enum callback by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56897\n* [13.x] Generate plural morph pivot table name by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/56832\n* [13.x] Resolve Symfony Console `add()` method deprecation by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/56488\n* [13.x] Add command method to contract by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/56978\n* Refactor: replace strpos check with str_contains for clarity by [@arshidkv12](https://github.com/arshidkv12) in https://github.com/laravel/framework/pull/57042\n* Remove unnecessary parameters by [@arshidkv12](https://github.com/arshidkv12) in https://github.com/laravel/framework/pull/57047\n* [README.md] change laravel bootcamp to laravel learn by [@MoZayedSaeid](https://github.com/MoZayedSaeid) in https://github.com/laravel/framework/pull/57176\n* [13.x] Resolve issues with tests by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57258\n* [13.x] Bind manager instances to custom driver closures by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57173\n* [13.x] Compile full DELETE with JOIN including ORDER BY and LIMIT in MySQL grammar by [@tegos](https://github.com/tegos) in https://github.com/laravel/framework/pull/57196\n* [13.x] Flush `Str` factories when tearing down test case by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57296\n* [13.x] Update reset password notification subject by [@ganyicz](https://github.com/ganyicz) in https://github.com/laravel/framework/pull/57882\n* [13.x] Update verification email subject capitalization by [@ganyicz](https://github.com/ganyicz) in https://github.com/laravel/framework/pull/57884\n* [13.x] Simplify preg_replace_array callback by removing unnecessary foreach loop by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57924\n* [13.x] Fix changes from Laravel 12 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57919\n* [13.x] Default `PendingRequest@pool()` to use 2 for concurrency by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57972\n* [13.x] Copy `Symfony\\Component\\HttpFoundation\\Request::get()` functionality to avoid breaking changes. by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58081\n* [13.x] Defer registering schedule registered using  `ApplicationBuilder::withScheduling()` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58160\n* [13.x] Return data object from `ModelInspector` to make `show:model` more flexible by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58230\n* [13.x] Add ability to default queue by class type by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58094\n* [13.x] Add reason to WorkerStopping event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58341\n* [13.x] Add starting to Monitor Contract by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58399\n* [13.x] add dispatchAfterResponse to the Dispatcher Contract by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58428\n* [13.x] Add origin verification to request forgery protection by [@benbjurstrom](https://github.com/benbjurstrom) in https://github.com/laravel/framework/pull/58400\n* [13.x] Improve `Enumerable` interface docblock types by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58181\n* Add missing chain method to interface by [@Jeroen-G](https://github.com/Jeroen-G) in https://github.com/laravel/framework/pull/58429\n* [13.x] Use unescaped unicode in `Js` support class by default by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58471\n* [13.x] Add enum types to repository contract / allow enums for tagged caches by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58481\n* [13.x] Restore eager-loaded relations when deserializing collections by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58477\n* [13.x] Bump minimum PHPUnit by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58537\n* [13.x] Respect default value for class dependencies in BoundMethod::call by [@comhon-project](https://github.com/comhon-project) in https://github.com/laravel/framework/pull/58553\n* [13.x] Bump minimum `symfony/process` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58548\n* [13.x] Fix `illuminate/json-schema` dependencies by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58612\n* [13.x] Add `hasSole` and `hasMany` to the `Enumerable` interface by [@JosephSilber](https://github.com/JosephSilber) in https://github.com/laravel/framework/pull/58610\n* [13.x] Ensure bootstrap withMiddleware works for the DownCommand by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58571\n* [13.x] Remove override attribute on removed method by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58628\n* [13.x] Ensures compatibility with `symfony/console` 8 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58629\n* [13.x] Add `cc` to Mailer contract by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58667\n* Fix ThrottleRequests over-throttling with multiple distinct rate limit keys (#54386) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58707\n* [13.x] Add `markEmailAsUnverified` to `MustVerifyEmail` interface by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58701\n* [13.x] Adds previous exceptions in exception view by [@DarkGhostHunter](https://github.com/DarkGhostHunter) in https://github.com/laravel/framework/pull/58680\n* Attributes by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/58578\n* [13.x] Accept CarbonInterval for PendingProcess timeouts by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/58842\n* [13.x] Add Setup/TearDown trait attributes by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58685\n* [13.x] Allow aliases to be set in Signature Attribute (#58853) by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58874\n* [13.x] Adds PHPUnit 13 support by [@nunomaduro](https://github.com/nunomaduro) in https://github.com/laravel/framework/pull/58890\n* [13.x] Display route binding fields in `route:list` output by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58889\n* [13.x] feat: respect `DeleteWhenMissingModels` attribute on queued notifications by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58908\n* [13.x] Resolve DeleteNotificationWhenMissingModelTest  by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58919\n* [13.x] add missing methods to Queue interface by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58914\n* [13.x] chore: define closure type on Middleware by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58929\n* [13.x] Ensure SyncQueue JobAttempted gets the actual exception by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58954\n* [13.x] Throw exception when served disks share the same URI by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58960\n* [13.x] withoutOverlapping docblock by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58973\n* [13.x] Fix `composer.json` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58975\n* [13.x] Update the dependencies version by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/58995\n* [13.x] Normalize composer.json by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/58996\n* [13.x] Add `flushLocks()` support to Cache stores by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58907\n* [13.x] Add cache `flushLocks()` events by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/59006\n* [13.x] Refactor parameter names that are implemented from the interface by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/59015\n* [13.x] Add missing [@throws](https://github.com/throws) into docblock for various methods by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/59016\n* Add insertOrIgnoreReturning method by [@antonkomarev](https://github.com/antonkomarev) in https://github.com/laravel/framework/pull/59025\n* Add corner case tests for insertOrIgnoreReturning by [@antonkomarev](https://github.com/antonkomarev) in https://github.com/laravel/framework/pull/59028\n* Extra validation on query builder upsert by [@antonkomarev](https://github.com/antonkomarev) in https://github.com/laravel/framework/pull/59029\n* [13.x] Add ErrorBag attribute support for FormRequest by [@Tresor-Kasenda](https://github.com/Tresor-Kasenda) in https://github.com/laravel/framework/pull/59033\n* [13.x] Add controller middleware attribute by [@JurianArie](https://github.com/JurianArie) in https://github.com/laravel/framework/pull/59030\n* [13.x] Add Authorize controller middleware attribute by [@JurianArie](https://github.com/JurianArie) in https://github.com/laravel/framework/pull/59048\n* [13.x] Fix `symfony/translation` deps by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/59054\n* [13.x] Remove supports for `laravel/serializable-closure` v1 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/59053\n* Add saveOrIgnore Eloquent Model method for conflict-safe inserts by [@antonkomarev](https://github.com/antonkomarev) in https://github.com/laravel/framework/pull/59026\n* [13.x] Add support for named arguments in event dispatching and broadcasting by [@ph7jack](https://github.com/ph7jack) in https://github.com/laravel/framework/pull/59075\n* [13.x] Supports `pda/pheanstalk` 8.0+ and remove 5.x by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/59072\n* [13.x] Bump dependencies by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/59069\n* [13.x] Add ability to set channel name via Log contextual attribute by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/59101\n* [13.x] Ensure insertOrIgnoreReturning only marks records as modified when rows are inserted by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59083\n* [13.x] Clean up ModelInfo by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/59080\n* [13.x] Clean up JsonApi by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/59079\n* [13.x] Indicate that raw queries should be literal strings by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/59081\n* [13.x] Update brick/math constraint and rounding mode constant by [@balu-lt](https://github.com/balu-lt) in https://github.com/laravel/framework/pull/59107\n* [13.x] fix: MorphToMany morphClass type by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/59110\n* [13.x] Rename Middleware attribute parameter from $value to $middleware  by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59133\n* [13.x] fix: QueueRoutes docblocks for getRoute and $routes property  by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59119\n* [13.x] fix: DoesntContain docblock typo by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59117\n* [13.x] BusFake assertNothingDispatched should check all dispatches by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59118\n* [13.x] fix: Align JsonApiResource flushState maxRelationshipDepth with trait default  by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59116\n* [13.x] Make Cache touch() TTL required and remove redundant value fetching  by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59121\n* [13.x] Fix previousPath() for external referrers by [@faytekin](https://github.com/faytekin) in https://github.com/laravel/framework/pull/59159\n* Add depth parameter to Arr::dot() by [@faytekin](https://github.com/faytekin) in https://github.com/laravel/framework/pull/59150\n* [13.x] Drop method_exists checks in MonitorCommand   by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59151\n* [12.x] Add strict integer validation to Numeric validation rule by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/59156\n* [12.x] Add *OrFail transaction methods to `BelongsToMany` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59153\n* [13.x] Add Exception to BatchCanceled event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59163\n* [13.x] Add support for `brick/math` 0.16 by [@balu-lt](https://github.com/balu-lt) in https://github.com/laravel/framework/pull/59165\n* Bump tar from 7.5.9 to 7.5.11 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/59164\n* [12.x] Add missing *OrFail transaction methods to BelongsToMany by [@erhanurgun](https://github.com/erhanurgun) in https://github.com/laravel/framework/pull/59168\n* [12.x] Add inOrderOf() method to query builder by [@faytekin](https://github.com/faytekin) in https://github.com/laravel/framework/pull/59162\n* [12.x] Add tcp_keepalive option to PhpRedis connector by [@heikokrebs](https://github.com/heikokrebs) in https://github.com/laravel/framework/pull/59158\n* [13.x] Add schedule:pause / resume command by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59169\n* [12.x] un`tap` PendingRequest by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/59188\n* [12.x] Fix float to int deprecation in trans_choice() for certain locales by [@hamedelasma](https://github.com/hamedelasma) in https://github.com/laravel/framework/pull/59174\n* [12.x] Allow `touch()` to accept multiple columns by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/59175\n* Revert \"Add composite index to jobs table migration for improved queue polling\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/59202\n* [12.x] Add fluent string validation rule builder by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59201\n* [13.x] Add schedule resume and pause events by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59172\n* [13.x] insertOrIgnoreReturning with multiple unique keys by [@tpetry](https://github.com/tpetry) in https://github.com/laravel/framework/pull/59187\n* Update `Command::withProgressBar` phpdoc to account for arrow functions and non-void return types by [@billypoke](https://github.com/billypoke) in https://github.com/laravel/framework/pull/58766\n* [12.x] Lazily evaluate value for constraints in `HasOneOrManyThrough` by [@Jacobs63](https://github.com/Jacobs63) in https://github.com/laravel/framework/pull/59231\n* Add string helper to get initials from a string by [@denjaland](https://github.com/denjaland) in https://github.com/laravel/framework/pull/59230\n* fix:  Strip gzip-compressed output from concurrent process response by [@NikhiltGhalme](https://github.com/NikhiltGhalme) in https://github.com/laravel/framework/pull/59224\n* [12.x] Fix failing tests introduced by #59201 by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59207\n* [12.x] Avoid redundant `Util::getParameterClassName()` call in container resolution by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59220\n* [12.x] Add missing conditional validation rule builders by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59209\n* [12.x] Skip placeholder replacements when message does not contain them by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59211\n* [12.x] Use `array_push` with spread operator in `MessageBag::all()` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59217\n* [12.x] Cache Route instances in CompiledRouteCollection::getByName() by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59221\n* [13.x] Add additional Artisan attributes for usage, help and hidden by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/59204\n* [12.x] Accept CarbonInterval for retry sleep duration by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/59232\n* [12.x] Fix failing phpstan by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/59245\n* [12.x] Update comments for PlanetScale MySQL and PostgreSQL by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/59244\n* [12.x] Use big integers for database cache expiration column by [@tanerkay](https://github.com/tanerkay) in https://github.com/laravel/framework/pull/59243\n* [13.x] Allow brick/math ^0.17 by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59249\n* [12.x] Display file path and line number for closure routes in `route:list` by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/59237\n* [12.x] Add wantsMarkdown() and acceptsMarkdown() request methods by [@joetannenbaum](https://github.com/joetannenbaum) in https://github.com/laravel/framework/pull/59238\n* [13.x] Ensure RequiredUnless handles null by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59235\n\n## [v12.54.1](https://github.com/laravel/framework/compare/v12.54.0...v12.54.1) - 2026-03-10\n\n* [12.x] Makes imports consistent by [@nunomaduro](https://github.com/nunomaduro) in https://github.com/laravel/framework/pull/59149\n\n## [v12.54.0](https://github.com/laravel/framework/compare/v12.53.0...v12.54.0) - 2026-03-10\n\n* [12.x] Fix division by zero error in `repeatEvery()` method by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58987\n* [12.x] Allow app.editor.base_path to be an empty string by [@kminek](https://github.com/kminek) in https://github.com/laravel/framework/pull/58991\n* [12.x] Add missing, remove unused parameters to docblocks by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/58989\n* Fix URL validation for punycode subdomains by [@mpa12](https://github.com/mpa12) in https://github.com/laravel/framework/pull/58982\n* [12.x] Prevent queue deadlock when reserving a job throws an exception (e.g., attempts overflow) by [@sadique-cws](https://github.com/sadique-cws) in https://github.com/laravel/framework/pull/58978\n* [12.x] bug: throttle with redis ignores after callback by [@RobertBoes](https://github.com/RobertBoes) in https://github.com/laravel/framework/pull/58990\n* Update brick/math version constraint to include 0.15 by [@julien-boudry](https://github.com/julien-boudry) in https://github.com/laravel/framework/pull/59005\n* Revert \"Update brick/math version constraint to include 0.15\" by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/59009\n* Bump rollup from 4.46.3 to 4.59.0 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/59013\n* [12.x] Fix TwoColumnDetail stripping trailing punctuation from second column values by [@theritvars](https://github.com/theritvars) in https://github.com/laravel/framework/pull/59010\n* [12.x] Add support for assertions on `BinaryFileResponse` by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/59018\n* [12.x] fix: array offset deprecation warning by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/59019\n* [12.x] Add tsvector column type for PostgreSQL by [@milroyfraser](https://github.com/milroyfraser) in https://github.com/laravel/framework/pull/59004\n* Memory Limit passed as string when run from supervisor by [@turbo124](https://github.com/turbo124) in https://github.com/laravel/framework/pull/59049\n* [12.x] Fix facade cache file permissions by [@nkoestinger](https://github.com/nkoestinger) in https://github.com/laravel/framework/pull/59059\n* [12.x] Display oldest pending job in queue:monitor output by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/59073\n* Fix type() method return type in Illuminate\\Filesystem\\Filesystem by [@GNfsys](https://github.com/GNfsys) in https://github.com/laravel/framework/pull/59071\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/59068\n* [12.x] Wrap flags in `int-mask-of` annotation by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/59082\n* Fix after-commit observers breaking -ing event cancellation by [@eyupcanakman](https://github.com/eyupcanakman) in https://github.com/laravel/framework/pull/59058\n* [12.x] Fix migrate:fresh failing when database does not exist by [@MElkmeshi](https://github.com/MElkmeshi) in https://github.com/laravel/framework/pull/59113\n* [12.x] Add `interval()` method to `InteractsWithData` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59114\n* [12.x] Hash displayName() in cache lock keys by [@A5hleyRich](https://github.com/A5hleyRich) in https://github.com/laravel/framework/pull/59141\n* [12.x] Improved html test helpers by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/59140\n* [12.x] Add Model::withoutRelation() for selective relation unloading    by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59137\n* [12.x] Include request context in HTTP client Response::dump() by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/59136\n* Fix enum handling in ModelNotFoundException error message by [@isaackaara](https://github.com/isaackaara) in https://github.com/laravel/framework/pull/59132\n* [12.x] Update composer.json to enforce commonmark version without DisallowedRawHtmlRenderer exploit by [@Smoggert](https://github.com/Smoggert) in https://github.com/laravel/framework/pull/59131\n* [12.x] Suppress chmod errors in Filesystem::replace() for non-POSIX filesystems by [@eyupcanakman](https://github.com/eyupcanakman) in https://github.com/laravel/framework/pull/59126\n* Add composite index to jobs table migration for improved queue polling by [@firecow](https://github.com/firecow) in https://github.com/laravel/framework/pull/59111\n* [12.x] Load custom markdown extensions for mail by [@dasundev](https://github.com/dasundev) in https://github.com/laravel/framework/pull/59051\n* [12.x] Fix docblock for RateLimiter `for()` method by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/59144\n* [12.x] Deduplicate paths in view:cache by [@ganyicz](https://github.com/ganyicz) in https://github.com/laravel/framework/pull/59145\n\n## [v12.53.0](https://github.com/laravel/framework/compare/v12.52.0...v12.53.0) - 2026-02-24\n\n* [12.x] Add multipleOf support to JsonSchema numeric types by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/58903\n* [12.x] chore: don't format notifiables in NotificationSender::send by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58900\n* [12.x] Add vector option to whereFullText for pre-computed tsvector columns by [@milroyfraser](https://github.com/milroyfraser) in https://github.com/laravel/framework/pull/58893\n* [12.x] Add array key support for `buildMorphMapFromModels()` function by [@josephkerkhof](https://github.com/josephkerkhof) in https://github.com/laravel/framework/pull/58891\n* [12.x] Fix RequestException summarizing for Guzzle streamed responses by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58909\n* [12.x] Tests for streamed RequestException by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58910\n* Support a serializable classes value on caches by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/58911\n* [12.x] Simplify TokenGuard methods by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/58923\n* [12.x] Add uniqueItems support to JsonSchema ArrayType by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/58922\n* [12.x] Add tests for `PhpRedisClusterConnection` flushdb method by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58917\n* [12.x] Add support for named arguments in event dispatching and broadcasting by [@ph7jack](https://github.com/ph7jack) in https://github.com/laravel/framework/pull/58913\n* [12.x] Allow `down` command to refresh maintenance mode options by [@alies-dev](https://github.com/alies-dev) in https://github.com/laravel/framework/pull/58918\n* [12.x] Rollback lingering PDO transaction before retrying on commit deadlock by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58906\n* [12.x] Simplify queue resolution using `match` expression by [@josephkerkhof](https://github.com/josephkerkhof) in https://github.com/laravel/framework/pull/58928\n* Bump tar from 7.5.7 to 7.5.9 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/58931\n* [12.x] Fix model serialization in queue jobs by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/58939\n* [12.x] Change Mail text alignment from left to start by [@zvizvi](https://github.com/zvizvi) in https://github.com/laravel/framework/pull/58935\n* [12.x] Refactor `convertValuesToBoolean` to use `match` for cleaner logic by [@josephkerkhof](https://github.com/josephkerkhof) in https://github.com/laravel/framework/pull/58927\n* [12.x] Allow Scheduled Command `Event` macros to be applied to schedule groups by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/58926\n* [12.x] Fix race condition on creating the real-time facade cache file (#58945) by [@sosias](https://github.com/sosias) in https://github.com/laravel/framework/pull/58947\n* [12.x] Show all mismatched values in `assertSessionHasAll` failure output by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58946\n* Fix RetryCommand not working for SQS FIFO queue by [@cwang22](https://github.com/cwang22) in https://github.com/laravel/framework/pull/58936\n* [12.x] Improve return types for Wormhole and InteractsWithTime by [@KentarouTakeda](https://github.com/KentarouTakeda) in https://github.com/laravel/framework/pull/58951\n* [12.x] Add `Cache::funnel()` for concurrency limiting with any cache driver by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/58439\n* [12.x]  Ensure `oldest_pending` is displayed in `queue:monitor` by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58952\n* [12.x] Fix/cross database null safe equals by [@patrickomeara](https://github.com/patrickomeara) in https://github.com/laravel/framework/pull/58962\n* [12.x] Add MySQL inRandomOrder regression tests by [@laraib15](https://github.com/laraib15) in https://github.com/laravel/framework/pull/58966\n* [12.x] Add missing [@throws](https://github.com/throws) docblocks to Illuminate/Http by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/58965\n* Fix Invalid Types by [@RyanSchaefer](https://github.com/RyanSchaefer) in https://github.com/laravel/framework/pull/58963\n* JSONP Check by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/58971\n* [12.x] Resolve Stan Mailable CI error by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58972\n* [12.x] Remove unnecessary dirname calls. by [@jelleroorda](https://github.com/jelleroorda) in https://github.com/laravel/framework/pull/58984\n* [12.x] Add missing [@throws](https://github.com/throws) docblocks to `Serializer` and `Type` classes in `Illuminate/JsonSchema` by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/58981\n\n## [v12.52.0](https://github.com/laravel/framework/compare/v12.51.0...v12.52.0) - 2026-02-17\n\n* [12.x] Fix: `@return` in doc blocks by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58746\n* [12.x] Ensure defer callbacks aren't discarded when using the sync queue by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58745\n* [12.x] Refactor: remove `Arr::wrap()` and add `Collection::wrap()` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58748\n* Add support for `temporaryUploadUrl` to the `local` filesystem by [@mnapoli](https://github.com/mnapoli) in https://github.com/laravel/framework/pull/58499\n* Only merge cached casts for accessed attribute by [@ug-christoph](https://github.com/ug-christoph) in https://github.com/laravel/framework/pull/57627\n* [12.x] Sort stan issue on PendingRequest by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58760\n* [12.x] Update alphabetical order in facades.yml by [@luisscruza](https://github.com/luisscruza) in https://github.com/laravel/framework/pull/58757\n* [12.x] allow string-based expressions for selectExpression() by [@tpetry](https://github.com/tpetry) in https://github.com/laravel/framework/pull/58753\n* Revert \"[12.x] Adjust freshTimestamp for SQL Server\" by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58758\n* [12.x] Fix return empty Collection for non-model JSON:API resources by [@noir4y](https://github.com/noir4y) in https://github.com/laravel/framework/pull/58752\n* [12.x] Refactor: remove extra space by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58751\n* [12.x] Standardize regex delimiter in ObserverMakeCommand::parseModel by [@mohammadRezaei1380](https://github.com/mohammadRezaei1380) in https://github.com/laravel/framework/pull/58777\n* [12.x] Fix incorrect [@return](https://github.com/return) type in VendorPublishCommand::publishTag by [@mohammadRezaei1380](https://github.com/mohammadRezaei1380) in https://github.com/laravel/framework/pull/58774\n* Fix phpdoc type in promptForMissingArgumentsUsing by [@billypoke](https://github.com/billypoke) in https://github.com/laravel/framework/pull/58768\n* [12.x] cast `Batch::progress()` return value to `int` by [@zjbarg](https://github.com/zjbarg) in https://github.com/laravel/framework/pull/58767\n* [12.x] Drop Collection import from `AbstractRouteCollection` by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58769\n* [12.x] Fix missing InputArgument::IS_ARRAY in getArguments PHPDoc by [@kayw-geek](https://github.com/kayw-geek) in https://github.com/laravel/framework/pull/58771\n* [12.x] Fix: `@return` for `resolveResourceRelationshipIdentifiers()` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58764\n* [12.x] `Mailable::later()` does not set delay on `SendQueuedMailable` instance by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58765\n* [12.x] Refactor: use `enum_value()` helper for environment value extraction by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58785\n* [12.x] Add delay support assertions for queued mailables by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58787\n* Fix MySQL connection string to use --ssl-mode=DISABLED for modern clients by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/58786\n* [12.x] Refactor: standardize regex by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58789\n* [12.x] Allow $preserveKeys param for LazyCollection random by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58791\n* [12.x] Refactor: `new Collection()` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58793\n* [12.x] Add `makeMany` method to Factory by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58795\n* [12.x] Add `withoutAfterMaking()` and `withoutAfterCreating()` factory helpers by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/58794\n* [12.x] Backport withMiddleware changes from 13.x by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58798\n* [12.x] Fix: add `|array` in doc block by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58805\n* [12.x] Add option to opt out of parallel safe cache prefix by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58801\n* [12.x] Normalize Throwable docblocks to fully-qualified name by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58802\n* [12.x] Refactor: remove unnecessary `\\BackedEnum` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58807\n* Use atomic writes when creating inline Blade component views by [@cyppe](https://github.com/cyppe) in https://github.com/laravel/framework/pull/58815\n* [12.x] Add missing tests for Request::fullUrlWithoutQuery by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58814\n* Improve File::toKilobytes() DocBlock return type by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/58811\n* Use atomic writes in BladeCompiler to prevent race condition by [@cyppe](https://github.com/cyppe) in https://github.com/laravel/framework/pull/58812\n* [12.x] Refactor: add `JSON decoded` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58830\n* [12.x] Refactor: add missing `@throws` tag in dock block by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58829\n* [12.x] Formatting by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58828\n* [12x]Refactor: remove unnecessary \\BackedEnum in HasAttributes.php by [@mohammadRezaei1380](https://github.com/mohammadRezaei1380) in https://github.com/laravel/framework/pull/58827\n* [12x] Refactor conditional message formatting using match expression by [@mohammadRezaei1380](https://github.com/mohammadRezaei1380) in https://github.com/laravel/framework/pull/58825\n* [12.x] Refactor: use `match` expression by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58824\n* [12.x] Simplify `compileSelect` method return by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58821\n* [12.x] Refactor: simplify code by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58820\n* [12.x] Refactor: remove unnecessary `\\BackedEnum` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58818\n* [12.x] Ensure HttpClientTest doesnt flake in Windows CI by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58817\n* [12.x] Refactor: `JSON decoded` to `decoded JSON` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58849\n* [12.x] Allow closure parameters in docblock for when() helper function by [@gazben](https://github.com/gazben) in https://github.com/laravel/framework/pull/58862\n* [12.x] Fix typo in cache `composer.json` by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58875\n* [12.x] Remove unnecessary `forgetDriver()`from TestCaches by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58878\n* Revert \"[12.x] Fixed precision checks for column types in SQL Server grammar\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/58888\n* [12.x] Display closures and standalone functions correctly in exception trace by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/58879\n\n## [v12.51.0](https://github.com/laravel/framework/compare/v12.50.0...v12.51.0) - 2026-02-10\n\n* Remove type hint in favor of return type by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/58621\n* [12.x] Adjust freshTimestamp for SQL Server by [@aimeos](https://github.com/aimeos) in https://github.com/laravel/framework/pull/58614\n* [12.x] Handle binary data in Js::encode() debug renderer by [@denis-chmel](https://github.com/denis-chmel) in https://github.com/laravel/framework/pull/58618\n* [12.x] Add ArrayObject props to AsEncryptedArrayObject to match AsArrayObject by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/58619\n* fix: Arr::wrap() return type by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58625\n* [12.x] Fix typo in type definition by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58624\n* [12.x] Prevent dupe locale checks in `Lang::get()` when locale matches fallback by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58626\n* [12.x] chore: add deprecation to Request::get() by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58635\n* [12.x] Fix Str::substrReplace for edge cases with negative offset or length by [@jboonstra70](https://github.com/jboonstra70) in https://github.com/laravel/framework/pull/58634\n* [12.x] Refactor: improve doc blocks by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58630\n* [12.x] Add BatchCancelled Event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58627\n* [12.x] Fix typo in type definition by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58638\n* [12.x] Update `reload` tasks to include `schedule:interruption` by [@adevade](https://github.com/adevade) in https://github.com/laravel/framework/pull/58637\n* docs: add missing description to FilesystemAdapter::report() docblock by [@eranishojha](https://github.com/eranishojha) in https://github.com/laravel/framework/pull/58640\n* [12.x] Allow closures for values in `firstOrCreate` and `createOrFirst` by [@gcavanunez](https://github.com/gcavanunez) in https://github.com/laravel/framework/pull/58639\n* [12.x] Support `afterSending` method on notification by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58654\n* [12.x] Allow Stringable::deduplicate() to accept array of characters by [@Tresor-Kasenda](https://github.com/Tresor-Kasenda) in https://github.com/laravel/framework/pull/58649\n* Update regex for trans_choice to allow negative ranges by [@hmazter](https://github.com/hmazter) in https://github.com/laravel/framework/pull/58648\n* Added timeout method to query builder for MySQL by [@Vladelis](https://github.com/Vladelis) in https://github.com/laravel/framework/pull/58644\n* [12.x] Add `assertJobs` method on `PendingBatchFake` by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58606\n* [12.x] Fix batch counts when deleteWhenMissingModels skips missing model jobs by [@yankewei](https://github.com/yankewei) in https://github.com/laravel/framework/pull/58541\n* [12.x] Fix Postgres sequence starting value for custom schemas/connections by [@joteejotee](https://github.com/joteejotee) in https://github.com/laravel/framework/pull/58199\n* [12.x] Add `whenFails` and `whenPasses` methods on `Validator` by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58655\n* [12.x] Bus::assertBatched() with array by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58659\n* [12.x] Refactor: improve doc block by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58677\n* [12.x] Add withoutHeader() method to Response by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58671\n* [12.x] Add integer array key support in phpdocs by [@dluague](https://github.com/dluague) in https://github.com/laravel/framework/pull/58668\n* `Illuminate\\Console\\Parser` typehint fix. by [@LastDragon-ru](https://github.com/LastDragon-ru) in https://github.com/laravel/framework/pull/58670\n* fix: replace substr with mb_substr for user agent encoding by [@jonagoldman](https://github.com/jonagoldman) in https://github.com/laravel/framework/pull/58703\n* chore: fix the Laravel ASCII SVG so that its characters perfectly align to columns by [@markjaquith](https://github.com/markjaquith) in https://github.com/laravel/framework/pull/58702\n* [12.x] Allow retrieving all view data via viewData() in TestResponse by [@shane-zeng](https://github.com/shane-zeng) in https://github.com/laravel/framework/pull/58700\n* Exception page: fix pop in for non main frames by [@martinpl](https://github.com/martinpl) in https://github.com/laravel/framework/pull/58698\n* [12.x] Add missing [@throws](https://github.com/throws) annotations to validation rules and JsonResponse by [@QDenka](https://github.com/QDenka) in https://github.com/laravel/framework/pull/58697\n* [12.x] Add conditional return type hint for Route::middleware() method. by [@marcreichel](https://github.com/marcreichel) in https://github.com/laravel/framework/pull/58699\n* [12.x] Improved type hints for when() helper function. by [@marcreichel](https://github.com/marcreichel) in https://github.com/laravel/framework/pull/58696\n* [12.x] Support Eloquent builders and relations as subqueries to update queries by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/58692\n* Add cache prefix isolation for parallel testing (#57584) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58691\n* Fix whereBetween to accept DatePeriod and handle missing end dates (#58092) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58687\n* Fix Str::isUrl() returning false for single-char domain names (#58538) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58686\n* Fix HTTP client response type hints for IDE compatibility (#58555) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58684\n* Fix types for ConfirmableTrait::confirmToProceed by [@rolfvandekrol](https://github.com/rolfvandekrol) in https://github.com/laravel/framework/pull/58681\n* [12.x] Refactor: simplify return with `??` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58679\n* [12.x] Refactor: replace `header` / `headers` with standardized `header(s)` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58678\n* Add SSL cert/key support to MySQL schema dump and load (#57821) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58690\n* Allow specifying Redis connection on Redis-based queue middleware by [@markieo1](https://github.com/markieo1) in https://github.com/laravel/framework/pull/58656\n* [12.x] Use JS to create the Laravel ASCII SVG logo on the fly by [@markjaquith](https://github.com/markjaquith) in https://github.com/laravel/framework/pull/58719\n* [12.x] Feat: add `orderByPivotDesc()` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58720\n* [12.x] Refactor: add `@throws \\InvalidArgumentException` to doc blocks by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58714\n* [12.x] Restore original dispatcher bindings after precognitive request by [@pindab0ter](https://github.com/pindab0ter) in https://github.com/laravel/framework/pull/58716\n* [12.x] Ensure throwIfStatus / throwUnlessStatus work for all status codes by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58724\n* Fix Queue::fake() not releasing unique job locks between tests (#58533) by [@HeathNaylor](https://github.com/HeathNaylor) in https://github.com/laravel/framework/pull/58718\n* [12.x] Refactor: add `_` to more readability digit by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58738\n* [12.x] Refactor: Clean up unused $config parameters in ConcurrencyManager  by [@alizadeh7091](https://github.com/alizadeh7091) in https://github.com/laravel/framework/pull/58739\n* [12.x] Refactor: use `Dumpable` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58743\n* [12.x] Update forever cookie factory docblock to reflect 400-day duration by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58744\n\n## [v12.50.0](https://github.com/laravel/framework/compare/v12.49.0...v12.50.0) - 2026-02-04\n\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58531\n* [12.x] Resolve the correct queue factory when using laravel octane by [@BertvanHoekelen](https://github.com/BertvanHoekelen) in https://github.com/laravel/framework/pull/58530\n* [12.x] Clear parallel test view cache directories by [@eduPHP](https://github.com/eduPHP) in https://github.com/laravel/framework/pull/58525\n* [12.x] fix: allow phpstan to understand default value for Request::enum by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58529\n* [12.x] feat: allow queued listeners to be unique by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58402\n* [12.x] Use morphMap when serializing model identifiers by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58482\n* [12.x] Add `authority`method to Support/Uri by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58534\n* [12.x] Use try/finally for buildStack cleanup in Container::build by [@comhon-project](https://github.com/comhon-project) in https://github.com/laravel/framework/pull/58536\n* [12.x] Update phpunit version constraints to address CVE by [@PerryvanderMeer](https://github.com/PerryvanderMeer) in https://github.com/laravel/framework/pull/58526\n* Bump tar from 7.5.6 to 7.5.7 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/58539\n* [12.x] Ensure Validator message defaults if using custom size messages by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58554\n* [12.x] Add withoutAppends to HasAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/58552\n* [12.x] Refactor: simplify in `match` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58547\n* Revert \"[12.x] Update phpunit version constraints to address CVE\" by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58542\n* [12.x] Add `hasMany()` method to collections by [@JosephSilber](https://github.com/JosephSilber) in https://github.com/laravel/framework/pull/58550\n* [12.x] Retain associative keys on eager loaded relations by [@Jade-GG](https://github.com/Jade-GG) in https://github.com/laravel/framework/pull/58506\n* [12.x] Add typed getters on Cache  by [@ahinkle](https://github.com/ahinkle) in https://github.com/laravel/framework/pull/58451\n* [12.x] Add `MaintenanceMode` facade to docblock generator by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/58564\n* [12.x] Adjust docblock for formatActionForCli by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58562\n* [12.x] brick/math `of` float deprecation by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58563\n* [12.x] Improve migration types by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58561\n* [12.x] Remove extra space by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58573\n* [12.x] Drop foreach from preg_replace_callback helper by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58570\n* [12.x] Improve typing in console/command namespace by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58565\n* [12.x] Refactor: improve tests by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58582\n* [12.x] Update callback type hints for Context's `Repository` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58581\n* [12.x] Exclude decorative ASCII art SVG from exception page in non-browser contexts by [@serhiilabs](https://github.com/serhiilabs) in https://github.com/laravel/framework/pull/58580\n* [12.x] Improve types of `Arr` helper by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58518\n* [12.x] Add tests for withoutAppends() method by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/58583\n* [12.x] Add tests for hasAppended() method by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/58587\n* [12.x] Sort flaky MaintenanceModeTest by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58590\n* [12.x] Preserve notification state mutations from via() in sendNow() by [@alimorgaan](https://github.com/alimorgaan) in https://github.com/laravel/framework/pull/58558\n* [12.x] Fix: add `|null` for `$name` in `storeAs()` by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58613\n* [12.x] Add `InteractsWithData::clamp()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58608\n* [12.x] try-catch all composer package uninstalls by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58609\n* [12.x] `InteractsWithData@enum()` refactor by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58607\n* [12.x] Enum support for Cache::get() with array keys by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58616\n* [12.x] Fixed precision checks for column types in SQL Server grammar by [@aimeos](https://github.com/aimeos) in https://github.com/laravel/framework/pull/58602\n* [12.x] Fix `illuminate/reflection` workflow directory by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58600\n* [12.x] Ensure File fail doesn't double translate in fail() by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58598\n* [12.x] Ensure mailable HTML assertions properly escape quotes by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58595\n\n## [v12.49.0](https://github.com/laravel/framework/compare/v12.48.1...v12.49.0) - 2026-01-28\n\n* [12.x] Clean up compiled views after parallel testing by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58440\n* [12.x] Support \"where subquery between columns\" by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58441\n* [12.x] Use searchable prompt for db:table command by [@sakshamgorey](https://github.com/sakshamgorey) in https://github.com/laravel/framework/pull/58442\n* [12.x] keep single NotificationSender instance by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/58452\n* [12.x] Allow enum keys in Cache::flexible() and withoutOverlapping() by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58444\n* [12.x] Add preserveKeys method to AnonymousResourceCollection by [@comhon-project](https://github.com/comhon-project) in https://github.com/laravel/framework/pull/58443\n* Bump tar from 7.5.3 to 7.5.6 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/58454\n* [12.x] Fix memory leak in `Arr::dot()` by [@benjamin-commentor](https://github.com/benjamin-commentor) in https://github.com/laravel/framework/pull/58458\n* 12.x fix: use multibyte-safe functions in Str::afterLast() by [@irabbi360](https://github.com/irabbi360) in https://github.com/laravel/framework/pull/58457\n* [12.x] Ensure Session now() and flash() accept enums by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58459\n* [12.x] Revert \"feat: aliasing when selecting database expressions (#58436)\" by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/framework/pull/58469\n* [12.x] Add `hasSole()` method to collections by [@JosephSilber](https://github.com/JosephSilber) in https://github.com/laravel/framework/pull/58463\n* [12.x] Skip message serialization when log level is not handled by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58475\n* [12.x] Add missing [@param](https://github.com/param) documentation to SessionGuard constructor by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58493\n* [12.x] do assignment instead of mutating to handle immutable carbon object. by [@MrPunyapal](https://github.com/MrPunyapal) in https://github.com/laravel/framework/pull/58498\n* Enhance index hint validation for multiple indexes by [@FlexIDK](https://github.com/FlexIDK) in https://github.com/laravel/framework/pull/58505\n* [12.x] Make QueueFake assertPushedTimes public by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58511\n* [12.x] Ignore deadlock on DatabaseLock release by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58507\n* [12.x] Allow `down` command --retry option to accept datetime values by [@alies-dev](https://github.com/alies-dev) in https://github.com/laravel/framework/pull/58509\n\n## [v12.48.1](https://github.com/laravel/framework/compare/v12.48.0...v12.48.1) - 2026-01-20\n\n## [v12.48.0](https://github.com/laravel/framework/compare/v12.47.0...v12.48.0) - 2026-01-20\n\n* [12.x] Fix missing variable reassignment by [@nunomaduro](https://github.com/nunomaduro) in https://github.com/laravel/framework/pull/58376\n* [12.x] Improve PendingRequest types by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58386\n* [12.x] Fix backward compatibility with third-party guards by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/58385\n* Make \\Illuminate\\Testing\\TestResponse::assertHeader() case insensitive by [@HenkPoley](https://github.com/HenkPoley) in https://github.com/laravel/framework/pull/58383\n* [12.x] Fix TypeError when validation rule has empty parameters by [@irabbi360](https://github.com/irabbi360) in https://github.com/laravel/framework/pull/58380\n* [12.x] Adjust PendingBatchFake to filter by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58375\n* [12.x] Resolve infinite loop when using deferred queue by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58373\n* [12.x] Fix and improve `\\Illuminate\\Support\\Str` types further by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58372\n* [12.x] Ensure Bus::chain filters out falsy items by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58369\n* [12.x] fix invalid array doctypes for Str::replaceMatches in v12.47.0 by [@marcreichel](https://github.com/marcreichel) in https://github.com/laravel/framework/pull/58364\n* [12.x] Remove useless use of `MockeryPHPUnitIntegration` by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/58363\n* [12.x] Fix: Drop indexes from failed_jobs by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58362\n* Translation lines may contain square brackets and curly braces now by [@edwinheij](https://github.com/edwinheij) in https://github.com/laravel/framework/pull/58367\n* [12.x] Add `skipWhen` functionality to `HandleCors` middleware by [@RobertBoes](https://github.com/RobertBoes) in https://github.com/laravel/framework/pull/58361\n* [12.x] Fix backward compatibility with third-party guards, again by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/58389\n* [12.x] Add type tests for `\\Illuminate\\Support\\Str` by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58365\n* [12.x] `new $class` instead of reflection for better performance by [@takaram](https://github.com/takaram) in https://github.com/laravel/framework/pull/58391\n* [12.x] Isolate compiled views per process during parallel testing by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58390\n* [12.x] Fix broken import by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/58394\n* [12.x] Implement Stringable in Enum rule by [@owenconti](https://github.com/owenconti) in https://github.com/laravel/framework/pull/58392\n* [12.x] Fix restoreLock for MemoizedStore by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58423\n* [12.x] Fix Filesystem::sharedGet partial reads (#58418) by [@sv63rus](https://github.com/sv63rus) in https://github.com/laravel/framework/pull/58419\n* [12.x] Add missing [@param](https://github.com/param) docblock to ValidatedInput::__isset() by [@ismaildasci](https://github.com/ismaildasci) in https://github.com/laravel/framework/pull/58410\n* [12.x] Add queue to JobPopping by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58413\n* [12.x] add backoff to JobReleasedAfterException event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58414\n* [12.x] Fix return type docblock for Number::abbreviate method by [@ismaildasci](https://github.com/ismaildasci) in https://github.com/laravel/framework/pull/58408\n* [12.x] Annotate tuple return type of Number::pairs() by [@ismaildasci](https://github.com/ismaildasci) in https://github.com/laravel/framework/pull/58409\n* Bump tar from 7.4.3 to 7.5.3 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/58404\n* [12.x] Update return type of merge for collections by [@ramonrietdijk](https://github.com/ramonrietdijk) in https://github.com/laravel/framework/pull/58405\n* [12.x] Fix missing import by [@irabbi360](https://github.com/irabbi360) in https://github.com/laravel/framework/pull/58401\n* [12.x] Account for `Throwable` inside of PendingRequest by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58395\n* [12.x] Allow setting flags for decoding json in the Http Client's Response by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58379\n* [12.x] chore: make PruneCommand::isPrunable() protected by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58430\n* [12.x] widen PendingRequest@pool() return type by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58437\n* [12.x] feat: query builder aliases for expressions by [@tpetry](https://github.com/tpetry) in https://github.com/laravel/framework/pull/58436\n* Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58432\n* [12.x] add BatchFinished event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58431\n\n## [v12.47.0](https://github.com/laravel/framework/compare/v12.46.0...v12.47.0) - 2026-01-13\n\n* [12.x] Add `@includeIsolated` directive for isolated Blade includes by [@KennedyTedesco](https://github.com/KennedyTedesco) in https://github.com/laravel/framework/pull/58311\n* [12.x] Fix typo in JsonApiResource trait method by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58326\n* [12.x] Add `Cache::withoutOverlapping()` to wrap `Cache::lock()->block()` by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/58303\n* Update return type annotations in FormRequest.php by [@arttiger](https://github.com/arttiger) in https://github.com/laravel/framework/pull/58333\n* [12.x] Fix QueryException showing wrong connection details for read PDO by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/58331\n* [12.x] Only fire `CacheFailedOver` and `QueueFailedOver` on first failure by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58330\n* allow precognitive requests to use wildcards with array validations (#57437) by [@markusheinemann](https://github.com/markusheinemann) in https://github.com/laravel/framework/pull/57486\n* [12.x] Fix docblock for Failovers by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58336\n* [12.x] Only fire composer uninstall events when removing dev packages by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58338\n* Vector things by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/58337\n* Update tailwind version by [@laserhybiz](https://github.com/laserhybiz) in https://github.com/laravel/framework/pull/58344\n* [12.x] Allow for enum keys in additional Session Store methods by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/58343\n* [12.x] JSON API: Deduplicate circular references  by [@mateusjatenee](https://github.com/mateusjatenee) in https://github.com/laravel/framework/pull/58348\n* [12.x] Improve `key:generate` error message when `APP_KEY` is set by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58345\n* [12.x] Add indexes to failed_jobs stub by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58355\n* [12.x] Improve types in `\\Illuminate\\Support\\Str` helper by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58356\n* [12.x] Fix MySQL port conflict in tests workflow by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58357\n* [12.x] Improve the return types for `Number::with*()` helpers by [@CasEbb](https://github.com/CasEbb) in https://github.com/laravel/framework/pull/58358\n* [12.x] Ensure `Bus::batch` filters out falsy items by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58360\n* [12.] Annotate tuple return type of `TableGuesser::guess()` by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58354\n* [12.x] Make Notification macroable by [@ekateiva](https://github.com/ekateiva) in https://github.com/laravel/framework/pull/58352\n* [12.x] Allow PendingBatch `onConnection` to use Enum by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58350\n\n## [v12.46.0](https://github.com/laravel/framework/compare/v12.45.2...v12.46.0) - 2026-01-07\n\n* [12.x] Add `Arr::onlyValues` and `Arr::exceptValues` by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/58317\n* [12.x] Fixed phpdoc of `Container::buildSelfBuildingInstance`, to prevent psalm from erroring when parsing the class by [@nicDamours](https://github.com/nicDamours) in https://github.com/laravel/framework/pull/58314\n* [12.x] Add `Collection::containsManyItems()` method by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/58312\n* [12.x] Table prefix not applied when cloning connections by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58288\n* [12.x] Added MySQL DDL locking options to MySQL grammar by [@Vladelis](https://github.com/Vladelis) in https://github.com/laravel/framework/pull/58293\n\n## [v12.45.2](https://github.com/laravel/framework/compare/v12.45.1...v12.45.2) - 2026-01-07\n\n* [12.x] Feature: allow UnitEnum in has() method of Gate class by [@webard](https://github.com/webard) in https://github.com/laravel/framework/pull/58310\n* [12.x] Fix `Validator::appendRules()` with pipe-separated rule strings by [@leo108](https://github.com/leo108) in https://github.com/laravel/framework/pull/58304\n* [12.x] Fix calling `toArray()` on `AnonymousResourceCollection` returns an array of resources by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58302\n\n## [v12.45.1](https://github.com/laravel/framework/compare/v12.45.0...v12.45.1) - 2026-01-07\n\n* [12.x] Fix `ResourceCollection` usage when used with an array instead of Model collection by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58299\n\n## [v12.45.0](https://github.com/laravel/framework/compare/v12.44.0...v12.45.0) - 2026-01-06\n\n* [12.x] JSON:API Resource by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57571\n* [12.x] Add static constructor to guest middleware by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/58204\n* [12.x] Include JsonResource in `ModelInspector` result by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58205\n* [12.x] Add queue paused / resume events by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58202\n* [12.x] Add attachment helper method to add attachment from cloud storage by [@PhiloNL](https://github.com/PhiloNL) in https://github.com/laravel/framework/pull/58201\n* [12.x] Normalize APP_URL when generating filesystem URLs by [@congkv](https://github.com/congkv) in https://github.com/laravel/framework/pull/58210\n* [12.x] Adjust AuthDatabaseTokenRepositoryTest by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58206\n* [12.x] Refactor `queuePaused` logic by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58215\n* Fix queue:listen timeout false positives after system sleep/wake by [@ranjith67](https://github.com/ranjith67) in https://github.com/laravel/framework/pull/58216\n* Change the remember cookie to store a MAC of the users password hash instead of their real password hash by [@Synchro](https://github.com/Synchro) in https://github.com/laravel/framework/pull/58107\n* Add connection details to QueryException error messages by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/58218\n* [12.x] Adjust README test status badge by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58222\n* [12.x] Use constant for session ID length by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58224\n* [12.x] Add type tests for PendingRequest.php by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/58232\n* feat: fire JobAttempted for sync jobs too by [@veeshpath](https://github.com/veeshpath) in https://github.com/laravel/framework/pull/58228\n* [12.x] Adjust getEventDispatcher docblock to allow null return by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58242\n* [12.x] Extract `JobAttempted` event dispatch to a separate method in `SyncQueue` by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58240\n* [12.x] ValidationException: update redirectTo property definition to include null by [@cheack](https://github.com/cheack) in https://github.com/laravel/framework/pull/58238\n* [12.x] Add BackedEnum support for session keys by [@ahinkle](https://github.com/ahinkle) in https://github.com/laravel/framework/pull/58241\n* [12.x] Update `upload-artifact` action by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58250\n* [12.x] Allow BackedEnum for Cache keys by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58246\n* [12.x] Add CommandFailed event and listenForFailures() for Redis connections by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58251\n* [12.x] Fix: Change BackedEnum to UnitEnum in Authorizable trait by [@webard](https://github.com/webard) in https://github.com/laravel/framework/pull/58258\n* [12.x]Refactor: remove if and replace ? by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58256\n* [12.x]Feat(MustVerifyEmail): add markEmailAsNotVerified() by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58255\n* [12.x] Feat: add havingNotBetween && orHavingBetween && orHavingNotBetween by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58259\n* [12.x] Formatting by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58266\n* [12.x] Refactor: add |null in dock block by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58268\n* Add type guard for ChainedBatch/Queueable chained property before array_shift by [@cyppe](https://github.com/cyppe) in https://github.com/laravel/framework/pull/58264\n* [12.x] Add lang attributes to mail layout by [@DBawazir2002](https://github.com/DBawazir2002) in https://github.com/laravel/framework/pull/58274\n* [12.x] Clean up `Builder` docblocks by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/58270\n* [12.x] Run Mockery cleanup via PHPUnit subscriber instead of explicit `m::close()` calls by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/58278\n* [12.x] Fix delayed Redis queue jobs with phpredis serialization enabled by [@iazaran](https://github.com/iazaran) in https://github.com/laravel/framework/pull/58235\n* [12.x] Add missing return type to Arr::array() by [@mischasigtermans](https://github.com/mischasigtermans) in https://github.com/laravel/framework/pull/58280\n* [12.x] Add --readable flag to env:encrypt for visible key names by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/58262\n* [12.x] Update fake method parameter type for disk by [@murilo-plantae](https://github.com/murilo-plantae) in https://github.com/laravel/framework/pull/58285\n* [12.x] Fix typo in BelongsToMany::createOrFirst method name by [@mischasigtermans](https://github.com/mischasigtermans) in https://github.com/laravel/framework/pull/58284\n* [12.x] Fix nth(), split() and splitIn() to throw InvalidArgumentException for invalid parameters by [@mischasigtermans](https://github.com/mischasigtermans) in https://github.com/laravel/framework/pull/58283\n* [12.x] Fix Str::chopStart() and Str::chopEnd() returning empty string when given empty needle by [@mischasigtermans](https://github.com/mischasigtermans) in https://github.com/laravel/framework/pull/58286\n* [12.x] Add AsBinary castable class by [@plumthedev](https://github.com/plumthedev) in https://github.com/laravel/framework/pull/58254\n* [12.x] Add enum to `persistentFake()`- and add tests by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58287\n* Update Inspiring Qoute's author name by [@kerog](https://github.com/kerog) in https://github.com/laravel/framework/pull/58292\n* [12.x] Fix: add `@throws \\InvalidArgumentException` to some dock block by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/58289\n* [12.x] Fix `Validator::sometimes()` usage with attributes containing `.` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58291\n* [12.x] Support \"where subquery between values\"  by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/58290\n* Capture PDO read / write type for query events by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/58156\n\n## [v12.44.0](https://github.com/laravel/framework/compare/v12.43.1...v12.44.0) - 2025-12-23\n\n* [12.x] Allow easier opting out of `DatabaseLock` prune lottery by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58152\n* [12.x] Specify that the query builder returns instances of `stdClass` by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/58150\n* [12.x] feat: add now methods to Date rule by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/58059\n* [12.x] Add ability to run callbacks after building an Http response by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58088\n* Fix docblocks by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/58157\n* [12.x] Fix Password::required() missing value validation and nullable empty … by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/58158\n* [12.x] Fixup Eloquent `Collection` (param) docblocks by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58170\n* [12.x] add MigrationSkipped event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58167\n* [12.x] Simplify `LazyCollection` `passthru` calls and docblocks by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58180\n* [12.x] Add BusBatchable tests by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58175\n* Add previous locale to LocaleUpdated event by [@OutlawPlz](https://github.com/OutlawPlz) in https://github.com/laravel/framework/pull/58179\n* [12.x] Fix inline mail embed replacement by Content-ID by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/58173\n* [12.x] Fix multibyte string handling in chopStart and chopEnd by [@mdariftiens](https://github.com/mdariftiens) in https://github.com/laravel/framework/pull/58183\n* [12.x] Improve `Collection` docblock types by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58176\n* [12.x] Fix unable to disable `created_at` or `updated_at` column when attaching models by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58164\n* Remove unused variables from destructured arrays by [@rolfvandekrol](https://github.com/rolfvandekrol) in https://github.com/laravel/framework/pull/58187\n* [12.x] use process to trigger package uninstall event by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58177\n* [12.x] Fix null array key deprecation in HasOneOrMany relation matching by [@serhiilabs](https://github.com/serhiilabs) in https://github.com/laravel/framework/pull/58191\n* [12.x] Fix `Password::required()` and `Password::sometimes()` usage as array by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58188\n* [12.x] Add TestResponse::assertHeaderContains assertion and tests by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58200\n* [12.x] Update setup-node action to v6 by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58196\n\n## [v12.43.1](https://github.com/laravel/framework/compare/v12.43.0...v12.43.1) - 2025-12-16\n\n* [12.x] Only exclude Command ending with `Test` isn't an instance of `Command` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58147\n\n## [v12.43.0](https://github.com/laravel/framework/compare/v12.42.0...v12.43.0) - 2025-12-16\n\n* [12.x] Add PHPDoc callable types for BusFake methods by [@alies-dev](https://github.com/alies-dev) in https://github.com/laravel/framework/pull/58070\n* Improve type annotations of `$batchId` in `Batchable` trait by [@markieo1](https://github.com/markieo1) in https://github.com/laravel/framework/pull/58069\n* [12.x] Fix deadlock in cache_locks on cleanup by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58071\n* feat: implement 'assertFailedDependency' response assertion by [@artengin](https://github.com/artengin) in https://github.com/laravel/framework/pull/58061\n* [12.x] Fix using `null` cache store triggering PHP 8.5 deprecation by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58074\n* [12.x] Fix deprecated usage of passing `null` to `array_key_exists` in `AsPivot` class by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58073\n* [12.x] Simplify clearing resolved instances for `Facade` classes by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/58072\n* [12.x] Add PHP 8.5 with Herd to passthrough variables in ServeCommand by [@bashgeek](https://github.com/bashgeek) in https://github.com/laravel/framework/pull/58080\n* [12.x] Update actions/checkout v4 to v6 by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58078\n* [12.x] Let Storage::fake() accept enum as disk name by [@bbredewold](https://github.com/bbredewold) in https://github.com/laravel/framework/pull/58076\n* Improve PHPDoc return type for synchronous HTTP Client methods by [@khaled-sadek](https://github.com/khaled-sadek) in https://github.com/laravel/framework/pull/58090\n* [12.x] Adjust testCanRetrieveAllFailedJobs by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58096\n* [12.x] Allow Factory connection method to accept null by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58108\n* [12.x] Make PendingDispatch::afterResponse conditional by [@kenneth-saey](https://github.com/kenneth-saey) in https://github.com/laravel/framework/pull/58099\n* [12.x] Add `mergeHidden` and `mergeVisible` methods to Collection class by [@mahmoudmohamedramadan](https://github.com/mahmoudmohamedramadan) in https://github.com/laravel/framework/pull/58110\n* Added \"SSL error: unexpected eof\" message to LostConnectionDetector by [@GuidoHendriks](https://github.com/GuidoHendriks) in https://github.com/laravel/framework/pull/58113\n* [12.x] Update git-auto-commit action by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58118\n* [12.x] Add tests for Support Uri class by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58114\n* [12.x] Make the Client Response class tappable by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/58115\n* [12.x] Add missing docblock param in FailedOver event docblocks by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58123\n* [12.x] Clean up DynamoDbStore by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58116\n* [12.x] Fix: Handle `ParseError` in `hasEvenNumberOfParentheses` when Xdebug is active by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58128\n* [12.x] Fix Password::required() to fail when value is missing by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/58125\n* [12.x] Add HigherOrderProxy tests (Collection & Tap) by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58138\n* [12.x] Run `ConnectionEstablished` event on database reconnection by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58136\n\n## [v12.42.0](https://github.com/laravel/framework/compare/v12.41.1...v12.42.0) - 2025-12-09\n\n* [12.x] Improve `Context::scope()` return type by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58012\n* [12.x] Allow float values in duration helpers for CarbonInterval by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/58006\n* Add whenTableHasIndex and whenTableDoesntHaveIndex to Builder by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/58005\n* [12.x] Add commandFileFinder method and exclude test files from command discovery by [@davidhemphill](https://github.com/davidhemphill) in https://github.com/laravel/framework/pull/58017\n* [12.x] Fix Cache spy not working with memoized cache by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57996\n* Respect --quiet and --silent in queue:work command by [@MatusBoa](https://github.com/MatusBoa) in https://github.com/laravel/framework/pull/58024\n* [12.x] Improve Blueprint docblocks with concrete value ranges for integer and text columns by [@nguyentranchung](https://github.com/nguyentranchung) in https://github.com/laravel/framework/pull/58019\n* [12.x] Modernize typecasting by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58037\n* [12.x] Fix `required` and `sometimes` validation of `Password` rule by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/58034\n* [12.x] Add support as a depdency for container by [@adrum](https://github.com/adrum) in https://github.com/laravel/framework/pull/58026\n* fix autoloading StringableObjectStub class in tests/Support/SupportStringableTest.php by [@angus-mcritchie](https://github.com/angus-mcritchie) in https://github.com/laravel/framework/pull/58030\n* [12.x] Remove calls to `optional()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58027\n* [12.x] Add `newRequest()` to Pool and Batch by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58038\n* [12.x] Align Listener docblock and add unit test for query shape by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/58040\n* [12.x] feat: add pre-migration hook when setting up databases in parallel tests by [@philipheimboeck](https://github.com/philipheimboeck) in https://github.com/laravel/framework/pull/58011\n* [12.x] Supports PHPUnit 12.5 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58042\n* [12.x] Add support for Enums in Translator replacements by [@hosni](https://github.com/hosni) in https://github.com/laravel/framework/pull/58048\n* [12.x] Fix `PendingRequest@pool()` && `batch()` concurrency by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57973\n* [12.x] New `illuminate/reflections` component from `illuminate/support` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58052\n* Make queue commands' option descriptions more consistent by [@jasonlbeggs](https://github.com/jasonlbeggs) in https://github.com/laravel/framework/pull/58058\n* [12.x] Add LICENSE, auto close for PRs and `.gitattributes` to `illuminate/reflection` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/58055\n* [12.x] `PendingRequest@withRequestContext()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/58054\n\n## [v12.41.1](https://github.com/laravel/framework/compare/v12.41.0...v12.41.1) - 2025-12-03\n\n## [v12.41.0](https://github.com/laravel/framework/compare/v12.40.2...v12.41.0) - 2025-12-03\n\n* [12.x] Add `throwUnless()` to `Illuminate\\Http\\Client\\Response` by [@CasEbb](https://github.com/CasEbb) in https://github.com/laravel/framework/pull/57951\n* [12.x] Fix deprecation error in `HasAttributes::addDateAttributesToArray()` when `UPDATED_AT = null` and model is cast to array by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57945\n* [12.x] Reduce indentation in `PendingRequest@send()` with an early return by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57943\n* [12.x] PendingRequest HTTP methods may also return promises by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57941\n* [12.x] Fix unable to flush redis tagged cache when prefix contains `-` instead of `_` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57927\n* fix: hasMorph/whereDoesntHaveMorph OR grouping with nullable morphs by [@hannrei](https://github.com/hannrei) in https://github.com/laravel/framework/pull/57937\n* [12.x] Flush only active buffers while streaming response using a generator by [@vaishnavyogesh](https://github.com/vaishnavyogesh) in https://github.com/laravel/framework/pull/57952\n* Fix substrReplace to be multibyte safe by [@Nasim25](https://github.com/Nasim25) in https://github.com/laravel/framework/pull/57936\n* [12.x] fixes static analysis error by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57953\n* [12.x] Pass `LoggerInterface` when constructing `RoundrobinTransport` instance by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/57956\n* [12.x] Optimize cache and cache_locks timeout by [@chrisnetonline](https://github.com/chrisnetonline) in https://github.com/laravel/framework/pull/57966\n* [12.x] Introduce `FluentPromise` to allow for cleaner chaining in Pool by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57967\n* [12.x] Add Dependency in JsonSchema by [@pushpak1300](https://github.com/pushpak1300) in https://github.com/laravel/framework/pull/57942\n* Introduce `lazy` object and `proxy` object support helpers by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/57831\n* [12.x] Add reload command and allow services to register by [@barryvdh](https://github.com/barryvdh) in https://github.com/laravel/framework/pull/57923\n* [12.x] Ensure pretending flag is always reset in `pretend()` method by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/57968\n* [12.x] Always restore missing-attribute flag in `offsetExists()` by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/57970\n* [12.x] Fix Arr::first for ArrayObject and AsArrayObject values by [@prince-noman](https://github.com/prince-noman) in https://github.com/laravel/framework/pull/57969\n* [12.x] Use displayName() for custom job identification by [@hxnk](https://github.com/hxnk) in https://github.com/laravel/framework/pull/57499\n* [12.x] Expand Redis DurationLimiter tests by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/57947\n* [12.x] Fix grammar in event dispatcher comment by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/57983\n* Modernize email template by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57987\n* [12.x] Improve event types by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/57986\n* [12.x] Add ability to ignore queuePaused \\ queueShouldRestart cache checks by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57975\n* [12.x] Fix cache:clear command exit code on failure by [@alies-dev](https://github.com/alies-dev) in https://github.com/laravel/framework/pull/57988\n* Bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/57994\n* [12.x] Add `milliseconds`, `weeks`, and `months` duration helpers to `Illuminate\\Support` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/57997\n* [12.x] Add wildcard pattern support to TrimStrings middleware by [@overtrue](https://github.com/overtrue) in https://github.com/laravel/framework/pull/57982\n\n## [v12.40.2](https://github.com/laravel/framework/compare/v12.40.1...v12.40.2) - 2025-11-26\n\n* [12.x] Modernize type casting by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/57914\n* [12.x] Improve missing attribute violation callable typehints by [@mosabbirrakib](https://github.com/mosabbirrakib) in https://github.com/laravel/framework/pull/57910\n* [12.x] Improve discarded attribute violation callable typehints by [@mosabbirrakib](https://github.com/mosabbirrakib) in https://github.com/laravel/framework/pull/57909\n* [12.x] add support for no mode in postgres full text search by [@opheus2](https://github.com/opheus2) in https://github.com/laravel/framework/pull/57915\n* [12.x] Guard RedisStore::scan() results against boolean failures by [@CicerBro](https://github.com/CicerBro) in https://github.com/laravel/framework/pull/57911\n* [12.x] Fix CallQueuedClosure::displayName after batch chain (#57597) by [@CreareWorks](https://github.com/CreareWorks) in https://github.com/laravel/framework/pull/57881\n* Pass Laravel context through with schedule tasks by [@jradtilbrook](https://github.com/jradtilbrook) in https://github.com/laravel/framework/pull/57918\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57926\n* [12.x] Eloquent Builder: completion for HigherOrderBuilderProxy fields by [@adelf](https://github.com/adelf) in https://github.com/laravel/framework/pull/57928\n* [12.x] fix: continue route matching rather than returning second fallbackRoute by [@ryzr](https://github.com/ryzr) in https://github.com/laravel/framework/pull/57922\n* [12.x] Pause a queue for given seconds by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/57917\n* Json Schema Contract by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57934\n\n## [v12.40.1](https://github.com/laravel/framework/compare/v12.40.0...v12.40.1) - 2025-11-25\n\n* Add support for instant column additions by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57907\n\n## [v12.40.0](https://github.com/laravel/framework/compare/v12.39.0...v12.40.0) - 2025-11-25\n\n* [12.x] Improve return type of `Str::replace()` by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/57820\n* [12.x] Fixup PHP 8.5 deprecations in `SupportArrTest` by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/57822\n* Add daysOfMonth() method to schedule tasks on specific days by [@yousefkadah](https://github.com/yousefkadah) in https://github.com/laravel/framework/pull/57817\n* [12.x] Add `encoding` validation rule for uploaded files by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/57823\n* [12.x] Allow CachedState properties to be nullable by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57826\n* [12.x] Resolve failing encoding test  by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57827\n* [12.x] Fixing MemoizedStore with Redis Cluster by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57828\n* [12.x] Update encoding validation message by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57834\n* [12.x] Use `scopedIf` in `CacheManager::memo()` by [@angelej](https://github.com/angelej) in https://github.com/laravel/framework/pull/57833\n* [12.x] Fixing RedisTaggedCache::flushStale with PhpRedisClusterConnection by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57837\n* [12.x] Add default parameter support to `Request::fluent()` method by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/57840\n* [12.x] Fix embedded image Content-ID inconsistency in cloned emails by [@yinheli](https://github.com/yinheli) in https://github.com/laravel/framework/pull/57726\n* [12.x] PredisClusterConnection::keys() by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57841\n* [12.x] PHP 8.5 Compatibility by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57835\n* [12.x] RateLimiter remaining to 0 to prevent negative values. by [@Button99](https://github.com/Button99) in https://github.com/laravel/framework/pull/57851\n* [12.x] Update RequestException@report() to return false by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57847\n* Time by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57856\n* Feature/queue pause resume by [@yousefkadah](https://github.com/yousefkadah) in https://github.com/laravel/framework/pull/57800\n* [12.x] Fixing RedisTaggedCache::flushValues with PredisClusterConnection by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57848\n* [12.x] Improve typehints for `QueriesRelationships` by [@CasEbb](https://github.com/CasEbb) in https://github.com/laravel/framework/pull/57830\n* [12.x] Fix flaky test by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57864\n* [12.x] optimize `AbstractRouteCollection@toSymfonyRouteCollection()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57870\n* [12.x] optimize `AbstractRouteCollection@matchAgainstRoute()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57871\n* [12.x] Moving redis integration tests by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57860\n* [12.x] Incorrect result of MemoizedStore::many with numeric keys and empty prefix by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57862\n* [12.x] Add testWrapEdgeCases for Str::wrap edge cases by [@miladev95](https://github.com/miladev95) in https://github.com/laravel/framework/pull/57861\n* [12.x] Add parameter validation to Collection::sliding() method. by [@Button99](https://github.com/Button99) in https://github.com/laravel/framework/pull/57875\n* [12.x] Update `path` method return type to always be a non-null string by [@IsmailBourbie](https://github.com/IsmailBourbie) in https://github.com/laravel/framework/pull/57873\n* Added Google's antigravity IDE support in ResolvesDumpSource.php by [@yeasherarafath](https://github.com/yeasherarafath) in https://github.com/laravel/framework/pull/57885\n* [12.x] Clean up queue pausing by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57863\n* [12.x] Simplify `ParsesQueue@parseQueue` logic by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/57886\n* [12.x] Improve lazy loading violation callable typehints by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57896\n* [12.x] Fix Accept header cache invalidation when header is modified by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57874\n* [12.x] Fix flaky test in CacheArrayStore (increment) by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57905\n* [12.x] Fix flaky test in ArraySessionHandler (garbage collection) by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57904\n* [12.x] Fix flaky test in ArraySessionHandler (almost expired session) by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57903\n* [12.x] Fix flaky test in ArraySessionHandler (expired session) by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57902\n\n## [v12.39.0](https://github.com/laravel/framework/compare/v12.38.1...v12.39.0) - 2025-11-18\n\n* [12.x] `ApplicationBuilder@withExceptions()` improvements by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57778\n* Carry `--force` to `make:test` for generators with `--test` by [@CasEbb](https://github.com/CasEbb) in https://github.com/laravel/framework/pull/57777\n* [12.x] Fix `Request::getAcceptableContentTypes()` changes in Symfony 7.4 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57783\n* [12.x] Accept string bindings in give attribute by [@pjotrvdh](https://github.com/pjotrvdh) in https://github.com/laravel/framework/pull/57747\n* [12.x] Fix `WithCachedConfig` to work with parallel test runs by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57785\n* [12.x] Tailwind pagination styling/accessibility updates by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57793\n* [12.x] `RequestException`: attempt to summarize message before reporting by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57767\n* [12.x] create new `@hasStack` Blade directive by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57788\n* Add `--middleware` filter to `route:list` by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/57797\n* [12.x] Fix stale in-memory SQLite connections after re-migration in RefreshDatabase by [@PouyaPour](https://github.com/PouyaPour) in https://github.com/laravel/framework/pull/57716\n* [12.x] Type-hint the `ResourceCollection::$collection` property as nullable by [@lorenzolosa](https://github.com/lorenzolosa) in https://github.com/laravel/framework/pull/57807\n* [12.x] Fix `Factory@insert()` to allow for array casts by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57794\n* [12.x] Improve typehints for `Http::pool()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57811\n\n## [v12.38.1](https://github.com/laravel/framework/compare/v12.38.0...v12.38.1) - 2025-11-13\n\n* [12.x] Fix `GeneratorCommand` missing `possibleModels()` method by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57769\n\n## [v12.38.0](https://github.com/laravel/framework/compare/v12.37.0...v12.38.0) - 2025-11-12\n\n* [12.x] Cache the result of `configurationIsCached()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57665\n* [12.x] model:show command prompt for missing input with model suggestion by [@mrazinshaikh](https://github.com/mrazinshaikh) in https://github.com/laravel/framework/pull/57671\n* Don't call Model::toArray() to get attributes for factory insert by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/57670\n* [12.x] Introduce `WithCachedRoutes` testing trait by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57623\n* [12.x] Add missing separators to `Stringable::ucwords` by [@kichetof](https://github.com/kichetof) in https://github.com/laravel/framework/pull/57688\n* [12.x] Cache result of `Application@routesAreCached()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57687\n* fix phpdoc return of HasAttributes::getArrayAttributeWithValue by [@chuckadams](https://github.com/chuckadams) in https://github.com/laravel/framework/pull/57691\n* [12.x] Remove unnecessary imports from BackgroundQueue and DeferredQueue. by [@seriquynh](https://github.com/seriquynh) in https://github.com/laravel/framework/pull/57699\n* [12.x] add SQLite support for whereNotMorphedTo method by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57698\n* [12.x] Handle AWS ElasticCache failover by reconnecting when READONLY by [@wsamoht](https://github.com/wsamoht) in https://github.com/laravel/framework/pull/57685\n* [12.x] Introduce `WithCachedConfig` testing trait by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57663\n* [12.x] Fix WithCachedConfig@tearDownWithCachedConfig() by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57708\n* [12.x] Reorder some core aliases in alphabetical order. by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/57706\n* Allow Resend ^1.0 by [@ziming](https://github.com/ziming) in https://github.com/laravel/framework/pull/57713\n* [12.x] memoize result of `Application@eventsAreCached()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57709\n* [12.x] Test `Factory@insert()` with hidden by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57722\n* [12.x] Separate workflow for Redis integration tests by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57710\n* [12.x] Types: HasDatabaseNotifications read/unread notifications by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/57718\n* [12.x] Supports Symfony 7.4 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57724\n* [12.x] Revert lowercasing validation message placeholders by [@florianraith](https://github.com/florianraith) in https://github.com/laravel/framework/pull/57733\n* [12.x] try another way to activate Broadcast routes by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57734\n* [12.x] Add environment information to json output of schedule:list command by [@mmachatschek](https://github.com/mmachatschek) in https://github.com/laravel/framework/pull/57741\n* [12.x] Make DumpCommand prohibitable by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57735\n* [12.x] Clean ConsoleApplicationTest by [@seriquynh](https://github.com/seriquynh) in https://github.com/laravel/framework/pull/57761\n* [12.x] Fix the docblock of the BroadcastManager::purge method. by [@seriquynh](https://github.com/seriquynh) in https://github.com/laravel/framework/pull/57758\n* [12.x] Fix setting request exception truncating doesn't work on HTTP layer when configured inside `bootstrap/app.php` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57759\n\n## [v12.37.0](https://github.com/laravel/framework/compare/v12.36.1...v12.37.0) - 2025-11-04\n\n* [12.x] allow passing custom \"depth\" to `files()` and `directories()` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57573\n* [12.x] EnumerateValues::value() support objects and return negative values by [@rafaelqueiroz](https://github.com/rafaelqueiroz) in https://github.com/laravel/framework/pull/57570\n* [12.x] Move duplicated logic to separate method to be reusable by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/57564\n* [12.x] Refactor unreleased data_has helper by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/57580\n* feat: added detailed about for cache failover driver by [@chinmaypurav](https://github.com/chinmaypurav) in https://github.com/laravel/framework/pull/57579\n* [12.x] fix data_has empty check by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/57586\n* [12.x] Fix: use trim before check empty string by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/57583\n* feat: added detailed about for queue failover driver by [@chinmaypurav](https://github.com/chinmaypurav) in https://github.com/laravel/framework/pull/57582\n* Feat: add mailers detail for failover or roundrobin by [@chinmaypurav](https://github.com/chinmaypurav) in https://github.com/laravel/framework/pull/57590\n* [12.x] Refactor: remove un use var by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/57617\n* [12.x] `Factory@insert()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57600\n* Fix ScheduleRunCommandTest failure on Windows by using OS-specific success command by [@Tina-1300](https://github.com/Tina-1300) in https://github.com/laravel/framework/pull/57621\n* [12.x] Add ucwords to Str and Stringable by [@braxey](https://github.com/braxey) in https://github.com/laravel/framework/pull/57581\n* [12.x] improve `Connection@listen()` docblock by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57633\n* [12.x] Fix: Correctly fallback to notification's connection/queue when using viaConnections/viaQueues by [@aydinfatih](https://github.com/aydinfatih) in https://github.com/laravel/framework/pull/57625\n* [12.x] Remove unused closure parameters in DatabaseServiceProvider by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57644\n* [12.x] Queue tests for Redis Cluster missing QUEUE_CONNECTION by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57641\n* refactor: remove unused parameter in ArtisanServiceProvider by [@omarchouman](https://github.com/omarchouman) in https://github.com/laravel/framework/pull/57658\n* [12.x] Ensure custom validation messages work for the File rule by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57656\n* Feature/json schema improvements by [@Anticom](https://github.com/Anticom) in https://github.com/laravel/framework/pull/57609\n* Process queue jobs in background (Concurrently::defer()) by [@barryvdh](https://github.com/barryvdh) in https://github.com/laravel/framework/pull/57648\n* [12.x] ChainedBatch keeps queue and connection of wrapped batch by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/57630\n\n## [v12.36.1](https://github.com/laravel/framework/compare/v12.36.0...v12.36.1) - 2025-10-29\n\n* [12.x] EnumerateValues::value() support and return negative values if exists #54910 by [@rafaelqueiroz](https://github.com/rafaelqueiroz) in https://github.com/laravel/framework/pull/57566\n* [12.x] always use the `operator` argument for `version_compare()` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57569\n* [12.x] add `allDirectories()` method to `Filesytem` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57565\n* Revert \"[12.x] EnumerateValues::value() support and return negative values if exists #54910\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57572\n\n## [v12.36.0](https://github.com/laravel/framework/compare/v12.35.1...v12.36.0) - 2025-10-28\n\n* [12.x] Remove return void from Http\\Client\\Batch's constructor by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/57518\n* [12.x] Namespace file cache lock keys by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57516\n* [12.x] Remove [@return](https://github.com/return) tag from constructor by [@noir4y](https://github.com/noir4y) in https://github.com/laravel/framework/pull/57536\n* [12.x] Add missing [@throws](https://github.com/throws) annotation by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57535\n* [12.x] allow chaining on setters by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57532\n* [12.x] Stop double prefixing S3 filesystem paths by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57534\n* [12.x] test `Uri` builder methods by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57549\n* [12.x] Refactor `jsonSerialize()` method to use match expression by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/57552\n* [12.x] redirect response enforce same origin by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57533\n* [12.x] Add Eloquent Collection methods: `setAppends` && `withoutAppends` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57561\n* [12.x] Fix buffer overflow when flushing Redis cache tags with many keys by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57562\n* [12.x] Allow validator message placeholers to be capitalized by [@florianraith](https://github.com/florianraith) in https://github.com/laravel/framework/pull/57556\n* Exclude property hooks on return of Model::__sleep() by [@rafaelqueiroz](https://github.com/rafaelqueiroz) in https://github.com/laravel/framework/pull/57557\n* [12.x] Add concurrency control to Http::pool and Http::batch by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/57555\n\n## [v12.35.1](https://github.com/laravel/framework/compare/v12.35.0...v12.35.1) - 2025-10-23\n\n* Store previous route name in session by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57477\n* [12.x] Update CSS in minimal exception view. by [@FoksVHox](https://github.com/FoksVHox) in https://github.com/laravel/framework/pull/57490\n* [12.x] Ensure HTTP batch results are returned in the same order as requested by [@jessarcher](https://github.com/jessarcher) in https://github.com/laravel/framework/pull/57483\n* [12.x] Correct `Response` namespace in `Batch` by [@simon-tma](https://github.com/simon-tma) in https://github.com/laravel/framework/pull/57481\n* [12.x] Rename NamedScope to Scope by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57478\n* Fix S3 adapter to use correct path separator and update related tests by [@Kleppinger](https://github.com/Kleppinger) in https://github.com/laravel/framework/pull/57497\n* [12.x] Replace Bootcamp with Laravel Learn by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57506\n* [12.x] Pass exception to `QueueFailedOver` event by [@jessarcher](https://github.com/jessarcher) in https://github.com/laravel/framework/pull/57503\n* [12.x] Add warning when server workers cannot be respected by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/57482\n* [12.x] Emit underlying store name in cache events when using failover by [@jessarcher](https://github.com/jessarcher) in https://github.com/laravel/framework/pull/57505\n\n## [v12.35.0](https://github.com/laravel/framework/compare/v12.34.0...v12.35.0) - 2025-10-21\n\n* [12.x] Fix `DB::update()` with subqueries is not supported for all databases by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57381\n* [12.x] Ensure custom validation messages work for AnyOf, Can and Enum by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57356\n* Added Neovim editor support in ResolvesDumpSource by [@cseknowledge](https://github.com/cseknowledge) in https://github.com/laravel/framework/pull/57392\n* Add clickable file reference for thrown exception by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/57400\n* [12.x] Render newlines in query tooltip by [@faisuc](https://github.com/faisuc) in https://github.com/laravel/framework/pull/57310\n* [12.x] Add SQS FIFO and fair queue messageGroup() method support by [@patrickcarlohickman](https://github.com/patrickcarlohickman) in https://github.com/laravel/framework/pull/57421\n* [12.x] Use MariaDB idiomatic `json_value()` by [@crishoj](https://github.com/crishoj) in https://github.com/laravel/framework/pull/57417\n* Deferred queue by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57428\n* Fix validate integer php doc type annotation by [@tei0110](https://github.com/tei0110) in https://github.com/laravel/framework/pull/57435\n* [12.x] Fix passing countable to Number::format() by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/57434\n* [12.x] Update `Route::middleware` to accept null by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/57436\n* Only replace first basePath occurrence in dump source href by [@fritz-c](https://github.com/fritz-c) in https://github.com/laravel/framework/pull/57458\n* [12.x] Add missing [@throws](https://github.com/throws) annotations to Encrypter class by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57451\n* [12.x] Add missing [@throws](https://github.com/throws) annotations to Database Connection class by [@sumaiazaman](https://github.com/sumaiazaman) in https://github.com/laravel/framework/pull/57452\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57461\n* Prevent TypeError in validateDigits when attribute value is an array by [@elyass-dehghan](https://github.com/elyass-dehghan) in https://github.com/laravel/framework/pull/57471\n* Bump vite from 7.1.6 to 7.1.11 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/57460\n* Failover cache by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57430\n* Must collect the unparsed event and payload when deferring events by [@moshe-autoleadstar](https://github.com/moshe-autoleadstar) in https://github.com/laravel/framework/pull/57453\n\n## [v12.34.0](https://github.com/laravel/framework/compare/v12.33.0...v12.34.0) - 2025-10-14\n\n* [12.x] PostgreSQL virtual columns by [@tpetry](https://github.com/tpetry) in https://github.com/laravel/framework/pull/57290\n* [12.x] Make Vite asset path generation extendable via inheritance by [@daun](https://github.com/daun) in https://github.com/laravel/framework/pull/57292\n* [12.x] Improve `Str` docblocks related to factories by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57297\n* Add missing waitUntil method to FakeInvokedProcess by [@yondifon](https://github.com/yondifon) in https://github.com/laravel/framework/pull/57030\n* Add support for Zed Editor in ResolvesDumpSource by [@miguilimzero](https://github.com/miguilimzero) in https://github.com/laravel/framework/pull/57298\n* [12.x] Remove leftover workaround by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57306\n* Fix return type order in view function signature by [@MadBox-99](https://github.com/MadBox-99) in https://github.com/laravel/framework/pull/57304\n* Adds support for `Trae IDE` in the local exception page by [@sajjadhossainshohag](https://github.com/sajjadhossainshohag) in https://github.com/laravel/framework/pull/57300\n* [12.x] Add enum support to `Schedule::useCache()` by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/57311\n* [12.x] Fix remaining PHP 8.5 null index array deprecations by [@IonBazan](https://github.com/IonBazan) in https://github.com/laravel/framework/pull/57308\n* Regenerate session during Auth::login() by [@valorin](https://github.com/valorin) in https://github.com/laravel/framework/pull/57204\n* [12.x] Formatting by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57321\n* Update text color in minimal error view to ensure better accessibility by [@FoksVHox](https://github.com/FoksVHox) in https://github.com/laravel/framework/pull/57318\n* [12.x] Fix text truncation on syntax-highlighted queries by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/57315\n* [12.x] Fix email rule helper message by [@erik-perri](https://github.com/erik-perri) in https://github.com/laravel/framework/pull/57323\n* [12.x] Do not assume `Str::uuid()` returns `Stringable` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57340\n* [12.x] Add missing [@throws](https://github.com/throws) annotation to Arr by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57336\n* [12.x] Use FQCN in docblocks by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57335\n* [12.x] feat: Support custom response without modifying the exception handler by [@chuoke](https://github.com/chuoke) in https://github.com/laravel/framework/pull/57342\n* [12.X] add support for windsurf IDE in ResolvesDumpSource by [@Sajid-al-islam](https://github.com/Sajid-al-islam) in https://github.com/laravel/framework/pull/57359\n* [12.x] Expand single-line array into multiline by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57350\n* [12.x] Added Kiro editor support in `ResolvesDumpSource`  by [@OmarFaruk-0x01](https://github.com/OmarFaruk-0x01) in https://github.com/laravel/framework/pull/57363\n* [12.x] fix schedule list cli format in multibye locale by [@jamessa](https://github.com/jamessa) in https://github.com/laravel/framework/pull/57367\n* Prototype failover queue by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57341\n* Add support for Fleet editor in ResolvesDumpSource by [@Rakib01](https://github.com/Rakib01) in https://github.com/laravel/framework/pull/57377\n* Allow closures when calling throw_if by [@chrispage1](https://github.com/chrispage1) in https://github.com/laravel/framework/pull/57349\n* [12.x] Add defer method to HTTP batch by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/57387\n* [12.x] Supports PHPUnit 12.4 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57388\n* [12.x] Http::batch - fix issue that non valid URL not triggering catch hook by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/57386\n\n## [v12.33.0](https://github.com/laravel/framework/compare/v12.32.5...v12.33.0) - 2025-10-07\n\n* Fix compiling queries that use orderByRaw with expressions by [@LukeTowers](https://github.com/LukeTowers) in https://github.com/laravel/framework/pull/57228\n* [12.x] Narrow type after `Str::is*(...)` check by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/57230\n* [12.x] Fix invalid docblock by [@tm1000](https://github.com/tm1000) in https://github.com/laravel/framework/pull/57240\n* [12.x] Refactor switch to match by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/57236\n* [12.x] Refactor switch to match by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/57237\n* [12.x] Fix rounded issue in exception frame component by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57239\n* [12.x] Ensure calling job within a group works as expected by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57224\n* fix: remove duplicated word in `Str::apa` method by [@balboacodes](https://github.com/balboacodes) in https://github.com/laravel/framework/pull/57254\n* refactor: add |null in docblock by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/57253\n* [12.x] Improve `php artisan config:cache` and `php artisan optimize` error messages for non-serializable values by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/57249\n* [12.x] Ensure cookie lifetime matches session lifetime in StartSession middleware by [@michaelcontento](https://github.com/michaelcontento) in https://github.com/laravel/framework/pull/57266\n* Run tests on PostgreSQL version 18 by [@JurianArie](https://github.com/JurianArie) in https://github.com/laravel/framework/pull/57232\n* [12x.] reduce repeated inserts in tests by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57273\n* [12.x] Fix using pushIf blade directive with complex conditions (#57264) by [@hosni](https://github.com/hosni) in https://github.com/laravel/framework/pull/57274\n* [12.x] Add Stringable::doesntContain() to match API symmetry by [@michaelcontento](https://github.com/michaelcontento) in https://github.com/laravel/framework/pull/57279\n* [12.x] Improve BroadcastManager error messages when trying to get a Broadcaster by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/57275\n* [12.x] HTTP Client: add mergeUrlParameters() to combine URL parameters without overwriting by [@leek](https://github.com/leek) in https://github.com/laravel/framework/pull/57282\n\n## [v12.32.5](https://github.com/laravel/framework/compare/v12.32.4...v12.32.5) - 2025-09-30\n\n## [v12.32.4](https://github.com/laravel/framework/compare/v12.32.3...v12.32.4) - 2025-09-30\n\n* [12.x] Use `Container::getInstance()` in `ComposerScripts::prePackageUninstall()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57226\n\n## [v12.32.3](https://github.com/laravel/framework/compare/v12.32.2...v12.32.3) - 2025-09-30\n\n* [12.x] Define LARAVEL_START if not already defined by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57222\n* [12.x] Clean up redundant type hints in docblocks by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57219\n\n## [v12.32.2](https://github.com/laravel/framework/compare/v12.32.1...v12.32.2) - 2025-09-30\n\n## [v12.32.1](https://github.com/laravel/framework/compare/v12.32.0...v12.32.1) - 2025-09-30\n\n* [13.x] Fix scopedBy attribute not following inheritance chain by [@Muffinman](https://github.com/Muffinman) in https://github.com/laravel/framework/pull/57213\n* [12.x] Fix AWS S3 adapter's constructor not allowing decorated adapter instances by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57217\n\n## [v12.32.0](https://github.com/laravel/framework/compare/v12.31.1...v12.32.0) - 2025-09-30\n\n* [12.x] fix static analysis error  by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57162\n* Fix: Handle non-string returns from Htmlable::toHtml() in e() helper by [@Carnicero90](https://github.com/Carnicero90) in https://github.com/laravel/framework/pull/57157\n* [12.x] Fix pending attributes in schedule group by [@jamessa](https://github.com/jamessa) in https://github.com/laravel/framework/pull/57156\n* Remove Request overview from Exceptions by [@barryvdh](https://github.com/barryvdh) in https://github.com/laravel/framework/pull/57158\n* [12.x] Pass \"throw\" option from scoped to parent disk by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57163\n* [12.x] Make docblock return type in line with actual return type by [@parijke](https://github.com/parijke) in https://github.com/laravel/framework/pull/57164\n* [12.x] Adjust `Arr` typehints by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57165\n* [12.x] Track filesystem adapter decoration by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57167\n* [12.x] Batch Job Failure Callbacks Support by [@yitzwillroth](https://github.com/yitzwillroth) in https://github.com/laravel/framework/pull/55916\n* [12.x] Fix operator precedence by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57169\n* [12.x] Clean up after filesystem manager tests by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57168\n* Fix: Improve validateInteger ergonomics and fix BC break by [@ntm-dev](https://github.com/ntm-dev) in https://github.com/laravel/framework/pull/57175\n* [12.x] Fix nested `can` and inherit models on route groups by [@bonroyage](https://github.com/bonroyage) in https://github.com/laravel/framework/pull/57172\n* [12.x] Syntax highlight on the frontend by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/57184\n* [12.x] Add missing Closure type to Collection::pluck() docblock  by [@Bariss61](https://github.com/Bariss61) in https://github.com/laravel/framework/pull/57178\n* Add database afterRollback callback support and tests by [@maltekuhr](https://github.com/maltekuhr) in https://github.com/laravel/framework/pull/57180\n* fix: add return type by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/57192\n* [12.x] Adds support enums for `ThrottleRequests::using` method by [@sethsandaru](https://github.com/sethsandaru) in https://github.com/laravel/framework/pull/57190\n* [12.x] Introduce \"after\" rate limiting by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/57125\n* [12.x] Json schema nullable by [@Katalam](https://github.com/Katalam) in https://github.com/laravel/framework/pull/57181\n* [12.x] Dispatch framework events on composer `pre-package-uninstall` event by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57144\n* [12.x] Add Http::batch by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/56946\n* [12.x] [Mail] Update `queue` PHPDoc according to function behavior by [@MrYamous](https://github.com/MrYamous) in https://github.com/laravel/framework/pull/57207\n* [12.x] Remove unnecessary parentheses by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57212\n* [12.x] Remove unnecessary parentheses by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57210\n* [12.x] Fixes error renderer report page by [@xiCO2k](https://github.com/xiCO2k) in https://github.com/laravel/framework/pull/57208\n* [12.x] Extend SQS FIFO and fair queue support by [@patrickcarlohickman](https://github.com/patrickcarlohickman) in https://github.com/laravel/framework/pull/57187\n\n## [v12.31.1](https://github.com/laravel/framework/compare/v12.31.0...v12.31.1) - 2025-09-23\n\n* Revert \"[12.x] Reintroduce short-hand \"false\" syntax for Blade component props\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57151\n\n## [v12.31.0](https://github.com/laravel/framework/compare/v12.30.1...v12.31.0) - 2025-09-23\n\n* Bump vite from 7.1.2 to 7.1.6 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/57114\n* [12.x] Reintroduce short-hand \"false\" syntax for Blade component props by [@PerryvanderMeer](https://github.com/PerryvanderMeer) in https://github.com/laravel/framework/pull/57104\n* [12.x] Allow Number parse helpers to return false by [@platoindebugmode](https://github.com/platoindebugmode) in https://github.com/laravel/framework/pull/57127\n* [12.x] Refactor `RedisTaggedCache@flush()` to allow for custom connections by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/57122\n* [12.x] Use light-dark scheme for exception renderer by [@pxlrbt](https://github.com/pxlrbt) in https://github.com/laravel/framework/pull/57128\n* [12.x] Replace logger helper and log function concrete return type ?LogManager with abstract ?LoggerInterface by [@abdelrahmenAyman](https://github.com/abdelrahmenAyman) in https://github.com/laravel/framework/pull/57028\n* [12.x] Fix session value is missing assertion by [@barclaymichael](https://github.com/barclaymichael) in https://github.com/laravel/framework/pull/57134\n* median() div swapped for intdiv() by [@artumi-richard](https://github.com/artumi-richard) in https://github.com/laravel/framework/pull/57148\n* [12.x] Fix PHP 8.5 null-key deprecations by [@IonBazan](https://github.com/IonBazan) in https://github.com/laravel/framework/pull/57137\n\n## [v12.30.1](https://github.com/laravel/framework/compare/v12.30.0...v12.30.1) - 2025-09-18\n\n* [12.x] Fix: Apply intl extension check to ordinal position to prevent issues by [@BinaryKitten](https://github.com/BinaryKitten) in https://github.com/laravel/framework/pull/57112\n\n## [v12.30.0](https://github.com/laravel/framework/compare/v12.29.0...v12.30.0) - 2025-09-18\n\n* [12.x] Allow newer versions for phiki/phiki than 2.0.0 by [@hebbet](https://github.com/hebbet) in https://github.com/laravel/framework/pull/57075\n* [12.x] Use null coalescing for memoryExceededExitCode by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57090\n* [12.x] Fix 'can' function that was defined in RouterRegistrar in #54648 by [@pdewit](https://github.com/pdewit) in https://github.com/laravel/framework/pull/57072\n* [12.x] Fix SQS FIFO and fair queue support by [@patrickcarlohickman](https://github.com/patrickcarlohickman) in https://github.com/laravel/framework/pull/57080\n* atomically flush redis cache tags by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57098\n* [12.x] Add type hints to `\\Illuminate\\Support\\Str` by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/57096\n* Doc: Update Database Connection getElapsedTime comment to specify unit by [@glensc](https://github.com/glensc) in https://github.com/laravel/framework/pull/57099\n* [12.x] Add support for Ordinal Position in validation messages by [@BinaryKitten](https://github.com/BinaryKitten) in https://github.com/laravel/framework/pull/57109\n* [12.x] Fix exception frame file path on Windows by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/57103\n* Add fallback to copy buttons on new exception page by [@joaokamun](https://github.com/joaokamun) in https://github.com/laravel/framework/pull/57092\n* [12.x] Adds `Macroable` trait to `Illuminate/Support/Benchmark` by [@1tim22](https://github.com/1tim22) in https://github.com/laravel/framework/pull/57107\n\n## [v12.29.0](https://github.com/laravel/framework/compare/v12.28.1...v12.29.0) - 2025-09-16\n\n* Ensure cached and uncached routes share same precedence when resolving actions and names by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/56920\n* [12.x] Re-enable previously commented assertions by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56930\n* [12.x] Reorder .gitignore entries for consistency and readability by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56963\n* [12.x] SQLite: Allow setting any pragmas by [@stancl](https://github.com/stancl) in https://github.com/laravel/framework/pull/56962\n* refactor: remove unused array from docblock by [@alipowerful7](https://github.com/alipowerful7) in https://github.com/laravel/framework/pull/56961\n* PendingResourceRegistration withoutMiddleware never returns array by [@moshe-autoleadstar](https://github.com/moshe-autoleadstar) in https://github.com/laravel/framework/pull/56959\n* [12.x] Allow not having \"fakerphp/faker\" installed by [@SjorsO](https://github.com/SjorsO) in https://github.com/laravel/framework/pull/56953\n* [12.x] Fix Validator placeholderHash PHPDoc by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56947\n* [12.x] Handle MariaDB innodb_snapshot_isolation=ON by [@Muffinman](https://github.com/Muffinman) in https://github.com/laravel/framework/pull/56945\n* [12.x] Add PhpRedis pack ignore numbers option by [@tuandp](https://github.com/tuandp) in https://github.com/laravel/framework/pull/56941\n* test(support): add edge-case tuples for preg_replace_array by [@realpvz](https://github.com/realpvz) in https://github.com/laravel/framework/pull/56937\n* [12.x] Allow for BackedEnum on dynamic blade component by [@gehrisandro](https://github.com/gehrisandro) in https://github.com/laravel/framework/pull/56940\n* [12.x] Remove one redundant array access by [@vincentvanhoven](https://github.com/vincentvanhoven) in https://github.com/laravel/framework/pull/56931\n* [12.x] Add withoutGlobalScopesExcept() to keep only specified global scopes by [@theHocineSaad](https://github.com/theHocineSaad) in https://github.com/laravel/framework/pull/56957\n* [12.x] Make visibility consistent by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56970\n* [12.x] Change list to tuple in PHPDoc block by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/56967\n* [12.x] Improve `AggregateServiceProvider` docblocks by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56968\n* [12.x] add --whisper option to schedule:work command by [@thojo0](https://github.com/thojo0) in https://github.com/laravel/framework/pull/56969\n* [12.x] Update Faker suggestion to match skeleton version by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56974\n* Refactor: use str_contains() instead of strpos() for clarity by [@arshidkv12](https://github.com/arshidkv12) in https://github.com/laravel/framework/pull/56979\n* [12.x] remove unnecessary `with()` helper call by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56975\n* [12.x] Config: Move some items into pragmas by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56980\n* Add callback support to takeUntilTimeout in LazyCollection by [@kamilkozak](https://github.com/kamilkozak) in https://github.com/laravel/framework/pull/56981\n* [12.x] Utilize the is_finite() PHP function by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56990\n* [12.x] Use property promotion in `MessageLogged` and narrow `$level` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56989\n* [12.x] do not use `with()` helper when no second argument is passed by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56986\n* [12.x] Correct the type of $handler from Connection::whenQueryingForLongerThan by [@sethsandaru](https://github.com/sethsandaru) in https://github.com/laravel/framework/pull/56987\n* [12.x] Some quick fixes by [@theHocineSaad](https://github.com/theHocineSaad) in https://github.com/laravel/framework/pull/56991\n* tests: Ensure transaction callbacks run in FIFO order by [@realpvz](https://github.com/realpvz) in https://github.com/laravel/framework/pull/56973\n* Pass $attributes and $parent arguments to Factory Sequence by [@fritz-c](https://github.com/fritz-c) in https://github.com/laravel/framework/pull/56972\n* [12.x] - Support `Castable` on `Enum` by [@jrseliga](https://github.com/jrseliga) in https://github.com/laravel/framework/pull/56977\n* [12.x] add trailing commas in multiline method signatures by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56992\n* [12.x] Improve docblocks for nullable parameters by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56995\n* [12.x] Improve docblocks for nullable parameters by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56996\n* [12.x] Improve docblocks for nullable parameters by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56997\n* Revert \"[12.x] Config: Move some items into pragmas\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/57003\n* [12.x]: Cache Session Driver by [@joaopalopes24](https://github.com/joaopalopes24) in https://github.com/laravel/framework/pull/56887\n* [12.x] Add support for #[UseResource(...)] and #[UseResourceCollection(...)] attributes on models by [@Lukasss93](https://github.com/Lukasss93) in https://github.com/laravel/framework/pull/56966\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57010\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/57031\n* [12.x] Infinite method chaining in contextual binding builder by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57026\n* [12.x] Improved manager typehints by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/57024\n* Bump vite from 5.4.19 to 5.4.20 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/57009\n* [12.x] Correct APC cache store docblock types by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/57020\n* [12.x] Enable dynamic tries() method on Queueable Listeners by [@glioympas](https://github.com/glioympas) in https://github.com/laravel/framework/pull/57014\n* [12.x] Add --json option to ScheduleListCommand by [@dxnter](https://github.com/dxnter) in https://github.com/laravel/framework/pull/57006\n* [12.x] `with()` helper call simplification by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57041\n* [12.x] handle all Enum types for default values by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/57040\n* [12.x] Refactor chained method calls for readability by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57050\n* [12.x] Improve docblock wording by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57056\n* [12.x] Refactor chained method calls for readability by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/57054\n* [12.x] Update local exception page by [@avosalmon](https://github.com/avosalmon) in https://github.com/laravel/framework/pull/57036\n* [12.x] Add ability to control QueueWorker memory exceeded exit code by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/57044\n* [12.x] Ensure `laravel-cloud-socket` respects `LOG_LEVEL` by [@PeteBishwhip](https://github.com/PeteBishwhip) in https://github.com/laravel/framework/pull/57071\n\n## [v12.28.1](https://github.com/laravel/framework/compare/v12.28.0...v12.28.1) - 2025-09-04\n\n* [12.x] Rename `group` to `messageGroup` property by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56919\n* Fix PHP_CLI_SERVER_WORKERS inside laravel/sail by [@akyrey](https://github.com/akyrey) in https://github.com/laravel/framework/pull/56923\n* Allow RouteRegistrar to be Macroable by [@moshe-autoleadstar](https://github.com/moshe-autoleadstar) in https://github.com/laravel/framework/pull/56921\n* [12.x] Fix SesV2Transport docblock by [@dwightwatson](https://github.com/dwightwatson) in https://github.com/laravel/framework/pull/56917\n* [12.x] Prevent unnecessary query logging on exceptions with a custom renderer by [@luanfreitasdev](https://github.com/luanfreitasdev) in https://github.com/laravel/framework/pull/56874\n* [12.x] Reduce meaningless intermediate variables by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56927\n\n## [v12.28.0](https://github.com/laravel/framework/compare/v12.27.1...v12.28.0) - 2025-09-03\n\n* [11.x] Correct how base options for missing config files are preloaded by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/framework/pull/56216\n* [11.x] backport #56235 by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56236\n* [11.x] Consistent use of `mb_split()` to split strings into words by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56617\n* [11.x] `CacheSchedulingMutex` should use lock connection by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56614\n* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56630\n* [11.x] Update `orchestra/testbench-core` deps by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56636\n* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56649\n* [11.x] Fix exception page not preparing SQL bindings by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56651\n* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56849\n* [11.x] Chore: Decouple Str::random() from Validator by [@michaeldyrynda](https://github.com/michaeldyrynda) in https://github.com/laravel/framework/pull/56852\n* [11.x] Allow a wider range of `brick/math` versions by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56890\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56894\n* [12.x] Switch back to ternaries in `DatabaseManager` to allow for empty named connections by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56906\n* [12.x] Update config/database.php to match the latest skeleton configuration by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56905\n* Update fluent() helper by [@tanthammar](https://github.com/tanthammar) in https://github.com/laravel/framework/pull/56900\n* [12.x] Add method to retrieve the command on InvokedProcess by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/56886\n* [12.x] provide a default slot name when compiling by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56883\n* [12.x] Allow enums on model connection property and methods by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56896\n* [12.x] Adds internal class by [@nunomaduro](https://github.com/nunomaduro) in https://github.com/laravel/framework/pull/56903\n\n## [v12.27.1](https://github.com/laravel/framework/compare/v12.27.0...v12.27.1) - 2025-09-02\n\n* [12.x] Allow a wider range of `brick/math` versions by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56891\n* [12.x] Fix secure_url() breaking changes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56885\n\n## [v12.27.0](https://github.com/laravel/framework/compare/v12.26.4...v12.27.0) - 2025-09-02\n\n* [12.x] Add prepend option for Str::plural() by [@caseydwyer](https://github.com/caseydwyer) in https://github.com/laravel/framework/pull/56802\n* [12.x] Fix multi-line embedded image replacement in mail views by [@iammursal](https://github.com/iammursal) in https://github.com/laravel/framework/pull/56828\n* [12.x] Add supports for SQS Fair Queue by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56763\n* [12.x] Support enum values in `Collection` `countBy` method by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56830\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56838\n* [12.x] Fix docblocks and all() method in ArrayStore for consistency by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56845\n* [12.x] Improve Grammar in ArrayLock by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56844\n* [12.x] Normalize comments for timestampsTz() and nullableTimestampsTz() by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56840\n* [12.x] Reduce meaningless intermediate variables by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56843\n* [12.x] Simpler and consistent `Arr::collapse()` by [@weshooper](https://github.com/weshooper) in https://github.com/laravel/framework/pull/56842\n* [12.x] Improving readability by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56847\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56850\n* [12.x] Remove extra space before line number in exception trace by [@mtbossa](https://github.com/mtbossa) in https://github.com/laravel/framework/pull/56863\n* [12.x] Remove unused variable by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56861\n* [12.x] Add support for `UnitEnum` in `Collection` `groupBy` method by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56857\n* [12.x] Add missing void return type to test methods by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56860\n* [12.x] Improve `countBy` docblock in `Collection` to allow for enum callback by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56856\n* [12.x] Improve `InteractsWithContainer` return types by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/56853\n* [12.x] Allow mass assignment for value object casting. by [@AbdelElrafa](https://github.com/AbdelElrafa) in https://github.com/laravel/framework/pull/56871\n* [12.x] Allows `APP_BASE_PATH` from `$_SERVER` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56868\n* [12.x] Fix typo in docblock by [@dwightwatson](https://github.com/dwightwatson) in https://github.com/laravel/framework/pull/56867\n* [12.x] Allow enums in other DatabaseManager methods by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56878\n* Add health score badge to README by [@jonathimer](https://github.com/jonathimer) in https://github.com/laravel/framework/pull/56875\n* [12.x] Let `toPrettyJson()` accepts options by [@lucasmichot](https://github.com/lucasmichot) in https://github.com/laravel/framework/pull/56876\n\n## [v12.26.4](https://github.com/laravel/framework/compare/v12.26.3...v12.26.4) - 2025-08-29\n\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56792\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56794\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56795\n* [12.x] Add support for nested array notation within `loadMissing` by [@angus-mcritchie](https://github.com/angus-mcritchie) in https://github.com/laravel/framework/pull/56711\n* [12.x] Colocate Container build functions with the `SelfBuilding` interface by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56731\n* perf: optimize loop performance by pre-calculating array counts in Str::apa() and fileSize() methods by [@AmadulHaque](https://github.com/AmadulHaque) in https://github.com/laravel/framework/pull/56796\n* fix: Helper function secure_url not always returning a string by [@SOD96](https://github.com/SOD96) in https://github.com/laravel/framework/pull/56807\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56803\n* [12.x] Parse Redis \"friendly\" algorithm names into integers by [@mateusjatenee](https://github.com/mateusjatenee) in https://github.com/laravel/framework/pull/56800\n* [12.x] Remove [@return](https://github.com/return) tags from constructors by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56814\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56813\n* [12.x] Use FQCN for [@mixin](https://github.com/mixin) annotation for consistency by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56811\n* [12.x] Remove leftover `method_exists` checks by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/56821\n* [12.x] Fix use array_first and array_last by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56820\n* Support enum in Collection -> keyBy() by [@zKoz210](https://github.com/zKoz210) in https://github.com/laravel/framework/pull/56786\n* Adds make:config command by [@inmanturbo](https://github.com/inmanturbo) in https://github.com/laravel/framework/pull/56819\n\n## [v12.26.3](https://github.com/laravel/framework/compare/v12.26.2...v12.26.3) - 2025-08-27\n\n* [12.x] add back return type by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56774\n* fix: base class guard in return types is breaking custom guards by [@phadaphunk](https://github.com/phadaphunk) in https://github.com/laravel/framework/pull/56779\n* [12.x] Standardise polyfill dependencies by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56781\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56790\n* [12.x] Refactor duplicated logic in ReplacesAttributes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56789\n* [12.x] Improve output grammar in `ScheduleRunCommand` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56776\n\n## [v12.26.2](https://github.com/laravel/framework/compare/v12.26.1...v12.26.2) - 2025-08-26\n\n* [12.x] fix: csrf_token can return null by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56768\n* [12.x] Fix `date_format` validation on DST Timezone by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56767\n* [12.x] Fix event helper by [@jasonvarga](https://github.com/jasonvarga) in https://github.com/laravel/framework/pull/56773\n\n## [v12.26.1](https://github.com/laravel/framework/compare/v12.26.0...v12.26.1) - 2025-08-26\n\n* [12.x] fix: add polyfill requirement to illuminate packages by [@erikgaal](https://github.com/erikgaal) in https://github.com/laravel/framework/pull/56765\n* [12.x] revert changes to `old()` helper by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56769\n\n## [v12.26.0](https://github.com/laravel/framework/compare/v12.25.0...v12.26.0) - 2025-08-26\n\n* [12.x] feat: add native return types to helper functions by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56684\n* [12.x] Allow passing enum to `Database` attribute by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56688\n* [12.x] Clean up redundant type hints in docblocks by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56690\n* Add ability to specify a transaction mode for SQLite connection by [@panda-madness](https://github.com/panda-madness) in https://github.com/laravel/framework/pull/56681\n* [12.x] Fix `spliceIntoPosition` docblock to allow `string|int` values by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56698\n* [12.x] Use array_first and array_last polyfills by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/56703\n* [12.x] Fix path to Str in exception markdown by [@apreiml](https://github.com/apreiml) in https://github.com/laravel/framework/pull/56705\n* [12.x] Add `withHeartbeat` method to `LazyCollection` by [@JosephSilber](https://github.com/JosephSilber) in https://github.com/laravel/framework/pull/56477\n* [12.x] Add toPrettyJson method by [@WendellAdriel](https://github.com/WendellAdriel) in https://github.com/laravel/framework/pull/56697\n* [12.x] Use `array_first` and `array_last` by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/56706\n* [12.x] Do not dispatch `MessageLogged` twice by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56713\n* [12.x] Order classes alphabetically by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56743\n* [12.x] Normalize file path separators for commands on Windows by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56734\n* [12.x] Improve `queue:prune-failed` tests coverage by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56732\n* [12.x] Align trait usage for consistency by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56727\n* [12.x] Fix composer suggests for illuminate/container by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56722\n* Add nullableTimestampsTz method to Blueprint by [@mohamedhabibwork](https://github.com/mohamedhabibwork) in https://github.com/laravel/framework/pull/56720\n* Add possibility to override symbol when using currency format by [@PhilippeThouvenot](https://github.com/PhilippeThouvenot) in https://github.com/laravel/framework/pull/56749\n* [12.x] Revert #56608 by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56752\n* Revert \"Add possibility to override symbol when using currency format\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/56753\n* [12.x] Support `null` parameter in `BusFake::chain()` method by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/56750\n* [12.x] Remove unnecessary return in ddBody for consistency by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56759\n* [12.x] Make interface accept UnitEnum by [@parijke](https://github.com/parijke) in https://github.com/laravel/framework/pull/56758\n* [12.x] Fix concurrency closure invocation: use base64 encoding by [@sashko-guz](https://github.com/sashko-guz) in https://github.com/laravel/framework/pull/56757\n* [12.x] `ArrayStore::all()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56751\n* [12.x] Fix: Add `$forceWrap` property to JsonResource for consistent API response #56724 by [@achrafAa](https://github.com/achrafAa) in https://github.com/laravel/framework/pull/56736\n* [12.x] Ensures casts objects can be transformed into strings by [@DarkGhostHunter](https://github.com/DarkGhostHunter) in https://github.com/laravel/framework/pull/56687\n\n## [v12.25.0](https://github.com/laravel/framework/compare/v12.24.0...v12.25.0) - 2025-08-18\n\n* [12.x] Prioritize Current Schema When Resolving the Table Name in `db:table` Command by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/56646\n* [12.x] Add `allowedUrls` through `preventStrayRequests` by [@rabrowne85](https://github.com/rabrowne85) in https://github.com/laravel/framework/pull/56645\n* [12.x] Add \"Copy as Markdown\" button to error page by [@mpociot](https://github.com/mpociot) in https://github.com/laravel/framework/pull/56657\n* [12.x] Indicate that `Context@scope()` may throw by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56655\n* [12.x] Remove [@throws](https://github.com/throws) phpDocs in the TransformToResource trait by [@adelf](https://github.com/adelf) in https://github.com/laravel/framework/pull/56667\n* [12.x] Improve docblocks for InteractsWithDatabase by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56666\n* [12.x] Fix prevent group attribute pollution in schedule by [@People-Sea](https://github.com/People-Sea) in https://github.com/laravel/framework/pull/56677\n* Add new `mergeVisible`, `mergeHidden` and `mergeAppends` methods. by [@jonerickson](https://github.com/jonerickson) in https://github.com/laravel/framework/pull/56678\n\n## [v12.24.0](https://github.com/laravel/framework/compare/v12.23.1...v12.24.0) - 2025-08-13\n\n* [8.4] Use PHP 8.4 array helpers in Arr utils by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56631\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56635\n* [12.x] Update `orchestra/testbench-core` deps by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56637\n* refactor: update cid param name by [@cpenned](https://github.com/cpenned) in https://github.com/laravel/framework/pull/56634\n* [12.x] Cache Singleton/Scoped attribute checks by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56633\n* [12.x] Add `Arr::push()` by [@inxilpro](https://github.com/inxilpro) in https://github.com/laravel/framework/pull/56632\n* [12.x] Add error message for `doesnt_contain` rule by [@apih](https://github.com/apih) in https://github.com/laravel/framework/pull/56644\n\n## [v12.23.1](https://github.com/laravel/framework/compare/v12.23.0...v12.23.1) - 2025-08-12\n\n## [v12.23.0](https://github.com/laravel/framework/compare/v12.22.1...v12.23.0) - 2025-08-12\n\n* [12.x] Prevent unintended sleep on early failure of assertSequence by [@xHeaven](https://github.com/xHeaven) in https://github.com/laravel/framework/pull/56583\n* [12.x] Redis cluster broadcaster by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/56581\n* [12.x] Alias Benchmark class by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/56594\n* [12.x] Add support for drop patterns to the `make:migration` command's `TableGuesser`. by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56608\n* [12.x] Improve collection return types by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/56599\n* [12.x] Fix collection typo by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/56597\n* Fix return type docblock for resetAttempts method in RateLimiter by [@jonagoldman](https://github.com/jonagoldman) in https://github.com/laravel/framework/pull/56596\n* Add 'page' field to paginator links by [@compico](https://github.com/compico) in https://github.com/laravel/framework/pull/56603\n* [12.x] Add support for inline attachments in Resend transport by [@jayanratna](https://github.com/jayanratna) in https://github.com/laravel/framework/pull/56598\n* Fix test failures in PHPUnit 12.3.2 by [@KentarouTakeda](https://github.com/KentarouTakeda) in https://github.com/laravel/framework/pull/56610\n* [12.x] Use new error and exception handler getters by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56623\n* [12.x] Use PHP 8.4 array helpers by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56619\n* [12.x] Prefer Symfony PHP polyfills over `function_exists` calls by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/56621\n* [12.x] `Bind` attribute accepts UnitEnum by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56616\n* [12.x] Add Vitess-specific safe to retry errors by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56615\n* [12.x] Handle null as a falsy condition by [@negoziator](https://github.com/negoziator) in https://github.com/laravel/framework/pull/56612\n* Added \"after\" support for morphs and nullableMorphs Blueprint by [@marcogermani87](https://github.com/marcogermani87) in https://github.com/laravel/framework/pull/56613\n* [12.x] Fix usage of `Scoped` and `Singleton` on interfaces by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56620\n* [12.x] Online (concurrently) index creation for PostgreSQL and SqlServer by [@vadimonus](https://github.com/vadimonus) in https://github.com/laravel/framework/pull/56625\n\n## [v12.22.1](https://github.com/laravel/framework/compare/v12.21.0...v12.22.1) - 2025-08-08\n\n* [12.x] Improved assertion message by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56579\n* [12.x] Fixed version increment by [@dciancu](https://github.com/dciancu) in https://github.com/laravel/framework/pull/56588\n* [12.x] Normalize file path separators in `make:migration` command on Windows by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56591\n* Revert \"[12.x] Improve PHPDoc blocks for array of arguments in Gate\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/56593\n\n## [v12.21.0](https://github.com/laravel/framework/compare/v12.20.0...v12.21.0) - 2025-07-22\n\n* fix(vite): #55793 add explicit as-script to link tag for script modul… by [@midsonlajeanty](https://github.com/midsonlajeanty) in https://github.com/laravel/framework/pull/55794\n* [12.x] Allow globally disabling Factory parent relationships via `Factory::dontExpandRelationshipsByDefault()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56154\n* [12.x] Adds checking if a value is between two columns by [@DarkGhostHunter](https://github.com/DarkGhostHunter) in https://github.com/laravel/framework/pull/56119\n* [12.x] Ensure database connection is always restored by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/56258\n* [12.x] Fix handling of `Htmlable` objects in `Js::convertDataToJavaScriptExpression()` by [@jj15asmr](https://github.com/jj15asmr) in https://github.com/laravel/framework/pull/56253\n* Reduce meaningless intermediate variables. by [@LjjGit](https://github.com/LjjGit) in https://github.com/laravel/framework/pull/56265\n* [12.x] Improve typehints for `AbstractCursorPaginator@through()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56267\n* Use `Date` facade instead of `time()` for `password_confirmed_at` check by [@dylanbr](https://github.com/dylanbr) in https://github.com/laravel/framework/pull/56270\n* [12.x] fix: Collection::transform() and Paginator::through() return types by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56273\n* [12.x] Merge 11.x into 12.x by [@u01jmg3](https://github.com/u01jmg3) in https://github.com/laravel/framework/pull/56289\n* [12.x] Reduce meaningless intermediate variables by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56288\n* [12.x] Refactor build Method to Use Null Coalescing Assignment for Default C… by [@Ashot1995](https://github.com/Ashot1995) in https://github.com/laravel/framework/pull/56283\n* [12.x] minor code formatting improvements by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56296\n* [12.x] Use more specific route binding exception message for child routes by [@jessekoerhuis](https://github.com/jessekoerhuis) in https://github.com/laravel/framework/pull/56298\n* [12.x] Fix Possible Undefined Variables by [@calfc](https://github.com/calfc) in https://github.com/laravel/framework/pull/56292\n* [12.x] Fix: Ensure scheduler `dailyAt()` method parses minutes and ignores seconds when seconds are provided by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56308\n* [12.x] Allows for strict boolean validation by [@peterfox](https://github.com/peterfox) in https://github.com/laravel/framework/pull/56313\n* Improve `SeedCommand` console output by [@Jehong-Ahn](https://github.com/Jehong-Ahn) in https://github.com/laravel/framework/pull/56310\n* [12.x] Add unified enum support across framework docs by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56271\n* [12.x] Allows for strict numeric validation by [@peterfox](https://github.com/peterfox) in https://github.com/laravel/framework/pull/56328\n* [12.x] Update PHPDoc annotations in `Validation` by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/56321\n* [12.x] Add operator class support for PostgreSQL GiST spatial indexes by [@joteejotee](https://github.com/joteejotee) in https://github.com/laravel/framework/pull/56324\n* Fix multipart array value parsing in HTTP client (#55732) by [@joteejotee](https://github.com/joteejotee) in https://github.com/laravel/framework/pull/56302\n* Fixes bug with ShouldBeUniqueUntilProcessing locks getting stuck due to Middleware by [@TWithers](https://github.com/TWithers) in https://github.com/laravel/framework/pull/56318\n* [12.x] add prompts based expectations to PendingCommand by [@BinaryKitten](https://github.com/BinaryKitten) in https://github.com/laravel/framework/pull/56260\n* [12.x] Add Singleton and Scoped attributes to Container by [@riasvdv](https://github.com/riasvdv) in https://github.com/laravel/framework/pull/56334\n* Fix unsetting model castable attribute when cast to object (#56335) by [@guram-vashakidze](https://github.com/guram-vashakidze) in https://github.com/laravel/framework/pull/56343\n* [12.x]  Fix/memory improvement by [@CharrafiMed](https://github.com/CharrafiMed) in https://github.com/laravel/framework/pull/56345\n* [12.x] Add hasMailer method to the mailable class by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/56340\n* [12.x] Consistent use of `mb_split()` to split strings into words by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/56338\n* [12.x] Add toStringable to Uri by [@Kyrch](https://github.com/Kyrch) in https://github.com/laravel/framework/pull/56359\n* [12.x] Fix PHPStan Integrations by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56369\n* Add 'isEmpty' and 'isNotEmpty' to Fluent by [@cworreschk](https://github.com/cworreschk) in https://github.com/laravel/framework/pull/56370\n* [12.x] Add mergeMetadata method to the Mailable class by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/56376\n* Add 'dontReportUsing' to filter exceptions to be reported by [@pelmered](https://github.com/pelmered) in https://github.com/laravel/framework/pull/56361\n\n## [v12.20.0](https://github.com/laravel/framework/compare/v12.19.3...v12.20.0) - 2025-07-08\n\n* [12.x] Pass TransportException to NotificationFailed event by [@hackel](https://github.com/hackel) in https://github.com/laravel/framework/pull/56061\n* [12.x] use `offset()` in place of `skip()` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56081\n* [12.x] use `limit()` in place of `take()` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56080\n* [12.x] Display job queue names when running queue:work with --verbose option by [@seriquynh](https://github.com/seriquynh) in https://github.com/laravel/framework/pull/56086\n* [12.x] use `offset()` and `limit()` in tests by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56089\n* [12.x] Localize “Pagination Navigation” aria-label by [@andylolz](https://github.com/andylolz) in https://github.com/laravel/framework/pull/56103\n* [12.x] Enhance the test coverage for Pipeline::through() by [@azim-kordpour](https://github.com/azim-kordpour) in https://github.com/laravel/framework/pull/56100\n* [12.x] Added `JsonSerializable` interface to `Uri` Class by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/56097\n* [12.x] Display job connection name when running queue:work with --verbose option by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56095\n* [12.x] Fix PHPDoc for Arr::sole method by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56096\n* [12.x] when a method returns `$this` set the return type to `static` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56092\n* [12.x] Use `int<0, max>` as docblock return type for database operations that return a count by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56117\n* [12.x] Add missing [@throws](https://github.com/throws) annotation to Number by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56116\n* [12.x] Correct PHPDoc for Arr::sole callable type to avoid return type ambiguity by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56108\n* Change return types of through (pagination) and transform (collection) by [@glamorous](https://github.com/glamorous) in https://github.com/laravel/framework/pull/56105\n* [12.x] Add maintenance mode facade for easier driver extension by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/56090\n* [12.x] Cache isSoftDeletable(), isPrunable(), and isMassPrunable() directly in model by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/56078\n* [12.x] Throws not throw by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56120\n* [12.x] Fix [@param](https://github.com/param) docblock to allow string by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56121\n* [11.x] Pass the limiter to the when & report callbacks by [@jimmypuckett](https://github.com/jimmypuckett) in https://github.com/laravel/framework/pull/56129\n* [12.x] remove the \"prefix\" option for cache password resets by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/56127\n* [12.x] Make Model::currentEncrypter public by [@JaZo](https://github.com/JaZo) in https://github.com/laravel/framework/pull/56130\n* [12.x] Add throws docblock by [@amirhshokri](https://github.com/amirhshokri) in https://github.com/laravel/framework/pull/56137\n* [12.x] Narrow integer range for `Collection` methods by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56135\n* [12.x] Allows using `--model` and `--except` via `PruneCommand` command by [@hosni](https://github.com/hosni) in https://github.com/laravel/framework/pull/56140\n* [12.x] Support Passing `Htmlable` Instances to `Js::from()` by [@jj15asmr](https://github.com/jj15asmr) in https://github.com/laravel/framework/pull/56159\n* #56124 Properly escape column defaults by [@asmecher](https://github.com/asmecher) in https://github.com/laravel/framework/pull/56158\n* [12.x] Return early on belongs-to-many relationship `syncWithoutDetaching` method when empty values are given by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/56157\n* [12.x] Add fakeFor and fakeExceptFor methods to Queue facade by [@MrPunyapal](https://github.com/MrPunyapal) in https://github.com/laravel/framework/pull/56149\n* [11.x] Backport test fixes by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56183\n* Revert \"[11.x] Pass the limiter to the when & report callbacks\" by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56184\n* Add failWhen method to ThrottlesExceptions job middleware by [@michaeldzjap](https://github.com/michaeldzjap) in https://github.com/laravel/framework/pull/56180\n* [12.x] Update Castable contract to accept string array by [@hosmelq](https://github.com/hosmelq) in https://github.com/laravel/framework/pull/56177\n* Feature: doesntStartWith() and doesntEndWith() string methods by [@balboacodes](https://github.com/balboacodes) in https://github.com/laravel/framework/pull/56168\n* [12.x] Add context remember functions by [@btaskew](https://github.com/btaskew) in https://github.com/laravel/framework/pull/56156\n* [12.x] Fix queue fake cleanup to always restore original queue manager by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/56165\n* [12.x] Pass the limiter to the when & report callbacks by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56187\n* [12.x] Add `Closure`-support to `$key`/`$value` in Collection `pluck()` method by [@ralphjsmit](https://github.com/ralphjsmit) in https://github.com/laravel/framework/pull/56188\n* [12.x] Add `collection()` to Config repository by [@KennedyTedesco](https://github.com/KennedyTedesco) in https://github.com/laravel/framework/pull/56200\n* Add int to allowed types of value in DatabaseRule by [@vkarchevskyi](https://github.com/vkarchevskyi) in https://github.com/laravel/framework/pull/56199\n* [12.x] Fix Event fake cleanup to always restore original event dispatcher by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/56189\n* [12.x] Align PHPDoc style in Number::parseFloat with the rest of the class by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56206\n* [12.x] Inconsistent use of [@return](https://github.com/return) type by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56207\n* [12.x] Resolve issue with Factory make when automatic eager loading by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/56211\n* [12.x] Refactor driver initialization using null coalescing assignment in Manager by [@Ashot1995](https://github.com/Ashot1995) in https://github.com/laravel/framework/pull/56210\n* [12.x] Add URL signature macros to `Request` docblock by [@duncanmcclean](https://github.com/duncanmcclean) in https://github.com/laravel/framework/pull/56230\n* [12.x] Update PHPDoc for dataForSometimesIteration by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/56229\n* [12.x] Avoid unnecessary filtering when no callback is provided by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/56225\n* [12.x] Make `Fluent` class iterable by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/56218\n* Improve Mailable assertion error messages with expected vs actual values by [@ahinkle](https://github.com/ahinkle) in https://github.com/laravel/framework/pull/56221\n* [12.x] Add `@​context` Blade directive by [@martinbean](https://github.com/martinbean) in https://github.com/laravel/framework/pull/56146\n* [12.x] fix: AsCommand properties not being set on commands by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56235\n* [12.x] Ensure `withLocale` and `withCurrency` always restore previous state by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/56234\n\n## [v12.19.3](https://github.com/laravel/framework/compare/v12.19.2...v12.19.3) - 2025-06-18\n\n* [12.x] Fix model pruning when non model files are in the same directory by [@rojtjo](https://github.com/rojtjo) in https://github.com/laravel/framework/pull/56071\n\n## [v12.19.2](https://github.com/laravel/framework/compare/v12.19.1...v12.19.2) - 2025-06-17\n\n## [v12.19.1](https://github.com/laravel/framework/compare/v12.19.0...v12.19.1) - 2025-06-17\n\n* Revert \"[12.x] Check if file exists before trying to delete it\" by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/56072\n\n## [v12.19.0](https://github.com/laravel/framework/compare/v12.18.0...v12.19.0) - 2025-06-17\n\n* [11.x] Fix validation to not throw incompatible validation exception by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55963\n* [12.x] Correct testEncryptAndDecrypt to properly test new methods by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/55985\n* [12.x] Check if file exists before trying to delete it by [@Jellyfrog](https://github.com/Jellyfrog) in https://github.com/laravel/framework/pull/55994\n* Clear cast caches when discarding changes by [@willtj](https://github.com/willtj) in https://github.com/laravel/framework/pull/55992\n* [12.x] Handle Null Check in Str::contains by [@Jellyfrog](https://github.com/Jellyfrog) in https://github.com/laravel/framework/pull/55991\n* [12.x] Remove call to deprecated `getDefaultDescription` method by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/55990\n* Bump brace-expansion from 2.0.1 to 2.0.2 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot) in https://github.com/laravel/framework/pull/55999\n* Enhance error handling in PendingRequest to convert TooManyRedirectsE… by [@achrafAa](https://github.com/achrafAa) in https://github.com/laravel/framework/pull/55998\n* [12.x] fix: remove Model intersection from UserProvider contract by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/56013\n* [12.x] Remove the only [@return](https://github.com/return) tag left on a constructor by [@JordanchoEftimov](https://github.com/JordanchoEftimov) in https://github.com/laravel/framework/pull/56001\n* [12.x] Introduce `ComputesOnceableHashInterface` by [@Jacobs63](https://github.com/Jacobs63) in https://github.com/laravel/framework/pull/56009\n* [12.x] Add assertRedirectBackWithErrors to TestResponse by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55987\n* [12.x] collapseWithKeys - Prevent exception in base case by [@DeanWunder](https://github.com/DeanWunder) in https://github.com/laravel/framework/pull/56002\n* [12.x] Standardize size() behavior and add extended queue metrics support by [@sylvesterdamgaard](https://github.com/sylvesterdamgaard) in https://github.com/laravel/framework/pull/56010\n* [11.x] Fix `symfony/console:7.4` compatibility by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/56015\n* [12.x] Improve constructor PHPDoc for controller middleware definition by [@JordanchoEftimov](https://github.com/JordanchoEftimov) in https://github.com/laravel/framework/pull/56021\n* Remove `@return` tags from constructors by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/56024\n* [12.x] sort helper functions in alphabetic order by [@gigabites19](https://github.com/gigabites19) in https://github.com/laravel/framework/pull/56031\n* [12.x] add Attachment::fromUploadedFile method by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/56027\n* [12.x]: Add UseEloquentBuilder attribute to register custom Eloquent Builder by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/56025\n* [12.x] Improve PHPDoc for the Illuminate\\Cache folder files by [@JordanchoEftimov](https://github.com/JordanchoEftimov) in https://github.com/laravel/framework/pull/56028\n* [12.x] Add a new model cast named asFluent by [@azim-kordpour](https://github.com/azim-kordpour) in https://github.com/laravel/framework/pull/56046\n* [12.x] Introduce `FailOnException` job middleware by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/56037\n* [12.x] isSoftDeletable(), isPrunable(), and isMassPrunable() to model class by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/56060\n\n## [v12.18.0](https://github.com/laravel/framework/compare/v12.17.0...v12.18.0) - 2025-06-10\n\n* document `through()` method in interfaces to fix IDE warnings by [@harryqt](https://github.com/harryqt) in https://github.com/laravel/framework/pull/55925\n* [12.x] Add encrypt and decrypt Str helper methods by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/55931\n* [12.x] Add a command option for making batchable jobs by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/55929\n* [12.x] fix: intersect Authenticatable with Model in UserProvider phpdocs by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/54061\n* [12.x] feat: create UsePolicy attribute by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55882\n* [12.x] `ScheduledTaskFailed` not dispatched on scheduled forground task fails by [@achrafAa](https://github.com/achrafAa) in https://github.com/laravel/framework/pull/55624\n* [12.x] Add generics to `Model::unguarded()` by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/55932\n* [12.x] Fix SSL Certificate and Connection Errors Leaking as Guzzle Exceptions by [@achrafAa](https://github.com/achrafAa) in https://github.com/laravel/framework/pull/55937\n* Fix deprecation warning in PHP 8.3 by ensuring string type in explode() by [@Khuthaily](https://github.com/Khuthaily) in https://github.com/laravel/framework/pull/55939\n* revert: #55939 by [@NickSdot](https://github.com/NickSdot) in https://github.com/laravel/framework/pull/55943\n* [12.x] feat: Add WorkerStarting event when worker daemon starts by [@Orrison](https://github.com/Orrison) in https://github.com/laravel/framework/pull/55941\n* [12.x] Allow setting the `RequestException` truncation limit per request by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55897\n* [12.x] feat: Make custom eloquent castings comparable for more granular isDirty check by [@SanderSander](https://github.com/SanderSander) in https://github.com/laravel/framework/pull/55945\n* [12.x] fix alphabetical order by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55965\n* [12.x] Use native named parameter instead of unused variable by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55964\n* [12.x] add generics to Model attribute related methods and properties by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55962\n* [12.x] Supports PHPUnit 12.2 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55961\n* [12.x] feat: Add ability to override SendQueuedNotifications job class by [@Orrison](https://github.com/Orrison) in https://github.com/laravel/framework/pull/55942\n* [12.x] Fix timezone validation test for PHP 8.3+ by [@platoindebugmode](https://github.com/platoindebugmode) in https://github.com/laravel/framework/pull/55956\n* Broadcasting Utilities by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55967\n* [12.x] Remove unused $guarded parameter from testChannelNameNormalization method by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55973\n* [12.x] Validate that `outOf` is greater than 0 in `Lottery` helper by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/55969\n* [12.x] Allow retrieving all reported exceptions from `ExceptionHandlerFake` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55972\n\n## [v12.17.0](https://github.com/laravel/framework/compare/v12.16.0...v12.17.0) - 2025-06-03\n\n* [11.x] Backport `TestResponse::assertRedirectBack` by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/55780\n* Add support for sending raw (non-encoded) attachments in Resend mail by [@Roywcm](https://github.com/Roywcm) in https://github.com/laravel/framework/pull/55837\n* [12.x] chore: return Collection from timestamps methods by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55871\n* [12.x] fix: fully qualify collection return type by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55873\n* [12.x] Fix Blade nested default component resolution for custom namespaces by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/55874\n* [12.x] Fix return types in console command handlers to void by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/55876\n* [12.x] Ability to perform higher order static calls on collection items by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/55880\n* Adds Resource helpers to cursor paginator by [@jsandfordhughescoop](https://github.com/jsandfordhughescoop) in https://github.com/laravel/framework/pull/55879\n* Add reorderDesc() to Query Builder by [@ghabriel25](https://github.com/ghabriel25) in https://github.com/laravel/framework/pull/55885\n* [11.x] Fixes Symfony Console 7.3 deprecations on closure command by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55888\n* [12.x] Add `AsUri` model cast by [@ash-jc-allen](https://github.com/ash-jc-allen) in https://github.com/laravel/framework/pull/55909\n* [12.x] feat: Add Contextual Implementation/Interface Binding via PHP8 Attribute by [@yitzwillroth](https://github.com/yitzwillroth) in https://github.com/laravel/framework/pull/55904\n* [12.x] Add tests for the `AuthenticateSession` Middleware by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55900\n* [12.x] Allow brick/math ^0.13 by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/54964\n* [12.x] fix: Factory::state and ::prependState generics by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55915\n\n## [v12.16.0](https://github.com/laravel/framework/compare/v12.15.0...v12.16.0) - 2025-05-27\n\n* [12.x] Change priority in optimize:clear by [@amirmohammadnajmi](https://github.com/amirmohammadnajmi) in https://github.com/laravel/framework/pull/55792\n* [12.x] Fix `TestResponse::assertSessionMissing()` when given an array of keys by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55800\n* [12.x] Allowing `Context` Attribute to Interact with Hidden by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55799\n* Add support for sending raw (non-encoded) attachments in Resend mail driver by [@Roywcm](https://github.com/Roywcm) in https://github.com/laravel/framework/pull/55803\n* [12.x] Added option to always defer for flexible cache by [@Zwartpet](https://github.com/Zwartpet) in https://github.com/laravel/framework/pull/55802\n* [12.x] style: Use null coalescing assignment (??=) for cleaner code by [@mohsenetm](https://github.com/mohsenetm) in https://github.com/laravel/framework/pull/55823\n* [12.x] Introducing `Arr::hasAll` by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55815\n* [12.x] Restore lazy loading check by [@decadence](https://github.com/decadence) in https://github.com/laravel/framework/pull/55817\n* [12.x] Minor language update by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55812\n* fix(cache/redis): use connectionAwareSerialize in RedisStore::putMany() by [@superbiche](https://github.com/superbiche) in https://github.com/laravel/framework/pull/55814\n* [12.x] Fix `ResponseFactory` should also accept `null` callback by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55833\n* [12.x] Add template variables to scope by [@wietsewarendorff](https://github.com/wietsewarendorff) in https://github.com/laravel/framework/pull/55830\n* [12.x] Introducing `toUri` to the `Stringable` Class by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55862\n* [12.x] Remove remaining [@return](https://github.com/return) tags from constructors by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55858\n* [12.x] Replace alias `is_integer()` with `is_int()` to comply with Laravel Pint by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/55851\n* Fix argument types for Illuminate/Database/Query/Builder::upsert() by [@jellisii](https://github.com/jellisii) in https://github.com/laravel/framework/pull/55849\n* [12.x] Add `in_array_keys` validation rule to check for presence of specified array keys by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/55807\n* [12.x] Add `Rule::contains` by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/55809\n\n## [v12.15.0](https://github.com/laravel/framework/compare/v12.14.1...v12.15.0) - 2025-05-20\n\n* [12.x] Add locale-aware number parsing methods to Number class by [@informagenie](https://github.com/informagenie) in https://github.com/laravel/framework/pull/55725\n* [12.x] Add a default option when retrieving an enum from data by [@elbojoloco](https://github.com/elbojoloco) in https://github.com/laravel/framework/pull/55735\n* Revert \"[12.x] Update \"Number::fileSize\" to use correct prefix and add prefix param\" by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/55741\n* [12.x] Remove apc by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55745\n* [12.x] Add param type for `assertJsonStructure` & `assertExactJsonStructure` methods by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/laravel/framework/pull/55743\n* [12.x] Fix type casting for environment variables in config files by [@adamwhp](https://github.com/adamwhp) in https://github.com/laravel/framework/pull/55737\n* [12.x] Preserve \"previous\" model state by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55729\n* [12.x] Passthru `getCountForPagination` on an Eloquent\\Builder by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55752\n* [12.x] Add `assertClientError` method to `TestResponse` by [@shane-zeng](https://github.com/shane-zeng) in https://github.com/laravel/framework/pull/55750\n* Install Broadcasting Command Fix for Livewire Starter Kit by [@joshcirre](https://github.com/joshcirre) in https://github.com/laravel/framework/pull/55774\n* Clarify units for benchmark value for IDE accessibility by [@mike-healy](https://github.com/mike-healy) in https://github.com/laravel/framework/pull/55781\n* Improved PHPDoc Return Types for Eloquent's Original Attribute Methods by [@clementbirkle](https://github.com/clementbirkle) in https://github.com/laravel/framework/pull/55779\n* [12.x] Prevent `preventsLazyLoading` exception when using `automaticallyEagerLoadRelationships` by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55771\n* [12.x] Add `hash` string helper by [@istiak-tridip](https://github.com/istiak-tridip) in https://github.com/laravel/framework/pull/55767\n* [12.x] Update `assertSessionMissing()` signature to match `assertSessionHas()` by [@nexxai](https://github.com/nexxai) in https://github.com/laravel/framework/pull/55763\n* Fix: php artisan db command if no password by [@mr-chetan](https://github.com/mr-chetan) in https://github.com/laravel/framework/pull/55761\n* [12.x] Types: InteractsWithPivotTable::sync by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/55762\n* [12.x] feat: Add `current_page_url` to Paginator by [@mariomka](https://github.com/mariomka) in https://github.com/laravel/framework/pull/55789\n* Correct return type in PhpDoc for command fail method by [@Muetze42](https://github.com/Muetze42) in https://github.com/laravel/framework/pull/55783\n* [12.x] Add `assertRedirectToAction` method to test redirection to controller actions by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/55788\n* [12.x] Add Context contextual attribute by [@martinbean](https://github.com/martinbean) in https://github.com/laravel/framework/pull/55760\n\n## [v12.14.1](https://github.com/laravel/framework/compare/v12.14.0...v12.14.1) - 2025-05-13\n\n* [10.x] Refine error messages for detecting lost connections (Debian bookworm compatibility) by [@mfn](https://github.com/mfn) in https://github.com/laravel/framework/pull/53794\n* [10.x] Bump minimum `league/commonmark` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/53829\n* [10.x] Backport 11.x PHP 8.4 fix for str_getcsv deprecation by [@aka-tpayne](https://github.com/aka-tpayne) in https://github.com/laravel/framework/pull/54074\n* [10.x] Fix attribute name used on `Validator` instance within certain rule classes by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54943\n* Add `Illuminate\\Support\\EncodedHtmlString` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54737\n* [11.x] Fix missing `return $this` for `assertOnlyJsonValidationErrors` by [@LeTamanoir](https://github.com/LeTamanoir) in https://github.com/laravel/framework/pull/55099\n* [11.x] Fix `Illuminate\\Support\\EncodedHtmlString` from causing breaking change by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55149\n* [11.x] Respect custom path for cached views by the `AboutCommand` by [@alies-dev](https://github.com/alies-dev) in https://github.com/laravel/framework/pull/55179\n* [11.x] Include all invisible characters in Str::trim by [@laserhybiz](https://github.com/laserhybiz) in https://github.com/laravel/framework/pull/54281\n* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55302\n* [11.x] Remove incorrect syntax from mail's `message` template by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55530\n* [11.x] Allows to toggle markdown email encoding by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55539\n* [11.x] Fix `EncodedHtmlString` to ignore instance of `HtmlString` by [@jbraband](https://github.com/jbraband) in https://github.com/laravel/framework/pull/55543\n* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55549\n* [11.x] Install Passport 13.x by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/55621\n* [11.x] Bump minimum league/commonmark by [@andrextor](https://github.com/andrextor) in https://github.com/laravel/framework/pull/55660\n* Backporting Timebox fixes to 11.x by [@valorin](https://github.com/valorin) in https://github.com/laravel/framework/pull/55705\n* Test SQLServer 2017 on Ubuntu 22.04 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55716\n* [11.x] Fix Symfony 7.3 deprecations by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55711\n* Easily implement broadcasting in a React/Vue Typescript app (Starter Kits) by [@tnylea](https://github.com/tnylea) in https://github.com/laravel/framework/pull/55170\n\n## [v12.14.0](https://github.com/laravel/framework/compare/v12.13.0...v12.14.0) - 2025-05-13\n\n* [12.x] Support `useCurrent` on date and year column types by [@nicholasbrantley](https://github.com/nicholasbrantley) in https://github.com/laravel/framework/pull/55619\n* [12.x] Update \"Number::fileSize\" to use correct prefix and add prefix param by [@Boy132](https://github.com/Boy132) in https://github.com/laravel/framework/pull/55678\n* [12.x] Update PHPDoc for whereRaw to allow Expression as $sql by [@mitoop](https://github.com/mitoop) in https://github.com/laravel/framework/pull/55674\n* Revert \"[12.x] Make Blueprint Resolver Statically\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55690\n* [12.x] Support Virtual Properties When Serializing Models by [@beschoenen](https://github.com/beschoenen) in https://github.com/laravel/framework/pull/55691\n* [12.X] Fix `Http::preventStrayRequests` error propagation when using `Http::pool` by [@LeTamanoir](https://github.com/LeTamanoir) in https://github.com/laravel/framework/pull/55689\n* [12.x] incorrect use of generics in Schema\\Builder by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55687\n* [12.x] Add option to disable MySQL ssl when restoring or squashing migrations by [@andersonls](https://github.com/andersonls) in https://github.com/laravel/framework/pull/55683\n* [12.x] Add `except` and `exceptHidden` methods to `Context` class by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/55692\n* [12.x] Container `currentlyResolving` utility by [@jrseliga](https://github.com/jrseliga) in https://github.com/laravel/framework/pull/55684\n* [12.x] Container `currentlyResolving` test by [@jrseliga](https://github.com/jrseliga) in https://github.com/laravel/framework/pull/55694\n* [12.x] Fix handling of default values for route parameters with a binding field by [@stancl](https://github.com/stancl) in https://github.com/laravel/framework/pull/55697\n* Move Timebox for Authentication and add to password resets by [@valorin](https://github.com/valorin) in https://github.com/laravel/framework/pull/55701\n* [12.x] perf: Optimize BladeCompiler by [@rzv-me](https://github.com/rzv-me) in https://github.com/laravel/framework/pull/55703\n* [12.x] perf: support iterables for event discovery paths by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55699\n* [12.x] Types: AuthorizesRequests::resourceAbilityMap by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/55706\n* [12.x] Add flexible support to memoized cache store by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55709\n* [12.x] Introduce Arr::from() by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/55715\n* [12.x] Fix the `getCurrentlyAttachedPivots` wrong `morphClass` for morph to many relationships by [@amir9480](https://github.com/amir9480) in https://github.com/laravel/framework/pull/55721\n* [12.x] Improve typehints for Http classes by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54783\n* Add deleteWhen for throttle exceptions job middleware by [@moshe-autoleadstar](https://github.com/moshe-autoleadstar) in https://github.com/laravel/framework/pull/55718\n\n## [v12.13.0](https://github.com/laravel/framework/compare/v12.12.0...v12.13.0) - 2025-05-07\n\n* [12.x] fix no arguments return type in request class by [@olivernybroe](https://github.com/olivernybroe) in https://github.com/laravel/framework/pull/55631\n* [12.x] Add support for callback evaluation in containsOneItem method by [@fernandokbs](https://github.com/fernandokbs) in https://github.com/laravel/framework/pull/55622\n* [12.x] add generics to aggregate related methods and properties by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55628\n* [12.x] Fix typo in PHPDoc by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55636\n* [12.x] Allow naming queued closures by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/55634\n* [12.x] Add `assertRedirectBack` assertion method by [@ryangjchandler](https://github.com/ryangjchandler) in https://github.com/laravel/framework/pull/55635\n* [12.x] Typehints for bindings by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55633\n* [12.x] add PHP Doc types to arrays for methods in Database\\Grammar by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55629\n* fix trim null arg deprecation by [@apreiml](https://github.com/apreiml) in https://github.com/laravel/framework/pull/55649\n* [12.x] Support predis/predis 3.x by [@gabrielrbarbosa](https://github.com/gabrielrbarbosa) in https://github.com/laravel/framework/pull/55641\n* Bump vite from 5.4.18 to 5.4.19 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot) in https://github.com/laravel/framework/pull/55655\n* [12.x] Fix predis versions by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/55654\n* [12.x] Bump minimum league/commonmark by [@szepeviktor](https://github.com/szepeviktor) in https://github.com/laravel/framework/pull/55659\n* [12.x] Fix typo in MemoizedStoreTest by [@szepeviktor](https://github.com/szepeviktor) in https://github.com/laravel/framework/pull/55662\n* [12.x] Queue event listeners with enum values by [@wgriffioen](https://github.com/wgriffioen) in https://github.com/laravel/framework/pull/55656\n* [12.x] Implement releaseAfter method in RateLimited middleware by [@adamjgriffith](https://github.com/adamjgriffith) in https://github.com/laravel/framework/pull/55671\n* [12.x] Improve Cache Tests by [@nuernbergerA](https://github.com/nuernbergerA) in https://github.com/laravel/framework/pull/55670\n* [12.x] Only pass model IDs to Eloquent `whereAttachedTo` method by [@ashleyshenton](https://github.com/ashleyshenton) in https://github.com/laravel/framework/pull/55666\n* feat(bus): allow adding multiple jobs to chain by [@dallyger](https://github.com/dallyger) in https://github.com/laravel/framework/pull/55668\n* [12.x] add generics to QueryBuilder’s column related methods by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55663\n\n## [v12.12.0](https://github.com/laravel/framework/compare/v12.11.1...v12.12.0) - 2025-05-01\n\n* [12.x] Make Blueprint Resolver Statically by [@finagin](https://github.com/finagin) in https://github.com/laravel/framework/pull/55607\n* [12.x] Allow limiting number of assets to preload by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55618\n* [12.x] Set job instance on \"failed\" command instance by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/55617\n\n## [v12.11.1](https://github.com/laravel/framework/compare/v12.11.0...v12.11.1) - 2025-04-30\n\n* Revert \"[12.x]`ScheduledTaskFailed` not dispatched on scheduled task failing\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55612\n* [12.x] Resolve issue with BelongsToManyRelationship factory by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/55608\n\n## [v12.11.0](https://github.com/laravel/framework/compare/v12.10.2...v12.11.0) - 2025-04-29\n\n* Add payload creation and original delay info to job payload by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55529\n* Add config option to ignore view cache timestamps by [@pizkaz](https://github.com/pizkaz) in https://github.com/laravel/framework/pull/55536\n* [12.x] Dispatch NotificationFailed when sending fails by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/55507\n* [12.x] Option to disable dispatchAfterResponse in a test by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55456\n* [12.x] Pass flags to custom Json::$encoder by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/55548\n* [12.x] Use pendingAttributes of relationships when creating relationship models via model factories by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55558\n* [12.x] Fix double query in model relation serialization by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55547\n* [12.x] Improve circular relation check in Automatic Relation Loading by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/55542\n* [12.x] Prevent relation autoload context from being serialized by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/55582\n* Remove `@internal` Annotation from `$components` Property in `InteractsWithIO` by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/55580\n* Ensure fake job implements job contract by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55574\n* [12.x] Fix `AnyOf` constructor parameter type by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/55577\n* Sync changes to Illuminate components before release by [@driesvints](https://github.com/driesvints) in https://github.com/laravel/framework/pull/55591\n* [12.x] Set class-string generics on `Enum` rule by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55588\n* [12.x] added detailed doc types to bindings related methods by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55576\n* [12.x] Improve [@use](https://github.com/use) directive to support function and const modifiers by [@rodolfosrg](https://github.com/rodolfosrg) in https://github.com/laravel/framework/pull/55583\n* 12.x scheduled task failed not dispatched on scheduled task failing by [@achrafAa](https://github.com/achrafAa) in https://github.com/laravel/framework/pull/55572\n* [12.x] Introduce Reflector methods for accessing class attributes by [@daniser](https://github.com/daniser) in https://github.com/laravel/framework/pull/55568\n* [12.x] Typed getters for Arr helper by [@tibbsa](https://github.com/tibbsa) in https://github.com/laravel/framework/pull/55567\n\n## [v12.10.2](https://github.com/laravel/framework/compare/v12.10.1...v12.10.2) - 2025-04-24\n\n* [12.x] Address Model@relationLoaded when relation is null by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/55531\n\n## [v12.10.1](https://github.com/laravel/framework/compare/v12.10.0...v12.10.1) - 2025-04-23\n\n* Revert \"Use value() helper in 'when' method to simplify code\" #55465 by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55514\n* [12.x] Use xxh128 when comparing views for changes by [@shawnlindstrom](https://github.com/shawnlindstrom) in https://github.com/laravel/framework/pull/55517\n* [12.x] Ensure related models is iterable on `HasRelationships@relationLoaded()` by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/55519\n* [12.x] Add Enum support for assertJsonPath in AssertableJsonString.php by [@azim-kordpour](https://github.com/azim-kordpour) in https://github.com/laravel/framework/pull/55516\n\n## [v12.10.0](https://github.com/laravel/framework/compare/v12.9.2...v12.10.0) - 2025-04-22\n\n* Use value() helper in 'when' method by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55465\n* [12.x] Test `@use` directive without quotes by [@osbre](https://github.com/osbre) in https://github.com/laravel/framework/pull/55462\n* [12.x] Enhance Broadcast Events Test Coverage by [@roshandelpoor](https://github.com/roshandelpoor) in https://github.com/laravel/framework/pull/55458\n* [12.x] Add `Conditionable` Trait to `Fluent`  by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/55455\n* [12.x] Fix relation auto loading with manually set relations by [@patrickweh](https://github.com/patrickweh) in https://github.com/laravel/framework/pull/55452\n* Add missing types to RateLimiter by [@ClaudioEyzaguirre](https://github.com/ClaudioEyzaguirre) in https://github.com/laravel/framework/pull/55445\n* [12.x] Fix for global autoload relationships not working  in certain cases by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/55443\n* [12.x] Fix adding `setTags` method on new cache flush events by [@erikn69](https://github.com/erikn69) in https://github.com/laravel/framework/pull/55405\n* Fix: Unique lock not being released after transaction rollback in ShouldBeUnique jobs with afterCommit() by [@toshitsuna-otsuka](https://github.com/toshitsuna-otsuka) in https://github.com/laravel/framework/pull/55420\n* [12.x] Extends `AsCollection` to map items into objects or other values by [@DarkGhostHunter](https://github.com/DarkGhostHunter) in https://github.com/laravel/framework/pull/55383\n* [12.x] Fix group imports in Blade `@use` directive by [@osbre](https://github.com/osbre) in https://github.com/laravel/framework/pull/55461\n* chore(tests): align test names with idiomatic naming style by [@kauffinger](https://github.com/kauffinger) in https://github.com/laravel/framework/pull/55496\n* Update compiled views only if they actually changed by [@pizkaz](https://github.com/pizkaz) in https://github.com/laravel/framework/pull/55450\n* Improve performance of Arr::dot method - 300x in some cases by [@cyppe](https://github.com/cyppe) in https://github.com/laravel/framework/pull/55495\n* [12.x] Add tests for `CacheBasedSessionHandler` by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55487\n* [12.x] Add tests for `FileSessionHandler` by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55484\n* [12.x] Add tests for `DatabaseSessionHandler` by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55485\n* [12.x] Fix many to many detach without IDs broken with custom pivot class by [@amir9480](https://github.com/amir9480) in https://github.com/laravel/framework/pull/55490\n* [12.x] Support nested relations on `relationLoaded` method by [@tmsperera](https://github.com/tmsperera) in https://github.com/laravel/framework/pull/55471\n* Bugfix for Cache::memo()->many() returning the wrong value with an integer key type by [@bmckay959](https://github.com/bmckay959) in https://github.com/laravel/framework/pull/55503\n* [12.x] Allow Container to build `Migrator` from class name by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55501\n\n## [v12.9.2](https://github.com/laravel/framework/compare/v12.9.1...v12.9.2) - 2025-04-16\n\n* [12.x] Fixed a bug in using `illuminate/console` in external apps by [@andrey-helldar](https://github.com/andrey-helldar) in https://github.com/laravel/framework/pull/55430\n* Disable SQLServer 2017 CI as `ubuntu-20.24` has been removed by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55425\n\n## [v12.9.1](https://github.com/laravel/framework/compare/v12.9.0...v12.9.1) - 2025-04-16\n\n* [12.x] Forward only passed arguments into Illuminate\\Database\\Eloquent\\Collection::partition method by [@MarekVikartovsky](https://github.com/MarekVikartovsky) in https://github.com/laravel/framework/pull/55422\n* [12.x] Add test for complex context manipulation in Logger by [@roshandelpoor](https://github.com/roshandelpoor) in https://github.com/laravel/framework/pull/55423\n* [12.x] Remove unused var from `DumpCommand` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55431\n* [12.x] Fix the serve command sometimes fails to destructure the request pool array by [@tonysm](https://github.com/tonysm) in https://github.com/laravel/framework/pull/55427\n* [12.x] Changes to `package-lock.json` should trigger `npm run build` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55426\n\n## [v12.9.0](https://github.com/laravel/framework/compare/v12.8.1...v12.9.0) - 2025-04-15\n\n* Add types to ViewErrorBag by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/55329\n* Add types to MessageBag by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/55327\n* [12.x] add generics to commonly used methods in Schema/Builder by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55330\n* Return frozen time for easier testing by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/55323\n* Enhance DetectsLostConnections to Support AWS Aurora Credential Rotation Scenario by [@msaifmfz](https://github.com/msaifmfz) in https://github.com/laravel/framework/pull/55331\n* [12.x] Rename test method of failedRequest() by [@LKaemmerling](https://github.com/LKaemmerling) in https://github.com/laravel/framework/pull/55332\n* feat: Add a callback to be called on transaction failure by [@dshafik](https://github.com/dshafik) in https://github.com/laravel/framework/pull/55338\n* [12.x]  Add withRelationshipAutoloading method to model by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/55344\n* [12.x] Enable HTTP client retries when middleware throws an exception by [@27pchrisl](https://github.com/27pchrisl) in https://github.com/laravel/framework/pull/55343\n* [12.x] Fix Closure serialization error in automatic relation loading by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/55345\n* Add test for Unique validation rule with WhereIn constraints by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55351\n* Add [@throws](https://github.com/throws) in doc-blocks by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55361\n* [12.x] Update `propagateRelationAutoloadCallbackToRelation` method doc-block by [@derian-all-win-software](https://github.com/derian-all-win-software) in https://github.com/laravel/framework/pull/55363\n* [12.x]  - Redis - Establish connection first, before set the options by [@alexmontoanelli](https://github.com/alexmontoanelli) in https://github.com/laravel/framework/pull/55370\n* [12.x] Fix translation FileLoader overrides with a missing key by [@fabio-ivona](https://github.com/fabio-ivona) in https://github.com/laravel/framework/pull/55342\n* [12.x] Fix pivot model events not working when using the `withPivotValue` by [@amir9480](https://github.com/amir9480) in https://github.com/laravel/framework/pull/55280\n* [12.x] Introduce memoized cache driver by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55304\n* [12.x] Add test for Filesystem::lastModified() method by [@roshandelpoor](https://github.com/roshandelpoor) in https://github.com/laravel/framework/pull/55389\n* [12.x] Supports `pda/pheanstalk` 7 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55397\n* [12.x] Add comprehensive filesystem operation tests to FilesystemTest by [@roshandelpoor](https://github.com/roshandelpoor) in https://github.com/laravel/framework/pull/55399\n* Bump vite from 5.4.17 to 5.4.18 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot) in https://github.com/laravel/framework/pull/55402\n* Add descriptive error messages to assertViewHas() by [@3Descape](https://github.com/3Descape) in https://github.com/laravel/framework/pull/55392\n* Use Generic Types Annotations for LazyCollection Methods by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55380\n* [12.x] Add test coverage for Process sequence with multiple env variables by [@roshandelpoor](https://github.com/roshandelpoor) in https://github.com/laravel/framework/pull/55406\n* [12.x] Fix cc/bcc/replyTo address merging in `MailMessage` by [@onlime](https://github.com/onlime) in https://github.com/laravel/framework/pull/55404\n* [12.x] Add a `make` function in the `Fluent` by [@michaelnabil230](https://github.com/michaelnabil230) in https://github.com/laravel/framework/pull/55417\n\n## [v12.8.1](https://github.com/laravel/framework/compare/v12.8.0...v12.8.1) - 2025-04-08\n\n## [v12.8.0](https://github.com/laravel/framework/compare/v12.7.2...v12.8.0) - 2025-04-08\n\n* [12.x] only check for soft deletes once when mass-pruning by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55274\n* [12.x] Add createMany mass-assignment variants to `HasOneOrMany` relation by [@onlime](https://github.com/onlime) in https://github.com/laravel/framework/pull/55262\n* cosmetic: include is_array() case in match construct of getArrayableItems by [@epic-64](https://github.com/epic-64) in https://github.com/laravel/framework/pull/55275\n* Add tests for InvokeSerializedClosureCommand by [@Amirhf1](https://github.com/Amirhf1) in https://github.com/laravel/framework/pull/55281\n* [12.x] Temporarily prevents PHPUnit 12.1 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55297\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55306\n* Bump vite from 5.4.12 to 5.4.17 in /src/Illuminate/Foundation/resources/exceptions/renderer by [@dependabot](https://github.com/dependabot) in https://github.com/laravel/framework/pull/55301\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55307\n* [12.x] add generics to array types for Schema Grammars by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55314\n* [12.x] fix missing nullable for Query/Grammar::compileInsertGetId by [@taka-oyama](https://github.com/taka-oyama) in https://github.com/laravel/framework/pull/55311\n* [12.x] Adds `fromJson()` to Collection by [@DarkGhostHunter](https://github.com/DarkGhostHunter) in https://github.com/laravel/framework/pull/55310\n* [12.x] Fix `illuminate/database` usage as standalone package by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/55309\n* Correct array key in InteractsWithInput by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/55287\n* [12.x] Fix support for adding custom observable events from traits by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/55286\n* [12.x] Added Automatic Relation Loading (Eager Loading) Feature by [@litvinchuk](https://github.com/litvinchuk) in https://github.com/laravel/framework/pull/53655\n* [12.x] Modify PHPDoc for Collection::chunkWhile functions to support preserving keys by [@jsvdvis](https://github.com/jsvdvis) in https://github.com/laravel/framework/pull/55324\n* [12.x] Introduce Rule::anyOf() for Validating Against Multiple Rule Sets by [@brianferri](https://github.com/brianferri) in https://github.com/laravel/framework/pull/55191\n\n## [v12.7.2](https://github.com/laravel/framework/compare/v12.7.1...v12.7.2) - 2025-04-03\n\n## [v12.7.1](https://github.com/laravel/framework/compare/v12.7.0...v12.7.1) - 2025-04-03\n\n## [v12.7.0](https://github.com/laravel/framework/compare/v12.6.0...v12.7.0) - 2025-04-03\n\n* [12.x] `AbstractPaginator` should implement `CanBeEscapedWhenCastToString` by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55256\n* [12.x] Add `whereAttachedTo()` Eloquent builder method by [@bakerkretzmar](https://github.com/bakerkretzmar) in https://github.com/laravel/framework/pull/55245\n* Make Illuminate\\Support\\Uri Macroable by [@riesjart](https://github.com/riesjart) in https://github.com/laravel/framework/pull/55260\n* [12.x] Add resource helper functions to Model/Collections by [@TimKunze96](https://github.com/TimKunze96) in https://github.com/laravel/framework/pull/55107\n* [12.x]: Use char(36) for uuid type on MariaDB < 10.7.0 by [@boedah](https://github.com/boedah) in https://github.com/laravel/framework/pull/55197\n* [12.x] Introducing `toArray` to `ComponentAttributeBag` class by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55258\n\n## [v12.6.0](https://github.com/laravel/framework/compare/v12.5.0...v12.6.0) - 2025-04-02\n\n* [12.x] Dont stop pruning if pruning one model fails by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55237\n* [12.x] Update Date Facade Docblocks by [@fdalcin](https://github.com/fdalcin) in https://github.com/laravel/framework/pull/55235\n* Make `db:seed` command prohibitable by [@spawnia](https://github.com/spawnia) in https://github.com/laravel/framework/pull/55238\n* [12.x] Introducing `Rules\\Password::appliedRules` Method by [@devajmeireles](https://github.com/devajmeireles) in https://github.com/laravel/framework/pull/55206\n* [12.x] Allowing merging model attributes before insert via `Model::fillAndInsert()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55038\n* [12.x] Fix type hints for DateTimeZone and DateTimeInterface on DateFactory by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55243\n* [12.x] Fix DateFactory docblock type hints by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55244\n* List missing `migrate:rollback` in DB::prohibitDestructiveCommands PhpDoc by [@spawnia](https://github.com/spawnia) in https://github.com/laravel/framework/pull/55252\n* [12.x] Add `Http::requestException()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55241\n* New: Uri `pathSegments()` helper method by [@chester-sykes](https://github.com/chester-sykes) in https://github.com/laravel/framework/pull/55250\n* [12.x] Do not require returning a Builder instance from a local scope method by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55246\n\n## [v12.5.0](https://github.com/laravel/framework/compare/v12.4.1...v12.5.0) - 2025-04-01\n\n* Correct misspellings by [@szepeviktor](https://github.com/szepeviktor) in https://github.com/laravel/framework/pull/55218\n* [12.x] Add ability to flush state on Vite helper by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55228\n* [12.x] Support taggeable store flushed cache events by [@erikn69](https://github.com/erikn69) in https://github.com/laravel/framework/pull/55223\n* Revert \"[12.x] Support taggeable store flushed cache events\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55232\n* [12.x] Allow configuration of retry period for RoundRobin and Failover mail transports by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/55222\n* [12.x] Add --json option to EventListCommand by [@hotsaucejake](https://github.com/hotsaucejake) in https://github.com/laravel/framework/pull/55207\n\n## [v12.4.1](https://github.com/laravel/framework/compare/v12.4.0...v12.4.1) - 2025-03-30\n\n* [12.x] Add `Expression` type to param `$value` of `QueryBuilder` `orHaving()` method by [@faissaloux](https://github.com/faissaloux) in https://github.com/laravel/framework/pull/55202\n* [12.x] Fix URL generation with optional parameters (regression in #54811) by [@stancl](https://github.com/stancl) in https://github.com/laravel/framework/pull/55213\n* [12.x] Fix failing tests on windows OS by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55210\n\n## [v12.4.0](https://github.com/laravel/framework/compare/v12.3.0...v12.4.0) - 2025-03-29\n\n* [12.x] Reset PHP’s peak memory usage when resetting scope for queue worker by [@TimWolla](https://github.com/TimWolla) in https://github.com/laravel/framework/pull/55069\n* [12.x] Add `AsHtmlString` cast by [@ralphjsmit](https://github.com/ralphjsmit) in https://github.com/laravel/framework/pull/55071\n* [12.x] Add `Arr::sole()` method by [@ralphjsmit](https://github.com/ralphjsmit) in https://github.com/laravel/framework/pull/55070\n* Improve warning message in `ApiInstallCommand` by [@sajjadhossainshohag](https://github.com/sajjadhossainshohag) in https://github.com/laravel/framework/pull/55081\n* [12.x] use already determined `related` property by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55075\n* [12.x] use \"class-string\" where appropriate in relations by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55074\n* [12.x] `QueueFake::listenersPushed()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55063\n* [12.x] Added except() method to Model class for excluding attributes by [@vishal2931](https://github.com/vishal2931) in https://github.com/laravel/framework/pull/55072\n* [12.x] fix: add TPivotModel default and define pivot property in {Belongs,Morph}ToMany by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55086\n* [12.x] remove `@return` docblocks on constructors by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55076\n* [12.x] Add NamedScope attribute by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/54450\n* [12.x] Improve syntax highlighting for stub type files by [@kayw-geek](https://github.com/kayw-geek) in https://github.com/laravel/framework/pull/55094\n* [12.x] Prefer `new Collection` over `Collection::make` by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55091\n* [12.x] Fix except() method to support casted values by [@vishal2931](https://github.com/vishal2931) in https://github.com/laravel/framework/pull/55124\n* [12.x] Add testcase for findSole method by [@mrvipchien](https://github.com/mrvipchien) in https://github.com/laravel/framework/pull/55115\n* [12.x] Types: PasswordBroker::reset by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/55109\n* [12.x] assertThrowsNothing by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/55100\n* [12.x] Fix type nullability on PasswordBroker.events property by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/55097\n* [12.x] Fix return type annotation in decrementPendingJobs method by [@shane-zeng](https://github.com/shane-zeng) in https://github.com/laravel/framework/pull/55133\n* [12.x] Fix return type annotation in compile method by [@shane-zeng](https://github.com/shane-zeng) in https://github.com/laravel/framework/pull/55132\n* [12.x] feat: Add `whereNull` and `whereNotNull` to `Assertablejson` by [@faissaloux](https://github.com/faissaloux) in https://github.com/laravel/framework/pull/55131\n* [12.x] fix: use contextual bindings in class dependency resolution by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55090\n* Better return types for `Illuminate\\Queue\\Jobs\\Job::getJobId()` and `Illuminate\\Queue\\Jobs\\DatabaseJob::getJobId()` methods by [@petrknap](https://github.com/petrknap) in https://github.com/laravel/framework/pull/55138\n* Remove remaining [@return](https://github.com/return) tags from constructors by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55136\n* [12.x] Various URL generation bugfixes by [@stancl](https://github.com/stancl) in https://github.com/laravel/framework/pull/54811\n* Add an optional `shouldRun` method to migrations. by [@danmatthews](https://github.com/danmatthews) in https://github.com/laravel/framework/pull/55011\n* [12.x] `Uri` prevent empty query string by [@rojtjo](https://github.com/rojtjo) in https://github.com/laravel/framework/pull/55146\n* [12.x] Only call the ob_flush function if there is active buffer in eventStream by [@tonysm](https://github.com/tonysm) in https://github.com/laravel/framework/pull/55141\n* [12.x] Add CacheFlushed Event by [@tech-wolf-tw](https://github.com/tech-wolf-tw) in https://github.com/laravel/framework/pull/55142\n* [12.x] Update DateFactory method annotations for Carbon v3 compatibility by [@kayw-geek](https://github.com/kayw-geek) in https://github.com/laravel/framework/pull/55151\n* [12.x] Improve docblocks for file related methods of InteractsWithInput by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/55156\n* [12.x] Enhance `FileViewFinder` doc-blocks by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/55183\n* Support using null-safe operator with `null` value by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/55175\n* [12.x] Fix: Make Paginated Queries Consistent Across Pages by [@tomchkk](https://github.com/tomchkk) in https://github.com/laravel/framework/pull/55176\n* [12.x] Add `pipe` method query builders by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55171\n* [12.x] fix: one of many subquery constraints by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/55168\n* [12.x] fix(postgres): missing parentheses in whereDate/whereTime for json columns by [@saibotk](https://github.com/saibotk) in https://github.com/laravel/framework/pull/55159\n* Fix factory creation through attributes  by [@davidstoker](https://github.com/davidstoker) in https://github.com/laravel/framework/pull/55190\n* [12.x] Fix Concurrency::run to preserve callback result order by [@chaker2710](https://github.com/chaker2710) in https://github.com/laravel/framework/pull/55161\n* [12.x] Log: Add optional keys parameter to `Log::withoutContext` to remove selected context from future logs by [@mattroylloyd](https://github.com/mattroylloyd) in https://github.com/laravel/framework/pull/55181\n* [12.x] Add `Expression` type to param `$value` of `QueryBuilder` `having()` method by [@faissaloux](https://github.com/faissaloux) in https://github.com/laravel/framework/pull/55200\n* [12.x] Add flag to disable where clauses for `withAttributes` method on Eloquent Builder  by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55199\n\n## [v12.3.0](https://github.com/laravel/framework/compare/v12.2.0...v12.3.0) - 2025-03-18\n\n* [12.x] fixes https://github.com/laravel/octane/issues/1010 by [@mihaileu](https://github.com/mihaileu) in https://github.com/laravel/framework/pull/55008\n* Added the missing 'trashed' event to getObservablesEvents() by [@duemti](https://github.com/duemti) in https://github.com/laravel/framework/pull/55004\n* [12.x] Enhance PHPDoc for Manager classes with `@param-closure-this` by [@kayw-geek](https://github.com/kayw-geek) in https://github.com/laravel/framework/pull/55002\n* [12.x] Fix `PendingRequest` typehints for `post`, `patch`, `put`, `delete` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54998\n* [12.x] Add test for untested methods in LazyCollection by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54996\n* [12.x] fix indentation by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/54995\n* [12.x] apply final Pint fixes by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55014\n* Enhance validation tests: Add test for connection name detection in Unique rule by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54993\n* [12.x] Add json:unicode cast to support JSON_UNESCAPED_UNICODE encoding by [@fuwasegu](https://github.com/fuwasegu) in https://github.com/laravel/framework/pull/54992\n* [12.x] Add “Storage Linked” to the `about` command by [@adampatterson](https://github.com/adampatterson) in https://github.com/laravel/framework/pull/54949\n* [12.x] Add support for native JSON/JSONB column types in SQLite Schema builder by [@fuwasegu](https://github.com/fuwasegu) in https://github.com/laravel/framework/pull/54991\n* [12.x] Fix `LogManager::configurationFor()` typehint by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/55016\n* [12.x] Add missing tests for LazyCollection methods by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/55022\n* [12.x] Refactor: Structural improvement for clarity by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55018\n* Improve `toKilobytes` to handle spaces and case-insensitive units by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/55019\n* [12.x] Fix mistake in `asJson` call in `HasAttributes.php` that was recently introduced by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55017\n* [12.x] reapply Pint style changes by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55015\n* Add validation test for forEach with null and empty array values by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/55047\n* [12.x] Types: EnumeratesValues Sum by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/55044\n* [12.x] Ensure Consistent Formatting in Generated Invokable Classes by [@AhmedAlaa4611](https://github.com/AhmedAlaa4611) in https://github.com/laravel/framework/pull/55034\n* Add element type to return array in Filesystem by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/55031\n* [12.x] Add support for PostgreSQL \"unique nulls not distinct\" by [@thierry2015](https://github.com/thierry2015) in https://github.com/laravel/framework/pull/55025\n* [12.x] standardize multiline ternaries by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55056\n* [12.x] improved readability for `aliasedPivotColumns` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55055\n* [12.x] remove progress bar from PHPStan output by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55054\n* [12.x] Fixes how the fluent Date rule builder handles `date_format` by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/55052\n* Adding SSL encryption and support for MySQL connection by [@mdiktushar](https://github.com/mdiktushar) in https://github.com/laravel/framework/pull/55048\n* Revert \"Adding SSL encryption and support for MySQL connection\" by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/55057\n* Ensure queue property is nullable by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/55058\n* [12.x] return `$this` for chaining by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55060\n* [12.x] prefer `new Collection` over `collect()` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55059\n* [12.x] use \"class-string\" type for `using` pivot model by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55053\n* [12.x] multiline chaining on Collections by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/55061\n\n## [v12.2.0](https://github.com/laravel/framework/compare/v12.1.1...v12.2.0) - 2025-03-12\n\n* Add dates to allowed PHPDoc types of Builder::having() by [@miken32](https://github.com/miken32) in https://github.com/laravel/framework/pull/54899\n* [11.x] Fix double negative in `whereNotMorphedTo()` query by [@owenvoke](https://github.com/owenvoke) in https://github.com/laravel/framework/pull/54902\n* Add test for Arr::partition by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/54913\n* [11.x] Expose process checkTimeout method by [@mattmcdev](https://github.com/mattmcdev) in https://github.com/laravel/framework/pull/54912\n* [12.x] Compilable for Validation Contract by [@peterfox](https://github.com/peterfox) in https://github.com/laravel/framework/pull/54882\n* [11.x] Backport \"Change `paginate()` method return types to `\\Illuminate\\Pagination\\LengthAwarePaginator`\" by [@carestad](https://github.com/carestad) in https://github.com/laravel/framework/pull/54917\n* [11.x] Revert faulty change to `EnumeratesValues::ensure()` doc block by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/54919\n* Ensure ValidationEmailRuleTest skips tests requiring the intl extension when unavailable by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54918\n* ✅ Ensure Enum validation is case-sensitive by adding a new test case. by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54922\n* [12.x] Feature: Collection chunk without preserving keys by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/54916\n* [12.x] Add test coverage for Uri::withQueryIfMissing method by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54923\n* Fix issue with using RedisCluster with compression or serialization by [@rzv-me](https://github.com/rzv-me) in https://github.com/laravel/framework/pull/54934\n* [12.x] Add test coverage for Str::replaceMatches method  by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54930\n* [12.x] Types: Collection chunk without preserving keys  by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/54924\n* [12.x] Add `ddBody` method to TestResponse for dumping various response payloads by [@Sammyjo20](https://github.com/Sammyjo20) in https://github.com/laravel/framework/pull/54933\n* [11.x] Backport \"Fix issue with using `RedisCluster` with compression or serialization\" by [@rzv-me](https://github.com/rzv-me) in https://github.com/laravel/framework/pull/54935\n* [12.x] feat: add `CanBeOneOfMany` support to `HasOneThrough` by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/54759\n* [12.x] Hotfix - Add function_exists check to ddBody in TestResponse by [@Sammyjo20](https://github.com/Sammyjo20) in https://github.com/laravel/framework/pull/54937\n* [12.x] Refactor: Remove unnecessary variables in Str class methods by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54963\n* Add Tests for Str::pluralPascal Method by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54957\n* [12.x] Fix visibility of setUp and tearDown in tests by [@naopusyu](https://github.com/naopusyu) in https://github.com/laravel/framework/pull/54950\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54944\n* Fix missing return in `assertOnlyInvalid` by [@parth391](https://github.com/parth391) in https://github.com/laravel/framework/pull/54941\n* Handle case when migrate:install command is called and table exists by [@joe-tito](https://github.com/joe-tito) in https://github.com/laravel/framework/pull/54938\n* [11.x] Fix callOnce in Seeder so it handles arrays properly by [@lbovit](https://github.com/lbovit) in https://github.com/laravel/framework/pull/54985\n* Change \"exceptoin\" spelling mistake to \"exception\" by [@hvlucas](https://github.com/hvlucas) in https://github.com/laravel/framework/pull/54979\n* [12.x] Add test for after method in LazyCollection by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54978\n* [12.x] Add `increment` and `decrement` methods to `Context` by [@mattmcdev](https://github.com/mattmcdev) in https://github.com/laravel/framework/pull/54976\n* Ensure ExcludeIf correctly rejects a null value as an invalid condition by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54973\n* [12.x] apply Pint rule \"no_spaces_around_offset\" by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/54970\n* [12.x] apply Pint rule \"single_line_comment_style\" by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/54969\n* [12.x] do not use mix of newline and inline formatting by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/54967\n* [12.x] use single indent for multiline ternaries by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/54971\n\n## [v12.1.1](https://github.com/laravel/framework/compare/v12.1.0...v12.1.1) - 2025-03-05\n\n* [11.x] Add valid values to ensure method by [@lancepioch](https://github.com/lancepioch) in https://github.com/laravel/framework/pull/54840\n* Fix attribute name used on `Validator` instance within certain rule classes by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54845\n* [11.x] Fix `Application::interBasePath()` fails to resolve application when project name is \"vendor\" by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54871\n* [11.x] Test improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54879\n* [12.x] DocBlock: Changed typehint for `Arr::partition` method by [@AndrewMast](https://github.com/AndrewMast) in https://github.com/laravel/framework/pull/54896\n* Enhance Email and Image Dimensions Validation Tests by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54897\n* [12.x] Apply default styling rules to the notification stub by [@ahinkle](https://github.com/ahinkle) in https://github.com/laravel/framework/pull/54895\n\n## [v12.1.0](https://github.com/laravel/framework/compare/v12.0.1...v12.1.0) - 2025-03-04\n\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54782\n* [12.x] Fix incorrect typehints in `BuildsWhereDateClauses` traits by [@mohprilaksono](https://github.com/mohprilaksono) in https://github.com/laravel/framework/pull/54784\n* [12.x] Improve queries readablility by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/54791\n* [12.x] Enhance eventStream to Support Custom Events and Start Messages by [@devhammed](https://github.com/devhammed) in https://github.com/laravel/framework/pull/54776\n* [12.x] Make the PendingCommand class tappable. by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/54801\n* [12.x] Add missing union type in event stream docblock by [@devhammed](https://github.com/devhammed) in https://github.com/laravel/framework/pull/54800\n* Change return types of `paginage()` methods to `\\Illuminate\\Pagination\\LengthAwarePaginator` by [@carestad](https://github.com/carestad) in https://github.com/laravel/framework/pull/54826\n* [12.x] Check if internal `Hasher::verifyConfiguration()` method exists on driver before forwarding call by [@rodrigopedra](https://github.com/rodrigopedra) in https://github.com/laravel/framework/pull/54833\n* [11.x] Fix using `AsStringable` cast on Notifiable's key by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54818\n* Add Tests for Handling Null Primary Keys and Special Values in Unique Validation Rule by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54823\n* Improve docblock for with() method to clarify it adds to existing eag… by [@igorlealantunes](https://github.com/igorlealantunes) in https://github.com/laravel/framework/pull/54838\n* [12.x] Fix dropping schema-qualified prefixed tables by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/54834\n* [12.x] Add `Context::scope()` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54799\n* Allow Http requests to be recorded without requests being faked by [@kemp](https://github.com/kemp) in https://github.com/laravel/framework/pull/54850\n* [12.x] Adds a new method \"getRawSql\" (with embedded bindings) to the QueryException class by [@erickcomp](https://github.com/erickcomp) in https://github.com/laravel/framework/pull/54849\n* Update Inspiring.php by [@ju-gow](https://github.com/ju-gow) in https://github.com/laravel/framework/pull/54846\n* [12.x] Correct use of named argument in `Date` facade and fix a return type.  by [@lmottasin](https://github.com/lmottasin) in https://github.com/laravel/framework/pull/54847\n* Add additional tests for Rule::array validation scenarios by [@alikhosravidev](https://github.com/alikhosravidev) in https://github.com/laravel/framework/pull/54844\n* [12.x] Remove return statement  by [@mohprilaksono](https://github.com/mohprilaksono) in https://github.com/laravel/framework/pull/54842\n* Fix typos by [@co63oc](https://github.com/co63oc) in https://github.com/laravel/framework/pull/54839\n* [12.x] Do not loop through middleware when excluded is empty by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54837\n* Add test for Arr::reject method in Illuminate Support by [@mohammadrasoulasghari](https://github.com/mohammadrasoulasghari) in https://github.com/laravel/framework/pull/54863\n* [12.x] Feature: Array partition by [@liamduckett](https://github.com/liamduckett) in https://github.com/laravel/framework/pull/54859\n* [12.x] Introduce `ContextLogProcessor` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54851\n\n## [v12.0.1](https://github.com/laravel/framework/compare/v12.0.0...v12.0.1) - 2025-02-24\n\n## [v12.0.0](https://github.com/laravel/framework/compare/v11.44.0..v12.0.0...v12.0.0) - 2025-02-24\n\n* [12.x] Prep Laravel v12 by [@driesvints](https://github.com/driesvints) in https://github.com/laravel/framework/pull/50406\n* [12.x] Make `Str::is()` match multiline strings by [@SjorsO](https://github.com/SjorsO) in https://github.com/laravel/framework/pull/51196\n* [12.x] Use native MariaDB CLI commands by [@staudenmeir](https://github.com/staudenmeir) in https://github.com/laravel/framework/pull/51505\n* [12.x] Adds missing streamJson() to ResponseFactory contract by [@wilsenhc](https://github.com/wilsenhc) in https://github.com/laravel/framework/pull/51544\n* [12.x] Preserve numeric keys on the first level of the validator rules by [@Tofandel](https://github.com/Tofandel) in https://github.com/laravel/framework/pull/51516\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/52248\n* [12.x] mergeIfMissing allows merging with nested arrays by [@KIKOmanasijev](https://github.com/KIKOmanasijev) in https://github.com/laravel/framework/pull/52242\n* [12.x] Fix chunked queries not honoring user-defined limits and offsets by [@tonysm](https://github.com/tonysm) in https://github.com/laravel/framework/pull/52093\n* [12.x] Replace md5 with much faster xxhash by [@GrahamCampbell](https://github.com/GrahamCampbell) in https://github.com/laravel/framework/pull/52301\n* [12.x] Switch models to UUID v7 by [@staudenmeir](https://github.com/staudenmeir) in https://github.com/laravel/framework/pull/52433\n* [12.x] Improved algorithm for Number::pairs() by [@hotmeteor](https://github.com/hotmeteor) in https://github.com/laravel/framework/pull/52641\n* Removed Duplicated Prefix on DynamoDbStore.php by [@felipehertzer](https://github.com/felipehertzer) in https://github.com/laravel/framework/pull/52986\n* [12.x] feat: configure default datetime precision on per-grammar basis by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/51821\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/53150\n* [12.x] Fix laravel/prompt dependency version constraint for illuminate/console by [@wouterj](https://github.com/wouterj) in https://github.com/laravel/framework/pull/53146\n* [12.x] Add generic return type to Container::instance() by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/53161\n* Map output of concurrecy calls to the index of the input by [@ovp87](https://github.com/ovp87) in https://github.com/laravel/framework/pull/53135\n* Change Composer hasPackage to public by [@buihanh2304](https://github.com/buihanh2304) in https://github.com/laravel/framework/pull/53282\n* [12.x] force `Eloquent\\Collection::partition` to return a base `Collection` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53304\n* [12.x] Better support for multi-dbs in the `RefreshDatabase` trait by [@tonysm](https://github.com/tonysm) in https://github.com/laravel/framework/pull/53231\n* [12.x] Validate UUID's version optionally by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/53341\n* [12.x] Validate UUID version 2 and max by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/53368\n* [12.x] Add step parameter to LazyCollection range method by [@Ashot1995](https://github.com/Ashot1995) in https://github.com/laravel/framework/pull/53473\n* [12.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/53524\n* [12.x] Avoid breaking change `RefreshDatabase::usingInMemoryDatabase()` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/53587\n* [12.x] fix: container resolution order when resolving class dependencies by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/53522\n* [12.x] Change the default for scheduled command `emailOutput()` to only send email if output exists by [@onlime](https://github.com/onlime) in https://github.com/laravel/framework/pull/53774\n* [12.x] Add `hasMorePages()` to `CursorPaginator` contract by [@KennedyTedesco](https://github.com/KennedyTedesco) in https://github.com/laravel/framework/pull/53762\n* [12.x] modernize `DatabaseTokenRepository` and make consistent with `CacheTokenRepository` by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53746\n* [12.x] chore: remove support for Carbon v2 by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/53825\n* [12.x] use promoted properties for Auth events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53847\n* [12.x] use promoted properties for Database events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53848\n* [12.x] use promoted properties for Console events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53851\n* [12.x] use promoted properties for Mail events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53852\n* [12.x] use promoted properties for Notification events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53853\n* [12.x] use promoted properties for Routing events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53854\n* [12.x] use promoted properties for Queue events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53855\n* [12.x] Restore database token repository property documentation by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/53908\n* [12.x] Use reject() instead of a negated filter() by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/53925\n* [12.x] Use first-class callable syntax to improve static analysis by [@shaedrich](https://github.com/shaedrich) in https://github.com/laravel/framework/pull/53924\n* [12.x] add type declarations for Console Events by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53947\n* [12.x] use type declaration on property by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53970\n* [12.x] Update Symfony and PHPUnit dependencies by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54019\n* [12.x] Allow `when()` helper to accept Closure condition parameter by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/54005\n* [12.x] Add test for collapse in collections by [@amirmohammadnajmi](https://github.com/amirmohammadnajmi) in https://github.com/laravel/framework/pull/54032\n* [12.x] Add test for benchmark utilities by [@amirmohammadnajmi](https://github.com/amirmohammadnajmi) in https://github.com/laravel/framework/pull/54055\n* [12.x] Fix once() cache when used in extended static class by [@FrittenKeeZ](https://github.com/FrittenKeeZ) in https://github.com/laravel/framework/pull/54094\n* [12.x] Ignore querystring parameters using closure when validating signed url  by [@gdebrauwer](https://github.com/gdebrauwer) in https://github.com/laravel/framework/pull/54104\n* Make `dropForeignIdFor` method complementary to `foreignIdFor` by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/54102\n* Allow scoped disks to be scoped from other scoped disks by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/54124\n* [12.x] Add test for Util::getParameterClassName() by [@amirmohammadnajmi](https://github.com/amirmohammadnajmi) in https://github.com/laravel/framework/pull/54209\n* Improve eloquent attach parameter consistency by [@fabpl](https://github.com/fabpl) in https://github.com/laravel/framework/pull/54225\n* [12.x] Enhance multi-database support by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/54274\n* [12.x] Fix Session's `getCookieExpirationDate` incompatibility with Carbon 3 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54313\n* [12.x] Update minimum PHPUnit versions by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54323\n* [12.x] Prevent XSS vulnerabilities by excluding SVGs by default in image validation by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/54331\n* [12.x] Convert interfaces from docblock to method by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54348\n* [12.x] Validate paths for UTF-8 characters by [@Jubeki](https://github.com/Jubeki) in https://github.com/laravel/framework/pull/54370\n* [12.x] Fix aggregate alias when using  expression by [@iamgergo](https://github.com/iamgergo) in https://github.com/laravel/framework/pull/54418\n* Added flash method to Session interface to fix IDE issues by [@eldair](https://github.com/eldair) in https://github.com/laravel/framework/pull/54421\n* Adding the withQueryString method to the paginator interface. by [@dvlpr91](https://github.com/dvlpr91) in https://github.com/laravel/framework/pull/54462\n* [12.x] feat: --memory=0 should mean skip memory exceeded verification (Breaking Change) by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/54393\n* Auto-discover nested policies following conventional, parallel hierarchy by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/54493\n* [12.x] Reintroduce PHPUnit 10.5 supports by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54490\n* [12.x] Allow limiting bcrypt hashing to 72 bytes to prevent insecure hashes. by [@waxim](https://github.com/waxim) in https://github.com/laravel/framework/pull/54509\n* [12.x] Fix accessing `Connection` property in `Grammar` classes by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/54487\n* [12.x] Configure connection on SQLite connector by [@hafezdivandari](https://github.com/hafezdivandari) in https://github.com/laravel/framework/pull/54588\n* [12.x] Introduce Job@resolveQueuedJobClass() by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54613\n* [12.x] Bind abstract from concrete's return type  by [@peterfox](https://github.com/peterfox) in https://github.com/laravel/framework/pull/54628\n* [12.x] Query builder PDO fetch modes by [@bert-w](https://github.com/bert-w) in https://github.com/laravel/framework/pull/54443\n* [12.x] Fix Illuminate components `composer.json` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54700\n* [12.x] Bump minimum `brick/math` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54694\n* [11.x] Fix parsing `PHP_CLI_SERVER_WORKERS` as `string` instead of `int` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54724\n* [11.x] Rename Redis parse connection for cluster test method to follow naming conventions by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54721\n* [11.x] Allow `readAt` method to use in database channel by [@utsavsomaiya](https://github.com/utsavsomaiya) in https://github.com/laravel/framework/pull/54729\n* [11.x] Fix: Custom Exceptions with Multiple Arguments does not properly rein… by [@pandiselvamm](https://github.com/pandiselvamm) in https://github.com/laravel/framework/pull/54705\n* [11.x] Update ConcurrencyTest exception reference to use namespace by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54732\n* [11.x] Deprecate `Factory::$modelNameResolver` by [@samlev](https://github.com/samlev) in https://github.com/laravel/framework/pull/54736\n* Update `config/app.php` to reflect laravel/laravel change for compatibility by [@askdkc](https://github.com/askdkc) in https://github.com/laravel/framework/pull/54752\n* [11x.] Improved typehints for `InteractsWithDatabase` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54748\n* [11.x] Improved typehints for `InteractsWithExceptionHandling` && `ExceptionHandlerFake` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54747\n* Add Env::extend to support custom adapters when loading environment variables by [@andrii-androshchuk](https://github.com/andrii-androshchuk) in https://github.com/laravel/framework/pull/54756\n* [12.x] Sync `filesystem.disk.local` configurations by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54764\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\"><a href=\"https://laravel.com\" target=\"_blank\"><img src=\"https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg\" width=\"400\"></a></p>\n\n<p align=\"center\">\n<a href=\"https://github.com/laravel/framework/actions\"><img src=\"https://github.com/laravel/framework/actions/workflows/tests.yml/badge.svg\" alt=\"Build Status\"></a>\n<a href=\"https://packagist.org/packages/laravel/framework\"><img src=\"https://img.shields.io/packagist/dt/laravel/framework\" alt=\"Total Downloads\"></a>\n<a href=\"https://packagist.org/packages/laravel/framework\"><img src=\"https://img.shields.io/packagist/v/laravel/framework\" alt=\"Latest Stable Version\"></a>\n<a href=\"https://packagist.org/packages/laravel/framework\"><img src=\"https://img.shields.io/packagist/l/laravel/framework\" alt=\"License\"></a>\n<a href=\"https://insights.linuxfoundation.org/project/laravel-framework\"><img src=\"https://insights.linuxfoundation.org/api/badge/health-score?project=laravel-framework\" alt=\"Health score\"></a>\n</p>\n\n## About Laravel\n\n> **Note:** This repository contains the core code of the Laravel framework. If you want to build an application using Laravel, visit the main [Laravel repository](https://github.com/laravel/laravel).\n\nLaravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:\n\n- [Simple, fast routing engine](https://laravel.com/docs/routing).\n- [Powerful dependency injection container](https://laravel.com/docs/container).\n- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.\n- Database agnostic [schema migrations](https://laravel.com/docs/migrations).\n- [Robust background job processing](https://laravel.com/docs/queues).\n- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).\n\nLaravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked.\n\n## Learning Laravel\n\nLaravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. You can also check out [Laravel Learn](https://laravel.com/learn), where you will be guided through building a modern Laravel application.\n\nIf you're not in the mood to read, [Laracasts](https://laracasts.com) contains thousands of video tutorials covering a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.\n\nYou can also watch bite-sized lessons with real-world projects on [Laravel Learn](https://laravel.com/learn), where you will be guided through building a Laravel application from scratch while learning PHP fundamentals.\n\n## Contributing\n\nThank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).\n\n## Code of Conduct\n\nIn order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).\n\n## Security Vulnerabilities\n\nPlease review [our security policy](https://github.com/laravel/framework/security/policy) on how to report security vulnerabilities.\n\n## License\n\nThe Laravel framework is open-sourced software licensed under the [MIT license](LICENSE.md).\n"
  },
  {
    "path": "RELEASE.md",
    "content": "# Release Instructions\n\nGo to the [\"manual release\" GitHub Action](https://github.com/laravel/framework/actions/workflows/releases.yml). Then, choose \"Run workflow\", select the correct branch, and enter the version you wish to release. Next, press \"Run workflow\" to execute the action. The workflow will automatically update the version in `Application.php`, tag a new release, run the splitter script for the Illuminate components, generate release notes, create a GitHub Release, and update the `CHANGELOG.md` file.\n\n<img width=\"400\" alt=\"Screenshot 2024-05-06 at 10 46 04\" src=\"https://github.com/laravel/framework/assets/594614/4dc5efc8-946e-4e96-9e79-8e26f92ea354\">\n"
  },
  {
    "path": "bin/release.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\n# Make sure the release tag is provided.\nif (( \"$#\" != 1 ))\nthen\n    echo \"Tag has to be provided.\"\n\n    exit 1\nfi\n\nRELEASE_BRANCH=\"13.x\"\nCURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)\nVERSION=$1\n\n# Make sure current branch and release branch match.\nif [[ \"$RELEASE_BRANCH\" != \"$CURRENT_BRANCH\" ]]\nthen\n    echo \"Release branch ($RELEASE_BRANCH) does not match the current active branch ($CURRENT_BRANCH).\"\n\n    exit 1\nfi\n\n# Make sure the working directory is clear.\nif [[ ! -z \"$(git status --porcelain)\" ]]\nthen\n    echo \"Your working directory is dirty. Did you forget to commit your changes?\"\n\n    exit 1\nfi\n\n# Make sure latest changes are fetched first.\ngit fetch origin\n\n# Make sure that release branch is in sync with origin.\nif [[ $(git rev-parse HEAD) != $(git rev-parse origin/$RELEASE_BRANCH) ]]\nthen\n    echo \"Your branch is out of date with its upstream. Did you forget to pull or push any changes before releasing?\"\n\n    exit 1\nfi\n\n# Always prepend with \"v\"\nif [[ $VERSION != v*  ]]\nthen\n    VERSION=\"v$VERSION\"\nfi\n\n# Tag Framework\ngit tag $VERSION\ngit push origin --tags\n\n# Tag Components\nfor REMOTE in auth broadcasting bus cache collections conditionable config console container contracts cookie database encryption events filesystem hashing http json-schema log macroable mail notifications pagination pipeline process queue reflection redis routing session support testing translation validation view\ndo\n    echo \"\"\n    echo \"\"\n    echo \"Releasing $REMOTE\";\n\n    TMP_DIR=\"/tmp/laravel-split\"\n    REMOTE_URL=\"git@github.com:illuminate/$REMOTE.git\"\n\n    rm -rf $TMP_DIR;\n    mkdir $TMP_DIR;\n\n    (\n        cd $TMP_DIR;\n\n        git clone $REMOTE_URL .\n        git checkout \"$RELEASE_BRANCH\";\n\n        git tag $VERSION\n        git push origin --tags\n    )\ndone\n"
  },
  {
    "path": "bin/split.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\nset -x\n\nCURRENT_BRANCH=\"13.x\"\n\nfunction split()\n{\n    SHA1=`./bin/splitsh-lite --prefix=$1`\n    git push $2 \"$SHA1:refs/heads/$CURRENT_BRANCH\" -f\n}\n\nfunction remote()\n{\n    git remote add $1 $2 || true\n}\n\ngit pull origin $CURRENT_BRANCH\n\nremote auth git@github.com:illuminate/auth.git\nremote broadcasting git@github.com:illuminate/broadcasting.git\nremote bus git@github.com:illuminate/bus.git\nremote cache git@github.com:illuminate/cache.git\nremote collections git@github.com:illuminate/collections.git\nremote conditionable git@github.com:illuminate/conditionable.git\nremote config git@github.com:illuminate/config.git\nremote console git@github.com:illuminate/console.git\nremote container git@github.com:illuminate/container.git\nremote contracts git@github.com:illuminate/contracts.git\nremote cookie git@github.com:illuminate/cookie.git\nremote database git@github.com:illuminate/database.git\nremote encryption git@github.com:illuminate/encryption.git\nremote events git@github.com:illuminate/events.git\nremote filesystem git@github.com:illuminate/filesystem.git\nremote hashing git@github.com:illuminate/hashing.git\nremote http git@github.com:illuminate/http.git\nremote json-schema git@github.com:illuminate/json-schema.git\nremote log git@github.com:illuminate/log.git\nremote macroable git@github.com:illuminate/macroable.git\nremote mail git@github.com:illuminate/mail.git\nremote notifications git@github.com:illuminate/notifications.git\nremote pagination git@github.com:illuminate/pagination.git\nremote pipeline git@github.com:illuminate/pipeline.git\nremote process git@github.com:illuminate/process.git\nremote queue git@github.com:illuminate/queue.git\nremote reflection git@github.com:illuminate/reflection.git\nremote redis git@github.com:illuminate/redis.git\nremote routing git@github.com:illuminate/routing.git\nremote session git@github.com:illuminate/session.git\nremote support git@github.com:illuminate/support.git\nremote testing git@github.com:illuminate/testing.git\nremote translation git@github.com:illuminate/translation.git\nremote validation git@github.com:illuminate/validation.git\nremote view git@github.com:illuminate/view.git\n\nsplit 'src/Illuminate/Auth' auth\nsplit 'src/Illuminate/Broadcasting' broadcasting\nsplit 'src/Illuminate/Bus' bus\nsplit 'src/Illuminate/Cache' cache\nsplit 'src/Illuminate/Collections' collections\nsplit 'src/Illuminate/Conditionable' conditionable\nsplit 'src/Illuminate/Config' config\nsplit 'src/Illuminate/Console' console\nsplit 'src/Illuminate/Container' container\nsplit 'src/Illuminate/Contracts' contracts\nsplit 'src/Illuminate/Cookie' cookie\nsplit 'src/Illuminate/Database' database\nsplit 'src/Illuminate/Encryption' encryption\nsplit 'src/Illuminate/Events' events\nsplit 'src/Illuminate/Filesystem' filesystem\nsplit 'src/Illuminate/Hashing' hashing\nsplit 'src/Illuminate/Http' http\nsplit 'src/Illuminate/JsonSchema' json-schema\nsplit 'src/Illuminate/Log' log\nsplit 'src/Illuminate/Macroable' macroable\nsplit 'src/Illuminate/Mail' mail\nsplit 'src/Illuminate/Notifications' notifications\nsplit 'src/Illuminate/Pagination' pagination\nsplit 'src/Illuminate/Pipeline' pipeline\nsplit 'src/Illuminate/Process' process\nsplit 'src/Illuminate/Queue' queue\nsplit 'src/Illuminate/Reflection' reflection\nsplit 'src/Illuminate/Redis' redis\nsplit 'src/Illuminate/Routing' routing\nsplit 'src/Illuminate/Session' session\nsplit 'src/Illuminate/Support' support\nsplit 'src/Illuminate/Testing' testing\nsplit 'src/Illuminate/Translation' translation\nsplit 'src/Illuminate/Validation' validation\nsplit 'src/Illuminate/View' view\n"
  },
  {
    "path": "bin/test.sh",
    "content": "#!/usr/bin/env bash\n\ndown=false\nphp=\"8.2\"\n\nwhile true; do\n  case \"$1\" in\n    --down ) down=true; shift ;;\n    --php ) php=$2; shift 2;;\n    -- ) shift; break ;;\n    * ) break ;;\n  esac\ndone\n\nif $down; then\n    docker-compose down -t 0\n\n    exit 0\nfi\n\necho \"Ensuring docker is running\"\n\nif ! docker info > /dev/null 2>&1; then\n  echo \"Please start docker first.\"\n  exit 1\nfi\n\necho \"Ensuring services are running\"\n\ndocker-compose up -d\n\nif docker run -it --rm \"registry.gitlab.com/grahamcampbell/php:$php-base\" -r \"\\$tries = 0; while (true) { try { \\$tries++; if (\\$tries > 30) { throw new RuntimeException('MySQL never became available'); } sleep(1); new PDO('mysql:host=docker.for.mac.localhost;dbname=forge', 'root', '', [PDO::ATTR_TIMEOUT => 3]); break; } catch (PDOException \\$e) {} }\"; then\n    echo \"Running tests\"\n\n    if docker run -it -w /data -v ${PWD}:/data:delegated \\\n       --user \"www-data\" --entrypoint vendor/bin/phpunit \\\n       --env CI=1 --env DB_HOST=docker.for.mac.localhost --env DB_USERNAME=root \\\n       --env DB_HOST=docker.for.mac.localhost --env DB_PORT=3306 \\\n       --env DYNAMODB_ENDPOINT=docker.for.mac.localhost:8000 --env DYNAMODB_CACHE_TABLE=cache --env AWS_ACCESS_KEY_ID=dummy --env AWS_SECRET_ACCESS_KEY=dummy \\\n       --env REDIS_HOST=docker.for.mac.localhost --env REDIS_PORT=6379 \\\n       --env MEMCACHED_HOST=docker.for.mac.localhost --env MEMCACHED_PORT=11211 \\\n       --rm \"registry.gitlab.com/grahamcampbell/php:$php-base\" \"$@\"; then\n        exit 0\n    else\n        exit 1\n    fi\nelse\n    docker-compose logs\n    exit 1\nfi\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"laravel/framework\",\n    \"description\": \"The Laravel Framework.\",\n    \"license\": \"MIT\",\n    \"keywords\": [\n        \"framework\",\n        \"laravel\"\n    ],\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-ctype\": \"*\",\n        \"ext-filter\": \"*\",\n        \"ext-hash\": \"*\",\n        \"ext-mbstring\": \"*\",\n        \"ext-openssl\": \"*\",\n        \"ext-session\": \"*\",\n        \"ext-tokenizer\": \"*\",\n        \"composer-runtime-api\": \"^2.2\",\n        \"brick/math\": \"^0.14.2 || ^0.15 || ^0.16 || ^0.17\",\n        \"doctrine/inflector\": \"^2.0.5\",\n        \"dragonmantank/cron-expression\": \"^3.4\",\n        \"egulias/email-validator\": \"^4.0\",\n        \"fruitcake/php-cors\": \"^1.3\",\n        \"guzzlehttp/guzzle\": \"^7.8.2\",\n        \"guzzlehttp/uri-template\": \"^1.0\",\n        \"laravel/prompts\": \"^0.3.0\",\n        \"laravel/serializable-closure\": \"^2.0.10\",\n        \"league/commonmark\": \"^2.8.1\",\n        \"league/flysystem\": \"^3.25.1\",\n        \"league/flysystem-local\": \"^3.25.1\",\n        \"league/uri\": \"^7.5.1\",\n        \"monolog/monolog\": \"^3.0\",\n        \"nesbot/carbon\": \"^3.8.4\",\n        \"nunomaduro/termwind\": \"^2.0\",\n        \"psr/container\": \"^1.1.1 || ^2.0.1\",\n        \"psr/log\": \"^1.0 || ^2.0 || ^3.0\",\n        \"psr/simple-cache\": \"^1.0 || ^2.0 || ^3.0\",\n        \"ramsey/uuid\": \"^4.7\",\n        \"symfony/console\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/error-handler\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/finder\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-kernel\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/mailer\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/mime\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/polyfill-php84\": \"^1.33\",\n        \"symfony/polyfill-php85\": \"^1.33\",\n        \"symfony/process\": \"^7.4.5 || ^8.0.5\",\n        \"symfony/routing\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/uid\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/var-dumper\": \"^7.4.0 || ^8.0.0\",\n        \"tijsverkoyen/css-to-inline-styles\": \"^2.2.5\",\n        \"vlucas/phpdotenv\": \"^5.6.1\",\n        \"voku/portable-ascii\": \"^2.0.2\"\n    },\n    \"require-dev\": {\n        \"ext-gmp\": \"*\",\n        \"ably/ably-php\": \"^1.0\",\n        \"aws/aws-sdk-php\": \"^3.322.9\",\n        \"fakerphp/faker\": \"^1.24\",\n        \"guzzlehttp/promises\": \"^2.0.3\",\n        \"guzzlehttp/psr7\": \"^2.4\",\n        \"laravel/pint\": \"^1.18\",\n        \"league/flysystem-aws-s3-v3\": \"^3.25.1\",\n        \"league/flysystem-ftp\": \"^3.25.1\",\n        \"league/flysystem-path-prefixing\": \"^3.25.1\",\n        \"league/flysystem-read-only\": \"^3.25.1\",\n        \"league/flysystem-sftp-v3\": \"^3.25.1\",\n        \"mockery/mockery\": \"^1.6.10\",\n        \"opis/json-schema\": \"^2.4.1\",\n        \"orchestra/testbench-core\": \"^11.0.0\",\n        \"pda/pheanstalk\": \"^7.0.0 || ^8.0.0\",\n        \"php-http/discovery\": \"^1.15\",\n        \"phpstan/phpstan\": \"^2.0\",\n        \"phpunit/phpunit\": \"^11.5.50 || ^12.5.8 || ^13.0.3\",\n        \"predis/predis\": \"^2.3 || ^3.0\",\n        \"resend/resend-php\": \"^1.0\",\n        \"symfony/cache\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-client\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/psr-http-message-bridge\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/translation\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"replace\": {\n        \"illuminate/auth\": \"self.version\",\n        \"illuminate/broadcasting\": \"self.version\",\n        \"illuminate/bus\": \"self.version\",\n        \"illuminate/cache\": \"self.version\",\n        \"illuminate/collections\": \"self.version\",\n        \"illuminate/concurrency\": \"self.version\",\n        \"illuminate/conditionable\": \"self.version\",\n        \"illuminate/config\": \"self.version\",\n        \"illuminate/console\": \"self.version\",\n        \"illuminate/container\": \"self.version\",\n        \"illuminate/contracts\": \"self.version\",\n        \"illuminate/cookie\": \"self.version\",\n        \"illuminate/database\": \"self.version\",\n        \"illuminate/encryption\": \"self.version\",\n        \"illuminate/events\": \"self.version\",\n        \"illuminate/filesystem\": \"self.version\",\n        \"illuminate/hashing\": \"self.version\",\n        \"illuminate/http\": \"self.version\",\n        \"illuminate/json-schema\": \"self.version\",\n        \"illuminate/log\": \"self.version\",\n        \"illuminate/macroable\": \"self.version\",\n        \"illuminate/mail\": \"self.version\",\n        \"illuminate/notifications\": \"self.version\",\n        \"illuminate/pagination\": \"self.version\",\n        \"illuminate/pipeline\": \"self.version\",\n        \"illuminate/process\": \"self.version\",\n        \"illuminate/queue\": \"self.version\",\n        \"illuminate/redis\": \"self.version\",\n        \"illuminate/reflection\": \"self.version\",\n        \"illuminate/routing\": \"self.version\",\n        \"illuminate/session\": \"self.version\",\n        \"illuminate/support\": \"self.version\",\n        \"illuminate/testing\": \"self.version\",\n        \"illuminate/translation\": \"self.version\",\n        \"illuminate/validation\": \"self.version\",\n        \"illuminate/view\": \"self.version\",\n        \"spatie/once\": \"*\"\n    },\n    \"conflict\": {\n        \"tightenco/collect\": \"<5.5.33\"\n    },\n    \"provide\": {\n        \"psr/container-implementation\": \"1.1 || 2.0\",\n        \"psr/log-implementation\": \"1.0 || 2.0 || 3.0\",\n        \"psr/simple-cache-implementation\": \"1.0 || 2.0 || 3.0\"\n    },\n    \"suggest\": {\n        \"ext-apcu\": \"Required to use the APC cache driver.\",\n        \"ext-fileinfo\": \"Required to use the Filesystem class.\",\n        \"ext-ftp\": \"Required to use the Flysystem FTP driver.\",\n        \"ext-gd\": \"Required to use Illuminate\\\\Http\\\\Testing\\\\FileFactory::image().\",\n        \"ext-memcached\": \"Required to use the memcache cache driver.\",\n        \"ext-pcntl\": \"Required to use all features of the queue worker and console signal trapping.\",\n        \"ext-pdo\": \"Required to use all database features.\",\n        \"ext-posix\": \"Required to use all features of the queue worker.\",\n        \"ext-redis\": \"Required to use the Redis cache and queue drivers (^4.0 || ^5.0 || ^6.0).\",\n        \"ably/ably-php\": \"Required to use the Ably broadcast driver (^1.0).\",\n        \"aws/aws-sdk-php\": \"Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).\",\n        \"brianium/paratest\": \"Required to run tests in parallel (^7.0 || ^8.0).\",\n        \"fakerphp/faker\": \"Required to generate fake data using the fake() helper (^1.23).\",\n        \"filp/whoops\": \"Required for friendly error pages in development (^2.14.3).\",\n        \"laravel/tinker\": \"Required to use the tinker console command (^2.0).\",\n        \"league/flysystem-aws-s3-v3\": \"Required to use the Flysystem S3 driver (^3.25.1).\",\n        \"league/flysystem-ftp\": \"Required to use the Flysystem FTP driver (^3.25.1).\",\n        \"league/flysystem-path-prefixing\": \"Required to use the scoped driver (^3.25.1).\",\n        \"league/flysystem-read-only\": \"Required to use read-only disks (^3.25.1)\",\n        \"league/flysystem-sftp-v3\": \"Required to use the Flysystem SFTP driver (^3.25.1).\",\n        \"mockery/mockery\": \"Required to use mocking (^1.6).\",\n        \"pda/pheanstalk\": \"Required to use the beanstalk queue driver (^7.0 || ^8.0).\",\n        \"php-http/discovery\": \"Required to use PSR-7 bridging features (^1.15).\",\n        \"phpunit/phpunit\": \"Required to use assertions and run tests (^11.5.50 || ^12.5.8 || ^13.0.3).\",\n        \"predis/predis\": \"Required to use the predis connector (^2.3 || ^3.0).\",\n        \"psr/http-message\": \"Required to allow Storage::put to accept a StreamInterface (^1.0).\",\n        \"pusher/pusher-php-server\": \"Required to use the Pusher broadcast driver (^6.0 || ^7.0).\",\n        \"resend/resend-php\": \"Required to enable support for the Resend mail transport (^0.10.0 || ^1.0).\",\n        \"symfony/cache\": \"Required to PSR-6 cache bridge (^7.4 || ^8.0).\",\n        \"symfony/filesystem\": \"Required to enable support for relative symbolic links (^7.4 || ^8.0).\",\n        \"symfony/http-client\": \"Required to enable support for the Symfony API mail transports (^7.4 || ^8.0).\",\n        \"symfony/mailgun-mailer\": \"Required to enable support for the Mailgun mail transport (^7.4 || ^8.0).\",\n        \"symfony/postmark-mailer\": \"Required to enable support for the Postmark mail transport (^7.4 || ^8.0).\",\n        \"symfony/psr-http-message-bridge\": \"Required to use PSR-7 bridging features (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"prefer-stable\": true,\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\\": \"src/Illuminate/\",\n            \"Illuminate\\\\Support\\\\\": [\n                \"src/Illuminate/Macroable/\",\n                \"src/Illuminate/Collections/\",\n                \"src/Illuminate/Conditionable/\",\n                \"src/Illuminate/Reflection/\"\n            ]\n        },\n        \"files\": [\n            \"src/Illuminate/Collections/functions.php\",\n            \"src/Illuminate/Collections/helpers.php\",\n            \"src/Illuminate/Events/functions.php\",\n            \"src/Illuminate/Filesystem/functions.php\",\n            \"src/Illuminate/Foundation/helpers.php\",\n            \"src/Illuminate/Log/functions.php\",\n            \"src/Illuminate/Reflection/helpers.php\",\n            \"src/Illuminate/Support/functions.php\",\n            \"src/Illuminate/Support/helpers.php\"\n        ]\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Tests\\\\\": \"tests/\"\n        },\n        \"files\": [\n            \"tests/Database/stubs/MigrationCreatorFakeMigration.php\"\n        ]\n    },\n    \"config\": {\n        \"allow-plugins\": {\n            \"composer/package-versions-deprecated\": true,\n            \"php-http/discovery\": false\n        },\n        \"audit\": {\n            \"ignore\": {\n                \"GHSA-vvj3-c3rp-c85p\": \"Ensure testing features are compatible with affected PHPUnit versions\"\n            }\n        },\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "config/app.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\ServiceProvider;\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Name\n    |--------------------------------------------------------------------------\n    |\n    | This value is the name of your application, which will be used when the\n    | framework needs to place the application's name in a notification or\n    | other UI elements where an application name needs to be displayed.\n    |\n    */\n\n    'name' => env('APP_NAME', 'Laravel'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Environment\n    |--------------------------------------------------------------------------\n    |\n    | This value determines the \"environment\" your application is currently\n    | running in. This may determine how you prefer to configure various\n    | services the application utilizes. Set this in your \".env\" file.\n    |\n    */\n\n    'env' => env('APP_ENV', 'production'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Debug Mode\n    |--------------------------------------------------------------------------\n    |\n    | When your application is in debug mode, detailed error messages with\n    | stack traces will be shown on every error that occurs within your\n    | application. If disabled, a simple generic error page is shown.\n    |\n    */\n\n    'debug' => (bool) env('APP_DEBUG', false),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application URL\n    |--------------------------------------------------------------------------\n    |\n    | This URL is used by the console to properly generate URLs when using\n    | the Artisan command line tool. You should set this to the root of\n    | the application so that it's available within Artisan commands.\n    |\n    */\n\n    'url' => env('APP_URL', 'http://localhost'),\n\n    'frontend_url' => env('FRONTEND_URL', 'http://localhost:3000'),\n\n    'asset_url' => env('ASSET_URL'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Timezone\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the default timezone for your application, which\n    | will be used by the PHP date and date-time functions. The timezone\n    | is set to \"UTC\" by default as it is suitable for most use cases.\n    |\n    */\n\n    'timezone' => 'UTC',\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Locale Configuration\n    |--------------------------------------------------------------------------\n    |\n    | The application locale determines the default locale that will be used\n    | by Laravel's translation / localization methods. This option can be\n    | set to any locale for which you plan to have translation strings.\n    |\n    */\n\n    'locale' => env('APP_LOCALE', 'en'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Fallback Locale\n    |--------------------------------------------------------------------------\n    |\n    | The fallback locale determines the locale to use when the default one\n    | is not available. You may change the value to correspond to any of\n    | the languages which are currently supported by your application.\n    |\n    */\n\n    'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Faker Locale\n    |--------------------------------------------------------------------------\n    |\n    | This locale will be used by the Faker PHP library when generating fake\n    | data for your database seeds. For example, this will be used to get\n    | localized telephone numbers, street address information and more.\n    |\n    */\n\n    'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Encryption Key\n    |--------------------------------------------------------------------------\n    |\n    | This key is utilized by Laravel's encryption services and should be set\n    | to a random, 32 character string to ensure that all encrypted values\n    | are secure. You should do this prior to deploying the application.\n    |\n    */\n\n    'cipher' => 'AES-256-CBC',\n\n    'key' => env('APP_KEY'),\n\n    'previous_keys' => [\n        ...array_filter(\n            explode(',', (string) env('APP_PREVIOUS_KEYS', ''))\n        ),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Maintenance Mode Driver\n    |--------------------------------------------------------------------------\n    |\n    | These configuration options determine the driver used to determine and\n    | manage Laravel's \"maintenance mode\" status. The \"cache\" driver will\n    | allow maintenance mode to be controlled across multiple machines.\n    |\n    | Supported drivers: \"file\", \"cache\"\n    |\n    */\n\n    'maintenance' => [\n        'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),\n        'store' => env('APP_MAINTENANCE_STORE', 'database'),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Autoloaded Service Providers\n    |--------------------------------------------------------------------------\n    |\n    | The service providers listed here will be automatically loaded on any\n    | requests to your application. You may add your own services to the\n    | arrays below to provide additional features to this application.\n    |\n    */\n\n    'providers' => ServiceProvider::defaultProviders()->merge([\n        // Package Service Providers...\n    ])->merge([\n        // Application Service Providers...\n        // App\\Providers\\AppServiceProvider::class,\n    ])->merge([\n        // Added Service Providers (Do not remove this line)...\n    ])->toArray(),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Class Aliases\n    |--------------------------------------------------------------------------\n    |\n    | This array of class aliases will be registered when this application\n    | is started. You may add any additional class aliases which should\n    | be loaded to the array. For speed, all aliases are lazy loaded.\n    |\n    */\n\n    'aliases' => Facade::defaultAliases()->merge([\n        // 'Example' => App\\Facades\\Example::class,\n    ])->toArray(),\n\n];\n"
  },
  {
    "path": "config/auth.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Authentication Defaults\n    |--------------------------------------------------------------------------\n    |\n    | This option defines the default authentication \"guard\" and password\n    | reset \"broker\" for your application. You may change these values\n    | as required, but they're a perfect start for most applications.\n    |\n    */\n\n    'defaults' => [\n        'guard' => env('AUTH_GUARD', 'web'),\n        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Authentication Guards\n    |--------------------------------------------------------------------------\n    |\n    | Next, you may define every authentication guard for your application.\n    | Of course, a great default configuration has been defined for you\n    | which utilizes session storage plus the Eloquent user provider.\n    |\n    | All authentication guards have a user provider, which defines how the\n    | users are actually retrieved out of your database or other storage\n    | system used by the application. Typically, Eloquent is utilized.\n    |\n    | Supported: \"session\"\n    |\n    */\n\n    'guards' => [\n        'web' => [\n            'driver' => 'session',\n            'provider' => 'users',\n        ],\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | User Providers\n    |--------------------------------------------------------------------------\n    |\n    | All authentication guards have a user provider, which defines how the\n    | users are actually retrieved out of your database or other storage\n    | system used by the application. Typically, Eloquent is utilized.\n    |\n    | If you have multiple user tables or models you may configure multiple\n    | providers to represent the model / table. These providers may then\n    | be assigned to any extra authentication guards you have defined.\n    |\n    | Supported: \"database\", \"eloquent\"\n    |\n    */\n\n    'providers' => [\n        'users' => [\n            'driver' => 'eloquent',\n            'model' => env('AUTH_MODEL', App\\Models\\User::class),\n        ],\n\n        // 'users' => [\n        //     'driver' => 'database',\n        //     'table' => 'users',\n        // ],\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Resetting Passwords\n    |--------------------------------------------------------------------------\n    |\n    | These configuration options specify the behavior of Laravel's password\n    | reset functionality, including the table utilized for token storage\n    | and the user provider that is invoked to actually retrieve users.\n    |\n    | The expiry time is the number of minutes that each reset token will be\n    | considered valid. This security feature keeps tokens short-lived so\n    | they have less time to be guessed. You may change this as needed.\n    |\n    | The throttle setting is the number of seconds a user must wait before\n    | generating more password reset tokens. This prevents the user from\n    | quickly generating a very large amount of password reset tokens.\n    |\n    */\n\n    'passwords' => [\n        'users' => [\n            'provider' => 'users',\n            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),\n            'expire' => 60,\n            'throttle' => 60,\n        ],\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Password Confirmation Timeout\n    |--------------------------------------------------------------------------\n    |\n    | Here you may define the number of seconds before a password confirmation\n    | window expires and users are asked to re-enter their password via the\n    | confirmation screen. By default, the timeout lasts for three hours.\n    |\n    */\n\n    'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),\n\n];\n"
  },
  {
    "path": "config/broadcasting.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Broadcaster\n    |--------------------------------------------------------------------------\n    |\n    | This option controls the default broadcaster that will be used by the\n    | framework when an event needs to be broadcast. You may set this to\n    | any of the connections defined in the \"connections\" array below.\n    |\n    | Supported: \"reverb\", \"pusher\", \"ably\", \"redis\", \"log\", \"null\"\n    |\n    */\n\n    'default' => env('BROADCAST_CONNECTION', 'null'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Broadcast Connections\n    |--------------------------------------------------------------------------\n    |\n    | Here you may define all of the broadcast connections that will be used\n    | to broadcast events to other systems or over WebSockets. Samples of\n    | each available type of connection are provided inside this array.\n    |\n    */\n\n    'connections' => [\n\n        'reverb' => [\n            'driver' => 'reverb',\n            'key' => env('REVERB_APP_KEY'),\n            'secret' => env('REVERB_APP_SECRET'),\n            'app_id' => env('REVERB_APP_ID'),\n            'options' => [\n                'host' => env('REVERB_HOST'),\n                'port' => env('REVERB_PORT', 443),\n                'scheme' => env('REVERB_SCHEME', 'https'),\n                'useTLS' => env('REVERB_SCHEME', 'https') === 'https',\n            ],\n            'client_options' => [\n                // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html\n            ],\n        ],\n\n        'pusher' => [\n            'driver' => 'pusher',\n            'key' => env('PUSHER_APP_KEY'),\n            'secret' => env('PUSHER_APP_SECRET'),\n            'app_id' => env('PUSHER_APP_ID'),\n            'options' => [\n                'cluster' => env('PUSHER_APP_CLUSTER'),\n                'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',\n                'port' => env('PUSHER_PORT', 443),\n                'scheme' => env('PUSHER_SCHEME', 'https'),\n                'encrypted' => true,\n                'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',\n            ],\n            'client_options' => [\n                // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html\n            ],\n        ],\n\n        'ably' => [\n            'driver' => 'ably',\n            'key' => env('ABLY_KEY'),\n        ],\n\n        'log' => [\n            'driver' => 'log',\n        ],\n\n        'null' => [\n            'driver' => 'null',\n        ],\n\n    ],\n\n];\n"
  },
  {
    "path": "config/cache.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Cache Store\n    |--------------------------------------------------------------------------\n    |\n    | This option controls the default cache store that will be used by the\n    | framework. This connection is utilized if another isn't explicitly\n    | specified when running a cache operation inside the application.\n    |\n    */\n\n    'default' => env('CACHE_STORE', 'database'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Cache Stores\n    |--------------------------------------------------------------------------\n    |\n    | Here you may define all of the cache \"stores\" for your application as\n    | well as their drivers. You may even define multiple stores for the\n    | same cache driver to group types of items stored in your caches.\n    |\n    | Supported drivers: \"array\", \"database\", \"file\", \"memcached\",\n    |                    \"redis\", \"dynamodb\", \"octane\",\n    |                    \"failover\", \"null\"\n    |\n    */\n\n    'stores' => [\n\n        'array' => [\n            'driver' => 'array',\n            'serialize' => false,\n        ],\n\n        'session' => [\n            'driver' => 'session',\n            'key' => env('SESSION_CACHE_KEY', '_cache'),\n        ],\n\n        'database' => [\n            'driver' => 'database',\n            'connection' => env('DB_CACHE_CONNECTION'),\n            'table' => env('DB_CACHE_TABLE', 'cache'),\n            'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'),\n            'lock_table' => env('DB_CACHE_LOCK_TABLE'),\n        ],\n\n        'file' => [\n            'driver' => 'file',\n            'path' => storage_path('framework/cache/data'),\n            'lock_path' => storage_path('framework/cache/data'),\n        ],\n\n        'memcached' => [\n            'driver' => 'memcached',\n            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),\n            'sasl' => [\n                env('MEMCACHED_USERNAME'),\n                env('MEMCACHED_PASSWORD'),\n            ],\n            'options' => [\n                // Memcached::OPT_CONNECT_TIMEOUT => 2000,\n            ],\n            'servers' => [\n                [\n                    'host' => env('MEMCACHED_HOST', '127.0.0.1'),\n                    'port' => env('MEMCACHED_PORT', 11211),\n                    'weight' => 100,\n                ],\n            ],\n        ],\n\n        'redis' => [\n            'driver' => 'redis',\n            'connection' => env('REDIS_CACHE_CONNECTION', 'cache'),\n            'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'),\n        ],\n\n        'dynamodb' => [\n            'driver' => 'dynamodb',\n            'key' => env('AWS_ACCESS_KEY_ID'),\n            'secret' => env('AWS_SECRET_ACCESS_KEY'),\n            'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),\n            'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),\n            'endpoint' => env('DYNAMODB_ENDPOINT'),\n        ],\n\n        'octane' => [\n            'driver' => 'octane',\n        ],\n\n        'failover' => [\n            'driver' => 'failover',\n            'stores' => [\n                'database',\n                'array',\n            ],\n        ],\n\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Cache Key Prefix\n    |--------------------------------------------------------------------------\n    |\n    | When utilizing the APC, database, memcached, Redis, and DynamoDB cache\n    | stores, there might be other applications using the same cache. For\n    | that reason, you may prefix every cache key to avoid collisions.\n    |\n    */\n\n    'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'),\n\n];\n"
  },
  {
    "path": "config/concurrency.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Concurrency Driver\n    |--------------------------------------------------------------------------\n    |\n    | This option determines the default concurrency driver that will be used\n    | by Laravel's concurrency functions. By default, concurrent work will\n    | be sent to isolated PHP processes which will return their results.\n    |\n    | Supported: \"process\", \"fork\", \"sync\"\n    |\n    */\n\n    'default' => env('CONCURRENCY_DRIVER', 'process'),\n\n];\n"
  },
  {
    "path": "config/cors.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Cross-Origin Resource Sharing (CORS) Configuration\n    |--------------------------------------------------------------------------\n    |\n    | Here you may configure your settings for cross-origin resource sharing\n    | or \"CORS\". This determines what cross-origin operations may execute\n    | in web browsers. You are free to adjust these settings as needed.\n    |\n    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\n    |\n    */\n\n    'paths' => ['api/*', 'sanctum/csrf-cookie'],\n\n    'allowed_methods' => ['*'],\n\n    'allowed_origins' => ['*'],\n\n    'allowed_origins_patterns' => [],\n\n    'allowed_headers' => ['*'],\n\n    'exposed_headers' => [],\n\n    'max_age' => 0,\n\n    'supports_credentials' => false,\n\n];\n"
  },
  {
    "path": "config/database.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Database Connection Name\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify which of the database connections below you wish\n    | to use as your default connection for database operations. This is\n    | the connection which will be utilized unless another connection\n    | is explicitly specified when you execute a query / statement.\n    |\n    */\n\n    'default' => env('DB_CONNECTION', 'sqlite'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Database Connections\n    |--------------------------------------------------------------------------\n    |\n    | Below are all of the database connections defined for your application.\n    | An example configuration is provided for each database system which\n    | is supported by Laravel. You're free to add / remove connections.\n    |\n    */\n\n    'connections' => [\n\n        'sqlite' => [\n            'driver' => 'sqlite',\n            'url' => env('DB_URL'),\n            'database' => env('DB_DATABASE', database_path('database.sqlite')),\n            'prefix' => '',\n            'prefix_indexes' => null,\n            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),\n            'busy_timeout' => null,\n            'journal_mode' => null,\n            'synchronous' => null,\n            'transaction_mode' => 'DEFERRED',\n            'pragmas' => [],\n        ],\n\n        'mysql' => [\n            'driver' => 'mysql',\n            'url' => env('DB_URL'),\n            'host' => env('DB_HOST', '127.0.0.1'),\n            'port' => env('DB_PORT', '3306'),\n            'database' => env('DB_DATABASE', 'laravel'),\n            'username' => env('DB_USERNAME', 'root'),\n            'password' => env('DB_PASSWORD', ''),\n            'unix_socket' => env('DB_SOCKET', ''),\n            'charset' => env('DB_CHARSET', 'utf8mb4'),\n            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),\n            'prefix' => '',\n            'prefix_indexes' => true,\n            'strict' => true,\n            'engine' => null,\n            'options' => extension_loaded('pdo_mysql') ? array_filter([\n                (PHP_VERSION_ID >= 80500 ? Pdo\\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),\n            ]) : [],\n        ],\n\n        'mariadb' => [\n            'driver' => 'mariadb',\n            'url' => env('DB_URL'),\n            'host' => env('DB_HOST', '127.0.0.1'),\n            'port' => env('DB_PORT', '3306'),\n            'database' => env('DB_DATABASE', 'laravel'),\n            'username' => env('DB_USERNAME', 'root'),\n            'password' => env('DB_PASSWORD', ''),\n            'unix_socket' => env('DB_SOCKET', ''),\n            'charset' => env('DB_CHARSET', 'utf8mb4'),\n            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),\n            'prefix' => '',\n            'prefix_indexes' => true,\n            'strict' => true,\n            'engine' => null,\n            'options' => extension_loaded('pdo_mysql') ? array_filter([\n                (PHP_VERSION_ID >= 80500 ? Pdo\\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),\n            ]) : [],\n        ],\n\n        'pgsql' => [\n            'driver' => 'pgsql',\n            'url' => env('DB_URL'),\n            'host' => env('DB_HOST', '127.0.0.1'),\n            'port' => env('DB_PORT', '5432'),\n            'database' => env('DB_DATABASE', 'laravel'),\n            'username' => env('DB_USERNAME', 'root'),\n            'password' => env('DB_PASSWORD', ''),\n            'charset' => env('DB_CHARSET', 'utf8'),\n            'prefix' => '',\n            'prefix_indexes' => true,\n            'search_path' => 'public',\n            'sslmode' => 'prefer',\n        ],\n\n        'sqlsrv' => [\n            'driver' => 'sqlsrv',\n            'url' => env('DB_URL'),\n            'host' => env('DB_HOST', 'localhost'),\n            'port' => env('DB_PORT', '1433'),\n            'database' => env('DB_DATABASE', 'laravel'),\n            'username' => env('DB_USERNAME', 'root'),\n            'password' => env('DB_PASSWORD', ''),\n            'charset' => env('DB_CHARSET', 'utf8'),\n            'prefix' => '',\n            'prefix_indexes' => true,\n            // 'encrypt' => env('DB_ENCRYPT', 'yes'),\n            // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),\n        ],\n\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Migration Repository Table\n    |--------------------------------------------------------------------------\n    |\n    | This table keeps track of all the migrations that have already run for\n    | your application. Using this information, we can determine which of\n    | the migrations on disk haven't actually been run on the database.\n    |\n    */\n\n    'migrations' => [\n        'table' => 'migrations',\n        'update_date_on_publish' => true,\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Redis Databases\n    |--------------------------------------------------------------------------\n    |\n    | Redis is an open source, fast, and advanced key-value store that also\n    | provides a richer body of commands than a typical key-value system\n    | such as Memcached. You may define your connection settings here.\n    |\n    */\n\n    'redis' => [\n\n        'client' => env('REDIS_CLIENT', 'phpredis'),\n\n        'options' => [\n            'cluster' => env('REDIS_CLUSTER', 'redis'),\n            'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),\n            'persistent' => env('REDIS_PERSISTENT', false),\n        ],\n\n        'default' => [\n            'url' => env('REDIS_URL'),\n            'host' => env('REDIS_HOST', '127.0.0.1'),\n            'username' => env('REDIS_USERNAME'),\n            'password' => env('REDIS_PASSWORD'),\n            'port' => env('REDIS_PORT', '6379'),\n            'database' => env('REDIS_DB', '0'),\n            'max_retries' => env('REDIS_MAX_RETRIES', 3),\n            'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'),\n            'backoff_base' => env('REDIS_BACKOFF_BASE', 100),\n            'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000),\n        ],\n\n        'cache' => [\n            'url' => env('REDIS_URL'),\n            'host' => env('REDIS_HOST', '127.0.0.1'),\n            'username' => env('REDIS_USERNAME'),\n            'password' => env('REDIS_PASSWORD'),\n            'port' => env('REDIS_PORT', '6379'),\n            'database' => env('REDIS_CACHE_DB', '1'),\n            'max_retries' => env('REDIS_MAX_RETRIES', 3),\n            'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'),\n            'backoff_base' => env('REDIS_BACKOFF_BASE', 100),\n            'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000),\n        ],\n\n    ],\n\n];\n"
  },
  {
    "path": "config/filesystems.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Filesystem Disk\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the default filesystem disk that should be used\n    | by the framework. The \"local\" disk, as well as a variety of cloud\n    | based disks are available to your application for file storage.\n    |\n    */\n\n    'default' => env('FILESYSTEM_DISK', 'local'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Filesystem Disks\n    |--------------------------------------------------------------------------\n    |\n    | Below you may configure as many filesystem disks as necessary, and you\n    | may even configure multiple disks for the same driver. Examples for\n    | most supported storage drivers are configured here for reference.\n    |\n    | Supported drivers: \"local\", \"ftp\", \"sftp\", \"s3\"\n    |\n    */\n\n    'disks' => [\n\n        'local' => [\n            'driver' => 'local',\n            'root' => storage_path('app/private'),\n            'serve' => true,\n            'throw' => false,\n            'report' => false,\n        ],\n\n        'public' => [\n            'driver' => 'local',\n            'root' => storage_path('app/public'),\n            'url' => rtrim((string) env('APP_URL'), '/').'/storage',\n            'visibility' => 'public',\n            'throw' => false,\n            'report' => false,\n        ],\n\n        's3' => [\n            'driver' => 's3',\n            'key' => env('AWS_ACCESS_KEY_ID'),\n            'secret' => env('AWS_SECRET_ACCESS_KEY'),\n            'region' => env('AWS_DEFAULT_REGION'),\n            'bucket' => env('AWS_BUCKET'),\n            'url' => env('AWS_URL'),\n            'endpoint' => env('AWS_ENDPOINT'),\n            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),\n            'throw' => false,\n            'report' => false,\n        ],\n\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Symbolic Links\n    |--------------------------------------------------------------------------\n    |\n    | Here you may configure the symbolic links that will be created when the\n    | `storage:link` Artisan command is executed. The array keys should be\n    | the locations of the links and the values should be their targets.\n    |\n    */\n\n    'links' => [\n        public_path('storage') => storage_path('app/public'),\n    ],\n\n];\n"
  },
  {
    "path": "config/hashing.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Hash Driver\n    |--------------------------------------------------------------------------\n    |\n    | This option controls the default hash driver that will be used to hash\n    | passwords for your application. By default, the bcrypt algorithm is\n    | used; however, you remain free to modify this option if you wish.\n    |\n    | Supported: \"bcrypt\", \"argon\", \"argon2id\"\n    |\n    */\n\n    'driver' => env('HASH_DRIVER', 'bcrypt'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Bcrypt Options\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the configuration options that should be used when\n    | passwords are hashed using the Bcrypt algorithm. This will allow you\n    | to control the amount of time it takes to hash the given password.\n    |\n    */\n\n    'bcrypt' => [\n        'rounds' => env('BCRYPT_ROUNDS', 12),\n        'verify' => env('HASH_VERIFY', true),\n        'limit' => env('BCRYPT_LIMIT', null),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Argon Options\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the configuration options that should be used when\n    | passwords are hashed using the Argon algorithm. These will allow you\n    | to control the amount of time it takes to hash the given password.\n    |\n    */\n\n    'argon' => [\n        'memory' => env('ARGON_MEMORY', 65536),\n        'threads' => env('ARGON_THREADS', 1),\n        'time' => env('ARGON_TIME', 4),\n        'verify' => env('HASH_VERIFY', true),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Rehash On Login\n    |--------------------------------------------------------------------------\n    |\n    | Setting this option to true will tell Laravel to automatically rehash\n    | the user's password during login if the configured work factor for\n    | the algorithm has changed, allowing graceful upgrades of hashes.\n    |\n    */\n\n    'rehash_on_login' => true,\n\n];\n"
  },
  {
    "path": "config/logging.php",
    "content": "<?php\n\nuse Monolog\\Handler\\NullHandler;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\SyslogUdpHandler;\nuse Monolog\\Processor\\PsrLogMessageProcessor;\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Log Channel\n    |--------------------------------------------------------------------------\n    |\n    | This option defines the default log channel that is utilized to write\n    | messages to your logs. The value provided here should match one of\n    | the channels present in the list of \"channels\" configured below.\n    |\n    */\n\n    'default' => env('LOG_CHANNEL', 'stack'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Deprecations Log Channel\n    |--------------------------------------------------------------------------\n    |\n    | This option controls the log channel that should be used to log warnings\n    | regarding deprecated PHP and library features. This allows you to get\n    | your application ready for upcoming major versions of dependencies.\n    |\n    */\n\n    'deprecations' => [\n        'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),\n        'trace' => env('LOG_DEPRECATIONS_TRACE', false),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Log Channels\n    |--------------------------------------------------------------------------\n    |\n    | Here you may configure the log channels for your application. Laravel\n    | utilizes the Monolog PHP logging library, which includes a variety\n    | of powerful log handlers and formatters that you're free to use.\n    |\n    | Available drivers: \"single\", \"daily\", \"slack\", \"syslog\",\n    |                    \"errorlog\", \"monolog\", \"custom\", \"stack\"\n    |\n    */\n\n    'channels' => [\n\n        'stack' => [\n            'driver' => 'stack',\n            'channels' => explode(',', (string) env('LOG_STACK', 'single')),\n            'ignore_exceptions' => false,\n        ],\n\n        'single' => [\n            'driver' => 'single',\n            'path' => storage_path('logs/laravel.log'),\n            'level' => env('LOG_LEVEL', 'debug'),\n            'replace_placeholders' => true,\n        ],\n\n        'daily' => [\n            'driver' => 'daily',\n            'path' => storage_path('logs/laravel.log'),\n            'level' => env('LOG_LEVEL', 'debug'),\n            'days' => env('LOG_DAILY_DAYS', 14),\n            'replace_placeholders' => true,\n        ],\n\n        'slack' => [\n            'driver' => 'slack',\n            'url' => env('LOG_SLACK_WEBHOOK_URL'),\n            'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),\n            'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),\n            'level' => env('LOG_LEVEL', 'critical'),\n            'replace_placeholders' => true,\n        ],\n\n        'papertrail' => [\n            'driver' => 'monolog',\n            'level' => env('LOG_LEVEL', 'debug'),\n            'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),\n            'handler_with' => [\n                'host' => env('PAPERTRAIL_URL'),\n                'port' => env('PAPERTRAIL_PORT'),\n                'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),\n            ],\n            'processors' => [PsrLogMessageProcessor::class],\n        ],\n\n        'stderr' => [\n            'driver' => 'monolog',\n            'level' => env('LOG_LEVEL', 'debug'),\n            'handler' => StreamHandler::class,\n            'handler_with' => [\n                'stream' => 'php://stderr',\n            ],\n            'formatter' => env('LOG_STDERR_FORMATTER'),\n            'processors' => [PsrLogMessageProcessor::class],\n        ],\n\n        'syslog' => [\n            'driver' => 'syslog',\n            'level' => env('LOG_LEVEL', 'debug'),\n            'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER),\n            'replace_placeholders' => true,\n        ],\n\n        'errorlog' => [\n            'driver' => 'errorlog',\n            'level' => env('LOG_LEVEL', 'debug'),\n            'replace_placeholders' => true,\n        ],\n\n        'null' => [\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n        ],\n\n        'emergency' => [\n            'path' => storage_path('logs/laravel.log'),\n        ],\n\n    ],\n\n];\n"
  },
  {
    "path": "config/mail.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Mailer\n    |--------------------------------------------------------------------------\n    |\n    | This option controls the default mailer that is used to send all email\n    | messages unless another mailer is explicitly specified when sending\n    | the message. All additional mailers can be configured within the\n    | \"mailers\" array. Examples of each type of mailer are provided.\n    |\n    */\n\n    'default' => env('MAIL_MAILER', 'log'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Mailer Configurations\n    |--------------------------------------------------------------------------\n    |\n    | Here you may configure all of the mailers used by your application plus\n    | their respective settings. Several examples have been configured for\n    | you and you are free to add your own as your application requires.\n    |\n    | Laravel supports a variety of mail \"transport\" drivers that can be used\n    | when delivering an email. You may specify which one you're using for\n    | your mailers below. You may also add additional mailers if needed.\n    |\n    | Supported: \"smtp\", \"sendmail\", \"mailgun\", \"ses\", \"ses-v2\",\n    |            \"postmark\", \"resend\", \"log\", \"array\",\n    |            \"failover\", \"roundrobin\"\n    |\n    */\n\n    'mailers' => [\n\n        'smtp' => [\n            'transport' => 'smtp',\n            'scheme' => env('MAIL_SCHEME'),\n            'url' => env('MAIL_URL'),\n            'host' => env('MAIL_HOST', '127.0.0.1'),\n            'port' => env('MAIL_PORT', 2525),\n            'username' => env('MAIL_USERNAME'),\n            'password' => env('MAIL_PASSWORD'),\n            'timeout' => null,\n            'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)),\n        ],\n\n        'ses' => [\n            'transport' => 'ses',\n        ],\n\n        'postmark' => [\n            'transport' => 'postmark',\n            // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),\n            // 'client' => [\n            //     'timeout' => 5,\n            // ],\n        ],\n\n        'resend' => [\n            'transport' => 'resend',\n        ],\n\n        'sendmail' => [\n            'transport' => 'sendmail',\n            'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),\n        ],\n\n        'log' => [\n            'transport' => 'log',\n            'channel' => env('MAIL_LOG_CHANNEL'),\n        ],\n\n        'array' => [\n            'transport' => 'array',\n        ],\n\n        'failover' => [\n            'transport' => 'failover',\n            'mailers' => [\n                'smtp',\n                'log',\n            ],\n            'retry_after' => 60,\n        ],\n\n        'roundrobin' => [\n            'transport' => 'roundrobin',\n            'mailers' => [\n                'ses',\n                'postmark',\n            ],\n            'retry_after' => 60,\n        ],\n\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Global \"From\" Address\n    |--------------------------------------------------------------------------\n    |\n    | You may wish for all emails sent by your application to be sent from\n    | the same address. Here you may specify a name and address that is\n    | used globally for all emails that are sent by your application.\n    |\n    */\n\n    'from' => [\n        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),\n        'name' => env('MAIL_FROM_NAME', 'Example'),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Markdown Mail Settings\n    |--------------------------------------------------------------------------\n    |\n    | If you are using Markdown based email rendering, you may configure your\n    | theme and component paths here, allowing you to customize the design\n    | of the emails. Or, you may simply stick with the Laravel defaults.\n    |\n    */\n\n    'markdown' => [\n        'theme' => env('MAIL_MARKDOWN_THEME', 'default'),\n\n        'paths' => [\n            resource_path('views/vendor/mail'),\n        ],\n\n        'extensions' => [\n            // \\League\\CommonMark\\Extension\\Strikethrough\\StrikethroughExtension::class,\n        ],\n    ],\n\n];\n"
  },
  {
    "path": "config/queue.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Queue Connection Name\n    |--------------------------------------------------------------------------\n    |\n    | Laravel's queue supports a variety of backends via a single, unified\n    | API, giving you convenient access to each backend using identical\n    | syntax for each. The default queue connection is defined below.\n    |\n    */\n\n    'default' => env('QUEUE_CONNECTION', 'database'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Queue Connections\n    |--------------------------------------------------------------------------\n    |\n    | Here you may configure the connection options for every queue backend\n    | used by your application. An example configuration is provided for\n    | each backend supported by Laravel. You're also free to add more.\n    |\n    | Drivers: \"sync\", \"database\", \"beanstalkd\", \"sqs\", \"redis\",\n    |          \"deferred\", \"failover\", \"null\"\n    |\n    */\n\n    'connections' => [\n\n        'sync' => [\n            'driver' => 'sync',\n        ],\n\n        'database' => [\n            'driver' => 'database',\n            'connection' => env('DB_QUEUE_CONNECTION'),\n            'table' => env('DB_QUEUE_TABLE', 'jobs'),\n            'queue' => env('DB_QUEUE', 'default'),\n            'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90),\n            'after_commit' => false,\n        ],\n\n        'beanstalkd' => [\n            'driver' => 'beanstalkd',\n            'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'),\n            'queue' => env('BEANSTALKD_QUEUE', 'default'),\n            'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90),\n            'block_for' => 0,\n            'after_commit' => false,\n        ],\n\n        'sqs' => [\n            'driver' => 'sqs',\n            'key' => env('AWS_ACCESS_KEY_ID'),\n            'secret' => env('AWS_SECRET_ACCESS_KEY'),\n            'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),\n            'queue' => env('SQS_QUEUE', 'default'),\n            'suffix' => env('SQS_SUFFIX'),\n            'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),\n            'after_commit' => false,\n        ],\n\n        'redis' => [\n            'driver' => 'redis',\n            'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),\n            'queue' => env('REDIS_QUEUE', 'default'),\n            'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90),\n            'block_for' => null,\n            'after_commit' => false,\n        ],\n\n        'deferred' => [\n            'driver' => 'deferred',\n        ],\n\n        'failover' => [\n            'driver' => 'failover',\n            'connections' => [\n                'database',\n                'deferred',\n            ],\n        ],\n\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Job Batching\n    |--------------------------------------------------------------------------\n    |\n    | The following options configure the database and table that store job\n    | batching information. These options can be updated to any database\n    | connection and table which has been defined by your application.\n    |\n    */\n\n    'batching' => [\n        'database' => env('DB_CONNECTION', 'sqlite'),\n        'table' => 'job_batches',\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Failed Queue Jobs\n    |--------------------------------------------------------------------------\n    |\n    | These options configure the behavior of failed queue job logging so you\n    | can control how and where failed jobs are stored. Laravel ships with\n    | support for storing failed jobs in a simple file or in a database.\n    |\n    | Supported drivers: \"database-uuids\", \"dynamodb\", \"file\", \"null\"\n    |\n    */\n\n    'failed' => [\n        'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),\n        'database' => env('DB_CONNECTION', 'sqlite'),\n        'table' => 'failed_jobs',\n    ],\n\n];\n"
  },
  {
    "path": "config/services.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Third Party Services\n    |--------------------------------------------------------------------------\n    |\n    | This file is for storing the credentials for third party services such\n    | as Mailgun, Postmark, AWS and more. This file provides the de facto\n    | location for this type of information, allowing packages to have\n    | a conventional file to locate the various service credentials.\n    |\n    */\n\n    'postmark' => [\n        'token' => env('POSTMARK_TOKEN'),\n    ],\n\n    'resend' => [\n        'key' => env('RESEND_KEY'),\n    ],\n\n    'ses' => [\n        'key' => env('AWS_ACCESS_KEY_ID'),\n        'secret' => env('AWS_SECRET_ACCESS_KEY'),\n        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),\n    ],\n\n    'slack' => [\n        'notifications' => [\n            'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),\n            'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),\n        ],\n    ],\n\n];\n"
  },
  {
    "path": "config/session.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Str;\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Default Session Driver\n    |--------------------------------------------------------------------------\n    |\n    | This option determines the default session driver that is utilized for\n    | incoming requests. Laravel supports a variety of storage options to\n    | persist session data. Database storage is a great default choice.\n    |\n    | Supported: \"file\", \"cookie\", \"database\", \"memcached\",\n    |            \"redis\", \"dynamodb\", \"array\"\n    |\n    */\n\n    'driver' => env('SESSION_DRIVER', 'database'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Lifetime\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the number of minutes that you wish the session\n    | to be allowed to remain idle before it expires. If you want them\n    | to expire immediately when the browser is closed then you may\n    | indicate that via the expire_on_close configuration option.\n    |\n    */\n\n    'lifetime' => (int) env('SESSION_LIFETIME', 120),\n\n    'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Encryption\n    |--------------------------------------------------------------------------\n    |\n    | This option allows you to easily specify that all of your session data\n    | should be encrypted before it's stored. All encryption is performed\n    | automatically by Laravel and you may use the session like normal.\n    |\n    */\n\n    'encrypt' => env('SESSION_ENCRYPT', false),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session File Location\n    |--------------------------------------------------------------------------\n    |\n    | When utilizing the \"file\" session driver, the session files are placed\n    | on disk. The default storage location is defined here; however, you\n    | are free to provide another location where they should be stored.\n    |\n    */\n\n    'files' => storage_path('framework/sessions'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Database Connection\n    |--------------------------------------------------------------------------\n    |\n    | When using the \"database\" or \"redis\" session drivers, you may specify a\n    | connection that should be used to manage these sessions. This should\n    | correspond to a connection in your database configuration options.\n    |\n    */\n\n    'connection' => env('SESSION_CONNECTION'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Database Table\n    |--------------------------------------------------------------------------\n    |\n    | When using the \"database\" session driver, you may specify the table to\n    | be used to store sessions. Of course, a sensible default is defined\n    | for you; however, you're welcome to change this to another table.\n    |\n    */\n\n    'table' => env('SESSION_TABLE', 'sessions'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Cache Store\n    |--------------------------------------------------------------------------\n    |\n    | When using one of the framework's cache driven session backends, you may\n    | define the cache store which should be used to store the session data\n    | between requests. This must match one of your defined cache stores.\n    |\n    | Affects: \"dynamodb\", \"memcached\", \"redis\"\n    |\n    */\n\n    'store' => env('SESSION_STORE'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Sweeping Lottery\n    |--------------------------------------------------------------------------\n    |\n    | Some session drivers must manually sweep their storage location to get\n    | rid of old sessions from storage. Here are the chances that it will\n    | happen on a given request. By default, the odds are 2 out of 100.\n    |\n    */\n\n    'lottery' => [2, 100],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Cookie Name\n    |--------------------------------------------------------------------------\n    |\n    | Here you may change the name of the session cookie that is created by\n    | the framework. Typically, you should not need to change this value\n    | since doing so does not grant a meaningful security improvement.\n    |\n    */\n\n    'cookie' => env(\n        'SESSION_COOKIE',\n        Str::snake((string) env('APP_NAME', 'laravel')).'_session'\n    ),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Cookie Path\n    |--------------------------------------------------------------------------\n    |\n    | The session cookie path determines the path for which the cookie will\n    | be regarded as available. Typically, this will be the root path of\n    | your application, but you're free to change this when necessary.\n    |\n    */\n\n    'path' => env('SESSION_PATH', '/'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Session Cookie Domain\n    |--------------------------------------------------------------------------\n    |\n    | This value determines the domain and subdomains the session cookie is\n    | available to. By default, the cookie will be available to the root\n    | domain and all subdomains. Typically, this shouldn't be changed.\n    |\n    */\n\n    'domain' => env('SESSION_DOMAIN'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | HTTPS Only Cookies\n    |--------------------------------------------------------------------------\n    |\n    | By setting this option to true, session cookies will only be sent back\n    | to the server if the browser has a HTTPS connection. This will keep\n    | the cookie from being sent to you when it can't be done securely.\n    |\n    */\n\n    'secure' => env('SESSION_SECURE_COOKIE'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | HTTP Access Only\n    |--------------------------------------------------------------------------\n    |\n    | Setting this value to true will prevent JavaScript from accessing the\n    | value of the cookie and the cookie will only be accessible through\n    | the HTTP protocol. It's unlikely you should disable this option.\n    |\n    */\n\n    'http_only' => env('SESSION_HTTP_ONLY', true),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Same-Site Cookies\n    |--------------------------------------------------------------------------\n    |\n    | This option determines how your cookies behave when cross-site requests\n    | take place, and can be used to mitigate CSRF attacks. By default, we\n    | will set this value to \"lax\" to permit secure cross-site requests.\n    |\n    | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value\n    |\n    | Supported: \"lax\", \"strict\", \"none\", null\n    |\n    */\n\n    'same_site' => env('SESSION_SAME_SITE', 'lax'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Partitioned Cookies\n    |--------------------------------------------------------------------------\n    |\n    | Setting this value to true will tie the cookie to the top-level site for\n    | a cross-site context. Partitioned cookies are accepted by the browser\n    | when flagged \"secure\" and the Same-Site attribute is set to \"none\".\n    |\n    */\n\n    'partitioned' => env('SESSION_PARTITIONED_COOKIE', false),\n\n];\n"
  },
  {
    "path": "config/view.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | View Storage Paths\n    |--------------------------------------------------------------------------\n    |\n    | Most templating systems load templates from disk. Here you may specify\n    | an array of paths that should be checked for your views. Of course\n    | the usual Laravel view path has already been registered for you.\n    |\n    */\n\n    'paths' => [\n        resource_path('views'),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Compiled View Path\n    |--------------------------------------------------------------------------\n    |\n    | This option determines where all the compiled Blade templates will be\n    | stored for your application. Typically, this is within the storage\n    | directory. However, as usual, you are free to change this value.\n    |\n    */\n\n    'compiled' => env(\n        'VIEW_COMPILED_PATH',\n        realpath(storage_path('framework/views'))\n    ),\n\n];\n"
  },
  {
    "path": "config-stubs/app.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Name\n    |--------------------------------------------------------------------------\n    |\n    | This value is the name of your application, which will be used when the\n    | framework needs to place the application's name in a notification or\n    | other UI elements where an application name needs to be displayed.\n    |\n    */\n\n    'name' => env('APP_NAME', 'Laravel'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Environment\n    |--------------------------------------------------------------------------\n    |\n    | This value determines the \"environment\" your application is currently\n    | running in. This may determine how you prefer to configure various\n    | services the application utilizes. Set this in your \".env\" file.\n    |\n    */\n\n    'env' => env('APP_ENV', 'production'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Debug Mode\n    |--------------------------------------------------------------------------\n    |\n    | When your application is in debug mode, detailed error messages with\n    | stack traces will be shown on every error that occurs within your\n    | application. If disabled, a simple generic error page is shown.\n    |\n    */\n\n    'debug' => (bool) env('APP_DEBUG', false),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application URL\n    |--------------------------------------------------------------------------\n    |\n    | This URL is used by the console to properly generate URLs when using\n    | the Artisan command line tool. You should set this to the root of\n    | the application so that it's available within Artisan commands.\n    |\n    */\n\n    'url' => env('APP_URL', 'http://localhost'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Timezone\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify the default timezone for your application, which\n    | will be used by the PHP date and date-time functions. The timezone\n    | is set to \"UTC\" by default as it is suitable for most use cases.\n    |\n    */\n\n    'timezone' => 'UTC',\n\n    /*\n    |--------------------------------------------------------------------------\n    | Application Locale Configuration\n    |--------------------------------------------------------------------------\n    |\n    | The application locale determines the default locale that will be used\n    | by Laravel's translation / localization methods. This option can be\n    | set to any locale for which you plan to have translation strings.\n    |\n    */\n\n    'locale' => env('APP_LOCALE', 'en'),\n\n    'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),\n\n    'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),\n\n    /*\n    |--------------------------------------------------------------------------\n    | Encryption Key\n    |--------------------------------------------------------------------------\n    |\n    | This key is utilized by Laravel's encryption services and should be set\n    | to a random, 32 character string to ensure that all encrypted values\n    | are secure. You should do this prior to deploying the application.\n    |\n    */\n\n    'cipher' => 'AES-256-CBC',\n\n    'key' => env('APP_KEY'),\n\n    'previous_keys' => [\n        ...array_filter(\n            explode(',', env('APP_PREVIOUS_KEYS', ''))\n        ),\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Maintenance Mode Driver\n    |--------------------------------------------------------------------------\n    |\n    | These configuration options determine the driver used to determine and\n    | manage Laravel's \"maintenance mode\" status. The \"cache\" driver will\n    | allow maintenance mode to be controlled across multiple machines.\n    |\n    | Supported drivers: \"file\", \"cache\"\n    |\n    */\n\n    'maintenance' => [\n        'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),\n        'store' => env('APP_MAINTENANCE_STORE', 'database'),\n    ],\n\n];\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3'\nservices:\n  dynamodb:\n    image: amazon/dynamodb-local:2.0.0\n    ports:\n      - \"8000:8000\"\n    command: [\"-jar\", \"DynamoDBLocal.jar\", \"-sharedDb\", \"-inMemory\"]\n  memcached:\n    image: memcached:1.6-alpine\n    ports:\n      - \"11211:11211\"\n    restart: always\n  mysql:\n    image: mysql/mysql-server:5.7\n    environment:\n      MYSQL_ALLOW_EMPTY_PASSWORD: 1\n      MYSQL_ROOT_PASSWORD: \"\"\n      MYSQL_DATABASE: \"forge\"\n      MYSQL_ROOT_HOST: \"%\"\n    ports:\n      - \"3306:3306\"\n    restart: always\n  # postgres:\n  #   image: postgres:15\n  #   environment:\n  #     POSTGRES_PASSWORD: \"secret\"\n  #     POSTGRES_DB: \"forge\"\n  #   ports:\n  #     - \"5432:5432\"\n  #   restart: always\n  # mariadb:\n  #   image: mariadb:11\n  #   environment:\n  #     MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: \"yes\"\n  #     MARIADB_ROOT_PASSWORD: \"\"\n  #     MARIADB_DATABASE: \"forge\"\n  #     MARIADB_ROOT_HOST: \"%\"\n  #   ports:\n  #     - \"3306:3306\"\n  #   restart: always\n  # mssql:\n  #   image: mcr.microsoft.com/mssql/server:2019-latest\n  #   environment:\n  #     ACCEPT_EULA: \"Y\"\n  #     SA_PASSWORD: \"Forge123\"\n  #   ports:\n  #     - \"1433:1433\"\n  #   restart: always\n  redis:\n    image: redis:7.0-alpine\n    ports:\n      - \"6379:6379\"\n    restart: always\n  # redis-cluster-0:\n  #   image: redis:7.0-alpine\n  #   ports:\n  #     - \"7000:7000\"\n  #   restart: always\n  #   command: redis-server --port 7000 --appendonly yes --cluster-enabled yes\n  # redis-cluster-1:\n  #   image: redis:7.0-alpine\n  #   ports:\n  #     - \"7001:7001\"\n  #   restart: always\n  #   command: redis-server --port 7001 --appendonly yes --cluster-enabled yes\n  # redis-cluster-2:\n  #   image: redis:7.0-alpine\n  #   ports:\n  #     - \"7002:7002\"\n  #   restart: always\n  #   command: redis-server --port 7002 --appendonly yes --cluster-enabled yes\n  # redis-cluster-creator:\n  #   image: redis:7.0-alpine\n  #   depends_on:\n  #     - redis-cluster-0\n  #     - redis-cluster-1\n  #     - redis-cluster-2\n  #   command: sh -c 'redis-cli --cluster create redis-cluster-0:7000 redis-cluster-1:7001 redis-cluster-2:7002 --cluster-replicas 0 --cluster-yes || true'\n  #   restart: no\n"
  },
  {
    "path": "phpstan.src.neon.dist",
    "content": "parameters:\n    level: 1\n    paths:\n        - src\n    excludePaths:\n        - src/Illuminate/Testing/ParallelRunner.php\n        - src/*/views/*\n    ignoreErrors:\n        - \"#\\\\(void\\\\) is used#\"\n        - \"#Access to an undefined property#\"\n        - \"#but return statement is missing.#\"\n        - \"#Call to an undefined method#\"\n        - \"#Caught class [a-zA-Z0-9\\\\\\\\_]+ not found.#\"\n        - \"#Class [a-zA-Z0-9\\\\\\\\_]+ not found.#\"\n        - \"#has invalid type#\"\n        - \"#Instantiated class [a-zA-Z0-9\\\\\\\\_]+ not found.#\"\n        - \"#Unsafe usage of new static#\"\n"
  },
  {
    "path": "phpstan.types.neon.dist",
    "content": "parameters:\n    level: max\n    paths:\n        - types\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n         beStrictAboutTestsThatDoNotTestAnything=\"false\"\n         colors=\"true\"\n         processIsolation=\"false\"\n         stopOnError=\"false\"\n         stopOnFailure=\"false\"\n         cacheDirectory=\".phpunit.cache\"\n         backupStaticProperties=\"false\">\n    <testsuites>\n        <testsuite name=\"Laravel Test Suite\">\n            <directory suffix=\"Test.php\">./tests</directory>\n        </testsuite>\n    </testsuites>\n    <extensions>\n        <bootstrap class=\"Illuminate\\Tests\\AfterEachTestExtension\" />\n    </extensions>\n    <php>\n        <ini name=\"date.timezone\" value=\"UTC\" />\n        <ini name=\"intl.default_locale\" value=\"C.UTF-8\" />\n        <ini name=\"memory_limit\" value=\"2048M\" />\n        <env name=\"DB_CONNECTION\" value=\"testing\" />\n        <!--\n        <env name=\"REDIS_CLIENT\" value=\"phpredis\" />\n        <env name=\"REDIS_HOST\" value=\"127.0.0.1\" />\n        <env name=\"REDIS_PORT\" value=\"6379\" />\n        -->\n    </php>\n</phpunit>\n"
  },
  {
    "path": "pint.json",
    "content": "{\n    \"preset\": \"empty\",\n    \"rules\": {\n        \"align_multiline_comment\": true,\n        \"array_indentation\": true,\n        \"array_syntax\": {\n            \"syntax\": \"short\"\n        },\n        \"binary_operator_spaces\": {\n            \"default\": \"single_space\"\n        },\n        \"blank_line_after_namespace\": true,\n        \"blank_line_after_opening_tag\": true,\n        \"blank_line_before_statement\": {\n            \"statements\": [\n                \"return\"\n            ]\n        },\n        \"blank_line_between_import_groups\": true,\n        \"blank_lines_before_namespace\": true,\n        \"braces_position\": {\n            \"control_structures_opening_brace\": \"same_line\",\n            \"functions_opening_brace\": \"next_line_unless_newline_at_signature_end\",\n            \"anonymous_functions_opening_brace\": \"same_line\",\n            \"classes_opening_brace\": \"next_line_unless_newline_at_signature_end\",\n            \"anonymous_classes_opening_brace\": \"next_line_unless_newline_at_signature_end\",\n            \"allow_single_line_empty_anonymous_classes\": false,\n            \"allow_single_line_anonymous_functions\": false\n        },\n        \"cast_spaces\": true,\n        \"class_definition\": true,\n        \"class_reference_name_casing\": true,\n        \"clean_namespace\": true,\n        \"compact_nullable_type_declaration\": true,\n        \"concat_space\": true,\n        \"constant_case\": {\n            \"case\": \"lower\"\n        },\n        \"control_structure_braces\": true,\n        \"declare_equal_normalize\": true,\n        \"elseif\": true,\n        \"encoding\": true,\n        \"full_opening_tag\": true,\n        \"function_declaration\": true,\n        \"heredoc_to_nowdoc\": true,\n        \"include\": true,\n        \"increment_style\": {\n            \"style\": \"post\"\n        },\n        \"indentation_type\": true,\n        \"integer_literal_case\": true,\n        \"lambda_not_used_import\": true,\n        \"line_ending\": true,\n        \"list_syntax\": {\n            \"syntax\": \"short\"\n        },\n        \"lowercase_cast\": true,\n        \"lowercase_keywords\": true,\n        \"lowercase_static_reference\": true,\n        \"magic_constant_casing\": true,\n        \"magic_method_casing\": true,\n        \"method_argument_space\": {\n            \"on_multiline\": \"ignore\"\n        },\n        \"method_chaining_indentation\": true,\n        \"modernize_types_casting\": true,\n        \"multiline_whitespace_before_semicolons\": {\n            \"strategy\": \"no_multi_line\"\n        },\n        \"native_function_casing\": true,\n        \"native_type_declaration_casing\": true,\n        \"no_alternative_syntax\": true,\n        \"no_binary_string\": true,\n        \"no_blank_lines_after_class_opening\": true,\n        \"no_blank_lines_after_phpdoc\": true,\n        \"no_closing_tag\": true,\n        \"no_empty_phpdoc\": true,\n        \"no_empty_statement\": true,\n        \"no_extra_blank_lines\": {\n            \"tokens\": [\n                \"extra\",\n                \"throw\",\n                \"use\"\n            ]\n        },\n        \"no_leading_import_slash\": true,\n        \"no_leading_namespace_whitespace\": true,\n        \"no_mixed_echo_print\": {\n            \"use\": \"echo\"\n        },\n        \"no_multiline_whitespace_around_double_arrow\": true,\n        \"no_short_bool_cast\": true,\n        \"no_singleline_whitespace_before_semicolons\": true,\n        \"no_space_around_double_colon\": true,\n        \"no_spaces_around_offset\": {\n            \"positions\": [\n                \"inside\",\n                \"outside\"\n            ]\n        },\n        \"no_spaces_after_function_name\": true,\n        \"no_trailing_comma_in_singleline\": true,\n        \"no_trailing_whitespace\": true,\n        \"no_trailing_whitespace_in_comment\": true,\n        \"no_unneeded_braces\": true,\n        \"no_unneeded_control_parentheses\": true,\n        \"no_unneeded_import_alias\": true,\n        \"no_unset_cast\": true,\n        \"no_unused_imports\": true,\n        \"no_useless_return\": true,\n        \"no_whitespace_before_comma_in_array\": true,\n        \"no_whitespace_in_blank_line\": true,\n        \"normalize_index_brace\": true,\n        \"not_operator_with_successor_space\": true,\n        \"nullable_type_declaration_for_default_null_value\": true,\n        \"object_operator_without_whitespace\": true,\n        \"ordered_imports\": {\n            \"sort_algorithm\": \"alpha\",\n            \"imports_order\": [\n                \"const\",\n                \"class\",\n                \"function\"\n            ]\n        },\n        \"phpdoc_align\": {\n            \"align\": \"left\",\n            \"spacing\": {\n                \"param\": 2\n            }\n        },\n        \"phpdoc_indent\": true,\n        \"phpdoc_inline_tag_normalizer\": true,\n        \"phpdoc_no_access\": true,\n        \"phpdoc_no_package\": true,\n        \"phpdoc_no_useless_inheritdoc\": true,\n        \"phpdoc_order\": {\n            \"order\": [\n                \"param\",\n                \"return\",\n                \"throws\"\n            ]\n        },\n        \"phpdoc_return_self_reference\": true,\n        \"phpdoc_scalar\": true,\n        \"phpdoc_separation\": {\n            \"groups\": [\n                [\n                    \"deprecated\",\n                    \"link\",\n                    \"see\",\n                    \"since\"\n                ],\n                [\n                    \"author\",\n                    \"copyright\",\n                    \"license\"\n                ],\n                [\n                    \"category\",\n                    \"package\",\n                    \"subpackage\"\n                ],\n                [\n                    \"property\",\n                    \"property-read\",\n                    \"property-write\"\n                ],\n                [\n                    \"param\",\n                    \"return\"\n                ]\n            ]\n        },\n        \"phpdoc_single_line_var_spacing\": true,\n        \"phpdoc_summary\": true,\n        \"phpdoc_trim\": true,\n        \"phpdoc_types\": true,\n        \"phpdoc_var_without_name\": true,\n        \"return_type_declaration\": {\n            \"space_before\": \"none\"\n        },\n        \"short_scalar_cast\": true,\n        \"single_blank_line_at_eof\": true,\n        \"single_class_element_per_statement\": true,\n        \"single_import_per_statement\": true,\n        \"single_line_after_imports\": true,\n        \"single_line_comment_style\": true,\n        \"single_quote\": true,\n        \"space_after_semicolon\": true,\n        \"spaces_inside_parentheses\": true,\n        \"standardize_not_equals\": true,\n        \"switch_case_semicolon_to_colon\": true,\n        \"switch_case_space\": true,\n        \"switch_continue_to_break\": true,\n        \"ternary_operator_spaces\": true,\n        \"trailing_comma_in_multiline\": true,\n        \"trim_array_spaces\": true,\n        \"type_declaration_spaces\": true,\n        \"types_spaces\": true,\n        \"unary_operator_spaces\": true,\n        \"visibility_required\": {\n            \"elements\": [\n                \"method\",\n                \"property\"\n            ]\n        },\n        \"whitespace_after_comma_in_array\": true\n    },\n    \"notPath\": [\n        \"tests/Foundation/fixtures/bad-syntax-strategy.php\"\n    ]\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Auth/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Auth/Access/AuthorizationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Access;\n\nuse Exception;\nuse Throwable;\n\nclass AuthorizationException extends Exception\n{\n    /**\n     * The response from the gate.\n     *\n     * @var \\Illuminate\\Auth\\Access\\Response\n     */\n    protected $response;\n\n    /**\n     * The HTTP response status code.\n     *\n     * @var int|null\n     */\n    protected $status;\n\n    /**\n     * Create a new authorization exception instance.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @param  \\Throwable|null  $previous\n     */\n    public function __construct($message = null, $code = null, ?Throwable $previous = null)\n    {\n        parent::__construct($message ?? 'This action is unauthorized.', 0, $previous);\n\n        $this->code = $code ?: 0;\n    }\n\n    /**\n     * Get the response from the gate.\n     *\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function response()\n    {\n        return $this->response;\n    }\n\n    /**\n     * Set the response from the gate.\n     *\n     * @param  \\Illuminate\\Auth\\Access\\Response  $response\n     * @return $this\n     */\n    public function setResponse($response)\n    {\n        $this->response = $response;\n\n        return $this;\n    }\n\n    /**\n     * Set the HTTP response status code.\n     *\n     * @param  int|null  $status\n     * @return $this\n     */\n    public function withStatus($status)\n    {\n        $this->status = $status;\n\n        return $this;\n    }\n\n    /**\n     * Set the HTTP response status code to 404.\n     *\n     * @return $this\n     */\n    public function asNotFound()\n    {\n        return $this->withStatus(404);\n    }\n\n    /**\n     * Determine if the HTTP status code has been set.\n     *\n     * @return bool\n     */\n    public function hasStatus()\n    {\n        return $this->status !== null;\n    }\n\n    /**\n     * Get the HTTP status code.\n     *\n     * @return int|null\n     */\n    public function status()\n    {\n        return $this->status;\n    }\n\n    /**\n     * Create a deny response object from this exception.\n     *\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function toResponse()\n    {\n        return Response::deny($this->message, $this->code)->withStatus($this->status);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Access/Events/GateEvaluated.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Access\\Events;\n\nclass GateEvaluated\n{\n    /**\n     * The authenticatable model.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public $user;\n\n    /**\n     * The ability being evaluated.\n     *\n     * @var string\n     */\n    public $ability;\n\n    /**\n     * The result of the evaluation.\n     *\n     * @var bool|null\n     */\n    public $result;\n\n    /**\n     * The arguments given during evaluation.\n     *\n     * @var array\n     */\n    public $arguments;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  string  $ability\n     * @param  bool|null  $result\n     * @param  array  $arguments\n     */\n    public function __construct($user, $ability, $result, $arguments)\n    {\n        $this->user = $user;\n        $this->ability = $ability;\n        $this->result = $result;\n        $this->arguments = $arguments;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Access/Gate.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Access;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Auth\\Access\\Events\\GateEvaluated;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate as GateContract;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UsePolicy;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse ReflectionClass;\nuse ReflectionFunction;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Gate implements GateContract\n{\n    use HandlesAuthorization;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The user resolver callable.\n     *\n     * @var callable\n     */\n    protected $userResolver;\n\n    /**\n     * All of the defined abilities.\n     *\n     * @var array\n     */\n    protected $abilities = [];\n\n    /**\n     * All of the defined policies.\n     *\n     * @var array\n     */\n    protected $policies = [];\n\n    /**\n     * All of the registered before callbacks.\n     *\n     * @var array\n     */\n    protected $beforeCallbacks = [];\n\n    /**\n     * All of the registered after callbacks.\n     *\n     * @var array\n     */\n    protected $afterCallbacks = [];\n\n    /**\n     * All of the defined abilities using class@method notation.\n     *\n     * @var array\n     */\n    protected $stringCallbacks = [];\n\n    /**\n     * The default denial response for gates and policies.\n     *\n     * @var \\Illuminate\\Auth\\Access\\Response|null\n     */\n    protected $defaultDenialResponse;\n\n    /**\n     * The callback to be used to guess policy names.\n     *\n     * @var callable|null\n     */\n    protected $guessPolicyNamesUsingCallback;\n\n    /**\n     * Create a new gate instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @param  callable  $userResolver\n     * @param  array  $abilities\n     * @param  array  $policies\n     * @param  array  $beforeCallbacks\n     * @param  array  $afterCallbacks\n     * @param  callable|null  $guessPolicyNamesUsingCallback\n     */\n    public function __construct(\n        Container $container,\n        callable $userResolver,\n        array $abilities = [],\n        array $policies = [],\n        array $beforeCallbacks = [],\n        array $afterCallbacks = [],\n        ?callable $guessPolicyNamesUsingCallback = null,\n    ) {\n        $this->policies = $policies;\n        $this->container = $container;\n        $this->abilities = $abilities;\n        $this->userResolver = $userResolver;\n        $this->afterCallbacks = $afterCallbacks;\n        $this->beforeCallbacks = $beforeCallbacks;\n        $this->guessPolicyNamesUsingCallback = $guessPolicyNamesUsingCallback;\n    }\n\n    /**\n     * Determine if a given ability has been defined.\n     *\n     * @param  \\UnitEnum|array|string  $ability\n     * @return bool\n     */\n    public function has($ability)\n    {\n        $abilities = is_array($ability) ? $ability : func_get_args();\n\n        foreach ($abilities as $ability) {\n            if (! isset($this->abilities[enum_value($ability)])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is false.\n     *\n     * @param  \\Illuminate\\Auth\\Access\\Response|\\Closure|bool  $condition\n     * @param  string|null  $message\n     * @param  string|null  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function allowIf($condition, $message = null, $code = null)\n    {\n        return $this->authorizeOnDemand($condition, $message, $code, true);\n    }\n\n    /**\n     * Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is true.\n     *\n     * @param  \\Illuminate\\Auth\\Access\\Response|\\Closure|bool  $condition\n     * @param  string|null  $message\n     * @param  string|null  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function denyIf($condition, $message = null, $code = null)\n    {\n        return $this->authorizeOnDemand($condition, $message, $code, false);\n    }\n\n    /**\n     * Authorize a given condition or callback.\n     *\n     * @param  \\Illuminate\\Auth\\Access\\Response|\\Closure|bool  $condition\n     * @param  string|null  $message\n     * @param  string|null  $code\n     * @param  bool  $allowWhenResponseIs\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    protected function authorizeOnDemand($condition, $message, $code, $allowWhenResponseIs)\n    {\n        $user = $this->resolveUser();\n\n        if ($condition instanceof Closure) {\n            $response = $this->canBeCalledWithUser($user, $condition)\n                ? $condition($user)\n                : new Response(false, $message, $code);\n        } else {\n            $response = $condition;\n        }\n\n        return ($response instanceof Response ? $response : new Response(\n            (bool) $response === $allowWhenResponseIs, $message, $code\n        ))->authorize();\n    }\n\n    /**\n     * Define a new ability.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  callable|array|string  $callback\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function define($ability, $callback)\n    {\n        $ability = enum_value($ability);\n\n        if (is_array($callback) && isset($callback[0]) && is_string($callback[0])) {\n            $callback = $callback[0].'@'.$callback[1];\n        }\n\n        if (is_callable($callback)) {\n            $this->abilities[$ability] = $callback;\n        } elseif (is_string($callback)) {\n            $this->stringCallbacks[$ability] = $callback;\n\n            $this->abilities[$ability] = $this->buildAbilityCallback($ability, $callback);\n        } else {\n            throw new InvalidArgumentException(\"Callback must be a callable, callback array, or a 'Class@method' string.\");\n        }\n\n        return $this;\n    }\n\n    /**\n     * Define abilities for a resource.\n     *\n     * @param  string  $name\n     * @param  string  $class\n     * @param  array|null  $abilities\n     * @return $this\n     */\n    public function resource($name, $class, ?array $abilities = null)\n    {\n        $abilities = $abilities ?: [\n            'viewAny' => 'viewAny',\n            'view' => 'view',\n            'create' => 'create',\n            'update' => 'update',\n            'delete' => 'delete',\n        ];\n\n        foreach ($abilities as $ability => $method) {\n            $this->define($name.'.'.$ability, $class.'@'.$method);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Create the ability callback for a callback string.\n     *\n     * @param  string  $ability\n     * @param  string  $callback\n     * @return \\Closure\n     */\n    protected function buildAbilityCallback($ability, $callback)\n    {\n        return function () use ($ability, $callback) {\n            if (str_contains($callback, '@')) {\n                [$class, $method] = Str::parseCallback($callback);\n            } else {\n                $class = $callback;\n            }\n\n            $policy = $this->resolvePolicy($class);\n\n            $arguments = func_get_args();\n\n            $user = array_shift($arguments);\n\n            $result = $this->callPolicyBefore(\n                $policy, $user, $ability, $arguments\n            );\n\n            if (! is_null($result)) {\n                return $result;\n            }\n\n            return isset($method)\n                ? $policy->{$method}(...func_get_args())\n                : $policy(...func_get_args());\n        };\n    }\n\n    /**\n     * Define a policy class for a given class type.\n     *\n     * @param  string  $class\n     * @param  string  $policy\n     * @return $this\n     */\n    public function policy($class, $policy)\n    {\n        $this->policies[$class] = $policy;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run before all Gate checks.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function before(callable $callback)\n    {\n        $this->beforeCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run after all Gate checks.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function after(callable $callback)\n    {\n        $this->afterCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Determine if all of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function allows($ability, $arguments = [])\n    {\n        return $this->check($ability, $arguments);\n    }\n\n    /**\n     * Determine if any of the given abilities should be denied for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function denies($ability, $arguments = [])\n    {\n        return ! $this->allows($ability, $arguments);\n    }\n\n    /**\n     * Determine if all of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function check($abilities, $arguments = [])\n    {\n        return (new Collection($abilities))->every(\n            fn ($ability) => $this->inspect($ability, $arguments)->allowed()\n        );\n    }\n\n    /**\n     * Determine if any one of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function any($abilities, $arguments = [])\n    {\n        return (new Collection($abilities))->contains(fn ($ability) => $this->check($ability, $arguments));\n    }\n\n    /**\n     * Determine if all of the given abilities should be denied for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function none($abilities, $arguments = [])\n    {\n        return ! $this->any($abilities, $arguments);\n    }\n\n    /**\n     * Determine if the given ability should be granted for the current user.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function authorize($ability, $arguments = [])\n    {\n        return $this->inspect($ability, $arguments)->authorize();\n    }\n\n    /**\n     * Inspect the user for the given ability.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function inspect($ability, $arguments = [])\n    {\n        try {\n            $result = $this->raw(enum_value($ability), $arguments);\n\n            if ($result instanceof Response) {\n                return $result;\n            }\n\n            return $result\n                ? Response::allow()\n                : ($this->defaultDenialResponse ?? Response::deny());\n        } catch (AuthorizationException $e) {\n            return $e->toResponse();\n        }\n    }\n\n    /**\n     * Get the raw result from the authorization callback.\n     *\n     * @param  string  $ability\n     * @param  mixed  $arguments\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function raw($ability, $arguments = [])\n    {\n        $arguments = Arr::wrap($arguments);\n\n        $user = $this->resolveUser();\n\n        // First we will call the \"before\" callbacks for the Gate. If any of these give\n        // back a non-null response, we will immediately return that result in order\n        // to let the developers override all checks for some authorization cases.\n        $result = $this->callBeforeCallbacks(\n            $user, $ability, $arguments\n        );\n\n        if (is_null($result)) {\n            $result = $this->callAuthCallback($user, $ability, $arguments);\n        }\n\n        // After calling the authorization callback, we will call the \"after\" callbacks\n        // that are registered with the Gate, which allows a developer to do logging\n        // if that is required for this application. Then we'll return the result.\n        return tap($this->callAfterCallbacks(\n            $user, $ability, $arguments, $result\n        ), function ($result) use ($user, $ability, $arguments) {\n            $this->dispatchGateEvaluatedEvent($user, $ability, $arguments, $result);\n        });\n    }\n\n    /**\n     * Determine whether the callback/method can be called with the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  \\Closure|string|array  $class\n     * @param  string|null  $method\n     * @return bool\n     */\n    protected function canBeCalledWithUser($user, $class, $method = null)\n    {\n        if (! is_null($user)) {\n            return true;\n        }\n\n        if (! is_null($method)) {\n            return $this->methodAllowsGuests($class, $method);\n        }\n\n        if (is_array($class)) {\n            $className = is_string($class[0]) ? $class[0] : get_class($class[0]);\n\n            return $this->methodAllowsGuests($className, $class[1]);\n        }\n\n        return $this->callbackAllowsGuests($class);\n    }\n\n    /**\n     * Determine if the given class method allows guests.\n     *\n     * @param  string  $class\n     * @param  string  $method\n     * @return bool\n     */\n    protected function methodAllowsGuests($class, $method)\n    {\n        try {\n            $reflection = new ReflectionClass($class);\n\n            $method = $reflection->getMethod($method);\n        } catch (Exception) {\n            return false;\n        }\n\n        if ($method) {\n            $parameters = $method->getParameters();\n\n            return isset($parameters[0]) && $this->parameterAllowsGuests($parameters[0]);\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the callback allows guests.\n     *\n     * @param  callable  $callback\n     * @return bool\n     *\n     * @throws \\ReflectionException\n     */\n    protected function callbackAllowsGuests($callback)\n    {\n        $parameters = (new ReflectionFunction($callback))->getParameters();\n\n        return isset($parameters[0]) && $this->parameterAllowsGuests($parameters[0]);\n    }\n\n    /**\n     * Determine if the given parameter allows guests.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @return bool\n     */\n    protected function parameterAllowsGuests($parameter)\n    {\n        return ($parameter->hasType() && $parameter->allowsNull()) ||\n               ($parameter->isDefaultValueAvailable() && is_null($parameter->getDefaultValue()));\n    }\n\n    /**\n     * Resolve and call the appropriate authorization callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @return bool\n     */\n    protected function callAuthCallback($user, $ability, array $arguments)\n    {\n        $callback = $this->resolveAuthCallback($user, $ability, $arguments);\n\n        return $callback($user, ...$arguments);\n    }\n\n    /**\n     * Call all of the before callbacks and return if a result is given.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @return bool|null\n     */\n    protected function callBeforeCallbacks($user, $ability, array $arguments)\n    {\n        foreach ($this->beforeCallbacks as $before) {\n            if (! $this->canBeCalledWithUser($user, $before)) {\n                continue;\n            }\n\n            if (! is_null($result = $before($user, $ability, $arguments))) {\n                return $result;\n            }\n        }\n    }\n\n    /**\n     * Call all of the after callbacks with check result.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @param  bool|null  $result\n     * @return bool|null\n     */\n    protected function callAfterCallbacks($user, $ability, array $arguments, $result)\n    {\n        foreach ($this->afterCallbacks as $after) {\n            if (! $this->canBeCalledWithUser($user, $after)) {\n                continue;\n            }\n\n            $afterResult = $after($user, $ability, $result, $arguments);\n\n            $result ??= $afterResult;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Dispatch a gate evaluation event.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @param  bool|null  $result\n     * @return void\n     */\n    protected function dispatchGateEvaluatedEvent($user, $ability, array $arguments, $result)\n    {\n        if ($this->container->bound(Dispatcher::class)) {\n            $this->container->make(Dispatcher::class)->dispatch(\n                new GateEvaluated($user, $ability, $result, $arguments)\n            );\n        }\n    }\n\n    /**\n     * Resolve the callable for the given ability and arguments.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @return callable\n     */\n    protected function resolveAuthCallback($user, $ability, array $arguments)\n    {\n        if (isset($arguments[0]) &&\n            ! is_null($policy = $this->getPolicyFor($arguments[0])) &&\n            $callback = $this->resolvePolicyCallback($user, $ability, $arguments, $policy)) {\n            return $callback;\n        }\n\n        if (isset($this->stringCallbacks[$ability])) {\n            [$class, $method] = Str::parseCallback($this->stringCallbacks[$ability]);\n\n            if ($this->canBeCalledWithUser($user, $class, $method ?: '__invoke')) {\n                return $this->abilities[$ability];\n            }\n        }\n\n        if (isset($this->abilities[$ability]) &&\n            $this->canBeCalledWithUser($user, $this->abilities[$ability])) {\n            return $this->abilities[$ability];\n        }\n\n        return function () {\n            //\n        };\n    }\n\n    /**\n     * Get a policy instance for a given class.\n     *\n     * @param  object|string  $class\n     * @return mixed\n     */\n    public function getPolicyFor($class)\n    {\n        if (is_object($class)) {\n            $class = get_class($class);\n        }\n\n        if (! is_string($class)) {\n            return;\n        }\n\n        if (isset($this->policies[$class])) {\n            return $this->resolvePolicy($this->policies[$class]);\n        }\n\n        $policy = $this->getPolicyFromAttribute($class);\n\n        if (! is_null($policy)) {\n            return $this->resolvePolicy($policy);\n        }\n\n        foreach ($this->guessPolicyName($class) as $guessedPolicy) {\n            if (class_exists($guessedPolicy)) {\n                return $this->resolvePolicy($guessedPolicy);\n            }\n        }\n\n        foreach ($this->policies as $expected => $policy) {\n            if (is_subclass_of($class, $expected)) {\n                return $this->resolvePolicy($policy);\n            }\n        }\n    }\n\n    /**\n     * Get the policy class from the class attribute.\n     *\n     * @param  class-string<*>  $class\n     * @return class-string<*>|null\n     */\n    protected function getPolicyFromAttribute(string $class): ?string\n    {\n        if (! class_exists($class)) {\n            return null;\n        }\n\n        $attributes = (new ReflectionClass($class))->getAttributes(UsePolicy::class);\n\n        return $attributes !== []\n            ? $attributes[0]->newInstance()->class\n            : null;\n    }\n\n    /**\n     * Guess the policy name for the given class.\n     *\n     * @param  string  $class\n     * @return array\n     */\n    protected function guessPolicyName($class)\n    {\n        if ($this->guessPolicyNamesUsingCallback) {\n            return Arr::wrap(call_user_func($this->guessPolicyNamesUsingCallback, $class));\n        }\n\n        $classDirname = str_replace('/', '\\\\', dirname(str_replace('\\\\', '/', $class)));\n\n        $classDirnameSegments = explode('\\\\', $classDirname);\n\n        return Arr::wrap(Collection::times(count($classDirnameSegments), function ($index) use ($class, $classDirnameSegments) {\n            $classDirname = implode('\\\\', array_slice($classDirnameSegments, 0, $index));\n\n            return $classDirname.'\\\\Policies\\\\'.class_basename($class).'Policy';\n        })->when(str_contains($classDirname, '\\\\Models\\\\'), function ($collection) use ($class, $classDirname) {\n            return $collection->concat([str_replace('\\\\Models\\\\', '\\\\Policies\\\\', $classDirname).'\\\\'.class_basename($class).'Policy'])\n                ->concat([str_replace('\\\\Models\\\\', '\\\\Models\\\\Policies\\\\', $classDirname).'\\\\'.class_basename($class).'Policy']);\n        })->reverse()->values()->first(function ($class) {\n            return class_exists($class);\n        }) ?: [$classDirname.'\\\\Policies\\\\'.class_basename($class).'Policy']);\n    }\n\n    /**\n     * Specify a callback to be used to guess policy names.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function guessPolicyNamesUsing(callable $callback)\n    {\n        $this->guessPolicyNamesUsingCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Build a policy class instance of the given type.\n     *\n     * @param  object|string  $class\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function resolvePolicy($class)\n    {\n        return $this->container->make($class);\n    }\n\n    /**\n     * Resolve the callback for a policy check.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @param  mixed  $policy\n     * @return bool|callable\n     */\n    protected function resolvePolicyCallback($user, $ability, array $arguments, $policy)\n    {\n        if (! is_callable([$policy, $this->formatAbilityToMethod($ability)])) {\n            return false;\n        }\n\n        return function () use ($user, $ability, $arguments, $policy) {\n            // This callback will be responsible for calling the policy's before method and\n            // running this policy method if necessary. This is used to when objects are\n            // mapped to policy objects in the user's configurations or on this class.\n            $result = $this->callPolicyBefore(\n                $policy, $user, $ability, $arguments\n            );\n\n            // When we receive a non-null result from this before method, we will return it\n            // as the \"final\" results. This will allow developers to override the checks\n            // in this policy to return the result for all rules defined in the class.\n            if (! is_null($result)) {\n                return $result;\n            }\n\n            $method = $this->formatAbilityToMethod($ability);\n\n            return $this->callPolicyMethod($policy, $method, $user, $arguments);\n        };\n    }\n\n    /**\n     * Call the \"before\" method on the given policy, if applicable.\n     *\n     * @param  mixed  $policy\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string  $ability\n     * @param  array  $arguments\n     * @return mixed\n     */\n    protected function callPolicyBefore($policy, $user, $ability, $arguments)\n    {\n        if (! method_exists($policy, 'before')) {\n            return;\n        }\n\n        if ($this->canBeCalledWithUser($user, $policy, 'before')) {\n            return $policy->before($user, $ability, ...$arguments);\n        }\n    }\n\n    /**\n     * Call the appropriate method on the given policy.\n     *\n     * @param  mixed  $policy\n     * @param  string  $method\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  array  $arguments\n     * @return mixed\n     */\n    protected function callPolicyMethod($policy, $method, $user, array $arguments)\n    {\n        // If this first argument is a string, that means they are passing a class name\n        // to the policy. We will remove the first argument from this argument array\n        // because this policy already knows what type of models it can authorize.\n        if (isset($arguments[0]) && is_string($arguments[0])) {\n            array_shift($arguments);\n        }\n\n        if (! is_callable([$policy, $method])) {\n            return;\n        }\n\n        if ($this->canBeCalledWithUser($user, $policy, $method)) {\n            return $policy->{$method}($user, ...$arguments);\n        }\n    }\n\n    /**\n     * Format the policy ability into a method name.\n     *\n     * @param  string  $ability\n     * @return string\n     */\n    protected function formatAbilityToMethod($ability)\n    {\n        return str_contains($ability, '-') ? Str::camel($ability) : $ability;\n    }\n\n    /**\n     * Get a gate instance for the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|mixed  $user\n     * @return static\n     */\n    public function forUser($user)\n    {\n        return new static(\n            $this->container,\n            fn () => $user,\n            $this->abilities,\n            $this->policies,\n            $this->beforeCallbacks,\n            $this->afterCallbacks,\n            $this->guessPolicyNamesUsingCallback,\n        );\n    }\n\n    /**\n     * Resolve the user from the user resolver.\n     *\n     * @return mixed\n     */\n    protected function resolveUser()\n    {\n        return call_user_func($this->userResolver);\n    }\n\n    /**\n     * Get all of the defined abilities.\n     *\n     * @return array\n     */\n    public function abilities()\n    {\n        return $this->abilities;\n    }\n\n    /**\n     * Get all of the defined policies.\n     *\n     * @return array\n     */\n    public function policies()\n    {\n        return $this->policies;\n    }\n\n    /**\n     * Set the default denial response for gates and policies.\n     *\n     * @param  \\Illuminate\\Auth\\Access\\Response  $response\n     * @return $this\n     */\n    public function defaultDenialResponse(Response $response)\n    {\n        $this->defaultDenialResponse = $response;\n\n        return $this;\n    }\n\n    /**\n     * Set the container instance used by the gate.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Access/HandlesAuthorization.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Access;\n\ntrait HandlesAuthorization\n{\n    /**\n     * Create a new access response.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    protected function allow($message = null, $code = null)\n    {\n        return Response::allow($message, $code);\n    }\n\n    /**\n     * Throws an unauthorized exception.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    protected function deny($message = null, $code = null)\n    {\n        return Response::deny($message, $code);\n    }\n\n    /**\n     * Deny with a HTTP status code.\n     *\n     * @param  int  $status\n     * @param  string|null  $message\n     * @param  int|null  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function denyWithStatus($status, $message = null, $code = null)\n    {\n        return Response::denyWithStatus($status, $message, $code);\n    }\n\n    /**\n     * Deny with a 404 HTTP status code.\n     *\n     * @param  string|null  $message\n     * @param  int|null  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function denyAsNotFound($message = null, $code = null)\n    {\n        return Response::denyWithStatus(404, $message, $code);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Access/Response.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Access;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nclass Response implements Arrayable, Stringable\n{\n    /**\n     * Indicates whether the response was allowed.\n     *\n     * @var bool\n     */\n    protected $allowed;\n\n    /**\n     * The response message.\n     *\n     * @var string|null\n     */\n    protected $message;\n\n    /**\n     * The response code.\n     *\n     * @var mixed\n     */\n    protected $code;\n\n    /**\n     * The HTTP response status code.\n     *\n     * @var int|null\n     */\n    protected $status;\n\n    /**\n     * Create a new response.\n     *\n     * @param  bool  $allowed\n     * @param  string|null  $message\n     * @param  mixed  $code\n     */\n    public function __construct($allowed, $message = '', $code = null)\n    {\n        $this->code = $code;\n        $this->allowed = $allowed;\n        $this->message = $message;\n    }\n\n    /**\n     * Create a new \"allow\" Response.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public static function allow($message = null, $code = null)\n    {\n        return new static(true, $message, $code);\n    }\n\n    /**\n     * Create a new \"deny\" Response.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public static function deny($message = null, $code = null)\n    {\n        return new static(false, $message, $code);\n    }\n\n    /**\n     * Create a new \"deny\" Response with a HTTP status code.\n     *\n     * @param  int  $status\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public static function denyWithStatus($status, $message = null, $code = null)\n    {\n        return static::deny($message, $code)->withStatus($status);\n    }\n\n    /**\n     * Create a new \"deny\" Response with a 404 HTTP status code.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $code\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public static function denyAsNotFound($message = null, $code = null)\n    {\n        return static::denyWithStatus(404, $message, $code);\n    }\n\n    /**\n     * Determine if the response was allowed.\n     *\n     * @return bool\n     */\n    public function allowed()\n    {\n        return $this->allowed;\n    }\n\n    /**\n     * Determine if the response was denied.\n     *\n     * @return bool\n     */\n    public function denied()\n    {\n        return ! $this->allowed();\n    }\n\n    /**\n     * Get the response message.\n     *\n     * @return string|null\n     */\n    public function message()\n    {\n        return $this->message;\n    }\n\n    /**\n     * Get the response code / reason.\n     *\n     * @return mixed\n     */\n    public function code()\n    {\n        return $this->code;\n    }\n\n    /**\n     * Throw authorization exception if response was denied.\n     *\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function authorize()\n    {\n        if ($this->denied()) {\n            throw (new AuthorizationException($this->message(), $this->code()))\n                ->setResponse($this)\n                ->withStatus($this->status);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the HTTP response status code.\n     *\n     * @param  null|int  $status\n     * @return $this\n     */\n    public function withStatus($status)\n    {\n        $this->status = $status;\n\n        return $this;\n    }\n\n    /**\n     * Set the HTTP response status code to 404.\n     *\n     * @return $this\n     */\n    public function asNotFound()\n    {\n        return $this->withStatus(404);\n    }\n\n    /**\n     * Get the HTTP status code.\n     *\n     * @return int|null\n     */\n    public function status()\n    {\n        return $this->status;\n    }\n\n    /**\n     * Convert the response to an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'allowed' => $this->allowed(),\n            'message' => $this->message(),\n            'code' => $this->code(),\n        ];\n    }\n\n    /**\n     * Get the string representation of the message.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->message();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/AuthManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\Factory as FactoryContract;\nuse InvalidArgumentException;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Auth\\Guard\n * @mixin \\Illuminate\\Contracts\\Auth\\StatefulGuard\n */\nclass AuthManager implements FactoryContract\n{\n    use CreatesUserProviders;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * The array of created \"drivers\".\n     *\n     * @var array\n     */\n    protected $guards = [];\n\n    /**\n     * The user resolver shared by various services.\n     *\n     * Determines the default user for Gate, Request, and the Authenticatable contract.\n     *\n     * @var \\Closure\n     */\n    protected $userResolver;\n\n    /**\n     * Create a new Auth manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n\n        $this->userResolver = fn ($guard = null) => $this->guard($guard)->user();\n    }\n\n    /**\n     * Attempt to get the guard from the local cache.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Auth\\Guard|\\Illuminate\\Contracts\\Auth\\StatefulGuard\n     */\n    public function guard($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        return $this->guards[$name] ??= $this->resolve($name);\n    }\n\n    /**\n     * Resolve the given guard.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Auth\\Guard|\\Illuminate\\Contracts\\Auth\\StatefulGuard\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Auth guard [{$name}] is not defined.\");\n        }\n\n        if (isset($this->customCreators[$config['driver']])) {\n            return $this->callCustomCreator($name, $config);\n        }\n\n        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';\n\n        if (method_exists($this, $driverMethod)) {\n            return $this->{$driverMethod}($name, $config);\n        }\n\n        throw new InvalidArgumentException(\n            \"Auth driver [{$config['driver']}] for guard [{$name}] is not defined.\"\n        );\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  string  $name\n     * @param  array  $config\n     * @return mixed\n     */\n    protected function callCustomCreator($name, array $config)\n    {\n        return $this->customCreators[$config['driver']]($this->app, $name, $config);\n    }\n\n    /**\n     * Create a session based authentication guard.\n     *\n     * @param  string  $name\n     * @param  array  $config\n     * @return \\Illuminate\\Auth\\SessionGuard\n     */\n    public function createSessionDriver($name, $config)\n    {\n        $guard = new SessionGuard(\n            $name,\n            $this->createUserProvider($config['provider'] ?? null),\n            $this->app['session.store'],\n            rehashOnLogin: $this->app['config']->get('hashing.rehash_on_login', true),\n            timeboxDuration: $this->app['config']->get('auth.timebox_duration', 200000),\n            hashKey: $this->app['config']->get('app.key'),\n        );\n\n        // When using the remember me functionality of the authentication services we\n        // will need to be set the encryption instance of the guard, which allows\n        // secure, encrypted cookie values to get generated for those cookies.\n        $guard->setCookieJar($this->app['cookie']);\n\n        $guard->setDispatcher($this->app['events']);\n\n        $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));\n\n        if (isset($config['remember'])) {\n            $guard->setRememberDuration($config['remember']);\n        }\n\n        return $guard;\n    }\n\n    /**\n     * Create a token based authentication guard.\n     *\n     * @param  string  $name\n     * @param  array  $config\n     * @return \\Illuminate\\Auth\\TokenGuard\n     */\n    public function createTokenDriver($name, $config)\n    {\n        // The token guard implements a basic API token based guard implementation\n        // that takes an API token field from the request and matches it to the\n        // user in the database or another persistence layer where users are.\n        $guard = new TokenGuard(\n            $this->createUserProvider($config['provider'] ?? null),\n            $this->app['request'],\n            $config['input_key'] ?? 'api_token',\n            $config['storage_key'] ?? 'api_token',\n            $config['hash'] ?? false\n        );\n\n        $this->app->refresh('request', $guard, 'setRequest');\n\n        return $guard;\n    }\n\n    /**\n     * Get the guard configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function getConfig($name)\n    {\n        return $this->app['config'][\"auth.guards.{$name}\"];\n    }\n\n    /**\n     * Get the default authentication driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['auth.defaults.guard'];\n    }\n\n    /**\n     * Set the default guard driver the factory should serve.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function shouldUse($name)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        $this->setDefaultDriver($name);\n\n        $this->userResolver = fn ($name = null) => $this->guard($name)->user();\n    }\n\n    /**\n     * Set the default authentication driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['auth.defaults.guard'] = $name;\n    }\n\n    /**\n     * Register a new callback based request guard.\n     *\n     * @param  string  $driver\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function viaRequest($driver, callable $callback)\n    {\n        return $this->extend($driver, function () use ($callback) {\n            $guard = new RequestGuard($callback, $this->app['request'], $this->createUserProvider());\n\n            $this->app->refresh('request', $guard, 'setRequest');\n\n            return $guard;\n        });\n    }\n\n    /**\n     * Get the user resolver callback.\n     *\n     * @return \\Closure\n     */\n    public function userResolver()\n    {\n        return $this->userResolver;\n    }\n\n    /**\n     * Set the callback to be used to resolve users.\n     *\n     * @param  \\Closure  $userResolver\n     * @return $this\n     */\n    public function resolveUsersUsing(Closure $userResolver)\n    {\n        $this->userResolver = $userResolver;\n\n        return $this;\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Register a custom provider creator Closure.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function provider($name, Closure $callback)\n    {\n        $this->customProviderCreators[$name] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Determines if any guards have already been resolved.\n     *\n     * @return bool\n     */\n    public function hasResolvedGuards()\n    {\n        return count($this->guards) > 0;\n    }\n\n    /**\n     * Forget all of the resolved guard instances.\n     *\n     * @return $this\n     */\n    public function forgetGuards()\n    {\n        $this->guards = [];\n\n        return $this;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->guard()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/AuthServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Auth\\Access\\Gate;\nuse Illuminate\\Auth\\Middleware\\RequirePassword;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate as GateContract;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as AuthenticatableContract;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass AuthServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerAuthenticator();\n        $this->registerUserResolver();\n        $this->registerAccessGate();\n        $this->registerRequirePassword();\n        $this->registerRequestRebindHandler();\n        $this->registerEventRebindHandler();\n    }\n\n    /**\n     * Register the authenticator services.\n     *\n     * @return void\n     */\n    protected function registerAuthenticator()\n    {\n        $this->app->singleton('auth', fn ($app) => new AuthManager($app));\n\n        $this->app->singleton('auth.driver', fn ($app) => $app['auth']->guard());\n    }\n\n    /**\n     * Register a resolver for the authenticated user.\n     *\n     * @return void\n     */\n    protected function registerUserResolver()\n    {\n        $this->app->bind(AuthenticatableContract::class, fn ($app) => call_user_func($app['auth']->userResolver()));\n    }\n\n    /**\n     * Register the access gate service.\n     *\n     * @return void\n     */\n    protected function registerAccessGate()\n    {\n        $this->app->singleton(GateContract::class, function ($app) {\n            return new Gate($app, fn () => call_user_func($app['auth']->userResolver()));\n        });\n    }\n\n    /**\n     * Register a resolver for the authenticated user.\n     *\n     * @return void\n     */\n    protected function registerRequirePassword()\n    {\n        $this->app->bind(RequirePassword::class, function ($app) {\n            return new RequirePassword(\n                $app[ResponseFactory::class],\n                $app[UrlGenerator::class],\n                $app['config']->get('auth.password_timeout')\n            );\n        });\n    }\n\n    /**\n     * Handle the re-binding of the request binding.\n     *\n     * @return void\n     */\n    protected function registerRequestRebindHandler()\n    {\n        $this->app->rebinding('request', function ($app, $request) {\n            $request->setUserResolver(function ($guard = null) use ($app) {\n                return call_user_func($app['auth']->userResolver(), $guard);\n            });\n        });\n    }\n\n    /**\n     * Handle the re-binding of the event dispatcher binding.\n     *\n     * @return void\n     */\n    protected function registerEventRebindHandler()\n    {\n        $this->app->rebinding('events', function ($app, $dispatcher) {\n            if (! $app->resolved('auth') ||\n                $app['auth']->hasResolvedGuards() === false) {\n                return;\n            }\n\n            if (method_exists($guard = $app['auth']->guard(), 'setDispatcher')) {\n                $guard->setDispatcher($dispatcher);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Authenticatable.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\ntrait Authenticatable\n{\n    /**\n     * The column name of the password field using during authentication.\n     *\n     * @var string\n     */\n    protected $authPasswordName = 'password';\n\n    /**\n     * The column name of the \"remember me\" token.\n     *\n     * @var string\n     */\n    protected $rememberTokenName = 'remember_token';\n\n    /**\n     * Get the name of the unique identifier for the user.\n     *\n     * @return string\n     */\n    public function getAuthIdentifierName()\n    {\n        return $this->getKeyName();\n    }\n\n    /**\n     * Get the unique identifier for the user.\n     *\n     * @return mixed\n     */\n    public function getAuthIdentifier()\n    {\n        return $this->{$this->getAuthIdentifierName()};\n    }\n\n    /**\n     * Get the unique broadcast identifier for the user.\n     *\n     * @return mixed\n     */\n    public function getAuthIdentifierForBroadcasting()\n    {\n        return $this->getAuthIdentifier();\n    }\n\n    /**\n     * Get the name of the password attribute for the user.\n     *\n     * @return string\n     */\n    public function getAuthPasswordName()\n    {\n        return $this->authPasswordName;\n    }\n\n    /**\n     * Get the password for the user.\n     *\n     * @return string\n     */\n    public function getAuthPassword()\n    {\n        return $this->{$this->getAuthPasswordName()};\n    }\n\n    /**\n     * Get the token value for the \"remember me\" session.\n     *\n     * @return string|null\n     */\n    public function getRememberToken()\n    {\n        if (! empty($this->getRememberTokenName())) {\n            return (string) $this->{$this->getRememberTokenName()};\n        }\n    }\n\n    /**\n     * Set the token value for the \"remember me\" session.\n     *\n     * @param  string  $value\n     * @return void\n     */\n    public function setRememberToken($value)\n    {\n        if (! empty($this->getRememberTokenName())) {\n            $this->{$this->getRememberTokenName()} = $value;\n        }\n    }\n\n    /**\n     * Get the column name for the \"remember me\" token.\n     *\n     * @return string\n     */\n    public function getRememberTokenName()\n    {\n        return $this->rememberTokenName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/AuthenticationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Exception;\nuse Illuminate\\Http\\Request;\n\nclass AuthenticationException extends Exception\n{\n    /**\n     * All of the guards that were checked.\n     *\n     * @var array\n     */\n    protected $guards;\n\n    /**\n     * The path the user should be redirected to.\n     *\n     * @var string|null\n     */\n    protected $redirectTo;\n\n    /**\n     * The callback that should be used to generate the authentication redirect path.\n     *\n     * @var callable\n     */\n    protected static $redirectToCallback;\n\n    /**\n     * Create a new authentication exception.\n     *\n     * @param  string  $message\n     * @param  array  $guards\n     * @param  string|null  $redirectTo\n     */\n    public function __construct($message = 'Unauthenticated.', array $guards = [], $redirectTo = null)\n    {\n        parent::__construct($message);\n\n        $this->guards = $guards;\n        $this->redirectTo = $redirectTo;\n    }\n\n    /**\n     * Get the guards that were checked.\n     *\n     * @return array\n     */\n    public function guards()\n    {\n        return $this->guards;\n    }\n\n    /**\n     * Get the path the user should be redirected to.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return string|null\n     */\n    public function redirectTo(Request $request)\n    {\n        if ($this->redirectTo) {\n            return $this->redirectTo;\n        }\n\n        if (static::$redirectToCallback) {\n            return call_user_func(static::$redirectToCallback, $request);\n        }\n    }\n\n    /**\n     * Specify the callback that should be used to generate the redirect path.\n     *\n     * @param  callable  $redirectToCallback\n     * @return void\n     */\n    public static function redirectUsing(callable $redirectToCallback)\n    {\n        static::$redirectToCallback = $redirectToCallback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Console/ClearResetsCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'auth:clear-resets')]\nclass ClearResetsCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'auth:clear-resets {name? : The name of the password broker}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Flush expired password reset tokens';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->laravel['auth.password']->broker($this->argument('name'))->getRepository()->deleteExpired();\n\n        $this->components->info('Expired reset tokens cleared successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub",
    "content": "<!DOCTYPE html>\n<html lang=\"{{ str_replace('_', '-', app()->getLocale()) }}\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <!-- CSRF Token -->\n    <meta name=\"csrf-token\" content=\"{{ csrf_token() }}\">\n\n    <title>{{ config('app.name', 'Laravel') }}</title>\n\n    <!-- Scripts -->\n    <script src=\"{{ asset('js/app.js') }}\" defer></script>\n\n    <!-- Styles -->\n    <link href=\"{{ asset('css/app.css') }}\" rel=\"stylesheet\">\n</head>\n<body>\n    <div id=\"app\">\n        <nav class=\"navbar navbar-expand-md navbar-light bg-white shadow-sm\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" href=\"{{ url('/') }}\">\n                    {{ config('app.name', 'Laravel') }}\n                </a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarSupportedContent\" aria-controls=\"navbarSupportedContent\" aria-expanded=\"false\" aria-label=\"{{ __('Toggle navigation') }}\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n\n                <div class=\"collapse navbar-collapse\" id=\"navbarSupportedContent\">\n                    <!-- Left Side Of Navbar -->\n                    <ul class=\"navbar-nav mr-auto\">\n\n                    </ul>\n\n                    <!-- Right Side Of Navbar -->\n                    <ul class=\"navbar-nav ml-auto\">\n                        <!-- Authentication Links -->\n                        @guest\n                            <li class=\"nav-item\">\n                                <a class=\"nav-link\" href=\"{{ route('login') }}\">{{ __('Login') }}</a>\n                            </li>\n                            @if (Route::has('register'))\n                                <li class=\"nav-item\">\n                                    <a class=\"nav-link\" href=\"{{ route('register') }}\">{{ __('Register') }}</a>\n                                </li>\n                            @endif\n                        @else\n                            <li class=\"nav-item dropdown\">\n                                <a id=\"navbarDropdown\" class=\"nav-link dropdown-toggle\" href=\"#\" role=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" v-pre>\n                                    {{ Auth::user()->name }} <span class=\"caret\"></span>\n                                </a>\n\n                                <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"navbarDropdown\">\n                                    <a class=\"dropdown-item\" href=\"{{ route('logout') }}\"\n                                       onclick=\"event.preventDefault();\n                                                     document.getElementById('logout-form').submit();\">\n                                        {{ __('Logout') }}\n                                    </a>\n\n                                    <form id=\"logout-form\" action=\"{{ route('logout') }}\" method=\"POST\" style=\"display: none;\">\n                                        @csrf\n                                    </form>\n                                </div>\n                            </li>\n                        @endguest\n                    </ul>\n                </div>\n            </div>\n        </nav>\n\n        <main class=\"py-4\">\n            @yield('content')\n        </main>\n    </div>\n</body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Auth/CreatesUserProviders.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse InvalidArgumentException;\n\ntrait CreatesUserProviders\n{\n    /**\n     * The registered custom provider creators.\n     *\n     * @var array\n     */\n    protected $customProviderCreators = [];\n\n    /**\n     * Create the user provider implementation for the driver.\n     *\n     * @param  string|null  $provider\n     * @return \\Illuminate\\Contracts\\Auth\\UserProvider|null\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function createUserProvider($provider = null)\n    {\n        if (is_null($config = $this->getProviderConfiguration($provider))) {\n            return;\n        }\n\n        if (isset($this->customProviderCreators[$driver = ($config['driver'] ?? null)])) {\n            return call_user_func(\n                $this->customProviderCreators[$driver], $this->app, $config\n            );\n        }\n\n        return match ($driver) {\n            'database' => $this->createDatabaseProvider($config),\n            'eloquent' => $this->createEloquentProvider($config),\n            default => throw new InvalidArgumentException(\n                \"Authentication user provider [{$driver}] is not defined.\"\n            ),\n        };\n    }\n\n    /**\n     * Get the user provider configuration.\n     *\n     * @param  string|null  $provider\n     * @return array|null\n     */\n    protected function getProviderConfiguration($provider)\n    {\n        if ($provider = $provider ?: $this->getDefaultUserProvider()) {\n            return $this->app['config']['auth.providers.'.$provider];\n        }\n    }\n\n    /**\n     * Create an instance of the database user provider.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Auth\\DatabaseUserProvider\n     */\n    protected function createDatabaseProvider($config)\n    {\n        return new DatabaseUserProvider(\n            $this->app['db']->connection($config['connection'] ?? null),\n            $this->app['hash'],\n            $config['table'],\n        );\n    }\n\n    /**\n     * Create an instance of the Eloquent user provider.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Auth\\EloquentUserProvider\n     */\n    protected function createEloquentProvider($config)\n    {\n        return new EloquentUserProvider($this->app['hash'], $config['model']);\n    }\n\n    /**\n     * Get the default user provider name.\n     *\n     * @return string\n     */\n    public function getDefaultUserProvider()\n    {\n        return $this->app['config']['auth.defaults.provider'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/DatabaseUserProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as UserContract;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\ConnectionInterface;\n\nclass DatabaseUserProvider implements UserProvider\n{\n    /**\n     * The active database connection.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected $connection;\n\n    /**\n     * The hasher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Hashing\\Hasher\n     */\n    protected $hasher;\n\n    /**\n     * The table containing the users.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * Create a new database user provider.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  \\Illuminate\\Contracts\\Hashing\\Hasher  $hasher\n     * @param  string  $table\n     */\n    public function __construct(ConnectionInterface $connection, HasherContract $hasher, $table)\n    {\n        $this->connection = $connection;\n        $this->table = $table;\n        $this->hasher = $hasher;\n    }\n\n    /**\n     * Retrieve a user by their unique identifier.\n     *\n     * @param  mixed  $identifier\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveById($identifier)\n    {\n        $user = $this->connection->table($this->table)->find($identifier);\n\n        return $this->getGenericUser($user);\n    }\n\n    /**\n     * Retrieve a user by their unique identifier and \"remember me\" token.\n     *\n     * @param  mixed  $identifier\n     * @param  string  $token\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveByToken($identifier, #[\\SensitiveParameter] $token)\n    {\n        $user = $this->getGenericUser(\n            $this->connection->table($this->table)->find($identifier)\n        );\n\n        return $user && $user->getRememberToken() && hash_equals($user->getRememberToken(), $token)\n            ? $user\n            : null;\n    }\n\n    /**\n     * Update the \"remember me\" token for the given user in storage.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string  $token\n     * @return void\n     */\n    public function updateRememberToken(UserContract $user, #[\\SensitiveParameter] $token)\n    {\n        $this->connection->table($this->table)\n            ->where($user->getAuthIdentifierName(), $user->getAuthIdentifier())\n            ->update([$user->getRememberTokenName() => $token]);\n    }\n\n    /**\n     * Retrieve a user by the given credentials.\n     *\n     * @param  array  $credentials\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveByCredentials(#[\\SensitiveParameter] array $credentials)\n    {\n        $credentials = array_filter(\n            $credentials,\n            fn ($key) => ! str_contains($key, 'password'),\n            ARRAY_FILTER_USE_KEY\n        );\n\n        if (empty($credentials)) {\n            return;\n        }\n\n        // First we will add each credential element to the query as a where clause.\n        // Then we can execute the query and, if we found a user, return it in a\n        // generic \"user\" object that will be utilized by the Guard instances.\n        $query = $this->connection->table($this->table);\n\n        foreach ($credentials as $key => $value) {\n            if (is_array($value) || $value instanceof Arrayable) {\n                $query->whereIn($key, $value);\n            } elseif ($value instanceof Closure) {\n                $value($query);\n            } else {\n                $query->where($key, $value);\n            }\n        }\n\n        // Now we are ready to execute the query to see if we have a user matching\n        // the given credentials. If not, we will just return null and indicate\n        // that there are no matching users from the given credential arrays.\n        $user = $query->first();\n\n        return $this->getGenericUser($user);\n    }\n\n    /**\n     * Get the generic user.\n     *\n     * @param  mixed  $user\n     * @return \\Illuminate\\Auth\\GenericUser|null\n     */\n    protected function getGenericUser($user)\n    {\n        if (! is_null($user)) {\n            return new GenericUser((array) $user);\n        }\n    }\n\n    /**\n     * Validate a user against the given credentials.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validateCredentials(UserContract $user, #[\\SensitiveParameter] array $credentials)\n    {\n        if (is_null($plain = $credentials['password'])) {\n            return false;\n        }\n\n        if (is_null($hashed = $user->getAuthPassword())) {\n            return false;\n        }\n\n        return $this->hasher->check($plain, $hashed);\n    }\n\n    /**\n     * Rehash the user's password if required and supported.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @param  bool  $force\n     * @return void\n     */\n    public function rehashPasswordIfRequired(UserContract $user, #[\\SensitiveParameter] array $credentials, bool $force = false)\n    {\n        if (! $this->hasher->needsRehash($user->getAuthPassword()) && ! $force) {\n            return;\n        }\n\n        $this->connection->table($this->table)\n            ->where($user->getAuthIdentifierName(), $user->getAuthIdentifier())\n            ->update([$user->getAuthPasswordName() => $this->hasher->make($credentials['password'])]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/EloquentUserProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as UserContract;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\n\nclass EloquentUserProvider implements UserProvider\n{\n    /**\n     * The hasher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Hashing\\Hasher\n     */\n    protected $hasher;\n\n    /**\n     * The Eloquent user model.\n     *\n     * @var class-string<\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model>\n     */\n    protected $model;\n\n    /**\n     * The callback that may modify the user retrieval queries.\n     *\n     * @var (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<*>):mixed)|null\n     */\n    protected $queryCallback;\n\n    /**\n     * Create a new database user provider.\n     *\n     * @param  \\Illuminate\\Contracts\\Hashing\\Hasher  $hasher\n     * @param  string  $model\n     */\n    public function __construct(HasherContract $hasher, $model)\n    {\n        $this->model = $model;\n        $this->hasher = $hasher;\n    }\n\n    /**\n     * Retrieve a user by their unique identifier.\n     *\n     * @param  mixed  $identifier\n     * @return (\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model)|null\n     */\n    public function retrieveById($identifier)\n    {\n        $model = $this->createModel();\n\n        return $this->newModelQuery($model)\n            ->where($model->getAuthIdentifierName(), $identifier)\n            ->first();\n    }\n\n    /**\n     * Retrieve a user by their unique identifier and \"remember me\" token.\n     *\n     * @param  mixed  $identifier\n     * @param  string  $token\n     * @return (\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model)|null\n     */\n    public function retrieveByToken($identifier, #[\\SensitiveParameter] $token)\n    {\n        $model = $this->createModel();\n\n        $retrievedModel = $this->newModelQuery($model)->where(\n            $model->getAuthIdentifierName(), $identifier\n        )->first();\n\n        if (! $retrievedModel) {\n            return;\n        }\n\n        $rememberToken = $retrievedModel->getRememberToken();\n\n        return $rememberToken && hash_equals($rememberToken, $token) ? $retrievedModel : null;\n    }\n\n    /**\n     * Update the \"remember me\" token for the given user in storage.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model  $user\n     * @param  string  $token\n     * @return void\n     */\n    public function updateRememberToken(UserContract $user, #[\\SensitiveParameter] $token)\n    {\n        $user->setRememberToken($token);\n\n        $timestamps = $user->timestamps;\n\n        $user->timestamps = false;\n\n        $user->save();\n\n        $user->timestamps = $timestamps;\n    }\n\n    /**\n     * Retrieve a user by the given credentials.\n     *\n     * @param  array  $credentials\n     * @return (\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model)|null\n     */\n    public function retrieveByCredentials(#[\\SensitiveParameter] array $credentials)\n    {\n        $credentials = array_filter(\n            $credentials,\n            fn ($key) => ! str_contains($key, 'password'),\n            ARRAY_FILTER_USE_KEY\n        );\n\n        if (empty($credentials)) {\n            return;\n        }\n\n        // First we will add each credential element to the query as a where clause.\n        // Then we can execute the query and, if we found a user, return it in a\n        // Eloquent User \"model\" that will be utilized by the Guard instances.\n        $query = $this->newModelQuery();\n\n        foreach ($credentials as $key => $value) {\n            if (is_array($value) || $value instanceof Arrayable) {\n                $query->whereIn($key, $value);\n            } elseif ($value instanceof Closure) {\n                $value($query);\n            } else {\n                $query->where($key, $value);\n            }\n        }\n\n        return $query->first();\n    }\n\n    /**\n     * Validate a user against the given credentials.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validateCredentials(UserContract $user, #[\\SensitiveParameter] array $credentials)\n    {\n        if (is_null($plain = $credentials['password'])) {\n            return false;\n        }\n\n        if (is_null($hashed = $user->getAuthPassword())) {\n            return false;\n        }\n\n        return $this->hasher->check($plain, $hashed);\n    }\n\n    /**\n     * Rehash the user's password if required and supported.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model  $user\n     * @param  array  $credentials\n     * @param  bool  $force\n     * @return void\n     */\n    public function rehashPasswordIfRequired(UserContract $user, #[\\SensitiveParameter] array $credentials, bool $force = false)\n    {\n        if (! $this->hasher->needsRehash($user->getAuthPassword()) && ! $force) {\n            return;\n        }\n\n        $user->forceFill([\n            $user->getAuthPasswordName() => $this->hasher->make($credentials['password']),\n        ])->save();\n    }\n\n    /**\n     * Get a new query builder for the model instance.\n     *\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  TModel|null  $model\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TModel>\n     */\n    protected function newModelQuery($model = null)\n    {\n        $query = is_null($model)\n            ? $this->createModel()->newQuery()\n            : $model->newQuery();\n\n        with($query, $this->queryCallback);\n\n        return $query;\n    }\n\n    /**\n     * Create a new instance of the model.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model\n     */\n    public function createModel()\n    {\n        $class = '\\\\'.ltrim($this->model, '\\\\');\n\n        return new $class;\n    }\n\n    /**\n     * Gets the hasher implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Hashing\\Hasher\n     */\n    public function getHasher()\n    {\n        return $this->hasher;\n    }\n\n    /**\n     * Sets the hasher implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Hashing\\Hasher  $hasher\n     * @return $this\n     */\n    public function setHasher(HasherContract $hasher)\n    {\n        $this->hasher = $hasher;\n\n        return $this;\n    }\n\n    /**\n     * Gets the name of the Eloquent user model.\n     *\n     * @return class-string<\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model>\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n    /**\n     * Sets the name of the Eloquent user model.\n     *\n     * @param  class-string<\\Illuminate\\Contracts\\Auth\\Authenticatable&\\Illuminate\\Database\\Eloquent\\Model>  $model\n     * @return $this\n     */\n    public function setModel($model)\n    {\n        $this->model = $model;\n\n        return $this;\n    }\n\n    /**\n     * Get the callback that modifies the query before retrieving users.\n     *\n     * @return (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<*>):mixed)|null\n     */\n    public function getQueryCallback()\n    {\n        return $this->queryCallback;\n    }\n\n    /**\n     * Sets the callback to modify the query before retrieving users.\n     *\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<*>):mixed)|null  $queryCallback\n     * @return $this\n     */\n    public function withQuery($queryCallback = null)\n    {\n        $this->queryCallback = $queryCallback;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Attempting.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nclass Attempting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  array  $credentials  The credentials for the user.\n     * @param  bool  $remember  Indicates if the user should be \"remembered\".\n     */\n    public function __construct(\n        public $guard,\n        #[\\SensitiveParameter] public $credentials,\n        public $remember,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Authenticated.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Authenticated\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The authenticated user.\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/CurrentDeviceLogout.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass CurrentDeviceLogout\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The authenticated user.\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Failed.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nclass Failed\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user  The user the attempter was trying to authenticate as.\n     * @param  array  $credentials  The credentials provided by the attempter.\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n        #[\\SensitiveParameter] public $credentials,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Lockout.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Http\\Request;\n\nclass Lockout\n{\n    /**\n     * The throttled request.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    public $request;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     */\n    public function __construct(Request $request)\n    {\n        $this->request = $request;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Login.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Login\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The authenticated user.\n     * @param  bool  $remember  Indicates if the user should be \"remembered\".\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n        public $remember,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Logout.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Logout\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The authenticated user.\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/OtherDeviceLogout.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass OtherDeviceLogout\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  \\Illuminate\\Contracts\\Auth\\Authenticatable\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/PasswordReset.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass PasswordReset\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The user.\n     */\n    public function __construct(\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/PasswordResetLinkSent.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass PasswordResetLinkSent\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user  The user instance.\n     */\n    public function __construct(\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Registered.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Registered\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The authenticated user.\n     */\n    public function __construct(\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Validated.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Validated\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $guard  The authentication guard name.\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user  The user retrieved and validated from the User Provider.\n     */\n    public function __construct(\n        public $guard,\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Events/Verified.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Events;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Verified\n{\n    use SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\MustVerifyEmail  $user  The verified user.\n     */\n    public function __construct(\n        public $user,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/GenericUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Contracts\\Auth\\Authenticatable as UserContract;\n\nclass GenericUser implements UserContract\n{\n    /**\n     * All of the user's attributes.\n     *\n     * @var array\n     */\n    protected $attributes;\n\n    /**\n     * Create a new generic User object.\n     *\n     * @param  array  $attributes\n     */\n    public function __construct(array $attributes)\n    {\n        $this->attributes = $attributes;\n    }\n\n    /**\n     * Get the name of the unique identifier for the user.\n     *\n     * @return string\n     */\n    public function getAuthIdentifierName()\n    {\n        return 'id';\n    }\n\n    /**\n     * Get the unique identifier for the user.\n     *\n     * @return mixed\n     */\n    public function getAuthIdentifier()\n    {\n        return $this->attributes[$this->getAuthIdentifierName()];\n    }\n\n    /**\n     * Get the name of the password attribute for the user.\n     *\n     * @return string\n     */\n    public function getAuthPasswordName()\n    {\n        return 'password';\n    }\n\n    /**\n     * Get the password for the user.\n     *\n     * @return string\n     */\n    public function getAuthPassword()\n    {\n        return $this->attributes[$this->getAuthPasswordName()];\n    }\n\n    /**\n     * Get the \"remember me\" token value.\n     *\n     * @return string\n     */\n    public function getRememberToken()\n    {\n        return $this->attributes[$this->getRememberTokenName()];\n    }\n\n    /**\n     * Set the \"remember me\" token value.\n     *\n     * @param  string  $value\n     * @return void\n     */\n    public function setRememberToken($value)\n    {\n        $this->attributes[$this->getRememberTokenName()] = $value;\n    }\n\n    /**\n     * Get the column name for the \"remember me\" token.\n     *\n     * @return string\n     */\n    public function getRememberTokenName()\n    {\n        return 'remember_token';\n    }\n\n    /**\n     * Dynamically access the user's attributes.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->attributes[$key];\n    }\n\n    /**\n     * Dynamically set an attribute on the user.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this->attributes[$key] = $value;\n    }\n\n    /**\n     * Dynamically check if a value is set on the user.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return isset($this->attributes[$key]);\n    }\n\n    /**\n     * Dynamically unset a value on the user.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function __unset($key)\n    {\n        unset($this->attributes[$key]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/GuardHelpers.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Contracts\\Auth\\Authenticatable as AuthenticatableContract;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\n\n/**\n * These methods are typically the same across all guards.\n */\ntrait GuardHelpers\n{\n    /**\n     * The currently authenticated user.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    protected $user;\n\n    /**\n     * The user provider implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\UserProvider\n     */\n    protected $provider;\n\n    /**\n     * Determine if the current user is authenticated. If not, throw an exception.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    public function authenticate()\n    {\n        return $this->user() ?? throw new AuthenticationException;\n    }\n\n    /**\n     * Determine if the guard has a user instance.\n     *\n     * @return bool\n     */\n    public function hasUser()\n    {\n        return ! is_null($this->user);\n    }\n\n    /**\n     * Determine if the current user is authenticated.\n     *\n     * @return bool\n     */\n    public function check()\n    {\n        return ! is_null($this->user());\n    }\n\n    /**\n     * Determine if the current user is a guest.\n     *\n     * @return bool\n     */\n    public function guest()\n    {\n        return ! $this->check();\n    }\n\n    /**\n     * Get the ID for the currently authenticated user.\n     *\n     * @return int|string|null\n     */\n    public function id()\n    {\n        return $this->user()?->getAuthIdentifier();\n    }\n\n    /**\n     * Set the current user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return $this\n     */\n    public function setUser(AuthenticatableContract $user)\n    {\n        $this->user = $user;\n\n        return $this;\n    }\n\n    /**\n     * Forget the current user.\n     *\n     * @return $this\n     */\n    public function forgetUser()\n    {\n        $this->user = null;\n\n        return $this;\n    }\n\n    /**\n     * Get the user provider used by the guard.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\UserProvider\n     */\n    public function getProvider()\n    {\n        return $this->provider;\n    }\n\n    /**\n     * Set the user provider used by the guard.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\UserProvider  $provider\n     * @return void\n     */\n    public function setProvider(UserProvider $provider)\n    {\n        $this->provider = $provider;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Listeners;\n\nuse Illuminate\\Auth\\Events\\Registered;\nuse Illuminate\\Contracts\\Auth\\MustVerifyEmail;\n\nclass SendEmailVerificationNotification\n{\n    /**\n     * Handle the event.\n     *\n     * @param  \\Illuminate\\Auth\\Events\\Registered  $event\n     * @return void\n     */\n    public function handle(Registered $event)\n    {\n        if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {\n            $event->user->sendEmailVerificationNotification();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/Authenticate.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Contracts\\Auth\\Factory as Auth;\nuse Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests;\nuse Illuminate\\Http\\Request;\n\nclass Authenticate implements AuthenticatesRequests\n{\n    /**\n     * The authentication factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Factory\n     */\n    protected $auth;\n\n    /**\n     * The callback that should be used to generate the authentication redirect path.\n     *\n     * @var callable\n     */\n    protected static $redirectToCallback;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Factory  $auth\n     */\n    public function __construct(Auth $auth)\n    {\n        $this->auth = $auth;\n    }\n\n    /**\n     * Specify the guards for the middleware.\n     *\n     * @param  string  $guard\n     * @param  string  $others\n     * @return string\n     */\n    public static function using($guard, ...$others)\n    {\n        return static::class.':'.implode(',', [$guard, ...$others]);\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string  ...$guards\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    public function handle($request, Closure $next, ...$guards)\n    {\n        $this->authenticate($request, $guards);\n\n        return $next($request);\n    }\n\n    /**\n     * Determine if the user is logged in to any of the given guards.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $guards\n     * @return void\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    protected function authenticate($request, array $guards)\n    {\n        if (empty($guards)) {\n            $guards = [null];\n        }\n\n        foreach ($guards as $guard) {\n            if ($this->auth->guard($guard)->check()) {\n                return $this->auth->shouldUse($guard);\n            }\n        }\n\n        $this->unauthenticated($request, $guards);\n    }\n\n    /**\n     * Handle an unauthenticated user.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $guards\n     * @return never\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    protected function unauthenticated($request, array $guards)\n    {\n        throw new AuthenticationException(\n            'Unauthenticated.',\n            $guards,\n            $request->expectsJson() ? null : $this->redirectTo($request),\n        );\n    }\n\n    /**\n     * Get the path the user should be redirected to when they are not authenticated.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return string|null\n     */\n    protected function redirectTo(Request $request)\n    {\n        if (static::$redirectToCallback) {\n            return call_user_func(static::$redirectToCallback, $request);\n        }\n    }\n\n    /**\n     * Specify the callback that should be used to generate the redirect path.\n     *\n     * @param  callable  $redirectToCallback\n     * @return void\n     */\n    public static function redirectUsing(callable $redirectToCallback)\n    {\n        static::$redirectToCallback = $redirectToCallback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/AuthenticateWithBasicAuth.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\Factory as AuthFactory;\n\nclass AuthenticateWithBasicAuth\n{\n    /**\n     * The guard factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Factory\n     */\n    protected $auth;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Factory  $auth\n     */\n    public function __construct(AuthFactory $auth)\n    {\n        $this->auth = $auth;\n    }\n\n    /**\n     * Specify the guard and field for the middleware.\n     *\n     * @param  string|null  $guard\n     * @param  string|null  $field\n     * @return string\n     *\n     * @named-arguments-supported\n     */\n    public static function using($guard = null, $field = null)\n    {\n        return static::class.':'.implode(',', func_get_args());\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string|null  $guard\n     * @param  string|null  $field\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException\n     */\n    public function handle($request, Closure $next, $guard = null, $field = null)\n    {\n        $this->auth->guard($guard)->basic($field ?: 'email');\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/Authorize.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Authorize\n{\n    /**\n     * The gate instance.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Access\\Gate\n     */\n    protected $gate;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Access\\Gate  $gate\n     */\n    public function __construct(Gate $gate)\n    {\n        $this->gate = $gate;\n    }\n\n    /**\n     * Specify the ability and models for the middleware.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  string  ...$models\n     * @return string\n     */\n    public static function using($ability, ...$models)\n    {\n        return static::class.':'.implode(',', [enum_value($ability), ...$models]);\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string  $ability\n     * @param  array|null  ...$models\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function handle($request, Closure $next, $ability, ...$models)\n    {\n        $this->gate->authorize($ability, $this->getGateArguments($request, $models));\n\n        return $next($request);\n    }\n\n    /**\n     * Get the arguments parameter for the gate.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array|null  $models\n     * @return array\n     */\n    protected function getGateArguments($request, $models)\n    {\n        if (is_null($models)) {\n            return [];\n        }\n\n        return (new Collection($models))\n            ->map(fn ($model) => $model instanceof Model ? $model : $this->getModel($request, $model))\n            ->all();\n    }\n\n    /**\n     * Get the model to authorize.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $model\n     * @return \\Illuminate\\Database\\Eloquent\\Model|string\n     */\n    protected function getModel($request, $model)\n    {\n        if ($this->isClassName($model)) {\n            return trim($model);\n        }\n\n        return $request->route($model, null) ??\n            ((preg_match(\"/^['\\\"](.*)['\\\"]$/\", trim($model), $matches)) ? $matches[1] : null);\n    }\n\n    /**\n     * Checks if the given string looks like a fully-qualified class name.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    protected function isClassName($value)\n    {\n        return str_contains($value, '\\\\');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/EnsureEmailIsVerified.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Auth\\MustVerifyEmail;\nuse Illuminate\\Support\\Facades\\Redirect;\nuse Illuminate\\Support\\Facades\\URL;\n\nclass EnsureEmailIsVerified\n{\n    /**\n     * Specify the redirect route for the middleware.\n     *\n     * @param  string  $route\n     * @return string\n     */\n    public static function redirectTo($route)\n    {\n        return static::class.':'.$route;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string|null  $redirectToRoute\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\RedirectResponse|null\n     */\n    public function handle($request, Closure $next, $redirectToRoute = null)\n    {\n        if (! $request->user() ||\n            ($request->user() instanceof MustVerifyEmail &&\n            ! $request->user()->hasVerifiedEmail())) {\n            return $request->expectsJson()\n                ? abort(403, 'Your email address is not verified.')\n                : Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));\n        }\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/RedirectIfAuthenticated.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Route;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass RedirectIfAuthenticated\n{\n    /**\n     * The callback that should be used to generate the authentication redirect path.\n     *\n     * @var callable|null\n     */\n    protected static $redirectToCallback;\n\n    /**\n     * Specify the guards for the middleware.\n     *\n     * @param  string  $guard\n     * @param  string  $others\n     * @return string\n     */\n    public static function using($guard, ...$others)\n    {\n        return static::class.':'.implode(',', [$guard, ...$others]);\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Closure(\\Illuminate\\Http\\Request): (\\Symfony\\Component\\HttpFoundation\\Response)  $next\n     */\n    public function handle(Request $request, Closure $next, string ...$guards): Response\n    {\n        $guards = empty($guards) ? [null] : $guards;\n\n        foreach ($guards as $guard) {\n            if (Auth::guard($guard)->check()) {\n                return redirect($this->redirectTo($request));\n            }\n        }\n\n        return $next($request);\n    }\n\n    /**\n     * Get the path the user should be redirected to when they are authenticated.\n     */\n    protected function redirectTo(Request $request): ?string\n    {\n        return static::$redirectToCallback\n            ? call_user_func(static::$redirectToCallback, $request)\n            : $this->defaultRedirectUri();\n    }\n\n    /**\n     * Get the default URI the user should be redirected to when they are authenticated.\n     */\n    protected function defaultRedirectUri(): string\n    {\n        foreach (['dashboard', 'home'] as $uri) {\n            if (Route::has($uri)) {\n                return route($uri);\n            }\n        }\n\n        $routes = Route::getRoutes()->get('GET');\n\n        foreach (['dashboard', 'home'] as $uri) {\n            if (isset($routes[$uri])) {\n                return '/'.$uri;\n            }\n        }\n\n        return '/';\n    }\n\n    /**\n     * Specify the callback that should be used to generate the redirect path.\n     *\n     * @param  callable  $redirectToCallback\n     * @return void\n     */\n    public static function redirectUsing(callable $redirectToCallback)\n    {\n        static::$redirectToCallback = $redirectToCallback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Middleware/RequirePassword.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Facades\\Date;\n\nclass RequirePassword\n{\n    /**\n     * The response factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\Routing\\ResponseFactory\n     */\n    protected $responseFactory;\n\n    /**\n     * The URL generator instance.\n     *\n     * @var \\Illuminate\\Contracts\\Routing\\UrlGenerator\n     */\n    protected $urlGenerator;\n\n    /**\n     * The password timeout.\n     *\n     * @var int\n     */\n    protected $passwordTimeout;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Routing\\ResponseFactory  $responseFactory\n     * @param  \\Illuminate\\Contracts\\Routing\\UrlGenerator  $urlGenerator\n     * @param  int|null  $passwordTimeout\n     */\n    public function __construct(ResponseFactory $responseFactory, UrlGenerator $urlGenerator, $passwordTimeout = null)\n    {\n        $this->responseFactory = $responseFactory;\n        $this->urlGenerator = $urlGenerator;\n        $this->passwordTimeout = $passwordTimeout ?: 10800;\n    }\n\n    /**\n     * Specify the redirect route and timeout for the middleware.\n     *\n     * @param  string|null  $redirectToRoute\n     * @param  string|int|null  $passwordTimeoutSeconds\n     * @return string\n     *\n     * @named-arguments-supported\n     */\n    public static function using($redirectToRoute = null, $passwordTimeoutSeconds = null)\n    {\n        return static::class.':'.implode(',', func_get_args());\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string|null  $redirectToRoute\n     * @param  string|int|null  $passwordTimeoutSeconds\n     * @return mixed\n     */\n    public function handle($request, Closure $next, $redirectToRoute = null, $passwordTimeoutSeconds = null)\n    {\n        if ($this->shouldConfirmPassword($request, $passwordTimeoutSeconds)) {\n            if ($request->expectsJson()) {\n                return $this->responseFactory->json([\n                    'message' => 'Password confirmation required.',\n                ], 423);\n            }\n\n            return $this->responseFactory->redirectGuest(\n                $this->urlGenerator->route($redirectToRoute ?: 'password.confirm')\n            );\n        }\n\n        return $next($request);\n    }\n\n    /**\n     * Determine if the confirmation timeout has expired.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  int|null  $passwordTimeoutSeconds\n     * @return bool\n     */\n    protected function shouldConfirmPassword($request, $passwordTimeoutSeconds = null)\n    {\n        $confirmedAt = Date::now()->unix() - $request->session()->get('auth.password_confirmed_at', 0);\n\n        return $confirmedAt > ($passwordTimeoutSeconds ?? $this->passwordTimeout);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/MustVerifyEmail.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Auth\\Notifications\\VerifyEmail;\n\ntrait MustVerifyEmail\n{\n    /**\n     * Determine if the user has verified their email address.\n     *\n     * @return bool\n     */\n    public function hasVerifiedEmail()\n    {\n        return ! is_null($this->email_verified_at);\n    }\n\n    /**\n     * Mark the user's email as verified.\n     *\n     * @return bool\n     */\n    public function markEmailAsVerified()\n    {\n        return $this->forceFill([\n            'email_verified_at' => $this->freshTimestamp(),\n        ])->save();\n    }\n\n    /**\n     * Mark the user's email as unverified.\n     *\n     * @return bool\n     */\n    public function markEmailAsUnverified()\n    {\n        return $this->forceFill([\n            'email_verified_at' => null,\n        ])->save();\n    }\n\n    /**\n     * Send the email verification notification.\n     *\n     * @return void\n     */\n    public function sendEmailVerificationNotification()\n    {\n        $this->notify(new VerifyEmail);\n    }\n\n    /**\n     * Get the email address that should be used for verification.\n     *\n     * @return string\n     */\n    public function getEmailForVerification()\n    {\n        return $this->email;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Notifications/ResetPassword.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Notifications;\n\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Facades\\Lang;\n\nclass ResetPassword extends Notification\n{\n    /**\n     * The password reset token.\n     *\n     * @var string\n     */\n    public $token;\n\n    /**\n     * The callback that should be used to create the reset password URL.\n     *\n     * @var (\\Closure(mixed, string): string)|null\n     */\n    public static $createUrlCallback;\n\n    /**\n     * The callback that should be used to build the mail message.\n     *\n     * @var (\\Closure(mixed, string): \\Illuminate\\Notifications\\Messages\\MailMessage|\\Illuminate\\Contracts\\Mail\\Mailable)|null\n     */\n    public static $toMailCallback;\n\n    /**\n     * Create a notification instance.\n     *\n     * @param  string  $token\n     */\n    public function __construct(#[\\SensitiveParameter] $token)\n    {\n        $this->token = $token;\n    }\n\n    /**\n     * Get the notification's channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return ['mail'];\n    }\n\n    /**\n     * Build the mail representation of the notification.\n     *\n     * @param  mixed  $notifiable\n     * @return \\Illuminate\\Notifications\\Messages\\MailMessage\n     */\n    public function toMail($notifiable)\n    {\n        if (static::$toMailCallback) {\n            return call_user_func(static::$toMailCallback, $notifiable, $this->token);\n        }\n\n        return $this->buildMailMessage($this->resetUrl($notifiable));\n    }\n\n    /**\n     * Get the reset password notification mail message for the given URL.\n     *\n     * @param  string  $url\n     * @return \\Illuminate\\Notifications\\Messages\\MailMessage\n     */\n    protected function buildMailMessage($url)\n    {\n        return (new MailMessage)\n            ->subject(Lang::get('Reset your password'))\n            ->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))\n            ->action(Lang::get('Reset Password'), $url)\n            ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))\n            ->line(Lang::get('If you did not request a password reset, no further action is required.'));\n    }\n\n    /**\n     * Get the reset URL for the given notifiable.\n     *\n     * @param  mixed  $notifiable\n     * @return string\n     */\n    protected function resetUrl($notifiable)\n    {\n        if (static::$createUrlCallback) {\n            return call_user_func(static::$createUrlCallback, $notifiable, $this->token);\n        }\n\n        return url(route('password.reset', [\n            'token' => $this->token,\n            'email' => $notifiable->getEmailForPasswordReset(),\n        ], false));\n    }\n\n    /**\n     * Set a callback that should be used when creating the reset password button URL.\n     *\n     * @param  \\Closure(mixed, string): string  $callback\n     * @return void\n     */\n    public static function createUrlUsing($callback)\n    {\n        static::$createUrlCallback = $callback;\n    }\n\n    /**\n     * Set a callback that should be used when building the notification mail message.\n     *\n     * @param  \\Closure(mixed, string): (\\Illuminate\\Notifications\\Messages\\MailMessage|\\Illuminate\\Contracts\\Mail\\Mailable)  $callback\n     * @return void\n     */\n    public static function toMailUsing($callback)\n    {\n        static::$toMailCallback = $callback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Notifications/VerifyEmail.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Notifications;\n\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Lang;\nuse Illuminate\\Support\\Facades\\URL;\n\nclass VerifyEmail extends Notification\n{\n    /**\n     * The callback that should be used to create the verify email URL.\n     *\n     * @var \\Closure|null\n     */\n    public static $createUrlCallback;\n\n    /**\n     * The callback that should be used to build the mail message.\n     *\n     * @var (\\Closure(mixed, string): \\Illuminate\\Notifications\\Messages\\MailMessage|\\Illuminate\\Contracts\\Mail\\Mailable)|null\n     */\n    public static $toMailCallback;\n\n    /**\n     * Get the notification's channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return ['mail'];\n    }\n\n    /**\n     * Build the mail representation of the notification.\n     *\n     * @param  mixed  $notifiable\n     * @return \\Illuminate\\Notifications\\Messages\\MailMessage\n     */\n    public function toMail($notifiable)\n    {\n        $verificationUrl = $this->verificationUrl($notifiable);\n\n        if (static::$toMailCallback) {\n            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);\n        }\n\n        return $this->buildMailMessage($verificationUrl);\n    }\n\n    /**\n     * Get the verify email notification mail message for the given URL.\n     *\n     * @param  string  $url\n     * @return \\Illuminate\\Notifications\\Messages\\MailMessage\n     */\n    protected function buildMailMessage($url)\n    {\n        return (new MailMessage)\n            ->subject(Lang::get('Verify your email address'))\n            ->line(Lang::get('Please click the button below to verify your email address.'))\n            ->action(Lang::get('Verify Email Address'), $url)\n            ->line(Lang::get('If you did not create an account, no further action is required.'));\n    }\n\n    /**\n     * Get the verification URL for the given notifiable.\n     *\n     * @param  mixed  $notifiable\n     * @return string\n     */\n    protected function verificationUrl($notifiable)\n    {\n        if (static::$createUrlCallback) {\n            return call_user_func(static::$createUrlCallback, $notifiable);\n        }\n\n        return URL::temporarySignedRoute(\n            'verification.verify',\n            Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),\n            [\n                'id' => $notifiable->getKey(),\n                'hash' => sha1($notifiable->getEmailForVerification()),\n            ]\n        );\n    }\n\n    /**\n     * Set a callback that should be used when creating the email verification URL.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function createUrlUsing($callback)\n    {\n        static::$createUrlCallback = $callback;\n    }\n\n    /**\n     * Set a callback that should be used when building the notification mail message.\n     *\n     * @param  \\Closure(mixed, string): (\\Illuminate\\Notifications\\Messages\\MailMessage|\\Illuminate\\Contracts\\Mail\\Mailable)  $callback\n     * @return void\n     */\n    public static function toMailUsing($callback)\n    {\n        static::$toMailCallback = $callback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/CacheTokenRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Contracts\\Auth\\CanResetPassword as CanResetPasswordContract;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\n\nclass CacheTokenRepository implements TokenRepositoryInterface\n{\n    /**\n     * The format of the stored Carbon object.\n     */\n    protected string $format = 'Y-m-d H:i:s';\n\n    /**\n     * Create a new token repository instance.\n     */\n    public function __construct(\n        protected Repository $cache,\n        protected HasherContract $hasher,\n        protected string $hashKey,\n        protected int $expires = 3600,\n        protected int $throttle = 60,\n    ) {\n    }\n\n    /**\n     * Create a new token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function create(CanResetPasswordContract $user)\n    {\n        $this->delete($user);\n\n        $token = hash_hmac('sha256', Str::random(40), $this->hashKey);\n\n        $this->cache->put(\n            $this->cacheKey($user),\n            [$this->hasher->make($token), Carbon::now()->format($this->format)],\n            $this->expires,\n        );\n\n        return $token;\n    }\n\n    /**\n     * Determine if a token record exists and is valid.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @param  string  $token\n     * @return bool\n     */\n    public function exists(CanResetPasswordContract $user, #[\\SensitiveParameter] $token)\n    {\n        [$record, $createdAt] = $this->cache->get($this->cacheKey($user));\n\n        return $record\n            && ! $this->tokenExpired($createdAt)\n            && $this->hasher->check($token, $record);\n    }\n\n    /**\n     * Determine if the token has expired.\n     *\n     * @param  string  $createdAt\n     * @return bool\n     */\n    protected function tokenExpired($createdAt)\n    {\n        return Carbon::createFromFormat($this->format, $createdAt)->addSeconds($this->expires)->isPast();\n    }\n\n    /**\n     * Determine if the given user recently created a password reset token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return bool\n     */\n    public function recentlyCreatedToken(CanResetPasswordContract $user)\n    {\n        [$record, $createdAt] = $this->cache->get($this->cacheKey($user));\n\n        return $record && $this->tokenRecentlyCreated($createdAt);\n    }\n\n    /**\n     * Determine if the token was recently created.\n     *\n     * @param  string  $createdAt\n     * @return bool\n     */\n    protected function tokenRecentlyCreated($createdAt)\n    {\n        if ($this->throttle <= 0) {\n            return false;\n        }\n\n        return Carbon::createFromFormat($this->format, $createdAt)->addSeconds(\n            $this->throttle\n        )->isFuture();\n    }\n\n    /**\n     * Delete a token record.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return void\n     */\n    public function delete(CanResetPasswordContract $user)\n    {\n        $this->cache->forget($this->cacheKey($user));\n    }\n\n    /**\n     * Delete expired tokens.\n     *\n     * @return void\n     */\n    public function deleteExpired()\n    {\n    }\n\n    /**\n     * Determine the cache key for the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function cacheKey(CanResetPasswordContract $user): string\n    {\n        return hash('sha256', $user->getEmailForPasswordReset());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/CanResetPassword.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Auth\\Notifications\\ResetPassword as ResetPasswordNotification;\n\ntrait CanResetPassword\n{\n    /**\n     * Get the e-mail address where password reset links are sent.\n     *\n     * @return string\n     */\n    public function getEmailForPasswordReset()\n    {\n        return $this->email;\n    }\n\n    /**\n     * Send the password reset notification.\n     *\n     * @param  string  $token\n     * @return void\n     */\n    public function sendPasswordResetNotification(#[\\SensitiveParameter] $token)\n    {\n        $this->notify(new ResetPasswordNotification($token));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Contracts\\Auth\\CanResetPassword as CanResetPasswordContract;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\n\nclass DatabaseTokenRepository implements TokenRepositoryInterface\n{\n    /**\n     * Create a new token repository instance.\n     *\n     * @param  int  $expires  The number of seconds a token should remain valid.\n     * @param  int  $throttle  Minimum number of seconds before the user can generate new password reset tokens.\n     */\n    public function __construct(\n        protected ConnectionInterface $connection,\n        protected HasherContract $hasher,\n        protected string $table,\n        protected string $hashKey,\n        protected int $expires = 3600,\n        protected int $throttle = 60,\n    ) {\n    }\n\n    /**\n     * Create a new token record.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function create(CanResetPasswordContract $user)\n    {\n        $email = $user->getEmailForPasswordReset();\n\n        $this->deleteExisting($user);\n\n        // We will create a new, random token for the user so that we can e-mail them\n        // a safe link to the password reset form. Then we will insert a record in\n        // the database so that we can verify the token within the actual reset.\n        $token = $this->createNewToken();\n\n        $this->getTable()->insert($this->getPayload($email, $token));\n\n        return $token;\n    }\n\n    /**\n     * Delete all existing reset tokens from the database.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return int\n     */\n    protected function deleteExisting(CanResetPasswordContract $user)\n    {\n        return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();\n    }\n\n    /**\n     * Build the record payload for the table.\n     *\n     * @param  string  $email\n     * @param  string  $token\n     * @return array\n     */\n    protected function getPayload($email, #[\\SensitiveParameter] $token)\n    {\n        return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new Carbon];\n    }\n\n    /**\n     * Determine if a token record exists and is valid.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @param  string  $token\n     * @return bool\n     */\n    public function exists(CanResetPasswordContract $user, #[\\SensitiveParameter] $token)\n    {\n        $record = (array) $this->getTable()->where(\n            'email', $user->getEmailForPasswordReset()\n        )->first();\n\n        return $record &&\n               ! $this->tokenExpired($record['created_at']) &&\n                 $this->hasher->check($token, $record['token']);\n    }\n\n    /**\n     * Determine if the token has expired.\n     *\n     * @param  string  $createdAt\n     * @return bool\n     */\n    protected function tokenExpired($createdAt)\n    {\n        return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();\n    }\n\n    /**\n     * Determine if the given user recently created a password reset token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return bool\n     */\n    public function recentlyCreatedToken(CanResetPasswordContract $user)\n    {\n        $record = (array) $this->getTable()->where(\n            'email', $user->getEmailForPasswordReset()\n        )->first();\n\n        return $record && $this->tokenRecentlyCreated($record['created_at']);\n    }\n\n    /**\n     * Determine if the token was recently created.\n     *\n     * @param  string  $createdAt\n     * @return bool\n     */\n    protected function tokenRecentlyCreated($createdAt)\n    {\n        if ($this->throttle <= 0) {\n            return false;\n        }\n\n        return Carbon::parse($createdAt)->addSeconds(\n            $this->throttle\n        )->isFuture();\n    }\n\n    /**\n     * Delete a token record by user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return void\n     */\n    public function delete(CanResetPasswordContract $user)\n    {\n        $this->deleteExisting($user);\n    }\n\n    /**\n     * Delete expired tokens.\n     *\n     * @return void\n     */\n    public function deleteExpired()\n    {\n        $expiredAt = Carbon::now()->subSeconds($this->expires);\n\n        $this->getTable()->where('created_at', '<', $expiredAt)->delete();\n    }\n\n    /**\n     * Create a new token for the user.\n     *\n     * @return string\n     */\n    public function createNewToken()\n    {\n        return hash_hmac('sha256', Str::random(40), $this->hashKey);\n    }\n\n    /**\n     * Get the database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Begin a new database query against the table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function getTable()\n    {\n        return $this->connection->table($this->table);\n    }\n\n    /**\n     * Get the hasher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Hashing\\Hasher\n     */\n    public function getHasher()\n    {\n        return $this->hasher;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/PasswordBroker.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Closure;\nuse Illuminate\\Auth\\Events\\PasswordResetLinkSent;\nuse Illuminate\\Contracts\\Auth\\CanResetPassword as CanResetPasswordContract;\nuse Illuminate\\Contracts\\Auth\\PasswordBroker as PasswordBrokerContract;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Timebox;\nuse UnexpectedValueException;\n\nclass PasswordBroker implements PasswordBrokerContract\n{\n    /**\n     * The password token repository.\n     *\n     * @var \\Illuminate\\Auth\\Passwords\\TokenRepositoryInterface\n     */\n    protected $tokens;\n\n    /**\n     * The user provider implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\UserProvider\n     */\n    protected $users;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $events;\n\n    /**\n     * The timebox instance.\n     *\n     * @var \\Illuminate\\Support\\Timebox\n     */\n    protected $timebox;\n\n    /**\n     * The number of microseconds that the timebox should wait for.\n     *\n     * @var int\n     */\n    protected $timeboxDuration;\n\n    /**\n     * Create a new password broker instance.\n     *\n     * @param  \\Illuminate\\Auth\\Passwords\\TokenRepositoryInterface  $tokens\n     * @param  \\Illuminate\\Contracts\\Auth\\UserProvider  $users\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher|null  $dispatcher\n     * @param  \\Illuminate\\Support\\Timebox|null  $timebox\n     * @param  int  $timeboxDuration\n     */\n    public function __construct(\n        #[\\SensitiveParameter] TokenRepositoryInterface $tokens,\n        UserProvider $users,\n        ?Dispatcher $dispatcher = null,\n        ?Timebox $timebox = null,\n        int $timeboxDuration = 200000,\n    ) {\n        $this->users = $users;\n        $this->tokens = $tokens;\n        $this->events = $dispatcher;\n        $this->timebox = $timebox ?: new Timebox;\n        $this->timeboxDuration = $timeboxDuration;\n    }\n\n    /**\n     * Send a password reset link to a user.\n     *\n     * @param  array  $credentials\n     * @param  \\Closure|null  $callback\n     * @return string\n     */\n    public function sendResetLink(#[\\SensitiveParameter] array $credentials, ?Closure $callback = null)\n    {\n        return $this->timebox->call(function () use ($credentials, $callback) {\n            // First we will check to see if we found a user at the given credentials and\n            // if we did not we will redirect back to this current URI with a piece of\n            // \"flash\" data in the session to indicate to the developers the errors.\n            $user = $this->getUser($credentials);\n\n            if (is_null($user)) {\n                return static::INVALID_USER;\n            }\n\n            if ($this->tokens->recentlyCreatedToken($user)) {\n                return static::RESET_THROTTLED;\n            }\n\n            $token = $this->tokens->create($user);\n\n            if ($callback) {\n                return $callback($user, $token) ?? static::RESET_LINK_SENT;\n            }\n\n            // Once we have the reset token, we are ready to send the message out to this\n            // user with a link to reset their password. We will then redirect back to\n            // the current URI having nothing set in the session to indicate errors.\n            $user->sendPasswordResetNotification($token);\n\n            $this->events?->dispatch(new PasswordResetLinkSent($user));\n\n            return static::RESET_LINK_SENT;\n        }, $this->timeboxDuration);\n    }\n\n    /**\n     * Reset the password for the given token.\n     *\n     * @param  array  $credentials\n     * @param  \\Closure  $callback\n     * @return string\n     */\n    public function reset(#[\\SensitiveParameter] array $credentials, Closure $callback)\n    {\n        return $this->timebox->call(function ($timebox) use ($credentials, $callback) {\n            $user = $this->validateReset($credentials);\n\n            // If the responses from the validate method is not a user instance, we will\n            // assume that it is a redirect and simply return it from this method and\n            // the user is properly redirected having an error message on the post.\n            if (! $user instanceof CanResetPasswordContract) {\n                return $user;\n            }\n\n            $password = $credentials['password'];\n\n            // Once the reset has been validated, we'll call the given callback with the\n            // new password. This gives the user an opportunity to store the password\n            // in their persistent storage. Then we'll delete the token and return.\n            $callback($user, $password);\n\n            $this->tokens->delete($user);\n\n            $timebox->returnEarly();\n\n            return static::PASSWORD_RESET;\n        }, $this->timeboxDuration);\n    }\n\n    /**\n     * Validate a password reset for the given credentials.\n     *\n     * @param  array  $credentials\n     * @return \\Illuminate\\Contracts\\Auth\\CanResetPassword|string\n     */\n    protected function validateReset(#[\\SensitiveParameter] array $credentials)\n    {\n        if (is_null($user = $this->getUser($credentials))) {\n            return static::INVALID_USER;\n        }\n\n        if (! $this->tokens->exists($user, $credentials['token'])) {\n            return static::INVALID_TOKEN;\n        }\n\n        return $user;\n    }\n\n    /**\n     * Get the user for the given credentials.\n     *\n     * @param  array  $credentials\n     * @return \\Illuminate\\Contracts\\Auth\\CanResetPassword|null\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function getUser(#[\\SensitiveParameter] array $credentials)\n    {\n        $credentials = Arr::except($credentials, ['token']);\n\n        $user = $this->users->retrieveByCredentials($credentials);\n\n        if ($user && ! $user instanceof CanResetPasswordContract) {\n            throw new UnexpectedValueException('User must implement CanResetPassword interface.');\n        }\n\n        return $user;\n    }\n\n    /**\n     * Create a new password reset token for the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function createToken(CanResetPasswordContract $user)\n    {\n        return $this->tokens->create($user);\n    }\n\n    /**\n     * Delete password reset tokens of the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return void\n     */\n    public function deleteToken(CanResetPasswordContract $user)\n    {\n        $this->tokens->delete($user);\n    }\n\n    /**\n     * Validate the given password reset token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @param  string  $token\n     * @return bool\n     */\n    public function tokenExists(CanResetPasswordContract $user, #[\\SensitiveParameter] $token)\n    {\n        return $this->tokens->exists($user, $token);\n    }\n\n    /**\n     * Get the password reset token repository implementation.\n     *\n     * @return \\Illuminate\\Auth\\Passwords\\TokenRepositoryInterface\n     */\n    public function getRepository()\n    {\n        return $this->tokens;\n    }\n\n    /**\n     * Get the timebox instance used by the guard.\n     *\n     * @return \\Illuminate\\Support\\Timebox\n     */\n    public function getTimebox()\n    {\n        return $this->timebox;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/PasswordBrokerManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Contracts\\Auth\\PasswordBrokerFactory as FactoryContract;\nuse InvalidArgumentException;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Auth\\PasswordBroker\n */\nclass PasswordBrokerManager implements FactoryContract\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of created \"drivers\".\n     *\n     * @var array\n     */\n    protected $brokers = [];\n\n    /**\n     * Create a new PasswordBroker manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Attempt to get the broker from the local cache.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Auth\\PasswordBroker\n     */\n    public function broker($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        return $this->brokers[$name] ?? ($this->brokers[$name] = $this->resolve($name));\n    }\n\n    /**\n     * Resolve the given broker.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Auth\\PasswordBroker\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Password resetter [{$name}] is not defined.\");\n        }\n\n        // The password broker uses a token repository to validate tokens and send user\n        // password e-mails, as well as validating that password reset process as an\n        // aggregate service of sorts providing a convenient interface for resets.\n        return new PasswordBroker(\n            $this->createTokenRepository($config),\n            $this->app['auth']->createUserProvider($config['provider'] ?? null),\n            $this->app['events'] ?? null,\n            timeboxDuration: $this->app['config']->get('auth.timebox_duration', 200000),\n        );\n    }\n\n    /**\n     * Create a token repository instance based on the given configuration.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Auth\\Passwords\\TokenRepositoryInterface\n     */\n    protected function createTokenRepository(array $config)\n    {\n        $key = $this->app['config']['app.key'];\n\n        if (str_starts_with($key, 'base64:')) {\n            $key = base64_decode(substr($key, 7));\n        }\n\n        if (isset($config['driver']) && $config['driver'] === 'cache') {\n            return new CacheTokenRepository(\n                $this->app['cache']->store($config['store'] ?? null),\n                $this->app['hash'],\n                $key,\n                ($config['expire'] ?? 60) * 60,\n                $config['throttle'] ?? 0,\n            );\n        }\n\n        return new DatabaseTokenRepository(\n            $this->app['db']->connection($config['connection'] ?? null),\n            $this->app['hash'],\n            $config['table'],\n            $key,\n            ($config['expire'] ?? 60) * 60,\n            $config['throttle'] ?? 0,\n        );\n    }\n\n    /**\n     * Get the password broker configuration.\n     *\n     * @param  string  $name\n     * @return array|null\n     */\n    protected function getConfig($name)\n    {\n        return $this->app['config'][\"auth.passwords.{$name}\"];\n    }\n\n    /**\n     * Get the default password broker name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['auth.defaults.passwords'];\n    }\n\n    /**\n     * Set the default password broker name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['auth.defaults.passwords'] = $name;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->broker()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/PasswordResetServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass PasswordResetServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerPasswordBroker();\n    }\n\n    /**\n     * Register the password broker instance.\n     *\n     * @return void\n     */\n    protected function registerPasswordBroker()\n    {\n        $this->app->singleton('auth.password', function ($app) {\n            return new PasswordBrokerManager($app);\n        });\n\n        $this->app->bind('auth.password.broker', function ($app) {\n            return $app->make('auth.password')->broker();\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['auth.password', 'auth.password.broker'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Passwords/TokenRepositoryInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth\\Passwords;\n\nuse Illuminate\\Contracts\\Auth\\CanResetPassword as CanResetPasswordContract;\n\ninterface TokenRepositoryInterface\n{\n    /**\n     * Create a new token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return string\n     */\n    public function create(CanResetPasswordContract $user);\n\n    /**\n     * Determine if a token record exists and is valid.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @param  string  $token\n     * @return bool\n     */\n    public function exists(CanResetPasswordContract $user, #[\\SensitiveParameter] $token);\n\n    /**\n     * Determine if the given user recently created a password reset token.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return bool\n     */\n    public function recentlyCreatedToken(CanResetPasswordContract $user);\n\n    /**\n     * Delete a token record.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\CanResetPassword  $user\n     * @return void\n     */\n    public function delete(CanResetPasswordContract $user);\n\n    /**\n     * Delete expired tokens.\n     *\n     * @return void\n     */\n    public function deleteExpired();\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/Recaller.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nclass Recaller\n{\n    /**\n     * The \"recaller\" / \"remember me\" cookie string.\n     *\n     * @var string\n     */\n    protected $recaller;\n\n    /**\n     * Create a new recaller instance.\n     *\n     * @param  string  $recaller\n     */\n    public function __construct($recaller)\n    {\n        $this->recaller = @unserialize($recaller, ['allowed_classes' => false]) ?: $recaller;\n    }\n\n    /**\n     * Get the user ID from the recaller.\n     *\n     * @return string\n     */\n    public function id()\n    {\n        return explode('|', $this->recaller, 3)[0];\n    }\n\n    /**\n     * Get the \"remember token\" token from the recaller.\n     *\n     * @return string\n     */\n    public function token()\n    {\n        return explode('|', $this->recaller, 3)[1];\n    }\n\n    /**\n     * Get the password from the recaller.\n     *\n     * @return string\n     */\n    public function hash()\n    {\n        return explode('|', $this->recaller, 4)[2];\n    }\n\n    /**\n     * Determine if the recaller is valid.\n     *\n     * @return bool\n     */\n    public function valid()\n    {\n        return $this->properString() && $this->hasAllSegments();\n    }\n\n    /**\n     * Determine if the recaller is an invalid string.\n     *\n     * @return bool\n     */\n    protected function properString()\n    {\n        return is_string($this->recaller) && str_contains($this->recaller, '|');\n    }\n\n    /**\n     * Determine if the recaller has all segments.\n     *\n     * @return bool\n     */\n    protected function hasAllSegments()\n    {\n        $segments = explode('|', $this->recaller);\n\n        return count($segments) >= 3 && trim($segments[0]) !== '' && trim($segments[1]) !== '';\n    }\n\n    /**\n     * Get the recaller's segments.\n     *\n     * @return array\n     */\n    public function segments()\n    {\n        return explode('|', $this->recaller);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/RequestGuard.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Contracts\\Auth\\Guard;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass RequestGuard implements Guard\n{\n    use GuardHelpers, Macroable;\n\n    /**\n     * The guard callback.\n     *\n     * @var callable\n     */\n    protected $callback;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * Create a new authentication guard.\n     *\n     * @param  callable  $callback\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Contracts\\Auth\\UserProvider|null  $provider\n     */\n    public function __construct(callable $callback, Request $request, ?UserProvider $provider = null)\n    {\n        $this->request = $request;\n        $this->callback = $callback;\n        $this->provider = $provider;\n    }\n\n    /**\n     * Get the currently authenticated user.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function user()\n    {\n        // If we've already retrieved the user for the current request we can just\n        // return it back immediately. We do not want to fetch the user data on\n        // every call to this method because that would be tremendously slow.\n        if (! is_null($this->user)) {\n            return $this->user;\n        }\n\n        return $this->user = call_user_func(\n            $this->callback, $this->request, $this->getProvider()\n        );\n    }\n\n    /**\n     * Validate a user's credentials.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validate(#[\\SensitiveParameter] array $credentials = [])\n    {\n        return ! is_null((new static(\n            $this->callback, $credentials['request'], $this->getProvider()\n        ))->user());\n    }\n\n    /**\n     * Set the current request instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return $this\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/SessionGuard.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Auth\\Events\\Attempting;\nuse Illuminate\\Auth\\Events\\Authenticated;\nuse Illuminate\\Auth\\Events\\CurrentDeviceLogout;\nuse Illuminate\\Auth\\Events\\Failed;\nuse Illuminate\\Auth\\Events\\Login;\nuse Illuminate\\Auth\\Events\\Logout;\nuse Illuminate\\Auth\\Events\\OtherDeviceLogout;\nuse Illuminate\\Auth\\Events\\Validated;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as AuthenticatableContract;\nuse Illuminate\\Contracts\\Auth\\StatefulGuard;\nuse Illuminate\\Contracts\\Auth\\SupportsBasicAuth;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Contracts\\Cookie\\QueueingFactory as CookieJar;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Timebox;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException;\n\nclass SessionGuard implements StatefulGuard, SupportsBasicAuth\n{\n    use GuardHelpers, Macroable;\n\n    /**\n     * The name of the guard. Typically \"web\".\n     *\n     * Corresponds to guard name in authentication configuration.\n     *\n     * @var string\n     */\n    public readonly string $name;\n\n    /**\n     * The user we last attempted to retrieve.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Authenticatable\n     */\n    protected $lastAttempted;\n\n    /**\n     * Indicates if the user was authenticated via a recaller cookie.\n     *\n     * @var bool\n     */\n    protected $viaRemember = false;\n\n    /**\n     * The number of minutes that the \"remember me\" cookie should be valid for.\n     *\n     * @var int\n     */\n    protected $rememberDuration = 576000;\n\n    /**\n     * The session used by the guard.\n     *\n     * @var \\Illuminate\\Contracts\\Session\\Session\n     */\n    protected $session;\n\n    /**\n     * The Illuminate cookie creator service.\n     *\n     * @var \\Illuminate\\Contracts\\Cookie\\QueueingFactory\n     */\n    protected $cookie;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\Request\n     */\n    protected $request;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The timebox instance.\n     *\n     * @var \\Illuminate\\Support\\Timebox\n     */\n    protected $timebox;\n\n    /**\n     * The number of microseconds that the timebox should wait for.\n     *\n     * @var int\n     */\n    protected $timeboxDuration;\n\n    /**\n     * Indicates if passwords should be rehashed on login if needed.\n     *\n     * @var bool\n     */\n    protected $rehashOnLogin;\n\n    /**\n     * The key used to hash recaller cookie values.\n     *\n     * @var string|null\n     */\n    protected $hashKey;\n\n    /**\n     * Indicates if the logout method has been called.\n     *\n     * @var bool\n     */\n    protected $loggedOut = false;\n\n    /**\n     * Indicates if a token user retrieval has been attempted.\n     *\n     * @var bool\n     */\n    protected $recallAttempted = false;\n\n    /**\n     * Create a new authentication guard.\n     *\n     * @param  string  $name\n     * @param  \\Illuminate\\Contracts\\Auth\\UserProvider  $provider\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request|null  $request\n     * @param  \\Illuminate\\Support\\Timebox|null  $timebox\n     * @param  bool  $rehashOnLogin\n     * @param  int  $timeboxDuration\n     * @param  string|null  $hashKey\n     */\n    public function __construct(\n        $name,\n        UserProvider $provider,\n        Session $session,\n        ?Request $request = null,\n        ?Timebox $timebox = null,\n        bool $rehashOnLogin = true,\n        int $timeboxDuration = 200000,\n        ?string $hashKey = null,\n    ) {\n        $this->name = $name;\n        $this->session = $session;\n        $this->request = $request;\n        $this->provider = $provider;\n        $this->timebox = $timebox ?: new Timebox;\n        $this->rehashOnLogin = $rehashOnLogin;\n        $this->timeboxDuration = $timeboxDuration;\n        $this->hashKey = $hashKey;\n    }\n\n    /**\n     * Get the currently authenticated user.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function user()\n    {\n        if ($this->loggedOut) {\n            return;\n        }\n\n        // If we've already retrieved the user for the current request we can just\n        // return it back immediately. We do not want to fetch the user data on\n        // every call to this method because that would be tremendously slow.\n        if (! is_null($this->user)) {\n            return $this->user;\n        }\n\n        $id = $this->session->get($this->getName());\n\n        // First we will try to load the user using the identifier in the session if\n        // one exists. Otherwise we will check for a \"remember me\" cookie in this\n        // request, and if one exists, attempt to retrieve the user using that.\n        if (! is_null($id) && $this->user = $this->provider->retrieveById($id)) {\n            $this->fireAuthenticatedEvent($this->user);\n        }\n\n        // If the user is null, but we decrypt a \"recaller\" cookie we can attempt to\n        // pull the user data on that cookie which serves as a remember cookie on\n        // the application. Once we have a user we can return it to the caller.\n        if (is_null($this->user) && ! is_null($recaller = $this->recaller())) {\n            $this->user = $this->userFromRecaller($recaller);\n\n            if ($this->user) {\n                $this->updateSession($this->user->getAuthIdentifier());\n\n                $this->fireLoginEvent($this->user, true);\n            }\n        }\n\n        return $this->user;\n    }\n\n    /**\n     * Pull a user from the repository by its \"remember me\" cookie token.\n     *\n     * @param  \\Illuminate\\Auth\\Recaller  $recaller\n     * @return mixed\n     */\n    protected function userFromRecaller($recaller)\n    {\n        if (! $recaller->valid() || $this->recallAttempted) {\n            return;\n        }\n\n        // If the user is null, but we decrypt a \"recaller\" cookie we can attempt to\n        // pull the user data on that cookie which serves as a remember cookie on\n        // the application. Once we have a user we can return it to the caller.\n        $this->recallAttempted = true;\n\n        $this->viaRemember = ! is_null($user = $this->provider->retrieveByToken(\n            $recaller->id(), $recaller->token()\n        ));\n\n        return $user;\n    }\n\n    /**\n     * Get the decrypted recaller cookie for the request.\n     *\n     * @return \\Illuminate\\Auth\\Recaller|null\n     */\n    protected function recaller()\n    {\n        if (is_null($this->request)) {\n            return;\n        }\n\n        if ($recaller = $this->request->cookies->get($this->getRecallerName())) {\n            return new Recaller($recaller);\n        }\n    }\n\n    /**\n     * Get the ID for the currently authenticated user.\n     *\n     * @return int|string|null\n     */\n    public function id()\n    {\n        if ($this->loggedOut) {\n            return;\n        }\n\n        return $this->user()\n            ? $this->user()->getAuthIdentifier()\n            : $this->session->get($this->getName());\n    }\n\n    /**\n     * Log a user into the application without sessions or cookies.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function once(array $credentials = [])\n    {\n        $this->fireAttemptEvent($credentials);\n\n        if ($this->validate($credentials)) {\n            $this->rehashPasswordIfRequired($this->lastAttempted, $credentials);\n\n            $this->setUser($this->lastAttempted);\n\n            return true;\n        }\n\n        $this->fireFailedEvent($this->lastAttempted, $credentials);\n\n        return false;\n    }\n\n    /**\n     * Log the given user ID into the application without sessions or cookies.\n     *\n     * @param  mixed  $id\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|false\n     */\n    public function onceUsingId($id)\n    {\n        if (! is_null($user = $this->provider->retrieveById($id))) {\n            $this->setUser($user);\n\n            return $user;\n        }\n\n        return false;\n    }\n\n    /**\n     * Validate a user's credentials.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validate(array $credentials = [])\n    {\n        return $this->timebox->call(function ($timebox) use ($credentials) {\n            $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);\n\n            $validated = $this->hasValidCredentials($user, $credentials);\n\n            if ($validated) {\n                $timebox->returnEarly();\n            }\n\n            return $validated;\n        }, $this->timeboxDuration);\n    }\n\n    /**\n     * Attempt to authenticate using HTTP Basic Auth.\n     *\n     * @param  string  $field\n     * @param  array  $extraConditions\n     * @return \\Symfony\\Component\\HttpFoundation\\Response|null\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException\n     */\n    public function basic($field = 'email', $extraConditions = [])\n    {\n        if ($this->check()) {\n            return;\n        }\n\n        // If a username is set on the HTTP basic request, we will return out without\n        // interrupting the request lifecycle. Otherwise, we'll need to generate a\n        // request indicating that the given credentials were invalid for login.\n        if ($this->attemptBasic($this->getRequest(), $field, $extraConditions)) {\n            return;\n        }\n\n        return $this->failedBasicResponse();\n    }\n\n    /**\n     * Perform a stateless HTTP Basic login attempt.\n     *\n     * @param  string  $field\n     * @param  array  $extraConditions\n     * @return \\Symfony\\Component\\HttpFoundation\\Response|null\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException\n     */\n    public function onceBasic($field = 'email', $extraConditions = [])\n    {\n        $credentials = $this->basicCredentials($this->getRequest(), $field);\n\n        if (! $this->once(array_merge($credentials, $extraConditions))) {\n            return $this->failedBasicResponse();\n        }\n    }\n\n    /**\n     * Attempt to authenticate using basic authentication.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @param  string  $field\n     * @param  array  $extraConditions\n     * @return bool\n     */\n    protected function attemptBasic(Request $request, $field, $extraConditions = [])\n    {\n        if (! $request->getUser()) {\n            return false;\n        }\n\n        return $this->attempt(array_merge(\n            $this->basicCredentials($request, $field), $extraConditions\n        ));\n    }\n\n    /**\n     * Get the credential array for an HTTP Basic request.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @param  string  $field\n     * @return array\n     */\n    protected function basicCredentials(Request $request, $field)\n    {\n        return [$field => $request->getUser(), 'password' => $request->getPassword()];\n    }\n\n    /**\n     * Get the response for basic authentication.\n     *\n     * @return void\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException\n     */\n    protected function failedBasicResponse()\n    {\n        throw new UnauthorizedHttpException('Basic', 'Invalid credentials.');\n    }\n\n    /**\n     * Attempt to authenticate a user using the given credentials.\n     *\n     * @param  array  $credentials\n     * @param  bool  $remember\n     * @return bool\n     */\n    public function attempt(array $credentials = [], $remember = false)\n    {\n        return $this->timebox->call(function ($timebox) use ($credentials, $remember) {\n            $this->fireAttemptEvent($credentials, $remember);\n\n            $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);\n\n            // If an implementation of UserInterface was returned, we'll ask the provider\n            // to validate the user against the given credentials, and if they are in\n            // fact valid we'll log the users into the application and return true.\n            if ($this->hasValidCredentials($user, $credentials)) {\n                $this->rehashPasswordIfRequired($user, $credentials);\n\n                $this->login($user, $remember);\n\n                $timebox->returnEarly();\n\n                return true;\n            }\n\n            // If the authentication attempt fails we will fire an event so that the user\n            // may be notified of any suspicious attempts to access their account from\n            // an unrecognized user. A developer may listen to this event as needed.\n            $this->fireFailedEvent($user, $credentials);\n\n            return false;\n        }, $this->timeboxDuration);\n    }\n\n    /**\n     * Attempt to authenticate a user with credentials and additional callbacks.\n     *\n     * @param  array  $credentials\n     * @param  array|callable|null  $callbacks\n     * @param  bool  $remember\n     * @return bool\n     */\n    public function attemptWhen(array $credentials = [], $callbacks = null, $remember = false)\n    {\n        return $this->timebox->call(function ($timebox) use ($credentials, $callbacks, $remember) {\n            $this->fireAttemptEvent($credentials, $remember);\n\n            $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);\n\n            // This method does the exact same thing as attempt, but also executes callbacks after\n            // the user is retrieved and validated. If one of the callbacks returns falsy we do\n            // not login the user. Instead, we will fail the specific authentication attempt.\n            if ($this->hasValidCredentials($user, $credentials) && $this->shouldLogin($callbacks, $user)) {\n                $this->rehashPasswordIfRequired($user, $credentials);\n\n                $this->login($user, $remember);\n\n                $timebox->returnEarly();\n\n                return true;\n            }\n\n            $this->fireFailedEvent($user, $credentials);\n\n            return false;\n        }, $this->timeboxDuration);\n    }\n\n    /**\n     * Determine if the user matches the credentials.\n     *\n     * @param  mixed  $user\n     * @param  array  $credentials\n     * @return bool\n     */\n    protected function hasValidCredentials($user, $credentials)\n    {\n        $validated = ! is_null($user) && $this->provider->validateCredentials($user, $credentials);\n\n        if ($validated) {\n            $this->fireValidatedEvent($user);\n        }\n\n        return $validated;\n    }\n\n    /**\n     * Determine if the user should login by executing the given callbacks.\n     *\n     * @param  array|callable|null  $callbacks\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return bool\n     */\n    protected function shouldLogin($callbacks, AuthenticatableContract $user)\n    {\n        foreach (Arr::wrap($callbacks) as $callback) {\n            if (! $callback($user, $this)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Rehash the user's password if enabled and required.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @return void\n     */\n    protected function rehashPasswordIfRequired(AuthenticatableContract $user, #[\\SensitiveParameter] array $credentials)\n    {\n        if ($this->rehashOnLogin) {\n            $this->provider->rehashPasswordIfRequired($user, $credentials);\n        }\n    }\n\n    /**\n     * Log the given user ID into the application.\n     *\n     * @param  mixed  $id\n     * @param  bool  $remember\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|false\n     */\n    public function loginUsingId($id, $remember = false)\n    {\n        if (! is_null($user = $this->provider->retrieveById($id))) {\n            $this->login($user, $remember);\n\n            return $user;\n        }\n\n        return false;\n    }\n\n    /**\n     * Log a user into the application.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  bool  $remember\n     * @return void\n     */\n    public function login(AuthenticatableContract $user, $remember = false)\n    {\n        $this->updateSession($user->getAuthIdentifier());\n\n        // If the user should be permanently \"remembered\" by the application we will\n        // queue a permanent cookie that contains the encrypted copy of the user\n        // identifier. We will then decrypt this later to retrieve the users.\n        if ($remember) {\n            $this->ensureRememberTokenIsSet($user);\n\n            $this->queueRecallerCookie($user);\n        }\n\n        // If we have an event dispatcher instance set we will fire an event so that\n        // any listeners will hook into the authentication events and run actions\n        // based on the login and logout events fired from the guard instances.\n        $this->fireLoginEvent($user, $remember);\n\n        $this->setUser($user);\n    }\n\n    /**\n     * Update the session with the given ID and regenerate the session's token.\n     *\n     * @param  string  $id\n     * @return void\n     */\n    protected function updateSession($id)\n    {\n        $this->session->put($this->getName(), $id);\n\n        $this->session->regenerate(true);\n    }\n\n    /**\n     * Create a new \"remember me\" token for the user if one doesn't already exist.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function ensureRememberTokenIsSet(AuthenticatableContract $user)\n    {\n        if (empty($user->getRememberToken())) {\n            $this->cycleRememberToken($user);\n        }\n    }\n\n    /**\n     * Queue the recaller cookie into the cookie jar.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function queueRecallerCookie(AuthenticatableContract $user)\n    {\n        $this->getCookieJar()->queue($this->createRecaller(\n            $user->getAuthIdentifier().'|'.\n            $user->getRememberToken().'|'.\n            $this->hashPasswordForCookie($user->getAuthPassword())\n        ));\n    }\n\n    /**\n     * Create a \"remember me\" cookie for a given ID.\n     *\n     * @param  string  $value\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    protected function createRecaller($value)\n    {\n        return $this->getCookieJar()->make($this->getRecallerName(), $value, $this->getRememberDuration());\n    }\n\n    /**\n     * Create a HMAC of the password hash for storage in cookies.\n     *\n     * @param  string  $passwordHash\n     * @return string\n     */\n    public function hashPasswordForCookie($passwordHash)\n    {\n        return hash_hmac(\n            'sha256',\n            $passwordHash,\n            $this->hashKey ?? 'base-key-for-password-hash-mac'\n        );\n    }\n\n    /**\n     * Log the user out of the application.\n     *\n     * @return void\n     */\n    public function logout()\n    {\n        $user = $this->user();\n\n        $this->clearUserDataFromStorage();\n\n        if (! is_null($this->user) && ! empty($user->getRememberToken())) {\n            $this->cycleRememberToken($user);\n        }\n\n        // If we have an event dispatcher instance, we can fire off the logout event\n        // so any further processing can be done. This allows the developer to be\n        // listening for anytime a user signs out of this application manually.\n        $this->events?->dispatch(new Logout($this->name, $user));\n\n        // Once we have fired the logout event we will clear the users out of memory\n        // so they are no longer available as the user is no longer considered as\n        // being signed into this application and should not be available here.\n        $this->user = null;\n\n        $this->loggedOut = true;\n    }\n\n    /**\n     * Log the user out of the application on their current device only.\n     *\n     * This method does not cycle the \"remember\" token.\n     *\n     * @return void\n     */\n    public function logoutCurrentDevice()\n    {\n        $user = $this->user();\n\n        $this->clearUserDataFromStorage();\n\n        // If we have an event dispatcher instance, we can fire off the logout event\n        // so any further processing can be done. This allows the developer to be\n        // listening for anytime a user signs out of this application manually.\n        $this->events?->dispatch(new CurrentDeviceLogout($this->name, $user));\n\n        // Once we have fired the logout event we will clear the users out of memory\n        // so they are no longer available as the user is no longer considered as\n        // being signed into this application and should not be available here.\n        $this->user = null;\n\n        $this->loggedOut = true;\n    }\n\n    /**\n     * Remove the user data from the session and cookies.\n     *\n     * @return void\n     */\n    protected function clearUserDataFromStorage()\n    {\n        $this->session->remove($this->getName());\n\n        $this->getCookieJar()->unqueue($this->getRecallerName());\n\n        if (! is_null($this->recaller())) {\n            $this->getCookieJar()->queue(\n                $this->getCookieJar()->forget($this->getRecallerName())\n            );\n        }\n    }\n\n    /**\n     * Refresh the \"remember me\" token for the user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function cycleRememberToken(AuthenticatableContract $user)\n    {\n        $user->setRememberToken($token = Str::random(60));\n\n        $this->provider->updateRememberToken($user, $token);\n    }\n\n    /**\n     * Invalidate other sessions for the current user.\n     *\n     * The application must be using the AuthenticateSession middleware.\n     *\n     * @param  string  $password\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    public function logoutOtherDevices($password)\n    {\n        if (! $this->user()) {\n            return;\n        }\n\n        $result = $this->rehashUserPasswordForDeviceLogout($password);\n\n        if ($this->recaller() ||\n            $this->getCookieJar()->hasQueued($this->getRecallerName())) {\n            $this->queueRecallerCookie($this->user());\n        }\n\n        $this->fireOtherDeviceLogoutEvent($this->user());\n\n        return $result;\n    }\n\n    /**\n     * Rehash the current user's password for logging out other devices via AuthenticateSession.\n     *\n     * @param  string  $password\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function rehashUserPasswordForDeviceLogout($password)\n    {\n        $user = $this->user();\n\n        if (! Hash::check($password, $user->getAuthPassword())) {\n            throw new InvalidArgumentException('The given password does not match the current password.');\n        }\n\n        $this->provider->rehashPasswordIfRequired(\n            $user, ['password' => $password], force: true\n        );\n    }\n\n    /**\n     * Register an authentication attempt event listener.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function attempting($callback)\n    {\n        $this->events?->listen(Events\\Attempting::class, $callback);\n    }\n\n    /**\n     * Fire the attempt event with the arguments.\n     *\n     * @param  array  $credentials\n     * @param  bool  $remember\n     * @return void\n     */\n    protected function fireAttemptEvent(array $credentials, $remember = false)\n    {\n        $this->events?->dispatch(new Attempting($this->name, $credentials, $remember));\n    }\n\n    /**\n     * Fires the validated event if the dispatcher is set.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function fireValidatedEvent($user)\n    {\n        $this->events?->dispatch(new Validated($this->name, $user));\n    }\n\n    /**\n     * Fire the login event if the dispatcher is set.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  bool  $remember\n     * @return void\n     */\n    protected function fireLoginEvent($user, $remember = false)\n    {\n        $this->events?->dispatch(new Login($this->name, $user, $remember));\n    }\n\n    /**\n     * Fire the authenticated event if the dispatcher is set.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function fireAuthenticatedEvent($user)\n    {\n        $this->events?->dispatch(new Authenticated($this->name, $user));\n    }\n\n    /**\n     * Fire the other device logout event if the dispatcher is set.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return void\n     */\n    protected function fireOtherDeviceLogoutEvent($user)\n    {\n        $this->events?->dispatch(new OtherDeviceLogout($this->name, $user));\n    }\n\n    /**\n     * Fire the failed authentication attempt event with the given arguments.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|null  $user\n     * @param  array  $credentials\n     * @return void\n     */\n    protected function fireFailedEvent($user, array $credentials)\n    {\n        $this->events?->dispatch(new Failed($this->name, $user, $credentials));\n    }\n\n    /**\n     * Get the last user we attempted to authenticate.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable\n     */\n    public function getLastAttempted()\n    {\n        return $this->lastAttempted;\n    }\n\n    /**\n     * Get a unique identifier for the auth session value.\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return 'login_'.$this->name.'_'.sha1(static::class);\n    }\n\n    /**\n     * Get the name of the cookie used to store the \"recaller\".\n     *\n     * @return string\n     */\n    public function getRecallerName()\n    {\n        return 'remember_'.$this->name.'_'.sha1(static::class);\n    }\n\n    /**\n     * Determine if the user was authenticated via \"remember me\" cookie.\n     *\n     * @return bool\n     */\n    public function viaRemember()\n    {\n        return $this->viaRemember;\n    }\n\n    /**\n     * Get the number of minutes the remember me cookie should be valid for.\n     *\n     * @return int\n     */\n    protected function getRememberDuration()\n    {\n        return $this->rememberDuration;\n    }\n\n    /**\n     * Set the number of minutes the remember me cookie should be valid for.\n     *\n     * @param  int  $minutes\n     * @return $this\n     */\n    public function setRememberDuration($minutes)\n    {\n        $this->rememberDuration = $minutes;\n\n        return $this;\n    }\n\n    /**\n     * Get the cookie creator instance used by the guard.\n     *\n     * @return \\Illuminate\\Contracts\\Cookie\\QueueingFactory\n     *\n     * @throws \\RuntimeException\n     */\n    public function getCookieJar()\n    {\n        if (! isset($this->cookie)) {\n            throw new RuntimeException('Cookie jar has not been set.');\n        }\n\n        return $this->cookie;\n    }\n\n    /**\n     * Set the cookie creator instance used by the guard.\n     *\n     * @param  \\Illuminate\\Contracts\\Cookie\\QueueingFactory  $cookie\n     * @return void\n     */\n    public function setCookieJar(CookieJar $cookie)\n    {\n        $this->cookie = $cookie;\n    }\n\n    /**\n     * Get the event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    public function getDispatcher()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Set the event dispatcher instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return void\n     */\n    public function setDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Get the session store used by the guard.\n     *\n     * @return \\Illuminate\\Contracts\\Session\\Session\n     */\n    public function getSession()\n    {\n        return $this->session;\n    }\n\n    /**\n     * Return the currently cached user.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function getUser()\n    {\n        return $this->user;\n    }\n\n    /**\n     * Set the current user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return $this\n     */\n    public function setUser(AuthenticatableContract $user)\n    {\n        $this->user = $user;\n\n        $this->loggedOut = false;\n\n        $this->fireAuthenticatedEvent($user);\n\n        return $this;\n    }\n\n    /**\n     * Get the current request instance.\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\Request\n     */\n    public function getRequest()\n    {\n        return $this->request ?: Request::createFromGlobals();\n    }\n\n    /**\n     * Set the current request instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @return $this\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n\n        return $this;\n    }\n\n    /**\n     * Get the timebox instance used by the guard.\n     *\n     * @return \\Illuminate\\Support\\Timebox\n     */\n    public function getTimebox()\n    {\n        return $this->timebox;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/TokenGuard.php",
    "content": "<?php\n\nnamespace Illuminate\\Auth;\n\nuse Illuminate\\Contracts\\Auth\\Guard;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass TokenGuard implements Guard\n{\n    use GuardHelpers, Macroable;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * The name of the query string item from the request containing the API token.\n     *\n     * @var string\n     */\n    protected $inputKey;\n\n    /**\n     * The name of the token \"column\" in persistent storage.\n     *\n     * @var string\n     */\n    protected $storageKey;\n\n    /**\n     * Indicates if the API token is hashed in storage.\n     *\n     * @var bool\n     */\n    protected $hash = false;\n\n    /**\n     * Create a new authentication guard.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\UserProvider  $provider\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $inputKey\n     * @param  string  $storageKey\n     * @param  bool  $hash\n     */\n    public function __construct(\n        UserProvider $provider,\n        Request $request,\n        $inputKey = 'api_token',\n        $storageKey = 'api_token',\n        $hash = false,\n    ) {\n        $this->hash = $hash;\n        $this->request = $request;\n        $this->provider = $provider;\n        $this->inputKey = $inputKey;\n        $this->storageKey = $storageKey;\n    }\n\n    /**\n     * Get the currently authenticated user.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function user()\n    {\n        // If we've already retrieved the user for the current request we can just\n        // return it back immediately. We do not want to fetch the user data on\n        // every call to this method because that would be tremendously slow.\n        if (! is_null($this->user)) {\n            return $this->user;\n        }\n\n        $user = null;\n\n        $token = $this->getTokenForRequest();\n\n        if (! empty($token)) {\n            $user = $this->provider->retrieveByCredentials([\n                $this->storageKey => $this->hash ? hash('sha256', $token) : $token,\n            ]);\n        }\n\n        return $this->user = $user;\n    }\n\n    /**\n     * Get the token for the current request.\n     *\n     * @return string|null\n     */\n    public function getTokenForRequest()\n    {\n        return $this->request->query($this->inputKey)\n            ?: $this->request->input($this->inputKey)\n            ?: $this->request->bearerToken()\n            ?: $this->request->getPassword();\n    }\n\n    /**\n     * Validate a user's credentials.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validate(array $credentials = [])\n    {\n        if (empty($credentials[$this->inputKey])) {\n            return false;\n        }\n\n        $credentials = [$this->storageKey => $credentials[$this->inputKey]];\n\n        return (bool) $this->provider->retrieveByCredentials($credentials);\n    }\n\n    /**\n     * Set the current request instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return $this\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Auth/composer.json",
    "content": "{\n    \"name\": \"illuminate/auth\",\n    \"description\": \"The Illuminate Auth package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-hash\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/http\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/queue\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"illuminate/console\": \"Required to use the auth:clear-resets command (^13.0).\",\n        \"illuminate/queue\": \"Required to fire login / logout events (^13.0).\",\n        \"illuminate/session\": \"Required to use the session based guard (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Auth\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/AnonymousEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Foundation\\Events\\Dispatchable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nclass AnonymousEvent implements ShouldBroadcast\n{\n    use Dispatchable, InteractsWithBroadcasting, InteractsWithSockets;\n\n    /**\n     * The connection the event should be broadcast on.\n     */\n    protected ?string $connection = null;\n\n    /**\n     * The name the event should be broadcast as.\n     */\n    protected ?string $name = null;\n\n    /**\n     * The payload the event should be broadcast with.\n     */\n    protected array $payload = [];\n\n    /**\n     * Should the broadcast include the current user.\n     */\n    protected bool $includeCurrentUser = true;\n\n    /**\n     * Indicates if the event should be broadcast synchronously.\n     */\n    protected bool $shouldBroadcastNow = false;\n\n    /**\n     * Create a new anonymous broadcastable event instance.\n     */\n    public function __construct(protected Channel|array|string $channels)\n    {\n        $this->channels = Arr::wrap($channels);\n    }\n\n    /**\n     * Set the connection the event should be broadcast on.\n     */\n    public function via(string $connection): static\n    {\n        $this->connection = $connection;\n\n        return $this;\n    }\n\n    /**\n     * Set the name the event should be broadcast as.\n     */\n    public function as(string $name): static\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Set the payload the event should be broadcast with.\n     */\n    public function with(Arrayable|array $payload): static\n    {\n        $this->payload = $payload instanceof Arrayable\n            ? $payload->toArray()\n            : (new Collection($payload))->map(\n                fn ($p) => $p instanceof Arrayable ? $p->toArray() : $p\n            )->all();\n\n        return $this;\n    }\n\n    /**\n     * Broadcast the event to everyone except the current user.\n     */\n    public function toOthers(): static\n    {\n        $this->includeCurrentUser = false;\n\n        return $this;\n    }\n\n    /**\n     * Broadcast the event.\n     */\n    public function sendNow(): void\n    {\n        $this->shouldBroadcastNow = true;\n\n        $this->send();\n    }\n\n    /**\n     * Broadcast the event.\n     */\n    public function send(): void\n    {\n        $broadcast = broadcast($this)->via($this->connection);\n\n        if (! $this->includeCurrentUser) {\n            $broadcast->toOthers();\n        }\n    }\n\n    /**\n     * Get the name the event should broadcast as.\n     */\n    public function broadcastAs(): string\n    {\n        return $this->name ?: class_basename($this);\n    }\n\n    /**\n     * Get the payload the event should broadcast with.\n     *\n     * @return array<string, mixed>\n     */\n    public function broadcastWith(): array\n    {\n        return $this->payload;\n    }\n\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]|string[]|string\n     */\n    public function broadcastOn(): Channel|array\n    {\n        return $this->channels;\n    }\n\n    /**\n     * Determine if the event should be broadcast synchronously.\n     */\n    public function shouldBroadcastNow(): bool\n    {\n        return $this->shouldBroadcastNow;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/BroadcastController.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Support\\Facades\\Broadcast;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass BroadcastController extends Controller\n{\n    /**\n     * Authenticate the request for channel access.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function authenticate(Request $request)\n    {\n        if ($request->hasSession()) {\n            $request->session()->reflash();\n        }\n\n        return Broadcast::auth($request);\n    }\n\n    /**\n     * Authenticate the current user.\n     *\n     * See: https://pusher.com/docs/channels/server_api/authenticating-users/#user-authentication.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|null\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    public function authenticateUser(Request $request)\n    {\n        if ($request->hasSession()) {\n            $request->session()->reflash();\n        }\n\n        return Broadcast::resolveAuthenticatedUser($request)\n            ?? throw new AccessDeniedHttpException;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/BroadcastEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastingFactory;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Queue\\Attributes\\Backoff;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\Attributes\\MaxExceptions;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\Attributes\\Timeout;\nuse Illuminate\\Queue\\Attributes\\Tries;\nuse Illuminate\\Support\\Arr;\nuse ReflectionClass;\nuse ReflectionProperty;\nuse Throwable;\n\nclass BroadcastEvent implements ShouldQueue\n{\n    use Queueable, ReadsQueueAttributes;\n\n    /**\n     * The event instance.\n     *\n     * @var mixed\n     */\n    public $event;\n\n    /**\n     * The number of times the job may be attempted.\n     *\n     * @var int\n     */\n    public $tries;\n\n    /**\n     * The number of seconds the job can run before timing out.\n     *\n     * @var int\n     */\n    public $timeout;\n\n    /**\n     * The number of seconds to wait before retrying the job when encountering an uncaught exception.\n     *\n     * @var int\n     */\n    public $backoff;\n\n    /**\n     * The maximum number of unhandled exceptions to allow before failing.\n     *\n     * @var int\n     */\n    public $maxExceptions;\n\n    /**\n     * Delete the job if its models no longer exist.\n     *\n     * @var bool\n     */\n    public $deleteWhenMissingModels = true;\n\n    /**\n     * Create a new job handler instance.\n     *\n     * @param  mixed  $event\n     */\n    public function __construct($event)\n    {\n        $this->event = $event;\n        $this->tries = $this->getAttributeValue($event, Tries::class, 'tries');\n        $this->timeout = $this->getAttributeValue($event, Timeout::class, 'timeout');\n        $this->backoff = $this->getAttributeValue($event, Backoff::class, 'backoff');\n        $this->afterCommit = property_exists($event, 'afterCommit') ? $event->afterCommit : null;\n        $this->maxExceptions = $this->getAttributeValue($event, MaxExceptions::class, 'maxExceptions');\n        $this->deleteWhenMissingModels = $this->getAttributeValue($event, DeleteWhenMissingModels::class, 'deleteWhenMissingModels');\n    }\n\n    /**\n     * Handle the queued job.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\Factory  $manager\n     * @return void\n     */\n    public function handle(BroadcastingFactory $manager)\n    {\n        $name = method_exists($this->event, 'broadcastAs')\n            ? $this->event->broadcastAs()\n            : get_class($this->event);\n\n        $channels = Arr::wrap($this->event->broadcastOn());\n\n        if (empty($channels)) {\n            return;\n        }\n\n        $connections = method_exists($this->event, 'broadcastConnections')\n            ? $this->event->broadcastConnections()\n            : [null];\n\n        $payload = $this->getPayloadFromEvent($this->event);\n\n        foreach ($connections as $connection) {\n            $manager->connection($connection)->broadcast(\n                $this->getConnectionChannels($channels, $connection),\n                $name,\n                $this->getConnectionPayload($payload, $connection)\n            );\n        }\n    }\n\n    /**\n     * Get the payload for the given event.\n     *\n     * @param  mixed  $event\n     * @return array\n     */\n    protected function getPayloadFromEvent($event)\n    {\n        if (method_exists($event, 'broadcastWith') &&\n            ! is_null($payload = $event->broadcastWith())) {\n            return array_merge($payload, ['socket' => data_get($event, 'socket')]);\n        }\n\n        $payload = [];\n\n        foreach ((new ReflectionClass($event))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {\n            $payload[$property->getName()] = $this->formatProperty($property->getValue($event));\n        }\n\n        unset($payload['broadcastQueue']);\n\n        return $payload;\n    }\n\n    /**\n     * Format the given value for a property.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function formatProperty($value)\n    {\n        if ($value instanceof Arrayable) {\n            return $value->toArray();\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the channels for the given connection.\n     *\n     * @param  array  $channels\n     * @param  string|null  $connection\n     * @return array\n     */\n    protected function getConnectionChannels($channels, $connection)\n    {\n        return is_array($channels[$connection ?? ''] ?? null)\n            ? $channels[$connection ?? '']\n            : $channels;\n    }\n\n    /**\n     * Get the payload for the given connection.\n     *\n     * @param  array  $payload\n     * @param  string|null  $connection\n     * @return array\n     */\n    protected function getConnectionPayload($payload, $connection)\n    {\n        $connectionPayload = is_array($payload[$connection ?? ''] ?? null)\n            ? $payload[$connection ?? '']\n            : $payload;\n\n        if (isset($payload['socket'])) {\n            $connectionPayload['socket'] = $payload['socket'];\n        }\n\n        return $connectionPayload;\n    }\n\n    /**\n     * Get the middleware for the underlying event.\n     *\n     * @return array<int, object>\n     */\n    public function middleware(): array\n    {\n        if (! method_exists($this->event, 'middleware')) {\n            return [];\n        }\n\n        return $this->event->middleware();\n    }\n\n    /**\n     * Handle a job failure.\n     *\n     * @param  \\Throwable|null  $e\n     * @return void\n     */\n    public function failed(?Throwable $e = null): void\n    {\n        if (! method_exists($this->event, 'failed')) {\n            return;\n        }\n\n        $this->event->failed($e);\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        return get_class($this->event);\n    }\n\n    /**\n     * Prepare the instance for cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->event = clone $this->event;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/BroadcastException.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse RuntimeException;\n\nclass BroadcastException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/BroadcastManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Ably\\AblyRest;\nuse Closure;\nuse GuzzleHttp\\Client as GuzzleClient;\nuse Illuminate\\Broadcasting\\Broadcasters\\AblyBroadcaster;\nuse Illuminate\\Broadcasting\\Broadcasters\\LogBroadcaster;\nuse Illuminate\\Broadcasting\\Broadcasters\\NullBroadcaster;\nuse Illuminate\\Broadcasting\\Broadcasters\\PusherBroadcaster;\nuse Illuminate\\Broadcasting\\Broadcasters\\RedisBroadcaster;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as FactoryContract;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldRescue;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcherContract;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Foundation\\CachesRoutes;\nuse Illuminate\\Queue\\Attributes\\Connection as ConnectionAttribute;\nuse Illuminate\\Queue\\Attributes\\Queue as QueueAttribute;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Support\\Queue\\Concerns\\ResolvesQueueRoutes;\nuse InvalidArgumentException;\nuse Psr\\Log\\LoggerInterface;\nuse Pusher\\Pusher;\nuse RuntimeException;\nuse Throwable;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n */\nclass BroadcastManager implements FactoryContract\n{\n    use ReadsQueueAttributes, ResolvesQueueRoutes;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $app;\n\n    /**\n     * The array of resolved broadcast drivers.\n     *\n     * @var array\n     */\n    protected $drivers = [];\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * Create a new manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Register the routes for handling broadcast channel authentication and sockets.\n     *\n     * @param  array|null  $attributes\n     * @return void\n     */\n    public function routes(?array $attributes = null)\n    {\n        if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) {\n            return;\n        }\n\n        $attributes = $attributes ?: ['middleware' => ['web']];\n\n        $this->app['router']->group($attributes, function ($router) {\n            $router->match(\n                ['get', 'post'], '/broadcasting/auth',\n                '\\\\'.BroadcastController::class.'@authenticate'\n            )->withoutMiddleware([\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery::class]);\n        });\n    }\n\n    /**\n     * Register the routes for handling broadcast user authentication.\n     *\n     * @param  array|null  $attributes\n     * @return void\n     */\n    public function userRoutes(?array $attributes = null)\n    {\n        if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) {\n            return;\n        }\n\n        $attributes = $attributes ?: ['middleware' => ['web']];\n\n        $this->app['router']->group($attributes, function ($router) {\n            $router->match(\n                ['get', 'post'], '/broadcasting/user-auth',\n                '\\\\'.BroadcastController::class.'@authenticateUser'\n            )->withoutMiddleware([\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery::class]);\n        });\n    }\n\n    /**\n     * Register the routes for handling broadcast authentication and sockets.\n     *\n     * Alias of \"routes\" method.\n     *\n     * @param  array|null  $attributes\n     * @return void\n     */\n    public function channelRoutes(?array $attributes = null)\n    {\n        $this->routes($attributes);\n    }\n\n    /**\n     * Get the socket ID for the given request.\n     *\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return string|null\n     */\n    public function socket($request = null)\n    {\n        if (! $request && ! $this->app->bound('request')) {\n            return;\n        }\n\n        $request = $request ?: $this->app['request'];\n\n        return $request->header('X-Socket-ID');\n    }\n\n    /**\n     * Begin sending an anonymous broadcast to the given channels.\n     */\n    public function on(Channel|string|array $channels): AnonymousEvent\n    {\n        return new AnonymousEvent($channels);\n    }\n\n    /**\n     * Begin sending an anonymous broadcast to the given private channels.\n     */\n    public function private(string $channel): AnonymousEvent\n    {\n        return $this->on(new PrivateChannel($channel));\n    }\n\n    /**\n     * Begin sending an anonymous broadcast to the given presence channels.\n     */\n    public function presence(string $channel): AnonymousEvent\n    {\n        return $this->on(new PresenceChannel($channel));\n    }\n\n    /**\n     * Begin broadcasting an event.\n     *\n     * @param  mixed  $event\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function event($event = null)\n    {\n        return new PendingBroadcast($this->app->make('events'), $event);\n    }\n\n    /**\n     * Queue the given event for broadcast.\n     *\n     * @param  mixed  $event\n     * @return void\n     */\n    public function queue($event)\n    {\n        if ($event instanceof ShouldBroadcastNow ||\n            (is_object($event) &&\n             method_exists($event, 'shouldBroadcastNow') &&\n             $event->shouldBroadcastNow())) {\n            $dispatch = fn () => $this->app->make(BusDispatcherContract::class)\n                ->dispatchNow(new BroadcastEvent(clone $event));\n\n            return $event instanceof ShouldRescue\n                ? $this->rescue($dispatch)\n                : $dispatch();\n        }\n\n        $queue = match (true) {\n            method_exists($event, 'broadcastQueue') => $event->broadcastQueue(),\n            isset($event->broadcastQueue) => $event->broadcastQueue,\n            isset($event->queue) => $event->queue,\n            default => null,\n        };\n\n        if (is_null($queue)) {\n            $queue = $this->getAttributeValue($event, QueueAttribute::class, 'queue')\n                ?? $this->resolveQueueFromQueueRoute($event)\n                ?? null;\n        }\n\n        $broadcastEvent = new BroadcastEvent(clone $event);\n\n        if ($event instanceof ShouldBeUnique) {\n            $broadcastEvent = new UniqueBroadcastEvent(clone $event);\n\n            if ($this->mustBeUniqueAndCannotAcquireLock($broadcastEvent)) {\n                return;\n            }\n        }\n\n        $push = fn () => $this->app->make('queue')\n            ->connection(\n                $event->connection\n                    ?? $this->getAttributeValue($event, ConnectionAttribute::class, 'connection')\n                    ?? $this->resolveConnectionFromQueueRoute($event)\n                    ?? null\n            )\n            ->pushOn($queue, $broadcastEvent);\n\n        $event instanceof ShouldRescue\n            ? $this->rescue($push)\n            : $push();\n    }\n\n    /**\n     * Determine if the broadcastable event must be unique and determine if we can acquire the necessary lock.\n     *\n     * @param  mixed  $event\n     * @return bool\n     */\n    protected function mustBeUniqueAndCannotAcquireLock($event)\n    {\n        return ! (new UniqueLock(\n            method_exists($event, 'uniqueVia')\n                ? $event->uniqueVia()\n                : $this->app->make(Cache::class)\n        ))->acquire($event);\n    }\n\n    /**\n     * Get a driver instance.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function connection($name = null)\n    {\n        return $this->driver($name);\n    }\n\n    /**\n     * Get a driver instance.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function driver($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        return $this->drivers[$name] = $this->get($name);\n    }\n\n    /**\n     * Attempt to get the connection from the local cache.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function get($name)\n    {\n        return $this->drivers[$name] ?? $this->resolve($name);\n    }\n\n    /**\n     * Resolve the given broadcaster.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\RuntimeException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Broadcast connection [{$name}] is not defined.\");\n        }\n\n        if (isset($this->customCreators[$config['driver']])) {\n            return $this->callCustomCreator($config);\n        }\n\n        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';\n\n        if (! method_exists($this, $driverMethod)) {\n            throw new InvalidArgumentException(\"Driver [{$config['driver']}] is not supported.\");\n        }\n\n        try {\n            return $this->{$driverMethod}($config);\n        } catch (Throwable $e) {\n            throw new RuntimeException(\"Failed to create broadcaster for connection \\\"{$name}\\\" with error: {$e->getMessage()}.\", 0, $e);\n        }\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  array  $config\n     * @return mixed\n     */\n    protected function callCustomCreator(array $config)\n    {\n        return $this->customCreators[$config['driver']]($this->app, $config);\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createReverbDriver(array $config)\n    {\n        return $this->createPusherDriver($config);\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createPusherDriver(array $config)\n    {\n        return new PusherBroadcaster($this->pusher($config), $config['jsonp'] ?? false);\n    }\n\n    /**\n     * Get a Pusher instance for the given configuration.\n     *\n     * @param  array  $config\n     * @return \\Pusher\\Pusher\n     */\n    public function pusher(array $config)\n    {\n        $guzzleClient = new GuzzleClient(\n            array_merge(\n                [\n                    'connect_timeout' => 10,\n                    'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,\n                    'timeout' => 30,\n                ],\n                $config['client_options'] ?? [],\n            ),\n        );\n\n        $pusher = new Pusher(\n            $config['key'],\n            $config['secret'],\n            $config['app_id'],\n            $config['options'] ?? [],\n            $guzzleClient,\n        );\n\n        if ($config['log'] ?? false) {\n            $pusher->setLogger($this->app->make(LoggerInterface::class));\n        }\n\n        return $pusher;\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createAblyDriver(array $config)\n    {\n        return new AblyBroadcaster($this->ably($config));\n    }\n\n    /**\n     * Get an Ably instance for the given configuration.\n     *\n     * @param  array  $config\n     * @return \\Ably\\AblyRest\n     */\n    public function ably(array $config)\n    {\n        return new AblyRest($config);\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createRedisDriver(array $config)\n    {\n        return new RedisBroadcaster(\n            $this->app->make('redis'), $config['connection'] ?? null,\n            $this->app['config']->get('database.redis.options.prefix', '')\n        );\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createLogDriver(array $config)\n    {\n        return new LogBroadcaster(\n            $this->app->make(LoggerInterface::class)\n        );\n    }\n\n    /**\n     * Create an instance of the driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    protected function createNullDriver(array $config)\n    {\n        return new NullBroadcaster;\n    }\n\n    /**\n     * Get the connection configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function getConfig($name)\n    {\n        if (! is_null($name) && $name !== 'null') {\n            return $this->app['config'][\"broadcasting.connections.{$name}\"];\n        }\n\n        return ['driver' => 'null'];\n    }\n\n    /**\n     * Get the default driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['broadcasting.default'] ?? 'null';\n    }\n\n    /**\n     * Set the default driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['broadcasting.default'] = $name;\n    }\n\n    /**\n     * Disconnect the given driver / connection and remove it from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name ??= $this->getDefaultDriver();\n\n        unset($this->drivers[$name]);\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback using \"rescue\" if possible.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    protected function rescue(Closure $callback)\n    {\n        if (function_exists('rescue')) {\n            return rescue($callback);\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Get the application instance used by the manager.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getApplication()\n    {\n        return $this->app;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Forget all of the resolved driver instances.\n     *\n     * @return $this\n     */\n    public function forgetDrivers()\n    {\n        $this->drivers = [];\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->driver()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/BroadcastServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Contracts\\Broadcasting\\Broadcaster as BroadcasterContract;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastingFactory;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass BroadcastServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton(BroadcastManager::class, fn ($app) => new BroadcastManager($app));\n\n        $this->app->singleton(BroadcasterContract::class, function ($app) {\n            return $app->make(BroadcastManager::class)->connection();\n        });\n\n        $this->app->alias(\n            BroadcastManager::class, BroadcastingFactory::class\n        );\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            BroadcastManager::class,\n            BroadcastingFactory::class,\n            BroadcasterContract::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/AblyBroadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Ably\\AblyRest;\nuse Ably\\Exceptions\\AblyException;\nuse Ably\\Models\\Message as AblyMessage;\nuse Illuminate\\Broadcasting\\BroadcastException;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\n/**\n * @author Matthew Hall (matthall28@gmail.com)\n * @author Taylor Otwell (taylor@laravel.com)\n */\nclass AblyBroadcaster extends Broadcaster\n{\n    /**\n     * The AblyRest SDK instance.\n     *\n     * @var \\Ably\\AblyRest\n     */\n    protected $ably;\n\n    /**\n     * Create a new broadcaster instance.\n     *\n     * @param  \\Ably\\AblyRest  $ably\n     */\n    public function __construct(AblyRest $ably)\n    {\n        $this->ably = $ably;\n    }\n\n    /**\n     * Authenticate the incoming request for a given channel.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    public function auth($request)\n    {\n        $channelName = $this->normalizeChannelName($request->channel_name);\n\n        if (empty($request->channel_name) ||\n            ($this->isGuardedChannel($request->channel_name) &&\n            ! $this->retrieveUser($request, $channelName))) {\n            throw new AccessDeniedHttpException;\n        }\n\n        return parent::verifyUserCanAccessChannel(\n            $request, $channelName\n        );\n    }\n\n    /**\n     * Return the valid authentication response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function validAuthenticationResponse($request, $result)\n    {\n        if (str_starts_with($request->channel_name, 'private')) {\n            $signature = $this->generateAblySignature(\n                $request->channel_name, $request->socket_id\n            );\n\n            return ['auth' => $this->getPublicToken().':'.$signature];\n        }\n\n        $channelName = $this->normalizeChannelName($request->channel_name);\n\n        $user = $this->retrieveUser($request, $channelName);\n\n        $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting')\n            ? $user->getAuthIdentifierForBroadcasting()\n            : $user->getAuthIdentifier();\n\n        $signature = $this->generateAblySignature(\n            $request->channel_name,\n            $request->socket_id,\n            $userData = array_filter([\n                'user_id' => (string) $broadcastIdentifier,\n                'user_info' => $result,\n            ])\n        );\n\n        return [\n            'auth' => $this->getPublicToken().':'.$signature,\n            'channel_data' => json_encode($userData),\n        ];\n    }\n\n    /**\n     * Generate the signature needed for Ably authentication headers.\n     *\n     * @param  string  $channelName\n     * @param  string  $socketId\n     * @param  array|null  $userData\n     * @return string\n     */\n    public function generateAblySignature($channelName, $socketId, $userData = null)\n    {\n        return hash_hmac(\n            'sha256',\n            sprintf('%s:%s%s', $socketId, $channelName, $userData ? ':'.json_encode($userData) : ''),\n            $this->getPrivateToken(),\n        );\n    }\n\n    /**\n     * Broadcast the given event.\n     *\n     * @param  array  $channels\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     *\n     * @throws \\Illuminate\\Broadcasting\\BroadcastException\n     */\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        try {\n            foreach ($this->formatChannels($channels) as $channel) {\n                $this->ably->channels->get($channel)->publish(\n                    $this->buildAblyMessage($event, $payload)\n                );\n            }\n        } catch (AblyException $e) {\n            throw new BroadcastException(\n                sprintf('Ably error: %s', $e->getMessage())\n            );\n        }\n    }\n\n    /**\n     * Build an Ably message object for broadcasting.\n     *\n     * @param  string  $event\n     * @param  array  $payload\n     * @return \\Ably\\Models\\Message\n     */\n    protected function buildAblyMessage($event, array $payload = [])\n    {\n        return tap(new AblyMessage, function ($message) use ($event, $payload) {\n            $message->name = $event;\n            $message->data = $payload;\n            $message->connectionKey = data_get($payload, 'socket');\n        });\n    }\n\n    /**\n     * Return true if the channel is protected by authentication.\n     *\n     * @param  string  $channel\n     * @return bool\n     */\n    public function isGuardedChannel($channel)\n    {\n        return Str::startsWith($channel, ['private-', 'presence-']);\n    }\n\n    /**\n     * Remove prefix from channel name.\n     *\n     * @param  string  $channel\n     * @return string\n     */\n    public function normalizeChannelName($channel)\n    {\n        if ($this->isGuardedChannel($channel)) {\n            return str_starts_with($channel, 'private-')\n                ? Str::replaceFirst('private-', '', $channel)\n                : Str::replaceFirst('presence-', '', $channel);\n        }\n\n        return $channel;\n    }\n\n    /**\n     * Format the channel array into an array of strings.\n     *\n     * @param  array  $channels\n     * @return array\n     */\n    protected function formatChannels(array $channels)\n    {\n        return array_map(function ($channel) {\n            $channel = (string) $channel;\n\n            if (Str::startsWith($channel, ['private-', 'presence-'])) {\n                return str_starts_with($channel, 'private-')\n                    ? Str::replaceFirst('private-', 'private:', $channel)\n                    : Str::replaceFirst('presence-', 'presence:', $channel);\n            }\n\n            return 'public:'.$channel;\n        }, $channels);\n    }\n\n    /**\n     * Get the public token value from the Ably key.\n     *\n     * @return string\n     */\n    protected function getPublicToken()\n    {\n        return Str::before($this->ably->options->key, ':');\n    }\n\n    /**\n     * Get the private token value from the Ably key.\n     *\n     * @return string\n     */\n    protected function getPrivateToken()\n    {\n        return Str::after($this->ably->options->key, ':');\n    }\n\n    /**\n     * Get the underlying Ably SDK instance.\n     *\n     * @return \\Ably\\AblyRest\n     */\n    public function getAbly()\n    {\n        return $this->ably;\n    }\n\n    /**\n     * Set the underlying Ably SDK instance.\n     *\n     * @param  \\Ably\\AblyRest  $ably\n     * @return void\n     */\n    public function setAbly($ably)\n    {\n        $this->ably = $ably;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Broadcasting\\Broadcaster as BroadcasterContract;\nuse Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel;\nuse Illuminate\\Contracts\\Routing\\BindingRegistrar;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Reflector;\nuse ReflectionClass;\nuse ReflectionFunction;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nabstract class Broadcaster implements BroadcasterContract\n{\n    /**\n     * The callback to resolve the authenticated user information.\n     *\n     * @var \\Closure|null\n     */\n    protected $authenticatedUserCallback = null;\n\n    /**\n     * The registered channel authenticators.\n     *\n     * @var array\n     */\n    protected $channels = [];\n\n    /**\n     * The registered channel options.\n     *\n     * @var array\n     */\n    protected $channelOptions = [];\n\n    /**\n     * The binding registrar instance.\n     *\n     * @var \\Illuminate\\Contracts\\Routing\\BindingRegistrar\n     */\n    protected $bindingRegistrar;\n\n    /**\n     * Resolve the authenticated user payload for the incoming connection request.\n     *\n     * See: https://pusher.com/docs/channels/library_auth_reference/auth-signatures/#user-authentication.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|null\n     */\n    public function resolveAuthenticatedUser($request)\n    {\n        if ($this->authenticatedUserCallback) {\n            return $this->authenticatedUserCallback->__invoke($request);\n        }\n    }\n\n    /**\n     * Register the user retrieval callback used to authenticate connections.\n     *\n     * See: https://pusher.com/docs/channels/library_auth_reference/auth-signatures/#user-authentication.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function resolveAuthenticatedUserUsing(Closure $callback)\n    {\n        $this->authenticatedUserCallback = $callback;\n    }\n\n    /**\n     * Register a channel authenticator.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|string  $channel\n     * @param  callable|string  $callback\n     * @param  array  $options\n     * @return $this\n     */\n    public function channel($channel, $callback, $options = [])\n    {\n        if ($channel instanceof HasBroadcastChannel) {\n            $channel = $channel->broadcastChannelRoute();\n        } elseif (is_string($channel) && class_exists($channel) && is_a($channel, HasBroadcastChannel::class, true)) {\n            $channel = (new $channel)->broadcastChannelRoute();\n        }\n\n        $this->channels[$channel] = $callback;\n\n        $this->channelOptions[$channel] = $options;\n\n        return $this;\n    }\n\n    /**\n     * Authenticate the incoming request for a given channel.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $channel\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    protected function verifyUserCanAccessChannel($request, $channel)\n    {\n        foreach ($this->channels as $pattern => $callback) {\n            if (! $this->channelNameMatchesPattern($channel, $pattern)) {\n                continue;\n            }\n\n            $parameters = $this->extractAuthParameters($pattern, $channel, $callback);\n\n            $handler = $this->normalizeChannelHandlerToCallable($callback);\n\n            $result = $handler($this->retrieveUser($request, $channel), ...$parameters);\n\n            if ($result === false) {\n                throw new AccessDeniedHttpException;\n            } elseif ($result) {\n                return $this->validAuthenticationResponse($request, $result);\n            }\n        }\n\n        throw new AccessDeniedHttpException;\n    }\n\n    /**\n     * Extract the parameters from the given pattern and channel.\n     *\n     * @param  string  $pattern\n     * @param  string  $channel\n     * @param  callable|string  $callback\n     * @return array\n     */\n    protected function extractAuthParameters($pattern, $channel, $callback)\n    {\n        $callbackParameters = $this->extractParameters($callback);\n\n        return (new Collection($this->extractChannelKeys($pattern, $channel)))\n            ->reject(fn ($value, $key) => is_numeric($key))\n            ->map(fn ($value, $key) => $this->resolveBinding($key, $value, $callbackParameters))\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Extracts the parameters out of what the user passed to handle the channel authentication.\n     *\n     * @param  callable|string  $callback\n     * @return \\ReflectionParameter[]\n     *\n     * @throws \\Exception\n     */\n    protected function extractParameters($callback)\n    {\n        if (is_callable($callback)) {\n            return (new ReflectionFunction($callback))->getParameters();\n        } elseif (is_string($callback)) {\n            return $this->extractParametersFromClass($callback);\n        }\n\n        throw new Exception('Given channel handler is an unknown type.');\n    }\n\n    /**\n     * Extracts the parameters out of a class channel's \"join\" method.\n     *\n     * @param  string  $callback\n     * @return \\ReflectionParameter[]\n     *\n     * @throws \\Exception\n     */\n    protected function extractParametersFromClass($callback)\n    {\n        $reflection = new ReflectionClass($callback);\n\n        if (! $reflection->hasMethod('join')) {\n            throw new Exception('Class based channel must define a \"join\" method.');\n        }\n\n        return $reflection->getMethod('join')->getParameters();\n    }\n\n    /**\n     * Extract the channel keys from the incoming channel name.\n     *\n     * @param  string  $pattern\n     * @param  string  $channel\n     * @return array\n     */\n    protected function extractChannelKeys($pattern, $channel)\n    {\n        preg_match('/^'.preg_replace('/\\{(.*?)\\}/', '(?<$1>[^\\.]+)', $pattern).'/', $channel, $keys);\n\n        return $keys;\n    }\n\n    /**\n     * Resolve the given parameter binding.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @param  array  $callbackParameters\n     * @return mixed\n     */\n    protected function resolveBinding($key, $value, $callbackParameters)\n    {\n        $newValue = $this->resolveExplicitBindingIfPossible($key, $value);\n\n        return $newValue === $value ? $this->resolveImplicitBindingIfPossible(\n            $key, $value, $callbackParameters\n        ) : $newValue;\n    }\n\n    /**\n     * Resolve an explicit parameter binding if applicable.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function resolveExplicitBindingIfPossible($key, $value)\n    {\n        $binder = $this->binder();\n\n        if ($binder && $binder->getBindingCallback($key)) {\n            return call_user_func($binder->getBindingCallback($key), $value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Resolve an implicit parameter binding if applicable.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $callbackParameters\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    protected function resolveImplicitBindingIfPossible($key, $value, $callbackParameters)\n    {\n        foreach ($callbackParameters as $parameter) {\n            if (! $this->isImplicitlyBindable($key, $parameter)) {\n                continue;\n            }\n\n            $className = Reflector::getParameterClassName($parameter);\n\n            if (is_null($model = (new $className)->resolveRouteBinding($value))) {\n                throw new AccessDeniedHttpException;\n            }\n\n            return $model;\n        }\n\n        return $value;\n    }\n\n    /**\n     * Determine if a given key and parameter is implicitly bindable.\n     *\n     * @param  string  $key\n     * @param  \\ReflectionParameter  $parameter\n     * @return bool\n     */\n    protected function isImplicitlyBindable($key, $parameter)\n    {\n        return $parameter->getName() === $key &&\n                        Reflector::isParameterSubclassOf($parameter, UrlRoutable::class);\n    }\n\n    /**\n     * Format the channel array into an array of strings.\n     *\n     * @param  array  $channels\n     * @return array\n     */\n    protected function formatChannels(array $channels)\n    {\n        return array_map(function ($channel) {\n            return (string) $channel;\n        }, $channels);\n    }\n\n    /**\n     * Get the model binding registrar instance.\n     *\n     * @return \\Illuminate\\Contracts\\Routing\\BindingRegistrar\n     */\n    protected function binder()\n    {\n        if (! $this->bindingRegistrar) {\n            $this->bindingRegistrar = Container::getInstance()->bound(BindingRegistrar::class)\n                ? Container::getInstance()->make(BindingRegistrar::class)\n                : null;\n        }\n\n        return $this->bindingRegistrar;\n    }\n\n    /**\n     * Normalize the given callback into a callable.\n     *\n     * @param  mixed  $callback\n     * @return callable\n     */\n    protected function normalizeChannelHandlerToCallable($callback)\n    {\n        return is_callable($callback) ? $callback : function (...$args) use ($callback) {\n            return Container::getInstance()\n                ->make($callback)\n                ->join(...$args);\n        };\n    }\n\n    /**\n     * Retrieve the authenticated user using the configured guard (if any).\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $channel\n     * @return mixed\n     */\n    protected function retrieveUser($request, $channel)\n    {\n        $options = $this->retrieveChannelOptions($channel);\n\n        $guards = $options['guards'] ?? null;\n\n        if (is_null($guards)) {\n            return $request->user();\n        }\n\n        foreach (Arr::wrap($guards) as $guard) {\n            if ($user = $request->user($guard)) {\n                return $user;\n            }\n        }\n    }\n\n    /**\n     * Retrieve options for a certain channel.\n     *\n     * @param  string  $channel\n     * @return array\n     */\n    protected function retrieveChannelOptions($channel)\n    {\n        foreach ($this->channelOptions as $pattern => $options) {\n            if (! $this->channelNameMatchesPattern($channel, $pattern)) {\n                continue;\n            }\n\n            return $options;\n        }\n\n        return [];\n    }\n\n    /**\n     * Check if the channel name from the request matches a pattern from registered channels.\n     *\n     * @param  string  $channel\n     * @param  string  $pattern\n     * @return bool\n     */\n    protected function channelNameMatchesPattern($channel, $pattern)\n    {\n        $pattern = str_replace('.', '\\.', $pattern);\n\n        return preg_match('/^'.preg_replace('/\\{(.*?)\\}/', '([^\\.]+)', $pattern).'$/', $channel);\n    }\n\n    /**\n     * Get all of the registered channels.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function getChannels()\n    {\n        return new Collection($this->channels);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Psr\\Log\\LoggerInterface;\n\nclass LogBroadcaster extends Broadcaster\n{\n    /**\n     * The logger implementation.\n     *\n     * @var \\Psr\\Log\\LoggerInterface\n     */\n    protected $logger;\n\n    /**\n     * Create a new broadcaster instance.\n     *\n     * @param  \\Psr\\Log\\LoggerInterface  $logger\n     */\n    public function __construct(LoggerInterface $logger)\n    {\n        $this->logger = $logger;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function auth($request)\n    {\n        //\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function validAuthenticationResponse($request, $result)\n    {\n        //\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        $channels = implode(', ', $this->formatChannels($channels));\n\n        $payload = json_encode($payload, JSON_PRETTY_PRINT);\n\n        $this->logger->info('Broadcasting ['.$event.'] on channels ['.$channels.'] with payload:'.PHP_EOL.$payload);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/NullBroadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nclass NullBroadcaster extends Broadcaster\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function auth($request)\n    {\n        //\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function validAuthenticationResponse($request, $result)\n    {\n        //\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Illuminate\\Broadcasting\\BroadcastException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Pusher\\ApiErrorException;\nuse Pusher\\Pusher;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass PusherBroadcaster extends Broadcaster\n{\n    use UsePusherChannelConventions;\n\n    /**\n     * The Pusher SDK instance.\n     *\n     * @var \\Pusher\\Pusher\n     */\n    protected $pusher;\n\n    /**\n     * Indicates if JSONP callbacks are allowed on authorization.\n     *\n     * @var bool\n     */\n    protected $allowJsonp = false;\n\n    /**\n     * Create a new broadcaster instance.\n     *\n     * @param  \\Pusher\\Pusher  $pusher\n     */\n    public function __construct(Pusher $pusher, bool $allowJsonp = false)\n    {\n        $this->pusher = $pusher;\n        $this->allowJsonp = $allowJsonp;\n    }\n\n    /**\n     * Resolve the authenticated user payload for an incoming connection request.\n     *\n     * See: https://pusher.com/docs/channels/library_auth_reference/auth-signatures/#user-authentication\n     * See: https://pusher.com/docs/channels/server_api/authenticating-users/#response\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|null\n     */\n    public function resolveAuthenticatedUser($request)\n    {\n        if (! $user = parent::resolveAuthenticatedUser($request)) {\n            return;\n        }\n\n        if (method_exists($this->pusher, 'authenticateUser')) {\n            return $this->pusher->authenticateUser($request->socket_id, $user);\n        }\n\n        $settings = $this->pusher->getSettings();\n        $encodedUser = json_encode($user);\n        $decodedString = \"{$request->socket_id}::user::{$encodedUser}\";\n\n        $auth = $settings['auth_key'].':'.hash_hmac(\n            'sha256', $decodedString, $settings['secret']\n        );\n\n        return [\n            'auth' => $auth,\n            'user_data' => $encodedUser,\n        ];\n    }\n\n    /**\n     * Authenticate the incoming request for a given channel.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    public function auth($request)\n    {\n        $channelName = $this->normalizeChannelName($request->channel_name);\n\n        if (empty($request->channel_name) ||\n            ($this->isGuardedChannel($request->channel_name) &&\n            ! $this->retrieveUser($request, $channelName))) {\n            throw new AccessDeniedHttpException;\n        }\n\n        return parent::verifyUserCanAccessChannel(\n            $request, $channelName\n        );\n    }\n\n    /**\n     * Return the valid authentication response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function validAuthenticationResponse($request, $result)\n    {\n        if (str_starts_with($request->channel_name, 'private')) {\n            return $this->decodePusherResponse(\n                $request,\n                method_exists($this->pusher, 'authorizeChannel')\n                    ? $this->pusher->authorizeChannel($request->channel_name, $request->socket_id)\n                    : $this->pusher->socket_auth($request->channel_name, $request->socket_id)\n            );\n        }\n\n        $channelName = $this->normalizeChannelName($request->channel_name);\n\n        $user = $this->retrieveUser($request, $channelName);\n\n        $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting')\n            ? $user->getAuthIdentifierForBroadcasting()\n            : $user->getAuthIdentifier();\n\n        return $this->decodePusherResponse(\n            $request,\n            method_exists($this->pusher, 'authorizePresenceChannel')\n                ? $this->pusher->authorizePresenceChannel($request->channel_name, $request->socket_id, $broadcastIdentifier, $result)\n                : $this->pusher->presence_auth($request->channel_name, $request->socket_id, $broadcastIdentifier, $result)\n        );\n    }\n\n    /**\n     * Decode the given Pusher response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  mixed  $response\n     * @return array\n     */\n    protected function decodePusherResponse($request, $response)\n    {\n        if (! $request->input('callback', false) || ! $this->allowJsonp) {\n            return json_decode($response, true);\n        }\n\n        return response()->json(json_decode($response, true))\n            ->withCallback($request->callback);\n    }\n\n    /**\n     * Broadcast the given event.\n     *\n     * @param  array  $channels\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     *\n     * @throws \\Illuminate\\Broadcasting\\BroadcastException\n     */\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        $socket = Arr::pull($payload, 'socket');\n\n        $parameters = $socket !== null ? ['socket_id' => $socket] : [];\n\n        $channels = new Collection($this->formatChannels($channels));\n\n        try {\n            $channels->chunk(100)->each(function ($channels) use ($event, $payload, $parameters) {\n                $this->pusher->trigger($channels->toArray(), $event, $payload, $parameters);\n            });\n        } catch (ApiErrorException $e) {\n            throw new BroadcastException(\n                sprintf('Pusher error: %s.', $e->getMessage())\n            );\n        }\n    }\n\n    /**\n     * Get the Pusher SDK instance.\n     *\n     * @return \\Pusher\\Pusher\n     */\n    public function getPusher()\n    {\n        return $this->pusher;\n    }\n\n    /**\n     * Set the Pusher SDK instance.\n     *\n     * @param  \\Pusher\\Pusher  $pusher\n     * @return void\n     */\n    public function setPusher($pusher)\n    {\n        $this->pusher = $pusher;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Illuminate\\Broadcasting\\BroadcastException;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisConnection;\nuse Illuminate\\Support\\Arr;\nuse Predis\\Connection\\Cluster\\RedisCluster;\nuse Predis\\Connection\\ConnectionException;\nuse RedisException;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass RedisBroadcaster extends Broadcaster\n{\n    use UsePusherChannelConventions;\n\n    /**\n     * The Redis instance.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    protected $redis;\n\n    /**\n     * The Redis connection to use for broadcasting.\n     *\n     * @var string|null\n     */\n    protected $connection = null;\n\n    /**\n     * The Redis key prefix.\n     *\n     * @var string\n     */\n    protected $prefix = '';\n\n    /**\n     * Create a new broadcaster instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Redis\\Factory  $redis\n     * @param  string|null  $connection\n     * @param  string  $prefix\n     */\n    public function __construct(Redis $redis, $connection = null, $prefix = '')\n    {\n        $this->redis = $redis;\n        $this->prefix = $prefix;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Authenticate the incoming request for a given channel.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException\n     */\n    public function auth($request)\n    {\n        $channelName = $this->normalizeChannelName(\n            str_replace($this->prefix, '', $request->channel_name)\n        );\n\n        if (empty($request->channel_name) ||\n            ($this->isGuardedChannel($request->channel_name) &&\n            ! $this->retrieveUser($request, $channelName))) {\n            throw new AccessDeniedHttpException;\n        }\n\n        return parent::verifyUserCanAccessChannel(\n            $request, $channelName\n        );\n    }\n\n    /**\n     * Return the valid authentication response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function validAuthenticationResponse($request, $result)\n    {\n        if (is_bool($result)) {\n            return json_encode($result);\n        }\n\n        $channelName = $this->normalizeChannelName($request->channel_name);\n\n        $user = $this->retrieveUser($request, $channelName);\n\n        $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting')\n            ? $user->getAuthIdentifierForBroadcasting()\n            : $user->getAuthIdentifier();\n\n        return json_encode(['channel_data' => [\n            'user_id' => $broadcastIdentifier,\n            'user_info' => $result,\n        ]]);\n    }\n\n    /**\n     * Broadcast the given event.\n     *\n     * @param  array  $channels\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     *\n     * @throws \\Illuminate\\Broadcasting\\BroadcastException\n     */\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        if (empty($channels)) {\n            return;\n        }\n\n        $connection = $this->redis->connection($this->connection);\n\n        $payload = json_encode([\n            'event' => $event,\n            'data' => $payload,\n            'socket' => Arr::pull($payload, 'socket'),\n        ]);\n\n        try {\n            if ($connection instanceof PhpRedisClusterConnection) {\n                foreach ($channels as $channel) {\n                    $connection->publish($channel, $payload);\n                }\n            } elseif ($connection instanceof PredisClusterConnection &&\n                $connection->client()->getConnection() instanceof RedisCluster) {\n                $randomClusterNodeConnection = new PredisConnection(\n                    $connection->client()->getClientBy('slot', mt_rand(0, 16383))\n                );\n\n                if ($events = $connection->getEventDispatcher()) {\n                    $randomClusterNodeConnection->setEventDispatcher($events);\n                }\n\n                $randomClusterNodeConnection->eval(\n                    $this->broadcastMultipleChannelsScript(),\n                    0, $payload, ...$this->formatChannels($channels)\n                );\n            } else {\n                $connection->eval(\n                    $this->broadcastMultipleChannelsScript(),\n                    0, $payload, ...$this->formatChannels($channels)\n                );\n            }\n        } catch (ConnectionException|RedisException $e) {\n            throw new BroadcastException(\n                sprintf('Redis error: %s.', $e->getMessage())\n            );\n        }\n    }\n\n    /**\n     * Get the Lua script for broadcasting to multiple channels.\n     *\n     * ARGV[1] - The payload\n     * ARGV[2...] - The channels\n     *\n     * @return string\n     */\n    protected function broadcastMultipleChannelsScript()\n    {\n        return <<<'LUA'\nfor i = 2, #ARGV do\n  redis.call('publish', ARGV[i], ARGV[1])\nend\nLUA;\n    }\n\n    /**\n     * Format the channel array into an array of strings.\n     *\n     * @param  array  $channels\n     * @return array\n     */\n    protected function formatChannels(array $channels)\n    {\n        return array_map(function ($channel) {\n            return $this->prefix.$channel;\n        }, parent::formatChannels($channels));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Broadcasters/UsePusherChannelConventions.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting\\Broadcasters;\n\nuse Illuminate\\Support\\Str;\n\ntrait UsePusherChannelConventions\n{\n    /**\n     * Return true if the channel is protected by authentication.\n     *\n     * @param  string  $channel\n     * @return bool\n     */\n    public function isGuardedChannel($channel)\n    {\n        return Str::startsWith($channel, ['private-', 'presence-']);\n    }\n\n    /**\n     * Remove prefix from channel name.\n     *\n     * @param  string  $channel\n     * @return string\n     */\n    public function normalizeChannelName($channel)\n    {\n        foreach (['private-encrypted-', 'private-', 'presence-'] as $prefix) {\n            if (Str::startsWith($channel, $prefix)) {\n                return Str::replaceFirst($prefix, '', $channel);\n            }\n        }\n\n        return $channel;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/Channel.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel;\nuse Stringable;\n\nclass Channel implements Stringable\n{\n    /**\n     * The channel's name.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * Create a new channel instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|string  $name\n     */\n    public function __construct($name)\n    {\n        $this->name = $name instanceof HasBroadcastChannel ? $name->broadcastChannel() : $name;\n    }\n\n    /**\n     * Convert the channel instance to a string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/EncryptedPrivateChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nclass EncryptedPrivateChannel extends Channel\n{\n    /**\n     * Create a new channel instance.\n     *\n     * @param  string  $name\n     */\n    public function __construct($name)\n    {\n        parent::__construct('private-encrypted-'.$name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/FakePendingBroadcast.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nclass FakePendingBroadcast extends PendingBroadcast\n{\n    /**\n     * Create a new pending broadcast instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Broadcast the event using a specific broadcaster.\n     *\n     * @param  string|null  $connection\n     * @return $this\n     */\n    public function via($connection = null)\n    {\n        return $this;\n    }\n\n    /**\n     * Broadcast the event to everyone except the current user.\n     *\n     * @return $this\n     */\n    public function toOthers()\n    {\n        return $this;\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/InteractsWithBroadcasting.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Support\\Arr;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait InteractsWithBroadcasting\n{\n    /**\n     * The broadcaster connection to use to broadcast the event.\n     *\n     * @var array\n     */\n    protected $broadcastConnection = [null];\n\n    /**\n     * Broadcast the event using a specific broadcaster.\n     *\n     * @param  \\UnitEnum|array|string|null  $connection\n     * @return $this\n     */\n    public function broadcastVia($connection = null)\n    {\n        $connection = enum_value($connection);\n\n        $this->broadcastConnection = is_null($connection)\n            ? [null]\n            : Arr::wrap($connection);\n\n        return $this;\n    }\n\n    /**\n     * Get the broadcaster connections the event should be broadcast on.\n     *\n     * @return array\n     */\n    public function broadcastConnections()\n    {\n        return $this->broadcastConnection;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/InteractsWithSockets.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Support\\Facades\\Broadcast;\n\ntrait InteractsWithSockets\n{\n    /**\n     * The socket ID for the user that raised the event.\n     *\n     * @var string|null\n     */\n    public $socket;\n\n    /**\n     * Exclude the current user from receiving the broadcast.\n     *\n     * @return $this\n     */\n    public function dontBroadcastToCurrentUser()\n    {\n        $this->socket = Broadcast::socket();\n\n        return $this;\n    }\n\n    /**\n     * Broadcast the event to everyone.\n     *\n     * @return $this\n     */\n    public function broadcastToEveryone()\n    {\n        $this->socket = null;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/PendingBroadcast.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass PendingBroadcast\n{\n    /**\n     * The event dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The event instance.\n     *\n     * @var mixed\n     */\n    protected $event;\n\n    /**\n     * Create a new pending broadcast instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @param  mixed  $event\n     */\n    public function __construct(Dispatcher $events, $event)\n    {\n        $this->event = $event;\n        $this->events = $events;\n    }\n\n    /**\n     * Broadcast the event using a specific broadcaster.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return $this\n     */\n    public function via($connection = null)\n    {\n        if (method_exists($this->event, 'broadcastVia')) {\n            $this->event->broadcastVia(enum_value($connection));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Broadcast the event to everyone except the current user.\n     *\n     * @return $this\n     */\n    public function toOthers()\n    {\n        if (method_exists($this->event, 'dontBroadcastToCurrentUser')) {\n            $this->event->dontBroadcastToCurrentUser();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        $this->events->dispatch($this->event);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/PresenceChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nclass PresenceChannel extends Channel\n{\n    /**\n     * Create a new channel instance.\n     *\n     * @param  string  $name\n     */\n    public function __construct($name)\n    {\n        parent::__construct('presence-'.$name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/PrivateChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel;\n\nclass PrivateChannel extends Channel\n{\n    /**\n     * Create a new channel instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|string  $name\n     */\n    public function __construct($name)\n    {\n        $name = $name instanceof HasBroadcastChannel ? $name->broadcastChannel() : $name;\n\n        parent::__construct('private-'.$name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/UniqueBroadcastEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Broadcasting;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\n\nclass UniqueBroadcastEvent extends BroadcastEvent implements ShouldBeUnique\n{\n    /**\n     * The unique lock identifier.\n     *\n     * @var mixed\n     */\n    public $uniqueId;\n\n    /**\n     * The number of seconds the unique lock should be maintained.\n     *\n     * @var int\n     */\n    public $uniqueFor;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  mixed  $event\n     */\n    public function __construct($event)\n    {\n        if (method_exists($event, 'uniqueId')) {\n            $this->uniqueId .= $event->uniqueId();\n        } elseif (property_exists($event, 'uniqueId')) {\n            $this->uniqueId .= $event->uniqueId;\n        }\n\n        if (method_exists($event, 'uniqueFor')) {\n            $this->uniqueFor = $event->uniqueFor();\n        } elseif (property_exists($event, 'uniqueFor')) {\n            $this->uniqueFor = $event->uniqueFor;\n        }\n\n        parent::__construct($event);\n    }\n\n    /**\n     * Resolve the cache implementation that should manage the event's uniqueness.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function uniqueVia()\n    {\n        return method_exists($this->event, 'uniqueVia')\n            ? $this->event->uniqueVia()\n            : Container::getInstance()->make(Repository::class);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Broadcasting/composer.json",
    "content": "{\n    \"name\": \"illuminate/broadcasting\",\n    \"description\": \"The Illuminate Broadcasting package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/bus\": \"^13.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/queue\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"psr/log\": \"^1.0 || ^2.0 || ^3.0\"\n    },\n    \"suggest\": {\n        \"ext-hash\": \"Required to use the Ably and Pusher broadcast drivers.\",\n        \"ably/ably-php\": \"Required to use the Ably broadcast driver (^1.0).\",\n        \"pusher/pusher-php-server\": \"Required to use the Pusher broadcast driver (^6.0 || ^7.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Broadcasting\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Bus/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Bus/Batch.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Carbon\\CarbonImmutable;\nuse Closure;\nuse Illuminate\\Bus\\Events\\BatchCanceled;\nuse Illuminate\\Bus\\Events\\BatchFinished;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueFactory;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse JsonSerializable;\nuse Throwable;\n\nclass Batch implements Arrayable, JsonSerializable\n{\n    /**\n     * The queue factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    protected $queue;\n\n    /**\n     * The repository implementation.\n     *\n     * @var \\Illuminate\\Bus\\BatchRepository\n     */\n    protected $repository;\n\n    /**\n     * The batch ID.\n     *\n     * @var string\n     */\n    public $id;\n\n    /**\n     * The batch name.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The total number of jobs that belong to the batch.\n     *\n     * @var int\n     */\n    public $totalJobs;\n\n    /**\n     * The total number of jobs that are still pending.\n     *\n     * @var int\n     */\n    public $pendingJobs;\n\n    /**\n     * The total number of jobs that have failed.\n     *\n     * @var int\n     */\n    public $failedJobs;\n\n    /**\n     * The IDs of the jobs that have failed.\n     *\n     * @var array\n     */\n    public $failedJobIds;\n\n    /**\n     * The batch options.\n     *\n     * @var array\n     */\n    public $options;\n\n    /**\n     * The date indicating when the batch was created.\n     *\n     * @var \\Carbon\\CarbonImmutable\n     */\n    public $createdAt;\n\n    /**\n     * The date indicating when the batch was cancelled.\n     *\n     * @var \\Carbon\\CarbonImmutable|null\n     */\n    public $cancelledAt;\n\n    /**\n     * The date indicating when the batch was finished.\n     *\n     * @var \\Carbon\\CarbonImmutable|null\n     */\n    public $finishedAt;\n\n    /**\n     * Create a new batch instance.\n     */\n    public function __construct(\n        QueueFactory $queue,\n        BatchRepository $repository,\n        string $id,\n        string $name,\n        int $totalJobs,\n        int $pendingJobs,\n        int $failedJobs,\n        array $failedJobIds,\n        array $options,\n        CarbonImmutable $createdAt,\n        ?CarbonImmutable $cancelledAt = null,\n        ?CarbonImmutable $finishedAt = null,\n    ) {\n        $this->queue = $queue;\n        $this->repository = $repository;\n        $this->id = $id;\n        $this->name = $name;\n        $this->totalJobs = $totalJobs;\n        $this->pendingJobs = $pendingJobs;\n        $this->failedJobs = $failedJobs;\n        $this->failedJobIds = $failedJobIds;\n        $this->options = $options;\n        $this->createdAt = $createdAt;\n        $this->cancelledAt = $cancelledAt;\n        $this->finishedAt = $finishedAt;\n    }\n\n    /**\n     * Get a fresh instance of the batch represented by this ID.\n     *\n     * @return self\n     */\n    public function fresh()\n    {\n        return $this->repository->find($this->id);\n    }\n\n    /**\n     * Add additional jobs to the batch.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable|object|array  $jobs\n     * @return self\n     */\n    public function add($jobs)\n    {\n        $count = 0;\n\n        $jobs = Collection::wrap($jobs)->map(function ($job) use (&$count) {\n            $job = $job instanceof Closure ? CallQueuedClosure::create($job) : $job;\n\n            if (is_array($job)) {\n                $count += count($job);\n\n                $chain = $this->prepareBatchedChain($job);\n\n                $first = $chain->first();\n\n                if (isset($this->options['queue'])) {\n                    $first->allOnQueue($this->options['queue']);\n                }\n\n                if (isset($this->options['connection'])) {\n                    $first->allOnConnection($this->options['connection']);\n                }\n\n                return $first->chain($chain->slice(1)->values()->all());\n            } else {\n                $job->withBatchId($this->id);\n\n                $count++;\n            }\n\n            return $job;\n        });\n\n        $this->repository->transaction(function () use ($jobs, $count) {\n            $this->repository->incrementTotalJobs($this->id, $count);\n\n            $this->queue->connection($this->options['connection'] ?? null)->bulk(\n                $jobs->all(),\n                $data = '',\n                $this->options['queue'] ?? null\n            );\n        });\n\n        return $this->fresh();\n    }\n\n    /**\n     * Prepare a chain that exists within the jobs being added.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function prepareBatchedChain(array $chain)\n    {\n        return (new Collection($chain))->map(function ($job) {\n            $job = $job instanceof Closure ? CallQueuedClosure::create($job) : $job;\n\n            return $job->withBatchId($this->id);\n        });\n    }\n\n    /**\n     * Get the total number of jobs that have been processed by the batch thus far.\n     *\n     * @return int\n     */\n    public function processedJobs()\n    {\n        return $this->totalJobs - $this->pendingJobs;\n    }\n\n    /**\n     * Get the percentage of jobs that have been processed (between 0-100).\n     *\n     * @return int<0, 100>\n     */\n    public function progress()\n    {\n        return $this->totalJobs > 0 ? (int) round(($this->processedJobs() / $this->totalJobs) * 100) : 0;\n    }\n\n    /**\n     * Record that a job within the batch finished successfully, executing any callbacks if necessary.\n     *\n     * @return void\n     */\n    public function recordSuccessfulJob(string $jobId)\n    {\n        $counts = $this->decrementPendingJobs($jobId);\n\n        if ($this->hasProgressCallbacks()) {\n            $this->invokeCallbacks('progress');\n        }\n\n        if ($counts->pendingJobs === 0) {\n            $this->repository->markAsFinished($this->id);\n\n            $container = Container::getInstance();\n\n            if ($container->bound(Dispatcher::class)) {\n                $container->make(Dispatcher::class)->dispatch(new BatchFinished($this));\n            }\n        }\n\n        if ($counts->pendingJobs === 0 && $this->hasThenCallbacks()) {\n            $this->invokeCallbacks('then');\n        }\n\n        if ($counts->allJobsHaveRanExactlyOnce() && $this->hasFinallyCallbacks()) {\n            $this->invokeCallbacks('finally');\n        }\n    }\n\n    /**\n     * Decrement the pending jobs for the batch.\n     *\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function decrementPendingJobs(string $jobId)\n    {\n        return $this->repository->decrementPendingJobs($this->id, $jobId);\n    }\n\n    /**\n     * Invoke the callbacks of the given type.\n     */\n    protected function invokeCallbacks(string $type, ?Throwable $e = null): void\n    {\n        $batch = $this->fresh();\n\n        foreach ($this->options[$type] ?? [] as $handler) {\n            $this->invokeHandlerCallback($handler, $batch, $e);\n        }\n    }\n\n    /**\n     * Determine if the batch has finished executing.\n     *\n     * @return bool\n     */\n    public function finished()\n    {\n        return ! is_null($this->finishedAt);\n    }\n\n    /**\n     * Determine if the batch has \"progress\" callbacks.\n     *\n     * @return bool\n     */\n    public function hasProgressCallbacks()\n    {\n        return isset($this->options['progress']) && ! empty($this->options['progress']);\n    }\n\n    /**\n     * Determine if the batch has \"success\" callbacks.\n     *\n     * @return bool\n     */\n    public function hasThenCallbacks()\n    {\n        return isset($this->options['then']) && ! empty($this->options['then']);\n    }\n\n    /**\n     * Determine if the batch allows jobs to fail without cancelling the batch.\n     *\n     * @return bool\n     */\n    public function allowsFailures()\n    {\n        return Arr::get($this->options, 'allowFailures', false) === true;\n    }\n\n    /**\n     * Determine if the batch has job failures.\n     *\n     * @return bool\n     */\n    public function hasFailures()\n    {\n        return $this->failedJobs > 0;\n    }\n\n    /**\n     * Record that a job within the batch failed to finish successfully, executing any callbacks if necessary.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function recordFailedJob(string $jobId, $e)\n    {\n        $counts = $this->incrementFailedJobs($jobId);\n\n        if ($counts->failedJobs === 1 && ! $this->allowsFailures()) {\n            $this->cancel($e);\n        }\n\n        if ($this->allowsFailures()) {\n            if ($this->hasProgressCallbacks()) {\n                $this->invokeCallbacks('progress', $e);\n            }\n\n            if ($this->hasFailureCallbacks()) {\n                $this->invokeCallbacks('failure', $e);\n            }\n        }\n\n        if ($counts->failedJobs === 1 && $this->hasCatchCallbacks()) {\n            $this->invokeCallbacks('catch', $e);\n        }\n\n        if ($counts->allJobsHaveRanExactlyOnce() && $this->hasFinallyCallbacks()) {\n            $this->invokeCallbacks('finally');\n        }\n    }\n\n    /**\n     * Increment the failed jobs for the batch.\n     *\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function incrementFailedJobs(string $jobId)\n    {\n        return $this->repository->incrementFailedJobs($this->id, $jobId);\n    }\n\n    /**\n     * Determine if the batch has \"catch\" callbacks.\n     *\n     * @return bool\n     */\n    public function hasCatchCallbacks()\n    {\n        return isset($this->options['catch']) && ! empty($this->options['catch']);\n    }\n\n    /**\n     * Determine if the batch has \"failure\" callbacks.\n     */\n    public function hasFailureCallbacks(): bool\n    {\n        return isset($this->options['failure']) && ! empty($this->options['failure']);\n    }\n\n    /**\n     * Determine if the batch has \"finally\" callbacks.\n     *\n     * @return bool\n     */\n    public function hasFinallyCallbacks()\n    {\n        return isset($this->options['finally']) && ! empty($this->options['finally']);\n    }\n\n    /**\n     * Cancel the batch.\n     *\n     * @param  \\Throwable|null  $exception\n     * @return void\n     */\n    public function cancel(?Throwable $exception = null)\n    {\n        $this->repository->cancel($this->id);\n\n        $container = Container::getInstance();\n\n        if ($container->bound(Dispatcher::class)) {\n            $container->make(Dispatcher::class)->dispatch(new BatchCanceled($this, $exception));\n        }\n    }\n\n    /**\n     * Determine if the batch has been cancelled.\n     *\n     * @return bool\n     */\n    public function canceled()\n    {\n        return $this->cancelled();\n    }\n\n    /**\n     * Determine if the batch has been cancelled.\n     *\n     * @return bool\n     */\n    public function cancelled()\n    {\n        return ! is_null($this->cancelledAt);\n    }\n\n    /**\n     * Delete the batch from storage.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        $this->repository->delete($this->id);\n    }\n\n    /**\n     * Invoke a batch callback handler.\n     *\n     * @param  callable  $handler\n     * @return void\n     */\n    protected function invokeHandlerCallback($handler, Batch $batch, ?Throwable $e = null)\n    {\n        try {\n            $handler($batch, $e);\n        } catch (Throwable $e) {\n            if (function_exists('report')) {\n                report($e);\n            }\n        }\n    }\n\n    /**\n     * Convert the batch to an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'id' => $this->id,\n            'name' => $this->name,\n            'totalJobs' => $this->totalJobs,\n            'pendingJobs' => $this->pendingJobs,\n            'processedJobs' => $this->processedJobs(),\n            'progress' => $this->progress(),\n            'failedJobs' => $this->failedJobs,\n            'options' => $this->options,\n            'createdAt' => $this->createdAt,\n            'cancelledAt' => $this->cancelledAt,\n            'finishedAt' => $this->finishedAt,\n        ];\n    }\n\n    /**\n     * Get the JSON serializable representation of the object.\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Dynamically access the batch's \"options\" via properties.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->options[$key] ?? null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/BatchFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueFactory;\n\nclass BatchFactory\n{\n    /**\n     * The queue factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    protected $queue;\n\n    /**\n     * Create a new batch factory instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     */\n    public function __construct(QueueFactory $queue)\n    {\n        $this->queue = $queue;\n    }\n\n    /**\n     * Create a new batch instance.\n     *\n     * @param  \\Illuminate\\Bus\\BatchRepository  $repository\n     * @param  string  $id\n     * @param  string  $name\n     * @param  int  $totalJobs\n     * @param  int  $pendingJobs\n     * @param  int  $failedJobs\n     * @param  array  $failedJobIds\n     * @param  array  $options\n     * @param  \\Carbon\\CarbonImmutable  $createdAt\n     * @param  \\Carbon\\CarbonImmutable|null  $cancelledAt\n     * @param  \\Carbon\\CarbonImmutable|null  $finishedAt\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function make(BatchRepository $repository,\n                         string $id,\n                         string $name,\n                         int $totalJobs,\n                         int $pendingJobs,\n                         int $failedJobs,\n                         array $failedJobIds,\n                         array $options,\n                         CarbonImmutable $createdAt,\n                         ?CarbonImmutable $cancelledAt,\n                         ?CarbonImmutable $finishedAt)\n    {\n        return new Batch($this->queue, $repository, $id, $name, $totalJobs, $pendingJobs, $failedJobs, $failedJobIds, $options, $createdAt, $cancelledAt, $finishedAt);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/BatchRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Closure;\n\ninterface BatchRepository\n{\n    /**\n     * Retrieve a list of batches.\n     *\n     * @param  int  $limit\n     * @param  mixed  $before\n     * @return \\Illuminate\\Bus\\Batch[]\n     */\n    public function get($limit, $before);\n\n    /**\n     * Retrieve information about an existing batch.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function find(string $batchId);\n\n    /**\n     * Store a new pending batch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function store(PendingBatch $batch);\n\n    /**\n     * Increment the total number of jobs within the batch.\n     *\n     * @param  string  $batchId\n     * @param  int  $amount\n     * @return void\n     */\n    public function incrementTotalJobs(string $batchId, int $amount);\n\n    /**\n     * Decrement the total number of pending jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function decrementPendingJobs(string $batchId, string $jobId);\n\n    /**\n     * Increment the total number of failed jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function incrementFailedJobs(string $batchId, string $jobId);\n\n    /**\n     * Mark the batch that has the given ID as finished.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function markAsFinished(string $batchId);\n\n    /**\n     * Cancel the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function cancel(string $batchId);\n\n    /**\n     * Delete the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function delete(string $batchId);\n\n    /**\n     * Execute the given Closure within a storage specific transaction.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function transaction(Closure $callback);\n\n    /**\n     * Rollback the last database transaction for the connection.\n     *\n     * @return void\n     */\n    public function rollBack();\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Batchable.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Testing\\Fakes\\BatchFake;\n\ntrait Batchable\n{\n    /**\n     * The batch ID (if applicable).\n     *\n     * @var string|null\n     */\n    public $batchId;\n\n    /**\n     * The fake batch, if applicable.\n     *\n     * @var \\Illuminate\\Support\\Testing\\Fakes\\BatchFake\n     */\n    private $fakeBatch;\n\n    /**\n     * Get the batch instance for the job, if applicable.\n     *\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function batch()\n    {\n        if ($this->fakeBatch) {\n            return $this->fakeBatch;\n        }\n\n        if ($this->batchId) {\n            return Container::getInstance()->make(BatchRepository::class)?->find($this->batchId);\n        }\n    }\n\n    /**\n     * Determine if the batch is still active and processing.\n     *\n     * @return bool\n     */\n    public function batching()\n    {\n        $batch = $this->batch();\n\n        return $batch && ! $batch->cancelled();\n    }\n\n    /**\n     * Set the batch ID on the job.\n     *\n     * @param  string  $batchId\n     * @return $this\n     */\n    public function withBatchId(string $batchId)\n    {\n        $this->batchId = $batchId;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should use a fake batch.\n     *\n     * @param  string  $id\n     * @param  string  $name\n     * @param  int  $totalJobs\n     * @param  int  $pendingJobs\n     * @param  int  $failedJobs\n     * @param  array  $failedJobIds\n     * @param  array  $options\n     * @param  \\Carbon\\CarbonImmutable|null  $createdAt\n     * @param  \\Carbon\\CarbonImmutable|null  $cancelledAt\n     * @param  \\Carbon\\CarbonImmutable|null  $finishedAt\n     * @return array{0: $this, 1: \\Illuminate\\Support\\Testing\\Fakes\\BatchFake}\n     */\n    public function withFakeBatch(string $id = '',\n                                  string $name = '',\n                                  int $totalJobs = 0,\n                                  int $pendingJobs = 0,\n                                  int $failedJobs = 0,\n                                  array $failedJobIds = [],\n                                  array $options = [],\n                                  ?CarbonImmutable $createdAt = null,\n                                  ?CarbonImmutable $cancelledAt = null,\n                                  ?CarbonImmutable $finishedAt = null)\n    {\n        $this->fakeBatch = new BatchFake(\n            empty($id) ? (string) Str::uuid() : $id,\n            $name,\n            $totalJobs,\n            $pendingJobs,\n            $failedJobs,\n            $failedJobIds,\n            $options,\n            $createdAt ?? CarbonImmutable::now(),\n            $cancelledAt,\n            $finishedAt,\n        );\n\n        return [$this, $this->fakeBatch];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/BusServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as DispatcherContract;\nuse Illuminate\\Contracts\\Bus\\QueueingDispatcher as QueueingDispatcherContract;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueFactoryContract;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass BusServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton(Dispatcher::class, function ($app) {\n            return new Dispatcher($app, function ($connection = null) {\n                return Container::getInstance()->make(QueueFactoryContract::class)->connection($connection);\n            });\n        });\n\n        $this->registerBatchServices();\n\n        $this->app->alias(\n            Dispatcher::class, DispatcherContract::class\n        );\n\n        $this->app->alias(\n            Dispatcher::class, QueueingDispatcherContract::class\n        );\n    }\n\n    /**\n     * Register the batch handling services.\n     *\n     * @return void\n     */\n    protected function registerBatchServices()\n    {\n        $this->app->singleton(BatchRepository::class, function ($app) {\n            $driver = $app->config->get('queue.batching.driver', 'database');\n\n            return $driver === 'dynamodb'\n                ? $app->make(DynamoBatchRepository::class)\n                : $app->make(DatabaseBatchRepository::class);\n        });\n\n        $this->app->singleton(DatabaseBatchRepository::class, function ($app) {\n            return new DatabaseBatchRepository(\n                $app->make(BatchFactory::class),\n                $app->make('db')->connection($app->config->get('queue.batching.database')),\n                $app->config->get('queue.batching.table', 'job_batches')\n            );\n        });\n\n        $this->app->singleton(DynamoBatchRepository::class, function ($app) {\n            $config = $app->config->get('queue.batching');\n\n            $dynamoConfig = [\n                'region' => $config['region'],\n                'version' => 'latest',\n                'endpoint' => $config['endpoint'] ?? null,\n            ];\n\n            if (! empty($config['key']) && ! empty($config['secret'])) {\n                $dynamoConfig['credentials'] = Arr::only($config, ['key', 'secret']);\n\n                if (! empty($config['token'])) {\n                    $dynamoConfig['credentials']['token'] = $config['token'];\n                }\n            }\n\n            return new DynamoBatchRepository(\n                $app->make(BatchFactory::class),\n                new DynamoDbClient($dynamoConfig),\n                $app->config->get('app.name'),\n                $app->config->get('queue.batching.table', 'job_batches'),\n                ttl: $app->config->get('queue.batching.ttl', null),\n                ttlAttribute: $app->config->get('queue.batching.ttl_attribute', 'ttl'),\n            );\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            Dispatcher::class,\n            DispatcherContract::class,\n            QueueingDispatcherContract::class,\n            BatchRepository::class,\n            DatabaseBatchRepository::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/ChainedBatch.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Collection;\nuse Throwable;\n\nclass ChainedBatch implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable;\n\n    /**\n     * The collection of batched jobs.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    public Collection $jobs;\n\n    /**\n     * The name of the batch.\n     *\n     * @var string\n     */\n    public string $name;\n\n    /**\n     * The batch options.\n     *\n     * @var array\n     */\n    public array $options;\n\n    /**\n     * Create a new chained batch instance.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     */\n    public function __construct(PendingBatch $batch)\n    {\n        $this->jobs = static::prepareNestedBatches($batch->jobs);\n\n        $this->name = $batch->name;\n        $this->options = $batch->options;\n\n        $this->queue = $batch->queue();\n        $this->connection = $batch->connection();\n    }\n\n    /**\n     * Prepare any nested batches within the given collection of jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $jobs\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public static function prepareNestedBatches(Collection $jobs): Collection\n    {\n        return $jobs->filter()->values()->map(fn ($job) => match (true) {\n            is_array($job) => static::prepareNestedBatches(new Collection($job))->all(),\n            $job instanceof Collection => static::prepareNestedBatches($job),\n            $job instanceof PendingBatch => new ChainedBatch($job),\n            default => $job,\n        });\n    }\n\n    /**\n     * Handle the job.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->attachRemainderOfChainToEndOfBatch(\n            $this->toPendingBatch()\n        )->dispatch();\n    }\n\n    /**\n     * Convert the chained batch instance into a pending batch.\n     *\n     * @return \\Illuminate\\Bus\\PendingBatch\n     */\n    public function toPendingBatch()\n    {\n        $batch = Container::getInstance()->make(Dispatcher::class)->batch($this->jobs);\n\n        $batch->name = $this->name;\n        $batch->options = $this->options;\n\n        if ($this->queue) {\n            $batch->onQueue($this->queue);\n        }\n\n        if ($this->connection) {\n            $batch->onConnection($this->connection);\n        }\n\n        foreach ($this->chainCatchCallbacks ?? [] as $callback) {\n            $batch->catch(function (Batch $batch, ?Throwable $exception) use ($callback) {\n                if (! $batch->allowsFailures()) {\n                    $callback($exception);\n                }\n            });\n        }\n\n        return $batch;\n    }\n\n    /**\n     * Move the remainder of the chain to a \"finally\" batch callback.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     * @return \\Illuminate\\Bus\\PendingBatch\n     */\n    protected function attachRemainderOfChainToEndOfBatch(PendingBatch $batch)\n    {\n        if (is_array($this->chained) && ! empty($this->chained)) {\n            $next = unserialize(array_shift($this->chained));\n\n            $next->chained = $this->chained;\n\n            $next->onConnection($next->connection ?: $this->chainConnection);\n            $next->onQueue($next->queue ?: $this->chainQueue);\n\n            $next->chainConnection = $this->chainConnection;\n            $next->chainQueue = $this->chainQueue;\n            $next->chainCatchCallbacks = $this->chainCatchCallbacks;\n\n            $batch->finally(function (Batch $batch) use ($next) {\n                if (! $batch->cancelled()) {\n                    Container::getInstance()->make(Dispatcher::class)->dispatch($next);\n                }\n            });\n\n            $this->chained = [];\n        }\n\n        return $batch;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/DatabaseBatchRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Carbon\\CarbonImmutable;\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Support\\Str;\nuse Throwable;\n\nclass DatabaseBatchRepository implements PrunableBatchRepository\n{\n    /**\n     * The batch factory instance.\n     *\n     * @var \\Illuminate\\Bus\\BatchFactory\n     */\n    protected $factory;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * The database table to use to store batch information.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * Create a new batch repository instance.\n     *\n     * @param  \\Illuminate\\Bus\\BatchFactory  $factory\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $table\n     */\n    public function __construct(BatchFactory $factory, Connection $connection, string $table)\n    {\n        $this->factory = $factory;\n        $this->connection = $connection;\n        $this->table = $table;\n    }\n\n    /**\n     * Retrieve a list of batches.\n     *\n     * @param  int  $limit\n     * @param  mixed  $before\n     * @return \\Illuminate\\Bus\\Batch[]\n     */\n    public function get($limit = 50, $before = null)\n    {\n        return $this->connection->table($this->table)\n            ->orderByDesc('id')\n            ->limit($limit)\n            ->when($before, fn ($q) => $q->where('id', '<', $before))\n            ->get()\n            ->map(function ($batch) {\n                return $this->toBatch($batch);\n            })\n            ->all();\n    }\n\n    /**\n     * Retrieve information about an existing batch.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function find(string $batchId)\n    {\n        $batch = $this->connection->table($this->table)\n            ->useWritePdo()\n            ->where('id', $batchId)\n            ->first();\n\n        if ($batch) {\n            return $this->toBatch($batch);\n        }\n    }\n\n    /**\n     * Store a new pending batch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function store(PendingBatch $batch)\n    {\n        $id = (string) Str::orderedUuid();\n\n        $this->connection->table($this->table)->insert([\n            'id' => $id,\n            'name' => $batch->name,\n            'total_jobs' => 0,\n            'pending_jobs' => 0,\n            'failed_jobs' => 0,\n            'failed_job_ids' => '[]',\n            'options' => $this->serialize($batch->options),\n            'created_at' => time(),\n            'cancelled_at' => null,\n            'finished_at' => null,\n        ]);\n\n        return $this->find($id);\n    }\n\n    /**\n     * Increment the total number of jobs within the batch.\n     *\n     * @param  string  $batchId\n     * @param  int  $amount\n     * @return void\n     */\n    public function incrementTotalJobs(string $batchId, int $amount)\n    {\n        $this->connection->table($this->table)->where('id', $batchId)->update([\n            'total_jobs' => new Expression('total_jobs + '.$amount),\n            'pending_jobs' => new Expression('pending_jobs + '.$amount),\n            'finished_at' => null,\n        ]);\n    }\n\n    /**\n     * Decrement the total number of pending jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function decrementPendingJobs(string $batchId, string $jobId)\n    {\n        $values = $this->updateAtomicValues($batchId, function ($batch) use ($jobId) {\n            return [\n                'pending_jobs' => $batch->pending_jobs - 1,\n                'failed_jobs' => $batch->failed_jobs,\n                'failed_job_ids' => json_encode(array_values(array_diff((array) json_decode($batch->failed_job_ids, true), [$jobId]))),\n            ];\n        });\n\n        return new UpdatedBatchJobCounts(\n            $values['pending_jobs'],\n            $values['failed_jobs']\n        );\n    }\n\n    /**\n     * Increment the total number of failed jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function incrementFailedJobs(string $batchId, string $jobId)\n    {\n        $values = $this->updateAtomicValues($batchId, function ($batch) use ($jobId) {\n            return [\n                'pending_jobs' => $batch->pending_jobs,\n                'failed_jobs' => $batch->failed_jobs + 1,\n                'failed_job_ids' => json_encode(array_values(array_unique(array_merge((array) json_decode($batch->failed_job_ids, true), [$jobId])))),\n            ];\n        });\n\n        return new UpdatedBatchJobCounts(\n            $values['pending_jobs'],\n            $values['failed_jobs']\n        );\n    }\n\n    /**\n     * Update an atomic value within the batch.\n     *\n     * @param  string  $batchId\n     * @param  \\Closure  $callback\n     * @return int|null\n     */\n    protected function updateAtomicValues(string $batchId, Closure $callback)\n    {\n        return $this->connection->transaction(function () use ($batchId, $callback) {\n            $batch = $this->connection->table($this->table)->where('id', $batchId)\n                ->lockForUpdate()\n                ->first();\n\n            return is_null($batch) ? [] : tap($callback($batch), function ($values) use ($batchId) {\n                $this->connection->table($this->table)->where('id', $batchId)->update($values);\n            });\n        });\n    }\n\n    /**\n     * Mark the batch that has the given ID as finished.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function markAsFinished(string $batchId)\n    {\n        $this->connection->table($this->table)->where('id', $batchId)->update([\n            'finished_at' => time(),\n        ]);\n    }\n\n    /**\n     * Cancel the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function cancel(string $batchId)\n    {\n        $this->connection->table($this->table)->where('id', $batchId)->update([\n            'cancelled_at' => time(),\n            'finished_at' => time(),\n        ]);\n    }\n\n    /**\n     * Delete the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function delete(string $batchId)\n    {\n        $this->connection->table($this->table)->where('id', $batchId)->delete();\n    }\n\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before)\n    {\n        $query = $this->connection->table($this->table)\n            ->whereNotNull('finished_at')\n            ->where('finished_at', '<', $before->getTimestamp());\n\n        $totalDeleted = 0;\n\n        do {\n            $deleted = $query->limit(1000)->delete();\n\n            $totalDeleted += $deleted;\n        } while ($deleted !== 0);\n\n        return $totalDeleted;\n    }\n\n    /**\n     * Prune all of the unfinished entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function pruneUnfinished(DateTimeInterface $before)\n    {\n        $query = $this->connection->table($this->table)\n            ->whereNull('finished_at')\n            ->where('created_at', '<', $before->getTimestamp());\n\n        $totalDeleted = 0;\n\n        do {\n            $deleted = $query->limit(1000)->delete();\n\n            $totalDeleted += $deleted;\n        } while ($deleted !== 0);\n\n        return $totalDeleted;\n    }\n\n    /**\n     * Prune all of the cancelled entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function pruneCancelled(DateTimeInterface $before)\n    {\n        $query = $this->connection->table($this->table)\n            ->whereNotNull('cancelled_at')\n            ->where('created_at', '<', $before->getTimestamp());\n\n        $totalDeleted = 0;\n\n        do {\n            $deleted = $query->limit(1000)->delete();\n\n            $totalDeleted += $deleted;\n        } while ($deleted !== 0);\n\n        return $totalDeleted;\n    }\n\n    /**\n     * Execute the given Closure within a storage specific transaction.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function transaction(Closure $callback)\n    {\n        return $this->connection->transaction(fn () => $callback());\n    }\n\n    /**\n     * Rollback the last database transaction for the connection.\n     *\n     * @return void\n     */\n    public function rollBack()\n    {\n        $this->connection->rollBack(toLevel: 0);\n    }\n\n    /**\n     * Serialize the given value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function serialize($value)\n    {\n        $serialized = serialize($value);\n\n        return $this->connection instanceof PostgresConnection\n            ? base64_encode($serialized)\n            : $serialized;\n    }\n\n    /**\n     * Unserialize the given value.\n     *\n     * @param  string  $serialized\n     * @return mixed\n     */\n    protected function unserialize($serialized)\n    {\n        if ($this->connection instanceof PostgresConnection &&\n            ! Str::contains($serialized, [':', ';'])) {\n            $serialized = base64_decode($serialized);\n        }\n\n        try {\n            return unserialize($serialized);\n        } catch (Throwable) {\n            return [];\n        }\n    }\n\n    /**\n     * Convert the given raw batch to a Batch object.\n     *\n     * @param  object  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    protected function toBatch($batch)\n    {\n        return $this->factory->make(\n            $this,\n            $batch->id,\n            $batch->name,\n            (int) $batch->total_jobs,\n            (int) $batch->pending_jobs,\n            (int) $batch->failed_jobs,\n            (array) json_decode($batch->failed_job_ids, true),\n            $this->unserialize($batch->options),\n            CarbonImmutable::createFromTimestamp($batch->created_at, date_default_timezone_get()),\n            $batch->cancelled_at ? CarbonImmutable::createFromTimestamp($batch->cancelled_at, date_default_timezone_get()) : $batch->cancelled_at,\n            $batch->finished_at ? CarbonImmutable::createFromTimestamp($batch->finished_at, date_default_timezone_get()) : $batch->finished_at\n        );\n    }\n\n    /**\n     * Get the underlying database connection.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Set the underlying database connection.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return void\n     */\n    public function setConnection(Connection $connection)\n    {\n        $this->connection = $connection;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Dispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Closure;\nuse Illuminate\\Contracts\\Bus\\QueueingDispatcher;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Queue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\PendingChain;\nuse Illuminate\\Pipeline\\Pipeline;\nuse Illuminate\\Queue\\Attributes\\Connection;\nuse Illuminate\\Queue\\Attributes\\Queue as QueueAttribute;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Jobs\\SyncJob;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Queue\\Concerns\\ResolvesQueueRoutes;\nuse RuntimeException;\n\nclass Dispatcher implements QueueingDispatcher\n{\n    use ReadsQueueAttributes, ResolvesQueueRoutes;\n\n    /**\n     * The container implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The pipeline instance for the bus.\n     *\n     * @var \\Illuminate\\Pipeline\\Pipeline\n     */\n    protected $pipeline;\n\n    /**\n     * The pipes to send commands through before dispatching.\n     *\n     * @var array\n     */\n    protected $pipes = [];\n\n    /**\n     * The command to handler mapping for non-self-handling events.\n     *\n     * @var array\n     */\n    protected $handlers = [];\n\n    /**\n     * The queue resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $queueResolver;\n\n    /**\n     * Indicates if dispatching after response is disabled.\n     *\n     * @var bool\n     */\n    protected $allowsDispatchingAfterResponses = true;\n\n    /**\n     * Create a new command dispatcher instance.\n     */\n    public function __construct(Container $container, ?Closure $queueResolver = null)\n    {\n        $this->container = $container;\n        $this->queueResolver = $queueResolver;\n        $this->pipeline = new Pipeline($container);\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function dispatch($command)\n    {\n        return $this->queueResolver && $this->commandShouldBeQueued($command)\n            ? $this->dispatchToQueue($command)\n            : $this->dispatchNow($command);\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchSync($command, $handler = null)\n    {\n        if ($this->queueResolver &&\n            $this->commandShouldBeQueued($command) &&\n            method_exists($command, 'onConnection')) {\n            return $this->dispatchToQueue($command->onConnection('sync'));\n        }\n\n        return $this->dispatchNow($command, $handler);\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process without using the synchronous queue.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchNow($command, $handler = null)\n    {\n        $uses = class_uses_recursive($command);\n\n        if (isset($uses[InteractsWithQueue::class], $uses[Queueable::class]) && ! $command->job) {\n            $command->setJob(new SyncJob($this->container, json_encode([]), 'sync', 'sync'));\n        }\n\n        if ($handler || $handler = $this->getCommandHandler($command)) {\n            $callback = function ($command) use ($handler) {\n                $method = method_exists($handler, 'handle') ? 'handle' : '__invoke';\n\n                return $handler->{$method}($command);\n            };\n        } else {\n            $callback = function ($command) {\n                $method = method_exists($command, 'handle') ? 'handle' : '__invoke';\n\n                return $this->container->call([$command, $method]);\n            };\n        }\n\n        return $this->pipeline->send($command)->through($this->pipes)->then($callback);\n    }\n\n    /**\n     * Attempt to find the batch with the given ID.\n     *\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function findBatch(string $batchId)\n    {\n        return $this->container->make(BatchRepository::class)->find($batchId);\n    }\n\n    /**\n     * Create a new batch of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $jobs\n     * @return \\Illuminate\\Bus\\PendingBatch\n     */\n    public function batch($jobs)\n    {\n        return new PendingBatch($this->container, Collection::wrap($jobs));\n    }\n\n    /**\n     * Create a new chain of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|null  $jobs\n     * @return \\Illuminate\\Foundation\\Bus\\PendingChain\n     */\n    public function chain($jobs = null)\n    {\n        $jobs = Collection::wrap($jobs);\n        $jobs = ChainedBatch::prepareNestedBatches($jobs);\n\n        return new PendingChain($jobs->shift(), $jobs->toArray());\n    }\n\n    /**\n     * Determine if the given command has a handler.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    public function hasCommandHandler($command)\n    {\n        return array_key_exists(get_class($command), $this->handlers);\n    }\n\n    /**\n     * Retrieve the handler for a command.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function getCommandHandler($command)\n    {\n        if ($this->hasCommandHandler($command)) {\n            return $this->container->make($this->handlers[get_class($command)]);\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the given command should be queued.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    protected function commandShouldBeQueued($command)\n    {\n        return $command instanceof ShouldQueue;\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler behind a queue.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public function dispatchToQueue($command)\n    {\n        $connection = $this->getAttributeValue($command, Connection::class, 'connection')\n            ?? $this->resolveConnectionFromQueueRoute($command)\n            ?? null;\n\n        $queue = ($this->queueResolver)($connection);\n\n        if (! $queue instanceof Queue) {\n            throw new RuntimeException('Queue resolver did not return a Queue implementation.');\n        }\n\n        if (method_exists($command, 'queue')) {\n            return $command->queue($queue, $command);\n        }\n\n        return $this->pushCommandToQueue($queue, $command);\n    }\n\n    /**\n     * Push the command onto the given queue instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Queue  $queue\n     * @param  mixed  $command\n     * @return mixed\n     */\n    protected function pushCommandToQueue($queue, $command)\n    {\n        $queueName = $this->getAttributeValue($command, QueueAttribute::class, 'queue')\n            ?? $this->resolveQueueFromQueueRoute($command)\n            ?? null;\n\n        if (isset($command->delay)) {\n            return $queue->later($command->delay, $command, queue: $queueName);\n        }\n\n        return $queue->push($command, queue: $queueName);\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler after the current process.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return void\n     */\n    public function dispatchAfterResponse($command, $handler = null)\n    {\n        if (! $this->allowsDispatchingAfterResponses) {\n            $this->dispatchSync($command);\n\n            return;\n        }\n\n        $this->container->terminating(function () use ($command, $handler) {\n            $this->dispatchSync($command, $handler);\n        });\n    }\n\n    /**\n     * Set the pipes through which commands should be piped before dispatching.\n     *\n     * @return $this\n     */\n    public function pipeThrough(array $pipes)\n    {\n        $this->pipes = $pipes;\n\n        return $this;\n    }\n\n    /**\n     * Map a command to a handler.\n     *\n     * @return $this\n     */\n    public function map(array $map)\n    {\n        $this->handlers = array_merge($this->handlers, $map);\n\n        return $this;\n    }\n\n    /**\n     * Allow dispatching after responses.\n     *\n     * @return $this\n     */\n    public function withDispatchingAfterResponses()\n    {\n        $this->allowsDispatchingAfterResponses = true;\n\n        return $this;\n    }\n\n    /**\n     * Disable dispatching after responses.\n     *\n     * @return $this\n     */\n    public function withoutDispatchingAfterResponses()\n    {\n        $this->allowsDispatchingAfterResponses = false;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/DynamoBatchRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Aws\\DynamoDb\\Marshaler;\nuse Carbon\\CarbonImmutable;\nuse Closure;\nuse Illuminate\\Support\\Str;\n\nclass DynamoBatchRepository implements BatchRepository\n{\n    /**\n     * The batch factory instance.\n     *\n     * @var \\Illuminate\\Bus\\BatchFactory\n     */\n    protected $factory;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Aws\\DynamoDb\\DynamoDbClient\n     */\n    protected $dynamoDbClient;\n\n    /**\n     * The application name.\n     *\n     * @var string\n     */\n    protected $applicationName;\n\n    /**\n     * The table to use to store batch information.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The time-to-live value for batch records.\n     *\n     * @var int\n     */\n    protected $ttl;\n\n    /**\n     * The name of the time-to-live attribute for batch records.\n     *\n     * @var string\n     */\n    protected $ttlAttribute;\n\n    /**\n     * The DynamoDB marshaler instance.\n     *\n     * @var \\Aws\\DynamoDb\\Marshaler\n     */\n    protected $marshaler;\n\n    /**\n     * Create a new batch repository instance.\n     */\n    public function __construct(\n        BatchFactory $factory,\n        DynamoDbClient $dynamoDbClient,\n        string $applicationName,\n        string $table,\n        ?int $ttl,\n        ?string $ttlAttribute,\n    ) {\n        $this->factory = $factory;\n        $this->dynamoDbClient = $dynamoDbClient;\n        $this->applicationName = $applicationName;\n        $this->table = $table;\n        $this->ttl = $ttl;\n        $this->ttlAttribute = $ttlAttribute;\n        $this->marshaler = new Marshaler;\n    }\n\n    /**\n     * Retrieve a list of batches.\n     *\n     * @param  int  $limit\n     * @param  mixed  $before\n     * @return \\Illuminate\\Bus\\Batch[]\n     */\n    public function get($limit = 50, $before = null)\n    {\n        $condition = 'application = :application';\n\n        if ($before) {\n            $condition = 'application = :application AND id < :id';\n        }\n\n        $result = $this->dynamoDbClient->query([\n            'TableName' => $this->table,\n            'KeyConditionExpression' => $condition,\n            'ExpressionAttributeValues' => array_filter([\n                ':application' => ['S' => $this->applicationName],\n                ':id' => array_filter(['S' => $before]),\n            ]),\n            'Limit' => $limit,\n            'ScanIndexForward' => false,\n        ]);\n\n        return array_map(\n            fn ($b) => $this->toBatch($this->marshaler->unmarshalItem($b, mapAsObject: true)),\n            $result['Items']\n        );\n    }\n\n    /**\n     * Retrieve information about an existing batch.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function find(string $batchId)\n    {\n        if (trim($batchId) === '') {\n            return null;\n        }\n\n        $b = $this->dynamoDbClient->getItem([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n        ]);\n\n        if (! isset($b['Item'])) {\n            // If we didn't find it via a standard read, attempt consistent read...\n            $b = $this->dynamoDbClient->getItem([\n                'TableName' => $this->table,\n                'Key' => [\n                    'application' => ['S' => $this->applicationName],\n                    'id' => ['S' => $batchId],\n                ],\n                'ConsistentRead' => true,\n            ]);\n\n            if (! isset($b['Item'])) {\n                return null;\n            }\n        }\n\n        $batch = $this->marshaler->unmarshalItem($b['Item'], mapAsObject: true);\n\n        if ($batch) {\n            return $this->toBatch($batch);\n        }\n    }\n\n    /**\n     * Store a new pending batch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function store(PendingBatch $batch)\n    {\n        $id = (string) Str::orderedUuid();\n\n        $batch = [\n            'id' => $id,\n            'name' => $batch->name,\n            'total_jobs' => 0,\n            'pending_jobs' => 0,\n            'failed_jobs' => 0,\n            'failed_job_ids' => [],\n            'options' => $this->serialize($batch->options ?? []),\n            'created_at' => time(),\n            'cancelled_at' => null,\n            'finished_at' => null,\n        ];\n\n        if (! is_null($this->ttl)) {\n            $batch[$this->ttlAttribute] = time() + $this->ttl;\n        }\n\n        $this->dynamoDbClient->putItem([\n            'TableName' => $this->table,\n            'Item' => $this->marshaler->marshalItem(\n                array_merge(['application' => $this->applicationName], $batch)\n            ),\n        ]);\n\n        return $this->find($id);\n    }\n\n    /**\n     * Increment the total number of jobs within the batch.\n     *\n     * @param  string  $batchId\n     * @param  int  $amount\n     * @return void\n     */\n    public function incrementTotalJobs(string $batchId, int $amount)\n    {\n        $update = 'SET total_jobs = total_jobs + :val, pending_jobs = pending_jobs + :val';\n\n        if ($this->ttl) {\n            $update = \"SET total_jobs = total_jobs + :val, pending_jobs = pending_jobs + :val, #{$this->ttlAttribute} = :ttl\";\n        }\n\n        $this->dynamoDbClient->updateItem(array_filter([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n            'UpdateExpression' => $update,\n            'ExpressionAttributeValues' => array_filter([\n                ':val' => ['N' => \"$amount\"],\n                ':ttl' => array_filter(['N' => $this->getExpiryTime()]),\n            ]),\n            'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(),\n            'ReturnValues' => 'ALL_NEW',\n        ]));\n    }\n\n    /**\n     * Decrement the total number of pending jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function decrementPendingJobs(string $batchId, string $jobId)\n    {\n        $update = 'SET pending_jobs = pending_jobs - :inc';\n\n        if ($this->ttl !== null) {\n            $update = \"SET pending_jobs = pending_jobs - :inc, #{$this->ttlAttribute} = :ttl\";\n        }\n\n        $batch = $this->dynamoDbClient->updateItem(array_filter([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n            'UpdateExpression' => $update,\n            'ExpressionAttributeValues' => array_filter([\n                ':inc' => ['N' => '1'],\n                ':ttl' => array_filter(['N' => $this->getExpiryTime()]),\n            ]),\n            'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(),\n            'ReturnValues' => 'ALL_NEW',\n        ]));\n\n        $values = $this->marshaler->unmarshalItem($batch['Attributes']);\n\n        return new UpdatedBatchJobCounts(\n            $values['pending_jobs'],\n            $values['failed_jobs']\n        );\n    }\n\n    /**\n     * Increment the total number of failed jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function incrementFailedJobs(string $batchId, string $jobId)\n    {\n        $update = 'SET failed_jobs = failed_jobs + :inc, failed_job_ids = list_append(failed_job_ids, :jobId)';\n\n        if ($this->ttl !== null) {\n            $update = \"SET failed_jobs = failed_jobs + :inc, failed_job_ids = list_append(failed_job_ids, :jobId), #{$this->ttlAttribute} = :ttl\";\n        }\n\n        $batch = $this->dynamoDbClient->updateItem(array_filter([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n            'UpdateExpression' => $update,\n            'ExpressionAttributeValues' => array_filter([\n                ':jobId' => $this->marshaler->marshalValue([$jobId]),\n                ':inc' => ['N' => '1'],\n                ':ttl' => array_filter(['N' => $this->getExpiryTime()]),\n            ]),\n            'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(),\n            'ReturnValues' => 'ALL_NEW',\n        ]));\n\n        $values = $this->marshaler->unmarshalItem($batch['Attributes']);\n\n        return new UpdatedBatchJobCounts(\n            $values['pending_jobs'],\n            $values['failed_jobs']\n        );\n    }\n\n    /**\n     * Mark the batch that has the given ID as finished.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function markAsFinished(string $batchId)\n    {\n        $update = 'SET finished_at = :timestamp';\n\n        if ($this->ttl !== null) {\n            $update = \"SET finished_at = :timestamp, #{$this->ttlAttribute} = :ttl\";\n        }\n\n        $this->dynamoDbClient->updateItem(array_filter([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n            'UpdateExpression' => $update,\n            'ExpressionAttributeValues' => array_filter([\n                ':timestamp' => ['N' => (string) time()],\n                ':ttl' => array_filter(['N' => $this->getExpiryTime()]),\n            ]),\n            'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(),\n        ]));\n    }\n\n    /**\n     * Cancel the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function cancel(string $batchId)\n    {\n        $update = 'SET cancelled_at = :timestamp, finished_at = :timestamp';\n\n        if ($this->ttl !== null) {\n            $update = \"SET cancelled_at = :timestamp, finished_at = :timestamp, #{$this->ttlAttribute} = :ttl\";\n        }\n\n        $this->dynamoDbClient->updateItem(array_filter([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n            'UpdateExpression' => $update,\n            'ExpressionAttributeValues' => array_filter([\n                ':timestamp' => ['N' => (string) time()],\n                ':ttl' => array_filter(['N' => $this->getExpiryTime()]),\n            ]),\n            'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(),\n        ]));\n    }\n\n    /**\n     * Delete the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function delete(string $batchId)\n    {\n        $this->dynamoDbClient->deleteItem([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'id' => ['S' => $batchId],\n            ],\n        ]);\n    }\n\n    /**\n     * Execute the given Closure within a storage specific transaction.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function transaction(Closure $callback)\n    {\n        return $callback();\n    }\n\n    /**\n     * Rollback the last database transaction for the connection.\n     *\n     * @return void\n     */\n    public function rollBack()\n    {\n    }\n\n    /**\n     * Convert the given raw batch to a Batch object.\n     *\n     * @param  object  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    protected function toBatch($batch)\n    {\n        return $this->factory->make(\n            $this,\n            $batch->id,\n            $batch->name,\n            (int) $batch->total_jobs,\n            (int) $batch->pending_jobs,\n            (int) $batch->failed_jobs,\n            $batch->failed_job_ids,\n            $this->unserialize($batch->options) ?? [],\n            CarbonImmutable::createFromTimestamp($batch->created_at, date_default_timezone_get()),\n            $batch->cancelled_at ? CarbonImmutable::createFromTimestamp($batch->cancelled_at, date_default_timezone_get()) : $batch->cancelled_at,\n            $batch->finished_at ? CarbonImmutable::createFromTimestamp($batch->finished_at, date_default_timezone_get()) : $batch->finished_at\n        );\n    }\n\n    /**\n     * Create the underlying DynamoDB table.\n     *\n     * @return void\n     */\n    public function createAwsDynamoTable(): void\n    {\n        $definition = [\n            'TableName' => $this->table,\n            'AttributeDefinitions' => [\n                [\n                    'AttributeName' => 'application',\n                    'AttributeType' => 'S',\n                ],\n                [\n                    'AttributeName' => 'id',\n                    'AttributeType' => 'S',\n                ],\n            ],\n            'KeySchema' => [\n                [\n                    'AttributeName' => 'application',\n                    'KeyType' => 'HASH',\n                ],\n                [\n                    'AttributeName' => 'id',\n                    'KeyType' => 'RANGE',\n                ],\n            ],\n            'BillingMode' => 'PAY_PER_REQUEST',\n        ];\n\n        $this->dynamoDbClient->createTable($definition);\n\n        if (! is_null($this->ttl)) {\n            $this->dynamoDbClient->updateTimeToLive([\n                'TableName' => $this->table,\n                'TimeToLiveSpecification' => [\n                    'AttributeName' => $this->ttlAttribute,\n                    'Enabled' => true,\n                ],\n            ]);\n        }\n    }\n\n    /**\n     * Delete the underlying DynamoDB table.\n     */\n    public function deleteAwsDynamoTable(): void\n    {\n        $this->dynamoDbClient->deleteTable([\n            'TableName' => $this->table,\n        ]);\n    }\n\n    /**\n     * Get the expiry time based on the configured time-to-live.\n     *\n     * @return string|null\n     */\n    protected function getExpiryTime(): ?string\n    {\n        return is_null($this->ttl) ? null : (string) (time() + $this->ttl);\n    }\n\n    /**\n     * Get the expression attribute name for the time-to-live attribute.\n     *\n     * @return array\n     */\n    protected function ttlExpressionAttributeName(): array\n    {\n        return is_null($this->ttl) ? [] : [\"#{$this->ttlAttribute}\" => $this->ttlAttribute];\n    }\n\n    /**\n     * Serialize the given value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function serialize($value)\n    {\n        return serialize($value);\n    }\n\n    /**\n     * Unserialize the given value.\n     *\n     * @param  string  $serialized\n     * @return mixed\n     */\n    protected function unserialize($serialized)\n    {\n        return unserialize($serialized);\n    }\n\n    /**\n     * Get the underlying DynamoDB client instance.\n     *\n     * @return \\Aws\\DynamoDb\\DynamoDbClient\n     */\n    public function getDynamoClient(): DynamoDbClient\n    {\n        return $this->dynamoDbClient;\n    }\n\n    /**\n     * The name of the table that contains the batch records.\n     *\n     * @return string\n     */\n    public function getTable(): string\n    {\n        return $this->table;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Events/BatchCanceled.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus\\Events;\n\nuse Illuminate\\Bus\\Batch;\nuse Throwable;\n\nclass BatchCanceled\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Bus\\Batch  $batch  The batch instance.\n     * @param  \\Throwable|null  $exception  The exception that caused the cancellation.\n     */\n    public function __construct(\n        public Batch $batch,\n        public ?Throwable $exception = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Events/BatchDispatched.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus\\Events;\n\nuse Illuminate\\Bus\\Batch;\n\nclass BatchDispatched\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Bus\\Batch  $batch  The batch instance.\n     */\n    public function __construct(\n        public Batch $batch,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Events/BatchFinished.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus\\Events;\n\nuse Illuminate\\Bus\\Batch;\n\nclass BatchFinished\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Bus\\Batch  $batch  The batch instance.\n     */\n    public function __construct(\n        public Batch $batch,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Bus/PendingBatch.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Closure;\nuse Illuminate\\Bus\\Events\\BatchDispatched;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher as EventDispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse RuntimeException;\nuse Throwable;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass PendingBatch\n{\n    use Conditionable;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The batch name.\n     *\n     * @var string\n     */\n    public $name = '';\n\n    /**\n     * The jobs that belong to the batch.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    public $jobs;\n\n    /**\n     * The batch options.\n     *\n     * @var array\n     */\n    public $options = [];\n\n    /**\n     * Jobs that have been verified to contain the Batchable trait.\n     *\n     * @var array<class-string, bool>\n     */\n    protected static $batchableClasses = [];\n\n    /**\n     * Create a new pending batch instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @param  \\Illuminate\\Support\\Collection  $jobs\n     */\n    public function __construct(Container $container, Collection $jobs)\n    {\n        $this->container = $container;\n\n        $this->jobs = $jobs->filter()->values()->each(function (object|array $job) {\n            $this->ensureJobIsBatchable($job);\n        });\n    }\n\n    /**\n     * Add jobs to the batch.\n     *\n     * @param  iterable|object|array  $jobs\n     * @return $this\n     */\n    public function add($jobs)\n    {\n        $jobs = is_iterable($jobs) ? $jobs : Arr::wrap($jobs);\n\n        foreach ($jobs as $job) {\n            $this->ensureJobIsBatchable($job);\n\n            $this->jobs->push($job);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Ensure the given job is batchable.\n     *\n     * @param  object|array  $job\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function ensureJobIsBatchable(object|array $job): void\n    {\n        foreach (Arr::wrap($job) as $job) {\n            if ($job instanceof PendingBatch || $job instanceof Closure) {\n                return;\n            }\n\n            if (! (static::$batchableClasses[$job::class] ?? false) && ! in_array(Batchable::class, class_uses_recursive($job))) {\n                static::$batchableClasses[$job::class] = false;\n\n                throw new RuntimeException(sprintf('Attempted to batch job [%s], but it does not use the Batchable trait.', $job::class));\n            }\n\n            static::$batchableClasses[$job::class] = true;\n        }\n    }\n\n    /**\n     * Add a callback to be executed when the batch is stored.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function before($callback)\n    {\n        $this->registerCallback('before', $callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the \"before\" callbacks that have been registered with the pending batch.\n     *\n     * @return array\n     */\n    public function beforeCallbacks()\n    {\n        return $this->options['before'] ?? [];\n    }\n\n    /**\n     * Add a callback to be executed after a job in the batch have executed successfully.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function progress($callback)\n    {\n        $this->registerCallback('progress', $callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the \"progress\" callbacks that have been registered with the pending batch.\n     *\n     * @return array\n     */\n    public function progressCallbacks()\n    {\n        return $this->options['progress'] ?? [];\n    }\n\n    /**\n     * Add a callback to be executed after all jobs in the batch have executed successfully.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function then($callback)\n    {\n        $this->registerCallback('then', $callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the \"then\" callbacks that have been registered with the pending batch.\n     *\n     * @return array\n     */\n    public function thenCallbacks()\n    {\n        return $this->options['then'] ?? [];\n    }\n\n    /**\n     * Add a callback to be executed after the first failing job in the batch.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function catch($callback)\n    {\n        $this->registerCallback('catch', $callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the \"catch\" callbacks that have been registered with the pending batch.\n     *\n     * @return array\n     */\n    public function catchCallbacks()\n    {\n        return $this->options['catch'] ?? [];\n    }\n\n    /**\n     * Add a callback to be executed after the batch has finished executing.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function finally($callback)\n    {\n        $this->registerCallback('finally', $callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the \"finally\" callbacks that have been registered with the pending batch.\n     *\n     * @return array\n     */\n    public function finallyCallbacks()\n    {\n        return $this->options['finally'] ?? [];\n    }\n\n    /**\n     * Indicate that the batch should not be canceled when a job within the batch fails.\n     *\n     * Optionally, add callbacks to be executed upon each job failure.\n     *\n     * @phpstan-type TParam (Closure(\\Illuminate\\Bus\\Batch, \\Throwable|null): mixed)|(callable(\\Illuminate\\Bus\\Batch, \\Throwable|null): mixed)\n     *\n     * @param  bool|TParam|array<array-key, TParam>  $param\n     * @return $this\n     */\n    public function allowFailures($param = true)\n    {\n        if (! is_bool($param)) {\n            $param = Arr::wrap($param);\n\n            foreach ($param as $callback) {\n                if (is_callable($callback)) {\n                    $this->registerCallback('failure', $callback);\n                }\n            }\n        }\n\n        $this->options['allowFailures'] = ! ($param === false);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the pending batch allows jobs to fail without cancelling the batch.\n     *\n     * @return bool\n     */\n    public function allowsFailures()\n    {\n        return Arr::get($this->options, 'allowFailures', false) === true;\n    }\n\n    /**\n     * Get the \"failure\" callbacks that have been registered with the pending batch.\n     *\n     * @return array<array-key, Closure|callable>\n     */\n    public function failureCallbacks(): array\n    {\n        return $this->options['failure'] ?? [];\n    }\n\n    /**\n     * Register a callback with proper serialization.\n     */\n    private function registerCallback(string $type, Closure|callable $callback): void\n    {\n        $this->options[$type][] = $callback instanceof Closure\n            ? new SerializableClosure($callback)\n            : $callback;\n    }\n\n    /**\n     * Set the name for the batch.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function name(string $name)\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Specify the queue connection that the batched jobs should run on.\n     *\n     * @param  \\UnitEnum|string  $connection\n     * @return $this\n     */\n    public function onConnection(UnitEnum|string $connection)\n    {\n        $this->options['connection'] = enum_value($connection);\n\n        return $this;\n    }\n\n    /**\n     * Get the connection used by the pending batch.\n     *\n     * @return string|null\n     */\n    public function connection()\n    {\n        return $this->options['connection'] ?? null;\n    }\n\n    /**\n     * Specify the queue that the batched jobs should run on.\n     *\n     * @param  \\UnitEnum|string|null  $queue\n     * @return $this\n     */\n    public function onQueue($queue)\n    {\n        $this->options['queue'] = enum_value($queue);\n\n        return $this;\n    }\n\n    /**\n     * Get the queue used by the pending batch.\n     *\n     * @return string|null\n     */\n    public function queue()\n    {\n        return $this->options['queue'] ?? null;\n    }\n\n    /**\n     * Add additional data into the batch's options array.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function withOption(string $key, $value)\n    {\n        $this->options[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Dispatch the batch.\n     *\n     * @return \\Illuminate\\Bus\\Batch\n     *\n     * @throws \\Throwable\n     */\n    public function dispatch()\n    {\n        $repository = $this->container->make(BatchRepository::class);\n\n        try {\n            $batch = $this->store($repository);\n\n            $batch = $batch->add($this->jobs);\n        } catch (Throwable $e) {\n            if (isset($batch)) {\n                $repository->delete($batch->id);\n            }\n\n            throw $e;\n        }\n\n        $this->container->make(EventDispatcher::class)->dispatch(\n            new BatchDispatched($batch)\n        );\n\n        return $batch;\n    }\n\n    /**\n     * Dispatch the batch after the response is sent to the browser.\n     *\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function dispatchAfterResponse()\n    {\n        $repository = $this->container->make(BatchRepository::class);\n\n        $batch = $this->store($repository);\n\n        if ($batch) {\n            $this->container->terminating(function () use ($batch) {\n                $this->dispatchExistingBatch($batch);\n            });\n        }\n\n        return $batch;\n    }\n\n    /**\n     * Dispatch an existing batch.\n     *\n     * @param  \\Illuminate\\Bus\\Batch  $batch\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function dispatchExistingBatch($batch)\n    {\n        try {\n            $batch = $batch->add($this->jobs);\n        } catch (Throwable $e) {\n            $batch->delete();\n\n            throw $e;\n        }\n\n        $this->container->make(EventDispatcher::class)->dispatch(\n            new BatchDispatched($batch)\n        );\n    }\n\n    /**\n     * Dispatch the batch if the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function dispatchIf($boolean)\n    {\n        return value($boolean) ? $this->dispatch() : null;\n    }\n\n    /**\n     * Dispatch the batch unless the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function dispatchUnless($boolean)\n    {\n        return ! value($boolean) ? $this->dispatch() : null;\n    }\n\n    /**\n     * Store the batch using the given repository.\n     *\n     * @param  \\Illuminate\\Bus\\BatchRepository  $repository\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    protected function store($repository)\n    {\n        $batch = $repository->store($this);\n\n        (new Collection($this->beforeCallbacks()))->each(function ($handler) use ($batch) {\n            try {\n                return $handler($batch);\n            } catch (Throwable $e) {\n                if (function_exists('report')) {\n                    report($e);\n                }\n            }\n        });\n\n        return $batch;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/PrunableBatchRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse DateTimeInterface;\n\ninterface PrunableBatchRepository extends BatchRepository\n{\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before);\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/Queueable.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Closure;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse RuntimeException;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait Queueable\n{\n    /**\n     * The name of the connection the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $connection;\n\n    /**\n     * The name of the queue the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $queue;\n\n    /**\n     * The job \"group\" the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $messageGroup;\n\n    /**\n     * The job deduplicator callback the job should use to generate the deduplication ID.\n     *\n     * @var \\Laravel\\SerializableClosure\\SerializableClosure|null\n     */\n    public $deduplicator;\n\n    /**\n     * The number of seconds before the job should be made available.\n     *\n     * @var \\DateTimeInterface|\\DateInterval|array|int|null\n     */\n    public $delay;\n\n    /**\n     * Indicates whether the job should be dispatched after all database transactions have committed.\n     *\n     * @var bool|null\n     */\n    public $afterCommit;\n\n    /**\n     * The middleware the job should be dispatched through.\n     *\n     * @var array\n     */\n    public $middleware = [];\n\n    /**\n     * The jobs that should run if this job is successful.\n     *\n     * @var array\n     */\n    public $chained = [];\n\n    /**\n     * The name of the connection the chain should be sent to.\n     *\n     * @var string|null\n     */\n    public $chainConnection;\n\n    /**\n     * The name of the queue the chain should be sent to.\n     *\n     * @var string|null\n     */\n    public $chainQueue;\n\n    /**\n     * The callbacks to be executed on chain failure.\n     *\n     * @var array|null\n     */\n    public $chainCatchCallbacks;\n\n    /**\n     * Set the desired connection for the job.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return $this\n     */\n    public function onConnection($connection)\n    {\n        $this->connection = enum_value($connection);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the job.\n     *\n     * @param  \\UnitEnum|string|null  $queue\n     * @return $this\n     */\n    public function onQueue($queue)\n    {\n        $this->queue = enum_value($queue);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job \"group\".\n     *\n     * This feature is only supported by some queues, such as Amazon SQS.\n     *\n     * @param  \\UnitEnum|string  $group\n     * @return $this\n     */\n    public function onGroup($group)\n    {\n        $this->messageGroup = enum_value($group);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job deduplicator callback.\n     *\n     * This feature is only supported by some queues, such as Amazon SQS FIFO.\n     *\n     * @param  callable|null  $deduplicator\n     * @return $this\n     */\n    public function withDeduplicator($deduplicator)\n    {\n        $this->deduplicator = $deduplicator instanceof Closure\n            ? new SerializableClosure($deduplicator)\n            : $deduplicator;\n\n        return $this;\n    }\n\n    /**\n     * Set the desired connection for the chain.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return $this\n     */\n    public function allOnConnection($connection)\n    {\n        $resolvedConnection = enum_value($connection);\n\n        $this->chainConnection = $resolvedConnection;\n        $this->connection = $resolvedConnection;\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the chain.\n     *\n     * @param  \\UnitEnum|string|null  $queue\n     * @return $this\n     */\n    public function allOnQueue($queue)\n    {\n        $resolvedQueue = enum_value($queue);\n\n        $this->chainQueue = $resolvedQueue;\n        $this->queue = $resolvedQueue;\n\n        return $this;\n    }\n\n    /**\n     * Set the desired delay in seconds for the job.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|array|int|null  $delay\n     * @return $this\n     */\n    public function delay($delay)\n    {\n        $this->delay = $delay;\n\n        return $this;\n    }\n\n    /**\n     * Set the delay for the job to zero seconds.\n     *\n     * @return $this\n     */\n    public function withoutDelay()\n    {\n        $this->delay = 0;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should be dispatched after all database transactions have committed.\n     *\n     * @return $this\n     */\n    public function afterCommit()\n    {\n        $this->afterCommit = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should not wait until database transactions have been committed before dispatching.\n     *\n     * @return $this\n     */\n    public function beforeCommit()\n    {\n        $this->afterCommit = false;\n\n        return $this;\n    }\n\n    /**\n     * Specify the middleware the job should be dispatched through.\n     *\n     * @param  array|object  $middleware\n     * @return $this\n     */\n    public function through($middleware)\n    {\n        $this->middleware = Arr::wrap($middleware);\n\n        return $this;\n    }\n\n    /**\n     * Set the jobs that should run if this job is successful.\n     *\n     * @param  array  $chain\n     * @return $this\n     */\n    public function chain($chain)\n    {\n        $this->chained = ChainedBatch::prepareNestedBatches(new Collection($chain))\n            ->map(fn ($job) => $this->serializeJob($job))\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Prepend a job to the current chain so that it is run after the currently running job.\n     *\n     * @param  mixed  $job\n     * @return $this\n     */\n    public function prependToChain($job)\n    {\n        $jobs = ChainedBatch::prepareNestedBatches(Collection::wrap($job));\n\n        foreach ($jobs->reverse() as $job) {\n            $this->chained = Arr::prepend($this->chained, $this->serializeJob($job));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Append a job to the end of the current chain.\n     *\n     * @param  mixed  $job\n     * @return $this\n     */\n    public function appendToChain($job)\n    {\n        $jobs = ChainedBatch::prepareNestedBatches(Collection::wrap($job));\n\n        foreach ($jobs as $job) {\n            $this->chained = array_merge($this->chained, [$this->serializeJob($job)]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Serialize a job for queuing.\n     *\n     * @param  mixed  $job\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function serializeJob($job)\n    {\n        if ($job instanceof Closure) {\n            if (! class_exists(CallQueuedClosure::class)) {\n                throw new RuntimeException(\n                    'To enable support for closure jobs, please install the illuminate/queue package.'\n                );\n            }\n\n            $job = CallQueuedClosure::create($job);\n        }\n\n        return serialize($job);\n    }\n\n    /**\n     * Dispatch the next job on the chain.\n     *\n     * @return void\n     */\n    public function dispatchNextJobInChain()\n    {\n        if (is_array($this->chained) && ! empty($this->chained)) {\n            dispatch(tap(unserialize(array_shift($this->chained)), function ($next) {\n                $next->chained = $this->chained;\n\n                $next->onConnection($next->connection ?: $this->chainConnection);\n                $next->onQueue($next->queue ?: $this->chainQueue);\n\n                $next->chainConnection = $this->chainConnection;\n                $next->chainQueue = $this->chainQueue;\n                $next->chainCatchCallbacks = $this->chainCatchCallbacks;\n            }));\n        }\n    }\n\n    /**\n     * Invoke all of the chain's failed job callbacks.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function invokeChainCatchCallbacks($e)\n    {\n        (new Collection($this->chainCatchCallbacks))->each(function ($callback) use ($e) {\n            $callback($e);\n        });\n    }\n\n    /**\n     * Assert that the job has the given chain of jobs attached to it.\n     *\n     * @param  array  $expectedChain\n     * @return void\n     */\n    public function assertHasChain($expectedChain)\n    {\n        PHPUnit::assertTrue(\n            (new Collection($expectedChain))->isNotEmpty(),\n            'The expected chain can not be empty.'\n        );\n\n        if ((new Collection($expectedChain))->contains(fn ($job) => is_object($job))) {\n            $expectedChain = (new Collection($expectedChain))->map(fn ($job) => serialize($job))->all();\n        } else {\n            $chain = (new Collection($this->chained))->map(fn ($job) => get_class(unserialize($job)))->all();\n        }\n\n        PHPUnit::assertTrue(\n            $expectedChain === ($chain ?? $this->chained),\n            'The job does not have the expected chain.'\n        );\n    }\n\n    /**\n     * Assert that the job has no remaining chained jobs.\n     *\n     * @return void\n     */\n    public function assertDoesntHaveChain()\n    {\n        PHPUnit::assertEmpty($this->chained, 'The job has chained jobs.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/UniqueLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\Attributes\\UniqueFor;\n\nclass UniqueLock\n{\n    use ReadsQueueAttributes;\n\n    /**\n     * The cache repository implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * Create a new unique lock manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        $this->cache = $cache;\n    }\n\n    /**\n     * Attempt to acquire a lock for the given job.\n     *\n     * @param  mixed  $job\n     * @return bool\n     */\n    public function acquire($job)\n    {\n        $uniqueFor = method_exists($job, 'uniqueFor')\n            ? $job->uniqueFor()\n            : ($this->getAttributeValue($job, UniqueFor::class, 'uniqueFor') ?? 0);\n\n        $cache = method_exists($job, 'uniqueVia')\n            ? ($job->uniqueVia() ?? $this->cache)\n            : $this->cache;\n\n        return (bool) $cache->lock($this->getKey($job), $uniqueFor)->get();\n    }\n\n    /**\n     * Release the lock for the given job.\n     *\n     * @param  mixed  $job\n     * @return void\n     */\n    public function release($job)\n    {\n        $cache = method_exists($job, 'uniqueVia')\n            ? ($job->uniqueVia() ?? $this->cache)\n            : $this->cache;\n\n        $cache->lock($this->getKey($job))->forceRelease();\n    }\n\n    /**\n     * Generate the lock key for the given job.\n     *\n     * @param  mixed  $job\n     * @return string\n     */\n    public static function getKey($job)\n    {\n        $uniqueId = method_exists($job, 'uniqueId')\n            ? $job->uniqueId()\n            : ($job->uniqueId ?? '');\n\n        $jobName = method_exists($job, 'displayName')\n            ? hash('xxh128', $job->displayName())\n            : get_class($job);\n\n        return 'laravel_unique_job:'.$jobName.':'.$uniqueId;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/UpdatedBatchJobCounts.php",
    "content": "<?php\n\nnamespace Illuminate\\Bus;\n\nclass UpdatedBatchJobCounts\n{\n    /**\n     * The number of pending jobs remaining for the batch.\n     *\n     * @var int\n     */\n    public $pendingJobs;\n\n    /**\n     * The number of failed jobs that belong to the batch.\n     *\n     * @var int\n     */\n    public $failedJobs;\n\n    /**\n     * Create a new batch job counts object.\n     *\n     * @param  int  $pendingJobs\n     * @param  int  $failedJobs\n     */\n    public function __construct(int $pendingJobs = 0, int $failedJobs = 0)\n    {\n        $this->pendingJobs = $pendingJobs;\n        $this->failedJobs = $failedJobs;\n    }\n\n    /**\n     * Determine if all jobs have run exactly once.\n     *\n     * @return bool\n     */\n    public function allJobsHaveRanExactlyOnce()\n    {\n        return ($this->pendingJobs - $this->failedJobs) === 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Bus/composer.json",
    "content": "{\n    \"name\": \"illuminate/bus\",\n    \"description\": \"The Illuminate Bus package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/pipeline\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"illuminate/queue\": \"Required to use closures when chaining jobs (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Bus\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Cache/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Cache/ApcStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass ApcStore extends TaggableStore\n{\n    use RetrievesMultipleKeys;\n\n    /**\n     * The APC wrapper instance.\n     *\n     * @var \\Illuminate\\Cache\\ApcWrapper\n     */\n    protected $apc;\n\n    /**\n     * A string that should be prepended to keys.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * Create a new APC store.\n     *\n     * @param  \\Illuminate\\Cache\\ApcWrapper  $apc\n     * @param  string  $prefix\n     */\n    public function __construct(ApcWrapper $apc, $prefix = '')\n    {\n        $this->apc = $apc;\n        $this->prefix = $prefix;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        return $this->apc->get($this->prefix.$key);\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return $this->apc->put($this->prefix.$key, $value, $seconds);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->apc->increment($this->prefix.$key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->apc->decrement($this->prefix.$key, $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 0);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        $value = $this->apc->get($key = $this->getPrefix().$key);\n\n        if (is_null($value)) {\n            return false;\n        }\n\n        return $this->apc->put($key, $value, $seconds);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return $this->apc->delete($this->prefix.$key);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        return $this->apc->flush();\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * Set the cache key prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = $prefix;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/ApcWrapper.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass ApcWrapper\n{\n    /**\n     * Get an item from the cache.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        $fetchedValue = apcu_fetch($key, $success);\n\n        return $success ? $fetchedValue : null;\n    }\n\n    /**\n     * Store an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return apcu_store($key, $value, $seconds);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function increment($key, $value)\n    {\n        return apcu_inc($key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function decrement($key, $value)\n    {\n        return apcu_dec($key, $value);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function delete($key)\n    {\n        return apcu_delete($key);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        return apcu_clear_cache();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/ArrayLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Support\\Carbon;\n\nclass ArrayLock extends Lock\n{\n    /**\n     * The parent array cache store.\n     *\n     * @var \\Illuminate\\Cache\\ArrayStore\n     */\n    protected $store;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Illuminate\\Cache\\ArrayStore  $store\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct($store, $name, $seconds, $owner = null)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->store = $store;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        $expiration = $this->store->locks[$this->name]['expiresAt'] ?? Carbon::now()->addSecond();\n\n        if ($this->exists() && $expiration->isFuture()) {\n            return false;\n        }\n\n        $this->store->locks[$this->name] = [\n            'owner' => $this->owner,\n            'expiresAt' => $this->seconds === 0 ? null : Carbon::now()->addSeconds($this->seconds),\n        ];\n\n        return true;\n    }\n\n    /**\n     * Determine if the current lock exists.\n     *\n     * @return bool\n     */\n    protected function exists()\n    {\n        return isset($this->store->locks[$this->name]);\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        if (! $this->exists()) {\n            return false;\n        }\n\n        if (! $this->isOwnedByCurrentProcess()) {\n            return false;\n        }\n\n        $this->forceRelease();\n\n        return true;\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return string|null\n     */\n    protected function getCurrentOwner()\n    {\n        if (! $this->exists()) {\n            return null;\n        }\n\n        return $this->store->locks[$this->name]['owner'];\n    }\n\n    /**\n     * Releases this lock regardless of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        unset($this->store->locks[$this->name]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/ArrayStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\CanFlushLocks;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\InteractsWithTime;\nuse RuntimeException;\n\nclass ArrayStore extends TaggableStore implements CanFlushLocks, LockProvider\n{\n    use InteractsWithTime, RetrievesMultipleKeys;\n\n    /**\n     * The array of stored values.\n     *\n     * @var array<string, array{value: mixed, expiresAt: float}>\n     */\n    protected $storage = [];\n\n    /**\n     * The array of locks.\n     *\n     * @var array<string, array{owner: ?string, expiresAt: ?\\Illuminate\\Support\\Carbon}>\n     */\n    public $locks = [];\n\n    /**\n     * Indicates if values are serialized within the store.\n     *\n     * @var bool\n     */\n    protected $serializesValues;\n\n    /**\n     * The classes that should be allowed during unserialization.\n     *\n     * @var array|bool|null\n     */\n    protected $serializableClasses;\n\n    /**\n     * Create a new Array store.\n     *\n     * @param  bool  $serializesValues\n     * @param  array|bool|null  $serializableClasses\n     */\n    public function __construct($serializesValues = false, $serializableClasses = null)\n    {\n        $this->serializesValues = $serializesValues;\n        $this->serializableClasses = $serializableClasses;\n    }\n\n    /**\n     * Get all of the cached values and their expiration times.\n     *\n     * @param  bool  $unserialize\n     * @return array<string, array{value: mixed, expiresAt: float}>\n     */\n    public function all($unserialize = true)\n    {\n        if ($unserialize === false || $this->serializesValues === false) {\n            return $this->storage;\n        }\n\n        $storage = [];\n\n        foreach ($this->storage as $key => $data) {\n            $storage[$key] = [\n                'value' => $this->unserialize($data['value']),\n                'expiresAt' => $data['expiresAt'],\n            ];\n        }\n\n        return $storage;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        if (! isset($this->storage[$key])) {\n            return;\n        }\n\n        $item = $this->storage[$key];\n\n        $expiresAt = $item['expiresAt'] ?? 0;\n\n        if ($expiresAt !== 0 && (Carbon::now()->getPreciseTimestamp(3) / 1000) >= $expiresAt) {\n            $this->forget($key);\n\n            return;\n        }\n\n        return $this->serializesValues ? $this->unserialize($item['value']) : $item['value'];\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        $this->storage[$key] = [\n            'value' => $this->serializesValues ? serialize($value) : $value,\n            'expiresAt' => $this->calculateExpiration($seconds),\n        ];\n\n        return true;\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function increment($key, $value = 1)\n    {\n        if (! is_null($existing = $this->get($key))) {\n            return tap(((int) $existing) + $value, function ($incremented) use ($key) {\n                $value = $this->serializesValues ? serialize($incremented) : $incremented;\n\n                $this->storage[$key]['value'] = $value;\n            });\n        }\n\n        $this->forever($key, $value);\n\n        return $value;\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->increment($key, $value * -1);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 0);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        $item = Arr::get($this->storage, $key = $this->getPrefix().$key, null);\n\n        if (is_null($item)) {\n            return false;\n        }\n\n        $item['expiresAt'] = $this->calculateExpiration($seconds);\n\n        $this->storage = array_merge($this->storage, [$key => $item]);\n\n        return true;\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        if (array_key_exists($key, $this->storage)) {\n            unset($this->storage[$key]);\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->storage = [];\n\n        return true;\n    }\n\n    /**\n     * Remove all locks from the store.\n     *\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function flushLocks(): bool\n    {\n        if (! $this->hasSeparateLockStore()) {\n            throw new RuntimeException('Flushing locks is only supported when the lock store is separate from the cache store.');\n        }\n\n        $this->locks = [];\n\n        return true;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return '';\n    }\n\n    /**\n     * Get the expiration time of the key.\n     *\n     * @param  int  $seconds\n     * @return float\n     */\n    protected function calculateExpiration($seconds)\n    {\n        return $this->toTimestamp($seconds);\n    }\n\n    /**\n     * Get the UNIX timestamp, with milliseconds, for the given number of seconds in the future.\n     *\n     * @param  int  $seconds\n     * @return float\n     */\n    protected function toTimestamp($seconds)\n    {\n        return $seconds > 0 ? (Carbon::now()->getPreciseTimestamp(3) / 1000) + $seconds : 0;\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new ArrayLock($this, $name, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Determine if the lock store is separate from the cache store.\n     *\n     * @return bool\n     */\n    public function hasSeparateLockStore(): bool\n    {\n        return true;\n    }\n\n    /**\n     * Unserialize the given value.\n     *\n     * @param  string  $value\n     * @return mixed\n     */\n    protected function unserialize($value)\n    {\n        if ($this->serializableClasses !== null) {\n            return unserialize($value, ['allowed_classes' => $this->serializableClasses]);\n        }\n\n        return unserialize($value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/CacheLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass CacheLock extends Lock\n{\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Store\n     */\n    protected $store;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct($store, $name, $seconds, $owner = null)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->store = $store;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        if (method_exists($this->store, 'add') && $this->seconds > 0) {\n            return $this->store->add(\n                $this->name, $this->owner, $this->seconds\n            );\n        }\n\n        if (! is_null($this->store->get($this->name))) {\n            return false;\n        }\n\n        return ($this->seconds > 0)\n            ? $this->store->put($this->name, $this->owner, $this->seconds)\n            : $this->store->forever($this->name, $this->owner);\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        if ($this->isOwnedByCurrentProcess()) {\n            return $this->store->forget($this->name);\n        }\n\n        return false;\n    }\n\n    /**\n     * Releases this lock regardless of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        $this->store->forget($this->name);\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return mixed\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->store->get($this->name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/CacheManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Closure;\nuse Illuminate\\Contracts\\Cache\\Factory as FactoryContract;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Support\\Arr;\nuse InvalidArgumentException;\nuse Mockery;\nuse Mockery\\LegacyMockInterface;\n\n/**\n * @mixin \\Illuminate\\Cache\\Repository\n * @mixin \\Illuminate\\Contracts\\Cache\\LockProvider\n */\nclass CacheManager implements FactoryContract\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of resolved cache stores.\n     *\n     * @var array\n     */\n    protected $stores = [];\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * Create a new Cache manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Get a cache store instance by name, wrapped in a repository.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function store($name = null)\n    {\n        $name = $name ?? $this->getDefaultDriver();\n\n        return $this->stores[$name] ??= $this->resolve($name);\n    }\n\n    /**\n     * Get a cache driver instance.\n     *\n     * @param  string|null  $driver\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function driver($driver = null)\n    {\n        return $this->store($driver);\n    }\n\n    /**\n     * Get a memoized cache driver instance.\n     *\n     * @param  string|null  $driver\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function memo($driver = null)\n    {\n        $driver = $driver ?? $this->getDefaultDriver();\n\n        $bindingKey = \"cache.__memoized:{$driver}\";\n\n        $isSpy = isset($this->app['cache']) && $this->app['cache'] instanceof LegacyMockInterface;\n\n        $this->app->scopedIf($bindingKey, function () use ($driver, $isSpy) {\n            $repository = $this->repository(\n                new MemoizedStore($driver, $this->store($driver)), ['events' => false]\n            );\n\n            return $isSpy ? Mockery::spy($repository) : $repository;\n        });\n\n        return $this->app->make($bindingKey);\n    }\n\n    /**\n     * Resolve the given store.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Cache store [{$name}] is not defined.\");\n        }\n\n        $config = Arr::add($config, 'store', $name);\n\n        return $this->build($config);\n    }\n\n    /**\n     * Build a cache repository with the given configuration.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function build(array $config)\n    {\n        $config = Arr::add($config, 'store', $config['name'] ?? 'ondemand');\n\n        if (isset($this->customCreators[$config['driver']])) {\n            return $this->callCustomCreator($config);\n        }\n\n        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';\n\n        if (method_exists($this, $driverMethod)) {\n            return $this->{$driverMethod}($config);\n        }\n\n        throw new InvalidArgumentException(\"Driver [{$config['driver']}] is not supported.\");\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  array  $config\n     * @return mixed\n     */\n    protected function callCustomCreator(array $config)\n    {\n        return $this->customCreators[$config['driver']]($this->app, $config);\n    }\n\n    /**\n     * Create an instance of the APC cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createApcDriver(array $config)\n    {\n        $prefix = $this->getPrefix($config);\n\n        return $this->repository(new ApcStore(new ApcWrapper, $prefix), $config);\n    }\n\n    /**\n     * Create an instance of the array cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createArrayDriver(array $config)\n    {\n        return $this->repository(new ArrayStore(\n            $config['serialize'] ?? false,\n            $this->getSerializableClasses($config),\n        ), $config);\n    }\n\n    /**\n     * Create an instance of the database cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createDatabaseDriver(array $config)\n    {\n        $connection = $this->app['db']->connection($config['connection'] ?? null);\n\n        $store = new DatabaseStore(\n            $connection,\n            $config['table'],\n            $this->getPrefix($config),\n            $config['lock_table'] ?? 'cache_locks',\n            $config['lock_lottery'] ?? [2, 100],\n            $config['lock_timeout'] ?? 86400,\n            $this->getSerializableClasses($config),\n        );\n\n        return $this->repository(\n            $store->setLockConnection(\n                $this->app['db']->connection($config['lock_connection'] ?? $config['connection'] ?? null)\n            ),\n            $config\n        );\n    }\n\n    /**\n     * Create an instance of the DynamoDB cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createDynamodbDriver(array $config)\n    {\n        $client = $this->newDynamodbClient($config);\n\n        return $this->repository(\n            new DynamoDbStore(\n                $client,\n                $config['table'],\n                $config['attributes']['key'] ?? 'key',\n                $config['attributes']['value'] ?? 'value',\n                $config['attributes']['expiration'] ?? 'expires_at',\n                $this->getPrefix($config),\n                $this->getSerializableClasses($config),\n            ),\n            $config\n        );\n    }\n\n    /**\n     * Create new DynamoDb Client instance.\n     *\n     * @return \\Aws\\DynamoDb\\DynamoDbClient\n     */\n    protected function newDynamodbClient(array $config)\n    {\n        $dynamoConfig = [\n            'region' => $config['region'],\n            'version' => 'latest',\n            'endpoint' => $config['endpoint'] ?? null,\n        ];\n\n        if (! empty($config['key']) && ! empty($config['secret'])) {\n            $dynamoConfig['credentials'] = Arr::only(\n                $config, ['key', 'secret']\n            );\n\n            if (! empty($config['token'])) {\n                $dynamoConfig['credentials']['token'] = $config['token'];\n            }\n        }\n\n        return new DynamoDbClient($dynamoConfig);\n    }\n\n    /**\n     * Create an instance of the failover cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createFailoverDriver(array $config)\n    {\n        return $this->repository(new FailoverStore(\n            $this,\n            $this->app->make(DispatcherContract::class),\n            $config['stores']\n        ), ['events' => false, ...$config]);\n    }\n\n    /**\n     * Create an instance of the file cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createFileDriver(array $config)\n    {\n        return $this->repository(\n            (new FileStore(\n                $this->app['files'],\n                $config['path'],\n                $config['permission'] ?? null,\n                $this->getSerializableClasses($config),\n            ))\n                ->setLockDirectory($config['lock_path'] ?? null),\n            $config\n        );\n    }\n\n    /**\n     * Create an instance of the Memcached cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createMemcachedDriver(array $config)\n    {\n        $prefix = $this->getPrefix($config);\n\n        $memcached = $this->app['memcached.connector']->connect(\n            $config['servers'],\n            $config['persistent_id'] ?? null,\n            $config['options'] ?? [],\n            array_filter($config['sasl'] ?? [])\n        );\n\n        return $this->repository(new MemcachedStore($memcached, $prefix), $config);\n    }\n\n    /**\n     * Create an instance of the Null cache driver.\n     *\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createNullDriver()\n    {\n        return $this->repository(new NullStore, []);\n    }\n\n    /**\n     * Create an instance of the Redis cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createRedisDriver(array $config)\n    {\n        $redis = $this->app['redis'];\n\n        $connection = $config['connection'] ?? 'default';\n\n        $store = new RedisStore(\n            $redis,\n            $this->getPrefix($config),\n            $connection,\n            $this->getSerializableClasses($config),\n        );\n\n        return $this->repository(\n            $store->setLockConnection($config['lock_connection'] ?? $connection),\n            $config\n        );\n    }\n\n    /**\n     * Create an instance of the session cache driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function createSessionDriver(array $config)\n    {\n        return $this->repository(\n            new SessionStore(\n                $this->getSession(),\n                $config['key'] ?? '_cache',\n            ),\n            $config\n        );\n    }\n\n    /**\n     * Get the session store implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Session\\Session\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function getSession()\n    {\n        $session = $this->app['session'] ?? null;\n\n        if (! $session) {\n            throw new InvalidArgumentException('Session store requires session manager to be available in container.');\n        }\n\n        return $session;\n    }\n\n    /**\n     * Create a new cache repository with the given implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @param  array  $config\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    public function repository(Store $store, array $config = [])\n    {\n        return tap(new Repository($store, Arr::only($config, ['store'])), function ($repository) use ($config) {\n            if ($config['events'] ?? true) {\n                $this->setEventDispatcher($repository);\n            }\n        });\n    }\n\n    /**\n     * Set the event dispatcher on the given repository instance.\n     *\n     * @param  \\Illuminate\\Cache\\Repository  $repository\n     * @return void\n     */\n    protected function setEventDispatcher(Repository $repository)\n    {\n        if (! $this->app->bound(DispatcherContract::class)) {\n            return;\n        }\n\n        $repository->setEventDispatcher(\n            $this->app[DispatcherContract::class]\n        );\n    }\n\n    /**\n     * Re-set the event dispatcher on all resolved cache repositories.\n     *\n     * @return void\n     */\n    public function refreshEventDispatcher()\n    {\n        array_map($this->setEventDispatcher(...), $this->stores);\n    }\n\n    /**\n     * Get the cache prefix.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getPrefix(array $config)\n    {\n        return $config['prefix'] ?? $this->app['config']['cache.prefix'];\n    }\n\n    /**\n     * Get the classes that should be allowed during unserialization.\n     *\n     * @param  array  $config\n     * @return array|bool|null\n     */\n    protected function getSerializableClasses(array $config)\n    {\n        return $this->app['config']['cache.serializable_classes'] ?? null;\n    }\n\n    /**\n     * Get the cache connection configuration.\n     *\n     * @param  string  $name\n     * @return array|null\n     */\n    protected function getConfig($name)\n    {\n        return $name !== 'null'\n            ? $this->app['config'][\"cache.stores.{$name}\"]\n            : ['driver' => 'null'];\n    }\n\n    /**\n     * Get the default cache driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['cache.default'] ?? 'null';\n    }\n\n    /**\n     * Set the default cache driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['cache.default'] = $name;\n    }\n\n    /**\n     * Unset the given driver instances.\n     *\n     * @param  array|string|null  $name\n     * @return $this\n     */\n    public function forgetDriver($name = null)\n    {\n        $name ??= $this->getDefaultDriver();\n\n        foreach ((array) $name as $cacheName) {\n            if (isset($this->stores[$cacheName])) {\n                unset($this->stores[$cacheName]);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Disconnect the given driver and remove from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name ??= $this->getDefaultDriver();\n\n        unset($this->stores[$name]);\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->store()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/CacheServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\nuse Symfony\\Component\\Cache\\Adapter\\Psr16Adapter;\n\nclass CacheServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('cache', function ($app) {\n            return new CacheManager($app);\n        });\n\n        $this->app->singleton('cache.store', function ($app) {\n            return $app['cache']->driver();\n        });\n\n        $this->app->singleton('cache.psr6', function ($app) {\n            return new Psr16Adapter($app['cache.store']);\n        });\n\n        $this->app->singleton('memcached.connector', function () {\n            return new MemcachedConnector;\n        });\n\n        $this->app->singleton(RateLimiter::class, function ($app) {\n            return new RateLimiter($app->make('cache')->driver(\n                $app['config']->get('cache.limiter')\n            ));\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            'cache', 'cache.store', 'cache.psr6', 'memcached.connector', RateLimiter::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Console/CacheTableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'make:cache-table', aliases: ['cache:table'])]\nclass CacheTableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:cache-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['cache:table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the cache database table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return 'cache';\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/cache.stub';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Console/ClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Console;\n\nuse BadMethodCallException;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'cache:clear')]\nclass ClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'cache:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Flush the application cache';\n\n    /**\n     * The cache manager instance.\n     *\n     * @var \\Illuminate\\Cache\\CacheManager\n     */\n    protected $cache;\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new cache clear command instance.\n     *\n     * @param  \\Illuminate\\Cache\\CacheManager  $cache\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(CacheManager $cache, Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->cache = $cache;\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->option('locks')) {\n            return $this->clearLocks();\n        }\n\n        $this->laravel['events']->dispatch(\n            'cache:clearing', [$this->argument('store'), $this->tags()]\n        );\n\n        $successful = $this->cache()->flush();\n\n        $this->flushFacades();\n\n        if (! $successful) {\n            $this->components->error('Failed to clear cache. Make sure you have the appropriate permissions.');\n\n            return self::FAILURE;\n        }\n\n        $this->laravel['events']->dispatch(\n            'cache:cleared', [$this->argument('store'), $this->tags()]\n        );\n\n        $this->components->info('Application cache cleared successfully.');\n\n        return self::SUCCESS;\n    }\n\n    /**\n     * Clear all locks from the cache store.\n     *\n     * @return int\n     */\n    protected function clearLocks()\n    {\n        if (! empty($this->tags())) {\n            $this->components->error('Cache tags cannot be used when clearing locks.');\n\n            return self::FAILURE;\n        }\n\n        try {\n            $successful = $this->cache()->flushLocks();\n        } catch (BadMethodCallException) {\n            $this->components->error('This cache store does not support clearing locks.');\n\n            return self::FAILURE;\n        }\n\n        if (! $successful) {\n            $this->components->error('Failed to clear cache locks. Make sure you have the appropriate permissions.');\n\n            return self::FAILURE;\n        }\n\n        $this->components->info('Application cache locks cleared successfully.');\n\n        return self::SUCCESS;\n    }\n\n    /**\n     * Flush the real-time facades stored in the cache directory.\n     *\n     * @return void\n     */\n    public function flushFacades()\n    {\n        if (! $this->files->exists($storagePath = storage_path('framework/cache'))) {\n            return;\n        }\n\n        foreach ($this->files->files($storagePath) as $file) {\n            if (preg_match('/facade-.*\\.php$/', $file)) {\n                $this->files->delete($file);\n            }\n        }\n    }\n\n    /**\n     * Get the cache instance for the command.\n     *\n     * @return \\Illuminate\\Cache\\Repository\n     */\n    protected function cache()\n    {\n        $cache = $this->cache->store($this->argument('store'));\n\n        return empty($this->tags()) ? $cache : $cache->tags($this->tags());\n    }\n\n    /**\n     * Get the tags passed to the command.\n     *\n     * @return array\n     */\n    protected function tags()\n    {\n        return array_filter(explode(',', $this->option('tags') ?? ''));\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getArguments()\n    {\n        return [\n            ['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear'],\n        ];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['tags', null, InputOption::VALUE_OPTIONAL, 'The cache tags you would like to clear', null],\n            ['locks', null, InputOption::VALUE_NONE, 'Only clear cache locks'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Console/ForgetCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Console;\n\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'cache:forget')]\nclass ForgetCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'cache:forget {key : The key to remove} {store? : The store to remove the key from}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Remove an item from the cache';\n\n    /**\n     * The cache manager instance.\n     *\n     * @var \\Illuminate\\Cache\\CacheManager\n     */\n    protected $cache;\n\n    /**\n     * Create a new cache clear command instance.\n     *\n     * @param  \\Illuminate\\Cache\\CacheManager  $cache\n     */\n    public function __construct(CacheManager $cache)\n    {\n        parent::__construct();\n\n        $this->cache = $cache;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->cache->store($this->argument('store'))->forget(\n            $this->argument('key')\n        );\n\n        $this->components->info('The ['.$this->argument('key').'] key has been removed from the cache.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Console/PruneStaleTagsCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Console;\n\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\n\n#[AsCommand(name: 'cache:prune-stale-tags')]\nclass PruneStaleTagsCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'cache:prune-stale-tags';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Prune stale cache tags from the cache (Redis only)';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Cache\\CacheManager  $cache\n     * @return int|null\n     */\n    public function handle(CacheManager $cache)\n    {\n        $cache = $cache->store($this->argument('store'));\n\n        if (method_exists($cache->getStore(), 'flushStaleTags')) {\n            $cache->flushStaleTags();\n        }\n\n        $this->components->info('Stale cache tags pruned successfully.');\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getArguments()\n    {\n        return [\n            ['store', InputArgument::OPTIONAL, 'The name of the store you would like to prune tags from'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Console/stubs/cache.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('cache', function (Blueprint $table) {\n            $table->string('key')->primary();\n            $table->mediumText('value');\n            $table->bigInteger('expiration')->index();\n        });\n\n        Schema::create('cache_locks', function (Blueprint $table) {\n            $table->string('key')->primary();\n            $table->string('owner');\n            $table->bigInteger('expiration')->index();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('cache');\n        Schema::dropIfExists('cache_locks');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Cache/DatabaseLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\DetectsConcurrencyErrors;\nuse Illuminate\\Database\\QueryException;\nuse Throwable;\n\nclass DatabaseLock extends Lock\n{\n    use DetectsConcurrencyErrors;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * The database table name.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The prune probability odds.\n     *\n     * @var array{int, int}|null\n     */\n    protected $lottery;\n\n    /**\n     * The default number of seconds that a lock should be held.\n     *\n     * @var int\n     */\n    protected $defaultTimeoutInSeconds;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $table\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @param  array{int, int}|null  $lottery\n     * @param  int  $defaultTimeoutInSeconds\n     */\n    public function __construct(Connection $connection, $table, $name, $seconds, $owner = null, $lottery = [2, 100], $defaultTimeoutInSeconds = 86400)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->connection = $connection;\n        $this->table = $table;\n        $this->lottery = $lottery;\n        $this->defaultTimeoutInSeconds = $defaultTimeoutInSeconds;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     *\n     * @throws \\Throwable\n     */\n    public function acquire()\n    {\n        try {\n            $this->connection->table($this->table)->insert([\n                'key' => $this->name,\n                'owner' => $this->owner,\n                'expiration' => $this->expiresAt(),\n            ]);\n\n            $acquired = true;\n        } catch (QueryException) {\n            $updated = $this->connection->table($this->table)\n                ->where('key', $this->name)\n                ->where(function ($query) {\n                    return $query->where('owner', $this->owner)->orWhere('expiration', '<=', $this->currentTime());\n                })->update([\n                    'owner' => $this->owner,\n                    'expiration' => $this->expiresAt(),\n                ]);\n\n            $acquired = $updated >= 1;\n        }\n\n        if (count($this->lottery ?? []) === 2 && random_int(1, $this->lottery[1]) <= $this->lottery[0]) {\n            $this->pruneExpiredLocks();\n        }\n\n        return $acquired;\n    }\n\n    /**\n     * Get the UNIX timestamp indicating when the lock should expire.\n     *\n     * @return int\n     */\n    protected function expiresAt()\n    {\n        $lockTimeout = $this->seconds > 0 ? $this->seconds : $this->defaultTimeoutInSeconds;\n\n        return $this->currentTime() + $lockTimeout;\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     *\n     * @throws \\Throwable\n     */\n    public function release()\n    {\n        if ($this->isOwnedByCurrentProcess()) {\n            try {\n                $this->connection->table($this->table)\n                    ->where('key', $this->name)\n                    ->where('owner', $this->owner)\n                    ->delete();\n\n                return true;\n            } catch (Throwable $e) {\n                if ($this->causedByConcurrencyError($e)) {\n                    return true;\n                }\n\n                throw $e;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Releases this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        $this->connection->table($this->table)\n            ->where('key', $this->name)\n            ->delete();\n    }\n\n    /**\n     * Deletes locks that are past expiration.\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function pruneExpiredLocks()\n    {\n        try {\n            $this->connection->table($this->table)\n                ->where('expiration', '<=', $this->currentTime())\n                ->delete();\n        } catch (Throwable $e) {\n            if (! $this->causedByConcurrencyError($e)) {\n                throw $e;\n            }\n        }\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return string|null\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->connection->table($this->table)->where('key', $this->name)->first()?->owner;\n    }\n\n    /**\n     * Get the name of the database connection being used to manage the lock.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return $this->connection->getName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/DatabaseStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Closure;\nuse Illuminate\\Contracts\\Cache\\CanFlushLocks;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Illuminate\\Database\\SqlServerConnection;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse RuntimeException;\n\nclass DatabaseStore implements CanFlushLocks, LockProvider, Store\n{\n    use InteractsWithTime;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected $connection;\n\n    /**\n     * The database connection instance that should be used to manage locks.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected $lockConnection;\n\n    /**\n     * The name of the cache table.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * A string that should be prepended to keys.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * The name of the cache locks table.\n     *\n     * @var string\n     */\n    protected $lockTable;\n\n    /**\n     * An array representation of the lock lottery odds.\n     *\n     * @var array\n     */\n    protected $lockLottery;\n\n    /**\n     * The default number of seconds that a lock should be held.\n     *\n     * @var int\n     */\n    protected $defaultLockTimeoutInSeconds;\n\n    /**\n     * The classes that should be allowed during unserialization.\n     *\n     * @var array|bool|null\n     */\n    protected $serializableClasses;\n\n    /**\n     * Create a new database store.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  string  $table\n     * @param  string  $prefix\n     * @param  string  $lockTable\n     * @param  array  $lockLottery\n     * @param  int  $defaultLockTimeoutInSeconds\n     * @param  array|bool|null  $serializableClasses\n     */\n    public function __construct(\n        ConnectionInterface $connection,\n        $table,\n        $prefix = '',\n        $lockTable = 'cache_locks',\n        $lockLottery = [2, 100],\n        $defaultLockTimeoutInSeconds = 86400,\n        $serializableClasses = null,\n    ) {\n        $this->table = $table;\n        $this->prefix = $prefix;\n        $this->connection = $connection;\n        $this->lockTable = $lockTable;\n        $this->lockLottery = $lockLottery;\n        $this->defaultLockTimeoutInSeconds = $defaultLockTimeoutInSeconds;\n        $this->serializableClasses = $serializableClasses;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        return $this->many([$key])[$key];\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        if (count($keys) === 0) {\n            return [];\n        }\n\n        $results = array_fill_keys($keys, null);\n\n        // First we will retrieve all of the items from the cache using their keys and\n        // the prefix value. Then we will need to iterate through each of the items\n        // and convert them to an object when they are currently in array format.\n        $values = $this->table()\n            ->whereIn('key', array_map(function ($key) {\n                return $this->prefix.$key;\n            }, $keys))\n            ->get()\n            ->map(function ($value) {\n                return is_array($value) ? (object) $value : $value;\n            });\n\n        $currentTime = $this->currentTime();\n\n        // If this cache expiration date is past the current time, we will remove this\n        // item from the cache. Then we will return a null value since the cache is\n        // expired. We will use \"Carbon\" to make this comparison with the column.\n        [$values, $expired] = $values->partition(function ($cache) use ($currentTime) {\n            return $cache->expiration > $currentTime;\n        });\n\n        if ($expired->isNotEmpty()) {\n            $this->forgetManyIfExpired($expired->pluck('key')->all(), prefixed: true);\n        }\n\n        return Arr::map($results, function ($value, $key) use ($values) {\n            if ($cache = $values->firstWhere('key', $this->prefix.$key)) {\n                return $this->unserialize($cache->value);\n            }\n\n            return $value;\n        });\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return $this->putMany([$key => $value], $seconds);\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        $serializedValues = [];\n\n        $expiration = $this->getTime() + $seconds;\n\n        foreach ($values as $key => $value) {\n            $serializedValues[] = [\n                'key' => $this->prefix.$key,\n                'value' => $this->serialize($value),\n                'expiration' => $expiration,\n            ];\n        }\n\n        return $this->table()->upsert($serializedValues, 'key') > 0;\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function add($key, $value, $seconds)\n    {\n        if (! is_null($this->get($key))) {\n            return false;\n        }\n\n        $key = $this->prefix.$key;\n        $value = $this->serialize($value);\n        $expiration = $this->getTime() + $seconds;\n\n        if (! $this->getConnection() instanceof SqlServerConnection) {\n            return $this->table()->insertOrIgnore(compact('key', 'value', 'expiration')) > 0;\n        }\n\n        try {\n            return $this->table()->insert(compact('key', 'value', 'expiration'));\n        } catch (QueryException) {\n            // ...\n        }\n\n        return false;\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->incrementOrDecrement($key, $value, function ($current, $value) {\n            return $current + $value;\n        });\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int  $value\n     * @return int|false\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->incrementOrDecrement($key, $value, function ($current, $value) {\n            return $current - $value;\n        });\n    }\n\n    /**\n     * Increment or decrement an item in the cache.\n     *\n     * @param  string  $key\n     * @param  int|float  $value\n     * @param  \\Closure  $callback\n     * @return int|false\n     */\n    protected function incrementOrDecrement($key, $value, Closure $callback)\n    {\n        return $this->connection->transaction(function () use ($key, $value, $callback) {\n            $prefixed = $this->prefix.$key;\n\n            $cache = $this->table()->where('key', $prefixed)\n                ->lockForUpdate()->first();\n\n            // If there is no value in the cache, we will return false here. Otherwise the\n            // value will be decrypted and we will proceed with this function to either\n            // increment or decrement this value based on the given action callbacks.\n            if (is_null($cache)) {\n                return false;\n            }\n\n            $cache = is_array($cache) ? (object) $cache : $cache;\n\n            $current = $this->unserialize($cache->value);\n\n            // Here we'll call this callback function that was given to the function which\n            // is used to either increment or decrement the function. We use a callback\n            // so we do not have to recreate all this logic in each of the functions.\n            $new = $callback((int) $current, $value);\n\n            if (! is_numeric($current)) {\n                return false;\n            }\n\n            // Here we will update the values in the table. We will also encrypt the value\n            // since database cache values are encrypted by default with secure storage\n            // that can't be easily read. We will return the new value after storing.\n            $this->table()->where('key', $prefixed)->update([\n                'value' => $this->serialize($new),\n            ]);\n\n            return $new;\n        });\n    }\n\n    /**\n     * Get the current system time.\n     *\n     * @return int\n     */\n    protected function getTime()\n    {\n        return $this->currentTime();\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 315360000);\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new DatabaseLock(\n            $this->lockConnection ?? $this->connection,\n            $this->lockTable,\n            $this->prefix.$name,\n            $seconds,\n            $owner,\n            $this->lockLottery,\n            $this->defaultLockTimeoutInSeconds\n        );\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        return (bool) $this->table()\n            ->where('key', '=', $this->getPrefix().$key)\n            ->where('expiration', '>', $now = $this->getTime())\n            ->update(['expiration' => $now + $seconds]);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return $this->forgetMany([$key]);\n    }\n\n    /**\n     * Remove an item from the cache if it is expired.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forgetIfExpired($key)\n    {\n        return $this->forgetManyIfExpired([$key]);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @param  array  $keys\n     * @return bool\n     */\n    protected function forgetMany(array $keys)\n    {\n        $this->table()->whereIn('key', (new Collection($keys))->flatMap(fn ($key) => [\n            $this->prefix.$key,\n            \"{$this->prefix}illuminate:cache:flexible:created:{$key}\",\n        ])->all())->delete();\n\n        return true;\n    }\n\n    /**\n     * Remove all expired items from the given set from the cache.\n     *\n     * @param  array  $keys\n     * @param  bool  $prefixed\n     * @return bool\n     */\n    protected function forgetManyIfExpired(array $keys, bool $prefixed = false)\n    {\n        $this->table()\n            ->whereIn('key', (new Collection($keys))->flatMap(fn ($key) => $prefixed ? [\n                $key,\n                $this->prefix.'illuminate:cache:flexible:created:'.Str::chopStart($key, $this->prefix),\n            ] : [\n                \"{$this->prefix}{$key}\",\n                \"{$this->prefix}illuminate:cache:flexible:created:{$key}\",\n            ])->all())\n            ->where('expiration', '<=', $this->getTime())\n            ->delete();\n\n        return true;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->table()->delete();\n\n        return true;\n    }\n\n    /**\n     * Remove all locks from the store.\n     *\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function flushLocks(): bool\n    {\n        if (! $this->hasSeparateLockStore()) {\n            throw new RuntimeException('Flushing locks is only supported when the lock store is separate from the cache store.');\n        }\n\n        $this->lockTable()->delete();\n\n        return true;\n    }\n\n    /**\n     * Get a query builder for the cache table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function table()\n    {\n        return $this->connection->table($this->table);\n    }\n\n    /**\n     * Get a query builder for the cache locks table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function lockTable()\n    {\n        return $this->lockConnection->table($this->lockTable);\n    }\n\n    /**\n     * Get the underlying database connection.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Set the underlying database connection.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @return $this\n     */\n    public function setConnection($connection)\n    {\n        $this->connection = $connection;\n\n        return $this;\n    }\n\n    /**\n     * Get the connection used to manage locks.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function getLockConnection()\n    {\n        return $this->lockConnection;\n    }\n\n    /**\n     * Specify the connection that should be used to manage locks.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @return $this\n     */\n    public function setLockConnection($connection)\n    {\n        $this->lockConnection = $connection;\n\n        return $this;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * Set the cache key prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = $prefix;\n    }\n\n    /**\n     * Serialize the given value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function serialize($value)\n    {\n        $result = serialize($value);\n\n        if (($this->connection instanceof PostgresConnection ||\n             $this->connection instanceof SQLiteConnection) &&\n            str_contains($result, \"\\0\")) {\n            $result = base64_encode($result);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Unserialize the given value.\n     *\n     * @param  string  $value\n     * @return mixed\n     */\n    protected function unserialize($value)\n    {\n        if (($this->connection instanceof PostgresConnection ||\n             $this->connection instanceof SQLiteConnection) &&\n            ! Str::contains($value, [':', ';'])) {\n            $value = base64_decode($value);\n        }\n\n        if ($this->serializableClasses !== null) {\n            return unserialize($value, ['allowed_classes' => $this->serializableClasses]);\n        }\n\n        return unserialize($value);\n    }\n\n    /**\n     * Determine if the lock store is separate from the cache store.\n     *\n     * @return bool\n     */\n    public function hasSeparateLockStore(): bool\n    {\n        return $this->lockTable !== $this->table;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/DynamoDbLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass DynamoDbLock extends Lock\n{\n    /**\n     * The DynamoDB client instance.\n     *\n     * @var \\Illuminate\\Cache\\DynamoDbStore\n     */\n    protected $dynamo;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Illuminate\\Cache\\DynamoDbStore  $dynamo\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct(DynamoDbStore $dynamo, $name, $seconds, $owner = null)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->dynamo = $dynamo;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        if ($this->seconds > 0) {\n            return $this->dynamo->add($this->name, $this->owner, $this->seconds);\n        }\n\n        return $this->dynamo->add($this->name, $this->owner, 86400);\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        if ($this->isOwnedByCurrentProcess()) {\n            return $this->dynamo->forget($this->name);\n        }\n\n        return false;\n    }\n\n    /**\n     * Release this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        $this->dynamo->forget($this->name);\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return mixed\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->dynamo->get($this->name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/DynamoDbStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Aws\\DynamoDb\\Exception\\DynamoDbException;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse RuntimeException;\n\nclass DynamoDbStore implements LockProvider, Store\n{\n    use InteractsWithTime;\n\n    /**\n     * A string that should be prepended to keys.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * The classes that should be allowed during unserialization.\n     *\n     * @var array|bool|null\n     */\n    protected $serializableClasses;\n\n    /**\n     * Create a new store instance.\n     *\n     * @param  \\Aws\\DynamoDb\\DynamoDbClient  $dynamo  The DynamoDB client instance.\n     * @param  string  $table  The table name.\n     * @param  string  $keyAttribute  The name of the attribute that should hold the key.\n     * @param  string  $valueAttribute  The name of the attribute that should hold the value.\n     * @param  string  $expirationAttribute  The name of the attribute that should hold the expiration timestamp.\n     * @param  string  $prefix\n     * @param  array|bool|null  $serializableClasses\n     */\n    public function __construct(\n        protected DynamoDbClient $dynamo,\n        protected $table,\n        protected $keyAttribute = 'key',\n        protected $valueAttribute = 'value',\n        protected $expirationAttribute = 'expires_at',\n        $prefix = '',\n        $serializableClasses = null,\n    ) {\n        $this->setPrefix($prefix);\n        $this->serializableClasses = $serializableClasses;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        $response = $this->dynamo->getItem([\n            'TableName' => $this->table,\n            'ConsistentRead' => false,\n            'Key' => [\n                $this->keyAttribute => [\n                    'S' => $this->prefix.$key,\n                ],\n            ],\n        ]);\n\n        if (! isset($response['Item'])) {\n            return;\n        }\n\n        if ($this->isExpired($response['Item'])) {\n            return;\n        }\n\n        if (isset($response['Item'][$this->valueAttribute])) {\n            return $this->unserialize(\n                $response['Item'][$this->valueAttribute]['S'] ??\n                $response['Item'][$this->valueAttribute]['N'] ??\n                null\n            );\n        }\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        if (count($keys) === 0) {\n            return [];\n        }\n\n        $prefixedKeys = array_map(function ($key) {\n            return $this->prefix.$key;\n        }, $keys);\n\n        $response = $this->dynamo->batchGetItem([\n            'RequestItems' => [\n                $this->table => [\n                    'ConsistentRead' => false,\n                    'Keys' => (new Collection($prefixedKeys))->map(fn ($key) => [\n                        $this->keyAttribute => [\n                            'S' => $key,\n                        ],\n                    ])->all(),\n                ],\n            ],\n        ]);\n\n        $now = Carbon::now();\n\n        return array_merge(\n            Arr::mapWithKeys($keys, fn ($key) => [$key => null]),\n            (new Collection($response['Responses'][$this->table]))->mapWithKeys(function ($response) use ($now) {\n                if ($this->isExpired($response, $now)) {\n                    $value = null;\n                } else {\n                    $value = $this->unserialize(\n                        $response[$this->valueAttribute]['S'] ??\n                        $response[$this->valueAttribute]['N'] ??\n                        null\n                    );\n                }\n\n                return [Str::replaceFirst($this->prefix, '', $response[$this->keyAttribute]['S']) => $value];\n            })->all());\n    }\n\n    /**\n     * Determine if the given item is expired.\n     *\n     * @param  array  $item\n     * @param  \\DateTimeInterface|null  $expiration\n     * @return bool\n     */\n    protected function isExpired(array $item, $expiration = null)\n    {\n        $expiration = $expiration ?: Carbon::now();\n\n        return isset($item[$this->expirationAttribute]) &&\n               $expiration->getTimestamp() >= $item[$this->expirationAttribute]['N'];\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        $this->dynamo->putItem([\n            'TableName' => $this->table,\n            'Item' => [\n                $this->keyAttribute => [\n                    'S' => $this->prefix.$key,\n                ],\n                $this->valueAttribute => [\n                    $this->type($value) => $this->serialize($value),\n                ],\n                $this->expirationAttribute => [\n                    'N' => (string) $this->toTimestamp($seconds),\n                ],\n            ],\n        ]);\n\n        return true;\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        if (count($values) === 0) {\n            return true;\n        }\n\n        $expiration = $this->toTimestamp($seconds);\n\n        $this->dynamo->batchWriteItem([\n            'RequestItems' => [\n                $this->table => (new Collection($values))->map(function ($value, $key) use ($expiration) {\n                    return [\n                        'PutRequest' => [\n                            'Item' => [\n                                $this->keyAttribute => [\n                                    'S' => $this->prefix.$key,\n                                ],\n                                $this->valueAttribute => [\n                                    $this->type($value) => $this->serialize($value),\n                                ],\n                                $this->expirationAttribute => [\n                                    'N' => (string) $expiration,\n                                ],\n                            ],\n                        ],\n                    ];\n                })->values()->all(),\n            ],\n        ]);\n\n        return true;\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     *\n     * @throws \\Aws\\DynamoDb\\Exception\\DynamoDbException\n     */\n    public function add($key, $value, $seconds)\n    {\n        try {\n            $this->dynamo->putItem([\n                'TableName' => $this->table,\n                'Item' => [\n                    $this->keyAttribute => [\n                        'S' => $this->prefix.$key,\n                    ],\n                    $this->valueAttribute => [\n                        $this->type($value) => $this->serialize($value),\n                    ],\n                    $this->expirationAttribute => [\n                        'N' => (string) $this->toTimestamp($seconds),\n                    ],\n                ],\n                'ConditionExpression' => 'attribute_not_exists(#key) OR #expires_at < :now',\n                'ExpressionAttributeNames' => [\n                    '#key' => $this->keyAttribute,\n                    '#expires_at' => $this->expirationAttribute,\n                ],\n                'ExpressionAttributeValues' => [\n                    ':now' => [\n                        'N' => (string) $this->currentTime(),\n                    ],\n                ],\n            ]);\n\n            return true;\n        } catch (DynamoDbException $e) {\n            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {\n                return false;\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     *\n     * @throws \\Aws\\DynamoDb\\Exception\\DynamoDbException\n     */\n    public function increment($key, $value = 1)\n    {\n        try {\n            $response = $this->dynamo->updateItem([\n                'TableName' => $this->table,\n                'Key' => [\n                    $this->keyAttribute => [\n                        'S' => $this->prefix.$key,\n                    ],\n                ],\n                'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',\n                'UpdateExpression' => 'SET #value = #value + :amount',\n                'ExpressionAttributeNames' => [\n                    '#key' => $this->keyAttribute,\n                    '#value' => $this->valueAttribute,\n                    '#expires_at' => $this->expirationAttribute,\n                ],\n                'ExpressionAttributeValues' => [\n                    ':now' => [\n                        'N' => (string) $this->currentTime(),\n                    ],\n                    ':amount' => [\n                        'N' => (string) $value,\n                    ],\n                ],\n                'ReturnValues' => 'UPDATED_NEW',\n            ]);\n\n            return (int) $response['Attributes'][$this->valueAttribute]['N'];\n        } catch (DynamoDbException $e) {\n            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {\n                return false;\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     *\n     * @throws \\Aws\\DynamoDb\\Exception\\DynamoDbException\n     */\n    public function decrement($key, $value = 1)\n    {\n        try {\n            $response = $this->dynamo->updateItem([\n                'TableName' => $this->table,\n                'Key' => [\n                    $this->keyAttribute => [\n                        'S' => $this->prefix.$key,\n                    ],\n                ],\n                'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',\n                'UpdateExpression' => 'SET #value = #value - :amount',\n                'ExpressionAttributeNames' => [\n                    '#key' => $this->keyAttribute,\n                    '#value' => $this->valueAttribute,\n                    '#expires_at' => $this->expirationAttribute,\n                ],\n                'ExpressionAttributeValues' => [\n                    ':now' => [\n                        'N' => (string) $this->currentTime(),\n                    ],\n                    ':amount' => [\n                        'N' => (string) $value,\n                    ],\n                ],\n                'ReturnValues' => 'UPDATED_NEW',\n            ]);\n\n            return (int) $response['Attributes'][$this->valueAttribute]['N'];\n        } catch (DynamoDbException $e) {\n            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {\n                return false;\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, Carbon::now()->addYears(5)->getTimestamp());\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new DynamoDbLock($this, $name, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     *\n     * @throws DynamoDbException\n     */\n    public function touch($key, $seconds)\n    {\n        try {\n            $this->dynamo->updateItem([\n                'TableName' => $this->table,\n                'Key' => [$this->keyAttribute => ['S' => $this->getPrefix().$key]],\n                'UpdateExpression' => 'SET #expiry = :expiry',\n                'ConditionExpression' => 'attribute_exists(#key) AND #expiry > :now',\n                'ExpressionAttributeNames' => [\n                    '#key' => $this->keyAttribute,\n                    '#expiry' => $this->expirationAttribute,\n                ],\n                'ExpressionAttributeValues' => [\n                    ':expiry' => ['N' => (string) $this->toTimestamp($seconds)],\n                    ':now' => ['N' => (string) $this->currentTime()],\n                ],\n            ]);\n        } catch (DynamoDbException $e) {\n            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {\n                return false;\n            }\n\n            throw $e;\n        }\n\n        return true;\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        $this->dynamo->deleteItem([\n            'TableName' => $this->table,\n            'Key' => [\n                $this->keyAttribute => [\n                    'S' => $this->prefix.$key,\n                ],\n            ],\n        ]);\n\n        return true;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return never\n     *\n     * @throws \\RuntimeException\n     */\n    public function flush()\n    {\n        throw new RuntimeException('DynamoDb does not support flushing an entire table. Please create a new table.');\n    }\n\n    /**\n     * Get the UNIX timestamp for the given number of seconds.\n     *\n     * @param  int  $seconds\n     * @return int\n     */\n    protected function toTimestamp($seconds)\n    {\n        return $seconds > 0\n            ? $this->availableAt($seconds)\n            : $this->currentTime();\n    }\n\n    /**\n     * Serialize the value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function serialize($value)\n    {\n        return is_numeric($value) ? (string) $value : serialize($value);\n    }\n\n    /**\n     * Unserialize the value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function unserialize($value)\n    {\n        if (filter_var($value, FILTER_VALIDATE_INT) !== false) {\n            return (int) $value;\n        }\n\n        if (is_numeric($value)) {\n            return (float) $value;\n        }\n\n        if ($this->serializableClasses !== null) {\n            return unserialize($value, ['allowed_classes' => $this->serializableClasses]);\n        }\n\n        return unserialize($value);\n    }\n\n    /**\n     * Get the DynamoDB type for the given value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function type($value)\n    {\n        return is_numeric($value) ? 'N' : 'S';\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * Set the cache key prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = $prefix;\n    }\n\n    /**\n     * Get the DynamoDb Client instance.\n     *\n     * @return \\Aws\\DynamoDb\\DynamoDbClient\n     */\n    public function getClient()\n    {\n        return $this->dynamo;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nabstract class CacheEvent\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public $storeName;\n\n    /**\n     * The key of the event.\n     *\n     * @var string\n     */\n    public $key;\n\n    /**\n     * The tags that were assigned to the key.\n     *\n     * @var array\n     */\n    public $tags;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  string  $key\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $key, array $tags = [])\n    {\n        $this->storeName = $storeName;\n        $this->key = $key;\n        $this->tags = $tags;\n    }\n\n    /**\n     * Set the tags for the cache event.\n     *\n     * @param  array  $tags\n     * @return $this\n     */\n    public function setTags($tags)\n    {\n        $this->tags = $tags;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheFailedOver.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nuse Throwable;\n\nclass CacheFailedOver\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName  The name of the cache store that failed.\n     * @param  \\Throwable  $exception  The exception that was thrown.\n     */\n    public function __construct(\n        public ?string $storeName,\n        public Throwable $exception,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheFlushFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheFlushFailed\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public $storeName;\n\n    /**\n     * The tags that were assigned to the key.\n     *\n     * @var array\n     */\n    public $tags;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  array  $tags\n     */\n    public function __construct($storeName, array $tags = [])\n    {\n        $this->storeName = $storeName;\n        $this->tags = $tags;\n    }\n\n    /**\n     * Set the tags for the cache event.\n     *\n     * @param  array  $tags\n     * @return $this\n     */\n    public function setTags($tags)\n    {\n        $this->tags = $tags;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheFlushed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheFlushed\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public $storeName;\n\n    /**\n     * The tags that were assigned to the key.\n     *\n     * @var array\n     */\n    public $tags;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  array  $tags\n     */\n    public function __construct($storeName, array $tags = [])\n    {\n        $this->storeName = $storeName;\n        $this->tags = $tags;\n    }\n\n    /**\n     * Set the tags for the cache event.\n     *\n     * @param  array  $tags\n     * @return $this\n     */\n    public function setTags($tags)\n    {\n        $this->tags = $tags;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheFlushing.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheFlushing\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public $storeName;\n\n    /**\n     * The tags that were assigned to the key.\n     *\n     * @var array\n     */\n    public $tags;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  array  $tags\n     */\n    public function __construct($storeName, array $tags = [])\n    {\n        $this->storeName = $storeName;\n        $this->tags = $tags;\n    }\n\n    /**\n     * Set the tags for the cache event.\n     *\n     * @param  array  $tags\n     * @return $this\n     */\n    public function setTags($tags)\n    {\n        $this->tags = $tags;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheHit.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheHit extends CacheEvent\n{\n    /**\n     * The value that was retrieved.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $key, $value, array $tags = [])\n    {\n        parent::__construct($storeName, $key, $tags);\n\n        $this->value = $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheLocksFlushFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheLocksFlushFailed\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public ?string $storeName;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     */\n    public function __construct(?string $storeName)\n    {\n        $this->storeName = $storeName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheLocksFlushed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheLocksFlushed\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public ?string $storeName;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     */\n    public function __construct(?string $storeName)\n    {\n        $this->storeName = $storeName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheLocksFlushing.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheLocksFlushing\n{\n    /**\n     * The name of the cache store.\n     *\n     * @var string|null\n     */\n    public ?string $storeName;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     */\n    public function __construct(?string $storeName)\n    {\n        $this->storeName = $storeName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/CacheMissed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass CacheMissed extends CacheEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/ForgettingKey.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass ForgettingKey extends CacheEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/KeyForgetFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass KeyForgetFailed extends CacheEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/KeyForgotten.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass KeyForgotten extends CacheEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/KeyWriteFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass KeyWriteFailed extends CacheEvent\n{\n    /**\n     * The value that would have been written.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * The number of seconds the key should have been valid.\n     *\n     * @var int|null\n     */\n    public $seconds;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int|null  $seconds\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $key, $value, $seconds = null, $tags = [])\n    {\n        parent::__construct($storeName, $key, $tags);\n\n        $this->value = $value;\n        $this->seconds = $seconds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/KeyWritten.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass KeyWritten extends CacheEvent\n{\n    /**\n     * The value that was written.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * The number of seconds the key should be valid.\n     *\n     * @var int|null\n     */\n    public $seconds;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int|null  $seconds\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $key, $value, $seconds = null, $tags = [])\n    {\n        parent::__construct($storeName, $key, $tags);\n\n        $this->value = $value;\n        $this->seconds = $seconds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/RetrievingKey.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass RetrievingKey extends CacheEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/RetrievingManyKeys.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass RetrievingManyKeys extends CacheEvent\n{\n    /**\n     * The keys that are being retrieved.\n     *\n     * @var array\n     */\n    public $keys;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  array  $keys\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $keys, array $tags = [])\n    {\n        parent::__construct($storeName, $keys[0] ?? '', $tags);\n\n        $this->keys = $keys;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/WritingKey.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass WritingKey extends CacheEvent\n{\n    /**\n     * The value that will be written.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * The number of seconds the key should be valid.\n     *\n     * @var int|null\n     */\n    public $seconds;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int|null  $seconds\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $key, $value, $seconds = null, $tags = [])\n    {\n        parent::__construct($storeName, $key, $tags);\n\n        $this->value = $value;\n        $this->seconds = $seconds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Events/WritingManyKeys.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Events;\n\nclass WritingManyKeys extends CacheEvent\n{\n    /**\n     * The keys that are being written.\n     *\n     * @var mixed\n     */\n    public $keys;\n\n    /**\n     * The value that is being written.\n     *\n     * @var mixed\n     */\n    public $values;\n\n    /**\n     * The number of seconds the keys should be valid.\n     *\n     * @var int|null\n     */\n    public $seconds;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $storeName\n     * @param  array  $keys\n     * @param  array  $values\n     * @param  int|null  $seconds\n     * @param  array  $tags\n     */\n    public function __construct($storeName, $keys, $values, $seconds = null, $tags = [])\n    {\n        parent::__construct($storeName, $keys[0], $tags);\n\n        $this->keys = $keys;\n        $this->values = $values;\n        $this->seconds = $seconds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/FailoverStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Cache\\Events\\CacheFailedOver;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse RuntimeException;\nuse Throwable;\n\nclass FailoverStore extends TaggableStore implements LockProvider\n{\n    /**\n     * The caches which failed on the last action.\n     *\n     * @var list<string>\n     */\n    protected array $failingCaches = [];\n\n    /**\n     * Create a new failover store.\n     *\n     * @param  array<int, string>  $stores\n     */\n    public function __construct(\n        protected CacheManager $cache,\n        protected Dispatcher $events,\n        protected array $stores\n    ) {\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function add($key, $value, $seconds)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Remove all expired tag set entries.\n     *\n     * @return void\n     */\n    public function flushStaleTags()\n    {\n        foreach ($this->stores as $store) {\n            if ($this->store($store)->getStore() instanceof RedisStore) {\n                $this->store($store)->flushStaleTags();\n\n                break;\n            }\n        }\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->attemptOnAllStores(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Attempt the given method on all stores.\n     *\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    protected function attemptOnAllStores(string $method, array $arguments)\n    {\n        [$lastException, $failedCaches] = [null, []];\n\n        try {\n            foreach ($this->stores as $store) {\n                try {\n                    return $this->store($store)->{$method}(...$arguments);\n                } catch (Throwable $e) {\n                    $lastException = $e;\n\n                    $failedCaches[] = $store;\n\n                    if (! in_array($store, $this->failingCaches)) {\n                        $this->events->dispatch(new CacheFailedOver($store, $e));\n                    }\n                }\n            }\n        } finally {\n            $this->failingCaches = $failedCaches;\n        }\n\n        throw $lastException ?? new RuntimeException('All failover cache stores failed.');\n    }\n\n    /**\n     * Get the cache store for the given store name.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected function store(string $store)\n    {\n        return $this->cache->store($store);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/FileLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass FileLock extends CacheLock\n{\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        return $this->store->add($this->name, $this->owner, $this->seconds);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/FileStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Exception;\nuse Illuminate\\Contracts\\Cache\\CanFlushLocks;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Contracts\\Filesystem\\LockTimeoutException;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Filesystem\\LockableFile;\nuse Illuminate\\Support\\InteractsWithTime;\nuse RuntimeException;\n\nclass FileStore implements CanFlushLocks, LockProvider, Store\n{\n    use InteractsWithTime, RetrievesMultipleKeys;\n\n    /**\n     * The Illuminate Filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The file cache directory.\n     *\n     * @var string\n     */\n    protected $directory;\n\n    /**\n     * The file cache lock directory.\n     *\n     * @var string|null\n     */\n    protected $lockDirectory;\n\n    /**\n     * Octal representation of the cache file permissions.\n     *\n     * @var int|null\n     */\n    protected $filePermission;\n\n    /**\n     * The classes that should be allowed during unserialization.\n     *\n     * @var array|bool|null\n     */\n    protected $serializableClasses;\n\n    /**\n     * Create a new file cache store instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $directory\n     * @param  int|null  $filePermission\n     * @param  array|bool|null  $serializableClasses\n     */\n    public function __construct(Filesystem $files, $directory, $filePermission = null, $serializableClasses = null)\n    {\n        $this->files = $files;\n        $this->directory = $directory;\n        $this->filePermission = $filePermission;\n        $this->serializableClasses = $serializableClasses;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        return $this->getPayload($key)['data'] ?? null;\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        $this->ensureCacheDirectoryExists($path = $this->path($key));\n\n        $result = $this->files->put(\n            $path, $this->expiration($seconds).serialize($value), true\n        );\n\n        if ($result !== false && $result > 0) {\n            $this->ensurePermissionsAreCorrect($path);\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function add($key, $value, $seconds)\n    {\n        $this->ensureCacheDirectoryExists($path = $this->path($key));\n\n        $file = new LockableFile($path, 'c+');\n\n        try {\n            $file->getExclusiveLock();\n        } catch (LockTimeoutException) {\n            $file->close();\n\n            return false;\n        }\n\n        $expire = $file->read(10);\n\n        if (empty($expire) || $this->currentTime() >= $expire) {\n            $file->truncate()\n                ->write($this->expiration($seconds).serialize($value))\n                ->close();\n\n            $this->ensurePermissionsAreCorrect($path);\n\n            return true;\n        }\n\n        $file->close();\n\n        return false;\n    }\n\n    /**\n     * Create the file cache directory if necessary.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function ensureCacheDirectoryExists($path)\n    {\n        $directory = dirname($path);\n\n        if (! $this->files->exists($directory)) {\n            $this->files->makeDirectory($directory, 0777, true, true);\n\n            // We're creating two levels of directories (e.g. 7e/24), so we check them both...\n            $this->ensurePermissionsAreCorrect($directory);\n            $this->ensurePermissionsAreCorrect(dirname($directory));\n        }\n    }\n\n    /**\n     * Ensure the created node has the correct permissions.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function ensurePermissionsAreCorrect($path)\n    {\n        if (is_null($this->filePermission) ||\n            intval($this->files->chmod($path), 8) == $this->filePermission) {\n            return;\n        }\n\n        $this->files->chmod($path, $this->filePermission);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function increment($key, $value = 1)\n    {\n        $raw = $this->getPayload($key);\n\n        return tap(((int) $raw['data']) + $value, function ($newValue) use ($key, $raw) {\n            $this->put($key, $newValue, $raw['time'] ?? 0);\n        });\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->increment($key, $value * -1);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 0);\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        $this->ensureCacheDirectoryExists($this->lockDirectory ?? $this->directory);\n\n        return new FileLock(\n            new static($this->files, $this->lockDirectory ?? $this->directory, $this->filePermission, $this->serializableClasses),\n            \"file-store-lock:{$name}\",\n            $seconds,\n            $owner\n        );\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        $payload = $this->getPayload($this->getPrefix().$key);\n\n        if (is_null($payload['data'])) {\n            return false;\n        }\n\n        return $this->put($key, $payload['data'], $seconds);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        if ($this->files->exists($file = $this->path($key))) {\n            return tap($this->files->delete($file), function ($forgotten) use ($key) {\n                if ($forgotten && $this->files->exists($file = $this->path(\"illuminate:cache:flexible:created:{$key}\"))) {\n                    $this->files->delete($file);\n                }\n            });\n        }\n\n        return false;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        if (! $this->files->isDirectory($this->directory)) {\n            return false;\n        }\n\n        foreach ($this->files->directories($this->directory) as $directory) {\n            $deleted = $this->files->deleteDirectory($directory);\n\n            if (! $deleted || $this->files->exists($directory)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Remove all locks from the store.\n     *\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function flushLocks(): bool\n    {\n        if (! $this->hasSeparateLockStore()) {\n            throw new RuntimeException('Flushing locks is only supported when the lock store is separate from the cache store.');\n        }\n\n        if (! $this->files->isDirectory($this->lockDirectory)) {\n            return false;\n        }\n\n        foreach ($this->files->directories($this->lockDirectory) as $lockDirectory) {\n            $deleted = $this->files->deleteDirectory($lockDirectory);\n\n            if (! $deleted || $this->files->exists($lockDirectory)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Retrieve an item and expiry time from the cache by key.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    protected function getPayload($key)\n    {\n        $path = $this->path($key);\n\n        // If the file doesn't exist, we obviously cannot return the cache so we will\n        // just return null. Otherwise, we'll get the contents of the file and get\n        // the expiration UNIX timestamps from the start of the file's contents.\n        try {\n            if (is_null($contents = $this->files->get($path, true))) {\n                return $this->emptyPayload();\n            }\n\n            $expire = substr($contents, 0, 10);\n        } catch (Exception) {\n            return $this->emptyPayload();\n        }\n\n        // If the current time is greater than expiration timestamps we will delete\n        // the file and return null. This helps clean up the old files and keeps\n        // this directory much cleaner for us as old files aren't hanging out.\n        if ($this->currentTime() >= $expire) {\n            $this->forget($key);\n\n            return $this->emptyPayload();\n        }\n\n        try {\n            $data = $this->unserialize(substr($contents, 10));\n        } catch (Exception) {\n            $this->forget($key);\n\n            return $this->emptyPayload();\n        }\n\n        // Next, we'll extract the number of seconds that are remaining for a cache\n        // so that we can properly retain the time for things like the increment\n        // operation that may be performed on this cache on a later operation.\n        $time = $expire - $this->currentTime();\n\n        return compact('data', 'time');\n    }\n\n    /**\n     * Unserialize the given value.\n     *\n     * @param  string  $value\n     * @return mixed\n     */\n    protected function unserialize($value)\n    {\n        if ($this->serializableClasses !== null) {\n            return unserialize($value, ['allowed_classes' => $this->serializableClasses]);\n        }\n\n        return unserialize($value);\n    }\n\n    /**\n     * Get a default empty payload for the cache.\n     *\n     * @return array\n     */\n    protected function emptyPayload()\n    {\n        return ['data' => null, 'time' => null];\n    }\n\n    /**\n     * Get the full path for the given cache key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    public function path($key)\n    {\n        $parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);\n\n        return $this->directory.'/'.implode('/', $parts).'/'.$hash;\n    }\n\n    /**\n     * Get the expiration time based on the given seconds.\n     *\n     * @param  int  $seconds\n     * @return int\n     */\n    protected function expiration($seconds)\n    {\n        $time = $this->availableAt($seconds);\n\n        return $seconds === 0 || $time > 9999999999 ? 9999999999 : $time;\n    }\n\n    /**\n     * Get the Filesystem instance.\n     *\n     * @return \\Illuminate\\Filesystem\\Filesystem\n     */\n    public function getFilesystem()\n    {\n        return $this->files;\n    }\n\n    /**\n     * Get the working directory of the cache.\n     *\n     * @return string\n     */\n    public function getDirectory()\n    {\n        return $this->directory;\n    }\n\n    /**\n     * Set the working directory of the cache.\n     *\n     * @param  string  $directory\n     * @return $this\n     */\n    public function setDirectory($directory)\n    {\n        $this->directory = $directory;\n\n        return $this;\n    }\n\n    /**\n     * Set the cache directory where locks should be stored.\n     *\n     * @param  string|null  $lockDirectory\n     * @return $this\n     */\n    public function setLockDirectory($lockDirectory)\n    {\n        $this->lockDirectory = $lockDirectory;\n\n        return $this;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return '';\n    }\n\n    /**\n     * Determine if the lock store is separate from the cache store.\n     *\n     * @return bool\n     */\n    public function hasSeparateLockStore(): bool\n    {\n        return $this->lockDirectory !== null && $this->lockDirectory !== $this->directory;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/HasCacheLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\ntrait HasCacheLock\n{\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new CacheLock($this, $name, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Cache/Limiters/ConcurrencyLimiter.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Limiters;\n\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\nuse Throwable;\n\nclass ConcurrencyLimiter\n{\n    /**\n     * The cache store instance.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\LockProvider\n     */\n    protected $store;\n\n    /**\n     * The name of the limiter.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The allowed number of concurrent locks.\n     *\n     * @var int\n     */\n    protected $maxLocks;\n\n    /**\n     * The number of seconds a slot should be maintained.\n     *\n     * @var int\n     */\n    protected $releaseAfter;\n\n    /**\n     * Create a new concurrency limiter instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\LockProvider  $store\n     * @param  string  $name\n     * @param  int  $maxLocks\n     * @param  int  $releaseAfter\n     */\n    public function __construct($store, $name, $maxLocks, $releaseAfter)\n    {\n        $this->name = $name;\n        $this->store = $store;\n        $this->maxLocks = $maxLocks;\n        $this->releaseAfter = $releaseAfter;\n    }\n\n    /**\n     * Attempt to acquire the lock for the given number of seconds.\n     *\n     * @param  int  $timeout\n     * @param  callable|null  $callback\n     * @param  int  $sleep\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Cache\\Limiters\\LimiterTimeoutException\n     * @throws \\Throwable\n     */\n    public function block($timeout, $callback = null, $sleep = 250)\n    {\n        $starting = time();\n\n        $id = Str::random(20);\n\n        while (! $slot = $this->acquire($id)) {\n            if (time() - $timeout >= $starting) {\n                throw new LimiterTimeoutException;\n            }\n\n            Sleep::usleep($sleep * 1000);\n        }\n\n        if (is_callable($callback)) {\n            try {\n                return tap($callback(), function () use ($slot) {\n                    $this->release($slot);\n                });\n            } catch (Throwable $exception) {\n                $this->release($slot);\n\n                throw $exception;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Attempt to acquire a slot lock.\n     *\n     * @param  string  $id\n     * @return \\Illuminate\\Contracts\\Cache\\Lock|false\n     */\n    protected function acquire($id)\n    {\n        for ($i = 1; $i <= $this->maxLocks; $i++) {\n            $lock = $this->store->lock($this->name.$i, $this->releaseAfter, $id);\n\n            if ($lock->acquire()) {\n                return $lock;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Lock  $lock\n     * @return void\n     */\n    protected function release($lock)\n    {\n        $lock->release();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Limiters/ConcurrencyLimiterBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Limiters;\n\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass ConcurrencyLimiterBuilder\n{\n    use InteractsWithTime;\n\n    /**\n     * The cache repository or Redis connection.\n     *\n     * @var \\Illuminate\\Cache\\Repository\n     */\n    public $connection;\n\n    /**\n     * The name of the lock.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The maximum number of entities that can hold the lock at the same time.\n     *\n     * @var int\n     */\n    public $maxLocks;\n\n    /**\n     * The number of seconds to maintain the lock until it is automatically released.\n     *\n     * @var int\n     */\n    public $releaseAfter = 60;\n\n    /**\n     * The number of seconds to block until a lock is available.\n     *\n     * @var int\n     */\n    public $timeout = 3;\n\n    /**\n     * The number of milliseconds to wait between attempts to acquire the lock.\n     *\n     * @var int\n     */\n    public $sleep = 250;\n\n    /**\n     * Create a new builder instance.\n     *\n     * @param  mixed  $connection\n     * @param  string  $name\n     */\n    public function __construct($connection, $name)\n    {\n        $this->name = $name;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Set the maximum number of locks that can be obtained per time window.\n     *\n     * @param  int  $maxLocks\n     * @return $this\n     */\n    public function limit($maxLocks)\n    {\n        $this->maxLocks = $maxLocks;\n\n        return $this;\n    }\n\n    /**\n     * Set the number of seconds until the lock will be released.\n     *\n     * @param  int  $releaseAfter\n     * @return $this\n     */\n    public function releaseAfter($releaseAfter)\n    {\n        $this->releaseAfter = $this->secondsUntil($releaseAfter);\n\n        return $this;\n    }\n\n    /**\n     * Set the number of seconds to block until a lock is available.\n     *\n     * @param  int  $timeout\n     * @return $this\n     */\n    public function block($timeout)\n    {\n        $this->timeout = $timeout;\n\n        return $this;\n    }\n\n    /**\n     * The number of milliseconds to wait between lock acquisition attempts.\n     *\n     * @param  int  $sleep\n     * @return $this\n     */\n    public function sleep($sleep)\n    {\n        $this->sleep = $sleep;\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback if a lock is obtained, otherwise call the failure callback.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $failure\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Cache\\Limiters\\LimiterTimeoutException\n     */\n    public function then(callable $callback, ?callable $failure = null)\n    {\n        try {\n            return $this->createLimiter()->block($this->timeout, $callback, $this->sleep);\n        } catch (LimiterTimeoutException $e) {\n            if ($failure) {\n                return $failure($e);\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Create the concurrency limiter instance.\n     *\n     * @return \\Illuminate\\Cache\\Limiters\\ConcurrencyLimiter\n     */\n    protected function createLimiter()\n    {\n        return new ConcurrencyLimiter(\n            $this->connection->getStore(),\n            $this->name,\n            $this->maxLocks,\n            $this->releaseAfter\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Limiters/LimiterTimeoutException.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\Limiters;\n\nuse Exception;\n\nclass LimiterTimeoutException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Lock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Lock as LockContract;\nuse Illuminate\\Contracts\\Cache\\LockTimeoutException;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\n\nabstract class Lock implements LockContract\n{\n    use InteractsWithTime;\n\n    /**\n     * The name of the lock.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The number of seconds the lock should be maintained.\n     *\n     * @var int\n     */\n    protected $seconds;\n\n    /**\n     * The scope identifier of this lock.\n     *\n     * @var string\n     */\n    protected $owner;\n\n    /**\n     * The number of milliseconds to wait before re-attempting to acquire a lock while blocking.\n     *\n     * @var int\n     */\n    protected $sleepMilliseconds = 250;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct($name, $seconds, $owner = null)\n    {\n        if (is_null($owner)) {\n            $owner = Str::random();\n        }\n\n        $this->name = $name;\n        $this->owner = $owner;\n        $this->seconds = $seconds;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    abstract public function acquire();\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    abstract public function release();\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return string\n     */\n    abstract protected function getCurrentOwner();\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @param  callable|null  $callback\n     * @return mixed\n     */\n    public function get($callback = null)\n    {\n        $result = $this->acquire();\n\n        if ($result && is_callable($callback)) {\n            try {\n                return $callback();\n            } finally {\n                $this->release();\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Attempt to acquire the lock for the given number of seconds.\n     *\n     * @param  int  $seconds\n     * @param  callable|null  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Cache\\LockTimeoutException\n     */\n    public function block($seconds, $callback = null)\n    {\n        $starting = ((int) Carbon::now()->format('Uu')) / 1000;\n\n        $milliseconds = $seconds * 1000;\n\n        while (! $this->acquire()) {\n            $now = ((int) Carbon::now()->format('Uu')) / 1000;\n\n            if (($now + $this->sleepMilliseconds - $milliseconds) >= $starting) {\n                throw new LockTimeoutException;\n            }\n\n            Sleep::usleep($this->sleepMilliseconds * 1000);\n        }\n\n        if (is_callable($callback)) {\n            try {\n                return $callback();\n            } finally {\n                $this->release();\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Returns the current owner of the lock.\n     *\n     * @return string\n     */\n    public function owner()\n    {\n        return $this->owner;\n    }\n\n    /**\n     * Determines whether this lock is allowed to release the lock in the driver.\n     *\n     * @return bool\n     */\n    public function isOwnedByCurrentProcess()\n    {\n        return $this->isOwnedBy($this->owner);\n    }\n\n    /**\n     * Determine whether this lock is owned by the given identifier.\n     *\n     * @param  string|null  $owner\n     * @return bool\n     */\n    public function isOwnedBy($owner)\n    {\n        return $this->getCurrentOwner() === $owner;\n    }\n\n    /**\n     * Specify the number of milliseconds to sleep in between blocked lock acquisition attempts.\n     *\n     * @param  int  $milliseconds\n     * @return $this\n     */\n    public function betweenBlockedAttemptsSleepFor($milliseconds)\n    {\n        $this->sleepMilliseconds = $milliseconds;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/LuaScripts.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass LuaScripts\n{\n    /**\n     * Get the Lua script that sets a key only when it does not yet exist.\n     *\n     * KEYS[1] - The name of the key\n     * ARGV[1] - The value of the key\n     * ARGV[2] - The number of seconds the key should be valid\n     *\n     * @return string\n     */\n    public static function add()\n    {\n        return <<<'LUA'\nreturn redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])\nLUA;\n    }\n\n    /**\n     * Get the Lua script to atomically release a lock.\n     *\n     * KEYS[1] - The name of the lock\n     * ARGV[1] - The owner key of the lock instance trying to release it\n     *\n     * @return string\n     */\n    public static function releaseLock()\n    {\n        return <<<'LUA'\nif redis.call(\"get\",KEYS[1]) == ARGV[1] then\n    return redis.call(\"del\",KEYS[1])\nelse\n    return 0\nend\nLUA;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/MemcachedConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Memcached;\n\nclass MemcachedConnector\n{\n    /**\n     * Create a new Memcached connection.\n     *\n     * @param  array  $servers\n     * @param  string|null  $connectionId\n     * @param  array  $options\n     * @param  array  $credentials\n     * @return \\Memcached\n     */\n    public function connect(array $servers, $connectionId = null, array $options = [], array $credentials = [])\n    {\n        $memcached = $this->getMemcached(\n            $connectionId, $credentials, $options\n        );\n\n        if (! $memcached->getServerList()) {\n            // For each server in the array, we'll just extract the configuration and add\n            // the server to the Memcached connection. Once we have added all of these\n            // servers we'll verify the connection is successful and return it back.\n            foreach ($servers as $server) {\n                $memcached->addServer(\n                    $server['host'], $server['port'], $server['weight']\n                );\n            }\n        }\n\n        return $memcached;\n    }\n\n    /**\n     * Get a new Memcached instance.\n     *\n     * @param  string|null  $connectionId\n     * @param  array  $credentials\n     * @param  array  $options\n     * @return \\Memcached\n     */\n    protected function getMemcached($connectionId, array $credentials, array $options)\n    {\n        $memcached = $this->createMemcachedInstance($connectionId);\n\n        if (count($credentials) === 2) {\n            $this->setCredentials($memcached, $credentials);\n        }\n\n        if (count($options)) {\n            $memcached->setOptions($options);\n        }\n\n        return $memcached;\n    }\n\n    /**\n     * Create the Memcached instance.\n     *\n     * @param  string|null  $connectionId\n     * @return \\Memcached\n     */\n    protected function createMemcachedInstance($connectionId)\n    {\n        return empty($connectionId) ? new Memcached : new Memcached($connectionId);\n    }\n\n    /**\n     * Set the SASL credentials on the Memcached connection.\n     *\n     * @param  \\Memcached  $memcached\n     * @param  array  $credentials\n     * @return void\n     */\n    protected function setCredentials($memcached, $credentials)\n    {\n        [$username, $password] = $credentials;\n\n        $memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);\n\n        $memcached->setSaslAuthData($username, $password);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/MemcachedLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass MemcachedLock extends Lock\n{\n    /**\n     * The Memcached instance.\n     *\n     * @var \\Memcached\n     */\n    protected $memcached;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Memcached  $memcached\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct($memcached, $name, $seconds, $owner = null)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->memcached = $memcached;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        return $this->memcached->add(\n            $this->name, $this->owner, $this->seconds\n        );\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        if ($this->isOwnedByCurrentProcess()) {\n            return $this->memcached->delete($this->name);\n        }\n\n        return false;\n    }\n\n    /**\n     * Releases this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        $this->memcached->delete($this->name);\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return mixed\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->memcached->get($this->name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/MemcachedStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Memcached;\nuse ReflectionMethod;\n\nclass MemcachedStore extends TaggableStore implements LockProvider\n{\n    use InteractsWithTime;\n\n    /**\n     * The Memcached instance.\n     *\n     * @var \\Memcached\n     */\n    protected $memcached;\n\n    /**\n     * A string that should be prepended to keys.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * Indicates whether we are using Memcached version >= 3.0.0.\n     *\n     * @var bool\n     */\n    protected $onVersionThree;\n\n    /**\n     * Create a new Memcached store.\n     *\n     * @param  \\Memcached  $memcached\n     * @param  string  $prefix\n     */\n    public function __construct($memcached, $prefix = '')\n    {\n        $this->setPrefix($prefix);\n        $this->memcached = $memcached;\n\n        $this->onVersionThree = (new ReflectionMethod('Memcached', 'getMulti'))\n            ->getNumberOfParameters() == 2;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        $value = $this->memcached->get($this->prefix.$key);\n\n        if ($this->memcached->getResultCode() == 0) {\n            return $value;\n        }\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        $prefixedKeys = array_map(function ($key) {\n            return $this->prefix.$key;\n        }, $keys);\n\n        if ($this->onVersionThree) {\n            $values = $this->memcached->getMulti($prefixedKeys, Memcached::GET_PRESERVE_ORDER);\n        } else {\n            $null = null;\n\n            $values = $this->memcached->getMulti($prefixedKeys, $null, Memcached::GET_PRESERVE_ORDER);\n        }\n\n        if ($this->memcached->getResultCode() != 0) {\n            return array_fill_keys($keys, null);\n        }\n\n        return array_combine($keys, $values);\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return $this->memcached->set(\n            $this->prefix.$key, $value, $this->calculateExpiration($seconds)\n        );\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        $prefixedValues = [];\n\n        foreach ($values as $key => $value) {\n            $prefixedValues[$this->prefix.$key] = $value;\n        }\n\n        return $this->memcached->setMulti(\n            $prefixedValues, $this->calculateExpiration($seconds)\n        );\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function add($key, $value, $seconds)\n    {\n        return $this->memcached->add(\n            $this->prefix.$key, $value, $this->calculateExpiration($seconds)\n        );\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->memcached->increment($this->prefix.$key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|false\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->memcached->decrement($this->prefix.$key, $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 0);\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        return $this->memcached->touch($this->getPrefix().$key, $this->calculateExpiration($seconds));\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return $this->memcached->delete($this->prefix.$key);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        return $this->memcached->flush();\n    }\n\n    /**\n     * Get the expiration time of the key.\n     *\n     * @param  int  $seconds\n     * @return int\n     */\n    protected function calculateExpiration($seconds)\n    {\n        return $this->toTimestamp($seconds);\n    }\n\n    /**\n     * Get the UNIX timestamp for the given number of seconds.\n     *\n     * @param  int  $seconds\n     * @return int\n     */\n    protected function toTimestamp($seconds)\n    {\n        return $seconds > 0 ? $this->availableAt($seconds) : 0;\n    }\n\n    /**\n     * Get the underlying Memcached connection.\n     *\n     * @return \\Memcached\n     */\n    public function getMemcached()\n    {\n        return $this->memcached;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * Set the cache key prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = $prefix;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/MemoizedStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Store;\n\nclass MemoizedStore implements LockProvider, Store\n{\n    /**\n     * The memoized cache values.\n     *\n     * @var array<string, mixed>\n     */\n    protected $cache = [];\n\n    /**\n     * Create a new memoized cache instance.\n     *\n     * @param  string  $name\n     * @param  \\Illuminate\\Cache\\Repository  $repository\n     */\n    public function __construct(\n        protected $name,\n        protected $repository,\n    ) {\n        //\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        $prefixedKey = $this->prefix($key);\n\n        if (array_key_exists($prefixedKey, $this->cache)) {\n            return $this->cache[$prefixedKey];\n        }\n\n        return $this->cache[$prefixedKey] = $this->repository->get($key);\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        [$memoized, $retrieved, $missing] = [[], [], []];\n\n        foreach ($keys as $key) {\n            $prefixedKey = $this->prefix($key);\n\n            if (array_key_exists($prefixedKey, $this->cache)) {\n                $memoized[$key] = $this->cache[$prefixedKey];\n            } else {\n                $missing[] = $key;\n            }\n        }\n\n        if (count($missing) > 0) {\n            $retrieved = tap($this->repository->many($missing), function ($values) {\n                foreach ($values as $key => $value) {\n                    $this->cache[$this->prefix($key)] = $value;\n                }\n            });\n        }\n\n        $result = [];\n\n        foreach ($keys as $key) {\n            if (array_key_exists($key, $memoized)) {\n                $result[$key] = $memoized[$key];\n            } else {\n                $result[$key] = $retrieved[$key];\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->put($key, $value, $seconds);\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        foreach ($values as $key => $value) {\n            unset($this->cache[$this->prefix($key)]);\n        }\n\n        return $this->repository->putMany($values, $seconds);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->increment($key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->decrement($key, $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->forever($key, $value);\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        if (! $this->repository->getStore() instanceof LockProvider) {\n            throw new BadMethodCallException('This cache store does not support locks.');\n        }\n\n        return $this->repository->getStore()->lock(...func_get_args());\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function restoreLock($name, $owner)\n    {\n        if (! $this->repository->getStore() instanceof LockProvider) {\n            throw new BadMethodCallException('This cache store does not support locks.');\n        }\n\n        return $this->repository->getStore()->restoreLock(...func_get_args());\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->touch($key, $seconds);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        unset($this->cache[$this->prefix($key)]);\n\n        return $this->repository->forget($key);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->cache = [];\n\n        return $this->repository->flush();\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->repository->getPrefix();\n    }\n\n    /**\n     * Prefix the given key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function prefix($key)\n    {\n        return $this->getPrefix().$key;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/NoLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass NoLock extends Lock\n{\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        return true;\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        return true;\n    }\n\n    /**\n     * Releases this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        //\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return mixed\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->owner;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/NullStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\LockProvider;\n\nclass NullStore extends TaggableStore implements LockProvider\n{\n    use RetrievesMultipleKeys;\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function get($key)\n    {\n        //\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        return false;\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return false\n     */\n    public function increment($key, $value = 1)\n    {\n        return false;\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return false\n     */\n    public function decrement($key, $value = 1)\n    {\n        return false;\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return false;\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        return new NoLock($name, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        return false;\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return true;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        return true;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/PhpRedisLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\n\nclass PhpRedisLock extends RedisLock\n{\n    /**\n     * Create a new phpredis lock instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\PhpRedisConnection  $redis\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct(PhpRedisConnection $redis, string $name, int $seconds, ?string $owner = null)\n    {\n        parent::__construct($redis, $name, $seconds, $owner);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public function release()\n    {\n        return (bool) $this->redis->eval(\n            LuaScripts::releaseLock(),\n            1,\n            $this->name,\n            ...$this->redis->pack([$this->owner])\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RateLimiter.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Closure;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass RateLimiter\n{\n    use InteractsWithTime;\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * The configured limit object resolvers.\n     *\n     * @var array\n     */\n    protected $limiters = [];\n\n    /**\n     * Create a new rate limiter instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        $this->cache = $cache;\n    }\n\n    /**\n     * Register a named rate limiter configuration.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function for($name, Closure $callback)\n    {\n        $resolvedName = $this->resolveLimiterName($name);\n\n        $this->limiters[$resolvedName] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the given named rate limiter.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @return \\Closure|null\n     */\n    public function limiter($name)\n    {\n        $resolvedName = $this->resolveLimiterName($name);\n\n        $limiter = $this->limiters[$resolvedName] ?? null;\n\n        if (! is_callable($limiter)) {\n            return;\n        }\n\n        return function (...$args) use ($limiter) {\n            $result = $limiter(...$args);\n\n            if (! is_array($result)) {\n                return $result;\n            }\n\n            $duplicates = (new Collection($result))->duplicates('key');\n\n            if ($duplicates->isEmpty()) {\n                return $result;\n            }\n\n            foreach ($result as $limit) {\n                if ($duplicates->contains($limit->key)) {\n                    $limit->key = $limit->fallbackKey();\n                }\n            }\n\n            return $result;\n        };\n    }\n\n    /**\n     * Attempts to execute a callback if it's not limited.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  \\Closure  $callback\n     * @param  \\DateTimeInterface|\\DateInterval|int  $decaySeconds\n     * @return mixed\n     */\n    public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60)\n    {\n        if ($this->tooManyAttempts($key, $maxAttempts)) {\n            return false;\n        }\n\n        if (is_null($result = $callback())) {\n            $result = true;\n        }\n\n        return tap($result, function () use ($key, $decaySeconds) {\n            $this->hit($key, $decaySeconds);\n        });\n    }\n\n    /**\n     * Determine if the given key has been \"accessed\" too many times.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @return bool\n     */\n    public function tooManyAttempts($key, $maxAttempts)\n    {\n        if ($this->attempts($key) >= $maxAttempts) {\n            if ($this->cache->has($this->cleanRateLimiterKey($key).':timer')) {\n                return true;\n            }\n\n            $this->resetAttempts($key);\n        }\n\n        return false;\n    }\n\n    /**\n     * Increment (by 1) the counter for a given key for a given decay time.\n     *\n     * @param  string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|int  $decaySeconds\n     * @return int\n     */\n    public function hit($key, $decaySeconds = 60)\n    {\n        return $this->increment($key, $decaySeconds);\n    }\n\n    /**\n     * Increment the counter for a given key for a given decay time by a given amount.\n     *\n     * @param  string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|int  $decaySeconds\n     * @param  int  $amount\n     * @return int\n     */\n    public function increment($key, $decaySeconds = 60, $amount = 1)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        $this->cache->add(\n            $key.':timer', $this->availableAt($decaySeconds), $decaySeconds\n        );\n\n        $added = $this->withoutSerializationOrCompression(\n            fn () => $this->cache->add($key, 0, $decaySeconds)\n        );\n\n        $hits = (int) $this->cache->increment($key, $amount);\n\n        if (! $added && $hits == 1) {\n            $this->withoutSerializationOrCompression(\n                fn () => $this->cache->put($key, 1, $decaySeconds)\n            );\n        }\n\n        return $hits;\n    }\n\n    /**\n     * Decrement the counter for a given key for a given decay time by a given amount.\n     *\n     * @param  string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|int  $decaySeconds\n     * @param  int  $amount\n     * @return int\n     */\n    public function decrement($key, $decaySeconds = 60, $amount = 1)\n    {\n        return $this->increment($key, $decaySeconds, $amount * -1);\n    }\n\n    /**\n     * Get the number of attempts for the given key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function attempts($key)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        return $this->withoutSerializationOrCompression(fn () => $this->cache->get($key, 0));\n    }\n\n    /**\n     * Reset the number of attempts for the given key.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function resetAttempts($key)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        return $this->cache->forget($key);\n    }\n\n    /**\n     * Get the number of retries left for the given key.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @return int\n     */\n    public function remaining($key, $maxAttempts)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        $attempts = $this->attempts($key);\n\n        return max(0, $maxAttempts - $attempts);\n    }\n\n    /**\n     * Get the number of retries left for the given key.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @return int\n     */\n    public function retriesLeft($key, $maxAttempts)\n    {\n        return $this->remaining($key, $maxAttempts);\n    }\n\n    /**\n     * Clear the hits and lockout timer for the given key.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function clear($key)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        $this->resetAttempts($key);\n\n        $this->cache->forget($key.':timer');\n    }\n\n    /**\n     * Get the number of seconds until the \"key\" is accessible again.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    public function availableIn($key)\n    {\n        $key = $this->cleanRateLimiterKey($key);\n\n        return max(0, $this->cache->get($key.':timer') - $this->currentTime());\n    }\n\n    /**\n     * Clean the rate limiter key from unicode characters.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    public function cleanRateLimiterKey($key)\n    {\n        return preg_replace('/&([a-z])[a-z]+;/i', '$1', htmlentities($key));\n    }\n\n    /**\n     * Execute the given callback without serialization or compression when applicable.\n     *\n     * @param  callable  $callback\n     * @return mixed\n     */\n    protected function withoutSerializationOrCompression(callable $callback)\n    {\n        $store = $this->cache->getStore();\n\n        if (! $store instanceof RedisStore) {\n            return $callback();\n        }\n\n        $connection = $store->connection();\n\n        if (! $connection instanceof PhpRedisConnection) {\n            return $callback();\n        }\n\n        return $connection->withoutSerializationOrCompression($callback);\n    }\n\n    /**\n     * Resolve the rate limiter name.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @return string\n     */\n    private function resolveLimiterName($name): string\n    {\n        return (string) enum_value($name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RateLimiting/GlobalLimit.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\RateLimiting;\n\nclass GlobalLimit extends Limit\n{\n    /**\n     * Create a new limit instance.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     */\n    public function __construct(int $maxAttempts, int $decaySeconds = 60)\n    {\n        parent::__construct('', $maxAttempts, $decaySeconds);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RateLimiting/Limit.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\RateLimiting;\n\nclass Limit\n{\n    /**\n     * The rate limit signature key.\n     *\n     * @var mixed\n     */\n    public $key;\n\n    /**\n     * The maximum number of attempts allowed within the given number of seconds.\n     *\n     * @var int\n     */\n    public $maxAttempts;\n\n    /**\n     * The number of seconds until the rate limit is reset.\n     *\n     * @var int\n     */\n    public $decaySeconds;\n\n    /**\n     * The after callback used to determine if the limiter should be hit.\n     *\n     * @var ?callable\n     */\n    public $afterCallback = null;\n\n    /**\n     * The response generator callback.\n     *\n     * @var callable\n     */\n    public $responseCallback;\n\n    /**\n     * Create a new limit instance.\n     *\n     * @param  mixed  $key\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     */\n    public function __construct($key = '', int $maxAttempts = 60, int $decaySeconds = 60)\n    {\n        $this->key = $key;\n        $this->maxAttempts = $maxAttempts;\n        $this->decaySeconds = $decaySeconds;\n    }\n\n    /**\n     * Create a new rate limit.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     * @return static\n     */\n    public static function perSecond($maxAttempts, $decaySeconds = 1)\n    {\n        return new static('', $maxAttempts, $decaySeconds);\n    }\n\n    /**\n     * Create a new rate limit.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decayMinutes\n     * @return static\n     */\n    public static function perMinute($maxAttempts, $decayMinutes = 1)\n    {\n        return new static('', $maxAttempts, 60 * $decayMinutes);\n    }\n\n    /**\n     * Create a new rate limit using minutes as decay time.\n     *\n     * @param  int  $decayMinutes\n     * @param  int  $maxAttempts\n     * @return static\n     */\n    public static function perMinutes($decayMinutes, $maxAttempts)\n    {\n        return new static('', $maxAttempts, 60 * $decayMinutes);\n    }\n\n    /**\n     * Create a new rate limit using hours as decay time.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decayHours\n     * @return static\n     */\n    public static function perHour($maxAttempts, $decayHours = 1)\n    {\n        return new static('', $maxAttempts, 60 * 60 * $decayHours);\n    }\n\n    /**\n     * Create a new rate limit using days as decay time.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decayDays\n     * @return static\n     */\n    public static function perDay($maxAttempts, $decayDays = 1)\n    {\n        return new static('', $maxAttempts, 60 * 60 * 24 * $decayDays);\n    }\n\n    /**\n     * Create a new unlimited rate limit.\n     *\n     * @return static\n     */\n    public static function none()\n    {\n        return new Unlimited;\n    }\n\n    /**\n     * Set the key of the rate limit.\n     *\n     * @param  mixed  $key\n     * @return $this\n     */\n    public function by($key)\n    {\n        $this->key = $key;\n\n        return $this;\n    }\n\n    /**\n     * Set the callback to determine if the limiter should be hit.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function after($callback)\n    {\n        $this->afterCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Set the callback that should generate the response when the limit is exceeded.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function response(callable $callback)\n    {\n        $this->responseCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get a potential fallback key for the limit.\n     *\n     * @return string\n     */\n    public function fallbackKey()\n    {\n        $prefix = $this->key ? \"{$this->key}:\" : '';\n\n        return \"{$prefix}attempts:{$this->maxAttempts}:decay:{$this->decaySeconds}\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RateLimiting/Unlimited.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache\\RateLimiting;\n\nclass Unlimited extends GlobalLimit\n{\n    /**\n     * Create a new limit instance.\n     */\n    public function __construct()\n    {\n        parent::__construct(PHP_INT_MAX);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RedisLock.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nclass RedisLock extends Lock\n{\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    protected $redis;\n\n    /**\n     * Create a new lock instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $redis\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     */\n    public function __construct($redis, $name, $seconds, $owner = null)\n    {\n        parent::__construct($name, $seconds, $owner);\n\n        $this->redis = $redis;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        if ($this->seconds > 0) {\n            return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true;\n        }\n\n        return $this->redis->setnx($this->name, $this->owner) === 1;\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release()\n    {\n        return (bool) $this->redis->eval(LuaScripts::releaseLock(), 1, $this->name, $this->owner);\n    }\n\n    /**\n     * Releases this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease()\n    {\n        $this->redis->del($this->name);\n    }\n\n    /**\n     * Returns the owner value written into the driver for this lock.\n     *\n     * @return string\n     */\n    protected function getCurrentOwner()\n    {\n        return $this->redis->get($this->name);\n    }\n\n    /**\n     * Get the name of the Redis connection being used to manage the lock.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return $this->redis->getName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RedisStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\CanFlushLocks;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Redis\\Connections\\PredisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisConnection;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Str;\nuse RuntimeException;\n\nclass RedisStore extends TaggableStore implements CanFlushLocks, LockProvider\n{\n    use RetrievesMultipleKeys {\n        many as private manyAlias;\n        putMany as private putManyAlias;\n    }\n\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    protected $redis;\n\n    /**\n     * A string that should be prepended to keys.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * The Redis connection instance that should be used to manage locks.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * The name of the connection that should be used for locks.\n     *\n     * @var string\n     */\n    protected $lockConnection;\n\n    /**\n     * The classes that should be allowed during unserialization.\n     *\n     * @var array|bool|null\n     */\n    protected $serializableClasses;\n\n    /**\n     * Create a new Redis store.\n     *\n     * @param  \\Illuminate\\Contracts\\Redis\\Factory  $redis\n     * @param  string  $prefix\n     * @param  string  $connection\n     * @param  array|bool|null  $serializableClasses\n     */\n    public function __construct(Redis $redis, $prefix = '', $connection = 'default', $serializableClasses = null)\n    {\n        $this->redis = $redis;\n        $this->setPrefix($prefix);\n        $this->setConnection($connection);\n        $this->serializableClasses = $serializableClasses;\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        $connection = $this->connection();\n\n        $value = $connection->get($this->prefix.$key);\n\n        return ! is_null($value) ? $this->connectionAwareUnserialize($value, $connection) : null;\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        if (count($keys) === 0) {\n            return [];\n        }\n\n        $results = [];\n\n        $connection = $this->connection();\n\n        // PredisClusterConnection does not support reading multiple values if the keys hash differently...\n        if ($connection instanceof PredisClusterConnection) {\n            return $this->manyAlias($keys);\n        }\n\n        $values = $connection->mget(array_map(function ($key) {\n            return $this->prefix.$key;\n        }, $keys));\n\n        foreach ($values as $index => $value) {\n            $results[$keys[$index]] = ! is_null($value) ? $this->connectionAwareUnserialize($value, $connection) : null;\n        }\n\n        return $results;\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        $connection = $this->connection();\n\n        return (bool) $connection->setex(\n            $this->prefix.$key, (int) max(1, $seconds), $this->connectionAwareSerialize($value, $connection)\n        );\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        $connection = $this->connection();\n\n        // Cluster connections do not support writing multiple values if the keys hash differently...\n        if ($connection instanceof PhpRedisClusterConnection ||\n            $connection instanceof PredisClusterConnection) {\n            return $this->putManyAlias($values, $seconds);\n        }\n\n        $serializedValues = [];\n\n        foreach ($values as $key => $value) {\n            $serializedValues[$this->prefix.$key] = $this->connectionAwareSerialize($value, $connection);\n        }\n\n        $connection->multi();\n\n        $manyResult = null;\n\n        foreach ($serializedValues as $key => $value) {\n            $result = (bool) $connection->setex(\n                $key, (int) max(1, $seconds), $value\n            );\n\n            $manyResult = is_null($manyResult) ? $result : $result && $manyResult;\n        }\n\n        $connection->exec();\n\n        return $manyResult ?: false;\n    }\n\n    /**\n     * Store an item in the cache if the key doesn't exist.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function add($key, $value, $seconds)\n    {\n        $connection = $this->connection();\n\n        return (bool) $connection->eval(\n            LuaScripts::add(), 1, $this->prefix.$key, $this->pack($value, $connection), (int) max(1, $seconds)\n        );\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->connection()->incrby($this->prefix.$key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->connection()->decrby($this->prefix.$key, $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        $connection = $this->connection();\n\n        return (bool) $connection->set($this->prefix.$key, $this->connectionAwareSerialize($value, $connection));\n    }\n\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null)\n    {\n        $lockName = $this->prefix.$name;\n\n        $lockConnection = $this->lockConnection();\n\n        if ($lockConnection instanceof PhpRedisConnection) {\n            return new PhpRedisLock($lockConnection, $lockName, $seconds, $owner);\n        }\n\n        return new RedisLock($lockConnection, $lockName, $seconds, $owner);\n    }\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner)\n    {\n        return $this->lock($name, 0, $owner);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        return (bool) $this->connection()->expire($this->getPrefix().$key, (int) max(1, $seconds));\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        return (bool) $this->connection()->del($this->prefix.$key);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->connection()->flushdb();\n\n        return true;\n    }\n\n    /**\n     * Remove all locks from the store.\n     *\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function flushLocks(): bool\n    {\n        if (! $this->hasSeparateLockStore()) {\n            throw new RuntimeException('Flushing locks is only supported when the lock store is separate from the cache store.');\n        }\n\n        $this->lockConnection()->flushdb();\n\n        return true;\n    }\n\n    /**\n     * Remove all expired tag set entries.\n     *\n     * @return void\n     */\n    public function flushStaleTags()\n    {\n        foreach ($this->currentTags()->chunk(1000) as $tags) {\n            $this->tags($tags->all())->flushStale();\n        }\n    }\n\n    /**\n     * Begin executing a new tags operation.\n     *\n     * @param  mixed  $names\n     * @return \\Illuminate\\Cache\\RedisTaggedCache\n     */\n    public function tags($names)\n    {\n        return new RedisTaggedCache(\n            $this, new RedisTagSet($this, is_array($names) ? $names : func_get_args())\n        );\n    }\n\n    /**\n     * Get a collection of all of the cache tags currently being used.\n     *\n     * @param  int  $chunkSize\n     * @return \\Illuminate\\Support\\LazyCollection\n     */\n    protected function currentTags($chunkSize = 1000)\n    {\n        $connection = $this->connection();\n\n        // Connections can have a global prefix...\n        $connectionPrefix = match (true) {\n            $connection instanceof PhpRedisConnection => $connection->_prefix(''),\n            $connection instanceof PredisConnection => $connection->getOptions()->prefix ?: '',\n            default => '',\n        };\n\n        $defaultCursorValue = match (true) {\n            $connection instanceof PhpRedisConnection && version_compare(phpversion('redis'), '6.1.0', '>=') => null,\n            default => '0',\n        };\n\n        $prefix = $connectionPrefix.$this->getPrefix();\n\n        return (new LazyCollection(function () use ($connection, $chunkSize, $prefix, $defaultCursorValue) {\n            $cursor = $defaultCursorValue;\n\n            do {\n                $scanResult = $connection->scan(\n                    $cursor,\n                    ['match' => $prefix.'tag:*:entries', 'count' => $chunkSize]\n                );\n\n                if (! is_array($scanResult)) {\n                    break;\n                }\n\n                [$cursor, $tagsChunk] = $scanResult;\n\n                if (! is_array($tagsChunk)) {\n                    break;\n                }\n\n                $tagsChunk = array_unique($tagsChunk);\n\n                if (empty($tagsChunk)) {\n                    continue;\n                }\n\n                foreach ($tagsChunk as $tag) {\n                    yield $tag;\n                }\n            } while (((string) $cursor) !== $defaultCursorValue);\n        }))->map(fn (string $tagKey) => Str::match('/^'.preg_quote($prefix, '/').'tag:(.*):entries$/', $tagKey));\n    }\n\n    /**\n     * Get the Redis connection instance.\n     *\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function connection()\n    {\n        return $this->redis->connection($this->connection);\n    }\n\n    /**\n     * Get the Redis connection instance that should be used to manage locks.\n     *\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function lockConnection()\n    {\n        return $this->redis->connection($this->lockConnection ?? $this->connection);\n    }\n\n    /**\n     * Specify the name of the connection that should be used to store data.\n     *\n     * @param  string  $connection\n     * @return void\n     */\n    public function setConnection($connection)\n    {\n        $this->connection = $connection;\n    }\n\n    /**\n     * Specify the name of the connection that should be used to manage locks.\n     *\n     * @param  string  $connection\n     * @return $this\n     */\n    public function setLockConnection($connection)\n    {\n        $this->lockConnection = $connection;\n\n        return $this;\n    }\n\n    /**\n     * Get the Redis database instance.\n     *\n     * @return \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    public function getRedis()\n    {\n        return $this->redis;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * Set the cache key prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = $prefix;\n    }\n\n    /**\n     * Prepare a value to be used with the Redis cache store when used by eval scripts.\n     *\n     * @param  mixed  $value\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @return mixed\n     */\n    protected function pack($value, $connection)\n    {\n        if ($connection instanceof PhpRedisConnection) {\n            if ($connection->serialized()) {\n                return $connection->pack([$value])[0];\n            }\n\n            if ($connection->compressed()) {\n                return $connection->pack([$this->serialize($value)])[0];\n            }\n        }\n\n        return $this->serialize($value);\n    }\n\n    /**\n     * Serialize the value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function serialize($value)\n    {\n        return $this->shouldBeStoredWithoutSerialization($value) ? $value : serialize($value);\n    }\n\n    /**\n     * Determine if the given value should be stored as plain value.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function shouldBeStoredWithoutSerialization($value): bool\n    {\n        return is_numeric($value) && is_finite($value);\n    }\n\n    /**\n     * Unserialize the value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function unserialize($value)\n    {\n        if (is_numeric($value)) {\n            return $value;\n        }\n\n        if ($this->serializableClasses !== null) {\n            return unserialize($value, ['allowed_classes' => $this->serializableClasses]);\n        }\n\n        return unserialize($value);\n    }\n\n    /**\n     * Handle connection specific considerations when a value needs to be serialized.\n     *\n     * @param  mixed  $value\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @return mixed\n     */\n    protected function connectionAwareSerialize($value, $connection)\n    {\n        if ($connection instanceof PhpRedisConnection && $connection->serialized()) {\n            return $value;\n        }\n\n        return $this->serialize($value);\n    }\n\n    /**\n     * Handle connection specific considerations when a value needs to be unserialized.\n     *\n     * @param  mixed  $value\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @return mixed\n     */\n    protected function connectionAwareUnserialize($value, $connection)\n    {\n        if ($connection instanceof PhpRedisConnection && $connection->serialized()) {\n            return $value;\n        }\n\n        return $this->unserialize($value);\n    }\n\n    /**\n     * Determine if the lock store is separate from the cache store.\n     *\n     * @return bool\n     */\n    public function hasSeparateLockStore(): bool\n    {\n        return $this->lockConnection !== $this->connection;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RedisTagSet.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\LazyCollection;\n\nclass RedisTagSet extends TagSet\n{\n    /**\n     * Add a reference entry to the tag set's underlying sorted set.\n     *\n     * @param  string  $key\n     * @param  int|null  $ttl\n     * @param  string|null  $updateWhen\n     * @return void\n     */\n    public function addEntry(string $key, ?int $ttl = null, $updateWhen = null)\n    {\n        $ttl = is_null($ttl) ? -1 : Carbon::now()->addSeconds($ttl)->getTimestamp();\n\n        foreach ($this->tagIds() as $tagKey) {\n            if ($updateWhen) {\n                $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $updateWhen, $ttl, $key);\n            } else {\n                $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $ttl, $key);\n            }\n        }\n    }\n\n    /**\n     * Get all of the cache entry keys for the tag set.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection\n     */\n    public function entries()\n    {\n        $connection = $this->store->connection();\n\n        $defaultCursorValue = match (true) {\n            $connection instanceof PhpRedisConnection && version_compare(phpversion('redis'), '6.1.0', '>=') => null,\n            default => '0',\n        };\n\n        return new LazyCollection(function () use ($connection, $defaultCursorValue) {\n            foreach ($this->tagIds() as $tagKey) {\n                $cursor = $defaultCursorValue;\n\n                do {\n                    $results = $connection->zscan(\n                        $this->store->getPrefix().$tagKey,\n                        $cursor,\n                        ['match' => '*', 'count' => 1000]\n                    );\n\n                    if (! is_array($results)) {\n                        break;\n                    }\n\n                    [$cursor, $entries] = $results;\n\n                    if (! is_array($entries)) {\n                        break;\n                    }\n\n                    $entries = array_unique(array_keys($entries));\n\n                    if (count($entries) === 0) {\n                        continue;\n                    }\n\n                    foreach ($entries as $entry) {\n                        yield $entry;\n                    }\n                } while (((string) $cursor) !== $defaultCursorValue);\n            }\n        });\n    }\n\n    /**\n     * Remove the stale entries from the tag set.\n     *\n     * @return void\n     */\n    public function flushStaleEntries()\n    {\n        $flushStaleEntries = function ($pipe) {\n            foreach ($this->tagIds() as $tagKey) {\n                $pipe->zremrangebyscore($this->store->getPrefix().$tagKey, 0, Carbon::now()->getTimestamp());\n            }\n        };\n\n        $connection = $this->store->connection();\n\n        if ($connection instanceof PhpRedisConnection) {\n            $flushStaleEntries($connection);\n        } else {\n            $connection->pipeline($flushStaleEntries);\n        }\n    }\n\n    /**\n     * Flush the tag from the cache.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function flushTag($name)\n    {\n        return $this->resetTag($name);\n    }\n\n    /**\n     * Reset the tag and return the new tag identifier.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function resetTag($name)\n    {\n        $this->store->forget($this->tagKey($name));\n\n        return $this->tagId($name);\n    }\n\n    /**\n     * Get the unique tag identifier for a given tag.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function tagId($name)\n    {\n        return \"tag:{$name}:entries\";\n    }\n\n    /**\n     * Get the tag identifier key for a given tag.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function tagKey($name)\n    {\n        return \"tag:{$name}:entries\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RedisTaggedCache.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Cache\\Events\\CacheFlushed;\nuse Illuminate\\Cache\\Events\\CacheFlushing;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Redis\\Connections\\PredisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisConnection;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass RedisTaggedCache extends TaggedCache\n{\n    /**\n     * Store an item in the cache if the key does not exist.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function add($key, $value, $ttl = null)\n    {\n        $key = enum_value($key);\n\n        $seconds = null;\n\n        if ($ttl !== null) {\n            $seconds = $this->getSeconds($ttl);\n\n            if ($seconds > 0) {\n                $this->tags->addEntry(\n                    $this->itemKey($key),\n                    $seconds\n                );\n            }\n        }\n\n        return parent::add($key, $value, $ttl);\n    }\n\n    /**\n     * Store an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function put($key, $value, $ttl = null)\n    {\n        $key = enum_value($key);\n\n        if (is_null($ttl)) {\n            return $this->forever($key, $value);\n        }\n\n        $seconds = $this->getSeconds($ttl);\n\n        if ($seconds > 0) {\n            $this->tags->addEntry(\n                $this->itemKey($key),\n                $seconds\n            );\n        }\n\n        return parent::put($key, $value, $ttl);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1)\n    {\n        $key = enum_value($key);\n\n        $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX');\n\n        return parent::increment($key, $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1)\n    {\n        $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX');\n\n        return parent::decrement($key, $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        $key = enum_value($key);\n\n        $this->tags->addEntry($this->itemKey($key));\n\n        return parent::forever($key, $value);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $connection = $this->store->connection();\n\n        if ($connection instanceof PredisClusterConnection ||\n            $connection instanceof PhpRedisClusterConnection) {\n            return $this->flushClusteredConnection();\n        }\n\n        $this->event(new CacheFlushing($this->getName()));\n\n        $redisPrefix = match (true) {\n            $connection instanceof PhpRedisConnection => $connection->client()->getOption(\\Redis::OPT_PREFIX),\n            $connection instanceof PredisConnection => $connection->client()->getOptions()->prefix,\n        };\n\n        $cachePrefix = $redisPrefix.$this->store->getPrefix();\n\n        $cacheTags = [];\n\n        foreach ($this->tags->getNames() as $name) {\n            $cacheTags[] = $cachePrefix.$this->tags->tagId($name);\n        }\n\n        $script = <<<'LUA'\n            local prefix = table.remove(ARGV, 1)\n\n            for i, key in ipairs(KEYS) do\n                redis.call('DEL', key)\n\n                for j, arg in ipairs(ARGV) do\n                    local zkey = string.gsub(key, prefix, \"\")\n                    redis.call('ZREM', arg, zkey)\n                end\n            end\n        LUA;\n\n        $entries = $this->tags->entries()\n            ->map(fn (string $key) => $this->store->getPrefix().$key)\n            ->chunk(1000);\n\n        foreach ($entries as $keysToBeDeleted) {\n            $connection->eval(\n                $script,\n                count($keysToBeDeleted),\n                ...$keysToBeDeleted,\n                ...[str_replace('-', '%-', $cachePrefix), ...$cacheTags]\n            );\n        }\n\n        $this->event(new CacheFlushed($this->getName()));\n\n        return true;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    protected function flushClusteredConnection()\n    {\n        $this->event(new CacheFlushing($this->getName()));\n\n        $this->flushValues();\n        $this->tags->flush();\n\n        $this->event(new CacheFlushed($this->getName()));\n\n        return true;\n    }\n\n    /**\n     * Flush the individual cache entries for the tags.\n     *\n     * @return void\n     */\n    protected function flushValues()\n    {\n        $entries = $this->tags->entries()\n            ->map(fn (string $key) => $this->store->getPrefix().$key)\n            ->chunk(1000);\n\n        $connection = $this->store->connection();\n\n        foreach ($entries as $cacheKeys) {\n            if ($connection instanceof PredisClusterConnection) {\n                $connection->pipeline(function ($connection) use ($cacheKeys) {\n                    foreach ($cacheKeys as $cacheKey) {\n                        $connection->del($cacheKey);\n                    }\n                });\n            } else {\n                $connection->del(...$cacheKeys);\n            }\n        }\n    }\n\n    /**\n     * Remove all stale reference entries from the tag set.\n     *\n     * @return bool\n     */\n    public function flushStale()\n    {\n        $this->tags->flushStaleEntries();\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/Repository.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse ArrayAccess;\nuse BadMethodCallException;\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Cache\\Events\\CacheFlushed;\nuse Illuminate\\Cache\\Events\\CacheFlushFailed;\nuse Illuminate\\Cache\\Events\\CacheFlushing;\nuse Illuminate\\Cache\\Events\\CacheHit;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushed;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushFailed;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushing;\nuse Illuminate\\Cache\\Events\\CacheMissed;\nuse Illuminate\\Cache\\Events\\ForgettingKey;\nuse Illuminate\\Cache\\Events\\KeyForgetFailed;\nuse Illuminate\\Cache\\Events\\KeyForgotten;\nuse Illuminate\\Cache\\Events\\KeyWriteFailed;\nuse Illuminate\\Cache\\Events\\KeyWritten;\nuse Illuminate\\Cache\\Events\\RetrievingKey;\nuse Illuminate\\Cache\\Events\\RetrievingManyKeys;\nuse Illuminate\\Cache\\Events\\WritingKey;\nuse Illuminate\\Cache\\Events\\WritingManyKeys;\nuse Illuminate\\Cache\\Limiters\\ConcurrencyLimiterBuilder;\nuse Illuminate\\Contracts\\Cache\\CanFlushLocks;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Repository as CacheContract;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\nuse function Illuminate\\Support\\defer;\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Cache\\Store\n */\nclass Repository implements ArrayAccess, CacheContract\n{\n    use InteractsWithTime, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Store\n     */\n    protected $store;\n\n    /**\n     * The event dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $events;\n\n    /**\n     * The default number of seconds to store items.\n     *\n     * @var int|null\n     */\n    protected $default = 3600;\n\n    /**\n     * The cache store configuration options.\n     *\n     * @var array\n     */\n    protected $config = [];\n\n    /**\n     * Create a new cache repository instance.\n     */\n    public function __construct(Store $store, array $config = [])\n    {\n        $this->store = $store;\n        $this->config = $config;\n    }\n\n    /**\n     * Determine if an item exists in the cache.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     */\n    public function has($key): bool\n    {\n        return ! is_null($this->get($key));\n    }\n\n    /**\n     * Determine if an item doesn't exist in the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @return bool\n     */\n    public function missing($key)\n    {\n        return ! $this->has($key);\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @param  mixed  $default\n     */\n    public function get($key, $default = null): mixed\n    {\n        if (is_array($key)) {\n            return $this->many($key);\n        }\n\n        $key = enum_value($key);\n\n        $this->event(new RetrievingKey($this->getName(), $key));\n\n        $value = $this->store->get($this->itemKey($key));\n\n        // If we could not find the cache value, we will fire the missed event and get\n        // the default value for this cache value. This default could be a callback\n        // so we will execute the value function which will resolve it if needed.\n        if (is_null($value)) {\n            $this->event(new CacheMissed($this->getName(), $key));\n\n            $value = value($default);\n        } else {\n            $this->event(new CacheHit($this->getName(), $key, $value));\n        }\n\n        return $value;\n    }\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        $this->event(new RetrievingManyKeys($this->getName(), $keys));\n\n        $values = $this->store->many((new Collection($keys))\n            ->map(fn ($value, $key) => is_string($key) ? $key : enum_value($value))\n            ->values()\n            ->all()\n        );\n\n        return (new Collection($values))\n            ->map(fn ($value, $key) => $this->handleManyResult($keys, $key, $value))\n            ->all();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getMultiple($keys, $default = null): iterable\n    {\n        $defaults = [];\n\n        foreach ($keys as $key) {\n            $defaults[enum_value($key)] = $default;\n        }\n\n        return $this->many($defaults);\n    }\n\n    /**\n     * Handle a result for the \"many\" method.\n     *\n     * @param  array  $keys\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function handleManyResult($keys, $key, $value)\n    {\n        // If we could not find the cache value, we will fire the missed event and get\n        // the default value for this cache value. This default could be a callback\n        // so we will execute the value function which will resolve it if needed.\n        if (is_null($value)) {\n            $this->event(new CacheMissed($this->getName(), $key));\n\n            return (isset($keys[$key]) && ! array_is_list($keys)) ? value($keys[$key]) : null;\n        }\n\n        // If we found a valid value we will fire the \"hit\" event and return the value\n        // back from this function. The \"hit\" event gives developers an opportunity\n        // to listen for every possible cache \"hit\" throughout this applications.\n        $this->event(new CacheHit($this->getName(), $key, $value));\n\n        return $value;\n    }\n\n    /**\n     * Retrieve an item from the cache and delete it.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function pull($key, $default = null)\n    {\n        return tap($this->get($key, $default), function () use ($key) {\n            $this->forget($key);\n        });\n    }\n\n    /**\n     * Retrieve a string item from the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  (\\Closure():(string|null))|string|null  $default\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function string($key, $default = null): string\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_string($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Cache value for key [%s] must be a string, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Retrieve an integer item from the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  (\\Closure():(int|null))|int|null  $default\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function integer($key, $default = null): int\n    {\n        $value = $this->get($key, $default);\n\n        if (is_int($value)) {\n            return $value;\n        }\n\n        if (filter_var($value, FILTER_VALIDATE_INT) !== false) {\n            return (int) $value;\n        }\n\n        throw new InvalidArgumentException(\n            sprintf('Cache value for key [%s] must be an integer, %s given.', $key, gettype($value))\n        );\n    }\n\n    /**\n     * Retrieve a float item from the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  (\\Closure():(float|null))|float|null  $default\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function float($key, $default = null): float\n    {\n        $value = $this->get($key, $default);\n\n        if (is_float($value)) {\n            return $value;\n        }\n\n        if (filter_var($value, FILTER_VALIDATE_FLOAT) !== false) {\n            return (float) $value;\n        }\n\n        throw new InvalidArgumentException(\n            sprintf('Cache value for key [%s] must be a float, %s given.', $key, gettype($value))\n        );\n    }\n\n    /**\n     * Retrieve a boolean item from the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  (\\Closure():(bool|null))|bool|null  $default\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function boolean($key, $default = null): bool\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_bool($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Cache value for key [%s] must be a boolean, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Retrieve an array item from the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  (\\Closure():(array<array-key, mixed>|null))|array<array-key, mixed>|null  $default\n     * @return array<array-key, mixed>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function array($key, $default = null): array\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_array($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Cache value for key [%s] must be an array, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Store an item in the cache.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function put($key, $value, $ttl = null)\n    {\n        if (is_array($key)) {\n            return $this->putMany($key, $value);\n        }\n\n        $key = enum_value($key);\n\n        if ($ttl === null) {\n            return $this->forever($key, $value);\n        }\n\n        $seconds = $this->getSeconds($ttl);\n\n        if ($seconds <= 0) {\n            return $this->forget($key);\n        }\n\n        $this->event(new WritingKey($this->getName(), $key, $value, $seconds));\n\n        $result = $this->store->put($this->itemKey($key), $value, $seconds);\n\n        if ($result) {\n            $this->event(new KeyWritten($this->getName(), $key, $value, $seconds));\n        } else {\n            $this->event(new KeyWriteFailed($this->getName(), $key, $value, $seconds));\n        }\n\n        return $result;\n    }\n\n    /**\n     * Store an item in the cache.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     */\n    public function set($key, $value, $ttl = null): bool\n    {\n        return $this->put($key, $value, $ttl);\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function putMany(array $values, $ttl = null)\n    {\n        if ($ttl === null) {\n            return $this->putManyForever($values);\n        }\n\n        $seconds = $this->getSeconds($ttl);\n\n        if ($seconds <= 0) {\n            return $this->deleteMultiple(array_keys($values));\n        }\n\n        $this->event(new WritingManyKeys($this->getName(), array_keys($values), array_values($values), $seconds));\n\n        $result = $this->store->putMany($values, $seconds);\n\n        foreach ($values as $key => $value) {\n            if ($result) {\n                $this->event(new KeyWritten($this->getName(), $key, $value, $seconds));\n            } else {\n                $this->event(new KeyWriteFailed($this->getName(), $key, $value, $seconds));\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Store multiple items in the cache indefinitely.\n     *\n     * @return bool\n     */\n    protected function putManyForever(array $values)\n    {\n        $result = true;\n\n        foreach ($values as $key => $value) {\n            if (! $this->forever($key, $value)) {\n                $result = false;\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function setMultiple($values, $ttl = null): bool\n    {\n        return $this->putMany(is_array($values) ? $values : iterator_to_array($values), $ttl);\n    }\n\n    /**\n     * Store an item in the cache if the key does not exist.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function add($key, $value, $ttl = null)\n    {\n        $key = enum_value($key);\n\n        $seconds = null;\n\n        if ($ttl !== null) {\n            $seconds = $this->getSeconds($ttl);\n\n            if ($seconds <= 0) {\n                return false;\n            }\n\n            // If the store has an \"add\" method we will call the method on the store so it\n            // has a chance to override this logic. Some drivers better support the way\n            // this operation should work with a total \"atomic\" implementation of it.\n            if (method_exists($this->store, 'add')) {\n                return $this->store->add(\n                    $this->itemKey($key), $value, $seconds\n                );\n            }\n        }\n\n        // If the value did not exist in the cache, we will put the value in the cache\n        // so it exists for subsequent requests. Then, we will return true so it is\n        // easy to know if the value gets added. Otherwise, we will return false.\n        if (is_null($this->get($key))) {\n            return $this->put($key, $value, $seconds);\n        }\n\n        return false;\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->store->increment(enum_value($key), $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->store->decrement(enum_value($key), $value);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        $key = enum_value($key);\n\n        $this->event(new WritingKey($this->getName(), $key, $value));\n\n        $result = $this->store->forever($this->itemKey($key), $value);\n\n        if ($result) {\n            $this->event(new KeyWritten($this->getName(), $key, $value));\n        } else {\n            $this->event(new KeyWriteFailed($this->getName(), $key, $value));\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  \\Closure|\\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function remember($key, $ttl, Closure $callback)\n    {\n        $value = $this->get($key);\n\n        // If the item exists in the cache we will just return this immediately and if\n        // not we will execute the given Closure and cache the result of that for a\n        // given number of seconds so it's available for all subsequent requests.\n        if (! is_null($value)) {\n            return $value;\n        }\n\n        $value = $callback();\n\n        $this->put($key, $value, value($ttl, $value));\n\n        return $value;\n    }\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result forever.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function sear($key, Closure $callback)\n    {\n        return $this->rememberForever($key, $callback);\n    }\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result forever.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function rememberForever($key, Closure $callback)\n    {\n        $value = $this->get($key);\n\n        // If the item exists in the cache we will just return this immediately\n        // and if not we will execute the given Closure and cache the result\n        // of that forever so it is available for all subsequent requests.\n        if (! is_null($value)) {\n            return $value;\n        }\n\n        $this->forever($key, $value = $callback());\n\n        return $value;\n    }\n\n    /**\n     * Retrieve an item from the cache by key, refreshing it in the background if it is stale.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  array{ 0: \\DateTimeInterface|\\DateInterval|int, 1: \\DateTimeInterface|\\DateInterval|int }  $ttl\n     * @param  (callable(): TCacheValue)  $callback\n     * @param  array{ seconds?: int, owner?: string }|null  $lock\n     * @param  bool  $alwaysDefer\n     * @return TCacheValue\n     */\n    public function flexible($key, $ttl, $callback, $lock = null, $alwaysDefer = false)\n    {\n        $key = enum_value($key);\n\n        [\n            $key => $value,\n            \"illuminate:cache:flexible:created:{$key}\" => $created,\n        ] = $this->many([$key, \"illuminate:cache:flexible:created:{$key}\"]);\n\n        if (in_array(null, [$value, $created], true)) {\n            return tap(value($callback), fn ($value) => $this->putMany([\n                $key => $value,\n                \"illuminate:cache:flexible:created:{$key}\" => Carbon::now()->getTimestamp(),\n            ], $ttl[1]));\n        }\n\n        if (($created + $this->getSeconds($ttl[0])) > Carbon::now()->getTimestamp()) {\n            return $value;\n        }\n\n        $refresh = function () use ($key, $ttl, $callback, $lock, $created) {\n            $this->store->lock(\n                \"illuminate:cache:flexible:lock:{$key}\",\n                $lock['seconds'] ?? 0,\n                $lock['owner'] ?? null,\n            )->get(function () use ($key, $callback, $created, $ttl) {\n                if ($created !== $this->get(\"illuminate:cache:flexible:created:{$key}\")) {\n                    return;\n                }\n\n                $this->putMany([\n                    $key => value($callback),\n                    \"illuminate:cache:flexible:created:{$key}\" => Carbon::now()->getTimestamp(),\n                ], $ttl[1]);\n            });\n        };\n\n        defer($refresh, \"illuminate:cache:flexible:{$key}\", $alwaysDefer);\n\n        return $value;\n    }\n\n    /**\n     * Set the expiration of a cached item.\n     *\n     * @param  string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|int  $ttl\n     * @return bool\n     */\n    public function touch($key, $ttl)\n    {\n        return $this->store->touch($this->itemKey($key), $this->getSeconds($ttl));\n    }\n\n    /**\n     * Execute a callback while holding an atomic lock on a cache mutex to prevent overlapping calls.\n     *\n     * @template TReturn\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  callable(): TReturn  $callback\n     * @param  int  $lockFor\n     * @param  int  $waitFor\n     * @param  string|null  $owner\n     * @return TReturn\n     *\n     * @throws \\Illuminate\\Contracts\\Cache\\LockTimeoutException\n     */\n    public function withoutOverlapping($key, callable $callback, $lockFor = 0, $waitFor = 10, $owner = null)\n    {\n        return $this->store->lock(enum_value($key), $lockFor, $owner)->block($waitFor, $callback);\n    }\n\n    /**\n     * Funnel a callback for a maximum number of simultaneous executions.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @return \\Illuminate\\Cache\\Limiters\\ConcurrencyLimiterBuilder\n     */\n    public function funnel($name)\n    {\n        if (! $this->store instanceof LockProvider) {\n            throw new BadMethodCallException('This cache store does not support locks.');\n        }\n\n        return new ConcurrencyLimiterBuilder($this, enum_value($name));\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        $key = enum_value($key);\n\n        $this->event(new ForgettingKey($this->getName(), $key));\n\n        return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) {\n            if ($result) {\n                $this->event(new KeyForgotten($this->getName(), $key));\n            } else {\n                $this->event(new KeyForgetFailed($this->getName(), $key));\n            }\n        });\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  \\UnitEnum|array|string  $key\n     */\n    public function delete($key): bool\n    {\n        return $this->forget($key);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function deleteMultiple($keys): bool\n    {\n        $result = true;\n\n        foreach ($keys as $key) {\n            if (! $this->forget($key)) {\n                $result = false;\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function clear(): bool\n    {\n        $this->event(new CacheFlushing($this->getName()));\n\n        $result = $this->store->flush();\n\n        if ($result) {\n            $this->event(new CacheFlushed($this->getName()));\n        } else {\n            $this->event(new CacheFlushFailed($this->getName()));\n        }\n\n        return $result;\n    }\n\n    /**\n     * Flush all locks from the cache store.\n     *\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function flushLocks(): bool\n    {\n        $store = $this->getStore();\n\n        if (! $this->supportsFlushingLocks()) {\n            throw new BadMethodCallException('This cache store does not support flushing locks.');\n        }\n\n        $this->event(new CacheLocksFlushing($this->getName()));\n\n        $result = $store->flushLocks();\n\n        if ($result) {\n            $this->event(new CacheLocksFlushed($this->getName()));\n        } else {\n            $this->event(new CacheLocksFlushFailed($this->getName()));\n        }\n\n        return $result;\n    }\n\n    /**\n     * Begin executing a new tags operation if the store supports it.\n     *\n     * @param  mixed  $names\n     * @return \\Illuminate\\Cache\\TaggedCache\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function tags($names)\n    {\n        if (! $this->supportsTags()) {\n            throw new BadMethodCallException('This cache store does not support tagging.');\n        }\n\n        $cache = $this->store->tags(is_array($names) ? $names : func_get_args());\n\n        $cache->config = $this->config;\n\n        if (! is_null($this->events)) {\n            $cache->setEventDispatcher($this->events);\n        }\n\n        return $cache->setDefaultCacheTime($this->default);\n    }\n\n    /**\n     * Format the key for a cache item.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function itemKey($key)\n    {\n        return $key;\n    }\n\n    /**\n     * Calculate the number of seconds for the given TTL.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $ttl\n     * @return int\n     */\n    protected function getSeconds($ttl)\n    {\n        $duration = $this->parseDateInterval($ttl);\n\n        if ($duration instanceof DateTimeInterface) {\n            $duration = (int) ceil(\n                Carbon::now()->diffInMilliseconds($duration, false) / 1000\n            );\n        }\n\n        return (int) ($duration > 0 ? $duration : 0);\n    }\n\n    /**\n     * Get the name of the cache store.\n     *\n     * @return string|null\n     */\n    public function getName()\n    {\n        return $this->config['store'] ?? null;\n    }\n\n    /**\n     * Determine if the current store supports tags.\n     *\n     * @return bool\n     */\n    public function supportsTags()\n    {\n        return method_exists($this->store, 'tags');\n    }\n\n    /**\n     * Determine if the current store supports flushing locks.\n     */\n    public function supportsFlushingLocks(): bool\n    {\n        return $this->store instanceof CanFlushLocks;\n    }\n\n    /**\n     * Get the default cache time.\n     *\n     * @return int|null\n     */\n    public function getDefaultCacheTime()\n    {\n        return $this->default;\n    }\n\n    /**\n     * Set the default cache time in seconds.\n     *\n     * @param  int|null  $seconds\n     * @return $this\n     */\n    public function setDefaultCacheTime($seconds)\n    {\n        $this->default = $seconds;\n\n        return $this;\n    }\n\n    /**\n     * Get the cache store implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Store\n     */\n    public function getStore()\n    {\n        return $this->store;\n    }\n\n    /**\n     * Set the cache store implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @return static\n     */\n    public function setStore($store)\n    {\n        $this->store = $store;\n\n        return $this;\n    }\n\n    /**\n     * Fire an event for this cache instance.\n     *\n     * @param  object|string  $event\n     * @return void\n     */\n    protected function event($event)\n    {\n        $this->events?->dispatch($event);\n    }\n\n    /**\n     * Get the event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getEventDispatcher()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Set the event dispatcher instance.\n     *\n     * @return void\n     */\n    public function setEventDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Determine if a cached value exists.\n     *\n     * @param  \\UnitEnum|string  $offset\n     */\n    public function offsetExists($offset): bool\n    {\n        return $this->has($offset);\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  \\UnitEnum|string  $offset\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->get($offset);\n    }\n\n    /**\n     * Store an item in the cache for the default time.\n     *\n     * @param  \\UnitEnum|string  $offset\n     * @param  mixed  $value\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->put($offset, $value, $this->default);\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  \\UnitEnum|string  $offset\n     */\n    public function offsetUnset($offset): void\n    {\n        $this->forget($offset);\n    }\n\n    /**\n     * Handle dynamic calls into macros or pass missing methods to the store.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->store->$method(...$parameters);\n    }\n\n    /**\n     * Clone cache repository instance.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->store = clone $this->store;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/RetrievesMultipleKeys.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Support\\Collection;\n\ntrait RetrievesMultipleKeys\n{\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function many(array $keys)\n    {\n        $return = [];\n\n        $keys = (new Collection($keys))\n            ->mapWithKeys(fn ($value, $key) => [is_string($key) ? $key : $value => is_string($key) ? $value : null])\n            ->all();\n\n        foreach ($keys as $key => $default) {\n            /** @phpstan-ignore arguments.count (some clients don't accept a default) */\n            $return[$key] = $this->get($key, $default);\n        }\n\n        return $return;\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds)\n    {\n        $manyResult = null;\n\n        foreach ($values as $key => $value) {\n            $result = $this->put($key, $value, $seconds);\n\n            $manyResult = is_null($manyResult) ? $result : $result && $manyResult;\n        }\n\n        return $manyResult ?: false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/SessionStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass SessionStore implements Store\n{\n    use InteractsWithTime, RetrievesMultipleKeys;\n\n    /**\n     * The key for cache items.\n     *\n     * @var string\n     */\n    public $key;\n\n    /**\n     * The session instance.\n     *\n     * @var \\Illuminate\\Contracts\\Session\\Session\n     */\n    public $session;\n\n    /**\n     * Create a new session cache store.\n     *\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @param  string  $key\n     */\n    public function __construct($session, $key = '_cache')\n    {\n        $this->key = $key;\n        $this->session = $session;\n    }\n\n    /**\n     * Get all of the cached values and their expiration times.\n     *\n     * @return array<string, array{value: mixed, expiresAt: float}>\n     */\n    public function all()\n    {\n        return $this->session->get($this->key, []);\n    }\n\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key)\n    {\n        if (! $this->session->exists($this->itemKey($key))) {\n            return;\n        }\n\n        $item = $this->session->get($this->itemKey($key));\n\n        $expiresAt = $item['expiresAt'] ?? 0;\n\n        if ($this->isExpired($expiresAt)) {\n            $this->forget($key);\n\n            return;\n        }\n\n        return $item['value'];\n    }\n\n    /**\n     * Determine if the given expiration time is expired.\n     *\n     * @param  int|float  $expiresAt\n     * @return bool\n     */\n    protected function isExpired($expiresAt)\n    {\n        return $expiresAt !== 0 && (Carbon::now()->getPreciseTimestamp(3) / 1000) >= $expiresAt;\n    }\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds)\n    {\n        $this->session->put($this->itemKey($key), [\n            'value' => $value,\n            'expiresAt' => $this->toTimestamp($seconds),\n        ]);\n\n        return true;\n    }\n\n    /**\n     * Get the UNIX timestamp, with milliseconds, for the given number of seconds in the future.\n     *\n     * @param  int  $seconds\n     * @return float\n     */\n    protected function toTimestamp($seconds)\n    {\n        return $seconds > 0 ? (Carbon::now()->getPreciseTimestamp(3) / 1000) + $seconds : 0;\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function increment($key, $value = 1)\n    {\n        if (! is_null($existing = $this->get($key))) {\n            return tap(((int) $existing) + $value, function ($incremented) use ($key) {\n                $this->session->put($this->itemKey(\"{$key}.value\"), $incremented);\n            });\n        }\n\n        $this->forever($key, $value);\n\n        return $value;\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->increment($key, $value * -1);\n    }\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value)\n    {\n        return $this->put($key, $value, 0);\n    }\n\n    /**\n     * Adjust the expiration time of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds)\n    {\n        $value = $this->get($key);\n\n        if (is_null($value)) {\n            return false;\n        }\n\n        $this->put($key, $value, $seconds);\n\n        return true;\n    }\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key)\n    {\n        if ($this->session->exists($this->itemKey($key))) {\n            $this->session->forget($this->itemKey($key));\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->session->put($this->key, []);\n\n        return true;\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function itemKey($key)\n    {\n        return \"{$this->key}.{$key}\";\n    }\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/TagSet.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Store;\n\nclass TagSet\n{\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Store\n     */\n    protected $store;\n\n    /**\n     * The tag names.\n     *\n     * @var array\n     */\n    protected $names = [];\n\n    /**\n     * Create a new TagSet instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @param  array  $names\n     */\n    public function __construct(Store $store, array $names = [])\n    {\n        $this->store = $store;\n        $this->names = $names;\n    }\n\n    /**\n     * Reset all tags in the set.\n     *\n     * @return void\n     */\n    public function reset()\n    {\n        array_walk($this->names, $this->resetTag(...));\n    }\n\n    /**\n     * Reset the tag and return the new tag identifier.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function resetTag($name)\n    {\n        $this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));\n\n        return $id;\n    }\n\n    /**\n     * Flush all the tags in the set.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        array_walk($this->names, $this->flushTag(...));\n    }\n\n    /**\n     * Flush the tag from the cache.\n     *\n     * @param  string  $name\n     */\n    public function flushTag($name)\n    {\n        $this->store->forget($this->tagKey($name));\n    }\n\n    /**\n     * Get a unique namespace that changes when any of the tags are flushed.\n     *\n     * @return string\n     */\n    public function getNamespace()\n    {\n        return implode('|', $this->tagIds());\n    }\n\n    /**\n     * Get an array of tag identifiers for all of the tags in the set.\n     *\n     * @return array\n     */\n    protected function tagIds()\n    {\n        return array_map($this->tagId(...), $this->names);\n    }\n\n    /**\n     * Get the unique tag identifier for a given tag.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function tagId($name)\n    {\n        return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);\n    }\n\n    /**\n     * Get the tag identifier key for a given tag.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function tagKey($name)\n    {\n        return 'tag:'.$name.':key';\n    }\n\n    /**\n     * Get all of the tag names in the set.\n     *\n     * @return array\n     */\n    public function getNames()\n    {\n        return $this->names;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/TaggableStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Store;\n\nabstract class TaggableStore implements Store\n{\n    /**\n     * Begin executing a new tags operation.\n     *\n     * @param  mixed  $names\n     * @return \\Illuminate\\Cache\\TaggedCache\n     */\n    public function tags($names)\n    {\n        return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/TaggedCache.php",
    "content": "<?php\n\nnamespace Illuminate\\Cache;\n\nuse Illuminate\\Cache\\Events\\CacheFlushed;\nuse Illuminate\\Cache\\Events\\CacheFlushing;\nuse Illuminate\\Contracts\\Cache\\Store;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass TaggedCache extends Repository\n{\n    use RetrievesMultipleKeys {\n        putMany as putManyAlias;\n    }\n\n    /**\n     * The tag set instance.\n     *\n     * @var \\Illuminate\\Cache\\TagSet\n     */\n    protected $tags;\n\n    /**\n     * Create a new tagged cache instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @param  \\Illuminate\\Cache\\TagSet  $tags\n     */\n    public function __construct(Store $store, TagSet $tags)\n    {\n        parent::__construct($store);\n\n        $this->tags = $tags;\n    }\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int|null  $ttl\n     * @return bool\n     */\n    public function putMany(array $values, $ttl = null)\n    {\n        if ($ttl === null) {\n            return $this->putManyForever($values);\n        }\n\n        return $this->putManyAlias($values, $ttl);\n    }\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1)\n    {\n        return $this->store->increment($this->itemKey(enum_value($key)), $value);\n    }\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1)\n    {\n        return $this->store->decrement($this->itemKey(enum_value($key)), $value);\n    }\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush()\n    {\n        $this->event(new CacheFlushing($this->getName()));\n\n        $this->tags->reset();\n\n        $this->event(new CacheFlushed($this->getName()));\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function itemKey($key)\n    {\n        return $this->taggedItemKey($key);\n    }\n\n    /**\n     * Get a fully-qualified key for a tagged item.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    public function taggedItemKey($key)\n    {\n        return sha1($this->tags->getNamespace()).':'.$key;\n    }\n\n    /**\n     * Fire an event for this cache instance.\n     *\n     * @param  object  $event\n     * @return void\n     */\n    protected function event($event)\n    {\n        if (method_exists($event, 'setTags')) {\n            $event->setTags($this->tags->getNames());\n        }\n\n        parent::event($event);\n    }\n\n    /**\n     * Get the tag set instance.\n     *\n     * @return \\Illuminate\\Cache\\TagSet\n     */\n    public function getTags()\n    {\n        return $this->tags;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cache/composer.json",
    "content": "{\n    \"name\": \"illuminate/cache\",\n    \"description\": \"The Illuminate Cache package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"provide\": {\n        \"psr/simple-cache-implementation\": \"1.0 || 2.0 || 3.0\"\n    },\n    \"suggest\": {\n        \"ext-apcu\": \"Required to use the APC cache driver.\",\n        \"ext-filter\": \"Required to use the DynamoDb cache driver.\",\n        \"ext-memcached\": \"Required to use the memcache cache driver.\",\n        \"illuminate/database\": \"Required to use the database cache driver (^13.0).\",\n        \"illuminate/filesystem\": \"Required to use the file cache driver (^13.0).\",\n        \"illuminate/redis\": \"Required to use the redis cache driver (^13.0).\",\n        \"symfony/cache\": \"Required to use PSR-6 cache bridge (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Cache\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Collections/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Collections/Arr.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArgumentCountError;\nuse ArrayAccess;\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse JsonSerializable;\nuse Random\\Randomizer;\nuse Traversable;\nuse WeakMap;\n\nclass Arr\n{\n    use Macroable;\n\n    /**\n     * Determine whether the given value is array accessible.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    public static function accessible($value)\n    {\n        return is_array($value) || $value instanceof ArrayAccess;\n    }\n\n    /**\n     * Determine whether the given value is arrayable.\n     *\n     * @param  mixed  $value\n     * @return ($value is array\n     *     ? true\n     *     : ($value is \\Illuminate\\Contracts\\Support\\Arrayable\n     *         ? true\n     *         : ($value is \\Traversable\n     *             ? true\n     *             : ($value is \\Illuminate\\Contracts\\Support\\Jsonable\n     *                 ? true\n     *                 : ($value is \\JsonSerializable ? true : false)\n     *             )\n     *         )\n     *     )\n     * )\n     */\n    public static function arrayable($value)\n    {\n        return is_array($value)\n            || $value instanceof Arrayable\n            || $value instanceof Traversable\n            || $value instanceof Jsonable\n            || $value instanceof JsonSerializable;\n    }\n\n    /**\n     * Add an element to an array using \"dot\" notation if it doesn't exist.\n     *\n     * @param  array  $array\n     * @param  string|int|float  $key\n     * @param  mixed  $value\n     * @return array\n     */\n    public static function add($array, $key, $value)\n    {\n        if (is_null(static::get($array, $key))) {\n            static::set($array, $key, $value);\n        }\n\n        return $array;\n    }\n\n    /**\n     * Get an array item from an array using \"dot\" notation.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function array(ArrayAccess|array $array, string|int|null $key, ?array $default = null): array\n    {\n        $value = Arr::get($array, $key, $default);\n\n        if (! is_array($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Array value for key [%s] must be an array, %s found.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get a boolean item from an array using \"dot\" notation.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function boolean(ArrayAccess|array $array, string|int|null $key, ?bool $default = null): bool\n    {\n        $value = Arr::get($array, $key, $default);\n\n        if (! is_bool($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Array value for key [%s] must be a boolean, %s found.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Collapse an array of arrays into a single array.\n     *\n     * @param  iterable  $array\n     * @return array\n     */\n    public static function collapse($array)\n    {\n        $results = [];\n\n        foreach ($array as $values) {\n            if ($values instanceof Collection) {\n                $results[] = $values->all();\n            } elseif (is_array($values)) {\n                $results[] = $values;\n            }\n        }\n\n        return array_merge([], ...$results);\n    }\n\n    /**\n     * Cross join the given arrays, returning all possible permutations.\n     *\n     * @template TValue\n     *\n     * @param  iterable<TValue>  ...$arrays\n     * @return array<int, array<array-key, TValue>>\n     */\n    public static function crossJoin(...$arrays)\n    {\n        $results = [[]];\n\n        foreach ($arrays as $index => $array) {\n            $append = [];\n\n            foreach ($results as $product) {\n                foreach ($array as $item) {\n                    $product[$index] = $item;\n\n                    $append[] = $product;\n                }\n            }\n\n            $results = $append;\n        }\n\n        return $results;\n    }\n\n    /**\n     * Divide an array into two arrays. One with keys and the other with values.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @return array{TKey[], TValue[]}\n     */\n    public static function divide($array)\n    {\n        return [array_keys($array), array_values($array)];\n    }\n\n    /**\n     * Flatten a multi-dimensional associative array with dots.\n     *\n     * @param  iterable  $array\n     * @param  string  $prepend\n     * @param  int  $depth\n     * @return array\n     */\n    public static function dot($array, $prepend = '', $depth = INF)\n    {\n        $results = [];\n\n        $flatten = function ($data, $prefix, $currentDepth) use (&$results, &$flatten, $depth): void {\n            foreach ($data as $key => $value) {\n                $newKey = $prefix.$key;\n\n                if (is_array($value) && ! empty($value) && $currentDepth < $depth) {\n                    $flatten($value, $newKey.'.', $currentDepth + 1);\n                } else {\n                    $results[$newKey] = $value;\n                }\n            }\n        };\n\n        $flatten($array, $prepend, 0);\n\n        // Destroy self-referencing closure to avoid memory leak...\n        $flatten = null;\n\n        return $results;\n    }\n\n    /**\n     * Convert a flatten \"dot\" notation array into an expanded array.\n     *\n     * @param  iterable  $array\n     * @return array\n     */\n    public static function undot($array)\n    {\n        $results = [];\n\n        foreach ($array as $key => $value) {\n            static::set($results, $key, $value);\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get all of the given array except for a specified array of keys.\n     *\n     * @param  array  $array\n     * @param  array|string|int|float  $keys\n     * @return array\n     */\n    public static function except($array, $keys)\n    {\n        static::forget($array, $keys);\n\n        return $array;\n    }\n\n    /**\n     * Get all of the given array except for a specified array of values.\n     *\n     * @param  array  $array\n     * @param  mixed  $values\n     * @param  bool  $strict\n     * @return array\n     */\n    public static function exceptValues($array, $values, $strict = false)\n    {\n        $values = (array) $values;\n\n        return array_filter($array, function ($value) use ($values, $strict) {\n            return ! in_array($value, $values, $strict);\n        });\n    }\n\n    /**\n     * Determine if the given key exists in the provided array.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|int|float  $key\n     * @return bool\n     */\n    public static function exists($array, $key)\n    {\n        if ($array instanceof Enumerable) {\n            return $array->has($key);\n        }\n\n        if ($array instanceof ArrayAccess) {\n            return $array->offsetExists($key);\n        }\n\n        if (is_float($key) || is_null($key)) {\n            $key = (string) $key;\n        }\n\n        return array_key_exists($key, $array);\n    }\n\n    /**\n     * Return the first element in an iterable passing a given truth test.\n     *\n     * @template TKey\n     * @template TValue\n     * @template TFirstDefault\n     *\n     * @param  iterable<TKey, TValue>  $array\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TFirstDefault|(\\Closure(): TFirstDefault)  $default\n     * @return TValue|TFirstDefault\n     */\n    public static function first($array, ?callable $callback = null, $default = null)\n    {\n        if (is_null($callback)) {\n            if (empty($array)) {\n                return value($default);\n            }\n\n            if (is_array($array)) {\n                return array_first($array);\n            }\n\n            foreach ($array as $item) {\n                return $item;\n            }\n\n            return value($default);\n        }\n\n        $array = static::from($array);\n\n        $key = array_find_key($array, $callback);\n\n        return $key !== null ? $array[$key] : value($default);\n    }\n\n    /**\n     * Return the last element in an array passing a given truth test.\n     *\n     * @template TKey\n     * @template TValue\n     * @template TLastDefault\n     *\n     * @param  iterable<TKey, TValue>  $array\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TLastDefault|(\\Closure(): TLastDefault)  $default\n     * @return TValue|TLastDefault\n     */\n    public static function last($array, ?callable $callback = null, $default = null)\n    {\n        if (is_null($callback)) {\n            return empty($array) ? value($default) : array_last($array);\n        }\n\n        return static::first(array_reverse($array, true), $callback, $default);\n    }\n\n    /**\n     * Take the first or last {$limit} items from an array.\n     *\n     * @param  array  $array\n     * @param  int  $limit\n     * @return array\n     */\n    public static function take($array, $limit)\n    {\n        if ($limit < 0) {\n            return array_slice($array, $limit, abs($limit));\n        }\n\n        return array_slice($array, 0, $limit);\n    }\n\n    /**\n     * Flatten a multi-dimensional array into a single level.\n     *\n     * @param  iterable  $array\n     * @param  int  $depth\n     * @return array\n     */\n    public static function flatten($array, $depth = INF)\n    {\n        $result = [];\n\n        foreach ($array as $item) {\n            $item = $item instanceof Collection ? $item->all() : $item;\n\n            if (! is_array($item)) {\n                $result[] = $item;\n            } else {\n                $values = $depth === 1\n                    ? array_values($item)\n                    : static::flatten($item, $depth - 1);\n\n                foreach ($values as $value) {\n                    $result[] = $value;\n                }\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get a float item from an array using \"dot\" notation.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function float(ArrayAccess|array $array, string|int|null $key, ?float $default = null): float\n    {\n        $value = Arr::get($array, $key, $default);\n\n        if (! is_float($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Array value for key [%s] must be a float, %s found.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Remove one or many array items from a given array using \"dot\" notation.\n     *\n     * @param  array  $array\n     * @param  array|string|int|float  $keys\n     * @return void\n     */\n    public static function forget(&$array, $keys)\n    {\n        $original = &$array;\n\n        $keys = (array) $keys;\n\n        if (count($keys) === 0) {\n            return;\n        }\n\n        foreach ($keys as $key) {\n            // if the exact key exists in the top-level, remove it\n            if (static::exists($array, $key)) {\n                unset($array[$key]);\n\n                continue;\n            }\n\n            $parts = explode('.', $key);\n\n            // clean up before each pass\n            $array = &$original;\n\n            while (count($parts) > 1) {\n                $part = array_shift($parts);\n\n                if (isset($array[$part]) && static::accessible($array[$part])) {\n                    $array = &$array[$part];\n                } else {\n                    continue 2;\n                }\n            }\n\n            unset($array[array_shift($parts)]);\n        }\n    }\n\n    /**\n     * Get the underlying array of items from the given argument.\n     *\n     * @template TKey of array-key = array-key\n     * @template TValue = mixed\n     *\n     * @param  array<TKey, TValue>|Enumerable<TKey, TValue>|Arrayable<TKey, TValue>|WeakMap<object, TValue>|Traversable<TKey, TValue>|Jsonable|JsonSerializable|object  $items\n     * @return ($items is WeakMap ? list<TValue> : array<TKey, TValue>)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function from($items)\n    {\n        return match (true) {\n            is_array($items) => $items,\n            $items instanceof Enumerable => $items->all(),\n            $items instanceof Arrayable => $items->toArray(),\n            $items instanceof WeakMap => iterator_to_array($items, false),\n            $items instanceof Traversable => iterator_to_array($items),\n            $items instanceof Jsonable => json_decode($items->toJson(), true),\n            $items instanceof JsonSerializable => (array) $items->jsonSerialize(),\n            is_object($items) => (array) $items,\n            default => throw new InvalidArgumentException('Items cannot be represented by a scalar value.'),\n        };\n    }\n\n    /**\n     * Get an item from an array using \"dot\" notation.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|int|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public static function get($array, $key, $default = null)\n    {\n        if (! static::accessible($array)) {\n            return value($default);\n        }\n\n        if (is_null($key)) {\n            return $array;\n        }\n\n        if (static::exists($array, $key)) {\n            return $array[$key];\n        }\n\n        if (! str_contains($key, '.')) {\n            return value($default);\n        }\n\n        foreach (explode('.', $key) as $segment) {\n            if (static::accessible($array) && static::exists($array, $segment)) {\n                $array = $array[$segment];\n            } else {\n                return value($default);\n            }\n        }\n\n        return $array;\n    }\n\n    /**\n     * Check if an item or items exist in an array using \"dot\" notation.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|array  $keys\n     * @return bool\n     */\n    public static function has($array, $keys)\n    {\n        $keys = (array) $keys;\n\n        if (! $array || $keys === []) {\n            return false;\n        }\n\n        foreach ($keys as $key) {\n            $subKeyArray = $array;\n\n            if (static::exists($array, $key)) {\n                continue;\n            }\n\n            foreach (explode('.', $key) as $segment) {\n                if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {\n                    $subKeyArray = $subKeyArray[$segment];\n                } else {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if all keys exist in an array using \"dot\" notation.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|array  $keys\n     * @return bool\n     */\n    public static function hasAll($array, $keys)\n    {\n        $keys = (array) $keys;\n\n        if (! $array || $keys === []) {\n            return false;\n        }\n\n        foreach ($keys as $key) {\n            if (! static::has($array, $key)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if any of the keys exist in an array using \"dot\" notation.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|array  $keys\n     * @return bool\n     */\n    public static function hasAny($array, $keys)\n    {\n        if (is_null($keys)) {\n            return false;\n        }\n\n        $keys = (array) $keys;\n\n        if (! $array) {\n            return false;\n        }\n\n        if ($keys === []) {\n            return false;\n        }\n\n        foreach ($keys as $key) {\n            if (static::has($array, $key)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if all items pass the given truth test.\n     *\n     * @param  iterable  $array\n     * @param  (callable(mixed, array-key): bool)  $callback\n     * @return bool\n     */\n    public static function every($array, callable $callback)\n    {\n        return array_all($array, $callback);\n    }\n\n    /**\n     * Determine if some items pass the given truth test.\n     *\n     * @param  iterable  $array\n     * @param  (callable(mixed, array-key): bool)  $callback\n     * @return bool\n     */\n    public static function some($array, callable $callback)\n    {\n        return array_any($array, $callback);\n    }\n\n    /**\n     * Get an integer item from an array using \"dot\" notation.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function integer(ArrayAccess|array $array, string|int|null $key, ?int $default = null): int\n    {\n        $value = Arr::get($array, $key, $default);\n\n        if (! is_int($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Array value for key [%s] must be an integer, %s found.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Determines if an array is associative.\n     *\n     * An array is \"associative\" if it doesn't have sequential numerical keys beginning with zero.\n     *\n     * @param  array  $array\n     * @return ($array is list ? false : true)\n     */\n    public static function isAssoc(array $array)\n    {\n        return ! array_is_list($array);\n    }\n\n    /**\n     * Determines if an array is a list.\n     *\n     * An array is a \"list\" if all array keys are sequential integers starting from 0 with no gaps in between.\n     *\n     * @param  array  $array\n     * @return ($array is list ? true : false)\n     */\n    public static function isList($array)\n    {\n        return array_is_list($array);\n    }\n\n    /**\n     * Join all items using a string. The final items can use a separate glue string.\n     *\n     * @param  array  $array\n     * @param  string  $glue\n     * @param  string  $finalGlue\n     * @return string\n     */\n    public static function join($array, $glue, $finalGlue = '')\n    {\n        if ($finalGlue === '') {\n            return implode($glue, $array);\n        }\n\n        if (count($array) === 0) {\n            return '';\n        }\n\n        if (count($array) === 1) {\n            return array_last($array);\n        }\n\n        $finalItem = array_pop($array);\n\n        return implode($glue, $array).$finalGlue.$finalItem;\n    }\n\n    /**\n     * Key an associative array by a field or using a callback.\n     *\n     * @param  iterable  $array\n     * @param  callable|array|string  $keyBy\n     * @return array\n     */\n    public static function keyBy($array, $keyBy)\n    {\n        return (new Collection($array))->keyBy($keyBy)->all();\n    }\n\n    /**\n     * Prepend the key names of an associative array.\n     *\n     * @param  array  $array\n     * @param  string  $prependWith\n     * @return array\n     */\n    public static function prependKeysWith($array, $prependWith)\n    {\n        return static::mapWithKeys($array, fn ($item, $key) => [$prependWith.$key => $item]);\n    }\n\n    /**\n     * Get a subset of the items from the given array.\n     *\n     * @param  array  $array\n     * @param  array|string  $keys\n     * @return array\n     */\n    public static function only($array, $keys)\n    {\n        return array_intersect_key($array, array_flip((array) $keys));\n    }\n\n    /**\n     * Get a subset of the items from the given array by value.\n     *\n     * @param  array  $array\n     * @param  mixed  $values\n     * @param  bool  $strict\n     * @return array\n     */\n    public static function onlyValues($array, $values, $strict = false)\n    {\n        $values = (array) $values;\n\n        return array_filter($array, function ($value) use ($values, $strict) {\n            return in_array($value, $values, $strict);\n        });\n    }\n\n    /**\n     * Select an array of values from an array.\n     *\n     * @param  array  $array\n     * @param  array|string  $keys\n     * @return array\n     */\n    public static function select($array, $keys)\n    {\n        $keys = static::wrap($keys);\n\n        return static::map($array, function ($item) use ($keys) {\n            $result = [];\n\n            foreach ($keys as $key) {\n                if (Arr::accessible($item) && Arr::exists($item, $key)) {\n                    $result[$key] = $item[$key];\n                } elseif (is_object($item) && isset($item->{$key})) {\n                    $result[$key] = $item->{$key};\n                }\n            }\n\n            return $result;\n        });\n    }\n\n    /**\n     * Pluck an array of values from an array.\n     *\n     * @param  iterable  $array\n     * @param  string|array|int|Closure|null  $value\n     * @param  string|array|Closure|null  $key\n     * @return array\n     */\n    public static function pluck($array, $value, $key = null)\n    {\n        $results = [];\n\n        [$value, $key] = static::explodePluckParameters($value, $key);\n\n        foreach ($array as $item) {\n            $itemValue = $value instanceof Closure\n                ? $value($item)\n                : data_get($item, $value);\n\n            // If the key is \"null\", we will just append the value to the array and keep\n            // looping. Otherwise we will key the array using the value of the key we\n            // received from the developer. Then we'll return the final array form.\n            if (is_null($key)) {\n                $results[] = $itemValue;\n            } else {\n                $itemKey = $key instanceof Closure\n                    ? $key($item)\n                    : data_get($item, $key);\n\n                if (is_object($itemKey) && method_exists($itemKey, '__toString')) {\n                    $itemKey = (string) $itemKey;\n                }\n\n                $results[$itemKey] = $itemValue;\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Explode the \"value\" and \"key\" arguments passed to \"pluck\".\n     *\n     * @param  Closure|array|string  $value\n     * @param  string|array|Closure|null  $key\n     * @return array\n     */\n    protected static function explodePluckParameters($value, $key)\n    {\n        $value = is_string($value) ? explode('.', $value) : $value;\n\n        $key = is_null($key) || is_array($key) || $key instanceof Closure ? $key : explode('.', $key);\n\n        return [$value, $key];\n    }\n\n    /**\n     * Run a map over each of the items in the array.\n     *\n     * @param  array  $array\n     * @param  callable  $callback\n     * @return array\n     */\n    public static function map(array $array, callable $callback)\n    {\n        $keys = array_keys($array);\n\n        try {\n            $items = array_map($callback, $array, $keys);\n        } catch (ArgumentCountError) {\n            $items = array_map($callback, $array);\n        }\n\n        return array_combine($keys, $items);\n    }\n\n    /**\n     * Run an associative map over each of the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TKey\n     * @template TValue\n     * @template TMapWithKeysKey of array-key\n     * @template TMapWithKeysValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback\n     * @return array\n     */\n    public static function mapWithKeys(array $array, callable $callback)\n    {\n        $result = [];\n\n        foreach ($array as $key => $value) {\n            $assoc = $callback($value, $key);\n\n            foreach ($assoc as $mapKey => $mapValue) {\n                $result[$mapKey] = $mapValue;\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Run a map over each nested chunk of items.\n     *\n     * @template TKey\n     * @template TValue\n     *\n     * @param  array<TKey, array>  $array\n     * @param  callable(mixed...): TValue  $callback\n     * @return array<TKey, TValue>\n     */\n    public static function mapSpread(array $array, callable $callback)\n    {\n        return static::map($array, function ($chunk, $key) use ($callback) {\n            $chunk[] = $key;\n\n            return $callback(...$chunk);\n        });\n    }\n\n    /**\n     * Push an item onto the beginning of an array.\n     *\n     * @param  array  $array\n     * @param  mixed  $value\n     * @param  mixed  $key\n     * @return array\n     */\n    public static function prepend($array, $value, $key = null)\n    {\n        if (func_num_args() == 2) {\n            array_unshift($array, $value);\n        } else {\n            $array = [$key => $value] + $array;\n        }\n\n        return $array;\n    }\n\n    /**\n     * Get a value from the array, and remove it.\n     *\n     * @param  array  $array\n     * @param  string|int  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public static function pull(&$array, $key, $default = null)\n    {\n        $value = static::get($array, $key, $default);\n\n        static::forget($array, $key);\n\n        return $value;\n    }\n\n    /**\n     * Convert the array into a query string.\n     *\n     * @param  array  $array\n     * @return string\n     */\n    public static function query($array)\n    {\n        return http_build_query($array, '', '&', PHP_QUERY_RFC3986);\n    }\n\n    /**\n     * Get one or a specified number of random values from an array.\n     *\n     * @param  array  $array\n     * @param  int|null  $number\n     * @param  bool  $preserveKeys\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function random($array, $number = null, $preserveKeys = false)\n    {\n        $requested = is_null($number) ? 1 : $number;\n\n        $count = count($array);\n\n        if ($requested > $count) {\n            throw new InvalidArgumentException(\n                \"You requested {$requested} items, but there are only {$count} items available.\"\n            );\n        }\n\n        if (empty($array) || (! is_null($number) && $number <= 0)) {\n            return is_null($number) ? null : [];\n        }\n\n        $keys = (new Randomizer)->pickArrayKeys($array, $requested);\n\n        if (is_null($number)) {\n            return $array[$keys[0]];\n        }\n\n        $results = [];\n\n        if ($preserveKeys) {\n            foreach ($keys as $key) {\n                $results[$key] = $array[$key];\n            }\n        } else {\n            foreach ($keys as $key) {\n                $results[] = $array[$key];\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Set an array item to a given value using \"dot\" notation.\n     *\n     * If no key is given to the method, the entire array will be replaced.\n     *\n     * @param  array  $array\n     * @param  string|int|null  $key\n     * @param  mixed  $value\n     * @return array\n     */\n    public static function set(&$array, $key, $value)\n    {\n        if (is_null($key)) {\n            return $array = $value;\n        }\n\n        $keys = explode('.', $key);\n\n        foreach ($keys as $i => $key) {\n            if (count($keys) === 1) {\n                break;\n            }\n\n            unset($keys[$i]);\n\n            // If the key doesn't exist at this depth, we will just create an empty array\n            // to hold the next value, allowing us to create the arrays to hold final\n            // values at the correct depth. Then we'll keep digging into the array.\n            if (! isset($array[$key]) || ! is_array($array[$key])) {\n                $array[$key] = [];\n            }\n\n            $array = &$array[$key];\n        }\n\n        $array[array_shift($keys)] = $value;\n\n        return $array;\n    }\n\n    /**\n     * Push an item into an array using \"dot\" notation.\n     *\n     * @param  \\ArrayAccess|array  $array\n     * @param  string|int|null  $key\n     * @param  mixed  $values\n     * @return array\n     */\n    public static function push(ArrayAccess|array &$array, string|int|null $key, mixed ...$values): array\n    {\n        $target = static::array($array, $key, []);\n\n        array_push($target, ...$values);\n\n        return static::set($array, $key, $target);\n    }\n\n    /**\n     * Shuffle the given array and return the result.\n     *\n     * @param  array  $array\n     * @return array\n     */\n    public static function shuffle($array)\n    {\n        return (new Randomizer)->shuffleArray($array);\n    }\n\n    /**\n     * Get the first item in the array, but only if exactly one item exists. Otherwise, throw an exception.\n     *\n     * @param  array  $array\n     * @param  (callable(mixed, array-key): array)|null  $callback\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     * @throws \\Illuminate\\Support\\MultipleItemsFoundException\n     */\n    public static function sole($array, ?callable $callback = null)\n    {\n        if ($callback) {\n            $array = static::where($array, $callback);\n        }\n\n        $count = count($array);\n\n        if ($count === 0) {\n            throw new ItemNotFoundException;\n        }\n\n        if ($count > 1) {\n            throw new MultipleItemsFoundException($count);\n        }\n\n        return static::first($array);\n    }\n\n    /**\n     * Sort the array using the given callback or \"dot\" notation.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  iterable<TKey, TValue>  $array\n     * @param  callable|string|null|array<int, (callable(TValue, TValue): -1|0|1)|array{string, 'asc'|'desc'}>  $callback\n     * @return array<TKey, TValue>\n     */\n    public static function sort($array, $callback = null)\n    {\n        return (new Collection($array))->sortBy($callback)->all();\n    }\n\n    /**\n     * Sort the array in descending order using the given callback or \"dot\" notation.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  iterable<TKey, TValue>  $array\n     * @param  callable|string|null|array<int, (callable(TValue, TValue): -1|0|1)|array{string, 'asc'|'desc'}>  $callback\n     * @return array<TKey, TValue>\n     */\n    public static function sortDesc($array, $callback = null)\n    {\n        return (new Collection($array))->sortByDesc($callback)->all();\n    }\n\n    /**\n     * Recursively sort an array by keys and values.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @param  int-mask-of<SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_LOCALE_STRING|SORT_NATURAL|SORT_FLAG_CASE>  $options\n     * @param  bool  $descending\n     * @return array<TKey, TValue>\n     */\n    public static function sortRecursive($array, $options = SORT_REGULAR, $descending = false)\n    {\n        foreach ($array as &$value) {\n            if (is_array($value)) {\n                $value = static::sortRecursive($value, $options, $descending);\n            }\n        }\n\n        if (! array_is_list($array)) {\n            $descending\n                ? krsort($array, $options)\n                : ksort($array, $options);\n        } else {\n            $descending\n                ? rsort($array, $options)\n                : sort($array, $options);\n        }\n\n        return $array;\n    }\n\n    /**\n     * Recursively sort an array by keys and values in descending order.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @param  int-mask-of<SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_LOCALE_STRING|SORT_NATURAL|SORT_FLAG_CASE>  $options\n     * @return array<TKey, TValue>\n     */\n    public static function sortRecursiveDesc($array, $options = SORT_REGULAR)\n    {\n        return static::sortRecursive($array, $options, true);\n    }\n\n    /**\n     * Get a string item from an array using \"dot\" notation.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function string(ArrayAccess|array $array, string|int|null $key, ?string $default = null): string\n    {\n        $value = Arr::get($array, $key, $default);\n\n        if (! is_string($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Array value for key [%s] must be a string, %s found.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Conditionally compile classes from an array into a CSS class list.\n     *\n     * @param  array<string, bool>|array<int, string|int>|string  $array\n     * @return ($array is array<string, false> ? '' : ($array is '' ? '' : ($array is array{} ? '' : non-empty-string)))\n     */\n    public static function toCssClasses($array)\n    {\n        $classList = static::wrap($array);\n\n        $classes = [];\n\n        foreach ($classList as $class => $constraint) {\n            if (is_numeric($class)) {\n                $classes[] = $constraint;\n            } elseif ($constraint) {\n                $classes[] = $class;\n            }\n        }\n\n        return implode(' ', $classes);\n    }\n\n    /**\n     * Conditionally compile styles from an array into a style list.\n     *\n     * @param  array<string, bool>|array<int, string|int>|string  $array\n     * @return ($array is array<string, false> ? '' : ($array is '' ? '' : ($array is array{} ? '' : non-empty-string)))\n     */\n    public static function toCssStyles($array)\n    {\n        $styleList = static::wrap($array);\n\n        $styles = [];\n\n        foreach ($styleList as $class => $constraint) {\n            if (is_numeric($class)) {\n                $styles[] = Str::finish($constraint, ';');\n            } elseif ($constraint) {\n                $styles[] = Str::finish($class, ';');\n            }\n        }\n\n        return implode(' ', $styles);\n    }\n\n    /**\n     * Filter the array using the given callback.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @param  callable(TValue, TKey): bool  $callback\n     * @return array<TKey, TValue>\n     */\n    public static function where($array, callable $callback)\n    {\n        return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);\n    }\n\n    /**\n     * Filter the array using the negation of the given callback.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>  $array\n     * @param  callable(TValue, TKey): bool  $callback\n     * @return array<TKey, TValue>\n     */\n    public static function reject($array, callable $callback)\n    {\n        return static::where($array, fn ($value, $key) => ! $callback($value, $key));\n    }\n\n    /**\n     * Partition the array into two arrays using the given callback.\n     *\n     * @template TKey of array-key\n     * @template TValue of mixed\n     *\n     * @param  iterable<TKey, TValue>  $array\n     * @param  callable(TValue, TKey): bool  $callback\n     * @return array<int<0, 1>, array<TKey, TValue>>\n     */\n    public static function partition($array, callable $callback)\n    {\n        $passed = [];\n        $failed = [];\n\n        foreach ($array as $key => $item) {\n            if ($callback($item, $key)) {\n                $passed[$key] = $item;\n            } else {\n                $failed[$key] = $item;\n            }\n        }\n\n        return [$passed, $failed];\n    }\n\n    /**\n     * Filter items where the value is not null.\n     *\n     * @param  array  $array\n     * @return array\n     */\n    public static function whereNotNull($array)\n    {\n        return static::where($array, fn ($value) => ! is_null($value));\n    }\n\n    /**\n     * If the given value is not an array and not null, wrap it in one.\n     *\n     * @template TKey of array-key = array-key\n     * @template TValue\n     *\n     * @param  array<TKey, TValue>|TValue|null  $value\n     * @return ($value is null ? array{} : ($value is array ? array<TKey, TValue> : array{TValue}))\n     */\n    public static function wrap($value)\n    {\n        if (is_null($value)) {\n            return [];\n        }\n\n        return is_array($value) ? $value : [$value];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/Collection.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString;\nuse Illuminate\\Support\\Traits\\EnumeratesValues;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\TransformsToResourceCollection;\nuse InvalidArgumentException;\nuse stdClass;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @implements \\ArrayAccess<TKey, TValue>\n * @implements \\Illuminate\\Support\\Enumerable<TKey, TValue>\n */\nclass Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable\n{\n    /**\n     * @use \\Illuminate\\Support\\Traits\\EnumeratesValues<TKey, TValue>\n     */\n    use EnumeratesValues, Macroable, TransformsToResourceCollection;\n\n    /**\n     * The items contained in the collection.\n     *\n     * @var array<TKey, TValue>\n     */\n    protected $items = [];\n\n    /**\n     * Create a new collection.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items\n     */\n    public function __construct($items = [])\n    {\n        $this->items = $this->getArrayableItems($items);\n    }\n\n    /**\n     * Create a collection with the given range.\n     *\n     * @param  int  $from\n     * @param  int  $to\n     * @param  int  $step\n     * @return static<int, int>\n     */\n    public static function range($from, $to, $step = 1)\n    {\n        return new static(range($from, $to, $step));\n    }\n\n    /**\n     * Get all of the items in the collection.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function all()\n    {\n        return $this->items;\n    }\n\n    /**\n     * Get a lazy collection for the items in this collection.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection<TKey, TValue>\n     */\n    public function lazy()\n    {\n        return new LazyCollection($this->items);\n    }\n\n    /**\n     * Get the median of a given key.\n     *\n     * @param  string|array<array-key, string>|null  $key\n     * @return float|int|null\n     */\n    public function median($key = null)\n    {\n        $values = (isset($key) ? $this->pluck($key) : $this)\n            ->reject(fn ($item) => is_null($item))\n            ->sort()->values();\n\n        $count = $values->count();\n\n        if ($count === 0) {\n            return;\n        }\n\n        $middle = intdiv($count, 2);\n\n        if ($count % 2) {\n            return $values->get($middle);\n        }\n\n        return (new static([\n            $values->get($middle - 1), $values->get($middle),\n        ]))->average();\n    }\n\n    /**\n     * Get the mode of a given key.\n     *\n     * @param  string|array<array-key, string>|null  $key\n     * @return array<int, float|int>|null\n     */\n    public function mode($key = null)\n    {\n        if ($this->count() === 0) {\n            return;\n        }\n\n        $collection = isset($key) ? $this->pluck($key) : $this;\n\n        $counts = new static;\n\n        $collection->each(fn ($value) => $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1);\n\n        $sorted = $counts->sort();\n\n        $highestValue = $sorted->last();\n\n        return $sorted->filter(fn ($value) => $value == $highestValue)\n            ->sort()->keys()->all();\n    }\n\n    /**\n     * Collapse the collection of items into a single array.\n     *\n     * @return static<int, mixed>\n     */\n    public function collapse()\n    {\n        return new static(Arr::collapse($this->items));\n    }\n\n    /**\n     * Collapse the collection of items into a single array while preserving its keys.\n     *\n     * @return static<mixed, mixed>\n     */\n    public function collapseWithKeys()\n    {\n        if (! $this->items) {\n            return new static;\n        }\n\n        $results = [];\n\n        foreach ($this->items as $key => $values) {\n            if ($values instanceof Collection) {\n                $values = $values->all();\n            } elseif (! is_array($values)) {\n                continue;\n            }\n\n            $results[$key] = $values;\n        }\n\n        if (! $results) {\n            return new static;\n        }\n\n        return new static(array_replace(...$results));\n    }\n\n    /**\n     * Determine if an item exists in the collection.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function contains($key, $operator = null, $value = null)\n    {\n        if (func_num_args() === 1) {\n            if ($this->useAsCallable($key)) {\n                return array_any($this->items, $key);\n            }\n\n            return in_array($key, $this->items);\n        }\n\n        return $this->contains($this->operatorForWhere(...func_get_args()));\n    }\n\n    /**\n     * Determine if an item exists, using strict comparison.\n     *\n     * @param  (callable(TValue): bool)|TValue|array-key  $key\n     * @param  TValue|null  $value\n     * @return bool\n     */\n    public function containsStrict($key, $value = null)\n    {\n        if (func_num_args() === 2) {\n            return $this->contains(fn ($item) => data_get($item, $key) === $value);\n        }\n\n        if ($this->useAsCallable($key)) {\n            return ! is_null($this->first($key));\n        }\n\n        return in_array($key, $this->items, true);\n    }\n\n    /**\n     * Determine if an item is not contained in the collection.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContain($key, $operator = null, $value = null)\n    {\n        return ! $this->contains(...func_get_args());\n    }\n\n    /**\n     * Determine if an item is not contained in the enumerable, using strict comparison.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContainStrict($key, $operator = null, $value = null)\n    {\n        return ! $this->containsStrict(...func_get_args());\n    }\n\n    /**\n     * Cross join with the given lists, returning all possible permutations.\n     *\n     * @template TCrossJoinKey\n     * @template TCrossJoinValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue>  ...$lists\n     * @return static<int, array<int, TValue|TCrossJoinValue>>\n     */\n    public function crossJoin(...$lists)\n    {\n        return new static(Arr::crossJoin(\n            $this->items, ...array_map($this->getArrayableItems(...), $lists)\n        ));\n    }\n\n    /**\n     * Get the items in the collection that are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @return static\n     */\n    public function diff($items)\n    {\n        return new static(array_diff($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Get the items in the collection that are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function diffUsing($items, callable $callback)\n    {\n        return new static(array_udiff($this->items, $this->getArrayableItems($items), $callback));\n    }\n\n    /**\n     * Get the items in the collection whose keys and values are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function diffAssoc($items)\n    {\n        return new static(array_diff_assoc($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Get the items in the collection whose keys and values are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function diffAssocUsing($items, callable $callback)\n    {\n        return new static(array_diff_uassoc($this->items, $this->getArrayableItems($items), $callback));\n    }\n\n    /**\n     * Get the items in the collection whose keys are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @return static\n     */\n    public function diffKeys($items)\n    {\n        return new static(array_diff_key($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Get the items in the collection whose keys are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function diffKeysUsing($items, callable $callback)\n    {\n        return new static(array_diff_ukey($this->items, $this->getArrayableItems($items), $callback));\n    }\n\n    /**\n     * Retrieve duplicate items from the collection.\n     *\n     * @template TMapValue\n     *\n     * @param  (callable(TValue): TMapValue)|string|null  $callback\n     * @param  bool  $strict\n     * @return static\n     */\n    public function duplicates($callback = null, $strict = false)\n    {\n        $items = $this->map($this->valueRetriever($callback));\n\n        $uniqueItems = $items->unique(null, $strict);\n\n        $compare = $this->duplicateComparator($strict);\n\n        $duplicates = new static;\n\n        foreach ($items as $key => $value) {\n            if ($uniqueItems->isNotEmpty() && $compare($value, $uniqueItems->first())) {\n                $uniqueItems->shift();\n            } else {\n                $duplicates[$key] = $value;\n            }\n        }\n\n        return $duplicates;\n    }\n\n    /**\n     * Retrieve duplicate items from the collection using strict comparison.\n     *\n     * @template TMapValue\n     *\n     * @param  (callable(TValue): TMapValue)|string|null  $callback\n     * @return static\n     */\n    public function duplicatesStrict($callback = null)\n    {\n        return $this->duplicates($callback, true);\n    }\n\n    /**\n     * Get the comparison function to detect duplicates.\n     *\n     * @param  bool  $strict\n     * @return callable(TValue, TValue): bool\n     */\n    protected function duplicateComparator($strict)\n    {\n        if ($strict) {\n            return fn ($a, $b) => $a === $b;\n        }\n\n        return fn ($a, $b) => $a == $b;\n    }\n\n    /**\n     * Get all items except for those with the specified keys.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys\n     * @return static\n     */\n    public function except($keys)\n    {\n        if (is_null($keys)) {\n            return new static($this->items);\n        }\n\n        if ($keys instanceof Enumerable) {\n            $keys = $keys->all();\n        } elseif (! is_array($keys)) {\n            $keys = func_get_args();\n        }\n\n        return new static(Arr::except($this->items, $keys));\n    }\n\n    /**\n     * Run a filter over each of the items.\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @return static\n     */\n    public function filter(?callable $callback = null)\n    {\n        if ($callback) {\n            return new static(Arr::where($this->items, $callback));\n        }\n\n        return new static(array_filter($this->items));\n    }\n\n    /**\n     * Get the first item from the collection passing the given truth test.\n     *\n     * @template TFirstDefault\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TFirstDefault|(\\Closure(): TFirstDefault)  $default\n     * @return TValue|TFirstDefault\n     */\n    public function first(?callable $callback = null, $default = null)\n    {\n        return Arr::first($this->items, $callback, $default);\n    }\n\n    /**\n     * Get a flattened array of the items in the collection.\n     *\n     * @param  int  $depth\n     * @return static<int, mixed>\n     */\n    public function flatten($depth = INF)\n    {\n        return new static(Arr::flatten($this->items, $depth));\n    }\n\n    /**\n     * Flip the items in the collection.\n     *\n     * @return static<TValue, TKey>\n     */\n    public function flip()\n    {\n        return new static(array_flip($this->items));\n    }\n\n    /**\n     * Remove an item from the collection by key.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TKey>|TKey  $keys\n     * @return $this\n     */\n    public function forget($keys)\n    {\n        foreach ($this->getArrayableItems($keys) as $key) {\n            $this->offsetUnset($key);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get an item from the collection by key.\n     *\n     * @template TGetDefault\n     *\n     * @param  TKey|null  $key\n     * @param  TGetDefault|(\\Closure(): TGetDefault)  $default\n     * @return TValue|TGetDefault\n     */\n    public function get($key, $default = null)\n    {\n        $key ??= '';\n\n        if (array_key_exists($key, $this->items)) {\n            return $this->items[$key];\n        }\n\n        return value($default);\n    }\n\n    /**\n     * Get an item from the collection by key or add it to collection if it does not exist.\n     *\n     * @template TGetOrPutValue\n     *\n     * @param  mixed  $key\n     * @param  TGetOrPutValue|(\\Closure(): TGetOrPutValue)  $value\n     * @return TValue|TGetOrPutValue\n     */\n    public function getOrPut($key, $value)\n    {\n        if (array_key_exists($key ?? '', $this->items)) {\n            return $this->items[$key ?? ''];\n        }\n\n        $this->offsetSet($key, $value = value($value));\n\n        return $value;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function groupBy($groupBy, $preserveKeys = false)\n    {\n        if (! $this->useAsCallable($groupBy) && is_array($groupBy)) {\n            $nextGroups = $groupBy;\n\n            $groupBy = array_shift($nextGroups);\n        }\n\n        $groupBy = $this->valueRetriever($groupBy);\n\n        $results = [];\n\n        foreach ($this->items as $key => $value) {\n            $groupKeys = $groupBy($value, $key);\n\n            if (! is_array($groupKeys)) {\n                $groupKeys = [$groupKeys];\n            }\n\n            foreach ($groupKeys as $groupKey) {\n                $groupKey = match (true) {\n                    is_bool($groupKey) => (int) $groupKey,\n                    $groupKey instanceof \\UnitEnum => enum_value($groupKey),\n                    $groupKey instanceof \\Stringable, is_null($groupKey) => (string) $groupKey,\n                    default => $groupKey,\n                };\n\n                if (! array_key_exists($groupKey, $results)) {\n                    $results[$groupKey] = new static;\n                }\n\n                $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value);\n            }\n        }\n\n        $result = new static($results);\n\n        if (! empty($nextGroups)) {\n            return $result->map->groupBy($nextGroups, $preserveKeys);\n        }\n\n        return $result;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function keyBy($keyBy)\n    {\n        $keyBy = $this->valueRetriever($keyBy);\n\n        $results = [];\n\n        foreach ($this->items as $key => $item) {\n            $resolvedKey = $keyBy($item, $key);\n\n            if ($resolvedKey instanceof \\UnitEnum) {\n                $resolvedKey = enum_value($resolvedKey);\n            }\n\n            if (is_object($resolvedKey)) {\n                $resolvedKey = (string) $resolvedKey;\n            }\n\n            $results[$resolvedKey] = $item;\n        }\n\n        return new static($results);\n    }\n\n    /**\n     * Determine if an item exists in the collection by key.\n     *\n     * @param  TKey|array<array-key, TKey>  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        return array_all($keys, fn ($key) => array_key_exists($key ?? '', $this->items));\n    }\n\n    /**\n     * Determine if any of the keys exist in the collection.\n     *\n     * @param  TKey|array<array-key, TKey>  $key\n     * @return bool\n     */\n    public function hasAny($key)\n    {\n        if ($this->isEmpty()) {\n            return false;\n        }\n\n        $keys = is_array($key) ? $key : func_get_args();\n\n        return array_any($keys, fn ($key) => array_key_exists($key ?? '', $this->items));\n    }\n\n    /**\n     * Concatenate values of a given key as a string.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $value\n     * @param  string|null  $glue\n     * @return string\n     */\n    public function implode($value, $glue = null)\n    {\n        if ($this->useAsCallable($value)) {\n            return implode($glue ?? '', $this->map($value)->all());\n        }\n\n        $first = $this->first();\n\n        if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) {\n            return implode($glue ?? '', $this->pluck($value)->all());\n        }\n\n        return implode($value ?? '', $this->items);\n    }\n\n    /**\n     * Intersect the collection with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function intersect($items)\n    {\n        return new static(array_intersect($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Intersect the collection with the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function intersectUsing($items, callable $callback)\n    {\n        return new static(array_uintersect($this->items, $this->getArrayableItems($items), $callback));\n    }\n\n    /**\n     * Intersect the collection with the given items with additional index check.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function intersectAssoc($items)\n    {\n        return new static(array_intersect_assoc($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Intersect the collection with the given items with additional index check, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function intersectAssocUsing($items, callable $callback)\n    {\n        return new static(array_intersect_uassoc($this->items, $this->getArrayableItems($items), $callback));\n    }\n\n    /**\n     * Intersect the collection with the given items by key.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @return static\n     */\n    public function intersectByKeys($items)\n    {\n        return new static(array_intersect_key(\n            $this->items, $this->getArrayableItems($items)\n        ));\n    }\n\n    /**\n     * Determine if the collection is empty or not.\n     *\n     * @phpstan-assert-if-true null $this->first()\n     * @phpstan-assert-if-true null $this->last()\n     *\n     * @phpstan-assert-if-false TValue $this->first()\n     * @phpstan-assert-if-false TValue $this->last()\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return empty($this->items);\n    }\n\n    /**\n     * Determine if the collection contains exactly one item. If a callback is provided, determine if exactly one item matches the condition.\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @return bool\n     *\n     * @deprecated 12.49.0 Use the `hasSole()` method instead.\n     */\n    public function containsOneItem(?callable $callback = null): bool\n    {\n        return $this->hasSole($callback);\n    }\n\n    /**\n     * Determine if the collection contains multiple items.\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @return bool\n     *\n     * @deprecated 12.50.0 Use the `hasMany()` method instead.\n     */\n    public function containsManyItems(?callable $callback = null): bool\n    {\n        return $this->hasMany($callback);\n    }\n\n    /**\n     * Join all items from the collection using a string. The final items can use a separate glue string.\n     *\n     * @param  string  $glue\n     * @param  string  $finalGlue\n     * @return TValue|string\n     */\n    public function join($glue, $finalGlue = '')\n    {\n        if ($finalGlue === '') {\n            return $this->implode($glue);\n        }\n\n        $count = $this->count();\n\n        if ($count === 0) {\n            return '';\n        }\n\n        if ($count === 1) {\n            return $this->last();\n        }\n\n        $collection = new static($this->items);\n\n        $finalItem = $collection->pop();\n\n        return $collection->implode($glue).$finalGlue.$finalItem;\n    }\n\n    /**\n     * Get the keys of the collection items.\n     *\n     * @return static<int, TKey>\n     */\n    public function keys()\n    {\n        return new static(array_keys($this->items));\n    }\n\n    /**\n     * Get the last item from the collection.\n     *\n     * @template TLastDefault\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TLastDefault|(\\Closure(): TLastDefault)  $default\n     * @return TValue|TLastDefault\n     */\n    public function last(?callable $callback = null, $default = null)\n    {\n        return Arr::last($this->items, $callback, $default);\n    }\n\n    /**\n     * Get the values of a given key.\n     *\n     * @param  \\Closure|string|int|array<array-key, string>|null  $value\n     * @param  \\Closure|string|null  $key\n     * @return static<array-key, mixed>\n     */\n    public function pluck($value, $key = null)\n    {\n        return new static(Arr::pluck($this->items, $value, $key));\n    }\n\n    /**\n     * Run a map over each of the items.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TValue, TKey): TMapValue  $callback\n     * @return static<TKey, TMapValue>\n     */\n    public function map(callable $callback)\n    {\n        return new static(Arr::map($this->items, $callback));\n    }\n\n    /**\n     * Run a dictionary map over the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapToDictionaryKey of array-key\n     * @template TMapToDictionaryValue\n     *\n     * @param  callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue>  $callback\n     * @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>\n     */\n    public function mapToDictionary(callable $callback)\n    {\n        $dictionary = [];\n\n        foreach ($this->items as $key => $item) {\n            $pair = $callback($item, $key);\n\n            $key = key($pair);\n\n            $value = reset($pair);\n\n            if (! isset($dictionary[$key])) {\n                $dictionary[$key] = [];\n            }\n\n            $dictionary[$key][] = $value;\n        }\n\n        return new static($dictionary);\n    }\n\n    /**\n     * Run an associative map over each of the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapWithKeysKey of array-key\n     * @template TMapWithKeysValue\n     *\n     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback\n     * @return static<TMapWithKeysKey, TMapWithKeysValue>\n     */\n    public function mapWithKeys(callable $callback)\n    {\n        return new static(Arr::mapWithKeys($this->items, $callback));\n    }\n\n    /**\n     * Merge the collection with the given items.\n     *\n     * @template TMergeValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TMergeValue>|iterable<TKey, TMergeValue>  $items\n     * @return static<TKey, TValue|TMergeValue>\n     */\n    public function merge($items)\n    {\n        return new static(array_merge($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Recursively merge the collection with the given items.\n     *\n     * @template TMergeRecursiveValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue>  $items\n     * @return static<TKey, TValue|TMergeRecursiveValue>\n     */\n    public function mergeRecursive($items)\n    {\n        return new static(array_merge_recursive($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Multiply the items in the collection by the multiplier.\n     *\n     * @param  int  $multiplier\n     * @return static\n     */\n    public function multiply(int $multiplier)\n    {\n        $new = new static;\n\n        for ($i = 0; $i < $multiplier; $i++) {\n            $new->push(...$this->items);\n        }\n\n        return $new;\n    }\n\n    /**\n     * Create a collection by using this collection for keys and another for its values.\n     *\n     * @template TCombineValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue>  $values\n     * @return static<TValue, TCombineValue>\n     */\n    public function combine($values)\n    {\n        return new static(array_combine($this->all(), $this->getArrayableItems($values)));\n    }\n\n    /**\n     * Union the collection with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function union($items)\n    {\n        return new static($this->items + $this->getArrayableItems($items));\n    }\n\n    /**\n     * Create a new collection consisting of every n-th element.\n     *\n     * @param  int  $step\n     * @param  int  $offset\n     * @return ($step is positive-int ? static : never)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function nth($step, $offset = 0)\n    {\n        if ($step < 1) {\n            throw new InvalidArgumentException('Step value must be at least 1.');\n        }\n\n        $new = [];\n\n        $position = 0;\n\n        foreach ($this->slice($offset)->items as $item) {\n            if ($position % $step === 0) {\n                $new[] = $item;\n            }\n\n            $position++;\n        }\n\n        return new static($new);\n    }\n\n    /**\n     * Get the items with the specified keys.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string|null  $keys\n     * @return static\n     */\n    public function only($keys)\n    {\n        if (is_null($keys)) {\n            return new static($this->items);\n        }\n\n        if ($keys instanceof Enumerable) {\n            $keys = $keys->all();\n        }\n\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        return new static(Arr::only($this->items, $keys));\n    }\n\n    /**\n     * Select specific values from the items within the collection.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string|null  $keys\n     * @return static\n     */\n    public function select($keys)\n    {\n        if (is_null($keys)) {\n            return new static($this->items);\n        }\n\n        if ($keys instanceof Enumerable) {\n            $keys = $keys->all();\n        }\n\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        return new static(Arr::select($this->items, $keys));\n    }\n\n    /**\n     * Get and remove the last N items from the collection.\n     *\n     * @param  int  $count\n     * @return ($count is 1 ? TValue|null : static<int, TValue>)\n     */\n    public function pop($count = 1)\n    {\n        if ($count < 1) {\n            return new static;\n        }\n\n        if ($count === 1) {\n            return array_pop($this->items);\n        }\n\n        if ($this->isEmpty()) {\n            return new static;\n        }\n\n        $results = [];\n\n        $collectionCount = $this->count();\n\n        foreach (range(1, min($count, $collectionCount)) as $item) {\n            $results[] = array_pop($this->items);\n        }\n\n        return new static($results);\n    }\n\n    /**\n     * Push an item onto the beginning of the collection.\n     *\n     * @param  TValue  $value\n     * @param  TKey  $key\n     * @return $this\n     */\n    public function prepend($value, $key = null)\n    {\n        $this->items = Arr::prepend($this->items, ...(func_num_args() > 1 ? func_get_args() : [$value]));\n\n        return $this;\n    }\n\n    /**\n     * Push one or more items onto the end of the collection.\n     *\n     * @param  TValue  ...$values\n     * @return $this\n     */\n    public function push(...$values)\n    {\n        foreach ($values as $value) {\n            $this->items[] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Prepend one or more items to the beginning of the collection.\n     *\n     * @param  TValue  ...$values\n     * @return $this\n     */\n    public function unshift(...$values)\n    {\n        array_unshift($this->items, ...$values);\n\n        return $this;\n    }\n\n    /**\n     * Push all of the given items onto the collection.\n     *\n     * @template TConcatKey of array-key\n     * @template TConcatValue\n     *\n     * @param  iterable<TConcatKey, TConcatValue>  $source\n     * @return static<TKey|TConcatKey, TValue|TConcatValue>\n     */\n    public function concat($source)\n    {\n        $result = new static($this);\n\n        foreach ($source as $item) {\n            $result->push($item);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get and remove an item from the collection.\n     *\n     * @template TPullDefault\n     *\n     * @param  TKey  $key\n     * @param  TPullDefault|(\\Closure(): TPullDefault)  $default\n     * @return TValue|TPullDefault\n     */\n    public function pull($key, $default = null)\n    {\n        return Arr::pull($this->items, $key, $default);\n    }\n\n    /**\n     * Put an item in the collection by key.\n     *\n     * @param  TKey  $key\n     * @param  TValue  $value\n     * @return $this\n     */\n    public function put($key, $value)\n    {\n        $this->offsetSet($key, $value);\n\n        return $this;\n    }\n\n    /**\n     * Get one or a specified number of items randomly from the collection.\n     *\n     * @param  (callable(self<TKey, TValue>): int)|int|null  $number\n     * @param  bool  $preserveKeys\n     * @return ($number is null ? TValue : static<int, TValue>)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function random($number = null, $preserveKeys = false)\n    {\n        if (is_null($number)) {\n            return Arr::random($this->items);\n        }\n\n        if (is_callable($number)) {\n            return new static(Arr::random($this->items, $number($this), $preserveKeys));\n        }\n\n        return new static(Arr::random($this->items, $number, $preserveKeys));\n    }\n\n    /**\n     * Replace the collection items with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function replace($items)\n    {\n        return new static(array_replace($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Recursively replace the collection items with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function replaceRecursive($items)\n    {\n        return new static(array_replace_recursive($this->items, $this->getArrayableItems($items)));\n    }\n\n    /**\n     * Reverse items order.\n     *\n     * @return static\n     */\n    public function reverse()\n    {\n        return new static(array_reverse($this->items, true));\n    }\n\n    /**\n     * Search the collection for a given value and return the corresponding key if successful.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TKey|false\n     */\n    public function search($value, $strict = false)\n    {\n        if (! $this->useAsCallable($value)) {\n            return array_search($value, $this->items, $strict);\n        }\n\n        return array_find_key($this->items, $value) ?? false;\n    }\n\n    /**\n     * Get the item before the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function before($value, $strict = false)\n    {\n        $key = $this->search($value, $strict);\n\n        if ($key === false) {\n            return null;\n        }\n\n        $position = ($keys = $this->keys())->search($key);\n\n        if ($position === 0) {\n            return null;\n        }\n\n        return $this->get($keys->get($position - 1));\n    }\n\n    /**\n     * Get the item after the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function after($value, $strict = false)\n    {\n        $key = $this->search($value, $strict);\n\n        if ($key === false) {\n            return null;\n        }\n\n        $position = ($keys = $this->keys())->search($key);\n\n        if ($position === $keys->count() - 1) {\n            return null;\n        }\n\n        return $this->get($keys->get($position + 1));\n    }\n\n    /**\n     * Get and remove the first N items from the collection.\n     *\n     * @param  int<0, max>  $count\n     * @return ($count is 1 ? TValue|null : static<int, TValue>)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function shift($count = 1)\n    {\n        if ($count < 0) {\n            throw new InvalidArgumentException('Number of shifted items may not be less than zero.');\n        }\n\n        if ($this->isEmpty()) {\n            return null;\n        }\n\n        if ($count === 0) {\n            return new static;\n        }\n\n        if ($count === 1) {\n            return array_shift($this->items);\n        }\n\n        $results = [];\n\n        $collectionCount = $this->count();\n\n        foreach (range(1, min($count, $collectionCount)) as $item) {\n            $results[] = array_shift($this->items);\n        }\n\n        return new static($results);\n    }\n\n    /**\n     * Shuffle the items in the collection.\n     *\n     * @return static\n     */\n    public function shuffle()\n    {\n        return new static(Arr::shuffle($this->items));\n    }\n\n    /**\n     * Create chunks representing a \"sliding window\" view of the items in the collection.\n     *\n     * @param  positive-int  $size\n     * @param  positive-int  $step\n     * @return static<int, static>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function sliding($size = 2, $step = 1)\n    {\n        if ($size < 1) {\n            throw new InvalidArgumentException('Size value must be at least 1.');\n        } elseif ($step < 1) {\n            throw new InvalidArgumentException('Step value must be at least 1.');\n        }\n\n        $chunks = floor(($this->count() - $size) / $step) + 1;\n\n        return static::times($chunks, fn ($number) => $this->slice(($number - 1) * $step, $size));\n    }\n\n    /**\n     * Skip the first {$count} items.\n     *\n     * @param  int  $count\n     * @return static\n     */\n    public function skip($count)\n    {\n        return $this->slice($count);\n    }\n\n    /**\n     * Skip items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipUntil($value)\n    {\n        return new static($this->lazy()->skipUntil($value)->all());\n    }\n\n    /**\n     * Skip items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipWhile($value)\n    {\n        return new static($this->lazy()->skipWhile($value)->all());\n    }\n\n    /**\n     * Slice the underlying collection array.\n     *\n     * @param  int  $offset\n     * @param  int|null  $length\n     * @return static\n     */\n    public function slice($offset, $length = null)\n    {\n        return new static(array_slice($this->items, $offset, $length, true));\n    }\n\n    /**\n     * Split a collection into a certain number of groups.\n     *\n     * @param  int  $numberOfGroups\n     * @return ($numberOfGroups is positive-int ? static<int, static> : never)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function split($numberOfGroups)\n    {\n        if ($numberOfGroups < 1) {\n            throw new InvalidArgumentException('Number of groups must be at least 1.');\n        }\n\n        if ($this->isEmpty()) {\n            return new static;\n        }\n\n        $groups = new static;\n\n        $groupSize = floor($this->count() / $numberOfGroups);\n\n        $remain = $this->count() % $numberOfGroups;\n\n        $start = 0;\n\n        for ($i = 0; $i < $numberOfGroups; $i++) {\n            $size = $groupSize;\n\n            if ($i < $remain) {\n                $size++;\n            }\n\n            if ($size) {\n                $groups->push(new static(array_slice($this->items, $start, $size)));\n\n                $start += $size;\n            }\n        }\n\n        return $groups;\n    }\n\n    /**\n     * Split a collection into a certain number of groups, and fill the first groups completely.\n     *\n     * @param  int  $numberOfGroups\n     * @return ($numberOfGroups is positive-int ? static<int, static> : never)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function splitIn($numberOfGroups)\n    {\n        if ($numberOfGroups < 1) {\n            throw new InvalidArgumentException('Number of groups must be at least 1.');\n        }\n\n        return $this->chunk((int) ceil($this->count() / $numberOfGroups));\n    }\n\n    /**\n     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     * @throws \\Illuminate\\Support\\MultipleItemsFoundException\n     */\n    public function sole($key = null, $operator = null, $value = null)\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        $items = $this->unless($filter == null)->filter($filter);\n\n        $count = $items->count();\n\n        if ($count === 0) {\n            throw new ItemNotFoundException;\n        }\n\n        if ($count > 1) {\n            throw new MultipleItemsFoundException($count);\n        }\n\n        return $items->first();\n    }\n\n    /**\n     * Determine if the collection contains a single item, optionally matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasSole($key = null, $operator = null, $value = null): bool\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        return $this\n            ->unless($filter == null)\n            ->filter($filter)\n            ->count() === 1;\n    }\n\n    /**\n     * Get the first item in the collection but throw an exception if no matching items exist.\n     *\n     * @param  (callable(TValue, TKey): bool)|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     */\n    public function firstOrFail($key = null, $operator = null, $value = null)\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        $placeholder = new stdClass();\n\n        $item = $this->first($filter, $placeholder);\n\n        if ($item === $placeholder) {\n            throw new ItemNotFoundException;\n        }\n\n        return $item;\n    }\n\n    /**\n     * Chunk the collection into chunks of the given size.\n     *\n     * @param  int  $size\n     * @param  bool  $preserveKeys\n     * @return ($preserveKeys is true ? static<int, static> : static<int, static<int, TValue>>)\n     */\n    public function chunk($size, $preserveKeys = true)\n    {\n        if ($size <= 0) {\n            return new static;\n        }\n\n        $chunks = [];\n\n        foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {\n            $chunks[] = new static($chunk);\n        }\n\n        return new static($chunks);\n    }\n\n    /**\n     * Chunk the collection into chunks with a callback.\n     *\n     * @param  callable(TValue, TKey, static<TKey, TValue>): bool  $callback\n     * @return static<int, static<TKey, TValue>>\n     */\n    public function chunkWhile(callable $callback)\n    {\n        return new static(\n            $this->lazy()->chunkWhile($callback)->mapInto(static::class)\n        );\n    }\n\n    /**\n     * Sort through each item with a callback.\n     *\n     * @param  (callable(TValue, TValue): int)|null|int  $callback\n     * @return static\n     */\n    public function sort($callback = null)\n    {\n        $items = $this->items;\n\n        $callback && is_callable($callback)\n            ? uasort($items, $callback)\n            : asort($items, $callback ?? SORT_REGULAR);\n\n        return new static($items);\n    }\n\n    /**\n     * Sort items in descending order.\n     *\n     * @param  int  $options\n     * @return static\n     */\n    public function sortDesc($options = SORT_REGULAR)\n    {\n        $items = $this->items;\n\n        arsort($items, $options);\n\n        return new static($items);\n    }\n\n    /**\n     * Sort the collection using the given callback.\n     *\n     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback\n     * @param  int  $options\n     * @param  bool  $descending\n     * @return static\n     */\n    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)\n    {\n        if (is_array($callback) && ! is_callable($callback)) {\n            return $this->sortByMany($callback, $options);\n        }\n\n        $results = [];\n\n        $callback = $this->valueRetriever($callback);\n\n        // First we will loop through the items and get the comparator from a callback\n        // function which we were given. Then, we will sort the returned values and\n        // grab all the corresponding values for the sorted keys from this array.\n        foreach ($this->items as $key => $value) {\n            $results[$key] = $callback($value, $key);\n        }\n\n        $descending ? arsort($results, $options)\n            : asort($results, $options);\n\n        // Once we have sorted all of the keys in the array, we will loop through them\n        // and grab the corresponding model so we can set the underlying items list\n        // to the sorted version. Then we'll just return the collection instance.\n        foreach (array_keys($results) as $key) {\n            $results[$key] = $this->items[$key];\n        }\n\n        return new static($results);\n    }\n\n    /**\n     * Sort the collection using multiple comparisons.\n     *\n     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>  $comparisons\n     * @param  int  $options\n     * @return static\n     */\n    protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR)\n    {\n        $items = $this->items;\n\n        uasort($items, function ($a, $b) use ($comparisons, $options) {\n            foreach ($comparisons as $comparison) {\n                $comparison = Arr::wrap($comparison);\n\n                $prop = $comparison[0];\n\n                $ascending = Arr::get($comparison, 1, true) === true ||\n                             Arr::get($comparison, 1, true) === 'asc';\n\n                if (! is_string($prop) && is_callable($prop)) {\n                    $result = $prop($a, $b);\n                } else {\n                    $values = [data_get($a, $prop), data_get($b, $prop)];\n\n                    if (! $ascending) {\n                        $values = array_reverse($values);\n                    }\n\n                    if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) {\n                        if (($options & SORT_NATURAL) === SORT_NATURAL) {\n                            $result = strnatcasecmp($values[0], $values[1]);\n                        } else {\n                            $result = strcasecmp($values[0], $values[1]);\n                        }\n                    } else {\n                        $result = match ($options) {\n                            SORT_NUMERIC => (int) $values[0] <=> (int) $values[1],\n                            SORT_STRING => strcmp($values[0], $values[1]),\n                            SORT_NATURAL => strnatcmp((string) $values[0], (string) $values[1]),\n                            SORT_LOCALE_STRING => strcoll($values[0], $values[1]),\n                            default => $values[0] <=> $values[1],\n                        };\n                    }\n                }\n\n                if ($result === 0) {\n                    continue;\n                }\n\n                return $result;\n            }\n        });\n\n        return new static($items);\n    }\n\n    /**\n     * Sort the collection in descending order using the given callback.\n     *\n     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback\n     * @param  int  $options\n     * @return static\n     */\n    public function sortByDesc($callback, $options = SORT_REGULAR)\n    {\n        if (is_array($callback) && ! is_callable($callback)) {\n            foreach ($callback as $index => $key) {\n                $comparison = Arr::wrap($key);\n\n                $comparison[1] = 'desc';\n\n                $callback[$index] = $comparison;\n            }\n        }\n\n        return $this->sortBy($callback, $options, true);\n    }\n\n    /**\n     * Sort the collection keys.\n     *\n     * @param  int  $options\n     * @param  bool  $descending\n     * @return static\n     */\n    public function sortKeys($options = SORT_REGULAR, $descending = false)\n    {\n        $items = $this->items;\n\n        $descending ? krsort($items, $options) : ksort($items, $options);\n\n        return new static($items);\n    }\n\n    /**\n     * Sort the collection keys in descending order.\n     *\n     * @param  int  $options\n     * @return static\n     */\n    public function sortKeysDesc($options = SORT_REGULAR)\n    {\n        return $this->sortKeys($options, true);\n    }\n\n    /**\n     * Sort the collection keys using a callback.\n     *\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function sortKeysUsing(callable $callback)\n    {\n        $items = $this->items;\n\n        uksort($items, $callback);\n\n        return new static($items);\n    }\n\n    /**\n     * Splice a portion of the underlying collection array.\n     *\n     * @param  int  $offset\n     * @param  int|null  $length\n     * @param  array<array-key, TValue>  $replacement\n     * @return static\n     */\n    public function splice($offset, $length = null, $replacement = [])\n    {\n        if (func_num_args() === 1) {\n            return new static(array_splice($this->items, $offset));\n        }\n\n        return new static(array_splice($this->items, $offset, $length, $this->getArrayableItems($replacement)));\n    }\n\n    /**\n     * Take the first or last {$limit} items.\n     *\n     * @param  int  $limit\n     * @return static\n     */\n    public function take($limit)\n    {\n        if ($limit < 0) {\n            return $this->slice($limit, abs($limit));\n        }\n\n        return $this->slice(0, $limit);\n    }\n\n    /**\n     * Take items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function takeUntil($value)\n    {\n        return new static($this->lazy()->takeUntil($value)->all());\n    }\n\n    /**\n     * Take items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function takeWhile($value)\n    {\n        return new static($this->lazy()->takeWhile($value)->all());\n    }\n\n    /**\n     * Transform each item in the collection using a callback.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TValue, TKey): TMapValue  $callback\n     * @return $this\n     *\n     * @phpstan-this-out static<TKey, TMapValue>\n     */\n    public function transform(callable $callback)\n    {\n        $this->items = $this->map($callback)->all();\n\n        return $this;\n    }\n\n    /**\n     * Flatten a multi-dimensional associative array with dots.\n     *\n     * @param  int  $depth\n     * @return static\n     */\n    public function dot($depth = INF)\n    {\n        return new static(Arr::dot($this->all(), '', $depth));\n    }\n\n    /**\n     * Convert a flatten \"dot\" notation array into an expanded array.\n     *\n     * @return static\n     */\n    public function undot()\n    {\n        return new static(Arr::undot($this->all()));\n    }\n\n    /**\n     * Return only unique items from the collection array.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @param  bool  $strict\n     * @return static\n     */\n    public function unique($key = null, $strict = false)\n    {\n        if (is_null($key) && $strict === false) {\n            return new static(array_unique($this->items, SORT_REGULAR));\n        }\n\n        $callback = $this->valueRetriever($key);\n\n        $exists = [];\n\n        return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {\n            if (in_array($id = $callback($item, $key), $exists, $strict)) {\n                return true;\n            }\n\n            $exists[] = $id;\n        });\n    }\n\n    /**\n     * Reset the keys on the underlying array.\n     *\n     * @return static<int, TValue>\n     */\n    public function values()\n    {\n        return new static(array_values($this->items));\n    }\n\n    /**\n     * Zip the collection together with one or more arrays.\n     *\n     * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);\n     *      => [[1, 4], [2, 5], [3, 6]]\n     *\n     * @template TZipValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items\n     * @return static<int, static<int, TValue|TZipValue>>\n     */\n    public function zip($items)\n    {\n        $arrayableItems = array_map(fn ($items) => $this->getArrayableItems($items), func_get_args());\n\n        $params = array_merge([fn () => new static(func_get_args()), $this->items], $arrayableItems);\n\n        return new static(array_map(...$params));\n    }\n\n    /**\n     * Pad collection to the specified length with a value.\n     *\n     * @template TPadValue\n     *\n     * @param  int  $size\n     * @param  TPadValue  $value\n     * @return static<int, TValue|TPadValue>\n     */\n    public function pad($size, $value)\n    {\n        return new static(array_pad($this->items, $size, $value));\n    }\n\n    /**\n     * Get an iterator for the items.\n     *\n     * @return \\ArrayIterator<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->items);\n    }\n\n    /**\n     * Count the number of items in the collection.\n     *\n     * @return int<0, max>\n     */\n    public function count(): int\n    {\n        return count($this->items);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function countBy($countBy = null)\n    {\n        return new static($this->lazy()->countBy($countBy)->all());\n    }\n\n    /**\n     * Add an item to the collection.\n     *\n     * @param  TValue  $item\n     * @return $this\n     */\n    public function add($item)\n    {\n        $this->items[] = $item;\n\n        return $this;\n    }\n\n    /**\n     * Get a base Support collection instance from this collection.\n     *\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    public function toBase()\n    {\n        return new self($this);\n    }\n\n    /**\n     * Determine if an item exists at an offset.\n     *\n     * @param  TKey  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->items[$offset]);\n    }\n\n    /**\n     * Get an item at a given offset.\n     *\n     * @param  TKey  $offset\n     * @return TValue\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->items[$offset];\n    }\n\n    /**\n     * Set the item at a given offset.\n     *\n     * @param  TKey|null  $offset\n     * @param  TValue  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        if (is_null($offset)) {\n            $this->items[] = $value;\n        } else {\n            $this->items[$offset] = $value;\n        }\n    }\n\n    /**\n     * Unset the item at a given offset.\n     *\n     * @param  TKey  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->items[$offset]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/Enumerable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse CachingIterator;\nuse Countable;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse IteratorAggregate;\nuse JsonSerializable;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @extends \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>\n * @extends \\IteratorAggregate<TKey, TValue>\n */\ninterface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable\n{\n    /**\n     * Create a new collection instance if the value isn't one already.\n     *\n     * @template TMakeKey of array-key\n     * @template TMakeValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|null  $items\n     * @return static<TMakeKey, TMakeValue>\n     */\n    public static function make($items = []);\n\n    /**\n     * Create a new instance by invoking the callback a given amount of times.\n     *\n     * @param  int  $number\n     * @param  callable|null  $callback\n     * @return static\n     */\n    public static function times($number, ?callable $callback = null);\n\n    /**\n     * Create a collection with the given range.\n     *\n     * @param  int  $from\n     * @param  int  $to\n     * @param  int  $step\n     * @return static\n     */\n    public static function range($from, $to, $step = 1);\n\n    /**\n     * Wrap the given value in a collection if applicable.\n     *\n     * @template TWrapValue\n     *\n     * @param  iterable<array-key, TWrapValue>|TWrapValue  $value\n     * @return static<array-key, TWrapValue>\n     */\n    public static function wrap($value);\n\n    /**\n     * Get the underlying items from the given collection if applicable.\n     *\n     * @template TUnwrapKey of array-key\n     * @template TUnwrapValue\n     *\n     * @param  array<TUnwrapKey, TUnwrapValue>|static<TUnwrapKey, TUnwrapValue>  $value\n     * @return array<TUnwrapKey, TUnwrapValue>\n     */\n    public static function unwrap($value);\n\n    /**\n     * Create a new instance with no items.\n     *\n     * @return static\n     */\n    public static function empty();\n\n    /**\n     * Get all items in the enumerable.\n     *\n     * @return array\n     */\n    public function all();\n\n    /**\n     * Alias for the \"avg\" method.\n     *\n     * @param  (callable(TValue): float|int)|string|null  $callback\n     * @return float|int|null\n     */\n    public function average($callback = null);\n\n    /**\n     * Get the median of a given key.\n     *\n     * @param  string|array<array-key, string>|null  $key\n     * @return float|int|null\n     */\n    public function median($key = null);\n\n    /**\n     * Get the mode of a given key.\n     *\n     * @param  string|array<array-key, string>|null  $key\n     * @return array<int, float|int>|null\n     */\n    public function mode($key = null);\n\n    /**\n     * Collapse the items into a single enumerable.\n     *\n     * @return static<int, mixed>\n     */\n    public function collapse();\n\n    /**\n     * Alias for the \"contains\" method.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function some($key, $operator = null, $value = null);\n\n    /**\n     * Determine if an item exists, using strict comparison.\n     *\n     * @param  (callable(TValue): bool)|TValue|array-key  $key\n     * @param  TValue|null  $value\n     * @return bool\n     */\n    public function containsStrict($key, $value = null);\n\n    /**\n     * Get the average value of a given key.\n     *\n     * @param  (callable(TValue): float|int)|string|null  $callback\n     * @return float|int|null\n     */\n    public function avg($callback = null);\n\n    /**\n     * Determine if an item exists in the enumerable.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function contains($key, $operator = null, $value = null);\n\n    /**\n     * Determine if an item is not contained in the collection.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContain($key, $operator = null, $value = null);\n\n    /**\n     * Cross join with the given lists, returning all possible permutations.\n     *\n     * @template TCrossJoinKey\n     * @template TCrossJoinValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue>  ...$lists\n     * @return static<int, array<int, TValue|TCrossJoinValue>>\n     */\n    public function crossJoin(...$lists);\n\n    /**\n     * Dump the collection and end the script.\n     *\n     * @param  mixed  ...$args\n     * @return never\n     */\n    public function dd(...$args);\n\n    /**\n     * Dump the collection.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args);\n\n    /**\n     * Get the items that are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @return static\n     */\n    public function diff($items);\n\n    /**\n     * Get the items that are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function diffUsing($items, callable $callback);\n\n    /**\n     * Get the items whose keys and values are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function diffAssoc($items);\n\n    /**\n     * Get the items whose keys and values are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function diffAssocUsing($items, callable $callback);\n\n    /**\n     * Get the items whose keys are not present in the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @return static\n     */\n    public function diffKeys($items);\n\n    /**\n     * Get the items whose keys are not present in the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function diffKeysUsing($items, callable $callback);\n\n    /**\n     * Retrieve duplicate items.\n     *\n     * @param  (callable(TValue): bool)|string|null  $callback\n     * @param  bool  $strict\n     * @return static\n     */\n    public function duplicates($callback = null, $strict = false);\n\n    /**\n     * Retrieve duplicate items using strict comparison.\n     *\n     * @param  (callable(TValue): bool)|string|null  $callback\n     * @return static\n     */\n    public function duplicatesStrict($callback = null);\n\n    /**\n     * Execute a callback over each item.\n     *\n     * @param  callable(TValue, TKey): mixed  $callback\n     * @return $this\n     */\n    public function each(callable $callback);\n\n    /**\n     * Execute a callback over each nested chunk of items.\n     *\n     * @param  callable  $callback\n     * @return static\n     */\n    public function eachSpread(callable $callback);\n\n    /**\n     * Determine if all items pass the given truth test.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function every($key, $operator = null, $value = null);\n\n    /**\n     * Get all items except for those with the specified keys.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>  $keys\n     * @return static\n     */\n    public function except($keys);\n\n    /**\n     * Run a filter over each of the items.\n     *\n     * @param  (callable(TValue): bool)|null  $callback\n     * @return static\n     */\n    public function filter(?callable $callback = null);\n\n    /**\n     * Apply the callback if the given \"value\" is (or resolves to) truthy.\n     *\n     * @template TWhenReturnType as null\n     *\n     * @param  bool  $value\n     * @param  (callable($this): TWhenReturnType)|null  $callback\n     * @param  (callable($this): TWhenReturnType)|null  $default\n     * @return $this|TWhenReturnType\n     */\n    public function when($value, ?callable $callback = null, ?callable $default = null);\n\n    /**\n     * Apply the callback if the collection is empty.\n     *\n     * @template TWhenEmptyReturnType\n     *\n     * @param  (callable($this): TWhenEmptyReturnType)  $callback\n     * @param  (callable($this): TWhenEmptyReturnType)|null  $default\n     * @return $this|TWhenEmptyReturnType\n     */\n    public function whenEmpty(callable $callback, ?callable $default = null);\n\n    /**\n     * Apply the callback if the collection is not empty.\n     *\n     * @template TWhenNotEmptyReturnType\n     *\n     * @param  callable($this): TWhenNotEmptyReturnType  $callback\n     * @param  (callable($this): TWhenNotEmptyReturnType)|null  $default\n     * @return $this|TWhenNotEmptyReturnType\n     */\n    public function whenNotEmpty(callable $callback, ?callable $default = null);\n\n    /**\n     * Apply the callback if the given \"value\" is (or resolves to) falsy.\n     *\n     * @template TUnlessReturnType\n     *\n     * @param  bool  $value\n     * @param  (callable($this): TUnlessReturnType)  $callback\n     * @param  (callable($this): TUnlessReturnType)|null  $default\n     * @return $this|TUnlessReturnType\n     */\n    public function unless($value, callable $callback, ?callable $default = null);\n\n    /**\n     * Apply the callback unless the collection is empty.\n     *\n     * @template TUnlessEmptyReturnType\n     *\n     * @param  callable($this): TUnlessEmptyReturnType  $callback\n     * @param  (callable($this): TUnlessEmptyReturnType)|null  $default\n     * @return $this|TUnlessEmptyReturnType\n     */\n    public function unlessEmpty(callable $callback, ?callable $default = null);\n\n    /**\n     * Apply the callback unless the collection is not empty.\n     *\n     * @template TUnlessNotEmptyReturnType\n     *\n     * @param  callable($this): TUnlessNotEmptyReturnType  $callback\n     * @param  (callable($this): TUnlessNotEmptyReturnType)|null  $default\n     * @return $this|TUnlessNotEmptyReturnType\n     */\n    public function unlessNotEmpty(callable $callback, ?callable $default = null);\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return static\n     */\n    public function where($key, $operator = null, $value = null);\n\n    /**\n     * Filter items where the value for the given key is null.\n     *\n     * @param  string|null  $key\n     * @return static\n     */\n    public function whereNull($key = null);\n\n    /**\n     * Filter items where the value for the given key is not null.\n     *\n     * @param  string|null  $key\n     * @return static\n     */\n    public function whereNotNull($key = null);\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return static\n     */\n    public function whereStrict($key, $value);\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @param  bool  $strict\n     * @return static\n     */\n    public function whereIn($key, $values, $strict = false);\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereInStrict($key, $values);\n\n    /**\n     * Filter items such that the value of the given key is between the given values.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereBetween($key, $values);\n\n    /**\n     * Filter items such that the value of the given key is not between the given values.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereNotBetween($key, $values);\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @param  bool  $strict\n     * @return static\n     */\n    public function whereNotIn($key, $values, $strict = false);\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereNotInStrict($key, $values);\n\n    /**\n     * Filter the items, removing any items that don't match the given type(s).\n     *\n     * @template TWhereInstanceOf\n     *\n     * @param  class-string<TWhereInstanceOf>|array<array-key, class-string<TWhereInstanceOf>>  $type\n     * @return static<TKey, TWhereInstanceOf>\n     */\n    public function whereInstanceOf($type);\n\n    /**\n     * Get the first item from the enumerable passing the given truth test.\n     *\n     * @template TFirstDefault\n     *\n     * @param  (callable(TValue,TKey): bool)|null  $callback\n     * @param  TFirstDefault|(\\Closure(): TFirstDefault)  $default\n     * @return TValue|TFirstDefault\n     */\n    public function first(?callable $callback = null, $default = null);\n\n    /**\n     * Get the first item by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue|null\n     */\n    public function firstWhere($key, $operator = null, $value = null);\n\n    /**\n     * Get a flattened array of the items in the collection.\n     *\n     * @param  int  $depth\n     * @return static\n     */\n    public function flatten($depth = INF);\n\n    /**\n     * Flip the values with their keys.\n     *\n     * @return static<TValue, TKey>\n     */\n    public function flip();\n\n    /**\n     * Get an item from the collection by key.\n     *\n     * @template TGetDefault\n     *\n     * @param  TKey  $key\n     * @param  TGetDefault|(\\Closure(): TGetDefault)  $default\n     * @return TValue|TGetDefault\n     */\n    public function get($key, $default = null);\n\n    /**\n     * Group an associative array by a field or using a callback.\n     *\n     * @template TGroupKey of array-key|\\UnitEnum|\\Stringable\n     *\n     * @param  (callable(TValue, TKey): TGroupKey)|array|string  $groupBy\n     * @param  bool  $preserveKeys\n     * @return static<\n     *  ($groupBy is (array|string)\n     *      ? array-key\n     *      : (TGroupKey is \\UnitEnum ? array-key : (TGroupKey is \\Stringable ? string : TGroupKey))),\n     *  static<($preserveKeys is true ? TKey : int), ($groupBy is array ? mixed : TValue)>\n     * >\n     */\n    public function groupBy($groupBy, $preserveKeys = false);\n\n    /**\n     * Key an associative array by a field or using a callback.\n     *\n     * @template TNewKey of array-key|\\UnitEnum\n     *\n     * @param  (callable(TValue, TKey): TNewKey)|array|string  $keyBy\n     * @return static<($keyBy is (array|string) ? array-key : (TNewKey is \\UnitEnum ? array-key : TNewKey)), TValue>\n     */\n    public function keyBy($keyBy);\n\n    /**\n     * Determine if an item exists in the collection by key.\n     *\n     * @param  TKey|array<array-key, TKey>  $key\n     * @return bool\n     */\n    public function has($key);\n\n    /**\n     * Determine if any of the keys exist in the collection.\n     *\n     * @param  mixed  $key\n     * @return bool\n     */\n    public function hasAny($key);\n\n    /**\n     * Concatenate values of a given key as a string.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string  $value\n     * @param  string|null  $glue\n     * @return string\n     */\n    public function implode($value, $glue = null);\n\n    /**\n     * Intersect the collection with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function intersect($items);\n\n    /**\n     * Intersect the collection with the given items, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function intersectUsing($items, callable $callback);\n\n    /**\n     * Intersect the collection with the given items with additional index check.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function intersectAssoc($items);\n\n    /**\n     * Intersect the collection with the given items with additional index check, using the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items\n     * @param  callable(TValue, TValue): int  $callback\n     * @return static\n     */\n    public function intersectAssocUsing($items, callable $callback);\n\n    /**\n     * Intersect the collection with the given items by key.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, mixed>|iterable<TKey, mixed>  $items\n     * @return static\n     */\n    public function intersectByKeys($items);\n\n    /**\n     * Determine if the collection is empty or not.\n     *\n     * @return bool\n     */\n    public function isEmpty();\n\n    /**\n     * Determine if the collection is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty();\n\n    /**\n     * Determine if the collection contains a single item.\n     *\n     * @return bool\n     */\n    public function containsOneItem();\n\n    /**\n     * Determine if the collection contains multiple items.\n     *\n     * @return bool\n     */\n    public function containsManyItems();\n\n    /**\n     * Determine if the collection contains a single item, optionally matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasSole($key = null, $operator = null, $value = null);\n\n    /**\n     * Determine if the collection contains multiple items, optionally matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasMany($key = null, $operator = null, $value = null);\n\n    /**\n     * Join all items from the collection using a string. The final items can use a separate glue string.\n     *\n     * @param  string  $glue\n     * @param  string  $finalGlue\n     * @return string\n     */\n    public function join($glue, $finalGlue = '');\n\n    /**\n     * Get the keys of the collection items.\n     *\n     * @return static<int, TKey>\n     */\n    public function keys();\n\n    /**\n     * Get the last item from the collection.\n     *\n     * @template TLastDefault\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TLastDefault|(\\Closure(): TLastDefault)  $default\n     * @return TValue|TLastDefault\n     */\n    public function last(?callable $callback = null, $default = null);\n\n    /**\n     * Run a map over each of the items.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TValue, TKey): TMapValue  $callback\n     * @return static<TKey, TMapValue>\n     */\n    public function map(callable $callback);\n\n    /**\n     * Run a map over each nested chunk of items.\n     *\n     * @param  callable  $callback\n     * @return static\n     */\n    public function mapSpread(callable $callback);\n\n    /**\n     * Run a dictionary map over the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapToDictionaryKey of array-key\n     * @template TMapToDictionaryValue\n     *\n     * @param  callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue>  $callback\n     * @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>\n     */\n    public function mapToDictionary(callable $callback);\n\n    /**\n     * Run a grouping map over the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapToGroupsKey of array-key\n     * @template TMapToGroupsValue\n     *\n     * @param  callable(TValue, TKey): array<TMapToGroupsKey, TMapToGroupsValue>  $callback\n     * @return static<TMapToGroupsKey, static<int, TMapToGroupsValue>>\n     */\n    public function mapToGroups(callable $callback);\n\n    /**\n     * Run an associative map over each of the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapWithKeysKey of array-key\n     * @template TMapWithKeysValue\n     *\n     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback\n     * @return static<TMapWithKeysKey, TMapWithKeysValue>\n     */\n    public function mapWithKeys(callable $callback);\n\n    /**\n     * Map a collection and flatten the result by a single level.\n     *\n     * @template TFlatMapKey of array-key\n     * @template TFlatMapValue\n     *\n     * @param  callable(TValue, TKey): (\\Illuminate\\Support\\Collection<TFlatMapKey, TFlatMapValue>|array<TFlatMapKey, TFlatMapValue>)  $callback\n     * @return static<TFlatMapKey, TFlatMapValue>\n     */\n    public function flatMap(callable $callback);\n\n    /**\n     * Map the values into a new class.\n     *\n     * @template TMapIntoValue\n     *\n     * @param  class-string<TMapIntoValue>  $class\n     * @return static<TKey, TMapIntoValue>\n     */\n    public function mapInto($class);\n\n    /**\n     * Merge the collection with the given items.\n     *\n     * @template TMergeValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TMergeValue>|iterable<TKey, TMergeValue>  $items\n     * @return static<TKey, TValue|TMergeValue>\n     */\n    public function merge($items);\n\n    /**\n     * Recursively merge the collection with the given items.\n     *\n     * @template TMergeRecursiveValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue>  $items\n     * @return static<TKey, TValue|TMergeRecursiveValue>\n     */\n    public function mergeRecursive($items);\n\n    /**\n     * Create a collection by using this collection for keys and another for its values.\n     *\n     * @template TCombineValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue>  $values\n     * @return static<TValue, TCombineValue>\n     */\n    public function combine($values);\n\n    /**\n     * Union the collection with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function union($items);\n\n    /**\n     * Get the min value of a given key.\n     *\n     * @param  (callable(TValue):mixed)|string|null  $callback\n     * @return mixed\n     */\n    public function min($callback = null);\n\n    /**\n     * Get the max value of a given key.\n     *\n     * @param  (callable(TValue):mixed)|string|null  $callback\n     * @return mixed\n     */\n    public function max($callback = null);\n\n    /**\n     * Create a new collection consisting of every n-th element.\n     *\n     * @param  int  $step\n     * @param  int  $offset\n     * @return static\n     */\n    public function nth($step, $offset = 0);\n\n    /**\n     * Get the items with the specified keys.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys\n     * @return static\n     */\n    public function only($keys);\n\n    /**\n     * \"Paginate\" the collection by slicing it into a smaller collection.\n     *\n     * @param  int  $page\n     * @param  int  $perPage\n     * @return static\n     */\n    public function forPage($page, $perPage);\n\n    /**\n     * Partition the collection into two arrays using the given callback or key.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return static<int<0, 1>, static<TKey, TValue>>\n     */\n    public function partition($key, $operator = null, $value = null);\n\n    /**\n     * Push all of the given items onto the collection.\n     *\n     * @template TConcatKey of array-key\n     * @template TConcatValue\n     *\n     * @param  iterable<TConcatKey, TConcatValue>  $source\n     * @return static<TKey|TConcatKey, TValue|TConcatValue>\n     */\n    public function concat($source);\n\n    /**\n     * Get one or a specified number of items randomly from the collection.\n     *\n     * @param  int|null  $number\n     * @return static<int, TValue>|TValue\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function random($number = null);\n\n    /**\n     * Reduce the collection to a single value.\n     *\n     * @template TReduceInitial\n     * @template TReduceReturnType\n     *\n     * @param  callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType  $callback\n     * @param  TReduceInitial  $initial\n     * @return TReduceInitial|TReduceReturnType\n     */\n    public function reduce(callable $callback, $initial = null);\n\n    /**\n     * Reduce the collection to multiple aggregate values.\n     *\n     * @param  callable  $callback\n     * @param  mixed  ...$initial\n     * @return array\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function reduceSpread(callable $callback, ...$initial);\n\n    /**\n     * Replace the collection items with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function replace($items);\n\n    /**\n     * Recursively replace the collection items with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function replaceRecursive($items);\n\n    /**\n     * Reverse items order.\n     *\n     * @return static\n     */\n    public function reverse();\n\n    /**\n     * Search the collection for a given value and return the corresponding key if successful.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @param  bool  $strict\n     * @return TKey|bool\n     */\n    public function search($value, $strict = false);\n\n    /**\n     * Get the item before the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function before($value, $strict = false);\n\n    /**\n     * Get the item after the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function after($value, $strict = false);\n\n    /**\n     * Shuffle the items in the collection.\n     *\n     * @return static\n     */\n    public function shuffle();\n\n    /**\n     * Create chunks representing a \"sliding window\" view of the items in the collection.\n     *\n     * @param  int  $size\n     * @param  int  $step\n     * @return static<int, static>\n     */\n    public function sliding($size = 2, $step = 1);\n\n    /**\n     * Skip the first {$count} items.\n     *\n     * @param  int  $count\n     * @return static\n     */\n    public function skip($count);\n\n    /**\n     * Skip items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipUntil($value);\n\n    /**\n     * Skip items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipWhile($value);\n\n    /**\n     * Get a slice of items from the enumerable.\n     *\n     * @param  int  $offset\n     * @param  int|null  $length\n     * @return static\n     */\n    public function slice($offset, $length = null);\n\n    /**\n     * Split a collection into a certain number of groups.\n     *\n     * @param  int  $numberOfGroups\n     * @return static<int, static>\n     */\n    public function split($numberOfGroups);\n\n    /**\n     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.\n     *\n     * @param  (callable(TValue, TKey): bool)|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     * @throws \\Illuminate\\Support\\MultipleItemsFoundException\n     */\n    public function sole($key = null, $operator = null, $value = null);\n\n    /**\n     * Get the first item in the collection but throw an exception if no matching items exist.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     */\n    public function firstOrFail($key = null, $operator = null, $value = null);\n\n    /**\n     * Chunk the collection into chunks of the given size.\n     *\n     * @param  int  $size\n     * @return static<int, static>\n     */\n    public function chunk($size);\n\n    /**\n     * Chunk the collection into chunks with a callback.\n     *\n     * @param  callable(TValue, TKey, static<int, TValue>): bool  $callback\n     * @return static<int, static<int, TValue>>\n     */\n    public function chunkWhile(callable $callback);\n\n    /**\n     * Split a collection into a certain number of groups, and fill the first groups completely.\n     *\n     * @param  int  $numberOfGroups\n     * @return static<int, static>\n     */\n    public function splitIn($numberOfGroups);\n\n    /**\n     * Sort through each item with a callback.\n     *\n     * @param  (callable(TValue, TValue): int)|null|int  $callback\n     * @return static\n     */\n    public function sort($callback = null);\n\n    /**\n     * Sort items in descending order.\n     *\n     * @param  int  $options\n     * @return static\n     */\n    public function sortDesc($options = SORT_REGULAR);\n\n    /**\n     * Sort the collection using the given callback.\n     *\n     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback\n     * @param  int  $options\n     * @param  bool  $descending\n     * @return static\n     */\n    public function sortBy($callback, $options = SORT_REGULAR, $descending = false);\n\n    /**\n     * Sort the collection in descending order using the given callback.\n     *\n     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback\n     * @param  int  $options\n     * @return static\n     */\n    public function sortByDesc($callback, $options = SORT_REGULAR);\n\n    /**\n     * Sort the collection keys.\n     *\n     * @param  int  $options\n     * @param  bool  $descending\n     * @return static\n     */\n    public function sortKeys($options = SORT_REGULAR, $descending = false);\n\n    /**\n     * Sort the collection keys in descending order.\n     *\n     * @param  int  $options\n     * @return static\n     */\n    public function sortKeysDesc($options = SORT_REGULAR);\n\n    /**\n     * Sort the collection keys using a callback.\n     *\n     * @param  callable(TKey, TKey): int  $callback\n     * @return static\n     */\n    public function sortKeysUsing(callable $callback);\n\n    /**\n     * Get the sum of the given values.\n     *\n     * @param  (callable(TValue): mixed)|string|null  $callback\n     * @return mixed\n     */\n    public function sum($callback = null);\n\n    /**\n     * Take the first or last {$limit} items.\n     *\n     * @param  int  $limit\n     * @return static\n     */\n    public function take($limit);\n\n    /**\n     * Take items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function takeUntil($value);\n\n    /**\n     * Take items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function takeWhile($value);\n\n    /**\n     * Pass the collection to the given callback and then return it.\n     *\n     * @param  callable(TValue): mixed  $callback\n     * @return $this\n     */\n    public function tap(callable $callback);\n\n    /**\n     * Pass the enumerable to the given callback and return the result.\n     *\n     * @template TPipeReturnType\n     *\n     * @param  callable($this): TPipeReturnType  $callback\n     * @return TPipeReturnType\n     */\n    public function pipe(callable $callback);\n\n    /**\n     * Pass the collection into a new class.\n     *\n     * @template TPipeIntoValue\n     *\n     * @param  class-string<TPipeIntoValue>  $class\n     * @return TPipeIntoValue\n     */\n    public function pipeInto($class);\n\n    /**\n     * Pass the collection through a series of callable pipes and return the result.\n     *\n     * @param  array<callable>  $pipes\n     * @return mixed\n     */\n    public function pipeThrough($pipes);\n\n    /**\n     * Get the values of a given key.\n     *\n     * @param  string|array<array-key, string>  $value\n     * @param  string|null  $key\n     * @return static<array-key, mixed>\n     */\n    public function pluck($value, $key = null);\n\n    /**\n     * Create a collection of all elements that do not pass a given truth test.\n     *\n     * @param  (callable(TValue, TKey): bool)|bool|TValue  $callback\n     * @return static\n     */\n    public function reject($callback = true);\n\n    /**\n     * Convert a flatten \"dot\" notation array into an expanded array.\n     *\n     * @return static\n     */\n    public function undot();\n\n    /**\n     * Return only unique items from the collection array.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @param  bool  $strict\n     * @return static\n     */\n    public function unique($key = null, $strict = false);\n\n    /**\n     * Return only unique items from the collection array using strict comparison.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @return static\n     */\n    public function uniqueStrict($key = null);\n\n    /**\n     * Reset the keys on the underlying array.\n     *\n     * @return static<int, TValue>\n     */\n    public function values();\n\n    /**\n     * Pad collection to the specified length with a value.\n     *\n     * @template TPadValue\n     *\n     * @param  int  $size\n     * @param  TPadValue  $value\n     * @return static<int, TValue|TPadValue>\n     */\n    public function pad($size, $value);\n\n    /**\n     * Get the values iterator.\n     *\n     * @return \\Traversable<TKey, TValue>\n     */\n    public function getIterator(): Traversable;\n\n    /**\n     * Count the number of items in the collection.\n     *\n     * @return int\n     */\n    public function count(): int;\n\n    /**\n     * Count the number of items in the collection by a field or using a callback.\n     *\n     * @param  (callable(TValue, TKey): (array-key|\\UnitEnum))|string|null  $countBy\n     * @return static<array-key, int>\n     */\n    public function countBy($countBy = null);\n\n    /**\n     * Zip the collection together with one or more arrays.\n     *\n     * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);\n     *      => [[1, 4], [2, 5], [3, 6]]\n     *\n     * @template TZipValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items\n     * @return static<int, static<int, TValue|TZipValue>>\n     */\n    public function zip($items);\n\n    /**\n     * Collect the values into a collection.\n     *\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    public function collect();\n\n    /**\n     * Get the collection of items as a plain array.\n     *\n     * @return array<TKey, mixed>\n     */\n    public function toArray();\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return mixed\n     */\n    public function jsonSerialize(): mixed;\n\n    /**\n     * Get the collection of items as JSON.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0);\n\n    /**\n     * Get the collection of items as pretty print formatted JSON.\n     *\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0);\n\n    /**\n     * Get a CachingIterator instance.\n     *\n     * @param  int  $flags\n     * @return \\CachingIterator\n     */\n    public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING);\n\n    /**\n     * Convert the collection to its string representation.\n     *\n     * @return string\n     */\n    public function __toString();\n\n    /**\n     * Indicate that the model's string representation should be escaped when __toString is invoked.\n     *\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function escapeWhenCastingToString($escape = true);\n\n    /**\n     * Add a method to the list of proxied methods.\n     *\n     * @param  string  $method\n     * @return void\n     */\n    public static function proxy($method);\n\n    /**\n     * Dynamically access collection proxies.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\Exception\n     */\n    public function __get($key);\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/HigherOrderCollectionProxy.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @mixin \\Illuminate\\Support\\Enumerable<TKey, TValue>\n * @mixin TValue\n */\nclass HigherOrderCollectionProxy\n{\n    /**\n     * The collection being operated on.\n     *\n     * @var \\Illuminate\\Support\\Enumerable<TKey, TValue>\n     */\n    protected $collection;\n\n    /**\n     * The method being proxied.\n     *\n     * @var string\n     */\n    protected $method;\n\n    /**\n     * Create a new proxy instance.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<TKey, TValue>  $collection\n     * @param  string  $method\n     */\n    public function __construct(Enumerable $collection, $method)\n    {\n        $this->method = $method;\n        $this->collection = $collection;\n    }\n\n    /**\n     * Proxy accessing an attribute onto the collection items.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->collection->{$this->method}(function ($value) use ($key) {\n            return is_array($value) ? $value[$key] : $value->{$key};\n        });\n    }\n\n    /**\n     * Proxy a method call onto the collection items.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->collection->{$this->method}(function ($value) use ($method, $parameters) {\n            return is_string($value)\n                ? $value::{$method}(...$parameters)\n                : $value->{$method}(...$parameters);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/ItemNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse RuntimeException;\n\nclass ItemNotFoundException extends RuntimeException\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Collections/LazyCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayIterator;\nuse Closure;\nuse DateInterval;\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Generator;\nuse Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString;\nuse Illuminate\\Support\\Traits\\EnumeratesValues;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse IteratorAggregate;\nuse stdClass;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @implements \\Illuminate\\Support\\Enumerable<TKey, TValue>\n */\nclass LazyCollection implements CanBeEscapedWhenCastToString, Enumerable\n{\n    /**\n     * @use \\Illuminate\\Support\\Traits\\EnumeratesValues<TKey, TValue>\n     */\n    use EnumeratesValues, Macroable;\n\n    /**\n     * The source from which to generate items.\n     *\n     * @var (Closure(): \\Generator<TKey, TValue, mixed, void>)|static|array<TKey, TValue>\n     */\n    public $source;\n\n    /**\n     * Create a new lazy collection instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>|(Closure(): \\Generator<TKey, TValue, mixed, void>)|self<TKey, TValue>|array<TKey, TValue>|null  $source\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($source = null)\n    {\n        if ($source instanceof Closure || $source instanceof self) {\n            $this->source = $source;\n        } elseif (is_null($source)) {\n            $this->source = static::empty();\n        } elseif ($source instanceof Generator) {\n            throw new InvalidArgumentException(\n                'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.'\n            );\n        } else {\n            $this->source = $this->getArrayableItems($source);\n        }\n    }\n\n    /**\n     * Create a new collection instance if the value isn't one already.\n     *\n     * @template TMakeKey of array-key\n     * @template TMakeValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|(Closure(): \\Generator<TMakeKey, TMakeValue, mixed, void>)|self<TMakeKey, TMakeValue>|array<TMakeKey, TMakeValue>|null  $items\n     * @return static<TMakeKey, TMakeValue>\n     */\n    public static function make($items = [])\n    {\n        return new static($items);\n    }\n\n    /**\n     * Create a collection with the given range.\n     *\n     * @param  int  $from\n     * @param  int  $to\n     * @param  int  $step\n     * @return ($step is zero ? never : static<int, int>)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function range($from, $to, $step = 1)\n    {\n        if ($step == 0) {\n            throw new InvalidArgumentException('Step value cannot be zero.');\n        }\n\n        return new static(function () use ($from, $to, $step) {\n            if ($from <= $to) {\n                for (; $from <= $to; $from += abs($step)) {\n                    yield $from;\n                }\n            } else {\n                for (; $from >= $to; $from -= abs($step)) {\n                    yield $from;\n                }\n            }\n        });\n    }\n\n    /**\n     * Get all items in the enumerable.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function all()\n    {\n        if (is_array($this->source)) {\n            return $this->source;\n        }\n\n        return iterator_to_array($this->getIterator());\n    }\n\n    /**\n     * Eager load all items into a new lazy collection backed by an array.\n     *\n     * @return static<TKey, TValue>\n     */\n    public function eager()\n    {\n        return new static($this->all());\n    }\n\n    /**\n     * Cache values as they're enumerated.\n     *\n     * @return static<TKey, TValue>\n     */\n    public function remember()\n    {\n        $iterator = $this->getIterator();\n\n        $iteratorIndex = 0;\n\n        $cache = [];\n\n        return new static(function () use ($iterator, &$iteratorIndex, &$cache) {\n            for ($index = 0; true; $index++) {\n                if (array_key_exists($index, $cache)) {\n                    yield $cache[$index][0] => $cache[$index][1];\n\n                    continue;\n                }\n\n                if ($iteratorIndex < $index) {\n                    $iterator->next();\n\n                    $iteratorIndex++;\n                }\n\n                if (! $iterator->valid()) {\n                    break;\n                }\n\n                $cache[$index] = [$iterator->key(), $iterator->current()];\n\n                yield $cache[$index][0] => $cache[$index][1];\n            }\n        });\n    }\n\n    /**\n     * Get the median of a given key.\n     *\n     * @param  string|array<array-key, string>|null  $key\n     * @return float|int|null\n     */\n    public function median($key = null)\n    {\n        return $this->collect()->median($key);\n    }\n\n    /**\n     * Get the mode of a given key.\n     *\n     * @param  string|array<string>|null  $key\n     * @return array<int, float|int>|null\n     */\n    public function mode($key = null)\n    {\n        return $this->collect()->mode($key);\n    }\n\n    /**\n     * Collapse the collection of items into a single array.\n     *\n     * @return static<int, mixed>\n     */\n    public function collapse()\n    {\n        return new static(function () {\n            foreach ($this as $values) {\n                if (is_array($values) || $values instanceof Enumerable) {\n                    foreach ($values as $value) {\n                        yield $value;\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Collapse the collection of items into a single array while preserving its keys.\n     *\n     * @return static<mixed, mixed>\n     */\n    public function collapseWithKeys()\n    {\n        return new static(function () {\n            foreach ($this as $values) {\n                if (is_array($values) || $values instanceof Enumerable) {\n                    foreach ($values as $key => $value) {\n                        yield $key => $value;\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Determine if an item exists in the enumerable.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function contains($key, $operator = null, $value = null)\n    {\n        if (func_num_args() === 1 && $this->useAsCallable($key)) {\n            $placeholder = new stdClass;\n\n            /** @var callable $key */\n            return $this->first($key, $placeholder) !== $placeholder;\n        }\n\n        if (func_num_args() === 1) {\n            $needle = $key;\n\n            foreach ($this as $value) {\n                if ($value == $needle) {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        return $this->contains($this->operatorForWhere(...func_get_args()));\n    }\n\n    /**\n     * Determine if an item exists, using strict comparison.\n     *\n     * @param  (callable(TValue): bool)|TValue|array-key  $key\n     * @param  TValue|null  $value\n     * @return bool\n     */\n    public function containsStrict($key, $value = null)\n    {\n        if (func_num_args() === 2) {\n            return $this->contains(fn ($item) => data_get($item, $key) === $value);\n        }\n\n        if ($this->useAsCallable($key)) {\n            return ! is_null($this->first($key));\n        }\n\n        foreach ($this as $item) {\n            if ($item === $key) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if an item is not contained in the enumerable.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContain($key, $operator = null, $value = null)\n    {\n        return ! $this->contains(...func_get_args());\n    }\n\n    /**\n     * Determine if an item is not contained in the enumerable, using strict comparison.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContainStrict($key, $operator = null, $value = null)\n    {\n        return ! $this->containsStrict(...func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function crossJoin(...$arrays)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function countBy($countBy = null)\n    {\n        $countBy = is_null($countBy)\n            ? $this->identity()\n            : $this->valueRetriever($countBy);\n\n        return new static(function () use ($countBy) {\n            $counts = [];\n\n            foreach ($this as $key => $value) {\n                $group = enum_value($countBy($value, $key));\n\n                if (empty($counts[$group])) {\n                    $counts[$group] = 0;\n                }\n\n                $counts[$group]++;\n            }\n\n            yield from $counts;\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diff($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diffUsing($items, callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diffAssoc($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diffAssocUsing($items, callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diffKeys($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function diffKeysUsing($items, callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function duplicates($callback = null, $strict = false)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function duplicatesStrict($callback = null)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function except($keys)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Run a filter over each of the items.\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @return static\n     */\n    public function filter(?callable $callback = null)\n    {\n        if (is_null($callback)) {\n            $callback = fn ($value) => (bool) $value;\n        }\n\n        return new static(function () use ($callback) {\n            foreach ($this as $key => $value) {\n                if ($callback($value, $key)) {\n                    yield $key => $value;\n                }\n            }\n        });\n    }\n\n    /**\n     * Get the first item from the enumerable passing the given truth test.\n     *\n     * @template TFirstDefault\n     *\n     * @param  (callable(TValue): bool)|null  $callback\n     * @param  TFirstDefault|(\\Closure(): TFirstDefault)  $default\n     * @return TValue|TFirstDefault\n     */\n    public function first(?callable $callback = null, $default = null)\n    {\n        $iterator = $this->getIterator();\n\n        if (is_null($callback)) {\n            if (! $iterator->valid()) {\n                return value($default);\n            }\n\n            return $iterator->current();\n        }\n\n        foreach ($iterator as $key => $value) {\n            if ($callback($value, $key)) {\n                return $value;\n            }\n        }\n\n        return value($default);\n    }\n\n    /**\n     * Get a flattened list of the items in the collection.\n     *\n     * @param  int  $depth\n     * @return static<int, mixed>\n     */\n    public function flatten($depth = INF)\n    {\n        $instance = new static(function () use ($depth) {\n            foreach ($this as $item) {\n                if (! is_array($item) && ! $item instanceof Enumerable) {\n                    yield $item;\n                } elseif ($depth === 1) {\n                    yield from $item;\n                } else {\n                    yield from (new static($item))->flatten($depth - 1);\n                }\n            }\n        });\n\n        return $instance->values();\n    }\n\n    /**\n     * Flip the items in the collection.\n     *\n     * @return static<TValue, TKey>\n     */\n    public function flip()\n    {\n        return new static(function () {\n            foreach ($this as $key => $value) {\n                yield $value => $key;\n            }\n        });\n    }\n\n    /**\n     * Get an item by key.\n     *\n     * @template TGetDefault\n     *\n     * @param  TKey|null  $key\n     * @param  TGetDefault|(\\Closure(): TGetDefault)  $default\n     * @return TValue|TGetDefault\n     */\n    public function get($key, $default = null)\n    {\n        if (is_null($key)) {\n            return;\n        }\n\n        foreach ($this as $outerKey => $outerValue) {\n            if ($outerKey == $key) {\n                return $outerValue;\n            }\n        }\n\n        return value($default);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function groupBy($groupBy, $preserveKeys = false)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function keyBy($keyBy)\n    {\n        return new static(function () use ($keyBy) {\n            $keyBy = $this->valueRetriever($keyBy);\n\n            foreach ($this as $key => $item) {\n                $resolvedKey = $keyBy($item, $key);\n\n                if (is_object($resolvedKey)) {\n                    $resolvedKey = (string) $resolvedKey;\n                }\n\n                yield $resolvedKey => $item;\n            }\n        });\n    }\n\n    /**\n     * Determine if an item exists in the collection by key.\n     *\n     * @param  mixed  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        $keys = array_flip(is_array($key) ? $key : func_get_args());\n        $count = count($keys);\n\n        foreach ($this as $key => $value) {\n            if (array_key_exists($key, $keys) && --$count == 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if any of the keys exist in the collection.\n     *\n     * @param  mixed  $key\n     * @return bool\n     */\n    public function hasAny($key)\n    {\n        $keys = array_flip(is_array($key) ? $key : func_get_args());\n\n        foreach ($this as $key => $value) {\n            if (array_key_exists($key, $keys)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Concatenate values of a given key as a string.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string  $value\n     * @param  string|null  $glue\n     * @return string\n     */\n    public function implode($value, $glue = null)\n    {\n        return $this->collect()->implode(...func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function intersect($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function intersectUsing($items, callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function intersectAssoc($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function intersectAssocUsing($items, callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function intersectByKeys($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Determine if the items are empty or not.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return ! $this->getIterator()->valid();\n    }\n\n    /**\n     * Determine if the collection contains a single item.\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @return bool\n     *\n     * @deprecated 12.49.0 Use the `hasSole()` method instead.\n     */\n    public function containsOneItem(?callable $callback = null): bool\n    {\n        return $this->hasSole($callback);\n    }\n\n    /**\n     * Determine if the collection contains multiple items.\n     *\n     * @return bool\n     *\n     * @deprecated 12.50.0 Use the `hasMany()` method instead.\n     */\n    public function containsManyItems(): bool\n    {\n        return $this->hasMany();\n    }\n\n    /**\n     * Join all items from the collection using a string. The final items can use a separate glue string.\n     *\n     * @param  string  $glue\n     * @param  string  $finalGlue\n     * @return string\n     */\n    public function join($glue, $finalGlue = '')\n    {\n        return $this->collect()->join(...func_get_args());\n    }\n\n    /**\n     * Get the keys of the collection items.\n     *\n     * @return static<int, TKey>\n     */\n    public function keys()\n    {\n        return new static(function () {\n            foreach ($this as $key => $value) {\n                yield $key;\n            }\n        });\n    }\n\n    /**\n     * Get the last item from the collection.\n     *\n     * @template TLastDefault\n     *\n     * @param  (callable(TValue, TKey): bool)|null  $callback\n     * @param  TLastDefault|(\\Closure(): TLastDefault)  $default\n     * @return TValue|TLastDefault\n     */\n    public function last(?callable $callback = null, $default = null)\n    {\n        $needle = $placeholder = new stdClass;\n\n        foreach ($this as $key => $value) {\n            if (is_null($callback) || $callback($value, $key)) {\n                $needle = $value;\n            }\n        }\n\n        return $needle === $placeholder ? value($default) : $needle;\n    }\n\n    /**\n     * Get the values of a given key.\n     *\n     * @param  string|array<array-key, string>  $value\n     * @param  string|null  $key\n     * @return static<array-key, mixed>\n     */\n    public function pluck($value, $key = null)\n    {\n        return new static(function () use ($value, $key) {\n            [$value, $key] = $this->explodePluckParameters($value, $key);\n\n            foreach ($this as $item) {\n                $itemValue = $value instanceof Closure\n                    ? $value($item)\n                    : data_get($item, $value);\n\n                if (is_null($key)) {\n                    yield $itemValue;\n                } else {\n                    $itemKey = $key instanceof Closure\n                        ? $key($item)\n                        : data_get($item, $key);\n\n                    if (is_object($itemKey) && method_exists($itemKey, '__toString')) {\n                        $itemKey = (string) $itemKey;\n                    }\n\n                    yield $itemKey => $itemValue;\n                }\n            }\n        });\n    }\n\n    /**\n     * Run a map over each of the items.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TValue, TKey): TMapValue  $callback\n     * @return static<TKey, TMapValue>\n     */\n    public function map(callable $callback)\n    {\n        return new static(function () use ($callback) {\n            foreach ($this as $key => $value) {\n                yield $key => $callback($value, $key);\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function mapToDictionary(callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Run an associative map over each of the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapWithKeysKey of array-key\n     * @template TMapWithKeysValue\n     *\n     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback\n     * @return static<TMapWithKeysKey, TMapWithKeysValue>\n     */\n    public function mapWithKeys(callable $callback)\n    {\n        return new static(function () use ($callback) {\n            foreach ($this as $key => $value) {\n                yield from $callback($value, $key);\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function merge($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function mergeRecursive($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Multiply the items in the collection by the multiplier.\n     *\n     * @param  int  $multiplier\n     * @return static\n     */\n    public function multiply(int $multiplier)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Create a collection by using this collection for keys and another for its values.\n     *\n     * @template TCombineValue\n     *\n     * @param  \\IteratorAggregate<array-key, TCombineValue>|array<array-key, TCombineValue>|(callable(): \\Generator<array-key, TCombineValue>)  $values\n     * @return static<TValue, TCombineValue>\n     */\n    public function combine($values)\n    {\n        return new static(function () use ($values) {\n            $values = $this->makeIterator($values);\n\n            $errorMessage = 'Both parameters should have an equal number of elements';\n\n            foreach ($this as $key) {\n                if (! $values->valid()) {\n                    trigger_error($errorMessage, E_USER_WARNING);\n\n                    break;\n                }\n\n                yield $key => $values->current();\n\n                $values->next();\n            }\n\n            if ($values->valid()) {\n                trigger_error($errorMessage, E_USER_WARNING);\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function union($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Create a new collection consisting of every n-th element.\n     *\n     * @param  int  $step\n     * @param  int  $offset\n     * @return ($step is positive-int ? static : never)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function nth($step, $offset = 0)\n    {\n        if ($step < 1) {\n            throw new InvalidArgumentException('Step value must be at least 1.');\n        }\n\n        return new static(function () use ($step, $offset) {\n            $position = 0;\n\n            foreach ($this->slice($offset) as $item) {\n                if ($position % $step === 0) {\n                    yield $item;\n                }\n\n                $position++;\n            }\n        });\n    }\n\n    /**\n     * Get the items with the specified keys.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys\n     * @return static\n     */\n    public function only($keys)\n    {\n        if ($keys instanceof Enumerable) {\n            $keys = $keys->all();\n        } elseif (! is_null($keys)) {\n            $keys = is_array($keys) ? $keys : func_get_args();\n        }\n\n        return new static(function () use ($keys) {\n            if (is_null($keys)) {\n                yield from $this;\n            } else {\n                $keys = array_flip($keys);\n\n                foreach ($this as $key => $value) {\n                    if (array_key_exists($key, $keys)) {\n                        yield $key => $value;\n\n                        unset($keys[$key]);\n\n                        if (empty($keys)) {\n                            break;\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Select specific values from the items within the collection.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys\n     * @return static\n     */\n    public function select($keys)\n    {\n        if ($keys instanceof Enumerable) {\n            $keys = $keys->all();\n        } elseif (! is_null($keys)) {\n            $keys = is_array($keys) ? $keys : func_get_args();\n        }\n\n        return new static(function () use ($keys) {\n            if (is_null($keys)) {\n                yield from $this;\n            } else {\n                foreach ($this as $item) {\n                    $result = [];\n\n                    foreach ($keys as $key) {\n                        if (Arr::accessible($item) && Arr::exists($item, $key)) {\n                            $result[$key] = $item[$key];\n                        } elseif (is_object($item) && isset($item->{$key})) {\n                            $result[$key] = $item->{$key};\n                        }\n                    }\n\n                    yield $result;\n                }\n            }\n        });\n    }\n\n    /**\n     * Push all of the given items onto the collection.\n     *\n     * @template TConcatKey of array-key\n     * @template TConcatValue\n     *\n     * @param  iterable<TConcatKey, TConcatValue>  $source\n     * @return static<TKey|TConcatKey, TValue|TConcatValue>\n     */\n    public function concat($source)\n    {\n        return (new static(function () use ($source) {\n            yield from $this;\n            yield from $source;\n        }))->values();\n    }\n\n    /**\n     * Get one or a specified number of items randomly from the collection.\n     *\n     * @param  int|null  $number\n     * @param  bool  $preserveKeys\n     * @return static<int, TValue>|TValue\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function random($number = null, $preserveKeys = false)\n    {\n        $result = $this->collect()->random(...func_get_args());\n\n        return is_null($number) ? $result : new static($result);\n    }\n\n    /**\n     * Replace the collection items with the given items.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @return static\n     */\n    public function replace($items)\n    {\n        return new static(function () use ($items) {\n            $items = $this->getArrayableItems($items);\n\n            foreach ($this as $key => $value) {\n                if (array_key_exists($key, $items)) {\n                    yield $key => $items[$key];\n\n                    unset($items[$key]);\n                } else {\n                    yield $key => $value;\n                }\n            }\n\n            foreach ($items as $key => $value) {\n                yield $key => $value;\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function replaceRecursive($items)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function reverse()\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Search the collection for a given value and return the corresponding key if successful.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TKey|false\n     */\n    public function search($value, $strict = false)\n    {\n        /** @var (callable(TValue,TKey): bool) $predicate */\n        $predicate = $this->useAsCallable($value)\n            ? $value\n            : function ($item) use ($value, $strict) {\n                return $strict ? $item === $value : $item == $value;\n            };\n\n        foreach ($this as $key => $item) {\n            if ($predicate($item, $key)) {\n                return $key;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the item before the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function before($value, $strict = false)\n    {\n        $previous = null;\n\n        /** @var (callable(TValue,TKey): bool) $predicate */\n        $predicate = $this->useAsCallable($value)\n            ? $value\n            : function ($item) use ($value, $strict) {\n                return $strict ? $item === $value : $item == $value;\n            };\n\n        foreach ($this as $key => $item) {\n            if ($predicate($item, $key)) {\n                return $previous;\n            }\n\n            $previous = $item;\n        }\n\n        return null;\n    }\n\n    /**\n     * Get the item after the given item.\n     *\n     * @param  TValue|(callable(TValue,TKey): bool)  $value\n     * @param  bool  $strict\n     * @return TValue|null\n     */\n    public function after($value, $strict = false)\n    {\n        $found = false;\n\n        /** @var (callable(TValue,TKey): bool) $predicate */\n        $predicate = $this->useAsCallable($value)\n            ? $value\n            : function ($item) use ($value, $strict) {\n                return $strict ? $item === $value : $item == $value;\n            };\n\n        foreach ($this as $key => $item) {\n            if ($found) {\n                return $item;\n            }\n\n            if ($predicate($item, $key)) {\n                $found = true;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function shuffle()\n    {\n        return $this->passthru(__FUNCTION__, []);\n    }\n\n    /**\n     * Create chunks representing a \"sliding window\" view of the items in the collection.\n     *\n     * @param  positive-int  $size\n     * @param  positive-int  $step\n     * @return static<int, static>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function sliding($size = 2, $step = 1)\n    {\n        if ($size < 1) {\n            throw new InvalidArgumentException('Size value must be at least 1.');\n        } elseif ($step < 1) {\n            throw new InvalidArgumentException('Step value must be at least 1.');\n        }\n\n        return new static(function () use ($size, $step) {\n            $iterator = $this->getIterator();\n\n            $chunk = [];\n\n            while ($iterator->valid()) {\n                $chunk[$iterator->key()] = $iterator->current();\n\n                if (count($chunk) == $size) {\n                    yield (new static($chunk))->tap(function () use (&$chunk, $step) {\n                        $chunk = array_slice($chunk, $step, null, true);\n                    });\n\n                    // If the $step between chunks is bigger than each chunk's $size\n                    // we will skip the extra items (which should never be in any\n                    // chunk) before we continue to the next chunk in the loop.\n                    if ($step > $size) {\n                        $skip = $step - $size;\n\n                        for ($i = 0; $i < $skip && $iterator->valid(); $i++) {\n                            $iterator->next();\n                        }\n                    }\n                }\n\n                $iterator->next();\n            }\n        });\n    }\n\n    /**\n     * Skip the first {$count} items.\n     *\n     * @param  int  $count\n     * @return static\n     */\n    public function skip($count)\n    {\n        return new static(function () use ($count) {\n            $iterator = $this->getIterator();\n\n            while ($iterator->valid() && $count--) {\n                $iterator->next();\n            }\n\n            while ($iterator->valid()) {\n                yield $iterator->key() => $iterator->current();\n\n                $iterator->next();\n            }\n        });\n    }\n\n    /**\n     * Skip items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipUntil($value)\n    {\n        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);\n\n        return $this->skipWhile($this->negate($callback));\n    }\n\n    /**\n     * Skip items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static\n     */\n    public function skipWhile($value)\n    {\n        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);\n\n        return new static(function () use ($callback) {\n            $iterator = $this->getIterator();\n\n            while ($iterator->valid() && $callback($iterator->current(), $iterator->key())) {\n                $iterator->next();\n            }\n\n            while ($iterator->valid()) {\n                yield $iterator->key() => $iterator->current();\n\n                $iterator->next();\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function slice($offset, $length = null)\n    {\n        if ($offset < 0 || $length < 0) {\n            return $this->passthru(__FUNCTION__, func_get_args());\n        }\n\n        $instance = $this->skip($offset);\n\n        return is_null($length) ? $instance : $instance->take($length);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @throws \\InvalidArgumentException\n     */\n    #[\\Override]\n    public function split($numberOfGroups)\n    {\n        if ($numberOfGroups < 1) {\n            throw new InvalidArgumentException('Number of groups must be at least 1.');\n        }\n\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     * @throws \\Illuminate\\Support\\MultipleItemsFoundException\n     */\n    public function sole($key = null, $operator = null, $value = null)\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        return $this\n            ->unless($filter == null)\n            ->filter($filter)\n            ->take(2)\n            ->collect()\n            ->sole();\n    }\n\n    /**\n     * Determine if the collection contains a single item or a single item matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasSole($key = null, $operator = null, $value = null): bool\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        return $this\n            ->unless($filter == null)\n            ->filter($filter)\n            ->take(2)\n            ->count() === 1;\n    }\n\n    /**\n     * Get the first item in the collection but throw an exception if no matching items exist.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     */\n    public function firstOrFail($key = null, $operator = null, $value = null)\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        return $this\n            ->unless($filter == null)\n            ->filter($filter)\n            ->take(1)\n            ->collect()\n            ->firstOrFail();\n    }\n\n    /**\n     * Chunk the collection into chunks of the given size.\n     *\n     * @param  int  $size\n     * @param  bool  $preserveKeys\n     * @return ($preserveKeys is true ? static<int, static> : static<int, static<int, TValue>>)\n     */\n    public function chunk($size, $preserveKeys = true)\n    {\n        if ($size <= 0) {\n            return static::empty();\n        }\n\n        $add = match ($preserveKeys) {\n            true => fn (array &$chunk, Traversable $iterator) => $chunk[$iterator->key()] = $iterator->current(),\n            false => fn (array &$chunk, Traversable $iterator) => $chunk[] = $iterator->current(),\n        };\n\n        return new static(function () use ($size, $add) {\n            $iterator = $this->getIterator();\n\n            while ($iterator->valid()) {\n                $chunk = [];\n\n                while (true) {\n                    $add($chunk, $iterator);\n\n                    if (count($chunk) < $size) {\n                        $iterator->next();\n\n                        if (! $iterator->valid()) {\n                            break;\n                        }\n                    } else {\n                        break;\n                    }\n                }\n\n                yield new static($chunk);\n\n                $iterator->next();\n            }\n        });\n    }\n\n    /**\n     * Split a collection into a certain number of groups, and fill the first groups completely.\n     *\n     * @param  int  $numberOfGroups\n     * @return ($numberOfGroups is positive-int ? static<int, static> : never)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function splitIn($numberOfGroups)\n    {\n        if ($numberOfGroups < 1) {\n            throw new InvalidArgumentException('Number of groups must be at least 1.');\n        }\n\n        return $this->chunk((int) ceil($this->count() / $numberOfGroups));\n    }\n\n    /**\n     * Chunk the collection into chunks with a callback.\n     *\n     * @param  callable(TValue, TKey, Collection<TKey, TValue>): bool  $callback\n     * @return static<int, static<TKey, TValue>>\n     */\n    public function chunkWhile(callable $callback)\n    {\n        return new static(function () use ($callback) {\n            $iterator = $this->getIterator();\n\n            $chunk = new Collection;\n\n            if ($iterator->valid()) {\n                $chunk[$iterator->key()] = $iterator->current();\n\n                $iterator->next();\n            }\n\n            while ($iterator->valid()) {\n                if (! $callback($iterator->current(), $iterator->key(), $chunk)) {\n                    yield new static($chunk);\n\n                    $chunk = new Collection;\n                }\n\n                $chunk[$iterator->key()] = $iterator->current();\n\n                $iterator->next();\n            }\n\n            if ($chunk->isNotEmpty()) {\n                yield new static($chunk);\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sort($callback = null)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortDesc($options = SORT_REGULAR)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortByDesc($callback, $options = SORT_REGULAR)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortKeys($options = SORT_REGULAR, $descending = false)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortKeysDesc($options = SORT_REGULAR)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function sortKeysUsing(callable $callback)\n    {\n        return $this->passthru(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Take the first or last {$limit} items.\n     *\n     * @param  int  $limit\n     * @return static<TKey, TValue>\n     */\n    public function take($limit)\n    {\n        if ($limit < 0) {\n            return new static(function () use ($limit) {\n                $limit = abs($limit);\n                $ringBuffer = [];\n                $position = 0;\n\n                foreach ($this as $key => $value) {\n                    $ringBuffer[$position] = [$key, $value];\n                    $position = ($position + 1) % $limit;\n                }\n\n                for ($i = 0, $end = min($limit, count($ringBuffer)); $i < $end; $i++) {\n                    $pointer = ($position + $i) % $limit;\n                    yield $ringBuffer[$pointer][0] => $ringBuffer[$pointer][1];\n                }\n            });\n        }\n\n        return new static(function () use ($limit) {\n            $iterator = $this->getIterator();\n\n            while ($limit--) {\n                if (! $iterator->valid()) {\n                    break;\n                }\n\n                yield $iterator->key() => $iterator->current();\n\n                if ($limit) {\n                    $iterator->next();\n                }\n            }\n        });\n    }\n\n    /**\n     * Take items in the collection until the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static<TKey, TValue>\n     */\n    public function takeUntil($value)\n    {\n        /** @var callable(TValue, TKey): bool $callback */\n        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);\n\n        return new static(function () use ($callback) {\n            foreach ($this as $key => $item) {\n                if ($callback($item, $key)) {\n                    break;\n                }\n\n                yield $key => $item;\n            }\n        });\n    }\n\n    /**\n     * Take items in the collection until a given point in time, with an optional callback on timeout.\n     *\n     * @param  \\DateTimeInterface  $timeout\n     * @param  callable(TValue|null, TKey|null): mixed|null  $callback\n     * @return static<TKey, TValue>\n     */\n    public function takeUntilTimeout(DateTimeInterface $timeout, ?callable $callback = null)\n    {\n        $timeout = $timeout->getTimestamp();\n\n        return new static(function () use ($timeout, $callback) {\n            if ($this->now() >= $timeout) {\n                if ($callback) {\n                    $callback(null, null);\n                }\n\n                return;\n            }\n\n            foreach ($this as $key => $value) {\n                yield $key => $value;\n\n                if ($this->now() >= $timeout) {\n                    if ($callback) {\n                        $callback($value, $key);\n                    }\n\n                    break;\n                }\n            }\n        });\n    }\n\n    /**\n     * Take items in the collection while the given condition is met.\n     *\n     * @param  TValue|callable(TValue,TKey): bool  $value\n     * @return static<TKey, TValue>\n     */\n    public function takeWhile($value)\n    {\n        /** @var callable(TValue, TKey): bool $callback */\n        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);\n\n        return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key));\n    }\n\n    /**\n     * Pass each item in the collection to the given callback, lazily.\n     *\n     * @param  callable(TValue, TKey): mixed  $callback\n     * @return static<TKey, TValue>\n     */\n    public function tapEach(callable $callback)\n    {\n        return new static(function () use ($callback) {\n            foreach ($this as $key => $value) {\n                $callback($value, $key);\n\n                yield $key => $value;\n            }\n        });\n    }\n\n    /**\n     * Throttle the values, releasing them at most once per the given seconds.\n     *\n     * @return static<TKey, TValue>\n     */\n    public function throttle(float $seconds)\n    {\n        return new static(function () use ($seconds) {\n            $microseconds = $seconds * 1_000_000;\n\n            foreach ($this as $key => $value) {\n                $fetchedAt = $this->preciseNow();\n\n                yield $key => $value;\n\n                $sleep = $microseconds - ($this->preciseNow() - $fetchedAt);\n\n                $this->usleep((int) $sleep);\n            }\n        });\n    }\n\n    /**\n     * Flatten a multi-dimensional associative array with dots.\n     *\n     * @param  int  $depth\n     * @return static\n     */\n    public function dot($depth = INF)\n    {\n        return $this->passthru(__FUNCTION__, [$depth]);\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function undot()\n    {\n        return $this->passthru(__FUNCTION__, []);\n    }\n\n    /**\n     * Return only unique items from the collection array.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @param  bool  $strict\n     * @return static<TKey, TValue>\n     */\n    public function unique($key = null, $strict = false)\n    {\n        $callback = $this->valueRetriever($key);\n\n        return new static(function () use ($callback, $strict) {\n            $exists = [];\n\n            foreach ($this as $key => $item) {\n                if (! in_array($id = $callback($item, $key), $exists, $strict)) {\n                    yield $key => $item;\n\n                    $exists[] = $id;\n                }\n            }\n        });\n    }\n\n    /**\n     * Reset the keys on the underlying array.\n     *\n     * @return static<int, TValue>\n     */\n    public function values()\n    {\n        return new static(function () {\n            foreach ($this as $item) {\n                yield $item;\n            }\n        });\n    }\n\n    /**\n     * Run the given callback every time the interval has passed.\n     *\n     * @return static<TKey, TValue>\n     */\n    public function withHeartbeat(DateInterval|int $interval, callable $callback)\n    {\n        $seconds = is_int($interval) ? $interval : $this->intervalSeconds($interval);\n\n        return new static(function () use ($seconds, $callback) {\n            $start = $this->now();\n\n            foreach ($this as $key => $value) {\n                $now = $this->now();\n\n                if (($now - $start) >= $seconds) {\n                    $callback();\n\n                    $start = $now;\n                }\n\n                yield $key => $value;\n            }\n        });\n    }\n\n    /**\n     * Get the total seconds from the given interval.\n     */\n    protected function intervalSeconds(DateInterval $interval): int\n    {\n        $start = new DateTimeImmutable();\n\n        return $start->add($interval)->getTimestamp() - $start->getTimestamp();\n    }\n\n    /**\n     * Zip the collection together with one or more arrays.\n     *\n     * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]);\n     *      => [[1, 4], [2, 5], [3, 6]]\n     *\n     * @template TZipValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items\n     * @return static<int, static<int, TValue|TZipValue>>\n     */\n    public function zip($items)\n    {\n        $iterables = func_get_args();\n\n        return new static(function () use ($iterables) {\n            $iterators = (new Collection($iterables))\n                ->map(fn ($iterable) => $this->makeIterator($iterable))\n                ->prepend($this->getIterator());\n\n            while ($iterators->contains->valid()) {\n                yield new static($iterators->map->current());\n\n                $iterators->each->next();\n            }\n        });\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    #[\\Override]\n    public function pad($size, $value)\n    {\n        if ($size < 0) {\n            return $this->passthru(__FUNCTION__, func_get_args());\n        }\n\n        return new static(function () use ($size, $value) {\n            $yielded = 0;\n\n            foreach ($this as $index => $item) {\n                yield $index => $item;\n\n                $yielded++;\n            }\n\n            while ($yielded++ < $size) {\n                yield $value;\n            }\n        });\n    }\n\n    /**\n     * Get the values iterator.\n     *\n     * @return \\Traversable<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return $this->makeIterator($this->source);\n    }\n\n    /**\n     * Count the number of items in the collection.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        if (is_array($this->source)) {\n            return count($this->source);\n        }\n\n        return iterator_count($this->getIterator());\n    }\n\n    /**\n     * Make an iterator from the given source.\n     *\n     * @template TIteratorKey of array-key\n     * @template TIteratorValue\n     *\n     * @param  \\IteratorAggregate<TIteratorKey, TIteratorValue>|array<TIteratorKey, TIteratorValue>|(callable(): \\Generator<TIteratorKey, TIteratorValue>)  $source\n     * @return \\Traversable<TIteratorKey, TIteratorValue>\n     */\n    protected function makeIterator($source)\n    {\n        if ($source instanceof IteratorAggregate) {\n            return $source->getIterator();\n        }\n\n        if (is_array($source)) {\n            return new ArrayIterator($source);\n        }\n\n        if (is_callable($source)) {\n            $maybeTraversable = $source();\n\n            return $maybeTraversable instanceof Traversable\n                ? $maybeTraversable\n                : new ArrayIterator(Arr::wrap($maybeTraversable));\n        }\n\n        return new ArrayIterator((array) $source);\n    }\n\n    /**\n     * Explode the \"value\" and \"key\" arguments passed to \"pluck\".\n     *\n     * @param  string|string[]  $value\n     * @param  string|string[]|null  $key\n     * @return array{string[],string[]|null}\n     */\n    protected function explodePluckParameters($value, $key)\n    {\n        $value = is_string($value) ? explode('.', $value) : $value;\n\n        $key = is_null($key) || is_array($key) || $key instanceof Closure ? $key : explode('.', $key);\n\n        return [$value, $key];\n    }\n\n    /**\n     * Pass this lazy collection through a method on the collection class.\n     *\n     * @param  string  $method\n     * @param  array<mixed>  $params\n     * @return static\n     */\n    protected function passthru($method, array $params)\n    {\n        return new static(function () use ($method, $params) {\n            yield from $this->collect()->$method(...$params);\n        });\n    }\n\n    /**\n     * Get the current time.\n     *\n     * @return int\n     */\n    protected function now()\n    {\n        return class_exists(Carbon::class)\n            ? Carbon::now()->timestamp\n            : time();\n    }\n\n    /**\n     * Get the precise current time.\n     *\n     * @return float\n     */\n    protected function preciseNow()\n    {\n        return class_exists(Carbon::class)\n            ? Carbon::now()->getPreciseTimestamp()\n            : microtime(true) * 1_000_000;\n    }\n\n    /**\n     * Sleep for the given amount of microseconds.\n     *\n     * @return void\n     */\n    protected function usleep(int $microseconds)\n    {\n        if ($microseconds <= 0) {\n            return;\n        }\n\n        class_exists(Sleep::class)\n            ? Sleep::usleep($microseconds)\n            : usleep($microseconds);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/MultipleItemsFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse RuntimeException;\n\nclass MultipleItemsFoundException extends RuntimeException\n{\n    /**\n     * The number of items found.\n     *\n     * @var int\n     */\n    public $count;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  int  $count\n     * @param  int  $code\n     * @param  \\Throwable|null  $previous\n     */\n    public function __construct($count, $code = 0, $previous = null)\n    {\n        $this->count = $count;\n\n        parent::__construct(\"$count items were found.\", $code, $previous);\n    }\n\n    /**\n     * Get the number of items found.\n     *\n     * @return int\n     */\n    public function getCount()\n    {\n        return $this->count;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/Traits/EnumeratesValues.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse BackedEnum;\nuse CachingIterator;\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Enumerable;\nuse Illuminate\\Support\\HigherOrderCollectionProxy;\nuse JsonSerializable;\nuse UnexpectedValueException;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $average\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $avg\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $contains\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $doesntContain\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $each\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $every\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $filter\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $first\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $flatMap\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $groupBy\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $hasMany\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $hasSole\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $keyBy\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $last\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $map\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $max\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $min\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $partition\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $percentage\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $reject\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $skipUntil\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $skipWhile\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $some\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $sortBy\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $sortByDesc\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $sum\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $takeUntil\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $takeWhile\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $unique\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $unless\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $until\n * @property-read HigherOrderCollectionProxy<TKey, TValue> $when\n */\ntrait EnumeratesValues\n{\n    use Conditionable;\n\n    /**\n     * Indicates that the object's string representation should be escaped when __toString is invoked.\n     *\n     * @var bool\n     */\n    protected $escapeWhenCastingToString = false;\n\n    /**\n     * The methods that can be proxied.\n     *\n     * @var array<int, string>\n     */\n    protected static $proxies = [\n        'average',\n        'avg',\n        'contains',\n        'doesntContain',\n        'each',\n        'every',\n        'filter',\n        'first',\n        'flatMap',\n        'groupBy',\n        'hasMany',\n        'hasSole',\n        'keyBy',\n        'last',\n        'map',\n        'max',\n        'min',\n        'partition',\n        'percentage',\n        'reject',\n        'skipUntil',\n        'skipWhile',\n        'some',\n        'sortBy',\n        'sortByDesc',\n        'sum',\n        'takeUntil',\n        'takeWhile',\n        'unique',\n        'unless',\n        'until',\n        'when',\n    ];\n\n    /**\n     * Create a new collection instance if the value isn't one already.\n     *\n     * @template TMakeKey of array-key\n     * @template TMakeValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|null  $items\n     * @return static<TMakeKey, TMakeValue>\n     */\n    public static function make($items = [])\n    {\n        return new static($items);\n    }\n\n    /**\n     * Wrap the given value in a collection if applicable.\n     *\n     * @template TWrapValue\n     *\n     * @param  iterable<array-key, TWrapValue>|TWrapValue  $value\n     * @return static<array-key, TWrapValue>\n     */\n    public static function wrap($value)\n    {\n        return $value instanceof Enumerable\n            ? new static($value)\n            : new static(Arr::wrap($value));\n    }\n\n    /**\n     * Get the underlying items from the given collection if applicable.\n     *\n     * @template TUnwrapKey of array-key\n     * @template TUnwrapValue\n     *\n     * @param  array<TUnwrapKey, TUnwrapValue>|static<TUnwrapKey, TUnwrapValue>  $value\n     * @return array<TUnwrapKey, TUnwrapValue>\n     */\n    public static function unwrap($value)\n    {\n        return $value instanceof Enumerable ? $value->all() : $value;\n    }\n\n    /**\n     * Create a new instance with no items.\n     *\n     * @return static\n     */\n    public static function empty()\n    {\n        return new static([]);\n    }\n\n    /**\n     * Create a new collection by invoking the callback a given amount of times.\n     *\n     * @template TTimesValue\n     *\n     * @param  int  $number\n     * @param  (callable(int): TTimesValue)|null  $callback\n     * @return static<int, TTimesValue>\n     */\n    public static function times($number, ?callable $callback = null)\n    {\n        if ($number < 1) {\n            return new static;\n        }\n\n        return static::range(1, $number)\n            ->unless($callback == null)\n            ->map($callback);\n    }\n\n    /**\n     * Create a new collection by decoding a JSON string.\n     *\n     * @param  string  $json\n     * @param  int  $depth\n     * @param  int  $flags\n     * @return static<TKey, TValue>\n     */\n    public static function fromJson($json, $depth = 512, $flags = 0)\n    {\n        return new static(json_decode($json, true, $depth, $flags));\n    }\n\n    /**\n     * Get the average value of a given key.\n     *\n     * @param  (callable(TValue): float|int)|string|null  $callback\n     * @return float|int|null\n     */\n    public function avg($callback = null)\n    {\n        $callback = $this->valueRetriever($callback);\n\n        $reduced = $this->reduce(static function (&$reduce, $value) use ($callback) {\n            if (! is_null($resolved = $callback($value))) {\n                $reduce[0] += $resolved;\n                $reduce[1]++;\n            }\n\n            return $reduce;\n        }, [0, 0]);\n\n        return $reduced[1] ? $reduced[0] / $reduced[1] : null;\n    }\n\n    /**\n     * Alias for the \"avg\" method.\n     *\n     * @param  (callable(TValue): float|int)|string|null  $callback\n     * @return float|int|null\n     */\n    public function average($callback = null)\n    {\n        return $this->avg($callback);\n    }\n\n    /**\n     * Alias for the \"contains\" method.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function some($key, $operator = null, $value = null)\n    {\n        return $this->contains(...func_get_args());\n    }\n\n    /**\n     * Dump the given arguments and terminate execution.\n     *\n     * @param  mixed  ...$args\n     * @return never\n     */\n    public function dd(...$args)\n    {\n        dd($this->all(), ...$args);\n    }\n\n    /**\n     * Dump the items.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args)\n    {\n        dump($this->all(), ...$args);\n\n        return $this;\n    }\n\n    /**\n     * Execute a callback over each item.\n     *\n     * @param  callable(TValue, TKey): mixed  $callback\n     * @return $this\n     */\n    public function each(callable $callback)\n    {\n        foreach ($this as $key => $item) {\n            if ($callback($item, $key) === false) {\n                break;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Execute a callback over each nested chunk of items.\n     *\n     * @param  callable(...mixed): mixed  $callback\n     * @return static\n     */\n    public function eachSpread(callable $callback)\n    {\n        return $this->each(function ($chunk, $key) use ($callback) {\n            $chunk[] = $key;\n\n            return $callback(...$chunk);\n        });\n    }\n\n    /**\n     * Determine if all items pass the given truth test.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function every($key, $operator = null, $value = null)\n    {\n        if (func_num_args() === 1) {\n            $callback = $this->valueRetriever($key);\n\n            foreach ($this as $k => $v) {\n                if (! $callback($v, $k)) {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        return $this->every($this->operatorForWhere(...func_get_args()));\n    }\n\n    /**\n     * Get the first item by the given key value pair.\n     *\n     * @param  callable|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return TValue|null\n     */\n    public function firstWhere($key, $operator = null, $value = null)\n    {\n        return $this->first($this->operatorForWhere(...func_get_args()));\n    }\n\n    /**\n     * Determine if the collection contains multiple items, optionally matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasMany($key = null, $operator = null, $value = null): bool\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        return $this\n            ->unless($filter == null)\n            ->filter($filter)\n            ->take(2)\n            ->count() === 2;\n    }\n\n    /**\n     * Get a single key's value from the first matching item in the collection.\n     *\n     * @template TValueDefault\n     *\n     * @param  string  $key\n     * @param  TValueDefault|(\\Closure(): TValueDefault)  $default\n     * @return TValue|TValueDefault\n     */\n    public function value($key, $default = null)\n    {\n        $value = $this->first(function ($target) use ($key) {\n            return data_has($target, $key);\n        });\n\n        return data_get($value, $key, $default);\n    }\n\n    /**\n     * Ensure that every item in the collection is of the expected type.\n     *\n     * @template TEnsureOfType\n     *\n     * @param  class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>|'string'|'int'|'float'|'bool'|'array'|'null'  $type\n     * @return static<TKey, TEnsureOfType>\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function ensure($type)\n    {\n        $allowedTypes = is_array($type) ? $type : [$type];\n\n        return $this->each(function ($item, $index) use ($allowedTypes) {\n            $itemType = get_debug_type($item);\n\n            foreach ($allowedTypes as $allowedType) {\n                if ($itemType === $allowedType || $item instanceof $allowedType) {\n                    return true;\n                }\n            }\n\n            throw new UnexpectedValueException(\n                sprintf(\"Collection should only include [%s] items, but '%s' found at position %d.\", implode(', ', $allowedTypes), $itemType, $index)\n            );\n        });\n    }\n\n    /**\n     * Determine if the collection is not empty.\n     *\n     * @phpstan-assert-if-true TValue $this->first()\n     * @phpstan-assert-if-true TValue $this->last()\n     *\n     * @phpstan-assert-if-false null $this->first()\n     * @phpstan-assert-if-false null $this->last()\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Run a map over each nested chunk of items.\n     *\n     * @template TMapSpreadValue\n     *\n     * @param  callable(mixed...): TMapSpreadValue  $callback\n     * @return static<TKey, TMapSpreadValue>\n     */\n    public function mapSpread(callable $callback)\n    {\n        return $this->map(function ($chunk, $key) use ($callback) {\n            $chunk[] = $key;\n\n            return $callback(...$chunk);\n        });\n    }\n\n    /**\n     * Run a grouping map over the items.\n     *\n     * The callback should return an associative array with a single key/value pair.\n     *\n     * @template TMapToGroupsKey of array-key\n     * @template TMapToGroupsValue\n     *\n     * @param  callable(TValue, TKey): array<TMapToGroupsKey, TMapToGroupsValue>  $callback\n     * @return static<TMapToGroupsKey, static<int, TMapToGroupsValue>>\n     */\n    public function mapToGroups(callable $callback)\n    {\n        $groups = $this->mapToDictionary($callback);\n\n        return $groups->map($this->make(...));\n    }\n\n    /**\n     * Map a collection and flatten the result by a single level.\n     *\n     * @template TFlatMapKey of array-key\n     * @template TFlatMapValue\n     *\n     * @param  callable(TValue, TKey): (\\Illuminate\\Support\\Collection<TFlatMapKey, TFlatMapValue>|array<TFlatMapKey, TFlatMapValue>)  $callback\n     * @return static<TFlatMapKey, TFlatMapValue>\n     */\n    public function flatMap(callable $callback)\n    {\n        return $this->map($callback)->collapse();\n    }\n\n    /**\n     * Map the values into a new class.\n     *\n     * @template TMapIntoValue\n     *\n     * @param  class-string<TMapIntoValue>  $class\n     * @return static<TKey, TMapIntoValue>\n     */\n    public function mapInto($class)\n    {\n        if (is_subclass_of($class, BackedEnum::class)) {\n            return $this->map(fn ($value, $key) => $class::from($value));\n        }\n\n        return $this->map(fn ($value, $key) => new $class($value, $key));\n    }\n\n    /**\n     * Get the min value of a given key.\n     *\n     * @param  (callable(TValue):mixed)|string|null  $callback\n     * @return mixed\n     */\n    public function min($callback = null)\n    {\n        $callback = $this->valueRetriever($callback);\n\n        return $this->map(fn ($value) => $callback($value))\n            ->reject(fn ($value) => is_null($value))\n            ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result);\n    }\n\n    /**\n     * Get the max value of a given key.\n     *\n     * @param  (callable(TValue):mixed)|string|null  $callback\n     * @return mixed\n     */\n    public function max($callback = null)\n    {\n        $callback = $this->valueRetriever($callback);\n\n        return $this->reject(fn ($value) => is_null($value))->reduce(function ($result, $item) use ($callback) {\n            $value = $callback($item);\n\n            return is_null($result) || $value > $result ? $value : $result;\n        });\n    }\n\n    /**\n     * \"Paginate\" the collection by slicing it into a smaller collection.\n     *\n     * @param  int  $page\n     * @param  int  $perPage\n     * @return static\n     */\n    public function forPage($page, $perPage)\n    {\n        $offset = max(0, ($page - 1) * $perPage);\n\n        return $this->slice($offset, $perPage);\n    }\n\n    /**\n     * Partition the collection into two arrays using the given callback or key.\n     *\n     * @param  (callable(TValue, TKey): bool)|TValue|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return static<int<0, 1>, static<TKey, TValue>>\n     */\n    public function partition($key, $operator = null, $value = null)\n    {\n        $callback = func_num_args() === 1\n            ? $this->valueRetriever($key)\n            : $this->operatorForWhere(...func_get_args());\n\n        [$passed, $failed] = Arr::partition($this->getIterator(), $callback);\n\n        return new static([new static($passed), new static($failed)]);\n    }\n\n    /**\n     * Calculate the percentage of items that pass a given truth test.\n     *\n     * @param  (callable(TValue, TKey): bool)  $callback\n     * @param  int  $precision\n     * @return float|null\n     */\n    public function percentage(callable $callback, int $precision = 2)\n    {\n        if ($this->isEmpty()) {\n            return null;\n        }\n\n        return round(\n            $this->filter($callback)->count() / $this->count() * 100,\n            $precision\n        );\n    }\n\n    /**\n     * Get the sum of the given values.\n     *\n     * @template TReturnType\n     *\n     * @param  (callable(TValue): TReturnType)|string|null  $callback\n     * @return ($callback is callable ? TReturnType : mixed)\n     */\n    public function sum($callback = null)\n    {\n        $callback = is_null($callback)\n            ? $this->identity()\n            : $this->valueRetriever($callback);\n\n        return $this->reduce(fn ($result, $item) => $result + $callback($item), 0);\n    }\n\n    /**\n     * Apply the callback if the collection is empty.\n     *\n     * @template TWhenEmptyReturnType\n     *\n     * @param  (callable($this): TWhenEmptyReturnType)  $callback\n     * @param  (callable($this): TWhenEmptyReturnType)|null  $default\n     * @return $this|TWhenEmptyReturnType\n     */\n    public function whenEmpty(callable $callback, ?callable $default = null)\n    {\n        return $this->when($this->isEmpty(), $callback, $default);\n    }\n\n    /**\n     * Apply the callback if the collection is not empty.\n     *\n     * @template TWhenNotEmptyReturnType\n     *\n     * @param  callable($this): TWhenNotEmptyReturnType  $callback\n     * @param  (callable($this): TWhenNotEmptyReturnType)|null  $default\n     * @return $this|TWhenNotEmptyReturnType\n     */\n    public function whenNotEmpty(callable $callback, ?callable $default = null)\n    {\n        return $this->when($this->isNotEmpty(), $callback, $default);\n    }\n\n    /**\n     * Apply the callback unless the collection is empty.\n     *\n     * @template TUnlessEmptyReturnType\n     *\n     * @param  callable($this): TUnlessEmptyReturnType  $callback\n     * @param  (callable($this): TUnlessEmptyReturnType)|null  $default\n     * @return $this|TUnlessEmptyReturnType\n     */\n    public function unlessEmpty(callable $callback, ?callable $default = null)\n    {\n        return $this->whenNotEmpty($callback, $default);\n    }\n\n    /**\n     * Apply the callback unless the collection is not empty.\n     *\n     * @template TUnlessNotEmptyReturnType\n     *\n     * @param  callable($this): TUnlessNotEmptyReturnType  $callback\n     * @param  (callable($this): TUnlessNotEmptyReturnType)|null  $default\n     * @return $this|TUnlessNotEmptyReturnType\n     */\n    public function unlessNotEmpty(callable $callback, ?callable $default = null)\n    {\n        return $this->whenEmpty($callback, $default);\n    }\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  callable|string  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return static\n     */\n    public function where($key, $operator = null, $value = null)\n    {\n        return $this->filter($this->operatorForWhere(...func_get_args()));\n    }\n\n    /**\n     * Filter items where the value for the given key is null.\n     *\n     * @param  string|null  $key\n     * @return static\n     */\n    public function whereNull($key = null)\n    {\n        return $this->whereStrict($key, null);\n    }\n\n    /**\n     * Filter items where the value for the given key is not null.\n     *\n     * @param  string|null  $key\n     * @return static\n     */\n    public function whereNotNull($key = null)\n    {\n        return $this->where($key, '!==', null);\n    }\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return static\n     */\n    public function whereStrict($key, $value)\n    {\n        return $this->where($key, '===', $value);\n    }\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @param  bool  $strict\n     * @return static\n     */\n    public function whereIn($key, $values, $strict = false)\n    {\n        $values = $this->getArrayableItems($values);\n\n        return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict));\n    }\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereInStrict($key, $values)\n    {\n        return $this->whereIn($key, $values, true);\n    }\n\n    /**\n     * Filter items such that the value of the given key is between the given values.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereBetween($key, $values)\n    {\n        return $this->where($key, '>=', reset($values))->where($key, '<=', end($values));\n    }\n\n    /**\n     * Filter items such that the value of the given key is not between the given values.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereNotBetween($key, $values)\n    {\n        return $this->filter(\n            fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values)\n        );\n    }\n\n    /**\n     * Filter items by the given key value pair.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @param  bool  $strict\n     * @return static\n     */\n    public function whereNotIn($key, $values, $strict = false)\n    {\n        $values = $this->getArrayableItems($values);\n\n        return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict));\n    }\n\n    /**\n     * Filter items by the given key value pair using strict comparison.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|iterable  $values\n     * @return static\n     */\n    public function whereNotInStrict($key, $values)\n    {\n        return $this->whereNotIn($key, $values, true);\n    }\n\n    /**\n     * Filter the items, removing any items that don't match the given type(s).\n     *\n     * @template TWhereInstanceOf\n     *\n     * @param  class-string<TWhereInstanceOf>|array<array-key, class-string<TWhereInstanceOf>>  $type\n     * @return static<TKey, TWhereInstanceOf>\n     */\n    public function whereInstanceOf($type)\n    {\n        return $this->filter(function ($value) use ($type) {\n            if (is_array($type)) {\n                foreach ($type as $classType) {\n                    if ($value instanceof $classType) {\n                        return true;\n                    }\n                }\n\n                return false;\n            }\n\n            return $value instanceof $type;\n        });\n    }\n\n    /**\n     * Pass the collection to the given callback and return the result.\n     *\n     * @template TPipeReturnType\n     *\n     * @param  callable($this): TPipeReturnType  $callback\n     * @return TPipeReturnType\n     */\n    public function pipe(callable $callback)\n    {\n        return $callback($this);\n    }\n\n    /**\n     * Pass the collection into a new class.\n     *\n     * @template TPipeIntoValue\n     *\n     * @param  class-string<TPipeIntoValue>  $class\n     * @return TPipeIntoValue\n     */\n    public function pipeInto($class)\n    {\n        return new $class($this);\n    }\n\n    /**\n     * Pass the collection through a series of callable pipes and return the result.\n     *\n     * @param  array<callable>  $callbacks\n     * @return mixed\n     */\n    public function pipeThrough($callbacks)\n    {\n        return (new Collection($callbacks))->reduce(\n            fn ($carry, $callback) => $callback($carry),\n            $this,\n        );\n    }\n\n    /**\n     * Reduce the collection to a single value.\n     *\n     * @template TReduceInitial\n     * @template TReduceReturnType\n     *\n     * @param  callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType  $callback\n     * @param  TReduceInitial  $initial\n     * @return TReduceReturnType\n     */\n    public function reduce(callable $callback, $initial = null)\n    {\n        $result = $initial;\n\n        foreach ($this as $key => $value) {\n            $result = $callback($result, $value, $key);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Reduce the collection to multiple aggregate values.\n     *\n     * @param  callable  $callback\n     * @param  mixed  ...$initial\n     * @return array\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function reduceSpread(callable $callback, ...$initial)\n    {\n        $result = $initial;\n\n        foreach ($this as $key => $value) {\n            $result = call_user_func_array($callback, array_merge($result, [$value, $key]));\n\n            if (! is_array($result)) {\n                throw new UnexpectedValueException(sprintf(\n                    \"%s::reduceSpread expects reducer to return an array, but got a '%s' instead.\",\n                    class_basename(static::class), gettype($result)\n                ));\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Reduce an associative collection to a single value.\n     *\n     * @template TReduceWithKeysInitial\n     * @template TReduceWithKeysReturnType\n     *\n     * @param  callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType  $callback\n     * @param  TReduceWithKeysInitial  $initial\n     * @return TReduceWithKeysReturnType\n     */\n    public function reduceWithKeys(callable $callback, $initial = null)\n    {\n        return $this->reduce($callback, $initial);\n    }\n\n    /**\n     * Create a collection of all elements that do not pass a given truth test.\n     *\n     * @param  (callable(TValue, TKey): bool)|bool|TValue  $callback\n     * @return static\n     */\n    public function reject($callback = true)\n    {\n        $useAsCallable = $this->useAsCallable($callback);\n\n        return $this->filter(function ($value, $key) use ($callback, $useAsCallable) {\n            return $useAsCallable\n                ? ! $callback($value, $key)\n                : $value != $callback;\n        });\n    }\n\n    /**\n     * Pass the collection to the given callback and then return it.\n     *\n     * @param  callable($this): mixed  $callback\n     * @return $this\n     */\n    public function tap(callable $callback)\n    {\n        $callback($this);\n\n        return $this;\n    }\n\n    /**\n     * Return only unique items from the collection array.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @param  bool  $strict\n     * @return static\n     */\n    public function unique($key = null, $strict = false)\n    {\n        $callback = $this->valueRetriever($key);\n\n        $exists = [];\n\n        return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {\n            if (in_array($id = $callback($item, $key), $exists, $strict)) {\n                return true;\n            }\n\n            $exists[] = $id;\n        });\n    }\n\n    /**\n     * Return only unique items from the collection array using strict comparison.\n     *\n     * @param  (callable(TValue, TKey): mixed)|string|null  $key\n     * @return static\n     */\n    public function uniqueStrict($key = null)\n    {\n        return $this->unique($key, true);\n    }\n\n    /**\n     * Collect the values into a collection.\n     *\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    public function collect()\n    {\n        return new Collection($this->all());\n    }\n\n    /**\n     * Get the collection of items as a plain array.\n     *\n     * @return array<TKey, mixed>\n     */\n    public function toArray()\n    {\n        return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all();\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array<TKey, mixed>\n     */\n    public function jsonSerialize(): array\n    {\n        return array_map(function ($value) {\n            return match (true) {\n                $value instanceof JsonSerializable => $value->jsonSerialize(),\n                $value instanceof Jsonable => json_decode($value->toJson(), true),\n                $value instanceof Arrayable => $value->toArray(),\n                default => $value,\n            };\n        }, $this->all());\n    }\n\n    /**\n     * Get the collection of items as JSON.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Get the collection of items as pretty print formatted JSON.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n\n    /**\n     * Get a CachingIterator instance.\n     *\n     * @param  int  $flags\n     * @return \\CachingIterator\n     */\n    public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)\n    {\n        return new CachingIterator($this->getIterator(), $flags);\n    }\n\n    /**\n     * Convert the collection to its string representation.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->escapeWhenCastingToString\n            ? e($this->toJson())\n            : $this->toJson();\n    }\n\n    /**\n     * Indicate that the model's string representation should be escaped when __toString is invoked.\n     *\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function escapeWhenCastingToString($escape = true)\n    {\n        $this->escapeWhenCastingToString = $escape;\n\n        return $this;\n    }\n\n    /**\n     * Add a method to the list of proxied methods.\n     *\n     * @param  string  $method\n     * @return void\n     */\n    public static function proxy($method)\n    {\n        static::$proxies[] = $method;\n    }\n\n    /**\n     * Dynamically access collection proxies.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\Exception\n     */\n    public function __get($key)\n    {\n        if (! in_array($key, static::$proxies)) {\n            throw new Exception(\"Property [{$key}] does not exist on this collection instance.\");\n        }\n\n        return new HigherOrderCollectionProxy($this, $key);\n    }\n\n    /**\n     * Results array of items from Collection or Arrayable.\n     *\n     * @param  mixed  $items\n     * @return array<TKey, TValue>\n     */\n    protected function getArrayableItems($items)\n    {\n        return is_null($items) || is_scalar($items) || $items instanceof UnitEnum\n            ? Arr::wrap($items)\n            : Arr::from($items);\n    }\n\n    /**\n     * Get an operator checker callback.\n     *\n     * @param  callable|string  $key\n     * @param  string|null  $operator\n     * @param  mixed  $value\n     * @return \\Closure\n     */\n    protected function operatorForWhere($key, $operator = null, $value = null)\n    {\n        if ($this->useAsCallable($key)) {\n            return $key;\n        }\n\n        if (func_num_args() === 1) {\n            $value = true;\n\n            $operator = '=';\n        }\n\n        if (func_num_args() === 2) {\n            $value = $operator;\n\n            $operator = '=';\n        }\n\n        return function ($item) use ($key, $operator, $value) {\n            $retrieved = enum_value(data_get($item, $key));\n            $value = enum_value($value);\n\n            $strings = array_filter([$retrieved, $value], function ($value) {\n                return match (true) {\n                    is_string($value) => true,\n                    $value instanceof \\Stringable => true,\n                    default => false,\n                };\n            });\n\n            if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) {\n                return in_array($operator, ['!=', '<>', '!==']);\n            }\n\n            switch ($operator) {\n                default:\n                case '=':\n                case '==':  return $retrieved == $value;\n                case '!=':\n                case '<>':  return $retrieved != $value;\n                case '<':   return $retrieved < $value;\n                case '>':   return $retrieved > $value;\n                case '<=':  return $retrieved <= $value;\n                case '>=':  return $retrieved >= $value;\n                case '===': return $retrieved === $value;\n                case '!==': return $retrieved !== $value;\n                case '<=>': return $retrieved <=> $value;\n            }\n        };\n    }\n\n    /**\n     * Determine if the given value is callable, but not a string.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function useAsCallable($value)\n    {\n        return ! is_string($value) && is_callable($value);\n    }\n\n    /**\n     * Get a value retrieving callback.\n     *\n     * @param  callable|string|null  $value\n     * @return callable\n     */\n    protected function valueRetriever($value)\n    {\n        if ($this->useAsCallable($value)) {\n            return $value;\n        }\n\n        return fn ($item) => data_get($item, $value);\n    }\n\n    /**\n     * Make a function to check an item's equality.\n     *\n     * @param  mixed  $value\n     * @return \\Closure(mixed): bool\n     */\n    protected function equality($value)\n    {\n        return fn ($item) => $item === $value;\n    }\n\n    /**\n     * Make a function using another function, by negating its result.\n     *\n     * @param  \\Closure  $callback\n     * @return \\Closure\n     */\n    protected function negate(Closure $callback)\n    {\n        return fn (...$params) => ! $callback(...$params);\n    }\n\n    /**\n     * Make a function that returns what's passed to it.\n     *\n     * @return \\Closure(TValue): TValue\n     */\n    protected function identity()\n    {\n        return fn ($value) => $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/Traits/TransformsToResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResourceCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\nuse LogicException;\nuse ReflectionClass;\n\ntrait TransformsToResourceCollection\n{\n    /**\n     * Create a new resource collection instance for the given resource.\n     *\n     * @param  class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>|null  $resourceClass\n     * @return \\Illuminate\\Http\\Resources\\Json\\ResourceCollection\n     *\n     * @throws \\Throwable\n     */\n    public function toResourceCollection(?string $resourceClass = null): ResourceCollection\n    {\n        if ($resourceClass === null) {\n            return $this->guessResourceCollection();\n        }\n\n        return $resourceClass::collection($this);\n    }\n\n    /**\n     * Guess the resource collection for the items.\n     *\n     * @return \\Illuminate\\Http\\Resources\\Json\\ResourceCollection\n     *\n     * @throws \\Throwable\n     */\n    protected function guessResourceCollection(): ResourceCollection\n    {\n        if ($this->isEmpty()) {\n            return new ResourceCollection($this);\n        }\n\n        $model = $this->items[0] ?? null;\n\n        throw_unless(is_object($model), LogicException::class, 'Resource collection guesser expects the collection to contain objects.');\n\n        /** @var class-string<Model> $className */\n        $className = get_class($model);\n\n        throw_unless(method_exists($className, 'guessResourceName'), LogicException::class, sprintf('Expected class %s to implement guessResourceName method. Make sure the model uses the TransformsToResource trait.', $className));\n\n        $useResourceCollection = $this->resolveResourceCollectionFromAttribute($className);\n\n        if ($useResourceCollection !== null && class_exists($useResourceCollection)) {\n            return new $useResourceCollection($this);\n        }\n\n        $useResource = $this->resolveResourceFromAttribute($className);\n\n        if ($useResource !== null && class_exists($useResource)) {\n            return $useResource::collection($this);\n        }\n\n        $resourceClasses = $className::guessResourceName();\n\n        foreach ($resourceClasses as $resourceClass) {\n            $resourceCollection = $resourceClass.'Collection';\n\n            if (is_string($resourceCollection) && class_exists($resourceCollection)) {\n                return new $resourceCollection($this);\n            }\n        }\n\n        foreach ($resourceClasses as $resourceClass) {\n            if (is_string($resourceClass) && class_exists($resourceClass)) {\n                return $resourceClass::collection($this);\n            }\n        }\n\n        throw new LogicException(sprintf('Failed to find resource class for model [%s].', $className));\n    }\n\n    /**\n     * Get the resource class from the class attribute.\n     *\n     * @param  class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>  $class\n     * @return class-string<*>|null\n     */\n    protected function resolveResourceFromAttribute(string $class): ?string\n    {\n        if (! class_exists($class)) {\n            return null;\n        }\n\n        $attributes = (new ReflectionClass($class))->getAttributes(UseResource::class);\n\n        return $attributes !== []\n            ? $attributes[0]->newInstance()->class\n            : null;\n    }\n\n    /**\n     * Get the resource collection class from the class attribute.\n     *\n     * @param  class-string<\\Illuminate\\Http\\Resources\\Json\\ResourceCollection>  $class\n     * @return class-string<*>|null\n     */\n    protected function resolveResourceCollectionFromAttribute(string $class): ?string\n    {\n        if (! class_exists($class)) {\n            return null;\n        }\n\n        $attributes = (new ReflectionClass($class))->getAttributes(UseResourceCollection::class);\n\n        return $attributes !== []\n            ? $attributes[0]->newInstance()->class\n            : null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/composer.json",
    "content": "{\n    \"name\": \"illuminate/collections\",\n    \"description\": \"The Illuminate Collections package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/conditionable\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"symfony/polyfill-php84\": \"^1.33\",\n        \"symfony/polyfill-php85\": \"^1.33\"\n    },\n    \"suggest\": {\n        \"illuminate/http\": \"Required to convert collections to API resources (^13.0).\",\n        \"symfony/var-dumper\": \"Required to use the dump method (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Support\\\\\": \"\"\n        },\n        \"files\": [\n            \"functions.php\",\n            \"helpers.php\"\n        ]\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/functions.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nif (! function_exists('Illuminate\\Support\\enum_value')) {\n    /**\n     * Return a scalar value for the given value that might be an enum.\n     *\n     * @internal\n     *\n     * @template TValue\n     * @template TDefault\n     *\n     * @param  TValue  $value\n     * @param  TDefault|callable(TValue): TDefault  $default\n     * @return ($value is empty ? TDefault : mixed)\n     */\n    function enum_value($value, $default = null)\n    {\n        return match (true) {\n            $value instanceof \\BackedEnum => $value->value,\n            $value instanceof \\UnitEnum => $value->name,\n\n            default => $value ?? value($default),\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Collections/helpers.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nif (! function_exists('collect')) {\n    /**\n     * Create a collection from the given value.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $value\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    function collect($value = []): Collection\n    {\n        return new Collection($value);\n    }\n}\n\nif (! function_exists('data_fill')) {\n    /**\n     * Fill in data where it's missing.\n     *\n     * @param  mixed  $target\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    function data_fill(&$target, $key, $value)\n    {\n        return data_set($target, $key, $value, false);\n    }\n}\n\nif (! function_exists('data_has')) {\n    /**\n     * Determine if a key / property exists on an array or object using \"dot\" notation.\n     *\n     * @param  mixed  $target\n     * @param  string|array|int|null  $key\n     * @return bool\n     */\n    function data_has($target, $key): bool\n    {\n        if (is_null($key) || $key === []) {\n            return false;\n        }\n\n        $key = is_array($key) ? $key : explode('.', $key);\n\n        foreach ($key as $segment) {\n            if (Arr::accessible($target) && Arr::exists($target, $segment)) {\n                $target = $target[$segment];\n            } elseif (is_object($target) && property_exists($target, $segment)) {\n                $target = $target->{$segment};\n            } else {\n                return false;\n            }\n        }\n\n        return true;\n    }\n}\n\nif (! function_exists('data_get')) {\n    /**\n     * Get an item from an array or object using \"dot\" notation.\n     *\n     * @param  mixed  $target\n     * @param  string|array|int|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    function data_get($target, $key, $default = null)\n    {\n        if (is_null($key)) {\n            return $target;\n        }\n\n        $key = is_array($key) ? $key : explode('.', $key);\n\n        foreach ($key as $i => $segment) {\n            unset($key[$i]);\n\n            if (is_null($segment)) {\n                return $target;\n            }\n\n            if ($segment === '*') {\n                if ($target instanceof Collection) {\n                    $target = $target->all();\n                } elseif (! is_iterable($target)) {\n                    return value($default);\n                }\n\n                $result = [];\n\n                foreach ($target as $item) {\n                    $result[] = data_get($item, $key);\n                }\n\n                return in_array('*', $key) ? Arr::collapse($result) : $result;\n            }\n\n            $segment = match ($segment) {\n                '\\*' => '*',\n                '\\{first}' => '{first}',\n                '{first}' => array_key_first(Arr::from($target)),\n                '\\{last}' => '{last}',\n                '{last}' => array_key_last(Arr::from($target)),\n                default => $segment,\n            };\n\n            if (Arr::accessible($target) && Arr::exists($target, $segment)) {\n                $target = $target[$segment];\n            } elseif (is_object($target) && isset($target->{$segment})) {\n                $target = $target->{$segment};\n            } else {\n                return value($default);\n            }\n        }\n\n        return $target;\n    }\n}\n\nif (! function_exists('data_set')) {\n    /**\n     * Set an item on an array or object using dot notation.\n     *\n     * @param  mixed  $target\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @param  bool  $overwrite\n     * @return mixed\n     */\n    function data_set(&$target, $key, $value, $overwrite = true)\n    {\n        $segments = is_array($key) ? $key : explode('.', $key);\n\n        if (($segment = array_shift($segments)) === '*') {\n            if (! Arr::accessible($target)) {\n                $target = [];\n            }\n\n            if ($segments) {\n                foreach ($target as &$inner) {\n                    data_set($inner, $segments, $value, $overwrite);\n                }\n            } elseif ($overwrite) {\n                foreach ($target as &$inner) {\n                    $inner = $value;\n                }\n            }\n        } elseif (Arr::accessible($target)) {\n            if ($segments) {\n                if (! Arr::exists($target, $segment)) {\n                    $target[$segment] = [];\n                }\n\n                data_set($target[$segment], $segments, $value, $overwrite);\n            } elseif ($overwrite || ! Arr::exists($target, $segment)) {\n                $target[$segment] = $value;\n            }\n        } elseif (is_object($target)) {\n            if ($segments) {\n                if (! isset($target->{$segment})) {\n                    $target->{$segment} = [];\n                }\n\n                data_set($target->{$segment}, $segments, $value, $overwrite);\n            } elseif ($overwrite || ! isset($target->{$segment})) {\n                $target->{$segment} = $value;\n            }\n        } else {\n            $target = [];\n\n            if ($segments) {\n                data_set($target[$segment], $segments, $value, $overwrite);\n            } elseif ($overwrite) {\n                $target[$segment] = $value;\n            }\n        }\n\n        return $target;\n    }\n}\n\nif (! function_exists('data_forget')) {\n    /**\n     * Remove / unset an item from an array or object using \"dot\" notation.\n     *\n     * @param  mixed  $target\n     * @param  string|array|int|null  $key\n     * @return mixed\n     */\n    function data_forget(&$target, $key)\n    {\n        $segments = is_array($key) ? $key : explode('.', $key);\n\n        if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) {\n            if ($segments) {\n                foreach ($target as &$inner) {\n                    data_forget($inner, $segments);\n                }\n            }\n        } elseif (Arr::accessible($target)) {\n            if ($segments && Arr::exists($target, $segment)) {\n                data_forget($target[$segment], $segments);\n            } else {\n                Arr::forget($target, $segment);\n            }\n        } elseif (is_object($target)) {\n            if ($segments && isset($target->{$segment})) {\n                data_forget($target->{$segment}, $segments);\n            } elseif (isset($target->{$segment})) {\n                unset($target->{$segment});\n            }\n        }\n\n        return $target;\n    }\n}\n\nif (! function_exists('head')) {\n    /**\n     * Get the first element of an array. Useful for method chaining.\n     *\n     * @param  array  $array\n     * @return mixed\n     */\n    function head($array)\n    {\n        return empty($array) ? false : array_first($array);\n    }\n}\n\nif (! function_exists('last')) {\n    /**\n     * Get the last element from an array.\n     *\n     * @param  array  $array\n     * @return mixed\n     */\n    function last($array)\n    {\n        return empty($array) ? false : array_last($array);\n    }\n}\n\nif (! function_exists('value')) {\n    /**\n     * Return the default value of the given value.\n     *\n     * @template TValue\n     * @template TArgs\n     *\n     * @param  TValue|\\Closure(TArgs): TValue  $value\n     * @param  TArgs  ...$args\n     * @return TValue\n     */\n    function value($value, ...$args)\n    {\n        return $value instanceof Closure ? $value(...$args) : $value;\n    }\n}\n\nif (! function_exists('when')) {\n    /**\n     * Return a value if the given condition is true.\n     *\n     * @template TValue\n     * @template TArgs\n     * @template TDefault\n     *\n     * @param  mixed  $condition\n     * @param  TValue|\\Closure(TArgs): TValue  $value\n     * @param  TDefault|\\Closure(): TDefault  $default\n     * @return ($condition is true|positive-int|non-falsy-string|non-empty-array ? TValue : ($condition is callable ? TValue|TDefault : TDefault))\n     */\n    function when($condition, $value, $default = null)\n    {\n        $condition = $condition instanceof Closure ? $condition() : $condition;\n\n        if ($condition) {\n            return value($value, $condition);\n        }\n\n        return value($default, $condition);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Concurrency/ConcurrencyManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency;\n\nuse Illuminate\\Process\\Factory as ProcessFactory;\nuse Illuminate\\Support\\MultipleInstanceManager;\nuse RuntimeException;\nuse Spatie\\Fork\\Fork;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Concurrency\\Driver\n */\nclass ConcurrencyManager extends MultipleInstanceManager\n{\n    /**\n     * Get a driver instance by name.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function driver($name = null)\n    {\n        return $this->instance($name);\n    }\n\n    /**\n     * Create an instance of the process concurrency driver.\n     *\n     * @return \\Illuminate\\Concurrency\\ProcessDriver\n     */\n    public function createProcessDriver()\n    {\n        return new ProcessDriver($this->app->make(ProcessFactory::class));\n    }\n\n    /**\n     * Create an instance of the fork concurrency driver.\n     *\n     * @return \\Illuminate\\Concurrency\\ForkDriver\n     *\n     * @throws \\RuntimeException\n     */\n    public function createForkDriver()\n    {\n        if (! $this->app->runningInConsole()) {\n            throw new RuntimeException('Due to PHP limitations, the fork driver may not be used within web requests.');\n        }\n\n        if (! class_exists(Fork::class)) {\n            throw new RuntimeException('Please install the \"spatie/fork\" Composer package in order to utilize the \"fork\" driver.');\n        }\n\n        return new ForkDriver;\n    }\n\n    /**\n     * Create an instance of the sync concurrency driver.\n     *\n     * @return \\Illuminate\\Concurrency\\SyncDriver\n     */\n    public function createSyncDriver()\n    {\n        return new SyncDriver;\n    }\n\n    /**\n     * Get the default instance name.\n     *\n     * @return string\n     */\n    public function getDefaultInstance()\n    {\n        return $this->app['config']['concurrency.default']\n            ?? $this->app['config']['concurrency.driver']\n            ?? 'process';\n    }\n\n    /**\n     * Set the default instance name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultInstance($name)\n    {\n        $this->app['config']['concurrency.default'] = $name;\n        $this->app['config']['concurrency.driver'] = $name;\n    }\n\n    /**\n     * Get the instance specific configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    public function getInstanceConfig($name)\n    {\n        return $this->app['config']->get(\n            'concurrency.driver.'.$name, ['driver' => $name],\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/ConcurrencyServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ConcurrencyServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton(ConcurrencyManager::class, function ($app) {\n            return new ConcurrencyManager($app);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            ConcurrencyManager::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/Console/InvokeSerializedClosureCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency\\Console;\n\nuse Illuminate\\Console\\Command;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Throwable;\n\n#[AsCommand(name: 'invoke-serialized-closure')]\nclass InvokeSerializedClosureCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'invoke-serialized-closure {code? : The serialized closure}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Invoke the given serialized closure';\n\n    /**\n     * Indicates whether the command should be shown in the Artisan command list.\n     *\n     * @var bool\n     */\n    protected $hidden = true;\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function handle()\n    {\n        try {\n            $this->output->write(json_encode([\n                'successful' => true,\n                'result' => serialize($this->laravel->call(match (true) {\n                    ! is_null($this->argument('code')) => unserialize($this->argument('code')),\n                    isset($_SERVER['LARAVEL_INVOKABLE_CLOSURE']) => unserialize(\n                        base64_decode($_SERVER['LARAVEL_INVOKABLE_CLOSURE'])\n                    ),\n                    default => fn () => null,\n                })),\n            ]));\n        } catch (Throwable $e) {\n            report($e);\n\n            $reflection = new ReflectionClass($e);\n            $constructor = $reflection->getConstructor();\n            $parameters = [];\n\n            if ($constructor) {\n                $declaringClass = $constructor->getDeclaringClass()->getName();\n\n                if ($declaringClass === $reflection->getName()) {\n                    foreach ($constructor->getParameters() as $parameter) {\n                        $parameters[$parameter->name] = $e->{$parameter->name} ?? null;\n                    }\n                }\n            }\n\n            $this->output->write(json_encode([\n                'successful' => false,\n                'exception' => get_class($e),\n                'message' => $e->getMessage(),\n                'file' => $e->getFile(),\n                'line' => $e->getLine(),\n                'parameters' => $parameters,\n            ]));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/ForkDriver.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency;\n\nuse Closure;\nuse Illuminate\\Contracts\\Concurrency\\Driver;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\nuse Spatie\\Fork\\Fork;\n\nuse function Illuminate\\Support\\defer;\n\nclass ForkDriver implements Driver\n{\n    /**\n     * Run the given tasks concurrently and return an array containing the results.\n     */\n    public function run(Closure|array $tasks): array\n    {\n        $tasks = Arr::wrap($tasks);\n\n        $keys = array_keys($tasks);\n        $values = array_values($tasks);\n\n        /** @phpstan-ignore class.notFound */\n        $results = Fork::new()->run(...$values);\n\n        ksort($results);\n\n        return array_combine($keys, $results);\n    }\n\n    /**\n     * Start the given tasks in the background after the current task has finished.\n     */\n    public function defer(Closure|array $tasks): DeferredCallback\n    {\n        return defer(fn () => $this->run($tasks));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Concurrency/ProcessDriver.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Contracts\\Concurrency\\Driver;\nuse Illuminate\\Process\\Factory as ProcessFactory;\nuse Illuminate\\Process\\Pool;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\nuse Laravel\\SerializableClosure\\SerializableClosure;\n\nuse function Illuminate\\Support\\defer;\n\nclass ProcessDriver implements Driver\n{\n    /**\n     * Create a new process based concurrency driver.\n     */\n    public function __construct(protected ProcessFactory $processFactory)\n    {\n        //\n    }\n\n    /**\n     * Run the given tasks concurrently and return an array containing the results.\n     */\n    public function run(Closure|array $tasks): array\n    {\n        $command = Application::formatCommandString('invoke-serialized-closure');\n\n        $results = $this->processFactory->pool(function (Pool $pool) use ($tasks, $command) {\n            foreach (Arr::wrap($tasks) as $key => $task) {\n                $pool->as($key)->path(base_path())->env([\n                    'LARAVEL_INVOKABLE_CLOSURE' => base64_encode(\n                        serialize(new SerializableClosure($task))\n                    ),\n                ])->command($command);\n            }\n        })->start()->wait();\n\n        return $results->collect()->mapWithKeys(function ($result, $key) {\n            if ($result->failed()) {\n                throw new Exception('Concurrent process failed with exit code ['.$result->exitCode().']. Message: '.$result->errorOutput());\n            }\n\n            $output = $result->output();\n\n            if (($pos = strpos($output, \"\\x1f\\x8b\")) !== false) {\n                $output = substr($output, 0, $pos);\n            }\n\n            $result = json_decode($output, true);\n\n            if (! $result['successful']) {\n                throw new $result['exception'](\n                    ...(! empty(array_filter($result['parameters']))\n                        ? $result['parameters']\n                        : [$result['message']])\n                );\n            }\n\n            return [$key => unserialize($result['result'])];\n        })->all();\n    }\n\n    /**\n     * Start the given tasks in the background after the current task has finished.\n     */\n    public function defer(Closure|array $tasks): DeferredCallback\n    {\n        $command = Application::formatCommandString('invoke-serialized-closure');\n\n        return defer(function () use ($tasks, $command) {\n            foreach (Arr::wrap($tasks) as $task) {\n                $this->processFactory->path(base_path())->env([\n                    'LARAVEL_INVOKABLE_CLOSURE' => base64_encode(\n                        serialize(new SerializableClosure($task))\n                    ),\n                ])->run($command.' 2>&1 &');\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/SyncDriver.php",
    "content": "<?php\n\nnamespace Illuminate\\Concurrency;\n\nuse Closure;\nuse Illuminate\\Contracts\\Concurrency\\Driver;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\n\nuse function Illuminate\\Support\\defer;\n\nclass SyncDriver implements Driver\n{\n    /**\n     * Run the given tasks concurrently and return an array containing the results.\n     */\n    public function run(Closure|array $tasks): array\n    {\n        return Collection::wrap($tasks)->map(\n            fn ($task) => $task()\n        )->all();\n    }\n\n    /**\n     * Start the given tasks in the background after the current task has finished.\n     */\n    public function defer(Closure|array $tasks): DeferredCallback\n    {\n        return defer(fn () => Collection::wrap($tasks)->each(fn ($task) => $task()));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Concurrency/composer.json",
    "content": "{\n    \"name\": \"illuminate/concurrency\",\n    \"description\": \"The Illuminate Concurrency package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/console\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/process\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"laravel/serializable-closure\": \"^2.0.10\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Concurrency\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Conditionable/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Conditionable/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Conditionable/HigherOrderWhenProxy.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nclass HigherOrderWhenProxy\n{\n    /**\n     * The target being conditionally operated on.\n     *\n     * @var mixed\n     */\n    protected $target;\n\n    /**\n     * The condition for proxying.\n     *\n     * @var bool\n     */\n    protected $condition;\n\n    /**\n     * Indicates whether the proxy has a condition.\n     *\n     * @var bool\n     */\n    protected $hasCondition = false;\n\n    /**\n     * Determine whether the condition should be negated.\n     *\n     * @var bool\n     */\n    protected $negateConditionOnCapture;\n\n    /**\n     * Create a new proxy instance.\n     *\n     * @param  mixed  $target\n     */\n    public function __construct($target)\n    {\n        $this->target = $target;\n    }\n\n    /**\n     * Set the condition on the proxy.\n     *\n     * @param  bool  $condition\n     * @return $this\n     */\n    public function condition($condition)\n    {\n        [$this->condition, $this->hasCondition] = [$condition, true];\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the condition should be negated.\n     *\n     * @return $this\n     */\n    public function negateConditionOnCapture()\n    {\n        $this->negateConditionOnCapture = true;\n\n        return $this;\n    }\n\n    /**\n     * Proxy accessing an attribute onto the target.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        if (! $this->hasCondition) {\n            $condition = $this->target->{$key};\n\n            return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);\n        }\n\n        return $this->condition\n            ? $this->target->{$key}\n            : $this->target;\n    }\n\n    /**\n     * Proxy a method call on the target.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (! $this->hasCondition) {\n            $condition = $this->target->{$method}(...$parameters);\n\n            return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);\n        }\n\n        return $this->condition\n            ? $this->target->{$method}(...$parameters)\n            : $this->target;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Conditionable/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Conditionable/Traits/Conditionable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Closure;\nuse Illuminate\\Support\\HigherOrderWhenProxy;\n\ntrait Conditionable\n{\n    /**\n     * Apply the callback if the given \"value\" is (or resolves to) truthy.\n     *\n     * @template TWhenParameter\n     * @template TWhenReturnType\n     *\n     * @param  (\\Closure($this): TWhenParameter)|TWhenParameter|null  $value\n     * @param  (callable($this, TWhenParameter): TWhenReturnType)|null  $callback\n     * @param  (callable($this, TWhenParameter): TWhenReturnType)|null  $default\n     * @return $this|TWhenReturnType\n     */\n    public function when($value = null, ?callable $callback = null, ?callable $default = null)\n    {\n        $value = $value instanceof Closure ? $value($this) : $value;\n\n        if (func_num_args() === 0) {\n            return new HigherOrderWhenProxy($this);\n        }\n\n        if (func_num_args() === 1) {\n            return (new HigherOrderWhenProxy($this))->condition($value);\n        }\n\n        if ($value) {\n            return $callback($this, $value) ?? $this;\n        } elseif ($default) {\n            return $default($this, $value) ?? $this;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Apply the callback if the given \"value\" is (or resolves to) falsy.\n     *\n     * @template TUnlessParameter\n     * @template TUnlessReturnType\n     *\n     * @param  (\\Closure($this): TUnlessParameter)|TUnlessParameter|null  $value\n     * @param  (callable($this, TUnlessParameter): TUnlessReturnType)|null  $callback\n     * @param  (callable($this, TUnlessParameter): TUnlessReturnType)|null  $default\n     * @return $this|TUnlessReturnType\n     */\n    public function unless($value = null, ?callable $callback = null, ?callable $default = null)\n    {\n        $value = $value instanceof Closure ? $value($this) : $value;\n\n        if (func_num_args() === 0) {\n            return (new HigherOrderWhenProxy($this))->negateConditionOnCapture();\n        }\n\n        if (func_num_args() === 1) {\n            return (new HigherOrderWhenProxy($this))->condition(! $value);\n        }\n\n        if (! $value) {\n            return $callback($this, $value) ?? $this;\n        } elseif ($default) {\n            return $default($this, $value) ?? $this;\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Conditionable/composer.json",
    "content": "{\n    \"name\": \"illuminate/conditionable\",\n    \"description\": \"The Illuminate Conditionable package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Support\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Config/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Config/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Config/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Config/Repository.php",
    "content": "<?php\n\nnamespace Illuminate\\Config;\n\nuse ArrayAccess;\nuse Illuminate\\Contracts\\Config\\Repository as ConfigContract;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\nclass Repository implements ArrayAccess, ConfigContract\n{\n    use Macroable;\n\n    /**\n     * All of the configuration items.\n     *\n     * @var array<string,mixed>\n     */\n    protected $items = [];\n\n    /**\n     * Create a new configuration repository.\n     *\n     * @param  array  $items\n     */\n    public function __construct(array $items = [])\n    {\n        $this->items = $items;\n    }\n\n    /**\n     * Determine if the given configuration value exists.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        return Arr::has($this->items, $key);\n    }\n\n    /**\n     * Get the specified configuration value.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null)\n    {\n        if (is_array($key)) {\n            return $this->getMany($key);\n        }\n\n        return Arr::get($this->items, $key, $default);\n    }\n\n    /**\n     * Get many configuration values.\n     *\n     * @param  array<string|int,mixed>  $keys\n     * @return array<string,mixed>\n     */\n    public function getMany($keys)\n    {\n        $config = [];\n\n        foreach ($keys as $key => $default) {\n            if (is_numeric($key)) {\n                [$key, $default] = [$default, null];\n            }\n\n            $config[$key] = Arr::get($this->items, $key, $default);\n        }\n\n        return $config;\n    }\n\n    /**\n     * Get the specified string configuration value.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(string|null))|string|null  $default\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function string(string $key, $default = null): string\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_string($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration value for key [%s] must be a string, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the specified integer configuration value.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(int|null))|int|null  $default\n     * @return int\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function integer(string $key, $default = null): int\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_int($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration value for key [%s] must be an integer, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the specified float configuration value.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(float|null))|float|null  $default\n     * @return float\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function float(string $key, $default = null): float\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_float($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration value for key [%s] must be a float, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the specified boolean configuration value.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(bool|null))|bool|null  $default\n     * @return bool\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function boolean(string $key, $default = null): bool\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_bool($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration value for key [%s] must be a boolean, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the specified array configuration value.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(array<array-key, mixed>|null))|array<array-key, mixed>|null  $default\n     * @return array<array-key, mixed>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function array(string $key, $default = null): array\n    {\n        $value = $this->get($key, $default);\n\n        if (! is_array($value)) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration value for key [%s] must be an array, %s given.', $key, gettype($value))\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the specified array configuration value as a collection.\n     *\n     * @param  string  $key\n     * @param  (\\Closure():(array<array-key, mixed>|null))|array<array-key, mixed>|null  $default\n     * @return Collection<array-key, mixed>\n     */\n    public function collection(string $key, $default = null): Collection\n    {\n        return new Collection($this->array($key, $default));\n    }\n\n    /**\n     * Set a given configuration value.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function set($key, $value = null)\n    {\n        $keys = is_array($key) ? $key : [$key => $value];\n\n        foreach ($keys as $key => $value) {\n            Arr::set($this->items, $key, $value);\n        }\n    }\n\n    /**\n     * Prepend a value onto an array configuration value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function prepend($key, $value)\n    {\n        $array = $this->get($key, []);\n\n        array_unshift($array, $value);\n\n        $this->set($key, $array);\n    }\n\n    /**\n     * Push a value onto an array configuration value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function push($key, $value)\n    {\n        $array = $this->get($key, []);\n\n        $array[] = $value;\n\n        $this->set($key, $array);\n    }\n\n    /**\n     * Get all of the configuration items for the application.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->items;\n    }\n\n    /**\n     * Determine if the given configuration option exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return $this->has($offset);\n    }\n\n    /**\n     * Get a configuration option.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->get($offset);\n    }\n\n    /**\n     * Set a configuration option.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->set($offset, $value);\n    }\n\n    /**\n     * Unset a configuration option.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        $this->set($offset, null);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Config/composer.json",
    "content": "{\n    \"name\": \"illuminate/config\",\n    \"description\": \"The Illuminate Config package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Config\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Console/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Console/Application.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Events\\ArtisanStarting;\nuse Illuminate\\Contracts\\Console\\Application as ApplicationContract;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\ProcessUtils;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Application as SymfonyApplication;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Command\\Command as SymfonyCommand;\nuse Symfony\\Component\\Console\\Exception\\CommandNotFoundException;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Input\\InputDefinition;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Input\\StringInput;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nuse function Illuminate\\Support\\artisan_binary;\nuse function Illuminate\\Support\\php_binary;\n\nclass Application extends SymfonyApplication implements ApplicationContract\n{\n    /**\n     * The Laravel application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $laravel;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The output from the previous command.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\BufferedOutput\n     */\n    protected $lastOutput;\n\n    /**\n     * The console application bootstrappers.\n     *\n     * @var array<array-key, \\Closure($this): void>\n     */\n    protected static $bootstrappers = [];\n\n    /**\n     * A map of command names to classes.\n     *\n     * @var array<string, \\Illuminate\\Console\\Command|string>\n     */\n    protected $commandMap = [];\n\n    /**\n     * Create a new Artisan console application.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $laravel\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @param  string  $version\n     */\n    public function __construct(Container $laravel, Dispatcher $events, $version)\n    {\n        parent::__construct('Laravel Framework', $version);\n\n        $this->laravel = $laravel;\n        $this->events = $events;\n        $this->setAutoExit(false);\n        $this->setCatchExceptions(false);\n\n        $this->events->dispatch(new ArtisanStarting($this));\n\n        $this->bootstrap();\n    }\n\n    /**\n     * Determine the proper PHP executable.\n     *\n     * @return string\n     */\n    public static function phpBinary()\n    {\n        return ProcessUtils::escapeArgument(php_binary());\n    }\n\n    /**\n     * Determine the proper Artisan executable.\n     *\n     * @return string\n     */\n    public static function artisanBinary()\n    {\n        return ProcessUtils::escapeArgument(artisan_binary());\n    }\n\n    /**\n     * Format the given command as a fully-qualified executable command.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    public static function formatCommandString($string)\n    {\n        return sprintf('%s %s %s', static::phpBinary(), static::artisanBinary(), $string);\n    }\n\n    /**\n     * Register a console \"starting\" bootstrapper.\n     *\n     * @param  \\Closure($this): void  $callback\n     * @return void\n     */\n    public static function starting(Closure $callback)\n    {\n        static::$bootstrappers[] = $callback;\n    }\n\n    /**\n     * Bootstrap the console application.\n     *\n     * @return void\n     */\n    protected function bootstrap()\n    {\n        foreach (static::$bootstrappers as $bootstrapper) {\n            $bootstrapper($this);\n        }\n    }\n\n    /**\n     * Clear the console application bootstrappers.\n     *\n     * @return void\n     */\n    public static function forgetBootstrappers()\n    {\n        static::$bootstrappers = [];\n    }\n\n    /**\n     * Run an Artisan console command by name.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $parameters\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $outputBuffer\n     * @return int\n     *\n     * @throws \\Symfony\\Component\\Console\\Exception\\CommandNotFoundException\n     */\n    public function call($command, array $parameters = [], $outputBuffer = null)\n    {\n        [$command, $input] = $this->parseCommand($command, $parameters);\n\n        if (! $this->has($command)) {\n            throw new CommandNotFoundException(sprintf('The command \"%s\" does not exist.', $command));\n        }\n\n        return $this->run(\n            $input, $this->lastOutput = $outputBuffer ?: new BufferedOutput\n        );\n    }\n\n    /**\n     * Parse the incoming Artisan command and its input.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $parameters\n     * @return array<string, \\Symfony\\Component\\Console\\Input\\ArrayInput>\n     */\n    protected function parseCommand($command, $parameters)\n    {\n        if (is_subclass_of($command, SymfonyCommand::class)) {\n            $callingClass = true;\n\n            if (is_object($command)) {\n                $command = get_class($command);\n            }\n\n            $command = $this->laravel->make($command)->getName();\n        }\n\n        if (! isset($callingClass) && empty($parameters)) {\n            $command = $this->getCommandName($input = new StringInput($command));\n        } else {\n            array_unshift($parameters, $command);\n\n            $input = new ArrayInput($parameters);\n        }\n\n        return [$command, $input];\n    }\n\n    /**\n     * Get the output for the last run command.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        return $this->lastOutput && method_exists($this->lastOutput, 'fetch')\n            ? $this->lastOutput->fetch()\n            : '';\n    }\n\n    /**\n     * Alias for addCommand() since Symfony's add() method was deprecated.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command|null\n     */\n    public function add(SymfonyCommand $command): ?SymfonyCommand\n    {\n        return $this->addCommand($command);\n    }\n\n    /**\n     * Add a command to the console.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|callable  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command|null\n     */\n    public function addCommand(SymfonyCommand|callable $command): ?SymfonyCommand\n    {\n        if ($command instanceof Command) {\n            $command->setLaravel($this->laravel);\n        }\n\n        return $this->addToParent($command);\n    }\n\n    /**\n     * Add the command to the parent instance.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|callable  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command\n     */\n    protected function addToParent(SymfonyCommand|callable $command)\n    {\n        return parent::addCommand($command);\n    }\n\n    /**\n     * Add a command, resolving through the application.\n     *\n     * @param  \\Illuminate\\Console\\Command|string  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command|null\n     */\n    public function resolve($command)\n    {\n        if (is_subclass_of($command, SymfonyCommand::class)) {\n            $attribute = (new ReflectionClass($command))->getAttributes(AsCommand::class);\n\n            $commandName = ! empty($attribute) ? $attribute[0]->newInstance()->name : null;\n\n            if (! is_null($commandName)) {\n                foreach (explode('|', $commandName) as $name) {\n                    $this->commandMap[$name] = $command;\n                }\n\n                return null;\n            }\n        }\n\n        if ($command instanceof Command) {\n            return $this->addCommand($command);\n        }\n\n        return $this->addCommand($this->laravel->make($command));\n    }\n\n    /**\n     * Resolve an array of commands through the application.\n     *\n     * @param  mixed  $commands\n     * @return $this\n     */\n    public function resolveCommands($commands)\n    {\n        $commands = is_array($commands) ? $commands : func_get_args();\n\n        foreach ($commands as $command) {\n            $this->resolve($command);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the container command loader for lazy resolution.\n     *\n     * @return $this\n     */\n    public function setContainerCommandLoader()\n    {\n        $this->setCommandLoader(new ContainerCommandLoader($this->laravel, $this->commandMap));\n\n        return $this;\n    }\n\n    /**\n     * Get the default input definition for the application.\n     *\n     * This is used to add the --env option to every available command.\n     *\n     * @return \\Symfony\\Component\\Console\\Input\\InputDefinition\n     */\n    #[\\Override]\n    protected function getDefaultInputDefinition(): InputDefinition\n    {\n        return tap(parent::getDefaultInputDefinition(), function ($definition) {\n            $definition->addOption($this->getEnvironmentOption());\n        });\n    }\n\n    /**\n     * Get the global environment option for the definition.\n     *\n     * @return \\Symfony\\Component\\Console\\Input\\InputOption\n     */\n    protected function getEnvironmentOption()\n    {\n        $message = 'The environment the command should run under';\n\n        return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);\n    }\n\n    /**\n     * Get the Laravel application instance.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getLaravel()\n    {\n        return $this->laravel;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Attributes/Description.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Description\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $description\n     */\n    public function __construct(public string $description)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Attributes/Help.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Help\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $help\n     */\n    public function __construct(public string $help)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Attributes/Hidden.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Hidden\n{\n    /**\n     * Create a new attribute instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Attributes/Signature.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Signature\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $signature\n     * @param  string[]|null  $aliases\n     */\n    public function __construct(public string $signature, public ?array $aliases = null)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Attributes/Usage.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass Usage\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $usage\n     */\n    public function __construct(public string $usage)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/BufferedConsoleOutput.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\n\nclass BufferedConsoleOutput extends ConsoleOutput\n{\n    /**\n     * The current buffer.\n     *\n     * @var string\n     */\n    protected $buffer = '';\n\n    /**\n     * Empties the buffer and returns its content.\n     *\n     * @return string\n     */\n    public function fetch()\n    {\n        return tap($this->buffer, function () {\n            $this->buffer = '';\n        });\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    protected function doWrite(string $message, bool $newline): void\n    {\n        $this->buffer .= $message;\n\n        if ($newline) {\n            $this->buffer .= \\PHP_EOL;\n        }\n\n        parent::doWrite($message, $newline);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/CacheCommandMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Cache\\DynamoDbStore;\nuse Illuminate\\Contracts\\Cache\\Factory as Cache;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass CacheCommandMutex implements CommandMutex\n{\n    use InteractsWithTime;\n\n    /**\n     * The cache factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    public $cache;\n\n    /**\n     * The cache store that should be used.\n     *\n     * @var string|null\n     */\n    public $store = null;\n\n    /**\n     * Create a new command mutex.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Factory  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        $this->cache = $cache;\n    }\n\n    /**\n     * Attempt to obtain a command mutex for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function create($command)\n    {\n        $store = $this->cache->store($this->store);\n\n        $expiresAt = method_exists($command, 'isolationLockExpiresAt')\n            ? $command->isolationLockExpiresAt()\n            : CarbonInterval::hour();\n\n        if ($this->shouldUseLocks($store->getStore())) {\n            return $store->getStore()->lock(\n                $this->commandMutexName($command),\n                $this->secondsUntil($expiresAt)\n            )->get();\n        }\n\n        return $store->add($this->commandMutexName($command), true, $expiresAt);\n    }\n\n    /**\n     * Determine if a command mutex exists for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function exists($command)\n    {\n        $store = $this->cache->store($this->store);\n\n        if ($this->shouldUseLocks($store->getStore())) {\n            $lock = $store->getStore()->lock($this->commandMutexName($command));\n\n            return tap(! $lock->get(), function ($exists) use ($lock) {\n                if ($exists) {\n                    $lock->release();\n                }\n            });\n        }\n\n        return $this->cache->store($this->store)->has($this->commandMutexName($command));\n    }\n\n    /**\n     * Release the mutex for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function forget($command)\n    {\n        $store = $this->cache->store($this->store);\n\n        if ($this->shouldUseLocks($store->getStore())) {\n            return $store->getStore()->lock($this->commandMutexName($command))->forceRelease();\n        }\n\n        return $this->cache->store($this->store)->forget($this->commandMutexName($command));\n    }\n\n    /**\n     * Get the isolatable command mutex name.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return string\n     */\n    protected function commandMutexName($command)\n    {\n        $baseName = 'framework'.DIRECTORY_SEPARATOR.'command-'.$command->getName();\n\n        return method_exists($command, 'isolatableId')\n            ? $baseName.'-'.$command->isolatableId()\n            : $baseName;\n    }\n\n    /**\n     * Specify the cache store that should be used.\n     *\n     * @param  string|null  $store\n     * @return $this\n     */\n    public function useStore($store)\n    {\n        $this->store = $store;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given store should use locks for command mutexes.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @return bool\n     */\n    protected function shouldUseLocks($store)\n    {\n        return $store instanceof LockProvider && ! $store instanceof DynamoDbStore;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Command.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Illuminate\\Console\\Attributes\\Description;\nuse Illuminate\\Console\\Attributes\\Help;\nuse Illuminate\\Console\\Attributes\\Hidden;\nuse Illuminate\\Console\\Attributes\\Signature;\nuse Illuminate\\Console\\Attributes\\Usage;\nuse Illuminate\\Console\\View\\Components\\Factory;\nuse Illuminate\\Contracts\\Console\\Isolatable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Command\\Command as SymfonyCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Throwable;\n\nclass Command extends SymfonyCommand\n{\n    use Concerns\\CallsCommands,\n        Concerns\\ConfiguresPrompts,\n        Concerns\\HasParameters,\n        Concerns\\InteractsWithIO,\n        Concerns\\InteractsWithSignals,\n        Concerns\\PromptsForMissingInput,\n        Macroable;\n\n    /**\n     * The Laravel application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $laravel;\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = '';\n\n    /**\n     * The console command help text.\n     *\n     * @var string\n     */\n    protected $help = '';\n\n    /**\n     * Indicates whether the command should be shown in the Artisan command list.\n     *\n     * @var bool\n     */\n    protected $hidden = false;\n\n    /**\n     * Indicates whether only one instance of the command can run at any given time.\n     *\n     * @var bool\n     */\n    protected $isolated = false;\n\n    /**\n     * The default exit code for isolated commands.\n     *\n     * @var self::SUCCESS|self::FAILURE|self::INVALID\n     */\n    protected $isolatedExitCode = self::SUCCESS;\n\n    /**\n     * The console command name aliases.\n     *\n     * @var string[]\n     */\n    protected $aliases;\n\n    /**\n     * Create a new console command instance.\n     */\n    public function __construct()\n    {\n        $this->configureFromAttributes();\n\n        // We will go ahead and set the name, description, and parameters on console\n        // commands just to make things a little easier on the developer. This is\n        // so they don't have to all be manually specified in the constructors.\n        if (isset($this->signature)) {\n            $this->configureUsingFluentDefinition();\n        } else {\n            parent::__construct($this->name);\n        }\n\n        $this->configureUsageFromAttribute();\n\n        // Once we have constructed the command, we'll set the description and other\n        // related properties of the command. If a signature wasn't used to build\n        // the command we'll set the arguments and the options on this command.\n        if (! empty($this->description)) {\n            $this->setDescription($this->description);\n        }\n\n        if (! empty($this->help)) {\n            $this->setHelp($this->help);\n        }\n\n        $this->setHidden($this->isHidden());\n\n        if (isset($this->aliases)) {\n            $this->setAliases((array) $this->aliases);\n        }\n\n        if (! isset($this->signature)) {\n            $this->specifyParameters();\n        }\n\n        if ($this instanceof Isolatable) {\n            $this->configureIsolation();\n        }\n    }\n\n    /**\n     * Configure the command from class attributes.\n     *\n     * @return void\n     */\n    protected function configureFromAttributes()\n    {\n        $reflection = new ReflectionClass($this);\n\n        $signature = $reflection->getAttributes(Signature::class);\n\n        if (count($signature) > 0) {\n            $signatureInstance = $signature[0]->newInstance();\n\n            $this->signature = $signatureInstance->signature;\n\n            if ($signatureInstance->aliases !== null) {\n                $this->aliases = $signatureInstance->aliases;\n            }\n        }\n\n        $description = $reflection->getAttributes(Description::class);\n\n        if (count($description) > 0) {\n            $this->description = $description[0]->newInstance()->description;\n        }\n\n        $help = $reflection->getAttributes(Help::class);\n\n        if (count($help) > 0) {\n            $this->help = $help[0]->newInstance()->help;\n        }\n\n        if (count($reflection->getAttributes(Hidden::class)) > 0) {\n            $this->hidden = true;\n        }\n    }\n\n    /**\n     * Configure usage examples for the command from class attributes.\n     *\n     * @return void\n     */\n    protected function configureUsageFromAttribute()\n    {\n        $reflection = new ReflectionClass($this);\n\n        foreach ($reflection->getAttributes(Usage::class) as $usage) {\n            $this->addUsage($usage->newInstance()->usage);\n        }\n    }\n\n    /**\n     * Configure the console command using a fluent definition.\n     *\n     * @return void\n     */\n    protected function configureUsingFluentDefinition()\n    {\n        [$name, $arguments, $options] = Parser::parse($this->signature);\n\n        parent::__construct($this->name = $name);\n\n        // After parsing the signature we will spin through the arguments and options\n        // and set them on this command. These will already be changed into proper\n        // instances of these \"InputArgument\" and \"InputOption\" Symfony classes.\n        $this->getDefinition()->addArguments($arguments);\n        $this->getDefinition()->addOptions($options);\n    }\n\n    /**\n     * Configure the console command for isolation.\n     *\n     * @return void\n     */\n    protected function configureIsolation()\n    {\n        $this->getDefinition()->addOption(new InputOption(\n            'isolated',\n            null,\n            InputOption::VALUE_OPTIONAL,\n            'Do not run the command if another instance of the command is already running',\n            $this->isolated\n        ));\n    }\n\n    /**\n     * Run the console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return int\n     */\n    #[\\Override]\n    public function run(InputInterface $input, OutputInterface $output): int\n    {\n        $this->output = $output instanceof OutputStyle ? $output : $this->laravel->make(\n            OutputStyle::class, ['input' => $input, 'output' => $output]\n        );\n\n        $this->components = $this->laravel->make(Factory::class, ['output' => $this->output]);\n\n        $this->configurePrompts($input);\n\n        try {\n            return parent::run(\n                $this->input = $input, $this->output\n            );\n        } finally {\n            $this->untrap();\n        }\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     */\n    #[\\Override]\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        if ($this instanceof Isolatable && $this->option('isolated') !== false &&\n            ! $this->commandIsolationMutex()->create($this)) {\n            $this->comment(sprintf(\n                'The [%s] command is already running.', $this->getName()\n            ));\n\n            return (int) (is_numeric($this->option('isolated'))\n                ? $this->option('isolated')\n                : $this->isolatedExitCode);\n        }\n\n        $method = method_exists($this, 'handle') ? 'handle' : '__invoke';\n\n        try {\n            return (int) $this->laravel->call([$this, $method]);\n        } catch (ManuallyFailedException $e) {\n            $this->components->error($e->getMessage());\n\n            return static::FAILURE;\n        } finally {\n            if ($this instanceof Isolatable && $this->option('isolated') !== false) {\n                $this->commandIsolationMutex()->forget($this);\n            }\n        }\n    }\n\n    /**\n     * Get a command isolation mutex instance for the command.\n     *\n     * @return \\Illuminate\\Console\\CommandMutex\n     */\n    protected function commandIsolationMutex()\n    {\n        return $this->laravel->bound(CommandMutex::class)\n            ? $this->laravel->make(CommandMutex::class)\n            : $this->laravel->make(CacheCommandMutex::class);\n    }\n\n    /**\n     * Resolve the console command instance for the given command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command\n     */\n    protected function resolveCommand($command)\n    {\n        if (is_string($command)) {\n            if (! class_exists($command)) {\n                return $this->getApplication()->find($command);\n            }\n\n            $command = $this->laravel->make($command);\n        }\n\n        if ($command instanceof SymfonyCommand) {\n            $command->setApplication($this->getApplication());\n        }\n\n        if ($command instanceof self) {\n            $command->setLaravel($this->getLaravel());\n        }\n\n        return $command;\n    }\n\n    /**\n     * Fail the command manually.\n     *\n     * @param  \\Throwable|string|null  $exception\n     * @return never\n     *\n     * @throws \\Illuminate\\Console\\ManuallyFailedException|\\Throwable\n     */\n    public function fail(Throwable|string|null $exception = null)\n    {\n        if (is_null($exception)) {\n            $exception = 'Command failed manually.';\n        }\n\n        if (is_string($exception)) {\n            $exception = new ManuallyFailedException($exception);\n        }\n\n        throw $exception;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    #[\\Override]\n    public function isHidden(): bool\n    {\n        return $this->hidden;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function setHidden(bool $hidden = true): static\n    {\n        parent::setHidden($this->hidden = $hidden);\n\n        return $this;\n    }\n\n    /**\n     * Get the Laravel application instance.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getLaravel()\n    {\n        return $this->laravel;\n    }\n\n    /**\n     * Set the Laravel application instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $laravel\n     * @return void\n     */\n    public function setLaravel($laravel)\n    {\n        $this->laravel = $laravel;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/CommandMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\ninterface CommandMutex\n{\n    /**\n     * Attempt to obtain a command mutex for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function create($command);\n\n    /**\n     * Determine if a command mutex exists for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function exists($command);\n\n    /**\n     * Release the mutex for the given command.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return bool\n     */\n    public function forget($command);\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/CallsCommands.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\ntrait CallsCommands\n{\n    /**\n     * Resolve the console command instance for the given command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @return \\Symfony\\Component\\Console\\Command\\Command\n     */\n    abstract protected function resolveCommand($command);\n\n    /**\n     * Call another console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $arguments\n     * @return int\n     */\n    public function call($command, array $arguments = [])\n    {\n        return $this->runCommand($command, $arguments, $this->output);\n    }\n\n    /**\n     * Call another console command without output.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $arguments\n     * @return int\n     */\n    public function callSilent($command, array $arguments = [])\n    {\n        return $this->runCommand($command, $arguments, new NullOutput);\n    }\n\n    /**\n     * Call another console command without output.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $arguments\n     * @return int\n     */\n    public function callSilently($command, array $arguments = [])\n    {\n        return $this->callSilent($command, $arguments);\n    }\n\n    /**\n     * Run the given console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $arguments\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return int\n     */\n    protected function runCommand($command, array $arguments, OutputInterface $output)\n    {\n        $arguments['command'] = $command;\n\n        $result = $this->resolveCommand($command)->run(\n            $this->createInputFromArguments($arguments), $output\n        );\n\n        $this->restorePrompts();\n\n        return $result;\n    }\n\n    /**\n     * Create an input instance from the given arguments.\n     *\n     * @param  array  $arguments\n     * @return \\Symfony\\Component\\Console\\Input\\ArrayInput\n     */\n    protected function createInputFromArguments(array $arguments)\n    {\n        return tap(new ArrayInput(array_merge($this->context(), $arguments)), function ($input) {\n            if ($input->getParameterOption('--no-interaction')) {\n                $input->setInteractive(false);\n            }\n        });\n    }\n\n    /**\n     * Get all of the context passed to the command.\n     *\n     * @return array{'--ansi'?: bool, '--no-ansi'?: bool, '--no-interaction'?: bool, '--quiet'?: bool, '--verbose'?: bool}\n     */\n    protected function context()\n    {\n        return (new Collection($this->option()))\n            ->only([\n                'ansi',\n                'no-ansi',\n                'no-interaction',\n                'quiet',\n                'verbose',\n            ])\n            ->filter()\n            ->mapWithKeys(fn ($value, $key) => [\"--{$key}\" => $value])\n            ->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/ConfiguresPrompts.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Illuminate\\Console\\PromptValidationException;\nuse Laravel\\Prompts\\ConfirmPrompt;\nuse Laravel\\Prompts\\MultiSearchPrompt;\nuse Laravel\\Prompts\\MultiSelectPrompt;\nuse Laravel\\Prompts\\PasswordPrompt;\nuse Laravel\\Prompts\\PausePrompt;\nuse Laravel\\Prompts\\Prompt;\nuse Laravel\\Prompts\\SearchPrompt;\nuse Laravel\\Prompts\\SelectPrompt;\nuse Laravel\\Prompts\\SuggestPrompt;\nuse Laravel\\Prompts\\TextareaPrompt;\nuse Laravel\\Prompts\\TextPrompt;\nuse stdClass;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\n\ntrait ConfiguresPrompts\n{\n    /**\n     * Configure the prompt fallbacks.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @return void\n     */\n    protected function configurePrompts(InputInterface $input)\n    {\n        Prompt::setOutput($this->output);\n\n        Prompt::interactive(($input->isInteractive() && defined('STDIN') && stream_isatty(STDIN)) || $this->laravel->runningUnitTests());\n\n        Prompt::validateUsing(fn (Prompt $prompt) => $this->validatePrompt($prompt->value(), $prompt->validate));\n\n        Prompt::fallbackWhen(windows_os() || $this->laravel->runningUnitTests());\n\n        TextPrompt::fallbackUsing(fn (TextPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->components->ask($prompt->label, $prompt->default ?: null) ?? '',\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        TextareaPrompt::fallbackUsing(fn (TextareaPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->components->ask($prompt->label, $prompt->default ?: null, multiline: true) ?? '',\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        PasswordPrompt::fallbackUsing(fn (PasswordPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->components->secret($prompt->label) ?? '',\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        PausePrompt::fallbackUsing(fn (PausePrompt $prompt) => $this->promptUntilValid(\n            function () use ($prompt) {\n                $this->components->ask($prompt->message, $prompt->value());\n\n                return $prompt->value();\n            },\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        ConfirmPrompt::fallbackUsing(fn (ConfirmPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->components->confirm($prompt->label, $prompt->default),\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        SelectPrompt::fallbackUsing(fn (SelectPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->selectFallback($prompt->label, $prompt->options, $prompt->default),\n            false,\n            $prompt->validate\n        ));\n\n        MultiSelectPrompt::fallbackUsing(fn (MultiSelectPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->multiselectFallback($prompt->label, $prompt->options, $prompt->default, $prompt->required),\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        SuggestPrompt::fallbackUsing(fn (SuggestPrompt $prompt) => $this->promptUntilValid(\n            fn () => $this->components->askWithCompletion($prompt->label, $prompt->options, $prompt->default ?: null) ?? '',\n            $prompt->required,\n            $prompt->validate\n        ));\n\n        SearchPrompt::fallbackUsing(fn (SearchPrompt $prompt) => $this->promptUntilValid(\n            function () use ($prompt) {\n                $query = $this->components->ask($prompt->label);\n\n                $options = ($prompt->options)($query);\n\n                return $this->selectFallback($prompt->label, $options);\n            },\n            false,\n            $prompt->validate\n        ));\n\n        MultiSearchPrompt::fallbackUsing(fn (MultiSearchPrompt $prompt) => $this->promptUntilValid(\n            function () use ($prompt) {\n                $query = $this->components->ask($prompt->label);\n\n                $options = ($prompt->options)($query);\n\n                return $this->multiselectFallback($prompt->label, $options, required: $prompt->required);\n            },\n            $prompt->required,\n            $prompt->validate\n        ));\n    }\n\n    /**\n     * Prompt the user until the given validation callback passes.\n     *\n     * @template PResult\n     *\n     * @param  \\Closure(): PResult  $prompt\n     * @param  bool|string  $required\n     * @param  (\\Closure(PResult): mixed)|null  $validate\n     * @return PResult\n     *\n     * @throws \\Illuminate\\Console\\PromptValidationException\n     */\n    protected function promptUntilValid($prompt, $required, $validate)\n    {\n        while (true) {\n            $result = $prompt();\n\n            if ($required && ($result === '' || $result === [] || $result === false)) {\n                $this->components->error(is_string($required) ? $required : 'Required.');\n\n                if ($this->laravel->runningUnitTests()) {\n                    throw new PromptValidationException;\n                } else {\n                    continue;\n                }\n            }\n\n            $error = is_callable($validate) ? $validate($result) : $this->validatePrompt($result, $validate);\n\n            if (is_string($error) && strlen($error) > 0) {\n                $this->components->error($error);\n\n                if ($this->laravel->runningUnitTests()) {\n                    throw new PromptValidationException;\n                } else {\n                    continue;\n                }\n            }\n\n            return $result;\n        }\n    }\n\n    /**\n     * Validate the given prompt value using the validator.\n     *\n     * @param  mixed  $value\n     * @param  mixed  $rules\n     * @return ?string\n     */\n    protected function validatePrompt($value, $rules)\n    {\n        if ($rules instanceof stdClass) {\n            $messages = $rules->messages ?? [];\n            $attributes = $rules->attributes ?? [];\n            $rules = $rules->rules ?? null;\n        }\n\n        if (! $rules) {\n            return;\n        }\n\n        $field = 'answer';\n\n        if (is_array($rules) && ! array_is_list($rules)) {\n            [$field, $rules] = [key($rules), current($rules)];\n        }\n\n        return $this->getPromptValidatorInstance(\n            $field, $value, $rules, $messages ?? [], $attributes ?? []\n        )->errors()->first();\n    }\n\n    /**\n     * Get the validator instance that should be used to validate prompts.\n     *\n     * @param  mixed  $field\n     * @param  mixed  $value\n     * @param  mixed  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return \\Illuminate\\Validation\\Validator\n     */\n    protected function getPromptValidatorInstance($field, $value, $rules, array $messages = [], array $attributes = [])\n    {\n        return $this->laravel['validator']->make(\n            [$field => $value],\n            [$field => $rules],\n            empty($messages) ? $this->validationMessages() : $messages,\n            empty($attributes) ? $this->validationAttributes() : $attributes,\n        );\n    }\n\n    /**\n     * Get the validation messages that should be used during prompt validation.\n     *\n     * @return array<string, string>\n     */\n    protected function validationMessages()\n    {\n        return [];\n    }\n\n    /**\n     * Get the validation attributes that should be used during prompt validation.\n     *\n     * @return array<string, string>\n     */\n    protected function validationAttributes()\n    {\n        return [];\n    }\n\n    /**\n     * Restore the prompts output.\n     *\n     * @return void\n     */\n    protected function restorePrompts()\n    {\n        Prompt::setOutput($this->output);\n    }\n\n    /**\n     * Select fallback.\n     *\n     * @param  string  $label\n     * @param  array<array-key, string>  $options\n     * @param  string|int|null  $default\n     * @return string|int\n     */\n    private function selectFallback($label, $options, $default = null)\n    {\n        $answer = $this->components->choice($label, $options, $default);\n\n        if (! array_is_list($options) && $answer === (string) (int) $answer) {\n            return (int) $answer;\n        }\n\n        return $answer;\n    }\n\n    /**\n     * Multi-select fallback.\n     *\n     * @param  string  $label\n     * @param  array  $options\n     * @param  array  $default\n     * @param  bool|string  $required\n     * @return array\n     */\n    private function multiselectFallback($label, $options, $default = [], $required = false)\n    {\n        $default = $default !== [] ? implode(',', $default) : null;\n\n        if ($required === false && ! $this->laravel->runningUnitTests()) {\n            $options = array_is_list($options)\n                ? ['None', ...$options]\n                : ['' => 'None'] + $options;\n\n            if ($default === null) {\n                $default = 'None';\n            }\n        }\n\n        $answers = $this->components->choice($label, $options, $default, null, true);\n\n        if (! array_is_list($options)) {\n            $answers = array_map(fn ($value) => $value === (string) (int) $value ? (int) $value : $value, $answers);\n        }\n\n        if ($required === false) {\n            return array_is_list($options)\n                ? array_values(array_filter($answers, fn ($value) => $value !== 'None'))\n                : array_filter($answers, fn ($value) => $value !== '');\n        }\n\n        return $answers;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/CreatesMatchingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\ntrait CreatesMatchingTest\n{\n    /**\n     * Add the standard command options for generating matching tests.\n     *\n     * @return void\n     */\n    protected function addTestOptions()\n    {\n        foreach (['test' => 'Test', 'pest' => 'Pest', 'phpunit' => 'PHPUnit'] as $option => $name) {\n            $this->getDefinition()->addOption(new InputOption(\n                $option,\n                null,\n                InputOption::VALUE_NONE,\n                \"Generate an accompanying {$name} test for the {$this->type}\"\n            ));\n        }\n    }\n\n    /**\n     * Create the matching test case if requested.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    protected function handleTestCreation($path)\n    {\n        if (! $this->option('test') && ! $this->option('pest') && ! $this->option('phpunit')) {\n            return false;\n        }\n\n        return $this->call('make:test', [\n            'name' => (new Stringable($path))->after($this->laravel['path'])->beforeLast('.php')->append('Test')->replace('\\\\', '/'),\n            '--pest' => $this->option('pest'),\n            '--phpunit' => $this->option('phpunit'),\n            '--force' => $this->hasOption('force') && $this->option('force'),\n        ]) == 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/FindsAvailableModels.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Finder\\Finder;\n\ntrait FindsAvailableModels\n{\n    /**\n     * Get a list of possible model names.\n     *\n     * @return array<int, string>\n     */\n    protected function findAvailableModels()\n    {\n        $modelPath = is_dir(app_path('Models')) ? app_path('Models') : app_path();\n\n        return (new Collection(Finder::create()->files()->depth(0)->in($modelPath)))\n            ->map(fn ($file) => $file->getBasename('.php'))\n            ->sort()\n            ->values()\n            ->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/HasParameters.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Symfony\\Component\\Console\\Completion\\CompletionInput;\nuse Symfony\\Component\\Console\\Completion\\CompletionSuggestions;\nuse Symfony\\Component\\Console\\Completion\\Suggestion;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\ntrait HasParameters\n{\n    /**\n     * Specify the arguments and options on the command.\n     *\n     * @return void\n     */\n    protected function specifyParameters()\n    {\n        // We will loop through all of the arguments and options for the command and\n        // set them all on the base command instance. This specifies what can get\n        // passed into these commands as \"parameters\" to control the execution.\n        foreach ($this->getArguments() as $arguments) {\n            if ($arguments instanceof InputArgument) {\n                $this->getDefinition()->addArgument($arguments);\n            } else {\n                $this->addArgument(...$arguments);\n            }\n        }\n\n        foreach ($this->getOptions() as $options) {\n            if ($options instanceof InputOption) {\n                $this->getDefinition()->addOption($options);\n            } else {\n                $this->addOption(...$options);\n            }\n        }\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return (InputArgument|array{\n     *    0: non-empty-string,\n     *    1?: int-mask-of<InputArgument::REQUIRED|InputArgument::OPTIONAL|InputArgument::IS_ARRAY>,\n     *    2?: string,\n     *    3?: mixed,\n     *    4?: list<string|Suggestion>|\\Closure(CompletionInput, CompletionSuggestions): list<string|Suggestion>\n     * })[]\n     */\n    protected function getArguments()\n    {\n        return [];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return (InputOption|array{\n     *    0: non-empty-string,\n     *    1?: string|non-empty-array<string>,\n     *    2?: int-mask-of<InputOption::VALUE_*>,\n     *    3?: string,\n     *    4?: mixed,\n     *    5?: list<string|Suggestion>|\\Closure(CompletionInput, CompletionSuggestions): list<string|Suggestion>\n     * })[]\n     */\n    protected function getOptions()\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/InteractsWithIO.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Closure;\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle;\nuse Symfony\\Component\\Console\\Helper\\Table;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\nuse Symfony\\Component\\Console\\Question\\Question;\n\ntrait InteractsWithIO\n{\n    /**\n     * The console components factory.\n     *\n     * @var \\Illuminate\\Console\\View\\Components\\Factory\n     */\n    protected $components;\n\n    /**\n     * The input interface implementation.\n     *\n     * @var \\Symfony\\Component\\Console\\Input\\InputInterface\n     */\n    protected $input;\n\n    /**\n     * The output interface implementation.\n     *\n     * @var \\Illuminate\\Console\\OutputStyle\n     */\n    protected $output;\n\n    /**\n     * The default verbosity of output commands.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*\n     */\n    protected $verbosity = OutputInterface::VERBOSITY_NORMAL;\n\n    /**\n     * The mapping between human-readable verbosity levels and Symfony's OutputInterface.\n     *\n     * @var array<string, \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*>\n     */\n    protected $verbosityMap = [\n        'v' => OutputInterface::VERBOSITY_VERBOSE,\n        'vv' => OutputInterface::VERBOSITY_VERY_VERBOSE,\n        'vvv' => OutputInterface::VERBOSITY_DEBUG,\n        'quiet' => OutputInterface::VERBOSITY_QUIET,\n        'normal' => OutputInterface::VERBOSITY_NORMAL,\n    ];\n\n    /**\n     * Determine if the given argument is present.\n     *\n     * @param  string|int  $name\n     * @return bool\n     */\n    public function hasArgument($name)\n    {\n        return $this->input->hasArgument($name);\n    }\n\n    /**\n     * Get the value of a command argument.\n     *\n     * @param  string|null  $key\n     * @return ($key is null ? array<array|string|float|int|bool|null> : array|string|float|int|bool|null)\n     */\n    public function argument($key = null)\n    {\n        if (is_null($key)) {\n            return $this->input->getArguments();\n        }\n\n        return $this->input->getArgument($key);\n    }\n\n    /**\n     * Get all of the arguments passed to the command.\n     *\n     * @return array<array|string|float|int|bool|null>\n     */\n    public function arguments()\n    {\n        return $this->argument();\n    }\n\n    /**\n     * Determine whether the option is defined in the command signature.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasOption($name)\n    {\n        return $this->input->hasOption($name);\n    }\n\n    /**\n     * Get the value of a command option.\n     *\n     * @param  string|null  $key\n     * @return ($key is null ? array<array|string|float|int|bool|null> : array|string|float|int|bool|null)\n     */\n    public function option($key = null)\n    {\n        if (is_null($key)) {\n            return $this->input->getOptions();\n        }\n\n        return $this->input->getOption($key);\n    }\n\n    /**\n     * Get all of the options passed to the command.\n     *\n     * @return array<array|string|float|int|bool|null>\n     */\n    public function options()\n    {\n        return $this->option();\n    }\n\n    /**\n     * Confirm a question with the user.\n     *\n     * @param  string  $question\n     * @param  bool  $default\n     * @return bool\n     */\n    public function confirm($question, $default = false)\n    {\n        return $this->output->confirm($question, $default);\n    }\n\n    /**\n     * Prompt the user for input.\n     *\n     * @param  string  $question\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function ask($question, $default = null)\n    {\n        return $this->output->ask($question, $default);\n    }\n\n    /**\n     * Prompt the user for input with auto completion.\n     *\n     * @param  string  $question\n     * @param  array|callable  $choices\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function anticipate($question, $choices, $default = null)\n    {\n        return $this->askWithCompletion($question, $choices, $default);\n    }\n\n    /**\n     * Prompt the user for input with auto completion.\n     *\n     * @param  string  $question\n     * @param  iterable|(callable(string): string[])  $choices\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function askWithCompletion($question, $choices, $default = null)\n    {\n        $question = new Question($question, $default);\n\n        is_callable($choices)\n            ? $question->setAutocompleterCallback($choices)\n            : $question->setAutocompleterValues($choices);\n\n        return $this->output->askQuestion($question);\n    }\n\n    /**\n     * Prompt the user for input but hide the answer from the console.\n     *\n     * @param  string  $question\n     * @param  bool  $fallback\n     * @return mixed\n     */\n    public function secret($question, $fallback = true)\n    {\n        $question = new Question($question);\n\n        $question->setHidden(true)->setHiddenFallback($fallback);\n\n        return $this->output->askQuestion($question);\n    }\n\n    /**\n     * Give the user a single choice from an array of answers.\n     *\n     * @param  string  $question\n     * @param  array<\\Stringable|string|float|int|bool>  $choices\n     * @param  string|int|null  $default\n     * @param  ?positive-int  $attempts\n     * @param  bool  $multiple\n     * @return string|array\n     */\n    public function choice($question, array $choices, $default = null, $attempts = null, $multiple = false)\n    {\n        $question = new ChoiceQuestion($question, $choices, $default);\n\n        $question->setMaxAttempts($attempts)->setMultiselect($multiple);\n\n        return $this->output->askQuestion($question);\n    }\n\n    /**\n     * Format input to textual table.\n     *\n     * @param  array  $headers\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $rows\n     * @param  \\Symfony\\Component\\Console\\Helper\\TableStyle|string  $tableStyle\n     * @param  array<int, \\Symfony\\Component\\Console\\Helper\\TableStyle|string>  $columnStyles\n     * @return void\n     */\n    public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])\n    {\n        $table = new Table($this->output);\n\n        if ($rows instanceof Arrayable) {\n            $rows = $rows->toArray();\n        }\n\n        $table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);\n\n        foreach ($columnStyles as $columnIndex => $columnStyle) {\n            $table->setColumnStyle($columnIndex, $columnStyle);\n        }\n\n        $table->render();\n    }\n\n    /**\n     * Execute a given callback while advancing a progress bar.\n     *\n     * @template TKey of array-key\n     * @template TValue\n     * @template TIterable of iterable<TKey, TValue>\n     *\n     * @param  TIterable|int  $totalSteps\n     * @param  \\Closure(\\Symfony\\Component\\Console\\Helper\\ProgressBar): mixed|\\Closure(TValue, \\Symfony\\Component\\Console\\Helper\\ProgressBar, TKey): mixed  $callback\n     * @return ($totalSteps is iterable ? TIterable : void)\n     */\n    public function withProgressBar($totalSteps, Closure $callback)\n    {\n        $bar = $this->output->createProgressBar(\n            is_iterable($totalSteps) ? count($totalSteps) : $totalSteps\n        );\n\n        $bar->start();\n\n        if (is_iterable($totalSteps)) {\n            foreach ($totalSteps as $key => $value) {\n                $callback($value, $bar, $key);\n\n                $bar->advance();\n            }\n        } else {\n            $callback($bar);\n        }\n\n        $bar->finish();\n\n        if (is_iterable($totalSteps)) {\n            return $totalSteps;\n        }\n    }\n\n    /**\n     * Write a string as information output.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function info($string, $verbosity = null)\n    {\n        $this->line($string, 'info', $verbosity);\n    }\n\n    /**\n     * Write a string as standard output.\n     *\n     * @param  string  $string\n     * @param  'info'|'comment'|'question'|'error'|'warn'|'alert'|null  $style\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function line($string, $style = null, $verbosity = null)\n    {\n        $styled = $style ? \"<$style>$string</$style>\" : $string;\n\n        $this->output->writeln($styled, $this->parseVerbosity($verbosity));\n    }\n\n    /**\n     * Write a string as comment output.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function comment($string, $verbosity = null)\n    {\n        $this->line($string, 'comment', $verbosity);\n    }\n\n    /**\n     * Write a string as question output.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function question($string, $verbosity = null)\n    {\n        $this->line($string, 'question', $verbosity);\n    }\n\n    /**\n     * Write a string as error output.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function error($string, $verbosity = null)\n    {\n        $this->line($string, 'error', $verbosity);\n    }\n\n    /**\n     * Write a string as warning output.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function warn($string, $verbosity = null)\n    {\n        if (! $this->output->getFormatter()->hasStyle('warning')) {\n            $style = new OutputFormatterStyle('yellow');\n\n            $this->output->getFormatter()->setStyle('warning', $style);\n        }\n\n        $this->line($string, 'warning', $verbosity);\n    }\n\n    /**\n     * Write a string in an alert box.\n     *\n     * @param  string  $string\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $verbosity\n     * @return void\n     */\n    public function alert($string, $verbosity = null)\n    {\n        $length = Str::length(strip_tags($string)) + 12;\n\n        $this->comment(str_repeat('*', $length), $verbosity);\n        $this->comment('*     '.$string.'     *', $verbosity);\n        $this->comment(str_repeat('*', $length), $verbosity);\n\n        $this->comment('', $verbosity);\n    }\n\n    /**\n     * Write a blank line.\n     *\n     * @param  int  $count\n     * @return $this\n     */\n    public function newLine($count = 1)\n    {\n        $this->output->newLine($count);\n\n        return $this;\n    }\n\n    /**\n     * Set the input interface implementation.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @return void\n     */\n    public function setInput(InputInterface $input)\n    {\n        $this->input = $input;\n    }\n\n    /**\n     * Set the output interface implementation.\n     *\n     * @param  \\Illuminate\\Console\\OutputStyle  $output\n     * @return void\n     */\n    public function setOutput(OutputStyle $output)\n    {\n        $this->output = $output;\n    }\n\n    /**\n     * Set the verbosity level.\n     *\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*  $level\n     * @return void\n     */\n    protected function setVerbosity($level)\n    {\n        $this->verbosity = $this->parseVerbosity($level);\n    }\n\n    /**\n     * Get the verbosity level in terms of Symfony's OutputInterface level.\n     *\n     * @param  'v'|'vv'|'vvv'|'quiet'|'normal'|\\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_*|null  $level\n     * @return int\n     */\n    protected function parseVerbosity($level = null)\n    {\n        $level ??= '';\n\n        if (isset($this->verbosityMap[$level])) {\n            $level = $this->verbosityMap[$level];\n        } elseif (! is_int($level)) {\n            $level = $this->verbosity;\n        }\n\n        return $level;\n    }\n\n    /**\n     * Get the output implementation.\n     *\n     * @return \\Illuminate\\Console\\OutputStyle\n     */\n    public function getOutput()\n    {\n        return $this->output;\n    }\n\n    /**\n     * Get the output component factory implementation.\n     *\n     * @return \\Illuminate\\Console\\View\\Components\\Factory\n     */\n    public function outputComponents()\n    {\n        return $this->components;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/InteractsWithSignals.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Illuminate\\Console\\Signals;\nuse Illuminate\\Support\\Collection;\n\ntrait InteractsWithSignals\n{\n    /**\n     * The signal registrar instance.\n     *\n     * @var \\Illuminate\\Console\\Signals|null\n     */\n    protected $signals;\n\n    /**\n     * Define a callback to be run when the given signal(s) occurs.\n     *\n     * @template TSignals of iterable<array-key, int>|int\n     *\n     * @param  (\\Closure():(TSignals))|TSignals  $signals\n     * @param  callable(int $signal): void  $callback\n     * @return void\n     */\n    public function trap($signals, $callback)\n    {\n        Signals::whenAvailable(function () use ($signals, $callback) {\n            $this->signals ??= new Signals(\n                $this->getApplication()->getSignalRegistry(),\n            );\n\n            Collection::wrap(value($signals))\n                ->each(fn ($signal) => $this->signals->register($signal, $callback));\n        });\n    }\n\n    /**\n     * Untrap signal handlers set within the command's handler.\n     *\n     * @return void\n     *\n     * @internal\n     */\n    public function untrap()\n    {\n        if (! is_null($this->signals)) {\n            $this->signals->unregister();\n\n            $this->signals = null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Concerns/PromptsForMissingInput.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Concerns;\n\nuse Closure;\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput as PromptsForMissingInputContract;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\text;\n\ntrait PromptsForMissingInput\n{\n    /**\n     * Interact with the user before validating the input.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function interact(InputInterface $input, OutputInterface $output): void\n    {\n        parent::interact($input, $output);\n\n        if ($this instanceof PromptsForMissingInputContract) {\n            $this->promptForMissingArguments($input, $output);\n        }\n    }\n\n    /**\n     * Prompt the user for any missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function promptForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        $prompted = (new Collection($this->getDefinition()->getArguments()))\n            ->reject(fn (InputArgument $argument) => $argument->getName() === 'command')\n            ->filter(fn (InputArgument $argument) => $argument->isRequired() && match (true) {\n                $argument->isArray() => empty($input->getArgument($argument->getName())),\n                default => is_null($input->getArgument($argument->getName())),\n            })\n            ->each(function (InputArgument $argument) use ($input) {\n                $label = $this->promptForMissingArgumentsUsing()[$argument->getName()] ??\n                    'What is '.lcfirst($argument->getDescription() ?: ('the '.$argument->getName())).'?';\n\n                if ($label instanceof Closure) {\n                    return $input->setArgument($argument->getName(), $argument->isArray() ? Arr::wrap($label()) : $label());\n                }\n\n                if (is_array($label)) {\n                    [$label, $placeholder] = $label;\n                }\n\n                $answer = text(\n                    label: $label,\n                    placeholder: $placeholder ?? '',\n                    validate: fn ($value) => empty($value) ? \"The {$argument->getName()} is required.\" : null,\n                );\n\n                $input->setArgument($argument->getName(), $argument->isArray() ? [$answer] : $answer);\n            })\n            ->isNotEmpty();\n\n        if ($prompted) {\n            $this->afterPromptingForMissingArguments($input, $output);\n        }\n    }\n\n    /**\n     * Prompt for missing input arguments using the returned questions.\n     *\n     * @return array<string, string|array{string, string}|\\Closure(): (array<int|string>|string|int|bool)>\n     */\n    protected function promptForMissingArgumentsUsing()\n    {\n        return [];\n    }\n\n    /**\n     * Perform actions after the user was prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        //\n    }\n\n    /**\n     * Whether the input contains any options that differ from the default values.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @return bool\n     */\n    protected function didReceiveOptions(InputInterface $input)\n    {\n        return (new Collection($this->getDefinition()->getOptions()))\n            ->reject(fn ($option) => $input->getOption($option->getName()) === $option->getDefault())\n            ->isNotEmpty();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/ConfirmableTrait.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse function Laravel\\Prompts\\confirm;\n\ntrait ConfirmableTrait\n{\n    /**\n     * Confirm before proceeding with the action.\n     *\n     * This method only asks for confirmation in production.\n     *\n     * @template TReturn of bool = bool\n     *\n     * @param  string  $warning\n     * @param  (\\Closure(): TReturn)|TReturn|null  $callback\n     * @return (TReturn is false ? true : bool)\n     */\n    public function confirmToProceed($warning = 'Application In Production', $callback = null)\n    {\n        $callback = is_null($callback) ? $this->getDefaultConfirmCallback() : $callback;\n\n        $shouldConfirm = value($callback);\n\n        if ($shouldConfirm) {\n            if ($this->hasOption('force') && $this->option('force')) {\n                return true;\n            }\n\n            $this->components->alert($warning);\n\n            $confirmed = confirm('Are you sure you want to run this command?', default: false);\n\n            if (! $confirmed) {\n                $this->components->warn('Command cancelled.');\n\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the default confirmation callback.\n     *\n     * @return \\Closure(): bool\n     */\n    protected function getDefaultConfirmCallback()\n    {\n        return function () {\n            return $this->getLaravel()->environment() === 'production';\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/ContainerCommandLoader.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Psr\\Container\\ContainerInterface;\nuse Symfony\\Component\\Console\\Command\\Command;\nuse Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface;\nuse Symfony\\Component\\Console\\Exception\\CommandNotFoundException;\n\nclass ContainerCommandLoader implements CommandLoaderInterface\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Psr\\Container\\ContainerInterface\n     */\n    protected $container;\n\n    /**\n     * A map of command names to classes.\n     *\n     * @var array<string, \\Illuminate\\Console\\Command|string>\n     */\n    protected $commandMap;\n\n    /**\n     * Create a new command loader instance.\n     *\n     * @param  \\Psr\\Container\\ContainerInterface  $container\n     * @param  array<string, \\Illuminate\\Console\\Command|string>  $commandMap\n     */\n    public function __construct(ContainerInterface $container, array $commandMap)\n    {\n        $this->container = $container;\n        $this->commandMap = $commandMap;\n    }\n\n    /**\n     * Resolve a command from the container.\n     *\n     * @param  string  $name\n     * @return \\Symfony\\Component\\Console\\Command\\Command\n     *\n     * @throws \\Symfony\\Component\\Console\\Exception\\CommandNotFoundException\n     */\n    public function get(string $name): Command\n    {\n        if (! $this->has($name)) {\n            throw new CommandNotFoundException(sprintf('Command \"%s\" does not exist.', $name));\n        }\n\n        return $this->container->get($this->commandMap[$name]);\n    }\n\n    /**\n     * Determines if a command exists.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function has(string $name): bool\n    {\n        return $name && isset($this->commandMap[$name]);\n    }\n\n    /**\n     * Get the command names.\n     *\n     * @return string[]\n     */\n    public function getNames(): array\n    {\n        return array_keys($this->commandMap);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Contracts/NewLineAware.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Contracts;\n\ninterface NewLineAware\n{\n    /**\n     * How many trailing newlines were written.\n     *\n     * @return int\n     */\n    public function newLinesWritten();\n\n    /**\n     * Whether a newline has already been written.\n     *\n     * @return bool\n     *\n     * @deprecated use newLinesWritten\n     */\n    public function newLineWritten();\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ArtisanStarting.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Application;\n\nclass ArtisanStarting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Application  $artisan  The Artisan application instance.\n     */\n    public function __construct(\n        public Application $artisan,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/CommandFinished.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass CommandFinished\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $command  The command name.\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input  The console input implementation.\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output  The command output implementation.\n     * @param  int  $exitCode  The command exit code.\n     */\n    public function __construct(\n        public string $command,\n        public InputInterface $input,\n        public OutputInterface $output,\n        public int $exitCode,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/CommandStarting.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass CommandStarting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $command  The command name.\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input  The console input implementation.\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output  The command output implementation.\n     */\n    public function __construct(\n        public string $command,\n        public InputInterface $input,\n        public OutputInterface $output,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/SchedulePaused.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nclass SchedulePaused\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduleResumed.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nclass ScheduleResumed\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduledBackgroundTaskFinished.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Scheduling\\Event;\n\nclass ScheduledBackgroundTaskFinished\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $task  The scheduled event that ran.\n     */\n    public function __construct(\n        public Event $task,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduledTaskFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Throwable;\n\nclass ScheduledTaskFailed\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $task  The scheduled event that failed.\n     * @param  \\Throwable  $exception  The exception that was thrown.\n     */\n    public function __construct(\n        public Event $task,\n        public Throwable $exception,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduledTaskFinished.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Scheduling\\Event;\n\nclass ScheduledTaskFinished\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $task  The scheduled event that ran.\n     * @param  float  $runtime  The runtime of the scheduled event.\n     */\n    public function __construct(\n        public Event $task,\n        public float $runtime,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduledTaskSkipped.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Scheduling\\Event;\n\nclass ScheduledTaskSkipped\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $task  The scheduled event being run.\n     */\n    public function __construct(\n        public Event $task,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Events/ScheduledTaskStarting.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Events;\n\nuse Illuminate\\Console\\Scheduling\\Event;\n\nclass ScheduledTaskStarting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $task  The scheduled event being run.\n     */\n    public function __construct(\n        public Event $task,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/GeneratorCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\Concerns\\FindsAvailableModels;\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Completion\\CompletionInput;\nuse Symfony\\Component\\Console\\Completion\\CompletionSuggestions;\nuse Symfony\\Component\\Console\\Completion\\Suggestion;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Finder\\Finder;\n\nabstract class GeneratorCommand extends Command implements PromptsForMissingInput\n{\n    use FindsAvailableModels;\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type;\n\n    /**\n     * Reserved names that cannot be used for generation.\n     *\n     * @var string[]\n     */\n    protected $reservedNames = [\n        '__halt_compiler',\n        'abstract',\n        'and',\n        'array',\n        'as',\n        'break',\n        'callable',\n        'case',\n        'catch',\n        'class',\n        'clone',\n        'const',\n        'continue',\n        'declare',\n        'default',\n        'die',\n        'do',\n        'echo',\n        'else',\n        'elseif',\n        'empty',\n        'enddeclare',\n        'endfor',\n        'endforeach',\n        'endif',\n        'endswitch',\n        'endwhile',\n        'enum',\n        'eval',\n        'exit',\n        'extends',\n        'false',\n        'final',\n        'finally',\n        'fn',\n        'for',\n        'foreach',\n        'function',\n        'global',\n        'goto',\n        'if',\n        'implements',\n        'include',\n        'include_once',\n        'instanceof',\n        'insteadof',\n        'interface',\n        'isset',\n        'list',\n        'match',\n        'namespace',\n        'new',\n        'or',\n        'parent',\n        'print',\n        'private',\n        'protected',\n        'public',\n        'readonly',\n        'require',\n        'require_once',\n        'return',\n        'self',\n        'static',\n        'switch',\n        'throw',\n        'trait',\n        'true',\n        'try',\n        'unset',\n        'use',\n        'var',\n        'while',\n        'xor',\n        'yield',\n        '__CLASS__',\n        '__DIR__',\n        '__FILE__',\n        '__FUNCTION__',\n        '__LINE__',\n        '__METHOD__',\n        '__NAMESPACE__',\n        '__TRAIT__',\n    ];\n\n    /**\n     * Create a new generator command instance.\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        if (in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {\n            $this->addTestOptions();\n        }\n\n        $this->files = $files;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    abstract protected function getStub();\n\n    /**\n     * Execute the console command.\n     *\n     * @return bool|null\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function handle()\n    {\n        // First we need to ensure that the given name is not a reserved word within the PHP\n        // language and that the class name will actually be valid. If it is not valid we\n        // can error now and prevent from polluting the filesystem using invalid files.\n        if ($this->isReservedName($this->getNameInput())) {\n            $this->components->error('The name \"'.$this->getNameInput().'\" is reserved by PHP.');\n\n            return false;\n        }\n\n        $name = $this->qualifyClass($this->getNameInput());\n\n        $path = $this->getPath($name);\n\n        // Next, We will check to see if the class already exists. If it does, we don't want\n        // to create the class and overwrite the user's code. So, we will bail out so the\n        // code is untouched. Otherwise, we will continue generating this class' files.\n        if ((! $this->hasOption('force') ||\n             ! $this->option('force')) &&\n             $this->alreadyExists($this->getNameInput())) {\n            $this->components->error($this->type.' already exists.');\n\n            return false;\n        }\n\n        // Next, we will generate the path to the location where this class' file should get\n        // written. Then, we will build the class and make the proper replacements on the\n        // stub files so that it gets the correctly formatted namespace and class name.\n        $this->makeDirectory($path);\n\n        $this->files->put($path, $this->sortImports($this->buildClass($name)));\n\n        $info = $this->type;\n\n        if (in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {\n            $this->handleTestCreation($path);\n        }\n\n        if (windows_os()) {\n            $path = str_replace('/', '\\\\', $path);\n        }\n\n        $this->components->info(sprintf('%s [%s] created successfully.', $info, $path));\n    }\n\n    /**\n     * Parse the class name and format according to the root namespace.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function qualifyClass($name)\n    {\n        $name = ltrim($name, '\\\\/');\n\n        $name = str_replace('/', '\\\\', $name);\n\n        $rootNamespace = $this->rootNamespace();\n\n        if (Str::startsWith($name, $rootNamespace)) {\n            return $name;\n        }\n\n        return $this->qualifyClass(\n            $this->getDefaultNamespace(trim($rootNamespace, '\\\\')).'\\\\'.$name\n        );\n    }\n\n    /**\n     * Qualify the given model class base name.\n     *\n     * @return class-string\n     */\n    protected function qualifyModel(string $model)\n    {\n        $model = ltrim($model, '\\\\/');\n\n        $model = str_replace('/', '\\\\', $model);\n\n        $rootNamespace = $this->rootNamespace();\n\n        if (Str::startsWith($model, $rootNamespace)) {\n            return $model;\n        }\n\n        return is_dir(app_path('Models'))\n            ? $rootNamespace.'Models\\\\'.$model\n            : $rootNamespace.$model;\n    }\n\n    /**\n     * Get a list of possible model names.\n     *\n     * @return array<int, string>\n     *\n     * @deprecated 12.38.0 Use `findAvailableModels()` method instead.\n     */\n    protected function possibleModels()\n    {\n        return $this->findAvailableModels();\n    }\n\n    /**\n     * Get a list of possible event names.\n     *\n     * @return array<int, string>\n     */\n    protected function possibleEvents()\n    {\n        $eventPath = app_path('Events');\n\n        if (! is_dir($eventPath)) {\n            return [];\n        }\n\n        return (new Collection(Finder::create()->files()->depth(0)->in($eventPath)))\n            ->map(fn ($file) => $file->getBasename('.php'))\n            ->sort()\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace;\n    }\n\n    /**\n     * Determine if the class already exists.\n     *\n     * @param  string  $rawName\n     * @return bool\n     */\n    protected function alreadyExists($rawName)\n    {\n        return $this->files->exists($this->getPath($this->qualifyClass($rawName)));\n    }\n\n    /**\n     * Get the destination class path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getPath($name)\n    {\n        $name = Str::replaceFirst($this->rootNamespace(), '', $name);\n\n        return $this->laravel['path'].'/'.str_replace('\\\\', '/', $name).'.php';\n    }\n\n    /**\n     * Build the directory for the class if necessary.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function makeDirectory($path)\n    {\n        if (! $this->files->isDirectory(dirname($path))) {\n            $this->files->makeDirectory(dirname($path), 0777, true, true);\n        }\n\n        return $path;\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    protected function buildClass($name)\n    {\n        $stub = $this->files->get($this->getStub());\n\n        return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);\n    }\n\n    /**\n     * Replace the namespace for the given stub.\n     *\n     * @param  string  $stub\n     * @param  string  $name\n     * @return $this\n     */\n    protected function replaceNamespace(&$stub, $name)\n    {\n        $searches = [\n            ['DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'],\n            ['{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'],\n            ['{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'],\n        ];\n\n        foreach ($searches as $search) {\n            $stub = str_replace(\n                $search,\n                [$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()],\n                $stub\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the full namespace for a given class, without the class name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getNamespace($name)\n    {\n        return trim(implode('\\\\', array_slice(explode('\\\\', $name), 0, -1)), '\\\\');\n    }\n\n    /**\n     * Replace the class name for the given stub.\n     *\n     * @param  string  $stub\n     * @param  string  $name\n     * @return string\n     */\n    protected function replaceClass($stub, $name)\n    {\n        $class = str_replace($this->getNamespace($name).'\\\\', '', $name);\n\n        return str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub);\n    }\n\n    /**\n     * Alphabetically sorts the imports for the given stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function sortImports($stub)\n    {\n        if (preg_match('/(?P<imports>(?:^use [^;{]+;$\\n?)+)/m', $stub, $match)) {\n            $imports = explode(\"\\n\", trim($match['imports']));\n\n            sort($imports);\n\n            return str_replace(trim($match['imports']), implode(\"\\n\", $imports), $stub);\n        }\n\n        return $stub;\n    }\n\n    /**\n     * Get the desired class name from the input.\n     *\n     * @return string\n     */\n    protected function getNameInput()\n    {\n        $name = trim($this->argument('name'));\n\n        if (Str::endsWith($name, '.php')) {\n            return Str::substr($name, 0, -4);\n        }\n\n        return $name;\n    }\n\n    /**\n     * Get the root namespace for the class.\n     *\n     * @return string\n     */\n    protected function rootNamespace()\n    {\n        return $this->laravel->getNamespace();\n    }\n\n    /**\n     * Get the model for the default guard's user provider.\n     *\n     * @return string|null\n     */\n    protected function userProviderModel()\n    {\n        $config = $this->laravel['config'];\n\n        $provider = $config->get('auth.guards.'.$config->get('auth.defaults.guard').'.provider');\n\n        return $config->get(\"auth.providers.{$provider}.model\");\n    }\n\n    /**\n     * Checks whether the given name is reserved.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    protected function isReservedName($name)\n    {\n        return in_array(\n            strtolower($name),\n            (new Collection($this->reservedNames))\n                ->transform(fn ($name) => strtolower($name))\n                ->all()\n        );\n    }\n\n    /**\n     * Get the first view directory path from the application configuration.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function viewPath($path = '')\n    {\n        $views = $this->laravel['config']['view.paths'][0] ?? resource_path('views');\n\n        return $views.($path ? DIRECTORY_SEPARATOR.$path : $path);\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return (InputArgument|array{\n     *    0: non-empty-string,\n     *    1?: InputArgument::REQUIRED|InputArgument::OPTIONAL|InputArgument::IS_ARRAY,\n     *    2?: string,\n     *    3?: mixed,\n     *    4?: list<string|Suggestion>|\\Closure(CompletionInput, CompletionSuggestions): list<string|Suggestion>\n     * })[]\n     */\n    protected function getArguments()\n    {\n        return [\n            ['name', InputArgument::REQUIRED, 'The name of the '.strtolower($this->type)],\n        ];\n    }\n\n    /**\n     * Prompt for missing input arguments using the returned questions.\n     *\n     * @return array<string, string|array{string, string}|\\Closure(): (array<int, string>|string|int|bool)>\n     */\n    protected function promptForMissingArgumentsUsing()\n    {\n        return [\n            'name' => [\n                'What should the '.strtolower($this->type).' be named?',\n                match ($this->type) {\n                    'Cast' => 'E.g. Json',\n                    'Channel' => 'E.g. OrderChannel',\n                    'Console command' => 'E.g. SendEmails',\n                    'Component' => 'E.g. Alert',\n                    'Controller' => 'E.g. UserController',\n                    'Event' => 'E.g. PodcastProcessed',\n                    'Exception' => 'E.g. InvalidOrderException',\n                    'Factory' => 'E.g. PostFactory',\n                    'Job' => 'E.g. ProcessPodcast',\n                    'Listener' => 'E.g. SendPodcastNotification',\n                    'Mailable' => 'E.g. OrderShipped',\n                    'Middleware' => 'E.g. EnsureTokenIsValid',\n                    'Model' => 'E.g. Flight',\n                    'Notification' => 'E.g. InvoicePaid',\n                    'Observer' => 'E.g. UserObserver',\n                    'Policy' => 'E.g. PostPolicy',\n                    'Provider' => 'E.g. ElasticServiceProvider',\n                    'Request' => 'E.g. StorePodcastRequest',\n                    'Resource' => 'E.g. UserResource',\n                    'Rule' => 'E.g. Uppercase',\n                    'Scope' => 'E.g. TrendingScope',\n                    'Seeder' => 'E.g. UserSeeder',\n                    'Test' => 'E.g. UserTest',\n                    default => '',\n                },\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Console/ManuallyFailedException.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse RuntimeException;\n\nclass ManuallyFailedException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Console/MigrationGeneratorCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Illuminate\\Filesystem\\Filesystem;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\nabstract class MigrationGeneratorCommand extends Command\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new migration generator command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    abstract protected function migrationTableName();\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    abstract protected function migrationStubFile();\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        $table = $this->migrationTableName();\n\n        if ($this->migrationExists($table)) {\n            $this->components->error('Migration already exists.');\n\n            return 1;\n        }\n\n        $this->replaceMigrationPlaceholders(\n            $this->createBaseMigration($table), $table\n        );\n\n        $this->components->info('Migration created successfully.');\n\n        return 0;\n    }\n\n    /**\n     * Create a base migration file for the table.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function createBaseMigration($table)\n    {\n        return $this->laravel['migration.creator']->create(\n            'create_'.$table.'_table', $this->laravel->databasePath('/migrations')\n        );\n    }\n\n    /**\n     * Replace the placeholders in the generated migration file.\n     *\n     * @param  string  $path\n     * @param  string  $table\n     * @return void\n     */\n    protected function replaceMigrationPlaceholders($path, $table)\n    {\n        $stub = str_replace(\n            '{{table}}', $table, $this->files->get($this->migrationStubFile())\n        );\n\n        $this->files->put($path, $stub);\n    }\n\n    /**\n     * Determine whether a migration for the table already exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function migrationExists($table)\n    {\n        return count($this->files->glob(\n            join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php')\n        )) !== 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/OutputStyle.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Illuminate\\Console\\Contracts\\NewLineAware;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Console\\Question\\Question;\nuse Symfony\\Component\\Console\\Style\\SymfonyStyle;\n\nclass OutputStyle extends SymfonyStyle implements NewLineAware\n{\n    /**\n     * The output instance.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    private $output;\n\n    /**\n     * The number of trailing new lines written by the last output.\n     *\n     * This is initialized as 1 to account for the new line written by the shell after executing a command.\n     *\n     * @var int\n     */\n    protected $newLinesWritten = 1;\n\n    /**\n     * If the last output written wrote a new line.\n     *\n     * @var bool\n     *\n     * @deprecated use $newLinesWritten\n     */\n    protected $newLineWritten = false;\n\n    /**\n     * Create a new Console OutputStyle instance.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     */\n    public function __construct(InputInterface $input, OutputInterface $output)\n    {\n        $this->output = $output;\n\n        parent::__construct($input, $output);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function askQuestion(Question $question): mixed\n    {\n        try {\n            return parent::askQuestion($question);\n        } finally {\n            $this->newLinesWritten++;\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function write(string|iterable $messages, bool $newline = false, int $options = 0): void\n    {\n        $this->newLinesWritten = $this->trailingNewLineCount($messages) + (int) $newline;\n        $this->newLineWritten = $this->newLinesWritten > 0;\n\n        parent::write($messages, $newline, $options);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void\n    {\n        if ($this->output->getVerbosity() >= $type) {\n            $this->newLinesWritten = $this->trailingNewLineCount($messages) + 1;\n            $this->newLineWritten = true;\n        }\n\n        parent::writeln($messages, $type);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function newLine(int $count = 1): void\n    {\n        $this->newLinesWritten += $count;\n        $this->newLineWritten = $this->newLinesWritten > 0;\n\n        parent::newLine($count);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function newLinesWritten()\n    {\n        if ($this->output instanceof static) {\n            return $this->output->newLinesWritten();\n        }\n\n        return $this->newLinesWritten;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @deprecated use newLinesWritten\n     */\n    public function newLineWritten()\n    {\n        if ($this->output instanceof static && $this->output->newLineWritten()) {\n            return true;\n        }\n\n        return $this->newLineWritten;\n    }\n\n    /*\n     * Count the number of trailing new lines in a string.\n     *\n     * @param  string|iterable<string>  $messages\n     * @return int\n     */\n    protected function trailingNewLineCount($messages)\n    {\n        if (is_iterable($messages)) {\n            $string = '';\n\n            foreach ($messages as $message) {\n                $string .= $message.PHP_EOL;\n            }\n        } else {\n            $string = $messages;\n        }\n\n        return strlen($string) - strlen(rtrim($string, PHP_EOL));\n    }\n\n    /**\n     * Returns whether verbosity is quiet (-q).\n     *\n     * @return bool\n     */\n    public function isQuiet(): bool\n    {\n        return $this->output->isQuiet();\n    }\n\n    /**\n     * Returns whether verbosity is verbose (-v).\n     *\n     * @return bool\n     */\n    public function isVerbose(): bool\n    {\n        return $this->output->isVerbose();\n    }\n\n    /**\n     * Returns whether verbosity is very verbose (-vv).\n     *\n     * @return bool\n     */\n    public function isVeryVerbose(): bool\n    {\n        return $this->output->isVeryVerbose();\n    }\n\n    /**\n     * Returns whether verbosity is debug (-vvv).\n     *\n     * @return bool\n     */\n    public function isDebug(): bool\n    {\n        return $this->output->isDebug();\n    }\n\n    /**\n     * Get the underlying Symfony output implementation.\n     *\n     * @return \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    public function getOutput()\n    {\n        return $this->output;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Parser.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse InvalidArgumentException;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\nclass Parser\n{\n    /**\n     * Parse the given console command definition into an array.\n     *\n     * @param  string  $expression\n     * @return array{string, array{}, array{}}|array{string, \\Symfony\\Component\\Console\\Input\\InputArgument[], \\Symfony\\Component\\Console\\Input\\InputOption[]}\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function parse(string $expression)\n    {\n        $name = static::name($expression);\n\n        if (preg_match_all('/\\{\\s*(.*?)\\s*\\}/', $expression, $matches) && count($matches[1])) {\n            return array_merge([$name], static::parameters($matches[1]));\n        }\n\n        return [$name, [], []];\n    }\n\n    /**\n     * Extract the name of the command from the expression.\n     *\n     * @param  string  $expression\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected static function name(string $expression)\n    {\n        if (! preg_match('/[^\\s]+/', $expression, $matches)) {\n            throw new InvalidArgumentException('Unable to determine command name from signature.');\n        }\n\n        return $matches[0];\n    }\n\n    /**\n     * Extract all parameters from the tokens.\n     *\n     * @param  string[]  $tokens\n     * @return array{\\Symfony\\Component\\Console\\Input\\InputArgument[], \\Symfony\\Component\\Console\\Input\\InputOption[]}\n     */\n    protected static function parameters(array $tokens)\n    {\n        $arguments = [];\n\n        $options = [];\n\n        foreach ($tokens as $token) {\n            if (preg_match('/^-{2,}(.*)/', $token, $matches)) {\n                $options[] = static::parseOption($matches[1]);\n            } else {\n                $arguments[] = static::parseArgument($token);\n            }\n        }\n\n        return [$arguments, $options];\n    }\n\n    /**\n     * Parse an argument expression.\n     *\n     * @param  string  $token\n     * @return \\Symfony\\Component\\Console\\Input\\InputArgument\n     */\n    protected static function parseArgument(string $token)\n    {\n        [$token, $description] = static::extractDescription($token);\n\n        return match (true) {\n            str_ends_with($token, '?*') => new InputArgument(trim($token, '?*'), InputArgument::IS_ARRAY, $description),\n            str_ends_with($token, '*') => new InputArgument(trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description),\n            str_ends_with($token, '?') => new InputArgument(trim($token, '?'), InputArgument::OPTIONAL, $description),\n            (bool) preg_match('/(.+)\\=\\*(.+)/', $token, $matches) => new InputArgument($matches[1], InputArgument::IS_ARRAY, $description, preg_split('/,\\s?/', $matches[2])),\n            (bool) preg_match('/(.+)\\=(.+)/', $token, $matches) => new InputArgument($matches[1], InputArgument::OPTIONAL, $description, $matches[2]),\n            default => new InputArgument($token, InputArgument::REQUIRED, $description),\n        };\n    }\n\n    /**\n     * Parse an option expression.\n     *\n     * @param  string  $token\n     * @return \\Symfony\\Component\\Console\\Input\\InputOption\n     */\n    protected static function parseOption(string $token)\n    {\n        [$token, $description] = static::extractDescription($token);\n\n        $matches = preg_split('/\\s*\\|\\s*/', $token, 2);\n\n        $shortcut = null;\n\n        if (isset($matches[1])) {\n            $shortcut = $matches[0];\n            $token = $matches[1];\n        }\n\n        return match (true) {\n            str_ends_with($token, '=') => new InputOption(trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description),\n            str_ends_with($token, '=*') => new InputOption(trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description),\n            (bool) preg_match('/(.+)\\=\\*(.+)/', $token, $matches) => new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description, preg_split('/,\\s?/', $matches[2])),\n            (bool) preg_match('/(.+)\\=(.+)/', $token, $matches) => new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL, $description, $matches[2]),\n            default => new InputOption($token, $shortcut, InputOption::VALUE_NONE, $description),\n        };\n    }\n\n    /**\n     * Parse the token into its token and description segments.\n     *\n     * @param  string  $token\n     * @return array{string, string}\n     */\n    protected static function extractDescription(string $token)\n    {\n        $parts = preg_split('/\\s+:\\s+/', trim($token), 2);\n\n        return count($parts) === 2 ? $parts : [$token, ''];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Prohibitable.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\ntrait Prohibitable\n{\n    /**\n     * Indicates if the command should be prohibited from running.\n     *\n     * @var bool\n     */\n    protected static $prohibitedFromRunning = false;\n\n    /**\n     * Indicate whether the command should be prohibited from running.\n     *\n     * @param  bool  $prohibit\n     * @return void\n     */\n    public static function prohibit($prohibit = true)\n    {\n        static::$prohibitedFromRunning = $prohibit;\n    }\n\n    /**\n     * Determine if the command is prohibited from running and display a warning if so.\n     *\n     * @param  bool  $quiet\n     * @return bool\n     */\n    protected function isProhibited(bool $quiet = false)\n    {\n        if (! static::$prohibitedFromRunning) {\n            return false;\n        }\n\n        if (! $quiet) {\n            $this->components->warn('This command is prohibited from running in this environment.');\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/PromptValidationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse RuntimeException;\n\nclass PromptValidationException extends RuntimeException\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Console/QuestionHelper.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\nuse Illuminate\\Console\\View\\Components\\TwoColumnDetail;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Formatter\\OutputFormatter;\nuse Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\nuse Symfony\\Component\\Console\\Question\\ConfirmationQuestion;\nuse Symfony\\Component\\Console\\Question\\Question;\n\nclass QuestionHelper extends SymfonyQuestionHelper\n{\n    /**\n     * {@inheritdoc}\n     *\n     * @return void\n     */\n    #[\\Override]\n    protected function writePrompt(OutputInterface $output, Question $question): void\n    {\n        $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());\n\n        $text = $this->ensureEndsWithPunctuation($text);\n\n        $text = \"  <fg=default;options=bold>$text</></>\";\n\n        $default = $question->getDefault();\n\n        if ($question->isMultiline()) {\n            $text .= sprintf(' (press %s to continue)', 'Windows' == PHP_OS_FAMILY\n                ? '<comment>Ctrl+Z</comment> then <comment>Enter</comment>'\n                : '<comment>Ctrl+D</comment>');\n        }\n\n        switch (true) {\n            case null === $default:\n                $text = sprintf('<info>%s</info>', $text);\n\n                break;\n\n            case $question instanceof ConfirmationQuestion:\n                $text = sprintf('<info>%s (yes/no)</info> [<comment>%s</comment>]', $text, $default ? 'yes' : 'no');\n\n                break;\n\n            case $question instanceof ChoiceQuestion:\n                $choices = $question->getChoices();\n                $text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($choices[$default] ?? $default));\n\n                break;\n\n            default:\n                $text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($default));\n\n                break;\n        }\n\n        $output->writeln($text);\n\n        if ($question instanceof ChoiceQuestion) {\n            foreach ($question->getChoices() as $key => $value) {\n                (new TwoColumnDetail($output))->render($value, $key);\n            }\n        }\n\n        $output->write('<options=bold>❯ </>');\n    }\n\n    /**\n     * Ensures the given string ends with punctuation.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    protected function ensureEndsWithPunctuation($string)\n    {\n        if (! (new Stringable($string))->endsWith(['?', ':', '!', '.'])) {\n            return \"$string:\";\n        }\n\n        return $string;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/CacheAware.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\ninterface CacheAware\n{\n    /**\n     * Specify the cache store that should be used.\n     *\n     * @param  string  $store\n     * @return $this\n     */\n    public function useStore($store);\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/CacheEventMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Cache\\DynamoDbStore;\nuse Illuminate\\Contracts\\Cache\\Factory as Cache;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\n\nclass CacheEventMutex implements EventMutex, CacheAware\n{\n    /**\n     * The cache repository implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    public $cache;\n\n    /**\n     * The cache store that should be used.\n     *\n     * @var string|null\n     */\n    public $store;\n\n    /**\n     * Create a new overlapping strategy.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Factory  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        $this->cache = $cache;\n    }\n\n    /**\n     * Attempt to obtain an event mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return bool\n     */\n    public function create(Event $event)\n    {\n        if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {\n            return $this->cache->store($this->store)->getStore()\n                ->lock($event->mutexName(), $event->expiresAt * 60)\n                ->acquire();\n        }\n\n        return $this->cache->store($this->store)->add(\n            $event->mutexName(), true, $event->expiresAt * 60\n        );\n    }\n\n    /**\n     * Determine if an event mutex exists for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return bool\n     */\n    public function exists(Event $event)\n    {\n        if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {\n            return ! $this->cache->store($this->store)->getStore()\n                ->lock($event->mutexName(), $event->expiresAt * 60)\n                ->get(fn () => true);\n        }\n\n        return $this->cache->store($this->store)->has($event->mutexName());\n    }\n\n    /**\n     * Clear the event mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    public function forget(Event $event)\n    {\n        if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {\n            $this->cache->store($this->store)->getStore()\n                ->lock($event->mutexName(), $event->expiresAt * 60)\n                ->forceRelease();\n\n            return;\n        }\n\n        $this->cache->store($this->store)->forget($event->mutexName());\n    }\n\n    /**\n     * Determine if the given store should use locks for cache event mutexes.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @return bool\n     */\n    protected function shouldUseLocks($store)\n    {\n        return $store instanceof LockProvider && ! $store instanceof DynamoDbStore;\n    }\n\n    /**\n     * Specify the cache store that should be used.\n     *\n     * @param  string  $store\n     * @return $this\n     */\n    public function useStore($store)\n    {\n        $this->store = $store;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse DateTimeInterface;\nuse Illuminate\\Cache\\DynamoDbStore;\nuse Illuminate\\Contracts\\Cache\\Factory as Cache;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\n\nclass CacheSchedulingMutex implements SchedulingMutex, CacheAware\n{\n    /**\n     * The cache factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    public $cache;\n\n    /**\n     * The cache store that should be used.\n     *\n     * @var string|null\n     */\n    public $store;\n\n    /**\n     * Create a new scheduling strategy.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Factory  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        $this->cache = $cache;\n    }\n\n    /**\n     * Attempt to obtain a scheduling mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeInterface  $time\n     * @return bool\n     */\n    public function create(Event $event, DateTimeInterface $time)\n    {\n        $mutexName = $event->mutexName().$time->format('Hi');\n\n        if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {\n            return $this->cache->store($this->store)->getStore()\n                ->lock($mutexName, 3600)\n                ->acquire();\n        }\n\n        return $this->cache->store($this->store)->add(\n            $mutexName, true, 3600\n        );\n    }\n\n    /**\n     * Determine if a scheduling mutex exists for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeInterface  $time\n     * @return bool\n     */\n    public function exists(Event $event, DateTimeInterface $time)\n    {\n        $mutexName = $event->mutexName().$time->format('Hi');\n\n        if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {\n            return ! $this->cache->store($this->store)->getStore()\n                ->lock($mutexName, 3600)\n                ->get(fn () => true);\n        }\n\n        return $this->cache->store($this->store)->has($mutexName);\n    }\n\n    /**\n     * Determine if the given store should use locks for cache event mutexes.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Store  $store\n     * @return bool\n     */\n    protected function shouldUseLocks($store)\n    {\n        return $store instanceof LockProvider && ! $store instanceof DynamoDbStore;\n    }\n\n    /**\n     * Specify the cache store that should be used.\n     *\n     * @param  string  $store\n     * @return $this\n     */\n    public function useStore($store)\n    {\n        $this->store = $store;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/CallbackEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Reflector;\nuse InvalidArgumentException;\nuse LogicException;\nuse RuntimeException;\nuse Throwable;\n\nclass CallbackEvent extends Event\n{\n    /**\n     * The callback to call.\n     *\n     * @var string\n     */\n    protected $callback;\n\n    /**\n     * The parameters to pass to the method.\n     *\n     * @var array\n     */\n    protected $parameters;\n\n    /**\n     * The result of the callback's execution.\n     *\n     * @var mixed\n     */\n    protected $result;\n\n    /**\n     * The exception that was thrown when calling the callback, if any.\n     *\n     * @var \\Throwable|null\n     */\n    protected $exception;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\EventMutex  $mutex\n     * @param  string|callable  $callback\n     * @param  array  $parameters\n     * @param  \\DateTimeZone|string|null  $timezone\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct(EventMutex $mutex, $callback, array $parameters = [], $timezone = null)\n    {\n        if (! is_string($callback) && ! Reflector::isCallable($callback)) {\n            throw new InvalidArgumentException(\n                'Invalid scheduled callback event. Must be a string or callable.'\n            );\n        }\n\n        $this->mutex = $mutex;\n        $this->callback = $callback;\n        $this->parameters = $parameters;\n        $this->timezone = $timezone;\n    }\n\n    /**\n     * Run the callback event.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function run(Container $container)\n    {\n        parent::run($container);\n\n        if ($this->exception) {\n            throw $this->exception;\n        }\n\n        return $this->result;\n    }\n\n    /**\n     * Determine if the event should skip because another process is overlapping.\n     *\n     * @return bool\n     */\n    public function shouldSkipDueToOverlapping()\n    {\n        return $this->description && parent::shouldSkipDueToOverlapping();\n    }\n\n    /**\n     * Indicate that the callback should run in the background.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function runInBackground()\n    {\n        throw new RuntimeException('Scheduled closures can not be run in the background.');\n    }\n\n    /**\n     * Run the callback.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return int\n     */\n    protected function execute($container)\n    {\n        try {\n            $this->result = is_object($this->callback)\n                ? $container->call([$this->callback, '__invoke'], $this->parameters)\n                : $container->call($this->callback, $this->parameters);\n\n            return $this->result === false ? 1 : 0;\n        } catch (Throwable $e) {\n            $this->exception = $e;\n\n            return 1;\n        }\n    }\n\n    /**\n     * Do not allow the event to overlap each other.\n     *\n     * The expiration time of the underlying cache lock may be specified in minutes.\n     *\n     * @param  int  $expiresAt\n     * @return $this\n     *\n     * @throws \\LogicException\n     */\n    public function withoutOverlapping($expiresAt = 1440)\n    {\n        if (! isset($this->description)) {\n            throw new LogicException(\n                \"A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'.\"\n            );\n        }\n\n        return parent::withoutOverlapping($expiresAt);\n    }\n\n    /**\n     * Allow the event to only run on one server for each cron expression.\n     *\n     * @return $this\n     *\n     * @throws \\LogicException\n     */\n    public function onOneServer()\n    {\n        if (! isset($this->description)) {\n            throw new LogicException(\n                \"A scheduled event name is required to only run on one server. Use the 'name' method before 'onOneServer'.\"\n            );\n        }\n\n        return parent::onOneServer();\n    }\n\n    /**\n     * Get the summary of the event for display.\n     *\n     * @return string\n     */\n    public function getSummaryForDisplay()\n    {\n        if (is_string($this->description)) {\n            return $this->description;\n        }\n\n        return is_string($this->callback) ? $this->callback : 'Callback';\n    }\n\n    /**\n     * Get the mutex name for the scheduled command.\n     *\n     * @return string\n     */\n    public function mutexName()\n    {\n        return 'framework/schedule-'.sha1($this->description ?? '');\n    }\n\n    /**\n     * Clear the mutex for the event.\n     *\n     * @return void\n     */\n    protected function removeMutex()\n    {\n        if ($this->description) {\n            parent::removeMutex();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/CommandBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Support\\ProcessUtils;\n\nclass CommandBuilder\n{\n    /**\n     * Build the command for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return string\n     */\n    public function buildCommand(Event $event)\n    {\n        if ($event->runInBackground) {\n            return $this->buildBackgroundCommand($event);\n        }\n\n        return $this->buildForegroundCommand($event);\n    }\n\n    /**\n     * Build the command for running the event in the foreground.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return string\n     */\n    protected function buildForegroundCommand(Event $event)\n    {\n        $output = ProcessUtils::escapeArgument($event->output);\n\n        return laravel_cloud()\n            ? $this->ensureCorrectUser($event, $event->command.' 2>&1 | tee '.($event->shouldAppendOutput ? '-a ' : '').$output)\n            : $this->ensureCorrectUser($event, $event->command.($event->shouldAppendOutput ? ' >> ' : ' > ').$output.' 2>&1');\n    }\n\n    /**\n     * Build the command for running the event in the background.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return string\n     */\n    protected function buildBackgroundCommand(Event $event)\n    {\n        $output = ProcessUtils::escapeArgument($event->output);\n\n        $redirect = $event->shouldAppendOutput ? ' >> ' : ' > ';\n\n        $finished = Application::formatCommandString('schedule:finish').' \"'.$event->mutexName().'\"';\n\n        if (windows_os()) {\n            return 'start /b cmd /v:on /c \"('.$event->command.' & '.$finished.' ^!ERRORLEVEL^!)'.$redirect.$output.' 2>&1\"';\n        }\n\n        return $this->ensureCorrectUser($event,\n            '('.$event->command.$redirect.$output.' 2>&1 ; '.$finished.' \"$?\") > '\n            .ProcessUtils::escapeArgument($event->getDefaultOutput()).' 2>&1 &'\n        );\n    }\n\n    /**\n     * Finalize the event's command syntax with the correct user.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  string  $command\n     * @return string\n     */\n    protected function ensureCorrectUser(Event $event, $command)\n    {\n        return $event->user && ! windows_os() ? 'sudo -u '.$event->user.' -- sh -c \\''.$command.'\\'' : $command;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/Event.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Closure;\nuse Cron\\CronExpression;\nuse GuzzleHttp\\Client as HttpClient;\nuse GuzzleHttp\\ClientInterface as HttpClientInterface;\nuse GuzzleHttp\\Exception\\TransferException;\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Mail\\Mailer;\nuse Illuminate\\Log\\Context\\Repository;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Psr\\Http\\Client\\ClientExceptionInterface;\nuse Symfony\\Component\\Process\\Process;\nuse Throwable;\n\nclass Event\n{\n    use Macroable, ManagesAttributes, ManagesFrequencies, ReflectsClosures, Tappable;\n\n    /**\n     * The command string.\n     *\n     * @var string|null\n     */\n    public $command;\n\n    /**\n     * The location that output should be sent to.\n     *\n     * @var string\n     */\n    public $output = '/dev/null';\n\n    /**\n     * Indicates whether output should be appended.\n     *\n     * @var bool\n     */\n    public $shouldAppendOutput = false;\n\n    /**\n     * The array of callbacks to be run before the event is started.\n     *\n     * @var array\n     */\n    protected $beforeCallbacks = [];\n\n    /**\n     * The array of callbacks to be run after the event is finished.\n     *\n     * @var array\n     */\n    protected $afterCallbacks = [];\n\n    /**\n     * The event mutex implementation.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\EventMutex\n     */\n    public $mutex;\n\n    /**\n     * The mutex name resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    public $mutexNameResolver;\n\n    /**\n     * The last time the event was checked for eligibility to run.\n     *\n     * Utilized by sub-minute repeated events.\n     *\n     * @var \\Illuminate\\Support\\Carbon|null\n     */\n    protected $lastChecked;\n\n    /**\n     * The exit status code of the command.\n     *\n     * @var int|null\n     */\n    public $exitCode;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\EventMutex  $mutex\n     * @param  string  $command\n     * @param  \\DateTimeZone|string|null  $timezone\n     */\n    public function __construct(EventMutex $mutex, $command, $timezone = null)\n    {\n        $this->mutex = $mutex;\n        $this->command = $command;\n        $this->timezone = $timezone;\n\n        $this->output = $this->getDefaultOutput();\n    }\n\n    /**\n     * Get the default output depending on the OS.\n     *\n     * @return string\n     */\n    public function getDefaultOutput()\n    {\n        return (DIRECTORY_SEPARATOR === '\\\\') ? 'NUL' : '/dev/null';\n    }\n\n    /**\n     * Run the given event.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function run(Container $container)\n    {\n        if ($this->shouldSkipDueToOverlapping()) {\n            return;\n        }\n\n        $exitCode = $this->start($container);\n\n        if (! $this->runInBackground) {\n            $this->finish($container, $exitCode);\n        }\n    }\n\n    /**\n     * Determine if the event should skip because another process is overlapping.\n     *\n     * @return bool\n     */\n    public function shouldSkipDueToOverlapping()\n    {\n        return $this->withoutOverlapping && ! $this->mutex->create($this);\n    }\n\n    /**\n     * Determine if the event has been configured to repeat multiple times per minute.\n     *\n     * @return bool\n     */\n    public function isRepeatable()\n    {\n        return ! is_null($this->repeatSeconds);\n    }\n\n    /**\n     * Determine if the event is ready to repeat.\n     *\n     * @return bool\n     */\n    public function shouldRepeatNow()\n    {\n        return $this->isRepeatable()\n            && $this->lastChecked?->diffInSeconds() >= $this->repeatSeconds;\n    }\n\n    /**\n     * Run the command process.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    protected function start($container)\n    {\n        try {\n            $this->callBeforeCallbacks($container);\n\n            return $this->execute($container);\n        } catch (Throwable $exception) {\n            $this->removeMutex();\n\n            throw $exception;\n        }\n    }\n\n    /**\n     * Run the command process.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return int\n     */\n    protected function execute($container)\n    {\n        $context = json_encode($container[Repository::class]->dehydrate());\n\n        return Process::fromShellCommandline(\n            $this->buildCommand(), base_path(), ['__LARAVEL_CONTEXT' => $context], null, null\n        )->run(\n            laravel_cloud()\n                ? fn ($type, $line) => fwrite($type === 'out' ? STDOUT : STDERR, $line)\n                : fn () => true\n        );\n    }\n\n    /**\n     * Mark the command process as finished and run callbacks/cleanup.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @param  int  $exitCode\n     * @return void\n     */\n    public function finish(Container $container, $exitCode)\n    {\n        $this->exitCode = (int) $exitCode;\n\n        try {\n            $this->callAfterCallbacks($container);\n        } finally {\n            $this->removeMutex();\n        }\n    }\n\n    /**\n     * Call all of the \"before\" callbacks for the event.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function callBeforeCallbacks(Container $container)\n    {\n        foreach ($this->beforeCallbacks as $callback) {\n            $container->call($callback);\n        }\n    }\n\n    /**\n     * Call all of the \"after\" callbacks for the event.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function callAfterCallbacks(Container $container)\n    {\n        foreach ($this->afterCallbacks as $callback) {\n            $container->call($callback);\n        }\n    }\n\n    /**\n     * Build the command string.\n     *\n     * @return string\n     */\n    public function buildCommand()\n    {\n        return (new CommandBuilder)->buildCommand($this);\n    }\n\n    /**\n     * Determine if the given event should run based on the Cron expression.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return bool\n     */\n    public function isDue($app)\n    {\n        if (! $this->runsInMaintenanceMode() && $app->isDownForMaintenance()) {\n            return false;\n        }\n\n        return $this->expressionPasses() &&\n               $this->runsInEnvironment($app->environment());\n    }\n\n    /**\n     * Determine if the event runs in maintenance mode.\n     *\n     * @return bool\n     */\n    public function runsInMaintenanceMode()\n    {\n        return $this->evenInMaintenanceMode;\n    }\n\n    /**\n     * Determine if the event runs when the scheduler is paused.\n     *\n     * @return bool\n     */\n    public function runsWhenPaused()\n    {\n        return $this->evenWhenPaused;\n    }\n\n    /**\n     * Determine if the Cron expression passes.\n     *\n     * @return bool\n     */\n    protected function expressionPasses()\n    {\n        $date = Date::now();\n\n        if ($this->timezone) {\n            $date = $date->setTimezone($this->timezone);\n        }\n\n        return (new CronExpression($this->expression))->isDue($date->toDateTimeString());\n    }\n\n    /**\n     * Determine if the event runs in the given environment.\n     *\n     * @param  string  $environment\n     * @return bool\n     */\n    public function runsInEnvironment($environment)\n    {\n        return empty($this->environments) || in_array($environment, $this->environments);\n    }\n\n    /**\n     * Determine if the filters pass for the event.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return bool\n     */\n    public function filtersPass($app)\n    {\n        $this->lastChecked = Date::now();\n\n        foreach ($this->filters as $callback) {\n            if (! $app->call($callback)) {\n                return false;\n            }\n        }\n\n        foreach ($this->rejects as $callback) {\n            if ($app->call($callback)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Ensure that the output is stored on disk in a log file.\n     *\n     * @return $this\n     */\n    public function storeOutput()\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        return $this;\n    }\n\n    /**\n     * Send the output of the command to a given location.\n     *\n     * @param  string  $location\n     * @param  bool  $append\n     * @return $this\n     */\n    public function sendOutputTo($location, $append = false)\n    {\n        $this->output = $location;\n\n        $this->shouldAppendOutput = $append;\n\n        return $this;\n    }\n\n    /**\n     * Append the output of the command to a given location.\n     *\n     * @param  string  $location\n     * @return $this\n     */\n    public function appendOutputTo($location)\n    {\n        return $this->sendOutputTo($location, true);\n    }\n\n    /**\n     * E-mail the results of the scheduled operation.\n     *\n     * @param  mixed  $addresses\n     * @param  bool  $onlyIfOutputExists\n     * @return $this\n     *\n     * @throws \\LogicException\n     */\n    public function emailOutputTo($addresses, $onlyIfOutputExists = true)\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        $addresses = Arr::wrap($addresses);\n\n        return $this->then(function (Mailer $mailer) use ($addresses, $onlyIfOutputExists) {\n            $this->emailOutput($mailer, $addresses, $onlyIfOutputExists);\n        });\n    }\n\n    /**\n     * E-mail the results of the scheduled operation if it produces output.\n     *\n     * @param  mixed  $addresses\n     * @return $this\n     *\n     * @throws \\LogicException\n     */\n    public function emailWrittenOutputTo($addresses)\n    {\n        return $this->emailOutputTo($addresses, true);\n    }\n\n    /**\n     * E-mail the results of the scheduled operation if it fails.\n     *\n     * @param  mixed  $addresses\n     * @return $this\n     */\n    public function emailOutputOnFailure($addresses)\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        $addresses = Arr::wrap($addresses);\n\n        return $this->onFailure(function (Mailer $mailer) use ($addresses) {\n            $this->emailOutput($mailer, $addresses, false);\n        });\n    }\n\n    /**\n     * Ensure that the command output is being captured.\n     *\n     * @return void\n     */\n    protected function ensureOutputIsBeingCaptured()\n    {\n        if (is_null($this->output) || $this->output == $this->getDefaultOutput()) {\n            $this->sendOutputTo(storage_path('logs/schedule-'.sha1($this->mutexName()).'.log'));\n        }\n    }\n\n    /**\n     * E-mail the output of the event to the recipients.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailer  $mailer\n     * @param  array  $addresses\n     * @param  bool  $onlyIfOutputExists\n     * @return void\n     */\n    protected function emailOutput(Mailer $mailer, $addresses, $onlyIfOutputExists = true)\n    {\n        $text = is_file($this->output) ? file_get_contents($this->output) : '';\n\n        if ($onlyIfOutputExists && empty($text)) {\n            return;\n        }\n\n        $mailer->raw($text, function ($m) use ($addresses) {\n            $m->to($addresses)->subject($this->getEmailSubject());\n        });\n    }\n\n    /**\n     * Get the e-mail subject line for output results.\n     *\n     * @return string\n     */\n    protected function getEmailSubject()\n    {\n        if ($this->description) {\n            return $this->description;\n        }\n\n        return \"Scheduled Job Output For [{$this->command}]\";\n    }\n\n    /**\n     * Register a callback to ping a given URL before the job runs.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingBefore($url)\n    {\n        return $this->before($this->pingCallback($url));\n    }\n\n    /**\n     * Register a callback to ping a given URL before the job runs if the given condition is true.\n     *\n     * @param  bool  $value\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingBeforeIf($value, $url)\n    {\n        return $value ? $this->pingBefore($url) : $this;\n    }\n\n    /**\n     * Register a callback to ping a given URL after the job runs.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function thenPing($url)\n    {\n        return $this->then($this->pingCallback($url));\n    }\n\n    /**\n     * Register a callback to ping a given URL after the job runs if the given condition is true.\n     *\n     * @param  bool  $value\n     * @param  string  $url\n     * @return $this\n     */\n    public function thenPingIf($value, $url)\n    {\n        return $value ? $this->thenPing($url) : $this;\n    }\n\n    /**\n     * Register a callback to ping a given URL if the operation succeeds.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingOnSuccess($url)\n    {\n        return $this->onSuccess($this->pingCallback($url));\n    }\n\n    /**\n     * Register a callback to ping a given URL if the operation succeeds and if the given condition is true.\n     *\n     * @param  bool  $value\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingOnSuccessIf($value, $url)\n    {\n        return $value ? $this->onSuccess($this->pingCallback($url)) : $this;\n    }\n\n    /**\n     * Register a callback to ping a given URL if the operation fails.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingOnFailure($url)\n    {\n        return $this->onFailure($this->pingCallback($url));\n    }\n\n    /**\n     * Register a callback to ping a given URL if the operation fails and if the given condition is true.\n     *\n     * @param  bool  $value\n     * @param  string  $url\n     * @return $this\n     */\n    public function pingOnFailureIf($value, $url)\n    {\n        return $value ? $this->onFailure($this->pingCallback($url)) : $this;\n    }\n\n    /**\n     * Get the callback that pings the given URL.\n     *\n     * @param  string  $url\n     * @return \\Closure\n     */\n    protected function pingCallback($url)\n    {\n        return function (Container $container) use ($url) {\n            try {\n                $this->getHttpClient($container)->request('GET', $url);\n            } catch (ClientExceptionInterface|TransferException $e) {\n                $container->make(ExceptionHandler::class)->report($e);\n            }\n        };\n    }\n\n    /**\n     * Get the Guzzle HTTP client to use to send pings.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\GuzzleHttp\\ClientInterface\n     */\n    protected function getHttpClient(Container $container)\n    {\n        return match (true) {\n            $container->bound(HttpClientInterface::class) => $container->make(HttpClientInterface::class),\n            $container->bound(HttpClient::class) => $container->make(HttpClient::class),\n            default => new HttpClient([\n                'connect_timeout' => 10,\n                'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,\n                'timeout' => 30,\n            ]),\n        };\n    }\n\n    /**\n     * Register a callback to be called before the operation.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function before(Closure $callback)\n    {\n        $this->beforeCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be called after the operation.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function after(Closure $callback)\n    {\n        return $this->then($callback);\n    }\n\n    /**\n     * Register a callback to be called after the operation.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function then(Closure $callback)\n    {\n        $parameters = $this->closureParameterTypes($callback);\n\n        if (Arr::get($parameters, 'output') === Stringable::class) {\n            return $this->thenWithOutput($callback);\n        }\n\n        $this->afterCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback that uses the output after the job runs.\n     *\n     * @param  \\Closure  $callback\n     * @param  bool  $onlyIfOutputExists\n     * @return $this\n     */\n    public function thenWithOutput(Closure $callback, $onlyIfOutputExists = false)\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        return $this->then($this->withOutputCallback($callback, $onlyIfOutputExists));\n    }\n\n    /**\n     * Register a callback to be called if the operation succeeds.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function onSuccess(Closure $callback)\n    {\n        $parameters = $this->closureParameterTypes($callback);\n\n        if (Arr::get($parameters, 'output') === Stringable::class) {\n            return $this->onSuccessWithOutput($callback);\n        }\n\n        return $this->then(function (Container $container) use ($callback) {\n            if ($this->exitCode === 0) {\n                $container->call($callback);\n            }\n        });\n    }\n\n    /**\n     * Register a callback that uses the output if the operation succeeds.\n     *\n     * @param  \\Closure  $callback\n     * @param  bool  $onlyIfOutputExists\n     * @return $this\n     */\n    public function onSuccessWithOutput(Closure $callback, $onlyIfOutputExists = false)\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        return $this->onSuccess($this->withOutputCallback($callback, $onlyIfOutputExists));\n    }\n\n    /**\n     * Register a callback to be called if the operation fails.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function onFailure(Closure $callback)\n    {\n        $parameters = $this->closureParameterTypes($callback);\n\n        if (Arr::get($parameters, 'output') === Stringable::class) {\n            return $this->onFailureWithOutput($callback);\n        }\n\n        return $this->then(function (Container $container) use ($callback) {\n            if ($this->exitCode !== 0) {\n                $container->call($callback);\n            }\n        });\n    }\n\n    /**\n     * Register a callback that uses the output if the operation fails.\n     *\n     * @param  \\Closure  $callback\n     * @param  bool  $onlyIfOutputExists\n     * @return $this\n     */\n    public function onFailureWithOutput(Closure $callback, $onlyIfOutputExists = false)\n    {\n        $this->ensureOutputIsBeingCaptured();\n\n        return $this->onFailure($this->withOutputCallback($callback, $onlyIfOutputExists));\n    }\n\n    /**\n     * Get a callback that provides output.\n     *\n     * @param  \\Closure  $callback\n     * @param  bool  $onlyIfOutputExists\n     * @return \\Closure\n     */\n    protected function withOutputCallback(Closure $callback, $onlyIfOutputExists = false)\n    {\n        return function (Container $container) use ($callback, $onlyIfOutputExists) {\n            $output = $this->output && is_file($this->output) ? file_get_contents($this->output) : '';\n\n            return $onlyIfOutputExists && empty($output)\n                ? null\n                : $container->call($callback, ['output' => new Stringable($output)]);\n        };\n    }\n\n    /**\n     * Get the summary of the event for display.\n     *\n     * @return string\n     */\n    public function getSummaryForDisplay()\n    {\n        if (is_string($this->description)) {\n            return $this->description;\n        }\n\n        return $this->buildCommand();\n    }\n\n    /**\n     * Determine the next due date for an event.\n     *\n     * @param  \\DateTimeInterface|string  $currentTime\n     * @param  int  $nth\n     * @param  bool  $allowCurrentDate\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    public function nextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)\n    {\n        return Date::instance((new CronExpression($this->getExpression()))\n            ->getNextRunDate($currentTime, $nth, $allowCurrentDate, $this->timezone));\n    }\n\n    /**\n     * Get the Cron expression for the event.\n     *\n     * @return string\n     */\n    public function getExpression()\n    {\n        return $this->expression;\n    }\n\n    /**\n     * Set the event mutex implementation to be used.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\EventMutex  $mutex\n     * @return $this\n     */\n    public function preventOverlapsUsing(EventMutex $mutex)\n    {\n        $this->mutex = $mutex;\n\n        return $this;\n    }\n\n    /**\n     * Get the mutex name for the scheduled command.\n     *\n     * @return string\n     */\n    public function mutexName()\n    {\n        $mutexNameResolver = $this->mutexNameResolver;\n\n        if (! is_null($mutexNameResolver) && is_callable($mutexNameResolver)) {\n            return $mutexNameResolver($this);\n        }\n\n        return 'framework'.DIRECTORY_SEPARATOR.'schedule-'.\n            sha1($this->expression.$this->normalizeCommand($this->command ?? ''));\n    }\n\n    /**\n     * Set the mutex name or name resolver callback.\n     *\n     * @param  \\Closure|string  $mutexName\n     * @return $this\n     */\n    public function createMutexNameUsing(Closure|string $mutexName)\n    {\n        $this->mutexNameResolver = is_string($mutexName) ? fn () => $mutexName : $mutexName;\n\n        return $this;\n    }\n\n    /**\n     * Delete the mutex for the event.\n     *\n     * @return void\n     */\n    protected function removeMutex()\n    {\n        if ($this->withoutOverlapping) {\n            $this->mutex->forget($this);\n        }\n    }\n\n    /**\n     * Format the given command string with a normalized PHP binary path.\n     *\n     * @param  string  $command\n     * @return string\n     */\n    public static function normalizeCommand($command)\n    {\n        return str_replace([\n            Application::phpBinary(),\n            Application::artisanBinary(),\n        ], [\n            'php',\n            preg_replace(\"#['\\\"]#\", '', Application::artisanBinary()),\n        ], $command);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/EventMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\ninterface EventMutex\n{\n    /**\n     * Attempt to obtain an event mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return bool\n     */\n    public function create(Event $event);\n\n    /**\n     * Determine if an event mutex exists for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return bool\n     */\n    public function exists(Event $event);\n\n    /**\n     * Clear the event mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    public function forget(Event $event);\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ManagesAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Support\\Reflector;\n\ntrait ManagesAttributes\n{\n    /**\n     * The cron expression representing the event's frequency.\n     *\n     * @var string\n     */\n    public $expression = '* * * * *';\n\n    /**\n     * How often to repeat the event during a minute.\n     *\n     * @var int|null\n     */\n    public $repeatSeconds = null;\n\n    /**\n     * The timezone the date should be evaluated on.\n     *\n     * @var \\DateTimeZone|string\n     */\n    public $timezone;\n\n    /**\n     * The user the command should run as.\n     *\n     * @var string|null\n     */\n    public $user;\n\n    /**\n     * The list of environments the command should run under.\n     *\n     * @var array\n     */\n    public $environments = [];\n\n    /**\n     * Indicates if the command should run in maintenance mode.\n     *\n     * @var bool\n     */\n    public $evenInMaintenanceMode = false;\n\n    /**\n     * Indicates if the command should run even when the scheduler is paused.\n     *\n     * @var bool\n     */\n    public $evenWhenPaused = false;\n\n    /**\n     * Indicates if the command should not overlap itself.\n     *\n     * @var bool\n     */\n    public $withoutOverlapping = false;\n\n    /**\n     * Indicates if the command should only be allowed to run on one server for each cron expression.\n     *\n     * @var bool\n     */\n    public $onOneServer = false;\n\n    /**\n     * The number of minutes the mutex should be valid.\n     *\n     * @var int\n     */\n    public $expiresAt = 1440;\n\n    /**\n     * Indicates if the command should run in the background.\n     *\n     * @var bool\n     */\n    public $runInBackground = false;\n\n    /**\n     * The array of filter callbacks.\n     *\n     * @var array\n     */\n    protected $filters = [];\n\n    /**\n     * The array of reject callbacks.\n     *\n     * @var array\n     */\n    protected $rejects = [];\n\n    /**\n     * The human-readable description of the event.\n     *\n     * @var string|null\n     */\n    public $description;\n\n    /**\n     * Set which user the command should run as.\n     *\n     * @param  string  $user\n     * @return $this\n     */\n    public function user($user)\n    {\n        $this->user = $user;\n\n        return $this;\n    }\n\n    /**\n     * Limit the environments the command should run in.\n     *\n     * @param  mixed  $environments\n     * @return $this\n     */\n    public function environments($environments)\n    {\n        $this->environments = is_array($environments) ? $environments : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * State that the command should run even in maintenance mode.\n     *\n     * @return $this\n     */\n    public function evenInMaintenanceMode()\n    {\n        $this->evenInMaintenanceMode = true;\n\n        return $this;\n    }\n\n    /**\n     * State that the command should run even when the scheduler is paused.\n     *\n     * @return $this\n     */\n    public function evenWhenPaused()\n    {\n        $this->evenWhenPaused = true;\n\n        return $this;\n    }\n\n    /**\n     * Do not allow the event to overlap each other.\n     * The expiration time of the underlying cache lock may be specified in minutes.\n     *\n     * @param  int  $expiresAt\n     * @return $this\n     */\n    public function withoutOverlapping($expiresAt = 1440)\n    {\n        $this->withoutOverlapping = true;\n\n        $this->expiresAt = $expiresAt;\n\n        return $this->skip(function () {\n            return $this->mutex->exists($this);\n        });\n    }\n\n    /**\n     * Allow the event to only run on one server for each cron expression.\n     *\n     * @return $this\n     */\n    public function onOneServer()\n    {\n        $this->onOneServer = true;\n\n        return $this;\n    }\n\n    /**\n     * State that the command should run in the background.\n     *\n     * @return $this\n     */\n    public function runInBackground()\n    {\n        $this->runInBackground = true;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to further filter the schedule.\n     *\n     * @param  \\Closure|bool  $callback\n     * @return $this\n     */\n    public function when($callback)\n    {\n        $this->filters[] = Reflector::isCallable($callback) ? $callback : function () use ($callback) {\n            return $callback;\n        };\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to further filter the schedule.\n     *\n     * @param  \\Closure|bool  $callback\n     * @return $this\n     */\n    public function skip($callback)\n    {\n        $this->rejects[] = Reflector::isCallable($callback) ? $callback : function () use ($callback) {\n            return $callback;\n        };\n\n        return $this;\n    }\n\n    /**\n     * Set the human-friendly description of the event.\n     *\n     * @param  string  $description\n     * @return $this\n     */\n    public function name($description)\n    {\n        return $this->description($description);\n    }\n\n    /**\n     * Set the human-friendly description of the event.\n     *\n     * @param  string  $description\n     * @return $this\n     */\n    public function description($description)\n    {\n        $this->description = $description;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ManagesFrequencies.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Support\\Carbon;\nuse InvalidArgumentException;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait ManagesFrequencies\n{\n    /**\n     * The Cron expression representing the event's frequency.\n     *\n     * @param  string  $expression\n     * @return $this\n     */\n    public function cron($expression)\n    {\n        $this->expression = $expression;\n\n        return $this;\n    }\n\n    /**\n     * Schedule the event to run between start and end time.\n     *\n     * @param  string  $startTime\n     * @param  string  $endTime\n     * @return $this\n     */\n    public function between($startTime, $endTime)\n    {\n        return $this->when($this->inTimeInterval($startTime, $endTime));\n    }\n\n    /**\n     * Schedule the event to not run between start and end time.\n     *\n     * @param  string  $startTime\n     * @param  string  $endTime\n     * @return $this\n     */\n    public function unlessBetween($startTime, $endTime)\n    {\n        return $this->skip($this->inTimeInterval($startTime, $endTime));\n    }\n\n    /**\n     * Schedule the event to run between start and end time.\n     *\n     * @param  string  $startTime\n     * @param  string  $endTime\n     * @return \\Closure\n     */\n    private function inTimeInterval($startTime, $endTime)\n    {\n        [$now, $startTime, $endTime] = [\n            Carbon::now($this->timezone),\n            Carbon::parse($startTime, $this->timezone),\n            Carbon::parse($endTime, $this->timezone),\n        ];\n\n        if ($endTime->lessThan($startTime)) {\n            if ($startTime->greaterThan($now)) {\n                $startTime = $startTime->subDay();\n            } else {\n                $endTime = $endTime->addDay();\n            }\n        }\n\n        return fn () => $now->between($startTime, $endTime);\n    }\n\n    /**\n     * Schedule the event to run every second.\n     *\n     * @return $this\n     */\n    public function everySecond()\n    {\n        return $this->repeatEvery(1);\n    }\n\n    /**\n     * Schedule the event to run every two seconds.\n     *\n     * @return $this\n     */\n    public function everyTwoSeconds()\n    {\n        return $this->repeatEvery(2);\n    }\n\n    /**\n     * Schedule the event to run every five seconds.\n     *\n     * @return $this\n     */\n    public function everyFiveSeconds()\n    {\n        return $this->repeatEvery(5);\n    }\n\n    /**\n     * Schedule the event to run every ten seconds.\n     *\n     * @return $this\n     */\n    public function everyTenSeconds()\n    {\n        return $this->repeatEvery(10);\n    }\n\n    /**\n     * Schedule the event to run every fifteen seconds.\n     *\n     * @return $this\n     */\n    public function everyFifteenSeconds()\n    {\n        return $this->repeatEvery(15);\n    }\n\n    /**\n     * Schedule the event to run every twenty seconds.\n     *\n     * @return $this\n     */\n    public function everyTwentySeconds()\n    {\n        return $this->repeatEvery(20);\n    }\n\n    /**\n     * Schedule the event to run every thirty seconds.\n     *\n     * @return $this\n     */\n    public function everyThirtySeconds()\n    {\n        return $this->repeatEvery(30);\n    }\n\n    /**\n     * Schedule the event to run multiple times per minute.\n     *\n     * @param  int<1, 59>  $seconds\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function repeatEvery($seconds)\n    {\n        if ($seconds <= 0) {\n            throw new InvalidArgumentException(\"The seconds [$seconds] must be greater than zero.\");\n        }\n\n        if (60 % $seconds !== 0) {\n            throw new InvalidArgumentException(\"The seconds [$seconds] are not evenly divisible by 60.\");\n        }\n\n        $this->repeatSeconds = $seconds;\n\n        return $this->everyMinute();\n    }\n\n    /**\n     * Schedule the event to run every minute.\n     *\n     * @return $this\n     */\n    public function everyMinute()\n    {\n        return $this->spliceIntoPosition(1, '*');\n    }\n\n    /**\n     * Schedule the event to run every two minutes.\n     *\n     * @return $this\n     */\n    public function everyTwoMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/2');\n    }\n\n    /**\n     * Schedule the event to run every three minutes.\n     *\n     * @return $this\n     */\n    public function everyThreeMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/3');\n    }\n\n    /**\n     * Schedule the event to run every four minutes.\n     *\n     * @return $this\n     */\n    public function everyFourMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/4');\n    }\n\n    /**\n     * Schedule the event to run every five minutes.\n     *\n     * @return $this\n     */\n    public function everyFiveMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/5');\n    }\n\n    /**\n     * Schedule the event to run every ten minutes.\n     *\n     * @return $this\n     */\n    public function everyTenMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/10');\n    }\n\n    /**\n     * Schedule the event to run every fifteen minutes.\n     *\n     * @return $this\n     */\n    public function everyFifteenMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/15');\n    }\n\n    /**\n     * Schedule the event to run every thirty minutes.\n     *\n     * @return $this\n     */\n    public function everyThirtyMinutes()\n    {\n        return $this->spliceIntoPosition(1, '*/30');\n    }\n\n    /**\n     * Schedule the event to run hourly.\n     *\n     * @return $this\n     */\n    public function hourly()\n    {\n        return $this->spliceIntoPosition(1, 0);\n    }\n\n    /**\n     * Schedule the event to run hourly at a given offset in the hour.\n     *\n     * @param  array|string|int<0, 59>|int<0, 59>[]  $offset\n     * @return $this\n     */\n    public function hourlyAt($offset)\n    {\n        return $this->hourBasedSchedule($offset, '*');\n    }\n\n    /**\n     * Schedule the event to run every odd hour.\n     *\n     * @param  array|string|int  $offset\n     * @return $this\n     */\n    public function everyOddHour($offset = 0)\n    {\n        return $this->hourBasedSchedule($offset, '1-23/2');\n    }\n\n    /**\n     * Schedule the event to run every two hours.\n     *\n     * @param  array|string|int  $offset\n     * @return $this\n     */\n    public function everyTwoHours($offset = 0)\n    {\n        return $this->hourBasedSchedule($offset, '*/2');\n    }\n\n    /**\n     * Schedule the event to run every three hours.\n     *\n     * @param  array|string|int  $offset\n     * @return $this\n     */\n    public function everyThreeHours($offset = 0)\n    {\n        return $this->hourBasedSchedule($offset, '*/3');\n    }\n\n    /**\n     * Schedule the event to run every four hours.\n     *\n     * @param  array|string|int  $offset\n     * @return $this\n     */\n    public function everyFourHours($offset = 0)\n    {\n        return $this->hourBasedSchedule($offset, '*/4');\n    }\n\n    /**\n     * Schedule the event to run every six hours.\n     *\n     * @param  array|string|int  $offset\n     * @return $this\n     */\n    public function everySixHours($offset = 0)\n    {\n        return $this->hourBasedSchedule($offset, '*/6');\n    }\n\n    /**\n     * Schedule the event to run daily.\n     *\n     * @return $this\n     */\n    public function daily()\n    {\n        return $this->hourBasedSchedule(0, 0);\n    }\n\n    /**\n     * Schedule the command at a given time.\n     *\n     * @param  string  $time\n     * @return $this\n     */\n    public function at($time)\n    {\n        return $this->dailyAt($time);\n    }\n\n    /**\n     * Schedule the event to run daily at a given time (10:00, 19:30, etc).\n     *\n     * @param  string  $time\n     * @return $this\n     */\n    public function dailyAt($time)\n    {\n        $segments = explode(':', $time);\n\n        return $this->hourBasedSchedule(\n            count($segments) >= 2 ? (int) $segments[1] : '0',\n            (int) $segments[0]\n        );\n    }\n\n    /**\n     * Schedule the event to run twice daily.\n     *\n     * @param  int<0, 23>  $first\n     * @param  int<0, 23>  $second\n     * @return $this\n     */\n    public function twiceDaily($first = 1, $second = 13)\n    {\n        return $this->twiceDailyAt($first, $second, 0);\n    }\n\n    /**\n     * Schedule the event to run twice daily at a given offset.\n     *\n     * @param  int<0, 23>  $first\n     * @param  int<0, 23>  $second\n     * @param  int<0, 59>  $offset\n     * @return $this\n     */\n    public function twiceDailyAt($first = 1, $second = 13, $offset = 0)\n    {\n        $hours = $first.','.$second;\n\n        return $this->hourBasedSchedule($offset, $hours);\n    }\n\n    /**\n     * Schedule the event to run at the given minutes and hours.\n     *\n     * @param  array|string|int<0, 59>  $minutes\n     * @param  array|string|int<0, 23>  $hours\n     * @return $this\n     */\n    protected function hourBasedSchedule($minutes, $hours)\n    {\n        $minutes = is_array($minutes) ? implode(',', $minutes) : $minutes;\n\n        $hours = is_array($hours) ? implode(',', $hours) : $hours;\n\n        return $this->spliceIntoPosition(1, $minutes)\n            ->spliceIntoPosition(2, $hours);\n    }\n\n    /**\n     * Schedule the event to run only on weekdays.\n     *\n     * @return $this\n     */\n    public function weekdays()\n    {\n        return $this->days(Schedule::MONDAY.'-'.Schedule::FRIDAY);\n    }\n\n    /**\n     * Schedule the event to run only on weekends.\n     *\n     * @return $this\n     */\n    public function weekends()\n    {\n        return $this->days(Schedule::SATURDAY.','.Schedule::SUNDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Mondays.\n     *\n     * @return $this\n     */\n    public function mondays()\n    {\n        return $this->days(Schedule::MONDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Tuesdays.\n     *\n     * @return $this\n     */\n    public function tuesdays()\n    {\n        return $this->days(Schedule::TUESDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Wednesdays.\n     *\n     * @return $this\n     */\n    public function wednesdays()\n    {\n        return $this->days(Schedule::WEDNESDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Thursdays.\n     *\n     * @return $this\n     */\n    public function thursdays()\n    {\n        return $this->days(Schedule::THURSDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Fridays.\n     *\n     * @return $this\n     */\n    public function fridays()\n    {\n        return $this->days(Schedule::FRIDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Saturdays.\n     *\n     * @return $this\n     */\n    public function saturdays()\n    {\n        return $this->days(Schedule::SATURDAY);\n    }\n\n    /**\n     * Schedule the event to run only on Sundays.\n     *\n     * @return $this\n     */\n    public function sundays()\n    {\n        return $this->days(Schedule::SUNDAY);\n    }\n\n    /**\n     * Schedule the event to run weekly.\n     *\n     * @return $this\n     */\n    public function weekly()\n    {\n        return $this->spliceIntoPosition(1, 0)\n            ->spliceIntoPosition(2, 0)\n            ->spliceIntoPosition(5, 0);\n    }\n\n    /**\n     * Schedule the event to run weekly on a given day and time.\n     *\n     * @param  mixed  $dayOfWeek\n     * @param  string  $time\n     * @return $this\n     */\n    public function weeklyOn($dayOfWeek, $time = '0:0')\n    {\n        $this->dailyAt($time);\n\n        return $this->days($dayOfWeek);\n    }\n\n    /**\n     * Schedule the event to run monthly.\n     *\n     * @return $this\n     */\n    public function monthly()\n    {\n        return $this->spliceIntoPosition(1, 0)\n            ->spliceIntoPosition(2, 0)\n            ->spliceIntoPosition(3, 1);\n    }\n\n    /**\n     * Schedule the event to run monthly on a given day and time.\n     *\n     * @param  int<1, 31>  $dayOfMonth\n     * @param  string  $time\n     * @return $this\n     */\n    public function monthlyOn($dayOfMonth = 1, $time = '0:0')\n    {\n        $this->dailyAt($time);\n\n        return $this->spliceIntoPosition(3, $dayOfMonth);\n    }\n\n    /**\n     * Schedule the event to run twice monthly at a given time.\n     *\n     * @param  int<1, 31>  $first\n     * @param  int<1, 31>  $second\n     * @param  string  $time\n     * @return $this\n     */\n    public function twiceMonthly($first = 1, $second = 16, $time = '0:0')\n    {\n        $daysOfMonth = $first.','.$second;\n\n        $this->dailyAt($time);\n\n        return $this->spliceIntoPosition(3, $daysOfMonth);\n    }\n\n    /**\n     * Schedule the event to run on the last day of the month.\n     *\n     * @param  string  $time\n     * @return $this\n     */\n    public function lastDayOfMonth($time = '0:0')\n    {\n        $this->dailyAt($time);\n\n        return $this->spliceIntoPosition(3, Carbon::now()->endOfMonth()->day);\n    }\n\n    /**\n     * Schedule the event to run on specific days of the month.\n     *\n     * @param  array<int<1, 31>>|int<1, 31>  ...$days\n     * @return $this\n     */\n    public function daysOfMonth(...$days)\n    {\n        $days = count($days) === 1 && is_array($days[0]) ? $days[0] : $days;\n\n        $this->dailyAt('0:0');\n\n        return $this->spliceIntoPosition(3, implode(',', $days));\n    }\n\n    /**\n     * Schedule the event to run quarterly.\n     *\n     * @return $this\n     */\n    public function quarterly()\n    {\n        return $this->spliceIntoPosition(1, 0)\n            ->spliceIntoPosition(2, 0)\n            ->spliceIntoPosition(3, 1)\n            ->spliceIntoPosition(4, '1-12/3');\n    }\n\n    /**\n     * Schedule the event to run quarterly on a given day and time.\n     *\n     * @param  int  $dayOfQuarter\n     * @param  string  $time\n     * @return $this\n     */\n    public function quarterlyOn($dayOfQuarter = 1, $time = '0:0')\n    {\n        $this->dailyAt($time);\n\n        return $this->spliceIntoPosition(3, $dayOfQuarter)\n            ->spliceIntoPosition(4, '1-12/3');\n    }\n\n    /**\n     * Schedule the event to run yearly.\n     *\n     * @return $this\n     */\n    public function yearly()\n    {\n        return $this->spliceIntoPosition(1, 0)\n            ->spliceIntoPosition(2, 0)\n            ->spliceIntoPosition(3, 1)\n            ->spliceIntoPosition(4, 1);\n    }\n\n    /**\n     * Schedule the event to run yearly on a given month, day, and time.\n     *\n     * @param  int  $month\n     * @param  int<1, 31>|string  $dayOfMonth\n     * @param  string  $time\n     * @return $this\n     */\n    public function yearlyOn($month = 1, $dayOfMonth = 1, $time = '0:0')\n    {\n        $this->dailyAt($time);\n\n        return $this->spliceIntoPosition(3, $dayOfMonth)\n            ->spliceIntoPosition(4, $month);\n    }\n\n    /**\n     * Set the days of the week the command should run on.\n     *\n     * @param  mixed  $days\n     * @return $this\n     */\n    public function days($days)\n    {\n        $days = is_array($days) ? $days : func_get_args();\n\n        return $this->spliceIntoPosition(5, implode(',', $days));\n    }\n\n    /**\n     * Set the timezone the date should be evaluated on.\n     *\n     * @param  \\UnitEnum|\\DateTimeZone|string  $timezone\n     * @return $this\n     */\n    public function timezone($timezone)\n    {\n        $this->timezone = enum_value($timezone);\n\n        return $this;\n    }\n\n    /**\n     * Splice the given value into the given position of the expression.\n     *\n     * @param  int  $position\n     * @param  string|int  $value\n     * @return $this\n     */\n    protected function spliceIntoPosition($position, $value)\n    {\n        $segments = preg_split(\"/\\s+/\", $this->expression);\n\n        $segments[$position - 1] = $value;\n\n        return $this->cron(implode(' ', $segments));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/PendingEventAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\n/**\n * @mixin \\Illuminate\\Console\\Scheduling\\Schedule\n */\nclass PendingEventAttributes\n{\n    use ManagesAttributes, ManagesFrequencies;\n\n    /**\n     * The recorded macro calls to replay on each event.\n     *\n     * @var array<int, array{string, array}>\n     */\n    protected array $macros = [];\n\n    /**\n     * Create a new pending event attributes instance.\n     */\n    public function __construct(\n        protected Schedule $schedule,\n    ) {\n    }\n\n    /**\n     * Do not allow the event to overlap each other.\n     *\n     * The expiration time of the underlying cache lock may be specified in minutes.\n     *\n     * @param  int  $expiresAt\n     * @return $this\n     */\n    public function withoutOverlapping($expiresAt = 1440)\n    {\n        $this->withoutOverlapping = true;\n\n        $this->expiresAt = $expiresAt;\n\n        return $this;\n    }\n\n    /**\n     * Merge the current attributes into the given event.\n     */\n    public function mergeAttributes(Event $event): void\n    {\n        $event->expression = $this->expression;\n        $event->repeatSeconds = $this->repeatSeconds;\n\n        if ($this->description !== null) {\n            $event->name($this->description);\n        }\n\n        if ($this->timezone !== null) {\n            $event->timezone($this->timezone);\n        }\n\n        if ($this->user !== null) {\n            $event->user = $this->user;\n        }\n\n        if (! empty($this->environments)) {\n            $event->environments($this->environments);\n        }\n\n        if ($this->evenInMaintenanceMode) {\n            $event->evenInMaintenanceMode();\n        }\n\n        if ($this->evenWhenPaused) {\n            $event->evenWhenPaused();\n        }\n\n        if ($this->withoutOverlapping) {\n            $event->withoutOverlapping($this->expiresAt);\n        }\n\n        if ($this->onOneServer) {\n            $event->onOneServer();\n        }\n\n        if ($this->runInBackground) {\n            $event->runInBackground();\n        }\n\n        foreach ($this->filters as $filter) {\n            $event->when($filter);\n        }\n\n        foreach ($this->rejects as $reject) {\n            $event->skip($reject);\n        }\n\n        foreach ($this->macros as [$method, $parameters]) {\n            $event->{$method}(...$parameters);\n        }\n    }\n\n    /**\n     * Proxy missing methods onto the underlying schedule.\n     */\n    public function __call(string $method, array $parameters): mixed\n    {\n        if (Event::hasMacro($method)) {\n            $this->macros[] = [$method, $parameters];\n\n            return $this;\n        }\n\n        return $this->schedule->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/Schedule.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse BadMethodCallException;\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ProcessUtils;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Command\\Command as SymfonyCommand;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @mixin \\Illuminate\\Console\\Scheduling\\PendingEventAttributes\n */\nclass Schedule\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    const SUNDAY = 0;\n\n    const MONDAY = 1;\n\n    const TUESDAY = 2;\n\n    const WEDNESDAY = 3;\n\n    const THURSDAY = 4;\n\n    const FRIDAY = 5;\n\n    const SATURDAY = 6;\n\n    /**\n     * All of the events on the schedule.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\Event[]\n     */\n    protected $events = [];\n\n    /**\n     * The event mutex implementation.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\EventMutex\n     */\n    protected $eventMutex;\n\n    /**\n     * The scheduling mutex implementation.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\SchedulingMutex\n     */\n    protected $schedulingMutex;\n\n    /**\n     * The timezone the date should be evaluated on.\n     *\n     * @var \\DateTimeZone|string\n     */\n    protected $timezone;\n\n    /**\n     * The job dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Bus\\Dispatcher\n     */\n    protected $dispatcher;\n\n    /**\n     * The cache of mutex results.\n     *\n     * @var array<string, bool>\n     */\n    protected $mutexCache = [];\n\n    /**\n     * The attributes to pass to the event.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\PendingEventAttributes|null\n     */\n    protected $attributes;\n\n    /**\n     * The schedule group attributes stack.\n     *\n     * @var array<int, PendingEventAttributes>\n     */\n    protected array $groupStack = [];\n\n    /**\n     * Create a new schedule instance.\n     *\n     * @param  \\DateTimeZone|string|null  $timezone\n     *\n     * @throws \\RuntimeException\n     */\n    public function __construct($timezone = null)\n    {\n        $this->timezone = $timezone;\n\n        if (! class_exists(Container::class)) {\n            throw new RuntimeException(\n                'A container implementation is required to use the scheduler. Please install the illuminate/container package.'\n            );\n        }\n\n        $container = Container::getInstance();\n\n        $this->eventMutex = $container->bound(EventMutex::class)\n            ? $container->make(EventMutex::class)\n            : $container->make(CacheEventMutex::class);\n\n        $this->schedulingMutex = $container->bound(SchedulingMutex::class)\n            ? $container->make(SchedulingMutex::class)\n            : $container->make(CacheSchedulingMutex::class);\n    }\n\n    /**\n     * Add a new callback event to the schedule.\n     *\n     * @param  string|callable  $callback\n     * @param  array  $parameters\n     * @return \\Illuminate\\Console\\Scheduling\\CallbackEvent\n     */\n    public function call($callback, array $parameters = [])\n    {\n        $this->events[] = $event = new CallbackEvent(\n            $this->eventMutex, $callback, $parameters, $this->timezone\n        );\n\n        $this->mergePendingAttributes($event);\n\n        return $event;\n    }\n\n    /**\n     * Add a new Artisan command event to the schedule.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $parameters\n     * @return \\Illuminate\\Console\\Scheduling\\Event\n     */\n    public function command($command, array $parameters = [])\n    {\n        if ($command instanceof SymfonyCommand) {\n            $command = get_class($command);\n\n            $command = Container::getInstance()->make($command);\n\n            return $this->exec(\n                Application::formatCommandString($command->getName()), $parameters,\n            )->description($command->getDescription());\n        }\n\n        if (class_exists($command)) {\n            $command = Container::getInstance()->make($command);\n\n            return $this->exec(\n                Application::formatCommandString($command->getName()), $parameters,\n            )->description($command->getDescription());\n        }\n\n        return $this->exec(\n            Application::formatCommandString($command), $parameters\n        );\n    }\n\n    /**\n     * Add a new job callback event to the schedule.\n     *\n     * @param  object|string  $job\n     * @param  \\UnitEnum|string|null  $queue\n     * @param  \\UnitEnum|string|null  $connection\n     * @return \\Illuminate\\Console\\Scheduling\\CallbackEvent\n     */\n    public function job($job, $queue = null, $connection = null)\n    {\n        $jobName = $job;\n\n        $queue = enum_value($queue);\n        $connection = enum_value($connection);\n\n        if (! is_string($job)) {\n            $jobName = method_exists($job, 'displayName')\n                ? $job->displayName()\n                : $job::class;\n        }\n\n        $this->events[] = $event = new CallbackEvent(\n            $this->eventMutex, function () use ($job, $queue, $connection) {\n                $job = is_string($job) ? Container::getInstance()->make($job) : $job;\n\n                if ($job instanceof ShouldQueue) {\n                    $this->dispatchToQueue($job, $queue ?? $job->queue, $connection ?? $job->connection);\n                } else {\n                    $this->dispatchNow($job);\n                }\n            }, [], $this->timezone\n        );\n\n        $event->name($jobName);\n\n        $this->mergePendingAttributes($event);\n\n        return $event;\n    }\n\n    /**\n     * Dispatch the given job to the queue.\n     *\n     * @param  object  $job\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function dispatchToQueue($job, $queue, $connection)\n    {\n        if ($job instanceof Closure) {\n            if (! class_exists(CallQueuedClosure::class)) {\n                throw new RuntimeException(\n                    'To enable support for closure jobs, please install the illuminate/queue package.'\n                );\n            }\n\n            $job = CallQueuedClosure::create($job);\n        }\n\n        if ($job instanceof ShouldBeUnique) {\n            return $this->dispatchUniqueJobToQueue($job, $queue, $connection);\n        }\n\n        $this->getDispatcher()->dispatch(\n            $job->onConnection($connection)->onQueue($queue)\n        );\n    }\n\n    /**\n     * Dispatch the given unique job to the queue.\n     *\n     * @param  object  $job\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function dispatchUniqueJobToQueue($job, $queue, $connection)\n    {\n        if (! Container::getInstance()->bound(Cache::class)) {\n            throw new RuntimeException('Cache driver not available. Scheduling unique jobs not supported.');\n        }\n\n        if (! (new UniqueLock(Container::getInstance()->make(Cache::class)))->acquire($job)) {\n            return;\n        }\n\n        $this->getDispatcher()->dispatch(\n            $job->onConnection($connection)->onQueue($queue)\n        );\n    }\n\n    /**\n     * Dispatch the given job right now.\n     *\n     * @param  object  $job\n     * @return void\n     */\n    protected function dispatchNow($job)\n    {\n        $this->getDispatcher()->dispatchNow($job);\n    }\n\n    /**\n     * Add a new command event to the schedule.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @return \\Illuminate\\Console\\Scheduling\\Event\n     */\n    public function exec($command, array $parameters = [])\n    {\n        if (count($parameters)) {\n            $command .= ' '.$this->compileParameters($parameters);\n        }\n\n        $this->events[] = $event = new Event($this->eventMutex, $command, $this->timezone);\n\n        $this->mergePendingAttributes($event);\n\n        return $event;\n    }\n\n    /**\n     * Create new schedule group.\n     *\n     * @param  \\Closure  $events\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function group(Closure $events)\n    {\n        if ($this->attributes === null) {\n            throw new RuntimeException('Invoke an attribute method such as Schedule::daily() before defining a schedule group.');\n        }\n\n        $this->groupStack[] = $this->attributes;\n        $this->attributes = null;\n\n        $events($this);\n\n        array_pop($this->groupStack);\n    }\n\n    /**\n     * Merge the current group attributes with the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    protected function mergePendingAttributes(Event $event)\n    {\n        if (! empty($this->groupStack)) {\n            $group = array_last($this->groupStack);\n\n            $group->mergeAttributes($event);\n        }\n\n        if (isset($this->attributes)) {\n            $this->attributes->mergeAttributes($event);\n\n            $this->attributes = null;\n        }\n    }\n\n    /**\n     * Compile parameters for a command.\n     *\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function compileParameters(array $parameters)\n    {\n        return (new Collection($parameters))->map(function ($value, $key) {\n            if (is_array($value)) {\n                return $this->compileArrayInput($key, $value);\n            }\n\n            if (! is_numeric($value) && ! preg_match('/^(-.$|--.*)/i', $value)) {\n                $value = ProcessUtils::escapeArgument($value);\n            }\n\n            return is_numeric($key) ? $value : \"{$key}={$value}\";\n        })->implode(' ');\n    }\n\n    /**\n     * Compile array input for a command.\n     *\n     * @param  string|int  $key\n     * @param  array  $value\n     * @return string\n     */\n    public function compileArrayInput($key, $value)\n    {\n        $value = (new Collection($value))->map(function ($value) {\n            return ProcessUtils::escapeArgument($value);\n        });\n\n        if (str_starts_with($key, '--')) {\n            $value = $value->map(function ($value) use ($key) {\n                return \"{$key}={$value}\";\n            });\n        } elseif (str_starts_with($key, '-')) {\n            $value = $value->map(function ($value) use ($key) {\n                return \"{$key} {$value}\";\n            });\n        }\n\n        return $value->implode(' ');\n    }\n\n    /**\n     * Determine if the server is allowed to run this event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeInterface  $time\n     * @return bool\n     */\n    public function serverShouldRun(Event $event, DateTimeInterface $time)\n    {\n        return $this->mutexCache[$event->mutexName()] ??= $this->schedulingMutex->create($event, $time);\n    }\n\n    /**\n     * Get all of the events on the schedule that are due.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function dueEvents($app)\n    {\n        return (new Collection($this->events))->filter->isDue($app);\n    }\n\n    /**\n     * Get all of the events on the schedule.\n     *\n     * @return \\Illuminate\\Console\\Scheduling\\Event[]\n     */\n    public function events()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Specify the cache store that should be used to store mutexes.\n     *\n     * @param  \\UnitEnum|string  $store\n     * @return $this\n     */\n    public function useCache($store)\n    {\n        $store = enum_value($store);\n\n        if ($this->eventMutex instanceof CacheAware) {\n            $this->eventMutex->useStore($store);\n        }\n\n        if ($this->schedulingMutex instanceof CacheAware) {\n            $this->schedulingMutex->useStore($store);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the job dispatcher, if available.\n     *\n     * @return \\Illuminate\\Contracts\\Bus\\Dispatcher\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getDispatcher()\n    {\n        if ($this->dispatcher === null) {\n            try {\n                $this->dispatcher = Container::getInstance()->make(Dispatcher::class);\n            } catch (BindingResolutionException $e) {\n                throw new RuntimeException(\n                    'Unable to resolve the dispatcher from the service container. Please bind it or install the illuminate/bus package.',\n                    is_int($e->getCode()) ? $e->getCode() : 0, $e\n                );\n            }\n        }\n\n        return $this->dispatcher;\n    }\n\n    /**\n     * Dynamically handle calls into the schedule instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (method_exists(PendingEventAttributes::class, $method) || Event::hasMacro($method)) {\n            $this->attributes ??= $this->groupStack ? clone array_last($this->groupStack) : new PendingEventAttributes($this);\n\n            return $this->attributes->$method(...$parameters);\n        }\n\n        throw new BadMethodCallException(sprintf(\n            'Method %s::%s does not exist.', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schedule:clear-cache')]\nclass ScheduleClearCacheCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'schedule:clear-cache';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Delete the cached mutex files created by scheduler';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @return void\n     */\n    public function handle(Schedule $schedule)\n    {\n        $mutexCleared = false;\n\n        foreach ($schedule->events() as $event) {\n            if ($event->mutex->exists($event)) {\n                $this->components->info(sprintf('Deleting mutex for [%s]', $event->command));\n\n                $event->mutex->forget($event);\n\n                $mutexCleared = true;\n            }\n        }\n\n        if (! $mutexCleared) {\n            $this->components->info('No mutex files were found.');\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleFinishCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Events\\ScheduledBackgroundTaskFinished;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schedule:finish')]\nclass ScheduleFinishCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'schedule:finish {id} {code=0}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Handle the completion of a scheduled command';\n\n    /**\n     * Indicates whether the command should be shown in the Artisan command list.\n     *\n     * @var bool\n     */\n    protected $hidden = true;\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @return void\n     */\n    public function handle(Schedule $schedule)\n    {\n        (new Collection($schedule->events()))\n            ->filter(fn ($value) => $value->mutexName() == $this->argument('id'))\n            ->each(function ($event) {\n                $event->finish($this->laravel, $this->argument('code'));\n\n                $this->laravel->make(Dispatcher::class)->dispatch(new ScheduledBackgroundTaskFinished($event));\n            });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleInterruptCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Support\\Facades\\Date;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schedule:interrupt')]\nclass ScheduleInterruptCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'schedule:interrupt';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Interrupt the current schedule run';\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * Create a new schedule interrupt command.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        parent::__construct();\n\n        $this->cache = $cache;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->cache->put('illuminate:schedule:interrupt', true, Date::now()->endOfMinute());\n\n        $this->components->info('Broadcasting schedule interrupt signal.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleListCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Closure;\nuse Cron\\CronExpression;\nuse DateTimeZone;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse ReflectionClass;\nuse ReflectionFunction;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Terminal;\n\n#[AsCommand(name: 'schedule:list')]\nclass ScheduleListCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'schedule:list\n        {--timezone= : The timezone that times should be displayed in}\n        {--next : Sort the listed tasks by their next due date}\n        {--json : Output the scheduled tasks as JSON}\n    ';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'List all scheduled tasks';\n\n    /**\n     * The terminal width resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $terminalWidthResolver;\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function handle(Schedule $schedule)\n    {\n        $events = new Collection($schedule->events());\n\n        if ($events->isEmpty()) {\n            if ($this->option('json')) {\n                $this->output->writeln('[]');\n            } else {\n                $this->components->info('No scheduled tasks have been defined.');\n            }\n\n            return;\n        }\n\n        $timezone = new DateTimeZone($this->option('timezone') ?? config('app.timezone'));\n\n        $events = $this->sortEvents($events, $timezone);\n\n        $this->display($events, $timezone);\n    }\n\n    /**\n     * Render the scheduled tasks information as JSON.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @param  \\DateTimeZone  $timezone\n     * @return void\n     */\n    protected function displayJson(Collection $events, DateTimeZone $timezone)\n    {\n        $this->output->writeln($events->map(function ($event) use ($timezone) {\n            $nextDueDate = $this->getNextDueDateForEvent($event, $timezone);\n\n            $command = $event->command ?? '';\n\n            if (! $this->output->isVerbose()) {\n                $command = $event->normalizeCommand($command);\n            }\n\n            if ($event instanceof CallbackEvent) {\n                $command = $event->getSummaryForDisplay();\n\n                if (in_array($command, ['Closure', 'Callback'])) {\n                    $command = 'Closure at: '.$this->getClosureLocation($event);\n                }\n            }\n\n            return [\n                'expression' => $event->expression,\n                'command' => $command,\n                'description' => $event->description ?? null,\n                'next_due_date' => $nextDueDate->format('Y-m-d H:i:s P'),\n                'next_due_date_human' => $nextDueDate->diffForHumans(),\n                'timezone' => $timezone->getName(),\n                'has_mutex' => $event->mutex->exists($event),\n                'repeat_seconds' => $event->isRepeatable() ? $event->repeatSeconds : null,\n                'environments' => $event->environments,\n            ];\n        })->values()->toJson());\n    }\n\n    /**\n     * Render the scheduled tasks information formatted for the CLI.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @param  \\DateTimeZone  $timezone\n     * @return void\n     */\n    protected function displayForCli(Collection $events, DateTimeZone $timezone)\n    {\n        $terminalWidth = self::getTerminalWidth();\n\n        $expressionSpacing = $this->getCronExpressionSpacing($events);\n\n        $repeatExpressionSpacing = $this->getRepeatExpressionSpacing($events);\n\n        $events = $events->map(function ($event) use ($terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone) {\n            return $this->listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone);\n        });\n\n        $this->line(\n            $events->flatten()->filter()->prepend('')->push('')->toArray()\n        );\n    }\n\n    /**\n     * Get the spacing to be used on each event row.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @return array<int, int>\n     */\n    private function getCronExpressionSpacing($events)\n    {\n        $rows = $events->map(fn ($event) => array_map(mb_strlen(...), preg_split(\"/\\s+/\", $event->expression)));\n\n        return (new Collection($rows[0] ?? []))->keys()->map(fn ($key) => $rows->max($key))->all();\n    }\n\n    /**\n     * Get the spacing to be used on each event row.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @return int\n     */\n    private function getRepeatExpressionSpacing($events)\n    {\n        return $events->map(fn ($event) => mb_strlen($this->getRepeatExpression($event)))->max();\n    }\n\n    /**\n     * List the given even in the console.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  int  $terminalWidth\n     * @param  array  $expressionSpacing\n     * @param  int  $repeatExpressionSpacing\n     * @param  \\DateTimeZone  $timezone\n     * @return array\n     */\n    private function listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone)\n    {\n        $expression = $this->formatCronExpression($event->expression, $expressionSpacing);\n\n        $repeatExpression = str_pad($this->getRepeatExpression($event), $repeatExpressionSpacing);\n\n        $command = $event->command ?? '';\n\n        $description = $event->description ?? '';\n\n        if (! $this->output->isVerbose()) {\n            $command = $event->normalizeCommand($command);\n        }\n\n        if ($event instanceof CallbackEvent) {\n            $command = $event->getSummaryForDisplay();\n\n            if (in_array($command, ['Closure', 'Callback'])) {\n                $command = 'Closure at: '.$this->getClosureLocation($event);\n            }\n        }\n\n        $command = mb_strlen($command) > 1 ? \"{$command} \" : '';\n\n        $nextDueDateLabel = 'Next Due:';\n\n        $nextDueDate = $this->getNextDueDateForEvent($event, $timezone);\n\n        $nextDueDate = $this->output->isVerbose()\n            ? $nextDueDate->format('Y-m-d H:i:s P')\n            : $nextDueDate->diffForHumans();\n\n        $hasMutex = $event->mutex->exists($event) ? 'Has Mutex › ' : '';\n\n        $dots = str_repeat('.', max(\n            $terminalWidth - mb_strwidth($expression.$repeatExpression.$command.$nextDueDateLabel.$nextDueDate.$hasMutex) - 8, 0\n        ));\n\n        // Highlight the parameters...\n        $command = preg_replace(\"#(php artisan [\\w\\-:]+) (.+)#\", '$1 <fg=yellow;options=bold>$2</>', $command);\n\n        return [sprintf(\n            '  <fg=yellow>%s</> <fg=#6C7280>%s</> %s<fg=#6C7280>%s %s%s %s</>',\n            $expression,\n            $repeatExpression,\n            $command,\n            $dots,\n            $hasMutex,\n            $nextDueDateLabel,\n            $nextDueDate\n        ), $this->output->isVerbose() && mb_strlen($description) > 1 ? sprintf(\n            '  <fg=#6C7280>%s%s %s</>',\n            str_repeat(' ', mb_strlen($expression) + 2),\n            '⇁',\n            $description\n        ) : ''];\n    }\n\n    /**\n     * Get the repeat expression for an event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return string\n     */\n    private function getRepeatExpression($event)\n    {\n        return $event->isRepeatable() ? \"{$event->repeatSeconds}s \" : '';\n    }\n\n    /**\n     * Sort the events by due date if option set.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @param  \\DateTimeZone  $timezone\n     * @return \\Illuminate\\Support\\Collection\n     */\n    private function sortEvents(\\Illuminate\\Support\\Collection $events, DateTimeZone $timezone)\n    {\n        return $this->option('next')\n            ? $events->sortBy(fn ($event) => $this->getNextDueDateForEvent($event, $timezone))\n            : $events;\n    }\n\n    /**\n     * Render the scheduled tasks information.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @param  \\DateTimeZone  $timezone\n     * @return void\n     */\n    protected function display(Collection $events, DateTimeZone $timezone)\n    {\n        $this->option('json') ? $this->displayJson($events, $timezone) : $this->displayForCli($events, $timezone);\n    }\n\n    /**\n     * Get the next due date for an event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeZone  $timezone\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    private function getNextDueDateForEvent($event, DateTimeZone $timezone)\n    {\n        $nextDueDate = Carbon::instance(\n            (new CronExpression($event->expression))\n                ->getNextRunDate(Carbon::now()->setTimezone($event->timezone))\n                ->setTimezone($timezone)\n        );\n\n        if (! $event->isRepeatable()) {\n            return $nextDueDate;\n        }\n\n        $previousDueDate = Carbon::instance(\n            (new CronExpression($event->expression))\n                ->getPreviousRunDate(Carbon::now()->setTimezone($event->timezone), allowCurrentDate: true)\n                ->setTimezone($timezone)\n        );\n\n        $now = Carbon::now()->setTimezone($event->timezone);\n\n        if (! $now->copy()->startOfMinute()->eq($previousDueDate)) {\n            return $nextDueDate;\n        }\n\n        return $now\n            ->endOfSecond()\n            ->ceilSeconds($event->repeatSeconds);\n    }\n\n    /**\n     * Format the cron expression based on the spacing provided.\n     *\n     * @param  string  $expression\n     * @param  array<int, int>  $spacing\n     * @return string\n     */\n    private function formatCronExpression($expression, $spacing)\n    {\n        $expressions = preg_split(\"/\\s+/\", $expression);\n\n        return (new Collection($spacing))\n            ->map(fn ($length, $index) => str_pad($expressions[$index], $length))\n            ->implode(' ');\n    }\n\n    /**\n     * Get the file and line number for the event closure.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\CallbackEvent  $event\n     * @return string\n     */\n    private function getClosureLocation(CallbackEvent $event)\n    {\n        $callback = (new ReflectionClass($event))->getProperty('callback')->getValue($event);\n\n        if ($callback instanceof Closure) {\n            $function = new ReflectionFunction($callback);\n\n            return sprintf(\n                '%s:%s',\n                str_replace($this->laravel->basePath().DIRECTORY_SEPARATOR, '', $function->getFileName() ?: ''),\n                $function->getStartLine()\n            );\n        }\n\n        if (is_string($callback)) {\n            return $callback;\n        }\n\n        if (is_array($callback)) {\n            $className = is_string($callback[0]) ? $callback[0] : $callback[0]::class;\n\n            return sprintf('%s::%s', $className, $callback[1]);\n        }\n\n        return sprintf('%s::__invoke', $callback::class);\n    }\n\n    /**\n     * Get the terminal width.\n     *\n     * @return int\n     */\n    public static function getTerminalWidth()\n    {\n        return is_null(static::$terminalWidthResolver)\n            ? (new Terminal)->getWidth()\n            : call_user_func(static::$terminalWidthResolver);\n    }\n\n    /**\n     * Set a callback that should be used when resolving the terminal width.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveTerminalWidthUsing($resolver)\n    {\n        static::$terminalWidthResolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/SchedulePauseCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Events\\SchedulePaused;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schedule:pause')]\nclass SchedulePauseCommand extends Command\n{\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Pause the scheduler';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(Cache $cache, Dispatcher $dispatcher)\n    {\n        $cache->forever('illuminate:schedule:paused', true);\n\n        $dispatcher->dispatch(new SchedulePaused);\n\n        $this->components->info('Scheduled task processing has been paused.');\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleResumeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Events\\ScheduleResumed;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schedule:resume', aliases: ['schedule:continue'])]\nclass ScheduleResumeCommand extends Command\n{\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Resume the schedule';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var list<string>\n     */\n    protected $aliases = ['schedule:continue'];\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(Cache $cache, Dispatcher $dispatcher)\n    {\n        $cache->forget('illuminate:schedule:paused');\n\n        $dispatcher->dispatch(new ScheduleResumed);\n\n        $this->components->info('Scheduled task processing has resumed.');\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleRunCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Exception;\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Events\\ScheduledTaskFailed;\nuse Illuminate\\Console\\Events\\ScheduledTaskFinished;\nuse Illuminate\\Console\\Events\\ScheduledTaskSkipped;\nuse Illuminate\\Console\\Events\\ScheduledTaskStarting;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Sleep;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Throwable;\n\n#[AsCommand(name: 'schedule:run')]\nclass ScheduleRunCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'schedule:run {--whisper : Do not output message indicating that no jobs were ready to run}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Run the scheduled commands';\n\n    /**\n     * The schedule instance.\n     *\n     * @var \\Illuminate\\Console\\Scheduling\\Schedule\n     */\n    protected $schedule;\n\n    /**\n     * The 24 hour timestamp this scheduler command started running.\n     *\n     * @var \\Illuminate\\Support\\Carbon\n     */\n    protected $startedAt;\n\n    /**\n     * Check if any events ran.\n     *\n     * @var bool\n     */\n    protected $eventsRan = false;\n\n    /**\n     * The event dispatcher.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $dispatcher;\n\n    /**\n     * The exception handler.\n     *\n     * @var \\Illuminate\\Contracts\\Debug\\ExceptionHandler\n     */\n    protected $handler;\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * The PHP binary used by the command.\n     *\n     * @var string\n     */\n    protected $phpBinary;\n\n    /**\n     * Create a new command instance.\n     */\n    public function __construct()\n    {\n        $this->startedAt = Date::now();\n\n        parent::__construct();\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     * @param  \\Illuminate\\Contracts\\Debug\\ExceptionHandler  $handler\n     * @return void\n     */\n    public function handle(Schedule $schedule, Dispatcher $dispatcher, Cache $cache, ExceptionHandler $handler)\n    {\n        $this->schedule = $schedule;\n        $this->dispatcher = $dispatcher;\n        $this->cache = $cache;\n        $this->handler = $handler;\n        $this->phpBinary = Application::phpBinary();\n\n        $events = $this->schedule->dueEvents($this->laravel);\n\n        if ($events->contains->isRepeatable()) {\n            $this->clearInterruptSignal();\n        }\n\n        $paused = $this->isPaused();\n\n        foreach ($events as $event) {\n            if ($paused && ! $event->runsWhenPaused()) {\n                $this->dispatcher->dispatch(new ScheduledTaskSkipped($event));\n\n                continue;\n            }\n\n            if (! $event->filtersPass($this->laravel)) {\n                $this->dispatcher->dispatch(new ScheduledTaskSkipped($event));\n\n                continue;\n            }\n\n            if (! $this->eventsRan) {\n                $this->newLine();\n            }\n\n            if ($event->onOneServer) {\n                $this->runSingleServerEvent($event);\n            } else {\n                $this->runEvent($event);\n            }\n\n            $this->eventsRan = true;\n        }\n\n        if ($events->contains->isRepeatable()) {\n            $this->repeatEvents($events->filter->isRepeatable());\n        }\n\n        if (! $this->eventsRan) {\n            if (! $this->option('whisper')) {\n                $this->components->info('No scheduled commands are ready to run.');\n            }\n        } else {\n            $this->newLine();\n        }\n    }\n\n    /**\n     * Run the given single server event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    protected function runSingleServerEvent($event)\n    {\n        if ($this->schedule->serverShouldRun($event, $this->startedAt)) {\n            $this->runEvent($event);\n        } else {\n            $this->components->info(sprintf(\n                'Skipping [%s] because the command already ran on another server.', $event->getSummaryForDisplay()\n            ));\n        }\n    }\n\n    /**\n     * Run the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    protected function runEvent($event)\n    {\n        $summary = $event->getSummaryForDisplay();\n\n        $command = $event instanceof CallbackEvent\n            ? $summary\n            : trim(str_replace($this->phpBinary, '', $event->command));\n\n        $description = sprintf(\n            '<fg=gray>%s</> Running [%s]%s',\n            Carbon::now()->format('Y-m-d H:i:s'),\n            $command,\n            $event->runInBackground ? ' in background' : '',\n        );\n\n        $this->components->task($description, function () use ($event) {\n            $this->dispatcher->dispatch(new ScheduledTaskStarting($event));\n\n            $start = microtime(true);\n\n            try {\n                $event->run($this->laravel);\n\n                $this->dispatcher->dispatch(new ScheduledTaskFinished(\n                    $event,\n                    round(microtime(true) - $start, 2)\n                ));\n\n                $this->eventsRan = true;\n\n                if ($event->exitCode != 0 && ! $event->runInBackground) {\n                    throw new Exception(\"Scheduled command [{$event->command}] failed with exit code [{$event->exitCode}].\");\n                }\n            } catch (Throwable $e) {\n                $this->dispatcher->dispatch(new ScheduledTaskFailed($event, $e));\n\n                $this->handler->report($e);\n            }\n\n            return $event->exitCode == 0;\n        });\n\n        if (! $event instanceof CallbackEvent) {\n            $this->components->bulletList([\n                $event->getSummaryForDisplay(),\n            ]);\n        }\n    }\n\n    /**\n     * Run the given repeating events.\n     *\n     * @param  \\Illuminate\\Support\\Collection<\\Illuminate\\Console\\Scheduling\\Event>  $events\n     * @return void\n     */\n    protected function repeatEvents($events)\n    {\n        $hasEnteredMaintenanceMode = false;\n\n        while (Date::now()->lte($this->startedAt->endOfMinute())) {\n            $paused = $this->isPaused();\n\n            foreach ($events as $event) {\n                if ($this->shouldInterrupt()) {\n                    return;\n                }\n\n                if (! $event->shouldRepeatNow()) {\n                    continue;\n                }\n\n                $hasEnteredMaintenanceMode = $hasEnteredMaintenanceMode || $this->laravel->isDownForMaintenance();\n\n                if ($hasEnteredMaintenanceMode && ! $event->runsInMaintenanceMode()) {\n                    continue;\n                }\n\n                if ($paused && ! $event->runsWhenPaused()) {\n                    $this->dispatcher->dispatch(new ScheduledTaskSkipped($event));\n\n                    continue;\n                }\n\n                if (! $event->filtersPass($this->laravel)) {\n                    $this->dispatcher->dispatch(new ScheduledTaskSkipped($event));\n\n                    continue;\n                }\n\n                if ($event->onOneServer) {\n                    $this->runSingleServerEvent($event);\n                } else {\n                    $this->runEvent($event);\n                }\n\n                $this->eventsRan = true;\n            }\n\n            Sleep::usleep(100_000);\n        }\n    }\n\n    /**\n     * Determine if the schedule is paused.\n     *\n     * @return bool\n     */\n    protected function isPaused()\n    {\n        return $this->cache->get('illuminate:schedule:paused', false);\n    }\n\n    /**\n     * Determine if the schedule run should be interrupted.\n     *\n     * @return bool\n     */\n    protected function shouldInterrupt()\n    {\n        return $this->cache->get('illuminate:schedule:interrupt', false);\n    }\n\n    /**\n     * Ensure the interrupt signal is cleared.\n     *\n     * @return void\n     */\n    protected function clearInterruptSignal()\n    {\n        $this->cache->forget('illuminate:schedule:interrupt');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleTestCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'schedule:test')]\nclass ScheduleTestCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'schedule:test {--name= : The name of the scheduled command to run}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Run a scheduled command';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @return void\n     */\n    public function handle(Schedule $schedule)\n    {\n        $phpBinary = Application::phpBinary();\n\n        $commands = $schedule->events();\n\n        $commandNames = [];\n\n        foreach ($commands as $command) {\n            $commandNames[] = $command->command ?? $command->getSummaryForDisplay();\n        }\n\n        if (empty($commandNames)) {\n            return $this->components->info('No scheduled commands have been defined.');\n        }\n\n        if (! empty($name = $this->option('name'))) {\n            $commandBinary = $phpBinary.' '.Application::artisanBinary();\n\n            $matches = array_filter($commandNames, function ($commandName) use ($commandBinary, $name) {\n                return trim(str_replace($commandBinary, '', $commandName)) === $name;\n            });\n\n            if (count($matches) !== 1) {\n                $this->components->info('No matching scheduled command found.');\n\n                return;\n            }\n\n            $index = key($matches);\n        } else {\n            $index = $this->getSelectedCommandByIndex($commandNames);\n        }\n\n        $event = $commands[$index];\n\n        $summary = $event->getSummaryForDisplay();\n\n        $command = $event instanceof CallbackEvent\n            ? $summary\n            : trim(str_replace($phpBinary, '', $event->command));\n\n        $description = sprintf(\n            'Running [%s]%s',\n            $command,\n            $event->runInBackground ? ' normally in background' : '',\n        );\n\n        $event->runInBackground = false;\n\n        $this->components->task($description, fn () => $event->run($this->laravel));\n\n        if (! $event instanceof CallbackEvent) {\n            $this->components->bulletList([$event->getSummaryForDisplay()]);\n        }\n\n        $this->newLine();\n    }\n\n    /**\n     * Get the selected command name by index.\n     *\n     * @param  array  $commandNames\n     * @return int\n     */\n    protected function getSelectedCommandByIndex(array $commandNames)\n    {\n        if (count($commandNames) !== count(array_unique($commandNames))) {\n            // Some commands (likely closures) have the same name, append unique indexes to each one...\n            $uniqueCommandNames = array_map(function ($index, $value) {\n                return \"$value [$index]\";\n            }, array_keys($commandNames), $commandNames);\n\n            $selectedCommand = select('Which command would you like to run?', $uniqueCommandNames);\n\n            preg_match('/\\[(\\d+)\\]/', $selectedCommand, $choice);\n\n            return (int) $choice[1];\n        } else {\n            return array_search(\n                select('Which command would you like to run?', $commandNames),\n                $commandNames\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/ScheduleWorkCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\ProcessUtils;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Process\\Process;\n\n#[AsCommand(name: 'schedule:work')]\nclass ScheduleWorkCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'schedule:work\n        {--run-output-file= : The file to direct <info>schedule:run</info> output to}\n        {--whisper : Do not output message indicating that no jobs were ready to run}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Start the schedule worker';\n\n    /**\n     * Execute the console command.\n     *\n     * @return never\n     */\n    public function handle()\n    {\n        $this->components->info(\n            'Running scheduled tasks.',\n            $this->getLaravel()->environment('local') ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE\n        );\n\n        [$lastExecutionStartedAt, $executions] = [Carbon::now()->subMinutes(10), []];\n\n        $command = Application::formatCommandString('schedule:run');\n\n        if ($this->option('whisper')) {\n            $command .= ' --whisper';\n        }\n\n        if ($this->option('run-output-file')) {\n            $command .= ' >> '.ProcessUtils::escapeArgument($this->option('run-output-file')).' 2>&1';\n        }\n\n        while (true) {\n            usleep(100 * 1000);\n\n            if (Carbon::now()->second === 0 &&\n                ! Carbon::now()->startOfMinute()->equalTo($lastExecutionStartedAt)) {\n                $executions[] = $execution = Process::fromShellCommandline($command, base_path());\n\n                $execution->start();\n\n                $lastExecutionStartedAt = Carbon::now()->startOfMinute();\n            }\n\n            foreach ($executions as $key => $execution) {\n                $output = $execution->getIncrementalOutput().\n                    $execution->getIncrementalErrorOutput();\n\n                $this->output->write(ltrim($output, \"\\n\"));\n\n                if (! $execution->isRunning()) {\n                    unset($executions[$key]);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Scheduling/SchedulingMutex.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\Scheduling;\n\nuse DateTimeInterface;\n\ninterface SchedulingMutex\n{\n    /**\n     * Attempt to obtain a scheduling mutex for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeInterface  $time\n     * @return bool\n     */\n    public function create(Event $event, DateTimeInterface $time);\n\n    /**\n     * Determine if a scheduling mutex exists for the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @param  \\DateTimeInterface  $time\n     * @return bool\n     */\n    public function exists(Event $event, DateTimeInterface $time);\n}\n"
  },
  {
    "path": "src/Illuminate/Console/Signals.php",
    "content": "<?php\n\nnamespace Illuminate\\Console;\n\n/**\n * @internal\n */\nclass Signals\n{\n    /**\n     * The signal registry instance.\n     *\n     * @var \\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry\n     */\n    protected $registry;\n\n    /**\n     * The signal registry's previous list of handlers.\n     *\n     * @var array<int, array<int, callable(int): void>>|null\n     */\n    protected $previousHandlers;\n\n    /**\n     * The current availability resolver, if any.\n     *\n     * @var (callable(): bool)|null\n     */\n    protected static $availabilityResolver;\n\n    /**\n     * Create a new signal registrar instance.\n     *\n     * @param  \\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry  $registry\n     */\n    public function __construct($registry)\n    {\n        $this->registry = $registry;\n\n        $this->previousHandlers = $this->getHandlers();\n    }\n\n    /**\n     * Register a new signal handler.\n     *\n     * @param  int  $signal\n     * @param  callable(int $signal): void  $callback\n     * @return void\n     */\n    public function register($signal, $callback)\n    {\n        $this->previousHandlers[$signal] ??= $this->initializeSignal($signal);\n\n        $handlers = $this->getHandlers();\n\n        $handlers[$signal] ??= $this->initializeSignal($signal);\n\n        $this->setHandlers($handlers);\n\n        $this->registry->register($signal, $callback);\n\n        $handlers = $this->getHandlers();\n\n        $lastHandlerInserted = array_pop($handlers[$signal]);\n\n        array_unshift($handlers[$signal], $lastHandlerInserted);\n\n        $this->setHandlers($handlers);\n    }\n\n    /**\n     * Gets the signal's existing handler in array format.\n     *\n     * @return array<int, callable(int $signal): void>|null\n     */\n    protected function initializeSignal($signal)\n    {\n        return is_callable($existingHandler = pcntl_signal_get_handler($signal))\n            ? [$existingHandler]\n            : null;\n    }\n\n    /**\n     * Unregister the current signal handlers.\n     *\n     * @return void\n     */\n    public function unregister()\n    {\n        $previousHandlers = $this->previousHandlers;\n\n        foreach ($previousHandlers as $signal => $handler) {\n            if (is_null($handler)) {\n                pcntl_signal($signal, SIG_DFL);\n\n                unset($previousHandlers[$signal]);\n            }\n        }\n\n        $this->setHandlers($previousHandlers);\n    }\n\n    /**\n     * Execute the given callback if \"signals\" should be used and are available.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function whenAvailable($callback)\n    {\n        $resolver = static::$availabilityResolver;\n\n        if ($resolver()) {\n            $callback();\n        }\n    }\n\n    /**\n     * Get the registry's handlers.\n     *\n     * @return array<int, array<int, callable>>\n     */\n    protected function getHandlers()\n    {\n        return (fn () => $this->signalHandlers)\n            ->call($this->registry);\n    }\n\n    /**\n     * Set the registry's handlers.\n     *\n     * @param  array<int, array<int, callable(int $signal):void>>  $handlers\n     * @return void\n     */\n    protected function setHandlers($handlers)\n    {\n        (fn () => $this->signalHandlers = $handlers)\n            ->call($this->registry);\n    }\n\n    /**\n     * Set the availability resolver.\n     *\n     * @param  (callable(): bool)  $resolver\n     * @return void\n     */\n    public static function resolveAvailabilityUsing($resolver)\n    {\n        static::$availabilityResolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Alert.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Alert extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        $string = $this->mutate($string, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsurePunctuation::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $this->renderView('alert', [\n            'content' => $string,\n        ], $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Ask.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Question\\Question;\n\nclass Ask extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $question\n     * @param  string|null  $default\n     * @param  bool  $multiline\n     * @return mixed\n     */\n    public function render($question, $default = null, $multiline = false)\n    {\n        return $this->usingQuestionHelper(\n            fn () => $this->output->askQuestion(\n                (new Question($question, $default))\n                    ->setMultiline($multiline)\n            )\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/AskWithCompletion.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Question\\Question;\n\nclass AskWithCompletion extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $question\n     * @param  array|callable  $choices\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function render($question, $choices, $default = null)\n    {\n        $question = new Question($question, $default);\n\n        is_callable($choices)\n            ? $question->setAutocompleterCallback($choices)\n            : $question->setAutocompleterValues($choices);\n\n        return $this->usingQuestionHelper(\n            fn () => $this->output->askQuestion($question)\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/BulletList.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass BulletList extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  array<int, string>  $elements\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($elements, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        $elements = $this->mutate($elements, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsureNoPunctuation::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $this->renderView('bullet-list', [\n            'elements' => $elements,\n        ], $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Choice.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\n\nclass Choice extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $question\n     * @param  array<array-key, string>  $choices\n     * @param  mixed  $default\n     * @param  int|null  $attempts\n     * @param  bool  $multiple\n     * @return mixed\n     */\n    public function render($question, $choices, $default = null, $attempts = null, $multiple = false)\n    {\n        return $this->usingQuestionHelper(\n            fn () => $this->output->askQuestion(\n                $this->getChoiceQuestion($question, $choices, $default)\n                    ->setMaxAttempts($attempts)\n                    ->setMultiselect($multiple)\n            ),\n        );\n    }\n\n    /**\n     * Get a ChoiceQuestion instance that handles array keys like Prompts.\n     *\n     * @param  string  $question\n     * @param  array  $choices\n     * @param  mixed  $default\n     * @return \\Symfony\\Component\\Console\\Question\\ChoiceQuestion\n     */\n    protected function getChoiceQuestion($question, $choices, $default)\n    {\n        return new class($question, $choices, $default) extends ChoiceQuestion\n        {\n            protected function isAssoc(array $array): bool\n            {\n                return ! array_is_list($array);\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Component.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\QuestionHelper;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper;\n\nuse function Termwind\\render;\nuse function Termwind\\renderUsing;\n\nabstract class Component\n{\n    /**\n     * The output style implementation.\n     *\n     * @var \\Illuminate\\Console\\OutputStyle\n     */\n    protected $output;\n\n    /**\n     * The list of mutators to apply on the view data.\n     *\n     * @var array<int, callable(string): string>\n     */\n    protected $mutators;\n\n    /**\n     * Creates a new component instance.\n     *\n     * @param  \\Illuminate\\Console\\OutputStyle  $output\n     */\n    public function __construct($output)\n    {\n        $this->output = $output;\n    }\n\n    /**\n     * Renders the given view.\n     *\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  int  $verbosity\n     * @return void\n     */\n    protected function renderView($view, $data, $verbosity)\n    {\n        renderUsing($this->output);\n\n        render((string) $this->compile($view, $data), $verbosity);\n    }\n\n    /**\n     * Compile the given view contents.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @return string\n     */\n    protected function compile($view, $data)\n    {\n        extract($data);\n\n        ob_start();\n\n        include __DIR__.\"/../../resources/views/components/$view.php\";\n\n        return tap(ob_get_contents(), function () {\n            ob_end_clean();\n        });\n    }\n\n    /**\n     * Mutates the given data with the given set of mutators.\n     *\n     * @param  array<int, string>|string  $data\n     * @param  array<int, callable(string): string>  $mutators\n     * @return array<int, string>|string\n     */\n    protected function mutate($data, $mutators)\n    {\n        foreach ($mutators as $mutator) {\n            $mutator = new $mutator;\n\n            if (is_iterable($data)) {\n                foreach ($data as $key => $value) {\n                    $data[$key] = $mutator($value);\n                }\n            } else {\n                $data = $mutator($data);\n            }\n        }\n\n        return $data;\n    }\n\n    /**\n     * Eventually performs a question using the component's question helper.\n     *\n     * @param  callable  $callable\n     * @return mixed\n     */\n    protected function usingQuestionHelper($callable)\n    {\n        $property = (new ReflectionClass(OutputStyle::class))\n            ->getParentClass()\n            ->getProperty('questionHelper');\n\n        $currentHelper = $property->isInitialized($this->output)\n            ? $property->getValue($this->output)\n            : new SymfonyQuestionHelper();\n\n        $property->setValue($this->output, new QuestionHelper);\n\n        try {\n            return $callable();\n        } finally {\n            $property->setValue($this->output, $currentHelper);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Confirm.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nclass Confirm extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $question\n     * @param  bool  $default\n     * @return bool\n     */\n    public function render($question, $default = false)\n    {\n        return $this->usingQuestionHelper(\n            fn () => $this->output->confirm($question, $default),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Error.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Error extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        (new Line($this->output))->render('error', $string, $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse InvalidArgumentException;\n\n/**\n * @method void alert(string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method mixed ask(string $question, string $default = null, bool $multiline = false)\n * @method mixed askWithCompletion(string $question, array|callable $choices, string $default = null)\n * @method void bulletList(array $elements, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method mixed choice(string $question, array $choices, $default = null, int $attempts = null, bool $multiple = false)\n * @method bool confirm(string $question, bool $default = false)\n * @method void info(string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void success(string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void error(string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void line(string $style, string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void secret(string $question, bool $fallback = true)\n * @method void task(string $description, ?callable $task = null, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void twoColumnDetail(string $first, ?string $second = null, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n * @method void warn(string $string, int $verbosity = \\Symfony\\Component\\Console\\Output\\OutputInterface::VERBOSITY_NORMAL)\n */\nclass Factory\n{\n    /**\n     * The output interface implementation.\n     *\n     * @var \\Illuminate\\Console\\OutputStyle\n     */\n    protected $output;\n\n    /**\n     * Creates a new factory instance.\n     *\n     * @param  \\Illuminate\\Console\\OutputStyle  $output\n     */\n    public function __construct($output)\n    {\n        $this->output = $output;\n    }\n\n    /**\n     * Dynamically handle calls into the component instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __call($method, $parameters)\n    {\n        $component = '\\Illuminate\\Console\\View\\Components\\\\'.ucfirst($method);\n\n        throw_unless(class_exists($component), new InvalidArgumentException(sprintf(\n            'Console component [%s] not found.', $method\n        )));\n\n        return (new $component($this->output))->render(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Info.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Info extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        (new Line($this->output))->render('info', $string, $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Line.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Illuminate\\Console\\Contracts\\NewLineAware;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Line extends Component\n{\n    /**\n     * The possible line styles.\n     *\n     * @var array<string, array<string, string>>\n     */\n    protected static $styles = [\n        'info' => [\n            'bgColor' => 'blue',\n            'fgColor' => 'white',\n            'title' => 'info',\n        ],\n        'success' => [\n            'bgColor' => 'green',\n            'fgColor' => 'white',\n            'title' => 'success',\n        ],\n        'warn' => [\n            'bgColor' => 'yellow',\n            'fgColor' => 'black',\n            'title' => 'warn',\n        ],\n        'error' => [\n            'bgColor' => 'red',\n            'fgColor' => 'white',\n            'title' => 'error',\n        ],\n    ];\n\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $style\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($style, $string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        $string = $this->mutate($string, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsurePunctuation::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $this->renderView('line', array_merge(static::$styles[$style], [\n            'marginTop' => $this->output instanceof NewLineAware ? max(0, 2 - $this->output->newLinesWritten()) : 1,\n            'content' => $string,\n        ]), $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Mutators/EnsureDynamicContentIsHighlighted.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components\\Mutators;\n\nclass EnsureDynamicContentIsHighlighted\n{\n    /**\n     * Highlight dynamic content within the given string.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    public function __invoke($string)\n    {\n        return preg_replace('/\\[([^\\]]+)\\]/', '<options=bold>[$1]</>', (string) $string);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Mutators/EnsureNoPunctuation.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components\\Mutators;\n\nuse Illuminate\\Support\\Stringable;\n\nclass EnsureNoPunctuation\n{\n    /**\n     * Ensures the given string does not end with punctuation.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    public function __invoke($string)\n    {\n        if ((new Stringable($string))->endsWith(['.', '?', '!', ':'])) {\n            return substr_replace($string, '', -1);\n        }\n\n        return $string;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Mutators/EnsurePunctuation.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components\\Mutators;\n\nuse Illuminate\\Support\\Stringable;\n\nclass EnsurePunctuation\n{\n    /**\n     * Ensures the given string ends with punctuation.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    public function __invoke($string)\n    {\n        if (! (new Stringable($string))->endsWith(['.', '?', '!', ':'])) {\n            return \"$string.\";\n        }\n\n        return $string;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Mutators/EnsureRelativePaths.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components\\Mutators;\n\nclass EnsureRelativePaths\n{\n    /**\n     * Ensures the given string only contains relative paths.\n     *\n     * @param  string  $string\n     * @return string\n     */\n    public function __invoke($string)\n    {\n        if (function_exists('app') && app()->has('path.base')) {\n            $string = str_replace(base_path().'/', '', $string);\n        }\n\n        return $string;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Secret.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Question\\Question;\n\nclass Secret extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $question\n     * @param  bool  $fallback\n     * @return mixed\n     */\n    public function render($question, $fallback = true)\n    {\n        $question = new Question($question);\n\n        $question->setHidden(true)->setHiddenFallback($fallback);\n\n        return $this->usingQuestionHelper(fn () => $this->output->askQuestion($question));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Success.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Success extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        (new Line($this->output))->render('success', $string, $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Task.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Illuminate\\Console\\View\\TaskResult;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Throwable;\n\nuse function Termwind\\terminal;\n\nclass Task extends Component\n{\n    use InteractsWithTime;\n\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $description\n     * @param  (callable(): bool)|null  $task\n     * @param  int  $verbosity\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function render($description, $task = null, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        $description = $this->mutate($description, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsureNoPunctuation::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $descriptionWidth = mb_strlen(preg_replace(\"/\\<[\\w=#\\/\\;,:.&,%?]+\\>|\\\\e\\[\\d+m/\", '$1', $description) ?? '');\n\n        $this->output->write(\"  $description \", false, $verbosity);\n\n        $startTime = microtime(true);\n\n        $result = TaskResult::Failure->value;\n\n        try {\n            $result = ($task ?: fn () => TaskResult::Success->value)();\n        } catch (Throwable $e) {\n            throw $e;\n        } finally {\n            $runTime = $task\n                ? (' '.$this->runTimeForHumans($startTime))\n                : '';\n\n            $runTimeWidth = mb_strlen($runTime);\n            $width = min(terminal()->width(), 150);\n            $dots = max($width - $descriptionWidth - $runTimeWidth - 10, 0);\n\n            $this->output->write(str_repeat('<fg=gray>.</>', $dots), false, $verbosity);\n            $this->output->write(\"<fg=gray>$runTime</>\", false, $verbosity);\n\n            $this->output->writeln(\n                match ($result) {\n                    TaskResult::Failure->value => ' <fg=red;options=bold>FAIL</>',\n                    TaskResult::Skipped->value => ' <fg=yellow;options=bold>SKIPPED</>',\n                    default => ' <fg=green;options=bold>DONE</>'\n                },\n                $verbosity,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/TwoColumnDetail.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass TwoColumnDetail extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $first\n     * @param  string|null  $second\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($first, $second = null, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        $first = $this->mutate($first, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsureNoPunctuation::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $second = $this->mutate($second, [\n            Mutators\\EnsureDynamicContentIsHighlighted::class,\n            Mutators\\EnsureRelativePaths::class,\n        ]);\n\n        $this->renderView('two-column-detail', [\n            'first' => $first,\n            'second' => $second,\n        ], $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/Components/Warn.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View\\Components;\n\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Warn extends Component\n{\n    /**\n     * Renders the component using the given arguments.\n     *\n     * @param  string  $string\n     * @param  int  $verbosity\n     * @return void\n     */\n    public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)\n    {\n        (new Line($this->output))->render('warn', $string, $verbosity);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/View/TaskResult.php",
    "content": "<?php\n\nnamespace Illuminate\\Console\\View;\n\nenum TaskResult: int\n{\n    case Success = 1;\n    case Failure = 2;\n    case Skipped = 3;\n}\n"
  },
  {
    "path": "src/Illuminate/Console/composer.json",
    "content": "{\n    \"name\": \"illuminate/console\",\n    \"description\": \"The Illuminate Console package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-mbstring\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"illuminate/view\": \"^13.0\",\n        \"laravel/prompts\": \"^0.3.0\",\n        \"nunomaduro/termwind\": \"^2.0\",\n        \"symfony/console\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/process\": \"^7.4.5 || ^8.0.5\"\n    },\n    \"suggest\": {\n        \"ext-pcntl\": \"Required to use signal trapping.\",\n        \"dragonmantank/cron-expression\": \"Required to use scheduler (^3.3.2).\",\n        \"guzzlehttp/guzzle\": \"Required to use the ping methods on schedules (^7.8).\",\n        \"illuminate/bus\": \"Required to use the scheduled job dispatcher (^13.0).\",\n        \"illuminate/container\": \"Required to use the scheduler (^13.0).\",\n        \"illuminate/filesystem\": \"Required to use the generator command (^13.0).\",\n        \"illuminate/queue\": \"Required to use closures for scheduled jobs (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Console\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Console/resources/views/components/alert.php",
    "content": "<div class=\"w-full mx-2 py-1 mt-1 bg-yellow text-black text-center uppercase\">\n    <?php echo htmlspecialchars($content) ?>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Console/resources/views/components/bullet-list.php",
    "content": "<div>\n    <?php foreach ($elements as $element) { ?>\n        <div class=\"text-gray mx-2\">\n            ⇂ <?php echo htmlspecialchars($element) ?>\n        </div>\n    <?php } ?>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Console/resources/views/components/line.php",
    "content": "<div class=\"mx-2 mb-1 mt-<?php echo $marginTop ?>\">\n    <span class=\"px-1 bg-<?php echo $bgColor ?> text-<?php echo $fgColor ?> uppercase\"><?php echo $title ?></span>\n    <span class=\"<?php if ($title) {\n        echo 'ml-1';\n    } ?>\">\n        <?php echo htmlspecialchars($content) ?>\n    </span>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Console/resources/views/components/two-column-detail.php",
    "content": "<div class=\"flex mx-2 max-w-150\">\n    <span>\n        <?php echo htmlspecialchars($first) ?>\n    </span>\n    <span class=\"flex-1 content-repeat-[.] text-gray ml-1\"></span>\n    <?php if ($second !== '') { ?>\n        <span class=\"ml-1\">\n            <?php echo htmlspecialchars($second) ?>\n        </span>\n    <?php } ?>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Container/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Container/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Auth.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Auth implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public ?string $guard = null)\n    {\n    }\n\n    /**\n     * Resolve the authentication guard.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Illuminate\\Contracts\\Auth\\Guard|\\Illuminate\\Contracts\\Auth\\StatefulGuard\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('auth')->guard($attribute->guard);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Authenticated.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Authenticated implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public ?string $guard = null)\n    {\n    }\n\n    /**\n     * Resolve the currently authenticated user.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return call_user_func($container->make('auth')->userResolver(), $attribute->guard);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Bind.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse InvalidArgumentException;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass Bind\n{\n    /**\n     * The concrete class to bind to.\n     *\n     * @var class-string\n     */\n    public string $concrete;\n\n    /**\n     * The environments the binding should apply for.\n     *\n     * @var non-empty-array<int, string>\n     */\n    public array $environments = [];\n\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string  $concrete\n     * @param  non-empty-array<int, \\BackedEnum|\\UnitEnum|non-empty-string>|non-empty-string|\\UnitEnum  $environments\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct(\n        string $concrete,\n        string|array|UnitEnum $environments = ['*'],\n    ) {\n        $environments = array_filter(is_array($environments) ? $environments : [$environments]);\n\n        if ($environments === []) {\n            throw new InvalidArgumentException('The environment property must be set and cannot be empty.');\n        }\n\n        $this->concrete = $concrete;\n\n        $this->environments = array_map(\n            fn ($environment) => enum_value($environment),\n            $environments,\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Cache.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Cache implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public ?string $store = null)\n    {\n    }\n\n    /**\n     * Resolve the cache store.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('cache')->store($attribute->store);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Config.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Config implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public string $key, public mixed $default = null)\n    {\n    }\n\n    /**\n     * Resolve the configuration value.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('config')->get($attribute->key, $attribute->default);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Context.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse Illuminate\\Log\\Context\\Repository;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Context implements ContextualAttribute\n{\n    /**\n     * Create a new attribute instance.\n     */\n    public function __construct(public string $key, public mixed $default = null, public bool $hidden = false)\n    {\n    }\n\n    /**\n     * Resolve the context value.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     */\n    public static function resolve(self $attribute, Container $container): mixed\n    {\n        $repository = $container->make(Repository::class);\n\n        return match ($attribute->hidden) {\n            true => $repository->getHidden($attribute->key, $attribute->default),\n            false => $repository->get($attribute->key, $attribute->default),\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/CurrentUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass CurrentUser extends Authenticated\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/DB.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass DB extends Database\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Database.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse UnitEnum;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Database implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public UnitEnum|string|null $connection = null)\n    {\n    }\n\n    /**\n     * Resolve the database connection.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('db')->connection($attribute->connection);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Give.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Give implements ContextualAttribute\n{\n    /**\n     * Provide a concrete class implementation for dependency injection.\n     *\n     * @param  string  $class\n     * @param  array|null  $params\n     */\n    public function __construct(\n        public string $class,\n        public array $params = [],\n    ) {\n    }\n\n    /**\n     * Resolve the dependency.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     */\n    public static function resolve(self $attribute, Container $container): mixed\n    {\n        return $container->make($attribute->class, $attribute->params);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Log.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Log implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     *\n     * @param  UnitEnum|string|null  $channel  The log configuration's channel name.\n     * @param  UnitEnum|string|null  $name  The name to prefix all logs with. Only to be used with Monolog drivers.\n     */\n    public function __construct(\n        public UnitEnum|string|null $channel = null,\n        public UnitEnum|string|null $name = null,\n    ) {\n    }\n\n    /**\n     * Resolve the log channel.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        $logger = $container->make('log')->channel(enum_value($attribute->channel));\n\n        if ($attribute->name !== null) {\n            $logger = $logger->withName(enum_value($attribute->name));\n        }\n\n        return $logger;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/RouteParameter.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass RouteParameter implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public string $parameter)\n    {\n    }\n\n    /**\n     * Resolve the route parameter.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('request')->route($attribute->parameter);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Scoped.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nfinal class Scoped\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Singleton.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nfinal class Singleton\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Storage.php",
    "content": "<?php\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass Storage implements ContextualAttribute\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct(public ?string $disk = null)\n    {\n    }\n\n    /**\n     * Resolve the storage disk.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->make('filesystem')->disk($attribute->disk);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Attributes/Tag.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Container\\Attributes;\n\nuse Attribute;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class Tag implements ContextualAttribute\n{\n    public function __construct(\n        public string $tag,\n    ) {\n    }\n\n    /**\n     * Resolve the tag.\n     *\n     * @param  self  $attribute\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return mixed\n     */\n    public static function resolve(self $attribute, Container $container)\n    {\n        return $container->tagged($attribute->tag);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/BoundMethod.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse InvalidArgumentException;\nuse ReflectionFunction;\nuse ReflectionMethod;\n\nclass BoundMethod\n{\n    /**\n     * Call the given Closure / class@method and inject its dependencies.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  callable|string  $callback\n     * @param  array  $parameters\n     * @param  string|null  $defaultMethod\n     * @return mixed\n     *\n     * @throws \\ReflectionException\n     * @throws \\InvalidArgumentException\n     */\n    public static function call($container, $callback, array $parameters = [], $defaultMethod = null)\n    {\n        if (is_string($callback) && ! $defaultMethod && method_exists($callback, '__invoke')) {\n            $defaultMethod = '__invoke';\n        }\n\n        if (static::isCallableWithAtSign($callback) || $defaultMethod) {\n            return static::callClass($container, $callback, $parameters, $defaultMethod);\n        }\n\n        return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) {\n            return $callback(...array_values(static::getMethodDependencies($container, $callback, $parameters)));\n        });\n    }\n\n    /**\n     * Call a string reference to a class using Class@method syntax.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  string  $target\n     * @param  array  $parameters\n     * @param  string|null  $defaultMethod\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected static function callClass($container, $target, array $parameters = [], $defaultMethod = null)\n    {\n        $segments = explode('@', $target);\n\n        // We will assume an @ sign is used to delimit the class name from the method\n        // name. We will split on this @ sign and then build a callable array that\n        // we can pass right back into the \"call\" method for dependency binding.\n        $method = count($segments) === 2\n            ? $segments[1]\n            : $defaultMethod;\n\n        if (is_null($method)) {\n            throw new InvalidArgumentException('Method not provided.');\n        }\n\n        return static::call(\n            $container,\n            [$container->make($segments[0]), $method],\n            $parameters\n        );\n    }\n\n    /**\n     * Call a method that has been bound to the container.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  callable  $callback\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected static function callBoundMethod($container, $callback, $default)\n    {\n        if (! is_array($callback)) {\n            return Util::unwrapIfClosure($default);\n        }\n\n        // Here we need to turn the array callable into a Class@method string we can use to\n        // examine the container and see if there are any method bindings for this given\n        // method. If there are, we can call this method binding callback immediately.\n        $method = static::normalizeMethod($callback);\n\n        if ($container->hasMethodBinding($method)) {\n            return $container->callMethodBinding($method, $callback[0]);\n        }\n\n        return Util::unwrapIfClosure($default);\n    }\n\n    /**\n     * Normalize the given callback into a Class@method string.\n     *\n     * @param  callable  $callback\n     * @return string\n     */\n    protected static function normalizeMethod($callback)\n    {\n        $class = is_string($callback[0]) ? $callback[0] : get_class($callback[0]);\n\n        return \"{$class}@{$callback[1]}\";\n    }\n\n    /**\n     * Get all dependencies for a given method.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  callable|string  $callback\n     * @param  array  $parameters\n     * @return array\n     *\n     * @throws \\ReflectionException\n     */\n    protected static function getMethodDependencies($container, $callback, array $parameters = [])\n    {\n        $dependencies = [];\n\n        foreach (static::getCallReflector($callback)->getParameters() as $parameter) {\n            static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies);\n        }\n\n        return array_merge($dependencies, array_values($parameters));\n    }\n\n    /**\n     * Get the proper reflection instance for the given callback.\n     *\n     * @param  callable|string  $callback\n     * @return \\ReflectionFunctionAbstract\n     *\n     * @throws \\ReflectionException\n     */\n    protected static function getCallReflector($callback)\n    {\n        if (is_string($callback) && str_contains($callback, '::')) {\n            $callback = explode('::', $callback);\n        } elseif (is_object($callback) && ! $callback instanceof Closure) {\n            $callback = [$callback, '__invoke'];\n        }\n\n        return is_array($callback)\n            ? new ReflectionMethod($callback[0], $callback[1])\n            : new ReflectionFunction($callback);\n    }\n\n    /**\n     * Get the dependency for the given call parameter.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\ReflectionParameter  $parameter\n     * @param  array  $parameters\n     * @param  array  $dependencies\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected static function addDependencyForCallParameter(\n        $container,\n        $parameter,\n        array &$parameters,\n        &$dependencies,\n    ) {\n        $pendingDependencies = [];\n\n        if (array_key_exists($paramName = $parameter->getName(), $parameters)) {\n            $pendingDependencies[] = $parameters[$paramName];\n\n            unset($parameters[$paramName]);\n        } elseif ($attribute = Util::getContextualAttributeFromDependency($parameter)) {\n            $pendingDependencies[] = $container->resolveFromAttribute($attribute);\n        } elseif (! is_null($className = Util::getParameterClassName($parameter))) {\n            if (array_key_exists($className, $parameters)) {\n                $pendingDependencies[] = $parameters[$className];\n\n                unset($parameters[$className]);\n            } elseif ($parameter->isVariadic()) {\n                $variadicDependencies = $container->make($className);\n\n                $pendingDependencies = array_merge($pendingDependencies, is_array($variadicDependencies)\n                    ? $variadicDependencies\n                    : [$variadicDependencies]);\n            } elseif ($parameter->isDefaultValueAvailable() && ! $container->bound($className)) {\n                $pendingDependencies[] = $parameter->getDefaultValue();\n            } else {\n                $pendingDependencies[] = $container->make($className);\n            }\n        } elseif ($parameter->isDefaultValueAvailable()) {\n            $pendingDependencies[] = $parameter->getDefaultValue();\n        } elseif (! $parameter->isOptional() && ! array_key_exists($paramName, $parameters)) {\n            $message = \"Unable to resolve dependency [{$parameter}] in class {$parameter->getDeclaringClass()->getName()}\";\n\n            throw new BindingResolutionException($message);\n        }\n\n        foreach ($pendingDependencies as $dependency) {\n            $container->fireAfterResolvingAttributeCallbacks($parameter->getAttributes(), $dependency);\n        }\n\n        $dependencies = array_merge($dependencies, $pendingDependencies);\n    }\n\n    /**\n     * Determine if the given string is in Class@method syntax.\n     *\n     * @param  mixed  $callback\n     * @return bool\n     */\n    protected static function isCallableWithAtSign($callback)\n    {\n        return is_string($callback) && str_contains($callback, '@');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Container.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse ArrayAccess;\nuse Closure;\nuse Exception;\nuse Illuminate\\Container\\Attributes\\Bind;\nuse Illuminate\\Container\\Attributes\\Scoped;\nuse Illuminate\\Container\\Attributes\\Singleton;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Contracts\\Container\\CircularDependencyException;\nuse Illuminate\\Contracts\\Container\\Container as ContainerContract;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse Illuminate\\Contracts\\Container\\SelfBuilding;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse LogicException;\nuse ReflectionAttribute;\nuse ReflectionClass;\nuse ReflectionException;\nuse ReflectionFunction;\nuse ReflectionParameter;\nuse TypeError;\n\nclass Container implements ArrayAccess, ContainerContract\n{\n    use ReflectsClosures;\n\n    /**\n     * The current globally available container (if any).\n     *\n     * @var static\n     */\n    protected static $instance;\n\n    /**\n     * An array of the types that have been resolved.\n     *\n     * @var bool[]\n     */\n    protected $resolved = [];\n\n    /**\n     * The container's bindings.\n     *\n     * @var array[]\n     */\n    protected $bindings = [];\n\n    /**\n     * The container's method bindings.\n     *\n     * @var \\Closure[]\n     */\n    protected $methodBindings = [];\n\n    /**\n     * The container's shared instances.\n     *\n     * @var object[]\n     */\n    protected $instances = [];\n\n    /**\n     * The container's scoped instances.\n     *\n     * @var array\n     */\n    protected $scopedInstances = [];\n\n    /**\n     * The registered type aliases.\n     *\n     * @var string[]\n     */\n    protected $aliases = [];\n\n    /**\n     * The registered aliases keyed by the abstract name.\n     *\n     * @var array[]\n     */\n    protected $abstractAliases = [];\n\n    /**\n     * The extension closures for services.\n     *\n     * @var array[]\n     */\n    protected $extenders = [];\n\n    /**\n     * All of the registered tags.\n     *\n     * @var array[]\n     */\n    protected $tags = [];\n\n    /**\n     * The stack of concretions currently being built.\n     *\n     * @var array[]\n     */\n    protected $buildStack = [];\n\n    /**\n     * The parameter override stack.\n     *\n     * @var array[]\n     */\n    protected $with = [];\n\n    /**\n     * The contextual binding map.\n     *\n     * @var array[]\n     */\n    public $contextual = [];\n\n    /**\n     * The contextual attribute handlers.\n     *\n     * @var array[]\n     */\n    public $contextualAttributes = [];\n\n    /**\n     * Whether an abstract class has already had its attributes checked for bindings.\n     *\n     * @var array<class-string, true>\n     */\n    protected $checkedForAttributeBindings = [];\n\n    /**\n     * Whether a class has already been checked for Singleton or Scoped attributes.\n     *\n     * @var array<class-string, \"scoped\"|\"singleton\"|null>\n     */\n    protected $checkedForSingletonOrScopedAttributes = [];\n\n    /**\n     * All of the registered rebound callbacks.\n     *\n     * @var array[]\n     */\n    protected $reboundCallbacks = [];\n\n    /**\n     * All of the global before resolving callbacks.\n     *\n     * @var \\Closure[]\n     */\n    protected $globalBeforeResolvingCallbacks = [];\n\n    /**\n     * All of the global resolving callbacks.\n     *\n     * @var \\Closure[]\n     */\n    protected $globalResolvingCallbacks = [];\n\n    /**\n     * All of the global after resolving callbacks.\n     *\n     * @var \\Closure[]\n     */\n    protected $globalAfterResolvingCallbacks = [];\n\n    /**\n     * All of the before resolving callbacks by class type.\n     *\n     * @var array[]\n     */\n    protected $beforeResolvingCallbacks = [];\n\n    /**\n     * All of the resolving callbacks by class type.\n     *\n     * @var array[]\n     */\n    protected $resolvingCallbacks = [];\n\n    /**\n     * All of the after resolving callbacks by class type.\n     *\n     * @var array[]\n     */\n    protected $afterResolvingCallbacks = [];\n\n    /**\n     * All of the after resolving attribute callbacks by class type.\n     *\n     * @var array[]\n     */\n    protected $afterResolvingAttributeCallbacks = [];\n\n    /**\n     * The callback used to determine the container's environment.\n     *\n     * @var (callable(array<int, string>|string): bool|string)|null\n     */\n    protected $environmentResolver = null;\n\n    /**\n     * Define a contextual binding.\n     *\n     * @param  array|string  $concrete\n     * @return \\Illuminate\\Contracts\\Container\\ContextualBindingBuilder\n     */\n    public function when($concrete)\n    {\n        $aliases = [];\n\n        foreach (Util::arrayWrap($concrete) as $c) {\n            $aliases[] = $this->getAlias($c);\n        }\n\n        return new ContextualBindingBuilder($this, $aliases);\n    }\n\n    /**\n     * Define a contextual binding based on an attribute.\n     *\n     * @return void\n     */\n    public function whenHasAttribute(string $attribute, Closure $handler)\n    {\n        $this->contextualAttributes[$attribute] = $handler;\n    }\n\n    /**\n     * Determine if the given abstract type has been bound.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function bound($abstract)\n    {\n        return isset($this->bindings[$abstract]) ||\n               isset($this->instances[$abstract]) ||\n               $this->isAlias($abstract);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function has(string $id): bool\n    {\n        return $this->bound($id);\n    }\n\n    /**\n     * Determine if the given abstract type has been resolved.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function resolved($abstract)\n    {\n        if ($this->isAlias($abstract)) {\n            $abstract = $this->getAlias($abstract);\n        }\n\n        return isset($this->resolved[$abstract]) ||\n               isset($this->instances[$abstract]);\n    }\n\n    /**\n     * Determine if a given type is shared.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function isShared($abstract)\n    {\n        if (isset($this->instances[$abstract])) {\n            return true;\n        }\n\n        if (isset($this->bindings[$abstract]['shared']) && $this->bindings[$abstract]['shared'] === true) {\n            return true;\n        }\n\n        if (! class_exists($abstract)) {\n            return false;\n        }\n\n        if (($scopedType = $this->getScopedTyped($abstract)) === null) {\n            return false;\n        }\n\n        if ($scopedType === 'scoped') {\n            if (! in_array($abstract, $this->scopedInstances, true)) {\n                $this->scopedInstances[] = $abstract;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if a ReflectionClass has scoping attributes applied.\n     *\n     * @param  ReflectionClass<object>|class-string  $reflection\n     * @return \"singleton\"|\"scoped\"|null\n     */\n    protected function getScopedTyped(ReflectionClass|string $reflection): ?string\n    {\n        $className = $reflection instanceof ReflectionClass\n            ? $reflection->getName()\n            : $reflection;\n\n        if (array_key_exists($className, $this->checkedForSingletonOrScopedAttributes)) {\n            return $this->checkedForSingletonOrScopedAttributes[$className];\n        }\n\n        try {\n            $reflection = $reflection instanceof ReflectionClass\n                ? $reflection\n                : new ReflectionClass($reflection);\n        } catch (ReflectionException) {\n            return $this->checkedForSingletonOrScopedAttributes[$className] = null;\n        }\n\n        $type = null;\n\n        if (! empty($reflection->getAttributes(Singleton::class))) {\n            $type = 'singleton';\n        } elseif (! empty($reflection->getAttributes(Scoped::class))) {\n            $type = 'scoped';\n        }\n\n        return $this->checkedForSingletonOrScopedAttributes[$className] = $type;\n    }\n\n    /**\n     * Determine if a given string is an alias.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function isAlias($name)\n    {\n        return isset($this->aliases[$name]);\n    }\n\n    /**\n     * Register a binding with the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @param  bool  $shared\n     * @return void\n     *\n     * @throws \\TypeError\n     * @throws ReflectionException\n     */\n    public function bind($abstract, $concrete = null, $shared = false)\n    {\n        if ($abstract instanceof Closure) {\n            return $this->bindBasedOnClosureReturnTypes(\n                $abstract, $concrete, $shared\n            );\n        }\n\n        $this->dropStaleInstances($abstract);\n\n        // If no concrete type was given, we will simply set the concrete type to the\n        // abstract type. After that, the concrete type to be registered as shared\n        // without being forced to state their classes in both of the parameters.\n        if (is_null($concrete)) {\n            $concrete = $abstract;\n        }\n\n        // If the factory is not a Closure, it means it is just a class name which is\n        // bound into this container to the abstract type and we will just wrap it\n        // up inside its own Closure to give us more convenience when extending.\n        if (! $concrete instanceof Closure) {\n            if (! is_string($concrete)) {\n                throw new TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null');\n            }\n\n            $concrete = $this->getClosure($abstract, $concrete);\n        }\n\n        $this->bindings[$abstract] = ['concrete' => $concrete, 'shared' => $shared];\n\n        // If the abstract type was already resolved in this container we'll fire the\n        // rebound listener so that any objects which have already gotten resolved\n        // can have their copy of the object updated via the listener callbacks.\n        if ($this->resolved($abstract)) {\n            $this->rebound($abstract);\n        }\n    }\n\n    /**\n     * Get the Closure to be used when building a type.\n     *\n     * @param  string  $abstract\n     * @param  string  $concrete\n     * @return \\Closure\n     */\n    protected function getClosure($abstract, $concrete)\n    {\n        return function ($container, $parameters = []) use ($abstract, $concrete) {\n            if ($abstract == $concrete) {\n                return $container->build($concrete);\n            }\n\n            return $container->resolve(\n                $concrete, $parameters, raiseEvents: false\n            );\n        };\n    }\n\n    /**\n     * Determine if the container has a method binding.\n     *\n     * @param  string  $method\n     * @return bool\n     */\n    public function hasMethodBinding($method)\n    {\n        return isset($this->methodBindings[$method]);\n    }\n\n    /**\n     * Bind a callback to resolve with Container::call.\n     *\n     * @param  array|string  $method\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function bindMethod($method, $callback)\n    {\n        $this->methodBindings[$this->parseBindMethod($method)] = $callback;\n    }\n\n    /**\n     * Get the method to be bound in class@method format.\n     *\n     * @param  array|string  $method\n     * @return string\n     */\n    protected function parseBindMethod($method)\n    {\n        if (is_array($method)) {\n            return $method[0].'@'.$method[1];\n        }\n\n        return $method;\n    }\n\n    /**\n     * Get the method binding for the given method.\n     *\n     * @param  string  $method\n     * @param  mixed  $instance\n     * @return mixed\n     */\n    public function callMethodBinding($method, $instance)\n    {\n        return call_user_func($this->methodBindings[$method], $instance, $this);\n    }\n\n    /**\n     * Add a contextual binding to the container.\n     *\n     * @param  string  $concrete\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string  $implementation\n     * @return void\n     */\n    public function addContextualBinding($concrete, $abstract, $implementation)\n    {\n        $this->contextual[$concrete][$this->getAlias($abstract)] = $implementation;\n    }\n\n    /**\n     * Register a binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @param  bool  $shared\n     * @return void\n     */\n    public function bindIf($abstract, $concrete = null, $shared = false)\n    {\n        if (! $this->bound($abstract)) {\n            $this->bind($abstract, $concrete, $shared);\n        }\n    }\n\n    /**\n     * Register a shared binding in the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function singleton($abstract, $concrete = null)\n    {\n        $this->bind($abstract, $concrete, true);\n    }\n\n    /**\n     * Register a shared binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function singletonIf($abstract, $concrete = null)\n    {\n        if (! $this->bound($abstract)) {\n            $this->singleton($abstract, $concrete);\n        }\n    }\n\n    /**\n     * Register a scoped binding in the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function scoped($abstract, $concrete = null)\n    {\n        $this->scopedInstances[] = $abstract;\n\n        $this->singleton($abstract, $concrete);\n    }\n\n    /**\n     * Register a scoped binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function scopedIf($abstract, $concrete = null)\n    {\n        if (! $this->bound($abstract)) {\n            $this->scoped($abstract, $concrete);\n        }\n    }\n\n    /**\n     * Register a binding with the container based on the given Closure's return types.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @param  bool  $shared\n     * @return void\n     */\n    protected function bindBasedOnClosureReturnTypes($abstract, $concrete = null, $shared = false)\n    {\n        $abstracts = $this->closureReturnTypes($abstract);\n\n        $concrete = $abstract;\n\n        foreach ($abstracts as $abstract) {\n            $this->bind($abstract, $concrete, $shared);\n        }\n    }\n\n    /**\n     * \"Extend\" an abstract type in the container.\n     *\n     * @param  string  $abstract\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function extend($abstract, Closure $closure)\n    {\n        $abstract = $this->getAlias($abstract);\n\n        if (isset($this->instances[$abstract])) {\n            $this->instances[$abstract] = $closure($this->instances[$abstract], $this);\n\n            $this->rebound($abstract);\n        } else {\n            $this->extenders[$abstract][] = $closure;\n\n            if ($this->resolved($abstract)) {\n                $this->rebound($abstract);\n            }\n        }\n    }\n\n    /**\n     * Register an existing instance as shared in the container.\n     *\n     * @template TInstance of mixed\n     *\n     * @param  string  $abstract\n     * @param  TInstance  $instance\n     * @return TInstance\n     */\n    public function instance($abstract, $instance)\n    {\n        $this->removeAbstractAlias($abstract);\n\n        $isBound = $this->bound($abstract);\n\n        unset($this->aliases[$abstract]);\n\n        // We'll check to determine if this type has been bound before, and if it has\n        // we will fire the rebound callbacks registered with the container and it\n        // can be updated with consuming classes that have gotten resolved here.\n        $this->instances[$abstract] = $instance;\n\n        if ($isBound) {\n            $this->rebound($abstract);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Remove an alias from the contextual binding alias cache.\n     *\n     * @param  string  $searched\n     * @return void\n     */\n    protected function removeAbstractAlias($searched)\n    {\n        if (! isset($this->aliases[$searched])) {\n            return;\n        }\n\n        foreach ($this->abstractAliases as $abstract => $aliases) {\n            foreach ($aliases as $index => $alias) {\n                if ($alias == $searched) {\n                    unset($this->abstractAliases[$abstract][$index]);\n                }\n            }\n        }\n    }\n\n    /**\n     * Assign a set of tags to a given binding.\n     *\n     * @param  array|string  $abstracts\n     * @param  mixed  ...$tags\n     * @return void\n     */\n    public function tag($abstracts, $tags)\n    {\n        $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1);\n\n        foreach ($tags as $tag) {\n            if (! isset($this->tags[$tag])) {\n                $this->tags[$tag] = [];\n            }\n\n            foreach ((array) $abstracts as $abstract) {\n                $this->tags[$tag][] = $abstract;\n            }\n        }\n    }\n\n    /**\n     * Resolve all of the bindings for a given tag.\n     *\n     * @param  string  $tag\n     * @return iterable\n     */\n    public function tagged($tag)\n    {\n        if (! isset($this->tags[$tag])) {\n            return [];\n        }\n\n        return new RewindableGenerator(function () use ($tag) {\n            foreach ($this->tags[$tag] as $abstract) {\n                yield $this->make($abstract);\n            }\n        }, count($this->tags[$tag]));\n    }\n\n    /**\n     * Alias a type to a different name.\n     *\n     * @param  string  $abstract\n     * @param  string  $alias\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function alias($abstract, $alias)\n    {\n        if ($alias === $abstract) {\n            throw new LogicException(\"[{$abstract}] is aliased to itself.\");\n        }\n\n        $this->removeAbstractAlias($alias);\n\n        $this->aliases[$alias] = $abstract;\n\n        $this->abstractAliases[$abstract][] = $alias;\n    }\n\n    /**\n     * Bind a new callback to an abstract's rebind event.\n     *\n     * @param  string  $abstract\n     * @return mixed\n     */\n    public function rebinding($abstract, Closure $callback)\n    {\n        $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback;\n\n        if ($this->bound($abstract)) {\n            return $this->make($abstract);\n        }\n    }\n\n    /**\n     * Refresh an instance on the given target and method.\n     *\n     * @param  string  $abstract\n     * @param  mixed  $target\n     * @param  string  $method\n     * @return mixed\n     */\n    public function refresh($abstract, $target, $method)\n    {\n        return $this->rebinding($abstract, function ($app, $instance) use ($target, $method) {\n            $target->{$method}($instance);\n        });\n    }\n\n    /**\n     * Fire the \"rebound\" callbacks for the given abstract type.\n     *\n     * @param  string  $abstract\n     * @return void\n     */\n    protected function rebound($abstract)\n    {\n        if (! $callbacks = $this->getReboundCallbacks($abstract)) {\n            return;\n        }\n\n        $instance = $this->make($abstract);\n\n        foreach ($callbacks as $callback) {\n            $callback($this, $instance);\n        }\n    }\n\n    /**\n     * Get the rebound callbacks for a given type.\n     *\n     * @param  string  $abstract\n     * @return array\n     */\n    protected function getReboundCallbacks($abstract)\n    {\n        return $this->reboundCallbacks[$abstract] ?? [];\n    }\n\n    /**\n     * Wrap the given closure such that its dependencies will be injected when executed.\n     *\n     * @return \\Closure\n     */\n    public function wrap(Closure $callback, array $parameters = [])\n    {\n        return fn () => $this->call($callback, $parameters);\n    }\n\n    /**\n     * Call the given Closure / class@method and inject its dependencies.\n     *\n     * @param  callable|string  $callback\n     * @param  array<string, mixed>  $parameters\n     * @param  string|null  $defaultMethod\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function call($callback, array $parameters = [], $defaultMethod = null)\n    {\n        $pushedToBuildStack = false;\n\n        if (($className = $this->getClassForCallable($callback)) && ! in_array(\n            $className,\n            $this->buildStack,\n            true\n        )) {\n            $this->buildStack[] = $className;\n\n            $pushedToBuildStack = true;\n        }\n\n        $result = BoundMethod::call($this, $callback, $parameters, $defaultMethod);\n\n        if ($pushedToBuildStack) {\n            array_pop($this->buildStack);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get the class name for the given callback, if one can be determined.\n     *\n     * @param  callable|string  $callback\n     * @return string|false\n     */\n    protected function getClassForCallable($callback)\n    {\n        if (is_callable($callback) &&\n            ! ($reflector = new ReflectionFunction($callback(...)))->isAnonymous()) {\n            return $reflector->getClosureScopeClass()->name ?? false;\n        }\n\n        return false;\n    }\n\n    /**\n     * Get a closure to resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $abstract\n     * @return ($abstract is class-string<TClass> ? \\Closure(): TClass : \\Closure(): mixed)\n     */\n    public function factory($abstract)\n    {\n        return fn () => $this->make($abstract);\n    }\n\n    /**\n     * An alias function name for make().\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>|callable  $abstract\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function makeWith($abstract, array $parameters = [])\n    {\n        return $this->make($abstract, $parameters);\n    }\n\n    /**\n     * Resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $abstract\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function make($abstract, array $parameters = [])\n    {\n        return $this->resolve($abstract, $parameters);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $id\n     * @return ($id is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\CircularDependencyException\n     * @throws \\Illuminate\\Container\\EntryNotFoundException\n     */\n    public function get(string $id)\n    {\n        try {\n            return $this->resolve($id);\n        } catch (Exception $e) {\n            if ($this->has($id) || $e instanceof CircularDependencyException) {\n                throw $e;\n            }\n\n            throw new EntryNotFoundException($id, is_int($e->getCode()) ? $e->getCode() : 0, $e);\n        }\n    }\n\n    /**\n     * Resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>|callable  $abstract\n     * @param  array  $parameters\n     * @param  bool  $raiseEvents\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     * @throws \\Illuminate\\Contracts\\Container\\CircularDependencyException\n     */\n    protected function resolve($abstract, $parameters = [], $raiseEvents = true)\n    {\n        $abstract = $this->getAlias($abstract);\n\n        // First we'll fire any event handlers which handle the \"before\" resolving of\n        // specific types. This gives some hooks the chance to add various extends\n        // calls to change the resolution of objects that they're interested in.\n        if ($raiseEvents) {\n            $this->fireBeforeResolvingCallbacks($abstract, $parameters);\n        }\n\n        $concrete = $this->getContextualConcrete($abstract);\n\n        $needsContextualBuild = ! empty($parameters) || ! is_null($concrete);\n\n        // If an instance of the type is currently being managed as a singleton we'll\n        // just return an existing instance instead of instantiating new instances\n        // so the developer can keep using the same objects instance every time.\n        if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {\n            return $this->instances[$abstract];\n        }\n\n        $this->with[] = $parameters;\n\n        if (is_null($concrete)) {\n            $concrete = $this->getConcrete($abstract);\n        }\n\n        // We're ready to instantiate an instance of the concrete type registered for\n        // the binding. This will instantiate the types, as well as resolve any of\n        // its \"nested\" dependencies recursively until all have gotten resolved.\n        $object = $this->isBuildable($concrete, $abstract)\n            ? $this->build($concrete)\n            : $this->make($concrete);\n\n        // If we defined any extenders for this type, we'll need to spin through them\n        // and apply them to the object being built. This allows for the extension\n        // of services, such as changing configuration or decorating the object.\n        foreach ($this->getExtenders($abstract) as $extender) {\n            $object = $extender($object, $this);\n        }\n\n        // If the requested type is registered as a singleton we'll want to cache off\n        // the instances in \"memory\" so we can return it later without creating an\n        // entirely new instance of an object on each subsequent request for it.\n        if ($this->isShared($abstract) && ! $needsContextualBuild) {\n            $this->instances[$abstract] = $object;\n        }\n\n        if ($raiseEvents) {\n            $this->fireResolvingCallbacks($abstract, $object);\n        }\n\n        // Before returning, we will also set the resolved flag to \"true\" and pop off\n        // the parameter overrides for this build. After those two things are done\n        // we will be ready to return back the fully constructed class instance.\n        if (! $needsContextualBuild) {\n            $this->resolved[$abstract] = true;\n        }\n\n        array_pop($this->with);\n\n        return $object;\n    }\n\n    /**\n     * Get the concrete type for a given abstract.\n     *\n     * @param  string|callable  $abstract\n     * @return mixed\n     */\n    protected function getConcrete($abstract)\n    {\n        // If we don't have a registered resolver or concrete for the type, we'll just\n        // assume each type is a concrete name and will attempt to resolve it as is\n        // since the container should be able to resolve concretes automatically.\n        if (isset($this->bindings[$abstract])) {\n            return $this->bindings[$abstract]['concrete'];\n        }\n\n        if ($this->environmentResolver === null ||\n            ($this->checkedForAttributeBindings[$abstract] ?? false) || ! is_string($abstract)) {\n            return $abstract;\n        }\n\n        return $this->getConcreteBindingFromAttributes($abstract);\n    }\n\n    /**\n     * Get the concrete binding for an abstract from the Bind attribute.\n     *\n     * @param  string  $abstract\n     * @return mixed\n     */\n    protected function getConcreteBindingFromAttributes($abstract)\n    {\n        $this->checkedForAttributeBindings[$abstract] = true;\n\n        try {\n            $reflected = new ReflectionClass($abstract);\n        } catch (ReflectionException) {\n            return $abstract;\n        }\n\n        $bindAttributes = $reflected->getAttributes(Bind::class);\n\n        if ($bindAttributes === []) {\n            return $abstract;\n        }\n\n        $concrete = $maybeConcrete = null;\n\n        foreach ($bindAttributes as $reflectedAttribute) {\n            $instance = $reflectedAttribute->newInstance();\n\n            if ($instance->environments === ['*']) {\n                $maybeConcrete = $instance->concrete;\n\n                continue;\n            }\n\n            if ($this->currentEnvironmentIs($instance->environments)) {\n                $concrete = $instance->concrete;\n\n                break;\n            }\n        }\n\n        if ($maybeConcrete !== null && $concrete === null) {\n            $concrete = $maybeConcrete;\n        }\n\n        if ($concrete === null) {\n            return $abstract;\n        }\n\n        match ($this->getScopedTyped($reflected)) {\n            'scoped' => $this->scoped($abstract, $concrete),\n            'singleton' => $this->singleton($abstract, $concrete),\n            null => $this->bind($abstract, $concrete),\n        };\n\n        return $this->bindings[$abstract]['concrete'];\n    }\n\n    /**\n     * Get the contextual concrete binding for the given abstract.\n     *\n     * @param  string|callable  $abstract\n     * @return \\Closure|string|array|null\n     */\n    protected function getContextualConcrete($abstract)\n    {\n        if (! is_null($binding = $this->findInContextualBindings($abstract))) {\n            return $binding;\n        }\n\n        // Next we need to see if a contextual binding might be bound under an alias of the\n        // given abstract type. So, we will need to check if any aliases exist with this\n        // type and then spin through them and check for contextual bindings on these.\n        if (empty($this->abstractAliases[$abstract])) {\n            return;\n        }\n\n        foreach ($this->abstractAliases[$abstract] as $alias) {\n            if (! is_null($binding = $this->findInContextualBindings($alias))) {\n                return $binding;\n            }\n        }\n    }\n\n    /**\n     * Find the concrete binding for the given abstract in the contextual binding array.\n     *\n     * @param  string|callable  $abstract\n     * @return \\Closure|string|null\n     */\n    protected function findInContextualBindings($abstract)\n    {\n        return $this->contextual[end($this->buildStack)][$abstract] ?? null;\n    }\n\n    /**\n     * Determine if the given concrete is buildable.\n     *\n     * @param  mixed  $concrete\n     * @param  string  $abstract\n     * @return bool\n     */\n    protected function isBuildable($concrete, $abstract)\n    {\n        return $concrete === $abstract || $concrete instanceof Closure;\n    }\n\n    /**\n     * Instantiate a concrete instance of the given type.\n     *\n     * @template TClass of object\n     *\n     * @param  \\Closure(static, array): TClass|class-string<TClass>  $concrete\n     * @return TClass\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     * @throws \\Illuminate\\Contracts\\Container\\CircularDependencyException\n     */\n    public function build($concrete)\n    {\n        // If the concrete type is actually a Closure, we will just execute it and\n        // hand back the results of the functions, which allows functions to be\n        // used as resolvers for more fine-tuned resolution of these objects.\n        if ($concrete instanceof Closure) {\n            $this->buildStack[] = spl_object_hash($concrete);\n\n            try {\n                return $concrete($this, $this->getLastParameterOverride());\n            } finally {\n                array_pop($this->buildStack);\n            }\n        }\n\n        try {\n            $reflector = new ReflectionClass($concrete);\n        } catch (ReflectionException $e) {\n            throw new BindingResolutionException(\"Target class [$concrete] does not exist.\", 0, $e);\n        }\n\n        // If the type is not instantiable, the developer is attempting to resolve\n        // an abstract type such as an Interface or Abstract Class and there is\n        // no binding registered for the abstractions so we need to bail out.\n        if (! $reflector->isInstantiable()) {\n            return $this->notInstantiable($concrete);\n        }\n\n        if (is_a($concrete, SelfBuilding::class, true) &&\n            ! in_array($concrete, $this->buildStack, true)) {\n            return $this->buildSelfBuildingInstance($concrete, $reflector);\n        }\n\n        $this->buildStack[] = $concrete;\n\n        $constructor = $reflector->getConstructor();\n\n        // If there are no constructors, that means there are no dependencies then\n        // we can just resolve the instances of the objects right away, without\n        // resolving any other types or dependencies out of these containers.\n        if (is_null($constructor)) {\n            array_pop($this->buildStack);\n\n            $this->fireAfterResolvingAttributeCallbacks(\n                $reflector->getAttributes(), $instance = new $concrete\n            );\n\n            return $instance;\n        }\n\n        $dependencies = $constructor->getParameters();\n\n        // Once we have all the constructor's parameters we can create each of the\n        // dependency instances and then use the reflection instances to make a\n        // new instance of this class, injecting the created dependencies in.\n        try {\n            $instances = $this->resolveDependencies($dependencies);\n        } finally {\n            array_pop($this->buildStack);\n        }\n\n        $this->fireAfterResolvingAttributeCallbacks(\n            $reflector->getAttributes(), $instance = new $concrete(...$instances)\n        );\n\n        return $instance;\n    }\n\n    /**\n     * Instantiate a concrete instance of the given self building type.\n     *\n     * @template TClass of object\n     *\n     * @param  object{'newInstance': \\Closure(static, array): TClass|class-string<TClass>}  $concrete\n     * @param  \\ReflectionClass  $reflector\n     * @return TClass\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function buildSelfBuildingInstance($concrete, $reflector)\n    {\n        if (! method_exists($concrete, 'newInstance')) {\n            throw new BindingResolutionException(\"No newInstance method exists for [$concrete].\");\n        }\n\n        $this->buildStack[] = $concrete;\n\n        $instance = $this->call([$concrete, 'newInstance']);\n\n        array_pop($this->buildStack);\n\n        $this->fireAfterResolvingAttributeCallbacks(\n            $reflector->getAttributes(), $instance\n        );\n\n        return $instance;\n    }\n\n    /**\n     * Resolve all of the dependencies from the ReflectionParameters.\n     *\n     * @param  \\ReflectionParameter[]  $dependencies\n     * @return array\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function resolveDependencies(array $dependencies)\n    {\n        $results = [];\n\n        foreach ($dependencies as $dependency) {\n            // If the dependency has an override for this particular build we will use\n            // that instead as the value. Otherwise, we will continue with this run\n            // of resolutions and let reflection attempt to determine the result.\n            if ($this->hasParameterOverride($dependency)) {\n                $results[] = $this->getParameterOverride($dependency);\n\n                continue;\n            }\n\n            $result = null;\n\n            if (! is_null($attribute = Util::getContextualAttributeFromDependency($dependency))) {\n                $result = $this->resolveFromAttribute($attribute);\n            }\n\n            // If the class is null, it means the dependency is a string or some other\n            // primitive type which we can not resolve since it is not a class and\n            // we will just bomb out with an error since we have no-where to go.\n            $result ??= is_null($className = Util::getParameterClassName($dependency))\n                ? $this->resolvePrimitive($dependency)\n                : $this->resolveClass($dependency, $className);\n\n            $this->fireAfterResolvingAttributeCallbacks($dependency->getAttributes(), $result);\n\n            if ($dependency->isVariadic()) {\n                $results = array_merge($results, $result);\n            } else {\n                $results[] = $result;\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Determine if the given dependency has a parameter override.\n     *\n     * @param  \\ReflectionParameter  $dependency\n     * @return bool\n     */\n    protected function hasParameterOverride($dependency)\n    {\n        return array_key_exists(\n            $dependency->name, $this->getLastParameterOverride()\n        );\n    }\n\n    /**\n     * Get a parameter override for a dependency.\n     *\n     * @param  \\ReflectionParameter  $dependency\n     * @return mixed\n     */\n    protected function getParameterOverride($dependency)\n    {\n        return $this->getLastParameterOverride()[$dependency->name];\n    }\n\n    /**\n     * Get the last parameter override.\n     *\n     * @return array\n     */\n    protected function getLastParameterOverride()\n    {\n        return count($this->with) ? array_last($this->with) : [];\n    }\n\n    /**\n     * Resolve a non-class hinted primitive dependency.\n     *\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function resolvePrimitive(ReflectionParameter $parameter)\n    {\n        if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->getName()))) {\n            return Util::unwrapIfClosure($concrete, $this);\n        }\n\n        if ($parameter->isDefaultValueAvailable()) {\n            return $parameter->getDefaultValue();\n        }\n\n        if ($parameter->isVariadic()) {\n            return [];\n        }\n\n        if ($parameter->hasType() && $parameter->allowsNull()) {\n            return null;\n        }\n\n        $this->unresolvablePrimitive($parameter);\n    }\n\n    /**\n     * Resolve a class based dependency from the container.\n     *\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function resolveClass(ReflectionParameter $parameter, ?string $className = null)\n    {\n        $className ??= Util::getParameterClassName($parameter);\n\n        // First we will check if a default value has been defined for the parameter.\n        // If it has, and no explicit binding exists, we should return it to avoid\n        // overriding any of the developer specified defaults for the parameters.\n        if ($parameter->isDefaultValueAvailable() &&\n            ! $this->bound($className) &&\n            $this->findInContextualBindings($className) === null) {\n            return $parameter->getDefaultValue();\n        }\n\n        try {\n            return $parameter->isVariadic()\n                ? $this->resolveVariadicClass($parameter)\n                : $this->make($className);\n        }\n\n        // If we can not resolve the class instance, we will check to see if the value\n        // is variadic. If it is, we will return an empty array as the value of the\n        // dependency similarly to how we handle scalar values in this situation.\n        catch (BindingResolutionException $e) {\n            if ($parameter->isVariadic()) {\n                array_pop($this->with);\n\n                return [];\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Resolve a class based variadic dependency from the container.\n     *\n     * @return mixed\n     */\n    protected function resolveVariadicClass(ReflectionParameter $parameter)\n    {\n        $className = Util::getParameterClassName($parameter);\n\n        $abstract = $this->getAlias($className);\n\n        if (! is_array($concrete = $this->getContextualConcrete($abstract))) {\n            return $this->make($className);\n        }\n\n        return array_map(fn ($abstract) => $this->resolve($abstract), $concrete);\n    }\n\n    /**\n     * Resolve a dependency based on an attribute.\n     *\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function resolveFromAttribute(ReflectionAttribute $attribute)\n    {\n        $handler = $this->contextualAttributes[$attribute->getName()] ?? null;\n\n        $instance = $attribute->newInstance();\n\n        if (is_null($handler) && method_exists($instance, 'resolve')) {\n            $handler = $instance->resolve(...);\n        }\n\n        if (is_null($handler)) {\n            throw new BindingResolutionException(\"Contextual binding attribute [{$attribute->getName()}] has no registered handler.\");\n        }\n\n        return $handler($instance, $this);\n    }\n\n    /**\n     * Throw an exception that the concrete is not instantiable.\n     *\n     * @param  string  $concrete\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function notInstantiable($concrete)\n    {\n        if (! empty($this->buildStack)) {\n            $previous = implode(', ', $this->buildStack);\n\n            $message = \"Target [$concrete] is not instantiable while building [$previous].\";\n        } else {\n            $message = \"Target [$concrete] is not instantiable.\";\n        }\n\n        throw new BindingResolutionException($message);\n    }\n\n    /**\n     * Throw an exception for an unresolvable primitive.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function unresolvablePrimitive(ReflectionParameter $parameter)\n    {\n        $message = \"Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}\";\n\n        throw new BindingResolutionException($message);\n    }\n\n    /**\n     * Register a new before resolving callback for all types.\n     *\n     * @param  \\Closure|string  $abstract\n     * @return void\n     */\n    public function beforeResolving($abstract, ?Closure $callback = null)\n    {\n        if (is_string($abstract)) {\n            $abstract = $this->getAlias($abstract);\n        }\n\n        if ($abstract instanceof Closure && is_null($callback)) {\n            $this->globalBeforeResolvingCallbacks[] = $abstract;\n        } else {\n            $this->beforeResolvingCallbacks[$abstract][] = $callback;\n        }\n    }\n\n    /**\n     * Register a new resolving callback.\n     *\n     * @param  \\Closure|string  $abstract\n     * @return void\n     */\n    public function resolving($abstract, ?Closure $callback = null)\n    {\n        if (is_string($abstract)) {\n            $abstract = $this->getAlias($abstract);\n        }\n\n        if (is_null($callback) && $abstract instanceof Closure) {\n            $this->globalResolvingCallbacks[] = $abstract;\n        } else {\n            $this->resolvingCallbacks[$abstract][] = $callback;\n        }\n    }\n\n    /**\n     * Register a new after resolving callback for all types.\n     *\n     * @param  \\Closure|string  $abstract\n     * @return void\n     */\n    public function afterResolving($abstract, ?Closure $callback = null)\n    {\n        if (is_string($abstract)) {\n            $abstract = $this->getAlias($abstract);\n        }\n\n        if ($abstract instanceof Closure && is_null($callback)) {\n            $this->globalAfterResolvingCallbacks[] = $abstract;\n        } else {\n            $this->afterResolvingCallbacks[$abstract][] = $callback;\n        }\n    }\n\n    /**\n     * Register a new after resolving attribute callback for all types.\n     *\n     * @return void\n     */\n    public function afterResolvingAttribute(string $attribute, \\Closure $callback)\n    {\n        $this->afterResolvingAttributeCallbacks[$attribute][] = $callback;\n    }\n\n    /**\n     * Fire all of the before resolving callbacks.\n     *\n     * @param  string  $abstract\n     * @param  array  $parameters\n     * @return void\n     */\n    protected function fireBeforeResolvingCallbacks($abstract, $parameters = [])\n    {\n        $this->fireBeforeCallbackArray($abstract, $parameters, $this->globalBeforeResolvingCallbacks);\n\n        foreach ($this->beforeResolvingCallbacks as $type => $callbacks) {\n            if ($type === $abstract || is_subclass_of($abstract, $type)) {\n                $this->fireBeforeCallbackArray($abstract, $parameters, $callbacks);\n            }\n        }\n    }\n\n    /**\n     * Fire an array of callbacks with an object.\n     *\n     * @param  string  $abstract\n     * @param  array  $parameters\n     * @return void\n     */\n    protected function fireBeforeCallbackArray($abstract, $parameters, array $callbacks)\n    {\n        foreach ($callbacks as $callback) {\n            $callback($abstract, $parameters, $this);\n        }\n    }\n\n    /**\n     * Fire all of the resolving callbacks.\n     *\n     * @param  string  $abstract\n     * @param  mixed  $object\n     * @return void\n     */\n    protected function fireResolvingCallbacks($abstract, $object)\n    {\n        $this->fireCallbackArray($object, $this->globalResolvingCallbacks);\n\n        $this->fireCallbackArray(\n            $object, $this->getCallbacksForType($abstract, $object, $this->resolvingCallbacks)\n        );\n\n        $this->fireAfterResolvingCallbacks($abstract, $object);\n    }\n\n    /**\n     * Fire all of the after resolving callbacks.\n     *\n     * @param  string  $abstract\n     * @param  mixed  $object\n     * @return void\n     */\n    protected function fireAfterResolvingCallbacks($abstract, $object)\n    {\n        $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks);\n\n        $this->fireCallbackArray(\n            $object, $this->getCallbacksForType($abstract, $object, $this->afterResolvingCallbacks)\n        );\n    }\n\n    /**\n     * Fire all of the after resolving attribute callbacks.\n     *\n     * @param  \\ReflectionAttribute[]  $attributes\n     * @param  mixed  $object\n     * @return void\n     */\n    public function fireAfterResolvingAttributeCallbacks(array $attributes, $object)\n    {\n        foreach ($attributes as $attribute) {\n            if (is_a($attribute->getName(), ContextualAttribute::class, true)) {\n                $instance = $attribute->newInstance();\n\n                if (method_exists($instance, 'after')) {\n                    $instance->after($instance, $object, $this);\n                }\n            }\n\n            $callbacks = $this->getCallbacksForType(\n                $attribute->getName(), $object, $this->afterResolvingAttributeCallbacks\n            );\n\n            foreach ($callbacks as $callback) {\n                $callback($attribute->newInstance(), $object, $this);\n            }\n        }\n    }\n\n    /**\n     * Get all callbacks for a given type.\n     *\n     * @param  string  $abstract\n     * @param  object  $object\n     * @return array\n     */\n    protected function getCallbacksForType($abstract, $object, array $callbacksPerType)\n    {\n        $results = [];\n\n        foreach ($callbacksPerType as $type => $callbacks) {\n            if ($type === $abstract || $object instanceof $type) {\n                $results = array_merge($results, $callbacks);\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Fire an array of callbacks with an object.\n     *\n     * @param  mixed  $object\n     * @return void\n     */\n    protected function fireCallbackArray($object, array $callbacks)\n    {\n        foreach ($callbacks as $callback) {\n            $callback($object, $this);\n        }\n    }\n\n    /**\n     * Get the name of the binding the container is currently resolving.\n     *\n     * @return class-string|string|null\n     */\n    public function currentlyResolving()\n    {\n        return array_last($this->buildStack) ?: null;\n    }\n\n    /**\n     * Get the container's bindings.\n     *\n     * @return array\n     */\n    public function getBindings()\n    {\n        return $this->bindings;\n    }\n\n    /**\n     * Get the alias for an abstract if available.\n     *\n     * @param  string  $abstract\n     * @return string\n     */\n    public function getAlias($abstract)\n    {\n        return isset($this->aliases[$abstract])\n            ? $this->getAlias($this->aliases[$abstract])\n            : $abstract;\n    }\n\n    /**\n     * Get the extender callbacks for a given type.\n     *\n     * @param  string  $abstract\n     * @return array\n     */\n    protected function getExtenders($abstract)\n    {\n        return $this->extenders[$this->getAlias($abstract)] ?? [];\n    }\n\n    /**\n     * Remove all of the extender callbacks for a given type.\n     *\n     * @param  string  $abstract\n     * @return void\n     */\n    public function forgetExtenders($abstract)\n    {\n        unset($this->extenders[$this->getAlias($abstract)]);\n    }\n\n    /**\n     * Drop all of the stale instances and aliases.\n     *\n     * @param  string  $abstract\n     * @return void\n     */\n    protected function dropStaleInstances($abstract)\n    {\n        unset($this->instances[$abstract], $this->aliases[$abstract]);\n    }\n\n    /**\n     * Remove a resolved instance from the instance cache.\n     *\n     * @param  string  $abstract\n     * @return void\n     */\n    public function forgetInstance($abstract)\n    {\n        unset($this->instances[$abstract]);\n    }\n\n    /**\n     * Clear all of the instances from the container.\n     *\n     * @return void\n     */\n    public function forgetInstances()\n    {\n        $this->instances = [];\n    }\n\n    /**\n     * Clear all of the scoped instances from the container.\n     *\n     * @return void\n     */\n    public function forgetScopedInstances()\n    {\n        foreach ($this->scopedInstances as $scoped) {\n            if ($scoped instanceof Closure) {\n                foreach ($this->closureReturnTypes($scoped) as $type) {\n                    unset($this->instances[$type]);\n                }\n            } else {\n                unset($this->instances[$scoped]);\n            }\n        }\n    }\n\n    /**\n     * Set the callback which determines the current container environment.\n     *\n     * @param  (callable(array<int, string>|string): bool|string)|null  $callback\n     * @return void\n     */\n    public function resolveEnvironmentUsing(?callable $callback)\n    {\n        $this->environmentResolver = $callback;\n    }\n\n    /**\n     * Determine the environment for the container.\n     *\n     * @param  array<int, string>|string  $environments\n     * @return bool\n     */\n    public function currentEnvironmentIs($environments)\n    {\n        return $this->environmentResolver === null\n            ? false\n            : call_user_func($this->environmentResolver, $environments);\n    }\n\n    /**\n     * Flush the container of all bindings and resolved instances.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        $this->aliases = [];\n        $this->resolved = [];\n        $this->bindings = [];\n        $this->instances = [];\n        $this->abstractAliases = [];\n        $this->scopedInstances = [];\n        $this->checkedForAttributeBindings = [];\n        $this->checkedForSingletonOrScopedAttributes = [];\n    }\n\n    /**\n     * Get the globally available instance of the container.\n     *\n     * @return static\n     */\n    public static function getInstance()\n    {\n        return static::$instance ??= new static;\n    }\n\n    /**\n     * Set the shared instance of the container.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container|static\n     */\n    public static function setInstance(?ContainerContract $container = null)\n    {\n        return static::$instance = $container;\n    }\n\n    /**\n     * Determine if a given offset exists.\n     *\n     * @param  string  $offset\n     */\n    public function offsetExists($offset): bool\n    {\n        return $this->bound($offset);\n    }\n\n    /**\n     * Get the value at a given offset.\n     *\n     * @param  string  $offset\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->make($offset);\n    }\n\n    /**\n     * Set the value at a given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->bind($offset, $value instanceof Closure ? $value : fn () => $value);\n    }\n\n    /**\n     * Unset the value at a given offset.\n     *\n     * @param  string  $offset\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->bindings[$offset], $this->instances[$offset], $this->resolved[$offset]);\n    }\n\n    /**\n     * Dynamically access container services.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this[$key];\n    }\n\n    /**\n     * Dynamically set container services.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this[$key] = $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/ContextualBindingBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\ContextualBindingBuilder as ContextualBindingBuilderContract;\n\nclass ContextualBindingBuilder implements ContextualBindingBuilderContract\n{\n    /**\n     * The underlying container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The concrete instance.\n     *\n     * @var string|array\n     */\n    protected $concrete;\n\n    /**\n     * The abstract target.\n     *\n     * @var string\n     */\n    protected $needs;\n\n    /**\n     * Create a new contextual binding builder.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @param  string|array  $concrete\n     */\n    public function __construct(Container $container, $concrete)\n    {\n        $this->concrete = $concrete;\n        $this->container = $container;\n    }\n\n    /**\n     * Define the abstract target that depends on the context.\n     *\n     * @param  string  $abstract\n     * @return $this\n     */\n    public function needs($abstract)\n    {\n        $this->needs = $abstract;\n\n        return $this;\n    }\n\n    /**\n     * Define the implementation for the contextual binding.\n     *\n     * @param  \\Closure|string|array  $implementation\n     * @return $this\n     */\n    public function give($implementation)\n    {\n        foreach (Util::arrayWrap($this->concrete) as $concrete) {\n            $this->container->addContextualBinding($concrete, $this->needs, $implementation);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Define tagged services to be used as the implementation for the contextual binding.\n     *\n     * @param  string  $tag\n     * @return $this\n     */\n    public function giveTagged($tag)\n    {\n        return $this->give(function ($container) use ($tag) {\n            $taggedServices = $container->tagged($tag);\n\n            return is_array($taggedServices) ? $taggedServices : iterator_to_array($taggedServices);\n        });\n    }\n\n    /**\n     * Specify the configuration item to bind as a primitive.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return $this\n     */\n    public function giveConfig($key, $default = null)\n    {\n        return $this->give(fn ($container) => $container->get('config')->get($key, $default));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/EntryNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse Exception;\nuse Psr\\Container\\NotFoundExceptionInterface;\n\nclass EntryNotFoundException extends Exception implements NotFoundExceptionInterface\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Container/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Container/RewindableGenerator.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse Countable;\nuse IteratorAggregate;\nuse Traversable;\n\nclass RewindableGenerator implements Countable, IteratorAggregate\n{\n    /**\n     * The generator callback.\n     *\n     * @var callable\n     */\n    protected $generator;\n\n    /**\n     * The number of tagged services.\n     *\n     * @var callable|int\n     */\n    protected $count;\n\n    /**\n     * Create a new generator instance.\n     *\n     * @param  callable  $generator\n     * @param  callable|int  $count\n     */\n    public function __construct(callable $generator, $count)\n    {\n        $this->count = $count;\n        $this->generator = $generator;\n    }\n\n    /**\n     * Get an iterator from the generator.\n     *\n     * @return \\Traversable\n     */\n    public function getIterator(): Traversable\n    {\n        return ($this->generator)();\n    }\n\n    /**\n     * Get the total number of tagged services.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        if (is_callable($count = $this->count)) {\n            $this->count = $count();\n        }\n\n        return $this->count;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/Util.php",
    "content": "<?php\n\nnamespace Illuminate\\Container;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse ReflectionAttribute;\nuse ReflectionNamedType;\n\n/**\n * @internal\n */\nclass Util\n{\n    /**\n     * If the given value is not an array and not null, wrap it in one.\n     *\n     * From Arr::wrap() in Illuminate\\Support.\n     *\n     * @param  mixed  $value\n     * @return array\n     */\n    public static function arrayWrap($value)\n    {\n        if (is_null($value)) {\n            return [];\n        }\n\n        return is_array($value) ? $value : [$value];\n    }\n\n    /**\n     * Return the default value of the given value.\n     *\n     * From global value() helper in Illuminate\\Support.\n     *\n     * @param  mixed  $value\n     * @param  mixed  ...$args\n     * @return mixed\n     */\n    public static function unwrapIfClosure($value, ...$args)\n    {\n        return $value instanceof Closure ? $value(...$args) : $value;\n    }\n\n    /**\n     * Get the class name of the given parameter's type, if possible.\n     *\n     * From Reflector::getParameterClassName() in Illuminate\\Support.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @return string|null\n     */\n    public static function getParameterClassName($parameter)\n    {\n        $type = $parameter->getType();\n\n        if (! $type instanceof ReflectionNamedType || $type->isBuiltin()) {\n            return null;\n        }\n\n        $name = $type->getName();\n\n        if (! is_null($class = $parameter->getDeclaringClass())) {\n            if ($name === 'self') {\n                return $class->getName();\n            }\n\n            if ($name === 'parent' && $parent = $class->getParentClass()) {\n                return $parent->getName();\n            }\n        }\n\n        return $name;\n    }\n\n    /**\n     * Get a contextual attribute from a dependency.\n     *\n     * @param  \\ReflectionParameter  $dependency\n     * @return \\ReflectionAttribute|null\n     */\n    public static function getContextualAttributeFromDependency($dependency)\n    {\n        return $dependency->getAttributes(ContextualAttribute::class, ReflectionAttribute::IS_INSTANCEOF)[0] ?? null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Container/composer.json",
    "content": "{\n    \"name\": \"illuminate/container\",\n    \"description\": \"The Illuminate Container package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/reflection\": \"^13.0\",\n        \"psr/container\": \"^1.1.1 || ^2.0.1\",\n        \"symfony/polyfill-php84\": \"^1.33\",\n        \"symfony/polyfill-php85\": \"^1.33\"\n    },\n    \"provide\": {\n        \"psr/container-implementation\": \"1.1 || 2.0\"\n    },\n    \"suggest\": {\n        \"illuminate/auth\": \"Required to use the Auth attribute\",\n        \"illuminate/cache\": \"Required to use the Cache attribute\",\n        \"illuminate/config\": \"Required to use the Config attribute\",\n        \"illuminate/database\": \"Required to use the DB attribute\",\n        \"illuminate/filesystem\": \"Required to use the Storage attribute\",\n        \"illuminate/log\": \"Required to use the Log or Context attributes\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Container\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Contracts/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Access/Authorizable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth\\Access;\n\ninterface Authorizable\n{\n    /**\n     * Determine if the entity has a given ability.\n     *\n     * @param  iterable|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function can($abilities, $arguments = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Access/Gate.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth\\Access;\n\ninterface Gate\n{\n    /**\n     * Determine if a given ability has been defined.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @return bool\n     */\n    public function has($ability);\n\n    /**\n     * Define a new ability.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  callable|string  $callback\n     * @return $this\n     */\n    public function define($ability, $callback);\n\n    /**\n     * Define abilities for a resource.\n     *\n     * @param  string  $name\n     * @param  string  $class\n     * @param  array|null  $abilities\n     * @return $this\n     */\n    public function resource($name, $class, ?array $abilities = null);\n\n    /**\n     * Define a policy class for a given class type.\n     *\n     * @param  string  $class\n     * @param  string  $policy\n     * @return $this\n     */\n    public function policy($class, $policy);\n\n    /**\n     * Register a callback to run before all Gate checks.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function before(callable $callback);\n\n    /**\n     * Register a callback to run after all Gate checks.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function after(callable $callback);\n\n    /**\n     * Determine if all of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function allows($ability, $arguments = []);\n\n    /**\n     * Determine if any of the given abilities should be denied for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function denies($ability, $arguments = []);\n\n    /**\n     * Determine if all of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function check($abilities, $arguments = []);\n\n    /**\n     * Determine if any one of the given abilities should be granted for the current user.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function any($abilities, $arguments = []);\n\n    /**\n     * Determine if the given ability should be granted for the current user.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function authorize($ability, $arguments = []);\n\n    /**\n     * Inspect the user for the given ability.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     */\n    public function inspect($ability, $arguments = []);\n\n    /**\n     * Get the raw result from the authorization callback.\n     *\n     * @param  string  $ability\n     * @param  mixed  $arguments\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function raw($ability, $arguments = []);\n\n    /**\n     * Get a policy instance for a given class.\n     *\n     * @param  object|string  $class\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function getPolicyFor($class);\n\n    /**\n     * Get a guard instance for the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|mixed  $user\n     * @return static\n     */\n    public function forUser($user);\n\n    /**\n     * Get all of the defined abilities.\n     *\n     * @return array\n     */\n    public function abilities();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Authenticatable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface Authenticatable\n{\n    /**\n     * Get the name of the unique identifier for the user.\n     *\n     * @return string\n     */\n    public function getAuthIdentifierName();\n\n    /**\n     * Get the unique identifier for the user.\n     *\n     * @return mixed\n     */\n    public function getAuthIdentifier();\n\n    /**\n     * Get the name of the password attribute for the user.\n     *\n     * @return string\n     */\n    public function getAuthPasswordName();\n\n    /**\n     * Get the password for the user.\n     *\n     * @return string\n     */\n    public function getAuthPassword();\n\n    /**\n     * Get the token value for the \"remember me\" session.\n     *\n     * @return string\n     */\n    public function getRememberToken();\n\n    /**\n     * Set the token value for the \"remember me\" session.\n     *\n     * @param  string  $value\n     * @return void\n     */\n    public function setRememberToken($value);\n\n    /**\n     * Get the column name for the \"remember me\" token.\n     *\n     * @return string\n     */\n    public function getRememberTokenName();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/CanResetPassword.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface CanResetPassword\n{\n    /**\n     * Get the e-mail address where password reset links are sent.\n     *\n     * @return string\n     */\n    public function getEmailForPasswordReset();\n\n    /**\n     * Send the password reset notification.\n     *\n     * @param  string  $token\n     * @return void\n     */\n    public function sendPasswordResetNotification($token);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface Factory\n{\n    /**\n     * Get a guard instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Auth\\Guard|\\Illuminate\\Contracts\\Auth\\StatefulGuard\n     */\n    public function guard($name = null);\n\n    /**\n     * Set the default guard the factory should serve.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function shouldUse($name);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Guard.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface Guard\n{\n    /**\n     * Determine if the current user is authenticated.\n     *\n     * @return bool\n     */\n    public function check();\n\n    /**\n     * Determine if the current user is a guest.\n     *\n     * @return bool\n     */\n    public function guest();\n\n    /**\n     * Get the currently authenticated user.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function user();\n\n    /**\n     * Get the ID for the currently authenticated user.\n     *\n     * @return int|string|null\n     */\n    public function id();\n\n    /**\n     * Validate a user's credentials.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validate(array $credentials = []);\n\n    /**\n     * Determine if the guard has a user instance.\n     *\n     * @return bool\n     */\n    public function hasUser();\n\n    /**\n     * Set the current user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @return $this\n     */\n    public function setUser(Authenticatable $user);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/Middleware/AuthenticatesRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth\\Middleware;\n\ninterface AuthenticatesRequests\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/MustVerifyEmail.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface MustVerifyEmail\n{\n    /**\n     * Determine if the user has verified their email address.\n     *\n     * @return bool\n     */\n    public function hasVerifiedEmail();\n\n    /**\n     * Mark the given user's email as verified.\n     *\n     * @return bool\n     */\n    public function markEmailAsVerified();\n\n    /**\n     * Mark the given user's email as unverified.\n     *\n     * @return bool\n     */\n    public function markEmailAsUnverified();\n\n    /**\n     * Send the email verification notification.\n     *\n     * @return void\n     */\n    public function sendEmailVerificationNotification();\n\n    /**\n     * Get the email address that should be used for verification.\n     *\n     * @return string\n     */\n    public function getEmailForVerification();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/PasswordBroker.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\nuse Closure;\n\ninterface PasswordBroker\n{\n    /**\n     * Constant representing a successfully sent reminder.\n     *\n     * @var string\n     */\n    const RESET_LINK_SENT = 'passwords.sent';\n\n    /**\n     * Constant representing a successfully reset password.\n     *\n     * @var string\n     */\n    const PASSWORD_RESET = 'passwords.reset';\n\n    /**\n     * Constant representing the user not found response.\n     *\n     * @var string\n     */\n    const INVALID_USER = 'passwords.user';\n\n    /**\n     * Constant representing an invalid token.\n     *\n     * @var string\n     */\n    const INVALID_TOKEN = 'passwords.token';\n\n    /**\n     * Constant representing a throttled reset attempt.\n     *\n     * @var string\n     */\n    const RESET_THROTTLED = 'passwords.throttled';\n\n    /**\n     * Send a password reset link to a user.\n     *\n     * @param  array  $credentials\n     * @param  \\Closure|null  $callback\n     * @return string\n     */\n    public function sendResetLink(array $credentials, ?Closure $callback = null);\n\n    /**\n     * Reset the password for the given token.\n     *\n     * @param  array  $credentials\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function reset(array $credentials, Closure $callback);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/PasswordBrokerFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface PasswordBrokerFactory\n{\n    /**\n     * Get a password broker instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Auth\\PasswordBroker\n     */\n    public function broker($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/StatefulGuard.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface StatefulGuard extends Guard\n{\n    /**\n     * Attempt to authenticate a user using the given credentials.\n     *\n     * @param  array  $credentials\n     * @param  bool  $remember\n     * @return bool\n     */\n    public function attempt(array $credentials = [], $remember = false);\n\n    /**\n     * Log a user into the application without sessions or cookies.\n     *\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function once(array $credentials = []);\n\n    /**\n     * Log a user into the application.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  bool  $remember\n     * @return void\n     */\n    public function login(Authenticatable $user, $remember = false);\n\n    /**\n     * Log the given user ID into the application.\n     *\n     * @param  mixed  $id\n     * @param  bool  $remember\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|false\n     */\n    public function loginUsingId($id, $remember = false);\n\n    /**\n     * Log the given user ID into the application without sessions or cookies.\n     *\n     * @param  mixed  $id\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|false\n     */\n    public function onceUsingId($id);\n\n    /**\n     * Determine if the user was authenticated via \"remember me\" cookie.\n     *\n     * @return bool\n     */\n    public function viaRemember();\n\n    /**\n     * Log the user out of the application.\n     *\n     * @return void\n     */\n    public function logout();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/SupportsBasicAuth.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface SupportsBasicAuth\n{\n    /**\n     * Attempt to authenticate using HTTP Basic Auth.\n     *\n     * @param  string  $field\n     * @param  array  $extraConditions\n     * @return \\Symfony\\Component\\HttpFoundation\\Response|null\n     */\n    public function basic($field = 'email', $extraConditions = []);\n\n    /**\n     * Perform a stateless HTTP Basic login attempt.\n     *\n     * @param  string  $field\n     * @param  array  $extraConditions\n     * @return \\Symfony\\Component\\HttpFoundation\\Response|null\n     */\n    public function onceBasic($field = 'email', $extraConditions = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Auth/UserProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Auth;\n\ninterface UserProvider\n{\n    /**\n     * Retrieve a user by their unique identifier.\n     *\n     * @param  mixed  $identifier\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveById($identifier);\n\n    /**\n     * Retrieve a user by their unique identifier and \"remember me\" token.\n     *\n     * @param  mixed  $identifier\n     * @param  string  $token\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveByToken($identifier, #[\\SensitiveParameter] $token);\n\n    /**\n     * Update the \"remember me\" token for the given user in storage.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string  $token\n     * @return void\n     */\n    public function updateRememberToken(Authenticatable $user, #[\\SensitiveParameter] $token);\n\n    /**\n     * Retrieve a user by the given credentials.\n     *\n     * @param  array  $credentials\n     * @return \\Illuminate\\Contracts\\Auth\\Authenticatable|null\n     */\n    public function retrieveByCredentials(#[\\SensitiveParameter] array $credentials);\n\n    /**\n     * Validate a user against the given credentials.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @return bool\n     */\n    public function validateCredentials(Authenticatable $user, #[\\SensitiveParameter] array $credentials);\n\n    /**\n     * Rehash the user's password if required and supported.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  array  $credentials\n     * @param  bool  $force\n     * @return void\n     */\n    public function rehashPasswordIfRequired(Authenticatable $user, #[\\SensitiveParameter] array $credentials, bool $force = false);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/Broadcaster.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface Broadcaster\n{\n    /**\n     * Authenticate the incoming request for a given channel.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return mixed\n     */\n    public function auth($request);\n\n    /**\n     * Return the valid authentication response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function validAuthenticationResponse($request, $result);\n\n    /**\n     * Broadcast the given event.\n     *\n     * @param  array  $channels\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     *\n     * @throws \\Illuminate\\Broadcasting\\BroadcastException\n     */\n    public function broadcast(array $channels, $event, array $payload = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface Factory\n{\n    /**\n     * Get a broadcaster implementation by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Broadcasting\\Broadcaster\n     */\n    public function connection($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/HasBroadcastChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface HasBroadcastChannel\n{\n    /**\n     * Get the broadcast channel route definition that is associated with the given entity.\n     *\n     * @return string\n     */\n    public function broadcastChannelRoute();\n\n    /**\n     * Get the broadcast channel name that is associated with the given entity.\n     *\n     * @return string\n     */\n    public function broadcastChannel();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/ShouldBeUnique.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface ShouldBeUnique\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/ShouldBroadcast.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface ShouldBroadcast\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]|string[]|string\n     */\n    public function broadcastOn();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/ShouldBroadcastNow.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface ShouldBroadcastNow extends ShouldBroadcast\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Broadcasting/ShouldRescue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Broadcasting;\n\ninterface ShouldRescue\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Bus/Dispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Bus;\n\ninterface Dispatcher\n{\n    /**\n     * Dispatch a command to its appropriate handler.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function dispatch($command);\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchSync($command, $handler = null);\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchNow($command, $handler = null);\n\n    /**\n     * Dispatch a command to its appropriate handler after the current process.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return void\n     */\n    public function dispatchAfterResponse($command, $handler = null);\n\n    /**\n     * Create a new chain of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|null  $jobs\n     * @return mixed\n     */\n    public function chain($jobs = null);\n\n    /**\n     * Determine if the given command has a handler.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    public function hasCommandHandler($command);\n\n    /**\n     * Retrieve the handler for a command.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function getCommandHandler($command);\n\n    /**\n     * Set the pipes commands should be piped through before dispatching.\n     *\n     * @param  array  $pipes\n     * @return $this\n     */\n    public function pipeThrough(array $pipes);\n\n    /**\n     * Map a command to a handler.\n     *\n     * @param  array  $map\n     * @return $this\n     */\n    public function map(array $map);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Bus/QueueingDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Bus;\n\ninterface QueueingDispatcher extends Dispatcher\n{\n    /**\n     * Attempt to find the batch with the given ID.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function findBatch(string $batchId);\n\n    /**\n     * Create a new batch of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array  $jobs\n     * @return \\Illuminate\\Bus\\PendingBatch\n     */\n    public function batch($jobs);\n\n    /**\n     * Dispatch a command to its appropriate handler behind a queue.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function dispatchToQueue($command);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/CanFlushLocks.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\ninterface CanFlushLocks\n{\n    /**\n     * Flush all locks managed by the store.\n     *\n     * @return bool\n     */\n    public function flushLocks(): bool;\n\n    /**\n     * Determine if the lock store is separate from the cache store.\n     *\n     * @return bool\n     */\n    public function hasSeparateLockStore(): bool;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\ninterface Factory\n{\n    /**\n     * Get a cache store instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function store($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/Lock.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\ninterface Lock\n{\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @param  callable|null  $callback\n     * @return mixed\n     */\n    public function get($callback = null);\n\n    /**\n     * Attempt to acquire the lock for the given number of seconds.\n     *\n     * @param  int  $seconds\n     * @param  callable|null  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Cache\\LockTimeoutException\n     */\n    public function block($seconds, $callback = null);\n\n    /**\n     * Release the lock.\n     *\n     * @return bool\n     */\n    public function release();\n\n    /**\n     * Returns the current owner of the lock.\n     *\n     * @return string\n     */\n    public function owner();\n\n    /**\n     * Releases this lock in disregard of ownership.\n     *\n     * @return void\n     */\n    public function forceRelease();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/LockProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\ninterface LockProvider\n{\n    /**\n     * Get a lock instance.\n     *\n     * @param  string  $name\n     * @param  int  $seconds\n     * @param  string|null  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function lock($name, $seconds = 0, $owner = null);\n\n    /**\n     * Restore a lock instance using the owner identifier.\n     *\n     * @param  string  $name\n     * @param  string  $owner\n     * @return \\Illuminate\\Contracts\\Cache\\Lock\n     */\n    public function restoreLock($name, $owner);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/LockTimeoutException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\nuse Exception;\n\nclass LockTimeoutException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/Repository.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\nuse Closure;\nuse Psr\\SimpleCache\\CacheInterface;\n\ninterface Repository extends CacheInterface\n{\n    /**\n     * Retrieve an item from the cache and delete it.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\BackedEnum|\\UnitEnum|array|string  $key\n     * @param  TCacheValue|(\\Closure(): TCacheValue)  $default\n     * @return (TCacheValue is null ? mixed : TCacheValue)\n     */\n    public function pull($key, $default = null);\n\n    /**\n     * Store an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function put($key, $value, $ttl = null);\n\n    /**\n     * Store an item in the cache if the key does not exist.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     * @return bool\n     */\n    public function add($key, $value, $ttl = null);\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1);\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1);\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value);\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|\\Closure|int|null  $ttl\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function remember($key, $ttl, Closure $callback);\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result forever.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function sear($key, Closure $callback);\n\n    /**\n     * Get an item from the cache, or execute the given Closure and store the result forever.\n     *\n     * @template TCacheValue\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  \\Closure(): TCacheValue  $callback\n     * @return TCacheValue\n     */\n    public function rememberForever($key, Closure $callback);\n\n    /**\n     * Set the expiration of a cached item.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @param  \\DateTimeInterface|\\DateInterval|int  $ttl\n     * @return bool\n     */\n    public function touch($key, $ttl);\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  \\BackedEnum|\\UnitEnum|string  $key\n     * @return bool\n     */\n    public function forget($key);\n\n    /**\n     * Get the cache store implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Store\n     */\n    public function getStore();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cache/Store.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cache;\n\ninterface Store\n{\n    /**\n     * Retrieve an item from the cache by key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function get($key);\n\n    /**\n     * Retrieve multiple items from the cache by key.\n     *\n     * Items not found in the cache will have a null value.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function many(array $keys);\n\n    /**\n     * Store an item in the cache for a given number of seconds.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function put($key, $value, $seconds);\n\n    /**\n     * Store multiple items in the cache for a given number of seconds.\n     *\n     * @param  array  $values\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function putMany(array $values, $seconds);\n\n    /**\n     * Increment the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function increment($key, $value = 1);\n\n    /**\n     * Decrement the value of an item in the cache.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return int|bool\n     */\n    public function decrement($key, $value = 1);\n\n    /**\n     * Store an item in the cache indefinitely.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function forever($key, $value);\n\n    /**\n     * Set the expiration of a cached item.\n     *\n     * @param  string  $key\n     * @param  int  $seconds\n     * @return bool\n     */\n    public function touch($key, $seconds);\n\n    /**\n     * Remove an item from the cache.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function forget($key);\n\n    /**\n     * Remove all items from the cache.\n     *\n     * @return bool\n     */\n    public function flush();\n\n    /**\n     * Get the cache key prefix.\n     *\n     * @return string\n     */\n    public function getPrefix();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Concurrency/Driver.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Concurrency;\n\nuse Closure;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\n\ninterface Driver\n{\n    /**\n     * Run the given tasks concurrently and return an array containing the results.\n     */\n    public function run(Closure|array $tasks): array;\n\n    /**\n     * Defer the execution of the given tasks.\n     */\n    public function defer(Closure|array $tasks): DeferredCallback;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Config/Repository.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Config;\n\ninterface Repository\n{\n    /**\n     * Determine if the given configuration value exists.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function has($key);\n\n    /**\n     * Get the specified configuration value.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null);\n\n    /**\n     * Get all of the configuration items for the application.\n     *\n     * @return array\n     */\n    public function all();\n\n    /**\n     * Set a given configuration value.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function set($key, $value = null);\n\n    /**\n     * Prepend a value onto an array configuration value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function prepend($key, $value);\n\n    /**\n     * Push a value onto an array configuration value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function push($key, $value);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Console/Application.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Console;\n\ninterface Application\n{\n    /**\n     * Run an Artisan console command by name.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $outputBuffer\n     * @return int\n     */\n    public function call($command, array $parameters = [], $outputBuffer = null);\n\n    /**\n     * Get the output from the last command.\n     *\n     * @return string\n     */\n    public function output();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Console/Isolatable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Console;\n\ninterface Isolatable\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Console/Kernel.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Console;\n\ninterface Kernel\n{\n    /**\n     * Bootstrap the application for artisan commands.\n     *\n     * @return void\n     */\n    public function bootstrap();\n\n    /**\n     * Handle an incoming console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $output\n     * @return int\n     */\n    public function handle($input, $output = null);\n\n    /**\n     * Run an Artisan console command by name.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $outputBuffer\n     * @return int\n     */\n    public function call($command, array $parameters = [], $outputBuffer = null);\n\n    /**\n     * Queue an Artisan console command by name.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public function queue($command, array $parameters = []);\n\n    /**\n     * Get all of the commands registered with the console.\n     *\n     * @return array\n     */\n    public function all();\n\n    /**\n     * Get the output for the last run command.\n     *\n     * @return string\n     */\n    public function output();\n\n    /**\n     * Terminate the application.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  int  $status\n     * @return void\n     */\n    public function terminate($input, $status);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Console/PromptsForMissingInput.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Console;\n\ninterface PromptsForMissingInput\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/BindingResolutionException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\nuse Exception;\nuse Psr\\Container\\ContainerExceptionInterface;\n\nclass BindingResolutionException extends Exception implements ContainerExceptionInterface\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/CircularDependencyException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\nuse Exception;\nuse Psr\\Container\\ContainerExceptionInterface;\n\nclass CircularDependencyException extends Exception implements ContainerExceptionInterface\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/Container.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\nuse Closure;\nuse Psr\\Container\\ContainerInterface;\n\ninterface Container extends ContainerInterface\n{\n    /**\n     * {@inheritdoc}\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $id\n     * @return ($id is class-string<TClass> ? TClass : mixed)\n     */\n    public function get(string $id);\n\n    /**\n     * Determine if the given abstract type has been bound.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function bound($abstract);\n\n    /**\n     * Alias a type to a different name.\n     *\n     * @param  string  $abstract\n     * @param  string  $alias\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function alias($abstract, $alias);\n\n    /**\n     * Assign a set of tags to a given binding.\n     *\n     * @param  array|string  $abstracts\n     * @param  mixed  ...$tags\n     * @return void\n     */\n    public function tag($abstracts, $tags);\n\n    /**\n     * Resolve all of the bindings for a given tag.\n     *\n     * @param  string  $tag\n     * @return iterable\n     */\n    public function tagged($tag);\n\n    /**\n     * Register a binding with the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @param  bool  $shared\n     * @return void\n     */\n    public function bind($abstract, $concrete = null, $shared = false);\n\n    /**\n     * Bind a callback to resolve with Container::call.\n     *\n     * @param  array|string  $method\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function bindMethod($method, $callback);\n\n    /**\n     * Register a binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @param  bool  $shared\n     * @return void\n     */\n    public function bindIf($abstract, $concrete = null, $shared = false);\n\n    /**\n     * Register a shared binding in the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function singleton($abstract, $concrete = null);\n\n    /**\n     * Register a shared binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function singletonIf($abstract, $concrete = null);\n\n    /**\n     * Register a scoped binding in the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function scoped($abstract, $concrete = null);\n\n    /**\n     * Register a scoped binding if it hasn't already been registered.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string|null  $concrete\n     * @return void\n     */\n    public function scopedIf($abstract, $concrete = null);\n\n    /**\n     * \"Extend\" an abstract type in the container.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure  $closure\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function extend($abstract, Closure $closure);\n\n    /**\n     * Register an existing instance as shared in the container.\n     *\n     * @template TInstance of mixed\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  TInstance  $instance\n     * @return TInstance\n     */\n    public function instance($abstract, $instance);\n\n    /**\n     * Add a contextual binding to the container.\n     *\n     * @param  string  $concrete\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|string  $implementation\n     * @return void\n     */\n    public function addContextualBinding($concrete, $abstract, $implementation);\n\n    /**\n     * Define a contextual binding.\n     *\n     * @param  string|array  $concrete\n     * @return \\Illuminate\\Contracts\\Container\\ContextualBindingBuilder\n     */\n    public function when($concrete);\n\n    /**\n     * Get a closure to resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $abstract\n     * @return ($abstract is class-string<TClass> ? \\Closure(): TClass : \\Closure(): mixed)\n     */\n    public function factory($abstract);\n\n    /**\n     * Flush the container of all bindings and resolved instances.\n     *\n     * @return void\n     */\n    public function flush();\n\n    /**\n     * Resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $abstract\n     * @param  array  $parameters\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function make($abstract, array $parameters = []);\n\n    /**\n     * Call the given Closure / class@method and inject its dependencies.\n     *\n     * @param  callable|string  $callback\n     * @param  array  $parameters\n     * @param  string|null  $defaultMethod\n     * @return mixed\n     */\n    public function call($callback, array $parameters = [], $defaultMethod = null);\n\n    /**\n     * Determine if the given abstract type has been resolved.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function resolved($abstract);\n\n    /**\n     * Register a new before resolving callback.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|null  $callback\n     * @return void\n     */\n    public function beforeResolving($abstract, ?Closure $callback = null);\n\n    /**\n     * Register a new resolving callback.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|null  $callback\n     * @return void\n     */\n    public function resolving($abstract, ?Closure $callback = null);\n\n    /**\n     * Register a new after resolving callback.\n     *\n     * @param  \\Closure|string  $abstract\n     * @param  \\Closure|null  $callback\n     * @return void\n     */\n    public function afterResolving($abstract, ?Closure $callback = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/ContextualAttribute.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\ninterface ContextualAttribute\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/ContextualBindingBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\ninterface ContextualBindingBuilder\n{\n    /**\n     * Define the abstract target that depends on the context.\n     *\n     * @param  string  $abstract\n     * @return $this\n     */\n    public function needs($abstract);\n\n    /**\n     * Define the implementation for the contextual binding.\n     *\n     * @param  \\Closure|string|array  $implementation\n     * @return $this\n     */\n    public function give($implementation);\n\n    /**\n     * Define tagged services to be used as the implementation for the contextual binding.\n     *\n     * @param  string  $tag\n     * @return $this\n     */\n    public function giveTagged($tag);\n\n    /**\n     * Specify the configuration item to bind as a primitive.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return $this\n     */\n    public function giveConfig($key, $default = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Container/SelfBuilding.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Container;\n\n/**\n * @method static newInstance(): static\n */\ninterface SelfBuilding\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cookie/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cookie;\n\ninterface Factory\n{\n    /**\n     * Create a new cookie instance.\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @param  int  $minutes\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  bool  $httpOnly\n     * @param  bool  $raw\n     * @param  string|null  $sameSite\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null);\n\n    /**\n     * Create a cookie that lasts \"forever\" (400 days).\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  bool  $httpOnly\n     * @param  bool  $raw\n     * @param  string|null  $sameSite\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null);\n\n    /**\n     * Expire the given cookie.\n     *\n     * @param  string  $name\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function forget($name, $path = null, $domain = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Cookie/QueueingFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Cookie;\n\ninterface QueueingFactory extends Factory\n{\n    /**\n     * Queue a cookie to send with the next response.\n     *\n     * @param  mixed  ...$parameters\n     * @return void\n     */\n    public function queue(...$parameters);\n\n    /**\n     * Remove a cookie from the queue.\n     *\n     * @param  string  $name\n     * @param  string|null  $path\n     * @return void\n     */\n    public function unqueue($name, $path = null);\n\n    /**\n     * Get the cookies which have been queued for the next request.\n     *\n     * @return array\n     */\n    public function getQueuedCookies();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/ConcurrencyErrorDetector.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database;\n\nuse Throwable;\n\ninterface ConcurrencyErrorDetector\n{\n    /**\n     * Determine if the given exception was caused by a concurrency error such as a deadlock or serialization failure.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function causedByConcurrencyError(Throwable $e): bool;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/Builder.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\nuse Illuminate\\Contracts\\Database\\Query\\Builder as BaseContract;\n\n/**\n * This interface is intentionally empty and exists to improve IDE support.\n *\n * @mixin \\Illuminate\\Database\\Eloquent\\Builder\n */\ninterface Builder extends BaseContract\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/Castable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\ninterface Castable\n{\n    /**\n     * Get the name of the caster class to use when casting from / to this cast target.\n     *\n     * @param  string[]  $arguments\n     * @return class-string<CastsAttributes|CastsInboundAttributes>|CastsAttributes|CastsInboundAttributes\n     */\n    public static function castUsing(array $arguments);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/CastsAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\n/**\n * @template TGet\n * @template TSet\n */\ninterface CastsAttributes\n{\n    /**\n     * Transform the attribute from the underlying model values.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array<string, mixed>  $attributes\n     * @return TGet|null\n     */\n    public function get(Model $model, string $key, mixed $value, array $attributes);\n\n    /**\n     * Transform the attribute to its underlying model values.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  TSet|null  $value\n     * @param  array<string, mixed>  $attributes\n     * @return mixed\n     */\n    public function set(Model $model, string $key, mixed $value, array $attributes);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/CastsInboundAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ninterface CastsInboundAttributes\n{\n    /**\n     * Transform the attribute to its underlying model values.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array<string, mixed>  $attributes\n     * @return mixed\n     */\n    public function set(Model $model, string $key, mixed $value, array $attributes);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/ComparesCastableAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ninterface ComparesCastableAttributes\n{\n    /**\n     * Determine if the given values are equal.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $firstValue\n     * @param  mixed  $secondValue\n     * @return bool\n     */\n    public function compare(Model $model, string $key, mixed $firstValue, mixed $secondValue);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/DeviatesCastableAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\ninterface DeviatesCastableAttributes\n{\n    /**\n     * Increment the attribute.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return mixed\n     */\n    public function increment($model, string $key, $value, array $attributes);\n\n    /**\n     * Decrement the attribute.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return mixed\n     */\n    public function decrement($model, string $key, $value, array $attributes);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/SerializesCastableAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ninterface SerializesCastableAttributes\n{\n    /**\n     * Serialize the attribute when converting the model to an array.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array<string, mixed>  $attributes\n     * @return mixed\n     */\n    public function serialize(Model $model, string $key, mixed $value, array $attributes);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Eloquent/SupportsPartialRelations.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Eloquent;\n\ninterface SupportsPartialRelations\n{\n    /**\n     * Indicate that the relation is a single result of a larger one-to-many relationship.\n     *\n     * @param  string|null  $column\n     * @param  string|\\Closure|null  $aggregate\n     * @param  string|null  $relation\n     * @return $this\n     */\n    public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null);\n\n    /**\n     * Determine whether the relationship is a one-of-many relationship.\n     *\n     * @return bool\n     */\n    public function isOneOfMany();\n\n    /**\n     * Get the one of many inner join subselect query builder instance.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder|void\n     */\n    public function getOneOfManySubQuery();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Events/MigrationEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Events;\n\ninterface MigrationEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/LostConnectionDetector.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database;\n\nuse Throwable;\n\ninterface LostConnectionDetector\n{\n    /**\n     * Determine if the given exception was caused by a lost connection.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function causedByLostConnection(Throwable $e): bool;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/ModelIdentifier.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\n\nclass ModelIdentifier\n{\n    /**\n     * Use the Relation morphMap for a Model's name when serializing.\n     */\n    protected static bool $useMorphMap = false;\n\n    /**\n     * The class name of the model.\n     *\n     * @var class-string<\\Illuminate\\Database\\Eloquent\\Model>|string|null\n     */\n    public $class;\n\n    /**\n     * The unique identifier of the model.\n     *\n     * This may be either a single ID or an array of IDs.\n     *\n     * @var mixed\n     */\n    public $id;\n\n    /**\n     * The relationships loaded on the model.\n     *\n     * @var array\n     */\n    public $relations;\n\n    /**\n     * The connection name of the model.\n     *\n     * @var string|null\n     */\n    public $connection;\n\n    /**\n     * The class name of the model collection.\n     *\n     * @var class-string<\\Illuminate\\Database\\Eloquent\\Collection>|null\n     */\n    public $collectionClass;\n\n    /**\n     * Create a new model identifier.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Model>|null  $class\n     * @param  mixed  $id\n     * @param  array  $relations\n     * @param  mixed  $connection\n     */\n    public function __construct($class, $id, array $relations, $connection)\n    {\n        if ($class !== null && self::$useMorphMap) {\n            $class = Relation::getMorphAlias($class);\n        }\n\n        $this->class = $class;\n        $this->id = $id;\n        $this->relations = $relations;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Specify the collection class that should be used when serializing / restoring collections.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Collection>  $collectionClass\n     * @return $this\n     */\n    public function useCollectionClass(?string $collectionClass)\n    {\n        $this->collectionClass = $collectionClass;\n\n        return $this;\n    }\n\n    /**\n     * Get the fully-qualified class name of the Model.\n     *\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Model>|null\n     */\n    public function getClass(): ?string\n    {\n        if (self::$useMorphMap && $this->class !== null) {\n            return Relation::getMorphedModel($this->class) ?? $this->class;\n        }\n\n        return $this->class;\n    }\n\n    /**\n     * Indicate whether to use the relational morph-map when serializing Models.\n     */\n    public static function useMorphMap(bool $useMorphMap = true): void\n    {\n        static::$useMorphMap = $useMorphMap;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Query/Builder.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Query;\n\n/**\n * This interface is intentionally empty and exists to improve IDE support.\n *\n * @mixin \\Illuminate\\Database\\Query\\Builder\n */\ninterface Builder\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Query/ConditionExpression.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Query;\n\ninterface ConditionExpression extends Expression\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Database/Query/Expression.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Database\\Query;\n\nuse Illuminate\\Database\\Grammar;\n\ninterface Expression\n{\n    /**\n     * Get the value of the expression.\n     *\n     * @param  \\Illuminate\\Database\\Grammar  $grammar\n     * @return string|int|float\n     */\n    public function getValue(Grammar $grammar);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Debug/ExceptionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Debug;\n\nuse Throwable;\n\ninterface ExceptionHandler\n{\n    /**\n     * Report or log an exception.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function report(Throwable $e);\n\n    /**\n     * Determine if the exception should be reported.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function shouldReport(Throwable $e);\n\n    /**\n     * Render an exception into an HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Throwable\n     */\n    public function render($request, Throwable $e);\n\n    /**\n     * Render an exception to the console.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @internal This method is not meant to be used or overwritten outside the framework.\n     */\n    public function renderForConsole($output, Throwable $e);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Debug/ShouldntReport.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Debug;\n\ninterface ShouldntReport\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Encryption/DecryptException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Encryption;\n\nuse RuntimeException;\n\nclass DecryptException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Encryption/EncryptException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Encryption;\n\nuse RuntimeException;\n\nclass EncryptException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Encryption/Encrypter.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Encryption;\n\ninterface Encrypter\n{\n    /**\n     * Encrypt the given value.\n     *\n     * @param  mixed  $value\n     * @param  bool  $serialize\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\EncryptException\n     */\n    public function encrypt(#[\\SensitiveParameter] $value, $serialize = true);\n\n    /**\n     * Decrypt the given value.\n     *\n     * @param  string  $payload\n     * @param  bool  $unserialize\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    public function decrypt($payload, $unserialize = true);\n\n    /**\n     * Get the encryption key that the encrypter is currently using.\n     *\n     * @return string\n     */\n    public function getKey();\n\n    /**\n     * Get the current encryption key and all previous encryption keys.\n     *\n     * @return array\n     */\n    public function getAllKeys();\n\n    /**\n     * Get the previous encryption keys.\n     *\n     * @return array\n     */\n    public function getPreviousKeys();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Encryption/StringEncrypter.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Encryption;\n\ninterface StringEncrypter\n{\n    /**\n     * Encrypt a string without serialization.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\EncryptException\n     */\n    public function encryptString(#[\\SensitiveParameter] $value);\n\n    /**\n     * Decrypt the given string without unserialization.\n     *\n     * @param  string  $payload\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    public function decryptString($payload);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Events/Dispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Events;\n\ninterface Dispatcher\n{\n    /**\n     * Register an event listener with the dispatcher.\n     *\n     * @param  \\Closure|string|array  $events\n     * @param  \\Closure|string|array|null  $listener\n     * @return void\n     */\n    public function listen($events, $listener = null);\n\n    /**\n     * Determine if a given event has listeners.\n     *\n     * @param  string  $eventName\n     * @return bool\n     */\n    public function hasListeners($eventName);\n\n    /**\n     * Register an event subscriber with the dispatcher.\n     *\n     * @param  object|string  $subscriber\n     * @return void\n     */\n    public function subscribe($subscriber);\n\n    /**\n     * Dispatch an event until the first non-null response is returned.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @return mixed\n     */\n    public function until($event, $payload = []);\n\n    /**\n     * Dispatch an event and call the listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return array|null\n     */\n    public function dispatch($event, $payload = [], $halt = false);\n\n    /**\n     * Register an event and payload to be fired later.\n     *\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     */\n    public function push($event, $payload = []);\n\n    /**\n     * Flush a set of pushed events.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function flush($event);\n\n    /**\n     * Remove a set of listeners from the dispatcher.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function forget($event);\n\n    /**\n     * Forget all of the queued listeners.\n     *\n     * @return void\n     */\n    public function forgetPushed();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Events/ShouldDispatchAfterCommit.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Events;\n\ninterface ShouldDispatchAfterCommit\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Events/ShouldHandleEventsAfterCommit.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Events;\n\ninterface ShouldHandleEventsAfterCommit\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Filesystem/Cloud.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Filesystem;\n\ninterface Cloud extends Filesystem\n{\n    /**\n     * Get the URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function url($path);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Filesystem/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Filesystem;\n\ninterface Factory\n{\n    /**\n     * Get a filesystem implementation.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function disk($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Filesystem/FileNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Filesystem;\n\nuse Exception;\n\nclass FileNotFoundException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Filesystem/Filesystem.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Filesystem;\n\ninterface Filesystem\n{\n    /**\n     * The public visibility setting.\n     *\n     * @var string\n     */\n    const VISIBILITY_PUBLIC = 'public';\n\n    /**\n     * The private visibility setting.\n     *\n     * @var string\n     */\n    const VISIBILITY_PRIVATE = 'private';\n\n    /**\n     * Get the full path to the file that exists at the given relative path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function path($path);\n\n    /**\n     * Determine if a file exists.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function exists($path);\n\n    /**\n     * Get the contents of a file.\n     *\n     * @param  string  $path\n     * @return string|null\n     */\n    public function get($path);\n\n    /**\n     * Get a resource to read the file.\n     *\n     * @param  string  $path\n     * @return resource|null The path resource or null on failure.\n     */\n    public function readStream($path);\n\n    /**\n     * Write the contents of a file.\n     *\n     * @param  string  $path\n     * @param  \\Psr\\Http\\Message\\StreamInterface|\\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|resource  $contents\n     * @param  mixed  $options\n     * @return bool\n     */\n    public function put($path, $contents, $options = []);\n\n    /**\n     * Store the uploaded file on the disk.\n     *\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string  $path\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null  $file\n     * @param  mixed  $options\n     * @return string|false\n     */\n    public function putFile($path, $file = null, $options = []);\n\n    /**\n     * Store the uploaded file on the disk with a given name.\n     *\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string  $path\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null  $file\n     * @param  string|array|null  $name\n     * @param  mixed  $options\n     * @return string|false\n     */\n    public function putFileAs($path, $file, $name = null, $options = []);\n\n    /**\n     * Write a new file using a stream.\n     *\n     * @param  string  $path\n     * @param  resource  $resource\n     * @param  array  $options\n     * @return bool\n     */\n    public function writeStream($path, $resource, array $options = []);\n\n    /**\n     * Get the visibility for the given path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function getVisibility($path);\n\n    /**\n     * Set the visibility for the given path.\n     *\n     * @param  string  $path\n     * @param  string  $visibility\n     * @return bool\n     */\n    public function setVisibility($path, $visibility);\n\n    /**\n     * Prepend to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @return bool\n     */\n    public function prepend($path, $data);\n\n    /**\n     * Append to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @return bool\n     */\n    public function append($path, $data);\n\n    /**\n     * Delete the file at a given path.\n     *\n     * @param  string|array  $paths\n     * @return bool\n     */\n    public function delete($paths);\n\n    /**\n     * Copy a file to a new location.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return bool\n     */\n    public function copy($from, $to);\n\n    /**\n     * Move a file to a new location.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return bool\n     */\n    public function move($from, $to);\n\n    /**\n     * Get the file size of a given file.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function size($path);\n\n    /**\n     * Get the file's last modification time.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function lastModified($path);\n\n    /**\n     * Get an array of all files in a directory.\n     *\n     * @param  string|null  $directory\n     * @param  bool  $recursive\n     * @return array<string>\n     */\n    public function files($directory = null, $recursive = false);\n\n    /**\n     * Get all of the files from the given directory (recursive).\n     *\n     * @param  string|null  $directory\n     * @return array<string>\n     */\n    public function allFiles($directory = null);\n\n    /**\n     * Get all of the directories within a given directory.\n     *\n     * @param  string|null  $directory\n     * @param  bool  $recursive\n     * @return array<string>\n     */\n    public function directories($directory = null, $recursive = false);\n\n    /**\n     * Get all (recursive) of the directories within a given directory.\n     *\n     * @param  string|null  $directory\n     * @return array<string>\n     */\n    public function allDirectories($directory = null);\n\n    /**\n     * Create a directory.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function makeDirectory($path);\n\n    /**\n     * Recursively delete a directory.\n     *\n     * @param  string  $directory\n     * @return bool\n     */\n    public function deleteDirectory($directory);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Filesystem/LockTimeoutException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Filesystem;\n\nuse Exception;\n\nclass LockTimeoutException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Foundation/Application.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Foundation;\n\nuse Illuminate\\Contracts\\Container\\Container;\n\ninterface Application extends Container\n{\n    /**\n     * Get the version number of the application.\n     *\n     * @return string\n     */\n    public function version();\n\n    /**\n     * Get the base path of the Laravel installation.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function basePath($path = '');\n\n    /**\n     * Get the path to the bootstrap directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function bootstrapPath($path = '');\n\n    /**\n     * Get the path to the application configuration files.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function configPath($path = '');\n\n    /**\n     * Get the path to the database directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function databasePath($path = '');\n\n    /**\n     * Get the path to the language files.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function langPath($path = '');\n\n    /**\n     * Get the path to the public directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function publicPath($path = '');\n\n    /**\n     * Get the path to the resources directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function resourcePath($path = '');\n\n    /**\n     * Get the path to the storage directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function storagePath($path = '');\n\n    /**\n     * Get or check the current application environment.\n     *\n     * @param  string|array  ...$environments\n     * @return string|bool\n     */\n    public function environment(...$environments);\n\n    /**\n     * Determine if the application is running in the console.\n     *\n     * @return bool\n     */\n    public function runningInConsole();\n\n    /**\n     * Determine if the application is running unit tests.\n     *\n     * @return bool\n     */\n    public function runningUnitTests();\n\n    /**\n     * Determine if the application is running with debug mode enabled.\n     *\n     * @return bool\n     */\n    public function hasDebugModeEnabled();\n\n    /**\n     * Get an instance of the maintenance mode manager implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\MaintenanceMode\n     */\n    public function maintenanceMode();\n\n    /**\n     * Determine if the application is currently down for maintenance.\n     *\n     * @return bool\n     */\n    public function isDownForMaintenance();\n\n    /**\n     * Register all of the configured providers.\n     *\n     * @return void\n     */\n    public function registerConfiguredProviders();\n\n    /**\n     * Register a service provider with the application.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider|string  $provider\n     * @param  bool  $force\n     * @return \\Illuminate\\Support\\ServiceProvider\n     */\n    public function register($provider, $force = false);\n\n    /**\n     * Register a deferred provider and service.\n     *\n     * @param  string  $provider\n     * @param  string|null  $service\n     * @return void\n     */\n    public function registerDeferredProvider($provider, $service = null);\n\n    /**\n     * Resolve a service provider instance from the class name.\n     *\n     * @param  string  $provider\n     * @return \\Illuminate\\Support\\ServiceProvider\n     */\n    public function resolveProvider($provider);\n\n    /**\n     * Boot the application's service providers.\n     *\n     * @return void\n     */\n    public function boot();\n\n    /**\n     * Register a new boot listener.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function booting($callback);\n\n    /**\n     * Register a new \"booted\" listener.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function booted($callback);\n\n    /**\n     * Run the given array of bootstrap classes.\n     *\n     * @param  array  $bootstrappers\n     * @return void\n     */\n    public function bootstrapWith(array $bootstrappers);\n\n    /**\n     * Get the current application locale.\n     *\n     * @return string\n     */\n    public function getLocale();\n\n    /**\n     * Get the application namespace.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function getNamespace();\n\n    /**\n     * Get the registered service provider instances if any exist.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider|string  $provider\n     * @return array\n     */\n    public function getProviders($provider);\n\n    /**\n     * Determine if the application has been bootstrapped before.\n     *\n     * @return bool\n     */\n    public function hasBeenBootstrapped();\n\n    /**\n     * Load and boot all of the remaining deferred providers.\n     *\n     * @return void\n     */\n    public function loadDeferredProviders();\n\n    /**\n     * Set the current application locale.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public function setLocale($locale);\n\n    /**\n     * Determine if middleware has been disabled for the application.\n     *\n     * @return bool\n     */\n    public function shouldSkipMiddleware();\n\n    /**\n     * Register a terminating callback with the application.\n     *\n     * @param  callable|string  $callback\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function terminating($callback);\n\n    /**\n     * Terminate the application.\n     *\n     * @return void\n     */\n    public function terminate();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Foundation/CachesConfiguration.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Foundation;\n\ninterface CachesConfiguration\n{\n    /**\n     * Determine if the application configuration is cached.\n     *\n     * @return bool\n     */\n    public function configurationIsCached();\n\n    /**\n     * Get the path to the configuration cache file.\n     *\n     * @return string\n     */\n    public function getCachedConfigPath();\n\n    /**\n     * Get the path to the cached services.php file.\n     *\n     * @return string\n     */\n    public function getCachedServicesPath();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Foundation/CachesRoutes.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Foundation;\n\ninterface CachesRoutes\n{\n    /**\n     * Determine if the application routes are cached.\n     *\n     * @return bool\n     */\n    public function routesAreCached();\n\n    /**\n     * Get the path to the routes cache file.\n     *\n     * @return string\n     */\n    public function getCachedRoutesPath();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Foundation/ExceptionRenderer.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Foundation;\n\ninterface ExceptionRenderer\n{\n    /**\n     * Renders the given exception as HTML.\n     *\n     * @param  \\Throwable  $throwable\n     * @return string\n     */\n    public function render($throwable);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Foundation/MaintenanceMode.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Foundation;\n\ninterface MaintenanceMode\n{\n    /**\n     * Take the application down for maintenance.\n     *\n     * @param  array  $payload\n     * @return void\n     */\n    public function activate(array $payload): void;\n\n    /**\n     * Take the application out of maintenance.\n     *\n     * @return void\n     */\n    public function deactivate(): void;\n\n    /**\n     * Determine if the application is currently down for maintenance.\n     *\n     * @return bool\n     */\n    public function active(): bool;\n\n    /**\n     * Get the data array which was provided when the application was placed into maintenance.\n     *\n     * @return array\n     */\n    public function data(): array;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Hashing/Hasher.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Hashing;\n\ninterface Hasher\n{\n    /**\n     * Get information about the given hashed value.\n     *\n     * @param  string  $hashedValue\n     * @return array\n     */\n    public function info($hashedValue);\n\n    /**\n     * Hash the given value.\n     *\n     * @param  string  $value\n     * @param  array  $options\n     * @return string\n     */\n    public function make(#[\\SensitiveParameter] $value, array $options = []);\n\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = []);\n\n    /**\n     * Check if the given hash has been hashed using the given options.\n     *\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function needsRehash($hashedValue, array $options = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Http/Kernel.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Http;\n\ninterface Kernel\n{\n    /**\n     * Bootstrap the application for HTTP requests.\n     *\n     * @return void\n     */\n    public function bootstrap();\n\n    /**\n     * Handle an incoming HTTP request.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function handle($request);\n\n    /**\n     * Perform any final actions for the request lifecycle.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @return void\n     */\n    public function terminate($request, $response);\n\n    /**\n     * Get the Laravel application instance.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getApplication();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/JsonSchema/JsonSchema.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\JsonSchema;\n\nuse Closure;\n\ninterface JsonSchema\n{\n    /**\n     * Create a new object schema instance.\n     *\n     * @param  (Closure(JsonSchema): array<string, \\Illuminate\\JsonSchema\\Types\\Type>)|array<string, \\Illuminate\\JsonSchema\\Types\\Type>  $properties\n     * @return \\Illuminate\\JsonSchema\\Types\\ObjectType\n     */\n    public function object(Closure|array $properties = []);\n\n    /**\n     * Create a new array property instance.\n     *\n     * @return \\Illuminate\\JsonSchema\\Types\\ArrayType\n     */\n    public function array();\n\n    /**\n     * Create a new string property instance.\n     *\n     * @return \\Illuminate\\JsonSchema\\Types\\StringType\n     */\n    public function string();\n\n    /**\n     * Create a new integer property instance.\n     *\n     * @return \\Illuminate\\JsonSchema\\Types\\IntegerType\n     */\n    public function integer();\n\n    /**\n     * Create a new number property instance.\n     *\n     * @return \\Illuminate\\JsonSchema\\Types\\NumberType\n     */\n    public function number();\n\n    /**\n     * Create a new boolean property instance.\n     *\n     * @return \\Illuminate\\JsonSchema\\Types\\BooleanType\n     */\n    public function boolean();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Contracts/Log/ContextLogProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Log;\n\nuse Monolog\\Processor\\ProcessorInterface;\n\ninterface ContextLogProcessor extends ProcessorInterface\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Mail/Attachable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Mail;\n\ninterface Attachable\n{\n    /**\n     * Get an attachment instance for this entity.\n     *\n     * @return \\Illuminate\\Mail\\Attachment\n     */\n    public function toMailAttachment();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Mail/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Mail;\n\ninterface Factory\n{\n    /**\n     * Get a mailer instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Mail\\Mailer\n     */\n    public function mailer($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Mail/MailQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Mail;\n\ninterface MailQueue\n{\n    /**\n     * Queue a new e-mail message for sending.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function queue($view, $queue = null);\n\n    /**\n     * Queue a new e-mail message for sending after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $view, $queue = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Mail/Mailable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Mail;\n\nuse Illuminate\\Contracts\\Queue\\Factory as Queue;\n\ninterface Mailable\n{\n    /**\n     * Send the message using the given mailer.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Factory|\\Illuminate\\Contracts\\Mail\\Mailer  $mailer\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send($mailer);\n\n    /**\n     * Queue the given message.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     * @return mixed\n     */\n    public function queue(Queue $queue);\n\n    /**\n     * Deliver the queued message after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     * @return mixed\n     */\n    public function later($delay, Queue $queue);\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return self\n     */\n    public function cc($address, $name = null);\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function bcc($address, $name = null);\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function to($address, $name = null);\n\n    /**\n     * Set the locale of the message.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale);\n\n    /**\n     * Set the name of the mailer that should be used to send the message.\n     *\n     * @param  string  $mailer\n     * @return $this\n     */\n    public function mailer($mailer);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Mail/Mailer.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Mail;\n\ninterface Mailer\n{\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function to($users);\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function cc($users);\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function bcc($users);\n\n    /**\n     * Send a new message with only a raw text part.\n     *\n     * @param  string  $text\n     * @param  mixed  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function raw($text, $callback);\n\n    /**\n     * Send a new message using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send($view, array $data = [], $callback = null);\n\n    /**\n     * Send a new message synchronously using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $mailable\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function sendNow($mailable, array $data = [], $callback = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Notifications/Dispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Notifications;\n\ninterface Dispatcher\n{\n    /**\n     * Send the given notification to the given notifiable entities.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function send($notifiables, $notification);\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @param  array|null  $channels\n     * @return void\n     */\n    public function sendNow($notifiables, $notification, ?array $channels = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Notifications/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Notifications;\n\ninterface Factory\n{\n    /**\n     * Get a channel instance by name.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function channel($name = null);\n\n    /**\n     * Send the given notification to the given notifiable entities.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function send($notifiables, $notification);\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function sendNow($notifiables, $notification);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Pagination/CursorPaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Pagination;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @method $this through(callable(TValue): mixed $callback)\n */\ninterface CursorPaginator\n{\n    /**\n     * Get the URL for a given cursor.\n     *\n     * @param  \\Illuminate\\Pagination\\Cursor|null  $cursor\n     * @return string\n     */\n    public function url($cursor);\n\n    /**\n     * Add a set of query string values to the paginator.\n     *\n     * @param  array|string|null  $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function appends($key, $value = null);\n\n    /**\n     * Get / set the URL fragment to be appended to URLs.\n     *\n     * @param  string|null  $fragment\n     * @return $this|string|null\n     */\n    public function fragment($fragment = null);\n\n    /**\n     * Add all current query string values to the paginator.\n     *\n     * @return $this\n     */\n    public function withQueryString();\n\n    /**\n     * Get the URL for the previous page, or null.\n     *\n     * @return string|null\n     */\n    public function previousPageUrl();\n\n    /**\n     * The URL for the next page, or null.\n     *\n     * @return string|null\n     */\n    public function nextPageUrl();\n\n    /**\n     * Get all of the items being paginated.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function items();\n\n    /**\n     * Get the \"cursor\" of the previous set of items.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function previousCursor();\n\n    /**\n     * Get the \"cursor\" of the next set of items.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function nextCursor();\n\n    /**\n     * Determine how many items are being shown per page.\n     *\n     * @return int\n     */\n    public function perPage();\n\n    /**\n     * Get the current cursor being paginated.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function cursor();\n\n    /**\n     * Determine if there are enough items to split into multiple pages.\n     *\n     * @return bool\n     */\n    public function hasPages();\n\n    /**\n     * Determine if there are more items in the data source.\n     *\n     * @return bool\n     */\n    public function hasMorePages();\n\n    /**\n     * Get the base path for paginator generated URLs.\n     *\n     * @return string|null\n     */\n    public function path();\n\n    /**\n     * Determine if the list of items is empty or not.\n     *\n     * @return bool\n     */\n    public function isEmpty();\n\n    /**\n     * Determine if the list of items is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty();\n\n    /**\n     * Render the paginator using a given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return string\n     */\n    public function render($view = null, $data = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Pagination/LengthAwarePaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Pagination;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @extends Paginator<TKey, TValue>\n */\ninterface LengthAwarePaginator extends Paginator\n{\n    /**\n     * Create a range of pagination URLs.\n     *\n     * @param  int  $start\n     * @param  int  $end\n     * @return array\n     */\n    public function getUrlRange($start, $end);\n\n    /**\n     * Determine the total number of items in the data store.\n     *\n     * @return int\n     */\n    public function total();\n\n    /**\n     * Get the page number of the last available page.\n     *\n     * @return int\n     */\n    public function lastPage();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Pagination/Paginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Pagination;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @method $this through(callable(TValue): mixed $callback)\n */\ninterface Paginator\n{\n    /**\n     * Get the URL for a given page.\n     *\n     * @param  int  $page\n     * @return string\n     */\n    public function url($page);\n\n    /**\n     * Add a set of query string values to the paginator.\n     *\n     * @param  array|string|null  $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function appends($key, $value = null);\n\n    /**\n     * Get / set the URL fragment to be appended to URLs.\n     *\n     * @param  string|null  $fragment\n     * @return $this|string|null\n     */\n    public function fragment($fragment = null);\n\n    /**\n     * Add all current query string values to the paginator.\n     *\n     * @return $this\n     */\n    public function withQueryString();\n\n    /**\n     * The URL for the next page, or null.\n     *\n     * @return string|null\n     */\n    public function nextPageUrl();\n\n    /**\n     * Get the URL for the previous page, or null.\n     *\n     * @return string|null\n     */\n    public function previousPageUrl();\n\n    /**\n     * Get all of the items being paginated.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function items();\n\n    /**\n     * Get the \"index\" of the first item being paginated.\n     *\n     * @return int|null\n     */\n    public function firstItem();\n\n    /**\n     * Get the \"index\" of the last item being paginated.\n     *\n     * @return int|null\n     */\n    public function lastItem();\n\n    /**\n     * Determine how many items are being shown per page.\n     *\n     * @return int\n     */\n    public function perPage();\n\n    /**\n     * Determine the current page being paginated.\n     *\n     * @return int\n     */\n    public function currentPage();\n\n    /**\n     * Determine if there are enough items to split into multiple pages.\n     *\n     * @return bool\n     */\n    public function hasPages();\n\n    /**\n     * Determine if there are more items in the data store.\n     *\n     * @return bool\n     */\n    public function hasMorePages();\n\n    /**\n     * Get the base path for paginator generated URLs.\n     *\n     * @return string|null\n     */\n    public function path();\n\n    /**\n     * Determine if the list of items is empty or not.\n     *\n     * @return bool\n     */\n    public function isEmpty();\n\n    /**\n     * Determine if the list of items is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty();\n\n    /**\n     * Render the paginator using a given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return string\n     */\n    public function render($view = null, $data = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Pipeline/Hub.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Pipeline;\n\ninterface Hub\n{\n    /**\n     * Send an object through one of the available pipelines.\n     *\n     * @param  mixed  $object\n     * @param  string|null  $pipeline\n     * @return mixed\n     */\n    public function pipe($object, $pipeline = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Pipeline/Pipeline.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Pipeline;\n\nuse Closure;\n\ninterface Pipeline\n{\n    /**\n     * Set the object being sent through the pipeline.\n     *\n     * @param  mixed  $passable\n     * @return $this\n     */\n    public function send($passable);\n\n    /**\n     * Set the array of pipes.\n     *\n     * @param  mixed  $pipes\n     * @return $this\n     */\n    public function through($pipes);\n\n    /**\n     * Set the method to call on the pipes.\n     *\n     * @param  string  $method\n     * @return $this\n     */\n    public function via($method);\n\n    /**\n     * Run the pipeline with a final destination callback.\n     *\n     * @param  \\Closure  $destination\n     * @return mixed\n     */\n    public function then(Closure $destination);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Process/InvokedProcess.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Process;\n\ninterface InvokedProcess\n{\n    /**\n     * Get the process ID if the process is still running.\n     *\n     * @return int|null\n     */\n    public function id();\n\n    /**\n     * Get the command line for the process.\n     *\n     * @return string\n     */\n    public function command();\n\n    /**\n     * Send a signal to the process.\n     *\n     * @param  int  $signal\n     * @return $this\n     */\n    public function signal(int $signal);\n\n    /**\n     * Determine if the process is still running.\n     *\n     * @return bool\n     */\n    public function running();\n\n    /**\n     * Get the standard output for the process.\n     *\n     * @return string\n     */\n    public function output();\n\n    /**\n     * Get the error output for the process.\n     *\n     * @return string\n     */\n    public function errorOutput();\n\n    /**\n     * Get the latest standard output for the process.\n     *\n     * @return string\n     */\n    public function latestOutput();\n\n    /**\n     * Get the latest error output for the process.\n     *\n     * @return string\n     */\n    public function latestErrorOutput();\n\n    /**\n     * Wait for the process to finish.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\ProcessResult\n     */\n    public function wait(?callable $output = null);\n\n    /**\n     * Wait until the given callback returns true.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\ProcessResult\n     */\n    public function waitUntil(?callable $output = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Process/ProcessResult.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Process;\n\ninterface ProcessResult\n{\n    /**\n     * Get the original command executed by the process.\n     *\n     * @return string\n     */\n    public function command();\n\n    /**\n     * Determine if the process was successful.\n     *\n     * @return bool\n     */\n    public function successful();\n\n    /**\n     * Determine if the process failed.\n     *\n     * @return bool\n     */\n    public function failed();\n\n    /**\n     * Get the exit code of the process.\n     *\n     * @return int|null\n     */\n    public function exitCode();\n\n    /**\n     * Get the standard output of the process.\n     *\n     * @return string\n     */\n    public function output();\n\n    /**\n     * Determine if the output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInOutput(string $output);\n\n    /**\n     * Get the error output of the process.\n     *\n     * @return string\n     */\n    public function errorOutput();\n\n    /**\n     * Determine if the error output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInErrorOutput(string $output);\n\n    /**\n     * Throw an exception if the process failed.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     */\n    public function throw(?callable $callback = null);\n\n    /**\n     * Throw an exception if the process failed and the given condition is true.\n     *\n     * @param  bool  $condition\n     * @param  callable|null  $callback\n     * @return $this\n     */\n    public function throwIf(bool $condition, ?callable $callback = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ClearableQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ClearableQueue\n{\n    /**\n     * Delete all of the jobs from the queue.\n     *\n     * @param  string  $queue\n     * @return int\n     */\n    public function clear($queue);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/EntityNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\nuse InvalidArgumentException;\n\nclass EntityNotFoundException extends InvalidArgumentException\n{\n    /**\n     * Create a new exception instance.\n     *\n     * @param  string  $type\n     * @param  mixed  $id\n     */\n    public function __construct($type, $id)\n    {\n        $id = (string) $id;\n\n        parent::__construct(\"Queueable entity [{$type}] not found for ID [{$id}].\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/EntityResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface EntityResolver\n{\n    /**\n     * Resolve the entity for the given ID.\n     *\n     * @param  string  $type\n     * @param  mixed  $id\n     * @return mixed\n     */\n    public function resolve($type, $id);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface Factory\n{\n    /**\n     * Resolve a queue connection instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connection($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/Job.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface Job\n{\n    /**\n     * Get the UUID of the job.\n     *\n     * @return string|null\n     */\n    public function uuid();\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string\n     */\n    public function getJobId();\n\n    /**\n     * Get the decoded body of the job.\n     *\n     * @return array\n     */\n    public function payload();\n\n    /**\n     * Fire the job.\n     *\n     * @return void\n     */\n    public function fire();\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0);\n\n    /**\n     * Determine if the job was released back into the queue.\n     *\n     * @return bool\n     */\n    public function isReleased();\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete();\n\n    /**\n     * Determine if the job has been deleted.\n     *\n     * @return bool\n     */\n    public function isDeleted();\n\n    /**\n     * Determine if the job has been deleted or released.\n     *\n     * @return bool\n     */\n    public function isDeletedOrReleased();\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts();\n\n    /**\n     * Determine if the job has been marked as a failure.\n     *\n     * @return bool\n     */\n    public function hasFailed();\n\n    /**\n     * Mark the job as \"failed\".\n     *\n     * @return void\n     */\n    public function markAsFailed();\n\n    /**\n     * Delete the job, call the \"failed\" method, and raise the failed job event.\n     *\n     * @param  \\Throwable|null  $e\n     * @return void\n     */\n    public function fail($e = null);\n\n    /**\n     * Get the number of times to attempt a job.\n     *\n     * @return int|null\n     */\n    public function maxTries();\n\n    /**\n     * Get the maximum number of exceptions allowed, regardless of attempts.\n     *\n     * @return int|null\n     */\n    public function maxExceptions();\n\n    /**\n     * Get the number of seconds the job can run.\n     *\n     * @return int|null\n     */\n    public function timeout();\n\n    /**\n     * Get the timestamp indicating when the job should timeout.\n     *\n     * @return int|null\n     */\n    public function retryUntil();\n\n    /**\n     * Get the name of the queued job class.\n     *\n     * @return string\n     */\n    public function getName();\n\n    /**\n     * Get the display name of the queued job class.\n     *\n     * Resolves the name of \"wrapped\" jobs such as class-based handlers.\n     *\n     * @return string\n     */\n    public function resolveName();\n\n    /**\n     * Get the class of the queued job.\n     *\n     * Resolves the class of \"wrapped\" jobs such as class-based handlers.\n     *\n     * @return string\n     */\n    public function resolveQueuedJobClass();\n\n    /**\n     * Get the name of the connection the job belongs to.\n     *\n     * @return string\n     */\n    public function getConnectionName();\n\n    /**\n     * Get the name of the queue the job belongs to.\n     *\n     * @return string\n     */\n    public function getQueue();\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/Monitor.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface Monitor\n{\n    /**\n     * Register a callback to be executed when a daemon queue is starting.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function starting($callback);\n\n    /**\n     * Register a callback to be executed on every iteration through the queue loop.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function looping($callback);\n\n    /**\n     * Register a callback to be executed when a job fails after the maximum number of retries.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function failing($callback);\n\n    /**\n     * Register a callback to be executed when a daemon queue is stopping.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function stopping($callback);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/Queue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface Queue\n{\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null);\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null);\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null);\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null);\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null);\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null);\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $queue\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function pushOn($queue, $job, $data = '');\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = []);\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null);\n\n    /**\n     * Push a new job onto a specific queue after (n) seconds.\n     *\n     * @param  string  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function laterOn($queue, $delay, $job, $data = '');\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function bulk($jobs, $data = '', $queue = null);\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null);\n\n    /**\n     * Get the connection name for the queue.\n     *\n     * @return string\n     */\n    public function getConnectionName();\n\n    /**\n     * Set the connection name for the queue.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setConnectionName($name);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/QueueableCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface QueueableCollection\n{\n    /**\n     * Get the type of the entities being queued.\n     *\n     * @return string|null\n     */\n    public function getQueueableClass();\n\n    /**\n     * Get the identifiers for all of the entities.\n     *\n     * @return array<int, mixed>\n     */\n    public function getQueueableIds();\n\n    /**\n     * Get the relationships of the entities being queued.\n     *\n     * @return array<int, string>\n     */\n    public function getQueueableRelations();\n\n    /**\n     * Get the connection of the entities being queued.\n     *\n     * @return string|null\n     */\n    public function getQueueableConnection();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/QueueableEntity.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface QueueableEntity\n{\n    /**\n     * Get the queueable identity for the entity.\n     *\n     * @return mixed\n     */\n    public function getQueueableId();\n\n    /**\n     * Get the relationships for the entity.\n     *\n     * @return array\n     */\n    public function getQueueableRelations();\n\n    /**\n     * Get the connection of the entity.\n     *\n     * @return string|null\n     */\n    public function getQueueableConnection();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ShouldBeEncrypted.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ShouldBeEncrypted\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ShouldBeUnique.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ShouldBeUnique\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ShouldBeUniqueUntilProcessing.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ShouldBeUniqueUntilProcessing extends ShouldBeUnique\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ShouldQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ShouldQueue\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Queue/ShouldQueueAfterCommit.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Queue;\n\ninterface ShouldQueueAfterCommit extends ShouldQueue\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Redis/Connection.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Redis;\n\nuse Closure;\n\ninterface Connection\n{\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function subscribe($channels, Closure $callback);\n\n    /**\n     * Subscribe to a set of given channels with wildcards.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function psubscribe($channels, Closure $callback);\n\n    /**\n     * Run a command against the Redis database.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function command($method, array $parameters = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Redis/Connector.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Redis;\n\ninterface Connector\n{\n    /**\n     * Create a connection to a Redis cluster.\n     *\n     * @param  array  $config\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function connect(array $config, array $options);\n\n    /**\n     * Create a connection to a Redis instance.\n     *\n     * @param  array  $config\n     * @param  array  $clusterOptions\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function connectToCluster(array $config, array $clusterOptions, array $options);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Redis/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Redis;\n\ninterface Factory\n{\n    /**\n     * Get a Redis connection by name.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function connection($name = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Redis/LimiterTimeoutException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Redis;\n\nuse Exception;\n\nclass LimiterTimeoutException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Routing/BindingRegistrar.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Routing;\n\ninterface BindingRegistrar\n{\n    /**\n     * Add a new route parameter binder.\n     *\n     * @param  string  $key\n     * @param  string|callable  $binder\n     * @return void\n     */\n    public function bind($key, $binder);\n\n    /**\n     * Get the binding callback for a given binding.\n     *\n     * @param  string  $key\n     * @return \\Closure\n     */\n    public function getBindingCallback($key);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Routing/Registrar.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Routing;\n\ninterface Registrar\n{\n    /**\n     * Register a new GET route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function get($uri, $action);\n\n    /**\n     * Register a new POST route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function post($uri, $action);\n\n    /**\n     * Register a new PUT route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function put($uri, $action);\n\n    /**\n     * Register a new DELETE route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function delete($uri, $action);\n\n    /**\n     * Register a new PATCH route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function patch($uri, $action);\n\n    /**\n     * Register a new OPTIONS route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function options($uri, $action);\n\n    /**\n     * Register a new route with the given verbs.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  array|string|callable  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function match($methods, $uri, $action);\n\n    /**\n     * Route a resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function resource($name, $controller, array $options = []);\n\n    /**\n     * Create a route group with shared attributes.\n     *\n     * @param  array  $attributes\n     * @param  \\Closure|string  $routes\n     * @return void\n     */\n    public function group(array $attributes, $routes);\n\n    /**\n     * Substitute the route bindings onto the route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function substituteBindings($route);\n\n    /**\n     * Substitute the implicit Eloquent model bindings for the route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     */\n    public function substituteImplicitBindings($route);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Routing/ResponseFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Routing;\n\nuse Closure;\nuse Illuminate\\Http\\StreamedEvent;\n\ninterface ResponseFactory\n{\n    /**\n     * Create a new response instance.\n     *\n     * @param  array|string  $content\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function make($content = '', $status = 200, array $headers = []);\n\n    /**\n     * Create a new \"no content\" response.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function noContent($status = 204, array $headers = []);\n\n    /**\n     * Create a new response for a given view.\n     *\n     * @param  string|array  $view\n     * @param  array  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function view($view, $data = [], $status = 200, array $headers = []);\n\n    /**\n     * Create a new JSON response instance.\n     *\n     * @param  mixed  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function json($data = [], $status = 200, array $headers = [], $options = 0);\n\n    /**\n     * Create a new JSONP response instance.\n     *\n     * @param  string  $callback\n     * @param  mixed  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function jsonp($callback, $data = [], $status = 200, array $headers = [], $options = 0);\n\n    /**\n     * Create a new event stream response.\n     *\n     * @param  \\Closure  $callback\n     * @param  array  $headers\n     * @param  \\Illuminate\\Http\\StreamedEvent|string|null  $endStreamWith\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function eventStream(Closure $callback, array $headers = [], StreamedEvent|string|null $endStreamWith = '</stream>');\n\n    /**\n     * Create a new streamed response instance.\n     *\n     * @param  callable  $callback\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function stream($callback, $status = 200, array $headers = []);\n\n    /**\n     * Create a new streamed JSON response instance.\n     *\n     * @param  array  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $encodingOptions\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedJsonResponse\n     */\n    public function streamJson($data, $status = 200, $headers = [], $encodingOptions = 15);\n\n    /**\n     * Create a new streamed response instance as a file download.\n     *\n     * @param  callable  $callback\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @param  string|null  $disposition\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function streamDownload($callback, $name = null, array $headers = [], $disposition = 'attachment');\n\n    /**\n     * Create a new file download response.\n     *\n     * @param  \\SplFileInfo|string  $file\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @param  string|null  $disposition\n     * @return \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse\n     */\n    public function download($file, $name = null, array $headers = [], $disposition = 'attachment');\n\n    /**\n     * Return the raw contents of a binary file.\n     *\n     * @param  \\SplFileInfo|string  $file\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse\n     */\n    public function file($file, array $headers = []);\n\n    /**\n     * Create a new redirect response to the given path.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectTo($path, $status = 302, $headers = [], $secure = null);\n\n    /**\n     * Create a new redirect response to a named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToRoute($route, $parameters = [], $status = 302, $headers = []);\n\n    /**\n     * Create a new redirect response to a controller action.\n     *\n     * @param  array|string  $action\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToAction($action, $parameters = [], $status = 302, $headers = []);\n\n    /**\n     * Create a new redirect response, while putting the current URL in the session.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectGuest($path, $status = 302, $headers = [], $secure = null);\n\n    /**\n     * Create a new redirect response to the previously intended location.\n     *\n     * @param  string  $default\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToIntended($default = '/', $status = 302, $headers = [], $secure = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Routing/UrlGenerator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Routing;\n\ninterface UrlGenerator\n{\n    /**\n     * Get the current URL for the request.\n     *\n     * @return string\n     */\n    public function current();\n\n    /**\n     * Get the URL for the previous request.\n     *\n     * @param  mixed  $fallback\n     * @return string\n     */\n    public function previous($fallback = false);\n\n    /**\n     * Generate an absolute URL to the given path.\n     *\n     * @param  string  $path\n     * @param  mixed  $extra\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function to($path, $extra = [], $secure = null);\n\n    /**\n     * Generate a secure, absolute URL to the given path.\n     *\n     * @param  string  $path\n     * @param  array  $parameters\n     * @return string\n     */\n    public function secure($path, $parameters = []);\n\n    /**\n     * Generate the URL to an application asset.\n     *\n     * @param  string  $path\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function asset($path, $secure = null);\n\n    /**\n     * Get the URL to a named route.\n     *\n     * @param  string  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function route($name, $parameters = [], $absolute = true);\n\n    /**\n     * Create a signed route URL for a named route.\n     *\n     * @param  string  $name\n     * @param  mixed  $parameters\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $expiration\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true);\n\n    /**\n     * Create a temporary signed route URL for a named route.\n     *\n     * @param  string  $name\n     * @param  \\DateTimeInterface|\\DateInterval|int  $expiration\n     * @param  array  $parameters\n     * @param  bool  $absolute\n     * @return string\n     */\n    public function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true);\n\n    /**\n     * Generate an absolute URL with the given query parameters.\n     *\n     * @param  string  $path\n     * @param  array  $query\n     * @param  mixed  $extra\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function query($path, $query = [], $extra = [], $secure = null);\n\n    /**\n     * Get the URL to a controller action.\n     *\n     * @param  string|array  $action\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return string\n     */\n    public function action($action, $parameters = [], $absolute = true);\n\n    /**\n     * Get the root controller namespace.\n     *\n     * @return string\n     */\n    public function getRootControllerNamespace();\n\n    /**\n     * Set the root controller namespace.\n     *\n     * @param  string  $rootNamespace\n     * @return $this\n     */\n    public function setRootControllerNamespace($rootNamespace);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Routing/UrlRoutable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Routing;\n\ninterface UrlRoutable\n{\n    /**\n     * Get the value of the model's route key.\n     *\n     * @return mixed\n     */\n    public function getRouteKey();\n\n    /**\n     * Get the route key for the model.\n     *\n     * @return string\n     */\n    public function getRouteKeyName();\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveRouteBinding($value, $field = null);\n\n    /**\n     * Retrieve the child model for a bound value.\n     *\n     * @param  string  $childType\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveChildRouteBinding($childType, $value, $field);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Session/Middleware/AuthenticatesSessions.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Session\\Middleware;\n\ninterface AuthenticatesSessions\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Session/Session.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Session;\n\ninterface Session\n{\n    /**\n     * Get the name of the session.\n     *\n     * @return string\n     */\n    public function getName();\n\n    /**\n     * Set the name of the session.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setName($name);\n\n    /**\n     * Get the current session ID.\n     *\n     * @return string\n     */\n    public function getId();\n\n    /**\n     * Set the session ID.\n     *\n     * @param  string  $id\n     * @return void\n     */\n    public function setId($id);\n\n    /**\n     * Start the session, reading the data from a handler.\n     *\n     * @return bool\n     */\n    public function start();\n\n    /**\n     * Save the session data to storage.\n     *\n     * @return void\n     */\n    public function save();\n\n    /**\n     * Get all of the session data.\n     *\n     * @return array\n     */\n    public function all();\n\n    /**\n     * Checks if a key exists.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function exists($key);\n\n    /**\n     * Checks if a key is present and not null.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function has($key);\n\n    /**\n     * Get an item from the session.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null);\n\n    /**\n     * Get the value of a given key and then forget it.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function pull($key, $default = null);\n\n    /**\n     * Put a key / value pair or array of key / value pairs in the session.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function put($key, $value = null);\n\n    /**\n     * Flash a key / value pair to the session.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function flash(string $key, $value = true);\n\n    /**\n     * Get the CSRF token value.\n     *\n     * @return string\n     */\n    public function token();\n\n    /**\n     * Regenerate the CSRF token value.\n     *\n     * @return void\n     */\n    public function regenerateToken();\n\n    /**\n     * Remove an item from the session, returning its value.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function remove($key);\n\n    /**\n     * Remove one or many items from the session.\n     *\n     * @param  string|array  $keys\n     * @return void\n     */\n    public function forget($keys);\n\n    /**\n     * Remove all of the items from the session.\n     *\n     * @return void\n     */\n    public function flush();\n\n    /**\n     * Flush the session data and regenerate the ID.\n     *\n     * @return bool\n     */\n    public function invalidate();\n\n    /**\n     * Generate a new session identifier.\n     *\n     * @param  bool  $destroy\n     * @return bool\n     */\n    public function regenerate($destroy = false);\n\n    /**\n     * Generate a new session ID for the session.\n     *\n     * @param  bool  $destroy\n     * @return bool\n     */\n    public function migrate($destroy = false);\n\n    /**\n     * Determine if the session has been started.\n     *\n     * @return bool\n     */\n    public function isStarted();\n\n    /**\n     * Get the previous URL from the session.\n     *\n     * @return string|null\n     */\n    public function previousUrl();\n\n    /**\n     * Set the \"previous\" URL in the session.\n     *\n     * @param  string  $url\n     * @return void\n     */\n    public function setPreviousUrl($url);\n\n    /**\n     * Get the session handler instance.\n     *\n     * @return \\SessionHandlerInterface\n     */\n    public function getHandler();\n\n    /**\n     * Determine if the session handler needs a request.\n     *\n     * @return bool\n     */\n    public function handlerNeedsRequest();\n\n    /**\n     * Set the request on the handler instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    public function setRequestOnHandler($request);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/Arrayable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\n/**\n * @template TKey of array-key\n * @template TValue\n */\ninterface Arrayable\n{\n    /**\n     * Get the instance as an array.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function toArray();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/CanBeEscapedWhenCastToString.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface CanBeEscapedWhenCastToString\n{\n    /**\n     * Indicate that the object's string representation should be escaped when __toString is invoked.\n     *\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function escapeWhenCastingToString($escape = true);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/DeferrableProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface DeferrableProvider\n{\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/DeferringDisplayableValue.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface DeferringDisplayableValue\n{\n    /**\n     * Resolve the displayable value that the class is deferring.\n     *\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable|string\n     */\n    public function resolveDisplayableValue();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/HasOnceHash.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface HasOnceHash\n{\n    /**\n     * Compute the hash that should be used to represent the object when given to a function using \"once\".\n     *\n     * @return string\n     */\n    public function onceHash();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/Htmlable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface Htmlable\n{\n    /**\n     * Get content as a string of HTML.\n     *\n     * @return string\n     */\n    public function toHtml();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/Jsonable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface Jsonable\n{\n    /**\n     * Convert the object to its JSON representation.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/MessageBag.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\nuse Countable;\n\ninterface MessageBag extends Arrayable, Countable\n{\n    /**\n     * Get the keys present in the message bag.\n     *\n     * @return array\n     */\n    public function keys();\n\n    /**\n     * Add a message to the bag.\n     *\n     * @param  string  $key\n     * @param  string  $message\n     * @return $this\n     */\n    public function add($key, $message);\n\n    /**\n     * Merge a new array of messages into the bag.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array  $messages\n     * @return $this\n     */\n    public function merge($messages);\n\n    /**\n     * Determine if messages exist for a given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function has($key);\n\n    /**\n     * Get the first message from the bag for a given key.\n     *\n     * @param  string|null  $key\n     * @param  string|null  $format\n     * @return string\n     */\n    public function first($key = null, $format = null);\n\n    /**\n     * Get all of the messages from the bag for a given key.\n     *\n     * @param  string  $key\n     * @param  string|null  $format\n     * @return array\n     */\n    public function get($key, $format = null);\n\n    /**\n     * Get all of the messages for every key in the bag.\n     *\n     * @param  string|null  $format\n     * @return array\n     */\n    public function all($format = null);\n\n    /**\n     * Remove a message from the bag.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function forget($key);\n\n    /**\n     * Get the raw messages in the container.\n     *\n     * @return array\n     */\n    public function getMessages();\n\n    /**\n     * Get the default message format.\n     *\n     * @return string\n     */\n    public function getFormat();\n\n    /**\n     * Set the default message format.\n     *\n     * @param  string  $format\n     * @return $this\n     */\n    public function setFormat($format = ':message');\n\n    /**\n     * Determine if the message bag has any messages.\n     *\n     * @return bool\n     */\n    public function isEmpty();\n\n    /**\n     * Determine if the message bag has any messages.\n     *\n     * @return bool\n     */\n    public function isNotEmpty();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/MessageProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface MessageProvider\n{\n    /**\n     * Get the messages for the instance.\n     *\n     * @return \\Illuminate\\Contracts\\Support\\MessageBag\n     */\n    public function getMessageBag();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/Renderable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface Renderable\n{\n    /**\n     * Get the evaluated contents of the object.\n     *\n     * @return string\n     */\n    public function render();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/Responsable.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\ninterface Responsable\n{\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function toResponse($request);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Support/ValidatedData.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Support;\n\nuse ArrayAccess;\nuse IteratorAggregate;\n\ninterface ValidatedData extends Arrayable, ArrayAccess, IteratorAggregate\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Translation/HasLocalePreference.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Translation;\n\ninterface HasLocalePreference\n{\n    /**\n     * Get the preferred locale of the entity.\n     *\n     * @return string|null\n     */\n    public function preferredLocale();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Translation/Loader.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Translation;\n\ninterface Loader\n{\n    /**\n     * Load the messages for the given locale.\n     *\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  string|null  $namespace\n     * @return array\n     */\n    public function load($locale, $group, $namespace = null);\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string  $hint\n     * @return void\n     */\n    public function addNamespace($namespace, $hint);\n\n    /**\n     * Add a new JSON path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addJsonPath($path);\n\n    /**\n     * Get an array of all the registered namespaces.\n     *\n     * @return array\n     */\n    public function namespaces();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Translation/Translator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Translation;\n\ninterface Translator\n{\n    /**\n     * Get the translation for a given key.\n     *\n     * @param  string  $key\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return mixed\n     */\n    public function get($key, array $replace = [], $locale = null);\n\n    /**\n     * Get a translation according to an integer value.\n     *\n     * @param  string  $key\n     * @param  \\Countable|int|float|array  $number\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return string\n     */\n    public function choice($key, $number, array $replace = [], $locale = null);\n\n    /**\n     * Get the default locale being used.\n     *\n     * @return string\n     */\n    public function getLocale();\n\n    /**\n     * Set the default locale.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public function setLocale($locale);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/CompilableRules.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\ninterface CompilableRules\n{\n    /**\n     * Compile the object into usable rules.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $data\n     * @param  mixed  $context\n     * @return \\stdClass\n     */\n    public function compile($attribute, $value, $data = null, $context = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/DataAwareRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\ninterface DataAwareRule\n{\n    /**\n     * Set the data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData(array $data);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\ninterface Factory\n{\n    /**\n     * Create a new Validator instance.\n     *\n     * @param  array  $data\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    public function make(array $data, array $rules, array $messages = [], array $attributes = []);\n\n    /**\n     * Register a custom validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @param  string|null  $message\n     * @return void\n     */\n    public function extend($rule, $extension, $message = null);\n\n    /**\n     * Register a custom implicit validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @param  string|null  $message\n     * @return void\n     */\n    public function extendImplicit($rule, $extension, $message = null);\n\n    /**\n     * Register a custom implicit validator message replacer.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $replacer\n     * @return void\n     */\n    public function replacer($rule, $replacer);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/ImplicitRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\n/**\n * @deprecated see ValidationRule\n */\ninterface ImplicitRule extends Rule\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/InvokableRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\nuse Closure;\n\n/**\n * @deprecated see ValidationRule\n */\ninterface InvokableRule\n{\n    /**\n     * Run the validation rule.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  \\Closure(string, ?string=): \\Illuminate\\Translation\\PotentiallyTranslatedString  $fail\n     * @return void\n     */\n    public function __invoke(string $attribute, mixed $value, Closure $fail);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/Rule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\n/**\n * @deprecated see ValidationRule\n */\ninterface Rule\n{\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value);\n\n    /**\n     * Get the validation error message.\n     *\n     * @return string|array\n     */\n    public function message();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/UncompromisedVerifier.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\ninterface UncompromisedVerifier\n{\n    /**\n     * Verify that the given data has not been compromised in data leaks.\n     *\n     * @param  array  $data\n     * @return bool\n     */\n    public function verify($data);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/ValidatesWhenResolved.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\ninterface ValidatesWhenResolved\n{\n    /**\n     * Validate the given class instance.\n     *\n     * @return void\n     */\n    public function validateResolved();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/ValidationRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\nuse Closure;\n\ninterface ValidationRule\n{\n    /**\n     * Run the validation rule.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  \\Closure(string, ?string=): \\Illuminate\\Translation\\PotentiallyTranslatedString  $fail\n     * @return void\n     */\n    public function validate(string $attribute, mixed $value, Closure $fail): void;\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/Validator.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\nuse Illuminate\\Contracts\\Support\\MessageProvider;\n\ninterface Validator extends MessageProvider\n{\n    /**\n     * Run the validator's rules against its data.\n     *\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validate();\n\n    /**\n     * Get the attributes and values that were validated.\n     *\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validated();\n\n    /**\n     * Determine if the data fails the validation rules.\n     *\n     * @return bool\n     */\n    public function fails();\n\n    /**\n     * Get the failed validation rules.\n     *\n     * @return array\n     */\n    public function failed();\n\n    /**\n     * Add conditions to a given field based on a Closure.\n     *\n     * @param  string|array  $attribute\n     * @param  string|array  $rules\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function sometimes($attribute, $rules, callable $callback);\n\n    /**\n     * Add an after validation callback.\n     *\n     * @param  callable|string  $callback\n     * @return $this\n     */\n    public function after($callback);\n\n    /**\n     * Get all of the validation error messages.\n     *\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function errors();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/Validation/ValidatorAwareRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\Validation;\n\nuse Illuminate\\Validation\\Validator;\n\ninterface ValidatorAwareRule\n{\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator(Validator $validator);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/View/Engine.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\View;\n\ninterface Engine\n{\n    /**\n     * Get the evaluated contents of the view.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return string\n     */\n    public function get($path, array $data = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/View/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\View;\n\ninterface Factory\n{\n    /**\n     * Determine if a given view exists.\n     *\n     * @param  string  $view\n     * @return bool\n     */\n    public function exists($view);\n\n    /**\n     * Get the evaluated view contents for the given path.\n     *\n     * @param  string  $path\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    public function file($path, $data = [], $mergeData = []);\n\n    /**\n     * Get the evaluated view contents for the given view.\n     *\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    public function make($view, $data = [], $mergeData = []);\n\n    /**\n     * Add a piece of shared data to the environment.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function share($key, $value = null);\n\n    /**\n     * Register a view composer event.\n     *\n     * @param  array|string  $views\n     * @param  \\Closure|string  $callback\n     * @return array\n     */\n    public function composer($views, $callback);\n\n    /**\n     * Register a view creator event.\n     *\n     * @param  array|string  $views\n     * @param  \\Closure|string  $callback\n     * @return array\n     */\n    public function creator($views, $callback);\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return $this\n     */\n    public function addNamespace($namespace, $hints);\n\n    /**\n     * Replace the namespace hints for the given namespace.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return $this\n     */\n    public function replaceNamespace($namespace, $hints);\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/View/View.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\View;\n\nuse Illuminate\\Contracts\\Support\\Renderable;\n\ninterface View extends Renderable\n{\n    /**\n     * Get the name of the view.\n     *\n     * @return string\n     */\n    public function name();\n\n    /**\n     * Add a piece of data to the view.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function with($key, $value = null);\n\n    /**\n     * Get the array of view data.\n     *\n     * @return array\n     */\n    public function getData();\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/View/ViewCompilationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Contracts\\View;\n\nuse Exception;\n\nclass ViewCompilationException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Contracts/composer.json",
    "content": "{\n    \"name\": \"illuminate/contracts\",\n    \"description\": \"The Illuminate Contracts package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"psr/container\": \"^1.1.1 || ^2.0.1\",\n        \"psr/simple-cache\": \"^1.0 || ^2.0 || ^3.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Contracts\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Cookie/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Cookie/CookieJar.php",
    "content": "<?php\n\nnamespace Illuminate\\Cookie;\n\nuse Illuminate\\Contracts\\Cookie\\QueueingFactory as JarContract;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass CookieJar implements JarContract\n{\n    use InteractsWithTime, Macroable;\n\n    /**\n     * The default path (if specified).\n     *\n     * @var string\n     */\n    protected $path = '/';\n\n    /**\n     * The default domain (if specified).\n     *\n     * @var string|null\n     */\n    protected $domain;\n\n    /**\n     * The default secure setting (defaults to null).\n     *\n     * @var bool|null\n     */\n    protected $secure;\n\n    /**\n     * The default SameSite option (defaults to lax).\n     *\n     * @var string\n     */\n    protected $sameSite = 'lax';\n\n    /**\n     * All of the cookies queued for sending.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\Cookie[]\n     */\n    protected $queued = [];\n\n    /**\n     * Create a new cookie instance.\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @param  int  $minutes\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  bool  $httpOnly\n     * @param  bool  $raw\n     * @param  string|null  $sameSite\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)\n    {\n        [$path, $domain, $secure, $sameSite] = $this->getPathAndDomain($path, $domain, $secure, $sameSite);\n\n        $time = ($minutes == 0) ? 0 : $this->availableAt($minutes * 60);\n\n        return new Cookie($name, $value, $time, $path, $domain, $secure, $httpOnly, $raw, $sameSite);\n    }\n\n    /**\n     * Create a cookie that lasts \"forever\" (400 days).\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  bool  $httpOnly\n     * @param  bool  $raw\n     * @param  string|null  $sameSite\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)\n    {\n        return $this->make($name, $value, 576000, $path, $domain, $secure, $httpOnly, $raw, $sameSite);\n    }\n\n    /**\n     * Expire the given cookie.\n     *\n     * @param  string  $name\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public function forget($name, $path = null, $domain = null)\n    {\n        return $this->make($name, null, -2628000, $path, $domain);\n    }\n\n    /**\n     * Determine if a cookie has been queued.\n     *\n     * @param  string  $key\n     * @param  string|null  $path\n     * @return bool\n     */\n    public function hasQueued($key, $path = null)\n    {\n        return ! is_null($this->queued($key, null, $path));\n    }\n\n    /**\n     * Get a queued cookie instance.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @param  string|null  $path\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie|null\n     */\n    public function queued($key, $default = null, $path = null)\n    {\n        $queued = Arr::get($this->queued, $key, $default);\n\n        if ($path === null) {\n            return Arr::last($queued, null, $default);\n        }\n\n        return Arr::get($queued, $path, $default);\n    }\n\n    /**\n     * Queue a cookie to send with the next response.\n     *\n     * @param  mixed  ...$parameters\n     * @return void\n     */\n    public function queue(...$parameters)\n    {\n        if (isset($parameters[0]) && $parameters[0] instanceof Cookie) {\n            $cookie = $parameters[0];\n        } else {\n            $cookie = $this->make(...array_values($parameters));\n        }\n\n        if (! isset($this->queued[$cookie->getName()])) {\n            $this->queued[$cookie->getName()] = [];\n        }\n\n        $this->queued[$cookie->getName()][$cookie->getPath()] = $cookie;\n    }\n\n    /**\n     * Queue a cookie to expire with the next response.\n     *\n     * @param  string  $name\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @return void\n     */\n    public function expire($name, $path = null, $domain = null)\n    {\n        $this->queue($this->forget($name, $path, $domain));\n    }\n\n    /**\n     * Remove a cookie from the queue.\n     *\n     * @param  string  $name\n     * @param  string|null  $path\n     * @return void\n     */\n    public function unqueue($name, $path = null)\n    {\n        if ($path === null) {\n            unset($this->queued[$name]);\n\n            return;\n        }\n\n        unset($this->queued[$name][$path]);\n\n        if (empty($this->queued[$name])) {\n            unset($this->queued[$name]);\n        }\n    }\n\n    /**\n     * Get the path and domain, or the default values.\n     *\n     * @param  string  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  string|null  $sameSite\n     * @return array\n     */\n    protected function getPathAndDomain($path, $domain, $secure = null, $sameSite = null)\n    {\n        return [$path ?: $this->path, $domain ?: $this->domain, is_bool($secure) ? $secure : $this->secure, $sameSite ?: $this->sameSite];\n    }\n\n    /**\n     * Set the default path and domain for the jar.\n     *\n     * @param  string  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  string|null  $sameSite\n     * @return $this\n     */\n    public function setDefaultPathAndDomain($path, $domain, $secure = false, $sameSite = null)\n    {\n        [$this->path, $this->domain, $this->secure, $this->sameSite] = [$path, $domain, $secure, $sameSite];\n\n        return $this;\n    }\n\n    /**\n     * Get the cookies which have been queued for the next request.\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie[]\n     */\n    public function getQueuedCookies()\n    {\n        return Arr::flatten($this->queued);\n    }\n\n    /**\n     * Flush the cookies which have been queued for the next request.\n     *\n     * @return $this\n     */\n    public function flushQueuedCookies()\n    {\n        $this->queued = [];\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/CookieServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Cookie;\n\nuse Illuminate\\Support\\ServiceProvider;\n\nclass CookieServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('cookie', function ($app) {\n            $config = $app->make('config')->get('session');\n\n            return (new CookieJar)->setDefaultPathAndDomain(\n                $config['path'], $config['domain'], $config['secure'], $config['same_site'] ?? null\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/CookieValuePrefix.php",
    "content": "<?php\n\nnamespace Illuminate\\Cookie;\n\nclass CookieValuePrefix\n{\n    /**\n     * Create a new cookie value prefix for the given cookie name.\n     *\n     * @param  string  $cookieName\n     * @param  string  $key\n     * @return string\n     */\n    public static function create($cookieName, $key)\n    {\n        return hash_hmac('sha1', $cookieName.'v2', $key).'|';\n    }\n\n    /**\n     * Remove the cookie value prefix.\n     *\n     * @param  string  $cookieValue\n     * @return string\n     */\n    public static function remove($cookieValue)\n    {\n        return substr($cookieValue, 41);\n    }\n\n    /**\n     * Validate a cookie value contains a valid prefix. If it does, return the cookie value with the prefix removed. Otherwise, return null.\n     *\n     * @param  string  $cookieName\n     * @param  string  $cookieValue\n     * @param  array  $keys\n     * @return string|null\n     */\n    public static function validate($cookieName, $cookieValue, array $keys)\n    {\n        foreach ($keys as $key) {\n            $hasValidPrefix = str_starts_with($cookieValue, static::create($cookieName, $key));\n\n            if ($hasValidPrefix) {\n                return static::remove($cookieValue);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Cookie\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Cookie\\QueueingFactory as CookieJar;\n\nclass AddQueuedCookiesToResponse\n{\n    /**\n     * The cookie jar instance.\n     *\n     * @var \\Illuminate\\Contracts\\Cookie\\QueueingFactory\n     */\n    protected $cookies;\n\n    /**\n     * Create a new CookieQueue instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cookie\\QueueingFactory  $cookies\n     */\n    public function __construct(CookieJar $cookies)\n    {\n        $this->cookies = $cookies;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        $response = $next($request);\n\n        foreach ($this->cookies->getQueuedCookies() as $cookie) {\n            $response->headers->setCookie($cookie);\n        }\n\n        return $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/Middleware/EncryptCookies.php",
    "content": "<?php\n\nnamespace Illuminate\\Cookie\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Contracts\\Encryption\\Encrypter as EncrypterContract;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Support\\Arr;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass EncryptCookies\n{\n    /**\n     * The encrypter instance.\n     *\n     * @var \\Illuminate\\Contracts\\Encryption\\Encrypter\n     */\n    protected $encrypter;\n\n    /**\n     * The names of the cookies that should not be encrypted.\n     *\n     * @var array<int, string>\n     */\n    protected $except = [];\n\n    /**\n     * The globally ignored cookies that should not be encrypted.\n     *\n     * @var array\n     */\n    protected static $neverEncrypt = [];\n\n    /**\n     * Indicates if cookies should be serialized.\n     *\n     * @var bool\n     */\n    protected static $serialize = false;\n\n    /**\n     * Create a new CookieGuard instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Encryption\\Encrypter  $encrypter\n     */\n    public function __construct(EncrypterContract $encrypter)\n    {\n        $this->encrypter = $encrypter;\n    }\n\n    /**\n     * Disable encryption for the given cookie name(s).\n     *\n     * @param  string|array  $name\n     * @return void\n     */\n    public function disableFor($name)\n    {\n        $this->except = array_merge($this->except, (array) $name);\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function handle($request, Closure $next)\n    {\n        return $this->encrypt($next($this->decrypt($request)));\n    }\n\n    /**\n     * Decrypt the cookies on the request.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Request\n     */\n    protected function decrypt(Request $request)\n    {\n        foreach ($request->cookies as $key => $cookie) {\n            if ($this->isDisabled($key)) {\n                continue;\n            }\n\n            try {\n                $value = $this->decryptCookie($key, $cookie);\n\n                $request->cookies->set($key, $this->validateValue($key, $value));\n            } catch (DecryptException) {\n                $request->cookies->set($key, null);\n            }\n        }\n\n        return $request;\n    }\n\n    /**\n     * Validate and remove the cookie value prefix from the value.\n     *\n     * @param  string  $key\n     * @param  array<string, string>|string  $value\n     * @return array|string|null\n     *\n     * @phpstan-return ($value is array ? array<string|null> : string|null)\n     */\n    protected function validateValue(string $key, $value)\n    {\n        return is_array($value)\n            ? $this->validateArray($key, $value)\n            : CookieValuePrefix::validate($key, $value, $this->encrypter->getAllKeys());\n    }\n\n    /**\n     * Validate and remove the cookie value prefix from all values of an array.\n     *\n     * @param  string  $key\n     * @param  array  $value\n     * @return array\n     */\n    protected function validateArray(string $key, array $value)\n    {\n        $validated = [];\n\n        foreach ($value as $index => $subValue) {\n            $validated[$index] = $this->validateValue(\"{$key}[{$index}]\", $subValue);\n        }\n\n        return $validated;\n    }\n\n    /**\n     * Decrypt the given cookie and return the value.\n     *\n     * @param  string  $name\n     * @param  string|array  $cookie\n     * @return string|array\n     */\n    protected function decryptCookie($name, $cookie)\n    {\n        return is_array($cookie)\n            ? $this->decryptArray($cookie)\n            : $this->encrypter->decrypt($cookie, static::serialized($name));\n    }\n\n    /**\n     * Decrypt an array based cookie.\n     *\n     * @param  array  $cookie\n     * @return array\n     */\n    protected function decryptArray(array $cookie)\n    {\n        $decrypted = [];\n\n        foreach ($cookie as $key => $value) {\n            if (is_string($value)) {\n                $decrypted[$key] = $this->encrypter->decrypt($value, static::serialized($key));\n            }\n\n            if (is_array($value)) {\n                $decrypted[$key] = $this->decryptArray($value);\n            }\n        }\n\n        return $decrypted;\n    }\n\n    /**\n     * Encrypt the cookies on an outgoing response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function encrypt(Response $response)\n    {\n        foreach ($response->headers->getCookies() as $cookie) {\n            if ($this->isDisabled($cookie->getName())) {\n                continue;\n            }\n\n            $response->headers->setCookie($this->duplicate(\n                $cookie,\n                $this->encrypter->encrypt(\n                    CookieValuePrefix::create($cookie->getName(), $this->encrypter->getKey()).$cookie->getValue(),\n                    static::serialized($cookie->getName())\n                )\n            ));\n        }\n\n        return $response;\n    }\n\n    /**\n     * Duplicate a cookie with a new value.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Cookie  $cookie\n     * @param  mixed  $value\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    protected function duplicate(Cookie $cookie, $value)\n    {\n        return $cookie->withValue($value);\n    }\n\n    /**\n     * Determine whether encryption has been disabled for the given cookie.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function isDisabled($name)\n    {\n        return in_array($name, array_merge($this->except, static::$neverEncrypt));\n    }\n\n    /**\n     * Indicate that the given cookies should never be encrypted.\n     *\n     * @param  array|string  $cookies\n     * @return void\n     */\n    public static function except($cookies)\n    {\n        static::$neverEncrypt = array_values(array_unique(\n            array_merge(static::$neverEncrypt, Arr::wrap($cookies))\n        ));\n    }\n\n    /**\n     * Determine if the cookie contents should be serialized.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public static function serialized($name)\n    {\n        return static::$serialize;\n    }\n\n    /**\n     * Flush the middleware's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$neverEncrypt = [];\n\n        static::$serialize = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Cookie/composer.json",
    "content": "{\n    \"name\": \"illuminate/cookie\",\n    \"description\": \"The Illuminate Cookie package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-hash\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-kernel\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Cookie\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Database/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Database/Capsule/Manager.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Capsule;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Connectors\\ConnectionFactory;\nuse Illuminate\\Database\\DatabaseManager;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Support\\Traits\\CapsuleManagerTrait;\nuse PDO;\n\nclass Manager\n{\n    use CapsuleManagerTrait;\n\n    /**\n     * The database manager instance.\n     *\n     * @var \\Illuminate\\Database\\DatabaseManager\n     */\n    protected $manager;\n\n    /**\n     * Create a new database capsule manager.\n     *\n     * @param  \\Illuminate\\Container\\Container|null  $container\n     */\n    public function __construct(?Container $container = null)\n    {\n        $this->setupContainer($container ?: new Container);\n\n        // Once we have the container setup, we will setup the default configuration\n        // options in the container \"config\" binding. This will make the database\n        // manager work correctly out of the box without extreme configuration.\n        $this->setupDefaultConfiguration();\n\n        $this->setupManager();\n    }\n\n    /**\n     * Setup the default database configuration options.\n     *\n     * @return void\n     */\n    protected function setupDefaultConfiguration()\n    {\n        $this->container['config']['database.fetch'] = PDO::FETCH_OBJ;\n\n        $this->container['config']['database.default'] = 'default';\n    }\n\n    /**\n     * Build the database manager instance.\n     *\n     * @return void\n     */\n    protected function setupManager()\n    {\n        $factory = new ConnectionFactory($this->container);\n\n        $this->manager = new DatabaseManager($this->container, $factory);\n    }\n\n    /**\n     * Get a connection instance from the global manager.\n     *\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public static function connection($connection = null)\n    {\n        return static::$instance->getConnection($connection);\n    }\n\n    /**\n     * Get a fluent query builder instance.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|string  $table\n     * @param  string|null  $as\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public static function table($table, $as = null, $connection = null)\n    {\n        return static::$instance->connection($connection)->table($table, $as);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    public static function schema($connection = null)\n    {\n        return static::$instance->connection($connection)->getSchemaBuilder();\n    }\n\n    /**\n     * Get a registered connection instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getConnection($name = null)\n    {\n        return $this->manager->connection($name);\n    }\n\n    /**\n     * Register a connection with the manager.\n     *\n     * @param  array  $config\n     * @param  string  $name\n     * @return void\n     */\n    public function addConnection(array $config, $name = 'default')\n    {\n        $connections = $this->container['config']['database.connections'];\n\n        $connections[$name] = $config;\n\n        $this->container['config']['database.connections'] = $connections;\n    }\n\n    /**\n     * Bootstrap Eloquent so it is ready for usage.\n     *\n     * @return void\n     */\n    public function bootEloquent()\n    {\n        Eloquent::setConnectionResolver($this->manager);\n\n        // If we have an event dispatcher instance, we will go ahead and register it\n        // with the Eloquent ORM, allowing for model callbacks while creating and\n        // updating \"model\" instances; however, it is not necessary to operate.\n        if ($dispatcher = $this->getEventDispatcher()) {\n            Eloquent::setEventDispatcher($dispatcher);\n        }\n    }\n\n    /**\n     * Set the fetch mode for the database connections.\n     *\n     * @param  int  $fetchMode\n     * @return $this\n     */\n    public function setFetchMode($fetchMode)\n    {\n        $this->container['config']['database.fetch'] = $fetchMode;\n\n        return $this;\n    }\n\n    /**\n     * Get the database manager instance.\n     *\n     * @return \\Illuminate\\Database\\DatabaseManager\n     */\n    public function getDatabaseManager()\n    {\n        return $this->manager;\n    }\n\n    /**\n     * Get the current event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getEventDispatcher()\n    {\n        if ($this->container->bound('events')) {\n            return $this->container['events'];\n        }\n    }\n\n    /**\n     * Set the event dispatcher instance to be used by connections.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @return void\n     */\n    public function setEventDispatcher(Dispatcher $dispatcher)\n    {\n        $this->container->instance('events', $dispatcher);\n    }\n\n    /**\n     * Dynamically pass methods to the default connection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public static function __callStatic($method, $parameters)\n    {\n        return static::connection()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ClassMorphViolationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass ClassMorphViolationException extends RuntimeException\n{\n    /**\n     * The name of the affected Eloquent model.\n     *\n     * @var string\n     */\n    public $model;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  object  $model\n     */\n    public function __construct($model)\n    {\n        $class = get_class($model);\n\n        parent::__construct(\"No morph map defined for model [{$class}].\");\n\n        $this->model = $class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/BuildsQueries.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\MultipleRecordsFoundException;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\RecordNotFoundException;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Pagination\\Paginator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse InvalidArgumentException;\nuse RuntimeException;\n\n/**\n * @template TValue\n *\n * @mixin \\Illuminate\\Database\\Query\\Builder\n */\ntrait BuildsQueries\n{\n    use Conditionable;\n\n    /**\n     * Chunk the results of the query.\n     *\n     * @param  int  $count\n     * @param  callable(\\Illuminate\\Support\\Collection<int, TValue>, int): mixed  $callback\n     * @return bool\n     */\n    public function chunk($count, callable $callback)\n    {\n        $this->enforceOrderBy();\n\n        $skip = $this->getOffset();\n        $remaining = $this->getLimit();\n\n        $page = 1;\n\n        do {\n            $offset = (($page - 1) * $count) + (int) $skip;\n\n            $limit = is_null($remaining) ? $count : min($count, $remaining);\n\n            if ($limit == 0) {\n                break;\n            }\n\n            $results = $this->offset($offset)->limit($limit)->get();\n\n            $countResults = $results->count();\n\n            if ($countResults == 0) {\n                break;\n            }\n\n            if (! is_null($remaining)) {\n                $remaining = max($remaining - $countResults, 0);\n            }\n\n            if ($callback($results, $page) === false) {\n                return false;\n            }\n\n            unset($results);\n\n            $page++;\n        } while ($countResults == $count);\n\n        return true;\n    }\n\n    /**\n     * Run a map over each item while chunking.\n     *\n     * @template TReturn\n     *\n     * @param  callable(TValue): TReturn  $callback\n     * @param  int  $count\n     * @return \\Illuminate\\Support\\Collection<int, TReturn>\n     */\n    public function chunkMap(callable $callback, $count = 1000)\n    {\n        $collection = new Collection;\n\n        $this->chunk($count, function ($items) use ($collection, $callback) {\n            $items->each(function ($item) use ($collection, $callback) {\n                $collection->push($callback($item));\n            });\n        });\n\n        return $collection;\n    }\n\n    /**\n     * Execute a callback over each item while chunking.\n     *\n     * @param  callable(TValue, int): mixed  $callback\n     * @param  int  $count\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function each(callable $callback, $count = 1000)\n    {\n        return $this->chunk($count, function ($results) use ($callback) {\n            foreach ($results as $key => $value) {\n                if ($callback($value, $key) === false) {\n                    return false;\n                }\n            }\n        });\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs.\n     *\n     * @param  int  $count\n     * @param  callable(\\Illuminate\\Support\\Collection<int, TValue>, int): mixed  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkById($count, callable $callback, $column = null, $alias = null)\n    {\n        return $this->orderedChunkById($count, $callback, $column, $alias);\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $count\n     * @param  callable(\\Illuminate\\Support\\Collection<int, TValue>, int): mixed  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n    {\n        return $this->orderedChunkById($count, $callback, $column, $alias, descending: true);\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs in a given order.\n     *\n     * @param  int  $count\n     * @param  callable(\\Illuminate\\Support\\Collection<int, TValue>, int): mixed  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @param  bool  $descending\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function orderedChunkById($count, callable $callback, $column = null, $alias = null, $descending = false)\n    {\n        $column ??= $this->defaultKeyName();\n        $alias ??= $column;\n        $lastId = null;\n        $skip = $this->getOffset();\n        $remaining = $this->getLimit();\n\n        $page = 1;\n\n        do {\n            $clone = clone $this;\n\n            if ($skip && $page > 1) {\n                $clone->offset(0);\n            }\n\n            $limit = is_null($remaining) ? $count : min($count, $remaining);\n\n            if ($limit == 0) {\n                break;\n            }\n\n            // We'll execute the query for the given page and get the results. If there are\n            // no results we can just break and return from here. When there are results\n            // we will call the callback with the current chunk of these results here.\n            if ($descending) {\n                $results = $clone->forPageBeforeId($limit, $lastId, $column)->get();\n            } else {\n                $results = $clone->forPageAfterId($limit, $lastId, $column)->get();\n            }\n\n            $countResults = $results->count();\n\n            if ($countResults == 0) {\n                break;\n            }\n\n            if (! is_null($remaining)) {\n                $remaining = max($remaining - $countResults, 0);\n            }\n\n            // On each chunk result set, we will pass them to the callback and then let the\n            // developer take care of everything within the callback, which allows us to\n            // keep the memory low for spinning through large result sets for working.\n            if ($callback($results, $page) === false) {\n                return false;\n            }\n\n            $lastId = data_get($results->last(), $alias);\n\n            if ($lastId === null) {\n                throw new RuntimeException(\"The chunkById operation was aborted because the [{$alias}] column is not present in the query result.\");\n            }\n\n            unset($results);\n\n            $page++;\n        } while ($countResults == $count);\n\n        return true;\n    }\n\n    /**\n     * Execute a callback over each item while chunking by ID.\n     *\n     * @param  callable(TValue, int): mixed  $callback\n     * @param  int  $count\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function eachById(callable $callback, $count = 1000, $column = null, $alias = null)\n    {\n        return $this->chunkById($count, function ($results, $page) use ($callback, $count) {\n            foreach ($results as $key => $value) {\n                if ($callback($value, (($page - 1) * $count) + $key) === false) {\n                    return false;\n                }\n            }\n        }, $column, $alias);\n    }\n\n    /**\n     * Query lazily, by chunks of the given size.\n     *\n     * @param  int  $chunkSize\n     * @return \\Illuminate\\Support\\LazyCollection<int, TValue>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function lazy($chunkSize = 1000)\n    {\n        if ($chunkSize < 1) {\n            throw new InvalidArgumentException('The chunk size should be at least 1');\n        }\n\n        $this->enforceOrderBy();\n\n        return new LazyCollection(function () use ($chunkSize) {\n            $page = 1;\n\n            while (true) {\n                $results = $this->forPage($page++, $chunkSize)->get();\n\n                foreach ($results as $result) {\n                    yield $result;\n                }\n\n                if ($results->count() < $chunkSize) {\n                    return;\n                }\n            }\n        });\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TValue>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function lazyById($chunkSize = 1000, $column = null, $alias = null)\n    {\n        return $this->orderedLazyById($chunkSize, $column, $alias);\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TValue>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null)\n    {\n        return $this->orderedLazyById($chunkSize, $column, $alias, true);\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs in a given order.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @param  bool  $descending\n     * @return \\Illuminate\\Support\\LazyCollection\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\RuntimeException\n     */\n    protected function orderedLazyById($chunkSize = 1000, $column = null, $alias = null, $descending = false)\n    {\n        if ($chunkSize < 1) {\n            throw new InvalidArgumentException('The chunk size should be at least 1');\n        }\n\n        $column ??= $this->defaultKeyName();\n\n        $alias ??= $column;\n\n        return new LazyCollection(function () use ($chunkSize, $column, $alias, $descending) {\n            $lastId = null;\n\n            while (true) {\n                $clone = clone $this;\n\n                if ($descending) {\n                    $results = $clone->forPageBeforeId($chunkSize, $lastId, $column)->get();\n                } else {\n                    $results = $clone->forPageAfterId($chunkSize, $lastId, $column)->get();\n                }\n\n                foreach ($results as $result) {\n                    yield $result;\n                }\n\n                if ($results->count() < $chunkSize) {\n                    return;\n                }\n\n                $lastId = $results->last()->{$alias};\n\n                if ($lastId === null) {\n                    throw new RuntimeException(\"The lazyById operation was aborted because the [{$alias}] column is not present in the query result.\");\n                }\n            }\n        });\n    }\n\n    /**\n     * Execute the query and get the first result.\n     *\n     * @param  array|string  $columns\n     * @return TValue|null\n     */\n    public function first($columns = ['*'])\n    {\n        return $this->limit(1)->get($columns)->first();\n    }\n\n    /**\n     * Execute the query and get the first result or throw an exception.\n     *\n     * @param  array|string  $columns\n     * @param  string|null  $message\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Database\\RecordNotFoundException\n     */\n    public function firstOrFail($columns = ['*'], $message = null)\n    {\n        if (! is_null($result = $this->first($columns))) {\n            return $result;\n        }\n\n        throw new RecordNotFoundException($message ?: 'No record found for the given query.');\n    }\n\n    /**\n     * Execute the query and get the first result if it's the sole matching record.\n     *\n     * @param  array|string  $columns\n     * @return TValue\n     *\n     * @throws \\Illuminate\\Database\\RecordsNotFoundException\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function sole($columns = ['*'])\n    {\n        $result = $this->limit(2)->get($columns);\n\n        $count = $result->count();\n\n        if ($count === 0) {\n            throw new RecordsNotFoundException;\n        }\n\n        if ($count > 1) {\n            throw new MultipleRecordsFoundException($count);\n        }\n\n        return $result->first();\n    }\n\n    /**\n     * Paginate the given query using a cursor paginator.\n     *\n     * @param  int  $perPage\n     * @param  array|string  $columns\n     * @param  string  $cursorName\n     * @param  \\Illuminate\\Pagination\\Cursor|string|null  $cursor\n     * @return \\Illuminate\\Contracts\\Pagination\\CursorPaginator\n     */\n    protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = 'cursor', $cursor = null)\n    {\n        if (! $cursor instanceof Cursor) {\n            $cursor = is_string($cursor)\n                ? Cursor::fromEncoded($cursor)\n                : CursorPaginator::resolveCurrentCursor($cursorName, $cursor);\n        }\n\n        $orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems());\n\n        if (! is_null($cursor)) {\n            // Reset the union bindings so we can add the cursor where in the correct position...\n            $this->setBindings([], 'union');\n\n            $addCursorConditions = function (self $builder, $previousColumn, $originalColumn, $i) use (&$addCursorConditions, $cursor, $orders) {\n                $unionBuilders = $builder->getUnionBuilders();\n\n                if (! is_null($previousColumn)) {\n                    $originalColumn ??= $this->getOriginalColumnNameForCursorPagination($this, $previousColumn);\n\n                    $builder->where(\n                        Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn,\n                        '=',\n                        $cursor->parameter($previousColumn)\n                    );\n\n                    $unionBuilders->each(function ($unionBuilder) use ($previousColumn, $cursor) {\n                        $unionBuilder->where(\n                            $this->getOriginalColumnNameForCursorPagination($unionBuilder, $previousColumn),\n                            '=',\n                            $cursor->parameter($previousColumn)\n                        );\n\n                        $this->addBinding($unionBuilder->getRawBindings()['where'], 'union');\n                    });\n                }\n\n                $builder->where(function (self $secondBuilder) use ($addCursorConditions, $cursor, $orders, $i, $unionBuilders) {\n                    ['column' => $column, 'direction' => $direction] = $orders[$i];\n\n                    $originalColumn = $this->getOriginalColumnNameForCursorPagination($this, $column);\n\n                    $secondBuilder->where(\n                        Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn,\n                        $direction === 'asc' ? '>' : '<',\n                        $cursor->parameter($column)\n                    );\n\n                    if ($i < $orders->count() - 1) {\n                        $secondBuilder->orWhere(function (self $thirdBuilder) use ($addCursorConditions, $column, $originalColumn, $i) {\n                            $addCursorConditions($thirdBuilder, $column, $originalColumn, $i + 1);\n                        });\n                    }\n\n                    $unionBuilders->each(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions) {\n                        $unionWheres = $unionBuilder->getRawBindings()['where'];\n\n                        $originalColumn = $this->getOriginalColumnNameForCursorPagination($unionBuilder, $column);\n                        $unionBuilder->where(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions, $originalColumn, $unionWheres) {\n                            $unionBuilder->where(\n                                $originalColumn,\n                                $direction === 'asc' ? '>' : '<',\n                                $cursor->parameter($column)\n                            );\n\n                            if ($i < $orders->count() - 1) {\n                                $unionBuilder->orWhere(function (self $fourthBuilder) use ($addCursorConditions, $column, $originalColumn, $i) {\n                                    $addCursorConditions($fourthBuilder, $column, $originalColumn, $i + 1);\n                                });\n                            }\n\n                            $this->addBinding($unionWheres, 'union');\n                            $this->addBinding($unionBuilder->getRawBindings()['where'], 'union');\n                        });\n                    });\n                });\n            };\n\n            $addCursorConditions($this, null, null, 0);\n        }\n\n        $this->limit($perPage + 1);\n\n        return $this->cursorPaginator($this->get($columns), $perPage, $cursor, [\n            'path' => Paginator::resolveCurrentPath(),\n            'cursorName' => $cursorName,\n            'parameters' => $orders->pluck('column')->toArray(),\n        ]);\n    }\n\n    /**\n     * Get the original column name of the given column, without any aliasing.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @param  string  $parameter\n     * @return string\n     */\n    protected function getOriginalColumnNameForCursorPagination($builder, string $parameter)\n    {\n        $columns = $builder instanceof Builder ? $builder->getQuery()->getColumns() : $builder->getColumns();\n\n        if (! is_null($columns)) {\n            foreach ($columns as $column) {\n                if (($position = strripos($column, ' as ')) !== false) {\n                    $original = substr($column, 0, $position);\n\n                    $alias = substr($column, $position + 4);\n\n                    if ($parameter === $alias || $builder->getGrammar()->wrap($parameter) === $alias) {\n                        return $original;\n                    }\n                }\n            }\n        }\n\n        return $parameter;\n    }\n\n    /**\n     * Create a new length-aware paginator instance.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $items\n     * @param  int  $total\n     * @param  int  $perPage\n     * @param  int  $currentPage\n     * @param  array  $options\n     * @return \\Illuminate\\Pagination\\LengthAwarePaginator\n     */\n    protected function paginator($items, $total, $perPage, $currentPage, $options)\n    {\n        return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(\n            'items', 'total', 'perPage', 'currentPage', 'options'\n        ));\n    }\n\n    /**\n     * Create a new simple paginator instance.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $items\n     * @param  int  $perPage\n     * @param  int  $currentPage\n     * @param  array  $options\n     * @return \\Illuminate\\Pagination\\Paginator\n     */\n    protected function simplePaginator($items, $perPage, $currentPage, $options)\n    {\n        return Container::getInstance()->makeWith(Paginator::class, compact(\n            'items', 'perPage', 'currentPage', 'options'\n        ));\n    }\n\n    /**\n     * Create a new cursor paginator instance.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $items\n     * @param  int  $perPage\n     * @param  \\Illuminate\\Pagination\\Cursor  $cursor\n     * @param  array  $options\n     * @return \\Illuminate\\Pagination\\CursorPaginator\n     */\n    protected function cursorPaginator($items, $perPage, $cursor, $options)\n    {\n        return Container::getInstance()->makeWith(CursorPaginator::class, compact(\n            'items', 'perPage', 'cursor', 'options'\n        ));\n    }\n\n    /**\n     * Pass the query to a given callback and then return it.\n     *\n     * @param  callable($this): mixed  $callback\n     * @return $this\n     */\n    public function tap($callback)\n    {\n        $callback($this);\n\n        return $this;\n    }\n\n    /**\n     * Pass the query to a given callback and return the result.\n     *\n     * @template TReturn\n     *\n     * @param  (callable($this): TReturn)  $callback\n     * @return (TReturn is null|void ? $this : TReturn)\n     */\n    public function pipe($callback)\n    {\n        return $callback($this) ?? $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/BuildsWhereDateClauses.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\n\ntrait BuildsWhereDateClauses\n{\n    /**\n     * Add a where clause to determine if a \"date\" column is in the past to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function wherePast($columns)\n    {\n        return $this->wherePastOrFuture($columns, '<', 'and');\n    }\n\n    /**\n     * Add a where clause to determine if a \"date\" column is in the past or now to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereNowOrPast($columns)\n    {\n        return $this->wherePastOrFuture($columns, '<=', 'and');\n    }\n\n    /**\n     * Add an \"or where\" clause to determine if a \"date\" column is in the past to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWherePast($columns)\n    {\n        return $this->wherePastOrFuture($columns, '<', 'or');\n    }\n\n    /**\n     * Add a where clause to determine if a \"date\" column is in the past or now to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereNowOrPast($columns)\n    {\n        return $this->wherePastOrFuture($columns, '<=', 'or');\n    }\n\n    /**\n     * Add a where clause to determine if a \"date\" column is in the future to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereFuture($columns)\n    {\n        return $this->wherePastOrFuture($columns, '>', 'and');\n    }\n\n    /**\n     * Add a where clause to determine if a \"date\" column is in the future or now to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereNowOrFuture($columns)\n    {\n        return $this->wherePastOrFuture($columns, '>=', 'and');\n    }\n\n    /**\n     * Add an \"or where\" clause to determine if a \"date\" column is in the future to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereFuture($columns)\n    {\n        return $this->wherePastOrFuture($columns, '>', 'or');\n    }\n\n    /**\n     * Add an \"or where\" clause to determine if a \"date\" column is in the future or now to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereNowOrFuture($columns)\n    {\n        return $this->wherePastOrFuture($columns, '>=', 'or');\n    }\n\n    /**\n     * Add an \"where\" clause to determine if a \"date\" column is in the past or future.\n     *\n     * @param  array|string  $columns\n     * @param  string  $operator\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function wherePastOrFuture($columns, $operator, $boolean)\n    {\n        $type = 'Basic';\n        $value = Carbon::now();\n\n        foreach (Arr::wrap($columns) as $column) {\n            $this->wheres[] = compact('type', 'column', 'boolean', 'operator', 'value');\n\n            $this->addBinding($value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is today to the query.\n     *\n     * @param  array|string  $columns\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereToday($columns, $boolean = 'and')\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '=', $boolean);\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is before today.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereBeforeToday($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '<', 'and');\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is today or before to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereTodayOrBefore($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '<=', 'and');\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is after today.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereAfterToday($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '>', 'and');\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is today or after to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function whereTodayOrAfter($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '>=', 'and');\n    }\n\n    /**\n     * Add an \"or where date\" clause to determine if a \"date\" column is today to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereToday($columns)\n    {\n        return $this->whereToday($columns, 'or');\n    }\n\n    /**\n     * Add an \"or where date\" clause to determine if a \"date\" column is before today.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereBeforeToday($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '<', 'or');\n    }\n\n    /**\n     * Add an \"or where date\" clause to determine if a \"date\" column is today or before to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereTodayOrBefore($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '<=', 'or');\n    }\n\n    /**\n     * Add an \"or where date\" clause to determine if a \"date\" column is after today.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereAfterToday($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '>', 'or');\n    }\n\n    /**\n     * Add an \"or where date\" clause to determine if a \"date\" column is today or after to the query.\n     *\n     * @param  array|string  $columns\n     * @return $this\n     */\n    public function orWhereTodayOrAfter($columns)\n    {\n        return $this->whereTodayBeforeOrAfter($columns, '>=', 'or');\n    }\n\n    /**\n     * Add a \"where date\" clause to determine if a \"date\" column is today or after to the query.\n     *\n     * @param  array|string  $columns\n     * @param  string  $operator\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function whereTodayBeforeOrAfter($columns, $operator, $boolean)\n    {\n        $value = Carbon::today()->format('Y-m-d');\n\n        foreach (Arr::wrap($columns) as $column) {\n            $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/CompilesJsonPaths.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\n\ntrait CompilesJsonPaths\n{\n    /**\n     * Split the given JSON selector into the field and the optional path and wrap them separately.\n     *\n     * @param  string  $column\n     * @return array\n     */\n    protected function wrapJsonFieldAndPath($column)\n    {\n        $parts = explode('->', $column, 2);\n\n        $field = $this->wrap($parts[0]);\n\n        $path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1], '->') : '';\n\n        return [$field, $path];\n    }\n\n    /**\n     * Wrap the given JSON path.\n     *\n     * @param  string  $value\n     * @param  string  $delimiter\n     * @return string\n     */\n    protected function wrapJsonPath($value, $delimiter = '->')\n    {\n        $value = preg_replace(\"/([\\\\\\\\]+)?\\\\'/\", \"''\", $value);\n\n        $jsonPath = (new Collection(explode($delimiter, $value)))\n            ->map(fn ($segment) => $this->wrapJsonPathSegment($segment))\n            ->join('.');\n\n        return \"'$\".(str_starts_with($jsonPath, '[') ? '' : '.').$jsonPath.\"'\";\n    }\n\n    /**\n     * Wrap the given JSON path segment.\n     *\n     * @param  string  $segment\n     * @return string\n     */\n    protected function wrapJsonPathSegment($segment)\n    {\n        if (preg_match('/(\\[[^\\]]+\\])+$/', $segment, $parts)) {\n            $key = Str::beforeLast($segment, $parts[0]);\n\n            if (! empty($key)) {\n                return '\"'.$key.'\"'.$parts[0];\n            }\n\n            return $parts[0];\n        }\n\n        return '\"'.$segment.'\"';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/ExplainsQueries.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\nuse Illuminate\\Support\\Collection;\n\ntrait ExplainsQueries\n{\n    /**\n     * Explains the query.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function explain()\n    {\n        $sql = $this->toSql();\n\n        $bindings = $this->getBindings();\n\n        $explanation = $this->getConnection()->select('EXPLAIN '.$sql, $bindings);\n\n        return new Collection($explanation);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/ManagesTransactions.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\nuse Closure;\nuse Illuminate\\Database\\DeadlockException;\nuse RuntimeException;\nuse Throwable;\n\n/**\n * @mixin \\Illuminate\\Database\\Connection\n */\ntrait ManagesTransactions\n{\n    /**\n     * @template TReturn of mixed\n     *\n     * Execute a Closure within a transaction.\n     *\n     * @param  (\\Closure(static): TReturn)  $callback\n     * @param  int  $attempts\n     * @return TReturn\n     *\n     * @throws \\Throwable\n     */\n    public function transaction(Closure $callback, $attempts = 1)\n    {\n        for ($currentAttempt = 1; $currentAttempt <= $attempts; $currentAttempt++) {\n            $this->beginTransaction();\n\n            // We'll simply execute the given callback within a try / catch block and if we\n            // catch any exception we can rollback this transaction so that none of this\n            // gets actually persisted to a database or stored in a permanent fashion.\n            try {\n                $callbackResult = $callback($this);\n            }\n\n            // If we catch an exception we'll rollback this transaction and try again if we\n            // are not out of attempts. If we are out of attempts we will just throw the\n            // exception back out, and let the developer handle an uncaught exception.\n            catch (Throwable $e) {\n                $this->handleTransactionException(\n                    $e, $currentAttempt, $attempts\n                );\n\n                continue;\n            }\n\n            $levelBeingCommitted = $this->transactions;\n\n            try {\n                if ($this->transactions == 1) {\n                    $this->fireConnectionEvent('committing');\n                    $this->getPdo()->commit();\n                }\n\n                $this->transactions = max(0, $this->transactions - 1);\n            } catch (Throwable $e) {\n                $this->handleCommitTransactionException(\n                    $e, $currentAttempt, $attempts\n                );\n\n                continue;\n            }\n\n            $this->transactionsManager?->commit(\n                $this->getName(),\n                $levelBeingCommitted,\n                $this->transactions\n            );\n\n            $this->fireConnectionEvent('committed');\n\n            return $callbackResult;\n        }\n    }\n\n    /**\n     * Handle an exception encountered when running a transacted statement.\n     *\n     * @param  \\Throwable  $e\n     * @param  int  $currentAttempt\n     * @param  int  $maxAttempts\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleTransactionException(Throwable $e, $currentAttempt, $maxAttempts)\n    {\n        // On a deadlock, MySQL rolls back the entire transaction so we can't just\n        // retry the query. We have to throw this exception all the way out and\n        // let the developer handle it in another way. We will decrement too.\n        if ($this->causedByConcurrencyError($e) &&\n            $this->transactions > 1) {\n            $this->transactions--;\n\n            $this->transactionsManager?->rollback(\n                $this->getName(), $this->transactions\n            );\n\n            throw new DeadlockException($e->getMessage(), is_int($e->getCode()) ? $e->getCode() : 0, $e);\n        }\n\n        // If there was an exception we will rollback this transaction and then we\n        // can check if we have exceeded the maximum attempt count for this and\n        // if we haven't we will return and try this query again in our loop.\n        $this->rollBack();\n\n        if ($this->causedByConcurrencyError($e) &&\n            $currentAttempt < $maxAttempts) {\n            return;\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Start a new database transaction.\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function beginTransaction()\n    {\n        foreach ($this->beforeStartingTransaction as $callback) {\n            $callback($this);\n        }\n\n        $this->createTransaction();\n\n        $this->transactions++;\n\n        $this->transactionsManager?->begin(\n            $this->getName(), $this->transactions\n        );\n\n        $this->fireConnectionEvent('beganTransaction');\n    }\n\n    /**\n     * Create a transaction within the database.\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function createTransaction()\n    {\n        if ($this->transactions == 0) {\n            $this->reconnectIfMissingConnection();\n\n            try {\n                $this->executeBeginTransactionStatement();\n            } catch (Throwable $e) {\n                $this->handleBeginTransactionException($e);\n            }\n        } elseif ($this->transactions >= 1 && $this->queryGrammar->supportsSavepoints()) {\n            $this->createSavepoint();\n        }\n    }\n\n    /**\n     * Create a save point within the database.\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function createSavepoint()\n    {\n        $this->getPdo()->exec(\n            $this->queryGrammar->compileSavepoint('trans'.($this->transactions + 1))\n        );\n    }\n\n    /**\n     * Handle an exception from a transaction beginning.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleBeginTransactionException(Throwable $e)\n    {\n        if ($this->causedByLostConnection($e)) {\n            $this->reconnect();\n\n            $this->executeBeginTransactionStatement();\n        } else {\n            throw $e;\n        }\n    }\n\n    /**\n     * Commit the active database transaction.\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function commit()\n    {\n        if ($this->transactionLevel() == 1) {\n            $this->fireConnectionEvent('committing');\n            $this->getPdo()->commit();\n        }\n\n        [$levelBeingCommitted, $this->transactions] = [\n            $this->transactions,\n            max(0, $this->transactions - 1),\n        ];\n\n        $this->transactionsManager?->commit(\n            $this->getName(), $levelBeingCommitted, $this->transactions\n        );\n\n        $this->fireConnectionEvent('committed');\n    }\n\n    /**\n     * Handle an exception encountered when committing a transaction.\n     *\n     * @param  \\Throwable  $e\n     * @param  int  $currentAttempt\n     * @param  int  $maxAttempts\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleCommitTransactionException(Throwable $e, $currentAttempt, $maxAttempts)\n    {\n        $this->transactions = max(0, $this->transactions - 1);\n\n        if ($this->causedByConcurrencyError($e) && $currentAttempt < $maxAttempts) {\n            $pdo = $this->getPdo();\n\n            if ($pdo->inTransaction()) {\n                $pdo->rollBack();\n            }\n\n            return;\n        }\n\n        if ($this->causedByLostConnection($e)) {\n            $this->transactions = 0;\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Rollback the active database transaction.\n     *\n     * @param  int|null  $toLevel\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function rollBack($toLevel = null)\n    {\n        // We allow developers to rollback to a certain transaction level. We will verify\n        // that this given transaction level is valid before attempting to rollback to\n        // that level. If it's not we will just return out and not attempt anything.\n        $toLevel = is_null($toLevel)\n            ? $this->transactions - 1\n            : $toLevel;\n\n        if ($toLevel < 0 || $toLevel >= $this->transactions) {\n            return;\n        }\n\n        // Next, we will actually perform this rollback within this database and fire the\n        // rollback event. We will also set the current transaction level to the given\n        // level that was passed into this method so it will be right from here out.\n        try {\n            $this->performRollBack($toLevel);\n        } catch (Throwable $e) {\n            $this->handleRollBackException($e);\n        }\n\n        $this->transactions = $toLevel;\n\n        $this->transactionsManager?->rollback(\n            $this->getName(), $this->transactions\n        );\n\n        $this->fireConnectionEvent('rollingBack');\n    }\n\n    /**\n     * Perform a rollback within the database.\n     *\n     * @param  int  $toLevel\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function performRollBack($toLevel)\n    {\n        if ($toLevel == 0) {\n            $pdo = $this->getPdo();\n\n            if ($pdo->inTransaction()) {\n                $pdo->rollBack();\n            }\n        } elseif ($this->queryGrammar->supportsSavepoints()) {\n            $this->getPdo()->exec(\n                $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1))\n            );\n        }\n    }\n\n    /**\n     * Handle an exception from a rollback.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleRollBackException(Throwable $e)\n    {\n        if ($this->causedByLostConnection($e)) {\n            $this->transactions = 0;\n\n            $this->transactionsManager?->rollback(\n                $this->getName(), $this->transactions\n            );\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Get the number of active transactions.\n     *\n     * @return int\n     */\n    public function transactionLevel()\n    {\n        return $this->transactions;\n    }\n\n    /**\n     * Execute the callback after a transaction commits.\n     *\n     * @param  callable  $callback\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function afterCommit($callback)\n    {\n        if ($this->transactionsManager) {\n            return $this->transactionsManager->addCallback($callback);\n        }\n\n        throw new RuntimeException('Transactions Manager has not been set.');\n    }\n\n    /**\n     * Execute the callback after a transaction rolls back.\n     *\n     * @param  callable  $callback\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function afterRollBack($callback)\n    {\n        if ($this->transactionsManager) {\n            return $this->transactionsManager->addCallbackForRollback($callback);\n        }\n\n        throw new RuntimeException('Transactions Manager has not been set.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Concerns/ParsesSearchPath.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Concerns;\n\ntrait ParsesSearchPath\n{\n    /**\n     * Parse the Postgres \"search_path\" configuration value into an array.\n     *\n     * @param  string|array|null  $searchPath\n     * @return array\n     */\n    protected function parseSearchPath($searchPath)\n    {\n        if (is_string($searchPath)) {\n            preg_match_all('/[^\\s,\"\\']+/', $searchPath, $matches);\n\n            $searchPath = $matches[0];\n        }\n\n        return array_map(function ($schema) {\n            return trim($schema, '\\'\"');\n        }, $searchPath ?? []);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ConcurrencyErrorDetector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Contracts\\Database\\ConcurrencyErrorDetector as ConcurrencyErrorDetectorContract;\nuse Illuminate\\Support\\Str;\nuse PDOException;\nuse Throwable;\n\nclass ConcurrencyErrorDetector implements ConcurrencyErrorDetectorContract\n{\n    /**\n     * Determine if the given exception was caused by a concurrency error such as a deadlock or serialization failure.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function causedByConcurrencyError(Throwable $e): bool\n    {\n        if ($e instanceof PDOException && ($e->getCode() === 40001 || $e->getCode() === '40001')) {\n            return true;\n        }\n\n        $message = $e->getMessage();\n\n        return Str::contains($message, [\n            'Deadlock found when trying to get lock',\n            'deadlock detected',\n            'The database file is locked',\n            'database is locked',\n            'database table is locked',\n            'A table in the database is locked',\n            'has been chosen as the deadlock victim',\n            'Lock wait timeout exceeded; try restarting transaction',\n            'WSREP detected deadlock/conflict and aborted the transaction. Try restarting the transaction',\n            'Record has changed since last read in table',\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ConfigurationUrlParser.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Support\\ConfigurationUrlParser as BaseConfigurationUrlParser;\n\nclass ConfigurationUrlParser extends BaseConfigurationUrlParser\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Carbon\\CarbonInterval;\nuse Closure;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Database\\Events\\StatementPrepared;\nuse Illuminate\\Database\\Events\\TransactionBeginning;\nuse Illuminate\\Database\\Events\\TransactionCommitted;\nuse Illuminate\\Database\\Events\\TransactionCommitting;\nuse Illuminate\\Database\\Events\\TransactionRolledBack;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Database\\Schema\\Builder as SchemaBuilder;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse PDO;\nuse PDOStatement;\nuse RuntimeException;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Connection implements ConnectionInterface\n{\n    use DetectsConcurrencyErrors,\n        DetectsLostConnections,\n        Concerns\\ManagesTransactions,\n        InteractsWithTime,\n        Macroable;\n\n    /**\n     * The active PDO connection.\n     *\n     * @var \\PDO|(\\Closure(): \\PDO)\n     */\n    protected $pdo;\n\n    /**\n     * The active PDO connection used for reads.\n     *\n     * @var \\PDO|(\\Closure(): \\PDO)\n     */\n    protected $readPdo;\n\n    /**\n     * The database connection configuration options for reading.\n     *\n     * @var array\n     */\n    protected $readPdoConfig = [];\n\n    /**\n     * The name of the connected database.\n     *\n     * @var string\n     */\n    protected $database;\n\n    /**\n     * The type of the connection.\n     *\n     * @var string|null\n     */\n    protected $readWriteType;\n\n    /**\n     * The table prefix for the connection.\n     *\n     * @var string\n     */\n    protected $tablePrefix = '';\n\n    /**\n     * The database connection configuration options.\n     *\n     * @var array\n     */\n    protected $config = [];\n\n    /**\n     * The reconnector instance for the connection.\n     *\n     * @var (callable(\\Illuminate\\Database\\Connection): mixed)\n     */\n    protected $reconnector;\n\n    /**\n     * The query grammar implementation.\n     *\n     * @var \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    protected $queryGrammar;\n\n    /**\n     * The schema grammar implementation.\n     *\n     * @var \\Illuminate\\Database\\Schema\\Grammars\\Grammar\n     */\n    protected $schemaGrammar;\n\n    /**\n     * The query post processor implementation.\n     *\n     * @var \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    protected $postProcessor;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $events;\n\n    /**\n     * The default fetch mode of the connection.\n     *\n     * @var int\n     */\n    protected $fetchMode = PDO::FETCH_OBJ;\n\n    /**\n     * The number of active transactions.\n     *\n     * @var int\n     */\n    protected $transactions = 0;\n\n    /**\n     * The transaction manager instance.\n     *\n     * @var \\Illuminate\\Database\\DatabaseTransactionsManager|null\n     */\n    protected $transactionsManager;\n\n    /**\n     * Indicates if changes have been made to the database.\n     *\n     * @var bool\n     */\n    protected $recordsModified = false;\n\n    /**\n     * Indicates if the connection should use the \"write\" PDO connection.\n     *\n     * @var bool\n     */\n    protected $readOnWriteConnection = false;\n\n    /**\n     * All of the queries run against the connection.\n     *\n     * @var array{query: string, bindings: array, time: float|null}[]\n     */\n    protected $queryLog = [];\n\n    /**\n     * Indicates whether queries are being logged.\n     *\n     * @var bool\n     */\n    protected $loggingQueries = false;\n\n    /**\n     * The duration of all executed queries in milliseconds.\n     *\n     * @var float\n     */\n    protected $totalQueryDuration = 0.0;\n\n    /**\n     * All of the registered query duration handlers.\n     *\n     * @var array{has_run: bool, handler: (callable(\\Illuminate\\Database\\Connection, class-string<\\Illuminate\\Database\\Events\\QueryExecuted>): mixed)}[]\n     */\n    protected $queryDurationHandlers = [];\n\n    /**\n     * Indicates if the connection is in a \"dry run\".\n     *\n     * @var bool\n     */\n    protected $pretending = false;\n\n    /**\n     * All of the callbacks that should be invoked before a transaction is started.\n     *\n     * @var \\Closure[]\n     */\n    protected $beforeStartingTransaction = [];\n\n    /**\n     * All of the callbacks that should be invoked before a query is executed.\n     *\n     * @var (\\Closure(string, array, \\Illuminate\\Database\\Connection): mixed)[]\n     */\n    protected $beforeExecutingCallbacks = [];\n\n    /**\n     * The connection resolvers.\n     *\n     * @var \\Closure[]\n     */\n    protected static $resolvers = [];\n\n    /**\n     * The last retrieved PDO read / write type.\n     *\n     * @var null|'read'|'write'\n     */\n    protected $latestPdoTypeRetrieved = null;\n\n    /**\n     * Create a new database connection instance.\n     *\n     * @param  \\PDO|(\\Closure(): \\PDO)  $pdo\n     * @param  string  $database\n     * @param  string  $tablePrefix\n     * @param  array  $config\n     */\n    public function __construct($pdo, $database = '', $tablePrefix = '', array $config = [])\n    {\n        $this->pdo = $pdo;\n\n        // First we will setup the default properties. We keep track of the DB\n        // name we are connected to since it is needed when some reflective\n        // type commands are run such as checking whether a table exists.\n        $this->database = $database;\n\n        $this->tablePrefix = $tablePrefix;\n\n        $this->config = $config;\n\n        // We need to initialize a query grammar and the query post processors\n        // which are both very important parts of the database abstractions\n        // so we initialize these to their default values while starting.\n        $this->useDefaultQueryGrammar();\n\n        $this->useDefaultPostProcessor();\n    }\n\n    /**\n     * Set the query grammar to the default implementation.\n     *\n     * @return void\n     */\n    public function useDefaultQueryGrammar()\n    {\n        $this->queryGrammar = $this->getDefaultQueryGrammar();\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Set the schema grammar to the default implementation.\n     *\n     * @return void\n     */\n    public function useDefaultSchemaGrammar()\n    {\n        $this->schemaGrammar = $this->getDefaultSchemaGrammar();\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\Grammar|null\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        //\n    }\n\n    /**\n     * Set the query post processor to the default implementation.\n     *\n     * @return void\n     */\n    public function useDefaultPostProcessor()\n    {\n        $this->postProcessor = $this->getDefaultPostProcessor();\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new Processor;\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new SchemaBuilder($this);\n    }\n\n    /**\n     * Begin a fluent query against a database table.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|\\UnitEnum|string  $table\n     * @param  string|null  $as\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function table($table, $as = null)\n    {\n        return $this->query()->from(enum_value($table), $as);\n    }\n\n    /**\n     * Get a new query builder instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function query()\n    {\n        return new QueryBuilder(\n            $this, $this->getQueryGrammar(), $this->getPostProcessor()\n        );\n    }\n\n    /**\n     * Run a select statement and return a single result.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @return mixed\n     */\n    public function selectOne($query, $bindings = [], $useReadPdo = true)\n    {\n        $records = $this->select($query, $bindings, $useReadPdo);\n\n        return array_shift($records);\n    }\n\n    /**\n     * Run a select statement and return the first column of the first row.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\MultipleColumnsSelectedException\n     */\n    public function scalar($query, $bindings = [], $useReadPdo = true)\n    {\n        $record = $this->selectOne($query, $bindings, $useReadPdo);\n\n        if (is_null($record)) {\n            return null;\n        }\n\n        $record = (array) $record;\n\n        if (count($record) > 1) {\n            throw new MultipleColumnsSelectedException;\n        }\n\n        return array_first($record);\n    }\n\n    /**\n     * Run a select statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return array\n     */\n    public function selectFromWriteConnection($query, $bindings = [])\n    {\n        return $this->select($query, $bindings, false);\n    }\n\n    /**\n     * Run a select statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @param  array  $fetchUsing\n     * @return array\n     */\n    public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = [])\n    {\n        return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) {\n            if ($this->pretending()) {\n                return [];\n            }\n\n            // For select statements, we'll simply execute the query and return an array\n            // of the database result set. Each element in the array will be a single\n            // row from the database table, and will either be an array or objects.\n            $statement = $this->prepared(\n                $this->getPdoForSelect($useReadPdo)->prepare($query)\n            );\n\n            $this->bindValues($statement, $this->prepareBindings($bindings));\n\n            $statement->execute();\n\n            return $statement->fetchAll(...$fetchUsing);\n        });\n    }\n\n    /**\n     * Run a select statement against the database and returns all of the result sets.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @param  array  $fetchUsing\n     * @return array\n     */\n    public function selectResultSets($query, $bindings = [], $useReadPdo = true, array $fetchUsing = [])\n    {\n        return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo, $fetchUsing) {\n            if ($this->pretending()) {\n                return [];\n            }\n\n            $statement = $this->prepared(\n                $this->getPdoForSelect($useReadPdo)->prepare($query)\n            );\n\n            $this->bindValues($statement, $this->prepareBindings($bindings));\n\n            $statement->execute();\n\n            $sets = [];\n\n            do {\n                $sets[] = $statement->fetchAll(...$fetchUsing);\n            } while ($statement->nextRowset());\n\n            return $sets;\n        });\n    }\n\n    /**\n     * Run a select statement against the database and returns a generator.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @param  array  $fetchUsing\n     * @return \\Generator<int, \\stdClass>\n     */\n    public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = [])\n    {\n        $statement = $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) {\n            if ($this->pretending()) {\n                return [];\n            }\n\n            // First we will create a statement for the query. Then, we will set the fetch\n            // mode and prepare the bindings for the query. Once that's done we will be\n            // ready to execute the query against the database and return the cursor.\n            $statement = $this->prepared($this->getPdoForSelect($useReadPdo)\n                ->prepare($query));\n\n            $this->bindValues(\n                $statement, $this->prepareBindings($bindings)\n            );\n\n            // Next, we'll execute the query against the database and return the statement\n            // so we can return the cursor. The cursor will use a PHP generator to give\n            // back one row at a time without using a bunch of memory to render them.\n            $statement->execute();\n\n            return $statement;\n        });\n\n        while ($record = $statement->fetch(...$fetchUsing)) {\n            yield $record;\n        }\n    }\n\n    /**\n     * Configure the PDO prepared statement.\n     *\n     * @param  \\PDOStatement  $statement\n     * @return \\PDOStatement\n     */\n    protected function prepared(PDOStatement $statement)\n    {\n        $statement->setFetchMode($this->fetchMode);\n\n        $this->event(new StatementPrepared($this, $statement));\n\n        return $statement;\n    }\n\n    /**\n     * Get the PDO connection to use for a select query.\n     *\n     * @param  bool  $useReadPdo\n     * @return \\PDO\n     */\n    protected function getPdoForSelect($useReadPdo = true)\n    {\n        return $useReadPdo ? $this->getReadPdo() : $this->getPdo();\n    }\n\n    /**\n     * Run an insert statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return bool\n     */\n    public function insert($query, $bindings = [])\n    {\n        return $this->statement($query, $bindings);\n    }\n\n    /**\n     * Run an update statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function update($query, $bindings = [])\n    {\n        return $this->affectingStatement($query, $bindings);\n    }\n\n    /**\n     * Run a delete statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function delete($query, $bindings = [])\n    {\n        return $this->affectingStatement($query, $bindings);\n    }\n\n    /**\n     * Execute an SQL statement and return the boolean result.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return bool\n     */\n    public function statement($query, $bindings = [])\n    {\n        return $this->run($query, $bindings, function ($query, $bindings) {\n            if ($this->pretending()) {\n                return true;\n            }\n\n            $statement = $this->getPdo()->prepare($query);\n\n            $this->bindValues($statement, $this->prepareBindings($bindings));\n\n            $this->recordsHaveBeenModified();\n\n            return $statement->execute();\n        });\n    }\n\n    /**\n     * Run an SQL statement and get the number of rows affected.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function affectingStatement($query, $bindings = [])\n    {\n        return $this->run($query, $bindings, function ($query, $bindings) {\n            if ($this->pretending()) {\n                return 0;\n            }\n\n            // For update or delete statements, we want to get the number of rows affected\n            // by the statement and return that back to the developer. We'll first need\n            // to execute the statement and then we'll use PDO to fetch the affected.\n            $statement = $this->getPdo()->prepare($query);\n\n            $this->bindValues($statement, $this->prepareBindings($bindings));\n\n            $statement->execute();\n\n            $this->recordsHaveBeenModified(\n                ($count = $statement->rowCount()) > 0\n            );\n\n            return $count;\n        });\n    }\n\n    /**\n     * Run a raw, unprepared query against the PDO connection.\n     *\n     * @param  literal-string  $query\n     * @return bool\n     */\n    public function unprepared($query)\n    {\n        return $this->run($query, [], function ($query) {\n            if ($this->pretending()) {\n                return true;\n            }\n\n            $this->recordsHaveBeenModified(\n                $change = $this->getPdo()->exec($query) !== false\n            );\n\n            return $change;\n        });\n    }\n\n    /**\n     * Get the number of open connections for the database.\n     *\n     * @return int|null\n     */\n    public function threadCount()\n    {\n        $query = $this->getQueryGrammar()->compileThreadCount();\n\n        return $query ? $this->scalar($query) : null;\n    }\n\n    /**\n     * Execute the given callback in \"dry run\" mode.\n     *\n     * @param  (\\Closure(\\Illuminate\\Database\\Connection): mixed)  $callback\n     * @return array{query: string, bindings: array, time: float|null}[]\n     */\n    public function pretend(Closure $callback)\n    {\n        return $this->withFreshQueryLog(function () use ($callback) {\n            $this->pretending = true;\n\n            try {\n                // Basically to make the database connection \"pretend\", we will just return\n                // the default values for all the query methods, then we will return an\n                // array of queries that were \"executed\" within the Closure callback.\n                $callback($this);\n\n                return $this->queryLog;\n            } finally {\n                $this->pretending = false;\n            }\n        });\n    }\n\n    /**\n     * Execute the given callback without \"pretending\".\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function withoutPretending(Closure $callback)\n    {\n        if (! $this->pretending) {\n            return $callback();\n        }\n\n        $this->pretending = false;\n\n        try {\n            return $callback();\n        } finally {\n            $this->pretending = true;\n        }\n    }\n\n    /**\n     * Execute the given callback in \"dry run\" mode.\n     *\n     * @param  (\\Closure(): array{query: string, bindings: array, time: float|null}[])  $callback\n     * @return array{query: string, bindings: array, time: float|null}[]\n     */\n    protected function withFreshQueryLog($callback)\n    {\n        $loggingQueries = $this->loggingQueries;\n\n        // First we will back up the value of the logging queries property and then\n        // we'll be ready to run callbacks. This query log will also get cleared\n        // so we will have a new log of all the queries that are executed now.\n        $this->enableQueryLog();\n\n        $this->queryLog = [];\n\n        // Now we'll execute this callback and capture the result. Once it has been\n        // executed we will restore the value of query logging and give back the\n        // value of the callback so the original callers can have the results.\n        $result = $callback();\n\n        $this->loggingQueries = $loggingQueries;\n\n        return $result;\n    }\n\n    /**\n     * Bind values to their parameters in the given statement.\n     *\n     * @param  \\PDOStatement  $statement\n     * @param  array  $bindings\n     * @return void\n     */\n    public function bindValues($statement, $bindings)\n    {\n        foreach ($bindings as $key => $value) {\n            $statement->bindValue(\n                is_string($key) ? $key : $key + 1,\n                $value,\n                match (true) {\n                    is_int($value) => PDO::PARAM_INT,\n                    is_resource($value) => PDO::PARAM_LOB,\n                    default => PDO::PARAM_STR\n                },\n            );\n        }\n    }\n\n    /**\n     * Prepare the query bindings for execution.\n     *\n     * @param  array  $bindings\n     * @return array\n     */\n    public function prepareBindings(array $bindings)\n    {\n        $grammar = $this->getQueryGrammar();\n\n        foreach ($bindings as $key => $value) {\n            // We need to transform all instances of DateTimeInterface into the actual\n            // date string. Each query grammar maintains its own date string format\n            // so we'll just ask the grammar for the format to get from the date.\n            if ($value instanceof DateTimeInterface) {\n                $bindings[$key] = $value->format($grammar->getDateFormat());\n            } elseif (is_bool($value)) {\n                $bindings[$key] = (int) $value;\n            }\n        }\n\n        return $bindings;\n    }\n\n    /**\n     * Run a SQL statement and log its execution context.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  \\Closure  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\QueryException\n     */\n    protected function run($query, $bindings, Closure $callback)\n    {\n        foreach ($this->beforeExecutingCallbacks as $beforeExecutingCallback) {\n            $beforeExecutingCallback($query, $bindings, $this);\n        }\n\n        $this->reconnectIfMissingConnection();\n\n        $start = microtime(true);\n\n        // Here we will run this query. If an exception occurs we'll determine if it was\n        // caused by a connection that has been lost. If that is the cause, we'll try\n        // to re-establish connection and re-run the query with a fresh connection.\n        try {\n            $result = $this->runQueryCallback($query, $bindings, $callback);\n        } catch (QueryException $e) {\n            $result = $this->handleQueryException(\n                $e, $query, $bindings, $callback\n            );\n        }\n\n        // Once we have run the query we will calculate the time that it took to run and\n        // then log the query, bindings, and execution time so we will report them on\n        // the event that the developer needs them. We'll log time in milliseconds.\n        $this->logQuery(\n            $query, $bindings, $this->getElapsedTime($start)\n        );\n\n        return $result;\n    }\n\n    /**\n     * Run a SQL statement.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  \\Closure  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\QueryException\n     */\n    protected function runQueryCallback($query, $bindings, Closure $callback)\n    {\n        // To execute the statement, we'll simply call the callback, which will actually\n        // run the SQL against the PDO connection. Then we can calculate the time it\n        // took to execute and log the query SQL, bindings and time in our memory.\n        try {\n            return $callback($query, $bindings);\n        }\n\n        // If an exception occurs when attempting to run a query, we'll format the error\n        // message to include the bindings with SQL, which will make this exception a\n        // lot more helpful to the developer instead of just the database's errors.\n        catch (Exception $e) {\n            $exceptionType = $this->isUniqueConstraintError($e)\n                ? UniqueConstraintViolationException::class\n                : QueryException::class;\n\n            throw new $exceptionType(\n                $this->getNameWithReadWriteType(),\n                $query,\n                $this->prepareBindings($bindings),\n                $e,\n                $this->getConnectionDetails(),\n                $this->latestReadWriteTypeUsed(),\n            );\n        }\n    }\n\n    /**\n     * Determine if the given database exception was caused by a unique constraint violation.\n     *\n     * @param  \\Exception  $exception\n     * @return bool\n     */\n    protected function isUniqueConstraintError(Exception $exception)\n    {\n        return false;\n    }\n\n    /**\n     * Log a query in the connection's query log.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  float|null  $time\n     * @return void\n     */\n    public function logQuery($query, $bindings, $time = null)\n    {\n        $this->totalQueryDuration += $time ?? 0.0;\n\n        $readWriteType = $this->latestReadWriteTypeUsed();\n\n        $this->event(new QueryExecuted($query, $bindings, $time, $this, $readWriteType));\n\n        $query = $this->pretending === true\n            ? $this->queryGrammar?->substituteBindingsIntoRawSql($query, $bindings) ?? $query\n            : $query;\n\n        if ($this->loggingQueries) {\n            $this->queryLog[] = compact('query', 'bindings', 'time', 'readWriteType');\n        }\n    }\n\n    /**\n     * Get the elapsed time in milliseconds since a given starting point.\n     *\n     * @param  float  $start\n     * @return float\n     */\n    protected function getElapsedTime($start)\n    {\n        return round((microtime(true) - $start) * 1000, 2);\n    }\n\n    /**\n     * Register a callback to be invoked when the connection queries for longer than a given amount of time.\n     *\n     * @param  \\DateTimeInterface|\\Carbon\\CarbonInterval|float|int  $threshold\n     * @param  (callable(\\Illuminate\\Database\\Connection, \\Illuminate\\Database\\Events\\QueryExecuted): mixed)  $handler\n     * @return void\n     */\n    public function whenQueryingForLongerThan($threshold, $handler)\n    {\n        $threshold = $threshold instanceof DateTimeInterface\n            ? $this->secondsUntil($threshold) * 1000\n            : $threshold;\n\n        $threshold = $threshold instanceof CarbonInterval\n            ? $threshold->totalMilliseconds\n            : $threshold;\n\n        $this->queryDurationHandlers[] = [\n            'has_run' => false,\n            'handler' => $handler,\n        ];\n\n        $key = count($this->queryDurationHandlers) - 1;\n\n        $this->listen(function ($event) use ($threshold, $handler, $key) {\n            if (! $this->queryDurationHandlers[$key]['has_run'] && $this->totalQueryDuration() > $threshold) {\n                $handler($this, $event);\n\n                $this->queryDurationHandlers[$key]['has_run'] = true;\n            }\n        });\n    }\n\n    /**\n     * Allow all the query duration handlers to run again, even if they have already run.\n     *\n     * @return void\n     */\n    public function allowQueryDurationHandlersToRunAgain()\n    {\n        foreach ($this->queryDurationHandlers as $key => $queryDurationHandler) {\n            $this->queryDurationHandlers[$key]['has_run'] = false;\n        }\n    }\n\n    /**\n     * Get the duration of all run queries in milliseconds.\n     *\n     * @return float\n     */\n    public function totalQueryDuration()\n    {\n        return $this->totalQueryDuration;\n    }\n\n    /**\n     * Reset the duration of all run queries.\n     *\n     * @return void\n     */\n    public function resetTotalQueryDuration()\n    {\n        $this->totalQueryDuration = 0.0;\n    }\n\n    /**\n     * Handle a query exception.\n     *\n     * @param  \\Illuminate\\Database\\QueryException  $e\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  \\Closure  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\QueryException\n     */\n    protected function handleQueryException(QueryException $e, $query, $bindings, Closure $callback)\n    {\n        if ($this->transactions >= 1) {\n            throw $e;\n        }\n\n        return $this->tryAgainIfCausedByLostConnection(\n            $e, $query, $bindings, $callback\n        );\n    }\n\n    /**\n     * Handle a query exception that occurred during query execution.\n     *\n     * @param  \\Illuminate\\Database\\QueryException  $e\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  \\Closure  $callback\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\QueryException\n     */\n    protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback)\n    {\n        if ($this->causedByLostConnection($e->getPrevious())) {\n            $this->reconnect();\n\n            return $this->runQueryCallback($query, $bindings, $callback);\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Reconnect to the database.\n     *\n     * @return mixed|false\n     *\n     * @throws \\Illuminate\\Database\\LostConnectionException\n     */\n    public function reconnect()\n    {\n        if (is_callable($this->reconnector)) {\n            return call_user_func($this->reconnector, $this);\n        }\n\n        throw new LostConnectionException('Lost connection and no reconnector available.');\n    }\n\n    /**\n     * Reconnect to the database if a PDO connection is missing.\n     *\n     * @return void\n     */\n    public function reconnectIfMissingConnection()\n    {\n        if (is_null($this->pdo)) {\n            $this->reconnect();\n        }\n    }\n\n    /**\n     * Disconnect from the underlying PDO connection.\n     *\n     * @return void\n     */\n    public function disconnect()\n    {\n        $this->setPdo(null)->setReadPdo(null);\n    }\n\n    /**\n     * Register a hook to be run just before a database transaction is started.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function beforeStartingTransaction(Closure $callback)\n    {\n        $this->beforeStartingTransaction[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a hook to be run just before a database query is executed.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function beforeExecuting(Closure $callback)\n    {\n        $this->beforeExecutingCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a database query listener with the connection.\n     *\n     * @param  \\Closure(\\Illuminate\\Database\\Events\\QueryExecuted)  $callback\n     * @return void\n     */\n    public function listen(Closure $callback)\n    {\n        $this->events?->listen(Events\\QueryExecuted::class, $callback);\n    }\n\n    /**\n     * Fire an event for this connection.\n     *\n     * @param  string  $event\n     * @return array|null\n     */\n    protected function fireConnectionEvent($event)\n    {\n        return $this->events?->dispatch(match ($event) {\n            'beganTransaction' => new TransactionBeginning($this),\n            'committed' => new TransactionCommitted($this),\n            'committing' => new TransactionCommitting($this),\n            'rollingBack' => new TransactionRolledBack($this),\n            default => null,\n        });\n    }\n\n    /**\n     * Fire the given event if possible.\n     *\n     * @param  mixed  $event\n     * @return void\n     */\n    protected function event($event)\n    {\n        $this->events?->dispatch($event);\n    }\n\n    /**\n     * Get a new raw query expression.\n     *\n     * @param  literal-string|int|float  $value\n     * @return \\Illuminate\\Contracts\\Database\\Query\\Expression\n     */\n    public function raw($value)\n    {\n        return new Expression($value);\n    }\n\n    /**\n     * Escape a value for safe SQL embedding.\n     *\n     * @param  string|float|int|bool|null  $value\n     * @param  bool  $binary\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function escape($value, $binary = false)\n    {\n        if ($value === null) {\n            return 'null';\n        } elseif ($binary) {\n            return $this->escapeBinary($value);\n        } elseif (is_int($value) || is_float($value)) {\n            return (string) $value;\n        } elseif (is_bool($value)) {\n            return $this->escapeBool($value);\n        } elseif (is_array($value)) {\n            throw new RuntimeException('The database connection does not support escaping arrays.');\n        } else {\n            if (str_contains($value, \"\\00\")) {\n                throw new RuntimeException('Strings with null bytes cannot be escaped. Use the binary escape option.');\n            }\n\n            if (preg_match('//u', $value) === false) {\n                throw new RuntimeException('Strings with invalid UTF-8 byte sequences cannot be escaped.');\n            }\n\n            return $this->escapeString($value);\n        }\n    }\n\n    /**\n     * Escape a string value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeString($value)\n    {\n        return $this->getReadPdo()->quote($value);\n    }\n\n    /**\n     * Escape a boolean value for safe SQL embedding.\n     *\n     * @param  bool  $value\n     * @return string\n     */\n    protected function escapeBool($value)\n    {\n        return $value ? '1' : '0';\n    }\n\n    /**\n     * Escape a binary value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function escapeBinary($value)\n    {\n        throw new RuntimeException('The database connection does not support escaping binary values.');\n    }\n\n    /**\n     * Determine if the database connection has modified any database records.\n     *\n     * @return bool\n     */\n    public function hasModifiedRecords()\n    {\n        return $this->recordsModified;\n    }\n\n    /**\n     * Indicate if any records have been modified.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public function recordsHaveBeenModified($value = true)\n    {\n        if (! $this->recordsModified) {\n            $this->recordsModified = $value;\n        }\n    }\n\n    /**\n     * Set the record modification state.\n     *\n     * @param  bool  $value\n     * @return $this\n     */\n    public function setRecordModificationState(bool $value)\n    {\n        $this->recordsModified = $value;\n\n        return $this;\n    }\n\n    /**\n     * Reset the record modification state.\n     *\n     * @return void\n     */\n    public function forgetRecordModificationState()\n    {\n        $this->recordsModified = false;\n    }\n\n    /**\n     * Indicate that the connection should use the write PDO connection for reads.\n     *\n     * @param  bool  $value\n     * @return $this\n     */\n    public function useWriteConnectionWhenReading($value = true)\n    {\n        $this->readOnWriteConnection = $value;\n\n        return $this;\n    }\n\n    /**\n     * Get the current PDO connection.\n     *\n     * @return \\PDO\n     */\n    public function getPdo()\n    {\n        $this->latestPdoTypeRetrieved = 'write';\n\n        if ($this->pdo instanceof Closure) {\n            return $this->pdo = call_user_func($this->pdo);\n        }\n\n        return $this->pdo;\n    }\n\n    /**\n     * Get the current PDO connection parameter without executing any reconnect logic.\n     *\n     * @return \\PDO|\\Closure|null\n     */\n    public function getRawPdo()\n    {\n        return $this->pdo;\n    }\n\n    /**\n     * Get the current PDO connection used for reading.\n     *\n     * @return \\PDO\n     */\n    public function getReadPdo()\n    {\n        if ($this->transactions > 0) {\n            return $this->getPdo();\n        }\n\n        if ($this->readOnWriteConnection ||\n            ($this->recordsModified && $this->getConfig('sticky'))) {\n            return $this->getPdo();\n        }\n\n        $this->latestPdoTypeRetrieved = 'read';\n\n        if ($this->readPdo instanceof Closure) {\n            return $this->readPdo = call_user_func($this->readPdo);\n        }\n\n        return $this->readPdo ?: $this->getPdo();\n    }\n\n    /**\n     * Get the current read PDO connection parameter without executing any reconnect logic.\n     *\n     * @return \\PDO|\\Closure|null\n     */\n    public function getRawReadPdo()\n    {\n        return $this->readPdo;\n    }\n\n    /**\n     * Set the PDO connection.\n     *\n     * @param  \\PDO|\\Closure|null  $pdo\n     * @return $this\n     */\n    public function setPdo($pdo)\n    {\n        $this->transactions = 0;\n\n        $this->pdo = $pdo;\n\n        return $this;\n    }\n\n    /**\n     * Set the PDO connection used for reading.\n     *\n     * @param  \\PDO|\\Closure|null  $pdo\n     * @return $this\n     */\n    public function setReadPdo($pdo)\n    {\n        $this->readPdo = $pdo;\n\n        return $this;\n    }\n\n    /**\n     * Set the read PDO connection configuration.\n     *\n     * @param  array  $config\n     * @return $this\n     */\n    public function setReadPdoConfig(array $config)\n    {\n        $this->readPdoConfig = $config;\n\n        return $this;\n    }\n\n    /**\n     * Set the reconnect instance on the connection.\n     *\n     * @param  (callable(\\Illuminate\\Database\\Connection): mixed)  $reconnector\n     * @return $this\n     */\n    public function setReconnector(callable $reconnector)\n    {\n        $this->reconnector = $reconnector;\n\n        return $this;\n    }\n\n    /**\n     * Get the database connection name.\n     *\n     * @return string|null\n     */\n    public function getName()\n    {\n        return $this->getConfig('name');\n    }\n\n    /**\n     * Get the database connection with its read / write type.\n     *\n     * @return string|null\n     */\n    public function getNameWithReadWriteType()\n    {\n        $name = $this->getName().($this->readWriteType ? '::'.$this->readWriteType : '');\n\n        return empty($name) ? null : $name;\n    }\n\n    /**\n     * Get an option from the configuration options.\n     *\n     * @param  string|null  $option\n     * @return mixed\n     */\n    public function getConfig($option = null)\n    {\n        return Arr::get($this->config, $option);\n    }\n\n    /**\n     * Get the basic connection information as an array for debugging.\n     *\n     * @return array\n     */\n    protected function getConnectionDetails()\n    {\n        $config = $this->latestReadWriteTypeUsed() === 'read'\n            ? $this->readPdoConfig\n            : $this->config;\n\n        return [\n            'driver' => $this->getDriverName(),\n            'name' => $this->getNameWithReadWriteType(),\n            'host' => $config['host'] ?? null,\n            'port' => $config['port'] ?? null,\n            'database' => $config['database'] ?? null,\n            'unix_socket' => $config['unix_socket'] ?? null,\n        ];\n    }\n\n    /**\n     * Get the PDO driver name.\n     *\n     * @return string\n     */\n    public function getDriverName()\n    {\n        return $this->getConfig('driver');\n    }\n\n    /**\n     * Get a human-readable name for the given connection driver.\n     *\n     * @return string\n     */\n    public function getDriverTitle()\n    {\n        return $this->getDriverName();\n    }\n\n    /**\n     * Get the query grammar used by the connection.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    public function getQueryGrammar()\n    {\n        return $this->queryGrammar;\n    }\n\n    /**\n     * Set the query grammar used by the connection.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Grammars\\Grammar  $grammar\n     * @return $this\n     */\n    public function setQueryGrammar(Query\\Grammars\\Grammar $grammar)\n    {\n        $this->queryGrammar = $grammar;\n\n        return $this;\n    }\n\n    /**\n     * Get the schema grammar used by the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\Grammar\n     */\n    public function getSchemaGrammar()\n    {\n        return $this->schemaGrammar;\n    }\n\n    /**\n     * Set the schema grammar used by the connection.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Grammars\\Grammar  $grammar\n     * @return $this\n     */\n    public function setSchemaGrammar(Schema\\Grammars\\Grammar $grammar)\n    {\n        $this->schemaGrammar = $grammar;\n\n        return $this;\n    }\n\n    /**\n     * Get the query post processor used by the connection.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    public function getPostProcessor()\n    {\n        return $this->postProcessor;\n    }\n\n    /**\n     * Set the query post processor used by the connection.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Processors\\Processor  $processor\n     * @return $this\n     */\n    public function setPostProcessor(Processor $processor)\n    {\n        $this->postProcessor = $processor;\n\n        return $this;\n    }\n\n    /**\n     * Get the event dispatcher used by the connection.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getEventDispatcher()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Set the event dispatcher instance on the connection.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return $this\n     */\n    public function setEventDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n\n        return $this;\n    }\n\n    /**\n     * Unset the event dispatcher for this connection.\n     *\n     * @return void\n     */\n    public function unsetEventDispatcher()\n    {\n        $this->events = null;\n    }\n\n    /**\n     * Run the statement to start a new transaction.\n     *\n     * @return void\n     */\n    protected function executeBeginTransactionStatement()\n    {\n        $this->getPdo()->beginTransaction();\n    }\n\n    /**\n     * Set the transaction manager instance on the connection.\n     *\n     * @param  \\Illuminate\\Database\\DatabaseTransactionsManager  $manager\n     * @return $this\n     */\n    public function setTransactionManager($manager)\n    {\n        $this->transactionsManager = $manager;\n\n        return $this;\n    }\n\n    /**\n     * Unset the transaction manager for this connection.\n     *\n     * @return void\n     */\n    public function unsetTransactionManager()\n    {\n        $this->transactionsManager = null;\n    }\n\n    /**\n     * Determine if the connection is in a \"dry run\".\n     *\n     * @return bool\n     */\n    public function pretending()\n    {\n        return $this->pretending === true;\n    }\n\n    /**\n     * Get the connection query log.\n     *\n     * @return array{query: string, bindings: array, time: float|null}[]\n     */\n    public function getQueryLog()\n    {\n        return $this->queryLog;\n    }\n\n    /**\n     * Get the connection query log with embedded bindings.\n     *\n     * @return array\n     */\n    public function getRawQueryLog()\n    {\n        return array_map(fn (array $log) => [\n            'raw_query' => $this->queryGrammar->substituteBindingsIntoRawSql(\n                $log['query'],\n                $this->prepareBindings($log['bindings'])\n            ),\n            'time' => $log['time'],\n        ], $this->getQueryLog());\n    }\n\n    /**\n     * Clear the query log.\n     *\n     * @return void\n     */\n    public function flushQueryLog()\n    {\n        $this->queryLog = [];\n    }\n\n    /**\n     * Enable the query log on the connection.\n     *\n     * @return void\n     */\n    public function enableQueryLog()\n    {\n        $this->loggingQueries = true;\n    }\n\n    /**\n     * Disable the query log on the connection.\n     *\n     * @return void\n     */\n    public function disableQueryLog()\n    {\n        $this->loggingQueries = false;\n    }\n\n    /**\n     * Determine whether we're logging queries.\n     *\n     * @return bool\n     */\n    public function logging()\n    {\n        return $this->loggingQueries;\n    }\n\n    /**\n     * Get the name of the connected database.\n     *\n     * @return string\n     */\n    public function getDatabaseName()\n    {\n        return $this->database;\n    }\n\n    /**\n     * Set the name of the connected database.\n     *\n     * @param  string  $database\n     * @return $this\n     */\n    public function setDatabaseName($database)\n    {\n        $this->database = $database;\n\n        return $this;\n    }\n\n    /**\n     * Set the read / write type of the connection.\n     *\n     * @param  string|null  $readWriteType\n     * @return $this\n     */\n    public function setReadWriteType($readWriteType)\n    {\n        $this->readWriteType = $readWriteType;\n\n        return $this;\n    }\n\n    /**\n     * Retrieve the latest read / write type used.\n     *\n     * @return 'read'|'write'|null\n     */\n    protected function latestReadWriteTypeUsed()\n    {\n        return $this->readWriteType ?? $this->latestPdoTypeRetrieved;\n    }\n\n    /**\n     * Get the table prefix for the connection.\n     *\n     * @return string\n     */\n    public function getTablePrefix()\n    {\n        return $this->tablePrefix;\n    }\n\n    /**\n     * Set the table prefix in use by the connection.\n     *\n     * @param  string  $prefix\n     * @return $this\n     */\n    public function setTablePrefix($prefix)\n    {\n        $this->tablePrefix = $prefix;\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback without table prefix.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function withoutTablePrefix(Closure $callback): mixed\n    {\n        $tablePrefix = $this->getTablePrefix();\n\n        $this->setTablePrefix('');\n\n        try {\n            return $callback($this);\n        } finally {\n            $this->setTablePrefix($tablePrefix);\n        }\n    }\n\n    /**\n     * Get the server version for the connection.\n     *\n     * @return string\n     */\n    public function getServerVersion(): string\n    {\n        return $this->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);\n    }\n\n    /**\n     * Register a connection resolver.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function resolverFor($driver, Closure $callback)\n    {\n        static::$resolvers[$driver] = $callback;\n    }\n\n    /**\n     * Get the connection resolver for the given driver.\n     *\n     * @param  string  $driver\n     * @return \\Closure|null\n     */\n    public static function getResolver($driver)\n    {\n        return static::$resolvers[$driver] ?? null;\n    }\n\n    /**\n     * Prepare the instance for cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        // When cloning, re-initialize grammars to reference cloned connection...\n        $this->useDefaultQueryGrammar();\n\n        if (! is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ConnectionInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Closure;\n\ninterface ConnectionInterface\n{\n    /**\n     * Begin a fluent query against a database table.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\UnitEnum|string  $table\n     * @param  string|null  $as\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function table($table, $as = null);\n\n    /**\n     * Get a new raw query expression.\n     *\n     * @param  literal-string|int|float  $value\n     * @return \\Illuminate\\Contracts\\Database\\Query\\Expression\n     */\n    public function raw($value);\n\n    /**\n     * Run a select statement and return a single result.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @return mixed\n     */\n    public function selectOne($query, $bindings = [], $useReadPdo = true);\n\n    /**\n     * Run a select statement and return the first column of the first row.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\MultipleColumnsSelectedException\n     */\n    public function scalar($query, $bindings = [], $useReadPdo = true);\n\n    /**\n     * Run a select statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @param  array  $fetchUsing\n     * @return array\n     */\n    public function select($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []);\n\n    /**\n     * Run a select statement against the database and returns a generator.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  bool  $useReadPdo\n     * @param  array  $fetchUsing\n     * @return \\Generator\n     */\n    public function cursor($query, $bindings = [], $useReadPdo = true, array $fetchUsing = []);\n\n    /**\n     * Run an insert statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return bool\n     */\n    public function insert($query, $bindings = []);\n\n    /**\n     * Run an update statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function update($query, $bindings = []);\n\n    /**\n     * Run a delete statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function delete($query, $bindings = []);\n\n    /**\n     * Execute an SQL statement and return the boolean result.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return bool\n     */\n    public function statement($query, $bindings = []);\n\n    /**\n     * Run an SQL statement and get the number of rows affected.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return int\n     */\n    public function affectingStatement($query, $bindings = []);\n\n    /**\n     * Run a raw, unprepared query against the PDO connection.\n     *\n     * @param  literal-string  $query\n     * @return bool\n     */\n    public function unprepared($query);\n\n    /**\n     * Prepare the query bindings for execution.\n     *\n     * @param  array  $bindings\n     * @return array\n     */\n    public function prepareBindings(array $bindings);\n\n    /**\n     * Execute a Closure within a transaction.\n     *\n     * @param  \\Closure  $callback\n     * @param  int  $attempts\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function transaction(Closure $callback, $attempts = 1);\n\n    /**\n     * Start a new database transaction.\n     *\n     * @return void\n     */\n    public function beginTransaction();\n\n    /**\n     * Commit the active database transaction.\n     *\n     * @return void\n     */\n    public function commit();\n\n    /**\n     * Rollback the active database transaction.\n     *\n     * @return void\n     */\n    public function rollBack();\n\n    /**\n     * Get the number of active transactions.\n     *\n     * @return int\n     */\n    public function transactionLevel();\n\n    /**\n     * Execute the given callback in \"dry run\" mode.\n     *\n     * @param  \\Closure  $callback\n     * @return array\n     */\n    public function pretend(Closure $callback);\n\n    /**\n     * Get the name of the connected database.\n     *\n     * @return string\n     */\n    public function getDatabaseName();\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ConnectionResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nclass ConnectionResolver implements ConnectionResolverInterface\n{\n    /**\n     * All of the registered connections.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface[]\n     */\n    protected $connections = [];\n\n    /**\n     * The default connection name.\n     *\n     * @var string\n     */\n    protected $default;\n\n    /**\n     * Create a new connection resolver instance.\n     *\n     * @param  array<string, \\Illuminate\\Database\\ConnectionInterface>  $connections\n     */\n    public function __construct(array $connections = [])\n    {\n        foreach ($connections as $name => $connection) {\n            $this->addConnection($name, $connection);\n        }\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function connection($name = null)\n    {\n        if (is_null($name)) {\n            $name = $this->getDefaultConnection();\n        }\n\n        return $this->connections[$name];\n    }\n\n    /**\n     * Add a connection to the resolver.\n     *\n     * @param  string  $name\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @return void\n     */\n    public function addConnection($name, ConnectionInterface $connection)\n    {\n        $this->connections[$name] = $connection;\n    }\n\n    /**\n     * Check if a connection has been registered.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasConnection($name)\n    {\n        return isset($this->connections[$name]);\n    }\n\n    /**\n     * Get the default connection name.\n     *\n     * @return string\n     */\n    public function getDefaultConnection()\n    {\n        return $this->default;\n    }\n\n    /**\n     * Set the default connection name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultConnection($name)\n    {\n        $this->default = $name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/ConnectionResolverInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\ninterface ConnectionResolverInterface\n{\n    /**\n     * Get a database connection instance.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function connection($name = null);\n\n    /**\n     * Get the default connection name.\n     *\n     * @return string\n     */\n    public function getDefaultConnection();\n\n    /**\n     * Set the default connection name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultConnection($name);\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/ConnectionFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\MariaDbConnection;\nuse Illuminate\\Database\\MySqlConnection;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Illuminate\\Database\\SqlServerConnection;\nuse Illuminate\\Support\\Arr;\nuse InvalidArgumentException;\nuse PDOException;\n\nclass ConnectionFactory\n{\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Create a new connection factory instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Establish a PDO connection based on the configuration.\n     *\n     * @param  array  $config\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function make(array $config, $name = null)\n    {\n        $config = $this->parseConfig($config, $name);\n\n        if (isset($config['read'])) {\n            return $this->createReadWriteConnection($config);\n        }\n\n        return $this->createSingleConnection($config);\n    }\n\n    /**\n     * Parse and prepare the database configuration.\n     *\n     * @param  array  $config\n     * @param  string  $name\n     * @return array\n     */\n    protected function parseConfig(array $config, $name)\n    {\n        return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);\n    }\n\n    /**\n     * Create a single database connection instance.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function createSingleConnection(array $config)\n    {\n        $pdo = $this->createPdoResolver($config);\n\n        return $this->createConnection(\n            $config['driver'], $pdo, $config['database'], $config['prefix'], $config\n        );\n    }\n\n    /**\n     * Create a read / write database connection instance.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function createReadWriteConnection(array $config)\n    {\n        $connection = $this->createSingleConnection($this->getWriteConfig($config));\n\n        return $connection\n            ->setReadPdo($this->createReadPdo($config))\n            ->setReadPdoConfig($this->getReadConfig($config));\n    }\n\n    /**\n     * Create a new PDO instance for reading.\n     *\n     * @param  array  $config\n     * @return \\Closure\n     */\n    protected function createReadPdo(array $config)\n    {\n        return $this->createPdoResolver($this->getReadConfig($config));\n    }\n\n    /**\n     * Get the read configuration for a read / write connection.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function getReadConfig(array $config)\n    {\n        return $this->mergeReadWriteConfig(\n            $config, $this->getReadWriteConfig($config, 'read')\n        );\n    }\n\n    /**\n     * Get the write configuration for a read / write connection.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function getWriteConfig(array $config)\n    {\n        return $this->mergeReadWriteConfig(\n            $config, $this->getReadWriteConfig($config, 'write')\n        );\n    }\n\n    /**\n     * Get a read / write level configuration.\n     *\n     * @param  array  $config\n     * @param  string  $type\n     * @return array\n     */\n    protected function getReadWriteConfig(array $config, $type)\n    {\n        return isset($config[$type][0])\n            ? Arr::random($config[$type])\n            : $config[$type];\n    }\n\n    /**\n     * Merge a configuration for a read / write connection.\n     *\n     * @param  array  $config\n     * @param  array  $merge\n     * @return array\n     */\n    protected function mergeReadWriteConfig(array $config, array $merge)\n    {\n        return Arr::except(array_merge($config, $merge), ['read', 'write']);\n    }\n\n    /**\n     * Create a new Closure that resolves to a PDO instance.\n     *\n     * @param  array  $config\n     * @return \\Closure\n     */\n    protected function createPdoResolver(array $config)\n    {\n        return array_key_exists('host', $config)\n            ? $this->createPdoResolverWithHosts($config)\n            : $this->createPdoResolverWithoutHosts($config);\n    }\n\n    /**\n     * Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts.\n     *\n     * @param  array  $config\n     * @return \\Closure\n     *\n     * @throws \\PDOException\n     */\n    protected function createPdoResolverWithHosts(array $config)\n    {\n        return function () use ($config) {\n            foreach (Arr::shuffle($this->parseHosts($config)) as $host) {\n                $config['host'] = $host;\n\n                try {\n                    return $this->createConnector($config)->connect($config);\n                } catch (PDOException $e) {\n                    continue;\n                }\n            }\n\n            if (isset($e)) {\n                throw $e;\n            }\n        };\n    }\n\n    /**\n     * Parse the hosts configuration item into an array.\n     *\n     * @param  array  $config\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseHosts(array $config)\n    {\n        $hosts = Arr::wrap($config['host']);\n\n        if (empty($hosts)) {\n            throw new InvalidArgumentException('Database hosts array is empty.');\n        }\n\n        return $hosts;\n    }\n\n    /**\n     * Create a new Closure that resolves to a PDO instance where there is no configured host.\n     *\n     * @param  array  $config\n     * @return \\Closure\n     */\n    protected function createPdoResolverWithoutHosts(array $config)\n    {\n        return fn () => $this->createConnector($config)->connect($config);\n    }\n\n    /**\n     * Create a connector instance based on the configuration.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Database\\Connectors\\ConnectorInterface\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function createConnector(array $config)\n    {\n        if (! isset($config['driver'])) {\n            throw new InvalidArgumentException('A driver must be specified.');\n        }\n\n        if ($this->container->bound($key = \"db.connector.{$config['driver']}\")) {\n            return $this->container->make($key);\n        }\n\n        return match ($config['driver']) {\n            'mysql' => new MySqlConnector,\n            'mariadb' => new MariaDbConnector,\n            'pgsql' => new PostgresConnector,\n            'sqlite' => new SQLiteConnector,\n            'sqlsrv' => new SqlServerConnector,\n            default => throw new InvalidArgumentException(\"Unsupported driver [{$config['driver']}].\"),\n        };\n    }\n\n    /**\n     * Create a new connection instance.\n     *\n     * @param  string  $driver\n     * @param  \\PDO|\\Closure  $connection\n     * @param  string  $database\n     * @param  string  $prefix\n     * @param  array  $config\n     * @return \\Illuminate\\Database\\Connection\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])\n    {\n        if ($resolver = Connection::getResolver($driver)) {\n            return $resolver($connection, $database, $prefix, $config);\n        }\n\n        return match ($driver) {\n            'mysql' => new MySqlConnection($connection, $database, $prefix, $config),\n            'mariadb' => new MariaDbConnection($connection, $database, $prefix, $config),\n            'pgsql' => new PostgresConnection($connection, $database, $prefix, $config),\n            'sqlite' => new SQLiteConnection($connection, $database, $prefix, $config),\n            'sqlsrv' => new SqlServerConnection($connection, $database, $prefix, $config),\n            default => throw new InvalidArgumentException(\"Unsupported driver [{$driver}].\"),\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/Connector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse Exception;\nuse Illuminate\\Database\\DetectsLostConnections;\nuse PDO;\nuse Throwable;\n\nclass Connector\n{\n    use DetectsLostConnections;\n\n    /**\n     * The default PDO connection options.\n     *\n     * @var array\n     */\n    protected $options = [\n        PDO::ATTR_CASE => PDO::CASE_NATURAL,\n        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,\n        PDO::ATTR_STRINGIFY_FETCHES => false,\n        PDO::ATTR_EMULATE_PREPARES => false,\n    ];\n\n    /**\n     * Create a new PDO connection.\n     *\n     * @param  string  $dsn\n     * @param  array  $config\n     * @param  array  $options\n     * @return \\PDO\n     *\n     * @throws \\Exception\n     */\n    public function createConnection($dsn, array $config, array $options)\n    {\n        [$username, $password] = [\n            $config['username'] ?? null, $config['password'] ?? null,\n        ];\n\n        try {\n            return $this->createPdoConnection(\n                $dsn, $username, $password, $options\n            );\n        } catch (Exception $e) {\n            return $this->tryAgainIfCausedByLostConnection(\n                $e, $dsn, $username, $password, $options\n            );\n        }\n    }\n\n    /**\n     * Create a new PDO connection instance.\n     *\n     * @param  string  $dsn\n     * @param  string  $username\n     * @param  string  $password\n     * @param  array  $options\n     * @return \\PDO\n     */\n    protected function createPdoConnection($dsn, $username, #[\\SensitiveParameter] $password, $options)\n    {\n        return version_compare(PHP_VERSION, '8.4.0', '<')\n            ? new PDO($dsn, $username, $password, $options)\n            : PDO::connect($dsn, $username, $password, $options); /** @phpstan-ignore staticMethod.notFound (PHP 8.4) */\n    }\n\n    /**\n     * Handle an exception that occurred during connect execution.\n     *\n     * @param  \\Throwable  $e\n     * @param  string  $dsn\n     * @param  string  $username\n     * @param  string  $password\n     * @param  array  $options\n     * @return \\PDO\n     *\n     * @throws \\Throwable\n     */\n    protected function tryAgainIfCausedByLostConnection(Throwable $e, $dsn, $username, #[\\SensitiveParameter] $password, $options)\n    {\n        if ($this->causedByLostConnection($e)) {\n            return $this->createPdoConnection($dsn, $username, $password, $options);\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Get the PDO options based on the configuration.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    public function getOptions(array $config)\n    {\n        $options = $config['options'] ?? [];\n\n        return array_diff_key($this->options, $options) + $options;\n    }\n\n    /**\n     * Get the default PDO connection options.\n     *\n     * @return array\n     */\n    public function getDefaultOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * Set the default PDO connection options.\n     *\n     * @param  array  $options\n     * @return void\n     */\n    public function setDefaultOptions(array $options)\n    {\n        $this->options = $options;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/ConnectorInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\ninterface ConnectorInterface\n{\n    /**\n     * Establish a database connection.\n     *\n     * @param  array  $config\n     * @return \\PDO\n     */\n    public function connect(array $config);\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/MariaDbConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse PDO;\n\nclass MariaDbConnector extends MySqlConnector\n{\n    /**\n     * Get the sql_mode value.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return string|null\n     */\n    protected function getSqlMode(PDO $connection, array $config)\n    {\n        if (isset($config['modes'])) {\n            return implode(',', $config['modes']);\n        }\n\n        if (! isset($config['strict'])) {\n            return null;\n        }\n\n        if (! $config['strict']) {\n            return 'NO_ENGINE_SUBSTITUTION';\n        }\n\n        return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/MySqlConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse PDO;\n\nclass MySqlConnector extends Connector implements ConnectorInterface\n{\n    /**\n     * Establish a database connection.\n     *\n     * @param  array  $config\n     * @return \\PDO\n     */\n    public function connect(array $config)\n    {\n        $dsn = $this->getDsn($config);\n\n        $options = $this->getOptions($config);\n\n        // We need to grab the PDO options that should be used while making the brand\n        // new connection instance. The PDO options control various aspects of the\n        // connection's behavior, and some might be specified by the developers.\n        $connection = $this->createConnection($dsn, $config, $options);\n\n        if (! empty($config['database']) &&\n            (! isset($config['use_db_after_connecting']) ||\n             $config['use_db_after_connecting'])) {\n            $connection->exec(\"use `{$config['database']}`;\");\n        }\n\n        $this->configureConnection($connection, $config);\n\n        return $connection;\n    }\n\n    /**\n     * Create a DSN string from a configuration.\n     *\n     * Chooses socket or host/port based on the 'unix_socket' config value.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getDsn(array $config)\n    {\n        return $this->hasSocket($config)\n            ? $this->getSocketDsn($config)\n            : $this->getHostDsn($config);\n    }\n\n    /**\n     * Determine if the given configuration array has a UNIX socket value.\n     *\n     * @param  array  $config\n     * @return bool\n     */\n    protected function hasSocket(array $config)\n    {\n        return isset($config['unix_socket']) && ! empty($config['unix_socket']);\n    }\n\n    /**\n     * Get the DSN string for a socket configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getSocketDsn(array $config)\n    {\n        return \"mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}\";\n    }\n\n    /**\n     * Get the DSN string for a host / port configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getHostDsn(array $config)\n    {\n        return isset($config['port'])\n            ? \"mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}\"\n            : \"mysql:host={$config['host']};dbname={$config['database']}\";\n    }\n\n    /**\n     * Configure the given PDO connection.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureConnection(PDO $connection, array $config)\n    {\n        if (isset($config['isolation_level'])) {\n            $connection->exec(sprintf('SET SESSION TRANSACTION ISOLATION LEVEL %s;', $config['isolation_level']));\n        }\n\n        $statements = [];\n\n        if (isset($config['charset'])) {\n            if (isset($config['collation'])) {\n                $statements[] = sprintf(\"NAMES '%s' COLLATE '%s'\", $config['charset'], $config['collation']);\n            } else {\n                $statements[] = sprintf(\"NAMES '%s'\", $config['charset']);\n            }\n        }\n\n        if (isset($config['timezone'])) {\n            $statements[] = sprintf(\"time_zone='%s'\", $config['timezone']);\n        }\n\n        $sqlMode = $this->getSqlMode($connection, $config);\n\n        if ($sqlMode !== null) {\n            $statements[] = sprintf(\"SESSION sql_mode='%s'\", $sqlMode);\n        }\n\n        if ($statements !== []) {\n            $connection->exec(sprintf('SET %s;', implode(', ', $statements)));\n        }\n    }\n\n    /**\n     * Get the sql_mode value.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return string|null\n     */\n    protected function getSqlMode(PDO $connection, array $config)\n    {\n        if (isset($config['modes'])) {\n            return implode(',', $config['modes']);\n        }\n\n        if (! isset($config['strict'])) {\n            return null;\n        }\n\n        if (! $config['strict']) {\n            return 'NO_ENGINE_SUBSTITUTION';\n        }\n\n        $version = $config['version'] ?? $connection->getAttribute(PDO::ATTR_SERVER_VERSION);\n\n        if (version_compare($version, '8.0.11', '>=')) {\n            return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';\n        }\n\n        return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/PostgresConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse Illuminate\\Database\\Concerns\\ParsesSearchPath;\nuse PDO;\n\nclass PostgresConnector extends Connector implements ConnectorInterface\n{\n    use ParsesSearchPath;\n\n    /**\n     * The default PDO connection options.\n     *\n     * @var array\n     */\n    protected $options = [\n        PDO::ATTR_CASE => PDO::CASE_NATURAL,\n        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,\n        PDO::ATTR_STRINGIFY_FETCHES => false,\n    ];\n\n    /**\n     * Establish a database connection.\n     *\n     * @param  array  $config\n     * @return \\PDO\n     */\n    public function connect(array $config)\n    {\n        // First we'll create the basic DSN and connection instance connecting to the\n        // using the configuration option specified by the developer. We will also\n        // set the default character set on the connections to UTF-8 by default.\n        $connection = $this->createConnection(\n            $this->getDsn($config), $config, $this->getOptions($config)\n        );\n\n        $this->configureIsolationLevel($connection, $config);\n\n        // Next, we will check to see if a timezone has been specified in this config\n        // and if it has we will issue a statement to modify the timezone with the\n        // database. Setting this DB timezone is an optional configuration item.\n        $this->configureTimezone($connection, $config);\n\n        $this->configureSearchPath($connection, $config);\n\n        $this->configureSynchronousCommit($connection, $config);\n\n        return $connection;\n    }\n\n    /**\n     * Create a DSN string from a configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getDsn(array $config)\n    {\n        // First we will create the basic DSN setup as well as the port if it is in\n        // in the configuration options. This will give us the basic DSN we will\n        // need to establish the PDO connections and return them back for use.\n        extract($config, EXTR_SKIP);\n\n        $host = isset($host) ? \"host={$host};\" : '';\n\n        // Sometimes - users may need to connect to a database that has a different\n        // name than the database used for \"information_schema\" queries. This is\n        // typically the case if using \"pgbouncer\" type software when pooling.\n        $database = $connect_via_database ?? $database ?? null;\n        $port = $connect_via_port ?? $port ?? null;\n\n        $dsn = \"pgsql:{$host}dbname='{$database}'\";\n\n        // If a port was specified, we will add it to this Postgres DSN connections\n        // format. Once we have done that we are ready to return this connection\n        // string back out for usage, as this has been fully constructed here.\n        if (! is_null($port)) {\n            $dsn .= \";port={$port}\";\n        }\n\n        if (isset($charset)) {\n            $dsn .= \";client_encoding='{$charset}'\";\n        }\n\n        // Postgres allows an application_name to be set by the user and this name is\n        // used to when monitoring the application with pg_stat_activity. So we'll\n        // determine if the option has been specified and run a statement if so.\n        if (isset($application_name)) {\n            $dsn .= \";application_name='\".str_replace(\"'\", \"\\'\", $application_name).\"'\";\n        }\n\n        return $this->addSslOptions($dsn, $config);\n    }\n\n    /**\n     * Add the SSL options to the DSN.\n     *\n     * @param  string  $dsn\n     * @param  array  $config\n     * @return string\n     */\n    protected function addSslOptions($dsn, array $config)\n    {\n        foreach (['sslmode', 'sslcert', 'sslkey', 'sslrootcert'] as $option) {\n            if (isset($config[$option])) {\n                $dsn .= \";{$option}={$config[$option]}\";\n            }\n        }\n\n        return $dsn;\n    }\n\n    /**\n     * Set the connection transaction isolation level.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureIsolationLevel($connection, array $config)\n    {\n        if (isset($config['isolation_level'])) {\n            $connection->prepare(\"set session characteristics as transaction isolation level {$config['isolation_level']}\")->execute();\n        }\n    }\n\n    /**\n     * Set the timezone on the connection.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureTimezone($connection, array $config)\n    {\n        if (isset($config['timezone'])) {\n            $timezone = $config['timezone'];\n\n            $connection->prepare(\"set time zone '{$timezone}'\")->execute();\n        }\n    }\n\n    /**\n     * Set the \"search_path\" on the database connection.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureSearchPath($connection, $config)\n    {\n        if (isset($config['search_path']) || isset($config['schema'])) {\n            $searchPath = $this->quoteSearchPath(\n                $this->parseSearchPath($config['search_path'] ?? $config['schema'])\n            );\n\n            $connection->prepare(\"set search_path to {$searchPath}\")->execute();\n        }\n    }\n\n    /**\n     * Format the search path for the DSN.\n     *\n     * @param  array  $searchPath\n     * @return string\n     */\n    protected function quoteSearchPath($searchPath)\n    {\n        return count($searchPath) === 1 ? '\"'.$searchPath[0].'\"' : '\"'.implode('\", \"', $searchPath).'\"';\n    }\n\n    /**\n     * Configure the synchronous_commit setting.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureSynchronousCommit($connection, array $config)\n    {\n        if (isset($config['synchronous_commit'])) {\n            $connection->prepare(\"set synchronous_commit to '{$config['synchronous_commit']}'\")->execute();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/SQLiteConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse Illuminate\\Database\\SQLiteDatabaseDoesNotExistException;\n\nclass SQLiteConnector extends Connector implements ConnectorInterface\n{\n    /**\n     * Establish a database connection.\n     *\n     * @param  array  $config\n     * @return \\PDO\n     */\n    public function connect(array $config)\n    {\n        $options = $this->getOptions($config);\n\n        $path = $this->parseDatabasePath($config['database']);\n\n        $connection = $this->createConnection(\"sqlite:{$path}\", $config, $options);\n\n        $this->configurePragmas($connection, $config);\n        $this->configureForeignKeyConstraints($connection, $config);\n        $this->configureBusyTimeout($connection, $config);\n        $this->configureJournalMode($connection, $config);\n        $this->configureSynchronous($connection, $config);\n\n        return $connection;\n    }\n\n    /**\n     * Get the absolute database path.\n     *\n     * @param  string  $path\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\SQLiteDatabaseDoesNotExistException\n     */\n    protected function parseDatabasePath(string $path): string\n    {\n        $database = $path;\n\n        // SQLite supports \"in-memory\" databases that only last as long as the owning\n        // connection does. These are useful for tests or for short lifetime store\n        // querying. In-memory databases shall be anonymous (:memory:) or named.\n        if ($path === ':memory:' ||\n            str_contains($path, '?mode=memory') ||\n            str_contains($path, '&mode=memory')\n        ) {\n            return $path;\n        }\n\n        $path = realpath($path) ?: realpath(base_path($path));\n\n        // Here we'll verify that the SQLite database exists before going any further\n        // as the developer probably wants to know if the database exists and this\n        // SQLite driver will not throw any exception if it does not by default.\n        if ($path === false) {\n            throw new SQLiteDatabaseDoesNotExistException($database);\n        }\n\n        return $path;\n    }\n\n    /**\n     * Set miscellaneous user-configured pragmas.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configurePragmas($connection, array $config): void\n    {\n        if (! isset($config['pragmas'])) {\n            return;\n        }\n\n        foreach ($config['pragmas'] as $pragma => $value) {\n            $connection->prepare(\"pragma {$pragma} = {$value}\")->execute();\n        }\n    }\n\n    /**\n     * Enable or disable foreign key constraints if configured.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureForeignKeyConstraints($connection, array $config): void\n    {\n        if (! isset($config['foreign_key_constraints'])) {\n            return;\n        }\n\n        $foreignKeys = $config['foreign_key_constraints'] ? 1 : 0;\n\n        $connection->prepare(\"pragma foreign_keys = {$foreignKeys}\")->execute();\n    }\n\n    /**\n     * Set the busy timeout if configured.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureBusyTimeout($connection, array $config): void\n    {\n        if (! isset($config['busy_timeout'])) {\n            return;\n        }\n\n        $connection->prepare(\"pragma busy_timeout = {$config['busy_timeout']}\")->execute();\n    }\n\n    /**\n     * Set the journal mode if configured.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureJournalMode($connection, array $config): void\n    {\n        if (! isset($config['journal_mode'])) {\n            return;\n        }\n\n        $connection->prepare(\"pragma journal_mode = {$config['journal_mode']}\")->execute();\n    }\n\n    /**\n     * Set the synchronous mode if configured.\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureSynchronous($connection, array $config): void\n    {\n        if (! isset($config['synchronous'])) {\n            return;\n        }\n\n        $connection->prepare(\"pragma synchronous = {$config['synchronous']}\")->execute();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Connectors/SqlServerConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Connectors;\n\nuse Illuminate\\Support\\Arr;\nuse PDO;\n\nclass SqlServerConnector extends Connector implements ConnectorInterface\n{\n    /**\n     * The PDO connection options.\n     *\n     * @var array\n     */\n    protected $options = [\n        PDO::ATTR_CASE => PDO::CASE_NATURAL,\n        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,\n        PDO::ATTR_STRINGIFY_FETCHES => false,\n    ];\n\n    /**\n     * Establish a database connection.\n     *\n     * @param  array  $config\n     * @return \\PDO\n     */\n    public function connect(array $config)\n    {\n        $options = $this->getOptions($config);\n\n        $connection = $this->createConnection($this->getDsn($config), $config, $options);\n\n        $this->configureIsolationLevel($connection, $config);\n\n        return $connection;\n    }\n\n    /**\n     * Set the connection transaction isolation level.\n     *\n     * https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql\n     *\n     * @param  \\PDO  $connection\n     * @param  array  $config\n     * @return void\n     */\n    protected function configureIsolationLevel($connection, array $config)\n    {\n        if (! isset($config['isolation_level'])) {\n            return;\n        }\n\n        $connection->prepare(\n            \"SET TRANSACTION ISOLATION LEVEL {$config['isolation_level']}\"\n        )->execute();\n    }\n\n    /**\n     * Create a DSN string from a configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getDsn(array $config)\n    {\n        // First we will create the basic DSN setup as well as the port if it is in\n        // in the configuration options. This will give us the basic DSN we will\n        // need to establish the PDO connections and return them back for use.\n        if ($this->prefersOdbc($config)) {\n            return $this->getOdbcDsn($config);\n        }\n\n        if (in_array('sqlsrv', $this->getAvailableDrivers())) {\n            return $this->getSqlSrvDsn($config);\n        } else {\n            return $this->getDblibDsn($config);\n        }\n    }\n\n    /**\n     * Determine if the database configuration prefers ODBC.\n     *\n     * @param  array  $config\n     * @return bool\n     */\n    protected function prefersOdbc(array $config)\n    {\n        return in_array('odbc', $this->getAvailableDrivers()) &&\n               ($config['odbc'] ?? null) === true;\n    }\n\n    /**\n     * Get the DSN string for a DbLib connection.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getDblibDsn(array $config)\n    {\n        return $this->buildConnectString('dblib', array_merge([\n            'host' => $this->buildHostString($config, ':'),\n            'dbname' => $config['database'],\n        ], Arr::only($config, ['appname', 'charset', 'version'])));\n    }\n\n    /**\n     * Get the DSN string for an ODBC connection.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getOdbcDsn(array $config)\n    {\n        return isset($config['odbc_datasource_name'])\n            ? 'odbc:'.$config['odbc_datasource_name']\n            : '';\n    }\n\n    /**\n     * Get the DSN string for a SqlSrv connection.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function getSqlSrvDsn(array $config)\n    {\n        $arguments = [\n            'Server' => $this->buildHostString($config, ','),\n        ];\n\n        if (isset($config['database'])) {\n            $arguments['Database'] = $config['database'];\n        }\n\n        if (isset($config['readonly'])) {\n            $arguments['ApplicationIntent'] = 'ReadOnly';\n        }\n\n        if (isset($config['pooling']) && $config['pooling'] === false) {\n            $arguments['ConnectionPooling'] = '0';\n        }\n\n        if (isset($config['appname'])) {\n            $arguments['APP'] = $config['appname'];\n        }\n\n        if (isset($config['encrypt'])) {\n            $arguments['Encrypt'] = $config['encrypt'];\n        }\n\n        if (isset($config['trust_server_certificate'])) {\n            $arguments['TrustServerCertificate'] = $config['trust_server_certificate'];\n        }\n\n        if (isset($config['multiple_active_result_sets']) && $config['multiple_active_result_sets'] === false) {\n            $arguments['MultipleActiveResultSets'] = 'false';\n        }\n\n        if (isset($config['transaction_isolation'])) {\n            $arguments['TransactionIsolation'] = $config['transaction_isolation'];\n        }\n\n        if (isset($config['multi_subnet_failover'])) {\n            $arguments['MultiSubnetFailover'] = $config['multi_subnet_failover'];\n        }\n\n        if (isset($config['column_encryption'])) {\n            $arguments['ColumnEncryption'] = $config['column_encryption'];\n        }\n\n        if (isset($config['key_store_authentication'])) {\n            $arguments['KeyStoreAuthentication'] = $config['key_store_authentication'];\n        }\n\n        if (isset($config['key_store_principal_id'])) {\n            $arguments['KeyStorePrincipalId'] = $config['key_store_principal_id'];\n        }\n\n        if (isset($config['key_store_secret'])) {\n            $arguments['KeyStoreSecret'] = $config['key_store_secret'];\n        }\n\n        if (isset($config['login_timeout'])) {\n            $arguments['LoginTimeout'] = $config['login_timeout'];\n        }\n\n        if (isset($config['authentication'])) {\n            $arguments['Authentication'] = $config['authentication'];\n        }\n\n        return $this->buildConnectString('sqlsrv', $arguments);\n    }\n\n    /**\n     * Build a connection string from the given arguments.\n     *\n     * @param  string  $driver\n     * @param  array  $arguments\n     * @return string\n     */\n    protected function buildConnectString($driver, array $arguments)\n    {\n        return $driver.':'.implode(';', array_map(function ($key) use ($arguments) {\n            return sprintf('%s=%s', $key, $arguments[$key]);\n        }, array_keys($arguments)));\n    }\n\n    /**\n     * Build a host string from the given configuration.\n     *\n     * @param  array  $config\n     * @param  string  $separator\n     * @return string\n     */\n    protected function buildHostString(array $config, $separator)\n    {\n        if (empty($config['port'])) {\n            return $config['host'];\n        }\n\n        return $config['host'].$separator.$config['port'];\n    }\n\n    /**\n     * Get the available PDO drivers.\n     *\n     * @return array\n     */\n    protected function getAvailableDrivers()\n    {\n        return PDO::getAvailableDrivers();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/DatabaseInspectionCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Support\\Arr;\n\nabstract class DatabaseInspectionCommand extends Command\n{\n    /**\n     * Get a human-readable name for the given connection.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  string  $database\n     * @return string\n     *\n     * @deprecated\n     */\n    protected function getConnectionName(ConnectionInterface $connection, $database)\n    {\n        return $connection->getDriverTitle();\n    }\n\n    /**\n     * Get the number of open connections for a database.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @return int|null\n     *\n     * @deprecated\n     */\n    protected function getConnectionCount(ConnectionInterface $connection)\n    {\n        return $connection->threadCount();\n    }\n\n    /**\n     * Get the connection configuration details for the given connection.\n     *\n     * @param  string|null  $database\n     * @return array\n     */\n    protected function getConfigFromDatabase($database)\n    {\n        $database ??= config('database.default');\n\n        return Arr::except(config('database.connections.'.$database), ['password']);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/DbCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\ConfigurationUrlParser;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\nuse Symfony\\Component\\Process\\Process;\nuse UnexpectedValueException;\n\n#[AsCommand(name: 'db')]\nclass DbCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'db {connection? : The database connection that should be used}\n               {--read : Connect to the read connection}\n               {--write : Connect to the write connection}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Start a new database CLI session';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        $connection = $this->getConnection();\n\n        if (! isset($connection['host']) && $connection['driver'] !== 'sqlite') {\n            $this->components->error('No host specified for this database connection.');\n            $this->line('  Use the <options=bold>[--read]</> and <options=bold>[--write]</> options to specify a read or write connection.');\n            $this->newLine();\n\n            return Command::FAILURE;\n        }\n\n        try {\n            (new Process(\n                array_merge([$command = $this->getCommand($connection)], $this->commandArguments($connection)),\n                null,\n                $this->commandEnvironment($connection)\n            ))->setTimeout(null)->setTty(true)->mustRun(function ($type, $buffer) {\n                $this->output->write($buffer);\n            });\n        } catch (ProcessFailedException $e) {\n            throw_unless($e->getProcess()->getExitCode() === 127, $e);\n\n            $this->error(\"{$command} not found in path.\");\n\n            return Command::FAILURE;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Get the database connection configuration.\n     *\n     * @return array\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function getConnection()\n    {\n        $connection = $this->laravel['config']['database.connections.'.\n            (($db = $this->argument('connection')) ?? $this->laravel['config']['database.default'])\n        ];\n\n        if (empty($connection)) {\n            throw new UnexpectedValueException(\"Invalid database connection [{$db}].\");\n        }\n\n        if (! empty($connection['url'])) {\n            $connection = (new ConfigurationUrlParser)->parseConfiguration($connection);\n        }\n\n        if ($this->option('read')) {\n            if (is_array($connection['read']['host'])) {\n                $connection['read']['host'] = $connection['read']['host'][0];\n            }\n\n            $connection = array_merge($connection, $connection['read']);\n        } elseif ($this->option('write')) {\n            if (is_array($connection['write']['host'])) {\n                $connection['write']['host'] = $connection['write']['host'][0];\n            }\n\n            $connection = array_merge($connection, $connection['write']);\n        }\n\n        return $connection;\n    }\n\n    /**\n     * Get the arguments for the database client command.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    public function commandArguments(array $connection)\n    {\n        $driver = ucfirst($connection['driver']);\n\n        return $this->{\"get{$driver}Arguments\"}($connection);\n    }\n\n    /**\n     * Get the environment variables for the database client command.\n     *\n     * @param  array  $connection\n     * @return array|null\n     */\n    public function commandEnvironment(array $connection)\n    {\n        $driver = ucfirst($connection['driver']);\n\n        if (method_exists($this, \"get{$driver}Environment\")) {\n            return $this->{\"get{$driver}Environment\"}($connection);\n        }\n\n        return null;\n    }\n\n    /**\n     * Get the database client command to run.\n     *\n     * @param  array  $connection\n     * @return string\n     */\n    public function getCommand(array $connection)\n    {\n        return [\n            'mysql' => 'mysql',\n            'mariadb' => 'mariadb',\n            'pgsql' => 'psql',\n            'sqlite' => 'sqlite3',\n            'sqlsrv' => 'sqlcmd',\n        ][$connection['driver']];\n    }\n\n    /**\n     * Get the arguments for the MySQL CLI.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getMysqlArguments(array $connection)\n    {\n        $optionalArguments = [\n            'password' => '--password='.$connection['password'],\n            'unix_socket' => '--socket='.($connection['unix_socket'] ?? ''),\n            'charset' => '--default-character-set='.($connection['charset'] ?? ''),\n        ];\n\n        if (! $connection['password']) {\n            unset($optionalArguments['password']);\n        }\n\n        return array_merge([\n            '--host='.$connection['host'],\n            '--port='.$connection['port'],\n            '--user='.$connection['username'],\n        ], $this->getOptionalArguments($optionalArguments, $connection), [$connection['database']]);\n    }\n\n    /**\n     * Get the arguments for the MariaDB CLI.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getMariaDbArguments(array $connection)\n    {\n        return $this->getMysqlArguments($connection);\n    }\n\n    /**\n     * Get the arguments for the Postgres CLI.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getPgsqlArguments(array $connection)\n    {\n        return [$connection['database']];\n    }\n\n    /**\n     * Get the arguments for the SQLite CLI.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getSqliteArguments(array $connection)\n    {\n        return [$connection['database']];\n    }\n\n    /**\n     * Get the arguments for the SQL Server CLI.\n     *\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getSqlsrvArguments(array $connection)\n    {\n        return array_merge(...$this->getOptionalArguments([\n            'database' => ['-d', $connection['database']],\n            'username' => ['-U', $connection['username']],\n            'password' => ['-P', $connection['password']],\n            'host' => ['-S', 'tcp:'.$connection['host']\n                        .($connection['port'] ? ','.$connection['port'] : ''), ],\n            'trust_server_certificate' => ['-C'],\n        ], $connection));\n    }\n\n    /**\n     * Get the environment variables for the Postgres CLI.\n     *\n     * @param  array  $connection\n     * @return array|null\n     */\n    protected function getPgsqlEnvironment(array $connection)\n    {\n        return array_merge(...$this->getOptionalArguments([\n            'username' => ['PGUSER' => $connection['username']],\n            'host' => ['PGHOST' => $connection['host']],\n            'port' => ['PGPORT' => $connection['port']],\n            'password' => ['PGPASSWORD' => $connection['password']],\n        ], $connection));\n    }\n\n    /**\n     * Get the optional arguments based on the connection configuration.\n     *\n     * @param  array  $args\n     * @param  array  $connection\n     * @return array\n     */\n    protected function getOptionalArguments(array $args, array $connection)\n    {\n        return array_values(array_filter($args, function ($key) use ($connection) {\n            return ! empty($connection[$key]);\n        }, ARRAY_FILTER_USE_KEY));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/DumpCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Events\\MigrationsPruned;\nuse Illuminate\\Database\\Events\\SchemaDumped;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\Config;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'schema:dump')]\nclass DumpCommand extends Command\n{\n    use Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'schema:dump\n                {--database= : The database connection to use}\n                {--path= : The path where the schema dump file should be stored}\n                {--prune : Delete all existing migration files}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Dump the given database schema';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $connections\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @return void\n     */\n    public function handle(ConnectionResolverInterface $connections, Dispatcher $dispatcher)\n    {\n        if ($this->isProhibited()) {\n            return Command::FAILURE;\n        }\n\n        $connection = $connections->connection($database = $this->input->getOption('database'));\n\n        $this->schemaState($connection)->dump(\n            $connection, $path = $this->path($connection)\n        );\n\n        $dispatcher->dispatch(new SchemaDumped($connection, $path));\n\n        $info = 'Database schema dumped';\n\n        if ($this->option('prune')) {\n            (new Filesystem)->deleteDirectory(\n                $path = database_path('migrations'), preserve: false\n            );\n\n            $info .= ' and pruned';\n\n            $dispatcher->dispatch(new MigrationsPruned($connection, $path));\n        }\n\n        $this->components->info($info.' successfully.');\n    }\n\n    /**\n     * Create a schema state instance for the given connection.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return mixed\n     */\n    protected function schemaState(Connection $connection)\n    {\n        $migrations = Config::get('database.migrations', 'migrations');\n\n        $migrationTable = is_array($migrations) ? ($migrations['table'] ?? 'migrations') : $migrations;\n\n        return $connection->getSchemaState()\n            ->withMigrationTable($migrationTable)\n            ->handleOutputUsing(function ($type, $buffer) {\n                $this->output->write($buffer);\n            });\n    }\n\n    /**\n     * Get the path that the dump should be written to.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     */\n    protected function path(Connection $connection)\n    {\n        return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.sql'), function ($path) {\n            (new Filesystem)->ensureDirectoryExists(dirname($path));\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Factories/FactoryMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Factories;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:factory')]\nclass FactoryMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:factory';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new model factory';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Factory';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/factory.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $factory = class_basename(Str::ucfirst(str_replace('Factory', '', $name)));\n\n        $namespaceModel = $this->option('model')\n            ? $this->qualifyModel($this->option('model'))\n            : $this->qualifyModel($this->guessModelName($name));\n\n        $model = class_basename($namespaceModel);\n\n        $namespace = $this->getNamespace(\n            Str::replaceFirst($this->rootNamespace(), 'Database\\\\Factories\\\\', $this->qualifyClass($this->getNameInput()))\n        );\n\n        $replace = [\n            '{{ factoryNamespace }}' => $namespace,\n            'NamespacedDummyModel' => $namespaceModel,\n            '{{ namespacedModel }}' => $namespaceModel,\n            '{{namespacedModel}}' => $namespaceModel,\n            'DummyModel' => $model,\n            '{{ model }}' => $model,\n            '{{model}}' => $model,\n            '{{ factory }}' => $factory,\n            '{{factory}}' => $factory,\n        ];\n\n        return str_replace(\n            array_keys($replace), array_values($replace), parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Get the destination class path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getPath($name)\n    {\n        $name = (new Stringable($name))->replaceFirst($this->rootNamespace(), '')->finish('Factory')->value();\n\n        return $this->laravel->databasePath().'/factories/'.str_replace('\\\\', '/', $name).'.php';\n    }\n\n    /**\n     * Guess the model name from the Factory name or return a default model name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function guessModelName($name)\n    {\n        if (str_ends_with($name, 'Factory')) {\n            $name = substr($name, 0, -7);\n        }\n\n        $modelName = $this->qualifyModel(Str::after($name, $this->rootNamespace()));\n\n        if (class_exists($modelName)) {\n            return $modelName;\n        }\n\n        if (is_dir(app_path('Models/'))) {\n            return $this->rootNamespace().'Models\\Model';\n        }\n\n        return $this->rootNamespace().'Model';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['model', 'm', InputOption::VALUE_OPTIONAL, 'The name of the model'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Factories/stubs/factory.stub",
    "content": "<?php\n\nnamespace {{ factoryNamespace }};\n\nuse {{ namespacedModel }};\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\n/**\n * @extends Factory<{{ model }}>\n */\nclass {{ factory }}Factory extends Factory\n{\n    /**\n     * Define the model's default state.\n     *\n     * @return array<string, mixed>\n     */\n    public function definition(): array\n    {\n        return [\n            //\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/BaseCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\n\nclass BaseCommand extends Command\n{\n    /**\n     * Get all of the migration paths.\n     *\n     * @return string[]\n     */\n    protected function getMigrationPaths()\n    {\n        // Here, we will check to see if a path option has been defined. If it has we will\n        // use the path relative to the root of the installation folder so our database\n        // migrations may be run for any customized path from within the application.\n        if ($this->input->hasOption('path') && $this->option('path')) {\n            return (new Collection($this->option('path')))->map(function ($path) {\n                return ! $this->usingRealPath()\n                    ? $this->laravel->basePath().'/'.$path\n                    : $path;\n            })->all();\n        }\n\n        return array_merge(\n            $this->migrator->paths(), [$this->getMigrationPath()]\n        );\n    }\n\n    /**\n     * Determine if the given path(s) are pre-resolved \"real\" paths.\n     *\n     * @return bool\n     */\n    protected function usingRealPath()\n    {\n        return $this->input->hasOption('realpath') && $this->option('realpath');\n    }\n\n    /**\n     * Get the path to the migration directory.\n     *\n     * @return string\n     */\n    protected function getMigrationPath()\n    {\n        return $this->laravel->databasePath().DIRECTORY_SEPARATOR.'migrations';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/FreshCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Events\\DatabaseRefreshed;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Throwable;\n\n#[AsCommand(name: 'migrate:fresh')]\nclass FreshCommand extends Command\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:fresh';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Drop all tables and re-run all migrations';\n\n    /**\n     * The migrator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migrator\n     */\n    protected $migrator;\n\n    /**\n     * Create a new fresh command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migrator  $migrator\n     */\n    public function __construct(Migrator $migrator)\n    {\n        parent::__construct();\n\n        $this->migrator = $migrator;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        $database = $this->input->getOption('database');\n\n        $this->migrator->usingConnection($database, function () use ($database) {\n            try {\n                $repositoryExists = $this->migrator->repositoryExists();\n            } catch (Throwable) {\n                $repositoryExists = false;\n            }\n\n            if ($repositoryExists) {\n                $this->newLine();\n\n                $this->components->task('Dropping all tables', fn () => $this->callSilent('db:wipe', array_filter([\n                    '--database' => $database,\n                    '--drop-views' => $this->option('drop-views'),\n                    '--drop-types' => $this->option('drop-types'),\n                    '--force' => true,\n                ])) == 0);\n            }\n        });\n\n        $this->newLine();\n\n        $this->call('migrate', array_filter([\n            '--database' => $database,\n            '--path' => $this->input->getOption('path'),\n            '--realpath' => $this->input->getOption('realpath'),\n            '--schema-path' => $this->input->getOption('schema-path'),\n            '--force' => true,\n            '--step' => $this->option('step'),\n        ]));\n\n        if ($this->laravel->bound(Dispatcher::class)) {\n            $this->laravel[Dispatcher::class]->dispatch(\n                new DatabaseRefreshed($database, $this->needsSeeding())\n            );\n        }\n\n        if ($this->needsSeeding()) {\n            $this->runSeeder($database);\n        }\n\n        return 0;\n    }\n\n    /**\n     * Determine if the developer has requested database seeding.\n     *\n     * @return bool\n     */\n    protected function needsSeeding()\n    {\n        return $this->option('seed') || $this->option('seeder');\n    }\n\n    /**\n     * Run the database seeder command.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function runSeeder($database)\n    {\n        $this->call('db:seed', array_filter([\n            '--database' => $database,\n            '--class' => $this->option('seeder') ?: 'Database\\\\Seeders\\\\DatabaseSeeder',\n            '--force' => true,\n        ]));\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n            ['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views'],\n            ['drop-types', null, InputOption::VALUE_NONE, 'Drop all tables and types (Postgres only)'],\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],\n            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],\n            ['schema-path', null, InputOption::VALUE_OPTIONAL, 'The path to a schema dump file'],\n            ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run'],\n            ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder'],\n            ['step', null, InputOption::VALUE_NONE, 'Force the migrations to be run so they can be rolled back individually'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/InstallCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Database\\Migrations\\MigrationRepositoryInterface;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'migrate:install')]\nclass InstallCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:install';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create the migration repository';\n\n    /**\n     * The repository instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\MigrationRepositoryInterface\n     */\n    protected $repository;\n\n    /**\n     * Create a new migration install command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\MigrationRepositoryInterface  $repository\n     */\n    public function __construct(MigrationRepositoryInterface $repository)\n    {\n        parent::__construct();\n\n        $this->repository = $repository;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->repository->setSource($this->input->getOption('database'));\n\n        if (! $this->repository->repositoryExists()) {\n            $this->repository->createRepository();\n        }\n\n        $this->components->info('Migration table created successfully.');\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/MigrateCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Contracts\\Console\\Isolatable;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Events\\SchemaLoaded;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Database\\SQLiteDatabaseDoesNotExistException;\nuse Illuminate\\Database\\SqlServerConnection;\nuse Illuminate\\Support\\Str;\nuse PDOException;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Throwable;\n\nuse function Laravel\\Prompts\\confirm;\n\n#[AsCommand(name: 'migrate')]\nclass MigrateCommand extends BaseCommand implements Isolatable\n{\n    use ConfirmableTrait;\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'migrate {--database= : The database connection to use}\n                {--force : Force the operation to run when in production}\n                {--path=* : The path(s) to the migrations files to be executed}\n                {--realpath : Indicate any provided migration file paths are pre-resolved absolute paths}\n                {--schema-path= : The path to a schema dump file}\n                {--pretend : Dump the SQL queries that would be run}\n                {--seed : Indicates if the seed task should be re-run}\n                {--seeder= : The class name of the root seeder}\n                {--step : Force the migrations to be run so they can be rolled back individually}\n                {--graceful : Return a successful exit code even if an error occurs}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Run the database migrations';\n\n    /**\n     * The migrator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migrator\n     */\n    protected $migrator;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $dispatcher;\n\n    /**\n     * Create a new migration command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migrator  $migrator\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     */\n    public function __construct(Migrator $migrator, Dispatcher $dispatcher)\n    {\n        parent::__construct();\n\n        $this->migrator = $migrator;\n        $this->dispatcher = $dispatcher;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    public function handle()\n    {\n        if (! $this->confirmToProceed()) {\n            return 1;\n        }\n\n        try {\n            $this->runMigrations();\n        } catch (Throwable $e) {\n            if ($this->option('graceful')) {\n                $this->components->warn($e->getMessage());\n\n                return 0;\n            }\n\n            throw $e;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Run the pending migrations.\n     *\n     * @return void\n     */\n    protected function runMigrations()\n    {\n        $this->migrator->usingConnection($this->option('database'), function () {\n            $this->prepareDatabase();\n\n            // Next, we will check to see if a path option has been defined. If it has\n            // we will use the path relative to the root of this installation folder\n            // so that migrations may be run for any path within the applications.\n            $this->migrator->setOutput($this->output)\n                ->run($this->getMigrationPaths(), [\n                    'pretend' => $this->option('pretend'),\n                    'step' => $this->option('step'),\n                ]);\n\n            // Finally, if the \"seed\" option has been given, we will re-run the database\n            // seed task to re-populate the database, which is convenient when adding\n            // a migration and a seed at the same time, as it is only this command.\n            if ($this->option('seed') && ! $this->option('pretend')) {\n                $this->call('db:seed', [\n                    '--class' => $this->option('seeder') ?: 'Database\\\\Seeders\\\\DatabaseSeeder',\n                    '--force' => true,\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Prepare the migration database for running.\n     *\n     * @return void\n     */\n    protected function prepareDatabase()\n    {\n        if (! $this->repositoryExists()) {\n            $this->components->info('Preparing database.');\n\n            $this->components->task('Creating migration table', function () {\n                return $this->callSilent('migrate:install', array_filter([\n                    '--database' => $this->option('database'),\n                ])) == 0;\n            });\n\n            $this->newLine();\n        }\n\n        if (! $this->migrator->hasRunAnyMigrations() && ! $this->option('pretend')) {\n            $this->loadSchemaState();\n        }\n    }\n\n    /**\n     * Determine if the migrator repository exists.\n     *\n     * @return bool\n     */\n    protected function repositoryExists()\n    {\n        return retry(2, fn () => $this->migrator->repositoryExists(), 0, function ($e) {\n            try {\n                return $this->handleMissingDatabase($e->getPrevious());\n            } catch (Throwable) {\n                return false;\n            }\n        });\n    }\n\n    /**\n     * Attempt to create the database if it is missing.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function handleMissingDatabase(Throwable $e)\n    {\n        if ($e instanceof SQLiteDatabaseDoesNotExistException) {\n            return $this->createMissingSqliteDatabase($e->path);\n        }\n\n        $connection = $this->migrator->resolveConnection($this->option('database'));\n\n        if (! $e instanceof PDOException) {\n            return false;\n        }\n\n        if (($e->getCode() === 1049 && in_array($connection->getDriverName(), ['mysql', 'mariadb'])) ||\n            (($e->errorInfo[0] ?? null) == '08006' &&\n              $connection->getDriverName() == 'pgsql' &&\n              Str::contains($e->getMessage(), '\"'.$connection->getDatabaseName().'\"'))) {\n            return $this->createMissingMySqlOrPgsqlDatabase($connection);\n        }\n\n        return false;\n    }\n\n    /**\n     * Create a missing SQLite database.\n     *\n     * @param  string  $path\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    protected function createMissingSqliteDatabase($path)\n    {\n        if ($this->option('force')) {\n            return touch($path);\n        }\n\n        if ($this->option('no-interaction')) {\n            return false;\n        }\n\n        $this->components->warn('The SQLite database configured for this application does not exist: '.$path);\n\n        if (! confirm('Would you like to create it?', default: true)) {\n            $this->components->info('Operation cancelled. No database was created.');\n\n            throw new RuntimeException('Database was not created. Aborting migration.');\n        }\n\n        return touch($path);\n    }\n\n    /**\n     * Create a missing MySQL or Postgres database.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    protected function createMissingMySqlOrPgsqlDatabase($connection)\n    {\n        if ($this->laravel['config']->get(\"database.connections.{$connection->getName()}.database\") !== $connection->getDatabaseName()) {\n            return false;\n        }\n\n        if (! $this->option('force') && $this->option('no-interaction')) {\n            return false;\n        }\n\n        if (! $this->option('force') && ! $this->option('no-interaction')) {\n            $this->components->warn(\"The database '{$connection->getDatabaseName()}' does not exist on the '{$connection->getName()}' connection.\");\n\n            if (! confirm('Would you like to create it?', default: true)) {\n                $this->components->info('Operation cancelled. No database was created.');\n\n                throw new RuntimeException('Database was not created. Aborting migration.');\n            }\n        }\n        try {\n            $this->laravel['config']->set(\n                \"database.connections.{$connection->getName()}.database\",\n                match ($connection->getDriverName()) {\n                    'mysql', 'mariadb' => null,\n                    'pgsql' => 'postgres',\n                },\n            );\n\n            $this->laravel['db']->purge();\n\n            $freshConnection = $this->migrator->resolveConnection($this->option('database'));\n\n            return tap($freshConnection->unprepared(\n                match ($connection->getDriverName()) {\n                    'mysql', 'mariadb' => \"CREATE DATABASE IF NOT EXISTS `{$connection->getDatabaseName()}`\",\n                    'pgsql' => 'CREATE DATABASE \"'.$connection->getDatabaseName().'\"',\n                }\n            ), function () {\n                $this->laravel['db']->purge();\n            });\n        } finally {\n            $this->laravel['config']->set(\"database.connections.{$connection->getName()}.database\", $connection->getDatabaseName());\n        }\n    }\n\n    /**\n     * Load the schema state to seed the initial database schema structure.\n     *\n     * @return void\n     */\n    protected function loadSchemaState()\n    {\n        $connection = $this->migrator->resolveConnection($this->option('database'));\n\n        // First, we will make sure that the connection supports schema loading and that\n        // the schema file exists before we proceed any further. If not, we will just\n        // continue with the standard migration operation as normal without errors.\n        if ($connection instanceof SqlServerConnection ||\n            ! is_file($path = $this->schemaPath($connection))) {\n            return;\n        }\n\n        $this->components->info('Loading stored database schemas.');\n\n        $this->components->task($path, function () use ($connection, $path) {\n            // Since the schema file will create the \"migrations\" table and reload it to its\n            // proper state, we need to delete it here so we don't get an error that this\n            // table already exists when the stored database schema file gets executed.\n            $this->migrator->deleteRepository();\n\n            $connection->getSchemaState()->handleOutputUsing(function ($type, $buffer) {\n                $this->output->write($buffer);\n            })->load($path);\n        });\n\n        $this->newLine();\n\n        // Finally, we will fire an event that this schema has been loaded so developers\n        // can perform any post schema load tasks that are necessary in listeners for\n        // this event, which may seed the database tables with some necessary data.\n        $this->dispatcher->dispatch(\n            new SchemaLoaded($connection, $path)\n        );\n    }\n\n    /**\n     * Get the path to the stored schema for the given connection.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return string\n     */\n    protected function schemaPath($connection)\n    {\n        if ($this->option('schema-path')) {\n            return $this->option('schema-path');\n        }\n\n        if (file_exists($path = database_path('schema/'.$connection->getName().'-schema.dump'))) {\n            return $path;\n        }\n\n        return database_path('schema/'.$connection->getName().'-schema.sql');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput;\nuse Illuminate\\Database\\Migrations\\MigrationCreator;\nuse Illuminate\\Support\\Composer;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'make:migration')]\nclass MigrateMakeCommand extends BaseCommand implements PromptsForMissingInput\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'make:migration {name : The name of the migration}\n        {--create= : The table to be created}\n        {--table= : The table to migrate}\n        {--path= : The location where the migration file should be created}\n        {--realpath : Indicate any provided migration file paths are pre-resolved absolute paths}\n        {--fullpath : Output the full path of the migration (Deprecated)}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new migration file';\n\n    /**\n     * The migration creator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\MigrationCreator\n     */\n    protected $creator;\n\n    /**\n     * The Composer instance.\n     *\n     * @var \\Illuminate\\Support\\Composer\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     */\n    protected $composer;\n\n    /**\n     * Create a new migration install command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\MigrationCreator  $creator\n     * @param  \\Illuminate\\Support\\Composer  $composer\n     */\n    public function __construct(MigrationCreator $creator, Composer $composer)\n    {\n        parent::__construct();\n\n        $this->creator = $creator;\n        $this->composer = $composer;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        // It's possible for the developer to specify the tables to modify in this\n        // schema operation. The developer may also specify if this table needs\n        // to be freshly created so we can create the appropriate migrations.\n        $name = Str::snake(trim($this->input->getArgument('name')));\n\n        $table = $this->input->getOption('table');\n\n        $create = $this->input->getOption('create') ?: false;\n\n        // If no table was given as an option but a create option is given then we\n        // will use the \"create\" option as the table name. This allows the devs\n        // to pass a table name into this option as a short-cut for creating.\n        if (! $table && is_string($create)) {\n            $table = $create;\n\n            $create = true;\n        }\n\n        // Next, we will attempt to guess the table name if this the migration has\n        // \"create\" in the name. This will allow us to provide a convenient way\n        // of creating migrations that create new tables for the application.\n        if (! $table) {\n            [$table, $create] = TableGuesser::guess($name);\n        }\n\n        // Now we are ready to write the migration out to disk. Once we've written\n        // the migration out, we will dump-autoload for the entire framework to\n        // make sure that the migrations are registered by the class loaders.\n        $this->writeMigration($name, $table, $create);\n    }\n\n    /**\n     * Write the migration file to disk.\n     *\n     * @param  string  $name\n     * @param  string  $table\n     * @param  bool  $create\n     * @return void\n     */\n    protected function writeMigration($name, $table, $create)\n    {\n        $file = $this->creator->create(\n            $name, $this->getMigrationPath(), $table, $create\n        );\n\n        if (windows_os()) {\n            $file = str_replace('/', '\\\\', $file);\n        }\n\n        $this->components->info(sprintf('Migration [%s] created successfully.', $file));\n    }\n\n    /**\n     * Get migration path (either specified by '--path' option or default location).\n     *\n     * @return string\n     */\n    protected function getMigrationPath()\n    {\n        if (! is_null($targetPath = $this->input->getOption('path'))) {\n            return ! $this->usingRealPath()\n                ? $this->laravel->basePath().'/'.$targetPath\n                : $targetPath;\n        }\n\n        return parent::getMigrationPath();\n    }\n\n    /**\n     * Prompt for missing input arguments using the returned questions.\n     *\n     * @return array\n     */\n    protected function promptForMissingArgumentsUsing()\n    {\n        return [\n            'name' => ['What should the migration be named?', 'E.g. create_flights_table'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/RefreshCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Events\\DatabaseRefreshed;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'migrate:refresh')]\nclass RefreshCommand extends Command\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:refresh';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Reset and re-run all migrations';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        // Next we'll gather some of the options so that we can have the right options\n        // to pass to the commands. This includes options such as which database to\n        // use and the path to use for the migration. Then we'll run the command.\n        $database = $this->input->getOption('database');\n\n        $path = $this->input->getOption('path');\n\n        // If the \"step\" option is specified it means we only want to rollback a small\n        // number of migrations before migrating again. For example, the user might\n        // only rollback and remigrate the latest four migrations instead of all.\n        $step = $this->input->getOption('step') ?: 0;\n\n        if ($step > 0) {\n            $this->runRollback($database, $path, $step);\n        } else {\n            $this->runReset($database, $path);\n        }\n\n        // The refresh command is essentially just a brief aggregate of a few other of\n        // the migration commands and just provides a convenient wrapper to execute\n        // them in succession. We'll also see if we need to re-seed the database.\n        $this->call('migrate', array_filter([\n            '--database' => $database,\n            '--path' => $path,\n            '--realpath' => $this->input->getOption('realpath'),\n            '--force' => true,\n        ]));\n\n        if ($this->laravel->bound(Dispatcher::class)) {\n            $this->laravel[Dispatcher::class]->dispatch(\n                new DatabaseRefreshed($database, $this->needsSeeding())\n            );\n        }\n\n        if ($this->needsSeeding()) {\n            $this->runSeeder($database);\n        }\n\n        return 0;\n    }\n\n    /**\n     * Run the rollback command.\n     *\n     * @param  string  $database\n     * @param  string  $path\n     * @param  int  $step\n     * @return void\n     */\n    protected function runRollback($database, $path, $step)\n    {\n        $this->call('migrate:rollback', array_filter([\n            '--database' => $database,\n            '--path' => $path,\n            '--realpath' => $this->input->getOption('realpath'),\n            '--step' => $step,\n            '--force' => true,\n        ]));\n    }\n\n    /**\n     * Run the reset command.\n     *\n     * @param  string  $database\n     * @param  string  $path\n     * @return void\n     */\n    protected function runReset($database, $path)\n    {\n        $this->call('migrate:reset', array_filter([\n            '--database' => $database,\n            '--path' => $path,\n            '--realpath' => $this->input->getOption('realpath'),\n            '--force' => true,\n        ]));\n    }\n\n    /**\n     * Determine if the developer has requested database seeding.\n     *\n     * @return bool\n     */\n    protected function needsSeeding()\n    {\n        return $this->option('seed') || $this->option('seeder');\n    }\n\n    /**\n     * Run the database seeder command.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function runSeeder($database)\n    {\n        $this->call('db:seed', array_filter([\n            '--database' => $database,\n            '--class' => $this->option('seeder') ?: 'Database\\\\Seeders\\\\DatabaseSeeder',\n            '--force' => true,\n        ]));\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],\n            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],\n            ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run'],\n            ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder'],\n            ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted & re-run'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/ResetCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'migrate:reset')]\nclass ResetCommand extends BaseCommand\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:reset';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Rollback all database migrations';\n\n    /**\n     * The migrator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migrator\n     */\n    protected $migrator;\n\n    /**\n     * Create a new migration rollback command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migrator  $migrator\n     */\n    public function __construct(Migrator $migrator)\n    {\n        parent::__construct();\n\n        $this->migrator = $migrator;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        return $this->migrator->usingConnection($this->option('database'), function () {\n            // First, we'll make sure that the migration table actually exists before we\n            // start trying to rollback and re-run all of the migrations. If it's not\n            // present we'll just bail out with an info message for the developers.\n            if (! $this->migrator->repositoryExists()) {\n                return $this->components->warn('Migration table not found.');\n            }\n\n            $this->migrator->setOutput($this->output)->reset(\n                $this->getMigrationPaths(), $this->option('pretend')\n            );\n        });\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n\n            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],\n\n            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],\n\n            ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/RollbackCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand('migrate:rollback')]\nclass RollbackCommand extends BaseCommand\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:rollback';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Rollback the last database migration';\n\n    /**\n     * The migrator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migrator\n     */\n    protected $migrator;\n\n    /**\n     * Create a new migration rollback command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migrator  $migrator\n     */\n    public function __construct(Migrator $migrator)\n    {\n        parent::__construct();\n\n        $this->migrator = $migrator;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        $this->migrator->usingConnection($this->option('database'), function () {\n            $this->migrator->setOutput($this->output)->rollback(\n                $this->getMigrationPaths(), [\n                    'pretend' => $this->option('pretend'),\n                    'step' => (int) $this->option('step'),\n                    'batch' => (int) $this->option('batch'),\n                ]\n            );\n        });\n\n        return 0;\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],\n            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],\n            ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'],\n            ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted'],\n            ['batch', null, InputOption::VALUE_REQUIRED, 'The batch of migrations (identified by their batch number) to be reverted'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/StatusCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'migrate:status')]\nclass StatusCommand extends BaseCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'migrate:status';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Show the status of each migration';\n\n    /**\n     * The migrator instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migrator\n     */\n    protected $migrator;\n\n    /**\n     * Create a new migration rollback command instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migrator  $migrator\n     */\n    public function __construct(Migrator $migrator)\n    {\n        parent::__construct();\n\n        $this->migrator = $migrator;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int|null\n     */\n    public function handle()\n    {\n        return $this->migrator->usingConnection($this->option('database'), function () {\n            if (! $this->migrator->repositoryExists()) {\n                $this->components->error('Migration table not found.');\n\n                return 1;\n            }\n\n            $ran = $this->migrator->getRepository()->getRan();\n\n            $batches = $this->migrator->getRepository()->getMigrationBatches();\n\n            $migrations = $this->getStatusFor($ran, $batches)\n                ->when($this->option('pending') !== false, fn ($collection) => $collection->filter(function ($migration) {\n                    return (new Stringable($migration[1]))->contains('Pending');\n                }));\n\n            if (count($migrations) > 0) {\n                $this->newLine();\n\n                $this->components->twoColumnDetail('<fg=gray>Migration name</>', '<fg=gray>Batch / Status</>');\n\n                $migrations\n                    ->each(\n                        fn ($migration) => $this->components->twoColumnDetail($migration[0], $migration[1])\n                    );\n\n                $this->newLine();\n            } elseif ($this->option('pending') !== false) {\n                $this->components->info('No pending migrations');\n            } else {\n                $this->components->info('No migrations found');\n            }\n\n            if ($this->option('pending') && $migrations->some(fn ($m) => (new Stringable($m[1]))->contains('Pending'))) {\n                return $this->option('pending');\n            }\n        });\n    }\n\n    /**\n     * Get the status for the given run migrations.\n     *\n     * @param  array  $ran\n     * @param  array  $batches\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getStatusFor(array $ran, array $batches)\n    {\n        return (new Collection($this->getAllMigrationFiles()))\n            ->map(function ($migration) use ($ran, $batches) {\n                $migrationName = $this->migrator->getMigrationName($migration);\n\n                $status = in_array($migrationName, $ran)\n                    ? '<fg=green;options=bold>Ran</>'\n                    : '<fg=yellow;options=bold>Pending</>';\n\n                if (in_array($migrationName, $ran)) {\n                    $status = '['.$batches[$migrationName].'] '.$status;\n                }\n\n                return [$migrationName, $status];\n            });\n    }\n\n    /**\n     * Get an array of all of the migration files.\n     *\n     * @return array\n     */\n    protected function getAllMigrationFiles()\n    {\n        return $this->migrator->getMigrationFiles($this->getMigrationPaths());\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n            ['pending', null, InputOption::VALUE_OPTIONAL, 'Only list pending migrations', false],\n            ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to use'],\n            ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Migrations/TableGuesser.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Migrations;\n\nclass TableGuesser\n{\n    const CREATE_PATTERNS = [\n        '/^create_(\\w+)_table$/',\n        '/^create_(\\w+)$/',\n    ];\n\n    const CHANGE_PATTERNS = [\n        '/.+_(to|from|in)_(\\w+)_table$/',\n        '/.+_(to|from|in)_(\\w+)$/',\n    ];\n\n    /**\n     * Attempt to guess the table name and \"creation\" status of the given migration.\n     *\n     * @param  string  $migration\n     * @return array{string, bool}\n     */\n    public static function guess($migration)\n    {\n        foreach (self::CREATE_PATTERNS as $pattern) {\n            if (preg_match($pattern, $migration, $matches)) {\n                return [$matches[1], $create = true];\n            }\n        }\n\n        foreach (self::CHANGE_PATTERNS as $pattern) {\n            if (preg_match($pattern, $migration, $matches)) {\n                return [$matches[2], $create = false];\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/MonitorCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Events\\DatabaseBusy;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'db:monitor')]\nclass MonitorCommand extends DatabaseInspectionCommand\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'db:monitor\n                {--databases= : The database connections to monitor}\n                {--max= : The maximum number of connections that can be open before an event is dispatched}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Monitor the number of connections on the specified database';\n\n    /**\n     * The connection resolver instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $connection;\n\n    /**\n     * The events dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $connection\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     */\n    public function __construct(ConnectionResolverInterface $connection, Dispatcher $events)\n    {\n        parent::__construct();\n\n        $this->connection = $connection;\n        $this->events = $events;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $databases = $this->parseDatabases($this->option('databases'));\n\n        $this->displayConnections($databases);\n\n        if ($this->option('max')) {\n            $this->dispatchEvents($databases);\n        }\n    }\n\n    /**\n     * Parse the database into an array of the connections.\n     *\n     * @param  string  $databases\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function parseDatabases($databases)\n    {\n        return (new Collection(explode(',', $databases)))->map(function ($database) {\n            if (! $database) {\n                $database = $this->laravel['config']['database.default'];\n            }\n\n            $maxConnections = $this->option('max');\n\n            $connections = $this->connection->connection($database)->threadCount();\n\n            return [\n                'database' => $database,\n                'connections' => $connections,\n                'status' => $maxConnections && $connections >= $maxConnections ? '<fg=yellow;options=bold>ALERT</>' : '<fg=green;options=bold>OK</>',\n            ];\n        });\n    }\n\n    /**\n     * Display the databases and their connection counts in the console.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $databases\n     * @return void\n     */\n    protected function displayConnections($databases)\n    {\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=gray>Database name</>', '<fg=gray>Connections</>');\n\n        $databases->each(function ($database) {\n            $status = '['.$database['connections'].'] '.$database['status'];\n\n            $this->components->twoColumnDetail($database['database'], $status);\n        });\n\n        $this->newLine();\n    }\n\n    /**\n     * Dispatch the database monitoring events.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $databases\n     * @return void\n     */\n    protected function dispatchEvents($databases)\n    {\n        $databases->each(function ($database) {\n            if ($database['status'] === '<fg=green;options=bold>OK</>') {\n                return;\n            }\n\n            $this->events->dispatch(\n                new DatabaseBusy(\n                    $database['database'],\n                    $database['connections']\n                )\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/PruneCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Events\\ModelPruningFinished;\nuse Illuminate\\Database\\Events\\ModelPruningStarting;\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Finder\\Finder;\n\n#[AsCommand(name: 'model:prune')]\nclass PruneCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'model:prune\n                                {--model=* : Class names of the models to be pruned}\n                                {--except=* : Class names of the models to be excluded from pruning}\n                                {--path=* : Absolute path(s) to directories where models are located}\n                                {--chunk=1000 : The number of models to retrieve per chunk of models to be deleted}\n                                {--pretend : Display the number of prunable records found instead of deleting them}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Prune models that are no longer needed';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return void\n     */\n    public function handle(Dispatcher $events)\n    {\n        $models = $this->models();\n\n        if ($models->isEmpty()) {\n            $this->components->info('No prunable models found.');\n\n            return;\n        }\n\n        if ($this->option('pretend')) {\n            $models->each(function ($model) {\n                $this->pretendToPrune($model);\n            });\n\n            return;\n        }\n\n        $pruning = [];\n\n        $events->listen(ModelsPruned::class, function ($event) use (&$pruning) {\n            if (! in_array($event->model, $pruning)) {\n                $pruning[] = $event->model;\n\n                $this->newLine();\n\n                $this->components->info(sprintf('Pruning [%s] records.', $event->model));\n            }\n\n            $this->components->twoColumnDetail($event->model, \"{$event->count} records\");\n        });\n\n        $events->dispatch(new ModelPruningStarting($models->all()));\n\n        $models->each(function ($model) {\n            $this->pruneModel($model);\n        });\n\n        $events->dispatch(new ModelPruningFinished($models->all()));\n\n        $events->forget(ModelsPruned::class);\n    }\n\n    /**\n     * Prune the given model.\n     *\n     * @param  string  $model\n     * @return void\n     */\n    protected function pruneModel(string $model)\n    {\n        $instance = new $model;\n\n        $chunkSize = property_exists($instance, 'prunableChunkSize')\n            ? $instance->prunableChunkSize\n            : $this->option('chunk');\n\n        $total = $model::isPrunable()\n            ? $instance->pruneAll($chunkSize)\n            : 0;\n\n        if ($total == 0) {\n            $this->components->info(\"No prunable [$model] records found.\");\n        }\n    }\n\n    /**\n     * Determine the models that should be pruned.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function models()\n    {\n        $models = $this->option('model');\n        $except = $this->option('except');\n\n        if ($models && $except) {\n            throw new InvalidArgumentException('The --models and --except options cannot be combined.');\n        }\n\n        if ($models) {\n            return (new Collection($models))\n                ->filter(static fn (string $model) => class_exists($model))\n                ->values();\n        }\n\n        return (new Collection(Finder::create()->in($this->getPath())->files()->name('*.php')))\n            ->map(function ($model) {\n                $namespace = $this->laravel->getNamespace();\n\n                return $namespace.str_replace(\n                    ['/', '.php'],\n                    ['\\\\', ''],\n                    Str::after($model->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)\n                );\n            })\n            ->when(! empty($except), fn ($models) => $models->reject(fn ($model) => in_array($model, $except)))\n            ->filter(fn ($model) => $this->isPrunable($model))\n            ->values();\n    }\n\n    /**\n     * Get the path where models are located.\n     *\n     * @return string[]|string\n     */\n    protected function getPath()\n    {\n        if (! empty($path = $this->option('path'))) {\n            return (new Collection($path))\n                ->map(fn ($path) => base_path($path))\n                ->all();\n        }\n\n        return app_path('Models');\n    }\n\n    /**\n     * Display how many models will be pruned.\n     *\n     * @param  class-string  $model\n     * @return void\n     */\n    protected function pretendToPrune($model)\n    {\n        $instance = new $model;\n\n        $count = $instance->prunable()\n            ->when($model::isSoftDeletable(), function ($query) {\n                $query->withTrashed();\n            })->count();\n\n        if ($count === 0) {\n            $this->components->info(\"No prunable [$model] records found.\");\n        } else {\n            $this->components->info(\"{$count} [{$model}] records will be pruned.\");\n        }\n    }\n\n    /**\n     * Determine if the given model is prunable.\n     *\n     * @param  string  $model\n     * @return bool\n     */\n    protected function isPrunable(string $model)\n    {\n        return class_exists($model)\n            && is_a($model, Model::class, true)\n            && ! (new \\ReflectionClass($model))->isAbstract()\n            && $model::isPrunable();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Seeds/SeedCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Seeds;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Illuminate\\Database\\ConnectionResolverInterface as Resolver;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'db:seed')]\nclass SeedCommand extends Command\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'db:seed';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Seed the database with records';\n\n    /**\n     * The connection resolver instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $resolver;\n\n    /**\n     * Create a new database seed command instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     */\n    public function __construct(Resolver $resolver)\n    {\n        parent::__construct();\n\n        $this->resolver = $resolver;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        $this->components->info('Seeding database.');\n\n        $previousConnection = $this->resolver->getDefaultConnection();\n\n        $this->resolver->setDefaultConnection($this->getDatabase());\n\n        Model::unguarded(function () {\n            $this->getSeeder()->__invoke();\n        });\n\n        if ($previousConnection) {\n            $this->resolver->setDefaultConnection($previousConnection);\n        }\n\n        return 0;\n    }\n\n    /**\n     * Get a seeder instance from the container.\n     *\n     * @return \\Illuminate\\Database\\Seeder\n     */\n    protected function getSeeder()\n    {\n        $class = $this->input->getArgument('class') ?? $this->input->getOption('class');\n\n        if (! str_contains($class, '\\\\')) {\n            $class = 'Database\\\\Seeders\\\\'.$class;\n        }\n\n        if ($class === 'Database\\\\Seeders\\\\DatabaseSeeder' &&\n            ! class_exists($class)) {\n            $class = 'DatabaseSeeder';\n        }\n\n        return $this->laravel->make($class)\n            ->setContainer($this->laravel)\n            ->setCommand($this);\n    }\n\n    /**\n     * Get the name of the database connection to use.\n     *\n     * @return string\n     */\n    protected function getDatabase()\n    {\n        $database = $this->input->getOption('database');\n\n        return $database ?: $this->laravel['config']['database.default'];\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getArguments()\n    {\n        return [\n            ['class', InputArgument::OPTIONAL, 'The class name of the root seeder', null],\n        ];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder', 'Database\\\\Seeders\\\\DatabaseSeeder'],\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'],\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Seeds/SeederMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Seeds;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'make:seeder')]\nclass SeederMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:seeder';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new seeder class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Seeder';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        parent::handle();\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/seeder.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return is_file($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the destination class path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getPath($name)\n    {\n        $name = str_replace('\\\\', '/', Str::replaceFirst($this->rootNamespace(), '', $name));\n\n        if (is_dir($this->laravel->databasePath().'/seeds')) {\n            return $this->laravel->databasePath().'/seeds/'.$name.'.php';\n        }\n\n        return $this->laravel->databasePath().'/seeders/'.$name.'.php';\n    }\n\n    /**\n     * Get the root namespace for the class.\n     *\n     * @return string\n     */\n    protected function rootNamespace()\n    {\n        return 'Database\\Seeders\\\\';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console\\Seeds;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ntrait WithoutModelEvents\n{\n    /**\n     * Prevent model events from being dispatched by the given callback.\n     *\n     * @param  callable  $callback\n     * @return callable\n     */\n    public function withoutModelEvents(callable $callback)\n    {\n        return fn () => Model::withoutEvents($callback);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/Seeds/stubs/seeder.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Console\\Seeds\\WithoutModelEvents;\nuse Illuminate\\Database\\Seeder;\n\nclass {{ class }} extends Seeder\n{\n    /**\n     * Run the database seeds.\n     */\n    public function run(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/ShowCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Number;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'db:show')]\nclass ShowCommand extends DatabaseInspectionCommand\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'db:show {--database= : The database connection}\n                {--json : Output the database information as JSON}\n                {--counts : Show the table row count <bg=red;options=bold> Note: This can be slow on large databases </>}\n                {--views : Show the database views <bg=red;options=bold> Note: This can be slow on large databases </>}\n                {--types : Show the user defined types}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Display information about the given database';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $connections\n     * @return int\n     */\n    public function handle(ConnectionResolverInterface $connections)\n    {\n        $connection = $connections->connection($database = $this->input->getOption('database'));\n\n        $schema = $connection->getSchemaBuilder();\n\n        $data = [\n            'platform' => [\n                'config' => $this->getConfigFromDatabase($database),\n                'name' => $connection->getDriverTitle(),\n                'connection' => $connection->getName(),\n                'version' => $connection->getServerVersion(),\n                'open_connections' => $connection->threadCount(),\n            ],\n            'tables' => $this->tables($connection, $schema),\n        ];\n\n        if ($this->option('views')) {\n            $data['views'] = $this->views($connection, $schema);\n        }\n\n        if ($this->option('types')) {\n            $data['types'] = $this->types($connection, $schema);\n        }\n\n        $this->display($data);\n\n        return 0;\n    }\n\n    /**\n     * Get information regarding the tables within the database.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function tables(ConnectionInterface $connection, Builder $schema)\n    {\n        return (new Collection($schema->getTables()))->map(fn ($table) => [\n            'table' => $table['name'],\n            'schema' => $table['schema'],\n            'schema_qualified_name' => $table['schema_qualified_name'],\n            'size' => $table['size'],\n            'rows' => $this->option('counts')\n                ? $connection->withoutTablePrefix(fn ($connection) => $connection->table($table['schema_qualified_name'])->count())\n                : null,\n            'engine' => $table['engine'],\n            'collation' => $table['collation'],\n            'comment' => $table['comment'],\n        ]);\n    }\n\n    /**\n     * Get information regarding the views within the database.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function views(ConnectionInterface $connection, Builder $schema)\n    {\n        return (new Collection($schema->getViews()))\n            ->map(fn ($view) => [\n                'view' => $view['name'],\n                'schema' => $view['schema'],\n                'rows' => $connection->withoutTablePrefix(fn ($connection) => $connection->table($view['schema_qualified_name'])->count()),\n            ]);\n    }\n\n    /**\n     * Get information regarding the user-defined types within the database.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function types(ConnectionInterface $connection, Builder $schema)\n    {\n        return (new Collection($schema->getTypes()))\n            ->map(fn ($type) => [\n                'name' => $type['name'],\n                'schema' => $type['schema'],\n                'type' => $type['type'],\n                'category' => $type['category'],\n            ]);\n    }\n\n    /**\n     * Render the database information.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function display(array $data)\n    {\n        $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data);\n    }\n\n    /**\n     * Render the database information as JSON.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function displayJson(array $data)\n    {\n        $this->output->writeln(json_encode($data));\n    }\n\n    /**\n     * Render the database information formatted for the CLI.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function displayForCli(array $data)\n    {\n        $platform = $data['platform'];\n        $tables = $data['tables'];\n        $views = $data['views'] ?? null;\n        $types = $data['types'] ?? null;\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>'.$platform['name'].'</>', $platform['version']);\n        $this->components->twoColumnDetail('Connection', $platform['connection']);\n        $this->components->twoColumnDetail('Database', Arr::get($platform['config'], 'database'));\n        $this->components->twoColumnDetail('Host', Arr::get($platform['config'], 'host'));\n        $this->components->twoColumnDetail('Port', Arr::get($platform['config'], 'port'));\n        $this->components->twoColumnDetail('Username', Arr::get($platform['config'], 'username'));\n        $this->components->twoColumnDetail('URL', Arr::get($platform['config'], 'url'));\n        $this->components->twoColumnDetail('Open Connections', $platform['open_connections']);\n        $this->components->twoColumnDetail('Tables', $tables->count());\n\n        if ($tableSizeSum = $tables->sum('size')) {\n            $this->components->twoColumnDetail('Total Size', Number::fileSize($tableSizeSum, 2));\n        }\n\n        $this->newLine();\n\n        if ($tables->isNotEmpty()) {\n            $hasSchema = ! is_null($tables->first()['schema']);\n\n            $this->components->twoColumnDetail(\n                ($hasSchema ? '<fg=green;options=bold>Schema</> <fg=gray;options=bold>/</> ' : '').'<fg=green;options=bold>Table</>',\n                'Size'.($this->option('counts') ? ' <fg=gray;options=bold>/</> <fg=yellow;options=bold>Rows</>' : '')\n            );\n\n            $tables->each(function ($table) {\n                $tableSize = is_null($table['size']) ? null : Number::fileSize($table['size'], 2);\n\n                $this->components->twoColumnDetail(\n                    ($table['schema'] ? $table['schema'].' <fg=gray;options=bold>/</> ' : '').$table['table'].($this->output->isVerbose() ? ' <fg=gray>'.$table['engine'].'</>' : null),\n                    ($tableSize ?? '—').($this->option('counts') ? ' <fg=gray;options=bold>/</> <fg=yellow;options=bold>'.Number::format($table['rows']).'</>' : '')\n                );\n\n                if ($this->output->isVerbose()) {\n                    if ($table['comment']) {\n                        $this->components->bulletList([\n                            $table['comment'],\n                        ]);\n                    }\n                }\n            });\n\n            $this->newLine();\n        }\n\n        if ($views && $views->isNotEmpty()) {\n            $hasSchema = ! is_null($views->first()['schema']);\n\n            $this->components->twoColumnDetail(\n                ($hasSchema ? '<fg=green;options=bold>Schema</> <fg=gray;options=bold>/</> ' : '').'<fg=green;options=bold>View</>',\n                '<fg=green;options=bold>Rows</>'\n            );\n\n            $views->each(fn ($view) => $this->components->twoColumnDetail(\n                ($view['schema'] ? $view['schema'].' <fg=gray;options=bold>/</> ' : '').$view['view'],\n                Number::format($view['rows'])\n            ));\n\n            $this->newLine();\n        }\n\n        if ($types && $types->isNotEmpty()) {\n            $hasSchema = ! is_null($types->first()['schema']);\n\n            $this->components->twoColumnDetail(\n                ($hasSchema ? '<fg=green;options=bold>Schema</> <fg=gray;options=bold>/</> ' : '').'<fg=green;options=bold>Type</>',\n                '<fg=green;options=bold>Type</> <fg=gray;options=bold>/</> <fg=green;options=bold>Category</>'\n            );\n\n            $types->each(fn ($type) => $this->components->twoColumnDetail(\n                ($type['schema'] ? $type['schema'].' <fg=gray;options=bold>/</> ' : '').$type['name'],\n                $type['type'].' <fg=gray;options=bold>/</> '.$type['category']\n            ));\n\n            $this->newLine();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/ShowModelCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Concerns\\FindsAvailableModels;\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Database\\Eloquent\\ModelInfo;\nuse Illuminate\\Database\\Eloquent\\ModelInspector;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'model:show')]\nclass ShowModelCommand extends DatabaseInspectionCommand implements PromptsForMissingInput\n{\n    use FindsAvailableModels;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'model:show {model}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Show information about an Eloquent model';\n\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'model:show {model : The model to show}\n                {--database= : The database connection to use}\n                {--json : Output the model as JSON}';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(ModelInspector $modelInspector)\n    {\n        try {\n            $info = $modelInspector->inspect(\n                $this->argument('model'),\n                $this->option('database')\n            );\n        } catch (BindingResolutionException $e) {\n            $this->components->error($e->getMessage());\n\n            return 1;\n        }\n\n        $this->display($info);\n\n        return 0;\n    }\n\n    /**\n     * Render the model information.\n     *\n     * @return void\n     */\n    protected function display(ModelInfo $modelData)\n    {\n        $this->option('json')\n            ? $this->displayJson($modelData)\n            : $this->displayCli($modelData);\n    }\n\n    /**\n     * Render the model information as JSON.\n     *\n     * @return void\n     */\n    protected function displayJson(ModelInfo $modelData)\n    {\n        $this->output->writeln(\n            (new Collection($modelData))->toJson()\n        );\n    }\n\n    /**\n     * Render the model information for the CLI.\n     *\n     * @return void\n     */\n    protected function displayCli(ModelInfo $modelData)\n    {\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>'.$modelData->class.'</>');\n        $this->components->twoColumnDetail('Database', $modelData->database);\n        $this->components->twoColumnDetail('Table', $modelData->table);\n\n        if ($policy = $modelData->policy ?? false) {\n            $this->components->twoColumnDetail('Policy', $policy);\n        }\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail(\n            '<fg=green;options=bold>Attributes</>',\n            'type <fg=gray>/</> <fg=yellow;options=bold>cast</>',\n        );\n\n        foreach ($modelData->attributes as $attribute) {\n            $first = trim(sprintf(\n                '%s %s',\n                $attribute['name'],\n                (new Collection(['increments', 'unique', 'nullable', 'fillable', 'hidden', 'appended']))\n                    ->filter(fn ($property) => $attribute[$property])\n                    ->map(fn ($property) => sprintf('<fg=gray>%s</>', $property))\n                    ->implode('<fg=gray>,</> ')\n            ));\n\n            $second = (new Collection([\n                $attribute['type'],\n                $attribute['cast'] ? '<fg=yellow;options=bold>'.$attribute['cast'].'</>' : null,\n            ]))->filter()->implode(' <fg=gray>/</> ');\n\n            $this->components->twoColumnDetail($first, $second);\n\n            if ($attribute['default'] !== null) {\n                $this->components->bulletList(\n                    [sprintf('default: %s', $attribute['default'])],\n                    OutputInterface::VERBOSITY_VERBOSE\n                );\n            }\n        }\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>Relations</>');\n\n        foreach ($modelData->relations as $relation) {\n            $this->components->twoColumnDetail(\n                sprintf('%s <fg=gray>%s</>', $relation['name'], $relation['type']),\n                $relation['related']\n            );\n        }\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>Events</>');\n\n        if ($modelData->events->count()) {\n            foreach ($modelData->events as $event) {\n                $this->components->twoColumnDetail(\n                    sprintf('%s', $event['event']),\n                    sprintf('%s', $event['class']),\n                );\n            }\n        }\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>Observers</>');\n\n        if ($modelData->observers->count()) {\n            foreach ($modelData->observers as $observer) {\n                $this->components->twoColumnDetail(\n                    sprintf('%s', $observer['event']),\n                    implode(', ', $observer['observer'])\n                );\n            }\n        }\n\n        $this->newLine();\n    }\n\n    /**\n     * Prompt for missing input arguments using the returned questions.\n     *\n     * @return array<string, \\Closure(): string>\n     */\n    protected function promptForMissingArgumentsUsing(): array\n    {\n        return [\n            'model' => fn (): string => suggest('Which model would you like to show?', $this->findAvailableModels()),\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/TableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Number;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Laravel\\Prompts\\search;\n\n#[AsCommand(name: 'db:table')]\nclass TableCommand extends DatabaseInspectionCommand\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'db:table\n                            {table? : The name of the table}\n                            {--database= : The database connection}\n                            {--json : Output the table information as JSON}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Display information about the given database table';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(ConnectionResolverInterface $connections)\n    {\n        $connection = $connections->connection($this->input->getOption('database'));\n        $tables = (new Collection($connection->getSchemaBuilder()->getTables()))\n            ->keyBy('schema_qualified_name')->all();\n\n        $tableNames = (new Collection($tables))->keys();\n\n        $tableName = $this->argument('table') ?: search(\n            'Which table would you like to inspect?',\n            fn (string $query) => $tableNames\n                ->filter(fn ($table) => str_contains(strtolower($table), strtolower($query)))\n                ->values()\n                ->all()\n        );\n\n        $table = $tables[$tableName] ?? (new Collection($tables))->when(\n            Arr::wrap($connection->getSchemaBuilder()->getCurrentSchemaListing()\n                ?? $connection->getSchemaBuilder()->getCurrentSchemaName()),\n            fn (Collection $collection, array $currentSchemas) => $collection->sortBy(\n                function (array $table) use ($currentSchemas) {\n                    $index = array_search($table['schema'], $currentSchemas);\n\n                    return $index === false ? PHP_INT_MAX : $index;\n                }\n            )\n        )->firstWhere('name', $tableName);\n\n        if (! $table) {\n            $this->components->warn(\"Table [{$tableName}] doesn't exist.\");\n\n            return 1;\n        }\n\n        [$columns, $indexes, $foreignKeys] = $connection->withoutTablePrefix(function ($connection) use ($table) {\n            $schema = $connection->getSchemaBuilder();\n            $tableName = $table['schema_qualified_name'];\n\n            return [\n                $this->columns($schema, $tableName),\n                $this->indexes($schema, $tableName),\n                $this->foreignKeys($schema, $tableName),\n            ];\n        });\n\n        $data = [\n            'table' => [\n                'schema' => $table['schema'],\n                'name' => $table['name'],\n                'schema_qualified_name' => $table['schema_qualified_name'],\n                'columns' => count($columns),\n                'size' => $table['size'],\n                'comment' => $table['comment'],\n                'collation' => $table['collation'],\n                'engine' => $table['engine'],\n            ],\n            'columns' => $columns,\n            'indexes' => $indexes,\n            'foreign_keys' => $foreignKeys,\n        ];\n\n        $this->display($data);\n\n        return 0;\n    }\n\n    /**\n     * Get the information regarding the table's columns.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @param  string  $table\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function columns(Builder $schema, string $table)\n    {\n        return (new Collection($schema->getColumns($table)))->map(fn ($column) => [\n            'column' => $column['name'],\n            'attributes' => $this->getAttributesForColumn($column),\n            'default' => $column['default'],\n            'type' => $column['type'],\n        ]);\n    }\n\n    /**\n     * Get the attributes for a table column.\n     *\n     * @param  array  $column\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getAttributesForColumn($column)\n    {\n        return (new Collection([\n            $column['type_name'],\n            $column['generation'] ? $column['generation']['type'] : null,\n            $column['auto_increment'] ? 'autoincrement' : null,\n            $column['nullable'] ? 'nullable' : null,\n            $column['collation'],\n        ]))->filter();\n    }\n\n    /**\n     * Get the information regarding the table's indexes.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @param  string  $table\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function indexes(Builder $schema, string $table)\n    {\n        return (new Collection($schema->getIndexes($table)))->map(fn ($index) => [\n            'name' => $index['name'],\n            'columns' => new Collection($index['columns']),\n            'attributes' => $this->getAttributesForIndex($index),\n        ]);\n    }\n\n    /**\n     * Get the attributes for a table index.\n     *\n     * @param  array  $index\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getAttributesForIndex($index)\n    {\n        return (new Collection([\n            $index['type'],\n            count($index['columns']) > 1 ? 'compound' : null,\n            $index['unique'] && ! $index['primary'] ? 'unique' : null,\n            $index['primary'] ? 'primary' : null,\n        ]))->filter();\n    }\n\n    /**\n     * Get the information regarding the table's foreign keys.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Builder  $schema\n     * @param  string  $table\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function foreignKeys(Builder $schema, string $table)\n    {\n        return (new Collection($schema->getForeignKeys($table)))->map(fn ($foreignKey) => [\n            'name' => $foreignKey['name'],\n            'columns' => new Collection($foreignKey['columns']),\n            'foreign_schema' => $foreignKey['foreign_schema'],\n            'foreign_table' => $foreignKey['foreign_table'],\n            'foreign_columns' => new Collection($foreignKey['foreign_columns']),\n            'on_update' => $foreignKey['on_update'],\n            'on_delete' => $foreignKey['on_delete'],\n        ]);\n    }\n\n    /**\n     * Render the table information.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function display(array $data)\n    {\n        $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data);\n    }\n\n    /**\n     * Render the table information as JSON.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function displayJson(array $data)\n    {\n        $this->output->writeln(json_encode($data));\n    }\n\n    /**\n     * Render the table information formatted for the CLI.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    protected function displayForCli(array $data)\n    {\n        [$table, $columns, $indexes, $foreignKeys] = [\n            $data['table'], $data['columns'], $data['indexes'], $data['foreign_keys'],\n        ];\n\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=green;options=bold>'.$table['schema_qualified_name'].'</>', $table['comment'] ? '<fg=gray>'.$table['comment'].'</>' : null);\n        $this->components->twoColumnDetail('Columns', $table['columns']);\n\n        if (! is_null($table['size'])) {\n            $this->components->twoColumnDetail('Size', Number::fileSize($table['size'], 2));\n        }\n\n        if ($table['engine']) {\n            $this->components->twoColumnDetail('Engine', $table['engine']);\n        }\n\n        if ($table['collation']) {\n            $this->components->twoColumnDetail('Collation', $table['collation']);\n        }\n\n        $this->newLine();\n\n        if ($columns->isNotEmpty()) {\n            $this->components->twoColumnDetail('<fg=green;options=bold>Column</>', 'Type');\n\n            $columns->each(function ($column) {\n                $this->components->twoColumnDetail(\n                    $column['column'].' <fg=gray>'.$column['attributes']->implode(', ').'</>',\n                    (! is_null($column['default']) ? '<fg=gray>'.$column['default'].'</> ' : '').$column['type']\n                );\n            });\n\n            $this->newLine();\n        }\n\n        if ($indexes->isNotEmpty()) {\n            $this->components->twoColumnDetail('<fg=green;options=bold>Index</>');\n\n            $indexes->each(function ($index) {\n                $this->components->twoColumnDetail(\n                    $index['name'].' <fg=gray>'.$index['columns']->implode(', ').'</>',\n                    $index['attributes']->implode(', ')\n                );\n            });\n\n            $this->newLine();\n        }\n\n        if ($foreignKeys->isNotEmpty()) {\n            $this->components->twoColumnDetail('<fg=green;options=bold>Foreign Key</>', 'On Update / On Delete');\n\n            $foreignKeys->each(function ($foreignKey) {\n                $this->components->twoColumnDetail(\n                    $foreignKey['name'].' <fg=gray;options=bold>'.$foreignKey['columns']->implode(', ').' references '.$foreignKey['foreign_columns']->implode(', ').' on '.$foreignKey['foreign_table'].'</>',\n                    $foreignKey['on_update'].' / '.$foreignKey['on_delete'],\n                );\n            });\n\n            $this->newLine();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Console/WipeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Console\\Prohibitable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'db:wipe')]\nclass WipeCommand extends Command\n{\n    use ConfirmableTrait, Prohibitable;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'db:wipe';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Drop all tables, views, and types';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        if ($this->isProhibited() ||\n            ! $this->confirmToProceed()) {\n            return Command::FAILURE;\n        }\n\n        $database = $this->input->getOption('database');\n\n        if ($this->option('drop-views')) {\n            $this->dropAllViews($database);\n\n            $this->components->info('Dropped all views successfully.');\n        }\n\n        $this->dropAllTables($database);\n\n        $this->components->info('Dropped all tables successfully.');\n\n        if ($this->option('drop-types')) {\n            $this->dropAllTypes($database);\n\n            $this->components->info('Dropped all types successfully.');\n        }\n\n        $this->flushDatabaseConnection($database);\n\n        return 0;\n    }\n\n    /**\n     * Drop all of the database tables.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function dropAllTables($database)\n    {\n        $this->laravel['db']->connection($database)\n            ->getSchemaBuilder()\n            ->dropAllTables();\n    }\n\n    /**\n     * Drop all of the database views.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function dropAllViews($database)\n    {\n        $this->laravel['db']->connection($database)\n            ->getSchemaBuilder()\n            ->dropAllViews();\n    }\n\n    /**\n     * Drop all of the database types.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function dropAllTypes($database)\n    {\n        $this->laravel['db']->connection($database)\n            ->getSchemaBuilder()\n            ->dropAllTypes();\n    }\n\n    /**\n     * Flush the given database connection.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function flushDatabaseConnection($database)\n    {\n        $this->laravel['db']->connection($database)->disconnect();\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],\n            ['drop-views', null, InputOption::VALUE_NONE, 'Drop all tables and views'],\n            ['drop-types', null, InputOption::VALUE_NONE, 'Drop all tables and types (Postgres only)'],\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DatabaseManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Database\\Connectors\\ConnectionFactory;\nuse Illuminate\\Database\\Events\\ConnectionEstablished;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ConfigurationUrlParser;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse PDO;\nuse RuntimeException;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @mixin \\Illuminate\\Database\\Connection\n */\nclass DatabaseManager implements ConnectionResolverInterface\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The database connection factory instance.\n     *\n     * @var \\Illuminate\\Database\\Connectors\\ConnectionFactory\n     */\n    protected $factory;\n\n    /**\n     * The active connection instances.\n     *\n     * @var array<string, \\Illuminate\\Database\\Connection>\n     */\n    protected $connections = [];\n\n    /**\n     * The dynamically configured (DB::build) connection configurations.\n     *\n     * @var array<string, array>\n     */\n    protected $dynamicConnectionConfigurations = [];\n\n    /**\n     * The custom connection resolvers.\n     *\n     * @var array<string, callable>\n     */\n    protected $extensions = [];\n\n    /**\n     * The callback to be executed to reconnect to a database.\n     *\n     * @var callable\n     */\n    protected $reconnector;\n\n    /**\n     * Create a new database manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Database\\Connectors\\ConnectionFactory  $factory\n     */\n    public function __construct($app, ConnectionFactory $factory)\n    {\n        $this->app = $app;\n        $this->factory = $factory;\n\n        $this->reconnector = function ($connection) {\n            $connection->setPdo(\n                $this->reconnect($connection->getNameWithReadWriteType())->getRawPdo()\n            );\n        };\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function connection($name = null)\n    {\n        [$database, $type] = $this->parseConnectionName($name = enum_value($name) ?: $this->getDefaultConnection());\n\n        // If we haven't created this connection, we'll create it based on the config\n        // provided in the application. Once we've created the connections we will\n        // set the \"fetch mode\" for PDO which determines the query return types.\n        if (! isset($this->connections[$name])) {\n            $this->connections[$name] = $this->configure(\n                $this->makeConnection($database), $type\n            );\n\n            $this->dispatchConnectionEstablishedEvent($this->connections[$name]);\n        }\n\n        return $this->connections[$name];\n    }\n\n    /**\n     * Build a database connection instance from the given configuration.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function build(array $config)\n    {\n        $config['name'] ??= static::calculateDynamicConnectionName($config);\n\n        $this->dynamicConnectionConfigurations[$config['name']] = $config;\n\n        return $this->connectUsing($config['name'], $config, true);\n    }\n\n    /**\n     * Calculate the dynamic connection name for an on-demand connection based on its configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    public static function calculateDynamicConnectionName(array $config)\n    {\n        return 'dynamic_'.md5((new Collection($config))->map(function ($value, $key) {\n            return $key.(is_string($value) || is_int($value) ? $value : '');\n        })->implode(''));\n    }\n\n    /**\n     * Get a database connection instance from the given configuration.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @param  array  $config\n     * @param  bool  $force\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     *\n     * @throws \\RuntimeException\n     */\n    public function connectUsing(string $name, array $config, bool $force = false)\n    {\n        if ($force) {\n            $this->purge($name = enum_value($name));\n        }\n\n        if (isset($this->connections[$name])) {\n            throw new RuntimeException(\"Cannot establish connection [$name] because another connection with that name already exists.\");\n        }\n\n        $connection = $this->configure(\n            $this->factory->make($config, $name), null\n        );\n\n        $this->dispatchConnectionEstablishedEvent($connection);\n\n        return tap($connection, fn ($connection) => $this->connections[$name] = $connection);\n    }\n\n    /**\n     * Parse the connection into an array of the name and read / write type.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function parseConnectionName($name)\n    {\n        return Str::endsWith($name, ['::read', '::write'])\n            ? explode('::', $name, 2)\n            : [$name, null];\n    }\n\n    /**\n     * Make the database connection instance.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function makeConnection($name)\n    {\n        $config = $this->configuration($name);\n\n        // First we will check by the connection name to see if an extension has been\n        // registered specifically for that connection. If it has we will call the\n        // Closure and pass it the config allowing it to resolve the connection.\n        if (isset($this->extensions[$name])) {\n            return call_user_func($this->extensions[$name], $config, $name);\n        }\n\n        // Next we will check to see if an extension has been registered for a driver\n        // and will call the Closure if so, which allows us to have a more generic\n        // resolver for the drivers themselves which applies to all connections.\n        if (isset($this->extensions[$driver = $config['driver']])) {\n            return call_user_func($this->extensions[$driver], $config, $name);\n        }\n\n        return $this->factory->make($config, $name);\n    }\n\n    /**\n     * Get the configuration for a connection.\n     *\n     * @param  string  $name\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function configuration($name)\n    {\n        $connections = $this->app['config']['database.connections'];\n\n        $config = $this->dynamicConnectionConfigurations[$name] ?? Arr::get($connections, $name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Database connection [{$name}] not configured.\");\n        }\n\n        return (new ConfigurationUrlParser)\n            ->parseConfiguration($config);\n    }\n\n    /**\n     * Prepare the database connection instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $type\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function configure(Connection $connection, $type)\n    {\n        $connection = $this->setPdoForType($connection, $type)->setReadWriteType($type);\n\n        // First we'll set the fetch mode and a few other dependencies of the database\n        // connection. This method basically just configures and prepares it to get\n        // used by the application. Once we're finished we'll return it back out.\n        if ($this->app->bound('events')) {\n            $connection->setEventDispatcher($this->app['events']);\n        }\n\n        if ($this->app->bound('db.transactions')) {\n            $connection->setTransactionManager($this->app['db.transactions']);\n        }\n\n        // Here we'll set a reconnector callback. This reconnector can be any callable\n        // so we will set a Closure to reconnect from this manager with the name of\n        // the connection, which will allow us to reconnect from the connections.\n        $connection->setReconnector($this->reconnector);\n\n        return $connection;\n    }\n\n    /**\n     * Dispatch the ConnectionEstablished event if the event dispatcher is available.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return void\n     */\n    protected function dispatchConnectionEstablishedEvent(Connection $connection)\n    {\n        if (! $this->app->bound('events')) {\n            return;\n        }\n\n        $this->app['events']->dispatch(\n            new ConnectionEstablished($connection)\n        );\n    }\n\n    /**\n     * Prepare the read / write mode for database connection instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string|null  $type\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function setPdoForType(Connection $connection, $type = null)\n    {\n        if ($type === 'read') {\n            $connection->setPdo($connection->getReadPdo());\n        } elseif ($type === 'write') {\n            $connection->setReadPdo($connection->getPdo());\n        }\n\n        return $connection;\n    }\n\n    /**\n     * Disconnect from the given database and remove from local cache.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $this->disconnect($name = enum_value($name) ?: $this->getDefaultConnection());\n\n        unset($this->connections[$name]);\n    }\n\n    /**\n     * Disconnect from the given database.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return void\n     */\n    public function disconnect($name = null)\n    {\n        if (isset($this->connections[$name = enum_value($name) ?: $this->getDefaultConnection()])) {\n            $this->connections[$name]->disconnect();\n        }\n    }\n\n    /**\n     * Reconnect to the given database.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function reconnect($name = null)\n    {\n        $this->disconnect($name = enum_value($name) ?: $this->getDefaultConnection());\n\n        if (! isset($this->connections[$name])) {\n            return $this->connection($name);\n        }\n\n        return tap($this->refreshPdoConnections($name), function ($connection) {\n            $this->dispatchConnectionEstablishedEvent($connection);\n        });\n    }\n\n    /**\n     * Set the default database connection for the callback execution.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @param  callable  $callback\n     * @return mixed\n     */\n    public function usingConnection($name, callable $callback)\n    {\n        $previousName = $this->getDefaultConnection();\n\n        $this->setDefaultConnection($name = enum_value($name));\n\n        try {\n            return $callback();\n        } finally {\n            $this->setDefaultConnection($previousName);\n        }\n    }\n\n    /**\n     * Refresh the PDO connections on a given connection.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function refreshPdoConnections($name)\n    {\n        [$database, $type] = $this->parseConnectionName($name);\n\n        $fresh = $this->configure(\n            $this->makeConnection($database), $type\n        );\n\n        return $this->connections[$name]\n            ->setPdo($fresh->getRawPdo())\n            ->setReadPdo($fresh->getRawReadPdo());\n    }\n\n    /**\n     * Get the default connection name.\n     *\n     * @return string\n     */\n    public function getDefaultConnection()\n    {\n        return $this->app['config']['database.default'];\n    }\n\n    /**\n     * Set the default connection name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultConnection($name)\n    {\n        $this->app['config']['database.default'] = $name;\n    }\n\n    /**\n     * Get all of the supported drivers.\n     *\n     * @return string[]\n     */\n    public function supportedDrivers()\n    {\n        return ['mysql', 'mariadb', 'pgsql', 'sqlite', 'sqlsrv'];\n    }\n\n    /**\n     * Get all of the drivers that are actually available.\n     *\n     * @return string[]\n     */\n    public function availableDrivers()\n    {\n        return array_intersect(\n            $this->supportedDrivers(),\n            str_replace('dblib', 'sqlsrv', PDO::getAvailableDrivers())\n        );\n    }\n\n    /**\n     * Register an extension connection resolver.\n     *\n     * @param  string  $name\n     * @param  callable  $resolver\n     * @return void\n     */\n    public function extend($name, callable $resolver)\n    {\n        $this->extensions[$name] = $resolver;\n    }\n\n    /**\n     * Remove an extension connection resolver.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function forgetExtension($name)\n    {\n        unset($this->extensions[$name]);\n    }\n\n    /**\n     * Return all of the created connections.\n     *\n     * @return array<string, \\Illuminate\\Database\\Connection>\n     */\n    public function getConnections()\n    {\n        return $this->connections;\n    }\n\n    /**\n     * Set the database reconnector callback.\n     *\n     * @param  callable  $reconnector\n     * @return void\n     */\n    public function setReconnector(callable $reconnector)\n    {\n        $this->reconnector = $reconnector;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically pass methods to the default connection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->connection()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DatabaseServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Faker\\Factory as FakerFactory;\nuse Faker\\Generator as FakerGenerator;\nuse Illuminate\\Contracts\\Database\\ConcurrencyErrorDetector as ConcurrencyErrorDetectorContract;\nuse Illuminate\\Contracts\\Database\\LostConnectionDetector as LostConnectionDetectorContract;\nuse Illuminate\\Contracts\\Queue\\EntityResolver;\nuse Illuminate\\Database\\Connectors\\ConnectionFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\QueueEntityResolver;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass DatabaseServiceProvider extends ServiceProvider\n{\n    /**\n     * The array of resolved Faker instances.\n     *\n     * @var array\n     */\n    protected static $fakers = [];\n\n    /**\n     * Bootstrap the application events.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        Model::setConnectionResolver($this->app['db']);\n\n        Model::setEventDispatcher($this->app['events']);\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        Model::clearBootedModels();\n\n        $this->registerConnectionServices();\n        $this->registerFakerGenerator();\n        $this->registerQueueableEntityResolver();\n    }\n\n    /**\n     * Register the primary database bindings.\n     *\n     * @return void\n     */\n    protected function registerConnectionServices()\n    {\n        // The connection factory is used to create the actual connection instances on\n        // the database. We will inject the factory into the manager so that it may\n        // make the connections while they are actually needed and not of before.\n        $this->app->singleton('db.factory', function ($app) {\n            return new ConnectionFactory($app);\n        });\n\n        // The database manager is used to resolve various connections, since multiple\n        // connections might be managed. It also implements the connection resolver\n        // interface which may be used by other components requiring connections.\n        $this->app->singleton('db', function ($app) {\n            return new DatabaseManager($app, $app['db.factory']);\n        });\n\n        $this->app->bind('db.connection', function ($app) {\n            return $app['db']->connection();\n        });\n\n        $this->app->bind('db.schema', function ($app) {\n            return $app['db']->connection()->getSchemaBuilder();\n        });\n\n        $this->app->singleton('db.transactions', function () {\n            return new DatabaseTransactionsManager;\n        });\n\n        $this->app->singleton(ConcurrencyErrorDetectorContract::class, function () {\n            return new ConcurrencyErrorDetector;\n        });\n\n        $this->app->singleton(LostConnectionDetectorContract::class, function () {\n            return new LostConnectionDetector;\n        });\n    }\n\n    /**\n     * Register the Faker Generator instance in the container.\n     *\n     * @return void\n     */\n    protected function registerFakerGenerator()\n    {\n        if (! class_exists(FakerGenerator::class)) {\n            return;\n        }\n\n        $this->app->singleton(FakerGenerator::class, function ($app, $parameters) {\n            $locale = $parameters['locale'] ?? $app['config']->get('app.faker_locale', 'en_US');\n\n            if (! isset(static::$fakers[$locale])) {\n                static::$fakers[$locale] = FakerFactory::create($locale);\n            }\n\n            static::$fakers[$locale]->unique(true);\n\n            return static::$fakers[$locale];\n        });\n    }\n\n    /**\n     * Register the queueable entity resolver implementation.\n     *\n     * @return void\n     */\n    protected function registerQueueableEntityResolver()\n    {\n        $this->app->singleton(EntityResolver::class, function () {\n            return new QueueEntityResolver;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DatabaseTransactionRecord.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nclass DatabaseTransactionRecord\n{\n    /**\n     * The name of the database connection.\n     *\n     * @var string\n     */\n    public $connection;\n\n    /**\n     * The transaction level.\n     *\n     * @var int\n     */\n    public $level;\n\n    /**\n     * The parent instance of this transaction.\n     *\n     * @var \\Illuminate\\Database\\DatabaseTransactionRecord\n     */\n    public $parent;\n\n    /**\n     * The callbacks that should be executed after committing.\n     *\n     * @var array\n     */\n    protected $callbacks = [];\n\n    /**\n     * The callbacks that should be executed after rollback.\n     *\n     * @var array\n     */\n    protected $callbacksForRollback = [];\n\n    /**\n     * Create a new database transaction record instance.\n     *\n     * @param  string  $connection\n     * @param  int  $level\n     * @param  \\Illuminate\\Database\\DatabaseTransactionRecord|null  $parent\n     */\n    public function __construct($connection, $level, ?DatabaseTransactionRecord $parent = null)\n    {\n        $this->connection = $connection;\n        $this->level = $level;\n        $this->parent = $parent;\n    }\n\n    /**\n     * Register a callback to be executed after committing.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function addCallback($callback)\n    {\n        $this->callbacks[] = $callback;\n    }\n\n    /**\n     * Register a callback to be executed after rollback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function addCallbackForRollback($callback)\n    {\n        $this->callbacksForRollback[] = $callback;\n    }\n\n    /**\n     * Execute all of the callbacks.\n     *\n     * @return void\n     */\n    public function executeCallbacks()\n    {\n        foreach ($this->callbacks as $callback) {\n            $callback();\n        }\n    }\n\n    /**\n     * Execute all of the callbacks for rollback.\n     *\n     * @return void\n     */\n    public function executeCallbacksForRollback()\n    {\n        foreach ($this->callbacksForRollback as $callback) {\n            $callback();\n        }\n    }\n\n    /**\n     * Get all of the callbacks.\n     *\n     * @return array\n     */\n    public function getCallbacks()\n    {\n        return $this->callbacks;\n    }\n\n    /**\n     * Get all of the callbacks for rollback.\n     *\n     * @return array\n     */\n    public function getCallbacksForRollback()\n    {\n        return $this->callbacksForRollback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DatabaseTransactionsManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Support\\Collection;\n\nclass DatabaseTransactionsManager\n{\n    /**\n     * All of the committed transactions.\n     *\n     * @var \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\DatabaseTransactionRecord>\n     */\n    protected $committedTransactions;\n\n    /**\n     * All of the pending transactions.\n     *\n     * @var \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\DatabaseTransactionRecord>\n     */\n    protected $pendingTransactions;\n\n    /**\n     * The current transaction.\n     *\n     * @var array\n     */\n    protected $currentTransaction = [];\n\n    /**\n     * Create a new database transactions manager instance.\n     */\n    public function __construct()\n    {\n        $this->committedTransactions = new Collection;\n        $this->pendingTransactions = new Collection;\n    }\n\n    /**\n     * Start a new database transaction.\n     *\n     * @param  string  $connection\n     * @param  int  $level\n     * @return void\n     */\n    public function begin($connection, $level)\n    {\n        $this->pendingTransactions->push(\n            $newTransaction = new DatabaseTransactionRecord(\n                $connection,\n                $level,\n                $this->currentTransaction[$connection] ?? null\n            )\n        );\n\n        $this->currentTransaction[$connection] = $newTransaction;\n    }\n\n    /**\n     * Commit the root database transaction and execute callbacks.\n     *\n     * @param  string  $connection\n     * @param  int  $levelBeingCommitted\n     * @param  int  $newTransactionLevel\n     * @return array\n     */\n    public function commit($connection, $levelBeingCommitted, $newTransactionLevel)\n    {\n        $this->stageTransactions($connection, $levelBeingCommitted);\n\n        if (isset($this->currentTransaction[$connection])) {\n            $this->currentTransaction[$connection] = $this->currentTransaction[$connection]->parent;\n        }\n\n        if (! $this->afterCommitCallbacksShouldBeExecuted($newTransactionLevel) &&\n            $newTransactionLevel !== 0) {\n            return [];\n        }\n\n        // This method is only called when the root database transaction is committed so there\n        // shouldn't be any pending transactions, but going to clear them here anyways just\n        // in case. This method could be refactored to receive a level in the future too.\n        $this->pendingTransactions = $this->pendingTransactions->reject(\n            fn ($transaction) => $transaction->connection === $connection &&\n                $transaction->level >= $levelBeingCommitted\n        )->values();\n\n        [$forThisConnection, $forOtherConnections] = $this->committedTransactions->partition(\n            fn ($transaction) => $transaction->connection == $connection\n        );\n\n        $this->committedTransactions = $forOtherConnections->values();\n\n        $forThisConnection->map->executeCallbacks();\n\n        return $forThisConnection;\n    }\n\n    /**\n     * Move relevant pending transactions to a committed state.\n     *\n     * @param  string  $connection\n     * @param  int  $levelBeingCommitted\n     * @return void\n     */\n    public function stageTransactions($connection, $levelBeingCommitted)\n    {\n        $this->committedTransactions = $this->committedTransactions->merge(\n            $this->pendingTransactions->filter(\n                fn ($transaction) => $transaction->connection === $connection &&\n                                     $transaction->level >= $levelBeingCommitted\n            )\n        );\n\n        $this->pendingTransactions = $this->pendingTransactions->reject(\n            fn ($transaction) => $transaction->connection === $connection &&\n                                 $transaction->level >= $levelBeingCommitted\n        );\n    }\n\n    /**\n     * Rollback the active database transaction.\n     *\n     * @param  string  $connection\n     * @param  int  $newTransactionLevel\n     * @return void\n     */\n    public function rollback($connection, $newTransactionLevel)\n    {\n        if ($newTransactionLevel === 0) {\n            $this->removeAllTransactionsForConnection($connection);\n        } else {\n            $this->pendingTransactions = $this->pendingTransactions->reject(\n                fn ($transaction) => $transaction->connection == $connection &&\n                                     $transaction->level > $newTransactionLevel\n            )->values();\n\n            if ($this->currentTransaction) {\n                do {\n                    $this->removeCommittedTransactionsThatAreChildrenOf($this->currentTransaction[$connection]);\n\n                    $this->currentTransaction[$connection]->executeCallbacksForRollback();\n\n                    $this->currentTransaction[$connection] = $this->currentTransaction[$connection]->parent;\n                } while (\n                    isset($this->currentTransaction[$connection]) &&\n                    $this->currentTransaction[$connection]->level > $newTransactionLevel\n                );\n            }\n        }\n    }\n\n    /**\n     * Remove all pending, completed, and current transactions for the given connection name.\n     *\n     * @param  string  $connection\n     * @return void\n     */\n    protected function removeAllTransactionsForConnection($connection)\n    {\n        if ($this->currentTransaction) {\n            for ($currentTransaction = $this->currentTransaction[$connection]; isset($currentTransaction); $currentTransaction = $currentTransaction->parent) {\n                $currentTransaction->executeCallbacksForRollback();\n            }\n        }\n\n        $this->currentTransaction[$connection] = null;\n\n        $this->pendingTransactions = $this->pendingTransactions->reject(\n            fn ($transaction) => $transaction->connection == $connection\n        )->values();\n\n        $this->committedTransactions = $this->committedTransactions->reject(\n            fn ($transaction) => $transaction->connection == $connection\n        )->values();\n    }\n\n    /**\n     * Remove all transactions that are children of the given transaction.\n     *\n     * @param  \\Illuminate\\Database\\DatabaseTransactionRecord  $transaction\n     * @return void\n     */\n    protected function removeCommittedTransactionsThatAreChildrenOf(DatabaseTransactionRecord $transaction)\n    {\n        [$removedTransactions, $this->committedTransactions] = $this->committedTransactions->partition(\n            fn ($committed) => $committed->connection == $transaction->connection &&\n                               $committed->parent === $transaction\n        );\n\n        // There may be multiple deeply nested transactions that have already committed that we\n        // also need to remove. We will recurse down the children of all removed transaction\n        // instances until there are no more deeply nested child transactions for removal.\n        $removedTransactions->each(\n            fn ($transaction) => $this->removeCommittedTransactionsThatAreChildrenOf($transaction)\n        );\n    }\n\n    /**\n     * Register a transaction callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function addCallback($callback)\n    {\n        if ($current = $this->callbackApplicableTransactions()->last()) {\n            return $current->addCallback($callback);\n        }\n\n        $callback();\n    }\n\n    /**\n     * Register a callback for transaction rollback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function addCallbackForRollback($callback)\n    {\n        if ($current = $this->callbackApplicableTransactions()->last()) {\n            return $current->addCallbackForRollback($callback);\n        }\n    }\n\n    /**\n     * Get the transactions that are applicable to callbacks.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\DatabaseTransactionRecord>\n     */\n    public function callbackApplicableTransactions()\n    {\n        return $this->pendingTransactions;\n    }\n\n    /**\n     * Determine if after commit callbacks should be executed for the given transaction level.\n     *\n     * @param  int  $level\n     * @return bool\n     */\n    public function afterCommitCallbacksShouldBeExecuted($level)\n    {\n        return $level === 0;\n    }\n\n    /**\n     * Get all of the pending transactions.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function getPendingTransactions()\n    {\n        return $this->pendingTransactions;\n    }\n\n    /**\n     * Get all of the committed transactions.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function getCommittedTransactions()\n    {\n        return $this->committedTransactions;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DeadlockException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse PDOException;\n\nclass DeadlockException extends PDOException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DetectsConcurrencyErrors.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Database\\ConcurrencyErrorDetector as ConcurrencyErrorDetectorContract;\nuse Throwable;\n\ntrait DetectsConcurrencyErrors\n{\n    /**\n     * Determine if the given exception was caused by a concurrency error such as a deadlock or serialization failure.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function causedByConcurrencyError(Throwable $e)\n    {\n        $container = Container::getInstance();\n\n        $detector = $container->bound(ConcurrencyErrorDetectorContract::class)\n            ? $container[ConcurrencyErrorDetectorContract::class]\n            : new ConcurrencyErrorDetector();\n\n        return $detector->causedByConcurrencyError($e);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/DetectsLostConnections.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Database\\LostConnectionDetector as LostConnectionDetectorContract;\nuse Throwable;\n\ntrait DetectsLostConnections\n{\n    /**\n     * Determine if the given exception was caused by a lost connection.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function causedByLostConnection(Throwable $e)\n    {\n        $container = Container::getInstance();\n\n        $detector = $container->bound(LostConnectionDetectorContract::class)\n            ? $container[LostConnectionDetectorContract::class]\n            : new LostConnectionDetector();\n\n        return $detector->causedByLostConnection($e);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Appends.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Appends\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $columns\n     */\n    public function __construct(public array $columns)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Boot.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_METHOD)]\nclass Boot\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/CollectedBy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass CollectedBy\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Collection<*, *>>  $collectionClass\n     */\n    public function __construct(public string $collectionClass)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Connection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Connection\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $name\n     */\n    public function __construct(public string $name)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Fillable.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Fillable\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $columns\n     */\n    public function __construct(public array $columns)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Guarded.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Guarded\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $columns\n     */\n    public function __construct(public array $columns)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Hidden.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Hidden\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $columns\n     */\n    public function __construct(public array $columns)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Initialize.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_METHOD)]\nclass Initialize\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/ObservedBy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass ObservedBy\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array|string  $classes\n     */\n    public function __construct(public array|string $classes)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Scope.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_METHOD)]\nclass Scope\n{\n    /**\n     * Create a new attribute instance.\n     */\n    public function __construct()\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/ScopedBy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass ScopedBy\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array|string  $classes\n     */\n    public function __construct(public array|string $classes)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Table.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Table\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string|null  $name\n     * @param  string|null  $key\n     * @param  string|null  $keyType\n     * @param  bool|null  $incrementing\n     * @param  bool|null  $timestamps\n     * @param  string|null  $dateFormat\n     */\n    public function __construct(\n        public ?string $name = null,\n        public ?string $key = null,\n        public ?string $keyType = null,\n        public ?bool $incrementing = null,\n        public ?bool $timestamps = null,\n        public ?string $dateFormat = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Touches.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Touches\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $relations\n     */\n    public function __construct(public array $relations)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Unguarded.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Unguarded\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/UseEloquentBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UseEloquentBuilder\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Builder>  $builderClass\n     */\n    public function __construct(public string $builderClass)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/UseFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UseFactory\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Factories\\Factory>  $factoryClass\n     */\n    public function __construct(public string $factoryClass)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/UsePolicy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UsePolicy\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<*>  $class\n     */\n    public function __construct(public string $class)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/UseResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UseResource\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<*>  $class\n     */\n    public function __construct(public string $class)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/UseResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UseResourceCollection\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  class-string<*>  $class\n     */\n    public function __construct(public string $class)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Attributes/Visible.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Visible\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int, string>  $columns\n     */\n    public function __construct(public array $columns)\n    {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/BroadcastableModelEventOccurred.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Broadcasting\\InteractsWithSockets;\nuse Illuminate\\Broadcasting\\PrivateChannel;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Collection as BaseCollection;\n\nclass BroadcastableModelEventOccurred implements ShouldBroadcast\n{\n    use InteractsWithSockets, SerializesModels;\n\n    /**\n     * The model instance corresponding to the event.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Model\n     */\n    public $model;\n\n    /**\n     * The event name (created, updated, etc.).\n     *\n     * @var string\n     */\n    protected $event;\n\n    /**\n     * The channels that the event should be broadcast on.\n     *\n     * @var array\n     */\n    protected $channels = [];\n\n    /**\n     * The queue connection that should be used to queue the broadcast job.\n     *\n     * @var string\n     */\n    public $connection;\n\n    /**\n     * The queue that should be used to queue the broadcast job.\n     *\n     * @var string\n     */\n    public $queue;\n\n    /**\n     * Indicates whether the job should be dispatched after all database transactions have committed.\n     *\n     * @var bool|null\n     */\n    public $afterCommit;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $event\n     */\n    public function __construct($model, $event)\n    {\n        $this->model = $model;\n        $this->event = $event;\n    }\n\n    /**\n     * The channels the event should broadcast on.\n     *\n     * @return array\n     */\n    public function broadcastOn()\n    {\n        $channels = empty($this->channels)\n            ? ($this->model->broadcastOn($this->event) ?: [])\n            : $this->channels;\n\n        return (new BaseCollection($channels))\n            ->map(fn ($channel) => $channel instanceof Model ? new PrivateChannel($channel) : $channel)\n            ->all();\n    }\n\n    /**\n     * The name the event should broadcast as.\n     *\n     * @return string\n     */\n    public function broadcastAs()\n    {\n        $default = class_basename($this->model).ucfirst($this->event);\n\n        return method_exists($this->model, 'broadcastAs')\n            ? ($this->model->broadcastAs($this->event) ?: $default)\n            : $default;\n    }\n\n    /**\n     * Get the data that should be sent with the broadcasted event.\n     *\n     * @return array|null\n     */\n    public function broadcastWith()\n    {\n        return method_exists($this->model, 'broadcastWith')\n            ? $this->model->broadcastWith($this->event)\n            : null;\n    }\n\n    /**\n     * Manually specify the channels the event should broadcast on.\n     *\n     * @param  array  $channels\n     * @return $this\n     */\n    public function onChannels(array $channels)\n    {\n        $this->channels = $channels;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the event should be broadcast synchronously.\n     *\n     * @return bool\n     */\n    public function shouldBroadcastNow()\n    {\n        return $this->event === 'deleted' &&\n               ! method_exists($this->model, 'bootSoftDeletes');\n    }\n\n    /**\n     * Get the event name.\n     *\n     * @return string\n     */\n    public function event()\n    {\n        return $this->event;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/BroadcastsEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Support\\Arr;\n\ntrait BroadcastsEvents\n{\n    /**\n     * Boot the event broadcasting trait.\n     *\n     * @return void\n     */\n    public static function bootBroadcastsEvents()\n    {\n        static::created(function ($model) {\n            $model->broadcastCreated();\n        });\n\n        static::updated(function ($model) {\n            $model->broadcastUpdated();\n        });\n\n        if (method_exists(static::class, 'bootSoftDeletes')) {\n            static::softDeleted(function ($model) {\n                $model->broadcastTrashed();\n            });\n\n            static::restored(function ($model) {\n                $model->broadcastRestored();\n            });\n        }\n\n        static::deleted(function ($model) {\n            $model->broadcastDeleted();\n        });\n    }\n\n    /**\n     * Broadcast that the model was created.\n     *\n     * @param  \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|array|null  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function broadcastCreated($channels = null)\n    {\n        return $this->broadcastIfBroadcastChannelsExistForEvent(\n            $this->newBroadcastableModelEvent('created'), 'created', $channels\n        );\n    }\n\n    /**\n     * Broadcast that the model was updated.\n     *\n     * @param  \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|array|null  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function broadcastUpdated($channels = null)\n    {\n        return $this->broadcastIfBroadcastChannelsExistForEvent(\n            $this->newBroadcastableModelEvent('updated'), 'updated', $channels\n        );\n    }\n\n    /**\n     * Broadcast that the model was trashed.\n     *\n     * @param  \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|array|null  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function broadcastTrashed($channels = null)\n    {\n        return $this->broadcastIfBroadcastChannelsExistForEvent(\n            $this->newBroadcastableModelEvent('trashed'), 'trashed', $channels\n        );\n    }\n\n    /**\n     * Broadcast that the model was restored.\n     *\n     * @param  \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|array|null  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function broadcastRestored($channels = null)\n    {\n        return $this->broadcastIfBroadcastChannelsExistForEvent(\n            $this->newBroadcastableModelEvent('restored'), 'restored', $channels\n        );\n    }\n\n    /**\n     * Broadcast that the model was deleted.\n     *\n     * @param  \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|array|null  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public function broadcastDeleted($channels = null)\n    {\n        return $this->broadcastIfBroadcastChannelsExistForEvent(\n            $this->newBroadcastableModelEvent('deleted'), 'deleted', $channels\n        );\n    }\n\n    /**\n     * Broadcast the given event instance if channels are configured for the model event.\n     *\n     * @param  mixed  $instance\n     * @param  string  $event\n     * @param  mixed  $channels\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast|null\n     */\n    protected function broadcastIfBroadcastChannelsExistForEvent($instance, $event, $channels = null)\n    {\n        if (! static::$isBroadcasting) {\n            return;\n        }\n\n        if (! empty($this->broadcastOn($event)) || ! empty($channels)) {\n            return broadcast($instance->onChannels(Arr::wrap($channels)));\n        }\n    }\n\n    /**\n     * Create a new broadcastable model event event.\n     *\n     * @param  string  $event\n     * @return mixed\n     */\n    public function newBroadcastableModelEvent($event)\n    {\n        return tap($this->newBroadcastableEvent($event), function ($event) {\n            $event->connection = property_exists($this, 'broadcastConnection')\n                ? $this->broadcastConnection\n                : $this->broadcastConnection();\n\n            $event->queue = property_exists($this, 'broadcastQueue')\n                ? $this->broadcastQueue\n                : $this->broadcastQueue();\n\n            $event->afterCommit = property_exists($this, 'broadcastAfterCommit')\n                ? $this->broadcastAfterCommit\n                : $this->broadcastAfterCommit();\n        });\n    }\n\n    /**\n     * Create a new broadcastable model event for the model.\n     *\n     * @param  string  $event\n     * @return \\Illuminate\\Database\\Eloquent\\BroadcastableModelEventOccurred\n     */\n    protected function newBroadcastableEvent(string $event)\n    {\n        return new BroadcastableModelEventOccurred($this, $event);\n    }\n\n    /**\n     * Get the channels that model events should broadcast on.\n     *\n     * @param  string  $event\n     * @return \\Illuminate\\Broadcasting\\Channel|array\n     */\n    public function broadcastOn($event)\n    {\n        return [$this];\n    }\n\n    /**\n     * Get the queue connection that should be used to broadcast model events.\n     *\n     * @return string|null\n     */\n    public function broadcastConnection()\n    {\n        //\n    }\n\n    /**\n     * Get the queue that should be used to broadcast model events.\n     *\n     * @return string|null\n     */\n    public function broadcastQueue()\n    {\n        //\n    }\n\n    /**\n     * Determine if the model event broadcast queued job should be dispatched after all transactions are committed.\n     *\n     * @return bool\n     */\n    public function broadcastAfterCommit()\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/BroadcastsEventsAfterCommit.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\ntrait BroadcastsEventsAfterCommit\n{\n    use BroadcastsEvents;\n\n    /**\n     * Determine if the model event broadcast queued job should be dispatched after all transactions are committed.\n     *\n     * @return bool\n     */\n    public function broadcastAfterCommit()\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Builder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse BadMethodCallException;\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Builder as BuilderContract;\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Concerns\\BuildsQueries;\nuse Illuminate\\Database\\Eloquent\\Concerns\\QueriesRelationships;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Pagination\\Paginator;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse ReflectionClass;\nuse ReflectionMethod;\n\n/**\n * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @property-read HigherOrderBuilderProxy|$this $orWhere\n * @property-read HigherOrderBuilderProxy|$this $whereNot\n * @property-read HigherOrderBuilderProxy|$this $orWhereNot\n *\n * @mixin \\Illuminate\\Database\\Query\\Builder\n */\nclass Builder implements BuilderContract\n{\n    /** @use \\Illuminate\\Database\\Concerns\\BuildsQueries<TModel> */\n    use BuildsQueries, ForwardsCalls, QueriesRelationships {\n        BuildsQueries::sole as baseSole;\n    }\n\n    /**\n     * The base query builder instance.\n     *\n     * @var \\Illuminate\\Database\\Query\\Builder\n     */\n    protected $query;\n\n    /**\n     * The model being queried.\n     *\n     * @var TModel\n     */\n    protected $model;\n\n    /**\n     * The attributes that should be added to new models created by this builder.\n     *\n     * @var array\n     */\n    public $pendingAttributes = [];\n\n    /**\n     * The relationships that should be eager loaded.\n     *\n     * @var array\n     */\n    protected $eagerLoad = [];\n\n    /**\n     * All of the globally registered builder macros.\n     *\n     * @var array\n     */\n    protected static $macros = [];\n\n    /**\n     * All of the locally registered builder macros.\n     *\n     * @var array\n     */\n    protected $localMacros = [];\n\n    /**\n     * A replacement for the typical delete function.\n     *\n     * @var \\Closure\n     */\n    protected $onDelete;\n\n    /**\n     * The properties that should be returned from query builder.\n     *\n     * @var string[]\n     */\n    protected $propertyPassthru = [\n        'from',\n    ];\n\n    /**\n     * The methods that should be returned from query builder.\n     *\n     * @var string[]\n     */\n    protected $passthru = [\n        'aggregate',\n        'average',\n        'avg',\n        'count',\n        'dd',\n        'ddrawsql',\n        'doesntexist',\n        'doesntexistor',\n        'dump',\n        'dumprawsql',\n        'exists',\n        'existsor',\n        'explain',\n        'getbindings',\n        'getconnection',\n        'getcountforpagination',\n        'getgrammar',\n        'getrawbindings',\n        'implode',\n        'insert',\n        'insertgetid',\n        'insertorignore',\n        'insertusing',\n        'insertorignoreusing',\n        'max',\n        'min',\n        'numericaggregate',\n        'raw',\n        'rawvalue',\n        'sum',\n        'tosql',\n        'torawsql',\n    ];\n\n    /**\n     * Applied global scopes.\n     *\n     * @var array\n     */\n    protected $scopes = [];\n\n    /**\n     * Removed global scopes.\n     *\n     * @var array\n     */\n    protected $removedScopes = [];\n\n    /**\n     * The callbacks that should be invoked after retrieving data from the database.\n     *\n     * @var array\n     */\n    protected $afterQueryCallbacks = [];\n\n    /**\n     * The callbacks that should be invoked on clone.\n     *\n     * @var array\n     */\n    protected $onCloneCallbacks = [];\n\n    /**\n     * Create a new Eloquent query builder instance.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     */\n    public function __construct(QueryBuilder $query)\n    {\n        $this->query = $query;\n    }\n\n    /**\n     * Create and return an un-saved model instance.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function make(array $attributes = [])\n    {\n        return $this->newModelInstance($attributes);\n    }\n\n    /**\n     * Register a new global scope.\n     *\n     * @param  string  $identifier\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|\\Closure  $scope\n     * @return $this\n     */\n    public function withGlobalScope($identifier, $scope)\n    {\n        $this->scopes[$identifier] = $scope;\n\n        if (method_exists($scope, 'extend')) {\n            $scope->extend($this);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Remove a registered global scope.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|string  $scope\n     * @return $this\n     */\n    public function withoutGlobalScope($scope)\n    {\n        if (! is_string($scope)) {\n            $scope = get_class($scope);\n        }\n\n        unset($this->scopes[$scope]);\n\n        $this->removedScopes[] = $scope;\n\n        return $this;\n    }\n\n    /**\n     * Remove all or passed registered global scopes.\n     *\n     * @param  array|null  $scopes\n     * @return $this\n     */\n    public function withoutGlobalScopes(?array $scopes = null)\n    {\n        if (! is_array($scopes)) {\n            $scopes = array_keys($this->scopes);\n        }\n\n        foreach ($scopes as $scope) {\n            $this->withoutGlobalScope($scope);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Remove all global scopes except the given scopes.\n     *\n     * @param  array  $scopes\n     * @return $this\n     */\n    public function withoutGlobalScopesExcept(array $scopes = [])\n    {\n        $this->withoutGlobalScopes(\n            array_diff(array_keys($this->scopes), $scopes)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get an array of global scopes that were removed from the query.\n     *\n     * @return array\n     */\n    public function removedScopes()\n    {\n        return $this->removedScopes;\n    }\n\n    /**\n     * Add a where clause on the primary key to the query.\n     *\n     * @param  mixed  $id\n     * @return $this\n     */\n    public function whereKey($id)\n    {\n        if ($id instanceof Model) {\n            $id = $id->getKey();\n        }\n\n        if (is_array($id) || $id instanceof Arrayable) {\n            if (in_array($this->model->getKeyType(), ['int', 'integer'])) {\n                $this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id);\n            } else {\n                $this->query->whereIn($this->model->getQualifiedKeyName(), $id);\n            }\n\n            return $this;\n        }\n\n        if ($id !== null && $this->model->getKeyType() === 'string') {\n            $id = (string) $id;\n        }\n\n        return $this->where($this->model->getQualifiedKeyName(), '=', $id);\n    }\n\n    /**\n     * Add a where clause on the primary key to the query.\n     *\n     * @param  mixed  $id\n     * @return $this\n     */\n    public function whereKeyNot($id)\n    {\n        if ($id instanceof Model) {\n            $id = $id->getKey();\n        }\n\n        if (is_array($id) || $id instanceof Arrayable) {\n            if (in_array($this->model->getKeyType(), ['int', 'integer'])) {\n                $this->query->whereIntegerNotInRaw($this->model->getQualifiedKeyName(), $id);\n            } else {\n                $this->query->whereNotIn($this->model->getQualifiedKeyName(), $id);\n            }\n\n            return $this;\n        }\n\n        if ($id !== null && $this->model->getKeyType() === 'string') {\n            $id = (string) $id;\n        }\n\n        return $this->where($this->model->getQualifiedKeyName(), '!=', $id);\n    }\n\n    /**\n     * Exclude the given models from the query results.\n     *\n     * @param  iterable|mixed  $models\n     * @return static\n     */\n    public function except($models)\n    {\n        return $this->whereKeyNot(\n            $models instanceof Model\n                ? $models->getKey()\n                : Collection::wrap($models)->modelKeys()\n        );\n    }\n\n    /**\n     * Add a basic where clause to the query.\n     *\n     * @param  (\\Closure(static): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function where($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        if ($column instanceof Closure && is_null($operator)) {\n            $column($query = $this->model->newQueryWithoutRelationships());\n\n            $this->eagerLoad = array_merge($this->eagerLoad, $query->getEagerLoads());\n\n            $this->withoutGlobalScopes(\n                $query->removedScopes()\n            );\n            $this->query->addNestedWhereQuery($query->getQuery(), $boolean);\n        } else {\n            $this->query->where(...func_get_args());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a basic where clause to the query, and return the first result.\n     *\n     * @param  (\\Closure(static): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return TModel|null\n     */\n    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        return $this->where(...func_get_args())->first();\n    }\n\n    /**\n     * Add an \"or where\" clause to the query.\n     *\n     * @param  (\\Closure(static): mixed)|array|string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhere($column, $operator = null, $value = null)\n    {\n        [$value, $operator] = $this->query->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->where($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a basic \"where not\" clause to the query.\n     *\n     * @param  (\\Closure(static): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNot($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        return $this->where($column, $operator, $value, $boolean.' not');\n    }\n\n    /**\n     * Add an \"or where not\" clause to the query.\n     *\n     * @param  (\\Closure(static): mixed)|array|string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereNot($column, $operator = null, $value = null)\n    {\n        return $this->whereNot($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add an \"order by\" clause for a timestamp to the query.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return $this\n     */\n    public function latest($column = null)\n    {\n        if (is_null($column)) {\n            $column = $this->model->getCreatedAtColumn() ?? 'created_at';\n        }\n\n        $this->query->latest($column);\n\n        return $this;\n    }\n\n    /**\n     * Add an \"order by\" clause for a timestamp to the query.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return $this\n     */\n    public function oldest($column = null)\n    {\n        if (is_null($column)) {\n            $column = $this->model->getCreatedAtColumn() ?? 'created_at';\n        }\n\n        $this->query->oldest($column);\n\n        return $this;\n    }\n\n    /**\n     * Create a collection of models from plain arrays.\n     *\n     * @param  array  $items\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function hydrate(array $items)\n    {\n        $instance = $this->newModelInstance();\n\n        return $instance->newCollection(array_map(function ($item) use ($items, $instance) {\n            $model = $instance->newFromBuilder($item);\n\n            if (count($items) > 1) {\n                $model->preventsLazyLoading = Model::preventsLazyLoading();\n            }\n\n            return $model;\n        }, $items));\n    }\n\n    /**\n     * Insert into the database after merging the model's default attributes, setting timestamps, and casting values.\n     *\n     * @param  array<int, array<string, mixed>>  $values\n     * @return bool\n     */\n    public function fillAndInsert(array $values)\n    {\n        return $this->insert($this->fillForInsert($values));\n    }\n\n    /**\n     * Insert (ignoring errors) into the database after merging the model's default attributes, setting timestamps, and casting values.\n     *\n     * @param  array<int, array<string, mixed>>  $values\n     * @return int\n     */\n    public function fillAndInsertOrIgnore(array $values)\n    {\n        return $this->insertOrIgnore($this->fillForInsert($values));\n    }\n\n    /**\n     * Insert a record into the database and get its ID after merging the model's default attributes, setting timestamps, and casting values.\n     *\n     * @param  array<string, mixed>  $values\n     * @return int\n     */\n    public function fillAndInsertGetId(array $values)\n    {\n        return $this->insertGetId($this->fillForInsert([$values])[0]);\n    }\n\n    /**\n     * Enrich the given values by merging in the model's default attributes, adding timestamps, and casting values.\n     *\n     * @param  array<int, array<string, mixed>>  $values\n     * @return array<int, array<string, mixed>>\n     */\n    public function fillForInsert(array $values)\n    {\n        if (empty($values)) {\n            return [];\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        $this->model->unguarded(function () use (&$values) {\n            foreach ($values as $key => $rowValues) {\n                $values[$key] = tap(\n                    $this->newModelInstance($rowValues),\n                    fn ($model) => $model->setUniqueIds()\n                )->getAttributes();\n            }\n        });\n\n        return $this->addTimestampsToUpsertValues($values);\n    }\n\n    /**\n     * Create a collection of models from a raw query.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function fromQuery($query, $bindings = [])\n    {\n        return $this->hydrate(\n            $this->query->getConnection()->select($query, $bindings)\n        );\n    }\n\n    /**\n     * Find a model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array|string  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TModel> : TModel|null)\n     */\n    public function find($id, $columns = ['*'])\n    {\n        if (is_array($id) || $id instanceof Arrayable) {\n            return $this->findMany($id, $columns);\n        }\n\n        return $this->whereKey($id)->first($columns);\n    }\n\n    /**\n     * Find a sole model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array|string  $columns\n     * @return TModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function findSole($id, $columns = ['*'])\n    {\n        return $this->whereKey($id)->sole($columns);\n    }\n\n    /**\n     * Find multiple models by their primary keys.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $ids\n     * @param  array|string  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function findMany($ids, $columns = ['*'])\n    {\n        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;\n\n        if (empty($ids)) {\n            return $this->model->newCollection();\n        }\n\n        return $this->whereKey($ids)->get($columns);\n    }\n\n    /**\n     * Find a model by its primary key or throw an exception.\n     *\n     * @param  mixed  $id\n     * @param  array|string  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TModel> : TModel)\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     */\n    public function findOrFail($id, $columns = ['*'])\n    {\n        $result = $this->find($id, $columns);\n\n        $id = $id instanceof Arrayable ? $id->toArray() : $id;\n\n        if (is_array($id)) {\n            if (count($result) !== count(array_unique($id))) {\n                throw (new ModelNotFoundException)->setModel(\n                    get_class($this->model), array_diff($id, $result->modelKeys())\n                );\n            }\n\n            return $result;\n        }\n\n        if (is_null($result)) {\n            throw (new ModelNotFoundException)->setModel(\n                get_class($this->model), $id\n            );\n        }\n\n        return $result;\n    }\n\n    /**\n     * Find a model by its primary key or return fresh model instance.\n     *\n     * @param  mixed  $id\n     * @param  array|string  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TModel> : TModel)\n     */\n    public function findOrNew($id, $columns = ['*'])\n    {\n        if (! is_null($model = $this->find($id, $columns))) {\n            return $model;\n        }\n\n        return $this->newModelInstance();\n    }\n\n    /**\n     * Find a model by its primary key or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  mixed  $id\n     * @param  (\\Closure(): TValue)|list<string>|string  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     *     : TModel|TValue\n     * )\n     */\n    public function findOr($id, $columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        if (! is_null($model = $this->find($id, $columns))) {\n            return $model;\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Get the first record matching the attributes or instantiate it.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TModel\n     */\n    public function firstOrNew(array $attributes = [], array $values = [])\n    {\n        if (! is_null($instance = $this->where($attributes)->first())) {\n            return $instance;\n        }\n\n        return $this->newModelInstance(array_merge($attributes, $values));\n    }\n\n    /**\n     * Get the first record matching the attributes. If the record is not found, create it.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TModel\n     */\n    public function firstOrCreate(array $attributes = [], Closure|array $values = [])\n    {\n        if (! is_null($instance = (clone $this)->where($attributes)->first())) {\n            return $instance;\n        }\n\n        return $this->createOrFirst($attributes, $values);\n    }\n\n    /**\n     * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TModel\n     *\n     * @throws \\Illuminate\\Database\\UniqueConstraintViolationException\n     */\n    public function createOrFirst(array $attributes = [], Closure|array $values = [])\n    {\n        try {\n            return $this->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, value($values))));\n        } catch (UniqueConstraintViolationException $e) {\n            return $this->useWritePdo()->where($attributes)->first() ?? throw $e;\n        }\n    }\n\n    /**\n     * Create or update a record matching the attributes, and fill it with values.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TModel\n     */\n    public function updateOrCreate(array $attributes, array $values = [])\n    {\n        return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {\n            if (! $instance->wasRecentlyCreated) {\n                $instance->fill($values)->save();\n            }\n        });\n    }\n\n    /**\n     * Create a record matching the attributes, or increment the existing record.\n     *\n     * @param  array  $attributes\n     * @param  string  $column\n     * @param  int|float  $default\n     * @param  int|float  $step\n     * @param  array  $extra\n     * @return TModel\n     */\n    public function incrementOrCreate(array $attributes, string $column = 'count', $default = 1, $step = 1, array $extra = [])\n    {\n        return tap($this->firstOrCreate($attributes, [$column => $default]), function ($instance) use ($column, $step, $extra) {\n            if (! $instance->wasRecentlyCreated) {\n                $instance->increment($column, $step, $extra);\n            }\n        });\n    }\n\n    /**\n     * Execute the query and get the first result or throw an exception.\n     *\n     * @param  array|string  $columns\n     * @return TModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     */\n    public function firstOrFail($columns = ['*'])\n    {\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        throw (new ModelNotFoundException)->setModel(get_class($this->model));\n    }\n\n    /**\n     * Execute the query and get the first result or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  (\\Closure(): TValue)|list<string>  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return TModel|TValue\n     */\n    public function firstOr($columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Execute the query and get the first result if it's the sole matching record.\n     *\n     * @param  array|string  $columns\n     * @return TModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function sole($columns = ['*'])\n    {\n        try {\n            return $this->baseSole($columns);\n        } catch (RecordsNotFoundException) {\n            throw (new ModelNotFoundException)->setModel(get_class($this->model));\n        }\n    }\n\n    /**\n     * Get a single column's value from the first result of a query.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return mixed\n     */\n    public function value($column)\n    {\n        if ($result = $this->first([$column])) {\n            $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;\n\n            return $result->{Str::afterLast($column, '.')};\n        }\n    }\n\n    /**\n     * Get a single column's value from the first result of a query if it's the sole matching record.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function soleValue($column)\n    {\n        $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;\n\n        return $this->sole([$column])->{Str::afterLast($column, '.')};\n    }\n\n    /**\n     * Get a single column's value from the first result of the query or throw an exception.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TModel>\n     */\n    public function valueOrFail($column)\n    {\n        $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;\n\n        return $this->firstOrFail([$column])->{Str::afterLast($column, '.')};\n    }\n\n    /**\n     * Execute the query as a \"select\" statement.\n     *\n     * @param  array|string  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function get($columns = ['*'])\n    {\n        $builder = $this->applyScopes();\n\n        // If we actually found models we will also eager load any relationships that\n        // have been specified as needing to be eager loaded, which will solve the\n        // n+1 query issue for the developers to avoid running a lot of queries.\n        if (count($models = $builder->getModels($columns)) > 0) {\n            $models = $builder->eagerLoadRelations($models);\n        }\n\n        return $this->applyAfterQueryCallbacks(\n            $builder->getModel()->newCollection($models)\n        );\n    }\n\n    /**\n     * Get the hydrated models without eager loading.\n     *\n     * @param  array|string  $columns\n     * @return array<int, TModel>\n     */\n    public function getModels($columns = ['*'])\n    {\n        return $this->model->hydrate(\n            $this->query->get($columns)->all()\n        )->all();\n    }\n\n    /**\n     * Eager load the relationships for the models.\n     *\n     * @param  array<int, TModel>  $models\n     * @return array<int, TModel>\n     */\n    public function eagerLoadRelations(array $models)\n    {\n        foreach ($this->eagerLoad as $name => $constraints) {\n            // For nested eager loads we'll skip loading them here and they will be set as an\n            // eager load on the query to retrieve the relation so that they will be eager\n            // loaded on that query, because that is where they get hydrated as models.\n            if (! str_contains($name, '.')) {\n                $models = $this->eagerLoadRelation($models, $name, $constraints);\n            }\n        }\n\n        return $models;\n    }\n\n    /**\n     * Eagerly load the relationship on a set of models.\n     *\n     * @param  array  $models\n     * @param  string  $name\n     * @param  \\Closure  $constraints\n     * @return array\n     */\n    protected function eagerLoadRelation(array $models, $name, Closure $constraints)\n    {\n        // First we will \"back up\" the existing where conditions on the query so we can\n        // add our eager constraints. Then we will merge the wheres that were on the\n        // query back to it in order that any where conditions might be specified.\n        $relation = $this->getRelation($name);\n\n        $relation->addEagerConstraints($models);\n\n        $constraints($relation);\n\n        // Once we have the results, we just match those back up to their parent models\n        // using the relationship instance. Then we just return the finished arrays\n        // of models which have been eagerly hydrated and are readied for return.\n        return $relation->match(\n            $relation->initRelation($models, $name),\n            $relation->getEager(), $name\n        );\n    }\n\n    /**\n     * Get the relation instance for the given relation name.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Relation<\\Illuminate\\Database\\Eloquent\\Model, TModel, *>\n     */\n    public function getRelation($name)\n    {\n        // We want to run a relationship query without any constrains so that we will\n        // not have to remove these where clauses manually which gets really hacky\n        // and error prone. We don't want constraints because we add eager ones.\n        $relation = Relation::noConstraints(function () use ($name) {\n            try {\n                return $this->getModel()->newInstance()->$name();\n            } catch (BadMethodCallException) {\n                throw RelationNotFoundException::make($this->getModel(), $name);\n            }\n        });\n\n        $nested = $this->relationsNestedUnder($name);\n\n        // If there are nested relationships set on the query, we will put those onto\n        // the query instances so that they can be handled after this relationship\n        // is loaded. In this way they will all trickle down as they are loaded.\n        if (count($nested) > 0) {\n            $relation->getQuery()->with($nested);\n        }\n\n        return $relation;\n    }\n\n    /**\n     * Get the deeply nested relations for a given top-level relation.\n     *\n     * @param  string  $relation\n     * @return array\n     */\n    protected function relationsNestedUnder($relation)\n    {\n        $nested = [];\n\n        // We are basically looking for any relationships that are nested deeper than\n        // the given top-level relationship. We will just check for any relations\n        // that start with the given top relations and adds them to our arrays.\n        foreach ($this->eagerLoad as $name => $constraints) {\n            if ($this->isNestedUnder($relation, $name)) {\n                $nested[substr($name, strlen($relation.'.'))] = $constraints;\n            }\n        }\n\n        return $nested;\n    }\n\n    /**\n     * Determine if the relationship is nested.\n     *\n     * @param  string  $relation\n     * @param  string  $name\n     * @return bool\n     */\n    protected function isNestedUnder($relation, $name)\n    {\n        return str_contains($name, '.') && str_starts_with($name, $relation.'.');\n    }\n\n    /**\n     * Register a closure to be invoked after the query is executed.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function afterQuery(Closure $callback)\n    {\n        $this->afterQueryCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Invoke the \"after query\" modification callbacks.\n     *\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function applyAfterQueryCallbacks($result)\n    {\n        foreach ($this->afterQueryCallbacks as $afterQueryCallback) {\n            $result = $afterQueryCallback($result) ?: $result;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get a lazy collection for the given query.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection<int, TModel>\n     */\n    public function cursor()\n    {\n        return $this->applyScopes()->query->cursor()->map(function ($record) {\n            $model = $this->newModelInstance()->newFromBuilder($record);\n\n            return $this->applyAfterQueryCallbacks($this->newModelInstance()->newCollection([$model]))->first();\n        })->reject(fn ($model) => is_null($model));\n    }\n\n    /**\n     * Add a generic \"order by\" clause if the query doesn't already have one.\n     *\n     * @return void\n     */\n    protected function enforceOrderBy()\n    {\n        if (empty($this->query->orders) && empty($this->query->unionOrders)) {\n            $this->orderBy($this->model->getQualifiedKeyName(), 'asc');\n        }\n    }\n\n    /**\n     * Get a collection with the values of a given column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  string|null  $key\n     * @return \\Illuminate\\Support\\Collection<array-key, mixed>\n     */\n    public function pluck($column, $key = null)\n    {\n        $results = $this->toBase()->pluck($column, $key);\n\n        $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;\n\n        $column = Str::after($column, \"{$this->model->getTable()}.\");\n\n        // If the model has a mutator for the requested column, we will spin through\n        // the results and mutate the values so that the mutated version of these\n        // columns are returned as you would expect from these Eloquent models.\n        if (! $this->model->hasAnyGetMutator($column) &&\n            ! $this->model->hasCast($column) &&\n            ! in_array($column, $this->model->getDates())) {\n            return $this->applyAfterQueryCallbacks($results);\n        }\n\n        return $this->applyAfterQueryCallbacks(\n            $results->map(function ($value) use ($column) {\n                return $this->model->newFromBuilder([$column => $value])->{$column};\n            })\n        );\n    }\n\n    /**\n     * Paginate the given query.\n     *\n     * @param  int|null|\\Closure  $perPage\n     * @param  array|string  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @param  \\Closure|int|null  $total\n     * @return \\Illuminate\\Pagination\\LengthAwarePaginator\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null, $total = null)\n    {\n        $page = $page ?: Paginator::resolveCurrentPage($pageName);\n\n        $total = value($total) ?? $this->toBase()->getCountForPagination();\n\n        $perPage = value($perPage, $total) ?: $this->model->getPerPage();\n\n        $results = $total\n            ? $this->forPage($page, $perPage)->get($columns)\n            : $this->model->newCollection();\n\n        return $this->paginator($results, $total, $perPage, $page, [\n            'path' => Paginator::resolveCurrentPath(),\n            'pageName' => $pageName,\n        ]);\n    }\n\n    /**\n     * Paginate the given query into a simple paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array|string  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Contracts\\Pagination\\Paginator\n     */\n    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $page = $page ?: Paginator::resolveCurrentPage($pageName);\n\n        $perPage = $perPage ?: $this->model->getPerPage();\n\n        // Next we will set the limit and offset for this query so that when we get the\n        // results we get the proper section of results. Then, we'll create the full\n        // paginator instances for these results with the given page and per page.\n        $this->offset(($page - 1) * $perPage)->limit($perPage + 1);\n\n        return $this->simplePaginator($this->get($columns), $perPage, $page, [\n            'path' => Paginator::resolveCurrentPath(),\n            'pageName' => $pageName,\n        ]);\n    }\n\n    /**\n     * Paginate the given query into a cursor paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array|string  $columns\n     * @param  string  $cursorName\n     * @param  \\Illuminate\\Pagination\\Cursor|string|null  $cursor\n     * @return \\Illuminate\\Contracts\\Pagination\\CursorPaginator\n     */\n    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)\n    {\n        $perPage = $perPage ?: $this->model->getPerPage();\n\n        return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);\n    }\n\n    /**\n     * Ensure the proper order by required for cursor pagination.\n     *\n     * @param  bool  $shouldReverse\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function ensureOrderForCursorPagination($shouldReverse = false)\n    {\n        if (empty($this->query->orders) && empty($this->query->unionOrders)) {\n            $this->enforceOrderBy();\n        }\n\n        $reverseDirection = function ($order) {\n            if (! isset($order['direction'])) {\n                return $order;\n            }\n\n            $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc';\n\n            return $order;\n        };\n\n        if ($shouldReverse) {\n            $this->query->orders = (new BaseCollection($this->query->orders))->map($reverseDirection)->toArray();\n            $this->query->unionOrders = (new BaseCollection($this->query->unionOrders))->map($reverseDirection)->toArray();\n        }\n\n        $orders = ! empty($this->query->unionOrders) ? $this->query->unionOrders : $this->query->orders;\n\n        return (new BaseCollection($orders))\n            ->filter(fn ($order) => Arr::has($order, 'direction'))\n            ->values();\n    }\n\n    /**\n     * Save a new model and return the instance.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function create(array $attributes = [])\n    {\n        return tap($this->newModelInstance($attributes), function ($instance) {\n            $instance->save();\n        });\n    }\n\n    /**\n     * Save a new model and return the instance without raising model events.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function createQuietly(array $attributes = [])\n    {\n        return Model::withoutEvents(fn () => $this->create($attributes));\n    }\n\n    /**\n     * Save a new model and return the instance. Allow mass-assignment.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function forceCreate(array $attributes)\n    {\n        return $this->model->unguarded(function () use ($attributes) {\n            return $this->newModelInstance()->create($attributes);\n        });\n    }\n\n    /**\n     * Save a new model instance with mass assignment without raising model events.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function forceCreateQuietly(array $attributes = [])\n    {\n        return Model::withoutEvents(fn () => $this->forceCreate($attributes));\n    }\n\n    /**\n     * Update records in the database.\n     *\n     * @param  array  $values\n     * @return int\n     */\n    public function update(array $values)\n    {\n        return $this->toBase()->update($this->addUpdatedAtColumn($values));\n    }\n\n    /**\n     * Insert new records or update the existing ones.\n     *\n     * @param  array  $values\n     * @param  array|string  $uniqueBy\n     * @param  array|null  $update\n     * @return int\n     */\n    public function upsert(array $values, $uniqueBy, $update = null)\n    {\n        if (empty($values)) {\n            return 0;\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        if (is_null($update)) {\n            $update = array_keys(array_first($values));\n        }\n\n        return $this->toBase()->upsert(\n            $this->addTimestampsToUpsertValues($this->addUniqueIdsToUpsertValues($values)),\n            $uniqueBy,\n            $this->addUpdatedAtToUpsertColumns($update)\n        );\n    }\n\n    /**\n     * Update the column's update timestamp.\n     *\n     * @param  array|string|null  $column\n     * @return int|false\n     */\n    public function touch($column = null)\n    {\n        $time = $this->model->freshTimestamp();\n\n        if ($column) {\n            $columns = (new BaseCollection(Arr::wrap($column)))->mapWithKeys(fn ($column) => [$column => $time])->all();\n\n            return $this->toBase()->update($columns);\n        }\n\n        $column = $this->model->getUpdatedAtColumn();\n\n        if (! $this->model->usesTimestamps() || is_null($column)) {\n            return false;\n        }\n\n        return $this->toBase()->update([$column => $time]);\n    }\n\n    /**\n     * Increment a column's value by a given amount.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    public function increment($column, $amount = 1, array $extra = [])\n    {\n        return $this->toBase()->increment(\n            $column, $amount, $this->addUpdatedAtColumn($extra)\n        );\n    }\n\n    /**\n     * Decrement a column's value by a given amount.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    public function decrement($column, $amount = 1, array $extra = [])\n    {\n        return $this->toBase()->decrement(\n            $column, $amount, $this->addUpdatedAtColumn($extra)\n        );\n    }\n\n    /**\n     * Add the \"updated at\" column to an array of values.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function addUpdatedAtColumn(array $values)\n    {\n        if (! $this->model->usesTimestamps() ||\n            is_null($this->model->getUpdatedAtColumn())) {\n            return $values;\n        }\n\n        $column = $this->model->getUpdatedAtColumn();\n\n        if (! array_key_exists($column, $values)) {\n            $timestamp = $this->model->freshTimestampString();\n\n            if (\n                $this->model->hasSetMutator($column)\n                || $this->model->hasAttributeSetMutator($column)\n                || $this->model->hasCast($column)\n            ) {\n                $timestamp = $this->model->newInstance()\n                    ->forceFill([$column => $timestamp])\n                    ->getAttributes()[$column] ?? $timestamp;\n            }\n\n            $values = array_merge([$column => $timestamp], $values);\n        }\n\n        $segments = preg_split('/\\s+as\\s+/i', $this->query->from);\n\n        $qualifiedColumn = array_last($segments).'.'.$column;\n\n        $values[$qualifiedColumn] = Arr::get($values, $qualifiedColumn, $values[$column]);\n\n        unset($values[$column]);\n\n        return $values;\n    }\n\n    /**\n     * Add unique IDs to the inserted values.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function addUniqueIdsToUpsertValues(array $values)\n    {\n        if (! $this->model->usesUniqueIds()) {\n            return $values;\n        }\n\n        foreach ($this->model->uniqueIds() as $uniqueIdAttribute) {\n            foreach ($values as &$row) {\n                if (! array_key_exists($uniqueIdAttribute, $row)) {\n                    $row = array_merge([$uniqueIdAttribute => $this->model->newUniqueId()], $row);\n                }\n            }\n        }\n\n        return $values;\n    }\n\n    /**\n     * Add timestamps to the inserted values.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function addTimestampsToUpsertValues(array $values)\n    {\n        if (! $this->model->usesTimestamps()) {\n            return $values;\n        }\n\n        $timestamp = $this->model->freshTimestampString();\n\n        $columns = array_filter([\n            $this->model->getCreatedAtColumn(),\n            $this->model->getUpdatedAtColumn(),\n        ]);\n\n        foreach ($columns as $column) {\n            foreach ($values as &$row) {\n                $row = array_merge([$column => $timestamp], $row);\n            }\n        }\n\n        return $values;\n    }\n\n    /**\n     * Add the \"updated at\" column to the updated columns.\n     *\n     * @param  array  $update\n     * @return array\n     */\n    protected function addUpdatedAtToUpsertColumns(array $update)\n    {\n        if (! $this->model->usesTimestamps()) {\n            return $update;\n        }\n\n        $column = $this->model->getUpdatedAtColumn();\n\n        if (! is_null($column) &&\n            ! array_key_exists($column, $update) &&\n            ! in_array($column, $update)) {\n            $update[] = $column;\n        }\n\n        return $update;\n    }\n\n    /**\n     * Delete records from the database.\n     *\n     * @return mixed\n     */\n    public function delete()\n    {\n        if (isset($this->onDelete)) {\n            return call_user_func($this->onDelete, $this);\n        }\n\n        return $this->toBase()->delete();\n    }\n\n    /**\n     * Run the default delete function on the builder.\n     *\n     * Since we do not apply scopes here, the row will actually be deleted.\n     *\n     * @return mixed\n     */\n    public function forceDelete()\n    {\n        return $this->query->delete();\n    }\n\n    /**\n     * Register a replacement for the default delete function.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function onDelete(Closure $callback)\n    {\n        $this->onDelete = $callback;\n    }\n\n    /**\n     * Determine if the given model has a scope.\n     *\n     * @param  string  $scope\n     * @return bool\n     */\n    public function hasNamedScope($scope)\n    {\n        return $this->model && $this->model->hasNamedScope($scope);\n    }\n\n    /**\n     * Call the given local model scopes.\n     *\n     * @param  array|string  $scopes\n     * @return static|mixed\n     */\n    public function scopes($scopes)\n    {\n        $builder = $this;\n\n        foreach (Arr::wrap($scopes) as $scope => $parameters) {\n            // If the scope key is an integer, then the scope was passed as the value and\n            // the parameter list is empty, so we will format the scope name and these\n            // parameters here. Then, we'll be ready to call the scope on the model.\n            if (is_int($scope)) {\n                [$scope, $parameters] = [$parameters, []];\n            }\n\n            // Next we'll pass the scope callback to the callScope method which will take\n            // care of grouping the \"wheres\" properly so the logical order doesn't get\n            // messed up when adding scopes. Then we'll return back out the builder.\n            $builder = $builder->callNamedScope(\n                $scope, Arr::wrap($parameters)\n            );\n        }\n\n        return $builder;\n    }\n\n    /**\n     * Apply the scopes to the Eloquent builder instance and return it.\n     *\n     * @return static\n     */\n    public function applyScopes()\n    {\n        if (! $this->scopes) {\n            return $this;\n        }\n\n        $builder = clone $this;\n\n        foreach ($this->scopes as $identifier => $scope) {\n            if (! isset($builder->scopes[$identifier])) {\n                continue;\n            }\n\n            $builder->callScope(function (self $builder) use ($scope) {\n                // If the scope is a Closure we will just go ahead and call the scope with the\n                // builder instance. The \"callScope\" method will properly group the clauses\n                // that are added to this query so \"where\" clauses maintain proper logic.\n                if ($scope instanceof Closure) {\n                    $scope($builder);\n                }\n\n                // If the scope is a scope object, we will call the apply method on this scope\n                // passing in the builder and the model instance. After we run all of these\n                // scopes we will return back the builder instance to the outside caller.\n                if ($scope instanceof Scope) {\n                    $scope->apply($builder, $this->getModel());\n                }\n            });\n        }\n\n        return $builder;\n    }\n\n    /**\n     * Apply the given scope on the current builder instance.\n     *\n     * @param  callable  $scope\n     * @param  array  $parameters\n     * @return mixed\n     */\n    protected function callScope(callable $scope, array $parameters = [])\n    {\n        array_unshift($parameters, $this);\n\n        $query = $this->getQuery();\n\n        // We will keep track of how many wheres are on the query before running the\n        // scope so that we can properly group the added scope constraints in the\n        // query as their own isolated nested where statement and avoid issues.\n        $originalWhereCount = is_null($query->wheres)\n            ? 0\n            : count($query->wheres);\n\n        $result = $scope(...$parameters) ?? $this;\n\n        if (count((array) $query->wheres) > $originalWhereCount) {\n            $this->addNewWheresWithinGroup($query, $originalWhereCount);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Apply the given named scope on the current builder instance.\n     *\n     * @param  string  $scope\n     * @param  array  $parameters\n     * @return mixed\n     */\n    protected function callNamedScope($scope, array $parameters = [])\n    {\n        return $this->callScope(function (...$parameters) use ($scope) {\n            return $this->model->callNamedScope($scope, $parameters);\n        }, $parameters);\n    }\n\n    /**\n     * Nest where conditions by slicing them at the given where count.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  int  $originalWhereCount\n     * @return void\n     */\n    protected function addNewWheresWithinGroup(QueryBuilder $query, $originalWhereCount)\n    {\n        // Here, we totally remove all of the where clauses since we are going to\n        // rebuild them as nested queries by slicing the groups of wheres into\n        // their own sections. This is to prevent any confusing logic order.\n        $allWheres = $query->wheres;\n\n        $query->wheres = [];\n\n        $this->groupWhereSliceForScope(\n            $query, array_slice($allWheres, 0, $originalWhereCount)\n        );\n\n        $this->groupWhereSliceForScope(\n            $query, array_slice($allWheres, $originalWhereCount)\n        );\n    }\n\n    /**\n     * Slice where conditions at the given offset and add them to the query as a nested condition.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $whereSlice\n     * @return void\n     */\n    protected function groupWhereSliceForScope(QueryBuilder $query, $whereSlice)\n    {\n        $whereBooleans = (new BaseCollection($whereSlice))->pluck('boolean');\n\n        // Here we'll check if the given subset of where clauses contains any \"or\"\n        // booleans and in this case create a nested where expression. That way\n        // we don't add any unnecessary nesting thus keeping the query clean.\n        if ($whereBooleans->contains(fn ($logicalOperator) => str_contains($logicalOperator, 'or'))) {\n            $query->wheres[] = $this->createNestedWhere(\n                $whereSlice, str_replace(' not', '', $whereBooleans->first())\n            );\n        } else {\n            $query->wheres = array_merge($query->wheres, $whereSlice);\n        }\n    }\n\n    /**\n     * Create a where array with nested where conditions.\n     *\n     * @param  array  $whereSlice\n     * @param  string  $boolean\n     * @return array\n     */\n    protected function createNestedWhere($whereSlice, $boolean = 'and')\n    {\n        $whereGroup = $this->getQuery()->forNestedWhere();\n\n        $whereGroup->wheres = $whereSlice;\n\n        return ['type' => 'Nested', 'query' => $whereGroup, 'boolean' => $boolean];\n    }\n\n    /**\n     * Specify relationships that should be eager loaded.\n     *\n     * @param  array<array-key, array|(\\Closure(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*,*,*>): mixed)|string>|string  $relations\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*,*,*>): mixed)|string|null  $callback\n     * @return $this\n     */\n    public function with($relations, $callback = null)\n    {\n        if ($callback instanceof Closure) {\n            $eagerLoad = $this->parseWithRelations([$relations => $callback]);\n        } else {\n            $eagerLoad = $this->parseWithRelations(is_string($relations) ? func_get_args() : $relations);\n        }\n\n        $this->eagerLoad = array_merge($this->eagerLoad, $eagerLoad);\n\n        return $this;\n    }\n\n    /**\n     * Prevent the specified relations from being eager loaded.\n     *\n     * @param  mixed  $relations\n     * @return $this\n     */\n    public function without($relations)\n    {\n        $this->eagerLoad = array_diff_key($this->eagerLoad, array_flip(\n            is_string($relations) ? func_get_args() : $relations\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Set the relationships that should be eager loaded while removing any previously added eager loading specifications.\n     *\n     * @param  array<array-key, array|(\\Closure(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*,*,*>): mixed)|string>|string  $relations\n     * @return $this\n     */\n    public function withOnly($relations)\n    {\n        $this->eagerLoad = [];\n\n        return $this->with($relations);\n    }\n\n    /**\n     * Create a new instance of the model being queried.\n     *\n     * @param  array  $attributes\n     * @return TModel\n     */\n    public function newModelInstance($attributes = [])\n    {\n        $attributes = array_merge($this->pendingAttributes, $attributes);\n\n        return $this->model->newInstance($attributes)->setConnection(\n            $this->query->getConnection()->getName()\n        );\n    }\n\n    /**\n     * Parse a list of relations into individuals.\n     *\n     * @param  array  $relations\n     * @return array\n     */\n    protected function parseWithRelations(array $relations)\n    {\n        if ($relations === []) {\n            return [];\n        }\n\n        $results = [];\n\n        foreach ($this->prepareNestedWithRelationships($relations) as $name => $constraints) {\n            // We need to separate out any nested includes, which allows the developers\n            // to load deep relationships using \"dots\" without stating each level of\n            // the relationship with its own key in the array of eager-load names.\n            $results = $this->addNestedWiths($name, $results);\n\n            $results[$name] = $constraints;\n        }\n\n        return $results;\n    }\n\n    /**\n     * Prepare nested with relationships.\n     *\n     * @param  array  $relations\n     * @param  string  $prefix\n     * @return array\n     */\n    protected function prepareNestedWithRelationships($relations, $prefix = '')\n    {\n        $preparedRelationships = [];\n\n        if ($prefix !== '') {\n            $prefix .= '.';\n        }\n\n        // If any of the relationships are formatted with the [$attribute => array()]\n        // syntax, we shall loop over the nested relations and prepend each key of\n        // this array while flattening into the traditional dot notation format.\n        foreach ($relations as $key => $value) {\n            if (! is_string($key) || ! is_array($value)) {\n                continue;\n            }\n\n            [$attribute, $attributeSelectConstraint] = $this->parseNameAndAttributeSelectionConstraint($key);\n\n            $preparedRelationships = array_merge(\n                $preparedRelationships,\n                [\"{$prefix}{$attribute}\" => $attributeSelectConstraint],\n                $this->prepareNestedWithRelationships($value, \"{$prefix}{$attribute}\"),\n            );\n\n            unset($relations[$key]);\n        }\n\n        // We now know that the remaining relationships are in a dot notation format\n        // and may be a string or Closure. We'll loop over them and ensure all of\n        // the present Closures are merged + strings are made into constraints.\n        foreach ($relations as $key => $value) {\n            if (is_numeric($key) && is_string($value)) {\n                [$key, $value] = $this->parseNameAndAttributeSelectionConstraint($value);\n            }\n\n            $preparedRelationships[$prefix.$key] = $this->combineConstraints([\n                $value,\n                $preparedRelationships[$prefix.$key] ?? static function () {\n                    //\n                },\n            ]);\n        }\n\n        return $preparedRelationships;\n    }\n\n    /**\n     * Combine an array of constraints into a single constraint.\n     *\n     * @param  array  $constraints\n     * @return \\Closure\n     */\n    protected function combineConstraints(array $constraints)\n    {\n        return function ($builder) use ($constraints) {\n            foreach ($constraints as $constraint) {\n                $builder = $constraint($builder) ?? $builder;\n            }\n\n            return $builder;\n        };\n    }\n\n    /**\n     * Parse the attribute select constraints from the name.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function parseNameAndAttributeSelectionConstraint($name)\n    {\n        return str_contains($name, ':')\n            ? $this->createSelectWithConstraint($name)\n            : [$name, static function () {\n                //\n            }];\n    }\n\n    /**\n     * Create a constraint to select the given columns for the relation.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function createSelectWithConstraint($name)\n    {\n        return [explode(':', $name)[0], static function ($query) use ($name) {\n            $query->select(array_map(static function ($column) use ($query) {\n                return $query instanceof BelongsToMany\n                    ? $query->getRelated()->qualifyColumn($column)\n                    : $column;\n            }, explode(',', explode(':', $name)[1])));\n        }];\n    }\n\n    /**\n     * Parse the nested relationships in a relation.\n     *\n     * @param  string  $name\n     * @param  array  $results\n     * @return array\n     */\n    protected function addNestedWiths($name, $results)\n    {\n        $progress = [];\n\n        // If the relation has already been set on the result array, we will not set it\n        // again, since that would override any constraints that were already placed\n        // on the relationships. We will only set the ones that are not specified.\n        foreach (explode('.', $name) as $segment) {\n            $progress[] = $segment;\n\n            if (! isset($results[$last = implode('.', $progress)])) {\n                $results[$last] = static function () {\n                    //\n                };\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Specify attributes that should be added to any new models created by this builder.\n     *\n     * The given key / value pairs will also be added as where conditions to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|array|string  $attributes\n     * @param  mixed  $value\n     * @param  bool  $asConditions\n     * @return $this\n     */\n    public function withAttributes(Expression|array|string $attributes, $value = null, $asConditions = true)\n    {\n        if (! is_array($attributes)) {\n            $attributes = [$attributes => $value];\n        }\n\n        if ($asConditions) {\n            foreach ($attributes as $column => $value) {\n                $this->where($this->qualifyColumn($column), $value);\n            }\n        }\n\n        $this->pendingAttributes = array_merge($this->pendingAttributes, $attributes);\n\n        return $this;\n    }\n\n    /**\n     * Apply query-time casts to the model instance.\n     *\n     * @param  array  $casts\n     * @return $this\n     */\n    public function withCasts($casts)\n    {\n        $this->model->mergeCasts($casts);\n\n        return $this;\n    }\n\n    /**\n     * Execute the given Closure within a transaction savepoint if needed.\n     *\n     * @template TModelValue\n     *\n     * @param  \\Closure(): TModelValue  $scope\n     * @return TModelValue\n     */\n    public function withSavepointIfNeeded(Closure $scope): mixed\n    {\n        return $this->getQuery()->getConnection()->transactionLevel() > 0\n            ? $this->getQuery()->getConnection()->transaction($scope)\n            : $scope();\n    }\n\n    /**\n     * Get the Eloquent builder instances that are used in the union of the query.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getUnionBuilders()\n    {\n        return isset($this->query->unions)\n            ? (new BaseCollection($this->query->unions))->pluck('query')\n            : new BaseCollection;\n    }\n\n    /**\n     * Get the underlying query builder instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function getQuery()\n    {\n        return $this->query;\n    }\n\n    /**\n     * Set the underlying query builder instance.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return $this\n     */\n    public function setQuery($query)\n    {\n        $this->query = $query;\n\n        return $this;\n    }\n\n    /**\n     * Get a base query builder instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function toBase()\n    {\n        return $this->applyScopes()->getQuery();\n    }\n\n    /**\n     * Get the relationships being eagerly loaded.\n     *\n     * @return array\n     */\n    public function getEagerLoads()\n    {\n        return $this->eagerLoad;\n    }\n\n    /**\n     * Set the relationships being eagerly loaded.\n     *\n     * @param  array  $eagerLoad\n     * @return $this\n     */\n    public function setEagerLoads(array $eagerLoad)\n    {\n        $this->eagerLoad = $eagerLoad;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given relationships should not be eagerly loaded.\n     *\n     * @param  array  $relations\n     * @return $this\n     */\n    public function withoutEagerLoad(array $relations)\n    {\n        $relations = array_diff(array_keys($this->model->getRelations()), $relations);\n\n        return $this->with($relations);\n    }\n\n    /**\n     * Flush the relationships being eagerly loaded.\n     *\n     * @return $this\n     */\n    public function withoutEagerLoads()\n    {\n        return $this->setEagerLoads([]);\n    }\n\n    /**\n     * Get the \"limit\" value from the query or null if it's not set.\n     *\n     * @return mixed\n     */\n    public function getLimit()\n    {\n        return $this->query->getLimit();\n    }\n\n    /**\n     * Get the \"offset\" value from the query or null if it's not set.\n     *\n     * @return mixed\n     */\n    public function getOffset()\n    {\n        return $this->query->getOffset();\n    }\n\n    /**\n     * Get the default key name of the table.\n     *\n     * @return string\n     */\n    protected function defaultKeyName()\n    {\n        return $this->getModel()->getKeyName();\n    }\n\n    /**\n     * Get the model instance being queried.\n     *\n     * @return TModel\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n    /**\n     * Set a model instance for the model being queried.\n     *\n     * @template TModelNew of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  TModelNew  $model\n     * @return static<TModelNew>\n     */\n    public function setModel(Model $model)\n    {\n        $this->model = $model;\n\n        $this->query->from($model->getTable());\n\n        return $this;\n    }\n\n    /**\n     * Qualify the given column name by the model's table.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return string\n     */\n    public function qualifyColumn($column)\n    {\n        $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;\n\n        return $this->model->qualifyColumn($column);\n    }\n\n    /**\n     * Qualify the given columns with the model's table.\n     *\n     * @param  array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $columns\n     * @return array\n     */\n    public function qualifyColumns($columns)\n    {\n        return $this->model->qualifyColumns($columns);\n    }\n\n    /**\n     * Get the given macro by name.\n     *\n     * @param  string  $name\n     * @return \\Closure\n     */\n    public function getMacro($name)\n    {\n        return Arr::get($this->localMacros, $name);\n    }\n\n    /**\n     * Checks if a macro is registered.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasMacro($name)\n    {\n        return isset($this->localMacros[$name]);\n    }\n\n    /**\n     * Get the given global macro by name.\n     *\n     * @param  string  $name\n     * @return \\Closure\n     */\n    public static function getGlobalMacro($name)\n    {\n        return Arr::get(static::$macros, $name);\n    }\n\n    /**\n     * Checks if a global macro is registered.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public static function hasGlobalMacro($name)\n    {\n        return isset(static::$macros[$name]);\n    }\n\n    /**\n     * Dynamically access builder proxies.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\Exception\n     */\n    public function __get($key)\n    {\n        if (in_array($key, ['orWhere', 'whereNot', 'orWhereNot'])) {\n            return new HigherOrderBuilderProxy($this, $key);\n        }\n\n        if (in_array($key, $this->propertyPassthru)) {\n            return $this->toBase()->{$key};\n        }\n\n        throw new Exception(\"Property [{$key}] does not exist on the Eloquent builder instance.\");\n    }\n\n    /**\n     * Dynamically handle calls into the query instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if ($method === 'macro') {\n            $this->localMacros[$parameters[0]] = $parameters[1];\n\n            return;\n        }\n\n        if ($this->hasMacro($method)) {\n            array_unshift($parameters, $this);\n\n            return $this->localMacros[$method](...$parameters);\n        }\n\n        if (static::hasGlobalMacro($method)) {\n            $callable = static::$macros[$method];\n\n            if ($callable instanceof Closure) {\n                $callable = $callable->bindTo($this, static::class);\n            }\n\n            return $callable(...$parameters);\n        }\n\n        if ($this->hasNamedScope($method)) {\n            return $this->callNamedScope($method, $parameters);\n        }\n\n        if (in_array(strtolower($method), $this->passthru)) {\n            return $this->toBase()->{$method}(...$parameters);\n        }\n\n        $this->forwardCallTo($this->query, $method, $parameters);\n\n        return $this;\n    }\n\n    /**\n     * Dynamically handle calls into the query instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public static function __callStatic($method, $parameters)\n    {\n        if ($method === 'macro') {\n            static::$macros[$parameters[0]] = $parameters[1];\n\n            return;\n        }\n\n        if ($method === 'mixin') {\n            return static::registerMixin($parameters[0], $parameters[1] ?? true);\n        }\n\n        if (! static::hasGlobalMacro($method)) {\n            static::throwBadMethodCallException($method);\n        }\n\n        $callable = static::$macros[$method];\n\n        if ($callable instanceof Closure) {\n            $callable = $callable->bindTo(null, static::class);\n        }\n\n        return $callable(...$parameters);\n    }\n\n    /**\n     * Register the given mixin with the builder.\n     *\n     * @param  string  $mixin\n     * @param  bool  $replace\n     * @return void\n     */\n    protected static function registerMixin($mixin, $replace)\n    {\n        $methods = (new ReflectionClass($mixin))->getMethods(\n            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED\n        );\n\n        foreach ($methods as $method) {\n            if ($replace || ! static::hasGlobalMacro($method->name)) {\n                static::macro($method->name, $method->invoke($mixin));\n            }\n        }\n    }\n\n    /**\n     * Clone the Eloquent query builder.\n     *\n     * @return static\n     */\n    public function clone()\n    {\n        return clone $this;\n    }\n\n    /**\n     * Register a closure to be invoked on a clone.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function onClone(Closure $callback)\n    {\n        $this->onCloneCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Force a clone of the underlying query builder when cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->query = clone $this->query;\n\n        foreach ($this->onCloneCallbacks as $onCloneCallback) {\n            $onCloneCallback($this);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/ArrayObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse ArrayObject as BaseArrayObject;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Collection;\nuse JsonSerializable;\n\n/**\n * @template TKey of array-key\n * @template TItem\n *\n * @extends  \\ArrayObject<TKey, TItem>\n */\nclass ArrayObject extends BaseArrayObject implements Arrayable, JsonSerializable\n{\n    /**\n     * Get a collection containing the underlying array.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function collect()\n    {\n        return new Collection($this->getArrayCopy());\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->getArrayCopy();\n    }\n\n    /**\n     * Get the array that should be JSON serialized.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->getArrayCopy();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\n\nclass AsArrayObject implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Database\\Eloquent\\Casts\\ArrayObject<array-key, mixed>, iterable>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                if (! isset($attributes[$key])) {\n                    return;\n                }\n\n                $data = Json::decode($attributes[$key]);\n\n                return is_array($data) ? new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS) : null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return [$key => Json::encode($value)];\n            }\n\n            public function serialize($model, string $key, $value, array $attributes)\n            {\n                return $value->getArrayCopy();\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsBinary.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\BinaryCodec;\nuse InvalidArgumentException;\n\nclass AsBinary implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array{string}  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            protected string $format;\n\n            public function __construct(protected array $arguments)\n            {\n                $this->format = $this->arguments[0]\n                    ?? throw new InvalidArgumentException('The binary codec format is required.');\n\n                if (! in_array($this->format, BinaryCodec::formats(), true)) {\n                    throw new InvalidArgumentException(sprintf(\n                        'Unsupported binary codec format [%s]. Allowed formats are: %s.',\n                        $this->format,\n                        implode(', ', BinaryCodec::formats()),\n                    ));\n                }\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                return BinaryCodec::decode($attributes[$key] ?? null, $this->format);\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return [$key => BinaryCodec::encode($value, $this->format)];\n            }\n        };\n    }\n\n    /**\n     * Encode / decode values as binary UUIDs.\n     */\n    public static function uuid(): string\n    {\n        return self::class.':uuid';\n    }\n\n    /**\n     * Encode / decode values as binary ULIDs.\n     */\n    public static function ulid(): string\n    {\n        return self::class.':ulid';\n    }\n\n    /**\n     * Encode / decode values using the given format.\n     */\n    public static function of(string $format): string\n    {\n        return self::class.':'.$format;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass AsCollection implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Collection<array-key, mixed>, iterable>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            public function __construct(protected array $arguments)\n            {\n                $this->arguments = array_pad(array_values($this->arguments), 2, '');\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                if (! isset($attributes[$key])) {\n                    return;\n                }\n\n                $data = Json::decode($attributes[$key]);\n\n                $collectionClass = empty($this->arguments[0]) ? Collection::class : $this->arguments[0];\n\n                if (! is_a($collectionClass, Collection::class, true)) {\n                    throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].');\n                }\n\n                if (! is_array($data)) {\n                    return null;\n                }\n\n                $instance = new $collectionClass($data);\n\n                if (! isset($this->arguments[1]) || ! $this->arguments[1]) {\n                    return $instance;\n                }\n\n                if (is_string($this->arguments[1])) {\n                    $this->arguments[1] = Str::parseCallback($this->arguments[1]);\n                }\n\n                return is_callable($this->arguments[1])\n                    ? $instance->map($this->arguments[1])\n                    : $instance->mapInto($this->arguments[1][0]);\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return [$key => Json::encode($value)];\n            }\n        };\n    }\n\n    /**\n     * Specify the type of object each item in the collection should be mapped to.\n     *\n     * @param  array{class-string, string}|class-string  $map\n     * @return string\n     */\n    public static function of($map)\n    {\n        return static::using('', $map);\n    }\n\n    /**\n     * Specify the collection type for the cast.\n     *\n     * @param  class-string  $class\n     * @param  array{class-string, string}|class-string|null  $map\n     * @return string\n     */\n    public static function using($class, $map = null)\n    {\n        if (is_array($map) && is_callable($map)) {\n            $map = $map[0].'@'.$map[1];\n        }\n\n        return static::class.':'.implode(',', [$class, $map]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Facades\\Crypt;\n\nclass AsEncryptedArrayObject implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Database\\Eloquent\\Casts\\ArrayObject<array-key, mixed>, iterable>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                if (isset($attributes[$key])) {\n                    return new ArrayObject(Json::decode(Crypt::decryptString($attributes[$key])), ArrayObject::ARRAY_AS_PROPS);\n                }\n\n                return null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                if (! is_null($value)) {\n                    return [$key => Crypt::encryptString(Json::encode($value))];\n                }\n\n                return null;\n            }\n\n            public function serialize($model, string $key, $value, array $attributes)\n            {\n                return ! is_null($value) ? $value->getArrayCopy() : null;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Crypt;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass AsEncryptedCollection implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Collection<array-key, mixed>, iterable>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            public function __construct(protected array $arguments)\n            {\n                $this->arguments = array_pad(array_values($this->arguments), 2, '');\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                $collectionClass = empty($this->arguments[0]) ? Collection::class : $this->arguments[0];\n\n                if (! is_a($collectionClass, Collection::class, true)) {\n                    throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].');\n                }\n\n                if (! isset($attributes[$key])) {\n                    return null;\n                }\n\n                $instance = new $collectionClass(Json::decode(Crypt::decryptString($attributes[$key])));\n\n                if (! isset($this->arguments[1]) || ! $this->arguments[1]) {\n                    return $instance;\n                }\n\n                if (is_string($this->arguments[1])) {\n                    $this->arguments[1] = Str::parseCallback($this->arguments[1]);\n                }\n\n                return is_callable($this->arguments[1])\n                    ? $instance->map($this->arguments[1])\n                    : $instance->mapInto($this->arguments[1][0]);\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                if (! is_null($value)) {\n                    return [$key => Crypt::encryptString(Json::encode($value))];\n                }\n\n                return null;\n            }\n        };\n    }\n\n    /**\n     * Specify the type of object each item in the collection should be mapped to.\n     *\n     * @param  array{class-string, string}|class-string  $map\n     * @return string\n     */\n    public static function of($map)\n    {\n        return static::using('', $map);\n    }\n\n    /**\n     * Specify the collection for the cast.\n     *\n     * @param  class-string  $class\n     * @param  array{class-string, string}|class-string|null  $map\n     * @return string\n     */\n    public static function using($class, $map = null)\n    {\n        if (is_array($map) && is_callable($map)) {\n            $map = $map[0].'@'.$map[1];\n        }\n\n        return static::class.':'.implode(',', [$class, $map]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsEnumArrayObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse BackedEnum;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass AsEnumArrayObject implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @template TEnum of \\UnitEnum\n     *\n     * @param  array{class-string<TEnum>}  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Database\\Eloquent\\Casts\\ArrayObject<array-key, TEnum>, iterable<TEnum>>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            protected $arguments;\n\n            public function __construct(array $arguments)\n            {\n                $this->arguments = $arguments;\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                if (! isset($attributes[$key])) {\n                    return;\n                }\n\n                $data = Json::decode($attributes[$key]);\n\n                if (! is_array($data)) {\n                    return;\n                }\n\n                $enumClass = $this->arguments[0];\n\n                return new ArrayObject((new Collection($data))->map(function ($value) use ($enumClass) {\n                    return is_subclass_of($enumClass, BackedEnum::class)\n                        ? $enumClass::from($value)\n                        : constant($enumClass.'::'.$value);\n                })->toArray());\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                if ($value === null) {\n                    return [$key => null];\n                }\n\n                $storable = [];\n\n                foreach ($value as $enum) {\n                    $storable[] = $this->getStorableEnumValue($enum);\n                }\n\n                return [$key => Json::encode($storable)];\n            }\n\n            public function serialize($model, string $key, $value, array $attributes)\n            {\n                return (new Collection($value->getArrayCopy()))\n                    ->map(fn ($enum) => $this->getStorableEnumValue($enum))\n                    ->toArray();\n            }\n\n            protected function getStorableEnumValue($enum)\n            {\n                if (is_string($enum) || is_int($enum)) {\n                    return $enum;\n                }\n\n                return enum_value($enum);\n            }\n        };\n    }\n\n    /**\n     * Specify the Enum for the cast.\n     *\n     * @param  class-string  $class\n     * @return string\n     */\n    public static function of($class)\n    {\n        return static::class.':'.$class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsEnumCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse BackedEnum;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass AsEnumCollection implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @template TEnum of \\UnitEnum\n     *\n     * @param  array{class-string<TEnum>}  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Collection<array-key, TEnum>, iterable<TEnum>>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class($arguments) implements CastsAttributes\n        {\n            protected $arguments;\n\n            public function __construct(array $arguments)\n            {\n                $this->arguments = $arguments;\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                if (! isset($attributes[$key])) {\n                    return;\n                }\n\n                $data = Json::decode($attributes[$key]);\n\n                if (! is_array($data)) {\n                    return;\n                }\n\n                $enumClass = $this->arguments[0];\n\n                return (new Collection($data))->map(function ($value) use ($enumClass) {\n                    return is_subclass_of($enumClass, BackedEnum::class)\n                        ? $enumClass::from($value)\n                        : constant($enumClass.'::'.$value);\n                });\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                $value = $value !== null\n                    ? Json::encode((new Collection($value))->map(function ($enum) {\n                        return $this->getStorableEnumValue($enum);\n                    })->jsonSerialize())\n                    : null;\n\n                return [$key => $value];\n            }\n\n            public function serialize($model, string $key, $value, array $attributes)\n            {\n                return (new Collection($value))\n                    ->map(fn ($enum) => $this->getStorableEnumValue($enum))\n                    ->toArray();\n            }\n\n            protected function getStorableEnumValue($enum)\n            {\n                if (is_string($enum) || is_int($enum)) {\n                    return $enum;\n                }\n\n                return enum_value($enum);\n            }\n        };\n    }\n\n    /**\n     * Specify the Enum for the cast.\n     *\n     * @param  class-string  $class\n     * @return string\n     */\n    public static function of($class)\n    {\n        return static::class.':'.$class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsFluent.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Fluent;\n\nclass AsFluent implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Fluent, string>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                return isset($value) ? new Fluent(Json::decode($value)) : null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return isset($value) ? [$key => Json::encode($value)] : null;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsHtmlString.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\HtmlString;\n\nclass AsHtmlString implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\HtmlString, string|HtmlString>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                return isset($value) ? new HtmlString($value) : null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return isset($value) ? (string) $value : null;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsStringable.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Stringable;\n\nclass AsStringable implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Stringable, string|\\Stringable>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                return isset($value) ? new Stringable($value) : null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return isset($value) ? (string) $value : null;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/AsUri.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Support\\Uri;\n\nclass AsUri implements Castable\n{\n    /**\n     * Get the caster class to use when casting from / to this cast target.\n     *\n     * @param  array  $arguments\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes<\\Illuminate\\Support\\Uri, string|Uri>\n     */\n    public static function castUsing(array $arguments)\n    {\n        return new class implements CastsAttributes\n        {\n            public function get($model, $key, $value, $attributes)\n            {\n                return isset($value) ? new Uri($value) : null;\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return isset($value) ? (string) $value : null;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/Attribute.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nclass Attribute\n{\n    /**\n     * The attribute accessor.\n     *\n     * @var callable\n     */\n    public $get;\n\n    /**\n     * The attribute mutator.\n     *\n     * @var callable\n     */\n    public $set;\n\n    /**\n     * Indicates if caching is enabled for this attribute.\n     *\n     * @var bool\n     */\n    public $withCaching = false;\n\n    /**\n     * Indicates if caching of objects is enabled for this attribute.\n     *\n     * @var bool\n     */\n    public $withObjectCaching = true;\n\n    /**\n     * Create a new attribute accessor / mutator.\n     *\n     * @param  callable|null  $get\n     * @param  callable|null  $set\n     */\n    public function __construct(?callable $get = null, ?callable $set = null)\n    {\n        $this->get = $get;\n        $this->set = $set;\n    }\n\n    /**\n     * Create a new attribute accessor / mutator.\n     *\n     * @param  callable|null  $get\n     * @param  callable|null  $set\n     * @return static\n     */\n    public static function make(?callable $get = null, ?callable $set = null): static\n    {\n        return new static($get, $set);\n    }\n\n    /**\n     * Create a new attribute accessor.\n     *\n     * @param  callable  $get\n     * @return static\n     */\n    public static function get(callable $get)\n    {\n        return new static($get);\n    }\n\n    /**\n     * Create a new attribute mutator.\n     *\n     * @param  callable  $set\n     * @return static\n     */\n    public static function set(callable $set)\n    {\n        return new static(null, $set);\n    }\n\n    /**\n     * Disable object caching for the attribute.\n     *\n     * @return static\n     */\n    public function withoutObjectCaching()\n    {\n        $this->withObjectCaching = false;\n\n        return $this;\n    }\n\n    /**\n     * Enable caching for the attribute.\n     *\n     * @return static\n     */\n    public function shouldCache()\n    {\n        $this->withCaching = true;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Casts/Json.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Casts;\n\nclass Json\n{\n    /**\n     * The custom JSON encoder.\n     *\n     * @var callable|null\n     */\n    protected static $encoder;\n\n    /**\n     * The custom JSON decode.\n     *\n     * @var callable|null\n     */\n    protected static $decoder;\n\n    /**\n     * Encode the given value.\n     */\n    public static function encode(mixed $value, int $flags = 0): mixed\n    {\n        return isset(static::$encoder)\n            ? (static::$encoder)($value, $flags)\n            : json_encode($value, $flags);\n    }\n\n    /**\n     * Decode the given value.\n     */\n    public static function decode(mixed $value, ?bool $associative = true): mixed\n    {\n        return isset(static::$decoder)\n            ? (static::$decoder)($value, $associative)\n            : json_decode($value, $associative);\n    }\n\n    /**\n     * Encode all values using the given callable.\n     */\n    public static function encodeUsing(?callable $encoder): void\n    {\n        static::$encoder = $encoder;\n    }\n\n    /**\n     * Decode all values using the given callable.\n     */\n    public static function decodeUsing(?callable $decoder): void\n    {\n        static::$decoder = $decoder;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Collection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Contracts\\Queue\\QueueableCollection;\nuse Illuminate\\Contracts\\Queue\\QueueableEntity;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse LogicException;\n\n/**\n * @template TKey of array-key\n * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Support\\Collection<TKey, TModel>\n */\nclass Collection extends BaseCollection implements QueueableCollection\n{\n    use InteractsWithDictionary;\n\n    /**\n     * Find a model in the collection by key.\n     *\n     * @template TFindDefault\n     *\n     * @param  mixed  $key\n     * @param  TFindDefault  $default\n     * @return ($key is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? static : TModel|TFindDefault)\n     */\n    public function find($key, $default = null)\n    {\n        if ($key instanceof Model) {\n            $key = $key->getKey();\n        }\n\n        if ($key instanceof Arrayable) {\n            $key = $key->toArray();\n        }\n\n        if (is_array($key)) {\n            if ($this->isEmpty()) {\n                return new static;\n            }\n\n            return $this->whereIn($this->first()->getKeyName(), $key);\n        }\n\n        return Arr::first($this->items, fn ($model) => $model->getKey() == $key, $default);\n    }\n\n    /**\n     * Find a model in the collection by key or throw an exception.\n     *\n     * @param  mixed  $key\n     * @return TModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException\n     */\n    public function findOrFail($key)\n    {\n        $result = $this->find($key);\n\n        if (is_array($key) && count($result) === count(array_unique($key))) {\n            return $result;\n        } elseif (! is_array($key) && ! is_null($result)) {\n            return $result;\n        }\n\n        $exception = new ModelNotFoundException;\n\n        if (! $model = head($this->items)) {\n            throw $exception;\n        }\n\n        $ids = is_array($key) ? array_diff($key, $result->modelKeys()) : $key;\n\n        $exception->setModel(get_class($model), $ids);\n\n        throw $exception;\n    }\n\n    /**\n     * Load a set of relationships onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @return $this\n     */\n    public function load($relations)\n    {\n        if ($this->isNotEmpty()) {\n            if (is_string($relations)) {\n                $relations = func_get_args();\n            }\n\n            $query = $this->first()->newQueryWithoutRelationships()->with($relations);\n\n            $this->items = $query->eagerLoadRelations($this->items);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Load a set of aggregations over relationship's column onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @param  string  $column\n     * @param  string|null  $function\n     * @return $this\n     */\n    public function loadAggregate($relations, $column, $function = null)\n    {\n        if ($this->isEmpty()) {\n            return $this;\n        }\n\n        $models = $this->first()->newModelQuery()\n            ->whereKey($this->modelKeys())\n            ->select($this->first()->getKeyName())\n            ->withAggregate($relations, $column, $function)\n            ->get()\n            ->keyBy($this->first()->getKeyName());\n\n        $attributes = Arr::except(\n            array_keys($models->first()->getAttributes()),\n            $models->first()->getKeyName()\n        );\n\n        $this->each(function ($model) use ($models, $attributes) {\n            $extraAttributes = Arr::only($models->get($model->getKey())->getAttributes(), $attributes);\n\n            $model->forceFill($extraAttributes)\n                ->syncOriginalAttributes($attributes)\n                ->mergeCasts($models->get($model->getKey())->getCasts());\n        });\n\n        return $this;\n    }\n\n    /**\n     * Load a set of relationship counts onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @return $this\n     */\n    public function loadCount($relations)\n    {\n        return $this->loadAggregate($relations, '*', 'count');\n    }\n\n    /**\n     * Load a set of relationship's max column values onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMax($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'max');\n    }\n\n    /**\n     * Load a set of relationship's min column values onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMin($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'min');\n    }\n\n    /**\n     * Load a set of relationship's column summations onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadSum($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'sum');\n    }\n\n    /**\n     * Load a set of relationship's average column values onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadAvg($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'avg');\n    }\n\n    /**\n     * Load a set of related existences onto the collection.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @return $this\n     */\n    public function loadExists($relations)\n    {\n        return $this->loadAggregate($relations, '*', 'exists');\n    }\n\n    /**\n     * Load a set of relationships onto the collection if they are not already eager loaded.\n     *\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>|string  $relations\n     * @return $this\n     */\n    public function loadMissing($relations)\n    {\n        if (is_string($relations)) {\n            $relations = func_get_args();\n        }\n\n        if ($this->isNotEmpty()) {\n            $query = $this->first()->newQueryWithoutRelationships()->with($relations);\n\n            foreach ($query->getEagerLoads() as $key => $value) {\n                $segments = explode('.', explode(':', $key)[0]);\n\n                if (str_contains($key, ':')) {\n                    $segments[count($segments) - 1] .= ':'.explode(':', $key)[1];\n                }\n\n                $path = [];\n\n                foreach ($segments as $segment) {\n                    $path[] = [$segment => $segment];\n                }\n\n                if (is_callable($value)) {\n                    $path[count($segments) - 1][array_last($segments)] = $value;\n                }\n\n                $this->loadMissingRelation($this, $path);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Load a relationship path for models of the given type if it is not already eager loaded.\n     *\n     * @param  array<int, <string, class-string>>  $tuples\n     * @return void\n     */\n    public function loadMissingRelationshipChain(array $tuples)\n    {\n        [$relation, $class] = array_shift($tuples);\n\n        $this->filter(function ($model) use ($relation, $class) {\n            return ! is_null($model) &&\n                ! $model->relationLoaded($relation) &&\n                $model::class === $class;\n        })->load($relation);\n\n        if (empty($tuples)) {\n            return;\n        }\n\n        $models = $this->pluck($relation)->whereNotNull();\n\n        if ($models->first() instanceof BaseCollection) {\n            $models = $models->collapse();\n        }\n\n        (new static($models))->loadMissingRelationshipChain($tuples);\n    }\n\n    /**\n     * Load a relationship path if it is not already eager loaded.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>  $models\n     * @param  array  $path\n     * @return void\n     */\n    protected function loadMissingRelation(self $models, array $path)\n    {\n        $relation = array_shift($path);\n\n        $name = explode(':', key($relation))[0];\n\n        if (is_string(reset($relation))) {\n            $relation = reset($relation);\n        }\n\n        $models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation);\n\n        if (empty($path)) {\n            return;\n        }\n\n        $models = $models->pluck($name)->filter();\n\n        if ($models->first() instanceof BaseCollection) {\n            $models = $models->collapse();\n        }\n\n        $this->loadMissingRelation(new static($models), $path);\n    }\n\n    /**\n     * Load a set of relationships onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>  $relations\n     * @return $this\n     */\n    public function loadMorph($relation, $relations)\n    {\n        $this->pluck($relation)\n            ->filter()\n            ->groupBy(fn ($model) => get_class($model))\n            ->each(fn ($models, $className) => static::make($models)->load($relations[$className] ?? []));\n\n        return $this;\n    }\n\n    /**\n     * Load a set of relationship counts onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array<array-key, array|(callable(\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|string>  $relations\n     * @return $this\n     */\n    public function loadMorphCount($relation, $relations)\n    {\n        $this->pluck($relation)\n            ->filter()\n            ->groupBy(fn ($model) => get_class($model))\n            ->each(fn ($models, $className) => static::make($models)->loadCount($relations[$className] ?? []));\n\n        return $this;\n    }\n\n    /**\n     * Determine if a key exists in the collection.\n     *\n     * @param  (callable(TModel, TKey): bool)|TModel|string|int  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function contains($key, $operator = null, $value = null)\n    {\n        if (func_num_args() > 1 || $this->useAsCallable($key)) {\n            return parent::contains(...func_get_args());\n        }\n\n        if ($key instanceof Model) {\n            return parent::contains(fn ($model) => $model->is($key));\n        }\n\n        return parent::contains(fn ($model) => $model->getKey() == $key);\n    }\n\n    /**\n     * Determine if a key does not exist in the collection.\n     *\n     * @param  (callable(TModel, TKey): bool)|TModel|string|int  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function doesntContain($key, $operator = null, $value = null)\n    {\n        return ! $this->contains(...func_get_args());\n    }\n\n    /**\n     * Get the array of primary keys.\n     *\n     * @return array<int, array-key>\n     */\n    public function modelKeys()\n    {\n        return array_map(fn ($model) => $model->getKey(), $this->items);\n    }\n\n    /**\n     * Merge the collection with the given items.\n     *\n     * @param  iterable<array-key, TModel>  $items\n     * @return static\n     */\n    public function merge($items)\n    {\n        $dictionary = $this->getDictionary();\n\n        foreach ($items as $item) {\n            $key = $this->getDictionaryKey($item->getKey());\n\n            if ($key !== null) {\n                $dictionary[$key] = $item;\n            }\n        }\n\n        return new static(array_values($dictionary));\n    }\n\n    /**\n     * Run a map over each of the items.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TModel, TKey): TMapValue  $callback\n     * @return \\Illuminate\\Support\\Collection<TKey, TMapValue>|static<TKey, TMapValue>\n     */\n    public function map(callable $callback)\n    {\n        $result = parent::map($callback);\n\n        return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;\n    }\n\n    /**\n     * Run an associative map over each of the items.\n     *\n     * The callback should return an associative array with a single key / value pair.\n     *\n     * @template TMapWithKeysKey of array-key\n     * @template TMapWithKeysValue\n     *\n     * @param  callable(TModel, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback\n     * @return \\Illuminate\\Support\\Collection<TMapWithKeysKey, TMapWithKeysValue>|static<TMapWithKeysKey, TMapWithKeysValue>\n     */\n    public function mapWithKeys(callable $callback)\n    {\n        $result = parent::mapWithKeys($callback);\n\n        return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result;\n    }\n\n    /**\n     * Reload a fresh model instance from the database for all the entities.\n     *\n     * @param  array<array-key, string>|string  $with\n     * @return static\n     */\n    public function fresh($with = [])\n    {\n        if ($this->isEmpty()) {\n            return new static;\n        }\n\n        $model = $this->first();\n\n        $freshModels = $model->newQueryWithoutScopes()\n            ->with(is_string($with) ? func_get_args() : $with)\n            ->whereIn($model->getKeyName(), $this->modelKeys())\n            ->get()\n            ->getDictionary();\n\n        return $this->filter(fn ($model) => $model->exists && isset($freshModels[$model->getKey()]))\n            ->map(fn ($model) => $freshModels[$model->getKey()]);\n    }\n\n    /**\n     * Diff the collection with the given items.\n     *\n     * @param  iterable<array-key, TModel>  $items\n     * @return static\n     */\n    public function diff($items)\n    {\n        $diff = new static;\n\n        $dictionary = $this->getDictionary($items);\n\n        foreach ($this->items as $item) {\n            $key = $this->getDictionaryKey($item->getKey());\n\n            if ($key === null || ! isset($dictionary[$key])) {\n                $diff->add($item);\n            }\n        }\n\n        return $diff;\n    }\n\n    /**\n     * Intersect the collection with the given items.\n     *\n     * @param  iterable<array-key, TModel>  $items\n     * @return static\n     */\n    public function intersect($items)\n    {\n        $intersect = new static;\n\n        if (empty($items)) {\n            return $intersect;\n        }\n\n        $dictionary = $this->getDictionary($items);\n\n        foreach ($this->items as $item) {\n            $key = $this->getDictionaryKey($item->getKey());\n\n            if ($key !== null && isset($dictionary[$key])) {\n                $intersect->add($item);\n            }\n        }\n\n        return $intersect;\n    }\n\n    /**\n     * Return only unique items from the collection.\n     *\n     * @param  (callable(TModel, TKey): mixed)|string|null  $key\n     * @param  bool  $strict\n     * @return static\n     */\n    public function unique($key = null, $strict = false)\n    {\n        if (! is_null($key)) {\n            return parent::unique($key, $strict);\n        }\n\n        return new static(array_values($this->getDictionary()));\n    }\n\n    /**\n     * Returns only the models from the collection with the specified keys.\n     *\n     * @param  array<array-key, mixed>|null  $keys\n     * @return static\n     */\n    public function only($keys)\n    {\n        if (is_null($keys)) {\n            return new static($this->items);\n        }\n\n        $dictionary = Arr::only($this->getDictionary(), array_map($this->getDictionaryKey(...), (array) $keys));\n\n        return new static(array_values($dictionary));\n    }\n\n    /**\n     * Returns all models in the collection except the models with specified keys.\n     *\n     * @param  array<array-key, mixed>|null  $keys\n     * @return static\n     */\n    public function except($keys)\n    {\n        if (is_null($keys)) {\n            return new static($this->items);\n        }\n\n        $dictionary = Arr::except($this->getDictionary(), array_map($this->getDictionaryKey(...), (array) $keys));\n\n        return new static(array_values($dictionary));\n    }\n\n    /**\n     * Make the given, typically visible, attributes hidden across the entire collection.\n     *\n     * @param  array<array-key, string>|string  $attributes\n     * @return $this\n     */\n    public function makeHidden($attributes)\n    {\n        return $this->each->makeHidden($attributes);\n    }\n\n    /**\n     * Merge the given, typically visible, attributes hidden across the entire collection.\n     *\n     * @param  array<array-key, string>|string  $attributes\n     * @return $this\n     */\n    public function mergeHidden($attributes)\n    {\n        return $this->each->mergeHidden($attributes);\n    }\n\n    /**\n     * Set the hidden attributes across the entire collection.\n     *\n     * @param  array<int, string>  $hidden\n     * @return $this\n     */\n    public function setHidden($hidden)\n    {\n        return $this->each->setHidden($hidden);\n    }\n\n    /**\n     * Make the given, typically hidden, attributes visible across the entire collection.\n     *\n     * @param  array<array-key, string>|string  $attributes\n     * @return $this\n     */\n    public function makeVisible($attributes)\n    {\n        return $this->each->makeVisible($attributes);\n    }\n\n    /**\n     * Merge the given, typically hidden, attributes visible across the entire collection.\n     *\n     * @param  array<array-key, string>|string  $attributes\n     * @return $this\n     */\n    public function mergeVisible($attributes)\n    {\n        return $this->each->mergeVisible($attributes);\n    }\n\n    /**\n     * Set the visible attributes across the entire collection.\n     *\n     * @param  array<int, string>  $visible\n     * @return $this\n     */\n    public function setVisible($visible)\n    {\n        return $this->each->setVisible($visible);\n    }\n\n    /**\n     * Append an attribute across the entire collection.\n     *\n     * @param  array<array-key, string>|string  $attributes\n     * @return $this\n     */\n    public function append($attributes)\n    {\n        return $this->each->append($attributes);\n    }\n\n    /**\n     * Sets the appends on every element of the collection, overwriting the existing appends for each.\n     *\n     * @param  array<array-key, mixed>  $appends\n     * @return $this\n     */\n    public function setAppends(array $appends)\n    {\n        return $this->each->setAppends($appends);\n    }\n\n    /**\n     * Remove appended properties from every element in the collection.\n     *\n     * @return $this\n     */\n    public function withoutAppends()\n    {\n        return $this->setAppends([]);\n    }\n\n    /**\n     * Get a dictionary keyed by primary keys.\n     *\n     * @param  iterable<array-key, TModel>|null  $items\n     * @return array<array-key, TModel>\n     */\n    public function getDictionary($items = null)\n    {\n        $items = is_null($items) ? $this->items : $items;\n\n        $dictionary = [];\n\n        foreach ($items as $value) {\n            $key = $this->getDictionaryKey($value->getKey());\n\n            if ($key !== null) {\n                $dictionary[$key] = $value;\n            }\n        }\n\n        return $dictionary;\n    }\n\n    /**\n     * The following methods are intercepted to always return base collections.\n     */\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<array-key, int>\n     */\n    #[\\Override]\n    public function countBy($countBy = null)\n    {\n        return $this->toBase()->countBy($countBy);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<int, mixed>\n     */\n    #[\\Override]\n    public function collapse()\n    {\n        return $this->toBase()->collapse();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<int, mixed>\n     */\n    #[\\Override]\n    public function flatten($depth = INF)\n    {\n        return $this->toBase()->flatten($depth);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<TModel, TKey>\n     */\n    #[\\Override]\n    public function flip()\n    {\n        return $this->toBase()->flip();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<int, TKey>\n     */\n    #[\\Override]\n    public function keys()\n    {\n        return $this->toBase()->keys();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @template TPadValue\n     *\n     * @return \\Illuminate\\Support\\Collection<int, TModel|TPadValue>\n     */\n    #[\\Override]\n    public function pad($size, $value)\n    {\n        return $this->toBase()->pad($size, $value);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<int<0, 1>, static<TKey, TModel>>\n     */\n    #[\\Override]\n    public function partition($key, $operator = null, $value = null)\n    {\n        return parent::partition(...func_get_args())->toBase();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @return \\Illuminate\\Support\\Collection<array-key, mixed>\n     */\n    #[\\Override]\n    public function pluck($value, $key = null)\n    {\n        return $this->toBase()->pluck($value, $key);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @template TZipValue\n     *\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Support\\Collection<int, TModel|TZipValue>>\n     */\n    #[\\Override]\n    public function zip($items)\n    {\n        return $this->toBase()->zip(...func_get_args());\n    }\n\n    /**\n     * Get the comparison function to detect duplicates.\n     *\n     * @return callable(TModel, TModel): bool\n     */\n    protected function duplicateComparator($strict)\n    {\n        return fn ($a, $b) => $a->is($b);\n    }\n\n    /**\n     * Enable relationship autoloading for all models in this collection.\n     *\n     * @return $this\n     */\n    public function withRelationshipAutoloading()\n    {\n        $callback = fn ($tuples) => $this->loadMissingRelationshipChain($tuples);\n\n        foreach ($this as $model) {\n            if (! $model->hasRelationAutoloadCallback()) {\n                $model->autoloadRelationsUsing($callback, $this);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the type of the entities being queued.\n     *\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    public function getQueueableClass()\n    {\n        if ($this->isEmpty()) {\n            return;\n        }\n\n        $class = $this->getQueueableModelClass($this->first());\n\n        $this->each(function ($model) use ($class) {\n            if ($this->getQueueableModelClass($model) !== $class) {\n                throw new LogicException('Queueing collections with multiple model types is not supported.');\n            }\n        });\n\n        return $class;\n    }\n\n    /**\n     * Get the queueable class name for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return string\n     */\n    protected function getQueueableModelClass($model)\n    {\n        return method_exists($model, 'getQueueableClassName')\n            ? $model->getQueueableClassName()\n            : get_class($model);\n    }\n\n    /**\n     * Get the identifiers for all of the entities.\n     *\n     * @return array<int, mixed>\n     */\n    public function getQueueableIds()\n    {\n        if ($this->isEmpty()) {\n            return [];\n        }\n\n        return $this->first() instanceof QueueableEntity\n            ? $this->map->getQueueableId()->all()\n            : $this->modelKeys();\n    }\n\n    /**\n     * Get the relationships of the entities being queued.\n     *\n     * @return array<int, string>\n     */\n    public function getQueueableRelations()\n    {\n        if ($this->isEmpty()) {\n            return [];\n        }\n\n        $relations = $this->map->getQueueableRelations()->all();\n\n        if (count($relations) === 0 || $relations === [[]]) {\n            return [];\n        } elseif (count($relations) === 1) {\n            return reset($relations);\n        } else {\n            return array_intersect(...array_values($relations));\n        }\n    }\n\n    /**\n     * Get the connection of the entities being queued.\n     *\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    public function getQueueableConnection()\n    {\n        if ($this->isEmpty()) {\n            return;\n        }\n\n        $connection = $this->first()->getConnectionName();\n\n        $this->each(function ($model) use ($connection) {\n            if ($model->getConnectionName() !== $connection) {\n                throw new LogicException('Queueing collections with multiple model connections is not supported.');\n            }\n        });\n\n        return $connection;\n    }\n\n    /**\n     * Get the Eloquent query builder from the collection.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TModel>\n     *\n     * @throws \\LogicException\n     */\n    public function toQuery()\n    {\n        $model = $this->first();\n\n        if (! $model) {\n            throw new LogicException('Unable to create query for empty collection.');\n        }\n\n        $class = get_class($model);\n\n        if ($this->reject(fn ($model) => $model instanceof $class)->isNotEmpty()) {\n            throw new LogicException('Unable to create query for collection with mixed types.');\n        }\n\n        return $model->newModelQuery()->whereKey($this->modelKeys());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Fillable;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Guarded;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Unguarded;\n\ntrait GuardsAttributes\n{\n    /**\n     * The attributes that are mass assignable.\n     *\n     * @var array<int, string>\n     */\n    protected $fillable = [];\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var array<string>\n     */\n    protected $guarded = ['*'];\n\n    /**\n     * Indicates if all mass assignment is enabled.\n     *\n     * @var bool\n     */\n    protected static $unguarded = false;\n\n    /**\n     * The actual columns that exist on the database and can be guarded.\n     *\n     * @var array<class-string,list<string>>\n     */\n    protected static $guardableColumns = [];\n\n    /**\n     * Initialize the GuardsAttributes trait.\n     *\n     * @return void\n     */\n    #[Initialize]\n    public function initializeGuardsAttributes()\n    {\n        if (empty($this->fillable)) {\n            $this->fillable = static::resolveClassAttribute(Fillable::class, 'columns') ?? [];\n        }\n\n        if ($this->guarded === ['*']) {\n            if (static::resolveClassAttribute(Unguarded::class) !== null) {\n                $this->guarded = [];\n            } else {\n                $this->guarded = static::resolveClassAttribute(Guarded::class, 'columns') ?? ['*'];\n            }\n        }\n    }\n\n    /**\n     * Get the fillable attributes for the model.\n     *\n     * @return array<string>\n     */\n    public function getFillable()\n    {\n        return $this->fillable;\n    }\n\n    /**\n     * Set the fillable attributes for the model.\n     *\n     * @param  array<string>  $fillable\n     * @return $this\n     */\n    public function fillable(array $fillable)\n    {\n        $this->fillable = $fillable;\n\n        return $this;\n    }\n\n    /**\n     * Merge new fillable attributes with existing fillable attributes on the model.\n     *\n     * @param  array<string>  $fillable\n     * @return $this\n     */\n    public function mergeFillable(array $fillable)\n    {\n        $this->fillable = array_values(array_unique(array_merge($this->fillable, $fillable)));\n\n        return $this;\n    }\n\n    /**\n     * Get the guarded attributes for the model.\n     *\n     * @return array<string>\n     */\n    public function getGuarded()\n    {\n        return self::$unguarded === true\n            ? []\n            : $this->guarded;\n    }\n\n    /**\n     * Set the guarded attributes for the model.\n     *\n     * @param  array<string>  $guarded\n     * @return $this\n     */\n    public function guard(array $guarded)\n    {\n        $this->guarded = $guarded;\n\n        return $this;\n    }\n\n    /**\n     * Merge new guarded attributes with existing guarded attributes on the model.\n     *\n     * @param  array<string>  $guarded\n     * @return $this\n     */\n    public function mergeGuarded(array $guarded)\n    {\n        $this->guarded = array_values(array_unique(array_merge($this->guarded, $guarded)));\n\n        return $this;\n    }\n\n    /**\n     * Disable all mass assignable restrictions.\n     *\n     * @param  bool  $state\n     * @return void\n     */\n    public static function unguard($state = true)\n    {\n        static::$unguarded = $state;\n    }\n\n    /**\n     * Enable the mass assignment restrictions.\n     *\n     * @return void\n     */\n    public static function reguard()\n    {\n        static::$unguarded = false;\n    }\n\n    /**\n     * Determine if the current state is \"unguarded\".\n     *\n     * @return bool\n     */\n    public static function isUnguarded()\n    {\n        return static::$unguarded;\n    }\n\n    /**\n     * Run the given callable while being unguarded.\n     *\n     * @template TReturn\n     *\n     * @param  callable(): TReturn  $callback\n     * @return TReturn\n     */\n    public static function unguarded(callable $callback)\n    {\n        if (static::$unguarded) {\n            return $callback();\n        }\n\n        static::unguard();\n\n        try {\n            return $callback();\n        } finally {\n            static::reguard();\n        }\n    }\n\n    /**\n     * Determine if the given attribute may be mass assigned.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function isFillable($key)\n    {\n        if (static::$unguarded) {\n            return true;\n        }\n\n        // If the key is in the \"fillable\" array, we can of course assume that it's\n        // a fillable attribute. Otherwise, we will check the guarded array when\n        // we need to determine if the attribute is black-listed on the model.\n        if (in_array($key, $this->getFillable())) {\n            return true;\n        }\n\n        // If the attribute is explicitly listed in the \"guarded\" array then we can\n        // return false immediately. This means this attribute is definitely not\n        // fillable and there is no point in going any further in this method.\n        if ($this->isGuarded($key)) {\n            return false;\n        }\n\n        return empty($this->getFillable()) &&\n            ! str_contains($key, '.') &&\n            ! str_starts_with($key, '_');\n    }\n\n    /**\n     * Determine if the given key is guarded.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function isGuarded($key)\n    {\n        if (empty($this->getGuarded())) {\n            return false;\n        }\n\n        return $this->getGuarded() == ['*'] ||\n               ! empty(preg_grep('/^'.preg_quote($key, '/').'$/i', $this->getGuarded())) ||\n               ! $this->isGuardableColumn($key);\n    }\n\n    /**\n     * Determine if the given column is a valid, guardable column.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isGuardableColumn($key)\n    {\n        if ($this->hasSetMutator($key) || $this->hasAttributeSetMutator($key) || $this->isClassCastable($key)) {\n            return true;\n        }\n\n        if (! isset(static::$guardableColumns[get_class($this)])) {\n            $columns = $this->getConnection()\n                ->getSchemaBuilder()\n                ->getColumnListing($this->getTable());\n\n            if (empty($columns)) {\n                return true;\n            }\n\n            static::$guardableColumns[get_class($this)] = $columns;\n        }\n\n        return in_array($key, static::$guardableColumns[get_class($this)]);\n    }\n\n    /**\n     * Determine if the model is totally guarded.\n     *\n     * @return bool\n     */\n    public function totallyGuarded()\n    {\n        return count($this->getFillable()) === 0 && $this->getGuarded() == ['*'];\n    }\n\n    /**\n     * Get the fillable attributes of a given array.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @return array<string, mixed>\n     */\n    protected function fillableFromArray(array $attributes)\n    {\n        if (count($this->getFillable()) > 0 && ! static::$unguarded) {\n            return array_intersect_key($attributes, array_flip($this->getFillable()));\n        }\n\n        return $attributes;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse BackedEnum;\nuse Brick\\Math\\BigDecimal;\nuse Brick\\Math\\Exception\\MathException as BrickMathException;\nuse Brick\\Math\\RoundingMode;\nuse Carbon\\CarbonImmutable;\nuse Carbon\\CarbonInterface;\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Appends;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Table;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Casts\\Json;\nuse Illuminate\\Database\\Eloquent\\InvalidCastException;\nuse Illuminate\\Database\\Eloquent\\JsonEncodingException;\nuse Illuminate\\Database\\Eloquent\\MissingAttributeException;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\LazyLoadingViolationException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Exceptions\\MathException;\nuse Illuminate\\Support\\Facades\\Crypt;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse LogicException;\nuse ReflectionClass;\nuse ReflectionMethod;\nuse ReflectionNamedType;\nuse RuntimeException;\nuse Stringable;\nuse ValueError;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait HasAttributes\n{\n    /**\n     * The model's attributes.\n     *\n     * @var array<string, mixed>\n     */\n    protected $attributes = [];\n\n    /**\n     * The model attribute's original state.\n     *\n     * @var array<string, mixed>\n     */\n    protected $original = [];\n\n    /**\n     * The changed model attributes.\n     *\n     * @var array<string, mixed>\n     */\n    protected $changes = [];\n\n    /**\n     * The previous state of the changed model attributes.\n     *\n     * @var array<string, mixed>\n     */\n    protected $previous = [];\n\n    /**\n     * The attributes that should be cast.\n     *\n     * @var array\n     */\n    protected $casts = [];\n\n    /**\n     * The attributes that have been cast using custom classes.\n     *\n     * @var array\n     */\n    protected $classCastCache = [];\n\n    /**\n     * The attributes that have been cast using \"Attribute\" return type mutators.\n     *\n     * @var array\n     */\n    protected $attributeCastCache = [];\n\n    /**\n     * The built-in, primitive cast types supported by Eloquent.\n     *\n     * @var string[]\n     */\n    protected static $primitiveCastTypes = [\n        'array',\n        'bool',\n        'boolean',\n        'collection',\n        'custom_datetime',\n        'date',\n        'datetime',\n        'decimal',\n        'double',\n        'encrypted',\n        'encrypted:array',\n        'encrypted:collection',\n        'encrypted:json',\n        'encrypted:object',\n        'float',\n        'hashed',\n        'immutable_date',\n        'immutable_datetime',\n        'immutable_custom_datetime',\n        'int',\n        'integer',\n        'json',\n        'json:unicode',\n        'object',\n        'real',\n        'string',\n        'timestamp',\n    ];\n\n    /**\n     * The storage format of the model's date columns.\n     *\n     * @var string|null\n     */\n    protected $dateFormat;\n\n    /**\n     * The accessors to append to the model's array form.\n     *\n     * @var array\n     */\n    protected $appends = [];\n\n    /**\n     * Indicates whether attributes are snake cased on arrays.\n     *\n     * @var bool\n     */\n    public static $snakeAttributes = true;\n\n    /**\n     * The cache of the mutated attributes for each class.\n     *\n     * @var array\n     */\n    protected static $mutatorCache = [];\n\n    /**\n     * The cache of the \"Attribute\" return type marked mutated attributes for each class.\n     *\n     * @var array\n     */\n    protected static $attributeMutatorCache = [];\n\n    /**\n     * The cache of the \"Attribute\" return type marked mutated, gettable attributes for each class.\n     *\n     * @var array\n     */\n    protected static $getAttributeMutatorCache = [];\n\n    /**\n     * The cache of the \"Attribute\" return type marked mutated, settable attributes for each class.\n     *\n     * @var array\n     */\n    protected static $setAttributeMutatorCache = [];\n\n    /**\n     * The cache of the converted cast types.\n     *\n     * @var array\n     */\n    protected static $castTypeCache = [];\n\n    /**\n     * The encrypter instance that is used to encrypt attributes.\n     *\n     * @var \\Illuminate\\Contracts\\Encryption\\Encrypter|null\n     */\n    public static $encrypter;\n\n    /**\n     * Initialize the trait.\n     *\n     * @return void\n     */\n    protected function initializeHasAttributes()\n    {\n        $this->casts = $this->ensureCastsAreStringValues(\n            array_merge($this->casts, $this->casts()),\n        );\n\n        $this->dateFormat ??= static::resolveClassAttribute(Table::class)->dateFormat ?? null;\n\n        if (empty($this->appends)) {\n            $this->appends = static::resolveClassAttribute(Appends::class, 'columns') ?? [];\n        }\n    }\n\n    /**\n     * Convert the model's attributes to an array.\n     *\n     * @return array<string, mixed>\n     */\n    public function attributesToArray()\n    {\n        // If an attribute is a date, we will cast it to a string after converting it\n        // to a DateTime / Carbon instance. This is so we will get some consistent\n        // formatting while accessing attributes vs. arraying / JSONing a model.\n        $attributes = $this->addDateAttributesToArray(\n            $attributes = $this->getArrayableAttributes()\n        );\n\n        $attributes = $this->addMutatedAttributesToArray(\n            $attributes, $mutatedAttributes = $this->getMutatedAttributes()\n        );\n\n        // Next we will handle any casts that have been setup for this model and cast\n        // the values to their appropriate type. If the attribute has a mutator we\n        // will not perform the cast on those attributes to avoid any confusion.\n        $attributes = $this->addCastAttributesToArray(\n            $attributes, $mutatedAttributes\n        );\n\n        // Here we will grab all of the appended, calculated attributes to this model\n        // as these attributes are not really in the attributes array, but are run\n        // when we need to array or JSON the model for convenience to the coder.\n        foreach ($this->getArrayableAppends() as $key) {\n            $attributes[$key] = $this->mutateAttributeForArray($key, null);\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Add the date attributes to the attributes array.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @return array<string, mixed>\n     */\n    protected function addDateAttributesToArray(array $attributes)\n    {\n        foreach ($this->getDates() as $key) {\n            if (is_null($key) || ! isset($attributes[$key])) {\n                continue;\n            }\n\n            $attributes[$key] = $this->serializeDate(\n                $this->asDateTime($attributes[$key])\n            );\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Add the mutated attributes to the attributes array.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  array<string, mixed>  $mutatedAttributes\n     * @return array<string, mixed>\n     */\n    protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes)\n    {\n        foreach ($mutatedAttributes as $key) {\n            // We want to spin through all the mutated attributes for this model and call\n            // the mutator for the attribute. We cache off every mutated attributes so\n            // we don't have to constantly check on attributes that actually change.\n            if (! array_key_exists($key, $attributes)) {\n                continue;\n            }\n\n            // Next, we will call the mutator for this attribute so that we can get these\n            // mutated attribute's actual values. After we finish mutating each of the\n            // attributes we will return this final array of the mutated attributes.\n            $attributes[$key] = $this->mutateAttributeForArray(\n                $key, $attributes[$key]\n            );\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Add the casted attributes to the attributes array.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  array<string, mixed>  $mutatedAttributes\n     * @return array<string, mixed>\n     */\n    protected function addCastAttributesToArray(array $attributes, array $mutatedAttributes)\n    {\n        foreach ($this->getCasts() as $key => $value) {\n            if (! array_key_exists($key, $attributes) ||\n                in_array($key, $mutatedAttributes)) {\n                continue;\n            }\n\n            // Here we will cast the attribute. Then, if the cast is a date or datetime cast\n            // then we will serialize the date for the array. This will convert the dates\n            // to strings based on the date format specified for these Eloquent models.\n            $attributes[$key] = $this->castAttribute(\n                $key, $attributes[$key]\n            );\n\n            // If the attribute cast was a date or a datetime, we will serialize the date as\n            // a string. This allows the developers to customize how dates are serialized\n            // into an array without affecting how they are persisted into the storage.\n            if (isset($attributes[$key]) && in_array($value, ['date', 'datetime', 'immutable_date', 'immutable_datetime'])) {\n                $attributes[$key] = $this->serializeDate($attributes[$key]);\n            }\n\n            if (isset($attributes[$key]) && ($this->isCustomDateTimeCast($value) ||\n                $this->isImmutableCustomDateTimeCast($value))) {\n                $attributes[$key] = $attributes[$key]->format(explode(':', $value, 2)[1]);\n            }\n\n            if ($attributes[$key] instanceof DateTimeInterface &&\n                $this->isClassCastable($key)) {\n                $attributes[$key] = $this->serializeDate($attributes[$key]);\n            }\n\n            if (isset($attributes[$key]) && $this->isClassSerializable($key)) {\n                $attributes[$key] = $this->serializeClassCastableAttribute($key, $attributes[$key]);\n            }\n\n            if ($this->isEnumCastable($key) && (! ($attributes[$key] ?? null) instanceof Arrayable)) {\n                $attributes[$key] = isset($attributes[$key]) ? $this->getStorableEnumValue($this->getCasts()[$key], $attributes[$key]) : null;\n            }\n\n            if ($attributes[$key] instanceof Arrayable) {\n                $attributes[$key] = $attributes[$key]->toArray();\n            }\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Get an attribute array of all arrayable attributes.\n     *\n     * @return array<string, mixed>\n     */\n    protected function getArrayableAttributes()\n    {\n        return $this->getArrayableItems($this->getAttributes());\n    }\n\n    /**\n     * Get all of the appendable values that are arrayable.\n     *\n     * @return array\n     */\n    protected function getArrayableAppends()\n    {\n        $appends = $this->getAppends();\n\n        if (! count($appends)) {\n            return [];\n        }\n\n        return $this->getArrayableItems(\n            array_combine($appends, $appends)\n        );\n    }\n\n    /**\n     * Get the model's relationships in array form.\n     *\n     * @return array\n     */\n    public function relationsToArray()\n    {\n        $attributes = [];\n\n        foreach ($this->getArrayableRelations() as $key => $value) {\n            // If the values implement the Arrayable interface we can just call this\n            // toArray method on the instances which will convert both models and\n            // collections to their proper array form and we'll set the values.\n            if ($value instanceof Arrayable) {\n                $relation = $value->toArray();\n            }\n\n            // If the value is null, we'll still go ahead and set it in this list of\n            // attributes, since null is used to represent empty relationships if\n            // it has a has one or belongs to type relationships on the models.\n            elseif (is_null($value)) {\n                $relation = $value;\n            }\n\n            // If the relationships snake-casing is enabled, we will snake case this\n            // key so that the relation attribute is snake cased in this returned\n            // array to the developers, making this consistent with attributes.\n            if (static::$snakeAttributes) {\n                $key = Str::snake($key);\n            }\n\n            // If the relation value has been set, we will set it on this attributes\n            // list for returning. If it was not arrayable or null, we'll not set\n            // the value on the array because it is some type of invalid value.\n            if (array_key_exists('relation', get_defined_vars())) { // check if $relation is in scope (could be null)\n                $attributes[$key] = $relation ?? null;\n            }\n\n            unset($relation);\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Get an attribute array of all arrayable relations.\n     *\n     * @return array\n     */\n    protected function getArrayableRelations()\n    {\n        return $this->getArrayableItems($this->relations);\n    }\n\n    /**\n     * Get an attribute array of all arrayable values.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function getArrayableItems(array $values)\n    {\n        if (count($this->getVisible()) > 0) {\n            $values = array_intersect_key($values, array_flip($this->getVisible()));\n        }\n\n        if (count($this->getHidden()) > 0) {\n            $values = array_diff_key($values, array_flip($this->getHidden()));\n        }\n\n        return $values;\n    }\n\n    /**\n     * Determine whether an attribute exists on the model.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasAttribute($key)\n    {\n        if (! $key) {\n            return false;\n        }\n\n        return array_key_exists($key, $this->attributes) ||\n            array_key_exists($key, $this->casts) ||\n            $this->hasGetMutator($key) ||\n            $this->hasAttributeMutator($key) ||\n            $this->isClassCastable($key);\n    }\n\n    /**\n     * Get an attribute from the model.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function getAttribute($key)\n    {\n        if (! $key) {\n            return;\n        }\n\n        // If the attribute exists in the attribute array or has a \"get\" mutator we will\n        // get the attribute's value. Otherwise, we will proceed as if the developers\n        // are asking for a relationship's value. This covers both types of values.\n        if ($this->hasAttribute($key)) {\n            return $this->getAttributeValue($key);\n        }\n\n        // Here we will determine if the model base class itself contains this given key\n        // since we don't want to treat any of those methods as relationships because\n        // they are all intended as helper methods and none of these are relations.\n        if (method_exists(self::class, $key)) {\n            return $this->throwMissingAttributeExceptionIfApplicable($key);\n        }\n\n        return $this->isRelation($key) || $this->relationLoaded($key)\n            ? $this->getRelationValue($key)\n            : $this->throwMissingAttributeExceptionIfApplicable($key);\n    }\n\n    /**\n     * Either throw a missing attribute exception or return null depending on Eloquent's configuration.\n     *\n     * @param  string  $key\n     * @return null\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\MissingAttributeException\n     */\n    protected function throwMissingAttributeExceptionIfApplicable($key)\n    {\n        if ($this->exists &&\n            ! $this->wasRecentlyCreated &&\n            static::preventsAccessingMissingAttributes()) {\n            if (isset(static::$missingAttributeViolationCallback)) {\n                return call_user_func(static::$missingAttributeViolationCallback, $this, $key);\n            }\n\n            throw new MissingAttributeException($this, $key);\n        }\n\n        return null;\n    }\n\n    /**\n     * Get a plain attribute (not a relationship).\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function getAttributeValue($key)\n    {\n        return $this->transformModelValue($key, $this->getAttributeFromArray($key));\n    }\n\n    /**\n     * Get an attribute from the $attributes array.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    protected function getAttributeFromArray($key)\n    {\n        $this->mergeAttributeFromCachedCasts($key);\n\n        return $this->attributes[$key] ?? null;\n    }\n\n    /**\n     * Get a relationship.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function getRelationValue($key)\n    {\n        // If the key already exists in the relationships array, it just means the\n        // relationship has already been loaded, so we'll just return it out of\n        // here because there is no need to query within the relations twice.\n        if ($this->relationLoaded($key)) {\n            return $this->relations[$key];\n        }\n\n        if (! $this->isRelation($key)) {\n            return;\n        }\n\n        if ($this->attemptToAutoloadRelation($key)) {\n            return $this->relations[$key];\n        }\n\n        if ($this->preventsLazyLoading) {\n            $this->handleLazyLoadingViolation($key);\n        }\n\n        // If the \"attribute\" exists as a method on the model, we will just assume\n        // it is a relationship and will load and return results from the query\n        // and hydrate the relationship's value on the \"relationships\" array.\n        return $this->getRelationshipFromMethod($key);\n    }\n\n    /**\n     * Determine if the given key is a relationship method on the model.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function isRelation($key)\n    {\n        if ($this->hasAttributeMutator($key)) {\n            return false;\n        }\n\n        return method_exists($this, $key) ||\n               $this->relationResolver(static::class, $key);\n    }\n\n    /**\n     * Handle a lazy loading violation.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\LazyLoadingViolationException\n     */\n    protected function handleLazyLoadingViolation($key)\n    {\n        if (isset(static::$lazyLoadingViolationCallback)) {\n            return call_user_func(static::$lazyLoadingViolationCallback, $this, $key);\n        }\n\n        if (! $this->exists || $this->wasRecentlyCreated) {\n            return;\n        }\n\n        throw new LazyLoadingViolationException($this, $key);\n    }\n\n    /**\n     * Get a relationship value from a method.\n     *\n     * @param  string  $method\n     * @return mixed\n     *\n     * @throws \\LogicException\n     */\n    protected function getRelationshipFromMethod($method)\n    {\n        $relation = $this->$method();\n\n        if (! $relation instanceof Relation) {\n            if (is_null($relation)) {\n                throw new LogicException(sprintf(\n                    '%s::%s must return a relationship instance, but \"null\" was returned. Was the \"return\" keyword used?', static::class, $method\n                ));\n            }\n\n            throw new LogicException(sprintf(\n                '%s::%s must return a relationship instance.', static::class, $method\n            ));\n        }\n\n        return tap($relation->getResults(), function ($results) use ($method) {\n            $this->setRelation($method, $results);\n        });\n    }\n\n    /**\n     * Determine if a get mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasGetMutator($key)\n    {\n        return method_exists($this, 'get'.Str::studly($key).'Attribute');\n    }\n\n    /**\n     * Determine if a \"Attribute\" return type marked mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasAttributeMutator($key)\n    {\n        if (isset(static::$attributeMutatorCache[get_class($this)][$key])) {\n            return static::$attributeMutatorCache[get_class($this)][$key];\n        }\n\n        if (! method_exists($this, $method = Str::camel($key))) {\n            return static::$attributeMutatorCache[get_class($this)][$key] = false;\n        }\n\n        $returnType = (new ReflectionMethod($this, $method))->getReturnType();\n\n        return static::$attributeMutatorCache[get_class($this)][$key] =\n                    $returnType instanceof ReflectionNamedType &&\n                    $returnType->getName() === Attribute::class;\n    }\n\n    /**\n     * Determine if a \"Attribute\" return type marked get mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasAttributeGetMutator($key)\n    {\n        if (isset(static::$getAttributeMutatorCache[get_class($this)][$key])) {\n            return static::$getAttributeMutatorCache[get_class($this)][$key];\n        }\n\n        if (! $this->hasAttributeMutator($key)) {\n            return static::$getAttributeMutatorCache[get_class($this)][$key] = false;\n        }\n\n        return static::$getAttributeMutatorCache[get_class($this)][$key] = is_callable($this->{Str::camel($key)}()->get);\n    }\n\n    /**\n     * Determine if any get mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasAnyGetMutator($key)\n    {\n        return $this->hasGetMutator($key) || $this->hasAttributeGetMutator($key);\n    }\n\n    /**\n     * Get the value of an attribute using its mutator.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function mutateAttribute($key, $value)\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        return $this->{'get'.Str::studly($key).'Attribute'}($value);\n    }\n\n    /**\n     * Get the value of an \"Attribute\" return type marked attribute using its mutator.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function mutateAttributeMarkedAttribute($key, $value)\n    {\n        if (array_key_exists($key, $this->attributeCastCache)) {\n            return $this->attributeCastCache[$key];\n        }\n\n        $this->mergeAttributesFromCachedCasts();\n\n        $attribute = $this->{Str::camel($key)}();\n\n        $value = call_user_func($attribute->get ?: function ($value) {\n            return $value;\n        }, $value, $this->attributes);\n\n        if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) {\n            $this->attributeCastCache[$key] = $value;\n        } else {\n            unset($this->attributeCastCache[$key]);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the value of an attribute using its mutator for array conversion.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function mutateAttributeForArray($key, $value)\n    {\n        if ($this->isClassCastable($key)) {\n            $value = $this->getClassCastableAttributeValue($key, $value);\n        } elseif (isset(static::$getAttributeMutatorCache[get_class($this)][$key]) &&\n                  static::$getAttributeMutatorCache[get_class($this)][$key] === true) {\n            $value = $this->mutateAttributeMarkedAttribute($key, $value);\n\n            $value = $value instanceof DateTimeInterface\n                ? $this->serializeDate($value)\n                : $value;\n        } else {\n            $value = $this->mutateAttribute($key, $value);\n        }\n\n        return $value instanceof Arrayable ? $value->toArray() : $value;\n    }\n\n    /**\n     * Merge new casts with existing casts on the model.\n     *\n     * @param  array  $casts\n     * @return $this\n     */\n    public function mergeCasts($casts)\n    {\n        $casts = $this->ensureCastsAreStringValues($casts);\n\n        $this->casts = array_merge($this->casts, $casts);\n\n        return $this;\n    }\n\n    /**\n     * Ensure that the given casts are strings.\n     *\n     * @param  array  $casts\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function ensureCastsAreStringValues($casts)\n    {\n        foreach ($casts as $attribute => $cast) {\n            $casts[$attribute] = match (true) {\n                is_object($cast) => value(function () use ($cast, $attribute) {\n                    if ($cast instanceof Stringable) {\n                        return (string) $cast;\n                    }\n\n                    throw new InvalidArgumentException(\n                        \"The cast object for the {$attribute} attribute must implement Stringable.\"\n                    );\n                }),\n                is_array($cast) => value(function () use ($cast) {\n                    if (count($cast) === 1) {\n                        return $cast[0];\n                    }\n\n                    [$cast, $arguments] = [array_shift($cast), $cast];\n\n                    return $cast.':'.implode(',', $arguments);\n                }),\n                default => $cast,\n            };\n        }\n\n        return $casts;\n    }\n\n    /**\n     * Cast an attribute to a native PHP type.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function castAttribute($key, $value)\n    {\n        $castType = $this->getCastType($key);\n\n        if (is_null($value) && in_array($castType, static::$primitiveCastTypes)) {\n            return $value;\n        }\n\n        // If the key is one of the encrypted castable types, we'll first decrypt\n        // the value and update the cast type so we may leverage the following\n        // logic for casting this value to any additionally specified types.\n        if ($this->isEncryptedCastable($key)) {\n            $value = $this->fromEncryptedString($value);\n\n            $castType = Str::after($castType, 'encrypted:');\n        }\n\n        switch ($castType) {\n            case 'int':\n            case 'integer':\n                return (int) $value;\n            case 'real':\n            case 'float':\n            case 'double':\n                return $this->fromFloat($value);\n            case 'decimal':\n                return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]);\n            case 'string':\n                return (string) $value;\n            case 'bool':\n            case 'boolean':\n                return (bool) $value;\n            case 'object':\n                return $this->fromJson($value, true);\n            case 'array':\n            case 'json':\n            case 'json:unicode':\n                return $this->fromJson($value);\n            case 'collection':\n                return new BaseCollection($this->fromJson($value));\n            case 'date':\n                return $this->asDate($value);\n            case 'datetime':\n            case 'custom_datetime':\n                return $this->asDateTime($value);\n            case 'immutable_date':\n                return $this->asDate($value)->toImmutable();\n            case 'immutable_custom_datetime':\n            case 'immutable_datetime':\n                return $this->asDateTime($value)->toImmutable();\n            case 'timestamp':\n                return $this->asTimestamp($value);\n        }\n\n        if ($this->isEnumCastable($key)) {\n            return $this->getEnumCastableAttributeValue($key, $value);\n        }\n\n        if ($this->isClassCastable($key)) {\n            return $this->getClassCastableAttributeValue($key, $value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Cast the given attribute using a custom cast class.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function getClassCastableAttributeValue($key, $value)\n    {\n        $caster = $this->resolveCasterClass($key);\n\n        $objectCachingDisabled = $caster->withoutObjectCaching ?? false;\n\n        if (isset($this->classCastCache[$key]) && ! $objectCachingDisabled) {\n            return $this->classCastCache[$key];\n        } else {\n            $value = $caster instanceof CastsInboundAttributes\n                ? $value\n                : $caster->get($this, $key, $value, $this->attributes);\n\n            if ($caster instanceof CastsInboundAttributes ||\n                ! is_object($value) ||\n                $objectCachingDisabled) {\n                unset($this->classCastCache[$key]);\n            } else {\n                $this->classCastCache[$key] = $value;\n            }\n\n            return $value;\n        }\n    }\n\n    /**\n     * Cast the given attribute to an enum.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function getEnumCastableAttributeValue($key, $value)\n    {\n        if (is_null($value)) {\n            return;\n        }\n\n        $castType = $this->getCasts()[$key];\n\n        if ($value instanceof $castType) {\n            return $value;\n        }\n\n        return $this->getEnumCaseFromValue($castType, $value);\n    }\n\n    /**\n     * Get the type of cast for a model attribute.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function getCastType($key)\n    {\n        $castType = $this->getCasts()[$key];\n\n        if (isset(static::$castTypeCache[$castType])) {\n            return static::$castTypeCache[$castType];\n        }\n\n        if ($this->isCustomDateTimeCast($castType)) {\n            $convertedCastType = 'custom_datetime';\n        } elseif ($this->isImmutableCustomDateTimeCast($castType)) {\n            $convertedCastType = 'immutable_custom_datetime';\n        } elseif ($this->isDecimalCast($castType)) {\n            $convertedCastType = 'decimal';\n        } elseif (class_exists($castType)) {\n            $convertedCastType = $castType;\n        } else {\n            $convertedCastType = trim(strtolower($castType));\n        }\n\n        return static::$castTypeCache[$castType] = $convertedCastType;\n    }\n\n    /**\n     * Increment or decrement the given attribute using the custom cast class.\n     *\n     * @param  string  $method\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function deviateClassCastableAttribute($method, $key, $value)\n    {\n        return $this->resolveCasterClass($key)->{$method}(\n            $this, $key, $value, $this->attributes\n        );\n    }\n\n    /**\n     * Serialize the given attribute using the custom cast class.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function serializeClassCastableAttribute($key, $value)\n    {\n        return $this->resolveCasterClass($key)->serialize(\n            $this, $key, $value, $this->attributes\n        );\n    }\n\n    /**\n     * Compare two values for the given attribute using the custom cast class.\n     *\n     * @param  string  $key\n     * @param  mixed  $original\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function compareClassCastableAttribute($key, $original, $value)\n    {\n        return $this->resolveCasterClass($key)->compare(\n            $this, $key, $original, $value\n        );\n    }\n\n    /**\n     * Determine if the cast type is a custom date time cast.\n     *\n     * @param  string  $cast\n     * @return bool\n     */\n    protected function isCustomDateTimeCast($cast)\n    {\n        return str_starts_with($cast, 'date:') ||\n                str_starts_with($cast, 'datetime:');\n    }\n\n    /**\n     * Determine if the cast type is an immutable custom date time cast.\n     *\n     * @param  string  $cast\n     * @return bool\n     */\n    protected function isImmutableCustomDateTimeCast($cast)\n    {\n        return str_starts_with($cast, 'immutable_date:') ||\n                str_starts_with($cast, 'immutable_datetime:');\n    }\n\n    /**\n     * Determine if the cast type is a decimal cast.\n     *\n     * @param  string  $cast\n     * @return bool\n     */\n    protected function isDecimalCast($cast)\n    {\n        return str_starts_with($cast, 'decimal:');\n    }\n\n    /**\n     * Set a given attribute on the model.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function setAttribute($key, $value)\n    {\n        // First we will check for the presence of a mutator for the set operation\n        // which simply lets the developers tweak the attribute as it is set on\n        // this model, such as \"json_encoding\" a listing of data for storage.\n        if ($this->hasSetMutator($key)) {\n            return $this->setMutatedAttributeValue($key, $value);\n        } elseif ($this->hasAttributeSetMutator($key)) {\n            return $this->setAttributeMarkedMutatedAttributeValue($key, $value);\n        }\n\n        // If an attribute is listed as a \"date\", we'll convert it from a DateTime\n        // instance into a form proper for storage on the database tables using\n        // the connection grammar's date format. We will auto set the values.\n        elseif (! is_null($value) && $this->isDateAttribute($key)) {\n            $value = $this->fromDateTime($value);\n        }\n\n        if ($this->isEnumCastable($key)) {\n            $this->setEnumCastableAttribute($key, $value);\n\n            return $this;\n        }\n\n        if ($this->isClassCastable($key)) {\n            $this->setClassCastableAttribute($key, $value);\n\n            return $this;\n        }\n\n        if (! is_null($value) && $this->isJsonCastable($key)) {\n            $value = $this->castAttributeAsJson($key, $value);\n        }\n\n        // If this attribute contains a JSON ->, we'll set the proper value in the\n        // attribute's underlying array. This takes care of properly nesting an\n        // attribute in the array's value in the case of deeply nested items.\n        if (str_contains($key, '->')) {\n            return $this->fillJsonAttribute($key, $value);\n        }\n\n        if (! is_null($value) && $this->isEncryptedCastable($key)) {\n            $value = $this->castAttributeAsEncryptedString($key, $value);\n        }\n\n        if (! is_null($value) && $this->hasCast($key, 'hashed')) {\n            $value = $this->castAttributeAsHashedString($key, $value);\n        }\n\n        $this->attributes[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Determine if a set mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasSetMutator($key)\n    {\n        return method_exists($this, 'set'.Str::studly($key).'Attribute');\n    }\n\n    /**\n     * Determine if an \"Attribute\" return type marked set mutator exists for an attribute.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasAttributeSetMutator($key)\n    {\n        $class = get_class($this);\n\n        if (isset(static::$setAttributeMutatorCache[$class][$key])) {\n            return static::$setAttributeMutatorCache[$class][$key];\n        }\n\n        if (! method_exists($this, $method = Str::camel($key))) {\n            return static::$setAttributeMutatorCache[$class][$key] = false;\n        }\n\n        $returnType = (new ReflectionMethod($this, $method))->getReturnType();\n\n        return static::$setAttributeMutatorCache[$class][$key] =\n                    $returnType instanceof ReflectionNamedType &&\n                    $returnType->getName() === Attribute::class &&\n                    is_callable($this->{$method}()->set);\n    }\n\n    /**\n     * Set the value of an attribute using its mutator.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function setMutatedAttributeValue($key, $value)\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        return $this->{'set'.Str::studly($key).'Attribute'}($value);\n    }\n\n    /**\n     * Set the value of a \"Attribute\" return type marked attribute using its mutator.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function setAttributeMarkedMutatedAttributeValue($key, $value)\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        $attribute = $this->{Str::camel($key)}();\n\n        $callback = $attribute->set ?: function ($value) use ($key) {\n            $this->attributes[$key] = $value;\n        };\n\n        $this->attributes = array_merge(\n            $this->attributes,\n            $this->normalizeCastClassResponse(\n                $key, $callback($value, $this->attributes)\n            )\n        );\n\n        if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) {\n            $this->attributeCastCache[$key] = $value;\n        } else {\n            unset($this->attributeCastCache[$key]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given attribute is a date or date castable.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isDateAttribute($key)\n    {\n        return in_array($key, $this->getDates(), true) ||\n            $this->isDateCastable($key);\n    }\n\n    /**\n     * Set a given JSON attribute on the model.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function fillJsonAttribute($key, $value)\n    {\n        [$key, $path] = explode('->', $key, 2);\n\n        $value = $this->asJson($this->getArrayAttributeWithValue(\n            $path, $key, $value\n        ), $this->getJsonCastFlags($key));\n\n        $this->attributes[$key] = $this->isEncryptedCastable($key)\n            ? $this->castAttributeAsEncryptedString($key, $value)\n            : $value;\n\n        if ($this->isClassCastable($key)) {\n            unset($this->classCastCache[$key]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the value of a class castable attribute.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    protected function setClassCastableAttribute($key, $value)\n    {\n        $caster = $this->resolveCasterClass($key);\n\n        $this->attributes = array_replace(\n            $this->attributes,\n            $this->normalizeCastClassResponse($key, $caster->set(\n                $this, $key, $value, $this->attributes\n            ))\n        );\n\n        if ($caster instanceof CastsInboundAttributes ||\n            ! is_object($value) ||\n            ($caster->withoutObjectCaching ?? false)) {\n            unset($this->classCastCache[$key]);\n        } else {\n            $this->classCastCache[$key] = $value;\n        }\n    }\n\n    /**\n     * Set the value of an enum castable attribute.\n     *\n     * @param  string  $key\n     * @param  \\UnitEnum|string|int|null  $value\n     * @return void\n     */\n    protected function setEnumCastableAttribute($key, $value)\n    {\n        $enumClass = $this->getCasts()[$key];\n\n        if (! isset($value)) {\n            $this->attributes[$key] = null;\n        } elseif (is_object($value)) {\n            $this->attributes[$key] = $this->getStorableEnumValue($enumClass, $value);\n        } else {\n            $this->attributes[$key] = $this->getStorableEnumValue(\n                $enumClass, $this->getEnumCaseFromValue($enumClass, $value)\n            );\n        }\n    }\n\n    /**\n     * Get an enum case instance from a given class and value.\n     *\n     * @param  string  $enumClass\n     * @param  string|int  $value\n     * @return \\UnitEnum\n     */\n    protected function getEnumCaseFromValue($enumClass, $value)\n    {\n        return is_subclass_of($enumClass, BackedEnum::class)\n            ? $enumClass::from($value)\n            : constant($enumClass.'::'.$value);\n    }\n\n    /**\n     * Get the storable value from the given enum.\n     *\n     * @param  string  $expectedEnum\n     * @param  \\UnitEnum  $value\n     * @return string|int\n     *\n     * @throws \\ValueError\n     */\n    protected function getStorableEnumValue($expectedEnum, $value)\n    {\n        if (! $value instanceof $expectedEnum) {\n            throw new ValueError(sprintf('Value [%s] is not of the expected enum type [%s].', var_export($value, true), $expectedEnum));\n        }\n\n        return enum_value($value);\n    }\n\n    /**\n     * Get an array attribute with the given key and value set.\n     *\n     * @param  string  $path\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return array\n     */\n    protected function getArrayAttributeWithValue($path, $key, $value)\n    {\n        return tap($this->getArrayAttributeByKey($key), function (&$array) use ($path, $value) {\n            Arr::set($array, str_replace('->', '.', $path), $value);\n        });\n    }\n\n    /**\n     * Get an array attribute or return an empty array if it is not set.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    protected function getArrayAttributeByKey($key)\n    {\n        if (! isset($this->attributes[$key])) {\n            return [];\n        }\n\n        return $this->fromJson(\n            $this->isEncryptedCastable($key)\n                ? $this->fromEncryptedString($this->attributes[$key])\n                : $this->attributes[$key]\n        );\n    }\n\n    /**\n     * Cast the given attribute to JSON.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\JsonEncodingException\n     */\n    protected function castAttributeAsJson($key, $value)\n    {\n        $value = $this->asJson($value, $this->getJsonCastFlags($key));\n\n        if ($value === false) {\n            throw JsonEncodingException::forAttribute(\n                $this, $key, json_last_error_msg()\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the JSON casting flags for the given attribute.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getJsonCastFlags($key)\n    {\n        $flags = 0;\n\n        if ($this->hasCast($key, ['json:unicode'])) {\n            $flags |= JSON_UNESCAPED_UNICODE;\n        }\n\n        return $flags;\n    }\n\n    /**\n     * Encode the given value as JSON.\n     *\n     * @param  mixed  $value\n     * @param  int  $flags\n     * @return string\n     */\n    protected function asJson($value, $flags = 0)\n    {\n        return Json::encode($value, $flags);\n    }\n\n    /**\n     * Decode the given JSON back into an array or object.\n     *\n     * @param  string|null  $value\n     * @param  bool  $asObject\n     * @return mixed\n     */\n    public function fromJson($value, $asObject = false)\n    {\n        if ($value === null || $value === '') {\n            return null;\n        }\n\n        return Json::decode($value, ! $asObject);\n    }\n\n    /**\n     * Decrypt the given encrypted string.\n     *\n     * @param  string  $value\n     * @return mixed\n     */\n    public function fromEncryptedString($value)\n    {\n        return static::currentEncrypter()->decrypt($value, false);\n    }\n\n    /**\n     * Cast the given attribute to an encrypted string.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function castAttributeAsEncryptedString($key, #[\\SensitiveParameter] $value)\n    {\n        return static::currentEncrypter()->encrypt($value, false);\n    }\n\n    /**\n     * Set the encrypter instance that will be used to encrypt attributes.\n     *\n     * @param  \\Illuminate\\Contracts\\Encryption\\Encrypter|null  $encrypter\n     * @return void\n     */\n    public static function encryptUsing($encrypter)\n    {\n        static::$encrypter = $encrypter;\n    }\n\n    /**\n     * Get the current encrypter being used by the model.\n     *\n     * @return \\Illuminate\\Contracts\\Encryption\\Encrypter\n     */\n    public static function currentEncrypter()\n    {\n        return static::$encrypter ?? Crypt::getFacadeRoot();\n    }\n\n    /**\n     * Cast the given attribute to a hashed string.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function castAttributeAsHashedString($key, #[\\SensitiveParameter] $value)\n    {\n        if ($value === null) {\n            return null;\n        }\n\n        if (! Hash::isHashed($value)) {\n            return Hash::make($value);\n        }\n\n        /** @phpstan-ignore staticMethod.notFound */\n        if (! Hash::verifyConfiguration($value)) {\n            throw new RuntimeException(\"Could not verify the hashed value's configuration.\");\n        }\n\n        return $value;\n    }\n\n    /**\n     * Decode the given float.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function fromFloat($value)\n    {\n        return match ((string) $value) {\n            'Infinity' => INF,\n            '-Infinity' => -INF,\n            'NaN' => NAN,\n            default => (float) $value,\n        };\n    }\n\n    /**\n     * Return a decimal as string.\n     *\n     * @param  float|string  $value\n     * @param  int  $decimals\n     * @return string\n     *\n     * @throws \\Illuminate\\Support\\Exceptions\\MathException\n     */\n    protected function asDecimal($value, $decimals)\n    {\n        try {\n            return (string) BigDecimal::of((string) $value)->toScale($decimals, RoundingMode::HalfUp);\n        } catch (BrickMathException $e) {\n            throw new MathException('Unable to cast value to a decimal.', previous: $e);\n        }\n    }\n\n    /**\n     * Return a timestamp as DateTime object with time set to 00:00:00.\n     *\n     * @param  mixed  $value\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    protected function asDate($value)\n    {\n        return $this->asDateTime($value)->startOfDay();\n    }\n\n    /**\n     * Return a timestamp as DateTime object.\n     *\n     * @param  mixed  $value\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    protected function asDateTime($value)\n    {\n        // If this value is already a Carbon instance, we shall just return it as is.\n        // This prevents us having to re-instantiate a Carbon instance when we know\n        // it already is one, which wouldn't be fulfilled by the DateTime check.\n        if ($value instanceof CarbonInterface) {\n            return Date::instance($value);\n        }\n\n        // If the value is already a DateTime instance, we will just skip the rest of\n        // these checks since they will be a waste of time, and hinder performance\n        // when checking the field. We will just return the DateTime right away.\n        if ($value instanceof DateTimeInterface) {\n            return Date::parse(\n                $value->format('Y-m-d H:i:s.u'), $value->getTimezone()\n            );\n        }\n\n        // If this value is an integer, we will assume it is a UNIX timestamp's value\n        // and format a Carbon object from this timestamp. This allows flexibility\n        // when defining your date fields as they might be UNIX timestamps here.\n        if (is_numeric($value)) {\n            return Date::createFromTimestamp($value, date_default_timezone_get());\n        }\n\n        // If the value is in simply year, month, day format, we will instantiate the\n        // Carbon instances from that format. Again, this provides for simple date\n        // fields on the database, while still supporting Carbonized conversion.\n        if ($this->isStandardDateFormat($value)) {\n            return Date::instance(Carbon::createFromFormat('Y-m-d', $value)->startOfDay());\n        }\n\n        $format = $this->getDateFormat();\n\n        // Finally, we will just assume this date is in the format used by default on\n        // the database connection and use that format to create the Carbon object\n        // that is returned back out to the developers after we convert it here.\n        try {\n            $date = Date::createFromFormat($format, $value);\n        } catch (InvalidArgumentException) {\n            $date = false;\n        }\n\n        return $date ?: Date::parse($value);\n    }\n\n    /**\n     * Determine if the given value is a standard date format.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    protected function isStandardDateFormat($value)\n    {\n        return preg_match('/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/', $value);\n    }\n\n    /**\n     * Convert a DateTime to a storable string.\n     *\n     * @param  mixed  $value\n     * @return string|null\n     */\n    public function fromDateTime($value)\n    {\n        return empty($value) ? $value : $this->asDateTime($value)->format(\n            $this->getDateFormat()\n        );\n    }\n\n    /**\n     * Return a timestamp as unix timestamp.\n     *\n     * @param  mixed  $value\n     * @return int\n     */\n    protected function asTimestamp($value)\n    {\n        return $this->asDateTime($value)->getTimestamp();\n    }\n\n    /**\n     * Prepare a date for array / JSON serialization.\n     *\n     * @param  \\DateTimeInterface  $date\n     * @return string\n     */\n    protected function serializeDate(DateTimeInterface $date)\n    {\n        return $date instanceof DateTimeImmutable ?\n            CarbonImmutable::instance($date)->toJSON() :\n            Carbon::instance($date)->toJSON();\n    }\n\n    /**\n     * Get the attributes that should be converted to dates.\n     *\n     * @return array<int, string|null>\n     */\n    public function getDates()\n    {\n        return $this->usesTimestamps() ? [\n            $this->getCreatedAtColumn(),\n            $this->getUpdatedAtColumn(),\n        ] : [];\n    }\n\n    /**\n     * Get the format for database stored dates.\n     *\n     * @return string\n     */\n    public function getDateFormat()\n    {\n        return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();\n    }\n\n    /**\n     * Set the date format used by the model.\n     *\n     * @param  string  $format\n     * @return $this\n     */\n    public function setDateFormat($format)\n    {\n        $this->dateFormat = $format;\n\n        return $this;\n    }\n\n    /**\n     * Determine whether an attribute should be cast to a native type.\n     *\n     * @param  string  $key\n     * @param  array|string|null  $types\n     * @return bool\n     */\n    public function hasCast($key, $types = null)\n    {\n        if (array_key_exists($key, $this->getCasts())) {\n            return $types ? in_array($this->getCastType($key), (array) $types, true) : true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the attributes that should be cast.\n     *\n     * @return array\n     */\n    public function getCasts()\n    {\n        if ($this->getIncrementing()) {\n            return array_merge([$this->getKeyName() => $this->getKeyType()], $this->casts);\n        }\n\n        return $this->casts;\n    }\n\n    /**\n     * Get the attributes that should be cast.\n     *\n     * @return array<string, string>\n     */\n    protected function casts()\n    {\n        return [];\n    }\n\n    /**\n     * Determine whether a value is Date / DateTime castable for inbound manipulation.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isDateCastable($key)\n    {\n        return $this->hasCast($key, ['date', 'datetime', 'immutable_date', 'immutable_datetime']);\n    }\n\n    /**\n     * Determine whether a value is Date / DateTime custom-castable for inbound manipulation.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isDateCastableWithCustomFormat($key)\n    {\n        return $this->hasCast($key, ['custom_datetime', 'immutable_custom_datetime']);\n    }\n\n    /**\n     * Determine whether a value is JSON castable for inbound manipulation.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isJsonCastable($key)\n    {\n        return $this->hasCast($key, ['array', 'json', 'json:unicode', 'object', 'collection', 'encrypted:array', 'encrypted:collection', 'encrypted:json', 'encrypted:object']);\n    }\n\n    /**\n     * Determine whether a value is an encrypted castable for inbound manipulation.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isEncryptedCastable($key)\n    {\n        return $this->hasCast($key, ['encrypted', 'encrypted:array', 'encrypted:collection', 'encrypted:json', 'encrypted:object']);\n    }\n\n    /**\n     * Determine if the given key is cast using a custom class.\n     *\n     * @param  string  $key\n     * @return bool\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\InvalidCastException\n     */\n    protected function isClassCastable($key)\n    {\n        $casts = $this->getCasts();\n\n        if (! array_key_exists($key, $casts)) {\n            return false;\n        }\n\n        $castType = $this->parseCasterClass($casts[$key]);\n\n        if (in_array($castType, static::$primitiveCastTypes)) {\n            return false;\n        }\n\n        if (class_exists($castType)) {\n            return true;\n        }\n\n        throw new InvalidCastException($this->getModel(), $key, $castType);\n    }\n\n    /**\n     * Determine if the given key is cast using an enum.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isEnumCastable($key)\n    {\n        $casts = $this->getCasts();\n\n        if (! array_key_exists($key, $casts)) {\n            return false;\n        }\n\n        $castType = $casts[$key];\n\n        if (in_array($castType, static::$primitiveCastTypes)) {\n            return false;\n        }\n\n        if (is_subclass_of($castType, Castable::class)) {\n            return false;\n        }\n\n        return enum_exists($castType);\n    }\n\n    /**\n     * Determine if the key is deviable using a custom class.\n     *\n     * @param  string  $key\n     * @return bool\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\InvalidCastException\n     */\n    protected function isClassDeviable($key)\n    {\n        if (! $this->isClassCastable($key)) {\n            return false;\n        }\n\n        $castType = $this->resolveCasterClass($key);\n\n        return method_exists($castType::class, 'increment') && method_exists($castType::class, 'decrement');\n    }\n\n    /**\n     * Determine if the key is serializable using a custom class.\n     *\n     * @param  string  $key\n     * @return bool\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\InvalidCastException\n     */\n    protected function isClassSerializable($key)\n    {\n        return ! $this->isEnumCastable($key) &&\n            $this->isClassCastable($key) &&\n            method_exists($this->resolveCasterClass($key), 'serialize');\n    }\n\n    /**\n     * Determine if the key is comparable using a custom class.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isClassComparable($key)\n    {\n        return ! $this->isEnumCastable($key) &&\n            $this->isClassCastable($key) &&\n            method_exists($this->resolveCasterClass($key), 'compare');\n    }\n\n    /**\n     * Resolve the custom caster class for a given key.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    protected function resolveCasterClass($key)\n    {\n        $castType = $this->getCasts()[$key];\n\n        $arguments = [];\n\n        if (is_string($castType) && str_contains($castType, ':')) {\n            $segments = explode(':', $castType, 2);\n\n            $castType = $segments[0];\n            $arguments = explode(',', $segments[1]);\n        }\n\n        if (is_subclass_of($castType, Castable::class)) {\n            $castType = $castType::castUsing($arguments);\n        }\n\n        if (is_object($castType)) {\n            return $castType;\n        }\n\n        return new $castType(...$arguments);\n    }\n\n    /**\n     * Parse the given caster class, removing any arguments.\n     *\n     * @param  string  $class\n     * @return string\n     */\n    protected function parseCasterClass($class)\n    {\n        return ! str_contains($class, ':')\n            ? $class\n            : explode(':', $class, 2)[0];\n    }\n\n    /**\n     * Merge the cast class and attribute cast attributes back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributesFromCachedCasts()\n    {\n        $this->mergeAttributesFromClassCasts();\n        $this->mergeAttributesFromAttributeCasts();\n    }\n\n    /**\n     * Merge the a cast class and attribute cast attribute back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributeFromCachedCasts(string $key)\n    {\n        $this->mergeAttributeFromClassCasts($key);\n        $this->mergeAttributeFromAttributeCasts($key);\n    }\n\n    /**\n     * Merge the cast class attributes back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributesFromClassCasts()\n    {\n        foreach ($this->classCastCache as $key => $value) {\n            $this->mergeAttributeFromClassCasts($key);\n        }\n    }\n\n    /**\n     * Merge the cast class attribute back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributeFromClassCasts(string $key): void\n    {\n        if (! isset($this->classCastCache[$key])) {\n            return;\n        }\n\n        $value = $this->classCastCache[$key];\n\n        $caster = $this->resolveCasterClass($key);\n\n        $this->attributes = array_merge(\n            $this->attributes,\n            $caster instanceof CastsInboundAttributes\n                ? [$key => $value]\n                : $this->normalizeCastClassResponse($key, $caster->set($this, $key, $value, $this->attributes))\n        );\n    }\n\n    /**\n     * Merge the cast class attributes back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributesFromAttributeCasts()\n    {\n        foreach ($this->attributeCastCache as $key => $value) {\n            $this->mergeAttributeFromAttributeCasts($key);\n        }\n    }\n\n    /**\n     * Merge the cast class attribute back into the model.\n     *\n     * @return void\n     */\n    protected function mergeAttributeFromAttributeCasts(string $key): void\n    {\n        if (! isset($this->attributeCastCache[$key])) {\n            return;\n        }\n\n        $value = $this->attributeCastCache[$key];\n\n        $attribute = $this->{Str::camel($key)}();\n\n        if ($attribute->get && ! $attribute->set) {\n            return;\n        }\n\n        $callback = $attribute->set ?: function ($value) use ($key) {\n            $this->attributes[$key] = $value;\n        };\n\n        $this->attributes = array_merge(\n            $this->attributes,\n            $this->normalizeCastClassResponse(\n                $key, $callback($value, $this->attributes)\n            )\n        );\n    }\n\n    /**\n     * Normalize the response from a custom class caster.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return array\n     */\n    protected function normalizeCastClassResponse($key, $value)\n    {\n        return is_array($value) ? $value : [$key => $value];\n    }\n\n    /**\n     * Get all of the current attributes on the model.\n     *\n     * @return array<string, mixed>\n     */\n    public function getAttributes()\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        return $this->attributes;\n    }\n\n    /**\n     * Get all of the current attributes on the model for an insert operation.\n     *\n     * @return array\n     */\n    protected function getAttributesForInsert()\n    {\n        return $this->getAttributes();\n    }\n\n    /**\n     * Set the array of model attributes. No checking is done.\n     *\n     * @param  array  $attributes\n     * @param  bool  $sync\n     * @return $this\n     */\n    public function setRawAttributes(array $attributes, $sync = false)\n    {\n        $this->attributes = $attributes;\n\n        if ($sync) {\n            $this->syncOriginal();\n        }\n\n        $this->classCastCache = [];\n        $this->attributeCastCache = [];\n\n        return $this;\n    }\n\n    /**\n     * Get the model's original attribute values.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? array<string, mixed> : mixed)\n     */\n    public function getOriginal($key = null, $default = null)\n    {\n        return (new static)->setRawAttributes(\n            $this->original, $sync = true\n        )->getOriginalWithoutRewindingModel($key, $default);\n    }\n\n    /**\n     * Get the model's original attribute values.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? array<string, mixed> : mixed)\n     */\n    protected function getOriginalWithoutRewindingModel($key = null, $default = null)\n    {\n        if ($key) {\n            return $this->transformModelValue(\n                $key, Arr::get($this->original, $key, $default)\n            );\n        }\n\n        return (new Collection($this->original))\n            ->mapWithKeys(fn ($value, $key) => [$key => $this->transformModelValue($key, $value)])\n            ->all();\n    }\n\n    /**\n     * Get the model's raw original attribute values.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? array<string, mixed> : mixed)\n     */\n    public function getRawOriginal($key = null, $default = null)\n    {\n        return Arr::get($this->original, $key, $default);\n    }\n\n    /**\n     * Get a subset of the model's attributes.\n     *\n     * @param  array<string>|mixed  $attributes\n     * @return array<string, mixed>\n     */\n    public function only($attributes)\n    {\n        $results = [];\n\n        foreach (is_array($attributes) ? $attributes : func_get_args() as $attribute) {\n            $results[$attribute] = $this->getAttribute($attribute);\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get all attributes except the given ones.\n     *\n     * @param  array<string>|mixed  $attributes\n     * @return array\n     */\n    public function except($attributes)\n    {\n        $attributes = is_array($attributes) ? $attributes : func_get_args();\n\n        $results = [];\n\n        foreach ($this->getAttributes() as $key => $value) {\n            if (! in_array($key, $attributes)) {\n                $results[$key] = $this->getAttribute($key);\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Sync the original attributes with the current.\n     *\n     * @return $this\n     */\n    public function syncOriginal()\n    {\n        $this->original = $this->getAttributes();\n\n        return $this;\n    }\n\n    /**\n     * Sync a single original attribute with its current value.\n     *\n     * @param  string  $attribute\n     * @return $this\n     */\n    public function syncOriginalAttribute($attribute)\n    {\n        return $this->syncOriginalAttributes($attribute);\n    }\n\n    /**\n     * Sync multiple original attribute with their current values.\n     *\n     * @param  array<string>|string  $attributes\n     * @return $this\n     */\n    public function syncOriginalAttributes($attributes)\n    {\n        $attributes = is_array($attributes) ? $attributes : func_get_args();\n\n        $modelAttributes = $this->getAttributes();\n\n        foreach ($attributes as $attribute) {\n            $this->original[$attribute] = $modelAttributes[$attribute];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Sync the changed attributes.\n     *\n     * @return $this\n     */\n    public function syncChanges()\n    {\n        $this->changes = $this->getDirty();\n        $this->previous = array_intersect_key($this->getRawOriginal(), $this->changes);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the model or any of the given attribute(s) have been modified.\n     *\n     * @param  array<string>|string|null  $attributes\n     * @return bool\n     */\n    public function isDirty($attributes = null)\n    {\n        return $this->hasChanges(\n            $this->getDirty(), is_array($attributes) ? $attributes : func_get_args()\n        );\n    }\n\n    /**\n     * Determine if the model or all the given attribute(s) have remained the same.\n     *\n     * @param  array<string>|string|null  $attributes\n     * @return bool\n     */\n    public function isClean($attributes = null)\n    {\n        return ! $this->isDirty(...func_get_args());\n    }\n\n    /**\n     * Discard attribute changes and reset the attributes to their original state.\n     *\n     * @return $this\n     */\n    public function discardChanges()\n    {\n        [$this->attributes, $this->changes, $this->previous] = [$this->original, [], []];\n\n        $this->classCastCache = [];\n        $this->attributeCastCache = [];\n\n        return $this;\n    }\n\n    /**\n     * Determine if the model or any of the given attribute(s) were changed when the model was last saved.\n     *\n     * @param  array<string>|string|null  $attributes\n     * @return bool\n     */\n    public function wasChanged($attributes = null)\n    {\n        return $this->hasChanges(\n            $this->getChanges(), is_array($attributes) ? $attributes : func_get_args()\n        );\n    }\n\n    /**\n     * Determine if any of the given attributes were changed when the model was last saved.\n     *\n     * @param  array<string>  $changes\n     * @param  array<string>|string|null  $attributes\n     * @return bool\n     */\n    protected function hasChanges($changes, $attributes = null)\n    {\n        // If no specific attributes were provided, we will just see if the dirty array\n        // already contains any attributes. If it does we will just return that this\n        // count is greater than zero. Else, we need to check specific attributes.\n        if (empty($attributes)) {\n            return count($changes) > 0;\n        }\n\n        // Here we will spin through every attribute and see if this is in the array of\n        // dirty attributes. If it is, we will return true and if we make it through\n        // all of the attributes for the entire array we will return false at end.\n        foreach (Arr::wrap($attributes) as $attribute) {\n            if (array_key_exists($attribute, $changes)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the attributes that have been changed since the last sync.\n     *\n     * @return array<string, mixed>\n     */\n    public function getDirty()\n    {\n        $dirty = [];\n\n        foreach ($this->getAttributes() as $key => $value) {\n            if (! $this->originalIsEquivalent($key)) {\n                $dirty[$key] = $value;\n            }\n        }\n\n        return $dirty;\n    }\n\n    /**\n     * Get the attributes that have been changed since the last sync for an update operation.\n     *\n     * @return array<string, mixed>\n     */\n    protected function getDirtyForUpdate()\n    {\n        return $this->getDirty();\n    }\n\n    /**\n     * Get the attributes that were changed when the model was last saved.\n     *\n     * @return array<string, mixed>\n     */\n    public function getChanges()\n    {\n        return $this->changes;\n    }\n\n    /**\n     * Get the attributes that were previously original before the model was last saved.\n     *\n     * @return array<string, mixed>\n     */\n    public function getPrevious()\n    {\n        return $this->previous;\n    }\n\n    /**\n     * Determine if the new and old values for a given key are equivalent.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function originalIsEquivalent($key)\n    {\n        if (! array_key_exists($key, $this->original)) {\n            return false;\n        }\n\n        $attribute = Arr::get($this->attributes, $key);\n        $original = Arr::get($this->original, $key);\n\n        if ($attribute === $original) {\n            return true;\n        } elseif (is_null($attribute)) {\n            return false;\n        } elseif ($this->isDateAttribute($key) || $this->isDateCastableWithCustomFormat($key)) {\n            return $this->fromDateTime($attribute) ===\n                $this->fromDateTime($original);\n        } elseif ($this->hasCast($key, ['object', 'collection'])) {\n            return $this->fromJson($attribute) ===\n                $this->fromJson($original);\n        } elseif ($this->hasCast($key, ['real', 'float', 'double'])) {\n            if ($original === null) {\n                return false;\n            }\n\n            return abs($this->castAttribute($key, $attribute) - $this->castAttribute($key, $original)) < PHP_FLOAT_EPSILON * 4;\n        } elseif ($this->isEncryptedCastable($key) && ! empty(static::currentEncrypter()->getPreviousKeys())) {\n            return false;\n        } elseif ($this->hasCast($key, static::$primitiveCastTypes)) {\n            return $this->castAttribute($key, $attribute) ===\n                $this->castAttribute($key, $original);\n        } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsArrayObject::class, AsCollection::class])) {\n            return $this->fromJson($attribute) === $this->fromJson($original);\n        } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsEnumArrayObject::class, AsEnumCollection::class])) {\n            return $this->fromJson($attribute) === $this->fromJson($original);\n        } elseif ($this->isClassCastable($key) && $original !== null && Str::startsWith($this->getCasts()[$key], [AsEncryptedArrayObject::class, AsEncryptedCollection::class])) {\n            if (empty(static::currentEncrypter()->getPreviousKeys())) {\n                return $this->fromEncryptedString($attribute) === $this->fromEncryptedString($original);\n            }\n\n            return false;\n        } elseif ($this->isClassComparable($key)) {\n            return $this->compareClassCastableAttribute($key, $original, $attribute);\n        }\n\n        return is_numeric($attribute) && is_numeric($original)\n            && strcmp((string) $attribute, (string) $original) === 0;\n    }\n\n    /**\n     * Transform a raw model value using mutators, casts, etc.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function transformModelValue($key, $value)\n    {\n        // If the attribute has a get mutator, we will call that then return what\n        // it returns as the value, which is useful for transforming values on\n        // retrieval from the model to a form that is more useful for usage.\n        if ($this->hasGetMutator($key)) {\n            return $this->mutateAttribute($key, $value);\n        } elseif ($this->hasAttributeGetMutator($key)) {\n            return $this->mutateAttributeMarkedAttribute($key, $value);\n        }\n\n        // If the attribute exists within the cast array, we will convert it to\n        // an appropriate native PHP type dependent upon the associated value\n        // given with the key in the pair. Dayle made this comment line up.\n        if ($this->hasCast($key)) {\n            if (static::preventsAccessingMissingAttributes() &&\n                ! array_key_exists($key, $this->attributes) &&\n                ($this->isEnumCastable($key) ||\n                 in_array($this->getCastType($key), static::$primitiveCastTypes))) {\n                $this->throwMissingAttributeExceptionIfApplicable($key);\n            }\n\n            return $this->castAttribute($key, $value);\n        }\n\n        // If the attribute is listed as a date, we will convert it to a DateTime\n        // instance on retrieval, which makes it quite convenient to work with\n        // date fields without having to create a mutator for each property.\n        if ($value !== null\n            && \\in_array($key, $this->getDates(), false)) {\n            return $this->asDateTime($value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Append attributes to query when building a query.\n     *\n     * @param  array<string>|string  $attributes\n     * @return $this\n     */\n    public function append($attributes)\n    {\n        $this->appends = array_values(array_unique(\n            array_merge($this->appends, is_string($attributes) ? func_get_args() : $attributes)\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Get the accessors that are being appended to model arrays.\n     *\n     * @return array\n     */\n    public function getAppends()\n    {\n        return $this->appends;\n    }\n\n    /**\n     * Set the accessors to append to model arrays.\n     *\n     * @param  array  $appends\n     * @return $this\n     */\n    public function setAppends(array $appends)\n    {\n        $this->appends = $appends;\n\n        return $this;\n    }\n\n    /**\n     * Merge new appended attributes with existing appended attributes on the model.\n     *\n     * @param  array<string>  $appends\n     * @return $this\n     */\n    public function mergeAppends(array $appends)\n    {\n        $this->appends = array_values(array_unique(array_merge($this->appends, $appends)));\n\n        return $this;\n    }\n\n    /**\n     * Return whether the accessor attribute has been appended.\n     *\n     * @param  string  $attribute\n     * @return bool\n     */\n    public function hasAppended($attribute)\n    {\n        return in_array($attribute, $this->getAppends());\n    }\n\n    /**\n     * Remove all appended properties from the model.\n     *\n     * @return $this\n     */\n    public function withoutAppends()\n    {\n        return $this->setAppends([]);\n    }\n\n    /**\n     * Get the mutated attributes for a given instance.\n     *\n     * @return array\n     */\n    public function getMutatedAttributes()\n    {\n        if (! isset(static::$mutatorCache[static::class])) {\n            static::cacheMutatedAttributes($this);\n        }\n\n        return static::$mutatorCache[static::class];\n    }\n\n    /**\n     * Extract and cache all the mutated attributes of a class.\n     *\n     * @param  object|string  $classOrInstance\n     * @return void\n     */\n    public static function cacheMutatedAttributes($classOrInstance)\n    {\n        $reflection = new ReflectionClass($classOrInstance);\n\n        $class = $reflection->getName();\n\n        static::$getAttributeMutatorCache[$class] = (new Collection($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($classOrInstance)))\n            ->mapWithKeys(fn ($match) => [lcfirst(static::$snakeAttributes ? Str::snake($match) : $match) => true])\n            ->all();\n\n        static::$mutatorCache[$class] = (new Collection(static::getMutatorMethods($class)))\n            ->merge($attributeMutatorMethods)\n            ->map(fn ($match) => lcfirst(static::$snakeAttributes ? Str::snake($match) : $match))\n            ->all();\n    }\n\n    /**\n     * Get all of the attribute mutator methods.\n     *\n     * @param  mixed  $class\n     * @return array\n     */\n    protected static function getMutatorMethods($class)\n    {\n        preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches);\n\n        return $matches[1];\n    }\n\n    /**\n     * Get all of the \"Attribute\" return typed attribute mutator methods.\n     *\n     * @param  mixed  $class\n     * @return array\n     */\n    protected static function getAttributeMarkedMutatorMethods($class)\n    {\n        $instance = is_object($class) ? $class : new $class;\n\n        return (new Collection((new ReflectionClass($instance))->getMethods()))->filter(function ($method) use ($instance) {\n            $returnType = $method->getReturnType();\n\n            if ($returnType instanceof ReflectionNamedType &&\n                $returnType->getName() === Attribute::class) {\n                if (is_callable($method->invoke($instance)->get)) {\n                    return true;\n                }\n            }\n\n            return false;\n        })->map->name->values()->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Eloquent\\Attributes\\ObservedBy;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Events\\NullDispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\nuse ReflectionClass;\n\ntrait HasEvents\n{\n    /**\n     * The event map for the model.\n     *\n     * Allows for object-based events for native Eloquent events.\n     *\n     * @var array<string, class-string>\n     */\n    protected $dispatchesEvents = [];\n\n    /**\n     * User exposed observable events.\n     *\n     * These are extra user-defined events observers may subscribe to.\n     *\n     * @var string[]\n     */\n    protected $observables = [];\n\n    /**\n     * Boot the has event trait for a model.\n     *\n     * @return void\n     */\n    public static function bootHasEvents()\n    {\n        static::whenBooted(fn () => static::observe(static::resolveObserveAttributes()));\n    }\n\n    /**\n     * Resolve the observe class names from the attributes.\n     *\n     * @return array\n     */\n    public static function resolveObserveAttributes()\n    {\n        $reflectionClass = new ReflectionClass(static::class);\n\n        $isEloquentGrandchild = is_subclass_of(static::class, Model::class)\n            && get_parent_class(static::class) !== Model::class;\n\n        return (new Collection($reflectionClass->getAttributes(ObservedBy::class)))\n            ->map(fn ($attribute) => $attribute->getArguments())\n            ->flatten()\n            ->when($isEloquentGrandchild, function (Collection $attributes) {\n                return (new Collection(get_parent_class(static::class)::resolveObserveAttributes()))\n                    ->merge($attributes);\n            })\n            ->all();\n    }\n\n    /**\n     * Register observers with the model.\n     *\n     * @param  object|string[]|string  $classes\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public static function observe($classes)\n    {\n        $instance = new static;\n\n        foreach (Arr::wrap($classes) as $class) {\n            $instance->registerObserver($class);\n        }\n    }\n\n    /**\n     * Register a single observer with the model.\n     *\n     * @param  object|string  $class\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function registerObserver($class)\n    {\n        $className = $this->resolveObserverClassName($class);\n\n        // When registering a model observer, we will spin through the possible events\n        // and determine if this observer has that method. If it does, we will hook\n        // it into the model's event system, making it convenient to watch these.\n        foreach ($this->getObservableEvents() as $event) {\n            if (method_exists($class, $event)) {\n                static::registerModelEvent($event, $className.'@'.$event);\n            }\n        }\n    }\n\n    /**\n     * Resolve the observer's class name from an object or string.\n     *\n     * @param  object|string  $class\n     * @return class-string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    private function resolveObserverClassName($class)\n    {\n        if (is_object($class)) {\n            return get_class($class);\n        }\n\n        if (class_exists($class)) {\n            return $class;\n        }\n\n        throw new InvalidArgumentException('Unable to find observer: '.$class);\n    }\n\n    /**\n     * Get the observable event names.\n     *\n     * @return string[]\n     */\n    public function getObservableEvents()\n    {\n        return array_merge(\n            [\n                'retrieved', 'creating', 'created', 'updating', 'updated',\n                'saving', 'saved', 'restoring', 'restored', 'replicating',\n                'trashed', 'deleting', 'deleted', 'forceDeleting', 'forceDeleted',\n            ],\n            $this->observables\n        );\n    }\n\n    /**\n     * Set the observable event names.\n     *\n     * @param  string[]  $observables\n     * @return $this\n     */\n    public function setObservableEvents(array $observables)\n    {\n        $this->observables = $observables;\n\n        return $this;\n    }\n\n    /**\n     * Add an observable event name.\n     *\n     * @param  string|string[]  $observables\n     * @return void\n     */\n    public function addObservableEvents($observables)\n    {\n        $this->observables = array_unique(array_merge(\n            $this->observables, is_array($observables) ? $observables : func_get_args()\n        ));\n    }\n\n    /**\n     * Remove an observable event name.\n     *\n     * @param  string|string[]  $observables\n     * @return void\n     */\n    public function removeObservableEvents($observables)\n    {\n        $this->observables = array_diff(\n            $this->observables, is_array($observables) ? $observables : func_get_args()\n        );\n    }\n\n    /**\n     * Register a model event with the dispatcher.\n     *\n     * @param  string  $event\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    protected static function registerModelEvent($event, $callback)\n    {\n        if (isset(static::$dispatcher)) {\n            $name = static::class;\n\n            static::$dispatcher->listen(\"eloquent.{$event}: {$name}\", $callback);\n        }\n    }\n\n    /**\n     * Fire the given event for the model.\n     *\n     * @param  string  $event\n     * @param  bool  $halt\n     * @return mixed\n     */\n    protected function fireModelEvent($event, $halt = true)\n    {\n        if (! isset(static::$dispatcher)) {\n            return true;\n        }\n\n        // First, we will get the proper method to call on the event dispatcher, and then we\n        // will attempt to fire a custom, object based event for the given event. If that\n        // returns a result we can return that result, or we'll call the string events.\n        $method = $halt ? 'until' : 'dispatch';\n\n        $result = $this->filterModelEventResults(\n            $this->fireCustomModelEvent($event, $method)\n        );\n\n        if ($result === false) {\n            return false;\n        }\n\n        return ! empty($result) ? $result : static::$dispatcher->{$method}(\n            \"eloquent.{$event}: \".static::class, $this\n        );\n    }\n\n    /**\n     * Fire a custom model event for the given event.\n     *\n     * @param  string  $event\n     * @param  'until'|'dispatch'  $method\n     * @return array|null|void\n     */\n    protected function fireCustomModelEvent($event, $method)\n    {\n        if (! isset($this->dispatchesEvents[$event])) {\n            return;\n        }\n\n        $result = static::$dispatcher->$method(new $this->dispatchesEvents[$event]($this));\n\n        if (! is_null($result)) {\n            return $result;\n        }\n    }\n\n    /**\n     * Filter the model event results.\n     *\n     * @param  mixed  $result\n     * @return mixed\n     */\n    protected function filterModelEventResults($result)\n    {\n        if (is_array($result)) {\n            $result = array_filter($result, function ($response) {\n                return ! is_null($response);\n            });\n        }\n\n        return $result;\n    }\n\n    /**\n     * Register a retrieved model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function retrieved($callback)\n    {\n        static::registerModelEvent('retrieved', $callback);\n    }\n\n    /**\n     * Register a saving model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function saving($callback)\n    {\n        static::registerModelEvent('saving', $callback);\n    }\n\n    /**\n     * Register a saved model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function saved($callback)\n    {\n        static::registerModelEvent('saved', $callback);\n    }\n\n    /**\n     * Register an updating model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function updating($callback)\n    {\n        static::registerModelEvent('updating', $callback);\n    }\n\n    /**\n     * Register an updated model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function updated($callback)\n    {\n        static::registerModelEvent('updated', $callback);\n    }\n\n    /**\n     * Register a creating model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function creating($callback)\n    {\n        static::registerModelEvent('creating', $callback);\n    }\n\n    /**\n     * Register a created model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function created($callback)\n    {\n        static::registerModelEvent('created', $callback);\n    }\n\n    /**\n     * Register a replicating model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function replicating($callback)\n    {\n        static::registerModelEvent('replicating', $callback);\n    }\n\n    /**\n     * Register a deleting model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function deleting($callback)\n    {\n        static::registerModelEvent('deleting', $callback);\n    }\n\n    /**\n     * Register a deleted model event with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string  $callback\n     * @return void\n     */\n    public static function deleted($callback)\n    {\n        static::registerModelEvent('deleted', $callback);\n    }\n\n    /**\n     * Remove all the event listeners for the model.\n     *\n     * @return void\n     */\n    public static function flushEventListeners()\n    {\n        if (! isset(static::$dispatcher)) {\n            return;\n        }\n\n        $instance = new static;\n\n        foreach ($instance->getObservableEvents() as $event) {\n            static::$dispatcher->forget(\"eloquent.{$event}: \".static::class);\n        }\n\n        foreach ($instance->dispatchesEvents as $event) {\n            static::$dispatcher->forget($event);\n        }\n    }\n\n    /**\n     * Get the event map for the model.\n     *\n     * @return array\n     */\n    public function dispatchesEvents()\n    {\n        return $this->dispatchesEvents;\n    }\n\n    /**\n     * Get the event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public static function getEventDispatcher()\n    {\n        return static::$dispatcher;\n    }\n\n    /**\n     * Set the event dispatcher instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @return void\n     */\n    public static function setEventDispatcher(Dispatcher $dispatcher)\n    {\n        static::$dispatcher = $dispatcher;\n    }\n\n    /**\n     * Unset the event dispatcher for models.\n     *\n     * @return void\n     */\n    public static function unsetEventDispatcher()\n    {\n        static::$dispatcher = null;\n    }\n\n    /**\n     * Execute a callback without firing any model events for any model type.\n     *\n     * @param  callable  $callback\n     * @return mixed\n     */\n    public static function withoutEvents(callable $callback)\n    {\n        $dispatcher = static::getEventDispatcher();\n\n        if ($dispatcher) {\n            static::setEventDispatcher(new NullDispatcher($dispatcher));\n        }\n\n        try {\n            return $callback();\n        } finally {\n            if ($dispatcher) {\n                static::setEventDispatcher($dispatcher);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasGlobalScopes.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Attributes\\ScopedBy;\nuse Illuminate\\Database\\Eloquent\\Scope;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\nuse ReflectionAttribute;\nuse ReflectionClass;\n\ntrait HasGlobalScopes\n{\n    /**\n     * Boot the has global scopes trait for a model.\n     *\n     * @return void\n     */\n    public static function bootHasGlobalScopes()\n    {\n        static::addGlobalScopes(static::resolveGlobalScopeAttributes());\n    }\n\n    /**\n     * Resolve the global scope class names from the attributes.\n     *\n     * @return array\n     */\n    public static function resolveGlobalScopeAttributes()\n    {\n        $reflectionClass = new ReflectionClass(static::class);\n\n        $attributes = (new Collection($reflectionClass->getAttributes(ScopedBy::class, ReflectionAttribute::IS_INSTANCEOF)));\n\n        foreach ($reflectionClass->getTraits() as $trait) {\n            $attributes->push(...$trait->getAttributes(ScopedBy::class, ReflectionAttribute::IS_INSTANCEOF));\n        }\n\n        return $attributes->map(fn ($attribute) => $attribute->getArguments())\n            ->flatten()\n            ->all();\n    }\n\n    /**\n     * Register a new global scope on the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|(\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<static>): mixed)|string  $scope\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|(\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<static>): mixed)|null  $implementation\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function addGlobalScope($scope, $implementation = null)\n    {\n        if (is_string($scope) && ($implementation instanceof Closure || $implementation instanceof Scope)) {\n            return static::$globalScopes[static::class][$scope] = $implementation;\n        } elseif ($scope instanceof Closure) {\n            return static::$globalScopes[static::class][spl_object_hash($scope)] = $scope;\n        } elseif ($scope instanceof Scope) {\n            return static::$globalScopes[static::class][get_class($scope)] = $scope;\n        } elseif (is_string($scope) && class_exists($scope) && is_subclass_of($scope, Scope::class)) {\n            return static::$globalScopes[static::class][$scope] = new $scope;\n        }\n\n        throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope or be a class name of a class extending '.Scope::class);\n    }\n\n    /**\n     * Register multiple global scopes on the model.\n     *\n     * @param  array  $scopes\n     * @return void\n     */\n    public static function addGlobalScopes(array $scopes)\n    {\n        foreach ($scopes as $key => $scope) {\n            if (is_string($key)) {\n                static::addGlobalScope($key, $scope);\n            } else {\n                static::addGlobalScope($scope);\n            }\n        }\n    }\n\n    /**\n     * Determine if a model has a global scope.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|string  $scope\n     * @return bool\n     */\n    public static function hasGlobalScope($scope)\n    {\n        return ! is_null(static::getGlobalScope($scope));\n    }\n\n    /**\n     * Get a global scope registered with the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|string  $scope\n     * @return \\Illuminate\\Database\\Eloquent\\Scope|(\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<static>): mixed)|null\n     */\n    public static function getGlobalScope($scope)\n    {\n        if (is_string($scope)) {\n            return Arr::get(static::$globalScopes, static::class.'.'.$scope);\n        }\n\n        return Arr::get(\n            static::$globalScopes, static::class.'.'.get_class($scope)\n        );\n    }\n\n    /**\n     * Get all of the global scopes that are currently registered.\n     *\n     * @return array\n     */\n    public static function getAllGlobalScopes()\n    {\n        return static::$globalScopes;\n    }\n\n    /**\n     * Set the current global scopes.\n     *\n     * @param  array  $scopes\n     * @return void\n     */\n    public static function setAllGlobalScopes($scopes)\n    {\n        static::$globalScopes = $scopes;\n    }\n\n    /**\n     * Get the global scopes for this class instance.\n     *\n     * @return array\n     */\n    public function getGlobalScopes()\n    {\n        return Arr::get(static::$globalScopes, static::class, []);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Closure;\nuse Illuminate\\Database\\ClassMorphViolationException;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Touches;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\PendingHasThroughRelationship;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\n\ntrait HasRelationships\n{\n    /**\n     * The loaded relationships for the model.\n     *\n     * @var array\n     */\n    protected $relations = [];\n\n    /**\n     * The relationships that should be touched on save.\n     *\n     * @var array\n     */\n    protected $touches = [];\n\n    /**\n     * The relationship autoloader callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $relationAutoloadCallback = null;\n\n    /**\n     * The relationship autoloader callback context.\n     *\n     * @var mixed\n     */\n    protected $relationAutoloadContext = null;\n\n    /**\n     * The many to many relationship methods.\n     *\n     * @var string[]\n     */\n    public static $manyMethods = [\n        'belongsToMany', 'morphToMany', 'morphedByMany',\n    ];\n\n    /**\n     * The relation resolver callbacks.\n     *\n     * @var array\n     */\n    protected static $relationResolvers = [];\n\n    /**\n     * Initialize the HasRelationships trait.\n     *\n     * @return void\n     */\n    #[Initialize]\n    public function initializeHasRelationships()\n    {\n        if (empty($this->touches)) {\n            $this->touches = static::resolveClassAttribute(Touches::class, 'relations') ?? [];\n        }\n    }\n\n    /**\n     * Get the dynamic relation resolver if defined or inherited, or return null.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $class\n     * @param  string  $key\n     * @return Closure|null\n     */\n    public function relationResolver($class, $key)\n    {\n        if ($resolver = static::$relationResolvers[$class][$key] ?? null) {\n            return $resolver;\n        }\n\n        if ($parent = get_parent_class($class)) {\n            return $this->relationResolver($parent, $key);\n        }\n\n        return null;\n    }\n\n    /**\n     * Define a dynamic relation resolver.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function resolveRelationUsing($name, Closure $callback)\n    {\n        static::$relationResolvers = array_replace_recursive(\n            static::$relationResolvers,\n            [static::class => [$name => $callback]]\n        );\n    }\n\n    /**\n     * Determine if a relationship autoloader callback has been defined.\n     *\n     * @return bool\n     */\n    public function hasRelationAutoloadCallback()\n    {\n        return ! is_null($this->relationAutoloadCallback);\n    }\n\n    /**\n     * Define an automatic relationship autoloader callback for this model and its relations.\n     *\n     * @param  \\Closure  $callback\n     * @param  mixed  $context\n     * @return $this\n     */\n    public function autoloadRelationsUsing(Closure $callback, $context = null)\n    {\n        // Prevent circular relation autoloading...\n        if ($context && $this->relationAutoloadContext === $context) {\n            return $this;\n        }\n\n        $this->relationAutoloadCallback = $callback;\n        $this->relationAutoloadContext = $context;\n\n        foreach ($this->relations as $key => $value) {\n            $this->propagateRelationAutoloadCallbackToRelation($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Attempt to autoload the given relationship using the autoload callback.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function attemptToAutoloadRelation($key)\n    {\n        if (! $this->hasRelationAutoloadCallback()) {\n            return false;\n        }\n\n        $this->invokeRelationAutoloadCallbackFor($key, []);\n\n        return $this->relationLoaded($key);\n    }\n\n    /**\n     * Invoke the relationship autoloader callback for the given relationships.\n     *\n     * @param  string  $key\n     * @param  array  $tuples\n     * @return void\n     */\n    protected function invokeRelationAutoloadCallbackFor($key, $tuples)\n    {\n        $tuples = array_merge([[$key, get_class($this)]], $tuples);\n\n        call_user_func($this->relationAutoloadCallback, $tuples);\n    }\n\n    /**\n     * Propagate the relationship autoloader callback to the given related models.\n     *\n     * @param  string  $key\n     * @param  mixed  $models\n     * @return void\n     */\n    protected function propagateRelationAutoloadCallbackToRelation($key, $models)\n    {\n        if (! $this->hasRelationAutoloadCallback() || ! $models) {\n            return;\n        }\n\n        if ($models instanceof Model) {\n            $models = [$models];\n        }\n\n        if (! is_iterable($models)) {\n            return;\n        }\n\n        $callback = fn (array $tuples) => $this->invokeRelationAutoloadCallbackFor($key, $tuples);\n\n        foreach ($models as $model) {\n            $model->autoloadRelationsUsing($callback, $this->relationAutoloadContext);\n        }\n    }\n\n    /**\n     * Define a one-to-one relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string|null  $foreignKey\n     * @param  string|null  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TRelatedModel, $this>\n     */\n    public function hasOne($related, $foreignKey = null, $localKey = null)\n    {\n        $instance = $this->newRelatedInstance($related);\n\n        $foreignKey = $foreignKey ?: $this->getForeignKey();\n\n        $localKey = $localKey ?: $this->getKeyName();\n\n        return $this->newHasOne($instance->newQuery(), $this, $instance->qualifyColumn($foreignKey), $localKey);\n    }\n\n    /**\n     * Instantiate a new HasOne relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $foreignKey\n     * @param  string  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TRelatedModel, TDeclaringModel>\n     */\n    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)\n    {\n        return new HasOne($query, $parent, $foreignKey, $localKey);\n    }\n\n    /**\n     * Define a has-one-through relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  class-string<TIntermediateModel>  $through\n     * @param  string|null  $firstKey\n     * @param  string|null  $secondKey\n     * @param  string|null  $localKey\n     * @param  string|null  $secondLocalKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough<TRelatedModel, TIntermediateModel, $this>\n     */\n    public function hasOneThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)\n    {\n        $through = $this->newRelatedThroughInstance($through);\n\n        $firstKey = $firstKey ?: $this->getForeignKey();\n\n        $secondKey = $secondKey ?: $through->getForeignKey();\n\n        return $this->newHasOneThrough(\n            $this->newRelatedInstance($related)->newQuery(),\n            $this,\n            $through,\n            $firstKey,\n            $secondKey,\n            $localKey ?: $this->getKeyName(),\n            $secondLocalKey ?: $through->getKeyName(),\n        );\n    }\n\n    /**\n     * Instantiate a new HasOneThrough relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $farParent\n     * @param  TIntermediateModel  $throughParent\n     * @param  string  $firstKey\n     * @param  string  $secondKey\n     * @param  string  $localKey\n     * @param  string  $secondLocalKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     */\n    protected function newHasOneThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)\n    {\n        return new HasOneThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);\n    }\n\n    /**\n     * Define a polymorphic one-to-one relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string  $name\n     * @param  string|null  $type\n     * @param  string|null  $id\n     * @param  string|null  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphOne<TRelatedModel, $this>\n     */\n    public function morphOne($related, $name, $type = null, $id = null, $localKey = null)\n    {\n        $instance = $this->newRelatedInstance($related);\n\n        [$type, $id] = $this->getMorphs($name, $type, $id);\n\n        $localKey = $localKey ?: $this->getKeyName();\n\n        return $this->newMorphOne($instance->newQuery(), $this, $instance->qualifyColumn($type), $instance->qualifyColumn($id), $localKey);\n    }\n\n    /**\n     * Instantiate a new MorphOne relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $type\n     * @param  string  $id\n     * @param  string  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphOne<TRelatedModel, TDeclaringModel>\n     */\n    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)\n    {\n        return new MorphOne($query, $parent, $type, $id, $localKey);\n    }\n\n    /**\n     * Define an inverse one-to-one or many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string|null  $foreignKey\n     * @param  string|null  $ownerKey\n     * @param  string|null  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo<TRelatedModel, $this>\n     */\n    public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)\n    {\n        // If no relation name was given, we will use this debug backtrace to extract\n        // the calling method's name and use that as the relationship name as most\n        // of the time this will be what we desire to use for the relationships.\n        if (is_null($relation)) {\n            $relation = $this->guessBelongsToRelation();\n        }\n\n        $instance = $this->newRelatedInstance($related);\n\n        // If no foreign key was supplied, we can use a backtrace to guess the proper\n        // foreign key name by using the name of the relationship function, which\n        // when combined with an \"_id\" should conventionally match the columns.\n        if (is_null($foreignKey)) {\n            $foreignKey = Str::snake($relation).'_'.$instance->getKeyName();\n        }\n\n        // Once we have the foreign key names we'll just create a new Eloquent query\n        // for the related models and return the relationship instance which will\n        // actually be responsible for retrieving and hydrating every relation.\n        $ownerKey = $ownerKey ?: $instance->getKeyName();\n\n        return $this->newBelongsTo(\n            $instance->newQuery(), $this, $foreignKey, $ownerKey, $relation\n        );\n    }\n\n    /**\n     * Instantiate a new BelongsTo relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $child\n     * @param  string  $foreignKey\n     * @param  string  $ownerKey\n     * @param  string  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo<TRelatedModel, TDeclaringModel>\n     */\n    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)\n    {\n        return new BelongsTo($query, $child, $foreignKey, $ownerKey, $relation);\n    }\n\n    /**\n     * Define a polymorphic, inverse one-to-one or many relationship.\n     *\n     * @param  string|null  $name\n     * @param  string|null  $type\n     * @param  string|null  $id\n     * @param  string|null  $ownerKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<\\Illuminate\\Database\\Eloquent\\Model, $this>\n     */\n    public function morphTo($name = null, $type = null, $id = null, $ownerKey = null)\n    {\n        // If no name is provided, we will use the backtrace to get the function name\n        // since that is most likely the name of the polymorphic interface. We can\n        // use that to get both the class and foreign key that will be utilized.\n        $name = $name ?: $this->guessBelongsToRelation();\n\n        [$type, $id] = $this->getMorphs(\n            Str::snake($name), $type, $id\n        );\n\n        // If the type value is null it is probably safe to assume we're eager loading\n        // the relationship. In this case we'll just pass in a dummy query where we\n        // need to remove any eager loads that may already be defined on a model.\n        return is_null($class = $this->getAttributeFromArray($type)) || $class === ''\n            ? $this->morphEagerTo($name, $type, $id, $ownerKey)\n            : $this->morphInstanceTo($class, $name, $type, $id, $ownerKey);\n    }\n\n    /**\n     * Define a polymorphic, inverse one-to-one or many relationship.\n     *\n     * @param  string  $name\n     * @param  string  $type\n     * @param  string  $id\n     * @param  string|null  $ownerKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<\\Illuminate\\Database\\Eloquent\\Model, $this>\n     */\n    protected function morphEagerTo($name, $type, $id, $ownerKey)\n    {\n        return $this->newMorphTo(\n            $this->newQuery()->setEagerLoads([]), $this, $id, $ownerKey, $type, $name\n        );\n    }\n\n    /**\n     * Define a polymorphic, inverse one-to-one or many relationship.\n     *\n     * @param  string  $target\n     * @param  string  $name\n     * @param  string  $type\n     * @param  string  $id\n     * @param  string|null  $ownerKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<\\Illuminate\\Database\\Eloquent\\Model, $this>\n     */\n    protected function morphInstanceTo($target, $name, $type, $id, $ownerKey)\n    {\n        $instance = $this->newRelatedInstance(\n            static::getActualClassNameForMorph($target)\n        );\n\n        return $this->newMorphTo(\n            $instance->newQuery(), $this, $id, $ownerKey ?? $instance->getKeyName(), $type, $name\n        );\n    }\n\n    /**\n     * Instantiate a new MorphTo relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $foreignKey\n     * @param  string|null  $ownerKey\n     * @param  string  $type\n     * @param  string  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, TDeclaringModel>\n     */\n    protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)\n    {\n        return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);\n    }\n\n    /**\n     * Retrieve the actual class name for a given morph class.\n     *\n     * @param  string  $class\n     * @return string\n     */\n    public static function getActualClassNameForMorph($class)\n    {\n        return Arr::get(Relation::morphMap() ?: [], $class, $class);\n    }\n\n    /**\n     * Guess the \"belongs to\" relationship name.\n     *\n     * @return string\n     */\n    protected function guessBelongsToRelation()\n    {\n        [, , $caller] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);\n\n        return $caller['function'];\n    }\n\n    /**\n     * Create a pending has-many-through or has-one-through relationship.\n     *\n     * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  string|\\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TIntermediateModel, covariant $this>|\\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TIntermediateModel, covariant $this>  $relationship\n     * @return (\n     *     $relationship is string\n     *     ? \\Illuminate\\Database\\Eloquent\\PendingHasThroughRelationship<\\Illuminate\\Database\\Eloquent\\Model, $this>\n     *     : (\n     *          $relationship is \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TIntermediateModel, $this>\n     *          ? \\Illuminate\\Database\\Eloquent\\PendingHasThroughRelationship<TIntermediateModel, $this, \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TIntermediateModel, $this>>\n     *          : \\Illuminate\\Database\\Eloquent\\PendingHasThroughRelationship<TIntermediateModel, $this, \\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TIntermediateModel, $this>>\n     *     )\n     * )\n     */\n    public function through($relationship)\n    {\n        if (is_string($relationship)) {\n            $relationship = $this->{$relationship}();\n        }\n\n        return new PendingHasThroughRelationship($this, $relationship);\n    }\n\n    /**\n     * Define a one-to-many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string|null  $foreignKey\n     * @param  string|null  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TRelatedModel, $this>\n     */\n    public function hasMany($related, $foreignKey = null, $localKey = null)\n    {\n        $instance = $this->newRelatedInstance($related);\n\n        $foreignKey = $foreignKey ?: $this->getForeignKey();\n\n        $localKey = $localKey ?: $this->getKeyName();\n\n        return $this->newHasMany(\n            $instance->newQuery(), $this, $instance->qualifyColumn($foreignKey), $localKey\n        );\n    }\n\n    /**\n     * Instantiate a new HasMany relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $foreignKey\n     * @param  string  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TRelatedModel, TDeclaringModel>\n     */\n    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)\n    {\n        return new HasMany($query, $parent, $foreignKey, $localKey);\n    }\n\n    /**\n     * Define a has-many-through relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  class-string<TIntermediateModel>  $through\n     * @param  string|null  $firstKey\n     * @param  string|null  $secondKey\n     * @param  string|null  $localKey\n     * @param  string|null  $secondLocalKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough<TRelatedModel, TIntermediateModel, $this>\n     */\n    public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)\n    {\n        $through = $this->newRelatedThroughInstance($through);\n\n        $firstKey = $firstKey ?: $this->getForeignKey();\n\n        $secondKey = $secondKey ?: $through->getForeignKey();\n\n        return $this->newHasManyThrough(\n            $this->newRelatedInstance($related)->newQuery(),\n            $this,\n            $through,\n            $firstKey,\n            $secondKey,\n            $localKey ?: $this->getKeyName(),\n            $secondLocalKey ?: $through->getKeyName()\n        );\n    }\n\n    /**\n     * Instantiate a new HasManyThrough relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $farParent\n     * @param  TIntermediateModel  $throughParent\n     * @param  string  $firstKey\n     * @param  string  $secondKey\n     * @param  string  $localKey\n     * @param  string  $secondLocalKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     */\n    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)\n    {\n        return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);\n    }\n\n    /**\n     * Define a polymorphic one-to-many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string  $name\n     * @param  string|null  $type\n     * @param  string|null  $id\n     * @param  string|null  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany<TRelatedModel, $this>\n     */\n    public function morphMany($related, $name, $type = null, $id = null, $localKey = null)\n    {\n        $instance = $this->newRelatedInstance($related);\n\n        // Here we will gather up the morph type and ID for the relationship so that we\n        // can properly query the intermediate table of a relation. Finally, we will\n        // get the table and create the relationship instances for the developers.\n        [$type, $id] = $this->getMorphs($name, $type, $id);\n\n        $localKey = $localKey ?: $this->getKeyName();\n\n        return $this->newMorphMany($instance->newQuery(), $this, $instance->qualifyColumn($type), $instance->qualifyColumn($id), $localKey);\n    }\n\n    /**\n     * Instantiate a new MorphMany relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $type\n     * @param  string  $id\n     * @param  string  $localKey\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany<TRelatedModel, TDeclaringModel>\n     */\n    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)\n    {\n        return new MorphMany($query, $parent, $type, $id, $localKey);\n    }\n\n    /**\n     * Define a many-to-many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string|class-string<\\Illuminate\\Database\\Eloquent\\Model>|null  $table\n     * @param  string|null  $foreignPivotKey\n     * @param  string|null  $relatedPivotKey\n     * @param  string|null  $parentKey\n     * @param  string|null  $relatedKey\n     * @param  string|null  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany<TRelatedModel, $this, \\Illuminate\\Database\\Eloquent\\Relations\\Pivot>\n     */\n    public function belongsToMany(\n        $related,\n        $table = null,\n        $foreignPivotKey = null,\n        $relatedPivotKey = null,\n        $parentKey = null,\n        $relatedKey = null,\n        $relation = null,\n    ) {\n        // If no relationship name was passed, we will pull backtraces to get the\n        // name of the calling function. We will use that function name as the\n        // title of this relation since that is a great convention to apply.\n        if (is_null($relation)) {\n            $relation = $this->guessBelongsToManyRelation();\n        }\n\n        // First, we'll need to determine the foreign key and \"other key\" for the\n        // relationship. Once we have determined the keys we'll make the query\n        // instances as well as the relationship instances we need for this.\n        $instance = $this->newRelatedInstance($related);\n\n        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();\n\n        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();\n\n        // If no table name was provided, we can guess it by concatenating the two\n        // models using underscores in alphabetical order. The two model names\n        // are transformed to snake case from their default CamelCase also.\n        if (is_null($table)) {\n            $table = $this->joiningTable($related, $instance);\n        }\n\n        return $this->newBelongsToMany(\n            $instance->newQuery(),\n            $this,\n            $table,\n            $foreignPivotKey,\n            $relatedPivotKey,\n            $parentKey ?: $this->getKeyName(),\n            $relatedKey ?: $instance->getKeyName(),\n            $relation,\n        );\n    }\n\n    /**\n     * Instantiate a new BelongsToMany relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string|class-string<\\Illuminate\\Database\\Eloquent\\Model>  $table\n     * @param  string  $foreignPivotKey\n     * @param  string  $relatedPivotKey\n     * @param  string  $parentKey\n     * @param  string  $relatedKey\n     * @param  string|null  $relationName\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany<TRelatedModel, TDeclaringModel, \\Illuminate\\Database\\Eloquent\\Relations\\Pivot>\n     */\n    protected function newBelongsToMany(\n        Builder $query,\n        Model $parent,\n        $table,\n        $foreignPivotKey,\n        $relatedPivotKey,\n        $parentKey,\n        $relatedKey,\n        $relationName = null,\n    ) {\n        return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);\n    }\n\n    /**\n     * Define a polymorphic many-to-many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string  $name\n     * @param  string|null  $table\n     * @param  string|null  $foreignPivotKey\n     * @param  string|null  $relatedPivotKey\n     * @param  string|null  $parentKey\n     * @param  string|null  $relatedKey\n     * @param  string|null  $relation\n     * @param  bool  $inverse\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany<TRelatedModel, $this>\n     */\n    public function morphToMany(\n        $related,\n        $name,\n        $table = null,\n        $foreignPivotKey = null,\n        $relatedPivotKey = null,\n        $parentKey = null,\n        $relatedKey = null,\n        $relation = null,\n        $inverse = false,\n    ) {\n        $relation = $relation ?: $this->guessBelongsToManyRelation();\n\n        // First, we will need to determine the foreign key and \"other key\" for the\n        // relationship. Once we have determined the keys we will make the query\n        // instances, as well as the relationship instances we need for these.\n        $instance = $this->newRelatedInstance($related);\n\n        $foreignPivotKey = $foreignPivotKey ?: $name.'_id';\n\n        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();\n\n        // Now we're ready to create a new query builder for the related model and\n        // the relationship instances for this relation. This relation will set\n        // appropriate query constraints then entirely manage the hydrations.\n        if (! $table) {\n            $words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE);\n\n            $lastWord = array_pop($words);\n\n            $table = implode('', $words).Str::plural($lastWord);\n        }\n\n        return $this->newMorphToMany(\n            $instance->newQuery(),\n            $this,\n            $name,\n            $table,\n            $foreignPivotKey,\n            $relatedPivotKey,\n            $parentKey ?: $this->getKeyName(),\n            $relatedKey ?: $instance->getKeyName(),\n            $relation,\n            $inverse,\n        );\n    }\n\n    /**\n     * Instantiate a new MorphToMany relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $name\n     * @param  string  $table\n     * @param  string  $foreignPivotKey\n     * @param  string  $relatedPivotKey\n     * @param  string  $parentKey\n     * @param  string  $relatedKey\n     * @param  string|null  $relationName\n     * @param  bool  $inverse\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany<TRelatedModel, TDeclaringModel>\n     */\n    protected function newMorphToMany(\n        Builder $query,\n        Model $parent,\n        $name,\n        $table,\n        $foreignPivotKey,\n        $relatedPivotKey,\n        $parentKey,\n        $relatedKey,\n        $relationName = null,\n        $inverse = false,\n    ) {\n        return new MorphToMany(\n            $query,\n            $parent,\n            $name,\n            $table,\n            $foreignPivotKey,\n            $relatedPivotKey,\n            $parentKey,\n            $relatedKey,\n            $relationName,\n            $inverse,\n        );\n    }\n\n    /**\n     * Define a polymorphic, inverse many-to-many relationship.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $related\n     * @param  string  $name\n     * @param  string|null  $table\n     * @param  string|null  $foreignPivotKey\n     * @param  string|null  $relatedPivotKey\n     * @param  string|null  $parentKey\n     * @param  string|null  $relatedKey\n     * @param  string|null  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany<TRelatedModel, $this>\n     */\n    public function morphedByMany(\n        $related,\n        $name,\n        $table = null,\n        $foreignPivotKey = null,\n        $relatedPivotKey = null,\n        $parentKey = null,\n        $relatedKey = null,\n        $relation = null,\n    ) {\n        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();\n\n        // For the inverse of the polymorphic many-to-many relations, we will change\n        // the way we determine the foreign and other keys, as it is the opposite\n        // of the morph-to-many method since we're figuring out these inverses.\n        $relatedPivotKey = $relatedPivotKey ?: $name.'_id';\n\n        return $this->morphToMany(\n            $related,\n            $name,\n            $table,\n            $foreignPivotKey,\n            $relatedPivotKey,\n            $parentKey,\n            $relatedKey,\n            $relation,\n            true,\n        );\n    }\n\n    /**\n     * Get the relationship name of the belongsToMany relationship.\n     *\n     * @return string|null\n     */\n    protected function guessBelongsToManyRelation()\n    {\n        $caller = Arr::first(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), function ($trace) {\n            return ! in_array(\n                $trace['function'],\n                array_merge(static::$manyMethods, ['guessBelongsToManyRelation'])\n            );\n        });\n\n        return $caller['function'] ?? null;\n    }\n\n    /**\n     * Get the joining table name for a many-to-many relation.\n     *\n     * @param  string  $related\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $instance\n     * @return string\n     */\n    public function joiningTable($related, $instance = null)\n    {\n        // The joining table name, by convention, is simply the snake cased models\n        // sorted alphabetically and concatenated with an underscore, so we can\n        // just sort the models and join them together to get the table name.\n        $segments = [\n            $instance\n                ? $instance->joiningTableSegment()\n                : Str::snake(class_basename($related)),\n            $this->joiningTableSegment(),\n        ];\n\n        // Now that we have the model names in an array we can just sort them and\n        // use the implode function to join them together with an underscores,\n        // which is typically used by convention within the database system.\n        sort($segments);\n\n        return strtolower(implode('_', $segments));\n    }\n\n    /**\n     * Get this model's half of the intermediate table name for belongsToMany relationships.\n     *\n     * @return string\n     */\n    public function joiningTableSegment()\n    {\n        return Str::snake(class_basename($this));\n    }\n\n    /**\n     * Determine if the model touches a given relation.\n     *\n     * @param  string  $relation\n     * @return bool\n     */\n    public function touches($relation)\n    {\n        return in_array($relation, $this->getTouchedRelations());\n    }\n\n    /**\n     * Touch the owning relations of the model.\n     *\n     * @return void\n     */\n    public function touchOwners()\n    {\n        $this->withoutRecursion(function () {\n            foreach ($this->getTouchedRelations() as $relation) {\n                $this->$relation()->touch();\n\n                if ($this->$relation instanceof self) {\n                    $this->$relation->fireModelEvent('saved', false);\n\n                    $this->$relation->touchOwners();\n                } elseif ($this->$relation instanceof EloquentCollection) {\n                    $this->$relation->each->touchOwners();\n                }\n            }\n        });\n    }\n\n    /**\n     * Get the polymorphic relationship columns.\n     *\n     * @param  string  $name\n     * @param  string  $type\n     * @param  string  $id\n     * @return array\n     */\n    protected function getMorphs($name, $type, $id)\n    {\n        return [$type ?: $name.'_type', $id ?: $name.'_id'];\n    }\n\n    /**\n     * Get the class name for polymorphic relations.\n     *\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\ClassMorphViolationException\n     */\n    public function getMorphClass()\n    {\n        $morphMap = Relation::morphMap();\n\n        if (! empty($morphMap) && in_array(static::class, $morphMap)) {\n            return array_search(static::class, $morphMap, true);\n        }\n\n        if (static::class === Pivot::class) {\n            return static::class;\n        }\n\n        if (Relation::requiresMorphMap()) {\n            throw new ClassMorphViolationException($this);\n        }\n\n        return static::class;\n    }\n\n    /**\n     * Create a new model instance for a related model.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $class\n     * @return TRelatedModel\n     */\n    protected function newRelatedInstance($class)\n    {\n        return tap(new $class, function ($instance) {\n            if (! $instance->getConnectionName()) {\n                $instance->setConnection($this->getConnectionName());\n            }\n        });\n    }\n\n    /**\n     * Create a new model instance for a related \"through\" model.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TRelatedModel>  $class\n     * @return TRelatedModel\n     */\n    protected function newRelatedThroughInstance($class)\n    {\n        return new $class;\n    }\n\n    /**\n     * Get all the loaded relations for the instance.\n     *\n     * @return array\n     */\n    public function getRelations()\n    {\n        return $this->relations;\n    }\n\n    /**\n     * Get a specified relationship.\n     *\n     * @param  string  $relation\n     * @return mixed\n     */\n    public function getRelation($relation)\n    {\n        return $this->relations[$relation];\n    }\n\n    /**\n     * Determine if the given relation is loaded.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function relationLoaded($key)\n    {\n        return array_key_exists($key, $this->relations);\n    }\n\n    /**\n     * Set the given relationship on the model.\n     *\n     * @param  string  $relation\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function setRelation($relation, $value)\n    {\n        $this->relations[$relation] = $value;\n\n        $this->propagateRelationAutoloadCallbackToRelation($relation, $value);\n\n        return $this;\n    }\n\n    /**\n     * Unset a loaded relationship.\n     *\n     * @param  string  $relation\n     * @return $this\n     */\n    public function unsetRelation($relation)\n    {\n        unset($this->relations[$relation]);\n\n        return $this;\n    }\n\n    /**\n     * Set the entire relations array on the model.\n     *\n     * @param  array  $relations\n     * @return $this\n     */\n    public function setRelations(array $relations)\n    {\n        $this->relations = $relations;\n\n        return $this;\n    }\n\n    /**\n     * Enable relationship autoloading for this model.\n     *\n     * @return $this\n     */\n    public function withRelationshipAutoloading()\n    {\n        $this->newCollection([$this])->withRelationshipAutoloading();\n\n        return $this;\n    }\n\n    /**\n     * Duplicate the instance and unset all the loaded relations.\n     *\n     * @return $this\n     */\n    public function withoutRelations()\n    {\n        $model = clone $this;\n\n        return $model->unsetRelations();\n    }\n\n    /**\n     * Duplicate the instance and unset the given loaded relations.\n     *\n     * @param  array|string  $relations\n     * @return $this\n     */\n    public function withoutRelation($relations)\n    {\n        $model = clone $this;\n\n        foreach ((array) $relations as $relation) {\n            $model->unsetRelation($relation);\n        }\n\n        return $model;\n    }\n\n    /**\n     * Unset all the loaded relations for the instance.\n     *\n     * @return $this\n     */\n    public function unsetRelations()\n    {\n        $this->relations = [];\n\n        return $this;\n    }\n\n    /**\n     * Get the relationships that are touched on save.\n     *\n     * @return array\n     */\n    public function getTouchedRelations()\n    {\n        return $this->touches;\n    }\n\n    /**\n     * Set the relationships that are touched on save.\n     *\n     * @param  array  $touches\n     * @return $this\n     */\n    public function setTouchedRelations(array $touches)\n    {\n        $this->touches = $touches;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasTimestamps.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Table;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Date;\n\ntrait HasTimestamps\n{\n    /**\n     * Indicates if the model should be timestamped.\n     *\n     * @var bool\n     */\n    public $timestamps = true;\n\n    /**\n     * The list of models classes that have timestamps temporarily disabled.\n     *\n     * @var array\n     */\n    protected static $ignoreTimestampsOn = [];\n\n    /**\n     * Initialize the HasTimestamps trait.\n     *\n     * @return void\n     */\n    #[Initialize]\n    public function initializeHasTimestamps()\n    {\n        if ($this->timestamps === true) {\n            if (($table = static::resolveClassAttribute(Table::class)) && $table->timestamps !== null) {\n                $this->timestamps = $table->timestamps;\n            }\n        }\n    }\n\n    /**\n     * Update the model's update timestamp.\n     *\n     * @param  array|string|null  $attribute\n     * @return bool\n     */\n    public function touch($attribute = null)\n    {\n        if ($attribute) {\n            $time = $this->freshTimestamp();\n\n            foreach (Arr::wrap($attribute) as $column) {\n                $this->{$column} = $time;\n            }\n\n            return $this->save();\n        }\n\n        if (! $this->usesTimestamps()) {\n            return false;\n        }\n\n        $this->updateTimestamps();\n\n        return $this->save();\n    }\n\n    /**\n     * Update the model's update timestamp without raising any events.\n     *\n     * @param  array|string|null  $attribute\n     * @return bool\n     */\n    public function touchQuietly($attribute = null)\n    {\n        return static::withoutEvents(fn () => $this->touch($attribute));\n    }\n\n    /**\n     * Update the creation and update timestamps.\n     *\n     * @return $this\n     */\n    public function updateTimestamps()\n    {\n        $time = $this->freshTimestamp();\n\n        $updatedAtColumn = $this->getUpdatedAtColumn();\n\n        if (! is_null($updatedAtColumn) && ! $this->isDirty($updatedAtColumn)) {\n            $this->setUpdatedAt($time);\n        }\n\n        $createdAtColumn = $this->getCreatedAtColumn();\n\n        if (! $this->exists && ! is_null($createdAtColumn) && ! $this->isDirty($createdAtColumn)) {\n            $this->setCreatedAt($time);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the value of the \"created at\" attribute.\n     *\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function setCreatedAt($value)\n    {\n        $this->{$this->getCreatedAtColumn()} = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the value of the \"updated at\" attribute.\n     *\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function setUpdatedAt($value)\n    {\n        $this->{$this->getUpdatedAtColumn()} = $value;\n\n        return $this;\n    }\n\n    /**\n     * Get a fresh timestamp for the model.\n     *\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    public function freshTimestamp()\n    {\n        return Date::now();\n    }\n\n    /**\n     * Get a fresh timestamp for the model.\n     *\n     * @return string\n     */\n    public function freshTimestampString()\n    {\n        return $this->fromDateTime($this->freshTimestamp());\n    }\n\n    /**\n     * Determine if the model uses timestamps.\n     *\n     * @return bool\n     */\n    public function usesTimestamps()\n    {\n        return $this->timestamps && ! static::isIgnoringTimestamps($this::class);\n    }\n\n    /**\n     * Get the name of the \"created at\" column.\n     *\n     * @return string|null\n     */\n    public function getCreatedAtColumn()\n    {\n        return static::CREATED_AT;\n    }\n\n    /**\n     * Get the name of the \"updated at\" column.\n     *\n     * @return string|null\n     */\n    public function getUpdatedAtColumn()\n    {\n        return static::UPDATED_AT;\n    }\n\n    /**\n     * Get the fully-qualified \"created at\" column.\n     *\n     * @return string|null\n     */\n    public function getQualifiedCreatedAtColumn()\n    {\n        $column = $this->getCreatedAtColumn();\n\n        return $column ? $this->qualifyColumn($column) : null;\n    }\n\n    /**\n     * Get the fully-qualified \"updated at\" column.\n     *\n     * @return string|null\n     */\n    public function getQualifiedUpdatedAtColumn()\n    {\n        $column = $this->getUpdatedAtColumn();\n\n        return $column ? $this->qualifyColumn($column) : null;\n    }\n\n    /**\n     * Disable timestamps for the current class during the given callback scope.\n     *\n     * @return mixed\n     */\n    public static function withoutTimestamps(callable $callback)\n    {\n        return static::withoutTimestampsOn([static::class], $callback);\n    }\n\n    /**\n     * Disable timestamps for the given model classes during the given callback scope.\n     *\n     * @param  array  $models\n     * @param  callable  $callback\n     * @return mixed\n     */\n    public static function withoutTimestampsOn($models, $callback)\n    {\n        static::$ignoreTimestampsOn = array_values(array_merge(static::$ignoreTimestampsOn, $models));\n\n        try {\n            return $callback();\n        } finally {\n            foreach ($models as $model) {\n                if (($key = array_search($model, static::$ignoreTimestampsOn, true)) !== false) {\n                    unset(static::$ignoreTimestampsOn[$key]);\n                }\n            }\n        }\n    }\n\n    /**\n     * Determine if the given model is ignoring timestamps / touches.\n     *\n     * @param  string|null  $class\n     * @return bool\n     */\n    public static function isIgnoringTimestamps($class = null)\n    {\n        $class ??= static::class;\n\n        foreach (static::$ignoreTimestampsOn as $ignoredClass) {\n            if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasUlids.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait HasUlids\n{\n    use HasUniqueStringIds;\n\n    /**\n     * Generate a new unique key for the model.\n     *\n     * @return string\n     */\n    public function newUniqueId()\n    {\n        return strtolower((string) Str::ulid());\n    }\n\n    /**\n     * Determine if given key is valid.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function isValidUniqueId($value): bool\n    {\n        return Str::isUlid($value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasUniqueIds.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\ntrait HasUniqueIds\n{\n    /**\n     * Indicates if the model uses unique IDs.\n     *\n     * @var bool\n     */\n    public $usesUniqueIds = false;\n\n    /**\n     * Determine if the model uses unique IDs.\n     *\n     * @return bool\n     */\n    public function usesUniqueIds()\n    {\n        return $this->usesUniqueIds;\n    }\n\n    /**\n     * Generate unique keys for the model.\n     *\n     * @return void\n     */\n    public function setUniqueIds()\n    {\n        foreach ($this->uniqueIds() as $column) {\n            if (empty($this->{$column})) {\n                $this->{$column} = $this->newUniqueId();\n            }\n        }\n    }\n\n    /**\n     * Generate a new key for the model.\n     *\n     * @return string\n     */\n    public function newUniqueId()\n    {\n        return null;\n    }\n\n    /**\n     * Get the columns that should receive a unique identifier.\n     *\n     * @return array\n     */\n    public function uniqueIds()\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasUniqueStringIds.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\n\ntrait HasUniqueStringIds\n{\n    /**\n     * Generate a new unique key for the model.\n     *\n     * @return mixed\n     */\n    abstract public function newUniqueId();\n\n    /**\n     * Determine if given key is valid.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    abstract protected function isValidUniqueId($value): bool;\n\n    /**\n     * Initialize the trait.\n     *\n     * @return void\n     */\n    public function initializeHasUniqueStringIds()\n    {\n        $this->usesUniqueIds = true;\n    }\n\n    /**\n     * Get the columns that should receive a unique identifier.\n     *\n     * @return array\n     */\n    public function uniqueIds()\n    {\n        return $this->usesUniqueIds() ? [$this->getKeyName()] : parent::uniqueIds();\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>  $query\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\Builder\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException\n     */\n    public function resolveRouteBindingQuery($query, $value, $field = null)\n    {\n        if ($field && in_array($field, $this->uniqueIds()) && ! $this->isValidUniqueId($value)) {\n            $this->handleInvalidUniqueId($value, $field);\n        }\n\n        if (! $field && in_array($this->getRouteKeyName(), $this->uniqueIds()) && ! $this->isValidUniqueId($value)) {\n            $this->handleInvalidUniqueId($value, $field);\n        }\n\n        return parent::resolveRouteBindingQuery($query, $value, $field);\n    }\n\n    /**\n     * Get the auto-incrementing key type.\n     *\n     * @return string\n     */\n    public function getKeyType()\n    {\n        if (in_array($this->getKeyName(), $this->uniqueIds())) {\n            return 'string';\n        }\n\n        return parent::getKeyType();\n    }\n\n    /**\n     * Get the value indicating whether the IDs are incrementing.\n     *\n     * @return bool\n     */\n    public function getIncrementing()\n    {\n        if (in_array($this->getKeyName(), $this->uniqueIds())) {\n            return false;\n        }\n\n        return parent::getIncrementing();\n    }\n\n    /**\n     * Throw an exception for the given invalid unique ID.\n     *\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return never\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException\n     */\n    protected function handleInvalidUniqueId($value, $field)\n    {\n        throw (new ModelNotFoundException)->setModel(get_class($this), $value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasUuids.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait HasUuids\n{\n    use HasUniqueStringIds;\n\n    /**\n     * Generate a new unique key for the model.\n     *\n     * @return string\n     */\n    public function newUniqueId()\n    {\n        return (string) Str::uuid7();\n    }\n\n    /**\n     * Determine if given key is valid.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function isValidUniqueId($value): bool\n    {\n        return Str::isUuid($value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HasVersion4Uuids.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait HasVersion4Uuids\n{\n    use HasUuids;\n\n    /**\n     * Generate a new UUID (version 4) for the model.\n     *\n     * @return string\n     */\n    public function newUniqueId()\n    {\n        return (string) Str::orderedUuid();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/HidesAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Hidden;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Visible;\n\ntrait HidesAttributes\n{\n    /**\n     * The attributes that should be hidden for serialization.\n     *\n     * @var array<string>\n     */\n    protected $hidden = [];\n\n    /**\n     * The attributes that should be visible in serialization.\n     *\n     * @var array<string>\n     */\n    protected $visible = [];\n\n    /**\n     * Initialize the HidesAttributes trait.\n     *\n     * @return void\n     */\n    #[Initialize]\n    public function initializeHidesAttributes()\n    {\n        if (empty($this->hidden)) {\n            $this->hidden = static::resolveClassAttribute(Hidden::class, 'columns') ?? [];\n        }\n\n        if (empty($this->visible)) {\n            $this->visible = static::resolveClassAttribute(Visible::class, 'columns') ?? [];\n        }\n    }\n\n    /**\n     * Get the hidden attributes for the model.\n     *\n     * @return array<string>\n     */\n    public function getHidden()\n    {\n        return $this->hidden;\n    }\n\n    /**\n     * Set the hidden attributes for the model.\n     *\n     * @param  array<string>  $hidden\n     * @return $this\n     */\n    public function setHidden(array $hidden)\n    {\n        $this->hidden = $hidden;\n\n        return $this;\n    }\n\n    /**\n     * Merge new hidden attributes with existing hidden attributes on the model.\n     *\n     * @param  array<string>  $hidden\n     * @return $this\n     */\n    public function mergeHidden(array $hidden)\n    {\n        $this->hidden = array_values(array_unique(array_merge($this->hidden, $hidden)));\n\n        return $this;\n    }\n\n    /**\n     * Get the visible attributes for the model.\n     *\n     * @return array<string>\n     */\n    public function getVisible()\n    {\n        return $this->visible;\n    }\n\n    /**\n     * Set the visible attributes for the model.\n     *\n     * @param  array<string>  $visible\n     * @return $this\n     */\n    public function setVisible(array $visible)\n    {\n        $this->visible = $visible;\n\n        return $this;\n    }\n\n    /**\n     * Merge new visible attributes with existing visible attributes on the model.\n     *\n     * @param  array<string>  $visible\n     * @return $this\n     */\n    public function mergeVisible(array $visible)\n    {\n        $this->visible = array_values(array_unique(array_merge($this->visible, $visible)));\n\n        return $this;\n    }\n\n    /**\n     * Make the given, typically hidden, attributes visible.\n     *\n     * @param  array<string>|string|null  $attributes\n     * @return $this\n     */\n    public function makeVisible($attributes)\n    {\n        $attributes = is_array($attributes) ? $attributes : func_get_args();\n\n        $this->hidden = array_diff($this->hidden, $attributes);\n\n        if (! empty($this->visible)) {\n            $this->visible = array_values(array_unique(array_merge($this->visible, $attributes)));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Make the given, typically hidden, attributes visible if the given truth test passes.\n     *\n     * @param  bool|\\Closure  $condition\n     * @param  array<string>|string|null  $attributes\n     * @return $this\n     */\n    public function makeVisibleIf($condition, $attributes)\n    {\n        return value($condition, $this) ? $this->makeVisible($attributes) : $this;\n    }\n\n    /**\n     * Make the given, typically visible, attributes hidden.\n     *\n     * @param  array<string>|string|null  $attributes\n     * @return $this\n     */\n    public function makeHidden($attributes)\n    {\n        $this->hidden = array_values(array_unique(array_merge(\n            $this->hidden, is_array($attributes) ? $attributes : func_get_args()\n        )));\n\n        return $this;\n    }\n\n    /**\n     * Make the given, typically visible, attributes hidden if the given truth test passes.\n     *\n     * @param  bool|\\Closure  $condition\n     * @param  array<string>|string|null  $attributes\n     * @return $this\n     */\n    public function makeHiddenIf($condition, $attributes)\n    {\n        return value($condition, $this) ? $this->makeHidden($attributes) : $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/PreventsCircularRecursion.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Onceable;\nuse WeakMap;\n\ntrait PreventsCircularRecursion\n{\n    /**\n     * The cache of objects processed to prevent infinite recursion.\n     *\n     * @var WeakMap<static, array<string, mixed>>\n     */\n    protected static $recursionCache;\n\n    /**\n     * Prevent a method from being called multiple times on the same object within the same call stack.\n     *\n     * @param  callable  $callback\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function withoutRecursion($callback, $default = null)\n    {\n        $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);\n\n        $onceable = Onceable::tryFromTrace($trace, $callback);\n\n        if (is_null($onceable)) {\n            return call_user_func($callback);\n        }\n\n        $stack = static::getRecursiveCallStack($this);\n\n        if (array_key_exists($onceable->hash, $stack)) {\n            return is_callable($stack[$onceable->hash])\n                ? static::setRecursiveCallValue($this, $onceable->hash, call_user_func($stack[$onceable->hash]))\n                : $stack[$onceable->hash];\n        }\n\n        try {\n            static::setRecursiveCallValue($this, $onceable->hash, $default);\n\n            return call_user_func($onceable->callable);\n        } finally {\n            static::clearRecursiveCallValue($this, $onceable->hash);\n        }\n    }\n\n    /**\n     * Remove an entry from the recursion cache for an object.\n     *\n     * @param  object  $object\n     * @param  string  $hash\n     */\n    protected static function clearRecursiveCallValue($object, string $hash)\n    {\n        if ($stack = Arr::except(static::getRecursiveCallStack($object), $hash)) {\n            static::getRecursionCache()->offsetSet($object, $stack);\n        } elseif (static::getRecursionCache()->offsetExists($object)) {\n            static::getRecursionCache()->offsetUnset($object);\n        }\n    }\n\n    /**\n     * Get the stack of methods being called recursively for the current object.\n     *\n     * @param  object  $object\n     * @return array\n     */\n    protected static function getRecursiveCallStack($object): array\n    {\n        return static::getRecursionCache()->offsetExists($object)\n            ? static::getRecursionCache()->offsetGet($object)\n            : [];\n    }\n\n    /**\n     * Get the current recursion cache being used by the model.\n     *\n     * @return WeakMap\n     */\n    protected static function getRecursionCache()\n    {\n        return static::$recursionCache ??= new WeakMap();\n    }\n\n    /**\n     * Set a value in the recursion cache for the given object and method.\n     *\n     * @param  object  $object\n     * @param  string  $hash\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected static function setRecursiveCallValue($object, string $hash, $value)\n    {\n        static::getRecursionCache()->offsetSet(\n            $object,\n            tap(static::getRecursiveCallStack($object), fn (&$stack) => $stack[$hash] = $value),\n        );\n\n        return static::getRecursiveCallStack($object)[$hash];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse BadMethodCallException;\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\RelationNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nuse function Illuminate\\Support\\enum_value;\n\n/** @mixin \\Illuminate\\Database\\Eloquent\\Builder */\ntrait QueriesRelationships\n{\n    /**\n     * Add a relationship count / exists condition to the query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @param  string  $boolean\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', ?Closure $callback = null)\n    {\n        if (is_string($relation)) {\n            if (str_contains($relation, '.')) {\n                return $this->hasNested($relation, $operator, $count, $boolean, $callback);\n            }\n\n            $relation = $this->getRelationWithoutConstraints($relation);\n        }\n\n        if ($relation instanceof MorphTo) {\n            return $this->hasMorph($relation, ['*'], $operator, $count, $boolean, $callback);\n        }\n\n        // If we only need to check for the existence of the relation, then we can optimize\n        // the subquery to only run a \"where exists\" clause instead of this full \"count\"\n        // clause. This will make these queries run much faster compared with a count.\n        $method = $this->canUseExistsForExistenceCheck($operator, $count)\n            ? 'getRelationExistenceQuery'\n            : 'getRelationExistenceCountQuery';\n\n        $hasQuery = $relation->{$method}(\n            $relation->getRelated()->newQueryWithoutRelationships(), $this\n        );\n\n        // Next we will call any given callback as an \"anonymous\" scope so they can get the\n        // proper logical grouping of the where clauses if needed by this Eloquent query\n        // builder. Then, we will be ready to finalize and return this query instance.\n        if ($callback) {\n            $hasQuery->callScope($callback);\n        }\n\n        return $this->addHasWhere(\n            $hasQuery, $relation, $operator, $count, $boolean\n        );\n    }\n\n    /**\n     * Add nested relationship count / exists conditions to the query.\n     *\n     * Sets up recursive call to whereHas until we finish the nested relation.\n     *\n     * @param  string  $relations\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @param  string  $boolean\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<*>): mixed)|null  $callback\n     * @return $this\n     */\n    protected function hasNested($relations, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)\n    {\n        $relations = explode('.', $relations);\n\n        $initialRelations = [...$relations];\n\n        $doesntHave = $operator === '<' && $count === 1;\n\n        if ($doesntHave) {\n            $operator = '>=';\n            $count = 1;\n        }\n\n        $closure = function ($q) use (&$closure, &$relations, $operator, $count, $callback, $initialRelations) {\n            // If the same closure is called multiple times, reset the relation array to loop through them again...\n            if ($count === 1 && empty($relations)) {\n                $relations = [...$initialRelations];\n\n                array_shift($relations);\n            }\n\n            // In order to nest \"has\", we need to add count relation constraints on the\n            // callback Closure. We'll do this by simply passing the Closure its own\n            // reference to itself so it calls itself recursively on each segment.\n            count($relations) > 1\n                ? $q->whereHas(array_shift($relations), $closure)\n                : $q->has(array_shift($relations), $operator, $count, 'and', $callback);\n        };\n\n        return $this->has(array_shift($relations), $doesntHave ? '<' : '>=', 1, $boolean, $closure);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with an \"or\".\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>|string  $relation\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function orHas($relation, $operator = '>=', $count = 1)\n    {\n        return $this->has($relation, $operator, $count, 'or');\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  string  $boolean\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @return $this\n     */\n    public function doesntHave($relation, $boolean = 'and', ?Closure $callback = null)\n    {\n        return $this->has($relation, '<', 1, $boolean, $callback);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with an \"or\".\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>|string  $relation\n     * @return $this\n     */\n    public function orDoesntHave($relation)\n    {\n        return $this->doesntHave($relation, 'or');\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with where clauses.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function whereHas($relation, ?Closure $callback = null, $operator = '>=', $count = 1)\n    {\n        return $this->has($relation, $operator, $count, 'and', $callback);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with where clauses.\n     *\n     * Also load the relationship with the same condition.\n     *\n     * @param  string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>): mixed)|null  $callback\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function withWhereHas($relation, ?Closure $callback = null, $operator = '>=', $count = 1)\n    {\n        return $this->whereHas(Str::before($relation, ':'), $callback, $operator, $count)\n            ->with($callback ? [$relation => fn ($query) => $callback($query)] : $relation);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with where clauses and an \"or\".\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function orWhereHas($relation, ?Closure $callback = null, $operator = '>=', $count = 1)\n    {\n        return $this->has($relation, $operator, $count, 'or', $callback);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with where clauses.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @return $this\n     */\n    public function whereDoesntHave($relation, ?Closure $callback = null)\n    {\n        return $this->doesntHave($relation, 'and', $callback);\n    }\n\n    /**\n     * Add a relationship count / exists condition to the query with where clauses and an \"or\".\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|null  $callback\n     * @return $this\n     */\n    public function orWhereDoesntHave($relation, ?Closure $callback = null)\n    {\n        return $this->doesntHave($relation, 'or', $callback);\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @param  string  $boolean\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @return $this\n     */\n    public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', ?Closure $callback = null)\n    {\n        if (is_string($relation)) {\n            $relation = $this->getRelationWithoutConstraints($relation);\n        }\n\n        $types = (array) $types;\n\n        $checkMorphNull = $types === ['*']\n            && (($operator === '<' && $count >= 1)\n                || ($operator === '<=' && $count >= 0)\n                || ($operator === '=' && $count === 0)\n                || ($operator === '!=' && $count >= 1));\n\n        if ($types === ['*']) {\n            $types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())\n                ->filter()\n                ->map(fn ($item) => enum_value($item))\n                ->all();\n        }\n\n        if (empty($types)) {\n            return $this->where(new Expression('0'), $operator, $count, $boolean);\n        }\n\n        foreach ($types as &$type) {\n            $type = Relation::getMorphedModel($type) ?? $type;\n        }\n\n        return $this->where(function ($query) use ($relation, $callback, $operator, $count, $types, $checkMorphNull) {\n            foreach ($types as $type) {\n                $query->orWhere(function ($query) use ($relation, $callback, $operator, $count, $type) {\n                    $belongsTo = $this->getBelongsToRelation($relation, $type);\n\n                    if ($callback) {\n                        $callback = function ($query) use ($callback, $type) {\n                            return $callback($query, $type);\n                        };\n                    }\n\n                    $query->where($this->qualifyColumn($relation->getMorphType()), '=', (new $type)->getMorphClass())\n                        ->whereHas($belongsTo, $callback, $operator, $count);\n                });\n            }\n\n            $query->when($checkMorphNull, fn (self $query) => $query->orWhereMorphedTo($relation, null));\n        }, null, null, $boolean);\n    }\n\n    /**\n     * Get the BelongsTo relationship for a single polymorphic type.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, TDeclaringModel>  $relation\n     * @param  class-string<TRelatedModel>  $type\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo<TRelatedModel, TDeclaringModel>\n     */\n    protected function getBelongsToRelation(MorphTo $relation, $type)\n    {\n        $belongsTo = Relation::noConstraints(function () use ($relation, $type) {\n            return $this->model->belongsTo(\n                $type,\n                $relation->getForeignKeyName(),\n                $relation->getOwnerKeyName()\n            );\n        });\n\n        $belongsTo->getQuery()->mergeConstraintsFrom($relation->getQuery());\n\n        return $belongsTo;\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with an \"or\".\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function orHasMorph($relation, $types, $operator = '>=', $count = 1)\n    {\n        return $this->hasMorph($relation, $types, $operator, $count, 'or');\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  string  $boolean\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @return $this\n     */\n    public function doesntHaveMorph($relation, $types, $boolean = 'and', ?Closure $callback = null)\n    {\n        return $this->hasMorph($relation, $types, '<', 1, $boolean, $callback);\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with an \"or\".\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @return $this\n     */\n    public function orDoesntHaveMorph($relation, $types)\n    {\n        return $this->doesntHaveMorph($relation, $types, 'or');\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with where clauses.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function whereHasMorph($relation, $types, ?Closure $callback = null, $operator = '>=', $count = 1)\n    {\n        return $this->hasMorph($relation, $types, $operator, $count, 'and', $callback);\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with where clauses and an \"or\".\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return $this\n     */\n    public function orWhereHasMorph($relation, $types, ?Closure $callback = null, $operator = '>=', $count = 1)\n    {\n        return $this->hasMorph($relation, $types, $operator, $count, 'or', $callback);\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with where clauses.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @return $this\n     */\n    public function whereDoesntHaveMorph($relation, $types, ?Closure $callback = null)\n    {\n        return $this->doesntHaveMorph($relation, $types, 'and', $callback);\n    }\n\n    /**\n     * Add a polymorphic relationship count / exists condition to the query with where clauses and an \"or\".\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>, string): mixed)|null  $callback\n     * @return $this\n     */\n    public function orWhereDoesntHaveMorph($relation, $types, ?Closure $callback = null)\n    {\n        return $this->doesntHaveMorph($relation, $types, 'or', $callback);\n    }\n\n    /**\n     * Add a basic where clause to a relationship query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function whereRelation($relation, $column, $operator = null, $value = null)\n    {\n        return $this->whereHas($relation, function ($query) use ($column, $operator, $value) {\n            if ($column instanceof Closure) {\n                $column($query);\n            } else {\n                $query->where($column, $operator, $value);\n            }\n        });\n    }\n\n    /**\n     * Add a basic where clause to a relationship query and eager-load the relationship with the same conditions.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>|string  $relation\n     * @param  \\Closure|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function withWhereRelation($relation, $column, $operator = null, $value = null)\n    {\n        return $this->whereRelation($relation, $column, $operator, $value)\n            ->with([\n                $relation => fn ($query) => $column instanceof Closure\n                    ? $column($query)\n                    : $query->where($column, $operator, $value),\n            ]);\n    }\n\n    /**\n     * Add an \"or where\" clause to a relationship query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereRelation($relation, $column, $operator = null, $value = null)\n    {\n        return $this->orWhereHas($relation, function ($query) use ($column, $operator, $value) {\n            if ($column instanceof Closure) {\n                $column($query);\n            } else {\n                $query->where($column, $operator, $value);\n            }\n        });\n    }\n\n    /**\n     * Add a basic count / exists condition to a relationship query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function whereDoesntHaveRelation($relation, $column, $operator = null, $value = null)\n    {\n        return $this->whereDoesntHave($relation, function ($query) use ($column, $operator, $value) {\n            if ($column instanceof Closure) {\n                $column($query);\n            } else {\n                $query->where($column, $operator, $value);\n            }\n        });\n    }\n\n    /**\n     * Add an \"or where\" clause to a relationship query.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, *, *>|string  $relation\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereDoesntHaveRelation($relation, $column, $operator = null, $value = null)\n    {\n        return $this->orWhereDoesntHave($relation, function ($query) use ($column, $operator, $value) {\n            if ($column instanceof Closure) {\n                $column($query);\n            } else {\n                $query->where($column, $operator, $value);\n            }\n        });\n    }\n\n    /**\n     * Add a polymorphic relationship condition to the query with a where clause.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function whereMorphRelation($relation, $types, $column, $operator = null, $value = null)\n    {\n        return $this->whereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {\n            $query->where($column, $operator, $value);\n        });\n    }\n\n    /**\n     * Add a polymorphic relationship condition to the query with an \"or where\" clause.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereMorphRelation($relation, $types, $column, $operator = null, $value = null)\n    {\n        return $this->orWhereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {\n            $query->where($column, $operator, $value);\n        });\n    }\n\n    /**\n     * Add a polymorphic relationship condition to the query with a doesn't have clause.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function whereMorphDoesntHaveRelation($relation, $types, $column, $operator = null, $value = null)\n    {\n        return $this->whereDoesntHaveMorph($relation, $types, function ($query) use ($column, $operator, $value) {\n            $query->where($column, $operator, $value);\n        });\n    }\n\n    /**\n     * Add a polymorphic relationship condition to the query with an \"or doesn't have\" clause.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<TRelatedModel, *>|string  $relation\n     * @param  string|array<int, string>  $types\n     * @param  (\\Closure(\\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>): mixed)|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereMorphDoesntHaveRelation($relation, $types, $column, $operator = null, $value = null)\n    {\n        return $this->orWhereDoesntHaveMorph($relation, $types, function ($query) use ($column, $operator, $value) {\n            $query->where($column, $operator, $value);\n        });\n    }\n\n    /**\n     * Add a morph-to relationship condition to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|iterable<int, \\Illuminate\\Database\\Eloquent\\Model>|string|null  $model\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function whereMorphedTo($relation, $model, $boolean = 'and')\n    {\n        if (is_string($relation)) {\n            $relation = $this->getRelationWithoutConstraints($relation);\n        }\n\n        if (is_null($model)) {\n            return $this->whereNull($relation->qualifyColumn($relation->getMorphType()), $boolean);\n        }\n\n        if (is_string($model)) {\n            $morphMap = Relation::morphMap();\n\n            if (! empty($morphMap) && in_array($model, $morphMap)) {\n                $model = array_search($model, $morphMap, true);\n            }\n\n            return $this->where($relation->qualifyColumn($relation->getMorphType()), $model, null, $boolean);\n        }\n\n        $models = BaseCollection::wrap($model);\n\n        if ($models->isEmpty()) {\n            throw new InvalidArgumentException('Collection given to whereMorphedTo method may not be empty.');\n        }\n\n        return $this->where(function ($query) use ($relation, $models) {\n            $models->groupBy(fn ($model) => $model->getMorphClass())->each(function ($models) use ($query, $relation) {\n                $query->orWhere(function ($query) use ($relation, $models) {\n                    $query->where($relation->qualifyColumn($relation->getMorphType()), $models->first()->getMorphClass())\n                        ->whereIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey());\n                });\n            });\n        }, null, null, $boolean);\n    }\n\n    /**\n     * Add a not morph-to relationship condition to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|iterable<int, \\Illuminate\\Database\\Eloquent\\Model>|string  $model\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function whereNotMorphedTo($relation, $model, $boolean = 'and')\n    {\n        if (is_string($relation)) {\n            $relation = $this->getRelationWithoutConstraints($relation);\n        }\n\n        if (is_string($model)) {\n            $morphMap = Relation::morphMap();\n\n            if (! empty($morphMap) && in_array($model, $morphMap)) {\n                $model = array_search($model, $morphMap, true);\n            }\n\n            return $this->whereNot(fn ($query) => $query->whereNullSafeEquals(\n                $relation->qualifyColumn($relation->getMorphType()), $model\n            ), null, null, $boolean);\n        }\n\n        $models = BaseCollection::wrap($model);\n\n        if ($models->isEmpty()) {\n            throw new InvalidArgumentException('Collection given to whereNotMorphedTo method may not be empty.');\n        }\n\n        return $this->whereNot(function ($query) use ($relation, $models) {\n            $models->groupBy(fn ($model) => $model->getMorphClass())->each(function ($models) use ($query, $relation) {\n                $query->orWhere(function ($query) use ($relation, $models) {\n                    $query->whereNullSafeEquals($relation->qualifyColumn($relation->getMorphType()), $models->first()->getMorphClass())\n                        ->whereIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey());\n                });\n            });\n        }, null, null, $boolean);\n    }\n\n    /**\n     * Add a morph-to relationship condition to the query with an \"or where\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|iterable<int, \\Illuminate\\Database\\Eloquent\\Model>|string|null  $model\n     * @return $this\n     */\n    public function orWhereMorphedTo($relation, $model)\n    {\n        return $this->whereMorphedTo($relation, $model, 'or');\n    }\n\n    /**\n     * Add a not morph-to relationship condition to the query with an \"or where\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<*, *>|string  $relation\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|iterable<int, \\Illuminate\\Database\\Eloquent\\Model>|string  $model\n     * @return $this\n     */\n    public function orWhereNotMorphedTo($relation, $model)\n    {\n        return $this->whereNotMorphedTo($relation, $model, 'or');\n    }\n\n    /**\n     * Add a \"belongs to\" relationship where clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|\\Illuminate\\Database\\Eloquent\\Collection<int, \\Illuminate\\Database\\Eloquent\\Model>  $related\n     * @param  string|null  $relationshipName\n     * @param  string  $boolean\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\Illuminate\\Database\\Eloquent\\RelationNotFoundException\n     */\n    public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and')\n    {\n        if (! $related instanceof EloquentCollection) {\n            $relatedCollection = $related->newCollection([$related]);\n        } else {\n            $relatedCollection = $related;\n\n            $related = $relatedCollection->first();\n        }\n\n        if ($relatedCollection->isEmpty()) {\n            throw new InvalidArgumentException('Collection given to whereBelongsTo method may not be empty.');\n        }\n\n        if ($relationshipName === null) {\n            $relationshipName = Str::camel(class_basename($related));\n        }\n\n        try {\n            $relationship = $this->model->{$relationshipName}();\n        } catch (BadMethodCallException) {\n            throw RelationNotFoundException::make($this->model, $relationshipName);\n        }\n\n        if (! $relationship instanceof BelongsTo) {\n            throw RelationNotFoundException::make($this->model, $relationshipName, BelongsTo::class);\n        }\n\n        $this->whereIn(\n            $relationship->getQualifiedForeignKeyName(),\n            $relatedCollection->pluck($relationship->getOwnerKeyName())->toArray(),\n            $boolean,\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add a \"BelongsTo\" relationship with an \"or where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $related\n     * @param  string|null  $relationshipName\n     * @return $this\n     */\n    public function orWhereBelongsTo($related, $relationshipName = null)\n    {\n        return $this->whereBelongsTo($related, $relationshipName, 'or');\n    }\n\n    /**\n     * Add a \"belongs to many\" relationship where clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|\\Illuminate\\Database\\Eloquent\\Collection<int, \\Illuminate\\Database\\Eloquent\\Model>  $related\n     * @param  string|null  $relationshipName\n     * @param  string  $boolean\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\Illuminate\\Database\\Eloquent\\RelationNotFoundException\n     */\n    public function whereAttachedTo($related, $relationshipName = null, $boolean = 'and')\n    {\n        $relatedCollection = $related instanceof EloquentCollection ? $related : $related->newCollection([$related]);\n\n        $related = $relatedCollection->first();\n\n        if ($relatedCollection->isEmpty()) {\n            throw new InvalidArgumentException('Collection given to whereAttachedTo method may not be empty.');\n        }\n\n        if ($relationshipName === null) {\n            $relationshipName = Str::plural(Str::camel(class_basename($related)));\n        }\n\n        try {\n            $relationship = $this->model->{$relationshipName}();\n        } catch (BadMethodCallException) {\n            throw RelationNotFoundException::make($this->model, $relationshipName);\n        }\n\n        if (! $relationship instanceof BelongsToMany) {\n            throw RelationNotFoundException::make($this->model, $relationshipName, BelongsToMany::class);\n        }\n\n        $this->has(\n            $relationshipName,\n            boolean: $boolean,\n            callback: fn (Builder $query) => $query->whereKey($relatedCollection->pluck($related->getKeyName())),\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add a \"belongs to many\" relationship with an \"or where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $related\n     * @param  string|null  $relationshipName\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function orWhereAttachedTo($related, $relationshipName = null)\n    {\n        return $this->whereAttachedTo($related, $relationshipName, 'or');\n    }\n\n    /**\n     * Add subselect queries to include an aggregate value for a relationship.\n     *\n     * @param  mixed  $relations\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string|null  $function\n     * @return $this\n     */\n    public function withAggregate($relations, $column, $function = null)\n    {\n        if (empty($relations)) {\n            return $this;\n        }\n\n        if (is_null($this->query->columns)) {\n            $this->query->select([$this->query->from.'.*']);\n        }\n\n        $relations = is_array($relations) ? $relations : [$relations];\n\n        foreach ($this->parseWithRelations($relations) as $name => $constraints) {\n            // First we will determine if the name has been aliased using an \"as\" clause on the name\n            // and if it has we will extract the actual relationship name and the desired name of\n            // the resulting column. This allows multiple aggregates on the same relationships.\n            $segments = explode(' ', $name);\n\n            unset($alias);\n\n            if (count($segments) === 3 && Str::lower($segments[1]) === 'as') {\n                [$name, $alias] = [$segments[0], $segments[2]];\n            }\n\n            $relation = $this->getRelationWithoutConstraints($name);\n\n            if ($function) {\n                if ($this->getQuery()->getGrammar()->isExpression($column)) {\n                    $aggregateColumn = $this->getQuery()->getGrammar()->getValue($column);\n                } else {\n                    $hashedColumn = $this->getRelationHashedColumn($column, $relation);\n\n                    $aggregateColumn = $this->getQuery()->getGrammar()->wrap(\n                        $column === '*' ? $column : $relation->getRelated()->qualifyColumn($hashedColumn)\n                    );\n                }\n\n                $expression = $function === 'exists' ? $aggregateColumn : sprintf('%s(%s)', $function, $aggregateColumn);\n            } else {\n                $expression = $this->getQuery()->getGrammar()->getValue($column);\n            }\n\n            // Here, we will grab the relationship sub-query and prepare to add it to the main query\n            // as a sub-select. First, we'll get the \"has\" query and use that to get the relation\n            // sub-query. We'll format this relationship name and append this column if needed.\n            $query = $relation->getRelationExistenceQuery(\n                $relation->getRelated()->newQuery(), $this, new Expression($expression)\n            )->setBindings([], 'select');\n\n            $query->callScope($constraints);\n\n            $query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();\n\n            // If the query contains certain elements like orderings / more than one column selected\n            // then we will remove those elements from the query so that it will execute properly\n            // when given to the database. Otherwise, we may receive SQL errors or poor syntax.\n            $query->orders = null;\n            $query->setBindings([], 'order');\n\n            if (count($query->columns) > 1) {\n                $query->columns = [$query->columns[0]];\n                $query->bindings['select'] = [];\n            }\n\n            // Finally, we will make the proper column alias to the query and run this sub-select on\n            // the query builder. Then, we will return the builder instance back to the developer\n            // for further constraint chaining that needs to take place on the query as needed.\n            $alias ??= Str::snake(\n                preg_replace(\n                    '/[^[:alnum:][:space:]_]/u',\n                    '',\n                    sprintf('%s %s %s', $name, $function, strtolower($this->getQuery()->getGrammar()->getValue($column)))\n                )\n            );\n\n            if ($function === 'exists') {\n                $this->selectRaw(\n                    sprintf('exists(%s) as %s', $query->toSql(), $this->getQuery()->grammar->wrap($alias)),\n                    $query->getBindings()\n                )->withCasts([$alias => 'bool']);\n            } else {\n                $this->selectSub(\n                    $function ? $query : $query->limit(1),\n                    $alias\n                );\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the relation hashed column name for the given column and relation.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>  $relation\n     * @return string\n     */\n    protected function getRelationHashedColumn($column, $relation)\n    {\n        if (str_contains($column, '.')) {\n            return $column;\n        }\n\n        return $this->getQuery()->from === $relation->getQuery()->getQuery()->from\n            ? \"{$relation->getRelationCountHash(false)}.$column\"\n            : $column;\n    }\n\n    /**\n     * Add subselect queries to count the relations.\n     *\n     * @param  mixed  $relations\n     * @return $this\n     */\n    public function withCount($relations)\n    {\n        return $this->withAggregate(is_array($relations) ? $relations : func_get_args(), '*', 'count');\n    }\n\n    /**\n     * Add subselect queries to include the max of the relation's column.\n     *\n     * @param  string|array  $relation\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function withMax($relation, $column)\n    {\n        return $this->withAggregate($relation, $column, 'max');\n    }\n\n    /**\n     * Add subselect queries to include the min of the relation's column.\n     *\n     * @param  string|array  $relation\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function withMin($relation, $column)\n    {\n        return $this->withAggregate($relation, $column, 'min');\n    }\n\n    /**\n     * Add subselect queries to include the sum of the relation's column.\n     *\n     * @param  string|array  $relation\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function withSum($relation, $column)\n    {\n        return $this->withAggregate($relation, $column, 'sum');\n    }\n\n    /**\n     * Add subselect queries to include the average of the relation's column.\n     *\n     * @param  string|array  $relation\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function withAvg($relation, $column)\n    {\n        return $this->withAggregate($relation, $column, 'avg');\n    }\n\n    /**\n     * Add subselect queries to include the existence of related models.\n     *\n     * @param  string|array  $relation\n     * @return $this\n     */\n    public function withExists($relation)\n    {\n        return $this->withAggregate($relation, '*', 'exists');\n    }\n\n    /**\n     * Add the \"has\" condition where clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $hasQuery\n     * @param  \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>  $relation\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function addHasWhere(Builder $hasQuery, Relation $relation, $operator, $count, $boolean)\n    {\n        $hasQuery->mergeConstraintsFrom($relation->getQuery());\n\n        return $this->canUseExistsForExistenceCheck($operator, $count)\n            ? $this->addWhereExistsQuery($hasQuery->toBase(), $boolean, $operator === '<' && $count === 1)\n            : $this->addWhereCountQuery($hasQuery->toBase(), $operator, $count, $boolean);\n    }\n\n    /**\n     * Merge the where constraints from another query to the current query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $from\n     * @return $this\n     */\n    public function mergeConstraintsFrom(Builder $from)\n    {\n        $whereBindings = $from->getQuery()->getRawBindings()['where'] ?? [];\n\n        $wheres = $from->getQuery()->from !== $this->getQuery()->from\n            ? $this->requalifyWhereTables(\n                $from->getQuery()->wheres,\n                $from->getQuery()->grammar->getValue($from->getQuery()->from),\n                $this->getModel()->getTable()\n            ) : $from->getQuery()->wheres;\n\n        // Here we have some other query that we want to merge the where constraints from. We will\n        // copy over any where constraints on the query as well as remove any global scopes the\n        // query might have removed. Then we will return ourselves with the finished merging.\n        return $this->withoutGlobalScopes(\n            $from->removedScopes()\n        )->mergeWheres(\n            $wheres, $whereBindings\n        );\n    }\n\n    /**\n     * Updates the table name for any columns with a new qualified name.\n     *\n     * @param  array  $wheres\n     * @param  string  $from\n     * @param  string  $to\n     * @return array\n     */\n    protected function requalifyWhereTables(array $wheres, string $from, string $to): array\n    {\n        return (new BaseCollection($wheres))->map(function ($where) use ($from, $to) {\n            return (new BaseCollection($where))->map(function ($value) use ($from, $to) {\n                return is_string($value) && str_starts_with($value, $from.'.')\n                    ? $to.'.'.Str::afterLast($value, '.')\n                    : $value;\n            });\n        })->toArray();\n    }\n\n    /**\n     * Add a sub-query count clause to this query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function addWhereCountQuery(QueryBuilder $query, $operator = '>=', $count = 1, $boolean = 'and')\n    {\n        $this->query->addBinding($query->getBindings(), 'where');\n\n        return $this->where(\n            new Expression('('.$query->toSql().')'),\n            $operator,\n            is_numeric($count) ? new Expression($count) : $count,\n            $boolean\n        );\n    }\n\n    /**\n     * Get the \"has relation\" base query instance.\n     *\n     * @param  string  $relation\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Relation<*, *, *>\n     */\n    protected function getRelationWithoutConstraints($relation)\n    {\n        return Relation::noConstraints(function () use ($relation) {\n            return $this->getModel()->{$relation}();\n        });\n    }\n\n    /**\n     * Check if we can run an \"exists\" query to optimize performance.\n     *\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|int  $count\n     * @return bool\n     */\n    protected function canUseExistsForExistenceCheck($operator, $count)\n    {\n        return ($operator === '>=' || $operator === '<') && $count === 1;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Concerns/TransformsToResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Support\\Str;\nuse LogicException;\nuse ReflectionClass;\n\ntrait TransformsToResource\n{\n    /**\n     * Create a new resource object for the given resource.\n     *\n     * @param  class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>|null  $resourceClass\n     * @return \\Illuminate\\Http\\Resources\\Json\\JsonResource\n     */\n    public function toResource(?string $resourceClass = null): JsonResource\n    {\n        if ($resourceClass === null) {\n            return $this->guessResource();\n        }\n\n        return $resourceClass::make($this);\n    }\n\n    /**\n     * Guess the resource class for the model.\n     *\n     * @return \\Illuminate\\Http\\Resources\\Json\\JsonResource\n     *\n     * @throws \\LogicException\n     */\n    protected function guessResource(): JsonResource\n    {\n        $resourceClass = $this->resolveResourceFromAttribute(static::class);\n\n        if ($resourceClass !== null && class_exists($resourceClass)) {\n            return $resourceClass::make($this);\n        }\n\n        foreach (static::guessResourceName() as $resourceClass) {\n            if (is_string($resourceClass) && class_exists($resourceClass)) {\n                return $resourceClass::make($this);\n            }\n        }\n\n        throw new LogicException(sprintf('Failed to find resource class for model [%s].', get_class($this)));\n    }\n\n    /**\n     * Guess the resource class name for the model.\n     *\n     * @return array{class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>, class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>}\n     */\n    public static function guessResourceName(): array\n    {\n        $modelClass = static::class;\n\n        if (! Str::contains($modelClass, '\\\\Models\\\\')) {\n            return [];\n        }\n\n        $relativeNamespace = Str::after($modelClass, '\\\\Models\\\\');\n\n        $relativeNamespace = Str::contains($relativeNamespace, '\\\\')\n            ? Str::before($relativeNamespace, '\\\\'.class_basename($modelClass))\n            : '';\n\n        $potentialResource = sprintf(\n            '%s\\\\Http\\\\Resources\\\\%s%s',\n            Str::before($modelClass, '\\\\Models'),\n            strlen($relativeNamespace) > 0 ? $relativeNamespace.'\\\\' : '',\n            class_basename($modelClass)\n        );\n\n        return [$potentialResource.'Resource', $potentialResource];\n    }\n\n    /**\n     * Get the resource class from the class attribute.\n     *\n     * @param  class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>  $class\n     * @return class-string<*>|null\n     */\n    protected function resolveResourceFromAttribute(string $class): ?string\n    {\n        if (! class_exists($class)) {\n            return null;\n        }\n\n        $attributes = (new ReflectionClass($class))->getAttributes(UseResource::class);\n\n        return $attributes !== []\n            ? $attributes[0]->newInstance()->class\n            : null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/Attributes/UseModel.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UseModel\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $class\n     */\n    public function __construct(public string $class)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/BelongsToManyRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\n\nclass BelongsToManyRelationship\n{\n    /**\n     * The related factory instance.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array\n     */\n    protected $factory;\n\n    /**\n     * The pivot attributes / attribute resolver.\n     *\n     * @var callable|array\n     */\n    protected $pivot;\n\n    /**\n     * The relationship name.\n     *\n     * @var string\n     */\n    protected $relationship;\n\n    /**\n     * Create a new attached relationship definition.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array  $factory\n     * @param  callable|array  $pivot\n     * @param  string  $relationship\n     */\n    public function __construct($factory, $pivot, $relationship)\n    {\n        $this->factory = $factory;\n        $this->pivot = $pivot;\n        $this->relationship = $relationship;\n    }\n\n    /**\n     * Create the attached relationship for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return void\n     */\n    public function createFor(Model $model)\n    {\n        $factoryInstance = $this->factory instanceof Factory;\n\n        if ($factoryInstance) {\n            $relationship = $model->{$this->relationship}();\n        }\n\n        Collection::wrap($factoryInstance ? $this->factory->prependState($relationship->getQuery()->pendingAttributes)->create([], $model) : $this->factory)->each(function ($attachable) use ($model) {\n            $model->{$this->relationship}()->attach(\n                $attachable,\n                is_callable($this->pivot) ? call_user_func($this->pivot, $model) : $this->pivot\n            );\n        });\n    }\n\n    /**\n     * Specify the model instances to always use when creating relationships.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $recycle\n     * @return $this\n     */\n    public function recycle($recycle)\n    {\n        if ($this->factory instanceof Factory) {\n            $this->factory = $this->factory->recycle($recycle);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\n\nclass BelongsToRelationship\n{\n    /**\n     * The related factory instance.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Database\\Eloquent\\Model\n     */\n    protected $factory;\n\n    /**\n     * The relationship name.\n     *\n     * @var string\n     */\n    protected $relationship;\n\n    /**\n     * The cached, resolved parent instance ID.\n     *\n     * @var mixed\n     */\n    protected $resolved;\n\n    /**\n     * Create a new \"belongs to\" relationship definition.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Database\\Eloquent\\Model  $factory\n     * @param  string  $relationship\n     */\n    public function __construct($factory, $relationship)\n    {\n        $this->factory = $factory;\n        $this->relationship = $relationship;\n    }\n\n    /**\n     * Get the parent model attributes and resolvers for the given child model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return array\n     */\n    public function attributesFor(Model $model)\n    {\n        $relationship = $model->{$this->relationship}();\n\n        return $relationship instanceof MorphTo ? [\n            $relationship->getMorphType() => $this->factory instanceof Factory ? $this->factory->newModel()->getMorphClass() : $this->factory->getMorphClass(),\n            $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()),\n        ] : [\n            $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()),\n        ];\n    }\n\n    /**\n     * Get the deferred resolver for this relationship's parent ID.\n     *\n     * @param  string|null  $key\n     * @return \\Closure\n     */\n    protected function resolver($key)\n    {\n        return function () use ($key) {\n            if (! $this->resolved) {\n                $instance = $this->factory instanceof Factory\n                    ? ($this->factory->getRandomRecycledModel($this->factory->modelName()) ?? $this->factory->create())\n                    : $this->factory;\n\n                return $this->resolved = $key ? $instance->{$key} : $instance->getKey();\n            }\n\n            return $this->resolved;\n        };\n    }\n\n    /**\n     * Specify the model instances to always use when creating relationships.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $recycle\n     * @return $this\n     */\n    public function recycle($recycle)\n    {\n        if ($this->factory instanceof Factory) {\n            $this->factory = $this->factory->recycle($recycle);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/CrossJoinSequence.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Illuminate\\Support\\Arr;\n\nclass CrossJoinSequence extends Sequence\n{\n    /**\n     * Create a new cross join sequence instance.\n     *\n     * @param  array  ...$sequences\n     */\n    public function __construct(...$sequences)\n    {\n        $crossJoined = array_map(\n            function ($a) {\n                return array_merge(...$a);\n            },\n            Arr::crossJoin(...$sequences),\n        );\n\n        parent::__construct(...$crossJoined);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Closure;\nuse Faker\\Generator;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Factories\\Attributes\\UseModel;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Enumerable;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse ReflectionClass;\nuse Throwable;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @method $this trashed()\n */\nabstract class Factory\n{\n    use Conditionable, ForwardsCalls, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The name of the factory's corresponding model.\n     *\n     * @var class-string<TModel>\n     */\n    protected $model;\n\n    /**\n     * The number of models that should be generated.\n     *\n     * @var int|null\n     */\n    protected $count;\n\n    /**\n     * The state transformations that will be applied to the model.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $states;\n\n    /**\n     * The parent relationships that will be applied to the model.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $has;\n\n    /**\n     * The child relationships that will be applied to the model.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $for;\n\n    /**\n     * The model instances to always use when creating relationships.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $recycle;\n\n    /**\n     * The \"after making\" callbacks that will be applied to the model.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $afterMaking;\n\n    /**\n     * The \"after creating\" callbacks that will be applied to the model.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $afterCreating;\n\n    /**\n     * Whether relationships should not be automatically created.\n     *\n     * @var bool\n     */\n    protected $expandRelationships = true;\n\n    /**\n     * The relationships that should not be automatically created.\n     *\n     * @var array\n     */\n    protected $excludeRelationships = [];\n\n    /**\n     * The name of the database connection that will be used to create the models.\n     *\n     * @var \\UnitEnum|string|null\n     */\n    protected $connection;\n\n    /**\n     * The current Faker instance.\n     *\n     * @var \\Faker\\Generator\n     */\n    protected $faker;\n\n    /**\n     * The default namespace where factories reside.\n     *\n     * @var string\n     */\n    public static $namespace = 'Database\\\\Factories\\\\';\n\n    /**\n     * @deprecated use $modelNameResolvers\n     *\n     * @var callable(self): class-string<TModel>\n     */\n    protected static $modelNameResolver;\n\n    /**\n     * The default model name resolvers.\n     *\n     * @var array<class-string, callable(self): class-string<TModel>>\n     */\n    protected static $modelNameResolvers = [];\n\n    /**\n     * The factory name resolver.\n     *\n     * @var callable\n     */\n    protected static $factoryNameResolver;\n\n    /**\n     * Whether to expand relationships by default.\n     *\n     * @var bool\n     */\n    protected static $expandRelationshipsByDefault = true;\n\n    /**\n     * The cached model class names resolved from attributes.\n     *\n     * @var array<class-string, class-string<TModel>|false>\n     */\n    protected static $cachedModelAttributes = [];\n\n    /**\n     * Create a new factory instance.\n     *\n     * @param  int|null  $count\n     * @param  \\Illuminate\\Support\\Collection|null  $states\n     * @param  \\Illuminate\\Support\\Collection|null  $has\n     * @param  \\Illuminate\\Support\\Collection|null  $for\n     * @param  \\Illuminate\\Support\\Collection|null  $afterMaking\n     * @param  \\Illuminate\\Support\\Collection|null  $afterCreating\n     * @param  \\UnitEnum|string|null  $connection\n     * @param  \\Illuminate\\Support\\Collection|null  $recycle\n     * @param  bool|null  $expandRelationships\n     * @param  array  $excludeRelationships\n     */\n    public function __construct(\n        $count = null,\n        ?Collection $states = null,\n        ?Collection $has = null,\n        ?Collection $for = null,\n        ?Collection $afterMaking = null,\n        ?Collection $afterCreating = null,\n        $connection = null,\n        ?Collection $recycle = null,\n        ?bool $expandRelationships = null,\n        array $excludeRelationships = [],\n    ) {\n        $this->count = $count;\n        $this->states = $states ?? new Collection;\n        $this->has = $has ?? new Collection;\n        $this->for = $for ?? new Collection;\n        $this->afterMaking = $afterMaking ?? new Collection;\n        $this->afterCreating = $afterCreating ?? new Collection;\n        $this->connection = $connection;\n        $this->recycle = $recycle ?? new Collection;\n        $this->faker = $this->withFaker();\n        $this->expandRelationships = $expandRelationships ?? self::$expandRelationshipsByDefault;\n        $this->excludeRelationships = $excludeRelationships;\n    }\n\n    /**\n     * Define the model's default state.\n     *\n     * @return array<string, mixed>\n     */\n    abstract public function definition();\n\n    /**\n     * Get a new factory instance for the given attributes.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @return static\n     */\n    public static function new($attributes = [])\n    {\n        return (new static)->state($attributes)->configure();\n    }\n\n    /**\n     * Get a new factory instance for the given number of models.\n     *\n     * @param  int  $count\n     * @return static\n     */\n    public static function times(int $count)\n    {\n        return static::new()->count($count);\n    }\n\n    /**\n     * Configure the factory.\n     *\n     * @return static\n     */\n    public function configure()\n    {\n        return $this;\n    }\n\n    /**\n     * Get the raw attributes generated by the factory.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return array<int|string, mixed>\n     */\n    public function raw($attributes = [], ?Model $parent = null)\n    {\n        if ($this->count === null) {\n            return $this->state($attributes)->getExpandedAttributes($parent);\n        }\n\n        return array_map(function () use ($attributes, $parent) {\n            return $this->state($attributes)->getExpandedAttributes($parent);\n        }, range(1, $this->count));\n    }\n\n    /**\n     * Create a single model and persist it to the database.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @return TModel\n     */\n    public function createOne($attributes = [])\n    {\n        return $this->count(null)->create($attributes);\n    }\n\n    /**\n     * Create a single model and persist it to the database without dispatching any model events.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @return TModel\n     */\n    public function createOneQuietly($attributes = [])\n    {\n        return $this->count(null)->createQuietly($attributes);\n    }\n\n    /**\n     * Create a collection of models and persist them to the database.\n     *\n     * @param  int|null|iterable<int, array<string, mixed>>  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function createMany(int|iterable|null $records = null)\n    {\n        $records ??= ($this->count ?? 1);\n\n        $this->count = null;\n\n        if (is_numeric($records)) {\n            $records = array_fill(0, $records, []);\n        }\n\n        return new EloquentCollection(\n            (new Collection($records))->map(function ($record) {\n                return $this->state($record)->create();\n            })\n        );\n    }\n\n    /**\n     * Create a collection of models and persist them to the database without dispatching any model events.\n     *\n     * @param  int|null|iterable<int, array<string, mixed>>  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function createManyQuietly(int|iterable|null $records = null)\n    {\n        return Model::withoutEvents(fn () => $this->createMany($records));\n    }\n\n    /**\n     * Create a collection of models and persist them to the database.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>|TModel\n     */\n    public function create($attributes = [], ?Model $parent = null)\n    {\n        if (! empty($attributes)) {\n            return $this->state($attributes)->create([], $parent);\n        }\n\n        $results = $this->make($attributes, $parent);\n\n        if ($results instanceof Model) {\n            $this->store(new Collection([$results]));\n\n            $this->callAfterCreating(new Collection([$results]), $parent);\n        } else {\n            $this->store($results);\n\n            $this->callAfterCreating($results, $parent);\n        }\n\n        return $results;\n    }\n\n    /**\n     * Create a collection of models and persist them to the database without dispatching any model events.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>|TModel\n     */\n    public function createQuietly($attributes = [], ?Model $parent = null)\n    {\n        return Model::withoutEvents(fn () => $this->create($attributes, $parent));\n    }\n\n    /**\n     * Create a callback that persists a model in the database when invoked.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Closure(): (\\Illuminate\\Database\\Eloquent\\Collection<int, TModel>|TModel)\n     */\n    public function lazy(array $attributes = [], ?Model $parent = null)\n    {\n        return fn () => $this->create($attributes, $parent);\n    }\n\n    /**\n     * Set the connection name on the results and store them.\n     *\n     * @param  \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Eloquent\\Model>  $results\n     * @return void\n     */\n    protected function store(Collection $results)\n    {\n        $results->each(function ($model) {\n            if (! isset($this->connection)) {\n                $model->setConnection($model->newQueryWithoutScopes()->getConnection()->getName());\n            }\n\n            $model->save();\n\n            foreach ($model->getRelations() as $name => $items) {\n                if ($items instanceof Enumerable && $items->isEmpty()) {\n                    $model->unsetRelation($name);\n                }\n            }\n\n            $this->createChildren($model);\n        });\n    }\n\n    /**\n     * Create the children for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return void\n     */\n    protected function createChildren(Model $model)\n    {\n        Model::unguarded(function () use ($model) {\n            $this->has->each(function ($has) use ($model) {\n                $has->recycle($this->recycle)->createFor($model);\n            });\n        });\n    }\n\n    /**\n     * Make a single instance of the model.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @return TModel\n     */\n    public function makeOne($attributes = [])\n    {\n        return $this->count(null)->make($attributes);\n    }\n\n    /**\n     * Create a collection of models.\n     *\n     * @param  (callable(array<string, mixed>): array<string, mixed>)|array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>|TModel\n     */\n    public function make($attributes = [], ?Model $parent = null)\n    {\n        $autoEagerLoadingEnabled = Model::isAutomaticallyEagerLoadingRelationships();\n\n        if ($autoEagerLoadingEnabled) {\n            Model::automaticallyEagerLoadRelationships(false);\n        }\n\n        try {\n            if (! empty($attributes)) {\n                return $this->state($attributes)->make([], $parent);\n            }\n\n            if ($this->count === null) {\n                return tap($this->makeInstance($parent), function ($instance) {\n                    $this->callAfterMaking(new Collection([$instance]));\n                });\n            }\n\n            if ($this->count < 1) {\n                return $this->newModel()->newCollection();\n            }\n\n            $instances = $this->newModel()->newCollection(array_map(function () use ($parent) {\n                return $this->makeInstance($parent);\n            }, range(1, $this->count)));\n\n            $this->callAfterMaking($instances);\n\n            return $instances;\n        } finally {\n            Model::automaticallyEagerLoadRelationships($autoEagerLoadingEnabled);\n        }\n    }\n\n    /**\n     * Create a collection of models.\n     *\n     * @param  iterable<int, array<string, mixed>>|int|null  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TModel>\n     */\n    public function makeMany(iterable|int|null $records = null)\n    {\n        $records ??= ($this->count ?? 1);\n\n        $this->count = null;\n\n        if (is_numeric($records)) {\n            $records = array_fill(0, $records, []);\n        }\n\n        return new EloquentCollection(\n            (new Collection($records))->map(function ($record) {\n                return $this->state($record)->make();\n            })\n        );\n    }\n\n    /**\n     * Insert the model records in bulk. No model events are emitted.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  Model|null  $parent\n     * @return void\n     */\n    public function insert(array $attributes = [], ?Model $parent = null): void\n    {\n        $made = $this->make($attributes, $parent);\n\n        $madeCollection = $made instanceof Collection\n            ? $made\n            : $this->newModel()->newCollection([$made]);\n\n        $model = $madeCollection->first();\n\n        if (isset($this->connection)) {\n            $model->setConnection($this->connection);\n        }\n\n        $query = $model->newQueryWithoutScopes();\n\n        $query->fillAndInsert(\n            $madeCollection->withoutAppends()\n                ->setHidden([])\n                ->map(static fn (Model $model) => $model->attributesToArray())\n                ->all()\n        );\n    }\n\n    /**\n     * Make an instance of the model with the given attributes.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Model\n     */\n    protected function makeInstance(?Model $parent)\n    {\n        return Model::unguarded(function () use ($parent) {\n            return tap($this->newModel($this->getExpandedAttributes($parent)), function ($instance) {\n                if (isset($this->connection)) {\n                    $instance->setConnection($this->connection);\n                }\n            });\n        });\n    }\n\n    /**\n     * Get a raw attributes array for the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return mixed\n     */\n    protected function getExpandedAttributes(?Model $parent)\n    {\n        return $this->expandAttributes($this->getRawAttributes($parent));\n    }\n\n    /**\n     * Get the raw attributes for the model as an array.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return array\n     */\n    protected function getRawAttributes(?Model $parent)\n    {\n        return $this->states->pipe(function ($states) {\n            return $this->for->isEmpty() ? $states : new Collection(array_merge([function () {\n                return $this->parentResolvers();\n            }], $states->all()));\n        })->reduce(function ($carry, $state) use ($parent) {\n            if ($state instanceof Closure) {\n                $state = $state->bindTo($this);\n            }\n\n            return array_merge($carry, $state($carry, $parent));\n        }, $this->definition());\n    }\n\n    /**\n     * Create the parent relationship resolvers (as deferred Closures).\n     *\n     * @return array\n     */\n    protected function parentResolvers()\n    {\n        return $this->for\n            ->map(fn (BelongsToRelationship $for) => $for->recycle($this->recycle)->attributesFor($this->newModel()))\n            ->collapse()\n            ->all();\n    }\n\n    /**\n     * Expand all attributes to their underlying values.\n     *\n     * @param  array  $definition\n     * @return array\n     */\n    protected function expandAttributes(array $definition)\n    {\n        return (new Collection($definition))\n            ->map($evaluateRelations = function ($attribute, $key) {\n                if (! $this->expandRelationships && $attribute instanceof self) {\n                    $attribute = null;\n                } elseif ($attribute instanceof self &&\n                    array_intersect([$attribute->modelName(), $key], $this->excludeRelationships)) {\n                    $attribute = null;\n                } elseif ($attribute instanceof self) {\n                    $attribute = $this->getRandomRecycledModel($attribute->modelName())?->getKey()\n                        ?? $attribute->recycle($this->recycle)->create()->getKey();\n                } elseif ($attribute instanceof Model) {\n                    $attribute = $attribute->getKey();\n                }\n\n                return $attribute;\n            })\n            ->map(function ($attribute, $key) use (&$definition, $evaluateRelations) {\n                if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) {\n                    $attribute = $attribute($definition);\n                }\n\n                $attribute = $evaluateRelations($attribute, $key);\n\n                $definition[$key] = $attribute;\n\n                return $attribute;\n            })\n            ->all();\n    }\n\n    /**\n     * Add a new state transformation to the model definition.\n     *\n     * @param  (callable(array<string, mixed>, Model|null): array<string, mixed>)|array<string, mixed>  $state\n     * @return static\n     */\n    public function state($state)\n    {\n        return $this->newInstance([\n            'states' => $this->states->concat([\n                is_callable($state) ? $state : fn () => $state,\n            ]),\n        ]);\n    }\n\n    /**\n     * Prepend a new state transformation to the model definition.\n     *\n     * @param  (callable(array<string, mixed>, Model|null): array<string, mixed>)|array<string, mixed>  $state\n     * @return static\n     */\n    public function prependState($state)\n    {\n        return $this->newInstance([\n            'states' => $this->states->prepend(\n                is_callable($state) ? $state : fn () => $state,\n            ),\n        ]);\n    }\n\n    /**\n     * Set a single model attribute.\n     *\n     * @param  string|int  $key\n     * @param  mixed  $value\n     * @return static\n     */\n    public function set($key, $value)\n    {\n        return $this->state([$key => $value]);\n    }\n\n    /**\n     * Add a new sequenced state transformation to the model definition.\n     *\n     * @param  mixed  ...$sequence\n     * @return static\n     */\n    public function sequence(...$sequence)\n    {\n        return $this->state(new Sequence(...$sequence));\n    }\n\n    /**\n     * Add a new sequenced state transformation to the model definition and update the pending creation count to the size of the sequence.\n     *\n     * @param  array  ...$sequence\n     * @return static\n     */\n    public function forEachSequence(...$sequence)\n    {\n        return $this->state(new Sequence(...$sequence))->count(count($sequence));\n    }\n\n    /**\n     * Add a new cross joined sequenced state transformation to the model definition.\n     *\n     * @param  array  ...$sequence\n     * @return static\n     */\n    public function crossJoinSequence(...$sequence)\n    {\n        return $this->state(new CrossJoinSequence(...$sequence));\n    }\n\n    /**\n     * Define a child relationship for the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory  $factory\n     * @param  string|null  $relationship\n     * @return static\n     */\n    public function has(self $factory, $relationship = null)\n    {\n        return $this->newInstance([\n            'has' => $this->has->concat([new Relationship(\n                $factory, $relationship ?? $this->guessRelationship($factory->modelName())\n            )]),\n        ]);\n    }\n\n    /**\n     * Attempt to guess the relationship name for a \"has\" relationship.\n     *\n     * @param  string  $related\n     * @return string\n     */\n    protected function guessRelationship(string $related)\n    {\n        $guess = Str::camel(Str::plural(class_basename($related)));\n\n        return method_exists($this->modelName(), $guess) ? $guess : Str::singular($guess);\n    }\n\n    /**\n     * Define an attached relationship for the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array  $factory\n     * @param  (callable(): array<string, mixed>)|array<string, mixed>  $pivot\n     * @param  string|null  $relationship\n     * @return static\n     */\n    public function hasAttached($factory, $pivot = [], $relationship = null)\n    {\n        return $this->newInstance([\n            'has' => $this->has->concat([new BelongsToManyRelationship(\n                $factory,\n                $pivot,\n                $relationship ?? Str::camel(Str::plural(class_basename(\n                    $factory instanceof Factory\n                        ? $factory->modelName()\n                        : Collection::wrap($factory)->first()\n                )))\n            )]),\n        ]);\n    }\n\n    /**\n     * Define a parent relationship for the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory|\\Illuminate\\Database\\Eloquent\\Model  $factory\n     * @param  string|null  $relationship\n     * @return static\n     */\n    public function for($factory, $relationship = null)\n    {\n        return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship(\n            $factory,\n            $relationship ?? Str::camel(class_basename(\n                $factory instanceof Factory ? $factory->modelName() : $factory\n            ))\n        )])]);\n    }\n\n    /**\n     * Provide model instances to use instead of any nested factory calls when creating relationships.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|\\Illuminate\\Support\\Collection|array  $model\n     * @return static\n     */\n    public function recycle($model)\n    {\n        // Group provided models by the type and merge them into existing recycle collection\n        return $this->newInstance([\n            'recycle' => $this->recycle\n                ->flatten()\n                ->merge(\n                    Collection::wrap($model instanceof Model ? func_get_args() : $model)\n                        ->flatten()\n                )->groupBy(fn ($model) => get_class($model)),\n        ]);\n    }\n\n    /**\n     * Retrieve a random model of a given type from previously provided models to recycle.\n     *\n     * @template TClass of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TClass>  $modelClassName\n     * @return TClass|null\n     */\n    public function getRandomRecycledModel($modelClassName)\n    {\n        return $this->recycle->get($modelClassName)?->random();\n    }\n\n    /**\n     * Add a new \"after making\" callback to the model definition.\n     *\n     * @param  \\Closure(TModel): mixed  $callback\n     * @return static\n     */\n    public function afterMaking(Closure $callback)\n    {\n        return $this->newInstance(['afterMaking' => $this->afterMaking->concat([$callback])]);\n    }\n\n    /**\n     * Add a new \"after creating\" callback to the model definition.\n     *\n     * @param  \\Closure(TModel, \\Illuminate\\Database\\Eloquent\\Model|null): mixed  $callback\n     * @return static\n     */\n    public function afterCreating(Closure $callback)\n    {\n        return $this->newInstance(['afterCreating' => $this->afterCreating->concat([$callback])]);\n    }\n\n    /**\n     * Remove the \"after making\" callbacks from the factory.\n     *\n     * @return static\n     */\n    public function withoutAfterMaking()\n    {\n        return $this->newInstance(['afterMaking' => new Collection]);\n    }\n\n    /**\n     * Remove the \"after creating\" callbacks from the factory.\n     *\n     * @return static\n     */\n    public function withoutAfterCreating()\n    {\n        return $this->newInstance(['afterCreating' => new Collection]);\n    }\n\n    /**\n     * Call the \"after making\" callbacks for the given model instances.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $instances\n     * @return void\n     */\n    protected function callAfterMaking(Collection $instances)\n    {\n        $instances->each(function ($model) {\n            $this->afterMaking->each(function ($callback) use ($model) {\n                $callback($model);\n            });\n        });\n    }\n\n    /**\n     * Call the \"after creating\" callbacks for the given model instances.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $instances\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return void\n     */\n    protected function callAfterCreating(Collection $instances, ?Model $parent = null)\n    {\n        $instances->each(function ($model) use ($parent) {\n            $this->afterCreating->each(function ($callback) use ($model, $parent) {\n                $callback($model, $parent);\n            });\n        });\n    }\n\n    /**\n     * Specify how many models should be generated.\n     *\n     * @param  int|null  $count\n     * @return static\n     */\n    public function count(?int $count)\n    {\n        return $this->newInstance(['count' => $count]);\n    }\n\n    /**\n     * Indicate that related parent models should not be created.\n     *\n     * @param  array<string|class-string<Model>>  $parents\n     * @return static\n     */\n    public function withoutParents($parents = [])\n    {\n        return $this->newInstance(! $parents ? ['expandRelationships' => false] : ['excludeRelationships' => $parents]);\n    }\n\n    /**\n     * Get the name of the database connection that is used to generate models.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return enum_value($this->connection);\n    }\n\n    /**\n     * Specify the database connection that should be used to generate models.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return static\n     */\n    public function connection(UnitEnum|string|null $connection)\n    {\n        return $this->newInstance(['connection' => $connection]);\n    }\n\n    /**\n     * Create a new instance of the factory builder with the given mutated properties.\n     *\n     * @param  array  $arguments\n     * @return static\n     */\n    protected function newInstance(array $arguments = [])\n    {\n        return new static(...array_values(array_merge([\n            'count' => $this->count,\n            'states' => $this->states,\n            'has' => $this->has,\n            'for' => $this->for,\n            'afterMaking' => $this->afterMaking,\n            'afterCreating' => $this->afterCreating,\n            'connection' => $this->connection,\n            'recycle' => $this->recycle,\n            'expandRelationships' => $this->expandRelationships,\n            'excludeRelationships' => $this->excludeRelationships,\n        ], $arguments)));\n    }\n\n    /**\n     * Get a new model instance.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @return TModel\n     */\n    public function newModel(array $attributes = [])\n    {\n        $model = $this->modelName();\n\n        return new $model($attributes);\n    }\n\n    /**\n     * Get the name of the model that is generated by the factory.\n     *\n     * @return class-string<TModel>\n     */\n    public function modelName()\n    {\n        if (! array_key_exists(static::class, static::$cachedModelAttributes)) {\n            $attribute = (new ReflectionClass($this))->getAttributes(UseModel::class);\n\n            static::$cachedModelAttributes[static::class] = count($attribute) > 0\n                ? $attribute[0]->newInstance()->class\n                : false;\n        }\n\n        if (static::$cachedModelAttributes[static::class]) {\n            return static::$cachedModelAttributes[static::class];\n        }\n\n        if ($this->model !== null) {\n            return $this->model;\n        }\n\n        $resolver = static::$modelNameResolvers[static::class] ?? static::$modelNameResolvers[self::class] ?? static::$modelNameResolver ?? function (self $factory) {\n            $namespacedFactoryBasename = Str::replaceLast(\n                'Factory', '', Str::replaceFirst(static::$namespace, '', $factory::class)\n            );\n\n            $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory));\n\n            $appNamespace = static::appNamespace();\n\n            return class_exists($appNamespace.'Models\\\\'.$namespacedFactoryBasename)\n                ? $appNamespace.'Models\\\\'.$namespacedFactoryBasename\n                : $appNamespace.$factoryBasename;\n        };\n\n        return $resolver($this);\n    }\n\n    /**\n     * Specify the callback that should be invoked to guess model names based on factory names.\n     *\n     * @param  callable(self): class-string<TModel>  $callback\n     * @return void\n     */\n    public static function guessModelNamesUsing(callable $callback)\n    {\n        static::$modelNameResolvers[static::class] = $callback;\n    }\n\n    /**\n     * Specify the default namespace that contains the application's model factories.\n     *\n     * @param  string  $namespace\n     * @return void\n     */\n    public static function useNamespace(string $namespace)\n    {\n        static::$namespace = $namespace;\n    }\n\n    /**\n     * Get a new factory instance for the given model name.\n     *\n     * @template TClass of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TClass>  $modelName\n     * @return \\Illuminate\\Database\\Eloquent\\Factories\\Factory<TClass>\n     */\n    public static function factoryForModel(string $modelName)\n    {\n        $factory = static::resolveFactoryName($modelName);\n\n        return $factory::new();\n    }\n\n    /**\n     * Specify the callback that should be invoked to guess factory names based on dynamic relationship names.\n     *\n     * @param  callable(class-string<\\Illuminate\\Database\\Eloquent\\Model>): class-string<\\Illuminate\\Database\\Eloquent\\Factories\\Factory>  $callback\n     * @return void\n     */\n    public static function guessFactoryNamesUsing(callable $callback)\n    {\n        static::$factoryNameResolver = $callback;\n    }\n\n    /**\n     * Specify that relationships should create parent relationships by default.\n     *\n     * @return void\n     */\n    public static function expandRelationshipsByDefault()\n    {\n        static::$expandRelationshipsByDefault = true;\n    }\n\n    /**\n     * Specify that relationships should not create parent relationships by default.\n     *\n     * @return void\n     */\n    public static function dontExpandRelationshipsByDefault()\n    {\n        static::$expandRelationshipsByDefault = false;\n    }\n\n    /**\n     * Get a new Faker instance.\n     *\n     * @return \\Faker\\Generator|null\n     */\n    protected function withFaker()\n    {\n        if (! class_exists(Generator::class)) {\n            return;\n        }\n\n        return Container::getInstance()->make(Generator::class);\n    }\n\n    /**\n     * Get the factory name for the given model name.\n     *\n     * @template TClass of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TClass>  $modelName\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Factories\\Factory<TClass>>\n     */\n    public static function resolveFactoryName(string $modelName)\n    {\n        $resolver = static::$factoryNameResolver ?? function (string $modelName) {\n            $appNamespace = static::appNamespace();\n\n            $modelName = Str::startsWith($modelName, $appNamespace.'Models\\\\')\n                ? Str::after($modelName, $appNamespace.'Models\\\\')\n                : Str::after($modelName, $appNamespace);\n\n            return static::$namespace.$modelName.'Factory';\n        };\n\n        return $resolver($modelName);\n    }\n\n    /**\n     * Get the application namespace for the application.\n     *\n     * @return string\n     */\n    protected static function appNamespace()\n    {\n        try {\n            return Container::getInstance()\n                ->make(Application::class)\n                ->getNamespace();\n        } catch (Throwable) {\n            return 'App\\\\';\n        }\n    }\n\n    /**\n     * Flush the factory's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$modelNameResolver = null;\n        static::$modelNameResolvers = [];\n        static::$factoryNameResolver = null;\n        static::$namespace = 'Database\\\\Factories\\\\';\n        static::$expandRelationshipsByDefault = true;\n    }\n\n    /**\n     * Proxy dynamic factory methods onto their proper methods.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if ($method === 'trashed' && $this->modelName()::isSoftDeletable()) {\n            return $this->state([\n                $this->newModel()->getDeletedAtColumn() => $parameters[0] ?? Carbon::now()->subDay(),\n            ]);\n        }\n\n        if (! Str::startsWith($method, ['for', 'has'])) {\n            static::throwBadMethodCallException($method);\n        }\n\n        $relationship = Str::camel(Str::substr($method, 3));\n\n        $relatedModel = get_class($this->newModel()->{$relationship}()->getRelated());\n\n        if (method_exists($relatedModel, 'newFactory')) {\n            $factory = $relatedModel::newFactory() ?? static::factoryForModel($relatedModel);\n        } else {\n            $factory = static::factoryForModel($relatedModel);\n        }\n\n        if (str_starts_with($method, 'for')) {\n            return $this->for($factory->state($parameters[0] ?? []), $relationship);\n        } elseif (str_starts_with($method, 'has')) {\n            return $this->has(\n                $factory\n                    ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : 1)\n                    ->state((is_callable($parameters[0] ?? null) || is_array($parameters[0] ?? null)) ? $parameters[0] : ($parameters[1] ?? [])),\n                $relationship\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/HasFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\n\n/**\n * @template TFactory of \\Illuminate\\Database\\Eloquent\\Factories\\Factory\n */\ntrait HasFactory\n{\n    /**\n     * Get a new factory instance for the model.\n     *\n     * @param  (callable(array<string, mixed>, static|null): array<string, mixed>)|array<string, mixed>|int|null  $count\n     * @param  (callable(array<string, mixed>, static|null): array<string, mixed>)|array<string, mixed>  $state\n     * @return TFactory\n     */\n    public static function factory($count = null, $state = [])\n    {\n        $factory = static::newFactory() ?? Factory::factoryForModel(static::class);\n\n        return $factory\n            ->count(is_numeric($count) ? $count : null)\n            ->state(is_callable($count) || is_array($count) ? $count : $state);\n    }\n\n    /**\n     * Create a new factory instance for the model.\n     *\n     * @return TFactory|null\n     */\n    protected static function newFactory()\n    {\n        if (isset(static::$factory)) {\n            return static::$factory::new();\n        }\n\n        return static::getUseFactoryAttribute() ?? null;\n    }\n\n    /**\n     * Get the factory from the UseFactory class attribute.\n     *\n     * @return TFactory|null\n     */\n    protected static function getUseFactoryAttribute()\n    {\n        $attributes = (new \\ReflectionClass(static::class))\n            ->getAttributes(UseFactory::class);\n\n        if ($attributes !== []) {\n            $useFactory = $attributes[0]->newInstance();\n\n            $factory = $useFactory->factoryClass::new();\n\n            $factory->guessModelNamesUsing(fn () => static::class);\n\n            return $factory;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/Relationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany;\n\nclass Relationship\n{\n    /**\n     * The related factory instance.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Factories\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The relationship name.\n     *\n     * @var string\n     */\n    protected $relationship;\n\n    /**\n     * Create a new child relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Factories\\Factory  $factory\n     * @param  string  $relationship\n     */\n    public function __construct(Factory $factory, $relationship)\n    {\n        $this->factory = $factory;\n        $this->relationship = $relationship;\n    }\n\n    /**\n     * Create the child relationship for the given parent model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @return void\n     */\n    public function createFor(Model $parent)\n    {\n        $relationship = $parent->{$this->relationship}();\n\n        if ($relationship instanceof MorphOneOrMany) {\n            $this->factory->state([\n                $relationship->getMorphType() => $relationship->getMorphClass(),\n                $relationship->getForeignKeyName() => $relationship->getParentKey(),\n            ])->prependState($relationship->getQuery()->pendingAttributes)->create([], $parent);\n        } elseif ($relationship instanceof HasOneOrMany) {\n            $this->factory->state([\n                $relationship->getForeignKeyName() => $relationship->getParentKey(),\n            ])->prependState($relationship->getQuery()->pendingAttributes)->create([], $parent);\n        } elseif ($relationship instanceof BelongsToMany) {\n            $relationship->attach(\n                $this->factory->prependState($relationship->getQuery()->pendingAttributes)->create([], $parent)\n            );\n        }\n    }\n\n    /**\n     * Specify the model instances to always use when creating relationships.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $recycle\n     * @return $this\n     */\n    public function recycle($recycle)\n    {\n        $this->factory = $this->factory->recycle($recycle);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Factories/Sequence.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Factories;\n\nuse Countable;\n\nclass Sequence implements Countable\n{\n    /**\n     * The sequence of return values.\n     *\n     * @var array\n     */\n    protected $sequence;\n\n    /**\n     * The count of the sequence items.\n     *\n     * @var int\n     */\n    public $count;\n\n    /**\n     * The current index of the sequence iteration.\n     *\n     * @var int\n     */\n    public $index = 0;\n\n    /**\n     * Create a new sequence instance.\n     *\n     * @param  mixed  ...$sequence\n     */\n    public function __construct(...$sequence)\n    {\n        $this->sequence = $sequence;\n        $this->count = count($sequence);\n    }\n\n    /**\n     * Get the current count of the sequence items.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return $this->count;\n    }\n\n    /**\n     * Get the next value in the sequence.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return mixed\n     */\n    public function __invoke($attributes = [], $parent = null)\n    {\n        return tap(value($this->sequence[$this->index % $this->count], $this, $attributes, $parent), function () {\n            $this->index = $this->index + 1;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/HasBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\n/**\n * @template TBuilder of \\Illuminate\\Database\\Eloquent\\Builder\n */\ntrait HasBuilder\n{\n    /**\n     * Begin querying the model.\n     *\n     * @return TBuilder\n     */\n    public static function query()\n    {\n        return parent::query();\n    }\n\n    /**\n     * Create a new Eloquent query builder for the model.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return TBuilder\n     */\n    public function newEloquentBuilder($query)\n    {\n        return parent::newEloquentBuilder($query);\n    }\n\n    /**\n     * Get a new query builder for the model's table.\n     *\n     * @return TBuilder\n     */\n    public function newQuery()\n    {\n        return parent::newQuery();\n    }\n\n    /**\n     * Get a new query builder that doesn't have any global scopes or eager loading.\n     *\n     * @return TBuilder\n     */\n    public function newModelQuery()\n    {\n        return parent::newModelQuery();\n    }\n\n    /**\n     * Get a new query builder with no relationships loaded.\n     *\n     * @return TBuilder\n     */\n    public function newQueryWithoutRelationships()\n    {\n        return parent::newQueryWithoutRelationships();\n    }\n\n    /**\n     * Get a new query builder that doesn't have any global scopes.\n     *\n     * @return TBuilder\n     */\n    public function newQueryWithoutScopes()\n    {\n        return parent::newQueryWithoutScopes();\n    }\n\n    /**\n     * Get a new query instance without a given scope.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|string  $scope\n     * @return TBuilder\n     */\n    public function newQueryWithoutScope($scope)\n    {\n        return parent::newQueryWithoutScope($scope);\n    }\n\n    /**\n     * Get a new query to restore one or more models by their queueable IDs.\n     *\n     * @param  array|int  $ids\n     * @return TBuilder\n     */\n    public function newQueryForRestoration($ids)\n    {\n        return parent::newQueryForRestoration($ids);\n    }\n\n    /**\n     * Begin querying the model on a given connection.\n     *\n     * @param  string|null  $connection\n     * @return TBuilder\n     */\n    public static function on($connection = null)\n    {\n        return parent::on($connection);\n    }\n\n    /**\n     * Begin querying the model on the write connection.\n     *\n     * @return TBuilder\n     */\n    public static function onWriteConnection()\n    {\n        return parent::onWriteConnection();\n    }\n\n    /**\n     * Begin querying a model with eager loading.\n     *\n     * @param  array|string  $relations\n     * @return TBuilder\n     */\n    public static function with($relations)\n    {\n        return parent::with($relations);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/HasCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\CollectedBy;\nuse ReflectionClass;\n\n/**\n * @template TCollection of \\Illuminate\\Database\\Eloquent\\Collection\n */\ntrait HasCollection\n{\n    /**\n     * The resolved collection class names by model.\n     *\n     * @var array<class-string<static>, class-string<TCollection>>\n     */\n    protected static array $resolvedCollectionClasses = [];\n\n    /**\n     * Create a new Eloquent Collection instance.\n     *\n     * @param  array<array-key, \\Illuminate\\Database\\Eloquent\\Model>  $models\n     * @return TCollection\n     */\n    public function newCollection(array $models = [])\n    {\n        static::$resolvedCollectionClasses[static::class] ??= ($this->resolveCollectionFromAttribute() ?? static::$collectionClass);\n\n        $collection = new static::$resolvedCollectionClasses[static::class]($models);\n\n        if (Model::isAutomaticallyEagerLoadingRelationships()) {\n            $collection->withRelationshipAutoloading();\n        }\n\n        return $collection;\n    }\n\n    /**\n     * Resolve the collection class name from the CollectedBy attribute.\n     *\n     * @return class-string<TCollection>|null\n     */\n    public function resolveCollectionFromAttribute()\n    {\n        $reflectionClass = new ReflectionClass(static::class);\n\n        $attributes = $reflectionClass->getAttributes(CollectedBy::class);\n\n        if (! isset($attributes[0]) || ! isset($attributes[0]->getArguments()[0])) {\n            return;\n        }\n\n        return $attributes[0]->getArguments()[0];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/HigherOrderBuilderProxy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\n/**\n * @mixin \\Illuminate\\Database\\Eloquent\\Builder\n */\nclass HigherOrderBuilderProxy\n{\n    /**\n     * The collection being operated on.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Builder<*>\n     */\n    protected $builder;\n\n    /**\n     * The method being proxied.\n     *\n     * @var string\n     */\n    protected $method;\n\n    /**\n     * Create a new proxy instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @param  string  $method\n     */\n    public function __construct(Builder $builder, $method)\n    {\n        $this->method = $method;\n        $this->builder = $builder;\n    }\n\n    /**\n     * Proxy a scope call onto the query builder.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->builder->{$this->method}(function ($value) use ($method, $parameters) {\n            return $value->{$method}(...$parameters);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/InvalidCastException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse RuntimeException;\n\nclass InvalidCastException extends RuntimeException\n{\n    /**\n     * The name of the affected Eloquent model.\n     *\n     * @var string\n     */\n    public $model;\n\n    /**\n     * The name of the column.\n     *\n     * @var string\n     */\n    public $column;\n\n    /**\n     * The name of the cast type.\n     *\n     * @var string\n     */\n    public $castType;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  object  $model\n     * @param  string  $column\n     * @param  string  $castType\n     */\n    public function __construct($model, $column, $castType)\n    {\n        $class = get_class($model);\n\n        parent::__construct(\"Call to undefined cast [{$castType}] on column [{$column}] in model [{$class}].\");\n\n        $this->model = $class;\n        $this->column = $column;\n        $this->castType = $castType;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/JsonEncodingException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse RuntimeException;\n\nclass JsonEncodingException extends RuntimeException\n{\n    /**\n     * Create a new JSON encoding exception for the model.\n     *\n     * @param  mixed  $model\n     * @param  string  $message\n     * @return static\n     */\n    public static function forModel($model, $message)\n    {\n        return new static('Error encoding model ['.get_class($model).'] with ID ['.$model->getKey().'] to JSON: '.$message);\n    }\n\n    /**\n     * Create a new JSON encoding exception for the resource.\n     *\n     * @param  \\Illuminate\\Http\\Resources\\Json\\JsonResource  $resource\n     * @param  string  $message\n     * @return static\n     */\n    public static function forResource($resource, $message)\n    {\n        $model = $resource->resource;\n\n        return new static('Error encoding resource ['.get_class($resource).'] with model ['.get_class($model).'] with ID ['.$model->getKey().'] to JSON: '.$message);\n    }\n\n    /**\n     * Create a new JSON encoding exception for an attribute.\n     *\n     * @param  mixed  $model\n     * @param  mixed  $key\n     * @param  string  $message\n     * @return static\n     */\n    public static function forAttribute($model, $key, $message)\n    {\n        $class = get_class($model);\n\n        return new static(\"Unable to encode attribute [{$key}] for model [{$class}] to JSON: {$message}.\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/MassAssignmentException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse RuntimeException;\n\nclass MassAssignmentException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/MassPrunable.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse LogicException;\n\ntrait MassPrunable\n{\n    /**\n     * Prune all prunable models in the database.\n     *\n     * @param  int  $chunkSize\n     * @return int\n     */\n    public function pruneAll(int $chunkSize = 1000)\n    {\n        $query = tap($this->prunable(), function ($query) use ($chunkSize) {\n            $query->when(! $query->getQuery()->limit, function ($query) use ($chunkSize) {\n                $query->limit($chunkSize);\n            });\n        });\n\n        $total = 0;\n\n        $softDeletable = static::isSoftDeletable();\n\n        do {\n            $total += $count = $softDeletable\n                ? $query->forceDelete()\n                : $query->delete();\n\n            if ($count > 0) {\n                event(new ModelsPruned(static::class, $total));\n            }\n        } while ($count > 0);\n\n        return $total;\n    }\n\n    /**\n     * Get the prunable model query.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     *\n     * @throws \\LogicException\n     */\n    public function prunable()\n    {\n        throw new LogicException('Please implement the prunable method on your model.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/MissingAttributeException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse OutOfBoundsException;\n\nclass MissingAttributeException extends OutOfBoundsException\n{\n    /**\n     * Create a new missing attribute exception instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     */\n    public function __construct($model, $key)\n    {\n        parent::__construct(sprintf(\n            'The attribute [%s] either does not exist or was not retrieved for model [%s].',\n            $key, get_class($model)\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Model.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse ArrayAccess;\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel;\nuse Illuminate\\Contracts\\Queue\\QueueableCollection;\nuse Illuminate\\Contracts\\Queue\\QueueableEntity;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Database\\ConnectionResolverInterface as Resolver;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Boot;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Connection;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope as LocalScope;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Table;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseEloquentBuilder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable as SupportStringable;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse JsonException;\nuse JsonSerializable;\nuse LogicException;\nuse ReflectionClass;\nuse ReflectionMethod;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nabstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToString, HasBroadcastChannel, Jsonable, JsonSerializable, QueueableEntity, Stringable, UrlRoutable\n{\n    use Concerns\\HasAttributes,\n        Concerns\\HasEvents,\n        Concerns\\HasGlobalScopes,\n        Concerns\\HasRelationships,\n        Concerns\\HasTimestamps,\n        Concerns\\HasUniqueIds,\n        Concerns\\HidesAttributes,\n        Concerns\\GuardsAttributes,\n        Concerns\\PreventsCircularRecursion,\n        Concerns\\TransformsToResource,\n        ForwardsCalls;\n    /** @use HasCollection<\\Illuminate\\Database\\Eloquent\\Collection<array-key, static & self>> */\n    use HasCollection;\n\n    /**\n     * The connection name for the model.\n     *\n     * @var \\UnitEnum|string|null\n     */\n    protected $connection;\n\n    /**\n     * The table associated with the model.\n     *\n     * @var string|null\n     */\n    protected $table;\n\n    /**\n     * The primary key for the model.\n     *\n     * @var string\n     */\n    protected $primaryKey = 'id';\n\n    /**\n     * The \"type\" of the primary key ID.\n     *\n     * @var string\n     */\n    protected $keyType = 'int';\n\n    /**\n     * Indicates if the IDs are auto-incrementing.\n     *\n     * @var bool\n     */\n    public $incrementing = true;\n\n    /**\n     * The relations to eager load on every query.\n     *\n     * @var array\n     */\n    protected $with = [];\n\n    /**\n     * The relationship counts that should be eager loaded on every query.\n     *\n     * @var array\n     */\n    protected $withCount = [];\n\n    /**\n     * Indicates whether lazy loading will be prevented on this model.\n     *\n     * @var bool\n     */\n    public $preventsLazyLoading = false;\n\n    /**\n     * The number of models to return for pagination.\n     *\n     * @var int\n     */\n    protected $perPage = 15;\n\n    /**\n     * Indicates if the model exists.\n     *\n     * @var bool\n     */\n    public $exists = false;\n\n    /**\n     * Indicates if the model was inserted during the object's lifecycle.\n     *\n     * @var bool\n     */\n    public $wasRecentlyCreated = false;\n\n    /**\n     * Indicates that the object's string representation should be escaped when __toString is invoked.\n     *\n     * @var bool\n     */\n    protected $escapeWhenCastingToString = false;\n\n    /**\n     * The connection resolver instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected static $resolver;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected static $dispatcher;\n\n    /**\n     * The models that are currently being booted.\n     *\n     * @var array\n     */\n    protected static $booting = [];\n\n    /**\n     * The array of booted models.\n     *\n     * @var array\n     */\n    protected static $booted = [];\n\n    /**\n     * The callbacks that should be executed after the model has booted.\n     *\n     * @var array\n     */\n    protected static $bootedCallbacks = [];\n\n    /**\n     * The array of trait initializers that will be called on each new instance.\n     *\n     * @var array\n     */\n    protected static $traitInitializers = [];\n\n    /**\n     * The array of global scopes on the model.\n     *\n     * @var array\n     */\n    protected static $globalScopes = [];\n\n    /**\n     * The list of models classes that should not be affected with touch.\n     *\n     * @var array\n     */\n    protected static $ignoreOnTouch = [];\n\n    /**\n     * Indicates whether lazy loading should be restricted on all models.\n     *\n     * @var bool\n     */\n    protected static $modelsShouldPreventLazyLoading = false;\n\n    /**\n     * Indicates whether relations should be automatically loaded on all models when they are accessed.\n     *\n     * @var bool\n     */\n    protected static $modelsShouldAutomaticallyEagerLoadRelationships = false;\n\n    /**\n     * The callback that is responsible for handling lazy loading violations.\n     *\n     * @var (callable(self, string))|null\n     */\n    protected static $lazyLoadingViolationCallback;\n\n    /**\n     * Indicates if an exception should be thrown instead of silently discarding non-fillable attributes.\n     *\n     * @var bool\n     */\n    protected static $modelsShouldPreventSilentlyDiscardingAttributes = false;\n\n    /**\n     * The callback that is responsible for handling discarded attribute violations.\n     *\n     * @var (callable(self, array))|null\n     */\n    protected static $discardedAttributeViolationCallback;\n\n    /**\n     * Indicates if an exception should be thrown when trying to access a missing attribute on a retrieved model.\n     *\n     * @var bool\n     */\n    protected static $modelsShouldPreventAccessingMissingAttributes = false;\n\n    /**\n     * The callback that is responsible for handling missing attribute violations.\n     *\n     * @var (callable(self, string))|null\n     */\n    protected static $missingAttributeViolationCallback;\n\n    /**\n     * Indicates if broadcasting is currently enabled.\n     *\n     * @var bool\n     */\n    protected static $isBroadcasting = true;\n\n    /**\n     * The Eloquent query builder class to use for the model.\n     *\n     * @var class-string<\\Illuminate\\Database\\Eloquent\\Builder<*>>\n     */\n    protected static string $builder = Builder::class;\n\n    /**\n     * The Eloquent collection class to use for the model.\n     *\n     * @var class-string<\\Illuminate\\Database\\Eloquent\\Collection<*, *>>\n     */\n    protected static string $collectionClass = Collection::class;\n\n    /**\n     * Cache of soft deletable models.\n     *\n     * @var array<class-string<self>, bool>\n     */\n    protected static array $isSoftDeletable;\n\n    /**\n     * Cache of prunable models.\n     *\n     * @var array<class-string<self>, bool>\n     */\n    protected static array $isPrunable;\n\n    /**\n     * Cache of mass prunable models.\n     *\n     * @var array<class-string<self>, bool>\n     */\n    protected static array $isMassPrunable;\n\n    /**\n     * Cache of resolved class attributes.\n     *\n     * @var array<class-string<self>, array<class-string, mixed>>\n     */\n    protected static array $classAttributes = [];\n\n    /**\n     * The name of the \"created at\" column.\n     *\n     * @var string|null\n     */\n    const CREATED_AT = 'created_at';\n\n    /**\n     * The name of the \"updated at\" column.\n     *\n     * @var string|null\n     */\n    const UPDATED_AT = 'updated_at';\n\n    /**\n     * Create a new Eloquent model instance.\n     *\n     * @param  array<string, mixed>  $attributes\n     */\n    public function __construct(array $attributes = [])\n    {\n        $this->bootIfNotBooted();\n        $this->initializeTraits();\n        $this->initializeModelAttributes();\n        $this->syncOriginal();\n        $this->fill($attributes);\n    }\n\n    /**\n     * Check if the model needs to be booted and if so, do it.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    protected function bootIfNotBooted()\n    {\n        if (! isset(static::$booted[static::class])) {\n            if (isset(static::$booting[static::class])) {\n                throw new LogicException('The ['.__METHOD__.'] method may not be called on model ['.static::class.'] while it is being booted.');\n            }\n\n            static::$booting[static::class] = true;\n\n            $this->fireModelEvent('booting', false);\n\n            static::booting();\n            static::boot();\n\n            static::$booted[static::class] = true;\n            unset(static::$booting[static::class]);\n\n            static::booted();\n\n            static::$bootedCallbacks[static::class] ??= [];\n\n            foreach (static::$bootedCallbacks[static::class] as $callback) {\n                $callback();\n            }\n\n            $this->fireModelEvent('booted', false);\n        }\n    }\n\n    /**\n     * Perform any actions required before the model boots.\n     *\n     * @return void\n     */\n    protected static function booting()\n    {\n        //\n    }\n\n    /**\n     * Bootstrap the model and its traits.\n     *\n     * @return void\n     */\n    protected static function boot()\n    {\n        static::bootTraits();\n    }\n\n    /**\n     * Boot all of the bootable traits on the model.\n     *\n     * @return void\n     */\n    protected static function bootTraits()\n    {\n        $class = static::class;\n\n        $booted = [];\n\n        static::$traitInitializers[$class] = [];\n\n        $uses = class_uses_recursive($class);\n\n        $conventionalBootMethods = array_map(static fn ($trait) => 'boot'.class_basename($trait), $uses);\n        $conventionalInitMethods = array_map(static fn ($trait) => 'initialize'.class_basename($trait), $uses);\n\n        foreach ((new ReflectionClass($class))->getMethods() as $method) {\n            if (! in_array($method->getName(), $booted) &&\n                $method->isStatic() &&\n                (in_array($method->getName(), $conventionalBootMethods) ||\n                $method->getAttributes(Boot::class) !== [])) {\n                $method->invoke(null);\n\n                $booted[] = $method->getName();\n            }\n\n            if (in_array($method->getName(), $conventionalInitMethods) ||\n                $method->getAttributes(Initialize::class) !== []) {\n                static::$traitInitializers[$class][] = $method->getName();\n            }\n        }\n\n        static::$traitInitializers[$class] = array_unique(static::$traitInitializers[$class]);\n    }\n\n    /**\n     * Initialize any initializable traits on the model.\n     *\n     * @return void\n     */\n    protected function initializeTraits()\n    {\n        foreach (static::$traitInitializers[static::class] as $method) {\n            $this->{$method}();\n        }\n    }\n\n    /**\n     * Initialize the model attributes from class attributes.\n     *\n     * @return void\n     */\n    public function initializeModelAttributes()\n    {\n        $table = static::resolveClassAttribute(Table::class);\n\n        $this->table ??= $table->name ?? null;\n        $this->connection ??= static::resolveClassAttribute(Connection::class, 'name');\n\n        if ($this->primaryKey === 'id' && $table && $table->key !== null) {\n            $this->primaryKey = $table->key;\n        }\n\n        if ($this->keyType === 'int' && $table && $table->keyType !== null) {\n            $this->keyType = $table->keyType;\n        }\n\n        if ($this->incrementing === true && $table && $table->incrementing !== null) {\n            $this->incrementing = $table->incrementing;\n        }\n    }\n\n    /**\n     * Perform any actions required after the model boots.\n     *\n     * @return void\n     */\n    protected static function booted()\n    {\n        //\n    }\n\n    /**\n     * Register a closure to be executed after the model has booted.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    protected static function whenBooted(Closure $callback)\n    {\n        static::$bootedCallbacks[static::class] ??= [];\n\n        static::$bootedCallbacks[static::class][] = $callback;\n    }\n\n    /**\n     * Clear the list of booted models so they will be re-booted.\n     *\n     * @return void\n     */\n    public static function clearBootedModels()\n    {\n        static::$booted = [];\n        static::$bootedCallbacks = [];\n        static::$classAttributes = [];\n        static::$globalScopes = [];\n    }\n\n    /**\n     * Disables relationship model touching for the current class during given callback scope.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function withoutTouching(callable $callback)\n    {\n        static::withoutTouchingOn([static::class], $callback);\n    }\n\n    /**\n     * Disables relationship model touching for the given model classes during given callback scope.\n     *\n     * @param  array  $models\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function withoutTouchingOn(array $models, callable $callback)\n    {\n        static::$ignoreOnTouch = array_values(array_merge(static::$ignoreOnTouch, $models));\n\n        try {\n            $callback();\n        } finally {\n            static::$ignoreOnTouch = array_values(array_diff(static::$ignoreOnTouch, $models));\n        }\n    }\n\n    /**\n     * Determine if the given model is ignoring touches.\n     *\n     * @param  string|null  $class\n     * @return bool\n     */\n    public static function isIgnoringTouch($class = null)\n    {\n        $class = $class ?: static::class;\n\n        if (! $class::UPDATED_AT) {\n            return true;\n        }\n\n        $timestamps = static::resolveClassAttribute(Table::class, 'timestamps', $class)\n            ?? get_class_vars($class)['timestamps'];\n\n        if (! $timestamps) {\n            return true;\n        }\n\n        foreach (static::$ignoreOnTouch as $ignoredClass) {\n            if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Indicate that models should prevent lazy loading, silently discarding attributes, and accessing missing attributes.\n     *\n     * @param  bool  $shouldBeStrict\n     * @return void\n     */\n    public static function shouldBeStrict(bool $shouldBeStrict = true)\n    {\n        static::preventLazyLoading($shouldBeStrict);\n        static::preventSilentlyDiscardingAttributes($shouldBeStrict);\n        static::preventAccessingMissingAttributes($shouldBeStrict);\n    }\n\n    /**\n     * Prevent model relationships from being lazy loaded.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public static function preventLazyLoading($value = true)\n    {\n        static::$modelsShouldPreventLazyLoading = $value;\n    }\n\n    /**\n     * Determine if model relationships should be automatically eager loaded when accessed.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public static function automaticallyEagerLoadRelationships($value = true)\n    {\n        static::$modelsShouldAutomaticallyEagerLoadRelationships = $value;\n    }\n\n    /**\n     * Register a callback that is responsible for handling lazy loading violations.\n     *\n     * @param  (callable(self, string))|null  $callback\n     * @return void\n     */\n    public static function handleLazyLoadingViolationUsing(?callable $callback)\n    {\n        static::$lazyLoadingViolationCallback = $callback;\n    }\n\n    /**\n     * Prevent non-fillable attributes from being silently discarded.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public static function preventSilentlyDiscardingAttributes($value = true)\n    {\n        static::$modelsShouldPreventSilentlyDiscardingAttributes = $value;\n    }\n\n    /**\n     * Register a callback that is responsible for handling discarded attribute violations.\n     *\n     * @param  (callable(self, array))|null  $callback\n     * @return void\n     */\n    public static function handleDiscardedAttributeViolationUsing(?callable $callback)\n    {\n        static::$discardedAttributeViolationCallback = $callback;\n    }\n\n    /**\n     * Prevent accessing missing attributes on retrieved models.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public static function preventAccessingMissingAttributes($value = true)\n    {\n        static::$modelsShouldPreventAccessingMissingAttributes = $value;\n    }\n\n    /**\n     * Register a callback that is responsible for handling missing attribute violations.\n     *\n     * @param  (callable(self, string))|null  $callback\n     * @return void\n     */\n    public static function handleMissingAttributeViolationUsing(?callable $callback)\n    {\n        static::$missingAttributeViolationCallback = $callback;\n    }\n\n    /**\n     * Execute a callback without broadcasting any model events for all model types.\n     *\n     * @param  callable  $callback\n     * @return mixed\n     */\n    public static function withoutBroadcasting(callable $callback)\n    {\n        $isBroadcasting = static::$isBroadcasting;\n\n        static::$isBroadcasting = false;\n\n        try {\n            return $callback();\n        } finally {\n            static::$isBroadcasting = $isBroadcasting;\n        }\n    }\n\n    /**\n     * Fill the model with an array of attributes.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @return $this\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\MassAssignmentException\n     */\n    public function fill(array $attributes)\n    {\n        $totallyGuarded = $this->totallyGuarded();\n\n        $fillable = $this->fillableFromArray($attributes);\n\n        foreach ($fillable as $key => $value) {\n            // The developers may choose to place some attributes in the \"fillable\" array\n            // which means only those attributes may be set through mass assignment to\n            // the model, and all others will just get ignored for security reasons.\n            if ($this->isFillable($key)) {\n                $this->setAttribute($key, $value);\n            } elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) {\n                if (isset(static::$discardedAttributeViolationCallback)) {\n                    call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]);\n                } else {\n                    throw new MassAssignmentException(sprintf(\n                        'Add [%s] to fillable property to allow mass assignment on [%s].',\n                        $key, get_class($this)\n                    ));\n                }\n            }\n        }\n\n        if (count($attributes) !== count($fillable) &&\n            static::preventsSilentlyDiscardingAttributes()) {\n            $keys = array_diff(array_keys($attributes), array_keys($fillable));\n\n            if (isset(static::$discardedAttributeViolationCallback)) {\n                call_user_func(static::$discardedAttributeViolationCallback, $this, $keys);\n            } else {\n                throw new MassAssignmentException(sprintf(\n                    'Add fillable property [%s] to allow mass assignment on [%s].',\n                    implode(', ', $keys),\n                    get_class($this)\n                ));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Fill the model with an array of attributes. Force mass assignment.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @return $this\n     */\n    public function forceFill(array $attributes)\n    {\n        return static::unguarded(fn () => $this->fill($attributes));\n    }\n\n    /**\n     * Qualify the given column name by the model's table.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    public function qualifyColumn($column)\n    {\n        if (str_contains($column, '.')) {\n            return $column;\n        }\n\n        return $this->getTable().'.'.$column;\n    }\n\n    /**\n     * Qualify the given columns with the model's table.\n     *\n     * @param  array  $columns\n     * @return array\n     */\n    public function qualifyColumns($columns)\n    {\n        return (new BaseCollection($columns))\n            ->map(fn ($column) => $this->qualifyColumn($column))\n            ->all();\n    }\n\n    /**\n     * Create a new instance of the given model.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  bool  $exists\n     * @return static\n     */\n    public function newInstance($attributes = [], $exists = false)\n    {\n        // This method just provides a convenient way for us to generate fresh model\n        // instances of this current model. It is particularly useful during the\n        // hydration of new objects via the Eloquent query builder instances.\n        $model = new static;\n\n        $model->exists = $exists;\n\n        $model->setConnection(\n            $this->getConnectionName()\n        );\n\n        $model->setTable($this->getTable());\n\n        $model->mergeCasts($this->casts);\n\n        $model->fill((array) $attributes);\n\n        return $model;\n    }\n\n    /**\n     * Create a new model instance that is existing.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  \\UnitEnum|string|null  $connection\n     * @return static\n     */\n    public function newFromBuilder($attributes = [], $connection = null)\n    {\n        $model = $this->newInstance([], true);\n\n        $model->setRawAttributes((array) $attributes, true);\n\n        $model->setConnection($connection ?? $this->getConnectionName());\n\n        $model->fireModelEvent('retrieved', false);\n\n        return $model;\n    }\n\n    /**\n     * Begin querying the model on a given connection.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public static function on($connection = null)\n    {\n        // First we will just create a fresh instance of this model, and then we can set the\n        // connection on the model so that it is used for the queries we execute, as well\n        // as being set on every relation we retrieve without a custom connection name.\n        return (new static)->setConnection($connection)->newQuery();\n    }\n\n    /**\n     * Begin querying the model on the write connection.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public static function onWriteConnection()\n    {\n        return static::query()->useWritePdo();\n    }\n\n    /**\n     * Get all of the models from the database.\n     *\n     * @param  array|string  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, static>\n     */\n    public static function all($columns = ['*'])\n    {\n        return static::query()->get(\n            is_array($columns) ? $columns : func_get_args()\n        );\n    }\n\n    /**\n     * Begin querying a model with eager loading.\n     *\n     * @param  array|string  $relations\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public static function with($relations)\n    {\n        return static::query()->with(\n            is_string($relations) ? func_get_args() : $relations\n        );\n    }\n\n    /**\n     * Eager load relations on the model.\n     *\n     * @param  array|string  $relations\n     * @return $this\n     */\n    public function load($relations)\n    {\n        $query = $this->newQueryWithoutRelationships()->with(\n            is_string($relations) ? func_get_args() : $relations\n        );\n\n        $query->eagerLoadRelations([$this]);\n\n        return $this;\n    }\n\n    /**\n     * Eager load relationships on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorph($relation, $relations)\n    {\n        if (! $this->{$relation}) {\n            return $this;\n        }\n\n        $className = get_class($this->{$relation});\n\n        $this->{$relation}->load($relations[$className] ?? []);\n\n        return $this;\n    }\n\n    /**\n     * Eager load relations on the model if they are not already eager loaded.\n     *\n     * @param  array|string  $relations\n     * @return $this\n     */\n    public function loadMissing($relations)\n    {\n        $relations = is_string($relations) ? func_get_args() : $relations;\n\n        $this->newCollection([$this])->loadMissing($relations);\n\n        return $this;\n    }\n\n    /**\n     * Eager load relation's column aggregations on the model.\n     *\n     * @param  array|string  $relations\n     * @param  string  $column\n     * @param  string|null  $function\n     * @return $this\n     */\n    public function loadAggregate($relations, $column, $function = null)\n    {\n        $this->newCollection([$this])->loadAggregate($relations, $column, $function);\n\n        return $this;\n    }\n\n    /**\n     * Eager load relation counts on the model.\n     *\n     * @param  array|string  $relations\n     * @return $this\n     */\n    public function loadCount($relations)\n    {\n        $relations = is_string($relations) ? func_get_args() : $relations;\n\n        return $this->loadAggregate($relations, '*', 'count');\n    }\n\n    /**\n     * Eager load relation max column values on the model.\n     *\n     * @param  array|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMax($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'max');\n    }\n\n    /**\n     * Eager load relation min column values on the model.\n     *\n     * @param  array|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMin($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'min');\n    }\n\n    /**\n     * Eager load relation's column summations on the model.\n     *\n     * @param  array|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadSum($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'sum');\n    }\n\n    /**\n     * Eager load relation average column values on the model.\n     *\n     * @param  array|string  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadAvg($relations, $column)\n    {\n        return $this->loadAggregate($relations, $column, 'avg');\n    }\n\n    /**\n     * Eager load related model existence values on the model.\n     *\n     * @param  array|string  $relations\n     * @return $this\n     */\n    public function loadExists($relations)\n    {\n        return $this->loadAggregate($relations, '*', 'exists');\n    }\n\n    /**\n     * Eager load relationship column aggregation on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @param  string  $column\n     * @param  string|null  $function\n     * @return $this\n     */\n    public function loadMorphAggregate($relation, $relations, $column, $function = null)\n    {\n        if (! $this->{$relation}) {\n            return $this;\n        }\n\n        $className = get_class($this->{$relation});\n\n        $this->{$relation}->loadAggregate($relations[$className] ?? [], $column, $function);\n\n        return $this;\n    }\n\n    /**\n     * Eager load relationship counts on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorphCount($relation, $relations)\n    {\n        return $this->loadMorphAggregate($relation, $relations, '*', 'count');\n    }\n\n    /**\n     * Eager load relationship max column values on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMorphMax($relation, $relations, $column)\n    {\n        return $this->loadMorphAggregate($relation, $relations, $column, 'max');\n    }\n\n    /**\n     * Eager load relationship min column values on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMorphMin($relation, $relations, $column)\n    {\n        return $this->loadMorphAggregate($relation, $relations, $column, 'min');\n    }\n\n    /**\n     * Eager load relationship column summations on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMorphSum($relation, $relations, $column)\n    {\n        return $this->loadMorphAggregate($relation, $relations, $column, 'sum');\n    }\n\n    /**\n     * Eager load relationship average column values on the polymorphic relation of a model.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @param  string  $column\n     * @return $this\n     */\n    public function loadMorphAvg($relation, $relations, $column)\n    {\n        return $this->loadMorphAggregate($relation, $relations, $column, 'avg');\n    }\n\n    /**\n     * Increment a column's value by a given amount.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    protected function increment($column, $amount = 1, array $extra = [])\n    {\n        return $this->incrementOrDecrement($column, $amount, $extra, 'increment');\n    }\n\n    /**\n     * Decrement a column's value by a given amount.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    protected function decrement($column, $amount = 1, array $extra = [])\n    {\n        return $this->incrementOrDecrement($column, $amount, $extra, 'decrement');\n    }\n\n    /**\n     * Run the increment or decrement method on the model.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @param  string  $method\n     * @return int\n     */\n    protected function incrementOrDecrement($column, $amount, $extra, $method)\n    {\n        if (! $this->exists) {\n            return $this->newQueryWithoutRelationships()->{$method}($column, $amount, $extra);\n        }\n\n        $this->{$column} = $this->isClassDeviable($column)\n            ? $this->deviateClassCastableAttribute($method, $column, $amount)\n            : $this->{$column} + ($method === 'increment' ? $amount : $amount * -1);\n\n        $this->forceFill($extra);\n\n        if ($this->fireModelEvent('updating') === false) {\n            return false;\n        }\n\n        if ($this->isClassDeviable($column)) {\n            $amount = (clone $this)->setAttribute($column, $amount)->getAttributeFromArray($column);\n        }\n\n        return tap($this->setKeysForSaveQuery($this->newQueryWithoutScopes())->{$method}($column, $amount, $extra), function () use ($column) {\n            $this->syncChanges();\n\n            $this->fireModelEvent('updated', false);\n\n            $this->syncOriginalAttribute($column);\n        });\n    }\n\n    /**\n     * Update the model in the database.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  array<string, mixed>  $options\n     * @return bool\n     */\n    public function update(array $attributes = [], array $options = [])\n    {\n        if (! $this->exists) {\n            return false;\n        }\n\n        return $this->fill($attributes)->save($options);\n    }\n\n    /**\n     * Update the model in the database within a transaction.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  array<string, mixed>  $options\n     * @return bool\n     *\n     * @throws \\Throwable\n     */\n    public function updateOrFail(array $attributes = [], array $options = [])\n    {\n        if (! $this->exists) {\n            return false;\n        }\n\n        return $this->fill($attributes)->saveOrFail($options);\n    }\n\n    /**\n     * Update the model in the database without raising any events.\n     *\n     * @param  array<string, mixed>  $attributes\n     * @param  array<string, mixed>  $options\n     * @return bool\n     */\n    public function updateQuietly(array $attributes = [], array $options = [])\n    {\n        if (! $this->exists) {\n            return false;\n        }\n\n        return $this->fill($attributes)->saveQuietly($options);\n    }\n\n    /**\n     * Increment a column's value by a given amount without raising any events.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    protected function incrementQuietly($column, $amount = 1, array $extra = [])\n    {\n        return static::withoutEvents(\n            fn () => $this->incrementOrDecrement($column, $amount, $extra, 'increment')\n        );\n    }\n\n    /**\n     * Decrement a column's value by a given amount without raising any events.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @param  array  $extra\n     * @return int\n     */\n    protected function decrementQuietly($column, $amount = 1, array $extra = [])\n    {\n        return static::withoutEvents(\n            fn () => $this->incrementOrDecrement($column, $amount, $extra, 'decrement')\n        );\n    }\n\n    /**\n     * Save the model and all of its relationships.\n     *\n     * @return bool\n     */\n    public function push()\n    {\n        return $this->withoutRecursion(function () {\n            if (! $this->save()) {\n                return false;\n            }\n\n            // To sync all of the relationships to the database, we will simply spin through\n            // the relationships and save each model via this \"push\" method, which allows\n            // us to recurse into all of these nested relations for the model instance.\n            foreach ($this->relations as $models) {\n                $models = $models instanceof Collection\n                    ? $models->all()\n                    : [$models];\n\n                foreach (array_filter($models) as $model) {\n                    if (! $model->push()) {\n                        return false;\n                    }\n                }\n            }\n\n            return true;\n        }, true);\n    }\n\n    /**\n     * Save the model and all of its relationships without raising any events to the parent model.\n     *\n     * @return bool\n     */\n    public function pushQuietly()\n    {\n        return static::withoutEvents(fn () => $this->push());\n    }\n\n    /**\n     * Save the model to the database without raising any events.\n     *\n     * @param  array  $options\n     * @return bool\n     */\n    public function saveQuietly(array $options = [])\n    {\n        return static::withoutEvents(fn () => $this->save($options));\n    }\n\n    /**\n     * Save the model to the database.\n     *\n     * @param  array  $options\n     * @return bool\n     */\n    public function save(array $options = [])\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        $query = $this->newModelQuery();\n\n        // If the \"saving\" event returns false we'll bail out of the save and return\n        // false, indicating that the save failed. This provides a chance for any\n        // listeners to cancel save operations if validations fail or whatever.\n        if ($this->fireModelEvent('saving') === false) {\n            return false;\n        }\n\n        // If the model already exists in the database we can just update our record\n        // that is already in this database using the current IDs in this \"where\"\n        // clause to only update this model. Otherwise, we'll just insert them.\n        if ($this->exists) {\n            $saved = $this->isDirty() ?\n                $this->performUpdate($query) : true;\n        }\n\n        // If the model is brand new, we'll insert it into our database and set the\n        // ID attribute on the model to the value of the newly inserted row's ID\n        // which is typically an auto-increment value managed by the database.\n        else {\n            $saved = $this->performInsert($query);\n\n            if (! $this->getConnectionName() &&\n                $connection = $query->getConnection()) {\n                $this->setConnection($connection->getName());\n            }\n        }\n\n        // If the model is successfully saved, we need to do a few more things once\n        // that is done. We will call the \"saved\" method here to run any actions\n        // we need to happen after a model gets successfully saved right here.\n        if ($saved) {\n            $this->finishSave($options);\n        }\n\n        return $saved;\n    }\n\n    /**\n     * Save the model to the database, ignoring specific unique constraint conflicts.\n     *\n     * @param  array  $options\n     * @param  array|string|null  $uniqueBy\n     * @return bool\n     */\n    public function saveOrIgnore(array $options = [], array|string|null $uniqueBy = null)\n    {\n        if ($this->exists) {\n            throw new LogicException('Cannot use saveOrIgnore on an existing model.');\n        }\n\n        $this->mergeAttributesFromCachedCasts();\n\n        $query = $this->newModelQuery();\n\n        if ($this->fireModelEvent('saving') === false) {\n            return false;\n        }\n\n        $saved = $this->performInsertOrIgnore($query, $uniqueBy);\n\n        if (! $this->getConnectionName() &&\n            $connection = $query->getConnection()) {\n            $this->setConnection($connection->getName());\n        }\n\n        if ($saved) {\n            $this->finishSave($options);\n        }\n\n        return $saved;\n    }\n\n    /**\n     * Save the model to the database within a transaction.\n     *\n     * @param  array  $options\n     * @return bool\n     *\n     * @throws \\Throwable\n     */\n    public function saveOrFail(array $options = [])\n    {\n        return $this->getConnection()->transaction(fn () => $this->save($options));\n    }\n\n    /**\n     * Perform any actions that are necessary after the model is saved.\n     *\n     * @param  array  $options\n     * @return void\n     */\n    protected function finishSave(array $options)\n    {\n        $this->fireModelEvent('saved', false);\n\n        if ($this->isDirty() && ($options['touch'] ?? true)) {\n            $this->touchOwners();\n        }\n\n        $this->syncOriginal();\n    }\n\n    /**\n     * Perform a model update operation.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return bool\n     */\n    protected function performUpdate(Builder $query)\n    {\n        // If the updating event returns false, we will cancel the update operation so\n        // developers can hook Validation systems into their models and cancel this\n        // operation if the model does not pass validation. Otherwise, we update.\n        if ($this->fireModelEvent('updating') === false) {\n            return false;\n        }\n\n        // First we need to create a fresh query instance and touch the creation and\n        // update timestamp on the model which are maintained by us for developer\n        // convenience. Then we will just continue saving the model instances.\n        if ($this->usesTimestamps()) {\n            $this->updateTimestamps();\n        }\n\n        // Once we have run the update operation, we will fire the \"updated\" event for\n        // this model instance. This will allow developers to hook into these after\n        // models are updated, giving them a chance to do any special processing.\n        $dirty = $this->getDirtyForUpdate();\n\n        if (count($dirty) > 0) {\n            $this->setKeysForSaveQuery($query)->update($dirty);\n\n            $this->syncChanges();\n\n            $this->fireModelEvent('updated', false);\n        }\n\n        return true;\n    }\n\n    /**\n     * Set the keys for a select query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSelectQuery($query)\n    {\n        $query->where($this->getKeyName(), '=', $this->getKeyForSelectQuery());\n\n        return $query;\n    }\n\n    /**\n     * Get the primary key value for a select query.\n     *\n     * @return mixed\n     */\n    protected function getKeyForSelectQuery()\n    {\n        return $this->original[$this->getKeyName()] ?? $this->getKey();\n    }\n\n    /**\n     * Set the keys for a save update query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSaveQuery($query)\n    {\n        $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());\n\n        return $query;\n    }\n\n    /**\n     * Get the primary key value for a save query.\n     *\n     * @return mixed\n     */\n    protected function getKeyForSaveQuery()\n    {\n        return $this->original[$this->getKeyName()] ?? $this->getKey();\n    }\n\n    /**\n     * Perform a model insert operation.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return bool\n     */\n    protected function performInsert(Builder $query)\n    {\n        if ($this->usesUniqueIds()) {\n            $this->setUniqueIds();\n        }\n\n        if ($this->fireModelEvent('creating') === false) {\n            return false;\n        }\n\n        // First we'll need to create a fresh query instance and touch the creation and\n        // update timestamps on this model, which are maintained by us for developer\n        // convenience. After, we will just continue saving these model instances.\n        if ($this->usesTimestamps()) {\n            $this->updateTimestamps();\n        }\n\n        // If the model has an incrementing key, we can use the \"insertGetId\" method on\n        // the query builder, which will give us back the final inserted ID for this\n        // table from the database. Not all tables have to be incrementing though.\n        $attributes = $this->getAttributesForInsert();\n\n        if ($this->getIncrementing()) {\n            $this->insertAndSetId($query, $attributes);\n        }\n\n        // If the table isn't incrementing we'll simply insert these attributes as they\n        // are. These attribute arrays must contain an \"id\" column previously placed\n        // there by the developer as the manually determined key for these models.\n        else {\n            if (empty($attributes)) {\n                return true;\n            }\n\n            $query->insert($attributes);\n        }\n\n        // We will go ahead and set the exists property to true, so that it is set when\n        // the created event is fired, just in case the developer tries to update it\n        // during the event. This will allow them to do so and run an update here.\n        $this->exists = true;\n\n        $this->wasRecentlyCreated = true;\n\n        $this->fireModelEvent('created', false);\n\n        return true;\n    }\n\n    /**\n     * Perform a model insert operation, ignoring specific unique constraint conflicts.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @param  array|string|null  $uniqueBy\n     * @return bool\n     */\n    protected function performInsertOrIgnore(Builder $query, array|string|null $uniqueBy)\n    {\n        if ($this->usesUniqueIds()) {\n            $this->setUniqueIds();\n        }\n\n        if ($this->fireModelEvent('creating') === false) {\n            return false;\n        }\n\n        if ($this->usesTimestamps()) {\n            $this->updateTimestamps();\n        }\n\n        $attributes = $this->getAttributesForInsert();\n\n        if (empty($attributes)) {\n            return true;\n        }\n\n        $result = $query->toBase()->insertOrIgnoreReturning($attributes, ['*'], $uniqueBy);\n\n        if ($result->isEmpty()) {\n            return false;\n        }\n\n        if ($this->getIncrementing()) {\n            $this->setAttribute(\n                $keyName = $this->getKeyName(),\n                $result->first()->{$keyName}\n            );\n        }\n\n        $this->exists = true;\n\n        $this->wasRecentlyCreated = true;\n\n        $this->fireModelEvent('created', false);\n\n        return true;\n    }\n\n    /**\n     * Insert the given attributes and set the ID on the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @param  array<string, mixed>  $attributes\n     * @return void\n     */\n    protected function insertAndSetId(Builder $query, $attributes)\n    {\n        $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());\n\n        $this->setAttribute($keyName, $id);\n    }\n\n    /**\n     * Destroy the models for the given IDs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|int|string  $ids\n     * @return int\n     */\n    public static function destroy($ids)\n    {\n        if ($ids instanceof EloquentCollection) {\n            $ids = $ids->modelKeys();\n        }\n\n        if ($ids instanceof BaseCollection) {\n            $ids = $ids->all();\n        }\n\n        $ids = is_array($ids) ? $ids : func_get_args();\n\n        if (count($ids) === 0) {\n            return 0;\n        }\n\n        // We will actually pull the models from the database table and call delete on\n        // each of them individually so that their events get fired properly with a\n        // correct set of attributes in case the developers wants to check these.\n        $key = ($instance = new static)->getKeyName();\n\n        $count = 0;\n\n        foreach ($instance->whereIn($key, $ids)->get() as $model) {\n            if ($model->delete()) {\n                $count++;\n            }\n        }\n\n        return $count;\n    }\n\n    /**\n     * Delete the model from the database.\n     *\n     * @return bool|null\n     *\n     * @throws \\LogicException\n     */\n    public function delete()\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        if (is_null($this->getKeyName())) {\n            throw new LogicException('No primary key defined on model.');\n        }\n\n        // If the model doesn't exist, there is nothing to delete so we'll just return\n        // immediately and not do anything else. Otherwise, we will continue with a\n        // deletion process on the model, firing the proper events, and so forth.\n        if (! $this->exists) {\n            return;\n        }\n\n        if ($this->fireModelEvent('deleting') === false) {\n            return false;\n        }\n\n        // Here, we'll touch the owning models, verifying these timestamps get updated\n        // for the models. This will allow any caching to get broken on the parents\n        // by the timestamp. Then we will go ahead and delete the model instance.\n        $this->touchOwners();\n\n        $this->performDeleteOnModel();\n\n        // Once the model has been deleted, we will fire off the deleted event so that\n        // the developers may hook into post-delete operations. We will then return\n        // a boolean true as the delete is presumably successful on the database.\n        $this->fireModelEvent('deleted', false);\n\n        return true;\n    }\n\n    /**\n     * Delete the model from the database without raising any events.\n     *\n     * @return bool\n     */\n    public function deleteQuietly()\n    {\n        return static::withoutEvents(fn () => $this->delete());\n    }\n\n    /**\n     * Delete the model from the database within a transaction.\n     *\n     * @return bool|null\n     *\n     * @throws \\Throwable\n     */\n    public function deleteOrFail()\n    {\n        if (! $this->exists) {\n            return false;\n        }\n\n        return $this->getConnection()->transaction(fn () => $this->delete());\n    }\n\n    /**\n     * Force a hard delete on a soft deleted model.\n     *\n     * This method protects developers from running forceDelete when the trait is missing.\n     *\n     * @return bool|null\n     */\n    public function forceDelete()\n    {\n        return $this->delete();\n    }\n\n    /**\n     * Force a hard destroy on a soft deleted model.\n     *\n     * This method protects developers from running forceDestroy when the trait is missing.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|int|string  $ids\n     * @return bool|null\n     */\n    public static function forceDestroy($ids)\n    {\n        return static::destroy($ids);\n    }\n\n    /**\n     * Perform the actual delete query on this model instance.\n     *\n     * @return void\n     */\n    protected function performDeleteOnModel()\n    {\n        $this->setKeysForSaveQuery($this->newModelQuery())->delete();\n\n        $this->exists = false;\n    }\n\n    /**\n     * Begin querying the model.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public static function query()\n    {\n        return (new static)->newQuery();\n    }\n\n    /**\n     * Get a new query builder for the model's table.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQuery()\n    {\n        return $this->registerGlobalScopes($this->newQueryWithoutScopes());\n    }\n\n    /**\n     * Get a new query builder that doesn't have any global scopes or eager loading.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newModelQuery()\n    {\n        return $this->newEloquentBuilder(\n            $this->newBaseQueryBuilder()\n        )->setModel($this);\n    }\n\n    /**\n     * Get a new query builder with no relationships loaded.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryWithoutRelationships()\n    {\n        return $this->registerGlobalScopes($this->newModelQuery());\n    }\n\n    /**\n     * Register the global scopes for this builder instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $builder\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function registerGlobalScopes($builder)\n    {\n        foreach ($this->getGlobalScopes() as $identifier => $scope) {\n            $builder->withGlobalScope($identifier, $scope);\n        }\n\n        return $builder;\n    }\n\n    /**\n     * Get a new query builder that doesn't have any global scopes.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryWithoutScopes()\n    {\n        return $this->newModelQuery()\n            ->with($this->with)\n            ->withCount($this->withCount);\n    }\n\n    /**\n     * Get a new query instance without a given scope.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Scope|string  $scope\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryWithoutScope($scope)\n    {\n        return $this->newQuery()->withoutGlobalScope($scope);\n    }\n\n    /**\n     * Get a new query to restore one or more models by their queueable IDs.\n     *\n     * @param  array|int  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryForRestoration($ids)\n    {\n        return $this->newQueryWithoutScopes()->whereKey($ids);\n    }\n\n    /**\n     * Create a new Eloquent query builder for the model.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<*>\n     */\n    public function newEloquentBuilder($query)\n    {\n        $builderClass = $this->resolveCustomBuilderClass();\n\n        if ($builderClass && is_subclass_of($builderClass, Builder::class)) {\n            return new $builderClass($query);\n        }\n\n        return new static::$builder($query);\n    }\n\n    /**\n     * Resolve the custom Eloquent builder class from the model attributes.\n     *\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Builder>|false\n     */\n    protected function resolveCustomBuilderClass()\n    {\n        $attributes = (new ReflectionClass($this))\n            ->getAttributes(UseEloquentBuilder::class);\n\n        return ! empty($attributes)\n            ? $attributes[0]->newInstance()->builderClass\n            : false;\n    }\n\n    /**\n     * Get a new query builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function newBaseQueryBuilder()\n    {\n        return $this->getConnection()->query();\n    }\n\n    /**\n     * Create a new pivot model instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @param  array<string, mixed>  $attributes\n     * @param  string  $table\n     * @param  bool  $exists\n     * @param  string|null  $using\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Pivot\n     */\n    public function newPivot(self $parent, array $attributes, $table, $exists, $using = null)\n    {\n        return $using ? $using::fromRawAttributes($parent, $attributes, $table, $exists)\n            : Pivot::fromAttributes($parent, $attributes, $table, $exists);\n    }\n\n    /**\n     * Determine if the model has a given scope.\n     *\n     * @param  string  $scope\n     * @return bool\n     */\n    public function hasNamedScope($scope)\n    {\n        return method_exists($this, 'scope'.ucfirst($scope)) ||\n            static::isScopeMethodWithAttribute($scope);\n    }\n\n    /**\n     * Apply the given named scope if possible.\n     *\n     * @param  string  $scope\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function callNamedScope($scope, array $parameters = [])\n    {\n        if ($this->isScopeMethodWithAttribute($scope)) {\n            return $this->{$scope}(...$parameters);\n        }\n\n        return $this->{'scope'.ucfirst($scope)}(...$parameters);\n    }\n\n    /**\n     * Determine if the given method has a scope attribute.\n     *\n     * @param  string  $method\n     * @return bool\n     */\n    protected static function isScopeMethodWithAttribute(string $method)\n    {\n        return method_exists(static::class, $method) &&\n            (new ReflectionMethod(static::class, $method))\n                ->getAttributes(LocalScope::class) !== [];\n    }\n\n    /**\n     * Convert the model instance to an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->withoutRecursion(\n            fn () => array_merge($this->attributesToArray(), $this->relationsToArray()),\n            fn () => $this->attributesToArray(),\n        );\n    }\n\n    /**\n     * Convert the model instance to JSON.\n     *\n     * @param  int  $options\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\JsonEncodingException\n     */\n    public function toJson($options = 0)\n    {\n        try {\n            $json = json_encode($this->jsonSerialize(), $options | JSON_THROW_ON_ERROR);\n        } catch (JsonException $e) {\n            throw JsonEncodingException::forModel($this, $e->getMessage());\n        }\n\n        return $json;\n    }\n\n    /**\n     * Convert the model instance to pretty print formatted JSON.\n     *\n     * @param  int  $options\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\JsonEncodingException\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return mixed\n     */\n    public function jsonSerialize(): mixed\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Reload a fresh model instance from the database.\n     *\n     * @param  array|string  $with\n     * @return static|null\n     */\n    public function fresh($with = [])\n    {\n        if (! $this->exists) {\n            return;\n        }\n\n        return $this->setKeysForSelectQuery($this->newQueryWithoutScopes())\n            ->useWritePdo()\n            ->with(is_string($with) ? func_get_args() : $with)\n            ->first();\n    }\n\n    /**\n     * Reload the current model instance with fresh attributes from the database.\n     *\n     * @return $this\n     */\n    public function refresh()\n    {\n        if (! $this->exists) {\n            return $this;\n        }\n\n        $this->setRawAttributes(\n            $this->setKeysForSelectQuery($this->newQueryWithoutScopes())\n                ->useWritePdo()\n                ->firstOrFail()\n                ->attributes\n        );\n\n        $this->load((new BaseCollection($this->relations))->reject(\n            fn ($relation) => $relation instanceof Pivot\n                || (is_object($relation) && in_array(AsPivot::class, class_uses_recursive($relation), true))\n        )->keys()->all());\n\n        $this->syncOriginal();\n\n        return $this;\n    }\n\n    /**\n     * Clone the model into a new, non-existing instance.\n     *\n     * @param  array|null  $except\n     * @return static\n     */\n    public function replicate(?array $except = null)\n    {\n        $defaults = array_values(array_filter([\n            $this->getKeyName(),\n            $this->getCreatedAtColumn(),\n            $this->getUpdatedAtColumn(),\n            ...$this->uniqueIds(),\n            'laravel_through_key',\n        ]));\n\n        $attributes = Arr::except(\n            $this->getAttributes(), $except ? array_unique(array_merge($except, $defaults)) : $defaults\n        );\n\n        return tap(new static, function ($instance) use ($attributes) {\n            $instance->setRawAttributes($attributes);\n\n            $instance->setRelations($this->relations);\n\n            $instance->fireModelEvent('replicating', false);\n        });\n    }\n\n    /**\n     * Clone the model into a new, non-existing instance without raising any events.\n     *\n     * @param  array|null  $except\n     * @return static\n     */\n    public function replicateQuietly(?array $except = null)\n    {\n        return static::withoutEvents(fn () => $this->replicate($except));\n    }\n\n    /**\n     * Determine if two models have the same ID and belong to the same table.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $model\n     * @return bool\n     */\n    public function is($model)\n    {\n        return ! is_null($model) &&\n            $this->getKey() === $model->getKey() &&\n            $this->getTable() === $model->getTable() &&\n            $this->getConnectionName() === $model->getConnectionName();\n    }\n\n    /**\n     * Determine if two models are not the same.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $model\n     * @return bool\n     */\n    public function isNot($model)\n    {\n        return ! $this->is($model);\n    }\n\n    /**\n     * Get the database connection for the model.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getConnection()\n    {\n        return static::resolveConnection($this->getConnectionName());\n    }\n\n    /**\n     * Get the current connection name for the model.\n     *\n     * @return string|null\n     */\n    public function getConnectionName()\n    {\n        return enum_value($this->connection);\n    }\n\n    /**\n     * Set the connection associated with the model.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return $this\n     */\n    public function setConnection($name)\n    {\n        $this->connection = $name;\n\n        return $this;\n    }\n\n    /**\n     * Resolve a connection instance.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public static function resolveConnection($connection = null)\n    {\n        return static::$resolver->connection($connection);\n    }\n\n    /**\n     * Get the connection resolver instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionResolverInterface|null\n     */\n    public static function getConnectionResolver()\n    {\n        return static::$resolver;\n    }\n\n    /**\n     * Set the connection resolver instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     * @return void\n     */\n    public static function setConnectionResolver(Resolver $resolver)\n    {\n        static::$resolver = $resolver;\n    }\n\n    /**\n     * Unset the connection resolver for models.\n     *\n     * @return void\n     */\n    public static function unsetConnectionResolver()\n    {\n        static::$resolver = null;\n    }\n\n    /**\n     * Get the table associated with the model.\n     *\n     * @return string\n     */\n    public function getTable()\n    {\n        return $this->table ?? Str::snake(Str::pluralStudly(class_basename($this)));\n    }\n\n    /**\n     * Set the table associated with the model.\n     *\n     * @param  string  $table\n     * @return $this\n     */\n    public function setTable($table)\n    {\n        $this->table = $table;\n\n        return $this;\n    }\n\n    /**\n     * Get the primary key for the model.\n     *\n     * @return string\n     */\n    public function getKeyName()\n    {\n        return $this->primaryKey;\n    }\n\n    /**\n     * Set the primary key for the model.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function setKeyName($key)\n    {\n        $this->primaryKey = $key;\n\n        return $this;\n    }\n\n    /**\n     * Get the table qualified key name.\n     *\n     * @return string\n     */\n    public function getQualifiedKeyName()\n    {\n        return $this->qualifyColumn($this->getKeyName());\n    }\n\n    /**\n     * Get the auto-incrementing key type.\n     *\n     * @return string\n     */\n    public function getKeyType()\n    {\n        return $this->keyType;\n    }\n\n    /**\n     * Set the data type for the primary key.\n     *\n     * @param  string  $type\n     * @return $this\n     */\n    public function setKeyType($type)\n    {\n        $this->keyType = $type;\n\n        return $this;\n    }\n\n    /**\n     * Get the value indicating whether the IDs are incrementing.\n     *\n     * @return bool\n     */\n    public function getIncrementing()\n    {\n        return $this->incrementing;\n    }\n\n    /**\n     * Set whether IDs are incrementing.\n     *\n     * @param  bool  $value\n     * @return $this\n     */\n    public function setIncrementing($value)\n    {\n        $this->incrementing = $value;\n\n        return $this;\n    }\n\n    /**\n     * Get the value of the model's primary key.\n     *\n     * @return mixed\n     */\n    public function getKey()\n    {\n        return $this->getAttribute($this->getKeyName());\n    }\n\n    /**\n     * Get the queueable identity for the entity.\n     *\n     * @return mixed\n     */\n    public function getQueueableId()\n    {\n        return $this->getKey();\n    }\n\n    /**\n     * Get the queueable relationships for the entity.\n     *\n     * @return array\n     */\n    public function getQueueableRelations()\n    {\n        return $this->withoutRecursion(function () {\n            $relations = [];\n\n            foreach ($this->getRelations() as $key => $relation) {\n                if (! method_exists($this, $key)) {\n                    continue;\n                }\n\n                $relations[] = $key;\n\n                if ($relation instanceof QueueableCollection) {\n                    foreach ($relation->getQueueableRelations() as $collectionValue) {\n                        $relations[] = $key.'.'.$collectionValue;\n                    }\n                }\n\n                if ($relation instanceof QueueableEntity) {\n                    foreach ($relation->getQueueableRelations() as $entityValue) {\n                        $relations[] = $key.'.'.$entityValue;\n                    }\n                }\n            }\n\n            return array_unique($relations);\n        }, []);\n    }\n\n    /**\n     * Get the queueable connection for the entity.\n     *\n     * @return string|null\n     */\n    public function getQueueableConnection()\n    {\n        return $this->getConnectionName();\n    }\n\n    /**\n     * Get the value of the model's route key.\n     *\n     * @return mixed\n     */\n    public function getRouteKey()\n    {\n        return $this->getAttribute($this->getRouteKeyName());\n    }\n\n    /**\n     * Get the route key for the model.\n     *\n     * @return string\n     */\n    public function getRouteKeyName()\n    {\n        return $this->getKeyName();\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveRouteBinding($value, $field = null)\n    {\n        return $this->resolveRouteBindingQuery($this, $value, $field)->first();\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveSoftDeletableRouteBinding($value, $field = null)\n    {\n        return $this->resolveRouteBindingQuery($this, $value, $field)->withTrashed()->first();\n    }\n\n    /**\n     * Retrieve the child model for a bound value.\n     *\n     * @param  string  $childType\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveChildRouteBinding($childType, $value, $field)\n    {\n        return $this->resolveChildRouteBindingQuery($childType, $value, $field)->first();\n    }\n\n    /**\n     * Retrieve the child model for a bound value.\n     *\n     * @param  string  $childType\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    public function resolveSoftDeletableChildRouteBinding($childType, $value, $field)\n    {\n        return $this->resolveChildRouteBindingQuery($childType, $value, $field)->withTrashed()->first();\n    }\n\n    /**\n     * Retrieve the child model query for a bound value.\n     *\n     * @param  string  $childType\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Relation<\\Illuminate\\Database\\Eloquent\\Model, $this, *>\n     */\n    protected function resolveChildRouteBindingQuery($childType, $value, $field)\n    {\n        $relationship = $this->{$this->childRouteBindingRelationshipName($childType)}();\n\n        $field = $field ?: $relationship->getRelated()->getRouteKeyName();\n\n        if ($relationship instanceof HasManyThrough ||\n            $relationship instanceof BelongsToMany) {\n            $field = $relationship->getRelated()->qualifyColumn($field);\n        }\n\n        return $relationship instanceof Model\n            ? $relationship->resolveRouteBindingQuery($relationship, $value, $field)\n            : $relationship->getRelated()->resolveRouteBindingQuery($relationship, $value, $field);\n    }\n\n    /**\n     * Retrieve the child route model binding relationship name for the given child type.\n     *\n     * @param  string  $childType\n     * @return string\n     */\n    protected function childRouteBindingRelationshipName($childType)\n    {\n        return Str::plural(Str::camel($childType));\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|\\Illuminate\\Contracts\\Database\\Eloquent\\Builder|\\Illuminate\\Database\\Eloquent\\Relations\\Relation  $query\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return \\Illuminate\\Contracts\\Database\\Eloquent\\Builder\n     */\n    public function resolveRouteBindingQuery($query, $value, $field = null)\n    {\n        return $query->where($field ?? $this->getRouteKeyName(), $value);\n    }\n\n    /**\n     * Get the default foreign key name for the model.\n     *\n     * @return string\n     */\n    public function getForeignKey()\n    {\n        return Str::snake(class_basename($this)).'_'.$this->getKeyName();\n    }\n\n    /**\n     * Get the number of models to return per page.\n     *\n     * @return int\n     */\n    public function getPerPage()\n    {\n        return $this->perPage;\n    }\n\n    /**\n     * Set the number of models to return per page.\n     *\n     * @param  int  $perPage\n     * @return $this\n     */\n    public function setPerPage($perPage)\n    {\n        $this->perPage = $perPage;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the model is soft deletable.\n     */\n    public static function isSoftDeletable(): bool\n    {\n        return static::$isSoftDeletable[static::class] ??= in_array(SoftDeletes::class, class_uses_recursive(static::class));\n    }\n\n    /**\n     * Determine if the model is prunable.\n     */\n    protected function isPrunable(): bool\n    {\n        return self::$isPrunable[static::class] ??= in_array(Prunable::class, class_uses_recursive(static::class)) || static::isMassPrunable();\n    }\n\n    /**\n     * Determine if the model is mass prunable.\n     */\n    protected function isMassPrunable(): bool\n    {\n        return self::$isMassPrunable[static::class] ??= in_array(MassPrunable::class, class_uses_recursive(static::class));\n    }\n\n    /**\n     * Determine if lazy loading is disabled.\n     *\n     * @return bool\n     */\n    public static function preventsLazyLoading()\n    {\n        return static::$modelsShouldPreventLazyLoading;\n    }\n\n    /**\n     * Determine if relationships are being automatically eager loaded when accessed.\n     *\n     * @return bool\n     */\n    public static function isAutomaticallyEagerLoadingRelationships()\n    {\n        return static::$modelsShouldAutomaticallyEagerLoadRelationships;\n    }\n\n    /**\n     * Determine if discarding guarded attribute fills is disabled.\n     *\n     * @return bool\n     */\n    public static function preventsSilentlyDiscardingAttributes()\n    {\n        return static::$modelsShouldPreventSilentlyDiscardingAttributes;\n    }\n\n    /**\n     * Determine if accessing missing attributes is disabled.\n     *\n     * @return bool\n     */\n    public static function preventsAccessingMissingAttributes()\n    {\n        return static::$modelsShouldPreventAccessingMissingAttributes;\n    }\n\n    /**\n     * Get the broadcast channel route definition that is associated with the given entity.\n     *\n     * @return string\n     */\n    public function broadcastChannelRoute()\n    {\n        return str_replace('\\\\', '.', get_class($this)).'.{'.Str::camel(class_basename($this)).'}';\n    }\n\n    /**\n     * Get the broadcast channel name that is associated with the given entity.\n     *\n     * @return string\n     */\n    public function broadcastChannel()\n    {\n        return str_replace('\\\\', '.', get_class($this)).'.'.$this->getKey();\n    }\n\n    /**\n     * Resolve a class attribute value from the model.\n     *\n     * @template TAttribute of object\n     *\n     * @param  class-string<TAttribute>  $attributeClass\n     * @param  string|null  $property\n     * @param  string|null  $class\n     * @return mixed\n     */\n    protected static function resolveClassAttribute(string $attributeClass, ?string $property = null, ?string $class = null)\n    {\n        $class = $class ?? static::class;\n\n        $cacheKey = $class.'@'.$attributeClass;\n\n        if (array_key_exists($cacheKey, static::$classAttributes)) {\n            return static::$classAttributes[$cacheKey];\n        }\n\n        try {\n            $reflection = new ReflectionClass($class);\n\n            do {\n                $attributes = $reflection->getAttributes($attributeClass);\n\n                if (count($attributes) > 0) {\n                    $instance = $attributes[0]->newInstance();\n\n                    return static::$classAttributes[$cacheKey] = $property ? $instance->{$property} : $instance;\n                }\n            } while ($reflection = $reflection->getParentClass());\n        } catch (Exception) {\n            //\n        }\n\n        return static::$classAttributes[$cacheKey] = null;\n    }\n\n    /**\n     * Dynamically retrieve attributes on the model.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->getAttribute($key);\n    }\n\n    /**\n     * Dynamically set attributes on the model.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this->setAttribute($key, $value);\n    }\n\n    /**\n     * Determine if the given attribute exists.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        $shouldPrevent = static::$modelsShouldPreventAccessingMissingAttributes;\n\n        static::$modelsShouldPreventAccessingMissingAttributes = false;\n\n        try {\n            return ! is_null($this->getAttribute($offset));\n        } finally {\n            static::$modelsShouldPreventAccessingMissingAttributes = $shouldPrevent;\n        }\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->getAttribute($offset);\n    }\n\n    /**\n     * Set the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->setAttribute($offset, $value);\n    }\n\n    /**\n     * Unset the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset(\n            $this->attributes[$offset],\n            $this->relations[$offset],\n            $this->attributeCastCache[$offset],\n            $this->classCastCache[$offset]\n        );\n    }\n\n    /**\n     * Determine if an attribute or relation exists on the model.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return $this->offsetExists($key);\n    }\n\n    /**\n     * Unset an attribute on the model.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function __unset($key)\n    {\n        $this->offsetUnset($key);\n    }\n\n    /**\n     * Handle dynamic method calls into the model.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (in_array($method, ['increment', 'decrement', 'incrementQuietly', 'decrementQuietly'])) {\n            return $this->$method(...$parameters);\n        }\n\n        if ($resolver = $this->relationResolver(static::class, $method)) {\n            return $resolver($this);\n        }\n\n        if (Str::startsWith($method, 'through') &&\n            method_exists($this, $relationMethod = (new SupportStringable($method))->after('through')->lcfirst()->toString())) {\n            return $this->through($relationMethod);\n        }\n\n        return $this->forwardCallTo($this->newQuery(), $method, $parameters);\n    }\n\n    /**\n     * Handle dynamic static method calls into the model.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public static function __callStatic($method, $parameters)\n    {\n        if (static::isScopeMethodWithAttribute($method)) {\n            return static::query()->$method(...$parameters);\n        }\n\n        return (new static)->$method(...$parameters);\n    }\n\n    /**\n     * Convert the model to its string representation.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->escapeWhenCastingToString\n            ? e($this->toJson())\n            : $this->toJson();\n    }\n\n    /**\n     * Indicate that the object's string representation should be escaped when __toString is invoked.\n     *\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function escapeWhenCastingToString($escape = true)\n    {\n        $this->escapeWhenCastingToString = $escape;\n\n        return $this;\n    }\n\n    /**\n     * Prepare the object for serialization.\n     *\n     * @return array\n     */\n    public function __sleep()\n    {\n        $this->mergeAttributesFromCachedCasts();\n\n        $this->classCastCache = [];\n        $this->attributeCastCache = [];\n        $this->relationAutoloadCallback = null;\n        $this->relationAutoloadContext = null;\n\n        $keys = get_object_vars($this);\n\n        if (version_compare(PHP_VERSION, '8.4.0', '>=')) {\n            foreach ((new ReflectionClass($this))->getProperties() as $property) {\n                if ($property->hasHooks()) {\n                    unset($keys[$property->getName()]);\n                }\n            }\n        }\n\n        return array_keys($keys);\n    }\n\n    /**\n     * When a model is being unserialized, check if it needs to be booted.\n     *\n     * @return void\n     */\n    public function __wakeup()\n    {\n        $this->bootIfNotBooted();\n        $this->initializeTraits();\n        $this->initializeModelAttributes();\n\n        if (static::isAutomaticallyEagerLoadingRelationships()) {\n            $this->withRelationshipAutoloading();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/ModelInfo.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse ArrayAccess;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse InvalidArgumentException;\nuse LogicException;\n\n/**\n * @implements Arrayable<string, mixed>\n *\n * @internal\n */\nclass ModelInfo implements Arrayable, ArrayAccess\n{\n    /**\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  class-string<TModel>  $class  The model's fully-qualified class.\n     * @param  string  $database  The database connection name.\n     * @param  string  $table  The database table name.\n     * @param  class-string|null  $policy  The policy that applies to the model.\n     * @param  \\Illuminate\\Support\\Collection<int, array<string, mixed>>  $attributes  The attributes available on the model.\n     * @param  \\Illuminate\\Support\\Collection<int, array{name: string, type: string, related: class-string<\\Illuminate\\Database\\Eloquent\\Model>}>  $relations  The relations defined on the model.\n     * @param  \\Illuminate\\Support\\Collection<int, array{event: string, class: string}>  $events  The events that the model dispatches.\n     * @param  \\Illuminate\\Support\\Collection<int, array{event: string, observer: array<int, string>}>  $observers  The observers registered for the model.\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Collection<TModel>>  $collection  The Collection class that collects the models.\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Builder<TModel>>  $builder  The Builder class registered for the model.\n     * @param  \\Illuminate\\Http\\Resources\\Json\\JsonResource|null  $resource  The JSON resource that represents the model.\n     */\n    public function __construct(\n        public $class,\n        public $database,\n        public $table,\n        public $policy,\n        public $attributes,\n        public $relations,\n        public $events,\n        public $observers,\n        public $collection,\n        public $builder,\n        public $resource\n    ) {\n    }\n\n    /**\n     * Convert the model info to an array.\n     *\n     * @return array{\n     *     \"class\": class-string<\\Illuminate\\Database\\Eloquent\\Model>,\n     *     database: string,\n     *     table: string,\n     *     policy: class-string|null,\n     *     attributes: \\Illuminate\\Support\\Collection<int, array<string, mixed>>,\n     *     relations: \\Illuminate\\Support\\Collection<int, array{name: string, type: string, related: class-string<\\Illuminate\\Database\\Eloquent\\Model>}>,\n     *     events: \\Illuminate\\Support\\Collection<int, array{event: string, class: string}>,\n     *     observers: \\Illuminate\\Support\\Collection<int, array{event: string, observer: array<int, string>}>, collection: class-string<\\Illuminate\\Database\\Eloquent\\Collection<\\Illuminate\\Database\\Eloquent\\Model>>,\n     *     builder: class-string<\\Illuminate\\Database\\Eloquent\\Builder<\\Illuminate\\Database\\Eloquent\\Model>>,\n     *     resource: \\Illuminate\\Http\\Resources\\Json\\JsonResource|null\n     * }\n     */\n    public function toArray()\n    {\n        return [\n            'class' => $this->class,\n            'database' => $this->database,\n            'table' => $this->table,\n            'policy' => $this->policy,\n            'attributes' => $this->attributes,\n            'relations' => $this->relations,\n            'events' => $this->events,\n            'observers' => $this->observers,\n            'collection' => $this->collection,\n            'builder' => $this->builder,\n            'resource' => $this->resource,\n        ];\n    }\n\n    public function offsetExists(mixed $offset): bool\n    {\n        return property_exists($this, $offset);\n    }\n\n    public function offsetGet(mixed $offset): mixed\n    {\n        return property_exists($this, $offset) ? $this->{$offset} : throw new InvalidArgumentException(\"Property {$offset} does not exist.\");\n    }\n\n    public function offsetSet(mixed $offset, mixed $value): void\n    {\n        throw new LogicException(self::class.' may not be mutated using array access.');\n    }\n\n    public function offsetUnset(mixed $offset): void\n    {\n        throw new LogicException(self::class.' may not be mutated using array access.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/ModelInspector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Facades\\Gate;\nuse Illuminate\\Support\\Str;\nuse ReflectionClass;\nuse ReflectionMethod;\nuse ReflectionNamedType;\nuse SplFileObject;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass ModelInspector\n{\n    /**\n     * The methods that can be called in a model to indicate a relation.\n     *\n     * @var list<string>\n     */\n    protected $relationMethods = [\n        'hasMany',\n        'hasManyThrough',\n        'hasOneThrough',\n        'belongsToMany',\n        'hasOne',\n        'belongsTo',\n        'morphOne',\n        'morphTo',\n        'morphMany',\n        'morphToMany',\n        'morphedByMany',\n    ];\n\n    /**\n     * Create a new model inspector instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app  The Laravel application instance.\n     */\n    public function __construct(protected Application $app)\n    {\n    }\n\n    /**\n     * Extract model details for the given model.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $model\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Database\\Eloquent\\ModelInfo\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function inspect($model, $connection = null)\n    {\n        $class = $this->qualifyModel($model);\n\n        /** @var \\Illuminate\\Database\\Eloquent\\Model $model */\n        $model = $this->app->make($class);\n\n        if ($connection !== null) {\n            $model->setConnection($connection);\n        }\n\n        return new ModelInfo(\n            class: $model::class,\n            database: $model->getConnection()->getName(),\n            table: $model->getConnection()->getTablePrefix().$model->getTable(),\n            policy: $this->getPolicy($model),\n            attributes: $this->getAttributes($model),\n            relations: $this->getRelations($model),\n            events: $this->getEvents($model),\n            observers: $this->getObservers($model),\n            collection: $this->getCollectedBy($model),\n            builder: $this->getBuilder($model),\n            resource: $this->getResource($model),\n        );\n    }\n\n    /**\n     * Get the column attributes for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Support\\Collection<int, array<string, mixed>>\n     */\n    protected function getAttributes($model)\n    {\n        $connection = $model->getConnection();\n        $schema = $connection->getSchemaBuilder();\n        $table = $model->getTable();\n        $columns = $schema->getColumns($table);\n        $indexes = $schema->getIndexes($table);\n\n        return (new BaseCollection($columns))\n            ->map(fn ($column) => [\n                'name' => $column['name'],\n                'type' => $column['type'],\n                'increments' => $column['auto_increment'],\n                'nullable' => $column['nullable'],\n                'default' => $this->getColumnDefault($column, $model),\n                'unique' => $this->columnIsUnique($column['name'], $indexes),\n                'fillable' => $model->isFillable($column['name']),\n                'hidden' => $this->attributeIsHidden($column['name'], $model),\n                'appended' => null,\n                'cast' => $this->getCastType($column['name'], $model),\n            ])\n            ->merge($this->getVirtualAttributes($model, $columns));\n    }\n\n    /**\n     * Get the virtual (non-column) attributes for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  array  $columns\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getVirtualAttributes($model, $columns)\n    {\n        $class = new ReflectionClass($model);\n\n        return (new BaseCollection($class->getMethods()))\n            ->reject(\n                fn (ReflectionMethod $method) => $method->isStatic()\n                    || $method->isAbstract()\n                    || $method->getDeclaringClass()->getName() === Model::class\n            )\n            ->mapWithKeys(function (ReflectionMethod $method) use ($model) {\n                if (preg_match('/^get(.+)Attribute$/', $method->getName(), $matches) === 1) {\n                    return [Str::snake($matches[1]) => 'accessor'];\n                } elseif ($model->hasAttributeMutator($method->getName())) {\n                    return [Str::snake($method->getName()) => 'attribute'];\n                } else {\n                    return [];\n                }\n            })\n            ->reject(fn ($cast, $name) => (new BaseCollection($columns))->contains('name', $name))\n            ->map(fn ($cast, $name) => [\n                'name' => $name,\n                'type' => null,\n                'increments' => false,\n                'nullable' => null,\n                'default' => null,\n                'unique' => null,\n                'fillable' => $model->isFillable($name),\n                'hidden' => $this->attributeIsHidden($name, $model),\n                'appended' => $model->hasAppended($name),\n                'cast' => $cast,\n            ])\n            ->values();\n    }\n\n    /**\n     * Get the relations from the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getRelations($model)\n    {\n        return (new BaseCollection(get_class_methods($model)))\n            ->map(fn ($method) => new ReflectionMethod($model, $method))\n            ->reject(\n                fn (ReflectionMethod $method) => $method->isStatic()\n                    || $method->isAbstract()\n                    || $method->getDeclaringClass()->getName() === Model::class\n                    || $method->getNumberOfParameters() > 0\n            )\n            ->filter(function (ReflectionMethod $method) {\n                if ($method->getReturnType() instanceof ReflectionNamedType\n                    && is_subclass_of($method->getReturnType()->getName(), Relation::class)) {\n                    return true;\n                }\n\n                $file = new SplFileObject($method->getFileName());\n                $file->seek($method->getStartLine() - 1);\n                $code = '';\n                while ($file->key() < $method->getEndLine()) {\n                    $code .= trim($file->current());\n                    $file->next();\n                }\n\n                return (new BaseCollection($this->relationMethods))\n                    ->contains(fn ($relationMethod) => str_contains($code, '$this->'.$relationMethod.'('));\n            })\n            ->map(function (ReflectionMethod $method) use ($model) {\n                $relation = $method->invoke($model);\n\n                if (! $relation instanceof Relation) {\n                    return null;\n                }\n\n                return [\n                    'name' => $method->getName(),\n                    'type' => Str::afterLast(get_class($relation), '\\\\'),\n                    'related' => get_class($relation->getRelated()),\n                ];\n            })\n            ->filter()\n            ->values();\n    }\n\n    /**\n     * Get the first policy associated with this model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return string|null\n     */\n    protected function getPolicy($model)\n    {\n        $policy = Gate::getPolicyFor($model::class);\n\n        return $policy ? $policy::class : null;\n    }\n\n    /**\n     * Get the events that the model dispatches.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getEvents($model)\n    {\n        return (new BaseCollection($model->dispatchesEvents()))\n            ->map(fn (string $class, string $event) => [\n                'event' => $event,\n                'class' => $class,\n            ])->values();\n    }\n\n    /**\n     * Get the observers watching this model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Support\\Collection\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function getObservers($model)\n    {\n        $listeners = $this->app->make('events')->getRawListeners();\n\n        // Get the Eloquent observers for this model...\n        $listeners = array_filter($listeners, function ($v, $key) use ($model) {\n            return Str::startsWith($key, 'eloquent.') && Str::endsWith($key, $model::class);\n        }, ARRAY_FILTER_USE_BOTH);\n\n        // Format listeners Eloquent verb => Observer methods...\n        $extractVerb = function ($key) {\n            preg_match('/eloquent.([a-zA-Z]+)\\: /', $key, $matches);\n\n            return $matches[1] ?? '?';\n        };\n\n        $formatted = [];\n\n        foreach ($listeners as $key => $observerMethods) {\n            $formatted[] = [\n                'event' => $extractVerb($key),\n                'observer' => array_map(fn ($obs) => is_string($obs) ? $obs : 'Closure', $observerMethods),\n            ];\n        }\n\n        return new BaseCollection($formatted);\n    }\n\n    /**\n     * Get the collection class being used by the model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Collection>\n     */\n    protected function getCollectedBy($model)\n    {\n        return $model->newCollection()::class;\n    }\n\n    /**\n     * Get the builder class being used by the model.\n     *\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  TModel  $model\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Builder<TModel>>\n     */\n    protected function getBuilder($model)\n    {\n        return $model->newQuery()::class;\n    }\n\n    /**\n     * Get the class used for JSON response transforming.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Http\\Resources\\Json\\JsonResource|null\n     */\n    protected function getResource($model)\n    {\n        return rescue(static fn () => $model->toResource()::class, null, false);\n    }\n\n    /**\n     * Qualify the given model class base name.\n     *\n     * @param  string  $model\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Model>\n     *\n     * @see \\Illuminate\\Console\\GeneratorCommand\n     */\n    protected function qualifyModel(string $model)\n    {\n        if (str_contains($model, '\\\\') && class_exists($model)) {\n            return $model;\n        }\n\n        $model = ltrim($model, '\\\\/');\n\n        $model = str_replace('/', '\\\\', $model);\n\n        $rootNamespace = $this->app->getNamespace();\n\n        if (Str::startsWith($model, $rootNamespace)) {\n            return $model;\n        }\n\n        return is_dir(app_path('Models'))\n            ? $rootNamespace.'Models\\\\'.$model\n            : $rootNamespace.$model;\n    }\n\n    /**\n     * Get the cast type for the given column.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return string|null\n     */\n    protected function getCastType($column, $model)\n    {\n        if ($model->hasGetMutator($column) || $model->hasSetMutator($column)) {\n            return 'accessor';\n        }\n\n        if ($model->hasAttributeMutator($column)) {\n            return 'attribute';\n        }\n\n        return $this->getCastsWithDates($model)->get($column) ?? null;\n    }\n\n    /**\n     * Get the model casts, including any date casts.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getCastsWithDates($model)\n    {\n        return (new BaseCollection($model->getDates()))\n            ->filter()\n            ->flip()\n            ->map(fn () => 'datetime')\n            ->merge($model->getCasts());\n    }\n\n    /**\n     * Determine if the given attribute is hidden.\n     *\n     * @param  string  $attribute\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return bool\n     */\n    protected function attributeIsHidden($attribute, $model)\n    {\n        if (count($model->getHidden()) > 0) {\n            return in_array($attribute, $model->getHidden());\n        }\n\n        if (count($model->getVisible()) > 0) {\n            return ! in_array($attribute, $model->getVisible());\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the default value for the given column.\n     *\n     * @param  array<string, mixed>  $column\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return mixed\n     */\n    protected function getColumnDefault($column, $model)\n    {\n        $attributeDefault = $model->getAttributes()[$column['name']] ?? null;\n\n        return enum_value($attributeDefault) ?? $column['default'];\n    }\n\n    /**\n     * Determine if the given attribute is unique.\n     *\n     * @param  string  $column\n     * @param  array  $indexes\n     * @return bool\n     */\n    protected function columnIsUnique($column, $indexes)\n    {\n        return (new BaseCollection($indexes))->contains(\n            fn ($index) => count($index['columns']) === 1 && $index['columns'][0] === $column && $index['unique']\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/ModelNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse BackedEnum;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Support\\Arr;\n\n/**\n * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n */\nclass ModelNotFoundException extends RecordsNotFoundException\n{\n    /**\n     * Name of the affected Eloquent model.\n     *\n     * @var class-string<TModel>\n     */\n    protected $model;\n\n    /**\n     * The affected model IDs.\n     *\n     * @var array<int, int|string>\n     */\n    protected $ids;\n\n    /**\n     * Set the affected Eloquent model and instance ids.\n     *\n     * @param  class-string<TModel>  $model\n     * @param  array<int, int|string>|int|string  $ids\n     * @return $this\n     */\n    public function setModel($model, $ids = [])\n    {\n        $this->model = $model;\n\n        $this->ids = array_map(\n            fn ($id) => $id instanceof BackedEnum ? $id->value : $id,\n            Arr::wrap($ids)\n        );\n\n        $this->message = \"No query results for model [{$model}]\";\n\n        if (count($this->ids) > 0) {\n            $this->message .= ' '.implode(', ', $this->ids);\n        } else {\n            $this->message .= '.';\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the affected Eloquent model.\n     *\n     * @return class-string<TModel>\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n    /**\n     * Get the affected Eloquent model IDs.\n     *\n     * @return array<int, int|string>\n     */\n    public function getIds()\n    {\n        return $this->ids;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/PendingHasThroughRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse BadMethodCallException;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\n\n/**\n * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TLocalRelationship of \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany<TIntermediateModel, TDeclaringModel>\n */\nclass PendingHasThroughRelationship\n{\n    /**\n     * The root model that the relationship exists on.\n     *\n     * @var TDeclaringModel\n     */\n    protected $rootModel;\n\n    /**\n     * The local relationship.\n     *\n     * @var TLocalRelationship\n     */\n    protected $localRelationship;\n\n    /**\n     * Create a pending has-many-through or has-one-through relationship.\n     *\n     * @param  TDeclaringModel  $rootModel\n     * @param  TLocalRelationship  $localRelationship\n     */\n    public function __construct($rootModel, $localRelationship)\n    {\n        $this->rootModel = $rootModel;\n\n        $this->localRelationship = $localRelationship;\n    }\n\n    /**\n     * Define the distant relationship that this model has.\n     *\n     * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  string|(callable(TIntermediateModel): (\\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TRelatedModel, TIntermediateModel>|\\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TRelatedModel, TIntermediateModel>|\\Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany<TRelatedModel, TIntermediateModel>))  $callback\n     * @return (\n     *     $callback is string\n     *     ? \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough<\\Illuminate\\Database\\Eloquent\\Model, TIntermediateModel, TDeclaringModel>|\\Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough<\\Illuminate\\Database\\Eloquent\\Model, TIntermediateModel, TDeclaringModel>\n     *     : (\n     *         TLocalRelationship is \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TIntermediateModel, TDeclaringModel>\n     *         ? \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     *         : (\n     *              $callback is callable(TIntermediateModel): \\Illuminate\\Database\\Eloquent\\Relations\\HasMany<TRelatedModel, TIntermediateModel>\n     *              ? \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     *              : \\Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     *         )\n     *     )\n     * )\n     */\n    public function has($callback)\n    {\n        if (is_string($callback)) {\n            $callback = fn () => $this->localRelationship->getRelated()->{$callback}();\n        }\n\n        $distantRelation = $callback($this->localRelationship->getRelated());\n\n        if ($distantRelation instanceof HasMany || $this->localRelationship instanceof HasMany) {\n            $returnedRelation = $this->rootModel->hasManyThrough(\n                $distantRelation->getRelated()::class,\n                $this->localRelationship->getRelated()::class,\n                $this->localRelationship->getForeignKeyName(),\n                $distantRelation->getForeignKeyName(),\n                $this->localRelationship->getLocalKeyName(),\n                $distantRelation->getLocalKeyName(),\n            );\n        } else {\n            $returnedRelation = $this->rootModel->hasOneThrough(\n                $distantRelation->getRelated()::class,\n                $this->localRelationship->getRelated()::class,\n                $this->localRelationship->getForeignKeyName(),\n                $distantRelation->getForeignKeyName(),\n                $this->localRelationship->getLocalKeyName(),\n                $distantRelation->getLocalKeyName(),\n            );\n        }\n\n        if ($this->localRelationship instanceof MorphOneOrMany) {\n            $returnedRelation->where($this->localRelationship->getQualifiedMorphType(), $this->localRelationship->getMorphClass());\n        }\n\n        return $returnedRelation;\n    }\n\n    /**\n     * Handle dynamic method calls into the model.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (Str::startsWith($method, 'has')) {\n            return $this->has((new Stringable($method))->after('has')->lcfirst()->toString());\n        }\n\n        throw new BadMethodCallException(sprintf(\n            'Call to undefined method %s::%s()', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Prunable.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse LogicException;\nuse Throwable;\n\ntrait Prunable\n{\n    /**\n     * Prune all prunable models in the database.\n     *\n     * @param  int  $chunkSize\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    public function pruneAll(int $chunkSize = 1000)\n    {\n        $total = 0;\n\n        $this->prunable()\n            ->when(static::isSoftDeletable(), function ($query) {\n                $query->withTrashed();\n            })->chunkById($chunkSize, function ($models) use (&$total) {\n                $models->each(function ($model) use (&$total) {\n                    try {\n                        $model->prune();\n\n                        $total++;\n                    } catch (Throwable $e) {\n                        $handler = app(ExceptionHandler::class);\n\n                        if ($handler) {\n                            $handler->report($e);\n                        } else {\n                            throw $e;\n                        }\n                    }\n                });\n\n                event(new ModelsPruned(static::class, $total));\n            });\n\n        return $total;\n    }\n\n    /**\n     * Get the prunable model query.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     *\n     * @throws \\LogicException\n     */\n    public function prunable()\n    {\n        throw new LogicException('Please implement the prunable method on your model.');\n    }\n\n    /**\n     * Prune the model in the database.\n     *\n     * @return bool|null\n     */\n    public function prune()\n    {\n        $this->pruning();\n\n        return static::isSoftDeletable()\n            ? $this->forceDelete()\n            : $this->delete();\n    }\n\n    /**\n     * Prepare the model for pruning.\n     *\n     * @return void\n     */\n    protected function pruning()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/QueueEntityResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Contracts\\Queue\\EntityNotFoundException;\nuse Illuminate\\Contracts\\Queue\\EntityResolver as EntityResolverContract;\n\nclass QueueEntityResolver implements EntityResolverContract\n{\n    /**\n     * Resolve the entity for the given ID.\n     *\n     * @param  string  $type\n     * @param  mixed  $id\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Queue\\EntityNotFoundException\n     */\n    public function resolve($type, $id)\n    {\n        $instance = (new $type)->find($id);\n\n        if ($instance) {\n            return $instance;\n        }\n\n        throw new EntityNotFoundException($type, $id);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/RelationNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse RuntimeException;\n\nclass RelationNotFoundException extends RuntimeException\n{\n    /**\n     * The name of the affected Eloquent model.\n     *\n     * @var string\n     */\n    public $model;\n\n    /**\n     * The name of the relation.\n     *\n     * @var string\n     */\n    public $relation;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  object  $model\n     * @param  string  $relation\n     * @param  string|null  $type\n     * @return static\n     */\n    public static function make($model, $relation, $type = null)\n    {\n        $class = get_class($model);\n\n        $instance = new static(\n            is_null($type)\n                ? \"Call to undefined relationship [{$relation}] on model [{$class}].\"\n                : \"Call to undefined relationship [{$relation}] on model [{$class}] of type [{$type}].\",\n        );\n\n        $instance->model = $class;\n        $instance->relation = $relation;\n\n        return $instance;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/BelongsTo.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\ComparesRelatedModels;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsDefaultModels;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, TDeclaringModel, ?TRelatedModel>\n */\nclass BelongsTo extends Relation\n{\n    use ComparesRelatedModels,\n        InteractsWithDictionary,\n        SupportsDefaultModels;\n\n    /**\n     * The child model instance of the relation.\n     *\n     * @var TDeclaringModel\n     */\n    protected $child;\n\n    /**\n     * The foreign key of the parent model.\n     *\n     * @var string\n     */\n    protected $foreignKey;\n\n    /**\n     * The associated key on the parent model.\n     *\n     * @var string\n     */\n    protected $ownerKey;\n\n    /**\n     * The name of the relationship.\n     *\n     * @var string\n     */\n    protected $relationName;\n\n    /**\n     * Create a new belongs to relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $child\n     * @param  string  $foreignKey\n     * @param  string  $ownerKey\n     * @param  string  $relationName\n     */\n    public function __construct(Builder $query, Model $child, $foreignKey, $ownerKey, $relationName)\n    {\n        $this->ownerKey = $ownerKey;\n        $this->relationName = $relationName;\n        $this->foreignKey = $foreignKey;\n\n        // In the underlying base relationship class, this variable is referred to as\n        // the \"parent\" since most relationships are not inversed. But, since this\n        // one is we will create a \"child\" variable for much better readability.\n        $this->child = $child;\n\n        parent::__construct($query, $child);\n    }\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        if (is_null($this->getForeignKeyFrom($this->child))) {\n            return $this->getDefaultFor($this->parent);\n        }\n\n        return $this->query->first() ?: $this->getDefaultFor($this->parent);\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    public function addConstraints()\n    {\n        if (static::$constraints) {\n            // For belongs to relationships, which are essentially the inverse of has one\n            // or has many relationships, we need to actually query on the primary key\n            // of the related models matching on the foreign key that's on a parent.\n            $key = $this->getQualifiedOwnerKeyName();\n\n            $this->query->where($key, '=', $this->getForeignKeyFrom($this->child));\n        }\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        // We'll grab the primary key name of the related models since it could be set to\n        // a non-standard name and not \"id\". We will then construct the constraint for\n        // our eagerly loading query so it returns the proper models from execution.\n        $key = $this->getQualifiedOwnerKeyName();\n\n        $whereIn = $this->whereInMethod($this->related, $this->ownerKey);\n\n        $this->whereInEager($whereIn, $key, $this->getEagerModelKeys($models));\n    }\n\n    /**\n     * Gather the keys from an array of related models.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @return array\n     */\n    protected function getEagerModelKeys(array $models)\n    {\n        $keys = [];\n\n        // First we need to gather all of the keys from the parent models so we know what\n        // to query for via the eager loading query. We will add them to an array then\n        // execute a \"where in\" statement to gather up all of those related records.\n        foreach ($models as $model) {\n            if (! is_null($value = $this->getForeignKeyFrom($model))) {\n                $keys[] = $value;\n            }\n        }\n\n        sort($keys);\n\n        return array_values(array_unique($keys));\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->getDefaultFor($model));\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        // First we will get to build a dictionary of the child models by their primary\n        // key of the relationship, then we can easily match the children back onto\n        // the parents using that dictionary and the primary key of the children.\n        $dictionary = [];\n\n        foreach ($results as $result) {\n            $attribute = $this->getDictionaryKey($this->getRelatedKeyFrom($result));\n\n            if ($attribute !== null) {\n                $dictionary[$attribute] = $result;\n            }\n        }\n\n        // Once we have the dictionary constructed, we can loop through all the parents\n        // and match back onto their children using these keys of the dictionary and\n        // the primary key of the children to map them onto the correct instances.\n        foreach ($models as $model) {\n            $attribute = $this->getDictionaryKey($this->getForeignKeyFrom($model));\n\n            if ($attribute !== null && isset($dictionary[$attribute])) {\n                $model->setRelation($relation, $dictionary[$attribute]);\n            }\n        }\n\n        return $models;\n    }\n\n    /**\n     * Associate the model instance to the given parent.\n     *\n     * @param  TRelatedModel|int|string|null  $model\n     * @return TDeclaringModel\n     */\n    public function associate($model)\n    {\n        $ownerKey = $model instanceof Model ? $model->getAttribute($this->ownerKey) : $model;\n\n        $this->child->setAttribute($this->foreignKey, $ownerKey);\n\n        if ($model instanceof Model) {\n            $this->child->setRelation($this->relationName, $model);\n        } else {\n            $this->child->unsetRelation($this->relationName);\n        }\n\n        return $this->child;\n    }\n\n    /**\n     * Dissociate previously associated model from the given parent.\n     *\n     * @return TDeclaringModel\n     */\n    public function dissociate()\n    {\n        $this->child->setAttribute($this->foreignKey, null);\n\n        return $this->child->setRelation($this->relationName, null);\n    }\n\n    /**\n     * Alias of \"dissociate\" method.\n     *\n     * @return TDeclaringModel\n     */\n    public function disassociate()\n    {\n        return $this->dissociate();\n    }\n\n    /**\n     * Touch all of the related models for the relationship.\n     *\n     * @return void\n     */\n    public function touch()\n    {\n        if (! is_null($this->getParentKey())) {\n            parent::touch();\n        }\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($parentQuery->getQuery()->from == $query->getQuery()->from) {\n            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);\n        }\n\n        return $query->select($columns)->whereColumn(\n            $this->getQualifiedForeignKeyName(), '=', $query->qualifyColumn($this->ownerKey)\n        );\n    }\n\n    /**\n     * Add the constraints for a relationship query on the same table.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        $query->select($columns)->from(\n            $query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash()\n        );\n\n        $query->getModel()->setTable($hash);\n\n        return $query->whereColumn(\n            $hash.'.'.$this->ownerKey, '=', $this->getQualifiedForeignKeyName()\n        );\n    }\n\n    /**\n     * Determine if the related model has an auto-incrementing ID.\n     *\n     * @return bool\n     */\n    protected function relationHasIncrementingId()\n    {\n        return $this->related->getIncrementing() &&\n            in_array($this->related->getKeyType(), ['int', 'integer']);\n    }\n\n    /**\n     * Make a new related instance for the given model.\n     *\n     * @param  TDeclaringModel  $parent\n     * @return TRelatedModel\n     */\n    protected function newRelatedInstanceFor(Model $parent)\n    {\n        return $this->related->newInstance();\n    }\n\n    /**\n     * Get the child of the relationship.\n     *\n     * @return TDeclaringModel\n     */\n    public function getChild()\n    {\n        return $this->child;\n    }\n\n    /**\n     * Get the foreign key of the relationship.\n     *\n     * @return string\n     */\n    public function getForeignKeyName()\n    {\n        return $this->foreignKey;\n    }\n\n    /**\n     * Get the fully-qualified foreign key of the relationship.\n     *\n     * @return string\n     */\n    public function getQualifiedForeignKeyName()\n    {\n        return $this->child->qualifyColumn($this->foreignKey);\n    }\n\n    /**\n     * Get the key value of the child's foreign key.\n     *\n     * @return mixed\n     */\n    public function getParentKey()\n    {\n        return $this->getForeignKeyFrom($this->child);\n    }\n\n    /**\n     * Get the associated key of the relationship.\n     *\n     * @return string\n     */\n    public function getOwnerKeyName()\n    {\n        return $this->ownerKey;\n    }\n\n    /**\n     * Get the fully-qualified associated key of the relationship.\n     *\n     * @return string\n     */\n    public function getQualifiedOwnerKeyName()\n    {\n        return $this->related->qualifyColumn($this->ownerKey);\n    }\n\n    /**\n     * Get the value of the model's foreign key.\n     *\n     * @param  TRelatedModel  $model\n     * @return int|string\n     */\n    protected function getRelatedKeyFrom(Model $model)\n    {\n        return $model->{$this->ownerKey};\n    }\n\n    /**\n     * Get the value of the model's foreign key.\n     *\n     * @param  TDeclaringModel  $model\n     * @return mixed\n     */\n    protected function getForeignKeyFrom(Model $model)\n    {\n        $foreignKey = $model->{$this->foreignKey};\n\n        return enum_value($foreignKey);\n    }\n\n    /**\n     * Get the name of the relationship.\n     *\n     * @return string\n     */\n    public function getRelationName()\n    {\n        return $this->relationName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithPivotTable;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TPivotModel of \\Illuminate\\Database\\Eloquent\\Relations\\Pivot = \\Illuminate\\Database\\Eloquent\\Relations\\Pivot\n * @template TAccessor of string = 'pivot'\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, TDeclaringModel, \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>>\n *\n * @todo use TAccessor when PHPStan bug is fixed: https://github.com/phpstan/phpstan/issues/12756\n */\nclass BelongsToMany extends Relation\n{\n    use InteractsWithDictionary, InteractsWithPivotTable;\n\n    /**\n     * The intermediate table for the relation.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The foreign key of the parent model.\n     *\n     * @var string\n     */\n    protected $foreignPivotKey;\n\n    /**\n     * The associated key of the relation.\n     *\n     * @var string\n     */\n    protected $relatedPivotKey;\n\n    /**\n     * The key name of the parent model.\n     *\n     * @var string\n     */\n    protected $parentKey;\n\n    /**\n     * The key name of the related model.\n     *\n     * @var string\n     */\n    protected $relatedKey;\n\n    /**\n     * The \"name\" of the relationship.\n     *\n     * @var string\n     */\n    protected $relationName;\n\n    /**\n     * The pivot table columns to retrieve.\n     *\n     * @var array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>\n     */\n    protected $pivotColumns = [];\n\n    /**\n     * Any pivot table restrictions for where clauses.\n     *\n     * @var array\n     */\n    protected $pivotWheres = [];\n\n    /**\n     * Any pivot table restrictions for whereIn clauses.\n     *\n     * @var array\n     */\n    protected $pivotWhereIns = [];\n\n    /**\n     * Any pivot table restrictions for whereNull clauses.\n     *\n     * @var array\n     */\n    protected $pivotWhereNulls = [];\n\n    /**\n     * The default values for the pivot columns.\n     *\n     * @var array\n     */\n    protected $pivotValues = [];\n\n    /**\n     * Indicates if timestamps are available on the pivot table.\n     *\n     * @var bool\n     */\n    public $withTimestamps = false;\n\n    /**\n     * The custom pivot table column for the created_at timestamp.\n     *\n     * @var string|null\n     */\n    protected $pivotCreatedAt;\n\n    /**\n     * The custom pivot table column for the updated_at timestamp.\n     *\n     * @var string|null\n     */\n    protected $pivotUpdatedAt;\n\n    /**\n     * The class name of the custom pivot model to use for the relationship.\n     *\n     * @var class-string<TPivotModel>\n     */\n    protected $using;\n\n    /**\n     * The name of the accessor to use for the \"pivot\" relationship.\n     *\n     * @var TAccessor\n     */\n    protected $accessor = 'pivot';\n\n    /**\n     * Create a new belongs to many relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string|class-string<TRelatedModel>  $table\n     * @param  string  $foreignPivotKey\n     * @param  string  $relatedPivotKey\n     * @param  string  $parentKey\n     * @param  string  $relatedKey\n     * @param  string|null  $relationName\n     */\n    public function __construct(\n        Builder $query,\n        Model $parent,\n        $table,\n        $foreignPivotKey,\n        $relatedPivotKey,\n        $parentKey,\n        $relatedKey,\n        $relationName = null,\n    ) {\n        $this->parentKey = $parentKey;\n        $this->relatedKey = $relatedKey;\n        $this->relationName = $relationName;\n        $this->relatedPivotKey = $relatedPivotKey;\n        $this->foreignPivotKey = $foreignPivotKey;\n        $this->table = $this->resolveTableName($table);\n\n        parent::__construct($query, $parent);\n    }\n\n    /**\n     * Attempt to resolve the intermediate table name from the given string.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function resolveTableName($table)\n    {\n        if (! str_contains($table, '\\\\') || ! class_exists($table)) {\n            return $table;\n        }\n\n        $model = new $table;\n\n        if (! $model instanceof Model) {\n            return $table;\n        }\n\n        if (in_array(AsPivot::class, class_uses_recursive($model))) {\n            $this->using($table);\n        }\n\n        return $model->getTable();\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    public function addConstraints()\n    {\n        $this->performJoin();\n\n        if (static::$constraints) {\n            $this->addWhereConstraints();\n        }\n    }\n\n    /**\n     * Set the join clause for the relation query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>|null  $query\n     * @return $this\n     */\n    protected function performJoin($query = null)\n    {\n        $query = $query ?: $this->query;\n\n        // We need to join to the intermediate table on the related model's primary\n        // key column with the intermediate table's foreign key for the related\n        // model instance. Then we can set the \"where\" for the parent models.\n        $query->join(\n            $this->table,\n            $this->getQualifiedRelatedKeyName(),\n            '=',\n            $this->getQualifiedRelatedPivotKeyName()\n        );\n\n        return $this;\n    }\n\n    /**\n     * Set the where clause for the relation query.\n     *\n     * @return $this\n     */\n    protected function addWhereConstraints()\n    {\n        $this->query->where(\n            $this->getQualifiedForeignPivotKeyName(), '=', $this->parent->{$this->parentKey}\n        );\n\n        return $this;\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        $whereIn = $this->whereInMethod($this->parent, $this->parentKey);\n\n        $this->whereInEager(\n            $whereIn,\n            $this->getQualifiedForeignPivotKeyName(),\n            $this->getKeys($models, $this->parentKey)\n        );\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->related->newCollection());\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        $dictionary = $this->buildDictionary($results);\n\n        // Once we have an array dictionary of child objects we can easily match the\n        // children back to their parent using the dictionary and the keys on the\n        // parent models. Then we should return these hydrated models back out.\n        foreach ($models as $model) {\n            $key = $this->getDictionaryKey($model->{$this->parentKey});\n\n            if ($key !== null && isset($dictionary[$key])) {\n                $model->setRelation(\n                    $relation, $this->related->newCollection($dictionary[$key])\n                );\n            }\n        }\n\n        return $models;\n    }\n\n    /**\n     * Build model dictionary keyed by the relation's foreign key.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @return array<array<array-key, TRelatedModel>>\n     */\n    protected function buildDictionary(EloquentCollection $results)\n    {\n        // First we'll build a dictionary of child models keyed by the foreign key\n        // of the relation so that we will easily and quickly match them to the\n        // parents without having a possibly slow inner loop for every model.\n        $dictionary = [];\n\n        $isAssociative = Arr::isAssoc($results->all());\n\n        foreach ($results as $key => $result) {\n            $value = $this->getDictionaryKey($result->{$this->accessor}->{$this->foreignPivotKey});\n\n            if ($value === null) {\n                continue;\n            }\n\n            if ($isAssociative) {\n                $dictionary[$value][$key] = $result;\n            } else {\n                $dictionary[$value][] = $result;\n            }\n        }\n\n        return $dictionary;\n    }\n\n    /**\n     * Get the class being used for pivot models.\n     *\n     * @return class-string<TPivotModel>\n     */\n    public function getPivotClass()\n    {\n        return $this->using ?? Pivot::class;\n    }\n\n    /**\n     * Specify the custom pivot model to use for the relationship.\n     *\n     * @template TNewPivotModel of \\Illuminate\\Database\\Eloquent\\Relations\\Pivot\n     *\n     * @param  class-string<TNewPivotModel>  $class\n     * @return $this\n     *\n     * @phpstan-this-out static<TRelatedModel, TDeclaringModel, TNewPivotModel, TAccessor>\n     */\n    public function using($class)\n    {\n        $this->using = $class;\n\n        return $this;\n    }\n\n    /**\n     * Specify the custom pivot accessor to use for the relationship.\n     *\n     * @template TNewAccessor of string\n     *\n     * @param  TNewAccessor  $accessor\n     * @return $this\n     *\n     * @phpstan-this-out static<TRelatedModel, TDeclaringModel, TPivotModel, TNewAccessor>\n     */\n    public function as($accessor)\n    {\n        $this->accessor = $accessor;\n\n        return $this;\n    }\n\n    /**\n     * Set a where clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function wherePivot($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        $this->pivotWheres[] = func_get_args();\n\n        return $this->where($this->qualifyPivotColumn($column), $operator, $value, $boolean);\n    }\n\n    /**\n     * Set a \"where between\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  array  $values\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function wherePivotBetween($column, array $values, $boolean = 'and', $not = false)\n    {\n        return $this->whereBetween($this->qualifyPivotColumn($column), $values, $boolean, $not);\n    }\n\n    /**\n     * Set a \"or where between\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  array  $values\n     * @return $this\n     */\n    public function orWherePivotBetween($column, array $values)\n    {\n        return $this->wherePivotBetween($column, $values, 'or');\n    }\n\n    /**\n     * Set a \"where pivot not between\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  array  $values\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function wherePivotNotBetween($column, array $values, $boolean = 'and')\n    {\n        return $this->wherePivotBetween($column, $values, $boolean, true);\n    }\n\n    /**\n     * Set a \"or where not between\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  array  $values\n     * @return $this\n     */\n    public function orWherePivotNotBetween($column, array $values)\n    {\n        return $this->wherePivotBetween($column, $values, 'or', true);\n    }\n\n    /**\n     * Set a \"where in\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $values\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function wherePivotIn($column, $values, $boolean = 'and', $not = false)\n    {\n        $this->pivotWhereIns[] = func_get_args();\n\n        return $this->whereIn($this->qualifyPivotColumn($column), $values, $boolean, $not);\n    }\n\n    /**\n     * Set an \"or where\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWherePivot($column, $operator = null, $value = null)\n    {\n        return $this->wherePivot($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Set a where clause for a pivot table column.\n     *\n     * In addition, new pivot records will receive this value.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string, string>  $column\n     * @param  mixed  $value\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function withPivotValue($column, $value = null)\n    {\n        if (is_array($column)) {\n            foreach ($column as $name => $value) {\n                $this->withPivotValue($name, $value);\n            }\n\n            return $this;\n        }\n\n        if (is_null($value)) {\n            throw new InvalidArgumentException('The provided value may not be null.');\n        }\n\n        $this->pivotValues[] = compact('column', 'value');\n\n        return $this->wherePivot($column, '=', $value);\n    }\n\n    /**\n     * Set an \"or where in\" clause for a pivot table column.\n     *\n     * @param  string  $column\n     * @param  mixed  $values\n     * @return $this\n     */\n    public function orWherePivotIn($column, $values)\n    {\n        return $this->wherePivotIn($column, $values, 'or');\n    }\n\n    /**\n     * Set a \"where not in\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $values\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function wherePivotNotIn($column, $values, $boolean = 'and')\n    {\n        return $this->wherePivotIn($column, $values, $boolean, true);\n    }\n\n    /**\n     * Set an \"or where not in\" clause for a pivot table column.\n     *\n     * @param  string  $column\n     * @param  mixed  $values\n     * @return $this\n     */\n    public function orWherePivotNotIn($column, $values)\n    {\n        return $this->wherePivotNotIn($column, $values, 'or');\n    }\n\n    /**\n     * Set a \"where null\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function wherePivotNull($column, $boolean = 'and', $not = false)\n    {\n        $this->pivotWhereNulls[] = func_get_args();\n\n        return $this->whereNull($this->qualifyPivotColumn($column), $boolean, $not);\n    }\n\n    /**\n     * Set a \"where not null\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function wherePivotNotNull($column, $boolean = 'and')\n    {\n        return $this->wherePivotNull($column, $boolean, true);\n    }\n\n    /**\n     * Set a \"or where null\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  bool  $not\n     * @return $this\n     */\n    public function orWherePivotNull($column, $not = false)\n    {\n        return $this->wherePivotNull($column, 'or', $not);\n    }\n\n    /**\n     * Set a \"or where not null\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return $this\n     */\n    public function orWherePivotNotNull($column)\n    {\n        return $this->orWherePivotNull($column, true);\n    }\n\n    /**\n     * Add an \"order by\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  string  $direction\n     * @return $this\n     */\n    public function orderByPivot($column, $direction = 'asc')\n    {\n        return $this->orderBy($this->qualifyPivotColumn($column), $direction);\n    }\n\n    /**\n     * Add an \"order by desc\" clause for a pivot table column.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return $this\n     */\n    public function orderByPivotDesc($column)\n    {\n        return $this->orderBy($this->qualifyPivotColumn($column), 'desc');\n    }\n\n    /**\n     * Find a related model by its primary key or return a new instance of the related model.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>\n     *     : TRelatedModel&object{pivot: TPivotModel}\n     * )\n     */\n    public function findOrNew($id, $columns = ['*'])\n    {\n        if (is_null($instance = $this->find($id, $columns))) {\n            $instance = $this->related->newInstance();\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Get the first related model record matching the attributes or instantiate it.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function firstOrNew(array $attributes = [], array $values = [])\n    {\n        if (is_null($instance = $this->related->where($attributes)->first())) {\n            $instance = $this->related->newInstance(array_merge($attributes, $values));\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Get the first record matching the attributes. If the record is not found, create it.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @param  array  $joining\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function firstOrCreate(array $attributes = [], Closure|array $values = [], array $joining = [], $touch = true)\n    {\n        if (is_null($instance = (clone $this)->where($attributes)->first())) {\n            if (is_null($instance = $this->related->where($attributes)->first())) {\n                $instance = $this->createOrFirst($attributes, $values, $joining, $touch);\n            } else {\n                try {\n                    $this->getQuery()->withSavepointIfNeeded(fn () => $this->attach($instance, $joining, $touch));\n                } catch (UniqueConstraintViolationException) {\n                    // Nothing to do, the model was already attached...\n                }\n            }\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @param  array  $joining\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     *\n     * @throws \\Illuminate\\Database\\UniqueConstraintViolationException\n     */\n    public function createOrFirst(array $attributes = [], Closure|array $values = [], array $joining = [], $touch = true)\n    {\n        try {\n            return $this->getQuery()->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, value($values)), $joining, $touch));\n        } catch (UniqueConstraintViolationException $e) {\n            // ...\n        }\n\n        try {\n            return tap($this->related->where($attributes)->first() ?? throw $e, function ($instance) use ($joining, $touch) {\n                $this->getQuery()->withSavepointIfNeeded(fn () => $this->attach($instance, $joining, $touch));\n            });\n        } catch (UniqueConstraintViolationException $e) {\n            return (clone $this)->useWritePdo()->where($attributes)->first() ?? throw $e;\n        }\n    }\n\n    /**\n     * Create or update a related record matching the attributes, and fill it with values.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @param  array  $joining\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true)\n    {\n        return tap($this->firstOrCreate($attributes, $values, $joining, $touch), function ($instance) use ($values) {\n            if (! $instance->wasRecentlyCreated) {\n                $instance->fill($values);\n\n                $instance->save(['touch' => false]);\n            }\n        });\n    }\n\n    /**\n     * Find a related model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>\n     *     : (TRelatedModel&object{pivot: TPivotModel})|null\n     * )\n     */\n    public function find($id, $columns = ['*'])\n    {\n        if (! $id instanceof Model && (is_array($id) || $id instanceof Arrayable)) {\n            return $this->findMany($id, $columns);\n        }\n\n        return $this->where(\n            $this->getRelated()->getQualifiedKeyName(), '=', $this->parseId($id)\n        )->first($columns);\n    }\n\n    /**\n     * Find a sole related model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function findSole($id, $columns = ['*'])\n    {\n        return $this->where(\n            $this->getRelated()->getQualifiedKeyName(), '=', $this->parseId($id)\n        )->sole($columns);\n    }\n\n    /**\n     * Find multiple related models by their primary keys.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $ids\n     * @param  array  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function findMany($ids, $columns = ['*'])\n    {\n        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;\n\n        if (empty($ids)) {\n            return $this->getRelated()->newCollection();\n        }\n\n        return $this->whereKey(\n            $this->parseIds($ids)\n        )->get($columns);\n    }\n\n    /**\n     * Find a related model by its primary key or throw an exception.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>\n     *     : TRelatedModel&object{pivot: TPivotModel}\n     * )\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     */\n    public function findOrFail($id, $columns = ['*'])\n    {\n        $result = $this->find($id, $columns);\n\n        $id = $id instanceof Arrayable ? $id->toArray() : $id;\n\n        if (is_array($id)) {\n            if (count($result) === count(array_unique($id))) {\n                return $result;\n            }\n        } elseif (! is_null($result)) {\n            return $result;\n        }\n\n        throw (new ModelNotFoundException)->setModel(get_class($this->related), $id);\n    }\n\n    /**\n     * Find a related model by its primary key or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  mixed  $id\n     * @param  (\\Closure(): TValue)|list<string>|string  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel&object{pivot: TPivotModel}>|TValue\n     *     : (TRelatedModel&object{pivot: TPivotModel})|TValue\n     * )\n     */\n    public function findOr($id, $columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        $result = $this->find($id, $columns);\n\n        $id = $id instanceof Arrayable ? $id->toArray() : $id;\n\n        if (is_array($id)) {\n            if (count($result) === count(array_unique($id))) {\n                return $result;\n            }\n        } elseif (! is_null($result)) {\n            return $result;\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Add a basic where clause to the query, and return the first result.\n     *\n     * @param  \\Closure|string|array  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return (TRelatedModel&object{pivot: TPivotModel})|null\n     */\n    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        return $this->where($column, $operator, $value, $boolean)->first();\n    }\n\n    /**\n     * Execute the query and get the first result.\n     *\n     * @param  array  $columns\n     * @return (TRelatedModel&object{pivot: TPivotModel})|null\n     */\n    public function first($columns = ['*'])\n    {\n        $results = $this->limit(1)->get($columns);\n\n        return count($results) > 0 ? $results->first() : null;\n    }\n\n    /**\n     * Execute the query and get the first result or throw an exception.\n     *\n     * @param  array  $columns\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     */\n    public function firstOrFail($columns = ['*'])\n    {\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        throw (new ModelNotFoundException)->setModel(get_class($this->related));\n    }\n\n    /**\n     * Execute the query and get the first result or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  (\\Closure(): TValue)|list<string>  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return (TRelatedModel&object{pivot: TPivotModel})|TValue\n     */\n    public function firstOr($columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        return $callback();\n    }\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        return ! is_null($this->parent->{$this->parentKey})\n            ? $this->get()\n            : $this->related->newCollection();\n    }\n\n    /** @inheritDoc */\n    public function get($columns = ['*'])\n    {\n        // First we'll add the proper select columns onto the query so it is run with\n        // the proper columns. Then, we will get the results and hydrate our pivot\n        // models with the result of those columns as a separate model relation.\n        $builder = $this->query->applyScopes();\n\n        $columns = $builder->getQuery()->columns ? [] : $columns;\n\n        $models = $builder->addSelect(\n            $this->shouldSelect($columns)\n        )->getModels();\n\n        $this->hydratePivotRelation($models);\n\n        // If we actually found models we will also eager load any relationships that\n        // have been specified as needing to be eager loaded. This will solve the\n        // n + 1 query problem for the developer and also increase performance.\n        if (count($models) > 0) {\n            $models = $builder->eagerLoadRelations($models);\n        }\n\n        return $this->query->applyAfterQueryCallbacks(\n            $this->related->newCollection($models)\n        );\n    }\n\n    /**\n     * Get the select columns for the relation query.\n     *\n     * @param  array  $columns\n     * @return array\n     */\n    protected function shouldSelect(array $columns = ['*'])\n    {\n        if ($columns == ['*']) {\n            $columns = [$this->related->qualifyColumn('*')];\n        }\n\n        return array_merge($columns, $this->aliasedPivotColumns());\n    }\n\n    /**\n     * Get the pivot columns for the relation.\n     *\n     * \"pivot_\" is prefixed at each column for easy removal later.\n     *\n     * @return array\n     */\n    protected function aliasedPivotColumns()\n    {\n        return (new BaseCollection([\n            $this->foreignPivotKey,\n            $this->relatedPivotKey,\n            ...$this->pivotColumns,\n        ]))\n            ->map(fn ($column) => $this->qualifyPivotColumn($column).' as pivot_'.$column)\n            ->unique()\n            ->all();\n    }\n\n    /**\n     * Get a paginator for the \"select\" statement.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Pagination\\LengthAwarePaginator<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return tap($this->query->paginate($perPage, $columns, $pageName, $page), function ($paginator) {\n            $this->hydratePivotRelation($paginator->items());\n        });\n    }\n\n    /**\n     * Paginate the given query into a simple paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Contracts\\Pagination\\Paginator<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return tap($this->query->simplePaginate($perPage, $columns, $pageName, $page), function ($paginator) {\n            $this->hydratePivotRelation($paginator->items());\n        });\n    }\n\n    /**\n     * Paginate the given query into a cursor paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $cursorName\n     * @param  string|null  $cursor\n     * @return \\Illuminate\\Contracts\\Pagination\\CursorPaginator<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return tap($this->query->cursorPaginate($perPage, $columns, $cursorName, $cursor), function ($paginator) {\n            $this->hydratePivotRelation($paginator->items());\n        });\n    }\n\n    /**\n     * Chunk the results of the query.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @return bool\n     */\n    public function chunk($count, callable $callback)\n    {\n        return $this->prepareQueryBuilder()->chunk($count, function ($results, $page) use ($callback) {\n            $this->hydratePivotRelation($results->all());\n\n            return $callback($results, $page);\n        });\n    }\n\n    /**\n     * Chunk the results of a query by comparing numeric IDs.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkById($count, callable $callback, $column = null, $alias = null)\n    {\n        return $this->orderedChunkById($count, $callback, $column, $alias);\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n    {\n        return $this->orderedChunkById($count, $callback, $column, $alias, descending: true);\n    }\n\n    /**\n     * Execute a callback over each item while chunking by ID.\n     *\n     * @param  callable  $callback\n     * @param  int  $count\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function eachById(callable $callback, $count = 1000, $column = null, $alias = null)\n    {\n        return $this->chunkById($count, function ($results, $page) use ($callback, $count) {\n            foreach ($results as $key => $value) {\n                if ($callback($value, (($page - 1) * $count) + $key) === false) {\n                    return false;\n                }\n            }\n        }, $column, $alias);\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs in a given order.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @param  bool  $descending\n     * @return bool\n     */\n    public function orderedChunkById($count, callable $callback, $column = null, $alias = null, $descending = false)\n    {\n        $column ??= $this->getRelated()->qualifyColumn(\n            $this->getRelatedKeyName()\n        );\n\n        $alias ??= $this->getRelatedKeyName();\n\n        return $this->prepareQueryBuilder()->orderedChunkById($count, function ($results, $page) use ($callback) {\n            $this->hydratePivotRelation($results->all());\n\n            return $callback($results, $page);\n        }, $column, $alias, $descending);\n    }\n\n    /**\n     * Execute a callback over each item while chunking.\n     *\n     * @param  callable  $callback\n     * @param  int  $count\n     * @return bool\n     */\n    public function each(callable $callback, $count = 1000)\n    {\n        return $this->chunk($count, function ($results) use ($callback) {\n            foreach ($results as $key => $value) {\n                if ($callback($value, $key) === false) {\n                    return false;\n                }\n            }\n        });\n    }\n\n    /**\n     * Query lazily, by chunks of the given size.\n     *\n     * @param  int  $chunkSize\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function lazy($chunkSize = 1000)\n    {\n        return $this->prepareQueryBuilder()->lazy($chunkSize)->map(function ($model) {\n            $this->hydratePivotRelation([$model]);\n\n            return $model;\n        });\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function lazyById($chunkSize = 1000, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->qualifyColumn(\n            $this->getRelatedKeyName()\n        );\n\n        $alias ??= $this->getRelatedKeyName();\n\n        return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias)->map(function ($model) {\n            $this->hydratePivotRelation([$model]);\n\n            return $model;\n        });\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->qualifyColumn(\n            $this->getRelatedKeyName()\n        );\n\n        $alias ??= $this->getRelatedKeyName();\n\n        return $this->prepareQueryBuilder()->lazyByIdDesc($chunkSize, $column, $alias)->map(function ($model) {\n            $this->hydratePivotRelation([$model]);\n\n            return $model;\n        });\n    }\n\n    /**\n     * Get a lazy collection for the given query.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function cursor()\n    {\n        return $this->prepareQueryBuilder()->cursor()->map(function ($model) {\n            $this->hydratePivotRelation([$model]);\n\n            return $model;\n        });\n    }\n\n    /**\n     * Prepare the query builder for query execution.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    protected function prepareQueryBuilder()\n    {\n        return $this->query->addSelect($this->shouldSelect());\n    }\n\n    /**\n     * Hydrate the pivot table relationship on the models.\n     *\n     * @param  array<int, TRelatedModel>  $models\n     * @return void\n     */\n    protected function hydratePivotRelation(array $models)\n    {\n        // To hydrate the pivot relationship, we will just gather the pivot attributes\n        // and create a new Pivot model, which is basically a dynamic model that we\n        // will set the attributes, table, and connections on it so it will work.\n        foreach ($models as $model) {\n            $model->setRelation($this->accessor, $this->newExistingPivot(\n                $this->migratePivotAttributes($model)\n            ));\n        }\n    }\n\n    /**\n     * Get the pivot attributes from a model.\n     *\n     * @param  TRelatedModel  $model\n     * @return array\n     */\n    protected function migratePivotAttributes(Model $model)\n    {\n        $values = [];\n\n        foreach ($model->getAttributes() as $key => $value) {\n            // To get the pivots attributes we will just take any of the attributes which\n            // begin with \"pivot_\" and add those to this arrays, as well as unsetting\n            // them from the parent's models since they exist in a different table.\n            if (str_starts_with($key, 'pivot_')) {\n                $values[substr($key, 6)] = $value;\n\n                unset($model->$key);\n            }\n        }\n\n        return $values;\n    }\n\n    /**\n     * If we're touching the parent model, touch.\n     *\n     * @return void\n     */\n    public function touchIfTouching()\n    {\n        if ($this->touchingParent()) {\n            $this->getParent()->touch();\n        }\n\n        if ($this->getParent()->touches($this->relationName)) {\n            $this->touch();\n        }\n    }\n\n    /**\n     * Determine if we should touch the parent on sync.\n     *\n     * @return bool\n     */\n    protected function touchingParent()\n    {\n        return $this->getRelated()->touches($this->guessInverseRelation());\n    }\n\n    /**\n     * Attempt to guess the name of the inverse of the relation.\n     *\n     * @return string\n     */\n    protected function guessInverseRelation()\n    {\n        return Str::camel(Str::pluralStudly(class_basename($this->getParent())));\n    }\n\n    /**\n     * Touch all of the related models for the relationship.\n     *\n     * E.g.: Touch all roles associated with this user.\n     *\n     * @return void\n     */\n    public function touch()\n    {\n        if ($this->related->isIgnoringTouch()) {\n            return;\n        }\n\n        $columns = [\n            $this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(),\n        ];\n\n        // If we actually have IDs for the relation, we will run the query to update all\n        // the related model's timestamps, to make sure these all reflect the changes\n        // to the parent models. This will help us keep any caching synced up here.\n        if (count($ids = $this->allRelatedIds()) > 0) {\n            $this->getRelated()->newQueryWithoutRelationships()->whereKey($ids)->update($columns);\n        }\n    }\n\n    /**\n     * Get all of the IDs for the related models.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, int|string>\n     */\n    public function allRelatedIds()\n    {\n        return $this->newPivotQuery()->pluck($this->relatedPivotKey);\n    }\n\n    /**\n     * Save a new model and attach it to the parent model.\n     *\n     * @param  TRelatedModel  $model\n     * @param  array  $pivotAttributes\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function save(Model $model, array $pivotAttributes = [], $touch = true)\n    {\n        $model->save(['touch' => false]);\n\n        $this->attach($model, $pivotAttributes, $touch);\n\n        return $model;\n    }\n\n    /**\n     * Save a new model without raising any events and attach it to the parent model.\n     *\n     * @param  TRelatedModel  $model\n     * @param  array  $pivotAttributes\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function saveQuietly(Model $model, array $pivotAttributes = [], $touch = true)\n    {\n        return Model::withoutEvents(function () use ($model, $pivotAttributes, $touch) {\n            return $this->save($model, $pivotAttributes, $touch);\n        });\n    }\n\n    /**\n     * Save an array of new models and attach them to the parent model.\n     *\n     * @template TContainer of \\Illuminate\\Support\\Collection<array-key, TRelatedModel>|array<array-key, TRelatedModel>\n     *\n     * @param  TContainer  $models\n     * @param  array  $pivotAttributes\n     * @return TContainer\n     */\n    public function saveMany($models, array $pivotAttributes = [])\n    {\n        foreach ($models as $key => $model) {\n            $this->save($model, (array) ($pivotAttributes[$key] ?? []), false);\n        }\n\n        $this->touchIfTouching();\n\n        return $models;\n    }\n\n    /**\n     * Save an array of new models without raising any events and attach them to the parent model.\n     *\n     * @template TContainer of \\Illuminate\\Support\\Collection<array-key, TRelatedModel>|array<array-key, TRelatedModel>\n     *\n     * @param  TContainer  $models\n     * @param  array  $pivotAttributes\n     * @return TContainer\n     */\n    public function saveManyQuietly($models, array $pivotAttributes = [])\n    {\n        return Model::withoutEvents(function () use ($models, $pivotAttributes) {\n            return $this->saveMany($models, $pivotAttributes);\n        });\n    }\n\n    /**\n     * Create a new instance of the related model.\n     *\n     * @param  array  $attributes\n     * @param  array  $joining\n     * @param  bool  $touch\n     * @return TRelatedModel&object{pivot: TPivotModel}\n     */\n    public function create(array $attributes = [], array $joining = [], $touch = true)\n    {\n        $attributes = array_merge($this->getQuery()->pendingAttributes, $attributes);\n\n        $instance = $this->related->newInstance($attributes);\n\n        // Once we save the related model, we need to attach it to the base model via\n        // through intermediate table so we'll use the existing \"attach\" method to\n        // accomplish this which will insert the record and any more attributes.\n        $instance->save(['touch' => false]);\n\n        $this->attach($instance, $joining, $touch);\n\n        return $instance;\n    }\n\n    /**\n     * Create an array of new instances of the related models.\n     *\n     * @param  iterable  $records\n     * @param  array  $joinings\n     * @return array<int, TRelatedModel&object{pivot: TPivotModel}>\n     */\n    public function createMany(iterable $records, array $joinings = [])\n    {\n        $instances = [];\n\n        foreach ($records as $key => $record) {\n            $instances[] = $this->create($record, (array) ($joinings[$key] ?? []), false);\n        }\n\n        $this->touchIfTouching();\n\n        return $instances;\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($parentQuery->getQuery()->from == $query->getQuery()->from) {\n            return $this->getRelationExistenceQueryForSelfJoin($query, $parentQuery, $columns);\n        }\n\n        $this->performJoin($query);\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /**\n     * Add the constraints for a relationship query on the same table.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQueryForSelfJoin(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        $query->select($columns);\n\n        $query->from($this->related->getTable().' as '.$hash = $this->getRelationCountHash());\n\n        $this->related->setTable($hash);\n\n        $this->performJoin($query);\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /**\n     * Alias to set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function take($value)\n    {\n        return $this->limit($value);\n    }\n\n    /**\n     * Set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function limit($value)\n    {\n        if ($this->parent->exists) {\n            $this->query->limit($value);\n        } else {\n            $column = $this->getExistenceCompareKey();\n\n            $grammar = $this->query->getQuery()->getGrammar();\n\n            if ($grammar instanceof MySqlGrammar && $grammar->useLegacyGroupLimit($this->query->getQuery())) {\n                $column = 'pivot_'.last(explode('.', $column));\n            }\n\n            $this->query->groupLimit($value, $column);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the key for comparing against the parent key in \"has\" query.\n     *\n     * @return string\n     */\n    public function getExistenceCompareKey()\n    {\n        return $this->getQualifiedForeignPivotKeyName();\n    }\n\n    /**\n     * Specify that the pivot table has creation and update timestamps.\n     *\n     * @param  string|null|false  $createdAt\n     * @param  string|null|false  $updatedAt\n     * @return $this\n     */\n    public function withTimestamps($createdAt = null, $updatedAt = null)\n    {\n        $this->pivotCreatedAt = $createdAt !== false ? $createdAt : null;\n        $this->pivotUpdatedAt = $updatedAt !== false ? $updatedAt : null;\n\n        $pivots = array_filter([\n            $createdAt !== false ? $this->createdAt() : null,\n            $updatedAt !== false ? $this->updatedAt() : null,\n        ]);\n\n        $this->withTimestamps = ! empty($pivots);\n\n        return $this->withTimestamps ? $this->withPivot($pivots) : $this;\n    }\n\n    /**\n     * Get the name of the \"created at\" column.\n     *\n     * @return string\n     */\n    public function createdAt()\n    {\n        return $this->pivotCreatedAt ?? $this->parent->getCreatedAtColumn() ?? Model::CREATED_AT;\n    }\n\n    /**\n     * Get the name of the \"updated at\" column.\n     *\n     * @return string\n     */\n    public function updatedAt()\n    {\n        return $this->pivotUpdatedAt ?? $this->parent->getUpdatedAtColumn() ?? Model::UPDATED_AT;\n    }\n\n    /**\n     * Get the foreign key for the relation.\n     *\n     * @return string\n     */\n    public function getForeignPivotKeyName()\n    {\n        return $this->foreignPivotKey;\n    }\n\n    /**\n     * Get the fully-qualified foreign key for the relation.\n     *\n     * @return string\n     */\n    public function getQualifiedForeignPivotKeyName()\n    {\n        return $this->qualifyPivotColumn($this->foreignPivotKey);\n    }\n\n    /**\n     * Get the \"related key\" for the relation.\n     *\n     * @return string\n     */\n    public function getRelatedPivotKeyName()\n    {\n        return $this->relatedPivotKey;\n    }\n\n    /**\n     * Get the fully-qualified \"related key\" for the relation.\n     *\n     * @return string\n     */\n    public function getQualifiedRelatedPivotKeyName()\n    {\n        return $this->qualifyPivotColumn($this->relatedPivotKey);\n    }\n\n    /**\n     * Get the parent key for the relationship.\n     *\n     * @return string\n     */\n    public function getParentKeyName()\n    {\n        return $this->parentKey;\n    }\n\n    /**\n     * Get the fully-qualified parent key name for the relation.\n     *\n     * @return string\n     */\n    public function getQualifiedParentKeyName()\n    {\n        return $this->parent->qualifyColumn($this->parentKey);\n    }\n\n    /**\n     * Get the related key for the relationship.\n     *\n     * @return string\n     */\n    public function getRelatedKeyName()\n    {\n        return $this->relatedKey;\n    }\n\n    /**\n     * Get the fully-qualified related key name for the relation.\n     *\n     * @return string\n     */\n    public function getQualifiedRelatedKeyName()\n    {\n        return $this->related->qualifyColumn($this->relatedKey);\n    }\n\n    /**\n     * Get the intermediate table for the relationship.\n     *\n     * @return string\n     */\n    public function getTable()\n    {\n        return $this->table;\n    }\n\n    /**\n     * Get the relationship name for the relationship.\n     *\n     * @return string\n     */\n    public function getRelationName()\n    {\n        return $this->relationName;\n    }\n\n    /**\n     * Get the name of the pivot accessor for this relationship.\n     *\n     * @return TAccessor\n     */\n    public function getPivotAccessor()\n    {\n        return $this->accessor;\n    }\n\n    /**\n     * Get the pivot columns for this relationship.\n     *\n     * @return array\n     */\n    public function getPivotColumns()\n    {\n        return $this->pivotColumns;\n    }\n\n    /**\n     * Qualify the given column name by the pivot table.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return string|\\Illuminate\\Contracts\\Database\\Query\\Expression\n     */\n    public function qualifyPivotColumn($column)\n    {\n        if ($this->query->getQuery()->getGrammar()->isExpression($column)) {\n            return $column;\n        }\n\n        return str_contains($column, '.')\n            ? $column\n            : $this->table.'.'.$column;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/AsPivot.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\nuse Illuminate\\Support\\Str;\n\ntrait AsPivot\n{\n    /**\n     * The parent model of the relationship.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Model\n     */\n    public $pivotParent;\n\n    /**\n     * The related model of the relationship.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Model\n     */\n    public $pivotRelated;\n\n    /**\n     * The name of the foreign key column.\n     *\n     * @var string\n     */\n    protected $foreignKey;\n\n    /**\n     * The name of the \"other key\" column.\n     *\n     * @var string\n     */\n    protected $relatedKey;\n\n    /**\n     * Create a new pivot model instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @param  array  $attributes\n     * @param  string  $table\n     * @param  bool  $exists\n     * @return static\n     */\n    public static function fromAttributes(Model $parent, $attributes, $table, $exists = false)\n    {\n        $instance = new static;\n\n        $instance->timestamps = $instance->hasTimestampAttributes($attributes);\n\n        // The pivot model is a \"dynamic\" model since we will set the tables dynamically\n        // for the instance. This allows it work for any intermediate tables for the\n        // many to many relationship that are defined by this developer's classes.\n        $instance->setConnection($parent->getConnectionName())\n            ->setTable($table)\n            ->forceFill($attributes)\n            ->syncOriginal();\n\n        // We store off the parent instance so we will access the timestamp column names\n        // for the model, since the pivot model timestamps aren't easily configurable\n        // from the developer's point of view. We can use the parents to get these.\n        $instance->pivotParent = $parent;\n\n        $instance->exists = $exists;\n\n        return $instance;\n    }\n\n    /**\n     * Create a new pivot model from raw values returned from a query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @param  array  $attributes\n     * @param  string  $table\n     * @param  bool  $exists\n     * @return static\n     */\n    public static function fromRawAttributes(Model $parent, $attributes, $table, $exists = false)\n    {\n        $instance = static::fromAttributes($parent, [], $table, $exists);\n\n        $instance->timestamps = $instance->hasTimestampAttributes($attributes);\n\n        $instance->setRawAttributes(\n            array_merge($instance->getRawOriginal(), $attributes), $exists\n        );\n\n        return $instance;\n    }\n\n    /**\n     * Set the keys for a select query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSelectQuery($query)\n    {\n        if (isset($this->attributes[$this->getKeyName()])) {\n            return parent::setKeysForSelectQuery($query);\n        }\n\n        $query->where($this->foreignKey, $this->getOriginal(\n            $this->foreignKey, $this->getAttribute($this->foreignKey)\n        ));\n\n        return $query->where($this->relatedKey, $this->getOriginal(\n            $this->relatedKey, $this->getAttribute($this->relatedKey)\n        ));\n    }\n\n    /**\n     * Set the keys for a save update query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSaveQuery($query)\n    {\n        return $this->setKeysForSelectQuery($query);\n    }\n\n    /**\n     * Delete the pivot model record from the database.\n     *\n     * @return int\n     */\n    public function delete()\n    {\n        if (isset($this->attributes[$this->getKeyName()])) {\n            return (int) parent::delete();\n        }\n\n        if ($this->fireModelEvent('deleting') === false) {\n            return 0;\n        }\n\n        $this->touchOwners();\n\n        return tap($this->getDeleteQuery()->delete(), function () {\n            $this->exists = false;\n\n            $this->fireModelEvent('deleted', false);\n        });\n    }\n\n    /**\n     * Get the query builder for a delete operation on the pivot.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function getDeleteQuery()\n    {\n        return $this->newQueryWithoutRelationships()->where([\n            $this->foreignKey => $this->getOriginal($this->foreignKey, $this->getAttribute($this->foreignKey)),\n            $this->relatedKey => $this->getOriginal($this->relatedKey, $this->getAttribute($this->relatedKey)),\n        ]);\n    }\n\n    /**\n     * Get the table associated with the model.\n     *\n     * @return string\n     */\n    public function getTable()\n    {\n        if (! isset($this->table) && (! $this instanceof MorphPivot)) {\n            $this->setTable(str_replace(\n                '\\\\', '', Str::snake(Str::singular(class_basename($this)))\n            ));\n        }\n\n        return parent::getTable();\n    }\n\n    /**\n     * Get the foreign key column name.\n     *\n     * @return string\n     */\n    public function getForeignKey()\n    {\n        return $this->foreignKey;\n    }\n\n    /**\n     * Get the \"related key\" column name.\n     *\n     * @return string\n     */\n    public function getRelatedKey()\n    {\n        return $this->relatedKey;\n    }\n\n    /**\n     * Get the \"related key\" column name.\n     *\n     * @return string\n     */\n    public function getOtherKey()\n    {\n        return $this->getRelatedKey();\n    }\n\n    /**\n     * Set the key names for the pivot model instance.\n     *\n     * @param  string  $foreignKey\n     * @param  string  $relatedKey\n     * @return $this\n     */\n    public function setPivotKeys($foreignKey, $relatedKey)\n    {\n        $this->foreignKey = $foreignKey;\n\n        $this->relatedKey = $relatedKey;\n\n        return $this;\n    }\n\n    /**\n     * Set the related model of the relationship.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $related\n     * @return $this\n     */\n    public function setRelatedModel(?Model $related = null)\n    {\n        $this->pivotRelated = $related;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the pivot model or given attributes has timestamp attributes.\n     *\n     * @param  array|null  $attributes\n     * @return bool\n     */\n    public function hasTimestampAttributes($attributes = null)\n    {\n        return ($createdAt = $this->getCreatedAtColumn()) !== null\n            && array_key_exists($createdAt, $attributes ?? $this->attributes);\n    }\n\n    /**\n     * Get the name of the \"created at\" column.\n     *\n     * @return string\n     */\n    public function getCreatedAtColumn()\n    {\n        return $this->pivotParent\n            ? $this->pivotParent->getCreatedAtColumn()\n            : parent::getCreatedAtColumn();\n    }\n\n    /**\n     * Get the name of the \"updated at\" column.\n     *\n     * @return string\n     */\n    public function getUpdatedAtColumn()\n    {\n        return $this->pivotParent\n            ? $this->pivotParent->getUpdatedAtColumn()\n            : parent::getUpdatedAtColumn();\n    }\n\n    /**\n     * Get the queueable identity for the entity.\n     *\n     * @return mixed\n     */\n    public function getQueueableId()\n    {\n        if (isset($this->attributes[$this->getKeyName()])) {\n            return $this->getKey();\n        }\n\n        return sprintf(\n            '%s:%s:%s:%s',\n            $this->foreignKey, $this->getAttribute($this->foreignKey),\n            $this->relatedKey, $this->getAttribute($this->relatedKey)\n        );\n    }\n\n    /**\n     * Get a new query to restore one or more models by their queueable IDs.\n     *\n     * @param  int[]|string[]|string  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryForRestoration($ids)\n    {\n        if (is_array($ids)) {\n            return $this->newQueryForCollectionRestoration($ids);\n        }\n\n        if (! str_contains($ids, ':')) {\n            return parent::newQueryForRestoration($ids);\n        }\n\n        $segments = explode(':', $ids);\n\n        return $this->newQueryWithoutScopes()\n            ->where($segments[0], $segments[1])\n            ->where($segments[2], $segments[3]);\n    }\n\n    /**\n     * Get a new query to restore multiple models by their queueable IDs.\n     *\n     * @param  int[]|string[]  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function newQueryForCollectionRestoration(array $ids)\n    {\n        $ids = array_values($ids);\n\n        if (! str_contains($ids[0], ':')) {\n            return parent::newQueryForRestoration($ids);\n        }\n\n        $query = $this->newQueryWithoutScopes();\n\n        foreach ($ids as $id) {\n            $segments = explode(':', $id);\n\n            $query->orWhere(function ($query) use ($segments) {\n                return $query->where($segments[0], $segments[1])\n                    ->where($segments[2], $segments[3]);\n            });\n        }\n\n        return $query;\n    }\n\n    /**\n     * Unset all the loaded relations for the instance.\n     *\n     * @return $this\n     */\n    public function unsetRelations()\n    {\n        $this->pivotParent = null;\n        $this->pivotRelated = null;\n        $this->relations = [];\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Query\\JoinClause;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\n\ntrait CanBeOneOfMany\n{\n    /**\n     * Determines whether the relationship is one-of-many.\n     *\n     * @var bool\n     */\n    protected $isOneOfMany = false;\n\n    /**\n     * The name of the relationship.\n     *\n     * @var string\n     */\n    protected $relationName;\n\n    /**\n     * The one of many inner join subselect query builder instance.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Builder<*>|null\n     */\n    protected $oneOfManySubQuery;\n\n    /**\n     * Add constraints for inner join subselect for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $query\n     * @param  string|null  $column\n     * @param  string|null  $aggregate\n     * @return void\n     */\n    abstract public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null);\n\n    /**\n     * Get the columns the determine the relationship groups.\n     *\n     * @return array|string\n     */\n    abstract public function getOneOfManySubQuerySelectColumns();\n\n    /**\n     * Add join query constraints for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinClause  $join\n     * @return void\n     */\n    abstract public function addOneOfManyJoinSubQueryConstraints(JoinClause $join);\n\n    /**\n     * Indicate that the relation is a single result of a larger one-to-many relationship.\n     *\n     * @param  string|array|null  $column\n     * @param  string|\\Closure|null  $aggregate\n     * @param  string|null  $relation\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null)\n    {\n        $this->isOneOfMany = true;\n\n        $this->relationName = $relation ?: $this->getDefaultOneOfManyJoinAlias(\n            $this->guessRelationship()\n        );\n\n        $keyName = $this->query->getModel()->getKeyName();\n\n        $columns = is_string($columns = $column) ? [\n            $column => $aggregate,\n            $keyName => $aggregate,\n        ] : $column;\n\n        if (! array_key_exists($keyName, $columns)) {\n            $columns[$keyName] = 'MAX';\n        }\n\n        if ($aggregate instanceof Closure) {\n            $closure = $aggregate;\n        }\n\n        foreach ($columns as $column => $aggregate) {\n            if (! in_array(strtolower($aggregate), ['min', 'max'])) {\n                throw new InvalidArgumentException(\"Invalid aggregate [{$aggregate}] used within ofMany relation. Available aggregates: MIN, MAX\");\n            }\n\n            $subQuery = $this->newOneOfManySubQuery(\n                $this->getOneOfManySubQuerySelectColumns(),\n                array_merge([$column], $previous['columns'] ?? []),\n                $aggregate,\n            );\n\n            if (isset($previous)) {\n                $this->addOneOfManyJoinSubQuery(\n                    $subQuery,\n                    $previous['subQuery'],\n                    $previous['columns'],\n                );\n            }\n\n            if (isset($closure)) {\n                $closure($subQuery);\n            }\n\n            if (! isset($previous)) {\n                $this->oneOfManySubQuery = $subQuery;\n            }\n\n            if (array_key_last($columns) == $column) {\n                $this->addOneOfManyJoinSubQuery(\n                    $this->query,\n                    $subQuery,\n                    array_merge([$column], $previous['columns'] ?? []),\n                );\n            }\n\n            $previous = [\n                'subQuery' => $subQuery,\n                'columns' => array_merge([$column], $previous['columns'] ?? []),\n            ];\n        }\n\n        $this->addConstraints();\n\n        $columns = $this->query->getQuery()->columns;\n\n        if (is_null($columns) || $columns === ['*']) {\n            $this->select([$this->qualifyColumn('*')]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the relation is the latest single result of a larger one-to-many relationship.\n     *\n     * @param  string|array|null  $column\n     * @param  string|null  $relation\n     * @return $this\n     */\n    public function latestOfMany($column = 'id', $relation = null)\n    {\n        return $this->ofMany(Collection::wrap($column)->mapWithKeys(function ($column) {\n            return [$column => 'MAX'];\n        })->all(), 'MAX', $relation);\n    }\n\n    /**\n     * Indicate that the relation is the oldest single result of a larger one-to-many relationship.\n     *\n     * @param  string|array|null  $column\n     * @param  string|null  $relation\n     * @return $this\n     */\n    public function oldestOfMany($column = 'id', $relation = null)\n    {\n        return $this->ofMany(Collection::wrap($column)->mapWithKeys(function ($column) {\n            return [$column => 'MIN'];\n        })->all(), 'MIN', $relation);\n    }\n\n    /**\n     * Get the default alias for the one of many inner join clause.\n     *\n     * @param  string  $relation\n     * @return string\n     */\n    protected function getDefaultOneOfManyJoinAlias($relation)\n    {\n        return $relation == $this->query->getModel()->getTable()\n            ? $relation.'_of_many'\n            : $relation;\n    }\n\n    /**\n     * Get a new query for the related model, grouping the query by the given column, often the foreign key of the relationship.\n     *\n     * @param  string|array  $groupBy\n     * @param  array<string>|null  $columns\n     * @param  string|null  $aggregate\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<*>\n     */\n    protected function newOneOfManySubQuery($groupBy, $columns = null, $aggregate = null)\n    {\n        $subQuery = $this->query->getModel()\n            ->newQuery()\n            ->withoutGlobalScopes($this->removedScopes());\n\n        foreach (Arr::wrap($groupBy) as $group) {\n            $subQuery->groupBy($this->qualifyRelatedColumn($group));\n        }\n\n        if (! is_null($columns)) {\n            foreach ($columns as $key => $column) {\n                $aggregatedColumn = $subQuery->getQuery()->grammar->wrap($subQuery->qualifyColumn($column));\n\n                if ($key === 0) {\n                    $aggregatedColumn = \"{$aggregate}({$aggregatedColumn})\";\n                } else {\n                    $aggregatedColumn = \"min({$aggregatedColumn})\";\n                }\n\n                $subQuery->selectRaw($aggregatedColumn.' as '.$subQuery->getQuery()->grammar->wrap($column.'_aggregate'));\n            }\n        }\n\n        $this->addOneOfManySubQueryConstraints($subQuery, column: null, aggregate: $aggregate);\n\n        return $subQuery;\n    }\n\n    /**\n     * Add the join subquery to the given query on the given column and the relationship's foreign key.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $parent\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $subQuery\n     * @param  array<string>  $on\n     * @return void\n     */\n    protected function addOneOfManyJoinSubQuery(Builder $parent, Builder $subQuery, $on)\n    {\n        $parent->beforeQuery(function ($parent) use ($subQuery, $on) {\n            $subQuery->applyBeforeQueryCallbacks();\n\n            $parent->joinSub($subQuery, $this->relationName, function ($join) use ($on) {\n                foreach ($on as $onColumn) {\n                    $join->on($this->qualifySubSelectColumn($onColumn.'_aggregate'), '=', $this->qualifyRelatedColumn($onColumn));\n                }\n\n                $this->addOneOfManyJoinSubQueryConstraints($join);\n            });\n        });\n    }\n\n    /**\n     * Merge the relationship query joins to the given query builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $query\n     * @return void\n     */\n    protected function mergeOneOfManyJoinsTo(Builder $query)\n    {\n        $query->getQuery()->beforeQueryCallbacks = $this->query->getQuery()->beforeQueryCallbacks;\n\n        $query->applyBeforeQueryCallbacks();\n    }\n\n    /**\n     * Get the query builder that will contain the relationship constraints.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<*>\n     */\n    protected function getRelationQuery()\n    {\n        return $this->isOneOfMany()\n            ? $this->oneOfManySubQuery\n            : $this->query;\n    }\n\n    /**\n     * Get the one of many inner join subselect builder instance.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<*>|void\n     */\n    public function getOneOfManySubQuery()\n    {\n        return $this->oneOfManySubQuery;\n    }\n\n    /**\n     * Get the qualified column name for the one-of-many relationship using the subselect join query's alias.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    public function qualifySubSelectColumn($column)\n    {\n        return $this->getRelationName().'.'.last(explode('.', $column));\n    }\n\n    /**\n     * Qualify related column using the related table name if it is not already qualified.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    protected function qualifyRelatedColumn($column)\n    {\n        return $this->query->getModel()->qualifyColumn($column);\n    }\n\n    /**\n     * Guess the \"hasOne\" relationship's name via backtrace.\n     *\n     * @return string\n     */\n    protected function guessRelationship()\n    {\n        return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];\n    }\n\n    /**\n     * Determine whether the relationship is a one-of-many relationship.\n     *\n     * @return bool\n     */\n    public function isOneOfMany()\n    {\n        return $this->isOneOfMany;\n    }\n\n    /**\n     * Get the name of the relationship.\n     *\n     * @return string\n     */\n    public function getRelationName()\n    {\n        return $this->relationName;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/ComparesRelatedModels.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations;\nuse Illuminate\\Database\\Eloquent\\Model;\n\ntrait ComparesRelatedModels\n{\n    /**\n     * Determine if the model is the related instance of the relationship.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $model\n     * @return bool\n     */\n    public function is($model)\n    {\n        $match = ! is_null($model) &&\n               $this->compareKeys($this->getParentKey(), $this->getRelatedKeyFrom($model)) &&\n               $this->related->getTable() === $model->getTable() &&\n               $this->related->getConnectionName() === $model->getConnectionName();\n\n        if ($match && $this instanceof SupportsPartialRelations && $this->isOneOfMany()) {\n            return $this->query\n                ->whereKey($model->getKey())\n                ->exists();\n        }\n\n        return $match;\n    }\n\n    /**\n     * Determine if the model is not the related instance of the relationship.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $model\n     * @return bool\n     */\n    public function isNot($model)\n    {\n        return ! $this->is($model);\n    }\n\n    /**\n     * Get the value of the parent model's key.\n     *\n     * @return mixed\n     */\n    abstract public function getParentKey();\n\n    /**\n     * Get the value of the model's related key.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @return mixed\n     */\n    abstract protected function getRelatedKeyFrom(Model $model);\n\n    /**\n     * Compare the parent key with the related key.\n     *\n     * @param  mixed  $parentKey\n     * @param  mixed  $relatedKey\n     * @return bool\n     */\n    protected function compareKeys($parentKey, $relatedKey)\n    {\n        if (empty($parentKey) || empty($relatedKey)) {\n            return false;\n        }\n\n        if (is_int($parentKey) || is_int($relatedKey)) {\n            return (int) $parentKey === (int) $relatedKey;\n        }\n\n        return $parentKey === $relatedKey;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithDictionary.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse InvalidArgumentException;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait InteractsWithDictionary\n{\n    /**\n     * Get a dictionary key attribute - casting it to a string if necessary.\n     *\n     * @param  mixed  $attribute\n     * @return string|int|null\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function getDictionaryKey($attribute)\n    {\n        if (is_null($attribute) || is_string($attribute) || is_int($attribute)) {\n            return $attribute;\n        }\n\n        if (is_object($attribute)) {\n            if (method_exists($attribute, '__toString')) {\n                return $attribute->__toString();\n            }\n\n            if ($attribute instanceof UnitEnum) {\n                return enum_value($attribute);\n            }\n\n            throw new InvalidArgumentException('Model attribute value is an object but does not have a __toString method.');\n        }\n\n        return (string) $attribute;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse BackedEnum;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Support\\Collection as BaseCollection;\n\ntrait InteractsWithPivotTable\n{\n    /**\n     * Toggles a model (or models) from the parent.\n     *\n     * Each existing model is detached, and non existing ones are attached.\n     *\n     * @param  mixed  $ids\n     * @param  bool  $touch\n     * @return array\n     */\n    public function toggle($ids, $touch = true)\n    {\n        $changes = [\n            'attached' => [], 'detached' => [],\n        ];\n\n        $records = $this->formatRecordsList($this->parseIds($ids));\n\n        // Next, we will determine which IDs should get removed from the join table by\n        // checking which of the given ID/records is in the list of current records\n        // and removing all of those rows from this \"intermediate\" joining table.\n        $detach = array_values(array_intersect(\n            $this->newPivotQuery()->pluck($this->relatedPivotKey)->all(),\n            array_keys($records)\n        ));\n\n        if (count($detach) > 0) {\n            $this->detach($detach, false);\n\n            $changes['detached'] = $this->castKeys($detach);\n        }\n\n        // Finally, for all of the records which were not \"detached\", we'll attach the\n        // records into the intermediate table. Then, we will add those attaches to\n        // this change list and get ready to return these results to the callers.\n        $attach = array_diff_key($records, array_flip($detach));\n\n        if (count($attach) > 0) {\n            $this->attach($attach, [], false);\n\n            $changes['attached'] = array_keys($attach);\n        }\n\n        // Once we have finished attaching or detaching the records, we will see if we\n        // have done any attaching or detaching, and if we have we will touch these\n        // relationships if they are configured to touch on any database updates.\n        if ($touch && (count($changes['attached']) ||\n                       count($changes['detached']))) {\n            $this->touchIfTouching();\n        }\n\n        return $changes;\n    }\n\n    /**\n     * Toggles a model (or models) from the parent within a transaction.\n     *\n     * @param  mixed  $ids\n     * @param  bool  $touch\n     * @return array\n     *\n     * @throws \\Throwable\n     */\n    public function toggleOrFail($ids, $touch = true)\n    {\n        return $this->parent->getConnection()->transaction(fn () => $this->toggle($ids, $touch));\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs without detaching.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array|int|string  $ids\n     * @return array{attached: array, detached: array, updated: array}\n     */\n    public function syncWithoutDetaching($ids)\n    {\n        return $this->sync($ids, false);\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs or collection of models.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array|int|string  $ids\n     * @param  bool  $detaching\n     * @return array{attached: array, detached: array, updated: array}\n     */\n    public function sync($ids, $detaching = true)\n    {\n        $changes = [\n            'attached' => [], 'detached' => [], 'updated' => [],\n        ];\n\n        $records = $this->formatRecordsList($this->parseIds($ids));\n\n        if (empty($records) && ! $detaching) {\n            return $changes;\n        }\n\n        // First we need to attach any of the associated models that are not currently\n        // in this joining table. We'll spin through the given IDs, checking to see\n        // if they exist in the array of current ones, and if not we will insert.\n        $current = $this->getCurrentlyAttachedPivots()\n            ->pluck($this->relatedPivotKey)->all();\n\n        // Next, we will take the differences of the currents and given IDs and detach\n        // all of the entities that exist in the \"current\" array but are not in the\n        // array of the new IDs given to the method which will complete the sync.\n        if ($detaching) {\n            $detach = array_diff($current, array_keys($records));\n\n            if (count($detach) > 0) {\n                $this->detach($detach, false);\n\n                $changes['detached'] = $this->castKeys($detach);\n            }\n        }\n\n        // Now we are finally ready to attach the new records. Note that we'll disable\n        // touching until after the entire operation is complete so we don't fire a\n        // ton of touch operations until we are totally done syncing the records.\n        $changes = array_merge(\n            $changes, $this->attachNew($records, $current, false)\n        );\n\n        // Once we have finished attaching or detaching the records, we will see if we\n        // have done any attaching or detaching, and if we have we will touch these\n        // relationships if they are configured to touch on any database updates.\n        if (count($changes['attached']) ||\n            count($changes['updated']) ||\n            count($changes['detached'])) {\n            $this->touchIfTouching();\n        }\n\n        return $changes;\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs or collection of models within a transaction.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array  $ids\n     * @param  bool  $detaching\n     * @return array{attached: array, detached: array, updated: array}\n     *\n     * @throws \\Throwable\n     */\n    public function syncOrFail($ids, $detaching = true)\n    {\n        return $this->parent->getConnection()->transaction(fn () => $this->sync($ids, $detaching));\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs without detaching within a transaction.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array  $ids\n     * @return array{attached: array, detached: array, updated: array}\n     *\n     * @throws \\Throwable\n     */\n    public function syncWithoutDetachingOrFail($ids)\n    {\n        return $this->syncOrFail($ids, false);\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs or collection of models with the given pivot values.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array|int|string  $ids\n     * @param  array  $values\n     * @param  bool  $detaching\n     * @return array{attached: array, detached: array, updated: array}\n     */\n    public function syncWithPivotValues($ids, array $values, bool $detaching = true)\n    {\n        return $this->sync((new BaseCollection($this->parseIds($ids)))->mapWithKeys(function ($id) use ($values) {\n            return [$id => $values];\n        }), $detaching);\n    }\n\n    /**\n     * Sync the intermediate tables with a list of IDs with the given pivot values within a transaction.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\Illuminate\\Database\\Eloquent\\Model|array|int|string  $ids\n     * @param  array  $values\n     * @param  bool  $detaching\n     * @return array{attached: array, detached: array, updated: array}\n     *\n     * @throws \\Throwable\n     */\n    public function syncWithPivotValuesOrFail($ids, array $values, bool $detaching = true)\n    {\n        return $this->parent->getConnection()->transaction(fn () => $this->syncWithPivotValues($ids, $values, $detaching));\n    }\n\n    /**\n     * Format the sync / toggle record list so that it is keyed by ID.\n     *\n     * @param  array  $records\n     * @return array\n     */\n    protected function formatRecordsList(array $records)\n    {\n        return (new BaseCollection($records))->mapWithKeys(function ($attributes, $id) {\n            if (! is_array($attributes)) {\n                [$id, $attributes] = [$attributes, []];\n            }\n\n            if ($id instanceof BackedEnum) {\n                $id = $id->value;\n            }\n\n            return [$id => $attributes];\n        })->all();\n    }\n\n    /**\n     * Attach all of the records that aren't in the given current records.\n     *\n     * @param  array  $records\n     * @param  array  $current\n     * @param  bool  $touch\n     * @return array\n     */\n    protected function attachNew(array $records, array $current, $touch = true)\n    {\n        $changes = ['attached' => [], 'updated' => []];\n\n        foreach ($records as $id => $attributes) {\n            // If the ID is not in the list of existing pivot IDs, we will insert a new pivot\n            // record, otherwise, we will just update this existing record on this joining\n            // table, so that the developers will easily update these records pain free.\n            if (! in_array($id, $current)) {\n                $this->attach($id, $attributes, $touch);\n\n                $changes['attached'][] = $this->castKey($id);\n            }\n\n            // Now we'll try to update an existing pivot record with the attributes that were\n            // given to the method. If the model is actually updated we will add it to the\n            // list of updated pivot records so we return them back out to the consumer.\n            elseif (count($attributes) > 0 &&\n                $this->updateExistingPivot($id, $attributes, $touch)) {\n                $changes['updated'][] = $this->castKey($id);\n            }\n        }\n\n        return $changes;\n    }\n\n    /**\n     * Update an existing pivot record on the table.\n     *\n     * @param  mixed  $id\n     * @param  array  $attributes\n     * @param  bool  $touch\n     * @return int\n     */\n    public function updateExistingPivot($id, array $attributes, $touch = true)\n    {\n        if ($this->using) {\n            return $this->updateExistingPivotUsingCustomClass($id, $attributes, $touch);\n        }\n\n        if ($this->hasPivotColumn($this->updatedAt())) {\n            $attributes = $this->addTimestampsToAttachment($attributes, true);\n        }\n\n        $updated = $this->newPivotStatementForId($id)->update(\n            $this->castAttributes($attributes)\n        );\n\n        if ($touch) {\n            $this->touchIfTouching();\n        }\n\n        return $updated;\n    }\n\n    /**\n     * Update an existing pivot record on the table within a transaction.\n     *\n     * @param  mixed  $id\n     * @param  array  $attributes\n     * @param  bool  $touch\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    public function updateExistingPivotOrFail($id, array $attributes, $touch = true)\n    {\n        return $this->parent->getConnection()->transaction(fn () => $this->updateExistingPivot($id, $attributes, $touch));\n    }\n\n    /**\n     * Update an existing pivot record on the table via a custom class.\n     *\n     * @param  mixed  $id\n     * @param  array  $attributes\n     * @param  bool  $touch\n     * @return int\n     */\n    protected function updateExistingPivotUsingCustomClass($id, array $attributes, $touch)\n    {\n        $pivot = $this->getCurrentlyAttachedPivotsForIds($id)->first();\n\n        $updated = $pivot ? $pivot->fill($attributes)->isDirty() : false;\n\n        if ($updated) {\n            $pivot->save();\n        }\n\n        if ($touch) {\n            $this->touchIfTouching();\n        }\n\n        return (int) $updated;\n    }\n\n    /**\n     * Attach a model to the parent.\n     *\n     * @param  mixed  $ids\n     * @param  array  $attributes\n     * @param  bool  $touch\n     * @return void\n     */\n    public function attach($ids, array $attributes = [], $touch = true)\n    {\n        if ($this->using) {\n            $this->attachUsingCustomClass($ids, $attributes);\n        } else {\n            // Here we will insert the attachment records into the pivot table. Once we have\n            // inserted the records, we will touch the relationships if necessary and the\n            // function will return. We can parse the IDs before inserting the records.\n            $this->newPivotStatement()->insert($this->formatAttachRecords(\n                $this->parseIds($ids), $attributes\n            ));\n        }\n\n        if ($touch) {\n            $this->touchIfTouching();\n        }\n    }\n\n    /**\n     * Attach a model to the parent within a transaction.\n     *\n     * @param  mixed  $ids\n     * @param  array  $attributes\n     * @param  bool  $touch\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function attachOrFail($ids, array $attributes = [], $touch = true)\n    {\n        $this->parent->getConnection()->transaction(fn () => $this->attach($ids, $attributes, $touch));\n    }\n\n    /**\n     * Attach a model to the parent using a custom class.\n     *\n     * @param  mixed  $ids\n     * @param  array  $attributes\n     * @return void\n     */\n    protected function attachUsingCustomClass($ids, array $attributes)\n    {\n        $records = $this->formatAttachRecords(\n            $this->parseIds($ids), $attributes\n        );\n\n        foreach ($records as $record) {\n            $this->newPivot($record, false)->save();\n        }\n    }\n\n    /**\n     * Create an array of records to insert into the pivot table.\n     *\n     * @param  array  $ids\n     * @param  array  $attributes\n     * @return array\n     */\n    protected function formatAttachRecords($ids, array $attributes)\n    {\n        $records = [];\n\n        $hasTimestamps = ($this->hasPivotColumn($this->createdAt()) ||\n                  $this->hasPivotColumn($this->updatedAt()));\n\n        // To create the attachment records, we will simply spin through the IDs given\n        // and create a new record to insert for each ID. Each ID may actually be a\n        // key in the array, with extra attributes to be placed in other columns.\n        foreach ($ids as $key => $value) {\n            $records[] = $this->formatAttachRecord(\n                $key, $value, $attributes, $hasTimestamps\n            );\n        }\n\n        return $records;\n    }\n\n    /**\n     * Create a full attachment record payload.\n     *\n     * @param  int  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @param  bool  $hasTimestamps\n     * @return array\n     */\n    protected function formatAttachRecord($key, $value, $attributes, $hasTimestamps)\n    {\n        [$id, $attributes] = $this->extractAttachIdAndAttributes($key, $value, $attributes);\n\n        return array_merge(\n            $this->baseAttachRecord($id, $hasTimestamps), $this->castAttributes($attributes)\n        );\n    }\n\n    /**\n     * Get the attach record ID and extra attributes.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return array\n     */\n    protected function extractAttachIdAndAttributes($key, $value, array $attributes)\n    {\n        return is_array($value)\n            ? [$key, array_merge($value, $attributes)]\n            : [$value, $attributes];\n    }\n\n    /**\n     * Create a new pivot attachment record.\n     *\n     * @param  int  $id\n     * @param  bool  $timed\n     * @return array\n     */\n    protected function baseAttachRecord($id, $timed)\n    {\n        $record[$this->relatedPivotKey] = $id;\n\n        $record[$this->foreignPivotKey] = $this->parent->{$this->parentKey};\n\n        // If the record needs to have creation and update timestamps, we will make\n        // them by calling the parent model's \"freshTimestamp\" method which will\n        // provide us with a fresh timestamp in this model's preferred format.\n        if ($timed) {\n            $record = $this->addTimestampsToAttachment($record);\n        }\n\n        foreach ($this->pivotValues as $value) {\n            $record[$value['column']] = $value['value'];\n        }\n\n        return $record;\n    }\n\n    /**\n     * Set the creation and update timestamps on an attach record.\n     *\n     * @param  array  $record\n     * @param  bool  $exists\n     * @return array\n     */\n    protected function addTimestampsToAttachment(array $record, $exists = false)\n    {\n        $fresh = $this->parent->freshTimestamp();\n\n        if ($this->using) {\n            $pivotModel = new $this->using;\n\n            $fresh = $pivotModel->fromDateTime($fresh);\n        }\n\n        if (! $exists && $this->hasPivotColumn($this->createdAt())) {\n            $record[$this->createdAt()] = $fresh;\n        }\n\n        if ($this->hasPivotColumn($this->updatedAt())) {\n            $record[$this->updatedAt()] = $fresh;\n        }\n\n        return $record;\n    }\n\n    /**\n     * Determine whether the given column is defined as a pivot column.\n     *\n     * @param  string  $column\n     * @return bool\n     */\n    public function hasPivotColumn($column)\n    {\n        return in_array($column, $this->pivotColumns);\n    }\n\n    /**\n     * Detach models from the relationship.\n     *\n     * @param  mixed  $ids\n     * @param  bool  $touch\n     * @return int\n     */\n    public function detach($ids = null, $touch = true)\n    {\n        if ($this->using) {\n            $results = $this->detachUsingCustomClass($ids);\n        } else {\n            $query = $this->newPivotQuery();\n\n            // If associated IDs were passed to the method we will only delete those\n            // associations, otherwise all of the association ties will be broken.\n            // We'll return the numbers of affected rows when we do the deletes.\n            if (! is_null($ids)) {\n                $ids = $this->parseIds($ids);\n\n                if (empty($ids)) {\n                    return 0;\n                }\n\n                $query->whereIn($this->getQualifiedRelatedPivotKeyName(), (array) $ids);\n            }\n\n            // Once we have all of the conditions set on the statement, we are ready\n            // to run the delete on the pivot table. Then, if the touch parameter\n            // is true, we will go ahead and touch all related models to sync.\n            $results = $query->delete();\n        }\n\n        if ($touch) {\n            $this->touchIfTouching();\n        }\n\n        return $results;\n    }\n\n    /**\n     * Detach models from the relationship within a transaction.\n     *\n     * @param  mixed  $ids\n     * @param  bool  $touch\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    public function detachOrFail($ids = null, $touch = true)\n    {\n        return $this->parent->getConnection()->transaction(fn () => $this->detach($ids, $touch));\n    }\n\n    /**\n     * Detach models from the relationship using a custom class.\n     *\n     * @param  mixed  $ids\n     * @return int\n     */\n    protected function detachUsingCustomClass($ids)\n    {\n        $results = 0;\n\n        $records = $this->getCurrentlyAttachedPivotsForIds($ids);\n\n        foreach ($records as $record) {\n            $results += $record->delete();\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get the pivot models that are currently attached.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getCurrentlyAttachedPivots()\n    {\n        return $this->getCurrentlyAttachedPivotsForIds();\n    }\n\n    /**\n     * Get the pivot models that are currently attached, filtered by related model keys.\n     *\n     * @param  mixed  $ids\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getCurrentlyAttachedPivotsForIds($ids = null)\n    {\n        return $this->newPivotQuery()\n            ->when(! is_null($ids), fn ($query) => $query->whereIn(\n                $this->getQualifiedRelatedPivotKeyName(), $this->parseIds($ids)\n            ))\n            ->get()\n            ->map(function ($record) {\n                $class = $this->using ?: Pivot::class;\n\n                $pivot = $class::fromRawAttributes($this->parent, (array) $record, $this->getTable(), true);\n\n                return $pivot\n                    ->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey)\n                    ->setRelatedModel($this->related);\n            });\n    }\n\n    /**\n     * Create a new pivot model instance.\n     *\n     * @param  array  $attributes\n     * @param  bool  $exists\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Pivot\n     */\n    public function newPivot(array $attributes = [], $exists = false)\n    {\n        $attributes = array_merge(array_column($this->pivotValues, 'value', 'column'), $attributes);\n\n        $pivot = $this->related->newPivot(\n            $this->parent, $attributes, $this->table, $exists, $this->using\n        );\n\n        return $pivot\n            ->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey)\n            ->setRelatedModel($this->related);\n    }\n\n    /**\n     * Create a new existing pivot model instance.\n     *\n     * @param  array  $attributes\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\Pivot\n     */\n    public function newExistingPivot(array $attributes = [])\n    {\n        return $this->newPivot($attributes, true);\n    }\n\n    /**\n     * Get a new plain query builder for the pivot table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function newPivotStatement()\n    {\n        return $this->query->getQuery()->newQuery()->from($this->table);\n    }\n\n    /**\n     * Get a new pivot statement for a given \"other\" ID.\n     *\n     * @param  mixed  $id\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function newPivotStatementForId($id)\n    {\n        return $this->newPivotQuery()->whereIn($this->getQualifiedRelatedPivotKeyName(), $this->parseIds($id));\n    }\n\n    /**\n     * Create a new query builder for the pivot table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function newPivotQuery()\n    {\n        $query = $this->newPivotStatement();\n\n        foreach ($this->pivotWheres as $arguments) {\n            $query->where(...$arguments);\n        }\n\n        foreach ($this->pivotWhereIns as $arguments) {\n            $query->whereIn(...$arguments);\n        }\n\n        foreach ($this->pivotWhereNulls as $arguments) {\n            $query->whereNull(...$arguments);\n        }\n\n        return $query->where($this->getQualifiedForeignPivotKeyName(), $this->parent->{$this->parentKey});\n    }\n\n    /**\n     * Set the columns on the pivot table to retrieve.\n     *\n     * @param  mixed  $columns\n     * @return $this\n     */\n    public function withPivot($columns)\n    {\n        $this->pivotColumns = array_merge(\n            $this->pivotColumns, is_array($columns) ? $columns : func_get_args()\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get all of the IDs from the given mixed value.\n     *\n     * @param  mixed  $value\n     * @return array\n     */\n    protected function parseIds($value)\n    {\n        if ($value instanceof Model) {\n            return [$value->{$this->relatedKey}];\n        }\n\n        if ($value instanceof EloquentCollection) {\n            return $value->pluck($this->relatedKey)->all();\n        }\n\n        if ($value instanceof BaseCollection || is_array($value)) {\n            return (new BaseCollection($value))\n                ->map(fn ($item) => $item instanceof Model ? $item->{$this->relatedKey} : $item)\n                ->all();\n        }\n\n        return (array) $value;\n    }\n\n    /**\n     * Get the ID from the given mixed value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function parseId($value)\n    {\n        return $value instanceof Model ? $value->{$this->relatedKey} : $value;\n    }\n\n    /**\n     * Cast the given keys to integers if they are numeric and string otherwise.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    protected function castKeys(array $keys)\n    {\n        return array_map(function ($v) {\n            return $this->castKey($v);\n        }, $keys);\n    }\n\n    /**\n     * Cast the given key to convert to primary key type.\n     *\n     * @param  mixed  $key\n     * @return mixed\n     */\n    protected function castKey($key)\n    {\n        return $this->getTypeSwapValue(\n            $this->related->getKeyType(),\n            $key\n        );\n    }\n\n    /**\n     * Cast the given pivot attributes.\n     *\n     * @param  array  $attributes\n     * @return array\n     */\n    protected function castAttributes($attributes)\n    {\n        return $this->using\n            ? $this->newPivot()->fill($attributes)->getAttributes()\n            : $attributes;\n    }\n\n    /**\n     * Converts a given value to a given type value.\n     *\n     * @param  string  $type\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function getTypeSwapValue($type, $value)\n    {\n        return match (strtolower($type)) {\n            'int', 'integer' => (int) $value,\n            'real', 'float', 'double' => (float) $value,\n            'string' => (string) $value,\n            default => $value,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/SupportsDefaultModels.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ntrait SupportsDefaultModels\n{\n    /**\n     * Indicates if a default model instance should be used.\n     *\n     * Alternatively, may be a Closure or array.\n     *\n     * @var \\Closure|array|bool\n     */\n    protected $withDefault;\n\n    /**\n     * Make a new related instance for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Model\n     */\n    abstract protected function newRelatedInstanceFor(Model $parent);\n\n    /**\n     * Return a new model instance in case the relationship does not exist.\n     *\n     * @param  \\Closure|array|bool  $callback\n     * @return $this\n     */\n    public function withDefault($callback = true)\n    {\n        $this->withDefault = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the default value for this relation.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    protected function getDefaultFor(Model $parent)\n    {\n        if (! $this->withDefault) {\n            return;\n        }\n\n        $instance = $this->newRelatedInstanceFor($parent);\n\n        if (is_callable($this->withDefault)) {\n            return call_user_func($this->withDefault, $instance, $parent) ?: $instance;\n        }\n\n        if (is_array($this->withDefault)) {\n            $instance->forceFill($this->withDefault);\n        }\n\n        return $instance;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Concerns/SupportsInverseRelations.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\RelationNotFoundException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\n\ntrait SupportsInverseRelations\n{\n    /**\n     * The name of the inverse relationship.\n     *\n     * @var string|null\n     */\n    protected ?string $inverseRelationship = null;\n\n    /**\n     * Instruct Eloquent to link the related models back to the parent after the relationship query has run.\n     *\n     * Alias of \"chaperone\".\n     *\n     * @param  string|null  $relation\n     * @return $this\n     */\n    public function inverse(?string $relation = null)\n    {\n        return $this->chaperone($relation);\n    }\n\n    /**\n     * Instruct Eloquent to link the related models back to the parent after the relationship query has run.\n     *\n     * @param  string|null  $relation\n     * @return $this\n     */\n    public function chaperone(?string $relation = null)\n    {\n        $relation ??= $this->guessInverseRelation();\n\n        if (! $relation || ! $this->getModel()->isRelation($relation)) {\n            throw RelationNotFoundException::make($this->getModel(), $relation ?: 'null');\n        }\n\n        if ($this->inverseRelationship === null && $relation) {\n            $this->query->afterQuery(function ($result) {\n                return $this->inverseRelationship\n                    ? $this->applyInverseRelationToCollection($result, $this->getParent())\n                    : $result;\n            });\n        }\n\n        $this->inverseRelationship = $relation;\n\n        return $this;\n    }\n\n    /**\n     * Guess the name of the inverse relationship.\n     *\n     * @return string|null\n     */\n    protected function guessInverseRelation(): ?string\n    {\n        return Arr::first(\n            $this->getPossibleInverseRelations(),\n            fn ($relation) => $relation && $this->getModel()->isRelation($relation)\n        );\n    }\n\n    /**\n     * Get the possible inverse relations for the parent model.\n     *\n     * @return array<non-empty-string>\n     */\n    protected function getPossibleInverseRelations(): array\n    {\n        return array_filter(array_unique([\n            Str::camel(Str::beforeLast($this->getForeignKeyName(), $this->getParent()->getKeyName())),\n            Str::camel(Str::beforeLast($this->getParent()->getForeignKey(), $this->getParent()->getKeyName())),\n            Str::camel(class_basename($this->getParent())),\n            'owner',\n            get_class($this->getParent()) === get_class($this->getModel()) ? 'parent' : null,\n        ]));\n    }\n\n    /**\n     * Set the inverse relation on all models in a collection.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection  $models\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Collection\n     */\n    protected function applyInverseRelationToCollection($models, ?Model $parent = null)\n    {\n        $parent ??= $this->getParent();\n\n        foreach ($models as $model) {\n            $model instanceof Model && $this->applyInverseRelationToModel($model, $parent);\n        }\n\n        return $models;\n    }\n\n    /**\n     * Set the inverse relation on a model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|null  $parent\n     * @return \\Illuminate\\Database\\Eloquent\\Model\n     */\n    protected function applyInverseRelationToModel(Model $model, ?Model $parent = null)\n    {\n        if ($inverse = $this->getInverseRelationship()) {\n            $parent ??= $this->getParent();\n\n            $model->setRelation($inverse, $parent);\n        }\n\n        return $model;\n    }\n\n    /**\n     * Get the name of the inverse relationship.\n     *\n     * @return string|null\n     */\n    public function getInverseRelationship()\n    {\n        return $this->inverseRelationship;\n    }\n\n    /**\n     * Remove the chaperone / inverse relationship for this query.\n     *\n     * Alias of \"withoutChaperone\".\n     *\n     * @return $this\n     */\n    public function withoutInverse()\n    {\n        return $this->withoutChaperone();\n    }\n\n    /**\n     * Remove the chaperone / inverse relationship for this query.\n     *\n     * @return $this\n     */\n    public function withoutChaperone()\n    {\n        $this->inverseRelationship = null;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany<TRelatedModel, TDeclaringModel, \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>>\n */\nclass HasMany extends HasOneOrMany\n{\n    /**\n     * Convert the relationship to a \"has one\" relationship.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOne<TRelatedModel, TDeclaringModel>\n     */\n    public function one()\n    {\n        return HasOne::noConstraints(fn () => tap(\n            new HasOne(\n                $this->getQuery(),\n                $this->parent,\n                $this->foreignKey,\n                $this->localKey\n            ),\n            function ($hasOne) {\n                if ($inverse = $this->getInverseRelationship()) {\n                    $hasOne->inverse($inverse);\n                }\n            }\n        ));\n    }\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        return ! is_null($this->getParentKey())\n            ? $this->query->get()\n            : $this->related->newCollection();\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->related->newCollection());\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchMany($models, $results, $relation);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel, \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>>\n */\nclass HasManyThrough extends HasOneOrManyThrough\n{\n    use InteractsWithDictionary;\n\n    /**\n     * Convert the relationship to a \"has one through\" relationship.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>\n     */\n    public function one()\n    {\n        return HasOneThrough::noConstraints(fn () => new HasOneThrough(\n            tap($this->getQuery(), fn (Builder $query) => $query->getQuery()->joins = []),\n            $this->farParent,\n            $this->throughParent,\n            $this->getFirstKeyName(),\n            $this->getForeignKeyName(),\n            $this->getLocalKeyName(),\n            $this->getSecondLocalKeyName(),\n        ));\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->related->newCollection());\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        $dictionary = $this->buildDictionary($results);\n\n        // Once we have the dictionary we can simply spin through the parent models to\n        // link them up with their children using the keyed dictionary to make the\n        // matching very convenient and easy work. Then we'll just return them.\n        foreach ($models as $model) {\n            $key = $this->getDictionaryKey($model->getAttribute($this->localKey));\n\n            if ($key !== null && isset($dictionary[$key])) {\n                $model->setRelation(\n                    $relation, $this->related->newCollection($dictionary[$key])\n                );\n            }\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        return ! is_null($this->farParent->{$this->localKey})\n            ? $this->get()\n            : $this->related->newCollection();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasOne.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\CanBeOneOfMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\ComparesRelatedModels;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsDefaultModels;\nuse Illuminate\\Database\\Query\\JoinClause;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany<TRelatedModel, TDeclaringModel, ?TRelatedModel>\n */\nclass HasOne extends HasOneOrMany implements SupportsPartialRelations\n{\n    use ComparesRelatedModels, CanBeOneOfMany, SupportsDefaultModels;\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        if (is_null($this->getParentKey())) {\n            return $this->getDefaultFor($this->parent);\n        }\n\n        return $this->query->first() ?: $this->getDefaultFor($this->parent);\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->getDefaultFor($model));\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchOne($models, $results, $relation);\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($this->isOneOfMany()) {\n            $this->mergeOneOfManyJoinsTo($query);\n        }\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /**\n     * Add constraints for inner join subselect for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  string|null  $column\n     * @param  string|null  $aggregate\n     * @return void\n     */\n    public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)\n    {\n        $query->addSelect($this->foreignKey);\n    }\n\n    /**\n     * Get the columns that should be selected by the one of many subquery.\n     *\n     * @return array|string\n     */\n    public function getOneOfManySubQuerySelectColumns()\n    {\n        return $this->foreignKey;\n    }\n\n    /**\n     * Add join query constraints for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinClause  $join\n     * @return void\n     */\n    public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)\n    {\n        $join->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));\n    }\n\n    /**\n     * Make a new related instance for the given model.\n     *\n     * @param  TDeclaringModel  $parent\n     * @return TRelatedModel\n     */\n    public function newRelatedInstanceFor(Model $parent)\n    {\n        return tap($this->related->newInstance(), function ($instance) use ($parent) {\n            $instance->setAttribute($this->getForeignKeyName(), $parent->{$this->localKey});\n            $this->applyInverseRelationToModel($instance, $parent);\n        });\n    }\n\n    /**\n     * Get the value of the model's foreign key.\n     *\n     * @param  TRelatedModel  $model\n     * @return int|string\n     */\n    protected function getRelatedKeyFrom(Model $model)\n    {\n        return $model->getAttribute($this->getForeignKeyName());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsInverseRelations;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Arr;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TResult\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, TDeclaringModel, TResult>\n */\nabstract class HasOneOrMany extends Relation\n{\n    use InteractsWithDictionary, SupportsInverseRelations;\n\n    /**\n     * The foreign key of the parent model.\n     *\n     * @var string\n     */\n    protected $foreignKey;\n\n    /**\n     * The local key of the parent model.\n     *\n     * @var string\n     */\n    protected $localKey;\n\n    /**\n     * Create a new has one or many relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $foreignKey\n     * @param  string  $localKey\n     */\n    public function __construct(Builder $query, Model $parent, $foreignKey, $localKey)\n    {\n        $this->localKey = $localKey;\n        $this->foreignKey = $foreignKey;\n\n        parent::__construct($query, $parent);\n    }\n\n    /**\n     * Create and return an un-saved instance of the related model.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function make(array $attributes = [])\n    {\n        return tap($this->related->newInstance($attributes), function ($instance) {\n            $this->setForeignAttributesForCreate($instance);\n            $this->applyInverseRelationToModel($instance);\n        });\n    }\n\n    /**\n     * Create and return an un-saved instance of the related models.\n     *\n     * @param  iterable  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function makeMany($records)\n    {\n        $instances = $this->related->newCollection();\n\n        foreach ($records as $record) {\n            $instances->push($this->make($record));\n        }\n\n        return $instances;\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    public function addConstraints()\n    {\n        if (static::$constraints) {\n            $query = $this->getRelationQuery();\n\n            $query->where($this->foreignKey, '=', $this->getParentKey());\n\n            $query->whereNotNull($this->foreignKey);\n        }\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        $whereIn = $this->whereInMethod($this->parent, $this->localKey);\n\n        $this->whereInEager(\n            $whereIn,\n            $this->foreignKey,\n            $this->getKeys($models, $this->localKey),\n            $this->getRelationQuery()\n        );\n    }\n\n    /**\n     * Match the eagerly loaded results to their single parents.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @param  string  $relation\n     * @return array<int, TDeclaringModel>\n     */\n    public function matchOne(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchOneOrMany($models, $results, $relation, 'one');\n    }\n\n    /**\n     * Match the eagerly loaded results to their many parents.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @param  string  $relation\n     * @return array<int, TDeclaringModel>\n     */\n    public function matchMany(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchOneOrMany($models, $results, $relation, 'many');\n    }\n\n    /**\n     * Match the eagerly loaded results to their many parents.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @param  string  $relation\n     * @param  string  $type\n     * @return array<int, TDeclaringModel>\n     */\n    protected function matchOneOrMany(array $models, EloquentCollection $results, $relation, $type)\n    {\n        $dictionary = $this->buildDictionary($results);\n\n        // Once we have the dictionary we can simply spin through the parent models to\n        // link them up with their children using the keyed dictionary to make the\n        // matching very convenient and easy work. Then we'll just return them.\n        foreach ($models as $model) {\n            $key = $this->getDictionaryKey($model->getAttribute($this->localKey));\n\n            if ($key !== null && isset($dictionary[$key])) {\n                $related = $this->getRelationValue($dictionary, $key, $type);\n\n                $model->setRelation($relation, $related);\n\n                // Apply the inverse relation if we have one...\n                $type === 'one'\n                    ? $this->applyInverseRelationToModel($related, $model)\n                    : $this->applyInverseRelationToCollection($related, $model);\n            }\n        }\n\n        return $models;\n    }\n\n    /**\n     * Get the value of a relationship by one or many type.\n     *\n     * @param  array  $dictionary\n     * @param  string  $key\n     * @param  string  $type\n     * @return mixed\n     */\n    protected function getRelationValue(array $dictionary, $key, $type)\n    {\n        $value = $dictionary[$key];\n\n        return $type === 'one' ? reset($value) : $this->related->newCollection($value);\n    }\n\n    /**\n     * Build model dictionary keyed by the relation's foreign key.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @return array<array<array-key, TRelatedModel>>\n     */\n    protected function buildDictionary(EloquentCollection $results)\n    {\n        $foreign = $this->getForeignKeyName();\n\n        $dictionary = [];\n\n        $isAssociative = Arr::isAssoc($results->all());\n\n        foreach ($results as $key => $item) {\n            $pairKey = $this->getDictionaryKey($item->{$foreign});\n\n            if ($pairKey === null) {\n                continue;\n            }\n\n            if ($isAssociative) {\n                $dictionary[$pairKey][$key] = $item;\n            } else {\n                $dictionary[$pairKey][] = $item;\n            }\n        }\n\n        return $dictionary;\n    }\n\n    /**\n     * Find a model by its primary key or return a new instance of the related model.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel> : TRelatedModel)\n     */\n    public function findOrNew($id, $columns = ['*'])\n    {\n        if (is_null($instance = $this->find($id, $columns))) {\n            $instance = $this->related->newInstance();\n\n            $this->setForeignAttributesForCreate($instance);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Get the first related model record matching the attributes or instantiate it.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TRelatedModel\n     */\n    public function firstOrNew(array $attributes = [], array $values = [])\n    {\n        if (is_null($instance = $this->where($attributes)->first())) {\n            $instance = $this->related->newInstance(array_merge($attributes, $values));\n\n            $this->setForeignAttributesForCreate($instance);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Get the first record matching the attributes. If the record is not found, create it.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TRelatedModel\n     */\n    public function firstOrCreate(array $attributes = [], Closure|array $values = [])\n    {\n        if (is_null($instance = (clone $this)->where($attributes)->first())) {\n            $instance = $this->createOrFirst($attributes, $values);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\UniqueConstraintViolationException\n     */\n    public function createOrFirst(array $attributes = [], Closure|array $values = [])\n    {\n        try {\n            return $this->getQuery()->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, value($values))));\n        } catch (UniqueConstraintViolationException $e) {\n            return $this->useWritePdo()->where($attributes)->first() ?? throw $e;\n        }\n    }\n\n    /**\n     * Create or update a related record matching the attributes, and fill it with values.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TRelatedModel\n     */\n    public function updateOrCreate(array $attributes, array $values = [])\n    {\n        return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {\n            if (! $instance->wasRecentlyCreated) {\n                $instance->fill($values)->save();\n            }\n        });\n    }\n\n    /**\n     * Insert new records or update the existing ones.\n     *\n     * @param  array  $values\n     * @param  array|string  $uniqueBy\n     * @param  array|null  $update\n     * @return int\n     */\n    public function upsert(array $values, $uniqueBy, $update = null)\n    {\n        if (! empty($values) && ! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        foreach ($values as $key => $value) {\n            $values[$key][$this->getForeignKeyName()] = $this->getParentKey();\n        }\n\n        return $this->getQuery()->upsert($values, $uniqueBy, $update);\n    }\n\n    /**\n     * Attach a model instance to the parent model.\n     *\n     * @param  TRelatedModel  $model\n     * @return TRelatedModel|false\n     */\n    public function save(Model $model)\n    {\n        $this->setForeignAttributesForCreate($model);\n\n        return $model->save() ? $model : false;\n    }\n\n    /**\n     * Attach a model instance without raising any events to the parent model.\n     *\n     * @param  TRelatedModel  $model\n     * @return TRelatedModel|false\n     */\n    public function saveQuietly(Model $model)\n    {\n        return Model::withoutEvents(function () use ($model) {\n            return $this->save($model);\n        });\n    }\n\n    /**\n     * Attach a collection of models to the parent instance.\n     *\n     * @param  iterable<TRelatedModel>  $models\n     * @return iterable<TRelatedModel>\n     */\n    public function saveMany($models)\n    {\n        foreach ($models as $model) {\n            $this->save($model);\n        }\n\n        return $models;\n    }\n\n    /**\n     * Attach a collection of models to the parent instance without raising any events to the parent model.\n     *\n     * @param  iterable<TRelatedModel>  $models\n     * @return iterable<TRelatedModel>\n     */\n    public function saveManyQuietly($models)\n    {\n        return Model::withoutEvents(function () use ($models) {\n            return $this->saveMany($models);\n        });\n    }\n\n    /**\n     * Create a new instance of the related model.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function create(array $attributes = [])\n    {\n        return tap($this->related->newInstance($attributes), function ($instance) {\n            $this->setForeignAttributesForCreate($instance);\n\n            $instance->save();\n\n            $this->applyInverseRelationToModel($instance);\n        });\n    }\n\n    /**\n     * Create a new instance of the related model without raising any events to the parent model.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function createQuietly(array $attributes = [])\n    {\n        return Model::withoutEvents(fn () => $this->create($attributes));\n    }\n\n    /**\n     * Create a new instance of the related model. Allow mass-assignment.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function forceCreate(array $attributes = [])\n    {\n        $attributes[$this->getForeignKeyName()] = $this->getParentKey();\n\n        return $this->applyInverseRelationToModel($this->related->forceCreate($attributes));\n    }\n\n    /**\n     * Create a new instance of the related model with mass assignment without raising model events.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function forceCreateQuietly(array $attributes = [])\n    {\n        return Model::withoutEvents(fn () => $this->forceCreate($attributes));\n    }\n\n    /**\n     * Create a Collection of new instances of the related model.\n     *\n     * @param  iterable  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function createMany(iterable $records)\n    {\n        $instances = $this->related->newCollection();\n\n        foreach ($records as $record) {\n            $instances->push($this->create($record));\n        }\n\n        return $instances;\n    }\n\n    /**\n     * Create a Collection of new instances of the related model without raising any events to the parent model.\n     *\n     * @param  iterable  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function createManyQuietly(iterable $records)\n    {\n        return Model::withoutEvents(fn () => $this->createMany($records));\n    }\n\n    /**\n     * Create a Collection of new instances of the related model, allowing mass-assignment.\n     *\n     * @param  iterable  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function forceCreateMany(iterable $records)\n    {\n        $instances = $this->related->newCollection();\n\n        foreach ($records as $record) {\n            $instances->push($this->forceCreate($record));\n        }\n\n        return $instances;\n    }\n\n    /**\n     * Create a Collection of new instances of the related model, allowing mass-assignment and without raising any events to the parent model.\n     *\n     * @param  iterable  $records\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function forceCreateManyQuietly(iterable $records)\n    {\n        return Model::withoutEvents(fn () => $this->forceCreateMany($records));\n    }\n\n    /**\n     * Set the foreign ID for creating a related model.\n     *\n     * @param  TRelatedModel  $model\n     * @return void\n     */\n    protected function setForeignAttributesForCreate(Model $model)\n    {\n        $model->setAttribute($this->getForeignKeyName(), $this->getParentKey());\n\n        foreach ($this->getQuery()->pendingAttributes as $key => $value) {\n            $attributes ??= $model->getAttributes();\n\n            if (! array_key_exists($key, $attributes)) {\n                $model->setAttribute($key, $value);\n            }\n        }\n\n        $this->applyInverseRelationToModel($model);\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($query->getQuery()->from == $parentQuery->getQuery()->from) {\n            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);\n        }\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /**\n     * Add the constraints for a relationship query on the same table.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());\n\n        $query->getModel()->setTable($hash);\n\n        return $query->select($columns)->whereColumn(\n            $this->getQualifiedParentKeyName(), '=', $hash.'.'.$this->getForeignKeyName()\n        );\n    }\n\n    /**\n     * Alias to set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function take($value)\n    {\n        return $this->limit($value);\n    }\n\n    /**\n     * Set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function limit($value)\n    {\n        if ($this->parent->exists) {\n            $this->query->limit($value);\n        } else {\n            $this->query->groupLimit($value, $this->getExistenceCompareKey());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the key for comparing against the parent key in \"has\" query.\n     *\n     * @return string\n     */\n    public function getExistenceCompareKey()\n    {\n        return $this->getQualifiedForeignKeyName();\n    }\n\n    /**\n     * Get the key value of the parent's local key.\n     *\n     * @return mixed\n     */\n    public function getParentKey()\n    {\n        return $this->parent->getAttribute($this->localKey);\n    }\n\n    /**\n     * Get the fully-qualified parent key name.\n     *\n     * @return string\n     */\n    public function getQualifiedParentKeyName()\n    {\n        return $this->parent->qualifyColumn($this->localKey);\n    }\n\n    /**\n     * Get the plain foreign key.\n     *\n     * @return string\n     */\n    public function getForeignKeyName()\n    {\n        $segments = explode('.', $this->getQualifiedForeignKeyName());\n\n        return array_last($segments);\n    }\n\n    /**\n     * Get the foreign key for the relationship.\n     *\n     * @return string\n     */\n    public function getQualifiedForeignKeyName()\n    {\n        return $this->foreignKey;\n    }\n\n    /**\n     * Get the local key for the relationship.\n     *\n     * @return string\n     */\n    public function getLocalKeyName()\n    {\n        return $this->localKey;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Arr;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TResult\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\Relation<TRelatedModel, TIntermediateModel, TResult>\n */\nabstract class HasOneOrManyThrough extends Relation\n{\n    use InteractsWithDictionary;\n\n    /**\n     * The \"through\" parent model instance.\n     *\n     * @var TIntermediateModel\n     */\n    protected $throughParent;\n\n    /**\n     * The far parent model instance.\n     *\n     * @var TDeclaringModel\n     */\n    protected $farParent;\n\n    /**\n     * The near key on the relationship.\n     *\n     * @var string\n     */\n    protected $firstKey;\n\n    /**\n     * The far key on the relationship.\n     *\n     * @var string\n     */\n    protected $secondKey;\n\n    /**\n     * The local key on the relationship.\n     *\n     * @var string\n     */\n    protected $localKey;\n\n    /**\n     * The local key on the intermediary model.\n     *\n     * @var string\n     */\n    protected $secondLocalKey;\n\n    /**\n     * Create a new has many through relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $farParent\n     * @param  TIntermediateModel  $throughParent\n     * @param  string  $firstKey\n     * @param  string  $secondKey\n     * @param  string  $localKey\n     * @param  string  $secondLocalKey\n     */\n    public function __construct(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)\n    {\n        $this->localKey = $localKey;\n        $this->firstKey = $firstKey;\n        $this->secondKey = $secondKey;\n        $this->farParent = $farParent;\n        $this->throughParent = $throughParent;\n        $this->secondLocalKey = $secondLocalKey;\n\n        parent::__construct($query, $throughParent);\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    public function addConstraints()\n    {\n        $query = $this->getRelationQuery();\n\n        $this->performJoin($query);\n\n        if (static::$constraints) {\n            $localValue = $this->farParent[$this->localKey];\n\n            $query->where($this->getQualifiedFirstKeyName(), '=', $localValue);\n        }\n    }\n\n    /**\n     * Set the join clause on the query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>|null  $query\n     * @return void\n     */\n    protected function performJoin(?Builder $query = null)\n    {\n        $query ??= $this->query;\n\n        $farKey = $this->getQualifiedFarKeyName();\n\n        $query->join($this->throughParent->getTable(), $this->getQualifiedParentKeyName(), '=', $farKey);\n\n        if ($this->throughParentSoftDeletes()) {\n            $query->withGlobalScope('SoftDeletableHasManyThrough', function ($query) {\n                $query->whereNull($this->throughParent->getQualifiedDeletedAtColumn());\n            });\n        }\n    }\n\n    /**\n     * Get the fully-qualified parent key name.\n     *\n     * @return string\n     */\n    public function getQualifiedParentKeyName()\n    {\n        return $this->parent->qualifyColumn($this->secondLocalKey);\n    }\n\n    /**\n     * Determine whether \"through\" parent of the relation uses Soft Deletes.\n     *\n     * @return bool\n     */\n    public function throughParentSoftDeletes()\n    {\n        return $this->throughParent::isSoftDeletable();\n    }\n\n    /**\n     * Indicate that trashed \"through\" parents should be included in the query.\n     *\n     * @return $this\n     */\n    public function withTrashedParents()\n    {\n        $this->query->withoutGlobalScope('SoftDeletableHasManyThrough');\n\n        return $this;\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        $whereIn = $this->whereInMethod($this->farParent, $this->localKey);\n\n        $this->whereInEager(\n            $whereIn,\n            $this->getQualifiedFirstKeyName(),\n            $this->getKeys($models, $this->localKey),\n            $this->getRelationQuery(),\n        );\n    }\n\n    /**\n     * Build model dictionary keyed by the relation's foreign key.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @return array<array<array-key, TRelatedModel>>\n     */\n    protected function buildDictionary(EloquentCollection $results)\n    {\n        $dictionary = [];\n\n        $isAssociative = Arr::isAssoc($results->all());\n\n        // First we will create a dictionary of models keyed by the foreign key of the\n        // relationship as this will allow us to quickly access all of the related\n        // models without having to do nested looping which will be quite slow.\n        foreach ($results as $key => $result) {\n            if ($isAssociative) {\n                $dictionary[$result->laravel_through_key][$key] = $result;\n            } else {\n                $dictionary[$result->laravel_through_key][] = $result;\n            }\n        }\n\n        return $dictionary;\n    }\n\n    /**\n     * Get the first related model record matching the attributes or instantiate it.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TRelatedModel\n     */\n    public function firstOrNew(array $attributes = [], array $values = [])\n    {\n        if (! is_null($instance = $this->where($attributes)->first())) {\n            return $instance;\n        }\n\n        return $this->related->newInstance(array_merge($attributes, $values));\n    }\n\n    /**\n     * Get the first record matching the attributes. If the record is not found, create it.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TRelatedModel\n     */\n    public function firstOrCreate(array $attributes = [], Closure|array $values = [])\n    {\n        if (! is_null($instance = (clone $this)->where($attributes)->first())) {\n            return $instance;\n        }\n\n        return $this->createOrFirst(array_merge($attributes, value($values)));\n    }\n\n    /**\n     * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record.\n     *\n     * @param  array  $attributes\n     * @param  (\\Closure(): array)|array  $values\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\UniqueConstraintViolationException\n     */\n    public function createOrFirst(array $attributes = [], Closure|array $values = [])\n    {\n        try {\n            return $this->getQuery()->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, value($values))));\n        } catch (UniqueConstraintViolationException $exception) {\n            return $this->where($attributes)->first() ?? throw $exception;\n        }\n    }\n\n    /**\n     * Create or update a related record matching the attributes, and fill it with values.\n     *\n     * @param  array  $attributes\n     * @param  array  $values\n     * @return TRelatedModel\n     */\n    public function updateOrCreate(array $attributes, array $values = [])\n    {\n        return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {\n            if (! $instance->wasRecentlyCreated) {\n                $instance->fill($values)->save();\n            }\n        });\n    }\n\n    /**\n     * Add a basic where clause to the query, and return the first result.\n     *\n     * @param  \\Closure|string|array  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return TRelatedModel|null\n     */\n    public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        return $this->where($column, $operator, $value, $boolean)->first();\n    }\n\n    /**\n     * Execute the query and get the first related model.\n     *\n     * @param  array  $columns\n     * @return TRelatedModel|null\n     */\n    public function first($columns = ['*'])\n    {\n        $results = $this->limit(1)->get($columns);\n\n        return count($results) > 0 ? $results->first() : null;\n    }\n\n    /**\n     * Execute the query and get the first result or throw an exception.\n     *\n     * @param  array  $columns\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     */\n    public function firstOrFail($columns = ['*'])\n    {\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        throw (new ModelNotFoundException)->setModel(get_class($this->related));\n    }\n\n    /**\n     * Execute the query and get the first result or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  (\\Closure(): TValue)|list<string>  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return TRelatedModel|TValue\n     */\n    public function firstOr($columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        if (! is_null($model = $this->first($columns))) {\n            return $model;\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Find a related model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel> : TRelatedModel|null)\n     */\n    public function find($id, $columns = ['*'])\n    {\n        if (is_array($id) || $id instanceof Arrayable) {\n            return $this->findMany($id, $columns);\n        }\n\n        return $this->where(\n            $this->getRelated()->getQualifiedKeyName(), '=', $id\n        )->first($columns);\n    }\n\n    /**\n     * Find a sole related model by its primary key.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function findSole($id, $columns = ['*'])\n    {\n        return $this->where(\n            $this->getRelated()->getQualifiedKeyName(), '=', $id\n        )->sole($columns);\n    }\n\n    /**\n     * Find multiple related models by their primary keys.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $ids\n     * @param  array  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function findMany($ids, $columns = ['*'])\n    {\n        $ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;\n\n        if (empty($ids)) {\n            return $this->getRelated()->newCollection();\n        }\n\n        return $this->whereIn(\n            $this->getRelated()->getQualifiedKeyName(), $ids\n        )->get($columns);\n    }\n\n    /**\n     * Find a related model by its primary key or throw an exception.\n     *\n     * @param  mixed  $id\n     * @param  array  $columns\n     * @return ($id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>) ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel> : TRelatedModel)\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     */\n    public function findOrFail($id, $columns = ['*'])\n    {\n        $result = $this->find($id, $columns);\n\n        $id = $id instanceof Arrayable ? $id->toArray() : $id;\n\n        if (is_array($id)) {\n            if (count($result) === count(array_unique($id))) {\n                return $result;\n            }\n        } elseif (! is_null($result)) {\n            return $result;\n        }\n\n        throw (new ModelNotFoundException)->setModel(get_class($this->related), $id);\n    }\n\n    /**\n     * Find a related model by its primary key or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  mixed  $id\n     * @param  (\\Closure(): TValue)|list<string>|string  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return (\n     *     $id is (\\Illuminate\\Contracts\\Support\\Arrayable<array-key, mixed>|array<mixed>)\n     *     ? \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>|TValue\n     *     : TRelatedModel|TValue\n     * )\n     */\n    public function findOr($id, $columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        $result = $this->find($id, $columns);\n\n        $id = $id instanceof Arrayable ? $id->toArray() : $id;\n\n        if (is_array($id)) {\n            if (count($result) === count(array_unique($id))) {\n                return $result;\n            }\n        } elseif (! is_null($result)) {\n            return $result;\n        }\n\n        return $callback();\n    }\n\n    /** @inheritDoc */\n    public function get($columns = ['*'])\n    {\n        $builder = $this->prepareQueryBuilder($columns);\n\n        $models = $builder->getModels();\n\n        // If we actually found models we will also eager load any relationships that\n        // have been specified as needing to be eager loaded. This will solve the\n        // n + 1 query problem for the developer and also increase performance.\n        if (count($models) > 0) {\n            $models = $builder->eagerLoadRelations($models);\n        }\n\n        return $this->query->applyAfterQueryCallbacks(\n            $this->related->newCollection($models)\n        );\n    }\n\n    /**\n     * Get a paginator for the \"select\" statement.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Pagination\\LengthAwarePaginator\n     */\n    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return $this->query->paginate($perPage, $columns, $pageName, $page);\n    }\n\n    /**\n     * Paginate the given query into a simple paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Contracts\\Pagination\\Paginator\n     */\n    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return $this->query->simplePaginate($perPage, $columns, $pageName, $page);\n    }\n\n    /**\n     * Paginate the given query into a cursor paginator.\n     *\n     * @param  int|null  $perPage\n     * @param  array  $columns\n     * @param  string  $cursorName\n     * @param  string|null  $cursor\n     * @return \\Illuminate\\Contracts\\Pagination\\CursorPaginator\n     */\n    public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)\n    {\n        $this->query->addSelect($this->shouldSelect($columns));\n\n        return $this->query->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n    }\n\n    /**\n     * Set the select clause for the relation query.\n     *\n     * @param  array  $columns\n     * @return array\n     */\n    protected function shouldSelect(array $columns = ['*'])\n    {\n        if ($columns == ['*']) {\n            $columns = [$this->related->qualifyColumn('*')];\n        }\n\n        return array_merge($columns, [$this->getQualifiedFirstKeyName().' as laravel_through_key']);\n    }\n\n    /**\n     * Chunk the results of the query.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @return bool\n     */\n    public function chunk($count, callable $callback)\n    {\n        return $this->prepareQueryBuilder()->chunk($count, $callback);\n    }\n\n    /**\n     * Chunk the results of a query by comparing numeric IDs.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkById($count, callable $callback, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->getQualifiedKeyName();\n\n        $alias ??= $this->getRelated()->getKeyName();\n\n        return $this->prepareQueryBuilder()->chunkById($count, $callback, $column, $alias);\n    }\n\n    /**\n     * Chunk the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $count\n     * @param  callable  $callback\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->getQualifiedKeyName();\n\n        $alias ??= $this->getRelated()->getKeyName();\n\n        return $this->prepareQueryBuilder()->chunkByIdDesc($count, $callback, $column, $alias);\n    }\n\n    /**\n     * Execute a callback over each item while chunking by ID.\n     *\n     * @param  callable  $callback\n     * @param  int  $count\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return bool\n     */\n    public function eachById(callable $callback, $count = 1000, $column = null, $alias = null)\n    {\n        $column = $column ?? $this->getRelated()->getQualifiedKeyName();\n\n        $alias = $alias ?? $this->getRelated()->getKeyName();\n\n        return $this->prepareQueryBuilder()->eachById($callback, $count, $column, $alias);\n    }\n\n    /**\n     * Get a generator for the given query.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel>\n     */\n    public function cursor()\n    {\n        return $this->prepareQueryBuilder()->cursor();\n    }\n\n    /**\n     * Execute a callback over each item while chunking.\n     *\n     * @param  callable  $callback\n     * @param  int  $count\n     * @return bool\n     */\n    public function each(callable $callback, $count = 1000)\n    {\n        return $this->chunk($count, function ($results) use ($callback) {\n            foreach ($results as $key => $value) {\n                if ($callback($value, $key) === false) {\n                    return false;\n                }\n            }\n        });\n    }\n\n    /**\n     * Query lazily, by chunks of the given size.\n     *\n     * @param  int  $chunkSize\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel>\n     */\n    public function lazy($chunkSize = 1000)\n    {\n        return $this->prepareQueryBuilder()->lazy($chunkSize);\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel>\n     */\n    public function lazyById($chunkSize = 1000, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->getQualifiedKeyName();\n\n        $alias ??= $this->getRelated()->getKeyName();\n\n        return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias);\n    }\n\n    /**\n     * Query lazily, by chunking the results of a query by comparing IDs in descending order.\n     *\n     * @param  int  $chunkSize\n     * @param  string|null  $column\n     * @param  string|null  $alias\n     * @return \\Illuminate\\Support\\LazyCollection<int, TRelatedModel>\n     */\n    public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null)\n    {\n        $column ??= $this->getRelated()->getQualifiedKeyName();\n\n        $alias ??= $this->getRelated()->getKeyName();\n\n        return $this->prepareQueryBuilder()->lazyByIdDesc($chunkSize, $column, $alias);\n    }\n\n    /**\n     * Prepare the query builder for query execution.\n     *\n     * @param  array  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    protected function prepareQueryBuilder($columns = ['*'])\n    {\n        $builder = $this->query->applyScopes();\n\n        return $builder->addSelect(\n            $this->shouldSelect($builder->getQuery()->columns ? [] : $columns)\n        );\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($parentQuery->getQuery()->from === $query->getQuery()->from) {\n            return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);\n        }\n\n        if ($parentQuery->getQuery()->from === $this->throughParent->getTable()) {\n            return $this->getRelationExistenceQueryForThroughSelfRelation($query, $parentQuery, $columns);\n        }\n\n        $this->performJoin($query);\n\n        return $query->select($columns)->whereColumn(\n            $this->getQualifiedLocalKeyName(), '=', $this->getQualifiedFirstKeyName()\n        );\n    }\n\n    /**\n     * Add the constraints for a relationship query on the same table.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());\n\n        $query->join($this->throughParent->getTable(), $this->getQualifiedParentKeyName(), '=', $hash.'.'.$this->secondKey);\n\n        if ($this->throughParentSoftDeletes()) {\n            $query->whereNull($this->throughParent->getQualifiedDeletedAtColumn());\n        }\n\n        $query->getModel()->setTable($hash);\n\n        return $query->select($columns)->whereColumn(\n            $parentQuery->getQuery()->from.'.'.$this->localKey, '=', $this->getQualifiedFirstKeyName()\n        );\n    }\n\n    /**\n     * Add the constraints for a relationship query on the same table as the through parent.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQueryForThroughSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        $table = $this->throughParent->getTable().' as '.$hash = $this->getRelationCountHash();\n\n        $query->join($table, $hash.'.'.$this->secondLocalKey, '=', $this->getQualifiedFarKeyName());\n\n        if ($this->throughParentSoftDeletes()) {\n            $query->whereNull($hash.'.'.$this->throughParent->getDeletedAtColumn());\n        }\n\n        return $query->select($columns)->whereColumn(\n            $parentQuery->getQuery()->from.'.'.$this->localKey, '=', $hash.'.'.$this->firstKey\n        );\n    }\n\n    /**\n     * Alias to set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function take($value)\n    {\n        return $this->limit($value);\n    }\n\n    /**\n     * Set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function limit($value)\n    {\n        if ($this->farParent->exists) {\n            $this->query->limit($value);\n        } else {\n            $column = $this->getQualifiedFirstKeyName();\n\n            $grammar = $this->query->getQuery()->getGrammar();\n\n            if ($grammar instanceof MySqlGrammar && $grammar->useLegacyGroupLimit($this->query->getQuery())) {\n                $column = 'laravel_through_key';\n            }\n\n            $this->query->groupLimit($value, $column);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the qualified foreign key on the related model.\n     *\n     * @return string\n     */\n    public function getQualifiedFarKeyName()\n    {\n        return $this->getQualifiedForeignKeyName();\n    }\n\n    /**\n     * Get the foreign key on the \"through\" model.\n     *\n     * @return string\n     */\n    public function getFirstKeyName()\n    {\n        return $this->firstKey;\n    }\n\n    /**\n     * Get the qualified foreign key on the \"through\" model.\n     *\n     * @return string\n     */\n    public function getQualifiedFirstKeyName()\n    {\n        return $this->throughParent->qualifyColumn($this->firstKey);\n    }\n\n    /**\n     * Get the foreign key on the related model.\n     *\n     * @return string\n     */\n    public function getForeignKeyName()\n    {\n        return $this->secondKey;\n    }\n\n    /**\n     * Get the qualified foreign key on the related model.\n     *\n     * @return string\n     */\n    public function getQualifiedForeignKeyName()\n    {\n        return $this->related->qualifyColumn($this->secondKey);\n    }\n\n    /**\n     * Get the local key on the far parent model.\n     *\n     * @return string\n     */\n    public function getLocalKeyName()\n    {\n        return $this->localKey;\n    }\n\n    /**\n     * Get the qualified local key on the far parent model.\n     *\n     * @return string\n     */\n    public function getQualifiedLocalKeyName()\n    {\n        return $this->farParent->qualifyColumn($this->localKey);\n    }\n\n    /**\n     * Get the local key on the intermediary model.\n     *\n     * @return string\n     */\n    public function getSecondLocalKeyName()\n    {\n        return $this->secondLocalKey;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/HasOneThrough.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\CanBeOneOfMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\ComparesRelatedModels;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsDefaultModels;\nuse Illuminate\\Database\\Query\\JoinClause;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TIntermediateModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel, ?TRelatedModel>\n */\nclass HasOneThrough extends HasOneOrManyThrough implements SupportsPartialRelations\n{\n    use ComparesRelatedModels, CanBeOneOfMany, InteractsWithDictionary, SupportsDefaultModels;\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        if (is_null($this->getParentKey())) {\n            return $this->getDefaultFor($this->farParent);\n        }\n\n        return $this->first() ?: $this->getDefaultFor($this->farParent);\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->getDefaultFor($model));\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        $dictionary = $this->buildDictionary($results);\n\n        // Once we have the dictionary we can simply spin through the parent models to\n        // link them up with their children using the keyed dictionary to make the\n        // matching very convenient and easy work. Then we'll just return them.\n        foreach ($models as $model) {\n            $key = $this->getDictionaryKey($model->getAttribute($this->localKey));\n\n            if ($key !== null && isset($dictionary[$key])) {\n                $value = $dictionary[$key];\n\n                $model->setRelation(\n                    $relation, reset($value)\n                );\n            }\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($this->isOneOfMany()) {\n            $this->mergeOneOfManyJoinsTo($query);\n        }\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /** @inheritDoc */\n    public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)\n    {\n        $query->addSelect([$this->getQualifiedFirstKeyName()]);\n\n        // We need to join subqueries that aren't the inner-most subquery which is joined in the CanBeOneOfMany::ofMany method...\n        if ($this->getOneOfManySubQuery() !== null) {\n            $this->performJoin($query);\n        }\n    }\n\n    /** @inheritDoc */\n    public function getOneOfManySubQuerySelectColumns()\n    {\n        return [$this->getQualifiedFirstKeyName()];\n    }\n\n    /** @inheritDoc */\n    public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)\n    {\n        $join->on($this->qualifySubSelectColumn($this->firstKey), '=', $this->getQualifiedFirstKeyName());\n    }\n\n    /**\n     * Make a new related instance for the given model.\n     *\n     * @param  TDeclaringModel  $parent\n     * @return TRelatedModel\n     */\n    public function newRelatedInstanceFor(Model $parent)\n    {\n        return $this->related->newInstance();\n    }\n\n    /** @inheritDoc */\n    protected function getRelatedKeyFrom(Model $model)\n    {\n        return $model->getAttribute($this->getForeignKeyName());\n    }\n\n    /** @inheritDoc */\n    public function getParentKey()\n    {\n        return $this->farParent->getAttribute($this->localKey);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany<TRelatedModel, TDeclaringModel, \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>>\n */\nclass MorphMany extends MorphOneOrMany\n{\n    /**\n     * Convert the relationship to a \"morph one\" relationship.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphOne<TRelatedModel, TDeclaringModel>\n     */\n    public function one()\n    {\n        return MorphOne::noConstraints(fn () => tap(\n            new MorphOne(\n                $this->getQuery(),\n                $this->getParent(),\n                $this->morphType,\n                $this->foreignKey,\n                $this->localKey\n            ),\n            function ($morphOne) {\n                if ($inverse = $this->getInverseRelationship()) {\n                    $morphOne->inverse($inverse);\n                }\n            }\n        ));\n    }\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        return ! is_null($this->getParentKey())\n            ? $this->query->get()\n            : $this->related->newCollection();\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->related->newCollection());\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchMany($models, $results, $relation);\n    }\n\n    /** @inheritDoc */\n    public function forceCreate(array $attributes = [])\n    {\n        $attributes[$this->getMorphType()] = $this->morphClass;\n\n        return parent::forceCreate($attributes);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphOne.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\CanBeOneOfMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\ComparesRelatedModels;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsDefaultModels;\nuse Illuminate\\Database\\Query\\JoinClause;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\MorphOneOrMany<TRelatedModel, TDeclaringModel, ?TRelatedModel>\n */\nclass MorphOne extends MorphOneOrMany implements SupportsPartialRelations\n{\n    use CanBeOneOfMany, ComparesRelatedModels, SupportsDefaultModels;\n\n    /** @inheritDoc */\n    public function getResults()\n    {\n        if (is_null($this->getParentKey())) {\n            return $this->getDefaultFor($this->parent);\n        }\n\n        return $this->query->first() ?: $this->getDefaultFor($this->parent);\n    }\n\n    /** @inheritDoc */\n    public function initRelation(array $models, $relation)\n    {\n        foreach ($models as $model) {\n            $model->setRelation($relation, $this->getDefaultFor($model));\n        }\n\n        return $models;\n    }\n\n    /** @inheritDoc */\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        return $this->matchOne($models, $results, $relation);\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        if ($this->isOneOfMany()) {\n            $this->mergeOneOfManyJoinsTo($query);\n        }\n\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns);\n    }\n\n    /**\n     * Add constraints for inner join subselect for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  string|null  $column\n     * @param  string|null  $aggregate\n     * @return void\n     */\n    public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)\n    {\n        $query->addSelect($this->foreignKey, $this->morphType);\n    }\n\n    /**\n     * Get the columns that should be selected by the one of many subquery.\n     *\n     * @return array|string\n     */\n    public function getOneOfManySubQuerySelectColumns()\n    {\n        return [$this->foreignKey, $this->morphType];\n    }\n\n    /**\n     * Add join query constraints for one of many relationships.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinClause  $join\n     * @return void\n     */\n    public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)\n    {\n        $join\n            ->on($this->qualifySubSelectColumn($this->morphType), '=', $this->qualifyRelatedColumn($this->morphType))\n            ->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));\n    }\n\n    /**\n     * Make a new related instance for the given model.\n     *\n     * @param  TDeclaringModel  $parent\n     * @return TRelatedModel\n     */\n    public function newRelatedInstanceFor(Model $parent)\n    {\n        return tap($this->related->newInstance(), function ($instance) use ($parent) {\n            $instance->setAttribute($this->getForeignKeyName(), $parent->{$this->localKey})\n                ->setAttribute($this->getMorphType(), $this->morphClass);\n\n            $this->applyInverseRelationToModel($instance, $parent);\n        });\n    }\n\n    /**\n     * Get the value of the model's foreign key.\n     *\n     * @param  TRelatedModel  $model\n     * @return int|string\n     */\n    protected function getRelatedKeyFrom(Model $model)\n    {\n        return $model->getAttribute($this->getForeignKeyName());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Str;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TResult\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\HasOneOrMany<TRelatedModel, TDeclaringModel, TResult>\n */\nabstract class MorphOneOrMany extends HasOneOrMany\n{\n    /**\n     * The foreign key type for the relationship.\n     *\n     * @var string\n     */\n    protected $morphType;\n\n    /**\n     * The morph class of the parent model.\n     *\n     * @var class-string<TDeclaringModel>|string\n     */\n    protected $morphClass;\n\n    /**\n     * Create a new morph one or many relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $type\n     * @param  string  $id\n     * @param  string  $localKey\n     */\n    public function __construct(Builder $query, Model $parent, $type, $id, $localKey)\n    {\n        $this->morphType = $type;\n\n        $this->morphClass = $parent->getMorphClass();\n\n        parent::__construct($query, $parent, $id, $localKey);\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    public function addConstraints()\n    {\n        if (static::$constraints) {\n            $this->getRelationQuery()->where($this->morphType, $this->morphClass);\n\n            parent::addConstraints();\n        }\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        parent::addEagerConstraints($models);\n\n        $this->getRelationQuery()->where($this->morphType, $this->morphClass);\n    }\n\n    /**\n     * Create a new instance of the related model. Allow mass-assignment.\n     *\n     * @param  array  $attributes\n     * @return TRelatedModel\n     */\n    public function forceCreate(array $attributes = [])\n    {\n        $attributes[$this->getForeignKeyName()] = $this->getParentKey();\n        $attributes[$this->getMorphType()] = $this->morphClass;\n\n        return $this->applyInverseRelationToModel($this->related->forceCreate($attributes));\n    }\n\n    /**\n     * Set the foreign ID and type for creating a related model.\n     *\n     * @param  TRelatedModel  $model\n     * @return void\n     */\n    protected function setForeignAttributesForCreate(Model $model)\n    {\n        $model->{$this->getForeignKeyName()} = $this->getParentKey();\n\n        $model->{$this->getMorphType()} = $this->morphClass;\n\n        foreach ($this->getQuery()->pendingAttributes as $key => $value) {\n            $attributes ??= $model->getAttributes();\n\n            if (! array_key_exists($key, $attributes)) {\n                $model->setAttribute($key, $value);\n            }\n        }\n\n        $this->applyInverseRelationToModel($model);\n    }\n\n    /**\n     * Insert new records or update the existing ones.\n     *\n     * @param  array  $values\n     * @param  array|string  $uniqueBy\n     * @param  array|null  $update\n     * @return int\n     */\n    public function upsert(array $values, $uniqueBy, $update = null)\n    {\n        if (! empty($values) && ! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        foreach ($values as $key => $value) {\n            $values[$key][$this->getMorphType()] = $this->getMorphClass();\n        }\n\n        return parent::upsert($values, $uniqueBy, $update);\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns)->where(\n            $query->qualifyColumn($this->getMorphType()), $this->morphClass\n        );\n    }\n\n    /**\n     * Get the foreign key \"type\" name.\n     *\n     * @return string\n     */\n    public function getQualifiedMorphType()\n    {\n        return $this->morphType;\n    }\n\n    /**\n     * Get the plain morph type name without the table.\n     *\n     * @return string\n     */\n    public function getMorphType()\n    {\n        return last(explode('.', $this->morphType));\n    }\n\n    /**\n     * Get the morph class of the parent model.\n     *\n     * @return class-string<TDeclaringModel>|string\n     */\n    public function getMorphClass()\n    {\n        return $this->morphClass;\n    }\n\n    /**\n     * Get the possible inverse relations for the parent model.\n     *\n     * @return array<non-empty-string>\n     */\n    protected function getPossibleInverseRelations(): array\n    {\n        return array_unique([\n            Str::beforeLast($this->getMorphType(), '_type'),\n            ...parent::getPossibleInverseRelations(),\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphPivot.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nclass MorphPivot extends Pivot\n{\n    /**\n     * The type of the polymorphic relation.\n     *\n     * Explicitly define this so it's not included in saved attributes.\n     *\n     * @var string\n     */\n    protected $morphType;\n\n    /**\n     * The value of the polymorphic relation.\n     *\n     * Explicitly define this so it's not included in saved attributes.\n     *\n     * @var class-string|string\n     */\n    protected $morphClass;\n\n    /**\n     * Set the keys for a save update query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSaveQuery($query)\n    {\n        $query->where($this->morphType, $this->morphClass);\n\n        return parent::setKeysForSaveQuery($query);\n    }\n\n    /**\n     * Set the keys for a select query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function setKeysForSelectQuery($query)\n    {\n        $query->where($this->morphType, $this->morphClass);\n\n        return parent::setKeysForSelectQuery($query);\n    }\n\n    /**\n     * Delete the pivot model record from the database.\n     *\n     * @return int\n     */\n    public function delete()\n    {\n        if (isset($this->attributes[$this->getKeyName()])) {\n            return (int) parent::delete();\n        }\n\n        if ($this->fireModelEvent('deleting') === false) {\n            return 0;\n        }\n\n        $query = $this->getDeleteQuery();\n\n        $query->where($this->morphType, $this->morphClass);\n\n        return tap($query->delete(), function () {\n            $this->exists = false;\n\n            $this->fireModelEvent('deleted', false);\n        });\n    }\n\n    /**\n     * Get the morph type for the pivot.\n     *\n     * @return string\n     */\n    public function getMorphType()\n    {\n        return $this->morphType;\n    }\n\n    /**\n     * Set the morph type for the pivot.\n     *\n     * @param  string  $morphType\n     * @return $this\n     */\n    public function setMorphType($morphType)\n    {\n        $this->morphType = $morphType;\n\n        return $this;\n    }\n\n    /**\n     * Set the morph class for the pivot.\n     *\n     * @param  class-string|string  $morphClass\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphPivot\n     */\n    public function setMorphClass($morphClass)\n    {\n        $this->morphClass = $morphClass;\n\n        return $this;\n    }\n\n    /**\n     * Get the queueable identity for the entity.\n     *\n     * @return mixed\n     */\n    public function getQueueableId()\n    {\n        if (isset($this->attributes[$this->getKeyName()])) {\n            return $this->getKey();\n        }\n\n        return sprintf(\n            '%s:%s:%s:%s:%s:%s',\n            $this->foreignKey, $this->getAttribute($this->foreignKey),\n            $this->relatedKey, $this->getAttribute($this->relatedKey),\n            $this->morphType, $this->morphClass\n        );\n    }\n\n    /**\n     * Get a new query to restore one or more models by their queueable IDs.\n     *\n     * @param  array|int  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function newQueryForRestoration($ids)\n    {\n        if (is_array($ids)) {\n            return $this->newQueryForCollectionRestoration($ids);\n        }\n\n        if (! str_contains($ids, ':')) {\n            return parent::newQueryForRestoration($ids);\n        }\n\n        $segments = explode(':', $ids);\n\n        return $this->newQueryWithoutScopes()\n            ->where($segments[0], $segments[1])\n            ->where($segments[2], $segments[3])\n            ->where($segments[4], $segments[5]);\n    }\n\n    /**\n     * Get a new query to restore multiple models by their queueable IDs.\n     *\n     * @param  array  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    protected function newQueryForCollectionRestoration(array $ids)\n    {\n        $ids = array_values($ids);\n\n        if (! str_contains($ids[0], ':')) {\n            return parent::newQueryForRestoration($ids);\n        }\n\n        $query = $this->newQueryWithoutScopes();\n\n        foreach ($ids as $id) {\n            $segments = explode(':', $id);\n\n            $query->orWhere(function ($query) use ($segments) {\n                return $query->where($segments[0], $segments[1])\n                    ->where($segments[2], $segments[3])\n                    ->where($segments[4], $segments[5]);\n            });\n        }\n\n        return $query;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphTo.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse BadMethodCallException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\InteractsWithDictionary;\nuse Illuminate\\Support\\Arr;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo<TRelatedModel, TDeclaringModel>\n */\nclass MorphTo extends BelongsTo\n{\n    use InteractsWithDictionary;\n\n    /**\n     * The type of the polymorphic relation.\n     *\n     * @var string\n     */\n    protected $morphType;\n\n    /**\n     * The associated key on the parent model.\n     *\n     * @var string|null\n     */\n    protected $ownerKey;\n\n    /**\n     * The models whose relations are being eager loaded.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Collection<int, TDeclaringModel>\n     */\n    protected $models;\n\n    /**\n     * All of the models keyed by ID.\n     *\n     * @var array\n     */\n    protected $dictionary = [];\n\n    /**\n     * A buffer of dynamic calls to query macros.\n     *\n     * @var array\n     */\n    protected $macroBuffer = [];\n\n    /**\n     * A map of relations to load for each individual morph type.\n     *\n     * @var array\n     */\n    protected $morphableEagerLoads = [];\n\n    /**\n     * A map of relationship counts to load for each individual morph type.\n     *\n     * @var array\n     */\n    protected $morphableEagerLoadCounts = [];\n\n    /**\n     * A map of constraints to apply for each individual morph type.\n     *\n     * @var array\n     */\n    protected $morphableConstraints = [];\n\n    /**\n     * Create a new morph to relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $foreignKey\n     * @param  string|null  $ownerKey\n     * @param  string  $type\n     * @param  string  $relation\n     */\n    public function __construct(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)\n    {\n        $this->morphType = $type;\n\n        parent::__construct($query, $parent, $foreignKey, $ownerKey, $relation);\n    }\n\n    /** @inheritDoc */\n    #[\\Override]\n    public function addEagerConstraints(array $models)\n    {\n        $this->buildDictionary($this->models = new EloquentCollection($models));\n    }\n\n    /**\n     * Build a dictionary with the models.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $models\n     * @return void\n     */\n    protected function buildDictionary(EloquentCollection $models)\n    {\n        $isAssociative = Arr::isAssoc($models->all());\n\n        foreach ($models as $key => $model) {\n            if ($model->{$this->morphType}) {\n                $morphTypeKey = $this->getDictionaryKey($model->{$this->morphType});\n                $foreignKeyKey = $this->getDictionaryKey($model->{$this->foreignKey});\n\n                if ($morphTypeKey === null || $foreignKeyKey === null) {\n                    continue;\n                }\n\n                if ($isAssociative) {\n                    $this->dictionary[$morphTypeKey][$foreignKeyKey][$key] = $model;\n                } else {\n                    $this->dictionary[$morphTypeKey][$foreignKeyKey][] = $model;\n                }\n            }\n        }\n    }\n\n    /**\n     * Get the results of the relationship.\n     *\n     * Called via eager load method of Eloquent query builder.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TDeclaringModel>\n     */\n    public function getEager()\n    {\n        foreach (array_keys($this->dictionary) as $type) {\n            $this->matchToMorphParents($type, $this->getResultsByType($type));\n        }\n\n        return $this->models;\n    }\n\n    /**\n     * Get all of the relation results for a type.\n     *\n     * @param  string  $type\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    protected function getResultsByType($type)\n    {\n        $instance = $this->createModelByType($type);\n\n        $ownerKey = $this->ownerKey ?? $instance->getKeyName();\n\n        $query = $this->replayMacros($instance->newQuery())\n            ->mergeConstraintsFrom($this->getQuery())\n            ->with(array_merge(\n                $this->getQuery()->getEagerLoads(),\n                (array) ($this->morphableEagerLoads[get_class($instance)] ?? [])\n            ))\n            ->withCount(\n                (array) ($this->morphableEagerLoadCounts[get_class($instance)] ?? [])\n            );\n\n        if ($callback = ($this->morphableConstraints[get_class($instance)] ?? null)) {\n            $callback($query);\n        }\n\n        $whereIn = $this->whereInMethod($instance, $ownerKey);\n\n        return $query->{$whereIn}(\n            $instance->qualifyColumn($ownerKey), $this->gatherKeysByType($type, $instance->getKeyType())\n        )->get();\n    }\n\n    /**\n     * Gather all of the foreign keys for a given type.\n     *\n     * @param  string  $type\n     * @param  string  $keyType\n     * @return array\n     */\n    protected function gatherKeysByType($type, $keyType)\n    {\n        return $keyType !== 'string'\n            ? array_keys($this->dictionary[$type])\n            : array_map(function ($modelId) {\n                return (string) $modelId;\n            }, array_filter(array_keys($this->dictionary[$type])));\n    }\n\n    /**\n     * Create a new model instance by type.\n     *\n     * @param  string  $type\n     * @return TRelatedModel\n     */\n    public function createModelByType($type)\n    {\n        $class = Model::getActualClassNameForMorph($type);\n\n        return tap(new $class, function ($instance) {\n            if (! $instance->getConnectionName()) {\n                $instance->setConnection($this->getConnection()->getName());\n            }\n        });\n    }\n\n    /** @inheritDoc */\n    #[\\Override]\n    public function match(array $models, EloquentCollection $results, $relation)\n    {\n        return $models;\n    }\n\n    /**\n     * Match the results for a given type to their parents.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @return void\n     */\n    protected function matchToMorphParents($type, EloquentCollection $results)\n    {\n        foreach ($results as $result) {\n            $ownerKey = ! is_null($this->ownerKey) ? $this->getDictionaryKey($result->{$this->ownerKey}) : $result->getKey();\n\n            if ($ownerKey !== null && isset($this->dictionary[$type][$ownerKey])) {\n                foreach ($this->dictionary[$type][$ownerKey] as $model) {\n                    $model->setRelation($this->relationName, $result);\n                }\n            }\n        }\n    }\n\n    /**\n     * Associate the model instance to the given parent.\n     *\n     * @param  TRelatedModel|null  $model\n     * @return TDeclaringModel\n     */\n    #[\\Override]\n    public function associate($model)\n    {\n        if ($model instanceof Model) {\n            $foreignKey = $this->ownerKey && $model->{$this->ownerKey}\n                ? $this->ownerKey\n                : $model->getKeyName();\n        }\n\n        $this->parent->setAttribute(\n            $this->foreignKey, $model instanceof Model ? $model->{$foreignKey} : null\n        );\n\n        $this->parent->setAttribute(\n            $this->morphType, $model instanceof Model ? $model->getMorphClass() : null\n        );\n\n        return $this->parent->setRelation($this->relationName, $model);\n    }\n\n    /**\n     * Dissociate previously associated model from the given parent.\n     *\n     * @return TDeclaringModel\n     */\n    #[\\Override]\n    public function dissociate()\n    {\n        $this->parent->setAttribute($this->foreignKey, null);\n\n        $this->parent->setAttribute($this->morphType, null);\n\n        return $this->parent->setRelation($this->relationName, null);\n    }\n\n    /** @inheritDoc */\n    #[\\Override]\n    public function touch()\n    {\n        if (! is_null($this->getParentKey())) {\n            parent::touch();\n        }\n    }\n\n    /** @inheritDoc */\n    #[\\Override]\n    protected function newRelatedInstanceFor(Model $parent)\n    {\n        return $parent->{$this->getRelationName()}()->getRelated()->newInstance();\n    }\n\n    /**\n     * Get the foreign key \"type\" name.\n     *\n     * @return string\n     */\n    public function getMorphType()\n    {\n        return $this->morphType;\n    }\n\n    /**\n     * Get the dictionary used by the relationship.\n     *\n     * @return array\n     */\n    public function getDictionary()\n    {\n        return $this->dictionary;\n    }\n\n    /**\n     * Specify which relations to load for a given morph type.\n     *\n     * @param  array  $with\n     * @return $this\n     */\n    public function morphWith(array $with)\n    {\n        $this->morphableEagerLoads = array_merge(\n            $this->morphableEagerLoads, $with\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify which relationship counts to load for a given morph type.\n     *\n     * @param  array  $withCount\n     * @return $this\n     */\n    public function morphWithCount(array $withCount)\n    {\n        $this->morphableEagerLoadCounts = array_merge(\n            $this->morphableEagerLoadCounts, $withCount\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify constraints on the query for a given morph type.\n     *\n     * @param  array  $callbacks\n     * @return $this\n     */\n    public function constrain(array $callbacks)\n    {\n        $this->morphableConstraints = array_merge(\n            $this->morphableConstraints, $callbacks\n        );\n\n        return $this;\n    }\n\n    /**\n     * Indicate that soft deleted models should be included in the results.\n     *\n     * @return $this\n     */\n    public function withTrashed()\n    {\n        $callback = fn ($query) => $query->hasMacro('withTrashed') ? $query->withTrashed() : $query;\n\n        $this->macroBuffer[] = [\n            'method' => 'when',\n            'parameters' => [true, $callback],\n        ];\n\n        return $this->when(true, $callback);\n    }\n\n    /**\n     * Indicate that soft deleted models should not be included in the results.\n     *\n     * @return $this\n     */\n    public function withoutTrashed()\n    {\n        $callback = fn ($query) => $query->hasMacro('withoutTrashed') ? $query->withoutTrashed() : $query;\n\n        $this->macroBuffer[] = [\n            'method' => 'when',\n            'parameters' => [true, $callback],\n        ];\n\n        return $this->when(true, $callback);\n    }\n\n    /**\n     * Indicate that only soft deleted models should be included in the results.\n     *\n     * @return $this\n     */\n    public function onlyTrashed()\n    {\n        $callback = fn ($query) => $query->hasMacro('onlyTrashed') ? $query->onlyTrashed() : $query;\n\n        $this->macroBuffer[] = [\n            'method' => 'when',\n            'parameters' => [true, $callback],\n        ];\n\n        return $this->when(true, $callback);\n    }\n\n    /**\n     * Replay stored macro calls on the actual related instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    protected function replayMacros(Builder $query)\n    {\n        foreach ($this->macroBuffer as $macro) {\n            $query->{$macro['method']}(...$macro['parameters']);\n        }\n\n        return $query;\n    }\n\n    /** @inheritDoc */\n    #[\\Override]\n    public function getQualifiedOwnerKeyName()\n    {\n        if (is_null($this->ownerKey)) {\n            return '';\n        }\n\n        return parent::getQualifiedOwnerKeyName();\n    }\n\n    /**\n     * Handle dynamic method calls to the relationship.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        try {\n            $result = parent::__call($method, $parameters);\n\n            if (in_array($method, ['select', 'selectRaw', 'selectSub', 'addSelect', 'withoutGlobalScopes'])) {\n                $this->macroBuffer[] = compact('method', 'parameters');\n            }\n\n            return $result;\n        }\n\n        // If we tried to call a method that does not exist on the parent Builder instance,\n        // we'll assume that we want to call a query macro (e.g. withTrashed) that only\n        // exists on related models. We will just store the call and replay it later.\n        catch (BadMethodCallException) {\n            $this->macroBuffer[] = compact('method', 'parameters');\n\n            return $this;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/MorphToMany.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TPivotModel of \\Illuminate\\Database\\Eloquent\\Relations\\Pivot = \\Illuminate\\Database\\Eloquent\\Relations\\MorphPivot\n * @template TAccessor of string = 'pivot'\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany<TRelatedModel, TDeclaringModel, TPivotModel, TAccessor>\n */\nclass MorphToMany extends BelongsToMany\n{\n    /**\n     * The type of the polymorphic relation.\n     *\n     * @var string\n     */\n    protected $morphType;\n\n    /**\n     * The morph class of the morph type constraint.\n     *\n     * @var class-string|string\n     */\n    protected $morphClass;\n\n    /**\n     * Indicates if we are connecting the inverse of the relation.\n     *\n     * This primarily affects the morphClass constraint.\n     *\n     * @var bool\n     */\n    protected $inverse;\n\n    /**\n     * Create a new morph to many relationship instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     * @param  string  $name\n     * @param  string  $table\n     * @param  string  $foreignPivotKey\n     * @param  string  $relatedPivotKey\n     * @param  string  $parentKey\n     * @param  string  $relatedKey\n     * @param  string|null  $relationName\n     * @param  bool  $inverse\n     */\n    public function __construct(\n        Builder $query,\n        Model $parent,\n        $name,\n        $table,\n        $foreignPivotKey,\n        $relatedPivotKey,\n        $parentKey,\n        $relatedKey,\n        $relationName = null,\n        $inverse = false,\n    ) {\n        $this->inverse = $inverse;\n        $this->morphType = $name.'_type';\n        $this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass();\n\n        parent::__construct(\n            $query, $parent, $table, $foreignPivotKey,\n            $relatedPivotKey, $parentKey, $relatedKey, $relationName\n        );\n    }\n\n    /**\n     * Set the where clause for the relation query.\n     *\n     * @return $this\n     */\n    protected function addWhereConstraints()\n    {\n        parent::addWhereConstraints();\n\n        $this->query->where($this->qualifyPivotColumn($this->morphType), $this->morphClass);\n\n        return $this;\n    }\n\n    /** @inheritDoc */\n    public function addEagerConstraints(array $models)\n    {\n        parent::addEagerConstraints($models);\n\n        $this->query->where($this->qualifyPivotColumn($this->morphType), $this->morphClass);\n    }\n\n    /**\n     * Create a new pivot attachment record.\n     *\n     * @param  int  $id\n     * @param  bool  $timed\n     * @return array\n     */\n    protected function baseAttachRecord($id, $timed)\n    {\n        return Arr::add(\n            parent::baseAttachRecord($id, $timed), $this->morphType, $this->morphClass\n        );\n    }\n\n    /** @inheritDoc */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        return parent::getRelationExistenceQuery($query, $parentQuery, $columns)->where(\n            $this->qualifyPivotColumn($this->morphType), $this->morphClass\n        );\n    }\n\n    /**\n     * Get the pivot models that are currently attached, filtered by related model keys.\n     *\n     * @param  mixed  $ids\n     * @return \\Illuminate\\Support\\Collection<int, TPivotModel>\n     */\n    protected function getCurrentlyAttachedPivotsForIds($ids = null)\n    {\n        return parent::getCurrentlyAttachedPivotsForIds($ids)->map(function ($record) {\n            return $record instanceof MorphPivot\n                ? $record->setMorphType($this->morphType)\n                    ->setMorphClass($this->morphClass)\n                : $record;\n        });\n    }\n\n    /**\n     * Create a new query builder for the pivot table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function newPivotQuery()\n    {\n        return parent::newPivotQuery()->where($this->morphType, $this->morphClass);\n    }\n\n    /**\n     * Create a new pivot model instance.\n     *\n     * @param  array  $attributes\n     * @param  bool  $exists\n     * @return TPivotModel\n     */\n    public function newPivot(array $attributes = [], $exists = false)\n    {\n        $using = $this->using;\n\n        $attributes = array_merge([$this->morphType => $this->morphClass], $attributes);\n\n        $pivot = $using\n            ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists)\n            : MorphPivot::fromAttributes($this->parent, $attributes, $this->table, $exists);\n\n        $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey)\n            ->setRelatedModel($this->related)\n            ->setMorphType($this->morphType)\n            ->setMorphClass($this->morphClass);\n\n        return $pivot;\n    }\n\n    /**\n     * Get the pivot columns for the relation.\n     *\n     * \"pivot_\" is prefixed at each column for easy removal later.\n     *\n     * @return array\n     */\n    protected function aliasedPivotColumns()\n    {\n        return (new Collection([\n            $this->foreignPivotKey,\n            $this->relatedPivotKey,\n            $this->morphType,\n            ...$this->pivotColumns,\n        ]))\n            ->map(fn ($column) => $this->qualifyPivotColumn($column).' as pivot_'.$column)\n            ->unique()\n            ->all();\n    }\n\n    /**\n     * Get the foreign key \"type\" name.\n     *\n     * @return string\n     */\n    public function getMorphType()\n    {\n        return $this->morphType;\n    }\n\n    /**\n     * Get the fully-qualified morph type for the relation.\n     *\n     * @return string\n     */\n    public function getQualifiedMorphTypeName()\n    {\n        return $this->qualifyPivotColumn($this->morphType);\n    }\n\n    /**\n     * Get the class name of the parent model.\n     *\n     * @return class-string|string\n     */\n    public function getMorphClass()\n    {\n        return $this->morphClass;\n    }\n\n    /**\n     * Get the indicator for a reverse relationship.\n     *\n     * @return bool\n     */\n    public function getInverse()\n    {\n        return $this->inverse;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Pivot.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\n\nclass Pivot extends Model\n{\n    use AsPivot;\n\n    /**\n     * Indicates if the IDs are auto-incrementing.\n     *\n     * @var bool\n     */\n    public $incrementing = false;\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var array<string>|bool\n     */\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Relations/Relation.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent\\Relations;\n\nuse Closure;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Builder as BuilderContract;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\MultipleRecordsFoundException;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Macroable;\n\n/**\n * @template TRelatedModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TDeclaringModel of \\Illuminate\\Database\\Eloquent\\Model\n * @template TResult\n *\n * @mixin \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n */\nabstract class Relation implements BuilderContract\n{\n    use ForwardsCalls, Macroable {\n        Macroable::__call as macroCall;\n    }\n\n    /**\n     * The Eloquent query builder instance.\n     *\n     * @var \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    protected $query;\n\n    /**\n     * The parent model instance.\n     *\n     * @var TDeclaringModel\n     */\n    protected $parent;\n\n    /**\n     * The related model instance.\n     *\n     * @var TRelatedModel\n     */\n    protected $related;\n\n    /**\n     * Indicates whether the eagerly loaded relation should implicitly return an empty collection.\n     *\n     * @var bool\n     */\n    protected $eagerKeysWereEmpty = false;\n\n    /**\n     * Indicates if the relation is adding constraints.\n     *\n     * @var bool\n     */\n    protected static $constraints = true;\n\n    /**\n     * An array to map morph names to their class names in the database.\n     *\n     * @var array<string, class-string<\\Illuminate\\Database\\Eloquent\\Model>>\n     */\n    public static $morphMap = [];\n\n    /**\n     * Prevents morph relationships without a morph map.\n     *\n     * @var bool\n     */\n    protected static $requireMorphMap = false;\n\n    /**\n     * The count of self joins.\n     *\n     * @var int\n     */\n    protected static $selfJoinCount = 0;\n\n    /**\n     * Create a new relation instance.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  TDeclaringModel  $parent\n     */\n    public function __construct(Builder $query, Model $parent)\n    {\n        $this->query = $query;\n        $this->parent = $parent;\n        $this->related = $query->getModel();\n\n        $this->addConstraints();\n    }\n\n    /**\n     * Run a callback with constraints disabled on the relation.\n     *\n     * @template TReturn of mixed\n     *\n     * @param  Closure(): TReturn  $callback\n     * @return TReturn\n     */\n    public static function noConstraints(Closure $callback)\n    {\n        $previous = static::$constraints;\n\n        static::$constraints = false;\n\n        // When resetting the relation where clause, we want to shift the first element\n        // off of the bindings, leaving only the constraints that the developers put\n        // as \"extra\" on the relationships, and not original relation constraints.\n        try {\n            return $callback();\n        } finally {\n            static::$constraints = $previous;\n        }\n    }\n\n    /**\n     * Set the base constraints on the relation query.\n     *\n     * @return void\n     */\n    abstract public function addConstraints();\n\n    /**\n     * Set the constraints for an eager load of the relation.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @return void\n     */\n    abstract public function addEagerConstraints(array $models);\n\n    /**\n     * Initialize the relation on a set of models.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  string  $relation\n     * @return array<int, TDeclaringModel>\n     */\n    abstract public function initRelation(array $models, $relation);\n\n    /**\n     * Match the eagerly loaded results to their parents.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>  $results\n     * @param  string  $relation\n     * @return array<int, TDeclaringModel>\n     */\n    abstract public function match(array $models, EloquentCollection $results, $relation);\n\n    /**\n     * Get the results of the relationship.\n     *\n     * @return TResult\n     */\n    abstract public function getResults();\n\n    /**\n     * Get the relationship for eager loading.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function getEager()\n    {\n        return $this->eagerKeysWereEmpty\n            ? $this->related->newCollection()\n            : $this->get();\n    }\n\n    /**\n     * Execute the query and get the first result if it's the sole matching record.\n     *\n     * @param  array|string  $columns\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function sole($columns = ['*'])\n    {\n        $result = $this->limit(2)->get($columns);\n\n        $count = $result->count();\n\n        if ($count === 0) {\n            throw (new ModelNotFoundException)->setModel(get_class($this->related));\n        }\n\n        if ($count > 1) {\n            throw new MultipleRecordsFoundException($count);\n        }\n\n        return $result->first();\n    }\n\n    /**\n     * Execute the query as a \"select\" statement.\n     *\n     * @param  array  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function get($columns = ['*'])\n    {\n        return $this->query->get($columns);\n    }\n\n    /**\n     * Touch all of the related models for the relationship.\n     *\n     * @return void\n     */\n    public function touch()\n    {\n        $model = $this->getRelated();\n\n        if (! $model::isIgnoringTouch()) {\n            $this->rawUpdate([\n                $model->getUpdatedAtColumn() => $model->freshTimestampString(),\n            ]);\n        }\n    }\n\n    /**\n     * Run a raw update against the base query.\n     *\n     * @param  array  $attributes\n     * @return int\n     */\n    public function rawUpdate(array $attributes = [])\n    {\n        return $this->query->withoutGlobalScopes()->update($attributes);\n    }\n\n    /**\n     * Add the constraints for a relationship count query.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceCountQuery(Builder $query, Builder $parentQuery)\n    {\n        return $this->getRelationExistenceQuery(\n            $query, $parentQuery, new Expression('count(*)')\n        )->setBindings([], 'select');\n    }\n\n    /**\n     * Add the constraints for an internal relationship existence query.\n     *\n     * Essentially, these queries compare on column names like whereColumn.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>  $query\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TDeclaringModel>  $parentQuery\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])\n    {\n        return $query->select($columns)->whereColumn(\n            $this->getQualifiedParentKeyName(), '=', $this->getExistenceCompareKey()\n        );\n    }\n\n    /**\n     * Get a relationship join table hash.\n     *\n     * @param  bool  $incrementJoinCount\n     * @return string\n     */\n    public function getRelationCountHash($incrementJoinCount = true)\n    {\n        return 'laravel_reserved_'.($incrementJoinCount ? static::$selfJoinCount++ : static::$selfJoinCount);\n    }\n\n    /**\n     * Get all of the primary keys for an array of models.\n     *\n     * @param  array<int, TDeclaringModel>  $models\n     * @param  string|null  $key\n     * @return array<int, int|string|null>\n     */\n    protected function getKeys(array $models, $key = null)\n    {\n        return (new BaseCollection($models))->map(function ($value) use ($key) {\n            return $key ? $value->getAttribute($key) : $value->getKey();\n        })->values()->unique(null, true)->sort()->all();\n    }\n\n    /**\n     * Get the query builder that will contain the relationship constraints.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    protected function getRelationQuery()\n    {\n        return $this->query;\n    }\n\n    /**\n     * Get the underlying query for the relation.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>\n     */\n    public function getQuery()\n    {\n        return $this->query;\n    }\n\n    /**\n     * Get the base query builder driving the Eloquent builder.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function getBaseQuery()\n    {\n        return $this->query->getQuery();\n    }\n\n    /**\n     * Get a base query builder instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function toBase()\n    {\n        return $this->query->toBase();\n    }\n\n    /**\n     * Get the parent model of the relation.\n     *\n     * @return TDeclaringModel\n     */\n    public function getParent()\n    {\n        return $this->parent;\n    }\n\n    /**\n     * Get the fully-qualified parent key name.\n     *\n     * @return string\n     */\n    public function getQualifiedParentKeyName()\n    {\n        return $this->parent->getQualifiedKeyName();\n    }\n\n    /**\n     * Get the related model of the relation.\n     *\n     * @return TRelatedModel\n     */\n    public function getRelated()\n    {\n        return $this->related;\n    }\n\n    /**\n     * Get the name of the \"created at\" column.\n     *\n     * @return string\n     */\n    public function createdAt()\n    {\n        return $this->parent->getCreatedAtColumn();\n    }\n\n    /**\n     * Get the name of the \"updated at\" column.\n     *\n     * @return string\n     */\n    public function updatedAt()\n    {\n        return $this->parent->getUpdatedAtColumn();\n    }\n\n    /**\n     * Get the name of the related model's \"updated at\" column.\n     *\n     * @return string\n     */\n    public function relatedUpdatedAt()\n    {\n        return $this->related->getUpdatedAtColumn();\n    }\n\n    /**\n     * Add a whereIn eager constraint for the given set of model keys to be loaded.\n     *\n     * @param  string  $whereIn\n     * @param  string  $key\n     * @param  array  $modelKeys\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TRelatedModel>|null  $query\n     * @return void\n     */\n    protected function whereInEager(string $whereIn, string $key, array $modelKeys, ?Builder $query = null)\n    {\n        ($query ?? $this->query)->{$whereIn}($key, $modelKeys);\n\n        if ($modelKeys === []) {\n            $this->eagerKeysWereEmpty = true;\n        }\n    }\n\n    /**\n     * Get the name of the \"where in\" method for eager loading.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @return string\n     */\n    protected function whereInMethod(Model $model, $key)\n    {\n        return $model->getKeyName() === last(explode('.', $key))\n            && in_array($model->getKeyType(), ['int', 'integer'])\n                ? 'whereIntegerInRaw'\n                : 'whereIn';\n    }\n\n    /**\n     * Prevent polymorphic relationships from being used without model mappings.\n     *\n     * @param  bool  $requireMorphMap\n     * @return void\n     */\n    public static function requireMorphMap($requireMorphMap = true)\n    {\n        static::$requireMorphMap = $requireMorphMap;\n    }\n\n    /**\n     * Determine if polymorphic relationships require explicit model mapping.\n     *\n     * @return bool\n     */\n    public static function requiresMorphMap()\n    {\n        return static::$requireMorphMap;\n    }\n\n    /**\n     * Define the morph map for polymorphic relations and require all morphed models to be explicitly mapped.\n     *\n     * @param  array<array-key, class-string<\\Illuminate\\Database\\Eloquent\\Model>>  $map\n     * @param  bool  $merge\n     * @return array\n     */\n    public static function enforceMorphMap(array $map, $merge = true)\n    {\n        static::requireMorphMap();\n\n        return static::morphMap($map, $merge);\n    }\n\n    /**\n     * Set or get the morph map for polymorphic relations.\n     *\n     * @param  array<array-key, class-string<\\Illuminate\\Database\\Eloquent\\Model>>|null  $map\n     * @param  bool  $merge\n     * @return array<string, class-string<\\Illuminate\\Database\\Eloquent\\Model>>\n     */\n    public static function morphMap(?array $map = null, $merge = true)\n    {\n        $map = static::buildMorphMapFromModels($map);\n\n        if (is_array($map)) {\n            static::$morphMap = $merge && static::$morphMap\n                ? $map + static::$morphMap\n                : $map;\n        }\n\n        return static::$morphMap;\n    }\n\n    /**\n     * Builds a table-keyed array from model class names.\n     *\n     * @param  array<array-key, class-string<\\Illuminate\\Database\\Eloquent\\Model>>|null  $models\n     * @return array<string, class-string<\\Illuminate\\Database\\Eloquent\\Model>>|null\n     */\n    protected static function buildMorphMapFromModels(?array $models = null)\n    {\n        if (is_null($models) || ! array_is_list($models)) {\n            return $models;\n        }\n\n        return array_combine(array_map(function ($model) {\n            return (new $model)->getTable();\n        }, $models), $models);\n    }\n\n    /**\n     * Get the model associated with a custom polymorphic type.\n     *\n     * @param  string  $alias\n     * @return class-string<\\Illuminate\\Database\\Eloquent\\Model>|null\n     */\n    public static function getMorphedModel($alias)\n    {\n        return static::$morphMap[$alias] ?? null;\n    }\n\n    /**\n     * Get the alias associated with a custom polymorphic class.\n     *\n     * @param  class-string<\\Illuminate\\Database\\Eloquent\\Model>  $className\n     * @return int|string\n     */\n    public static function getMorphAlias(string $className)\n    {\n        return array_search($className, static::$morphMap, strict: true) ?: $className;\n    }\n\n    /**\n     * Handle dynamic method calls to the relationship.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->forwardDecoratedCallTo($this->query, $method, $parameters);\n    }\n\n    /**\n     * Force a clone of the underlying query builder when cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->query = clone $this->query;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/Scope.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\ninterface Scope\n{\n    /**\n     * Apply the scope to a given Eloquent query builder.\n     *\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TModel>  $builder\n     * @param  TModel  $model\n     * @return void\n     */\n    public function apply(Builder $builder, Model $model);\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/SoftDeletes.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Support\\Collection as BaseCollection;\n\n/**\n * @method static \\Illuminate\\Database\\Eloquent\\Builder<static> withTrashed(bool $withTrashed = true)\n * @method static \\Illuminate\\Database\\Eloquent\\Builder<static> onlyTrashed()\n * @method static \\Illuminate\\Database\\Eloquent\\Builder<static> withoutTrashed()\n * @method static static restoreOrCreate(array<string, mixed> $attributes = [], array<string, mixed> $values = [])\n * @method static static createOrRestore(array<string, mixed> $attributes = [], array<string, mixed> $values = [])\n */\ntrait SoftDeletes\n{\n    /**\n     * Indicates if the model is currently force deleting.\n     *\n     * @var bool\n     */\n    protected $forceDeleting = false;\n\n    /**\n     * Boot the soft deleting trait for a model.\n     *\n     * @return void\n     */\n    public static function bootSoftDeletes()\n    {\n        static::addGlobalScope(new SoftDeletingScope);\n    }\n\n    /**\n     * Initialize the soft deleting trait for an instance.\n     *\n     * @return void\n     */\n    public function initializeSoftDeletes()\n    {\n        if (! isset($this->casts[$this->getDeletedAtColumn()])) {\n            $this->casts[$this->getDeletedAtColumn()] = 'datetime';\n        }\n    }\n\n    /**\n     * Force a hard delete on a soft deleted model.\n     *\n     * @return bool|null\n     */\n    public function forceDelete()\n    {\n        if ($this->fireModelEvent('forceDeleting') === false) {\n            return false;\n        }\n\n        $this->forceDeleting = true;\n\n        return tap($this->delete(), function ($deleted) {\n            $this->forceDeleting = false;\n\n            if ($deleted) {\n                $this->fireModelEvent('forceDeleted', false);\n            }\n        });\n    }\n\n    /**\n     * Force a hard delete on a soft deleted model without raising any events.\n     *\n     * @return bool|null\n     */\n    public function forceDeleteQuietly()\n    {\n        return static::withoutEvents(fn () => $this->forceDelete());\n    }\n\n    /**\n     * Destroy the models for the given IDs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|int|string  $ids\n     * @return int\n     */\n    public static function forceDestroy($ids)\n    {\n        if ($ids instanceof EloquentCollection) {\n            $ids = $ids->modelKeys();\n        }\n\n        if ($ids instanceof BaseCollection) {\n            $ids = $ids->all();\n        }\n\n        $ids = is_array($ids) ? $ids : func_get_args();\n\n        if (count($ids) === 0) {\n            return 0;\n        }\n\n        // We will actually pull the models from the database table and call delete on\n        // each of them individually so that their events get fired properly with a\n        // correct set of attributes in case the developers wants to check these.\n        $key = ($instance = new static)->getKeyName();\n\n        $count = 0;\n\n        foreach ($instance->withTrashed()->whereIn($key, $ids)->get() as $model) {\n            if ($model->forceDelete()) {\n                $count++;\n            }\n        }\n\n        return $count;\n    }\n\n    /**\n     * Perform the actual delete query on this model instance.\n     *\n     * @return mixed\n     */\n    protected function performDeleteOnModel()\n    {\n        if ($this->forceDeleting) {\n            return tap($this->setKeysForSaveQuery($this->newModelQuery())->forceDelete(), function () {\n                $this->exists = false;\n            });\n        }\n\n        return $this->runSoftDelete();\n    }\n\n    /**\n     * Perform the actual delete query on this model instance.\n     *\n     * @return void\n     */\n    protected function runSoftDelete()\n    {\n        $query = $this->setKeysForSaveQuery($this->newModelQuery());\n\n        $time = $this->freshTimestamp();\n\n        $columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];\n\n        $this->{$this->getDeletedAtColumn()} = $time;\n\n        if ($this->usesTimestamps() && ! is_null($this->getUpdatedAtColumn())) {\n            $this->{$this->getUpdatedAtColumn()} = $time;\n\n            $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);\n        }\n\n        $query->update($columns);\n\n        $this->syncOriginalAttributes(array_keys($columns));\n\n        $this->fireModelEvent('trashed', false);\n    }\n\n    /**\n     * Restore a soft-deleted model instance.\n     *\n     * @return bool\n     */\n    public function restore()\n    {\n        // If the restoring event does not return false, we will proceed with this\n        // restore operation. Otherwise, we bail out so the developer will stop\n        // the restore totally. We will clear the deleted timestamp and save.\n        if ($this->fireModelEvent('restoring') === false) {\n            return false;\n        }\n\n        $this->{$this->getDeletedAtColumn()} = null;\n\n        // Once we have saved the model, we will fire the \"restored\" event so this\n        // developer will do anything they need to after a restore operation is\n        // totally finished. Then we will return the result of the save call.\n        $this->exists = true;\n\n        $result = $this->save();\n\n        $this->fireModelEvent('restored', false);\n\n        return $result;\n    }\n\n    /**\n     * Restore a soft-deleted model instance without raising any events.\n     *\n     * @return bool\n     */\n    public function restoreQuietly()\n    {\n        return static::withoutEvents(fn () => $this->restore());\n    }\n\n    /**\n     * Determine if the model instance has been soft-deleted.\n     *\n     * @return bool\n     */\n    public function trashed()\n    {\n        return ! is_null($this->{$this->getDeletedAtColumn()});\n    }\n\n    /**\n     * Register a \"softDeleted\" model event callback with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|class-string  $callback\n     * @return void\n     */\n    public static function softDeleted($callback)\n    {\n        static::registerModelEvent('trashed', $callback);\n    }\n\n    /**\n     * Register a \"restoring\" model event callback with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|class-string  $callback\n     * @return void\n     */\n    public static function restoring($callback)\n    {\n        static::registerModelEvent('restoring', $callback);\n    }\n\n    /**\n     * Register a \"restored\" model event callback with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|class-string  $callback\n     * @return void\n     */\n    public static function restored($callback)\n    {\n        static::registerModelEvent('restored', $callback);\n    }\n\n    /**\n     * Register a \"forceDeleting\" model event callback with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|class-string  $callback\n     * @return void\n     */\n    public static function forceDeleting($callback)\n    {\n        static::registerModelEvent('forceDeleting', $callback);\n    }\n\n    /**\n     * Register a \"forceDeleted\" model event callback with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|class-string  $callback\n     * @return void\n     */\n    public static function forceDeleted($callback)\n    {\n        static::registerModelEvent('forceDeleted', $callback);\n    }\n\n    /**\n     * Determine if the model is currently force deleting.\n     *\n     * @return bool\n     */\n    public function isForceDeleting()\n    {\n        return $this->forceDeleting;\n    }\n\n    /**\n     * Get the name of the \"deleted at\" column.\n     *\n     * @return string\n     */\n    public function getDeletedAtColumn()\n    {\n        return defined(static::class.'::DELETED_AT') ? static::DELETED_AT : 'deleted_at';\n    }\n\n    /**\n     * Get the fully-qualified \"deleted at\" column.\n     *\n     * @return string\n     */\n    public function getQualifiedDeletedAtColumn()\n    {\n        return $this->qualifyColumn($this->getDeletedAtColumn());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Eloquent/SoftDeletingScope.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Eloquent;\n\nclass SoftDeletingScope implements Scope\n{\n    /**\n     * All of the extensions to be added to the builder.\n     *\n     * @var string[]\n     */\n    protected $extensions = ['Restore', 'RestoreOrCreate', 'CreateOrRestore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];\n\n    /**\n     * Apply the scope to a given Eloquent query builder.\n     *\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<TModel>  $builder\n     * @param  TModel  $model\n     * @return void\n     */\n    public function apply(Builder $builder, Model $model)\n    {\n        $builder->whereNull($model->getQualifiedDeletedAtColumn());\n    }\n\n    /**\n     * Extend the query builder with the needed functions.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    public function extend(Builder $builder)\n    {\n        foreach ($this->extensions as $extension) {\n            $this->{\"add{$extension}\"}($builder);\n        }\n\n        $builder->onDelete(function (Builder $builder) {\n            $column = $this->getDeletedAtColumn($builder);\n\n            return $builder->update([\n                $column => $builder->getModel()->freshTimestampString(),\n            ]);\n        });\n    }\n\n    /**\n     * Get the \"deleted at\" column for the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return string\n     */\n    protected function getDeletedAtColumn(Builder $builder)\n    {\n        if (count((array) $builder->getQuery()->joins) > 0) {\n            return $builder->getModel()->getQualifiedDeletedAtColumn();\n        }\n\n        return $builder->getModel()->getDeletedAtColumn();\n    }\n\n    /**\n     * Add the restore extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addRestore(Builder $builder)\n    {\n        $builder->macro('restore', function (Builder $builder) {\n            $builder->withTrashed();\n\n            return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]);\n        });\n    }\n\n    /**\n     * Add the restore-or-create extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addRestoreOrCreate(Builder $builder)\n    {\n        $builder->macro('restoreOrCreate', function (Builder $builder, array $attributes = [], array $values = []) {\n            $builder->withTrashed();\n\n            return tap($builder->firstOrCreate($attributes, $values), function ($instance) {\n                $instance->restore();\n            });\n        });\n    }\n\n    /**\n     * Add the create-or-restore extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addCreateOrRestore(Builder $builder)\n    {\n        $builder->macro('createOrRestore', function (Builder $builder, array $attributes = [], array $values = []) {\n            $builder->withTrashed();\n\n            return tap($builder->createOrFirst($attributes, $values), function ($instance) {\n                $instance->restore();\n            });\n        });\n    }\n\n    /**\n     * Add the with-trashed extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addWithTrashed(Builder $builder)\n    {\n        $builder->macro('withTrashed', function (Builder $builder, $withTrashed = true) {\n            if (! $withTrashed) {\n                return $builder->withoutTrashed();\n            }\n\n            return $builder->withoutGlobalScope($this);\n        });\n    }\n\n    /**\n     * Add the without-trashed extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addWithoutTrashed(Builder $builder)\n    {\n        $builder->macro('withoutTrashed', function (Builder $builder) {\n            $model = $builder->getModel();\n\n            $builder->withoutGlobalScope($this)->whereNull(\n                $model->getQualifiedDeletedAtColumn()\n            );\n\n            return $builder;\n        });\n    }\n\n    /**\n     * Add the only-trashed extension to the builder.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<*>  $builder\n     * @return void\n     */\n    protected function addOnlyTrashed(Builder $builder)\n    {\n        $builder->macro('onlyTrashed', function (Builder $builder) {\n            $model = $builder->getModel();\n\n            $builder->withoutGlobalScope($this)->whereNotNull(\n                $model->getQualifiedDeletedAtColumn()\n            );\n\n            return $builder;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/ConnectionEstablished.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass ConnectionEstablished extends ConnectionEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/ConnectionEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nabstract class ConnectionEvent\n{\n    /**\n     * The name of the connection.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    public $connection;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     */\n    public function __construct($connection)\n    {\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/DatabaseBusy.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass DatabaseBusy\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The database connection name.\n     * @param  int  $connections  The number of open connections.\n     */\n    public function __construct(\n        public $connectionName,\n        public $connections,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/DatabaseRefreshed.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Contracts\\Database\\Events\\MigrationEvent as MigrationEventContract;\n\nclass DatabaseRefreshed implements MigrationEventContract\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $database\n     * @param  bool  $seeding\n     */\n    public function __construct(\n        public ?string $database = null,\n        public bool $seeding = false,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationEnded.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass MigrationEnded extends MigrationEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Contracts\\Database\\Events\\MigrationEvent as MigrationEventContract;\nuse Illuminate\\Database\\Migrations\\Migration;\n\nabstract class MigrationEvent implements MigrationEventContract\n{\n    /**\n     * A migration instance.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\Migration\n     */\n    public $migration;\n\n    /**\n     * The migration method that was called.\n     *\n     * @var string\n     */\n    public $method;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\Migration  $migration\n     * @param  string  $method\n     */\n    public function __construct(Migration $migration, $method)\n    {\n        $this->method = $method;\n        $this->migration = $migration;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationSkipped.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Contracts\\Database\\Events\\MigrationEvent;\n\nclass MigrationSkipped implements MigrationEvent\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $migrationName  The name of the migration that was skipped.\n     */\n    public function __construct(\n        public $migrationName,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationStarted.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass MigrationStarted extends MigrationEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationsEnded.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass MigrationsEnded extends MigrationsEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationsEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Contracts\\Database\\Events\\MigrationEvent as MigrationEventContract;\n\nabstract class MigrationsEvent implements MigrationEventContract\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $method  The migration method that was invoked.\n     * @param  array<string, mixed>  $options  The options provided when the migration method was invoked.\n     */\n    public function __construct(\n        public $method,\n        public array $options = [],\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationsPruned.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Database\\Connection;\n\nclass MigrationsPruned\n{\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    public $connection;\n\n    /**\n     * The database connection name.\n     *\n     * @var string|null\n     */\n    public $connectionName;\n\n    /**\n     * The path to the directory where migrations were pruned.\n     *\n     * @var string\n     */\n    public $path;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     */\n    public function __construct(Connection $connection, string $path)\n    {\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n        $this->path = $path;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/MigrationsStarted.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass MigrationsStarted extends MigrationsEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/ModelPruningFinished.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass ModelPruningFinished\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  array<class-string>  $models  The class names of the models that were pruned.\n     */\n    public function __construct(\n        public $models,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/ModelPruningStarting.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass ModelPruningStarting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  array<class-string>  $models  The class names of the models that will be pruned.\n     */\n    public function __construct(\n        public $models,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/ModelsPruned.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass ModelsPruned\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $model  The class name of the model that was pruned.\n     * @param  int  $count  The number of pruned records.\n     */\n    public function __construct(\n        public $model,\n        public $count,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/NoPendingMigrations.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nuse Illuminate\\Contracts\\Database\\Events\\MigrationEvent;\n\nclass NoPendingMigrations implements MigrationEvent\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $method  The migration method that was called.\n     */\n    public function __construct(\n        public $method,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/QueryExecuted.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass QueryExecuted\n{\n    /**\n     * The SQL query that was executed.\n     *\n     * @var string\n     */\n    public $sql;\n\n    /**\n     * The array of query bindings.\n     *\n     * @var array\n     */\n    public $bindings;\n\n    /**\n     * The number of milliseconds it took to execute the query.\n     *\n     * @var float\n     */\n    public $time;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    public $connection;\n\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * The PDO read / write type for the executed query.\n     *\n     * @var null|'read'|'write'\n     */\n    public $readWriteType;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $sql\n     * @param  array  $bindings\n     * @param  float|null  $time\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  null|'read'|'write'  $readWriteType\n     */\n    public function __construct($sql, $bindings, $time, $connection, $readWriteType = null)\n    {\n        $this->sql = $sql;\n        $this->time = $time;\n        $this->bindings = $bindings;\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n        $this->readWriteType = $readWriteType;\n    }\n\n    /**\n     * Get the raw SQL representation of the query with embedded bindings.\n     *\n     * @return string\n     */\n    public function toRawSql()\n    {\n        return $this->connection\n            ->query()\n            ->getGrammar()\n            ->substituteBindingsIntoRawSql($this->sql, $this->connection->prepareBindings($this->bindings));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/SchemaDumped.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass SchemaDumped\n{\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    public $connection;\n\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * The path to the schema dump.\n     *\n     * @var string\n     */\n    public $path;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     */\n    public function __construct($connection, $path)\n    {\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n        $this->path = $path;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/SchemaLoaded.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass SchemaLoaded\n{\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    public $connection;\n\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * The path to the schema dump.\n     *\n     * @var string\n     */\n    public $path;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     */\n    public function __construct($connection, $path)\n    {\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n        $this->path = $path;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/StatementPrepared.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass StatementPrepared\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection  The database connection instance.\n     * @param  \\PDOStatement  $statement  The PDO statement.\n     */\n    public function __construct(\n        public $connection,\n        public $statement,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/TransactionBeginning.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass TransactionBeginning extends ConnectionEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/TransactionCommitted.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass TransactionCommitted extends ConnectionEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/TransactionCommitting.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass TransactionCommitting extends ConnectionEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Events/TransactionRolledBack.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Events;\n\nclass TransactionRolledBack extends ConnectionEvent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Grammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\n\nabstract class Grammar\n{\n    use Macroable;\n\n    /**\n     * The connection used for escaping values.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * Create a new grammar instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     */\n    public function __construct(Connection $connection)\n    {\n        $this->connection = $connection;\n    }\n\n    /**\n     * Wrap an array of values.\n     *\n     * @param  array<\\Illuminate\\Contracts\\Database\\Query\\Expression|string>  $values\n     * @return array<string>\n     */\n    public function wrapArray(array $values)\n    {\n        return array_map($this->wrap(...), $values);\n    }\n\n    /**\n     * Wrap a table in keyword identifiers.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  string|null  $prefix\n     * @return string\n     */\n    public function wrapTable($table, $prefix = null)\n    {\n        if ($this->isExpression($table)) {\n            return $this->getValue($table);\n        }\n\n        $prefix ??= $this->connection->getTablePrefix();\n\n        // If the table being wrapped has an alias we'll need to separate the pieces\n        // so we can prefix the table and then wrap each of the segments on their\n        // own and then join these both back together using the \"as\" connector.\n        if (stripos($table, ' as ') !== false) {\n            return $this->wrapAliasedTable($table, $prefix);\n        }\n\n        // If the table being wrapped has a custom schema name specified, we need to\n        // prefix the last segment as the table name then wrap each segment alone\n        // and eventually join them both back together using the dot connector.\n        if (str_contains($table, '.')) {\n            $table = substr_replace($table, '.'.$prefix, strrpos($table, '.'), 1);\n\n            return (new Collection(explode('.', $table)))\n                ->map($this->wrapValue(...))\n                ->implode('.');\n        }\n\n        return $this->wrapValue($prefix.$table);\n    }\n\n    /**\n     * Wrap a value in keyword identifiers.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $value\n     * @return string\n     */\n    public function wrap($value)\n    {\n        if ($this->isExpression($value)) {\n            return $this->getValue($value);\n        }\n\n        // If the value being wrapped has a column alias we will need to separate out\n        // the pieces so we can wrap each of the segments of the expression on its\n        // own, and then join these both back together using the \"as\" connector.\n        if (stripos($value, ' as ') !== false) {\n            return $this->wrapAliasedValue($value);\n        }\n\n        // If the given value is a JSON selector we will wrap it differently than a\n        // traditional value. We will need to split this path and wrap each part\n        // wrapped, etc. Otherwise, we will simply wrap the value as a string.\n        if ($this->isJsonSelector($value)) {\n            return $this->wrapJsonSelector($value);\n        }\n\n        return $this->wrapSegments(explode('.', $value));\n    }\n\n    /**\n     * Wrap a value that has an alias.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapAliasedValue($value)\n    {\n        $segments = preg_split('/\\s+as\\s+/i', $value);\n\n        return $this->wrap($segments[0]).' as '.$this->wrapValue($segments[1]);\n    }\n\n    /**\n     * Wrap a table that has an alias.\n     *\n     * @param  string  $value\n     * @param  string|null  $prefix\n     * @return string\n     */\n    protected function wrapAliasedTable($value, $prefix = null)\n    {\n        $segments = preg_split('/\\s+as\\s+/i', $value);\n\n        $prefix ??= $this->connection->getTablePrefix();\n\n        return $this->wrapTable($segments[0], $prefix).' as '.$this->wrapValue($prefix.$segments[1]);\n    }\n\n    /**\n     * Wrap the given value segments.\n     *\n     * @param  list<string>  $segments\n     * @return string\n     */\n    protected function wrapSegments($segments)\n    {\n        return (new Collection($segments))->map(function ($segment, $key) use ($segments) {\n            return $key == 0 && count($segments) > 1\n                ? $this->wrapTable($segment)\n                : $this->wrapValue($segment);\n        })->implode('.');\n    }\n\n    /**\n     * Wrap a single string in keyword identifiers.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapValue($value)\n    {\n        if ($value !== '*') {\n            return '\"'.str_replace('\"', '\"\"', $value).'\"';\n        }\n\n        return $value;\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function wrapJsonSelector($value)\n    {\n        throw new RuntimeException('This database engine does not support JSON operations.');\n    }\n\n    /**\n     * Determine if the given string is a JSON selector.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    protected function isJsonSelector($value)\n    {\n        return str_contains($value, '->');\n    }\n\n    /**\n     * Convert an array of column names into a delimited string.\n     *\n     * @param  array<\\Illuminate\\Contracts\\Database\\Query\\Expression|string>  $columns\n     * @return string\n     */\n    public function columnize(array $columns)\n    {\n        return implode(', ', array_map($this->wrap(...), $columns));\n    }\n\n    /**\n     * Create query parameter place-holders for an array.\n     *\n     * @param  array<mixed>  $values\n     * @return string\n     */\n    public function parameterize(array $values)\n    {\n        return implode(', ', array_map($this->parameter(...), $values));\n    }\n\n    /**\n     * Get the appropriate query parameter place-holder for a value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    public function parameter($value)\n    {\n        return $this->isExpression($value) ? $this->getValue($value) : '?';\n    }\n\n    /**\n     * Quote the given string literal.\n     *\n     * @param  string|array<string>  $value\n     * @return string\n     */\n    public function quoteString($value)\n    {\n        if (is_array($value)) {\n            return implode(', ', array_map([$this, __FUNCTION__], $value));\n        }\n\n        return \"'$value'\";\n    }\n\n    /**\n     * Escapes a value for safe SQL embedding.\n     *\n     * @param  string|float|int|bool|null  $value\n     * @param  bool  $binary\n     * @return string\n     */\n    public function escape($value, $binary = false)\n    {\n        return $this->connection->escape($value, $binary);\n    }\n\n    /**\n     * Determine if the given value is a raw expression.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function isExpression($value)\n    {\n        return $value instanceof Expression;\n    }\n\n    /**\n     * Transforms expressions to their scalar types.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|int|float  $expression\n     * @return string|int|float\n     */\n    public function getValue($expression)\n    {\n        if ($this->isExpression($expression)) {\n            return $this->getValue($expression->getValue($this));\n        }\n\n        return $expression;\n    }\n\n    /**\n     * Get the format for database stored dates.\n     *\n     * @return string\n     */\n    public function getDateFormat()\n    {\n        return 'Y-m-d H:i:s';\n    }\n\n    /**\n     * Get the grammar's table prefix.\n     *\n     * @deprecated Use DB::getTablePrefix()\n     *\n     * @return string\n     */\n    public function getTablePrefix()\n    {\n        return $this->connection->getTablePrefix();\n    }\n\n    /**\n     * Set the grammar's table prefix.\n     *\n     * @deprecated Use DB::setTablePrefix()\n     *\n     * @param  string  $prefix\n     * @return $this\n     */\n    public function setTablePrefix($prefix)\n    {\n        $this->connection->setTablePrefix($prefix);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Database/LazyLoadingViolationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass LazyLoadingViolationException extends RuntimeException\n{\n    /**\n     * The name of the affected Eloquent model.\n     *\n     * @var string\n     */\n    public $model;\n\n    /**\n     * The name of the relation.\n     *\n     * @var string\n     */\n    public $relation;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  object  $model\n     * @param  string  $relation\n     */\n    public function __construct($model, $relation)\n    {\n        $class = get_class($model);\n\n        parent::__construct(\"Attempted to lazy load [{$relation}] on model [{$class}] but lazy loading is disabled.\");\n\n        $this->model = $class;\n        $this->relation = $relation;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/LostConnectionDetector.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Contracts\\Database\\LostConnectionDetector as LostConnectionDetectorContract;\nuse Illuminate\\Support\\Str;\nuse Throwable;\n\nclass LostConnectionDetector implements LostConnectionDetectorContract\n{\n    /**\n     * Determine if the given exception was caused by a lost connection.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function causedByLostConnection(Throwable $e): bool\n    {\n        $message = $e->getMessage();\n\n        return Str::contains($message, [\n            'server has gone away',\n            'Server has gone away',\n            'no connection to the server',\n            'Lost connection',\n            'is dead or not enabled',\n            'Error while sending',\n            'decryption failed or bad record mac',\n            'server closed the connection unexpectedly',\n            'SSL connection has been closed unexpectedly',\n            'Error writing data to the connection',\n            'Resource deadlock avoided',\n            'Transaction() on null',\n            'child connection forced to terminate due to client_idle_limit',\n            'query_wait_timeout',\n            'reset by peer',\n            'Physical connection is not usable',\n            'TCP Provider: Error code 0x68',\n            'ORA-03114',\n            'Packets out of order. Expected',\n            'Adaptive Server connection failed',\n            'Communication link failure',\n            'connection is no longer usable',\n            'Login timeout expired',\n            'SQLSTATE[HY000] [2002] Connection refused',\n            'running with the --read-only option so it cannot execute this statement',\n            'The connection is broken and recovery is not possible. The connection is marked by the client driver as unrecoverable. No attempt was made to restore the connection.',\n            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Try again',\n            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known',\n            'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for',\n            'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: EOF detected',\n            'SSL error: unexpected eof',\n            'SQLSTATE[HY000] [2002] Connection timed out',\n            'SSL: Connection timed out',\n            'SQLSTATE[HY000]: General error: 1105 The last transaction was aborted due to Seamless Scaling. Please retry.',\n            'Temporary failure in name resolution',\n            'SQLSTATE[08S01]: Communication link failure',\n            'SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host',\n            'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: No route to host',\n            'The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.',\n            'SQLSTATE[08006] [7] could not translate host name',\n            'TCP Provider: Error code 0x274C',\n            'SQLSTATE[HY000] [2002] No such file or directory',\n            'SSL: Operation timed out',\n            'Reason: Server is in script upgrade mode. Only administrator can connect at this time.',\n            'Unknown $curl_error_code: 77',\n            'SSL: Handshake timed out',\n            'SSL error: sslv3 alert unexpected message',\n            'unrecognized SSL error code:',\n            'SQLSTATE[HY000] [1045] Access denied for user',\n            'SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it',\n            'SQLSTATE[HY000] [2002] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond',\n            'SQLSTATE[HY000] [2002] Network is unreachable',\n            'SQLSTATE[HY000] [2002] The requested address is not valid in its context',\n            'SQLSTATE[HY000] [2002] A socket operation was attempted to an unreachable network',\n            'SQLSTATE[HY000] [2002] Operation now in progress',\n            'SQLSTATE[HY000] [2002] Operation in progress',\n            'SQLSTATE[HY000]: General error: 3989',\n            'went away',\n            'No such file or directory',\n            'server is shutting down',\n            'failed to connect to',\n            'Channel connection is closed',\n            'Connection lost',\n            'Broken pipe',\n            'SQLSTATE[25006]: Read only sql transaction: 7',\n\n            // PlanetScale MySQL / Vitess related things...\n            'vtgate connection error: no healthy endpoints',\n            'primary is not serving, there may be a reparent operation in progress',\n            'current keyspace is being resharded',\n            'no healthy tablet available',\n            'transaction pool connection limit exceeded',\n            'SSL operation failed with code 5',\n\n            // PlanetScale PostgreSQL / pg_bouncer related things...\n            'no primary available for branch',\n            'no replica available for branch',\n            'no running members available for branch',\n            'failed to connect to upstream',\n            'failed to send startup message',\n            'failed to read startup message',\n            'canceling statement due to conflict with recovery',\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/LostConnectionException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse LogicException;\n\nclass LostConnectionException extends LogicException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/MariaDbConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Database\\Query\\Grammars\\MariaDbGrammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\MariaDbProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\MariaDbGrammar as SchemaGrammar;\nuse Illuminate\\Database\\Schema\\MariaDbBuilder;\nuse Illuminate\\Database\\Schema\\MariaDbSchemaState;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\n\nclass MariaDbConnection extends MySqlConnection\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function getDriverTitle()\n    {\n        return 'MariaDB';\n    }\n\n    /**\n     * Determine if the connected database is a MariaDB database.\n     *\n     * @return bool\n     */\n    public function isMaria()\n    {\n        return true;\n    }\n\n    /**\n     * Get the server version for the connection.\n     *\n     * @return string\n     */\n    public function getServerVersion(): string\n    {\n        return Str::between(parent::getServerVersion(), '5.5.5-', '-MariaDB');\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\MariaDbGrammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\MariaDbBuilder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new MariaDbBuilder($this);\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\MariaDbGrammar\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        return new SchemaGrammar($this);\n    }\n\n    /**\n     * Get the schema state for the connection.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     * @return \\Illuminate\\Database\\Schema\\MariaDbSchemaState\n     */\n    public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        return new MariaDbSchemaState($this, $files, $processFactory);\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\MariaDbProcessor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new MariaDbProcessor;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/MigrationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Database\\Console\\Migrations\\FreshCommand;\nuse Illuminate\\Database\\Console\\Migrations\\InstallCommand;\nuse Illuminate\\Database\\Console\\Migrations\\MigrateCommand;\nuse Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RefreshCommand;\nuse Illuminate\\Database\\Console\\Migrations\\ResetCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RollbackCommand;\nuse Illuminate\\Database\\Console\\Migrations\\StatusCommand;\nuse Illuminate\\Database\\Migrations\\DatabaseMigrationRepository;\nuse Illuminate\\Database\\Migrations\\MigrationCreator;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass MigrationServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * The commands to be registered.\n     *\n     * @var array\n     */\n    protected $commands = [\n        'Migrate' => MigrateCommand::class,\n        'MigrateFresh' => FreshCommand::class,\n        'MigrateInstall' => InstallCommand::class,\n        'MigrateRefresh' => RefreshCommand::class,\n        'MigrateReset' => ResetCommand::class,\n        'MigrateRollback' => RollbackCommand::class,\n        'MigrateStatus' => StatusCommand::class,\n        'MigrateMake' => MigrateMakeCommand::class,\n    ];\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerRepository();\n\n        $this->registerMigrator();\n\n        $this->registerCreator();\n\n        $this->registerCommands($this->commands);\n    }\n\n    /**\n     * Register the migration repository service.\n     *\n     * @return void\n     */\n    protected function registerRepository()\n    {\n        $this->app->singleton('migration.repository', function ($app) {\n            $migrations = $app['config']['database.migrations'];\n\n            $table = is_array($migrations) ? ($migrations['table'] ?? null) : $migrations;\n\n            return new DatabaseMigrationRepository($app['db'], $table);\n        });\n    }\n\n    /**\n     * Register the migrator service.\n     *\n     * @return void\n     */\n    protected function registerMigrator()\n    {\n        // The migrator is responsible for actually running and rollback the migration\n        // files in the application. We'll pass in our database connection resolver\n        // so the migrator can resolve any of these connections when it needs to.\n        $this->app->singleton('migrator', function ($app) {\n            $repository = $app['migration.repository'];\n\n            return new Migrator($repository, $app['db'], $app['files'], $app['events']);\n        });\n\n        $this->app->bind(Migrator::class, fn ($app) => $app['migrator']);\n    }\n\n    /**\n     * Register the migration creator.\n     *\n     * @return void\n     */\n    protected function registerCreator()\n    {\n        $this->app->singleton('migration.creator', function ($app) {\n            return new MigrationCreator($app['files'], $app->basePath('stubs'));\n        });\n    }\n\n    /**\n     * Register the given commands.\n     *\n     * @param  array  $commands\n     * @return void\n     */\n    protected function registerCommands(array $commands)\n    {\n        foreach (array_keys($commands) as $command) {\n            $this->{\"register{$command}Command\"}();\n        }\n\n        $this->commands(array_values($commands));\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateCommand()\n    {\n        $this->app->singleton(MigrateCommand::class, function ($app) {\n            return new MigrateCommand($app['migrator'], $app[Dispatcher::class]);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateFreshCommand()\n    {\n        $this->app->singleton(FreshCommand::class, function ($app) {\n            return new FreshCommand($app['migrator']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateInstallCommand()\n    {\n        $this->app->singleton(InstallCommand::class, function ($app) {\n            return new InstallCommand($app['migration.repository']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateMakeCommand()\n    {\n        $this->app->singleton(MigrateMakeCommand::class, function ($app) {\n            // Once we have the migration creator registered, we will create the command\n            // and inject the creator. The creator is responsible for the actual file\n            // creation of the migrations, and may be extended by these developers.\n            $creator = $app['migration.creator'];\n\n            $composer = $app['composer'];\n\n            return new MigrateMakeCommand($creator, $composer);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateRefreshCommand()\n    {\n        $this->app->singleton(RefreshCommand::class);\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateResetCommand()\n    {\n        $this->app->singleton(ResetCommand::class, function ($app) {\n            return new ResetCommand($app['migrator']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateRollbackCommand()\n    {\n        $this->app->singleton(RollbackCommand::class, function ($app) {\n            return new RollbackCommand($app['migrator']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMigrateStatusCommand()\n    {\n        $this->app->singleton(StatusCommand::class, function ($app) {\n            return new StatusCommand($app['migrator']);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return array_merge([\n            'migrator', 'migration.repository', 'migration.creator', Migrator::class,\n        ], array_values($this->commands));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\nuse Illuminate\\Database\\ConnectionResolverInterface as Resolver;\n\nclass DatabaseMigrationRepository implements MigrationRepositoryInterface\n{\n    /**\n     * The database connection resolver instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $resolver;\n\n    /**\n     * The name of the migration table.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The name of the database connection to use.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * Create a new database migration repository instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     * @param  string  $table\n     */\n    public function __construct(Resolver $resolver, $table)\n    {\n        $this->table = $table;\n        $this->resolver = $resolver;\n    }\n\n    /**\n     * Get the completed migrations.\n     *\n     * @return string[]\n     */\n    public function getRan()\n    {\n        return $this->table()\n            ->orderBy('batch', 'asc')\n            ->orderBy('migration', 'asc')\n            ->pluck('migration')->all();\n    }\n\n    /**\n     * Get the list of migrations.\n     *\n     * @param  int  $steps\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getMigrations($steps)\n    {\n        $query = $this->table()->where('batch', '>=', '1');\n\n        return $query->orderBy('batch', 'desc')\n            ->orderBy('migration', 'desc')\n            ->limit($steps)\n            ->get()\n            ->all();\n    }\n\n    /**\n     * Get the list of the migrations by batch number.\n     *\n     * @param  int  $batch\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getMigrationsByBatch($batch)\n    {\n        return $this->table()\n            ->where('batch', $batch)\n            ->orderBy('migration', 'desc')\n            ->get()\n            ->all();\n    }\n\n    /**\n     * Get the last migration batch.\n     *\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getLast()\n    {\n        $query = $this->table()->where('batch', $this->getLastBatchNumber());\n\n        return $query->orderBy('migration', 'desc')->get()->all();\n    }\n\n    /**\n     * Get the completed migrations with their batch numbers.\n     *\n     * @return array<int, string>[]\n     */\n    public function getMigrationBatches()\n    {\n        return $this->table()\n            ->orderBy('batch', 'asc')\n            ->orderBy('migration', 'asc')\n            ->pluck('batch', 'migration')->all();\n    }\n\n    /**\n     * Log that a migration was run.\n     *\n     * @param  string  $file\n     * @param  int  $batch\n     * @return void\n     */\n    public function log($file, $batch)\n    {\n        $record = ['migration' => $file, 'batch' => $batch];\n\n        $this->table()->insert($record);\n    }\n\n    /**\n     * Remove a migration from the log.\n     *\n     * @param  object{id?: int, migration: string, batch?: int}  $migration\n     * @return void\n     */\n    public function delete($migration)\n    {\n        $this->table()->where('migration', $migration->migration)->delete();\n    }\n\n    /**\n     * Get the next migration batch number.\n     *\n     * @return int\n     */\n    public function getNextBatchNumber()\n    {\n        return $this->getLastBatchNumber() + 1;\n    }\n\n    /**\n     * Get the last migration batch number.\n     *\n     * @return int\n     */\n    public function getLastBatchNumber()\n    {\n        return $this->table()->max('batch');\n    }\n\n    /**\n     * Create the migration repository data store.\n     *\n     * @return void\n     */\n    public function createRepository()\n    {\n        $schema = $this->getConnection()->getSchemaBuilder();\n\n        $schema->create($this->table, function ($table) {\n            // The migrations table is responsible for keeping track of which of the\n            // migrations have actually run for the application. We'll create the\n            // table to hold the migration file's path as well as the batch ID.\n            $table->increments('id');\n            $table->string('migration');\n            $table->integer('batch');\n        });\n    }\n\n    /**\n     * Determine if the migration repository exists.\n     *\n     * @return bool\n     */\n    public function repositoryExists()\n    {\n        $schema = $this->getConnection()->getSchemaBuilder();\n\n        return $schema->hasTable($this->table);\n    }\n\n    /**\n     * Delete the migration repository data store.\n     *\n     * @return void\n     */\n    public function deleteRepository()\n    {\n        $schema = $this->getConnection()->getSchemaBuilder();\n\n        $schema->drop($this->table);\n    }\n\n    /**\n     * Get a query builder for the migration table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function table()\n    {\n        return $this->getConnection()->table($this->table)->useWritePdo();\n    }\n\n    /**\n     * Get the connection resolver instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    public function getConnectionResolver()\n    {\n        return $this->resolver;\n    }\n\n    /**\n     * Resolve the database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getConnection()\n    {\n        return $this->resolver->connection($this->connection);\n    }\n\n    /**\n     * Set the information source to gather data.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setSource($name)\n    {\n        $this->connection = $name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/Migration.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\nabstract class Migration\n{\n    /**\n     * The name of the database connection to use.\n     *\n     * @var string|null\n     */\n    protected $connection;\n\n    /**\n     * Enables, if supported, wrapping the migration within a transaction.\n     *\n     * @var bool\n     */\n    public $withinTransaction = true;\n\n    /**\n     * Get the migration connection name.\n     *\n     * @return string|null\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Determine if this migration should run.\n     *\n     * @return bool\n     */\n    public function shouldRun(): bool\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/MigrationCreator.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\nuse Closure;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass MigrationCreator\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The custom app stubs directory.\n     *\n     * @var string\n     */\n    protected $customStubPath;\n\n    /**\n     * The registered post create hooks.\n     *\n     * @var (\\Closure(string, string): void)[]\n     */\n    protected $postCreate = [];\n\n    /**\n     * Create a new migration creator instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $customStubPath\n     */\n    public function __construct(Filesystem $files, $customStubPath)\n    {\n        $this->files = $files;\n        $this->customStubPath = $customStubPath;\n    }\n\n    /**\n     * Create a new migration at the given path.\n     *\n     * @param  string  $name\n     * @param  string  $path\n     * @param  string|null  $table\n     * @param  bool  $create\n     * @return string\n     *\n     * @throws \\Exception\n     */\n    public function create($name, $path, $table = null, $create = false)\n    {\n        $this->ensureMigrationDoesntAlreadyExist($name, $path);\n\n        // First we will get the stub file for the migration, which serves as a type\n        // of template for the migration. Once we have those we will populate the\n        // various place-holders, save the file, and run the post create event.\n        $stub = $this->getStub($table, $create);\n\n        $path = $this->getPath($name, $path);\n\n        $this->files->ensureDirectoryExists(dirname($path));\n\n        $this->files->put(\n            $path, $this->populateStub($stub, $table)\n        );\n\n        // Next, we will fire any hooks that are supposed to fire after a migration is\n        // created. Once that is done we'll be ready to return the full path to the\n        // migration file so it can be used however it's needed by the developer.\n        $this->firePostCreateHooks($table, $path);\n\n        return $path;\n    }\n\n    /**\n     * Ensure that a migration with the given name doesn't already exist.\n     *\n     * @param  string  $name\n     * @param  string|null  $migrationPath\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function ensureMigrationDoesntAlreadyExist($name, $migrationPath = null)\n    {\n        if (! empty($migrationPath)) {\n            $migrationFiles = $this->files->glob($migrationPath.'/*.php');\n\n            foreach ($migrationFiles as $migrationFile) {\n                $this->files->requireOnce($migrationFile);\n            }\n        }\n\n        if (class_exists($className = $this->getClassName($name))) {\n            throw new InvalidArgumentException(\"A {$className} class already exists.\");\n        }\n    }\n\n    /**\n     * Get the migration stub file.\n     *\n     * @param  string|null  $table\n     * @param  bool  $create\n     * @return string\n     */\n    protected function getStub($table, $create)\n    {\n        if (is_null($table)) {\n            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.stub')\n                ? $customPath\n                : $this->stubPath().'/migration.stub';\n        } elseif ($create) {\n            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.create.stub')\n                ? $customPath\n                : $this->stubPath().'/migration.create.stub';\n        } else {\n            $stub = $this->files->exists($customPath = $this->customStubPath.'/migration.update.stub')\n                ? $customPath\n                : $this->stubPath().'/migration.update.stub';\n        }\n\n        return $this->files->get($stub);\n    }\n\n    /**\n     * Populate the place-holders in the migration stub.\n     *\n     * @param  string  $stub\n     * @param  string|null  $table\n     * @return string\n     */\n    protected function populateStub($stub, $table)\n    {\n        // Here we will replace the table place-holders with the table specified by\n        // the developer, which is useful for quickly creating a tables creation\n        // or update migration from the console instead of typing it manually.\n        if (! is_null($table)) {\n            $stub = str_replace(\n                ['DummyTable', '{{ table }}', '{{table}}'],\n                $table, $stub\n            );\n        }\n\n        return $stub;\n    }\n\n    /**\n     * Get the class name of a migration name.\n     *\n     * @param  string  $name\n     * @return class-string<\\Illuminate\\Database\\Migrations\\Migration>\n     */\n    protected function getClassName($name)\n    {\n        return Str::studly($name);\n    }\n\n    /**\n     * Get the full path to the migration.\n     *\n     * @param  string  $name\n     * @param  string  $path\n     * @return string\n     */\n    protected function getPath($name, $path)\n    {\n        return $path.'/'.$this->getDatePrefix().'_'.$name.'.php';\n    }\n\n    /**\n     * Fire the registered post create hooks.\n     *\n     * @param  string|null  $table\n     * @param  string  $path\n     * @return void\n     */\n    protected function firePostCreateHooks($table, $path)\n    {\n        foreach ($this->postCreate as $callback) {\n            $callback($table, $path);\n        }\n    }\n\n    /**\n     * Register a post migration create hook.\n     *\n     * @param  (\\Closure(string, string): void)  $callback\n     * @return void\n     */\n    public function afterCreate(Closure $callback)\n    {\n        $this->postCreate[] = $callback;\n    }\n\n    /**\n     * Get the date prefix for the migration.\n     *\n     * @return string\n     */\n    protected function getDatePrefix()\n    {\n        return date('Y_m_d_His');\n    }\n\n    /**\n     * Get the path to the stubs.\n     *\n     * @return string\n     */\n    public function stubPath()\n    {\n        return __DIR__.'/stubs';\n    }\n\n    /**\n     * Get the filesystem instance.\n     *\n     * @return \\Illuminate\\Filesystem\\Filesystem\n     */\n    public function getFilesystem()\n    {\n        return $this->files;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\ninterface MigrationRepositoryInterface\n{\n    /**\n     * Get the completed migrations.\n     *\n     * @return string[]\n     */\n    public function getRan();\n\n    /**\n     * Get the list of migrations.\n     *\n     * @param  int  $steps\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getMigrations($steps);\n\n    /**\n     * Get the list of the migrations by batch.\n     *\n     * @param  int  $batch\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getMigrationsByBatch($batch);\n\n    /**\n     * Get the last migration batch.\n     *\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    public function getLast();\n\n    /**\n     * Get the completed migrations with their batch numbers.\n     *\n     * @return array<int, string>[]\n     */\n    public function getMigrationBatches();\n\n    /**\n     * Log that a migration was run.\n     *\n     * @param  string  $file\n     * @param  int  $batch\n     * @return void\n     */\n    public function log($file, $batch);\n\n    /**\n     * Remove a migration from the log.\n     *\n     * @param  objectt{id?: int, migration: string, batch?: int}  $migration\n     * @return void\n     */\n    public function delete($migration);\n\n    /**\n     * Get the next migration batch number.\n     *\n     * @return int\n     */\n    public function getNextBatchNumber();\n\n    /**\n     * Create the migration repository data store.\n     *\n     * @return void\n     */\n    public function createRepository();\n\n    /**\n     * Determine if the migration repository exists.\n     *\n     * @return bool\n     */\n    public function repositoryExists();\n\n    /**\n     * Delete the migration repository data store.\n     *\n     * @return void\n     */\n    public function deleteRepository();\n\n    /**\n     * Set the information source to gather data.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setSource($name);\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/MigrationResult.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\nenum MigrationResult: int\n{\n    case Success = 1;\n    case Failure = 2;\n    case Skipped = 3;\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/Migrator.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Migrations;\n\nuse Closure;\nuse Illuminate\\Console\\View\\Components\\BulletList;\nuse Illuminate\\Console\\View\\Components\\Info;\nuse Illuminate\\Console\\View\\Components\\Task;\nuse Illuminate\\Console\\View\\Components\\TwoColumnDetail;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\ConnectionResolverInterface as Resolver;\nuse Illuminate\\Database\\Events\\MigrationEnded;\nuse Illuminate\\Database\\Events\\MigrationsEnded;\nuse Illuminate\\Database\\Events\\MigrationSkipped;\nuse Illuminate\\Database\\Events\\MigrationsStarted;\nuse Illuminate\\Database\\Events\\MigrationStarted;\nuse Illuminate\\Database\\Events\\NoPendingMigrations;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass Migrator\n{\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The migration repository implementation.\n     *\n     * @var \\Illuminate\\Database\\Migrations\\MigrationRepositoryInterface\n     */\n    protected $repository;\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The connection resolver instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $resolver;\n\n    /**\n     * The custom connection resolver callback.\n     *\n     * @var (\\Closure(\\Illuminate\\Database\\ConnectionResolverInterface, ?string): \\Illuminate\\Database\\Connection)|null\n     */\n    protected static $connectionResolverCallback;\n\n    /**\n     * The name of the default connection.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * The paths to all of the migration files.\n     *\n     * @var string[]\n     */\n    protected $paths = [];\n\n    /**\n     * The paths that have already been required.\n     *\n     * @var array<string, \\Illuminate\\Database\\Migrations\\Migration|null>\n     */\n    protected static $requiredPathCache = [];\n\n    /**\n     * The output interface implementation.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    protected $output;\n\n    /**\n     * The pending migrations to skip.\n     *\n     * @var list<string>\n     */\n    protected static $withoutMigrations = [];\n\n    /**\n     * Create a new migrator instance.\n     *\n     * @param  \\Illuminate\\Database\\Migrations\\MigrationRepositoryInterface  $repository\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher|null  $dispatcher\n     */\n    public function __construct(\n        MigrationRepositoryInterface $repository,\n        Resolver $resolver,\n        Filesystem $files,\n        ?Dispatcher $dispatcher = null,\n    ) {\n        $this->files = $files;\n        $this->events = $dispatcher;\n        $this->resolver = $resolver;\n        $this->repository = $repository;\n    }\n\n    /**\n     * Run the pending migrations at a given path.\n     *\n     * @param  string[]|string  $paths\n     * @param  array<string, mixed>  $options\n     * @return string[]\n     */\n    public function run($paths = [], array $options = [])\n    {\n        // Once we grab all of the migration files for the path, we will compare them\n        // against the migrations that have already been run for this package then\n        // run each of the outstanding migrations against a database connection.\n        $files = $this->getMigrationFiles($paths);\n\n        $this->requireFiles($migrations = $this->pendingMigrations(\n            $files, $this->repository->getRan()\n        ));\n\n        // Once we have all these migrations that are outstanding we are ready to run\n        // we will go ahead and run them \"up\". This will execute each migration as\n        // an operation against a database. Then we'll return this list of them.\n        $this->runPending($migrations, $options);\n\n        return $migrations;\n    }\n\n    /**\n     * Get the migration files that have not yet run.\n     *\n     * @param  string[]  $files\n     * @param  string[]  $ran\n     * @return string[]\n     */\n    protected function pendingMigrations($files, $ran)\n    {\n        $migrationsToSkip = $this->migrationsToSkip();\n\n        return (new Collection($files))\n            ->reject(fn ($file) => in_array($migrationName = $this->getMigrationName($file), $ran) ||\n                in_array($migrationName, $migrationsToSkip)\n            )\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Get list of pending migrations to skip.\n     *\n     * @return list<string>\n     */\n    protected function migrationsToSkip()\n    {\n        return (new Collection(self::$withoutMigrations))\n            ->map($this->getMigrationName(...))\n            ->all();\n    }\n\n    /**\n     * Run an array of migrations.\n     *\n     * @param  string[]  $migrations\n     * @param  array<string, mixed>  $options\n     * @return void\n     */\n    public function runPending(array $migrations, array $options = [])\n    {\n        // First we will just make sure that there are any migrations to run. If there\n        // aren't, we will just make a note of it to the developer so they're aware\n        // that all of the migrations have been run against this database system.\n        if (count($migrations) === 0) {\n            $this->fireMigrationEvent(new NoPendingMigrations('up'));\n\n            $this->write(Info::class, 'Nothing to migrate');\n\n            return;\n        }\n\n        // Next, we will get the next batch number for the migrations so we can insert\n        // correct batch number in the database migrations repository when we store\n        // each migration's execution. We will also extract a few of the options.\n        $batch = $this->repository->getNextBatchNumber();\n\n        $pretend = $options['pretend'] ?? false;\n\n        $step = $options['step'] ?? false;\n\n        $this->fireMigrationEvent(new MigrationsStarted('up', $options));\n\n        $this->write(Info::class, 'Running migrations.');\n\n        // Once we have the array of migrations, we will spin through them and run the\n        // migrations \"up\" so the changes are made to the databases. We'll then log\n        // that the migration was run so we don't repeat it next time we execute.\n        foreach ($migrations as $file) {\n            $this->runUp($file, $batch, $pretend);\n\n            if ($step) {\n                $batch++;\n            }\n        }\n\n        $this->fireMigrationEvent(new MigrationsEnded('up', $options));\n\n        $this->output?->writeln('');\n    }\n\n    /**\n     * Run \"up\" a migration instance.\n     *\n     * @param  string  $file\n     * @param  int  $batch\n     * @param  bool  $pretend\n     * @return void\n     */\n    protected function runUp($file, $batch, $pretend)\n    {\n        // First we will resolve a \"real\" instance of the migration class from this\n        // migration file name. Once we have the instances we can run the actual\n        // command such as \"up\" or \"down\", or we can just simulate the action.\n        $migration = $this->resolvePath($file);\n\n        $name = $this->getMigrationName($file);\n\n        if ($pretend) {\n            return $this->pretendToRun($migration, 'up');\n        }\n\n        $shouldRunMigration = $migration instanceof Migration\n            ? $migration->shouldRun()\n            : true;\n\n        if (! $shouldRunMigration) {\n            $this->fireMigrationEvent(new MigrationSkipped($name));\n\n            $this->write(Task::class, $name, fn () => MigrationResult::Skipped->value);\n        } else {\n            $this->write(Task::class, $name, fn () => $this->runMigration($migration, 'up'));\n\n            // Once we have run a migrations class, we will log that it was run in this\n            // repository so that we don't try to run it next time we do a migration\n            // in the application. A migration repository keeps the migrate order.\n            $this->repository->log($name, $batch);\n        }\n    }\n\n    /**\n     * Rollback the last migration operation.\n     *\n     * @param  string[]|string  $paths\n     * @param  array<string, mixed>  $options\n     * @return string[]\n     */\n    public function rollback($paths = [], array $options = [])\n    {\n        // We want to pull in the last batch of migrations that ran on the previous\n        // migration operation. We'll then reverse those migrations and run each\n        // of them \"down\" to reverse the last migration \"operation\" which ran.\n        $migrations = $this->getMigrationsForRollback($options);\n\n        if (count($migrations) === 0) {\n            $this->fireMigrationEvent(new NoPendingMigrations('down'));\n\n            $this->write(Info::class, 'Nothing to rollback.');\n\n            return [];\n        }\n\n        return tap($this->rollbackMigrations($migrations, $paths, $options), function () {\n            $this->output?->writeln('');\n        });\n    }\n\n    /**\n     * Get the migrations for a rollback operation.\n     *\n     * @param  array<string, mixed>  $options\n     * @return array{id: int, migration: string, batch: int}[]\n     */\n    protected function getMigrationsForRollback(array $options)\n    {\n        if (($steps = $options['step'] ?? 0) > 0) {\n            return $this->repository->getMigrations($steps);\n        }\n\n        if (($batch = $options['batch'] ?? 0) > 0) {\n            return $this->repository->getMigrationsByBatch($batch);\n        }\n\n        return $this->repository->getLast();\n    }\n\n    /**\n     * Rollback the given migrations.\n     *\n     * @param  array  $migrations\n     * @param  string[]|string  $paths\n     * @param  array<string, mixed>  $options\n     * @return string[]\n     */\n    protected function rollbackMigrations(array $migrations, $paths, array $options)\n    {\n        $rolledBack = [];\n\n        $this->requireFiles($files = $this->getMigrationFiles($paths));\n\n        $this->fireMigrationEvent(new MigrationsStarted('down', $options));\n\n        $this->write(Info::class, 'Rolling back migrations.');\n\n        // Next we will run through all of the migrations and call the \"down\" method\n        // which will reverse each migration in order. This getLast method on the\n        // repository already returns these migration's names in reverse order.\n        foreach ($migrations as $migration) {\n            $migration = (object) $migration;\n\n            if (! $file = Arr::get($files, $migration->migration)) {\n                $this->write(TwoColumnDetail::class, $migration->migration, '<fg=yellow;options=bold>Migration not found</>');\n\n                continue;\n            }\n\n            $rolledBack[] = $file;\n\n            $this->runDown(\n                $file, $migration,\n                $options['pretend'] ?? false\n            );\n        }\n\n        $this->fireMigrationEvent(new MigrationsEnded('down', $options));\n\n        return $rolledBack;\n    }\n\n    /**\n     * Rolls all of the currently applied migrations back.\n     *\n     * @param  string[]|string  $paths\n     * @param  bool  $pretend\n     * @return array\n     */\n    public function reset($paths = [], $pretend = false)\n    {\n        // Next, we will reverse the migration list so we can run them back in the\n        // correct order for resetting this database. This will allow us to get\n        // the database back into its \"empty\" state ready for the migrations.\n        $migrations = array_reverse($this->repository->getRan());\n\n        if (count($migrations) === 0) {\n            $this->write(Info::class, 'Nothing to rollback.');\n\n            return [];\n        }\n\n        return tap($this->resetMigrations($migrations, Arr::wrap($paths), $pretend), function () {\n            $this->output?->writeln('');\n        });\n    }\n\n    /**\n     * Reset the given migrations.\n     *\n     * @param  string[]  $migrations\n     * @param  string[]  $paths\n     * @param  bool  $pretend\n     * @return array\n     */\n    protected function resetMigrations(array $migrations, array $paths, $pretend = false)\n    {\n        // Since the getRan method that retrieves the migration name just gives us the\n        // migration name, we will format the names into objects with the name as a\n        // property on the objects so that we can pass it to the rollback method.\n        $migrations = (new Collection($migrations))->map(fn ($m) => (object) ['migration' => $m])->all();\n\n        return $this->rollbackMigrations(\n            $migrations, $paths, compact('pretend')\n        );\n    }\n\n    /**\n     * Run \"down\" a migration instance.\n     *\n     * @param  string  $file\n     * @param  object  $migration\n     * @param  bool  $pretend\n     * @return void\n     */\n    protected function runDown($file, $migration, $pretend)\n    {\n        // First we will get the file name of the migration so we can resolve out an\n        // instance of the migration. Once we get an instance we can either run a\n        // pretend execution of the migration or we can run the real migration.\n        $instance = $this->resolvePath($file);\n\n        $name = $this->getMigrationName($file);\n\n        if ($pretend) {\n            return $this->pretendToRun($instance, 'down');\n        }\n\n        $this->write(Task::class, $name, fn () => $this->runMigration($instance, 'down'));\n\n        // Once we have successfully run the migration \"down\" we will remove it from\n        // the migration repository so it will be considered to have not been run\n        // by the application then will be able to fire by any later operation.\n        $this->repository->delete($migration);\n    }\n\n    /**\n     * Run a migration inside a transaction if the database supports it.\n     *\n     * @param  object  $migration\n     * @param  string  $method\n     * @return void\n     */\n    protected function runMigration($migration, $method)\n    {\n        $connection = $this->resolveConnection(\n            $migration->getConnection()\n        );\n\n        $callback = function () use ($connection, $migration, $method) {\n            if (method_exists($migration, $method)) {\n                $this->fireMigrationEvent(new MigrationStarted($migration, $method));\n\n                $this->runMethod($connection, $migration, $method);\n\n                $this->fireMigrationEvent(new MigrationEnded($migration, $method));\n            }\n        };\n\n        $this->getSchemaGrammar($connection)->supportsSchemaTransactions()\n            && $migration->withinTransaction\n                ? $connection->transaction($callback)\n                : $callback();\n    }\n\n    /**\n     * Pretend to run the migrations.\n     *\n     * @param  object  $migration\n     * @param  string  $method\n     * @return void\n     */\n    protected function pretendToRun($migration, $method)\n    {\n        $name = get_class($migration);\n\n        $reflectionClass = new ReflectionClass($migration);\n\n        if ($reflectionClass->isAnonymous()) {\n            $name = $this->getMigrationName($reflectionClass->getFileName());\n        }\n\n        $this->write(TwoColumnDetail::class, $name);\n\n        $this->write(\n            BulletList::class,\n            (new Collection($this->getQueries($migration, $method)))->map(fn ($query) => $query['query'])\n        );\n    }\n\n    /**\n     * Get all of the queries that would be run for a migration.\n     *\n     * @param  object  $migration\n     * @param  string  $method\n     * @return array\n     */\n    protected function getQueries($migration, $method)\n    {\n        // Now that we have the connections we can resolve it and pretend to run the\n        // queries against the database returning the array of raw SQL statements\n        // that would get fired against the database system for this migration.\n        $db = $this->resolveConnection(\n            $migration->getConnection()\n        );\n\n        return $db->pretend(function () use ($db, $migration, $method) {\n            if (method_exists($migration, $method)) {\n                $this->runMethod($db, $migration, $method);\n            }\n        });\n    }\n\n    /**\n     * Run a migration method on the given connection.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  object  $migration\n     * @param  string  $method\n     * @return void\n     */\n    protected function runMethod($connection, $migration, $method)\n    {\n        $previousConnection = $this->resolver->getDefaultConnection();\n\n        try {\n            $this->resolver->setDefaultConnection($connection->getName());\n\n            $migration->{$method}();\n        } finally {\n            $this->resolver->setDefaultConnection($previousConnection);\n        }\n    }\n\n    /**\n     * Resolve a migration instance from a file.\n     *\n     * @param  string  $file\n     * @return object\n     */\n    public function resolve($file)\n    {\n        $class = $this->getMigrationClass($file);\n\n        return new $class;\n    }\n\n    /**\n     * Resolve a migration instance from a migration path.\n     *\n     * @param  string  $path\n     * @return object\n     */\n    protected function resolvePath(string $path)\n    {\n        $class = $this->getMigrationClass($this->getMigrationName($path));\n\n        if (class_exists($class) && realpath($path) == (new ReflectionClass($class))->getFileName()) {\n            return new $class;\n        }\n\n        $migration = static::$requiredPathCache[$path] ??= $this->files->getRequire($path);\n\n        if (is_object($migration)) {\n            return method_exists($migration, '__construct')\n                ? $this->files->getRequire($path)\n                : clone $migration;\n        }\n\n        return new $class;\n    }\n\n    /**\n     * Generate a migration class name based on the migration file name.\n     *\n     * @param  string  $migrationName\n     * @return string\n     */\n    protected function getMigrationClass(string $migrationName): string\n    {\n        return Str::studly(implode('_', array_slice(explode('_', $migrationName), 4)));\n    }\n\n    /**\n     * Get all of the migration files in a given path.\n     *\n     * @param  string|array  $paths\n     * @return array<string, string>\n     */\n    public function getMigrationFiles($paths)\n    {\n        return (new Collection($paths))\n            ->flatMap(fn ($path) => str_ends_with($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php'))\n            ->filter()\n            ->values()\n            ->keyBy(fn ($file) => $this->getMigrationName($file))\n            ->sortBy(fn ($file, $key) => $key)\n            ->all();\n    }\n\n    /**\n     * Require in all the migration files in a given path.\n     *\n     * @param  string[]  $files\n     * @return void\n     */\n    public function requireFiles(array $files)\n    {\n        foreach ($files as $file) {\n            $this->files->requireOnce($file);\n        }\n    }\n\n    /**\n     * Get the name of the migration.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function getMigrationName($path)\n    {\n        return str_replace('.php', '', basename($path));\n    }\n\n    /**\n     * Register a custom migration path.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function path($path)\n    {\n        $this->paths = array_unique(array_merge($this->paths, [$path]));\n    }\n\n    /**\n     * Get all of the custom migration paths.\n     *\n     * @return string[]\n     */\n    public function paths()\n    {\n        return $this->paths;\n    }\n\n    /**\n     * Set the pending migrations to skip.\n     *\n     * @param  list<string>  $migrations\n     * @return void\n     */\n    public static function withoutMigrations(array $migrations)\n    {\n        static::$withoutMigrations = $migrations;\n    }\n\n    /**\n     * Get the default connection name.\n     *\n     * @return string\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Execute the given callback using the given connection as the default connection.\n     *\n     * @template TReturn\n     *\n     * @param  string  $name\n     * @param  (callable(): TReturn)  $callback\n     * @return mixed\n     */\n    public function usingConnection($name, callable $callback)\n    {\n        $previousConnection = $this->resolver->getDefaultConnection();\n\n        $this->setConnection($name);\n\n        try {\n            return $callback();\n        } finally {\n            $this->setConnection($previousConnection);\n        }\n    }\n\n    /**\n     * Set the default connection name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setConnection($name)\n    {\n        if (! is_null($name)) {\n            $this->resolver->setDefaultConnection($name);\n        }\n\n        $this->repository->setSource($name);\n\n        $this->connection = $name;\n    }\n\n    /**\n     * Resolve the database connection instance.\n     *\n     * @param  string  $connection\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function resolveConnection($connection)\n    {\n        if (static::$connectionResolverCallback) {\n            return call_user_func(\n                static::$connectionResolverCallback,\n                $this->resolver,\n                $connection ?: $this->connection\n            );\n        } else {\n            return $this->resolver->connection($connection ?: $this->connection);\n        }\n    }\n\n    /**\n     * Set a connection resolver callback.\n     *\n     * @param  \\Closure(\\Illuminate\\Database\\ConnectionResolverInterface, ?string): \\Illuminate\\Database\\Connection  $callback\n     * @return void\n     */\n    public static function resolveConnectionsUsing(Closure $callback)\n    {\n        static::$connectionResolverCallback = $callback;\n    }\n\n    /**\n     * Get the schema grammar out of a migration connection.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\Grammar\n     */\n    protected function getSchemaGrammar($connection)\n    {\n        if (is_null($grammar = $connection->getSchemaGrammar())) {\n            $connection->useDefaultSchemaGrammar();\n\n            $grammar = $connection->getSchemaGrammar();\n        }\n\n        return $grammar;\n    }\n\n    /**\n     * Get the migration repository instance.\n     *\n     * @return \\Illuminate\\Database\\Migrations\\MigrationRepositoryInterface\n     */\n    public function getRepository()\n    {\n        return $this->repository;\n    }\n\n    /**\n     * Determine if the migration repository exists.\n     *\n     * @return bool\n     */\n    public function repositoryExists()\n    {\n        return $this->repository->repositoryExists();\n    }\n\n    /**\n     * Determine if any migrations have been run.\n     *\n     * @return bool\n     */\n    public function hasRunAnyMigrations()\n    {\n        return $this->repositoryExists() && count($this->repository->getRan()) > 0;\n    }\n\n    /**\n     * Delete the migration repository data store.\n     *\n     * @return void\n     */\n    public function deleteRepository()\n    {\n        $this->repository->deleteRepository();\n    }\n\n    /**\n     * Get the file system instance.\n     *\n     * @return \\Illuminate\\Filesystem\\Filesystem\n     */\n    public function getFilesystem()\n    {\n        return $this->files;\n    }\n\n    /**\n     * Set the output implementation that should be used by the console.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return $this\n     */\n    public function setOutput(OutputInterface $output)\n    {\n        $this->output = $output;\n\n        return $this;\n    }\n\n    /**\n     * Write to the console's output.\n     *\n     * @param  string  $component\n     * @param  array<int, string>|string  ...$arguments\n     * @return void\n     */\n    protected function write($component, ...$arguments)\n    {\n        if ($this->output && class_exists($component)) {\n            (new $component($this->output))->render(...$arguments);\n        } else {\n            foreach ($arguments as $argument) {\n                if (is_callable($argument)) {\n                    $argument();\n                }\n            }\n        }\n    }\n\n    /**\n     * Fire the given event for the migration.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Events\\MigrationEvent  $event\n     * @return void\n     */\n    public function fireMigrationEvent($event)\n    {\n        $this->events?->dispatch($event);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/stubs/migration.create.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('{{ table }}', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('{{ table }}');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/stubs/migration.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        //\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        //\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Database/Migrations/stubs/migration.update.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::table('{{ table }}', function (Blueprint $table) {\n            //\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::table('{{ table }}', function (Blueprint $table) {\n            //\n        });\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Database/MultipleColumnsSelectedException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass MultipleColumnsSelectedException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/MultipleRecordsFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass MultipleRecordsFoundException extends RuntimeException\n{\n    /**\n     * The number of records found.\n     *\n     * @var int\n     */\n    public $count;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  int  $count\n     * @param  int  $code\n     * @param  \\Throwable|null  $previous\n     */\n    public function __construct($count, $code = 0, $previous = null)\n    {\n        $this->count = $count;\n\n        parent::__construct(\"$count records were found.\", $code, $previous);\n    }\n\n    /**\n     * Get the number of records found.\n     *\n     * @return int\n     */\n    public function getCount()\n    {\n        return $this->count;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/MySqlConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\MySqlProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar as SchemaGrammar;\nuse Illuminate\\Database\\Schema\\MySqlBuilder;\nuse Illuminate\\Database\\Schema\\MySqlSchemaState;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\nuse PDO;\n\nclass MySqlConnection extends Connection\n{\n    /**\n     * The last inserted ID generated by the server.\n     *\n     * @var string|int|null\n     */\n    protected $lastInsertId;\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getDriverTitle()\n    {\n        return $this->isMaria() ? 'MariaDB' : 'MySQL';\n    }\n\n    /**\n     * Run an insert statement against the database.\n     *\n     * @param  string  $query\n     * @param  array  $bindings\n     * @param  string|null  $sequence\n     * @return bool\n     */\n    public function insert($query, $bindings = [], $sequence = null)\n    {\n        return $this->run($query, $bindings, function ($query, $bindings) use ($sequence) {\n            if ($this->pretending()) {\n                return true;\n            }\n\n            $statement = $this->getPdo()->prepare($query);\n\n            $this->bindValues($statement, $this->prepareBindings($bindings));\n\n            $this->recordsHaveBeenModified();\n\n            $result = $statement->execute();\n\n            $this->lastInsertId = $this->getPdo()->lastInsertId($sequence);\n\n            return $result;\n        });\n    }\n\n    /**\n     * Escape a binary value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeBinary($value)\n    {\n        $hex = bin2hex($value);\n\n        return \"x'{$hex}'\";\n    }\n\n    /**\n     * Determine if the given database exception was caused by a unique constraint violation.\n     *\n     * @param  \\Exception  $exception\n     * @return bool\n     */\n    protected function isUniqueConstraintError(Exception $exception)\n    {\n        return (bool) preg_match('#Integrity constraint violation: 1062#i', $exception->getMessage());\n    }\n\n    /**\n     * Get the connection's last insert ID.\n     *\n     * @return string|int|null\n     */\n    public function getLastInsertId()\n    {\n        return $this->lastInsertId;\n    }\n\n    /**\n     * Determine if the connected database is a MariaDB database.\n     *\n     * @return bool\n     */\n    public function isMaria()\n    {\n        return str_contains($this->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), 'MariaDB');\n    }\n\n    /**\n     * Get the server version for the connection.\n     *\n     * @return string\n     */\n    public function getServerVersion(): string\n    {\n        return str_contains($version = parent::getServerVersion(), 'MariaDB')\n            ? Str::between($version, '5.5.5-', '-MariaDB')\n            : $version;\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\MySqlGrammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\MySqlBuilder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new MySqlBuilder($this);\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        return new SchemaGrammar($this);\n    }\n\n    /**\n     * Get the schema state for the connection.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     * @return \\Illuminate\\Database\\Schema\\MySqlSchemaState\n     */\n    public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        return new MySqlSchemaState($this, $files, $processFactory);\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\MySqlProcessor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new MySqlProcessor;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/PostgresConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Query\\Grammars\\PostgresGrammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\PostgresProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar as SchemaGrammar;\nuse Illuminate\\Database\\Schema\\PostgresBuilder;\nuse Illuminate\\Database\\Schema\\PostgresSchemaState;\nuse Illuminate\\Filesystem\\Filesystem;\n\nclass PostgresConnection extends Connection\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function getDriverTitle()\n    {\n        return 'PostgreSQL';\n    }\n\n    /**\n     * Escape a binary value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeBinary($value)\n    {\n        $hex = bin2hex($value);\n\n        return \"'\\x{$hex}'::bytea\";\n    }\n\n    /**\n     * Escape a bool value for safe SQL embedding.\n     *\n     * @param  bool  $value\n     * @return string\n     */\n    protected function escapeBool($value)\n    {\n        return $value ? 'true' : 'false';\n    }\n\n    /**\n     * Determine if the given database exception was caused by a unique constraint violation.\n     *\n     * @param  \\Exception  $exception\n     * @return bool\n     */\n    protected function isUniqueConstraintError(Exception $exception)\n    {\n        return '23505' === $exception->getCode();\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\PostgresGrammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\PostgresBuilder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new PostgresBuilder($this);\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        return new SchemaGrammar($this);\n    }\n\n    /**\n     * Get the schema state for the connection.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     * @return \\Illuminate\\Database\\Schema\\PostgresSchemaState\n     */\n    public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        return new PostgresSchemaState($this, $files, $processFactory);\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\PostgresProcessor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new PostgresProcessor;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Builder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query;\n\nuse BackedEnum;\nuse Closure;\nuse DatePeriod;\nuse DateTimeInterface;\nuse Illuminate\\Contracts\\Database\\Query\\Builder as BuilderContract;\nuse Illuminate\\Contracts\\Database\\Query\\ConditionExpression;\nuse Illuminate\\Contracts\\Database\\Query\\Expression as ExpressionContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Concerns\\BuildsQueries;\nuse Illuminate\\Database\\Concerns\\BuildsWhereDateClauses;\nuse Illuminate\\Database\\Concerns\\ExplainsQueries;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\Eloquent\\Builder as EloquentBuilder;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Pagination\\Paginator;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse LogicException;\nuse RuntimeException;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Builder implements BuilderContract\n{\n    /** @use \\Illuminate\\Database\\Concerns\\BuildsQueries<\\stdClass> */\n    use BuildsWhereDateClauses, BuildsQueries, ExplainsQueries, ForwardsCalls, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    public $connection;\n\n    /**\n     * The database query grammar instance.\n     *\n     * @var \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    public $grammar;\n\n    /**\n     * The database query post processor instance.\n     *\n     * @var \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    public $processor;\n\n    /**\n     * The current query value bindings.\n     *\n     * @var array{\n     *     select: list<mixed>,\n     *     from: list<mixed>,\n     *     join: list<mixed>,\n     *     where: list<mixed>,\n     *     groupBy: list<mixed>,\n     *     having: list<mixed>,\n     *     order: list<mixed>,\n     *     union: list<mixed>,\n     *     unionOrder: list<mixed>,\n     * }\n     */\n    public $bindings = [\n        'select' => [],\n        'from' => [],\n        'join' => [],\n        'where' => [],\n        'groupBy' => [],\n        'having' => [],\n        'order' => [],\n        'union' => [],\n        'unionOrder' => [],\n    ];\n\n    /**\n     * An aggregate function and column to be run.\n     *\n     * @var array{\n     *     function: string,\n     *     columns: array<\\Illuminate\\Contracts\\Database\\Query\\Expression|string>\n     * }|null\n     */\n    public $aggregate;\n\n    /**\n     * The columns that should be returned.\n     *\n     * @var array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>|null\n     */\n    public $columns;\n\n    /**\n     * Indicates if the query returns distinct results.\n     *\n     * Occasionally contains the columns that should be distinct.\n     *\n     * @var bool|array\n     */\n    public $distinct = false;\n\n    /**\n     * The table which the query is targeting.\n     *\n     * @var \\Illuminate\\Database\\Query\\Expression|string\n     */\n    public $from;\n\n    /**\n     * The index hint for the query.\n     *\n     * @var \\Illuminate\\Database\\Query\\IndexHint|null\n     */\n    public $indexHint;\n\n    /**\n     * The table joins for the query.\n     *\n     * @var array|null\n     */\n    public $joins;\n\n    /**\n     * The where constraints for the query.\n     *\n     * @var array\n     */\n    public $wheres = [];\n\n    /**\n     * The groupings for the query.\n     *\n     * @var array|null\n     */\n    public $groups;\n\n    /**\n     * The having constraints for the query.\n     *\n     * @var array|null\n     */\n    public $havings;\n\n    /**\n     * The orderings for the query.\n     *\n     * @var array|null\n     */\n    public $orders;\n\n    /**\n     * The maximum number of records to return.\n     *\n     * @var int|null\n     */\n    public $limit;\n\n    /**\n     * The maximum number of records to return per group.\n     *\n     * @var array|null\n     */\n    public $groupLimit;\n\n    /**\n     * The number of records to skip.\n     *\n     * @var int|null\n     */\n    public $offset;\n\n    /**\n     * The query union statements.\n     *\n     * @var array|null\n     */\n    public $unions;\n\n    /**\n     * The maximum number of union records to return.\n     *\n     * @var int|null\n     */\n    public $unionLimit;\n\n    /**\n     * The number of union records to skip.\n     *\n     * @var int|null\n     */\n    public $unionOffset;\n\n    /**\n     * The orderings for the union query.\n     *\n     * @var array|null\n     */\n    public $unionOrders;\n\n    /**\n     * Indicates whether row locking is being used.\n     *\n     * @var string|bool|null\n     */\n    public $lock;\n\n    /**\n     * The query execution timeout in seconds.\n     *\n     * @var int|null\n     */\n    public $timeout;\n\n    /**\n     * The callbacks that should be invoked before the query is executed.\n     *\n     * @var array\n     */\n    public $beforeQueryCallbacks = [];\n\n    /**\n     * The callbacks that should be invoked after retrieving data from the database.\n     *\n     * @var array\n     */\n    protected $afterQueryCallbacks = [];\n\n    /**\n     * All of the available clause operators.\n     *\n     * @var string[]\n     */\n    public $operators = [\n        '=', '<', '>', '<=', '>=', '<>', '!=', '<=>',\n        'like', 'like binary', 'not like', 'ilike',\n        '&', '|', '^', '<<', '>>', '&~', 'is', 'is not',\n        'rlike', 'not rlike', 'regexp', 'not regexp',\n        '~', '~*', '!~', '!~*', 'similar to',\n        'not similar to', 'not ilike', '~~*', '!~~*',\n    ];\n\n    /**\n     * All of the available bitwise operators.\n     *\n     * @var string[]\n     */\n    public $bitwiseOperators = [\n        '&', '|', '^', '<<', '>>', '&~',\n    ];\n\n    /**\n     * Whether to use write pdo for the select.\n     *\n     * @var bool\n     */\n    public $useWritePdo = false;\n\n    /**\n     * The custom arguments for the PDOStatement::fetchAll / fetch functions.\n     *\n     * @var array\n     */\n    public array $fetchUsing = [];\n\n    /**\n     * Create a new query builder instance.\n     */\n    public function __construct(\n        ConnectionInterface $connection,\n        ?Grammar $grammar = null,\n        ?Processor $processor = null,\n    ) {\n        $this->connection = $connection;\n        $this->grammar = $grammar ?: $connection->getQueryGrammar();\n        $this->processor = $processor ?: $connection->getPostProcessor();\n    }\n\n    /**\n     * Set the columns to be selected.\n     *\n     * @param  mixed  $columns\n     * @return $this\n     */\n    public function select($columns = ['*'])\n    {\n        $this->columns = [];\n        $this->bindings['select'] = [];\n\n        $columns = is_array($columns) ? $columns : func_get_args();\n\n        foreach ($columns as $as => $column) {\n            if (is_string($as) && $this->isQueryable($column)) {\n                $this->selectSub($column, $as);\n            } else {\n                $this->columns[] = $column;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a subselect expression to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function selectSub($query, $as)\n    {\n        [$query, $bindings] = $this->createSub($query);\n\n        return $this->selectRaw(\n            '('.$query.') as '.$this->grammar->wrap($as), $bindings\n        );\n    }\n\n    /**\n     * Add a select expression to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|literal-string  $expression\n     * @param  string  $as\n     * @return $this\n     */\n    public function selectExpression($expression, $as)\n    {\n        return $this->selectRaw(\n            '('.$this->grammar->getValue($expression).') as '.$this->grammar->wrap($as)\n        );\n    }\n\n    /**\n     * Add a new \"raw\" select expression to the query.\n     *\n     * @param  literal-string  $expression\n     * @return $this\n     */\n    public function selectRaw($expression, array $bindings = [])\n    {\n        $this->addSelect(new Expression($expression));\n\n        if ($bindings) {\n            $this->addBinding($bindings, 'select');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Makes \"from\" fetch from a subquery.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function fromSub($query, $as)\n    {\n        [$query, $bindings] = $this->createSub($query);\n\n        return $this->fromRaw('('.$query.') as '.$this->grammar->wrapTable($as), $bindings);\n    }\n\n    /**\n     * Add a raw \"from\" clause to the query.\n     *\n     * @param  literal-string  $expression\n     * @param  mixed  $bindings\n     * @return $this\n     */\n    public function fromRaw($expression, $bindings = [])\n    {\n        $this->from = new Expression($expression);\n\n        $this->addBinding($bindings, 'from');\n\n        return $this;\n    }\n\n    /**\n     * Creates a subquery and parse it.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @return array\n     */\n    protected function createSub($query)\n    {\n        // If the given query is a Closure, we will execute it while passing in a new\n        // query instance to the Closure. This will give the developer a chance to\n        // format and work with the query before we cast it to a raw SQL string.\n        if ($query instanceof Closure) {\n            $callback = $query;\n\n            $callback($query = $this->forSubQuery());\n        }\n\n        return $this->parseSub($query);\n    }\n\n    /**\n     * Parse the subquery into SQL and bindings.\n     *\n     * @param  mixed  $query\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseSub($query)\n    {\n        if ($query instanceof self || $query instanceof EloquentBuilder || $query instanceof Relation) {\n            $query = $this->prependDatabaseNameIfCrossDatabaseQuery($query);\n\n            return [$query->toSql(), $query->getBindings()];\n        } elseif (is_string($query)) {\n            return [$query, []];\n        } else {\n            throw new InvalidArgumentException(\n                'A subquery must be a query builder instance, a Closure, or a string.'\n            );\n        }\n    }\n\n    /**\n     * Prepend the database name if the given query is on another database.\n     *\n     * @param  mixed  $query\n     * @return mixed\n     */\n    protected function prependDatabaseNameIfCrossDatabaseQuery($query)\n    {\n        if ($query->getConnection()->getDatabaseName() !==\n            $this->getConnection()->getDatabaseName()) {\n            $databaseName = $query->getConnection()->getDatabaseName();\n\n            if (! str_starts_with($query->from, $databaseName) && ! str_contains($query->from, '.')) {\n                $query->from($databaseName.'.'.$query->from);\n            }\n        }\n\n        return $query;\n    }\n\n    /**\n     * Add a new select column to the query.\n     *\n     * @param  mixed  $column\n     * @return $this\n     */\n    public function addSelect($column)\n    {\n        $columns = is_array($column) ? $column : func_get_args();\n\n        foreach ($columns as $as => $column) {\n            if (is_string($as) && $this->isQueryable($column)) {\n                if (is_null($this->columns)) {\n                    $this->select($this->from.'.*');\n                }\n\n                $this->selectSub($column, $as);\n            } else {\n                if (is_array($this->columns) && in_array($column, $this->columns, true)) {\n                    continue;\n                }\n\n                $this->columns[] = $column;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a vector-similarity selection to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Support\\Collection<int, float>|\\Illuminate\\Contracts\\Support\\Arrayable|array<int, float>|string  $vector\n     * @param  string|null  $as\n     * @return $this\n     */\n    public function selectVectorDistance($column, $vector, $as = null)\n    {\n        $this->ensureConnectionSupportsVectors();\n\n        if (is_string($vector)) {\n            $vector = Str::of($vector)->toEmbeddings(cache: true);\n        }\n\n        $this->addBinding(\n            json_encode(\n                $vector instanceof Arrayable\n                    ? $vector->toArray()\n                    : $vector,\n                flags: JSON_THROW_ON_ERROR\n            ),\n            'select',\n        );\n\n        $as = $this->getGrammar()->wrap($as ?? $column.'_distance');\n\n        return $this->addSelect(\n            new Expression(\"({$this->getGrammar()->wrap($column)} <=> ?) as {$as}\")\n        );\n    }\n\n    /**\n     * Force the query to only return distinct results.\n     *\n     * @return $this\n     */\n    public function distinct()\n    {\n        $columns = func_get_args();\n\n        if (count($columns) > 0) {\n            $this->distinct = is_array($columns[0]) || is_bool($columns[0]) ? $columns[0] : $columns;\n        } else {\n            $this->distinct = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the table which the query is targeting.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  string|null  $as\n     * @return $this\n     */\n    public function from($table, $as = null)\n    {\n        if ($this->isQueryable($table)) {\n            return $this->fromSub($table, $as);\n        }\n\n        $this->from = $as ? \"{$table} as {$as}\" : $table;\n\n        return $this;\n    }\n\n    /**\n     * Add an index hint to suggest a query index.\n     *\n     * @param  string  $index\n     * @return $this\n     */\n    public function useIndex($index)\n    {\n        $this->indexHint = new IndexHint('hint', $index);\n\n        return $this;\n    }\n\n    /**\n     * Add an index hint to force a query index.\n     *\n     * @param  string  $index\n     * @return $this\n     */\n    public function forceIndex($index)\n    {\n        $this->indexHint = new IndexHint('force', $index);\n\n        return $this;\n    }\n\n    /**\n     * Add an index hint to ignore a query index.\n     *\n     * @param  string  $index\n     * @return $this\n     */\n    public function ignoreIndex($index)\n    {\n        $this->indexHint = new IndexHint('ignore', $index);\n\n        return $this;\n    }\n\n    /**\n     * Add a \"join\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @param  string  $type\n     * @param  bool  $where\n     * @return $this\n     */\n    public function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)\n    {\n        $join = $this->newJoinClause($this, $type, $table);\n\n        // If the first \"column\" of the join is really a Closure instance the developer\n        // is trying to build a join with a complex \"on\" clause containing more than\n        // one condition, so we'll add the join and call a Closure with the query.\n        if ($first instanceof Closure) {\n            $first($join);\n\n            $this->joins[] = $join;\n\n            $this->addBinding($join->getBindings(), 'join');\n        }\n\n        // If the column is simply a string, we can assume the join simply has a basic\n        // \"on\" clause with a single condition. So we will just build the join with\n        // this simple join clauses attached to it. There is not a join callback.\n        else {\n            $method = $where ? 'where' : 'on';\n\n            $this->joins[] = $join->$method($first, $operator, $second);\n\n            $this->addBinding($join->getBindings(), 'join');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a \"join where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $second\n     * @param  string  $type\n     * @return $this\n     */\n    public function joinWhere($table, $first, $operator, $second, $type = 'inner')\n    {\n        return $this->join($table, $first, $operator, $second, $type, true);\n    }\n\n    /**\n     * Add a \"subquery join\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @param  string  $type\n     * @param  bool  $where\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)\n    {\n        [$query, $bindings] = $this->createSub($query);\n\n        $expression = '('.$query.') as '.$this->grammar->wrapTable($as);\n\n        $this->addBinding($bindings, 'join');\n\n        return $this->join(new Expression($expression), $first, $operator, $second, $type, $where);\n    }\n\n    /**\n     * Add a \"lateral join\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @return $this\n     */\n    public function joinLateral($query, string $as, string $type = 'inner')\n    {\n        [$query, $bindings] = $this->createSub($query);\n\n        $expression = '('.$query.') as '.$this->grammar->wrapTable($as);\n\n        $this->addBinding($bindings, 'join');\n\n        $this->joins[] = $this->newJoinLateralClause($this, $type, new Expression($expression));\n\n        return $this;\n    }\n\n    /**\n     * Add a lateral left join to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @return $this\n     */\n    public function leftJoinLateral($query, string $as)\n    {\n        return $this->joinLateral($query, $as, 'left');\n    }\n\n    /**\n     * Add a left join to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function leftJoin($table, $first, $operator = null, $second = null)\n    {\n        return $this->join($table, $first, $operator, $second, 'left');\n    }\n\n    /**\n     * Add a \"join where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function leftJoinWhere($table, $first, $operator, $second)\n    {\n        return $this->joinWhere($table, $first, $operator, $second, 'left');\n    }\n\n    /**\n     * Add a subquery left join to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function leftJoinSub($query, $as, $first, $operator = null, $second = null)\n    {\n        return $this->joinSub($query, $as, $first, $operator, $second, 'left');\n    }\n\n    /**\n     * Add a right join to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function rightJoin($table, $first, $operator = null, $second = null)\n    {\n        return $this->join($table, $first, $operator, $second, 'right');\n    }\n\n    /**\n     * Add a \"right join where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $second\n     * @return $this\n     */\n    public function rightJoinWhere($table, $first, $operator, $second)\n    {\n        return $this->joinWhere($table, $first, $operator, $second, 'right');\n    }\n\n    /**\n     * Add a subquery right join to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function rightJoinSub($query, $as, $first, $operator = null, $second = null)\n    {\n        return $this->joinSub($query, $as, $first, $operator, $second, 'right');\n    }\n\n    /**\n     * Add a \"cross join\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function crossJoin($table, $first = null, $operator = null, $second = null)\n    {\n        if ($first) {\n            return $this->join($table, $first, $operator, $second, 'cross');\n        }\n\n        $this->joins[] = $this->newJoinClause($this, 'cross', $table);\n\n        return $this;\n    }\n\n    /**\n     * Add a subquery cross join to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @return $this\n     */\n    public function crossJoinSub($query, $as)\n    {\n        [$query, $bindings] = $this->createSub($query);\n\n        $expression = '('.$query.') as '.$this->grammar->wrapTable($as);\n\n        $this->addBinding($bindings, 'join');\n\n        $this->joins[] = $this->newJoinClause($this, 'cross', new Expression($expression));\n\n        return $this;\n    }\n\n    /**\n     * Add a straight join to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function straightJoin($table, $first, $operator = null, $second = null)\n    {\n        return $this->join($table, $first, $operator, $second, 'straight_join');\n    }\n\n    /**\n     * Add a \"straight join where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $second\n     * @return $this\n     */\n    public function straightJoinWhere($table, $first, $operator, $second)\n    {\n        return $this->joinWhere($table, $first, $operator, $second, 'straight_join');\n    }\n\n    /**\n     * Add a subquery straight join to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @param  string  $as\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return $this\n     */\n    public function straightJoinSub($query, $as, $first, $operator = null, $second = null)\n    {\n        return $this->joinSub($query, $as, $first, $operator, $second, 'straight_join');\n    }\n\n    /**\n     * Get a new \"join\" clause.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @return \\Illuminate\\Database\\Query\\JoinClause\n     */\n    protected function newJoinClause(self $parentQuery, $type, $table)\n    {\n        return new JoinClause($parentQuery, $type, $table);\n    }\n\n    /**\n     * Get a new \"join lateral\" clause.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @return \\Illuminate\\Database\\Query\\JoinLateralClause\n     */\n    protected function newJoinLateralClause(self $parentQuery, $type, $table)\n    {\n        return new JoinLateralClause($parentQuery, $type, $table);\n    }\n\n    /**\n     * Merge an array of \"where\" clauses and bindings.\n     *\n     * @param  array  $wheres\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function mergeWheres($wheres, $bindings)\n    {\n        $this->wheres = array_merge($this->wheres, (array) $wheres);\n\n        $this->bindings['where'] = array_values(\n            array_merge($this->bindings['where'], (array) $bindings)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add a basic \"where\" clause to the query.\n     *\n     * @param  \\Closure|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function where($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        if ($column instanceof ConditionExpression) {\n            $type = 'Expression';\n\n            $this->wheres[] = compact('type', 'column', 'boolean');\n\n            return $this;\n        }\n\n        // If the column is an array, we will assume it is an array of key-value pairs\n        // and can add them each as a where clause. We will maintain the boolean we\n        // received when the method was called and pass it into the nested where.\n        if (is_array($column)) {\n            return $this->addArrayOfWheres($column, $boolean);\n        }\n\n        // Here we will make some assumptions about the operator. If only 2 values are\n        // passed to the method, we will assume that the operator is an equals sign\n        // and keep going. Otherwise, we'll require the operator to be passed in.\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the column is actually a Closure instance, we will assume the developer\n        // wants to begin a nested where statement which is wrapped in parentheses.\n        // We will add that Closure to the query and return back out immediately.\n        if ($column instanceof Closure && is_null($operator)) {\n            return $this->whereNested($column, $boolean);\n        }\n\n        // If the column is a Closure instance and there is an operator value, we will\n        // assume the developer wants to run a subquery and then compare the result\n        // of that subquery with the given value that was provided to the method.\n        if ($this->isQueryable($column) && ! is_null($operator)) {\n            [$sub, $bindings] = $this->createSub($column);\n\n            return $this->addBinding($bindings, 'where')\n                ->where(new Expression('('.$sub.')'), $operator, $value, $boolean);\n        }\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        // If the value is a Closure, it means the developer is performing an entire\n        // sub-select within the query and we will need to compile the sub-select\n        // within the where clause to get the appropriate query record results.\n        if ($this->isQueryable($value)) {\n            return $this->whereSub($column, $operator, $value, $boolean);\n        }\n\n        // If the value is \"null\", we will just assume the developer wants to add a\n        // where null clause to the query. So, we will allow a short-cut here to\n        // that method for convenience so the developer doesn't have to check.\n        if (is_null($value)) {\n            return $this->whereNull($column, $boolean, ! in_array($operator, ['=', '<=>'], true));\n        }\n\n        $type = 'Basic';\n\n        $columnString = ($column instanceof ExpressionContract)\n            ? $this->grammar->getValue($column)\n            : $column;\n\n        // If the column is making a JSON reference we'll check to see if the value\n        // is a boolean. If it is, we'll add the raw boolean string as an actual\n        // value to the query to ensure this is properly handled by the query.\n        if (str_contains($columnString, '->') && is_bool($value)) {\n            $value = new Expression($value ? 'true' : 'false');\n\n            if (is_string($column)) {\n                $type = 'JsonBoolean';\n            }\n        }\n\n        if ($this->isBitwiseOperator($operator)) {\n            $type = 'Bitwise';\n        }\n\n        if ($operator === '<=>') {\n            $type = 'NullSafeEquals';\n        }\n\n        // Now that we are working with just a simple query we can put the elements\n        // in our array and add the query binding to our array of bindings that\n        // will be bound to each SQL statements when it is finally executed.\n        $this->wheres[] = compact(\n            'type', 'column', 'operator', 'value', 'boolean'\n        );\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($this->flattenValue($value), 'where');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an array of \"where\" clauses to the query.\n     *\n     * @param  array  $column\n     * @param  string  $boolean\n     * @param  string  $method\n     * @return $this\n     */\n    protected function addArrayOfWheres($column, $boolean, $method = 'where')\n    {\n        return $this->whereNested(function ($query) use ($column, $method, $boolean) {\n            foreach ($column as $key => $value) {\n                if (is_numeric($key) && is_array($value)) {\n                    $query->{$method}(...array_values($value), boolean: $boolean);\n                } else {\n                    $query->{$method}($key, '=', $value, $boolean);\n                }\n            }\n        }, $boolean);\n    }\n\n    /**\n     * Prepare the value and operator for a where clause.\n     *\n     * @param  string  $value\n     * @param  string  $operator\n     * @param  bool  $useDefault\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function prepareValueAndOperator($value, $operator, $useDefault = false)\n    {\n        if ($useDefault) {\n            return [$operator, '='];\n        } elseif ($this->invalidOperatorAndValue($operator, $value)) {\n            throw new InvalidArgumentException('Illegal operator and value combination.');\n        }\n\n        return [$value, $operator];\n    }\n\n    /**\n     * Determine if the given operator and value combination is legal.\n     *\n     * Prevents using Null values with invalid operators.\n     *\n     * @param  string  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function invalidOperatorAndValue($operator, $value)\n    {\n        return is_null($value) && in_array($operator, $this->operators) &&\n             ! in_array($operator, ['=', '<=>', '<>', '!=']);\n    }\n\n    /**\n     * Determine if the given operator is supported.\n     *\n     * @param  string  $operator\n     * @return bool\n     */\n    protected function invalidOperator($operator)\n    {\n        return ! is_string($operator) || (! in_array(strtolower($operator), $this->operators, true) &&\n               ! in_array(strtolower($operator), $this->grammar->getOperators(), true));\n    }\n\n    /**\n     * Determine if the operator is a bitwise operator.\n     *\n     * @param  string  $operator\n     * @return bool\n     */\n    protected function isBitwiseOperator($operator)\n    {\n        return in_array(strtolower($operator), $this->bitwiseOperators, true) ||\n               in_array(strtolower($operator), $this->grammar->getBitwiseOperators(), true);\n    }\n\n    /**\n     * Add an \"or where\" clause to the query.\n     *\n     * @param  \\Closure|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhere($column, $operator = null, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->where($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a basic \"where not\" clause to the query.\n     *\n     * @param  \\Closure|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNot($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        if (is_array($column)) {\n            return $this->whereNested(function ($query) use ($column, $operator, $value, $boolean) {\n                $query->where($column, $operator, $value, $boolean);\n            }, $boolean.' not');\n        }\n\n        return $this->where($column, $operator, $value, $boolean.' not');\n    }\n\n    /**\n     * Add an \"or where not\" clause to the query.\n     *\n     * @param  \\Closure|string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereNot($column, $operator = null, $value = null)\n    {\n        return $this->whereNot($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where\" clause comparing two columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|array  $first\n     * @param  string|null  $operator\n     * @param  string|null  $second\n     * @param  string|null  $boolean\n     * @return $this\n     */\n    public function whereColumn($first, $operator = null, $second = null, $boolean = 'and')\n    {\n        // If the column is an array, we will assume it is an array of key-value pairs\n        // and can add them each as a where clause. We will maintain the boolean we\n        // received when the method was called and pass it into the nested where.\n        if (is_array($first)) {\n            return $this->addArrayOfWheres($first, $boolean, 'whereColumn');\n        }\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$second, $operator] = [$operator, '='];\n        }\n\n        // Finally, we will add this where clause into this array of clauses that we\n        // are building for the query. All of them will be compiled via a grammar\n        // once the query is about to be executed and run against the database.\n        $type = 'Column';\n\n        $this->wheres[] = compact(\n            'type', 'first', 'operator', 'second', 'boolean'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where\" clause comparing two columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|array  $first\n     * @param  string|null  $operator\n     * @param  string|null  $second\n     * @return $this\n     */\n    public function orWhereColumn($first, $operator = null, $second = null)\n    {\n        return $this->whereColumn($first, $operator, $second, 'or');\n    }\n\n    /**\n     * Add a vector similarity clause to the query, filtering by minimum similarity and ordering by similarity.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Support\\Collection<int, float>|\\Illuminate\\Contracts\\Support\\Arrayable|array<int, float>|string  $vector\n     * @param  float  $minSimilarity  A value between 0.0 and 1.0, where 1.0 is identical.\n     * @param  bool  $order\n     * @return $this\n     */\n    public function whereVectorSimilarTo($column, $vector, $minSimilarity = 0.6, $order = true)\n    {\n        if (is_string($vector)) {\n            $vector = Str::of($vector)->toEmbeddings(cache: true);\n        }\n\n        $this->whereVectorDistanceLessThan($column, $vector, 1 - $minSimilarity);\n\n        if ($order) {\n            $this->orderByVectorDistance($column, $vector);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a vector distance \"where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Support\\Collection<int, float>|\\Illuminate\\Contracts\\Support\\Arrayable|array<int, float>|string  $vector\n     * @param  float  $maxDistance\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereVectorDistanceLessThan($column, $vector, $maxDistance, $boolean = 'and')\n    {\n        $this->ensureConnectionSupportsVectors();\n\n        if (is_string($vector)) {\n            $vector = Str::of($vector)->toEmbeddings(cache: true);\n        }\n\n        return $this->whereRaw(\n            \"({$this->getGrammar()->wrap($column)} <=> ?) <= ?\",\n            [\n                json_encode(\n                    $vector instanceof Arrayable\n                        ? $vector->toArray()\n                        : $vector,\n                    flags: JSON_THROW_ON_ERROR\n                ),\n                $maxDistance,\n            ],\n            $boolean\n        );\n    }\n\n    /**\n     * Add a vector distance \"or where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Support\\Collection<int, float>|\\Illuminate\\Contracts\\Support\\Arrayable|array<int, float>|string  $vector\n     * @param  float  $maxDistance\n     * @return $this\n     */\n    public function orWhereVectorDistanceLessThan($column, $vector, $maxDistance)\n    {\n        return $this->whereVectorDistanceLessThan($column, $vector, $maxDistance, 'or');\n    }\n\n    /**\n     * Add a raw \"where\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|literal-string  $sql\n     * @param  mixed  $bindings\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereRaw($sql, $bindings = [], $boolean = 'and')\n    {\n        $this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean];\n\n        $this->addBinding((array) $bindings, 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add a raw \"or where\" clause to the query.\n     *\n     * @param  literal-string  $sql\n     * @param  mixed  $bindings\n     * @return $this\n     */\n    public function orWhereRaw($sql, $bindings = [])\n    {\n        return $this->whereRaw($sql, $bindings, 'or');\n    }\n\n    /**\n     * Add a \"where like\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $value\n     * @param  bool  $caseSensitive\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereLike($column, $value, $caseSensitive = false, $boolean = 'and', $not = false)\n    {\n        $type = 'Like';\n\n        $this->wheres[] = compact('type', 'column', 'value', 'caseSensitive', 'boolean', 'not');\n\n        if (method_exists($this->grammar, 'prepareWhereLikeBinding')) {\n            $value = $this->grammar->prepareWhereLikeBinding($value, $caseSensitive);\n        }\n\n        $this->addBinding($value);\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where like\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $value\n     * @param  bool  $caseSensitive\n     * @return $this\n     */\n    public function orWhereLike($column, $value, $caseSensitive = false)\n    {\n        return $this->whereLike($column, $value, $caseSensitive, 'or', false);\n    }\n\n    /**\n     * Add a \"where not like\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $value\n     * @param  bool  $caseSensitive\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotLike($column, $value, $caseSensitive = false, $boolean = 'and')\n    {\n        return $this->whereLike($column, $value, $caseSensitive, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not like\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $value\n     * @param  bool  $caseSensitive\n     * @return $this\n     */\n    public function orWhereNotLike($column, $value, $caseSensitive = false)\n    {\n        return $this->whereNotLike($column, $value, $caseSensitive, 'or');\n    }\n\n    /**\n     * Add a \"where null safe equals\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNullSafeEquals($column, $value, $boolean = 'and')\n    {\n        $type = 'NullSafeEquals';\n\n        $this->wheres[] = compact('type', 'column', 'value', 'boolean');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($this->flattenValue($value), 'where');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where null safe equals\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereNullSafeEquals($column, $value)\n    {\n        return $this->whereNullSafeEquals($column, $value, 'or');\n    }\n\n    /**\n     * Add a \"where in\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $values\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function whereIn($column, $values, $boolean = 'and', $not = false)\n    {\n        $type = $not ? 'NotIn' : 'In';\n\n        // If the value is a query builder instance we will assume the developer wants to\n        // look for any values that exist within this given query. So, we will add the\n        // query accordingly so that this query is properly executed when it is run.\n        if ($this->isQueryable($values)) {\n            [$query, $bindings] = $this->createSub($values);\n\n            $values = [new Expression($query)];\n\n            $this->addBinding($bindings, 'where');\n        }\n\n        // Next, if the value is Arrayable we need to cast it to its raw array form so we\n        // have the underlying array value instead of an Arrayable object which is not\n        // able to be added as a binding, etc. We will then add to the wheres array.\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->wheres[] = compact('type', 'column', 'values', 'boolean');\n\n        if (count($values) !== count(Arr::flatten($values, 1))) {\n            throw new InvalidArgumentException('Nested arrays may not be passed to whereIn method.');\n        }\n\n        // Finally, we'll add a binding for each value unless that value is an expression\n        // in which case we will just skip over it since it will be the query as a raw\n        // string and not as a parameterized place-holder to be replaced by the PDO.\n        $this->addBinding($this->cleanBindings($values), 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where in\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $values\n     * @return $this\n     */\n    public function orWhereIn($column, $values)\n    {\n        return $this->whereIn($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where not in\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $values\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotIn($column, $values, $boolean = 'and')\n    {\n        return $this->whereIn($column, $values, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not in\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $values\n     * @return $this\n     */\n    public function orWhereNotIn($column, $values)\n    {\n        return $this->whereNotIn($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where in raw\" clause for integer values to the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $values\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false)\n    {\n        $type = $not ? 'NotInRaw' : 'InRaw';\n\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $values = Arr::flatten($values);\n\n        foreach ($values as &$value) {\n            $value = (int) ($value instanceof BackedEnum ? $value->value : $value);\n        }\n\n        $this->wheres[] = compact('type', 'column', 'values', 'boolean');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where in raw\" clause for integer values to the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $values\n     * @return $this\n     */\n    public function orWhereIntegerInRaw($column, $values)\n    {\n        return $this->whereIntegerInRaw($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where not in raw\" clause for integer values to the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $values\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereIntegerNotInRaw($column, $values, $boolean = 'and')\n    {\n        return $this->whereIntegerInRaw($column, $values, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not in raw\" clause for integer values to the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $values\n     * @return $this\n     */\n    public function orWhereIntegerNotInRaw($column, $values)\n    {\n        return $this->whereIntegerNotInRaw($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where null\" clause to the query.\n     *\n     * @param  string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $columns\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereNull($columns, $boolean = 'and', $not = false)\n    {\n        $type = $not ? 'NotNull' : 'Null';\n\n        foreach (Arr::wrap($columns) as $column) {\n            $this->wheres[] = compact('type', 'column', 'boolean');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where null\" clause to the query.\n     *\n     * @param  string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $column\n     * @return $this\n     */\n    public function orWhereNull($column)\n    {\n        return $this->whereNull($column, 'or');\n    }\n\n    /**\n     * Add a \"where not null\" clause to the query.\n     *\n     * @param  string|array|\\Illuminate\\Contracts\\Database\\Query\\Expression  $columns\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotNull($columns, $boolean = 'and')\n    {\n        return $this->whereNull($columns, $boolean, true);\n    }\n\n    /**\n     * Add a \"where between\" statement to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereBetween($column, iterable $values, $boolean = 'and', $not = false)\n    {\n        $type = 'between';\n\n        if ($this->isQueryable($column)) {\n            [$sub, $bindings] = $this->createSub($column);\n\n            return $this->addBinding($bindings, 'where')\n                ->whereBetween(new Expression('('.$sub.')'), $values, $boolean, $not);\n        }\n\n        if ($values instanceof DatePeriod) {\n            $values = $this->resolveDatePeriodBounds($values);\n        }\n\n        $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');\n\n        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add a \"where between\" statement using columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereBetweenColumns($column, array $values, $boolean = 'and', $not = false)\n    {\n        $type = 'betweenColumns';\n\n        if ($this->isQueryable($column)) {\n            [$sub, $bindings] = $this->createSub($column);\n\n            return $this->addBinding($bindings, 'where')\n                ->whereBetweenColumns(new Expression('('.$sub.')'), $values, $boolean, $not);\n        }\n\n        $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where between\" statement to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orWhereBetween($column, iterable $values)\n    {\n        return $this->whereBetween($column, $values, 'or');\n    }\n\n    /**\n     * Add an \"or where between\" statement using columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orWhereBetweenColumns($column, array $values)\n    {\n        return $this->whereBetweenColumns($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where not between\" statement to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotBetween($column, iterable $values, $boolean = 'and')\n    {\n        return $this->whereBetween($column, $values, $boolean, true);\n    }\n\n    /**\n     * Add a \"where not between\" statement using columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotBetweenColumns($column, array $values, $boolean = 'and')\n    {\n        return $this->whereBetweenColumns($column, $values, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not between\" statement to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orWhereNotBetween($column, iterable $values)\n    {\n        return $this->whereNotBetween($column, $values, 'or');\n    }\n\n    /**\n     * Add an \"or where not between\" statement using columns to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orWhereNotBetweenColumns($column, array $values)\n    {\n        return $this->whereNotBetweenColumns($column, $values, 'or');\n    }\n\n    /**\n     * Add a \"where between columns\" statement using a value to the query.\n     *\n     * @param  mixed  $value\n     * @param  array{\\Illuminate\\Contracts\\Database\\Query\\Expression|string, \\Illuminate\\Contracts\\Database\\Query\\Expression|string}  $columns\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereValueBetween($value, array $columns, $boolean = 'and', $not = false)\n    {\n        $type = 'valueBetween';\n\n        $this->wheres[] = compact('type', 'value', 'columns', 'boolean', 'not');\n\n        $this->addBinding($value, 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where between columns\" statement using a value to the query.\n     *\n     * @param  mixed  $value\n     * @param  array{\\Illuminate\\Contracts\\Database\\Query\\Expression|string, \\Illuminate\\Contracts\\Database\\Query\\Expression|string}  $columns\n     * @return $this\n     */\n    public function orWhereValueBetween($value, array $columns)\n    {\n        return $this->whereValueBetween($value, $columns, 'or');\n    }\n\n    /**\n     * Add a \"where not between columns\" statement using a value to the query.\n     *\n     * @param  mixed  $value\n     * @param  array{\\Illuminate\\Contracts\\Database\\Query\\Expression|string, \\Illuminate\\Contracts\\Database\\Query\\Expression|string}  $columns\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereValueNotBetween($value, array $columns, $boolean = 'and')\n    {\n        return $this->whereValueBetween($value, $columns, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not between columns\" statement using a value to the query.\n     *\n     * @param  mixed  $value\n     * @param  array{\\Illuminate\\Contracts\\Database\\Query\\Expression|string, \\Illuminate\\Contracts\\Database\\Query\\Expression|string}  $columns\n     * @return $this\n     */\n    public function orWhereValueNotBetween($value, array $columns)\n    {\n        return $this->whereValueNotBetween($value, $columns, 'or');\n    }\n\n    /**\n     * Add an \"or where not null\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orWhereNotNull($column)\n    {\n        return $this->whereNotNull($column, 'or');\n    }\n\n    /**\n     * Add a \"where date\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|null  $operator\n     * @param  \\DateTimeInterface|string|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereDate($column, $operator, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $value = $this->flattenValue($value);\n\n        if ($value instanceof DateTimeInterface) {\n            $value = $value->format('Y-m-d');\n        }\n\n        return $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean);\n    }\n\n    /**\n     * Add an \"or where date\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|null  $operator\n     * @param  \\DateTimeInterface|string|null  $value\n     * @return $this\n     */\n    public function orWhereDate($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereDate($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where time\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|null  $operator\n     * @param  \\DateTimeInterface|string|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereTime($column, $operator, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $value = $this->flattenValue($value);\n\n        if ($value instanceof DateTimeInterface) {\n            $value = $value->format('H:i:s');\n        }\n\n        return $this->addDateBasedWhere('Time', $column, $operator, $value, $boolean);\n    }\n\n    /**\n     * Add an \"or where time\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|null  $operator\n     * @param  \\DateTimeInterface|string|null  $value\n     * @return $this\n     */\n    public function orWhereTime($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereTime($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where day\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereDay($column, $operator, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $value = $this->flattenValue($value);\n\n        if ($value instanceof DateTimeInterface) {\n            $value = $value->format('d');\n        }\n\n        if (! $value instanceof ExpressionContract) {\n            $value = sprintf('%02d', $value);\n        }\n\n        return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean);\n    }\n\n    /**\n     * Add an \"or where day\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @return $this\n     */\n    public function orWhereDay($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereDay($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where month\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereMonth($column, $operator, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $value = $this->flattenValue($value);\n\n        if ($value instanceof DateTimeInterface) {\n            $value = $value->format('m');\n        }\n\n        if (! $value instanceof ExpressionContract) {\n            $value = sprintf('%02d', $value);\n        }\n\n        return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean);\n    }\n\n    /**\n     * Add an \"or where month\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @return $this\n     */\n    public function orWhereMonth($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereMonth($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where year\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereYear($column, $operator, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $value = $this->flattenValue($value);\n\n        if ($value instanceof DateTimeInterface) {\n            $value = $value->format('Y');\n        }\n\n        return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean);\n    }\n\n    /**\n     * Add an \"or where year\" statement to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\DateTimeInterface|string|int|null  $operator\n     * @param  \\DateTimeInterface|string|int|null  $value\n     * @return $this\n     */\n    public function orWhereYear($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereYear($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a date based (year, month, day, time) statement to the query.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')\n    {\n        $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($value, 'where');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a nested \"where\" statement to the query.\n     *\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNested(Closure $callback, $boolean = 'and')\n    {\n        $callback($query = $this->forNestedWhere());\n\n        return $this->addNestedWhereQuery($query, $boolean);\n    }\n\n    /**\n     * Create a new query instance for nested where condition.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function forNestedWhere()\n    {\n        return $this->newQuery()->from($this->from);\n    }\n\n    /**\n     * Add another query builder as a nested where to the query builder.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function addNestedWhereQuery($query, $boolean = 'and')\n    {\n        if (count($query->wheres)) {\n            $type = 'Nested';\n\n            $this->wheres[] = compact('type', 'query', 'boolean');\n\n            $this->addBinding($query->getRawBindings()['where'], 'where');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a full sub-select to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $operator\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $callback\n     * @param  string  $boolean\n     * @return $this\n     */\n    protected function whereSub($column, $operator, $callback, $boolean)\n    {\n        $type = 'Sub';\n\n        if ($callback instanceof Closure) {\n            // Once we have the query instance we can simply execute it so it can add all\n            // of the sub-select's conditions to itself, and then we can cache it off\n            // in the array of where clauses for the \"main\" parent query instance.\n            $callback($query = $this->forSubQuery());\n        } else {\n            $query = $callback instanceof EloquentBuilder ? $callback->toBase() : $callback;\n        }\n\n        $this->wheres[] = compact(\n            'type', 'column', 'operator', 'query', 'boolean'\n        );\n\n        $this->addBinding($query->getBindings(), 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"exists\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $callback\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereExists($callback, $boolean = 'and', $not = false)\n    {\n        if ($callback instanceof Closure) {\n            $query = $this->forSubQuery();\n\n            // Similar to the sub-select clause, we will create a new query instance so\n            // the developer may cleanly specify the entire exists query and we will\n            // compile the whole thing in the grammar and insert it into the SQL.\n            $callback($query);\n        } else {\n            $query = $callback instanceof EloquentBuilder ? $callback->toBase() : $callback;\n        }\n\n        return $this->addWhereExistsQuery($query, $boolean, $not);\n    }\n\n    /**\n     * Add an \"or where exists\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $callback\n     * @param  bool  $not\n     * @return $this\n     */\n    public function orWhereExists($callback, $not = false)\n    {\n        return $this->whereExists($callback, 'or', $not);\n    }\n\n    /**\n     * Add a \"where not exists\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $callback\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNotExists($callback, $boolean = 'and')\n    {\n        return $this->whereExists($callback, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where not exists\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $callback\n     * @return $this\n     */\n    public function orWhereNotExists($callback)\n    {\n        return $this->orWhereExists($callback, true);\n    }\n\n    /**\n     * Add an \"exists\" clause to the query.\n     *\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function addWhereExistsQuery(self $query, $boolean = 'and', $not = false)\n    {\n        $type = $not ? 'NotExists' : 'Exists';\n\n        $this->wheres[] = compact('type', 'query', 'boolean');\n\n        $this->addBinding($query->getBindings(), 'where');\n\n        return $this;\n    }\n\n    /**\n     * Adds a where condition using row values.\n     *\n     * @param  array  $columns\n     * @param  string  $operator\n     * @param  array  $values\n     * @param  string  $boolean\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function whereRowValues($columns, $operator, $values, $boolean = 'and')\n    {\n        if (count($columns) !== count($values)) {\n            throw new InvalidArgumentException('The number of columns must match the number of values');\n        }\n\n        $type = 'RowValues';\n\n        $this->wheres[] = compact('type', 'columns', 'operator', 'values', 'boolean');\n\n        $this->addBinding($this->cleanBindings($values));\n\n        return $this;\n    }\n\n    /**\n     * Adds an or where condition using row values.\n     *\n     * @param  array  $columns\n     * @param  string  $operator\n     * @param  array  $values\n     * @return $this\n     */\n    public function orWhereRowValues($columns, $operator, $values)\n    {\n        return $this->whereRowValues($columns, $operator, $values, 'or');\n    }\n\n    /**\n     * Add a \"where JSON contains\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereJsonContains($column, $value, $boolean = 'and', $not = false)\n    {\n        $type = 'JsonContains';\n\n        $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($this->grammar->prepareBindingForJsonContains($value));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where JSON contains\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereJsonContains($column, $value)\n    {\n        return $this->whereJsonContains($column, $value, 'or');\n    }\n\n    /**\n     * Add a \"where JSON not contains\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereJsonDoesntContain($column, $value, $boolean = 'and')\n    {\n        return $this->whereJsonContains($column, $value, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where JSON not contains\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereJsonDoesntContain($column, $value)\n    {\n        return $this->whereJsonDoesntContain($column, $value, 'or');\n    }\n\n    /**\n     * Add a \"where JSON overlaps\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereJsonOverlaps($column, $value, $boolean = 'and', $not = false)\n    {\n        $type = 'JsonOverlaps';\n\n        $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($this->grammar->prepareBindingForJsonContains($value));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where JSON overlaps\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereJsonOverlaps($column, $value)\n    {\n        return $this->whereJsonOverlaps($column, $value, 'or');\n    }\n\n    /**\n     * Add a \"where JSON not overlap\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereJsonDoesntOverlap($column, $value, $boolean = 'and')\n    {\n        return $this->whereJsonOverlaps($column, $value, $boolean, true);\n    }\n\n    /**\n     * Add an \"or where JSON not overlap\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereJsonDoesntOverlap($column, $value)\n    {\n        return $this->whereJsonDoesntOverlap($column, $value, 'or');\n    }\n\n    /**\n     * Add a clause that determines if a JSON path exists to the query.\n     *\n     * @param  string  $column\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function whereJsonContainsKey($column, $boolean = 'and', $not = false)\n    {\n        $type = 'JsonContainsKey';\n\n        $this->wheres[] = compact('type', 'column', 'boolean', 'not');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or\" clause that determines if a JSON path exists to the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function orWhereJsonContainsKey($column)\n    {\n        return $this->whereJsonContainsKey($column, 'or');\n    }\n\n    /**\n     * Add a clause that determines if a JSON path does not exist to the query.\n     *\n     * @param  string  $column\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereJsonDoesntContainKey($column, $boolean = 'and')\n    {\n        return $this->whereJsonContainsKey($column, $boolean, true);\n    }\n\n    /**\n     * Add an \"or\" clause that determines if a JSON path does not exist to the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function orWhereJsonDoesntContainKey($column)\n    {\n        return $this->whereJsonDoesntContainKey($column, 'or');\n    }\n\n    /**\n     * Add a \"where JSON length\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereJsonLength($column, $operator, $value = null, $boolean = 'and')\n    {\n        $type = 'JsonLength';\n\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding((int) $this->flattenValue($value));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where JSON length\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereJsonLength($column, $operator, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->whereJsonLength($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Handles dynamic \"where\" clauses to the query.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function dynamicWhere($method, $parameters)\n    {\n        $finder = substr($method, 5);\n\n        $segments = preg_split(\n            '/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE\n        );\n\n        // The connector variable will determine which connector will be used for the\n        // query condition. We will change it as we come across new boolean values\n        // in the dynamic method strings, which could contain a number of these.\n        $connector = 'and';\n\n        $index = 0;\n\n        foreach ($segments as $segment) {\n            // If the segment is not a boolean connector, we can assume it is a column's name\n            // and we will add it to the query as a new constraint as a where clause, then\n            // we can keep iterating through the dynamic method string's segments again.\n            if ($segment !== 'And' && $segment !== 'Or') {\n                $this->addDynamic($segment, $connector, $parameters, $index);\n\n                $index++;\n            }\n\n            // Otherwise, we will store the connector so we know how the next where clause we\n            // find in the query should be connected to the previous ones, meaning we will\n            // have the proper boolean connector to connect the next where clause found.\n            else {\n                $connector = $segment;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a single dynamic \"where\" clause statement to the query.\n     *\n     * @param  string  $segment\n     * @param  string  $connector\n     * @param  array  $parameters\n     * @param  int  $index\n     * @return void\n     */\n    protected function addDynamic($segment, $connector, $parameters, $index)\n    {\n        // Once we have parsed out the columns and formatted the boolean operators we\n        // are ready to add it to this query as a where clause just like any other\n        // clause on the query. Then we'll increment the parameter index values.\n        $bool = strtolower($connector);\n\n        $this->where(Str::snake($segment), '=', $parameters[$index], $bool);\n    }\n\n    /**\n     * Add a \"where fulltext\" clause to the query.\n     *\n     * @param  string|string[]  $columns\n     * @param  string  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereFullText($columns, $value, array $options = [], $boolean = 'and')\n    {\n        $type = 'Fulltext';\n\n        $columns = (array) $columns;\n\n        $this->wheres[] = compact('type', 'columns', 'value', 'options', 'boolean');\n\n        $this->addBinding($value);\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where fulltext\" clause to the query.\n     *\n     * @param  string|string[]  $columns\n     * @param  string  $value\n     * @return $this\n     */\n    public function orWhereFullText($columns, $value, array $options = [])\n    {\n        return $this->whereFullText($columns, $value, $options, 'or');\n    }\n\n    /**\n     * Add a \"where\" clause to the query for multiple columns with \"and\" conditions between them.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereAll($columns, $operator = null, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        $this->whereNested(function ($query) use ($columns, $operator, $value) {\n            foreach ($columns as $column) {\n                $query->where($column, $operator, $value, 'and');\n            }\n        }, $boolean);\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where\" clause to the query for multiple columns with \"and\" conditions between them.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereAll($columns, $operator = null, $value = null)\n    {\n        return $this->whereAll($columns, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where\" clause to the query for multiple columns with \"or\" conditions between them.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereAny($columns, $operator = null, $value = null, $boolean = 'and')\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        $this->whereNested(function ($query) use ($columns, $operator, $value) {\n            foreach ($columns as $column) {\n                $query->where($column, $operator, $value, 'or');\n            }\n        }, $boolean);\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where\" clause to the query for multiple columns with \"or\" conditions between them.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereAny($columns, $operator = null, $value = null)\n    {\n        return $this->whereAny($columns, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"where not\" clause to the query for multiple columns where none of the conditions should be true.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function whereNone($columns, $operator = null, $value = null, $boolean = 'and')\n    {\n        return $this->whereAny($columns, $operator, $value, $boolean.' not');\n    }\n\n    /**\n     * Add an \"or where not\" clause to the query for multiple columns where none of the conditions should be true.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression[]|\\Closure[]|string[]  $columns\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function orWhereNone($columns, $operator = null, $value = null)\n    {\n        return $this->whereNone($columns, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a \"group by\" clause to the query.\n     *\n     * @param  array|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  ...$groups\n     * @return $this\n     */\n    public function groupBy(...$groups)\n    {\n        foreach ($groups as $group) {\n            $this->groups = array_merge(\n                (array) $this->groups,\n                Arr::wrap($group)\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a raw \"groupBy\" clause to the query.\n     *\n     * @param  literal-string  $sql\n     * @return $this\n     */\n    public function groupByRaw($sql, array $bindings = [])\n    {\n        $this->groups[] = new Expression($sql);\n\n        $this->addBinding($bindings, 'groupBy');\n\n        return $this;\n    }\n\n    /**\n     * Add a \"having\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|\\Closure|string  $column\n     * @param  \\DateTimeInterface|string|int|float|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|\\DateTimeInterface|string|int|float|null  $value\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function having($column, $operator = null, $value = null, $boolean = 'and')\n    {\n        $type = 'Basic';\n\n        if ($column instanceof ConditionExpression) {\n            $type = 'Expression';\n\n            $this->havings[] = compact('type', 'column', 'boolean');\n\n            return $this;\n        }\n\n        // Here we will make some assumptions about the operator. If only 2 values are\n        // passed to the method, we will assume that the operator is an equals sign\n        // and keep going. Otherwise, we'll require the operator to be passed in.\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        if ($column instanceof Closure && is_null($operator)) {\n            return $this->havingNested($column, $boolean);\n        }\n\n        // If the given operator is not found in the list of valid operators we will\n        // assume that the developer is just short-cutting the '=' operators and\n        // we will set the operators to '=' and set the values appropriately.\n        if ($this->invalidOperator($operator)) {\n            [$value, $operator] = [$operator, '='];\n        }\n\n        if ($this->isBitwiseOperator($operator)) {\n            $type = 'Bitwise';\n        }\n\n        $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');\n\n        if (! $value instanceof ExpressionContract) {\n            $this->addBinding($this->flattenValue($value), 'having');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or having\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|\\Closure|string  $column\n     * @param  \\DateTimeInterface|string|int|float|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|\\DateTimeInterface|string|int|float|null  $value\n     * @return $this\n     */\n    public function orHaving($column, $operator = null, $value = null)\n    {\n        [$value, $operator] = $this->prepareValueAndOperator(\n            $value, $operator, func_num_args() === 2\n        );\n\n        return $this->having($column, $operator, $value, 'or');\n    }\n\n    /**\n     * Add a nested \"having\" statement to the query.\n     *\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function havingNested(Closure $callback, $boolean = 'and')\n    {\n        $callback($query = $this->forNestedWhere());\n\n        return $this->addNestedHavingQuery($query, $boolean);\n    }\n\n    /**\n     * Add another query builder as a nested having to the query builder.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function addNestedHavingQuery($query, $boolean = 'and')\n    {\n        if (count($query->havings)) {\n            $type = 'Nested';\n\n            $this->havings[] = compact('type', 'query', 'boolean');\n\n            $this->addBinding($query->getRawBindings()['having'], 'having');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a \"having null\" clause to the query.\n     *\n     * @param  array|string  $columns\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function havingNull($columns, $boolean = 'and', $not = false)\n    {\n        $type = $not ? 'NotNull' : 'Null';\n\n        foreach (Arr::wrap($columns) as $column) {\n            $this->havings[] = compact('type', 'column', 'boolean');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or having null\" clause to the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function orHavingNull($column)\n    {\n        return $this->havingNull($column, 'or');\n    }\n\n    /**\n     * Add a \"having not null\" clause to the query.\n     *\n     * @param  array|string  $columns\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function havingNotNull($columns, $boolean = 'and')\n    {\n        return $this->havingNull($columns, $boolean, true);\n    }\n\n    /**\n     * Add an \"or having not null\" clause to the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function orHavingNotNull($column)\n    {\n        return $this->havingNotNull($column, 'or');\n    }\n\n    /**\n     * Add a \"having between\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  string  $boolean\n     * @param  bool  $not\n     * @return $this\n     */\n    public function havingBetween($column, iterable $values, $boolean = 'and', $not = false)\n    {\n        $type = 'between';\n\n        if ($values instanceof DatePeriod) {\n            $values = $this->resolveDatePeriodBounds($values);\n        }\n\n        $this->havings[] = compact('type', 'column', 'values', 'boolean', 'not');\n\n        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'having');\n\n        return $this;\n    }\n\n    /**\n     * Add a \"having not between\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  iterable  $values\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function havingNotBetween($column, iterable $values, $boolean = 'and')\n    {\n        return $this->havingBetween($column, $values, $boolean, true);\n    }\n\n    /**\n     * Add an \"or having between\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  iterable  $values\n     * @return $this\n     */\n    public function orHavingBetween($column, iterable $values)\n    {\n        return $this->havingBetween($column, $values, 'or');\n    }\n\n    /**\n     * Add an \"or having not between\" clause to the query.\n     *\n     * @param  string  $column\n     * @param  iterable  $values\n     * @return $this\n     */\n    public function orHavingNotBetween($column, iterable $values)\n    {\n        return $this->havingBetween($column, $values, 'or', true);\n    }\n\n    /**\n     * Resolve the start and end dates from a DatePeriod.\n     *\n     * @param  \\DatePeriod  $period\n     * @return array{\\DateTimeInterface, \\DateTimeInterface}\n     */\n    protected function resolveDatePeriodBounds(DatePeriod $period)\n    {\n        [$start, $end] = [$period->getStartDate(), $period->getEndDate()];\n\n        if ($end === null) {\n            $end = clone $start;\n\n            $recurrences = $period->getRecurrences();\n\n            for ($i = 0; $i < $recurrences; $i++) {\n                $end = $end->add($period->getDateInterval());\n            }\n        }\n\n        return [$start, $end];\n    }\n\n    /**\n     * Add a raw \"having\" clause to the query.\n     *\n     * @param  literal-string  $sql\n     * @param  string  $boolean\n     * @return $this\n     */\n    public function havingRaw($sql, array $bindings = [], $boolean = 'and')\n    {\n        $type = 'Raw';\n\n        $this->havings[] = compact('type', 'sql', 'boolean');\n\n        $this->addBinding($bindings, 'having');\n\n        return $this;\n    }\n\n    /**\n     * Add a raw \"or having\" clause to the query.\n     *\n     * @param  literal-string  $sql\n     * @return $this\n     */\n    public function orHavingRaw($sql, array $bindings = [])\n    {\n        return $this->havingRaw($sql, $bindings, 'or');\n    }\n\n    /**\n     * Add an \"order by\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string  $direction\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function orderBy($column, $direction = 'asc')\n    {\n        if ($this->isQueryable($column)) {\n            [$query, $bindings] = $this->createSub($column);\n\n            $column = new Expression('('.$query.')');\n\n            $this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');\n        }\n\n        $direction = strtolower($direction);\n\n        if (! in_array($direction, ['asc', 'desc'], true)) {\n            throw new InvalidArgumentException('Order direction must be \"asc\" or \"desc\".');\n        }\n\n        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [\n            'column' => $column,\n            'direction' => $direction,\n        ];\n\n        return $this;\n    }\n\n    /**\n     * Add a descending \"order by\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function orderByDesc($column)\n    {\n        return $this->orderBy($column, 'desc');\n    }\n\n    /**\n     * Add an \"order by\" clause for a timestamp to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function latest($column = 'created_at')\n    {\n        return $this->orderBy($column, 'desc');\n    }\n\n    /**\n     * Add an \"order by\" clause for a timestamp to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return $this\n     */\n    public function oldest($column = 'created_at')\n    {\n        return $this->orderBy($column, 'asc');\n    }\n\n    /**\n     * Add a vector-distance \"order by\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Support\\Collection<int, float>|\\Illuminate\\Contracts\\Support\\Arrayable|array<int, float>  $vector\n     * @return $this\n     */\n    public function orderByVectorDistance($column, $vector)\n    {\n        $this->ensureConnectionSupportsVectors();\n\n        if (is_string($vector)) {\n            $vector = Str::of($vector)->toEmbeddings(cache: true);\n        }\n\n        $this->addBinding(\n            json_encode(\n                $vector instanceof Arrayable\n                    ? $vector->toArray()\n                    : $vector,\n                flags: JSON_THROW_ON_ERROR\n            ),\n            $this->unions ? 'unionOrder' : 'order'\n        );\n\n        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [\n            'column' => new Expression(\"({$this->getGrammar()->wrap($column)} <=> ?)\"),\n            'direction' => 'asc',\n        ];\n\n        return $this;\n    }\n\n    /**\n     * Put the query's results in random order.\n     *\n     * @param  string|int  $seed\n     * @return $this\n     */\n    public function inRandomOrder($seed = '')\n    {\n        return $this->orderByRaw($this->grammar->compileRandom($seed));\n    }\n\n    /**\n     * Add an \"order by\" clause to order results by a given sequence of values.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $values\n     * @return $this\n     */\n    public function inOrderOf($column, $values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $values = array_values($values);\n\n        if (empty($values)) {\n            return $this;\n        }\n\n        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [\n            'type' => 'InOrderOf',\n            'column' => $column,\n            'values' => $values,\n        ];\n\n        $this->addBinding($this->cleanBindings($values), $this->unions ? 'unionOrder' : 'order');\n\n        return $this;\n    }\n\n    /**\n     * Add a raw \"order by\" clause to the query.\n     *\n     * @param  literal-string  $sql\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function orderByRaw($sql, $bindings = [])\n    {\n        $type = 'Raw';\n\n        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = compact('type', 'sql');\n\n        $this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');\n\n        return $this;\n    }\n\n    /**\n     * Alias to set the \"offset\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function skip($value)\n    {\n        return $this->offset($value);\n    }\n\n    /**\n     * Set the \"offset\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function offset($value)\n    {\n        $property = $this->unions ? 'unionOffset' : 'offset';\n\n        $this->$property = max(0, (int) $value);\n\n        return $this;\n    }\n\n    /**\n     * Alias to set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function take($value)\n    {\n        return $this->limit($value);\n    }\n\n    /**\n     * Set the \"limit\" value of the query.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function limit($value)\n    {\n        $property = $this->unions ? 'unionLimit' : 'limit';\n\n        if ($value >= 0) {\n            $this->$property = ! is_null($value) ? (int) $value : null;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a \"group limit\" clause to the query.\n     *\n     * @param  int  $value\n     * @param  string  $column\n     * @return $this\n     */\n    public function groupLimit($value, $column)\n    {\n        if ($value >= 0) {\n            $this->groupLimit = compact('value', 'column');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the limit and offset for a given page.\n     *\n     * @param  int  $page\n     * @param  int  $perPage\n     * @return $this\n     */\n    public function forPage($page, $perPage = 15)\n    {\n        return $this->offset(($page - 1) * $perPage)->limit($perPage);\n    }\n\n    /**\n     * Constrain the query to the previous \"page\" of results before a given ID.\n     *\n     * @param  int  $perPage\n     * @param  int|null  $lastId\n     * @param  string  $column\n     * @return $this\n     */\n    public function forPageBeforeId($perPage = 15, $lastId = 0, $column = 'id')\n    {\n        $this->orders = $this->removeExistingOrdersFor($column);\n\n        if (is_null($lastId)) {\n            $this->whereNotNull($column);\n        } else {\n            $this->where($column, '<', $lastId);\n        }\n\n        return $this->orderBy($column, 'desc')\n            ->limit($perPage);\n    }\n\n    /**\n     * Constrain the query to the next \"page\" of results after a given ID.\n     *\n     * @param  int  $perPage\n     * @param  int|null  $lastId\n     * @param  string  $column\n     * @return $this\n     */\n    public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')\n    {\n        $this->orders = $this->removeExistingOrdersFor($column);\n\n        if (is_null($lastId)) {\n            $this->whereNotNull($column);\n        } else {\n            $this->where($column, '>', $lastId);\n        }\n\n        return $this->orderBy($column, 'asc')\n            ->limit($perPage);\n    }\n\n    /**\n     * Remove all existing orders and optionally add a new order.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $column\n     * @param  string  $direction\n     * @return $this\n     */\n    public function reorder($column = null, $direction = 'asc')\n    {\n        $this->orders = null;\n        $this->unionOrders = null;\n        $this->bindings['order'] = [];\n        $this->bindings['unionOrder'] = [];\n\n        if ($column) {\n            return $this->orderBy($column, $direction);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add descending \"reorder\" clause to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $column\n     * @return $this\n     */\n    public function reorderDesc($column)\n    {\n        return $this->reorder($column, 'desc');\n    }\n\n    /**\n     * Get an array with all orders with a given column removed.\n     *\n     * @param  string  $column\n     * @return array\n     */\n    protected function removeExistingOrdersFor($column)\n    {\n        return (new Collection($this->orders))\n            ->reject(fn ($order) => isset($order['column']) && $order['column'] === $column)\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Add a \"union\" statement to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $query\n     * @param  bool  $all\n     * @return $this\n     */\n    public function union($query, $all = false)\n    {\n        if ($query instanceof Closure) {\n            $query($query = $this->newQuery());\n        }\n\n        $this->unions[] = compact('query', 'all');\n\n        $this->addBinding($query->getBindings(), 'union');\n\n        return $this;\n    }\n\n    /**\n     * Add a \"union all\" statement to the query.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>  $query\n     * @return $this\n     */\n    public function unionAll($query)\n    {\n        return $this->union($query, true);\n    }\n\n    /**\n     * Lock the selected rows in the table.\n     *\n     * @param  string|bool  $value\n     * @return $this\n     */\n    public function lock($value = true)\n    {\n        $this->lock = $value;\n\n        if (! is_null($this->lock)) {\n            $this->useWritePdo();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Lock the selected rows in the table for updating.\n     *\n     * @return $this\n     */\n    public function lockForUpdate()\n    {\n        return $this->lock(true);\n    }\n\n    /**\n     * Share lock the selected rows in the table.\n     *\n     * @return $this\n     */\n    public function sharedLock()\n    {\n        return $this->lock(false);\n    }\n\n    /**\n     * Set a query execution timeout in seconds.\n     *\n     * @param  int|null  $seconds\n     * @return $this\n     *\n     * @throws InvalidArgumentException\n     */\n    public function timeout(?int $seconds): static\n    {\n        if ($seconds !== null && $seconds <= 0) {\n            throw new InvalidArgumentException('Timeout must be greater than zero.');\n        }\n\n        $this->timeout = $seconds;\n\n        return $this;\n    }\n\n    /**\n     * Register a closure to be invoked before the query is executed.\n     *\n     * @return $this\n     */\n    public function beforeQuery(callable $callback)\n    {\n        $this->beforeQueryCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Invoke the \"before query\" modification callbacks.\n     *\n     * @return void\n     */\n    public function applyBeforeQueryCallbacks()\n    {\n        foreach ($this->beforeQueryCallbacks as $callback) {\n            $callback($this);\n        }\n\n        $this->beforeQueryCallbacks = [];\n    }\n\n    /**\n     * Register a closure to be invoked after the query is executed.\n     *\n     * @return $this\n     */\n    public function afterQuery(Closure $callback)\n    {\n        $this->afterQueryCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Invoke the \"after query\" modification callbacks.\n     *\n     * @param  mixed  $result\n     * @return mixed\n     */\n    public function applyAfterQueryCallbacks($result)\n    {\n        foreach ($this->afterQueryCallbacks as $afterQueryCallback) {\n            $result = $afterQueryCallback($result) ?: $result;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get the SQL representation of the query.\n     *\n     * @return string\n     */\n    public function toSql()\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        return $this->grammar->compileSelect($this);\n    }\n\n    /**\n     * Get the raw SQL representation of the query with embedded bindings.\n     *\n     * @return string\n     */\n    public function toRawSql()\n    {\n        return $this->grammar->substituteBindingsIntoRawSql(\n            $this->toSql(), $this->connection->prepareBindings($this->getBindings())\n        );\n    }\n\n    /**\n     * Execute a query for a single record by ID.\n     *\n     * @param  int|string  $id\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @return \\stdClass|null\n     */\n    public function find($id, $columns = ['*'])\n    {\n        return $this->where('id', '=', $id)->first($columns);\n    }\n\n    /**\n     * Execute a query for a single record by ID or call a callback.\n     *\n     * @template TValue\n     *\n     * @param  mixed  $id\n     * @param  (\\Closure(): TValue)|string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @param  (\\Closure(): TValue)|null  $callback\n     * @return \\stdClass|TValue\n     */\n    public function findOr($id, $columns = ['*'], ?Closure $callback = null)\n    {\n        if ($columns instanceof Closure) {\n            $callback = $columns;\n\n            $columns = ['*'];\n        }\n\n        if (! is_null($data = $this->find($id, $columns))) {\n            return $data;\n        }\n\n        return $callback();\n    }\n\n    /**\n     * Get a single column's value from the first result of a query.\n     *\n     * @param  string  $column\n     * @return mixed\n     */\n    public function value($column)\n    {\n        $result = (array) $this->first([$column]);\n\n        return count($result) > 0 ? array_first($result) : null;\n    }\n\n    /**\n     * Get a single expression value from the first result of a query.\n     *\n     * @param  literal-string  $expression\n     * @return mixed\n     */\n    public function rawValue(string $expression, array $bindings = [])\n    {\n        $result = (array) $this->selectRaw($expression, $bindings)->first();\n\n        return count($result) > 0 ? array_first($result) : null;\n    }\n\n    /**\n     * Get a single column's value from the first result of a query if it's the sole matching record.\n     *\n     * @param  string  $column\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\RecordsNotFoundException\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function soleValue($column)\n    {\n        $result = (array) $this->sole([$column]);\n\n        return array_first($result);\n    }\n\n    /**\n     * Execute the query as a \"select\" statement.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @return \\Illuminate\\Support\\Collection<int, \\stdClass>\n     */\n    public function get($columns = ['*'])\n    {\n        $original = $this->columns;\n\n        $this->columns ??= Arr::wrap($columns);\n\n        $items = new Collection($this->processor->processSelect($this, $this->runSelect()));\n\n        $this->columns = $original;\n\n        return $this->applyAfterQueryCallbacks(\n            isset($this->groupLimit) ? $this->withoutGroupLimitKeys($items) : $items\n        );\n    }\n\n    /**\n     * Run the query as a \"select\" statement against the connection.\n     *\n     * @return array\n     */\n    protected function runSelect()\n    {\n        return $this->connection->select(\n            $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing\n        );\n    }\n\n    /**\n     * Remove the group limit keys from the results in the collection.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $items\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function withoutGroupLimitKeys($items)\n    {\n        $keysToRemove = ['laravel_row'];\n\n        if (is_string($this->groupLimit['column'])) {\n            $column = last(explode('.', $this->groupLimit['column']));\n\n            $keysToRemove[] = '@laravel_group := '.$this->grammar->wrap($column);\n            $keysToRemove[] = '@laravel_group := '.$this->grammar->wrap('pivot_'.$column);\n        }\n\n        $items->each(function ($item) use ($keysToRemove) {\n            foreach ($keysToRemove as $key) {\n                unset($item->$key);\n            }\n        });\n\n        return $items;\n    }\n\n    /**\n     * Paginate the given query into a simple paginator.\n     *\n     * @param  int|\\Closure  $perPage\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @param  \\Closure|int|null  $total\n     * @return \\Illuminate\\Pagination\\LengthAwarePaginator\n     */\n    public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null, $total = null)\n    {\n        $page = $page ?: Paginator::resolveCurrentPage($pageName);\n\n        $total = value($total) ?? $this->getCountForPagination();\n\n        $perPage = value($perPage, $total);\n\n        $results = $total ? $this->forPage($page, $perPage)->get($columns) : new Collection;\n\n        return $this->paginator($results, $total, $perPage, $page, [\n            'path' => Paginator::resolveCurrentPath(),\n            'pageName' => $pageName,\n        ]);\n    }\n\n    /**\n     * Get a paginator only supporting simple next and previous links.\n     *\n     * This is more efficient on larger data-sets, etc.\n     *\n     * @param  int  $perPage\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @param  string  $pageName\n     * @param  int|null  $page\n     * @return \\Illuminate\\Contracts\\Pagination\\Paginator\n     */\n    public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)\n    {\n        $page = $page ?: Paginator::resolveCurrentPage($pageName);\n\n        $this->offset(($page - 1) * $perPage)->limit($perPage + 1);\n\n        return $this->simplePaginator($this->get($columns), $perPage, $page, [\n            'path' => Paginator::resolveCurrentPath(),\n            'pageName' => $pageName,\n        ]);\n    }\n\n    /**\n     * Get a paginator only supporting simple next and previous links.\n     *\n     * This is more efficient on larger data-sets, etc.\n     *\n     * @param  int|null  $perPage\n     * @param  string|\\Illuminate\\Contracts\\Database\\Query\\Expression|array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @param  string  $cursorName\n     * @param  \\Illuminate\\Pagination\\Cursor|string|null  $cursor\n     * @return \\Illuminate\\Contracts\\Pagination\\CursorPaginator\n     */\n    public function cursorPaginate($perPage = 15, $columns = ['*'], $cursorName = 'cursor', $cursor = null)\n    {\n        return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);\n    }\n\n    /**\n     * Ensure the proper order by required for cursor pagination.\n     *\n     * @param  bool  $shouldReverse\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function ensureOrderForCursorPagination($shouldReverse = false)\n    {\n        if (empty($this->orders) && empty($this->unionOrders)) {\n            $this->enforceOrderBy();\n        }\n\n        $reverseDirection = function ($order) {\n            if (! isset($order['direction'])) {\n                return $order;\n            }\n\n            $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc';\n\n            return $order;\n        };\n\n        if ($shouldReverse) {\n            $this->orders = (new Collection($this->orders))->map($reverseDirection)->toArray();\n            $this->unionOrders = (new Collection($this->unionOrders))->map($reverseDirection)->toArray();\n        }\n\n        $orders = ! empty($this->unionOrders) ? $this->unionOrders : $this->orders;\n\n        return (new Collection($orders))\n            ->filter(fn ($order) => Arr::has($order, 'direction'))\n            ->values();\n    }\n\n    /**\n     * Get the count of the total records for the paginator.\n     *\n     * @param  array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @return int<0, max>\n     */\n    public function getCountForPagination($columns = ['*'])\n    {\n        $results = $this->runPaginationCountQuery($columns);\n\n        // Once we have run the pagination count query, we will get the resulting count and\n        // take into account what type of query it was. When there is a group by we will\n        // just return the count of the entire results set since that will be correct.\n        if (! isset($results[0])) {\n            return 0;\n        } elseif (is_object($results[0])) {\n            return (int) $results[0]->aggregate;\n        }\n\n        return (int) array_change_key_case((array) $results[0])['aggregate'];\n    }\n\n    /**\n     * Run a pagination count query.\n     *\n     * @param  array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @return array<mixed>\n     */\n    protected function runPaginationCountQuery($columns = ['*'])\n    {\n        if ($this->groups || $this->havings) {\n            $clone = $this->cloneForPaginationCount();\n\n            if (is_null($clone->columns) && ! empty($this->joins)) {\n                $clone->select($this->from.'.*');\n            }\n\n            return $this->newQuery()\n                ->from(new Expression('('.$clone->toSql().') as '.$this->grammar->wrap('aggregate_table')))\n                ->mergeBindings($clone)\n                ->setAggregate('count', $this->withoutSelectAliases($columns))\n                ->get()->all();\n        }\n\n        $without = $this->unions ? ['unionOrders', 'unionLimit', 'unionOffset'] : ['columns', 'orders', 'limit', 'offset'];\n\n        return $this->cloneWithout($without)\n            ->cloneWithoutBindings($this->unions ? ['unionOrder'] : ['select', 'order'])\n            ->setAggregate('count', $this->withoutSelectAliases($columns))\n            ->get()->all();\n    }\n\n    /**\n     * Clone the existing query instance for usage in a pagination subquery.\n     *\n     * @return self\n     */\n    protected function cloneForPaginationCount()\n    {\n        return $this->cloneWithout(['orders', 'limit', 'offset'])\n            ->cloneWithoutBindings(['order']);\n    }\n\n    /**\n     * Remove the column aliases since they will break count queries.\n     *\n     * @param  array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>  $columns\n     * @return array<string|\\Illuminate\\Contracts\\Database\\Query\\Expression>\n     */\n    protected function withoutSelectAliases(array $columns)\n    {\n        return array_map(function ($column) {\n            return is_string($column) && ($aliasPosition = stripos($column, ' as ')) !== false\n                ? substr($column, 0, $aliasPosition)\n                : $column;\n        }, $columns);\n    }\n\n    /**\n     * Get a lazy collection for the given query.\n     *\n     * @return \\Illuminate\\Support\\LazyCollection<int, \\stdClass>\n     */\n    public function cursor()\n    {\n        if (is_null($this->columns)) {\n            $this->columns = ['*'];\n        }\n\n        return (new LazyCollection(function () {\n            yield from $this->connection->cursor(\n                $this->toSql(), $this->getBindings(), ! $this->useWritePdo, $this->fetchUsing\n            );\n        }))->map(function ($item) {\n            return $this->applyAfterQueryCallbacks(new Collection([$item]))->first();\n        })->reject(fn ($item) => is_null($item));\n    }\n\n    /**\n     * Throw an exception if the query doesn't have an orderBy clause.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function enforceOrderBy()\n    {\n        if (empty($this->orders) && empty($this->unionOrders)) {\n            throw new RuntimeException('You must specify an orderBy clause when using this function.');\n        }\n    }\n\n    /**\n     * Get a collection instance containing the values of a given column.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  string|null  $key\n     * @return \\Illuminate\\Support\\Collection<array-key, mixed>\n     */\n    public function pluck($column, $key = null)\n    {\n        $original = $this->columns;\n\n        // First, we will need to select the results of the query accounting for the\n        // given columns / key. Once we have the results, we will be able to take\n        // the results and get the exact data that was requested for the query.\n        $this->columns ??= is_null($key) || $key === $column\n            ? [$column]\n            : [$column, $key];\n\n        $queryResult = $this->processor->processSelect($this, $this->runSelect());\n\n        $this->columns = $original;\n\n        if (empty($queryResult)) {\n            return new Collection;\n        }\n\n        // If the columns are qualified with a table or have an alias, we cannot use\n        // those directly in the \"pluck\" operations since the results from the DB\n        // are only keyed by the column itself. We'll strip the table out here.\n        $column = $this->stripTableForPluck($column);\n\n        $key = $this->stripTableForPluck($key);\n\n        return $this->applyAfterQueryCallbacks(\n            is_array($queryResult[0])\n                ? $this->pluckFromArrayColumn($queryResult, $column, $key)\n                : $this->pluckFromObjectColumn($queryResult, $column, $key)\n        );\n    }\n\n    /**\n     * Strip off the table name or alias from a column identifier.\n     *\n     * @param  string  $column\n     * @return string|null\n     */\n    protected function stripTableForPluck($column)\n    {\n        if (is_null($column)) {\n            return $column;\n        }\n\n        $columnString = $column instanceof ExpressionContract\n            ? $this->grammar->getValue($column)\n            : $column;\n\n        $separator = str_contains(strtolower($columnString), ' as ') ? ' as ' : '\\.';\n\n        return last(preg_split('~'.$separator.'~i', $columnString));\n    }\n\n    /**\n     * Retrieve column values from rows represented as objects.\n     *\n     * @param  array  $queryResult\n     * @param  string  $column\n     * @param  string  $key\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function pluckFromObjectColumn($queryResult, $column, $key)\n    {\n        $results = [];\n\n        if (is_null($key)) {\n            foreach ($queryResult as $row) {\n                $results[] = $row->$column;\n            }\n        } else {\n            foreach ($queryResult as $row) {\n                $results[$row->$key] = $row->$column;\n            }\n        }\n\n        return new Collection($results);\n    }\n\n    /**\n     * Retrieve column values from rows represented as arrays.\n     *\n     * @param  array  $queryResult\n     * @param  string  $column\n     * @param  string  $key\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function pluckFromArrayColumn($queryResult, $column, $key)\n    {\n        $results = [];\n\n        if (is_null($key)) {\n            foreach ($queryResult as $row) {\n                $results[] = $row[$column];\n            }\n        } else {\n            foreach ($queryResult as $row) {\n                $results[$row[$key]] = $row[$column];\n            }\n        }\n\n        return new Collection($results);\n    }\n\n    /**\n     * Concatenate values of a given column as a string.\n     *\n     * @param  string  $column\n     * @param  string  $glue\n     * @return string\n     */\n    public function implode($column, $glue = '')\n    {\n        return $this->pluck($column)->implode($glue);\n    }\n\n    /**\n     * Determine if any rows exist for the current query.\n     *\n     * @return bool\n     */\n    public function exists()\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        $results = $this->connection->select(\n            $this->grammar->compileExists($this), $this->getBindings(), ! $this->useWritePdo\n        );\n\n        // If the results have rows, we will get the row and see if the exists column is a\n        // boolean true. If there are no results for this query we will return false as\n        // there are no rows for this query at all, and we can return that info here.\n        if (isset($results[0])) {\n            $results = (array) $results[0];\n\n            return (bool) $results['exists'];\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if no rows exist for the current query.\n     *\n     * @return bool\n     */\n    public function doesntExist()\n    {\n        return ! $this->exists();\n    }\n\n    /**\n     * Execute the given callback if no rows exist for the current query.\n     *\n     * @return mixed\n     */\n    public function existsOr(Closure $callback)\n    {\n        return $this->exists() ? true : $callback();\n    }\n\n    /**\n     * Execute the given callback if rows exist for the current query.\n     *\n     * @return mixed\n     */\n    public function doesntExistOr(Closure $callback)\n    {\n        return $this->doesntExist() ? true : $callback();\n    }\n\n    /**\n     * Retrieve the \"count\" result of the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $columns\n     * @return int<0, max>\n     */\n    public function count($columns = '*')\n    {\n        return (int) $this->aggregate(__FUNCTION__, Arr::wrap($columns));\n    }\n\n    /**\n     * Retrieve the minimum value of a given column.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return mixed\n     */\n    public function min($column)\n    {\n        return $this->aggregate(__FUNCTION__, [$column]);\n    }\n\n    /**\n     * Retrieve the maximum value of a given column.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return mixed\n     */\n    public function max($column)\n    {\n        return $this->aggregate(__FUNCTION__, [$column]);\n    }\n\n    /**\n     * Retrieve the sum of the values of a given column.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return mixed\n     */\n    public function sum($column)\n    {\n        $result = $this->aggregate(__FUNCTION__, [$column]);\n\n        return $result ?: 0;\n    }\n\n    /**\n     * Retrieve the average of the values of a given column.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return mixed\n     */\n    public function avg($column)\n    {\n        return $this->aggregate(__FUNCTION__, [$column]);\n    }\n\n    /**\n     * Alias for the \"avg\" method.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @return mixed\n     */\n    public function average($column)\n    {\n        return $this->avg($column);\n    }\n\n    /**\n     * Execute an aggregate function on the database.\n     *\n     * @param  string  $function\n     * @param  array  $columns\n     * @return mixed\n     */\n    public function aggregate($function, $columns = ['*'])\n    {\n        $results = $this->cloneWithout($this->unions || $this->havings ? [] : ['columns'])\n            ->cloneWithoutBindings($this->unions || $this->havings ? [] : ['select'])\n            ->setAggregate($function, $columns)\n            ->get($columns);\n\n        if (! $results->isEmpty()) {\n            return array_change_key_case((array) $results[0])['aggregate'];\n        }\n    }\n\n    /**\n     * Execute a numeric aggregate function on the database.\n     *\n     * @param  string  $function\n     * @param  array  $columns\n     * @return float|int\n     */\n    public function numericAggregate($function, $columns = ['*'])\n    {\n        $result = $this->aggregate($function, $columns);\n\n        // If there is no result, we can obviously just return 0 here. Next, we will check\n        // if the result is an integer or float. If it is already one of these two data\n        // types we can just return the result as-is, otherwise we will convert this.\n        if (! $result) {\n            return 0;\n        }\n\n        if (is_int($result) || is_float($result)) {\n            return $result;\n        }\n\n        // If the result doesn't contain a decimal place, we will assume it is an int then\n        // cast it to one. When it does we will cast it to a float since it needs to be\n        // cast to the expected data type for the developers out of pure convenience.\n        return ! str_contains((string) $result, '.')\n            ? (int) $result\n            : (float) $result;\n    }\n\n    /**\n     * Set the aggregate property without running the query.\n     *\n     * @param  string  $function\n     * @param  array<\\Illuminate\\Contracts\\Database\\Query\\Expression|string>  $columns\n     * @return $this\n     */\n    protected function setAggregate($function, $columns)\n    {\n        $this->aggregate = compact('function', 'columns');\n\n        if (empty($this->groups)) {\n            $this->orders = null;\n\n            $this->bindings['order'] = [];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Insert new records into the database.\n     *\n     * @return bool\n     */\n    public function insert(array $values)\n    {\n        // Since every insert gets treated like a batch insert, we will make sure the\n        // bindings are structured in a way that is convenient when building these\n        // inserts statements by verifying these elements are actually an array.\n        if (empty($values)) {\n            return true;\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        // Here, we will sort the insert keys for every record so that each insert is\n        // in the same order for the record. We need to make sure this is the case\n        // so there are not any errors or problems when inserting these records.\n        else {\n            foreach ($values as $key => $value) {\n                ksort($value);\n\n                $values[$key] = $value;\n            }\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        // Finally, we will run this query against the database connection and return\n        // the results. We will need to also flatten these bindings before running\n        // the query so they are all in one huge, flattened array for execution.\n        return $this->connection->insert(\n            $this->grammar->compileInsert($this, $values),\n            $this->cleanBindings(Arr::flatten($values, 1))\n        );\n    }\n\n    /**\n     * Insert new records into the database while ignoring errors.\n     *\n     * @return int<0, max>\n     */\n    public function insertOrIgnore(array $values)\n    {\n        if (empty($values)) {\n            return 0;\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        } else {\n            foreach ($values as $key => $value) {\n                ksort($value);\n\n                $values[$key] = $value;\n            }\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        return $this->connection->affectingStatement(\n            $this->grammar->compileInsertOrIgnore($this, $values),\n            $this->cleanBindings(Arr::flatten($values, 1))\n        );\n    }\n\n    /**\n     * Insert new records into the database and returning specified columns with optional ignoring specific conflicts.\n     *\n     * @param  non-empty-array<non-empty-string>  $returning\n     * @param  non-empty-string|non-empty-array<non-empty-string>|null  $uniqueBy\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function insertOrIgnoreReturning(array $values, array $returning = ['*'], array|string|null $uniqueBy = null)\n    {\n        if (empty($values)) {\n            return new Collection;\n        }\n\n        if ($uniqueBy === [] || $uniqueBy === '') {\n            throw new InvalidArgumentException('The unique columns must not be empty.');\n        }\n\n        if ($returning === []) {\n            throw new InvalidArgumentException('The returning columns must not be empty.');\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        } else {\n            foreach ($values as $key => $value) {\n                ksort($value);\n\n                $values[$key] = $value;\n            }\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        $sql = $this->grammar->compileInsertOrIgnoreReturning($this, $values, $returning, $uniqueBy === null ? null : Arr::wrap($uniqueBy));\n\n        $result = new Collection(\n            $this->connection->selectFromWriteConnection($sql, $this->cleanBindings(Arr::flatten($values, 1)))\n        );\n\n        $this->connection->recordsHaveBeenModified($result->isNotEmpty());\n\n        return $result;\n    }\n\n    /**\n     * Insert a new record and get the value of the primary key.\n     *\n     * @param  string|null  $sequence\n     * @return int\n     */\n    public function insertGetId(array $values, $sequence = null)\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        $sql = $this->grammar->compileInsertGetId($this, $values, $sequence);\n\n        $values = $this->cleanBindings($values);\n\n        return $this->processor->processInsertGetId($this, $sql, $values, $sequence);\n    }\n\n    /**\n     * Insert new records into the table using a subquery.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @return int\n     */\n    public function insertUsing(array $columns, $query)\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        [$sql, $bindings] = $this->createSub($query);\n\n        return $this->connection->affectingStatement(\n            $this->grammar->compileInsertUsing($this, $columns, $sql),\n            $this->cleanBindings($bindings)\n        );\n    }\n\n    /**\n     * Insert new records into the table using a subquery while ignoring errors.\n     *\n     * @param  \\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Database\\Eloquent\\Builder<*>|string  $query\n     * @return int\n     */\n    public function insertOrIgnoreUsing(array $columns, $query)\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        [$sql, $bindings] = $this->createSub($query);\n\n        return $this->connection->affectingStatement(\n            $this->grammar->compileInsertOrIgnoreUsing($this, $columns, $sql),\n            $this->cleanBindings($bindings)\n        );\n    }\n\n    /**\n     * Update records in the database.\n     *\n     * @return int<0, max>\n     */\n    public function update(array $values)\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        $values = (new Collection($values))->map(function ($value) {\n            if (! $value instanceof self && ! $value instanceof EloquentBuilder && ! $value instanceof Relation) {\n                return ['value' => $value, 'bindings' => match (true) {\n                    $value instanceof Collection => $value->all(),\n                    $value instanceof UnitEnum => enum_value($value),\n                    default => $value,\n                }];\n            }\n\n            [$query, $bindings] = $this->parseSub($value);\n\n            return ['value' => new Expression(\"({$query})\"), 'bindings' => fn () => $bindings];\n        });\n\n        $sql = $this->grammar->compileUpdate($this, $values->map(fn ($value) => $value['value'])->all());\n\n        return $this->connection->update($sql, $this->cleanBindings(\n            $this->grammar->prepareBindingsForUpdate($this->bindings, $values->map(fn ($value) => $value['bindings'])->all())\n        ));\n    }\n\n    /**\n     * Update records in a PostgreSQL database using the update from syntax.\n     *\n     * @return int\n     *\n     * @throws \\LogicException\n     */\n    public function updateFrom(array $values)\n    {\n        if (! method_exists($this->grammar, 'compileUpdateFrom')) {\n            throw new LogicException('This database engine does not support the updateFrom method.');\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        $sql = $this->grammar->compileUpdateFrom($this, $values);\n\n        return $this->connection->update($sql, $this->cleanBindings(\n            $this->grammar->prepareBindingsForUpdateFrom($this->bindings, $values)\n        ));\n    }\n\n    /**\n     * Insert or update a record matching the attributes, and fill it with values.\n     *\n     * @return bool\n     */\n    public function updateOrInsert(array $attributes, array|callable $values = [])\n    {\n        $exists = $this->where($attributes)->exists();\n\n        if ($values instanceof Closure) {\n            $values = $values($exists);\n        }\n\n        if (! $exists) {\n            return $this->insert(array_merge($attributes, $values));\n        }\n\n        if (empty($values)) {\n            return true;\n        }\n\n        return (bool) $this->limit(1)->update($values);\n    }\n\n    /**\n     * Insert new records or update the existing ones.\n     *\n     * @param  non-empty-string|non-empty-array<int, non-empty-string>  $uniqueBy\n     * @return int\n     */\n    public function upsert(array $values, array|string $uniqueBy, ?array $update = null)\n    {\n        if ($uniqueBy === [] || $uniqueBy === '') {\n            throw new InvalidArgumentException('The unique columns must not be empty.');\n        }\n\n        if (empty($values)) {\n            return 0;\n        } elseif ($update === []) {\n            return (int) $this->insert($values);\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        } else {\n            foreach ($values as $key => $value) {\n                ksort($value);\n\n                $values[$key] = $value;\n            }\n        }\n\n        if (is_null($update)) {\n            $update = array_keys(array_first($values));\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        $bindings = $this->cleanBindings(array_merge(\n            Arr::flatten($values, 1),\n            (new Collection($update))\n                ->reject(fn ($value, $key) => is_int($key))\n                ->all()\n        ));\n\n        return $this->connection->affectingStatement(\n            $this->grammar->compileUpsert($this, $values, (array) $uniqueBy, $update),\n            $bindings\n        );\n    }\n\n    /**\n     * Increment a column's value by a given amount.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @return int<0, max>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function increment($column, $amount = 1, array $extra = [])\n    {\n        if (! is_numeric($amount)) {\n            throw new InvalidArgumentException('Non-numeric value passed to increment method.');\n        }\n\n        return $this->incrementEach([$column => $amount], $extra);\n    }\n\n    /**\n     * Increment the given column's values by the given amounts.\n     *\n     * @param  array<string, float|int|numeric-string>  $columns\n     * @param  array<string, mixed>  $extra\n     * @return int<0, max>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function incrementEach(array $columns, array $extra = [])\n    {\n        foreach ($columns as $column => $amount) {\n            if (! is_numeric($amount)) {\n                throw new InvalidArgumentException(\"Non-numeric value passed as increment amount for column: '$column'.\");\n            } elseif (! is_string($column)) {\n                throw new InvalidArgumentException('Non-associative array passed to incrementEach method.');\n            }\n\n            $columns[$column] = $this->raw(\"{$this->grammar->wrap($column)} + $amount\");\n        }\n\n        return $this->update(array_merge($columns, $extra));\n    }\n\n    /**\n     * Decrement a column's value by a given amount.\n     *\n     * @param  string  $column\n     * @param  float|int  $amount\n     * @return int<0, max>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function decrement($column, $amount = 1, array $extra = [])\n    {\n        if (! is_numeric($amount)) {\n            throw new InvalidArgumentException('Non-numeric value passed to decrement method.');\n        }\n\n        return $this->decrementEach([$column => $amount], $extra);\n    }\n\n    /**\n     * Decrement the given column's values by the given amounts.\n     *\n     * @param  array<string, float|int|numeric-string>  $columns\n     * @param  array<string, mixed>  $extra\n     * @return int<0, max>\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function decrementEach(array $columns, array $extra = [])\n    {\n        foreach ($columns as $column => $amount) {\n            if (! is_numeric($amount)) {\n                throw new InvalidArgumentException(\"Non-numeric value passed as decrement amount for column: '$column'.\");\n            } elseif (! is_string($column)) {\n                throw new InvalidArgumentException('Non-associative array passed to decrementEach method.');\n            }\n\n            $columns[$column] = $this->raw(\"{$this->grammar->wrap($column)} - $amount\");\n        }\n\n        return $this->update(array_merge($columns, $extra));\n    }\n\n    /**\n     * Delete records from the database.\n     *\n     * @param  mixed  $id\n     * @return int\n     */\n    public function delete($id = null)\n    {\n        // If an ID is passed to the method, we will set the where clause to check the\n        // ID to let developers to simply and quickly remove a single row from this\n        // database without manually specifying the \"where\" clauses on the query.\n        if (! is_null($id)) {\n            $this->where($this->from.'.id', '=', $id);\n        }\n\n        $this->applyBeforeQueryCallbacks();\n\n        return $this->connection->delete(\n            $this->grammar->compileDelete($this), $this->cleanBindings(\n                $this->grammar->prepareBindingsForDelete($this->bindings)\n            )\n        );\n    }\n\n    /**\n     * Run a \"truncate\" statement on the table.\n     *\n     * @return void\n     */\n    public function truncate()\n    {\n        $this->applyBeforeQueryCallbacks();\n\n        foreach ($this->grammar->compileTruncate($this) as $sql => $bindings) {\n            $this->connection->statement($sql, $bindings);\n        }\n    }\n\n    /**\n     * Get a new instance of the query builder.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function newQuery()\n    {\n        return new static($this->connection, $this->grammar, $this->processor);\n    }\n\n    /**\n     * Create a new query instance for a sub-query.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function forSubQuery()\n    {\n        return $this->newQuery();\n    }\n\n    /**\n     * Get all of the query builder's columns in a text-only array with all expressions evaluated.\n     *\n     * @return list<string>\n     */\n    public function getColumns()\n    {\n        return ! is_null($this->columns)\n            ? array_map(fn ($column) => $this->grammar->getValue($column), $this->columns)\n            : [];\n    }\n\n    /**\n     * Create a raw database expression.\n     *\n     * @param  literal-string|int|float  $value\n     * @return \\Illuminate\\Contracts\\Database\\Query\\Expression\n     */\n    public function raw($value)\n    {\n        return $this->connection->raw($value);\n    }\n\n    /**\n     * Get the query builder instances that are used in the union of the query.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getUnionBuilders()\n    {\n        return isset($this->unions)\n            ? (new Collection($this->unions))->pluck('query')\n            : new Collection;\n    }\n\n    /**\n     * Get the \"limit\" value for the query or null if it's not set.\n     *\n     * @return mixed\n     */\n    public function getLimit()\n    {\n        $value = $this->unions ? $this->unionLimit : $this->limit;\n\n        return ! is_null($value) ? (int) $value : null;\n    }\n\n    /**\n     * Get the \"offset\" value for the query or null if it's not set.\n     *\n     * @return mixed\n     */\n    public function getOffset()\n    {\n        $value = $this->unions ? $this->unionOffset : $this->offset;\n\n        return ! is_null($value) ? (int) $value : null;\n    }\n\n    /**\n     * Get the current query value bindings in a flattened array.\n     *\n     * @return list<mixed>\n     */\n    public function getBindings()\n    {\n        return Arr::flatten($this->bindings);\n    }\n\n    /**\n     * Get the raw array of bindings.\n     *\n     * @return array{\n     *      select: list<mixed>,\n     *      from: list<mixed>,\n     *      join: list<mixed>,\n     *      where: list<mixed>,\n     *      groupBy: list<mixed>,\n     *      having: list<mixed>,\n     *      order: list<mixed>,\n     *      union: list<mixed>,\n     *      unionOrder: list<mixed>,\n     * }\n     */\n    public function getRawBindings()\n    {\n        return $this->bindings;\n    }\n\n    /**\n     * Set the bindings on the query builder.\n     *\n     * @param  list<mixed>  $bindings\n     * @param  \"select\"|\"from\"|\"join\"|\"where\"|\"groupBy\"|\"having\"|\"order\"|\"union\"|\"unionOrder\"  $type\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setBindings(array $bindings, $type = 'where')\n    {\n        if (! array_key_exists($type, $this->bindings)) {\n            throw new InvalidArgumentException(\"Invalid binding type: {$type}.\");\n        }\n\n        $this->bindings[$type] = $bindings;\n\n        return $this;\n    }\n\n    /**\n     * Add a binding to the query.\n     *\n     * @param  mixed  $value\n     * @param  \"select\"|\"from\"|\"join\"|\"where\"|\"groupBy\"|\"having\"|\"order\"|\"union\"|\"unionOrder\"  $type\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function addBinding($value, $type = 'where')\n    {\n        if (! array_key_exists($type, $this->bindings)) {\n            throw new InvalidArgumentException(\"Invalid binding type: {$type}.\");\n        }\n\n        if (is_array($value)) {\n            $this->bindings[$type] = array_values(array_map(\n                $this->castBinding(...),\n                array_merge($this->bindings[$type], $value),\n            ));\n        } else {\n            $this->bindings[$type][] = $this->castBinding($value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Cast the given binding value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function castBinding($value)\n    {\n        return enum_value($value);\n    }\n\n    /**\n     * Merge an array of bindings into our bindings.\n     *\n     * @param  self  $query\n     * @return $this\n     */\n    public function mergeBindings(self $query)\n    {\n        $this->bindings = array_merge_recursive($this->bindings, $query->bindings);\n\n        return $this;\n    }\n\n    /**\n     * Remove all of the expressions from a list of bindings.\n     *\n     * @param  array<mixed>  $bindings\n     * @return list<mixed>\n     */\n    public function cleanBindings(array $bindings)\n    {\n        return (new Collection($bindings))\n            ->reject(function ($binding) {\n                return $binding instanceof ExpressionContract;\n            })\n            ->map($this->castBinding(...))\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Get a scalar type value from an unknown type of input.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function flattenValue($value)\n    {\n        return is_array($value) ? head(Arr::flatten($value)) : $value;\n    }\n\n    /**\n     * Get the default key name of the table.\n     *\n     * @return string\n     */\n    protected function defaultKeyName()\n    {\n        return 'id';\n    }\n\n    /**\n     * Get the database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Ensure the database connection supports vector queries.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function ensureConnectionSupportsVectors()\n    {\n        if (! $this->connection instanceof PostgresConnection) {\n            throw new RuntimeException('Vector distance queries are only supported by Postgres.');\n        }\n    }\n\n    /**\n     * Get the database query processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    public function getProcessor()\n    {\n        return $this->processor;\n    }\n\n    /**\n     * Get the query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    public function getGrammar()\n    {\n        return $this->grammar;\n    }\n\n    /**\n     * Use the \"write\" PDO connection when executing the query.\n     *\n     * @return $this\n     */\n    public function useWritePdo()\n    {\n        $this->useWritePdo = true;\n\n        return $this;\n    }\n\n    /**\n     * Specify arguments for the PDOStatement::fetchAll / fetch functions.\n     *\n     * @param  mixed  ...$fetchUsing\n     * @return $this\n     */\n    public function fetchUsing(...$fetchUsing)\n    {\n        $this->fetchUsing = $fetchUsing;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the value is a query builder instance or a Closure.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function isQueryable($value)\n    {\n        return $value instanceof self ||\n               $value instanceof EloquentBuilder ||\n               $value instanceof Relation ||\n               $value instanceof Closure;\n    }\n\n    /**\n     * Clone the query.\n     *\n     * @return static\n     */\n    public function clone()\n    {\n        return clone $this;\n    }\n\n    /**\n     * Clone the query without the given properties.\n     *\n     * @return static\n     */\n    public function cloneWithout(array $properties)\n    {\n        return tap($this->clone(), function ($clone) use ($properties) {\n            foreach ($properties as $property) {\n                $clone->{$property} = null;\n            }\n        });\n    }\n\n    /**\n     * Clone the query without the given bindings.\n     *\n     * @return static\n     */\n    public function cloneWithoutBindings(array $except)\n    {\n        return tap($this->clone(), function ($clone) use ($except) {\n            foreach ($except as $type) {\n                $clone->bindings[$type] = [];\n            }\n        });\n    }\n\n    /**\n     * Dump the current SQL and bindings.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args)\n    {\n        dump(\n            $this->toSql(),\n            $this->getBindings(),\n            ...$args,\n        );\n\n        return $this;\n    }\n\n    /**\n     * Dump the raw current SQL with embedded bindings.\n     *\n     * @return $this\n     */\n    public function dumpRawSql()\n    {\n        dump($this->toRawSql());\n\n        return $this;\n    }\n\n    /**\n     * Die and dump the current SQL and bindings.\n     *\n     * @return never\n     */\n    public function dd()\n    {\n        dd($this->toSql(), $this->getBindings());\n    }\n\n    /**\n     * Die and dump the current SQL with embedded bindings.\n     *\n     * @return never\n     */\n    public function ddRawSql()\n    {\n        dd($this->toRawSql());\n    }\n\n    /**\n     * Handle dynamic method calls into the method.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (str_starts_with($method, 'where')) {\n            return $this->dynamicWhere($method, $parameters);\n        }\n\n        static::throwBadMethodCallException($method);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Expression.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression as ExpressionContract;\nuse Illuminate\\Database\\Grammar;\n\n/**\n * @template TValue of literal-string|int|float\n */\nclass Expression implements ExpressionContract\n{\n    /**\n     * Create a new raw query expression.\n     *\n     * @param  TValue  $value\n     */\n    public function __construct(\n        protected $value,\n    ) {\n    }\n\n    /**\n     * Get the value of the expression.\n     *\n     * @param  \\Illuminate\\Database\\Grammar  $grammar\n     * @return TValue\n     */\n    public function getValue(Grammar $grammar)\n    {\n        return $this->value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/Grammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Concerns\\CompilesJsonPaths;\nuse Illuminate\\Database\\Grammar as BaseGrammar;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\JoinClause;\nuse Illuminate\\Database\\Query\\JoinLateralClause;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse RuntimeException;\n\nclass Grammar extends BaseGrammar\n{\n    use CompilesJsonPaths;\n\n    /**\n     * The grammar specific operators.\n     *\n     * @var array\n     */\n    protected $operators = [];\n\n    /**\n     * The grammar specific bitwise operators.\n     *\n     * @var array\n     */\n    protected $bitwiseOperators = [];\n\n    /**\n     * The components that make up a select clause.\n     *\n     * @var string[]\n     */\n    protected $selectComponents = [\n        'aggregate',\n        'columns',\n        'from',\n        'indexHint',\n        'joins',\n        'wheres',\n        'groups',\n        'havings',\n        'orders',\n        'limit',\n        'offset',\n        'lock',\n    ];\n\n    /**\n     * Compile a select query into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileSelect(Builder $query)\n    {\n        if (($query->unions || $query->havings) && $query->aggregate) {\n            return $this->compileUnionAggregate($query);\n        }\n\n        // If a \"group limit\" is in place, we will need to compile the SQL to use a\n        // different syntax. This primarily supports limits on eager loads using\n        // Eloquent. We'll also set the columns if they have not been defined.\n        if (isset($query->groupLimit)) {\n            if (is_null($query->columns)) {\n                $query->columns = ['*'];\n            }\n\n            return $this->compileGroupLimit($query);\n        }\n\n        // If the query does not have any columns set, we'll set the columns to the\n        // * character to just get all of the columns from the database. Then we\n        // can build the query and concatenate all the pieces together as one.\n        $original = $query->columns;\n\n        if (is_null($query->columns)) {\n            $query->columns = ['*'];\n        }\n\n        // To compile the query, we'll spin through each component of the query and\n        // see if that component exists. If it does we'll just call the compiler\n        // function for the component which is responsible for making the SQL.\n        $sql = trim($this->concatenate(\n            $this->compileComponents($query))\n        );\n\n        if ($query->unions) {\n            $sql = $this->wrapUnion($sql).' '.$this->compileUnions($query);\n        }\n\n        $query->columns = $original;\n\n        return $sql;\n    }\n\n    /**\n     * Compile the components necessary for a select clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return array\n     */\n    protected function compileComponents(Builder $query)\n    {\n        $sql = [];\n\n        foreach ($this->selectComponents as $component) {\n            if (isset($query->$component)) {\n                $method = 'compile'.ucfirst($component);\n\n                $sql[$component] = $this->$method($query, $query->$component);\n            }\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile an aggregated select clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array{function: string, columns: array<\\Illuminate\\Contracts\\Database\\Query\\Expression|string>}  $aggregate\n     * @return string\n     */\n    protected function compileAggregate(Builder $query, $aggregate)\n    {\n        $column = $this->columnize($aggregate['columns']);\n\n        // If the query has a \"distinct\" constraint and we're not asking for all columns\n        // we need to prepend \"distinct\" onto the column name so that the query takes\n        // it into account when it performs the aggregating operations on the data.\n        if (is_array($query->distinct)) {\n            $column = 'distinct '.$this->columnize($query->distinct);\n        } elseif ($query->distinct && $column !== '*') {\n            $column = 'distinct '.$column;\n        }\n\n        return 'select '.$aggregate['function'].'('.$column.') as aggregate';\n    }\n\n    /**\n     * Compile the \"select *\" portion of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @return string|null\n     */\n    protected function compileColumns(Builder $query, $columns)\n    {\n        // If the query is actually performing an aggregating select, we will let that\n        // compiler handle the building of the select clauses, as it will need some\n        // more syntax that is best handled by that function to keep things neat.\n        if (! is_null($query->aggregate)) {\n            return;\n        }\n\n        if ($query->distinct) {\n            $select = 'select distinct ';\n        } else {\n            $select = 'select ';\n        }\n\n        return $select.$this->columnize($columns);\n    }\n\n    /**\n     * Compile the \"from\" portion of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @return string\n     */\n    protected function compileFrom(Builder $query, $table)\n    {\n        return 'from '.$this->wrapTable($table);\n    }\n\n    /**\n     * Compile the \"join\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $joins\n     * @return string\n     */\n    protected function compileJoins(Builder $query, $joins)\n    {\n        return (new Collection($joins))->map(function ($join) use ($query) {\n            $table = $this->wrapTable($join->table);\n\n            $nestedJoins = is_null($join->joins) ? '' : ' '.$this->compileJoins($query, $join->joins);\n\n            $tableAndNestedJoins = is_null($join->joins) ? $table : '('.$table.$nestedJoins.')';\n\n            if ($join instanceof JoinLateralClause) {\n                return $this->compileJoinLateral($join, $tableAndNestedJoins);\n            }\n\n            $joinWord = ($join->type === 'straight_join' && $this->supportsStraightJoins()) ? '' : ' join';\n\n            return trim(\"{$join->type}{$joinWord} {$tableAndNestedJoins} {$this->compileWheres($join)}\");\n        })->implode(' ');\n    }\n\n    /**\n     * Compile a \"lateral join\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinLateralClause  $join\n     * @param  string  $expression\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileJoinLateral(JoinLateralClause $join, string $expression): string\n    {\n        throw new RuntimeException('This database engine does not support lateral joins.');\n    }\n\n    /**\n     * Determine if the grammar supports straight joins.\n     *\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    protected function supportsStraightJoins()\n    {\n        throw new RuntimeException('This database engine does not support straight joins.');\n    }\n\n    /**\n     * Compile the \"where\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileWheres(Builder $query)\n    {\n        // Each type of where clause has its own compiler function, which is responsible\n        // for actually creating the where clauses SQL. This helps keep the code nice\n        // and maintainable since each clause has a very small method that it uses.\n        if (is_null($query->wheres)) {\n            return '';\n        }\n\n        // If we actually have some where clauses, we will strip off the first boolean\n        // operator, which is added by the query builders for convenience so we can\n        // avoid checking for the first clauses in each of the compilers methods.\n        if (count($sql = $this->compileWheresToArray($query)) > 0) {\n            return $this->concatenateWhereClauses($query, $sql);\n        }\n\n        return '';\n    }\n\n    /**\n     * Get an array of all the where clauses for the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return array\n     */\n    protected function compileWheresToArray($query)\n    {\n        return (new Collection($query->wheres))\n            ->map(fn ($where) => $where['boolean'].' '.$this->{\"where{$where['type']}\"}($query, $where))\n            ->all();\n    }\n\n    /**\n     * Format the where clause statements into one string.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $sql\n     * @return string\n     */\n    protected function concatenateWhereClauses($query, $sql)\n    {\n        $conjunction = $query instanceof JoinClause ? 'on' : 'where';\n\n        return $conjunction.' '.$this->removeLeadingBoolean(implode(' ', $sql));\n    }\n\n    /**\n     * Compile a raw where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereRaw(Builder $query, $where)\n    {\n        return $where['sql'] instanceof Expression ? $where['sql']->getValue($this) : $where['sql'];\n    }\n\n    /**\n     * Compile a basic where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBasic(Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        $operator = str_replace('?', '??', $where['operator']);\n\n        return $this->wrap($where['column']).' '.$operator.' '.$value;\n    }\n\n    /**\n     * Compile a bitwise operator where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBitwise(Builder $query, $where)\n    {\n        return $this->whereBasic($query, $where);\n    }\n\n    /**\n     * Compile a \"where like\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function whereLike(Builder $query, $where)\n    {\n        if ($where['caseSensitive']) {\n            throw new RuntimeException('This database engine does not support case sensitive like operations.');\n        }\n\n        $where['operator'] = $where['not'] ? 'not like' : 'like';\n\n        return $this->whereBasic($query, $where);\n    }\n\n    /**\n     * Compile a \"where null safe equals\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNullSafeEquals(Builder $query, $where)\n    {\n        return $this->wrap($where['column']).' is not distinct from '.$this->parameter($where['value']);\n    }\n\n    /**\n     * Compile a \"where in\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereIn(Builder $query, $where)\n    {\n        if (! empty($where['values'])) {\n            return $this->wrap($where['column']).' in ('.$this->parameterize($where['values']).')';\n        }\n\n        return '0 = 1';\n    }\n\n    /**\n     * Compile a \"where not in\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNotIn(Builder $query, $where)\n    {\n        if (! empty($where['values'])) {\n            return $this->wrap($where['column']).' not in ('.$this->parameterize($where['values']).')';\n        }\n\n        return '1 = 1';\n    }\n\n    /**\n     * Compile a \"where not in raw\" clause.\n     *\n     * For safety, whereIntegerInRaw ensures this method is only used with integer values.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNotInRaw(Builder $query, $where)\n    {\n        if (! empty($where['values'])) {\n            return $this->wrap($where['column']).' not in ('.implode(', ', $where['values']).')';\n        }\n\n        return '1 = 1';\n    }\n\n    /**\n     * Compile a \"where in raw\" clause.\n     *\n     * For safety, whereIntegerInRaw ensures this method is only used with integer values.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereInRaw(Builder $query, $where)\n    {\n        if (! empty($where['values'])) {\n            return $this->wrap($where['column']).' in ('.implode(', ', $where['values']).')';\n        }\n\n        return '0 = 1';\n    }\n\n    /**\n     * Compile a \"where null\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNull(Builder $query, $where)\n    {\n        return $this->wrap($where['column']).' is null';\n    }\n\n    /**\n     * Compile a \"where not null\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNotNull(Builder $query, $where)\n    {\n        return $this->wrap($where['column']).' is not null';\n    }\n\n    /**\n     * Compile a \"between\" where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBetween(Builder $query, $where)\n    {\n        $between = $where['not'] ? 'not between' : 'between';\n\n        $min = $this->parameter(is_array($where['values']) ? array_first($where['values']) : $where['values'][0]);\n\n        $max = $this->parameter(is_array($where['values']) ? array_last($where['values']) : $where['values'][1]);\n\n        return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max;\n    }\n\n    /**\n     * Compile a \"between\" where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBetweenColumns(Builder $query, $where)\n    {\n        $between = $where['not'] ? 'not between' : 'between';\n\n        $min = $this->wrap(is_array($where['values']) ? array_first($where['values']) : $where['values'][0]);\n\n        $max = $this->wrap(is_array($where['values']) ? array_last($where['values']) : $where['values'][1]);\n\n        return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max;\n    }\n\n    /**\n     * Compile a \"value between\" where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereValueBetween(Builder $query, $where)\n    {\n        $between = $where['not'] ? 'not between' : 'between';\n\n        $min = $this->wrap(is_array($where['columns']) ? array_first($where['columns']) : $where['columns'][0]);\n\n        $max = $this->wrap(is_array($where['columns']) ? array_last($where['columns']) : $where['columns'][1]);\n\n        return $this->parameter($where['value']).' '.$between.' '.$min.' and '.$max;\n    }\n\n    /**\n     * Compile a \"where date\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDate(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('date', $query, $where);\n    }\n\n    /**\n     * Compile a \"where time\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereTime(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('time', $query, $where);\n    }\n\n    /**\n     * Compile a \"where day\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDay(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('day', $query, $where);\n    }\n\n    /**\n     * Compile a \"where month\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereMonth(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('month', $query, $where);\n    }\n\n    /**\n     * Compile a \"where year\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereYear(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('year', $query, $where);\n    }\n\n    /**\n     * Compile a date based where clause.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function dateBasedWhere($type, Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        return $type.'('.$this->wrap($where['column']).') '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a where clause comparing two columns.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereColumn(Builder $query, $where)\n    {\n        return $this->wrap($where['first']).' '.$where['operator'].' '.$this->wrap($where['second']);\n    }\n\n    /**\n     * Compile a nested where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNested(Builder $query, $where)\n    {\n        // Here we will calculate what portion of the string we need to remove. If this\n        // is a join clause query, we need to remove the \"on\" portion of the SQL and\n        // if it is a normal query we need to take the leading \"where\" of queries.\n        $offset = $where['query'] instanceof JoinClause ? 3 : 6;\n\n        return '('.substr($this->compileWheres($where['query']), $offset).')';\n    }\n\n    /**\n     * Compile a where condition with a sub-select.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereSub(Builder $query, $where)\n    {\n        $select = $this->compileSelect($where['query']);\n\n        return $this->wrap($where['column']).' '.$where['operator'].\" ($select)\";\n    }\n\n    /**\n     * Compile a where exists clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereExists(Builder $query, $where)\n    {\n        return 'exists ('.$this->compileSelect($where['query']).')';\n    }\n\n    /**\n     * Compile a where exists clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNotExists(Builder $query, $where)\n    {\n        return 'not exists ('.$this->compileSelect($where['query']).')';\n    }\n\n    /**\n     * Compile a where row values condition.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereRowValues(Builder $query, $where)\n    {\n        $columns = $this->columnize($where['columns']);\n\n        $values = $this->parameterize($where['values']);\n\n        return '('.$columns.') '.$where['operator'].' ('.$values.')';\n    }\n\n    /**\n     * Compile a \"where JSON boolean\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereJsonBoolean(Builder $query, $where)\n    {\n        $column = $this->wrapJsonBooleanSelector($where['column']);\n\n        $value = $this->wrapJsonBooleanValue(\n            $this->parameter($where['value'])\n        );\n\n        return $column.' '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a \"where JSON contains\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereJsonContains(Builder $query, $where)\n    {\n        $not = $where['not'] ? 'not ' : '';\n\n        return $not.$this->compileJsonContains(\n            $where['column'],\n            $this->parameter($where['value'])\n        );\n    }\n\n    /**\n     * Compile a \"JSON contains\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function compileJsonContains($column, $value)\n    {\n        throw new RuntimeException('This database engine does not support JSON contains operations.');\n    }\n\n    /**\n     * Compile a \"where JSON overlaps\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereJsonOverlaps(Builder $query, $where)\n    {\n        $not = $where['not'] ? 'not ' : '';\n\n        return $not.$this->compileJsonOverlaps(\n            $where['column'],\n            $this->parameter($where['value'])\n        );\n    }\n\n    /**\n     * Compile a \"JSON overlaps\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function compileJsonOverlaps($column, $value)\n    {\n        throw new RuntimeException('This database engine does not support JSON overlaps operations.');\n    }\n\n    /**\n     * Prepare the binding for a \"JSON contains\" statement.\n     *\n     * @param  mixed  $binding\n     * @return string\n     */\n    public function prepareBindingForJsonContains($binding)\n    {\n        return json_encode($binding, JSON_UNESCAPED_UNICODE);\n    }\n\n    /**\n     * Compile a \"where JSON contains key\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereJsonContainsKey(Builder $query, $where)\n    {\n        $not = $where['not'] ? 'not ' : '';\n\n        return $not.$this->compileJsonContainsKey(\n            $where['column']\n        );\n    }\n\n    /**\n     * Compile a \"JSON contains key\" statement into SQL.\n     *\n     * @param  string  $column\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function compileJsonContainsKey($column)\n    {\n        throw new RuntimeException('This database engine does not support JSON contains key operations.');\n    }\n\n    /**\n     * Compile a \"where JSON length\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereJsonLength(Builder $query, $where)\n    {\n        return $this->compileJsonLength(\n            $where['column'],\n            $where['operator'],\n            $this->parameter($where['value'])\n        );\n    }\n\n    /**\n     * Compile a \"JSON length\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $operator\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function compileJsonLength($column, $operator, $value)\n    {\n        throw new RuntimeException('This database engine does not support JSON length operations.');\n    }\n\n    /**\n     * Compile a \"JSON value cast\" statement into SQL.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileJsonValueCast($value)\n    {\n        return $value;\n    }\n\n    /**\n     * Compile a \"where fulltext\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function whereFullText(Builder $query, $where)\n    {\n        throw new RuntimeException('This database engine does not support fulltext search operations.');\n    }\n\n    /**\n     * Compile a clause based on an expression.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    public function whereExpression(Builder $query, $where)\n    {\n        return $where['column']->getValue($this);\n    }\n\n    /**\n     * Compile the \"group by\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $groups\n     * @return string\n     */\n    protected function compileGroups(Builder $query, $groups)\n    {\n        return 'group by '.$this->columnize($groups);\n    }\n\n    /**\n     * Compile the \"having\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileHavings(Builder $query)\n    {\n        return 'having '.$this->removeLeadingBoolean((new Collection($query->havings))->map(function ($having) {\n            return $having['boolean'].' '.$this->compileHaving($having);\n        })->implode(' '));\n    }\n\n    /**\n     * Compile a single having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHaving(array $having)\n    {\n        // If the having clause is \"raw\", we can just return the clause straight away\n        // without doing any more processing on it. Otherwise, we will compile the\n        // clause into SQL based on the components that make it up from builder.\n        return match ($having['type']) {\n            'Raw' => $having['sql'],\n            'between' => $this->compileHavingBetween($having),\n            'Null' => $this->compileHavingNull($having),\n            'NotNull' => $this->compileHavingNotNull($having),\n            'bit' => $this->compileHavingBit($having),\n            'Expression' => $this->compileHavingExpression($having),\n            'Nested' => $this->compileNestedHavings($having),\n            default => $this->compileBasicHaving($having),\n        };\n    }\n\n    /**\n     * Compile a basic having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileBasicHaving($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        $parameter = $this->parameter($having['value']);\n\n        return $column.' '.$having['operator'].' '.$parameter;\n    }\n\n    /**\n     * Compile a \"between\" having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingBetween($having)\n    {\n        $between = $having['not'] ? 'not between' : 'between';\n\n        $column = $this->wrap($having['column']);\n\n        $min = $this->parameter(head($having['values']));\n\n        $max = $this->parameter(last($having['values']));\n\n        return $column.' '.$between.' '.$min.' and '.$max;\n    }\n\n    /**\n     * Compile a having null clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingNull($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        return $column.' is null';\n    }\n\n    /**\n     * Compile a having not null clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingNotNull($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        return $column.' is not null';\n    }\n\n    /**\n     * Compile a having clause involving a bit operator.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingBit($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        $parameter = $this->parameter($having['value']);\n\n        return '('.$column.' '.$having['operator'].' '.$parameter.') != 0';\n    }\n\n    /**\n     * Compile a having clause involving an expression.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingExpression($having)\n    {\n        return $having['column']->getValue($this);\n    }\n\n    /**\n     * Compile a nested having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileNestedHavings($having)\n    {\n        return '('.substr($this->compileHavings($having['query']), 7).')';\n    }\n\n    /**\n     * Compile the \"order by\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $orders\n     * @return string\n     */\n    protected function compileOrders(Builder $query, $orders)\n    {\n        if (! empty($orders)) {\n            return 'order by '.implode(', ', $this->compileOrdersToArray($query, $orders));\n        }\n\n        return '';\n    }\n\n    /**\n     * Compile the query orders to an array.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $orders\n     * @return array\n     */\n    protected function compileOrdersToArray(Builder $query, $orders)\n    {\n        return array_map(function ($order) use ($query) {\n            if (isset($order['sql']) && $order['sql'] instanceof Expression) {\n                return $order['sql']->getValue($query->getGrammar());\n            }\n\n            if (isset($order['type']) && $order['type'] === 'InOrderOf') {\n                return $this->compileInOrderOf($order);\n            }\n\n            return $order['sql'] ?? $this->wrap($order['column']).' '.$order['direction'];\n        }, $orders);\n    }\n\n    /**\n     * Compile an \"in order of\" clause.\n     *\n     * @param  array  $order\n     * @return string\n     */\n    protected function compileInOrderOf($order)\n    {\n        $column = $this->wrap($order['column']);\n\n        $cases = [];\n\n        foreach (array_values($order['values']) as $index => $value) {\n            $cases[] = 'when '.$column.' = '.$this->parameter($value).' then '.$index;\n        }\n\n        return 'case '.implode(' ', $cases).' else '.count($order['values']).' end';\n    }\n\n    /**\n     * Compile the random statement into SQL.\n     *\n     * @param  string|int  $seed\n     * @return string\n     */\n    public function compileRandom($seed)\n    {\n        return 'RANDOM()';\n    }\n\n    /**\n     * Compile the \"limit\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  int  $limit\n     * @return string\n     */\n    protected function compileLimit(Builder $query, $limit)\n    {\n        return 'limit '.(int) $limit;\n    }\n\n    /**\n     * Compile a group limit clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileGroupLimit(Builder $query)\n    {\n        $selectBindings = array_merge($query->getRawBindings()['select'], $query->getRawBindings()['order']);\n\n        $query->setBindings($selectBindings, 'select');\n        $query->setBindings([], 'order');\n\n        $limit = (int) $query->groupLimit['value'];\n        $offset = $query->offset;\n\n        if (isset($offset)) {\n            $offset = (int) $offset;\n            $limit += $offset;\n\n            $query->offset = null;\n        }\n\n        $components = $this->compileComponents($query);\n\n        $components['columns'] .= $this->compileRowNumber(\n            $query->groupLimit['column'],\n            $components['orders'] ?? ''\n        );\n\n        unset($components['orders']);\n\n        $table = $this->wrap('laravel_table');\n        $row = $this->wrap('laravel_row');\n\n        $sql = $this->concatenate($components);\n\n        $sql = 'select * from ('.$sql.') as '.$table.' where '.$row.' <= '.$limit;\n\n        if (isset($offset)) {\n            $sql .= ' and '.$row.' > '.$offset;\n        }\n\n        return $sql.' order by '.$row;\n    }\n\n    /**\n     * Compile a row number clause.\n     *\n     * @param  string  $partition\n     * @param  string  $orders\n     * @return string\n     */\n    protected function compileRowNumber($partition, $orders)\n    {\n        $over = trim('partition by '.$this->wrap($partition).' '.$orders);\n\n        return ', row_number() over ('.$over.') as '.$this->wrap('laravel_row');\n    }\n\n    /**\n     * Compile the \"offset\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  int  $offset\n     * @return string\n     */\n    protected function compileOffset(Builder $query, $offset)\n    {\n        return 'offset '.(int) $offset;\n    }\n\n    /**\n     * Compile the \"union\" queries attached to the main query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileUnions(Builder $query)\n    {\n        $sql = '';\n\n        foreach ($query->unions as $union) {\n            $sql .= $this->compileUnion($union);\n        }\n\n        if (! empty($query->unionOrders)) {\n            $sql .= ' '.$this->compileOrders($query, $query->unionOrders);\n        }\n\n        if (isset($query->unionLimit)) {\n            $sql .= ' '.$this->compileLimit($query, $query->unionLimit);\n        }\n\n        if (isset($query->unionOffset)) {\n            $sql .= ' '.$this->compileOffset($query, $query->unionOffset);\n        }\n\n        return ltrim($sql);\n    }\n\n    /**\n     * Compile a single union statement.\n     *\n     * @param  array  $union\n     * @return string\n     */\n    protected function compileUnion(array $union)\n    {\n        $conjunction = $union['all'] ? ' union all ' : ' union ';\n\n        return $conjunction.$this->wrapUnion($union['query']->toSql());\n    }\n\n    /**\n     * Wrap a union subquery in parentheses.\n     *\n     * @param  string  $sql\n     * @return string\n     */\n    protected function wrapUnion($sql)\n    {\n        return '('.$sql.')';\n    }\n\n    /**\n     * Compile a union aggregate query into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileUnionAggregate(Builder $query)\n    {\n        $sql = $this->compileAggregate($query, $query->aggregate);\n\n        $query->aggregate = null;\n\n        return $sql.' from ('.$this->compileSelect($query).') as '.$this->wrapTable('temp_table');\n    }\n\n    /**\n     * Compile an exists statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileExists(Builder $query)\n    {\n        $select = $this->compileSelect($query);\n\n        return \"select exists({$select}) as {$this->wrap('exists')}\";\n    }\n\n    /**\n     * Compile an insert statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileInsert(Builder $query, array $values)\n    {\n        // Essentially we will force every insert to be treated as a batch insert which\n        // simply makes creating the SQL easier for us since we can utilize the same\n        // basic routine regardless of an amount of records given to us to insert.\n        $table = $this->wrapTable($query->from);\n\n        if (empty($values)) {\n            return \"insert into {$table} default values\";\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        }\n\n        $columns = $this->columnize(array_keys(array_first($values)));\n\n        // We need to build a list of parameter place-holders of values that are bound\n        // to the query. Each insert should have the exact same number of parameter\n        // bindings so we will loop through the record and parameterize them all.\n        $parameters = (new Collection($values))\n            ->map(fn ($record) => '('.$this->parameterize($record).')')\n            ->implode(', ');\n\n        return \"insert into $table ($columns) values $parameters\";\n    }\n\n    /**\n     * Compile an insert ignore statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileInsertOrIgnore(Builder $query, array $values)\n    {\n        throw new RuntimeException('This database engine does not support inserting while ignoring errors.');\n    }\n\n    /**\n     * Compile an insert or ignore statement with a returning clause into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $returning\n     * @param  array|null  $uniqueBy\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileInsertOrIgnoreReturning(Builder $query, array $values, array $returning, ?array $uniqueBy)\n    {\n        throw new RuntimeException('This database engine does not support insert or ignore with returning.');\n    }\n\n    /**\n     * Compile an insert and get ID statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return string\n     */\n    public function compileInsertGetId(Builder $query, $values, $sequence)\n    {\n        return $this->compileInsert($query, $values);\n    }\n\n    /**\n     * Compile an insert statement using a subquery into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @param  string  $sql\n     * @return string\n     */\n    public function compileInsertUsing(Builder $query, array $columns, string $sql)\n    {\n        $table = $this->wrapTable($query->from);\n\n        if (empty($columns) || $columns === ['*']) {\n            return \"insert into {$table} $sql\";\n        }\n\n        return \"insert into {$table} ({$this->columnize($columns)}) $sql\";\n    }\n\n    /**\n     * Compile an insert ignore statement using a subquery into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @param  string  $sql\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql)\n    {\n        throw new RuntimeException('This database engine does not support inserting while ignoring errors.');\n    }\n\n    /**\n     * Compile an update statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileUpdate(Builder $query, array $values)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $columns = $this->compileUpdateColumns($query, $values);\n\n        $where = $this->compileWheres($query);\n\n        return trim(\n            isset($query->joins)\n                ? $this->compileUpdateWithJoins($query, $table, $columns, $where)\n                : $this->compileUpdateWithoutJoins($query, $table, $columns, $where)\n        );\n    }\n\n    /**\n     * Compile the columns for an update statement.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateColumns(Builder $query, array $values)\n    {\n        return (new Collection($values))\n            ->map(fn ($value, $key) => $this->wrap($key).' = '.$this->parameter($value))\n            ->implode(', ');\n    }\n\n    /**\n     * Compile an update statement without joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $columns\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileUpdateWithoutJoins(Builder $query, $table, $columns, $where)\n    {\n        return \"update {$table} set {$columns} {$where}\";\n    }\n\n    /**\n     * Compile an update statement with joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $columns\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileUpdateWithJoins(Builder $query, $table, $columns, $where)\n    {\n        $joins = $this->compileJoins($query, $query->joins);\n\n        return \"update {$table} {$joins} set {$columns} {$where}\";\n    }\n\n    /**\n     * Compile an \"upsert\" statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $uniqueBy\n     * @param  array  $update\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)\n    {\n        throw new RuntimeException('This database engine does not support upserts.');\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    public function prepareBindingsForUpdate(array $bindings, array $values)\n    {\n        $cleanBindings = Arr::except($bindings, ['select', 'join']);\n\n        $values = Arr::flatten(array_map(fn ($value) => value($value), $values));\n\n        return array_values(\n            array_merge($bindings['join'], $values, Arr::flatten($cleanBindings))\n        );\n    }\n\n    /**\n     * Compile a delete statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileDelete(Builder $query)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $where = $this->compileWheres($query);\n\n        return trim(\n            isset($query->joins)\n                ? $this->compileDeleteWithJoins($query, $table, $where)\n                : $this->compileDeleteWithoutJoins($query, $table, $where)\n        );\n    }\n\n    /**\n     * Compile a delete statement without joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)\n    {\n        return \"delete from {$table} {$where}\";\n    }\n\n    /**\n     * Compile a delete statement with joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileDeleteWithJoins(Builder $query, $table, $where)\n    {\n        $alias = last(explode(' as ', $table));\n\n        $joins = $this->compileJoins($query, $query->joins);\n\n        return \"delete {$alias} from {$table} {$joins} {$where}\";\n    }\n\n    /**\n     * Prepare the bindings for a delete statement.\n     *\n     * @param  array  $bindings\n     * @return array\n     */\n    public function prepareBindingsForDelete(array $bindings)\n    {\n        return Arr::flatten(\n            Arr::except($bindings, 'select')\n        );\n    }\n\n    /**\n     * Compile a truncate table statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return array\n     */\n    public function compileTruncate(Builder $query)\n    {\n        return ['truncate table '.$this->wrapTable($query->from) => []];\n    }\n\n    /**\n     * Compile the lock into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  bool|string  $value\n     * @return string\n     */\n    protected function compileLock(Builder $query, $value)\n    {\n        return is_string($value) ? $value : '';\n    }\n\n    /**\n     * Compile a query to get the number of open connections for a database.\n     *\n     * @return string|null\n     */\n    public function compileThreadCount()\n    {\n        return null;\n    }\n\n    /**\n     * Determine if the grammar supports savepoints.\n     *\n     * @return bool\n     */\n    public function supportsSavepoints()\n    {\n        return true;\n    }\n\n    /**\n     * Compile the SQL statement to define a savepoint.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileSavepoint($name)\n    {\n        return 'SAVEPOINT '.$name;\n    }\n\n    /**\n     * Compile the SQL statement to execute a savepoint rollback.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileSavepointRollBack($name)\n    {\n        return 'ROLLBACK TO SAVEPOINT '.$name;\n    }\n\n    /**\n     * Wrap the given JSON selector for boolean values.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanSelector($value)\n    {\n        return $this->wrapJsonSelector($value);\n    }\n\n    /**\n     * Wrap the given JSON boolean value.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanValue($value)\n    {\n        return $value;\n    }\n\n    /**\n     * Concatenate an array of segments, removing empties.\n     *\n     * @param  array  $segments\n     * @return string\n     */\n    protected function concatenate($segments)\n    {\n        return implode(' ', array_filter($segments, function ($value) {\n            return (string) $value !== '';\n        }));\n    }\n\n    /**\n     * Remove the leading boolean from a statement.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function removeLeadingBoolean($value)\n    {\n        return preg_replace('/and |or /i', '', $value, 1);\n    }\n\n    /**\n     * Substitute the given bindings into the given raw SQL query.\n     *\n     * @param  string  $sql\n     * @param  array  $bindings\n     * @return string\n     */\n    public function substituteBindingsIntoRawSql($sql, $bindings)\n    {\n        $bindings = array_map(fn ($value) => $this->escape($value, is_resource($value) || gettype($value) === 'resource (closed)'), $bindings);\n\n        $query = '';\n        $bindingIndex = 0;\n\n        $isStringLiteral = false;\n\n        for ($i = 0; $i < strlen($sql); $i++) {\n            $char = $sql[$i];\n            $nextChar = $sql[$i + 1] ?? null;\n\n            // Single quotes can be escaped as '' according to the SQL standard while\n            // MySQL uses \\'. Postgres has operators like ?| that must get encoded\n            // in PHP like ??|. We should skip over the escaped characters here.\n            if (in_array($char.$nextChar, [\"\\'\", \"''\", '??'])) {\n                $query .= $char.$nextChar;\n                $i += 1;\n            } elseif ($char === \"'\") { // Starting / leaving string literal...\n                $query .= $char;\n                $isStringLiteral = ! $isStringLiteral;\n            } elseif ($char === '?' && ! $isStringLiteral) { // Substitutable binding...\n                $query .= $bindings[$bindingIndex++] ?? '?';\n            } else { // Normal character...\n                $query .= $char;\n            }\n        }\n\n        return $query;\n    }\n\n    /**\n     * Get the grammar specific operators.\n     *\n     * @return array\n     */\n    public function getOperators()\n    {\n        return $this->operators;\n    }\n\n    /**\n     * Get the grammar specific bitwise operators.\n     *\n     * @return array\n     */\n    public function getBitwiseOperators()\n    {\n        return $this->bitwiseOperators;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/MariaDbGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\JoinLateralClause;\nuse RuntimeException;\n\nclass MariaDbGrammar extends MySqlGrammar\n{\n    /**\n     * Compile a \"lateral join\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinLateralClause  $join\n     * @param  string  $expression\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileJoinLateral(JoinLateralClause $join, string $expression): string\n    {\n        throw new RuntimeException('This database engine does not support lateral joins.');\n    }\n\n    /**\n     * Compile a \"JSON value cast\" statement into SQL.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileJsonValueCast($value)\n    {\n        return \"json_query({$value}, '$')\";\n    }\n\n    /**\n     * Compile a query to get the number of open connections for a database.\n     *\n     * @return string\n     */\n    public function compileThreadCount()\n    {\n        return 'select variable_value as `Value` from information_schema.global_status where variable_name = \\'THREADS_CONNECTED\\'';\n    }\n\n    /**\n     * Determine whether to use a legacy group limit clause for MySQL < 8.0.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return bool\n     */\n    public function useLegacyGroupLimit(Builder $query)\n    {\n        return false;\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_value('.$field.$path.')';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/MySqlGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\JoinLateralClause;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass MySqlGrammar extends Grammar\n{\n    /**\n     * The grammar specific operators.\n     *\n     * @var string[]\n     */\n    protected $operators = ['sounds like'];\n\n    /**\n     * Compile a select query into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileSelect(Builder $query)\n    {\n        $sql = parent::compileSelect($query);\n\n        if ($query->timeout === null) {\n            return $sql;\n        }\n\n        $milliseconds = $query->timeout * 1000;\n\n        return preg_replace(\n            '/^select\\b/i',\n            'select /*+ MAX_EXECUTION_TIME('.$milliseconds.') */',\n            $sql,\n            1\n        );\n    }\n\n    /**\n     * Compile a \"where like\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereLike(Builder $query, $where)\n    {\n        $where['operator'] = $where['not'] ? 'not ' : '';\n\n        $where['operator'] .= $where['caseSensitive'] ? 'like binary' : 'like';\n\n        return $this->whereBasic($query, $where);\n    }\n\n    /**\n     * Compile a \"where null safe equals\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNullSafeEquals(Builder $query, $where)\n    {\n        return $this->wrap($where['column']).' <=> '.$this->parameter($where['value']);\n    }\n\n    /**\n     * Add a \"where null\" clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNull(Builder $query, $where)\n    {\n        $columnValue = (string) $this->getValue($where['column']);\n\n        if ($this->isJsonSelector($columnValue)) {\n            [$field, $path] = $this->wrapJsonFieldAndPath($columnValue);\n\n            return '(json_extract('.$field.$path.') is null OR json_type(json_extract('.$field.$path.')) = \\'NULL\\')';\n        }\n\n        return parent::whereNull($query, $where);\n    }\n\n    /**\n     * Add a \"where not null\" clause to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNotNull(Builder $query, $where)\n    {\n        $columnValue = (string) $this->getValue($where['column']);\n\n        if ($this->isJsonSelector($columnValue)) {\n            [$field, $path] = $this->wrapJsonFieldAndPath($columnValue);\n\n            return '(json_extract('.$field.$path.') is not null AND json_type(json_extract('.$field.$path.')) != \\'NULL\\')';\n        }\n\n        return parent::whereNotNull($query, $where);\n    }\n\n    /**\n     * Compile a \"where fulltext\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    public function whereFullText(Builder $query, $where)\n    {\n        $columns = $this->columnize($where['columns']);\n\n        $value = $this->parameter($where['value']);\n\n        $mode = ($where['options']['mode'] ?? []) === 'boolean'\n            ? ' in boolean mode'\n            : ' in natural language mode';\n\n        $expanded = ($where['options']['expanded'] ?? []) && ($where['options']['mode'] ?? []) !== 'boolean'\n            ? ' with query expansion'\n            : '';\n\n        return \"match ({$columns}) against (\".$value.\"{$mode}{$expanded})\";\n    }\n\n    /**\n     * Compile the index hints for the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  \\Illuminate\\Database\\Query\\IndexHint  $indexHint\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileIndexHint(Builder $query, $indexHint)\n    {\n        $index = $indexHint->index;\n\n        $indexes = array_map('trim', explode(',', $index));\n\n        foreach ($indexes as $i) {\n            if (! preg_match('/^[a-zA-Z0-9_$]+$/', $i)) {\n                throw new InvalidArgumentException('Index name contains invalid characters.');\n            }\n        }\n\n        return match ($indexHint->type) {\n            'hint' => \"use index ({$index})\",\n            'force' => \"force index ({$index})\",\n            default => \"ignore index ({$index})\",\n        };\n    }\n\n    /**\n     * Compile a group limit clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileGroupLimit(Builder $query)\n    {\n        return $this->useLegacyGroupLimit($query)\n            ? $this->compileLegacyGroupLimit($query)\n            : parent::compileGroupLimit($query);\n    }\n\n    /**\n     * Determine whether to use a legacy group limit clause for MySQL < 8.0.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return bool\n     */\n    public function useLegacyGroupLimit(Builder $query)\n    {\n        $version = $query->getConnection()->getServerVersion();\n\n        return ! $query->getConnection()->isMaria() && version_compare($version, '8.0.11', '<');\n    }\n\n    /**\n     * Compile a group limit clause for MySQL < 8.0.\n     *\n     * Derived from https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileLegacyGroupLimit(Builder $query)\n    {\n        $limit = (int) $query->groupLimit['value'];\n        $offset = $query->offset;\n\n        if (isset($offset)) {\n            $offset = (int) $offset;\n            $limit += $offset;\n\n            $query->offset = null;\n        }\n\n        $column = last(explode('.', $query->groupLimit['column']));\n        $column = $this->wrap($column);\n\n        $partition = ', @laravel_row := if(@laravel_group = '.$column.', @laravel_row + 1, 1) as `laravel_row`';\n        $partition .= ', @laravel_group := '.$column;\n\n        $orders = (array) $query->orders;\n\n        array_unshift($orders, [\n            'column' => $query->groupLimit['column'],\n            'direction' => 'asc',\n        ]);\n\n        $query->orders = $orders;\n\n        $components = $this->compileComponents($query);\n\n        $sql = $this->concatenate($components);\n\n        $from = '(select @laravel_row := 0, @laravel_group := 0) as `laravel_vars`, ('.$sql.') as `laravel_table`';\n\n        $sql = 'select `laravel_table`.*'.$partition.' from '.$from.' having `laravel_row` <= '.$limit;\n\n        if (isset($offset)) {\n            $sql .= ' and `laravel_row` > '.$offset;\n        }\n\n        return $sql.' order by `laravel_row`';\n    }\n\n    /**\n     * Compile an insert ignore statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileInsertOrIgnore(Builder $query, array $values)\n    {\n        return Str::replaceFirst('insert', 'insert ignore', $this->compileInsert($query, $values));\n    }\n\n    /**\n     * Compile an insert ignore statement using a subquery into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @param  string  $sql\n     * @return string\n     */\n    public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql)\n    {\n        return Str::replaceFirst('insert', 'insert ignore', $this->compileInsertUsing($query, $columns, $sql));\n    }\n\n    /**\n     * Compile a \"JSON contains\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonContains($column, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'json_contains('.$field.', '.$value.$path.')';\n    }\n\n    /**\n     * Compile a \"JSON overlaps\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonOverlaps($column, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'json_overlaps('.$field.', '.$value.$path.')';\n    }\n\n    /**\n     * Compile a \"JSON contains key\" statement into SQL.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileJsonContainsKey($column)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'ifnull(json_contains_path('.$field.', \\'one\\''.$path.'), 0)';\n    }\n\n    /**\n     * Compile a \"JSON length\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $operator\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonLength($column, $operator, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'json_length('.$field.$path.') '.$operator.' '.$value;\n    }\n\n    /**\n     * Compile a \"JSON value cast\" statement into SQL.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileJsonValueCast($value)\n    {\n        return 'cast('.$value.' as json)';\n    }\n\n    /**\n     * Compile the random statement into SQL.\n     *\n     * @param  string|int  $seed\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function compileRandom($seed)\n    {\n        if ($seed === '' || $seed === null) {\n            return 'RAND()';\n        }\n\n        if (! is_numeric($seed)) {\n            throw new InvalidArgumentException('The seed value must be numeric.');\n        }\n\n        return 'RAND('.(int) $seed.')';\n    }\n\n    /**\n     * Compile the lock into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  bool|string  $value\n     * @return string\n     */\n    protected function compileLock(Builder $query, $value)\n    {\n        if (! is_string($value)) {\n            return $value ? 'for update' : 'lock in share mode';\n        }\n\n        return $value;\n    }\n\n    /**\n     * Compile an insert statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileInsert(Builder $query, array $values)\n    {\n        if (empty($values)) {\n            $values = [[]];\n        }\n\n        return parent::compileInsert($query, $values);\n    }\n\n    /**\n     * Compile the columns for an update statement.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateColumns(Builder $query, array $values)\n    {\n        return (new Collection($values))->map(function ($value, $key) {\n            if ($this->isJsonSelector($key)) {\n                return $this->compileJsonUpdateColumn($key, $value);\n            }\n\n            return $this->wrap($key).' = '.$this->parameter($value);\n        })->implode(', ');\n    }\n\n    /**\n     * Compile an \"upsert\" statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $uniqueBy\n     * @param  array  $update\n     * @return string\n     */\n    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)\n    {\n        $useUpsertAlias = $query->connection->getConfig('use_upsert_alias');\n\n        $sql = $this->compileInsert($query, $values);\n\n        if ($useUpsertAlias) {\n            $sql .= ' as laravel_upsert_alias';\n        }\n\n        $sql .= ' on duplicate key update ';\n\n        $columns = (new Collection($update))->map(function ($value, $key) use ($useUpsertAlias) {\n            if (! is_numeric($key)) {\n                return $this->wrap($key).' = '.$this->parameter($value);\n            }\n\n            return $useUpsertAlias\n                ? $this->wrap($value).' = '.$this->wrap('laravel_upsert_alias').'.'.$this->wrap($value)\n                : $this->wrap($value).' = values('.$this->wrap($value).')';\n        })->implode(', ');\n\n        return $sql.$columns;\n    }\n\n    /**\n     * Compile a \"lateral join\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinLateralClause  $join\n     * @param  string  $expression\n     * @return string\n     */\n    public function compileJoinLateral(JoinLateralClause $join, string $expression): string\n    {\n        return trim(\"{$join->type} join lateral {$expression} on true\");\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function supportsStraightJoins()\n    {\n        return true;\n    }\n\n    /**\n     * Prepare a JSON column being updated using the JSON_SET function.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function compileJsonUpdateColumn($key, $value)\n    {\n        if (is_bool($value)) {\n            $value = $value ? 'true' : 'false';\n        } elseif (is_array($value)) {\n            $value = 'cast(? as json)';\n        } else {\n            $value = $this->parameter($value);\n        }\n\n        [$field, $path] = $this->wrapJsonFieldAndPath($key);\n\n        return \"{$field} = json_set({$field}{$path}, {$value})\";\n    }\n\n    /**\n     * Compile an update statement without joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $columns\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileUpdateWithoutJoins(Builder $query, $table, $columns, $where)\n    {\n        $sql = parent::compileUpdateWithoutJoins($query, $table, $columns, $where);\n\n        if (! empty($query->orders)) {\n            $sql .= ' '.$this->compileOrders($query, $query->orders);\n        }\n\n        if (isset($query->limit)) {\n            $sql .= ' '.$this->compileLimit($query, $query->limit);\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * Booleans, integers, and doubles are inserted into JSON updates as raw values.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    #[\\Override]\n    public function prepareBindingsForUpdate(array $bindings, array $values)\n    {\n        $values = (new Collection($values))\n            ->reject(fn ($value, $column) => $this->isJsonSelector($column) && is_bool($value))\n            ->map(fn ($value) => is_array($value) ? json_encode($value) : $value)\n            ->all();\n\n        return parent::prepareBindingsForUpdate($bindings, $values);\n    }\n\n    /**\n     * Compile a delete statement without joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)\n    {\n        $sql = parent::compileDeleteWithoutJoins($query, $table, $where);\n\n        if (! empty($query->orders)) {\n            $sql .= ' '.$this->compileOrders($query, $query->orders);\n        }\n\n        if (isset($query->limit)) {\n            $sql .= ' '.$this->compileLimit($query, $query->limit);\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a delete statement with joins into SQL.\n     *\n     * Adds ORDER BY and LIMIT if present, for platforms that allow them (e.g., PlanetScale).\n     *\n     * Standard MySQL does not support ORDER BY or LIMIT with joined deletes and will throw a syntax error.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileDeleteWithJoins(Builder $query, $table, $where)\n    {\n        $sql = parent::compileDeleteWithJoins($query, $table, $where);\n\n        if (! empty($query->orders)) {\n            $sql .= ' '.$this->compileOrders($query, $query->orders);\n        }\n\n        if (isset($query->limit)) {\n            $sql .= ' '.$this->compileLimit($query, $query->limit);\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a query to get the number of open connections for a database.\n     *\n     * @return string\n     */\n    public function compileThreadCount()\n    {\n        return 'select variable_value as `Value` from performance_schema.session_status where variable_name = \\'threads_connected\\'';\n    }\n\n    /**\n     * Wrap a single string in keyword identifiers.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapValue($value)\n    {\n        return $value === '*' ? $value : '`'.str_replace('`', '``', $value).'`';\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_unquote(json_extract('.$field.$path.'))';\n    }\n\n    /**\n     * Wrap the given JSON selector for boolean values.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_extract('.$field.$path.')';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/PostgresGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\JoinLateralClause;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\n\nclass PostgresGrammar extends Grammar\n{\n    /**\n     * All of the available clause operators.\n     *\n     * @var string[]\n     */\n    protected $operators = [\n        '=', '<', '>', '<=', '>=', '<>', '!=',\n        'like', 'not like', 'between', 'ilike', 'not ilike',\n        '~', '&', '|', '#', '<<', '>>', '<<=', '>>=',\n        '&&', '@>', '<@', '?', '?|', '?&', '||', '-', '@?', '@@', '#-',\n        'is distinct from', 'is not distinct from',\n    ];\n\n    /**\n     * The Postgres grammar specific custom operators.\n     *\n     * @var array\n     */\n    protected static $customOperators = [];\n\n    /**\n     * The grammar specific bitwise operators.\n     *\n     * @var array\n     */\n    protected $bitwiseOperators = [\n        '~', '&', '|', '#', '<<', '>>', '<<=', '>>=',\n    ];\n\n    /**\n     * Indicates if the cascade option should be used when truncating.\n     *\n     * @var bool\n     */\n    protected static $cascadeTruncate = true;\n\n    /**\n     * Compile a basic where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBasic(Builder $query, $where)\n    {\n        if (str_contains(strtolower($where['operator']), 'like')) {\n            return sprintf(\n                '%s::text %s %s',\n                $this->wrap($where['column']),\n                $where['operator'],\n                $this->parameter($where['value'])\n            );\n        }\n\n        return parent::whereBasic($query, $where);\n    }\n\n    /**\n     * Compile a bitwise operator where clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBitwise(Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        $operator = str_replace('?', '??', $where['operator']);\n\n        return '('.$this->wrap($where['column']).' '.$operator.' '.$value.')::bool';\n    }\n\n    /**\n     * Compile a \"where like\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereLike(Builder $query, $where)\n    {\n        $where['operator'] = $where['not'] ? 'not ' : '';\n\n        $where['operator'] .= $where['caseSensitive'] ? 'like' : 'ilike';\n\n        return $this->whereBasic($query, $where);\n    }\n\n    /**\n     * Compile a \"where date\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDate(Builder $query, $where)\n    {\n        $column = $this->wrap($where['column']);\n        $value = $this->parameter($where['value']);\n\n        if ($this->isJsonSelector($where['column'])) {\n            $column = '('.$column.')';\n        }\n\n        return $column.'::date '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a \"where time\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereTime(Builder $query, $where)\n    {\n        $column = $this->wrap($where['column']);\n        $value = $this->parameter($where['value']);\n\n        if ($this->isJsonSelector($where['column'])) {\n            $column = '('.$column.')';\n        }\n\n        return $column.'::time '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a date based where clause.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function dateBasedWhere($type, Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        return 'extract('.$type.' from '.$this->wrap($where['column']).') '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a \"where fulltext\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    public function whereFullText(Builder $query, $where)\n    {\n        $language = $where['options']['language'] ?? 'english';\n\n        if (! in_array($language, $this->validFullTextLanguages())) {\n            $language = 'english';\n        }\n\n        $isVector = $where['options']['vector'] ?? false;\n\n        $columns = (new Collection($where['columns']))\n            ->map(fn ($column) => $isVector\n                ? $this->wrap($column)\n                : \"to_tsvector('{$language}', {$this->wrap($column)})\")\n            ->implode(' || ');\n\n        $mode = 'plainto_tsquery';\n\n        if (($where['options']['mode'] ?? []) === 'phrase') {\n            $mode = 'phraseto_tsquery';\n        }\n\n        if (($where['options']['mode'] ?? []) === 'websearch') {\n            $mode = 'websearch_to_tsquery';\n        }\n\n        if (($where['options']['mode'] ?? []) === 'raw') {\n            $mode = 'to_tsquery';\n        }\n\n        return \"({$columns}) @@ {$mode}('{$language}', {$this->parameter($where['value'])})\";\n    }\n\n    /**\n     * Get an array of valid full text languages.\n     *\n     * @return array\n     */\n    protected function validFullTextLanguages()\n    {\n        return [\n            'simple',\n            'arabic',\n            'danish',\n            'dutch',\n            'english',\n            'finnish',\n            'french',\n            'german',\n            'hungarian',\n            'indonesian',\n            'irish',\n            'italian',\n            'lithuanian',\n            'nepali',\n            'norwegian',\n            'portuguese',\n            'romanian',\n            'russian',\n            'spanish',\n            'swedish',\n            'tamil',\n            'turkish',\n        ];\n    }\n\n    /**\n     * Compile the \"select *\" portion of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @return string|null\n     */\n    protected function compileColumns(Builder $query, $columns)\n    {\n        // If the query is actually performing an aggregating select, we will let that\n        // compiler handle the building of the select clauses, as it will need some\n        // more syntax that is best handled by that function to keep things neat.\n        if (! is_null($query->aggregate)) {\n            return;\n        }\n\n        if (is_array($query->distinct)) {\n            $select = 'select distinct on ('.$this->columnize($query->distinct).') ';\n        } elseif ($query->distinct) {\n            $select = 'select distinct ';\n        } else {\n            $select = 'select ';\n        }\n\n        return $select.$this->columnize($columns);\n    }\n\n    /**\n     * Compile a \"JSON contains\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonContains($column, $value)\n    {\n        $column = str_replace('->>', '->', $this->wrap($column));\n\n        return '('.$column.')::jsonb @> '.$value;\n    }\n\n    /**\n     * Compile a \"JSON contains key\" statement into SQL.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileJsonContainsKey($column)\n    {\n        $segments = explode('->', $column);\n\n        $lastSegment = array_pop($segments);\n\n        if (filter_var($lastSegment, FILTER_VALIDATE_INT) !== false) {\n            $i = $lastSegment;\n        } elseif (preg_match('/\\[(-?[0-9]+)\\]$/', $lastSegment, $matches)) {\n            $segments[] = Str::beforeLast($lastSegment, $matches[0]);\n\n            $i = $matches[1];\n        }\n\n        $column = str_replace('->>', '->', $this->wrap(implode('->', $segments)));\n\n        if (isset($i)) {\n            return vsprintf('case when %s then %s else false end', [\n                'jsonb_typeof(('.$column.\")::jsonb) = 'array'\",\n                'jsonb_array_length(('.$column.')::jsonb) >= '.($i < 0 ? abs($i) : $i + 1),\n            ]);\n        }\n\n        $key = \"'\".str_replace(\"'\", \"''\", $lastSegment).\"'\";\n\n        return 'coalesce(('.$column.')::jsonb ?? '.$key.', false)';\n    }\n\n    /**\n     * Compile a \"JSON length\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $operator\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonLength($column, $operator, $value)\n    {\n        $column = str_replace('->>', '->', $this->wrap($column));\n\n        return 'jsonb_array_length(('.$column.')::jsonb) '.$operator.' '.$value;\n    }\n\n    /**\n     * Compile a single having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHaving(array $having)\n    {\n        if ($having['type'] === 'Bitwise') {\n            return $this->compileHavingBitwise($having);\n        }\n\n        return parent::compileHaving($having);\n    }\n\n    /**\n     * Compile a having clause involving a bitwise operator.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingBitwise($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        $parameter = $this->parameter($having['value']);\n\n        return '('.$column.' '.$having['operator'].' '.$parameter.')::bool';\n    }\n\n    /**\n     * Compile the lock into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  bool|string  $value\n     * @return string\n     */\n    protected function compileLock(Builder $query, $value)\n    {\n        if (! is_string($value)) {\n            return $value ? 'for update' : 'for share';\n        }\n\n        return $value;\n    }\n\n    /**\n     * Compile an insert ignore statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileInsertOrIgnore(Builder $query, array $values)\n    {\n        return $this->compileInsert($query, $values).' on conflict do nothing';\n    }\n\n    /**\n     * Compile an insert or ignore statement with a returning clause into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $returning\n     * @param  array|null  $uniqueBy\n     * @return string\n     */\n    public function compileInsertOrIgnoreReturning(Builder $query, array $values, array $returning, ?array $uniqueBy)\n    {\n        $insert = $this->compileInsert($query, $values);\n\n        return match ($uniqueBy) {\n            null => \"{$insert} on conflict do nothing returning {$this->columnize($returning)}\",\n            default => \"{$insert} on conflict ({$this->columnize($uniqueBy)}) do nothing returning {$this->columnize($returning)}\",\n        };\n    }\n\n    /**\n     * Compile an insert ignore statement using a subquery into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @param  string  $sql\n     * @return string\n     */\n    public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql)\n    {\n        return $this->compileInsertUsing($query, $columns, $sql).' on conflict do nothing';\n    }\n\n    /**\n     * Compile an insert and get ID statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return string\n     */\n    public function compileInsertGetId(Builder $query, $values, $sequence)\n    {\n        return $this->compileInsert($query, $values).' returning '.$this->wrap($sequence ?: 'id');\n    }\n\n    /**\n     * Compile an update statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileUpdate(Builder $query, array $values)\n    {\n        if (isset($query->joins) || isset($query->limit)) {\n            return $this->compileUpdateWithJoinsOrLimit($query, $values);\n        }\n\n        return parent::compileUpdate($query, $values);\n    }\n\n    /**\n     * Compile the columns for an update statement.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateColumns(Builder $query, array $values)\n    {\n        return (new Collection($values))->map(function ($value, $key) {\n            $column = last(explode('.', $key));\n\n            if ($this->isJsonSelector($key)) {\n                return $this->compileJsonUpdateColumn($column, $value);\n            }\n\n            return $this->wrap($column).' = '.$this->parameter($value);\n        })->implode(', ');\n    }\n\n    /**\n     * Compile an \"upsert\" statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $uniqueBy\n     * @param  array  $update\n     * @return string\n     */\n    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)\n    {\n        $sql = $this->compileInsert($query, $values);\n\n        $sql .= ' on conflict ('.$this->columnize($uniqueBy).') do update set ';\n\n        $columns = (new Collection($update))->map(function ($value, $key) {\n            return is_numeric($key)\n                ? $this->wrap($value).' = '.$this->wrapValue('excluded').'.'.$this->wrap($value)\n                : $this->wrap($key).' = '.$this->parameter($value);\n        })->implode(', ');\n\n        return $sql.$columns;\n    }\n\n    /**\n     * Compile a \"lateral join\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinLateralClause  $join\n     * @param  string  $expression\n     * @return string\n     */\n    public function compileJoinLateral(JoinLateralClause $join, string $expression): string\n    {\n        return trim(\"{$join->type} join lateral {$expression} on true\");\n    }\n\n    /**\n     * Prepares a JSON column being updated using the JSONB_SET function.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function compileJsonUpdateColumn($key, $value)\n    {\n        $segments = explode('->', $key);\n\n        $field = $this->wrap(array_shift($segments));\n\n        $path = \"'{\".implode(',', $this->wrapJsonPathAttributes($segments, '\"')).\"}'\";\n\n        return \"{$field} = jsonb_set({$field}::jsonb, {$path}, {$this->parameter($value)})\";\n    }\n\n    /**\n     * Compile an update from statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileUpdateFrom(Builder $query, $values)\n    {\n        $table = $this->wrapTable($query->from);\n\n        // Each one of the columns in the update statements needs to be wrapped in the\n        // keyword identifiers, also a place-holder needs to be created for each of\n        // the values in the list of bindings so we can make the sets statements.\n        $columns = $this->compileUpdateColumns($query, $values);\n\n        $from = '';\n\n        if (isset($query->joins)) {\n            // When using Postgres, updates with joins list the joined tables in the from\n            // clause, which is different than other systems like MySQL. Here, we will\n            // compile out the tables that are joined and add them to a from clause.\n            $froms = (new Collection($query->joins))\n                ->map(fn ($join) => $this->wrapTable($join->table))\n                ->all();\n\n            if (count($froms) > 0) {\n                $from = ' from '.implode(', ', $froms);\n            }\n        }\n\n        $where = $this->compileUpdateWheres($query);\n\n        return trim(\"update {$table} set {$columns}{$from} {$where}\");\n    }\n\n    /**\n     * Compile the additional where clauses for updates with joins.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileUpdateWheres(Builder $query)\n    {\n        $baseWheres = $this->compileWheres($query);\n\n        if (! isset($query->joins)) {\n            return $baseWheres;\n        }\n\n        // Once we compile the join constraints, we will either use them as the where\n        // clause or append them to the existing base where clauses. If we need to\n        // strip the leading boolean we will do so when using as the only where.\n        $joinWheres = $this->compileUpdateJoinWheres($query);\n\n        if (trim($baseWheres) == '') {\n            return 'where '.$this->removeLeadingBoolean($joinWheres);\n        }\n\n        return $baseWheres.' '.$joinWheres;\n    }\n\n    /**\n     * Compile the \"join\" clause where clauses for an update.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileUpdateJoinWheres(Builder $query)\n    {\n        $joinWheres = [];\n\n        // Here we will just loop through all of the join constraints and compile them\n        // all out then implode them. This should give us \"where\" like syntax after\n        // everything has been built and then we will join it to the real wheres.\n        foreach ($query->joins as $join) {\n            foreach ($join->wheres as $where) {\n                $method = \"where{$where['type']}\";\n\n                $joinWheres[] = $where['boolean'].' '.$this->$method($query, $where);\n            }\n        }\n\n        return implode(' ', $joinWheres);\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    public function prepareBindingsForUpdateFrom(array $bindings, array $values)\n    {\n        $values = (new Collection($values))\n            ->map(function ($value, $column) {\n                return is_array($value) || ($this->isJsonSelector($column) && ! $this->isExpression($value))\n                    ? json_encode($value)\n                    : $value;\n            })\n            ->all();\n\n        $bindingsWithoutWhere = Arr::except($bindings, ['select', 'where']);\n\n        return array_values(\n            array_merge($values, $bindings['where'], Arr::flatten($bindingsWithoutWhere))\n        );\n    }\n\n    /**\n     * Compile an update statement with joins or limit into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $columns = $this->compileUpdateColumns($query, $values);\n\n        $alias = last(preg_split('/\\s+as\\s+/i', $query->from));\n\n        $selectSql = $this->compileSelect($query->select($alias.'.ctid'));\n\n        return \"update {$table} set {$columns} where {$this->wrap('ctid')} in ({$selectSql})\";\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    #[\\Override]\n    public function prepareBindingsForUpdate(array $bindings, array $values)\n    {\n        $values = (new Collection($values))->map(function ($value, $column) {\n            return is_array($value) || ($this->isJsonSelector($column) && ! $this->isExpression($value))\n                ? json_encode($value)\n                : $value;\n        })->all();\n\n        $cleanBindings = Arr::except($bindings, 'select');\n\n        $values = Arr::flatten(array_map(fn ($value) => value($value), $values));\n\n        return array_values(\n            array_merge($values, Arr::flatten($cleanBindings))\n        );\n    }\n\n    /**\n     * Compile a delete statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileDelete(Builder $query)\n    {\n        if (isset($query->joins) || isset($query->limit)) {\n            return $this->compileDeleteWithJoinsOrLimit($query);\n        }\n\n        return parent::compileDelete($query);\n    }\n\n    /**\n     * Compile a delete statement with joins or limit into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileDeleteWithJoinsOrLimit(Builder $query)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $alias = last(preg_split('/\\s+as\\s+/i', $query->from));\n\n        $selectSql = $this->compileSelect($query->select($alias.'.ctid'));\n\n        return \"delete from {$table} where {$this->wrap('ctid')} in ({$selectSql})\";\n    }\n\n    /**\n     * Compile a truncate table statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return array\n     */\n    public function compileTruncate(Builder $query)\n    {\n        return ['truncate '.$this->wrapTable($query->from).' restart identity'.(static::$cascadeTruncate ? ' cascade' : '') => []];\n    }\n\n    /**\n     * Compile a query to get the number of open connections for a database.\n     *\n     * @return string\n     */\n    public function compileThreadCount()\n    {\n        return 'select count(*) as \"Value\" from pg_stat_activity';\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        $path = explode('->', $value);\n\n        $field = $this->wrapSegments(explode('.', array_shift($path)));\n\n        $wrappedPath = $this->wrapJsonPathAttributes($path);\n\n        $attribute = array_pop($wrappedPath);\n\n        if (! empty($wrappedPath)) {\n            return $field.'->'.implode('->', $wrappedPath).'->>'.$attribute;\n        }\n\n        return $field.'->>'.$attribute;\n    }\n\n    /**\n     * Wrap the given JSON selector for boolean values.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanSelector($value)\n    {\n        $selector = str_replace(\n            '->>', '->',\n            $this->wrapJsonSelector($value)\n        );\n\n        return '('.$selector.')::jsonb';\n    }\n\n    /**\n     * Wrap the given JSON boolean value.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanValue($value)\n    {\n        return \"'\".$value.\"'::jsonb\";\n    }\n\n    /**\n     * Wrap the attributes of the given JSON path.\n     *\n     * @param  array  $path\n     * @return array\n     */\n    protected function wrapJsonPathAttributes($path)\n    {\n        $quote = func_num_args() === 2 ? func_get_arg(1) : \"'\";\n\n        return (new Collection($path))\n            ->map(fn ($attribute) => $this->parseJsonPathArrayKeys($attribute))\n            ->collapse()\n            ->map(function ($attribute) use ($quote) {\n                return filter_var($attribute, FILTER_VALIDATE_INT) !== false\n                    ? $attribute\n                    : $quote.$attribute.$quote;\n            })\n            ->all();\n    }\n\n    /**\n     * Parse the given JSON path attribute for array keys.\n     *\n     * @param  string  $attribute\n     * @return array\n     */\n    protected function parseJsonPathArrayKeys($attribute)\n    {\n        if (preg_match('/(\\[[^\\]]+\\])+$/', $attribute, $parts)) {\n            $key = Str::beforeLast($attribute, $parts[0]);\n\n            preg_match_all('/\\[([^\\]]+)\\]/', $parts[0], $keys);\n\n            return (new Collection([$key]))\n                ->merge($keys[1])\n                ->diff('')\n                ->values()\n                ->all();\n        }\n\n        return [$attribute];\n    }\n\n    /**\n     * Substitute the given bindings into the given raw SQL query.\n     *\n     * @param  string  $sql\n     * @param  array  $bindings\n     * @return string\n     */\n    public function substituteBindingsIntoRawSql($sql, $bindings)\n    {\n        $query = parent::substituteBindingsIntoRawSql($sql, $bindings);\n\n        foreach ($this->operators as $operator) {\n            if (! str_contains($operator, '?')) {\n                continue;\n            }\n\n            $query = str_replace(str_replace('?', '??', $operator), $operator, $query);\n        }\n\n        return $query;\n    }\n\n    /**\n     * Get the Postgres grammar specific operators.\n     *\n     * @return array\n     */\n    public function getOperators()\n    {\n        return array_values(array_unique(array_merge(parent::getOperators(), static::$customOperators)));\n    }\n\n    /**\n     * Set any Postgres grammar specific custom operators.\n     *\n     * @param  array  $operators\n     * @return void\n     */\n    public static function customOperators(array $operators)\n    {\n        static::$customOperators = array_values(\n            array_merge(static::$customOperators, array_filter(array_filter($operators, 'is_string')))\n        );\n    }\n\n    /**\n     * Enable or disable the \"cascade\" option when compiling the truncate statement.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public static function cascadeOnTruncate(bool $value = true)\n    {\n        static::$cascadeTruncate = $value;\n    }\n\n    /**\n     * @deprecated use cascadeOnTruncate\n     */\n    public static function cascadeOnTrucate(bool $value = true)\n    {\n        self::cascadeOnTruncate($value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass SQLiteGrammar extends Grammar\n{\n    /**\n     * All of the available clause operators.\n     *\n     * @var string[]\n     */\n    protected $operators = [\n        '=', '<', '>', '<=', '>=', '<>', '!=',\n        'like', 'not like', 'ilike',\n        '&', '|', '<<', '>>',\n    ];\n\n    /**\n     * Compile the lock into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  bool|string  $value\n     * @return string\n     */\n    protected function compileLock(Builder $query, $value)\n    {\n        return '';\n    }\n\n    /**\n     * Wrap a union subquery in parentheses.\n     *\n     * @param  string  $sql\n     * @return string\n     */\n    protected function wrapUnion($sql)\n    {\n        return 'select * from ('.$sql.')';\n    }\n\n    /**\n     * Compile a \"where like\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereLike(Builder $query, $where)\n    {\n        if ($where['caseSensitive'] == false) {\n            return parent::whereLike($query, $where);\n        }\n        $where['operator'] = $where['not'] ? 'not glob' : 'glob';\n\n        return $this->whereBasic($query, $where);\n    }\n\n    /**\n     * Convert a LIKE pattern to a GLOB pattern using simple string replacement.\n     *\n     * @param  string  $value\n     * @param  bool  $caseSensitive\n     * @return string\n     */\n    public function prepareWhereLikeBinding($value, $caseSensitive)\n    {\n        return $caseSensitive === false ? $value : str_replace(\n            ['*', '?', '%', '_'],\n            ['[*]', '[?]', '*', '?'],\n            $value\n        );\n    }\n\n    /**\n     * Compile a \"where null safe equals\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNullSafeEquals(Builder $query, $where)\n    {\n        return $this->wrap($where['column']).' is '.$this->parameter($where['value']);\n    }\n\n    /**\n     * Compile a \"where date\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDate(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('%Y-%m-%d', $query, $where);\n    }\n\n    /**\n     * Compile a \"where day\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDay(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('%d', $query, $where);\n    }\n\n    /**\n     * Compile a \"where month\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereMonth(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('%m', $query, $where);\n    }\n\n    /**\n     * Compile a \"where year\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereYear(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('%Y', $query, $where);\n    }\n\n    /**\n     * Compile a \"where time\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereTime(Builder $query, $where)\n    {\n        return $this->dateBasedWhere('%H:%M:%S', $query, $where);\n    }\n\n    /**\n     * Compile a date based where clause.\n     *\n     * @param  string  $type\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function dateBasedWhere($type, Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        return \"strftime('{$type}', {$this->wrap($where['column'])}) {$where['operator']} cast({$value} as text)\";\n    }\n\n    /**\n     * Compile the index hints for the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  \\Illuminate\\Database\\Query\\IndexHint  $indexHint\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileIndexHint(Builder $query, $indexHint)\n    {\n        if ($indexHint->type !== 'force') {\n            return '';\n        }\n\n        $index = $indexHint->index;\n\n        if (! preg_match('/^[a-zA-Z0-9_$]+$/', $index)) {\n            throw new InvalidArgumentException('Index name contains invalid characters.');\n        }\n\n        return \"indexed by {$index}\";\n    }\n\n    /**\n     * Compile a \"JSON length\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $operator\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonLength($column, $operator, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'json_array_length('.$field.$path.') '.$operator.' '.$value;\n    }\n\n    /**\n     * Compile a \"JSON contains\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function compileJsonContains($column, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'exists (select 1 from json_each('.$field.$path.') where '.$this->wrap('json_each.value').' is '.$value.')';\n    }\n\n    /**\n     * Prepare the binding for a \"JSON contains\" statement.\n     *\n     * @param  mixed  $binding\n     * @return mixed\n     */\n    public function prepareBindingForJsonContains($binding)\n    {\n        return $binding;\n    }\n\n    /**\n     * Compile a \"JSON contains key\" statement into SQL.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileJsonContainsKey($column)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return 'json_type('.$field.$path.') is not null';\n    }\n\n    /**\n     * Compile a group limit clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileGroupLimit(Builder $query)\n    {\n        $version = $query->getConnection()->getServerVersion();\n\n        if (version_compare($version, '3.25.0', '>=')) {\n            return parent::compileGroupLimit($query);\n        }\n\n        $query->groupLimit = null;\n\n        return $this->compileSelect($query);\n    }\n\n    /**\n     * Compile an update statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileUpdate(Builder $query, array $values)\n    {\n        if (isset($query->joins) || isset($query->limit)) {\n            return $this->compileUpdateWithJoinsOrLimit($query, $values);\n        }\n\n        return parent::compileUpdate($query, $values);\n    }\n\n    /**\n     * Compile an insert ignore statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    public function compileInsertOrIgnore(Builder $query, array $values)\n    {\n        return Str::replaceFirst('insert', 'insert or ignore', $this->compileInsert($query, $values));\n    }\n\n    /**\n     * Compile an insert or ignore statement with a returning clause into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $returning\n     * @param  array|null  $uniqueBy\n     * @return string\n     */\n    public function compileInsertOrIgnoreReturning(Builder $query, array $values, array $returning, ?array $uniqueBy)\n    {\n        $insert = $this->compileInsert($query, $values);\n\n        return match ($uniqueBy) {\n            null => \"{$insert} on conflict do nothing returning {$this->columnize($returning)}\",\n            default => \"{$insert} on conflict ({$this->columnize($uniqueBy)}) do nothing returning {$this->columnize($returning)}\",\n        };\n    }\n\n    /**\n     * Compile an insert ignore statement using a subquery into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @param  string  $sql\n     * @return string\n     */\n    public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql)\n    {\n        return Str::replaceFirst('insert', 'insert or ignore', $this->compileInsertUsing($query, $columns, $sql));\n    }\n\n    /**\n     * Compile the columns for an update statement.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateColumns(Builder $query, array $values)\n    {\n        $jsonGroups = $this->groupJsonColumnsForUpdate($values);\n\n        return (new Collection($values))\n            ->reject(fn ($value, $key) => $this->isJsonSelector($key))\n            ->merge($jsonGroups)\n            ->map(function ($value, $key) use ($jsonGroups) {\n                $column = last(explode('.', $key));\n\n                $value = isset($jsonGroups[$key]) ? $this->compileJsonPatch($column, $value) : $this->parameter($value);\n\n                return $this->wrap($column).' = '.$value;\n            })\n            ->implode(', ');\n    }\n\n    /**\n     * Compile an \"upsert\" statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $uniqueBy\n     * @param  array  $update\n     * @return string\n     */\n    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)\n    {\n        $sql = $this->compileInsert($query, $values);\n\n        $sql .= ' on conflict ('.$this->columnize($uniqueBy).') do update set ';\n\n        $columns = (new Collection($update))->map(function ($value, $key) {\n            return is_numeric($key)\n                ? $this->wrap($value).' = '.$this->wrapValue('excluded').'.'.$this->wrap($value)\n                : $this->wrap($key).' = '.$this->parameter($value);\n        })->implode(', ');\n\n        return $sql.$columns;\n    }\n\n    /**\n     * Group the nested JSON columns.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function groupJsonColumnsForUpdate(array $values)\n    {\n        $groups = [];\n\n        foreach ($values as $key => $value) {\n            if ($this->isJsonSelector($key)) {\n                Arr::set($groups, str_replace('->', '.', Str::after($key, '.')), $value);\n            }\n        }\n\n        return $groups;\n    }\n\n    /**\n     * Compile a \"JSON\" patch statement into SQL.\n     *\n     * @param  string  $column\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function compileJsonPatch($column, $value)\n    {\n        return \"json_patch(ifnull({$this->wrap($column)}, json('{}')), json({$this->parameter($value)}))\";\n    }\n\n    /**\n     * Compile an update statement with joins or limit into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @return string\n     */\n    protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $columns = $this->compileUpdateColumns($query, $values);\n\n        $alias = last(preg_split('/\\s+as\\s+/i', $query->from));\n\n        $selectSql = $this->compileSelect($query->select($alias.'.rowid'));\n\n        return \"update {$table} set {$columns} where {$this->wrap('rowid')} in ({$selectSql})\";\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    #[\\Override]\n    public function prepareBindingsForUpdate(array $bindings, array $values)\n    {\n        $groups = $this->groupJsonColumnsForUpdate($values);\n\n        $values = (new Collection($values))\n            ->reject(fn ($value, $key) => $this->isJsonSelector($key))\n            ->merge($groups)\n            ->map(fn ($value) => is_array($value) ? json_encode($value) : $value)\n            ->all();\n\n        $cleanBindings = Arr::except($bindings, 'select');\n\n        $values = Arr::flatten(array_map(fn ($value) => value($value), $values));\n\n        return array_values(\n            array_merge($values, Arr::flatten($cleanBindings))\n        );\n    }\n\n    /**\n     * Compile a delete statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileDelete(Builder $query)\n    {\n        if (isset($query->joins) || isset($query->limit)) {\n            return $this->compileDeleteWithJoinsOrLimit($query);\n        }\n\n        return parent::compileDelete($query);\n    }\n\n    /**\n     * Compile a delete statement with joins or limit into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    protected function compileDeleteWithJoinsOrLimit(Builder $query)\n    {\n        $table = $this->wrapTable($query->from);\n\n        $alias = last(preg_split('/\\s+as\\s+/i', $query->from));\n\n        $selectSql = $this->compileSelect($query->select($alias.'.rowid'));\n\n        return \"delete from {$table} where {$this->wrap('rowid')} in ({$selectSql})\";\n    }\n\n    /**\n     * Compile a truncate table statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return array\n     */\n    public function compileTruncate(Builder $query)\n    {\n        [$schema, $table] = $query->getConnection()->getSchemaBuilder()->parseSchemaAndTable($query->from);\n\n        $schema = $schema ? $this->wrapValue($schema).'.' : '';\n\n        return [\n            'delete from '.$schema.'sqlite_sequence where name = ?' => [$query->getConnection()->getTablePrefix().$table],\n            'delete from '.$this->wrapTable($query->from) => [],\n        ];\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_extract('.$field.$path.')';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Grammars;\n\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\JoinLateralClause;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nclass SqlServerGrammar extends Grammar\n{\n    /**\n     * All of the available clause operators.\n     *\n     * @var string[]\n     */\n    protected $operators = [\n        '=', '<', '>', '<=', '>=', '!<', '!>', '<>', '!=',\n        'like', 'not like', 'ilike',\n        '&', '&=', '|', '|=', '^', '^=',\n    ];\n\n    /**\n     * The components that make up a select clause.\n     *\n     * @var string[]\n     */\n    protected $selectComponents = [\n        'aggregate',\n        'columns',\n        'from',\n        'indexHint',\n        'joins',\n        'wheres',\n        'groups',\n        'havings',\n        'orders',\n        'offset',\n        'limit',\n        'lock',\n    ];\n\n    /**\n     * Compile a select query into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileSelect(Builder $query)\n    {\n        // An order by clause is required for SQL Server offset to function...\n        if ($query->offset && empty($query->orders)) {\n            $query->orders[] = ['sql' => '(SELECT 0)'];\n        }\n\n        return parent::compileSelect($query);\n    }\n\n    /**\n     * Compile the \"select *\" portion of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $columns\n     * @return string|null\n     */\n    protected function compileColumns(Builder $query, $columns)\n    {\n        if (! is_null($query->aggregate)) {\n            return;\n        }\n\n        $select = $query->distinct ? 'select distinct ' : 'select ';\n\n        // If there is a limit on the query, but not an offset, we will add the top\n        // clause to the query, which serves as a \"limit\" type clause within the\n        // SQL Server system similar to the limit keywords available in MySQL.\n        if (is_numeric($query->limit) && $query->limit > 0 && $query->offset <= 0) {\n            $select .= 'top '.((int) $query->limit).' ';\n        }\n\n        return $select.$this->columnize($columns);\n    }\n\n    /**\n     * Compile the \"from\" portion of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @return string\n     */\n    protected function compileFrom(Builder $query, $table)\n    {\n        $from = parent::compileFrom($query, $table);\n\n        if (is_string($query->lock)) {\n            return $from.' '.$query->lock;\n        }\n\n        if (! is_null($query->lock)) {\n            return $from.' with(rowlock,'.($query->lock ? 'updlock,' : '').'holdlock)';\n        }\n\n        return $from;\n    }\n\n    /**\n     * Compile the index hints for the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  \\Illuminate\\Database\\Query\\IndexHint  $indexHint\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileIndexHint(Builder $query, $indexHint)\n    {\n        if ($indexHint->type !== 'force') {\n            return '';\n        }\n\n        $index = $indexHint->index;\n\n        if (! preg_match('/^[a-zA-Z0-9_$]+$/', $index)) {\n            throw new InvalidArgumentException('Index name contains invalid characters.');\n        }\n\n        return \"with (index([{$index}]))\";\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereBitwise(Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        $operator = str_replace('?', '??', $where['operator']);\n\n        return '('.$this->wrap($where['column']).' '.$operator.' '.$value.') != 0';\n    }\n\n    /**\n     * Compile a \"where null safe equals\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereNullSafeEquals(Builder $query, $where)\n    {\n        return 'exists (select '.$this->wrap($where['column']).' intersect select '.$this->parameter($where['value']).')';\n    }\n\n    /**\n     * Compile a \"where date\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereDate(Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        return 'cast('.$this->wrap($where['column']).' as date) '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a \"where time\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $where\n     * @return string\n     */\n    protected function whereTime(Builder $query, $where)\n    {\n        $value = $this->parameter($where['value']);\n\n        return 'cast('.$this->wrap($where['column']).' as time) '.$where['operator'].' '.$value;\n    }\n\n    /**\n     * Compile a \"JSON contains\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonContains($column, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return $value.' in (select [value] from openjson('.$field.$path.'))';\n    }\n\n    /**\n     * Prepare the binding for a \"JSON contains\" statement.\n     *\n     * @param  mixed  $binding\n     * @return string\n     */\n    public function prepareBindingForJsonContains($binding)\n    {\n        return is_bool($binding) ? json_encode($binding) : $binding;\n    }\n\n    /**\n     * Compile a \"JSON contains key\" statement into SQL.\n     *\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileJsonContainsKey($column)\n    {\n        $segments = explode('->', $column);\n\n        $lastSegment = array_pop($segments);\n\n        if (preg_match('/\\[([0-9]+)\\]$/', $lastSegment, $matches)) {\n            $segments[] = Str::beforeLast($lastSegment, $matches[0]);\n\n            $key = $matches[1];\n        } else {\n            $key = \"'\".str_replace(\"'\", \"''\", $lastSegment).\"'\";\n        }\n\n        [$field, $path] = $this->wrapJsonFieldAndPath(implode('->', $segments));\n\n        return $key.' in (select [key] from openjson('.$field.$path.'))';\n    }\n\n    /**\n     * Compile a \"JSON length\" statement into SQL.\n     *\n     * @param  string  $column\n     * @param  string  $operator\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileJsonLength($column, $operator, $value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($column);\n\n        return '(select count(*) from openjson('.$field.$path.')) '.$operator.' '.$value;\n    }\n\n    /**\n     * Compile a \"JSON value cast\" statement into SQL.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileJsonValueCast($value)\n    {\n        return 'json_query('.$value.')';\n    }\n\n    /**\n     * Compile a single having clause.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHaving(array $having)\n    {\n        if ($having['type'] === 'Bitwise') {\n            return $this->compileHavingBitwise($having);\n        }\n\n        return parent::compileHaving($having);\n    }\n\n    /**\n     * Compile a having clause involving a bitwise operator.\n     *\n     * @param  array  $having\n     * @return string\n     */\n    protected function compileHavingBitwise($having)\n    {\n        $column = $this->wrap($having['column']);\n\n        $parameter = $this->parameter($having['value']);\n\n        return '('.$column.' '.$having['operator'].' '.$parameter.') != 0';\n    }\n\n    /**\n     * Compile a delete statement without joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileDeleteWithoutJoins(Builder $query, $table, $where)\n    {\n        $sql = parent::compileDeleteWithoutJoins($query, $table, $where);\n\n        return ! is_null($query->limit) && $query->limit > 0 && $query->offset <= 0\n            ? Str::replaceFirst('delete', 'delete top ('.$query->limit.')', $sql)\n            : $sql;\n    }\n\n    /**\n     * Compile the random statement into SQL.\n     *\n     * @param  string|int  $seed\n     * @return string\n     */\n    public function compileRandom($seed)\n    {\n        return 'NEWID()';\n    }\n\n    /**\n     * Compile the \"limit\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  int  $limit\n     * @return string\n     */\n    protected function compileLimit(Builder $query, $limit)\n    {\n        $limit = (int) $limit;\n\n        if ($limit && $query->offset > 0) {\n            return \"fetch next {$limit} rows only\";\n        }\n\n        return '';\n    }\n\n    /**\n     * Compile a row number clause.\n     *\n     * @param  string  $partition\n     * @param  string  $orders\n     * @return string\n     */\n    protected function compileRowNumber($partition, $orders)\n    {\n        if (empty($orders)) {\n            $orders = 'order by (select 0)';\n        }\n\n        return parent::compileRowNumber($partition, $orders);\n    }\n\n    /**\n     * Compile the \"offset\" portions of the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  int  $offset\n     * @return string\n     */\n    protected function compileOffset(Builder $query, $offset)\n    {\n        $offset = (int) $offset;\n\n        if ($offset) {\n            return \"offset {$offset} rows\";\n        }\n\n        return '';\n    }\n\n    /**\n     * Compile the lock into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  bool|string  $value\n     * @return string\n     */\n    protected function compileLock(Builder $query, $value)\n    {\n        return '';\n    }\n\n    /**\n     * Wrap a union subquery in parentheses.\n     *\n     * @param  string  $sql\n     * @return string\n     */\n    protected function wrapUnion($sql)\n    {\n        return 'select * from ('.$sql.') as '.$this->wrapTable('temp_table');\n    }\n\n    /**\n     * Compile an exists statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return string\n     */\n    public function compileExists(Builder $query)\n    {\n        $existsQuery = clone $query;\n\n        $existsQuery->columns = [];\n\n        return $this->compileSelect($existsQuery->selectRaw('1 [exists]')->limit(1));\n    }\n\n    /**\n     * Compile an update statement with joins into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $table\n     * @param  string  $columns\n     * @param  string  $where\n     * @return string\n     */\n    protected function compileUpdateWithJoins(Builder $query, $table, $columns, $where)\n    {\n        $alias = last(explode(' as ', $table));\n\n        $joins = $this->compileJoins($query, $query->joins);\n\n        return \"update {$alias} set {$columns} from {$table} {$joins} {$where}\";\n    }\n\n    /**\n     * Compile an \"upsert\" statement into SQL.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $values\n     * @param  array  $uniqueBy\n     * @param  array  $update\n     * @return string\n     */\n    public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)\n    {\n        $columns = $this->columnize(array_keys(array_first($values)));\n\n        $sql = 'merge '.$this->wrapTable($query->from).' ';\n\n        $parameters = (new Collection($values))\n            ->map(fn ($record) => '('.$this->parameterize($record).')')\n            ->implode(', ');\n\n        $sql .= 'using (values '.$parameters.') '.$this->wrapTable('laravel_source').' ('.$columns.') ';\n\n        $on = (new Collection($uniqueBy))\n            ->map(fn ($column) => $this->wrap('laravel_source.'.$column).' = '.$this->wrap($query->from.'.'.$column))\n            ->implode(' and ');\n\n        $sql .= 'on '.$on.' ';\n\n        if ($update) {\n            $update = (new Collection($update))->map(function ($value, $key) {\n                return is_numeric($key)\n                    ? $this->wrap($value).' = '.$this->wrap('laravel_source.'.$value)\n                    : $this->wrap($key).' = '.$this->parameter($value);\n            })->implode(', ');\n\n            $sql .= 'when matched then update set '.$update.' ';\n        }\n\n        $sql .= 'when not matched then insert ('.$columns.') values ('.$columns.');';\n\n        return $sql;\n    }\n\n    /**\n     * Prepare the bindings for an update statement.\n     *\n     * @param  array  $bindings\n     * @param  array  $values\n     * @return array\n     */\n    #[\\Override]\n    public function prepareBindingsForUpdate(array $bindings, array $values)\n    {\n        $cleanBindings = Arr::except($bindings, 'select');\n\n        $values = Arr::flatten(array_map(fn ($value) => value($value), $values));\n\n        return array_values(\n            array_merge($values, Arr::flatten($cleanBindings))\n        );\n    }\n\n    /**\n     * Compile a \"lateral join\" clause.\n     *\n     * @param  \\Illuminate\\Database\\Query\\JoinLateralClause  $join\n     * @param  string  $expression\n     * @return string\n     */\n    public function compileJoinLateral(JoinLateralClause $join, string $expression): string\n    {\n        $type = $join->type == 'left' ? 'outer' : 'cross';\n\n        return trim(\"{$type} apply {$expression}\");\n    }\n\n    /**\n     * Compile the SQL statement to define a savepoint.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileSavepoint($name)\n    {\n        return 'SAVE TRANSACTION '.$name;\n    }\n\n    /**\n     * Compile the SQL statement to execute a savepoint rollback.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileSavepointRollBack($name)\n    {\n        return 'ROLLBACK TRANSACTION '.$name;\n    }\n\n    /**\n     * Compile a query to get the number of open connections for a database.\n     *\n     * @return string\n     */\n    public function compileThreadCount()\n    {\n        return 'select count(*) Value from sys.dm_exec_sessions where status = N\\'running\\'';\n    }\n\n    /**\n     * Get the format for database stored dates.\n     *\n     * @return string\n     */\n    public function getDateFormat()\n    {\n        return 'Y-m-d H:i:s.v';\n    }\n\n    /**\n     * Wrap a single string in keyword identifiers.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapValue($value)\n    {\n        return $value === '*' ? $value : '['.str_replace(']', ']]', $value).']';\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_value('.$field.$path.')';\n    }\n\n    /**\n     * Wrap the given JSON boolean value.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonBooleanValue($value)\n    {\n        return \"'\".$value.\"'\";\n    }\n\n    /**\n     * Wrap a table in keyword identifiers.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $table\n     * @param  string|null  $prefix\n     * @return string\n     */\n    public function wrapTable($table, $prefix = null)\n    {\n        if (! $this->isExpression($table)) {\n            return $this->wrapTableValuedFunction(parent::wrapTable($table, $prefix));\n        }\n\n        return $this->getValue($table);\n    }\n\n    /**\n     * Wrap a table in keyword identifiers.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function wrapTableValuedFunction($table)\n    {\n        if (preg_match('/^(.+?)(\\(.*?\\))]$/', $table, $matches) === 1) {\n            $table = $matches[1].']'.$matches[2];\n        }\n\n        return $table;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/IndexHint.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query;\n\nclass IndexHint\n{\n    /**\n     * The type of query hint.\n     *\n     * @var string\n     */\n    public $type;\n\n    /**\n     * The name of the index.\n     *\n     * @var string\n     */\n    public $index;\n\n    /**\n     * Create a new index hint instance.\n     *\n     * @param  string  $type\n     * @param  string  $index\n     */\n    public function __construct($type, $index)\n    {\n        $this->type = $type;\n        $this->index = $index;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/JoinClause.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query;\n\nuse Closure;\n\nclass JoinClause extends Builder\n{\n    /**\n     * The type of join being performed.\n     *\n     * @var string\n     */\n    public $type;\n\n    /**\n     * The table the join clause is joining to.\n     *\n     * @var \\Illuminate\\Contracts\\Database\\Query\\Expression|string\n     */\n    public $table;\n\n    /**\n     * The connection of the parent query builder.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected $parentConnection;\n\n    /**\n     * The grammar of the parent query builder.\n     *\n     * @var \\Illuminate\\Database\\Query\\Grammars\\Grammar\n     */\n    protected $parentGrammar;\n\n    /**\n     * The processor of the parent query builder.\n     *\n     * @var \\Illuminate\\Database\\Query\\Processors\\Processor\n     */\n    protected $parentProcessor;\n\n    /**\n     * The class name of the parent query builder.\n     *\n     * @var string\n     */\n    protected $parentClass;\n\n    /**\n     * Create a new join clause instance.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $parentQuery\n     * @param  string  $type\n     * @param  string  $table\n     */\n    public function __construct(Builder $parentQuery, $type, $table)\n    {\n        $this->type = $type;\n        $this->table = $table;\n        $this->parentClass = get_class($parentQuery);\n        $this->parentGrammar = $parentQuery->getGrammar();\n        $this->parentProcessor = $parentQuery->getProcessor();\n        $this->parentConnection = $parentQuery->getConnection();\n\n        parent::__construct(\n            $this->parentConnection, $this->parentGrammar, $this->parentProcessor\n        );\n    }\n\n    /**\n     * Add an \"on\" clause to the join.\n     *\n     * On clauses can be chained, e.g.\n     *\n     *  $join->on('contacts.user_id', '=', 'users.id')\n     *       ->on('contacts.info_id', '=', 'info.id')\n     *\n     * will produce the following SQL:\n     *\n     * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id`\n     *\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @param  string  $boolean\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function on($first, $operator = null, $second = null, $boolean = 'and')\n    {\n        if ($first instanceof Closure) {\n            return $this->whereNested($first, $boolean);\n        }\n\n        return $this->whereColumn($first, $operator, $second, $boolean);\n    }\n\n    /**\n     * Add an \"or on\" clause to the join.\n     *\n     * @param  \\Closure|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $first\n     * @param  string|null  $operator\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string|null  $second\n     * @return \\Illuminate\\Database\\Query\\JoinClause\n     */\n    public function orOn($first, $operator = null, $second = null)\n    {\n        return $this->on($first, $operator, $second, 'or');\n    }\n\n    /**\n     * Get a new instance of the join clause builder.\n     *\n     * @return \\Illuminate\\Database\\Query\\JoinClause\n     */\n    public function newQuery()\n    {\n        return new static($this->newParentQuery(), $this->type, $this->table);\n    }\n\n    /**\n     * Create a new query instance for sub-query.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function forSubQuery()\n    {\n        return $this->newParentQuery()->newQuery();\n    }\n\n    /**\n     * Create a new parent query instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function newParentQuery()\n    {\n        $class = $this->parentClass;\n\n        return new $class($this->parentConnection, $this->parentGrammar, $this->parentProcessor);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/JoinLateralClause.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query;\n\nclass JoinLateralClause extends JoinClause\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/MariaDbProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nclass MariaDbProcessor extends MySqlProcessor\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/MySqlProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nuse Illuminate\\Database\\Query\\Builder;\n\nclass MySqlProcessor extends Processor\n{\n    /**\n     * Process the results of a column listing query.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  array  $results\n     * @return array\n     */\n    public function processColumnListing($results)\n    {\n        return array_map(function ($result) {\n            return ((object) $result)->column_name;\n        }, $results);\n    }\n\n    /**\n     * Process an  \"insert get ID\" query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $sql\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return int\n     */\n    public function processInsertGetId(Builder $query, $sql, $values, $sequence = null)\n    {\n        $query->getConnection()->insert($sql, $values, $sequence);\n\n        $id = $query->getConnection()->getLastInsertId();\n\n        return is_numeric($id) ? (int) $id : $id;\n    }\n\n    /** @inheritDoc */\n    public function processColumns($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'type_name' => $result->type_name,\n                'type' => $result->type,\n                'collation' => $result->collation,\n                'nullable' => $result->nullable === 'YES',\n                'default' => $result->default,\n                'auto_increment' => $result->extra === 'auto_increment',\n                'comment' => $result->comment ?: null,\n                'generation' => $result->expression ? [\n                    'type' => match ($result->extra) {\n                        'STORED GENERATED' => 'stored',\n                        'VIRTUAL GENERATED' => 'virtual',\n                        default => null,\n                    },\n                    'expression' => $result->expression,\n                ] : null,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processIndexes($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $name = strtolower($result->name),\n                'columns' => $result->columns ? explode(',', $result->columns) : [],\n                'type' => strtolower($result->type),\n                'unique' => (bool) $result->unique,\n                'primary' => $name === 'primary',\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processForeignKeys($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'columns' => explode(',', $result->columns),\n                'foreign_schema' => $result->foreign_schema,\n                'foreign_table' => $result->foreign_table,\n                'foreign_columns' => explode(',', $result->foreign_columns),\n                'on_update' => strtolower($result->on_update),\n                'on_delete' => strtolower($result->on_delete),\n            ];\n        }, $results);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/PostgresProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nuse Illuminate\\Database\\Query\\Builder;\n\nclass PostgresProcessor extends Processor\n{\n    /**\n     * Process an \"insert get ID\" query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $sql\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return int\n     */\n    public function processInsertGetId(Builder $query, $sql, $values, $sequence = null)\n    {\n        $connection = $query->getConnection();\n\n        $connection->recordsHaveBeenModified();\n\n        $result = $connection->selectFromWriteConnection($sql, $values)[0];\n\n        $sequence = $sequence ?: 'id';\n\n        $id = is_object($result) ? $result->{$sequence} : $result[$sequence];\n\n        return is_numeric($id) ? (int) $id : $id;\n    }\n\n    /** @inheritDoc */\n    public function processTypes($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'schema' => $result->schema,\n                'schema_qualified_name' => $result->schema.'.'.$result->name,\n                'implicit' => (bool) $result->implicit,\n                'type' => match (strtolower($result->type)) {\n                    'b' => 'base',\n                    'c' => 'composite',\n                    'd' => 'domain',\n                    'e' => 'enum',\n                    'p' => 'pseudo',\n                    'r' => 'range',\n                    'm' => 'multirange',\n                    default => null,\n                },\n                'category' => match (strtolower($result->category)) {\n                    'a' => 'array',\n                    'b' => 'boolean',\n                    'c' => 'composite',\n                    'd' => 'date_time',\n                    'e' => 'enum',\n                    'g' => 'geometric',\n                    'i' => 'network_address',\n                    'n' => 'numeric',\n                    'p' => 'pseudo',\n                    'r' => 'range',\n                    's' => 'string',\n                    't' => 'timespan',\n                    'u' => 'user_defined',\n                    'v' => 'bit_string',\n                    'x' => 'unknown',\n                    'z' => 'internal_use',\n                    default => null,\n                },\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processColumns($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            $autoincrement = $result->default !== null && str_starts_with($result->default, 'nextval(');\n\n            return [\n                'name' => $result->name,\n                'type_name' => $result->type_name,\n                'type' => $result->type,\n                'collation' => $result->collation,\n                'nullable' => (bool) $result->nullable,\n                'default' => $result->generated ? null : $result->default,\n                'auto_increment' => $autoincrement,\n                'comment' => $result->comment,\n                'generation' => $result->generated ? [\n                    'type' => match ($result->generated) {\n                        's' => 'stored',\n                        'v' => 'virtual',\n                        default => null,\n                    },\n                    'expression' => $result->default,\n                ] : null,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processIndexes($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => strtolower($result->name),\n                'columns' => $result->columns ? explode(',', $result->columns) : [],\n                'type' => strtolower($result->type),\n                'unique' => (bool) $result->unique,\n                'primary' => (bool) $result->primary,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processForeignKeys($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'columns' => explode(',', $result->columns),\n                'foreign_schema' => $result->foreign_schema,\n                'foreign_table' => $result->foreign_table,\n                'foreign_columns' => explode(',', $result->foreign_columns),\n                'on_update' => match (strtolower($result->on_update)) {\n                    'a' => 'no action',\n                    'r' => 'restrict',\n                    'c' => 'cascade',\n                    'n' => 'set null',\n                    'd' => 'set default',\n                    default => null,\n                },\n                'on_delete' => match (strtolower($result->on_delete)) {\n                    'a' => 'no action',\n                    'r' => 'restrict',\n                    'c' => 'cascade',\n                    'n' => 'set null',\n                    'd' => 'set default',\n                    default => null,\n                },\n            ];\n        }, $results);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/Processor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nuse Illuminate\\Database\\Query\\Builder;\n\nclass Processor\n{\n    /**\n     * Process the results of a \"select\" query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $results\n     * @return array\n     */\n    public function processSelect(Builder $query, $results)\n    {\n        return $results;\n    }\n\n    /**\n     * Process an  \"insert get ID\" query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $sql\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return int\n     */\n    public function processInsertGetId(Builder $query, $sql, $values, $sequence = null)\n    {\n        $query->getConnection()->insert($sql, $values);\n\n        $id = $query->getConnection()->getPdo()->lastInsertId($sequence);\n\n        return is_numeric($id) ? (int) $id : $id;\n    }\n\n    /**\n     * Process the results of a schemas query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, path: string|null, default: bool}>\n     */\n    public function processSchemas($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'path' => $result->path ?? null, // SQLite Only...\n                'default' => (bool) $result->default,\n            ];\n        }, $results);\n    }\n\n    /**\n     * Process the results of a tables query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, schema: string|null, schema_qualified_name: string, size: int|null, comment: string|null, collation: string|null, engine: string|null}>\n     */\n    public function processTables($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'schema' => $result->schema ?? null,\n                'schema_qualified_name' => isset($result->schema) ? $result->schema.'.'.$result->name : $result->name,\n                'size' => isset($result->size) ? (int) $result->size : null,\n                'comment' => $result->comment ?? null, // MySQL and PostgreSQL\n                'collation' => $result->collation ?? null, // MySQL only\n                'engine' => $result->engine ?? null, // MySQL only\n            ];\n        }, $results);\n    }\n\n    /**\n     * Process the results of a views query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, schema: string, schema_qualified_name: string, definition: string}>\n     */\n    public function processViews($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'schema' => $result->schema ?? null,\n                'schema_qualified_name' => isset($result->schema) ? $result->schema.'.'.$result->name : $result->name,\n                'definition' => $result->definition,\n            ];\n        }, $results);\n    }\n\n    /**\n     * Process the results of a types query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, schema: string, type: string, type: string, category: string, implicit: bool}>\n     */\n    public function processTypes($results)\n    {\n        return $results;\n    }\n\n    /**\n     * Process the results of a columns query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, type: string, type_name: string, nullable: bool, default: mixed, auto_increment: bool, comment: string|null, generation: array{type: string, expression: string|null}|null}>\n     */\n    public function processColumns($results)\n    {\n        return $results;\n    }\n\n    /**\n     * Process the results of an indexes query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, columns: list<string>, type: string, unique: bool, primary: bool}>\n     */\n    public function processIndexes($results)\n    {\n        return $results;\n    }\n\n    /**\n     * Process the results of a foreign keys query.\n     *\n     * @param  list<array<string, mixed>>  $results\n     * @return list<array{name: string, columns: list<string>, foreign_schema: string, foreign_table: string, foreign_columns: list<string>, on_update: string, on_delete: string}>\n     */\n    public function processForeignKeys($results)\n    {\n        return $results;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/SQLiteProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nclass SQLiteProcessor extends Processor\n{\n    /** @inheritDoc */\n    public function processColumns($results, $sql = '')\n    {\n        $hasPrimaryKey = array_sum(array_column($results, 'primary')) === 1;\n\n        return array_map(function ($result) use ($hasPrimaryKey, $sql) {\n            $result = (object) $result;\n\n            $type = strtolower($result->type);\n\n            $safeName = preg_quote($result->name, '/');\n\n            $collation = preg_match(\n                '/\\b'.$safeName.'\\b[^,(]+(?:\\([^()]+\\)[^,]*)?(?:(?:default|check|as)\\s*(?:\\(.*?\\))?[^,]*)*collate\\s+[\"\\'`]?(\\w+)/i',\n                $sql,\n                $matches\n            ) === 1 ? strtolower($matches[1]) : null;\n\n            $isGenerated = in_array($result->extra, [2, 3]);\n\n            $expression = $isGenerated && preg_match(\n                '/\\b'.$safeName.'\\b[^,]+\\s+as\\s+\\(((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*)\\)/i',\n                $sql,\n                $matches\n            ) === 1 ? $matches[1] : null;\n\n            return [\n                'name' => $result->name,\n                'type_name' => strtok($type, '(') ?: '',\n                'type' => $type,\n                'collation' => $collation,\n                'nullable' => (bool) $result->nullable,\n                'default' => $result->default,\n                'auto_increment' => $hasPrimaryKey && $result->primary && $type === 'integer',\n                'comment' => null,\n                'generation' => $isGenerated ? [\n                    'type' => match ((int) $result->extra) {\n                        3 => 'stored',\n                        2 => 'virtual',\n                        default => null,\n                    },\n                    'expression' => $expression,\n                ] : null,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processIndexes($results)\n    {\n        $primaryCount = 0;\n\n        $indexes = array_map(function ($result) use (&$primaryCount) {\n            $result = (object) $result;\n\n            if ($isPrimary = (bool) $result->primary) {\n                $primaryCount += 1;\n            }\n\n            return [\n                'name' => strtolower($result->name),\n                'columns' => $result->columns ? explode(',', $result->columns) : [],\n                'type' => null,\n                'unique' => (bool) $result->unique,\n                'primary' => $isPrimary,\n            ];\n        }, $results);\n\n        if ($primaryCount > 1) {\n            $indexes = array_filter($indexes, fn ($index) => $index['name'] !== 'primary');\n        }\n\n        return $indexes;\n    }\n\n    /** @inheritDoc */\n    public function processForeignKeys($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => null,\n                'columns' => explode(',', $result->columns),\n                'foreign_schema' => $result->foreign_schema,\n                'foreign_table' => $result->foreign_table,\n                'foreign_columns' => explode(',', $result->foreign_columns),\n                'on_update' => strtolower($result->on_update),\n                'on_delete' => strtolower($result->on_delete),\n            ];\n        }, $results);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Query/Processors/SqlServerProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Query\\Processors;\n\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\n\nclass SqlServerProcessor extends Processor\n{\n    /**\n     * Process an \"insert get ID\" query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $sql\n     * @param  array  $values\n     * @param  string|null  $sequence\n     * @return int\n     */\n    public function processInsertGetId(Builder $query, $sql, $values, $sequence = null)\n    {\n        $connection = $query->getConnection();\n\n        $connection->insert($sql, $values);\n\n        if ($connection->getConfig('odbc') === true) {\n            $id = $this->processInsertGetIdForOdbc($connection);\n        } else {\n            $id = $connection->getPdo()->lastInsertId();\n        }\n\n        return is_numeric($id) ? (int) $id : $id;\n    }\n\n    /**\n     * Process an \"insert get ID\" query for ODBC.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @return int\n     *\n     * @throws \\Exception\n     */\n    protected function processInsertGetIdForOdbc(Connection $connection)\n    {\n        $result = $connection->selectFromWriteConnection(\n            'SELECT CAST(COALESCE(SCOPE_IDENTITY(), @@IDENTITY) AS int) AS insertid'\n        );\n\n        if (! $result) {\n            throw new Exception('Unable to retrieve lastInsertID for ODBC.');\n        }\n\n        $row = $result[0];\n\n        return is_object($row) ? $row->insertid : $row['insertid'];\n    }\n\n    /** @inheritDoc */\n    public function processColumns($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            $type = match ($typeName = $result->type_name) {\n                'binary', 'varbinary', 'char', 'varchar', 'nchar', 'nvarchar' => $result->length == -1 ? $typeName.'(max)' : $typeName.\"($result->length)\",\n                'decimal', 'numeric' => $typeName.\"($result->precision,$result->places)\",\n                'float', 'datetime2', 'datetimeoffset', 'time' => $typeName.\"($result->precision)\",\n                default => $typeName,\n            };\n\n            return [\n                'name' => $result->name,\n                'type_name' => $result->type_name,\n                'type' => $type,\n                'collation' => $result->collation,\n                'nullable' => (bool) $result->nullable,\n                'default' => $result->default,\n                'auto_increment' => (bool) $result->autoincrement,\n                'comment' => $result->comment,\n                'generation' => $result->expression ? [\n                    'type' => $result->persisted ? 'stored' : 'virtual',\n                    'expression' => $result->expression,\n                ] : null,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processIndexes($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => strtolower($result->name),\n                'columns' => $result->columns ? explode(',', $result->columns) : [],\n                'type' => strtolower($result->type),\n                'unique' => (bool) $result->unique,\n                'primary' => (bool) $result->primary,\n            ];\n        }, $results);\n    }\n\n    /** @inheritDoc */\n    public function processForeignKeys($results)\n    {\n        return array_map(function ($result) {\n            $result = (object) $result;\n\n            return [\n                'name' => $result->name,\n                'columns' => explode(',', $result->columns),\n                'foreign_schema' => $result->foreign_schema,\n                'foreign_table' => $result->foreign_table,\n                'foreign_columns' => explode(',', $result->foreign_columns),\n                'on_update' => strtolower(str_replace('_', ' ', $result->on_update)),\n                'on_delete' => strtolower(str_replace('_', ' ', $result->on_delete)),\n            ];\n        }, $results);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/QueryException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Str;\nuse PDOException;\nuse Throwable;\n\nclass QueryException extends PDOException\n{\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * The SQL for the query.\n     *\n     * @var string\n     */\n    protected $sql;\n\n    /**\n     * The bindings for the query.\n     *\n     * @var array\n     */\n    protected $bindings;\n\n    /**\n     * The PDO read / write type for the executed query.\n     *\n     * @var null|'read'|'write'\n     */\n    public $readWriteType;\n\n    /**\n     * The connection details for the query (host, port, database, etc.).\n     *\n     * @var array\n     */\n    protected $connectionDetails = [];\n\n    /**\n     * Create a new query exception instance.\n     *\n     * @param  string  $connectionName\n     * @param  string  $sql\n     * @param  array  $bindings\n     * @param  \\Throwable  $previous\n     * @param  array  $connectionDetails\n     * @param  null|'read'|'write'  $readWriteType\n     */\n    public function __construct($connectionName, $sql, array $bindings, Throwable $previous, array $connectionDetails = [], $readWriteType = null)\n    {\n        parent::__construct('', 0, $previous);\n\n        $this->connectionName = $connectionName;\n        $this->sql = $sql;\n        $this->bindings = $bindings;\n        $this->connectionDetails = $connectionDetails;\n        $this->readWriteType = $readWriteType;\n        $this->code = $previous->getCode();\n        $this->message = $this->formatMessage($connectionName, $sql, $bindings, $previous);\n\n        if ($previous instanceof PDOException) {\n            $this->errorInfo = $previous->errorInfo;\n        }\n    }\n\n    /**\n     * Format the SQL error message.\n     *\n     * @param  string  $connectionName\n     * @param  string  $sql\n     * @param  array  $bindings\n     * @param  \\Throwable  $previous\n     * @return string\n     */\n    protected function formatMessage($connectionName, $sql, $bindings, Throwable $previous)\n    {\n        $details = $this->formatConnectionDetails();\n\n        return $previous->getMessage().' (Connection: '.$connectionName.$details.', SQL: '.Str::replaceArray('?', $bindings, $sql).')';\n    }\n\n    /**\n     * Format the connection details for the error message.\n     *\n     * @return string\n     */\n    protected function formatConnectionDetails()\n    {\n        if (empty($this->connectionDetails)) {\n            return '';\n        }\n\n        $driver = $this->connectionDetails['driver'] ?? '';\n\n        $segments = [];\n\n        if ($driver !== 'sqlite') {\n            if (! empty($this->connectionDetails['unix_socket'])) {\n                $segments[] = 'Socket: '.$this->connectionDetails['unix_socket'];\n            } else {\n                $host = $this->connectionDetails['host'] ?? '';\n\n                $segments[] = 'Host: '.(is_array($host) ? implode(', ', $host) : $host);\n                $segments[] = 'Port: '.($this->connectionDetails['port'] ?? '');\n            }\n        }\n\n        $segments[] = 'Database: '.($this->connectionDetails['database'] ?? '');\n\n        return ', '.implode(', ', $segments);\n    }\n\n    /**\n     * Get the connection name for the query.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n\n    /**\n     * Get the SQL for the query.\n     *\n     * @return string\n     */\n    public function getSql()\n    {\n        return $this->sql;\n    }\n\n    /**\n     * Get the raw SQL representation of the query with embedded bindings.\n     */\n    public function getRawSql(): string\n    {\n        return DB::connection($this->getConnectionName())\n            ->getQueryGrammar()\n            ->substituteBindingsIntoRawSql($this->getSql(), $this->getBindings());\n    }\n\n    /**\n     * Get the bindings for the query.\n     *\n     * @return array\n     */\n    public function getBindings()\n    {\n        return $this->bindings;\n    }\n\n    /**\n     * Get information about the connection such as host, port, database, etc.\n     *\n     * @return array\n     */\n    public function getConnectionDetails()\n    {\n        return $this->connectionDetails;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/README.md",
    "content": "## Illuminate Database\n\nThe Illuminate Database component is a full database toolkit for PHP, providing an expressive query builder, ActiveRecord style ORM, and schema builder. It currently supports MySQL, Postgres, SQL Server, and SQLite. It also serves as the database layer of the Laravel PHP framework.\n\n### Usage Instructions\n\nFirst, create a new \"Capsule\" manager instance. Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible.\n\n```PHP\nuse Illuminate\\Database\\Capsule\\Manager as Capsule;\n\n$capsule = new Capsule;\n\n$capsule->addConnection([\n    'driver' => 'mysql',\n    'host' => 'localhost',\n    'database' => 'database',\n    'username' => 'root',\n    'password' => 'password',\n    'charset' => 'utf8',\n    'collation' => 'utf8_unicode_ci',\n    'prefix' => '',\n]);\n\n// Set the event dispatcher used by Eloquent models... (optional)\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Container\\Container;\n$capsule->setEventDispatcher(new Dispatcher(new Container));\n\n// Make this Capsule instance available globally via static methods... (optional)\n$capsule->setAsGlobal();\n\n// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())\n$capsule->bootEloquent();\n```\n\n> `composer require \"illuminate/events\"` required when you need to use observers with Eloquent.\n\nOnce the Capsule instance has been registered. You may use it like so:\n\n**Using The Query Builder**\n\n```PHP\n$users = Capsule::table('users')->where('votes', '>', 100)->get();\n```\nOther core methods may be accessed directly from the Capsule in the same manner as from the DB facade:\n```PHP\n$results = Capsule::select('select * from users where id = ?', [1]);\n```\n\n**Using The Schema Builder**\n\n```PHP\nCapsule::schema()->create('users', function ($table) {\n    $table->increments('id');\n    $table->string('email')->unique();\n    $table->timestamps();\n});\n```\n\n**Using The Eloquent ORM**\n\n```PHP\nclass User extends Illuminate\\Database\\Eloquent\\Model {}\n\n$users = User::where('votes', '>', 1)->get();\n```\n\nFor further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](https://laravel.com/docs).\n"
  },
  {
    "path": "src/Illuminate/Database/RecordNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass RecordNotFoundException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/RecordsNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse RuntimeException;\n\nclass RecordsNotFoundException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/SQLiteConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\SQLiteProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\SQLiteGrammar as SchemaGrammar;\nuse Illuminate\\Database\\Schema\\SQLiteBuilder;\nuse Illuminate\\Database\\Schema\\SqliteSchemaState;\nuse Illuminate\\Filesystem\\Filesystem;\n\nclass SQLiteConnection extends Connection\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function getDriverTitle()\n    {\n        return 'SQLite';\n    }\n\n    /**\n     * Run the statement to start a new transaction.\n     *\n     * @return void\n     */\n    protected function executeBeginTransactionStatement()\n    {\n        if (version_compare(PHP_VERSION, '8.4.0', '>=')) {\n            $mode = $this->getConfig('transaction_mode') ?? 'DEFERRED';\n\n            $this->getPdo()->exec(\"BEGIN {$mode} TRANSACTION\");\n\n            return;\n        }\n\n        $this->getPdo()->beginTransaction();\n    }\n\n    /**\n     * Escape a binary value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeBinary($value)\n    {\n        $hex = bin2hex($value);\n\n        return \"x'{$hex}'\";\n    }\n\n    /**\n     * Determine if the given database exception was caused by a unique constraint violation.\n     *\n     * @param  \\Exception  $exception\n     * @return bool\n     */\n    protected function isUniqueConstraintError(Exception $exception)\n    {\n        return (bool) preg_match('#(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)#i', $exception->getMessage());\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\SQLiteBuilder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new SQLiteBuilder($this);\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\SQLiteGrammar\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        return new SchemaGrammar($this);\n    }\n\n    /**\n     * Get the schema state for the connection.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     *\n     * @throws \\RuntimeException\n     */\n    public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        return new SqliteSchemaState($this, $files, $processFactory);\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\SQLiteProcessor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new SQLiteProcessor;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/SQLiteDatabaseDoesNotExistException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse InvalidArgumentException;\n\nclass SQLiteDatabaseDoesNotExistException extends InvalidArgumentException\n{\n    /**\n     * The path to the database.\n     *\n     * @var string\n     */\n    public $path;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  string  $path\n     */\n    public function __construct($path)\n    {\n        parent::__construct(\"Database file at path [{$path}] does not exist. Ensure this is an absolute path to the database.\");\n\n        $this->path = $path;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Blueprint.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Closure;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Grammars\\Grammar;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Schema\\Grammars\\SQLiteGrammar;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Blueprint\n{\n    use Macroable;\n\n    /**\n     * The database connection instance.\n     */\n    protected Connection $connection;\n\n    /**\n     * The schema grammar instance.\n     */\n    protected Grammar $grammar;\n\n    /**\n     * The table the blueprint describes.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The columns that should be added to the table.\n     *\n     * @var \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    protected $columns = [];\n\n    /**\n     * The commands that should be run for the table.\n     *\n     * @var \\Illuminate\\Support\\Fluent[]\n     */\n    protected $commands = [];\n\n    /**\n     * The storage engine that should be used for the table.\n     *\n     * @var string\n     */\n    public $engine;\n\n    /**\n     * The default character set that should be used for the table.\n     *\n     * @var string\n     */\n    public $charset;\n\n    /**\n     * The collation that should be used for the table.\n     *\n     * @var string\n     */\n    public $collation;\n\n    /**\n     * Whether to make the table temporary.\n     *\n     * @var bool\n     */\n    public $temporary = false;\n\n    /**\n     * The column to add new columns after.\n     *\n     * @var string\n     */\n    public $after;\n\n    /**\n     * The blueprint state instance.\n     *\n     * @var \\Illuminate\\Database\\Schema\\BlueprintState|null\n     */\n    protected $state;\n\n    /**\n     * Create a new schema blueprint.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $table\n     * @param  (\\Closure(self): void)|null  $callback\n     */\n    public function __construct(Connection $connection, $table, ?Closure $callback = null)\n    {\n        $this->connection = $connection;\n        $this->grammar = $connection->getSchemaGrammar();\n        $this->table = $table;\n\n        if (! is_null($callback)) {\n            $callback($this);\n        }\n    }\n\n    /**\n     * Execute the blueprint against the database.\n     *\n     * @return void\n     */\n    public function build()\n    {\n        foreach ($this->toSql() as $statement) {\n            $this->connection->statement($statement);\n        }\n    }\n\n    /**\n     * Get the raw SQL statements for the blueprint.\n     *\n     * @return array\n     */\n    public function toSql()\n    {\n        $this->addImpliedCommands();\n\n        $statements = [];\n\n        // Each type of command has a corresponding compiler function on the schema\n        // grammar which is used to build the necessary SQL statements to build\n        // the blueprint element, so we'll just call that compilers function.\n        $this->ensureCommandsAreValid();\n\n        foreach ($this->commands as $command) {\n            if ($command->shouldBeSkipped) {\n                continue;\n            }\n\n            $method = 'compile'.ucfirst($command->name);\n\n            if (method_exists($this->grammar, $method) || $this->grammar::hasMacro($method)) {\n                if ($this->hasState()) {\n                    $this->state->update($command);\n                }\n\n                if (! is_null($sql = $this->grammar->$method($this, $command))) {\n                    $statements = array_merge($statements, (array) $sql);\n                }\n            }\n        }\n\n        return $statements;\n    }\n\n    /**\n     * Ensure the commands on the blueprint are valid for the connection type.\n     *\n     * @return void\n     *\n     * @throws \\BadMethodCallException\n     */\n    protected function ensureCommandsAreValid()\n    {\n        //\n    }\n\n    /**\n     * Get all of the commands matching the given names.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  array  $names\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function commandsNamed(array $names)\n    {\n        return (new Collection($this->commands))\n            ->filter(fn ($command) => in_array($command->name, $names));\n    }\n\n    /**\n     * Add the commands that are implied by the blueprint's state.\n     *\n     * @return void\n     */\n    protected function addImpliedCommands()\n    {\n        $this->addFluentIndexes();\n        $this->addFluentCommands();\n\n        if (! $this->creating()) {\n            $this->commands = array_map(\n                fn ($command) => $command instanceof ColumnDefinition\n                    ? $this->createCommand($command->change ? 'change' : 'add', ['column' => $command])\n                    : $command,\n                $this->commands\n            );\n\n            $this->addAlterCommands();\n        }\n    }\n\n    /**\n     * Add the index commands fluently specified on columns.\n     *\n     * @return void\n     */\n    protected function addFluentIndexes()\n    {\n        foreach ($this->columns as $column) {\n            foreach (['primary', 'unique', 'index', 'fulltext', 'fullText', 'spatialIndex', 'vectorIndex'] as $index) {\n                // If the column is supposed to be changed to an auto increment column and\n                // the specified index is primary, there is no need to add a command on\n                // MySQL, as it will be handled during the column definition instead.\n                if ($index === 'primary' && $column->autoIncrement && $column->change && $this->grammar instanceof MySqlGrammar) {\n                    continue 2;\n                }\n\n                // If the index has been specified on the given column, but is simply equal\n                // to \"true\" (boolean), no name has been specified for this index so the\n                // index method can be called without a name and it will generate one.\n                if ($column->{$index} === true) {\n                    $indexMethod = $index === 'index' && $column->type === 'vector'\n                        ? 'vectorIndex'\n                        : $index;\n\n                    $this->{$indexMethod}($column->name);\n                    $column->{$index} = null;\n\n                    continue 2;\n                }\n\n                // If the index has been specified on the given column, but it equals false\n                // and the column is supposed to be changed, we will call the drop index\n                // method with an array of column to drop it by its conventional name.\n                elseif ($column->{$index} === false && $column->change) {\n                    $this->{'drop'.ucfirst($index)}([$column->name]);\n                    $column->{$index} = null;\n\n                    continue 2;\n                }\n\n                // If the index has been specified on the given column, and it has a string\n                // value, we'll go ahead and call the index method and pass the name for\n                // the index since the developer specified the explicit name for this.\n                elseif (isset($column->{$index})) {\n                    $indexMethod = $index === 'index' && $column->type === 'vector'\n                        ? 'vectorIndex'\n                        : $index;\n\n                    $this->{$indexMethod}($column->name, $column->{$index});\n                    $column->{$index} = null;\n\n                    continue 2;\n                }\n            }\n        }\n    }\n\n    /**\n     * Add the fluent commands specified on any columns.\n     *\n     * @return void\n     */\n    public function addFluentCommands()\n    {\n        foreach ($this->columns as $column) {\n            foreach ($this->grammar->getFluentCommands() as $commandName) {\n                $this->addCommand($commandName, compact('column'));\n            }\n        }\n    }\n\n    /**\n     * Add the alter commands if whenever needed.\n     *\n     * @return void\n     */\n    public function addAlterCommands()\n    {\n        if (! $this->grammar instanceof SQLiteGrammar) {\n            return;\n        }\n\n        $alterCommands = $this->grammar->getAlterCommands();\n\n        [$commands, $lastCommandWasAlter, $hasAlterCommand] = [\n            [], false, false,\n        ];\n\n        foreach ($this->commands as $command) {\n            if (in_array($command->name, $alterCommands)) {\n                $hasAlterCommand = true;\n                $lastCommandWasAlter = true;\n            } elseif ($lastCommandWasAlter) {\n                $commands[] = $this->createCommand('alter');\n                $lastCommandWasAlter = false;\n            }\n\n            $commands[] = $command;\n        }\n\n        if ($lastCommandWasAlter) {\n            $commands[] = $this->createCommand('alter');\n        }\n\n        if ($hasAlterCommand) {\n            $this->state = new BlueprintState($this, $this->connection);\n        }\n\n        $this->commands = $commands;\n    }\n\n    /**\n     * Determine if the blueprint has a create command.\n     *\n     * @return bool\n     */\n    public function creating()\n    {\n        return (new Collection($this->commands))\n            ->contains(fn ($command) => ! $command instanceof ColumnDefinition && $command->name === 'create');\n    }\n\n    /**\n     * Indicate that the table needs to be created.\n     *\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function create()\n    {\n        return $this->addCommand('create');\n    }\n\n    /**\n     * Specify the storage engine that should be used for the table.\n     *\n     * @param  string  $engine\n     * @return void\n     */\n    public function engine($engine)\n    {\n        $this->engine = $engine;\n    }\n\n    /**\n     * Specify that the InnoDB storage engine should be used for the table (MySQL only).\n     *\n     * @return void\n     */\n    public function innoDb()\n    {\n        $this->engine('InnoDB');\n    }\n\n    /**\n     * Specify the character set that should be used for the table.\n     *\n     * @param  string  $charset\n     * @return void\n     */\n    public function charset($charset)\n    {\n        $this->charset = $charset;\n    }\n\n    /**\n     * Specify the collation that should be used for the table.\n     *\n     * @param  string  $collation\n     * @return void\n     */\n    public function collation($collation)\n    {\n        $this->collation = $collation;\n    }\n\n    /**\n     * Indicate that the table needs to be temporary.\n     *\n     * @return void\n     */\n    public function temporary()\n    {\n        $this->temporary = true;\n    }\n\n    /**\n     * Indicate that the table should be dropped.\n     *\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function drop()\n    {\n        return $this->addCommand('drop');\n    }\n\n    /**\n     * Indicate that the table should be dropped if it exists.\n     *\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropIfExists()\n    {\n        return $this->addCommand('dropIfExists');\n    }\n\n    /**\n     * Indicate that the given columns should be dropped.\n     *\n     * @param  mixed  $columns\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropColumn($columns)\n    {\n        $columns = is_array($columns) ? $columns : func_get_args();\n\n        return $this->addCommand('dropColumn', compact('columns'));\n    }\n\n    /**\n     * Indicate that the given columns should be renamed.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function renameColumn($from, $to)\n    {\n        return $this->addCommand('renameColumn', compact('from', 'to'));\n    }\n\n    /**\n     * Indicate that the given primary key should be dropped.\n     *\n     * @param  string|array|null  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropPrimary($index = null)\n    {\n        return $this->dropIndexCommand('dropPrimary', 'primary', $index);\n    }\n\n    /**\n     * Indicate that the given unique key should be dropped.\n     *\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropUnique($index)\n    {\n        return $this->dropIndexCommand('dropUnique', 'unique', $index);\n    }\n\n    /**\n     * Indicate that the given index should be dropped.\n     *\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropIndex($index)\n    {\n        return $this->dropIndexCommand('dropIndex', 'index', $index);\n    }\n\n    /**\n     * Indicate that the given fulltext index should be dropped.\n     *\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropFullText($index)\n    {\n        return $this->dropIndexCommand('dropFullText', 'fulltext', $index);\n    }\n\n    /**\n     * Indicate that the given spatial index should be dropped.\n     *\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropSpatialIndex($index)\n    {\n        return $this->dropIndexCommand('dropSpatialIndex', 'spatialIndex', $index);\n    }\n\n    /**\n     * Indicate that the given foreign key should be dropped.\n     *\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropForeign($index)\n    {\n        return $this->dropIndexCommand('dropForeign', 'foreign', $index);\n    }\n\n    /**\n     * Indicate that the given column and foreign key should be dropped.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropConstrainedForeignId($column)\n    {\n        $this->dropForeign([$column]);\n\n        return $this->dropColumn($column);\n    }\n\n    /**\n     * Indicate that the given foreign key should be dropped.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|string  $model\n     * @param  string|null  $column\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropForeignIdFor($model, $column = null)\n    {\n        if (is_string($model)) {\n            $model = new $model;\n        }\n\n        return $this->dropColumn($column ?: $model->getForeignKey());\n    }\n\n    /**\n     * Indicate that the given foreign key should be dropped.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|string  $model\n     * @param  string|null  $column\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function dropConstrainedForeignIdFor($model, $column = null)\n    {\n        if (is_string($model)) {\n            $model = new $model;\n        }\n\n        return $this->dropConstrainedForeignId($column ?: $model->getForeignKey());\n    }\n\n    /**\n     * Indicate that the given indexes should be renamed.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function renameIndex($from, $to)\n    {\n        return $this->addCommand('renameIndex', compact('from', 'to'));\n    }\n\n    /**\n     * Indicate that the timestamp columns should be dropped.\n     *\n     * @return void\n     */\n    public function dropTimestamps()\n    {\n        $this->dropColumn('created_at', 'updated_at');\n    }\n\n    /**\n     * Indicate that the timestamp columns should be dropped.\n     *\n     * @return void\n     */\n    public function dropTimestampsTz()\n    {\n        $this->dropTimestamps();\n    }\n\n    /**\n     * Indicate that the soft delete column should be dropped.\n     *\n     * @param  string  $column\n     * @return void\n     */\n    public function dropSoftDeletes($column = 'deleted_at')\n    {\n        $this->dropColumn($column);\n    }\n\n    /**\n     * Indicate that the soft delete column should be dropped.\n     *\n     * @param  string  $column\n     * @return void\n     */\n    public function dropSoftDeletesTz($column = 'deleted_at')\n    {\n        $this->dropSoftDeletes($column);\n    }\n\n    /**\n     * Indicate that the remember token column should be dropped.\n     *\n     * @return void\n     */\n    public function dropRememberToken()\n    {\n        $this->dropColumn('remember_token');\n    }\n\n    /**\n     * Indicate that the polymorphic columns should be dropped.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @return void\n     */\n    public function dropMorphs($name, $indexName = null)\n    {\n        $this->dropIndex($indexName ?: $this->createIndexName('index', [\"{$name}_type\", \"{$name}_id\"]));\n\n        $this->dropColumn(\"{$name}_type\", \"{$name}_id\");\n    }\n\n    /**\n     * Rename the table to a given name.\n     *\n     * @param  string  $to\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function rename($to)\n    {\n        return $this->addCommand('rename', compact('to'));\n    }\n\n    /**\n     * Specify the primary key(s) for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @param  string|null  $algorithm\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function primary($columns, $name = null, $algorithm = null)\n    {\n        return $this->indexCommand('primary', $columns, $name, $algorithm);\n    }\n\n    /**\n     * Specify a unique index for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @param  string|null  $algorithm\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function unique($columns, $name = null, $algorithm = null)\n    {\n        return $this->indexCommand('unique', $columns, $name, $algorithm);\n    }\n\n    /**\n     * Specify an index for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @param  string|null  $algorithm\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function index($columns, $name = null, $algorithm = null)\n    {\n        return $this->indexCommand('index', $columns, $name, $algorithm);\n    }\n\n    /**\n     * Specify a fulltext index for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @param  string|null  $algorithm\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function fullText($columns, $name = null, $algorithm = null)\n    {\n        return $this->indexCommand('fulltext', $columns, $name, $algorithm);\n    }\n\n    /**\n     * Specify a spatial index for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @param  string|null  $operatorClass\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function spatialIndex($columns, $name = null, $operatorClass = null)\n    {\n        return $this->indexCommand('spatialIndex', $columns, $name, null, $operatorClass);\n    }\n\n    /**\n     * Specify a vector index for the table.\n     *\n     * @param  string  $column\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function vectorIndex($column, $name = null)\n    {\n        return $this->indexCommand('vectorIndex', $column, $name, 'hnsw', 'vector_cosine_ops');\n    }\n\n    /**\n     * Specify a raw index for the table.\n     *\n     * @param  string  $expression\n     * @param  string  $name\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition\n     */\n    public function rawIndex($expression, $name)\n    {\n        return $this->index([new Expression($expression)], $name);\n    }\n\n    /**\n     * Specify a foreign key for the table.\n     *\n     * @param  string|array  $columns\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\Schema\\ForeignKeyDefinition\n     */\n    public function foreign($columns, $name = null)\n    {\n        $command = new ForeignKeyDefinition(\n            $this->indexCommand('foreign', $columns, $name)->getAttributes()\n        );\n\n        $this->commands[count($this->commands) - 1] = $command;\n\n        return $command;\n    }\n\n    /**\n     * Create a new auto-incrementing big integer column on the table (8-byte, 0 to 18,446,744,073,709,551,615).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function id($column = 'id')\n    {\n        return $this->bigIncrements($column);\n    }\n\n    /**\n     * Create a new auto-incrementing integer column on the table (4-byte, 0 to 4,294,967,295).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function increments($column)\n    {\n        return $this->unsignedInteger($column, true);\n    }\n\n    /**\n     * Create a new auto-incrementing integer column on the table (4-byte, 0 to 4,294,967,295).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function integerIncrements($column)\n    {\n        return $this->unsignedInteger($column, true);\n    }\n\n    /**\n     * Create a new auto-incrementing tiny integer column on the table (1-byte, 0 to 255).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function tinyIncrements($column)\n    {\n        return $this->unsignedTinyInteger($column, true);\n    }\n\n    /**\n     * Create a new auto-incrementing small integer column on the table (2-byte, 0 to 65,535).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function smallIncrements($column)\n    {\n        return $this->unsignedSmallInteger($column, true);\n    }\n\n    /**\n     * Create a new auto-incrementing medium integer column on the table (3-byte, 0 to 16,777,215).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function mediumIncrements($column)\n    {\n        return $this->unsignedMediumInteger($column, true);\n    }\n\n    /**\n     * Create a new auto-incrementing big integer column on the table (8-byte, 0 to 18,446,744,073,709,551,615).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function bigIncrements($column)\n    {\n        return $this->unsignedBigInteger($column, true);\n    }\n\n    /**\n     * Create a new char column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $length\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function char($column, $length = null)\n    {\n        $length = ! is_null($length) ? $length : Builder::$defaultStringLength;\n\n        return $this->addColumn('char', $column, compact('length'));\n    }\n\n    /**\n     * Create a new string column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $length\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function string($column, $length = null)\n    {\n        $length = $length ?: Builder::$defaultStringLength;\n\n        return $this->addColumn('string', $column, compact('length'));\n    }\n\n    /**\n     * Create a new tiny text column on the table (up to 255 characters).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function tinyText($column)\n    {\n        return $this->addColumn('tinyText', $column);\n    }\n\n    /**\n     * Create a new text column on the table (up to 65,535 characters / ~64 KB).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function text($column)\n    {\n        return $this->addColumn('text', $column);\n    }\n\n    /**\n     * Create a new medium text column on the table (up to 16,777,215 characters / ~16 MB).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function mediumText($column)\n    {\n        return $this->addColumn('mediumText', $column);\n    }\n\n    /**\n     * Create a new long text column on the table (up to 4,294,967,295 characters / ~4 GB).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function longText($column)\n    {\n        return $this->addColumn('longText', $column);\n    }\n\n    /**\n     * Create a new integer (4-byte) column on the table.\n     * Range: -2,147,483,648 to 2,147,483,647 (signed) or 0 to 4,294,967,295 (unsigned).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @param  bool  $unsigned\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function integer($column, $autoIncrement = false, $unsigned = false)\n    {\n        return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));\n    }\n\n    /**\n     * Create a new tiny integer (1-byte) column on the table.\n     * Range: -128 to 127 (signed) or 0 to 255 (unsigned).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @param  bool  $unsigned\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function tinyInteger($column, $autoIncrement = false, $unsigned = false)\n    {\n        return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned'));\n    }\n\n    /**\n     * Create a new small integer (2-byte) column on the table.\n     * Range: -32,768 to 32,767 (signed) or 0 to 65,535 (unsigned).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @param  bool  $unsigned\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function smallInteger($column, $autoIncrement = false, $unsigned = false)\n    {\n        return $this->addColumn('smallInteger', $column, compact('autoIncrement', 'unsigned'));\n    }\n\n    /**\n     * Create a new medium integer (3-byte) column on the table.\n     * Range: -8,388,608 to 8,388,607 (signed) or 0 to 16,777,215 (unsigned).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @param  bool  $unsigned\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function mediumInteger($column, $autoIncrement = false, $unsigned = false)\n    {\n        return $this->addColumn('mediumInteger', $column, compact('autoIncrement', 'unsigned'));\n    }\n\n    /**\n     * Create a new big integer (8-byte) column on the table.\n     * Range: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (signed) or 0 to 18,446,744,073,709,551,615 (unsigned).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @param  bool  $unsigned\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function bigInteger($column, $autoIncrement = false, $unsigned = false)\n    {\n        return $this->addColumn('bigInteger', $column, compact('autoIncrement', 'unsigned'));\n    }\n\n    /**\n     * Create a new unsigned integer column on the table (4-byte, 0 to 4,294,967,295).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function unsignedInteger($column, $autoIncrement = false)\n    {\n        return $this->integer($column, $autoIncrement, true);\n    }\n\n    /**\n     * Create a new unsigned tiny integer column on the table (1-byte, 0 to 255).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function unsignedTinyInteger($column, $autoIncrement = false)\n    {\n        return $this->tinyInteger($column, $autoIncrement, true);\n    }\n\n    /**\n     * Create a new unsigned small integer column on the table (2-byte, 0 to 65,535).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function unsignedSmallInteger($column, $autoIncrement = false)\n    {\n        return $this->smallInteger($column, $autoIncrement, true);\n    }\n\n    /**\n     * Create a new unsigned medium integer column on the table (3-byte, 0 to 16,777,215).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function unsignedMediumInteger($column, $autoIncrement = false)\n    {\n        return $this->mediumInteger($column, $autoIncrement, true);\n    }\n\n    /**\n     * Create a new unsigned big integer column on the table (8-byte, 0 to 18,446,744,073,709,551,615).\n     *\n     * @param  string  $column\n     * @param  bool  $autoIncrement\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function unsignedBigInteger($column, $autoIncrement = false)\n    {\n        return $this->bigInteger($column, $autoIncrement, true);\n    }\n\n    /**\n     * Create a new unsigned big integer column on the table (8-byte, 0 to 18,446,744,073,709,551,615).\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ForeignIdColumnDefinition\n     */\n    public function foreignId($column)\n    {\n        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [\n            'type' => 'bigInteger',\n            'name' => $column,\n            'autoIncrement' => false,\n            'unsigned' => true,\n        ]));\n    }\n\n    /**\n     * Create a foreign ID column for the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|string  $model\n     * @param  string|null  $column\n     * @return \\Illuminate\\Database\\Schema\\ForeignIdColumnDefinition\n     */\n    public function foreignIdFor($model, $column = null)\n    {\n        if (is_string($model)) {\n            $model = new $model;\n        }\n\n        $column = $column ?: $model->getForeignKey();\n\n        if ($model->getKeyType() === 'int') {\n            return $this->foreignId($column)\n                ->table($model->getTable())\n                ->referencesModelColumn($model->getKeyName());\n        }\n\n        $modelTraits = class_uses_recursive($model);\n\n        if (in_array(HasUlids::class, $modelTraits, true)) {\n            return $this->foreignUlid($column, 26)\n                ->table($model->getTable())\n                ->referencesModelColumn($model->getKeyName());\n        }\n\n        return $this->foreignUuid($column)\n            ->table($model->getTable())\n            ->referencesModelColumn($model->getKeyName());\n    }\n\n    /**\n     * Create a new float column on the table.\n     *\n     * @param  string  $column\n     * @param  int  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function float($column, $precision = 53)\n    {\n        return $this->addColumn('float', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new double column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function double($column)\n    {\n        return $this->addColumn('double', $column);\n    }\n\n    /**\n     * Create a new decimal column on the table.\n     *\n     * @param  string  $column\n     * @param  int  $total\n     * @param  int  $places\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function decimal($column, $total = 8, $places = 2)\n    {\n        return $this->addColumn('decimal', $column, compact('total', 'places'));\n    }\n\n    /**\n     * Create a new boolean column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function boolean($column)\n    {\n        return $this->addColumn('boolean', $column);\n    }\n\n    /**\n     * Create a new enum column on the table.\n     *\n     * @param  string  $column\n     * @param  array  $allowed\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function enum($column, array $allowed)\n    {\n        $allowed = array_map(fn ($value) => enum_value($value), $allowed);\n\n        return $this->addColumn('enum', $column, compact('allowed'));\n    }\n\n    /**\n     * Create a new set column on the table.\n     *\n     * @param  string  $column\n     * @param  array  $allowed\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function set($column, array $allowed)\n    {\n        return $this->addColumn('set', $column, compact('allowed'));\n    }\n\n    /**\n     * Create a new json column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function json($column)\n    {\n        return $this->addColumn('json', $column);\n    }\n\n    /**\n     * Create a new jsonb column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function jsonb($column)\n    {\n        return $this->addColumn('jsonb', $column);\n    }\n\n    /**\n     * Create a new date column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function date($column)\n    {\n        return $this->addColumn('date', $column);\n    }\n\n    /**\n     * Create a new date-time column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function dateTime($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('dateTime', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new date-time column (with time zone) on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function dateTimeTz($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('dateTimeTz', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new time column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function time($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('time', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new time column (with time zone) on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function timeTz($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('timeTz', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new timestamp column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function timestamp($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('timestamp', $column, compact('precision'));\n    }\n\n    /**\n     * Create a new timestamp (with time zone) column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function timestampTz($column, $precision = null)\n    {\n        $precision ??= $this->defaultTimePrecision();\n\n        return $this->addColumn('timestampTz', $column, compact('precision'));\n    }\n\n    /**\n     * Add nullable creation and update timestamps to the table.\n     *\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Schema\\ColumnDefinition>\n     */\n    public function timestamps($precision = null)\n    {\n        return new Collection([\n            $this->timestamp('created_at', $precision)->nullable(),\n            $this->timestamp('updated_at', $precision)->nullable(),\n        ]);\n    }\n\n    /**\n     * Add nullable creation and update timestamps to the table.\n     *\n     * Alias for self::timestamps().\n     *\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Schema\\ColumnDefinition>\n     */\n    public function nullableTimestamps($precision = null)\n    {\n        return $this->timestamps($precision);\n    }\n\n    /**\n     * Add nullable creation and update timestampTz columns to the table.\n     *\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Schema\\ColumnDefinition>\n     */\n    public function timestampsTz($precision = null)\n    {\n        return new Collection([\n            $this->timestampTz('created_at', $precision)->nullable(),\n            $this->timestampTz('updated_at', $precision)->nullable(),\n        ]);\n    }\n\n    /**\n     * Add nullable creation and update timestampTz columns to the table.\n     *\n     * Alias for self::timestampsTz().\n     *\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Schema\\ColumnDefinition>\n     */\n    public function nullableTimestampsTz($precision = null)\n    {\n        return $this->timestampsTz($precision);\n    }\n\n    /**\n     * Add creation and update datetime columns to the table.\n     *\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\Schema\\ColumnDefinition>\n     */\n    public function datetimes($precision = null)\n    {\n        return new Collection([\n            $this->datetime('created_at', $precision)->nullable(),\n            $this->datetime('updated_at', $precision)->nullable(),\n        ]);\n    }\n\n    /**\n     * Add a \"deleted at\" timestamp for the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function softDeletes($column = 'deleted_at', $precision = null)\n    {\n        return $this->timestamp($column, $precision)->nullable();\n    }\n\n    /**\n     * Add a \"deleted at\" timestampTz for the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function softDeletesTz($column = 'deleted_at', $precision = null)\n    {\n        return $this->timestampTz($column, $precision)->nullable();\n    }\n\n    /**\n     * Add a \"deleted at\" datetime column to the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $precision\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function softDeletesDatetime($column = 'deleted_at', $precision = null)\n    {\n        return $this->dateTime($column, $precision)->nullable();\n    }\n\n    /**\n     * Create a new year column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function year($column)\n    {\n        return $this->addColumn('year', $column);\n    }\n\n    /**\n     * Create a new binary column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $length\n     * @param  bool  $fixed\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function binary($column, $length = null, $fixed = false)\n    {\n        return $this->addColumn('binary', $column, compact('length', 'fixed'));\n    }\n\n    /**\n     * Create a new UUID column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function uuid($column = 'uuid')\n    {\n        return $this->addColumn('uuid', $column);\n    }\n\n    /**\n     * Create a new UUID column on the table with a foreign key constraint.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ForeignIdColumnDefinition\n     */\n    public function foreignUuid($column)\n    {\n        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [\n            'type' => 'uuid',\n            'name' => $column,\n        ]));\n    }\n\n    /**\n     * Create a new ULID column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $length\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function ulid($column = 'ulid', $length = 26)\n    {\n        return $this->char($column, $length);\n    }\n\n    /**\n     * Create a new ULID column on the table with a foreign key constraint.\n     *\n     * @param  string  $column\n     * @param  int|null  $length\n     * @return \\Illuminate\\Database\\Schema\\ForeignIdColumnDefinition\n     */\n    public function foreignUlid($column, $length = 26)\n    {\n        return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [\n            'type' => 'char',\n            'name' => $column,\n            'length' => $length,\n        ]));\n    }\n\n    /**\n     * Create a new IP address column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function ipAddress($column = 'ip_address')\n    {\n        return $this->addColumn('ipAddress', $column);\n    }\n\n    /**\n     * Create a new MAC address column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function macAddress($column = 'mac_address')\n    {\n        return $this->addColumn('macAddress', $column);\n    }\n\n    /**\n     * Create a new geometry column on the table.\n     *\n     * @param  string  $column\n     * @param  string|null  $subtype\n     * @param  int  $srid\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function geometry($column, $subtype = null, $srid = 0)\n    {\n        return $this->addColumn('geometry', $column, compact('subtype', 'srid'));\n    }\n\n    /**\n     * Create a new geography column on the table.\n     *\n     * @param  string  $column\n     * @param  string|null  $subtype\n     * @param  int  $srid\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function geography($column, $subtype = null, $srid = 4326)\n    {\n        return $this->addColumn('geography', $column, compact('subtype', 'srid'));\n    }\n\n    /**\n     * Create a new generated, computed column on the table.\n     *\n     * @param  string  $column\n     * @param  string  $expression\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function computed($column, $expression)\n    {\n        return $this->addColumn('computed', $column, compact('expression'));\n    }\n\n    /**\n     * Create a new vector column on the table.\n     *\n     * @param  string  $column\n     * @param  int|null  $dimensions\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function vector($column, $dimensions = null)\n    {\n        $options = $dimensions ? compact('dimensions') : [];\n\n        return $this->addColumn('vector', $column, $options);\n    }\n\n    /**\n     * Create a new tsvector column on the table.\n     *\n     * @param  string  $column\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function tsvector($column)\n    {\n        return $this->addColumn('tsvector', $column);\n    }\n\n    /**\n     * Add the proper columns for a polymorphic table.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function morphs($name, $indexName = null, $after = null)\n    {\n        if (Builder::$defaultMorphKeyType === 'uuid') {\n            $this->uuidMorphs($name, $indexName, $after);\n        } elseif (Builder::$defaultMorphKeyType === 'ulid') {\n            $this->ulidMorphs($name, $indexName, $after);\n        } else {\n            $this->numericMorphs($name, $indexName, $after);\n        }\n    }\n\n    /**\n     * Add nullable columns for a polymorphic table.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function nullableMorphs($name, $indexName = null, $after = null)\n    {\n        if (Builder::$defaultMorphKeyType === 'uuid') {\n            $this->nullableUuidMorphs($name, $indexName, $after);\n        } elseif (Builder::$defaultMorphKeyType === 'ulid') {\n            $this->nullableUlidMorphs($name, $indexName, $after);\n        } else {\n            $this->nullableNumericMorphs($name, $indexName, $after);\n        }\n    }\n\n    /**\n     * Add the proper columns for a polymorphic table using numeric IDs (incremental).\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function numericMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->after($after);\n\n        $this->unsignedBigInteger(\"{$name}_id\")\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add nullable columns for a polymorphic table using numeric IDs (incremental).\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function nullableNumericMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->nullable()\n            ->after($after);\n\n        $this->unsignedBigInteger(\"{$name}_id\")\n            ->nullable()\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add the proper columns for a polymorphic table using UUIDs.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function uuidMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->after($after);\n\n        $this->uuid(\"{$name}_id\")\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add nullable columns for a polymorphic table using UUIDs.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function nullableUuidMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->nullable()\n            ->after($after);\n\n        $this->uuid(\"{$name}_id\")\n            ->nullable()\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add the proper columns for a polymorphic table using ULIDs.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function ulidMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->after($after);\n\n        $this->ulid(\"{$name}_id\")\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add nullable columns for a polymorphic table using ULIDs.\n     *\n     * @param  string  $name\n     * @param  string|null  $indexName\n     * @param  string|null  $after\n     * @return void\n     */\n    public function nullableUlidMorphs($name, $indexName = null, $after = null)\n    {\n        $this->string(\"{$name}_type\")\n            ->nullable()\n            ->after($after);\n\n        $this->ulid(\"{$name}_id\")\n            ->nullable()\n            ->after(! is_null($after) ? \"{$name}_type\" : null);\n\n        $this->index([\"{$name}_type\", \"{$name}_id\"], $indexName);\n    }\n\n    /**\n     * Add the `remember_token` column to the table.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function rememberToken()\n    {\n        return $this->string('remember_token', 100)->nullable();\n    }\n\n    /**\n     * Create a new custom column on the table.\n     *\n     * @param  string  $column\n     * @param  string  $definition\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function rawColumn($column, $definition)\n    {\n        return $this->addColumn('raw', $column, compact('definition'));\n    }\n\n    /**\n     * Add a comment to the table.\n     *\n     * @param  string  $comment\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function comment($comment)\n    {\n        return $this->addCommand('tableComment', compact('comment'));\n    }\n\n    /**\n     * Create a new index command on the blueprint.\n     *\n     * @param  string  $type\n     * @param  string|array  $columns\n     * @param  string  $index\n     * @param  string|null  $algorithm\n     * @param  string|null  $operatorClass\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    protected function indexCommand($type, $columns, $index, $algorithm = null, $operatorClass = null)\n    {\n        $columns = (array) $columns;\n\n        // If no name was specified for this index, we will create one using a basic\n        // convention of the table name, followed by the columns, followed by an\n        // index type, such as primary or index, which makes the index unique.\n        $index = $index ?: $this->createIndexName($type, $columns);\n\n        return $this->addCommand(\n            $type, compact('index', 'columns', 'algorithm', 'operatorClass')\n        );\n    }\n\n    /**\n     * Create a new drop index command on the blueprint.\n     *\n     * @param  string  $command\n     * @param  string  $type\n     * @param  string|array  $index\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    protected function dropIndexCommand($command, $type, $index)\n    {\n        $columns = [];\n\n        // If the given \"index\" is actually an array of columns, the developer means\n        // to drop an index merely by specifying the columns involved without the\n        // conventional name, so we will build the index name from the columns.\n        if (is_array($index)) {\n            $index = $this->createIndexName($type, $columns = $index);\n        }\n\n        return $this->indexCommand($command, $columns, $index);\n    }\n\n    /**\n     * Create a default index name for the table.\n     *\n     * @param  string  $type\n     * @param  array  $columns\n     * @return string\n     */\n    protected function createIndexName($type, array $columns)\n    {\n        $table = $this->table;\n\n        if ($this->connection->getConfig('prefix_indexes')) {\n            $table = str_contains($this->table, '.')\n                ? substr_replace($this->table, '.'.$this->connection->getTablePrefix(), strrpos($this->table, '.'), 1)\n                : $this->connection->getTablePrefix().$this->table;\n        }\n\n        $index = strtolower($table.'_'.implode('_', $columns).'_'.$type);\n\n        return str_replace(['-', '.'], '_', $index);\n    }\n\n    /**\n     * Add a new column to the blueprint.\n     *\n     * @param  string  $type\n     * @param  string  $name\n     * @param  array  $parameters\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    public function addColumn($type, $name, array $parameters = [])\n    {\n        return $this->addColumnDefinition(new ColumnDefinition(\n            array_merge(compact('type', 'name'), $parameters)\n        ));\n    }\n\n    /**\n     * Add a new column definition to the blueprint.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\ColumnDefinition  $definition\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition\n     */\n    protected function addColumnDefinition($definition)\n    {\n        $this->columns[] = $definition;\n\n        if (! $this->creating()) {\n            $this->commands[] = $definition;\n        }\n\n        if ($this->after) {\n            $definition->after($this->after);\n\n            $this->after = $definition->name;\n        }\n\n        return $definition;\n    }\n\n    /**\n     * Add the columns from the callback after the given column.\n     *\n     * @param  string  $column\n     * @param  (\\Closure(self): void)  $callback\n     * @return void\n     */\n    public function after($column, Closure $callback)\n    {\n        $this->after = $column;\n\n        $callback($this);\n\n        $this->after = null;\n    }\n\n    /**\n     * Remove a column from the schema blueprint.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function removeColumn($name)\n    {\n        $this->columns = array_values(array_filter($this->columns, function ($c) use ($name) {\n            return $c['name'] != $name;\n        }));\n\n        $this->commands = array_values(array_filter($this->commands, function ($c) use ($name) {\n            return ! $c instanceof ColumnDefinition || $c['name'] != $name;\n        }));\n\n        return $this;\n    }\n\n    /**\n     * Add a new command to the blueprint.\n     *\n     * @param  string  $name\n     * @param  array  $parameters\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    protected function addCommand($name, array $parameters = [])\n    {\n        $this->commands[] = $command = $this->createCommand($name, $parameters);\n\n        return $command;\n    }\n\n    /**\n     * Create a new Fluent command.\n     *\n     * @param  string  $name\n     * @param  array  $parameters\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    protected function createCommand($name, array $parameters = [])\n    {\n        return new Fluent(array_merge(compact('name'), $parameters));\n    }\n\n    /**\n     * Get the table the blueprint describes.\n     *\n     * @return string\n     */\n    public function getTable()\n    {\n        return $this->table;\n    }\n\n    /**\n     * Get the table prefix.\n     *\n     * @deprecated Use DB::getTablePrefix()\n     *\n     * @return string\n     */\n    public function getPrefix()\n    {\n        return $this->connection->getTablePrefix();\n    }\n\n    /**\n     * Get the columns on the blueprint.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    public function getColumns()\n    {\n        return $this->columns;\n    }\n\n    /**\n     * Get the commands on the blueprint.\n     *\n     * @return \\Illuminate\\Support\\Fluent[]\n     */\n    public function getCommands()\n    {\n        return $this->commands;\n    }\n\n    /**\n     * Determine if the blueprint has state.\n     *\n     * @return bool\n     */\n    private function hasState(): bool\n    {\n        return ! is_null($this->state);\n    }\n\n    /**\n     * Get the state of the blueprint.\n     *\n     * @return \\Illuminate\\Database\\Schema\\BlueprintState\n     */\n    public function getState()\n    {\n        return $this->state;\n    }\n\n    /**\n     * Get the columns on the blueprint that should be added.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    public function getAddedColumns()\n    {\n        return array_filter($this->columns, function ($column) {\n            return ! $column->change;\n        });\n    }\n\n    /**\n     * Get the columns on the blueprint that should be changed.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    public function getChangedColumns()\n    {\n        return array_filter($this->columns, function ($column) {\n            return (bool) $column->change;\n        });\n    }\n\n    /**\n     * Get the default time precision.\n     */\n    protected function defaultTimePrecision(): ?int\n    {\n        return $this->connection->getSchemaBuilder()::$defaultTimePrecision;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/BlueprintState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Str;\n\nclass BlueprintState\n{\n    /**\n     * The blueprint instance.\n     *\n     * @var \\Illuminate\\Database\\Schema\\Blueprint\n     */\n    protected $blueprint;\n\n    /**\n     * The connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * The columns.\n     *\n     * @var \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    private $columns;\n\n    /**\n     * The primary key.\n     *\n     * @var \\Illuminate\\Database\\Schema\\IndexDefinition|null\n     */\n    private $primaryKey;\n\n    /**\n     * The indexes.\n     *\n     * @var \\Illuminate\\Database\\Schema\\IndexDefinition[]\n     */\n    private $indexes;\n\n    /**\n     * The foreign keys.\n     *\n     * @var \\Illuminate\\Database\\Schema\\ForeignKeyDefinition[]\n     */\n    private $foreignKeys;\n\n    /**\n     * Create a new blueprint state instance.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     */\n    public function __construct(Blueprint $blueprint, Connection $connection)\n    {\n        $this->blueprint = $blueprint;\n        $this->connection = $connection;\n\n        $schema = $connection->getSchemaBuilder();\n        $table = $blueprint->getTable();\n\n        $this->columns = (new Collection($schema->getColumns($table)))->map(fn ($column) => new ColumnDefinition([\n            'name' => $column['name'],\n            'type' => $column['type_name'],\n            'full_type_definition' => $column['type'],\n            'nullable' => $column['nullable'],\n            'default' => is_null($column['default']) ? null : new Expression(Str::wrap($column['default'], '(', ')')),\n            'autoIncrement' => $column['auto_increment'],\n            'collation' => $column['collation'],\n            'comment' => $column['comment'],\n            'virtualAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'virtual'\n                ? $column['generation']['expression']\n                : null,\n            'storedAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'stored'\n                ? $column['generation']['expression']\n                : null,\n        ]))->all();\n\n        [$primary, $indexes] = (new Collection($schema->getIndexes($table)))->map(fn ($index) => new IndexDefinition([\n            'name' => match (true) {\n                $index['primary'] => 'primary',\n                $index['unique'] => 'unique',\n                default => 'index',\n            },\n            'index' => $index['name'],\n            'columns' => $index['columns'],\n        ]))->partition(fn ($index) => $index->name === 'primary');\n\n        $this->indexes = $indexes->all();\n        $this->primaryKey = $primary->first();\n\n        $this->foreignKeys = (new Collection($schema->getForeignKeys($table)))->map(fn ($foreignKey) => new ForeignKeyDefinition([\n            'columns' => $foreignKey['columns'],\n            'on' => new Expression($foreignKey['foreign_table']),\n            'references' => $foreignKey['foreign_columns'],\n            'onUpdate' => $foreignKey['on_update'],\n            'onDelete' => $foreignKey['on_delete'],\n        ]))->all();\n    }\n\n    /**\n     * Get the primary key.\n     *\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition|null\n     */\n    public function getPrimaryKey()\n    {\n        return $this->primaryKey;\n    }\n\n    /**\n     * Get the columns.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ColumnDefinition[]\n     */\n    public function getColumns()\n    {\n        return $this->columns;\n    }\n\n    /**\n     * Get the indexes.\n     *\n     * @return \\Illuminate\\Database\\Schema\\IndexDefinition[]\n     */\n    public function getIndexes()\n    {\n        return $this->indexes;\n    }\n\n    /**\n     * Get the foreign keys.\n     *\n     * @return \\Illuminate\\Database\\Schema\\ForeignKeyDefinition[]\n     */\n    public function getForeignKeys()\n    {\n        return $this->foreignKeys;\n    }\n\n    /*\n     * Update the blueprint's state.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return void\n     */\n    public function update(Fluent $command)\n    {\n        switch ($command->name) {\n            case 'alter':\n                // Already handled...\n                break;\n\n            case 'add':\n                $this->columns[] = $command->column;\n                break;\n\n            case 'change':\n                foreach ($this->columns as &$column) {\n                    if ($column->name === $command->column->name) {\n                        $column = $command->column;\n                        break;\n                    }\n                }\n\n                break;\n\n            case 'renameColumn':\n                foreach ($this->columns as $column) {\n                    if ($column->name === $command->from) {\n                        $column->name = $command->to;\n                        break;\n                    }\n                }\n\n                if ($this->primaryKey) {\n                    $this->primaryKey->columns = str_replace($command->from, $command->to, $this->primaryKey->columns);\n                }\n\n                foreach ($this->indexes as $index) {\n                    $index->columns = str_replace($command->from, $command->to, $index->columns);\n                }\n\n                foreach ($this->foreignKeys as $foreignKey) {\n                    $foreignKey->columns = str_replace($command->from, $command->to, $foreignKey->columns);\n                }\n\n                break;\n\n            case 'dropColumn':\n                $this->columns = array_values(\n                    array_filter($this->columns, fn ($column) => ! in_array($column->name, $command->columns))\n                );\n\n                break;\n\n            case 'primary':\n                $this->primaryKey = $command;\n                break;\n\n            case 'unique':\n            case 'index':\n                $this->indexes[] = $command;\n                break;\n\n            case 'renameIndex':\n                foreach ($this->indexes as $index) {\n                    if ($index->index === $command->from) {\n                        $index->index = $command->to;\n                        break;\n                    }\n                }\n\n                break;\n\n            case 'foreign':\n                $this->foreignKeys[] = $command;\n                break;\n\n            case 'dropPrimary':\n                $this->primaryKey = null;\n                break;\n\n            case 'dropIndex':\n            case 'dropUnique':\n                $this->indexes = array_values(\n                    array_filter($this->indexes, fn ($index) => $index->index !== $command->index)\n                );\n\n                break;\n\n            case 'dropForeign':\n                $this->foreignKeys = array_values(\n                    array_filter($this->foreignKeys, fn ($fk) => $fk->columns !== $command->columns)\n                );\n\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Builder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse LogicException;\nuse RuntimeException;\n\nclass Builder\n{\n    use Macroable;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * The schema grammar instance.\n     *\n     * @var \\Illuminate\\Database\\Schema\\Grammars\\Grammar\n     */\n    protected $grammar;\n\n    /**\n     * The Blueprint resolver callback.\n     *\n     * @var \\Closure(\\Illuminate\\Database\\Connection, string, \\Closure|null): \\Illuminate\\Database\\Schema\\Blueprint\n     */\n    protected $resolver;\n\n    /**\n     * The default string length for migrations.\n     *\n     * @var non-negative-int|null\n     */\n    public static $defaultStringLength = 255;\n\n    /**\n     * The default time precision for migrations.\n     */\n    public static ?int $defaultTimePrecision = 0;\n\n    /**\n     * The default relationship morph key type.\n     *\n     * @var 'int'|'uuid'|'ulid'\n     */\n    public static $defaultMorphKeyType = 'int';\n\n    /**\n     * Create a new database Schema manager.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     */\n    public function __construct(Connection $connection)\n    {\n        $this->connection = $connection;\n        $this->grammar = $connection->getSchemaGrammar();\n    }\n\n    /**\n     * Set the default string length for migrations.\n     *\n     * @param  non-negative-int  $length\n     * @return void\n     */\n    public static function defaultStringLength($length)\n    {\n        static::$defaultStringLength = $length;\n    }\n\n    /**\n     * Set the default time precision for migrations.\n     */\n    public static function defaultTimePrecision(?int $precision): void\n    {\n        static::$defaultTimePrecision = $precision;\n    }\n\n    /**\n     * Set the default morph key type for migrations.\n     *\n     * @param  string  $type\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function defaultMorphKeyType(string $type)\n    {\n        if (! in_array($type, ['int', 'uuid', 'ulid'])) {\n            throw new InvalidArgumentException(\"Morph key type must be 'int', 'uuid', or 'ulid'.\");\n        }\n\n        static::$defaultMorphKeyType = $type;\n    }\n\n    /**\n     * Set the default morph key type for migrations to UUIDs.\n     *\n     * @return void\n     */\n    public static function morphUsingUuids()\n    {\n        static::defaultMorphKeyType('uuid');\n    }\n\n    /**\n     * Set the default morph key type for migrations to ULIDs.\n     *\n     * @return void\n     */\n    public static function morphUsingUlids()\n    {\n        static::defaultMorphKeyType('ulid');\n    }\n\n    /**\n     * Create a database in the schema.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function createDatabase($name)\n    {\n        return $this->connection->statement(\n            $this->grammar->compileCreateDatabase($name)\n        );\n    }\n\n    /**\n     * Drop a database from the schema if the database exists.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function dropDatabaseIfExists($name)\n    {\n        return $this->connection->statement(\n            $this->grammar->compileDropDatabaseIfExists($name)\n        );\n    }\n\n    /**\n     * Get the schemas that belong to the connection.\n     *\n     * @return list<array{name: string, path: string|null, default: bool}>\n     */\n    public function getSchemas()\n    {\n        return $this->connection->getPostProcessor()->processSchemas(\n            $this->connection->selectFromWriteConnection($this->grammar->compileSchemas())\n        );\n    }\n\n    /**\n     * Determine if the given table exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    public function hasTable($table)\n    {\n        [$schema, $table] = $this->parseSchemaAndTable($table);\n\n        $table = $this->connection->getTablePrefix().$table;\n\n        if ($sql = $this->grammar->compileTableExists($schema, $table)) {\n            return (bool) $this->connection->scalar($sql);\n        }\n\n        foreach ($this->getTables($schema ?? $this->getCurrentSchemaName()) as $value) {\n            if (strtolower($table) === strtolower($value['name'])) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the given view exists.\n     *\n     * @param  string  $view\n     * @return bool\n     */\n    public function hasView($view)\n    {\n        [$schema, $view] = $this->parseSchemaAndTable($view);\n\n        $view = $this->connection->getTablePrefix().$view;\n\n        foreach ($this->getViews($schema ?? $this->getCurrentSchemaName()) as $value) {\n            if (strtolower($view) === strtolower($value['name'])) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the tables that belong to the connection.\n     *\n     * @param  string|string[]|null  $schema\n     * @return list<array{name: string, schema: string|null, schema_qualified_name: string, size: int|null, comment: string|null, collation: string|null, engine: string|null}>\n     */\n    public function getTables($schema = null)\n    {\n        return $this->connection->getPostProcessor()->processTables(\n            $this->connection->selectFromWriteConnection($this->grammar->compileTables($schema))\n        );\n    }\n\n    /**\n     * Get the names of the tables that belong to the connection.\n     *\n     * @param  string|string[]|null  $schema\n     * @param  bool  $schemaQualified\n     * @return list<string>\n     */\n    public function getTableListing($schema = null, $schemaQualified = true)\n    {\n        return array_column(\n            $this->getTables($schema),\n            $schemaQualified ? 'schema_qualified_name' : 'name'\n        );\n    }\n\n    /**\n     * Get the views that belong to the connection.\n     *\n     * @param  string|string[]|null  $schema\n     * @return list<array{name: string, schema: string|null, schema_qualified_name: string, definition: string}>\n     */\n    public function getViews($schema = null)\n    {\n        return $this->connection->getPostProcessor()->processViews(\n            $this->connection->selectFromWriteConnection($this->grammar->compileViews($schema))\n        );\n    }\n\n    /**\n     * Get the user-defined types that belong to the connection.\n     *\n     * @param  string|string[]|null  $schema\n     * @return list<array{name: string, schema: string, type: string, type: string, category: string, implicit: bool}>\n     */\n    public function getTypes($schema = null)\n    {\n        return $this->connection->getPostProcessor()->processTypes(\n            $this->connection->selectFromWriteConnection($this->grammar->compileTypes($schema))\n        );\n    }\n\n    /**\n     * Determine if the given table has a given column.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @return bool\n     */\n    public function hasColumn($table, $column)\n    {\n        return in_array(\n            strtolower($column), array_map(strtolower(...), $this->getColumnListing($table))\n        );\n    }\n\n    /**\n     * Determine if the given table has given columns.\n     *\n     * @param  string  $table\n     * @param  array<string>  $columns\n     * @return bool\n     */\n    public function hasColumns($table, array $columns)\n    {\n        $tableColumns = array_map(strtolower(...), $this->getColumnListing($table));\n\n        foreach ($columns as $column) {\n            if (! in_array(strtolower($column), $tableColumns)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Execute a table builder callback if the given table has a given column.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function whenTableHasColumn(string $table, string $column, Closure $callback)\n    {\n        if ($this->hasColumn($table, $column)) {\n            $this->table($table, fn (Blueprint $table) => $callback($table));\n        }\n    }\n\n    /**\n     * Execute a table builder callback if the given table doesn't have a given column.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function whenTableDoesntHaveColumn(string $table, string $column, Closure $callback)\n    {\n        if (! $this->hasColumn($table, $column)) {\n            $this->table($table, fn (Blueprint $table) => $callback($table));\n        }\n    }\n\n    /**\n     * Execute a table builder callback if the given table has a given index.\n     *\n     * @param  string  $table\n     * @param  string|array  $index\n     * @param  \\Closure  $callback\n     * @param  string|null  $type\n     * @return void\n     */\n    public function whenTableHasIndex(string $table, string|array $index, Closure $callback, ?string $type = null)\n    {\n        if ($this->hasIndex($table, $index, $type)) {\n            $this->table($table, fn (Blueprint $table) => $callback($table));\n        }\n    }\n\n    /**\n     * Execute a table builder callback if the given table doesn't have a given index.\n     *\n     * @param  string  $table\n     * @param  string|array  $index\n     * @param  \\Closure  $callback\n     * @param  string|null  $type\n     * @return void\n     */\n    public function whenTableDoesntHaveIndex(string $table, string|array $index, Closure $callback, ?string $type = null)\n    {\n        if (! $this->hasIndex($table, $index, $type)) {\n            $this->table($table, fn (Blueprint $table) => $callback($table));\n        }\n    }\n\n    /**\n     * Get the data type for the given column name.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @param  bool  $fullDefinition\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function getColumnType($table, $column, $fullDefinition = false)\n    {\n        $columns = $this->getColumns($table);\n\n        foreach ($columns as $value) {\n            if (strtolower($value['name']) === strtolower($column)) {\n                return $fullDefinition ? $value['type'] : $value['type_name'];\n            }\n        }\n\n        throw new InvalidArgumentException(\"There is no column with name '$column' on table '$table'.\");\n    }\n\n    /**\n     * Get the column listing for a given table.\n     *\n     * @param  string  $table\n     * @return list<string>\n     */\n    public function getColumnListing($table)\n    {\n        return array_column($this->getColumns($table), 'name');\n    }\n\n    /**\n     * Get the columns for a given table.\n     *\n     * @param  string  $table\n     * @return list<array{name: string, type: string, type_name: string, nullable: bool, default: mixed, auto_increment: bool, comment: string|null, generation: array{type: string, expression: string|null}|null}>\n     */\n    public function getColumns($table)\n    {\n        [$schema, $table] = $this->parseSchemaAndTable($table);\n\n        $table = $this->connection->getTablePrefix().$table;\n\n        return $this->connection->getPostProcessor()->processColumns(\n            $this->connection->selectFromWriteConnection(\n                $this->grammar->compileColumns($schema, $table)\n            )\n        );\n    }\n\n    /**\n     * Get the indexes for a given table.\n     *\n     * @param  string  $table\n     * @return list<array{name: string, columns: list<string>, type: string, unique: bool, primary: bool}>\n     */\n    public function getIndexes($table)\n    {\n        [$schema, $table] = $this->parseSchemaAndTable($table);\n\n        $table = $this->connection->getTablePrefix().$table;\n\n        return $this->connection->getPostProcessor()->processIndexes(\n            $this->connection->selectFromWriteConnection(\n                $this->grammar->compileIndexes($schema, $table)\n            )\n        );\n    }\n\n    /**\n     * Get the names of the indexes for a given table.\n     *\n     * @param  string  $table\n     * @return list<string>\n     */\n    public function getIndexListing($table)\n    {\n        return array_column($this->getIndexes($table), 'name');\n    }\n\n    /**\n     * Determine if the given table has a given index.\n     *\n     * @param  string  $table\n     * @param  string|array  $index\n     * @param  string|null  $type\n     * @return bool\n     */\n    public function hasIndex($table, $index, $type = null)\n    {\n        $type = is_null($type) ? $type : strtolower($type);\n\n        foreach ($this->getIndexes($table) as $value) {\n            $typeMatches = is_null($type)\n                || ($type === 'primary' && $value['primary'])\n                || ($type === 'unique' && $value['unique'])\n                || $type === $value['type'];\n\n            if (($value['name'] === $index || $value['columns'] === $index) && $typeMatches) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the foreign keys for a given table.\n     *\n     * @param  string  $table\n     * @return array\n     */\n    public function getForeignKeys($table)\n    {\n        [$schema, $table] = $this->parseSchemaAndTable($table);\n\n        $table = $this->connection->getTablePrefix().$table;\n\n        return $this->connection->getPostProcessor()->processForeignKeys(\n            $this->connection->selectFromWriteConnection(\n                $this->grammar->compileForeignKeys($schema, $table)\n            )\n        );\n    }\n\n    /**\n     * Modify a table on the schema.\n     *\n     * @param  string  $table\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function table($table, Closure $callback)\n    {\n        $this->build($this->createBlueprint($table, $callback));\n    }\n\n    /**\n     * Create a new table on the schema.\n     *\n     * @param  string  $table\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function create($table, Closure $callback)\n    {\n        $this->build(tap($this->createBlueprint($table), function ($blueprint) use ($callback) {\n            $blueprint->create();\n\n            $callback($blueprint);\n        }));\n    }\n\n    /**\n     * Drop a table from the schema.\n     *\n     * @param  string  $table\n     * @return void\n     */\n    public function drop($table)\n    {\n        $this->build(tap($this->createBlueprint($table), function ($blueprint) {\n            $blueprint->drop();\n        }));\n    }\n\n    /**\n     * Drop a table from the schema if it exists.\n     *\n     * @param  string  $table\n     * @return void\n     */\n    public function dropIfExists($table)\n    {\n        $this->build(tap($this->createBlueprint($table), function ($blueprint) {\n            $blueprint->dropIfExists();\n        }));\n    }\n\n    /**\n     * Drop columns from a table schema.\n     *\n     * @param  string  $table\n     * @param  string|array<string>  $columns\n     * @return void\n     */\n    public function dropColumns($table, $columns)\n    {\n        $this->table($table, function (Blueprint $blueprint) use ($columns) {\n            $blueprint->dropColumn($columns);\n        });\n    }\n\n    /**\n     * Drop all tables from the database.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function dropAllTables()\n    {\n        throw new LogicException('This database driver does not support dropping all tables.');\n    }\n\n    /**\n     * Drop all views from the database.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function dropAllViews()\n    {\n        throw new LogicException('This database driver does not support dropping all views.');\n    }\n\n    /**\n     * Drop all types from the database.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function dropAllTypes()\n    {\n        throw new LogicException('This database driver does not support dropping all types.');\n    }\n\n    /**\n     * Rename a table on the schema.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return void\n     */\n    public function rename($from, $to)\n    {\n        $this->build(tap($this->createBlueprint($from), function ($blueprint) use ($to) {\n            $blueprint->rename($to);\n        }));\n    }\n\n    /**\n     * Enable foreign key constraints.\n     *\n     * @return bool\n     */\n    public function enableForeignKeyConstraints()\n    {\n        return $this->connection->statement(\n            $this->grammar->compileEnableForeignKeyConstraints()\n        );\n    }\n\n    /**\n     * Disable foreign key constraints.\n     *\n     * @return bool\n     */\n    public function disableForeignKeyConstraints()\n    {\n        return $this->connection->statement(\n            $this->grammar->compileDisableForeignKeyConstraints()\n        );\n    }\n\n    /**\n     * Disable foreign key constraints during the execution of a callback.\n     *\n     * @template TReturn\n     *\n     * @param  (\\Closure(): TReturn)  $callback\n     * @return TReturn\n     */\n    public function withoutForeignKeyConstraints(Closure $callback)\n    {\n        $this->disableForeignKeyConstraints();\n\n        try {\n            return $callback();\n        } finally {\n            $this->enableForeignKeyConstraints();\n        }\n    }\n\n    /**\n     * Create the vector extension on the schema if it does not exist.\n     *\n     * @param  string|null  $schema\n     * @return void\n     */\n    public function ensureVectorExtensionExists($schema = null)\n    {\n        $this->ensureExtensionExists('vector', $schema);\n    }\n\n    /**\n     * Create a new extension on the schema if it does not exist.\n     *\n     * @param  string  $name\n     * @param  string|null  $schema\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function ensureExtensionExists($name, $schema = null)\n    {\n        if (! $this->getConnection() instanceof PostgresConnection) {\n            throw new RuntimeException('Extensions are only supported by Postgres.');\n        }\n\n        $name = $this->getConnection()->getSchemaGrammar()->wrap($name);\n\n        $this->getConnection()->statement(match (filled($schema)) {\n            true => \"create extension if not exists {$name} schema {$this->getConnection()->getSchemaGrammar()->wrap($schema)}\",\n            false => \"create extension if not exists {$name}\",\n        });\n    }\n\n    /**\n     * Execute the blueprint to build / modify the table.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @return void\n     */\n    protected function build(Blueprint $blueprint)\n    {\n        $blueprint->build();\n    }\n\n    /**\n     * Create a new command set with a Closure.\n     *\n     * @param  string  $table\n     * @param  \\Closure|null  $callback\n     * @return \\Illuminate\\Database\\Schema\\Blueprint\n     */\n    protected function createBlueprint($table, ?Closure $callback = null)\n    {\n        $connection = $this->connection;\n\n        if (isset($this->resolver)) {\n            return call_user_func($this->resolver, $connection, $table, $callback);\n        }\n\n        return Container::getInstance()->make(Blueprint::class, compact('connection', 'table', 'callback'));\n    }\n\n    /**\n     * Get the names of the current schemas for the connection.\n     *\n     * @return string[]|null\n     */\n    public function getCurrentSchemaListing()\n    {\n        return null;\n    }\n\n    /**\n     * Get the default schema name for the connection.\n     *\n     * @return string|null\n     */\n    public function getCurrentSchemaName()\n    {\n        return $this->getCurrentSchemaListing()[0] ?? null;\n    }\n\n    /**\n     * Parse the given database object reference and extract the schema and table.\n     *\n     * @param  string  $reference\n     * @param  string|bool|null  $withDefaultSchema\n     * @return array{string|null, string}\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function parseSchemaAndTable($reference, $withDefaultSchema = null)\n    {\n        $segments = explode('.', $reference);\n\n        if (count($segments) > 2) {\n            throw new InvalidArgumentException(\n                \"Using three-part references is not supported, you may use `Schema::connection('{$segments[0]}')` instead.\"\n            );\n        }\n\n        $table = $segments[1] ?? $segments[0];\n\n        $schema = match (true) {\n            isset($segments[1]) => $segments[0],\n            is_string($withDefaultSchema) => $withDefaultSchema,\n            $withDefaultSchema => $this->getCurrentSchemaName(),\n            default => null,\n        };\n\n        return [$schema, $table];\n    }\n\n    /**\n     * Get the database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * Set the Schema Blueprint resolver callback.\n     *\n     * @param  \\Closure(\\Illuminate\\Database\\Connection, string, \\Closure|null): \\Illuminate\\Database\\Schema\\Blueprint  $resolver\n     * @return void\n     */\n    public function blueprintResolver(Closure $resolver)\n    {\n        $this->resolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/ColumnDefinition.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Support\\Fluent;\n\n/**\n * @method $this after(string $column) Place the column \"after\" another column (MySQL)\n * @method $this always(bool $value = true) Used as a modifier for generatedAs() (PostgreSQL)\n * @method $this autoIncrement() Set INTEGER columns as auto-increment (primary key)\n * @method $this change() Change the column\n * @method $this charset(string $charset) Specify a character set for the column (MySQL)\n * @method $this collation(string $collation) Specify a collation for the column\n * @method $this comment(string $comment) Add a comment to the column (MySQL/PostgreSQL)\n * @method $this default(mixed $value) Specify a \"default\" value for the column\n * @method $this first() Place the column \"first\" in the table (MySQL)\n * @method $this from(int $startingValue) Set the starting value of an auto-incrementing field (MySQL/PostgreSQL)\n * @method $this fulltext(bool|string $indexName = null) Add a fulltext index\n * @method $this generatedAs(string|\\Illuminate\\Contracts\\Database\\Query\\Expression $expression = null) Create a SQL compliant identity column (PostgreSQL)\n * @method $this instant() Specify that algorithm=instant should be used for the column operation (MySQL)\n * @method $this index(bool|string $indexName = null) Add an index\n * @method $this invisible() Specify that the column should be invisible to \"SELECT *\" (MySQL)\n * @method $this lock(('none'|'shared'|'default'|'exclusive') $value) Specify the DDL lock mode for the column operation (MySQL)\n * @method $this nullable(bool $value = true) Allow NULL values to be inserted into the column\n * @method $this persisted() Mark the computed generated column as persistent (SQL Server)\n * @method $this primary(bool $value = true) Add a primary index\n * @method $this spatialIndex(bool|string $indexName = null) Add a spatial index\n * @method $this vectorIndex(bool|string $indexName = null) Add a vector index\n * @method $this startingValue(int $startingValue) Set the starting value of an auto-incrementing field (MySQL/PostgreSQL)\n * @method $this storedAs(string|\\Illuminate\\Contracts\\Database\\Query\\Expression $expression) Create a stored generated column (MySQL/PostgreSQL/SQLite)\n * @method $this type(string $type) Specify a type for the column\n * @method $this unique(bool|string $indexName = null) Add a unique index\n * @method $this unsigned() Set the INTEGER column as UNSIGNED (MySQL)\n * @method $this useCurrent() Set the TIMESTAMP column to use CURRENT_TIMESTAMP as default value\n * @method $this useCurrentOnUpdate() Set the TIMESTAMP column to use CURRENT_TIMESTAMP when updating (MySQL)\n * @method $this virtualAs(string|\\Illuminate\\Contracts\\Database\\Query\\Expression $expression) Create a virtual generated column (MySQL/PostgreSQL/SQLite)\n */\nclass ColumnDefinition extends Fluent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/ForeignIdColumnDefinition.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Support\\Stringable;\n\nclass ForeignIdColumnDefinition extends ColumnDefinition\n{\n    /**\n     * The schema builder blueprint instance.\n     *\n     * @var \\Illuminate\\Database\\Schema\\Blueprint\n     */\n    protected $blueprint;\n\n    /**\n     * Create a new foreign ID column definition.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  array  $attributes\n     */\n    public function __construct(Blueprint $blueprint, $attributes = [])\n    {\n        parent::__construct($attributes);\n\n        $this->blueprint = $blueprint;\n    }\n\n    /**\n     * Create a foreign key constraint on this column referencing the \"id\" column of the conventionally related table.\n     *\n     * @param  string|null  $table\n     * @param  string|null  $column\n     * @param  string|null  $indexName\n     * @return \\Illuminate\\Database\\Schema\\ForeignKeyDefinition\n     */\n    public function constrained($table = null, $column = null, $indexName = null)\n    {\n        $table ??= $this->table;\n        $column ??= $this->referencesModelColumn ?? 'id';\n\n        return $this->references($column, $indexName)->on($table ?? (new Stringable($this->name))->beforeLast('_'.$column)->plural());\n    }\n\n    /**\n     * Specify which column this foreign ID references on another table.\n     *\n     * @param  string  $column\n     * @param  string|null  $indexName\n     * @return \\Illuminate\\Database\\Schema\\ForeignKeyDefinition\n     */\n    public function references($column, $indexName = null)\n    {\n        return $this->blueprint->foreign($this->name, $indexName)->references($column);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/ForeignKeyDefinition.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Support\\Fluent;\n\n/**\n * @method ForeignKeyDefinition deferrable(bool $value = true) Set the foreign key as deferrable (PostgreSQL)\n * @method ForeignKeyDefinition initiallyImmediate(bool $value = true) Set the default time to check the constraint (PostgreSQL)\n * @method ForeignKeyDefinition lock(('none'|'shared'|'default'|'exclusive') $value) Specify the DDL lock mode for the foreign key operation (MySQL)\n * @method ForeignKeyDefinition on(string $table) Specify the referenced table\n * @method ForeignKeyDefinition onDelete(('cascade'|'restrict'|'set null'|'no action') $action) Add an ON DELETE action\n * @method ForeignKeyDefinition onUpdate(('cascade'|'restrict'|'set null'|'no action') $action) Add an ON UPDATE action\n * @method ForeignKeyDefinition references(string|string[] $columns) Specify the referenced column(s)\n */\nclass ForeignKeyDefinition extends Fluent\n{\n    /**\n     * Indicate that updates should cascade.\n     *\n     * @return $this\n     */\n    public function cascadeOnUpdate()\n    {\n        return $this->onUpdate('cascade');\n    }\n\n    /**\n     * Indicate that updates should be restricted.\n     *\n     * @return $this\n     */\n    public function restrictOnUpdate()\n    {\n        return $this->onUpdate('restrict');\n    }\n\n    /**\n     * Indicate that updates should set the foreign key value to null.\n     *\n     * @return $this\n     */\n    public function nullOnUpdate()\n    {\n        return $this->onUpdate('set null');\n    }\n\n    /**\n     * Indicate that updates should have \"no action\".\n     *\n     * @return $this\n     */\n    public function noActionOnUpdate()\n    {\n        return $this->onUpdate('no action');\n    }\n\n    /**\n     * Indicate that deletes should cascade.\n     *\n     * @return $this\n     */\n    public function cascadeOnDelete()\n    {\n        return $this->onDelete('cascade');\n    }\n\n    /**\n     * Indicate that deletes should be restricted.\n     *\n     * @return $this\n     */\n    public function restrictOnDelete()\n    {\n        return $this->onDelete('restrict');\n    }\n\n    /**\n     * Indicate that deletes should set the foreign key value to null.\n     *\n     * @return $this\n     */\n    public function nullOnDelete()\n    {\n        return $this->onDelete('set null');\n    }\n\n    /**\n     * Indicate that deletes should have \"no action\".\n     *\n     * @return $this\n     */\n    public function noActionOnDelete()\n    {\n        return $this->onDelete('no action');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/Grammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Concerns\\CompilesJsonPaths;\nuse Illuminate\\Database\\Grammar as BaseGrammar;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fluent;\nuse RuntimeException;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\nabstract class Grammar extends BaseGrammar\n{\n    use CompilesJsonPaths;\n\n    /**\n     * The possible column modifiers.\n     *\n     * @var string[]\n     */\n    protected $modifiers = [];\n\n    /**\n     * If this Grammar supports schema changes wrapped in a transaction.\n     *\n     * @var bool\n     */\n    protected $transactions = false;\n\n    /**\n     * The commands to be executed outside of create or alter command.\n     *\n     * @var array\n     */\n    protected $fluentCommands = [];\n\n    /**\n     * Compile a create database command.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileCreateDatabase($name)\n    {\n        return sprintf('create database %s',\n            $this->wrapValue($name),\n        );\n    }\n\n    /**\n     * Compile a drop database if exists command.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileDropDatabaseIfExists($name)\n    {\n        return sprintf('drop database if exists %s',\n            $this->wrapValue($name)\n        );\n    }\n\n    /**\n     * Compile the query to determine the schemas.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileSchemas()\n    {\n        throw new RuntimeException('This database driver does not support retrieving schemas.');\n    }\n\n    /**\n     * Compile the query to determine if the given table exists.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string|null\n     */\n    public function compileTableExists($schema, $table)\n    {\n        //\n    }\n\n    /**\n     * Compile the query to determine the tables.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileTables($schema)\n    {\n        throw new RuntimeException('This database driver does not support retrieving tables.');\n    }\n\n    /**\n     * Compile the query to determine the views.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileViews($schema)\n    {\n        throw new RuntimeException('This database driver does not support retrieving views.');\n    }\n\n    /**\n     * Compile the query to determine the user-defined types.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileTypes($schema)\n    {\n        throw new RuntimeException('This database driver does not support retrieving user-defined types.');\n    }\n\n    /**\n     * Compile the query to determine the columns.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileColumns($schema, $table)\n    {\n        throw new RuntimeException('This database driver does not support retrieving columns.');\n    }\n\n    /**\n     * Compile the query to determine the indexes.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileIndexes($schema, $table)\n    {\n        throw new RuntimeException('This database driver does not support retrieving indexes.');\n    }\n\n    /**\n     * Compile a vector index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileVectorIndex(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('The database driver in use does not support vector indexes.');\n    }\n\n    /**\n     * Compile the query to determine the foreign keys.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileForeignKeys($schema, $table)\n    {\n        throw new RuntimeException('This database driver does not support retrieving foreign keys.');\n    }\n\n    /**\n     * Compile a rename column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return list<string>|string\n     */\n    public function compileRenameColumn(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s rename column %s to %s',\n            $this->wrapTable($blueprint),\n            $this->wrap($command->from),\n            $this->wrap($command->to)\n        );\n    }\n\n    /**\n     * Compile a change column command into a series of SQL statements.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return list<string>|string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileChange(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('This database driver does not support modifying columns.');\n    }\n\n    /**\n     * Compile a fulltext index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileFulltext(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('This database driver does not support fulltext index creation.');\n    }\n\n    /**\n     * Compile a drop fulltext index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileDropFullText(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('This database driver does not support fulltext index removal.');\n    }\n\n    /**\n     * Compile a foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileForeign(Blueprint $blueprint, Fluent $command)\n    {\n        // We need to prepare several of the elements of the foreign key definition\n        // before we can create the SQL, such as wrapping the tables and convert\n        // an array of columns to comma-delimited strings for the SQL queries.\n        $sql = sprintf('alter table %s add constraint %s ',\n            $this->wrapTable($blueprint),\n            $this->wrap($command->index)\n        );\n\n        // Once we have the initial portion of the SQL statement we will add on the\n        // key name, table name, and referenced columns. These will complete the\n        // main portion of the SQL statement and this SQL will almost be done.\n        $sql .= sprintf('foreign key (%s) references %s (%s)',\n            $this->columnize($command->columns),\n            $this->wrapTable($command->on),\n            $this->columnize((array) $command->references)\n        );\n\n        // Once we have the basic foreign key creation statement constructed we can\n        // build out the syntax for what should happen on an update or delete of\n        // the affected columns, which will get something like \"cascade\", etc.\n        if (! is_null($command->onDelete)) {\n            $sql .= \" on delete {$command->onDelete}\";\n        }\n\n        if (! is_null($command->onUpdate)) {\n            $sql .= \" on update {$command->onUpdate}\";\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a drop foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileDropForeign(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('This database driver does not support dropping foreign keys.');\n    }\n\n    /**\n     * Compile the blueprint's added column definitions.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @return array\n     */\n    protected function getColumns(Blueprint $blueprint)\n    {\n        $columns = [];\n\n        foreach ($blueprint->getAddedColumns() as $column) {\n            $columns[] = $this->getColumn($blueprint, $column);\n        }\n\n        return $columns;\n    }\n\n    /**\n     * Compile the column definition.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Database\\Schema\\ColumnDefinition  $column\n     * @return string\n     */\n    protected function getColumn(Blueprint $blueprint, $column)\n    {\n        // Each of the column types has their own compiler functions, which are tasked\n        // with turning the column definition into its SQL format for this platform\n        // used by the connection. The column's modifiers are compiled and added.\n        $sql = $this->wrap($column).' '.$this->getType($column);\n\n        return $this->addModifiers($sql, $blueprint, $column);\n    }\n\n    /**\n     * Get the SQL for the column data type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function getType(Fluent $column)\n    {\n        return $this->{'type'.ucfirst($column->type)}($column);\n    }\n\n    /**\n     * Create the column definition for a generated, computed column type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function typeComputed(Fluent $column)\n    {\n        throw new RuntimeException('This database driver does not support the computed type.');\n    }\n\n    /**\n     * Create the column definition for a vector type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function typeVector(Fluent $column)\n    {\n        throw new RuntimeException('This database driver does not support the vector type.');\n    }\n\n    /**\n     * Create the column definition for a tsvector type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function typeTsvector(Fluent $column)\n    {\n        throw new RuntimeException('This database driver does not support the tsvector type.');\n    }\n\n    /**\n     * Create the column definition for a raw column type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeRaw(Fluent $column)\n    {\n        return $column->offsetGet('definition');\n    }\n\n    /**\n     * Add the column modifiers to the definition.\n     *\n     * @param  string  $sql\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function addModifiers($sql, Blueprint $blueprint, Fluent $column)\n    {\n        foreach ($this->modifiers as $modifier) {\n            if (method_exists($this, $method = \"modify{$modifier}\")) {\n                $sql .= $this->{$method}($blueprint, $column);\n            }\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Get the command with a given name if it exists on the blueprint.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  string  $name\n     * @return \\Illuminate\\Support\\Fluent|null\n     */\n    protected function getCommandByName(Blueprint $blueprint, $name)\n    {\n        $commands = $this->getCommandsByName($blueprint, $name);\n\n        if (count($commands) > 0) {\n            return array_first($commands);\n        }\n    }\n\n    /**\n     * Get all of the commands with a given name.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  string  $name\n     * @return array\n     */\n    protected function getCommandsByName(Blueprint $blueprint, $name)\n    {\n        return array_filter($blueprint->getCommands(), function ($value) use ($name) {\n            return $value->name == $name;\n        });\n    }\n\n    /*\n     * Determine if a command with a given name exists on the blueprint.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  string  $name\n     * @return bool\n     */\n    protected function hasCommand(Blueprint $blueprint, $name)\n    {\n        foreach ($blueprint->getCommands() as $command) {\n            if ($command->name === $name) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Add a prefix to an array of values.\n     *\n     * @param  string  $prefix\n     * @param  array<string>  $values\n     * @return array<string>\n     */\n    public function prefixArray($prefix, array $values)\n    {\n        return array_map(function ($value) use ($prefix) {\n            return $prefix.' '.$value;\n        }, $values);\n    }\n\n    /**\n     * Wrap a table in keyword identifiers.\n     *\n     * @param  mixed  $table\n     * @param  string|null  $prefix\n     * @return string\n     */\n    public function wrapTable($table, $prefix = null)\n    {\n        return parent::wrapTable(\n            $table instanceof Blueprint ? $table->getTable() : $table,\n            $prefix\n        );\n    }\n\n    /**\n     * Wrap a value in keyword identifiers.\n     *\n     * @param  \\Illuminate\\Support\\Fluent|\\Illuminate\\Contracts\\Database\\Query\\Expression|string  $value\n     * @return string\n     */\n    public function wrap($value)\n    {\n        return parent::wrap(\n            $value instanceof Fluent ? $value->name : $value,\n        );\n    }\n\n    /**\n     * Format a value so that it can be used in \"default\" clauses.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function getDefaultValue($value)\n    {\n        if ($value instanceof Expression) {\n            return $this->getValue($value);\n        }\n\n        if ($value instanceof UnitEnum) {\n            return \"'\".str_replace(\"'\", \"''\", enum_value($value)).\"'\";\n        }\n\n        return is_bool($value)\n            ? \"'\".(int) $value.\"'\"\n            : \"'\".str_replace(\"'\", \"''\", $value).\"'\";\n    }\n\n    /**\n     * Get the fluent commands for the grammar.\n     *\n     * @return array\n     */\n    public function getFluentCommands()\n    {\n        return $this->fluentCommands;\n    }\n\n    /**\n     * Check if this Grammar supports schema changes wrapped in a transaction.\n     *\n     * @return bool\n     */\n    public function supportsSchemaTransactions()\n    {\n        return $this->transactions;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/MariaDbGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fluent;\n\nclass MariaDbGrammar extends MySqlGrammar\n{\n    /** @inheritDoc */\n    public function compileRenameColumn(Blueprint $blueprint, Fluent $command)\n    {\n        if (version_compare($this->connection->getServerVersion(), '10.5.2', '<')) {\n            return $this->compileLegacyRenameColumn($blueprint, $command);\n        }\n\n        return parent::compileRenameColumn($blueprint, $command);\n    }\n\n    /**\n     * Create the column definition for a uuid type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeUuid(Fluent $column)\n    {\n        if (version_compare($this->connection->getServerVersion(), '10.7.0', '<')) {\n            return 'char(36)';\n        }\n\n        return 'uuid';\n    }\n\n    /**\n     * Create the column definition for a spatial Geometry type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeometry(Fluent $column)\n    {\n        $subtype = $column->subtype ? strtolower($column->subtype) : null;\n\n        if (! in_array($subtype, ['point', 'linestring', 'polygon', 'geometrycollection', 'multipoint', 'multilinestring', 'multipolygon'])) {\n            $subtype = null;\n        }\n\n        return sprintf('%s%s',\n            $subtype ?? 'geometry',\n            $column->srid ? ' ref_system_id='.$column->srid : ''\n        );\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_value('.$field.$path.')';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\ColumnDefinition;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse RuntimeException;\n\nclass MySqlGrammar extends Grammar\n{\n    /**\n     * The possible column modifiers.\n     *\n     * @var string[]\n     */\n    protected $modifiers = [\n        'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable',\n        'Default', 'OnUpdate', 'Invisible', 'Increment', 'Comment', 'After', 'First',\n    ];\n\n    /**\n     * The possible column serials.\n     *\n     * @var string[]\n     */\n    protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];\n\n    /**\n     * The commands to be executed outside of create or alter commands.\n     *\n     * @var string[]\n     */\n    protected $fluentCommands = ['AutoIncrementStartingValues'];\n\n    /**\n     * Compile a create database command.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileCreateDatabase($name)\n    {\n        $sql = parent::compileCreateDatabase($name);\n\n        if ($charset = $this->connection->getConfig('charset')) {\n            $sql .= sprintf(' default character set %s', $this->wrapValue($charset));\n        }\n\n        if ($collation = $this->connection->getConfig('collation')) {\n            $sql .= sprintf(' default collate %s', $this->wrapValue($collation));\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile the query to determine the schemas.\n     *\n     * @return string\n     */\n    public function compileSchemas()\n    {\n        return 'select schema_name as name, schema_name = schema() as `default` from information_schema.schemata where '\n            .$this->compileSchemaWhereClause(null, 'schema_name')\n            .' order by schema_name';\n    }\n\n    /**\n     * Compile the query to determine if the given table exists.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileTableExists($schema, $table)\n    {\n        return sprintf(\n            'select exists (select 1 from information_schema.tables where '\n            .\"table_schema = %s and table_name = %s and table_type in ('BASE TABLE', 'SYSTEM VERSIONED')) as `exists`\",\n            $schema ? $this->quoteString($schema) : 'schema()',\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the tables.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileTables($schema)\n    {\n        return sprintf(\n            'select table_name as `name`, table_schema as `schema`, (data_length + index_length) as `size`, '\n            .'table_comment as `comment`, engine as `engine`, table_collation as `collation` '\n            .\"from information_schema.tables where table_type in ('BASE TABLE', 'SYSTEM VERSIONED') and \"\n            .$this->compileSchemaWhereClause($schema, 'table_schema')\n            .' order by table_schema, table_name',\n            $this->quoteString($schema)\n        );\n    }\n\n    /**\n     * Compile the query to determine the views.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileViews($schema)\n    {\n        return 'select table_name as `name`, table_schema as `schema`, view_definition as `definition` '\n            .'from information_schema.views where '\n            .$this->compileSchemaWhereClause($schema, 'table_schema')\n            .' order by table_schema, table_name';\n    }\n\n    /**\n     * Compile the query to compare the schema.\n     *\n     * @param  string|string[]|null  $schema\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileSchemaWhereClause($schema, $column)\n    {\n        return $column.(match (true) {\n            ! empty($schema) && is_array($schema) => ' in ('.$this->quoteString($schema).')',\n            ! empty($schema) => ' = '.$this->quoteString($schema),\n            default => \" not in ('information_schema', 'mysql', 'ndbinfo', 'performance_schema', 'sys')\",\n        });\n    }\n\n    /**\n     * Compile the query to determine the columns.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileColumns($schema, $table)\n    {\n        return sprintf(\n            'select column_name as `name`, data_type as `type_name`, column_type as `type`, '\n            .'collation_name as `collation`, is_nullable as `nullable`, '\n            .'column_default as `default`, column_comment as `comment`, '\n            .'generation_expression as `expression`, extra as `extra` '\n            .'from information_schema.columns where table_schema = %s and table_name = %s '\n            .'order by ordinal_position asc',\n            $schema ? $this->quoteString($schema) : 'schema()',\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the indexes.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileIndexes($schema, $table)\n    {\n        return sprintf(\n            'select index_name as `name`, group_concat(column_name order by seq_in_index) as `columns`, '\n            .'index_type as `type`, not non_unique as `unique` '\n            .'from information_schema.statistics where table_schema = %s and table_name = %s '\n            .'group by index_name, index_type, non_unique',\n            $schema ? $this->quoteString($schema) : 'schema()',\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the foreign keys.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileForeignKeys($schema, $table)\n    {\n        return sprintf(\n            'select kc.constraint_name as `name`, '\n            .'group_concat(kc.column_name order by kc.ordinal_position) as `columns`, '\n            .'kc.referenced_table_schema as `foreign_schema`, '\n            .'kc.referenced_table_name as `foreign_table`, '\n            .'group_concat(kc.referenced_column_name order by kc.ordinal_position) as `foreign_columns`, '\n            .'rc.update_rule as `on_update`, '\n            .'rc.delete_rule as `on_delete` '\n            .'from information_schema.key_column_usage kc join information_schema.referential_constraints rc '\n            .'on kc.constraint_schema = rc.constraint_schema and kc.constraint_name = rc.constraint_name '\n            .'where kc.table_schema = %s and kc.table_name = %s and kc.referenced_table_name is not null '\n            .'group by kc.constraint_name, kc.referenced_table_schema, kc.referenced_table_name, rc.update_rule, rc.delete_rule',\n            $schema ? $this->quoteString($schema) : 'schema()',\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile a create table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileCreate(Blueprint $blueprint, Fluent $command)\n    {\n        $sql = $this->compileCreateTable(\n            $blueprint, $command\n        );\n\n        // Once we have the primary SQL, we can add the encoding option to the SQL for\n        // the table.  Then, we can check if a storage engine has been supplied for\n        // the table. If so, we will add the engine declaration to the SQL query.\n        $sql = $this->compileCreateEncoding(\n            $sql, $blueprint\n        );\n\n        // Finally, we will append the engine configuration onto this SQL statement as\n        // the final thing we do before returning this finished SQL. Once this gets\n        // added the query will be ready to execute against the real connections.\n        return $this->compileCreateEngine($sql, $blueprint);\n    }\n\n    /**\n     * Create the main create table clause.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    protected function compileCreateTable($blueprint, $command)\n    {\n        $tableStructure = $this->getColumns($blueprint);\n\n        if ($primaryKey = $this->getCommandByName($blueprint, 'primary')) {\n            $tableStructure[] = sprintf(\n                'primary key %s(%s)',\n                $primaryKey->algorithm ? 'using '.$primaryKey->algorithm : '',\n                $this->columnize($primaryKey->columns)\n            );\n\n            $primaryKey->shouldBeSkipped = true;\n        }\n\n        return sprintf('%s table %s (%s)',\n            $blueprint->temporary ? 'create temporary' : 'create',\n            $this->wrapTable($blueprint),\n            implode(', ', $tableStructure)\n        );\n    }\n\n    /**\n     * Append the character set specifications to a command.\n     *\n     * @param  string  $sql\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @return string\n     */\n    protected function compileCreateEncoding($sql, Blueprint $blueprint)\n    {\n        // First we will set the character set if one has been set on either the create\n        // blueprint itself or on the root configuration for the connection that the\n        // table is being created on. We will add these to the create table query.\n        if (isset($blueprint->charset)) {\n            $sql .= ' default character set '.$blueprint->charset;\n        } elseif (! is_null($charset = $this->connection->getConfig('charset'))) {\n            $sql .= ' default character set '.$charset;\n        }\n\n        // Next we will add the collation to the create table statement if one has been\n        // added to either this create table blueprint or the configuration for this\n        // connection that the query is targeting. We'll add it to this SQL query.\n        if (isset($blueprint->collation)) {\n            $sql .= \" collate '{$blueprint->collation}'\";\n        } elseif (! is_null($collation = $this->connection->getConfig('collation'))) {\n            $sql .= \" collate '{$collation}'\";\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Append the engine specifications to a command.\n     *\n     * @param  string  $sql\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @return string\n     */\n    protected function compileCreateEngine($sql, Blueprint $blueprint)\n    {\n        if (isset($blueprint->engine)) {\n            return $sql.' engine = '.$blueprint->engine;\n        } elseif (! is_null($engine = $this->connection->getConfig('engine'))) {\n            return $sql.' engine = '.$engine;\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile an add column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAdd(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add %s%s%s',\n            $this->wrapTable($blueprint),\n            $this->getColumn($blueprint, $command->column),\n            $command->column->instant ? ', algorithm=instant' : '',\n            $command->column->lock ? ', lock='.$command->column->lock : ''\n        );\n    }\n\n    /**\n     * Compile the auto-incrementing column starting values.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAutoIncrementStartingValues(Blueprint $blueprint, Fluent $command)\n    {\n        if ($command->column->autoIncrement\n            && $value = $command->column->get('startingValue', $command->column->get('from'))) {\n            return 'alter table '.$this->wrapTable($blueprint).' auto_increment = '.$value;\n        }\n    }\n\n    /** @inheritDoc */\n    public function compileRenameColumn(Blueprint $blueprint, Fluent $command)\n    {\n        $isMaria = $this->connection->isMaria();\n        $version = $this->connection->getServerVersion();\n\n        if (($isMaria && version_compare($version, '10.5.2', '<')) ||\n            (! $isMaria && version_compare($version, '8.0.3', '<'))) {\n            return $this->compileLegacyRenameColumn($blueprint, $command);\n        }\n\n        return parent::compileRenameColumn($blueprint, $command);\n    }\n\n    /**\n     * Compile a rename column command for legacy versions of MySQL.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    protected function compileLegacyRenameColumn(Blueprint $blueprint, Fluent $command)\n    {\n        $column = (new Collection($this->connection->getSchemaBuilder()->getColumns($blueprint->getTable())))\n            ->firstWhere('name', $command->from);\n\n        $modifiers = $this->addModifiers($column['type'], $blueprint, new ColumnDefinition([\n            'change' => true,\n            'type' => match ($column['type_name']) {\n                'bigint' => 'bigInteger',\n                'int' => 'integer',\n                'mediumint' => 'mediumInteger',\n                'smallint' => 'smallInteger',\n                'tinyint' => 'tinyInteger',\n                default => $column['type_name'],\n            },\n            'nullable' => $column['nullable'],\n            'default' => $column['default'] && (str_starts_with(strtolower($column['default']), 'current_timestamp') || $column['default'] === 'NULL')\n                ? new Expression($column['default'])\n                : $column['default'],\n            'autoIncrement' => $column['auto_increment'],\n            'collation' => $column['collation'],\n            'comment' => $column['comment'],\n            'virtualAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'virtual'\n                ? $column['generation']['expression']\n                : null,\n            'storedAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'stored'\n                ? $column['generation']['expression']\n                : null,\n        ]));\n\n        return sprintf('alter table %s change %s %s %s',\n            $this->wrapTable($blueprint),\n            $this->wrap($command->from),\n            $this->wrap($command->to),\n            $modifiers\n        );\n    }\n\n    /** @inheritDoc */\n    public function compileChange(Blueprint $blueprint, Fluent $command)\n    {\n        $column = $command->column;\n\n        $sql = sprintf('alter table %s %s %s%s %s',\n            $this->wrapTable($blueprint),\n            is_null($column->renameTo) ? 'modify' : 'change',\n            $this->wrap($column),\n            is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo),\n            $this->getType($column)\n        );\n\n        $sql = $this->addModifiers($sql, $blueprint, $column);\n\n        if ($column->instant) {\n            $sql .= ', algorithm=instant';\n        }\n\n        if ($column->lock) {\n            $sql .= ', lock='.$column->lock;\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compilePrimary(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add primary key %s(%s)%s',\n            $this->wrapTable($blueprint),\n            $command->algorithm ? 'using '.$command->algorithm : '',\n            $this->columnize($command->columns),\n            $command->lock ? ', lock='.$command->lock : ''\n        );\n    }\n\n    /**\n     * Compile a unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileUnique(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileKey($blueprint, $command, 'unique');\n    }\n\n    /**\n     * Compile a plain index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileKey($blueprint, $command, 'index');\n    }\n\n    /**\n     * Compile a fulltext index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileFullText(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileKey($blueprint, $command, 'fulltext');\n    }\n\n    /**\n     * Compile a spatial index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileKey($blueprint, $command, 'spatial index');\n    }\n\n    /**\n     * Compile an index creation command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @param  string  $type\n     * @return string\n     */\n    protected function compileKey(Blueprint $blueprint, Fluent $command, $type)\n    {\n        return sprintf('alter table %s add %s %s%s(%s)%s',\n            $this->wrapTable($blueprint),\n            $type,\n            $this->wrap($command->index),\n            $command->algorithm ? ' using '.$command->algorithm : '',\n            $this->columnize($command->columns),\n            $command->lock ? ', lock='.$command->lock : ''\n        );\n    }\n\n    /**\n     * Compile a drop table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDrop(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile a drop table (if exists) command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table if exists '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile a drop column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropColumn(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $this->prefixArray('drop', $this->wrapArray($command->columns));\n\n        $sql = 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);\n\n        if ($command->instant) {\n            $sql .= ', algorithm=instant';\n        }\n\n        if ($command->lock) {\n            $sql .= ', lock='.$command->lock;\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a drop primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)\n    {\n        return 'alter table '.$this->wrapTable($blueprint).' drop primary key';\n    }\n\n    /**\n     * Compile a drop unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropUnique(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop index {$index}\";\n    }\n\n    /**\n     * Compile a drop index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIndex(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop index {$index}\";\n    }\n\n    /**\n     * Compile a drop fulltext index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropFullText(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a drop spatial index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileForeign(Blueprint $blueprint, Fluent $command)\n    {\n        $sql = parent::compileForeign($blueprint, $command);\n\n        if ($command->lock) {\n            $sql .= ', lock='.$command->lock;\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a drop foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropForeign(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop foreign key {$index}\";\n    }\n\n    /**\n     * Compile a rename table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRename(Blueprint $blueprint, Fluent $command)\n    {\n        $from = $this->wrapTable($blueprint);\n\n        return \"rename table {$from} to \".$this->wrapTable($command->to);\n    }\n\n    /**\n     * Compile a rename index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s rename index %s to %s',\n            $this->wrapTable($blueprint),\n            $this->wrap($command->from),\n            $this->wrap($command->to)\n        );\n    }\n\n    /**\n     * Compile the SQL needed to drop all tables.\n     *\n     * @param  array<string>  $tables\n     * @return string\n     */\n    public function compileDropAllTables($tables)\n    {\n        return 'drop table '.implode(', ', $this->escapeNames($tables));\n    }\n\n    /**\n     * Compile the SQL needed to drop all views.\n     *\n     * @param  array<string>  $views\n     * @return string\n     */\n    public function compileDropAllViews($views)\n    {\n        return 'drop view '.implode(', ', $this->escapeNames($views));\n    }\n\n    /**\n     * Compile the command to enable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileEnableForeignKeyConstraints()\n    {\n        return 'SET FOREIGN_KEY_CHECKS=1;';\n    }\n\n    /**\n     * Compile the command to disable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileDisableForeignKeyConstraints()\n    {\n        return 'SET FOREIGN_KEY_CHECKS=0;';\n    }\n\n    /**\n     * Compile a table comment command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileTableComment(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s comment = %s',\n            $this->wrapTable($blueprint),\n            \"'\".str_replace(\"'\", \"''\", $command->comment).\"'\"\n        );\n    }\n\n    /**\n     * Quote-escape the given tables, views, or types.\n     *\n     * @param  array<string>  $names\n     * @return array<string>\n     */\n    public function escapeNames($names)\n    {\n        return array_map(\n            fn ($name) => (new Collection(explode('.', $name)))->map($this->wrapValue(...))->implode('.'),\n            $names\n        );\n    }\n\n    /**\n     * Create the column definition for a char type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeChar(Fluent $column)\n    {\n        return \"char({$column->length})\";\n    }\n\n    /**\n     * Create the column definition for a string type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeString(Fluent $column)\n    {\n        return \"varchar({$column->length})\";\n    }\n\n    /**\n     * Create the column definition for a tiny text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyText(Fluent $column)\n    {\n        return 'tinytext';\n    }\n\n    /**\n     * Create the column definition for a text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a medium text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumText(Fluent $column)\n    {\n        return 'mediumtext';\n    }\n\n    /**\n     * Create the column definition for a long text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeLongText(Fluent $column)\n    {\n        return 'longtext';\n    }\n\n    /**\n     * Create the column definition for a big integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBigInteger(Fluent $column)\n    {\n        return 'bigint';\n    }\n\n    /**\n     * Create the column definition for an integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeInteger(Fluent $column)\n    {\n        return 'int';\n    }\n\n    /**\n     * Create the column definition for a medium integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumInteger(Fluent $column)\n    {\n        return 'mediumint';\n    }\n\n    /**\n     * Create the column definition for a tiny integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyInteger(Fluent $column)\n    {\n        return 'tinyint';\n    }\n\n    /**\n     * Create the column definition for a small integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeSmallInteger(Fluent $column)\n    {\n        return 'smallint';\n    }\n\n    /**\n     * Create the column definition for a float type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeFloat(Fluent $column)\n    {\n        if ($column->precision) {\n            return \"float({$column->precision})\";\n        }\n\n        return 'float';\n    }\n\n    /**\n     * Create the column definition for a double type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDouble(Fluent $column)\n    {\n        return 'double';\n    }\n\n    /**\n     * Create the column definition for a decimal type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDecimal(Fluent $column)\n    {\n        return \"decimal({$column->total}, {$column->places})\";\n    }\n\n    /**\n     * Create the column definition for a boolean type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBoolean(Fluent $column)\n    {\n        return 'tinyint(1)';\n    }\n\n    /**\n     * Create the column definition for an enumeration type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeEnum(Fluent $column)\n    {\n        return sprintf('enum(%s)', $this->quoteString($column->allowed));\n    }\n\n    /**\n     * Create the column definition for a set enumeration type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeSet(Fluent $column)\n    {\n        return sprintf('set(%s)', $this->quoteString($column->allowed));\n    }\n\n    /**\n     * Create the column definition for a json type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJson(Fluent $column)\n    {\n        return 'json';\n    }\n\n    /**\n     * Create the column definition for a jsonb type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJsonb(Fluent $column)\n    {\n        return 'json';\n    }\n\n    /**\n     * Create the column definition for a date type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDate(Fluent $column)\n    {\n        $isMaria = $this->connection->isMaria();\n        $version = $this->connection->getServerVersion();\n\n        if ($isMaria ||\n            (! $isMaria && version_compare($version, '8.0.13', '>='))) {\n            if ($column->useCurrent) {\n                $column->default(new Expression('(CURDATE())'));\n            }\n        }\n\n        return 'date';\n    }\n\n    /**\n     * Create the column definition for a date-time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTime(Fluent $column)\n    {\n        $current = $column->precision ? \"CURRENT_TIMESTAMP($column->precision)\" : 'CURRENT_TIMESTAMP';\n\n        if ($column->useCurrent) {\n            $column->default(new Expression($current));\n        }\n\n        if ($column->useCurrentOnUpdate) {\n            $column->onUpdate(new Expression($current));\n        }\n\n        return $column->precision ? \"datetime($column->precision)\" : 'datetime';\n    }\n\n    /**\n     * Create the column definition for a date-time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTimeTz(Fluent $column)\n    {\n        return $this->typeDateTime($column);\n    }\n\n    /**\n     * Create the column definition for a time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTime(Fluent $column)\n    {\n        return $column->precision ? \"time($column->precision)\" : 'time';\n    }\n\n    /**\n     * Create the column definition for a time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimeTz(Fluent $column)\n    {\n        return $this->typeTime($column);\n    }\n\n    /**\n     * Create the column definition for a timestamp type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestamp(Fluent $column)\n    {\n        $current = $column->precision ? \"CURRENT_TIMESTAMP($column->precision)\" : 'CURRENT_TIMESTAMP';\n\n        if ($column->useCurrent) {\n            $column->default(new Expression($current));\n        }\n\n        if ($column->useCurrentOnUpdate) {\n            $column->onUpdate(new Expression($current));\n        }\n\n        return $column->precision ? \"timestamp($column->precision)\" : 'timestamp';\n    }\n\n    /**\n     * Create the column definition for a timestamp (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestampTz(Fluent $column)\n    {\n        return $this->typeTimestamp($column);\n    }\n\n    /**\n     * Create the column definition for a year type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeYear(Fluent $column)\n    {\n        $isMaria = $this->connection->isMaria();\n        $version = $this->connection->getServerVersion();\n\n        if ($isMaria ||\n            (! $isMaria && version_compare($version, '8.0.13', '>='))) {\n            if ($column->useCurrent) {\n                $column->default(new Expression('(YEAR(CURDATE()))'));\n            }\n        }\n\n        return 'year';\n    }\n\n    /**\n     * Create the column definition for a binary type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBinary(Fluent $column)\n    {\n        if ($column->length) {\n            return $column->fixed ? \"binary({$column->length})\" : \"varbinary({$column->length})\";\n        }\n\n        return 'blob';\n    }\n\n    /**\n     * Create the column definition for a uuid type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeUuid(Fluent $column)\n    {\n        return 'char(36)';\n    }\n\n    /**\n     * Create the column definition for an IP address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeIpAddress(Fluent $column)\n    {\n        return 'varchar(45)';\n    }\n\n    /**\n     * Create the column definition for a MAC address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMacAddress(Fluent $column)\n    {\n        return 'varchar(17)';\n    }\n\n    /**\n     * Create the column definition for a spatial Geometry type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeometry(Fluent $column)\n    {\n        $subtype = $column->subtype ? strtolower($column->subtype) : null;\n\n        if (! in_array($subtype, ['point', 'linestring', 'polygon', 'geometrycollection', 'multipoint', 'multilinestring', 'multipolygon'])) {\n            $subtype = null;\n        }\n\n        return sprintf('%s%s',\n            $subtype ?? 'geometry',\n            match (true) {\n                $column->srid && $this->connection->isMaria() => ' ref_system_id='.$column->srid,\n                (bool) $column->srid => ' srid '.$column->srid,\n                default => '',\n            }\n        );\n    }\n\n    /**\n     * Create the column definition for a spatial Geography type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeography(Fluent $column)\n    {\n        return $this->typeGeometry($column);\n    }\n\n    /**\n     * Create the column definition for a generated, computed column type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function typeComputed(Fluent $column)\n    {\n        throw new RuntimeException('This database driver requires a type, see the virtualAs / storedAs modifiers.');\n    }\n\n    /**\n     * Create the column definition for a vector type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeVector(Fluent $column)\n    {\n        return isset($column->dimensions) && $column->dimensions !== ''\n            ? \"vector({$column->dimensions})\"\n            : 'vector';\n    }\n\n    /**\n     * Get the SQL for a generated virtual column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($virtualAs = $column->virtualAsJson)) {\n            if ($this->isJsonSelector($virtualAs)) {\n                $virtualAs = $this->wrapJsonSelector($virtualAs);\n            }\n\n            return \" as ({$virtualAs})\";\n        }\n\n        if (! is_null($virtualAs = $column->virtualAs)) {\n            return \" as ({$this->getValue($virtualAs)})\";\n        }\n    }\n\n    /**\n     * Get the SQL for a generated stored column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($storedAs = $column->storedAsJson)) {\n            if ($this->isJsonSelector($storedAs)) {\n                $storedAs = $this->wrapJsonSelector($storedAs);\n            }\n\n            return \" as ({$storedAs}) stored\";\n        }\n\n        if (! is_null($storedAs = $column->storedAs)) {\n            return \" as ({$this->getValue($storedAs)}) stored\";\n        }\n    }\n\n    /**\n     * Get the SQL for an unsigned column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyUnsigned(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->unsigned) {\n            return ' unsigned';\n        }\n    }\n\n    /**\n     * Get the SQL for a character set column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyCharset(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->charset)) {\n            return ' character set '.$column->charset;\n        }\n    }\n\n    /**\n     * Get the SQL for a collation column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyCollate(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->collation)) {\n            return \" collate '{$column->collation}'\";\n        }\n    }\n\n    /**\n     * Get the SQL for a nullable column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyNullable(Blueprint $blueprint, Fluent $column)\n    {\n        if (is_null($column->virtualAs) &&\n            is_null($column->virtualAsJson) &&\n            is_null($column->storedAs) &&\n            is_null($column->storedAsJson)) {\n            return $column->nullable ? ' null' : ' not null';\n        }\n\n        if ($column->nullable === false) {\n            return ' not null';\n        }\n    }\n\n    /**\n     * Get the SQL for an invisible column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyInvisible(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->invisible)) {\n            return ' invisible';\n        }\n    }\n\n    /**\n     * Get the SQL for a default column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyDefault(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->default)) {\n            return ' default '.$this->getDefaultValue($column->default);\n        }\n    }\n\n    /**\n     * Get the SQL for an \"on update\" column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyOnUpdate(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->onUpdate)) {\n            return ' on update '.$this->getValue($column->onUpdate);\n        }\n    }\n\n    /**\n     * Get the SQL for an auto-increment column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)\n    {\n        if (in_array($column->type, $this->serials) && $column->autoIncrement) {\n            return $this->hasCommand($blueprint, 'primary') || ($column->change && ! $column->primary)\n                ? ' auto_increment'\n                : ' auto_increment primary key';\n        }\n    }\n\n    /**\n     * Get the SQL for a \"first\" column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyFirst(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->first)) {\n            return ' first';\n        }\n    }\n\n    /**\n     * Get the SQL for an \"after\" column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyAfter(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->after)) {\n            return ' after '.$this->wrap($column->after);\n        }\n    }\n\n    /**\n     * Get the SQL for a \"comment\" column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyComment(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->comment)) {\n            return \" comment '\".addslashes($column->comment).\"'\";\n        }\n    }\n\n    /**\n     * Wrap a single string in keyword identifiers.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapValue($value)\n    {\n        if ($value !== '*') {\n            return '`'.str_replace('`', '``', $value).'`';\n        }\n\n        return $value;\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_unquote(json_extract('.$field.$path.'))';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse LogicException;\n\nclass PostgresGrammar extends Grammar\n{\n    /**\n     * If this Grammar supports schema changes wrapped in a transaction.\n     *\n     * @var bool\n     */\n    protected $transactions = true;\n\n    /**\n     * The possible column modifiers.\n     *\n     * @var string[]\n     */\n    protected $modifiers = ['Collate', 'Nullable', 'Default', 'VirtualAs', 'StoredAs', 'GeneratedAs', 'Increment'];\n\n    /**\n     * The columns available as serials.\n     *\n     * @var string[]\n     */\n    protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];\n\n    /**\n     * The commands to be executed outside of create or alter command.\n     *\n     * @var string[]\n     */\n    protected $fluentCommands = ['AutoIncrementStartingValues', 'Comment'];\n\n    /**\n     * Compile a create database command.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public function compileCreateDatabase($name)\n    {\n        $sql = parent::compileCreateDatabase($name);\n\n        if ($charset = $this->connection->getConfig('charset')) {\n            $sql .= sprintf(' encoding %s', $this->wrapValue($charset));\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile the query to determine the schemas.\n     *\n     * @return string\n     */\n    public function compileSchemas()\n    {\n        return 'select nspname as name, nspname = current_schema() as \"default\" from pg_namespace where '\n            .$this->compileSchemaWhereClause(null, 'nspname')\n            .' order by nspname';\n    }\n\n    /**\n     * Compile the query to determine if the given table exists.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileTableExists($schema, $table)\n    {\n        return sprintf(\n            'select exists (select 1 from pg_class c, pg_namespace n where '\n            .\"n.nspname = %s and c.relname = %s and c.relkind in ('r', 'p') and n.oid = c.relnamespace)\",\n            $schema ? $this->quoteString($schema) : 'current_schema()',\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the tables.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileTables($schema)\n    {\n        return 'select c.relname as name, n.nspname as schema, pg_total_relation_size(c.oid) as size, '\n            .\"obj_description(c.oid, 'pg_class') as comment from pg_class c, pg_namespace n \"\n            .\"where c.relkind in ('r', 'p') and n.oid = c.relnamespace and \"\n            .$this->compileSchemaWhereClause($schema, 'n.nspname')\n            .' order by n.nspname, c.relname';\n    }\n\n    /**\n     * Compile the query to determine the views.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileViews($schema)\n    {\n        return 'select viewname as name, schemaname as schema, definition from pg_views where '\n            .$this->compileSchemaWhereClause($schema, 'schemaname')\n            .' order by schemaname, viewname';\n    }\n\n    /**\n     * Compile the query to determine the user-defined types.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileTypes($schema)\n    {\n        return 'select t.typname as name, n.nspname as schema, t.typtype as type, t.typcategory as category, '\n            .\"((t.typinput = 'array_in'::regproc and t.typoutput = 'array_out'::regproc) or t.typtype = 'm') as implicit \"\n            .'from pg_type t join pg_namespace n on n.oid = t.typnamespace '\n            .'left join pg_class c on c.oid = t.typrelid '\n            .'left join pg_type el on el.oid = t.typelem '\n            .'left join pg_class ce on ce.oid = el.typrelid '\n            .\"where ((t.typrelid = 0 and (ce.relkind = 'c' or ce.relkind is null)) or c.relkind = 'c') \"\n            .\"and not exists (select 1 from pg_depend d where d.objid in (t.oid, t.typelem) and d.deptype = 'e') and \"\n            .$this->compileSchemaWhereClause($schema, 'n.nspname');\n    }\n\n    /**\n     * Compile the query to compare the schema.\n     *\n     * @param  string|string[]|null  $schema\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileSchemaWhereClause($schema, $column)\n    {\n        return $column.(match (true) {\n            ! empty($schema) && is_array($schema) => ' in ('.$this->quoteString($schema).')',\n            ! empty($schema) => ' = '.$this->quoteString($schema),\n            default => \" <> 'information_schema' and $column not like 'pg\\_%'\",\n        });\n    }\n\n    /**\n     * Compile the query to determine the columns.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileColumns($schema, $table)\n    {\n        return sprintf(\n            'select a.attname as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, '\n            .'(select tc.collcollate from pg_catalog.pg_collation tc where tc.oid = a.attcollation) as collation, '\n            .'not a.attnotnull as nullable, '\n            .'(select pg_get_expr(adbin, adrelid) from pg_attrdef where c.oid = pg_attrdef.adrelid and pg_attrdef.adnum = a.attnum) as default, '\n            .(version_compare($this->connection->getServerVersion(), '12.0', '<') ? \"'' as generated, \" : 'a.attgenerated as generated, ')\n            .'col_description(c.oid, a.attnum) as comment '\n            .'from pg_attribute a, pg_class c, pg_type t, pg_namespace n '\n            .'where c.relname = %s and n.nspname = %s and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid and n.oid = c.relnamespace '\n            .'order by a.attnum',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'current_schema()'\n        );\n    }\n\n    /**\n     * Compile the query to determine the indexes.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileIndexes($schema, $table)\n    {\n        return sprintf(\n            \"select ic.relname as name, string_agg(a.attname, ',' order by indseq.ord) as columns, \"\n            .'am.amname as \"type\", i.indisunique as \"unique\", i.indisprimary as \"primary\" '\n            .'from pg_index i '\n            .'join pg_class tc on tc.oid = i.indrelid '\n            .'join pg_namespace tn on tn.oid = tc.relnamespace '\n            .'join pg_class ic on ic.oid = i.indexrelid '\n            .'join pg_am am on am.oid = ic.relam '\n            .'join lateral unnest(i.indkey) with ordinality as indseq(num, ord) on true '\n            .'left join pg_attribute a on a.attrelid = i.indrelid and a.attnum = indseq.num '\n            .'where tc.relname = %s and tn.nspname = %s '\n            .'group by ic.relname, am.amname, i.indisunique, i.indisprimary',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'current_schema()'\n        );\n    }\n\n    /**\n     * Compile the query to determine the foreign keys.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileForeignKeys($schema, $table)\n    {\n        return sprintf(\n            'select c.conname as name, '\n            .\"string_agg(la.attname, ',' order by conseq.ord) as columns, \"\n            .'fn.nspname as foreign_schema, fc.relname as foreign_table, '\n            .\"string_agg(fa.attname, ',' order by conseq.ord) as foreign_columns, \"\n            .'c.confupdtype as on_update, c.confdeltype as on_delete '\n            .'from pg_constraint c '\n            .'join pg_class tc on c.conrelid = tc.oid '\n            .'join pg_namespace tn on tn.oid = tc.relnamespace '\n            .'join pg_class fc on c.confrelid = fc.oid '\n            .'join pg_namespace fn on fn.oid = fc.relnamespace '\n            .'join lateral unnest(c.conkey) with ordinality as conseq(num, ord) on true '\n            .'join pg_attribute la on la.attrelid = c.conrelid and la.attnum = conseq.num '\n            .'join pg_attribute fa on fa.attrelid = c.confrelid and fa.attnum = c.confkey[conseq.ord] '\n            .\"where c.contype = 'f' and tc.relname = %s and tn.nspname = %s \"\n            .'group by c.conname, fn.nspname, fc.relname, c.confupdtype, c.confdeltype',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'current_schema()'\n        );\n    }\n\n    /**\n     * Compile a create table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileCreate(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('%s table %s (%s)',\n            $blueprint->temporary ? 'create temporary' : 'create',\n            $this->wrapTable($blueprint),\n            implode(', ', $this->getColumns($blueprint))\n        );\n    }\n\n    /**\n     * Compile a column addition command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAdd(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add column %s',\n            $this->wrapTable($blueprint),\n            $this->getColumn($blueprint, $command->column)\n        );\n    }\n\n    /**\n     * Compile the auto-incrementing column starting values.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAutoIncrementStartingValues(Blueprint $blueprint, Fluent $command)\n    {\n        if ($command->column->autoIncrement\n            && $value = $command->column->get('startingValue', $command->column->get('from'))) {\n            return sprintf(\n                'select setval(pg_get_serial_sequence(%s, %s), %s, false)',\n                $this->quoteString($this->wrapTable($blueprint)),\n                $this->quoteString($command->column->name),\n                $value\n            );\n        }\n    }\n\n    /** @inheritDoc */\n    public function compileChange(Blueprint $blueprint, Fluent $command)\n    {\n        $column = $command->column;\n\n        $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)];\n\n        foreach ($this->modifiers as $modifier) {\n            if ($modifier === 'Collate') {\n                continue;\n            }\n\n            if (method_exists($this, $method = \"modify{$modifier}\")) {\n                $constraints = (array) $this->{$method}($blueprint, $column);\n\n                foreach ($constraints as $constraint) {\n                    $changes[] = $constraint;\n                }\n            }\n        }\n\n        return sprintf('alter table %s %s',\n            $this->wrapTable($blueprint),\n            implode(', ', $this->prefixArray('alter column '.$this->wrap($column), $changes))\n        );\n    }\n\n    /**\n     * Compile a primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compilePrimary(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $this->columnize($command->columns);\n\n        return 'alter table '.$this->wrapTable($blueprint).\" add primary key ({$columns})\";\n    }\n\n    /**\n     * Compile a unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string[]\n     */\n    public function compileUnique(Blueprint $blueprint, Fluent $command)\n    {\n        $uniqueStatement = 'unique';\n\n        if (! is_null($command->nullsNotDistinct)) {\n            $uniqueStatement .= ' nulls '.($command->nullsNotDistinct ? 'not distinct' : 'distinct');\n        }\n\n        if ($command->online || $command->algorithm) {\n            $createIndexSql = sprintf('create unique index %s%s on %s%s (%s)',\n                $command->online ? 'concurrently ' : '',\n                $this->wrap($command->index),\n                $this->wrapTable($blueprint),\n                $command->algorithm ? ' using '.$command->algorithm : '',\n                $this->columnize($command->columns)\n            );\n\n            $sql = sprintf('alter table %s add constraint %s unique using index %s',\n                $this->wrapTable($blueprint),\n                $this->wrap($command->index),\n                $this->wrap($command->index)\n            );\n        } else {\n            $sql = sprintf(\n                'alter table %s add constraint %s %s (%s)',\n                $this->wrapTable($blueprint),\n                $this->wrap($command->index),\n                $uniqueStatement,\n                $this->columnize($command->columns)\n            );\n        }\n\n        if (! is_null($command->deferrable)) {\n            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';\n        }\n\n        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {\n            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';\n        }\n\n        return isset($createIndexSql) ? [$createIndexSql, $sql] : [$sql];\n    }\n\n    /**\n     * Compile a plain index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('create index %s%s on %s%s (%s)',\n            $command->online ? 'concurrently ' : '',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            $command->algorithm ? ' using '.$command->algorithm : '',\n            $this->columnize($command->columns)\n        );\n    }\n\n    /**\n     * Compile a fulltext index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileFulltext(Blueprint $blueprint, Fluent $command)\n    {\n        $language = $command->language ?: 'english';\n\n        $columns = array_map(function ($column) use ($language) {\n            return \"to_tsvector({$this->quoteString($language)}, {$this->wrap($column)})\";\n        }, $command->columns);\n\n        return sprintf('create index %s%s on %s using gin ((%s))',\n            $command->online ? 'concurrently ' : '',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            implode(' || ', $columns)\n        );\n    }\n\n    /**\n     * Compile a spatial index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        $command->algorithm = 'gist';\n\n        if (! is_null($command->operatorClass)) {\n            return $this->compileIndexWithOperatorClass($blueprint, $command);\n        }\n\n        return $this->compileIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a vector index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileVectorIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileIndexWithOperatorClass($blueprint, $command);\n    }\n\n    /**\n     * Compile a spatial index with operator class key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    protected function compileIndexWithOperatorClass(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $this->columnizeWithOperatorClass($command->columns, $command->operatorClass);\n\n        return sprintf('create index %s%s on %s%s (%s)',\n            $command->online ? 'concurrently ' : '',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            $command->algorithm ? ' using '.$command->algorithm : '',\n            $columns\n        );\n    }\n\n    /**\n     * Convert an array of column names to a delimited string with operator class.\n     *\n     * @param  array  $columns\n     * @param  string  $operatorClass\n     * @return string\n     */\n    protected function columnizeWithOperatorClass(array $columns, $operatorClass)\n    {\n        return implode(', ', array_map(function ($column) use ($operatorClass) {\n            return $this->wrap($column).' '.$operatorClass;\n        }, $columns));\n    }\n\n    /**\n     * Compile a foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileForeign(Blueprint $blueprint, Fluent $command)\n    {\n        $sql = parent::compileForeign($blueprint, $command);\n\n        if (! is_null($command->deferrable)) {\n            $sql .= $command->deferrable ? ' deferrable' : ' not deferrable';\n        }\n\n        if ($command->deferrable && ! is_null($command->initiallyImmediate)) {\n            $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred';\n        }\n\n        if (! is_null($command->notValid)) {\n            $sql .= ' not valid';\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Compile a drop table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDrop(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile a drop table (if exists) command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table if exists '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile the SQL needed to drop all tables.\n     *\n     * @param  array<string>  $tables\n     * @return string\n     */\n    public function compileDropAllTables($tables)\n    {\n        return 'drop table '.implode(', ', $this->escapeNames($tables)).' cascade';\n    }\n\n    /**\n     * Compile the SQL needed to drop all views.\n     *\n     * @param  array<string>  $views\n     * @return string\n     */\n    public function compileDropAllViews($views)\n    {\n        return 'drop view '.implode(', ', $this->escapeNames($views)).' cascade';\n    }\n\n    /**\n     * Compile the SQL needed to drop all types.\n     *\n     * @param  array<string>  $types\n     * @return string\n     */\n    public function compileDropAllTypes($types)\n    {\n        return 'drop type '.implode(', ', $this->escapeNames($types)).' cascade';\n    }\n\n    /**\n     * Compile the SQL needed to drop all domains.\n     *\n     * @param  array<string>  $domains\n     * @return string\n     */\n    public function compileDropAllDomains($domains)\n    {\n        return 'drop domain '.implode(', ', $this->escapeNames($domains)).' cascade';\n    }\n\n    /**\n     * Compile a drop column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropColumn(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));\n\n        return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns);\n    }\n\n    /**\n     * Compile a drop primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)\n    {\n        [, $table] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($blueprint->getTable());\n        $index = $this->wrap(\"{$this->connection->getTablePrefix()}{$table}_pkey\");\n\n        return 'alter table '.$this->wrapTable($blueprint).\" drop constraint {$index}\";\n    }\n\n    /**\n     * Compile a drop unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropUnique(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop constraint {$index}\";\n    }\n\n    /**\n     * Compile a drop index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return \"drop index {$this->wrap($command->index)}\";\n    }\n\n    /**\n     * Compile a drop fulltext index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropFullText(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a drop spatial index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a drop foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropForeign(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop constraint {$index}\";\n    }\n\n    /**\n     * Compile a rename table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRename(Blueprint $blueprint, Fluent $command)\n    {\n        $from = $this->wrapTable($blueprint);\n\n        return \"alter table {$from} rename to \".$this->wrapTable($command->to);\n    }\n\n    /**\n     * Compile a rename index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter index %s rename to %s',\n            $this->wrap($command->from),\n            $this->wrap($command->to)\n        );\n    }\n\n    /**\n     * Compile the command to enable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileEnableForeignKeyConstraints()\n    {\n        return 'SET CONSTRAINTS ALL IMMEDIATE;';\n    }\n\n    /**\n     * Compile the command to disable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileDisableForeignKeyConstraints()\n    {\n        return 'SET CONSTRAINTS ALL DEFERRED;';\n    }\n\n    /**\n     * Compile a comment command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileComment(Blueprint $blueprint, Fluent $command)\n    {\n        if (! is_null($comment = $command->column->comment) || $command->column->change) {\n            return sprintf('comment on column %s.%s is %s',\n                $this->wrapTable($blueprint),\n                $this->wrap($command->column->name),\n                is_null($comment) ? 'NULL' : \"'\".str_replace(\"'\", \"''\", $comment).\"'\"\n            );\n        }\n    }\n\n    /**\n     * Compile a table comment command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileTableComment(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('comment on table %s is %s',\n            $this->wrapTable($blueprint),\n            \"'\".str_replace(\"'\", \"''\", $command->comment).\"'\"\n        );\n    }\n\n    /**\n     * Quote-escape the given tables, views, or types.\n     *\n     * @param  array<string>  $names\n     * @return array<string>\n     */\n    public function escapeNames($names)\n    {\n        return array_map(\n            fn ($name) => (new Collection(explode('.', $name)))->map($this->wrapValue(...))->implode('.'),\n            $names\n        );\n    }\n\n    /**\n     * Create the column definition for a char type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeChar(Fluent $column)\n    {\n        if ($column->length) {\n            return \"char({$column->length})\";\n        }\n\n        return 'char';\n    }\n\n    /**\n     * Create the column definition for a string type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeString(Fluent $column)\n    {\n        if ($column->length) {\n            return \"varchar({$column->length})\";\n        }\n\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for a tiny text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyText(Fluent $column)\n    {\n        return 'varchar(255)';\n    }\n\n    /**\n     * Create the column definition for a text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a medium text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a long text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeLongText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for an integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeInteger(Fluent $column)\n    {\n        return $column->autoIncrement && is_null($column->generatedAs) && ! $column->change ? 'serial' : 'integer';\n    }\n\n    /**\n     * Create the column definition for a big integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBigInteger(Fluent $column)\n    {\n        return $column->autoIncrement && is_null($column->generatedAs) && ! $column->change ? 'bigserial' : 'bigint';\n    }\n\n    /**\n     * Create the column definition for a medium integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumInteger(Fluent $column)\n    {\n        return $this->typeInteger($column);\n    }\n\n    /**\n     * Create the column definition for a tiny integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyInteger(Fluent $column)\n    {\n        return $this->typeSmallInteger($column);\n    }\n\n    /**\n     * Create the column definition for a small integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeSmallInteger(Fluent $column)\n    {\n        return $column->autoIncrement && is_null($column->generatedAs) && ! $column->change ? 'smallserial' : 'smallint';\n    }\n\n    /**\n     * Create the column definition for a float type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeFloat(Fluent $column)\n    {\n        if ($column->precision) {\n            return \"float({$column->precision})\";\n        }\n\n        return 'float';\n    }\n\n    /**\n     * Create the column definition for a double type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDouble(Fluent $column)\n    {\n        return 'double precision';\n    }\n\n    /**\n     * Create the column definition for a real type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeReal(Fluent $column)\n    {\n        return 'real';\n    }\n\n    /**\n     * Create the column definition for a decimal type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDecimal(Fluent $column)\n    {\n        return \"decimal({$column->total}, {$column->places})\";\n    }\n\n    /**\n     * Create the column definition for a boolean type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBoolean(Fluent $column)\n    {\n        return 'boolean';\n    }\n\n    /**\n     * Create the column definition for an enumeration type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeEnum(Fluent $column)\n    {\n        return sprintf(\n            'varchar(255) check (\"%s\" in (%s))',\n            $column->name,\n            $this->quoteString($column->allowed)\n        );\n    }\n\n    /**\n     * Create the column definition for a json type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJson(Fluent $column)\n    {\n        return 'json';\n    }\n\n    /**\n     * Create the column definition for a jsonb type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJsonb(Fluent $column)\n    {\n        return 'jsonb';\n    }\n\n    /**\n     * Create the column definition for a date type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDate(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_DATE'));\n        }\n\n        return 'date';\n    }\n\n    /**\n     * Create the column definition for a date-time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTime(Fluent $column)\n    {\n        return $this->typeTimestamp($column);\n    }\n\n    /**\n     * Create the column definition for a date-time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTimeTz(Fluent $column)\n    {\n        return $this->typeTimestampTz($column);\n    }\n\n    /**\n     * Create the column definition for a time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTime(Fluent $column)\n    {\n        return 'time'.(is_null($column->precision) ? '' : \"($column->precision)\").' without time zone';\n    }\n\n    /**\n     * Create the column definition for a time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimeTz(Fluent $column)\n    {\n        return 'time'.(is_null($column->precision) ? '' : \"($column->precision)\").' with time zone';\n    }\n\n    /**\n     * Create the column definition for a timestamp type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestamp(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_TIMESTAMP'));\n        }\n\n        return 'timestamp'.(is_null($column->precision) ? '' : \"($column->precision)\").' without time zone';\n    }\n\n    /**\n     * Create the column definition for a timestamp (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestampTz(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_TIMESTAMP'));\n        }\n\n        return 'timestamp'.(is_null($column->precision) ? '' : \"($column->precision)\").' with time zone';\n    }\n\n    /**\n     * Create the column definition for a year type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeYear(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('EXTRACT(YEAR FROM CURRENT_DATE)'));\n        }\n\n        return $this->typeInteger($column);\n    }\n\n    /**\n     * Create the column definition for a binary type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBinary(Fluent $column)\n    {\n        return 'bytea';\n    }\n\n    /**\n     * Create the column definition for a uuid type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeUuid(Fluent $column)\n    {\n        return 'uuid';\n    }\n\n    /**\n     * Create the column definition for an IP address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeIpAddress(Fluent $column)\n    {\n        return 'inet';\n    }\n\n    /**\n     * Create the column definition for a MAC address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMacAddress(Fluent $column)\n    {\n        return 'macaddr';\n    }\n\n    /**\n     * Create the column definition for a spatial Geometry type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeometry(Fluent $column)\n    {\n        if ($column->subtype) {\n            return sprintf('geometry(%s%s)',\n                strtolower($column->subtype),\n                $column->srid ? ','.$column->srid : ''\n            );\n        }\n\n        return 'geometry';\n    }\n\n    /**\n     * Create the column definition for a spatial Geography type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeography(Fluent $column)\n    {\n        if ($column->subtype) {\n            return sprintf('geography(%s%s)',\n                strtolower($column->subtype),\n                $column->srid ? ','.$column->srid : ''\n            );\n        }\n\n        return 'geography';\n    }\n\n    /**\n     * Create the column definition for a vector type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeVector(Fluent $column)\n    {\n        return isset($column->dimensions) && $column->dimensions !== ''\n            ? \"vector({$column->dimensions})\"\n            : 'vector';\n    }\n\n    /**\n     * Create the column definition for a tsvector type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTsvector(Fluent $column)\n    {\n        return 'tsvector';\n    }\n\n    /**\n     * Get the SQL for a collation column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyCollate(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->collation)) {\n            return ' collate '.$this->wrapValue($column->collation);\n        }\n    }\n\n    /**\n     * Get the SQL for a nullable column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyNullable(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            return $column->nullable ? 'drop not null' : 'set not null';\n        }\n\n        return $column->nullable ? ' null' : ' not null';\n    }\n\n    /**\n     * Get the SQL for a default column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyDefault(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            if (! $column->autoIncrement || ! is_null($column->generatedAs)) {\n                return is_null($column->default) ? 'drop default' : 'set default '.$this->getDefaultValue($column->default);\n            }\n\n            return null;\n        }\n\n        if (! is_null($column->default)) {\n            return ' default '.$this->getDefaultValue($column->default);\n        }\n    }\n\n    /**\n     * Get the SQL for an auto-increment column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)\n    {\n        if (! $column->change\n            && ! $this->hasCommand($blueprint, 'primary')\n            && (in_array($column->type, $this->serials) || ($column->generatedAs !== null))\n            && $column->autoIncrement) {\n            return ' primary key';\n        }\n    }\n\n    /**\n     * Get the SQL for a generated virtual column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            if (array_key_exists('virtualAs', $column->getAttributes())) {\n                return is_null($column->virtualAs)\n                    ? 'drop expression if exists'\n                    : throw new LogicException('This database driver does not support modifying generated columns.');\n            }\n\n            return null;\n        }\n\n        if (! is_null($column->virtualAs)) {\n            return \" generated always as ({$this->getValue($column->virtualAs)}) virtual\";\n        }\n    }\n\n    /**\n     * Get the SQL for a generated stored column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            if (array_key_exists('storedAs', $column->getAttributes())) {\n                return is_null($column->storedAs)\n                    ? 'drop expression if exists'\n                    : throw new LogicException('This database driver does not support modifying generated columns.');\n            }\n\n            return null;\n        }\n\n        if (! is_null($column->storedAs)) {\n            return \" generated always as ({$this->getValue($column->storedAs)}) stored\";\n        }\n    }\n\n    /**\n     * Get the SQL for an identity column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|list<string>|null\n     */\n    protected function modifyGeneratedAs(Blueprint $blueprint, Fluent $column)\n    {\n        $sql = null;\n\n        if (! is_null($column->generatedAs)) {\n            $sql = sprintf(\n                ' generated %s as identity%s',\n                $column->always ? 'always' : 'by default',\n                ! is_bool($column->generatedAs) && ! empty($column->generatedAs) ? \" ({$column->generatedAs})\" : ''\n            );\n        }\n\n        if ($column->change) {\n            $changes = $column->autoIncrement && is_null($sql) ? [] : ['drop identity if exists'];\n\n            if (! is_null($sql)) {\n                $changes[] = 'add '.$sql;\n            }\n\n            return $changes;\n        }\n\n        return $sql;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\IndexDefinition;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse RuntimeException;\n\nclass SQLiteGrammar extends Grammar\n{\n    /**\n     * The possible column modifiers.\n     *\n     * @var string[]\n     */\n    protected $modifiers = ['Increment', 'Nullable', 'Default', 'Collate', 'VirtualAs', 'StoredAs'];\n\n    /**\n     * The columns available as serials.\n     *\n     * @var string[]\n     */\n    protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger'];\n\n    /**\n     * Get the commands to be compiled on the alter command.\n     *\n     * @return array\n     */\n    public function getAlterCommands()\n    {\n        $alterCommands = ['change', 'primary', 'dropPrimary', 'foreign', 'dropForeign'];\n\n        if (version_compare($this->connection->getServerVersion(), '3.35', '<')) {\n            $alterCommands[] = 'dropColumn';\n        }\n\n        return $alterCommands;\n    }\n\n    /**\n     * Compile the query to determine the SQL text that describes the given object.\n     *\n     * @param  string|null  $schema\n     * @param  string  $name\n     * @param  string  $type\n     * @return string\n     */\n    public function compileSqlCreateStatement($schema, $name, $type = 'table')\n    {\n        return sprintf('select \"sql\" from %s.sqlite_master where type = %s and name = %s',\n            $this->wrapValue($schema ?? 'main'),\n            $this->quoteString($type),\n            $this->quoteString($name)\n        );\n    }\n\n    /**\n     * Compile the query to determine if the dbstat table is available.\n     *\n     * @return string\n     */\n    public function compileDbstatExists()\n    {\n        return \"select exists (select 1 from pragma_compile_options where compile_options = 'ENABLE_DBSTAT_VTAB') as enabled\";\n    }\n\n    /**\n     * Compile the query to determine the schemas.\n     *\n     * @return string\n     */\n    public function compileSchemas()\n    {\n        return 'select name, file as path, name = \\'main\\' as \"default\" from pragma_database_list order by name';\n    }\n\n    /**\n     * Compile the query to determine if the given table exists.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileTableExists($schema, $table)\n    {\n        return sprintf(\n            'select exists (select 1 from %s.sqlite_master where name = %s and type = \\'table\\') as \"exists\"',\n            $this->wrapValue($schema ?? 'main'),\n            $this->quoteString($table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the tables.\n     *\n     * @param  string|string[]|null  $schema\n     * @param  bool  $withSize\n     * @return string\n     */\n    public function compileTables($schema, $withSize = false)\n    {\n        return 'select tl.name as name, tl.schema as schema'\n            .($withSize ? ', (select sum(s.pgsize) '\n                .'from (select tl.name as name union select il.name as name from pragma_index_list(tl.name, tl.schema) as il) as es '\n                .'join dbstat(tl.schema) as s on s.name = es.name) as size' : '')\n            .' from pragma_table_list as tl where'\n            .(match (true) {\n                ! empty($schema) && is_array($schema) => ' tl.schema in ('.$this->quoteString($schema).') and',\n                ! empty($schema) => ' tl.schema = '.$this->quoteString($schema).' and',\n                default => '',\n            })\n            .\" tl.type in ('table', 'virtual') and tl.name not like 'sqlite\\_%' escape '\\' \"\n            .'order by tl.schema, tl.name';\n    }\n\n    /**\n     * Compile the query for legacy versions of SQLite to determine the tables.\n     *\n     * @param  string  $schema\n     * @param  bool  $withSize\n     * @return string\n     */\n    public function compileLegacyTables($schema, $withSize = false)\n    {\n        return $withSize\n            ? sprintf(\n                'select m.tbl_name as name, %s as schema, sum(s.pgsize) as size from %s.sqlite_master as m '\n                .'join dbstat(%s) as s on s.name = m.name '\n                .\"where m.type in ('table', 'index') and m.tbl_name not like 'sqlite\\_%%' escape '\\' \"\n                .'group by m.tbl_name '\n                .'order by m.tbl_name',\n                $this->quoteString($schema),\n                $this->wrapValue($schema),\n                $this->quoteString($schema)\n            )\n            : sprintf(\n                'select name, %s as schema from %s.sqlite_master '\n                .\"where type = 'table' and name not like 'sqlite\\_%%' escape '\\' order by name\",\n                $this->quoteString($schema),\n                $this->wrapValue($schema)\n            );\n    }\n\n    /**\n     * Compile the query to determine the views.\n     *\n     * @param  string  $schema\n     * @return string\n     */\n    public function compileViews($schema)\n    {\n        return sprintf(\n            \"select name, %s as schema, sql as definition from %s.sqlite_master where type = 'view' order by name\",\n            $this->quoteString($schema),\n            $this->wrapValue($schema)\n        );\n    }\n\n    /**\n     * Compile the query to determine the columns.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileColumns($schema, $table)\n    {\n        return sprintf(\n            'select name, type, not \"notnull\" as \"nullable\", dflt_value as \"default\", pk as \"primary\", hidden as \"extra\" '\n            .'from pragma_table_xinfo(%s, %s) order by cid asc',\n            $this->quoteString($table),\n            $this->quoteString($schema ?? 'main')\n        );\n    }\n\n    /**\n     * Compile the query to determine the indexes.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileIndexes($schema, $table)\n    {\n        return sprintf(\n            'select \\'primary\\' as name, group_concat(col) as columns, 1 as \"unique\", 1 as \"primary\" '\n            .'from (select name as col from pragma_table_xinfo(%s, %s) where pk > 0 order by pk, cid) group by name '\n            .'union select name, group_concat(col) as columns, \"unique\", origin = \\'pk\\' as \"primary\" '\n            .'from (select il.*, ii.name as col from pragma_index_list(%s, %s) il, pragma_index_info(il.name, %s) ii order by il.seq, ii.seqno) '\n            .'group by name, \"unique\", \"primary\"',\n            $table = $this->quoteString($table),\n            $schema = $this->quoteString($schema ?? 'main'),\n            $table,\n            $schema,\n            $schema\n        );\n    }\n\n    /**\n     * Compile the query to determine the foreign keys.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileForeignKeys($schema, $table)\n    {\n        return sprintf(\n            'select group_concat(\"from\") as columns, %s as foreign_schema, \"table\" as foreign_table, '\n            .'group_concat(\"to\") as foreign_columns, on_update, on_delete '\n            .'from (select * from pragma_foreign_key_list(%s, %s) order by id desc, seq) '\n            .'group by id, \"table\", on_update, on_delete',\n            $schema = $this->quoteString($schema ?? 'main'),\n            $this->quoteString($table),\n            $schema\n        );\n    }\n\n    /**\n     * Compile a create table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileCreate(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('%s table %s (%s%s%s)',\n            $blueprint->temporary ? 'create temporary' : 'create',\n            $this->wrapTable($blueprint),\n            implode(', ', $this->getColumns($blueprint)),\n            $this->addForeignKeys($this->getCommandsByName($blueprint, 'foreign')),\n            $this->addPrimaryKeys($this->getCommandByName($blueprint, 'primary'))\n        );\n    }\n\n    /**\n     * Get the foreign key syntax for a table creation statement.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\ForeignKeyDefinition[]  $foreignKeys\n     * @return string|null\n     */\n    protected function addForeignKeys($foreignKeys)\n    {\n        return (new Collection($foreignKeys))->reduce(function ($sql, $foreign) {\n            // Once we have all the foreign key commands for the table creation statement\n            // we'll loop through each of them and add them to the create table SQL we\n            // are building, since SQLite needs foreign keys on the tables creation.\n            return $sql.$this->getForeignKey($foreign);\n        }, '');\n    }\n\n    /**\n     * Get the SQL for the foreign key.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $foreign\n     * @return string\n     */\n    protected function getForeignKey($foreign)\n    {\n        // We need to columnize the columns that the foreign key is being defined for\n        // so that it is a properly formatted list. Once we have done this, we can\n        // return the foreign key SQL declaration to the calling method for use.\n        $sql = sprintf(', foreign key(%s) references %s(%s)',\n            $this->columnize($foreign->columns),\n            $this->wrapTable($foreign->on),\n            $this->columnize((array) $foreign->references)\n        );\n\n        if (! is_null($foreign->onDelete)) {\n            $sql .= \" on delete {$foreign->onDelete}\";\n        }\n\n        // If this foreign key specifies the action to be taken on update we will add\n        // that to the statement here. We'll append it to this SQL and then return\n        // this SQL so we can keep adding any other foreign constraints to this.\n        if (! is_null($foreign->onUpdate)) {\n            $sql .= \" on update {$foreign->onUpdate}\";\n        }\n\n        return $sql;\n    }\n\n    /**\n     * Get the primary key syntax for a table creation statement.\n     *\n     * @param  \\Illuminate\\Support\\Fluent|null  $primary\n     * @return string|null\n     */\n    protected function addPrimaryKeys($primary)\n    {\n        if (! is_null($primary)) {\n            return \", primary key ({$this->columnize($primary->columns)})\";\n        }\n    }\n\n    /**\n     * Compile alter table commands for adding columns.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAdd(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add column %s',\n            $this->wrapTable($blueprint),\n            $this->getColumn($blueprint, $command->column)\n        );\n    }\n\n    /**\n     * Compile alter table command into a series of SQL statements.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return list<string>|string\n     */\n    public function compileAlter(Blueprint $blueprint, Fluent $command)\n    {\n        $columnNames = [];\n        $autoIncrementColumn = null;\n\n        $columns = (new Collection($blueprint->getState()->getColumns()))\n            ->map(function ($column) use ($blueprint, &$columnNames, &$autoIncrementColumn) {\n                $name = $this->wrap($column);\n\n                $autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn;\n\n                if (is_null($column->virtualAs) && is_null($column->virtualAsJson) &&\n                    is_null($column->storedAs) && is_null($column->storedAsJson)) {\n                    $columnNames[] = $name;\n                }\n\n                return $this->addModifiers(\n                    $this->wrap($column).' '.($column->full_type_definition ?? $this->getType($column)),\n                    $blueprint,\n                    $column\n                );\n            })->all();\n\n        $indexes = (new Collection($blueprint->getState()->getIndexes()))\n            ->reject(fn ($index) => str_starts_with('sqlite_', $index->index))\n            ->map(fn ($index) => $this->{'compile'.ucfirst($index->name)}($blueprint, $index))\n            ->all();\n\n        [, $tableName] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($blueprint->getTable());\n        $tempTable = $this->wrapTable($blueprint, '__temp__'.$this->connection->getTablePrefix());\n        $table = $this->wrapTable($blueprint);\n        $columnNames = implode(', ', $columnNames);\n\n        $foreignKeyConstraintsEnabled = $this->connection->scalar($this->pragma('foreign_keys'));\n\n        return array_filter(array_merge([\n            $foreignKeyConstraintsEnabled ? $this->compileDisableForeignKeyConstraints() : null,\n            sprintf('create table %s (%s%s%s)',\n                $tempTable,\n                implode(', ', $columns),\n                $this->addForeignKeys($blueprint->getState()->getForeignKeys()),\n                $autoIncrementColumn ? '' : $this->addPrimaryKeys($blueprint->getState()->getPrimaryKey())\n            ),\n            sprintf('insert into %s (%s) select %s from %s', $tempTable, $columnNames, $columnNames, $table),\n            sprintf('drop table %s', $table),\n            sprintf('alter table %s rename to %s', $tempTable, $this->wrapTable($tableName)),\n        ], $indexes, [$foreignKeyConstraintsEnabled ? $this->compileEnableForeignKeyConstraints() : null]));\n    }\n\n    /** @inheritDoc */\n    public function compileChange(Blueprint $blueprint, Fluent $command)\n    {\n        // Handled on table alteration...\n    }\n\n    /**\n     * Compile a primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compilePrimary(Blueprint $blueprint, Fluent $command)\n    {\n        // Handled on table creation or alteration...\n    }\n\n    /**\n     * Compile a unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileUnique(Blueprint $blueprint, Fluent $command)\n    {\n        [$schema, $table] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($blueprint->getTable());\n\n        return sprintf('create unique index %s%s on %s (%s)',\n            $schema ? $this->wrapValue($schema).'.' : '',\n            $this->wrap($command->index),\n            $this->wrapTable($table),\n            $this->columnize($command->columns)\n        );\n    }\n\n    /**\n     * Compile a plain index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileIndex(Blueprint $blueprint, Fluent $command)\n    {\n        [$schema, $table] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($blueprint->getTable());\n\n        return sprintf('create index %s%s on %s (%s)',\n            $schema ? $this->wrapValue($schema).'.' : '',\n            $this->wrap($command->index),\n            $this->wrapTable($table),\n            $this->columnize($command->columns)\n        );\n    }\n\n    /**\n     * Compile a spatial index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('The database driver in use does not support spatial indexes.');\n    }\n\n    /**\n     * Compile a foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string|null\n     */\n    public function compileForeign(Blueprint $blueprint, Fluent $command)\n    {\n        // Handled on table creation or alteration...\n    }\n\n    /**\n     * Compile a drop table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDrop(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile a drop table (if exists) command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table if exists '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile the SQL needed to drop all tables.\n     *\n     * @param  string|null  $schema\n     * @return string\n     */\n    public function compileDropAllTables($schema = null)\n    {\n        return sprintf(\"delete from %s.sqlite_master where type in ('table', 'index', 'trigger')\",\n            $this->wrapValue($schema ?? 'main')\n        );\n    }\n\n    /**\n     * Compile the SQL needed to drop all views.\n     *\n     * @param  string|null  $schema\n     * @return string\n     */\n    public function compileDropAllViews($schema = null)\n    {\n        return sprintf(\"delete from %s.sqlite_master where type in ('view')\",\n            $this->wrapValue($schema ?? 'main')\n        );\n    }\n\n    /**\n     * Compile the SQL needed to rebuild the database.\n     *\n     * @param  string|null  $schema\n     * @return string\n     */\n    public function compileRebuild($schema = null)\n    {\n        return sprintf('vacuum %s',\n            $this->wrapValue($schema ?? 'main')\n        );\n    }\n\n    /**\n     * Compile a drop column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return list<string>|null\n     */\n    public function compileDropColumn(Blueprint $blueprint, Fluent $command)\n    {\n        if (version_compare($this->connection->getServerVersion(), '3.35', '<')) {\n            // Handled on table alteration...\n\n            return null;\n        }\n\n        $table = $this->wrapTable($blueprint);\n\n        $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns));\n\n        return (new Collection($columns))->map(fn ($column) => 'alter table '.$table.' '.$column)->all();\n    }\n\n    /**\n     * Compile a drop primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)\n    {\n        // Handled on table alteration...\n    }\n\n    /**\n     * Compile a drop unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropUnique(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a drop index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIndex(Blueprint $blueprint, Fluent $command)\n    {\n        [$schema] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($blueprint->getTable());\n\n        return sprintf('drop index %s%s',\n            $schema ? $this->wrapValue($schema).'.' : '',\n            $this->wrap($command->index)\n        );\n    }\n\n    /**\n     * Compile a drop spatial index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        throw new RuntimeException('The database driver in use does not support spatial indexes.');\n    }\n\n    /**\n     * Compile a drop foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileDropForeign(Blueprint $blueprint, Fluent $command)\n    {\n        if (empty($command->columns)) {\n            throw new RuntimeException('This database driver does not support dropping foreign keys by name.');\n        }\n\n        // Handled on table alteration...\n    }\n\n    /**\n     * Compile a rename table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRename(Blueprint $blueprint, Fluent $command)\n    {\n        $from = $this->wrapTable($blueprint);\n\n        return \"alter table {$from} rename to \".$this->wrapTable($command->to);\n    }\n\n    /**\n     * Compile a rename index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)\n    {\n        $indexes = $this->connection->getSchemaBuilder()->getIndexes($blueprint->getTable());\n\n        $index = Arr::first($indexes, fn ($index) => $index['name'] === $command->from);\n\n        if (! $index) {\n            throw new RuntimeException(\"Index [{$command->from}] does not exist.\");\n        }\n\n        if ($index['primary']) {\n            throw new RuntimeException('SQLite does not support altering primary keys.');\n        }\n\n        if ($index['unique']) {\n            return [\n                $this->compileDropUnique($blueprint, new IndexDefinition(['index' => $index['name']])),\n                $this->compileUnique($blueprint,\n                    new IndexDefinition(['index' => $command->to, 'columns' => $index['columns']])\n                ),\n            ];\n        }\n\n        return [\n            $this->compileDropIndex($blueprint, new IndexDefinition(['index' => $index['name']])),\n            $this->compileIndex($blueprint,\n                new IndexDefinition(['index' => $command->to, 'columns' => $index['columns']])\n            ),\n        ];\n    }\n\n    /**\n     * Compile the command to enable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileEnableForeignKeyConstraints()\n    {\n        return $this->pragma('foreign_keys', 1);\n    }\n\n    /**\n     * Compile the command to disable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileDisableForeignKeyConstraints()\n    {\n        return $this->pragma('foreign_keys', 0);\n    }\n\n    /**\n     * Get the SQL to get or set a PRAGMA value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return string\n     */\n    public function pragma(string $key, mixed $value = null): string\n    {\n        return sprintf('pragma %s%s',\n            $key,\n            is_null($value) ? '' : ' = '.$value\n        );\n    }\n\n    /**\n     * Create the column definition for a char type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeChar(Fluent $column)\n    {\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for a string type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeString(Fluent $column)\n    {\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for a tiny text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a medium text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for a long text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeLongText(Fluent $column)\n    {\n        return 'text';\n    }\n\n    /**\n     * Create the column definition for an integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeInteger(Fluent $column)\n    {\n        return 'integer';\n    }\n\n    /**\n     * Create the column definition for a big integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBigInteger(Fluent $column)\n    {\n        return 'integer';\n    }\n\n    /**\n     * Create the column definition for a medium integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumInteger(Fluent $column)\n    {\n        return 'integer';\n    }\n\n    /**\n     * Create the column definition for a tiny integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyInteger(Fluent $column)\n    {\n        return 'integer';\n    }\n\n    /**\n     * Create the column definition for a small integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeSmallInteger(Fluent $column)\n    {\n        return 'integer';\n    }\n\n    /**\n     * Create the column definition for a float type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeFloat(Fluent $column)\n    {\n        return 'float';\n    }\n\n    /**\n     * Create the column definition for a double type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDouble(Fluent $column)\n    {\n        return 'double';\n    }\n\n    /**\n     * Create the column definition for a decimal type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDecimal(Fluent $column)\n    {\n        return 'numeric';\n    }\n\n    /**\n     * Create the column definition for a boolean type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBoolean(Fluent $column)\n    {\n        return 'tinyint(1)';\n    }\n\n    /**\n     * Create the column definition for an enumeration type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeEnum(Fluent $column)\n    {\n        return sprintf(\n            'varchar check (\"%s\" in (%s))',\n            $column->name,\n            $this->quoteString($column->allowed)\n        );\n    }\n\n    /**\n     * Create the column definition for a json type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJson(Fluent $column)\n    {\n        return $this->connection->getConfig('use_native_json') ? 'json' : 'text';\n    }\n\n    /**\n     * Create the column definition for a jsonb type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJsonb(Fluent $column)\n    {\n        return $this->connection->getConfig('use_native_jsonb') ? 'jsonb' : 'text';\n    }\n\n    /**\n     * Create the column definition for a date type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDate(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_DATE'));\n        }\n\n        return 'date';\n    }\n\n    /**\n     * Create the column definition for a date-time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTime(Fluent $column)\n    {\n        return $this->typeTimestamp($column);\n    }\n\n    /**\n     * Create the column definition for a date-time (with time zone) type.\n     *\n     * Note: \"SQLite does not have a storage class set aside for storing dates and/or times.\"\n     *\n     * @link https://www.sqlite.org/datatype3.html\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTimeTz(Fluent $column)\n    {\n        return $this->typeDateTime($column);\n    }\n\n    /**\n     * Create the column definition for a time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTime(Fluent $column)\n    {\n        return 'time';\n    }\n\n    /**\n     * Create the column definition for a time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimeTz(Fluent $column)\n    {\n        return $this->typeTime($column);\n    }\n\n    /**\n     * Create the column definition for a timestamp type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestamp(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_TIMESTAMP'));\n        }\n\n        return 'datetime';\n    }\n\n    /**\n     * Create the column definition for a timestamp (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestampTz(Fluent $column)\n    {\n        return $this->typeTimestamp($column);\n    }\n\n    /**\n     * Create the column definition for a year type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeYear(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression(\"(CAST(strftime('%Y', 'now') AS INTEGER))\"));\n        }\n\n        return $this->typeInteger($column);\n    }\n\n    /**\n     * Create the column definition for a binary type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBinary(Fluent $column)\n    {\n        return 'blob';\n    }\n\n    /**\n     * Create the column definition for a uuid type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeUuid(Fluent $column)\n    {\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for an IP address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeIpAddress(Fluent $column)\n    {\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for a MAC address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMacAddress(Fluent $column)\n    {\n        return 'varchar';\n    }\n\n    /**\n     * Create the column definition for a spatial Geometry type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeometry(Fluent $column)\n    {\n        return 'geometry';\n    }\n\n    /**\n     * Create the column definition for a spatial Geography type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeography(Fluent $column)\n    {\n        return $this->typeGeometry($column);\n    }\n\n    /**\n     * Create the column definition for a generated, computed column type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function typeComputed(Fluent $column)\n    {\n        throw new RuntimeException('This database driver requires a type, see the virtualAs / storedAs modifiers.');\n    }\n\n    /**\n     * Get the SQL for a generated virtual column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($virtualAs = $column->virtualAsJson)) {\n            if ($this->isJsonSelector($virtualAs)) {\n                $virtualAs = $this->wrapJsonSelector($virtualAs);\n            }\n\n            return \" as ({$virtualAs})\";\n        }\n\n        if (! is_null($virtualAs = $column->virtualAs)) {\n            return \" as ({$this->getValue($virtualAs)})\";\n        }\n    }\n\n    /**\n     * Get the SQL for a generated stored column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyStoredAs(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($storedAs = $column->storedAsJson)) {\n            if ($this->isJsonSelector($storedAs)) {\n                $storedAs = $this->wrapJsonSelector($storedAs);\n            }\n\n            return \" as ({$storedAs}) stored\";\n        }\n\n        if (! is_null($storedAs = $column->storedAs)) {\n            return \" as ({$this->getValue($column->storedAs)}) stored\";\n        }\n    }\n\n    /**\n     * Get the SQL for a nullable column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyNullable(Blueprint $blueprint, Fluent $column)\n    {\n        if (is_null($column->virtualAs) &&\n            is_null($column->virtualAsJson) &&\n            is_null($column->storedAs) &&\n            is_null($column->storedAsJson)) {\n            return $column->nullable ? '' : ' not null';\n        }\n\n        if ($column->nullable === false) {\n            return ' not null';\n        }\n    }\n\n    /**\n     * Get the SQL for a default column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyDefault(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->virtualAsJson) && is_null($column->storedAs)) {\n            return ' default '.$this->getDefaultValue($column->default);\n        }\n    }\n\n    /**\n     * Get the SQL for an auto-increment column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)\n    {\n        if (in_array($column->type, $this->serials) && $column->autoIncrement) {\n            return ' primary key autoincrement';\n        }\n    }\n\n    /**\n     * Get the SQL for a collation column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyCollate(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->collation)) {\n            return \" collate '{$column->collation}'\";\n        }\n    }\n\n    /**\n     * Wrap the given JSON selector.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapJsonSelector($value)\n    {\n        [$field, $path] = $this->wrapJsonFieldAndPath($value);\n\n        return 'json_extract('.$field.$path.')';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema\\Grammars;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Fluent;\n\nclass SqlServerGrammar extends Grammar\n{\n    /**\n     * If this Grammar supports schema changes wrapped in a transaction.\n     *\n     * @var bool\n     */\n    protected $transactions = true;\n\n    /**\n     * The possible column modifiers.\n     *\n     * @var string[]\n     */\n    protected $modifiers = ['Collate', 'Nullable', 'Default', 'Persisted', 'Increment'];\n\n    /**\n     * The columns available as serials.\n     *\n     * @var string[]\n     */\n    protected $serials = ['tinyInteger', 'smallInteger', 'mediumInteger', 'integer', 'bigInteger'];\n\n    /**\n     * The commands to be executed outside of create or alter command.\n     *\n     * @var string[]\n     */\n    protected $fluentCommands = ['Default'];\n\n    /**\n     * Compile the query to determine the schemas.\n     *\n     * @return string\n     */\n    public function compileSchemas()\n    {\n        return 'select name, iif(schema_id = schema_id(), 1, 0) as [default] from sys.schemas '\n            .\"where name not in ('information_schema', 'sys') and name not like 'db[_]%' order by name\";\n    }\n\n    /**\n     * Compile the query to determine if the given table exists.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileTableExists($schema, $table)\n    {\n        return sprintf(\n            'select (case when object_id(%s, \\'U\\') is null then 0 else 1 end) as [exists]',\n            $this->quoteString($schema ? $schema.'.'.$table : $table)\n        );\n    }\n\n    /**\n     * Compile the query to determine the tables.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileTables($schema)\n    {\n        return 'select t.name as name, schema_name(t.schema_id) as [schema], sum(u.total_pages) * 8 * 1024 as size '\n            .'from sys.tables as t '\n            .'join sys.partitions as p on p.object_id = t.object_id '\n            .'join sys.allocation_units as u on u.container_id = p.hobt_id '\n            .\"where t.is_ms_shipped = 0 and t.name <> 'sysdiagrams'\"\n            .$this->compileSchemaWhereClause($schema, 'schema_name(t.schema_id)')\n            .' group by t.name, t.schema_id '\n            .'order by [schema], t.name';\n    }\n\n    /**\n     * Compile the query to determine the views.\n     *\n     * @param  string|string[]|null  $schema\n     * @return string\n     */\n    public function compileViews($schema)\n    {\n        return 'select name, schema_name(v.schema_id) as [schema], definition from sys.views as v '\n            .'inner join sys.sql_modules as m on v.object_id = m.object_id '\n            .'where v.is_ms_shipped = 0'\n            .$this->compileSchemaWhereClause($schema, 'schema_name(v.schema_id)')\n            .' order by [schema], name';\n    }\n\n    /**\n     * Compile the query to compare the schema.\n     *\n     * @param  string|string[]|null  $schema\n     * @param  string  $column\n     * @return string\n     */\n    protected function compileSchemaWhereClause($schema, $column)\n    {\n        return match (true) {\n            ! empty($schema) && is_array($schema) => \" and $column in (\".$this->quoteString($schema).')',\n            ! empty($schema) => \" and $column = \".$this->quoteString($schema),\n            default => '',\n        };\n    }\n\n    /**\n     * Compile the query to determine the columns.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileColumns($schema, $table)\n    {\n        return sprintf(\n            'select col.name, type.name as type_name, '\n            .'col.max_length as length, col.precision as precision, col.scale as places, '\n            .'col.is_nullable as nullable, def.definition as [default], '\n            .'col.is_identity as autoincrement, col.collation_name as collation, '\n            .'com.definition as [expression], is_persisted as [persisted], '\n            .'cast(prop.value as nvarchar(max)) as comment '\n            .'from sys.columns as col '\n            .'join sys.types as type on col.user_type_id = type.user_type_id '\n            .'join sys.objects as obj on col.object_id = obj.object_id '\n            .'join sys.schemas as scm on obj.schema_id = scm.schema_id '\n            .'left join sys.default_constraints def on col.default_object_id = def.object_id and col.object_id = def.parent_object_id '\n            .\"left join sys.extended_properties as prop on obj.object_id = prop.major_id and col.column_id = prop.minor_id and prop.name = 'MS_Description' \"\n            .'left join sys.computed_columns as com on col.column_id = com.column_id and col.object_id = com.object_id '\n            .\"where obj.type in ('U', 'V') and obj.name = %s and scm.name = %s \"\n            .'order by col.column_id',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'schema_name()',\n        );\n    }\n\n    /**\n     * Compile the query to determine the indexes.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileIndexes($schema, $table)\n    {\n        return sprintf(\n            \"select idx.name as name, string_agg(col.name, ',') within group (order by idxcol.key_ordinal) as columns, \"\n            .'idx.type_desc as [type], idx.is_unique as [unique], idx.is_primary_key as [primary] '\n            .'from sys.indexes as idx '\n            .'join sys.tables as tbl on idx.object_id = tbl.object_id '\n            .'join sys.schemas as scm on tbl.schema_id = scm.schema_id '\n            .'join sys.index_columns as idxcol on idx.object_id = idxcol.object_id and idx.index_id = idxcol.index_id '\n            .'join sys.columns as col on idxcol.object_id = col.object_id and idxcol.column_id = col.column_id '\n            .'where tbl.name = %s and scm.name = %s '\n            .'group by idx.name, idx.type_desc, idx.is_unique, idx.is_primary_key',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'schema_name()',\n        );\n    }\n\n    /**\n     * Compile the query to determine the foreign keys.\n     *\n     * @param  string|null  $schema\n     * @param  string  $table\n     * @return string\n     */\n    public function compileForeignKeys($schema, $table)\n    {\n        return sprintf(\n            'select fk.name as name, '\n            .\"string_agg(lc.name, ',') within group (order by fkc.constraint_column_id) as columns, \"\n            .'fs.name as foreign_schema, ft.name as foreign_table, '\n            .\"string_agg(fc.name, ',') within group (order by fkc.constraint_column_id) as foreign_columns, \"\n            .'fk.update_referential_action_desc as on_update, '\n            .'fk.delete_referential_action_desc as on_delete '\n            .'from sys.foreign_keys as fk '\n            .'join sys.foreign_key_columns as fkc on fkc.constraint_object_id = fk.object_id '\n            .'join sys.tables as lt on lt.object_id = fk.parent_object_id '\n            .'join sys.schemas as ls on lt.schema_id = ls.schema_id '\n            .'join sys.columns as lc on fkc.parent_object_id = lc.object_id and fkc.parent_column_id = lc.column_id '\n            .'join sys.tables as ft on ft.object_id = fk.referenced_object_id '\n            .'join sys.schemas as fs on ft.schema_id = fs.schema_id '\n            .'join sys.columns as fc on fkc.referenced_object_id = fc.object_id and fkc.referenced_column_id = fc.column_id '\n            .'where lt.name = %s and ls.name = %s '\n            .'group by fk.name, fs.name, ft.name, fk.update_referential_action_desc, fk.delete_referential_action_desc',\n            $this->quoteString($table),\n            $schema ? $this->quoteString($schema) : 'schema_name()',\n        );\n    }\n\n    /**\n     * Compile a create table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileCreate(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('create table %s (%s)',\n            $this->wrapTable($blueprint, $blueprint->temporary ? '#'.$this->connection->getTablePrefix() : null),\n            implode(', ', $this->getColumns($blueprint))\n        );\n    }\n\n    /**\n     * Compile a column addition table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileAdd(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add %s',\n            $this->wrapTable($blueprint),\n            $this->getColumn($blueprint, $command->column)\n        );\n    }\n\n    /** @inheritDoc */\n    public function compileRenameColumn(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf(\"sp_rename %s, %s, N'COLUMN'\",\n            $this->quoteString($this->wrapTable($blueprint).'.'.$this->wrap($command->from)),\n            $this->wrap($command->to)\n        );\n    }\n\n    /** @inheritDoc */\n    public function compileChange(Blueprint $blueprint, Fluent $command)\n    {\n        return [\n            $this->compileDropDefaultConstraint($blueprint, $command),\n            sprintf('alter table %s alter column %s',\n                $this->wrapTable($blueprint),\n                $this->getColumn($blueprint, $command->column),\n            ),\n        ];\n    }\n\n    /**\n     * Compile a primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compilePrimary(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('alter table %s add constraint %s primary key (%s)',\n            $this->wrapTable($blueprint),\n            $this->wrap($command->index),\n            $this->columnize($command->columns)\n        );\n    }\n\n    /**\n     * Compile a unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileUnique(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('create unique index %s on %s (%s)%s',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            $this->columnize($command->columns),\n            $command->online ? ' with (online = on)' : ''\n        );\n    }\n\n    /**\n     * Compile a plain index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('create index %s on %s (%s)%s',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            $this->columnize($command->columns),\n            $command->online ? ' with (online = on)' : ''\n        );\n    }\n\n    /**\n     * Compile a spatial index key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('create spatial index %s on %s (%s)',\n            $this->wrap($command->index),\n            $this->wrapTable($blueprint),\n            $this->columnize($command->columns)\n        );\n    }\n\n    /**\n     * Compile a default command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string|null\n     */\n    public function compileDefault(Blueprint $blueprint, Fluent $command)\n    {\n        if ($command->column->change && ! is_null($command->column->default)) {\n            return sprintf('alter table %s add default %s for %s',\n                $this->wrapTable($blueprint),\n                $this->getDefaultValue($command->column->default),\n                $this->wrap($command->column)\n            );\n        }\n    }\n\n    /**\n     * Compile a drop table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDrop(Blueprint $blueprint, Fluent $command)\n    {\n        return 'drop table '.$this->wrapTable($blueprint);\n    }\n\n    /**\n     * Compile a drop table (if exists) command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIfExists(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('if object_id(%s, \\'U\\') is not null drop table %s',\n            $this->quoteString($this->wrapTable($blueprint)),\n            $this->wrapTable($blueprint)\n        );\n    }\n\n    /**\n     * Compile the SQL needed to drop all tables.\n     *\n     * @return string\n     */\n    public function compileDropAllTables()\n    {\n        return \"EXEC sp_msforeachtable 'DROP TABLE ?'\";\n    }\n\n    /**\n     * Compile a drop column command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropColumn(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $this->wrapArray($command->columns);\n\n        $dropExistingConstraintsSql = $this->compileDropDefaultConstraint($blueprint, $command).';';\n\n        return $dropExistingConstraintsSql.'alter table '.$this->wrapTable($blueprint).' drop column '.implode(', ', $columns);\n    }\n\n    /**\n     * Compile a drop default constraint command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropDefaultConstraint(Blueprint $blueprint, Fluent $command)\n    {\n        $columns = $command->name === 'change'\n            ? \"'\".$command->column->name.\"'\"\n            : \"'\".implode(\"', '\", $command->columns).\"'\";\n\n        $table = $this->wrapTable($blueprint);\n        $tableName = $this->quoteString($this->wrapTable($blueprint));\n\n        $sql = \"DECLARE @sql NVARCHAR(MAX) = '';\";\n        $sql .= \"SELECT @sql += 'ALTER TABLE $table DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' \";\n        $sql .= 'FROM sys.columns ';\n        $sql .= \"WHERE [object_id] = OBJECT_ID($tableName) AND [name] in ($columns) AND [default_object_id] <> 0;\";\n        $sql .= 'EXEC(@sql)';\n\n        return $sql;\n    }\n\n    /**\n     * Compile a drop primary key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropPrimary(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop constraint {$index}\";\n    }\n\n    /**\n     * Compile a drop unique key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropUnique(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"drop index {$index} on {$this->wrapTable($blueprint)}\";\n    }\n\n    /**\n     * Compile a drop index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropIndex(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"drop index {$index} on {$this->wrapTable($blueprint)}\";\n    }\n\n    /**\n     * Compile a drop spatial index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return $this->compileDropIndex($blueprint, $command);\n    }\n\n    /**\n     * Compile a drop foreign key command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileDropForeign(Blueprint $blueprint, Fluent $command)\n    {\n        $index = $this->wrap($command->index);\n\n        return \"alter table {$this->wrapTable($blueprint)} drop constraint {$index}\";\n    }\n\n    /**\n     * Compile a rename table command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRename(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf('sp_rename %s, %s',\n            $this->quoteString($this->wrapTable($blueprint)),\n            $this->wrapTable($command->to)\n        );\n    }\n\n    /**\n     * Compile a rename index command.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $command\n     * @return string\n     */\n    public function compileRenameIndex(Blueprint $blueprint, Fluent $command)\n    {\n        return sprintf(\"sp_rename %s, %s, N'INDEX'\",\n            $this->quoteString($this->wrapTable($blueprint).'.'.$this->wrap($command->from)),\n            $this->wrap($command->to)\n        );\n    }\n\n    /**\n     * Compile the command to enable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileEnableForeignKeyConstraints()\n    {\n        return 'EXEC sp_msforeachtable @command1=\"print \\'?\\'\", @command2=\"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\";';\n    }\n\n    /**\n     * Compile the command to disable foreign key constraints.\n     *\n     * @return string\n     */\n    public function compileDisableForeignKeyConstraints()\n    {\n        return 'EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\";';\n    }\n\n    /**\n     * Compile the command to drop all foreign keys.\n     *\n     * @return string\n     */\n    public function compileDropAllForeignKeys()\n    {\n        return \"DECLARE @sql NVARCHAR(MAX) = N'';\n            SELECT @sql += 'ALTER TABLE '\n                + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + + QUOTENAME(OBJECT_NAME(parent_object_id))\n                + ' DROP CONSTRAINT ' + QUOTENAME(name) + ';'\n            FROM sys.foreign_keys;\n\n            EXEC sp_executesql @sql;\";\n    }\n\n    /**\n     * Compile the command to drop all views.\n     *\n     * @return string\n     */\n    public function compileDropAllViews()\n    {\n        return \"DECLARE @sql NVARCHAR(MAX) = N'';\n            SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';'\n            FROM sys.views;\n\n            EXEC sp_executesql @sql;\";\n    }\n\n    /**\n     * Create the column definition for a char type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeChar(Fluent $column)\n    {\n        return \"nchar({$column->length})\";\n    }\n\n    /**\n     * Create the column definition for a string type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeString(Fluent $column)\n    {\n        return \"nvarchar({$column->length})\";\n    }\n\n    /**\n     * Create the column definition for a tiny text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyText(Fluent $column)\n    {\n        return 'nvarchar(255)';\n    }\n\n    /**\n     * Create the column definition for a text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeText(Fluent $column)\n    {\n        return 'nvarchar(max)';\n    }\n\n    /**\n     * Create the column definition for a medium text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumText(Fluent $column)\n    {\n        return 'nvarchar(max)';\n    }\n\n    /**\n     * Create the column definition for a long text type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeLongText(Fluent $column)\n    {\n        return 'nvarchar(max)';\n    }\n\n    /**\n     * Create the column definition for an integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeInteger(Fluent $column)\n    {\n        return 'int';\n    }\n\n    /**\n     * Create the column definition for a big integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBigInteger(Fluent $column)\n    {\n        return 'bigint';\n    }\n\n    /**\n     * Create the column definition for a medium integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMediumInteger(Fluent $column)\n    {\n        return 'int';\n    }\n\n    /**\n     * Create the column definition for a tiny integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTinyInteger(Fluent $column)\n    {\n        return 'tinyint';\n    }\n\n    /**\n     * Create the column definition for a small integer type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeSmallInteger(Fluent $column)\n    {\n        return 'smallint';\n    }\n\n    /**\n     * Create the column definition for a float type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeFloat(Fluent $column)\n    {\n        if ($column->precision) {\n            return \"float({$column->precision})\";\n        }\n\n        return 'float';\n    }\n\n    /**\n     * Create the column definition for a double type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDouble(Fluent $column)\n    {\n        return 'double precision';\n    }\n\n    /**\n     * Create the column definition for a decimal type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDecimal(Fluent $column)\n    {\n        return \"decimal({$column->total}, {$column->places})\";\n    }\n\n    /**\n     * Create the column definition for a boolean type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBoolean(Fluent $column)\n    {\n        return 'bit';\n    }\n\n    /**\n     * Create the column definition for an enumeration type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeEnum(Fluent $column)\n    {\n        return sprintf(\n            'nvarchar(255) check (\"%s\" in (%s))',\n            $column->name,\n            $this->quoteString($column->allowed)\n        );\n    }\n\n    /**\n     * Create the column definition for a json type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJson(Fluent $column)\n    {\n        return 'nvarchar(max)';\n    }\n\n    /**\n     * Create the column definition for a jsonb type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeJsonb(Fluent $column)\n    {\n        return 'nvarchar(max)';\n    }\n\n    /**\n     * Create the column definition for a date type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDate(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CAST(GETDATE() AS DATE)'));\n        }\n\n        return 'date';\n    }\n\n    /**\n     * Create the column definition for a date-time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTime(Fluent $column)\n    {\n        return $this->typeTimestamp($column);\n    }\n\n    /**\n     * Create the column definition for a date-time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeDateTimeTz(Fluent $column)\n    {\n        return $this->typeTimestampTz($column);\n    }\n\n    /**\n     * Create the column definition for a time type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTime(Fluent $column)\n    {\n        return $column->precision ? \"time($column->precision)\" : 'time';\n    }\n\n    /**\n     * Create the column definition for a time (with time zone) type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimeTz(Fluent $column)\n    {\n        return $this->typeTime($column);\n    }\n\n    /**\n     * Create the column definition for a timestamp type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestamp(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_TIMESTAMP'));\n        }\n\n        return $column->precision ? \"datetime2($column->precision)\" : 'datetime';\n    }\n\n    /**\n     * Create the column definition for a timestamp (with time zone) type.\n     *\n     * @link https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql?view=sql-server-ver15\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeTimestampTz(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CURRENT_TIMESTAMP'));\n        }\n\n        return $column->precision ? \"datetimeoffset($column->precision)\" : 'datetimeoffset';\n    }\n\n    /**\n     * Create the column definition for a year type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeYear(Fluent $column)\n    {\n        if ($column->useCurrent) {\n            $column->default(new Expression('CAST(YEAR(GETDATE()) AS INTEGER)'));\n        }\n\n        return $this->typeInteger($column);\n    }\n\n    /**\n     * Create the column definition for a binary type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeBinary(Fluent $column)\n    {\n        if ($column->length) {\n            return $column->fixed ? \"binary({$column->length})\" : \"varbinary({$column->length})\";\n        }\n\n        return 'varbinary(max)';\n    }\n\n    /**\n     * Create the column definition for a uuid type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeUuid(Fluent $column)\n    {\n        return 'uniqueidentifier';\n    }\n\n    /**\n     * Create the column definition for an IP address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeIpAddress(Fluent $column)\n    {\n        return 'nvarchar(45)';\n    }\n\n    /**\n     * Create the column definition for a MAC address type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeMacAddress(Fluent $column)\n    {\n        return 'nvarchar(17)';\n    }\n\n    /**\n     * Create the column definition for a spatial Geometry type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeometry(Fluent $column)\n    {\n        return 'geometry';\n    }\n\n    /**\n     * Create the column definition for a spatial Geography type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string\n     */\n    protected function typeGeography(Fluent $column)\n    {\n        return 'geography';\n    }\n\n    /**\n     * Create the column definition for a generated, computed column type.\n     *\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function typeComputed(Fluent $column)\n    {\n        return \"as ({$this->getValue($column->expression)})\";\n    }\n\n    /**\n     * Get the SQL for a collation column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyCollate(Blueprint $blueprint, Fluent $column)\n    {\n        if (! is_null($column->collation)) {\n            return ' collate '.$column->collation;\n        }\n    }\n\n    /**\n     * Get the SQL for a nullable column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyNullable(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->type !== 'computed') {\n            return $column->nullable ? ' null' : ' not null';\n        }\n    }\n\n    /**\n     * Get the SQL for a default column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyDefault(Blueprint $blueprint, Fluent $column)\n    {\n        if (! $column->change && ! is_null($column->default)) {\n            return ' default '.$this->getDefaultValue($column->default);\n        }\n    }\n\n    /**\n     * Get the SQL for an auto-increment column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyIncrement(Blueprint $blueprint, Fluent $column)\n    {\n        if (! $column->change && in_array($column->type, $this->serials) && $column->autoIncrement) {\n            return $this->hasCommand($blueprint, 'primary') ? ' identity' : ' identity primary key';\n        }\n    }\n\n    /**\n     * Get the SQL for a generated stored column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     */\n    protected function modifyPersisted(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            if ($column->type === 'computed') {\n                return $column->persisted ? ' add persisted' : ' drop persisted';\n            }\n\n            return null;\n        }\n\n        if ($column->persisted) {\n            return ' persisted';\n        }\n    }\n\n    /**\n     * Quote the given string literal.\n     *\n     * @param  string|array<string>  $value\n     * @return string\n     */\n    public function quoteString($value)\n    {\n        if (is_array($value)) {\n            return implode(', ', array_map([$this, __FUNCTION__], $value));\n        }\n\n        return \"N'$value'\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/IndexDefinition.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Support\\Fluent;\n\n/**\n * @method $this algorithm(string $algorithm) Specify an algorithm for the index (MySQL/PostgreSQL)\n * @method $this deferrable(bool $value = true) Specify that the unique index is deferrable (PostgreSQL)\n * @method $this initiallyImmediate(bool $value = true) Specify the default time to check the unique index constraint (PostgreSQL)\n * @method $this language(string $language) Specify a language for the full text index (PostgreSQL)\n * @method $this lock(('none'|'shared'|'default'|'exclusive') $value) Specify the DDL lock mode for the index operation (MySQL)\n * @method $this nullsNotDistinct(bool $value = true) Specify that the null values should not be treated as distinct (PostgreSQL)\n * @method $this online(bool $value = true) Specify that index creation should not lock the table (PostgreSQL/SqlServer)\n */\nclass IndexDefinition extends Fluent\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/MariaDbBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nclass MariaDbBuilder extends MySqlBuilder\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/MariaDbSchemaState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nclass MariaDbSchemaState extends MySqlSchemaState\n{\n    /**\n     * Load the given schema file into the database.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function load($path)\n    {\n        $versionInfo = $this->detectClientVersion();\n\n        $command = 'mariadb '.$this->connectionString($versionInfo).' --database=\"${:LARAVEL_LOAD_DATABASE}\" < \"${:LARAVEL_LOAD_PATH}\"';\n\n        $process = $this->makeProcess($command)->setTimeout(null);\n\n        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            'LARAVEL_LOAD_PATH' => $path,\n        ]));\n    }\n\n    /**\n     * Get the base dump command arguments for MariaDB as a string.\n     *\n     * @return string\n     */\n    protected function baseDumpCommand()\n    {\n        $versionInfo = $this->detectClientVersion();\n\n        $command = 'mariadb-dump '.$this->connectionString($versionInfo).' --no-tablespaces --skip-add-locks --skip-comments --skip-set-charset --tz-utc';\n\n        return $command.' \"${:LARAVEL_LOAD_DATABASE}\"';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/MySqlBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nclass MySqlBuilder extends Builder\n{\n    /**\n     * Drop all tables from the database.\n     *\n     * @return void\n     */\n    public function dropAllTables()\n    {\n        $tables = $this->getTableListing($this->getCurrentSchemaListing());\n\n        if (empty($tables)) {\n            return;\n        }\n\n        $this->disableForeignKeyConstraints();\n\n        try {\n            $this->connection->statement(\n                $this->grammar->compileDropAllTables($tables)\n            );\n        } finally {\n            $this->enableForeignKeyConstraints();\n        }\n    }\n\n    /**\n     * Drop all views from the database.\n     *\n     * @return void\n     */\n    public function dropAllViews()\n    {\n        $views = array_column($this->getViews($this->getCurrentSchemaListing()), 'schema_qualified_name');\n\n        if (empty($views)) {\n            return;\n        }\n\n        $this->connection->statement(\n            $this->grammar->compileDropAllViews($views)\n        );\n    }\n\n    /**\n     * Get the names of current schemas for the connection.\n     *\n     * @return string[]|null\n     */\n    public function getCurrentSchemaListing()\n    {\n        return [$this->connection->getDatabaseName()];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/MySqlSchemaState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\nuse Symfony\\Component\\Process\\Process;\n\nclass MySqlSchemaState extends SchemaState\n{\n    /**\n     * Dump the database's schema into a file.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     * @return void\n     */\n    public function dump(Connection $connection, $path)\n    {\n        $this->executeDumpProcess($this->makeProcess(\n            $this->baseDumpCommand().' --routines --result-file=\"${:LARAVEL_LOAD_PATH}\" --no-data'\n        ), $this->output, array_merge($this->baseVariables($this->connection->getConfig()), [\n            'LARAVEL_LOAD_PATH' => $path,\n        ]));\n\n        $this->removeAutoIncrementingState($path);\n\n        if ($this->hasMigrationTable()) {\n            $this->appendMigrationData($path);\n        }\n    }\n\n    /**\n     * Remove the auto-incrementing state from the given schema dump.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function removeAutoIncrementingState(string $path)\n    {\n        $this->files->put($path, preg_replace(\n            '/\\s+AUTO_INCREMENT=[0-9]+/iu',\n            '',\n            $this->files->get($path)\n        ));\n    }\n\n    /**\n     * Append the migration data to the schema dump.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function appendMigrationData(string $path)\n    {\n        $process = $this->executeDumpProcess($this->makeProcess(\n            $this->baseDumpCommand().' '.$this->getMigrationTable().' --no-create-info --skip-extended-insert --skip-routines --compact --complete-insert'\n        ), null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            //\n        ]));\n\n        $this->files->append($path, $process->getOutput());\n    }\n\n    /**\n     * Load the given schema file into the database.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function load($path)\n    {\n        $versionInfo = $this->detectClientVersion();\n\n        $command = 'mysql '.$this->connectionString($versionInfo).' --database=\"${:LARAVEL_LOAD_DATABASE}\" < \"${:LARAVEL_LOAD_PATH}\"';\n\n        $process = $this->makeProcess($command)->setTimeout(null);\n\n        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            'LARAVEL_LOAD_PATH' => $path,\n        ]));\n    }\n\n    /**\n     * Get the base dump command arguments for MySQL as a string.\n     *\n     * @return string\n     */\n    protected function baseDumpCommand()\n    {\n        $versionInfo = $this->detectClientVersion();\n\n        $command = 'mysqldump '.$this->connectionString($versionInfo).' --no-tablespaces --skip-add-locks --skip-comments --skip-set-charset --tz-utc --column-statistics=0';\n\n        if (! $this->connection->isMaria()) {\n            $command .= ' --set-gtid-purged=OFF';\n        }\n\n        return $command.' \"${:LARAVEL_LOAD_DATABASE}\"';\n    }\n\n    /**\n     * Generate a basic connection string (--socket, --host, --port, --user, --password) for the database.\n     *\n     * @param  array{version: string, isMariaDb: bool}  $versionInfo\n     * @return string\n     */\n    protected function connectionString(array $versionInfo)\n    {\n        $value = ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\"';\n\n        $config = $this->connection->getConfig();\n\n        $value .= $config['unix_socket'] ?? false\n            ? ' --socket=\"${:LARAVEL_LOAD_SOCKET}\"'\n            : ' --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\"';\n\n        /** @phpstan-ignore class.notFound */\n        if (isset($config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA])) {\n            $value .= ' --ssl-ca=\"${:LARAVEL_LOAD_SSL_CA}\"';\n        }\n\n        /** @phpstan-ignore class.notFound */\n        if (isset($config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CERT : \\PDO::MYSQL_ATTR_SSL_CERT])) {\n            $value .= ' --ssl-cert=\"${:LARAVEL_LOAD_SSL_CERT}\"';\n        }\n\n        /** @phpstan-ignore class.notFound */\n        if (isset($config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_KEY : \\PDO::MYSQL_ATTR_SSL_KEY])) {\n            $value .= ' --ssl-key=\"${:LARAVEL_LOAD_SSL_KEY}\"';\n        }\n\n        /** @phpstan-ignore class.notFound */\n        $verifyCertOption = PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_VERIFY_SERVER_CERT : \\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT;\n\n        if (isset($config['options'][$verifyCertOption]) && $config['options'][$verifyCertOption] === false) {\n            if (version_compare($versionInfo['version'], '5.7.11', '>=') && ! $versionInfo['isMariaDb']) {\n                $value .= ' --ssl-mode=DISABLED';\n            } else {\n                $value .= ' --ssl=off';\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the base variables for a dump / load command.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function baseVariables(array $config)\n    {\n        $config['host'] ??= '';\n\n        return [\n            'LARAVEL_LOAD_SOCKET' => $config['unix_socket'] ?? '',\n            'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],\n            'LARAVEL_LOAD_PORT' => $config['port'] ?? '',\n            'LARAVEL_LOAD_USER' => $config['username'],\n            'LARAVEL_LOAD_PASSWORD' => $config['password'] ?? '',\n            'LARAVEL_LOAD_DATABASE' => $config['database'],\n            'LARAVEL_LOAD_SSL_CA' => $config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA] ?? '', // @phpstan-ignore class.notFound\n            'LARAVEL_LOAD_SSL_CERT' => $config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CERT : \\PDO::MYSQL_ATTR_SSL_CERT] ?? '', // @phpstan-ignore class.notFound\n            'LARAVEL_LOAD_SSL_KEY' => $config['options'][PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_KEY : \\PDO::MYSQL_ATTR_SSL_KEY] ?? '', // @phpstan-ignore class.notFound\n        ];\n    }\n\n    /**\n     * Execute the given dump process.\n     *\n     * @param  \\Symfony\\Component\\Process\\Process  $process\n     * @param  callable  $output\n     * @param  array  $variables\n     * @param  int  $depth\n     * @return \\Symfony\\Component\\Process\\Process\n     *\n     * @throws \\Throwable\n     */\n    protected function executeDumpProcess(Process $process, $output, array $variables, int $depth = 0)\n    {\n        if ($depth > 30) {\n            throw new Exception('Dump execution exceeded maximum depth of 30.');\n        }\n\n        try {\n            $process->setTimeout(null)->mustRun($output, $variables);\n        } catch (Exception $e) {\n            if (Str::contains($e->getMessage(), ['column-statistics', 'column_statistics'])) {\n                return $this->executeDumpProcess(Process::fromShellCommandLine(\n                    str_replace(' --column-statistics=0', '', $process->getCommandLine())\n                ), $output, $variables, $depth + 1);\n            }\n\n            if (str_contains($e->getMessage(), 'set-gtid-purged')) {\n                return $this->executeDumpProcess(Process::fromShellCommandLine(\n                    str_replace(' --set-gtid-purged=OFF', '', $process->getCommandLine())\n                ), $output, $variables, $depth + 1);\n            }\n\n            throw $e;\n        }\n\n        return $process;\n    }\n\n    /**\n     * Detect the MySQL client version.\n     *\n     * @return array{version: string, isMariaDb: bool}\n     */\n    protected function detectClientVersion(): array\n    {\n        [$version, $isMariaDb] = ['8.0.0', false];\n\n        try {\n            $versionOutput = $this->makeProcess('mysql --version')->mustRun()->getOutput();\n\n            if (preg_match('/(\\d+\\.\\d+\\.\\d+)/', $versionOutput, $matches)) {\n                $version = $matches[1];\n            }\n\n            $isMariaDb = stripos($versionOutput, 'mariadb') !== false;\n        } catch (ProcessFailedException) {\n        }\n\n        return [\n            'version' => $version,\n            'isMariaDb' => $isMariaDb,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/PostgresBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\Concerns\\ParsesSearchPath;\n\nclass PostgresBuilder extends Builder\n{\n    use ParsesSearchPath;\n\n    /**\n     * Drop all tables from the database.\n     *\n     * @return void\n     */\n    public function dropAllTables()\n    {\n        $tables = [];\n\n        $excludedTables = $this->connection->getConfig('dont_drop') ?? ['spatial_ref_sys'];\n\n        foreach ($this->getTables($this->getCurrentSchemaListing()) as $table) {\n            if (empty(array_intersect([$table['name'], $table['schema_qualified_name']], $excludedTables))) {\n                $tables[] = $table['schema_qualified_name'];\n            }\n        }\n\n        if (empty($tables)) {\n            return;\n        }\n\n        $this->connection->statement(\n            $this->grammar->compileDropAllTables($tables)\n        );\n    }\n\n    /**\n     * Drop all views from the database.\n     *\n     * @return void\n     */\n    public function dropAllViews()\n    {\n        $views = array_column($this->getViews($this->getCurrentSchemaListing()), 'schema_qualified_name');\n\n        if (empty($views)) {\n            return;\n        }\n\n        $this->connection->statement(\n            $this->grammar->compileDropAllViews($views)\n        );\n    }\n\n    /**\n     * Drop all types from the database.\n     *\n     * @return void\n     */\n    public function dropAllTypes()\n    {\n        $types = [];\n        $domains = [];\n\n        foreach ($this->getTypes($this->getCurrentSchemaListing()) as $type) {\n            if (! $type['implicit']) {\n                if ($type['type'] === 'domain') {\n                    $domains[] = $type['schema_qualified_name'];\n                } else {\n                    $types[] = $type['schema_qualified_name'];\n                }\n            }\n        }\n\n        if (! empty($types)) {\n            $this->connection->statement($this->grammar->compileDropAllTypes($types));\n        }\n\n        if (! empty($domains)) {\n            $this->connection->statement($this->grammar->compileDropAllDomains($domains));\n        }\n    }\n\n    /**\n     * Get the current schemas for the connection.\n     *\n     * @return string[]\n     */\n    public function getCurrentSchemaListing()\n    {\n        return array_map(\n            fn ($schema) => $schema === '$user' ? $this->connection->getConfig('username') : $schema,\n            $this->parseSearchPath(\n                $this->connection->getConfig('search_path')\n                    ?: $this->connection->getConfig('schema')\n                    ?: 'public'\n            )\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/PostgresSchemaState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Support\\Collection;\n\nclass PostgresSchemaState extends SchemaState\n{\n    /**\n     * Dump the database's schema into a file.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     * @return void\n     */\n    public function dump(Connection $connection, $path)\n    {\n        $commands = new Collection([\n            $this->baseDumpCommand().' --schema-only > '.$path,\n        ]);\n\n        if ($this->hasMigrationTable()) {\n            $commands->push($this->baseDumpCommand().' -t '.$this->getMigrationTable().' --data-only >> '.$path);\n        }\n\n        $commands->map(function ($command, $path) {\n            $this->makeProcess($command)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [\n                'LARAVEL_LOAD_PATH' => $path,\n            ]));\n        });\n    }\n\n    /**\n     * Load the given schema file into the database.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function load($path)\n    {\n        $command = 'pg_restore --no-owner --no-acl --clean --if-exists --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --username=\"${:LARAVEL_LOAD_USER}\" --dbname=\"${:LARAVEL_LOAD_DATABASE}\" \"${:LARAVEL_LOAD_PATH}\"';\n\n        if (str_ends_with($path, '.sql')) {\n            $command = 'psql --file=\"${:LARAVEL_LOAD_PATH}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --username=\"${:LARAVEL_LOAD_USER}\" --dbname=\"${:LARAVEL_LOAD_DATABASE}\"';\n        }\n\n        $process = $this->makeProcess($command);\n\n        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            'LARAVEL_LOAD_PATH' => $path,\n        ]));\n    }\n\n    /**\n     * Get the name of the application's migration table.\n     *\n     * @return string\n     */\n    protected function getMigrationTable(): string\n    {\n        [$schema, $table] = $this->connection->getSchemaBuilder()->parseSchemaAndTable($this->migrationTable, withDefaultSchema: true);\n\n        return $schema.'.'.$this->connection->getTablePrefix().$table;\n    }\n\n    /**\n     * Get the base dump command arguments for PostgreSQL as a string.\n     *\n     * @return string\n     */\n    protected function baseDumpCommand()\n    {\n        return 'pg_dump --no-owner --no-acl --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --username=\"${:LARAVEL_LOAD_USER}\" --dbname=\"${:LARAVEL_LOAD_DATABASE}\"';\n    }\n\n    /**\n     * Get the base variables for a dump / load command.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function baseVariables(array $config)\n    {\n        $config['host'] ??= '';\n\n        return [\n            'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'],\n            'LARAVEL_LOAD_PORT' => $config['port'] ?? '',\n            'LARAVEL_LOAD_USER' => $config['username'],\n            'PGPASSWORD' => $config['password'],\n            'LARAVEL_LOAD_DATABASE' => $config['database'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/SQLiteBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\File;\n\nclass SQLiteBuilder extends Builder\n{\n    /**\n     * Create a database in the schema.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function createDatabase($name)\n    {\n        return File::put($name, '') !== false;\n    }\n\n    /**\n     * Drop a database from the schema if the database exists.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function dropDatabaseIfExists($name)\n    {\n        return ! File::exists($name) || File::delete($name);\n    }\n\n    /** @inheritDoc */\n    public function getTables($schema = null)\n    {\n        try {\n            $withSize = $this->connection->scalar($this->grammar->compileDbstatExists());\n        } catch (QueryException) {\n            $withSize = false;\n        }\n\n        if (version_compare($this->connection->getServerVersion(), '3.37.0', '<')) {\n            $schema ??= array_column($this->getSchemas(), 'name');\n\n            $tables = [];\n\n            foreach (Arr::wrap($schema) as $name) {\n                $tables = array_merge($tables, $this->connection->selectFromWriteConnection(\n                    $this->grammar->compileLegacyTables($name, $withSize)\n                ));\n            }\n\n            return $this->connection->getPostProcessor()->processTables($tables);\n        }\n\n        return $this->connection->getPostProcessor()->processTables(\n            $this->connection->selectFromWriteConnection(\n                $this->grammar->compileTables($schema)\n            )\n        );\n    }\n\n    /** @inheritDoc */\n    public function getViews($schema = null)\n    {\n        $schema ??= array_column($this->getSchemas(), 'name');\n\n        $views = [];\n\n        foreach (Arr::wrap($schema) as $name) {\n            $views = array_merge($views, $this->connection->selectFromWriteConnection(\n                $this->grammar->compileViews($name)\n            ));\n        }\n\n        return $this->connection->getPostProcessor()->processViews($views);\n    }\n\n    /** @inheritDoc */\n    public function getColumns($table)\n    {\n        [$schema, $table] = $this->parseSchemaAndTable($table);\n\n        $table = $this->connection->getTablePrefix().$table;\n\n        return $this->connection->getPostProcessor()->processColumns(\n            $this->connection->selectFromWriteConnection($this->grammar->compileColumns($schema, $table)),\n            $this->connection->scalar($this->grammar->compileSqlCreateStatement($schema, $table))\n        );\n    }\n\n    /**\n     * Drop all tables from the database.\n     *\n     * @return void\n     */\n    public function dropAllTables()\n    {\n        foreach ($this->getCurrentSchemaListing() as $schema) {\n            $database = $schema === 'main'\n                ? $this->connection->getDatabaseName()\n                : (array_column($this->getSchemas(), 'path', 'name')[$schema] ?: ':memory:');\n\n            if ($database !== ':memory:' &&\n                ! str_contains($database, '?mode=memory') &&\n                ! str_contains($database, '&mode=memory')\n            ) {\n                $this->refreshDatabaseFile($database);\n            } else {\n                $this->pragma('writable_schema', 1);\n\n                $this->connection->statement($this->grammar->compileDropAllTables($schema));\n\n                $this->pragma('writable_schema', 0);\n\n                $this->connection->statement($this->grammar->compileRebuild($schema));\n            }\n        }\n    }\n\n    /**\n     * Drop all views from the database.\n     *\n     * @return void\n     */\n    public function dropAllViews()\n    {\n        foreach ($this->getCurrentSchemaListing() as $schema) {\n            $this->pragma('writable_schema', 1);\n\n            $this->connection->statement($this->grammar->compileDropAllViews($schema));\n\n            $this->pragma('writable_schema', 0);\n\n            $this->connection->statement($this->grammar->compileRebuild($schema));\n        }\n    }\n\n    /**\n     * Get the value for the given pragma name or set the given value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function pragma($key, $value = null)\n    {\n        return is_null($value)\n            ? $this->connection->scalar($this->grammar->pragma($key))\n            : $this->connection->statement($this->grammar->pragma($key, $value));\n    }\n\n    /**\n     * Empty the database file.\n     *\n     * @param  string|null  $path\n     * @return void\n     */\n    public function refreshDatabaseFile($path = null)\n    {\n        file_put_contents($path ?? $this->connection->getDatabaseName(), '');\n    }\n\n    /**\n     * Get the names of current schemas for the connection.\n     *\n     * @return string[]|null\n     */\n    public function getCurrentSchemaListing()\n    {\n        return ['main'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/SchemaState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Process\\Process;\n\nabstract class SchemaState\n{\n    /**\n     * The connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $connection;\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The name of the application's migration table.\n     *\n     * @var string\n     */\n    protected $migrationTable = 'migrations';\n\n    /**\n     * The process factory callback.\n     *\n     * @var callable\n     */\n    protected $processFactory;\n\n    /**\n     * The output callable instance.\n     *\n     * @var callable\n     */\n    protected $output;\n\n    /**\n     * Create a new dumper instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     */\n    public function __construct(Connection $connection, ?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        $this->connection = $connection;\n\n        $this->files = $files ?: new Filesystem;\n\n        $this->processFactory = $processFactory ?: function (...$arguments) {\n            return Process::fromShellCommandline(...$arguments)->setTimeout(null);\n        };\n\n        $this->handleOutputUsing(function () {\n            //\n        });\n    }\n\n    /**\n     * Dump the database's schema into a file.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     * @return void\n     */\n    abstract public function dump(Connection $connection, $path);\n\n    /**\n     * Load the given schema file into the database.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    abstract public function load($path);\n\n    /**\n     * Create a new process instance.\n     *\n     * @param  mixed  ...$arguments\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    public function makeProcess(...$arguments)\n    {\n        return call_user_func($this->processFactory, ...$arguments);\n    }\n\n    /**\n     * Determine if the current connection has a migration table.\n     *\n     * @return bool\n     */\n    public function hasMigrationTable(): bool\n    {\n        return $this->connection->getSchemaBuilder()->hasTable($this->migrationTable);\n    }\n\n    /**\n     * Get the name of the application's migration table.\n     *\n     * @return string\n     */\n    protected function getMigrationTable(): string\n    {\n        return $this->connection->getTablePrefix().$this->migrationTable;\n    }\n\n    /**\n     * Specify the name of the application's migration table.\n     *\n     * @param  string  $table\n     * @return $this\n     */\n    public function withMigrationTable(string $table)\n    {\n        $this->migrationTable = $table;\n\n        return $this;\n    }\n\n    /**\n     * Specify the callback that should be used to handle process output.\n     *\n     * @param  callable  $output\n     * @return $this\n     */\n    public function handleOutputUsing(callable $output)\n    {\n        $this->output = $output;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/SqlServerBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Support\\Arr;\n\nclass SqlServerBuilder extends Builder\n{\n    /**\n     * Drop all tables from the database.\n     *\n     * @return void\n     */\n    public function dropAllTables()\n    {\n        $this->connection->statement($this->grammar->compileDropAllForeignKeys());\n\n        $this->connection->statement($this->grammar->compileDropAllTables());\n    }\n\n    /**\n     * Drop all views from the database.\n     *\n     * @return void\n     */\n    public function dropAllViews()\n    {\n        $this->connection->statement($this->grammar->compileDropAllViews());\n    }\n\n    /**\n     * Get the default schema name for the connection.\n     *\n     * @return string|null\n     */\n    public function getCurrentSchemaName()\n    {\n        return Arr::first($this->getSchemas(), fn ($schema) => $schema['default'])['name'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Schema/SqliteSchemaState.php",
    "content": "<?php\n\nnamespace Illuminate\\Database\\Schema;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Support\\Collection;\n\nclass SqliteSchemaState extends SchemaState\n{\n    /**\n     * Dump the database's schema into a file.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $connection\n     * @param  string  $path\n     * @return void\n     */\n    public function dump(Connection $connection, $path)\n    {\n        $process = $this->makeProcess($this->baseCommand().' \".schema --indent\"')\n            ->setTimeout(null)\n            ->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n                //\n            ]));\n\n        $migrations = preg_replace('/CREATE TABLE sqlite_.+?\\);[\\r\\n]+/is', '', $process->getOutput());\n\n        $this->files->put($path, $migrations.PHP_EOL);\n\n        if ($this->hasMigrationTable()) {\n            $this->appendMigrationData($path);\n        }\n    }\n\n    /**\n     * Append the migration data to the schema dump.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function appendMigrationData(string $path)\n    {\n        $process = $this->makeProcess(\n            $this->baseCommand().' \".dump \\''.$this->getMigrationTable().'\\'\"'\n        )->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            //\n        ]));\n\n        $migrations = (new Collection(preg_split(\"/\\r\\n|\\n|\\r/\", $process->getOutput())))\n            ->filter(fn ($line) => preg_match('/^\\s*(--|INSERT\\s)/iu', $line) === 1 && strlen($line) > 0)\n            ->all();\n\n        $this->files->append($path, implode(PHP_EOL, $migrations).PHP_EOL);\n    }\n\n    /**\n     * Load the given schema file into the database.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function load($path)\n    {\n        $database = $this->connection->getDatabaseName();\n\n        if ($database === ':memory:' ||\n            str_contains($database, '?mode=memory') ||\n            str_contains($database, '&mode=memory')\n        ) {\n            $this->connection->getPdo()->exec($this->files->get($path));\n\n            return;\n        }\n\n        $process = $this->makeProcess($this->baseCommand().' < \"${:LARAVEL_LOAD_PATH}\"');\n\n        $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [\n            'LARAVEL_LOAD_PATH' => $path,\n        ]));\n    }\n\n    /**\n     * Get the base sqlite command arguments as a string.\n     *\n     * @return string\n     */\n    protected function baseCommand()\n    {\n        return 'sqlite3 \"${:LARAVEL_LOAD_DATABASE}\"';\n    }\n\n    /**\n     * Get the base variables for a dump / load command.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function baseVariables(array $config)\n    {\n        return [\n            'LARAVEL_LOAD_DATABASE' => $config['database'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/Seeder.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\View\\Components\\TwoColumnDetail;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Database\\Console\\Seeds\\WithoutModelEvents;\nuse Illuminate\\Support\\Arr;\nuse InvalidArgumentException;\n\nabstract class Seeder\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The console command instance.\n     *\n     * @var \\Illuminate\\Console\\Command\n     */\n    protected $command;\n\n    /**\n     * Seeders that have been called at least one time.\n     *\n     * @var array\n     */\n    protected static $called = [];\n\n    /**\n     * Run the given seeder class.\n     *\n     * @param  array|string  $class\n     * @param  bool  $silent\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function call($class, $silent = false, array $parameters = [])\n    {\n        $classes = Arr::wrap($class);\n\n        foreach ($classes as $class) {\n            $seeder = $this->resolve($class);\n\n            $name = get_class($seeder);\n\n            if ($silent === false && isset($this->command)) {\n                (new TwoColumnDetail($this->command->getOutput()))\n                    ->render($name, '<fg=yellow;options=bold>RUNNING</>');\n            }\n\n            $startTime = microtime(true);\n\n            $seeder->__invoke($parameters);\n\n            if ($silent === false && isset($this->command)) {\n                $runTime = number_format((microtime(true) - $startTime) * 1000);\n\n                (new TwoColumnDetail($this->command->getOutput()))\n                    ->render($name, \"<fg=gray>$runTime ms</> <fg=green;options=bold>DONE</>\");\n\n                $this->command->getOutput()->writeln('');\n            }\n\n            static::$called[] = $class;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Run the given seeder class.\n     *\n     * @param  array|string  $class\n     * @param  array  $parameters\n     * @return void\n     */\n    public function callWith($class, array $parameters = [])\n    {\n        $this->call($class, false, $parameters);\n    }\n\n    /**\n     * Silently run the given seeder class.\n     *\n     * @param  array|string  $class\n     * @param  array  $parameters\n     * @return void\n     */\n    public function callSilent($class, array $parameters = [])\n    {\n        $this->call($class, true, $parameters);\n    }\n\n    /**\n     * Run the given seeder class once.\n     *\n     * @param  array|string  $class\n     * @param  bool  $silent\n     * @return void\n     */\n    public function callOnce($class, $silent = false, array $parameters = [])\n    {\n        $classes = Arr::wrap($class);\n\n        foreach ($classes as $class) {\n            if (in_array($class, static::$called)) {\n                continue;\n            }\n\n            $this->call($class, $silent, $parameters);\n        }\n    }\n\n    /**\n     * Resolve an instance of the given seeder class.\n     *\n     * @param  string  $class\n     * @return \\Illuminate\\Database\\Seeder\n     */\n    protected function resolve($class)\n    {\n        if (isset($this->container)) {\n            $instance = $this->container->make($class);\n\n            $instance->setContainer($this->container);\n        } else {\n            $instance = new $class;\n        }\n\n        if (isset($this->command)) {\n            $instance->setCommand($this->command);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Set the IoC container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Set the console command instance.\n     *\n     * @param  \\Illuminate\\Console\\Command  $command\n     * @return $this\n     */\n    public function setCommand(Command $command)\n    {\n        $this->command = $command;\n\n        return $this;\n    }\n\n    /**\n     * Run the database seeds.\n     *\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __invoke(array $parameters = [])\n    {\n        if (! method_exists($this, 'run')) {\n            throw new InvalidArgumentException('Method [run] missing from '.get_class($this));\n        }\n\n        $callback = fn () => isset($this->container)\n            ? $this->container->call([$this, 'run'], $parameters)\n            : $this->run(...$parameters);\n\n        $uses = array_flip(class_uses_recursive(static::class));\n\n        if (isset($uses[WithoutModelEvents::class])) {\n            $callback = $this->withoutModelEvents($callback);\n        }\n\n        return $callback();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/SqlServerConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar as QueryGrammar;\nuse Illuminate\\Database\\Query\\Processors\\SqlServerProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\SqlServerGrammar as SchemaGrammar;\nuse Illuminate\\Database\\Schema\\SqlServerBuilder;\nuse Illuminate\\Filesystem\\Filesystem;\nuse RuntimeException;\nuse Throwable;\n\nclass SqlServerConnection extends Connection\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function getDriverTitle()\n    {\n        return 'SQL Server';\n    }\n\n    /**\n     * Execute a Closure within a transaction.\n     *\n     * @param  \\Closure  $callback\n     * @param  int  $attempts\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function transaction(Closure $callback, $attempts = 1)\n    {\n        for ($a = 1; $a <= $attempts; $a++) {\n            if ($this->getDriverName() === 'sqlsrv') {\n                return parent::transaction($callback, $attempts);\n            }\n\n            $this->getPdo()->exec('BEGIN TRAN');\n\n            // We'll simply execute the given callback within a try / catch block\n            // and if we catch any exception we can rollback the transaction\n            // so that none of the changes are persisted to the database.\n            try {\n                $result = $callback($this);\n\n                $this->getPdo()->exec('COMMIT TRAN');\n            }\n\n            // If we catch an exception, we will rollback so nothing gets messed\n            // up in the database. Then we'll re-throw the exception so it can\n            // be handled how the developer sees fit for their applications.\n            catch (Throwable $e) {\n                $this->getPdo()->exec('ROLLBACK TRAN');\n\n                throw $e;\n            }\n\n            return $result;\n        }\n    }\n\n    /**\n     * Escape a binary value for safe SQL embedding.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeBinary($value)\n    {\n        $hex = bin2hex($value);\n\n        return \"0x{$hex}\";\n    }\n\n    /**\n     * Determine if the given database exception was caused by a unique constraint violation.\n     *\n     * @param  \\Exception  $exception\n     * @return bool\n     */\n    protected function isUniqueConstraintError(Exception $exception)\n    {\n        return (bool) preg_match('#Cannot insert duplicate key row in object#i', $exception->getMessage());\n    }\n\n    /**\n     * Get the default query grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar\n     */\n    protected function getDefaultQueryGrammar()\n    {\n        return new QueryGrammar($this);\n    }\n\n    /**\n     * Get a schema builder instance for the connection.\n     *\n     * @return \\Illuminate\\Database\\Schema\\SqlServerBuilder\n     */\n    public function getSchemaBuilder()\n    {\n        if (is_null($this->schemaGrammar)) {\n            $this->useDefaultSchemaGrammar();\n        }\n\n        return new SqlServerBuilder($this);\n    }\n\n    /**\n     * Get the default schema grammar instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Grammars\\SqlServerGrammar\n     */\n    protected function getDefaultSchemaGrammar()\n    {\n        return new SchemaGrammar($this);\n    }\n\n    /**\n     * Get the schema state for the connection.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     * @param  callable|null  $processFactory\n     *\n     * @throws \\RuntimeException\n     */\n    public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null)\n    {\n        throw new RuntimeException('Schema dumping is not supported when using SQL Server.');\n    }\n\n    /**\n     * Get the default post processor instance.\n     *\n     * @return \\Illuminate\\Database\\Query\\Processors\\SqlServerProcessor\n     */\n    protected function getDefaultPostProcessor()\n    {\n        return new SqlServerProcessor;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Database/UniqueConstraintViolationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Database;\n\nclass UniqueConstraintViolationException extends QueryException\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Database/composer.json",
    "content": "{\n    \"name\": \"illuminate/database\",\n    \"description\": \"The Illuminate Database package.\",\n    \"license\": \"MIT\",\n    \"keywords\": [\n        \"laravel\",\n        \"database\",\n        \"sql\",\n        \"orm\"\n    ],\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-pdo\": \"*\",\n        \"brick/math\": \"^0.14.2 || ^0.15 || ^0.16 || ^0.17\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"laravel/serializable-closure\": \"^2.0.10\",\n        \"symfony/polyfill-php85\": \"^1.33\"\n    },\n    \"suggest\": {\n        \"ext-filter\": \"Required to use the Postgres database driver.\",\n        \"fakerphp/faker\": \"Required to use the eloquent factory builder (^1.24).\",\n        \"illuminate/console\": \"Required to use the database commands (^13.0).\",\n        \"illuminate/events\": \"Required to use the observers with Eloquent (^13.0).\",\n        \"illuminate/filesystem\": \"Required to use the migrations (^13.0).\",\n        \"illuminate/http\": \"Required to convert Eloquent models to API resources (^13.0).\",\n        \"illuminate/pagination\": \"Required to paginate the result set (^13.0).\",\n        \"symfony/finder\": \"Required to use Eloquent model factories (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Database\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Encryption/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Encryption/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Encryption/Encrypter.php",
    "content": "<?php\n\nnamespace Illuminate\\Encryption;\n\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Contracts\\Encryption\\Encrypter as EncrypterContract;\nuse Illuminate\\Contracts\\Encryption\\EncryptException;\nuse Illuminate\\Contracts\\Encryption\\StringEncrypter;\nuse RuntimeException;\n\nclass Encrypter implements EncrypterContract, StringEncrypter\n{\n    /**\n     * The encryption key.\n     *\n     * @var string\n     */\n    protected $key;\n\n    /**\n     * The previous / legacy encryption keys.\n     *\n     * @var array\n     */\n    protected $previousKeys = [];\n\n    /**\n     * The algorithm used for encryption.\n     *\n     * @var string\n     */\n    protected $cipher;\n\n    /**\n     * The supported cipher algorithms and their properties.\n     *\n     * @var array\n     */\n    private static $supportedCiphers = [\n        'aes-128-cbc' => ['size' => 16, 'aead' => false],\n        'aes-256-cbc' => ['size' => 32, 'aead' => false],\n        'aes-128-gcm' => ['size' => 16, 'aead' => true],\n        'aes-256-gcm' => ['size' => 32, 'aead' => true],\n    ];\n\n    /**\n     * Create a new encrypter instance.\n     *\n     * @param  string  $key\n     * @param  string  $cipher\n     *\n     * @throws \\RuntimeException\n     */\n    public function __construct($key, $cipher = 'aes-128-cbc')\n    {\n        $key = (string) $key;\n\n        if (! static::supported($key, $cipher)) {\n            $ciphers = implode(', ', array_keys(self::$supportedCiphers));\n\n            throw new RuntimeException(\"Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}.\");\n        }\n\n        $this->key = $key;\n        $this->cipher = $cipher;\n    }\n\n    /**\n     * Determine if the given key and cipher combination is valid.\n     *\n     * @param  string  $key\n     * @param  string  $cipher\n     * @return bool\n     */\n    public static function supported($key, $cipher)\n    {\n        if (! isset(self::$supportedCiphers[strtolower($cipher)])) {\n            return false;\n        }\n\n        return mb_strlen($key, '8bit') === self::$supportedCiphers[strtolower($cipher)]['size'];\n    }\n\n    /**\n     * Create a new encryption key for the given cipher.\n     *\n     * @param  string  $cipher\n     * @return string\n     */\n    public static function generateKey($cipher)\n    {\n        return random_bytes(self::$supportedCiphers[strtolower($cipher)]['size'] ?? 32);\n    }\n\n    /**\n     * Encrypt the given value.\n     *\n     * @param  mixed  $value\n     * @param  bool  $serialize\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\EncryptException\n     */\n    public function encrypt(#[\\SensitiveParameter] $value, $serialize = true)\n    {\n        $iv = random_bytes(openssl_cipher_iv_length(strtolower($this->cipher)));\n\n        $value = \\openssl_encrypt(\n            $serialize ? serialize($value) : $value,\n            strtolower($this->cipher), $this->key, 0, $iv, $tag\n        );\n\n        if ($value === false) {\n            throw new EncryptException('Could not encrypt the data.');\n        }\n\n        $iv = base64_encode($iv);\n        $tag = base64_encode($tag ?? '');\n\n        $mac = self::$supportedCiphers[strtolower($this->cipher)]['aead']\n            ? '' // For AEAD-algorithms, the tag / MAC is returned by openssl_encrypt...\n            : $this->hash($iv, $value, $this->key);\n\n        $json = json_encode(compact('iv', 'value', 'mac', 'tag'), JSON_UNESCAPED_SLASHES);\n\n        if (json_last_error() !== JSON_ERROR_NONE) {\n            throw new EncryptException('Could not encrypt the data.');\n        }\n\n        return base64_encode($json);\n    }\n\n    /**\n     * Encrypt a string without serialization.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\EncryptException\n     */\n    public function encryptString(#[\\SensitiveParameter] $value)\n    {\n        return $this->encrypt($value, false);\n    }\n\n    /**\n     * Decrypt the given value.\n     *\n     * @param  string  $payload\n     * @param  bool  $unserialize\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    public function decrypt($payload, $unserialize = true)\n    {\n        $payload = $this->getJsonPayload($payload);\n\n        $iv = base64_decode($payload['iv']);\n\n        $this->ensureTagIsValid(\n            $tag = empty($payload['tag']) ? null : base64_decode($payload['tag'])\n        );\n\n        $foundValidMac = false;\n\n        // Here we will decrypt the value. If we are able to successfully decrypt it\n        // we will then unserialize it and return it out to the caller. If we are\n        // unable to decrypt this value we will throw out an exception message.\n        foreach ($this->getAllKeys() as $key) {\n            if (\n                $this->shouldValidateMac() &&\n                ! ($foundValidMac = $foundValidMac || $this->validMacForKey($payload, $key))\n            ) {\n                continue;\n            }\n\n            $decrypted = \\openssl_decrypt(\n                $payload['value'], strtolower($this->cipher), $key, 0, $iv, $tag ?? ''\n            );\n\n            if ($decrypted !== false) {\n                break;\n            }\n        }\n\n        if ($this->shouldValidateMac() && ! $foundValidMac) {\n            throw new DecryptException('The MAC is invalid.');\n        }\n\n        if (($decrypted ?? false) === false) {\n            throw new DecryptException('Could not decrypt the data.');\n        }\n\n        return $unserialize ? unserialize($decrypted) : $decrypted;\n    }\n\n    /**\n     * Decrypt the given string without unserialization.\n     *\n     * @param  string  $payload\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    public function decryptString($payload)\n    {\n        return $this->decrypt($payload, false);\n    }\n\n    /**\n     * Create a MAC for the given value.\n     *\n     * @param  string  $iv\n     * @param  mixed  $value\n     * @param  string  $key\n     * @return string\n     */\n    protected function hash(#[\\SensitiveParameter] $iv, #[\\SensitiveParameter] $value, #[\\SensitiveParameter] $key)\n    {\n        return hash_hmac('sha256', $iv.$value, $key);\n    }\n\n    /**\n     * Get the JSON array from the given payload.\n     *\n     * @param  string  $payload\n     * @return array\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    protected function getJsonPayload($payload)\n    {\n        if (! is_string($payload)) {\n            throw new DecryptException('The payload is invalid.');\n        }\n\n        $payload = json_decode(base64_decode($payload), true);\n\n        // If the payload is not valid JSON or does not have the proper keys set we will\n        // assume it is invalid and bail out of the routine since we will not be able\n        // to decrypt the given value. We'll also check the MAC for this encryption.\n        if (! $this->validPayload($payload)) {\n            throw new DecryptException('The payload is invalid.');\n        }\n\n        return $payload;\n    }\n\n    /**\n     * Verify that the encryption payload is valid.\n     *\n     * @param  mixed  $payload\n     * @return bool\n     */\n    protected function validPayload($payload)\n    {\n        if (! is_array($payload)) {\n            return false;\n        }\n\n        foreach (['iv', 'value', 'mac'] as $item) {\n            if (! isset($payload[$item]) || ! is_string($payload[$item])) {\n                return false;\n            }\n        }\n\n        if (isset($payload['tag']) && ! is_string($payload['tag'])) {\n            return false;\n        }\n\n        return strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length(strtolower($this->cipher));\n    }\n\n    /**\n     * Determine if the MAC for the given payload is valid for the primary key.\n     *\n     * @param  array  $payload\n     * @return bool\n     */\n    protected function validMac(array $payload)\n    {\n        return $this->validMacForKey($payload, $this->key);\n    }\n\n    /**\n     * Determine if the MAC is valid for the given payload and key.\n     *\n     * @param  array  $payload\n     * @param  string  $key\n     * @return bool\n     */\n    protected function validMacForKey(#[\\SensitiveParameter] $payload, $key)\n    {\n        return hash_equals(\n            $this->hash($payload['iv'], $payload['value'], $key), $payload['mac']\n        );\n    }\n\n    /**\n     * Ensure the given tag is a valid tag given the selected cipher.\n     *\n     * @param  string  $tag\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Encryption\\DecryptException\n     */\n    protected function ensureTagIsValid($tag)\n    {\n        if (self::$supportedCiphers[strtolower($this->cipher)]['aead'] && strlen($tag) !== 16) {\n            throw new DecryptException('Could not decrypt the data.');\n        }\n\n        if (! self::$supportedCiphers[strtolower($this->cipher)]['aead'] && is_string($tag)) {\n            throw new DecryptException('Unable to use tag because the cipher algorithm does not support AEAD.');\n        }\n    }\n\n    /**\n     * Determine if we should validate the MAC while decrypting.\n     *\n     * @return bool\n     */\n    protected function shouldValidateMac()\n    {\n        return ! self::$supportedCiphers[strtolower($this->cipher)]['aead'];\n    }\n\n    /**\n     * Determine if the given value appears to be encrypted by this encrypter.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    public static function appearsEncrypted($value)\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        $decoded = base64_decode($value, true);\n\n        if ($decoded === false) {\n            return false;\n        }\n\n        $payload = json_decode($decoded, true);\n\n        return is_array($payload)\n            && isset($payload['iv'], $payload['value'], $payload['mac']);\n    }\n\n    /**\n     * Get the encryption key that the encrypter is currently using.\n     *\n     * @return string\n     */\n    public function getKey()\n    {\n        return $this->key;\n    }\n\n    /**\n     * Get the current encryption key and all previous encryption keys.\n     *\n     * @return array\n     */\n    public function getAllKeys()\n    {\n        return [$this->key, ...$this->previousKeys];\n    }\n\n    /**\n     * Get the previous encryption keys.\n     *\n     * @return array\n     */\n    public function getPreviousKeys()\n    {\n        return $this->previousKeys;\n    }\n\n    /**\n     * Set the previous / legacy encryption keys that should be utilized if decryption fails.\n     *\n     * @param  array  $keys\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function previousKeys(array $keys)\n    {\n        foreach ($keys as $key) {\n            if (! static::supported($key, $this->cipher)) {\n                $ciphers = implode(', ', array_keys(self::$supportedCiphers));\n\n                throw new RuntimeException(\"Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}.\");\n            }\n        }\n\n        $this->previousKeys = $keys;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Encryption/EncryptionServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Encryption;\n\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Support\\Str;\nuse Laravel\\SerializableClosure\\SerializableClosure;\n\nclass EncryptionServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerEncrypter();\n        $this->registerSerializableClosureSecurityKey();\n    }\n\n    /**\n     * Register the encrypter.\n     *\n     * @return void\n     */\n    protected function registerEncrypter()\n    {\n        $this->app->singleton('encrypter', function ($app) {\n            $config = $app->make('config')->get('app');\n\n            return (new Encrypter($this->parseKey($config), $config['cipher']))\n                ->previousKeys(array_map(\n                    fn ($key) => $this->parseKey(['key' => $key]),\n                    $config['previous_keys'] ?? []\n                ));\n        });\n    }\n\n    /**\n     * Configure Serializable Closure signing for security.\n     *\n     * @return void\n     */\n    protected function registerSerializableClosureSecurityKey()\n    {\n        $config = $this->app->make('config')->get('app');\n\n        if (! class_exists(SerializableClosure::class) || empty($config['key'])) {\n            return;\n        }\n\n        SerializableClosure::setSecretKey($this->parseKey($config));\n    }\n\n    /**\n     * Parse the encryption key.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function parseKey(array $config)\n    {\n        if (Str::startsWith($key = $this->key($config), $prefix = 'base64:')) {\n            $key = base64_decode(Str::after($key, $prefix));\n        }\n\n        return $key;\n    }\n\n    /**\n     * Extract the encryption key from the given configuration.\n     *\n     * @param  array  $config\n     * @return string\n     *\n     * @throws \\Illuminate\\Encryption\\MissingAppKeyException\n     */\n    protected function key(array $config)\n    {\n        return tap($config['key'], function ($key) {\n            if (empty($key)) {\n                throw new MissingAppKeyException;\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Encryption/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Encryption/MissingAppKeyException.php",
    "content": "<?php\n\nnamespace Illuminate\\Encryption;\n\nuse RuntimeException;\n\nclass MissingAppKeyException extends RuntimeException\n{\n    /**\n     * Create a new exception instance.\n     *\n     * @param  string  $message\n     */\n    public function __construct($message = 'No application encryption key has been specified.')\n    {\n        parent::__construct($message);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Encryption/composer.json",
    "content": "{\n    \"name\": \"illuminate/encryption\",\n    \"description\": \"The Illuminate Encryption package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-hash\": \"*\",\n        \"ext-mbstring\": \"*\",\n        \"ext-openssl\": \"*\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Encryption\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Events/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Events/CallQueuedListener.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass CallQueuedListener implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable;\n\n    /**\n     * The listener class name.\n     *\n     * @var class-string\n     */\n    public $class;\n\n    /**\n     * The listener method.\n     *\n     * @var string\n     */\n    public $method;\n\n    /**\n     * The data to be passed to the listener.\n     *\n     * @var array\n     */\n    public $data;\n\n    /**\n     * The number of times the job may be attempted.\n     *\n     * @var int\n     */\n    public $tries;\n\n    /**\n     * The maximum number of exceptions allowed, regardless of attempts.\n     *\n     * @var int\n     */\n    public $maxExceptions;\n\n    /**\n     * The number of seconds to wait before retrying a job that encountered an uncaught exception.\n     *\n     * @var int\n     */\n    public $backoff;\n\n    /**\n     * The timestamp indicating when the job should timeout.\n     *\n     * @var int\n     */\n    public $retryUntil;\n\n    /**\n     * The number of seconds the job can run before timing out.\n     *\n     * @var int\n     */\n    public $timeout;\n\n    /**\n     * Indicates if the job should fail if the timeout is exceeded.\n     *\n     * @var bool\n     */\n    public $failOnTimeout = false;\n\n    /**\n     * Indicates if the job should be encrypted.\n     *\n     * @var bool\n     */\n    public $shouldBeEncrypted = false;\n\n    /**\n     * Indicates if the job should be deleted when models are missing.\n     *\n     * @var bool\n     */\n    public $deleteWhenMissingModels;\n\n    /**\n     * Indicates if the listener should be unique.\n     */\n    public bool $shouldBeUnique = false;\n\n    /**\n     * Indicates if the listener should be unique until processing begins.\n     */\n    public bool $shouldBeUniqueUntilProcessing = false;\n\n    /**\n     * The unique ID of the listener.\n     */\n    public mixed $uniqueId = null;\n\n    /**\n     * The number of seconds the unique lock should be maintained.\n     */\n    public ?int $uniqueFor = null;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  class-string  $class\n     * @param  string  $method\n     * @param  array  $data\n     */\n    public function __construct($class, $method, $data)\n    {\n        $this->data = $data;\n        $this->class = $class;\n        $this->method = $method;\n    }\n\n    /**\n     * Handle the queued job.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return void\n     */\n    public function handle(Container $container)\n    {\n        $this->prepareData();\n\n        $handler = $this->setJobInstanceIfNecessary(\n            $this->job, $container->make($this->class)\n        );\n\n        $handler->{$this->method}(...array_values($this->data));\n    }\n\n    /**\n     * Determine if the listener should be unique.\n     */\n    public function shouldBeUnique(): bool\n    {\n        return $this->shouldBeUnique;\n    }\n\n    /**\n     * Determine if the listener should be unique until processing begins.\n     */\n    public function shouldBeUniqueUntilProcessing(): bool\n    {\n        return $this->shouldBeUniqueUntilProcessing;\n    }\n\n    /**\n     * Get the unique ID for the listener.\n     */\n    public function uniqueId(): mixed\n    {\n        return $this->uniqueId;\n    }\n\n    /**\n     * Get the number of seconds the unique lock should be maintained.\n     */\n    public function uniqueFor(): ?int\n    {\n        return $this->uniqueFor;\n    }\n\n    /**\n     * Get the cache store used to manage unique locks.\n     */\n    public function uniqueVia(): ?Cache\n    {\n        $listener = Container::getInstance()->make($this->class);\n\n        if (! method_exists($listener, 'uniqueVia')) {\n            return null;\n        }\n\n        $this->prepareData();\n\n        return $listener->uniqueVia(...array_values($this->data));\n    }\n\n    /**\n     * Set the job instance of the given class if necessary.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  object  $instance\n     * @return object\n     */\n    protected function setJobInstanceIfNecessary(Job $job, $instance)\n    {\n        if (in_array(InteractsWithQueue::class, class_uses_recursive($instance))) {\n            $instance->setJob($job);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Call the failed method on the job instance.\n     *\n     * The event instance and the exception will be passed.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function failed($e)\n    {\n        $this->prepareData();\n\n        $handler = Container::getInstance()->make($this->class);\n\n        $parameters = array_merge(array_values($this->data), [$e]);\n\n        if (method_exists($handler, 'failed')) {\n            $handler->failed(...$parameters);\n        }\n    }\n\n    /**\n     * Unserialize the data if needed.\n     *\n     * @return void\n     */\n    protected function prepareData()\n    {\n        if (is_string($this->data)) {\n            $this->data = unserialize($this->data);\n        }\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        return $this->class;\n    }\n\n    /**\n     * Prepare the instance for cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->data = array_map(function ($data) {\n            return is_object($data) ? clone $data : $data;\n        }, $this->data);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/Dispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastFactory;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Container\\Container as ContainerContract;\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit;\nuse Illuminate\\Contracts\\Events\\ShouldHandleEventsAfterCommit;\nuse Illuminate\\Contracts\\Queue\\ShouldBeEncrypted;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Queue\\Attributes\\Backoff;\nuse Illuminate\\Queue\\Attributes\\Connection;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\Attributes\\FailOnTimeout;\nuse Illuminate\\Queue\\Attributes\\MaxExceptions;\nuse Illuminate\\Queue\\Attributes\\Queue as QueueAttribute;\nuse Illuminate\\Queue\\Attributes\\Timeout;\nuse Illuminate\\Queue\\Attributes\\Tries;\nuse Illuminate\\Queue\\Attributes\\UniqueFor;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Queue\\Concerns\\ResolvesQueueRoutes;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\ReadsClassAttributes;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse ReflectionClass;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Dispatcher implements DispatcherContract\n{\n    use Macroable, ReadsClassAttributes, ReflectsClosures, ResolvesQueueRoutes;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The registered event listeners.\n     *\n     * @var array<string, callable|array|class-string|null>\n     */\n    protected $listeners = [];\n\n    /**\n     * The wildcard listeners.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $wildcards = [];\n\n    /**\n     * The cached wildcard listeners.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $wildcardsCache = [];\n\n    /**\n     * The queue resolver instance.\n     *\n     * @var callable(): \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    protected $queueResolver;\n\n    /**\n     * The database transaction manager resolver instance.\n     *\n     * @var callable\n     */\n    protected $transactionManagerResolver;\n\n    /**\n     * The currently deferred events.\n     *\n     * @var array\n     */\n    protected $deferredEvents = [];\n\n    /**\n     * Indicates if events should be deferred.\n     *\n     * @var bool\n     */\n    protected $deferringEvents = false;\n\n    /**\n     * The specific events to defer (null means defer all events).\n     *\n     * @var string[]|null\n     */\n    protected $eventsToDefer = null;\n\n    /**\n     * Create a new event dispatcher instance.\n     */\n    public function __construct(?ContainerContract $container = null)\n    {\n        $this->container = $container ?: new Container;\n    }\n\n    /**\n     * Register an event listener with the dispatcher.\n     *\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string|string  $events\n     * @param  \\Illuminate\\Events\\QueuedClosure|callable|array|class-string|null  $listener\n     * @return void\n     */\n    public function listen($events, $listener = null)\n    {\n        if ($events instanceof Closure) {\n            return (new Collection($this->firstClosureParameterTypes($events)))\n                ->each(function ($event) use ($events) {\n                    $this->listen($event, $events);\n                });\n        } elseif ($events instanceof QueuedClosure) {\n            return (new Collection($this->firstClosureParameterTypes($events->closure)))\n                ->each(function ($event) use ($events) {\n                    $this->listen($event, $events->resolve());\n                });\n        } elseif ($listener instanceof QueuedClosure) {\n            $listener = $listener->resolve();\n        }\n\n        foreach ((array) $events as $event) {\n            if (str_contains($event, '*')) {\n                $this->setupWildcardListen($event, $listener);\n            } else {\n                $this->listeners[$event][] = $listener;\n            }\n        }\n    }\n\n    /**\n     * Setup a wildcard listener callback.\n     *\n     * @param  string  $event\n     * @param  \\Closure|string  $listener\n     * @return void\n     */\n    protected function setupWildcardListen($event, $listener)\n    {\n        $this->wildcards[$event][] = $listener;\n\n        $this->wildcardsCache = [];\n    }\n\n    /**\n     * Determine if a given event has listeners.\n     *\n     * @param  string  $eventName\n     * @return bool\n     */\n    public function hasListeners($eventName)\n    {\n        return isset($this->listeners[$eventName]) ||\n               isset($this->wildcards[$eventName]) ||\n               $this->hasWildcardListeners($eventName);\n    }\n\n    /**\n     * Determine if the given event has any wildcard listeners.\n     *\n     * @param  string  $eventName\n     * @return bool\n     */\n    public function hasWildcardListeners($eventName)\n    {\n        foreach ($this->wildcards as $key => $listeners) {\n            if (Str::is($key, $eventName)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Register an event and payload to be fired later.\n     *\n     * @param  string  $event\n     * @param  object|array  $payload\n     * @return void\n     */\n    public function push($event, $payload = [])\n    {\n        $this->listen($event.'_pushed', function () use ($event, $payload) {\n            $this->dispatch($event, $payload);\n        });\n    }\n\n    /**\n     * Flush a set of pushed events.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function flush($event)\n    {\n        $this->dispatch($event.'_pushed');\n    }\n\n    /**\n     * Register an event subscriber with the dispatcher.\n     *\n     * @param  object|string  $subscriber\n     * @return void\n     */\n    public function subscribe($subscriber)\n    {\n        $subscriber = $this->resolveSubscriber($subscriber);\n\n        $events = $subscriber->subscribe($this);\n\n        if (is_array($events)) {\n            foreach ($events as $event => $listeners) {\n                foreach (Arr::wrap($listeners) as $listener) {\n                    if (is_string($listener) && method_exists($subscriber, $listener)) {\n                        $this->listen($event, [get_class($subscriber), $listener]);\n\n                        continue;\n                    }\n\n                    $this->listen($event, $listener);\n                }\n            }\n        }\n    }\n\n    /**\n     * Resolve the subscriber instance.\n     *\n     * @param  object|class-string  $subscriber\n     * @return ($subscriber is object ? object : mixed)\n     */\n    protected function resolveSubscriber($subscriber)\n    {\n        if (is_string($subscriber)) {\n            return $this->container->make($subscriber);\n        }\n\n        return $subscriber;\n    }\n\n    /**\n     * Fire an event until the first non-null response is returned.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @return array|null\n     */\n    public function until($event, $payload = [])\n    {\n        return $this->dispatch($event, $payload, true);\n    }\n\n    /**\n     * Fire an event and call the listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return array|null\n     */\n    public function dispatch($event, $payload = [], $halt = false)\n    {\n        // When the given \"event\" is actually an object, we will assume it is an event\n        // object, and use the class as the event name and this event itself as the\n        // payload to the handler, which makes object-based events quite simple.\n        [$isEventObject, $parsedEvent, $parsedPayload] = [\n            is_object($event),\n            ...$this->parseEventAndPayload($event, $payload),\n        ];\n\n        if ($this->shouldDeferEvent($parsedEvent)) {\n            $this->deferredEvents[] = func_get_args();\n\n            return null;\n        }\n\n        // If the event is not intended to be dispatched unless the current database\n        // transaction is successful, we'll register a callback which will handle\n        // dispatching this event on the next successful DB transaction commit.\n        if ($isEventObject &&\n            $parsedPayload[0] instanceof ShouldDispatchAfterCommit &&\n            ! is_null($transactions = $this->resolveTransactionManager())) {\n            $transactions->addCallback(\n                fn () => $this->invokeListeners($parsedEvent, $parsedPayload, $halt)\n            );\n\n            return null;\n        }\n\n        return $this->invokeListeners($parsedEvent, $parsedPayload, $halt);\n    }\n\n    /**\n     * Broadcast an event and call its listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return array|null\n     */\n    protected function invokeListeners($event, $payload, $halt = false)\n    {\n        if ($this->shouldBroadcast($payload)) {\n            $this->broadcastEvent($payload[0]);\n        }\n\n        $responses = [];\n\n        foreach ($this->getListeners($event) as $listener) {\n            $response = $listener($event, $payload);\n\n            // If a response is returned from the listener and event halting is enabled\n            // we will just return this response, and not call the rest of the event\n            // listeners. Otherwise we will add the response on the response list.\n            if ($halt && ! is_null($response)) {\n                return $response;\n            }\n\n            // If a boolean false is returned from a listener, we will stop propagating\n            // the event to any further listeners down in the chain, else we keep on\n            // looping through the listeners and firing every one in our sequence.\n            if ($response === false) {\n                break;\n            }\n\n            $responses[] = $response;\n        }\n\n        return $halt ? null : $responses;\n    }\n\n    /**\n     * Parse the given event and payload and prepare them for dispatching.\n     *\n     * @param  mixed  $event\n     * @param  mixed  $payload\n     * @return array{string, array}\n     */\n    protected function parseEventAndPayload($event, $payload)\n    {\n        if (is_object($event)) {\n            [$payload, $event] = [[$event], get_class($event)];\n        }\n\n        return [$event, Arr::wrap($payload)];\n    }\n\n    /**\n     * Determine if the payload has a broadcastable event.\n     *\n     * @return bool\n     */\n    protected function shouldBroadcast(array $payload)\n    {\n        return isset($payload[0]) &&\n               $payload[0] instanceof ShouldBroadcast &&\n               $this->broadcastWhen($payload[0]);\n    }\n\n    /**\n     * Check if the event should be broadcasted by the condition.\n     *\n     * @param  mixed  $event\n     * @return bool\n     */\n    protected function broadcastWhen($event)\n    {\n        return method_exists($event, 'broadcastWhen')\n            ? $event->broadcastWhen()\n            : true;\n    }\n\n    /**\n     * Broadcast the given event class.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast  $event\n     * @return void\n     */\n    protected function broadcastEvent($event)\n    {\n        $this->container->make(BroadcastFactory::class)->queue($event);\n    }\n\n    /**\n     * Get all of the listeners for a given event name.\n     *\n     * @param  string  $eventName\n     * @return array\n     */\n    public function getListeners($eventName)\n    {\n        $listeners = array_merge(\n            $this->prepareListeners($eventName),\n            $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName)\n        );\n\n        return class_exists($eventName, false)\n            ? $this->addInterfaceListeners($eventName, $listeners)\n            : $listeners;\n    }\n\n    /**\n     * Get the wildcard listeners for the event.\n     *\n     * @param  string  $eventName\n     * @return array\n     */\n    protected function getWildcardListeners($eventName)\n    {\n        $wildcards = [];\n\n        foreach ($this->wildcards as $key => $listeners) {\n            if (Str::is($key, $eventName)) {\n                foreach ($listeners as $listener) {\n                    $wildcards[] = $this->makeListener($listener, true);\n                }\n            }\n        }\n\n        return $this->wildcardsCache[$eventName] = $wildcards;\n    }\n\n    /**\n     * Add the listeners for the event's interfaces to the given array.\n     *\n     * @param  string  $eventName\n     * @return array\n     */\n    protected function addInterfaceListeners($eventName, array $listeners = [])\n    {\n        foreach (class_implements($eventName) as $interface) {\n            if (isset($this->listeners[$interface])) {\n                foreach ($this->prepareListeners($interface) as $names) {\n                    $listeners = array_merge($listeners, (array) $names);\n                }\n            }\n        }\n\n        return $listeners;\n    }\n\n    /**\n     * Prepare the listeners for a given event.\n     *\n     * @return \\Closure[]\n     */\n    protected function prepareListeners(string $eventName)\n    {\n        $listeners = [];\n\n        foreach ($this->listeners[$eventName] ?? [] as $listener) {\n            $listeners[] = $this->makeListener($listener);\n        }\n\n        return $listeners;\n    }\n\n    /**\n     * Register an event listener with the dispatcher.\n     *\n     * @param  \\Closure|string|array{class-string, string}  $listener\n     * @param  bool  $wildcard\n     * @return \\Closure\n     */\n    public function makeListener($listener, $wildcard = false)\n    {\n        if (is_string($listener)) {\n            return $this->createClassListener($listener, $wildcard);\n        }\n\n        if (is_array($listener) && isset($listener[0]) && is_string($listener[0])) {\n            return $this->createClassListener($listener, $wildcard);\n        }\n\n        return function ($event, $payload) use ($listener, $wildcard) {\n            if ($wildcard) {\n                return $listener($event, $payload);\n            }\n\n            return $listener(...array_values($payload));\n        };\n    }\n\n    /**\n     * Create a class based listener using the IoC container.\n     *\n     * @param  string  $listener\n     * @param  bool  $wildcard\n     * @return \\Closure\n     */\n    public function createClassListener($listener, $wildcard = false)\n    {\n        return function ($event, $payload) use ($listener, $wildcard) {\n            if ($wildcard) {\n                return call_user_func($this->createClassCallable($listener), $event, $payload);\n            }\n\n            $callable = $this->createClassCallable($listener);\n\n            return $callable(...array_values($payload));\n        };\n    }\n\n    /**\n     * Create the class based event callable.\n     *\n     * @param  array{class-string, string}|string  $listener\n     * @return callable\n     */\n    protected function createClassCallable($listener)\n    {\n        [$class, $method] = is_array($listener)\n            ? $listener\n            : $this->parseClassCallable($listener);\n\n        if (! method_exists($class, $method)) {\n            $method = '__invoke';\n        }\n\n        if ($this->handlerShouldBeQueued($class)) {\n            return $this->createQueuedHandlerCallable($class, $method);\n        }\n\n        $listener = $this->container->make($class);\n\n        return $this->handlerShouldBeDispatchedAfterDatabaseTransactions($listener)\n                && ! in_array($method, ['creating', 'updating', 'saving', 'deleting', 'restoring', 'forceDeleting'])\n            ? $this->createCallbackForListenerRunningAfterCommits($listener, $method)\n            : [$listener, $method];\n    }\n\n    /**\n     * Parse the class listener into class and method.\n     *\n     * @param  string  $listener\n     * @return array{class-string, string}\n     */\n    protected function parseClassCallable($listener)\n    {\n        return Str::parseCallback($listener, 'handle');\n    }\n\n    /**\n     * Determine if the event handler class should be queued.\n     *\n     * @param  class-string  $class\n     * @return bool\n     *\n     * @phpstan-assert-if-true class-string<\\Illuminate\\Contracts\\Queue\\ShouldQueue> $class\n     */\n    protected function handlerShouldBeQueued($class)\n    {\n        try {\n            return (new ReflectionClass($class))->implementsInterface(\n                ShouldQueue::class\n            );\n        } catch (Exception) {\n            return false;\n        }\n    }\n\n    /**\n     * Create a callable for putting an event handler on the queue.\n     *\n     * @param  class-string  $class\n     * @param  string  $method\n     * @return \\Closure(): void\n     */\n    protected function createQueuedHandlerCallable($class, $method)\n    {\n        return function () use ($class, $method) {\n            $arguments = array_map(function ($a) {\n                return is_object($a) ? clone $a : $a;\n            }, func_get_args());\n\n            if ($this->handlerWantsToBeQueued($class, $arguments)) {\n                $this->queueHandler($class, $method, $arguments);\n            }\n        };\n    }\n\n    /**\n     * Determine if the given event handler should be dispatched after all database transactions have committed.\n     *\n     * @param  mixed  $listener\n     * @return bool\n     */\n    protected function handlerShouldBeDispatchedAfterDatabaseTransactions($listener)\n    {\n        return (($listener->afterCommit ?? null) ||\n                $listener instanceof ShouldHandleEventsAfterCommit) &&\n                $this->resolveTransactionManager();\n    }\n\n    /**\n     * Create a callable for dispatching a listener after database transactions.\n     *\n     * @param  mixed  $listener\n     * @param  string  $method\n     * @return \\Closure\n     */\n    protected function createCallbackForListenerRunningAfterCommits($listener, $method)\n    {\n        return function () use ($method, $listener) {\n            $payload = func_get_args();\n\n            $this->resolveTransactionManager()->addCallback(\n                function () use ($listener, $method, $payload) {\n                    $listener->$method(...$payload);\n                }\n            );\n        };\n    }\n\n    /**\n     * Determine if the event handler wants to be queued.\n     *\n     * @param  class-string  $class\n     * @param  array  $arguments\n     * @return bool\n     */\n    protected function handlerWantsToBeQueued($class, $arguments)\n    {\n        $instance = $this->container->make($class);\n\n        if (method_exists($instance, 'shouldQueue')) {\n            return $instance->shouldQueue($arguments[0]);\n        }\n\n        return true;\n    }\n\n    /**\n     * Queue the handler class.\n     *\n     * @param  string  $class\n     * @param  string  $method\n     * @param  array  $arguments\n     * @return void\n     */\n    protected function queueHandler($class, $method, $arguments)\n    {\n        [$listener, $job] = $this->createListenerAndJob($class, $method, $arguments);\n\n        if ($job->shouldBeUnique &&\n            ! (new UniqueLock($this->container->make(Cache::class)))->acquire($job)) {\n            return;\n        }\n\n        $connectionName = method_exists($listener, 'viaConnection')\n            ? (isset($arguments[0]) ? $listener->viaConnection($arguments[0]) : $listener->viaConnection())\n            : $this->getAttributeValue($listener, Connection::class, 'connection');\n\n        $connection = $this->resolveQueue()->connection(\n            $connectionName ?? $this->resolveConnectionFromQueueRoute($listener) ?? null\n        );\n\n        $queue = method_exists($listener, 'viaQueue')\n            ? (isset($arguments[0]) ? $listener->viaQueue($arguments[0]) : $listener->viaQueue())\n            : $this->getAttributeValue($listener, QueueAttribute::class, 'queue');\n\n        $delay = method_exists($listener, 'withDelay')\n            ? (isset($arguments[0]) ? $listener->withDelay($arguments[0]) : $listener->withDelay())\n            : $listener->delay ?? null;\n\n        if (is_null($queue)) {\n            $queue = $this->resolveQueueFromQueueRoute($listener) ?? null;\n        }\n\n        is_null($delay)\n            ? $connection->pushOn(enum_value($queue), $job)\n            : $connection->laterOn(enum_value($queue), $delay, $job);\n    }\n\n    /**\n     * Create the listener and job for a queued listener.\n     *\n     * @template TListener\n     *\n     * @param  class-string<TListener>  $class\n     * @param  string  $method\n     * @param  array  $arguments\n     * @return array{TListener, mixed}\n     */\n    protected function createListenerAndJob($class, $method, $arguments)\n    {\n        $listener = (new ReflectionClass($class))->newInstanceWithoutConstructor();\n\n        return [$listener, $this->propagateListenerOptions(\n            $listener, new CallQueuedListener($class, $method, $arguments)\n        )];\n    }\n\n    /**\n     * Propagate listener options to the job.\n     *\n     * @param  mixed  $listener\n     * @param  \\Illuminate\\Events\\CallQueuedListener  $job\n     * @return \\Illuminate\\Events\\CallQueuedListener\n     */\n    protected function propagateListenerOptions($listener, $job)\n    {\n        return tap($job, function ($job) use ($listener) {\n            $data = array_values($job->data);\n\n            if ($listener instanceof ShouldQueueAfterCommit) {\n                $job->afterCommit = true;\n            } else {\n                $job->afterCommit = property_exists($listener, 'afterCommit') ? $listener->afterCommit : null;\n            }\n\n            $job->backoff = method_exists($listener, 'backoff') ? $listener->backoff(...$data) : $this->getAttributeValue($listener, Backoff::class, 'backoff');\n            $job->maxExceptions = $this->getAttributeValue($listener, MaxExceptions::class, 'maxExceptions');\n            $job->retryUntil = method_exists($listener, 'retryUntil') ? $listener->retryUntil(...$data) : null;\n            $job->shouldBeEncrypted = $listener instanceof ShouldBeEncrypted;\n            $job->timeout = $this->getAttributeValue($listener, Timeout::class, 'timeout');\n            $job->failOnTimeout = $this->getAttributeValue($listener, FailOnTimeout::class, 'failOnTimeout') ?? false;\n            $job->deleteWhenMissingModels = $this->getAttributeValue($listener, DeleteWhenMissingModels::class, 'deleteWhenMissingModels') ?? false;\n            $job->tries = method_exists($listener, 'tries') ? $listener->tries(...$data) : $this->getAttributeValue($listener, Tries::class, 'tries');\n            $job->messageGroup = method_exists($listener, 'messageGroup') ? $listener->messageGroup(...$data) : ($listener->messageGroup ?? null);\n            $job->withDeduplicator(method_exists($listener, 'deduplicator')\n                ? $listener->deduplicator(...$data)\n                : (method_exists($listener, 'deduplicationId') ? $listener->deduplicationId(...) : null)\n            );\n\n            $job->through(array_merge(\n                method_exists($listener, 'middleware') ? $listener->middleware(...$data) : [],\n                $listener->middleware ?? []\n            ));\n\n            $job->shouldBeUnique = $listener instanceof ShouldBeUnique;\n            $job->shouldBeUniqueUntilProcessing = $listener instanceof ShouldBeUniqueUntilProcessing;\n\n            if ($job->shouldBeUnique) {\n                $job->uniqueId = method_exists($listener, 'uniqueId')\n                    ? $listener->uniqueId(...$data)\n                    : ($listener->uniqueId ?? null);\n\n                $job->uniqueFor = method_exists($listener, 'uniqueFor')\n                    ? $listener->uniqueFor(...$data)\n                    : ($this->getAttributeValue($listener, UniqueFor::class, 'uniqueFor') ?? 0);\n            }\n        });\n    }\n\n    /**\n     * Remove a set of listeners from the dispatcher.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function forget($event)\n    {\n        if (str_contains($event, '*')) {\n            unset($this->wildcards[$event]);\n        } else {\n            unset($this->listeners[$event]);\n        }\n\n        foreach ($this->wildcardsCache as $key => $listeners) {\n            if (Str::is($event, $key)) {\n                unset($this->wildcardsCache[$key]);\n            }\n        }\n    }\n\n    /**\n     * Forget all of the pushed listeners.\n     *\n     * @return void\n     */\n    public function forgetPushed()\n    {\n        foreach ($this->listeners as $key => $value) {\n            if (str_ends_with($key, '_pushed')) {\n                $this->forget($key);\n            }\n        }\n    }\n\n    /**\n     * Get the queue implementation from the resolver.\n     *\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    protected function resolveQueue()\n    {\n        return call_user_func($this->queueResolver);\n    }\n\n    /**\n     * Set the queue resolver implementation.\n     *\n     * @param  callable(): \\Illuminate\\Contracts\\Queue\\Queue  $resolver\n     * @return $this\n     */\n    public function setQueueResolver(callable $resolver)\n    {\n        $this->queueResolver = $resolver;\n\n        return $this;\n    }\n\n    /**\n     * Get the database transaction manager implementation from the resolver.\n     *\n     * @return \\Illuminate\\Database\\DatabaseTransactionsManager|null\n     */\n    protected function resolveTransactionManager()\n    {\n        return call_user_func($this->transactionManagerResolver);\n    }\n\n    /**\n     * Set the database transaction manager resolver implementation.\n     *\n     * @param  (callable(): (\\Illuminate\\Database\\DatabaseTransactionsManager|null))  $resolver\n     * @return $this\n     */\n    public function setTransactionManagerResolver(callable $resolver)\n    {\n        $this->transactionManagerResolver = $resolver;\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback while deferring events, then dispatch all deferred events.\n     *\n     * @template TResult\n     *\n     * @param  callable(): TResult  $callback\n     * @param  string[]|null  $events\n     * @return TResult\n     */\n    public function defer(callable $callback, ?array $events = null)\n    {\n        $wasDeferring = $this->deferringEvents;\n        $previousDeferredEvents = $this->deferredEvents;\n        $previousEventsToDefer = $this->eventsToDefer;\n\n        $this->deferringEvents = true;\n        $this->deferredEvents = [];\n        $this->eventsToDefer = $events;\n\n        try {\n            $result = $callback();\n\n            $this->deferringEvents = false;\n\n            foreach ($this->deferredEvents as $args) {\n                $this->dispatch(...$args);\n            }\n\n            return $result;\n        } finally {\n            $this->deferringEvents = $wasDeferring;\n            $this->deferredEvents = $previousDeferredEvents;\n            $this->eventsToDefer = $previousEventsToDefer;\n        }\n    }\n\n    /**\n     * Determine if the given event should be deferred.\n     *\n     * @return bool\n     */\n    protected function shouldDeferEvent(string $event)\n    {\n        return $this->deferringEvents && ($this->eventsToDefer === null || in_array($event, $this->eventsToDefer));\n    }\n\n    /**\n     * Gets the raw, unprepared listeners.\n     *\n     * @return array\n     */\n    public function getRawListeners()\n    {\n        return $this->listeners;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/EventServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Illuminate\\Contracts\\Queue\\Factory as QueueFactoryContract;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass EventServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('events', function ($app) {\n            return (new Dispatcher($app))->setQueueResolver(function () {\n                return app(QueueFactoryContract::class);\n            })->setTransactionManagerResolver(function () {\n                return app()->bound('db.transactions')\n                    ? app('db.transactions')\n                    : null;\n            });\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/InvokeQueuedClosure.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Illuminate\\Support\\Collection;\n\nclass InvokeQueuedClosure\n{\n    /**\n     * Handle the event.\n     *\n     * @param  \\Laravel\\SerializableClosure\\SerializableClosure  $closure\n     * @param  array  $arguments\n     * @return void\n     */\n    public function handle($closure, array $arguments)\n    {\n        call_user_func($closure->getClosure(), ...$arguments);\n    }\n\n    /**\n     * Handle a job failure.\n     *\n     * @param  \\Laravel\\SerializableClosure\\SerializableClosure  $closure\n     * @param  array  $arguments\n     * @param  array  $catchCallbacks\n     * @param  \\Throwable  $exception\n     * @return void\n     */\n    public function failed($closure, array $arguments, array $catchCallbacks, $exception)\n    {\n        $arguments[] = $exception;\n\n        (new Collection($catchCallbacks))->each->__invoke(...$arguments);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Events/NullDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\n\nclass NullDispatcher implements DispatcherContract\n{\n    use ForwardsCalls;\n\n    /**\n     * The underlying event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $dispatcher;\n\n    /**\n     * Create a new event dispatcher instance that does not fire.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     */\n    public function __construct(DispatcherContract $dispatcher)\n    {\n        $this->dispatcher = $dispatcher;\n    }\n\n    /**\n     * Don't fire an event.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return void\n     */\n    public function dispatch($event, $payload = [], $halt = false)\n    {\n        //\n    }\n\n    /**\n     * Don't register an event and payload to be fired later.\n     *\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     */\n    public function push($event, $payload = [])\n    {\n        //\n    }\n\n    /**\n     * Don't dispatch an event.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @return mixed\n     */\n    public function until($event, $payload = [])\n    {\n        //\n    }\n\n    /**\n     * Register an event listener with the dispatcher.\n     *\n     * @param  \\Closure|string|array  $events\n     * @param  \\Closure|string|array|null  $listener\n     * @return void\n     */\n    public function listen($events, $listener = null)\n    {\n        $this->dispatcher->listen($events, $listener);\n    }\n\n    /**\n     * Determine if a given event has listeners.\n     *\n     * @param  string  $eventName\n     * @return bool\n     */\n    public function hasListeners($eventName)\n    {\n        return $this->dispatcher->hasListeners($eventName);\n    }\n\n    /**\n     * Register an event subscriber with the dispatcher.\n     *\n     * @param  object|string  $subscriber\n     * @return void\n     */\n    public function subscribe($subscriber)\n    {\n        $this->dispatcher->subscribe($subscriber);\n    }\n\n    /**\n     * Flush a set of pushed events.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function flush($event)\n    {\n        $this->dispatcher->flush($event);\n    }\n\n    /**\n     * Remove a set of listeners from the dispatcher.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function forget($event)\n    {\n        $this->dispatcher->forget($event);\n    }\n\n    /**\n     * Forget all of the queued listeners.\n     *\n     * @return void\n     */\n    public function forgetPushed()\n    {\n        $this->dispatcher->forgetPushed();\n    }\n\n    /**\n     * Dynamically pass method calls to the underlying dispatcher.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardDecoratedCallTo($this->dispatcher, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/QueuedClosure.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Closure;\nuse Illuminate\\Support\\Collection;\nuse Laravel\\SerializableClosure\\SerializableClosure;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass QueuedClosure\n{\n    /**\n     * The underlying Closure.\n     *\n     * @var \\Closure\n     */\n    public $closure;\n\n    /**\n     * The name of the connection the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $connection;\n\n    /**\n     * The name of the queue the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $queue;\n\n    /**\n     * The job \"group\" the job should be sent to.\n     *\n     * @var string|null\n     */\n    public $messageGroup;\n\n    /**\n     * The job deduplicator callback the job should use to generate the deduplication ID.\n     *\n     * @var \\Laravel\\SerializableClosure\\SerializableClosure|null\n     */\n    public $deduplicator;\n\n    /**\n     * The number of seconds before the job should be made available.\n     *\n     * @var \\DateTimeInterface|\\DateInterval|int|null\n     */\n    public $delay;\n\n    /**\n     * All of the \"catch\" callbacks for the queued closure.\n     *\n     * @var array\n     */\n    public $catchCallbacks = [];\n\n    /**\n     * Create a new queued closure event listener resolver.\n     *\n     * @param  \\Closure  $closure\n     */\n    public function __construct(Closure $closure)\n    {\n        $this->closure = $closure;\n    }\n\n    /**\n     * Set the desired connection for the job.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return $this\n     */\n    public function onConnection($connection)\n    {\n        $this->connection = enum_value($connection);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the job.\n     *\n     * @param  \\UnitEnum|string|null  $queue\n     * @return $this\n     */\n    public function onQueue($queue)\n    {\n        $this->queue = enum_value($queue);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job \"group\".\n     *\n     * This feature is only supported by some queues, such as Amazon SQS.\n     *\n     * @param  \\UnitEnum|string  $group\n     * @return $this\n     */\n    public function onGroup($group)\n    {\n        $this->messageGroup = enum_value($group);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job deduplicator callback.\n     *\n     * This feature is only supported by some queues, such as Amazon SQS FIFO.\n     *\n     * @param  callable|null  $deduplicator\n     * @return $this\n     */\n    public function withDeduplicator($deduplicator)\n    {\n        $this->deduplicator = $deduplicator instanceof Closure\n            ? new SerializableClosure($deduplicator)\n            : $deduplicator;\n\n        return $this;\n    }\n\n    /**\n     * Set the desired delay in seconds for the job.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return $this\n     */\n    public function delay($delay)\n    {\n        $this->delay = $delay;\n\n        return $this;\n    }\n\n    /**\n     * Specify a callback that should be invoked if the queued listener job fails.\n     *\n     * @param  \\Closure  $closure\n     * @return $this\n     */\n    public function catch(Closure $closure)\n    {\n        $this->catchCallbacks[] = $closure;\n\n        return $this;\n    }\n\n    /**\n     * Resolve the actual event listener callback.\n     *\n     * @return \\Closure\n     */\n    public function resolve()\n    {\n        return function (...$arguments) {\n            dispatch(new CallQueuedListener(InvokeQueuedClosure::class, 'handle', [\n                'closure' => new SerializableClosure($this->closure),\n                'arguments' => $arguments,\n                'catch' => (new Collection($this->catchCallbacks))\n                    ->map(fn ($callback) => new SerializableClosure($callback))\n                    ->all(),\n            ]))\n                ->onConnection($this->connection)\n                ->onQueue($this->queue)\n                ->delay($this->delay)\n                ->onGroup($this->messageGroup)\n                ->withDeduplicator($this->deduplicator);\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/composer.json",
    "content": "{\n    \"name\": \"illuminate/events\",\n    \"description\": \"The Illuminate Events package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/bus\": \"^13.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Events\\\\\": \"\"\n        },\n        \"files\": [\n            \"functions.php\"\n        ]\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Events/functions.php",
    "content": "<?php\n\nnamespace Illuminate\\Events;\n\nuse Closure;\n\nif (! function_exists('Illuminate\\Events\\queueable')) {\n    /**\n     * Create a new queued Closure event listener.\n     *\n     * @param  \\Closure  $closure\n     */\n    function queueable(Closure $closure): QueuedClosure\n    {\n        return new QueuedClosure($closure);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Filesystem/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Filesystem/AwsS3V3Adapter.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Aws\\S3\\S3Client;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse League\\Flysystem\\FilesystemAdapter as FlysystemAdapter;\nuse League\\Flysystem\\FilesystemOperator;\n\nclass AwsS3V3Adapter extends FilesystemAdapter\n{\n    use Conditionable;\n\n    /**\n     * The AWS S3 client.\n     *\n     * @var \\Aws\\S3\\S3Client\n     */\n    protected $client;\n\n    /**\n     * Create a new AwsS3V3FilesystemAdapter instance.\n     *\n     * @param  \\League\\Flysystem\\FilesystemOperator  $driver\n     * @param  \\League\\Flysystem\\FilesystemAdapter  $adapter\n     * @param  array  $config\n     * @param  \\Aws\\S3\\S3Client  $client\n     */\n    public function __construct(FilesystemOperator $driver, FlysystemAdapter $adapter, array $config, S3Client $client)\n    {\n        $config['directory_separator'] = '/';\n\n        parent::__construct($driver, $adapter, $config);\n\n        $this->client = $client;\n    }\n\n    /**\n     * Get the URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function url($path)\n    {\n        // If an explicit base URL has been set on the disk configuration then we will use\n        // it as the base URL instead of the default path. This allows the developer to\n        // have full control over the base path for this filesystem's generated URLs.\n        if (isset($this->config['url'])) {\n            return $this->concatPathToUrl($this->config['url'], $this->prefixer->prefixPath($path));\n        }\n\n        return $this->client->getObjectUrl(\n            $this->config['bucket'], $this->prefixer->prefixPath($path)\n        );\n    }\n\n    /**\n     * Determine if temporary URLs can be generated.\n     *\n     * @return bool\n     */\n    public function providesTemporaryUrls()\n    {\n        return true;\n    }\n\n    /**\n     * Get a temporary URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return string\n     */\n    public function temporaryUrl($path, $expiration, array $options = [])\n    {\n        $command = $this->client->getCommand('GetObject', array_merge([\n            'Bucket' => $this->config['bucket'],\n            'Key' => $this->prefixer->prefixPath($path),\n        ], $options));\n\n        $uri = $this->client->createPresignedRequest(\n            $command, $expiration, $options\n        )->getUri();\n\n        // If an explicit base URL has been set on the disk configuration then we will use\n        // it as the base URL instead of the default path. This allows the developer to\n        // have full control over the base path for this filesystem's generated URLs.\n        if (isset($this->config['temporary_url'])) {\n            $uri = $this->replaceBaseUrl($uri, $this->config['temporary_url']);\n        }\n\n        return (string) $uri;\n    }\n\n    /**\n     * Get a temporary upload URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return array\n     */\n    public function temporaryUploadUrl($path, $expiration, array $options = [])\n    {\n        $command = $this->client->getCommand('PutObject', array_merge([\n            'Bucket' => $this->config['bucket'],\n            'Key' => $this->prefixer->prefixPath($path),\n        ], $options));\n\n        $signedRequest = $this->client->createPresignedRequest(\n            $command, $expiration, $options\n        );\n\n        $uri = $signedRequest->getUri();\n\n        // If an explicit base URL has been set on the disk configuration then we will use\n        // it as the base URL instead of the default path. This allows the developer to\n        // have full control over the base path for this filesystem's generated URLs.\n        if (isset($this->config['temporary_url'])) {\n            $uri = $this->replaceBaseUrl($uri, $this->config['temporary_url']);\n        }\n\n        return [\n            'url' => (string) $uri,\n            'headers' => $signedRequest->getHeaders(),\n        ];\n    }\n\n    /**\n     * Get the underlying S3 client.\n     *\n     * @return \\Aws\\S3\\S3Client\n     */\n    public function getClient()\n    {\n        return $this->client;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/Filesystem.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse ErrorException;\nuse FilesystemIterator;\nuse Illuminate\\Contracts\\Filesystem\\FileNotFoundException;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\nuse SplFileObject;\nuse Symfony\\Component\\Filesystem\\Filesystem as SymfonyFilesystem;\nuse Symfony\\Component\\Finder\\Finder;\nuse Symfony\\Component\\Mime\\MimeTypes;\n\nclass Filesystem\n{\n    use Conditionable, Macroable;\n\n    /**\n     * Determine if a file or directory exists.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function exists($path)\n    {\n        return file_exists($path);\n    }\n\n    /**\n     * Determine if a file or directory is missing.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function missing($path)\n    {\n        return ! $this->exists($path);\n    }\n\n    /**\n     * Get the contents of a file.\n     *\n     * @param  string  $path\n     * @param  bool  $lock\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function get($path, $lock = false)\n    {\n        if ($this->isFile($path)) {\n            return $lock ? $this->sharedGet($path) : file_get_contents($path);\n        }\n\n        throw new FileNotFoundException(\"File does not exist at path {$path}.\");\n    }\n\n    /**\n     * Get the contents of a file as decoded JSON.\n     *\n     * @param  string  $path\n     * @param  int  $flags\n     * @param  bool  $lock\n     * @return array\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function json($path, $flags = 0, $lock = false)\n    {\n        return json_decode($this->get($path, $lock), true, 512, $flags);\n    }\n\n    /**\n     * Get contents of a file with shared access.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function sharedGet($path)\n    {\n        $contents = '';\n\n        $handle = fopen($path, 'rb');\n\n        if ($handle) {\n            try {\n                if (flock($handle, LOCK_SH)) {\n                    clearstatcache(true, $path);\n\n                    $contents = stream_get_contents($handle);\n\n                    flock($handle, LOCK_UN);\n                }\n            } finally {\n                fclose($handle);\n            }\n        }\n\n        return $contents;\n    }\n\n    /**\n     * Get the returned value of a file.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function getRequire($path, array $data = [])\n    {\n        if ($this->isFile($path)) {\n            $__path = $path;\n            $__data = $data;\n\n            return (static function () use ($__path, $__data) {\n                extract($__data, EXTR_SKIP);\n\n                return require $__path;\n            })();\n        }\n\n        throw new FileNotFoundException(\"File does not exist at path {$path}.\");\n    }\n\n    /**\n     * Require the given file once.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function requireOnce($path, array $data = [])\n    {\n        if ($this->isFile($path)) {\n            $__path = $path;\n            $__data = $data;\n\n            return (static function () use ($__path, $__data) {\n                extract($__data, EXTR_SKIP);\n\n                return require_once $__path;\n            })();\n        }\n\n        throw new FileNotFoundException(\"File does not exist at path {$path}.\");\n    }\n\n    /**\n     * Get the contents of a file one line at a time.\n     *\n     * @param  string  $path\n     * @return \\Illuminate\\Support\\LazyCollection\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function lines($path)\n    {\n        if (! $this->isFile($path)) {\n            throw new FileNotFoundException(\n                \"File does not exist at path {$path}.\"\n            );\n        }\n\n        return new LazyCollection(function () use ($path) {\n            $file = new SplFileObject($path);\n\n            $file->setFlags(SplFileObject::DROP_NEW_LINE);\n\n            while (! $file->eof()) {\n                yield $file->fgets();\n            }\n        });\n    }\n\n    /**\n     * Get the hash of the file at the given path.\n     *\n     * @param  string  $path\n     * @param  string  $algorithm\n     * @return string|false\n     */\n    public function hash($path, $algorithm = 'md5')\n    {\n        return hash_file($algorithm, $path);\n    }\n\n    /**\n     * Write the contents of a file.\n     *\n     * @param  string  $path\n     * @param  string  $contents\n     * @param  bool  $lock\n     * @return int|bool\n     */\n    public function put($path, $contents, $lock = false)\n    {\n        return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);\n    }\n\n    /**\n     * Write the contents of a file, replacing it atomically if it already exists.\n     *\n     * @param  string  $path\n     * @param  string  $content\n     * @param  int|null  $mode\n     * @return void\n     */\n    public function replace($path, $content, $mode = null)\n    {\n        // If the path already exists and is a symlink, get the real path...\n        clearstatcache(true, $path);\n\n        $path = realpath($path) ?: $path;\n\n        $tempPath = tempnam(dirname($path), basename($path));\n\n        // Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...\n        if (! is_null($mode)) {\n            @chmod($tempPath, $mode);\n        } else {\n            @chmod($tempPath, 0777 - umask());\n        }\n\n        file_put_contents($tempPath, $content);\n\n        rename($tempPath, $path);\n    }\n\n    /**\n     * Replace a given string within a given file.\n     *\n     * @param  array|string  $search\n     * @param  array|string  $replace\n     * @param  string  $path\n     * @return void\n     */\n    public function replaceInFile($search, $replace, $path)\n    {\n        file_put_contents($path, str_replace($search, $replace, file_get_contents($path)));\n    }\n\n    /**\n     * Prepend to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @return int\n     */\n    public function prepend($path, $data)\n    {\n        if ($this->exists($path)) {\n            return $this->put($path, $data.$this->get($path));\n        }\n\n        return $this->put($path, $data);\n    }\n\n    /**\n     * Append to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @param  bool  $lock\n     * @return int\n     */\n    public function append($path, $data, $lock = false)\n    {\n        return file_put_contents($path, $data, FILE_APPEND | ($lock ? LOCK_EX : 0));\n    }\n\n    /**\n     * Get or set UNIX mode of a file or directory.\n     *\n     * @param  string  $path\n     * @param  int|null  $mode\n     * @return mixed\n     */\n    public function chmod($path, $mode = null)\n    {\n        if ($mode) {\n            return chmod($path, $mode);\n        }\n\n        return substr(sprintf('%o', fileperms($path)), -4);\n    }\n\n    /**\n     * Delete the file at a given path.\n     *\n     * @param  string|array  $paths\n     * @return bool\n     */\n    public function delete($paths)\n    {\n        $paths = is_array($paths) ? $paths : func_get_args();\n\n        $success = true;\n\n        foreach ($paths as $path) {\n            try {\n                if (@unlink($path)) {\n                    clearstatcache(false, $path);\n                } else {\n                    $success = false;\n                }\n            } catch (ErrorException) {\n                $success = false;\n            }\n        }\n\n        return $success;\n    }\n\n    /**\n     * Move a file to a new location.\n     *\n     * @param  string  $path\n     * @param  string  $target\n     * @return bool\n     */\n    public function move($path, $target)\n    {\n        return rename($path, $target);\n    }\n\n    /**\n     * Copy a file to a new location.\n     *\n     * @param  string  $path\n     * @param  string  $target\n     * @return bool\n     */\n    public function copy($path, $target)\n    {\n        return copy($path, $target);\n    }\n\n    /**\n     * Create a symlink to the target file or directory. On Windows, a hard link is created if the target is a file.\n     *\n     * @param  string  $target\n     * @param  string  $link\n     * @return bool|null\n     */\n    public function link($target, $link)\n    {\n        if (! windows_os()) {\n            if (function_exists('symlink')) {\n                return symlink($target, $link);\n            } else {\n                return exec('ln -s '.escapeshellarg($target).' '.escapeshellarg($link)) !== false;\n            }\n        }\n\n        $mode = $this->isDirectory($target) ? 'J' : 'H';\n\n        exec(\"mklink /{$mode} \".escapeshellarg($link).' '.escapeshellarg($target));\n    }\n\n    /**\n     * Create a relative symlink to the target file or directory.\n     *\n     * @param  string  $target\n     * @param  string  $link\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function relativeLink($target, $link)\n    {\n        if (! class_exists(SymfonyFilesystem::class)) {\n            throw new RuntimeException(\n                'To enable support for relative links, please install the symfony/filesystem package.'\n            );\n        }\n\n        $relativeTarget = (new SymfonyFilesystem)->makePathRelative($target, dirname($link));\n\n        $this->link($this->isFile($target) ? rtrim($relativeTarget, '/') : $relativeTarget, $link);\n    }\n\n    /**\n     * Extract the file name from a file path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function name($path)\n    {\n        return pathinfo($path, PATHINFO_FILENAME);\n    }\n\n    /**\n     * Extract the trailing name component from a file path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function basename($path)\n    {\n        return pathinfo($path, PATHINFO_BASENAME);\n    }\n\n    /**\n     * Extract the parent directory from a file path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function dirname($path)\n    {\n        return pathinfo($path, PATHINFO_DIRNAME);\n    }\n\n    /**\n     * Extract the file extension from a file path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function extension($path)\n    {\n        return pathinfo($path, PATHINFO_EXTENSION);\n    }\n\n    /**\n     * Guess the file extension from the MIME type of a given file.\n     *\n     * @param  string  $path\n     * @return string|null\n     *\n     * @throws \\RuntimeException\n     */\n    public function guessExtension($path)\n    {\n        if (! class_exists(MimeTypes::class)) {\n            throw new RuntimeException(\n                'To enable support for guessing extensions, please install the symfony/mime package.'\n            );\n        }\n\n        return (new MimeTypes)->getExtensions($this->mimeType($path))[0] ?? null;\n    }\n\n    /**\n     * Get the file type of a given file.\n     *\n     * @param  string  $path\n     * @return string|false\n     */\n    public function type($path)\n    {\n        return filetype($path);\n    }\n\n    /**\n     * Get the MIME type of a given file.\n     *\n     * @param  string  $path\n     * @return string|false\n     */\n    public function mimeType($path)\n    {\n        return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);\n    }\n\n    /**\n     * Get the file size of a given file.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function size($path)\n    {\n        return filesize($path);\n    }\n\n    /**\n     * Get the file's last modification time.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function lastModified($path)\n    {\n        return filemtime($path);\n    }\n\n    /**\n     * Determine if the given path is a directory.\n     *\n     * @param  string  $directory\n     * @return bool\n     */\n    public function isDirectory($directory)\n    {\n        return is_dir($directory);\n    }\n\n    /**\n     * Determine if the given path is a directory that does not contain any other files or directories.\n     *\n     * @param  string  $directory\n     * @param  bool  $ignoreDotFiles\n     * @return bool\n     */\n    public function isEmptyDirectory($directory, $ignoreDotFiles = false)\n    {\n        return ! Finder::create()->ignoreDotFiles($ignoreDotFiles)->in($directory)->depth(0)->hasResults();\n    }\n\n    /**\n     * Determine if the given path is readable.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function isReadable($path)\n    {\n        return is_readable($path);\n    }\n\n    /**\n     * Determine if the given path is writable.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function isWritable($path)\n    {\n        return is_writable($path);\n    }\n\n    /**\n     * Determine if two files are the same by comparing their hashes.\n     *\n     * @param  string  $firstFile\n     * @param  string  $secondFile\n     * @return bool\n     */\n    public function hasSameHash($firstFile, $secondFile)\n    {\n        $hash = @hash_file('xxh128', $firstFile);\n\n        return $hash && hash_equals($hash, (string) @hash_file('xxh128', $secondFile));\n    }\n\n    /**\n     * Determine if the given path is a file.\n     *\n     * @param  string  $file\n     * @return bool\n     */\n    public function isFile($file)\n    {\n        return is_file($file);\n    }\n\n    /**\n     * Find path names matching a given pattern.\n     *\n     * @param  string  $pattern\n     * @param  int  $flags\n     * @return array\n     */\n    public function glob($pattern, $flags = 0)\n    {\n        return glob($pattern, $flags);\n    }\n\n    /**\n     * Get an array of all files in a directory.\n     *\n     * @param  string  $directory\n     * @param  bool  $hidden\n     * @return \\Symfony\\Component\\Finder\\SplFileInfo[]\n     */\n    public function files($directory, $hidden = false, array|string|int $depth = 0)\n    {\n        return iterator_to_array(\n            Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->depth($depth)->sortByName(),\n            false\n        );\n    }\n\n    /**\n     * Get all of the files from the given directory (recursive).\n     *\n     * @param  string  $directory\n     * @param  bool  $hidden\n     * @return \\Symfony\\Component\\Finder\\SplFileInfo[]\n     */\n    public function allFiles($directory, $hidden = false)\n    {\n        return $this->files($directory, $hidden, []);\n    }\n\n    /**\n     * Get all of the directories within a given directory.\n     *\n     * @param  string  $directory\n     * @return array\n     */\n    public function directories($directory, array|string|int $depth = 0)\n    {\n        $directories = [];\n\n        foreach (Finder::create()->in($directory)->directories()->depth($depth)->sortByName() as $dir) {\n            $directories[] = $dir->getPathname();\n        }\n\n        return $directories;\n    }\n\n    /**\n     * Get all the directories within a given directory (recursive).\n     *\n     * @return array\n     */\n    public function allDirectories(string $directory): array\n    {\n        return $this->directories($directory, []);\n    }\n\n    /**\n     * Ensure a directory exists.\n     *\n     * @param  string  $path\n     * @param  int  $mode\n     * @param  bool  $recursive\n     * @return void\n     */\n    public function ensureDirectoryExists($path, $mode = 0755, $recursive = true)\n    {\n        if (! $this->isDirectory($path)) {\n            $this->makeDirectory($path, $mode, $recursive);\n        }\n    }\n\n    /**\n     * Create a directory.\n     *\n     * @param  string  $path\n     * @param  int  $mode\n     * @param  bool  $recursive\n     * @param  bool  $force\n     * @return bool\n     */\n    public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false)\n    {\n        if ($force) {\n            return @mkdir($path, $mode, $recursive);\n        }\n\n        return mkdir($path, $mode, $recursive);\n    }\n\n    /**\n     * Move a directory.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @param  bool  $overwrite\n     * @return bool\n     */\n    public function moveDirectory($from, $to, $overwrite = false)\n    {\n        if ($overwrite && $this->isDirectory($to) && ! $this->deleteDirectory($to)) {\n            return false;\n        }\n\n        return @rename($from, $to) === true;\n    }\n\n    /**\n     * Copy a directory from one location to another.\n     *\n     * @param  string  $directory\n     * @param  string  $destination\n     * @param  int|null  $options\n     * @return bool\n     */\n    public function copyDirectory($directory, $destination, $options = null)\n    {\n        if (! $this->isDirectory($directory)) {\n            return false;\n        }\n\n        $options = $options ?: FilesystemIterator::SKIP_DOTS;\n\n        // If the destination directory does not actually exist, we will go ahead and\n        // create it recursively, which just gets the destination prepared to copy\n        // the files over. Once we make the directory we'll proceed the copying.\n        $this->ensureDirectoryExists($destination, 0777);\n\n        $items = new FilesystemIterator($directory, $options);\n\n        foreach ($items as $item) {\n            // As we spin through items, we will check to see if the current file is actually\n            // a directory or a file. When it is actually a directory we will need to call\n            // back into this function recursively to keep copying these nested folders.\n            $target = $destination.'/'.$item->getBasename();\n\n            if ($item->isDir()) {\n                $path = $item->getPathname();\n\n                if (! $this->copyDirectory($path, $target, $options)) {\n                    return false;\n                }\n            }\n\n            // If the current items is just a regular file, we will just copy this to the new\n            // location and keep looping. If for some reason the copy fails we'll bail out\n            // and return false, so the developer is aware that the copy process failed.\n            elseif (! $this->copy($item->getPathname(), $target)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Recursively delete a directory.\n     *\n     * The directory itself may be optionally preserved.\n     *\n     * @param  string  $directory\n     * @param  bool  $preserve\n     * @return bool\n     */\n    public function deleteDirectory($directory, $preserve = false)\n    {\n        if (! $this->isDirectory($directory)) {\n            return false;\n        }\n\n        $items = new FilesystemIterator($directory);\n\n        foreach ($items as $item) {\n            // If the item is a directory, we can just recurse into the function and\n            // delete that sub-directory otherwise we'll just delete the file and\n            // keep iterating through each file until the directory is cleaned.\n            if ($item->isDir() && ! $item->isLink()) {\n                $this->deleteDirectory($item->getPathname());\n            }\n\n            // If the item is just a file, we can go ahead and delete it since we're\n            // just looping through and waxing all of the files in this directory\n            // and calling directories recursively, so we delete the real path.\n            else {\n                $this->delete($item->getPathname());\n            }\n        }\n\n        unset($items);\n\n        if (! $preserve) {\n            @rmdir($directory);\n        }\n\n        return true;\n    }\n\n    /**\n     * Remove all of the directories within a given directory.\n     *\n     * @param  string  $directory\n     * @return bool\n     */\n    public function deleteDirectories($directory)\n    {\n        $allDirectories = $this->directories($directory);\n\n        if (! empty($allDirectories)) {\n            foreach ($allDirectories as $directoryName) {\n                $this->deleteDirectory($directoryName);\n            }\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Empty the specified directory of all files and folders.\n     *\n     * @param  string  $directory\n     * @return bool\n     */\n    public function cleanDirectory($directory)\n    {\n        return $this->deleteDirectory($directory, true);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/FilesystemAdapter.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Filesystem\\Cloud as CloudFilesystemContract;\nuse Illuminate\\Contracts\\Filesystem\\Filesystem as FilesystemContract;\nuse Illuminate\\Http\\File;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse League\\Flysystem\\FilesystemAdapter as FlysystemAdapter;\nuse League\\Flysystem\\FilesystemOperator;\nuse League\\Flysystem\\Ftp\\FtpAdapter;\nuse League\\Flysystem\\Local\\LocalFilesystemAdapter as LocalAdapter;\nuse League\\Flysystem\\PathPrefixer;\nuse League\\Flysystem\\PhpseclibV3\\SftpAdapter;\nuse League\\Flysystem\\StorageAttributes;\nuse League\\Flysystem\\UnableToCopyFile;\nuse League\\Flysystem\\UnableToCreateDirectory;\nuse League\\Flysystem\\UnableToDeleteDirectory;\nuse League\\Flysystem\\UnableToDeleteFile;\nuse League\\Flysystem\\UnableToMoveFile;\nuse League\\Flysystem\\UnableToProvideChecksum;\nuse League\\Flysystem\\UnableToReadFile;\nuse League\\Flysystem\\UnableToRetrieveMetadata;\nuse League\\Flysystem\\UnableToSetVisibility;\nuse League\\Flysystem\\UnableToWriteFile;\nuse League\\Flysystem\\Visibility;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse Psr\\Http\\Message\\StreamInterface;\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\n/**\n * @mixin \\League\\Flysystem\\FilesystemOperator\n */\nclass FilesystemAdapter implements CloudFilesystemContract\n{\n    use Conditionable;\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The Flysystem filesystem implementation.\n     *\n     * @var \\League\\Flysystem\\FilesystemOperator\n     */\n    protected $driver;\n\n    /**\n     * The Flysystem adapter implementation.\n     *\n     * @var \\League\\Flysystem\\FilesystemAdapter\n     */\n    protected $adapter;\n\n    /**\n     * The filesystem configuration.\n     *\n     * @var array\n     */\n    protected $config;\n\n    /**\n     * The Flysystem PathPrefixer instance.\n     *\n     * @var \\League\\Flysystem\\PathPrefixer\n     */\n    protected $prefixer;\n\n    /**\n     * The file server callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $serveCallback;\n\n    /**\n     * The temporary URL builder callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $temporaryUrlCallback;\n\n    /**\n     * The temporary upload URL builder callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $temporaryUploadUrlCallback;\n\n    /**\n     * Create a new filesystem adapter instance.\n     *\n     * @param  \\League\\Flysystem\\FilesystemOperator  $driver\n     * @param  \\League\\Flysystem\\FilesystemAdapter  $adapter\n     * @param  array  $config\n     */\n    public function __construct(FilesystemOperator $driver, FlysystemAdapter $adapter, array $config = [])\n    {\n        $this->driver = $driver;\n        $this->adapter = $adapter;\n        $this->config = $config;\n        $separator = $config['directory_separator'] ?? DIRECTORY_SEPARATOR;\n\n        $this->prefixer = new PathPrefixer($config['root'] ?? '', $separator);\n\n        if (isset($config['prefix'])) {\n            $this->prefixer = new PathPrefixer($this->prefixer->prefixPath($config['prefix']), $separator);\n        }\n    }\n\n    /**\n     * Assert that the given file or directory exists.\n     *\n     * @param  string|array  $path\n     * @param  string|null  $content\n     * @return $this\n     */\n    public function assertExists($path, $content = null)\n    {\n        clearstatcache();\n\n        $paths = Arr::wrap($path);\n\n        foreach ($paths as $path) {\n            PHPUnit::assertTrue(\n                $this->exists($path), \"Unable to find a file or directory at path [{$path}].\"\n            );\n\n            if (! is_null($content)) {\n                $actual = $this->get($path);\n\n                PHPUnit::assertSame(\n                    $content,\n                    $actual,\n                    \"File or directory [{$path}] was found, but content [{$actual}] does not match [{$content}].\"\n                );\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the number of files in path equals the expected count.\n     *\n     * @param  string  $path\n     * @param  int  $count\n     * @param  bool  $recursive\n     * @return $this\n     */\n    public function assertCount($path, $count, $recursive = false)\n    {\n        clearstatcache();\n\n        $actual = count($this->files($path, $recursive));\n\n        PHPUnit::assertEquals(\n            $count, $actual, \"Expected [{$count}] files at [{$path}], but found [{$actual}].\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given file or directory does not exist.\n     *\n     * @param  string|array  $path\n     * @return $this\n     */\n    public function assertMissing($path)\n    {\n        clearstatcache();\n\n        $paths = Arr::wrap($path);\n\n        foreach ($paths as $path) {\n            PHPUnit::assertFalse(\n                $this->exists($path), \"Found unexpected file or directory at path [{$path}].\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given directory is empty.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function assertDirectoryEmpty($path)\n    {\n        PHPUnit::assertEmpty(\n            $this->allFiles($path), \"Directory [{$path}] is not empty.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Determine if a file or directory exists.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function exists($path)\n    {\n        return $this->driver->has($path);\n    }\n\n    /**\n     * Determine if a file or directory is missing.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function missing($path)\n    {\n        return ! $this->exists($path);\n    }\n\n    /**\n     * Determine if a file exists.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function fileExists($path)\n    {\n        return $this->driver->fileExists($path);\n    }\n\n    /**\n     * Determine if a file is missing.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function fileMissing($path)\n    {\n        return ! $this->fileExists($path);\n    }\n\n    /**\n     * Determine if a directory exists.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function directoryExists($path)\n    {\n        return $this->driver->directoryExists($path);\n    }\n\n    /**\n     * Determine if a directory is missing.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function directoryMissing($path)\n    {\n        return ! $this->directoryExists($path);\n    }\n\n    /**\n     * Get the full path to the file that exists at the given relative path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function path($path)\n    {\n        return $this->prefixer->prefixPath($path);\n    }\n\n    /**\n     * Get the contents of a file.\n     *\n     * @param  string  $path\n     * @return string|null\n     */\n    public function get($path)\n    {\n        try {\n            return $this->driver->read($path);\n        } catch (UnableToReadFile $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n        }\n    }\n\n    /**\n     * Get the contents of a file as decoded JSON.\n     *\n     * @param  string  $path\n     * @param  int  $flags\n     * @return array|null\n     */\n    public function json($path, $flags = 0)\n    {\n        $content = $this->get($path);\n\n        return is_null($content) ? null : json_decode($content, true, 512, $flags);\n    }\n\n    /**\n     * Create a streamed response for a given file.\n     *\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @param  string|null  $disposition\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function response($path, $name = null, array $headers = [], $disposition = 'inline')\n    {\n        $response = new StreamedResponse;\n\n        $headers['Content-Type'] ??= $this->mimeType($path);\n        $headers['Content-Length'] ??= $this->size($path);\n\n        if (! array_key_exists('Content-Disposition', $headers)) {\n            $filename = $name ?? basename($path);\n\n            $disposition = $response->headers->makeDisposition(\n                $disposition, $filename, $this->fallbackName($filename)\n            );\n\n            $headers['Content-Disposition'] = $disposition;\n        }\n\n        $response->headers->replace($headers);\n\n        $response->setCallback(function () use ($path) {\n            $stream = $this->readStream($path);\n            fpassthru($stream);\n            fclose($stream);\n        });\n\n        return $response;\n    }\n\n    /**\n     * Create a streamed download response for a given file.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function serve(Request $request, $path, $name = null, array $headers = [])\n    {\n        return isset($this->serveCallback)\n            ? call_user_func($this->serveCallback, $request, $path, $headers)\n            : $this->response($path, $name, $headers);\n    }\n\n    /**\n     * Create a streamed download response for a given file.\n     *\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function download($path, $name = null, array $headers = [])\n    {\n        return $this->response($path, $name, $headers, 'attachment');\n    }\n\n    /**\n     * Convert the string to ASCII characters that are equivalent to the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function fallbackName($name)\n    {\n        return str_replace('%', '', Str::ascii($name));\n    }\n\n    /**\n     * Write the contents of a file.\n     *\n     * @param  string  $path\n     * @param  \\Psr\\Http\\Message\\StreamInterface|\\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|resource  $contents\n     * @param  mixed  $options\n     * @return string|bool\n     */\n    public function put($path, $contents, $options = [])\n    {\n        $options = is_string($options)\n            ? ['visibility' => $options]\n            : (array) $options;\n\n        // If the given contents is actually a file or uploaded file instance than we will\n        // automatically store the file using a stream. This provides a convenient path\n        // for the developer to store streams without managing them manually in code.\n        if ($contents instanceof File ||\n            $contents instanceof UploadedFile) {\n            return $this->putFile($path, $contents, $options);\n        }\n\n        try {\n            if ($contents instanceof StreamInterface) {\n                $this->driver->writeStream($path, $contents->detach(), $options);\n\n                return true;\n            }\n\n            is_resource($contents)\n                ? $this->driver->writeStream($path, $contents, $options)\n                : $this->driver->write($path, $contents, $options);\n        } catch (UnableToWriteFile|UnableToSetVisibility $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Store the uploaded file on the disk.\n     *\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string  $path\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null  $file\n     * @param  mixed  $options\n     * @return string|false\n     */\n    public function putFile($path, $file = null, $options = [])\n    {\n        if (is_null($file) || is_array($file)) {\n            [$path, $file, $options] = ['', $path, $file ?? []];\n        }\n\n        $file = is_string($file) ? new File($file) : $file;\n\n        return $this->putFileAs($path, $file, $file->hashName(), $options);\n    }\n\n    /**\n     * Store the uploaded file on the disk with a given name.\n     *\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string  $path\n     * @param  \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null  $file\n     * @param  string|array|null  $name\n     * @param  mixed  $options\n     * @return string|false\n     */\n    public function putFileAs($path, $file, $name = null, $options = [])\n    {\n        if (is_null($name) || is_array($name)) {\n            [$path, $file, $name, $options] = ['', $path, $file, $name ?? []];\n        }\n\n        $stream = fopen(is_string($file) ? $file : $file->getRealPath(), 'r');\n\n        // Next, we will format the path of the file and store the file using a stream since\n        // they provide better performance than alternatives. Once we write the file this\n        // stream will get closed automatically by us so the developer doesn't have to.\n        $result = $this->put(\n            $path = trim($path.'/'.$name, '/'), $stream, $options\n        );\n\n        if (is_resource($stream)) {\n            fclose($stream);\n        }\n\n        return $result ? $path : false;\n    }\n\n    /**\n     * Get the visibility for the given path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function getVisibility($path)\n    {\n        if ($this->driver->visibility($path) == Visibility::PUBLIC) {\n            return FilesystemContract::VISIBILITY_PUBLIC;\n        }\n\n        return FilesystemContract::VISIBILITY_PRIVATE;\n    }\n\n    /**\n     * Set the visibility for the given path.\n     *\n     * @param  string  $path\n     * @param  string  $visibility\n     * @return bool\n     */\n    public function setVisibility($path, $visibility)\n    {\n        try {\n            $this->driver->setVisibility($path, $this->parseVisibility($visibility));\n        } catch (UnableToSetVisibility $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Prepend to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @param  string  $separator\n     * @return bool\n     */\n    public function prepend($path, $data, $separator = PHP_EOL)\n    {\n        if ($this->fileExists($path)) {\n            return $this->put($path, $data.$separator.$this->get($path));\n        }\n\n        return $this->put($path, $data);\n    }\n\n    /**\n     * Append to a file.\n     *\n     * @param  string  $path\n     * @param  string  $data\n     * @param  string  $separator\n     * @return bool\n     */\n    public function append($path, $data, $separator = PHP_EOL)\n    {\n        if ($this->fileExists($path)) {\n            return $this->put($path, $this->get($path).$separator.$data);\n        }\n\n        return $this->put($path, $data);\n    }\n\n    /**\n     * Delete the file at a given path.\n     *\n     * @param  string|array  $paths\n     * @return bool\n     */\n    public function delete($paths)\n    {\n        $paths = is_array($paths) ? $paths : func_get_args();\n\n        $success = true;\n\n        foreach ($paths as $path) {\n            try {\n                $this->driver->delete($path);\n            } catch (UnableToDeleteFile $e) {\n                throw_if($this->throwsExceptions(), $e);\n\n                $this->report($e);\n\n                $success = false;\n            }\n        }\n\n        return $success;\n    }\n\n    /**\n     * Copy a file to a new location.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return bool\n     */\n    public function copy($from, $to)\n    {\n        try {\n            $this->driver->copy($from, $to);\n        } catch (UnableToCopyFile $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Move a file to a new location.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return bool\n     */\n    public function move($from, $to)\n    {\n        try {\n            $this->driver->move($from, $to);\n        } catch (UnableToMoveFile $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the file size of a given file.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function size($path)\n    {\n        return $this->driver->fileSize($path);\n    }\n\n    /**\n     * Get the checksum for a file.\n     *\n     * @return string|false\n     *\n     * @throws UnableToProvideChecksum\n     */\n    public function checksum(string $path, array $options = [])\n    {\n        try {\n            return $this->driver->checksum($path, $options);\n        } catch (UnableToProvideChecksum $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n    }\n\n    /**\n     * Get the mime-type of a given file.\n     *\n     * @param  string  $path\n     * @return string|false\n     */\n    public function mimeType($path)\n    {\n        try {\n            return $this->driver->mimeType($path);\n        } catch (UnableToRetrieveMetadata $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the file's last modification time.\n     *\n     * @param  string  $path\n     * @return int\n     */\n    public function lastModified($path)\n    {\n        return $this->driver->lastModified($path);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function readStream($path)\n    {\n        try {\n            return $this->driver->readStream($path);\n        } catch (UnableToReadFile $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function writeStream($path, $resource, array $options = [])\n    {\n        try {\n            $this->driver->writeStream($path, $resource, $options);\n        } catch (UnableToWriteFile|UnableToSetVisibility $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function url($path)\n    {\n        if (isset($this->config['prefix'])) {\n            $path = $this->concatPathToUrl($this->config['prefix'], $path);\n        }\n\n        $adapter = $this->adapter;\n\n        if (method_exists($adapter, 'getUrl')) {\n            return $adapter->getUrl($path);\n        } elseif (method_exists($this->driver, 'getUrl')) {\n            return $this->driver->getUrl($path);\n        } elseif ($adapter instanceof FtpAdapter || $adapter instanceof SftpAdapter) {\n            return $this->getFtpUrl($path);\n        } elseif ($adapter instanceof LocalAdapter) {\n            return $this->getLocalUrl($path);\n        } else {\n            throw new RuntimeException('This driver does not support retrieving URLs.');\n        }\n    }\n\n    /**\n     * Get the URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function getFtpUrl($path)\n    {\n        return isset($this->config['url'])\n            ? $this->concatPathToUrl($this->config['url'], $path)\n            : $path;\n    }\n\n    /**\n     * Get the URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function getLocalUrl($path)\n    {\n        // If an explicit base URL has been set on the disk configuration then we will use\n        // it as the base URL instead of the default path. This allows the developer to\n        // have full control over the base path for this filesystem's generated URLs.\n        if (isset($this->config['url'])) {\n            return $this->concatPathToUrl($this->config['url'], $path);\n        }\n\n        $path = '/storage/'.$path;\n\n        // If the path contains \"storage/public\", it probably means the developer is using\n        // the default disk to generate the path instead of the \"public\" disk like they\n        // are really supposed to use. We will remove the public from this path here.\n        if (str_contains($path, '/storage/public/')) {\n            return Str::replaceFirst('/public/', '/', $path);\n        }\n\n        return $path;\n    }\n\n    /**\n     * Determine if temporary URLs can be generated.\n     *\n     * @return bool\n     */\n    public function providesTemporaryUrls()\n    {\n        return method_exists($this->adapter, 'getTemporaryUrl') || isset($this->temporaryUrlCallback);\n    }\n\n    /**\n     * Determine if temporary upload URLs can be generated.\n     *\n     * @return bool\n     */\n    public function providesTemporaryUploadUrls()\n    {\n        return method_exists($this->adapter, 'temporaryUploadUrl') || isset($this->temporaryUploadUrlCallback);\n    }\n\n    /**\n     * Get a temporary URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function temporaryUrl($path, $expiration, array $options = [])\n    {\n        if (method_exists($this->adapter, 'getTemporaryUrl')) {\n            return $this->adapter->getTemporaryUrl($path, $expiration, $options);\n        }\n\n        if ($this->temporaryUrlCallback) {\n            return $this->temporaryUrlCallback->bindTo($this, static::class)(\n                $path, $expiration, $options\n            );\n        }\n\n        throw new RuntimeException('This driver does not support creating temporary URLs.');\n    }\n\n    /**\n     * Get a temporary upload URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    public function temporaryUploadUrl($path, $expiration, array $options = [])\n    {\n        if (method_exists($this->adapter, 'temporaryUploadUrl')) {\n            return $this->adapter->temporaryUploadUrl($path, $expiration, $options);\n        }\n\n        if ($this->temporaryUploadUrlCallback) {\n            return $this->temporaryUploadUrlCallback->bindTo($this, static::class)(\n                $path, $expiration, $options\n            );\n        }\n\n        throw new RuntimeException('This driver does not support creating temporary upload URLs.');\n    }\n\n    /**\n     * Concatenate a path to a URL.\n     *\n     * @param  string  $url\n     * @param  string  $path\n     * @return string\n     */\n    protected function concatPathToUrl($url, $path)\n    {\n        return rtrim($url, '/').'/'.ltrim($path, '/');\n    }\n\n    /**\n     * Replace the scheme, host and port of the given UriInterface with values from the given URL.\n     *\n     * @param  \\Psr\\Http\\Message\\UriInterface  $uri\n     * @param  string  $url\n     * @return \\Psr\\Http\\Message\\UriInterface\n     */\n    protected function replaceBaseUrl($uri, $url)\n    {\n        $parsed = parse_url($url);\n\n        return $uri\n            ->withScheme($parsed['scheme'])\n            ->withHost($parsed['host'])\n            ->withPort($parsed['port'] ?? null);\n    }\n\n    /**\n     * Get an array of all files in a directory.\n     *\n     * @param  string|null  $directory\n     * @param  bool  $recursive\n     * @return array\n     */\n    public function files($directory = null, $recursive = false)\n    {\n        return $this->driver->listContents($directory ?? '', $recursive)\n            ->filter(function (StorageAttributes $attributes) {\n                return $attributes->isFile();\n            })\n            ->sortByPath()\n            ->map(function (StorageAttributes $attributes) {\n                return $attributes->path();\n            })\n            ->toArray();\n    }\n\n    /**\n     * Get all of the files from the given directory (recursive).\n     *\n     * @param  string|null  $directory\n     * @return array\n     */\n    public function allFiles($directory = null)\n    {\n        return $this->files($directory, true);\n    }\n\n    /**\n     * Get all of the directories within a given directory.\n     *\n     * @param  string|null  $directory\n     * @param  bool  $recursive\n     * @return array\n     */\n    public function directories($directory = null, $recursive = false)\n    {\n        return $this->driver->listContents($directory ?? '', $recursive)\n            ->filter(function (StorageAttributes $attributes) {\n                return $attributes->isDir();\n            })\n            ->map(function (StorageAttributes $attributes) {\n                return $attributes->path();\n            })\n            ->toArray();\n    }\n\n    /**\n     * Get all the directories within a given directory (recursive).\n     *\n     * @param  string|null  $directory\n     * @return array\n     */\n    public function allDirectories($directory = null)\n    {\n        return $this->directories($directory, true);\n    }\n\n    /**\n     * Create a directory.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function makeDirectory($path)\n    {\n        try {\n            $this->driver->createDirectory($path);\n        } catch (UnableToCreateDirectory|UnableToSetVisibility $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Recursively delete a directory.\n     *\n     * @param  string  $directory\n     * @return bool\n     */\n    public function deleteDirectory($directory)\n    {\n        try {\n            $this->driver->deleteDirectory($directory);\n        } catch (UnableToDeleteDirectory $e) {\n            throw_if($this->throwsExceptions(), $e);\n\n            $this->report($e);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the Flysystem driver.\n     *\n     * @return \\League\\Flysystem\\FilesystemOperator\n     */\n    public function getDriver()\n    {\n        return $this->driver;\n    }\n\n    /**\n     * Get the Flysystem adapter.\n     *\n     * @return \\League\\Flysystem\\FilesystemAdapter\n     */\n    public function getAdapter()\n    {\n        return $this->adapter;\n    }\n\n    /**\n     * Get the configuration values.\n     *\n     * @return array\n     */\n    public function getConfig()\n    {\n        return $this->config;\n    }\n\n    /**\n     * Parse the given visibility value.\n     *\n     * @param  string|null  $visibility\n     * @return string|null\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseVisibility($visibility)\n    {\n        if (is_null($visibility)) {\n            return;\n        }\n\n        return match ($visibility) {\n            FilesystemContract::VISIBILITY_PUBLIC => Visibility::PUBLIC,\n            FilesystemContract::VISIBILITY_PRIVATE => Visibility::PRIVATE,\n            default => throw new InvalidArgumentException(\"Unknown visibility: {$visibility}.\"),\n        };\n    }\n\n    /**\n     * Define a custom callback that generates file download responses.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function serveUsing(Closure $callback)\n    {\n        $this->serveCallback = $callback;\n    }\n\n    /**\n     * Define a custom temporary URL builder callback.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function buildTemporaryUrlsUsing(Closure $callback)\n    {\n        $this->temporaryUrlCallback = $callback;\n    }\n\n    /**\n     * Define a custom temporary upload URL builder callback.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function buildTemporaryUploadUrlsUsing(Closure $callback)\n    {\n        $this->temporaryUploadUrlCallback = $callback;\n    }\n\n    /**\n     * Determine if Flysystem exceptions should be thrown.\n     *\n     * @return bool\n     */\n    protected function throwsExceptions(): bool\n    {\n        return (bool) ($this->config['throw'] ?? false);\n    }\n\n    /**\n     * Report the exception.\n     *\n     * @param  \\Throwable  $exception\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function report($exception)\n    {\n        if ($this->shouldReport() && Container::getInstance()->bound(ExceptionHandler::class)) {\n            Container::getInstance()->make(ExceptionHandler::class)->report($exception);\n        }\n    }\n\n    /**\n     * Determine if Flysystem exceptions should be reported.\n     *\n     * @return bool\n     */\n    protected function shouldReport(): bool\n    {\n        return (bool) ($this->config['report'] ?? false);\n    }\n\n    /**\n     * Pass dynamic methods call onto Flysystem.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->driver->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/FilesystemManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Aws\\S3\\S3Client;\nuse Closure;\nuse Illuminate\\Contracts\\Filesystem\\Factory as FactoryContract;\nuse Illuminate\\Support\\Arr;\nuse InvalidArgumentException;\nuse League\\Flysystem\\AwsS3V3\\AwsS3V3Adapter as S3Adapter;\nuse League\\Flysystem\\AwsS3V3\\PortableVisibilityConverter as AwsS3PortableVisibilityConverter;\nuse League\\Flysystem\\Filesystem as Flysystem;\nuse League\\Flysystem\\FilesystemAdapter as FlysystemAdapter;\nuse League\\Flysystem\\Ftp\\FtpAdapter;\nuse League\\Flysystem\\Ftp\\FtpConnectionOptions;\nuse League\\Flysystem\\Local\\LocalFilesystemAdapter as LocalAdapter;\nuse League\\Flysystem\\PathPrefixing\\PathPrefixedAdapter;\nuse League\\Flysystem\\PhpseclibV3\\SftpAdapter;\nuse League\\Flysystem\\PhpseclibV3\\SftpConnectionProvider;\nuse League\\Flysystem\\ReadOnly\\ReadOnlyFilesystemAdapter;\nuse League\\Flysystem\\UnixVisibility\\PortableVisibilityConverter;\nuse League\\Flysystem\\Visibility;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Filesystem\\Filesystem\n * @mixin \\Illuminate\\Filesystem\\FilesystemAdapter\n */\nclass FilesystemManager implements FactoryContract\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of resolved filesystem drivers.\n     *\n     * @var array\n     */\n    protected $disks = [];\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * Create a new filesystem manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Get a filesystem instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function drive($name = null)\n    {\n        return $this->disk($name);\n    }\n\n    /**\n     * Get a filesystem instance.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function disk($name = null)\n    {\n        $name = enum_value($name) ?: $this->getDefaultDriver();\n\n        return $this->disks[$name] = $this->get($name);\n    }\n\n    /**\n     * Get a default cloud filesystem instance.\n     *\n     * @return \\Illuminate\\Contracts\\Filesystem\\Cloud\n     */\n    public function cloud()\n    {\n        $name = $this->getDefaultCloudDriver();\n\n        return $this->disks[$name] = $this->get($name);\n    }\n\n    /**\n     * Build an on-demand disk.\n     *\n     * @param  string|array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function build($config)\n    {\n        return $this->resolve('ondemand', is_array($config) ? $config : [\n            'driver' => 'local',\n            'root' => $config,\n        ]);\n    }\n\n    /**\n     * Attempt to get the disk from the local cache.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    protected function get($name)\n    {\n        return $this->disks[$name] ?? $this->resolve($name);\n    }\n\n    /**\n     * Resolve the given disk.\n     *\n     * @param  string  $name\n     * @param  array|null  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name, $config = null)\n    {\n        $config ??= $this->getConfig($name);\n\n        if (empty($config['driver'])) {\n            throw new InvalidArgumentException(\"Disk [{$name}] does not have a configured driver.\");\n        }\n\n        $driver = $config['driver'];\n\n        if (isset($this->customCreators[$driver])) {\n            return $this->callCustomCreator($config);\n        }\n\n        $driverMethod = 'create'.ucfirst($driver).'Driver';\n\n        if (! method_exists($this, $driverMethod)) {\n            throw new InvalidArgumentException(\"Driver [{$driver}] is not supported.\");\n        }\n\n        return $this->{$driverMethod}($config, $name);\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    protected function callCustomCreator(array $config)\n    {\n        return $this->customCreators[$config['driver']]($this->app, $config);\n    }\n\n    /**\n     * Create an instance of the local driver.\n     *\n     * @param  array  $config\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function createLocalDriver(array $config, string $name = 'local')\n    {\n        $visibility = PortableVisibilityConverter::fromArray(\n            $config['permissions'] ?? [],\n            $config['directory_visibility'] ?? $config['visibility'] ?? Visibility::PRIVATE\n        );\n\n        $links = ($config['links'] ?? null) === 'skip'\n            ? LocalAdapter::SKIP_LINKS\n            : LocalAdapter::DISALLOW_LINKS;\n\n        $adapter = new LocalAdapter(\n            $config['root'], $visibility, $config['lock'] ?? LOCK_EX, $links\n        );\n\n        return (new LocalFilesystemAdapter(\n            $this->createFlysystem($adapter, $config), $adapter, $config\n        ))->diskName(\n            $name\n        )->shouldServeSignedUrls(\n            $config['serve'] ?? false,\n            fn () => $this->app['url'],\n        );\n    }\n\n    /**\n     * Create an instance of the ftp driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function createFtpDriver(array $config)\n    {\n        if (! isset($config['root'])) {\n            $config['root'] = '';\n        }\n\n        $adapter = new FtpAdapter(FtpConnectionOptions::fromArray($config));\n\n        return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config);\n    }\n\n    /**\n     * Create an instance of the sftp driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public function createSftpDriver(array $config)\n    {\n        $provider = SftpConnectionProvider::fromArray($config);\n\n        $root = $config['root'] ?? '';\n\n        $visibility = PortableVisibilityConverter::fromArray(\n            $config['permissions'] ?? []\n        );\n\n        $adapter = new SftpAdapter($provider, $root, $visibility);\n\n        return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config);\n    }\n\n    /**\n     * Create an instance of the Amazon S3 driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Cloud\n     */\n    public function createS3Driver(array $config)\n    {\n        $s3Config = $this->formatS3Config($config);\n\n        $root = (string) ($s3Config['root'] ?? '');\n\n        $visibility = new AwsS3PortableVisibilityConverter(\n            $config['visibility'] ?? Visibility::PUBLIC\n        );\n\n        $streamReads = $s3Config['stream_reads'] ?? false;\n\n        $client = new S3Client($s3Config);\n\n        $adapter = new S3Adapter($client, $s3Config['bucket'], $root, $visibility, null, $config['options'] ?? [], $streamReads);\n\n        return new AwsS3V3Adapter(\n            $this->createFlysystem($adapter, $config), $adapter, $s3Config, $client\n        );\n    }\n\n    /**\n     * Format the given S3 configuration with the default options.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function formatS3Config(array $config)\n    {\n        $config += ['version' => 'latest'];\n\n        if (! empty($config['key']) && ! empty($config['secret'])) {\n            $config['credentials'] = Arr::only($config, ['key', 'secret']);\n\n            if (! empty($config['token'])) {\n                $config['credentials']['token'] = $config['token'];\n            }\n        }\n\n        return Arr::except($config, ['token']);\n    }\n\n    /**\n     * Create a scoped driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function createScopedDriver(array $config)\n    {\n        if (empty($config['disk'])) {\n            throw new InvalidArgumentException('Scoped disk is missing \"disk\" configuration option.');\n        } elseif (empty($config['prefix'])) {\n            throw new InvalidArgumentException('Scoped disk is missing \"prefix\" configuration option.');\n        }\n\n        return $this->build(tap(\n            is_string($config['disk']) ? $this->getConfig($config['disk']) : $config['disk'],\n            function (&$parent) use ($config) {\n                if (empty($parent['prefix'])) {\n                    $parent['prefix'] = $config['prefix'];\n                } else {\n                    $separator = $parent['directory_separator'] ?? DIRECTORY_SEPARATOR;\n\n                    $parentPrefix = rtrim($parent['prefix'], $separator);\n                    $scopedPrefix = ltrim($config['prefix'], $separator);\n\n                    $parent['prefix'] = \"{$parentPrefix}{$separator}{$scopedPrefix}\";\n                }\n\n                if (isset($config['visibility'])) {\n                    $parent['visibility'] = $config['visibility'];\n                }\n\n                if (isset($config['throw'])) {\n                    $parent['throw'] = $config['throw'];\n                }\n            }\n        ));\n    }\n\n    /**\n     * Create a Flysystem instance with the given adapter.\n     *\n     * @param  \\League\\Flysystem\\FilesystemAdapter  $adapter\n     * @param  array  $config\n     * @return \\League\\Flysystem\\FilesystemOperator\n     */\n    protected function createFlysystem(FlysystemAdapter $adapter, array $config)\n    {\n        if ($config['read-only'] ?? false) {\n            $adapter = new ReadOnlyFilesystemAdapter($adapter);\n        }\n\n        if (! empty($config['prefix'])) {\n            $adapter = new PathPrefixedAdapter($adapter, $config['prefix']);\n        }\n\n        if (str_contains($config['endpoint'] ?? '', 'r2.cloudflarestorage.com')) {\n            $config['retain_visibility'] = false;\n        }\n\n        return new Flysystem($adapter, Arr::only($config, [\n            'directory_visibility',\n            'disable_asserts',\n            'retain_visibility',\n            'temporary_url',\n            'url',\n            'visibility',\n        ]));\n    }\n\n    /**\n     * Set the given disk instance.\n     *\n     * @param  string  $name\n     * @param  mixed  $disk\n     * @return $this\n     */\n    public function set($name, $disk)\n    {\n        $this->disks[$name] = $disk;\n\n        return $this;\n    }\n\n    /**\n     * Get the filesystem connection configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function getConfig($name)\n    {\n        return $this->app['config'][\"filesystems.disks.{$name}\"] ?: [];\n    }\n\n    /**\n     * Get the default driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['filesystems.default'];\n    }\n\n    /**\n     * Get the default cloud driver name.\n     *\n     * @return string\n     */\n    public function getDefaultCloudDriver()\n    {\n        return $this->app['config']['filesystems.cloud'] ?? 's3';\n    }\n\n    /**\n     * Unset the given disk instances.\n     *\n     * @param  array|string  $disk\n     * @return $this\n     */\n    public function forgetDisk($disk)\n    {\n        foreach ((array) $disk as $diskName) {\n            unset($this->disks[$diskName]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Disconnect the given disk and remove from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name ??= $this->getDefaultDriver();\n\n        unset($this->disks[$name]);\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->disk()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/FilesystemServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Illuminate\\Contracts\\Foundation\\CachesRoutes;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\ServiceProvider;\nuse InvalidArgumentException;\n\nclass FilesystemServiceProvider extends ServiceProvider\n{\n    /**\n     * Bootstrap the filesystem.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        $this->serveFiles();\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerNativeFilesystem();\n        $this->registerFlysystem();\n    }\n\n    /**\n     * Register the native filesystem implementation.\n     *\n     * @return void\n     */\n    protected function registerNativeFilesystem()\n    {\n        $this->app->singleton('files', function () {\n            return new Filesystem;\n        });\n    }\n\n    /**\n     * Register the driver based filesystem.\n     *\n     * @return void\n     */\n    protected function registerFlysystem()\n    {\n        $this->registerManager();\n\n        $this->app->singleton('filesystem.disk', function ($app) {\n            return $app['filesystem']->disk($this->getDefaultDriver());\n        });\n\n        $this->app->singleton('filesystem.cloud', function ($app) {\n            return $app['filesystem']->disk($this->getCloudDriver());\n        });\n    }\n\n    /**\n     * Register the filesystem manager.\n     *\n     * @return void\n     */\n    protected function registerManager()\n    {\n        $this->app->singleton('filesystem', function ($app) {\n            return new FilesystemManager($app);\n        });\n    }\n\n    /**\n     * Register protected file serving.\n     *\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function serveFiles()\n    {\n        if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) {\n            return;\n        }\n\n        $served = [];\n\n        foreach ($this->app['config']['filesystems.disks'] ?? [] as $disk => $config) {\n            if (! $this->shouldServeFiles($config)) {\n                continue;\n            }\n\n            $this->app->booted(function ($app) use ($disk, $config, &$served) {\n                $uri = isset($config['url'])\n                    ? rtrim(parse_url($config['url'])['path'], '/')\n                    : '/storage';\n\n                if (isset($served[$uri])) {\n                    throw new InvalidArgumentException(\n                        \"The [{$disk}] disk conflicts with the [{$served[$uri]}] disk at [{$uri}]. Each served disk must have a unique URL.\"\n                    );\n                }\n\n                $served[$uri] = $disk;\n\n                $isProduction = $app->isProduction();\n\n                Route::get($uri.'/{path}', function (Request $request, string $path) use ($disk, $config, $isProduction) {\n                    return (new ServeFile(\n                        $disk,\n                        $config,\n                        $isProduction\n                    ))($request, $path);\n                })->where('path', '.*')->name('storage.'.$disk);\n\n                Route::put($uri.'/{path}', function (Request $request, string $path) use ($disk, $config, $isProduction) {\n                    return (new ReceiveFile(\n                        $disk,\n                        $config,\n                        $isProduction\n                    ))($request, $path);\n                })->where('path', '.*')->name('storage.'.$disk.'.upload');\n            });\n        }\n    }\n\n    /**\n     * Determine if the disk is serveable.\n     *\n     * @param  array  $config\n     * @return bool\n     */\n    protected function shouldServeFiles(array $config)\n    {\n        return $config['driver'] === 'local' && ($config['serve'] ?? false);\n    }\n\n    /**\n     * Get the default file driver.\n     *\n     * @return string\n     */\n    protected function getDefaultDriver()\n    {\n        return $this->app['config']['filesystems.default'];\n    }\n\n    /**\n     * Get the default cloud based file driver.\n     *\n     * @return string\n     */\n    protected function getCloudDriver()\n    {\n        return $this->app['config']['filesystems.cloud'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Filesystem/LocalFilesystemAdapter.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Closure;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse RuntimeException;\n\nclass LocalFilesystemAdapter extends FilesystemAdapter\n{\n    use Conditionable;\n\n    /**\n     * The name of the filesystem disk.\n     *\n     * @var string\n     */\n    protected $disk;\n\n    /**\n     * Indicates if signed URLs should serve corresponding files.\n     *\n     * @var bool\n     */\n    protected $shouldServeSignedUrls = false;\n\n    /**\n     * The Closure that should be used to resolve the URL generator.\n     *\n     * @var \\Closure\n     */\n    protected $urlGeneratorResolver;\n\n    /**\n     * Determine if temporary URLs can be generated.\n     *\n     * @return bool\n     */\n    public function providesTemporaryUrls()\n    {\n        return $this->temporaryUrlCallback || (\n            $this->shouldServeSignedUrls && $this->urlGeneratorResolver instanceof Closure\n        );\n    }\n\n    /**\n     * Determine if temporary upload URLs can be generated.\n     *\n     * @return bool\n     */\n    public function providesTemporaryUploadUrls()\n    {\n        return $this->temporaryUploadUrlCallback || (\n            $this->shouldServeSignedUrls && $this->urlGeneratorResolver instanceof Closure\n        );\n    }\n\n    /**\n     * Get a temporary URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function temporaryUrl($path, $expiration, array $options = [])\n    {\n        if ($this->temporaryUrlCallback) {\n            return $this->temporaryUrlCallback->bindTo($this, static::class)(\n                $path, $expiration, $options\n            );\n        }\n\n        if (! $this->providesTemporaryUrls()) {\n            throw new RuntimeException('This driver does not support creating temporary URLs.');\n        }\n\n        $url = call_user_func($this->urlGeneratorResolver);\n\n        return $url->to($url->temporarySignedRoute(\n            'storage.'.$this->disk,\n            $expiration,\n            ['path' => $path],\n            absolute: false\n        ));\n    }\n\n    /**\n     * Get a temporary upload URL for the file at the given path.\n     *\n     * @param  string  $path\n     * @param  \\DateTimeInterface  $expiration\n     * @param  array  $options\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    public function temporaryUploadUrl($path, $expiration, array $options = [])\n    {\n        if ($this->temporaryUploadUrlCallback) {\n            return $this->temporaryUploadUrlCallback->bindTo($this, static::class)(\n                $path, $expiration, $options\n            );\n        }\n\n        if (! $this->providesTemporaryUploadUrls()) {\n            throw new RuntimeException('This driver does not support creating temporary upload URLs.');\n        }\n\n        $url = call_user_func($this->urlGeneratorResolver);\n\n        return [\n            'url' => $url->to($url->temporarySignedRoute(\n                'storage.'.$this->disk.'.upload',\n                $expiration,\n                ['path' => $path, 'upload' => true],\n                absolute: false\n            )),\n            'headers' => [],\n        ];\n    }\n\n    /**\n     * Specify the name of the disk the adapter is managing.\n     *\n     * @param  string  $disk\n     * @return $this\n     */\n    public function diskName(string $disk)\n    {\n        $this->disk = $disk;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that signed URLs should serve the corresponding files.\n     *\n     * @param  bool  $serve\n     * @param  \\Closure|null  $urlGeneratorResolver\n     * @return $this\n     */\n    public function shouldServeSignedUrls(bool $serve = true, ?Closure $urlGeneratorResolver = null)\n    {\n        $this->shouldServeSignedUrls = $serve;\n        $this->urlGeneratorResolver = $urlGeneratorResolver;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/LockableFile.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Illuminate\\Contracts\\Filesystem\\LockTimeoutException;\n\nclass LockableFile\n{\n    /**\n     * The file resource.\n     *\n     * @var resource\n     */\n    protected $handle;\n\n    /**\n     * The file path.\n     *\n     * @var string\n     */\n    protected $path;\n\n    /**\n     * Indicates if the file is locked.\n     *\n     * @var bool\n     */\n    protected $isLocked = false;\n\n    /**\n     * Create a new File instance.\n     *\n     * @param  string  $path\n     * @param  string  $mode\n     */\n    public function __construct($path, $mode)\n    {\n        $this->path = $path;\n\n        $this->ensureDirectoryExists($path);\n        $this->createResource($path, $mode);\n    }\n\n    /**\n     * Create the file's directory if necessary.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function ensureDirectoryExists($path)\n    {\n        if (! file_exists(dirname($path))) {\n            @mkdir(dirname($path), 0777, true);\n        }\n    }\n\n    /**\n     * Create the file resource.\n     *\n     * @param  string  $path\n     * @param  string  $mode\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    protected function createResource($path, $mode)\n    {\n        $this->handle = fopen($path, $mode);\n    }\n\n    /**\n     * Read the file contents.\n     *\n     * @param  int|null  $length\n     * @return string\n     */\n    public function read($length = null)\n    {\n        clearstatcache(true, $this->path);\n\n        return fread($this->handle, $length ?? ($this->size() ?: 1));\n    }\n\n    /**\n     * Get the file size.\n     *\n     * @return int\n     */\n    public function size()\n    {\n        return filesize($this->path);\n    }\n\n    /**\n     * Write to the file.\n     *\n     * @param  string  $contents\n     * @return $this\n     */\n    public function write($contents)\n    {\n        fwrite($this->handle, $contents);\n\n        fflush($this->handle);\n\n        return $this;\n    }\n\n    /**\n     * Truncate the file.\n     *\n     * @return $this\n     */\n    public function truncate()\n    {\n        rewind($this->handle);\n\n        ftruncate($this->handle, 0);\n\n        return $this;\n    }\n\n    /**\n     * Get a shared lock on the file.\n     *\n     * @param  bool  $block\n     * @return $this\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\LockTimeoutException\n     */\n    public function getSharedLock($block = false)\n    {\n        if (! flock($this->handle, LOCK_SH | ($block ? 0 : LOCK_NB))) {\n            throw new LockTimeoutException(\"Unable to acquire file lock at path [{$this->path}].\");\n        }\n\n        $this->isLocked = true;\n\n        return $this;\n    }\n\n    /**\n     * Get an exclusive lock on the file.\n     *\n     * @param  bool  $block\n     * @return $this\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\LockTimeoutException\n     */\n    public function getExclusiveLock($block = false)\n    {\n        if (! flock($this->handle, LOCK_EX | ($block ? 0 : LOCK_NB))) {\n            throw new LockTimeoutException(\"Unable to acquire file lock at path [{$this->path}].\");\n        }\n\n        $this->isLocked = true;\n\n        return $this;\n    }\n\n    /**\n     * Release the lock on the file.\n     *\n     * @return $this\n     */\n    public function releaseLock()\n    {\n        flock($this->handle, LOCK_UN);\n\n        $this->isLocked = false;\n\n        return $this;\n    }\n\n    /**\n     * Close the file.\n     *\n     * @return bool\n     */\n    public function close()\n    {\n        if ($this->isLocked) {\n            $this->releaseLock();\n        }\n\n        return fclose($this->handle);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/ReceiveFile.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\PathTraversalDetected;\n\nclass ReceiveFile\n{\n    /**\n     * Create a new invokable controller to receive files.\n     */\n    public function __construct(\n        protected string $disk,\n        protected array $config,\n        protected bool $isProduction,\n    ) {\n        //\n    }\n\n    /**\n     * Handle the incoming request.\n     */\n    public function __invoke(Request $request, string $path): Response\n    {\n        abort_unless(\n            $this->hasValidSignature($request),\n            $this->isProduction ? 404 : 403\n        );\n\n        try {\n            Storage::disk($this->disk)->put($path, $request->getContent());\n\n            return response()->noContent();\n        } catch (PathTraversalDetected $e) {\n            abort(404);\n        }\n    }\n\n    /**\n     * Determine if the request has a valid signature if applicable.\n     */\n    protected function hasValidSignature(Request $request): bool\n    {\n        return $request->boolean('upload') && $request->hasValidRelativeSignature();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/ServeFile.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\PathTraversalDetected;\n\nclass ServeFile\n{\n    /**\n     * Create a new invokable controller to serve files.\n     */\n    public function __construct(\n        protected string $disk,\n        protected array $config,\n        protected bool $isProduction,\n    ) {\n        //\n    }\n\n    /**\n     * Handle the incoming request.\n     */\n    public function __invoke(Request $request, string $path)\n    {\n        abort_unless(\n            $this->hasValidSignature($request),\n            $this->isProduction ? 404 : 403\n        );\n        try {\n            abort_unless(Storage::disk($this->disk)->exists($path), 404);\n\n            $headers = [\n                'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',\n                'Content-Security-Policy' => \"default-src 'none'; style-src 'unsafe-inline'; sandbox\",\n            ];\n\n            return tap(\n                Storage::disk($this->disk)->serve($request, $path, headers: $headers),\n                function ($response) use ($headers) {\n                    if (! $response->headers->has('Content-Security-Policy')) {\n                        $response->headers->replace($headers);\n                    }\n                }\n            );\n        } catch (PathTraversalDetected $e) {\n            abort(404);\n        }\n    }\n\n    /**\n     * Determine if the request has a valid signature if applicable.\n     */\n    protected function hasValidSignature(Request $request): bool\n    {\n        return ! $request->boolean('upload') && (\n            ($this->config['visibility'] ?? 'private') === 'public' ||\n            $request->hasValidRelativeSignature()\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/composer.json",
    "content": "{\n    \"name\": \"illuminate/filesystem\",\n    \"description\": \"The Illuminate Filesystem package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/finder\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"suggest\": {\n        \"ext-fileinfo\": \"Required to use the Filesystem class.\",\n        \"ext-ftp\": \"Required to use the Flysystem FTP driver.\",\n        \"ext-hash\": \"Required to use the Filesystem class.\",\n        \"illuminate/http\": \"Required for handling uploaded files (^13.0).\",\n        \"league/flysystem\": \"Required to use the Flysystem local driver (^3.25.1).\",\n        \"league/flysystem-aws-s3-v3\": \"Required to use the Flysystem S3 driver (^3.25.1).\",\n        \"league/flysystem-ftp\": \"Required to use the Flysystem FTP driver (^3.25.1).\",\n        \"league/flysystem-sftp-v3\": \"Required to use the Flysystem SFTP driver (^3.25.1).\",\n        \"psr/http-message\": \"Required to allow Storage::put to accept a StreamInterface (^1.0).\",\n        \"symfony/filesystem\": \"Required to enable support for relative symbolic links (^7.4 || ^8.0).\",\n        \"symfony/mime\": \"Required to enable support for guessing extensions (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Filesystem\\\\\": \"\"\n        },\n        \"files\": [\n            \"functions.php\"\n        ]\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Filesystem/functions.php",
    "content": "<?php\n\nnamespace Illuminate\\Filesystem;\n\nif (! function_exists('Illuminate\\Filesystem\\join_paths')) {\n    /**\n     * Join the given paths together.\n     *\n     * @param  string|null  $basePath\n     * @param  string  ...$paths\n     */\n    function join_paths($basePath, ...$paths): string\n    {\n        foreach ($paths as $index => $path) {\n            if (empty($path) && $path !== '0') {\n                unset($paths[$index]);\n            } else {\n                $paths[$index] = DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR);\n            }\n        }\n\n        return $basePath.implode('', $paths);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/AliasLoader.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nclass AliasLoader\n{\n    /**\n     * The array of class aliases.\n     *\n     * @var array\n     */\n    protected $aliases;\n\n    /**\n     * Indicates if a loader has been registered.\n     *\n     * @var bool\n     */\n    protected $registered = false;\n\n    /**\n     * The namespace for all real-time facades.\n     *\n     * @var string\n     */\n    protected static $facadeNamespace = 'Facades\\\\';\n\n    /**\n     * The singleton instance of the loader.\n     *\n     * @var \\Illuminate\\Foundation\\AliasLoader\n     */\n    protected static $instance;\n\n    /**\n     * Create a new AliasLoader instance.\n     *\n     * @param  array  $aliases\n     */\n    private function __construct($aliases)\n    {\n        $this->aliases = $aliases;\n    }\n\n    /**\n     * Get or create the singleton alias loader instance.\n     *\n     * @param  array  $aliases\n     * @return \\Illuminate\\Foundation\\AliasLoader\n     */\n    public static function getInstance(array $aliases = [])\n    {\n        if (is_null(static::$instance)) {\n            return static::$instance = new static($aliases);\n        }\n\n        $aliases = array_merge(static::$instance->getAliases(), $aliases);\n\n        static::$instance->setAliases($aliases);\n\n        return static::$instance;\n    }\n\n    /**\n     * Load a class alias if it is registered.\n     *\n     * @param  string  $alias\n     * @return bool|null\n     */\n    public function load($alias)\n    {\n        if (static::$facadeNamespace && str_starts_with($alias, static::$facadeNamespace)) {\n            $this->loadFacade($alias);\n\n            return true;\n        }\n\n        if (isset($this->aliases[$alias])) {\n            return class_alias($this->aliases[$alias], $alias);\n        }\n    }\n\n    /**\n     * Load a real-time facade for the given alias.\n     *\n     * @param  string  $alias\n     * @return void\n     */\n    protected function loadFacade($alias)\n    {\n        require $this->ensureFacadeExists($alias);\n    }\n\n    /**\n     * Ensure that the given alias has an existing real-time facade class.\n     *\n     * @param  string  $alias\n     * @return string\n     */\n    protected function ensureFacadeExists($alias)\n    {\n        if (is_file($path = storage_path('framework/cache/facade-'.sha1($alias).'.php'))) {\n            return $path;\n        }\n\n        $stub = $this->formatFacadeStub(\n            $alias, file_get_contents(__DIR__.'/stubs/facade.stub')\n        );\n\n        // Atomic write to prevent race conditions...\n        $tempPath = tempnam(dirname($path), 'facade-');\n\n        // Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...\n        @chmod($tempPath, 0777 - umask());\n\n        file_put_contents($tempPath, $stub);\n\n        rename($tempPath, $path);\n\n        return $path;\n    }\n\n    /**\n     * Format the facade stub with the proper namespace and class.\n     *\n     * @param  string  $alias\n     * @param  string  $stub\n     * @return string\n     */\n    protected function formatFacadeStub($alias, $stub)\n    {\n        $replacements = [\n            str_replace('/', '\\\\', dirname(str_replace('\\\\', '/', $alias))),\n            class_basename($alias),\n            substr($alias, strlen(static::$facadeNamespace)),\n        ];\n\n        return str_replace(\n            ['DummyNamespace', 'DummyClass', 'DummyTarget'], $replacements, $stub\n        );\n    }\n\n    /**\n     * Add an alias to the loader.\n     *\n     * @param  string  $alias\n     * @param  string  $class\n     * @return void\n     */\n    public function alias($alias, $class)\n    {\n        $this->aliases[$alias] = $class;\n    }\n\n    /**\n     * Register the loader on the auto-loader stack.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        if (! $this->registered) {\n            $this->prependToLoaderStack();\n\n            $this->registered = true;\n        }\n    }\n\n    /**\n     * Prepend the load method to the auto-loader stack.\n     *\n     * @return void\n     */\n    protected function prependToLoaderStack()\n    {\n        spl_autoload_register($this->load(...), true, true);\n    }\n\n    /**\n     * Get the registered aliases.\n     *\n     * @return array\n     */\n    public function getAliases()\n    {\n        return $this->aliases;\n    }\n\n    /**\n     * Set the registered aliases.\n     *\n     * @param  array  $aliases\n     * @return void\n     */\n    public function setAliases(array $aliases)\n    {\n        $this->aliases = $aliases;\n    }\n\n    /**\n     * Indicates if the loader has been registered.\n     *\n     * @return bool\n     */\n    public function isRegistered()\n    {\n        return $this->registered;\n    }\n\n    /**\n     * Set the \"registered\" state of the loader.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public function setRegistered($value)\n    {\n        $this->registered = $value;\n    }\n\n    /**\n     * Set the real-time facade namespace.\n     *\n     * @param  string  $namespace\n     * @return void\n     */\n    public static function setFacadeNamespace($namespace)\n    {\n        static::$facadeNamespace = rtrim($namespace, '\\\\').'\\\\';\n    }\n\n    /**\n     * Set the value of the singleton alias loader.\n     *\n     * @param  \\Illuminate\\Foundation\\AliasLoader  $loader\n     * @return void\n     */\n    public static function setInstance($loader)\n    {\n        static::$instance = $loader;\n    }\n\n    /**\n     * Clone method.\n     *\n     * @return void\n     */\n    private function __clone()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Application.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Closure;\nuse Composer\\Autoload\\ClassLoader;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\nuse Illuminate\\Contracts\\Foundation\\Application as ApplicationContract;\nuse Illuminate\\Contracts\\Foundation\\CachesConfiguration;\nuse Illuminate\\Contracts\\Foundation\\CachesRoutes;\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode as MaintenanceModeContract;\nuse Illuminate\\Contracts\\Http\\Kernel as HttpKernelContract;\nuse Illuminate\\Events\\EventServiceProvider;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables;\nuse Illuminate\\Foundation\\Events\\LocaleUpdated;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Log\\Context\\ContextServiceProvider;\nuse Illuminate\\Log\\LogServiceProvider;\nuse Illuminate\\Routing\\RoutingServiceProvider;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Symfony\\Component\\HttpKernel\\HttpKernelInterface;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\nclass Application extends Container implements ApplicationContract, CachesConfiguration, CachesRoutes, HttpKernelInterface\n{\n    use Macroable;\n\n    /**\n     * The Laravel framework version.\n     *\n     * @var string\n     */\n    const VERSION = '13.1.1';\n\n    /**\n     * The base path for the Laravel installation.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * The array of registered callbacks.\n     *\n     * @var callable[]\n     */\n    protected $registeredCallbacks = [];\n\n    /**\n     * Indicates if the application has been bootstrapped before.\n     *\n     * @var bool\n     */\n    protected $hasBeenBootstrapped = false;\n\n    /**\n     * Indicates if the application has \"booted\".\n     *\n     * @var bool\n     */\n    protected $booted = false;\n\n    /**\n     * The array of booting callbacks.\n     *\n     * @var callable[]\n     */\n    protected $bootingCallbacks = [];\n\n    /**\n     * The array of booted callbacks.\n     *\n     * @var callable[]\n     */\n    protected $bootedCallbacks = [];\n\n    /**\n     * The array of terminating callbacks.\n     *\n     * @var callable[]\n     */\n    protected $terminatingCallbacks = [];\n\n    /**\n     * All of the registered service providers.\n     *\n     * @var array<string, \\Illuminate\\Support\\ServiceProvider>\n     */\n    protected $serviceProviders = [];\n\n    /**\n     * The names of the loaded service providers.\n     *\n     * @var array\n     */\n    protected $loadedProviders = [];\n\n    /**\n     * The deferred services and their providers.\n     *\n     * @var array\n     */\n    protected $deferredServices = [];\n\n    /**\n     * The custom bootstrap path defined by the developer.\n     *\n     * @var string\n     */\n    protected $bootstrapPath;\n\n    /**\n     * The custom application path defined by the developer.\n     *\n     * @var string\n     */\n    protected $appPath;\n\n    /**\n     * The custom configuration path defined by the developer.\n     *\n     * @var string\n     */\n    protected $configPath;\n\n    /**\n     * The custom database path defined by the developer.\n     *\n     * @var string\n     */\n    protected $databasePath;\n\n    /**\n     * The custom language file path defined by the developer.\n     *\n     * @var string\n     */\n    protected $langPath;\n\n    /**\n     * The custom public / web path defined by the developer.\n     *\n     * @var string\n     */\n    protected $publicPath;\n\n    /**\n     * The custom storage path defined by the developer.\n     *\n     * @var string\n     */\n    protected $storagePath;\n\n    /**\n     * The custom environment path defined by the developer.\n     *\n     * @var string\n     */\n    protected $environmentPath;\n\n    /**\n     * The environment file to load during bootstrapping.\n     *\n     * @var string\n     */\n    protected $environmentFile = '.env';\n\n    /**\n     * Indicates if the application is running in the console.\n     *\n     * @var bool|null\n     */\n    protected $isRunningInConsole;\n\n    /**\n     * The application namespace.\n     *\n     * @var string\n     */\n    protected $namespace;\n\n    /**\n     * Indicates if the framework's base configuration should be merged.\n     *\n     * @var bool\n     */\n    protected $mergeFrameworkConfiguration = true;\n\n    /**\n     * The prefixes of absolute cache paths for use during normalization.\n     *\n     * @var string[]\n     */\n    protected $absoluteCachePathPrefixes = ['/', '\\\\'];\n\n    /**\n     * Create a new Illuminate application instance.\n     *\n     * @param  string|null  $basePath\n     */\n    public function __construct($basePath = null)\n    {\n        if ($basePath) {\n            $this->setBasePath($basePath);\n        }\n\n        $this->registerBaseBindings();\n        $this->registerBaseServiceProviders();\n        $this->registerCoreContainerAliases();\n        $this->registerLaravelCloudServices();\n    }\n\n    /**\n     * Begin configuring a new Laravel application instance.\n     *\n     * @param  string|null  $basePath\n     * @return \\Illuminate\\Foundation\\Configuration\\ApplicationBuilder\n     */\n    public static function configure(?string $basePath = null)\n    {\n        $basePath = match (true) {\n            is_string($basePath) => $basePath,\n            default => static::inferBasePath(),\n        };\n\n        return (new Configuration\\ApplicationBuilder(new static($basePath)))\n            ->withKernels()\n            ->withEvents()\n            ->withCommands()\n            ->withProviders();\n    }\n\n    /**\n     * Infer the application's base directory from the environment.\n     *\n     * @return string\n     */\n    public static function inferBasePath()\n    {\n        return match (true) {\n            isset($_ENV['APP_BASE_PATH']) => $_ENV['APP_BASE_PATH'],\n            isset($_SERVER['APP_BASE_PATH']) => $_SERVER['APP_BASE_PATH'],\n            default => dirname(array_values(array_filter(\n                array_keys(ClassLoader::getRegisteredLoaders()),\n                fn ($path) => ! str_starts_with($path, 'phar://'),\n            ))[0]),\n        };\n    }\n\n    /**\n     * Get the version number of the application.\n     *\n     * @return string\n     */\n    public function version()\n    {\n        return static::VERSION;\n    }\n\n    /**\n     * Register the basic bindings into the container.\n     *\n     * @return void\n     */\n    protected function registerBaseBindings()\n    {\n        static::setInstance($this);\n\n        $this->instance('app', $this);\n\n        $this->instance(Container::class, $this);\n        $this->singleton(Mix::class);\n\n        $this->singleton(PackageManifest::class, fn () => new PackageManifest(\n            new Filesystem, $this->basePath(), $this->getCachedPackagesPath()\n        ));\n    }\n\n    /**\n     * Register all of the base service providers.\n     *\n     * @return void\n     */\n    protected function registerBaseServiceProviders()\n    {\n        $this->register(new EventServiceProvider($this));\n        $this->register(new LogServiceProvider($this));\n        $this->register(new ContextServiceProvider($this));\n        $this->register(new RoutingServiceProvider($this));\n    }\n\n    /**\n     * Register any services needed for Laravel Cloud.\n     *\n     * @return void\n     */\n    protected function registerLaravelCloudServices()\n    {\n        if (! laravel_cloud()) {\n            return;\n        }\n\n        $this['events']->listen(\n            'bootstrapping: *',\n            fn ($bootstrapper) => Cloud::bootstrapperBootstrapping($this, Str::after($bootstrapper, 'bootstrapping: '))\n        );\n\n        $this['events']->listen(\n            'bootstrapped: *',\n            fn ($bootstrapper) => Cloud::bootstrapperBootstrapped($this, Str::after($bootstrapper, 'bootstrapped: '))\n        );\n    }\n\n    /**\n     * Run the given array of bootstrap classes.\n     *\n     * @param  string[]  $bootstrappers\n     * @return void\n     */\n    public function bootstrapWith(array $bootstrappers)\n    {\n        $this->hasBeenBootstrapped = true;\n\n        foreach ($bootstrappers as $bootstrapper) {\n            $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);\n\n            $this->make($bootstrapper)->bootstrap($this);\n\n            $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);\n        }\n    }\n\n    /**\n     * Register a callback to run after loading the environment.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function afterLoadingEnvironment(Closure $callback)\n    {\n        $this->afterBootstrapping(\n            LoadEnvironmentVariables::class, $callback\n        );\n    }\n\n    /**\n     * Register a callback to run before a bootstrapper.\n     *\n     * @param  string  $bootstrapper\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function beforeBootstrapping($bootstrapper, Closure $callback)\n    {\n        $this['events']->listen('bootstrapping: '.$bootstrapper, $callback);\n    }\n\n    /**\n     * Register a callback to run after a bootstrapper.\n     *\n     * @param  string  $bootstrapper\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function afterBootstrapping($bootstrapper, Closure $callback)\n    {\n        $this['events']->listen('bootstrapped: '.$bootstrapper, $callback);\n    }\n\n    /**\n     * Determine if the application has been bootstrapped before.\n     *\n     * @return bool\n     */\n    public function hasBeenBootstrapped()\n    {\n        return $this->hasBeenBootstrapped;\n    }\n\n    /**\n     * Set the base path for the application.\n     *\n     * @param  string  $basePath\n     * @return $this\n     */\n    public function setBasePath($basePath)\n    {\n        $this->basePath = rtrim($basePath, '\\/');\n\n        $this->bindPathsInContainer();\n\n        return $this;\n    }\n\n    /**\n     * Bind all of the application paths in the container.\n     *\n     * @return void\n     */\n    protected function bindPathsInContainer()\n    {\n        $this->instance('path', $this->path());\n        $this->instance('path.base', $this->basePath());\n        $this->instance('path.config', $this->configPath());\n        $this->instance('path.database', $this->databasePath());\n        $this->instance('path.public', $this->publicPath());\n        $this->instance('path.resources', $this->resourcePath());\n        $this->instance('path.storage', $this->storagePath());\n\n        $this->useBootstrapPath(value(function () {\n            return is_dir($directory = $this->basePath('.laravel'))\n                ? $directory\n                : $this->basePath('bootstrap');\n        }));\n\n        $this->useLangPath(value(function () {\n            return is_dir($directory = $this->resourcePath('lang'))\n                ? $directory\n                : $this->basePath('lang');\n        }));\n    }\n\n    /**\n     * Get the path to the application \"app\" directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function path($path = '')\n    {\n        return $this->joinPaths($this->appPath ?: $this->basePath('app'), $path);\n    }\n\n    /**\n     * Set the application directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useAppPath($path)\n    {\n        $this->appPath = $path;\n\n        $this->instance('path', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the base path of the Laravel installation.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function basePath($path = '')\n    {\n        return $this->joinPaths($this->basePath, $path);\n    }\n\n    /**\n     * Get the path to the bootstrap directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function bootstrapPath($path = '')\n    {\n        return $this->joinPaths($this->bootstrapPath, $path);\n    }\n\n    /**\n     * Get the path to the service provider list in the bootstrap directory.\n     *\n     * @return string\n     */\n    public function getBootstrapProvidersPath()\n    {\n        return $this->bootstrapPath('providers.php');\n    }\n\n    /**\n     * Set the bootstrap file directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useBootstrapPath($path)\n    {\n        $this->bootstrapPath = $path;\n\n        $this->instance('path.bootstrap', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the application configuration files.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function configPath($path = '')\n    {\n        return $this->joinPaths($this->configPath ?: $this->basePath('config'), $path);\n    }\n\n    /**\n     * Set the configuration directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useConfigPath($path)\n    {\n        $this->configPath = $path;\n\n        $this->instance('path.config', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the database directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function databasePath($path = '')\n    {\n        return $this->joinPaths($this->databasePath ?: $this->basePath('database'), $path);\n    }\n\n    /**\n     * Set the database directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useDatabasePath($path)\n    {\n        $this->databasePath = $path;\n\n        $this->instance('path.database', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the language files.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function langPath($path = '')\n    {\n        return $this->joinPaths($this->langPath, $path);\n    }\n\n    /**\n     * Set the language file directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useLangPath($path)\n    {\n        $this->langPath = $path;\n\n        $this->instance('path.lang', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the public / web directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function publicPath($path = '')\n    {\n        return $this->joinPaths($this->publicPath ?: $this->basePath('public'), $path);\n    }\n\n    /**\n     * Set the public / web directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function usePublicPath($path)\n    {\n        $this->publicPath = $path;\n\n        $this->instance('path.public', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the storage directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function storagePath($path = '')\n    {\n        if (isset($_ENV['LARAVEL_STORAGE_PATH'])) {\n            return $this->joinPaths($this->storagePath ?: $_ENV['LARAVEL_STORAGE_PATH'], $path);\n        }\n\n        if (isset($_SERVER['LARAVEL_STORAGE_PATH'])) {\n            return $this->joinPaths($this->storagePath ?: $_SERVER['LARAVEL_STORAGE_PATH'], $path);\n        }\n\n        return $this->joinPaths($this->storagePath ?: $this->basePath('storage'), $path);\n    }\n\n    /**\n     * Set the storage directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useStoragePath($path)\n    {\n        $this->storagePath = $path;\n\n        $this->instance('path.storage', $path);\n\n        return $this;\n    }\n\n    /**\n     * Get the path to the resources directory.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function resourcePath($path = '')\n    {\n        return $this->joinPaths($this->basePath('resources'), $path);\n    }\n\n    /**\n     * Get the path to the views directory.\n     *\n     * This method returns the first configured path in the array of view paths.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function viewPath($path = '')\n    {\n        $viewPath = rtrim($this['config']->get('view.paths')[0], DIRECTORY_SEPARATOR);\n\n        return $this->joinPaths($viewPath, $path);\n    }\n\n    /**\n     * Join the given paths together.\n     *\n     * @param  string  $basePath\n     * @param  string  $path\n     * @return string\n     */\n    public function joinPaths($basePath, $path = '')\n    {\n        return join_paths($basePath, $path);\n    }\n\n    /**\n     * Get the path to the environment file directory.\n     *\n     * @return string\n     */\n    public function environmentPath()\n    {\n        return $this->environmentPath ?: $this->basePath;\n    }\n\n    /**\n     * Set the directory for the environment file.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useEnvironmentPath($path)\n    {\n        $this->environmentPath = $path;\n\n        return $this;\n    }\n\n    /**\n     * Set the environment file to be loaded during bootstrapping.\n     *\n     * @param  string  $file\n     * @return $this\n     */\n    public function loadEnvironmentFrom($file)\n    {\n        $this->environmentFile = $file;\n\n        return $this;\n    }\n\n    /**\n     * Get the environment file the application is using.\n     *\n     * @return string\n     */\n    public function environmentFile()\n    {\n        return $this->environmentFile ?: '.env';\n    }\n\n    /**\n     * Get the fully-qualified path to the environment file.\n     *\n     * @return string\n     */\n    public function environmentFilePath()\n    {\n        return $this->environmentPath().DIRECTORY_SEPARATOR.$this->environmentFile();\n    }\n\n    /**\n     * Get or check the current application environment.\n     *\n     * @param  string|array  ...$environments\n     * @return string|bool\n     */\n    public function environment(...$environments)\n    {\n        if (count($environments) > 0) {\n            $patterns = is_array($environments[0]) ? $environments[0] : $environments;\n\n            return Str::is($patterns, $this['env']);\n        }\n\n        return $this['env'];\n    }\n\n    /**\n     * Determine if the application is in the local environment.\n     *\n     * @return bool\n     */\n    public function isLocal()\n    {\n        return $this['env'] === 'local';\n    }\n\n    /**\n     * Determine if the application is in the production environment.\n     *\n     * @return bool\n     */\n    public function isProduction()\n    {\n        return $this['env'] === 'production';\n    }\n\n    /**\n     * Detect the application's current environment.\n     *\n     * @param  \\Closure  $callback\n     * @return string\n     */\n    public function detectEnvironment(Closure $callback)\n    {\n        $args = $this->runningInConsole() && isset($_SERVER['argv'])\n            ? $_SERVER['argv']\n            : null;\n\n        return $this['env'] = (new EnvironmentDetector)->detect($callback, $args);\n    }\n\n    /**\n     * Determine if the application is running in the console.\n     *\n     * @return bool\n     */\n    public function runningInConsole()\n    {\n        if ($this->isRunningInConsole === null) {\n            $this->isRunningInConsole = Env::get('APP_RUNNING_IN_CONSOLE') ?? (\\PHP_SAPI === 'cli' || \\PHP_SAPI === 'phpdbg');\n        }\n\n        return $this->isRunningInConsole;\n    }\n\n    /**\n     * Determine if the application is running any of the given console commands.\n     *\n     * @param  string|array  ...$commands\n     * @return bool\n     */\n    public function runningConsoleCommand(...$commands)\n    {\n        if (! $this->runningInConsole()) {\n            return false;\n        }\n\n        return in_array(\n            $_SERVER['argv'][1] ?? null,\n            is_array($commands[0]) ? $commands[0] : $commands\n        );\n    }\n\n    /**\n     * Determine if the application is running unit tests.\n     *\n     * @return bool\n     */\n    public function runningUnitTests()\n    {\n        return $this->bound('env') && $this['env'] === 'testing';\n    }\n\n    /**\n     * Determine if the application is running with debug mode enabled.\n     *\n     * @return bool\n     */\n    public function hasDebugModeEnabled()\n    {\n        return (bool) $this['config']->get('app.debug');\n    }\n\n    /**\n     * Register a new registered listener.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function registered($callback)\n    {\n        $this->registeredCallbacks[] = $callback;\n    }\n\n    /**\n     * Register all of the configured providers.\n     *\n     * @return void\n     */\n    public function registerConfiguredProviders()\n    {\n        $providers = (new Collection($this->make('config')->get('app.providers')))\n            ->partition(fn ($provider) => str_starts_with($provider, 'Illuminate\\\\'));\n\n        $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);\n\n        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))\n            ->load($providers->collapse()->toArray());\n\n        $this->fireAppCallbacks($this->registeredCallbacks);\n    }\n\n    /**\n     * Register a service provider with the application.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider|string  $provider\n     * @param  bool  $force\n     * @return \\Illuminate\\Support\\ServiceProvider\n     */\n    public function register($provider, $force = false)\n    {\n        if (($registered = $this->getProvider($provider)) && ! $force) {\n            return $registered;\n        }\n\n        // If the given \"provider\" is a string, we will resolve it, passing in the\n        // application instance automatically for the developer. This is simply\n        // a more convenient way of specifying your service provider classes.\n        if (is_string($provider)) {\n            $provider = $this->resolveProvider($provider);\n        }\n\n        $provider->register();\n\n        // If there are bindings / singletons set as properties on the provider we\n        // will spin through them and register them with the application, which\n        // serves as a convenience layer while registering a lot of bindings.\n        if (property_exists($provider, 'bindings')) {\n            foreach ($provider->bindings as $key => $value) {\n                $this->bind($key, $value);\n            }\n        }\n\n        if (property_exists($provider, 'singletons')) {\n            foreach ($provider->singletons as $key => $value) {\n                $key = is_int($key) ? $value : $key;\n\n                $this->singleton($key, $value);\n            }\n        }\n\n        $this->markAsRegistered($provider);\n\n        // If the application has already booted, we will call this boot method on\n        // the provider class so it has an opportunity to do its boot logic and\n        // will be ready for any usage by this developer's application logic.\n        if ($this->isBooted()) {\n            $this->bootProvider($provider);\n        }\n\n        return $provider;\n    }\n\n    /**\n     * Get the registered service provider instance if it exists.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider|string  $provider\n     * @return \\Illuminate\\Support\\ServiceProvider|null\n     */\n    public function getProvider($provider)\n    {\n        $name = is_string($provider) ? $provider : get_class($provider);\n\n        return $this->serviceProviders[$name] ?? null;\n    }\n\n    /**\n     * Get the registered service provider instances if any exist.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider|string  $provider\n     * @return array\n     */\n    public function getProviders($provider)\n    {\n        $name = is_string($provider) ? $provider : get_class($provider);\n\n        return Arr::where($this->serviceProviders, fn ($value) => $value instanceof $name);\n    }\n\n    /**\n     * Resolve a service provider instance from the class name.\n     *\n     * @param  string  $provider\n     * @return \\Illuminate\\Support\\ServiceProvider\n     */\n    public function resolveProvider($provider)\n    {\n        return new $provider($this);\n    }\n\n    /**\n     * Mark the given provider as registered.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider  $provider\n     * @return void\n     */\n    protected function markAsRegistered($provider)\n    {\n        $class = get_class($provider);\n\n        $this->serviceProviders[$class] = $provider;\n\n        $this->loadedProviders[$class] = true;\n    }\n\n    /**\n     * Load and boot all of the remaining deferred providers.\n     *\n     * @return void\n     */\n    public function loadDeferredProviders()\n    {\n        // We will simply spin through each of the deferred providers and register each\n        // one and boot them if the application has booted. This should make each of\n        // the remaining services available to this application for immediate use.\n        foreach ($this->deferredServices as $service => $provider) {\n            $this->loadDeferredProvider($service);\n        }\n\n        $this->deferredServices = [];\n    }\n\n    /**\n     * Load the provider for a deferred service.\n     *\n     * @param  string  $service\n     * @return void\n     */\n    public function loadDeferredProvider($service)\n    {\n        if (! $this->isDeferredService($service)) {\n            return;\n        }\n\n        $provider = $this->deferredServices[$service];\n\n        // If the service provider has not already been loaded and registered we can\n        // register it with the application and remove the service from this list\n        // of deferred services, since it will already be loaded on subsequent.\n        if (! isset($this->loadedProviders[$provider])) {\n            $this->registerDeferredProvider($provider, $service);\n        }\n    }\n\n    /**\n     * Register a deferred provider and service.\n     *\n     * @param  string  $provider\n     * @param  string|null  $service\n     * @return void\n     */\n    public function registerDeferredProvider($provider, $service = null)\n    {\n        // Once the provider that provides the deferred service has been registered we\n        // will remove it from our local list of the deferred services with related\n        // providers so that this container does not try to resolve it out again.\n        if ($service) {\n            unset($this->deferredServices[$service]);\n        }\n\n        $this->register($instance = new $provider($this));\n\n        if (! $this->isBooted()) {\n            $this->booting(function () use ($instance) {\n                $this->bootProvider($instance);\n            });\n        }\n    }\n\n    /**\n     * Resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $abstract\n     * @param  array  $parameters\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function make($abstract, array $parameters = [])\n    {\n        $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));\n\n        return parent::make($abstract, $parameters);\n    }\n\n    /**\n     * Resolve the given type from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>|callable  $abstract\n     * @param  array  $parameters\n     * @param  bool  $raiseEvents\n     * @return ($abstract is class-string<TClass> ? TClass : mixed)\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     * @throws \\Illuminate\\Contracts\\Container\\CircularDependencyException\n     */\n    protected function resolve($abstract, $parameters = [], $raiseEvents = true)\n    {\n        $this->loadDeferredProviderIfNeeded($abstract = $this->getAlias($abstract));\n\n        return parent::resolve($abstract, $parameters, $raiseEvents);\n    }\n\n    /**\n     * Load the deferred provider if the given type is a deferred service and the instance has not been loaded.\n     *\n     * @param  string  $abstract\n     * @return void\n     */\n    protected function loadDeferredProviderIfNeeded($abstract)\n    {\n        if ($this->isDeferredService($abstract) && ! isset($this->instances[$abstract])) {\n            $this->loadDeferredProvider($abstract);\n        }\n    }\n\n    /**\n     * Determine if the given abstract type has been bound.\n     *\n     * @param  string  $abstract\n     * @return bool\n     */\n    public function bound($abstract)\n    {\n        return $this->isDeferredService($abstract) || parent::bound($abstract);\n    }\n\n    /**\n     * Determine if the application has booted.\n     *\n     * @return bool\n     */\n    public function isBooted()\n    {\n        return $this->booted;\n    }\n\n    /**\n     * Boot the application's service providers.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        if ($this->isBooted()) {\n            return;\n        }\n\n        // Once the application has booted we will also fire some \"booted\" callbacks\n        // for any listeners that need to do work after this initial booting gets\n        // finished. This is useful when ordering the boot-up processes we run.\n        $this->fireAppCallbacks($this->bootingCallbacks);\n\n        array_walk($this->serviceProviders, function ($p) {\n            $this->bootProvider($p);\n        });\n\n        $this->booted = true;\n\n        $this->fireAppCallbacks($this->bootedCallbacks);\n    }\n\n    /**\n     * Boot the given service provider.\n     *\n     * @param  \\Illuminate\\Support\\ServiceProvider  $provider\n     * @return void\n     */\n    protected function bootProvider(ServiceProvider $provider)\n    {\n        $provider->callBootingCallbacks();\n\n        if (method_exists($provider, 'boot')) {\n            $this->call([$provider, 'boot']);\n        }\n\n        $provider->callBootedCallbacks();\n    }\n\n    /**\n     * Register a new boot listener.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function booting($callback)\n    {\n        $this->bootingCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a new \"booted\" listener.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function booted($callback)\n    {\n        $this->bootedCallbacks[] = $callback;\n\n        if ($this->isBooted()) {\n            $callback($this);\n        }\n    }\n\n    /**\n     * Call the booting callbacks for the application.\n     *\n     * @param  callable[]  $callbacks\n     * @return void\n     */\n    protected function fireAppCallbacks(array &$callbacks)\n    {\n        $index = 0;\n\n        while ($index < count($callbacks)) {\n            $callbacks[$index]($this);\n\n            $index++;\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function handle(SymfonyRequest $request, int $type = self::MAIN_REQUEST, bool $catch = true): SymfonyResponse\n    {\n        return $this[HttpKernelContract::class]->handle(Request::createFromBase($request));\n    }\n\n    /**\n     * Handle the incoming HTTP request and send the response to the browser.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    public function handleRequest(Request $request)\n    {\n        $kernel = $this->make(HttpKernelContract::class);\n\n        $response = $kernel->handle($request)->send();\n\n        $kernel->terminate($request, $response);\n    }\n\n    /**\n     * Handle the incoming Artisan command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @return int\n     */\n    public function handleCommand(InputInterface $input)\n    {\n        $kernel = $this->make(ConsoleKernelContract::class);\n\n        $status = $kernel->handle(\n            $input,\n            new ConsoleOutput\n        );\n\n        $kernel->terminate($input, $status);\n\n        return $status;\n    }\n\n    /**\n     * Determine if the framework's base configuration should be merged.\n     *\n     * @return bool\n     */\n    public function shouldMergeFrameworkConfiguration()\n    {\n        return $this->mergeFrameworkConfiguration;\n    }\n\n    /**\n     * Indicate that the framework's base configuration should not be merged.\n     *\n     * @return $this\n     */\n    public function dontMergeFrameworkConfiguration()\n    {\n        $this->mergeFrameworkConfiguration = false;\n\n        return $this;\n    }\n\n    /**\n     * Determine if middleware has been disabled for the application.\n     *\n     * @return bool\n     */\n    public function shouldSkipMiddleware()\n    {\n        return $this->bound('middleware.disable') &&\n               $this->make('middleware.disable') === true;\n    }\n\n    /**\n     * Get the path to the cached services.php file.\n     *\n     * @return string\n     */\n    public function getCachedServicesPath()\n    {\n        return $this->normalizeCachePath('APP_SERVICES_CACHE', 'cache/services.php');\n    }\n\n    /**\n     * Get the path to the cached packages.php file.\n     *\n     * @return string\n     */\n    public function getCachedPackagesPath()\n    {\n        return $this->normalizeCachePath('APP_PACKAGES_CACHE', 'cache/packages.php');\n    }\n\n    /**\n     * Determine if the application configuration is cached.\n     *\n     * @return bool\n     */\n    public function configurationIsCached()\n    {\n        if ($this->bound('config_loaded_from_cache')) {\n            return (bool) $this->make('config_loaded_from_cache');\n        }\n\n        return $this->instance('config_loaded_from_cache', is_file($this->getCachedConfigPath()));\n    }\n\n    /**\n     * Get the path to the configuration cache file.\n     *\n     * @return string\n     */\n    public function getCachedConfigPath()\n    {\n        return $this->normalizeCachePath('APP_CONFIG_CACHE', 'cache/config.php');\n    }\n\n    /**\n     * Determine if the application routes are cached.\n     *\n     * @return bool\n     */\n    public function routesAreCached()\n    {\n        if ($this->bound('routes.cached')) {\n            return (bool) $this->make('routes.cached');\n        }\n\n        return $this->instance('routes.cached', $this['files']->exists($this->getCachedRoutesPath()));\n    }\n\n    /**\n     * Get the path to the routes cache file.\n     *\n     * @return string\n     */\n    public function getCachedRoutesPath()\n    {\n        return $this->normalizeCachePath('APP_ROUTES_CACHE', 'cache/routes-v7.php');\n    }\n\n    /**\n     * Determine if the application events are cached.\n     *\n     * @return bool\n     */\n    public function eventsAreCached()\n    {\n        if ($this->bound('events.cached')) {\n            return (bool) $this->make('events.cached');\n        }\n\n        return $this->instance(\n            'events.cached', $this['files']->exists($this->getCachedEventsPath())\n        );\n    }\n\n    /**\n     * Get the path to the events cache file.\n     *\n     * @return string\n     */\n    public function getCachedEventsPath()\n    {\n        return $this->normalizeCachePath('APP_EVENTS_CACHE', 'cache/events.php');\n    }\n\n    /**\n     * Normalize a relative or absolute path to a cache file.\n     *\n     * @param  string  $key\n     * @param  string  $default\n     * @return string\n     */\n    protected function normalizeCachePath($key, $default)\n    {\n        if (is_null($env = Env::get($key))) {\n            return $this->bootstrapPath($default);\n        }\n\n        return Str::startsWith($env, $this->absoluteCachePathPrefixes)\n            ? $env\n            : $this->basePath($env);\n    }\n\n    /**\n     * Add new prefix to list of absolute path prefixes.\n     *\n     * @param  string  $prefix\n     * @return $this\n     */\n    public function addAbsoluteCachePathPrefix($prefix)\n    {\n        $this->absoluteCachePathPrefixes[] = $prefix;\n\n        return $this;\n    }\n\n    /**\n     * Get an instance of the maintenance mode manager implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\MaintenanceMode\n     */\n    public function maintenanceMode()\n    {\n        return $this->make(MaintenanceModeContract::class);\n    }\n\n    /**\n     * Determine if the application is currently down for maintenance.\n     *\n     * @return bool\n     */\n    public function isDownForMaintenance()\n    {\n        return $this->maintenanceMode()->active();\n    }\n\n    /**\n     * Throw an HttpException with the given data.\n     *\n     * @param  int  $code\n     * @param  string  $message\n     * @param  array  $headers\n     * @return never\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    public function abort($code, $message = '', array $headers = [])\n    {\n        if ($code == 404) {\n            throw new NotFoundHttpException($message, null, 0, $headers);\n        }\n\n        throw new HttpException($code, $message, null, $headers);\n    }\n\n    /**\n     * Register a terminating callback with the application.\n     *\n     * @param  callable|string  $callback\n     * @return $this\n     */\n    public function terminating($callback)\n    {\n        $this->terminatingCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Terminate the application.\n     *\n     * @return void\n     */\n    public function terminate()\n    {\n        $index = 0;\n\n        while ($index < count($this->terminatingCallbacks)) {\n            $this->call($this->terminatingCallbacks[$index]);\n\n            $index++;\n        }\n    }\n\n    /**\n     * Get the service providers that have been loaded.\n     *\n     * @return array<string, bool>\n     */\n    public function getLoadedProviders()\n    {\n        return $this->loadedProviders;\n    }\n\n    /**\n     * Determine if the given service provider is loaded.\n     *\n     * @param  string  $provider\n     * @return bool\n     */\n    public function providerIsLoaded(string $provider)\n    {\n        return isset($this->loadedProviders[$provider]);\n    }\n\n    /**\n     * Get the application's deferred services.\n     *\n     * @return array\n     */\n    public function getDeferredServices()\n    {\n        return $this->deferredServices;\n    }\n\n    /**\n     * Set the application's deferred services.\n     *\n     * @param  array  $services\n     * @return void\n     */\n    public function setDeferredServices(array $services)\n    {\n        $this->deferredServices = $services;\n    }\n\n    /**\n     * Determine if the given service is a deferred service.\n     *\n     * @param  string  $service\n     * @return bool\n     */\n    public function isDeferredService($service)\n    {\n        return isset($this->deferredServices[$service]);\n    }\n\n    /**\n     * Add an array of services to the application's deferred services.\n     *\n     * @param  array  $services\n     * @return void\n     */\n    public function addDeferredServices(array $services)\n    {\n        $this->deferredServices = array_merge($this->deferredServices, $services);\n    }\n\n    /**\n     * Remove an array of services from the application's deferred services.\n     *\n     * @param  array  $services\n     * @return void\n     */\n    public function removeDeferredServices(array $services)\n    {\n        foreach ($services as $service) {\n            unset($this->deferredServices[$service]);\n        }\n    }\n\n    /**\n     * Configure the real-time facade namespace.\n     *\n     * @param  string  $namespace\n     * @return void\n     */\n    public function provideFacades($namespace)\n    {\n        AliasLoader::setFacadeNamespace($namespace);\n    }\n\n    /**\n     * Get the current application locale.\n     *\n     * @return string\n     */\n    public function getLocale()\n    {\n        return $this['config']->get('app.locale');\n    }\n\n    /**\n     * Get the current application locale.\n     *\n     * @return string\n     */\n    public function currentLocale()\n    {\n        return $this->getLocale();\n    }\n\n    /**\n     * Get the current application fallback locale.\n     *\n     * @return string\n     */\n    public function getFallbackLocale()\n    {\n        return $this['config']->get('app.fallback_locale');\n    }\n\n    /**\n     * Set the current application locale.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public function setLocale($locale)\n    {\n        $previous = $this['config']->get('app.locale');\n\n        $this['config']->set('app.locale', $locale);\n\n        $this['translator']->setLocale($locale);\n\n        $this['events']->dispatch(new LocaleUpdated($locale, $previous));\n    }\n\n    /**\n     * Set the current application fallback locale.\n     *\n     * @param  string  $fallbackLocale\n     * @return void\n     */\n    public function setFallbackLocale($fallbackLocale)\n    {\n        $this['config']->set('app.fallback_locale', $fallbackLocale);\n\n        $this['translator']->setFallback($fallbackLocale);\n    }\n\n    /**\n     * Determine if the application locale is the given locale.\n     *\n     * @param  string  $locale\n     * @return bool\n     */\n    public function isLocale($locale)\n    {\n        return $this->getLocale() == $locale;\n    }\n\n    /**\n     * Register the core class aliases in the container.\n     *\n     * @return void\n     */\n    public function registerCoreContainerAliases()\n    {\n        foreach ([\n            'app' => [self::class, \\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Contracts\\Foundation\\Application::class, \\Psr\\Container\\ContainerInterface::class],\n            'auth' => [\\Illuminate\\Auth\\AuthManager::class, \\Illuminate\\Contracts\\Auth\\Factory::class],\n            'auth.driver' => [\\Illuminate\\Contracts\\Auth\\Guard::class],\n            'auth.password' => [\\Illuminate\\Auth\\Passwords\\PasswordBrokerManager::class, \\Illuminate\\Contracts\\Auth\\PasswordBrokerFactory::class],\n            'auth.password.broker' => [\\Illuminate\\Auth\\Passwords\\PasswordBroker::class, \\Illuminate\\Contracts\\Auth\\PasswordBroker::class],\n            'blade.compiler' => [\\Illuminate\\View\\Compilers\\BladeCompiler::class],\n            'cache' => [\\Illuminate\\Cache\\CacheManager::class, \\Illuminate\\Contracts\\Cache\\Factory::class],\n            'cache.store' => [\\Illuminate\\Cache\\Repository::class, \\Illuminate\\Contracts\\Cache\\Repository::class, \\Psr\\SimpleCache\\CacheInterface::class],\n            'cache.psr6' => [\\Symfony\\Component\\Cache\\Adapter\\Psr16Adapter::class, \\Symfony\\Component\\Cache\\Adapter\\AdapterInterface::class, \\Psr\\Cache\\CacheItemPoolInterface::class],\n            'config' => [\\Illuminate\\Config\\Repository::class, \\Illuminate\\Contracts\\Config\\Repository::class],\n            'cookie' => [\\Illuminate\\Cookie\\CookieJar::class, \\Illuminate\\Contracts\\Cookie\\Factory::class, \\Illuminate\\Contracts\\Cookie\\QueueingFactory::class],\n            'db' => [\\Illuminate\\Database\\DatabaseManager::class, \\Illuminate\\Database\\ConnectionResolverInterface::class],\n            'db.connection' => [\\Illuminate\\Database\\Connection::class, \\Illuminate\\Database\\ConnectionInterface::class],\n            'db.schema' => [\\Illuminate\\Database\\Schema\\Builder::class],\n            'encrypter' => [\\Illuminate\\Encryption\\Encrypter::class, \\Illuminate\\Contracts\\Encryption\\Encrypter::class, \\Illuminate\\Contracts\\Encryption\\StringEncrypter::class],\n            'events' => [\\Illuminate\\Events\\Dispatcher::class, \\Illuminate\\Contracts\\Events\\Dispatcher::class],\n            'files' => [\\Illuminate\\Filesystem\\Filesystem::class],\n            'filesystem' => [\\Illuminate\\Filesystem\\FilesystemManager::class, \\Illuminate\\Contracts\\Filesystem\\Factory::class],\n            'filesystem.disk' => [\\Illuminate\\Contracts\\Filesystem\\Filesystem::class],\n            'filesystem.cloud' => [\\Illuminate\\Contracts\\Filesystem\\Cloud::class],\n            'hash' => [\\Illuminate\\Hashing\\HashManager::class],\n            'hash.driver' => [\\Illuminate\\Contracts\\Hashing\\Hasher::class],\n            'log' => [\\Illuminate\\Log\\LogManager::class, \\Psr\\Log\\LoggerInterface::class],\n            'mail.manager' => [\\Illuminate\\Mail\\MailManager::class, \\Illuminate\\Contracts\\Mail\\Factory::class],\n            'mailer' => [\\Illuminate\\Mail\\Mailer::class, \\Illuminate\\Contracts\\Mail\\Mailer::class, \\Illuminate\\Contracts\\Mail\\MailQueue::class],\n            'queue' => [\\Illuminate\\Queue\\QueueManager::class, \\Illuminate\\Contracts\\Queue\\Factory::class, \\Illuminate\\Contracts\\Queue\\Monitor::class],\n            'queue.connection' => [\\Illuminate\\Contracts\\Queue\\Queue::class],\n            'queue.failer' => [\\Illuminate\\Queue\\Failed\\FailedJobProviderInterface::class],\n            'redirect' => [\\Illuminate\\Routing\\Redirector::class],\n            'redis' => [\\Illuminate\\Redis\\RedisManager::class, \\Illuminate\\Contracts\\Redis\\Factory::class],\n            'redis.connection' => [\\Illuminate\\Redis\\Connections\\Connection::class, \\Illuminate\\Contracts\\Redis\\Connection::class],\n            'request' => [\\Illuminate\\Http\\Request::class, \\Symfony\\Component\\HttpFoundation\\Request::class],\n            'router' => [\\Illuminate\\Routing\\Router::class, \\Illuminate\\Contracts\\Routing\\Registrar::class, \\Illuminate\\Contracts\\Routing\\BindingRegistrar::class],\n            'session' => [\\Illuminate\\Session\\SessionManager::class],\n            'session.store' => [\\Illuminate\\Session\\Store::class, \\Illuminate\\Contracts\\Session\\Session::class],\n            'translator' => [\\Illuminate\\Translation\\Translator::class, \\Illuminate\\Contracts\\Translation\\Translator::class],\n            'url' => [\\Illuminate\\Routing\\UrlGenerator::class, \\Illuminate\\Contracts\\Routing\\UrlGenerator::class],\n            'validator' => [\\Illuminate\\Validation\\Factory::class, \\Illuminate\\Contracts\\Validation\\Factory::class],\n            'view' => [\\Illuminate\\View\\Factory::class, \\Illuminate\\Contracts\\View\\Factory::class],\n        ] as $key => $aliases) {\n            foreach ($aliases as $alias) {\n                $this->alias($key, $alias);\n            }\n        }\n    }\n\n    /**\n     * Flush the container of all bindings and resolved instances.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        parent::flush();\n\n        $this->buildStack = [];\n        $this->loadedProviders = [];\n        $this->bootedCallbacks = [];\n        $this->bootingCallbacks = [];\n        $this->deferredServices = [];\n        $this->reboundCallbacks = [];\n        $this->serviceProviders = [];\n        $this->resolvingCallbacks = [];\n        $this->terminatingCallbacks = [];\n        $this->beforeResolvingCallbacks = [];\n        $this->afterResolvingCallbacks = [];\n        $this->globalBeforeResolvingCallbacks = [];\n        $this->globalResolvingCallbacks = [];\n        $this->globalAfterResolvingCallbacks = [];\n    }\n\n    /**\n     * Get the application namespace.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function getNamespace()\n    {\n        if (! is_null($this->namespace)) {\n            return $this->namespace;\n        }\n\n        $composer = json_decode(file_get_contents($this->basePath('composer.json')), true);\n\n        foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) {\n            foreach ((array) $path as $pathChoice) {\n                if (realpath($this->path()) === realpath($this->basePath($pathChoice))) {\n                    return $this->namespace = $namespace;\n                }\n            }\n        }\n\n        throw new RuntimeException('Unable to detect application namespace.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Auth/Access/Authorizable.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Auth\\Access;\n\nuse Illuminate\\Contracts\\Auth\\Access\\Gate;\n\ntrait Authorizable\n{\n    /**\n     * Determine if the entity has the given abilities.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function can($abilities, $arguments = [])\n    {\n        return app(Gate::class)->forUser($this)->check($abilities, $arguments);\n    }\n\n    /**\n     * Determine if the entity has any of the given abilities.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function canAny($abilities, $arguments = [])\n    {\n        return app(Gate::class)->forUser($this)->any($abilities, $arguments);\n    }\n\n    /**\n     * Determine if the entity does not have the given abilities.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function cant($abilities, $arguments = [])\n    {\n        return ! $this->can($abilities, $arguments);\n    }\n\n    /**\n     * Determine if the entity does not have the given abilities.\n     *\n     * @param  iterable|\\UnitEnum|string  $abilities\n     * @param  mixed  $arguments\n     * @return bool\n     */\n    public function cannot($abilities, $arguments = [])\n    {\n        return $this->cant($abilities, $arguments);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Auth\\Access;\n\nuse Illuminate\\Contracts\\Auth\\Access\\Gate;\nuse Illuminate\\Support\\Str;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait AuthorizesRequests\n{\n    /**\n     * Authorize a given action for the current user.\n     *\n     * @param  mixed  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function authorize($ability, $arguments = [])\n    {\n        [$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);\n\n        return app(Gate::class)->authorize($ability, $arguments);\n    }\n\n    /**\n     * Authorize a given action for a user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable|mixed  $user\n     * @param  mixed  $ability\n     * @param  mixed  $arguments\n     * @return \\Illuminate\\Auth\\Access\\Response\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    public function authorizeForUser($user, $ability, $arguments = [])\n    {\n        [$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);\n\n        return app(Gate::class)->forUser($user)->authorize($ability, $arguments);\n    }\n\n    /**\n     * Guesses the ability's name if it wasn't provided.\n     *\n     * @param  mixed  $ability\n     * @param  mixed  $arguments\n     * @return array\n     */\n    protected function parseAbilityAndArguments($ability, $arguments)\n    {\n        $ability = enum_value($ability);\n\n        if (is_string($ability) && ! str_contains($ability, '\\\\')) {\n            return [$ability, $arguments];\n        }\n\n        $method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];\n\n        return [$this->normalizeGuessedAbilityName($method), $ability];\n    }\n\n    /**\n     * Normalize the ability name that has been guessed from the method name.\n     *\n     * @param  string  $ability\n     * @return string\n     */\n    protected function normalizeGuessedAbilityName($ability)\n    {\n        $map = $this->resourceAbilityMap();\n\n        return $map[$ability] ?? $ability;\n    }\n\n    /**\n     * Authorize a resource action based on the incoming request.\n     *\n     * @param  string|array  $model\n     * @param  string|array|null  $parameter\n     * @param  array  $options\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return void\n     */\n    public function authorizeResource($model, $parameter = null, array $options = [], $request = null)\n    {\n        $model = is_array($model) ? implode(',', $model) : $model;\n\n        $parameter = is_array($parameter) ? implode(',', $parameter) : $parameter;\n\n        $parameter = $parameter ?: Str::snake(class_basename($model));\n\n        $middleware = [];\n\n        foreach ($this->resourceAbilityMap() as $method => $ability) {\n            $modelName = in_array($method, $this->resourceMethodsWithoutModels()) ? $model : $parameter;\n\n            $middleware[\"can:{$ability},{$modelName}\"][] = $method;\n        }\n\n        foreach ($middleware as $middlewareName => $methods) {\n            $this->middleware($middlewareName, $options)->only($methods);\n        }\n    }\n\n    /**\n     * Get the map of resource methods to ability names.\n     *\n     * @return array<string, string>\n     */\n    protected function resourceAbilityMap()\n    {\n        return [\n            'index' => 'viewAny',\n            'show' => 'view',\n            'create' => 'create',\n            'store' => 'create',\n            'edit' => 'update',\n            'update' => 'update',\n            'destroy' => 'delete',\n        ];\n    }\n\n    /**\n     * Get the list of resource methods which do not have model parameters.\n     *\n     * @return list<string>\n     */\n    protected function resourceMethodsWithoutModels()\n    {\n        return ['index', 'create', 'store'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Auth/EmailVerificationRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Auth;\n\nuse Illuminate\\Auth\\Events\\Verified;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Validation\\Validator;\n\nclass EmailVerificationRequest extends FormRequest\n{\n    /**\n     * Determine if the user is authorized to make this request.\n     *\n     * @return bool\n     */\n    public function authorize()\n    {\n        if (! hash_equals((string) $this->user()->getKey(), (string) $this->route('id'))) {\n            return false;\n        }\n\n        if (! hash_equals(sha1($this->user()->getEmailForVerification()), (string) $this->route('hash'))) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the validation rules that apply to the request.\n     *\n     * @return array\n     */\n    public function rules()\n    {\n        return [\n            //\n        ];\n    }\n\n    /**\n     * Fulfill the email verification request.\n     *\n     * @return void\n     */\n    public function fulfill()\n    {\n        if (! $this->user()->hasVerifiedEmail()) {\n            $this->user()->markEmailAsVerified();\n\n            event(new Verified($this->user()));\n        }\n    }\n\n    /**\n     * Configure the validator instance.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return \\Illuminate\\Validation\\Validator\n     */\n    public function withValidator(Validator $validator)\n    {\n        return $validator;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Auth/User.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Auth;\n\nuse Illuminate\\Auth\\Authenticatable;\nuse Illuminate\\Auth\\MustVerifyEmail;\nuse Illuminate\\Auth\\Passwords\\CanResetPassword;\nuse Illuminate\\Contracts\\Auth\\Access\\Authorizable as AuthorizableContract;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as AuthenticatableContract;\nuse Illuminate\\Contracts\\Auth\\CanResetPassword as CanResetPasswordContract;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Auth\\Access\\Authorizable;\n\nclass User extends Model implements\n    AuthenticatableContract,\n    AuthorizableContract,\n    CanResetPasswordContract\n{\n    use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/BootProviders.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\n\nclass BootProviders\n{\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        $app->boot();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/HandleExceptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse ErrorException;\nuse Exception;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Log\\LogManager;\nuse Illuminate\\Support\\Env;\nuse Monolog\\Handler\\NullHandler;\nuse PHPUnit\\Framework\\TestCase;\nuse PHPUnit\\Runner\\ErrorHandler;\nuse PHPUnit\\Runner\\Version;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\nuse Symfony\\Component\\ErrorHandler\\Error\\FatalError;\nuse Throwable;\n\nclass HandleExceptions\n{\n    /**\n     * Reserved memory so that errors can be displayed properly on memory exhaustion.\n     *\n     * @var string|null\n     */\n    public static $reservedMemory;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected static $app;\n\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        static::$reservedMemory = str_repeat('x', 32768);\n\n        static::$app = $app;\n\n        error_reporting(-1);\n\n        set_error_handler($this->forwardsTo('handleError'));\n\n        set_exception_handler($this->forwardsTo('handleException'));\n\n        register_shutdown_function($this->forwardsTo('handleShutdown'));\n\n        if (! $app->environment('testing')) {\n            ini_set('display_errors', 'Off');\n        }\n    }\n\n    /**\n     * Report PHP deprecations, or convert PHP errors to ErrorException instances.\n     *\n     * @param  int  $level\n     * @param  string  $message\n     * @param  string  $file\n     * @param  int  $line\n     * @return void\n     *\n     * @throws \\ErrorException\n     */\n    public function handleError($level, $message, $file = '', $line = 0)\n    {\n        if ($this->isDeprecation($level)) {\n            $this->handleDeprecationError($message, $file, $line, $level);\n        } elseif (error_reporting() & $level) {\n            throw new ErrorException($message, 0, $level, $file, $line);\n        }\n    }\n\n    /**\n     * Reports a deprecation to the \"deprecations\" logger.\n     *\n     * @param  string  $message\n     * @param  string  $file\n     * @param  int  $line\n     * @param  int  $level\n     * @return void\n     */\n    public function handleDeprecationError($message, $file, $line, $level = E_DEPRECATED)\n    {\n        if ($this->shouldIgnoreDeprecationErrors()) {\n            return;\n        }\n\n        try {\n            $logger = static::$app->make(LogManager::class);\n        } catch (Exception) {\n            return;\n        }\n\n        $this->ensureDeprecationLoggerIsConfigured();\n\n        $options = static::$app['config']->get('logging.deprecations') ?? [];\n\n        with($logger->channel('deprecations'), function ($log) use ($message, $file, $line, $level, $options) {\n            if ($options['trace'] ?? false) {\n                $log->warning((string) new ErrorException($message, 0, $level, $file, $line));\n            } else {\n                $log->warning(sprintf('%s in %s on line %s',\n                    $message, $file, $line\n                ));\n            }\n        });\n    }\n\n    /**\n     * Determine if deprecation errors should be ignored.\n     *\n     * @return bool\n     */\n    protected function shouldIgnoreDeprecationErrors()\n    {\n        return ! class_exists(LogManager::class)\n            || ! static::$app->hasBeenBootstrapped()\n            || (static::$app->runningUnitTests() && ! Env::get('LOG_DEPRECATIONS_WHILE_TESTING'));\n    }\n\n    /**\n     * Ensure the \"deprecations\" logger is configured.\n     *\n     * @return void\n     */\n    protected function ensureDeprecationLoggerIsConfigured()\n    {\n        $config = static::$app['config'];\n\n        if ($config->get('logging.channels.deprecations')) {\n            return;\n        }\n\n        $this->ensureNullLogDriverIsConfigured();\n\n        if (is_array($options = $config->get('logging.deprecations'))) {\n            $driver = $options['channel'] ?? 'null';\n        } else {\n            $driver = $options ?? 'null';\n        }\n\n        $config->set('logging.channels.deprecations', $config->get(\"logging.channels.{$driver}\"));\n    }\n\n    /**\n     * Ensure the \"null\" log driver is configured.\n     *\n     * @return void\n     */\n    protected function ensureNullLogDriverIsConfigured()\n    {\n        $config = static::$app['config'];\n\n        if ($config->get('logging.channels.null')) {\n            return;\n        }\n\n        $config->set('logging.channels.null', [\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n        ]);\n    }\n\n    /**\n     * Handle an uncaught exception from the application.\n     *\n     * Note: Most exceptions can be handled via the try / catch block in\n     * the HTTP and Console kernels. But, fatal error exceptions must\n     * be handled differently since they are not normal exceptions.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function handleException(Throwable $e)\n    {\n        static::$reservedMemory = null;\n\n        try {\n            $this->getExceptionHandler()->report($e);\n        } catch (Exception) {\n            $exceptionHandlerFailed = true;\n        }\n\n        if (static::$app->runningInConsole()) {\n            $this->renderForConsole($e);\n\n            if ($exceptionHandlerFailed ?? false) {\n                exit(1);\n            }\n        } else {\n            $this->renderHttpResponse($e);\n        }\n    }\n\n    /**\n     * Render an exception to the console.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function renderForConsole(Throwable $e)\n    {\n        $this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);\n    }\n\n    /**\n     * Render an exception as an HTTP response and send it.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function renderHttpResponse(Throwable $e)\n    {\n        $this->getExceptionHandler()->render(static::$app['request'], $e)->send();\n    }\n\n    /**\n     * Handle the PHP shutdown event.\n     *\n     * @return void\n     */\n    public function handleShutdown()\n    {\n        static::$reservedMemory = null;\n\n        if (! is_null($error = error_get_last()) && $this->isFatal($error['type'])) {\n            $this->handleException($this->fatalErrorFromPhpError($error, 0));\n        }\n    }\n\n    /**\n     * Create a new fatal error instance from an error array.\n     *\n     * @param  array  $error\n     * @param  int|null  $traceOffset\n     * @return \\Symfony\\Component\\ErrorHandler\\Error\\FatalError\n     */\n    protected function fatalErrorFromPhpError(array $error, $traceOffset = null)\n    {\n        return new FatalError($error['message'], 0, $error, $traceOffset);\n    }\n\n    /**\n     * Forward a method call to the given method if an application instance exists.\n     *\n     * @return callable\n     */\n    protected function forwardsTo($method)\n    {\n        return fn (...$arguments) => static::$app\n            ? $this->{$method}(...$arguments)\n            : false;\n    }\n\n    /**\n     * Determine if the error level is a deprecation.\n     *\n     * @param  int  $level\n     * @return bool\n     */\n    protected function isDeprecation($level)\n    {\n        return in_array($level, [E_DEPRECATED, E_USER_DEPRECATED]);\n    }\n\n    /**\n     * Determine if the error type is fatal.\n     *\n     * @param  int  $type\n     * @return bool\n     */\n    protected function isFatal($type)\n    {\n        return in_array($type, [E_COMPILE_ERROR, E_CORE_ERROR, E_ERROR, E_PARSE]);\n    }\n\n    /**\n     * Get an instance of the exception handler.\n     *\n     * @return \\Illuminate\\Contracts\\Debug\\ExceptionHandler\n     */\n    protected function getExceptionHandler()\n    {\n        return static::$app->make(ExceptionHandler::class);\n    }\n\n    /**\n     * Clear the local application instance from memory.\n     *\n     * @return void\n     *\n     * @deprecated This method will be removed in a future Laravel version.\n     */\n    public static function forgetApp()\n    {\n        static::$app = null;\n    }\n\n    /**\n     * Flush the bootstrapper's global state.\n     *\n     * @param  \\PHPUnit\\Framework\\TestCase|null  $testCase\n     * @return void\n     */\n    public static function flushState(?TestCase $testCase = null)\n    {\n        if (is_null(static::$app)) {\n            return;\n        }\n\n        static::flushHandlersState($testCase);\n\n        static::$app = null;\n\n        static::$reservedMemory = null;\n    }\n\n    /**\n     * Flush the bootstrapper's global handlers state.\n     *\n     * @param  \\PHPUnit\\Framework\\TestCase|null  $testCase\n     * @return void\n     */\n    public static function flushHandlersState(?TestCase $testCase = null)\n    {\n        while (get_exception_handler() !== null) {\n            restore_exception_handler();\n        }\n\n        while (get_error_handler() !== null) {\n            restore_error_handler();\n        }\n\n        if (class_exists(ErrorHandler::class)) {\n            $instance = ErrorHandler::instance();\n\n            if ((fn () => $this->enabled ?? false)->call($instance)) {\n                $instance->disable();\n\n                if (version_compare(Version::id(), '12.3.4', '>=')) {\n                    $instance->enable($testCase);\n                } else {\n                    $instance->enable();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Closure;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Contracts\\Config\\Repository as RepositoryContract;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Support\\Collection;\nuse SplFileInfo;\nuse Symfony\\Component\\Finder\\Finder;\n\nclass LoadConfiguration\n{\n    /**\n     * The closure that resolves the permanent, static configuration if applicable.\n     *\n     * @var (Closure(Application): array<array-key, mixed>)|null\n     */\n    protected static ?Closure $alwaysUseConfig = null;\n\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        $items = [];\n\n        // First we will see if we have a cache configuration file. If we do, we'll load\n        // the configuration items from that file so that it is very quick. Otherwise\n        // we will need to spin through every configuration file and load them all.\n        $loadedFromCache = false;\n\n        if (self::$alwaysUseConfig !== null) {\n            $items = $app->call(self::$alwaysUseConfig);\n\n            $loadedFromCache = true;\n        } elseif (file_exists($cached = $app->getCachedConfigPath())) {\n            $items = require $cached;\n\n            $loadedFromCache = true;\n        }\n\n        $app->instance('config_loaded_from_cache', $loadedFromCache);\n\n        // Next we will spin through all of the configuration files in the configuration\n        // directory and load each one into the repository. This will make all of the\n        // options available to the developer for use in various parts of this app.\n        $app->instance('config', $config = new Repository($items));\n\n        if (! $loadedFromCache) {\n            $this->loadConfigurationFiles($app, $config);\n        }\n\n        // Finally, we will set the application's environment based on the configuration\n        // values that were loaded. We will pass a callback which will be used to get\n        // the environment in a web context where an \"--env\" switch is not present.\n        $app->detectEnvironment(fn () => $config->get('app.env', 'production'));\n\n        $app->resolveEnvironmentUsing($app->environment(...));\n\n        date_default_timezone_set($config->get('app.timezone', 'UTC'));\n\n        mb_internal_encoding('UTF-8');\n    }\n\n    /**\n     * Load the configuration items from all of the files.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Contracts\\Config\\Repository  $repository\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    protected function loadConfigurationFiles(Application $app, RepositoryContract $repository)\n    {\n        $files = $this->getConfigurationFiles($app);\n\n        $shouldMerge = method_exists($app, 'shouldMergeFrameworkConfiguration')\n            ? $app->shouldMergeFrameworkConfiguration()\n            : true;\n\n        $base = $shouldMerge\n            ? $this->getBaseConfiguration()\n            : [];\n\n        foreach ((new Collection($base))->diffKeys($files) as $name => $config) {\n            $repository->set($name, $config);\n        }\n\n        foreach ($files as $name => $path) {\n            $base = $this->loadConfigurationFile($repository, $name, $path, $base);\n        }\n\n        foreach ($base as $name => $config) {\n            $repository->set($name, $config);\n        }\n    }\n\n    /**\n     * Load the given configuration file.\n     *\n     * @param  \\Illuminate\\Contracts\\Config\\Repository  $repository\n     * @param  string  $name\n     * @param  string  $path\n     * @param  array  $base\n     * @return array\n     */\n    protected function loadConfigurationFile(RepositoryContract $repository, $name, $path, array $base)\n    {\n        $config = (fn () => require $path)();\n\n        if (isset($base[$name])) {\n            $config = array_merge($base[$name], $config);\n\n            foreach ($this->mergeableOptions($name) as $option) {\n                if (isset($config[$option])) {\n                    $config[$option] = array_merge($base[$name][$option], $config[$option]);\n                }\n            }\n\n            unset($base[$name]);\n        }\n\n        $repository->set($name, $config);\n\n        return $base;\n    }\n\n    /**\n     * Get the options within the configuration file that should be merged again.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function mergeableOptions($name)\n    {\n        return [\n            'auth' => ['guards', 'providers', 'passwords'],\n            'broadcasting' => ['connections'],\n            'cache' => ['stores'],\n            'database' => ['connections'],\n            'filesystems' => ['disks'],\n            'logging' => ['channels'],\n            'mail' => ['mailers'],\n            'queue' => ['connections'],\n        ][$name] ?? [];\n    }\n\n    /**\n     * Get all of the configuration files for the application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return array\n     */\n    protected function getConfigurationFiles(Application $app)\n    {\n        $files = [];\n\n        $configPath = realpath($app->configPath());\n\n        if (! $configPath) {\n            return [];\n        }\n\n        foreach (Finder::create()->files()->name('*.php')->in($configPath) as $file) {\n            $directory = $this->getNestedDirectory($file, $configPath);\n\n            $files[$directory.basename($file->getRealPath(), '.php')] = $file->getRealPath();\n        }\n\n        ksort($files, SORT_NATURAL);\n\n        return $files;\n    }\n\n    /**\n     * Get the configuration file nesting path.\n     *\n     * @param  \\SplFileInfo  $file\n     * @param  string  $configPath\n     * @return string\n     */\n    protected function getNestedDirectory(SplFileInfo $file, $configPath)\n    {\n        $directory = $file->getPath();\n\n        if ($nested = trim(str_replace($configPath, '', $directory), DIRECTORY_SEPARATOR)) {\n            $nested = str_replace(DIRECTORY_SEPARATOR, '.', $nested).'.';\n        }\n\n        return $nested;\n    }\n\n    /**\n     * Get the base configuration files.\n     *\n     * @return array\n     */\n    protected function getBaseConfiguration()\n    {\n        $config = [];\n\n        foreach (Finder::create()->files()->name('*.php')->in(__DIR__.'/../../../../config') as $file) {\n            $config[basename($file->getRealPath(), '.php')] = require $file->getRealPath();\n        }\n\n        return $config;\n    }\n\n    /**\n     * Set a callback to return the permanent, static configuration values.\n     *\n     * @param  (Closure(Application): array<array-key, mixed>)|null  $alwaysUseConfig\n     * @return void\n     */\n    public static function alwaysUse(?Closure $alwaysUseConfig): void\n    {\n        static::$alwaysUseConfig = $alwaysUseConfig;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Dotenv\\Dotenv;\nuse Dotenv\\Exception\\InvalidFileException;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Support\\Env;\nuse Symfony\\Component\\Console\\Input\\ArgvInput;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\n\nclass LoadEnvironmentVariables\n{\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        if ($app->configurationIsCached()) {\n            return;\n        }\n\n        $this->checkForSpecificEnvironmentFile($app);\n\n        try {\n            $this->createDotenv($app)->safeLoad();\n        } catch (InvalidFileException $e) {\n            $this->writeErrorAndDie($e);\n        }\n    }\n\n    /**\n     * Detect if a custom environment file matching the APP_ENV exists.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function checkForSpecificEnvironmentFile($app)\n    {\n        if ($app->runningInConsole() &&\n            ($input = new ArgvInput)->hasParameterOption('--env') &&\n            $this->setEnvironmentFilePath($app, $app->environmentFile().'.'.$input->getParameterOption('--env'))) {\n            return;\n        }\n\n        $environment = Env::get('APP_ENV');\n\n        if (! $environment) {\n            return;\n        }\n\n        $this->setEnvironmentFilePath(\n            $app, $app->environmentFile().'.'.$environment\n        );\n    }\n\n    /**\n     * Load a custom environment file.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  string  $file\n     * @return bool\n     */\n    protected function setEnvironmentFilePath($app, $file)\n    {\n        if (is_file($app->environmentPath().'/'.$file)) {\n            $app->loadEnvironmentFrom($file);\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Create a Dotenv instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return \\Dotenv\\Dotenv\n     */\n    protected function createDotenv($app)\n    {\n        return Dotenv::create(\n            Env::getRepository(),\n            $app->environmentPath(),\n            $app->environmentFile()\n        );\n    }\n\n    /**\n     * Write the error information to the screen and exit.\n     *\n     * @param  \\Dotenv\\Exception\\InvalidFileException  $e\n     * @return never\n     */\n    protected function writeErrorAndDie(InvalidFileException $e)\n    {\n        $output = (new ConsoleOutput)->getErrorOutput();\n\n        $output->writeln('The environment file is invalid!');\n        $output->writeln($e->getMessage());\n\n        http_response_code(500);\n\n        exit(1);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/RegisterFacades.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Foundation\\AliasLoader;\nuse Illuminate\\Foundation\\PackageManifest;\nuse Illuminate\\Support\\Facades\\Facade;\n\nclass RegisterFacades\n{\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        Facade::clearResolvedInstances();\n\n        Facade::setFacadeApplication($app);\n\n        AliasLoader::getInstance(array_merge(\n            $app->make('config')->get('app.aliases', []),\n            $app->make(PackageManifest::class)->aliases()\n        ))->register();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/RegisterProviders.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass RegisterProviders\n{\n    /**\n     * The service providers that should be merged before registration.\n     *\n     * @var array\n     */\n    protected static $merge = [];\n\n    /**\n     * The path to the bootstrap provider configuration file.\n     *\n     * @var string|null\n     */\n    protected static $bootstrapProviderPath;\n\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        if (! $app->bound('config_loaded_from_cache') ||\n            $app->make('config_loaded_from_cache') === false) {\n            $this->mergeAdditionalProviders($app);\n        }\n\n        $app->registerConfiguredProviders();\n    }\n\n    /**\n     * Merge the additional configured providers into the configuration.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     */\n    protected function mergeAdditionalProviders(Application $app)\n    {\n        if (static::$bootstrapProviderPath &&\n            file_exists(static::$bootstrapProviderPath)) {\n            $packageProviders = require static::$bootstrapProviderPath;\n\n            foreach ($packageProviders as $index => $provider) {\n                if (! class_exists($provider)) {\n                    unset($packageProviders[$index]);\n                }\n            }\n        }\n\n        $app->make('config')->set(\n            'app.providers',\n            array_merge(\n                $app->make('config')->get('app.providers') ?? ServiceProvider::defaultProviders()->toArray(),\n                static::$merge,\n                array_values($packageProviders ?? []),\n            ),\n        );\n    }\n\n    /**\n     * Merge the given providers into the provider configuration before registration.\n     *\n     * @param  array  $providers\n     * @param  string|null  $bootstrapProviderPath\n     * @return void\n     */\n    public static function merge(array $providers, ?string $bootstrapProviderPath = null)\n    {\n        static::$bootstrapProviderPath = $bootstrapProviderPath;\n\n        static::$merge = array_values(array_filter(array_unique(\n            array_merge(static::$merge, $providers)\n        )));\n    }\n\n    /**\n     * Flush the bootstrapper's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$bootstrapProviderPath = null;\n\n        static::$merge = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bootstrap;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Http\\Request;\n\nclass SetRequestForConsole\n{\n    /**\n     * Bootstrap the given application.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public function bootstrap(Application $app)\n    {\n        $uri = $app->make('config')->get('app.url', 'http://localhost');\n\n        $components = parse_url($uri);\n\n        $server = $_SERVER;\n\n        if (isset($components['path'])) {\n            $server = array_merge($server, [\n                'SCRIPT_FILENAME' => $components['path'],\n                'SCRIPT_NAME' => $components['path'],\n            ]);\n        }\n\n        $app->instance('request', Request::create(\n            $uri, 'GET', [], [], [], $server\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bus/Dispatchable.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bus;\n\nuse Closure;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Support\\Fluent;\n\ntrait Dispatchable\n{\n    /**\n     * Dispatch the job with the given arguments.\n     *\n     * @param  mixed  ...$arguments\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public static function dispatch(...$arguments)\n    {\n        return static::newPendingDispatch(new static(...$arguments));\n    }\n\n    /**\n     * Dispatch the job with the given arguments if the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @param  mixed  ...$arguments\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch|\\Illuminate\\Support\\Fluent\n     */\n    public static function dispatchIf($boolean, ...$arguments)\n    {\n        if ($boolean instanceof Closure) {\n            $dispatchable = new static(...$arguments);\n\n            return value($boolean, $dispatchable)\n                ? static::newPendingDispatch($dispatchable)\n                : new Fluent;\n        }\n\n        return value($boolean)\n            ? static::newPendingDispatch(new static(...$arguments))\n            : new Fluent;\n    }\n\n    /**\n     * Dispatch the job with the given arguments unless the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @param  mixed  ...$arguments\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch|\\Illuminate\\Support\\Fluent\n     */\n    public static function dispatchUnless($boolean, ...$arguments)\n    {\n        if ($boolean instanceof Closure) {\n            $dispatchable = new static(...$arguments);\n\n            return ! value($boolean, $dispatchable)\n                ? static::newPendingDispatch($dispatchable)\n                : new Fluent;\n        }\n\n        return ! value($boolean)\n            ? static::newPendingDispatch(new static(...$arguments))\n            : new Fluent;\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public static function dispatchSync(...$arguments)\n    {\n        return app(Dispatcher::class)->dispatchSync(new static(...$arguments));\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler after the current process.\n     *\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public static function dispatchAfterResponse(...$arguments)\n    {\n        return self::dispatch(...$arguments)->afterResponse();\n    }\n\n    /**\n     * Set the jobs that should run if this job is successful.\n     *\n     * @param  array  $chain\n     * @return \\Illuminate\\Foundation\\Bus\\PendingChain\n     */\n    public static function withChain($chain)\n    {\n        return new PendingChain(static::class, $chain);\n    }\n\n    /**\n     * Create a new pending job dispatch instance.\n     *\n     * @param  mixed  $job\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    protected static function newPendingDispatch($job)\n    {\n        return new PendingDispatch($job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bus/DispatchesJobs.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bus;\n\ntrait DispatchesJobs\n{\n    /**\n     * Dispatch a job to its appropriate handler.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    protected function dispatch($job)\n    {\n        return dispatch($job);\n    }\n\n    /**\n     * Dispatch a job to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    public function dispatchSync($job)\n    {\n        return dispatch_sync($job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bus/PendingChain.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bus;\n\nuse Closure;\nuse Illuminate\\Bus\\ChainedBatch;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Laravel\\SerializableClosure\\SerializableClosure;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass PendingChain\n{\n    use Conditionable;\n\n    /**\n     * The class name of the job being dispatched.\n     *\n     * @var mixed\n     */\n    public $job;\n\n    /**\n     * The jobs to be chained.\n     *\n     * @var array\n     */\n    public $chain;\n\n    /**\n     * The name of the connection the chain should be sent to.\n     *\n     * @var string|null\n     */\n    public $connection;\n\n    /**\n     * The name of the queue the chain should be sent to.\n     *\n     * @var string|null\n     */\n    public $queue;\n\n    /**\n     * The number of seconds before the chain should be made available.\n     *\n     * @var \\DateTimeInterface|\\DateInterval|int|null\n     */\n    public $delay;\n\n    /**\n     * The callbacks to be executed on failure.\n     *\n     * @var array\n     */\n    public $catchCallbacks = [];\n\n    /**\n     * Create a new PendingChain instance.\n     *\n     * @param  mixed  $job\n     * @param  array  $chain\n     */\n    public function __construct($job, $chain)\n    {\n        $this->job = $job;\n        $this->chain = $chain;\n    }\n\n    /**\n     * Set the desired connection for the job.\n     *\n     * @param  \\UnitEnum|string|null  $connection\n     * @return $this\n     */\n    public function onConnection($connection)\n    {\n        $this->connection = enum_value($connection);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the job.\n     *\n     * @param  \\UnitEnum|string|null  $queue\n     * @return $this\n     */\n    public function onQueue($queue)\n    {\n        $this->queue = enum_value($queue);\n\n        return $this;\n    }\n\n    /**\n     * Prepend a job to the chain.\n     *\n     * @param  mixed  $job\n     * @return $this\n     */\n    public function prepend($job)\n    {\n        $jobs = ChainedBatch::prepareNestedBatches(\n            Collection::wrap($job)\n        );\n\n        if ($this->job) {\n            array_unshift($this->chain, $this->job);\n        }\n\n        $this->job = $jobs->shift();\n\n        array_unshift($this->chain, ...$jobs->toArray());\n\n        return $this;\n    }\n\n    /**\n     * Append a job to the chain.\n     *\n     * @param  mixed  $job\n     * @return $this\n     */\n    public function append($job)\n    {\n        $jobs = ChainedBatch::prepareNestedBatches(\n            Collection::wrap($job)\n        );\n\n        if (! $this->job) {\n            $this->job = $jobs->shift();\n        }\n\n        array_push($this->chain, ...$jobs->toArray());\n\n        return $this;\n    }\n\n    /**\n     * Set the desired delay in seconds for the chain.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return $this\n     */\n    public function delay($delay)\n    {\n        $this->delay = $delay;\n\n        return $this;\n    }\n\n    /**\n     * Add a callback to be executed on job failure.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function catch($callback)\n    {\n        $this->catchCallbacks[] = $callback instanceof Closure\n            ? new SerializableClosure($callback)\n            : $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the \"catch\" callbacks that have been registered.\n     *\n     * @return array\n     */\n    public function catchCallbacks()\n    {\n        return $this->catchCallbacks ?? [];\n    }\n\n    /**\n     * Dispatch the job chain.\n     *\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public function dispatch()\n    {\n        if (is_string($this->job)) {\n            $firstJob = new $this->job(...func_get_args());\n        } elseif ($this->job instanceof Closure) {\n            $firstJob = CallQueuedClosure::create($this->job);\n        } else {\n            $firstJob = $this->job;\n        }\n\n        if ($this->connection) {\n            $firstJob->chainConnection = $this->connection;\n            $firstJob->connection = $firstJob->connection ?: $this->connection;\n        }\n\n        if ($this->queue) {\n            $firstJob->chainQueue = $this->queue;\n            $firstJob->queue = $firstJob->queue ?: $this->queue;\n        }\n\n        if ($this->delay) {\n            $firstJob->delay = ! is_null($firstJob->delay) ? $firstJob->delay : $this->delay;\n        }\n\n        $firstJob->chain($this->chain);\n        $firstJob->chainCatchCallbacks = $this->catchCallbacks();\n\n        return app(Dispatcher::class)->dispatch($firstJob);\n    }\n\n    /**\n     * Dispatch the job chain if the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch|null\n     */\n    public function dispatchIf($boolean)\n    {\n        return value($boolean) ? $this->dispatch() : null;\n    }\n\n    /**\n     * Dispatch the job chain unless the given truth test passes.\n     *\n     * @param  bool|\\Closure  $boolean\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch|null\n     */\n    public function dispatchUnless($boolean)\n    {\n        return ! value($boolean) ? $this->dispatch() : null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bus/PendingClosureDispatch.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bus;\n\nuse Closure;\n\nclass PendingClosureDispatch extends PendingDispatch\n{\n    /**\n     * Add a callback to be executed if the job fails.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function catch(Closure $callback)\n    {\n        $this->job->onFailure($callback);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Bus/PendingDispatch.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Bus;\n\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Foundation\\Queue\\InteractsWithUniqueJobs;\n\nclass PendingDispatch\n{\n    use InteractsWithUniqueJobs;\n\n    /**\n     * The job.\n     *\n     * @var mixed\n     */\n    protected $job;\n\n    /**\n     * Indicates if the job should be dispatched immediately after sending the response.\n     *\n     * @var bool\n     */\n    protected $afterResponse = false;\n\n    /**\n     * Create a new pending job dispatch.\n     *\n     * @param  mixed  $job\n     */\n    public function __construct($job)\n    {\n        $this->job = $job;\n    }\n\n    /**\n     * Set the desired connection for the job.\n     *\n     * @param  \\BackedEnum|string|null  $connection\n     * @return $this\n     */\n    public function onConnection($connection)\n    {\n        $this->job->onConnection($connection);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the job.\n     *\n     * @param  \\BackedEnum|string|null  $queue\n     * @return $this\n     */\n    public function onQueue($queue)\n    {\n        $this->job->onQueue($queue);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job \"group\".\n     *\n     * This feature is only supported by some queues, such as Amazon SQS.\n     *\n     * @param  \\UnitEnum|string  $group\n     * @return $this\n     */\n    public function onGroup($group)\n    {\n        $this->job->onGroup($group);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired job deduplicator callback.\n     *\n     * This feature is only supported by some queues, such as Amazon SQS FIFO.\n     *\n     * @param  callable|null  $deduplicator\n     * @return $this\n     */\n    public function withDeduplicator($deduplicator)\n    {\n        $this->job->withDeduplicator($deduplicator);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired connection for the chain.\n     *\n     * @param  \\BackedEnum|string|null  $connection\n     * @return $this\n     */\n    public function allOnConnection($connection)\n    {\n        $this->job->allOnConnection($connection);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired queue for the chain.\n     *\n     * @param  \\BackedEnum|string|null  $queue\n     * @return $this\n     */\n    public function allOnQueue($queue)\n    {\n        $this->job->allOnQueue($queue);\n\n        return $this;\n    }\n\n    /**\n     * Set the desired delay in seconds for the job.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return $this\n     */\n    public function delay($delay)\n    {\n        $this->job->delay($delay);\n\n        return $this;\n    }\n\n    /**\n     * Set the delay for the job to zero seconds.\n     *\n     * @return $this\n     */\n    public function withoutDelay()\n    {\n        $this->job->withoutDelay();\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should be dispatched after all database transactions have committed.\n     *\n     * @return $this\n     */\n    public function afterCommit()\n    {\n        $this->job->afterCommit();\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should not wait until database transactions have been committed before dispatching.\n     *\n     * @return $this\n     */\n    public function beforeCommit()\n    {\n        $this->job->beforeCommit();\n\n        return $this;\n    }\n\n    /**\n     * Set the jobs that should run if this job is successful.\n     *\n     * @param  array  $chain\n     * @return $this\n     */\n    public function chain($chain)\n    {\n        $this->job->chain($chain);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the job should be dispatched after the response is sent to the browser.\n     *\n     * @param  bool  $afterResponse\n     * @return $this\n     */\n    public function afterResponse($afterResponse = true)\n    {\n        $this->afterResponse = $afterResponse;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the job should be dispatched.\n     *\n     * @return bool\n     */\n    protected function shouldDispatch()\n    {\n        if (! $this->job instanceof ShouldBeUnique) {\n            return true;\n        }\n\n        return (new UniqueLock(Container::getInstance()->make(Cache::class)))\n            ->acquire($this->job);\n    }\n\n    /**\n     * Get the underlying job instance.\n     *\n     * @return mixed\n     */\n    public function getJob()\n    {\n        return $this->job;\n    }\n\n    /**\n     * Dynamically proxy methods to the underlying job.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function __call($method, $parameters)\n    {\n        $this->job->{$method}(...$parameters);\n\n        return $this;\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        $this->addUniqueJobInformationToContext($this->job);\n\n        if (! $this->shouldDispatch()) {\n            $this->removeUniqueJobInformationFromContext($this->job);\n\n            return;\n        } elseif ($this->afterResponse) {\n            app(Dispatcher::class)->dispatchAfterResponse($this->job);\n        } else {\n            app(Dispatcher::class)->dispatch($this->job);\n        }\n\n        $this->removeUniqueJobInformationFromContext($this->job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/CacheBasedMaintenanceMode.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode;\n\nclass CacheBasedMaintenanceMode implements MaintenanceMode\n{\n    /**\n     * The cache factory.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    protected $cache;\n\n    /**\n     * The cache store that should be utilized.\n     *\n     * @var string\n     */\n    protected $store;\n\n    /**\n     * The cache key to use when storing maintenance mode information.\n     *\n     * @var string\n     */\n    protected $key;\n\n    /**\n     * Create a new cache based maintenance mode implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Factory  $cache\n     * @param  string  $store\n     * @param  string  $key\n     */\n    public function __construct(Factory $cache, string $store, string $key)\n    {\n        $this->cache = $cache;\n        $this->store = $store;\n        $this->key = $key;\n    }\n\n    /**\n     * Take the application down for maintenance.\n     *\n     * @param  array  $payload\n     * @return void\n     */\n    public function activate(array $payload): void\n    {\n        $this->getStore()->put($this->key, $payload);\n    }\n\n    /**\n     * Take the application out of maintenance.\n     *\n     * @return void\n     */\n    public function deactivate(): void\n    {\n        $this->getStore()->forget($this->key);\n    }\n\n    /**\n     * Determine if the application is currently down for maintenance.\n     *\n     * @return bool\n     */\n    public function active(): bool\n    {\n        return $this->getStore()->has($this->key);\n    }\n\n    /**\n     * Get the data array which was provided when the application was placed into maintenance.\n     *\n     * @return array\n     */\n    public function data(): array\n    {\n        return $this->getStore()->get($this->key);\n    }\n\n    /**\n     * Get the cache store to use.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected function getStore(): Repository\n    {\n        return $this->cache->store($this->store);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Cloud.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Foundation\\Bootstrap\\HandleExceptions;\nuse Illuminate\\Foundation\\Bootstrap\\LoadConfiguration;\nuse Monolog\\Formatter\\JsonFormatter;\nuse Monolog\\Handler\\SocketHandler;\nuse PDO;\n\nclass Cloud\n{\n    /**\n     * Handle a bootstrapper that is bootstrapping.\n     */\n    public static function bootstrapperBootstrapping(Application $app, string $bootstrapper): void\n    {\n        //\n    }\n\n    /**\n     * Handle a bootstrapper that has bootstrapped.\n     */\n    public static function bootstrapperBootstrapped(Application $app, string $bootstrapper): void\n    {\n        (match ($bootstrapper) {\n            LoadConfiguration::class => function () use ($app) {\n                static::configureDisks($app);\n                static::configureUnpooledPostgresConnection($app);\n                static::ensureMigrationsUseUnpooledConnection($app);\n            },\n            HandleExceptions::class => function () use ($app) {\n                static::configureCloudLogging($app);\n            },\n            default => fn () => true,\n        })();\n    }\n\n    /**\n     * Configure the Laravel Cloud disks if applicable.\n     */\n    public static function configureDisks(Application $app): void\n    {\n        if (! isset($_SERVER['LARAVEL_CLOUD_DISK_CONFIG'])) {\n            return;\n        }\n\n        $disks = json_decode($_SERVER['LARAVEL_CLOUD_DISK_CONFIG'], true);\n\n        foreach ($disks as $disk) {\n            $app['config']->set('filesystems.disks.'.$disk['disk'], [\n                'driver' => 's3',\n                'key' => $disk['access_key_id'],\n                'secret' => $disk['access_key_secret'],\n                'bucket' => $disk['bucket'],\n                'url' => $disk['url'],\n                'endpoint' => $disk['endpoint'],\n                'region' => 'auto',\n                'use_path_style_endpoint' => false,\n                'throw' => false,\n                'report' => false,\n            ]);\n\n            if ($disk['is_default'] ?? false) {\n                $app['config']->set('filesystems.default', $disk['disk']);\n            }\n        }\n    }\n\n    /**\n     * Configure the unpooled Laravel Postgres connection if applicable.\n     */\n    public static function configureUnpooledPostgresConnection(Application $app): void\n    {\n        $host = $app['config']->get('database.connections.pgsql.host', '');\n\n        if (str_contains($host, 'pg.laravel.cloud') &&\n            str_contains($host, '-pooler')) {\n            $app['config']->set(\n                'database.connections.pgsql-unpooled',\n                array_merge($app['config']->get('database.connections.pgsql'), [\n                    'host' => str_replace('-pooler', '', $host),\n                ])\n            );\n\n            $app['config']->set(\n                'database.connections.pgsql.options',\n                array_merge(\n                    $app['config']->get('database.connections.pgsql.options', []),\n                    [PDO::ATTR_EMULATE_PREPARES => true],\n                ),\n            );\n        }\n    }\n\n    /**\n     * Ensure that migrations use the unpooled Postgres connection if applicable.\n     */\n    public static function ensureMigrationsUseUnpooledConnection(Application $app): void\n    {\n        if (! is_array($app['config']->get('database.connections.pgsql-unpooled'))) {\n            return;\n        }\n\n        Migrator::resolveConnectionsUsing(function ($resolver, $connection) use ($app) {\n            $connection = $connection ?? $app['config']->get('database.default');\n\n            return $resolver->connection(\n                $connection === 'pgsql' ? 'pgsql-unpooled' : $connection\n            );\n        });\n    }\n\n    /**\n     * Configure the Laravel Cloud log channels.\n     */\n    public static function configureCloudLogging(Application $app): void\n    {\n        $app['config']->set('logging.channels.stderr.formatter_with', [\n            'includeStacktraces' => true,\n        ]);\n\n        $app['config']->set('logging.channels.laravel-cloud-socket', [\n            'driver' => 'monolog',\n            'level' => $_ENV['LOG_LEVEL'] ?? $_SERVER['LOG_LEVEL'] ?? 'debug',\n            'handler' => SocketHandler::class,\n            'formatter' => JsonFormatter::class,\n            'formatter_with' => [\n                'includeStacktraces' => true,\n            ],\n            'with' => [\n                'connectionString' => $_ENV['LARAVEL_CLOUD_LOG_SOCKET'] ??\n                                      $_SERVER['LARAVEL_CLOUD_LOG_SOCKET'] ??\n                                      'unix:///tmp/cloud-init.sock',\n                'persistent' => true,\n            ],\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/ComposerScripts.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Composer\\Installer\\PackageEvent;\nuse Composer\\IO\\IOInterface;\nuse Composer\\Script\\Event;\nuse Illuminate\\Concurrency\\ProcessDriver;\nuse Illuminate\\Encryption\\EncryptionServiceProvider;\nuse Illuminate\\Foundation\\Bootstrap\\LoadConfiguration;\nuse Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables;\nuse Throwable;\n\nclass ComposerScripts\n{\n    /**\n     * Handle the post-install Composer event.\n     *\n     * @param  \\Composer\\Script\\Event  $event\n     * @return void\n     */\n    public static function postInstall(Event $event)\n    {\n        require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php';\n\n        static::clearCompiled();\n    }\n\n    /**\n     * Handle the post-update Composer event.\n     *\n     * @param  \\Composer\\Script\\Event  $event\n     * @return void\n     */\n    public static function postUpdate(Event $event)\n    {\n        require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php';\n\n        static::clearCompiled();\n    }\n\n    /**\n     * Handle the post-autoload-dump Composer event.\n     *\n     * @param  \\Composer\\Script\\Event  $event\n     * @return void\n     */\n    public static function postAutoloadDump(Event $event)\n    {\n        require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php';\n\n        static::clearCompiled();\n    }\n\n    /**\n     * Handle the pre-package-uninstall Composer event.\n     *\n     * @param  \\Composer\\Installer\\PackageEvent  $event\n     * @return void\n     */\n    public static function prePackageUninstall(PackageEvent $event)\n    {\n        // Package uninstall events are only applicable when uninstalling packages in dev environments...\n        if (! $event->isDevMode()) {\n            return;\n        }\n\n        $eventName = null;\n        try {\n            require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php';\n\n            $laravel = new Application(getcwd());\n\n            $laravel->bootstrapWith([\n                LoadEnvironmentVariables::class,\n                LoadConfiguration::class,\n            ]);\n\n            // Ensure we can encrypt our serializable closure...\n            (new EncryptionServiceProvider($laravel))->register();\n\n            $name = $event->getOperation()->getPackage()->getName();\n            $eventName = \"composer_package.{$name}:pre_uninstall\";\n\n            $laravel->make(ProcessDriver::class)->run(\n                static fn () => app()['events']->dispatch($eventName)\n            );\n        } catch (Throwable $e) {\n            // Ignore any errors to allow the package removal to complete...\n            $event->getIO()->write('There was an error dispatching or handling the ['.($eventName ?? 'unknown').'] event. Continuing with package removal...');\n            $event->getIO()->writeError('Exception message: '.$e->getMessage(), verbosity: IOInterface::VERBOSE); // @phpstan-ignore class.notFound (Composer exists if this is running)\n        }\n    }\n\n    /**\n     * Clear the cached Laravel bootstrapping files.\n     *\n     * @return void\n     */\n    protected static function clearCompiled()\n    {\n        $laravel = new Application(getcwd());\n\n        if (is_file($configPath = $laravel->getCachedConfigPath())) {\n            @unlink($configPath);\n        }\n\n        if (is_file($servicesPath = $laravel->getCachedServicesPath())) {\n            @unlink($servicesPath);\n        }\n\n        if (is_file($packagesPath = $laravel->getCachedPackagesPath())) {\n            @unlink($packagesPath);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Concerns/ResolvesDumpSource.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Concerns;\n\nuse Illuminate\\Support\\Str;\nuse Throwable;\n\ntrait ResolvesDumpSource\n{\n    /**\n     * All of the href formats for common editors.\n     *\n     * @var array<string, string>\n     */\n    protected $editorHrefs = [\n        'antigravity' => 'antigravity://file/{file}:{line}',\n        'atom' => 'atom://core/open/file?filename={file}&line={line}',\n        'cursor' => 'cursor://file/{file}:{line}',\n        'emacs' => 'emacs://open?url=file://{file}&line={line}',\n        'fleet' => 'fleet://open?file={file}&line={line}',\n        'idea' => 'idea://open?file={file}&line={line}',\n        'kiro' => 'kiro://file/{file}:{line}',\n        'macvim' => 'mvim://open/?url=file://{file}&line={line}',\n        'neovim' => 'nvim://open?url=file://{file}&line={line}',\n        'netbeans' => 'netbeans://open/?f={file}:{line}',\n        'nova' => 'nova://core/open/file?filename={file}&line={line}',\n        'phpstorm' => 'phpstorm://open?file={file}&line={line}',\n        'sublime' => 'subl://open?url=file://{file}&line={line}',\n        'textmate' => 'txmt://open?url=file://{file}&line={line}',\n        'trae' => 'trae://file/{file}:{line}',\n        'vscode' => 'vscode://file/{file}:{line}',\n        'vscode-insiders' => 'vscode-insiders://file/{file}:{line}',\n        'vscode-insiders-remote' => 'vscode-insiders://vscode-remote/{file}:{line}',\n        'vscode-remote' => 'vscode://vscode-remote/{file}:{line}',\n        'vscodium' => 'vscodium://file/{file}:{line}',\n        'windsurf' => 'windsurf://file/{file}:{line}',\n        'xdebug' => 'xdebug://{file}@{line}',\n        'zed' => 'zed://file/{file}:{line}',\n    ];\n\n    /**\n     * Files that require special trace handling and their levels.\n     *\n     * @var array<string, int>\n     */\n    protected static $adjustableTraces = [\n        'symfony/var-dumper/Resources/functions/dump.php' => 1,\n        'Illuminate/Collections/Traits/EnumeratesValues.php' => 4,\n    ];\n\n    /**\n     * The source resolver.\n     *\n     * @var (callable(): (array{0: string, 1: string, 2: int|null}|null))|null|false\n     */\n    protected static $dumpSourceResolver;\n\n    /**\n     * Resolve the source of the dump call.\n     *\n     * @return array{0: string, 1: string, 2: int|null}|null\n     */\n    public function resolveDumpSource()\n    {\n        if (static::$dumpSourceResolver === false) {\n            return null;\n        }\n\n        if (static::$dumpSourceResolver) {\n            return call_user_func(static::$dumpSourceResolver);\n        }\n\n        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 20);\n\n        $sourceKey = null;\n\n        foreach ($trace as $traceKey => $traceFile) {\n            if (! isset($traceFile['file'])) {\n                continue;\n            }\n\n            foreach (self::$adjustableTraces as $name => $key) {\n                if (str_ends_with(\n                    $traceFile['file'],\n                    str_replace('/', DIRECTORY_SEPARATOR, $name)\n                )) {\n                    $sourceKey = $traceKey + $key;\n                    break;\n                }\n            }\n\n            if (! is_null($sourceKey)) {\n                break;\n            }\n        }\n\n        if (is_null($sourceKey)) {\n            return;\n        }\n\n        $file = $trace[$sourceKey]['file'] ?? null;\n        $line = $trace[$sourceKey]['line'] ?? null;\n\n        if (is_null($file) || is_null($line)) {\n            return;\n        }\n\n        $relativeFile = $file;\n\n        if ($this->isCompiledViewFile($file)) {\n            $file = $this->getOriginalFileForCompiledView($file);\n            $line = null;\n        }\n\n        if (str_starts_with($file, $this->basePath)) {\n            $relativeFile = substr($file, strlen($this->basePath) + 1);\n        }\n\n        return [$file, $relativeFile, $line];\n    }\n\n    /**\n     * Determine if the given file is a view compiled.\n     *\n     * @param  string  $file\n     * @return bool\n     */\n    protected function isCompiledViewFile($file)\n    {\n        return str_starts_with($file, $this->compiledViewPath) && str_ends_with($file, '.php');\n    }\n\n    /**\n     * Get the original view compiled file by the given compiled file.\n     *\n     * @param  string  $file\n     * @return string\n     */\n    protected function getOriginalFileForCompiledView($file)\n    {\n        preg_match('/\\/\\*\\*PATH\\s(.*)\\sENDPATH/', file_get_contents($file), $matches);\n\n        if (isset($matches[1])) {\n            $file = $matches[1];\n        }\n\n        return $file;\n    }\n\n    /**\n     * Resolve the source href, if possible.\n     *\n     * @param  string  $file\n     * @param  int|null  $line\n     * @return string|null\n     */\n    protected function resolveSourceHref($file, $line)\n    {\n        try {\n            $editor = config('app.editor');\n        } catch (Throwable) {\n            // ..\n        }\n\n        if (! isset($editor)) {\n            return;\n        }\n\n        $href = is_array($editor) && isset($editor['href'])\n            ? $editor['href']\n            : ($this->editorHrefs[$editor['name'] ?? $editor] ?? sprintf('%s://open?file={file}&line={line}', $editor['name'] ?? $editor));\n\n        $basePath = $editor['base_path'] ?? false;\n\n        if ($basePath !== false) {\n            $file = Str::replaceStart($this->basePath, $basePath, $file);\n        }\n\n        return str_replace(\n            ['{file}', '{line}'],\n            [$file, is_null($line) ? 1 : $line],\n            $href,\n        );\n    }\n\n    /**\n     * Set the resolver that resolves the source of the dump call.\n     *\n     * @param  (callable(): (array{0: string, 1: string, 2: int|null}|null))|null  $callable\n     * @return void\n     */\n    public static function resolveDumpSourceUsing($callable)\n    {\n        static::$dumpSourceResolver = $callable;\n    }\n\n    /**\n     * Don't include the location / file of the dump in dumps.\n     *\n     * @return void\n     */\n    public static function dontIncludeSource()\n    {\n        static::$dumpSourceResolver = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Configuration/ApplicationBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Configuration;\n\nuse Closure;\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernel;\nuse Illuminate\\Contracts\\Http\\Kernel as HttpKernel;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\RegisterProviders;\nuse Illuminate\\Foundation\\Events\\DiagnosingHealth;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Foundation\\Support\\Providers\\EventServiceProvider as AppEventServiceProvider;\nuse Illuminate\\Foundation\\Support\\Providers\\RouteServiceProvider as AppRouteServiceProvider;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Broadcast;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\View;\nuse Laravel\\Folio\\Folio;\n\nclass ApplicationBuilder\n{\n    /**\n     * The service provider that are marked for registration.\n     *\n     * @var array\n     */\n    protected array $pendingProviders = [];\n\n    /**\n     * Any additional routing callbacks that should be invoked while registering routes.\n     *\n     * @var array\n     */\n    protected array $additionalRoutingCallbacks = [];\n\n    /**\n     * The Folio / page middleware that have been defined by the user.\n     *\n     * @var array\n     */\n    protected array $pageMiddleware = [];\n\n    /**\n     * Create a new application builder instance.\n     */\n    public function __construct(protected Application $app)\n    {\n    }\n\n    /**\n     * Register the standard kernel classes for the application.\n     *\n     * @return $this\n     */\n    public function withKernels()\n    {\n        $this->app->singleton(\n            \\Illuminate\\Contracts\\Http\\Kernel::class,\n            \\Illuminate\\Foundation\\Http\\Kernel::class,\n        );\n\n        $this->app->singleton(\n            \\Illuminate\\Contracts\\Console\\Kernel::class,\n            \\Illuminate\\Foundation\\Console\\Kernel::class,\n        );\n\n        return $this;\n    }\n\n    /**\n     * Register additional service providers.\n     *\n     * @param  array  $providers\n     * @param  bool  $withBootstrapProviders\n     * @return $this\n     */\n    public function withProviders(array $providers = [], bool $withBootstrapProviders = true)\n    {\n        RegisterProviders::merge(\n            $providers,\n            $withBootstrapProviders\n                ? $this->app->getBootstrapProvidersPath()\n                : null\n        );\n\n        return $this;\n    }\n\n    /**\n     * Register the core event service provider for the application.\n     *\n     * @param  iterable<int, string>|bool  $discover\n     * @return $this\n     */\n    public function withEvents(iterable|bool $discover = true)\n    {\n        if (is_iterable($discover)) {\n            AppEventServiceProvider::setEventDiscoveryPaths($discover);\n        }\n\n        if ($discover === false) {\n            AppEventServiceProvider::disableEventDiscovery();\n        }\n\n        if (! isset($this->pendingProviders[AppEventServiceProvider::class])) {\n            $this->app->booting(function () {\n                $this->app->register(AppEventServiceProvider::class);\n            });\n        }\n\n        $this->pendingProviders[AppEventServiceProvider::class] = true;\n\n        return $this;\n    }\n\n    /**\n     * Register the broadcasting services for the application.\n     *\n     * @param  string  $channels\n     * @param  array  $attributes\n     * @return $this\n     */\n    public function withBroadcasting(string $channels, array $attributes = [])\n    {\n        $this->app->booted(function () use ($channels, $attributes) {\n            Broadcast::routes(! empty($attributes) ? $attributes : null);\n\n            if (file_exists($channels)) {\n                require $channels;\n            }\n        });\n\n        return $this;\n    }\n\n    /**\n     * Register the routing services for the application.\n     *\n     * @param  \\Closure|null  $using\n     * @param  array|string|null  $web\n     * @param  array|string|null  $api\n     * @param  string|null  $commands\n     * @param  string|null  $channels\n     * @param  string|null  $pages\n     * @param  string  $apiPrefix\n     * @param  callable|null  $then\n     * @return $this\n     */\n    public function withRouting(?Closure $using = null,\n        array|string|null $web = null,\n        array|string|null $api = null,\n        ?string $commands = null,\n        ?string $channels = null,\n        ?string $pages = null,\n        ?string $health = null,\n        string $apiPrefix = 'api',\n        ?callable $then = null)\n    {\n        if (is_null($using) && (is_string($web) || is_array($web) || is_string($api) || is_array($api) || is_string($pages) || is_string($health)) || is_callable($then)) {\n            $using = $this->buildRoutingCallback($web, $api, $pages, $health, $apiPrefix, $then);\n\n            if (is_string($health)) {\n                PreventRequestsDuringMaintenance::except($health);\n            }\n        }\n\n        AppRouteServiceProvider::loadRoutesUsing($using);\n\n        $this->app->booting(function () {\n            $this->app->register(AppRouteServiceProvider::class, force: true);\n        });\n\n        if (is_string($commands) && realpath($commands) !== false) {\n            $this->withCommands([$commands]);\n        }\n\n        if (is_string($channels) && realpath($channels) !== false) {\n            $this->withBroadcasting($channels);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Create the routing callback for the application.\n     *\n     * @param  array|string|null  $web\n     * @param  array|string|null  $api\n     * @param  string|null  $pages\n     * @param  string|null  $health\n     * @param  string  $apiPrefix\n     * @param  callable|null  $then\n     * @return \\Closure\n     *\n     * @throws \\Throwable\n     */\n    protected function buildRoutingCallback(array|string|null $web,\n        array|string|null $api,\n        ?string $pages,\n        ?string $health,\n        string $apiPrefix,\n        ?callable $then)\n    {\n        return function () use ($web, $api, $pages, $health, $apiPrefix, $then) {\n            if (is_string($api) || is_array($api)) {\n                if (is_array($api)) {\n                    foreach ($api as $apiRoute) {\n                        if (realpath($apiRoute) !== false) {\n                            Route::middleware('api')->prefix($apiPrefix)->group($apiRoute);\n                        }\n                    }\n                } else {\n                    Route::middleware('api')->prefix($apiPrefix)->group($api);\n                }\n            }\n\n            if (is_string($health)) {\n                Route::get($health, function () {\n                    $exception = null;\n\n                    try {\n                        Event::dispatch(new DiagnosingHealth);\n                    } catch (\\Throwable $e) {\n                        if (app()->hasDebugModeEnabled()) {\n                            throw $e;\n                        }\n\n                        report($e);\n\n                        $exception = $e->getMessage();\n                    }\n\n                    return response(View::file(__DIR__.'/../resources/health-up.blade.php', [\n                        'exception' => $exception,\n                    ]), status: $exception ? 500 : 200);\n                });\n            }\n\n            if (is_string($web) || is_array($web)) {\n                if (is_array($web)) {\n                    foreach ($web as $webRoute) {\n                        if (realpath($webRoute) !== false) {\n                            Route::middleware('web')->group($webRoute);\n                        }\n                    }\n                } else {\n                    Route::middleware('web')->group($web);\n                }\n            }\n\n            foreach ($this->additionalRoutingCallbacks as $callback) {\n                $callback();\n            }\n\n            if (is_string($pages) &&\n                realpath($pages) !== false &&\n                class_exists(Folio::class)) {\n                Folio::route($pages, middleware: $this->pageMiddleware);\n            }\n\n            if (is_callable($then)) {\n                $then($this->app);\n            }\n        };\n    }\n\n    /**\n     * Register the global middleware, middleware groups, and middleware aliases for the application.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     */\n    public function withMiddleware(?callable $callback = null)\n    {\n        $this->app->afterResolving(HttpKernel::class, function ($kernel) use ($callback) {\n            $middleware = (new Middleware)\n                ->redirectGuestsTo(fn () => route('login'));\n\n            if (! is_null($callback)) {\n                $callback($middleware);\n            }\n\n            $this->pageMiddleware = $middleware->getPageMiddleware();\n            $kernel->setGlobalMiddleware($middleware->getGlobalMiddleware());\n            $kernel->setMiddlewareGroups($middleware->getMiddlewareGroups());\n            $kernel->setMiddlewareAliases($middleware->getMiddlewareAliases());\n\n            if ($priorities = $middleware->getMiddlewarePriority()) {\n                $kernel->setMiddlewarePriority($priorities);\n            }\n\n            if ($priorityAppends = $middleware->getMiddlewarePriorityAppends()) {\n                foreach ($priorityAppends as $newMiddleware => $after) {\n                    $kernel->addToMiddlewarePriorityAfter($after, $newMiddleware);\n                }\n            }\n\n            if ($priorityPrepends = $middleware->getMiddlewarePriorityPrepends()) {\n                foreach ($priorityPrepends as $newMiddleware => $before) {\n                    $kernel->addToMiddlewarePriorityBefore($before, $newMiddleware);\n                }\n            }\n        });\n\n        $this->app->afterResolving(ConsoleKernel::class, function () use ($callback) {\n            if (! is_null($callback)) {\n                $callback(new Middleware);\n            }\n        });\n\n        return $this;\n    }\n\n    /**\n     * Register additional Artisan commands with the application.\n     *\n     * @param  array  $commands\n     * @return $this\n     */\n    public function withCommands(array $commands = [])\n    {\n        if (empty($commands)) {\n            $commands = [$this->app->path('Console/Commands')];\n        }\n\n        $this->app->afterResolving(ConsoleKernel::class, function ($kernel) use ($commands) {\n            [$commands, $paths] = (new Collection($commands))->partition(fn ($command) => class_exists($command));\n            [$routes, $paths] = $paths->partition(fn ($path) => is_file($path));\n\n            $this->app->booted(static function () use ($kernel, $commands, $paths, $routes) {\n                $kernel->addCommands($commands->all());\n                $kernel->addCommandPaths($paths->all());\n                $kernel->addCommandRoutePaths($routes->all());\n            });\n        });\n\n        return $this;\n    }\n\n    /**\n     * Register additional Artisan route paths.\n     *\n     * @param  array  $paths\n     * @return $this\n     */\n    protected function withCommandRouting(array $paths)\n    {\n        $this->app->afterResolving(ConsoleKernel::class, function ($kernel) use ($paths) {\n            $this->app->booted(fn () => $kernel->addCommandRoutePaths($paths));\n        });\n\n        return $this;\n    }\n\n    /**\n     * Register the scheduled tasks for the application.\n     *\n     * @param  callable(\\Illuminate\\Console\\Scheduling\\Schedule $schedule): void  $callback\n     * @return $this\n     */\n    public function withSchedule(callable $callback)\n    {\n        Artisan::starting(function () use ($callback) {\n            $this->app->afterResolving(Schedule::class, fn ($schedule) => $callback($schedule));\n\n            if ($this->app->resolved(Schedule::class)) {\n                $callback($this->app->make(Schedule::class));\n            }\n        });\n\n        return $this;\n    }\n\n    /**\n     * Register and configure the application's exception handler.\n     *\n     * @param  callable(\\Illuminate\\Foundation\\Configuration\\Exceptions)|null  $using\n     * @return $this\n     */\n    public function withExceptions(?callable $using = null)\n    {\n        $this->app->singleton(\n            \\Illuminate\\Contracts\\Debug\\ExceptionHandler::class,\n            \\Illuminate\\Foundation\\Exceptions\\Handler::class\n        );\n\n        if ($using !== null) {\n            $this->app->afterResolving(\n                \\Illuminate\\Foundation\\Exceptions\\Handler::class,\n                fn ($handler) => $using(new Exceptions($handler)),\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register an array of container bindings to be bound when the application is booting.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function withBindings(array $bindings)\n    {\n        return $this->registered(function ($app) use ($bindings) {\n            foreach ($bindings as $abstract => $concrete) {\n                $app->bind($abstract, $concrete);\n            }\n        });\n    }\n\n    /**\n     * Register an array of singleton container bindings to be bound when the application is booting.\n     *\n     * @param  array  $singletons\n     * @return $this\n     */\n    public function withSingletons(array $singletons)\n    {\n        return $this->registered(function ($app) use ($singletons) {\n            foreach ($singletons as $abstract => $concrete) {\n                if (is_string($abstract)) {\n                    $app->singleton($abstract, $concrete);\n                } else {\n                    $app->singleton($concrete);\n                }\n            }\n        });\n    }\n\n    /**\n     * Register an array of scoped singleton container bindings to be bound when the application is booting.\n     *\n     * @param  array  $scopedSingletons\n     * @return $this\n     */\n    public function withScopedSingletons(array $scopedSingletons)\n    {\n        return $this->registered(function ($app) use ($scopedSingletons) {\n            foreach ($scopedSingletons as $abstract => $concrete) {\n                if (is_string($abstract)) {\n                    $app->scoped($abstract, $concrete);\n                } else {\n                    $app->scoped($concrete);\n                }\n            }\n        });\n    }\n\n    /**\n     * Register a callback to be invoked when the application's service providers are registered.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function registered(callable $callback)\n    {\n        $this->app->registered($callback);\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be invoked when the application is \"booting\".\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function booting(callable $callback)\n    {\n        $this->app->booting($callback);\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be invoked when the application is \"booted\".\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function booted(callable $callback)\n    {\n        $this->app->booted($callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the application instance.\n     *\n     * @return \\Illuminate\\Foundation\\Application\n     */\n    public function create()\n    {\n        return $this->app;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Configuration/Exceptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Configuration;\n\nuse Closure;\nuse Illuminate\\Foundation\\Exceptions\\Handler;\nuse Illuminate\\Http\\Client\\RequestException;\nuse Illuminate\\Support\\Arr;\n\nclass Exceptions\n{\n    /**\n     * Create a new exception handling configuration instance.\n     *\n     * @param  \\Illuminate\\Foundation\\Exceptions\\Handler  $handler\n     */\n    public function __construct(public Handler $handler)\n    {\n    }\n\n    /**\n     * Register a reportable callback.\n     *\n     * @param  callable  $using\n     * @return \\Illuminate\\Foundation\\Exceptions\\ReportableHandler\n     */\n    public function report(callable $using)\n    {\n        return $this->handler->reportable($using);\n    }\n\n    /**\n     * Register a reportable callback.\n     *\n     * @param  callable  $reportUsing\n     * @return \\Illuminate\\Foundation\\Exceptions\\ReportableHandler\n     */\n    public function reportable(callable $reportUsing)\n    {\n        return $this->handler->reportable($reportUsing);\n    }\n\n    /**\n     * Register a renderable callback.\n     *\n     * @param  callable  $using\n     * @return $this\n     */\n    public function render(callable $using)\n    {\n        $this->handler->renderable($using);\n\n        return $this;\n    }\n\n    /**\n     * Register a renderable callback.\n     *\n     * @param  callable  $renderUsing\n     * @return $this\n     */\n    public function renderable(callable $renderUsing)\n    {\n        $this->handler->renderable($renderUsing);\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to prepare the final, rendered exception response.\n     *\n     * @param  callable  $using\n     * @return $this\n     */\n    public function respond(callable $using)\n    {\n        $this->handler->respondUsing($using);\n\n        return $this;\n    }\n\n    /**\n     * Specify the callback that should be used to throttle reportable exceptions.\n     *\n     * @param  callable  $throttleUsing\n     * @return $this\n     */\n    public function throttle(callable $throttleUsing)\n    {\n        $this->handler->throttleUsing($throttleUsing);\n\n        return $this;\n    }\n\n    /**\n     * Register a new exception mapping.\n     *\n     * @param  \\Closure|string  $from\n     * @param  \\Closure|string|null  $to\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function map($from, $to = null)\n    {\n        $this->handler->map($from, $to);\n\n        return $this;\n    }\n\n    /**\n     * Set the log level for the given exception type.\n     *\n     * @param  class-string<\\Throwable>  $type\n     * @param  \\Psr\\Log\\LogLevel::*  $level\n     * @return $this\n     */\n    public function level(string $type, string $level)\n    {\n        $this->handler->level($type, $level);\n\n        return $this;\n    }\n\n    /**\n     * Register a closure that should be used to build exception context data.\n     *\n     * @param  \\Closure  $contextCallback\n     * @return $this\n     */\n    public function context(Closure $contextCallback)\n    {\n        $this->handler->buildContextUsing($contextCallback);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given exception type should not be reported.\n     *\n     * @param  array|string  $class\n     * @return $this\n     */\n    public function dontReport(array|string $class)\n    {\n        foreach (Arr::wrap($class) as $exceptionClass) {\n            $this->handler->dontReport($exceptionClass);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to determine if an exception should not be reported.\n     *\n     * @param  (\\Closure(\\Throwable): bool)  $dontReportWhen\n     * @return $this\n     */\n    public function dontReportWhen(Closure $dontReportWhen)\n    {\n        $this->handler->dontReportWhen($dontReportWhen);\n\n        return $this;\n    }\n\n    /**\n     * Do not report duplicate exceptions.\n     *\n     * @return $this\n     */\n    public function dontReportDuplicates()\n    {\n        $this->handler->dontReportDuplicates();\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given attributes should never be flashed to the session on validation errors.\n     *\n     * @param  array|string  $attributes\n     * @return $this\n     */\n    public function dontFlash(array|string $attributes)\n    {\n        $this->handler->dontFlash($attributes);\n\n        return $this;\n    }\n\n    /**\n     * Register the callable that determines if the exception handler response should be JSON.\n     *\n     * @param  callable(\\Illuminate\\Http\\Request $request, \\Throwable): bool  $callback\n     * @return $this\n     */\n    public function shouldRenderJsonWhen(callable $callback)\n    {\n        $this->handler->shouldRenderJsonWhen($callback);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given exception class should not be ignored.\n     *\n     * @param  array<int, class-string<\\Throwable>>|class-string<\\Throwable>  $class\n     * @return $this\n     */\n    public function stopIgnoring(array|string $class)\n    {\n        $this->handler->stopIgnoring($class);\n\n        return $this;\n    }\n\n    /**\n     * Set the truncation length for request exception messages.\n     *\n     * @param  int  $length\n     * @return $this\n     */\n    public function truncateRequestExceptionsAt(int $length)\n    {\n        RequestException::truncateAt($length);\n\n        return $this;\n    }\n\n    /**\n     * Disable truncation of request exception messages.\n     *\n     * @return $this\n     */\n    public function dontTruncateRequestExceptions()\n    {\n        RequestException::dontTruncate();\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Configuration/Middleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Configuration;\n\nuse Closure;\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Auth\\Middleware\\Authenticate;\nuse Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated;\nuse Illuminate\\Cookie\\Middleware\\EncryptCookies;\nuse Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Foundation\\Http\\Middleware\\TrimStrings;\nuse Illuminate\\Http\\Middleware\\TrustHosts;\nuse Illuminate\\Http\\Middleware\\TrustProxies;\nuse Illuminate\\Routing\\Middleware\\ValidateSignature;\nuse Illuminate\\Session\\Middleware\\AuthenticateSession;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nclass Middleware\n{\n    /**\n     * The user defined global middleware stack.\n     *\n     * @var array\n     */\n    protected $global = [];\n\n    /**\n     * The middleware that should be prepended to the global middleware stack.\n     *\n     * @var array\n     */\n    protected $prepends = [];\n\n    /**\n     * The middleware that should be appended to the global middleware stack.\n     *\n     * @var array\n     */\n    protected $appends = [];\n\n    /**\n     * The middleware that should be removed from the global middleware stack.\n     *\n     * @var array\n     */\n    protected $removals = [];\n\n    /**\n     * The middleware that should be replaced in the global middleware stack.\n     *\n     * @var array\n     */\n    protected $replacements = [];\n\n    /**\n     * The user defined middleware groups.\n     *\n     * @var array\n     */\n    protected $groups = [];\n\n    /**\n     * The middleware that should be prepended to the specified groups.\n     *\n     * @var array\n     */\n    protected $groupPrepends = [];\n\n    /**\n     * The middleware that should be appended to the specified groups.\n     *\n     * @var array\n     */\n    protected $groupAppends = [];\n\n    /**\n     * The middleware that should be removed from the specified groups.\n     *\n     * @var array\n     */\n    protected $groupRemovals = [];\n\n    /**\n     * The middleware that should be replaced in the specified groups.\n     *\n     * @var array\n     */\n    protected $groupReplacements = [];\n\n    /**\n     * The Folio / page middleware for the application.\n     *\n     * @var array\n     */\n    protected $pageMiddleware = [];\n\n    /**\n     * Indicates if the \"trust hosts\" middleware is enabled.\n     *\n     * @var bool\n     */\n    protected $trustHosts = false;\n\n    /**\n     * Indicates if Sanctum's frontend state middleware is enabled.\n     *\n     * @var bool\n     */\n    protected $statefulApi = false;\n\n    /**\n     * Indicates the API middleware group's rate limiter.\n     *\n     * @var string\n     */\n    protected $apiLimiter;\n\n    /**\n     * Indicates if Redis throttling should be applied.\n     *\n     * @var bool\n     */\n    protected $throttleWithRedis = false;\n\n    /**\n     * Indicates if sessions should be authenticated for the \"web\" middleware group.\n     *\n     * @var bool\n     */\n    protected $authenticatedSessions = false;\n\n    /**\n     * The custom middleware aliases.\n     *\n     * @var array\n     */\n    protected $customAliases = [];\n\n    /**\n     * The custom middleware priority definition.\n     *\n     * @var array\n     */\n    protected $priority = [];\n\n    /**\n     * The middleware to prepend to the middleware priority definition.\n     *\n     * @var array\n     */\n    protected $prependPriority = [];\n\n    /**\n     * The middleware to append to the middleware priority definition.\n     *\n     * @var array\n     */\n    protected $appendPriority = [];\n\n    /**\n     * Prepend middleware to the application's global middleware stack.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function prepend(array|string $middleware)\n    {\n        $this->prepends = array_merge(\n            Arr::wrap($middleware),\n            $this->prepends\n        );\n\n        return $this;\n    }\n\n    /**\n     * Append middleware to the application's global middleware stack.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function append(array|string $middleware)\n    {\n        $this->appends = array_merge(\n            $this->appends,\n            Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Remove middleware from the application's global middleware stack.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function remove(array|string $middleware)\n    {\n        $this->removals = array_merge(\n            $this->removals,\n            Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify a middleware that should be replaced with another middleware.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @return $this\n     */\n    public function replace(string $search, string $replace)\n    {\n        $this->replacements[$search] = $replace;\n\n        return $this;\n    }\n\n    /**\n     * Define the global middleware for the application.\n     *\n     * @param  array  $middleware\n     * @return $this\n     */\n    public function use(array $middleware)\n    {\n        $this->global = $middleware;\n\n        return $this;\n    }\n\n    /**\n     * Define a middleware group.\n     *\n     * @param  string  $group\n     * @param  array  $middleware\n     * @return $this\n     */\n    public function group(string $group, array $middleware)\n    {\n        $this->groups[$group] = $middleware;\n\n        return $this;\n    }\n\n    /**\n     * Prepend the given middleware to the specified group.\n     *\n     * @param  string  $group\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function prependToGroup(string $group, array|string $middleware)\n    {\n        $this->groupPrepends[$group] = array_merge(\n            Arr::wrap($middleware),\n            $this->groupPrepends[$group] ?? []\n        );\n\n        return $this;\n    }\n\n    /**\n     * Append the given middleware to the specified group.\n     *\n     * @param  string  $group\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function appendToGroup(string $group, array|string $middleware)\n    {\n        $this->groupAppends[$group] = array_merge(\n            $this->groupAppends[$group] ?? [],\n            Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Remove the given middleware from the specified group.\n     *\n     * @param  string  $group\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function removeFromGroup(string $group, array|string $middleware)\n    {\n        $this->groupRemovals[$group] = array_merge(\n            Arr::wrap($middleware),\n            $this->groupRemovals[$group] ?? []\n        );\n\n        return $this;\n    }\n\n    /**\n     * Replace the given middleware in the specified group with another middleware.\n     *\n     * @param  string  $group\n     * @param  string  $search\n     * @param  string  $replace\n     * @return $this\n     */\n    public function replaceInGroup(string $group, string $search, string $replace)\n    {\n        $this->groupReplacements[$group][$search] = $replace;\n\n        return $this;\n    }\n\n    /**\n     * Modify the middleware in the \"web\" group.\n     *\n     * @param  array|string  $append\n     * @param  array|string  $prepend\n     * @param  array|string  $remove\n     * @param  array  $replace\n     * @return $this\n     */\n    public function web(array|string $append = [], array|string $prepend = [], array|string $remove = [], array $replace = [])\n    {\n        return $this->modifyGroup('web', $append, $prepend, $remove, $replace);\n    }\n\n    /**\n     * Modify the middleware in the \"api\" group.\n     *\n     * @param  array|string  $append\n     * @param  array|string  $prepend\n     * @param  array|string  $remove\n     * @param  array  $replace\n     * @return $this\n     */\n    public function api(array|string $append = [], array|string $prepend = [], array|string $remove = [], array $replace = [])\n    {\n        return $this->modifyGroup('api', $append, $prepend, $remove, $replace);\n    }\n\n    /**\n     * Modify the middleware in the given group.\n     *\n     * @param  string  $group\n     * @param  array|string  $append\n     * @param  array|string  $prepend\n     * @param  array|string  $remove\n     * @param  array  $replace\n     * @return $this\n     */\n    protected function modifyGroup(string $group, array|string $append, array|string $prepend, array|string $remove, array $replace)\n    {\n        if (! empty($append)) {\n            $this->appendToGroup($group, $append);\n        }\n\n        if (! empty($prepend)) {\n            $this->prependToGroup($group, $prepend);\n        }\n\n        if (! empty($remove)) {\n            $this->removeFromGroup($group, $remove);\n        }\n\n        if (! empty($replace)) {\n            foreach ($replace as $search => $replace) {\n                $this->replaceInGroup($group, $search, $replace);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register the Folio / page middleware for the application.\n     *\n     * @param  array  $middleware\n     * @return $this\n     */\n    public function pages(array $middleware)\n    {\n        $this->pageMiddleware = $middleware;\n\n        return $this;\n    }\n\n    /**\n     * Register additional middleware aliases.\n     *\n     * @param  array  $aliases\n     * @return $this\n     */\n    public function alias(array $aliases)\n    {\n        $this->customAliases = $aliases;\n\n        return $this;\n    }\n\n    /**\n     * Define the middleware priority for the application.\n     *\n     * @param  array  $priority\n     * @return $this\n     */\n    public function priority(array $priority)\n    {\n        $this->priority = $priority;\n\n        return $this;\n    }\n\n    /**\n     * Prepend middleware to the priority middleware.\n     *\n     * @param  array|string  $before\n     * @param  string  $prepend\n     * @return $this\n     */\n    public function prependToPriorityList($before, $prepend)\n    {\n        $this->prependPriority[$prepend] = $before;\n\n        return $this;\n    }\n\n    /**\n     * Append middleware to the priority middleware.\n     *\n     * @param  array|string  $after\n     * @param  string  $append\n     * @return $this\n     */\n    public function appendToPriorityList($after, $append)\n    {\n        $this->appendPriority[$append] = $after;\n\n        return $this;\n    }\n\n    /**\n     * Get the global middleware.\n     *\n     * @return array\n     */\n    public function getGlobalMiddleware()\n    {\n        $middleware = $this->global ?: array_values(array_filter([\n            \\Illuminate\\Http\\Middleware\\ValidatePathEncoding::class,\n            \\Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks::class,\n            $this->trustHosts ? \\Illuminate\\Http\\Middleware\\TrustHosts::class : null,\n            \\Illuminate\\Http\\Middleware\\TrustProxies::class,\n            \\Illuminate\\Http\\Middleware\\HandleCors::class,\n            \\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance::class,\n            \\Illuminate\\Http\\Middleware\\ValidatePostSize::class,\n            \\Illuminate\\Foundation\\Http\\Middleware\\TrimStrings::class,\n            \\Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull::class,\n        ]));\n\n        $middleware = array_map(function ($middleware) {\n            return $this->replacements[$middleware] ?? $middleware;\n        }, $middleware);\n\n        return array_values(array_filter(\n            array_diff(\n                array_unique(array_merge($this->prepends, $middleware, $this->appends)),\n                $this->removals\n            )\n        ));\n    }\n\n    /**\n     * Get the middleware groups.\n     *\n     * @return array\n     */\n    public function getMiddlewareGroups()\n    {\n        $middleware = [\n            'web' => array_values(array_filter([\n                \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n                \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n                \\Illuminate\\Session\\Middleware\\StartSession::class,\n                \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n                \\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery::class,\n                \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n                $this->authenticatedSessions ? 'auth.session' : null,\n            ])),\n\n            'api' => array_values(array_filter([\n                $this->statefulApi ? \\Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful::class : null,\n                $this->apiLimiter ? 'throttle:'.$this->apiLimiter : null,\n                \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n            ])),\n        ];\n\n        $middleware = array_merge($middleware, $this->groups);\n\n        foreach ($middleware as $group => $groupedMiddleware) {\n            foreach ($groupedMiddleware as $index => $groupMiddleware) {\n                if (isset($this->groupReplacements[$group][$groupMiddleware])) {\n                    $middleware[$group][$index] = $this->groupReplacements[$group][$groupMiddleware];\n                }\n            }\n        }\n\n        foreach ($this->groupRemovals as $group => $removals) {\n            $middleware[$group] = array_values(array_filter(\n                array_diff($middleware[$group] ?? [], $removals)\n            ));\n        }\n\n        foreach ($this->groupPrepends as $group => $prepends) {\n            $middleware[$group] = array_values(array_filter(\n                array_unique(array_merge($prepends, $middleware[$group] ?? []))\n            ));\n        }\n\n        foreach ($this->groupAppends as $group => $appends) {\n            $middleware[$group] = array_values(array_filter(\n                array_unique(array_merge($middleware[$group] ?? [], $appends))\n            ));\n        }\n\n        return $middleware;\n    }\n\n    /**\n     * Configure where guests are redirected by the \"auth\" middleware.\n     *\n     * @param  callable|string  $redirect\n     * @return $this\n     */\n    public function redirectGuestsTo(callable|string $redirect)\n    {\n        return $this->redirectTo(guests: $redirect);\n    }\n\n    /**\n     * Configure where users are redirected by the \"guest\" middleware.\n     *\n     * @param  callable|string  $redirect\n     * @return $this\n     */\n    public function redirectUsersTo(callable|string $redirect)\n    {\n        return $this->redirectTo(users: $redirect);\n    }\n\n    /**\n     * Configure where users are redirected by the authentication and guest middleware.\n     *\n     * @param  callable|string|null  $guests\n     * @param  callable|string|null  $users\n     * @return $this\n     */\n    public function redirectTo(callable|string|null $guests = null, callable|string|null $users = null)\n    {\n        $guests = is_string($guests) ? fn () => $guests : $guests;\n        $users = is_string($users) ? fn () => $users : $users;\n\n        if ($guests) {\n            Authenticate::redirectUsing($guests);\n            AuthenticateSession::redirectUsing($guests);\n            AuthenticationException::redirectUsing($guests);\n        }\n\n        if ($users) {\n            RedirectIfAuthenticated::redirectUsing($users);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Configure the cookie encryption middleware.\n     *\n     * @param  array<int, string>  $except\n     * @return $this\n     */\n    public function encryptCookies(array $except = [])\n    {\n        EncryptCookies::except($except);\n\n        return $this;\n    }\n\n    /**\n     * Configure the request forgery prevention middleware.\n     *\n     * @param  array  $except\n     * @param  bool  $originOnly\n     * @param  bool  $allowSameSite\n     * @return $this\n     */\n    public function preventRequestForgery(array $except = [], bool $originOnly = false, bool $allowSameSite = false)\n    {\n        if (! empty($except)) {\n            PreventRequestForgery::except($except);\n        }\n\n        PreventRequestForgery::useOriginOnly($originOnly);\n        PreventRequestForgery::allowSameSite($allowSameSite);\n\n        return $this;\n    }\n\n    /**\n     * Configure the CSRF token validation middleware.\n     *\n     * @deprecated Use preventRequestForgery() instead.\n     *\n     * @param  array  $except\n     * @return $this\n     */\n    public function validateCsrfTokens(array $except = [])\n    {\n        return $this->preventRequestForgery($except);\n    }\n\n    /**\n     * Configure the URL signature validation middleware.\n     *\n     * @param  array  $except\n     * @return $this\n     */\n    public function validateSignatures(array $except = [])\n    {\n        ValidateSignature::except($except);\n\n        return $this;\n    }\n\n    /**\n     * Configure the empty string conversion middleware.\n     *\n     * @param  array<int, (\\Closure(\\Illuminate\\Http\\Request): bool)>  $except\n     * @return $this\n     */\n    public function convertEmptyStringsToNull(array $except = [])\n    {\n        (new Collection($except))->each(fn (Closure $callback) => ConvertEmptyStringsToNull::skipWhen($callback));\n\n        return $this;\n    }\n\n    /**\n     * Configure the string trimming middleware.\n     *\n     * @param  array<int, (\\Closure(\\Illuminate\\Http\\Request): bool)|string>  $except\n     * @return $this\n     */\n    public function trimStrings(array $except = [])\n    {\n        [$skipWhen, $except] = (new Collection($except))->partition(fn ($value) => $value instanceof Closure);\n\n        $skipWhen->each(fn (Closure $callback) => TrimStrings::skipWhen($callback));\n\n        TrimStrings::except($except->all());\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the trusted host middleware should be enabled.\n     *\n     * @param  array<int, string>|(callable(): array<int, string>)|null  $at\n     * @param  bool  $subdomains\n     * @return $this\n     */\n    public function trustHosts(array|callable|null $at = null, bool $subdomains = true)\n    {\n        $this->trustHosts = true;\n\n        if (! is_null($at)) {\n            TrustHosts::at($at, $subdomains);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Configure the trusted proxies for the application.\n     *\n     * @param  array<int, string>|string|null  $at\n     * @param  int|null  $headers\n     * @return $this\n     */\n    public function trustProxies(array|string|null $at = null, ?int $headers = null)\n    {\n        if (! is_null($at)) {\n            TrustProxies::at($at);\n        }\n\n        if (! is_null($headers)) {\n            TrustProxies::withHeaders($headers);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Configure the middleware that prevents requests during maintenance mode.\n     *\n     * @param  array<int, string>  $except\n     * @return $this\n     */\n    public function preventRequestsDuringMaintenance(array $except = [])\n    {\n        PreventRequestsDuringMaintenance::except($except);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that Sanctum's frontend state middleware should be enabled.\n     *\n     * @return $this\n     */\n    public function statefulApi()\n    {\n        $this->statefulApi = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the API middleware group's throttling middleware should be enabled.\n     *\n     * @param  string  $limiter\n     * @param  bool  $redis\n     * @return $this\n     */\n    public function throttleApi($limiter = 'api', $redis = false)\n    {\n        $this->apiLimiter = $limiter;\n\n        if ($redis) {\n            $this->throttleWithRedis();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Indicate that Laravel's throttling middleware should use Redis.\n     *\n     * @return $this\n     */\n    public function throttleWithRedis()\n    {\n        $this->throttleWithRedis = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that sessions should be authenticated for the \"web\" middleware group.\n     *\n     * @return $this\n     */\n    public function authenticateSessions()\n    {\n        $this->authenticatedSessions = true;\n\n        return $this;\n    }\n\n    /**\n     * Get the Folio / page middleware for the application.\n     *\n     * @return array\n     */\n    public function getPageMiddleware()\n    {\n        return $this->pageMiddleware;\n    }\n\n    /**\n     * Get the middleware aliases.\n     *\n     * @return array\n     */\n    public function getMiddlewareAliases()\n    {\n        return array_merge($this->defaultAliases(), $this->customAliases);\n    }\n\n    /**\n     * Get the default middleware aliases.\n     *\n     * @return array\n     */\n    protected function defaultAliases()\n    {\n        $aliases = [\n            'auth' => \\Illuminate\\Auth\\Middleware\\Authenticate::class,\n            'auth.basic' => \\Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth::class,\n            'auth.session' => \\Illuminate\\Session\\Middleware\\AuthenticateSession::class,\n            'cache.headers' => \\Illuminate\\Http\\Middleware\\SetCacheHeaders::class,\n            'can' => \\Illuminate\\Auth\\Middleware\\Authorize::class,\n            'guest' => \\Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated::class,\n            'password.confirm' => \\Illuminate\\Auth\\Middleware\\RequirePassword::class,\n            'precognitive' => \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,\n            'signed' => \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,\n            'throttle' => $this->throttleWithRedis\n                ? \\Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis::class\n                : \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,\n            'verified' => \\Illuminate\\Auth\\Middleware\\EnsureEmailIsVerified::class,\n        ];\n\n        if (class_exists(\\Spark\\Http\\Middleware\\VerifyBillableIsSubscribed::class)) {\n            $aliases['subscribed'] = \\Spark\\Http\\Middleware\\VerifyBillableIsSubscribed::class;\n        }\n\n        return $aliases;\n    }\n\n    /**\n     * Get the middleware priority for the application.\n     *\n     * @return array\n     */\n    public function getMiddlewarePriority()\n    {\n        return $this->priority;\n    }\n\n    /**\n     * Get the middleware to prepend to the middleware priority definition.\n     *\n     * @return array\n     */\n    public function getMiddlewarePriorityPrepends()\n    {\n        return $this->prependPriority;\n    }\n\n    /**\n     * Get the middleware to append to the middleware priority definition.\n     *\n     * @return array\n     */\n    public function getMiddlewarePriorityAppends()\n    {\n        return $this->appendPriority;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/AboutCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Composer;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'about')]\nclass AboutCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'about {--only= : The section to display}\n                {--json : Output the information as JSON}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Display basic information about your application';\n\n    /**\n     * The Composer instance.\n     *\n     * @var \\Illuminate\\Support\\Composer\n     */\n    protected $composer;\n\n    /**\n     * The data to display.\n     *\n     * @var array\n     */\n    protected static $data = [];\n\n    /**\n     * The registered callables that add custom data to the command output.\n     *\n     * @var array\n     */\n    protected static $customDataResolvers = [];\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  \\Illuminate\\Support\\Composer  $composer\n     */\n    public function __construct(Composer $composer)\n    {\n        parent::__construct();\n\n        $this->composer = $composer;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        $this->gatherApplicationInformation();\n\n        (new Collection(static::$data))\n            ->map(fn ($items) => (new Collection($items))\n                ->map(function ($value) {\n                    if (is_array($value)) {\n                        return [$value];\n                    }\n\n                    if (is_string($value)) {\n                        $value = $this->laravel->make($value);\n                    }\n\n                    return (new Collection($this->laravel->call($value)))\n                        ->map(fn ($value, $key) => [$key, $value])\n                        ->values()\n                        ->all();\n                })->flatten(1)\n            )\n            ->sortBy(function ($data, $key) {\n                $index = array_search($key, ['Environment', 'Cache', 'Drivers']);\n\n                return $index === false ? 99 : $index;\n            })\n            ->filter(function ($data, $key) {\n                return $this->option('only') ? in_array($this->toSearchKeyword($key), $this->sections()) : true;\n            })\n            ->pipe(fn ($data) => $this->display($data));\n\n        $this->newLine();\n\n        return 0;\n    }\n\n    /**\n     * Display the application information.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $data\n     * @return void\n     */\n    protected function display($data)\n    {\n        $this->option('json') ? $this->displayJson($data) : $this->displayDetail($data);\n    }\n\n    /**\n     * Display the application information as a detail view.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $data\n     * @return void\n     */\n    protected function displayDetail($data)\n    {\n        $data->each(function ($data, $section) {\n            $this->newLine();\n\n            $this->components->twoColumnDetail('  <fg=green;options=bold>'.$section.'</>');\n\n            $data->pipe(fn ($data) => $section !== 'Environment' ? $data->sort() : $data)->each(function ($detail) {\n                [$label, $value] = $detail;\n\n                $this->components->twoColumnDetail($label, value($value, false));\n            });\n        });\n    }\n\n    /**\n     * Display the application information as JSON.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $data\n     * @return void\n     */\n    protected function displayJson($data)\n    {\n        $output = $data->flatMap(function ($data, $section) {\n            return [\n                (new Stringable($section))->snake()->value() => $data->mapWithKeys(fn ($item, $key) => [\n                    $this->toSearchKeyword($item[0]) => value($item[1], true),\n                ]),\n            ];\n        });\n\n        $this->output->writeln(strip_tags(json_encode($output)));\n    }\n\n    /**\n     * Gather information about the application.\n     *\n     * @return void\n     */\n    protected function gatherApplicationInformation()\n    {\n        self::$data = [];\n\n        $formatEnabledStatus = fn ($value) => $value ? '<fg=yellow;options=bold>ENABLED</>' : 'OFF';\n        $formatCachedStatus = fn ($value) => $value ? '<fg=green;options=bold>CACHED</>' : '<fg=yellow;options=bold>NOT CACHED</>';\n        $formatStorageLinkedStatus = fn ($value) => $value ? '<fg=green;options=bold>LINKED</>' : '<fg=yellow;options=bold>NOT LINKED</>';\n\n        static::addToSection('Environment', fn () => [\n            'Application Name' => config('app.name'),\n            'Laravel Version' => $this->laravel->version(),\n            'PHP Version' => phpversion(),\n            'Composer Version' => $this->composer->getVersion() ?? '<fg=yellow;options=bold>-</>',\n            'Environment' => $this->laravel->environment(),\n            'Debug Mode' => static::format(config('app.debug'), console: $formatEnabledStatus),\n            'URL' => Str::of(config('app.url'))->replace(['http://', 'https://'], ''),\n            'Maintenance Mode' => static::format($this->laravel->isDownForMaintenance(), console: $formatEnabledStatus),\n            'Timezone' => config('app.timezone'),\n            'Locale' => config('app.locale'),\n        ]);\n\n        static::addToSection('Cache', fn () => [\n            'Config' => static::format($this->laravel->configurationIsCached(), console: $formatCachedStatus),\n            'Events' => static::format($this->laravel->eventsAreCached(), console: $formatCachedStatus),\n            'Routes' => static::format($this->laravel->routesAreCached(), console: $formatCachedStatus),\n            'Views' => static::format($this->hasPhpFiles(config('view.compiled')), console: $formatCachedStatus),\n        ]);\n\n        static::addToSection('Drivers', fn () => array_filter([\n            'Broadcasting' => config('broadcasting.default'),\n            'Cache' => function ($json) {\n                $cacheStore = config('cache.default');\n\n                if (config('cache.stores.'.$cacheStore.'.driver') === 'failover') {\n                    $secondary = new Collection(config('cache.stores.'.$cacheStore.'.stores'));\n\n                    return value(static::format(\n                        value: $cacheStore,\n                        console: fn ($value) => '<fg=yellow;options=bold>'.$value.'</> <fg=gray;options=bold>/</> '.$secondary->implode(', '),\n                        json: fn () => $secondary->all(),\n                    ), $json);\n                }\n\n                return $cacheStore;\n            },\n            'Database' => config('database.default'),\n            'Logs' => function ($json) {\n                $logChannel = config('logging.default');\n\n                if (config('logging.channels.'.$logChannel.'.driver') === 'stack') {\n                    $secondary = new Collection(config('logging.channels.'.$logChannel.'.channels'));\n\n                    return value(static::format(\n                        value: $logChannel,\n                        console: fn ($value) => '<fg=yellow;options=bold>'.$value.'</> <fg=gray;options=bold>/</> '.$secondary->implode(', '),\n                        json: fn () => $secondary->all(),\n                    ), $json);\n                } else {\n                    $logs = $logChannel;\n                }\n\n                return $logs;\n            },\n            'Mail' => function ($json) {\n                $mailMailer = config('mail.default');\n\n                if (in_array(config('mail.mailers.'.$mailMailer.'.transport'), ['failover', 'roundrobin'])) {\n                    $secondary = new Collection(config('mail.mailers.'.$mailMailer.'.mailers'));\n\n                    return value(static::format(\n                        value: $mailMailer,\n                        console: fn ($value) => '<fg=yellow;options=bold>'.$value.'</> <fg=gray;options=bold>/</> '.$secondary->implode(', '),\n                        json: fn () => $secondary->all(),\n                    ), $json);\n                }\n\n                return $mailMailer;\n            },\n            'Octane' => config('octane.server'),\n            'Queue' => function ($json) {\n                $queueConnection = config('queue.default');\n\n                if (config('queue.connections.'.$queueConnection.'.driver') === 'failover') {\n                    $secondary = new Collection(config('queue.connections.'.$queueConnection.'.connections'));\n\n                    return value(static::format(\n                        value: $queueConnection,\n                        console: fn ($value) => '<fg=yellow;options=bold>'.$value.'</> <fg=gray;options=bold>/</> '.$secondary->implode(', '),\n                        json: fn () => $secondary->all(),\n                    ), $json);\n                }\n\n                return $queueConnection;\n            },\n            'Scout' => config('scout.driver'),\n            'Session' => config('session.driver'),\n        ]));\n\n        static::addToSection('Storage', fn () => [\n            ...$this->determineStoragePathLinkStatus($formatStorageLinkedStatus),\n        ]);\n\n        (new Collection(static::$customDataResolvers))->each->__invoke();\n    }\n\n    /**\n     * Determine storage symbolic links status.\n     *\n     * @param  callable  $formatStorageLinkedStatus\n     * @return array<string,mixed>\n     */\n    protected function determineStoragePathLinkStatus(callable $formatStorageLinkedStatus): array\n    {\n        return (new Collection(config('filesystems.links', [])))\n            ->mapWithKeys(function ($target, $link) use ($formatStorageLinkedStatus) {\n                $path = Str::replace(public_path(), '', $link);\n\n                return [public_path($path) => static::format(file_exists($link), console: $formatStorageLinkedStatus)];\n            })\n            ->toArray();\n    }\n\n    /**\n     * Determine whether the given directory has PHP files.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    protected function hasPhpFiles(string $path): bool\n    {\n        return count(glob($path.'/*.php')) > 0;\n    }\n\n    /**\n     * Add additional data to the output of the \"about\" command.\n     *\n     * @param  string  $section\n     * @param  callable|string|array  $data\n     * @param  string|null  $value\n     * @return void\n     */\n    public static function add(string $section, $data, ?string $value = null)\n    {\n        static::$customDataResolvers[] = fn () => static::addToSection($section, $data, $value);\n    }\n\n    /**\n     * Add additional data to the output of the \"about\" command.\n     *\n     * @param  string  $section\n     * @param  callable|string|array  $data\n     * @param  string|null  $value\n     * @return void\n     */\n    protected static function addToSection(string $section, $data, ?string $value = null)\n    {\n        if (is_array($data)) {\n            foreach ($data as $key => $value) {\n                self::$data[$section][] = [$key, $value];\n            }\n        } elseif (is_callable($data) || ($value === null && class_exists($data))) {\n            self::$data[$section][] = $data;\n        } else {\n            self::$data[$section][] = [$data, $value];\n        }\n    }\n\n    /**\n     * Get the sections provided to the command.\n     *\n     * @return array\n     */\n    protected function sections()\n    {\n        return (new Collection(explode(',', $this->option('only') ?? '')))\n            ->filter()\n            ->map(fn ($only) => $this->toSearchKeyword($only))\n            ->all();\n    }\n\n    /**\n     * Materialize a function that formats a given value for CLI or JSON output.\n     *\n     * @param  mixed  $value\n     * @param  (\\Closure(mixed):(mixed))|null  $console\n     * @param  (\\Closure(mixed):(mixed))|null  $json\n     * @return \\Closure(bool):mixed\n     */\n    public static function format($value, ?Closure $console = null, ?Closure $json = null)\n    {\n        return function ($isJson) use ($value, $console, $json) {\n            if ($isJson === true && $json instanceof Closure) {\n                return value($json, $value);\n            } elseif ($isJson === false && $console instanceof Closure) {\n                return value($console, $value);\n            }\n\n            return value($value);\n        };\n    }\n\n    /**\n     * Format the given string for searching.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function toSearchKeyword(string $value)\n    {\n        return (new Stringable($value))->lower()->snake()->value();\n    }\n\n    /**\n     * Flush the registered about data.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$data = [];\n\n        static::$customDataResolvers = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ApiInstallCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Process;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Support\\artisan_binary;\nuse function Illuminate\\Support\\php_binary;\n\n#[AsCommand(name: 'install:api')]\nclass ApiInstallCommand extends Command\n{\n    use InteractsWithComposerPackages;\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'install:api\n                    {--composer=global : Absolute path to the Composer binary which should be used to install packages}\n                    {--force : Overwrite any existing API routes file}\n                    {--passport : Install Laravel Passport instead of Laravel Sanctum}\n                    {--without-migration-prompt : Do not prompt to run pending migrations}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create an API routes file and install Laravel Sanctum or Laravel Passport';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if ($this->option('passport')) {\n            $this->installPassport();\n        } else {\n            $this->installSanctum();\n        }\n\n        if (file_exists($apiRoutesPath = $this->laravel->basePath('routes/api.php')) &&\n            ! $this->option('force')) {\n            $this->components->error('API routes file already exists.');\n        } else {\n            $this->components->info('Published API routes file.');\n\n            copy(__DIR__.'/stubs/api-routes.stub', $apiRoutesPath);\n\n            if ($this->option('passport')) {\n                (new Filesystem)->replaceInFile(\n                    'auth:sanctum',\n                    'auth:api',\n                    $apiRoutesPath,\n                );\n            }\n\n            $this->uncommentApiRoutesFile();\n        }\n\n        if ($this->option('passport')) {\n            Process::run([\n                php_binary(),\n                artisan_binary(),\n                'passport:install',\n            ]);\n\n            $this->components->info('API scaffolding installed. Please add the [Laravel\\Passport\\HasApiTokens] trait to your User model.');\n        } else {\n            if (! $this->option('without-migration-prompt')) {\n                if ($this->confirm('One new database migration has been published. Would you like to run all pending database migrations?', true)) {\n                    $this->call('migrate');\n                }\n            }\n\n            $this->components->info('API scaffolding installed. Please add the [Laravel\\Sanctum\\HasApiTokens] trait to your User model.');\n        }\n    }\n\n    /**\n     * Uncomment the API routes file in the application bootstrap file.\n     *\n     * @return void\n     */\n    protected function uncommentApiRoutesFile()\n    {\n        $appBootstrapPath = $this->laravel->bootstrapPath('app.php');\n\n        $content = file_get_contents($appBootstrapPath);\n\n        if (str_contains($content, '// api: ')) {\n            (new Filesystem)->replaceInFile(\n                '// api: ',\n                'api: ',\n                $appBootstrapPath,\n            );\n        } elseif (str_contains($content, 'web: __DIR__.\\'/../routes/web.php\\',')) {\n            (new Filesystem)->replaceInFile(\n                'web: __DIR__.\\'/../routes/web.php\\',',\n                'web: __DIR__.\\'/../routes/web.php\\','.PHP_EOL.'        api: __DIR__.\\'/../routes/api.php\\',',\n                $appBootstrapPath,\n            );\n        } else {\n            $this->components->warn(\"Unable to automatically add API route definition to [{$appBootstrapPath}]. API route file should be registered manually.\");\n\n            return;\n        }\n    }\n\n    /**\n     * Install Laravel Sanctum into the application.\n     *\n     * @return void\n     */\n    protected function installSanctum()\n    {\n        $this->requireComposerPackages($this->option('composer'), [\n            'laravel/sanctum:^4.0',\n        ]);\n\n        $migrationPublished = (new Collection(scandir($this->laravel->databasePath('migrations'))))->contains(function ($migration) {\n            return preg_match('/\\d{4}_\\d{2}_\\d{2}_\\d{6}_create_personal_access_tokens_table.php/', $migration);\n        });\n\n        if (! $migrationPublished) {\n            Process::run([\n                php_binary(),\n                artisan_binary(),\n                'vendor:publish',\n                '--provider',\n                'Laravel\\\\Sanctum\\\\SanctumServiceProvider',\n            ]);\n        }\n    }\n\n    /**\n     * Install Laravel Passport into the application.\n     *\n     * @return void\n     */\n    protected function installPassport()\n    {\n        $this->requireComposerPackages($this->option('composer'), [\n            'laravel/passport:^13.0',\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/BroadcastingInstallCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Composer\\InstalledVersions;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Facades\\Process;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Support\\artisan_binary;\nuse function Illuminate\\Support\\php_binary;\nuse function Laravel\\Prompts\\confirm;\nuse function Laravel\\Prompts\\password;\nuse function Laravel\\Prompts\\select;\nuse function Laravel\\Prompts\\text;\n\n#[AsCommand(name: 'install:broadcasting')]\nclass BroadcastingInstallCommand extends Command\n{\n    use InteractsWithComposerPackages;\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'install:broadcasting\n                    {--composer=global : Absolute path to the Composer binary which should be used to install packages}\n                    {--force : Overwrite any existing broadcasting routes file}\n                    {--without-reverb : Do not prompt to install Laravel Reverb}\n                    {--reverb : Install Laravel Reverb as the default broadcaster}\n                    {--pusher : Install Pusher as the default broadcaster}\n                    {--ably : Install Ably as the default broadcaster}\n                    {--without-node : Do not prompt to install Node dependencies}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a broadcasting channel routes file';\n\n    /**\n     * The broadcasting driver to use.\n     *\n     * @var string|null\n     */\n    protected $driver = null;\n\n    /**\n     * The framework packages to install.\n     *\n     * @var array\n     */\n    protected $frameworkPackages = [\n        'react' => '@laravel/echo-react',\n        'vue' => '@laravel/echo-vue',\n    ];\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->call('config:publish', ['name' => 'broadcasting']);\n\n        // Install channel routes file...\n        if (! file_exists($broadcastingRoutesPath = $this->laravel->basePath('routes/channels.php')) || $this->option('force')) {\n            $this->components->info(\"Published 'channels' route file.\");\n\n            copy(__DIR__.'/stubs/broadcasting-routes.stub', $broadcastingRoutesPath);\n        }\n\n        $this->uncommentChannelsRoutesFile();\n        $this->enableBroadcastServiceProvider();\n\n        $this->driver = $this->resolveDriver();\n\n        Env::writeVariable('BROADCAST_CONNECTION', $this->driver, $this->laravel->basePath('.env'), true);\n\n        $this->collectDriverConfig();\n        $this->installDriverPackages();\n\n        if ($this->isUsingSupportedFramework()) {\n            // If this is a supported framework, we will use the framework-specific Echo helpers...\n            $this->injectFrameworkSpecificConfiguration();\n        } else {\n            // Standard JavaScript implementation...\n            if (! file_exists($echoScriptPath = $this->laravel->resourcePath('js/echo.js'))) {\n                if (! is_dir($directory = $this->laravel->resourcePath('js'))) {\n                    mkdir($directory, 0755, true);\n                }\n\n                $stubPath = __DIR__.'/stubs/echo-js-'.$this->driver.'.stub';\n\n                if (! file_exists($stubPath)) {\n                    $stubPath = __DIR__.'/stubs/echo-js-reverb.stub';\n                }\n\n                copy($stubPath, $echoScriptPath);\n            }\n\n            // Only add the bootstrap import for the standard JS implementation...\n            if (file_exists($bootstrapScriptPath = $this->laravel->resourcePath('js/bootstrap.js'))) {\n                $bootstrapScript = file_get_contents(\n                    $bootstrapScriptPath\n                );\n\n                if (! str_contains($bootstrapScript, './echo')) {\n                    file_put_contents(\n                        $bootstrapScriptPath,\n                        trim($bootstrapScript.PHP_EOL.file_get_contents(__DIR__.'/stubs/echo-bootstrap-js.stub')).PHP_EOL,\n                    );\n                }\n            } elseif (file_exists($appScriptPath = $this->laravel->resourcePath('js/app.js'))) {\n                // If no bootstrap.js, try app.js...\n                $appScript = file_get_contents(\n                    $appScriptPath\n                );\n\n                if (! str_contains($appScript, './echo')) {\n                    file_put_contents(\n                        $appScriptPath,\n                        trim($appScript.PHP_EOL.file_get_contents(__DIR__.'/stubs/echo-bootstrap-js.stub')).PHP_EOL,\n                    );\n                }\n            }\n        }\n\n        $this->installReverb();\n\n        $this->installNodeDependencies();\n    }\n\n    /**\n     * Uncomment the \"channels\" routes file in the application bootstrap file.\n     *\n     * @return void\n     */\n    protected function uncommentChannelsRoutesFile()\n    {\n        $appBootstrapPath = $this->laravel->bootstrapPath('app.php');\n\n        $content = file_get_contents($appBootstrapPath);\n\n        if (str_contains($content, '// channels: ')) {\n            (new Filesystem)->replaceInFile(\n                '// channels: ',\n                'channels: ',\n                $appBootstrapPath,\n            );\n        } elseif (str_contains($content, 'channels: ')) {\n            return;\n        } elseif (str_contains($content, 'commands: __DIR__.\\'/../routes/console.php\\',')) {\n            (new Filesystem)->replaceInFile(\n                'commands: __DIR__.\\'/../routes/console.php\\',',\n                'commands: __DIR__.\\'/../routes/console.php\\','.PHP_EOL.'        channels: __DIR__.\\'/../routes/channels.php\\',',\n                $appBootstrapPath,\n            );\n        } elseif (str_contains($content, '->withRouting(')) {\n            (new Filesystem)->replaceInFile(\n                '->withRouting(',\n                '->withRouting('.PHP_EOL.'        channels: __DIR__.\\'/../routes/channels.php\\',',\n                $appBootstrapPath,\n            );\n        } else {\n            $this->components->error('Unable to register broadcast routes. Please register them manually in ['.$appBootstrapPath.'].');\n        }\n    }\n\n    /**\n     * Uncomment the \"BroadcastServiceProvider\" in the application configuration.\n     *\n     * @return void\n     */\n    protected function enableBroadcastServiceProvider()\n    {\n        $filesystem = new Filesystem;\n\n        if (\n            ! $filesystem->exists(app()->configPath('app.php')) ||\n            ! $filesystem->exists('app/Providers/BroadcastServiceProvider.php')\n        ) {\n            return;\n        }\n\n        $config = $filesystem->get(app()->configPath('app.php'));\n\n        if (str_contains($config, '// App\\Providers\\BroadcastServiceProvider::class')) {\n            $filesystem->replaceInFile(\n                '// App\\Providers\\BroadcastServiceProvider::class',\n                'App\\Providers\\BroadcastServiceProvider::class',\n                app()->configPath('app.php'),\n            );\n        }\n    }\n\n    /**\n     * Collect the driver configuration.\n     *\n     * @return void\n     */\n    protected function collectDriverConfig()\n    {\n        $envPath = $this->laravel->basePath('.env');\n\n        if (! file_exists($envPath)) {\n            return;\n        }\n\n        match ($this->driver) {\n            'pusher' => $this->collectPusherConfig(),\n            'ably' => $this->collectAblyConfig(),\n            default => null,\n        };\n    }\n\n    /**\n     * Install the driver packages.\n     *\n     * @return void\n     */\n    protected function installDriverPackages()\n    {\n        $package = match ($this->driver) {\n            'pusher' => 'pusher/pusher-php-server',\n            'ably' => 'ably/ably-php',\n            default => null,\n        };\n\n        if (! $package || InstalledVersions::isInstalled($package)) {\n            return;\n        }\n\n        $this->requireComposerPackages($this->option('composer'), [$package]);\n    }\n\n    /**\n     * Collect the Pusher configuration.\n     *\n     * @return void\n     */\n    protected function collectPusherConfig()\n    {\n        $appId = text('Pusher App ID', 'Enter your Pusher app ID');\n        $key = password('Pusher App Key', 'Enter your Pusher app key');\n        $secret = password('Pusher App Secret', 'Enter your Pusher app secret');\n\n        $cluster = select('Pusher App Cluster', [\n            'mt1',\n            'us2',\n            'us3',\n            'eu',\n            'ap1',\n            'ap2',\n            'ap3',\n            'ap4',\n            'sa1',\n        ]);\n\n        Env::writeVariables([\n            'PUSHER_APP_ID' => $appId,\n            'PUSHER_APP_KEY' => $key,\n            'PUSHER_APP_SECRET' => $secret,\n            'PUSHER_APP_CLUSTER' => $cluster,\n            'PUSHER_PORT' => 443,\n            'PUSHER_SCHEME' => 'https',\n            'VITE_PUSHER_APP_KEY' => '${PUSHER_APP_KEY}',\n            'VITE_PUSHER_APP_CLUSTER' => '${PUSHER_APP_CLUSTER}',\n            'VITE_PUSHER_HOST' => '${PUSHER_HOST}',\n            'VITE_PUSHER_PORT' => '${PUSHER_PORT}',\n            'VITE_PUSHER_SCHEME' => '${PUSHER_SCHEME}',\n        ], $this->laravel->basePath('.env'));\n    }\n\n    /**\n     * Collect the Ably configuration.\n     *\n     * @return void\n     */\n    protected function collectAblyConfig()\n    {\n        $this->components->warn('Make sure to enable \"Pusher protocol support\" in your Ably app settings.');\n\n        $key = password('Ably Key', 'Enter your Ably key');\n\n        $publicKey = explode(':', $key)[0] ?? $key;\n\n        Env::writeVariables([\n            'ABLY_KEY' => $key,\n            'ABLY_PUBLIC_KEY' => $publicKey,\n            'VITE_ABLY_PUBLIC_KEY' => '${ABLY_PUBLIC_KEY}',\n        ], $this->laravel->basePath('.env'));\n    }\n\n    /**\n     * Inject Echo configuration into the application's main file.\n     *\n     * @return void\n     */\n    protected function injectFrameworkSpecificConfiguration()\n    {\n        if ($this->appUsesVue()) {\n            $importPath = $this->frameworkPackages['vue'];\n\n            $filePaths = [\n                $this->laravel->resourcePath('js/app.ts'),\n                $this->laravel->resourcePath('js/app.js'),\n            ];\n        } else {\n            $importPath = $this->frameworkPackages['react'];\n\n            $filePaths = [\n                $this->laravel->resourcePath('js/app.tsx'),\n                $this->laravel->resourcePath('js/app.jsx'),\n            ];\n        }\n\n        $filePath = array_filter($filePaths, function ($path) {\n            return file_exists($path);\n        })[0] ?? null;\n\n        if (! $filePath) {\n            $this->components->warn(\"Could not find file [{$filePaths[0]}]. Skipping automatic Echo configuration.\");\n\n            return;\n        }\n\n        $contents = file_get_contents($filePath);\n\n        $echoCode = <<<JS\n        import { configureEcho } from '{$importPath}';\n\n        configureEcho({\n            broadcaster: '{$this->driver}',\n        });\n        JS;\n\n        preg_match_all('/^import .+;$/m', $contents, $matches);\n\n        if (empty($matches[0])) {\n            // Add the Echo configuration to the top of the file if no import statements are found...\n            $newContents = $echoCode.PHP_EOL.$contents;\n\n            file_put_contents($filePath, $newContents);\n        } else {\n            // Add Echo configuration after the last import...\n            $lastImport = array_last($matches[0]);\n\n            $positionOfLastImport = strrpos($contents, $lastImport);\n\n            if ($positionOfLastImport !== false) {\n                $insertPosition = $positionOfLastImport + strlen($lastImport);\n                $newContents = substr($contents, 0, $insertPosition).PHP_EOL.$echoCode.substr($contents, $insertPosition);\n\n                file_put_contents($filePath, $newContents);\n            }\n        }\n\n        $this->components->info('Echo configuration added to ['.basename($filePath).'].');\n    }\n\n    /**\n     * Install Laravel Reverb into the application if desired.\n     *\n     * @return void\n     */\n    protected function installReverb()\n    {\n        if ($this->driver !== 'reverb' || $this->option('without-reverb') || InstalledVersions::isInstalled('laravel/reverb')) {\n            return;\n        }\n\n        if (! confirm('Would you like to install Laravel Reverb?', default: true)) {\n            return;\n        }\n\n        $this->requireComposerPackages($this->option('composer'), [\n            'laravel/reverb:^1.0',\n        ]);\n\n        Process::run([\n            php_binary(),\n            artisan_binary(),\n            'reverb:install',\n        ]);\n\n        $this->components->info('Reverb installed successfully.');\n    }\n\n    /**\n     * Install and build Node dependencies.\n     *\n     * @return void\n     */\n    protected function installNodeDependencies()\n    {\n        if ($this->option('without-node') || ! confirm('Would you like to install and build the Node dependencies required for broadcasting?', default: true)) {\n            return;\n        }\n\n        $this->components->info('Installing and building Node dependencies.');\n\n        if (file_exists(base_path('pnpm-lock.yaml'))) {\n            $commands = [\n                'pnpm add --save-dev laravel-echo pusher-js',\n                'pnpm run build',\n            ];\n        } elseif (file_exists(base_path('yarn.lock'))) {\n            $commands = [\n                'yarn add --dev laravel-echo pusher-js',\n                'yarn run build',\n            ];\n        } elseif (file_exists(base_path('bun.lock')) || file_exists(base_path('bun.lockb'))) {\n            $commands = [\n                'bun add --dev laravel-echo pusher-js',\n                'bun run build',\n            ];\n        } else {\n            $commands = [\n                'npm install --save-dev laravel-echo pusher-js',\n                'npm run build',\n            ];\n        }\n\n        if ($this->appUsesVue()) {\n            $commands[0] .= ' '.$this->frameworkPackages['vue'];\n        } elseif ($this->appUsesReact()) {\n            $commands[0] .= ' '.$this->frameworkPackages['react'];\n        }\n\n        $command = Process::command(implode(' && ', $commands))\n            ->path(base_path());\n\n        if (! windows_os()) {\n            $command->tty(true);\n        }\n\n        if ($command->run()->failed()) {\n            $this->components->warn(\"Node dependency installation failed. Please run the following commands manually: \\n\\n\".implode(' && ', $commands));\n        } else {\n            $this->components->info('Node dependencies installed successfully.');\n        }\n    }\n\n    /**\n     * Resolve the provider to use based on the user's choice.\n     *\n     * @return string\n     */\n    protected function resolveDriver(): string\n    {\n        if ($this->option('reverb')) {\n            return 'reverb';\n        }\n\n        if ($this->option('pusher')) {\n            return 'pusher';\n        }\n\n        if ($this->option('ably')) {\n            return 'ably';\n        }\n\n        return select('Which broadcasting driver would you like to use?', [\n            'reverb' => 'Laravel Reverb',\n            'pusher' => 'Pusher',\n            'ably' => 'Ably',\n        ]);\n    }\n\n    /**\n     * Detect if the user is using a supported framework (React or Vue).\n     *\n     * @return bool\n     */\n    protected function isUsingSupportedFramework(): bool\n    {\n        return $this->appUsesReact() || $this->appUsesVue();\n    }\n\n    /**\n     * Detect if the user is using React.\n     *\n     * @return bool\n     */\n    protected function appUsesReact(): bool\n    {\n        return $this->packageDependenciesInclude('react');\n    }\n\n    /**\n     * Detect if the user is using Vue.\n     *\n     * @return bool\n     */\n    protected function appUsesVue(): bool\n    {\n        return $this->packageDependenciesInclude('vue');\n    }\n\n    /**\n     * Detect if the package is installed.\n     *\n     * @return bool\n     */\n    protected function packageDependenciesInclude(string $package): bool\n    {\n        $packageJsonPath = $this->laravel->basePath('package.json');\n\n        if (! file_exists($packageJsonPath)) {\n            return false;\n        }\n\n        $packageJson = json_decode(file_get_contents($packageJsonPath), true);\n\n        return isset($packageJson['dependencies'][$package]) ||\n            isset($packageJson['devDependencies'][$package]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/CastMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:cast')]\nclass CastMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:cast';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new custom Eloquent cast class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Cast';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->option('inbound')\n            ? $this->resolveStubPath('/stubs/cast.inbound.stub')\n            : $this->resolveStubPath('/stubs/cast.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Casts';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the cast already exists'],\n            ['inbound', null, InputOption::VALUE_NONE, 'Generate an inbound cast class'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ChannelListCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Broadcasting\\Broadcaster;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Terminal;\n\n#[AsCommand(name: 'channel:list')]\nclass ChannelListCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'channel:list';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'List all registered private broadcast channels';\n\n    /**\n     * The terminal width resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $terminalWidthResolver;\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Contracts\\Broadcasting\\Broadcaster  $broadcaster\n     * @return void\n     */\n    public function handle(Broadcaster $broadcaster)\n    {\n        $channels = $broadcaster->getChannels();\n\n        if (! $this->laravel->providerIsLoaded('App\\Providers\\BroadcastServiceProvider') &&\n            file_exists($this->laravel->path('Providers/BroadcastServiceProvider.php'))) {\n            $this->components->warn('The [App\\Providers\\BroadcastServiceProvider] has not been loaded. Your private channels may not be loaded.');\n        }\n\n        if (! $channels->count()) {\n            return $this->components->error(\"Your application doesn't have any private broadcasting channels.\");\n        }\n\n        $this->displayChannels($channels);\n    }\n\n    /**\n     * Display the channel information on the console.\n     *\n     * @param  Collection  $channels\n     * @return void\n     */\n    protected function displayChannels($channels)\n    {\n        $this->output->writeln($this->forCli($channels));\n    }\n\n    /**\n     * Convert the given channels to regular CLI output.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $channels\n     * @return array\n     */\n    protected function forCli($channels)\n    {\n        $maxChannelName = $channels->keys()->max(function ($channelName) {\n            return mb_strlen($channelName);\n        });\n\n        $terminalWidth = $this->getTerminalWidth();\n\n        $channelCount = $this->determineChannelCountOutput($channels, $terminalWidth);\n\n        return $channels->map(function ($channel, $channelName) use ($maxChannelName, $terminalWidth) {\n            $resolver = $channel instanceof Closure ? 'Closure' : $channel;\n\n            $spaces = str_repeat(' ', max($maxChannelName + 6 - mb_strlen($channelName), 0));\n\n            $dots = str_repeat('.', max(\n                $terminalWidth - mb_strlen($channelName.$spaces.$resolver) - 6, 0\n            ));\n\n            $dots = empty($dots) ? $dots : \" $dots\";\n\n            return sprintf(\n                '  <fg=blue;options=bold>%s</> %s<fg=white>%s</><fg=#6C7280>%s</>',\n                $channelName,\n                $spaces,\n                $resolver,\n                $dots,\n            );\n        })\n            ->filter()\n            ->sort()\n            ->prepend('')\n            ->push('')->push($channelCount)->push('')\n            ->toArray();\n    }\n\n    /**\n     * Determine and return the output for displaying the number of registered channels in the CLI output.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $channels\n     * @param  int  $terminalWidth\n     * @return string\n     */\n    protected function determineChannelCountOutput($channels, $terminalWidth)\n    {\n        $channelCountText = 'Showing ['.$channels->count().'] private channels';\n\n        $offset = $terminalWidth - mb_strlen($channelCountText) - 2;\n\n        $spaces = str_repeat(' ', $offset);\n\n        return $spaces.'<fg=blue;options=bold>Showing ['.$channels->count().'] private channels</>';\n    }\n\n    /**\n     * Get the terminal width.\n     *\n     * @return int\n     */\n    public static function getTerminalWidth()\n    {\n        return is_null(static::$terminalWidthResolver)\n            ? (new Terminal)->getWidth()\n            : call_user_func(static::$terminalWidthResolver);\n    }\n\n    /**\n     * Set a callback that should be used when resolving the terminal width.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveTerminalWidthUsing($resolver)\n    {\n        static::$terminalWidthResolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ChannelMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:channel')]\nclass ChannelMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:channel';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new channel class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Channel';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        return str_replace(\n            ['DummyUser', '{{ userModel }}'],\n            class_basename($this->userProviderModel()),\n            parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return __DIR__.'/stubs/channel.stub';\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Broadcasting';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the channel already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ClassMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:class')]\nclass ClassMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:class';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Class';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->option('invokable')\n            ? $this->resolveStubPath('/stubs/class.invokable.stub')\n            : $this->resolveStubPath('/stubs/class.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['invokable', 'i', InputOption::VALUE_NONE, 'Generate a single method, invokable class'],\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the class already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ClearCompiledCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'clear-compiled')]\nclass ClearCompiledCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'clear-compiled';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Remove the compiled class file';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (is_file($servicesPath = $this->laravel->getCachedServicesPath())) {\n            @unlink($servicesPath);\n        }\n\n        if (is_file($packagesPath = $this->laravel->getCachedPackagesPath())) {\n            @unlink($packagesPath);\n        }\n\n        $this->components->info('Compiled services and packages files removed successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/CliDumper.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Concerns\\ResolvesDumpSource;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\nuse Symfony\\Component\\VarDumper\\Caster\\ReflectionCaster;\nuse Symfony\\Component\\VarDumper\\Cloner\\Data;\nuse Symfony\\Component\\VarDumper\\Cloner\\VarCloner;\nuse Symfony\\Component\\VarDumper\\Dumper\\CliDumper as BaseCliDumper;\nuse Symfony\\Component\\VarDumper\\VarDumper;\n\nclass CliDumper extends BaseCliDumper\n{\n    use ResolvesDumpSource;\n\n    /**\n     * The base path of the application.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * The output instance.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    protected $output;\n\n    /**\n     * The compiled view path for the application.\n     *\n     * @var string\n     */\n    protected $compiledViewPath;\n\n    /**\n     * If the dumper is currently dumping.\n     *\n     * @var bool\n     */\n    protected $dumping = false;\n\n    /**\n     * Create a new CLI dumper instance.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @param  string  $basePath\n     * @param  string  $compiledViewPath\n     */\n    public function __construct($output, $basePath, $compiledViewPath)\n    {\n        parent::__construct();\n\n        $this->basePath = $basePath;\n        $this->output = $output;\n        $this->compiledViewPath = $compiledViewPath;\n\n        $this->setColors($this->supportsColors());\n    }\n\n    /**\n     * Create a new CLI dumper instance and register it as the default dumper.\n     *\n     * @param  string  $basePath\n     * @param  string  $compiledViewPath\n     * @return void\n     */\n    public static function register($basePath, $compiledViewPath)\n    {\n        $cloner = tap(new VarCloner())->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);\n\n        $dumper = new static(new ConsoleOutput(), $basePath, $compiledViewPath);\n\n        VarDumper::setHandler(fn ($value) => $dumper->dumpWithSource($cloner->cloneVar($value)));\n    }\n\n    /**\n     * Dump a variable with its source file / line.\n     *\n     * @param  \\Symfony\\Component\\VarDumper\\Cloner\\Data  $data\n     * @return void\n     */\n    public function dumpWithSource(Data $data)\n    {\n        if ($this->dumping) {\n            $this->dump($data);\n\n            return;\n        }\n\n        $this->dumping = true;\n\n        $output = (string) $this->dump($data, true);\n        $lines = explode(\"\\n\", $output);\n\n        $lines[array_key_last($lines) - 1] .= $this->getDumpSourceContent();\n\n        $this->output->write(implode(\"\\n\", $lines));\n\n        $this->dumping = false;\n    }\n\n    /**\n     * Get the dump's source console content.\n     *\n     * @return string\n     */\n    protected function getDumpSourceContent()\n    {\n        if (is_null($dumpSource = $this->resolveDumpSource())) {\n            return '';\n        }\n\n        [$file, $relativeFile, $line] = $dumpSource;\n\n        $href = $this->resolveSourceHref($file, $line);\n\n        return sprintf(\n            ' <fg=gray>// <fg=gray%s>%s%s</></>',\n            is_null($href) ? '' : \";href=$href\",\n            $relativeFile,\n            is_null($line) ? '' : \":$line\"\n        );\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    protected function supportsColors(): bool\n    {\n        return $this->output->isDecorated();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ClosureCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ManuallyFailedException;\nuse Illuminate\\Support\\Facades\\Schedule;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse ReflectionFunction;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\n/**\n * @mixin \\Illuminate\\Console\\Scheduling\\Event\n */\nclass ClosureCommand extends Command\n{\n    use ForwardsCalls;\n\n    /**\n     * The command callback.\n     *\n     * @var \\Closure\n     */\n    protected $callback;\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = '';\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  string  $signature\n     * @param  \\Closure  $callback\n     */\n    public function __construct($signature, Closure $callback)\n    {\n        $this->callback = $callback;\n        $this->signature = $signature;\n\n        parent::__construct();\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return int\n     */\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        $inputs = array_merge($input->getArguments(), $input->getOptions());\n\n        $parameters = [];\n\n        foreach ((new ReflectionFunction($this->callback))->getParameters() as $parameter) {\n            if (isset($inputs[$parameter->getName()])) {\n                $parameters[$parameter->getName()] = $inputs[$parameter->getName()];\n            }\n        }\n\n        try {\n            return (int) $this->laravel->call(\n                $this->callback->bindTo($this, $this), $parameters\n            );\n        } catch (ManuallyFailedException $e) {\n            $this->components->error($e->getMessage());\n\n            return static::FAILURE;\n        }\n    }\n\n    /**\n     * Set the description for the command.\n     *\n     * @param  string  $description\n     * @return $this\n     */\n    public function purpose($description)\n    {\n        return $this->describe($description);\n    }\n\n    /**\n     * Set the description for the command.\n     *\n     * @param  string  $description\n     * @return $this\n     */\n    public function describe($description)\n    {\n        $this->setDescription($description);\n\n        return $this;\n    }\n\n    /**\n     * Create a new scheduled event for the command.\n     *\n     * @param  array  $parameters\n     * @return \\Illuminate\\Console\\Scheduling\\Event\n     */\n    public function schedule($parameters = [])\n    {\n        return Schedule::command($this->name, $parameters);\n    }\n\n    /**\n     * Dynamically proxy calls to a new scheduled event.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->schedule(), $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ComponentMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Foundation\\Inspiring;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:component')]\nclass ComponentMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:component';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new view component class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Component';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if ($this->option('view')) {\n            return $this->writeView();\n        }\n\n        if (parent::handle() === false && ! $this->option('force')) {\n            return;\n        }\n\n        if (! $this->option('inline')) {\n            $this->writeView();\n        }\n    }\n\n    /**\n     * Write the view for the component.\n     *\n     * @return void\n     */\n    protected function writeView()\n    {\n        $separator = '/';\n\n        if (windows_os()) {\n            $separator = '\\\\';\n        }\n\n        $path = $this->viewPath(\n            str_replace('.', $separator, $this->getView()).'.blade.php'\n        );\n\n        if (! $this->files->isDirectory(dirname($path))) {\n            $this->files->makeDirectory(dirname($path), 0777, true, true);\n        }\n\n        if ($this->files->exists($path) && ! $this->option('force')) {\n            $this->components->error('View already exists.');\n\n            return;\n        }\n\n        file_put_contents(\n            $path,\n            '<div>\n    <!-- '.Inspiring::quotes()->random().' -->\n</div>'\n        );\n\n        $this->components->info(sprintf('%s [%s] created successfully.', 'View', $path));\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        if ($this->option('inline')) {\n            return str_replace(\n                ['DummyView', '{{ view }}'],\n                \"<<<'blade'\\n<div>\\n    <!-- \".Inspiring::quotes()->random().\" -->\\n</div>\\nblade\",\n                parent::buildClass($name)\n            );\n        }\n\n        return str_replace(\n            ['DummyView', '{{ view }}'],\n            'view(\\''.$this->getView().'\\')',\n            parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Get the view name relative to the view path.\n     *\n     * @return string view\n     */\n    protected function getView()\n    {\n        $segments = explode('/', str_replace('\\\\', '/', $this->argument('name')));\n\n        $name = array_pop($segments);\n\n        $path = is_string($this->option('path'))\n            ? explode('/', trim($this->option('path'), '/'))\n            : [\n                'components',\n                ...$segments,\n            ];\n\n        $path[] = $name;\n\n        return (new Collection($path))\n            ->map(fn ($segment) => Str::kebab($segment))\n            ->implode('.');\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/view-component.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\View\\Components';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['inline', null, InputOption::VALUE_NONE, 'Create a component that renders an inline view'],\n            ['view', null, InputOption::VALUE_NONE, 'Create an anonymous component with only a view'],\n            ['path', null, InputOption::VALUE_REQUIRED, 'The location where the component view should be created'],\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the component already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConfigCacheCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Arr;\nuse LogicException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Throwable;\n\n#[AsCommand(name: 'config:cache')]\nclass ConfigCacheCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'config:cache';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a cache file for faster configuration loading';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new config cache command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function handle()\n    {\n        $this->callSilent('config:clear');\n\n        $config = $this->getFreshConfiguration();\n\n        $configPath = $this->laravel->getCachedConfigPath();\n\n        $this->files->put(\n            $configPath, '<?php return '.var_export($config, true).';'.PHP_EOL\n        );\n\n        try {\n            require $configPath;\n        } catch (Throwable $e) {\n            $this->files->delete($configPath);\n\n            foreach (Arr::dot($config) as $key => $value) {\n                try {\n                    eval(var_export($value, true).';');\n                } catch (Throwable $e) {\n                    throw new LogicException(\"Your configuration files could not be serialized because the value at \\\"{$key}\\\" is non-serializable.\", 0, $e);\n                }\n            }\n\n            throw new LogicException('Your configuration files are not serializable.', 0, $e);\n        }\n\n        $this->components->info('Configuration cached successfully.');\n    }\n\n    /**\n     * Boot a fresh copy of the application configuration.\n     *\n     * @return array\n     */\n    protected function getFreshConfiguration()\n    {\n        $app = require $this->laravel->bootstrapPath('app.php');\n\n        $app->useStoragePath($this->laravel->storagePath());\n\n        $app->make(ConsoleKernelContract::class)->bootstrap();\n\n        return $app['config']->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConfigClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'config:clear')]\nclass ConfigClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'config:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Remove the configuration cache file';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new config clear command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->files->delete($this->laravel->getCachedConfigPath());\n\n        $this->components->info('Configuration cache cleared successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConfigMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[AsCommand(name: 'make:config', aliases: ['config:make'])]\nclass ConfigMakeCommand extends GeneratorCommand\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $name = 'make:config';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new configuration file';\n\n    /**\n     * The type of file being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Config';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array<int, string>\n     */\n    protected $aliases = ['config:make'];\n\n    /**\n     * Get the destination file path.\n     *\n     * @param  string  $name\n     */\n    protected function getPath($name): string\n    {\n        return config_path(Str::finish($this->argument('name'), '.php'));\n    }\n\n    /**\n     * Get the stub file for the generator.\n     */\n    protected function getStub(): string\n    {\n        $relativePath = join_paths('stubs', 'config.stub');\n\n        return file_exists($customPath = $this->laravel->basePath($relativePath))\n            ? $customPath\n            : join_paths(__DIR__, $relativePath);\n    }\n\n    /**\n     * Get the console command arguments.\n     */\n    protected function getOptions(): array\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the configuration file even if it already exists'],\n        ];\n    }\n\n    /**\n     * Prompt for missing input arguments using the returned questions.\n     *\n     * @return array\n     */\n    protected function promptForMissingArgumentsUsing()\n    {\n        return [\n            'name' => 'What should the configuration file be named?',\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConfigPublishCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Finder\\Finder;\n\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'config:publish')]\nclass ConfigPublishCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'config:publish\n                    {name? : The name of the configuration file to publish}\n                    {--all : Publish all configuration files}\n                    {--force : Overwrite any existing configuration files}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Publish configuration files to your application';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        $config = $this->getBaseConfigurationFiles();\n\n        if (is_null($this->argument('name')) && $this->option('all')) {\n            foreach ($config as $key => $file) {\n                $this->publish($key, $file, $this->laravel->configPath().'/'.$key.'.php');\n            }\n\n            return;\n        }\n\n        $name = (string) (is_null($this->argument('name')) ? select(\n            label: 'Which configuration file would you like to publish?',\n            options: (new Collection($config))->map(fn (string $path) => basename($path, '.php')),\n        ) : $this->argument('name'));\n\n        if (! is_null($name) && ! isset($config[$name])) {\n            $this->components->error('Unrecognized configuration file.');\n\n            return 1;\n        }\n\n        $this->publish($name, $config[$name], $this->laravel->configPath().'/'.$name.'.php');\n    }\n\n    /**\n     * Publish the given file to the given destination.\n     *\n     * @param  string  $name\n     * @param  string  $file\n     * @param  string  $destination\n     * @return void\n     */\n    protected function publish(string $name, string $file, string $destination)\n    {\n        if (file_exists($destination) && ! $this->option('force')) {\n            $this->components->error(\"The '{$name}' configuration file already exists.\");\n\n            return;\n        }\n\n        copy($file, $destination);\n\n        $this->components->info(\"Published '{$name}' configuration file.\");\n    }\n\n    /**\n     * Get an array containing the base configuration files.\n     *\n     * @return array\n     */\n    protected function getBaseConfigurationFiles()\n    {\n        $config = [];\n\n        $shouldMergeConfiguration = $this->laravel->shouldMergeFrameworkConfiguration();\n\n        foreach (Finder::create()->files()->name('*.php')->in(__DIR__.'/../../../../config') as $file) {\n            $name = basename($file->getRealPath(), '.php');\n\n            $config[$name] = ($shouldMergeConfiguration === true && file_exists($stubPath = (__DIR__.'/../../../../config-stubs/'.$name.'.php')))\n                ? $stubPath\n                : $file->getRealPath();\n        }\n\n        return (new Collection($config))->sortKeys()->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConfigShowCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Arr;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'config:show')]\nclass ConfigShowCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'config:show {config : The configuration file or key to show}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Display all of the values for a given configuration file or key';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        $config = $this->argument('config');\n\n        if (! config()->has($config)) {\n            $this->fail(\"Configuration file or key <comment>{$config}</comment> does not exist.\");\n        }\n\n        $this->newLine();\n        $this->render($config);\n        $this->newLine();\n\n        return Command::SUCCESS;\n    }\n\n    /**\n     * Render the configuration values.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function render($name)\n    {\n        $data = config($name);\n\n        if (! is_array($data)) {\n            $this->title($name, $this->formatValue($data));\n\n            return;\n        }\n\n        $this->title($name);\n\n        foreach (Arr::dot($data) as $key => $value) {\n            $this->components->twoColumnDetail(\n                $this->formatKey($key),\n                $this->formatValue($value)\n            );\n        }\n    }\n\n    /**\n     * Render the title.\n     *\n     * @param  string  $title\n     * @param  string|null  $subtitle\n     * @return void\n     */\n    public function title($title, $subtitle = null)\n    {\n        $this->components->twoColumnDetail(\n            \"<fg=green;options=bold>{$title}</>\",\n            $subtitle,\n        );\n    }\n\n    /**\n     * Format the given configuration key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function formatKey($key)\n    {\n        return preg_replace_callback(\n            '/(.*)\\.(.*)$/', fn ($matches) => sprintf(\n                '<fg=gray>%s ⇁</> %s',\n                str_replace('.', ' ⇁ ', $matches[1]),\n                $matches[2]\n            ), $key\n        );\n    }\n\n    /**\n     * Format the given configuration value.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function formatValue($value)\n    {\n        return match (true) {\n            is_bool($value) => sprintf('<fg=#ef8414;options=bold>%s</>', $value ? 'true' : 'false'),\n            is_null($value) => '<fg=#ef8414;options=bold>null</>',\n            is_numeric($value) => \"<fg=#ef8414;options=bold>{$value}</>\",\n            is_array($value) => '[]',\n            is_object($value) => get_class($value),\n            is_string($value) => $value,\n            default => print_r($value, true),\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ConsoleMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:command')]\nclass ConsoleMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:command';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new Artisan command';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Console command';\n\n    /**\n     * Replace the class name for the given stub.\n     *\n     * @param  string  $stub\n     * @param  string  $name\n     * @return string\n     */\n    protected function replaceClass($stub, $name)\n    {\n        $stub = parent::replaceClass($stub, $name);\n\n        $command = $this->option('command') ?: 'app:'.(new Stringable($name))->classBasename()->kebab()->value();\n\n        return str_replace(['dummy:command', '{{ command }}'], $command, $stub);\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        $relativePath = '/stubs/console.stub';\n\n        return file_exists($customPath = $this->laravel->basePath(trim($relativePath, '/')))\n            ? $customPath\n            : __DIR__.$relativePath;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Console\\Commands';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getArguments()\n    {\n        return [\n            ['name', InputArgument::REQUIRED, 'The name of the command'],\n        ];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the console command already exists'],\n            ['command', null, InputOption::VALUE_OPTIONAL, 'The terminal command that will be used to invoke the class'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/DocsCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Http\\Client\\Factory as Http;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\nuse Symfony\\Component\\Process\\ExecutableFinder;\nuse Symfony\\Component\\Process\\Process;\nuse Throwable;\n\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'docs')]\nclass DocsCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'docs {page? : The documentation page to open} {section? : The section of the page to open}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Access the Laravel documentation';\n\n    /**\n     * The console command help text.\n     *\n     * @var string\n     */\n    protected $help = 'If you would like to perform a content search against the documentation, you may call: <fg=green>php artisan docs -- </><fg=green;options=bold;>search query here</>';\n\n    /**\n     * The HTTP client instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Factory\n     */\n    protected $http;\n\n    /**\n     * The cache repository implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * The custom URL opener.\n     *\n     * @var callable|null\n     */\n    protected $urlOpener;\n\n    /**\n     * The custom documentation version to open.\n     *\n     * @var string|null\n     */\n    protected $version;\n\n    /**\n     * The operating system family.\n     *\n     * @var string\n     */\n    protected $systemOsFamily = PHP_OS_FAMILY;\n\n    /**\n     * Configure the current command.\n     *\n     * @return void\n     */\n    protected function configure(): void\n    {\n        parent::configure();\n\n        if ($this->isSearching()) {\n            $this->ignoreValidationErrors();\n        }\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Factory  $http\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     * @return int\n     *\n     * @throws \\Symfony\\Component\\Process\\Exception\\ProcessFailedException\n     */\n    public function handle(Http $http, Cache $cache)\n    {\n        $this->http = $http;\n        $this->cache = $cache;\n\n        try {\n            $this->openUrl();\n        } catch (ProcessFailedException $e) {\n            if ($e->getProcess()->getExitCodeText() === 'Interrupt') {\n                return $e->getProcess()->getExitCode();\n            }\n\n            throw $e;\n        }\n\n        $this->refreshDocs();\n\n        return Command::SUCCESS;\n    }\n\n    /**\n     * Open the documentation URL.\n     *\n     * @return void\n     */\n    protected function openUrl()\n    {\n        $url = $this->url();\n\n        $this->components->info(\"Opening the docs to: <fg=yellow>{$url}</>\");\n\n        $this->open($url);\n    }\n\n    /**\n     * The URL to the documentation page.\n     *\n     * @return string\n     */\n    protected function url()\n    {\n        if ($this->isSearching()) {\n            return \"https://laravel.com/docs/{$this->version()}?\".Arr::query([\n                'q' => $this->searchQuery(),\n            ]);\n        }\n\n        $page = $this->page();\n\n        return trim(\"https://laravel.com/docs/{$this->version()}/{$page}#{$this->section($page)}\", '#/');\n    }\n\n    /**\n     * The page the user is opening.\n     *\n     * @return string\n     */\n    protected function page()\n    {\n        $page = $this->resolvePage();\n\n        if ($page === null) {\n            $this->components->warn('Unable to determine the page you are trying to visit.');\n\n            return '/';\n        }\n\n        return $page;\n    }\n\n    /**\n     * Determine the page to open.\n     *\n     * @return string|null\n     */\n    protected function resolvePage()\n    {\n        if ($this->option('no-interaction') && $this->didNotRequestPage()) {\n            return '/';\n        }\n\n        return $this->didNotRequestPage()\n            ? $this->askForPage()\n            : $this->guessPage($this->argument('page'));\n    }\n\n    /**\n     * Determine if the user requested a specific page when calling the command.\n     *\n     * @return bool\n     */\n    protected function didNotRequestPage()\n    {\n        return $this->argument('page') === null;\n    }\n\n    /**\n     * Ask the user which page they would like to open.\n     *\n     * @return string|null\n     */\n    protected function askForPage()\n    {\n        return $this->askForPageViaCustomStrategy() ?? $this->askForPageViaAutocomplete();\n    }\n\n    /**\n     * Ask the user which page they would like to open via a custom strategy.\n     *\n     * @return string|null\n     */\n    protected function askForPageViaCustomStrategy()\n    {\n        try {\n            $strategy = require Env::get('ARTISAN_DOCS_ASK_STRATEGY');\n        } catch (Throwable) {\n            return null;\n        }\n\n        if (! is_callable($strategy)) {\n            return null;\n        }\n\n        return $strategy($this) ?? '/';\n    }\n\n    /**\n     * Ask the user which page they would like to open using autocomplete.\n     *\n     * @return string|null\n     */\n    protected function askForPageViaAutocomplete()\n    {\n        $choice = suggest(\n            label: 'Which page would you like to open?',\n            options: fn ($value) => $this->pages()\n                ->mapWithKeys(fn ($option) => [\n                    Str::lower($option['title']) => $option['title'],\n                ])\n                ->filter(fn ($title) => str_contains(Str::lower($title), Str::lower($value)))\n                ->all(),\n            placeholder: 'E.g. Collections'\n        );\n\n        return $this->pages()->filter(\n            fn ($page) => $page['title'] === $choice || Str::lower($page['title']) === $choice\n        )->keys()->first() ?: $this->guessPage($choice);\n    }\n\n    /**\n     * Guess the page the user is attempting to open.\n     *\n     * @return string|null\n     */\n    protected function guessPage($search)\n    {\n        return $this->pages()\n            ->filter(fn ($page) => str_starts_with(\n                Str::slug($page['title'], ' '),\n                Str::slug($search, ' ')\n            ))->keys()->first() ?? $this->pages()->map(fn ($page) => similar_text(\n                Str::slug($page['title'], ' '),\n                Str::slug($search, ' '),\n            ))\n            ->filter(fn ($score) => $score >= min(3, Str::length($search)))\n            ->sortDesc()\n            ->keys()\n            ->sortByDesc(fn ($slug) => Str::contains(\n                Str::slug($this->pages()[$slug]['title'], ' '),\n                Str::slug($search, ' ')\n            ) ? 1 : 0)\n            ->first();\n    }\n\n    /**\n     * The section the user specifically asked to open.\n     *\n     * @param  string  $page\n     * @return string|null\n     */\n    protected function section($page)\n    {\n        return $this->didNotRequestSection()\n            ? null\n            : $this->guessSection($page);\n    }\n\n    /**\n     * Determine if the user requested a specific section when calling the command.\n     *\n     * @return bool\n     */\n    protected function didNotRequestSection()\n    {\n        return $this->argument('section') === null;\n    }\n\n    /**\n     * Guess the section the user is attempting to open.\n     *\n     * @param  string  $page\n     * @return string|null\n     */\n    protected function guessSection($page)\n    {\n        return $this->sectionsFor($page)\n            ->filter(fn ($section) => str_starts_with(\n                Str::slug($section['title'], ' '),\n                Str::slug($this->argument('section'), ' ')\n            ))->keys()->first() ?? $this->sectionsFor($page)->map(fn ($section) => similar_text(\n                Str::slug($section['title'], ' '),\n                Str::slug($this->argument('section'), ' '),\n            ))\n            ->filter(fn ($score) => $score >= min(3, Str::length($this->argument('section'))))\n            ->sortDesc()\n            ->keys()\n            ->sortByDesc(fn ($slug) => Str::contains(\n                Str::slug($this->sectionsFor($page)[$slug]['title'], ' '),\n                Str::slug($this->argument('section'), ' ')\n            ) ? 1 : 0)\n            ->first();\n    }\n\n    /**\n     * Open the URL in the user's browser.\n     *\n     * @param  string  $url\n     * @return void\n     */\n    protected function open($url)\n    {\n        ($this->urlOpener ?? function ($url) {\n            if (Env::get('ARTISAN_DOCS_OPEN_STRATEGY')) {\n                $this->openViaCustomStrategy($url);\n            } elseif (in_array($this->systemOsFamily, ['Darwin', 'Windows', 'Linux'])) {\n                $this->openViaBuiltInStrategy($url);\n            } else {\n                $this->components->warn('Unable to open the URL on your system. You will need to open it yourself or create a custom opener for your system.');\n            }\n        })($url);\n    }\n\n    /**\n     * Open the URL via a custom strategy.\n     *\n     * @param  string  $url\n     * @return void\n     */\n    protected function openViaCustomStrategy($url)\n    {\n        try {\n            $command = require Env::get('ARTISAN_DOCS_OPEN_STRATEGY');\n        } catch (Throwable) {\n            $command = null;\n        }\n\n        if (! is_callable($command)) {\n            $this->components->warn('Unable to open the URL with your custom strategy. You will need to open it yourself.');\n\n            return;\n        }\n\n        $command($url);\n    }\n\n    /**\n     * Open the URL via the built in strategy.\n     *\n     * @param  string  $url\n     * @return void\n     *\n     * @throws \\Symfony\\Component\\Process\\Exception\\ProcessFailedException\n     */\n    protected function openViaBuiltInStrategy($url)\n    {\n        if ($this->systemOsFamily === 'Windows') {\n            $process = tap(Process::fromShellCommandline(escapeshellcmd(\"start {$url}\")))->run();\n\n            if (! $process->isSuccessful()) {\n                throw new ProcessFailedException($process);\n            }\n\n            return;\n        }\n\n        $binary = (new Collection(match ($this->systemOsFamily) {\n            'Darwin' => ['open'],\n            'Linux' => ['xdg-open', 'wslview'],\n        }))->first(fn ($binary) => (new ExecutableFinder)->find($binary) !== null);\n\n        if ($binary === null) {\n            $this->components->warn('Unable to open the URL on your system. You will need to open it yourself or create a custom opener for your system.');\n\n            return;\n        }\n\n        $process = tap(Process::fromShellCommandline(escapeshellcmd(\"{$binary} {$url}\")))->run();\n\n        if (! $process->isSuccessful()) {\n            throw new ProcessFailedException($process);\n        }\n    }\n\n    /**\n     * The available sections for the page.\n     *\n     * @param  string  $page\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function sectionsFor($page)\n    {\n        return new Collection($this->pages()[$page]['sections']);\n    }\n\n    /**\n     * The pages available to open.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function pages()\n    {\n        return new Collection($this->docs()['pages']);\n    }\n\n    /**\n     * Get the documentation index as a collection.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function docs()\n    {\n        return $this->cache->remember(\n            \"artisan.docs.{{$this->version()}}.index\",\n            CarbonInterval::months(2),\n            fn () => $this->fetchDocs()->throw()->collect()\n        );\n    }\n\n    /**\n     * Refresh the cached copy of the documentation index.\n     *\n     * @return void\n     */\n    protected function refreshDocs()\n    {\n        $response = $this->fetchDocs();\n\n        if ($response->successful()) {\n            $this->cache->put(\"artisan.docs.{{$this->version()}}.index\", $response->collect(), CarbonInterval::months(2));\n        }\n    }\n\n    /**\n     * Fetch the documentation index from the Laravel website.\n     *\n     * @return \\Illuminate\\Http\\Client\\Response\n     */\n    protected function fetchDocs()\n    {\n        return $this->http->get(\"https://laravel.com/docs/{$this->version()}/index.json\");\n    }\n\n    /**\n     * Determine the version of the docs to open.\n     *\n     * @return string\n     */\n    protected function version()\n    {\n        return Str::before($this->version ?? $this->laravel->version(), '.').'.x';\n    }\n\n    /**\n     * The search query the user provided.\n     *\n     * @return string\n     */\n    protected function searchQuery()\n    {\n        return (new Collection($_SERVER['argv']))->skip(3)->implode(' ');\n    }\n\n    /**\n     * Determine if the command is intended to perform a search.\n     *\n     * @return bool\n     */\n    protected function isSearching()\n    {\n        return ($_SERVER['argv'][2] ?? null) === '--';\n    }\n\n    /**\n     * Set the documentation version.\n     *\n     * @param  string  $version\n     * @return $this\n     */\n    public function setVersion($version)\n    {\n        $this->version = $version;\n\n        return $this;\n    }\n\n    /**\n     * Set a custom URL opener.\n     *\n     * @param  callable|null  $opener\n     * @return $this\n     */\n    public function setUrlOpener($opener)\n    {\n        $this->urlOpener = $opener;\n\n        return $this;\n    }\n\n    /**\n     * Set the system operating system family.\n     *\n     * @param  string  $family\n     * @return $this\n     */\n    public function setSystemOsFamily($family)\n    {\n        $this->systemOsFamily = $family;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/DownCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse App\\Http\\Middleware\\PreventRequestsDuringMaintenance as AppPreventRequestsDuringMaintenance;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Foundation\\Events\\MaintenanceModeEnabled;\nuse Illuminate\\Foundation\\Exceptions\\RegisterErrorViewPaths;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Throwable;\n\n#[AsCommand(name: 'down')]\nclass DownCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'down {--redirect= : The path that users should be redirected to}\n                                 {--render= : The view that should be prerendered for display during maintenance mode}\n                                 {--retry= : The number of seconds or the datetime after which the request may be retried}\n                                 {--refresh= : The number of seconds after which the browser may refresh}\n                                 {--secret= : The secret phrase that may be used to bypass maintenance mode}\n                                 {--with-secret : Generate a random secret phrase that may be used to bypass maintenance mode}\n                                 {--status=503 : The status code that should be used when returning the maintenance mode response}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Put the application into maintenance / demo mode';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        try {\n            $wasAlreadyDown = $this->laravel->maintenanceMode()->active();\n\n            $downFilePayload = $this->getDownFilePayload();\n\n            $this->laravel->maintenanceMode()->activate($downFilePayload);\n\n            file_put_contents(\n                storage_path('framework/maintenance.php'),\n                file_get_contents(__DIR__.'/stubs/maintenance-mode.stub')\n            );\n\n            $this->laravel->get('events')->dispatch(new MaintenanceModeEnabled());\n\n            $this->components->info($wasAlreadyDown\n                ? 'Maintenance mode options updated.'\n                : 'Application is now in maintenance mode.'\n            );\n\n            if ($downFilePayload['secret'] !== null) {\n                $this->components->info('You may bypass maintenance mode via ['.config('app.url').\"/{$downFilePayload['secret']}].\");\n            }\n        } catch (Exception $e) {\n            $this->components->error(sprintf(\n                'Failed to enter maintenance mode: %s.',\n                $e->getMessage(),\n            ));\n\n            return 1;\n        }\n    }\n\n    /**\n     * Get the payload to be placed in the \"down\" file.\n     *\n     * @return array\n     */\n    protected function getDownFilePayload()\n    {\n        return [\n            'except' => $this->excludedPaths(),\n            'redirect' => $this->redirectPath(),\n            'retry' => $this->getRetryTime(),\n            'refresh' => $this->option('refresh'),\n            'secret' => $this->getSecret(),\n            'status' => (int) ($this->option('status') ?? 503),\n            'template' => $this->option('render') ? $this->prerenderView() : null,\n        ];\n    }\n\n    /**\n     * Get the paths that should be excluded from maintenance mode.\n     *\n     * @return array\n     */\n    protected function excludedPaths()\n    {\n        try {\n            return $this->laravel->make(AppPreventRequestsDuringMaintenance::class)->getExcludedPaths();\n        } catch (Throwable) {\n            try {\n                return $this->laravel->make(PreventRequestsDuringMaintenance::class)->getExcludedPaths();\n            } catch (Throwable) {\n                return [];\n            }\n        }\n    }\n\n    /**\n     * Get the path that users should be redirected to.\n     *\n     * @return string\n     */\n    protected function redirectPath()\n    {\n        if ($this->option('redirect') && $this->option('redirect') !== '/') {\n            return '/'.trim($this->option('redirect'), '/');\n        }\n\n        return $this->option('redirect');\n    }\n\n    /**\n     * Prerender the specified view so that it can be rendered even before loading Composer.\n     *\n     * @return string\n     */\n    protected function prerenderView()\n    {\n        (new RegisterErrorViewPaths)();\n\n        return view($this->option('render'), [\n            'retryAfter' => $this->option('retry'),\n        ])->render();\n    }\n\n    /**\n     * Get the number of seconds or date / time the client should wait before retrying their request.\n     *\n     * @return int|string|null\n     */\n    protected function getRetryTime()\n    {\n        $retry = $this->option('retry');\n\n        if (is_numeric($retry) && $retry > 0) {\n            return (int) $retry;\n        }\n\n        if (is_string($retry) && ! empty($retry)) {\n            try {\n                $date = Carbon::parse($retry);\n\n                return $date->format(DateTimeInterface::RFC7231);\n            } catch (Exception) {\n                return null;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Get the secret phrase that may be used to bypass maintenance mode.\n     *\n     * @return string|null\n     */\n    protected function getSecret()\n    {\n        return match (true) {\n            ! is_null($this->option('secret')) => $this->option('secret'),\n            $this->option('with-secret') => Str::random(),\n            default => null,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EnumMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'make:enum')]\nclass EnumMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:enum';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new enum';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Enum';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('string') || $this->option('int')) {\n            return $this->resolveStubPath('/stubs/enum.backed.stub');\n        }\n\n        return $this->resolveStubPath('/stubs/enum.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return match (true) {\n            is_dir(app_path('Enums')) => $rootNamespace.'\\\\Enums',\n            is_dir(app_path('Enumerations')) => $rootNamespace.'\\\\Enumerations',\n            default => $rootNamespace,\n        };\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    protected function buildClass($name)\n    {\n        if ($this->option('string') || $this->option('int')) {\n            return str_replace(\n                ['{{ type }}'],\n                $this->option('string') ? 'string' : 'int',\n                parent::buildClass($name)\n            );\n        }\n\n        return parent::buildClass($name);\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $type = select('Which type of enum would you like?', [\n            'pure' => 'Pure enum',\n            'string' => 'Backed enum (String)',\n            'int' => 'Backed enum (Integer)',\n        ]);\n\n        if ($type !== 'pure') {\n            $input->setOption($type, true);\n        }\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['string', 's', InputOption::VALUE_NONE, 'Generate a string backed enum.'],\n            ['int', 'i', InputOption::VALUE_NONE, 'Generate an integer backed enum.'],\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the enum even if the enum already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EnvironmentCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'env')]\nclass EnvironmentCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'env';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Display the current framework environment';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->components->info(sprintf(\n            'The application environment is [%s].',\n            $this->laravel['env'],\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EnvironmentDecryptCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Dotenv\\Parser\\Lines;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Laravel\\Prompts\\password;\n\n#[AsCommand(name: 'env:decrypt')]\nclass EnvironmentDecryptCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'env:decrypt\n                    {--key= : The encryption key}\n                    {--cipher= : The encryption cipher}\n                    {--env= : The environment to be decrypted}\n                    {--force : Overwrite the existing environment file}\n                    {--path= : Path to write the decrypted file}\n                    {--filename= : Filename of the decrypted file}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Decrypt an environment file';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $key = $this->option('key') ?: Env::get('LARAVEL_ENV_ENCRYPTION_KEY');\n\n        if (! $key && $this->input->isInteractive()) {\n            $key = password('What is the decryption key?');\n        }\n\n        if (! $key) {\n            $this->fail('A decryption key is required.');\n        }\n\n        $cipher = $this->option('cipher') ?: 'AES-256-CBC';\n\n        $key = $this->parseKey($key);\n\n        $encryptedFile = ($this->option('env')\n            ? Str::finish($this->laravel->environmentPath(), DIRECTORY_SEPARATOR).'.env.'.$this->option('env')\n            : $this->laravel->environmentFilePath()).'.encrypted';\n\n        $outputFile = $this->outputFilePath();\n\n        if (Str::endsWith($outputFile, '.encrypted')) {\n            $this->fail('Invalid filename.');\n        }\n\n        if (! $this->files->exists($encryptedFile)) {\n            $this->fail('Encrypted environment file not found.');\n        }\n\n        if ($this->files->exists($outputFile) && ! $this->option('force')) {\n            $this->fail('Environment file already exists.');\n        }\n\n        try {\n            $encrypter = new Encrypter($key, $cipher);\n\n            $encryptedContents = $this->files->get($encryptedFile);\n\n            $decrypted = $this->isReadableFormat($encryptedContents)\n                ? $this->decryptReadableFormat($encryptedContents, $encrypter)\n                : $encrypter->decrypt($encryptedContents);\n\n            $this->files->put($outputFile, $decrypted);\n        } catch (Exception $e) {\n            $this->fail($e->getMessage());\n        }\n\n        $this->components->info('Environment successfully decrypted.');\n\n        $this->components->twoColumnDetail('Decrypted file', $outputFile);\n\n        $this->newLine();\n    }\n\n    /**\n     * Determine if the content is in readable format where each variable still has its own plain-text key.\n     *\n     * @param  string  $contents\n     * @return bool\n     */\n    protected function isReadableFormat(string $contents): bool\n    {\n        return ! Encrypter::appearsEncrypted($contents);\n    }\n\n    /**\n     * Decrypt the environment file from readable format.\n     *\n     * @param  string  $contents\n     * @param  \\Illuminate\\Encryption\\Encrypter  $encrypter\n     * @return string\n     */\n    protected function decryptReadableFormat(string $contents, Encrypter $encrypter): string\n    {\n        $result = '';\n\n        foreach (Lines::process(preg_split('/\\r\\n|\\r|\\n/', $contents)) as $entry) {\n            $pos = strpos($entry, '=');\n\n            if ($pos === false) {\n                continue;\n            }\n\n            $name = substr($entry, 0, $pos);\n            $encryptedValue = substr($entry, $pos + 1);\n\n            $result .= $name.'='.$encrypter->decryptString($encryptedValue).\"\\n\";\n        }\n\n        return $result;\n    }\n\n    /**\n     * Parse the encryption key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function parseKey(string $key)\n    {\n        if (Str::startsWith($key, $prefix = 'base64:')) {\n            $key = base64_decode(Str::after($key, $prefix));\n        }\n\n        return $key;\n    }\n\n    /**\n     * Get the output file path that should be used for the command.\n     *\n     * @return string\n     */\n    protected function outputFilePath()\n    {\n        $path = Str::finish($this->option('path') ?: $this->laravel->environmentPath(), DIRECTORY_SEPARATOR);\n\n        $outputFile = $this->option('filename') ?: ('.env'.($this->option('env') ? '.'.$this->option('env') : ''));\n        $outputFile = ltrim($outputFile, DIRECTORY_SEPARATOR);\n\n        return $path.$outputFile;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EnvironmentEncryptCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Dotenv\\Parser\\Lines;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Laravel\\Prompts\\password;\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'env:encrypt')]\nclass EnvironmentEncryptCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'env:encrypt\n                    {--key= : The encryption key}\n                    {--cipher= : The encryption cipher}\n                    {--env= : The environment to be encrypted}\n                    {--readable : Encrypt each variable individually with readable, plain-text variable names}\n                    {--prune : Delete the original environment file}\n                    {--force : Overwrite the existing encrypted environment file}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Encrypt an environment file';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $cipher = $this->option('cipher') ?: 'AES-256-CBC';\n\n        $key = $this->option('key');\n\n        if (! $key && $this->input->isInteractive()) {\n            $ask = select(\n                label: 'What encryption key would you like to use?',\n                options: [\n                    'generate' => 'Generate a random encryption key',\n                    'ask' => 'Provide an encryption key',\n                ],\n                default: 'generate'\n            );\n\n            if ($ask == 'ask') {\n                $key = password('What is the encryption key?');\n            }\n        }\n\n        $keyPassed = $key !== null;\n\n        $environmentFile = $this->option('env')\n            ? Str::finish($this->laravel->environmentPath(), DIRECTORY_SEPARATOR).'.env.'.$this->option('env')\n            : $this->laravel->environmentFilePath();\n\n        $encryptedFile = $environmentFile.'.encrypted';\n\n        if (! $keyPassed) {\n            $key = Encrypter::generateKey($cipher);\n        }\n\n        if (! $this->files->exists($environmentFile)) {\n            $this->fail('Environment file not found.');\n        }\n\n        if ($this->files->exists($encryptedFile) && ! $this->option('force')) {\n            $this->fail('Encrypted environment file already exists.');\n        }\n\n        try {\n            $encrypter = new Encrypter($this->parseKey($key), $cipher);\n\n            $contents = $this->files->get($environmentFile);\n\n            $encrypted = $this->option('readable')\n                ? $this->encryptReadableFormat($contents, $encrypter)\n                : $encrypter->encrypt($contents);\n\n            $this->files->put($encryptedFile, $encrypted);\n        } catch (Exception $e) {\n            $this->fail($e->getMessage());\n        }\n\n        if ($this->option('prune')) {\n            $this->files->delete($environmentFile);\n        }\n\n        $this->components->info('Environment successfully encrypted.');\n\n        $this->components->twoColumnDetail('Key', $keyPassed ? $key : 'base64:'.base64_encode($key));\n        $this->components->twoColumnDetail('Cipher', $cipher);\n        $this->components->twoColumnDetail('Encrypted file', $encryptedFile);\n\n        $this->newLine();\n    }\n\n    /**\n     * Encrypt the environment file in readable format.\n     *\n     * @param  string  $contents\n     * @param  \\Illuminate\\Encryption\\Encrypter  $encrypter\n     * @return string\n     */\n    protected function encryptReadableFormat(string $contents, Encrypter $encrypter): string\n    {\n        $result = '';\n\n        foreach (Lines::process(preg_split('/\\r\\n|\\r|\\n/', $contents)) as $entry) {\n            $pos = strpos($entry, '=');\n\n            if ($pos === false) {\n                continue;\n            }\n\n            $name = substr($entry, 0, $pos);\n            $value = substr($entry, $pos + 1);\n\n            $result .= $name.'='.$encrypter->encryptString($value).\"\\n\";\n        }\n\n        return $result;\n    }\n\n    /**\n     * Parse the encryption key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function parseKey(string $key)\n    {\n        if (Str::startsWith($key, $prefix = 'base64:')) {\n            $key = base64_decode(Str::after($key, $prefix));\n        }\n\n        return $key;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EventCacheCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Foundation\\Support\\Providers\\EventServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'event:cache')]\nclass EventCacheCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'event:cache';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = \"Discover and cache the application's events and listeners\";\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->callSilent('event:clear');\n\n        file_put_contents(\n            $this->laravel->getCachedEventsPath(),\n            '<?php return '.var_export($this->getEvents(), true).';'\n        );\n\n        $this->components->info('Events cached successfully.');\n    }\n\n    /**\n     * Get all of the events and listeners configured for the application.\n     *\n     * @return array\n     */\n    protected function getEvents()\n    {\n        $events = [];\n\n        foreach ($this->laravel->getProviders(EventServiceProvider::class) as $provider) {\n            $providerEvents = array_merge_recursive($provider->shouldDiscoverEvents() ? $provider->discoverEvents() : [], $provider->listens());\n\n            $events[get_class($provider)] = $providerEvents;\n        }\n\n        return $events;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EventClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'event:clear')]\nclass EventClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'event:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Clear all cached events and listeners';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new config clear command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function handle()\n    {\n        $this->files->delete($this->laravel->getCachedEventsPath());\n\n        $this->components->info('Cached events cleared successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EventGenerateCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Foundation\\Support\\Providers\\EventServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'event:generate')]\nclass EventGenerateCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'event:generate';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Generate the missing events and listeners based on registration';\n\n    /**\n     * Indicates whether the command should be shown in the Artisan command list.\n     *\n     * @var bool\n     */\n    protected $hidden = true;\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $providers = $this->laravel->getProviders(EventServiceProvider::class);\n\n        foreach ($providers as $provider) {\n            foreach ($provider->listens() as $event => $listeners) {\n                $this->makeEventAndListeners($event, $listeners);\n            }\n        }\n\n        $this->components->info('Events and listeners generated successfully.');\n    }\n\n    /**\n     * Make the event and listeners for the given event.\n     *\n     * @param  string  $event\n     * @param  array  $listeners\n     * @return void\n     */\n    protected function makeEventAndListeners($event, $listeners)\n    {\n        if (! str_contains($event, '\\\\')) {\n            return;\n        }\n\n        $this->callSilent('make:event', ['name' => $event]);\n\n        $this->makeListeners($event, $listeners);\n    }\n\n    /**\n     * Make the listeners for the given event.\n     *\n     * @param  string  $event\n     * @param  array  $listeners\n     * @return void\n     */\n    protected function makeListeners($event, $listeners)\n    {\n        foreach ($listeners as $listener) {\n            $listener = preg_replace('/@.+$/', '', $listener);\n\n            $this->callSilent('make:listener', array_filter(\n                ['name' => $listener, '--event' => $event]\n            ));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EventListCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Support\\Collection;\nuse ReflectionFunction;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'event:list')]\nclass EventListCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'event:list\n                            {--event= : Filter the events by name}\n                            {--json : Output the events and listeners as JSON}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = \"List the application's events and listeners\";\n\n    /**\n     * The events dispatcher resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $eventsResolver;\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $events = $this->getEvents()->sortKeys();\n\n        if ($events->isEmpty()) {\n            if ($this->option('json')) {\n                $this->output->writeln('[]');\n            } else {\n                $this->components->info(\"Your application doesn't have any events matching the given criteria.\");\n            }\n\n            return;\n        }\n\n        if ($this->option('json')) {\n            $this->displayJson($events);\n        } else {\n            $this->displayForCli($events);\n        }\n    }\n\n    /**\n     * Display events and their listeners in JSON.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @return void\n     */\n    protected function displayJson(Collection $events)\n    {\n        $data = $events->map(function ($listeners, $event) {\n            return [\n                'event' => strip_tags($this->appendEventInterfaces($event)),\n                'listeners' => (new Collection($listeners))->map(fn ($listener) => strip_tags($listener))->values()->all(),\n            ];\n        })->values();\n\n        $this->output->writeln($data->toJson());\n    }\n\n    /**\n     * Display the events and their listeners for the CLI.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @return void\n     */\n    protected function displayForCli(Collection $events)\n    {\n        $this->newLine();\n\n        $events->each(function ($listeners, $event) {\n            $this->components->twoColumnDetail($this->appendEventInterfaces($event));\n            $this->components->bulletList($listeners);\n        });\n\n        $this->newLine();\n    }\n\n    /**\n     * Get all of the events and listeners configured for the application.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getEvents()\n    {\n        $events = new Collection($this->getListenersOnDispatcher());\n\n        if ($this->filteringByEvent()) {\n            $events = $this->filterEvents($events);\n        }\n\n        return $events;\n    }\n\n    /**\n     * Get the event / listeners from the dispatcher object.\n     *\n     * @return array\n     */\n    protected function getListenersOnDispatcher()\n    {\n        $events = [];\n\n        foreach ($this->getRawListeners() as $event => $rawListeners) {\n            foreach ($rawListeners as $rawListener) {\n                if (is_string($rawListener)) {\n                    $events[$event][] = $this->appendListenerInterfaces($rawListener);\n                } elseif ($rawListener instanceof Closure) {\n                    $events[$event][] = $this->stringifyClosure($rawListener);\n                } elseif (is_array($rawListener) && count($rawListener) === 2) {\n                    if (is_object($rawListener[0])) {\n                        $rawListener[0] = get_class($rawListener[0]);\n                    }\n\n                    $events[$event][] = $this->appendListenerInterfaces(implode('@', $rawListener));\n                }\n            }\n        }\n\n        return $events;\n    }\n\n    /**\n     * Add the event implemented interfaces to the output.\n     *\n     * @param  string  $event\n     * @return string\n     */\n    protected function appendEventInterfaces($event)\n    {\n        if (! class_exists($event)) {\n            return $event;\n        }\n\n        $interfaces = class_implements($event);\n\n        if (in_array(ShouldBroadcast::class, $interfaces)) {\n            $event .= ' <fg=bright-blue>(ShouldBroadcast)</>';\n        }\n\n        return $event;\n    }\n\n    /**\n     * Add the listener implemented interfaces to the output.\n     *\n     * @param  string  $listener\n     * @return string\n     */\n    protected function appendListenerInterfaces($listener)\n    {\n        $listener = explode('@', $listener);\n\n        $interfaces = class_implements($listener[0]);\n\n        $listener = implode('@', $listener);\n\n        if (in_array(ShouldQueue::class, $interfaces)) {\n            $listener .= ' <fg=bright-blue>(ShouldQueue)</>';\n        }\n\n        return $listener;\n    }\n\n    /**\n     * Get a displayable string representation of a Closure listener.\n     *\n     * @param  \\Closure  $rawListener\n     * @return string\n     */\n    protected function stringifyClosure(Closure $rawListener)\n    {\n        $reflection = new ReflectionFunction($rawListener);\n\n        $path = str_replace([base_path(), DIRECTORY_SEPARATOR], ['', '/'], $reflection->getFileName() ?: '');\n\n        return 'Closure at: '.$path.':'.$reflection->getStartLine();\n    }\n\n    /**\n     * Filter the given events using the provided event name filter.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $events\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function filterEvents($events)\n    {\n        if (! $eventName = $this->option('event')) {\n            return $events;\n        }\n\n        return $events->filter(\n            fn ($listeners, $event) => str_contains($event, $eventName)\n        );\n    }\n\n    /**\n     * Determine whether the user is filtering by an event name.\n     *\n     * @return bool\n     */\n    protected function filteringByEvent()\n    {\n        return ! empty($this->option('event'));\n    }\n\n    /**\n     * Gets the raw version of event listeners from the event dispatcher.\n     *\n     * @return array\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function getRawListeners()\n    {\n        return $this->getEventsDispatcher()->getRawListeners();\n    }\n\n    /**\n     * Get the event dispatcher.\n     *\n     * @return \\Illuminate\\Events\\Dispatcher\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function getEventsDispatcher()\n    {\n        return is_null(self::$eventsResolver)\n            ? $this->getLaravel()->make('events')\n            : call_user_func(self::$eventsResolver);\n    }\n\n    /**\n     * Set a callback that should be used when resolving the events dispatcher.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveEventsUsing($resolver)\n    {\n        static::$eventsResolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/EventMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:event')]\nclass EventMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:event';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new event class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Event';\n\n    /**\n     * Determine if the class already exists.\n     *\n     * @param  string  $rawName\n     * @return bool\n     */\n    protected function alreadyExists($rawName)\n    {\n        return class_exists($rawName) ||\n               $this->files->exists($this->getPath($this->qualifyClass($rawName)));\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/event.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Events';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the event already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ExceptionMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\confirm;\n\n#[AsCommand(name: 'make:exception')]\nclass ExceptionMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:exception';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new custom exception class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Exception';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('render')) {\n            return $this->option('report')\n                ? __DIR__.'/stubs/exception-render-report.stub'\n                : __DIR__.'/stubs/exception-render.stub';\n        }\n\n        return $this->option('report')\n            ? __DIR__.'/stubs/exception-report.stub'\n            : __DIR__.'/stubs/exception.stub';\n    }\n\n    /**\n     * Determine if the class already exists.\n     *\n     * @param  string  $rawName\n     * @return bool\n     */\n    protected function alreadyExists($rawName)\n    {\n        return class_exists($this->rootNamespace().'Exceptions\\\\'.$rawName);\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Exceptions';\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $input->setOption('report', confirm('Should the exception have a report method?', default: false));\n        $input->setOption('render', confirm('Should the exception have a render method?', default: false));\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the exception already exists'],\n            ['render', null, InputOption::VALUE_NONE, 'Create the exception with an empty render method'],\n            ['report', null, InputOption::VALUE_NONE, 'Create the exception with an empty report method'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/InteractsWithComposerPackages.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Symfony\\Component\\Process\\Process;\n\nuse function Illuminate\\Support\\php_binary;\n\ntrait InteractsWithComposerPackages\n{\n    /**\n     * Installs the given Composer Packages into the application.\n     *\n     * @param  string  $composer\n     * @param  array  $packages\n     * @return bool\n     */\n    protected function requireComposerPackages(string $composer, array $packages)\n    {\n        if ($composer !== 'global') {\n            $command = [$this->phpBinary(), $composer, 'require'];\n        }\n\n        $command = array_merge(\n            $command ?? ['composer', 'require'],\n            $packages,\n        );\n\n        return ! (new Process($command, $this->laravel->basePath(), ['COMPOSER_MEMORY_LIMIT' => '-1']))\n            ->setTimeout(null)\n            ->run(function ($type, $output) {\n                $this->output->write($output);\n            });\n    }\n\n    /**\n     * Get the path to the appropriate PHP binary.\n     *\n     * @return string\n     */\n    protected function phpBinary()\n    {\n        return php_binary();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/InterfaceMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:interface')]\nclass InterfaceMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:interface';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new interface';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Interface';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return __DIR__.'/stubs/interface.stub';\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return match (true) {\n            is_dir(app_path('Contracts')) => $rootNamespace.'\\\\Contracts',\n            is_dir(app_path('Interfaces')) => $rootNamespace.'\\\\Interfaces',\n            default => $rootNamespace,\n        };\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the interface even if the interface already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/JobMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:job')]\nclass JobMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:job';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new job class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Job';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('batched')) {\n            return $this->resolveStubPath('/stubs/job.batched.queued.stub');\n        }\n\n        return $this->option('sync')\n            ? $this->resolveStubPath('/stubs/job.stub')\n            : $this->resolveStubPath('/stubs/job.queued.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Jobs';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the job already exists'],\n            ['sync', null, InputOption::VALUE_NONE, 'Indicates that the job should be synchronous'],\n            ['batched', null, InputOption::VALUE_NONE, 'Indicates that the job should be batchable'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/JobMiddlewareMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:job-middleware')]\nclass JobMiddlewareMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:job-middleware';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new job middleware class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Middleware';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/job.middleware.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Jobs\\Middleware';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the job middleware already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/Kernel.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Carbon\\CarbonInterval;\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Events\\CommandFinished;\nuse Illuminate\\Console\\Events\\CommandStarting;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Console\\Kernel as KernelContract;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Foundation\\Events\\Terminating;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse ReflectionClass;\nuse SplFileInfo;\nuse Symfony\\Component\\Console\\ConsoleEvents;\nuse Symfony\\Component\\Console\\Event\\ConsoleCommandEvent;\nuse Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent;\nuse Symfony\\Component\\EventDispatcher\\EventDispatcher;\nuse Symfony\\Component\\Finder\\Finder;\nuse Throwable;\nuse WeakMap;\n\nclass Kernel implements KernelContract\n{\n    use InteractsWithTime;\n\n    /**\n     * The application implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The event dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The Symfony event dispatcher implementation.\n     *\n     * @var \\Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface|null\n     */\n    protected $symfonyDispatcher;\n\n    /**\n     * The Artisan application instance.\n     *\n     * @var \\Illuminate\\Console\\Application|null\n     */\n    protected $artisan;\n\n    /**\n     * The Artisan commands provided by the application.\n     *\n     * @var array\n     */\n    protected $commands = [];\n\n    /**\n     * The paths where Artisan commands should be automatically discovered.\n     *\n     * @var array\n     */\n    protected $commandPaths = [];\n\n    /**\n     * The paths where Artisan \"routes\" should be automatically discovered.\n     *\n     * @var array\n     */\n    protected $commandRoutePaths = [];\n\n    /**\n     * Indicates if the Closure commands have been loaded.\n     *\n     * @var bool\n     */\n    protected $commandsLoaded = false;\n\n    /**\n     * The commands paths that have been \"loaded\".\n     *\n     * @var array\n     */\n    protected $loadedPaths = [];\n\n    /**\n     * All of the registered command duration handlers.\n     *\n     * @var array\n     */\n    protected $commandLifecycleDurationHandlers = [];\n\n    /**\n     * When the currently handled command started.\n     *\n     * @var \\Illuminate\\Support\\Carbon|null\n     */\n    protected $commandStartedAt;\n\n    /**\n     * The bootstrap classes for the application.\n     *\n     * @var string[]\n     */\n    protected $bootstrappers = [\n        \\Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables::class,\n        \\Illuminate\\Foundation\\Bootstrap\\LoadConfiguration::class,\n        \\Illuminate\\Foundation\\Bootstrap\\HandleExceptions::class,\n        \\Illuminate\\Foundation\\Bootstrap\\RegisterFacades::class,\n        \\Illuminate\\Foundation\\Bootstrap\\SetRequestForConsole::class,\n        \\Illuminate\\Foundation\\Bootstrap\\RegisterProviders::class,\n        \\Illuminate\\Foundation\\Bootstrap\\BootProviders::class,\n    ];\n\n    /**\n     * Create a new console kernel instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     */\n    public function __construct(Application $app, Dispatcher $events)\n    {\n        if (! defined('ARTISAN_BINARY')) {\n            define('ARTISAN_BINARY', 'artisan');\n        }\n\n        $this->app = $app;\n        $this->events = $events;\n\n        $this->app->booted(function () {\n            if (! $this->app->runningUnitTests()) {\n                $this->rerouteSymfonyCommandEvents();\n            }\n        });\n    }\n\n    /**\n     * Re-route the Symfony command events to their Laravel counterparts.\n     *\n     * @internal\n     *\n     * @return $this\n     */\n    public function rerouteSymfonyCommandEvents()\n    {\n        if (is_null($this->symfonyDispatcher)) {\n            $this->symfonyDispatcher = new EventDispatcher;\n\n            $this->symfonyDispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {\n                $this->events->dispatch(\n                    new CommandStarting($event->getCommand()?->getName() ?? '', $event->getInput(), $event->getOutput())\n                );\n            });\n\n            $this->symfonyDispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {\n                $this->events->dispatch(\n                    new CommandFinished($event->getCommand()?->getName() ?? '', $event->getInput(), $event->getOutput(), $event->getExitCode())\n                );\n            });\n        }\n\n        return $this;\n    }\n\n    /**\n     * Run the console application.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $output\n     * @return int\n     */\n    public function handle($input, $output = null)\n    {\n        $this->commandStartedAt = Carbon::now();\n\n        try {\n            if (in_array($input->getFirstArgument(), ['env:encrypt', 'env:decrypt'], true)) {\n                $this->bootstrapWithoutBootingProviders();\n            }\n\n            $this->bootstrap();\n\n            return $this->getArtisan()->run($input, $output);\n        } catch (Throwable $e) {\n            $this->reportException($e);\n\n            $this->renderException($output, $e);\n\n            return 1;\n        }\n    }\n\n    /**\n     * Terminate the application.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  int  $status\n     * @return void\n     */\n    public function terminate($input, $status)\n    {\n        $this->events->dispatch(new Terminating);\n\n        $this->app->terminate();\n\n        if ($this->commandStartedAt === null) {\n            return;\n        }\n\n        $this->commandStartedAt->setTimezone($this->app['config']->get('app.timezone') ?? 'UTC');\n\n        foreach ($this->commandLifecycleDurationHandlers as ['threshold' => $threshold, 'handler' => $handler]) {\n            $end ??= Carbon::now();\n\n            if ($this->commandStartedAt->diffInMilliseconds($end) > $threshold) {\n                $handler($this->commandStartedAt, $input, $status);\n            }\n        }\n\n        $this->commandStartedAt = null;\n    }\n\n    /**\n     * Register a callback to be invoked when the command lifecycle duration exceeds a given amount of time.\n     *\n     * @param  \\DateTimeInterface|\\Carbon\\CarbonInterval|float|int  $threshold\n     * @param  callable  $handler\n     * @return void\n     */\n    public function whenCommandLifecycleIsLongerThan($threshold, $handler)\n    {\n        $threshold = $threshold instanceof DateTimeInterface\n            ? $this->secondsUntil($threshold) * 1000\n            : $threshold;\n\n        $threshold = $threshold instanceof CarbonInterval\n            ? $threshold->totalMilliseconds\n            : $threshold;\n\n        $this->commandLifecycleDurationHandlers[] = [\n            'threshold' => $threshold,\n            'handler' => $handler,\n        ];\n    }\n\n    /**\n     * When the command being handled started.\n     *\n     * @return \\Illuminate\\Support\\Carbon|null\n     */\n    public function commandStartedAt()\n    {\n        return $this->commandStartedAt;\n    }\n\n    /**\n     * Define the application's command schedule.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Schedule  $schedule\n     * @return void\n     */\n    protected function schedule(Schedule $schedule)\n    {\n        //\n    }\n\n    /**\n     * Resolve a console schedule instance.\n     *\n     * @return \\Illuminate\\Console\\Scheduling\\Schedule\n     */\n    public function resolveConsoleSchedule()\n    {\n        return tap(new Schedule($this->scheduleTimezone()), function ($schedule) {\n            $this->schedule($schedule->useCache($this->scheduleCache()));\n        });\n    }\n\n    /**\n     * Get the timezone that should be used by default for scheduled events.\n     *\n     * @return \\DateTimeZone|string|null\n     */\n    protected function scheduleTimezone()\n    {\n        $config = $this->app['config'];\n\n        return $config->get('app.schedule_timezone', $config->get('app.timezone'));\n    }\n\n    /**\n     * Get the name of the cache store that should manage scheduling mutexes.\n     *\n     * @return string|null\n     */\n    protected function scheduleCache()\n    {\n        return $this->app['config']->get('cache.schedule_store', Env::get('SCHEDULE_CACHE_DRIVER', function () {\n            return Env::get('SCHEDULE_CACHE_STORE');\n        }));\n    }\n\n    /**\n     * Register the commands for the application.\n     *\n     * @return void\n     */\n    protected function commands()\n    {\n        //\n    }\n\n    /**\n     * Register a Closure based command with the application.\n     *\n     * @param  string  $signature\n     * @param  \\Closure  $callback\n     * @return \\Illuminate\\Foundation\\Console\\ClosureCommand\n     */\n    public function command($signature, Closure $callback)\n    {\n        $command = new ClosureCommand($signature, $callback);\n\n        Artisan::starting(function ($artisan) use ($command) {\n            $artisan->add($command);\n        });\n\n        return $command;\n    }\n\n    /**\n     * Register all of the commands in the given directory.\n     *\n     * @param  array|string  $paths\n     * @return void\n     */\n    protected function load($paths)\n    {\n        $paths = array_unique(Arr::wrap($paths));\n\n        $paths = array_filter($paths, function ($path) {\n            return is_dir($path);\n        });\n\n        if (empty($paths)) {\n            return;\n        }\n\n        $this->loadedPaths = array_values(\n            array_unique(array_merge($this->loadedPaths, $paths))\n        );\n\n        $namespace = $this->app->getNamespace();\n\n        $possibleCommands = new WeakMap;\n\n        $filterCommands = function (SplFileInfo $file) use ($namespace, &$possibleCommands) {\n            $commandClassName = $this->commandClassFromFile($file, $namespace);\n\n            $possibleCommands[$file] = $commandClassName;\n\n            $command = rescue(fn () => new ReflectionClass($commandClassName), null, false);\n\n            return $command instanceof ReflectionClass\n                && $command->isSubClassOf(Command::class)\n                && ! $command->isAbstract();\n        };\n\n        foreach ($this->findCommands($paths)->filter($filterCommands) as $file) {\n            Artisan::starting(function ($artisan) use ($file, $possibleCommands) {\n                $artisan->resolve($possibleCommands[$file]);\n            });\n        }\n    }\n\n    /**\n     * Get the Finder instance for discovering command files.\n     *\n     * @param  array  $paths\n     * @return \\Symfony\\Component\\Finder\\Finder\n     */\n    protected function findCommands(array $paths)\n    {\n        return Finder::create()->in($paths)->name('*.php')->files();\n    }\n\n    /**\n     * Extract the command class name from the given file path.\n     *\n     * @param  \\SplFileInfo  $file\n     * @param  string  $namespace\n     * @return string\n     */\n    protected function commandClassFromFile(SplFileInfo $file, string $namespace): string\n    {\n        return $namespace.str_replace(\n            ['/', '.php'],\n            ['\\\\', ''],\n            Str::after($file->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)\n        );\n    }\n\n    /**\n     * Register the given command with the console application.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command  $command\n     * @return void\n     */\n    public function registerCommand($command)\n    {\n        $this->getArtisan()->add($command);\n    }\n\n    /**\n     * Run an Artisan console command by name.\n     *\n     * @param  \\Symfony\\Component\\Console\\Command\\Command|string  $command\n     * @param  array  $parameters\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface|null  $outputBuffer\n     * @return int\n     *\n     * @throws \\Symfony\\Component\\Console\\Exception\\CommandNotFoundException\n     */\n    public function call($command, array $parameters = [], $outputBuffer = null)\n    {\n        if (in_array($command, ['env:encrypt', 'env:decrypt'], true)) {\n            $this->bootstrapWithoutBootingProviders();\n        }\n\n        $this->bootstrap();\n\n        return $this->getArtisan()->call($command, $parameters, $outputBuffer);\n    }\n\n    /**\n     * Queue the given console command.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public function queue($command, array $parameters = [])\n    {\n        return QueuedCommand::dispatch(func_get_args());\n    }\n\n    /**\n     * Get all of the commands registered with the console.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        $this->bootstrap();\n\n        return $this->getArtisan()->all();\n    }\n\n    /**\n     * Get the output for the last run command.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        $this->bootstrap();\n\n        return $this->getArtisan()->output();\n    }\n\n    /**\n     * Bootstrap the application for artisan commands.\n     *\n     * @return void\n     */\n    public function bootstrap()\n    {\n        if (! $this->app->hasBeenBootstrapped()) {\n            $this->app->bootstrapWith($this->bootstrappers());\n        }\n\n        $this->app->loadDeferredProviders();\n\n        if (! $this->commandsLoaded) {\n            $this->commands();\n\n            if ($this->shouldDiscoverCommands()) {\n                $this->discoverCommands();\n            }\n\n            $this->commandsLoaded = true;\n        }\n    }\n\n    /**\n     * Discover the commands that should be automatically loaded.\n     *\n     * @return void\n     */\n    protected function discoverCommands()\n    {\n        foreach ($this->commandPaths as $path) {\n            $this->load($path);\n        }\n\n        foreach ($this->commandRoutePaths as $path) {\n            if (file_exists($path)) {\n                require $path;\n            }\n        }\n    }\n\n    /**\n     * Bootstrap the application without booting service providers.\n     *\n     * @return void\n     */\n    public function bootstrapWithoutBootingProviders()\n    {\n        $this->app->bootstrapWith(\n            (new Collection($this->bootstrappers()))\n                ->reject(fn ($bootstrapper) => $bootstrapper === \\Illuminate\\Foundation\\Bootstrap\\BootProviders::class)\n                ->all()\n        );\n    }\n\n    /**\n     * Determine if the kernel should discover commands.\n     *\n     * @return bool\n     */\n    protected function shouldDiscoverCommands()\n    {\n        return get_class($this) === __CLASS__;\n    }\n\n    /**\n     * Get the Artisan application instance.\n     *\n     * @return \\Illuminate\\Console\\Application\n     */\n    protected function getArtisan()\n    {\n        if (is_null($this->artisan)) {\n            $this->artisan = (new Artisan($this->app, $this->events, $this->app->version()))\n                ->resolveCommands($this->commands)\n                ->setContainerCommandLoader();\n\n            if ($this->symfonyDispatcher instanceof EventDispatcher) {\n                $this->artisan->setDispatcher($this->symfonyDispatcher);\n                $this->artisan->setSignalsToDispatchEvent();\n            }\n        }\n\n        return $this->artisan;\n    }\n\n    /**\n     * Set the Artisan application instance.\n     *\n     * @param  \\Illuminate\\Console\\Application|null  $artisan\n     * @return void\n     */\n    public function setArtisan($artisan)\n    {\n        $this->artisan = $artisan;\n    }\n\n    /**\n     * Set the Artisan commands provided by the application.\n     *\n     * @param  array  $commands\n     * @return $this\n     */\n    public function addCommands(array $commands)\n    {\n        $this->commands = array_values(array_unique(array_merge($this->commands, $commands)));\n\n        return $this;\n    }\n\n    /**\n     * Set the paths that should have their Artisan commands automatically discovered.\n     *\n     * @param  array  $paths\n     * @return $this\n     */\n    public function addCommandPaths(array $paths)\n    {\n        $this->commandPaths = array_values(array_unique(array_merge($this->commandPaths, $paths)));\n\n        return $this;\n    }\n\n    /**\n     * Set the paths that should have their Artisan \"routes\" automatically discovered.\n     *\n     * @param  array  $paths\n     * @return $this\n     */\n    public function addCommandRoutePaths(array $paths)\n    {\n        $this->commandRoutePaths = array_values(array_unique(array_merge($this->commandRoutePaths, $paths)));\n\n        return $this;\n    }\n\n    /**\n     * Get the bootstrap classes for the application.\n     *\n     * @return array\n     */\n    protected function bootstrappers()\n    {\n        return $this->bootstrappers;\n    }\n\n    /**\n     * Report the exception to the exception handler.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function reportException(Throwable $e)\n    {\n        $this->app[ExceptionHandler::class]->report($e);\n    }\n\n    /**\n     * Render the given exception.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function renderException($output, Throwable $e)\n    {\n        $this->app[ExceptionHandler::class]->renderForConsole($output, $e);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/KeyGenerateCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Encryption\\Encrypter;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'key:generate')]\nclass KeyGenerateCommand extends Command\n{\n    use ConfirmableTrait;\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'key:generate\n                    {--show : Display the key instead of modifying files}\n                    {--force : Force the operation to run when in production}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Set the application key';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $key = $this->generateRandomKey();\n\n        if ($this->option('show')) {\n            return $this->line('<comment>'.$key.'</comment>');\n        }\n\n        // Next, we will replace the application key in the environment file so it is\n        // automatically setup for this developer. This key gets generated using a\n        // secure random byte generator and is later base64 encoded for storage.\n        if (! $this->setKeyInEnvironmentFile($key)) {\n            return;\n        }\n\n        $this->laravel['config']['app.key'] = $key;\n\n        $this->components->info('Application key set successfully.');\n    }\n\n    /**\n     * Generate a random key for the application.\n     *\n     * @return string\n     */\n    protected function generateRandomKey()\n    {\n        return 'base64:'.base64_encode(\n            Encrypter::generateKey($this->laravel['config']['app.cipher'])\n        );\n    }\n\n    /**\n     * Set the application key in the environment file.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function setKeyInEnvironmentFile($key)\n    {\n        $currentKey = $this->laravel['config']['app.key'];\n\n        if (strlen($currentKey) !== 0 && (! $this->confirmToProceed())) {\n            return false;\n        }\n\n        if (! $this->writeNewEnvironmentFileWith($key)) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Write a new environment file with the given key.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function writeNewEnvironmentFileWith($key)\n    {\n        $replaced = preg_replace(\n            $this->keyReplacementPattern(),\n            'APP_KEY='.$key,\n            $input = file_get_contents($this->laravel->environmentFilePath())\n        );\n\n        if ($replaced === $input || $replaced === null) {\n            if (isset($_ENV['APP_KEY'])) {\n                $this->components->error('Unable to set application key. APP_KEY is already present in the environment.');\n            } else {\n                $this->components->error('Unable to set application key. No APP_KEY variable was found in the .env file.');\n            }\n\n            return false;\n        }\n\n        file_put_contents($this->laravel->environmentFilePath(), $replaced);\n\n        return true;\n    }\n\n    /**\n     * Get a regex pattern that will match env APP_KEY with any random key.\n     *\n     * @return string\n     */\n    protected function keyReplacementPattern()\n    {\n        $escaped = preg_quote('='.$this->laravel['config']['app.key'], '/');\n\n        return \"/^APP_KEY{$escaped}/m\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/LangPublishCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'lang:publish')]\nclass LangPublishCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'lang:publish\n                    {--existing : Publish and overwrite only the files that have already been published}\n                    {--force : Overwrite any existing files}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Publish all language files that are available for customization';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (! is_dir($langPath = $this->laravel->basePath('lang/en'))) {\n            (new Filesystem)->makeDirectory($langPath, recursive: true);\n        }\n\n        $stubs = [\n            realpath(__DIR__.'/../../Translation/lang/en/auth.php') => 'auth.php',\n            realpath(__DIR__.'/../../Translation/lang/en/pagination.php') => 'pagination.php',\n            realpath(__DIR__.'/../../Translation/lang/en/passwords.php') => 'passwords.php',\n            realpath(__DIR__.'/../../Translation/lang/en/validation.php') => 'validation.php',\n        ];\n\n        foreach ($stubs as $from => $to) {\n            $to = $langPath.DIRECTORY_SEPARATOR.ltrim($to, DIRECTORY_SEPARATOR);\n\n            if ((! $this->option('existing') && (! file_exists($to) || $this->option('force')))\n                || ($this->option('existing') && file_exists($to))) {\n                file_put_contents($to, file_get_contents($from));\n            }\n        }\n\n        $this->components->info('Language files published successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ListenerMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'make:listener')]\nclass ListenerMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:listener';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new event listener class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Listener';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $event = $this->option('event') ?? '';\n\n        if (! Str::startsWith($event, [\n            $this->laravel->getNamespace(),\n            'Illuminate',\n            '\\\\',\n        ])) {\n            $event = $this->laravel->getNamespace().'Events\\\\'.str_replace('/', '\\\\', $event);\n        }\n\n        $stub = str_replace(\n            ['DummyEvent', '{{ event }}'], class_basename($event), parent::buildClass($name)\n        );\n\n        return str_replace(\n            ['DummyFullEvent', '{{ eventNamespace }}'], trim($event, '\\\\'), $stub\n        );\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('queued')) {\n            return $this->option('event')\n                ? $this->resolveStubPath('/stubs/listener.typed.queued.stub')\n                : $this->resolveStubPath('/stubs/listener.queued.stub');\n        }\n\n        return $this->option('event')\n            ? $this->resolveStubPath('/stubs/listener.typed.stub')\n            : $this->resolveStubPath('/stubs/listener.stub');\n    }\n\n    /**\n     * Determine if the class already exists.\n     *\n     * @param  string  $rawName\n     * @return bool\n     */\n    protected function alreadyExists($rawName)\n    {\n        return class_exists($this->qualifyClass($rawName));\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Listeners';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['event', 'e', InputOption::VALUE_OPTIONAL, 'The event class being listened for'],\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the listener already exists'],\n            ['queued', null, InputOption::VALUE_NONE, 'Indicates the event listener should be queued'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $event = suggest(\n            'What event should be listened for? (Optional)',\n            $this->possibleEvents(),\n        );\n\n        if ($event) {\n            $input->setOption('event', $event);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/MailMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Foundation\\Inspiring;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'make:mail')]\nclass MailMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:mail';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new email class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Mailable';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (parent::handle() === false && ! $this->option('force')) {\n            return;\n        }\n\n        if ($this->option('markdown') !== false) {\n            $this->writeMarkdownTemplate();\n        }\n\n        if ($this->option('view') !== false) {\n            $this->writeView();\n        }\n    }\n\n    /**\n     * Write the Markdown template for the mailable.\n     *\n     * @return void\n     */\n    protected function writeMarkdownTemplate()\n    {\n        $separator = '/';\n\n        if (windows_os()) {\n            $separator = '\\\\';\n        }\n\n        $path = $this->viewPath(\n            str_replace('.', $separator, $this->getView()).'.blade.php'\n        );\n\n        if ($this->files->exists($path)) {\n            return $this->components->error(sprintf('%s [%s] already exists.', 'Markdown view', $path));\n        }\n\n        $this->files->ensureDirectoryExists(dirname($path));\n\n        $this->files->put($path, file_get_contents(__DIR__.'/stubs/markdown.stub'));\n\n        $this->components->info(sprintf('%s [%s] created successfully.', 'Markdown view', $path));\n    }\n\n    /**\n     * Write the Blade template for the mailable.\n     *\n     * @return void\n     */\n    protected function writeView()\n    {\n        $separator = '/';\n\n        if (windows_os()) {\n            $separator = '\\\\';\n        }\n\n        $path = $this->viewPath(\n            str_replace('.', $separator, $this->getView()).'.blade.php'\n        );\n\n        if ($this->files->exists($path)) {\n            return $this->components->error(sprintf('%s [%s] already exists.', 'View', $path));\n        }\n\n        $this->files->ensureDirectoryExists(dirname($path));\n\n        $stub = str_replace(\n            '{{ quote }}',\n            Inspiring::quotes()->random(),\n            file_get_contents(__DIR__.'/stubs/view.stub')\n        );\n\n        $this->files->put($path, $stub);\n\n        $this->components->info(sprintf('%s [%s] created successfully.', 'View', $path));\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $class = str_replace(\n            '{{ subject }}',\n            Str::headline(str_replace($this->getNamespace($name).'\\\\', '', $name)),\n            parent::buildClass($name)\n        );\n\n        if ($this->option('markdown') !== false || $this->option('view') !== false) {\n            $class = str_replace(['DummyView', '{{ view }}'], $this->getView(), $class);\n        }\n\n        return $class;\n    }\n\n    /**\n     * Get the view name.\n     *\n     * @return string\n     */\n    protected function getView()\n    {\n        $view = $this->option('markdown') ?: $this->option('view');\n\n        if (! $view) {\n            $name = str_replace('\\\\', '/', $this->argument('name'));\n\n            $view = 'mail.'.(new Collection(explode('/', $name)))\n                ->map(fn ($part) => Str::kebab($part))\n                ->implode('.');\n        }\n\n        return $view;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('markdown') !== false) {\n            return $this->resolveStubPath('/stubs/markdown-mail.stub');\n        }\n\n        if ($this->option('view') !== false) {\n            return $this->resolveStubPath('/stubs/view-mail.stub');\n        }\n\n        return $this->resolveStubPath('/stubs/mail.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Mail';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the mailable already exists'],\n            ['markdown', 'm', InputOption::VALUE_OPTIONAL, 'Create a new Markdown template for the mailable', false],\n            ['view', null, InputOption::VALUE_OPTIONAL, 'Create a new Blade template for the mailable', false],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $type = select('Would you like to create a view?', [\n            'markdown' => 'Markdown View',\n            'view' => 'Empty View',\n            'none' => 'No View',\n        ]);\n\n        if ($type !== 'none') {\n            $input->setOption($type, null);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ModelMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\confirm;\nuse function Laravel\\Prompts\\multiselect;\n\n#[AsCommand(name: 'make:model')]\nclass ModelMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:model';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new Eloquent model class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Model';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (parent::handle() === false && ! $this->option('force')) {\n            if (! $this->alreadyExists($this->getNameInput())) {\n                return false;\n            }\n\n            if (! confirm('Do you want to generate additional components for the model?')) {\n                return false;\n            } else {\n                $this->afterPromptingForMissingArguments($this->input, $this->output);\n            }\n        }\n\n        if ($this->option('all')) {\n            $this->input->setOption('factory', true);\n            $this->input->setOption('seed', true);\n            $this->input->setOption('migration', true);\n            $this->input->setOption('controller', true);\n            $this->input->setOption('policy', true);\n            $this->input->setOption('resource', true);\n        }\n\n        if ($this->option('factory')) {\n            $this->createFactory();\n        }\n\n        if ($this->option('migration')) {\n            $this->createMigration();\n        }\n\n        if ($this->option('seed')) {\n            $this->createSeeder();\n        }\n\n        if ($this->option('controller') || $this->option('resource') || $this->option('api')) {\n            $this->createController();\n        } elseif ($this->option('requests')) {\n            $this->createFormRequests();\n        }\n\n        if ($this->option('policy')) {\n            $this->createPolicy();\n        }\n    }\n\n    /**\n     * Create a model factory for the model.\n     *\n     * @return void\n     */\n    protected function createFactory()\n    {\n        $factory = Str::studly($this->argument('name'));\n\n        $this->call('make:factory', [\n            'name' => \"{$factory}Factory\",\n            '--model' => $this->qualifyClass($this->getNameInput()),\n        ]);\n    }\n\n    /**\n     * Create a migration file for the model.\n     *\n     * @return void\n     */\n    protected function createMigration()\n    {\n        $table = Str::snake(Str::pluralStudly(class_basename($this->argument('name'))));\n\n        if ($this->option('pivot')) {\n            $table = Str::singular($table);\n        }\n\n        $this->call('make:migration', [\n            'name' => \"create_{$table}_table\",\n            '--create' => $table,\n        ]);\n    }\n\n    /**\n     * Create a seeder file for the model.\n     *\n     * @return void\n     */\n    protected function createSeeder()\n    {\n        $seeder = Str::studly(class_basename($this->argument('name')));\n\n        $this->call('make:seeder', [\n            'name' => \"{$seeder}Seeder\",\n        ]);\n    }\n\n    /**\n     * Create a controller for the model.\n     *\n     * @return void\n     */\n    protected function createController()\n    {\n        $controller = Str::studly(class_basename($this->argument('name')));\n\n        $modelName = $this->qualifyClass($this->getNameInput());\n\n        $this->call('make:controller', array_filter([\n            'name' => \"{$controller}Controller\",\n            '--model' => $this->option('resource') || $this->option('api') ? $modelName : null,\n            '--api' => $this->option('api'),\n            '--requests' => $this->option('requests') || $this->option('all'),\n            '--test' => $this->option('test'),\n            '--pest' => $this->option('pest'),\n        ]));\n    }\n\n    /**\n     * Create the form requests for the model.\n     *\n     * @return void\n     */\n    protected function createFormRequests()\n    {\n        $request = Str::studly(class_basename($this->argument('name')));\n\n        $this->call('make:request', [\n            'name' => \"Store{$request}Request\",\n        ]);\n\n        $this->call('make:request', [\n            'name' => \"Update{$request}Request\",\n        ]);\n    }\n\n    /**\n     * Create a policy file for the model.\n     *\n     * @return void\n     */\n    protected function createPolicy()\n    {\n        $policy = Str::studly(class_basename($this->argument('name')));\n\n        $this->call('make:policy', [\n            'name' => \"{$policy}Policy\",\n            '--model' => $this->qualifyClass($this->getNameInput()),\n        ]);\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        if ($this->option('pivot')) {\n            return $this->resolveStubPath('/stubs/model.pivot.stub');\n        }\n\n        if ($this->option('morph-pivot')) {\n            return $this->resolveStubPath('/stubs/model.morph-pivot.stub');\n        }\n\n        return $this->resolveStubPath('/stubs/model.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return is_dir(app_path('Models')) ? $rootNamespace.'\\\\Models' : $rootNamespace;\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    protected function buildClass($name)\n    {\n        $replace = $this->buildFactoryReplacements();\n\n        return str_replace(\n            array_keys($replace), array_values($replace), parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Build the replacements for a factory.\n     *\n     * @return array<string, string>\n     */\n    protected function buildFactoryReplacements()\n    {\n        $replacements = [];\n\n        if ($this->option('factory') || $this->option('all')) {\n            $modelPath = Str::of($this->argument('name'))->studly()->replace('/', '\\\\')->toString();\n\n            $factoryNamespace = '\\\\Database\\\\Factories\\\\'.$modelPath.'Factory';\n\n            $factoryCode = <<<EOT\n            /** @use HasFactory<$factoryNamespace> */\n                use HasFactory;\n            EOT;\n\n            $replacements['{{ factory }}'] = $factoryCode;\n            $replacements['{{ factoryImport }}'] = 'use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;';\n        } else {\n            $replacements['{{ factory }}'] = '//';\n            $replacements[\"{{ factoryImport }}\\n\"] = '';\n            $replacements[\"{{ factoryImport }}\\r\\n\"] = '';\n        }\n\n        return $replacements;\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['all', 'a', InputOption::VALUE_NONE, 'Generate a migration, seeder, factory, policy, resource controller, and form request classes for the model'],\n            ['controller', 'c', InputOption::VALUE_NONE, 'Create a new controller for the model'],\n            ['factory', 'f', InputOption::VALUE_NONE, 'Create a new factory for the model'],\n            ['force', null, InputOption::VALUE_NONE, 'Create the class even if the model already exists'],\n            ['migration', 'm', InputOption::VALUE_NONE, 'Create a new migration file for the model'],\n            ['morph-pivot', null, InputOption::VALUE_NONE, 'Indicates if the generated model should be a custom polymorphic intermediate table model'],\n            ['policy', null, InputOption::VALUE_NONE, 'Create a new policy for the model'],\n            ['seed', 's', InputOption::VALUE_NONE, 'Create a new seeder for the model'],\n            ['pivot', 'p', InputOption::VALUE_NONE, 'Indicates if the generated model should be a custom intermediate table model'],\n            ['resource', 'r', InputOption::VALUE_NONE, 'Indicates if the generated controller should be a resource controller'],\n            ['api', null, InputOption::VALUE_NONE, 'Indicates if the generated controller should be an API resource controller'],\n            ['requests', 'R', InputOption::VALUE_NONE, 'Create new form request classes and use them in the resource controller'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {\n            return;\n        }\n\n        (new Collection(multiselect('Would you like any of the following?', [\n            'seed' => 'Database Seeder',\n            'factory' => 'Factory',\n            'requests' => 'Form Requests',\n            'migration' => 'Migration',\n            'policy' => 'Policy',\n            'resource' => 'Resource Controller',\n        ])))->each(fn ($option) => $input->setOption($option, true));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/NotificationMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\confirm;\nuse function Laravel\\Prompts\\text;\n\n#[AsCommand(name: 'make:notification')]\nclass NotificationMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:notification';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new notification class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Notification';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (parent::handle() === false && ! $this->option('force')) {\n            return;\n        }\n\n        if ($this->option('markdown')) {\n            $this->writeMarkdownTemplate();\n        }\n    }\n\n    /**\n     * Write the Markdown template for the mailable.\n     *\n     * @return void\n     */\n    protected function writeMarkdownTemplate()\n    {\n        $separator = '/';\n\n        if (windows_os()) {\n            $separator = '\\\\';\n        }\n\n        $path = $this->viewPath(\n            str_replace('.', $separator, $this->option('markdown')).'.blade.php'\n        );\n\n        if (! $this->files->isDirectory(dirname($path))) {\n            $this->files->makeDirectory(dirname($path), 0755, true);\n        }\n\n        $this->files->put($path, file_get_contents(__DIR__.'/stubs/markdown.stub'));\n\n        $this->components->info(sprintf('%s [%s] created successfully.', 'Markdown', $path));\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $class = parent::buildClass($name);\n\n        if ($this->option('markdown')) {\n            $class = str_replace(['DummyView', '{{ view }}'], $this->option('markdown'), $class);\n        }\n\n        return $class;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->option('markdown')\n            ? $this->resolveStubPath('/stubs/markdown-notification.stub')\n            : $this->resolveStubPath('/stubs/notification.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Notifications';\n    }\n\n    /**\n     * Perform actions after the user was prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $wantsMarkdownView = confirm('Would you like to create a markdown view?');\n\n        if ($wantsMarkdownView) {\n            $defaultMarkdownView = (new Collection(explode('/', str_replace('\\\\', '/', $this->argument('name')))))\n                ->map(fn ($path) => Str::kebab($path))\n                ->prepend('mail')\n                ->implode('.');\n\n            $markdownView = text('What should the markdown view be named?', default: $defaultMarkdownView);\n\n            $input->setOption('markdown', $markdownView);\n        }\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the notification already exists'],\n            ['markdown', 'm', InputOption::VALUE_OPTIONAL, 'Create a new Markdown template for the notification'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ObserverMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse InvalidArgumentException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'make:observer')]\nclass ObserverMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:observer';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new observer class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Observer';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $stub = parent::buildClass($name);\n\n        $model = $this->option('model');\n\n        return $model ? $this->replaceModel($stub, $model) : $stub;\n    }\n\n    /**\n     * Replace the model for the given stub.\n     *\n     * @param  string  $stub\n     * @param  string  $model\n     * @return string\n     */\n    protected function replaceModel($stub, $model)\n    {\n        $modelClass = $this->parseModel($model);\n\n        $replace = [\n            'DummyFullModelClass' => $modelClass,\n            '{{ namespacedModel }}' => $modelClass,\n            '{{namespacedModel}}' => $modelClass,\n            'DummyModelClass' => class_basename($modelClass),\n            '{{ model }}' => class_basename($modelClass),\n            '{{model}}' => class_basename($modelClass),\n            'DummyModelVariable' => lcfirst(class_basename($modelClass)),\n            '{{ modelVariable }}' => lcfirst(class_basename($modelClass)),\n            '{{modelVariable}}' => lcfirst(class_basename($modelClass)),\n        ];\n\n        return str_replace(\n            array_keys($replace), array_values($replace), $stub\n        );\n    }\n\n    /**\n     * Get the fully-qualified model class name.\n     *\n     * @param  string  $model\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseModel($model)\n    {\n        if (preg_match('/[^A-Za-z0-9_\\/\\\\\\\\]/', $model)) {\n            throw new InvalidArgumentException('Model name contains invalid characters.');\n        }\n\n        return $this->qualifyModel($model);\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->option('model')\n            ? $this->resolveStubPath('/stubs/observer.stub')\n            : $this->resolveStubPath('/stubs/observer.plain.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Observers';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the observer already exists'],\n            ['model', 'm', InputOption::VALUE_OPTIONAL, 'The model that the observer applies to'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $model = suggest(\n            'What model should be observed? (Optional)',\n            $this->findAvailableModels(),\n        );\n\n        if ($model) {\n            $input->setOption('model', $model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/OptimizeClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'optimize:clear')]\nclass OptimizeClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'optimize:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Remove the cached bootstrap files';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->components->info('Clearing cached bootstrap files.');\n\n        $exceptions = Collection::wrap(explode(',', $this->option('except') ?? ''))\n            ->map(fn ($except) => trim($except))\n            ->filter()\n            ->unique()\n            ->flip();\n\n        $tasks = Collection::wrap($this->getOptimizeClearTasks())\n            ->reject(fn ($command, $key) => $exceptions->hasAny([$command, $key]))\n            ->toArray();\n\n        foreach ($tasks as $description => $command) {\n            $this->components->task($description, fn () => $this->callSilently($command) == 0);\n        }\n\n        $this->newLine();\n    }\n\n    /**\n     * Get the commands that should be run to clear the \"optimization\" files.\n     *\n     * @return array\n     */\n    public function getOptimizeClearTasks()\n    {\n        return [\n            'config' => 'config:clear',\n            'cache' => 'cache:clear',\n            'compiled' => 'clear-compiled',\n            'events' => 'event:clear',\n            'routes' => 'route:clear',\n            'views' => 'view:clear',\n            ...ServiceProvider::$optimizeClearCommands,\n        ];\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['except', 'e', InputOption::VALUE_OPTIONAL, 'The commands to skip'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/OptimizeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'optimize')]\nclass OptimizeCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'optimize';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Cache framework bootstrap, configuration, and metadata to increase performance';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->components->info('Caching framework bootstrap, configuration, and metadata.');\n\n        $exceptions = Collection::wrap(explode(',', $this->option('except') ?? ''))\n            ->map(fn ($except) => trim($except))\n            ->filter()\n            ->unique()\n            ->flip();\n\n        $tasks = Collection::wrap($this->getOptimizeTasks())\n            ->reject(fn ($command, $key) => $exceptions->hasAny([$command, $key]))\n            ->toArray();\n\n        foreach ($tasks as $description => $command) {\n            $this->components->task($description, fn () => $this->callSilently($command) == 0);\n        }\n\n        $this->newLine();\n    }\n\n    /**\n     * Get the commands that should be run to optimize the framework.\n     *\n     * @return array\n     */\n    protected function getOptimizeTasks()\n    {\n        return [\n            'config' => 'config:cache',\n            'events' => 'event:cache',\n            'routes' => 'route:cache',\n            'views' => 'view:cache',\n            ...ServiceProvider::$optimizeCommands,\n        ];\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['except', 'e', InputOption::VALUE_OPTIONAL, 'Do not run the commands matching the key or name'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/PackageDiscoverCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Foundation\\PackageManifest;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'package:discover')]\nclass PackageDiscoverCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'package:discover';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Rebuild the cached package manifest';\n\n    /**\n     * Execute the console command.\n     *\n     * @param  \\Illuminate\\Foundation\\PackageManifest  $manifest\n     * @return void\n     */\n    public function handle(PackageManifest $manifest)\n    {\n        $this->components->info('Discovering packages');\n\n        $manifest->build();\n\n        (new Collection($manifest->manifest))\n            ->keys()\n            ->each(fn ($description) => $this->components->task($description))\n            ->whenNotEmpty(fn () => $this->newLine());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/PolicyMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse LogicException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'make:policy')]\nclass PolicyMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:policy';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new policy class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Policy';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $stub = $this->replaceUserNamespace(\n            parent::buildClass($name)\n        );\n\n        $model = $this->option('model');\n\n        return $model ? $this->replaceModel($stub, $model) : $stub;\n    }\n\n    /**\n     * Replace the User model namespace.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function replaceUserNamespace($stub)\n    {\n        $model = $this->userProviderModel();\n\n        if (! $model) {\n            return $stub;\n        }\n\n        return str_replace(\n            $this->rootNamespace().'User',\n            $model,\n            $stub\n        );\n    }\n\n    /**\n     * Get the model for the guard's user provider.\n     *\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    protected function userProviderModel()\n    {\n        $config = $this->laravel['config'];\n\n        $guard = $this->option('guard') ?: $config->get('auth.defaults.guard');\n\n        if (is_null($guardProvider = $config->get('auth.guards.'.$guard.'.provider'))) {\n            throw new LogicException('The ['.$guard.'] guard is not defined in your \"auth\" configuration file.');\n        }\n\n        if (! $config->get('auth.providers.'.$guardProvider.'.model')) {\n            return 'App\\\\Models\\\\User';\n        }\n\n        return $config->get(\n            'auth.providers.'.$guardProvider.'.model'\n        );\n    }\n\n    /**\n     * Replace the model for the given stub.\n     *\n     * @param  string  $stub\n     * @param  string  $model\n     * @return string\n     */\n    protected function replaceModel($stub, $model)\n    {\n        $model = str_replace('/', '\\\\', $model);\n\n        if (str_starts_with($model, '\\\\')) {\n            $namespacedModel = trim($model, '\\\\');\n        } else {\n            $namespacedModel = $this->qualifyModel($model);\n        }\n\n        $model = class_basename(trim($model, '\\\\'));\n\n        $dummyUser = class_basename($this->userProviderModel());\n\n        $dummyModel = Str::camel($model) === 'user' ? 'model' : $model;\n\n        $replace = [\n            'NamespacedDummyModel' => $namespacedModel,\n            '{{ namespacedModel }}' => $namespacedModel,\n            '{{namespacedModel}}' => $namespacedModel,\n            'DummyModel' => $model,\n            '{{ model }}' => $model,\n            '{{model}}' => $model,\n            'dummyModel' => Str::camel($dummyModel),\n            '{{ modelVariable }}' => Str::camel($dummyModel),\n            '{{modelVariable}}' => Str::camel($dummyModel),\n            'DummyUser' => $dummyUser,\n            '{{ user }}' => $dummyUser,\n            '{{user}}' => $dummyUser,\n            '$user' => '$'.Str::camel($dummyUser),\n        ];\n\n        $stub = str_replace(\n            array_keys($replace), array_values($replace), $stub\n        );\n\n        return preg_replace(\n            vsprintf('/use %s;[\\r\\n]+use %s;/', [\n                preg_quote($namespacedModel, '/'),\n                preg_quote($namespacedModel, '/'),\n            ]),\n            \"use {$namespacedModel};\",\n            $stub\n        );\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->option('model')\n            ? $this->resolveStubPath('/stubs/policy.stub')\n            : $this->resolveStubPath('/stubs/policy.plain.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Policies';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the policy already exists'],\n            ['model', 'm', InputOption::VALUE_OPTIONAL, 'The model that the policy applies to'],\n            ['guard', 'g', InputOption::VALUE_OPTIONAL, 'The guard that the policy relies on'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $model = suggest(\n            'What model should this policy apply to? (Optional)',\n            $this->findAvailableModels(),\n        );\n\n        if ($model) {\n            $input->setOption('model', $model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ProviderMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\ServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:provider')]\nclass ProviderMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:provider';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new service provider class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Provider';\n\n    /**\n     * Execute the console command.\n     *\n     * @return bool|null\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function handle()\n    {\n        $result = parent::handle();\n\n        if ($result === false) {\n            return $result;\n        }\n\n        ServiceProvider::addProviderToBootstrapFile(\n            $this->qualifyClass($this->getNameInput()),\n            $this->laravel->getBootstrapProvidersPath(),\n        );\n\n        return $result;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/provider.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Providers';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the provider already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/QueuedCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Console\\Kernel as KernelContract;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\n\nclass QueuedCommand implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    /**\n     * The data to pass to the Artisan command.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  array  $data\n     */\n    public function __construct($data)\n    {\n        $this->data = $data;\n    }\n\n    /**\n     * Handle the job.\n     *\n     * @param  \\Illuminate\\Contracts\\Console\\Kernel  $kernel\n     * @return void\n     */\n    public function handle(KernelContract $kernel)\n    {\n        $kernel->call(...array_values($this->data));\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        return array_values($this->data)[0];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ReloadCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ServiceProvider;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'reload')]\nclass ReloadCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'reload';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Reload running services';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->components->info('Reloading services.');\n\n        $exceptions = Collection::wrap(explode(',', $this->option('except') ?? ''))\n            ->map(fn ($except) => trim($except))\n            ->filter()\n            ->unique()\n            ->flip();\n\n        $tasks = Collection::wrap($this->getReloadTasks())\n            ->reject(fn ($command, $key) => $exceptions->hasAny([$command, $key]))\n            ->toArray();\n\n        foreach ($tasks as $description => $command) {\n            $this->components->task($description, fn () => $this->callSilently($command) == 0);\n        }\n\n        $this->newLine();\n    }\n\n    /**\n     * Get the commands that should be reloaded.\n     *\n     * @return array\n     */\n    public function getReloadTasks()\n    {\n        return [\n            'queue' => 'queue:restart',\n            'schedule' => 'schedule:interrupt',\n            ...ServiceProvider::$reloadCommands,\n        ];\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['except', 'e', InputOption::VALUE_OPTIONAL, 'The commands to skip'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/RequestMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:request')]\nclass RequestMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:request';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new form request class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Request';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/request.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Http\\Requests';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the request already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ResourceMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:resource')]\nclass ResourceMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:resource';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new resource';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Resource';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if ($this->collection()) {\n            $this->type = 'Resource collection';\n        }\n\n        parent::handle();\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return match (true) {\n            $this->collection() => $this->resolveStubPath('/stubs/resource-collection.stub'),\n            $this->option('json-api') => $this->resolveStubPath('/stubs/resource-json-api.stub'),\n            default => $this->resolveStubPath('/stubs/resource.stub'),\n        };\n    }\n\n    /**\n     * Determine if the command is generating a resource collection.\n     *\n     * @return bool\n     */\n    protected function collection()\n    {\n        return $this->option('collection') ||\n               str_ends_with($this->argument('name'), 'Collection');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Http\\Resources';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the resource already exists'],\n            ['json-api', 'j', InputOption::VALUE_NONE, 'Create a JSON:API resource'],\n            ['collection', 'c', InputOption::VALUE_NONE, 'Create a resource collection'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/RouteCacheCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Routing\\RouteCollection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'route:cache')]\nclass RouteCacheCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'route:cache';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a route cache file for faster route registration';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new route command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->callSilent('route:clear');\n\n        $routes = $this->getFreshApplicationRoutes();\n\n        if (count($routes) === 0) {\n            return $this->components->error(\"Your application doesn't have any routes.\");\n        }\n\n        foreach ($routes as $route) {\n            $route->prepareForSerialization();\n        }\n\n        $this->files->put(\n            $this->laravel->getCachedRoutesPath(), $this->buildRouteCacheFile($routes)\n        );\n\n        $this->components->info('Routes cached successfully.');\n    }\n\n    /**\n     * Boot a fresh copy of the application and get the routes.\n     *\n     * @return \\Illuminate\\Routing\\RouteCollection\n     */\n    protected function getFreshApplicationRoutes()\n    {\n        return tap($this->getFreshApplication()['router']->getRoutes(), function ($routes) {\n            $routes->refreshNameLookups();\n            $routes->refreshActionLookups();\n        });\n    }\n\n    /**\n     * Get a fresh application instance.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected function getFreshApplication()\n    {\n        return tap(require $this->laravel->bootstrapPath('app.php'), function ($app) {\n            $app->make(ConsoleKernelContract::class)->bootstrap();\n        });\n    }\n\n    /**\n     * Build the route cache file.\n     *\n     * @param  \\Illuminate\\Routing\\RouteCollection  $routes\n     * @return string\n     */\n    protected function buildRouteCacheFile(RouteCollection $routes)\n    {\n        $stub = $this->files->get(__DIR__.'/stubs/routes.stub');\n\n        return str_replace('{{routes}}', var_export($routes->compile(), true), $stub);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/RouteClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'route:clear')]\nclass RouteClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'route:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Remove the route cache file';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new route clear command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->files->delete($this->laravel->getCachedRoutesPath());\n\n        $this->components->info('Route cache cleared successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/RouteListCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Closure;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Routing\\ViewController;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse ReflectionClass;\nuse ReflectionFunction;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Terminal;\n\n#[AsCommand(name: 'route:list')]\nclass RouteListCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'route:list';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'List all registered routes';\n\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The table headers for the command.\n     *\n     * @var string[]\n     */\n    protected $headers = ['Domain', 'Method', 'URI', 'Name', 'Action', 'Middleware', 'Path'];\n\n    /**\n     * The terminal width resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $terminalWidthResolver;\n\n    /**\n     * The verb colors for the command.\n     *\n     * @var array\n     */\n    protected $verbColors = [\n        'ANY' => 'red',\n        'GET' => 'blue',\n        'HEAD' => '#6C7280',\n        'OPTIONS' => '#6C7280',\n        'POST' => 'yellow',\n        'PUT' => 'yellow',\n        'PATCH' => 'yellow',\n        'DELETE' => 'red',\n    ];\n\n    /**\n     * Create a new route command instance.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     */\n    public function __construct(Router $router)\n    {\n        parent::__construct();\n\n        $this->router = $router;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (! $this->output->isVeryVerbose()) {\n            $this->router->flushMiddlewareGroups();\n        }\n\n        if (! $this->router->getRoutes()->count()) {\n            return $this->components->error(\"Your application doesn't have any routes.\");\n        }\n\n        if (empty($routes = $this->getRoutes())) {\n            return $this->components->error(\"Your application doesn't have any routes matching the given criteria.\");\n        }\n\n        $this->displayRoutes($routes);\n    }\n\n    /**\n     * Compile the routes into a displayable format.\n     *\n     * @return array\n     */\n    protected function getRoutes()\n    {\n        $routes = (new Collection($this->router->getRoutes()))\n            ->map(fn ($route) => $this->getRouteInformation($route))\n            ->filter()\n            ->all();\n\n        if (($sort = $this->option('sort')) !== null) {\n            $routes = $this->sortRoutes($sort, $routes);\n        } else {\n            $routes = $this->sortRoutes('uri', $routes);\n        }\n\n        if ($this->option('reverse')) {\n            $routes = array_reverse($routes);\n        }\n\n        return $this->pluckColumns($routes);\n    }\n\n    /**\n     * Get the route information for a given route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return array\n     */\n    protected function getRouteInformation(Route $route)\n    {\n        return $this->filterRoute([\n            'domain' => $route->domain(),\n            'method' => implode('|', $route->methods()),\n            'uri' => $this->resolveUri($route),\n            'name' => $route->getName(),\n            'action' => ltrim($route->getActionName(), '\\\\'),\n            'middleware' => $this->getMiddleware($route),\n            'path' => $this->getClosurePath($route),\n            'vendor' => $this->isVendorRoute($route),\n        ]);\n    }\n\n    /**\n     * Sort the routes by a given element.\n     *\n     * @param  string  $sort\n     * @param  array  $routes\n     * @return array\n     */\n    protected function sortRoutes($sort, array $routes)\n    {\n        if ($sort === 'definition') {\n            return $routes;\n        }\n\n        if (Str::contains($sort, ',')) {\n            $sort = explode(',', $sort);\n        }\n\n        return (new Collection($routes))\n            ->sortBy($sort)\n            ->toArray();\n    }\n\n    /**\n     * Remove unnecessary columns from the routes.\n     *\n     * @param  array  $routes\n     * @return array\n     */\n    protected function pluckColumns(array $routes)\n    {\n        return array_map(function ($route) {\n            return Arr::only($route, $this->getColumns());\n        }, $routes);\n    }\n\n    /**\n     * Display the route information on the console.\n     *\n     * @param  array  $routes\n     * @return void\n     */\n    protected function displayRoutes(array $routes)\n    {\n        $routes = new Collection($routes);\n\n        $this->output->writeln(\n            $this->option('json') ? $this->asJson($routes) : $this->forCli($routes)\n        );\n    }\n\n    /**\n     * Get the URI for the given route, including any binding fields.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return string\n     */\n    protected function resolveUri(Route $route)\n    {\n        $uri = $route->uri();\n\n        foreach ($route->bindingFields() as $parameter => $field) {\n            $uri = str_replace(\"{{$parameter}}\", \"{{$parameter}:{$field}}\", $uri);\n        }\n\n        return $uri;\n    }\n\n    /**\n     * Get the middleware for the route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return string\n     */\n    protected function getMiddleware($route)\n    {\n        return (new Collection($this->router->gatherRouteMiddleware($route)))\n            ->map(fn ($middleware) => $middleware instanceof Closure ? 'Closure' : $middleware)\n            ->implode(\"\\n\");\n    }\n\n    /**\n     * Get the file path and line number for a closure-based route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return string|null\n     */\n    protected function getClosurePath(Route $route)\n    {\n        if (! $route->action['uses'] instanceof Closure) {\n            return null;\n        }\n\n        $reflection = new ReflectionFunction($route->action['uses']);\n\n        return str_replace(\n            '\\\\', '/', ltrim(Str::after($reflection->getFileName(), base_path()), DIRECTORY_SEPARATOR)\n        ).':'.$reflection->getStartLine();\n    }\n\n    /**\n     * Determine if the route has been defined outside of the application.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return bool\n     */\n    protected function isVendorRoute(Route $route)\n    {\n        if ($route->action['uses'] instanceof Closure) {\n            $path = (new ReflectionFunction($route->action['uses']))\n                ->getFileName();\n        } elseif (is_string($route->action['uses']) &&\n                  str_contains($route->action['uses'], 'SerializableClosure')) {\n            return false;\n        } elseif (is_string($route->action['uses'])) {\n            if ($this->isFrameworkController($route)) {\n                return false;\n            }\n\n            $path = (new ReflectionClass($route->getControllerClass()))\n                ->getFileName();\n        } else {\n            return false;\n        }\n\n        return str_starts_with($path, base_path('vendor'));\n    }\n\n    /**\n     * Determine if the route uses a framework controller.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return bool\n     */\n    protected function isFrameworkController(Route $route)\n    {\n        return in_array($route->getControllerClass(), [\n            '\\Illuminate\\Routing\\RedirectController',\n            '\\Illuminate\\Routing\\ViewController',\n        ], true);\n    }\n\n    /**\n     * Filter the route by URI and / or name.\n     *\n     * @param  array  $route\n     * @return array|null\n     */\n    protected function filterRoute(array $route)\n    {\n        if (($this->option('name') && ! Str::contains((string) $route['name'], $this->option('name'))) ||\n            ($this->option('action') && isset($route['action']) && is_string($route['action']) && ! Str::contains($route['action'], $this->option('action'))) ||\n            ($this->option('path') && ! Str::contains($route['uri'], $this->option('path'))) ||\n            ($this->option('method') && ! Str::contains($route['method'], strtoupper($this->option('method')))) ||\n            ($this->option('domain') && ! Str::contains((string) $route['domain'], $this->option('domain'))) ||\n            ($this->option('middleware') && ! Str::contains($route['middleware'], $this->option('middleware'))) ||\n            ($this->option('except-vendor') && $route['vendor']) ||\n            ($this->option('only-vendor') && ! $route['vendor'])) {\n            return;\n        }\n\n        if ($this->option('except-path')) {\n            foreach (explode(',', $this->option('except-path')) as $path) {\n                if (str_contains($route['uri'], $path)) {\n                    return;\n                }\n            }\n        }\n\n        return $route;\n    }\n\n    /**\n     * Get the table headers for the visible columns.\n     *\n     * @return array\n     */\n    protected function getHeaders()\n    {\n        return Arr::only($this->headers, array_keys($this->getColumns()));\n    }\n\n    /**\n     * Get the column names to show (lowercase table headers).\n     *\n     * @return array\n     */\n    protected function getColumns()\n    {\n        return array_map(strtolower(...), $this->headers);\n    }\n\n    /**\n     * Parse the column list.\n     *\n     * @param  array  $columns\n     * @return array\n     */\n    protected function parseColumns(array $columns)\n    {\n        $results = [];\n\n        foreach ($columns as $column) {\n            if (str_contains($column, ',')) {\n                $results = array_merge($results, explode(',', $column));\n            } else {\n                $results[] = $column;\n            }\n        }\n\n        return array_map(strtolower(...), $results);\n    }\n\n    /**\n     * Convert the given routes to JSON.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $routes\n     * @return string\n     */\n    protected function asJson($routes)\n    {\n        return $routes\n            ->map(function ($route) {\n                $route['middleware'] = empty($route['middleware']) ? [] : explode(\"\\n\", $route['middleware']);\n\n                return $route;\n            })\n            ->values()\n            ->toJson();\n    }\n\n    /**\n     * Convert the given routes to regular CLI output.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $routes\n     * @return array\n     */\n    protected function forCli($routes)\n    {\n        $routes = $routes->map(\n            fn ($route) => array_merge($route, [\n                'action' => $this->formatActionForCli($route),\n                'method' => $route['method'] == 'GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS' ? 'ANY' : $route['method'],\n                'uri' => $route['domain'] ? ($route['domain'].'/'.ltrim($route['uri'], '/')) : $route['uri'],\n            ]),\n        );\n\n        $maxMethod = mb_strlen($routes->max('method'));\n\n        $terminalWidth = $this->getTerminalWidth();\n\n        $routeCount = $this->determineRouteCountOutput($routes, $terminalWidth);\n\n        return $routes->map(function ($route) use ($maxMethod, $terminalWidth) {\n            [\n                'action' => $action,\n                'domain' => $domain,\n                'method' => $method,\n                'middleware' => $middleware,\n                'uri' => $uri,\n            ] = $route;\n\n            $middleware = (new Stringable($middleware))->explode(\"\\n\")->filter()->whenNotEmpty(\n                fn ($collection) => $collection->map(\n                    fn ($middleware) => sprintf('         %s⇂ %s', str_repeat(' ', $maxMethod), $middleware)\n                )\n            )->implode(\"\\n\");\n\n            $spaces = str_repeat(' ', max($maxMethod + 6 - mb_strlen($method), 0));\n\n            $dots = str_repeat('.', max(\n                $terminalWidth - mb_strlen($method.$spaces.$uri.$action) - 6 - ($action ? 1 : 0), 0\n            ));\n\n            $dots = empty($dots) ? $dots : \" $dots\";\n\n            if ($action && ! $this->output->isVerbose() && mb_strlen($method.$spaces.$uri.$action.$dots) > ($terminalWidth - 6)) {\n                $action = substr($action, 0, $terminalWidth - 7 - mb_strlen($method.$spaces.$uri.$dots)).'…';\n            }\n\n            $method = (new Stringable($method))->explode('|')->map(\n                fn ($method) => sprintf('<fg=%s>%s</>', $this->verbColors[$method] ?? 'default', $method),\n            )->implode('<fg=#6C7280>|</>');\n\n            return [sprintf(\n                '  <fg=white;options=bold>%s</> %s<fg=white>%s</><fg=#6C7280>%s %s</>',\n                $method,\n                $spaces,\n                preg_replace('#({[^}]+})#', '<fg=yellow>$1</>', $uri),\n                $dots,\n                str_replace('   ', ' › ', $action ?? ''),\n            ), $this->output->isVerbose() && ! empty($middleware) ? \"<fg=#6C7280>$middleware</>\" : null];\n        })\n            ->flatten()\n            ->filter()\n            ->prepend('')\n            ->push('')->push($routeCount)->push('')\n            ->toArray();\n    }\n\n    /**\n     * Get the formatted action for display on the CLI.\n     *\n     * @param  array  $route\n     * @return string|null\n     */\n    protected function formatActionForCli($route)\n    {\n        ['action' => $action, 'name' => $name] = $route;\n\n        if ($action === 'Closure' || $action === ViewController::class) {\n            $path = $route['path'] ?? null;\n\n            if ($name && $path) {\n                return $name.'   '.$path;\n            }\n\n            return $name ?? $path;\n        }\n\n        $name = $name ? \"$name   \" : null;\n\n        $rootControllerNamespace = $this->laravel[UrlGenerator::class]->getRootControllerNamespace()\n            ?? ($this->laravel->getNamespace().'Http\\\\Controllers');\n\n        if (str_starts_with($action, $rootControllerNamespace)) {\n            return $name.substr($action, mb_strlen($rootControllerNamespace) + 1);\n        }\n\n        $actionClass = explode('@', $action)[0];\n\n        if (class_exists($actionClass) && str_starts_with((new ReflectionClass($actionClass))->getFilename(), base_path('vendor'))) {\n            $actionCollection = new Collection(explode('\\\\', $action));\n\n            return $name.$actionCollection->take(2)->implode('\\\\').'   '.$actionCollection->last();\n        }\n\n        return $name.$action;\n    }\n\n    /**\n     * Determine and return the output for displaying the number of routes in the CLI output.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $routes\n     * @param  int  $terminalWidth\n     * @return string\n     */\n    protected function determineRouteCountOutput($routes, $terminalWidth)\n    {\n        $routeCountText = 'Showing ['.$routes->count().'] routes';\n\n        $offset = $terminalWidth - mb_strlen($routeCountText) - 2;\n\n        $spaces = str_repeat(' ', $offset);\n\n        return $spaces.'<fg=blue;options=bold>Showing ['.$routes->count().'] routes</>';\n    }\n\n    /**\n     * Get the terminal width.\n     *\n     * @return int\n     */\n    public static function getTerminalWidth()\n    {\n        return is_null(static::$terminalWidthResolver)\n            ? (new Terminal)->getWidth()\n            : call_user_func(static::$terminalWidthResolver);\n    }\n\n    /**\n     * Set a callback that should be used when resolving the terminal width.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveTerminalWidthUsing($resolver)\n    {\n        static::$terminalWidthResolver = $resolver;\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['json', null, InputOption::VALUE_NONE, 'Output the route list as JSON'],\n            ['method', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by method'],\n            ['action', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by action'],\n            ['name', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by name'],\n            ['domain', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by domain'],\n            ['middleware', null, InputOption::VALUE_OPTIONAL, 'Filter the routes by middleware'],\n            ['path', null, InputOption::VALUE_OPTIONAL, 'Only show routes matching the given path pattern'],\n            ['except-path', null, InputOption::VALUE_OPTIONAL, 'Do not display the routes matching the given path pattern'],\n            ['reverse', 'r', InputOption::VALUE_NONE, 'Reverse the ordering of the routes'],\n            ['sort', null, InputOption::VALUE_OPTIONAL, 'The column (domain, method, uri, name, action, middleware, definition) to sort by', 'uri'],\n            ['except-vendor', null, InputOption::VALUE_NONE, 'Do not display routes defined by vendor packages'],\n            ['only-vendor', null, InputOption::VALUE_NONE, 'Only display routes defined by vendor packages'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/RuleMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:rule')]\nclass RuleMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:rule';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new validation rule';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Rule';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    protected function buildClass($name)\n    {\n        return str_replace(\n            '{{ ruleType }}',\n            $this->option('implicit') ? 'ImplicitRule' : 'Rule',\n            parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        $stub = $this->option('implicit')\n            ? '/stubs/rule.implicit.stub'\n            : '/stubs/rule.stub';\n\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Rules';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the rule already exists'],\n            ['implicit', 'i', InputOption::VALUE_NONE, 'Generate an implicit rule'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ScopeMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:scope')]\nclass ScopeMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:scope';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new scope class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Scope';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/scope.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return is_dir(app_path('Models')) ? $rootNamespace.'\\\\Models\\\\Scopes' : $rootNamespace.'\\Scopes';\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the scope already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ServeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Process\\Process;\n\nuse function Illuminate\\Support\\php_binary;\nuse function Termwind\\terminal;\n\n#[AsCommand(name: 'serve')]\nclass ServeCommand extends Command\n{\n    use InteractsWithTime;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'serve';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Serve the application on the PHP development server';\n\n    /**\n     * The number of PHP CLI server workers.\n     *\n     * @var int<2, max>|false\n     */\n    protected $phpServerWorkers = 1;\n\n    /**\n     * The current port offset.\n     *\n     * @var int\n     */\n    protected $portOffset = 0;\n\n    /**\n     * The list of lines that are pending to be output.\n     *\n     * @var string\n     */\n    protected $outputBuffer = '';\n\n    /**\n     * The list of requests being handled and their start time.\n     *\n     * @var array<int, \\Illuminate\\Support\\Carbon>\n     */\n    protected $requestsPool;\n\n    /**\n     * Indicates if the \"Server running on...\" output message has been displayed.\n     *\n     * @var bool\n     */\n    protected $serverRunningHasBeenDisplayed = false;\n\n    /**\n     * The environment variables that should be passed from host machine to the PHP server process.\n     *\n     * @var string[]\n     */\n    public static $passthroughVariables = [\n        'APP_ENV',\n        'HERD_PHP_81_INI_SCAN_DIR',\n        'HERD_PHP_82_INI_SCAN_DIR',\n        'HERD_PHP_83_INI_SCAN_DIR',\n        'HERD_PHP_84_INI_SCAN_DIR',\n        'HERD_PHP_85_INI_SCAN_DIR',\n        'IGNITION_LOCAL_SITES_PATH',\n        'LARAVEL_SAIL',\n        'PATH',\n        'PHP_IDE_CONFIG',\n        'SYSTEMROOT',\n        'XDEBUG_CONFIG',\n        'XDEBUG_MODE',\n        'XDEBUG_SESSION',\n    ];\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function initialize(InputInterface $input, OutputInterface $output): void\n    {\n        $this->phpServerWorkers = transform((int) env('PHP_CLI_SERVER_WORKERS', 1), function (int $workers) {\n            if ($workers < 2) {\n                return false;\n            }\n\n            if ($workers > 1 &&\n                ! $this->option('no-reload') &&\n                ! (int) env('LARAVEL_SAIL', 0)) {\n                $this->components->warn('Unable to respect the `PHP_CLI_SERVER_WORKERS` environment variable without the `--no-reload` flag. Only creating a single server.');\n\n                return false;\n            }\n\n            return $workers;\n        });\n\n        parent::initialize($input, $output);\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     *\n     * @throws \\Exception\n     */\n    public function handle()\n    {\n        $environmentFile = $this->option('env')\n            ? base_path('.env').'.'.$this->option('env')\n            : base_path('.env');\n\n        $hasEnvironment = file_exists($environmentFile);\n\n        $environmentLastModified = $hasEnvironment\n            ? filemtime($environmentFile)\n            : Carbon::now()->addDays(30)->getTimestamp();\n\n        $process = $this->startProcess($hasEnvironment);\n\n        while ($process->isRunning()) {\n            if ($hasEnvironment) {\n                clearstatcache(false, $environmentFile);\n            }\n\n            if (! $this->option('no-reload') &&\n                $hasEnvironment &&\n                filemtime($environmentFile) > $environmentLastModified) {\n                $environmentLastModified = filemtime($environmentFile);\n\n                $this->newLine();\n\n                $this->components->info('Environment modified. Restarting server...');\n\n                $process->stop(5);\n\n                $this->serverRunningHasBeenDisplayed = false;\n\n                $process = $this->startProcess($hasEnvironment);\n            }\n\n            usleep(500 * 1000);\n        }\n\n        $status = $process->getExitCode();\n\n        if ($status && $this->canTryAnotherPort()) {\n            $this->portOffset += 1;\n\n            return $this->handle();\n        }\n\n        return $status;\n    }\n\n    /**\n     * Start a new server process.\n     *\n     * @param  bool  $hasEnvironment\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    protected function startProcess($hasEnvironment)\n    {\n        $process = new Process($this->serverCommand(), public_path(), (new Collection($_ENV))->mapWithKeys(function ($value, $key) use ($hasEnvironment) {\n            if ($this->option('no-reload') || ! $hasEnvironment) {\n                return [$key => $value];\n            }\n\n            return in_array($key, static::$passthroughVariables) ? [$key => $value] : [$key => false];\n        })->merge(['PHP_CLI_SERVER_WORKERS' => $this->phpServerWorkers])->all());\n\n        $this->trap(fn () => [SIGTERM, SIGINT, SIGHUP, SIGUSR1, SIGUSR2, SIGQUIT], function ($signal) use ($process) {\n            if ($process->isRunning()) {\n                $process->stop(10, $signal);\n            }\n\n            exit;\n        });\n\n        $process->start($this->handleProcessOutput());\n\n        return $process;\n    }\n\n    /**\n     * Get the full server command.\n     *\n     * @return array\n     */\n    protected function serverCommand()\n    {\n        $server = file_exists(base_path('server.php'))\n            ? base_path('server.php')\n            : __DIR__.'/../resources/server.php';\n\n        return [\n            php_binary(),\n            '-S',\n            $this->host().':'.$this->port(),\n            $server,\n        ];\n    }\n\n    /**\n     * Get the host for the command.\n     *\n     * @return string\n     */\n    protected function host()\n    {\n        [$host] = $this->getHostAndPort();\n\n        return $host;\n    }\n\n    /**\n     * Get the port for the command.\n     *\n     * @return string\n     */\n    protected function port()\n    {\n        $port = $this->input->getOption('port');\n\n        if (is_null($port)) {\n            [, $port] = $this->getHostAndPort();\n        }\n\n        $port = $port ?: 8000;\n\n        return $port + $this->portOffset;\n    }\n\n    /**\n     * Get the host and port from the host option string.\n     *\n     * @return array\n     */\n    protected function getHostAndPort()\n    {\n        if (preg_match('/(\\[.*\\]):?([0-9]+)?/', $this->input->getOption('host'), $matches) !== false) {\n            return [\n                $matches[1] ?? $this->input->getOption('host'),\n                $matches[2] ?? null,\n            ];\n        }\n\n        $hostParts = explode(':', $this->input->getOption('host'));\n\n        return [\n            $hostParts[0],\n            $hostParts[1] ?? null,\n        ];\n    }\n\n    /**\n     * Check if the command has reached its maximum number of port tries.\n     *\n     * @return bool\n     */\n    protected function canTryAnotherPort()\n    {\n        return is_null($this->input->getOption('port')) &&\n            ($this->input->getOption('tries') > $this->portOffset);\n    }\n\n    /**\n     * Returns a \"callable\" to handle the process output.\n     *\n     * @return callable(string, string): void\n     */\n    protected function handleProcessOutput()\n    {\n        return function ($type, $buffer) {\n            $this->outputBuffer .= $buffer;\n\n            $this->flushOutputBuffer();\n        };\n    }\n\n    /**\n     * Flush the output buffer.\n     *\n     * @return void\n     */\n    protected function flushOutputBuffer()\n    {\n        $lines = (new Stringable($this->outputBuffer))->explode(\"\\n\");\n\n        $this->outputBuffer = (string) $lines->pop();\n\n        $lines\n            ->map(fn ($line) => trim($line))\n            ->filter()\n            ->each(function ($line) {\n                if ((new Stringable($line))->contains('Development Server (http')) {\n                    if ($this->serverRunningHasBeenDisplayed === false) {\n                        $this->serverRunningHasBeenDisplayed = true;\n\n                        $this->components->info(\"Server running on [http://{$this->host()}:{$this->port()}].\");\n                        $this->comment('  <fg=yellow;options=bold>Press Ctrl+C to stop the server</>');\n\n                        $this->newLine();\n                    }\n\n                    return;\n                }\n\n                if ((new Stringable($line))->contains(' Accepted')) {\n                    $requestPort = static::getRequestPortFromLine($line);\n\n                    $this->requestsPool[$requestPort] = [\n                        $this->getDateFromLine($line),\n                        $this->requestsPool[$requestPort][1] ?? false,\n                        microtime(true),\n                    ];\n                } elseif ((new Stringable($line))->contains([' [200]: GET '])) {\n                    $requestPort = static::getRequestPortFromLine($line);\n\n                    $this->requestsPool[$requestPort][1] = trim(explode('[200]: GET', $line)[1]);\n                } elseif ((new Stringable($line))->contains('URI:')) {\n                    $requestPort = static::getRequestPortFromLine($line);\n\n                    $this->requestsPool[$requestPort][1] = trim(explode('URI: ', $line)[1]);\n                } elseif ((new Stringable($line))->contains(' Closing')) {\n                    $requestPort = static::getRequestPortFromLine($line);\n\n                    if (empty($this->requestsPool[$requestPort]) || count($this->requestsPool[$requestPort] ?? []) !== 3) {\n                        $this->requestsPool[$requestPort] = [\n                            $this->getDateFromLine($line),\n                            false,\n                            microtime(true),\n                        ];\n                    }\n\n                    [$startDate, $file, $startMicrotime] = $this->requestsPool[$requestPort];\n\n                    $formattedStartedAt = $startDate->format('Y-m-d H:i:s');\n\n                    unset($this->requestsPool[$requestPort]);\n\n                    [$date, $time] = explode(' ', $formattedStartedAt);\n\n                    $this->output->write(\"  <fg=gray>$date</> $time\");\n\n                    $runTime = $this->runTimeForHumans($startMicrotime);\n\n                    if ($file) {\n                        $this->output->write($file = \" $file\");\n                    }\n\n                    $dots = max(terminal()->width() - mb_strlen($formattedStartedAt) - mb_strlen($file) - mb_strlen($runTime) - 9, 0);\n\n                    $this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));\n                    $this->output->writeln(\" <fg=gray>~ {$runTime}</>\");\n                } elseif ((new Stringable($line))->contains(['Closed without sending a request', 'Failed to poll event'])) {\n                    // ...\n                } elseif (! empty($line)) {\n                    if ((new Stringable($line))->startsWith('[')) {\n                        $line = (new Stringable($line))->after('] ');\n                    }\n\n                    $this->output->writeln(\"  <fg=gray>$line</>\");\n                }\n            });\n    }\n\n    /**\n     * Get the date from the given PHP server output.\n     *\n     * @param  string  $line\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    protected function getDateFromLine($line)\n    {\n        $regex = ! windows_os() && is_int($this->phpServerWorkers)\n            ? '/^\\[\\d+]\\s\\[([a-zA-Z0-9: ]+)\\]/'\n            : '/^\\[([^\\]]+)\\]/';\n\n        $line = str_replace('  ', ' ', $line);\n\n        preg_match($regex, $line, $matches);\n\n        return Carbon::createFromFormat('D M d H:i:s Y', $matches[1]);\n    }\n\n    /**\n     * Get the request port from the given PHP server output.\n     *\n     * @param  string  $line\n     * @return int\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function getRequestPortFromLine($line)\n    {\n        preg_match('/(\\[\\w+\\s\\w+\\s\\d+\\s[\\d:]+\\s\\d{4}\\]\\s)?:(\\d+)\\s(?:(?:\\w+$)|(?:\\[.*))/', $line, $matches);\n\n        if (! isset($matches[2])) {\n            throw new \\InvalidArgumentException(\"Failed to extract the request port. Ensure the log line contains a valid port: {$line}\");\n        }\n\n        return (int) $matches[2];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on', Env::get('SERVER_HOST', '127.0.0.1')],\n            ['port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on', Env::get('SERVER_PORT')],\n            ['tries', null, InputOption::VALUE_OPTIONAL, 'The max number of ports to attempt to serve from', 10],\n            ['no-reload', null, InputOption::VALUE_NONE, 'Do not reload the development server on .env file changes'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/StorageLinkCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'storage:link')]\nclass StorageLinkCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'storage:link\n                {--relative : Create the symbolic link using relative paths}\n                {--force : Recreate existing symbolic links}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create the symbolic links configured for the application';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $relative = $this->option('relative');\n\n        foreach ($this->links() as $link => $target) {\n            if (file_exists($link) && ! $this->isRemovableSymlink($link, $this->option('force'))) {\n                $this->components->error(\"The [$link] link already exists.\");\n                continue;\n            }\n\n            if (is_link($link)) {\n                $this->laravel->make('files')->delete($link);\n            }\n\n            if ($relative) {\n                $this->laravel->make('files')->relativeLink($target, $link);\n            } else {\n                $this->laravel->make('files')->link($target, $link);\n            }\n\n            $this->components->info(\"The [$link] link has been connected to [$target].\");\n        }\n    }\n\n    /**\n     * Get the symbolic links that are configured for the application.\n     *\n     * @return array\n     */\n    protected function links()\n    {\n        return $this->laravel['config']['filesystems.links'] ??\n               [public_path('storage') => storage_path('app/public')];\n    }\n\n    /**\n     * Determine if the provided path is a symlink that can be removed.\n     *\n     * @param  string  $link\n     * @param  bool  $force\n     * @return bool\n     */\n    protected function isRemovableSymlink(string $link, bool $force): bool\n    {\n        return is_link($link) && $force;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/StorageUnlinkCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'storage:unlink')]\nclass StorageUnlinkCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'storage:unlink';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Delete existing symbolic links configured for the application';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        foreach ($this->links() as $link => $target) {\n            if (! file_exists($link) || ! is_link($link)) {\n                continue;\n            }\n\n            $this->laravel->make('files')->delete($link);\n\n            $this->components->info(\"The [$link] link has been deleted.\");\n        }\n    }\n\n    /**\n     * Get the symbolic links that are configured for the application.\n     *\n     * @return array\n     */\n    protected function links()\n    {\n        return $this->laravel['config']['filesystems.links'] ??\n               [public_path('storage') => storage_path('app/public')];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/StubPublishCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Events\\PublishingStubs;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'stub:publish')]\nclass StubPublishCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'stub:publish\n                    {--existing : Publish and overwrite only the files that have already been published}\n                    {--force : Overwrite any existing files}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Publish all stubs that are available for customization';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (! is_dir($stubsPath = $this->laravel->basePath('stubs'))) {\n            (new Filesystem)->makeDirectory($stubsPath);\n        }\n\n        $stubs = [\n            __DIR__.'/stubs/cast.inbound.stub' => 'cast.inbound.stub',\n            __DIR__.'/stubs/cast.stub' => 'cast.stub',\n            __DIR__.'/stubs/class.stub' => 'class.stub',\n            __DIR__.'/stubs/class.invokable.stub' => 'class.invokable.stub',\n            __DIR__.'/stubs/console.stub' => 'console.stub',\n            __DIR__.'/stubs/enum.stub' => 'enum.stub',\n            __DIR__.'/stubs/enum.backed.stub' => 'enum.backed.stub',\n            __DIR__.'/stubs/event.stub' => 'event.stub',\n            __DIR__.'/stubs/job.queued.stub' => 'job.queued.stub',\n            __DIR__.'/stubs/job.stub' => 'job.stub',\n            __DIR__.'/stubs/listener.typed.queued.stub' => 'listener.typed.queued.stub',\n            __DIR__.'/stubs/listener.queued.stub' => 'listener.queued.stub',\n            __DIR__.'/stubs/listener.typed.stub' => 'listener.typed.stub',\n            __DIR__.'/stubs/listener.stub' => 'listener.stub',\n            __DIR__.'/stubs/mail.stub' => 'mail.stub',\n            __DIR__.'/stubs/markdown-mail.stub' => 'markdown-mail.stub',\n            __DIR__.'/stubs/markdown-notification.stub' => 'markdown-notification.stub',\n            __DIR__.'/stubs/model.pivot.stub' => 'model.pivot.stub',\n            __DIR__.'/stubs/model.stub' => 'model.stub',\n            __DIR__.'/stubs/notification.stub' => 'notification.stub',\n            __DIR__.'/stubs/observer.plain.stub' => 'observer.plain.stub',\n            __DIR__.'/stubs/observer.stub' => 'observer.stub',\n            __DIR__.'/stubs/pest.stub' => 'pest.stub',\n            __DIR__.'/stubs/pest.unit.stub' => 'pest.unit.stub',\n            __DIR__.'/stubs/policy.plain.stub' => 'policy.plain.stub',\n            __DIR__.'/stubs/policy.stub' => 'policy.stub',\n            __DIR__.'/stubs/provider.stub' => 'provider.stub',\n            __DIR__.'/stubs/request.stub' => 'request.stub',\n            __DIR__.'/stubs/resource.stub' => 'resource.stub',\n            __DIR__.'/stubs/resource-collection.stub' => 'resource-collection.stub',\n            __DIR__.'/stubs/rule.stub' => 'rule.stub',\n            __DIR__.'/stubs/scope.stub' => 'scope.stub',\n            __DIR__.'/stubs/test.stub' => 'test.stub',\n            __DIR__.'/stubs/test.unit.stub' => 'test.unit.stub',\n            __DIR__.'/stubs/trait.stub' => 'trait.stub',\n            __DIR__.'/stubs/view-component.stub' => 'view-component.stub',\n            realpath(__DIR__.'/../../Database/Console/Factories/stubs/factory.stub') => 'factory.stub',\n            realpath(__DIR__.'/../../Database/Console/Seeds/stubs/seeder.stub') => 'seeder.stub',\n            realpath(__DIR__.'/../../Database/Migrations/stubs/migration.create.stub') => 'migration.create.stub',\n            realpath(__DIR__.'/../../Database/Migrations/stubs/migration.stub') => 'migration.stub',\n            realpath(__DIR__.'/../../Database/Migrations/stubs/migration.update.stub') => 'migration.update.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.api.stub') => 'controller.api.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.invokable.stub') => 'controller.invokable.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.model.api.stub') => 'controller.model.api.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.model.stub') => 'controller.model.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.api.stub') => 'controller.nested.api.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.api.stub') => 'controller.nested.singleton.api.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.singleton.stub') => 'controller.nested.singleton.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.nested.stub') => 'controller.nested.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.plain.stub') => 'controller.plain.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.api.stub') => 'controller.singleton.api.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.singleton.stub') => 'controller.singleton.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/controller.stub') => 'controller.stub',\n            realpath(__DIR__.'/../../Routing/Console/stubs/middleware.stub') => 'middleware.stub',\n        ];\n\n        $this->laravel['events']->dispatch($event = new PublishingStubs($stubs));\n\n        foreach ($event->stubs as $from => $to) {\n            $to = $stubsPath.DIRECTORY_SEPARATOR.ltrim($to, DIRECTORY_SEPARATOR);\n\n            if ((! $this->option('existing') && (! file_exists($to) || $this->option('force')))\n                || ($this->option('existing') && file_exists($to))) {\n                file_put_contents($to, file_get_contents($from));\n            }\n        }\n\n        $this->components->info('Stubs published successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/TestMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'make:test')]\nclass TestMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:test';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new test class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Test';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        $suffix = $this->option('unit') ? '.unit.stub' : '.stub';\n\n        return $this->usingPest()\n            ? $this->resolveStubPath('/stubs/pest'.$suffix)\n            : $this->resolveStubPath('/stubs/test'.$suffix);\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the destination class path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getPath($name)\n    {\n        $name = Str::replaceFirst($this->rootNamespace(), '', $name);\n\n        return base_path('tests').str_replace('\\\\', '/', $name).'.php';\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        if ($this->option('unit')) {\n            return $rootNamespace.'\\Unit';\n        } else {\n            return $rootNamespace.'\\Feature';\n        }\n    }\n\n    /**\n     * Get the root namespace for the class.\n     *\n     * @return string\n     */\n    protected function rootNamespace()\n    {\n        return 'Tests';\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the test even if the test already exists'],\n            ['unit', 'u', InputOption::VALUE_NONE, 'Create a unit test'],\n            ['pest', null, InputOption::VALUE_NONE, 'Create a Pest test'],\n            ['phpunit', null, InputOption::VALUE_NONE, 'Create a PHPUnit test'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $type = select('Which type of test would you like?', [\n            'feature' => 'Feature',\n            'unit' => 'Unit',\n        ]);\n\n        match ($type) {\n            'feature' => null,\n            'unit' => $input->setOption('unit', true),\n        };\n    }\n\n    /**\n     * Determine if Pest is being used by the application.\n     *\n     * @return bool\n     */\n    protected function usingPest()\n    {\n        if ($this->option('phpunit')) {\n            return false;\n        }\n\n        return $this->option('pest') ||\n            (function_exists('\\Pest\\\\version') &&\n             file_exists(base_path('tests').'/Pest.php'));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/TraitMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:trait')]\nclass TraitMakeCommand extends GeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:trait';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new trait';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Trait';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/trait.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return match (true) {\n            is_dir(app_path('Concerns')) => $rootNamespace.'\\\\Concerns',\n            is_dir(app_path('Traits')) => $rootNamespace.'\\\\Traits',\n            default => $rootNamespace,\n        };\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the trait even if the trait already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/UpCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Foundation\\Events\\MaintenanceModeDisabled;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'up')]\nclass UpCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'up';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Bring the application out of maintenance mode';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle()\n    {\n        try {\n            if (! $this->laravel->maintenanceMode()->active()) {\n                $this->components->info('Application is already up.');\n\n                return 0;\n            }\n\n            $this->laravel->maintenanceMode()->deactivate();\n\n            if (is_file(storage_path('framework/maintenance.php'))) {\n                unlink(storage_path('framework/maintenance.php'));\n            }\n\n            $this->laravel->get('events')->dispatch(new MaintenanceModeDisabled());\n\n            $this->components->info('Application is now live.');\n        } catch (Exception $e) {\n            $this->components->error(sprintf(\n                'Failed to disable maintenance mode: %s.',\n                $e->getMessage(),\n            ));\n\n            return 1;\n        }\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/VendorPublishCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Events\\VendorTagPublished;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Support\\Str;\nuse League\\Flysystem\\Filesystem as Flysystem;\nuse League\\Flysystem\\Local\\LocalFilesystemAdapter as LocalAdapter;\nuse League\\Flysystem\\MountManager;\nuse League\\Flysystem\\UnixVisibility\\PortableVisibilityConverter;\nuse League\\Flysystem\\Visibility;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Laravel\\Prompts\\search;\nuse function Laravel\\Prompts\\select;\n\n#[AsCommand(name: 'vendor:publish')]\nclass VendorPublishCommand extends Command\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The provider to publish.\n     *\n     * @var string|null\n     */\n    protected $provider = null;\n\n    /**\n     * The tags to publish.\n     *\n     * @var array\n     */\n    protected $tags = [];\n\n    /**\n     * The time the command started.\n     *\n     * @var \\Illuminate\\Support\\Carbon|null\n     */\n    protected $publishedAt;\n\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'vendor:publish\n                    {--existing : Publish and overwrite only the files that have already been published}\n                    {--force : Overwrite any existing files}\n                    {--all : Publish assets for all service providers without prompt}\n                    {--provider= : The service provider that has assets you want to publish}\n                    {--tag=* : One or many tags that have assets you want to publish}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Publish any publishable assets from vendor packages';\n\n    /**\n     * Indicates if migration dates should be updated while publishing.\n     *\n     * @var bool\n     */\n    protected static $updateMigrationDates = true;\n\n    /**\n     * Create a new command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->publishedAt = Carbon::now();\n\n        $this->determineWhatShouldBePublished();\n\n        foreach ($this->tags ?: [null] as $tag) {\n            $this->publishTag($tag);\n        }\n    }\n\n    /**\n     * Determine the provider or tag(s) to publish.\n     *\n     * @return void\n     */\n    protected function determineWhatShouldBePublished()\n    {\n        if ($this->option('all')) {\n            return;\n        }\n\n        [$this->provider, $this->tags] = [\n            $this->option('provider'), (array) $this->option('tag'),\n        ];\n\n        if (! $this->provider && ! $this->tags) {\n            $this->promptForProviderOrTag();\n        }\n    }\n\n    /**\n     * Prompt for which provider or tag to publish.\n     *\n     * @return void\n     */\n    protected function promptForProviderOrTag()\n    {\n        $choices = $this->publishableChoices();\n\n        $choice = windows_os()\n            ? select(\n                \"Which provider or tag's files would you like to publish?\",\n                $choices,\n                scroll: 15,\n            )\n            : search(\n                label: \"Which provider or tag's files would you like to publish?\",\n                placeholder: 'Search...',\n                options: fn ($search) => array_values(array_filter(\n                    $choices,\n                    fn ($choice) => str_contains(strtolower($choice), strtolower($search))\n                )),\n                scroll: 15,\n            );\n\n        if ($choice == $choices[0] || is_null($choice)) {\n            return;\n        }\n\n        $this->parseChoice($choice);\n    }\n\n    /**\n     * The choices available via the prompt.\n     *\n     * @return array\n     */\n    protected function publishableChoices()\n    {\n        return array_merge(\n            ['All providers and tags'],\n            preg_filter('/^/', '<fg=gray>Provider:</> ', Arr::sort(ServiceProvider::publishableProviders())),\n            preg_filter('/^/', '<fg=gray>Tag:</> ', Arr::sort(ServiceProvider::publishableGroups()))\n        );\n    }\n\n    /**\n     * Parse the answer that was given via the prompt.\n     *\n     * @param  string  $choice\n     * @return void\n     */\n    protected function parseChoice($choice)\n    {\n        [$type, $value] = explode(': ', strip_tags($choice));\n\n        if ($type === 'Provider') {\n            $this->provider = $value;\n        } elseif ($type === 'Tag') {\n            $this->tags = [$value];\n        }\n    }\n\n    /**\n     * Publishes the assets for a tag.\n     *\n     * @param  string  $tag\n     * @return void\n     */\n    protected function publishTag($tag)\n    {\n        $pathsToPublish = $this->pathsToPublish($tag);\n\n        if ($publishing = count($pathsToPublish) > 0) {\n            $this->components->info(sprintf(\n                'Publishing %sassets',\n                $tag ? \"[$tag] \" : '',\n            ));\n        }\n\n        foreach ($pathsToPublish as $from => $to) {\n            $this->publishItem($from, $to);\n        }\n\n        if ($publishing === false) {\n            $this->components->info('No publishable resources for tag ['.$tag.'].');\n        } else {\n            $this->laravel['events']->dispatch(new VendorTagPublished($tag, $pathsToPublish));\n\n            $this->newLine();\n        }\n    }\n\n    /**\n     * Get all of the paths to publish.\n     *\n     * @param  string  $tag\n     * @return array\n     */\n    protected function pathsToPublish($tag)\n    {\n        return ServiceProvider::pathsToPublish(\n            $this->provider, $tag\n        );\n    }\n\n    /**\n     * Publish the given item from and to the given location.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return void\n     */\n    protected function publishItem($from, $to)\n    {\n        if ($this->files->isFile($from)) {\n            return $this->publishFile($from, $to);\n        } elseif ($this->files->isDirectory($from)) {\n            return $this->publishDirectory($from, $to);\n        }\n\n        $this->components->error(\"Can't locate path: <{$from}>\");\n    }\n\n    /**\n     * Publish the file to the given path.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return void\n     */\n    protected function publishFile($from, $to)\n    {\n        if ((! $this->option('existing') && (! $this->files->exists($to) || $this->option('force')))\n            || ($this->option('existing') && $this->files->exists($to))) {\n            $to = $this->ensureMigrationNameIsUpToDate($from, $to);\n\n            $this->createParentDirectory(dirname($to));\n\n            $this->files->copy($from, $to);\n\n            $this->status($from, $to, 'file');\n        } else {\n            if ($this->option('existing')) {\n                $this->components->twoColumnDetail(sprintf(\n                    'File [%s] does not exist',\n                    str_replace(base_path().'/', '', $to),\n                ), '<fg=yellow;options=bold>SKIPPED</>');\n            } else {\n                $this->components->twoColumnDetail(sprintf(\n                    'File [%s] already exists',\n                    str_replace(base_path().'/', '', realpath($to)),\n                ), '<fg=yellow;options=bold>SKIPPED</>');\n            }\n        }\n    }\n\n    /**\n     * Publish the directory to the given directory.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return void\n     */\n    protected function publishDirectory($from, $to)\n    {\n        $visibility = PortableVisibilityConverter::fromArray([], Visibility::PUBLIC);\n\n        $this->moveManagedFiles($from, new MountManager([\n            'from' => new Flysystem(new LocalAdapter($from)),\n            'to' => new Flysystem(new LocalAdapter($to, $visibility)),\n        ]));\n\n        $this->status($from, $to, 'directory');\n    }\n\n    /**\n     * Move all the files in the given MountManager.\n     *\n     * @param  string  $from\n     * @param  \\League\\Flysystem\\MountManager  $manager\n     * @return void\n     */\n    protected function moveManagedFiles($from, $manager)\n    {\n        foreach ($manager->listContents('from://', true)->sortByPath() as $file) {\n            $path = Str::after($file['path'], 'from://');\n\n            if (\n                $file['type'] === 'file'\n                && (\n                    (! $this->option('existing') && (! $manager->fileExists('to://'.$path) || $this->option('force')))\n                    || ($this->option('existing') && $manager->fileExists('to://'.$path))\n                )\n            ) {\n                $path = $this->ensureMigrationNameIsUpToDate($from, $path);\n\n                $manager->write('to://'.$path, $manager->read($file['path']));\n            }\n        }\n    }\n\n    /**\n     * Create the directory to house the published files if needed.\n     *\n     * @param  string  $directory\n     * @return void\n     */\n    protected function createParentDirectory($directory)\n    {\n        if (! $this->files->isDirectory($directory)) {\n            $this->files->makeDirectory($directory, 0755, true);\n        }\n    }\n\n    /**\n     * Ensure the given migration name is up-to-date.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return string\n     */\n    protected function ensureMigrationNameIsUpToDate($from, $to)\n    {\n        if (static::$updateMigrationDates === false) {\n            return $to;\n        }\n\n        $from = realpath($from);\n\n        foreach (ServiceProvider::publishableMigrationPaths() as $path) {\n            $path = realpath($path);\n\n            if ($from === $path && preg_match('/\\d{4}_(\\d{2})_(\\d{2})_(\\d{6})_/', $to)) {\n                $this->publishedAt = $this->publishedAt->addSecond();\n\n                return preg_replace(\n                    '/\\d{4}_(\\d{2})_(\\d{2})_(\\d{6})_/',\n                    $this->publishedAt->format('Y_m_d_His').'_',\n                    $to,\n                );\n            }\n        }\n\n        return $to;\n    }\n\n    /**\n     * Write a status message to the console.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @param  string  $type\n     * @return void\n     */\n    protected function status($from, $to, $type)\n    {\n        $from = str_replace(base_path().'/', '', realpath($from));\n\n        $to = str_replace(base_path().'/', '', realpath($to));\n\n        $this->components->task(sprintf(\n            'Copying %s [%s] to [%s]',\n            $type,\n            $from,\n            $to,\n        ));\n    }\n\n    /**\n     * Instruct the command to not update the dates on migrations when publishing.\n     *\n     * @return void\n     */\n    public static function dontUpdateMigrationDates()\n    {\n        static::$updateMigrationDates = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ViewCacheCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Finder\\Finder;\nuse Symfony\\Component\\Finder\\SplFileInfo;\n\n#[AsCommand(name: 'view:cache')]\nclass ViewCacheCommand extends Command\n{\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $signature = 'view:cache';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = \"Compile all of the application's Blade templates\";\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->callSilent('view:clear');\n\n        $this->paths()->each(function ($path) {\n            $prefix = $this->output->isVeryVerbose() ? '<fg=yellow;options=bold>DIR</> ' : '';\n\n            $this->components->task($prefix.$path, null, OutputInterface::VERBOSITY_VERBOSE);\n\n            $this->compileViews($this->bladeFilesIn([$path]));\n        });\n\n        $this->newLine();\n\n        $this->components->info('Blade templates cached successfully.');\n    }\n\n    /**\n     * Compile the given view files.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $views\n     * @return void\n     */\n    protected function compileViews(Collection $views)\n    {\n        $compiler = $this->laravel['view']->getEngineResolver()->resolve('blade')->getCompiler();\n\n        $views->map(function (SplFileInfo $file) use ($compiler) {\n            $this->components->task('    '.$file->getRelativePathname(), null, OutputInterface::VERBOSITY_VERY_VERBOSE);\n\n            $compiler->compile($file->getRealPath());\n        });\n\n        if ($this->output->isVeryVerbose()) {\n            $this->newLine();\n        }\n    }\n\n    /**\n     * Get the Blade files in the given path.\n     *\n     * @param  array  $paths\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function bladeFilesIn(array $paths)\n    {\n        $extensions = (new Collection($this->laravel['view']->getExtensions()))\n            ->filter(fn ($value) => $value === 'blade')\n            ->keys()\n            ->map(fn ($extension) => \"*.{$extension}\")\n            ->all();\n\n        return new Collection(\n            Finder::create()\n                ->in($paths)\n                ->exclude('vendor')\n                ->name($extensions)\n                ->files()\n        );\n    }\n\n    /**\n     * Get all of the possible view paths.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function paths()\n    {\n        $finder = $this->laravel['view']->getFinder();\n\n        $paths = (new Collection($finder->getPaths()))->merge(\n            (new Collection($finder->getHints()))->flatten()\n        )->unique();\n\n        return $paths->reject(fn ($path) => $paths->contains(function ($existing) use ($path) {\n            return $existing !== $path && str_starts_with(realpath($path) ?: $path, realpath($existing) ?: $existing);\n        }))->values();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ViewClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Filesystem\\Filesystem;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'view:clear')]\nclass ViewClearCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'view:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Clear all compiled view files';\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new config clear command instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        parent::__construct();\n\n        $this->files = $files;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function handle()\n    {\n        $path = $this->laravel['config']['view.compiled'];\n\n        if (! $path) {\n            throw new RuntimeException('View path not found.');\n        }\n\n        $this->laravel['view.engine.resolver']\n            ->resolve('blade')\n            ->forgetCompiledOrNotExpired();\n\n        foreach ($this->files->glob(\"{$path}/*\") as $view) {\n            if ($this->files->isDirectory($view)) {\n                $this->files->deleteDirectory($view);\n            } else {\n                $this->files->delete($view);\n            }\n        }\n\n        $this->components->info('Compiled views cleared successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/ViewMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Illuminate\\Foundation\\Inspiring;\nuse Illuminate\\Support\\Facades\\File;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'make:view')]\nclass ViewMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new view';\n\n    /**\n     * The name and signature of the console command.\n     *\n     * @var string\n     */\n    protected $name = 'make:view';\n\n    /**\n     * The type of file being generated.\n     *\n     * @var string\n     */\n    protected $type = 'View';\n\n    /**\n     * Build the class with the given name.\n     *\n     * @param  string  $name\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    protected function buildClass($name)\n    {\n        $contents = parent::buildClass($name);\n\n        return str_replace(\n            '{{ quote }}',\n            Inspiring::quotes()->random(),\n            $contents,\n        );\n    }\n\n    /**\n     * Get the destination view path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function getPath($name)\n    {\n        return $this->viewPath(\n            $this->getNameInput().'.'.$this->option('extension'),\n        );\n    }\n\n    /**\n     * Get the desired view name from the input.\n     *\n     * @return string\n     */\n    protected function getNameInput()\n    {\n        $name = trim($this->argument('name'));\n\n        $name = str_replace(['\\\\', '.'], '/', $name);\n\n        return $name;\n    }\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath(\n            '/stubs/view.stub',\n        );\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the destination test case path.\n     *\n     * @return string\n     */\n    protected function getTestPath()\n    {\n        return base_path(\n            Str::of($this->testClassFullyQualifiedName())\n                ->replace('\\\\', '/')\n                ->replaceFirst('Tests/Feature', 'tests/Feature')\n                ->append('Test.php')\n                ->value()\n        );\n    }\n\n    /**\n     * Create the matching test case if requested.\n     *\n     * @param  string  $path\n     */\n    protected function handleTestCreation($path): bool\n    {\n        if (! $this->option('test') && ! $this->option('pest') && ! $this->option('phpunit')) {\n            return false;\n        }\n\n        $contents = preg_replace(\n            ['/\\{{ namespace \\}}/', '/\\{{ class \\}}/', '/\\{{ name \\}}/'],\n            [$this->testNamespace(), $this->testClassName(), $this->testViewName()],\n            File::get($this->getTestStub()),\n        );\n\n        File::ensureDirectoryExists(dirname($this->getTestPath()), 0755, true);\n\n        $result = File::put($path = $this->getTestPath(), $contents);\n\n        $this->components->info(sprintf('%s [%s] created successfully.', 'Test', $path));\n\n        return $result !== false;\n    }\n\n    /**\n     * Get the namespace for the test.\n     *\n     * @return string\n     */\n    protected function testNamespace()\n    {\n        return Str::of($this->testClassFullyQualifiedName())\n            ->beforeLast('\\\\')\n            ->value();\n    }\n\n    /**\n     * Get the class name for the test.\n     *\n     * @return string\n     */\n    protected function testClassName()\n    {\n        return Str::of($this->testClassFullyQualifiedName())\n            ->afterLast('\\\\')\n            ->append('Test')\n            ->value();\n    }\n\n    /**\n     * Get the class fully-qualified name for the test.\n     *\n     * @return string\n     */\n    protected function testClassFullyQualifiedName()\n    {\n        $name = Str::of(Str::lower($this->getNameInput()))->replace('.'.$this->option('extension'), '');\n\n        $namespacedName = Str::of(\n            (new Stringable($name))\n                ->replace('/', ' ')\n                ->explode(' ')\n                ->map(fn ($part) => (new Stringable($part))->ucfirst())\n                ->implode('\\\\')\n        )\n            ->replace(['-', '_'], ' ')\n            ->explode(' ')\n            ->map(fn ($part) => (new Stringable($part))->ucfirst())\n            ->implode('');\n\n        return 'Tests\\\\Feature\\\\View\\\\'.$namespacedName;\n    }\n\n    /**\n     * Get the test stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getTestStub()\n    {\n        $stubName = 'view.'.($this->usingPest() ? 'pest' : 'test').'.stub';\n\n        return file_exists($customPath = $this->laravel->basePath(\"stubs/$stubName\"))\n            ? $customPath\n            : __DIR__.'/stubs/'.$stubName;\n    }\n\n    /**\n     * Get the view name for the test.\n     *\n     * @return string\n     */\n    protected function testViewName()\n    {\n        return Str::of($this->getNameInput())\n            ->replace('/', '.')\n            ->lower()\n            ->value();\n    }\n\n    /**\n     * Determine if Pest is being used by the application.\n     *\n     * @return bool\n     */\n    protected function usingPest()\n    {\n        if ($this->option('phpunit')) {\n            return false;\n        }\n\n        return $this->option('pest') ||\n            (function_exists('\\Pest\\\\version') &&\n             file_exists(base_path('tests').'/Pest.php'));\n    }\n\n    /**\n     * Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['extension', null, InputOption::VALUE_OPTIONAL, 'The extension of the generated view', 'blade.php'],\n            ['force', 'f', InputOption::VALUE_NONE, 'Create the view even if the view already exists'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/api-routes.stub",
    "content": "<?php\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::get('/user', function (Request $request) {\n    return $request->user();\n})->middleware('auth:sanctum');\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/broadcasting-routes.stub",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Broadcast;\n\nBroadcast::channel('App.Models.User.{id}', function ($user, $id) {\n    return (int) $user->id === (int) $id;\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/cast.inbound.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes;\n\nclass {{ class }} implements CastsInboundAttributes\n{\n    /**\n     * Prepare the given value for storage.\n     *\n     * @param  array<string, mixed>  $attributes\n     */\n    public function set(Model $model, string $key, mixed $value, array $attributes): mixed\n    {\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/cast.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\n\nclass {{ class }} implements CastsAttributes\n{\n    /**\n     * Cast the given value.\n     *\n     * @param  array<string, mixed>  $attributes\n     */\n    public function get(Model $model, string $key, mixed $value, array $attributes): mixed\n    {\n        return $value;\n    }\n\n    /**\n     * Prepare the given value for storage.\n     *\n     * @param  array<string, mixed>  $attributes\n     */\n    public function set(Model $model, string $key, mixed $value, array $attributes): mixed\n    {\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/channel.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedUserModel }};\n\nclass {{ class }}\n{\n    /**\n     * Create a new channel instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Authenticate the user's access to the channel.\n     */\n    public function join({{ userModel }} $user): array|bool\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/class.invokable.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nclass {{ class }}\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Invoke the class instance.\n     */\n    public function __invoke(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/class.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nclass {{ class }}\n{\n    /**\n     * Create a new class instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/config.stub",
    "content": "<?php\n\nreturn [\n    //\n];\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/console.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Console\\Attributes\\Description;\nuse Illuminate\\Console\\Attributes\\Signature;\nuse Illuminate\\Console\\Command;\n\n#[Signature('{{ command }}')]\n#[Description('Command description')]\nclass {{ class }} extends Command\n{\n    /**\n     * Execute the console command.\n     */\n    public function handle()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/echo-bootstrap-js.stub",
    "content": "/**\n * Echo exposes an expressive API for subscribing to channels and listening\n * for events that are broadcast by Laravel. Echo and event broadcasting\n * allow your team to quickly build robust real-time web applications.\n */\n\nimport './echo';\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/echo-js-ably.stub",
    "content": "import Echo from 'laravel-echo';\n\nimport Pusher from 'pusher-js';\nwindow.Pusher = Pusher;\n\nwindow.Echo = new Echo({\n    broadcaster: \"pusher\",\n    key: import.meta.env.VITE_ABLY_PUBLIC_KEY,\n    wsHost: \"realtime-pusher.ably.io\",\n    wsPort: 443,\n    disableStats: true,\n    encrypted: true,\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/echo-js-pusher.stub",
    "content": "import Echo from 'laravel-echo';\n\nimport Pusher from 'pusher-js';\nwindow.Pusher = Pusher;\n\nwindow.Echo = new Echo({\n    broadcaster: \"pusher\",\n    key: import.meta.env.VITE_PUSHER_APP_KEY,\n    cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,\n    forceTLS: true,\n    wsHost: import.meta.env.VITE_PUSHER_HOST,\n    wsPort: import.meta.env.VITE_PUSHER_PORT,\n    wssPort: import.meta.env.VITE_PUSHER_PORT,\n    enabledTransports: [\"ws\", \"wss\"],\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/echo-js-reverb.stub",
    "content": "import Echo from 'laravel-echo';\n\nimport Pusher from 'pusher-js';\nwindow.Pusher = Pusher;\n\nwindow.Echo = new Echo({\n    broadcaster: 'reverb',\n    key: import.meta.env.VITE_REVERB_APP_KEY,\n    wsHost: import.meta.env.VITE_REVERB_HOST,\n    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,\n    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,\n    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',\n    enabledTransports: ['ws', 'wss'],\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/enum.backed.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nenum {{ class }}: {{ type }}\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/enum.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nenum {{ class }}\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/event.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Broadcasting\\Channel;\nuse Illuminate\\Broadcasting\\InteractsWithSockets;\nuse Illuminate\\Broadcasting\\PresenceChannel;\nuse Illuminate\\Broadcasting\\PrivateChannel;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Foundation\\Events\\Dispatchable;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass {{ class }}\n{\n    use Dispatchable, InteractsWithSockets, SerializesModels;\n\n    /**\n     * Create a new event instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return array<int, Channel>\n     */\n    public function broadcastOn(): array\n    {\n        return [\n            new PrivateChannel('channel-name'),\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/exception-render-report.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Exception;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\n\nclass {{ class }} extends Exception\n{\n    /**\n     * Report the exception.\n     */\n    public function report(): void\n    {\n        //\n    }\n\n    /**\n     * Render the exception as an HTTP response.\n     */\n    public function render(Request $request): Response\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/exception-render.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Exception;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\n\nclass {{ class }} extends Exception\n{\n    /**\n     * Render the exception as an HTTP response.\n     */\n    public function render(Request $request): Response\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/exception-report.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Exception;\n\nclass {{ class }} extends Exception\n{\n    /**\n     * Report the exception.\n     */\n    public function report(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/exception.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Exception;\n\nclass {{ class }} extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/interface.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\ninterface {{ class }}\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/job.batched.queued.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass {{ class }} implements ShouldQueue\n{\n    use Batchable, Queueable;\n\n    /**\n     * Create a new job instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Execute the job.\n     */\n    public function handle(): void\n    {\n        if ($this->batch()->cancelled()) {\n            // The batch has been cancelled...\n\n            return;\n        }\n\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/job.middleware.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Closure;\n\nclass {{ class }}\n{\n    /**\n     * Process the queued job.\n     *\n     * @param  Closure(object): void  $next\n     */\n    public function handle(object $job, Closure $next): void\n    {\n        $next($job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/job.queued.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass {{ class }} implements ShouldQueue\n{\n    use Queueable;\n\n    /**\n     * Create a new job instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Execute the job.\n     */\n    public function handle(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/job.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\n\nclass {{ class }}\n{\n    use Dispatchable;\n\n    /**\n     * Create a new job instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Execute the job.\n     */\n    public function handle(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/listener.queued.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass {{ class }} implements ShouldQueue\n{\n    use InteractsWithQueue;\n\n    /**\n     * Create the event listener.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Handle the event.\n     */\n    public function handle(object $event): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/listener.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass {{ class }}\n{\n    /**\n     * Create the event listener.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Handle the event.\n     */\n    public function handle(object $event): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/listener.typed.queued.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ eventNamespace }};\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass {{ class }} implements ShouldQueue\n{\n    use InteractsWithQueue;\n\n    /**\n     * Create the event listener.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Handle the event.\n     */\n    public function handle({{ event }} $event): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/listener.typed.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ eventNamespace }};\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass {{ class }}\n{\n    /**\n     * Create the event listener.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Handle the event.\n     */\n    public function handle({{ event }} $event): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/mail.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Attachment;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass {{ class }} extends Mailable\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new message instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the message envelope.\n     */\n    public function envelope(): Envelope\n    {\n        return new Envelope(\n            subject: '{{ subject }}',\n        );\n    }\n\n    /**\n     * Get the message content definition.\n     */\n    public function content(): Content\n    {\n        return new Content(\n            view: 'view.name',\n        );\n    }\n\n    /**\n     * Get the attachments for the message.\n     *\n     * @return array<int, Attachment>\n     */\n    public function attachments(): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/maintenance-mode.stub",
    "content": "<?php\n\n// Check if the application is in maintenance mode...\nif (! file_exists($down = __DIR__.'/down')) {\n    return;\n}\n\n// Decode the \"down\" file's JSON...\n$data = json_decode(file_get_contents($down), true);\n\n// Allow framework to handle request if no prerendered template...\nif (! isset($data['template'])) {\n    return;\n}\n\n// Allow framework to handle request if request URI is in the exclude list...\nif (isset($data['except'])) {\n    $uri = parse_url($_SERVER['REQUEST_URI'])['path'];\n\n    $uri = rawurldecode($uri !== '/' ? trim($uri, '/') : $uri);\n\n    foreach ((array) $data['except'] as $except) {\n        $except = $except !== '/' ? trim($except, '/') : $except;\n\n        if ($except == $uri) {\n            return;\n        }\n\n        $except = preg_quote($except, '#');\n\n        $except = str_replace('\\*', '.*', $except);\n\n        if (preg_match('#^'.$except.'\\z#u', $uri) === 1) {\n            return;\n        }\n    }\n}\n\n// Allow framework to handle maintenance mode bypass route...\nif (isset($data['secret']) && $_SERVER['REQUEST_URI'] === '/'.$data['secret']) {\n    return;\n}\n\n// Determine if maintenance mode bypass cookie is valid...\nif (isset($_COOKIE['laravel_maintenance']) && isset($data['secret'])) {\n    $payload = json_decode(base64_decode($_COOKIE['laravel_maintenance']), true);\n\n    if (is_array($payload) &&\n        is_numeric($payload['expires_at'] ?? null) &&\n        isset($payload['mac']) &&\n        hash_equals(hash_hmac('sha256', $payload['expires_at'], $data['secret']), $payload['mac']) &&\n        (int) $payload['expires_at'] >= time()) {\n        return;\n    }\n}\n\n// Redirect to the proper path if necessary...\nif (isset($data['redirect']) && $_SERVER['REQUEST_URI'] !== $data['redirect']) {\n    http_response_code(302);\n    header('Location: '.$data['redirect']);\n\n    exit;\n}\n\n// Output the prerendered template...\nhttp_response_code($data['status'] ?? 503);\n\nif (isset($data['retry'])) {\n    header('Retry-After: '.$data['retry']);\n}\n\nif (isset($data['refresh'])) {\n    header('Refresh: '.$data['refresh']);\n}\n\necho $data['template'];\n\nexit;\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/markdown-mail.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Attachment;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass {{ class }} extends Mailable\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new message instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the message envelope.\n     */\n    public function envelope(): Envelope\n    {\n        return new Envelope(\n            subject: '{{ subject }}',\n        );\n    }\n\n    /**\n     * Get the message content definition.\n     */\n    public function content(): Content\n    {\n        return new Content(\n            markdown: '{{ view }}',\n        );\n    }\n\n    /**\n     * Get the attachments for the message.\n     *\n     * @return array<int, Attachment>\n     */\n    public function attachments(): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/markdown-notification.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notification;\n\nclass {{ class }} extends Notification\n{\n    use Queueable;\n\n    /**\n     * Create a new notification instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the notification's delivery channels.\n     *\n     * @return array<int, string>\n     */\n    public function via(object $notifiable): array\n    {\n        return ['mail'];\n    }\n\n    /**\n     * Get the mail representation of the notification.\n     */\n    public function toMail(object $notifiable): MailMessage\n    {\n        return (new MailMessage)->markdown('{{ view }}');\n    }\n\n    /**\n     * Get the array representation of the notification.\n     *\n     * @return array<string, mixed>\n     */\n    public function toArray(object $notifiable): array\n    {\n        return [\n            //\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/markdown.stub",
    "content": "<x-mail::message>\n# Introduction\n\nThe body of your message.\n\n<x-mail::button :url=\"''\">\nButton Text\n</x-mail::button>\n\nThanks,<br>\n{{ config('app.name') }}\n</x-mail::message>\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/model.morph-pivot.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\n\nclass {{ class }} extends MorphPivot\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/model.pivot.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\n\nclass {{ class }} extends Pivot\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/model.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\n{{ factoryImport }}\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass {{ class }} extends Model\n{\n    {{ factory }}\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/notification.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notification;\n\nclass {{ class }} extends Notification\n{\n    use Queueable;\n\n    /**\n     * Create a new notification instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the notification's delivery channels.\n     *\n     * @return array<int, string>\n     */\n    public function via(object $notifiable): array\n    {\n        return ['mail'];\n    }\n\n    /**\n     * Get the mail representation of the notification.\n     */\n    public function toMail(object $notifiable): MailMessage\n    {\n        return (new MailMessage)\n            ->line('The introduction to the notification.')\n            ->action('Notification Action', url('/'))\n            ->line('Thank you for using our application!');\n    }\n\n    /**\n     * Get the array representation of the notification.\n     *\n     * @return array<string, mixed>\n     */\n    public function toArray(object $notifiable): array\n    {\n        return [\n            //\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/observer.plain.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nclass {{ class }}\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/observer.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\n\nclass {{ class }}\n{\n    /**\n     * Handle the {{ model }} \"created\" event.\n     */\n    public function created({{ model }} ${{ modelVariable }}): void\n    {\n        //\n    }\n\n    /**\n     * Handle the {{ model }} \"updated\" event.\n     */\n    public function updated({{ model }} ${{ modelVariable }}): void\n    {\n        //\n    }\n\n    /**\n     * Handle the {{ model }} \"deleted\" event.\n     */\n    public function deleted({{ model }} ${{ modelVariable }}): void\n    {\n        //\n    }\n\n    /**\n     * Handle the {{ model }} \"restored\" event.\n     */\n    public function restored({{ model }} ${{ modelVariable }}): void\n    {\n        //\n    }\n\n    /**\n     * Handle the {{ model }} \"force deleted\" event.\n     */\n    public function forceDeleted({{ model }} ${{ modelVariable }}): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/pest.stub",
    "content": "<?php\n\ntest('example', function () {\n    $response = $this->get('/');\n\n    $response->assertStatus(200);\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/pest.unit.stub",
    "content": "<?php\n\ntest('example', function () {\n    expect(true)->toBeTrue();\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/policy.plain.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedUserModel }};\n\nclass {{ class }}\n{\n    /**\n     * Create a new policy instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/policy.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Auth\\Access\\Response;\nuse {{ namespacedModel }};\nuse {{ namespacedUserModel }};\n\nclass {{ class }}\n{\n    /**\n     * Determine whether the user can view any models.\n     */\n    public function viewAny({{ user }} $user): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can view the model.\n     */\n    public function view({{ user }} $user, {{ model }} ${{ modelVariable }}): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can create models.\n     */\n    public function create({{ user }} $user): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can update the model.\n     */\n    public function update({{ user }} $user, {{ model }} ${{ modelVariable }}): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can delete the model.\n     */\n    public function delete({{ user }} $user, {{ model }} ${{ modelVariable }}): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can restore the model.\n     */\n    public function restore({{ user }} $user, {{ model }} ${{ modelVariable }}): bool\n    {\n        return false;\n    }\n\n    /**\n     * Determine whether the user can permanently delete the model.\n     */\n    public function forceDelete({{ user }} $user, {{ model }} ${{ modelVariable }}): bool\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/provider.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Support\\ServiceProvider;\n\nclass {{ class }} extends ServiceProvider\n{\n    /**\n     * Register services.\n     */\n    public function register(): void\n    {\n        //\n    }\n\n    /**\n     * Bootstrap services.\n     */\n    public function boot(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/request.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Contracts\\Validation\\ValidationRule;\nuse Illuminate\\Foundation\\Http\\FormRequest;\n\nclass {{ class }} extends FormRequest\n{\n    /**\n     * Determine if the user is authorized to make this request.\n     */\n    public function authorize(): bool\n    {\n        return false;\n    }\n\n    /**\n     * Get the validation rules that apply to the request.\n     *\n     * @return array<string, ValidationRule|array<mixed>|string>\n     */\n    public function rules(): array\n    {\n        return [\n            //\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/resource-collection.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass {{ class }} extends ResourceCollection\n{\n    /**\n     * Transform the resource collection into an array.\n     *\n     * @return array<int|string, mixed>\n     */\n    public function toArray(Request $request): array\n    {\n        return parent::toArray($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/resource-json-api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass {{ class }} extends JsonApiResource\n{\n    /**\n     * The resource's attributes.\n     */\n    public $attributes = [\n        // ...\n    ];\n\n    /**\n     * The resource's relationships.\n     */\n    public $relationships = [\n        // ...\n    ];\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/resource.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass {{ class }} extends JsonResource\n{\n    /**\n     * Transform the resource into an array.\n     *\n     * @return array<string, mixed>\n     */\n    public function toArray(Request $request): array\n    {\n        return parent::toArray($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/routes.stub",
    "content": "<?php\n\napp('router')->setCompiledRoutes(\n    {{routes}}\n);\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/rule.implicit.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Closure;\nuse Illuminate\\Contracts\\Validation\\ValidationRule;\nuse Illuminate\\Translation\\PotentiallyTranslatedString;\n\nclass {{ class }} implements ValidationRule\n{\n    /**\n     * Indicates whether the rule should be implicit.\n     *\n     * @var bool\n     */\n    public $implicit = true;\n\n    /**\n     * Run the validation rule.\n     *\n     * @param  Closure(string, ?string=): PotentiallyTranslatedString  $fail\n     */\n    public function validate(string $attribute, mixed $value, Closure $fail): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/rule.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Closure;\nuse Illuminate\\Contracts\\Validation\\ValidationRule;\nuse Illuminate\\Translation\\PotentiallyTranslatedString;\n\nclass {{ class }} implements ValidationRule\n{\n    /**\n     * Run the validation rule.\n     *\n     * @param  Closure(string, ?string=): PotentiallyTranslatedString  $fail\n     */\n    public function validate(string $attribute, mixed $value, Closure $fail): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/scope.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Scope;\n\nclass {{ class }} implements Scope\n{\n    /**\n     * Apply the scope to a given Eloquent query builder.\n     */\n    public function apply(Builder $builder, Model $model): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/test.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Foundation\\Testing\\WithFaker;\nuse Tests\\TestCase;\n\nclass {{ class }} extends TestCase\n{\n    /**\n     * A basic feature test example.\n     */\n    public function test_example(): void\n    {\n        $response = $this->get('/');\n\n        $response->assertStatus(200);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/test.unit.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass {{ class }} extends TestCase\n{\n    /**\n     * A basic unit test example.\n     */\n    public function test_example(): void\n    {\n        $this->assertTrue(true);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/trait.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\ntrait {{ class }}\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/view-component.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Closure;\nuse Illuminate\\View\\Component;\nuse Illuminate\\Contracts\\View\\View;\n\nclass {{ class }} extends Component\n{\n    /**\n     * Create a new component instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the view / contents that represent the component.\n     */\n    public function render(): View|Closure|string\n    {\n        return {{ view }};\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/view-mail.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Attachment;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass {{ class }} extends Mailable\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new message instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n\n    /**\n     * Get the message envelope.\n     */\n    public function envelope(): Envelope\n    {\n        return new Envelope(\n            subject: '{{ subject }}',\n        );\n    }\n\n    /**\n     * Get the message content definition.\n     */\n    public function content(): Content\n    {\n        return new Content(\n            view: '{{ view }}',\n        );\n    }\n\n    /**\n     * Get the attachments for the message.\n     *\n     * @return array<int, Attachment>\n     */\n    public function attachments(): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/view.pest.stub",
    "content": "<?php\n\nit('can render', function () {\n    $contents = $this->view('{{ name }}', [\n        //\n    ]);\n\n    $contents->assertSee('');\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/view.stub",
    "content": "<div>\n    <!-- {{ quote }} -->\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/Console/stubs/view.test.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Tests\\TestCase;\n\nclass {{ class }} extends TestCase\n{\n    /**\n     * A basic view test example.\n     */\n    public function test_it_can_render(): void\n    {\n        $contents = $this->view('{{ name }}', [\n            //\n        ]);\n\n        $contents->assertSee('');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/EnvironmentDetector.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Closure;\n\nclass EnvironmentDetector\n{\n    /**\n     * Detect the application's current environment.\n     *\n     * @param  \\Closure  $callback\n     * @param  array|null  $consoleArgs\n     * @return string\n     */\n    public function detect(Closure $callback, $consoleArgs = null)\n    {\n        if ($consoleArgs) {\n            return $this->detectConsoleEnvironment($callback, $consoleArgs);\n        }\n\n        return $this->detectWebEnvironment($callback);\n    }\n\n    /**\n     * Set the application environment for a web request.\n     *\n     * @param  \\Closure  $callback\n     * @return string\n     */\n    protected function detectWebEnvironment(Closure $callback)\n    {\n        return $callback();\n    }\n\n    /**\n     * Set the application environment from command-line arguments.\n     *\n     * @param  \\Closure  $callback\n     * @param  array  $args\n     * @return string\n     */\n    protected function detectConsoleEnvironment(Closure $callback, array $args)\n    {\n        // First we will check if an environment argument was passed via console arguments\n        // and if it was that automatically overrides as the environment. Otherwise, we\n        // will check the environment as a \"web\" request like a typical HTTP request.\n        if (! is_null($value = $this->getEnvironmentArgument($args))) {\n            return $value;\n        }\n\n        return $this->detectWebEnvironment($callback);\n    }\n\n    /**\n     * Get the environment argument from the console.\n     *\n     * @param  array  $args\n     * @return string|null\n     */\n    protected function getEnvironmentArgument(array $args)\n    {\n        foreach ($args as $i => $value) {\n            if ($value === '--env') {\n                return $args[$i + 1] ?? null;\n            }\n\n            if (str_starts_with($value, '--env=')) {\n                return head(array_slice(explode('=', $value), 1));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/DiagnosingHealth.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass DiagnosingHealth\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/DiscoverEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Str;\nuse ReflectionClass;\nuse ReflectionException;\nuse ReflectionMethod;\nuse SplFileInfo;\nuse Symfony\\Component\\Finder\\Finder;\n\nclass DiscoverEvents\n{\n    /**\n     * The callback to be used to guess class names.\n     *\n     * @var (callable(SplFileInfo, string): class-string)|null\n     */\n    public static $guessClassNamesUsingCallback;\n\n    /**\n     * Get all of the events and listeners by searching the given listener directory.\n     *\n     * @param  array<int, string>|string  $listenerPath\n     * @param  string  $basePath\n     * @return array\n     */\n    public static function within($listenerPath, $basePath)\n    {\n        if (Arr::wrap($listenerPath) === []) {\n            return [];\n        }\n\n        $listeners = new Collection(static::getListenerEvents(\n            Finder::create()->files()->in($listenerPath), $basePath\n        ));\n\n        $discoveredEvents = [];\n\n        foreach ($listeners as $listener => $events) {\n            foreach ($events as $event) {\n                if (! isset($discoveredEvents[$event])) {\n                    $discoveredEvents[$event] = [];\n                }\n\n                $discoveredEvents[$event][] = $listener;\n            }\n        }\n\n        return $discoveredEvents;\n    }\n\n    /**\n     * Get all of the listeners and their corresponding events.\n     *\n     * @param  iterable<string, SplFileInfo>  $listeners\n     * @param  string  $basePath\n     * @return array\n     */\n    protected static function getListenerEvents($listeners, $basePath)\n    {\n        $listenerEvents = [];\n\n        foreach ($listeners as $listener) {\n            try {\n                $listener = new ReflectionClass(\n                    static::classFromFile($listener, $basePath)\n                );\n            } catch (ReflectionException) {\n                continue;\n            }\n\n            if (! $listener->isInstantiable()) {\n                continue;\n            }\n\n            foreach ($listener->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {\n                if ((! Str::is('handle*', $method->name) && ! Str::is('__invoke', $method->name)) ||\n                    ! isset($method->getParameters()[0])) {\n                    continue;\n                }\n\n                $listenerEvents[$listener->name.'@'.$method->name] =\n                                Reflector::getParameterClassNames($method->getParameters()[0]);\n            }\n        }\n\n        return array_filter($listenerEvents);\n    }\n\n    /**\n     * Extract the class name from the given file path.\n     *\n     * @param  \\SplFileInfo  $file\n     * @param  string  $basePath\n     * @return class-string\n     */\n    protected static function classFromFile(SplFileInfo $file, $basePath)\n    {\n        if (static::$guessClassNamesUsingCallback) {\n            return call_user_func(static::$guessClassNamesUsingCallback, $file, $basePath);\n        }\n\n        $class = trim(Str::replaceFirst($basePath, '', $file->getRealPath()), DIRECTORY_SEPARATOR);\n\n        return ucfirst(Str::camel(str_replace(\n            [DIRECTORY_SEPARATOR, ucfirst(basename(app()->path())).'\\\\'],\n            ['\\\\', app()->getNamespace()],\n            ucfirst(Str::replaceLast('.php', '', $class))\n        )));\n    }\n\n    /**\n     * Specify a callback to be used to guess class names.\n     *\n     * @param  callable(SplFileInfo, string): class-string  $callback\n     * @return void\n     */\n    public static function guessClassNamesUsing(callable $callback)\n    {\n        static::$guessClassNamesUsingCallback = $callback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/Dispatchable.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\ntrait Dispatchable\n{\n    /**\n     * Dispatch the event with the given arguments.\n     *\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public static function dispatch(...$arguments)\n    {\n        return event(new static(...$arguments));\n    }\n\n    /**\n     * Dispatch the event with the given arguments if the given truth test passes.\n     *\n     * @param  bool  $boolean\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public static function dispatchIf($boolean, ...$arguments)\n    {\n        if ($boolean) {\n            return event(new static(...$arguments));\n        }\n    }\n\n    /**\n     * Dispatch the event with the given arguments unless the given truth test passes.\n     *\n     * @param  bool  $boolean\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public static function dispatchUnless($boolean, ...$arguments)\n    {\n        if (! $boolean) {\n            return event(new static(...$arguments));\n        }\n    }\n\n    /**\n     * Broadcast the event with the given arguments.\n     *\n     * @param  mixed  ...$arguments\n     * @return \\Illuminate\\Broadcasting\\PendingBroadcast\n     */\n    public static function broadcast(...$arguments)\n    {\n        return broadcast(new static(...$arguments));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/LocaleUpdated.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass LocaleUpdated\n{\n    /**\n     * The new locale.\n     *\n     * @var string\n     */\n    public $locale;\n\n    /**\n     * The previous locale.\n     *\n     * @var ?string\n     */\n    public $previousLocale;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $locale\n     * @param  ?string  $previousLocale\n     */\n    public function __construct($locale, $previousLocale = null)\n    {\n        $this->locale = $locale;\n\n        $this->previousLocale = $previousLocale;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/MaintenanceModeDisabled.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass MaintenanceModeDisabled\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/MaintenanceModeEnabled.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass MaintenanceModeEnabled\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/PublishingStubs.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass PublishingStubs\n{\n    use Dispatchable;\n\n    /**\n     * The stubs being published.\n     *\n     * @var array\n     */\n    public $stubs = [];\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  array  $stubs\n     */\n    public function __construct(array $stubs)\n    {\n        $this->stubs = $stubs;\n    }\n\n    /**\n     * Add a new stub to be published.\n     *\n     * @param  string  $path\n     * @param  string  $name\n     * @return $this\n     */\n    public function add(string $path, string $name)\n    {\n        $this->stubs[$path] = $name;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/Terminating.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass Terminating\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Events/VendorTagPublished.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Events;\n\nclass VendorTagPublished\n{\n    /**\n     * The vendor tag that was published.\n     *\n     * @var string\n     */\n    public $tag;\n\n    /**\n     * The publishable paths registered by the tag.\n     *\n     * @var array\n     */\n    public $paths;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $tag\n     * @param  array  $paths\n     */\n    public function __construct($tag, $paths)\n    {\n        $this->tag = $tag;\n        $this->paths = $paths;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Handler.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Cache\\RateLimiting\\Unlimited;\nuse Illuminate\\Console\\View\\Components\\BulletList;\nuse Illuminate\\Console\\View\\Components\\Error;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler as ExceptionHandlerContract;\nuse Illuminate\\Contracts\\Debug\\ShouldntReport;\nuse Illuminate\\Contracts\\Foundation\\ExceptionRenderer;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\MultipleRecordsFoundException;\nuse Illuminate\\Database\\RecordNotFoundException;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\Exceptions\\OriginMismatchException;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Session\\TokenMismatchException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Lottery;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LogLevel;\nuse Symfony\\Component\\Console\\Application as ConsoleApplication;\nuse Symfony\\Component\\Console\\Exception\\CommandNotFoundException;\nuse Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer;\nuse Symfony\\Component\\HttpFoundation\\Exception\\RequestExceptionInterface;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse as SymfonyRedirectResponse;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Throwable;\nuse WeakMap;\n\nclass Handler implements ExceptionHandlerContract\n{\n    use ReflectsClosures;\n\n    /**\n     * The container implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * A list of the exception types that are not reported.\n     *\n     * @var array<int, class-string<\\Throwable>>\n     */\n    protected $dontReport = [];\n\n    /**\n     * The callbacks that inspect exceptions to determine if they should be reported.\n     *\n     * @var array\n     */\n    protected $dontReportCallbacks = [];\n\n    /**\n     * The callbacks that should be used during reporting.\n     *\n     * @var \\Illuminate\\Foundation\\Exceptions\\ReportableHandler[]\n     */\n    protected $reportCallbacks = [];\n\n    /**\n     * A map of exceptions with their corresponding custom log levels.\n     *\n     * @var array<class-string<\\Throwable>, \\Psr\\Log\\LogLevel::*>\n     */\n    protected $levels = [];\n\n    /**\n     * The callbacks that should be used to throttle reportable exceptions.\n     *\n     * @var array\n     */\n    protected $throttleCallbacks = [];\n\n    /**\n     * The callbacks that should be used to build exception context data.\n     *\n     * @var array\n     */\n    protected $contextCallbacks = [];\n\n    /**\n     * The callbacks that should be used during rendering.\n     *\n     * @var \\Closure[]\n     */\n    protected $renderCallbacks = [];\n\n    /**\n     * The callback that determines if the exception handler response should be JSON.\n     *\n     * @var callable|null\n     */\n    protected $shouldRenderJsonWhenCallback;\n\n    /**\n     * The callback that prepares responses to be returned to the browser.\n     *\n     * @var callable|null\n     */\n    protected $finalizeResponseCallback;\n\n    /**\n     * The registered exception mappings.\n     *\n     * @var array<string, \\Closure>\n     */\n    protected $exceptionMap = [];\n\n    /**\n     * Indicates that throttled keys should be hashed.\n     *\n     * @var bool\n     */\n    protected $hashThrottleKeys = true;\n\n    /**\n     * A list of the internal exception types that should not be reported.\n     *\n     * @var array<int, class-string<\\Throwable>>\n     */\n    protected $internalDontReport = [\n        AuthenticationException::class,\n        AuthorizationException::class,\n        BackedEnumCaseNotFoundException::class,\n        HttpException::class,\n        HttpResponseException::class,\n        ModelNotFoundException::class,\n        MultipleRecordsFoundException::class,\n        OriginMismatchException::class,\n        RecordNotFoundException::class,\n        RecordsNotFoundException::class,\n        RequestExceptionInterface::class,\n        TokenMismatchException::class,\n        ValidationException::class,\n    ];\n\n    /**\n     * A list of the inputs that are never flashed for validation exceptions.\n     *\n     * @var array<int, string>\n     */\n    protected $dontFlash = [\n        'current_password',\n        'password',\n        'password_confirmation',\n    ];\n\n    /**\n     * Indicates that an exception instance should only be reported once.\n     *\n     * @var bool\n     */\n    protected $withoutDuplicates = false;\n\n    /**\n     * The already reported exception map.\n     *\n     * @var \\WeakMap\n     */\n    protected $reportedExceptionMap;\n\n    /**\n     * Create a new exception handler instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n\n        $this->reportedExceptionMap = new WeakMap;\n\n        $this->register();\n    }\n\n    /**\n     * Register the exception handling callbacks for the application.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        //\n    }\n\n    /**\n     * Register a reportable callback.\n     *\n     * @param  callable  $reportUsing\n     * @return \\Illuminate\\Foundation\\Exceptions\\ReportableHandler\n     */\n    public function reportable(callable $reportUsing)\n    {\n        if (! $reportUsing instanceof Closure) {\n            $reportUsing = Closure::fromCallable($reportUsing);\n        }\n\n        return tap(new ReportableHandler($reportUsing), function ($callback) {\n            $this->reportCallbacks[] = $callback;\n        });\n    }\n\n    /**\n     * Register a renderable callback.\n     *\n     * @param  callable  $renderUsing\n     * @return $this\n     */\n    public function renderable(callable $renderUsing)\n    {\n        if (! $renderUsing instanceof Closure) {\n            $renderUsing = Closure::fromCallable($renderUsing);\n        }\n\n        $this->renderCallbacks[] = $renderUsing;\n\n        return $this;\n    }\n\n    /**\n     * Register a new exception mapping.\n     *\n     * @param  \\Closure|string  $from\n     * @param  \\Closure|string|null  $to\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function map($from, $to = null)\n    {\n        if (is_string($to)) {\n            $to = fn ($exception) => new $to('', 0, $exception);\n        }\n\n        if (is_callable($from) && is_null($to)) {\n            $from = $this->firstClosureParameterType($to = $from);\n        }\n\n        if (! is_string($from) || ! $to instanceof Closure) {\n            throw new InvalidArgumentException('Invalid exception mapping.');\n        }\n\n        $this->exceptionMap[$from] = $to;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given exception type should not be reported.\n     *\n     * Alias of \"ignore\".\n     *\n     * @param  array|string  $exceptions\n     * @return $this\n     */\n    public function dontReport(array|string $exceptions)\n    {\n        return $this->ignore($exceptions);\n    }\n\n    /**\n     * Register a callback to determine if an exception should not be reported.\n     *\n     * @param  (callable(\\Throwable): bool)  $dontReportWhen\n     * @return $this\n     */\n    public function dontReportWhen(callable $dontReportWhen)\n    {\n        if (! $dontReportWhen instanceof Closure) {\n            $dontReportWhen = Closure::fromCallable($dontReportWhen);\n        }\n\n        $this->dontReportCallbacks[] = $dontReportWhen;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given exception type should not be reported.\n     *\n     * @param  array|string  $exceptions\n     * @return $this\n     */\n    public function ignore(array|string $exceptions)\n    {\n        $exceptions = Arr::wrap($exceptions);\n\n        $this->dontReport = array_values(array_unique(array_merge($this->dontReport, $exceptions)));\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the given attributes should never be flashed to the session on validation errors.\n     *\n     * @param  array|string  $attributes\n     * @return $this\n     */\n    public function dontFlash(array|string $attributes)\n    {\n        $this->dontFlash = array_values(array_unique(\n            array_merge($this->dontFlash, Arr::wrap($attributes))\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Set the log level for the given exception type.\n     *\n     * @param  class-string<\\Throwable>  $type\n     * @param  \\Psr\\Log\\LogLevel::*  $level\n     * @return $this\n     */\n    public function level($type, $level)\n    {\n        $this->levels[$type] = $level;\n\n        return $this;\n    }\n\n    /**\n     * Report or log an exception.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function report(Throwable $e)\n    {\n        $e = $this->mapException($e);\n\n        if ($this->shouldntReport($e)) {\n            return;\n        }\n\n        $this->reportThrowable($e);\n    }\n\n    /**\n     * Reports error based on report method on exception or to logger.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function reportThrowable(Throwable $e): void\n    {\n        $this->reportedExceptionMap[$e] = true;\n\n        if (Reflector::isCallable($reportCallable = [$e, 'report']) &&\n            $this->container->call($reportCallable) !== false) {\n            return;\n        }\n\n        foreach ($this->reportCallbacks as $reportCallback) {\n            if ($reportCallback->handles($e) && $reportCallback($e) === false) {\n                return;\n            }\n        }\n\n        try {\n            $logger = $this->newLogger();\n        } catch (Exception) {\n            throw $e;\n        }\n\n        $level = $this->mapLogLevel($e);\n\n        $context = $this->buildExceptionContext($e);\n\n        method_exists($logger, $level)\n            ? $logger->{$level}($e->getMessage(), $context)\n            : $logger->log($level, $e->getMessage(), $context);\n    }\n\n    /**\n     * Determine if the exception should be reported.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function shouldReport(Throwable $e)\n    {\n        return ! $this->shouldntReport($e);\n    }\n\n    /**\n     * Determine if the exception is in the \"do not report\" list.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function shouldntReport(Throwable $e)\n    {\n        if ($this->withoutDuplicates && ($this->reportedExceptionMap[$e] ?? false)) {\n            return true;\n        }\n\n        if ($e instanceof ShouldntReport) {\n            return true;\n        }\n\n        $dontReport = array_merge($this->dontReport, $this->internalDontReport);\n\n        if (! is_null(Arr::first($dontReport, fn ($type) => $e instanceof $type))) {\n            return true;\n        }\n\n        foreach ($this->dontReportCallbacks as $dontReportCallback) {\n            if ($dontReportCallback($e) === true) {\n                return true;\n            }\n        }\n\n        return rescue(fn () => with($this->throttle($e), function ($throttle) use ($e) {\n            if ($throttle instanceof Unlimited || $throttle === null) {\n                return false;\n            }\n\n            if ($throttle instanceof Lottery) {\n                return ! $throttle($e);\n            }\n\n            return ! $this->container->make(RateLimiter::class)->attempt(\n                with($throttle->key ?: 'illuminate:foundation:exceptions:'.$e::class, fn ($key) => $this->hashThrottleKeys ? hash('xxh128', $key) : $key),\n                $throttle->maxAttempts,\n                fn () => true,\n                $throttle->decaySeconds\n            );\n        }), rescue: false, report: false);\n    }\n\n    /**\n     * Throttle the given exception.\n     *\n     * @param  \\Throwable  $e\n     * @return \\Illuminate\\Support\\Lottery|\\Illuminate\\Cache\\RateLimiting\\Limit|null\n     */\n    protected function throttle(Throwable $e)\n    {\n        foreach ($this->throttleCallbacks as $throttleCallback) {\n            foreach ($this->firstClosureParameterTypes($throttleCallback) as $type) {\n                if (is_a($e, $type)) {\n                    $response = $throttleCallback($e);\n\n                    if (! is_null($response)) {\n                        return $response;\n                    }\n                }\n            }\n        }\n\n        return Limit::none();\n    }\n\n    /**\n     * Specify the callback that should be used to throttle reportable exceptions.\n     *\n     * @param  callable  $throttleUsing\n     * @return $this\n     */\n    public function throttleUsing(callable $throttleUsing)\n    {\n        if (! $throttleUsing instanceof Closure) {\n            $throttleUsing = Closure::fromCallable($throttleUsing);\n        }\n\n        $this->throttleCallbacks[] = $throttleUsing;\n\n        return $this;\n    }\n\n    /**\n     * Remove the given exception class from the list of exceptions that should be ignored.\n     *\n     * @param  array|string  $exceptions\n     * @return $this\n     */\n    public function stopIgnoring(array|string $exceptions)\n    {\n        $exceptions = Arr::wrap($exceptions);\n\n        $this->dontReport = (new Collection($this->dontReport))\n            ->reject(fn ($ignored) => in_array($ignored, $exceptions))\n            ->values()\n            ->all();\n\n        $this->internalDontReport = (new Collection($this->internalDontReport))\n            ->reject(fn ($ignored) => in_array($ignored, $exceptions))\n            ->values()\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Create the context array for logging the given exception.\n     *\n     * @param  \\Throwable  $e\n     * @return array\n     */\n    protected function buildExceptionContext(Throwable $e)\n    {\n        return array_merge(\n            $this->exceptionContext($e),\n            $this->context(),\n            ['exception' => $e]\n        );\n    }\n\n    /**\n     * Get the default exception context variables for logging.\n     *\n     * @param  \\Throwable  $e\n     * @return array\n     */\n    protected function exceptionContext(Throwable $e)\n    {\n        $context = [];\n\n        if (method_exists($e, 'context')) {\n            $context = $e->context();\n        }\n\n        foreach ($this->contextCallbacks as $callback) {\n            $context = array_merge($context, $callback($e, $context));\n        }\n\n        return $context;\n    }\n\n    /**\n     * Get the default context variables for logging.\n     *\n     * @return array\n     */\n    protected function context()\n    {\n        try {\n            return array_filter([\n                'userId' => Auth::id(),\n            ]);\n        } catch (Throwable) {\n            return [];\n        }\n    }\n\n    /**\n     * Register a closure that should be used to build exception context data.\n     *\n     * @param  \\Closure  $contextCallback\n     * @return $this\n     */\n    public function buildContextUsing(Closure $contextCallback)\n    {\n        $this->contextCallbacks[] = $contextCallback;\n\n        return $this;\n    }\n\n    /**\n     * Render an exception into an HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Throwable\n     */\n    public function render($request, Throwable $e)\n    {\n        $e = $this->mapException($e);\n\n        if (method_exists($e, 'render') && $response = $e->render($request)) {\n            return $this->finalizeRenderedResponse(\n                $request,\n                Router::toResponse($request, $response),\n                $e\n            );\n        }\n\n        if ($e instanceof Responsable) {\n            return $this->finalizeRenderedResponse($request, $e->toResponse($request), $e);\n        }\n\n        $e = $this->prepareException($e);\n\n        if ($response = $this->renderViaCallbacks($request, $e)) {\n            return $this->finalizeRenderedResponse($request, $response, $e);\n        }\n\n        return $this->finalizeRenderedResponse($request, match (true) {\n            $e instanceof HttpResponseException => $e->getResponse(),\n            $e instanceof AuthenticationException => $this->unauthenticated($request, $e),\n            $e instanceof ValidationException => $this->convertValidationExceptionToResponse($e, $request),\n            default => $this->renderExceptionResponse($request, $e),\n        }, $e);\n    }\n\n    /**\n     * Prepare the final, rendered response to be returned to the browser.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function finalizeRenderedResponse($request, $response, Throwable $e)\n    {\n        return $this->finalizeResponseCallback\n            ? call_user_func($this->finalizeResponseCallback, $response, $e, $request)\n            : $response;\n    }\n\n    /**\n     * Prepare the final, rendered response for an exception using the given callback.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function respondUsing($callback)\n    {\n        $this->finalizeResponseCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Prepare exception for rendering.\n     *\n     * @param  \\Throwable  $e\n     * @return \\Throwable\n     */\n    protected function prepareException(Throwable $e)\n    {\n        return match (true) {\n            $e instanceof BackedEnumCaseNotFoundException => new NotFoundHttpException($e->getMessage(), $e),\n            $e instanceof ModelNotFoundException => new NotFoundHttpException($e->getMessage(), $e),\n            $e instanceof AuthorizationException && $e->hasStatus() => new HttpException(\n                $e->status(), $e->response()?->message() ?: (Response::$statusTexts[$e->status()] ?? 'Whoops, looks like something went wrong.'), $e\n            ),\n            $e instanceof AuthorizationException && ! $e->hasStatus() => new AccessDeniedHttpException($e->getMessage(), $e),\n            $e instanceof OriginMismatchException => new HttpException(403, $e->getMessage(), $e),\n            $e instanceof TokenMismatchException => new HttpException(419, $e->getMessage(), $e),\n            $e instanceof RequestExceptionInterface => new BadRequestHttpException('Bad request.', $e),\n            $e instanceof RecordNotFoundException => new NotFoundHttpException('Not found.', $e),\n            $e instanceof RecordsNotFoundException => new NotFoundHttpException('Not found.', $e),\n            default => $e,\n        };\n    }\n\n    /**\n     * Map the exception using a registered mapper if possible.\n     *\n     * @param  \\Throwable  $e\n     * @return \\Throwable\n     */\n    protected function mapException(Throwable $e)\n    {\n        if (method_exists($e, 'getInnerException') &&\n            ($inner = $e->getInnerException()) instanceof Throwable) {\n            return $inner;\n        }\n\n        foreach ($this->exceptionMap as $class => $mapper) {\n            if (is_a($e, $class)) {\n                return $mapper($e);\n            }\n        }\n\n        return $e;\n    }\n\n    /**\n     * Try to render a response from request and exception via render callbacks.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return mixed\n     *\n     * @throws \\ReflectionException\n     */\n    protected function renderViaCallbacks($request, Throwable $e)\n    {\n        foreach ($this->renderCallbacks as $renderCallback) {\n            foreach ($this->firstClosureParameterTypes($renderCallback) as $type) {\n                if (is_a($e, $type)) {\n                    $response = $renderCallback($e, $request);\n\n                    if (! is_null($response)) {\n                        return $response;\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Render a default exception response if any.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\JsonResponse|\\Illuminate\\Http\\RedirectResponse\n     */\n    protected function renderExceptionResponse($request, Throwable $e)\n    {\n        return $this->shouldReturnJson($request, $e)\n            ? $this->prepareJsonResponse($request, $e)\n            : $this->prepareResponse($request, $e);\n    }\n\n    /**\n     * Convert an authentication exception into a response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Auth\\AuthenticationException  $exception\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\JsonResponse|\\Illuminate\\Http\\RedirectResponse\n     */\n    protected function unauthenticated($request, AuthenticationException $exception)\n    {\n        return $this->shouldReturnJson($request, $exception)\n            ? response()->json(['message' => $exception->getMessage()], 401)\n            : redirect()->guest($exception->redirectTo($request) ?? route('login'));\n    }\n\n    /**\n     * Create a response object from the given validation exception.\n     *\n     * @param  \\Illuminate\\Validation\\ValidationException  $e\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function convertValidationExceptionToResponse(ValidationException $e, $request)\n    {\n        if ($e->response) {\n            return $e->response;\n        }\n\n        return $this->shouldReturnJson($request, $e)\n            ? $this->invalidJson($request, $e)\n            : $this->invalid($request, $e);\n    }\n\n    /**\n     * Convert a validation exception into a response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Validation\\ValidationException  $exception\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\JsonResponse|\\Illuminate\\Http\\RedirectResponse\n     */\n    protected function invalid($request, ValidationException $exception)\n    {\n        return redirect($exception->redirectTo ?? url()->previous())\n            ->withInput(Arr::except($request->input(), $this->dontFlash))\n            ->withErrors($exception->errors(), $request->input('_error_bag', $exception->errorBag));\n    }\n\n    /**\n     * Convert a validation exception into a JSON response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Validation\\ValidationException  $exception\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    protected function invalidJson($request, ValidationException $exception)\n    {\n        return response()->json([\n            'message' => $exception->getMessage(),\n            'errors' => $exception->errors(),\n        ], $exception->status);\n    }\n\n    /**\n     * Determine if the exception handler response should be JSON.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function shouldReturnJson($request, Throwable $e)\n    {\n        return $this->shouldRenderJsonWhenCallback\n            ? call_user_func($this->shouldRenderJsonWhenCallback, $request, $e)\n            : $request->expectsJson();\n    }\n\n    /**\n     * Register the callable that determines if the exception handler response should be JSON.\n     *\n     * @param  callable(\\Illuminate\\Http\\Request $request, \\Throwable): bool  $callback\n     * @return $this\n     */\n    public function shouldRenderJsonWhen($callback)\n    {\n        $this->shouldRenderJsonWhenCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Prepare a response for the given exception.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\JsonResponse|\\Illuminate\\Http\\RedirectResponse\n     */\n    protected function prepareResponse($request, Throwable $e)\n    {\n        if (! $this->isHttpException($e) && config('app.debug')) {\n            return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e)->prepare($request);\n        }\n\n        if (! $this->isHttpException($e)) {\n            $e = new HttpException(500, $e->getMessage(), $e);\n        }\n\n        return $this->toIlluminateResponse(\n            $this->renderHttpException($e), $e\n        )->prepare($request);\n    }\n\n    /**\n     * Create a Symfony response for the given exception.\n     *\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function convertExceptionToResponse(Throwable $e)\n    {\n        return new SymfonyResponse(\n            $this->renderExceptionContent($e),\n            $this->isHttpException($e) ? $e->getStatusCode() : 500,\n            $this->isHttpException($e) ? $e->getHeaders() : []\n        );\n    }\n\n    /**\n     * Get the response content for the given exception.\n     *\n     * @param  \\Throwable  $e\n     * @return string\n     */\n    protected function renderExceptionContent(Throwable $e)\n    {\n        try {\n            if (config('app.debug')) {\n                if (app()->has(ExceptionRenderer::class)) {\n                    return $this->renderExceptionWithCustomRenderer($e);\n                } elseif ($this->container->bound(Renderer::class)) {\n                    return $this->container->make(Renderer::class)->render(request(), $e);\n                }\n            }\n\n            return $this->renderExceptionWithSymfony($e, config('app.debug'));\n        } catch (Throwable $e) {\n            return $this->renderExceptionWithSymfony($e, config('app.debug'));\n        }\n    }\n\n    /**\n     * Render an exception to a string using the registered `ExceptionRenderer`.\n     *\n     * @param  \\Throwable  $e\n     * @return string\n     */\n    protected function renderExceptionWithCustomRenderer(Throwable $e)\n    {\n        return app(ExceptionRenderer::class)->render($e);\n    }\n\n    /**\n     * Render an exception to a string using Symfony.\n     *\n     * @param  \\Throwable  $e\n     * @param  bool  $debug\n     * @return string\n     */\n    protected function renderExceptionWithSymfony(Throwable $e, $debug)\n    {\n        $renderer = new HtmlErrorRenderer($debug);\n\n        return $renderer->render($e)->getAsString();\n    }\n\n    /**\n     * Render the given HttpException.\n     *\n     * @param  \\Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Throwable\n     */\n    protected function renderHttpException(HttpExceptionInterface $e)\n    {\n        $this->registerErrorViewPaths();\n\n        if ($view = $this->getHttpExceptionView($e)) {\n            try {\n                return response()->view($view, [\n                    'errors' => new ViewErrorBag,\n                    'exception' => $e,\n                ], $e->getStatusCode(), $e->getHeaders());\n            } catch (Throwable $t) {\n                config('app.debug') && throw $t;\n\n                $this->report($t);\n            }\n        }\n\n        return $this->convertExceptionToResponse($e);\n    }\n\n    /**\n     * Register the error template hint paths.\n     *\n     * @return void\n     */\n    protected function registerErrorViewPaths()\n    {\n        (new RegisterErrorViewPaths)();\n    }\n\n    /**\n     * Get the view used to render HTTP exceptions.\n     *\n     * @param  \\Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface  $e\n     * @return string|null\n     */\n    protected function getHttpExceptionView(HttpExceptionInterface $e)\n    {\n        $view = 'errors::'.$e->getStatusCode();\n\n        if (view()->exists($view)) {\n            return $view;\n        }\n\n        $view = substr($view, 0, -2).'xx';\n\n        if (view()->exists($view)) {\n            return $view;\n        }\n\n        return null;\n    }\n\n    /**\n     * Map the given exception into an Illuminate response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @param  \\Throwable  $e\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Http\\RedirectResponse\n     */\n    protected function toIlluminateResponse($response, Throwable $e)\n    {\n        if ($response instanceof SymfonyRedirectResponse) {\n            $response = new RedirectResponse(\n                $response->getTargetUrl(), $response->getStatusCode(), $response->headers->all()\n            );\n        } else {\n            $response = response(\n                $response->getContent(), $response->getStatusCode(), $response->headers->all()\n            );\n        }\n\n        return $response->withException($e);\n    }\n\n    /**\n     * Prepare a JSON response for the given exception.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    protected function prepareJsonResponse($request, Throwable $e)\n    {\n        return response()->json(\n            $this->convertExceptionToArray($e),\n            $this->isHttpException($e) ? $e->getStatusCode() : 500,\n            $this->isHttpException($e) ? $e->getHeaders() : [],\n            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES\n        );\n    }\n\n    /**\n     * Convert the given exception to an array.\n     *\n     * @param  \\Throwable  $e\n     * @return array\n     */\n    protected function convertExceptionToArray(Throwable $e)\n    {\n        return config('app.debug') ? [\n            'message' => $e->getMessage(),\n            'exception' => get_class($e),\n            'file' => $e->getFile(),\n            'line' => $e->getLine(),\n            'trace' => (new Collection($e->getTrace()))->map(fn ($trace) => Arr::except($trace, ['args']))->all(),\n        ] : [\n            'message' => $this->isHttpException($e) ? $e->getMessage() : 'Server Error',\n        ];\n    }\n\n    /**\n     * Render an exception to the console.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @internal This method is not meant to be used or overwritten outside the framework.\n     */\n    public function renderForConsole($output, Throwable $e)\n    {\n        if ($e instanceof CommandNotFoundException) {\n            $message = Str::of($e->getMessage())->explode('.')->first();\n\n            if (! empty($alternatives = $e->getAlternatives())) {\n                $message .= '. Did you mean one of these?';\n\n                (new Error($output))->render($message);\n                (new BulletList($output))->render($alternatives);\n\n                $output->writeln('');\n            } else {\n                (new Error($output))->render($message);\n            }\n\n            return;\n        }\n\n        (new ConsoleApplication)->renderThrowable($e, $output);\n    }\n\n    /**\n     * Do not report duplicate exceptions.\n     *\n     * @return $this\n     */\n    public function dontReportDuplicates()\n    {\n        $this->withoutDuplicates = true;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given exception is an HTTP exception.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function isHttpException(Throwable $e)\n    {\n        return $e instanceof HttpExceptionInterface;\n    }\n\n    /**\n     * Map the exception to a log level.\n     *\n     * @param  \\Throwable  $e\n     * @return \\Psr\\Log\\LogLevel::*\n     */\n    protected function mapLogLevel(Throwable $e)\n    {\n        return Arr::first(\n            $this->levels, fn ($level, $type) => $e instanceof $type, LogLevel::ERROR\n        );\n    }\n\n    /**\n     * Create a new logger instance.\n     *\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function newLogger()\n    {\n        return $this->container->make(LoggerInterface::class);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/RegisterErrorViewPaths.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\View;\n\nclass RegisterErrorViewPaths\n{\n    /**\n     * Register the error view paths.\n     *\n     * @return void\n     */\n    public function __invoke()\n    {\n        View::replaceNamespace('errors', (new Collection(config('view.paths')))\n            ->map(fn ($path) => \"{$path}/errors\")\n            ->push(__DIR__.'/views')\n            ->all()\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Renderer/Exception.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Renderer;\n\nuse Closure;\nuse Composer\\Autoload\\ClassLoader;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Bootstrap\\HandleExceptions;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\ErrorHandler\\Exception\\FlattenException;\n\nclass Exception\n{\n    /**\n     * The \"flattened\" exception instance.\n     *\n     * @var \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException\n     */\n    protected $exception;\n\n    /**\n     * The current request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * The exception listener instance.\n     *\n     * @var \\Illuminate\\Foundation\\Exceptions\\Renderer\\Listener\n     */\n    protected $listener;\n\n    /**\n     * The application's base path.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * Creates a new exception renderer instance.\n     *\n     * @param  \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException  $exception\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Foundation\\Exceptions\\Renderer\\Listener  $listener\n     * @param  string  $basePath\n     */\n    public function __construct(FlattenException $exception, Request $request, Listener $listener, string $basePath)\n    {\n        $this->exception = $exception;\n        $this->request = $request;\n        $this->listener = $listener;\n        $this->basePath = $basePath;\n    }\n\n    /**\n     * Get the exception title.\n     *\n     * @return string\n     */\n    public function title()\n    {\n        return $this->exception->getStatusText();\n    }\n\n    /**\n     * Get the exception message.\n     *\n     * @return string\n     */\n    public function message()\n    {\n        return $this->exception->getMessage();\n    }\n\n    /**\n     * Get the exception class name.\n     *\n     * @return string\n     */\n    public function class()\n    {\n        return $this->exception->getClass();\n    }\n\n    /**\n     * Get the exception code.\n     *\n     * @return int|string\n     */\n    public function code()\n    {\n        return $this->exception->getCode();\n    }\n\n    /**\n     * Get the HTTP status code.\n     *\n     * @return int\n     */\n    public function httpStatusCode()\n    {\n        return $this->exception->getStatusCode();\n    }\n\n    /**\n     * Get the previous exceptions in the chain.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, static>\n     */\n    public function previousExceptions()\n    {\n        return once(fn () => (new Collection($this->exception->getAllPrevious()))->map(\n            fn ($previous) => new static($previous, $this->request, $this->listener, $this->basePath),\n        ));\n    }\n\n    /**\n     * Get the exception's frames.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, Frame>\n     */\n    public function frames()\n    {\n        return once(function () {\n            $classMap = array_map(function ($path) {\n                return (string) realpath($path);\n            }, array_values(ClassLoader::getRegisteredLoaders())[0]->getClassMap());\n\n            $trace = $this->exception->getTrace();\n\n            if (count($trace) > 1 && empty($trace[0]['class']) && empty($trace[0]['function'])) {\n                $trace[0]['class'] = $trace[1]['class'] ?? '';\n                $trace[0]['type'] = $trace[1]['type'] ?? '';\n                $trace[0]['function'] = $trace[1]['function'] ?? '';\n                $trace[0]['args'] = $trace[1]['args'] ?? [];\n            }\n\n            $trace = array_values(array_filter(\n                $trace, fn ($trace) => isset($trace['file']),\n            ));\n\n            if (($trace[1]['class'] ?? '') === HandleExceptions::class) {\n                array_shift($trace);\n                array_shift($trace);\n            }\n\n            $frames = [];\n            $previousFrame = null;\n\n            foreach (array_reverse($trace) as $frameData) {\n                $frame = new Frame($this->exception, $classMap, $frameData, $this->basePath, $previousFrame);\n                $frames[] = $frame;\n                $previousFrame = $frame;\n            }\n\n            $frames = array_reverse($frames);\n\n            foreach ($frames as $frame) {\n                if (! $frame->isFromVendor()) {\n                    $frame->markAsMain();\n                    break;\n                }\n            }\n\n            return new Collection($frames);\n        });\n    }\n\n    /**\n     * Get the exception's frames grouped by vendor status.\n     *\n     * @return array<int, array{is_vendor: bool, frames: array<int, Frame>}>\n     */\n    public function frameGroups()\n    {\n        $groups = [];\n\n        foreach ($this->frames() as $frame) {\n            $isVendor = $frame->isFromVendor();\n\n            if (empty($groups) || $groups[array_key_last($groups)]['is_vendor'] !== $isVendor) {\n                $groups[] = [\n                    'is_vendor' => $isVendor,\n                    'frames' => [],\n                ];\n            }\n\n            $groups[array_key_last($groups)]['frames'][] = $frame;\n        }\n\n        return $groups;\n    }\n\n    /**\n     * Get the exception's request instance.\n     *\n     * @return \\Illuminate\\Http\\Request\n     */\n    public function request()\n    {\n        return $this->request;\n    }\n\n    /**\n     * Get the request's headers.\n     *\n     * @return array<string, string>\n     */\n    public function requestHeaders()\n    {\n        return array_map(function (array $header) {\n            return implode(', ', $header);\n        }, $this->request()->headers->all());\n    }\n\n    /**\n     * Get the request's body parameters.\n     *\n     * @return string|null\n     */\n    public function requestBody()\n    {\n        if (empty($payload = $this->request()->all())) {\n            return null;\n        }\n\n        $json = (string) json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);\n\n        return str_replace('\\\\', '', $json);\n    }\n\n    /**\n     * Get the application's route context.\n     *\n     * @return array<string, string>\n     */\n    public function applicationRouteContext()\n    {\n        $route = $this->request()->route();\n\n        return $route ? array_filter([\n            'controller' => $route->getActionName(),\n            'route name' => $route->getName() ?: null,\n            'middleware' => implode(', ', array_map(function ($middleware) {\n                return $middleware instanceof Closure ? 'Closure' : $middleware;\n            }, $route->gatherMiddleware())),\n        ]) : [];\n    }\n\n    /**\n     * Get the application's route parameters context.\n     *\n     * @return array<string, mixed>|null\n     */\n    public function applicationRouteParametersContext()\n    {\n        $parameters = $this->request()->route()?->parameters();\n\n        return $parameters ? json_encode(array_map(\n            fn ($value) => $value instanceof Model ? $value->withoutRelations() : $value,\n            $parameters\n        ), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : null;\n    }\n\n    /**\n     * Get the application's SQL queries.\n     *\n     * @return array<int, array{connectionName: string, time: float, sql: string}>\n     */\n    public function applicationQueries()\n    {\n        return array_map(function (array $query) {\n            $sql = $query['sql'];\n\n            foreach ($query['bindings'] as $binding) {\n                $sql = match (gettype($binding)) {\n                    'integer', 'double' => preg_replace('/\\?/', $binding, $sql, 1),\n                    'NULL' => preg_replace('/\\?/', 'NULL', $sql, 1),\n                    default => preg_replace('/\\?/', \"'$binding'\", $sql, 1),\n                };\n            }\n\n            return [\n                'connectionName' => $query['connectionName'],\n                'time' => $query['time'],\n                'sql' => $sql,\n            ];\n        }, $this->listener->queries());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Renderer/Frame.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Renderer;\n\nuse Illuminate\\Foundation\\Concerns\\ResolvesDumpSource;\nuse Symfony\\Component\\ErrorHandler\\Exception\\FlattenException;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\nclass Frame\n{\n    use ResolvesDumpSource;\n\n    /**\n     * The \"flattened\" exception instance.\n     *\n     * @var \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException\n     */\n    protected $exception;\n\n    /**\n     * The application's class map.\n     *\n     * @var array<string, string>\n     */\n    protected $classMap;\n\n    /**\n     * The frame's raw data from the \"flattened\" exception.\n     *\n     * @var array{file: string, line: int, class?: string, type?: string, function?: string}\n     */\n    protected $frame;\n\n    /**\n     * The application's base path.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * The previous frame.\n     *\n     * @var \\Illuminate\\Foundation\\Exceptions\\Renderer\\Frame|null\n     */\n    protected $previous;\n\n    /**\n     * Whether this frame is the main (first non-vendor) frame.\n     *\n     * @var bool\n     */\n    protected $isMain = false;\n\n    /**\n     * Create a new frame instance.\n     *\n     * @param  \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException  $exception\n     * @param  array<string, string>  $classMap\n     * @param  array{file: string, line: int, class?: string, type?: string, function?: string, args?: array}  $frame\n     * @param  string  $basePath\n     * @param  \\Illuminate\\Foundation\\Exceptions\\Renderer\\Frame|null  $previous\n     */\n    public function __construct(FlattenException $exception, array $classMap, array $frame, string $basePath, ?Frame $previous = null)\n    {\n        $this->exception = $exception;\n        $this->classMap = $classMap;\n        $this->frame = $frame;\n        $this->basePath = $basePath;\n        $this->previous = $previous;\n    }\n\n    /**\n     * Get the frame's source / origin.\n     *\n     * @return string\n     */\n    public function source()\n    {\n        return match (true) {\n            is_string($this->class()) => $this->class(),\n            default => $this->file(),\n        };\n    }\n\n    /**\n     * Get the frame's editor link.\n     *\n     * @return string\n     */\n    public function editorHref()\n    {\n        return $this->resolveSourceHref($this->frame['file'], $this->line());\n    }\n\n    /**\n     * Get the frame's class, if any.\n     *\n     * @return string|null\n     */\n    public function class()\n    {\n        if (! empty($this->frame['class'])) {\n            return $this->frame['class'];\n        }\n\n        $class = array_search((string) realpath($this->frame['file']), $this->classMap, true);\n\n        return $class === false ? null : $class;\n    }\n\n    /**\n     * Get the frame's file.\n     *\n     * @return string\n     */\n    public function file()\n    {\n        return match (true) {\n            ! isset($this->frame['file']) => '[internal function]',\n            ! is_string($this->frame['file']) => '[unknown file]',\n            default => str_replace($this->basePath.DIRECTORY_SEPARATOR, '', $this->frame['file']),\n        };\n    }\n\n    /**\n     * Get the frame's line number.\n     *\n     * @return int\n     */\n    public function line()\n    {\n        if (! is_file($this->frame['file']) || ! is_readable($this->frame['file'])) {\n            return 0;\n        }\n\n        $maxLines = count(file($this->frame['file']) ?: []);\n\n        return $this->frame['line'] > $maxLines ? 1 : $this->frame['line'];\n    }\n\n    /**\n     * Get the frame's function operator.\n     *\n     * @return '::'|'->'|''\n     */\n    public function operator()\n    {\n        return $this->frame['type'] ?? '';\n    }\n\n    /**\n     * Get the frame's function or method.\n     *\n     * @return string\n     */\n    public function callable()\n    {\n        return match (true) {\n            ! empty($this->frame['function']) => $this->frame['function'],\n            default => 'throw',\n        };\n    }\n\n    /**\n     * Get the frame's arguments.\n     *\n     * @return array\n     */\n    public function args()\n    {\n        if (! isset($this->frame['args']) || ! is_array($this->frame['args']) || count($this->frame['args']) === 0) {\n            return [];\n        }\n\n        return array_map(function ($argument) {\n            [$key, $value] = $argument;\n\n            return match ($key) {\n                'object' => \"{$key}({$value})\",\n                default => $key,\n            };\n        }, $this->frame['args']);\n    }\n\n    /**\n     * Get the frame's code snippet.\n     *\n     * @return string\n     */\n    public function snippet()\n    {\n        if (! is_file($this->frame['file']) || ! is_readable($this->frame['file'])) {\n            return '';\n        }\n\n        $contents = file($this->frame['file']) ?: [];\n\n        $start = max($this->line() - 6, 0);\n\n        $length = 8 * 2 + 1;\n\n        return implode('', array_slice($contents, $start, $length));\n    }\n\n    /**\n     * Determine if the frame is from the vendor directory.\n     *\n     * @return bool\n     */\n    public function isFromVendor()\n    {\n        return ! str_starts_with($this->frame['file'], $this->basePath)\n            || str_starts_with($this->frame['file'], join_paths($this->basePath, 'vendor'));\n    }\n\n    /**\n     * Get the previous frame.\n     *\n     * @return \\Illuminate\\Foundation\\Exceptions\\Renderer\\Frame|null\n     */\n    public function previous()\n    {\n        return $this->previous;\n    }\n\n    /**\n     * Mark this frame as the main frame.\n     *\n     * @return void\n     */\n    public function markAsMain()\n    {\n        $this->isMain = true;\n    }\n\n    /**\n     * Determine if this is the main frame.\n     *\n     * @return bool\n     */\n    public function isMain()\n    {\n        return $this->isMain;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Renderer/Listener.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Renderer;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Queue\\Events\\JobProcessed;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Laravel\\Octane\\Events\\RequestReceived;\nuse Laravel\\Octane\\Events\\RequestTerminated;\nuse Laravel\\Octane\\Events\\TaskReceived;\nuse Laravel\\Octane\\Events\\TickReceived;\n\nclass Listener\n{\n    /**\n     * The queries that have been executed.\n     *\n     * @var array<int, array{connectionName: string, time: float, sql: string, bindings: array}>\n     */\n    protected $queries = [];\n\n    /**\n     * Register the appropriate listeners on the given event dispatcher.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return void\n     */\n    public function registerListeners(Dispatcher $events)\n    {\n        $events->listen(QueryExecuted::class, $this->onQueryExecuted(...));\n\n        $events->listen([JobProcessing::class, JobProcessed::class], function () {\n            $this->queries = [];\n        });\n\n        if (isset($_SERVER['LARAVEL_OCTANE'])) {\n            $events->listen([RequestReceived::class, TaskReceived::class, TickReceived::class, RequestTerminated::class], function () {\n                $this->queries = [];\n            });\n        }\n    }\n\n    /**\n     * Returns the queries that have been executed.\n     *\n     * @return array<int, array{connectionName: string, time: float, sql: string, bindings: array}>\n     */\n    public function queries()\n    {\n        return $this->queries;\n    }\n\n    /**\n     * Listens for the query executed event.\n     *\n     * @param  \\Illuminate\\Database\\Events\\QueryExecuted  $event\n     * @return void\n     */\n    public function onQueryExecuted(QueryExecuted $event)\n    {\n        if (count($this->queries) === 101) {\n            return;\n        }\n\n        $this->queries[] = [\n            'connectionName' => $event->connectionName,\n            'time' => $event->time,\n            'sql' => $event->sql,\n            'bindings' => $event->connection->prepareBindings($event->bindings),\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Renderer/Mappers/BladeMapper.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Renderer\\Mappers;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\View\\Compilers\\BladeCompiler;\nuse Illuminate\\View\\ViewException;\nuse ReflectionClass;\nuse ReflectionProperty;\nuse Symfony\\Component\\ErrorHandler\\Exception\\FlattenException;\nuse Throwable;\n\n/*\n * This file contains parts of https://github.com/spatie/laravel-ignition.\n *\n * (c) Spatie <info@spatie.be>\n *\n * For the full copyright and license information, please review its LICENSE:\n *\n * The MIT License (MIT)\n *\n * Copyright (c) Spatie <info@spatie.be>\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\n * THE SOFTWARE.\n */\n\nclass BladeMapper\n{\n    /**\n     * The view factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The Blade compiler instance.\n     *\n     * @var \\Illuminate\\View\\Compilers\\BladeCompiler\n     */\n    protected $bladeCompiler;\n\n    /**\n     * Create a new Blade mapper instance.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $factory\n     * @param  \\Illuminate\\View\\Compilers\\BladeCompiler  $bladeCompiler\n     */\n    public function __construct(Factory $factory, BladeCompiler $bladeCompiler)\n    {\n        $this->factory = $factory;\n        $this->bladeCompiler = $bladeCompiler;\n    }\n\n    /**\n     * Map cached view paths to their original paths.\n     *\n     * @param  \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException  $exception\n     * @return \\Symfony\\Component\\ErrorHandler\\Exception\\FlattenException\n     */\n    public function map(FlattenException $exception)\n    {\n        while ($exception->getClass() === ViewException::class) {\n            if (($previous = $exception->getPrevious()) === null) {\n                break;\n            }\n\n            $exception = $previous;\n        }\n\n        $trace = (new Collection($exception->getTrace()))\n            ->map(function ($frame) {\n                if ($originalPath = $this->findCompiledView((string) Arr::get($frame, 'file', ''))) {\n                    $frame['file'] = $originalPath;\n                    $frame['line'] = $this->detectLineNumber($frame['file'], $frame['line']);\n                }\n\n                return $frame;\n            })->toArray();\n\n        return tap($exception, fn () => (fn () => $this->trace = $trace)->call($exception));\n    }\n\n    /**\n     * Find the compiled view file for the given compiled path.\n     *\n     * @param  string  $compiledPath\n     * @return string|null\n     */\n    protected function findCompiledView(string $compiledPath)\n    {\n        return once(fn () => $this->getKnownPaths())[$compiledPath] ?? null;\n    }\n\n    /**\n     * Get the list of known paths from the compiler engine.\n     *\n     * @return array<string, string>\n     */\n    protected function getKnownPaths()\n    {\n        $compilerEngineReflection = new ReflectionClass(\n            $bladeCompilerEngine = $this->factory->getEngineResolver()->resolve('blade'),\n        );\n\n        if (! $compilerEngineReflection->hasProperty('lastCompiled') && $compilerEngineReflection->hasProperty('engine')) {\n            $compilerEngine = $compilerEngineReflection->getProperty('engine');\n            $compilerEngine = $compilerEngine->getValue($bladeCompilerEngine);\n            $lastCompiled = new ReflectionProperty($compilerEngine, 'lastCompiled');\n            $lastCompiled = $lastCompiled->getValue($compilerEngine);\n        } else {\n            $lastCompiled = $compilerEngineReflection->getProperty('lastCompiled');\n            $lastCompiled = $lastCompiled->getValue($bladeCompilerEngine);\n        }\n\n        $knownPaths = [];\n        foreach ($lastCompiled as $lastCompiledPath) {\n            $compiledPath = $bladeCompilerEngine->getCompiler()->getCompiledPath($lastCompiledPath);\n\n            $knownPaths[realpath($compiledPath ?? $lastCompiledPath)] = realpath($lastCompiledPath);\n        }\n\n        return $knownPaths;\n    }\n\n    /**\n     * Filter out the view data that should not be shown in the exception report.\n     *\n     * @param  array<string, mixed>  $data\n     * @return array<string, mixed>\n     */\n    protected function filterViewData(array $data)\n    {\n        return array_filter($data, function ($value, $key) {\n            if ($key === 'app') {\n                return ! $value instanceof Application;\n            }\n\n            return $key !== '__env';\n        }, ARRAY_FILTER_USE_BOTH);\n    }\n\n    /**\n     * Detect the line number in the original blade file.\n     *\n     * @param  string  $filename\n     * @param  int  $compiledLineNumber\n     * @return int\n     */\n    protected function detectLineNumber(string $filename, int $compiledLineNumber)\n    {\n        $map = $this->compileSourcemap((string) file_get_contents($filename));\n\n        return $this->findClosestLineNumberMapping($map, $compiledLineNumber);\n    }\n\n    /**\n     * Compile the source map for the given blade file.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileSourcemap(string $value)\n    {\n        try {\n            $value = $this->addEchoLineNumbers($value);\n            $value = $this->addStatementLineNumbers($value);\n            $value = $this->addBladeComponentLineNumbers($value);\n\n            $value = $this->bladeCompiler->compileString($value);\n\n            return $this->trimEmptyLines($value);\n        } catch (Throwable $e) {\n            report($e);\n\n            return $value;\n        }\n    }\n\n    /**\n     * Add line numbers to echo statements.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function addEchoLineNumbers(string $value)\n    {\n        $echoPairs = [['{{', '}}'], ['{{{', '}}}'], ['{!!', '!!}']];\n\n        foreach ($echoPairs as $pair) {\n            // Matches {{ $value }}, {!! $value !!} and  {{{ $value }}} depending on $pair\n            $pattern = sprintf('/(@)?%s\\s*(.+?)\\s*%s(\\r?\\n)?/s', $pair[0], $pair[1]);\n\n            if (preg_match_all($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {\n                foreach (array_reverse($matches[0]) as $match) {\n                    $position = mb_strlen(substr($value, 0, $match[1]));\n\n                    $value = $this->insertLineNumberAtPosition($position, $value);\n                }\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Add line numbers to blade statements.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function addStatementLineNumbers(string $value)\n    {\n        $shouldInsertLineNumbers = preg_match_all(\n            '/\\B@(@?\\w+(?:::\\w+)?)([ \\t]*)(\\( ( (?>[^()]+) | (?3) )* \\))?/x',\n            $value,\n            $matches,\n            PREG_OFFSET_CAPTURE\n        );\n\n        if ($shouldInsertLineNumbers) {\n            foreach (array_reverse($matches[0]) as $match) {\n                $position = mb_strlen(substr($value, 0, $match[1]));\n\n                $value = $this->insertLineNumberAtPosition($position, $value);\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Add line numbers to blade components.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function addBladeComponentLineNumbers(string $value)\n    {\n        $shouldInsertLineNumbers = preg_match_all(\n            '/<\\s*x[-:]([\\w\\-:.]*)/mx',\n            $value,\n            $matches,\n            PREG_OFFSET_CAPTURE\n        );\n\n        if ($shouldInsertLineNumbers) {\n            foreach (array_reverse($matches[0]) as $match) {\n                $position = mb_strlen(substr($value, 0, $match[1]));\n\n                $value = $this->insertLineNumberAtPosition($position, $value);\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Insert a line number at the given position.\n     *\n     * @param  int  $position\n     * @param  string  $value\n     * @return string\n     */\n    protected function insertLineNumberAtPosition(int $position, string $value)\n    {\n        $before = mb_substr($value, 0, $position);\n\n        $lineNumber = count(explode(\"\\n\", $before));\n\n        return mb_substr($value, 0, $position).\"|---LINE:{$lineNumber}---|\".mb_substr($value, $position);\n    }\n\n    /**\n     * Trim empty lines from the given value.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function trimEmptyLines(string $value)\n    {\n        $value = preg_replace('/^\\|---LINE:([0-9]+)---\\|$/m', '', $value);\n\n        return ltrim((string) $value, PHP_EOL);\n    }\n\n    /**\n     * Find the closest line number mapping in the given source map.\n     *\n     * @param  string  $map\n     * @param  int  $compiledLineNumber\n     * @return int\n     */\n    protected function findClosestLineNumberMapping(string $map, int $compiledLineNumber)\n    {\n        $map = explode(\"\\n\", $map);\n\n        $maxDistance = 20;\n\n        $pattern = '/\\|---LINE:(?P<line>[0-9]+)---\\|/m';\n\n        $lineNumberToCheck = $compiledLineNumber - 1;\n\n        while (true) {\n            if ($lineNumberToCheck < $compiledLineNumber - $maxDistance) {\n                return min($compiledLineNumber, count($map));\n            }\n\n            if (preg_match($pattern, $map[$lineNumberToCheck] ?? '', $matches)) {\n                return (int) $matches['line'];\n            }\n\n            $lineNumberToCheck--;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Renderer/Renderer.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Renderer;\n\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Mappers\\BladeMapper;\nuse Illuminate\\Http\\Request;\nuse Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer;\nuse Throwable;\n\nclass Renderer\n{\n    /**\n     * The path to the renderer's distribution files.\n     *\n     * @var string\n     */\n    protected const DIST = __DIR__.'/../../resources/exceptions/renderer/dist/';\n\n    /**\n     * The view factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $viewFactory;\n\n    /**\n     * The exception listener instance.\n     *\n     * @var \\Illuminate\\Foundation\\Exceptions\\Renderer\\Listener\n     */\n    protected $listener;\n\n    /**\n     * The HTML error renderer instance.\n     *\n     * @var \\Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer\n     */\n    protected $htmlErrorRenderer;\n\n    /**\n     * The Blade mapper instance.\n     *\n     * @var \\Illuminate\\Foundation\\Exceptions\\Renderer\\Mappers\\BladeMapper\n     */\n    protected $bladeMapper;\n\n    /**\n     * The application's base path.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * Creates a new exception renderer instance.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $viewFactory\n     * @param  \\Illuminate\\Foundation\\Exceptions\\Renderer\\Listener  $listener\n     * @param  \\Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer  $htmlErrorRenderer\n     * @param  \\Illuminate\\Foundation\\Exceptions\\Renderer\\Mappers\\BladeMapper  $bladeMapper\n     * @param  string  $basePath\n     */\n    public function __construct(\n        Factory $viewFactory,\n        Listener $listener,\n        HtmlErrorRenderer $htmlErrorRenderer,\n        BladeMapper $bladeMapper,\n        string $basePath,\n    ) {\n        $this->viewFactory = $viewFactory;\n        $this->listener = $listener;\n        $this->htmlErrorRenderer = $htmlErrorRenderer;\n        $this->bladeMapper = $bladeMapper;\n        $this->basePath = $basePath;\n    }\n\n    /**\n     * Render the given exception as an HTML string.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $throwable\n     * @return string\n     */\n    public function render(Request $request, Throwable $throwable)\n    {\n        $flattenException = $this->bladeMapper->map(\n            $this->htmlErrorRenderer->render($throwable),\n        );\n\n        $exception = new Exception($flattenException, $request, $this->listener, $this->basePath);\n\n        $exceptionAsMarkdown = $this->viewFactory->make('laravel-exceptions-renderer::markdown', [\n            'exception' => $exception,\n        ])->render();\n\n        return $this->viewFactory->make('laravel-exceptions-renderer::show', [\n            'exception' => $exception,\n            'exceptionAsMarkdown' => $exceptionAsMarkdown,\n        ])->render();\n    }\n\n    /**\n     * Get the renderer's CSS content.\n     *\n     * @return string\n     */\n    public static function css()\n    {\n        return '<style>'.file_get_contents(static::DIST.'styles.css').'</style>';\n    }\n\n    /**\n     * Get the renderer's JavaScript content.\n     *\n     * @return string\n     */\n    public static function js()\n    {\n        $viteJsAutoRefresh = '';\n\n        $vite = app(\\Illuminate\\Foundation\\Vite::class);\n\n        if (is_file($vite->hotFile())) {\n            $viteJsAutoRefresh = $vite->__invoke([]);\n        }\n\n        return '<script>'\n            .file_get_contents(static::DIST.'scripts.js')\n            .'</script>'.$viteJsAutoRefresh;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/ReportableHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions;\n\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Throwable;\n\nclass ReportableHandler\n{\n    use ReflectsClosures;\n\n    /**\n     * The underlying callback.\n     *\n     * @var callable\n     */\n    protected $callback;\n\n    /**\n     * Indicates if reporting should stop after invoking this handler.\n     *\n     * @var bool\n     */\n    protected $shouldStop = false;\n\n    /**\n     * Create a new reportable handler instance.\n     *\n     * @param  callable  $callback\n     */\n    public function __construct(callable $callback)\n    {\n        $this->callback = $callback;\n    }\n\n    /**\n     * Invoke the handler.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function __invoke(Throwable $e)\n    {\n        $result = call_user_func($this->callback, $e);\n\n        if ($result === false) {\n            return false;\n        }\n\n        return ! $this->shouldStop;\n    }\n\n    /**\n     * Determine if the callback handles the given exception.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function handles(Throwable $e)\n    {\n        foreach ($this->firstClosureParameterTypes($this->callback) as $type) {\n            if (is_a($e, $type)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Indicate that report handling should stop after invoking this callback.\n     *\n     * @return $this\n     */\n    public function stop()\n    {\n        $this->shouldStop = true;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Whoops/WhoopsExceptionRenderer.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Whoops;\n\nuse Illuminate\\Contracts\\Foundation\\ExceptionRenderer;\nuse Whoops\\Run as Whoops;\n\nuse function tap;\n\nclass WhoopsExceptionRenderer implements ExceptionRenderer\n{\n    /**\n     * Renders the given exception as HTML.\n     *\n     * @param  \\Throwable  $throwable\n     * @return string\n     */\n    public function render($throwable)\n    {\n        return tap(new Whoops, function ($whoops) {\n            $whoops->appendHandler($this->whoopsHandler());\n\n            $whoops->writeToOutput(false);\n\n            $whoops->allowQuit(false);\n        })->handleException($throwable);\n    }\n\n    /**\n     * Get the Whoops handler for the application.\n     *\n     * @return \\Whoops\\Handler\\Handler\n     */\n    protected function whoopsHandler()\n    {\n        return (new WhoopsHandler)->forDebug();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/Whoops/WhoopsHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Exceptions\\Whoops;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Arr;\nuse Whoops\\Handler\\PrettyPageHandler;\n\nclass WhoopsHandler\n{\n    /**\n     * Create a new Whoops handler for debug mode.\n     *\n     * @return \\Whoops\\Handler\\PrettyPageHandler\n     */\n    public function forDebug()\n    {\n        return tap(new PrettyPageHandler, function ($handler) {\n            $handler->handleUnconditionally(true);\n\n            $this->registerApplicationPaths($handler)\n                ->registerBlacklist($handler)\n                ->registerEditor($handler);\n        });\n    }\n\n    /**\n     * Register the application paths with the handler.\n     *\n     * @param  \\Whoops\\Handler\\PrettyPageHandler  $handler\n     * @return $this\n     */\n    protected function registerApplicationPaths($handler)\n    {\n        $handler->setApplicationPaths(\n            array_flip($this->directoriesExceptVendor())\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get the application paths except for the \"vendor\" directory.\n     *\n     * @return array\n     */\n    protected function directoriesExceptVendor()\n    {\n        return Arr::except(\n            array_flip((new Filesystem)->directories(base_path())),\n            [base_path('vendor')]\n        );\n    }\n\n    /**\n     * Register the blacklist with the handler.\n     *\n     * @param  \\Whoops\\Handler\\PrettyPageHandler  $handler\n     * @return $this\n     */\n    protected function registerBlacklist($handler)\n    {\n        foreach (config('app.debug_blacklist', config('app.debug_hide', [])) as $key => $secrets) {\n            foreach ($secrets as $secret) {\n                $handler->blacklist($key, $secret);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register the editor with the handler.\n     *\n     * @param  \\Whoops\\Handler\\PrettyPageHandler  $handler\n     * @return $this\n     */\n    protected function registerEditor($handler)\n    {\n        if (config('app.editor', false)) {\n            $handler->setEditor(config('app.editor'));\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/401.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Unauthorized'))\n@section('code', '401')\n@section('message', __('Unauthorized'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/402.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Payment Required'))\n@section('code', '402')\n@section('message', __('Payment Required'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/403.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Forbidden'))\n@section('code', '403')\n@section('message', __($exception->getMessage() ?: 'Forbidden'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/404.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Not Found'))\n@section('code', '404')\n@section('message', __('Not Found'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/419.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Page Expired'))\n@section('code', '419')\n@section('message', __('Page Expired'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/429.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Too Many Requests'))\n@section('code', '429')\n@section('message', __('Too Many Requests'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/500.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Server Error'))\n@section('code', '500')\n@section('message', __('Server Error'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/503.blade.php",
    "content": "@extends('errors::minimal')\n\n@section('title', __('Service Unavailable'))\n@section('code', '503')\n@section('message', __('Service Unavailable'))\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/layout.blade.php",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n        <title>@yield('title')</title>\n\n        <!-- Styles -->\n        <style>\n            html, body {\n                background-color: #fff;\n                color: #636b6f;\n                font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n                font-weight: 100;\n                height: 100vh;\n                margin: 0;\n            }\n\n            .full-height {\n                height: 100vh;\n            }\n\n            .flex-center {\n                align-items: center;\n                display: flex;\n                justify-content: center;\n            }\n\n            .position-ref {\n                position: relative;\n            }\n\n            .content {\n                text-align: center;\n            }\n\n            .title {\n                font-size: 36px;\n                padding: 20px;\n            }\n        </style>\n    </head>\n    <body>\n        <div class=\"flex-center position-ref full-height\">\n            <div class=\"content\">\n                <div class=\"title\">\n                    @yield('message')\n                </div>\n            </div>\n        </div>\n    </body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Foundation/Exceptions/views/minimal.blade.php",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n        <title>@yield('title')</title>\n\n        <style>\n            /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tracking-wider{letter-spacing:.05em}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@media (min-width:640px){.sm\\:rounded-lg{border-radius:.5rem}.sm\\:block{display:block}.sm\\:items-center{align-items:center}.sm\\:justify-start{justify-content:flex-start}.sm\\:justify-between{justify-content:space-between}.sm\\:h-20{height:5rem}.sm\\:ml-0{margin-left:0}.sm\\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\\:pt-0{padding-top:0}.sm\\:text-left{text-align:left}.sm\\:text-right{text-align:right}}@media (min-width:768px){.md\\:border-t-0{border-top-width:0}.md\\:border-l{border-left-width:1px}.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\\:text-gray-300 { --text-opacity: 1; color: #e2e8f0; color: rgba(226,232,240,var(--text-opacity)) }}\n        </style>\n\n        <style>\n            body {\n                font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n            }\n        </style>\n    </head>\n    <body class=\"antialiased bg-white text-black\">\n        <div class=\"relative flex items-top justify-center min-h-screen bg-white text-black sm:items-center sm:pt-0\" role=\"main\">\n            <div class=\"max-w-xl mx-auto sm:px-6 lg:px-8\">\n                <div class=\"flex items-center pt-8 sm:justify-start sm:pt-0\">\n                    <h1 class=\"px-4 text-lg text-black border-r border-gray-400\">\n                        @yield('code')\n                    </h1>\n\n                    <div class=\"ml-4 text-lg text-black\">\n                        @yield('message')\n                    </div>\n                </div>\n            </div>\n        </div>\n    </body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Foundation/FileBasedMaintenanceMode.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode as MaintenanceModeContract;\n\nclass FileBasedMaintenanceMode implements MaintenanceModeContract\n{\n    /**\n     * Take the application down for maintenance.\n     *\n     * @param  array  $payload\n     * @return void\n     */\n    public function activate(array $payload): void\n    {\n        file_put_contents(\n            $this->path(),\n            json_encode($payload, JSON_PRETTY_PRINT)\n        );\n    }\n\n    /**\n     * Take the application out of maintenance.\n     *\n     * @return void\n     */\n    public function deactivate(): void\n    {\n        if ($this->active()) {\n            unlink($this->path());\n        }\n    }\n\n    /**\n     * Determine if the application is currently down for maintenance.\n     *\n     * @return bool\n     */\n    public function active(): bool\n    {\n        return file_exists($this->path());\n    }\n\n    /**\n     * Get the data array which was provided when the application was placed into maintenance.\n     *\n     * @return array\n     */\n    public function data(): array\n    {\n        return json_decode(file_get_contents($this->path()), true);\n    }\n\n    /**\n     * Get the path where the file is stored that signals that the application is down for maintenance.\n     *\n     * @return string\n     */\n    protected function path(): string\n    {\n        return storage_path('framework/down');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Attributes/ErrorBag.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass ErrorBag\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $name\n     */\n    public function __construct(public string $name)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Attributes/RedirectTo.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass RedirectTo\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $url\n     */\n    public function __construct(public string $url)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Attributes/RedirectToRoute.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass RedirectToRoute\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $route\n     */\n    public function __construct(public string $route)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Attributes/StopOnFirstFailure.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass StopOnFirstFailure\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Events/RequestHandled.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Events;\n\nclass RequestHandled\n{\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    public $request;\n\n    /**\n     * The response instance.\n     *\n     * @var \\Illuminate\\Http\\Response\n     */\n    public $response;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\Response  $response\n     */\n    public function __construct($request, $response)\n    {\n        $this->request = $request;\n        $this->response = $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/FormRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Response;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Validation\\Factory as ValidationFactory;\nuse Illuminate\\Contracts\\Validation\\ValidatesWhenResolved;\nuse Illuminate\\Contracts\\Validation\\Validator;\nuse Illuminate\\Foundation\\Http\\Attributes\\ErrorBag;\nuse Illuminate\\Foundation\\Http\\Attributes\\RedirectTo;\nuse Illuminate\\Foundation\\Http\\Attributes\\RedirectToRoute;\nuse Illuminate\\Foundation\\Http\\Attributes\\StopOnFirstFailure;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Validation\\ValidatesWhenResolvedTrait;\nuse ReflectionClass;\n\nclass FormRequest extends Request implements ValidatesWhenResolved\n{\n    use ValidatesWhenResolvedTrait;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The redirector instance.\n     *\n     * @var \\Illuminate\\Routing\\Redirector\n     */\n    protected $redirector;\n\n    /**\n     * The URI to redirect to if validation fails.\n     *\n     * @var string\n     */\n    protected $redirect;\n\n    /**\n     * The route to redirect to if validation fails.\n     *\n     * @var string\n     */\n    protected $redirectRoute;\n\n    /**\n     * The controller action to redirect to if validation fails.\n     *\n     * @var string\n     */\n    protected $redirectAction;\n\n    /**\n     * The key to be used for the view error bag.\n     *\n     * @var string\n     */\n    protected $errorBag = 'default';\n\n    /**\n     * Indicates whether validation should stop after the first rule failure.\n     *\n     * @var bool\n     */\n    protected $stopOnFirstFailure = false;\n\n    /**\n     * The validator instance.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * Get the validator instance for the request.\n     *\n     * @return \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    protected function getValidatorInstance()\n    {\n        if ($this->validator) {\n            return $this->validator;\n        }\n\n        $this->configureFromAttributes();\n\n        $factory = $this->container->make(ValidationFactory::class);\n\n        if (method_exists($this, 'validator')) {\n            $validator = $this->container->call($this->validator(...), compact('factory'));\n        } else {\n            $validator = $this->createDefaultValidator($factory);\n        }\n\n        if (method_exists($this, 'withValidator')) {\n            $this->withValidator($validator);\n        }\n\n        if (method_exists($this, 'after')) {\n            $validator->after($this->container->call(\n                $this->after(...),\n                ['validator' => $validator]\n            ));\n        }\n\n        $this->setValidator($validator);\n\n        return $this->validator;\n    }\n\n    /**\n     * Configure the form request from class attributes.\n     *\n     * @return void\n     */\n    protected function configureFromAttributes()\n    {\n        $reflection = new ReflectionClass($this);\n\n        if (count($reflection->getAttributes(StopOnFirstFailure::class)) > 0) {\n            $this->stopOnFirstFailure = true;\n        }\n\n        $redirectTo = $reflection->getAttributes(RedirectTo::class);\n\n        if (count($redirectTo) > 0) {\n            $this->redirect = $redirectTo[0]->newInstance()->url;\n        }\n\n        $redirectToRoute = $reflection->getAttributes(RedirectToRoute::class);\n\n        if (count($redirectToRoute) > 0) {\n            $this->redirectRoute = $redirectToRoute[0]->newInstance()->route;\n        }\n\n        $errorBag = $reflection->getAttributes(ErrorBag::class);\n\n        if (count($errorBag) > 0) {\n            $this->errorBag = $errorBag[0]->newInstance()->name;\n        }\n    }\n\n    /**\n     * Create the default validator instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Factory  $factory\n     * @return \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    protected function createDefaultValidator(ValidationFactory $factory)\n    {\n        $rules = $this->validationRules();\n\n        $validator = $factory->make(\n            $this->validationData(),\n            $rules,\n            $this->messages(),\n            $this->attributes(),\n        )->stopOnFirstFailure($this->stopOnFirstFailure);\n\n        if ($this->isPrecognitive()) {\n            $validator->setRules(\n                $this->filterPrecognitiveRules($validator->getRulesWithoutPlaceholders())\n            );\n        }\n\n        return $validator;\n    }\n\n    /**\n     * Get data to be validated from the request.\n     *\n     * @return array\n     */\n    public function validationData()\n    {\n        return $this->all();\n    }\n\n    /**\n     * Get the validation rules for this form request.\n     *\n     * @return array\n     */\n    protected function validationRules()\n    {\n        return method_exists($this, 'rules') ? $this->container->call([$this, 'rules']) : [];\n    }\n\n    /**\n     * Handle a failed validation attempt.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return void\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    protected function failedValidation(Validator $validator)\n    {\n        $exception = $validator->getException();\n\n        throw (new $exception($validator))\n            ->errorBag($this->errorBag)\n            ->redirectTo($this->getRedirectUrl());\n    }\n\n    /**\n     * Get the URL to redirect to on a validation error.\n     *\n     * @return string\n     */\n    protected function getRedirectUrl()\n    {\n        $url = $this->redirector->getUrlGenerator();\n\n        if ($this->redirect) {\n            return $url->to($this->redirect);\n        } elseif ($this->redirectRoute) {\n            return $url->route($this->redirectRoute);\n        } elseif ($this->redirectAction) {\n            return $url->action($this->redirectAction);\n        }\n\n        return $url->previous();\n    }\n\n    /**\n     * Determine if the request passes the authorization check.\n     *\n     * @return bool\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    protected function passesAuthorization()\n    {\n        if (method_exists($this, 'authorize')) {\n            $result = $this->container->call([$this, 'authorize']);\n\n            return $result instanceof Response ? $result->authorize() : $result;\n        }\n\n        return true;\n    }\n\n    /**\n     * Handle a failed authorization attempt.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException\n     */\n    protected function failedAuthorization()\n    {\n        throw new AuthorizationException;\n    }\n\n    /**\n     * Get a validated input container for the validated input.\n     *\n     * @param  array|null  $keys\n     * @return \\Illuminate\\Support\\ValidatedInput|array\n     */\n    public function safe(?array $keys = null)\n    {\n        return is_array($keys)\n            ? $this->validator->safe()->only($keys)\n            : $this->validator->safe();\n    }\n\n    /**\n     * Get the validated data from the request.\n     *\n     * @param  array|int|string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function validated($key = null, $default = null)\n    {\n        return data_get($this->validator->validated(), $key, $default);\n    }\n\n    /**\n     * Get custom messages for validator errors.\n     *\n     * @return array<string, string>\n     */\n    public function messages()\n    {\n        return [];\n    }\n\n    /**\n     * Get custom attributes for validator errors.\n     *\n     * @return array<string, string>\n     */\n    public function attributes()\n    {\n        return [];\n    }\n\n    /**\n     * Set the Validator instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator(Validator $validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * Set the Redirector instance.\n     *\n     * @param  \\Illuminate\\Routing\\Redirector  $redirector\n     * @return $this\n     */\n    public function setRedirector(Redirector $redirector)\n    {\n        $this->redirector = $redirector;\n\n        return $this;\n    }\n\n    /**\n     * Set the container implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/HtmlDumper.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http;\n\nuse Illuminate\\Foundation\\Concerns\\ResolvesDumpSource;\nuse Symfony\\Component\\VarDumper\\Caster\\ReflectionCaster;\nuse Symfony\\Component\\VarDumper\\Cloner\\Data;\nuse Symfony\\Component\\VarDumper\\Cloner\\VarCloner;\nuse Symfony\\Component\\VarDumper\\Dumper\\HtmlDumper as BaseHtmlDumper;\nuse Symfony\\Component\\VarDumper\\VarDumper;\n\nclass HtmlDumper extends BaseHtmlDumper\n{\n    use ResolvesDumpSource;\n\n    /**\n     * Where the source should be placed on \"expanded\" kind of dumps.\n     *\n     * @var string\n     */\n    const EXPANDED_SEPARATOR = 'class=sf-dump-expanded>';\n\n    /**\n     * Where the source should be placed on \"non expanded\" kind of dumps.\n     *\n     * @var string\n     */\n    const NON_EXPANDED_SEPARATOR = \"\\n</pre><script>\";\n\n    /**\n     * The base path of the application.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * The compiled view path of the application.\n     *\n     * @var string\n     */\n    protected $compiledViewPath;\n\n    /**\n     * If the dumper is currently dumping.\n     *\n     * @var bool\n     */\n    protected $dumping = false;\n\n    /**\n     * Create a new HTML dumper instance.\n     *\n     * @param  string  $basePath\n     * @param  string  $compiledViewPath\n     */\n    public function __construct($basePath, $compiledViewPath)\n    {\n        parent::__construct();\n\n        $this->basePath = $basePath;\n        $this->compiledViewPath = $compiledViewPath;\n    }\n\n    /**\n     * Create a new HTML dumper instance and register it as the default dumper.\n     *\n     * @param  string  $basePath\n     * @param  string  $compiledViewPath\n     * @return void\n     */\n    public static function register($basePath, $compiledViewPath)\n    {\n        $cloner = tap(new VarCloner())->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);\n\n        $dumper = new static($basePath, $compiledViewPath);\n\n        VarDumper::setHandler(fn ($value) => $dumper->dumpWithSource($cloner->cloneVar($value)));\n    }\n\n    /**\n     * Dump a variable with its source file / line.\n     *\n     * @param  \\Symfony\\Component\\VarDumper\\Cloner\\Data  $data\n     * @return void\n     */\n    public function dumpWithSource(Data $data)\n    {\n        if ($this->dumping) {\n            $this->dump($data);\n\n            return;\n        }\n\n        $this->dumping = true;\n\n        $output = (string) $this->dump($data, true);\n\n        $output = match (true) {\n            str_contains($output, static::EXPANDED_SEPARATOR) => str_replace(\n                static::EXPANDED_SEPARATOR,\n                static::EXPANDED_SEPARATOR.$this->getDumpSourceContent(),\n                $output,\n            ),\n            str_contains($output, static::NON_EXPANDED_SEPARATOR) => str_replace(\n                static::NON_EXPANDED_SEPARATOR,\n                $this->getDumpSourceContent().static::NON_EXPANDED_SEPARATOR,\n                $output,\n            ),\n            default => $output,\n        };\n\n        fwrite($this->outputStream, $output);\n\n        $this->dumping = false;\n    }\n\n    /**\n     * Get the dump's source HTML content.\n     *\n     * @return string\n     */\n    protected function getDumpSourceContent()\n    {\n        if (is_null($dumpSource = $this->resolveDumpSource())) {\n            return '';\n        }\n\n        [$file, $relativeFile, $line] = $dumpSource;\n\n        $source = sprintf('%s%s', $relativeFile, is_null($line) ? '' : \":$line\");\n\n        if ($href = $this->resolveSourceHref($file, $line)) {\n            $source = sprintf('<a href=\"%s\">%s</a>', $href, $source);\n        }\n\n        return sprintf('<span style=\"color: #A0A0A0;\"> // %s</span>', $source);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Kernel.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http;\n\nuse Carbon\\CarbonInterval;\nuse DateTimeInterface;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\Http\\Kernel as KernelContract;\nuse Illuminate\\Foundation\\Events\\Terminating;\nuse Illuminate\\Foundation\\Http\\Events\\RequestHandled;\nuse Illuminate\\Routing\\Pipeline;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Request;\nuse Illuminate\\Support\\InteractsWithTime;\nuse InvalidArgumentException;\nuse Throwable;\n\nclass Kernel implements KernelContract\n{\n    use InteractsWithTime;\n\n    /**\n     * The application implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The bootstrap classes for the application.\n     *\n     * @var string[]\n     */\n    protected $bootstrappers = [\n        \\Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables::class,\n        \\Illuminate\\Foundation\\Bootstrap\\LoadConfiguration::class,\n        \\Illuminate\\Foundation\\Bootstrap\\HandleExceptions::class,\n        \\Illuminate\\Foundation\\Bootstrap\\RegisterFacades::class,\n        \\Illuminate\\Foundation\\Bootstrap\\RegisterProviders::class,\n        \\Illuminate\\Foundation\\Bootstrap\\BootProviders::class,\n    ];\n\n    /**\n     * The application's middleware stack.\n     *\n     * @var array<int, class-string|string>\n     */\n    protected $middleware = [];\n\n    /**\n     * The application's route middleware groups.\n     *\n     * @var array<string, array<int, class-string|string>>\n     */\n    protected $middlewareGroups = [];\n\n    /**\n     * The application's route middleware.\n     *\n     * @var array<string, class-string|string>\n     *\n     * @deprecated\n     */\n    protected $routeMiddleware = [];\n\n    /**\n     * The application's middleware aliases.\n     *\n     * @var array<string, class-string|string>\n     */\n    protected $middlewareAliases = [];\n\n    /**\n     * All of the registered request duration handlers.\n     *\n     * @var array\n     */\n    protected $requestLifecycleDurationHandlers = [];\n\n    /**\n     * When the kernel starting handling the current request.\n     *\n     * @var \\Illuminate\\Support\\Carbon|null\n     */\n    protected $requestStartedAt;\n\n    /**\n     * The priority-sorted list of middleware.\n     *\n     * Forces non-global middleware to always be in the given order.\n     *\n     * @var string[]\n     */\n    protected $middlewarePriority = [\n        \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,\n        \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n        \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n        \\Illuminate\\Session\\Middleware\\StartSession::class,\n        \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n        \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n        \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,\n        \\Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis::class,\n        \\Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions::class,\n        \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n        \\Illuminate\\Auth\\Middleware\\Authorize::class,\n    ];\n\n    /**\n     * Create a new HTTP kernel instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Routing\\Router  $router\n     */\n    public function __construct(Application $app, Router $router)\n    {\n        $this->app = $app;\n        $this->router = $router;\n\n        $this->syncMiddlewareToRouter();\n    }\n\n    /**\n     * Handle an incoming HTTP request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function handle($request)\n    {\n        $this->requestStartedAt = Carbon::now();\n\n        try {\n            $request->enableHttpMethodParameterOverride();\n\n            $response = $this->sendRequestThroughRouter($request);\n        } catch (Throwable $e) {\n            $this->reportException($e);\n\n            $response = $this->renderException($request, $e);\n        }\n\n        $this->app['events']->dispatch(\n            new RequestHandled($request, $response)\n        );\n\n        return $response;\n    }\n\n    /**\n     * Send the given request through the middleware / router.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\Response\n     */\n    protected function sendRequestThroughRouter($request)\n    {\n        $this->app->instance('request', $request);\n\n        Request::clearResolvedInstance();\n\n        $this->bootstrap();\n\n        return (new Pipeline($this->app))\n            ->send($request)\n            ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)\n            ->then($this->dispatchToRouter());\n    }\n\n    /**\n     * Bootstrap the application for HTTP requests.\n     *\n     * @return void\n     */\n    public function bootstrap()\n    {\n        if (! $this->app->hasBeenBootstrapped()) {\n            $this->app->bootstrapWith($this->bootstrappers());\n        }\n    }\n\n    /**\n     * Get the route dispatcher callback.\n     *\n     * @return \\Closure\n     */\n    protected function dispatchToRouter()\n    {\n        return function ($request) {\n            $this->app->instance('request', $request);\n\n            return $this->router->dispatch($request);\n        };\n    }\n\n    /**\n     * Call the terminate method on any terminable middleware.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\Response  $response\n     * @return void\n     */\n    public function terminate($request, $response)\n    {\n        $this->app['events']->dispatch(new Terminating);\n\n        $this->terminateMiddleware($request, $response);\n\n        $this->app->terminate();\n\n        if ($this->requestStartedAt === null) {\n            return;\n        }\n\n        $this->requestStartedAt->setTimezone($this->app['config']->get('app.timezone') ?? 'UTC');\n\n        foreach ($this->requestLifecycleDurationHandlers as ['threshold' => $threshold, 'handler' => $handler]) {\n            $end ??= Carbon::now();\n\n            if ($this->requestStartedAt->diffInMilliseconds($end) > $threshold) {\n                $handler($this->requestStartedAt, $request, $response);\n            }\n        }\n\n        $this->requestStartedAt = null;\n    }\n\n    /**\n     * Call the terminate method on any terminable middleware.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\Response  $response\n     * @return void\n     */\n    protected function terminateMiddleware($request, $response)\n    {\n        $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(\n            $this->gatherRouteMiddleware($request),\n            $this->middleware\n        );\n\n        foreach ($middlewares as $middleware) {\n            if (! is_string($middleware)) {\n                continue;\n            }\n\n            [$name] = $this->parseMiddleware($middleware);\n\n            $instance = $this->app->make($name);\n\n            if (method_exists($instance, 'terminate')) {\n                $instance->terminate($request, $response);\n            }\n        }\n    }\n\n    /**\n     * Register a callback to be invoked when the requests lifecycle duration exceeds a given amount of time.\n     *\n     * @param  \\DateTimeInterface|\\Carbon\\CarbonInterval|float|int  $threshold\n     * @param  callable  $handler\n     * @return void\n     */\n    public function whenRequestLifecycleIsLongerThan($threshold, $handler)\n    {\n        $threshold = $threshold instanceof DateTimeInterface\n            ? $this->secondsUntil($threshold) * 1000\n            : $threshold;\n\n        $threshold = $threshold instanceof CarbonInterval\n            ? $threshold->totalMilliseconds\n            : $threshold;\n\n        $this->requestLifecycleDurationHandlers[] = [\n            'threshold' => $threshold,\n            'handler' => $handler,\n        ];\n    }\n\n    /**\n     * When the request being handled started.\n     *\n     * @return \\Illuminate\\Support\\Carbon|null\n     */\n    public function requestStartedAt()\n    {\n        return $this->requestStartedAt;\n    }\n\n    /**\n     * Gather the route middleware for the given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    protected function gatherRouteMiddleware($request)\n    {\n        if ($route = $request->route()) {\n            return $this->router->gatherRouteMiddleware($route);\n        }\n\n        return [];\n    }\n\n    /**\n     * Parse a middleware string to get the name and parameters.\n     *\n     * @param  string  $middleware\n     * @return array\n     */\n    protected function parseMiddleware($middleware)\n    {\n        [$name, $parameters] = array_pad(explode(':', $middleware, 2), 2, []);\n\n        if (is_string($parameters)) {\n            $parameters = explode(',', $parameters);\n        }\n\n        return [$name, $parameters];\n    }\n\n    /**\n     * Determine if the kernel has a given middleware.\n     *\n     * @param  string  $middleware\n     * @return bool\n     */\n    public function hasMiddleware($middleware)\n    {\n        return in_array($middleware, $this->middleware);\n    }\n\n    /**\n     * Add a new middleware to the beginning of the stack if it does not already exist.\n     *\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function prependMiddleware($middleware)\n    {\n        if (array_search($middleware, $this->middleware) === false) {\n            array_unshift($this->middleware, $middleware);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a new middleware to end of the stack if it does not already exist.\n     *\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function pushMiddleware($middleware)\n    {\n        if (array_search($middleware, $this->middleware) === false) {\n            $this->middleware[] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Prepend the given middleware to the given middleware group.\n     *\n     * @param  string  $group\n     * @param  string  $middleware\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function prependMiddlewareToGroup($group, $middleware)\n    {\n        if (! isset($this->middlewareGroups[$group])) {\n            throw new InvalidArgumentException(\"The [{$group}] middleware group has not been defined.\");\n        }\n\n        if (array_search($middleware, $this->middlewareGroups[$group]) === false) {\n            array_unshift($this->middlewareGroups[$group], $middleware);\n        }\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Append the given middleware to the given middleware group.\n     *\n     * @param  string  $group\n     * @param  string  $middleware\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function appendMiddlewareToGroup($group, $middleware)\n    {\n        if (! isset($this->middlewareGroups[$group])) {\n            throw new InvalidArgumentException(\"The [{$group}] middleware group has not been defined.\");\n        }\n\n        if (array_search($middleware, $this->middlewareGroups[$group]) === false) {\n            $this->middlewareGroups[$group][] = $middleware;\n        }\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Prepend the given middleware to the middleware priority list.\n     *\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function prependToMiddlewarePriority($middleware)\n    {\n        if (! in_array($middleware, $this->middlewarePriority)) {\n            array_unshift($this->middlewarePriority, $middleware);\n        }\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Append the given middleware to the middleware priority list.\n     *\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function appendToMiddlewarePriority($middleware)\n    {\n        if (! in_array($middleware, $this->middlewarePriority)) {\n            $this->middlewarePriority[] = $middleware;\n        }\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Add the given middleware to the middleware priority list before other middleware.\n     *\n     * @param  array|string  $before\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function addToMiddlewarePriorityBefore($before, $middleware)\n    {\n        return $this->addToMiddlewarePriorityRelative($before, $middleware, after: false);\n    }\n\n    /**\n     * Add the given middleware to the middleware priority list after other middleware.\n     *\n     * @param  array|string  $after\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function addToMiddlewarePriorityAfter($after, $middleware)\n    {\n        return $this->addToMiddlewarePriorityRelative($after, $middleware);\n    }\n\n    /**\n     * Add the given middleware to the middleware priority list relative to other middleware.\n     *\n     * @param  string|array  $existing\n     * @param  string  $middleware\n     * @param  bool  $after\n     * @return $this\n     */\n    protected function addToMiddlewarePriorityRelative($existing, $middleware, $after = true)\n    {\n        if (! in_array($middleware, $this->middlewarePriority)) {\n            $index = $after ? 0 : count($this->middlewarePriority);\n\n            foreach ((array) $existing as $existingMiddleware) {\n                if (in_array($existingMiddleware, $this->middlewarePriority)) {\n                    $middlewareIndex = array_search($existingMiddleware, $this->middlewarePriority);\n\n                    if ($after && $middlewareIndex > $index) {\n                        $index = $middlewareIndex + 1;\n                    } elseif ($after === false && $middlewareIndex < $index) {\n                        $index = $middlewareIndex;\n                    }\n                }\n            }\n\n            if ($index === 0 && $after === false) {\n                array_unshift($this->middlewarePriority, $middleware);\n            } elseif (($after && $index === 0) || $index === count($this->middlewarePriority)) {\n                $this->middlewarePriority[] = $middleware;\n            } else {\n                array_splice($this->middlewarePriority, $index, 0, $middleware);\n            }\n        }\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Sync the current state of the middleware to the router.\n     *\n     * @return void\n     */\n    protected function syncMiddlewareToRouter()\n    {\n        $this->router->middlewarePriority = $this->middlewarePriority;\n\n        foreach ($this->middlewareGroups as $key => $middleware) {\n            $this->router->middlewareGroup($key, $middleware);\n        }\n\n        foreach (array_merge($this->routeMiddleware, $this->middlewareAliases) as $key => $middleware) {\n            $this->router->aliasMiddleware($key, $middleware);\n        }\n    }\n\n    /**\n     * Get the priority-sorted list of middleware.\n     *\n     * @return array\n     */\n    public function getMiddlewarePriority()\n    {\n        return $this->middlewarePriority;\n    }\n\n    /**\n     * Get the bootstrap classes for the application.\n     *\n     * @return array\n     */\n    protected function bootstrappers()\n    {\n        return $this->bootstrappers;\n    }\n\n    /**\n     * Report the exception to the exception handler.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function reportException(Throwable $e)\n    {\n        $this->app[ExceptionHandler::class]->report($e);\n    }\n\n    /**\n     * Render the exception to a response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function renderException($request, Throwable $e)\n    {\n        return $this->app[ExceptionHandler::class]->render($request, $e);\n    }\n\n    /**\n     * Get the application's global middleware.\n     *\n     * @return array\n     */\n    public function getGlobalMiddleware()\n    {\n        return $this->middleware;\n    }\n\n    /**\n     * Set the application's global middleware.\n     *\n     * @param  array  $middleware\n     * @return $this\n     */\n    public function setGlobalMiddleware(array $middleware)\n    {\n        $this->middleware = $middleware;\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Get the application's route middleware groups.\n     *\n     * @return array\n     */\n    public function getMiddlewareGroups()\n    {\n        return $this->middlewareGroups;\n    }\n\n    /**\n     * Set the application's middleware groups.\n     *\n     * @param  array  $groups\n     * @return $this\n     */\n    public function setMiddlewareGroups(array $groups)\n    {\n        $this->middlewareGroups = $groups;\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Get the application's route middleware aliases.\n     *\n     * @return array\n     *\n     * @deprecated\n     */\n    public function getRouteMiddleware()\n    {\n        return $this->getMiddlewareAliases();\n    }\n\n    /**\n     * Get the application's route middleware aliases.\n     *\n     * @return array\n     */\n    public function getMiddlewareAliases()\n    {\n        return array_merge($this->routeMiddleware, $this->middlewareAliases);\n    }\n\n    /**\n     * Set the application's route middleware aliases.\n     *\n     * @param  array  $aliases\n     * @return $this\n     */\n    public function setMiddlewareAliases(array $aliases)\n    {\n        $this->middlewareAliases = $aliases;\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Set the application's middleware priority.\n     *\n     * @param  array  $priority\n     * @return $this\n     */\n    public function setMiddlewarePriority(array $priority)\n    {\n        $this->middlewarePriority = $priority;\n\n        $this->syncMiddlewareToRouter();\n\n        return $this;\n    }\n\n    /**\n     * Get the Laravel application instance.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getApplication()\n    {\n        return $this->app;\n    }\n\n    /**\n     * Set the Laravel application instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication(Application $app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/MaintenanceModeBypassCookie.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http;\n\nuse Illuminate\\Support\\Carbon;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass MaintenanceModeBypassCookie\n{\n    /**\n     * Create a new maintenance mode bypass cookie.\n     *\n     * @param  string  $key\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    public static function create(string $key)\n    {\n        $expiresAt = Carbon::now()->addHours(12);\n\n        return new Cookie('laravel_maintenance', base64_encode(json_encode([\n            'expires_at' => $expiresAt->getTimestamp(),\n            'mac' => hash_hmac('sha256', $expiresAt->getTimestamp(), $key),\n        ])), $expiresAt, config('session.path'), config('session.domain'));\n    }\n\n    /**\n     * Determine if the given maintenance mode bypass cookie is valid.\n     *\n     * @param  string  $cookie\n     * @param  string  $key\n     * @return bool\n     */\n    public static function isValid(string $cookie, string $key)\n    {\n        $payload = json_decode(base64_decode($cookie), true);\n\n        return is_array($payload) &&\n            is_numeric($payload['expires_at'] ?? null) &&\n            isset($payload['mac']) &&\n            hash_equals(hash_hmac('sha256', $payload['expires_at'], $key), $payload['mac']) &&\n            (int) $payload['expires_at'] >= Carbon::now()->getTimestamp();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nclass CheckForMaintenanceMode extends PreventRequestsDuringMaintenance\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/Concerns/ExcludesPaths.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware\\Concerns;\n\ntrait ExcludesPaths\n{\n    /**\n     * Determine if the request has a URI that should be excluded.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    protected function inExceptArray($request)\n    {\n        foreach ($this->getExcludedPaths() as $except) {\n            if ($except !== '/') {\n                $except = trim($except, '/');\n            }\n\n            if ($request->fullUrlIs($except) || $request->is($except)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the URIs that should be excluded.\n     *\n     * @return array\n     */\n    public function getExcludedPaths()\n    {\n        return $this->except ?? [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\n\nclass ConvertEmptyStringsToNull extends TransformsRequest\n{\n    /**\n     * All of the registered skip callbacks.\n     *\n     * @var array\n     */\n    protected static $skipCallbacks = [];\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        foreach (static::$skipCallbacks as $callback) {\n            if ($callback($request)) {\n                return $next($request);\n            }\n        }\n\n        return parent::handle($request, $next);\n    }\n\n    /**\n     * Transform the given value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function transform($key, $value)\n    {\n        return $value === '' ? null : $value;\n    }\n\n    /**\n     * Register a callback that instructs the middleware to be skipped.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function skipWhen(Closure $callback)\n    {\n        static::$skipCallbacks[] = $callback;\n    }\n\n    /**\n     * Flush the middleware's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$skipCallbacks = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/HandlePrecognitiveRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Foundation\\Routing\\PrecognitionCallableDispatcher;\nuse Illuminate\\Foundation\\Routing\\PrecognitionControllerDispatcher;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\n\nclass HandlePrecognitiveRequests\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function handle($request, $next)\n    {\n        if (! $request->isAttemptingPrecognition()) {\n            return $this->appendVaryHeader($request, $next($request));\n        }\n\n        $bindings = $this->container->getBindings();\n        $callableBinding = $bindings[CallableDispatcherContract::class] ?? null;\n        $controllerBinding = $bindings[ControllerDispatcherContract::class] ?? null;\n\n        $this->prepareForPrecognition($request);\n\n        return tap($next($request), function ($response) use ($request, $callableBinding, $controllerBinding) {\n            $response->headers->set('Precognition', 'true');\n\n            $this->appendVaryHeader($request, $response);\n\n            $this->restoreDispatchers($callableBinding, $controllerBinding);\n        });\n    }\n\n    /**\n     * Prepare to handle a precognitive request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function prepareForPrecognition($request)\n    {\n        $request->attributes->set('precognitive', true);\n\n        $this->container->bind(CallableDispatcherContract::class, fn ($app) => new PrecognitionCallableDispatcher($app));\n        $this->container->bind(ControllerDispatcherContract::class, fn ($app) => new PrecognitionControllerDispatcher($app));\n    }\n\n    /**\n     * Append the appropriate \"Vary\" header to the given response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\Response  $response\n     * @return \\Illuminate\\Http\\Response\n     */\n    protected function appendVaryHeader($request, $response)\n    {\n        return tap($response, fn () => $response->headers->set('Vary', implode(', ', array_filter([\n            $response->headers->get('Vary'),\n            'Precognition',\n        ]))));\n    }\n\n    /**\n     * Restore the original route dispatcher bindings.\n     *\n     * @param  array|null  $callableBinding\n     * @param  array|null  $controllerBinding\n     * @return void\n     */\n    protected function restoreDispatchers($callableBinding, $controllerBinding)\n    {\n        if ($callableBinding) {\n            $this->container->bind(CallableDispatcherContract::class, $callableBinding['concrete'], $callableBinding['shared']);\n        }\n\n        if ($controllerBinding) {\n            $this->container->bind(ControllerDispatcherContract::class, $controllerBinding['concrete'], $controllerBinding['shared']);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass InvokeDeferredCallbacks\n{\n    /**\n     * Handle the incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function handle(Request $request, Closure $next)\n    {\n        return $next($request);\n    }\n\n    /**\n     * Invoke the deferred callbacks.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @return void\n     */\n    public function terminate(Request $request, Response $response)\n    {\n        Container::getInstance()\n            ->make(DeferredCallbackCollection::class)\n            ->invokeWhen(fn ($callback) => $response->getStatusCode() < 400 || $callback->always);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/PreventRequestForgery.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Cookie\\Middleware\\EncryptCookies;\nuse Illuminate\\Foundation\\Http\\Middleware\\Concerns\\ExcludesPaths;\nuse Illuminate\\Http\\Exceptions\\OriginMismatchException;\nuse Illuminate\\Session\\TokenMismatchException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass PreventRequestForgery\n{\n    use ExcludesPaths,\n        InteractsWithTime;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The encrypter implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Encryption\\Encrypter\n     */\n    protected $encrypter;\n\n    /**\n     * The URIs that should be excluded.\n     *\n     * @var array<int, string>\n     */\n    protected $except = [];\n\n    /**\n     * The globally ignored URIs that should be excluded from CSRF verification.\n     *\n     * @var array\n     */\n    protected static $neverVerify = [];\n\n    /**\n     * Indicates whether the XSRF-TOKEN cookie should be set on the response.\n     *\n     * @var bool\n     */\n    protected $addHttpCookie = true;\n\n    /**\n     * Indicates whether requests from the same site should be allowed.\n     *\n     * @var bool\n     */\n    protected static $allowSameSite = false;\n\n    /**\n     * Indicates whether only origin verification should be used.\n     *\n     * @var bool\n     */\n    protected static $originOnly = false;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Contracts\\Encryption\\Encrypter  $encrypter\n     */\n    public function __construct(Application $app, Encrypter $encrypter)\n    {\n        $this->app = $app;\n        $this->encrypter = $encrypter;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Session\\TokenMismatchException\n     * @throws \\Illuminate\\Http\\Exceptions\\OriginMismatchException\n     */\n    public function handle($request, Closure $next)\n    {\n        if (\n            $this->isReading($request) ||\n            $this->runningUnitTests() ||\n            $this->inExceptArray($request) ||\n            $this->hasValidOrigin($request) ||\n            $this->tokensMatch($request)\n        ) {\n            return tap($next($request), function ($response) use ($request) {\n                if ($this->shouldAddXsrfTokenCookie()) {\n                    $this->addCookieToResponse($request, $response);\n                }\n            });\n        }\n\n        throw new TokenMismatchException('CSRF token mismatch.');\n    }\n\n    /**\n     * Determine if the HTTP request uses a ‘read’ verb.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    protected function isReading($request)\n    {\n        return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);\n    }\n\n    /**\n     * Determine if the application is running unit tests.\n     *\n     * @return bool\n     */\n    protected function runningUnitTests()\n    {\n        return $this->app->runningInConsole() && $this->app->runningUnitTests();\n    }\n\n    /**\n     * Determine if the request has a valid origin based on the Sec-Fetch-Site header.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\OriginMismatchException\n     */\n    protected function hasValidOrigin($request)\n    {\n        $secFetchSite = $request->header('Sec-Fetch-Site');\n\n        if ($secFetchSite === 'same-origin') {\n            return true;\n        }\n\n        if ($secFetchSite === 'same-site' && static::$allowSameSite) {\n            return true;\n        }\n\n        if (static::$originOnly) {\n            throw new OriginMismatchException('Origin mismatch.');\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the session and input CSRF tokens match.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    protected function tokensMatch($request)\n    {\n        $token = $this->getTokenFromRequest($request);\n\n        return is_string($request->session()->token()) &&\n               is_string($token) &&\n               hash_equals($request->session()->token(), $token);\n    }\n\n    /**\n     * Get the CSRF token from the request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return string|null\n     */\n    protected function getTokenFromRequest($request)\n    {\n        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');\n\n        if (! $token && $header = $request->header('X-XSRF-TOKEN')) {\n            try {\n                $token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));\n            } catch (DecryptException) {\n                $token = '';\n            }\n        }\n\n        return $token;\n    }\n\n    /**\n     * Determine if the cookie should be added to the response.\n     *\n     * @return bool\n     */\n    public function shouldAddXsrfTokenCookie()\n    {\n        if (static::$originOnly) {\n            return false;\n        }\n\n        return $this->addHttpCookie;\n    }\n\n    /**\n     * Add the CSRF token to the response cookies.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function addCookieToResponse($request, $response)\n    {\n        $config = config('session');\n\n        if ($response instanceof Responsable) {\n            $response = $response->toResponse($request);\n        }\n\n        $response->headers->setCookie($this->newCookie($request, $config));\n\n        return $response;\n    }\n\n    /**\n     * Create a new \"XSRF-TOKEN\" cookie that contains the CSRF token.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $config\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie\n     */\n    protected function newCookie($request, $config)\n    {\n        return new Cookie(\n            'XSRF-TOKEN',\n            $request->session()->token(),\n            $this->availableAt(60 * $config['lifetime']),\n            $config['path'],\n            $config['domain'],\n            $config['secure'],\n            false,\n            false,\n            $config['same_site'] ?? null,\n            $config['partitioned'] ?? false\n        );\n    }\n\n    /**\n     * Indicate that the given URIs should be excluded from CSRF verification.\n     *\n     * @param  array|string  $uris\n     * @return void\n     */\n    public static function except($uris)\n    {\n        static::$neverVerify = array_values(array_unique(\n            array_merge(static::$neverVerify, Arr::wrap($uris))\n        ));\n    }\n\n    /**\n     * Indicate that requests from the same site should be allowed.\n     *\n     * @param  bool  $allow\n     * @return void\n     */\n    public static function allowSameSite($allow = true)\n    {\n        static::$allowSameSite = $allow;\n    }\n\n    /**\n     * Indicate that only origin verification should be used.\n     *\n     * @param  bool  $originOnly\n     * @return void\n     */\n    public static function useOriginOnly($originOnly = true)\n    {\n        static::$originOnly = $originOnly;\n    }\n\n    /**\n     * Get the URIs that should be excluded.\n     *\n     * @return array\n     */\n    public function getExcludedPaths()\n    {\n        return array_merge($this->except, static::$neverVerify);\n    }\n\n    /**\n     * Determine if the cookie contents should be serialized.\n     *\n     * @return bool\n     */\n    public static function serialized()\n    {\n        return EncryptCookies::serialized('XSRF-TOKEN');\n    }\n\n    /**\n     * Flush the state of the middleware.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$neverVerify = [];\n        static::$allowSameSite = false;\n        static::$originOnly = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\nuse ErrorException;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Foundation\\Http\\MaintenanceModeBypassCookie;\nuse Illuminate\\Foundation\\Http\\Middleware\\Concerns\\ExcludesPaths;\nuse Illuminate\\Support\\Arr;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass PreventRequestsDuringMaintenance\n{\n    use ExcludesPaths;\n\n    /**\n     * The application implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The URIs that should be excluded.\n     *\n     * @var array<int, string>\n     */\n    protected $except = [];\n\n    /**\n     * The URIs that should be accessible during maintenance.\n     *\n     * @var array\n     */\n    protected static $neverPrevent = [];\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct(Application $app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     * @throws \\ErrorException\n     */\n    public function handle($request, Closure $next)\n    {\n        if ($this->inExceptArray($request)) {\n            return $next($request);\n        }\n\n        if ($this->app->maintenanceMode()->active()) {\n            try {\n                $data = $this->app->maintenanceMode()->data();\n            } catch (ErrorException $exception) {\n                if (! $this->app->maintenanceMode()->active()) {\n                    return $next($request);\n                }\n\n                throw $exception;\n            }\n\n            if (isset($data['secret']) && $request->path() === $data['secret']) {\n                return $this->bypassResponse($data['secret']);\n            }\n\n            if ($this->hasValidBypassCookie($request, $data)) {\n                return $next($request);\n            }\n\n            if (isset($data['redirect'])) {\n                $path = $data['redirect'] === '/'\n                    ? $data['redirect']\n                    : trim($data['redirect'], '/');\n\n                if ($request->path() !== $path) {\n                    return redirect($path);\n                }\n            }\n\n            if (isset($data['template'])) {\n                return response(\n                    $data['template'],\n                    $data['status'] ?? 503,\n                    $this->getHeaders($data)\n                );\n            }\n\n            throw new HttpException(\n                $data['status'] ?? 503,\n                'Service Unavailable',\n                null,\n                $this->getHeaders($data)\n            );\n        }\n\n        return $next($request);\n    }\n\n    /**\n     * Determine if the incoming request has a maintenance mode bypass cookie.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $data\n     * @return bool\n     */\n    protected function hasValidBypassCookie($request, array $data)\n    {\n        return isset($data['secret']) &&\n                $request->cookie('laravel_maintenance') &&\n                MaintenanceModeBypassCookie::isValid(\n                    $request->cookie('laravel_maintenance'),\n                    $data['secret']\n                );\n    }\n\n    /**\n     * Redirect the user to their intended destination with a maintenance mode bypass cookie.\n     *\n     * @param  string  $secret\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    protected function bypassResponse(string $secret)\n    {\n        return redirect()->intended('/')->withCookie(\n            MaintenanceModeBypassCookie::create($secret)\n        );\n    }\n\n    /**\n     * Get the headers that should be sent with the response.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function getHeaders($data)\n    {\n        $headers = isset($data['retry']) ? ['Retry-After' => $data['retry']] : [];\n\n        if (isset($data['refresh'])) {\n            $headers['Refresh'] = $data['refresh'];\n        }\n\n        return $headers;\n    }\n\n    /**\n     * Get the URIs that should be excluded.\n     *\n     * @return array\n     */\n    public function getExcludedPaths()\n    {\n        return array_merge($this->except, static::$neverPrevent);\n    }\n\n    /**\n     * Indicate that the given URIs should always be accessible.\n     *\n     * @param  array|string  $uris\n     * @return void\n     */\n    public static function except($uris)\n    {\n        static::$neverPrevent = array_values(array_unique(\n            array_merge(static::$neverPrevent, Arr::wrap($uris))\n        ));\n    }\n\n    /**\n     * Flush the state of the middleware.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$neverPrevent = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\nuse Symfony\\Component\\HttpFoundation\\ParameterBag;\n\nclass TransformsRequest\n{\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        $this->clean($request);\n\n        return $next($request);\n    }\n\n    /**\n     * Clean the request's data.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function clean($request)\n    {\n        $this->cleanParameterBag($request->query);\n\n        if ($request->isJson()) {\n            $this->cleanParameterBag($request->json());\n        } elseif ($request->request !== $request->query) {\n            $this->cleanParameterBag($request->request);\n        }\n    }\n\n    /**\n     * Clean the data in the parameter bag.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\ParameterBag  $bag\n     * @return void\n     */\n    protected function cleanParameterBag(ParameterBag $bag)\n    {\n        $bag->replace($this->cleanArray($bag->all()));\n    }\n\n    /**\n     * Clean the data in the given array.\n     *\n     * @param  array  $data\n     * @param  string  $keyPrefix\n     * @return array\n     */\n    protected function cleanArray(array $data, $keyPrefix = '')\n    {\n        foreach ($data as $key => $value) {\n            $data[$key] = $this->cleanValue($keyPrefix.$key, $value);\n        }\n\n        return $data;\n    }\n\n    /**\n     * Clean the given value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function cleanValue($key, $value)\n    {\n        if (is_array($value)) {\n            return $this->cleanArray($value, $key.'.');\n        }\n\n        return $this->transform($key, $value);\n    }\n\n    /**\n     * Transform the given value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function transform($key, $value)\n    {\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\n\nclass TrimStrings extends TransformsRequest\n{\n    /**\n     * The attributes that should not be trimmed.\n     *\n     * @var array<int, string>\n     */\n    protected $except = [\n        'current_password',\n        'password',\n        'password_confirmation',\n    ];\n\n    /**\n     * The globally ignored attributes that should not be trimmed.\n     *\n     * @var array\n     */\n    protected static $neverTrim = [];\n\n    /**\n     * All of the registered skip callbacks.\n     *\n     * @var array\n     */\n    protected static $skipCallbacks = [];\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        foreach (static::$skipCallbacks as $callback) {\n            if ($callback($request)) {\n                return $next($request);\n            }\n        }\n\n        return parent::handle($request, $next);\n    }\n\n    /**\n     * Transform the given value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function transform($key, $value)\n    {\n        $except = array_merge($this->except, static::$neverTrim);\n\n        if ($this->shouldSkip($key, $except) || ! is_string($value)) {\n            return $value;\n        }\n\n        return Str::trim($value);\n    }\n\n    /**\n     * Determine if the given key should be skipped.\n     *\n     * @param  string  $key\n     * @param  array  $except\n     * @return bool\n     */\n    protected function shouldSkip($key, $except)\n    {\n        return Str::is($except, $key);\n    }\n\n    /**\n     * Indicate that the given attributes should never be trimmed.\n     *\n     * @param  array|string  $attributes\n     * @return void\n     */\n    public static function except($attributes)\n    {\n        static::$neverTrim = array_values(array_unique(\n            array_merge(static::$neverTrim, Arr::wrap($attributes))\n        ));\n    }\n\n    /**\n     * Register a callback that instructs the middleware to be skipped.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function skipWhen(Closure $callback)\n    {\n        static::$skipCallbacks[] = $callback;\n    }\n\n    /**\n     * Flush the middleware's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$neverTrim = [];\n\n        static::$skipCallbacks = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/ValidateCsrfToken.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\n/**\n * @deprecated Use PreventRequestForgery instead.\n */\nclass ValidateCsrfToken extends PreventRequestForgery\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Http\\Middleware\\ValidatePostSize as Middleware;\n\nclass ValidatePostSize extends Middleware\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Http\\Middleware;\n\n/**\n * @deprecated Use PreventRequestForgery instead.\n */\nclass VerifyCsrfToken extends PreventRequestForgery\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Inspiring.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Stringable;\n\n/*\n                                                   .~))>>\n                                                  .~)>>\n                                                .~))))>>>\n                                              .~))>>             ___\n                                            .~))>>)))>>      .-~))>>\n                                          .~)))))>>       .-~))>>)>\n                                        .~)))>>))))>>  .-~)>>)>\n                    )                 .~))>>))))>>  .-~)))))>>)>\n                 ( )@@*)             //)>))))))  .-~))))>>)>\n               ).@(@@               //))>>))) .-~))>>)))))>>)>\n             (( @.@).              //))))) .-~)>>)))))>>)>\n           ))  )@@*.@@ )          //)>))) //))))))>>))))>>)>\n        ((  ((@@@.@@             |/))))) //)))))>>)))>>)>\n       )) @@*. )@@ )   (\\_(\\-\\b  |))>)) //)))>>)))))))>>)>\n     (( @@@(.@(@ .    _/`-`  ~|b |>))) //)>>)))))))>>)>\n      )* @@@ )@*     (@)  (@) /\\b|))) //))))))>>))))>>\n    (( @. )@( @ .   _/  /    /  \\b)) //))>>)))))>>>_._\n     )@@ (@@*)@@.  (6///6)- / ^  \\b)//))))))>>)))>>   ~~-.\n  ( @jgs@@. @@@.*@_ VvvvvV//  ^  \\b/)>>))))>>      _.     `bb\n   ((@@ @@@*.(@@ . - | o |' \\ (  ^   \\b)))>>        .'       b`,\n    ((@@).*@@ )@ )   \\^^^/  ((   ^  ~)_        \\  /           b `,\n      (@@. (@@ ).     `-'   (((   ^    `\\ \\ \\ \\ \\|             b  `.\n        (*.@*              / ((((        \\| | |  \\       .       b `.\n                          / / (((((  \\    \\ /  _.-~\\     Y,      b  ;\n                         / / / (((((( \\    \\.-~   _.`\" _.-~`,    b  ;\n                        /   /   `(((((()    )    (((((~      `,  b  ;\n                      _/  _/      `\"\"\"/   /'                  ; b   ;\n                  _.-~_.-~           /  /'                _.'~bb _.'\n                ((((~~              / /'              _.'~bb.--~\n                                   ((((          __.-~bb.-~\n                                               .'  b .~~\n                                               :bb ,'\n                                               ~~~~\n */\n\nclass Inspiring\n{\n    /**\n     * Get an inspiring quote.\n     *\n     * Taylor & Dayle made this commit from Jungfraujoch. (11,333 ft.)\n     *\n     * May McGinnis always control the board. #LaraconUS2015\n     *\n     * RIP Charlie - Feb 6, 2018\n     *\n     * @return string\n     */\n    public static function quote()\n    {\n        return static::formatForConsole(static::quotes()->random());\n    }\n\n    /**\n     * Get the collection of inspiring quotes.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public static function quotes()\n    {\n        return new Collection([\n            'Act only according to that maxim whereby you can, at the same time, will that it should become a universal law. - Immanuel Kant',\n            'An unexamined life is not worth living. - Socrates',\n            'Be present above all else. - Naval Ravikant',\n            'Do what you can, with what you have, where you are. - Theodore Roosevelt',\n            'Happiness is not something readymade. It comes from your own actions. - Dalai Lama',\n            'He who is contented is rich. - Laozi',\n            'I begin to speak only when I am certain what I will say is not better left unsaid. - Cato the Younger',\n            'I have not failed. I\\'ve just found 10,000 ways that won\\'t work. - Thomas Edison',\n            'If you do not have a consistent goal in life, you can not live it in a consistent way. - Marcus Aurelius',\n            'It is never too late to be what you might have been. - George Eliot',\n            'It is not the man who has too little, but the man who craves more, that is poor. - Seneca',\n            'It is quality rather than quantity that matters. - Lucius Annaeus Seneca',\n            'Knowing is not enough; we must apply. Being willing is not enough; we must do. - Leonardo da Vinci',\n            'Let all your things have their places; let each part of your business have its time. - Benjamin Franklin',\n            'Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi',\n            'No surplus words or unnecessary actions. - Marcus Aurelius',\n            'Nothing worth having comes easy. - Theodore Roosevelt',\n            'Order your soul. Reduce your wants. - Augustine',\n            'People find pleasure in different ways. I find it in keeping my mind clear. - Marcus Aurelius',\n            'Simplicity is an acquired taste. - Katharine Gerould',\n            'Simplicity is the consequence of refined emotions. - Jean D\\'Alembert',\n            'Simplicity is the essence of happiness. - Cedric Bledsoe',\n            'Simplicity is the ultimate sophistication. - Leonardo da Vinci',\n            'Smile, breathe, and go slowly. - Thich Nhat Hanh',\n            'The only way to do great work is to love what you do. - Steve Jobs',\n            'The whole future lies in uncertainty: live immediately. - Seneca',\n            'Very little is needed to make a happy life. - Marcus Aurelius',\n            'Waste no more time arguing what a good man should be, be one. - Marcus Aurelius',\n            'Well begun is half done. - Aristotle',\n            'When there is no desire, all things are at peace. - Laozi',\n            'Walk as if you are kissing the Earth with your feet. - Thich Nhat Hanh',\n            'Because you are alive, everything is possible. - Thich Nhat Hanh',\n            'Breathing in, I calm body and mind. Breathing out, I smile. - Thich Nhat Hanh',\n            'Life is available only in the present moment. - Thich Nhat Hanh',\n            'The best way to take care of the future is to take care of the present moment. - Thich Nhat Hanh',\n            'Nothing in life is to be feared, it is only to be understood. Now is the time to understand more, so that we may fear less. - Maria Skłodowska-Curie',\n            'The biggest battle is the war against ignorance. - Mustafa Kemal Atatürk',\n            'Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead',\n            'You must be the change you wish to see in the world. - Mahatma Gandhi',\n            'It always seems impossible until it is done. - Nelson Mandela',\n            'We must ship. - Taylor Otwell',\n        ]);\n    }\n\n    /**\n     * Formats the given quote for a pretty console output.\n     *\n     * @param  string  $quote\n     * @return string\n     */\n    protected static function formatForConsole($quote)\n    {\n        [$text, $author] = (new Stringable($quote))->explode('-');\n\n        return sprintf(\n            \"\\n  <options=bold>“ %s ”</>\\n  <fg=gray>— %s</>\\n\",\n            trim($text),\n            trim($author),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/MaintenanceModeManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Support\\Manager;\n\nclass MaintenanceModeManager extends Manager\n{\n    /**\n     * Create an instance of the file based maintenance driver.\n     *\n     * @return \\Illuminate\\Foundation\\FileBasedMaintenanceMode\n     */\n    protected function createFileDriver(): FileBasedMaintenanceMode\n    {\n        return new FileBasedMaintenanceMode();\n    }\n\n    /**\n     * Create an instance of the cache based maintenance driver.\n     *\n     * @return \\Illuminate\\Foundation\\CacheBasedMaintenanceMode\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function createCacheDriver(): CacheBasedMaintenanceMode\n    {\n        return new CacheBasedMaintenanceMode(\n            $this->container->make('cache'),\n            $this->config->get('app.maintenance.store') ?: $this->config->get('cache.default'),\n            'illuminate:foundation:down'\n        );\n    }\n\n    /**\n     * Get the default driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver(): string\n    {\n        return $this->config->get('app.maintenance.driver', 'file');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Mix.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Str;\n\nclass Mix\n{\n    /**\n     * Get the path to a versioned Mix file.\n     *\n     * @param  string  $path\n     * @param  string  $manifestDirectory\n     * @return \\Illuminate\\Support\\HtmlString|string\n     *\n     * @throws \\Illuminate\\Foundation\\MixManifestNotFoundException|\\Illuminate\\Foundation\\MixFileNotFoundException\n     */\n    public function __invoke($path, $manifestDirectory = '')\n    {\n        static $manifests = [];\n\n        if (! str_starts_with($path, '/')) {\n            $path = \"/{$path}\";\n        }\n\n        if ($manifestDirectory && ! str_starts_with($manifestDirectory, '/')) {\n            $manifestDirectory = \"/{$manifestDirectory}\";\n        }\n\n        if (is_file(public_path($manifestDirectory.'/hot'))) {\n            $url = rtrim(file_get_contents(public_path($manifestDirectory.'/hot')));\n\n            $customUrl = app('config')->get('app.mix_hot_proxy_url');\n\n            if (! empty($customUrl)) {\n                return new HtmlString(\"{$customUrl}{$path}\");\n            }\n\n            if (Str::startsWith($url, ['http://', 'https://'])) {\n                return new HtmlString(Str::after($url, ':').$path);\n            }\n\n            return new HtmlString(\"//localhost:8080{$path}\");\n        }\n\n        $manifestPath = public_path($manifestDirectory.'/mix-manifest.json');\n\n        if (! isset($manifests[$manifestPath])) {\n            if (! is_file($manifestPath)) {\n                throw new MixManifestNotFoundException(\"Mix manifest not found at: {$manifestPath}\");\n            }\n\n            $manifests[$manifestPath] = json_decode(file_get_contents($manifestPath), true);\n        }\n\n        $manifest = $manifests[$manifestPath];\n\n        if (! isset($manifest[$path])) {\n            $exception = new MixFileNotFoundException(\"Unable to locate Mix file: {$path}.\");\n\n            if (! app('config')->get('app.debug')) {\n                report($exception);\n\n                return $path;\n            } else {\n                throw $exception;\n            }\n        }\n\n        return new HtmlString(app('config')->get('app.mix_url').$manifestDirectory.$manifest[$path]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/MixFileNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Exception;\n\nclass MixFileNotFoundException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/MixManifestNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Exception;\n\nclass MixManifestNotFoundException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/PackageManifest.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Exception;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Env;\n\nclass PackageManifest\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    public $files;\n\n    /**\n     * The base path.\n     *\n     * @var string\n     */\n    public $basePath;\n\n    /**\n     * The vendor path.\n     *\n     * @var string\n     */\n    public $vendorPath;\n\n    /**\n     * The manifest path.\n     *\n     * @var string|null\n     */\n    public $manifestPath;\n\n    /**\n     * The loaded manifest array.\n     *\n     * @var array\n     */\n    public $manifest;\n\n    /**\n     * Create a new package manifest instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $basePath\n     * @param  string  $manifestPath\n     */\n    public function __construct(Filesystem $files, $basePath, $manifestPath)\n    {\n        $this->files = $files;\n        $this->basePath = $basePath;\n        $this->manifestPath = $manifestPath;\n        $this->vendorPath = Env::get('COMPOSER_VENDOR_DIR') ?: $basePath.'/vendor';\n    }\n\n    /**\n     * Get all of the service provider class names for all packages.\n     *\n     * @return array\n     */\n    public function providers()\n    {\n        return $this->config('providers');\n    }\n\n    /**\n     * Get all of the aliases for all packages.\n     *\n     * @return array\n     */\n    public function aliases()\n    {\n        return $this->config('aliases');\n    }\n\n    /**\n     * Get all of the values for all packages for the given configuration name.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    public function config($key)\n    {\n        return (new Collection($this->getManifest()))\n            ->flatMap(fn ($configuration) => (array) ($configuration[$key] ?? []))\n            ->filter()\n            ->all();\n    }\n\n    /**\n     * Get the current package manifest.\n     *\n     * @return array\n     */\n    protected function getManifest()\n    {\n        if (! is_null($this->manifest)) {\n            return $this->manifest;\n        }\n\n        if (! is_file($this->manifestPath)) {\n            $this->build();\n        }\n\n        return $this->manifest = is_file($this->manifestPath) ?\n            $this->files->getRequire($this->manifestPath) : [];\n    }\n\n    /**\n     * Build the manifest and write it to disk.\n     *\n     * @return void\n     */\n    public function build()\n    {\n        $packages = [];\n\n        if ($this->files->exists($path = $this->vendorPath.'/composer/installed.json')) {\n            $installed = json_decode($this->files->get($path), true);\n\n            $packages = $installed['packages'] ?? $installed;\n        }\n\n        $ignoreAll = in_array('*', $ignore = $this->packagesToIgnore());\n\n        $this->write((new Collection($packages))->mapWithKeys(function ($package) {\n            return [$this->format($package['name']) => $package['extra']['laravel'] ?? []];\n        })->each(function ($configuration) use (&$ignore) {\n            $ignore = array_merge($ignore, $configuration['dont-discover'] ?? []);\n        })->reject(function ($configuration, $package) use ($ignore, $ignoreAll) {\n            return $ignoreAll || in_array($package, $ignore);\n        })->filter()->all());\n    }\n\n    /**\n     * Format the given package name.\n     *\n     * @param  string  $package\n     * @return string\n     */\n    protected function format($package)\n    {\n        return str_replace($this->vendorPath.'/', '', $package);\n    }\n\n    /**\n     * Get all of the package names that should be ignored.\n     *\n     * @return array\n     */\n    protected function packagesToIgnore()\n    {\n        if (! is_file($this->basePath.'/composer.json')) {\n            return [];\n        }\n\n        return json_decode(file_get_contents(\n            $this->basePath.'/composer.json'\n        ), true)['extra']['laravel']['dont-discover'] ?? [];\n    }\n\n    /**\n     * Write the given manifest array to disk.\n     *\n     * @param  array  $manifest\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    protected function write(array $manifest)\n    {\n        if (! is_writable($dirname = dirname($this->manifestPath))) {\n            throw new Exception(\"The {$dirname} directory must be present and writable.\");\n        }\n\n        $this->files->replace(\n            $this->manifestPath, '<?php return '.var_export($manifest, true).';'\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Precognition.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nclass Precognition\n{\n    /**\n     * Get the \"after\" validation hook that can be used for precognition requests.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Closure\n     */\n    public static function afterValidationHook($request)\n    {\n        return function ($validator) use ($request) {\n            if ($validator->messages()->isEmpty() && $request->headers->has('Precognition-Validate-Only')) {\n                abort(204, headers: ['Precognition-Success' => 'true']);\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/ProviderRepository.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Exception;\nuse Illuminate\\Contracts\\Foundation\\Application as ApplicationContract;\nuse Illuminate\\Filesystem\\Filesystem;\n\nclass ProviderRepository\n{\n    /**\n     * The application implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The path to the manifest file.\n     *\n     * @var string\n     */\n    protected $manifestPath;\n\n    /**\n     * Create a new service repository instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $manifestPath\n     */\n    public function __construct(ApplicationContract $app, Filesystem $files, $manifestPath)\n    {\n        $this->app = $app;\n        $this->files = $files;\n        $this->manifestPath = $manifestPath;\n    }\n\n    /**\n     * Register the application service providers.\n     *\n     * @param  array  $providers\n     * @return void\n     */\n    public function load(array $providers)\n    {\n        $manifest = $this->loadManifest();\n\n        // First we will load the service manifest, which contains information on all\n        // service providers registered with the application and which services it\n        // provides. This is used to know which services are \"deferred\" loaders.\n        if ($this->shouldRecompile($manifest, $providers)) {\n            $manifest = $this->compileManifest($providers);\n        }\n\n        // Next, we will register events to load the providers for each of the events\n        // that it has requested. This allows the service provider to defer itself\n        // while still getting automatically loaded when a certain event occurs.\n        foreach ($manifest['when'] as $provider => $events) {\n            $this->registerLoadEvents($provider, $events);\n        }\n\n        // We will go ahead and register all of the eagerly loaded providers with the\n        // application so their services can be registered with the application as\n        // a provided service. Then we will set the deferred service list on it.\n        foreach ($manifest['eager'] as $provider) {\n            $this->app->register($provider);\n        }\n\n        $this->app->addDeferredServices($manifest['deferred']);\n    }\n\n    /**\n     * Load the service provider manifest JSON file.\n     *\n     * @return array|null\n     */\n    public function loadManifest()\n    {\n        // The service manifest is a file containing a JSON representation of every\n        // service provided by the application and whether its provider is using\n        // deferred loading or should be eagerly loaded on each request to us.\n        if ($this->files->exists($this->manifestPath)) {\n            $manifest = $this->files->getRequire($this->manifestPath);\n\n            if ($manifest) {\n                return array_merge(['when' => []], $manifest);\n            }\n        }\n    }\n\n    /**\n     * Determine if the manifest should be compiled.\n     *\n     * @param  array  $manifest\n     * @param  array  $providers\n     * @return bool\n     */\n    public function shouldRecompile($manifest, $providers)\n    {\n        return is_null($manifest) || $manifest['providers'] != $providers;\n    }\n\n    /**\n     * Register the load events for the given provider.\n     *\n     * @param  string  $provider\n     * @param  array  $events\n     * @return void\n     */\n    protected function registerLoadEvents($provider, array $events)\n    {\n        if (count($events) < 1) {\n            return;\n        }\n\n        $this->app->make('events')->listen($events, fn () => $this->app->register($provider));\n    }\n\n    /**\n     * Compile the application service manifest file.\n     *\n     * @param  array  $providers\n     * @return array\n     */\n    protected function compileManifest($providers)\n    {\n        // The service manifest should contain a list of all of the providers for\n        // the application so we can compare it on each request to the service\n        // and determine if the manifest should be recompiled or is current.\n        $manifest = $this->freshManifest($providers);\n\n        foreach ($providers as $provider) {\n            $instance = $this->createProvider($provider);\n\n            // When recompiling the service manifest, we will spin through each of the\n            // providers and check if it's a deferred provider or not. If so we'll\n            // add it's provided services to the manifest and note the provider.\n            if ($instance->isDeferred()) {\n                foreach ($instance->provides() as $service) {\n                    $manifest['deferred'][$service] = $provider;\n                }\n\n                $manifest['when'][$provider] = $instance->when();\n            }\n\n            // If the service providers are not deferred, we will simply add it to an\n            // array of eagerly loaded providers that will get registered on every\n            // request to this application instead of \"lazy\" loading every time.\n            else {\n                $manifest['eager'][] = $provider;\n            }\n        }\n\n        return $this->writeManifest($manifest);\n    }\n\n    /**\n     * Create a fresh service manifest data structure.\n     *\n     * @param  array  $providers\n     * @return array\n     */\n    protected function freshManifest(array $providers)\n    {\n        return ['providers' => $providers, 'eager' => [], 'deferred' => []];\n    }\n\n    /**\n     * Write the service manifest file to disk.\n     *\n     * @param  array  $manifest\n     * @return array\n     *\n     * @throws \\Exception\n     */\n    public function writeManifest($manifest)\n    {\n        if (! is_writable($dirname = dirname($this->manifestPath))) {\n            throw new Exception(\"The {$dirname} directory must be present and writable.\");\n        }\n\n        $this->files->replace(\n            $this->manifestPath, '<?php return '.var_export($manifest, true).';'\n        );\n\n        return array_merge(['when' => []], $manifest);\n    }\n\n    /**\n     * Create a new provider instance.\n     *\n     * @param  string  $provider\n     * @return \\Illuminate\\Support\\ServiceProvider\n     */\n    public function createProvider($provider)\n    {\n        return new $provider($this->app);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Providers;\n\nuse Illuminate\\Auth\\Console\\ClearResetsCommand;\nuse Illuminate\\Cache\\Console\\CacheTableCommand;\nuse Illuminate\\Cache\\Console\\ClearCommand as CacheClearCommand;\nuse Illuminate\\Cache\\Console\\ForgetCommand as CacheForgetCommand;\nuse Illuminate\\Cache\\Console\\PruneStaleTagsCommand;\nuse Illuminate\\Concurrency\\Console\\InvokeSerializedClosureCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleClearCacheCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleFinishCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleInterruptCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleListCommand;\nuse Illuminate\\Console\\Scheduling\\SchedulePauseCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleResumeCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleRunCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleTestCommand;\nuse Illuminate\\Console\\Scheduling\\ScheduleWorkCommand;\nuse Illuminate\\Console\\Signals;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Database\\Console\\DbCommand;\nuse Illuminate\\Database\\Console\\DumpCommand;\nuse Illuminate\\Database\\Console\\Factories\\FactoryMakeCommand;\nuse Illuminate\\Database\\Console\\MonitorCommand as DatabaseMonitorCommand;\nuse Illuminate\\Database\\Console\\PruneCommand;\nuse Illuminate\\Database\\Console\\Seeds\\SeedCommand;\nuse Illuminate\\Database\\Console\\Seeds\\SeederMakeCommand;\nuse Illuminate\\Database\\Console\\ShowCommand;\nuse Illuminate\\Database\\Console\\ShowModelCommand;\nuse Illuminate\\Database\\Console\\TableCommand as DatabaseTableCommand;\nuse Illuminate\\Database\\Console\\WipeCommand;\nuse Illuminate\\Foundation\\Console\\AboutCommand;\nuse Illuminate\\Foundation\\Console\\ApiInstallCommand;\nuse Illuminate\\Foundation\\Console\\BroadcastingInstallCommand;\nuse Illuminate\\Foundation\\Console\\CastMakeCommand;\nuse Illuminate\\Foundation\\Console\\ChannelListCommand;\nuse Illuminate\\Foundation\\Console\\ChannelMakeCommand;\nuse Illuminate\\Foundation\\Console\\ClassMakeCommand;\nuse Illuminate\\Foundation\\Console\\ClearCompiledCommand;\nuse Illuminate\\Foundation\\Console\\ComponentMakeCommand;\nuse Illuminate\\Foundation\\Console\\ConfigCacheCommand;\nuse Illuminate\\Foundation\\Console\\ConfigClearCommand;\nuse Illuminate\\Foundation\\Console\\ConfigMakeCommand;\nuse Illuminate\\Foundation\\Console\\ConfigPublishCommand;\nuse Illuminate\\Foundation\\Console\\ConfigShowCommand;\nuse Illuminate\\Foundation\\Console\\ConsoleMakeCommand;\nuse Illuminate\\Foundation\\Console\\DocsCommand;\nuse Illuminate\\Foundation\\Console\\DownCommand;\nuse Illuminate\\Foundation\\Console\\EnumMakeCommand;\nuse Illuminate\\Foundation\\Console\\EnvironmentCommand;\nuse Illuminate\\Foundation\\Console\\EnvironmentDecryptCommand;\nuse Illuminate\\Foundation\\Console\\EnvironmentEncryptCommand;\nuse Illuminate\\Foundation\\Console\\EventCacheCommand;\nuse Illuminate\\Foundation\\Console\\EventClearCommand;\nuse Illuminate\\Foundation\\Console\\EventGenerateCommand;\nuse Illuminate\\Foundation\\Console\\EventListCommand;\nuse Illuminate\\Foundation\\Console\\EventMakeCommand;\nuse Illuminate\\Foundation\\Console\\ExceptionMakeCommand;\nuse Illuminate\\Foundation\\Console\\InterfaceMakeCommand;\nuse Illuminate\\Foundation\\Console\\JobMakeCommand;\nuse Illuminate\\Foundation\\Console\\JobMiddlewareMakeCommand;\nuse Illuminate\\Foundation\\Console\\KeyGenerateCommand;\nuse Illuminate\\Foundation\\Console\\LangPublishCommand;\nuse Illuminate\\Foundation\\Console\\ListenerMakeCommand;\nuse Illuminate\\Foundation\\Console\\MailMakeCommand;\nuse Illuminate\\Foundation\\Console\\ModelMakeCommand;\nuse Illuminate\\Foundation\\Console\\NotificationMakeCommand;\nuse Illuminate\\Foundation\\Console\\ObserverMakeCommand;\nuse Illuminate\\Foundation\\Console\\OptimizeClearCommand;\nuse Illuminate\\Foundation\\Console\\OptimizeCommand;\nuse Illuminate\\Foundation\\Console\\PackageDiscoverCommand;\nuse Illuminate\\Foundation\\Console\\PolicyMakeCommand;\nuse Illuminate\\Foundation\\Console\\ProviderMakeCommand;\nuse Illuminate\\Foundation\\Console\\ReloadCommand;\nuse Illuminate\\Foundation\\Console\\RequestMakeCommand;\nuse Illuminate\\Foundation\\Console\\ResourceMakeCommand;\nuse Illuminate\\Foundation\\Console\\RouteCacheCommand;\nuse Illuminate\\Foundation\\Console\\RouteClearCommand;\nuse Illuminate\\Foundation\\Console\\RouteListCommand;\nuse Illuminate\\Foundation\\Console\\RuleMakeCommand;\nuse Illuminate\\Foundation\\Console\\ScopeMakeCommand;\nuse Illuminate\\Foundation\\Console\\ServeCommand;\nuse Illuminate\\Foundation\\Console\\StorageLinkCommand;\nuse Illuminate\\Foundation\\Console\\StorageUnlinkCommand;\nuse Illuminate\\Foundation\\Console\\StubPublishCommand;\nuse Illuminate\\Foundation\\Console\\TestMakeCommand;\nuse Illuminate\\Foundation\\Console\\TraitMakeCommand;\nuse Illuminate\\Foundation\\Console\\UpCommand;\nuse Illuminate\\Foundation\\Console\\VendorPublishCommand;\nuse Illuminate\\Foundation\\Console\\ViewCacheCommand;\nuse Illuminate\\Foundation\\Console\\ViewClearCommand;\nuse Illuminate\\Foundation\\Console\\ViewMakeCommand;\nuse Illuminate\\Notifications\\Console\\NotificationTableCommand;\nuse Illuminate\\Queue\\Console\\BatchesTableCommand;\nuse Illuminate\\Queue\\Console\\ClearCommand as QueueClearCommand;\nuse Illuminate\\Queue\\Console\\FailedTableCommand;\nuse Illuminate\\Queue\\Console\\FlushFailedCommand as FlushFailedQueueCommand;\nuse Illuminate\\Queue\\Console\\ForgetFailedCommand as ForgetFailedQueueCommand;\nuse Illuminate\\Queue\\Console\\ListenCommand as QueueListenCommand;\nuse Illuminate\\Queue\\Console\\ListFailedCommand as ListFailedQueueCommand;\nuse Illuminate\\Queue\\Console\\MonitorCommand as QueueMonitorCommand;\nuse Illuminate\\Queue\\Console\\PauseCommand as QueuePauseCommand;\nuse Illuminate\\Queue\\Console\\PruneBatchesCommand as QueuePruneBatchesCommand;\nuse Illuminate\\Queue\\Console\\PruneFailedJobsCommand as QueuePruneFailedJobsCommand;\nuse Illuminate\\Queue\\Console\\RestartCommand as QueueRestartCommand;\nuse Illuminate\\Queue\\Console\\ResumeCommand as QueueResumeCommand;\nuse Illuminate\\Queue\\Console\\RetryBatchCommand as QueueRetryBatchCommand;\nuse Illuminate\\Queue\\Console\\RetryCommand as QueueRetryCommand;\nuse Illuminate\\Queue\\Console\\TableCommand;\nuse Illuminate\\Queue\\Console\\WorkCommand as QueueWorkCommand;\nuse Illuminate\\Routing\\Console\\ControllerMakeCommand;\nuse Illuminate\\Routing\\Console\\MiddlewareMakeCommand;\nuse Illuminate\\Session\\Console\\SessionTableCommand;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ArtisanServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * The commands to be registered.\n     *\n     * @var array\n     */\n    protected $commands = [\n        'About' => AboutCommand::class,\n        'CacheClear' => CacheClearCommand::class,\n        'CacheForget' => CacheForgetCommand::class,\n        'ClearCompiled' => ClearCompiledCommand::class,\n        'ClearResets' => ClearResetsCommand::class,\n        'ConfigCache' => ConfigCacheCommand::class,\n        'ConfigClear' => ConfigClearCommand::class,\n        'ConfigShow' => ConfigShowCommand::class,\n        'Db' => DbCommand::class,\n        'DbMonitor' => DatabaseMonitorCommand::class,\n        'DbPrune' => PruneCommand::class,\n        'DbShow' => ShowCommand::class,\n        'DbTable' => DatabaseTableCommand::class,\n        'DbWipe' => WipeCommand::class,\n        'Down' => DownCommand::class,\n        'Environment' => EnvironmentCommand::class,\n        'EnvironmentDecrypt' => EnvironmentDecryptCommand::class,\n        'EnvironmentEncrypt' => EnvironmentEncryptCommand::class,\n        'EventCache' => EventCacheCommand::class,\n        'EventClear' => EventClearCommand::class,\n        'EventList' => EventListCommand::class,\n        'InvokeSerializedClosure' => InvokeSerializedClosureCommand::class,\n        'KeyGenerate' => KeyGenerateCommand::class,\n        'Optimize' => OptimizeCommand::class,\n        'OptimizeClear' => OptimizeClearCommand::class,\n        'PackageDiscover' => PackageDiscoverCommand::class,\n        'PruneStaleTagsCommand' => PruneStaleTagsCommand::class,\n        'QueueClear' => QueueClearCommand::class,\n        'QueueFailed' => ListFailedQueueCommand::class,\n        'QueueFlush' => FlushFailedQueueCommand::class,\n        'QueueForget' => ForgetFailedQueueCommand::class,\n        'QueueListen' => QueueListenCommand::class,\n        'QueueMonitor' => QueueMonitorCommand::class,\n        'QueuePause' => QueuePauseCommand::class,\n        'QueuePruneBatches' => QueuePruneBatchesCommand::class,\n        'QueuePruneFailedJobs' => QueuePruneFailedJobsCommand::class,\n        'QueueRestart' => QueueRestartCommand::class,\n        'QueueResume' => QueueResumeCommand::class,\n        'QueueRetry' => QueueRetryCommand::class,\n        'QueueRetryBatch' => QueueRetryBatchCommand::class,\n        'QueueWork' => QueueWorkCommand::class,\n        'Reload' => ReloadCommand::class,\n        'RouteCache' => RouteCacheCommand::class,\n        'RouteClear' => RouteClearCommand::class,\n        'RouteList' => RouteListCommand::class,\n        'SchemaDump' => DumpCommand::class,\n        'Seed' => SeedCommand::class,\n        'ScheduleFinish' => ScheduleFinishCommand::class,\n        'ScheduleList' => ScheduleListCommand::class,\n        'ScheduleRun' => ScheduleRunCommand::class,\n        'ScheduleClearCache' => ScheduleClearCacheCommand::class,\n        'ScheduleTest' => ScheduleTestCommand::class,\n        'ScheduleWork' => ScheduleWorkCommand::class,\n        'ScheduleInterrupt' => ScheduleInterruptCommand::class,\n        'SchedulePause' => SchedulePauseCommand::class,\n        'ScheduleResume' => ScheduleResumeCommand::class,\n        'ShowModel' => ShowModelCommand::class,\n        'StorageLink' => StorageLinkCommand::class,\n        'StorageUnlink' => StorageUnlinkCommand::class,\n        'Up' => UpCommand::class,\n        'ViewCache' => ViewCacheCommand::class,\n        'ViewClear' => ViewClearCommand::class,\n    ];\n\n    /**\n     * The commands to be registered.\n     *\n     * @var array\n     */\n    protected $devCommands = [\n        'ApiInstall' => ApiInstallCommand::class,\n        'BroadcastingInstall' => BroadcastingInstallCommand::class,\n        'CacheTable' => CacheTableCommand::class,\n        'CastMake' => CastMakeCommand::class,\n        'ChannelList' => ChannelListCommand::class,\n        'ChannelMake' => ChannelMakeCommand::class,\n        'ClassMake' => ClassMakeCommand::class,\n        'ComponentMake' => ComponentMakeCommand::class,\n        'ConfigMake' => ConfigMakeCommand::class,\n        'ConfigPublish' => ConfigPublishCommand::class,\n        'ConsoleMake' => ConsoleMakeCommand::class,\n        'ControllerMake' => ControllerMakeCommand::class,\n        'Docs' => DocsCommand::class,\n        'EnumMake' => EnumMakeCommand::class,\n        'EventGenerate' => EventGenerateCommand::class,\n        'EventMake' => EventMakeCommand::class,\n        'ExceptionMake' => ExceptionMakeCommand::class,\n        'FactoryMake' => FactoryMakeCommand::class,\n        'InterfaceMake' => InterfaceMakeCommand::class,\n        'JobMake' => JobMakeCommand::class,\n        'JobMiddlewareMake' => JobMiddlewareMakeCommand::class,\n        'LangPublish' => LangPublishCommand::class,\n        'ListenerMake' => ListenerMakeCommand::class,\n        'MailMake' => MailMakeCommand::class,\n        'MiddlewareMake' => MiddlewareMakeCommand::class,\n        'ModelMake' => ModelMakeCommand::class,\n        'NotificationMake' => NotificationMakeCommand::class,\n        'NotificationTable' => NotificationTableCommand::class,\n        'ObserverMake' => ObserverMakeCommand::class,\n        'PolicyMake' => PolicyMakeCommand::class,\n        'ProviderMake' => ProviderMakeCommand::class,\n        'QueueFailedTable' => FailedTableCommand::class,\n        'QueueTable' => TableCommand::class,\n        'QueueBatchesTable' => BatchesTableCommand::class,\n        'RequestMake' => RequestMakeCommand::class,\n        'ResourceMake' => ResourceMakeCommand::class,\n        'RuleMake' => RuleMakeCommand::class,\n        'ScopeMake' => ScopeMakeCommand::class,\n        'SeederMake' => SeederMakeCommand::class,\n        'SessionTable' => SessionTableCommand::class,\n        'Serve' => ServeCommand::class,\n        'StubPublish' => StubPublishCommand::class,\n        'TestMake' => TestMakeCommand::class,\n        'TraitMake' => TraitMakeCommand::class,\n        'VendorPublish' => VendorPublishCommand::class,\n        'ViewMake' => ViewMakeCommand::class,\n    ];\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerCommands(array_merge(\n            $this->commands,\n            $this->devCommands\n        ));\n\n        Signals::resolveAvailabilityUsing(function () {\n            return $this->app->runningInConsole()\n                && ! $this->app->runningUnitTests()\n                && extension_loaded('pcntl');\n        });\n    }\n\n    /**\n     * Register the given commands.\n     *\n     * @return void\n     */\n    protected function registerCommands(array $commands)\n    {\n        foreach ($commands as $commandName => $command) {\n            $method = \"register{$commandName}Command\";\n\n            if (method_exists($this, $method)) {\n                $this->{$method}();\n            } else {\n                $this->app->singleton($command);\n            }\n        }\n\n        $this->commands(array_values($commands));\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerAboutCommand()\n    {\n        $this->app->singleton(AboutCommand::class, function ($app) {\n            return new AboutCommand($app['composer']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerCacheClearCommand()\n    {\n        $this->app->singleton(CacheClearCommand::class, function ($app) {\n            return new CacheClearCommand($app['cache'], $app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerCacheForgetCommand()\n    {\n        $this->app->singleton(CacheForgetCommand::class, function ($app) {\n            return new CacheForgetCommand($app['cache']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerCacheTableCommand()\n    {\n        $this->app->singleton(CacheTableCommand::class, function ($app) {\n            return new CacheTableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerCastMakeCommand()\n    {\n        $this->app->singleton(CastMakeCommand::class, function ($app) {\n            return new CastMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerChannelMakeCommand()\n    {\n        $this->app->singleton(ChannelMakeCommand::class, function ($app) {\n            return new ChannelMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerClassMakeCommand()\n    {\n        $this->app->singleton(ClassMakeCommand::class, function ($app) {\n            return new ClassMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerComponentMakeCommand()\n    {\n        $this->app->singleton(ComponentMakeCommand::class, function ($app) {\n            return new ComponentMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerConfigCacheCommand()\n    {\n        $this->app->singleton(ConfigCacheCommand::class, function ($app) {\n            return new ConfigCacheCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerConfigClearCommand()\n    {\n        $this->app->singleton(ConfigClearCommand::class, function ($app) {\n            return new ConfigClearCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerConfigMakeCommand()\n    {\n        $this->app->singleton(ConfigMakeCommand::class, function ($app) {\n            return new ConfigMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerConfigPublishCommand()\n    {\n        $this->app->singleton(ConfigPublishCommand::class, function () {\n            return new ConfigPublishCommand;\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerConsoleMakeCommand()\n    {\n        $this->app->singleton(ConsoleMakeCommand::class, function ($app) {\n            return new ConsoleMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerControllerMakeCommand()\n    {\n        $this->app->singleton(ControllerMakeCommand::class, function ($app) {\n            return new ControllerMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerEnumMakeCommand()\n    {\n        $this->app->singleton(EnumMakeCommand::class, function ($app) {\n            return new EnumMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerEventMakeCommand()\n    {\n        $this->app->singleton(EventMakeCommand::class, function ($app) {\n            return new EventMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerExceptionMakeCommand()\n    {\n        $this->app->singleton(ExceptionMakeCommand::class, function ($app) {\n            return new ExceptionMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerFactoryMakeCommand()\n    {\n        $this->app->singleton(FactoryMakeCommand::class, function ($app) {\n            return new FactoryMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerEventClearCommand()\n    {\n        $this->app->singleton(EventClearCommand::class, function ($app) {\n            return new EventClearCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerInterfaceMakeCommand()\n    {\n        $this->app->singleton(InterfaceMakeCommand::class, function ($app) {\n            return new InterfaceMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerJobMakeCommand()\n    {\n        $this->app->singleton(JobMakeCommand::class, function ($app) {\n            return new JobMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerJobMiddlewareMakeCommand()\n    {\n        $this->app->singleton(JobMiddlewareMakeCommand::class, function ($app) {\n            return new JobMiddlewareMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerListenerMakeCommand()\n    {\n        $this->app->singleton(ListenerMakeCommand::class, function ($app) {\n            return new ListenerMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMailMakeCommand()\n    {\n        $this->app->singleton(MailMakeCommand::class, function ($app) {\n            return new MailMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerMiddlewareMakeCommand()\n    {\n        $this->app->singleton(MiddlewareMakeCommand::class, function ($app) {\n            return new MiddlewareMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerModelMakeCommand()\n    {\n        $this->app->singleton(ModelMakeCommand::class, function ($app) {\n            return new ModelMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerNotificationMakeCommand()\n    {\n        $this->app->singleton(NotificationMakeCommand::class, function ($app) {\n            return new NotificationMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerNotificationTableCommand()\n    {\n        $this->app->singleton(NotificationTableCommand::class, function ($app) {\n            return new NotificationTableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerObserverMakeCommand()\n    {\n        $this->app->singleton(ObserverMakeCommand::class, function ($app) {\n            return new ObserverMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerPolicyMakeCommand()\n    {\n        $this->app->singleton(PolicyMakeCommand::class, function ($app) {\n            return new PolicyMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerProviderMakeCommand()\n    {\n        $this->app->singleton(ProviderMakeCommand::class, function ($app) {\n            return new ProviderMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueForgetCommand()\n    {\n        $this->app->singleton(ForgetFailedQueueCommand::class);\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueListenCommand()\n    {\n        $this->app->singleton(QueueListenCommand::class, function ($app) {\n            return new QueueListenCommand($app['queue.listener']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueMonitorCommand()\n    {\n        $this->app->singleton(QueueMonitorCommand::class, function ($app) {\n            return new QueueMonitorCommand($app['queue'], $app['events']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueuePruneBatchesCommand()\n    {\n        $this->app->singleton(QueuePruneBatchesCommand::class, function () {\n            return new QueuePruneBatchesCommand;\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueuePruneFailedJobsCommand()\n    {\n        $this->app->singleton(QueuePruneFailedJobsCommand::class, function () {\n            return new QueuePruneFailedJobsCommand;\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueRestartCommand()\n    {\n        $this->app->singleton(QueueRestartCommand::class, function ($app) {\n            return new QueueRestartCommand($app['cache.store']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueWorkCommand()\n    {\n        $this->app->singleton(QueueWorkCommand::class, function ($app) {\n            return new QueueWorkCommand($app['queue.worker'], $app['cache.store']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueFailedTableCommand()\n    {\n        $this->app->singleton(FailedTableCommand::class, function ($app) {\n            return new FailedTableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueTableCommand()\n    {\n        $this->app->singleton(TableCommand::class, function ($app) {\n            return new TableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerQueueBatchesTableCommand()\n    {\n        $this->app->singleton(BatchesTableCommand::class, function ($app) {\n            return new BatchesTableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerRequestMakeCommand()\n    {\n        $this->app->singleton(RequestMakeCommand::class, function ($app) {\n            return new RequestMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerResourceMakeCommand()\n    {\n        $this->app->singleton(ResourceMakeCommand::class, function ($app) {\n            return new ResourceMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerRuleMakeCommand()\n    {\n        $this->app->singleton(RuleMakeCommand::class, function ($app) {\n            return new RuleMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerScopeMakeCommand()\n    {\n        $this->app->singleton(ScopeMakeCommand::class, function ($app) {\n            return new ScopeMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerSeederMakeCommand()\n    {\n        $this->app->singleton(SeederMakeCommand::class, function ($app) {\n            return new SeederMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerSessionTableCommand()\n    {\n        $this->app->singleton(SessionTableCommand::class, function ($app) {\n            return new SessionTableCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerRouteCacheCommand()\n    {\n        $this->app->singleton(RouteCacheCommand::class, function ($app) {\n            return new RouteCacheCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerRouteClearCommand()\n    {\n        $this->app->singleton(RouteClearCommand::class, function ($app) {\n            return new RouteClearCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerRouteListCommand()\n    {\n        $this->app->singleton(RouteListCommand::class, function ($app) {\n            return new RouteListCommand($app['router']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerSeedCommand()\n    {\n        $this->app->singleton(SeedCommand::class, function ($app) {\n            return new SeedCommand($app['db']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerTestMakeCommand()\n    {\n        $this->app->singleton(TestMakeCommand::class, function ($app) {\n            return new TestMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerTraitMakeCommand()\n    {\n        $this->app->singleton(TraitMakeCommand::class, function ($app) {\n            return new TraitMakeCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerVendorPublishCommand()\n    {\n        $this->app->singleton(VendorPublishCommand::class, function ($app) {\n            return new VendorPublishCommand($app['files']);\n        });\n    }\n\n    /**\n     * Register the command.\n     *\n     * @return void\n     */\n    protected function registerViewClearCommand()\n    {\n        $this->app->singleton(ViewClearCommand::class, function ($app) {\n            return new ViewClearCommand($app['files']);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return array_merge(array_values($this->commands), array_values($this->devCommands));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Providers/ComposerServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Providers;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\Composer;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ComposerServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('composer', function ($app) {\n            return new Composer($app['files'], $app->basePath());\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['composer'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Providers/ConsoleSupportServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Providers;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Database\\MigrationServiceProvider;\nuse Illuminate\\Support\\AggregateServiceProvider;\n\nclass ConsoleSupportServiceProvider extends AggregateServiceProvider implements DeferrableProvider\n{\n    /**\n     * The provider class names.\n     *\n     * @var string[]\n     */\n    protected $providers = [\n        ArtisanServiceProvider::class,\n        MigrationServiceProvider::class,\n        ComposerServiceProvider::class,\n    ];\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Providers;\n\nuse Illuminate\\Contracts\\Validation\\ValidatesWhenResolved;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass FormRequestServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        //\n    }\n\n    /**\n     * Bootstrap the application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        $this->app->afterResolving(ValidatesWhenResolved::class, function ($resolved) {\n            $resolved->validateResolved();\n        });\n\n        $this->app->resolving(FormRequest::class, function ($request, $app) {\n            $request = FormRequest::createFrom($app['request'], $request);\n\n            $request->setContainer($app)->setRedirector($app->make(Redirector::class));\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Providers/FoundationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Providers;\n\nuse Illuminate\\Console\\Events\\CommandFinished;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernel;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\Foundation\\ExceptionRenderer;\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode as MaintenanceModeContract;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\Grammar;\nuse Illuminate\\Foundation\\Console\\CliDumper;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Listener;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Mappers\\BladeMapper;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer;\nuse Illuminate\\Foundation\\Http\\HtmlDumper;\nuse Illuminate\\Foundation\\MaintenanceModeManager;\nuse Illuminate\\Foundation\\Precognition;\nuse Illuminate\\Foundation\\Vite;\nuse Illuminate\\Http\\Client\\Factory as HttpFactory;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Log\\Events\\MessageLogged;\nuse Illuminate\\Queue\\Events\\JobAttempted;\nuse Illuminate\\Support\\AggregateServiceProvider;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Illuminate\\Support\\Facades\\URL;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Testing\\LoggedExceptionCollection;\nuse Illuminate\\Testing\\ParallelTestingServiceProvider;\nuse Illuminate\\Validation\\ValidationException;\nuse Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer;\nuse Symfony\\Component\\VarDumper\\Caster\\StubCaster;\nuse Symfony\\Component\\VarDumper\\Cloner\\AbstractCloner;\n\nclass FoundationServiceProvider extends AggregateServiceProvider\n{\n    /**\n     * The provider class names.\n     *\n     * @var string[]\n     */\n    protected $providers = [\n        FormRequestServiceProvider::class,\n        ParallelTestingServiceProvider::class,\n    ];\n\n    /**\n     * The singletons to register into the container.\n     *\n     * @var array\n     */\n    public $singletons = [\n        HttpFactory::class => HttpFactory::class,\n        Vite::class => Vite::class,\n    ];\n\n    /**\n     * Boot the service provider.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        if ($this->app->runningInConsole()) {\n            $this->publishes([\n                __DIR__.'/../Exceptions/views' => $this->app->resourcePath('views/errors/'),\n            ], 'laravel-errors');\n        }\n\n        if ($this->app->hasDebugModeEnabled() && ! $this->app->has(ExceptionRenderer::class)) {\n            $this->app->make(Listener::class)->registerListeners(\n                $this->app->make(Dispatcher::class)\n            );\n        }\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        parent::register();\n\n        $this->registerConsoleSchedule();\n        $this->registerDumper();\n        $this->registerRequestValidation();\n        $this->registerRequestSignatureValidation();\n        $this->registerUriUrlGeneration();\n        $this->registerDeferHandler();\n        $this->registerExceptionTracking();\n        $this->registerExceptionRenderer();\n        $this->registerMaintenanceModeManager();\n    }\n\n    /**\n     * Register the console schedule implementation.\n     *\n     * @return void\n     */\n    public function registerConsoleSchedule()\n    {\n        $this->app->singleton(Schedule::class, function ($app) {\n            return $app->make(ConsoleKernel::class)->resolveConsoleSchedule();\n        });\n    }\n\n    /**\n     * Register a var dumper (with source) to debug variables.\n     *\n     * @return void\n     */\n    public function registerDumper()\n    {\n        AbstractCloner::$defaultCasters[ConnectionInterface::class] ??= [StubCaster::class, 'cutInternals'];\n        AbstractCloner::$defaultCasters[Container::class] ??= [StubCaster::class, 'cutInternals'];\n        AbstractCloner::$defaultCasters[Dispatcher::class] ??= [StubCaster::class, 'cutInternals'];\n        AbstractCloner::$defaultCasters[Factory::class] ??= [StubCaster::class, 'cutInternals'];\n        AbstractCloner::$defaultCasters[Grammar::class] ??= [StubCaster::class, 'cutInternals'];\n\n        $basePath = $this->app->basePath();\n\n        $compiledViewPath = $this->app['config']->get('view.compiled');\n\n        $format = $_SERVER['VAR_DUMPER_FORMAT'] ?? null;\n\n        match (true) {\n            'html' == $format => HtmlDumper::register($basePath, $compiledViewPath),\n            'cli' == $format => CliDumper::register($basePath, $compiledViewPath),\n            'server' == $format => null,\n            $format && 'tcp' == parse_url($format, PHP_URL_SCHEME) => null,\n            default => in_array(PHP_SAPI, ['cli', 'phpdbg']) ? CliDumper::register($basePath, $compiledViewPath) : HtmlDumper::register($basePath, $compiledViewPath),\n        };\n    }\n\n    /**\n     * Register the \"validate\" macro on the request.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function registerRequestValidation()\n    {\n        Request::macro('validate', function (array $rules, ...$params) {\n            return tap(validator($this->all(), $rules, ...$params), function ($validator) {\n                if ($this->isPrecognitive()) {\n                    $validator->after(Precognition::afterValidationHook($this))\n                        ->setRules(\n                            $this->filterPrecognitiveRules($validator->getRulesWithoutPlaceholders())\n                        );\n                }\n            })->validate();\n        });\n\n        Request::macro('validateWithBag', function (string $errorBag, array $rules, ...$params) {\n            try {\n                return $this->validate($rules, ...$params);\n            } catch (ValidationException $e) {\n                $e->errorBag = $errorBag;\n\n                throw $e;\n            }\n        });\n    }\n\n    /**\n     * Register the \"hasValidSignature\" macro on the request.\n     *\n     * @return void\n     */\n    public function registerRequestSignatureValidation()\n    {\n        Request::macro('hasValidSignature', function ($absolute = true) {\n            return URL::hasValidSignature($this, $absolute);\n        });\n\n        Request::macro('hasValidRelativeSignature', function () {\n            return URL::hasValidSignature($this, $absolute = false);\n        });\n\n        Request::macro('hasValidSignatureWhileIgnoring', function ($ignoreQuery = [], $absolute = true) {\n            return URL::hasValidSignature($this, $absolute, $ignoreQuery);\n        });\n\n        Request::macro('hasValidRelativeSignatureWhileIgnoring', function ($ignoreQuery = []) {\n            return URL::hasValidSignature($this, $absolute = false, $ignoreQuery);\n        });\n    }\n\n    /**\n     * Register the URL resolver for the URI generator.\n     *\n     * @return void\n     */\n    protected function registerUriUrlGeneration()\n    {\n        Uri::setUrlGeneratorResolver(fn () => app('url'));\n    }\n\n    /**\n     * Register the \"defer\" function termination handler.\n     *\n     * @return void\n     */\n    protected function registerDeferHandler()\n    {\n        $this->app->scoped(DeferredCallbackCollection::class);\n\n        $this->app['events']->listen(function (CommandFinished $event) {\n            app(DeferredCallbackCollection::class)->invokeWhen(fn ($callback) => app()->runningInConsole() && ($event->exitCode === 0 || $callback->always));\n        });\n\n        $this->app['events']->listen(function (JobAttempted $event) {\n            if (in_array($event->connectionName, ['sync', 'deferred'])) {\n                return;\n            }\n\n            app(DeferredCallbackCollection::class)->invokeWhen(fn ($callback) => ($event->successful() || $callback->always));\n        });\n    }\n\n    /**\n     * Register an event listener to track logged exceptions.\n     *\n     * @return void\n     */\n    protected function registerExceptionTracking()\n    {\n        if (! $this->app->runningUnitTests()) {\n            return;\n        }\n\n        $this->app->instance(\n            LoggedExceptionCollection::class,\n            new LoggedExceptionCollection\n        );\n\n        $this->app->make('events')->listen(MessageLogged::class, function ($event) {\n            if (isset($event->context['exception'])) {\n                $this->app->make(LoggedExceptionCollection::class)\n                    ->push($event->context['exception']);\n            }\n        });\n    }\n\n    /**\n     * Register the exceptions renderer.\n     *\n     * @return void\n     */\n    protected function registerExceptionRenderer()\n    {\n        $this->loadViewsFrom(__DIR__.'/../Exceptions/views', 'laravel-exceptions');\n\n        if (! $this->app->hasDebugModeEnabled()) {\n            return;\n        }\n\n        $this->loadViewsFrom(__DIR__.'/../resources/exceptions/renderer', 'laravel-exceptions-renderer');\n\n        $this->app->singleton(Renderer::class, function (Application $app) {\n            $errorRenderer = new HtmlErrorRenderer(\n                $app['config']->get('app.debug'),\n            );\n\n            return new Renderer(\n                $app->make(Factory::class),\n                $app->make(Listener::class),\n                $errorRenderer,\n                $app->make(BladeMapper::class),\n                $app->basePath(),\n            );\n        });\n\n        $this->app->singleton(Listener::class);\n    }\n\n    /**\n     * Register the maintenance mode manager service.\n     *\n     * @return void\n     */\n    public function registerMaintenanceModeManager()\n    {\n        $this->app->singleton(MaintenanceModeManager::class);\n\n        $this->app->bind(\n            MaintenanceModeContract::class,\n            fn () => $this->app->make(MaintenanceModeManager::class)->driver()\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Queue/InteractsWithUniqueJobs.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Queue;\n\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Support\\Facades\\Context;\n\ntrait InteractsWithUniqueJobs\n{\n    /**\n     * Store unique job information in the context in case we can't resolve the job on the queue side.\n     *\n     * @param  mixed  $job\n     * @return void\n     */\n    public function addUniqueJobInformationToContext($job): void\n    {\n        if ($job instanceof ShouldBeUnique) {\n            Context::addHidden([\n                'laravel_unique_job_cache_store' => $this->getUniqueJobCacheStore($job),\n                'laravel_unique_job_key' => UniqueLock::getKey($job),\n            ]);\n        }\n    }\n\n    /**\n     * Remove the unique job information from the context.\n     *\n     * @param  mixed  $job\n     * @return void\n     */\n    public function removeUniqueJobInformationFromContext($job): void\n    {\n        if ($job instanceof ShouldBeUnique) {\n            Context::forgetHidden([\n                'laravel_unique_job_cache_store',\n                'laravel_unique_job_key',\n            ]);\n        }\n    }\n\n    /**\n     * Determine the cache store used by the unique job to acquire locks.\n     *\n     * @param  mixed  $job\n     * @return string|null\n     */\n    protected function getUniqueJobCacheStore($job): ?string\n    {\n        return method_exists($job, 'uniqueVia')\n            ? $job->uniqueVia()->getName()\n            : config('cache.default');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Queue/Queueable.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Queue;\n\nuse Illuminate\\Bus\\Queueable as QueueableByBus;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\n\ntrait Queueable\n{\n    use Dispatchable, InteractsWithQueue, QueueableByBus, SerializesModels;\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Routing/PrecognitionCallableDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Routing;\n\nuse Illuminate\\Routing\\CallableDispatcher;\nuse Illuminate\\Routing\\Route;\n\nclass PrecognitionCallableDispatcher extends CallableDispatcher\n{\n    /**\n     * Dispatch a request to a given callable.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  callable  $callable\n     * @return mixed\n     */\n    public function dispatch(Route $route, $callable)\n    {\n        $this->resolveParameters($route, $callable);\n\n        abort(204, headers: ['Precognition-Success' => 'true']);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Routing/PrecognitionControllerDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Routing;\n\nuse Illuminate\\Routing\\ControllerDispatcher;\nuse Illuminate\\Routing\\Route;\nuse RuntimeException;\n\nclass PrecognitionControllerDispatcher extends ControllerDispatcher\n{\n    /**\n     * Dispatch a request to a given controller and method.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $controller\n     * @param  string  $method\n     * @return void\n     */\n    public function dispatch(Route $route, $controller, $method)\n    {\n        $this->ensureMethodExists($controller, $method);\n\n        $this->resolveParameters($route, $controller, $method);\n\n        abort(204, headers: ['Precognition-Success' => 'true']);\n    }\n\n    /**\n     * Ensure that the given method exists on the controller.\n     *\n     * @param  object  $controller\n     * @param  string  $method\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    protected function ensureMethodExists($controller, $method)\n    {\n        if (method_exists($controller, $method)) {\n            return $this;\n        }\n\n        $class = $controller::class;\n\n        throw new RuntimeException(\"Attempting to predict the outcome of the [{$class}::{$method}()] method but the method is not defined.\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Support/Providers/AuthServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Support\\Providers;\n\nuse Illuminate\\Support\\Facades\\Gate;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass AuthServiceProvider extends ServiceProvider\n{\n    /**\n     * The policy mappings for the application.\n     *\n     * @var array<class-string, class-string>\n     */\n    protected $policies = [];\n\n    /**\n     * Register the application's policies.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->booting(function () {\n            $this->registerPolicies();\n        });\n    }\n\n    /**\n     * Register the application's policies.\n     *\n     * @return void\n     */\n    public function registerPolicies()\n    {\n        foreach ($this->policies() as $model => $policy) {\n            Gate::policy($model, $policy);\n        }\n    }\n\n    /**\n     * Get the policies defined on the provider.\n     *\n     * @return array<class-string, class-string>\n     */\n    public function policies()\n    {\n        return $this->policies;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Support/Providers/EventServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Support\\Providers;\n\nuse Illuminate\\Auth\\Events\\Registered;\nuse Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification;\nuse Illuminate\\Foundation\\Events\\DiscoverEvents;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass EventServiceProvider extends ServiceProvider\n{\n    /**\n     * The event handler mappings for the application.\n     *\n     * @var array<string, array<int, string>>\n     */\n    protected $listen = [];\n\n    /**\n     * The subscribers to register.\n     *\n     * @var array\n     */\n    protected $subscribe = [];\n\n    /**\n     * The model observers to register.\n     *\n     * @var array<string, string|object|array<int, string|object>>\n     */\n    protected $observers = [];\n\n    /**\n     * Indicates if events should be discovered.\n     *\n     * @var bool\n     */\n    protected static $shouldDiscoverEvents = true;\n\n    /**\n     * The configured event discovery paths.\n     *\n     * @var iterable<int, string>|null\n     */\n    protected static $eventDiscoveryPaths;\n\n    /**\n     * Register the application's event listeners.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->booting(function () {\n            $events = $this->getEvents();\n\n            foreach ($events as $event => $listeners) {\n                foreach (array_unique($listeners, SORT_REGULAR) as $listener) {\n                    Event::listen($event, $listener);\n                }\n            }\n\n            foreach ($this->subscribe as $subscriber) {\n                Event::subscribe($subscriber);\n            }\n\n            foreach ($this->observers as $model => $observers) {\n                $model::observe($observers);\n            }\n        });\n\n        $this->booted(function () {\n            $this->configureEmailVerification();\n        });\n    }\n\n    /**\n     * Boot any application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        //\n    }\n\n    /**\n     * Get the events and handlers.\n     *\n     * @return array\n     */\n    public function listens()\n    {\n        return $this->listen;\n    }\n\n    /**\n     * Get the discovered events and listeners for the application.\n     *\n     * @return array\n     */\n    public function getEvents()\n    {\n        if ($this->app->eventsAreCached()) {\n            $cache = require $this->app->getCachedEventsPath();\n\n            return $cache[get_class($this)] ?? [];\n        } else {\n            return array_merge_recursive(\n                $this->discoveredEvents(),\n                $this->listens()\n            );\n        }\n    }\n\n    /**\n     * Get the discovered events for the application.\n     *\n     * @return array\n     */\n    protected function discoveredEvents()\n    {\n        return $this->shouldDiscoverEvents()\n            ? $this->discoverEvents()\n            : [];\n    }\n\n    /**\n     * Determine if events and listeners should be automatically discovered.\n     *\n     * @return bool\n     */\n    public function shouldDiscoverEvents()\n    {\n        return get_class($this) === __CLASS__ && static::$shouldDiscoverEvents === true;\n    }\n\n    /**\n     * Discover the events and listeners for the application.\n     *\n     * @return array\n     */\n    public function discoverEvents()\n    {\n        return (new LazyCollection($this->discoverEventsWithin()))\n            ->flatMap(function ($directory) {\n                return glob($directory, GLOB_ONLYDIR);\n            })\n            ->reject(function ($directory) {\n                return ! is_dir($directory);\n            })\n            ->pipe(fn ($directories) => DiscoverEvents::within(\n                $directories->all(),\n                $this->eventDiscoveryBasePath(),\n            ));\n    }\n\n    /**\n     * Get the listener directories that should be used to discover events.\n     *\n     * @return iterable<int, string>\n     */\n    protected function discoverEventsWithin()\n    {\n        return static::$eventDiscoveryPaths ?: [\n            $this->app->path('Listeners'),\n        ];\n    }\n\n    /**\n     * Add the given event discovery paths to the application's event discovery paths.\n     *\n     * @param  string|iterable<int, string>  $paths\n     * @return void\n     */\n    public static function addEventDiscoveryPaths(iterable|string $paths)\n    {\n        static::$eventDiscoveryPaths = (new LazyCollection(static::$eventDiscoveryPaths))\n            ->merge(is_string($paths) ? [$paths] : $paths)\n            ->unique()\n            ->values();\n    }\n\n    /**\n     * Set the globally configured event discovery paths.\n     *\n     * @param  iterable<int, string>  $paths\n     * @return void\n     */\n    public static function setEventDiscoveryPaths(iterable $paths)\n    {\n        static::$eventDiscoveryPaths = $paths;\n    }\n\n    /**\n     * Get the base path to be used during event discovery.\n     *\n     * @return string\n     */\n    protected function eventDiscoveryBasePath()\n    {\n        return base_path();\n    }\n\n    /**\n     * Disable event discovery for the application.\n     *\n     * @return void\n     */\n    public static function disableEventDiscovery()\n    {\n        static::$shouldDiscoverEvents = false;\n    }\n\n    /**\n     * Configure the proper event listeners for email verification.\n     *\n     * @return void\n     */\n    protected function configureEmailVerification()\n    {\n        if (! isset($this->listen[Registered::class]) ||\n            ! in_array(SendEmailVerificationNotification::class, Arr::wrap($this->listen[Registered::class]))) {\n            Event::listen(Registered::class, SendEmailVerificationNotification::class);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Support\\Providers;\n\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\n\n/**\n * @mixin \\Illuminate\\Routing\\Router\n */\nclass RouteServiceProvider extends ServiceProvider\n{\n    use ForwardsCalls;\n\n    /**\n     * The controller namespace for the application.\n     *\n     * @var string|null\n     */\n    protected $namespace;\n\n    /**\n     * The callback that should be used to load the application's routes.\n     *\n     * @var \\Closure|null\n     */\n    protected $loadRoutesUsing;\n\n    /**\n     * The global callback that should be used to load the application's routes.\n     *\n     * @var \\Closure|null\n     */\n    protected static $alwaysLoadRoutesUsing;\n\n    /**\n     * The callback that should be used to load the application's cached routes.\n     *\n     * @var \\Closure|null\n     */\n    protected static $alwaysLoadCachedRoutesUsing;\n\n    /**\n     * Register any application services.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->booted(function () {\n            $this->setRootControllerNamespace();\n\n            if ($this->routesAreCached()) {\n                $this->loadCachedRoutes();\n            } else {\n                $this->loadRoutes();\n\n                $this->app->booted(function () {\n                    $this->app['router']->getRoutes()->refreshNameLookups();\n                    $this->app['router']->getRoutes()->refreshActionLookups();\n                });\n            }\n        });\n    }\n\n    /**\n     * Bootstrap any application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        //\n    }\n\n    /**\n     * Register the callback that will be used to load the application's routes.\n     *\n     * @param  \\Closure  $routesCallback\n     * @return $this\n     */\n    protected function routes(Closure $routesCallback)\n    {\n        $this->loadRoutesUsing = $routesCallback;\n\n        return $this;\n    }\n\n    /**\n     * Register the callback that will be used to load the application's routes.\n     *\n     * @param  \\Closure|null  $routesCallback\n     * @return void\n     */\n    public static function loadRoutesUsing(?Closure $routesCallback)\n    {\n        self::$alwaysLoadRoutesUsing = $routesCallback;\n    }\n\n    /**\n     * Register the callback that will be used to load the application's cached routes.\n     *\n     * @param  \\Closure|null  $routesCallback\n     * @return void\n     */\n    public static function loadCachedRoutesUsing(?Closure $routesCallback)\n    {\n        self::$alwaysLoadCachedRoutesUsing = $routesCallback;\n    }\n\n    /**\n     * Set the root controller namespace for the application.\n     *\n     * @return void\n     */\n    protected function setRootControllerNamespace()\n    {\n        if (! is_null($this->namespace)) {\n            $this->app[UrlGenerator::class]->setRootControllerNamespace($this->namespace);\n        }\n    }\n\n    /**\n     * Determine if the application routes are cached.\n     *\n     * @return bool\n     */\n    protected function routesAreCached()\n    {\n        return $this->app->routesAreCached();\n    }\n\n    /**\n     * Load the cached routes for the application.\n     *\n     * @return void\n     */\n    protected function loadCachedRoutes()\n    {\n        if (! is_null(self::$alwaysLoadCachedRoutesUsing)) {\n            $this->app->call(self::$alwaysLoadCachedRoutesUsing);\n\n            return;\n        }\n\n        $this->app->booted(function () {\n            require $this->app->getCachedRoutesPath();\n        });\n    }\n\n    /**\n     * Load the application routes.\n     *\n     * @return void\n     */\n    protected function loadRoutes()\n    {\n        if (! is_null(self::$alwaysLoadRoutesUsing)) {\n            $this->app->call(self::$alwaysLoadRoutesUsing);\n        }\n\n        if (! is_null($this->loadRoutesUsing)) {\n            $this->app->call($this->loadRoutesUsing);\n        } elseif (method_exists($this, 'map')) {\n            $this->app->call([$this, 'map']);\n        }\n    }\n\n    /**\n     * Pass dynamic methods onto the router instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo(\n            $this->app->make(Router::class), $method, $parameters\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Attributes/Seed.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Seed\n{\n    /**\n     * Create a new attribute instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Attributes/Seeder.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Seeder\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $class\n     */\n    public function __construct(public string $class)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Attributes/SetUp.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_METHOD)]\nclass SetUp\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Attributes/TearDown.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_METHOD)]\nclass TearDown\n{\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/CachedState.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nclass CachedState\n{\n    public static ?array $cachedRoutes = null;\n    public static ?array $cachedConfig = null;\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithAuthentication.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Contracts\\Auth\\Authenticatable as UserContract;\n\ntrait InteractsWithAuthentication\n{\n    /**\n     * Set the currently logged in user for the application.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function actingAs(UserContract $user, $guard = null)\n    {\n        return $this->be($user, $guard);\n    }\n\n    /**\n     * Clear the currently logged in user for the application.\n     *\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function actingAsGuest($guard = null)\n    {\n        $this->app['auth']->guard($guard)->forgetUser();\n\n        $this->app['auth']->shouldUse($guard);\n\n        return $this;\n    }\n\n    /**\n     * Set the currently logged in user for the application.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function be(UserContract $user, $guard = null)\n    {\n        if (isset($user->wasRecentlyCreated) && $user->wasRecentlyCreated) {\n            $user->wasRecentlyCreated = false;\n        }\n\n        $this->app['auth']->guard($guard)->setUser($user);\n\n        $this->app['auth']->shouldUse($guard);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the user is authenticated.\n     *\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function assertAuthenticated($guard = null)\n    {\n        $this->assertTrue($this->isAuthenticated($guard), 'The user is not authenticated');\n\n        return $this;\n    }\n\n    /**\n     * Assert that the user is not authenticated.\n     *\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function assertGuest($guard = null)\n    {\n        $this->assertFalse($this->isAuthenticated($guard), 'The user is authenticated');\n\n        return $this;\n    }\n\n    /**\n     * Return true if the user is authenticated, false otherwise.\n     *\n     * @param  string|null  $guard\n     * @return bool\n     */\n    protected function isAuthenticated($guard = null)\n    {\n        return $this->app->make('auth')->guard($guard)->check();\n    }\n\n    /**\n     * Assert that the user is authenticated as the given user.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Authenticatable  $user\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function assertAuthenticatedAs($user, $guard = null)\n    {\n        $expected = $this->app->make('auth')->guard($guard)->user();\n\n        $this->assertNotNull($expected, 'The current user is not authenticated.');\n\n        $this->assertInstanceOf(\n            get_class($expected), $user,\n            'The currently authenticated user is not who was expected'\n        );\n\n        $this->assertSame(\n            $expected->getAuthIdentifier(), $user->getAuthIdentifier(),\n            'The currently authenticated user is not who was expected'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given credentials are valid.\n     *\n     * @param  array  $credentials\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function assertCredentials(array $credentials, $guard = null)\n    {\n        $this->assertTrue(\n            $this->hasCredentials($credentials, $guard), 'The given credentials are invalid.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given credentials are invalid.\n     *\n     * @param  array  $credentials\n     * @param  string|null  $guard\n     * @return $this\n     */\n    public function assertInvalidCredentials(array $credentials, $guard = null)\n    {\n        $this->assertFalse(\n            $this->hasCredentials($credentials, $guard), 'The given credentials are valid.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Return true if the credentials are valid, false otherwise.\n     *\n     * @param  array  $credentials\n     * @param  string|null  $guard\n     * @return bool\n     */\n    protected function hasCredentials(array $credentials, $guard = null)\n    {\n        $provider = $this->app->make('auth')->guard($guard)->getProvider();\n\n        $user = $provider->retrieveByCredentials($credentials);\n\n        return $user && $provider->validateCredentials($user, $credentials);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Testing\\PendingCommand;\n\ntrait InteractsWithConsole\n{\n    /**\n     * Indicates if the console output should be mocked.\n     *\n     * @var bool\n     */\n    public $mockConsoleOutput = true;\n\n    /**\n     * Indicates if the command is expected to output anything.\n     *\n     * @var bool|null\n     */\n    public $expectsOutput;\n\n    /**\n     * All of the expected output lines.\n     *\n     * @var array\n     */\n    public $expectedOutput = [];\n\n    /**\n     * All of the expected text to be present in the output.\n     *\n     * @var array\n     */\n    public $expectedOutputSubstrings = [];\n\n    /**\n     * All of the output lines that aren't expected to be displayed.\n     *\n     * @var array\n     */\n    public $unexpectedOutput = [];\n\n    /**\n     * All of the text that is not expected to be present in the output.\n     *\n     * @var array\n     */\n    public $unexpectedOutputSubstrings = [];\n\n    /**\n     * All of the expected output tables.\n     *\n     * @var array\n     */\n    public $expectedTables = [];\n\n    /**\n     * All of the expected questions.\n     *\n     * @var array\n     */\n    public $expectedQuestions = [];\n\n    /**\n     * All of the expected choice questions.\n     *\n     * @var array\n     */\n    public $expectedChoices = [];\n\n    /**\n     * Call artisan command and return code.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @return \\Illuminate\\Testing\\PendingCommand|int\n     */\n    public function artisan($command, $parameters = [])\n    {\n        if (! $this->mockConsoleOutput) {\n            return $this->app[Kernel::class]->call($command, $parameters);\n        }\n\n        return new PendingCommand($this, $this->app, $command, $parameters);\n    }\n\n    /**\n     * Disable mocking the console output.\n     *\n     * @return $this\n     */\n    protected function withoutMockingConsoleOutput()\n    {\n        $this->mockConsoleOutput = false;\n\n        $this->app->offsetUnset(OutputStyle::class);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithContainer.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Closure;\nuse Illuminate\\Foundation\\Mix;\nuse Illuminate\\Foundation\\Vite;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Illuminate\\Support\\Facades\\Vite as ViteFacade;\nuse Illuminate\\Support\\HtmlString;\nuse Mockery;\n\ntrait InteractsWithContainer\n{\n    /**\n     * The original Vite handler.\n     *\n     * @var \\Illuminate\\Foundation\\Vite|null\n     */\n    protected $originalVite;\n\n    /**\n     * The original Laravel Mix handler.\n     *\n     * @var \\Illuminate\\Foundation\\Mix|null\n     */\n    protected $originalMix;\n\n    /**\n     * The original deferred callbacks collection.\n     *\n     * @var \\Illuminate\\Support\\Defer\\DeferredCallbackCollection|null\n     */\n    protected $originalDeferredCallbacksCollection;\n\n    /**\n     * Register an instance of an object in the container.\n     *\n     * @template TSwap of object\n     *\n     * @param  string  $abstract\n     * @param  TSwap  $instance\n     * @return TSwap\n     */\n    protected function swap($abstract, $instance)\n    {\n        return $this->instance($abstract, $instance);\n    }\n\n    /**\n     * Register an instance of an object in the container.\n     *\n     * @template TInstance of object\n     *\n     * @param  string  $abstract\n     * @param  TInstance  $instance\n     * @return TInstance\n     */\n    protected function instance($abstract, $instance)\n    {\n        $this->app->instance($abstract, $instance);\n\n        return $instance;\n    }\n\n    /**\n     * Mock an instance of an object in the container.\n     *\n     * @param  string  $abstract\n     * @param  \\Closure|null  $mock\n     * @return \\Mockery\\MockInterface\n     */\n    protected function mock($abstract, ?Closure $mock = null)\n    {\n        return $this->instance($abstract, Mockery::mock(...array_filter(func_get_args())));\n    }\n\n    /**\n     * Mock a partial instance of an object in the container.\n     *\n     * @param  string  $abstract\n     * @param  \\Closure|null  $mock\n     * @return \\Mockery\\MockInterface\n     */\n    protected function partialMock($abstract, ?Closure $mock = null)\n    {\n        return $this->instance($abstract, Mockery::mock(...array_filter(func_get_args()))->makePartial());\n    }\n\n    /**\n     * Spy an instance of an object in the container.\n     *\n     * @param  string  $abstract\n     * @param  \\Closure|null  $mock\n     * @return \\Mockery\\MockInterface\n     */\n    protected function spy($abstract, ?Closure $mock = null)\n    {\n        return $this->instance($abstract, Mockery::spy(...array_filter(func_get_args())));\n    }\n\n    /**\n     * Instruct the container to forget a previously mocked / spied instance of an object.\n     *\n     * @param  string  $abstract\n     * @return $this\n     */\n    protected function forgetMock($abstract)\n    {\n        $this->app->forgetInstance($abstract);\n\n        return $this;\n    }\n\n    /**\n     * Register an empty handler for Vite in the container.\n     *\n     * @return $this\n     */\n    protected function withoutVite()\n    {\n        if ($this->originalVite == null) {\n            $this->originalVite = app(Vite::class);\n        }\n\n        ViteFacade::clearResolvedInstance();\n\n        $this->swap(Vite::class, new class extends Vite\n        {\n            public function __invoke($entrypoints, $buildDirectory = null)\n            {\n                return new HtmlString('');\n            }\n\n            public function __call($method, $parameters)\n            {\n                return '';\n            }\n\n            public function __toString()\n            {\n                return '';\n            }\n\n            public function useIntegrityKey($key)\n            {\n                return $this;\n            }\n\n            public function useBuildDirectory($path)\n            {\n                return $this;\n            }\n\n            public function useHotFile($path)\n            {\n                return $this;\n            }\n\n            public function withEntryPoints($entryPoints)\n            {\n                return $this;\n            }\n\n            public function useScriptTagAttributes($attributes)\n            {\n                return $this;\n            }\n\n            public function useStyleTagAttributes($attributes)\n            {\n                return $this;\n            }\n\n            public function usePreloadTagAttributes($attributes)\n            {\n                return $this;\n            }\n\n            public function preloadedAssets()\n            {\n                return [];\n            }\n\n            public function reactRefresh()\n            {\n                return '';\n            }\n\n            public function content($asset, $buildDirectory = null)\n            {\n                return '';\n            }\n\n            public function asset($asset, $buildDirectory = null)\n            {\n                return '';\n            }\n        });\n\n        return $this;\n    }\n\n    /**\n     * Restore Vite in the container.\n     *\n     * @return $this\n     */\n    protected function withVite()\n    {\n        if ($this->originalVite) {\n            $this->app->instance(Vite::class, $this->originalVite);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register an empty handler for Laravel Mix in the container.\n     *\n     * @return $this\n     */\n    protected function withoutMix()\n    {\n        if ($this->originalMix == null) {\n            $this->originalMix = app(Mix::class);\n        }\n\n        $this->swap(Mix::class, function () {\n            return new HtmlString('');\n        });\n\n        return $this;\n    }\n\n    /**\n     * Restore Laravel Mix in the container.\n     *\n     * @return $this\n     */\n    protected function withMix()\n    {\n        if ($this->originalMix) {\n            $this->app->instance(Mix::class, $this->originalMix);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Execute deferred functions immediately.\n     *\n     * @return $this\n     */\n    protected function withoutDefer()\n    {\n        if ($this->originalDeferredCallbacksCollection == null) {\n            $this->originalDeferredCallbacksCollection = $this->app->make(DeferredCallbackCollection::class);\n        }\n\n        $this->swap(DeferredCallbackCollection::class, new class extends DeferredCallbackCollection\n        {\n            public function offsetSet(mixed $offset, mixed $value): void\n            {\n                $value();\n            }\n        });\n\n        return $this;\n    }\n\n    /**\n     * Restore deferred functions.\n     *\n     * @return $this\n     */\n    protected function withDefer()\n    {\n        if ($this->originalDeferredCallbacksCollection) {\n            $this->app->instance(DeferredCallbackCollection::class, $this->originalDeferredCallbacksCollection);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Testing\\Constraints\\CountInDatabase;\nuse Illuminate\\Testing\\Constraints\\HasInDatabase;\nuse Illuminate\\Testing\\Constraints\\NotSoftDeletedInDatabase;\nuse Illuminate\\Testing\\Constraints\\SoftDeletedInDatabase;\nuse PHPUnit\\Framework\\Constraint\\LogicalNot as ReverseConstraint;\n\ntrait InteractsWithDatabase\n{\n    /**\n     * Assert that a given where condition exists in the database.\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  array<string, mixed>  $data\n     * @param  string|null  $connection\n     * @return $this\n     */\n    protected function assertDatabaseHas($table, array $data = [], $connection = null)\n    {\n        if (is_iterable($table)) {\n            foreach ($table as $item) {\n                $this->assertDatabaseHas($item, $data, $connection);\n            }\n\n            return $this;\n        }\n\n        if ($table instanceof Model) {\n            $data = [\n                $table->getKeyName() => $table->getKey(),\n                ...$data,\n            ];\n        }\n\n        $this->assertThat(\n            $this->getTable($table), new HasInDatabase($this->getConnection($connection, $table), $data)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that a given where condition does not exist in the database.\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  array<string, mixed>  $data\n     * @param  string|null  $connection\n     * @return $this\n     */\n    protected function assertDatabaseMissing($table, array $data = [], $connection = null)\n    {\n        if (is_iterable($table)) {\n            foreach ($table as $item) {\n                $this->assertDatabaseMissing($item, $data, $connection);\n            }\n\n            return $this;\n        }\n\n        if ($table instanceof Model) {\n            $data = [\n                $table->getKeyName() => $table->getKey(),\n                ...$data,\n            ];\n        }\n\n        $constraint = new ReverseConstraint(\n            new HasInDatabase($this->getConnection($connection, $table), $data)\n        );\n\n        $this->assertThat($this->getTable($table), $constraint);\n\n        return $this;\n    }\n\n    /**\n     * Assert the count of table entries.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  int  $count\n     * @param  string|null  $connection\n     * @return $this\n     */\n    protected function assertDatabaseCount($table, int $count, $connection = null)\n    {\n        $this->assertThat(\n            $this->getTable($table), new CountInDatabase($this->getConnection($connection, $table), $count)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given table has no entries.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  string|null  $connection\n     * @return $this\n     */\n    protected function assertDatabaseEmpty($table, $connection = null)\n    {\n        $this->assertThat(\n            $this->getTable($table), new CountInDatabase($this->getConnection($connection, $table), 0)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the given record has been \"soft deleted\".\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  array<string, mixed>  $data\n     * @param  string|null  $connection\n     * @param  string|null  $deletedAtColumn\n     * @return $this\n     */\n    protected function assertSoftDeleted($table, array $data = [], $connection = null, $deletedAtColumn = 'deleted_at')\n    {\n        if (is_iterable($table)) {\n            foreach ($table as $item) {\n                $this->assertSoftDeleted($item, $data, $connection);\n            }\n\n            return $this;\n        }\n\n        if ($this->isSoftDeletableModel($table)) {\n            return $this->assertSoftDeleted(\n                $table->getTable(),\n                array_merge($data, [$table->getKeyName() => $table->getKey()]),\n                $table->getConnectionName(),\n                $table->getDeletedAtColumn()\n            );\n        }\n\n        $this->assertThat(\n            $this->getTable($table),\n            new SoftDeletedInDatabase(\n                $this->getConnection($connection, $table),\n                $data,\n                $this->getDeletedAtColumn($table, $deletedAtColumn)\n            )\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the given record has not been \"soft deleted\".\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  array<string, mixed>  $data\n     * @param  string|null  $connection\n     * @param  string|null  $deletedAtColumn\n     * @return $this\n     */\n    protected function assertNotSoftDeleted($table, array $data = [], $connection = null, $deletedAtColumn = 'deleted_at')\n    {\n        if (is_iterable($table)) {\n            foreach ($table as $item) {\n                $this->assertNotSoftDeleted($item, $data, $connection);\n            }\n\n            return $this;\n        }\n\n        if ($this->isSoftDeletableModel($table)) {\n            return $this->assertNotSoftDeleted(\n                $table->getTable(),\n                array_merge($data, [$table->getKeyName() => $table->getKey()]),\n                $table->getConnectionName(),\n                $table->getDeletedAtColumn()\n            );\n        }\n\n        $this->assertThat(\n            $this->getTable($table),\n            new NotSoftDeletedInDatabase(\n                $this->getConnection($connection, $table),\n                $data,\n                $this->getDeletedAtColumn($table, $deletedAtColumn)\n            )\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the given model exists in the database.\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $model\n     * @return $this\n     */\n    protected function assertModelExists($model)\n    {\n        return $this->assertDatabaseHas($model);\n    }\n\n    /**\n     * Assert the given model does not exist in the database.\n     *\n     * @param  iterable<\\Illuminate\\Database\\Eloquent\\Model>|\\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $model\n     * @return $this\n     */\n    protected function assertModelMissing($model)\n    {\n        return $this->assertDatabaseMissing($model);\n    }\n\n    /**\n     * Specify the number of database queries that should occur throughout the test.\n     *\n     * @param  int  $expected\n     * @param  string|null  $connection\n     * @return $this\n     */\n    public function expectsDatabaseQueryCount($expected, $connection = null)\n    {\n        $connectionInstance = $this->getConnection($connection);\n\n        $actual = 0;\n\n        $connectionInstance->listen(function (QueryExecuted $event) use (&$actual, $connectionInstance, $connection) {\n            if (is_null($connection) || $connectionInstance === $event->connection) {\n                $actual++;\n            }\n        });\n\n        $this->beforeApplicationDestroyed(function () use (&$actual, $expected, $connectionInstance) {\n            $this->assertSame(\n                $expected,\n                $actual,\n                \"Expected {$expected} database queries on the [{$connectionInstance->getName()}] connection. {$actual} occurred.\"\n            );\n        });\n\n        return $this;\n    }\n\n    /**\n     * Determine if the argument is a soft deletable model.\n     *\n     * @param  mixed  $model\n     * @return bool\n     */\n    protected function isSoftDeletableModel($model)\n    {\n        return $model instanceof Model && $model::isSoftDeletable();\n    }\n\n    /**\n     * Cast a JSON string to a database compatible type.\n     *\n     * @param  array|object|string  $value\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Contracts\\Database\\Query\\Expression\n     */\n    public function castAsJson($value, $connection = null)\n    {\n        if ($value instanceof Jsonable) {\n            $value = $value->toJson();\n        } elseif (is_array($value) || is_object($value)) {\n            $value = json_encode($value);\n        }\n\n        $db = DB::connection($connection);\n\n        $value = $db->getPdo()->quote($value);\n\n        return $db->raw(\n            $db->getQueryGrammar()->compileJsonValueCast($value)\n        );\n    }\n\n    /**\n     * Get the database connection.\n     *\n     * @param  string|null  $connection\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string|null  $table\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function getConnection($connection = null, $table = null)\n    {\n        $database = $this->app->make('db');\n\n        $connection = $connection ?: $this->getTableConnection($table) ?: $database->getDefaultConnection();\n\n        return $database->connection($connection);\n    }\n\n    /**\n     * Get the table name from the given model or string.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @return string\n     */\n    protected function getTable($table)\n    {\n        if ($table instanceof Model) {\n            return $table->getTable();\n        }\n\n        return $this->newModelFor($table)?->getTable() ?: $table;\n    }\n\n    /**\n     * Get the table connection specified in the given model.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @return string|null\n     */\n    protected function getTableConnection($table)\n    {\n        if ($table instanceof Model) {\n            return $table->getConnectionName();\n        }\n\n        return $this->newModelFor($table)?->getConnectionName();\n    }\n\n    /**\n     * Get the table column name used for soft deletes.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @param  string  $defaultColumnName\n     * @return string\n     */\n    protected function getDeletedAtColumn($table, $defaultColumnName = 'deleted_at')\n    {\n        return $this->newModelFor($table)?->getDeletedAtColumn() ?: $defaultColumnName;\n    }\n\n    /**\n     * Get the model entity from the given model or string.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|class-string<\\Illuminate\\Database\\Eloquent\\Model>|string  $table\n     * @return \\Illuminate\\Database\\Eloquent\\Model|null\n     */\n    protected function newModelFor($table)\n    {\n        return is_subclass_of($table, Model::class) ? (new $table) : null;\n    }\n\n    /**\n     * Seed a given database connection.\n     *\n     * @param  list<string>|class-string<\\Illuminate\\Database\\Seeder>|string  $class\n     * @return $this\n     */\n    public function seed($class = 'Database\\\\Seeders\\\\DatabaseSeeder')\n    {\n        foreach (Arr::wrap($class) as $class) {\n            $this->artisan('db:seed', ['--class' => $class, '--no-interaction' => true]);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithDeprecationHandling.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse ErrorException;\n\ntrait InteractsWithDeprecationHandling\n{\n    /**\n     * The original deprecation handler.\n     *\n     * @var callable|null\n     */\n    protected $originalDeprecationHandler;\n\n    /**\n     * Restore deprecation handling.\n     *\n     * @return $this\n     */\n    protected function withDeprecationHandling()\n    {\n        if ($this->originalDeprecationHandler) {\n            set_error_handler(tap($this->originalDeprecationHandler, fn () => $this->originalDeprecationHandler = null));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Disable deprecation handling for the test.\n     *\n     * @return $this\n     *\n     * @throws \\ErrorException\n     */\n    protected function withoutDeprecationHandling()\n    {\n        if ($this->originalDeprecationHandler == null) {\n            $this->originalDeprecationHandler = set_error_handler(function ($level, $message, $file = '', $line = 0) {\n                if (in_array($level, [E_DEPRECATED, E_USER_DEPRECATED]) || (error_reporting() & $level)) {\n                    throw new ErrorException($message, 0, $level, $file, $line);\n                }\n            });\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Closure;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Illuminate\\Testing\\Assert;\nuse Illuminate\\Validation\\ValidationException;\nuse Symfony\\Component\\Console\\Application as ConsoleApplication;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Throwable;\n\ntrait InteractsWithExceptionHandling\n{\n    use ReflectsClosures;\n\n    /**\n     * The original exception handler.\n     *\n     * @var \\Illuminate\\Contracts\\Debug\\ExceptionHandler|null\n     */\n    protected $originalExceptionHandler;\n\n    /**\n     * Restore exception handling.\n     *\n     * @return $this\n     */\n    protected function withExceptionHandling()\n    {\n        if ($this->originalExceptionHandler) {\n            $currentExceptionHandler = app(ExceptionHandler::class);\n\n            $currentExceptionHandler instanceof ExceptionHandlerFake\n                ? $currentExceptionHandler->setHandler($this->originalExceptionHandler)\n                : $this->app->instance(ExceptionHandler::class, $this->originalExceptionHandler);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Only handle the given exceptions via the exception handler.\n     *\n     * @param  list<class-string<\\Throwable>>  $exceptions\n     * @return $this\n     */\n    protected function handleExceptions(array $exceptions)\n    {\n        return $this->withoutExceptionHandling($exceptions);\n    }\n\n    /**\n     * Only handle validation exceptions via the exception handler.\n     *\n     * @return $this\n     */\n    protected function handleValidationExceptions()\n    {\n        return $this->handleExceptions([ValidationException::class]);\n    }\n\n    /**\n     * Disable exception handling for the test.\n     *\n     * @param  list<class-string<\\Throwable>>  $except\n     * @return $this\n     */\n    protected function withoutExceptionHandling(array $except = [])\n    {\n        if ($this->originalExceptionHandler == null) {\n            $currentExceptionHandler = app(ExceptionHandler::class);\n\n            $this->originalExceptionHandler = $currentExceptionHandler instanceof ExceptionHandlerFake\n                ? $currentExceptionHandler->handler()\n                : $currentExceptionHandler;\n        }\n\n        $exceptionHandler = new class($this->originalExceptionHandler, $except) implements ExceptionHandler, WithoutExceptionHandlingHandler\n        {\n            protected $except;\n            protected $originalHandler;\n\n            /**\n             * Create a new class instance.\n             *\n             * @param  \\Illuminate\\Contracts\\Debug\\ExceptionHandler  $originalHandler\n             * @param  list<class-string<\\Throwable>>  $except\n             * @return void\n             */\n            public function __construct($originalHandler, $except = [])\n            {\n                $this->except = $except;\n                $this->originalHandler = $originalHandler;\n            }\n\n            /**\n             * Report or log an exception.\n             *\n             * @param  \\Throwable  $e\n             * @return void\n             *\n             * @throws \\Exception\n             */\n            public function report(Throwable $e)\n            {\n                //\n            }\n\n            /**\n             * Determine if the exception should be reported.\n             *\n             * @param  \\Throwable  $e\n             * @return false\n             */\n            public function shouldReport(Throwable $e)\n            {\n                return false;\n            }\n\n            /**\n             * Render an exception into an HTTP response.\n             *\n             * @param  \\Illuminate\\Http\\Request  $request\n             * @param  \\Throwable  $e\n             * @return \\Symfony\\Component\\HttpFoundation\\Response\n             *\n             * @throws \\Throwable\n             */\n            public function render($request, Throwable $e)\n            {\n                foreach ($this->except as $class) {\n                    if ($e instanceof $class) {\n                        return $this->originalHandler->render($request, $e);\n                    }\n                }\n\n                if ($e instanceof NotFoundHttpException) {\n                    throw new NotFoundHttpException(\n                        \"{$request->method()} {$request->url()}\", $e, is_int($e->getCode()) ? $e->getCode() : 0\n                    );\n                }\n\n                throw $e;\n            }\n\n            /**\n             * Render an exception to the console.\n             *\n             * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n             * @param  \\Throwable  $e\n             * @return void\n             */\n            public function renderForConsole($output, Throwable $e)\n            {\n                (new ConsoleApplication)->renderThrowable($e, $output);\n            }\n        };\n\n        $currentExceptionHandler = app(ExceptionHandler::class);\n\n        $currentExceptionHandler instanceof ExceptionHandlerFake\n            ? $currentExceptionHandler->setHandler($exceptionHandler)\n            : $this->app->instance(ExceptionHandler::class, $exceptionHandler);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given callback throws an exception with the given message when invoked.\n     *\n     * @param  \\Closure  $test\n     * @param  (\\Closure(\\Throwable): bool)|class-string<\\Throwable>  $expectedClass\n     * @param  string|null  $expectedMessage\n     * @return $this\n     */\n    protected function assertThrows(Closure $test, string|Closure $expectedClass = Throwable::class, ?string $expectedMessage = null)\n    {\n        [$expectedClass, $expectedClassCallback] = $expectedClass instanceof Closure\n            ? [$this->firstClosureParameterType($expectedClass), $expectedClass]\n            : [$expectedClass, null];\n\n        try {\n            $test();\n\n            $thrown = false;\n        } catch (Throwable $exception) {\n            $thrown = $exception instanceof $expectedClass && ($expectedClassCallback === null || $expectedClassCallback($exception));\n\n            $actualMessage = $exception->getMessage();\n        }\n\n        Assert::assertTrue(\n            $thrown,\n            sprintf('Failed asserting that exception of type \"%s\" was thrown.', $expectedClass)\n        );\n\n        if (isset($expectedMessage)) {\n            if (! isset($actualMessage)) {\n                Assert::fail(\n                    sprintf(\n                        'Failed asserting that exception of type \"%s\" with message \"%s\" was thrown.',\n                        $expectedClass,\n                        $expectedMessage\n                    )\n                );\n            } else {\n                Assert::assertStringContainsString($expectedMessage, $actualMessage);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given callback does not throw an exception.\n     *\n     * @param  \\Closure  $test\n     * @return $this\n     */\n    protected function assertDoesntThrow(Closure $test)\n    {\n        try {\n            $test();\n\n            $thrown = false;\n        } catch (Throwable $exception) {\n            $thrown = true;\n\n            $exceptionClass = get_class($exception);\n            $exceptionMessage = $exception->getMessage();\n        }\n\n        Assert::assertTrue(\n            ! $thrown,\n            sprintf('Unexpected exception of type %s with message %s was thrown.', $exceptionClass ?? null, $exceptionMessage ?? null)\n        );\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithRedis.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Exception;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Redis\\RedisManager;\nuse Illuminate\\Support\\Env;\n\ntrait InteractsWithRedis\n{\n    /**\n     * Indicate connection failed if redis is not available.\n     *\n     * @var bool\n     */\n    private static $connectionFailedOnceWithDefaultsSkip = false;\n\n    /**\n     * Redis manager instance.\n     *\n     * @var array<string, \\Illuminate\\Redis\\RedisManager>\n     */\n    private $redis;\n\n    /**\n     * Setup redis connection.\n     *\n     * @return void\n     */\n    public function setUpRedis()\n    {\n        if (! extension_loaded('redis')) {\n            $this->markTestSkipped('The redis extension is not installed. Please install the extension to enable '.__CLASS__);\n        }\n\n        if (static::$connectionFailedOnceWithDefaultsSkip) {\n            $this->markTestSkipped('Trying default host/port failed, please set environment variable REDIS_HOST & REDIS_PORT to enable '.__CLASS__);\n        }\n\n        $app = $this->app ?? new Application;\n        $host = Env::get('REDIS_HOST', '127.0.0.1');\n        $port = Env::get('REDIS_PORT', 6379);\n\n        foreach (static::redisDriverProvider() as $driver) {\n            if (Env::get('REDIS_CLUSTER_HOSTS_AND_PORTS')) {\n                $config = [\n                    'options' => [\n                        'cluster' => 'redis',\n                        'prefix' => 'test_',\n                    ],\n                    'clusters' => [\n                        'default' => array_map(\n                            static fn ($hostAndPort) => [\n                                'host' => explode(':', $hostAndPort)[0],\n                                'port' => explode(':', $hostAndPort)[1],\n                            ],\n                            explode(',', Env::get('REDIS_CLUSTER_HOSTS_AND_PORTS')),\n                        ),\n                    ],\n                ];\n            } else {\n                $config = [\n                    'options' => [\n                        'prefix' => 'test_',\n                    ],\n                    'default' => [\n                        'host' => $host,\n                        'port' => $port,\n                        'database' => 5,\n                        'timeout' => 0.5,\n                        'name' => 'default',\n                    ],\n                    'cache' => [\n                        'host' => $host,\n                        'port' => $port,\n                        'database' => 6,\n                        'timeout' => 0.5,\n                    ],\n                ];\n            }\n            $this->redis[$driver[0]] = new RedisManager($app, $driver[0], $config);\n        }\n\n        $defaultDriver = Env::get('REDIS_CLIENT', 'phpredis');\n\n        try {\n            $this->redis[$defaultDriver]->connection()->flushdb();\n        } catch (Exception) {\n            if ($host === '127.0.0.1' && $port === 6379 && Env::get('REDIS_HOST') === null) {\n                static::$connectionFailedOnceWithDefaultsSkip = true;\n\n                $this->markTestSkipped('Trying default host/port failed, please set environment variable REDIS_HOST & REDIS_PORT to enable '.__CLASS__);\n            }\n        }\n\n        $app->instance('redis', $this->redis[$defaultDriver]);\n    }\n\n    /**\n     * Teardown redis connection.\n     *\n     * @return void\n     */\n    public function tearDownRedis()\n    {\n        if (static::$connectionFailedOnceWithDefaultsSkip === true) {\n            return;\n        }\n\n        if (isset($this->redis['phpredis'])) {\n            $this->redis['phpredis']->connection()->flushdb();\n        }\n\n        foreach (static::redisDriverProvider() as $driver) {\n            if (isset($this->redis[$driver[0]])) {\n                $this->redis[$driver[0]]->connection()->disconnect();\n            }\n        }\n    }\n\n    /**\n     * Get redis driver provider.\n     *\n     * @return array\n     */\n    public static function redisDriverProvider()\n    {\n        return [\n            ['predis'],\n            ['phpredis'],\n        ];\n    }\n\n    /**\n     * Run test if redis is available.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function ifRedisAvailable($callback)\n    {\n        $this->setUpRedis();\n\n        $callback();\n\n        $this->tearDownRedis();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithSession.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\ntrait InteractsWithSession\n{\n    /**\n     * Set the session to the given array.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function withSession(array $data)\n    {\n        $this->session($data);\n\n        return $this;\n    }\n\n    /**\n     * Set the session to the given array.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function session(array $data)\n    {\n        $this->startSession();\n\n        foreach ($data as $key => $value) {\n            $this->app['session']->put($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Start the session for the application.\n     *\n     * @return $this\n     */\n    protected function startSession()\n    {\n        if (! $this->app['session']->isStarted()) {\n            $this->app['session']->start();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Flush all of the current session data.\n     *\n     * @return $this\n     */\n    public function flushSession()\n    {\n        $this->startSession();\n\n        $this->app['session']->flush();\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithTestCaseLifecycle.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Cookie\\Middleware\\EncryptCookies;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Foundation\\Bootstrap\\HandleExceptions;\nuse Illuminate\\Foundation\\Bootstrap\\RegisterProviders;\nuse Illuminate\\Foundation\\Console\\AboutCommand;\nuse Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Foundation\\Http\\Middleware\\TrimStrings;\nuse Illuminate\\Foundation\\Testing\\Attributes\\SetUp;\nuse Illuminate\\Foundation\\Testing\\Attributes\\TearDown;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Foundation\\Testing\\DatabaseTransactions;\nuse Illuminate\\Foundation\\Testing\\DatabaseTruncation;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Foundation\\Testing\\WithFaker;\nuse Illuminate\\Foundation\\Testing\\WithoutMiddleware;\nuse Illuminate\\Http\\Client\\Response;\nuse Illuminate\\Http\\Middleware\\HandleCors;\nuse Illuminate\\Http\\Middleware\\TrustHosts;\nuse Illuminate\\Http\\Middleware\\TrustProxies;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Queue\\Console\\WorkCommand;\nuse Illuminate\\Queue\\Queue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\EncodedHtmlString;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\ParallelTesting;\nuse Illuminate\\Support\\Once;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Validation\\Validator;\nuse Illuminate\\View\\Component;\nuse Mockery;\nuse Mockery\\Exception\\InvalidCountException;\nuse PHPUnit\\Metadata\\Annotation\\Parser\\Registry as PHPUnitRegistry;\nuse ReflectionClass;\nuse Throwable;\n\ntrait InteractsWithTestCaseLifecycle\n{\n    /**\n     * The Illuminate application instance.\n     *\n     * @var \\Illuminate\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The callbacks that should be run after the application is created.\n     *\n     * @var array\n     */\n    protected $afterApplicationCreatedCallbacks = [];\n\n    /**\n     * The callbacks that should be run before the application is destroyed.\n     *\n     * @var array\n     */\n    protected $beforeApplicationDestroyedCallbacks = [];\n\n    /**\n     * The exception thrown while running an application destruction callback.\n     *\n     * @var \\Throwable\n     */\n    protected $callbackException;\n\n    /**\n     * Indicates if we have made it through the base setUp function.\n     *\n     * @var bool\n     */\n    protected $setUpHasRun = false;\n\n    /**\n     * Setup the test environment.\n     *\n     * @internal\n     *\n     * @return void\n     */\n    protected function setUpTheTestEnvironment(): void\n    {\n        Facade::clearResolvedInstances();\n\n        if (! $this->app) {\n            $this->refreshApplication();\n\n            ParallelTesting::callSetUpTestCaseCallbacks($this);\n        }\n\n        $this->setUpTraits();\n\n        foreach ($this->afterApplicationCreatedCallbacks as $callback) {\n            $callback();\n        }\n\n        Model::setEventDispatcher($this->app['events']);\n\n        $this->setUpHasRun = true;\n    }\n\n    /**\n     * Clean up the testing environment before the next test.\n     *\n     * @internal\n     *\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function tearDownTheTestEnvironment(): void\n    {\n        if ($this->app) {\n            $this->callBeforeApplicationDestroyedCallbacks();\n\n            ParallelTesting::callTearDownTestCaseCallbacks($this);\n\n            $this->app->flush();\n\n            $this->app = null;\n        }\n\n        $this->setUpHasRun = false;\n\n        if (property_exists($this, 'serverVariables')) {\n            $this->serverVariables = [];\n        }\n\n        if (property_exists($this, 'defaultHeaders')) {\n            $this->defaultHeaders = [];\n        }\n\n        if (class_exists('Mockery')) {\n            if ($container = Mockery::getContainer()) {\n                $this->addToAssertionCount($container->mockery_getExpectationCount());\n            }\n\n            try {\n                Mockery::close();\n            } catch (InvalidCountException $e) {\n                if (! Str::contains($e->getMethodName(), ['doWrite', 'askQuestion'])) {\n                    throw $e;\n                }\n            }\n        }\n\n        if (class_exists(Carbon::class)) {\n            Carbon::setTestNow();\n        }\n\n        if (class_exists(CarbonImmutable::class)) {\n            CarbonImmutable::setTestNow();\n        }\n\n        $this->afterApplicationCreatedCallbacks = [];\n        $this->beforeApplicationDestroyedCallbacks = [];\n\n        if (property_exists($this, 'originalExceptionHandler')) {\n            $this->originalExceptionHandler = null;\n        }\n\n        if (property_exists($this, 'originalDeprecationHandler')) {\n            $this->originalDeprecationHandler = null;\n        }\n\n        AboutCommand::flushState();\n        Artisan::forgetBootstrappers();\n        Component::flushCache();\n        Component::forgetComponentsResolver();\n        Component::forgetFactory();\n        ConvertEmptyStringsToNull::flushState();\n        Factory::flushState();\n        EncodedHtmlString::flushState();\n        EncryptCookies::flushState();\n        HandleCors::flushState();\n        HandleExceptions::flushState($this);\n        JsonApiResource::flushState();\n        JsonResource::flushState();\n        Markdown::flushState();\n        Migrator::withoutMigrations([]);\n        Once::flush();\n        PreventRequestsDuringMaintenance::flushState();\n        Queue::createPayloadUsing(null);\n        RegisterProviders::flushState();\n        Response::flushState();\n        Sleep::fake(false);\n        Str::resetFactoryState();\n        TrimStrings::flushState();\n        TrustProxies::flushState();\n        TrustHosts::flushState();\n        PreventRequestForgery::flushState();\n        Validator::flushState();\n        WorkCommand::flushState();\n\n        if ($this->callbackException) {\n            throw $this->callbackException;\n        }\n    }\n\n    /**\n     * Boot the testing helper traits.\n     *\n     * @return array\n     */\n    protected function setUpTraits()\n    {\n        $uses = $this->traitsUsedByTest ?? array_flip(class_uses_recursive(static::class));\n\n        if (isset($uses[RefreshDatabase::class])) {\n            $this->refreshDatabase();\n        }\n\n        if (isset($uses[DatabaseMigrations::class])) {\n            $this->runDatabaseMigrations();\n        }\n\n        if (isset($uses[DatabaseTruncation::class])) {\n            $this->truncateDatabaseTables();\n        }\n\n        if (isset($uses[DatabaseTransactions::class])) {\n            $this->beginDatabaseTransaction();\n        }\n\n        if (isset($uses[WithoutMiddleware::class])) {\n            $this->disableMiddlewareForAllTests();\n        }\n\n        if (isset($uses[WithFaker::class])) {\n            $this->setUpFaker();\n        }\n\n        foreach ($uses as $trait) {\n            if (method_exists($this, $method = 'setUp'.class_basename($trait))) {\n                $this->{$method}();\n            }\n\n            if (method_exists($this, $method = 'tearDown'.class_basename($trait))) {\n                $this->beforeApplicationDestroyed(fn () => $this->{$method}());\n            }\n\n            foreach ((new ReflectionClass($trait))->getMethods() as $method) {\n                if ($method->getAttributes(SetUp::class) !== []) {\n                    $this->{$method->getName()}();\n                }\n\n                if ($method->getAttributes(TearDown::class) !== []) {\n                    $this->beforeApplicationDestroyed(fn () => $this->{$method->getName()}());\n                }\n            }\n        }\n\n        return $uses;\n    }\n\n    /**\n     * Clean up the testing environment before the next test case.\n     *\n     * @internal\n     *\n     * @return void\n     */\n    public static function tearDownAfterClassUsingTestCase()\n    {\n        if (class_exists(PHPUnitRegistry::class)) {\n            (function () {\n                $this->classDocBlocks = [];\n                $this->methodDocBlocks = [];\n            })->call(PHPUnitRegistry::getInstance());\n        }\n    }\n\n    /**\n     * Register a callback to be run after the application is created.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function afterApplicationCreated(callable $callback)\n    {\n        $this->afterApplicationCreatedCallbacks[] = $callback;\n\n        if ($this->setUpHasRun) {\n            $callback();\n        }\n    }\n\n    /**\n     * Register a callback to be run before the application is destroyed.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function beforeApplicationDestroyed(callable $callback)\n    {\n        $this->beforeApplicationDestroyedCallbacks[] = $callback;\n    }\n\n    /**\n     * Execute the application's pre-destruction callbacks.\n     *\n     * @return void\n     */\n    protected function callBeforeApplicationDestroyedCallbacks()\n    {\n        foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {\n            try {\n                $callback();\n            } catch (Throwable $e) {\n                if (! $this->callbackException) {\n                    $this->callbackException = $e;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithTime.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Foundation\\Testing\\Wormhole;\nuse Illuminate\\Support\\Carbon;\n\ntrait InteractsWithTime\n{\n    /**\n     * @template TReturn of mixed\n     *\n     * Freeze time.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? \\Illuminate\\Support\\Carbon : TReturn)\n     */\n    public function freezeTime($callback = null)\n    {\n        $result = $this->travelTo($now = Carbon::now(), $callback);\n\n        return is_null($callback) ? $now : $result;\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Freeze time at the beginning of the current second.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? \\Illuminate\\Support\\Carbon : TReturn)\n     */\n    public function freezeSecond($callback = null)\n    {\n        $result = $this->travelTo($now = Carbon::now()->startOfSecond(), $callback);\n\n        return is_null($callback) ? $now : $result;\n    }\n\n    /**\n     * Begin travelling to another time.\n     *\n     * @param  int  $value\n     * @return \\Illuminate\\Foundation\\Testing\\Wormhole\n     */\n    public function travel($value)\n    {\n        return new Wormhole($value);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel to another time.\n     *\n     * @param  \\DateTimeInterface|\\Closure|\\Illuminate\\Support\\Carbon|string|bool|null  $date\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function travelTo($date, $callback = null)\n    {\n        Carbon::setTestNow($date);\n\n        if ($callback) {\n            return tap($callback($date), function () {\n                Carbon::setTestNow();\n            });\n        }\n    }\n\n    /**\n     * Travel back to the current time.\n     *\n     * @return \\DateTimeInterface\n     */\n    public function travelBack()\n    {\n        return Wormhole::back();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/InteractsWithViews.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Support\\Facades\\View as ViewFacade;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Illuminate\\Testing\\TestComponent;\nuse Illuminate\\Testing\\TestView;\nuse Illuminate\\View\\View;\n\ntrait InteractsWithViews\n{\n    /**\n     * Create a new TestView from the given view.\n     *\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @return \\Illuminate\\Testing\\TestView\n     */\n    protected function view(string $view, $data = [])\n    {\n        return new TestView(view($view, $data));\n    }\n\n    /**\n     * Render the contents of the given Blade template string.\n     *\n     * @param  string  $template\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @return \\Illuminate\\Testing\\TestView\n     */\n    protected function blade(string $template, $data = [])\n    {\n        $tempDirectory = sys_get_temp_dir();\n\n        if (! in_array($tempDirectory, ViewFacade::getFinder()->getPaths())) {\n            ViewFacade::addLocation(sys_get_temp_dir());\n        }\n\n        $tempFileInfo = pathinfo(tempnam($tempDirectory, 'laravel-blade'));\n\n        $tempFile = $tempFileInfo['dirname'].'/'.$tempFileInfo['filename'].'.blade.php';\n\n        file_put_contents($tempFile, $template);\n\n        return new TestView(view($tempFileInfo['filename'], $data));\n    }\n\n    /**\n     * Render the given view component.\n     *\n     * @param  string  $componentClass\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @return \\Illuminate\\Testing\\TestComponent\n     */\n    protected function component(string $componentClass, $data = [])\n    {\n        $component = $this->app->make($componentClass, $data);\n\n        $view = value($component->resolveView(), $data);\n\n        $view = $view instanceof View\n            ? $view->with($component->data())\n            : view($view, $component->data());\n\n        return new TestComponent($component, $view);\n    }\n\n    /**\n     * Populate the shared view error bag with the given errors.\n     *\n     * @param  array  $errors\n     * @param  string  $key\n     * @return $this\n     */\n    protected function withViewErrors(array $errors, $key = 'default')\n    {\n        ViewFacade::share('errors', (new ViewErrorBag)->put($key, new MessageBag($errors)));\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\nuse BackedEnum;\nuse Illuminate\\Contracts\\Http\\Kernel as HttpKernel;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Testing\\LoggedExceptionCollection;\nuse Illuminate\\Testing\\TestResponse;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile as SymfonyUploadedFile;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\ntrait MakesHttpRequests\n{\n    /**\n     * Additional headers for the request.\n     *\n     * @var array\n     */\n    protected $defaultHeaders = [];\n\n    /**\n     * Additional cookies for the request.\n     *\n     * @var array\n     */\n    protected $defaultCookies = [];\n\n    /**\n     * Additional cookies will not be encrypted for the request.\n     *\n     * @var array\n     */\n    protected $unencryptedCookies = [];\n\n    /**\n     * Additional server variables for the request.\n     *\n     * @var array\n     */\n    protected $serverVariables = [];\n\n    /**\n     * Indicates whether redirects should be followed.\n     *\n     * @var bool\n     */\n    protected $followRedirects = false;\n\n    /**\n     * Indicates whether cookies should be encrypted.\n     *\n     * @var bool\n     */\n    protected $encryptCookies = true;\n\n    /**\n     * Indicated whether JSON requests should be performed \"with credentials\" (cookies).\n     *\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials\n     *\n     * @var bool\n     */\n    protected $withCredentials = false;\n\n    /**\n     * Define additional headers to be sent with the request.\n     *\n     * @param  array  $headers\n     * @return $this\n     */\n    public function withHeaders(array $headers)\n    {\n        $this->defaultHeaders = array_merge($this->defaultHeaders, $headers);\n\n        return $this;\n    }\n\n    /**\n     * Add a header to be sent with the request.\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @return $this\n     */\n    public function withHeader(string $name, string $value)\n    {\n        $this->defaultHeaders[$name] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Remove a header from the request.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function withoutHeader(string $name)\n    {\n        unset($this->defaultHeaders[$name]);\n\n        return $this;\n    }\n\n    /**\n     * Remove headers from the request.\n     *\n     * @param  array  $headers\n     * @return $this\n     */\n    public function withoutHeaders(array $headers)\n    {\n        foreach ($headers as $name) {\n            $this->withoutHeader($name);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an authorization token for the request.\n     *\n     * @param  string  $token\n     * @param  string  $type\n     * @return $this\n     */\n    public function withToken(string $token, string $type = 'Bearer')\n    {\n        return $this->withHeader('Authorization', $type.' '.$token);\n    }\n\n    /**\n     * Add a basic authentication header to the request with the given credentials.\n     *\n     * @param  string  $username\n     * @param  string  $password\n     * @return $this\n     */\n    public function withBasicAuth(string $username, string $password)\n    {\n        return $this->withToken(base64_encode(\"$username:$password\"), 'Basic');\n    }\n\n    /**\n     * Remove the authorization token from the request.\n     *\n     * @return $this\n     */\n    public function withoutToken()\n    {\n        return $this->withoutHeader('Authorization');\n    }\n\n    /**\n     * Flush all the configured headers.\n     *\n     * @return $this\n     */\n    public function flushHeaders()\n    {\n        $this->defaultHeaders = [];\n\n        return $this;\n    }\n\n    /**\n     * Define a set of server variables to be sent with the requests.\n     *\n     * @param  array  $server\n     * @return $this\n     */\n    public function withServerVariables(array $server)\n    {\n        $this->serverVariables = $server;\n\n        return $this;\n    }\n\n    /**\n     * Disable middleware for the test.\n     *\n     * @param  string|array|null  $middleware\n     * @return $this\n     */\n    public function withoutMiddleware($middleware = null)\n    {\n        if (is_null($middleware)) {\n            $this->app->instance('middleware.disable', true);\n\n            return $this;\n        }\n\n        foreach ((array) $middleware as $abstract) {\n            $this->app->instance($abstract, new class\n            {\n                public function handle($request, $next)\n                {\n                    return $next($request);\n                }\n            });\n        }\n\n        return $this;\n    }\n\n    /**\n     * Enable the given middleware for the test.\n     *\n     * @param  string|array|null  $middleware\n     * @return $this\n     */\n    public function withMiddleware($middleware = null)\n    {\n        if (is_null($middleware)) {\n            unset($this->app['middleware.disable']);\n\n            return $this;\n        }\n\n        foreach ((array) $middleware as $abstract) {\n            unset($this->app[$abstract]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Define additional cookies to be sent with the request.\n     *\n     * @param  array  $cookies\n     * @return $this\n     */\n    public function withCookies(array $cookies)\n    {\n        $this->defaultCookies = array_merge($this->defaultCookies, $cookies);\n\n        return $this;\n    }\n\n    /**\n     * Add a cookie to be sent with the request.\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @return $this\n     */\n    public function withCookie(string $name, string $value)\n    {\n        $this->defaultCookies[$name] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Define additional cookies will not be encrypted before sending with the request.\n     *\n     * @param  array  $cookies\n     * @return $this\n     */\n    public function withUnencryptedCookies(array $cookies)\n    {\n        $this->unencryptedCookies = array_merge($this->unencryptedCookies, $cookies);\n\n        return $this;\n    }\n\n    /**\n     * Add a cookie will not be encrypted before sending with the request.\n     *\n     * @param  string  $name\n     * @param  string  $value\n     * @return $this\n     */\n    public function withUnencryptedCookie(string $name, string $value)\n    {\n        $this->unencryptedCookies[$name] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Automatically follow any redirects returned from the response.\n     *\n     * @return $this\n     */\n    public function followingRedirects()\n    {\n        $this->followRedirects = true;\n\n        return $this;\n    }\n\n    /**\n     * Include cookies and authorization headers for JSON requests.\n     *\n     * @return $this\n     */\n    public function withCredentials()\n    {\n        $this->withCredentials = true;\n\n        return $this;\n    }\n\n    /**\n     * Disable automatic encryption of cookie values.\n     *\n     * @return $this\n     */\n    public function disableCookieEncryption()\n    {\n        $this->encryptCookies = false;\n\n        return $this;\n    }\n\n    /**\n     * Set the referer header and previous URL session value from a given URL in order to simulate a previous request.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function from(string $url)\n    {\n        $this->app['session']->setPreviousUrl($url);\n\n        return $this->withHeader('referer', $url);\n    }\n\n    /**\n     * Set the referer header and previous URL session value from a given route in order to simulate a previous request.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @return $this\n     */\n    public function fromRoute(BackedEnum|string $name, $parameters = [])\n    {\n        return $this->from($this->app['url']->route($name, $parameters));\n    }\n\n    /**\n     * Set the Precognition header to \"true\".\n     *\n     * @return $this\n     */\n    public function withPrecognition()\n    {\n        return $this->withHeader('Precognition', 'true');\n    }\n\n    /**\n     * Visit the given URI with a GET request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function get($uri, array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('GET', $uri, [], $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with a GET request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function getJson($uri, array $headers = [], $options = 0)\n    {\n        return $this->json('GET', $uri, [], $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with a POST request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function post($uri, array $data = [], array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('POST', $uri, $data, $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with a POST request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function postJson($uri, array $data = [], array $headers = [], $options = 0)\n    {\n        return $this->json('POST', $uri, $data, $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with a PUT request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function put($uri, array $data = [], array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('PUT', $uri, $data, $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with a PUT request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function putJson($uri, array $data = [], array $headers = [], $options = 0)\n    {\n        return $this->json('PUT', $uri, $data, $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with a PATCH request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function patch($uri, array $data = [], array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('PATCH', $uri, $data, $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with a PATCH request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function patchJson($uri, array $data = [], array $headers = [], $options = 0)\n    {\n        return $this->json('PATCH', $uri, $data, $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with a DELETE request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function delete($uri, array $data = [], array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('DELETE', $uri, $data, $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with a DELETE request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function deleteJson($uri, array $data = [], array $headers = [], $options = 0)\n    {\n        return $this->json('DELETE', $uri, $data, $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with an OPTIONS request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function options($uri, array $data = [], array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('OPTIONS', $uri, $data, $cookies, [], $server);\n    }\n\n    /**\n     * Visit the given URI with an OPTIONS request, expecting a JSON response.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function optionsJson($uri, array $data = [], array $headers = [], $options = 0)\n    {\n        return $this->json('OPTIONS', $uri, $data, $headers, $options);\n    }\n\n    /**\n     * Visit the given URI with a HEAD request.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $headers\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function head($uri, array $headers = [])\n    {\n        $server = $this->transformHeadersToServerVars($headers);\n\n        $cookies = $this->prepareCookiesForRequest();\n\n        return $this->call('HEAD', $uri, [], $cookies, [], $server);\n    }\n\n    /**\n     * Call the given URI with a JSON request.\n     *\n     * @param  string  $method\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $data\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function json($method, $uri, array $data = [], array $headers = [], $options = 0)\n    {\n        $files = $this->extractFilesFromDataArray($data);\n\n        $content = json_encode($data, $options);\n\n        $headers = array_merge([\n            'CONTENT_LENGTH' => mb_strlen($content, '8bit'),\n            'CONTENT_TYPE' => 'application/json',\n            'Accept' => 'application/json',\n        ], $headers);\n\n        return $this->call(\n            $method,\n            $uri,\n            [],\n            $this->prepareCookiesForJsonRequest(),\n            $files,\n            $this->transformHeadersToServerVars($headers),\n            $content\n        );\n    }\n\n    /**\n     * Call the given URI and return the Response.\n     *\n     * @param  string  $method\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @param  array  $parameters\n     * @param  array  $cookies\n     * @param  array  $files\n     * @param  array  $server\n     * @param  string|null  $content\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)\n    {\n        $kernel = $this->app->make(HttpKernel::class);\n\n        $files = array_merge($files, $this->extractFilesFromDataArray($parameters));\n\n        $symfonyRequest = SymfonyRequest::create(\n            $this->prepareUrlForRequest($uri), $method, $parameters,\n            $cookies, $files, array_replace($this->serverVariables, $server), $content\n        );\n\n        $response = $kernel->handle(\n            $request = $this->createTestRequest($symfonyRequest)\n        );\n\n        $kernel->terminate($request, $response);\n\n        if ($this->followRedirects) {\n            $response = $this->followRedirects($response);\n        }\n\n        return $this->createTestResponse($response, $request);\n    }\n\n    /**\n     * Turn the given URI into a fully-qualified URL.\n     *\n     * @param  \\Illuminate\\Support\\Uri|string  $uri\n     * @return string\n     */\n    protected function prepareUrlForRequest($uri)\n    {\n        $uri = $uri instanceof Uri ? $uri->value() : $uri;\n\n        if (str_starts_with($uri, '/')) {\n            $uri = substr($uri, 1);\n        }\n\n        return trim(url($uri), '/');\n    }\n\n    /**\n     * Transform headers array to array of $_SERVER vars with HTTP_* format.\n     *\n     * @param  array  $headers\n     * @return array\n     */\n    protected function transformHeadersToServerVars(array $headers)\n    {\n        return (new Collection(array_merge($this->defaultHeaders, $headers)))->mapWithKeys(function ($value, $name) {\n            $name = strtr(strtoupper($name), '-', '_');\n\n            return [$this->formatServerHeaderKey($name) => $value];\n        })->all();\n    }\n\n    /**\n     * Format the header name for the server array.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function formatServerHeaderKey($name)\n    {\n        if (! str_starts_with($name, 'HTTP_') && $name !== 'CONTENT_TYPE' && $name !== 'REMOTE_ADDR') {\n            return 'HTTP_'.$name;\n        }\n\n        return $name;\n    }\n\n    /**\n     * Extract the file uploads from the given data array.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function extractFilesFromDataArray(&$data)\n    {\n        $files = [];\n\n        foreach ($data as $key => $value) {\n            if ($value instanceof SymfonyUploadedFile) {\n                $files[$key] = $value;\n\n                unset($data[$key]);\n            }\n\n            if (is_array($value)) {\n                $files[$key] = $this->extractFilesFromDataArray($value);\n\n                $data[$key] = $value;\n            }\n        }\n\n        return $files;\n    }\n\n    /**\n     * If enabled, encrypt cookie values for request.\n     *\n     * @return array\n     */\n    protected function prepareCookiesForRequest()\n    {\n        if (! $this->encryptCookies) {\n            return array_merge($this->defaultCookies, $this->unencryptedCookies);\n        }\n\n        return (new Collection($this->defaultCookies))\n            ->map(fn ($value, $key) => encrypt(CookieValuePrefix::create($key, app('encrypter')->getKey()).$value, false))\n            ->merge($this->unencryptedCookies)\n            ->all();\n    }\n\n    /**\n     * If enabled, add cookies for JSON requests.\n     *\n     * @return array\n     */\n    protected function prepareCookiesForJsonRequest()\n    {\n        return $this->withCredentials ? $this->prepareCookiesForRequest() : [];\n    }\n\n    /**\n     * Follow a redirect chain until a non-redirect is received.\n     *\n     * @param  \\Illuminate\\Http\\Response|\\Illuminate\\Testing\\TestResponse  $response\n     * @return \\Illuminate\\Http\\Response|\\Illuminate\\Testing\\TestResponse\n     */\n    protected function followRedirects($response)\n    {\n        $this->followRedirects = false;\n\n        while ($response->isRedirect()) {\n            $response = $this->get($response->headers->get('Location'));\n        }\n\n        return $response;\n    }\n\n    /**\n     * Create the request instance used for testing from the given Symfony request.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $symfonyRequest\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function createTestRequest($symfonyRequest)\n    {\n        return Request::createFromBase($symfonyRequest);\n    }\n\n    /**\n     * Create the test response instance from the given response.\n     *\n     * @param  \\Illuminate\\Http\\Response  $response\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Testing\\TestResponse\n     */\n    protected function createTestResponse($response, $request)\n    {\n        return tap(TestResponse::fromBaseResponse($response, $request), function ($response) {\n            $response->withExceptions(\n                $this->app->bound(LoggedExceptionCollection::class)\n                    ? $this->app->make(LoggedExceptionCollection::class)\n                    : new LoggedExceptionCollection\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Concerns/WithoutExceptionHandlingHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Concerns;\n\ninterface WithoutExceptionHandlingHandler\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/DatabaseMigrations.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Testing\\Traits\\CanConfigureMigrationCommands;\n\ntrait DatabaseMigrations\n{\n    use CanConfigureMigrationCommands;\n\n    /**\n     * Define hooks to migrate the database before and after each test.\n     *\n     * @return void\n     */\n    public function runDatabaseMigrations()\n    {\n        $this->beforeRefreshingDatabase();\n        $this->refreshTestDatabase();\n        $this->afterRefreshingDatabase();\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->artisan('migrate:rollback');\n\n            RefreshDatabaseState::$migrated = false;\n        });\n    }\n\n    /**\n     * Refresh a conventional test database.\n     *\n     * @return void\n     */\n    protected function refreshTestDatabase()\n    {\n        $this->artisan('migrate:fresh', $this->migrateFreshUsing());\n\n        $this->app[Kernel::class]->setArtisan(null);\n    }\n\n    /**\n     * Perform any work that should take place before the database has started refreshing.\n     *\n     * @return void\n     */\n    protected function beforeRefreshingDatabase()\n    {\n        // ...\n    }\n\n    /**\n     * Perform any work that should take place once the database has finished refreshing.\n     *\n     * @return void\n     */\n    protected function afterRefreshingDatabase()\n    {\n        // ...\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/DatabaseTransactions.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\ntrait DatabaseTransactions\n{\n    /**\n     * Handle database transactions on the specified connections.\n     *\n     * @return void\n     */\n    public function beginDatabaseTransaction()\n    {\n        $database = $this->app->make('db');\n\n        $connections = $this->connectionsToTransact();\n\n        $this->app->instance('db.transactions', $transactionsManager = new DatabaseTransactionsManager($connections));\n\n        foreach ($connections as $name) {\n            $connection = $database->connection($name);\n            $connection->setTransactionManager($transactionsManager);\n            $dispatcher = $connection->getEventDispatcher();\n\n            $connection->unsetEventDispatcher();\n            $connection->beginTransaction();\n            $connection->setEventDispatcher($dispatcher);\n        }\n\n        $this->beforeApplicationDestroyed(function () use ($database) {\n            foreach ($this->connectionsToTransact() as $name) {\n                $connection = $database->connection($name);\n                $dispatcher = $connection->getEventDispatcher();\n\n                $connection->unsetEventDispatcher();\n                $connection->rollBack();\n                $connection->setEventDispatcher($dispatcher);\n                $connection->disconnect();\n            }\n        });\n    }\n\n    /**\n     * The database connections that should have transactions.\n     *\n     * @return array\n     */\n    protected function connectionsToTransact()\n    {\n        return property_exists($this, 'connectionsToTransact')\n            ? $this->connectionsToTransact\n            : [null];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/DatabaseTransactionsManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Database\\DatabaseTransactionsManager as BaseManager;\n\nclass DatabaseTransactionsManager extends BaseManager\n{\n    /**\n     * The names of the connections transacting during tests.\n     */\n    protected array $connectionsTransacting;\n\n    /**\n     * Create a new database transaction manager instance.\n     *\n     * @param  array  $connectionsTransacting\n     */\n    public function __construct(array $connectionsTransacting)\n    {\n        parent::__construct();\n\n        $this->connectionsTransacting = $connectionsTransacting;\n    }\n\n    /**\n     * Register a transaction callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function addCallback($callback)\n    {\n        // If there are no transactions, we'll run the callbacks right away. Also, we'll run it\n        // right away when we're in test mode and we only have the wrapping transaction. For\n        // every other case, we'll queue up the callback to run after the commit happens.\n        if ($this->callbackApplicableTransactions()->count() === 0) {\n            return $callback();\n        }\n\n        $this->pendingTransactions->last()->addCallback($callback);\n    }\n\n    /**\n     * Get the transactions that are applicable to callbacks.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Database\\DatabaseTransactionRecord>\n     */\n    public function callbackApplicableTransactions()\n    {\n        return $this->pendingTransactions->skip(count($this->connectionsTransacting))->values();\n    }\n\n    /**\n     * Determine if after commit callbacks should be executed for the given transaction level.\n     *\n     * @param  int  $level\n     * @return bool\n     */\n    public function afterCommitCallbacksShouldBeExecuted($level)\n    {\n        return $level === 1;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/DatabaseTruncation.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Foundation\\Testing\\Traits\\CanConfigureMigrationCommands;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\ntrait DatabaseTruncation\n{\n    use CanConfigureMigrationCommands;\n\n    /**\n     * The cached names of the database tables for each connection.\n     *\n     * @var array\n     */\n    protected static array $allTables;\n\n    /**\n     * Truncate the database tables for all configured connections.\n     *\n     * @return void\n     */\n    protected function truncateDatabaseTables(): void\n    {\n        $this->beforeTruncatingDatabase();\n\n        // Migrate and seed the database on first run...\n        if (! RefreshDatabaseState::$migrated) {\n            $this->artisan('migrate:fresh', $this->migrateFreshUsing());\n\n            $this->app[Kernel::class]->setArtisan(null);\n\n            RefreshDatabaseState::$migrated = true;\n\n            return;\n        }\n\n        // Always clear any test data on subsequent runs...\n        $this->truncateTablesForAllConnections();\n\n        if ($seeder = $this->seeder()) {\n            // Use a specific seeder class...\n            $this->artisan('db:seed', ['--class' => $seeder]);\n        } elseif ($this->shouldSeed()) {\n            // Use the default seeder class...\n            $this->artisan('db:seed');\n        }\n\n        $this->afterTruncatingDatabase();\n    }\n\n    /**\n     * Truncate the database tables for all configured connections.\n     *\n     * @return void\n     */\n    protected function truncateTablesForAllConnections(): void\n    {\n        $database = $this->app->make('db');\n\n        (new Collection($this->connectionsToTruncate()))\n            ->each(function ($name) use ($database) {\n                $connection = $database->connection($name);\n\n                $connection->getSchemaBuilder()->withoutForeignKeyConstraints(\n                    fn () => $this->truncateTablesForConnection($connection, $name)\n                );\n            });\n    }\n\n    /**\n     * Truncate the database tables for the given database connection.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  string|null  $name\n     * @return void\n     */\n    protected function truncateTablesForConnection(ConnectionInterface $connection, ?string $name): void\n    {\n        $dispatcher = $connection->getEventDispatcher();\n\n        $connection->unsetEventDispatcher();\n\n        (new Collection($this->getAllTablesForConnection($connection, $name)))\n            ->when(\n                $this->tablesToTruncate($connection, $name),\n                function (Collection $tables, array $tablesToTruncate) {\n                    return $tables->filter(fn (array $table) => $this->tableExistsIn($table, $tablesToTruncate));\n                },\n                function (Collection $tables) use ($connection, $name) {\n                    $exceptTables = $this->exceptTables($connection, $name);\n\n                    return $tables->reject(fn (array $table) => $this->tableExistsIn($table, $exceptTables));\n                }\n            )\n            ->each(function (array $table) use ($connection) {\n                $connection->withoutTablePrefix(function ($connection) use ($table) {\n                    $table = $connection->table($table['schema_qualified_name']);\n\n                    if ($table->exists()) {\n                        $table->truncate();\n                    }\n                });\n            });\n\n        $connection->setEventDispatcher($dispatcher);\n    }\n\n    /**\n     * Get all the tables that belong to the connection.\n     */\n    protected function getAllTablesForConnection(ConnectionInterface $connection, ?string $name): array\n    {\n        if (isset(static::$allTables[$name])) {\n            return static::$allTables[$name];\n        }\n\n        $schema = $connection->getSchemaBuilder();\n\n        return static::$allTables[$name] = Arr::from($schema->getTables($schema->getCurrentSchemaListing()));\n    }\n\n    /**\n     * Determine if a table exists in the given list, with or without its schema.\n     */\n    protected function tableExistsIn(array $table, array $tables): bool\n    {\n        return $table['schema']\n            ? ! empty(array_intersect([$table['name'], $table['schema_qualified_name']], $tables))\n            : in_array($table['name'], $tables);\n    }\n\n    /**\n     * The database connections that should have their tables truncated.\n     *\n     * @return array\n     */\n    protected function connectionsToTruncate(): array\n    {\n        return property_exists($this, 'connectionsToTruncate')\n            ? $this->connectionsToTruncate\n            : [null];\n    }\n\n    /**\n     * Get the tables that should be truncated.\n     */\n    protected function tablesToTruncate(ConnectionInterface $connection, ?string $connectionName): ?array\n    {\n        return property_exists($this, 'tablesToTruncate') && is_array($this->tablesToTruncate)\n            ? $this->tablesToTruncate[$connectionName] ?? $this->tablesToTruncate\n            : null;\n    }\n\n    /**\n     * Get the tables that should not be truncated.\n     */\n    protected function exceptTables(ConnectionInterface $connection, ?string $connectionName): array\n    {\n        $migrations = $this->app['config']->get('database.migrations');\n\n        $migrationsTable = is_array($migrations) ? ($migrations['table'] ?? 'migrations') : $migrations;\n        $migrationsTable = $connection->getTablePrefix().$migrationsTable;\n\n        return property_exists($this, 'exceptTables') && is_array($this->exceptTables)\n            ? array_merge(\n                $this->exceptTables[$connectionName] ?? $this->exceptTables,\n                [$migrationsTable],\n            )\n            : [$migrationsTable];\n    }\n\n    /**\n     * Perform any work that should take place before the database has started truncating.\n     *\n     * @return void\n     */\n    protected function beforeTruncatingDatabase(): void\n    {\n        //\n    }\n\n    /**\n     * Perform any work that should take place once the database has finished truncating.\n     *\n     * @return void\n     */\n    protected function afterTruncatingDatabase(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/LazilyRefreshDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\ntrait LazilyRefreshDatabase\n{\n    use RefreshDatabase {\n        refreshDatabase as baseRefreshDatabase;\n    }\n\n    /**\n     * Define hooks to migrate the database before and after each test.\n     *\n     * @return void\n     */\n    public function refreshDatabase()\n    {\n        $database = $this->app->make('db');\n\n        $callback = function () {\n            if (RefreshDatabaseState::$lazilyRefreshed) {\n                return;\n            }\n\n            RefreshDatabaseState::$lazilyRefreshed = true;\n\n            if (property_exists($this, 'mockConsoleOutput')) {\n                $shouldMockOutput = $this->mockConsoleOutput;\n\n                $this->mockConsoleOutput = false;\n            }\n\n            $this->baseRefreshDatabase();\n\n            if (property_exists($this, 'mockConsoleOutput')) {\n                $this->mockConsoleOutput = $shouldMockOutput;\n            }\n        };\n\n        $database->beforeStartingTransaction($callback);\n        $database->beforeExecuting($callback);\n\n        $this->beforeApplicationDestroyed(function () {\n            RefreshDatabaseState::$lazilyRefreshed = false;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/RefreshDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Testing\\Traits\\CanConfigureMigrationCommands;\n\ntrait RefreshDatabase\n{\n    use CanConfigureMigrationCommands;\n\n    /**\n     * Define hooks to migrate the database before and after each test.\n     *\n     * @return void\n     */\n    public function refreshDatabase()\n    {\n        $this->beforeRefreshingDatabase();\n\n        if ($this->usingInMemoryDatabases()) {\n            $this->restoreInMemoryDatabase();\n        }\n\n        $this->refreshTestDatabase();\n\n        $this->afterRefreshingDatabase();\n    }\n\n    /**\n     * Determine if any of the connections transacting is using in-memory databases.\n     *\n     * @return bool\n     */\n    protected function usingInMemoryDatabases()\n    {\n        foreach ($this->connectionsToTransact() as $name) {\n            if ($this->usingInMemoryDatabase($name)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if a given database connection is an in-memory database.\n     *\n     * @return bool\n     */\n    protected function usingInMemoryDatabase(?string $name = null)\n    {\n        if (is_null($name)) {\n            $name = config('database.default');\n        }\n\n        return config(\"database.connections.{$name}.database\") === ':memory:';\n    }\n\n    /**\n     * Restore the in-memory database between tests.\n     *\n     * @return void\n     */\n    protected function restoreInMemoryDatabase()\n    {\n        $database = $this->app->make('db');\n\n        foreach ($this->connectionsToTransact() as $name) {\n            if (isset(RefreshDatabaseState::$inMemoryConnections[$name])) {\n                $database->connection($name)->setPdo(RefreshDatabaseState::$inMemoryConnections[$name]);\n            }\n        }\n    }\n\n    /**\n     * Refresh a conventional test database.\n     *\n     * @return void\n     */\n    protected function refreshTestDatabase()\n    {\n        if (! RefreshDatabaseState::$migrated) {\n            $this->migrateDatabases();\n\n            $this->app[Kernel::class]->setArtisan(null);\n\n            $this->updateLocalCacheOfInMemoryDatabases();\n\n            RefreshDatabaseState::$migrated = true;\n        }\n\n        $this->beginDatabaseTransaction();\n    }\n\n    /**\n     * Update locally cached in-memory PDO connections after migration.\n     *\n     * @return void\n     */\n    protected function updateLocalCacheOfInMemoryDatabases()\n    {\n        $database = $this->app->make('db');\n\n        foreach ($this->connectionsToTransact() as $name) {\n            if ($this->usingInMemoryDatabase($name)) {\n                RefreshDatabaseState::$inMemoryConnections[$name] = $database->connection($name)->getPdo();\n            }\n        }\n    }\n\n    /**\n     * Migrate the database.\n     *\n     * @return void\n     */\n    protected function migrateDatabases()\n    {\n        $this->artisan('migrate:fresh', $this->migrateFreshUsing());\n    }\n\n    /**\n     * Begin a database transaction on the testing database.\n     *\n     * @return void\n     */\n    public function beginDatabaseTransaction()\n    {\n        $database = $this->app->make('db');\n\n        $connections = $this->connectionsToTransact();\n\n        $this->app->instance('db.transactions', $transactionsManager = new DatabaseTransactionsManager($connections));\n\n        foreach ($connections as $name) {\n            $connection = $database->connection($name);\n\n            $connection->setTransactionManager($transactionsManager);\n\n            if ($this->usingInMemoryDatabase($name)) {\n                RefreshDatabaseState::$inMemoryConnections[$name] ??= $connection->getPdo();\n            }\n\n            $dispatcher = $connection->getEventDispatcher();\n\n            $connection->unsetEventDispatcher();\n            $connection->beginTransaction();\n            $connection->setEventDispatcher($dispatcher);\n        }\n\n        $this->beforeApplicationDestroyed(function () use ($database) {\n            foreach ($this->connectionsToTransact() as $name) {\n                $connection = $database->connection($name);\n                $dispatcher = $connection->getEventDispatcher();\n\n                $connection->unsetEventDispatcher();\n\n                if ($connection->getPdo() && ! $connection->getPdo()->inTransaction()) {\n                    RefreshDatabaseState::$migrated = false;\n                }\n\n                $connection->rollBack();\n                $connection->setEventDispatcher($dispatcher);\n                $connection->disconnect();\n            }\n        });\n    }\n\n    /**\n     * The database connections that should have transactions.\n     *\n     * @return array\n     */\n    protected function connectionsToTransact()\n    {\n        return property_exists($this, 'connectionsToTransact')\n            ? $this->connectionsToTransact\n            : [config('database.default')];\n    }\n\n    /**\n     * Perform any work that should take place before the database has started refreshing.\n     *\n     * @return void\n     */\n    protected function beforeRefreshingDatabase()\n    {\n        // ...\n    }\n\n    /**\n     * Perform any work that should take place once the database has finished refreshing.\n     *\n     * @return void\n     */\n    protected function afterRefreshingDatabase()\n    {\n        // ...\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/RefreshDatabaseState.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nclass RefreshDatabaseState\n{\n    /**\n     * The current SQLite in-memory database connections.\n     *\n     * @var array<string, \\PDO>\n     */\n    public static $inMemoryConnections = [];\n\n    /**\n     * Indicates if the test database has been migrated.\n     *\n     * @var bool\n     */\n    public static $migrated = false;\n\n    /**\n     * Indicates if a lazy refresh hook has been invoked.\n     *\n     * @var bool\n     */\n    public static $lazilyRefreshed = false;\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/TestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Application;\nuse PHPUnit\\Framework\\TestCase as BaseTestCase;\n\nabstract class TestCase extends BaseTestCase\n{\n    use Concerns\\InteractsWithContainer,\n        Concerns\\MakesHttpRequests,\n        Concerns\\InteractsWithAuthentication,\n        Concerns\\InteractsWithConsole,\n        Concerns\\InteractsWithDatabase,\n        Concerns\\InteractsWithDeprecationHandling,\n        Concerns\\InteractsWithExceptionHandling,\n        Concerns\\InteractsWithSession,\n        Concerns\\InteractsWithTime,\n        Concerns\\InteractsWithTestCaseLifecycle,\n        Concerns\\InteractsWithViews;\n\n    /**\n     * The list of trait that this test uses, fetched recursively.\n     *\n     * @var array<class-string, int>\n     */\n    protected array $traitsUsedByTest;\n\n    /**\n     * Creates the application.\n     *\n     * @return \\Illuminate\\Foundation\\Application\n     */\n    public function createApplication()\n    {\n        $app = require Application::inferBasePath().'/bootstrap/app.php';\n\n        $this->traitsUsedByTest = array_flip(class_uses_recursive(static::class));\n\n        if (isset(CachedState::$cachedConfig) &&\n            isset($this->traitsUsedByTest[WithCachedConfig::class])) {\n            $this->markConfigCached($app);\n        }\n\n        if (isset(CachedState::$cachedRoutes) &&\n            isset($this->traitsUsedByTest[WithCachedRoutes::class])) {\n            $app->booting(fn () => $this->markRoutesCached($app));\n        }\n\n        $app->make(Kernel::class)->bootstrap();\n\n        return $app;\n    }\n\n    /**\n     * Setup the test environment.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $this->setUpTheTestEnvironment();\n    }\n\n    /**\n     * Refresh the application instance.\n     *\n     * @return void\n     */\n    protected function refreshApplication()\n    {\n        $this->app = $this->createApplication();\n    }\n\n    /**\n     * Clean up the testing environment before the next test.\n     *\n     * @return void\n     *\n     * @throws \\Mockery\\Exception\\InvalidCountException\n     */\n    protected function tearDown(): void\n    {\n        $this->tearDownTheTestEnvironment();\n    }\n\n    /**\n     * Clean up the testing environment before the next test case.\n     *\n     * @return void\n     */\n    public static function tearDownAfterClass(): void\n    {\n        static::tearDownAfterClassUsingTestCase();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Traits/CanConfigureMigrationCommands.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing\\Traits;\n\nuse Illuminate\\Foundation\\Testing\\Attributes\\Seed;\nuse Illuminate\\Foundation\\Testing\\Attributes\\Seeder;\nuse ReflectionClass;\n\ntrait CanConfigureMigrationCommands\n{\n    /**\n     * The parameters that should be used when running \"migrate:fresh\".\n     *\n     * @return array\n     */\n    protected function migrateFreshUsing()\n    {\n        $seeder = $this->seeder();\n\n        return array_merge(\n            [\n                '--drop-views' => $this->shouldDropViews(),\n                '--drop-types' => $this->shouldDropTypes(),\n            ],\n            $seeder ? ['--seeder' => $seeder] : ['--seed' => $this->shouldSeed()]\n        );\n    }\n\n    /**\n     * Determine if views should be dropped when refreshing the database.\n     *\n     * @return bool\n     */\n    protected function shouldDropViews()\n    {\n        return property_exists($this, 'dropViews') ? $this->dropViews : false;\n    }\n\n    /**\n     * Determine if types should be dropped when refreshing the database.\n     *\n     * @return bool\n     */\n    protected function shouldDropTypes()\n    {\n        return property_exists($this, 'dropTypes') ? $this->dropTypes : false;\n    }\n\n    /**\n     * Determine if the seed task should be run when refreshing the database.\n     *\n     * @return bool\n     */\n    protected function shouldSeed()\n    {\n        $class = new ReflectionClass($this);\n\n        do {\n            if (count($class->getAttributes(Seed::class)) > 0) {\n                return true;\n            }\n        } while ($class = $class->getParentClass());\n\n        return property_exists($this, 'seed') ? $this->seed : false;\n    }\n\n    /**\n     * Determine the specific seeder class that should be used when refreshing the database.\n     *\n     * @return mixed\n     */\n    protected function seeder()\n    {\n        $class = new ReflectionClass($this);\n\n        do {\n            $seeder = $class->getAttributes(Seeder::class);\n\n            if (count($seeder) > 0) {\n                return $seeder[0]->newInstance()->class;\n            }\n        } while ($class = $class->getParentClass());\n\n        return property_exists($this, 'seeder') ? $this->seeder : false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/WithCachedConfig.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\LoadConfiguration;\n\ntrait WithCachedConfig\n{\n    /**\n     * After resolving the configuration once, we can cache it for the remaining tests.\n     */\n    protected function setUpWithCachedConfig(): void\n    {\n        if ((CachedState::$cachedConfig ?? null) === null) {\n            CachedState::$cachedConfig = $this->app->make('config')->all();\n        }\n\n        $this->markConfigCached($this->app);\n    }\n\n    /**\n     * Reset the cached configuration.\n     *\n     * This is helpful if some of the tests in the suite apply this trait while others do not.\n     */\n    protected function tearDownWithCachedConfig(): void\n    {\n        LoadConfiguration::alwaysUse(null);\n    }\n\n    /**\n     * Inform the container that the configuration is cached.\n     */\n    protected function markConfigCached(Application $app): void\n    {\n        $app->instance('config_loaded_from_cache', true);\n\n        LoadConfiguration::alwaysUse(static fn () => CachedState::$cachedConfig);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/WithCachedRoutes.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Support\\Providers\\RouteServiceProvider;\n\ntrait WithCachedRoutes\n{\n    /**\n     * After creating the routes once, we can cache them for the remaining tests.\n     *\n     * @return void\n     */\n    protected function setUpWithCachedRoutes(): void\n    {\n        if ((CachedState::$cachedRoutes ?? null) === null) {\n            $routes = $this->app['router']->getRoutes();\n\n            $routes->refreshNameLookups();\n            $routes->refreshActionLookups();\n\n            CachedState::$cachedRoutes = $routes->compile();\n        }\n\n        $this->markRoutesCached($this->app);\n    }\n\n    /**\n     * Reset the route service provider so it's not defaulting to loading cached routes.\n     *\n     * This is helpful if some of the tests in the suite apply this trait while others do not.\n     *\n     * @return void\n     */\n    protected function tearDownWithCachedRoutes(): void\n    {\n        RouteServiceProvider::loadCachedRoutesUsing(null);\n    }\n\n    /**\n     * Inform the container to treat routes as cached.\n     */\n    protected function markRoutesCached(Application $app): void\n    {\n        $app->instance('routes.cached', true);\n\n        RouteServiceProvider::loadCachedRoutesUsing(\n            static fn () => app('router')->setCompiledRoutes(CachedState::$cachedRoutes)\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/WithConsoleEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernel;\n\ntrait WithConsoleEvents\n{\n    /**\n     * Register console events.\n     *\n     * @return void\n     */\n    protected function setUpWithConsoleEvents()\n    {\n        $this->app[ConsoleKernel::class]->rerouteSymfonyCommandEvents();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/WithFaker.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Faker\\Factory;\nuse Faker\\Generator;\n\ntrait WithFaker\n{\n    /**\n     * The Faker instance.\n     *\n     * @var \\Faker\\Generator\n     */\n    protected $faker;\n\n    /**\n     * Setup up the Faker instance.\n     *\n     * @return void\n     */\n    protected function setUpFaker()\n    {\n        $this->faker = $this->makeFaker();\n    }\n\n    /**\n     * Get the default Faker instance for a given locale.\n     *\n     * @param  string|null  $locale\n     * @return \\Faker\\Generator\n     */\n    protected function faker($locale = null)\n    {\n        return is_null($locale) ? $this->faker : $this->makeFaker($locale);\n    }\n\n    /**\n     * Create a Faker instance for the given locale.\n     *\n     * @param  string|null  $locale\n     * @return \\Faker\\Generator\n     */\n    protected function makeFaker($locale = null)\n    {\n        if (isset($this->app)) {\n            $locale ??= $this->app->make('config')->get('app.faker_locale', Factory::DEFAULT_LOCALE);\n\n            if ($this->app->bound(Generator::class)) {\n                return $this->app->make(Generator::class, ['locale' => $locale]);\n            }\n        }\n\n        return Factory::create($locale ?? Factory::DEFAULT_LOCALE);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/WithoutMiddleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Exception;\n\ntrait WithoutMiddleware\n{\n    /**\n     * Prevent all middleware from being executed for this test class.\n     *\n     * @throws \\Exception\n     */\n    public function disableMiddlewareForAllTests()\n    {\n        if (method_exists($this, 'withoutMiddleware')) {\n            $this->withoutMiddleware();\n        } else {\n            throw new Exception('Unable to disable middleware. MakesHttpRequests trait not used.');\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Testing/Wormhole.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Testing;\n\nuse Illuminate\\Support\\Carbon;\n\nclass Wormhole\n{\n    /**\n     * The amount of time to travel.\n     *\n     * @var int\n     */\n    public $value;\n\n    /**\n     * Create a new wormhole instance.\n     *\n     * @param  int  $value\n     */\n    public function __construct($value)\n    {\n        $this->value = $value;\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of microseconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function microsecond($callback = null)\n    {\n        return $this->microseconds($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of microseconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function microseconds($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addMicroseconds($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of milliseconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function millisecond($callback = null)\n    {\n        return $this->milliseconds($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of milliseconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function milliseconds($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addMilliseconds($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of seconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function second($callback = null)\n    {\n        return $this->seconds($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of seconds.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function seconds($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addSeconds($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of minutes.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function minute($callback = null)\n    {\n        return $this->minutes($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of minutes.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function minutes($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addMinutes($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of hours.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function hour($callback = null)\n    {\n        return $this->hours($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of hours.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function hours($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addHours($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of days.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function day($callback = null)\n    {\n        return $this->days($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of days.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function days($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addDays($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of weeks.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function week($callback = null)\n    {\n        return $this->weeks($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of weeks.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function weeks($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addWeeks($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of months.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function month($callback = null)\n    {\n        return $this->months($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of months.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function months($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addMonths($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of years.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function year($callback = null)\n    {\n        return $this->years($callback);\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Travel forward the given number of years.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    public function years($callback = null)\n    {\n        Carbon::setTestNow(Carbon::now()->addYears($this->value));\n\n        return $this->handleCallback($callback);\n    }\n\n    /**\n     * Travel back to the current time.\n     *\n     * @return \\DateTimeInterface\n     */\n    public static function back()\n    {\n        Carbon::setTestNow();\n\n        return Carbon::now();\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Handle the given optional execution callback.\n     *\n     * @param  (callable(): TReturn)|null  $callback\n     * @return ($callback is null ? void : TReturn)\n     */\n    protected function handleCallback($callback)\n    {\n        if ($callback) {\n            return tap($callback(), function () {\n                Carbon::setTestNow();\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Validation/ValidatesRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation\\Validation;\n\nuse Illuminate\\Contracts\\Validation\\Factory;\nuse Illuminate\\Foundation\\Precognition;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\n\ntrait ValidatesRequests\n{\n    /**\n     * Run the validation routine against the given validator.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator|array  $validator\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validateWith($validator, ?Request $request = null)\n    {\n        $request = $request ?: request();\n\n        if (is_array($validator)) {\n            $validator = $this->getValidationFactory()->make($request->all(), $validator);\n        }\n\n        if ($request->isPrecognitive()) {\n            $validator->after(Precognition::afterValidationHook($request))\n                ->setRules(\n                    $request->filterPrecognitiveRules($validator->getRulesWithoutPlaceholders())\n                );\n        }\n\n        return $validator->validate();\n    }\n\n    /**\n     * Validate the given request with the given rules.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validate(Request $request, array $rules,\n                             array $messages = [], array $attributes = [])\n    {\n        $validator = $this->getValidationFactory()->make(\n            $request->all(), $rules, $messages, $attributes\n        );\n\n        if ($request->isPrecognitive()) {\n            $validator->after(Precognition::afterValidationHook($request))\n                ->setRules(\n                    $request->filterPrecognitiveRules($validator->getRulesWithoutPlaceholders())\n                );\n        }\n\n        return $validator->validate();\n    }\n\n    /**\n     * Validate the given request with the given rules.\n     *\n     * @param  string  $errorBag\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validateWithBag($errorBag, Request $request, array $rules,\n                                    array $messages = [], array $attributes = [])\n    {\n        try {\n            return $this->validate($request, $rules, $messages, $attributes);\n        } catch (ValidationException $e) {\n            $e->errorBag = $errorBag;\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Get a validation factory instance.\n     *\n     * @return \\Illuminate\\Contracts\\Validation\\Factory\n     */\n    protected function getValidationFactory()\n    {\n        return app(Factory::class);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/Vite.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Js;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass Vite implements Htmlable\n{\n    use Macroable;\n\n    /**\n     * The Content Security Policy nonce to apply to all generated tags.\n     *\n     * @var string|null\n     */\n    protected $nonce;\n\n    /**\n     * The key to check for integrity hashes within the manifest.\n     *\n     * @var string|false\n     */\n    protected $integrityKey = 'integrity';\n\n    /**\n     * The configured entry points.\n     *\n     * @var array\n     */\n    protected $entryPoints = [];\n\n    /**\n     * The path to the \"hot\" file.\n     *\n     * @var string|null\n     */\n    protected $hotFile;\n\n    /**\n     * The path to the build directory.\n     *\n     * @var string\n     */\n    protected $buildDirectory = 'build';\n\n    /**\n     * The name of the manifest file.\n     *\n     * @var string\n     */\n    protected $manifestFilename = 'manifest.json';\n\n    /**\n     * The custom asset path resolver.\n     *\n     * @var callable|null\n     */\n    protected $assetPathResolver = null;\n\n    /**\n     * The script tag attributes resolvers.\n     *\n     * @var array\n     */\n    protected $scriptTagAttributesResolvers = [];\n\n    /**\n     * The style tag attributes resolvers.\n     *\n     * @var array\n     */\n    protected $styleTagAttributesResolvers = [];\n\n    /**\n     * The preload tag attributes resolvers.\n     *\n     * @var array\n     */\n    protected $preloadTagAttributesResolvers = [];\n\n    /**\n     * The preloaded assets.\n     *\n     * @var array\n     */\n    protected $preloadedAssets = [];\n\n    /**\n     * The cached manifest files.\n     *\n     * @var array\n     */\n    protected static $manifests = [];\n\n    /**\n     * The prefetching strategy to use.\n     *\n     * @var null|'waterfall'|'aggressive'\n     */\n    protected $prefetchStrategy = null;\n\n    /**\n     * The number of assets to load concurrently when using the \"waterfall\" strategy.\n     *\n     * @var int\n     */\n    protected $prefetchConcurrently = 3;\n\n    /**\n     * The name of the event that should trigger prefetching. The event must be dispatched on the `window`.\n     *\n     * @var string\n     */\n    protected $prefetchEvent = 'load';\n\n    /**\n     * Get the preloaded assets.\n     *\n     * @return array\n     */\n    public function preloadedAssets()\n    {\n        return $this->preloadedAssets;\n    }\n\n    /**\n     * Get the Content Security Policy nonce applied to all generated tags.\n     *\n     * @return string|null\n     */\n    public function cspNonce()\n    {\n        return $this->nonce;\n    }\n\n    /**\n     * Generate or set a Content Security Policy nonce to apply to all generated tags.\n     *\n     * @param  string|null  $nonce\n     * @return string\n     */\n    public function useCspNonce($nonce = null)\n    {\n        return $this->nonce = $nonce ?? Str::random(40);\n    }\n\n    /**\n     * Use the given key to detect integrity hashes in the manifest.\n     *\n     * @param  string|false  $key\n     * @return $this\n     */\n    public function useIntegrityKey($key)\n    {\n        $this->integrityKey = $key;\n\n        return $this;\n    }\n\n    /**\n     * Set the Vite entry points.\n     *\n     * @param  array  $entryPoints\n     * @return $this\n     */\n    public function withEntryPoints($entryPoints)\n    {\n        $this->entryPoints = $entryPoints;\n\n        return $this;\n    }\n\n    /**\n     * Merge additional Vite entry points with the current set.\n     *\n     * @param  array  $entryPoints\n     * @return $this\n     */\n    public function mergeEntryPoints($entryPoints)\n    {\n        return $this->withEntryPoints(array_unique([\n            ...$this->entryPoints,\n            ...$entryPoints,\n        ]));\n    }\n\n    /**\n     * Set the filename for the manifest file.\n     *\n     * @param  string  $filename\n     * @return $this\n     */\n    public function useManifestFilename($filename)\n    {\n        $this->manifestFilename = $filename;\n\n        return $this;\n    }\n\n    /**\n     * Resolve asset paths using the provided resolver.\n     *\n     * @param  callable|null  $resolver\n     * @return $this\n     */\n    public function createAssetPathsUsing($resolver)\n    {\n        $this->assetPathResolver = $resolver;\n\n        return $this;\n    }\n\n    /**\n     * Get the Vite \"hot\" file path.\n     *\n     * @return string\n     */\n    public function hotFile()\n    {\n        return $this->hotFile ?? public_path('/hot');\n    }\n\n    /**\n     * Set the Vite \"hot\" file path.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useHotFile($path)\n    {\n        $this->hotFile = $path;\n\n        return $this;\n    }\n\n    /**\n     * Set the Vite build directory.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function useBuildDirectory($path)\n    {\n        $this->buildDirectory = $path;\n\n        return $this;\n    }\n\n    /**\n     * Use the given callback to resolve attributes for script tags.\n     *\n     * @param  (callable(string, string, ?array, ?array): array)|array  $attributes\n     * @return $this\n     */\n    public function useScriptTagAttributes($attributes)\n    {\n        if (! is_callable($attributes)) {\n            $attributes = fn () => $attributes;\n        }\n\n        $this->scriptTagAttributesResolvers[] = $attributes;\n\n        return $this;\n    }\n\n    /**\n     * Use the given callback to resolve attributes for style tags.\n     *\n     * @param  (callable(string, string, ?array, ?array): array)|array  $attributes\n     * @return $this\n     */\n    public function useStyleTagAttributes($attributes)\n    {\n        if (! is_callable($attributes)) {\n            $attributes = fn () => $attributes;\n        }\n\n        $this->styleTagAttributesResolvers[] = $attributes;\n\n        return $this;\n    }\n\n    /**\n     * Use the given callback to resolve attributes for preload tags.\n     *\n     * @param  (callable(string, string, ?array, ?array): (array|false))|array|false  $attributes\n     * @return $this\n     */\n    public function usePreloadTagAttributes($attributes)\n    {\n        if (! is_callable($attributes)) {\n            $attributes = fn () => $attributes;\n        }\n\n        $this->preloadTagAttributesResolvers[] = $attributes;\n\n        return $this;\n    }\n\n    /**\n     * Eagerly prefetch assets.\n     *\n     * @param  int|null  $concurrency\n     * @param  string  $event\n     * @return $this\n     */\n    public function prefetch($concurrency = null, $event = 'load')\n    {\n        $this->prefetchEvent = $event;\n\n        return $concurrency === null\n            ? $this->usePrefetchStrategy('aggressive')\n            : $this->usePrefetchStrategy('waterfall', ['concurrency' => $concurrency]);\n    }\n\n    /**\n     * Use the \"waterfall\" prefetching strategy.\n     *\n     * @return $this\n     */\n    public function useWaterfallPrefetching(?int $concurrency = null)\n    {\n        return $this->usePrefetchStrategy('waterfall', [\n            'concurrency' => $concurrency ?? $this->prefetchConcurrently,\n        ]);\n    }\n\n    /**\n     * Use the \"aggressive\" prefetching strategy.\n     *\n     * @return $this\n     */\n    public function useAggressivePrefetching()\n    {\n        return $this->usePrefetchStrategy('aggressive');\n    }\n\n    /**\n     * Set the prefetching strategy.\n     *\n     * @param  'waterfall'|'aggressive'|null  $strategy\n     * @param  array  $config\n     * @return $this\n     */\n    public function usePrefetchStrategy($strategy, $config = [])\n    {\n        $this->prefetchStrategy = $strategy;\n\n        if ($strategy === 'waterfall') {\n            $this->prefetchConcurrently = $config['concurrency'] ?? $this->prefetchConcurrently;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Generate Vite tags for an entrypoint.\n     *\n     * @param  string|string[]  $entrypoints\n     * @param  string|null  $buildDirectory\n     * @return \\Illuminate\\Support\\HtmlString\n     *\n     * @throws \\Exception\n     */\n    public function __invoke($entrypoints, $buildDirectory = null)\n    {\n        $entrypoints = new Collection($entrypoints);\n        $buildDirectory ??= $this->buildDirectory;\n\n        if ($this->isRunningHot()) {\n            return new HtmlString(\n                $entrypoints\n                    ->prepend('@vite/client')\n                    ->map(fn ($entrypoint) => $this->makeTagForChunk($entrypoint, $this->hotAsset($entrypoint), null, null))\n                    ->join('')\n            );\n        }\n\n        $manifest = $this->manifest($buildDirectory);\n\n        $tags = new Collection;\n        $preloads = new Collection;\n\n        foreach ($entrypoints as $entrypoint) {\n            $chunk = $this->chunk($manifest, $entrypoint);\n\n            $preloads->push([\n                $chunk['src'],\n                $this->assetPath(\"{$buildDirectory}/{$chunk['file']}\"),\n                $chunk,\n                $manifest,\n            ]);\n\n            foreach ($chunk['imports'] ?? [] as $import) {\n                $preloads->push([\n                    $import,\n                    $this->assetPath(\"{$buildDirectory}/{$manifest[$import]['file']}\"),\n                    $manifest[$import],\n                    $manifest,\n                ]);\n\n                foreach ($manifest[$import]['css'] ?? [] as $css) {\n                    $partialManifest = (new Collection($manifest))->where('file', $css);\n\n                    $preloads->push([\n                        $partialManifest->keys()->first(),\n                        $this->assetPath(\"{$buildDirectory}/{$css}\"),\n                        $partialManifest->first(),\n                        $manifest,\n                    ]);\n\n                    $tags->push($this->makeTagForChunk(\n                        $partialManifest->keys()->first(),\n                        $this->assetPath(\"{$buildDirectory}/{$css}\"),\n                        $partialManifest->first(),\n                        $manifest\n                    ));\n                }\n            }\n\n            $tags->push($this->makeTagForChunk(\n                $entrypoint,\n                $this->assetPath(\"{$buildDirectory}/{$chunk['file']}\"),\n                $chunk,\n                $manifest\n            ));\n\n            foreach ($chunk['css'] ?? [] as $css) {\n                $partialManifest = (new Collection($manifest))->where('file', $css);\n\n                $preloads->push([\n                    $partialManifest->keys()->first(),\n                    $this->assetPath(\"{$buildDirectory}/{$css}\"),\n                    $partialManifest->first(),\n                    $manifest,\n                ]);\n\n                $tags->push($this->makeTagForChunk(\n                    $partialManifest->keys()->first(),\n                    $this->assetPath(\"{$buildDirectory}/{$css}\"),\n                    $partialManifest->first(),\n                    $manifest\n                ));\n            }\n        }\n\n        [$stylesheets, $scripts] = $tags->unique()->partition(fn ($tag) => str_starts_with($tag, '<link'));\n\n        $preloads = $preloads->unique()\n            ->sortByDesc(fn ($args) => $this->isCssPath($args[1]))\n            ->map(fn ($args) => $this->makePreloadTagForChunk(...$args));\n\n        $base = $preloads->join('').$stylesheets->join('').$scripts->join('');\n\n        if ($this->prefetchStrategy === null || $this->isRunningHot()) {\n            return new HtmlString($base);\n        }\n\n        $discoveredImports = [];\n\n        return (new Collection($entrypoints))\n            ->flatMap(fn ($entrypoint) => (new Collection($manifest[$entrypoint]['dynamicImports'] ?? []))\n                ->map(fn ($import) => $manifest[$import])\n                ->filter(fn ($chunk) => str_ends_with($chunk['file'], '.js') || str_ends_with($chunk['file'], '.css'))\n                ->flatMap($f = function ($chunk) use (&$f, $manifest, &$discoveredImports) {\n                    return (new Collection([...$chunk['imports'] ?? [], ...$chunk['dynamicImports'] ?? []]))\n                        ->reject(function ($import) use (&$discoveredImports) {\n                            if (isset($discoveredImports[$import])) {\n                                return true;\n                            }\n\n                            return ! $discoveredImports[$import] = true;\n                        })\n                        ->reduce(\n                            fn ($chunks, $import) => $chunks->merge(\n                                $f($manifest[$import])\n                            ), new Collection([$chunk]))\n                        ->merge((new Collection($chunk['css'] ?? []))->map(\n                            fn ($css) => (new Collection($manifest))->first(fn ($chunk) => $chunk['file'] === $css) ?? [\n                                'file' => $css,\n                            ],\n                        ));\n                })\n                ->map(function ($chunk) use ($buildDirectory, $manifest) {\n                    return (new Collection([\n                        ...$this->resolvePreloadTagAttributes(\n                            $chunk['src'] ?? null,\n                            $url = $this->assetPath(\"{$buildDirectory}/{$chunk['file']}\"),\n                            $chunk,\n                            $manifest,\n                        ),\n                        'rel' => 'prefetch',\n                        'fetchpriority' => 'low',\n                        'href' => $url,\n                    ]))->reject(\n                        fn ($value) => in_array($value, [null, false], true)\n                    )->mapWithKeys(fn ($value, $key) => [\n                        $key = (is_int($key) ? $value : $key) => $value === true ? $key : $value,\n                    ])->all();\n                })\n                ->reject(fn ($attributes) => isset($this->preloadedAssets[$attributes['href']])))\n            ->unique('href')\n            ->values()\n            ->pipe(fn ($assets) => with(Js::from($assets), fn ($assets) => match ($this->prefetchStrategy) {\n                'waterfall' => new HtmlString($base.<<<HTML\n\n                    <script{$this->nonceAttribute()}>\n                         window.addEventListener('{$this->prefetchEvent}', () => window.setTimeout(() => {\n                            const makeLink = (asset) => {\n                                const link = document.createElement('link')\n\n                                Object.keys(asset).forEach((attribute) => {\n                                    link.setAttribute(attribute, asset[attribute])\n                                })\n\n                                return link\n                            }\n\n                            const loadNext = (assets, count) => window.setTimeout(() => {\n                                if (count > assets.length) {\n                                    count = assets.length\n\n                                    if (count === 0) {\n                                        return\n                                    }\n                                }\n\n                                const fragment = new DocumentFragment\n\n                                while (count > 0) {\n                                    const link = makeLink(assets.shift())\n                                    fragment.append(link)\n                                    count--\n\n                                    if (assets.length) {\n                                        link.onload = () => loadNext(assets, 1)\n                                        link.onerror = () => loadNext(assets, 1)\n                                    }\n                                }\n\n                                document.head.append(fragment)\n                            })\n\n                            loadNext({$assets}, {$this->prefetchConcurrently})\n                        }))\n                    </script>\n                    HTML),\n                'aggressive' => new HtmlString($base.<<<HTML\n\n                    <script{$this->nonceAttribute()}>\n                         window.addEventListener('{$this->prefetchEvent}', () => window.setTimeout(() => {\n                            const makeLink = (asset) => {\n                                const link = document.createElement('link')\n\n                                Object.keys(asset).forEach((attribute) => {\n                                    link.setAttribute(attribute, asset[attribute])\n                                })\n\n                                return link\n                            }\n\n                            const fragment = new DocumentFragment;\n                            {$assets}.forEach((asset) => fragment.append(makeLink(asset)))\n                            document.head.append(fragment)\n                         }))\n                    </script>\n                    HTML),\n            }));\n    }\n\n    /**\n     * Make tag for the given chunk.\n     *\n     * @param  string  $src\n     * @param  string  $url\n     * @param  array|null  $chunk\n     * @param  array|null  $manifest\n     * @return string\n     */\n    protected function makeTagForChunk($src, $url, $chunk, $manifest)\n    {\n        if (\n            $this->nonce === null\n            && $this->integrityKey !== false\n            && ! array_key_exists($this->integrityKey, $chunk ?? [])\n            && $this->scriptTagAttributesResolvers === []\n            && $this->styleTagAttributesResolvers === []) {\n            return $this->makeTag($url);\n        }\n\n        if ($this->isCssPath($url)) {\n            return $this->makeStylesheetTagWithAttributes(\n                $url,\n                $this->resolveStylesheetTagAttributes($src, $url, $chunk, $manifest)\n            );\n        }\n\n        return $this->makeScriptTagWithAttributes(\n            $url,\n            $this->resolveScriptTagAttributes($src, $url, $chunk, $manifest)\n        );\n    }\n\n    /**\n     * Make a preload tag for the given chunk.\n     *\n     * @param  string  $src\n     * @param  string  $url\n     * @param  array  $chunk\n     * @param  array  $manifest\n     * @return string\n     */\n    protected function makePreloadTagForChunk($src, $url, $chunk, $manifest)\n    {\n        $attributes = $this->resolvePreloadTagAttributes($src, $url, $chunk, $manifest);\n\n        if ($attributes === false) {\n            return '';\n        }\n\n        $this->preloadedAssets[$url] = $this->parseAttributes(\n            (new Collection($attributes))->forget('href')->all()\n        );\n\n        return '<link '.implode(' ', $this->parseAttributes($attributes)).' />';\n    }\n\n    /**\n     * Resolve the attributes for the chunks generated script tag.\n     *\n     * @param  string  $src\n     * @param  string  $url\n     * @param  array|null  $chunk\n     * @param  array|null  $manifest\n     * @return array\n     */\n    protected function resolveScriptTagAttributes($src, $url, $chunk, $manifest)\n    {\n        $attributes = $this->integrityKey !== false\n            ? ['integrity' => $chunk[$this->integrityKey] ?? false]\n            : [];\n\n        foreach ($this->scriptTagAttributesResolvers as $resolver) {\n            $attributes = array_merge($attributes, $resolver($src, $url, $chunk, $manifest));\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Resolve the attributes for the chunks generated stylesheet tag.\n     *\n     * @param  string  $src\n     * @param  string  $url\n     * @param  array|null  $chunk\n     * @param  array|null  $manifest\n     * @return array\n     */\n    protected function resolveStylesheetTagAttributes($src, $url, $chunk, $manifest)\n    {\n        $attributes = $this->integrityKey !== false\n            ? ['integrity' => $chunk[$this->integrityKey] ?? false]\n            : [];\n\n        foreach ($this->styleTagAttributesResolvers as $resolver) {\n            $attributes = array_merge($attributes, $resolver($src, $url, $chunk, $manifest));\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Resolve the attributes for the chunks generated preload tag.\n     *\n     * @param  string  $src\n     * @param  string  $url\n     * @param  array  $chunk\n     * @param  array  $manifest\n     * @return array|false\n     */\n    protected function resolvePreloadTagAttributes($src, $url, $chunk, $manifest)\n    {\n        $attributes = $this->isCssPath($url) ? [\n            'rel' => 'preload',\n            'as' => 'style',\n            'href' => $url,\n            'nonce' => $this->nonce ?? false,\n            'crossorigin' => $this->resolveStylesheetTagAttributes($src, $url, $chunk, $manifest)['crossorigin'] ?? false,\n        ] : [\n            'rel' => 'modulepreload',\n            'as' => 'script',\n            'href' => $url,\n            'nonce' => $this->nonce ?? false,\n            'crossorigin' => $this->resolveScriptTagAttributes($src, $url, $chunk, $manifest)['crossorigin'] ?? false,\n        ];\n\n        $attributes = $this->integrityKey !== false\n            ? array_merge($attributes, ['integrity' => $chunk[$this->integrityKey] ?? false])\n            : $attributes;\n\n        foreach ($this->preloadTagAttributesResolvers as $resolver) {\n            if (false === ($resolvedAttributes = $resolver($src, $url, $chunk, $manifest))) {\n                return false;\n            }\n\n            $attributes = array_merge($attributes, $resolvedAttributes);\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Generate an appropriate tag for the given URL in HMR mode.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  string  $url\n     * @return string\n     */\n    protected function makeTag($url)\n    {\n        if ($this->isCssPath($url)) {\n            return $this->makeStylesheetTag($url);\n        }\n\n        return $this->makeScriptTag($url);\n    }\n\n    /**\n     * Generate a script tag for the given URL.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  string  $url\n     * @return string\n     */\n    protected function makeScriptTag($url)\n    {\n        return $this->makeScriptTagWithAttributes($url, []);\n    }\n\n    /**\n     * Generate a stylesheet tag for the given URL in HMR mode.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  string  $url\n     * @return string\n     */\n    protected function makeStylesheetTag($url)\n    {\n        return $this->makeStylesheetTagWithAttributes($url, []);\n    }\n\n    /**\n     * Generate a script tag with attributes for the given URL.\n     *\n     * @param  string  $url\n     * @param  array  $attributes\n     * @return string\n     */\n    protected function makeScriptTagWithAttributes($url, $attributes)\n    {\n        $attributes = $this->parseAttributes(array_merge([\n            'type' => 'module',\n            'src' => $url,\n            'nonce' => $this->nonce ?? false,\n        ], $attributes));\n\n        return '<script '.implode(' ', $attributes).'></script>';\n    }\n\n    /**\n     * Generate a link tag with attributes for the given URL.\n     *\n     * @param  string  $url\n     * @param  array  $attributes\n     * @return string\n     */\n    protected function makeStylesheetTagWithAttributes($url, $attributes)\n    {\n        $attributes = $this->parseAttributes(array_merge([\n            'rel' => 'stylesheet',\n            'href' => $url,\n            'nonce' => $this->nonce ?? false,\n        ], $attributes));\n\n        return '<link '.implode(' ', $attributes).' />';\n    }\n\n    /**\n     * Determine whether the given path is a CSS file.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    protected function isCssPath($path)\n    {\n        return preg_match('/\\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\\?[^\\.]*)?$/', $path) === 1;\n    }\n\n    /**\n     * Parse the attributes into key=\"value\" strings.\n     *\n     * @param  array  $attributes\n     * @return array\n     */\n    protected function parseAttributes($attributes)\n    {\n        return (new Collection($attributes))\n            ->reject(fn ($value, $key) => in_array($value, [false, null], true))\n            ->flatMap(fn ($value, $key) => $value === true ? [$key] : [$key => $value])\n            ->map(fn ($value, $key) => is_int($key) ? $value : $key.'=\"'.$value.'\"')\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Generate React refresh runtime script.\n     *\n     * @return \\Illuminate\\Support\\HtmlString|void\n     */\n    public function reactRefresh()\n    {\n        if (! $this->isRunningHot()) {\n            return;\n        }\n\n        $attributes = $this->parseAttributes([\n            'nonce' => $this->cspNonce(),\n        ]);\n\n        return new HtmlString(\n            sprintf(\n                <<<'HTML'\n                <script type=\"module\" %s>\n                    import RefreshRuntime from '%s'\n                    RefreshRuntime.injectIntoGlobalHook(window)\n                    window.$RefreshReg$ = () => {}\n                    window.$RefreshSig$ = () => (type) => type\n                    window.__vite_plugin_react_preamble_installed__ = true\n                </script>\n                HTML,\n                implode(' ', $attributes),\n                $this->hotAsset('@react-refresh')\n            )\n        );\n    }\n\n    /**\n     * Get the path to a given asset when running in HMR mode.\n     *\n     * @return string\n     */\n    protected function hotAsset($asset)\n    {\n        return rtrim(file_get_contents($this->hotFile())).'/'.$asset;\n    }\n\n    /**\n     * Get the URL for an asset.\n     *\n     * @param  string  $asset\n     * @param  string|null  $buildDirectory\n     * @return string\n     */\n    public function asset($asset, $buildDirectory = null)\n    {\n        $buildDirectory ??= $this->buildDirectory;\n\n        if ($this->isRunningHot()) {\n            return $this->hotAsset($asset);\n        }\n\n        $chunk = $this->chunk($this->manifest($buildDirectory), $asset);\n\n        return $this->assetPath($buildDirectory.'/'.$chunk['file']);\n    }\n\n    /**\n     * Get the content of a given asset.\n     *\n     * @param  string  $asset\n     * @param  string|null  $buildDirectory\n     * @return string\n     *\n     * @throws \\Illuminate\\Foundation\\ViteException\n     */\n    public function content($asset, $buildDirectory = null)\n    {\n        $buildDirectory ??= $this->buildDirectory;\n\n        $chunk = $this->chunk($this->manifest($buildDirectory), $asset);\n\n        $path = $this->publicPath($buildDirectory.'/'.$chunk['file']);\n\n        if (! is_file($path) || ! file_exists($path)) {\n            throw new ViteException(\"Unable to locate file from Vite manifest: {$path}.\");\n        }\n\n        return file_get_contents($path);\n    }\n\n    /**\n     * Generate an asset path for the application.\n     *\n     * @param  string  $path\n     * @param  bool|null  $secure\n     * @return string\n     */\n    protected function assetPath($path, $secure = null)\n    {\n        return ($this->assetPathResolver ?? asset(...))($path, $secure);\n    }\n\n    /**\n     * Generate a public path for an asset.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function publicPath($path)\n    {\n        return public_path($path);\n    }\n\n    /**\n     * Get the manifest file for the given build directory.\n     *\n     * @param  string  $buildDirectory\n     * @return array\n     *\n     * @throws \\Illuminate\\Foundation\\ViteManifestNotFoundException\n     */\n    protected function manifest($buildDirectory)\n    {\n        $path = $this->manifestPath($buildDirectory);\n\n        if (! isset(static::$manifests[$path])) {\n            if (! is_file($path)) {\n                throw new ViteManifestNotFoundException(\"Vite manifest not found at: $path\");\n            }\n\n            static::$manifests[$path] = json_decode(file_get_contents($path), true);\n        }\n\n        return static::$manifests[$path];\n    }\n\n    /**\n     * Get the path to the manifest file for the given build directory.\n     *\n     * @param  string  $buildDirectory\n     * @return string\n     */\n    protected function manifestPath($buildDirectory)\n    {\n        return public_path($buildDirectory.'/'.$this->manifestFilename);\n    }\n\n    /**\n     * Get a unique hash representing the current manifest, or null if there is no manifest.\n     *\n     * @param  string|null  $buildDirectory\n     * @return string|null\n     */\n    public function manifestHash($buildDirectory = null)\n    {\n        $buildDirectory ??= $this->buildDirectory;\n\n        if ($this->isRunningHot()) {\n            return null;\n        }\n\n        if (! is_file($path = $this->manifestPath($buildDirectory))) {\n            return null;\n        }\n\n        return md5_file($path) ?: null;\n    }\n\n    /**\n     * Get the chunk for the given entry point / asset.\n     *\n     * @param  array  $manifest\n     * @param  string  $file\n     * @return array\n     *\n     * @throws \\Illuminate\\Foundation\\ViteException\n     */\n    protected function chunk($manifest, $file)\n    {\n        if (! isset($manifest[$file])) {\n            throw new ViteException(\"Unable to locate file in Vite manifest: {$file}.\");\n        }\n\n        return $manifest[$file];\n    }\n\n    /**\n     * Get the nonce attribute for the prefetch script tags.\n     *\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    protected function nonceAttribute()\n    {\n        if ($this->cspNonce() === null) {\n            return new HtmlString('');\n        }\n\n        return new HtmlString(' nonce=\"'.$this->cspNonce().'\"');\n    }\n\n    /**\n     * Determine if the HMR server is running.\n     *\n     * @return bool\n     */\n    public function isRunningHot()\n    {\n        return is_file($this->hotFile());\n    }\n\n    /**\n     * Get the Vite tag content as a string of HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->__invoke($this->entryPoints)->toHtml();\n    }\n\n    /**\n     * Flush state.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        $this->preloadedAssets = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/ViteException.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\nuse Exception;\n\nclass ViteException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/ViteManifestNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Foundation;\n\n/**\n * @deprecated use ViteException\n */\nclass ViteManifestNotFoundException extends ViteException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/helpers.php",
    "content": "<?php\n\nuse Carbon\\CarbonInterface;\nuse Illuminate\\Broadcasting\\FakePendingBroadcast;\nuse Illuminate\\Broadcasting\\PendingBroadcast;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate;\nuse Illuminate\\Contracts\\Auth\\Factory as AuthFactory;\nuse Illuminate\\Contracts\\Auth\\Guard;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastFactory;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Cookie\\Factory as CookieFactory;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Contracts\\Translation\\Translator;\nuse Illuminate\\Contracts\\Validation\\Factory as ValidationFactory;\nuse Illuminate\\Contracts\\Validation\\Validator as ValidatorContract;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Contracts\\View\\View as ViewContract;\nuse Illuminate\\Cookie\\CookieJar;\nuse Illuminate\\Foundation\\Bus\\PendingClosureDispatch;\nuse Illuminate\\Foundation\\Bus\\PendingDispatch;\nuse Illuminate\\Foundation\\Mix;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Response as IlluminateResponse;\nuse Illuminate\\Log\\Context\\Repository as ContextRepository;\nuse Illuminate\\Log\\LogManager;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Uri;\nuse League\\Uri\\Contracts\\UriInterface;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nuse function Illuminate\\Support\\enum_value;\n\nif (! function_exists('abort')) {\n    /**\n     * Throw an HttpException with the given data.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response|\\Illuminate\\Contracts\\Support\\Responsable|int  $code\n     * @param  string  $message\n     * @return never\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     * @throws \\Illuminate\\Http\\Exceptions\\HttpResponseException\n     */\n    function abort($code, $message = '', array $headers = [])\n    {\n        if ($code instanceof Response) {\n            throw new HttpResponseException($code);\n        } elseif ($code instanceof Responsable) {\n            throw new HttpResponseException($code->toResponse(request()));\n        }\n\n        app()->abort($code, $message, $headers);\n    }\n}\n\nif (! function_exists('abort_if')) {\n    /**\n     * Throw an HttpException with the given data if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response|\\Illuminate\\Contracts\\Support\\Responsable|int  $code\n     * @param  string  $message\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    function abort_if($boolean, $code, $message = '', array $headers = []): void\n    {\n        if ($boolean) {\n            abort($code, $message, $headers);\n        }\n    }\n}\n\nif (! function_exists('abort_unless')) {\n    /**\n     * Throw an HttpException with the given data unless the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response|\\Illuminate\\Contracts\\Support\\Responsable|int  $code\n     * @param  string  $message\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    function abort_unless($boolean, $code, $message = '', array $headers = []): void\n    {\n        if (! $boolean) {\n            abort($code, $message, $headers);\n        }\n    }\n}\n\nif (! function_exists('action')) {\n    /**\n     * Generate the URL to a controller action.\n     *\n     * @param  string|array  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     */\n    function action($name, $parameters = [], $absolute = true): string\n    {\n        return app('url')->action($name, $parameters, $absolute);\n    }\n}\n\nif (! function_exists('app')) {\n    /**\n     * Get the available container instance.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>|null  $abstract\n     * @return ($abstract is class-string<TClass> ? TClass : ($abstract is null ? \\Illuminate\\Foundation\\Application : mixed))\n     */\n    function app($abstract = null, array $parameters = [])\n    {\n        if (is_null($abstract)) {\n            return Container::getInstance();\n        }\n\n        return Container::getInstance()->make($abstract, $parameters);\n    }\n}\n\nif (! function_exists('app_path')) {\n    /**\n     * Get the path to the application folder.\n     *\n     * @param  string  $path\n     */\n    function app_path($path = ''): string\n    {\n        return app()->path($path);\n    }\n}\n\nif (! function_exists('asset')) {\n    /**\n     * Generate an asset path for the application.\n     *\n     * @param  string  $path\n     * @param  bool|null  $secure\n     */\n    function asset($path, $secure = null): string\n    {\n        return app('url')->asset($path, $secure);\n    }\n}\n\nif (! function_exists('auth')) {\n    /**\n     * Get the available auth instance.\n     *\n     * @param  string|null  $guard\n     * @return ($guard is null ? \\Illuminate\\Contracts\\Auth\\Factory : \\Illuminate\\Contracts\\Auth\\Guard)\n     */\n    function auth($guard = null): AuthFactory|Guard\n    {\n        if (is_null($guard)) {\n            return app(AuthFactory::class);\n        }\n\n        return app(AuthFactory::class)->guard($guard);\n    }\n}\n\nif (! function_exists('back')) {\n    /**\n     * Create a new redirect response to the previous location.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  mixed  $fallback\n     */\n    function back($status = 302, $headers = [], $fallback = false): RedirectResponse\n    {\n        return app('redirect')->back($status, $headers, $fallback);\n    }\n}\n\nif (! function_exists('base_path')) {\n    /**\n     * Get the path to the base of the install.\n     *\n     * @param  string  $path\n     */\n    function base_path($path = ''): string\n    {\n        return app()->basePath($path);\n    }\n}\n\nif (! function_exists('bcrypt')) {\n    /**\n     * Hash the given value against the bcrypt algorithm.\n     *\n     * @param  string  $value\n     * @param  array  $options\n     */\n    function bcrypt($value, $options = []): string\n    {\n        return app('hash')->driver('bcrypt')->make($value, $options);\n    }\n}\n\nif (! function_exists('broadcast')) {\n    /**\n     * Begin broadcasting an event.\n     *\n     * @param  mixed  $event\n     */\n    function broadcast($event = null): PendingBroadcast\n    {\n        return app(BroadcastFactory::class)->event($event);\n    }\n}\n\nif (! function_exists('broadcast_if')) {\n    /**\n     * Begin broadcasting an event if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  mixed  $event\n     */\n    function broadcast_if($boolean, $event = null): PendingBroadcast\n    {\n        if ($boolean) {\n            return app(BroadcastFactory::class)->event(value($event));\n        } else {\n            return new FakePendingBroadcast;\n        }\n    }\n}\n\nif (! function_exists('broadcast_unless')) {\n    /**\n     * Begin broadcasting an event unless the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  mixed  $event\n     */\n    function broadcast_unless($boolean, $event = null): PendingBroadcast\n    {\n        if (! $boolean) {\n            return app(BroadcastFactory::class)->event(value($event));\n        } else {\n            return new FakePendingBroadcast;\n        }\n    }\n}\n\nif (! function_exists('cache')) {\n    /**\n     * Get / set the specified cache value.\n     *\n     * If an array is passed, we'll assume you want to put to the cache.\n     *\n     * @param  string|array<string, mixed>|null  $key  key|data\n     * @param  mixed  $default  default|expiration|null\n     * @return ($key is null ? \\Illuminate\\Cache\\CacheManager : ($key is string ? mixed : bool))\n     *\n     * @throws \\InvalidArgumentException\n     */\n    function cache($key = null, $default = null)\n    {\n        if (is_null($key)) {\n            return app('cache');\n        }\n\n        if (is_string($key)) {\n            return app('cache')->get($key, $default);\n        }\n\n        if (! is_array($key)) {\n            throw new InvalidArgumentException(\n                'When setting a value in the cache, you must pass an array of key / value pairs.'\n            );\n        }\n\n        return app('cache')->put(key($key), array_first($key), ttl: $default);\n    }\n}\n\nif (! function_exists('config')) {\n    /**\n     * Get / set the specified configuration value.\n     *\n     * If an array is passed as the key, we will assume you want to set an array of values.\n     *\n     * @param  array<string, mixed>|string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? \\Illuminate\\Config\\Repository : ($key is string ? mixed : null))\n     */\n    function config($key = null, $default = null)\n    {\n        if (is_null($key)) {\n            return app('config');\n        }\n\n        if (is_array($key)) {\n            return app('config')->set($key);\n        }\n\n        return app('config')->get($key, $default);\n    }\n}\n\nif (! function_exists('config_path')) {\n    /**\n     * Get the configuration path.\n     *\n     * @param  string  $path\n     */\n    function config_path($path = ''): string\n    {\n        return app()->configPath($path);\n    }\n}\n\nif (! function_exists('context')) {\n    /**\n     * Get / set the specified context value.\n     *\n     * @param  array|string|null  $key\n     * @param  mixed  $default\n     * @return ($key is string ? mixed : \\Illuminate\\Log\\Context\\Repository)\n     */\n    function context($key = null, $default = null)\n    {\n        $context = app(ContextRepository::class);\n\n        return match (true) {\n            is_null($key) => $context,\n            is_array($key) => $context->add($key),\n            default => $context->get($key, $default),\n        };\n    }\n}\n\nif (! function_exists('cookie')) {\n    /**\n     * Create a new cookie instance.\n     *\n     * @param  string|null  $name\n     * @param  string|null  $value\n     * @param  int  $minutes\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @param  bool|null  $secure\n     * @param  bool  $httpOnly\n     * @param  bool  $raw\n     * @param  string|null  $sameSite\n     * @return ($name is null ? \\Illuminate\\Cookie\\CookieJar : \\Symfony\\Component\\HttpFoundation\\Cookie)\n     */\n    function cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null): CookieJar|Cookie\n    {\n        $cookie = app(CookieFactory::class);\n\n        if (is_null($name)) {\n            return $cookie;\n        }\n\n        return $cookie->make($name, $value, $minutes, $path, $domain, $secure, $httpOnly, $raw, $sameSite);\n    }\n}\n\nif (! function_exists('csrf_field')) {\n    /**\n     * Generate a CSRF token form field.\n     */\n    function csrf_field(): HtmlString\n    {\n        return new HtmlString('<input type=\"hidden\" name=\"_token\" value=\"'.csrf_token().'\" autocomplete=\"off\">');\n    }\n}\n\nif (! function_exists('csrf_token')) {\n    /**\n     * Get the CSRF token value.\n     *\n     * @throws \\RuntimeException\n     */\n    function csrf_token(): ?string\n    {\n        $session = app('session');\n\n        if (isset($session)) {\n            return $session->token();\n        }\n\n        throw new RuntimeException('Application session store not set.');\n    }\n}\n\nif (! function_exists('database_path')) {\n    /**\n     * Get the database path.\n     *\n     * @param  string  $path\n     */\n    function database_path($path = ''): string\n    {\n        return app()->databasePath($path);\n    }\n}\n\nif (! function_exists('decrypt')) {\n    /**\n     * Decrypt the given value.\n     *\n     * @param  string  $value\n     * @param  bool  $unserialize\n     * @return mixed\n     */\n    function decrypt($value, $unserialize = true)\n    {\n        return app('encrypter')->decrypt($value, $unserialize);\n    }\n}\n\nif (! function_exists('defer')) {\n    /**\n     * Defer execution of the given callback.\n     *\n     * @return ($callback is null ? \\Illuminate\\Support\\Defer\\DeferredCallbackCollection : \\Illuminate\\Support\\Defer\\DeferredCallback)\n     */\n    function defer(?callable $callback = null, ?string $name = null, bool $always = false): DeferredCallback|DeferredCallbackCollection\n    {\n        return \\Illuminate\\Support\\defer($callback, $name, $always);\n    }\n}\n\nif (! function_exists('dispatch')) {\n    /**\n     * Dispatch a job to its appropriate handler.\n     *\n     * @param  mixed  $job\n     * @return ($job is \\Closure ? \\Illuminate\\Foundation\\Bus\\PendingClosureDispatch : \\Illuminate\\Foundation\\Bus\\PendingDispatch)\n     */\n    function dispatch($job): PendingDispatch|PendingClosureDispatch\n    {\n        return $job instanceof Closure\n            ? new PendingClosureDispatch(CallQueuedClosure::create($job))\n            : new PendingDispatch($job);\n    }\n}\n\nif (! function_exists('dispatch_sync')) {\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  $job\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    function dispatch_sync($job, $handler = null)\n    {\n        return app(Dispatcher::class)->dispatchSync($job, $handler);\n    }\n}\n\nif (! function_exists('encrypt')) {\n    /**\n     * Encrypt the given value.\n     *\n     * @param  mixed  $value\n     * @param  bool  $serialize\n     */\n    function encrypt($value, $serialize = true): string\n    {\n        return app('encrypter')->encrypt($value, $serialize);\n    }\n}\n\nif (! function_exists('event')) {\n    /**\n     * Dispatch an event and call the listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return array|null\n     */\n    function event(...$args)\n    {\n        return app('events')->dispatch(...$args);\n    }\n}\n\nif (! function_exists('fake') && class_exists(\\Faker\\Factory::class)) {\n    /**\n     * Get a faker instance.\n     *\n     * @param  string|null  $locale\n     */\n    function fake($locale = null): \\Faker\\Generator\n    {\n        if (app()->bound('config')) {\n            $locale ??= app('config')->get('app.faker_locale');\n        }\n\n        $locale ??= 'en_US';\n\n        $abstract = \\Faker\\Generator::class.':'.$locale;\n\n        if (! app()->bound($abstract)) {\n            app()->singleton($abstract, fn () => \\Faker\\Factory::create($locale));\n        }\n\n        return app()->make($abstract);\n    }\n}\n\nif (! function_exists('info')) {\n    /**\n     * Write some information to the log.\n     *\n     * @param  string  $message\n     * @param  array  $context\n     */\n    function info($message, $context = []): void\n    {\n        app('log')->info($message, $context);\n    }\n}\n\nif (! function_exists('lang_path')) {\n    /**\n     * Get the path to the language folder.\n     *\n     * @param  string  $path\n     */\n    function lang_path($path = ''): string\n    {\n        return app()->langPath($path);\n    }\n}\n\nif (! function_exists('logger')) {\n    /**\n     * Log a debug message to the logs.\n     *\n     * @param  string|null  $message\n     * @return ($message is null ? \\Psr\\Log\\LoggerInterface : null)\n     */\n    function logger($message = null, array $context = []): ?LoggerInterface\n    {\n        if (is_null($message)) {\n            return app('log');\n        }\n\n        return app('log')->debug($message, $context);\n    }\n}\n\nif (! function_exists('logs')) {\n    /**\n     * Get a log driver instance.\n     *\n     * @param  string|null  $driver\n     * @return ($driver is null ? \\Illuminate\\Log\\LogManager : \\Psr\\Log\\LoggerInterface)\n     */\n    function logs($driver = null): LoggerInterface|LogManager\n    {\n        return $driver ? app('log')->driver($driver) : app('log');\n    }\n}\n\nif (! function_exists('method_field')) {\n    /**\n     * Generate a form field to spoof the HTTP verb used by forms.\n     *\n     * @param  string  $method\n     */\n    function method_field($method): HtmlString\n    {\n        return new HtmlString('<input type=\"hidden\" name=\"_method\" value=\"'.$method.'\">');\n    }\n}\n\nif (! function_exists('mix')) {\n    /**\n     * Get the path to a versioned Mix file.\n     *\n     * @param  string  $path\n     * @param  string  $manifestDirectory\n     *\n     * @throws \\Exception\n     */\n    function mix($path, $manifestDirectory = ''): HtmlString|string\n    {\n        return app(Mix::class)(...func_get_args());\n    }\n}\n\nif (! function_exists('now')) {\n    /**\n     * Create a new Carbon instance for the current time.\n     *\n     * @param  \\DateTimeZone|\\UnitEnum|string|null  $tz\n     */\n    function now($tz = null): CarbonInterface\n    {\n        return Date::now(enum_value($tz));\n    }\n}\n\nif (! function_exists('old')) {\n    /**\n     * Retrieve an old input item.\n     *\n     * @param  string|null  $key\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|string|array|null  $default\n     * @return string|array|null\n     */\n    function old($key = null, $default = null)\n    {\n        return app('request')->old($key, $default);\n    }\n}\n\nif (! function_exists('policy')) {\n    /**\n     * Get a policy instance for a given class.\n     *\n     * @param  object|string  $class\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    function policy($class)\n    {\n        return app(Gate::class)->getPolicyFor($class);\n    }\n}\n\nif (! function_exists('precognitive')) {\n    /**\n     * Handle a Precognition controller hook.\n     *\n     * @param  null|callable  $callable\n     * @return mixed\n     */\n    function precognitive($callable = null)\n    {\n        $callable ??= function () {\n            //\n        };\n\n        $payload = $callable(function ($default, $precognition = null) {\n            $response = request()->isPrecognitive()\n                ? ($precognition ?? $default)\n                : $default;\n\n            abort(Router::toResponse(request(), value($response)));\n        });\n\n        if (request()->isPrecognitive()) {\n            abort(204, headers: ['Precognition-Success' => 'true']);\n        }\n\n        return $payload;\n    }\n}\n\nif (! function_exists('public_path')) {\n    /**\n     * Get the path to the public folder.\n     *\n     * @param  string  $path\n     */\n    function public_path($path = ''): string\n    {\n        return app()->publicPath($path);\n    }\n}\n\nif (! function_exists('redirect')) {\n    /**\n     * Get an instance of the redirector.\n     *\n     * @param  string|null  $to\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return ($to is null ? \\Illuminate\\Routing\\Redirector : \\Illuminate\\Http\\RedirectResponse)\n     */\n    function redirect($to = null, $status = 302, $headers = [], $secure = null): Redirector|RedirectResponse\n    {\n        if (is_null($to)) {\n            return app('redirect');\n        }\n\n        return app('redirect')->to($to, $status, $headers, $secure);\n    }\n}\n\nif (! function_exists('report')) {\n    /**\n     * Report an exception.\n     *\n     * @param  \\Throwable|string  $exception\n     */\n    function report($exception): void\n    {\n        if (is_string($exception)) {\n            $exception = new Exception($exception);\n        }\n\n        app(ExceptionHandler::class)->report($exception);\n    }\n}\n\nif (! function_exists('report_if')) {\n    /**\n     * Report an exception if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  \\Throwable|string  $exception\n     */\n    function report_if($boolean, $exception): void\n    {\n        if ($boolean) {\n            report($exception);\n        }\n    }\n}\n\nif (! function_exists('report_unless')) {\n    /**\n     * Report an exception unless the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  \\Throwable|string  $exception\n     */\n    function report_unless($boolean, $exception): void\n    {\n        if (! $boolean) {\n            report($exception);\n        }\n    }\n}\n\nif (! function_exists('request')) {\n    /**\n     * Get an instance of the current request or an input item from the request.\n     *\n     * @param  list<string>|string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? \\Illuminate\\Http\\Request : ($key is string ? mixed : array<string, mixed>))\n     */\n    function request($key = null, $default = null)\n    {\n        if (is_null($key)) {\n            return app('request');\n        }\n\n        if (is_array($key)) {\n            return app('request')->only($key);\n        }\n\n        $value = app('request')->__get($key);\n\n        return is_null($value) ? value($default) : $value;\n    }\n}\n\nif (! function_exists('rescue')) {\n    /**\n     * Catch a potential exception and return a default value.\n     *\n     * @template TValue\n     * @template TFallback\n     *\n     * @param  callable(): TValue  $callback\n     * @param  (callable(\\Throwable): TFallback)|TFallback  $rescue\n     * @param  bool|callable(\\Throwable): bool  $report\n     * @return TValue|TFallback\n     */\n    function rescue(callable $callback, $rescue = null, $report = true)\n    {\n        try {\n            return $callback();\n        } catch (Throwable $e) {\n            if (value($report, $e)) {\n                report($e);\n            }\n\n            return value($rescue, $e);\n        }\n    }\n}\n\nif (! function_exists('resolve')) {\n    /**\n     * Resolve a service from the container.\n     *\n     * @template TClass of object\n     *\n     * @param  string|class-string<TClass>  $name\n     * @return ($name is class-string<TClass> ? TClass : mixed)\n     */\n    function resolve($name, array $parameters = [])\n    {\n        return app($name, $parameters);\n    }\n}\n\nif (! function_exists('resource_path')) {\n    /**\n     * Get the path to the resources folder.\n     *\n     * @param  string  $path\n     */\n    function resource_path($path = ''): string\n    {\n        return app()->resourcePath($path);\n    }\n}\n\nif (! function_exists('response')) {\n    /**\n     * Return a new response from the application.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\View|string|array|null  $content\n     * @param  int  $status\n     * @return ($content is null ? \\Illuminate\\Contracts\\Routing\\ResponseFactory : \\Illuminate\\Http\\Response)\n     */\n    function response($content = null, $status = 200, array $headers = []): ResponseFactory|IlluminateResponse\n    {\n        $factory = app(ResponseFactory::class);\n\n        if (func_num_args() === 0) {\n            return $factory;\n        }\n\n        return $factory->make($content ?? '', $status, $headers);\n    }\n}\n\nif (! function_exists('route')) {\n    /**\n     * Generate the URL to a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     */\n    function route($name, $parameters = [], $absolute = true): string\n    {\n        return app('url')->route($name, $parameters, $absolute);\n    }\n}\n\nif (! function_exists('secure_asset')) {\n    /**\n     * Generate an asset path for the application.\n     *\n     * @param  string  $path\n     */\n    function secure_asset($path): string\n    {\n        return asset($path, true);\n    }\n}\n\nif (! function_exists('secure_url')) {\n    /**\n     * Generate a HTTPS url for the application.\n     *\n     * @param  string  $path\n     * @param  mixed  $parameters\n     * @return string\n     */\n    function secure_url($path, $parameters = [])\n    {\n        return url($path, $parameters, true);\n    }\n}\n\nif (! function_exists('session')) {\n    /**\n     * Get / set the specified session value.\n     *\n     * If an array is passed as the key, we will assume you want to set an array of values.\n     *\n     * @param  array<string, mixed>|string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? \\Illuminate\\Session\\SessionManager : ($key is string ? mixed : null))\n     */\n    function session($key = null, $default = null)\n    {\n        if (is_null($key)) {\n            return app('session');\n        }\n\n        if (is_array($key)) {\n            return app('session')->put($key);\n        }\n\n        return app('session')->get($key, $default);\n    }\n}\n\nif (! function_exists('storage_path')) {\n    /**\n     * Get the path to the storage folder.\n     *\n     * @param  string  $path\n     */\n    function storage_path($path = ''): string\n    {\n        return app()->storagePath($path);\n    }\n}\n\nif (! function_exists('to_action')) {\n    /**\n     * Create a new redirect response to a controller action.\n     *\n     * @param  string|array  $action\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    function to_action($action, $parameters = [], $status = 302, $headers = [])\n    {\n        return redirect()->action($action, $parameters, $status, $headers);\n    }\n}\n\nif (! function_exists('to_route')) {\n    /**\n     * Create a new redirect response to a named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    function to_route($route, $parameters = [], $status = 302, $headers = [])\n    {\n        return redirect()->route($route, $parameters, $status, $headers);\n    }\n}\n\nif (! function_exists('today')) {\n    /**\n     * Create a new Carbon instance for the current date.\n     *\n     * @param  \\DateTimeZone|\\UnitEnum|string|null  $tz\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    function today($tz = null): CarbonInterface\n    {\n        return Date::today(enum_value($tz));\n    }\n}\n\nif (! function_exists('trans')) {\n    /**\n     * Translate the given message.\n     *\n     * @param  string|null  $key\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return ($key is null ? \\Illuminate\\Contracts\\Translation\\Translator : array|string)\n     */\n    function trans($key = null, $replace = [], $locale = null): Translator|array|string\n    {\n        if (is_null($key)) {\n            return app('translator');\n        }\n\n        return app('translator')->get($key, $replace, $locale);\n    }\n}\n\nif (! function_exists('trans_choice')) {\n    /**\n     * Translates the given message based on a count.\n     *\n     * @param  string  $key\n     * @param  \\Countable|int|float|array  $number\n     * @param  string|null  $locale\n     */\n    function trans_choice($key, $number, array $replace = [], $locale = null): string\n    {\n        return app('translator')->choice($key, $number, $replace, $locale);\n    }\n}\n\nif (! function_exists('__')) {\n    /**\n     * Translate the given message.\n     *\n     * @param  string|null  $key\n     * @param  array  $replace\n     * @param  string|null  $locale\n     */\n    function __($key = null, $replace = [], $locale = null): string|array|null\n    {\n        if (is_null($key)) {\n            return $key;\n        }\n\n        return trans($key, $replace, $locale);\n    }\n}\n\nif (! function_exists('uri')) {\n    /**\n     * Generate a URI for the application.\n     */\n    function uri(UriInterface|Stringable|array|string $uri, mixed $parameters = [], bool $absolute = true): Uri\n    {\n        return match (true) {\n            is_array($uri) || str_contains($uri, '\\\\') => Uri::action($uri, $parameters, $absolute),\n            str_contains($uri, '.') && Route::has($uri) => Uri::route($uri, $parameters, $absolute),\n            default => Uri::of($uri),\n        };\n    }\n}\n\nif (! function_exists('url')) {\n    /**\n     * Generate a URL for the application.\n     *\n     * @param  string|null  $path\n     * @param  mixed  $parameters\n     * @param  bool|null  $secure\n     * @return ($path is null ? \\Illuminate\\Contracts\\Routing\\UrlGenerator : string)\n     */\n    function url($path = null, $parameters = [], $secure = null): UrlGenerator|string\n    {\n        if (is_null($path)) {\n            return app(UrlGenerator::class);\n        }\n\n        return app(UrlGenerator::class)->to($path, $parameters, $secure);\n    }\n}\n\nif (! function_exists('validator')) {\n    /**\n     * Create a new Validator instance.\n     *\n     * @return ($data is null ? \\Illuminate\\Contracts\\Validation\\Factory : \\Illuminate\\Contracts\\Validation\\Validator)\n     */\n    function validator(?array $data = null, array $rules = [], array $messages = [], array $attributes = []): ValidatorContract|ValidationFactory\n    {\n        $factory = app(ValidationFactory::class);\n\n        if (func_num_args() === 0) {\n            return $factory;\n        }\n\n        return $factory->make($data ?? [], $rules, $messages, $attributes);\n    }\n}\n\nif (! function_exists('view')) {\n    /**\n     * Get the evaluated view contents for the given view.\n     *\n     * @param  string|null  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return ($view is null ? \\Illuminate\\Contracts\\View\\Factory : \\Illuminate\\Contracts\\View\\View)\n     */\n    function view($view = null, $data = [], $mergeData = []): ViewFactory|ViewContract\n    {\n        $factory = app(ViewFactory::class);\n\n        if (func_num_args() === 0) {\n            return $factory;\n        }\n\n        return $factory->make($view, $data, $mergeData);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/.gitignore",
    "content": "/node_modules\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/badge.blade.php",
    "content": "@props(['type' => 'default', 'variant' => 'soft'])\n\n@php\n$baseClasses = 'inline-flex w-fit shrink-0 items-center justify-center gap-1 font-mono leading-3 uppercase transition-colors dark:border [&_svg]:size-2.5 h-6 min-w-5 rounded-md px-1.5 text-xs/none';\n\n$types = [\n    'default' => [\n        'soft' => 'bg-black/8 text-neutral-900 dark:border-neutral-700 dark:bg-white/10 dark:text-neutral-100',\n        'solid' => 'bg-neutral-600 text-neutral-100 dark:border-neutral-500 dark:bg-neutral-600',\n    ],\n    'success' => [\n        'soft' => 'bg-emerald-200 text-emerald-900 dark:border-emerald-600 dark:bg-emerald-900/70 dark:text-emerald-400',\n        'solid' => 'bg-emerald-600 dark:border-emerald-500 dark:bg-emerald-600',\n    ],\n    'primary' => [\n        'soft' => 'bg-blue-100 text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-300',\n        'solid' => 'bg-blue-700 dark:border-blue-600 dark:bg-blue-700',\n    ],\n    'error' => [\n        'soft' => 'bg-rose-200 text-rose-900 dark:border-rose-900 dark:bg-rose-950 dark:text-rose-100 dark:[&_svg]:!text-white',\n        'solid' => 'bg-rose-600 dark:border-rose-500 dark:bg-rose-600',\n    ],\n    'alert' => [\n        'soft' => 'bg-amber-200 text-amber-900 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-300',\n        'solid' => 'bg-amber-600 dark:border-amber-500 dark:bg-amber-600',\n    ],\n    'white' => [\n        'soft' => 'bg-white text-neutral-900 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100',\n        'solid' => 'bg-black/10 text-neutral-900 dark:text-neutral-900 dark:bg-white',\n    ],\n];\n\n$variants = [\n    'soft' => '',\n    'solid' => 'text-white dark:text-white [&_svg]:!text-white',\n];\n\n$typeClasses = $types[$type][$variant] ?? $types['default']['soft'];\n$variantClasses = $variants[$variant] ?? $variants['soft'];\n\n$classes = implode(' ', [$baseClasses, $typeClasses, $variantClasses]);\n\n@endphp\n\n<div {{ $attributes->merge(['class' => $classes]) }}>\n    {{ $slot }}\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/empty-state.blade.php",
    "content": "@props(['message'])\n\n<div class=\"bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md w-full p-5 uppercase text-sm text-center font-mono shadow-xs text-neutral-600 dark:text-neutral-400\">\n    <span class=\"text-neutral-400 dark:text-neutral-600\">// </span>{{ $message }}\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/file-with-line.blade.php",
    "content": "@props(['frame', 'direction' => 'ltr'])\n\n@php\n    $file = $frame->file();\n    $line = $frame->line();\n@endphp\n\n<div\n    {{ $attributes->merge(['class' => 'truncate font-mono text-xs text-neutral-500 dark:text-neutral-400']) }}\n    dir=\"{{ $direction }}\"\n>\n    <span data-tippy-content=\"{{ $file }}:{{ $line }}\">\n        @if (config('app.editor'))\n            <a href=\"{{ $frame->editorHref() }}\" @click.stop>\n                <span class=\"hover:underline decoration-neutral-400\">{{ $file }}</span><span class=\"text-neutral-500\">:{{ $line }}</span>\n            </a>\n        @else\n            {{ $file }}<span class=\"text-neutral-500\">:{{ $line }}</span>\n        @endif\n    </span>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/formatted-source.blade.php",
    "content": "@props(['frame'])\n\n@php\n    $class = $frame->class();\n    $operator = $frame->operator();\n    $callable = $frame->callable();\n\n    if ($class && $operator) {\n        $source = $class.$operator.$callable.'('.implode(', ', $frame->args()).')';\n    } elseif ($callable !== 'throw') {\n        $source = $callable.'('.implode(', ', $frame->args()).')';\n    } else {\n        $source = $frame->source();\n    }\n@endphp\n\n<x-laravel-exceptions-renderer::syntax-highlight\n    :code=\"$source\"\n    language=\"php\"\n    truncate\n    class=\"text-xs min-w-0\"\n    data-tippy-content=\"{{ $source }}\"\n/>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/frame-code.blade.php",
    "content": "@props(['code', 'highlightedLine'])\n\n<div\n    class=\"text-sm rounded-b-lg bg-neutral-50 border-t border-neutral-100 dark:bg-neutral-900 dark:border-white/10\"\n    {{ $attributes }}\n>\n    <x-laravel-exceptions-renderer::syntax-highlight\n        :code=\"$code\"\n        language=\"php\"\n        editor\n        :starting-line=\"max(1, $highlightedLine - 5)\"\n        :highlighted-line=\"min(5, $highlightedLine - 1)\"\n        class=\"overflow-x-auto\"\n    />\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/frame.blade.php",
    "content": "@props(['frame'])\n\n<div\n    x-data=\"{\n        expanded: {{ $frame->isMain() ? 'true' : 'false' }},\n        hasCode: {{ $frame->snippet() ? 'true' : 'false' }}\n    }\"\n    class=\"group rounded-lg border border-neutral-200 dark:border-white/10 overflow-hidden shadow-xs\"\n    :class=\"{ 'dark:border-white/5': expanded }\"\n>\n    <div\n        class=\"flex h-11 items-center gap-3 bg-white pr-2.5 pl-4 overflow-x-auto dark:bg-white/3\"\n        :class=\"{\n            'cursor-pointer hover:bg-white/50 dark:hover:bg-white/5 hover:[&_svg]:stroke-emerald-500': hasCode,\n            'dark:bg-white/5 rounded-t-lg': expanded,\n            'dark:bg-white/3 rounded-lg': !expanded\n        }\"\n        @click=\"hasCode && (expanded = !expanded)\"\n    >\n        {{-- Dot --}}\n        <div class=\"flex size-3 items-center justify-center flex-shrink-0\">\n          <div\n          class=\"size-2 rounded-full\"\n          :class=\"{\n            'bg-rose-500 dark:bg-neutral-400': expanded,\n            'bg-rose-200 dark:bg-neutral-700': !expanded\n          }\"\n          ></div>\n        </div>\n\n        <div class=\"flex flex-1 items-center justify-between gap-6 min-w-0\">\n            <x-laravel-exceptions-renderer::formatted-source :$frame />\n            <x-laravel-exceptions-renderer::file-with-line :$frame direction=\"rtl\" />\n        </div>\n\n        <div class=\"flex-shrink-0\">\n            <button\n                x-cloak\n                type=\"button\"\n                class=\"flex h-6 w-6 cursor-pointer items-center justify-center rounded-md dark:border dark:border-white/8 group-hover:text-blue-500 group-hover:dark:text-emerald-500\"\n                :class=\"{\n                    'text-blue-500 dark:text-emerald-500 dark:bg-white/5': expanded,\n                    'text-neutral-500 dark:text-neutral-500 dark:bg-white/3': !expanded,\n                }\"\n            >\n                <x-laravel-exceptions-renderer::icons.chevrons-down-up x-show=\"expanded\" />\n                <x-laravel-exceptions-renderer::icons.chevrons-up-down x-show=\"!expanded\" />\n            </button>\n        </div>\n    </div>\n\n    @if($snippet = $frame->snippet())\n        <x-laravel-exceptions-renderer::frame-code :code=\"$snippet\" :highlightedLine=\"$frame->line()\" x-show=\"expanded\" :x-cloak=\"!$frame->isMain()\" />\n    @endif\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/header.blade.php",
    "content": "@props(['exception'])\n\n<div class=\"flex flex-col pt-8 sm:pt-16 overflow-x-auto\">\n    <div class=\"flex flex-col gap-5 mb-8\">\n        <h1 class=\"text-3xl font-semibold text-neutral-950 dark:text-white\">{{ $exception->class() }}</h1>\n        <x-laravel-exceptions-renderer::file-with-line :frame=\"$exception->frames()->first()\" class=\"-mt-3 text-xs\" />\n        <p class=\"text-xl font-light text-neutral-800 dark:text-neutral-300\">\n            {{ $exception->message() }}\n        </p>\n    </div>\n\n    <div class=\"flex items-start gap-2 mb-8 sm:mb-16\">\n        <div class=\"bg-white dark:bg-white/[3%] border border-neutral-200 dark:border-white/10 divide-x divide-neutral-200 dark:divide-white/10 rounded-md shadow-xs flex items-center gap-0.5\">\n            <div class=\"flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]\">\n                <span class=\"text-neutral-400 dark:text-neutral-500\">LARAVEL</span>\n                <span class=\"text-neutral-500 dark:text-neutral-300\">{{ app()->version() }}</span>\n            </div>\n            <div class=\"flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]\">\n                <span class=\"text-neutral-400 dark:text-neutral-500\">PHP</span>\n                <span class=\"text-neutral-500 dark:text-neutral-300\">{{ PHP_VERSION }}</span>\n            </div>\n        </div>\n        <x-laravel-exceptions-renderer::badge type=\"error\">\n            <x-laravel-exceptions-renderer::icons.alert class=\"w-2.5 h-2.5\" />\n            UNHANDLED\n        </x-laravel-exceptions-renderer::badge>\n        <x-laravel-exceptions-renderer::badge type=\"error\" variant=\"solid\">\n            CODE {{ $exception->code() }}\n        </x-laravel-exceptions-renderer::badge>\n    </div>\n\n    <x-laravel-exceptions-renderer::request-url :$exception :request=\"$exception->request()\" class=\"relative z-50\" />\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/http-method.blade.php",
    "content": "@props(['method'])\n\n@php\n$type = match ($method) {\n    'GET', 'OPTIONS', 'ANY' => 'default',\n    'POST' => 'success',\n    'PUT', 'PATCH' => 'primary',\n    'DELETE' => 'error',\n    default => 'default',\n};\n@endphp\n\n<x-laravel-exceptions-renderer::badge type=\"{{ $type }}\">\n    <x-laravel-exceptions-renderer::icons.globe class=\"w-2.5 h-2.5\" />\n    {{ $method }}\n</x-laravel-exceptions-renderer::badge>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/alert.blade.php",
    "content": "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <g clip-path=\"url(#clip0_14732_6105)\">\n        <path d=\"M9.87466 7.8287L5.92654 0.549947C5.82917 0.369362 5.68068 0.221523 5.49966 0.124947C5.25374 -0.00665839 4.9658 -0.0358401 4.69847 0.0437494C4.43115 0.123339 4.20606 0.305262 4.07216 0.549947L0.124664 7.8287C0.0383472 7.98887 -0.00481098 8.16875 -0.000569449 8.35066C0.00367208 8.53256 0.0551674 8.71024 0.148856 8.86622C0.242546 9.0222 0.375205 9.15112 0.533798 9.24031C0.692391 9.32951 0.871462 9.37591 1.05341 9.37495H8.94591C9.12031 9.37495 9.29203 9.33202 9.44591 9.24995C9.56783 9.18524 9.67572 9.09703 9.76338 8.99041C9.85104 8.8838 9.91672 8.76088 9.95663 8.62876C9.99655 8.49663 10.0099 8.35791 9.99595 8.22059C9.98199 8.08328 9.94036 7.95009 9.87466 7.8287ZM4.99966 8.12495C4.87605 8.12495 4.75521 8.08829 4.65243 8.01962C4.54965 7.95094 4.46954 7.85333 4.42224 7.73912C4.37493 7.62492 4.36256 7.49925 4.38667 7.37802C4.41079 7.25678 4.47031 7.14541 4.55772 7.05801C4.64513 6.9706 4.75649 6.91107 4.87773 6.88696C4.99897 6.86284 5.12464 6.87522 5.23884 6.92252C5.35304 6.96983 5.45066 7.04993 5.51933 7.15272C5.58801 7.2555 5.62466 7.37633 5.62466 7.49995C5.62466 7.66571 5.55882 7.82468 5.44161 7.94189C5.3244 8.0591 5.16542 8.12495 4.99966 8.12495ZM5.62466 5.93745C5.62466 6.02033 5.59174 6.09981 5.53313 6.15842C5.47453 6.21702 5.39504 6.24995 5.31216 6.24995H4.68716C4.60428 6.24995 4.5248 6.21702 4.46619 6.15842C4.40759 6.09981 4.37466 6.02033 4.37466 5.93745V3.43745C4.37466 3.35457 4.40759 3.27508 4.46619 3.21648C4.5248 3.15787 4.60428 3.12495 4.68716 3.12495H5.31216C5.39504 3.12495 5.47453 3.15787 5.53313 3.21648C5.59174 3.27508 5.62466 3.35457 5.62466 3.43745V5.93745Z\" fill=\"currentColor\" />\n    </g>\n    <defs>\n        <clipPath id=\"clip0_14732_6105\">\n            <rect width=\"10\" height=\"10\" />\n        </clipPath>\n    </defs>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/check.blade.php",
    "content": "<svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" {{ $attributes }}>\n    <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\"></path>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevron-left.blade.php",
    "content": "<svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M5.125 0.75L0.875 5L5.125 9.25\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevron-right.blade.php",
    "content": "<svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M0.875 9.25L5.125 5L0.875 0.75\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevrons-down-up.blade.php",
    "content": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"12\" viewBox=\"0 0 8 12\" fill=\"none\" {{ $attributes }}>\n  <g clip-path=\"url(#clip0_14550_6168)\">\n    <path d=\"M6.75 11.0001L4 8.25012L1.25 11.0001\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M6.75 1.50012L4 4.25012L1.25 1.50012\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n  </g>\n  <defs>\n    <clipPath id=\"clip0_14550_6168\">\n      <rect width=\"8\" height=\"11\" fill=\"white\" style=\"fill:white;fill-opacity:1;\" transform=\"translate(0 0.500122)\"/>\n    </clipPath>\n  </defs>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevrons-left.blade.php",
    "content": "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M4.75 1L0.75 5L4.75 9\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M9.25 1L5.25 5L9.25 9\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevrons-right.blade.php",
    "content": "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M5.25 9L9.25 5L5.25 1\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M0.75 9L4.75 5L0.75 1\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/chevrons-up-down.blade.php",
    "content": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" {{ $attributes }}>\n  <g clip-path=\"url(#clip0_14550_6155)\">\n    <path d=\"M8.75 8.25012L6 11.0001L3.25 8.25012\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M8.75 3.75012L6 1.00012L3.25 3.75012\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n  </g>\n  <defs>\n    <clipPath id=\"clip0_14550_6155\">\n      <rect width=\"12\" height=\"12\" fill=\"white\" style=\"fill:white;fill-opacity:1;\"/>\n    </clipPath>\n  </defs>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/copy.blade.php",
    "content": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" {{ $attributes }}>\n  <g clip-path=\"url(#clip0_14732_6079)\">\n    <path d=\"M4.25 4.25012V1.25012H10.75V7.75012H7.75M7.75 4.25012H1.25V10.7501H7.75V4.25012Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n  </g>\n  <defs>\n    <clipPath id=\"clip0_14732_6079\">\n      <rect width=\"12\" height=\"12\" />\n    </clipPath>\n  </defs>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/database.blade.php",
    "content": "<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M9.75 2.56944C9.75 3.29815 8.07107 3.88889 6 3.88889C3.92893 3.88889 2.25 3.29815 2.25 2.56944M9.75 2.56944C9.75 1.84074 8.07107 1.25 6 1.25C3.92893 1.25 2.25 1.84074 2.25 2.56944M9.75 2.56944V9.43056C9.75 10.1593 8.07107 10.75 6 10.75C3.92893 10.75 2.25 10.1593 2.25 9.43056V2.56944M9.75 5.94434C9.75 6.67304 8.07107 7.26378 6 7.26378C3.92893 7.26378 2.25 6.67304 2.25 5.94434\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/folder-open.blade.php",
    "content": "<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <g clip-path=\"url(#clip0_14732_6211)\">\n        <path d=\"M1.75 5.25V2.75C1.75 1.922 2.422 1.25 3.25 1.25H4.202C4.808 1.25 5.381 1.525 5.761 1.998L6.364 2.75H8.25C9.355 2.75 10.25 3.645 10.25 4.75V5.25\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n        <path d=\"M2.46801 5.25H9.53101C10.44 5.25 11.14 6.052 11.017 6.953L10.735 9.021C10.6 10.012 9.75301 10.751 8.75301 10.751H3.24601C2.24601 10.751 1.39901 10.012 1.26401 9.021L0.982011 6.953C0.859011 6.052 1.55901 5.25 2.46801 5.25Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    </g>\n    <defs>\n        <clipPath id=\"clip0_14732_6211\">\n            <rect width=\"12\" height=\"12\" />\n        </clipPath>\n    </defs>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/folder.blade.php",
    "content": "<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M2.75 2.75H5.614L5.316 2.114C5.069 1.587 4.54 1.25 3.958 1.25H2.25C1.422 1.25 0.75 1.922 0.75 2.75V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z\" />\n    <path d=\"M0.75 4.75V2.75C0.75 1.922 1.422 1.25 2.25 1.25H3.958C4.54 1.25 5.069 1.587 5.316 2.114L5.614 2.75\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M2.75 2.75H9.25C10.355 2.75 11.25 3.645 11.25 4.75V8.25C11.25 9.355 10.355 10.25 9.25 10.25H2.75C1.645 10.25 0.75 9.355 0.75 8.25V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/globe.blade.php",
    "content": "<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {{ $attributes }}>\n    <path d=\"M5.99996 10.6876C7.10936 10.6876 8.00871 8.58896 8.00871 6.00012C8.00871 3.41129 7.10936 1.31262 5.99996 1.31262C4.89056 1.31262 3.99121 3.41129 3.99121 6.00012C3.99121 8.58896 4.89056 10.6876 5.99996 10.6876Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M1.3125 6.00012H10.6875\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n    <path d=\"M6 10.6876C8.58883 10.6876 10.6875 8.58896 10.6875 6.00012C10.6875 3.41129 8.58883 1.31262 6 1.31262C3.41117 1.31262 1.3125 3.41129 1.3125 6.00012C1.3125 8.58896 3.41117 10.6876 6 10.6876Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/info.blade.php",
    "content": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" {{ $attributes }}>\n    <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n    <path d=\"M12 16v-4\"/>\n    <path d=\"M12 8h.01\"/>\n</svg>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/icons/laravel-ascii.blade.php",
    "content": "<svg fill=\"currentColor\" viewBox=\"0 0 1268 308\" xmlns=\"http://www.w3.org/2000/svg\">\n<defs>\n<path id=\"a\" d=\"m0 0v-0.49449h1.7215v-4.3497l-1.6849-0.00916v-0.40291c1.3278 0 1.6849-0.22893 1.8131-1.1538h0.43954v5.9155h1.7399v0.49449h-4.0292z\"/>\n<path id=\"b\" d=\"m0 0c-1.3186 0-2.1062-1.227-2.1062-3.2965 0-2.0696 0.78752-3.2966 2.1062-3.2966s2.1062 1.227 2.1062 3.2966c0 2.0695-0.78752 3.2965-2.1062 3.2965zm0-3.8918c0.3205 0 0.56774 0.2473 0.56774 0.5678 0 0.3113-0.24724 0.5677-0.56774 0.5677-0.31134 0-0.56775-0.2564-0.56775-0.5677 0-0.3205 0.25641-0.5678 0.56775-0.5678zm0 3.3973c0.99813 0 1.5567-1.0164 1.5567-2.802 0-1.7857-0.55859-2.8021-1.5567-2.8021s-1.5567 1.0164-1.5567 2.8021c0 1.7856 0.55859 2.802 1.5567 2.802z\"/>\n</defs>\n</svg>\n<script>\n(()=>{\nconst d=\"10A212.9A|AB2AB2AB2A212.2AB2AB2AB|6AB3A212.4AB4A|2ABAB3ABA212.AB4AB2A|10A212.3AB4AB|AB2ABAB3A212.AB3AB3A|8ABA212.7ABA|ABAB2AB3A212.2ABAB4A|10A212.6AB2A|2AB2ABAB2A32.9A61.9A73.9A19.AB2AB4A|9AB28.5AB2AB2AB4A3.10A6.25A10.5AB2AB2AB4A4.9A4.9A20.11A9.5AB2AB2AB5A15.7ABA|ABABAB4A25.4ABAB9AB4A.2AB3AB2AB6.2AB2AB2ABAB2AB2ABAB2AB3A7.4ABAB9AB5A.2AB2AB2AB4.2AB2AB2ABA18.2AB2AB2AB2A7.4AB11AB2AB3A12.ABABAB3A|7AB2A23.3AB7ABABABAB3AB8AB3A6.4AB10AB7ABA5.3AB7ABABAB4AB2AB5AB4A5.5AB4A17.7AB2A6.3AB4ABABABABAB10A10.8AB|2AB2AB3AB21.3AB3AB2AB14ABABAB4ABA6.AB4AB2ABABAB4ABAB4A3.3AB3AB2AB8AB7ABAB3AB2A6.AB5ABA16.2ABABAB3A6.2AB3AB13AB2ABAB4A8.2AB3AB2A|10A20.2AB10AB7.ABAB7AB4A6.3AB12AB5AB2A2.2AB10AB7.2ABAB10AB6.3AB6A14.11A4.10AB11.7AB3A7.4AB4A|ABAB2ABABA19.6ABABAB14.3AB2AB3AB2A6.AB3ABAB2A16.6ABABAB14.3AB2ABAB4A7.4ABAB3A13.ABAB2AB2AB4.2ABABABABA15.AB2AB2AB2A6.AB5ABA|10A19.AB2AB5A16.12A6.9AB15.2AB2AB5A16.9AB2A8.AB5AB2A11.10A4.10A17.10A5.3AB2AB2A|2ABABAB3A18.4AB3ABA18.AB2ABAB2ABA6.2ABAB2AB2A15.4AB3ABA18.ABAB2AB3AB8.4AB5A10.2AB2ABABABA4.ABAB2AB3A18.AB2ABAB2A5.AB7A|8ABA17.2AB4AB3A19.10A6.10A15.AB4AB2A20.10A9.AB3AB2ABA9.10A4.9AB27AB5.4AB2ABA|AB2AB5A17.4AB5A20.AB2ABABABA6.AB2ABAB2AB14.4AB5A20.2AB2ABAB2A10.10A7.2ABAB2AB2A5.AB2ABAB4AB2AB2AB2ABAB2ABABABABAB5A4.2AB6A|6ABABA17.AB4AB2AB20.10A6.10A14.2AB4AB2A21.8AB11.ABABAB2AB6.11A5.8AB7AB18AB3A4.4ABAB2A|ABAB6A17.3AB6A20.2ABAB2AB2A6.ABAB2ABABA14.5AB4A20.2ABAB2AB2A11.10A4.2ABAB2ABABA6.2AB2AB4ABABAB3AB2ABAB2AB2AB2AB4ABA4.AB6AB|5AB2ABA18.4AB2AB2A19.10A6.10A15.AB4AB2A20.10A12.2AB2AB2ABA3.10A7.7AB2A33.3AB2AB2A|2AB7A18.AB8A18.2AB2ABABABA6.2AB2AB2ABA15.3AB4ABA18.2AB2ABAB2AB12.11A.2AB2ABAB2A9.ABAB6A32.AB7A|4ABAB3A19.2ABABAB4A15.2AB9A6.10A15.5AB6A15.2AB9A13.ABABAB2AB5AB5AB9.5ABAB3A17.4A10.4AB2ABA|AB6ABA19.8AB4A11.2AB3AB2AB3AB6.ABABABAB2A16.AB4AB2AB3A10.3AB4AB2ABABA14.9ABAB4AB2A11.2AB5AB2A14.3AB5A7.2AB6A|3AB2AB20A3.2AB2AB3AB7A.16AB2A6.10A17.2AB7AB5A2.10AB8A14.3ABAB8AB3A13.4AB8A8.4AB3AB5A5.5ABABA|AB7AB2ABAB2AB2ABAB2ABA5.8ABAB2AB3AB2ABAB2AB2ABAB4A6.2AB2AB2ABA19.2ABAB5AB2AB3AB2ABAB5ABAB2ABA15.6ABAB2AB5A15.4AB2ABAB10AB8ABA7.ABAB5A|4AB2AB11AB7A6.2ABAB9AB11AB5ABA6.10A20.5ABAB15ABAB8A16.AB11ABA17.AB8AB2AB2AB4ABABAB2A9.6AB2A|2AB6ABAB2ABAB5ABAB2A9.8AB2ABABABABA2.5ABAB2A6.ABAB2ABABA22.8AB2ABABABAB3A2.4ABAB2A16.3ABAB2AB2AB2A20.2ABAB8AB2AB7A11.2AB5AB|5ABAB10AB8A12.7AB6A4.AB5AB2A6.10A26.AB12A5.2AB6A17.9AB3A24.2AB2ABAB6ABA15.4ABAB2A\",\ns=document.currentScript.previousElementSibling,\nns=\"http://www.w3.org/2000/svg\";\nconst ox=0.32415,oy=7.3223,cw=5.4907,rh=10.0,zx=1.923,zy=0.0915;\nd.split(\"|\").forEach((r,ri)=>{const g=document.createElementNS(ns,\"g\");g.setAttribute(\"transform\",\"translate(0,\"+(oy+ri*rh)+\")\");let col=0;for(let i=0;i<r.length;i++){let c=r[i],n=1;if(c>=\"0\"&&c<=\"9\"){n=c;while(i+1<r.length&&r[i+1]>=\"0\"&&r[i+1]<=\"9\")n+=r[++i];n=+n;c=r[++i];}if(c===\".\"){col+=n;continue;}for(let j=0;j<n;j++){const u=document.createElementNS(ns,\"use\");u.setAttribute(\"href\",c===\"A\"?\"#a\":\"#b\");u.setAttribute(\"x\",ox+col*cw+(c===\"B\"?zx:0));if(c===\"B\")u.setAttribute(\"y\",zy);g.appendChild(u);col++;}}s.appendChild(g);});\n})();\n</script>"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/laravel-ascii-spotlight.blade.php",
    "content": "<div\n    class=\"relative text-neutral-400 dark:text-neutral-400\"\n    x-data=\"{ spotlight: { x: 0, y: 0 } }\"\n    @mousemove=\"const rect = $el.getBoundingClientRect(); spotlight = { x: $event.clientX - rect.left, y: $event.clientY - rect.top }\">\n    <div\n        class=\"absolute w-full text-neutral-800 dark:text-neutral-100\"\n        x-data=\"{ isDark: window.matchMedia('(prefers-color-scheme: dark)').matches || document.documentElement.classList.contains('dark') }\"\n        :style=\"\n            'mask-image: radial-gradient(circle at ' +\n                spotlight.x +\n                'px ' +\n                spotlight.y +\n                'px, black 0%, transparent ' + (isDark ? '150px' : '120px') + '); -webkit-mask-image: radial-gradient(circle at ' +\n                spotlight.x +\n                'px ' +\n                spotlight.y +\n                'px, black 0%, transparent ' + (isDark ? '600px' : '400px') + ');'\n        \">\n        <x-laravel-exceptions-renderer::icons.laravel-ascii />\n    </div>\n    <x-laravel-exceptions-renderer::icons.laravel-ascii />\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/layout.blade.php",
    "content": "@use('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer')\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n\n    <title>{{ config('app.name', 'Laravel') }}</title>\n\n    <link\n        rel=\"icon\" type=\"image/svg+xml\"\n        href=\"data:image/svg+xml,%3Csvg viewBox='0 -.11376601 49.74245785 51.31690859' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z' fill='%23ff2d20'/%3E%3C/svg%3E\"\n    />\n\n    {!! Renderer::css() !!}\n</head>\n<body class=\"font-sans antialiased overflow-x-hidden bg-neutral-50 dark:bg-neutral-900 dark:text-white scheme-light-dark\">\n    <div class=\"min-h-dvh\">\n        {{ $slot }}\n    </div>\n\n    {!! Renderer::js() !!}\n</body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/previous-exceptions.blade.php",
    "content": "@props(['exception'])\n\n<div id=\"previous-exceptions\" class=\"flex flex-col gap-2.5 bg-neutral-50 dark:bg-white/1 border border-neutral-200 dark:border-neutral-800 rounded-xl p-2.5 shadow-xs\">\n    <div class=\"flex items-center gap-2.5 p-2\">\n        <div class=\"bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/5 rounded-md w-6 h-6 flex items-center justify-center p-1\">\n            <x-laravel-exceptions-renderer::icons.alert class=\"w-2.5 h-2.5 text-blue-500 dark:text-emerald-500\" />\n        </div>\n        <h3 class=\"text-base font-semibold text-neutral-900 dark:text-white\">Previous {{ Str::plural('exception', $exception->previousExceptions()->count()) }}</h3>\n    </div>\n\n    <div class=\"flex flex-col\">\n        @foreach ($exception->previousExceptions() as $index => $previous)\n            <div class=\"flex gap-2.5 px-2\">\n                {{-- Timeline column --}}\n                @if ($exception->previousExceptions()->count() > 1)\n                    <div class=\"flex flex-col items-center w-6 flex-shrink-0 self-stretch\">\n                        @if ($index > 0)\n                            <div class=\"h-[23.5px] w-px border-l border-dashed border-emerald-900\"></div>\n                        @else\n                            <div class=\"h-[23.5px]\"></div>\n                        @endif\n\n                        <div class=\"size-[9px] flex-shrink-0 rounded-full bg-emerald-800\"></div>\n\n                        @if ($index < $exception->previousExceptions()->count() - 1)\n                            <div class=\"flex-1 w-px border-l border-dashed border-emerald-900\"></div>\n                        @else\n                            <div class=\"flex-1\"></div>\n                        @endif\n                    </div>\n                @endif\n\n                {{-- Exception content --}}\n                <div\n                    x-data=\"{ expanded: false }\"\n                    class=\"group/exception flex-1 min-w-0 rounded-lg my-1.5\"\n                    :class=\"{\n                        'border border-neutral-200 bg-white/50 dark:bg-white/2 dark:border-white/5': expanded,\n                        @if ($exception->previousExceptions()->count() === 1)\n                            'border border-neutral-200 dark:border-transparent dark:bg-white/2': !expanded,\n                        @else\n                            'hover:border hover:border-neutral-200 dark:hover:border-none': !expanded,\n                        @endif\n                    }\"\n                >\n                    {{-- Header + Message --}}\n                    <div\n                        class=\"flex gap-2.5 p-3 cursor-pointer rounded-lg\"\n                        :class=\"{ 'hover:bg-white/50 dark:hover:bg-white/2': !expanded }\"\n                        @click=\"expanded = !expanded\"\n                    >\n                        <div\n                            class=\"flex-1 min-w-0\"\n                            :class=\"expanded ? 'flex flex-col' : 'flex items-baseline gap-2'\"\n                        >\n                            <h4 class=\"font-mono text-sm font-medium text-neutral-900 dark:text-white flex-shrink-0 max-w-full truncate\">{{ $previous->class() }}</h4>\n                            <p\n                                class=\"text-sm text-neutral-500 dark:text-neutral-400\"\n                                :class=\"expanded ? 'mt-1 break-words' : 'truncate'\"\n                            >{{ $previous->message() }}</p>\n                        </div>\n                        <button\n                            type=\"button\"\n                            class=\"flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center rounded-md border border-neutral-200 dark:border-white/8 group-hover/exception:text-blue-500 group-hover/exception:dark:text-emerald-500\"\n                            :class=\"{\n                                'text-blue-500 dark:text-emerald-500 dark:bg-white/5': expanded,\n                                'text-neutral-500 dark:text-neutral-500 dark:bg-white/3': !expanded,\n                            }\"\n                        >\n                            <x-laravel-exceptions-renderer::icons.chevrons-down-up x-show=\"expanded\" />\n                            <x-laravel-exceptions-renderer::icons.chevrons-up-down x-show=\"!expanded\" x-cloak />\n                        </button>\n                    </div>\n\n                    {{-- Collapsible trace --}}\n                    <div x-show=\"expanded\" x-cloak class=\"flex flex-col gap-1.5 p-3\">\n                        @foreach ($previous->frameGroups() as $group)\n                            @if ($group['is_vendor'])\n                                <x-laravel-exceptions-renderer::vendor-frames :frames=\"$group['frames']\" />\n                            @else\n                                @foreach ($group['frames'] as $frame)\n                                    <x-laravel-exceptions-renderer::frame :$frame />\n                                @endforeach\n                            @endif\n                        @endforeach\n                    </div>\n                </div>\n            </div>\n        @endforeach\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php",
    "content": "@props(['queries'])\n\n<div\n    {{ $attributes->merge(['class' => \"flex flex-col gap-2.5 bg-neutral-50 dark:bg-white/1 border border-neutral-200 dark:border-neutral-800 rounded-xl p-2.5 shadow-xs\"]) }}\n    x-data=\"{\n        totalQueries: {{ min(count($queries), 100) }},\n        currentPage: 1,\n        perPage: 10,\n        get totalPages() {\n            return Math.ceil(this.totalQueries / this.perPage);\n        },\n        get hasPrevious() {\n            return this.currentPage > 1;\n        },\n        get hasNext() {\n            return this.currentPage < this.totalPages;\n        },\n        goToPage(page) {\n            if (page >= 1 && page <= this.totalPages) {\n                this.currentPage = page;\n            }\n        },\n        first() {\n            this.currentPage = 1;\n        },\n        last() {\n            this.currentPage = this.totalPages;\n        },\n        previous() {\n            if (this.hasPrevious) {\n                this.currentPage--;\n            }\n        },\n        next() {\n            if (this.hasNext) {\n                this.currentPage++;\n            }\n        },\n        get visiblePages() {\n            const total = this.totalPages;\n            const current = this.currentPage;\n            const pages = [];\n\n            if (total <= 7) {\n                for (let i = 1; i <= total; i++) {\n                    pages.push({ type: 'page', value: i });\n                }\n            } else {\n                if (current <= 4) {\n                    for (let i = 1; i <= 5; i++) {\n                        pages.push({ type: 'page', value: i });\n                    }\n                    if (total > 6) {\n                        pages.push({ type: 'ellipsis', value: '...', id: 'end' });\n                        pages.push({ type: 'page', value: total });\n                    }\n                } else if (current > total - 4) {\n                    pages.push({ type: 'page', value: 1 });\n                    if (total > 6) {\n                        pages.push({ type: 'ellipsis', value: '...', id: 'start' });\n                    }\n                    for (let i = Math.max(total - 4, 2); i <= total; i++) {\n                        pages.push({ type: 'page', value: i });\n                    }\n                } else {\n                    pages.push({ type: 'page', value: 1 });\n                    pages.push({ type: 'ellipsis', value: '...', id: 'start' });\n                    for (let i = current - 1; i <= current + 1; i++) {\n                        pages.push({ type: 'page', value: i });\n                    }\n                    pages.push({ type: 'ellipsis', value: '...', id: 'end' });\n                    pages.push({ type: 'page', value: total });\n                }\n            }\n            return pages;\n        }\n    }\"\n>\n    <div class=\"flex items-center justify-between p-2\">\n        <div class=\"flex items-center gap-2.5\">\n            <div class=\"bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/5 rounded-md w-6 h-6 flex items-center justify-center p-1\">\n                <x-laravel-exceptions-renderer::icons.database class=\"w-2.5 h-2.5 text-blue-500 dark:text-emerald-500\" />\n            </div>\n            <h3 class=\"text-base font-semibold\">Queries</h3>\n        </div>\n        <div x-show=\"totalQueries > 0\" class=\"text-sm text-neutral-500 dark:text-neutral-400 flex items-center gap-2\">\n            <span x-text=\"`${((currentPage - 1) * perPage) + 1}-${Math.min(currentPage * perPage, totalQueries)} of ${totalQueries}`\"></span>\n            @if (count($queries) > 100)\n                <x-laravel-exceptions-renderer::icons.info\n                    class=\"w-3 h-3 text-blue-500 dark:text-emerald-500\"\n                    data-tippy-content=\"Only the first 100 queries are shown\"\n                />\n            @endif\n        </div>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n        @forelse (array_slice($queries, 0, 100) as $index => ['connectionName' => $connectionName, 'sql' => $sql, 'time' => $time])\n        <div\n            class=\"border border-neutral-200 dark:border-none bg-white dark:bg-white/[3%] rounded-md h-10 flex items-center justify-between gap-4 px-4 text-xs font-mono shadow-xs\"\n            x-show=\"Math.floor({{ $index }} / perPage) === (currentPage - 1)\"\n        >\n            <div class=\"flex items-center gap-2 truncate\">\n                <div class=\"flex items-center gap-2\">\n                    <x-laravel-exceptions-renderer::icons.database class=\"w-3 h-3 text-neutral-500 dark:text-neutral-400\" />\n                    <span class=\"text-neutral-500 dark:text-neutral-400\">{{ $connectionName }}</span>\n                </div>\n                <x-laravel-exceptions-renderer::syntax-highlight\n                    :code=\"$sql\"\n                    language=\"sql\"\n                    truncate\n                    class=\"min-w-0\"\n                    data-tippy-content=\"{{ nl2br($sql) }}\"\n                />\n            </div>\n            <div class=\"text-neutral-500 dark:text-neutral-200 text-right flex-shrink-0\">{{ $time }}ms</div>\n        </div>\n        @empty\n        <x-laravel-exceptions-renderer::empty-state message=\"No queries executed\" />\n        @endforelse\n    </div>\n\n    <!-- Pagination Controls -->\n    <div x-cloak x-show=\"totalPages > 1\" class=\"flex items-center justify-center gap-1 py-4 font-mono\">\n        <!-- First Button -->\n        <button\n            @click=\"first()\"\n            class=\"cursor-pointer flex items-center justify-center w-8 h-8 rounded-md transition-colors\"\n            :disabled=\"!hasPrevious\"\n            :class=\"hasPrevious ? 'text-neutral-500 dark:text-neutral-300 hover:bg-neutral-200 hover:dark:text-white hover:dark:bg-white/5' : 'text-neutral-600 cursor-not-allowed!'\"\n        >\n            <x-laravel-exceptions-renderer::icons.chevrons-left class=\"w-3 h-3\" />\n        </button>\n\n        <!-- Previous Button -->\n        <button\n            @click=\"previous()\"\n            class=\"cursor-pointer flex items-center justify-center w-8 h-8 rounded-md transition-colors\"\n            :class=\"hasPrevious ? 'text-neutral-500 dark:text-neutral-300 hover:bg-neutral-200 hover:dark:text-white hover:dark:bg-white/5' : 'text-neutral-600 cursor-not-allowed!'\"\n            :disabled=\"!hasPrevious\"\n        >\n            <x-laravel-exceptions-renderer::icons.chevron-left class=\"w-3 h-3\" />\n        </button>\n\n        <!-- Page Numbers -->\n        <template x-for=\"(page, index) in visiblePages\" :key=\"`page-${page.type}-${page.value}-${page.id || index}`\">\n            <div>\n                <template x-if=\"page.type === 'ellipsis'\">\n                    <span class=\"flex items-center justify-center w-8 h-8 text-neutral-500\">...</span>\n                </template>\n                <template x-if=\"page.type === 'page'\">\n                    <button\n                        @click=\"goToPage(page.value)\"\n                        class=\"cursor-pointer flex items-center justify-center w-8 h-8 rounded-md text-sm font-medium transition-colors\"\n                        :class=\"currentPage === page.value ? 'bg-blue-600 text-white' : 'text-neutral-500 dark:text-neutral-300 hover:bg-neutral-200 hover:dark:text-white hover:dark:bg-white/5'\"\n                        x-text=\"page.value\"\n                    ></button>\n                </template>\n            </div>\n        </template>\n\n        <!-- Next Button -->\n        <button\n            @click=\"next()\"\n            class=\"cursor-pointer flex items-center justify-center w-8 h-8 rounded-md transition-colors\"\n            :class=\"hasNext ? 'text-neutral-500 dark:text-neutral-300 hover:bg-neutral-200 hover:dark:text-white hover:dark:bg-white/5' : 'text-neutral-600 cursor-not-allowed!'\"\n            :disabled=\"!hasNext\"\n        >\n            <x-laravel-exceptions-renderer::icons.chevron-right class=\"w-3 h-3\" />\n        </button>\n\n        <!-- Last Button -->\n        <button\n            @click=\"last()\"\n            class=\"cursor-pointer flex items-center justify-center w-8 h-8 rounded-md transition-colors\"\n            :class=\"hasNext ? 'text-neutral-500 dark:text-neutral-300 hover:bg-neutral-200 hover:dark:text-white hover:dark:bg-white/5' : 'text-neutral-600 cursor-not-allowed!'\"\n            :disabled=\"!hasNext\"\n        >\n            <x-laravel-exceptions-renderer::icons.chevrons-right class=\"w-3 h-3\" />\n        </button>\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/request-body.blade.php",
    "content": "@props(['body'])\n\n<div class=\"flex flex-col gap-3\">\n    <h2 class=\"text-lg font-semibold\">Body</h2>\n    @if($body)\n    <div class=\"bg-white dark:bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md overflow-x-auto p-5 text-sm font-mono shadow-xs\">\n        <x-laravel-exceptions-renderer::syntax-highlight :code=\"$body\" language=\"json\" />\n    </div>\n    @else\n    <x-laravel-exceptions-renderer::empty-state message=\"No request body\" />\n    @endif\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/request-header.blade.php",
    "content": "@props(['headers'])\n\n<div class=\"flex flex-col gap-3\">\n    <h2 class=\"text-lg font-semibold text-neutral-900 dark:text-white\">Headers</h2>\n    <div class=\"flex flex-col\">\n        @foreach ($headers as $key => $value)\n        <div class=\"flex max-w-full items-baseline gap-2 h-10 text-sm font-mono\">\n            <div class=\"uppercase text-neutral-500 dark:text-neutral-400 shrink-0\">{{ $key }}</div>\n            <div class=\"min-w-6 grow h-3 border-b-2 border-dotted border-neutral-300 dark:border-white/20\"></div>\n            <div class=\"truncate text-neutral-900 dark:text-white\">\n                <span data-tippy-content=\"{{ $value }}\">\n                    {{ $value }}\n                </span>\n            </div>\n        </div>\n        @endforeach\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/request-url.blade.php",
    "content": "@props(['exception', 'request'])\n\n<div\n    x-data=\"{\n        copied: false,\n        async copyToClipboard() {\n            try {\n                await window.copyToClipboard('{{ $request->fullUrl() }}');\n                this.copied = true;\n                setTimeout(() => { this.copied = false }, 3000);\n            } catch (err) {\n                console.error('Failed to copy the requestURL: ', err);\n            }\n        }\n    }\"\n    {{ $attributes->merge(['class' => \"bg-white dark:bg-[#1a1a1a] border border-neutral-200 dark:border-white/10 rounded-lg flex items-center justify-between h-10 px-2 shadow-xs\"]) }}\n>\n    <div class=\"flex items-center gap-3 w-full\">\n        <x-laravel-exceptions-renderer::badge type=\"error\" variant=\"solid\">\n            <x-laravel-exceptions-renderer::icons.alert class=\"w-2.5 h-2.5\" />\n            {{ $exception->httpStatusCode() }}\n        </x-laravel-exceptions-renderer::badge>\n        <x-laravel-exceptions-renderer::http-method method=\"{{ $request->method() }}\" />\n        <div class=\"flex-1 text-sm font-light truncate text-neutral-950 dark:text-white\">\n            <span data-tippy-content=\"{{ $request->fullUrl() }}\">\n                {{ $request->fullUrl() }}\n            </span>\n        </div>\n        <button\n            x-cloak\n            @click=\"copyToClipboard()\"\n            @class([\n                \"rounded-md w-6 h-6 flex flex-shrink-0 items-center justify-center cursor-pointer border transition-colors duration-200 ease-in-out\",\n                \"bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10\",\n            ])\n        >\n            <x-laravel-exceptions-renderer::icons.copy class=\"w-3 h-3 text-neutral-400\" x-show=\"!copied\" />\n            <x-laravel-exceptions-renderer::icons.check class=\"w-3 h-3 text-emerald-500\" x-show=\"copied\" />\n        </button>\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/routing-parameter.blade.php",
    "content": "@props(['routeParameters'])\n\n<div class=\"flex flex-col gap-3\">\n    <h2 class=\"text-lg font-semibold\">Routing parameters</h2>\n    @if ($routeParameters)\n    <div class=\"bg-white dark:bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md overflow-x-auto p-5 text-sm font-mono shadow-xs\">\n        <x-laravel-exceptions-renderer::syntax-highlight :code=\"$routeParameters\" language=\"json\" />\n    </div>\n    @else\n    <x-laravel-exceptions-renderer::empty-state message=\"No routing parameters\" />\n    @endif\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/routing.blade.php",
    "content": "@props(['routing'])\n\n<div class=\"flex flex-col gap-3\">\n    <h2 class=\"text-lg font-semibold\">Routing</h2>\n    <div class=\"flex flex-col\">\n        @forelse ($routing as $key => $value)\n        <div class=\"flex max-w-full items-baseline gap-2 h-10 text-sm font-mono\">\n            <div class=\"uppercase text-neutral-500 dark:text-neutral-400 shrink-0\">{{ $key }}</div>\n            <div class=\"min-w-6 grow h-3 border-b-2 border-dotted border-neutral-300 dark:border-white/20\"></div>\n            <div class=\"truncate text-neutral-900 dark:text-white\">\n                <span data-tippy-content=\"{{ $value }}\">\n                    {{ $value }}\n                </span>\n            </div>\n        </div>\n        @empty\n        <x-laravel-exceptions-renderer::empty-state message=\"No routing context\" />\n        @endforelse\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/section-container.blade.php",
    "content": "<section\n    {{ $attributes->merge(['class' => \"w-full max-w-7xl mx-auto p-4 sm:p-14 border-x border-dashed border-neutral-300 dark:border-white/[9%]\"]) }}\n>\n    {{ $slot }}\n</section>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/separator.blade.php",
    "content": "<div {{ $attributes->merge(['class' => \"h-0 w-full relative\"]) }}>\n    <div class=\"absolute top-[-1px] left-0 right-0 bottom-0 border-t border-dashed border-neutral-300 dark:border-white/[9%]\"></div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/syntax-highlight.blade.php",
    "content": "@props([\n    'code',\n    'language',\n    'editor' => false,\n    'startingLine' => 1,\n    'highlightedLine' => null,\n    'truncate' => false,\n])\n\n@php\n    $fallback = $truncate ? '<pre class=\"truncate\"><code>' : '<pre><code>';\n\n    if ($editor) {\n        $lines = explode(\"\\n\", $code);\n\n        foreach ($lines as $index => $line) {\n            $lineNumber = $startingLine + $index;\n            $highlight = $highlightedLine === $index;\n            $lineClass = implode(' ', [\n                'block px-4 py-1 h-7 even:bg-white odd:bg-white/2 even:dark:bg-white/2 odd:dark:bg-white/4',\n                $highlight ? 'bg-rose-200! dark:bg-rose-900!' : '',\n            ]);\n            $lineNumberClass = implode(' ', [\n                'mr-6 text-neutral-500! dark:text-neutral-600!',\n                $highlight ? 'dark:text-white!' : '',\n            ]);\n\n            $fallback .= '<span class=\"' . $lineClass . '\">';\n            $fallback .= '<span class=\"' . $lineNumberClass . '\">' . $lineNumber . '</span>';\n            $fallback .= htmlspecialchars($line);\n            $fallback .= '</span>';\n        }\n\n    } else {\n        $fallback .= htmlspecialchars($code);\n    }\n\n    $fallback .= '</code></pre>';\n@endphp\n\n<div\n    x-data=\"{ highlightedCode: null }\"\n    x-init=\"\n        highlightedCode = window.highlight(\n            {{ Illuminate\\Support\\Js::from($code) }},\n            {{ Illuminate\\Support\\Js::from($language) }},\n            {{ Illuminate\\Support\\Js::from($truncate) }},\n            {{ Illuminate\\Support\\Js::from($editor) }},\n            {{ Illuminate\\Support\\Js::from($startingLine) }},\n            {{ Illuminate\\Support\\Js::from($highlightedLine) }}\n        );\n    \"\n    {{ $attributes }}\n>\n    <div\n        x-cloak\n        x-html=\"highlightedCode\"\n    ></div>\n    <div x-show=\"!highlightedCode\">{!! $fallback !!}</div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/topbar.blade.php",
    "content": "@props(['title', 'markdown'])\n\n<script>\n    const markdown = {{ Illuminate\\Support\\Js::from($markdown) }}\n</script>\n\n<div\n    class=\"flex items-center justify-between\"\n    x-data=\"{\n        copied: false,\n        async copyToClipboard() {\n            try {\n                await window.copyToClipboard(markdown);\n                this.copied = true;\n                setTimeout(() => { this.copied = false }, 3000);\n            } catch (err) {\n                console.error('Failed to copy the markdown: ', err);\n            }\n        }\n    }\"\n>\n    <div class=\"flex items-center gap-2 h-[56px]\">\n        <div class=\"w-[18px] h-[18px] flex items-center justify-center bg-rose-500 rounded-md\">\n            <svg width=\"2\" height=\"10\" class=\"text-white\" viewBox=\"0 0 2 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n                <path d=\"M1.00006 6.3188C1.41416 6.3188 1.75006 5.98295 1.75006 5.56885V1.43115C1.75006 1.01705 1.41416 0.681152 1.00006 0.681152C0.585961 0.681152 0.250061 1.01705 0.250061 1.43115V5.56885C0.250061 5.98295 0.585961 6.3188 1.00006 6.3188Z\" fill=\"currentColor\" />\n                <path d=\"M1.00006 9.41699C1.55235 9.41699 2.00007 8.96929 2.00007 8.41699C2.00007 7.86469 1.55235 7.41699 1.00006 7.41699C0.447781 7.41699 6.10352e-05 7.86469 6.10352e-05 8.41699C6.10352e-05 8.96929 0.447781 9.41699 1.00006 9.41699Z\" fill=\"currentColor \"/>\n            </svg>\n        </div>\n        <div class=\"font-medium text-sm text-neutral-900 dark:text-white\">\n            {{ $title }}\n        </div>\n    </div>\n\n    <button\n        x-cloak\n        @class([\n            \"text-sm rounded-md border px-3 h-8 flex items-center gap-2 transition-colors duration-200 ease-in-out cursor-pointer shadow-xs\",\n            \"text-neutral-600 dark:text-neutral-400 bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10\",\n        ])\n        @click=\"copyToClipboard()\"\n    >\n        <x-laravel-exceptions-renderer::icons.copy class=\"w-3 h-3\" x-show=\"!copied\" />\n        <x-laravel-exceptions-renderer::icons.check class=\"w-3 h-3 text-emerald-500\" x-show=\"copied\" />\n        <span x-text=\"copied ? 'Copied to clipboard' : 'Copy as Markdown'\"></span>\n    </button>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/trace.blade.php",
    "content": "@props(['exception'])\n\n<div class=\"flex flex-col gap-2.5 bg-neutral-50 dark:bg-white/1 border border-neutral-200 dark:border-neutral-800 rounded-xl p-2.5 shadow-xs\">\n    <div class=\"flex items-center gap-2.5 p-2\">\n        <div class=\"bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/5 rounded-md w-6 h-6 flex items-center justify-center p-1\">\n            <x-laravel-exceptions-renderer::icons.alert class=\"w-2.5 h-2.5 text-blue-500 dark:text-emerald-500\" />\n        </div>\n        <h3 class=\"text-base font-semibold text-neutral-900 dark:text-white\">Exception trace</h3>\n        @if ($exception->previousExceptions()->isNotEmpty())\n            <a href=\"#previous-exceptions\" class=\"ml-auto text-sm text-neutral-500 dark:text-neutral-400 hover:text-blue-500 dark:hover:text-emerald-500 transition-colors\">\n                {{ $exception->previousExceptions()->count() }} previous {{ Str::plural('exception', $exception->previousExceptions()->count()) }}\n            </a>\n        @endif\n    </div>\n\n    <div class=\"flex flex-col gap-1.5\">\n        @foreach ($exception->frameGroups() as $group)\n            @if ($group['is_vendor'])\n                <x-laravel-exceptions-renderer::vendor-frames :frames=\"$group['frames']\" />\n            @else\n                @foreach ($group['frames'] as $frame)\n                    <x-laravel-exceptions-renderer::frame :$frame />\n                @endforeach\n            @endif\n        @endforeach\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/vendor-frame.blade.php",
    "content": "@props(['frame'])\n\n<div class=\"grid gap-3 p-4 bg-neutral-50 dark:bg-transparent overflow-x-auto rounded-lg\">\n    @if($frame->previous())\n        <div class=\"flex\">\n            <x-laravel-exceptions-renderer::formatted-source :$frame className=\"text-xs\" />\n        </div>\n    @else\n        <span class=\"font-mono text-xs leading-3 text-neutral-500\">Entrypoint</span>\n    @endif\n\n    <x-laravel-exceptions-renderer::file-with-line :$frame class=\"text-xs\" />\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/components/vendor-frames.blade.php",
    "content": "@props(['frames'])\n\n@use('Illuminate\\Support\\Str')\n\n<div\n    x-data=\"{ expanded: false }\"\n    class=\"group rounded-lg border border-neutral-200 dark:border-white/5\"\n    :class=\"{\n        'bg-white dark:bg-white/5 shadow-xs': expanded,\n        'border-dashed border-neutral-300 bg-neutral-50 opacity-90 dark:border-white/10 dark:bg-white/1': !expanded,\n    }\"\n>\n    <div\n        class=\"flex h-11 cursor-pointer items-center gap-3 rounded-lg pr-2.5 pl-4 hover:bg-white/50 dark:hover:bg-white/2\"\n        @click=\"expanded = !expanded\"\n    >\n        <x-laravel-exceptions-renderer::icons.folder class=\"w-3 h-3 text-neutral-400\" x-show=\"!expanded\" x-cloak />\n        <x-laravel-exceptions-renderer::icons.folder-open class=\"w-3 h-3 text-blue-500 dark:text-emerald-500\" x-show=\"expanded\" />\n\n        <div class=\"flex-1 font-mono text-xs leading-3 text-neutral-900 dark:text-neutral-400\">\n            {{ count($frames)}} vendor {{ Str::plural('frame', count($frames))}}\n        </div>\n\n        <button\n            x-cloak\n            type=\"button\"\n            class=\"flex h-6 w-6 cursor-pointer items-center justify-center rounded-md dark:border dark:border-white/8 group-hover:text-blue-500 group-hover:dark:text-emerald-500\"\n            :class=\"{\n                'text-blue-500 dark:text-emerald-500 dark:bg-white/5': expanded,\n                'text-neutral-500 dark:text-neutral-500 dark:bg-white/3': !expanded,\n            }\"\n        >\n            <x-laravel-exceptions-renderer::icons.chevrons-down-up x-show=\"expanded\" />\n            <x-laravel-exceptions-renderer::icons.chevrons-up-down x-show=\"!expanded\" />\n        </button>\n    </div>\n\n    <div x-cloak class=\"flex flex-col rounded-b-lg divide-y divide-neutral-200 border-t border-neutral-200 dark:divide-white/5 dark:border-white/5\" x-show=\"expanded\">\n        @foreach ($frames as $frame)\n            <div class=\"flex flex-col divide-y divide-neutral-200 dark:divide-white/5\">\n                <x-laravel-exceptions-renderer::vendor-frame :$frame />\n            </div>\n        @endforeach\n    </div>\n</div>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/dist/scripts.js",
    "content": "var lr=!1,ur=!1,ot=[],pr=-1,Wr=!1;function Ql(e){tu(e)}function Jl(){Wr=!0}function eu(){Wr=!1,io()}function tu(e){ot.includes(e)||ot.push(e),io()}function nu(e){let t=ot.indexOf(e);t!==-1&&t>pr&&ot.splice(t,1)}function io(){if(!ur&&!lr){if(Wr)return;lr=!0,queueMicrotask(au)}}function au(){lr=!1,ur=!0;for(let e=0;e<ot.length;e++)ot[e](),pr=e;ot.length=0,pr=-1,ur=!1}var zt,_t,Bt,so,dr=!0;function ru(e){dr=!1,e(),dr=!0}function iu(e){zt=e.reactive,Bt=e.release,_t=t=>e.effect(t,{scheduler:n=>{dr?Ql(n):n()}}),so=e.raw}function Mi(e){_t=e}function su(e){let t=()=>{};return[a=>{let r=_t(a);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(i=>i())}),e._x_effects.add(r),t=()=>{r!==void 0&&(e._x_effects.delete(r),Bt(r))},r},()=>{t()}]}function oo(e,t){let n=!0,a,r=_t(()=>{let i=e();if(JSON.stringify(i),!n&&(typeof i==\"object\"||i!==a)){let s=a;queueMicrotask(()=>{t(i,s)})}a=i,n=!1});return()=>Bt(r)}async function ou(e){Jl();try{await e(),await Promise.resolve()}finally{eu()}}var co=[],lo=[],uo=[];function cu(e){uo.push(e)}function Vr(e,t){typeof t==\"function\"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,lo.push(t))}function po(e){co.push(e)}function mo(e,t,n){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(n)}function ho(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([n,a])=>{(t===void 0||t.includes(n))&&(a.forEach(r=>r()),delete e._x_attributeCleanups[n])})}function lu(e){for(e._x_effects?.forEach(nu);e._x_cleanups?.length;)e._x_cleanups.pop()()}var Zr=new MutationObserver(Qr),Yr=!1;function Xr(){Zr.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),Yr=!0}function go(){uu(),Zr.disconnect(),Yr=!1}var tn=[];function uu(){let e=Zr.takeRecords();tn.push(()=>e.length>0&&Qr(e));let t=tn.length;queueMicrotask(()=>{if(tn.length===t)for(;tn.length>0;)tn.shift()()})}function z(e){if(!Yr)return e();go();let t=e();return Xr(),t}var Kr=!1,la=[];function pu(){Kr=!0}function du(){Kr=!1,Qr(la),la=[]}function Qr(e){if(Kr){la=la.concat(e);return}let t=[],n=new Set,a=new Map,r=new Map;for(let i=0;i<e.length;i++)if(!e[i].target._x_ignoreMutationObserver&&(e[i].type===\"childList\"&&(e[i].removedNodes.forEach(s=>{s.nodeType===1&&s._x_marker&&n.add(s)}),e[i].addedNodes.forEach(s=>{if(s.nodeType===1){if(n.has(s)){n.delete(s);return}s._x_marker||t.push(s)}})),e[i].type===\"attributes\")){let s=e[i].target,o=e[i].attributeName,c=e[i].oldValue,l=()=>{a.has(s)||a.set(s,[]),a.get(s).push({name:o,value:s.getAttribute(o)})},u=()=>{r.has(s)||r.set(s,[]),r.get(s).push(o)};s.hasAttribute(o)&&c===null?l():s.hasAttribute(o)?(u(),l()):u()}r.forEach((i,s)=>{ho(s,i)}),a.forEach((i,s)=>{co.forEach(o=>o(s,i))});for(let i of n)t.some(s=>s.contains(i))||lo.forEach(s=>s(i));for(let i of t)i.isConnected&&uo.forEach(s=>s(i));t=null,n=null,a=null,r=null}function fo(e){return mt(dt(e))}function Fn(e,t,n){return e._x_dataStack=[t,...dt(n||e)],()=>{e._x_dataStack=e._x_dataStack.filter(a=>a!==t)}}function dt(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot==\"function\"&&e instanceof ShadowRoot?dt(e.host):e.parentNode?dt(e.parentNode):[]}function mt(e){return new Proxy({objects:e},mu)}var mu={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(n=>Object.prototype.hasOwnProperty.call(n,t)||Reflect.has(n,t))},get({objects:e},t,n){return t==\"toJSON\"?hu:Reflect.get(e.find(a=>Reflect.has(a,t))||{},t,n)},set({objects:e},t,n,a){const r=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],i=Object.getOwnPropertyDescriptor(r,t);return i?.set&&i?.get?i.set.call(a,n)||!0:Reflect.set(r,t,n)}};function hu(){return Reflect.ownKeys(this).reduce((t,n)=>(t[n]=Reflect.get(this,n),t),{})}function Jr(e){let t=a=>typeof a==\"object\"&&!Array.isArray(a)&&a!==null,n=(a,r=\"\")=>{Object.entries(Object.getOwnPropertyDescriptors(a)).forEach(([i,{value:s,enumerable:o}])=>{if(o===!1||s===void 0||typeof s==\"object\"&&s!==null&&s.__v_skip)return;let c=r===\"\"?i:`${r}.${i}`;typeof s==\"object\"&&s!==null&&s._x_interceptor?a[i]=s.initialize(e,c,i):t(s)&&s!==a&&!(s instanceof Element)&&n(s,c)})};return n(e)}function bo(e,t=()=>{}){let n={initialValue:void 0,_x_interceptor:!0,initialize(a,r,i){return e(this.initialValue,()=>gu(a,r),s=>mr(a,r,s),r,i)}};return t(n),a=>{if(typeof a==\"object\"&&a!==null&&a._x_interceptor){let r=n.initialize.bind(n);n.initialize=(i,s,o)=>{let c=a.initialize(i,s,o);return n.initialValue=c,r(i,s,o)}}else n.initialValue=a;return n}}function gu(e,t){return t.split(\".\").reduce((n,a)=>n[a],e)}function mr(e,t,n){if(typeof t==\"string\"&&(t=t.split(\".\")),t.length===1)e[t[0]]=n;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),mr(e[t[0]],t.slice(1),n)}}var _o={};function ve(e,t){_o[e]=t}function fn(e,t){let n=fu(t);return Object.entries(_o).forEach(([a,r])=>{Object.defineProperty(e,`$${a}`,{get(){return r(t,n)},enumerable:!1})}),e}function fu(e){let[t,n]=Fo(e),a={interceptor:bo,...t};return Vr(e,n),a}function bu(e,t,n,...a){try{return n(...a)}catch(r){bn(r,e,t)}}function bn(...e){return yo(...e)}var yo=yu;function _u(e){yo=e}function yu(e,t,n=void 0){e=Object.assign(e??{message:\"No error message given.\"},{el:t,expression:n}),console.warn(`Alpine Expression Error: ${e.message}\n\n${n?'Expression: \"'+n+`\"\n\n`:\"\"}`,t),setTimeout(()=>{throw e},0)}var Rt=!0;function vo(e){let t=Rt;Rt=!1;let n=e();return Rt=t,n}function ct(e,t,n={}){let a;return ne(e,t)(r=>a=r,n),a}function ne(...e){return wo(...e)}var wo=ko;function vu(e){wo=e}var xo;function wu(e){xo=e}function ko(e,t){let n={};fn(n,e);let a=[n,...dt(e)],r=typeof t==\"function\"?xu(a,t):Cu(a,t,e);return bu.bind(null,e,t,r)}function xu(e,t){return(n=()=>{},{scope:a={},params:r=[],context:i}={})=>{if(!Rt){_n(n,t,mt([a,...e]),r);return}let s=t.apply(mt([a,...e]),r);_n(n,s)}}var za={};function ku(e,t){if(za[e])return za[e];let n=Object.getPrototypeOf(async function(){}).constructor,a=/^[\\n\\s]*if.*\\(.*\\)/.test(e.trim())||/^(let|const)\\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,i=(()=>{try{let s=new n([\"__self\",\"scope\"],`with (scope) { __self.result = ${a} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,\"name\",{value:`[Alpine] ${e}`}),s}catch(s){return bn(s,t,e),Promise.resolve()}})();return za[e]=i,i}function Cu(e,t,n){let a=ku(t,n);return(r=()=>{},{scope:i={},params:s=[],context:o}={})=>{a.result=void 0,a.finished=!1;let c=mt([i,...e]);if(typeof a==\"function\"){let l=a.call(o,a,c).catch(u=>bn(u,n,t));a.finished?(_n(r,a.result,c,s,n),a.result=void 0):l.then(u=>{_n(r,u,c,s,n)}).catch(u=>bn(u,n,t)).finally(()=>a.result=void 0)}}}function _n(e,t,n,a,r){if(Rt&&typeof t==\"function\"){let i=t.apply(n,a);i instanceof Promise?i.then(s=>_n(e,s,n,a)).catch(s=>bn(s,r,t)):e(i)}else typeof t==\"object\"&&t instanceof Promise?t.then(i=>e(i)):e(t)}function Eu(...e){return xo(...e)}function Fu(e,t,n={}){let a={};fn(a,e);let r=[a,...dt(e)],i=mt([n.scope??{},...r]),s=n.params??[];if(t.includes(\"await\")){let o=Object.getPrototypeOf(async function(){}).constructor,c=/^[\\n\\s]*if.*\\(.*\\)/.test(t.trim())||/^(let|const)\\s/.test(t.trim())?`(async()=>{ ${t} })()`:t;return new o([\"scope\"],`with (scope) { let __result = ${c}; return __result }`).call(n.context,i)}else{let o=/^[\\n\\s]*if.*\\(.*\\)/.test(t.trim())||/^(let|const)\\s/.test(t.trim())?`(()=>{ ${t} })()`:t,l=new Function([\"scope\"],`with (scope) { let __result = ${o}; return __result }`).call(n.context,i);return typeof l==\"function\"&&Rt?l.apply(i,s):l}}var ei=\"x-\";function Ut(e=\"\"){return ei+e}function $u(e){ei=e}var ua={};function W(e,t){return ua[e]=t,{before(n){if(!ua[n]){console.warn(String.raw`Cannot find directive \\`${n}\\`. \\`${e}\\` will use the default order of execution`);return}const a=rt.indexOf(n);rt.splice(a>=0?a:rt.indexOf(\"DEFAULT\"),0,e)}}}function ju(e){return Object.keys(ua).includes(e)}function ti(e,t,n){if(t=Array.from(t),e._x_virtualDirectives){let i=Object.entries(e._x_virtualDirectives).map(([o,c])=>({name:o,value:c})),s=Co(i);i=i.map(o=>s.find(c=>c.name===o.name)?{name:`x-bind:${o.name}`,value:`\"${o.value}\"`}:o),t=t.concat(i)}let a={};return t.map(So((i,s)=>a[i]=s)).filter(To).map(Tu(a,n)).sort(Ru).map(i=>Au(e,i))}function Co(e){return Array.from(e).map(So()).filter(t=>!To(t))}var hr=!1,on=new Map,Eo=Symbol();function Su(e){hr=!0;let t=Symbol();Eo=t,on.set(t,[]);let n=()=>{for(;on.get(t).length;)on.get(t).shift()();on.delete(t)},a=()=>{hr=!1,n()};e(n),a()}function Fo(e){let t=[],n=o=>t.push(o),[a,r]=su(e);return t.push(r),[{Alpine:Ht,effect:a,cleanup:n,evaluateLater:ne.bind(ne,e),evaluate:ct.bind(ct,e)},()=>t.forEach(o=>o())]}function Au(e,t){let n=()=>{},a=ua[t.type]||n,[r,i]=Fo(e);mo(e,t.original,i);let s=()=>{e._x_ignore||e._x_ignoreSelf||(a.inline&&a.inline(e,t,r),a=a.bind(a,e,t,r),hr?on.get(Eo).push(a):a())};return s.runCleanups=i,s}var $o=(e,t)=>({name:n,value:a})=>(n.startsWith(e)&&(n=n.replace(e,t)),{name:n,value:a}),jo=e=>e;function So(e=()=>{}){return({name:t,value:n})=>{let{name:a,value:r}=Ao.reduce((i,s)=>s(i),{name:t,value:n});return a!==t&&e(a,t),{name:a,value:r}}}var Ao=[];function ni(e){Ao.push(e)}function To({name:e}){return Ro().test(e)}var Ro=()=>new RegExp(`^${ei}([^:^.]+)\\\\b`);function Tu(e,t){return({name:n,value:a})=>{n===a&&(a=\"\");let r=n.match(Ro()),i=n.match(/:([a-zA-Z0-9\\-_:]+)/),s=n.match(/\\.[^.\\]]+(?=[^\\]]*$)/g)||[],o=t||e[n]||n;return{type:r?r[1]:null,value:i?i[1]:null,modifiers:s.map(c=>c.replace(\".\",\"\")),expression:a,original:o}}}var gr=\"DEFAULT\",rt=[\"ignore\",\"ref\",\"data\",\"id\",\"anchor\",\"bind\",\"init\",\"for\",\"model\",\"modelable\",\"transition\",\"show\",\"if\",gr,\"teleport\"];function Ru(e,t){let n=rt.indexOf(e.type)===-1?gr:e.type,a=rt.indexOf(t.type)===-1?gr:t.type;return rt.indexOf(n)-rt.indexOf(a)}function ln(e,t,n={}){e.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0,composed:!0,cancelable:!0}))}function ht(e,t){if(typeof ShadowRoot==\"function\"&&e instanceof ShadowRoot){Array.from(e.children).forEach(r=>ht(r,t));return}let n=!1;if(t(e,()=>n=!0),n)return;let a=e.firstElementChild;for(;a;)ht(a,t),a=a.nextElementSibling}function pe(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var qi=!1;function Ou(){qi&&pe(\"Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems.\"),qi=!0,document.body||pe(\"Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?\"),ln(document,\"alpine:init\"),ln(document,\"alpine:initializing\"),Xr(),cu(t=>Pe(t,ht)),Vr(t=>Gt(t)),po((t,n)=>{ti(t,n).forEach(a=>a())});let e=t=>!Ea(t.parentElement,!0);Array.from(document.querySelectorAll(Io().join(\",\"))).filter(e).forEach(t=>{Pe(t)}),ln(document,\"alpine:initialized\"),setTimeout(()=>{Pu()})}var ai=[],Oo=[];function No(){return ai.map(e=>e())}function Io(){return ai.concat(Oo).map(e=>e())}function Lo(e){ai.push(e)}function Po(e){Oo.push(e)}function Ea(e,t=!1){return gt(e,n=>{if((t?Io():No()).some(r=>n.matches(r)))return!0})}function gt(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),e.parentNode instanceof ShadowRoot)return gt(e.parentNode.host,t);if(e.parentElement)return gt(e.parentElement,t)}}function Nu(e){return No().some(t=>e.matches(t))}var Do=[];function Iu(e){Do.push(e)}var Lu=1;function Pe(e,t=ht,n=()=>{}){gt(e,a=>a._x_ignore)||Su(()=>{t(e,(a,r)=>{a._x_marker||(n(a,r),Do.forEach(i=>i(a,r)),ti(a,a.attributes).forEach(i=>i()),a._x_ignore||(a._x_marker=Lu++),a._x_ignore&&r())})})}function Gt(e,t=ht){t(e,n=>{lu(n),ho(n),delete n._x_marker})}function Pu(){[[\"ui\",\"dialog\",[\"[x-dialog], [x-popover]\"]],[\"anchor\",\"anchor\",[\"[x-anchor]\"]],[\"sort\",\"sort\",[\"[x-sort]\"]]].forEach(([t,n,a])=>{ju(n)||a.some(r=>{if(document.querySelector(r))return pe(`found \"${r}\", but missing ${t} plugin`),!0})})}var fr=[],ri=!1;function ii(e=()=>{}){return queueMicrotask(()=>{ri||setTimeout(()=>{br()})}),new Promise(t=>{fr.push(()=>{e(),t()})})}function br(){for(ri=!1;fr.length;)fr.shift()()}function Du(){ri=!0}function si(e,t){return Array.isArray(t)?zi(e,t.join(\" \")):typeof t==\"object\"&&t!==null?Mu(e,t):typeof t==\"function\"?si(e,t()):zi(e,t)}function zi(e,t){let n=r=>r.split(\" \").filter(i=>!e.classList.contains(i)).filter(Boolean),a=r=>(e.classList.add(...r),()=>{e.classList.remove(...r)});return t=t===!0?t=\"\":t||\"\",a(n(t))}function Mu(e,t){let n=o=>o.split(\" \").filter(Boolean),a=Object.entries(t).flatMap(([o,c])=>c?n(o):!1).filter(Boolean),r=Object.entries(t).flatMap(([o,c])=>c?!1:n(o)).filter(Boolean),i=[],s=[];return r.forEach(o=>{e.classList.contains(o)&&(e.classList.remove(o),s.push(o))}),a.forEach(o=>{e.classList.contains(o)||(e.classList.add(o),i.push(o))}),()=>{s.forEach(o=>e.classList.add(o)),i.forEach(o=>e.classList.remove(o))}}function Fa(e,t){return typeof t==\"object\"&&t!==null?qu(e,t):zu(e,t)}function qu(e,t){let n={};return Object.entries(t).forEach(([a,r])=>{n[a]=e.style[a],a.startsWith(\"--\")||(a=Bu(a)),e.style.setProperty(a,r)}),setTimeout(()=>{e.style.length===0&&e.removeAttribute(\"style\")}),()=>{Fa(e,n)}}function zu(e,t){let n=e.getAttribute(\"style\",t);return e.setAttribute(\"style\",t),()=>{e.setAttribute(\"style\",n||\"\")}}function Bu(e){return e.replace(/([a-z])([A-Z])/g,\"$1-$2\").toLowerCase()}function _r(e,t=()=>{}){let n=!1;return function(){n?t.apply(this,arguments):(n=!0,e.apply(this,arguments))}}W(\"transition\",(e,{value:t,modifiers:n,expression:a},{evaluate:r})=>{typeof a==\"function\"&&(a=r(a)),a!==!1&&(!a||typeof a==\"boolean\"?Gu(e,n,t):Uu(e,a,t))});function Uu(e,t,n){Mo(e,si,\"\"),{enter:r=>{e._x_transition.enter.during=r},\"enter-start\":r=>{e._x_transition.enter.start=r},\"enter-end\":r=>{e._x_transition.enter.end=r},leave:r=>{e._x_transition.leave.during=r},\"leave-start\":r=>{e._x_transition.leave.start=r},\"leave-end\":r=>{e._x_transition.leave.end=r}}[n](t)}function Gu(e,t,n){Mo(e,Fa);let a=!t.includes(\"in\")&&!t.includes(\"out\")&&!n,r=a||t.includes(\"in\")||[\"enter\"].includes(n),i=a||t.includes(\"out\")||[\"leave\"].includes(n);t.includes(\"in\")&&!a&&(t=t.filter((b,w)=>w<t.indexOf(\"out\"))),t.includes(\"out\")&&!a&&(t=t.filter((b,w)=>w>t.indexOf(\"out\")));let s=!t.includes(\"opacity\")&&!t.includes(\"scale\"),o=s||t.includes(\"opacity\"),c=s||t.includes(\"scale\"),l=o?0:1,u=c?nn(t,\"scale\",95)/100:1,p=nn(t,\"delay\",0)/1e3,m=nn(t,\"origin\",\"center\"),h=\"opacity, transform\",g=nn(t,\"duration\",150)/1e3,_=nn(t,\"duration\",75)/1e3,f=\"cubic-bezier(0.4, 0.0, 0.2, 1)\";r&&(e._x_transition.enter.during={transformOrigin:m,transitionDelay:`${p}s`,transitionProperty:h,transitionDuration:`${g}s`,transitionTimingFunction:f},e._x_transition.enter.start={opacity:l,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:\"scale(1)\"}),i&&(e._x_transition.leave.during={transformOrigin:m,transitionDelay:`${p}s`,transitionProperty:h,transitionDuration:`${_}s`,transitionTimingFunction:f},e._x_transition.leave.start={opacity:1,transform:\"scale(1)\"},e._x_transition.leave.end={opacity:l,transform:`scale(${u})`})}function Mo(e,t,n={}){e._x_transition||(e._x_transition={enter:{during:n,start:n,end:n},leave:{during:n,start:n,end:n},in(a=()=>{},r=()=>{}){yr(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},a,r)},out(a=()=>{},r=()=>{}){yr(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},a,r)}})}window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,n,a){const r=document.visibilityState===\"visible\"?requestAnimationFrame:setTimeout;let i=()=>r(n);if(t){e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(n):i():e._x_transition?e._x_transition.in(n):i();return}e._x_hidePromise=e._x_transition?new Promise((s,o)=>{e._x_transition.out(()=>{},()=>s(a)),e._x_transitioning&&e._x_transitioning.beforeCancel(()=>o({isFromCancelledTransition:!0}))}):Promise.resolve(a),queueMicrotask(()=>{let s=qo(e);s?(s._x_hideChildren||(s._x_hideChildren=[]),s._x_hideChildren.push(e)):r(()=>{let o=c=>{let l=Promise.all([c._x_hidePromise,...(c._x_hideChildren||[]).map(o)]).then(([u])=>u?.());return delete c._x_hidePromise,delete c._x_hideChildren,l};o(e).catch(c=>{if(!c.isFromCancelledTransition)throw c})})})};function qo(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:qo(t)}function yr(e,t,{during:n,start:a,end:r}={},i=()=>{},s=()=>{}){if(e._x_transitioning&&e._x_transitioning.cancel(),Object.keys(n).length===0&&Object.keys(a).length===0&&Object.keys(r).length===0){i(),s();return}let o,c,l;Hu(e,{start(){o=t(e,a)},during(){c=t(e,n)},before:i,end(){o(),l=t(e,r)},after:s,cleanup(){c(),l()}})}function Hu(e,t){let n,a,r,i=_r(()=>{z(()=>{n=!0,a||t.before(),r||(t.end(),br()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning})});e._x_transitioning={beforeCancels:[],beforeCancel(s){this.beforeCancels.push(s)},cancel:_r(function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();i()}),finish:i},z(()=>{t.start(),t.during()}),Du(),requestAnimationFrame(()=>{if(n)return;let s=Number(getComputedStyle(e).transitionDuration.replace(/,.*/,\"\").replace(\"s\",\"\"))*1e3,o=Number(getComputedStyle(e).transitionDelay.replace(/,.*/,\"\").replace(\"s\",\"\"))*1e3;s===0&&(s=Number(getComputedStyle(e).animationDuration.replace(\"s\",\"\"))*1e3),z(()=>{t.before()}),a=!0,requestAnimationFrame(()=>{n||(z(()=>{t.end()}),br(),setTimeout(e._x_transitioning.finish,s+o),r=!0)})})}function nn(e,t,n){if(e.indexOf(t)===-1)return n;const a=e[e.indexOf(t)+1];if(!a||t===\"scale\"&&isNaN(a))return n;if(t===\"duration\"||t===\"delay\"){let r=a.match(/([0-9]+)ms/);if(r)return r[1]}return t===\"origin\"&&[\"top\",\"right\",\"left\",\"center\",\"bottom\"].includes(e[e.indexOf(t)+2])?[a,e[e.indexOf(t)+2]].join(\" \"):a}var He=!1;function Ve(e,t=()=>{}){return(...n)=>He?t(...n):e(...n)}function Wu(e){return(...t)=>He&&e(...t)}var zo=[];function $a(e){zo.push(e)}function Vu(e,t){zo.forEach(n=>n(e,t)),He=!0,Bo(()=>{Pe(t,(n,a)=>{a(n,()=>{})})}),He=!1}var vr=!1;function Zu(e,t){t._x_dataStack||(t._x_dataStack=e._x_dataStack),He=!0,vr=!0,Bo(()=>{Yu(t)}),He=!1,vr=!1}function Yu(e){let t=!1;Pe(e,(a,r)=>{ht(a,(i,s)=>{if(t&&Nu(i))return s();t=!0,r(i,s)})})}function Bo(e){let t=_t;Mi((n,a)=>{let r=t(n);return Bt(r),()=>{}}),e(),Mi(t)}function Uo(e,t,n,a=[]){switch(e._x_bindings||(e._x_bindings=zt({})),e._x_bindings[t]=n,t=a.includes(\"camel\")?ap(t):t,t){case\"value\":Xu(e,n);break;case\"style\":Qu(e,n);break;case\"class\":Ku(e,n);break;case\"selected\":case\"checked\":Ju(e,t,n);break;default:Go(e,t,n);break}}function Xu(e,t){if(Vo(e))e.attributes.value===void 0&&(e.value=t),window.fromModel&&(typeof t==\"boolean\"?e.checked=ra(e.value)===t:e.checked=Bi(e.value,t));else if(oi(e))Number.isInteger(t)?e.value=t:!Array.isArray(t)&&typeof t!=\"boolean\"&&![null,void 0].includes(t)?e.value=String(t):Array.isArray(t)?e.checked=t.some(n=>Bi(n,e.value)):e.checked=!!t;else if(e.tagName===\"SELECT\")np(e,t);else{if(e.value===t)return;e.value=t===void 0?\"\":t}}function Ku(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedClasses=si(e,t)}function Qu(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles(),e._x_undoAddedStyles=Fa(e,t)}function Ju(e,t,n){Go(e,t,n),tp(e,t,n)}function Go(e,t,n){[null,void 0,!1].includes(n)&&ip(t)?e.removeAttribute(t):(Ho(t)&&(n=t),ep(e,t,n))}function ep(e,t,n){e.getAttribute(t)!=n&&e.setAttribute(t,n)}function tp(e,t,n){e[t]!==n&&(e[t]=n)}function np(e,t){const n=[].concat(t).map(a=>a+\"\");Array.from(e.options).forEach(a=>{a.selected=n.includes(a.value)})}function ap(e){return e.toLowerCase().replace(/-(\\w)/g,(t,n)=>n.toUpperCase())}function Bi(e,t){return e==t}function ra(e){return[1,\"1\",\"true\",\"on\",\"yes\",!0].includes(e)?!0:[0,\"0\",\"false\",\"off\",\"no\",!1].includes(e)?!1:e?!!e:null}var rp=new Set([\"allowfullscreen\",\"async\",\"autofocus\",\"autoplay\",\"checked\",\"controls\",\"default\",\"defer\",\"disabled\",\"formnovalidate\",\"inert\",\"ismap\",\"itemscope\",\"loop\",\"multiple\",\"muted\",\"nomodule\",\"novalidate\",\"open\",\"playsinline\",\"readonly\",\"required\",\"reversed\",\"selected\",\"shadowrootclonable\",\"shadowrootdelegatesfocus\",\"shadowrootserializable\"]);function Ho(e){return rp.has(e)}function ip(e){return![\"aria-pressed\",\"aria-checked\",\"aria-expanded\",\"aria-selected\"].includes(e)}function sp(e,t,n){return e._x_bindings&&e._x_bindings[t]!==void 0?e._x_bindings[t]:Wo(e,t,n)}function op(e,t,n,a=!0){if(e._x_bindings&&e._x_bindings[t]!==void 0)return e._x_bindings[t];if(e._x_inlineBindings&&e._x_inlineBindings[t]!==void 0){let r=e._x_inlineBindings[t];return r.extract=a,vo(()=>ct(e,r.expression))}return Wo(e,t,n)}function Wo(e,t,n){let a=e.getAttribute(t);return a===null?typeof n==\"function\"?n():n:a===\"\"?!0:Ho(t)?!![t,\"true\"].includes(a):a}function oi(e){return e.type===\"checkbox\"||e.localName===\"ui-checkbox\"||e.localName===\"ui-switch\"}function Vo(e){return e.type===\"radio\"||e.localName===\"ui-radio\"}function Zo(e,t){let n;return function(){const a=this,r=arguments,i=function(){n=null,e.apply(a,r)};clearTimeout(n),n=setTimeout(i,t)}}function Yo(e,t){let n;return function(){let a=this,r=arguments;n||(e.apply(a,r),n=!0,setTimeout(()=>n=!1,t))}}function Xo({get:e,set:t},{get:n,set:a}){let r=!0,i,s=_t(()=>{let o=e(),c=n();if(r)a(Ba(o)),r=!1;else{let l=JSON.stringify(o),u=JSON.stringify(c);l!==i?a(Ba(o)):l!==u&&t(Ba(c))}i=JSON.stringify(e()),JSON.stringify(n())});return()=>{Bt(s)}}function Ba(e){return typeof e==\"object\"?JSON.parse(JSON.stringify(e)):e}function cp(e){(Array.isArray(e)?e:[e]).forEach(n=>n(Ht))}var et={},Ui=!1;function lp(e,t){if(Ui||(et=zt(et),Ui=!0),t===void 0)return et[e];et[e]=t,Jr(et[e]),typeof t==\"object\"&&t!==null&&t.hasOwnProperty(\"init\")&&typeof t.init==\"function\"&&et[e].init()}function up(){return et}var Ko={};function pp(e,t){let n=typeof t!=\"function\"?()=>t:t;return e instanceof Element?Qo(e,n()):(Ko[e]=n,()=>{})}function dp(e){return Object.entries(Ko).forEach(([t,n])=>{Object.defineProperty(e,t,{get(){return(...a)=>n(...a)}})}),e}function Qo(e,t,n){let a=[];for(;a.length;)a.pop()();let r=Object.entries(t).map(([s,o])=>({name:s,value:o})),i=Co(r);return r=r.map(s=>i.find(o=>o.name===s.name)?{name:`x-bind:${s.name}`,value:`\"${s.value}\"`}:s),ti(e,r,n).map(s=>{a.push(s.runCleanups),s()}),()=>{for(;a.length;)a.pop()()}}var Jo={};function mp(e,t){Jo[e]=t}function hp(e,t){return Object.entries(Jo).forEach(([n,a])=>{Object.defineProperty(e,n,{get(){return(...r)=>a.bind(t)(...r)},enumerable:!1})}),e}var gp={get reactive(){return zt},get release(){return Bt},get effect(){return _t},get raw(){return so},get transaction(){return ou},version:\"3.15.8\",flushAndStopDeferringMutations:du,dontAutoEvaluateFunctions:vo,disableEffectScheduling:ru,startObservingMutations:Xr,stopObservingMutations:go,setReactivityEngine:iu,onAttributeRemoved:mo,onAttributesAdded:po,closestDataStack:dt,skipDuringClone:Ve,onlyDuringClone:Wu,addRootSelector:Lo,addInitSelector:Po,setErrorHandler:_u,interceptClone:$a,addScopeToNode:Fn,deferMutations:pu,mapAttributes:ni,evaluateLater:ne,interceptInit:Iu,initInterceptors:Jr,injectMagics:fn,setEvaluator:vu,setRawEvaluator:wu,mergeProxies:mt,extractProp:op,findClosest:gt,onElRemoved:Vr,closestRoot:Ea,destroyTree:Gt,interceptor:bo,transition:yr,setStyles:Fa,mutateDom:z,directive:W,entangle:Xo,throttle:Yo,debounce:Zo,evaluate:ct,evaluateRaw:Eu,initTree:Pe,nextTick:ii,prefixed:Ut,prefix:$u,plugin:cp,magic:ve,store:lp,start:Ou,clone:Zu,cloneNode:Vu,bound:sp,$data:fo,watch:oo,walk:ht,data:mp,bind:pp},Ht=gp;function fp(e,t){const n=Object.create(null),a=e.split(\",\");for(let r=0;r<a.length;r++)n[a[r]]=!0;return r=>!!n[r]}var bp=Object.freeze({}),_p=Object.prototype.hasOwnProperty,ja=(e,t)=>_p.call(e,t),lt=Array.isArray,un=e=>ec(e)===\"[object Map]\",yp=e=>typeof e==\"string\",ci=e=>typeof e==\"symbol\",Sa=e=>e!==null&&typeof e==\"object\",vp=Object.prototype.toString,ec=e=>vp.call(e),tc=e=>ec(e).slice(8,-1),li=e=>yp(e)&&e!==\"NaN\"&&e[0]!==\"-\"&&\"\"+parseInt(e,10)===e,wp=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},xp=wp(e=>e.charAt(0).toUpperCase()+e.slice(1)),nc=(e,t)=>e!==t&&(e===e||t===t),wr=new WeakMap,an=[],Ee,ut=Symbol(\"iterate\"),xr=Symbol(\"Map key iterate\");function kp(e){return e&&e._isEffect===!0}function Cp(e,t=bp){kp(e)&&(e=e.raw);const n=$p(e,t);return t.lazy||n(),n}function Ep(e){e.active&&(ac(e),e.options.onStop&&e.options.onStop(),e.active=!1)}var Fp=0;function $p(e,t){const n=function(){if(!n.active)return e();if(!an.includes(n)){ac(n);try{return Sp(),an.push(n),Ee=n,e()}finally{an.pop(),rc(),Ee=an[an.length-1]}}};return n.id=Fp++,n.allowRecurse=!!t.allowRecurse,n._isEffect=!0,n.active=!0,n.raw=e,n.deps=[],n.options=t,n}function ac(e){const{deps:t}=e;if(t.length){for(let n=0;n<t.length;n++)t[n].delete(e);t.length=0}}var It=!0,ui=[];function jp(){ui.push(It),It=!1}function Sp(){ui.push(It),It=!0}function rc(){const e=ui.pop();It=e===void 0?!0:e}function ye(e,t,n){if(!It||Ee===void 0)return;let a=wr.get(e);a||wr.set(e,a=new Map);let r=a.get(n);r||a.set(n,r=new Set),r.has(Ee)||(r.add(Ee),Ee.deps.push(r),Ee.options.onTrack&&Ee.options.onTrack({effect:Ee,target:e,type:t,key:n}))}function We(e,t,n,a,r,i){const s=wr.get(e);if(!s)return;const o=new Set,c=u=>{u&&u.forEach(p=>{(p!==Ee||p.allowRecurse)&&o.add(p)})};if(t===\"clear\")s.forEach(c);else if(n===\"length\"&&lt(e))s.forEach((u,p)=>{(p===\"length\"||p>=a)&&c(u)});else switch(n!==void 0&&c(s.get(n)),t){case\"add\":lt(e)?li(n)&&c(s.get(\"length\")):(c(s.get(ut)),un(e)&&c(s.get(xr)));break;case\"delete\":lt(e)||(c(s.get(ut)),un(e)&&c(s.get(xr)));break;case\"set\":un(e)&&c(s.get(ut));break}const l=u=>{u.options.onTrigger&&u.options.onTrigger({effect:u,target:e,key:n,type:t,newValue:a,oldValue:r,oldTarget:i}),u.options.scheduler?u.options.scheduler(u):u()};o.forEach(l)}var Ap=fp(\"__proto__,__v_isRef,__isVue\"),ic=new Set(Object.getOwnPropertyNames(Symbol).map(e=>Symbol[e]).filter(ci)),Tp=sc(),Rp=sc(!0),Gi=Op();function Op(){const e={};return[\"includes\",\"indexOf\",\"lastIndexOf\"].forEach(t=>{e[t]=function(...n){const a=M(this);for(let i=0,s=this.length;i<s;i++)ye(a,\"get\",i+\"\");const r=a[t](...n);return r===-1||r===!1?a[t](...n.map(M)):r}}),[\"push\",\"pop\",\"shift\",\"unshift\",\"splice\"].forEach(t=>{e[t]=function(...n){jp();const a=M(this)[t].apply(this,n);return rc(),a}}),e}function sc(e=!1,t=!1){return function(a,r,i){if(r===\"__v_isReactive\")return!e;if(r===\"__v_isReadonly\")return e;if(r===\"__v_raw\"&&i===(e?t?Vp:uc:t?Wp:lc).get(a))return a;const s=lt(a);if(!e&&s&&ja(Gi,r))return Reflect.get(Gi,r,i);const o=Reflect.get(a,r,i);return(ci(r)?ic.has(r):Ap(r))||(e||ye(a,\"get\",r),t)?o:kr(o)?!s||!li(r)?o.value:o:Sa(o)?e?pc(o):hi(o):o}}var Np=Ip();function Ip(e=!1){return function(n,a,r,i){let s=n[a];if(!e&&(r=M(r),s=M(s),!lt(n)&&kr(s)&&!kr(r)))return s.value=r,!0;const o=lt(n)&&li(a)?Number(a)<n.length:ja(n,a),c=Reflect.set(n,a,r,i);return n===M(i)&&(o?nc(r,s)&&We(n,\"set\",a,r,s):We(n,\"add\",a,r)),c}}function Lp(e,t){const n=ja(e,t),a=e[t],r=Reflect.deleteProperty(e,t);return r&&n&&We(e,\"delete\",t,void 0,a),r}function Pp(e,t){const n=Reflect.has(e,t);return(!ci(t)||!ic.has(t))&&ye(e,\"has\",t),n}function Dp(e){return ye(e,\"iterate\",lt(e)?\"length\":ut),Reflect.ownKeys(e)}var Mp={get:Tp,set:Np,deleteProperty:Lp,has:Pp,ownKeys:Dp},qp={get:Rp,set(e,t){return console.warn(`Set operation on key \"${String(t)}\" failed: target is readonly.`,e),!0},deleteProperty(e,t){return console.warn(`Delete operation on key \"${String(t)}\" failed: target is readonly.`,e),!0}},pi=e=>Sa(e)?hi(e):e,di=e=>Sa(e)?pc(e):e,mi=e=>e,Aa=e=>Reflect.getPrototypeOf(e);function Gn(e,t,n=!1,a=!1){e=e.__v_raw;const r=M(e),i=M(t);t!==i&&!n&&ye(r,\"get\",t),!n&&ye(r,\"get\",i);const{has:s}=Aa(r),o=a?mi:n?di:pi;if(s.call(r,t))return o(e.get(t));if(s.call(r,i))return o(e.get(i));e!==r&&e.get(t)}function Hn(e,t=!1){const n=this.__v_raw,a=M(n),r=M(e);return e!==r&&!t&&ye(a,\"has\",e),!t&&ye(a,\"has\",r),e===r?n.has(e):n.has(e)||n.has(r)}function Wn(e,t=!1){return e=e.__v_raw,!t&&ye(M(e),\"iterate\",ut),Reflect.get(e,\"size\",e)}function Hi(e){e=M(e);const t=M(this);return Aa(t).has.call(t,e)||(t.add(e),We(t,\"add\",e,e)),this}function Wi(e,t){t=M(t);const n=M(this),{has:a,get:r}=Aa(n);let i=a.call(n,e);i?cc(n,a,e):(e=M(e),i=a.call(n,e));const s=r.call(n,e);return n.set(e,t),i?nc(t,s)&&We(n,\"set\",e,t,s):We(n,\"add\",e,t),this}function Vi(e){const t=M(this),{has:n,get:a}=Aa(t);let r=n.call(t,e);r?cc(t,n,e):(e=M(e),r=n.call(t,e));const i=a?a.call(t,e):void 0,s=t.delete(e);return r&&We(t,\"delete\",e,void 0,i),s}function Zi(){const e=M(this),t=e.size!==0,n=un(e)?new Map(e):new Set(e),a=e.clear();return t&&We(e,\"clear\",void 0,void 0,n),a}function Vn(e,t){return function(a,r){const i=this,s=i.__v_raw,o=M(s),c=t?mi:e?di:pi;return!e&&ye(o,\"iterate\",ut),s.forEach((l,u)=>a.call(r,c(l),c(u),i))}}function Zn(e,t,n){return function(...a){const r=this.__v_raw,i=M(r),s=un(i),o=e===\"entries\"||e===Symbol.iterator&&s,c=e===\"keys\"&&s,l=r[e](...a),u=n?mi:t?di:pi;return!t&&ye(i,\"iterate\",c?xr:ut),{next(){const{value:p,done:m}=l.next();return m?{value:p,done:m}:{value:o?[u(p[0]),u(p[1])]:u(p),done:m}},[Symbol.iterator](){return this}}}}function ze(e){return function(...t){{const n=t[0]?`on key \"${t[0]}\" `:\"\";console.warn(`${xp(e)} operation ${n}failed: target is readonly.`,M(this))}return e===\"delete\"?!1:this}}function zp(){const e={get(i){return Gn(this,i)},get size(){return Wn(this)},has:Hn,add:Hi,set:Wi,delete:Vi,clear:Zi,forEach:Vn(!1,!1)},t={get(i){return Gn(this,i,!1,!0)},get size(){return Wn(this)},has:Hn,add:Hi,set:Wi,delete:Vi,clear:Zi,forEach:Vn(!1,!0)},n={get(i){return Gn(this,i,!0)},get size(){return Wn(this,!0)},has(i){return Hn.call(this,i,!0)},add:ze(\"add\"),set:ze(\"set\"),delete:ze(\"delete\"),clear:ze(\"clear\"),forEach:Vn(!0,!1)},a={get(i){return Gn(this,i,!0,!0)},get size(){return Wn(this,!0)},has(i){return Hn.call(this,i,!0)},add:ze(\"add\"),set:ze(\"set\"),delete:ze(\"delete\"),clear:ze(\"clear\"),forEach:Vn(!0,!0)};return[\"keys\",\"values\",\"entries\",Symbol.iterator].forEach(i=>{e[i]=Zn(i,!1,!1),n[i]=Zn(i,!0,!1),t[i]=Zn(i,!1,!0),a[i]=Zn(i,!0,!0)}),[e,n,t,a]}var[Bp,Up]=zp();function oc(e,t){const n=e?Up:Bp;return(a,r,i)=>r===\"__v_isReactive\"?!e:r===\"__v_isReadonly\"?e:r===\"__v_raw\"?a:Reflect.get(ja(n,r)&&r in a?n:a,r,i)}var Gp={get:oc(!1)},Hp={get:oc(!0)};function cc(e,t,n){const a=M(n);if(a!==n&&t.call(e,a)){const r=tc(e);console.warn(`Reactive ${r} contains both the raw and reactive versions of the same object${r===\"Map\"?\" as keys\":\"\"}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`)}}var lc=new WeakMap,Wp=new WeakMap,uc=new WeakMap,Vp=new WeakMap;function Zp(e){switch(e){case\"Object\":case\"Array\":return 1;case\"Map\":case\"Set\":case\"WeakMap\":case\"WeakSet\":return 2;default:return 0}}function Yp(e){return e.__v_skip||!Object.isExtensible(e)?0:Zp(tc(e))}function hi(e){return e&&e.__v_isReadonly?e:dc(e,!1,Mp,Gp,lc)}function pc(e){return dc(e,!0,qp,Hp,uc)}function dc(e,t,n,a,r){if(!Sa(e))return console.warn(`value cannot be made reactive: ${String(e)}`),e;if(e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const s=Yp(e);if(s===0)return e;const o=new Proxy(e,s===2?a:n);return r.set(e,o),o}function M(e){return e&&M(e.__v_raw)||e}function kr(e){return!!(e&&e.__v_isRef===!0)}ve(\"nextTick\",()=>ii);ve(\"dispatch\",e=>ln.bind(ln,e));ve(\"watch\",(e,{evaluateLater:t,cleanup:n})=>(a,r)=>{let i=t(a),o=oo(()=>{let c;return i(l=>c=l),c},r);n(o)});ve(\"store\",up);ve(\"data\",e=>fo(e));ve(\"root\",e=>Ea(e));ve(\"refs\",e=>(e._x_refs_proxy||(e._x_refs_proxy=mt(Xp(e))),e._x_refs_proxy));function Xp(e){let t=[];return gt(e,n=>{n._x_refs&&t.push(n._x_refs)}),t}var Ua={};function mc(e){return Ua[e]||(Ua[e]=0),++Ua[e]}function Kp(e,t){return gt(e,n=>{if(n._x_ids&&n._x_ids[t])return!0})}function Qp(e,t){e._x_ids||(e._x_ids={}),e._x_ids[t]||(e._x_ids[t]=mc(t))}ve(\"id\",(e,{cleanup:t})=>(n,a=null)=>{let r=`${n}${a?`-${a}`:\"\"}`;return Jp(e,r,t,()=>{let i=Kp(e,n),s=i?i._x_ids[n]:mc(n);return a?`${n}-${s}-${a}`:`${n}-${s}`})});$a((e,t)=>{e._x_id&&(t._x_id=e._x_id)});function Jp(e,t,n,a){if(e._x_id||(e._x_id={}),e._x_id[t])return e._x_id[t];let r=a();return e._x_id[t]=r,n(()=>{delete e._x_id[t]}),r}ve(\"el\",e=>e);hc(\"Focus\",\"focus\",\"focus\");hc(\"Persist\",\"persist\",\"persist\");function hc(e,t,n){ve(t,a=>pe(`You can't use [$${t}] without first installing the \"${e}\" plugin here: https://alpinejs.dev/plugins/${n}`,a))}W(\"modelable\",(e,{expression:t},{effect:n,evaluateLater:a,cleanup:r})=>{let i=a(t),s=()=>{let u;return i(p=>u=p),u},o=a(`${t} = __placeholder`),c=u=>o(()=>{},{scope:{__placeholder:u}}),l=s();c(l),queueMicrotask(()=>{if(!e._x_model)return;e._x_removeModelListeners.default();let u=e._x_model.get,p=e._x_model.set,m=Xo({get(){return u()},set(h){p(h)}},{get(){return s()},set(h){c(h)}});r(m)})});W(\"teleport\",(e,{modifiers:t,expression:n},{cleanup:a})=>{e.tagName.toLowerCase()!==\"template\"&&pe(\"x-teleport can only be used on a <template> tag\",e);let r=Yi(n),i=e.content.cloneNode(!0).firstElementChild;e._x_teleport=i,i._x_teleportBack=e,e.setAttribute(\"data-teleport-template\",!0),i.setAttribute(\"data-teleport-target\",!0),e._x_forwardEvents&&e._x_forwardEvents.forEach(o=>{i.addEventListener(o,c=>{c.stopPropagation(),e.dispatchEvent(new c.constructor(c.type,c))})}),Fn(i,{},e);let s=(o,c,l)=>{l.includes(\"prepend\")?c.parentNode.insertBefore(o,c):l.includes(\"append\")?c.parentNode.insertBefore(o,c.nextSibling):c.appendChild(o)};z(()=>{s(i,r,t),Ve(()=>{Pe(i)})()}),e._x_teleportPutBack=()=>{let o=Yi(n);z(()=>{s(e._x_teleport,o,t)})},a(()=>z(()=>{i.remove(),Gt(i)}))});var ed=document.createElement(\"div\");function Yi(e){let t=Ve(()=>document.querySelector(e),()=>ed)();return t||pe(`Cannot find x-teleport element for selector: \"${e}\"`),t}var gc=()=>{};gc.inline=(e,{modifiers:t},{cleanup:n})=>{t.includes(\"self\")?e._x_ignoreSelf=!0:e._x_ignore=!0,n(()=>{t.includes(\"self\")?delete e._x_ignoreSelf:delete e._x_ignore})};W(\"ignore\",gc);W(\"effect\",Ve((e,{expression:t},{effect:n})=>{n(ne(e,t))}));function $t(e,t,n,a){let r=e,i=c=>a(c),s={},o=(c,l)=>u=>l(c,u);if(n.includes(\"dot\")&&(t=td(t)),n.includes(\"camel\")&&(t=nd(t)),n.includes(\"passive\")&&(s.passive=!0),n.includes(\"capture\")&&(s.capture=!0),n.includes(\"window\")&&(r=window),n.includes(\"document\")&&(r=document),n.includes(\"debounce\")){let c=n[n.indexOf(\"debounce\")+1]||\"invalid-wait\",l=pa(c.split(\"ms\")[0])?Number(c.split(\"ms\")[0]):250;i=Zo(i,l)}if(n.includes(\"throttle\")){let c=n[n.indexOf(\"throttle\")+1]||\"invalid-wait\",l=pa(c.split(\"ms\")[0])?Number(c.split(\"ms\")[0]):250;i=Yo(i,l)}return n.includes(\"prevent\")&&(i=o(i,(c,l)=>{l.preventDefault(),c(l)})),n.includes(\"stop\")&&(i=o(i,(c,l)=>{l.stopPropagation(),c(l)})),n.includes(\"once\")&&(i=o(i,(c,l)=>{c(l),r.removeEventListener(t,i,s)})),(n.includes(\"away\")||n.includes(\"outside\"))&&(r=document,i=o(i,(c,l)=>{e.contains(l.target)||l.target.isConnected!==!1&&(e.offsetWidth<1&&e.offsetHeight<1||e._x_isShown!==!1&&c(l))})),n.includes(\"self\")&&(i=o(i,(c,l)=>{l.target===e&&c(l)})),t===\"submit\"&&(i=o(i,(c,l)=>{l.target._x_pendingModelUpdates&&l.target._x_pendingModelUpdates.forEach(u=>u()),c(l)})),(rd(t)||fc(t))&&(i=o(i,(c,l)=>{id(l,n)||c(l)})),r.addEventListener(t,i,s),()=>{r.removeEventListener(t,i,s)}}function td(e){return e.replace(/-/g,\".\")}function nd(e){return e.toLowerCase().replace(/-(\\w)/g,(t,n)=>n.toUpperCase())}function pa(e){return!Array.isArray(e)&&!isNaN(e)}function ad(e){return[\" \",\"_\"].includes(e)?e:e.replace(/([a-z])([A-Z])/g,\"$1-$2\").replace(/[_\\s]/,\"-\").toLowerCase()}function rd(e){return[\"keydown\",\"keyup\"].includes(e)}function fc(e){return[\"contextmenu\",\"click\",\"mouse\"].some(t=>e.includes(t))}function id(e,t){let n=t.filter(i=>![\"window\",\"document\",\"prevent\",\"stop\",\"once\",\"capture\",\"self\",\"away\",\"outside\",\"passive\",\"preserve-scroll\",\"blur\",\"change\",\"lazy\"].includes(i));if(n.includes(\"debounce\")){let i=n.indexOf(\"debounce\");n.splice(i,pa((n[i+1]||\"invalid-wait\").split(\"ms\")[0])?2:1)}if(n.includes(\"throttle\")){let i=n.indexOf(\"throttle\");n.splice(i,pa((n[i+1]||\"invalid-wait\").split(\"ms\")[0])?2:1)}if(n.length===0||n.length===1&&Xi(e.key).includes(n[0]))return!1;const r=[\"ctrl\",\"shift\",\"alt\",\"meta\",\"cmd\",\"super\"].filter(i=>n.includes(i));return n=n.filter(i=>!r.includes(i)),!(r.length>0&&r.filter(s=>((s===\"cmd\"||s===\"super\")&&(s=\"meta\"),e[`${s}Key`])).length===r.length&&(fc(e.type)||Xi(e.key).includes(n[0])))}function Xi(e){if(!e)return[];e=ad(e);let t={ctrl:\"control\",slash:\"/\",space:\" \",spacebar:\" \",cmd:\"meta\",esc:\"escape\",up:\"arrow-up\",down:\"arrow-down\",left:\"arrow-left\",right:\"arrow-right\",period:\".\",comma:\",\",equal:\"=\",minus:\"-\",underscore:\"_\"};return t[e]=e,Object.keys(t).map(n=>{if(t[n]===e)return n}).filter(n=>n)}W(\"model\",(e,{modifiers:t,expression:n},{effect:a,cleanup:r})=>{let i=e;t.includes(\"parent\")&&(i=e.parentNode);let s=ne(i,n),o;typeof n==\"string\"?o=ne(i,`${n} = __placeholder`):typeof n==\"function\"&&typeof n()==\"string\"?o=ne(i,`${n()} = __placeholder`):o=()=>{};let c=()=>{let _;return s(f=>_=f),Ki(_)?_.get():_},l=_=>{let f;s(b=>f=b),Ki(f)?f.set(_):o(()=>{},{scope:{__placeholder:_}})};typeof n==\"string\"&&e.type===\"radio\"&&z(()=>{e.hasAttribute(\"name\")||e.setAttribute(\"name\",n)});let u=t.includes(\"change\")||t.includes(\"lazy\"),p=t.includes(\"blur\"),m=t.includes(\"enter\"),h=u||p||m,g;if(He)g=()=>{};else if(h){let _=[],f=b=>l(Yn(e,t,b,c()));if(u&&_.push($t(e,\"change\",t,f)),p&&(_.push($t(e,\"blur\",t,f)),e.form)){let b=()=>f({target:e});e.form._x_pendingModelUpdates||(e.form._x_pendingModelUpdates=[]),e.form._x_pendingModelUpdates.push(b),r(()=>e.form._x_pendingModelUpdates.splice(e.form._x_pendingModelUpdates.indexOf(b),1))}m&&_.push($t(e,\"keydown\",t,b=>{b.key===\"Enter\"&&f(b)})),g=()=>_.forEach(b=>b())}else{let _=e.tagName.toLowerCase()===\"select\"||[\"checkbox\",\"radio\"].includes(e.type)?\"change\":\"input\";g=$t(e,_,t,f=>{l(Yn(e,t,f,c()))})}if(t.includes(\"fill\")&&([void 0,null,\"\"].includes(c())||oi(e)&&Array.isArray(c())||e.tagName.toLowerCase()===\"select\"&&e.multiple)&&l(Yn(e,t,{target:e},c())),e._x_removeModelListeners||(e._x_removeModelListeners={}),e._x_removeModelListeners.default=g,r(()=>e._x_removeModelListeners.default()),e.form){let _=$t(e.form,\"reset\",[],f=>{ii(()=>e._x_model&&e._x_model.set(Yn(e,t,{target:e},c())))});r(()=>_())}e._x_model={get(){return c()},set(_){l(_)}},e._x_forceModelUpdate=_=>{_===void 0&&typeof n==\"string\"&&n.match(/\\./)&&(_=\"\"),window.fromModel=!0,z(()=>Uo(e,\"value\",_)),delete window.fromModel},a(()=>{let _=c();t.includes(\"unintrusive\")&&document.activeElement.isSameNode(e)||e._x_forceModelUpdate(_)})});function Yn(e,t,n,a){return z(()=>{if(n instanceof CustomEvent&&n.detail!==void 0)return n.detail!==null&&n.detail!==void 0?n.detail:n.target.value;if(oi(e))if(Array.isArray(a)){let r=null;return t.includes(\"number\")?r=Ga(n.target.value):t.includes(\"boolean\")?r=ra(n.target.value):r=n.target.value,n.target.checked?a.includes(r)?a:a.concat([r]):a.filter(i=>!sd(i,r))}else return n.target.checked;else{if(e.tagName.toLowerCase()===\"select\"&&e.multiple)return t.includes(\"number\")?Array.from(n.target.selectedOptions).map(r=>{let i=r.value||r.text;return Ga(i)}):t.includes(\"boolean\")?Array.from(n.target.selectedOptions).map(r=>{let i=r.value||r.text;return ra(i)}):Array.from(n.target.selectedOptions).map(r=>r.value||r.text);{let r;return Vo(e)?n.target.checked?r=n.target.value:r=a:r=n.target.value,t.includes(\"number\")?Ga(r):t.includes(\"boolean\")?ra(r):t.includes(\"trim\")?r.trim():r}}})}function Ga(e){let t=e?parseFloat(e):null;return od(t)?t:e}function sd(e,t){return e==t}function od(e){return!Array.isArray(e)&&!isNaN(e)}function Ki(e){return e!==null&&typeof e==\"object\"&&typeof e.get==\"function\"&&typeof e.set==\"function\"}W(\"cloak\",e=>queueMicrotask(()=>z(()=>e.removeAttribute(Ut(\"cloak\")))));Po(()=>`[${Ut(\"init\")}]`);W(\"init\",Ve((e,{expression:t},{evaluate:n})=>typeof t==\"string\"?!!t.trim()&&n(t,{},!1):n(t,{},!1)));W(\"text\",(e,{expression:t},{effect:n,evaluateLater:a})=>{let r=a(t);n(()=>{r(i=>{z(()=>{e.textContent=i})})})});W(\"html\",(e,{expression:t},{effect:n,evaluateLater:a})=>{let r=a(t);n(()=>{r(i=>{z(()=>{e.innerHTML=i,e._x_ignoreSelf=!0,Pe(e),delete e._x_ignoreSelf})})})});ni($o(\":\",jo(Ut(\"bind:\"))));var bc=(e,{value:t,modifiers:n,expression:a,original:r},{effect:i,cleanup:s})=>{if(!t){let c={};dp(c),ne(e,a)(u=>{Qo(e,u,r)},{scope:c});return}if(t===\"key\")return cd(e,a);if(e._x_inlineBindings&&e._x_inlineBindings[t]&&e._x_inlineBindings[t].extract)return;let o=ne(e,a);i(()=>o(c=>{c===void 0&&typeof a==\"string\"&&a.match(/\\./)&&(c=\"\"),z(()=>Uo(e,t,c,n))})),s(()=>{e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedStyles&&e._x_undoAddedStyles()})};bc.inline=(e,{value:t,modifiers:n,expression:a})=>{t&&(e._x_inlineBindings||(e._x_inlineBindings={}),e._x_inlineBindings[t]={expression:a,extract:!1})};W(\"bind\",bc);function cd(e,t){e._x_keyExpression=t}Lo(()=>`[${Ut(\"data\")}]`);W(\"data\",(e,{expression:t},{cleanup:n})=>{if(ld(e))return;t=t===\"\"?\"{}\":t;let a={};fn(a,e);let r={};hp(r,a);let i=ct(e,t,{scope:r});(i===void 0||i===!0)&&(i={}),fn(i,e);let s=zt(i);Jr(s);let o=Fn(e,s);s.init&&ct(e,s.init),n(()=>{s.destroy&&ct(e,s.destroy),o()})});$a((e,t)=>{e._x_dataStack&&(t._x_dataStack=e._x_dataStack,t.setAttribute(\"data-has-alpine-state\",!0))});function ld(e){return He?vr?!0:e.hasAttribute(\"data-has-alpine-state\"):!1}W(\"show\",(e,{modifiers:t,expression:n},{effect:a})=>{let r=ne(e,n);e._x_doHide||(e._x_doHide=()=>{z(()=>{e.style.setProperty(\"display\",\"none\",t.includes(\"important\")?\"important\":void 0)})}),e._x_doShow||(e._x_doShow=()=>{z(()=>{e.style.length===1&&e.style.display===\"none\"?e.removeAttribute(\"style\"):e.style.removeProperty(\"display\")})});let i=()=>{e._x_doHide(),e._x_isShown=!1},s=()=>{e._x_doShow(),e._x_isShown=!0},o=()=>setTimeout(s),c=_r(p=>p?s():i(),p=>{typeof e._x_toggleAndCascadeWithTransitions==\"function\"?e._x_toggleAndCascadeWithTransitions(e,p,s,i):p?o():i()}),l,u=!0;a(()=>r(p=>{!u&&p===l||(t.includes(\"immediate\")&&(p?o():i()),c(p),l=p,u=!1)}))});W(\"for\",(e,{expression:t},{effect:n,cleanup:a})=>{let r=pd(t),i=ne(e,r.items),s=ne(e,e._x_keyExpression||\"index\");e._x_prevKeys=[],e._x_lookup={},n(()=>ud(e,r,i,s)),a(()=>{Object.values(e._x_lookup).forEach(o=>z(()=>{Gt(o),o.remove()})),delete e._x_prevKeys,delete e._x_lookup})});function ud(e,t,n,a){let r=s=>typeof s==\"object\"&&!Array.isArray(s),i=e;n(s=>{dd(s)&&s>=0&&(s=Array.from(Array(s).keys(),f=>f+1)),s===void 0&&(s=[]);let o=e._x_lookup,c=e._x_prevKeys,l=[],u=[];if(r(s))s=Object.entries(s).map(([f,b])=>{let w=Qi(t,b,f,s);a(y=>{u.includes(y)&&pe(\"Duplicate key on x-for\",e),u.push(y)},{scope:{index:f,...w}}),l.push(w)});else for(let f=0;f<s.length;f++){let b=Qi(t,s[f],f,s);a(w=>{u.includes(w)&&pe(\"Duplicate key on x-for\",e),u.push(w)},{scope:{index:f,...b}}),l.push(b)}let p=[],m=[],h=[],g=[];for(let f=0;f<c.length;f++){let b=c[f];u.indexOf(b)===-1&&h.push(b)}c=c.filter(f=>!h.includes(f));let _=\"template\";for(let f=0;f<u.length;f++){let b=u[f],w=c.indexOf(b);if(w===-1)c.splice(f,0,b),p.push([_,f]);else if(w!==f){let y=c.splice(f,1)[0],d=c.splice(w-1,1)[0];c.splice(f,0,d),c.splice(w,0,y),m.push([y,d])}else g.push(b);_=b}for(let f=0;f<h.length;f++){let b=h[f];b in o&&(z(()=>{Gt(o[b]),o[b].remove()}),delete o[b])}for(let f=0;f<m.length;f++){let[b,w]=m[f],y=o[b],d=o[w],C=document.createElement(\"div\");z(()=>{d||pe('x-for \":key\" is undefined or invalid',i,w,o),d.after(C),y.after(d),d._x_currentIfEl&&d.after(d._x_currentIfEl),C.before(y),y._x_currentIfEl&&y.after(y._x_currentIfEl),C.remove()}),d._x_refreshXForScope(l[u.indexOf(w)])}for(let f=0;f<p.length;f++){let[b,w]=p[f],y=b===\"template\"?i:o[b];y._x_currentIfEl&&(y=y._x_currentIfEl);let d=l[w],C=u[w],k=document.importNode(i.content,!0).firstElementChild,$=zt(d);Fn(k,$,i),k._x_refreshXForScope=T=>{Object.entries(T).forEach(([I,N])=>{$[I]=N})},z(()=>{y.after(k),Ve(()=>Pe(k))()}),typeof C==\"object\"&&pe(\"x-for key cannot be an object, it must be a string or an integer\",i),o[C]=k}for(let f=0;f<g.length;f++)o[g[f]]._x_refreshXForScope(l[u.indexOf(g[f])]);i._x_prevKeys=u})}function pd(e){let t=/,([^,\\}\\]]*)(?:,([^,\\}\\]]*))?$/,n=/^\\s*\\(|\\)\\s*$/g,a=/([\\s\\S]*?)\\s+(?:in|of)\\s+([\\s\\S]*)/,r=e.match(a);if(!r)return;let i={};i.items=r[2].trim();let s=r[1].replace(n,\"\").trim(),o=s.match(t);return o?(i.item=s.replace(t,\"\").trim(),i.index=o[1].trim(),o[2]&&(i.collection=o[2].trim())):i.item=s,i}function Qi(e,t,n,a){let r={};return/^\\[.*\\]$/.test(e.item)&&Array.isArray(t)?e.item.replace(\"[\",\"\").replace(\"]\",\"\").split(\",\").map(s=>s.trim()).forEach((s,o)=>{r[s]=t[o]}):/^\\{.*\\}$/.test(e.item)&&!Array.isArray(t)&&typeof t==\"object\"?e.item.replace(\"{\",\"\").replace(\"}\",\"\").split(\",\").map(s=>s.trim()).forEach(s=>{r[s]=t[s]}):r[e.item]=t,e.index&&(r[e.index]=n),e.collection&&(r[e.collection]=a),r}function dd(e){return!Array.isArray(e)&&!isNaN(e)}function _c(){}_c.inline=(e,{expression:t},{cleanup:n})=>{let a=Ea(e);a._x_refs||(a._x_refs={}),a._x_refs[t]=e,n(()=>delete a._x_refs[t])};W(\"ref\",_c);W(\"if\",(e,{expression:t},{effect:n,cleanup:a})=>{e.tagName.toLowerCase()!==\"template\"&&pe(\"x-if can only be used on a <template> tag\",e);let r=ne(e,t),i=()=>{if(e._x_currentIfEl)return e._x_currentIfEl;let o=e.content.cloneNode(!0).firstElementChild;return Fn(o,{},e),z(()=>{e.after(o),Ve(()=>Pe(o))()}),e._x_currentIfEl=o,e._x_undoIf=()=>{z(()=>{Gt(o),o.remove()}),delete e._x_currentIfEl},o},s=()=>{e._x_undoIf&&(e._x_undoIf(),delete e._x_undoIf)};n(()=>r(o=>{o?i():s()})),a(()=>e._x_undoIf&&e._x_undoIf())});W(\"id\",(e,{expression:t},{evaluate:n})=>{n(t).forEach(r=>Qp(e,r))});$a((e,t)=>{e._x_ids&&(t._x_ids=e._x_ids)});ni($o(\"@\",jo(Ut(\"on:\"))));W(\"on\",Ve((e,{value:t,modifiers:n,expression:a},{cleanup:r})=>{let i=a?ne(e,a):()=>{};e.tagName.toLowerCase()===\"template\"&&(e._x_forwardEvents||(e._x_forwardEvents=[]),e._x_forwardEvents.includes(t)||e._x_forwardEvents.push(t));let s=$t(e,t,n,o=>{i(()=>{},{scope:{$event:o},params:[o]})});r(()=>s())}));Ta(\"Collapse\",\"collapse\",\"collapse\");Ta(\"Intersect\",\"intersect\",\"intersect\");Ta(\"Focus\",\"trap\",\"focus\");Ta(\"Mask\",\"mask\",\"mask\");function Ta(e,t,n){W(t,a=>pe(`You can't use [x-${t}] without first installing the \"${e}\" plugin here: https://alpinejs.dev/plugins/${n}`,a))}Ht.setEvaluator(ko);Ht.setRawEvaluator(Fu);Ht.setReactivityEngine({reactive:hi,effect:Cp,release:Ep,raw:M});var md=Ht,yc=md,ae=\"top\",he=\"bottom\",ge=\"right\",re=\"left\",gi=\"auto\",$n=[ae,he,ge,re],Lt=\"start\",yn=\"end\",hd=\"clippingParents\",vc=\"viewport\",rn=\"popper\",gd=\"reference\",Ji=$n.reduce(function(e,t){return e.concat([t+\"-\"+Lt,t+\"-\"+yn])},[]),wc=[].concat($n,[gi]).reduce(function(e,t){return e.concat([t,t+\"-\"+Lt,t+\"-\"+yn])},[]),fd=\"beforeRead\",bd=\"read\",_d=\"afterRead\",yd=\"beforeMain\",vd=\"main\",wd=\"afterMain\",xd=\"beforeWrite\",kd=\"write\",Cd=\"afterWrite\",Ed=[fd,bd,_d,yd,vd,wd,xd,kd,Cd];function je(e){return e?(e.nodeName||\"\").toLowerCase():null}function oe(e){if(e==null)return window;if(e.toString()!==\"[object Window]\"){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function ft(e){var t=oe(e).Element;return e instanceof t||e instanceof Element}function me(e){var t=oe(e).HTMLElement;return e instanceof t||e instanceof HTMLElement}function fi(e){if(typeof ShadowRoot>\"u\")return!1;var t=oe(e).ShadowRoot;return e instanceof t||e instanceof ShadowRoot}function Fd(e){var t=e.state;Object.keys(t.elements).forEach(function(n){var a=t.styles[n]||{},r=t.attributes[n]||{},i=t.elements[n];!me(i)||!je(i)||(Object.assign(i.style,a),Object.keys(r).forEach(function(s){var o=r[s];o===!1?i.removeAttribute(s):i.setAttribute(s,o===!0?\"\":o)}))})}function $d(e){var t=e.state,n={popper:{position:t.options.strategy,left:\"0\",top:\"0\",margin:\"0\"},arrow:{position:\"absolute\"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach(function(a){var r=t.elements[a],i=t.attributes[a]||{},s=Object.keys(t.styles.hasOwnProperty(a)?t.styles[a]:n[a]),o=s.reduce(function(c,l){return c[l]=\"\",c},{});!me(r)||!je(r)||(Object.assign(r.style,o),Object.keys(i).forEach(function(c){r.removeAttribute(c)}))})}}const xc={name:\"applyStyles\",enabled:!0,phase:\"write\",fn:Fd,effect:$d,requires:[\"computeStyles\"]};function $e(e){return e.split(\"-\")[0]}var pt=Math.max,da=Math.min,Pt=Math.round;function Cr(){var e=navigator.userAgentData;return e!=null&&e.brands&&Array.isArray(e.brands)?e.brands.map(function(t){return t.brand+\"/\"+t.version}).join(\" \"):navigator.userAgent}function kc(){return!/^((?!chrome|android).)*safari/i.test(Cr())}function Dt(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!1);var a=e.getBoundingClientRect(),r=1,i=1;t&&me(e)&&(r=e.offsetWidth>0&&Pt(a.width)/e.offsetWidth||1,i=e.offsetHeight>0&&Pt(a.height)/e.offsetHeight||1);var s=ft(e)?oe(e):window,o=s.visualViewport,c=!kc()&&n,l=(a.left+(c&&o?o.offsetLeft:0))/r,u=(a.top+(c&&o?o.offsetTop:0))/i,p=a.width/r,m=a.height/i;return{width:p,height:m,top:u,right:l+p,bottom:u+m,left:l,x:l,y:u}}function bi(e){var t=Dt(e),n=e.offsetWidth,a=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-a)<=1&&(a=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:a}}function Cc(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&fi(n)){var a=t;do{if(a&&e.isSameNode(a))return!0;a=a.parentNode||a.host}while(a)}return!1}function De(e){return oe(e).getComputedStyle(e)}function jd(e){return[\"table\",\"td\",\"th\"].indexOf(je(e))>=0}function Ze(e){return((ft(e)?e.ownerDocument:e.document)||window.document).documentElement}function Ra(e){return je(e)===\"html\"?e:e.assignedSlot||e.parentNode||(fi(e)?e.host:null)||Ze(e)}function es(e){return!me(e)||De(e).position===\"fixed\"?null:e.offsetParent}function Sd(e){var t=/firefox/i.test(Cr()),n=/Trident/i.test(Cr());if(n&&me(e)){var a=De(e);if(a.position===\"fixed\")return null}var r=Ra(e);for(fi(r)&&(r=r.host);me(r)&&[\"html\",\"body\"].indexOf(je(r))<0;){var i=De(r);if(i.transform!==\"none\"||i.perspective!==\"none\"||i.contain===\"paint\"||[\"transform\",\"perspective\"].indexOf(i.willChange)!==-1||t&&i.willChange===\"filter\"||t&&i.filter&&i.filter!==\"none\")return r;r=r.parentNode}return null}function jn(e){for(var t=oe(e),n=es(e);n&&jd(n)&&De(n).position===\"static\";)n=es(n);return n&&(je(n)===\"html\"||je(n)===\"body\"&&De(n).position===\"static\")?t:n||Sd(e)||t}function _i(e){return[\"top\",\"bottom\"].indexOf(e)>=0?\"x\":\"y\"}function pn(e,t,n){return pt(e,da(t,n))}function Ad(e,t,n){var a=pn(e,t,n);return a>n?n:a}function Ec(){return{top:0,right:0,bottom:0,left:0}}function Fc(e){return Object.assign({},Ec(),e)}function $c(e,t){return t.reduce(function(n,a){return n[a]=e,n},{})}var Td=function(t,n){return t=typeof t==\"function\"?t(Object.assign({},n.rects,{placement:n.placement})):t,Fc(typeof t!=\"number\"?t:$c(t,$n))};function Rd(e){var t,n=e.state,a=e.name,r=e.options,i=n.elements.arrow,s=n.modifiersData.popperOffsets,o=$e(n.placement),c=_i(o),l=[re,ge].indexOf(o)>=0,u=l?\"height\":\"width\";if(!(!i||!s)){var p=Td(r.padding,n),m=bi(i),h=c===\"y\"?ae:re,g=c===\"y\"?he:ge,_=n.rects.reference[u]+n.rects.reference[c]-s[c]-n.rects.popper[u],f=s[c]-n.rects.reference[c],b=jn(i),w=b?c===\"y\"?b.clientHeight||0:b.clientWidth||0:0,y=_/2-f/2,d=p[h],C=w-m[u]-p[g],k=w/2-m[u]/2+y,$=pn(d,k,C),T=c;n.modifiersData[a]=(t={},t[T]=$,t.centerOffset=$-k,t)}}function Od(e){var t=e.state,n=e.options,a=n.element,r=a===void 0?\"[data-popper-arrow]\":a;r!=null&&(typeof r==\"string\"&&(r=t.elements.popper.querySelector(r),!r)||Cc(t.elements.popper,r)&&(t.elements.arrow=r))}const Nd={name:\"arrow\",enabled:!0,phase:\"main\",fn:Rd,effect:Od,requires:[\"popperOffsets\"],requiresIfExists:[\"preventOverflow\"]};function Mt(e){return e.split(\"-\")[1]}var Id={top:\"auto\",right:\"auto\",bottom:\"auto\",left:\"auto\"};function Ld(e,t){var n=e.x,a=e.y,r=t.devicePixelRatio||1;return{x:Pt(n*r)/r||0,y:Pt(a*r)/r||0}}function ts(e){var t,n=e.popper,a=e.popperRect,r=e.placement,i=e.variation,s=e.offsets,o=e.position,c=e.gpuAcceleration,l=e.adaptive,u=e.roundOffsets,p=e.isFixed,m=s.x,h=m===void 0?0:m,g=s.y,_=g===void 0?0:g,f=typeof u==\"function\"?u({x:h,y:_}):{x:h,y:_};h=f.x,_=f.y;var b=s.hasOwnProperty(\"x\"),w=s.hasOwnProperty(\"y\"),y=re,d=ae,C=window;if(l){var k=jn(n),$=\"clientHeight\",T=\"clientWidth\";if(k===oe(n)&&(k=Ze(n),De(k).position!==\"static\"&&o===\"absolute\"&&($=\"scrollHeight\",T=\"scrollWidth\")),k=k,r===ae||(r===re||r===ge)&&i===yn){d=he;var I=p&&k===C&&C.visualViewport?C.visualViewport.height:k[$];_-=I-a.height,_*=c?1:-1}if(r===re||(r===ae||r===he)&&i===yn){y=ge;var N=p&&k===C&&C.visualViewport?C.visualViewport.width:k[T];h-=N-a.width,h*=c?1:-1}}var D=Object.assign({position:o},l&&Id),R=u===!0?Ld({x:h,y:_},oe(n)):{x:h,y:_};if(h=R.x,_=R.y,c){var L;return Object.assign({},D,(L={},L[d]=w?\"0\":\"\",L[y]=b?\"0\":\"\",L.transform=(C.devicePixelRatio||1)<=1?\"translate(\"+h+\"px, \"+_+\"px)\":\"translate3d(\"+h+\"px, \"+_+\"px, 0)\",L))}return Object.assign({},D,(t={},t[d]=w?_+\"px\":\"\",t[y]=b?h+\"px\":\"\",t.transform=\"\",t))}function Pd(e){var t=e.state,n=e.options,a=n.gpuAcceleration,r=a===void 0?!0:a,i=n.adaptive,s=i===void 0?!0:i,o=n.roundOffsets,c=o===void 0?!0:o,l={placement:$e(t.placement),variation:Mt(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r,isFixed:t.options.strategy===\"fixed\"};t.modifiersData.popperOffsets!=null&&(t.styles.popper=Object.assign({},t.styles.popper,ts(Object.assign({},l,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:s,roundOffsets:c})))),t.modifiersData.arrow!=null&&(t.styles.arrow=Object.assign({},t.styles.arrow,ts(Object.assign({},l,{offsets:t.modifiersData.arrow,position:\"absolute\",adaptive:!1,roundOffsets:c})))),t.attributes.popper=Object.assign({},t.attributes.popper,{\"data-popper-placement\":t.placement})}const Dd={name:\"computeStyles\",enabled:!0,phase:\"beforeWrite\",fn:Pd,data:{}};var Xn={passive:!0};function Md(e){var t=e.state,n=e.instance,a=e.options,r=a.scroll,i=r===void 0?!0:r,s=a.resize,o=s===void 0?!0:s,c=oe(t.elements.popper),l=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&l.forEach(function(u){u.addEventListener(\"scroll\",n.update,Xn)}),o&&c.addEventListener(\"resize\",n.update,Xn),function(){i&&l.forEach(function(u){u.removeEventListener(\"scroll\",n.update,Xn)}),o&&c.removeEventListener(\"resize\",n.update,Xn)}}const qd={name:\"eventListeners\",enabled:!0,phase:\"write\",fn:function(){},effect:Md,data:{}};var zd={left:\"right\",right:\"left\",bottom:\"top\",top:\"bottom\"};function ia(e){return e.replace(/left|right|bottom|top/g,function(t){return zd[t]})}var Bd={start:\"end\",end:\"start\"};function ns(e){return e.replace(/start|end/g,function(t){return Bd[t]})}function yi(e){var t=oe(e),n=t.pageXOffset,a=t.pageYOffset;return{scrollLeft:n,scrollTop:a}}function vi(e){return Dt(Ze(e)).left+yi(e).scrollLeft}function Ud(e,t){var n=oe(e),a=Ze(e),r=n.visualViewport,i=a.clientWidth,s=a.clientHeight,o=0,c=0;if(r){i=r.width,s=r.height;var l=kc();(l||!l&&t===\"fixed\")&&(o=r.offsetLeft,c=r.offsetTop)}return{width:i,height:s,x:o+vi(e),y:c}}function Gd(e){var t,n=Ze(e),a=yi(e),r=(t=e.ownerDocument)==null?void 0:t.body,i=pt(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),s=pt(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),o=-a.scrollLeft+vi(e),c=-a.scrollTop;return De(r||n).direction===\"rtl\"&&(o+=pt(n.clientWidth,r?r.clientWidth:0)-i),{width:i,height:s,x:o,y:c}}function wi(e){var t=De(e),n=t.overflow,a=t.overflowX,r=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+r+a)}function jc(e){return[\"html\",\"body\",\"#document\"].indexOf(je(e))>=0?e.ownerDocument.body:me(e)&&wi(e)?e:jc(Ra(e))}function dn(e,t){var n;t===void 0&&(t=[]);var a=jc(e),r=a===((n=e.ownerDocument)==null?void 0:n.body),i=oe(a),s=r?[i].concat(i.visualViewport||[],wi(a)?a:[]):a,o=t.concat(s);return r?o:o.concat(dn(Ra(s)))}function Er(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function Hd(e,t){var n=Dt(e,!1,t===\"fixed\");return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}function as(e,t,n){return t===vc?Er(Ud(e,n)):ft(t)?Hd(t,n):Er(Gd(Ze(e)))}function Wd(e){var t=dn(Ra(e)),n=[\"absolute\",\"fixed\"].indexOf(De(e).position)>=0,a=n&&me(e)?jn(e):e;return ft(a)?t.filter(function(r){return ft(r)&&Cc(r,a)&&je(r)!==\"body\"}):[]}function Vd(e,t,n,a){var r=t===\"clippingParents\"?Wd(e):[].concat(t),i=[].concat(r,[n]),s=i[0],o=i.reduce(function(c,l){var u=as(e,l,a);return c.top=pt(u.top,c.top),c.right=da(u.right,c.right),c.bottom=da(u.bottom,c.bottom),c.left=pt(u.left,c.left),c},as(e,s,a));return o.width=o.right-o.left,o.height=o.bottom-o.top,o.x=o.left,o.y=o.top,o}function Sc(e){var t=e.reference,n=e.element,a=e.placement,r=a?$e(a):null,i=a?Mt(a):null,s=t.x+t.width/2-n.width/2,o=t.y+t.height/2-n.height/2,c;switch(r){case ae:c={x:s,y:t.y-n.height};break;case he:c={x:s,y:t.y+t.height};break;case ge:c={x:t.x+t.width,y:o};break;case re:c={x:t.x-n.width,y:o};break;default:c={x:t.x,y:t.y}}var l=r?_i(r):null;if(l!=null){var u=l===\"y\"?\"height\":\"width\";switch(i){case Lt:c[l]=c[l]-(t[u]/2-n[u]/2);break;case yn:c[l]=c[l]+(t[u]/2-n[u]/2);break}}return c}function vn(e,t){t===void 0&&(t={});var n=t,a=n.placement,r=a===void 0?e.placement:a,i=n.strategy,s=i===void 0?e.strategy:i,o=n.boundary,c=o===void 0?hd:o,l=n.rootBoundary,u=l===void 0?vc:l,p=n.elementContext,m=p===void 0?rn:p,h=n.altBoundary,g=h===void 0?!1:h,_=n.padding,f=_===void 0?0:_,b=Fc(typeof f!=\"number\"?f:$c(f,$n)),w=m===rn?gd:rn,y=e.rects.popper,d=e.elements[g?w:m],C=Vd(ft(d)?d:d.contextElement||Ze(e.elements.popper),c,u,s),k=Dt(e.elements.reference),$=Sc({reference:k,element:y,placement:r}),T=Er(Object.assign({},y,$)),I=m===rn?T:k,N={top:C.top-I.top+b.top,bottom:I.bottom-C.bottom+b.bottom,left:C.left-I.left+b.left,right:I.right-C.right+b.right},D=e.modifiersData.offset;if(m===rn&&D){var R=D[r];Object.keys(N).forEach(function(L){var q=[ge,he].indexOf(L)>=0?1:-1,U=[ae,he].indexOf(L)>=0?\"y\":\"x\";N[L]+=R[U]*q})}return N}function Zd(e,t){t===void 0&&(t={});var n=t,a=n.placement,r=n.boundary,i=n.rootBoundary,s=n.padding,o=n.flipVariations,c=n.allowedAutoPlacements,l=c===void 0?wc:c,u=Mt(a),p=u?o?Ji:Ji.filter(function(g){return Mt(g)===u}):$n,m=p.filter(function(g){return l.indexOf(g)>=0});m.length===0&&(m=p);var h=m.reduce(function(g,_){return g[_]=vn(e,{placement:_,boundary:r,rootBoundary:i,padding:s})[$e(_)],g},{});return Object.keys(h).sort(function(g,_){return h[g]-h[_]})}function Yd(e){if($e(e)===gi)return[];var t=ia(e);return[ns(e),t,ns(t)]}function Xd(e){var t=e.state,n=e.options,a=e.name;if(!t.modifiersData[a]._skip){for(var r=n.mainAxis,i=r===void 0?!0:r,s=n.altAxis,o=s===void 0?!0:s,c=n.fallbackPlacements,l=n.padding,u=n.boundary,p=n.rootBoundary,m=n.altBoundary,h=n.flipVariations,g=h===void 0?!0:h,_=n.allowedAutoPlacements,f=t.options.placement,b=$e(f),w=b===f,y=c||(w||!g?[ia(f)]:Yd(f)),d=[f].concat(y).reduce(function(Se,fe){return Se.concat($e(fe)===gi?Zd(t,{placement:fe,boundary:u,rootBoundary:p,padding:l,flipVariations:g,allowedAutoPlacements:_}):fe)},[]),C=t.rects.reference,k=t.rects.popper,$=new Map,T=!0,I=d[0],N=0;N<d.length;N++){var D=d[N],R=$e(D),L=Mt(D)===Lt,q=[ae,he].indexOf(R)>=0,U=q?\"width\":\"height\",G=vn(t,{placement:D,boundary:u,rootBoundary:p,altBoundary:m,padding:l}),Q=q?L?ge:re:L?he:ae;C[U]>k[U]&&(Q=ia(Q));var K=ia(Q),we=[];if(i&&we.push(G[R]<=0),o&&we.push(G[Q]<=0,G[K]<=0),we.every(function(Se){return Se})){I=D,T=!1;break}$.set(D,we)}if(T)for(var xe=g?3:1,Ye=function(fe){var Ae=d.find(function(vt){var Te=$.get(vt);if(Te)return Te.slice(0,fe).every(function(wt){return wt})});if(Ae)return I=Ae,\"break\"},ke=xe;ke>0;ke--){var Xe=Ye(ke);if(Xe===\"break\")break}t.placement!==I&&(t.modifiersData[a]._skip=!0,t.placement=I,t.reset=!0)}}const Kd={name:\"flip\",enabled:!0,phase:\"main\",fn:Xd,requiresIfExists:[\"offset\"],data:{_skip:!1}};function rs(e,t,n){return n===void 0&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function is(e){return[ae,ge,he,re].some(function(t){return e[t]>=0})}function Qd(e){var t=e.state,n=e.name,a=t.rects.reference,r=t.rects.popper,i=t.modifiersData.preventOverflow,s=vn(t,{elementContext:\"reference\"}),o=vn(t,{altBoundary:!0}),c=rs(s,a),l=rs(o,r,i),u=is(c),p=is(l);t.modifiersData[n]={referenceClippingOffsets:c,popperEscapeOffsets:l,isReferenceHidden:u,hasPopperEscaped:p},t.attributes.popper=Object.assign({},t.attributes.popper,{\"data-popper-reference-hidden\":u,\"data-popper-escaped\":p})}const Jd={name:\"hide\",enabled:!0,phase:\"main\",requiresIfExists:[\"preventOverflow\"],fn:Qd};function em(e,t,n){var a=$e(e),r=[re,ae].indexOf(a)>=0?-1:1,i=typeof n==\"function\"?n(Object.assign({},t,{placement:e})):n,s=i[0],o=i[1];return s=s||0,o=(o||0)*r,[re,ge].indexOf(a)>=0?{x:o,y:s}:{x:s,y:o}}function tm(e){var t=e.state,n=e.options,a=e.name,r=n.offset,i=r===void 0?[0,0]:r,s=wc.reduce(function(u,p){return u[p]=em(p,t.rects,i),u},{}),o=s[t.placement],c=o.x,l=o.y;t.modifiersData.popperOffsets!=null&&(t.modifiersData.popperOffsets.x+=c,t.modifiersData.popperOffsets.y+=l),t.modifiersData[a]=s}const nm={name:\"offset\",enabled:!0,phase:\"main\",requires:[\"popperOffsets\"],fn:tm};function am(e){var t=e.state,n=e.name;t.modifiersData[n]=Sc({reference:t.rects.reference,element:t.rects.popper,placement:t.placement})}const rm={name:\"popperOffsets\",enabled:!0,phase:\"read\",fn:am,data:{}};function im(e){return e===\"x\"?\"y\":\"x\"}function sm(e){var t=e.state,n=e.options,a=e.name,r=n.mainAxis,i=r===void 0?!0:r,s=n.altAxis,o=s===void 0?!1:s,c=n.boundary,l=n.rootBoundary,u=n.altBoundary,p=n.padding,m=n.tether,h=m===void 0?!0:m,g=n.tetherOffset,_=g===void 0?0:g,f=vn(t,{boundary:c,rootBoundary:l,padding:p,altBoundary:u}),b=$e(t.placement),w=Mt(t.placement),y=!w,d=_i(b),C=im(d),k=t.modifiersData.popperOffsets,$=t.rects.reference,T=t.rects.popper,I=typeof _==\"function\"?_(Object.assign({},t.rects,{placement:t.placement})):_,N=typeof I==\"number\"?{mainAxis:I,altAxis:I}:Object.assign({mainAxis:0,altAxis:0},I),D=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,R={x:0,y:0};if(k){if(i){var L,q=d===\"y\"?ae:re,U=d===\"y\"?he:ge,G=d===\"y\"?\"height\":\"width\",Q=k[d],K=Q+f[q],we=Q-f[U],xe=h?-T[G]/2:0,Ye=w===Lt?$[G]:T[G],ke=w===Lt?-T[G]:-$[G],Xe=t.elements.arrow,Se=h&&Xe?bi(Xe):{width:0,height:0},fe=t.modifiersData[\"arrow#persistent\"]?t.modifiersData[\"arrow#persistent\"].padding:Ec(),Ae=fe[q],vt=fe[U],Te=pn(0,$[G],Se[G]),wt=y?$[G]/2-xe-Te-Ae-N.mainAxis:Ye-Te-Ae-N.mainAxis,Me=y?-$[G]/2+xe+Te+vt+N.mainAxis:ke+Te+vt+N.mainAxis,xt=t.elements.arrow&&jn(t.elements.arrow),On=xt?d===\"y\"?xt.clientTop||0:xt.clientLeft||0:0,Xt=(L=D?.[d])!=null?L:0,Nn=Q+wt-Xt-On,In=Q+Me-Xt,Kt=pn(h?da(K,Nn):K,Q,h?pt(we,In):we);k[d]=Kt,R[d]=Kt-Q}if(o){var Qt,Ln=d===\"x\"?ae:re,Pn=d===\"x\"?he:ge,Re=k[C],qe=C===\"y\"?\"height\":\"width\",Jt=Re+f[Ln],Ke=Re-f[Pn],en=[ae,re].indexOf(b)!==-1,Dn=(Qt=D?.[C])!=null?Qt:0,Mn=en?Jt:Re-$[qe]-T[qe]-Dn+N.altAxis,qn=en?Re+$[qe]+T[qe]-Dn-N.altAxis:Ke,zn=h&&en?Ad(Mn,Re,qn):pn(h?Mn:Jt,Re,h?qn:Ke);k[C]=zn,R[C]=zn-Re}t.modifiersData[a]=R}}const om={name:\"preventOverflow\",enabled:!0,phase:\"main\",fn:sm,requiresIfExists:[\"offset\"]};function cm(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}function lm(e){return e===oe(e)||!me(e)?yi(e):cm(e)}function um(e){var t=e.getBoundingClientRect(),n=Pt(t.width)/e.offsetWidth||1,a=Pt(t.height)/e.offsetHeight||1;return n!==1||a!==1}function pm(e,t,n){n===void 0&&(n=!1);var a=me(t),r=me(t)&&um(t),i=Ze(t),s=Dt(e,r,n),o={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!n)&&((je(t)!==\"body\"||wi(i))&&(o=lm(t)),me(t)?(c=Dt(t,!0),c.x+=t.clientLeft,c.y+=t.clientTop):i&&(c.x=vi(i))),{x:s.left+o.scrollLeft-c.x,y:s.top+o.scrollTop-c.y,width:s.width,height:s.height}}function dm(e){var t=new Map,n=new Set,a=[];e.forEach(function(i){t.set(i.name,i)});function r(i){n.add(i.name);var s=[].concat(i.requires||[],i.requiresIfExists||[]);s.forEach(function(o){if(!n.has(o)){var c=t.get(o);c&&r(c)}}),a.push(i)}return e.forEach(function(i){n.has(i.name)||r(i)}),a}function mm(e){var t=dm(e);return Ed.reduce(function(n,a){return n.concat(t.filter(function(r){return r.phase===a}))},[])}function hm(e){var t;return function(){return t||(t=new Promise(function(n){Promise.resolve().then(function(){t=void 0,n(e())})})),t}}function gm(e){var t=e.reduce(function(n,a){var r=n[a.name];return n[a.name]=r?Object.assign({},r,a,{options:Object.assign({},r.options,a.options),data:Object.assign({},r.data,a.data)}):a,n},{});return Object.keys(t).map(function(n){return t[n]})}var ss={placement:\"bottom\",modifiers:[],strategy:\"absolute\"};function os(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some(function(a){return!(a&&typeof a.getBoundingClientRect==\"function\")})}function fm(e){e===void 0&&(e={});var t=e,n=t.defaultModifiers,a=n===void 0?[]:n,r=t.defaultOptions,i=r===void 0?ss:r;return function(o,c,l){l===void 0&&(l=i);var u={placement:\"bottom\",orderedModifiers:[],options:Object.assign({},ss,i),modifiersData:{},elements:{reference:o,popper:c},attributes:{},styles:{}},p=[],m=!1,h={state:u,setOptions:function(b){var w=typeof b==\"function\"?b(u.options):b;_(),u.options=Object.assign({},i,u.options,w),u.scrollParents={reference:ft(o)?dn(o):o.contextElement?dn(o.contextElement):[],popper:dn(c)};var y=mm(gm([].concat(a,u.options.modifiers)));return u.orderedModifiers=y.filter(function(d){return d.enabled}),g(),h.update()},forceUpdate:function(){if(!m){var b=u.elements,w=b.reference,y=b.popper;if(os(w,y)){u.rects={reference:pm(w,jn(y),u.options.strategy===\"fixed\"),popper:bi(y)},u.reset=!1,u.placement=u.options.placement,u.orderedModifiers.forEach(function(N){return u.modifiersData[N.name]=Object.assign({},N.data)});for(var d=0;d<u.orderedModifiers.length;d++){if(u.reset===!0){u.reset=!1,d=-1;continue}var C=u.orderedModifiers[d],k=C.fn,$=C.options,T=$===void 0?{}:$,I=C.name;typeof k==\"function\"&&(u=k({state:u,options:T,name:I,instance:h})||u)}}}},update:hm(function(){return new Promise(function(f){h.forceUpdate(),f(u)})}),destroy:function(){_(),m=!0}};if(!os(o,c))return h;h.setOptions(l).then(function(f){!m&&l.onFirstUpdate&&l.onFirstUpdate(f)});function g(){u.orderedModifiers.forEach(function(f){var b=f.name,w=f.options,y=w===void 0?{}:w,d=f.effect;if(typeof d==\"function\"){var C=d({state:u,name:b,instance:h,options:y}),k=function(){};p.push(C||k)}})}function _(){p.forEach(function(f){return f()}),p=[]}return h}}var bm=[qd,rm,Dd,xc,nm,Kd,om,Nd,Jd],_m=fm({defaultModifiers:bm}),ym=\"tippy-box\",Ac=\"tippy-content\",vm=\"tippy-backdrop\",Tc=\"tippy-arrow\",Rc=\"tippy-svg-arrow\",tt={passive:!0,capture:!0},Oc=function(){return document.body};function Ha(e,t,n){if(Array.isArray(e)){var a=e[t];return a??(Array.isArray(n)?n[t]:n)}return e}function xi(e,t){var n={}.toString.call(e);return n.indexOf(\"[object\")===0&&n.indexOf(t+\"]\")>-1}function Nc(e,t){return typeof e==\"function\"?e.apply(void 0,t):e}function cs(e,t){if(t===0)return e;var n;return function(a){clearTimeout(n),n=setTimeout(function(){e(a)},t)}}function wm(e){return e.split(/\\s+/).filter(Boolean)}function jt(e){return[].concat(e)}function ls(e,t){e.indexOf(t)===-1&&e.push(t)}function xm(e){return e.filter(function(t,n){return e.indexOf(t)===n})}function km(e){return e.split(\"-\")[0]}function ma(e){return[].slice.call(e)}function us(e){return Object.keys(e).reduce(function(t,n){return e[n]!==void 0&&(t[n]=e[n]),t},{})}function mn(){return document.createElement(\"div\")}function Oa(e){return[\"Element\",\"Fragment\"].some(function(t){return xi(e,t)})}function Cm(e){return xi(e,\"NodeList\")}function Em(e){return xi(e,\"MouseEvent\")}function Fm(e){return!!(e&&e._tippy&&e._tippy.reference===e)}function $m(e){return Oa(e)?[e]:Cm(e)?ma(e):Array.isArray(e)?e:ma(document.querySelectorAll(e))}function Wa(e,t){e.forEach(function(n){n&&(n.style.transitionDuration=t+\"ms\")})}function ps(e,t){e.forEach(function(n){n&&n.setAttribute(\"data-state\",t)})}function jm(e){var t,n=jt(e),a=n[0];return a!=null&&(t=a.ownerDocument)!=null&&t.body?a.ownerDocument:document}function Sm(e,t){var n=t.clientX,a=t.clientY;return e.every(function(r){var i=r.popperRect,s=r.popperState,o=r.props,c=o.interactiveBorder,l=km(s.placement),u=s.modifiersData.offset;if(!u)return!0;var p=l===\"bottom\"?u.top.y:0,m=l===\"top\"?u.bottom.y:0,h=l===\"right\"?u.left.x:0,g=l===\"left\"?u.right.x:0,_=i.top-a+p>c,f=a-i.bottom-m>c,b=i.left-n+h>c,w=n-i.right-g>c;return _||f||b||w})}function Va(e,t,n){var a=t+\"EventListener\";[\"transitionend\",\"webkitTransitionEnd\"].forEach(function(r){e[a](r,n)})}function ds(e,t){for(var n=t;n;){var a;if(e.contains(n))return!0;n=n.getRootNode==null||(a=n.getRootNode())==null?void 0:a.host}return!1}var Fe={isTouch:!1},ms=0;function Am(){Fe.isTouch||(Fe.isTouch=!0,window.performance&&document.addEventListener(\"mousemove\",Ic))}function Ic(){var e=performance.now();e-ms<20&&(Fe.isTouch=!1,document.removeEventListener(\"mousemove\",Ic)),ms=e}function Tm(){var e=document.activeElement;if(Fm(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}function Rm(){document.addEventListener(\"touchstart\",Am,tt),window.addEventListener(\"blur\",Tm)}var Om=typeof window<\"u\"&&typeof document<\"u\",Nm=Om?!!window.msCrypto:!1,Im={animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},Lm={allowHTML:!1,animation:\"fade\",arrow:!0,content:\"\",inertia:!1,maxWidth:350,role:\"tooltip\",theme:\"\",zIndex:9999},_e=Object.assign({appendTo:Oc,aria:{content:\"auto\",expanded:\"auto\"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:\"\",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:\"top\",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:\"mouseenter focus\",triggerTarget:null},Im,Lm),Pm=Object.keys(_e),Dm=function(t){var n=Object.keys(t);n.forEach(function(a){_e[a]=t[a]})};function Lc(e){var t=e.plugins||[],n=t.reduce(function(a,r){var i=r.name,s=r.defaultValue;if(i){var o;a[i]=e[i]!==void 0?e[i]:(o=_e[i])!=null?o:s}return a},{});return Object.assign({},e,n)}function Mm(e,t){var n=t?Object.keys(Lc(Object.assign({},_e,{plugins:t}))):Pm,a=n.reduce(function(r,i){var s=(e.getAttribute(\"data-tippy-\"+i)||\"\").trim();if(!s)return r;if(i===\"content\")r[i]=s;else try{r[i]=JSON.parse(s)}catch{r[i]=s}return r},{});return a}function hs(e,t){var n=Object.assign({},t,{content:Nc(t.content,[e])},t.ignoreAttributes?{}:Mm(e,t.plugins));return n.aria=Object.assign({},_e.aria,n.aria),n.aria={expanded:n.aria.expanded===\"auto\"?t.interactive:n.aria.expanded,content:n.aria.content===\"auto\"?t.interactive?null:\"describedby\":n.aria.content},n}var qm=function(){return\"innerHTML\"};function Fr(e,t){e[qm()]=t}function gs(e){var t=mn();return e===!0?t.className=Tc:(t.className=Rc,Oa(e)?t.appendChild(e):Fr(t,e)),t}function fs(e,t){Oa(t.content)?(Fr(e,\"\"),e.appendChild(t.content)):typeof t.content!=\"function\"&&(t.allowHTML?Fr(e,t.content):e.textContent=t.content)}function $r(e){var t=e.firstElementChild,n=ma(t.children);return{box:t,content:n.find(function(a){return a.classList.contains(Ac)}),arrow:n.find(function(a){return a.classList.contains(Tc)||a.classList.contains(Rc)}),backdrop:n.find(function(a){return a.classList.contains(vm)})}}function Pc(e){var t=mn(),n=mn();n.className=ym,n.setAttribute(\"data-state\",\"hidden\"),n.setAttribute(\"tabindex\",\"-1\");var a=mn();a.className=Ac,a.setAttribute(\"data-state\",\"hidden\"),fs(a,e.props),t.appendChild(n),n.appendChild(a),r(e.props,e.props);function r(i,s){var o=$r(t),c=o.box,l=o.content,u=o.arrow;s.theme?c.setAttribute(\"data-theme\",s.theme):c.removeAttribute(\"data-theme\"),typeof s.animation==\"string\"?c.setAttribute(\"data-animation\",s.animation):c.removeAttribute(\"data-animation\"),s.inertia?c.setAttribute(\"data-inertia\",\"\"):c.removeAttribute(\"data-inertia\"),c.style.maxWidth=typeof s.maxWidth==\"number\"?s.maxWidth+\"px\":s.maxWidth,s.role?c.setAttribute(\"role\",s.role):c.removeAttribute(\"role\"),(i.content!==s.content||i.allowHTML!==s.allowHTML)&&fs(l,e.props),s.arrow?u?i.arrow!==s.arrow&&(c.removeChild(u),c.appendChild(gs(s.arrow))):c.appendChild(gs(s.arrow)):u&&c.removeChild(u)}return{popper:t,onUpdate:r}}Pc.$$tippy=!0;var zm=1,Kn=[],Za=[];function Bm(e,t){var n=hs(e,Object.assign({},_e,Lc(us(t)))),a,r,i,s=!1,o=!1,c=!1,l=!1,u,p,m,h=[],g=cs(Nn,n.interactiveDebounce),_,f=zm++,b=null,w=xm(n.plugins),y={isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},d={id:f,reference:e,popper:mn(),popperInstance:b,props:n,state:y,plugins:w,clearDelayTimeouts:Mn,setProps:qn,setContent:zn,show:Wl,hide:Vl,hideWithInteractivity:Zl,enable:en,disable:Dn,unmount:Yl,destroy:Xl};if(!n.render)return d;var C=n.render(d),k=C.popper,$=C.onUpdate;k.setAttribute(\"data-tippy-root\",\"\"),k.id=\"tippy-\"+d.id,d.popper=k,e._tippy=d,k._tippy=d;var T=w.map(function(v){return v.fn(d)}),I=e.hasAttribute(\"aria-expanded\");return xt(),xe(),Q(),K(\"onCreate\",[d]),n.showOnCreate&&Jt(),k.addEventListener(\"mouseenter\",function(){d.props.interactive&&d.state.isVisible&&d.clearDelayTimeouts()}),k.addEventListener(\"mouseleave\",function(){d.props.interactive&&d.props.trigger.indexOf(\"mouseenter\")>=0&&q().addEventListener(\"mousemove\",g)}),d;function N(){var v=d.props.touch;return Array.isArray(v)?v:[v,0]}function D(){return N()[0]===\"hold\"}function R(){var v;return!!((v=d.props.render)!=null&&v.$$tippy)}function L(){return _||e}function q(){var v=L().parentNode;return v?jm(v):document}function U(){return $r(k)}function G(v){return d.state.isMounted&&!d.state.isVisible||Fe.isTouch||u&&u.type===\"focus\"?0:Ha(d.props.delay,v?0:1,_e.delay)}function Q(v){v===void 0&&(v=!1),k.style.pointerEvents=d.props.interactive&&!v?\"\":\"none\",k.style.zIndex=\"\"+d.props.zIndex}function K(v,E,F){if(F===void 0&&(F=!0),T.forEach(function(A){A[v]&&A[v].apply(A,E)}),F){var O;(O=d.props)[v].apply(O,E)}}function we(){var v=d.props.aria;if(v.content){var E=\"aria-\"+v.content,F=k.id,O=jt(d.props.triggerTarget||e);O.forEach(function(A){var te=A.getAttribute(E);if(d.state.isVisible)A.setAttribute(E,te?te+\" \"+F:F);else{var ce=te&&te.replace(F,\"\").trim();ce?A.setAttribute(E,ce):A.removeAttribute(E)}})}}function xe(){if(!(I||!d.props.aria.expanded)){var v=jt(d.props.triggerTarget||e);v.forEach(function(E){d.props.interactive?E.setAttribute(\"aria-expanded\",d.state.isVisible&&E===L()?\"true\":\"false\"):E.removeAttribute(\"aria-expanded\")})}}function Ye(){q().removeEventListener(\"mousemove\",g),Kn=Kn.filter(function(v){return v!==g})}function ke(v){if(!(Fe.isTouch&&(c||v.type===\"mousedown\"))){var E=v.composedPath&&v.composedPath()[0]||v.target;if(!(d.props.interactive&&ds(k,E))){if(jt(d.props.triggerTarget||e).some(function(F){return ds(F,E)})){if(Fe.isTouch||d.state.isVisible&&d.props.trigger.indexOf(\"click\")>=0)return}else K(\"onClickOutside\",[d,v]);d.props.hideOnClick===!0&&(d.clearDelayTimeouts(),d.hide(),o=!0,setTimeout(function(){o=!1}),d.state.isMounted||Ae())}}}function Xe(){c=!0}function Se(){c=!1}function fe(){var v=q();v.addEventListener(\"mousedown\",ke,!0),v.addEventListener(\"touchend\",ke,tt),v.addEventListener(\"touchstart\",Se,tt),v.addEventListener(\"touchmove\",Xe,tt)}function Ae(){var v=q();v.removeEventListener(\"mousedown\",ke,!0),v.removeEventListener(\"touchend\",ke,tt),v.removeEventListener(\"touchstart\",Se,tt),v.removeEventListener(\"touchmove\",Xe,tt)}function vt(v,E){wt(v,function(){!d.state.isVisible&&k.parentNode&&k.parentNode.contains(k)&&E()})}function Te(v,E){wt(v,E)}function wt(v,E){var F=U().box;function O(A){A.target===F&&(Va(F,\"remove\",O),E())}if(v===0)return E();Va(F,\"remove\",p),Va(F,\"add\",O),p=O}function Me(v,E,F){F===void 0&&(F=!1);var O=jt(d.props.triggerTarget||e);O.forEach(function(A){A.addEventListener(v,E,F),h.push({node:A,eventType:v,handler:E,options:F})})}function xt(){D()&&(Me(\"touchstart\",Xt,{passive:!0}),Me(\"touchend\",In,{passive:!0})),wm(d.props.trigger).forEach(function(v){if(v!==\"manual\")switch(Me(v,Xt),v){case\"mouseenter\":Me(\"mouseleave\",In);break;case\"focus\":Me(Nm?\"focusout\":\"blur\",Kt);break;case\"focusin\":Me(\"focusout\",Kt);break}})}function On(){h.forEach(function(v){var E=v.node,F=v.eventType,O=v.handler,A=v.options;E.removeEventListener(F,O,A)}),h=[]}function Xt(v){var E,F=!1;if(!(!d.state.isEnabled||Qt(v)||o)){var O=((E=u)==null?void 0:E.type)===\"focus\";u=v,_=v.currentTarget,xe(),!d.state.isVisible&&Em(v)&&Kn.forEach(function(A){return A(v)}),v.type===\"click\"&&(d.props.trigger.indexOf(\"mouseenter\")<0||s)&&d.props.hideOnClick!==!1&&d.state.isVisible?F=!0:Jt(v),v.type===\"click\"&&(s=!F),F&&!O&&Ke(v)}}function Nn(v){var E=v.target,F=L().contains(E)||k.contains(E);if(!(v.type===\"mousemove\"&&F)){var O=qe().concat(k).map(function(A){var te,ce=A._tippy,kt=(te=ce.popperInstance)==null?void 0:te.state;return kt?{popperRect:A.getBoundingClientRect(),popperState:kt,props:n}:null}).filter(Boolean);Sm(O,v)&&(Ye(),Ke(v))}}function In(v){var E=Qt(v)||d.props.trigger.indexOf(\"click\")>=0&&s;if(!E){if(d.props.interactive){d.hideWithInteractivity(v);return}Ke(v)}}function Kt(v){d.props.trigger.indexOf(\"focusin\")<0&&v.target!==L()||d.props.interactive&&v.relatedTarget&&k.contains(v.relatedTarget)||Ke(v)}function Qt(v){return Fe.isTouch?D()!==v.type.indexOf(\"touch\")>=0:!1}function Ln(){Pn();var v=d.props,E=v.popperOptions,F=v.placement,O=v.offset,A=v.getReferenceClientRect,te=v.moveTransition,ce=R()?$r(k).arrow:null,kt=A?{getBoundingClientRect:A,contextElement:A.contextElement||L()}:e,Di={name:\"$$tippy\",enabled:!0,phase:\"beforeWrite\",requires:[\"computeStyles\"],fn:function(Bn){var Ct=Bn.state;if(R()){var Kl=U(),qa=Kl.box;[\"placement\",\"reference-hidden\",\"escaped\"].forEach(function(Un){Un===\"placement\"?qa.setAttribute(\"data-placement\",Ct.placement):Ct.attributes.popper[\"data-popper-\"+Un]?qa.setAttribute(\"data-\"+Un,\"\"):qa.removeAttribute(\"data-\"+Un)}),Ct.attributes.popper={}}}},Qe=[{name:\"offset\",options:{offset:O}},{name:\"preventOverflow\",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:\"flip\",options:{padding:5}},{name:\"computeStyles\",options:{adaptive:!te}},Di];R()&&ce&&Qe.push({name:\"arrow\",options:{element:ce,padding:3}}),Qe.push.apply(Qe,E?.modifiers||[]),d.popperInstance=_m(kt,k,Object.assign({},E,{placement:F,onFirstUpdate:m,modifiers:Qe}))}function Pn(){d.popperInstance&&(d.popperInstance.destroy(),d.popperInstance=null)}function Re(){var v=d.props.appendTo,E,F=L();d.props.interactive&&v===Oc||v===\"parent\"?E=F.parentNode:E=Nc(v,[F]),E.contains(k)||E.appendChild(k),d.state.isMounted=!0,Ln()}function qe(){return ma(k.querySelectorAll(\"[data-tippy-root]\"))}function Jt(v){d.clearDelayTimeouts(),v&&K(\"onTrigger\",[d,v]),fe();var E=G(!0),F=N(),O=F[0],A=F[1];Fe.isTouch&&O===\"hold\"&&A&&(E=A),E?a=setTimeout(function(){d.show()},E):d.show()}function Ke(v){if(d.clearDelayTimeouts(),K(\"onUntrigger\",[d,v]),!d.state.isVisible){Ae();return}if(!(d.props.trigger.indexOf(\"mouseenter\")>=0&&d.props.trigger.indexOf(\"click\")>=0&&[\"mouseleave\",\"mousemove\"].indexOf(v.type)>=0&&s)){var E=G(!1);E?r=setTimeout(function(){d.state.isVisible&&d.hide()},E):i=requestAnimationFrame(function(){d.hide()})}}function en(){d.state.isEnabled=!0}function Dn(){d.hide(),d.state.isEnabled=!1}function Mn(){clearTimeout(a),clearTimeout(r),cancelAnimationFrame(i)}function qn(v){if(!d.state.isDestroyed){K(\"onBeforeUpdate\",[d,v]),On();var E=d.props,F=hs(e,Object.assign({},E,us(v),{ignoreAttributes:!0}));d.props=F,xt(),E.interactiveDebounce!==F.interactiveDebounce&&(Ye(),g=cs(Nn,F.interactiveDebounce)),E.triggerTarget&&!F.triggerTarget?jt(E.triggerTarget).forEach(function(O){O.removeAttribute(\"aria-expanded\")}):F.triggerTarget&&e.removeAttribute(\"aria-expanded\"),xe(),Q(),$&&$(E,F),d.popperInstance&&(Ln(),qe().forEach(function(O){requestAnimationFrame(O._tippy.popperInstance.forceUpdate)})),K(\"onAfterUpdate\",[d,v])}}function zn(v){d.setProps({content:v})}function Wl(){var v=d.state.isVisible,E=d.state.isDestroyed,F=!d.state.isEnabled,O=Fe.isTouch&&!d.props.touch,A=Ha(d.props.duration,0,_e.duration);if(!(v||E||F||O)&&!L().hasAttribute(\"disabled\")&&(K(\"onShow\",[d],!1),d.props.onShow(d)!==!1)){if(d.state.isVisible=!0,R()&&(k.style.visibility=\"visible\"),Q(),fe(),d.state.isMounted||(k.style.transition=\"none\"),R()){var te=U(),ce=te.box,kt=te.content;Wa([ce,kt],0)}m=function(){var Qe;if(!(!d.state.isVisible||l)){if(l=!0,k.offsetHeight,k.style.transition=d.props.moveTransition,R()&&d.props.animation){var Ma=U(),Bn=Ma.box,Ct=Ma.content;Wa([Bn,Ct],A),ps([Bn,Ct],\"visible\")}we(),xe(),ls(Za,d),(Qe=d.popperInstance)==null||Qe.forceUpdate(),K(\"onMount\",[d]),d.props.animation&&R()&&Te(A,function(){d.state.isShown=!0,K(\"onShown\",[d])})}},Re()}}function Vl(){var v=!d.state.isVisible,E=d.state.isDestroyed,F=!d.state.isEnabled,O=Ha(d.props.duration,1,_e.duration);if(!(v||E||F)&&(K(\"onHide\",[d],!1),d.props.onHide(d)!==!1)){if(d.state.isVisible=!1,d.state.isShown=!1,l=!1,s=!1,R()&&(k.style.visibility=\"hidden\"),Ye(),Ae(),Q(!0),R()){var A=U(),te=A.box,ce=A.content;d.props.animation&&(Wa([te,ce],O),ps([te,ce],\"hidden\"))}we(),xe(),d.props.animation?R()&&vt(O,d.unmount):d.unmount()}}function Zl(v){q().addEventListener(\"mousemove\",g),ls(Kn,g),g(v)}function Yl(){d.state.isVisible&&d.hide(),d.state.isMounted&&(Pn(),qe().forEach(function(v){v._tippy.unmount()}),k.parentNode&&k.parentNode.removeChild(k),Za=Za.filter(function(v){return v!==d}),d.state.isMounted=!1,K(\"onHidden\",[d]))}function Xl(){d.state.isDestroyed||(d.clearDelayTimeouts(),d.unmount(),On(),delete e._tippy,d.state.isDestroyed=!0,K(\"onDestroy\",[d]))}}function Sn(e,t){t===void 0&&(t={});var n=_e.plugins.concat(t.plugins||[]);Rm();var a=Object.assign({},t,{plugins:n}),r=$m(e),i=r.reduce(function(s,o){var c=o&&Bm(o,a);return c&&s.push(c),s},[]);return Oa(e)?i[0]:i}Sn.defaultProps=_e;Sn.setDefaultProps=Dm;Sn.currentInput=Fe;Object.assign({},xc,{effect:function(t){var n=t.state,a={popper:{position:n.options.strategy,left:\"0\",top:\"0\",margin:\"0\"},arrow:{position:\"absolute\"},reference:{}};Object.assign(n.elements.popper.style,a.popper),n.styles=a,n.elements.arrow&&Object.assign(n.elements.arrow.style,a.arrow)}});Sn.setDefaultProps({render:Pc});let Y=class extends Error{constructor(t){super(t),this.name=\"ShikiError\"}};function Um(e){return ki(e)}function ki(e){return Array.isArray(e)?Gm(e):e instanceof RegExp?e:typeof e==\"object\"?Hm(e):e}function Gm(e){let t=[];for(let n=0,a=e.length;n<a;n++)t[n]=ki(e[n]);return t}function Hm(e){let t={};for(let n in e)t[n]=ki(e[n]);return t}function Dc(e,...t){return t.forEach(n=>{for(let a in n)e[a]=n[a]}),e}function Mc(e){const t=~e.lastIndexOf(\"/\")||~e.lastIndexOf(\"\\\\\");return t===0?e:~t===e.length-1?Mc(e.substring(0,e.length-1)):e.substr(~t+1)}var Ya=/\\$(\\d+)|\\${(\\d+):\\/(downcase|upcase)}/g,Qn=class{static hasCaptures(e){return e===null?!1:(Ya.lastIndex=0,Ya.test(e))}static replaceCaptures(e,t,n){return e.replace(Ya,(a,r,i,s)=>{let o=n[parseInt(r||i,10)];if(o){let c=t.substring(o.start,o.end);for(;c[0]===\".\";)c=c.substring(1);switch(s){case\"downcase\":return c.toLowerCase();case\"upcase\":return c.toUpperCase();default:return c}}else return a})}};function qc(e,t){return e<t?-1:e>t?1:0}function zc(e,t){if(e===null&&t===null)return 0;if(!e)return-1;if(!t)return 1;let n=e.length,a=t.length;if(n===a){for(let r=0;r<n;r++){let i=qc(e[r],t[r]);if(i!==0)return i}return 0}return n-a}function bs(e){return!!(/^#[0-9a-f]{6}$/i.test(e)||/^#[0-9a-f]{8}$/i.test(e)||/^#[0-9a-f]{3}$/i.test(e)||/^#[0-9a-f]{4}$/i.test(e))}function Bc(e){return e.replace(/[\\-\\\\\\{\\}\\*\\+\\?\\|\\^\\$\\.\\,\\[\\]\\(\\)\\#\\s]/g,\"\\\\$&\")}var Uc=class{constructor(e){this.fn=e}cache=new Map;get(e){if(this.cache.has(e))return this.cache.get(e);const t=this.fn(e);return this.cache.set(e,t),t}},ha=class{constructor(e,t,n){this._colorMap=e,this._defaults=t,this._root=n}static createFromRawTheme(e,t){return this.createFromParsedTheme(Zm(e),t)}static createFromParsedTheme(e,t){return Xm(e,t)}_cachedMatchRoot=new Uc(e=>this._root.match(e));getColorMap(){return this._colorMap.getColorMap()}getDefaults(){return this._defaults}match(e){if(e===null)return this._defaults;const t=e.scopeName,a=this._cachedMatchRoot.get(t).find(r=>Wm(e.parent,r.parentScopes));return a?new Gc(a.fontStyle,a.foreground,a.background):null}},Xa=class sa{constructor(t,n){this.parent=t,this.scopeName=n}static push(t,n){for(const a of n)t=new sa(t,a);return t}static from(...t){let n=null;for(let a=0;a<t.length;a++)n=new sa(n,t[a]);return n}push(t){return new sa(this,t)}getSegments(){let t=this;const n=[];for(;t;)n.push(t.scopeName),t=t.parent;return n.reverse(),n}toString(){return this.getSegments().join(\" \")}extends(t){return this===t?!0:this.parent===null?!1:this.parent.extends(t)}getExtensionIfDefined(t){const n=[];let a=this;for(;a&&a!==t;)n.push(a.scopeName),a=a.parent;return a===t?n.reverse():void 0}};function Wm(e,t){if(t.length===0)return!0;for(let n=0;n<t.length;n++){let a=t[n],r=!1;if(a===\">\"){if(n===t.length-1)return!1;a=t[++n],r=!0}for(;e&&!Vm(e.scopeName,a);){if(r)return!1;e=e.parent}if(!e)return!1;e=e.parent}return!0}function Vm(e,t){return t===e||e.startsWith(t)&&e[t.length]===\".\"}var Gc=class{constructor(e,t,n){this.fontStyle=e,this.foregroundId=t,this.backgroundId=n}};function Zm(e){if(!e)return[];if(!e.settings||!Array.isArray(e.settings))return[];let t=e.settings,n=[],a=0;for(let r=0,i=t.length;r<i;r++){let s=t[r];if(!s.settings)continue;let o;if(typeof s.scope==\"string\"){let p=s.scope;p=p.replace(/^[,]+/,\"\"),p=p.replace(/[,]+$/,\"\"),o=p.split(\",\")}else Array.isArray(s.scope)?o=s.scope:o=[\"\"];let c=-1;if(typeof s.settings.fontStyle==\"string\"){c=0;let p=s.settings.fontStyle.split(\" \");for(let m=0,h=p.length;m<h;m++)switch(p[m]){case\"italic\":c=c|1;break;case\"bold\":c=c|2;break;case\"underline\":c=c|4;break;case\"strikethrough\":c=c|8;break}}let l=null;typeof s.settings.foreground==\"string\"&&bs(s.settings.foreground)&&(l=s.settings.foreground);let u=null;typeof s.settings.background==\"string\"&&bs(s.settings.background)&&(u=s.settings.background);for(let p=0,m=o.length;p<m;p++){let g=o[p].trim().split(\" \"),_=g[g.length-1],f=null;g.length>1&&(f=g.slice(0,g.length-1),f.reverse()),n[a++]=new Ym(_,f,r,c,l,u)}}return n}var Ym=class{constructor(e,t,n,a,r,i){this.scope=e,this.parentScopes=t,this.index=n,this.fontStyle=a,this.foreground=r,this.background=i}},ee=(e=>(e[e.NotSet=-1]=\"NotSet\",e[e.None=0]=\"None\",e[e.Italic=1]=\"Italic\",e[e.Bold=2]=\"Bold\",e[e.Underline=4]=\"Underline\",e[e.Strikethrough=8]=\"Strikethrough\",e))(ee||{});function Xm(e,t){e.sort((c,l)=>{let u=qc(c.scope,l.scope);return u!==0||(u=zc(c.parentScopes,l.parentScopes),u!==0)?u:c.index-l.index});let n=0,a=\"#000000\",r=\"#ffffff\";for(;e.length>=1&&e[0].scope===\"\";){let c=e.shift();c.fontStyle!==-1&&(n=c.fontStyle),c.foreground!==null&&(a=c.foreground),c.background!==null&&(r=c.background)}let i=new Km(t),s=new Gc(n,i.getId(a),i.getId(r)),o=new Jm(new jr(0,null,-1,0,0),[]);for(let c=0,l=e.length;c<l;c++){let u=e[c];o.insert(0,u.scope,u.parentScopes,u.fontStyle,i.getId(u.foreground),i.getId(u.background))}return new ha(i,s,o)}var Km=class{_isFrozen;_lastColorId;_id2color;_color2id;constructor(e){if(this._lastColorId=0,this._id2color=[],this._color2id=Object.create(null),Array.isArray(e)){this._isFrozen=!0;for(let t=0,n=e.length;t<n;t++)this._color2id[e[t]]=t,this._id2color[t]=e[t]}else this._isFrozen=!1}getId(e){if(e===null)return 0;e=e.toUpperCase();let t=this._color2id[e];if(t)return t;if(this._isFrozen)throw new Error(`Missing color in color map - ${e}`);return t=++this._lastColorId,this._color2id[e]=t,this._id2color[t]=e,t}getColorMap(){return this._id2color.slice(0)}},Qm=Object.freeze([]),jr=class Hc{scopeDepth;parentScopes;fontStyle;foreground;background;constructor(t,n,a,r,i){this.scopeDepth=t,this.parentScopes=n||Qm,this.fontStyle=a,this.foreground=r,this.background=i}clone(){return new Hc(this.scopeDepth,this.parentScopes,this.fontStyle,this.foreground,this.background)}static cloneArr(t){let n=[];for(let a=0,r=t.length;a<r;a++)n[a]=t[a].clone();return n}acceptOverwrite(t,n,a,r){this.scopeDepth>t?console.log(\"how did this happen?\"):this.scopeDepth=t,n!==-1&&(this.fontStyle=n),a!==0&&(this.foreground=a),r!==0&&(this.background=r)}},Jm=class Sr{constructor(t,n=[],a={}){this._mainRule=t,this._children=a,this._rulesWithParentScopes=n}_rulesWithParentScopes;static _cmpBySpecificity(t,n){if(t.scopeDepth!==n.scopeDepth)return n.scopeDepth-t.scopeDepth;let a=0,r=0;for(;t.parentScopes[a]===\">\"&&a++,n.parentScopes[r]===\">\"&&r++,!(a>=t.parentScopes.length||r>=n.parentScopes.length);){const i=n.parentScopes[r].length-t.parentScopes[a].length;if(i!==0)return i;a++,r++}return n.parentScopes.length-t.parentScopes.length}match(t){if(t!==\"\"){let a=t.indexOf(\".\"),r,i;if(a===-1?(r=t,i=\"\"):(r=t.substring(0,a),i=t.substring(a+1)),this._children.hasOwnProperty(r))return this._children[r].match(i)}const n=this._rulesWithParentScopes.concat(this._mainRule);return n.sort(Sr._cmpBySpecificity),n}insert(t,n,a,r,i,s){if(n===\"\"){this._doInsertHere(t,a,r,i,s);return}let o=n.indexOf(\".\"),c,l;o===-1?(c=n,l=\"\"):(c=n.substring(0,o),l=n.substring(o+1));let u;this._children.hasOwnProperty(c)?u=this._children[c]:(u=new Sr(this._mainRule.clone(),jr.cloneArr(this._rulesWithParentScopes)),this._children[c]=u),u.insert(t+1,l,a,r,i,s)}_doInsertHere(t,n,a,r,i){if(n===null){this._mainRule.acceptOverwrite(t,a,r,i);return}for(let s=0,o=this._rulesWithParentScopes.length;s<o;s++){let c=this._rulesWithParentScopes[s];if(zc(c.parentScopes,n)===0){c.acceptOverwrite(t,a,r,i);return}}a===-1&&(a=this._mainRule.fontStyle),r===0&&(r=this._mainRule.foreground),i===0&&(i=this._mainRule.background),this._rulesWithParentScopes.push(new jr(t,n,a,r,i))}},qt=class le{static toBinaryStr(t){return t.toString(2).padStart(32,\"0\")}static print(t){const n=le.getLanguageId(t),a=le.getTokenType(t),r=le.getFontStyle(t),i=le.getForeground(t),s=le.getBackground(t);console.log({languageId:n,tokenType:a,fontStyle:r,foreground:i,background:s})}static getLanguageId(t){return(t&255)>>>0}static getTokenType(t){return(t&768)>>>8}static containsBalancedBrackets(t){return(t&1024)!==0}static getFontStyle(t){return(t&30720)>>>11}static getForeground(t){return(t&16744448)>>>15}static getBackground(t){return(t&4278190080)>>>24}static set(t,n,a,r,i,s,o){let c=le.getLanguageId(t),l=le.getTokenType(t),u=le.containsBalancedBrackets(t)?1:0,p=le.getFontStyle(t),m=le.getForeground(t),h=le.getBackground(t);return n!==0&&(c=n),a!==8&&(l=a),r!==null&&(u=r?1:0),i!==-1&&(p=i),s!==0&&(m=s),o!==0&&(h=o),(c<<0|l<<8|u<<10|p<<11|m<<15|h<<24)>>>0}};function ga(e,t){const n=[],a=eh(e);let r=a.next();for(;r!==null;){let c=0;if(r.length===2&&r.charAt(1)===\":\"){switch(r.charAt(0)){case\"R\":c=1;break;case\"L\":c=-1;break;default:console.log(`Unknown priority ${r} in scope selector`)}r=a.next()}let l=s();if(n.push({matcher:l,priority:c}),r!==\",\")break;r=a.next()}return n;function i(){if(r===\"-\"){r=a.next();const c=i();return l=>!!c&&!c(l)}if(r===\"(\"){r=a.next();const c=o();return r===\")\"&&(r=a.next()),c}if(_s(r)){const c=[];do c.push(r),r=a.next();while(_s(r));return l=>t(c,l)}return null}function s(){const c=[];let l=i();for(;l;)c.push(l),l=i();return u=>c.every(p=>p(u))}function o(){const c=[];let l=s();for(;l&&(c.push(l),r===\"|\"||r===\",\");){do r=a.next();while(r===\"|\"||r===\",\");l=s()}return u=>c.some(p=>p(u))}}function _s(e){return!!e&&!!e.match(/[\\w\\.:]+/)}function eh(e){let t=/([LR]:|[\\w\\.:][\\w\\.:\\-]*|[\\,\\|\\-\\(\\)])/g,n=t.exec(e);return{next:()=>{if(!n)return null;const a=n[0];return n=t.exec(e),a}}}function Wc(e){typeof e.dispose==\"function\"&&e.dispose()}var wn=class{constructor(e){this.scopeName=e}toKey(){return this.scopeName}},th=class{constructor(e,t){this.scopeName=e,this.ruleName=t}toKey(){return`${this.scopeName}#${this.ruleName}`}},nh=class{_references=[];_seenReferenceKeys=new Set;get references(){return this._references}visitedRule=new Set;add(e){const t=e.toKey();this._seenReferenceKeys.has(t)||(this._seenReferenceKeys.add(t),this._references.push(e))}},ah=class{constructor(e,t){this.repo=e,this.initialScopeName=t,this.seenFullScopeRequests.add(this.initialScopeName),this.Q=[new wn(this.initialScopeName)]}seenFullScopeRequests=new Set;seenPartialScopeRequests=new Set;Q;processQueue(){const e=this.Q;this.Q=[];const t=new nh;for(const n of e)rh(n,this.initialScopeName,this.repo,t);for(const n of t.references)if(n instanceof wn){if(this.seenFullScopeRequests.has(n.scopeName))continue;this.seenFullScopeRequests.add(n.scopeName),this.Q.push(n)}else{if(this.seenFullScopeRequests.has(n.scopeName)||this.seenPartialScopeRequests.has(n.toKey()))continue;this.seenPartialScopeRequests.add(n.toKey()),this.Q.push(n)}}};function rh(e,t,n,a){const r=n.lookup(e.scopeName);if(!r){if(e.scopeName===t)throw new Error(`No grammar provided for <${t}>`);return}const i=n.lookup(t);e instanceof wn?oa({baseGrammar:i,selfGrammar:r},a):Ar(e.ruleName,{baseGrammar:i,selfGrammar:r,repository:r.repository},a);const s=n.injections(e.scopeName);if(s)for(const o of s)a.add(new wn(o))}function Ar(e,t,n){if(t.repository&&t.repository[e]){const a=t.repository[e];fa([a],t,n)}}function oa(e,t){e.selfGrammar.patterns&&Array.isArray(e.selfGrammar.patterns)&&fa(e.selfGrammar.patterns,{...e,repository:e.selfGrammar.repository},t),e.selfGrammar.injections&&fa(Object.values(e.selfGrammar.injections),{...e,repository:e.selfGrammar.repository},t)}function fa(e,t,n){for(const a of e){if(n.visitedRule.has(a))continue;n.visitedRule.add(a);const r=a.repository?Dc({},t.repository,a.repository):t.repository;Array.isArray(a.patterns)&&fa(a.patterns,{...t,repository:r},n);const i=a.include;if(!i)continue;const s=Vc(i);switch(s.kind){case 0:oa({...t,selfGrammar:t.baseGrammar},n);break;case 1:oa(t,n);break;case 2:Ar(s.ruleName,{...t,repository:r},n);break;case 3:case 4:const o=s.scopeName===t.selfGrammar.scopeName?t.selfGrammar:s.scopeName===t.baseGrammar.scopeName?t.baseGrammar:void 0;if(o){const c={baseGrammar:t.baseGrammar,selfGrammar:o,repository:r};s.kind===4?Ar(s.ruleName,c,n):oa(c,n)}else s.kind===4?n.add(new th(s.scopeName,s.ruleName)):n.add(new wn(s.scopeName));break}}}var ih=class{kind=0},sh=class{kind=1},oh=class{constructor(e){this.ruleName=e}kind=2},ch=class{constructor(e){this.scopeName=e}kind=3},lh=class{constructor(e,t){this.scopeName=e,this.ruleName=t}kind=4};function Vc(e){if(e===\"$base\")return new ih;if(e===\"$self\")return new sh;const t=e.indexOf(\"#\");if(t===-1)return new ch(e);if(t===0)return new oh(e.substring(1));{const n=e.substring(0,t),a=e.substring(t+1);return new lh(n,a)}}var uh=/\\\\(\\d+)/,ys=/\\\\(\\d+)/g,ph=-1,Zc=-2;var An=class{$location;id;_nameIsCapturing;_name;_contentNameIsCapturing;_contentName;constructor(e,t,n,a){this.$location=e,this.id=t,this._name=n||null,this._nameIsCapturing=Qn.hasCaptures(this._name),this._contentName=a||null,this._contentNameIsCapturing=Qn.hasCaptures(this._contentName)}get debugName(){const e=this.$location?`${Mc(this.$location.filename)}:${this.$location.line}`:\"unknown\";return`${this.constructor.name}#${this.id} @ ${e}`}getName(e,t){return!this._nameIsCapturing||this._name===null||e===null||t===null?this._name:Qn.replaceCaptures(this._name,e,t)}getContentName(e,t){return!this._contentNameIsCapturing||this._contentName===null?this._contentName:Qn.replaceCaptures(this._contentName,e,t)}},dh=class extends An{retokenizeCapturedWithRuleId;constructor(e,t,n,a,r){super(e,t,n,a),this.retokenizeCapturedWithRuleId=r}dispose(){}collectPatterns(e,t){throw new Error(\"Not supported!\")}compile(e,t){throw new Error(\"Not supported!\")}compileAG(e,t,n,a){throw new Error(\"Not supported!\")}},mh=class extends An{_match;captures;_cachedCompiledPatterns;constructor(e,t,n,a,r){super(e,t,n,null),this._match=new xn(a,this.id),this.captures=r,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugMatchRegExp(){return`${this._match.source}`}collectPatterns(e,t){t.push(this._match)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,a){return this._getCachedCompiledPatterns(e).compileAG(e,n,a)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new kn,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},vs=class extends An{hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,a,r){super(e,t,n,a),this.patterns=r.patterns,this.hasMissingPatterns=r.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}collectPatterns(e,t){for(const n of this.patterns)e.getRule(n).collectPatterns(e,t)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,a){return this._getCachedCompiledPatterns(e).compileAG(e,n,a)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new kn,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},Tr=class extends An{_begin;beginCaptures;_end;endHasBackReferences;endCaptures;applyEndPatternLast;hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,a,r,i,s,o,c,l){super(e,t,n,a),this._begin=new xn(r,this.id),this.beginCaptures=i,this._end=new xn(s||\"￿\",-1),this.endHasBackReferences=this._end.hasBackReferences,this.endCaptures=o,this.applyEndPatternLast=c||!1,this.patterns=l.patterns,this.hasMissingPatterns=l.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugEndRegExp(){return`${this._end.source}`}getEndWithResolvedBackReferences(e,t){return this._end.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e,t).compile(e)}compileAG(e,t,n,a){return this._getCachedCompiledPatterns(e,t).compileAG(e,n,a)}_getCachedCompiledPatterns(e,t){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new kn;for(const n of this.patterns)e.getRule(n).collectPatterns(e,this._cachedCompiledPatterns);this.applyEndPatternLast?this._cachedCompiledPatterns.push(this._end.hasBackReferences?this._end.clone():this._end):this._cachedCompiledPatterns.unshift(this._end.hasBackReferences?this._end.clone():this._end)}return this._end.hasBackReferences&&(this.applyEndPatternLast?this._cachedCompiledPatterns.setSource(this._cachedCompiledPatterns.length()-1,t):this._cachedCompiledPatterns.setSource(0,t)),this._cachedCompiledPatterns}},ba=class extends An{_begin;beginCaptures;whileCaptures;_while;whileHasBackReferences;hasMissingPatterns;patterns;_cachedCompiledPatterns;_cachedCompiledWhilePatterns;constructor(e,t,n,a,r,i,s,o,c){super(e,t,n,a),this._begin=new xn(r,this.id),this.beginCaptures=i,this.whileCaptures=o,this._while=new xn(s,Zc),this.whileHasBackReferences=this._while.hasBackReferences,this.patterns=c.patterns,this.hasMissingPatterns=c.hasMissingPatterns,this._cachedCompiledPatterns=null,this._cachedCompiledWhilePatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null),this._cachedCompiledWhilePatterns&&(this._cachedCompiledWhilePatterns.dispose(),this._cachedCompiledWhilePatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugWhileRegExp(){return`${this._while.source}`}getWhileWithResolvedBackReferences(e,t){return this._while.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,a){return this._getCachedCompiledPatterns(e).compileAG(e,n,a)}_getCachedCompiledPatterns(e){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new kn;for(const t of this.patterns)e.getRule(t).collectPatterns(e,this._cachedCompiledPatterns)}return this._cachedCompiledPatterns}compileWhile(e,t){return this._getCachedCompiledWhilePatterns(e,t).compile(e)}compileWhileAG(e,t,n,a){return this._getCachedCompiledWhilePatterns(e,t).compileAG(e,n,a)}_getCachedCompiledWhilePatterns(e,t){return this._cachedCompiledWhilePatterns||(this._cachedCompiledWhilePatterns=new kn,this._cachedCompiledWhilePatterns.push(this._while.hasBackReferences?this._while.clone():this._while)),this._while.hasBackReferences&&this._cachedCompiledWhilePatterns.setSource(0,t||\"￿\"),this._cachedCompiledWhilePatterns}},Yc=class J{static createCaptureRule(t,n,a,r,i){return t.registerRule(s=>new dh(n,s,a,r,i))}static getCompiledRuleId(t,n,a){return t.id||n.registerRule(r=>{if(t.id=r,t.match)return new mh(t.$vscodeTextmateLocation,t.id,t.name,t.match,J._compileCaptures(t.captures,n,a));if(typeof t.begin>\"u\"){t.repository&&(a=Dc({},a,t.repository));let i=t.patterns;return typeof i>\"u\"&&t.include&&(i=[{include:t.include}]),new vs(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,J._compilePatterns(i,n,a))}return t.while?new ba(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,J._compileCaptures(t.beginCaptures||t.captures,n,a),t.while,J._compileCaptures(t.whileCaptures||t.captures,n,a),J._compilePatterns(t.patterns,n,a)):new Tr(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,J._compileCaptures(t.beginCaptures||t.captures,n,a),t.end,J._compileCaptures(t.endCaptures||t.captures,n,a),t.applyEndPatternLast,J._compilePatterns(t.patterns,n,a))}),t.id}static _compileCaptures(t,n,a){let r=[];if(t){let i=0;for(const s in t){if(s===\"$vscodeTextmateLocation\")continue;const o=parseInt(s,10);o>i&&(i=o)}for(let s=0;s<=i;s++)r[s]=null;for(const s in t){if(s===\"$vscodeTextmateLocation\")continue;const o=parseInt(s,10);let c=0;t[s].patterns&&(c=J.getCompiledRuleId(t[s],n,a)),r[o]=J.createCaptureRule(n,t[s].$vscodeTextmateLocation,t[s].name,t[s].contentName,c)}}return r}static _compilePatterns(t,n,a){let r=[];if(t)for(let i=0,s=t.length;i<s;i++){const o=t[i];let c=-1;if(o.include){const l=Vc(o.include);switch(l.kind){case 0:case 1:c=J.getCompiledRuleId(a[o.include],n,a);break;case 2:let u=a[l.ruleName];u&&(c=J.getCompiledRuleId(u,n,a));break;case 3:case 4:const p=l.scopeName,m=l.kind===4?l.ruleName:null,h=n.getExternalGrammar(p,a);if(h)if(m){let g=h.repository[m];g&&(c=J.getCompiledRuleId(g,n,h.repository))}else c=J.getCompiledRuleId(h.repository.$self,n,h.repository);break}}else c=J.getCompiledRuleId(o,n,a);if(c!==-1){const l=n.getRule(c);let u=!1;if((l instanceof vs||l instanceof Tr||l instanceof ba)&&l.hasMissingPatterns&&l.patterns.length===0&&(u=!0),u)continue;r.push(c)}}return{patterns:r,hasMissingPatterns:(t?t.length:0)!==r.length}}},xn=class Xc{source;ruleId;hasAnchor;hasBackReferences;_anchorCache;constructor(t,n){if(t&&typeof t==\"string\"){const a=t.length;let r=0,i=[],s=!1;for(let o=0;o<a;o++)if(t.charAt(o)===\"\\\\\"&&o+1<a){const l=t.charAt(o+1);l===\"z\"?(i.push(t.substring(r,o)),i.push(\"$(?!\\\\n)(?<!\\\\n)\"),r=o+2):(l===\"A\"||l===\"G\")&&(s=!0),o++}this.hasAnchor=s,r===0?this.source=t:(i.push(t.substring(r,a)),this.source=i.join(\"\"))}else this.hasAnchor=!1,this.source=t;this.hasAnchor?this._anchorCache=this._buildAnchorCache():this._anchorCache=null,this.ruleId=n,typeof this.source==\"string\"?this.hasBackReferences=uh.test(this.source):this.hasBackReferences=!1}clone(){return new Xc(this.source,this.ruleId)}setSource(t){this.source!==t&&(this.source=t,this.hasAnchor&&(this._anchorCache=this._buildAnchorCache()))}resolveBackReferences(t,n){if(typeof this.source!=\"string\")throw new Error(\"This method should only be called if the source is a string\");let a=n.map(r=>t.substring(r.start,r.end));return ys.lastIndex=0,this.source.replace(ys,(r,i)=>Bc(a[parseInt(i,10)]||\"\"))}_buildAnchorCache(){if(typeof this.source!=\"string\")throw new Error(\"This method should only be called if the source is a string\");let t=[],n=[],a=[],r=[],i,s,o,c;for(i=0,s=this.source.length;i<s;i++)o=this.source.charAt(i),t[i]=o,n[i]=o,a[i]=o,r[i]=o,o===\"\\\\\"&&i+1<s&&(c=this.source.charAt(i+1),c===\"A\"?(t[i+1]=\"￿\",n[i+1]=\"￿\",a[i+1]=\"A\",r[i+1]=\"A\"):c===\"G\"?(t[i+1]=\"￿\",n[i+1]=\"G\",a[i+1]=\"￿\",r[i+1]=\"G\"):(t[i+1]=c,n[i+1]=c,a[i+1]=c,r[i+1]=c),i++);return{A0_G0:t.join(\"\"),A0_G1:n.join(\"\"),A1_G0:a.join(\"\"),A1_G1:r.join(\"\")}}resolveAnchors(t,n){return!this.hasAnchor||!this._anchorCache||typeof this.source!=\"string\"?this.source:t?n?this._anchorCache.A1_G1:this._anchorCache.A1_G0:n?this._anchorCache.A0_G1:this._anchorCache.A0_G0}},kn=class{_items;_hasAnchors;_cached;_anchorCache;constructor(){this._items=[],this._hasAnchors=!1,this._cached=null,this._anchorCache={A0_G0:null,A0_G1:null,A1_G0:null,A1_G1:null}}dispose(){this._disposeCaches()}_disposeCaches(){this._cached&&(this._cached.dispose(),this._cached=null),this._anchorCache.A0_G0&&(this._anchorCache.A0_G0.dispose(),this._anchorCache.A0_G0=null),this._anchorCache.A0_G1&&(this._anchorCache.A0_G1.dispose(),this._anchorCache.A0_G1=null),this._anchorCache.A1_G0&&(this._anchorCache.A1_G0.dispose(),this._anchorCache.A1_G0=null),this._anchorCache.A1_G1&&(this._anchorCache.A1_G1.dispose(),this._anchorCache.A1_G1=null)}push(e){this._items.push(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}unshift(e){this._items.unshift(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}length(){return this._items.length}setSource(e,t){this._items[e].source!==t&&(this._disposeCaches(),this._items[e].setSource(t))}compile(e){if(!this._cached){let t=this._items.map(n=>n.source);this._cached=new ws(e,t,this._items.map(n=>n.ruleId))}return this._cached}compileAG(e,t,n){return this._hasAnchors?t?n?(this._anchorCache.A1_G1||(this._anchorCache.A1_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G1):(this._anchorCache.A1_G0||(this._anchorCache.A1_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G0):n?(this._anchorCache.A0_G1||(this._anchorCache.A0_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G1):(this._anchorCache.A0_G0||(this._anchorCache.A0_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G0):this.compile(e)}_resolveAnchors(e,t,n){let a=this._items.map(r=>r.resolveAnchors(t,n));return new ws(e,a,this._items.map(r=>r.ruleId))}},ws=class{constructor(e,t,n){this.regExps=t,this.rules=n,this.scanner=e.createOnigScanner(t)}scanner;dispose(){typeof this.scanner.dispose==\"function\"&&this.scanner.dispose()}toString(){const e=[];for(let t=0,n=this.rules.length;t<n;t++)e.push(\"   - \"+this.rules[t]+\": \"+this.regExps[t]);return e.join(`\n`)}findNextMatchSync(e,t,n){const a=this.scanner.findNextMatchSync(e,t,n);return a?{ruleId:this.rules[a.index],captureIndices:a.captureIndices}:null}},Ka=class{constructor(e,t){this.languageId=e,this.tokenType=t}},hh=class Rr{_defaultAttributes;_embeddedLanguagesMatcher;constructor(t,n){this._defaultAttributes=new Ka(t,8),this._embeddedLanguagesMatcher=new gh(Object.entries(n||{}))}getDefaultAttributes(){return this._defaultAttributes}getBasicScopeAttributes(t){return t===null?Rr._NULL_SCOPE_METADATA:this._getBasicScopeAttributes.get(t)}static _NULL_SCOPE_METADATA=new Ka(0,0);_getBasicScopeAttributes=new Uc(t=>{const n=this._scopeToLanguage(t),a=this._toStandardTokenType(t);return new Ka(n,a)});_scopeToLanguage(t){return this._embeddedLanguagesMatcher.match(t)||0}_toStandardTokenType(t){const n=t.match(Rr.STANDARD_TOKEN_TYPE_REGEXP);if(!n)return 8;switch(n[1]){case\"comment\":return 1;case\"string\":return 2;case\"regex\":return 3;case\"meta.embedded\":return 0}throw new Error(\"Unexpected match for standard token type!\")}static STANDARD_TOKEN_TYPE_REGEXP=/\\b(comment|string|regex|meta\\.embedded)\\b/},gh=class{values;scopesRegExp;constructor(e){if(e.length===0)this.values=null,this.scopesRegExp=null;else{this.values=new Map(e);const t=e.map(([n,a])=>Bc(n));t.sort(),t.reverse(),this.scopesRegExp=new RegExp(`^((${t.join(\")|(\")}))($|\\\\.)`,\"\")}}match(e){if(!this.scopesRegExp)return;const t=e.match(this.scopesRegExp);if(t)return this.values.get(t[1])}},xs=class{constructor(e,t){this.stack=e,this.stoppedEarly=t}};function Kc(e,t,n,a,r,i,s,o){const c=t.content.length;let l=!1,u=-1;if(s){const h=fh(e,t,n,a,r,i);r=h.stack,a=h.linePos,n=h.isFirstLine,u=h.anchorPosition}const p=Date.now();for(;!l;){if(o!==0&&Date.now()-p>o)return new xs(r,!0);m()}return new xs(r,!1);function m(){const h=bh(e,t,n,a,r,u);if(!h){i.produce(r,c),l=!0;return}const g=h.captureIndices,_=h.matchedRuleId,f=g&&g.length>0?g[0].end>a:!1;if(_===ph){const b=r.getRule(e);i.produce(r,g[0].start),r=r.withContentNameScopesList(r.nameScopesList),cn(e,t,n,r,i,b.endCaptures,g),i.produce(r,g[0].end);const w=r;if(r=r.parent,u=w.getAnchorPos(),!f&&w.getEnterPos()===a){r=w,i.produce(r,c),l=!0;return}}else{const b=e.getRule(_);i.produce(r,g[0].start);const w=r,y=b.getName(t.content,g),d=r.contentNameScopesList.pushAttributed(y,e);if(r=r.push(_,a,u,g[0].end===c,null,d,d),b instanceof Tr){const C=b;cn(e,t,n,r,i,C.beginCaptures,g),i.produce(r,g[0].end),u=g[0].end;const k=C.getContentName(t.content,g),$=d.pushAttributed(k,e);if(r=r.withContentNameScopesList($),C.endHasBackReferences&&(r=r.withEndRule(C.getEndWithResolvedBackReferences(t.content,g))),!f&&w.hasSameRuleAs(r)){r=r.pop(),i.produce(r,c),l=!0;return}}else if(b instanceof ba){const C=b;cn(e,t,n,r,i,C.beginCaptures,g),i.produce(r,g[0].end),u=g[0].end;const k=C.getContentName(t.content,g),$=d.pushAttributed(k,e);if(r=r.withContentNameScopesList($),C.whileHasBackReferences&&(r=r.withEndRule(C.getWhileWithResolvedBackReferences(t.content,g))),!f&&w.hasSameRuleAs(r)){r=r.pop(),i.produce(r,c),l=!0;return}}else if(cn(e,t,n,r,i,b.captures,g),i.produce(r,g[0].end),r=r.pop(),!f){r=r.safePop(),i.produce(r,c),l=!0;return}}g[0].end>a&&(a=g[0].end,n=!1)}}function fh(e,t,n,a,r,i){let s=r.beginRuleCapturedEOL?0:-1;const o=[];for(let c=r;c;c=c.pop()){const l=c.getRule(e);l instanceof ba&&o.push({rule:l,stack:c})}for(let c=o.pop();c;c=o.pop()){const{ruleScanner:l,findOptions:u}=vh(c.rule,e,c.stack.endRule,n,a===s),p=l.findNextMatchSync(t,a,u);if(p){if(p.ruleId!==Zc){r=c.stack.pop();break}p.captureIndices&&p.captureIndices.length&&(i.produce(c.stack,p.captureIndices[0].start),cn(e,t,n,c.stack,i,c.rule.whileCaptures,p.captureIndices),i.produce(c.stack,p.captureIndices[0].end),s=p.captureIndices[0].end,p.captureIndices[0].end>a&&(a=p.captureIndices[0].end,n=!1))}else{r=c.stack.pop();break}}return{stack:r,linePos:a,anchorPosition:s,isFirstLine:n}}function bh(e,t,n,a,r,i){const s=_h(e,t,n,a,r,i),o=e.getInjections();if(o.length===0)return s;const c=yh(o,e,t,n,a,r,i);if(!c)return s;if(!s)return c;const l=s.captureIndices[0].start,u=c.captureIndices[0].start;return u<l||c.priorityMatch&&u===l?c:s}function _h(e,t,n,a,r,i){const s=r.getRule(e),{ruleScanner:o,findOptions:c}=Qc(s,e,r.endRule,n,a===i),l=o.findNextMatchSync(t,a,c);return l?{captureIndices:l.captureIndices,matchedRuleId:l.ruleId}:null}function yh(e,t,n,a,r,i,s){let o=Number.MAX_VALUE,c=null,l,u=0;const p=i.contentNameScopesList.getScopeNames();for(let m=0,h=e.length;m<h;m++){const g=e[m];if(!g.matcher(p))continue;const _=t.getRule(g.ruleId),{ruleScanner:f,findOptions:b}=Qc(_,t,null,a,r===s),w=f.findNextMatchSync(n,r,b);if(!w)continue;const y=w.captureIndices[0].start;if(!(y>=o)&&(o=y,c=w.captureIndices,l=w.ruleId,u=g.priority,o===r))break}return c?{priorityMatch:u===-1,captureIndices:c,matchedRuleId:l}:null}function Qc(e,t,n,a,r){return{ruleScanner:e.compileAG(t,n,a,r),findOptions:0}}function vh(e,t,n,a,r){return{ruleScanner:e.compileWhileAG(t,n,a,r),findOptions:0}}function cn(e,t,n,a,r,i,s){if(i.length===0)return;const o=t.content,c=Math.min(i.length,s.length),l=[],u=s[0].end;for(let p=0;p<c;p++){const m=i[p];if(m===null)continue;const h=s[p];if(h.length===0)continue;if(h.start>u)break;for(;l.length>0&&l[l.length-1].endPos<=h.start;)r.produceFromScopes(l[l.length-1].scopes,l[l.length-1].endPos),l.pop();if(l.length>0?r.produceFromScopes(l[l.length-1].scopes,h.start):r.produce(a,h.start),m.retokenizeCapturedWithRuleId){const _=m.getName(o,s),f=a.contentNameScopesList.pushAttributed(_,e),b=m.getContentName(o,s),w=f.pushAttributed(b,e),y=a.push(m.retokenizeCapturedWithRuleId,h.start,-1,!1,null,f,w),d=e.createOnigString(o.substring(0,h.end));Kc(e,d,n&&h.start===0,h.start,y,r,!1,0),Wc(d);continue}const g=m.getName(o,s);if(g!==null){const f=(l.length>0?l[l.length-1].scopes:a.contentNameScopesList).pushAttributed(g,e);l.push(new wh(f,h.end))}}for(;l.length>0;)r.produceFromScopes(l[l.length-1].scopes,l[l.length-1].endPos),l.pop()}var wh=class{scopes;endPos;constructor(e,t){this.scopes=e,this.endPos=t}};function xh(e,t,n,a,r,i,s,o){return new Ch(e,t,n,a,r,i,s,o)}function ks(e,t,n,a,r){const i=ga(t,_a),s=Yc.getCompiledRuleId(n,a,r.repository);for(const o of i)e.push({debugSelector:t,matcher:o.matcher,ruleId:s,grammar:r,priority:o.priority})}function _a(e,t){if(t.length<e.length)return!1;let n=0;return e.every(a=>{for(let r=n;r<t.length;r++)if(kh(t[r],a))return n=r+1,!0;return!1})}function kh(e,t){if(!e)return!1;if(e===t)return!0;const n=t.length;return e.length>n&&e.substr(0,n)===t&&e[n]===\".\"}var Ch=class{constructor(e,t,n,a,r,i,s,o){if(this._rootScopeName=e,this.balancedBracketSelectors=i,this._onigLib=o,this._basicScopeAttributesProvider=new hh(n,a),this._rootId=-1,this._lastRuleId=0,this._ruleId2desc=[null],this._includedGrammars={},this._grammarRepository=s,this._grammar=Cs(t,null),this._injections=null,this._tokenTypeMatchers=[],r)for(const c of Object.keys(r)){const l=ga(c,_a);for(const u of l)this._tokenTypeMatchers.push({matcher:u.matcher,type:r[c]})}}_rootId;_lastRuleId;_ruleId2desc;_includedGrammars;_grammarRepository;_grammar;_injections;_basicScopeAttributesProvider;_tokenTypeMatchers;get themeProvider(){return this._grammarRepository}dispose(){for(const e of this._ruleId2desc)e&&e.dispose()}createOnigScanner(e){return this._onigLib.createOnigScanner(e)}createOnigString(e){return this._onigLib.createOnigString(e)}getMetadataForScope(e){return this._basicScopeAttributesProvider.getBasicScopeAttributes(e)}_collectInjections(){const e={lookup:r=>r===this._rootScopeName?this._grammar:this.getExternalGrammar(r),injections:r=>this._grammarRepository.injections(r)},t=[],n=this._rootScopeName,a=e.lookup(n);if(a){const r=a.injections;if(r)for(let s in r)ks(t,s,r[s],this,a);const i=this._grammarRepository.injections(n);i&&i.forEach(s=>{const o=this.getExternalGrammar(s);if(o){const c=o.injectionSelector;c&&ks(t,c,o,this,o)}})}return t.sort((r,i)=>r.priority-i.priority),t}getInjections(){return this._injections===null&&(this._injections=this._collectInjections()),this._injections}registerRule(e){const t=++this._lastRuleId,n=e(t);return this._ruleId2desc[t]=n,n}getRule(e){return this._ruleId2desc[e]}getExternalGrammar(e,t){if(this._includedGrammars[e])return this._includedGrammars[e];if(this._grammarRepository){const n=this._grammarRepository.lookup(e);if(n)return this._includedGrammars[e]=Cs(n,t&&t.$base),this._includedGrammars[e]}}tokenizeLine(e,t,n=0){const a=this._tokenize(e,t,!1,n);return{tokens:a.lineTokens.getResult(a.ruleStack,a.lineLength),ruleStack:a.ruleStack,stoppedEarly:a.stoppedEarly}}tokenizeLine2(e,t,n=0){const a=this._tokenize(e,t,!0,n);return{tokens:a.lineTokens.getBinaryResult(a.ruleStack,a.lineLength),ruleStack:a.ruleStack,stoppedEarly:a.stoppedEarly}}_tokenize(e,t,n,a){this._rootId===-1&&(this._rootId=Yc.getCompiledRuleId(this._grammar.repository.$self,this,this._grammar.repository),this.getInjections());let r;if(!t||t===Or.NULL){r=!0;const l=this._basicScopeAttributesProvider.getDefaultAttributes(),u=this.themeProvider.getDefaults(),p=qt.set(0,l.languageId,l.tokenType,null,u.fontStyle,u.foregroundId,u.backgroundId),m=this.getRule(this._rootId).getName(null,null);let h;m?h=hn.createRootAndLookUpScopeName(m,p,this):h=hn.createRoot(\"unknown\",p),t=new Or(null,this._rootId,-1,-1,!1,null,h,h)}else r=!1,t.reset();e=e+`\n`;const i=this.createOnigString(e),s=i.content.length,o=new Fh(n,e,this._tokenTypeMatchers,this.balancedBracketSelectors),c=Kc(this,i,r,0,t,o,!0,a);return Wc(i),{lineLength:s,lineTokens:o,ruleStack:c.stack,stoppedEarly:c.stoppedEarly}}};function Cs(e,t){return e=Um(e),e.repository=e.repository||{},e.repository.$self={$vscodeTextmateLocation:e.$vscodeTextmateLocation,patterns:e.patterns,name:e.scopeName},e.repository.$base=t||e.repository.$self,e}var hn=class Ce{constructor(t,n,a){this.parent=t,this.scopePath=n,this.tokenAttributes=a}static fromExtension(t,n){let a=t,r=t?.scopePath??null;for(const i of n)r=Xa.push(r,i.scopeNames),a=new Ce(a,r,i.encodedTokenAttributes);return a}static createRoot(t,n){return new Ce(null,new Xa(null,t),n)}static createRootAndLookUpScopeName(t,n,a){const r=a.getMetadataForScope(t),i=new Xa(null,t),s=a.themeProvider.themeMatch(i),o=Ce.mergeAttributes(n,r,s);return new Ce(null,i,o)}get scopeName(){return this.scopePath.scopeName}toString(){return this.getScopeNames().join(\" \")}equals(t){return Ce.equals(this,t)}static equals(t,n){do{if(t===n||!t&&!n)return!0;if(!t||!n||t.scopeName!==n.scopeName||t.tokenAttributes!==n.tokenAttributes)return!1;t=t.parent,n=n.parent}while(!0)}static mergeAttributes(t,n,a){let r=-1,i=0,s=0;return a!==null&&(r=a.fontStyle,i=a.foregroundId,s=a.backgroundId),qt.set(t,n.languageId,n.tokenType,null,r,i,s)}pushAttributed(t,n){if(t===null)return this;if(t.indexOf(\" \")===-1)return Ce._pushAttributed(this,t,n);const a=t.split(/ /g);let r=this;for(const i of a)r=Ce._pushAttributed(r,i,n);return r}static _pushAttributed(t,n,a){const r=a.getMetadataForScope(n),i=t.scopePath.push(n),s=a.themeProvider.themeMatch(i),o=Ce.mergeAttributes(t.tokenAttributes,r,s);return new Ce(t,i,o)}getScopeNames(){return this.scopePath.getSegments()}getExtensionIfDefined(t){const n=[];let a=this;for(;a&&a!==t;)n.push({encodedTokenAttributes:a.tokenAttributes,scopeNames:a.scopePath.getExtensionIfDefined(a.parent?.scopePath??null)}),a=a.parent;return a===t?n.reverse():void 0}},Or=class nt{constructor(t,n,a,r,i,s,o,c){this.parent=t,this.ruleId=n,this.beginRuleCapturedEOL=i,this.endRule=s,this.nameScopesList=o,this.contentNameScopesList=c,this.depth=this.parent?this.parent.depth+1:1,this._enterPos=a,this._anchorPos=r}_stackElementBrand=void 0;static NULL=new nt(null,0,0,0,!1,null,null,null);_enterPos;_anchorPos;depth;equals(t){return t===null?!1:nt._equals(this,t)}static _equals(t,n){return t===n?!0:this._structuralEquals(t,n)?hn.equals(t.contentNameScopesList,n.contentNameScopesList):!1}static _structuralEquals(t,n){do{if(t===n||!t&&!n)return!0;if(!t||!n||t.depth!==n.depth||t.ruleId!==n.ruleId||t.endRule!==n.endRule)return!1;t=t.parent,n=n.parent}while(!0)}clone(){return this}static _reset(t){for(;t;)t._enterPos=-1,t._anchorPos=-1,t=t.parent}reset(){nt._reset(this)}pop(){return this.parent}safePop(){return this.parent?this.parent:this}push(t,n,a,r,i,s,o){return new nt(this,t,n,a,r,i,s,o)}getEnterPos(){return this._enterPos}getAnchorPos(){return this._anchorPos}getRule(t){return t.getRule(this.ruleId)}toString(){const t=[];return this._writeString(t,0),\"[\"+t.join(\",\")+\"]\"}_writeString(t,n){return this.parent&&(n=this.parent._writeString(t,n)),t[n++]=`(${this.ruleId}, ${this.nameScopesList?.toString()}, ${this.contentNameScopesList?.toString()})`,n}withContentNameScopesList(t){return this.contentNameScopesList===t?this:this.parent.push(this.ruleId,this._enterPos,this._anchorPos,this.beginRuleCapturedEOL,this.endRule,this.nameScopesList,t)}withEndRule(t){return this.endRule===t?this:new nt(this.parent,this.ruleId,this._enterPos,this._anchorPos,this.beginRuleCapturedEOL,t,this.nameScopesList,this.contentNameScopesList)}hasSameRuleAs(t){let n=this;for(;n&&n._enterPos===t._enterPos;){if(n.ruleId===t.ruleId)return!0;n=n.parent}return!1}toStateStackFrame(){return{ruleId:this.ruleId,beginRuleCapturedEOL:this.beginRuleCapturedEOL,endRule:this.endRule,nameScopesList:this.nameScopesList?.getExtensionIfDefined(this.parent?.nameScopesList??null)??[],contentNameScopesList:this.contentNameScopesList?.getExtensionIfDefined(this.nameScopesList)??[]}}static pushFrame(t,n){const a=hn.fromExtension(t?.nameScopesList??null,n.nameScopesList);return new nt(t,n.ruleId,n.enterPos??-1,n.anchorPos??-1,n.beginRuleCapturedEOL,n.endRule,a,hn.fromExtension(a,n.contentNameScopesList))}},Eh=class{balancedBracketScopes;unbalancedBracketScopes;allowAny=!1;constructor(e,t){this.balancedBracketScopes=e.flatMap(n=>n===\"*\"?(this.allowAny=!0,[]):ga(n,_a).map(a=>a.matcher)),this.unbalancedBracketScopes=t.flatMap(n=>ga(n,_a).map(a=>a.matcher))}get matchesAlways(){return this.allowAny&&this.unbalancedBracketScopes.length===0}get matchesNever(){return this.balancedBracketScopes.length===0&&!this.allowAny}match(e){for(const t of this.unbalancedBracketScopes)if(t(e))return!1;for(const t of this.balancedBracketScopes)if(t(e))return!0;return this.allowAny}},Fh=class{constructor(e,t,n,a){this.balancedBracketSelectors=a,this._emitBinaryTokens=e,this._tokenTypeOverrides=n,this._lineText=null,this._tokens=[],this._binaryTokens=[],this._lastTokenEndIndex=0}_emitBinaryTokens;_lineText;_tokens;_binaryTokens;_lastTokenEndIndex;_tokenTypeOverrides;produce(e,t){this.produceFromScopes(e.contentNameScopesList,t)}produceFromScopes(e,t){if(this._lastTokenEndIndex>=t)return;if(this._emitBinaryTokens){let a=e?.tokenAttributes??0,r=!1;if(this.balancedBracketSelectors?.matchesAlways&&(r=!0),this._tokenTypeOverrides.length>0||this.balancedBracketSelectors&&!this.balancedBracketSelectors.matchesAlways&&!this.balancedBracketSelectors.matchesNever){const i=e?.getScopeNames()??[];for(const s of this._tokenTypeOverrides)s.matcher(i)&&(a=qt.set(a,0,s.type,null,-1,0,0));this.balancedBracketSelectors&&(r=this.balancedBracketSelectors.match(i))}if(r&&(a=qt.set(a,0,8,r,-1,0,0)),this._binaryTokens.length>0&&this._binaryTokens[this._binaryTokens.length-1]===a){this._lastTokenEndIndex=t;return}this._binaryTokens.push(this._lastTokenEndIndex),this._binaryTokens.push(a),this._lastTokenEndIndex=t;return}const n=e?.getScopeNames()??[];this._tokens.push({startIndex:this._lastTokenEndIndex,endIndex:t,scopes:n}),this._lastTokenEndIndex=t}getResult(e,t){return this._tokens.length>0&&this._tokens[this._tokens.length-1].startIndex===t-1&&this._tokens.pop(),this._tokens.length===0&&(this._lastTokenEndIndex=-1,this.produce(e,t),this._tokens[this._tokens.length-1].startIndex=0),this._tokens}getBinaryResult(e,t){this._binaryTokens.length>0&&this._binaryTokens[this._binaryTokens.length-2]===t-1&&(this._binaryTokens.pop(),this._binaryTokens.pop()),this._binaryTokens.length===0&&(this._lastTokenEndIndex=-1,this.produce(e,t),this._binaryTokens[this._binaryTokens.length-2]=0);const n=new Uint32Array(this._binaryTokens.length);for(let a=0,r=this._binaryTokens.length;a<r;a++)n[a]=this._binaryTokens[a];return n}},$h=class{constructor(e,t){this._onigLib=t,this._theme=e}_grammars=new Map;_rawGrammars=new Map;_injectionGrammars=new Map;_theme;dispose(){for(const e of this._grammars.values())e.dispose()}setTheme(e){this._theme=e}getColorMap(){return this._theme.getColorMap()}addGrammar(e,t){this._rawGrammars.set(e.scopeName,e),t&&this._injectionGrammars.set(e.scopeName,t)}lookup(e){return this._rawGrammars.get(e)}injections(e){return this._injectionGrammars.get(e)}getDefaults(){return this._theme.getDefaults()}themeMatch(e){return this._theme.match(e)}grammarForScopeName(e,t,n,a,r){if(!this._grammars.has(e)){let i=this._rawGrammars.get(e);if(!i)return null;this._grammars.set(e,xh(e,i,t,n,a,r,this,this._onigLib))}return this._grammars.get(e)}},jh=class{_options;_syncRegistry;_ensureGrammarCache;constructor(t){this._options=t,this._syncRegistry=new $h(ha.createFromRawTheme(t.theme,t.colorMap),t.onigLib),this._ensureGrammarCache=new Map}dispose(){this._syncRegistry.dispose()}setTheme(t,n){this._syncRegistry.setTheme(ha.createFromRawTheme(t,n))}getColorMap(){return this._syncRegistry.getColorMap()}loadGrammarWithEmbeddedLanguages(t,n,a){return this.loadGrammarWithConfiguration(t,n,{embeddedLanguages:a})}loadGrammarWithConfiguration(t,n,a){return this._loadGrammar(t,n,a.embeddedLanguages,a.tokenTypes,new Eh(a.balancedBracketSelectors||[],a.unbalancedBracketSelectors||[]))}loadGrammar(t){return this._loadGrammar(t,0,null,null,null)}_loadGrammar(t,n,a,r,i){const s=new ah(this._syncRegistry,t);for(;s.Q.length>0;)s.Q.map(o=>this._loadSingleGrammar(o.scopeName)),s.processQueue();return this._grammarForScopeName(t,n,a,r,i)}_loadSingleGrammar(t){this._ensureGrammarCache.has(t)||(this._doLoadSingleGrammar(t),this._ensureGrammarCache.set(t,!0))}_doLoadSingleGrammar(t){const n=this._options.loadGrammar(t);if(n){const a=typeof this._options.getInjections==\"function\"?this._options.getInjections(t):void 0;this._syncRegistry.addGrammar(n,a)}}addGrammar(t,n=[],a=0,r=null){return this._syncRegistry.addGrammar(t,n),this._grammarForScopeName(t.scopeName,a,r)}_grammarForScopeName(t,n=0,a=null,r=null,i=null){return this._syncRegistry.grammarForScopeName(t,n,a,r,i)}},Nr=Or.NULL;const Sh=[\"area\",\"base\",\"basefont\",\"bgsound\",\"br\",\"col\",\"command\",\"embed\",\"frame\",\"hr\",\"image\",\"img\",\"input\",\"keygen\",\"link\",\"meta\",\"param\",\"source\",\"track\",\"wbr\"];class Tn{constructor(t,n,a){this.normal=n,this.property=t,a&&(this.space=a)}}Tn.prototype.normal={};Tn.prototype.property={};Tn.prototype.space=void 0;function Jc(e,t){const n={},a={};for(const r of e)Object.assign(n,r.property),Object.assign(a,r.normal);return new Tn(n,a,t)}function Ir(e){return e.toLowerCase()}class ie{constructor(t,n){this.attribute=n,this.property=t}}ie.prototype.attribute=\"\";ie.prototype.booleanish=!1;ie.prototype.boolean=!1;ie.prototype.commaOrSpaceSeparated=!1;ie.prototype.commaSeparated=!1;ie.prototype.defined=!1;ie.prototype.mustUseProperty=!1;ie.prototype.number=!1;ie.prototype.overloadedBoolean=!1;ie.prototype.property=\"\";ie.prototype.spaceSeparated=!1;ie.prototype.space=void 0;let Ah=0;const S=yt(),H=yt(),Lr=yt(),x=yt(),P=yt(),Ot=yt(),se=yt();function yt(){return 2**++Ah}const Pr=Object.freeze(Object.defineProperty({__proto__:null,boolean:S,booleanish:H,commaOrSpaceSeparated:se,commaSeparated:Ot,number:x,overloadedBoolean:Lr,spaceSeparated:P},Symbol.toStringTag,{value:\"Module\"})),Qa=Object.keys(Pr);class Ci extends ie{constructor(t,n,a,r){let i=-1;if(super(t,n),Es(this,\"space\",r),typeof a==\"number\")for(;++i<Qa.length;){const s=Qa[i];Es(this,Qa[i],(a&Pr[s])===Pr[s])}}}Ci.prototype.defined=!0;function Es(e,t,n){n&&(e[t]=n)}function Wt(e){const t={},n={};for(const[a,r]of Object.entries(e.properties)){const i=new Ci(a,e.transform(e.attributes||{},a),r,e.space);e.mustUseProperty&&e.mustUseProperty.includes(a)&&(i.mustUseProperty=!0),t[a]=i,n[Ir(a)]=a,n[Ir(i.attribute)]=a}return new Tn(t,n,e.space)}const el=Wt({properties:{ariaActiveDescendant:null,ariaAtomic:H,ariaAutoComplete:null,ariaBusy:H,ariaChecked:H,ariaColCount:x,ariaColIndex:x,ariaColSpan:x,ariaControls:P,ariaCurrent:null,ariaDescribedBy:P,ariaDetails:null,ariaDisabled:H,ariaDropEffect:P,ariaErrorMessage:null,ariaExpanded:H,ariaFlowTo:P,ariaGrabbed:H,ariaHasPopup:null,ariaHidden:H,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:P,ariaLevel:x,ariaLive:null,ariaModal:H,ariaMultiLine:H,ariaMultiSelectable:H,ariaOrientation:null,ariaOwns:P,ariaPlaceholder:null,ariaPosInSet:x,ariaPressed:H,ariaReadOnly:H,ariaRelevant:null,ariaRequired:H,ariaRoleDescription:P,ariaRowCount:x,ariaRowIndex:x,ariaRowSpan:x,ariaSelected:H,ariaSetSize:x,ariaSort:null,ariaValueMax:x,ariaValueMin:x,ariaValueNow:x,ariaValueText:null,role:null},transform(e,t){return t===\"role\"?t:\"aria-\"+t.slice(4).toLowerCase()}});function tl(e,t){return t in e?e[t]:t}function nl(e,t){return tl(e,t.toLowerCase())}const Th=Wt({attributes:{acceptcharset:\"accept-charset\",classname:\"class\",htmlfor:\"for\",httpequiv:\"http-equiv\"},mustUseProperty:[\"checked\",\"multiple\",\"muted\",\"selected\"],properties:{abbr:null,accept:Ot,acceptCharset:P,accessKey:P,action:null,allow:null,allowFullScreen:S,allowPaymentRequest:S,allowUserMedia:S,alt:null,as:null,async:S,autoCapitalize:null,autoComplete:P,autoFocus:S,autoPlay:S,blocking:P,capture:null,charSet:null,checked:S,cite:null,className:P,cols:x,colSpan:null,content:null,contentEditable:H,controls:S,controlsList:P,coords:x|Ot,crossOrigin:null,data:null,dateTime:null,decoding:null,default:S,defer:S,dir:null,dirName:null,disabled:S,download:Lr,draggable:H,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:S,formTarget:null,headers:P,height:x,hidden:Lr,high:x,href:null,hrefLang:null,htmlFor:P,httpEquiv:P,id:null,imageSizes:null,imageSrcSet:null,inert:S,inputMode:null,integrity:null,is:null,isMap:S,itemId:null,itemProp:P,itemRef:P,itemScope:S,itemType:P,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:S,low:x,manifest:null,max:null,maxLength:x,media:null,method:null,min:null,minLength:x,multiple:S,muted:S,name:null,nonce:null,noModule:S,noValidate:S,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:S,optimum:x,pattern:null,ping:P,placeholder:null,playsInline:S,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:S,referrerPolicy:null,rel:P,required:S,reversed:S,rows:x,rowSpan:x,sandbox:P,scope:null,scoped:S,seamless:S,selected:S,shadowRootClonable:S,shadowRootDelegatesFocus:S,shadowRootMode:null,shape:null,size:x,sizes:null,slot:null,span:x,spellCheck:H,src:null,srcDoc:null,srcLang:null,srcSet:null,start:x,step:null,style:null,tabIndex:x,target:null,title:null,translate:null,type:null,typeMustMatch:S,useMap:null,value:H,width:x,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:P,axis:null,background:null,bgColor:null,border:x,borderColor:null,bottomMargin:x,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:S,declare:S,event:null,face:null,frame:null,frameBorder:null,hSpace:x,leftMargin:x,link:null,longDesc:null,lowSrc:null,marginHeight:x,marginWidth:x,noResize:S,noHref:S,noShade:S,noWrap:S,object:null,profile:null,prompt:null,rev:null,rightMargin:x,rules:null,scheme:null,scrolling:H,standby:null,summary:null,text:null,topMargin:x,valueType:null,version:null,vAlign:null,vLink:null,vSpace:x,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:S,disableRemotePlayback:S,prefix:null,property:null,results:x,security:null,unselectable:null},space:\"html\",transform:nl}),Rh=Wt({attributes:{accentHeight:\"accent-height\",alignmentBaseline:\"alignment-baseline\",arabicForm:\"arabic-form\",baselineShift:\"baseline-shift\",capHeight:\"cap-height\",className:\"class\",clipPath:\"clip-path\",clipRule:\"clip-rule\",colorInterpolation:\"color-interpolation\",colorInterpolationFilters:\"color-interpolation-filters\",colorProfile:\"color-profile\",colorRendering:\"color-rendering\",crossOrigin:\"crossorigin\",dataType:\"datatype\",dominantBaseline:\"dominant-baseline\",enableBackground:\"enable-background\",fillOpacity:\"fill-opacity\",fillRule:\"fill-rule\",floodColor:\"flood-color\",floodOpacity:\"flood-opacity\",fontFamily:\"font-family\",fontSize:\"font-size\",fontSizeAdjust:\"font-size-adjust\",fontStretch:\"font-stretch\",fontStyle:\"font-style\",fontVariant:\"font-variant\",fontWeight:\"font-weight\",glyphName:\"glyph-name\",glyphOrientationHorizontal:\"glyph-orientation-horizontal\",glyphOrientationVertical:\"glyph-orientation-vertical\",hrefLang:\"hreflang\",horizAdvX:\"horiz-adv-x\",horizOriginX:\"horiz-origin-x\",horizOriginY:\"horiz-origin-y\",imageRendering:\"image-rendering\",letterSpacing:\"letter-spacing\",lightingColor:\"lighting-color\",markerEnd:\"marker-end\",markerMid:\"marker-mid\",markerStart:\"marker-start\",navDown:\"nav-down\",navDownLeft:\"nav-down-left\",navDownRight:\"nav-down-right\",navLeft:\"nav-left\",navNext:\"nav-next\",navPrev:\"nav-prev\",navRight:\"nav-right\",navUp:\"nav-up\",navUpLeft:\"nav-up-left\",navUpRight:\"nav-up-right\",onAbort:\"onabort\",onActivate:\"onactivate\",onAfterPrint:\"onafterprint\",onBeforePrint:\"onbeforeprint\",onBegin:\"onbegin\",onCancel:\"oncancel\",onCanPlay:\"oncanplay\",onCanPlayThrough:\"oncanplaythrough\",onChange:\"onchange\",onClick:\"onclick\",onClose:\"onclose\",onCopy:\"oncopy\",onCueChange:\"oncuechange\",onCut:\"oncut\",onDblClick:\"ondblclick\",onDrag:\"ondrag\",onDragEnd:\"ondragend\",onDragEnter:\"ondragenter\",onDragExit:\"ondragexit\",onDragLeave:\"ondragleave\",onDragOver:\"ondragover\",onDragStart:\"ondragstart\",onDrop:\"ondrop\",onDurationChange:\"ondurationchange\",onEmptied:\"onemptied\",onEnd:\"onend\",onEnded:\"onended\",onError:\"onerror\",onFocus:\"onfocus\",onFocusIn:\"onfocusin\",onFocusOut:\"onfocusout\",onHashChange:\"onhashchange\",onInput:\"oninput\",onInvalid:\"oninvalid\",onKeyDown:\"onkeydown\",onKeyPress:\"onkeypress\",onKeyUp:\"onkeyup\",onLoad:\"onload\",onLoadedData:\"onloadeddata\",onLoadedMetadata:\"onloadedmetadata\",onLoadStart:\"onloadstart\",onMessage:\"onmessage\",onMouseDown:\"onmousedown\",onMouseEnter:\"onmouseenter\",onMouseLeave:\"onmouseleave\",onMouseMove:\"onmousemove\",onMouseOut:\"onmouseout\",onMouseOver:\"onmouseover\",onMouseUp:\"onmouseup\",onMouseWheel:\"onmousewheel\",onOffline:\"onoffline\",onOnline:\"ononline\",onPageHide:\"onpagehide\",onPageShow:\"onpageshow\",onPaste:\"onpaste\",onPause:\"onpause\",onPlay:\"onplay\",onPlaying:\"onplaying\",onPopState:\"onpopstate\",onProgress:\"onprogress\",onRateChange:\"onratechange\",onRepeat:\"onrepeat\",onReset:\"onreset\",onResize:\"onresize\",onScroll:\"onscroll\",onSeeked:\"onseeked\",onSeeking:\"onseeking\",onSelect:\"onselect\",onShow:\"onshow\",onStalled:\"onstalled\",onStorage:\"onstorage\",onSubmit:\"onsubmit\",onSuspend:\"onsuspend\",onTimeUpdate:\"ontimeupdate\",onToggle:\"ontoggle\",onUnload:\"onunload\",onVolumeChange:\"onvolumechange\",onWaiting:\"onwaiting\",onZoom:\"onzoom\",overlinePosition:\"overline-position\",overlineThickness:\"overline-thickness\",paintOrder:\"paint-order\",panose1:\"panose-1\",pointerEvents:\"pointer-events\",referrerPolicy:\"referrerpolicy\",renderingIntent:\"rendering-intent\",shapeRendering:\"shape-rendering\",stopColor:\"stop-color\",stopOpacity:\"stop-opacity\",strikethroughPosition:\"strikethrough-position\",strikethroughThickness:\"strikethrough-thickness\",strokeDashArray:\"stroke-dasharray\",strokeDashOffset:\"stroke-dashoffset\",strokeLineCap:\"stroke-linecap\",strokeLineJoin:\"stroke-linejoin\",strokeMiterLimit:\"stroke-miterlimit\",strokeOpacity:\"stroke-opacity\",strokeWidth:\"stroke-width\",tabIndex:\"tabindex\",textAnchor:\"text-anchor\",textDecoration:\"text-decoration\",textRendering:\"text-rendering\",transformOrigin:\"transform-origin\",typeOf:\"typeof\",underlinePosition:\"underline-position\",underlineThickness:\"underline-thickness\",unicodeBidi:\"unicode-bidi\",unicodeRange:\"unicode-range\",unitsPerEm:\"units-per-em\",vAlphabetic:\"v-alphabetic\",vHanging:\"v-hanging\",vIdeographic:\"v-ideographic\",vMathematical:\"v-mathematical\",vectorEffect:\"vector-effect\",vertAdvY:\"vert-adv-y\",vertOriginX:\"vert-origin-x\",vertOriginY:\"vert-origin-y\",wordSpacing:\"word-spacing\",writingMode:\"writing-mode\",xHeight:\"x-height\",playbackOrder:\"playbackorder\",timelineBegin:\"timelinebegin\"},properties:{about:se,accentHeight:x,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:x,amplitude:x,arabicForm:null,ascent:x,attributeName:null,attributeType:null,azimuth:x,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:x,by:null,calcMode:null,capHeight:x,className:P,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:x,diffuseConstant:x,direction:null,display:null,dur:null,divisor:x,dominantBaseline:null,download:S,dx:null,dy:null,edgeMode:null,editable:null,elevation:x,enableBackground:null,end:null,event:null,exponent:x,externalResourcesRequired:null,fill:null,fillOpacity:x,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:Ot,g2:Ot,glyphName:Ot,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:x,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:x,horizOriginX:x,horizOriginY:x,id:null,ideographic:x,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:x,k:x,k1:x,k2:x,k3:x,k4:x,kernelMatrix:se,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:x,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:x,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:x,overlineThickness:x,paintOrder:null,panose1:null,path:null,pathLength:x,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:P,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:x,pointsAtY:x,pointsAtZ:x,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:se,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:se,rev:se,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:se,requiredFeatures:se,requiredFonts:se,requiredFormats:se,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:x,specularExponent:x,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:x,strikethroughThickness:x,string:null,stroke:null,strokeDashArray:se,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:x,strokeOpacity:x,strokeWidth:null,style:null,surfaceScale:x,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:se,tabIndex:x,tableValues:null,target:null,targetX:x,targetY:x,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:se,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:x,underlineThickness:x,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:x,values:null,vAlphabetic:x,vMathematical:x,vectorEffect:null,vHanging:x,vIdeographic:x,version:null,vertAdvY:x,vertOriginX:x,vertOriginY:x,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:x,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null},space:\"svg\",transform:tl}),al=Wt({properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null},space:\"xlink\",transform(e,t){return\"xlink:\"+t.slice(5).toLowerCase()}}),rl=Wt({attributes:{xmlnsxlink:\"xmlns:xlink\"},properties:{xmlnsXLink:null,xmlns:null},space:\"xmlns\",transform:nl}),il=Wt({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:\"xml\",transform(e,t){return\"xml:\"+t.slice(3).toLowerCase()}}),Oh=/[A-Z]/g,Fs=/-[a-z]/g,Nh=/^data[-\\w.:]+$/i;function Ih(e,t){const n=Ir(t);let a=t,r=ie;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)===\"data\"&&Nh.test(t)){if(t.charAt(4)===\"-\"){const i=t.slice(5).replace(Fs,Ph);a=\"data\"+i.charAt(0).toUpperCase()+i.slice(1)}else{const i=t.slice(4);if(!Fs.test(i)){let s=i.replace(Oh,Lh);s.charAt(0)!==\"-\"&&(s=\"-\"+s),t=\"data\"+s}}r=Ci}return new r(a,t)}function Lh(e){return\"-\"+e.toLowerCase()}function Ph(e){return e.charAt(1).toUpperCase()}const Dh=Jc([el,Th,al,rl,il],\"html\"),sl=Jc([el,Rh,al,rl,il],\"svg\"),$s={}.hasOwnProperty;function Mh(e,t){const n=t||{};function a(r,...i){let s=a.invalid;const o=a.handlers;if(r&&$s.call(r,e)){const c=String(r[e]);s=$s.call(o,c)?o[c]:a.unknown}if(s)return s.call(this,r,...i)}return a.handlers=n.handlers||{},a.invalid=n.invalid,a.unknown=n.unknown,a}const qh=/[\"&'<>`]/g,zh=/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,Bh=/[\\x01-\\t\\v\\f\\x0E-\\x1F\\x7F\\x81\\x8D\\x8F\\x90\\x9D\\xA0-\\uFFFF]/g,Uh=/[|\\\\{}()[\\]^$+*?.]/g,js=new WeakMap;function Gh(e,t){if(e=e.replace(t.subset?Hh(t.subset):qh,a),t.subset||t.escapeOnly)return e;return e.replace(zh,n).replace(Bh,a);function n(r,i,s){return t.format((r.charCodeAt(0)-55296)*1024+r.charCodeAt(1)-56320+65536,s.charCodeAt(i+2),t)}function a(r,i,s){return t.format(r.charCodeAt(0),s.charCodeAt(i+1),t)}}function Hh(e){let t=js.get(e);return t||(t=Wh(e),js.set(e,t)),t}function Wh(e){const t=[];let n=-1;for(;++n<e.length;)t.push(e[n].replace(Uh,\"\\\\$&\"));return new RegExp(\"(?:\"+t.join(\"|\")+\")\",\"g\")}const Vh=/[\\dA-Fa-f]/;function Zh(e,t,n){const a=\"&#x\"+e.toString(16).toUpperCase();return n&&t&&!Vh.test(String.fromCharCode(t))?a:a+\";\"}const Yh=/\\d/;function Xh(e,t,n){const a=\"&#\"+String(e);return n&&t&&!Yh.test(String.fromCharCode(t))?a:a+\";\"}const Kh=[\"AElig\",\"AMP\",\"Aacute\",\"Acirc\",\"Agrave\",\"Aring\",\"Atilde\",\"Auml\",\"COPY\",\"Ccedil\",\"ETH\",\"Eacute\",\"Ecirc\",\"Egrave\",\"Euml\",\"GT\",\"Iacute\",\"Icirc\",\"Igrave\",\"Iuml\",\"LT\",\"Ntilde\",\"Oacute\",\"Ocirc\",\"Ograve\",\"Oslash\",\"Otilde\",\"Ouml\",\"QUOT\",\"REG\",\"THORN\",\"Uacute\",\"Ucirc\",\"Ugrave\",\"Uuml\",\"Yacute\",\"aacute\",\"acirc\",\"acute\",\"aelig\",\"agrave\",\"amp\",\"aring\",\"atilde\",\"auml\",\"brvbar\",\"ccedil\",\"cedil\",\"cent\",\"copy\",\"curren\",\"deg\",\"divide\",\"eacute\",\"ecirc\",\"egrave\",\"eth\",\"euml\",\"frac12\",\"frac14\",\"frac34\",\"gt\",\"iacute\",\"icirc\",\"iexcl\",\"igrave\",\"iquest\",\"iuml\",\"laquo\",\"lt\",\"macr\",\"micro\",\"middot\",\"nbsp\",\"not\",\"ntilde\",\"oacute\",\"ocirc\",\"ograve\",\"ordf\",\"ordm\",\"oslash\",\"otilde\",\"ouml\",\"para\",\"plusmn\",\"pound\",\"quot\",\"raquo\",\"reg\",\"sect\",\"shy\",\"sup1\",\"sup2\",\"sup3\",\"szlig\",\"thorn\",\"times\",\"uacute\",\"ucirc\",\"ugrave\",\"uml\",\"uuml\",\"yacute\",\"yen\",\"yuml\"],Ja={nbsp:\" \",iexcl:\"¡\",cent:\"¢\",pound:\"£\",curren:\"¤\",yen:\"¥\",brvbar:\"¦\",sect:\"§\",uml:\"¨\",copy:\"©\",ordf:\"ª\",laquo:\"«\",not:\"¬\",shy:\"­\",reg:\"®\",macr:\"¯\",deg:\"°\",plusmn:\"±\",sup2:\"²\",sup3:\"³\",acute:\"´\",micro:\"µ\",para:\"¶\",middot:\"·\",cedil:\"¸\",sup1:\"¹\",ordm:\"º\",raquo:\"»\",frac14:\"¼\",frac12:\"½\",frac34:\"¾\",iquest:\"¿\",Agrave:\"À\",Aacute:\"Á\",Acirc:\"Â\",Atilde:\"Ã\",Auml:\"Ä\",Aring:\"Å\",AElig:\"Æ\",Ccedil:\"Ç\",Egrave:\"È\",Eacute:\"É\",Ecirc:\"Ê\",Euml:\"Ë\",Igrave:\"Ì\",Iacute:\"Í\",Icirc:\"Î\",Iuml:\"Ï\",ETH:\"Ð\",Ntilde:\"Ñ\",Ograve:\"Ò\",Oacute:\"Ó\",Ocirc:\"Ô\",Otilde:\"Õ\",Ouml:\"Ö\",times:\"×\",Oslash:\"Ø\",Ugrave:\"Ù\",Uacute:\"Ú\",Ucirc:\"Û\",Uuml:\"Ü\",Yacute:\"Ý\",THORN:\"Þ\",szlig:\"ß\",agrave:\"à\",aacute:\"á\",acirc:\"â\",atilde:\"ã\",auml:\"ä\",aring:\"å\",aelig:\"æ\",ccedil:\"ç\",egrave:\"è\",eacute:\"é\",ecirc:\"ê\",euml:\"ë\",igrave:\"ì\",iacute:\"í\",icirc:\"î\",iuml:\"ï\",eth:\"ð\",ntilde:\"ñ\",ograve:\"ò\",oacute:\"ó\",ocirc:\"ô\",otilde:\"õ\",ouml:\"ö\",divide:\"÷\",oslash:\"ø\",ugrave:\"ù\",uacute:\"ú\",ucirc:\"û\",uuml:\"ü\",yacute:\"ý\",thorn:\"þ\",yuml:\"ÿ\",fnof:\"ƒ\",Alpha:\"Α\",Beta:\"Β\",Gamma:\"Γ\",Delta:\"Δ\",Epsilon:\"Ε\",Zeta:\"Ζ\",Eta:\"Η\",Theta:\"Θ\",Iota:\"Ι\",Kappa:\"Κ\",Lambda:\"Λ\",Mu:\"Μ\",Nu:\"Ν\",Xi:\"Ξ\",Omicron:\"Ο\",Pi:\"Π\",Rho:\"Ρ\",Sigma:\"Σ\",Tau:\"Τ\",Upsilon:\"Υ\",Phi:\"Φ\",Chi:\"Χ\",Psi:\"Ψ\",Omega:\"Ω\",alpha:\"α\",beta:\"β\",gamma:\"γ\",delta:\"δ\",epsilon:\"ε\",zeta:\"ζ\",eta:\"η\",theta:\"θ\",iota:\"ι\",kappa:\"κ\",lambda:\"λ\",mu:\"μ\",nu:\"ν\",xi:\"ξ\",omicron:\"ο\",pi:\"π\",rho:\"ρ\",sigmaf:\"ς\",sigma:\"σ\",tau:\"τ\",upsilon:\"υ\",phi:\"φ\",chi:\"χ\",psi:\"ψ\",omega:\"ω\",thetasym:\"ϑ\",upsih:\"ϒ\",piv:\"ϖ\",bull:\"•\",hellip:\"…\",prime:\"′\",Prime:\"″\",oline:\"‾\",frasl:\"⁄\",weierp:\"℘\",image:\"ℑ\",real:\"ℜ\",trade:\"™\",alefsym:\"ℵ\",larr:\"←\",uarr:\"↑\",rarr:\"→\",darr:\"↓\",harr:\"↔\",crarr:\"↵\",lArr:\"⇐\",uArr:\"⇑\",rArr:\"⇒\",dArr:\"⇓\",hArr:\"⇔\",forall:\"∀\",part:\"∂\",exist:\"∃\",empty:\"∅\",nabla:\"∇\",isin:\"∈\",notin:\"∉\",ni:\"∋\",prod:\"∏\",sum:\"∑\",minus:\"−\",lowast:\"∗\",radic:\"√\",prop:\"∝\",infin:\"∞\",ang:\"∠\",and:\"∧\",or:\"∨\",cap:\"∩\",cup:\"∪\",int:\"∫\",there4:\"∴\",sim:\"∼\",cong:\"≅\",asymp:\"≈\",ne:\"≠\",equiv:\"≡\",le:\"≤\",ge:\"≥\",sub:\"⊂\",sup:\"⊃\",nsub:\"⊄\",sube:\"⊆\",supe:\"⊇\",oplus:\"⊕\",otimes:\"⊗\",perp:\"⊥\",sdot:\"⋅\",lceil:\"⌈\",rceil:\"⌉\",lfloor:\"⌊\",rfloor:\"⌋\",lang:\"〈\",rang:\"〉\",loz:\"◊\",spades:\"♠\",clubs:\"♣\",hearts:\"♥\",diams:\"♦\",quot:'\"',amp:\"&\",lt:\"<\",gt:\">\",OElig:\"Œ\",oelig:\"œ\",Scaron:\"Š\",scaron:\"š\",Yuml:\"Ÿ\",circ:\"ˆ\",tilde:\"˜\",ensp:\" \",emsp:\" \",thinsp:\" \",zwnj:\"‌\",zwj:\"‍\",lrm:\"‎\",rlm:\"‏\",ndash:\"–\",mdash:\"—\",lsquo:\"‘\",rsquo:\"’\",sbquo:\"‚\",ldquo:\"“\",rdquo:\"”\",bdquo:\"„\",dagger:\"†\",Dagger:\"‡\",permil:\"‰\",lsaquo:\"‹\",rsaquo:\"›\",euro:\"€\"},Qh=[\"cent\",\"copy\",\"divide\",\"gt\",\"lt\",\"not\",\"para\",\"times\"],ol={}.hasOwnProperty,Dr={};let Jn;for(Jn in Ja)ol.call(Ja,Jn)&&(Dr[Ja[Jn]]=Jn);const Jh=/[^\\dA-Za-z]/;function eg(e,t,n,a){const r=String.fromCharCode(e);if(ol.call(Dr,r)){const i=Dr[r],s=\"&\"+i;return n&&Kh.includes(i)&&!Qh.includes(i)&&(!a||t&&t!==61&&Jh.test(String.fromCharCode(t)))?s:s+\";\"}return\"\"}function tg(e,t,n){let a=Zh(e,t,n.omitOptionalSemicolons),r;if((n.useNamedReferences||n.useShortestReferences)&&(r=eg(e,t,n.omitOptionalSemicolons,n.attribute)),(n.useShortestReferences||!r)&&n.useShortestReferences){const i=Xh(e,t,n.omitOptionalSemicolons);i.length<a.length&&(a=i)}return r&&(!n.useShortestReferences||r.length<a.length)?r:a}function Nt(e,t){return Gh(e,Object.assign({format:tg},t))}const ng=/^>|^->|<!--|-->|--!>|<!-$/g,ag=[\">\"],rg=[\"<\",\">\"];function ig(e,t,n,a){return a.settings.bogusComments?\"<?\"+Nt(e.value,Object.assign({},a.settings.characterReferences,{subset:ag}))+\">\":\"<!--\"+e.value.replace(ng,r)+\"-->\";function r(i){return Nt(i,Object.assign({},a.settings.characterReferences,{subset:rg}))}}function sg(e,t,n,a){return\"<!\"+(a.settings.upperDoctype?\"DOCTYPE\":\"doctype\")+(a.settings.tightDoctype?\"\":\" \")+\"html>\"}function Ss(e,t){const n=String(e);if(typeof t!=\"string\")throw new TypeError(\"Expected character\");let a=0,r=n.indexOf(t);for(;r!==-1;)a++,r=n.indexOf(t,r+t.length);return a}function og(e,t){const n=t||{};return(e[e.length-1]===\"\"?[...e,\"\"]:e).join((n.padRight?\" \":\"\")+\",\"+(n.padLeft===!1?\"\":\" \")).trim()}function cg(e){return e.join(\" \").trim()}const lg=/[ \\t\\n\\f\\r]/g;function Ei(e){return typeof e==\"object\"?e.type===\"text\"?As(e.value):!1:As(e)}function As(e){return e.replace(lg,\"\")===\"\"}const Z=ll(1),cl=ll(-1),ug=[];function ll(e){return t;function t(n,a,r){const i=n?n.children:ug;let s=(a||0)+e,o=i[s];if(!r)for(;o&&Ei(o);)s+=e,o=i[s];return o}}const pg={}.hasOwnProperty;function ul(e){return t;function t(n,a,r){return pg.call(e,n.tagName)&&e[n.tagName](n,a,r)}}const Fi=ul({body:mg,caption:er,colgroup:er,dd:bg,dt:fg,head:er,html:dg,li:gg,optgroup:_g,option:yg,p:hg,rp:Ts,rt:Ts,tbody:wg,td:Rs,tfoot:xg,th:Rs,thead:vg,tr:kg});function er(e,t,n){const a=Z(n,t,!0);return!a||a.type!==\"comment\"&&!(a.type===\"text\"&&Ei(a.value.charAt(0)))}function dg(e,t,n){const a=Z(n,t);return!a||a.type!==\"comment\"}function mg(e,t,n){const a=Z(n,t);return!a||a.type!==\"comment\"}function hg(e,t,n){const a=Z(n,t);return a?a.type===\"element\"&&(a.tagName===\"address\"||a.tagName===\"article\"||a.tagName===\"aside\"||a.tagName===\"blockquote\"||a.tagName===\"details\"||a.tagName===\"div\"||a.tagName===\"dl\"||a.tagName===\"fieldset\"||a.tagName===\"figcaption\"||a.tagName===\"figure\"||a.tagName===\"footer\"||a.tagName===\"form\"||a.tagName===\"h1\"||a.tagName===\"h2\"||a.tagName===\"h3\"||a.tagName===\"h4\"||a.tagName===\"h5\"||a.tagName===\"h6\"||a.tagName===\"header\"||a.tagName===\"hgroup\"||a.tagName===\"hr\"||a.tagName===\"main\"||a.tagName===\"menu\"||a.tagName===\"nav\"||a.tagName===\"ol\"||a.tagName===\"p\"||a.tagName===\"pre\"||a.tagName===\"section\"||a.tagName===\"table\"||a.tagName===\"ul\"):!n||!(n.type===\"element\"&&(n.tagName===\"a\"||n.tagName===\"audio\"||n.tagName===\"del\"||n.tagName===\"ins\"||n.tagName===\"map\"||n.tagName===\"noscript\"||n.tagName===\"video\"))}function gg(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&a.tagName===\"li\"}function fg(e,t,n){const a=Z(n,t);return!!(a&&a.type===\"element\"&&(a.tagName===\"dt\"||a.tagName===\"dd\"))}function bg(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&(a.tagName===\"dt\"||a.tagName===\"dd\")}function Ts(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&(a.tagName===\"rp\"||a.tagName===\"rt\")}function _g(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&a.tagName===\"optgroup\"}function yg(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&(a.tagName===\"option\"||a.tagName===\"optgroup\")}function vg(e,t,n){const a=Z(n,t);return!!(a&&a.type===\"element\"&&(a.tagName===\"tbody\"||a.tagName===\"tfoot\"))}function wg(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&(a.tagName===\"tbody\"||a.tagName===\"tfoot\")}function xg(e,t,n){return!Z(n,t)}function kg(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&a.tagName===\"tr\"}function Rs(e,t,n){const a=Z(n,t);return!a||a.type===\"element\"&&(a.tagName===\"td\"||a.tagName===\"th\")}const Cg=ul({body:$g,colgroup:jg,head:Fg,html:Eg,tbody:Sg});function Eg(e){const t=Z(e,-1);return!t||t.type!==\"comment\"}function Fg(e){const t=new Set;for(const a of e.children)if(a.type===\"element\"&&(a.tagName===\"base\"||a.tagName===\"title\")){if(t.has(a.tagName))return!1;t.add(a.tagName)}const n=e.children[0];return!n||n.type===\"element\"}function $g(e){const t=Z(e,-1,!0);return!t||t.type!==\"comment\"&&!(t.type===\"text\"&&Ei(t.value.charAt(0)))&&!(t.type===\"element\"&&(t.tagName===\"meta\"||t.tagName===\"link\"||t.tagName===\"script\"||t.tagName===\"style\"||t.tagName===\"template\"))}function jg(e,t,n){const a=cl(n,t),r=Z(e,-1,!0);return n&&a&&a.type===\"element\"&&a.tagName===\"colgroup\"&&Fi(a,n.children.indexOf(a),n)?!1:!!(r&&r.type===\"element\"&&r.tagName===\"col\")}function Sg(e,t,n){const a=cl(n,t),r=Z(e,-1);return n&&a&&a.type===\"element\"&&(a.tagName===\"thead\"||a.tagName===\"tbody\")&&Fi(a,n.children.indexOf(a),n)?!1:!!(r&&r.type===\"element\"&&r.tagName===\"tr\")}const ea={name:[[`\t\n\\f\\r &/=>`.split(\"\"),`\t\n\\f\\r \"&'/=>\\``.split(\"\")],[`\\0\t\n\\f\\r \"&'/<=>`.split(\"\"),`\\0\t\n\\f\\r \"&'/<=>\\``.split(\"\")]],unquoted:[[`\t\n\\f\\r &>`.split(\"\"),`\\0\t\n\\f\\r \"&'<=>\\``.split(\"\")],[`\\0\t\n\\f\\r \"&'<=>\\``.split(\"\"),`\\0\t\n\\f\\r \"&'<=>\\``.split(\"\")]],single:[[\"&'\".split(\"\"),\"\\\"&'`\".split(\"\")],[\"\\0&'\".split(\"\"),\"\\0\\\"&'`\".split(\"\")]],double:[['\"&'.split(\"\"),\"\\\"&'`\".split(\"\")],['\\0\"&'.split(\"\"),\"\\0\\\"&'`\".split(\"\")]]};function Ag(e,t,n,a){const r=a.schema,i=r.space===\"svg\"?!1:a.settings.omitOptionalTags;let s=r.space===\"svg\"?a.settings.closeEmptyElements:a.settings.voids.includes(e.tagName.toLowerCase());const o=[];let c;r.space===\"html\"&&e.tagName===\"svg\"&&(a.schema=sl);const l=Tg(a,e.properties),u=a.all(r.space===\"html\"&&e.tagName===\"template\"?e.content:e);return a.schema=r,u&&(s=!1),(l||!i||!Cg(e,t,n))&&(o.push(\"<\",e.tagName,l?\" \"+l:\"\"),s&&(r.space===\"svg\"||a.settings.closeSelfClosing)&&(c=l.charAt(l.length-1),(!a.settings.tightSelfClosing||c===\"/\"||c&&c!=='\"'&&c!==\"'\")&&o.push(\" \"),o.push(\"/\")),o.push(\">\")),o.push(u),!s&&(!i||!Fi(e,t,n))&&o.push(\"</\"+e.tagName+\">\"),o.join(\"\")}function Tg(e,t){const n=[];let a=-1,r;if(t){for(r in t)if(t[r]!==null&&t[r]!==void 0){const i=Rg(e,r,t[r]);i&&n.push(i)}}for(;++a<n.length;){const i=e.settings.tightAttributes?n[a].charAt(n[a].length-1):void 0;a!==n.length-1&&i!=='\"'&&i!==\"'\"&&(n[a]+=\" \")}return n.join(\"\")}function Rg(e,t,n){const a=Ih(e.schema,t),r=e.settings.allowParseErrors&&e.schema.space===\"html\"?0:1,i=e.settings.allowDangerousCharacters?0:1;let s=e.quote,o;if(a.overloadedBoolean&&(n===a.attribute||n===\"\")?n=!0:(a.boolean||a.overloadedBoolean)&&(typeof n!=\"string\"||n===a.attribute||n===\"\")&&(n=!!n),n==null||n===!1||typeof n==\"number\"&&Number.isNaN(n))return\"\";const c=Nt(a.attribute,Object.assign({},e.settings.characterReferences,{subset:ea.name[r][i]}));return n===!0||(n=Array.isArray(n)?(a.commaSeparated?og:cg)(n,{padLeft:!e.settings.tightCommaSeparatedLists}):String(n),e.settings.collapseEmptyAttributes&&!n)?c:(e.settings.preferUnquoted&&(o=Nt(n,Object.assign({},e.settings.characterReferences,{attribute:!0,subset:ea.unquoted[r][i]}))),o!==n&&(e.settings.quoteSmart&&Ss(n,s)>Ss(n,e.alternative)&&(s=e.alternative),o=s+Nt(n,Object.assign({},e.settings.characterReferences,{subset:(s===\"'\"?ea.single:ea.double)[r][i],attribute:!0}))+s),c+(o&&\"=\"+o))}const Og=[\"<\",\"&\"];function pl(e,t,n,a){return n&&n.type===\"element\"&&(n.tagName===\"script\"||n.tagName===\"style\")?e.value:Nt(e.value,Object.assign({},a.settings.characterReferences,{subset:Og}))}function Ng(e,t,n,a){return a.settings.allowDangerousHtml?e.value:pl(e,t,n,a)}function Ig(e,t,n,a){return a.all(e)}const Lg=Mh(\"type\",{invalid:Pg,unknown:Dg,handlers:{comment:ig,doctype:sg,element:Ag,raw:Ng,root:Ig,text:pl}});function Pg(e){throw new Error(\"Expected node, not `\"+e+\"`\")}function Dg(e){const t=e;throw new Error(\"Cannot compile unknown node `\"+t.type+\"`\")}const Mg={},qg={},zg=[];function Bg(e,t){const n=t||Mg,a=n.quote||'\"',r=a==='\"'?\"'\":'\"';if(a!=='\"'&&a!==\"'\")throw new Error(\"Invalid quote `\"+a+\"`, expected `'` or `\\\"`\");return{one:Ug,all:Gg,settings:{omitOptionalTags:n.omitOptionalTags||!1,allowParseErrors:n.allowParseErrors||!1,allowDangerousCharacters:n.allowDangerousCharacters||!1,quoteSmart:n.quoteSmart||!1,preferUnquoted:n.preferUnquoted||!1,tightAttributes:n.tightAttributes||!1,upperDoctype:n.upperDoctype||!1,tightDoctype:n.tightDoctype||!1,bogusComments:n.bogusComments||!1,tightCommaSeparatedLists:n.tightCommaSeparatedLists||!1,tightSelfClosing:n.tightSelfClosing||!1,collapseEmptyAttributes:n.collapseEmptyAttributes||!1,allowDangerousHtml:n.allowDangerousHtml||!1,voids:n.voids||Sh,characterReferences:n.characterReferences||qg,closeSelfClosing:n.closeSelfClosing||!1,closeEmptyElements:n.closeEmptyElements||!1},schema:n.space===\"svg\"?sl:Dh,quote:a,alternative:r}.one(Array.isArray(e)?{type:\"root\",children:e}:e,void 0,void 0)}function Ug(e,t,n){return Lg(e,t,n,this)}function Gg(e){const t=[],n=e&&e.children||zg;let a=-1;for(;++a<n.length;)t[a]=this.one(n[a],a,e);return t.join(\"\")}function ya(e,t){const n=typeof e==\"string\"?{}:{...e.colorReplacements},a=typeof e==\"string\"?e:e.name;for(const[r,i]of Object.entries(t?.colorReplacements||{}))typeof i==\"string\"?n[r]=i:r===a&&Object.assign(n,i);return n}function Ge(e,t){return e&&(t?.[e?.toLowerCase()]||e)}function Hg(e){return Array.isArray(e)?e:[e]}async function dl(e){return Promise.resolve(typeof e==\"function\"?e():e).then(t=>t.default||t)}function $i(e){return!e||[\"plaintext\",\"txt\",\"text\",\"plain\"].includes(e)}function Wg(e){return e===\"ansi\"||$i(e)}function ji(e){return e===\"none\"}function Vg(e){return ji(e)}function ml(e,t){if(!t)return e;e.properties||={},e.properties.class||=[],typeof e.properties.class==\"string\"&&(e.properties.class=e.properties.class.split(/\\s+/g)),Array.isArray(e.properties.class)||(e.properties.class=[]);const n=Array.isArray(t)?t:t.split(/\\s+/g);for(const a of n)a&&!e.properties.class.includes(a)&&e.properties.class.push(a);return e}function Na(e,t=!1){if(e.length===0)return[[\"\",0]];const n=e.split(/(\\r?\\n)/g);let a=0;const r=[];for(let i=0;i<n.length;i+=2){const s=t?n[i]+(n[i+1]||\"\"):n[i];r.push([s,a]),a+=n[i].length,a+=n[i+1]?.length||0}return r}function Zg(e){const t=Na(e,!0).map(([r])=>r);function n(r){if(r===e.length)return{line:t.length-1,character:t[t.length-1].length};let i=r,s=0;for(const o of t){if(i<o.length)break;i-=o.length,s++}return{line:s,character:i}}function a(r,i){let s=0;for(let o=0;o<r;o++)s+=t[o].length;return s+=i,s}return{lines:t,indexToPos:n,posToIndex:a}}const Si=\"light-dark()\",Yg=[\"color\",\"background-color\"];function Xg(e,t){let n=0;const a=[];for(const r of t)r>n&&a.push({...e,content:e.content.slice(n,r),offset:e.offset+n}),n=r;return n<e.content.length&&a.push({...e,content:e.content.slice(n),offset:e.offset+n}),a}function Kg(e,t){const n=Array.from(t instanceof Set?t:new Set(t)).sort((a,r)=>a-r);return n.length?e.map(a=>a.flatMap(r=>{const i=n.filter(s=>r.offset<s&&s<r.offset+r.content.length).map(s=>s-r.offset).sort((s,o)=>s-o);return i.length?Xg(r,i):r})):e}function Qg(e,t,n,a,r=\"css-vars\"){const i={content:e.content,explanation:e.explanation,offset:e.offset},s=t.map(u=>va(e.variants[u])),o=new Set(s.flatMap(u=>Object.keys(u))),c={},l=(u,p)=>{const m=p===\"color\"?\"\":p===\"background-color\"?\"-bg\":`-${p}`;return n+t[u]+(p===\"color\"?\"\":m)};return s.forEach((u,p)=>{for(const m of o){const h=u[m]||\"inherit\";if(p===0&&a&&Yg.includes(m))if(a===Si&&s.length>1){const g=t.findIndex(w=>w===\"light\"),_=t.findIndex(w=>w===\"dark\");if(g===-1||_===-1)throw new Y('When using `defaultColor: \"light-dark()\"`, you must provide both `light` and `dark` themes');const f=s[g][m]||\"inherit\",b=s[_][m]||\"inherit\";c[m]=`light-dark(${f}, ${b})`,r===\"css-vars\"&&(c[l(p,m)]=h)}else c[m]=h;else r===\"css-vars\"&&(c[l(p,m)]=h)}}),i.htmlStyle=c,i}function va(e){const t={};if(e.color&&(t.color=e.color),e.bgColor&&(t[\"background-color\"]=e.bgColor),e.fontStyle){e.fontStyle&ee.Italic&&(t[\"font-style\"]=\"italic\"),e.fontStyle&ee.Bold&&(t[\"font-weight\"]=\"bold\");const n=[];e.fontStyle&ee.Underline&&n.push(\"underline\"),e.fontStyle&ee.Strikethrough&&n.push(\"line-through\"),n.length&&(t[\"text-decoration\"]=n.join(\" \"))}return t}function Mr(e){return typeof e==\"string\"?e:Object.entries(e).map(([t,n])=>`${t}:${n}`).join(\";\")}const hl=new WeakMap;function Ia(e,t){hl.set(e,t)}function Cn(e){return hl.get(e)}class Vt{_stacks={};lang;get themes(){return Object.keys(this._stacks)}get theme(){return this.themes[0]}get _stack(){return this._stacks[this.theme]}static initial(t,n){return new Vt(Object.fromEntries(Hg(n).map(a=>[a,Nr])),t)}constructor(...t){if(t.length===2){const[n,a]=t;this.lang=a,this._stacks=n}else{const[n,a,r]=t;this.lang=a,this._stacks={[r]:n}}}getInternalStack(t=this.theme){return this._stacks[t]}getScopes(t=this.theme){return Jg(this._stacks[t])}toJSON(){return{lang:this.lang,theme:this.theme,themes:this.themes,scopes:this.getScopes()}}}function Jg(e){const t=[],n=new Set;function a(r){if(n.has(r))return;n.add(r);const i=r?.nameScopesList?.scopeName;i&&t.push(i),r.parent&&a(r.parent)}return a(e),t}function ef(e,t){if(!(e instanceof Vt))throw new Y(\"Invalid grammar state\");return e.getInternalStack(t)}function tf(){const e=new WeakMap;function t(n){if(!e.has(n.meta)){let a=function(s){if(typeof s==\"number\"){if(s<0||s>n.source.length)throw new Y(`Invalid decoration offset: ${s}. Code length: ${n.source.length}`);return{...r.indexToPos(s),offset:s}}else{const o=r.lines[s.line];if(o===void 0)throw new Y(`Invalid decoration position ${JSON.stringify(s)}. Lines length: ${r.lines.length}`);let c=s.character;if(c<0&&(c=o.length+c),c<0||c>o.length)throw new Y(`Invalid decoration position ${JSON.stringify(s)}. Line ${s.line} length: ${o.length}`);return{...s,character:c,offset:r.posToIndex(s.line,c)}}};const r=Zg(n.source),i=(n.options.decorations||[]).map(s=>({...s,start:a(s.start),end:a(s.end)}));nf(i),e.set(n.meta,{decorations:i,converter:r,source:n.source})}return e.get(n.meta)}return{name:\"shiki:decorations\",tokens(n){if(!this.options.decorations?.length)return;const r=t(this).decorations.flatMap(s=>[s.start.offset,s.end.offset]);return Kg(n,r)},code(n){if(!this.options.decorations?.length)return;const a=t(this),r=Array.from(n.children).filter(u=>u.type===\"element\"&&u.tagName===\"span\");if(r.length!==a.converter.lines.length)throw new Y(`Number of lines in code element (${r.length}) does not match the number of lines in the source (${a.converter.lines.length}). Failed to apply decorations.`);function i(u,p,m,h){const g=r[u];let _=\"\",f=-1,b=-1;if(p===0&&(f=0),m===0&&(b=0),m===Number.POSITIVE_INFINITY&&(b=g.children.length),f===-1||b===-1)for(let y=0;y<g.children.length;y++)_+=gl(g.children[y]),f===-1&&_.length===p&&(f=y+1),b===-1&&_.length===m&&(b=y+1);if(f===-1)throw new Y(`Failed to find start index for decoration ${JSON.stringify(h.start)}`);if(b===-1)throw new Y(`Failed to find end index for decoration ${JSON.stringify(h.end)}`);const w=g.children.slice(f,b);if(!h.alwaysWrap&&w.length===g.children.length)o(g,h,\"line\");else if(!h.alwaysWrap&&w.length===1&&w[0].type===\"element\")o(w[0],h,\"token\");else{const y={type:\"element\",tagName:\"span\",properties:{},children:w};o(y,h,\"wrapper\"),g.children.splice(f,w.length,y)}}function s(u,p){r[u]=o(r[u],p,\"line\")}function o(u,p,m){const h=p.properties||{},g=p.transform||(_=>_);return u.tagName=p.tagName||\"span\",u.properties={...u.properties,...h,class:u.properties.class},p.properties?.class&&ml(u,p.properties.class),u=g(u,m)||u,u}const c=[],l=a.decorations.sort((u,p)=>p.start.offset-u.start.offset||u.end.offset-p.end.offset);for(const u of l){const{start:p,end:m}=u;if(p.line===m.line)i(p.line,p.character,m.character,u);else if(p.line<m.line){i(p.line,p.character,Number.POSITIVE_INFINITY,u);for(let h=p.line+1;h<m.line;h++)c.unshift(()=>s(h,u));i(m.line,0,m.character,u)}}c.forEach(u=>u())}}}function nf(e){for(let t=0;t<e.length;t++){const n=e[t];if(n.start.offset>n.end.offset)throw new Y(`Invalid decoration range: ${JSON.stringify(n.start)} - ${JSON.stringify(n.end)}`);for(let a=t+1;a<e.length;a++){const r=e[a],i=n.start.offset<=r.start.offset&&r.start.offset<n.end.offset,s=n.start.offset<r.end.offset&&r.end.offset<=n.end.offset,o=r.start.offset<=n.start.offset&&n.start.offset<r.end.offset,c=r.start.offset<n.end.offset&&n.end.offset<=r.end.offset;if(i||s||o||c){if(i&&s||o&&c||o&&n.start.offset===n.end.offset||s&&r.start.offset===r.end.offset)continue;throw new Y(`Decorations ${JSON.stringify(n.start)} and ${JSON.stringify(r.start)} intersect.`)}}}}function gl(e){return e.type===\"text\"?e.value:e.type===\"element\"?e.children.map(gl).join(\"\"):\"\"}const af=[tf()];function wa(e){const t=rf(e.transformers||[]);return[...t.pre,...t.normal,...t.post,...af]}function rf(e){const t=[],n=[],a=[];for(const r of e)switch(r.enforce){case\"pre\":t.push(r);break;case\"post\":n.push(r);break;default:a.push(r)}return{pre:t,post:n,normal:a}}var it=[\"black\",\"red\",\"green\",\"yellow\",\"blue\",\"magenta\",\"cyan\",\"white\",\"brightBlack\",\"brightRed\",\"brightGreen\",\"brightYellow\",\"brightBlue\",\"brightMagenta\",\"brightCyan\",\"brightWhite\"],tr={1:\"bold\",2:\"dim\",3:\"italic\",4:\"underline\",7:\"reverse\",8:\"hidden\",9:\"strikethrough\"};function sf(e,t){const n=e.indexOf(\"\\x1B\",t);if(n!==-1&&e[n+1]===\"[\"){const a=e.indexOf(\"m\",n);if(a!==-1)return{sequence:e.substring(n+2,a).split(\";\"),startPosition:n,position:a+1}}return{position:e.length}}function Os(e){const t=e.shift();if(t===\"2\"){const n=e.splice(0,3).map(a=>Number.parseInt(a));return n.length!==3||n.some(a=>Number.isNaN(a))?void 0:{type:\"rgb\",rgb:n}}else if(t===\"5\"){const n=e.shift();if(n)return{type:\"table\",index:Number(n)}}}function of(e){const t=[];for(;e.length>0;){const n=e.shift();if(!n)continue;const a=Number.parseInt(n);if(!Number.isNaN(a))if(a===0)t.push({type:\"resetAll\"});else if(a<=9)tr[a]&&t.push({type:\"setDecoration\",value:tr[a]});else if(a<=29){const r=tr[a-20];r&&(t.push({type:\"resetDecoration\",value:r}),r===\"dim\"&&t.push({type:\"resetDecoration\",value:\"bold\"}))}else if(a<=37)t.push({type:\"setForegroundColor\",value:{type:\"named\",name:it[a-30]}});else if(a===38){const r=Os(e);r&&t.push({type:\"setForegroundColor\",value:r})}else if(a===39)t.push({type:\"resetForegroundColor\"});else if(a<=47)t.push({type:\"setBackgroundColor\",value:{type:\"named\",name:it[a-40]}});else if(a===48){const r=Os(e);r&&t.push({type:\"setBackgroundColor\",value:r})}else a===49?t.push({type:\"resetBackgroundColor\"}):a===53?t.push({type:\"setDecoration\",value:\"overline\"}):a===55?t.push({type:\"resetDecoration\",value:\"overline\"}):a>=90&&a<=97?t.push({type:\"setForegroundColor\",value:{type:\"named\",name:it[a-90+8]}}):a>=100&&a<=107&&t.push({type:\"setBackgroundColor\",value:{type:\"named\",name:it[a-100+8]}})}return t}function cf(){let e=null,t=null,n=new Set;return{parse(a){const r=[];let i=0;do{const s=sf(a,i),o=s.sequence?a.substring(i,s.startPosition):a.substring(i);if(o.length>0&&r.push({value:o,foreground:e,background:t,decorations:new Set(n)}),s.sequence){const c=of(s.sequence);for(const l of c)l.type===\"resetAll\"?(e=null,t=null,n.clear()):l.type===\"resetForegroundColor\"?e=null:l.type===\"resetBackgroundColor\"?t=null:l.type===\"resetDecoration\"&&n.delete(l.value);for(const l of c)l.type===\"setForegroundColor\"?e=l.value:l.type===\"setBackgroundColor\"?t=l.value:l.type===\"setDecoration\"&&n.add(l.value)}i=s.position}while(i<a.length);return r}}}var lf={black:\"#000000\",red:\"#bb0000\",green:\"#00bb00\",yellow:\"#bbbb00\",blue:\"#0000bb\",magenta:\"#ff00ff\",cyan:\"#00bbbb\",white:\"#eeeeee\",brightBlack:\"#555555\",brightRed:\"#ff5555\",brightGreen:\"#00ff00\",brightYellow:\"#ffff55\",brightBlue:\"#5555ff\",brightMagenta:\"#ff55ff\",brightCyan:\"#55ffff\",brightWhite:\"#ffffff\"};function uf(e=lf){function t(o){return e[o]}function n(o){return`#${o.map(c=>Math.max(0,Math.min(c,255)).toString(16).padStart(2,\"0\")).join(\"\")}`}let a;function r(){if(a)return a;a=[];for(let l=0;l<it.length;l++)a.push(t(it[l]));let o=[0,95,135,175,215,255];for(let l=0;l<6;l++)for(let u=0;u<6;u++)for(let p=0;p<6;p++)a.push(n([o[l],o[u],o[p]]));let c=8;for(let l=0;l<24;l++,c+=10)a.push(n([c,c,c]));return a}function i(o){return r()[o]}function s(o){switch(o.type){case\"named\":return t(o.name);case\"rgb\":return n(o.rgb);case\"table\":return i(o.index)}}return{value:s}}const pf={black:\"#000000\",red:\"#cd3131\",green:\"#0DBC79\",yellow:\"#E5E510\",blue:\"#2472C8\",magenta:\"#BC3FBC\",cyan:\"#11A8CD\",white:\"#E5E5E5\",brightBlack:\"#666666\",brightRed:\"#F14C4C\",brightGreen:\"#23D18B\",brightYellow:\"#F5F543\",brightBlue:\"#3B8EEA\",brightMagenta:\"#D670D6\",brightCyan:\"#29B8DB\",brightWhite:\"#FFFFFF\"};function df(e,t,n){const a=ya(e,n),r=Na(t),i=Object.fromEntries(it.map(c=>{const l=`terminal.ansi${c[0].toUpperCase()}${c.substring(1)}`,u=e.colors?.[l];return[c,u||pf[c]]})),s=uf(i),o=cf();return r.map(c=>o.parse(c[0]).map(l=>{let u,p;l.decorations.has(\"reverse\")?(u=l.background?s.value(l.background):e.bg,p=l.foreground?s.value(l.foreground):e.fg):(u=l.foreground?s.value(l.foreground):e.fg,p=l.background?s.value(l.background):void 0),u=Ge(u,a),p=Ge(p,a),l.decorations.has(\"dim\")&&(u=mf(u));let m=ee.None;return l.decorations.has(\"bold\")&&(m|=ee.Bold),l.decorations.has(\"italic\")&&(m|=ee.Italic),l.decorations.has(\"underline\")&&(m|=ee.Underline),l.decorations.has(\"strikethrough\")&&(m|=ee.Strikethrough),{content:l.value,offset:c[1],color:u,bgColor:p,fontStyle:m}}))}function mf(e){const t=e.match(/#([0-9a-f]{3,8})/i);if(t){const a=t[1];if(a.length===8){const r=Math.round(Number.parseInt(a.slice(6,8),16)/2).toString(16).padStart(2,\"0\");return`#${a.slice(0,6)}${r}`}else{if(a.length===6)return`#${a}80`;if(a.length===4){const r=a[0],i=a[1],s=a[2],o=a[3],c=Math.round(Number.parseInt(`${o}${o}`,16)/2).toString(16).padStart(2,\"0\");return`#${r}${r}${i}${i}${s}${s}${c}`}else if(a.length===3){const r=a[0],i=a[1],s=a[2];return`#${r}${r}${i}${i}${s}${s}80`}}}const n=e.match(/var\\((--[\\w-]+-ansi-[\\w-]+)\\)/);return n?`var(${n[1]}-dim)`:e}function Ai(e,t,n={}){const{theme:a=e.getLoadedThemes()[0]}=n,r=e.resolveLangAlias(n.lang||\"text\");if($i(r)||ji(a))return Na(t).map(c=>[{content:c[0],offset:c[1]}]);const{theme:i,colorMap:s}=e.setTheme(a);if(r===\"ansi\")return df(i,t,n);const o=e.getLanguage(n.lang||\"text\");if(n.grammarState){if(n.grammarState.lang!==o.name)throw new Y(`Grammar state language \"${n.grammarState.lang}\" does not match highlight language \"${o.name}\"`);if(!n.grammarState.themes.includes(i.name))throw new Y(`Grammar state themes \"${n.grammarState.themes}\" do not contain highlight theme \"${i.name}\"`)}return gf(t,o,i,s,n)}function hf(...e){if(e.length===2)return Cn(e[1]);const[t,n,a={}]=e,{lang:r=\"text\",theme:i=t.getLoadedThemes()[0]}=a;if($i(r)||ji(i))throw new Y(\"Plain language does not have grammar state\");if(r===\"ansi\")throw new Y(\"ANSI language does not have grammar state\");const{theme:s,colorMap:o}=t.setTheme(i),c=t.getLanguage(r);return new Vt(Ti(n,c,s,o,a).stateStack,c.name,s.name)}function gf(e,t,n,a,r){const i=Ti(e,t,n,a,r),s=new Vt(i.stateStack,t.name,n.name);return Ia(i.tokens,s),i.tokens}function Ti(e,t,n,a,r){const i=ya(n,r),{tokenizeMaxLineLength:s=0,tokenizeTimeLimit:o=500}=r,c=Na(e);let l=r.grammarState?ef(r.grammarState,n.name)??Nr:r.grammarContextCode!=null?Ti(r.grammarContextCode,t,n,a,{...r,grammarState:void 0,grammarContextCode:void 0}).stateStack:Nr,u=[];const p=[];for(let m=0,h=c.length;m<h;m++){const[g,_]=c[m];if(g===\"\"){u=[],p.push([]);continue}if(s>0&&g.length>=s){u=[],p.push([{content:g,offset:_,color:\"\",fontStyle:0}]);continue}let f,b,w;r.includeExplanation&&(f=t.tokenizeLine(g,l,o),b=f.tokens,w=0);const y=t.tokenizeLine2(g,l,o),d=y.tokens.length/2;for(let C=0;C<d;C++){const k=y.tokens[2*C],$=C+1<d?y.tokens[2*C+2]:g.length;if(k===$)continue;const T=y.tokens[2*C+1],I=Ge(a[qt.getForeground(T)],i),N=qt.getFontStyle(T),D={content:g.substring(k,$),offset:_+k,color:I,fontStyle:N};if(r.includeExplanation){const R=[];if(r.includeExplanation!==\"scopeName\")for(const q of n.settings){let U;switch(typeof q.scope){case\"string\":U=q.scope.split(/,/).map(G=>G.trim());break;case\"object\":U=q.scope;break;default:continue}R.push({settings:q,selectors:U.map(G=>G.split(/ /))})}D.explanation=[];let L=0;for(;k+L<$;){const q=b[w],U=g.substring(q.startIndex,q.endIndex);L+=U.length,D.explanation.push({content:U,scopes:r.includeExplanation===\"scopeName\"?ff(q.scopes):bf(R,q.scopes)}),w+=1}}u.push(D)}p.push(u),u=[],l=y.ruleStack}return{tokens:p,stateStack:l}}function ff(e){return e.map(t=>({scopeName:t}))}function bf(e,t){const n=[];for(let a=0,r=t.length;a<r;a++){const i=t[a];n[a]={scopeName:i,themeMatches:yf(e,i,t.slice(0,a))}}return n}function Ns(e,t){return e===t||t.substring(0,e.length)===e&&t[e.length]===\".\"}function _f(e,t,n){if(!Ns(e[e.length-1],t))return!1;let a=e.length-2,r=n.length-1;for(;a>=0&&r>=0;)Ns(e[a],n[r])&&(a-=1),r-=1;return a===-1}function yf(e,t,n){const a=[];for(const{selectors:r,settings:i}of e)for(const s of r)if(_f(s,t,n)){a.push(i);break}return a}function fl(e,t,n){const a=Object.entries(n.themes).filter(c=>c[1]).map(c=>({color:c[0],theme:c[1]})),r=a.map(c=>{const l=Ai(e,t,{...n,theme:c.theme}),u=Cn(l),p=typeof c.theme==\"string\"?c.theme:c.theme.name;return{tokens:l,state:u,theme:p}}),i=vf(...r.map(c=>c.tokens)),s=i[0].map((c,l)=>c.map((u,p)=>{const m={content:u.content,variants:{},offset:u.offset};return\"includeExplanation\"in n&&n.includeExplanation&&(m.explanation=u.explanation),i.forEach((h,g)=>{const{content:_,explanation:f,offset:b,...w}=h[l][p];m.variants[a[g].color]=w}),m})),o=r[0].state?new Vt(Object.fromEntries(r.map(c=>[c.theme,c.state?.getInternalStack(c.theme)])),r[0].state.lang):void 0;return o&&Ia(s,o),s}function vf(...e){const t=e.map(()=>[]),n=e.length;for(let a=0;a<e[0].length;a++){const r=e.map(c=>c[a]),i=t.map(()=>[]);t.forEach((c,l)=>c.push(i[l]));const s=r.map(()=>0),o=r.map(c=>c[0]);for(;o.every(c=>c);){const c=Math.min(...o.map(l=>l.content.length));for(let l=0;l<n;l++){const u=o[l];u.content.length===c?(i[l].push(u),s[l]+=1,o[l]=r[l][s[l]]):(i[l].push({...u,content:u.content.slice(0,c)}),o[l]={...u,content:u.content.slice(c),offset:u.offset+c})}}}return t}function xa(e,t,n){let a,r,i,s,o,c;if(\"themes\"in n){const{defaultColor:l=\"light\",cssVariablePrefix:u=\"--shiki-\",colorsRendering:p=\"css-vars\"}=n,m=Object.entries(n.themes).filter(b=>b[1]).map(b=>({color:b[0],theme:b[1]})).sort((b,w)=>b.color===l?-1:w.color===l?1:0);if(m.length===0)throw new Y(\"`themes` option must not be empty\");const h=fl(e,t,n);if(c=Cn(h),l&&Si!==l&&!m.find(b=>b.color===l))throw new Y(`\\`themes\\` option must contain the defaultColor key \\`${l}\\``);const g=m.map(b=>e.getTheme(b.theme)),_=m.map(b=>b.color);i=h.map(b=>b.map(w=>Qg(w,_,u,l,p))),c&&Ia(i,c);const f=m.map(b=>ya(b.theme,n));r=Is(m,g,f,u,l,\"fg\",p),a=Is(m,g,f,u,l,\"bg\",p),s=`shiki-themes ${g.map(b=>b.name).join(\" \")}`,o=l?void 0:[r,a].join(\";\")}else if(\"theme\"in n){const l=ya(n.theme,n);i=Ai(e,t,n);const u=e.getTheme(n.theme);a=Ge(u.bg,l),r=Ge(u.fg,l),s=u.name,c=Cn(i)}else throw new Y(\"Invalid options, either `theme` or `themes` must be provided\");return{tokens:i,fg:r,bg:a,themeName:s,rootStyle:o,grammarState:c}}function Is(e,t,n,a,r,i,s){return e.map((o,c)=>{const l=Ge(t[c][i],n[c])||\"inherit\",u=`${a+o.color}${i===\"bg\"?\"-bg\":\"\"}:${l}`;if(c===0&&r){if(r===Si&&e.length>1){const p=e.findIndex(_=>_.color===\"light\"),m=e.findIndex(_=>_.color===\"dark\");if(p===-1||m===-1)throw new Y('When using `defaultColor: \"light-dark()\"`, you must provide both `light` and `dark` themes');const h=Ge(t[p][i],n[p])||\"inherit\",g=Ge(t[m][i],n[m])||\"inherit\";return`light-dark(${h}, ${g});${u}`}return l}return s===\"css-vars\"?u:null}).filter(o=>!!o).join(\";\")}function ka(e,t,n,a={meta:{},options:n,codeToHast:(r,i)=>ka(e,r,i),codeToTokens:(r,i)=>xa(e,r,i)}){let r=t;for(const g of wa(n))r=g.preprocess?.call(a,r,n)||r;let{tokens:i,fg:s,bg:o,themeName:c,rootStyle:l,grammarState:u}=xa(e,r,n);const{mergeWhitespaces:p=!0,mergeSameStyleTokens:m=!1}=n;p===!0?i=xf(i):p===\"never\"&&(i=kf(i)),m&&(i=Cf(i));const h={...a,get source(){return r}};for(const g of wa(n))i=g.tokens?.call(h,i)||i;return wf(i,{...n,fg:s,bg:o,themeName:c,rootStyle:n.rootStyle===!1?!1:n.rootStyle??l},h,u)}function wf(e,t,n,a=Cn(e)){const r=wa(t),i=[],s={type:\"root\",children:[]},{structure:o=\"classic\",tabindex:c=\"0\"}=t,l={class:`shiki ${t.themeName||\"\"}`};t.rootStyle!==!1&&(t.rootStyle!=null?l.style=t.rootStyle:l.style=`background-color:${t.bg};color:${t.fg}`),c!==!1&&c!=null&&(l.tabindex=c.toString());for(const[_,f]of Object.entries(t.meta||{}))_.startsWith(\"_\")||(l[_]=f);let u={type:\"element\",tagName:\"pre\",properties:l,children:[],data:t.data},p={type:\"element\",tagName:\"code\",properties:{},children:i};const m=[],h={...n,structure:o,addClassToHast:ml,get source(){return n.source},get tokens(){return e},get options(){return t},get root(){return s},get pre(){return u},get code(){return p},get lines(){return m}};if(e.forEach((_,f)=>{f&&(o===\"inline\"?s.children.push({type:\"element\",tagName:\"br\",properties:{},children:[]}):o===\"classic\"&&i.push({type:\"text\",value:`\n`}));let b={type:\"element\",tagName:\"span\",properties:{class:\"line\"},children:[]},w=0;for(const y of _){let d={type:\"element\",tagName:\"span\",properties:{...y.htmlAttrs},children:[{type:\"text\",value:y.content}]};const C=Mr(y.htmlStyle||va(y));C&&(d.properties.style=C);for(const k of r)d=k?.span?.call(h,d,f+1,w,b,y)||d;o===\"inline\"?s.children.push(d):o===\"classic\"&&b.children.push(d),w+=y.content.length}if(o===\"classic\"){for(const y of r)b=y?.line?.call(h,b,f+1)||b;m.push(b),i.push(b)}else o===\"inline\"&&m.push(b)}),o===\"classic\"){for(const _ of r)p=_?.code?.call(h,p)||p;u.children.push(p);for(const _ of r)u=_?.pre?.call(h,u)||u;s.children.push(u)}else if(o===\"inline\"){const _=[];let f={type:\"element\",tagName:\"span\",properties:{class:\"line\"},children:[]};for(const y of s.children)y.type===\"element\"&&y.tagName===\"br\"?(_.push(f),f={type:\"element\",tagName:\"span\",properties:{class:\"line\"},children:[]}):(y.type===\"element\"||y.type===\"text\")&&f.children.push(y);_.push(f);let w={type:\"element\",tagName:\"code\",properties:{},children:_};for(const y of r)w=y?.code?.call(h,w)||w;s.children=[];for(let y=0;y<w.children.length;y++){y>0&&s.children.push({type:\"element\",tagName:\"br\",properties:{},children:[]});const d=w.children[y];d.type===\"element\"&&s.children.push(...d.children)}}let g=s;for(const _ of r)g=_?.root?.call(h,g)||g;return a&&Ia(g,a),g}function xf(e){return e.map(t=>{const n=[];let a=\"\",r;return t.forEach((i,s)=>{const c=!(i.fontStyle&&(i.fontStyle&ee.Underline||i.fontStyle&ee.Strikethrough));c&&i.content.match(/^\\s+$/)&&t[s+1]?(r===void 0&&(r=i.offset),a+=i.content):a?(c?n.push({...i,offset:r,content:a+i.content}):n.push({content:a,offset:r},i),r=void 0,a=\"\"):n.push(i)}),n})}function kf(e){return e.map(t=>t.flatMap(n=>{if(n.content.match(/^\\s+$/))return n;const a=n.content.match(/^(\\s*)(.*?)(\\s*)$/);if(!a)return n;const[,r,i,s]=a;if(!r&&!s)return n;const o=[{...n,offset:n.offset+r.length,content:i}];return r&&o.unshift({content:r,offset:n.offset}),s&&o.push({content:s,offset:n.offset+r.length+i.length}),o}))}function Cf(e){return e.map(t=>{const n=[];for(const a of t){if(n.length===0){n.push({...a});continue}const r=n[n.length-1],i=Mr(r.htmlStyle||va(r)),s=Mr(a.htmlStyle||va(a)),o=r.fontStyle&&(r.fontStyle&ee.Underline||r.fontStyle&ee.Strikethrough),c=a.fontStyle&&(a.fontStyle&ee.Underline||a.fontStyle&ee.Strikethrough);!o&&!c&&i===s?r.content+=a.content:n.push({...a})}return n})}const Ef=Bg;function Ff(e,t,n){const a={meta:{},options:n,codeToHast:(i,s)=>ka(e,i,s),codeToTokens:(i,s)=>xa(e,i,s)};let r=Ef(ka(e,t,n,a));for(const i of wa(n))r=i.postprocess?.call(a,r,n)||r;return r}const Ls={light:\"#333333\",dark:\"#bbbbbb\"},Ps={light:\"#fffffe\",dark:\"#1e1e1e\"},Ds=\"__shiki_resolved\";function Ri(e){if(e?.[Ds])return e;const t={...e};t.tokenColors&&!t.settings&&(t.settings=t.tokenColors,delete t.tokenColors),t.type||=\"dark\",t.colorReplacements={...t.colorReplacements},t.settings||=[];let{bg:n,fg:a}=t;if(!n||!a){const o=t.settings?t.settings.find(c=>!c.name&&!c.scope):void 0;o?.settings?.foreground&&(a=o.settings.foreground),o?.settings?.background&&(n=o.settings.background),!a&&t?.colors?.[\"editor.foreground\"]&&(a=t.colors[\"editor.foreground\"]),!n&&t?.colors?.[\"editor.background\"]&&(n=t.colors[\"editor.background\"]),a||(a=t.type===\"light\"?Ls.light:Ls.dark),n||(n=t.type===\"light\"?Ps.light:Ps.dark),t.fg=a,t.bg=n}t.settings[0]&&t.settings[0].settings&&!t.settings[0].scope||t.settings.unshift({settings:{foreground:t.fg,background:t.bg}});let r=0;const i=new Map;function s(o){if(i.has(o))return i.get(o);r+=1;const c=`#${r.toString(16).padStart(8,\"0\").toLowerCase()}`;return t.colorReplacements?.[`#${c}`]?s(o):(i.set(o,c),c)}t.settings=t.settings.map(o=>{const c=o.settings?.foreground&&!o.settings.foreground.startsWith(\"#\"),l=o.settings?.background&&!o.settings.background.startsWith(\"#\");if(!c&&!l)return o;const u={...o,settings:{...o.settings}};if(c){const p=s(o.settings.foreground);t.colorReplacements[p]=o.settings.foreground,u.settings.foreground=p}if(l){const p=s(o.settings.background);t.colorReplacements[p]=o.settings.background,u.settings.background=p}return u});for(const o of Object.keys(t.colors||{}))if((o===\"editor.foreground\"||o===\"editor.background\"||o.startsWith(\"terminal.ansi\"))&&!t.colors[o]?.startsWith(\"#\")){const c=s(t.colors[o]);t.colorReplacements[c]=t.colors[o],t.colors[o]=c}return Object.defineProperty(t,Ds,{enumerable:!1,writable:!1,value:!0}),t}async function $f(e){return Array.from(new Set((await Promise.all(e.filter(t=>!Wg(t)).map(async t=>await dl(t).then(n=>Array.isArray(n)?n:[n])))).flat()))}async function jf(e){return(await Promise.all(e.map(async n=>Vg(n)?null:Ri(await dl(n))))).filter(n=>!!n)}class Tt extends Error{constructor(t){super(t),this.name=\"ShikiError\"}}function bl(e,t){if(!t)return e;if(t[e]){const n=new Set([e]);for(;t[e];){if(e=t[e],n.has(e))throw new Tt(`Circular alias \\`${Array.from(n).join(\" -> \")} -> ${e}\\``);n.add(e)}}return e}class Sf extends jh{constructor(t,n,a,r={}){super(t),this._resolver=t,this._themes=n,this._langs=a,this._alias=r,this._themes.map(i=>this.loadTheme(i)),this.loadLanguages(this._langs)}_resolvedThemes=new Map;_resolvedGrammars=new Map;_langMap=new Map;_langGraph=new Map;_textmateThemeCache=new WeakMap;_loadedThemesCache=null;_loadedLanguagesCache=null;getTheme(t){return typeof t==\"string\"?this._resolvedThemes.get(t):this.loadTheme(t)}loadTheme(t){const n=Ri(t);return n.name&&(this._resolvedThemes.set(n.name,n),this._loadedThemesCache=null),n}getLoadedThemes(){return this._loadedThemesCache||(this._loadedThemesCache=[...this._resolvedThemes.keys()]),this._loadedThemesCache}setTheme(t){let n=this._textmateThemeCache.get(t);n||(n=ha.createFromRawTheme(t),this._textmateThemeCache.set(t,n)),this._syncRegistry.setTheme(n)}getGrammar(t){return t=bl(t,this._alias),this._resolvedGrammars.get(t)}loadLanguage(t){if(this.getGrammar(t.name))return;const n=new Set([...this._langMap.values()].filter(i=>i.embeddedLangsLazy?.includes(t.name)));this._resolver.addLanguage(t);const a={balancedBracketSelectors:t.balancedBracketSelectors||[\"*\"],unbalancedBracketSelectors:t.unbalancedBracketSelectors||[]};this._syncRegistry._rawGrammars.set(t.scopeName,t);const r=this.loadGrammarWithConfiguration(t.scopeName,1,a);if(r.name=t.name,this._resolvedGrammars.set(t.name,r),t.aliases&&t.aliases.forEach(i=>{this._alias[i]=t.name}),this._loadedLanguagesCache=null,n.size)for(const i of n)this._resolvedGrammars.delete(i.name),this._loadedLanguagesCache=null,this._syncRegistry?._injectionGrammars?.delete(i.scopeName),this._syncRegistry?._grammars?.delete(i.scopeName),this.loadLanguage(this._langMap.get(i.name))}dispose(){super.dispose(),this._resolvedThemes.clear(),this._resolvedGrammars.clear(),this._langMap.clear(),this._langGraph.clear(),this._loadedThemesCache=null}loadLanguages(t){for(const r of t)this.resolveEmbeddedLanguages(r);const n=Array.from(this._langGraph.entries()),a=n.filter(([r,i])=>!i);if(a.length){const r=n.filter(([i,s])=>s?(s.embeddedLanguages||s.embeddedLangs)?.some(c=>a.map(([l])=>l).includes(c)):!1).filter(i=>!a.includes(i));throw new Tt(`Missing languages ${a.map(([i])=>`\\`${i}\\``).join(\", \")}, required by ${r.map(([i])=>`\\`${i}\\``).join(\", \")}`)}for(const[r,i]of n)this._resolver.addLanguage(i);for(const[r,i]of n)this.loadLanguage(i)}getLoadedLanguages(){return this._loadedLanguagesCache||(this._loadedLanguagesCache=[...new Set([...this._resolvedGrammars.keys(),...Object.keys(this._alias)])]),this._loadedLanguagesCache}resolveEmbeddedLanguages(t){this._langMap.set(t.name,t),this._langGraph.set(t.name,t);const n=t.embeddedLanguages??t.embeddedLangs;if(n)for(const a of n)this._langGraph.set(a,this._langMap.get(a))}}class Af{_langs=new Map;_scopeToLang=new Map;_injections=new Map;_onigLib;constructor(t,n){this._onigLib={createOnigScanner:a=>t.createScanner(a),createOnigString:a=>t.createString(a)},n.forEach(a=>this.addLanguage(a))}get onigLib(){return this._onigLib}getLangRegistration(t){return this._langs.get(t)}loadGrammar(t){return this._scopeToLang.get(t)}addLanguage(t){this._langs.set(t.name,t),t.aliases&&t.aliases.forEach(n=>{this._langs.set(n,t)}),this._scopeToLang.set(t.scopeName,t),t.injectTo&&t.injectTo.forEach(n=>{this._injections.get(n)||this._injections.set(n,[]),this._injections.get(n).push(t.scopeName)})}getInjections(t){const n=t.split(\".\");let a=[];for(let r=1;r<=n.length;r++){const i=n.slice(0,r).join(\".\");a=[...a,...this._injections.get(i)||[]]}return a}}let sn=0;function Tf(e){sn+=1,e.warnings!==!1&&sn>=10&&sn%10===0&&console.warn(`[Shiki] ${sn} instances have been created. Shiki is supposed to be used as a singleton, consider refactoring your code to cache your highlighter instance; Or call \\`highlighter.dispose()\\` to release unused instances.`);let t=!1;if(!e.engine)throw new Tt(\"`engine` option is required for synchronous mode\");const n=(e.langs||[]).flat(1),a=(e.themes||[]).flat(1).map(Ri),r=new Af(e.engine,n),i=new Sf(r,a,n,e.langAlias);let s;function o(y){return bl(y,e.langAlias)}function c(y){b();const d=i.getGrammar(typeof y==\"string\"?y:y.name);if(!d)throw new Tt(`Language \\`${y}\\` not found, you may need to load it first`);return d}function l(y){if(y===\"none\")return{bg:\"\",fg:\"\",name:\"none\",settings:[],type:\"dark\"};b();const d=i.getTheme(y);if(!d)throw new Tt(`Theme \\`${y}\\` not found, you may need to load it first`);return d}function u(y){b();const d=l(y);s!==y&&(i.setTheme(d),s=y);const C=i.getColorMap();return{theme:d,colorMap:C}}function p(){return b(),i.getLoadedThemes()}function m(){return b(),i.getLoadedLanguages()}function h(...y){b(),i.loadLanguages(y.flat(1))}async function g(...y){return h(await $f(y))}function _(...y){b();for(const d of y.flat(1))i.loadTheme(d)}async function f(...y){return b(),_(await jf(y))}function b(){if(t)throw new Tt(\"Shiki instance has been disposed\")}function w(){t||(t=!0,i.dispose(),sn-=1)}return{setTheme:u,getTheme:l,getLanguage:c,getLoadedThemes:p,getLoadedLanguages:m,resolveLangAlias:o,loadLanguage:g,loadLanguageSync:h,loadTheme:f,loadThemeSync:_,dispose:w,[Symbol.dispose]:w}}function Rf(e){const t=Tf(e);return{getLastGrammarState:(...n)=>hf(t,...n),codeToTokensBase:(n,a)=>Ai(t,n,a),codeToTokensWithThemes:(n,a)=>fl(t,n,a),codeToTokens:(n,a)=>xa(t,n,a),codeToHast:(n,a)=>ka(t,n,a),codeToHtml:(n,a)=>Ff(t,n,a),getBundledLanguages:()=>({}),getBundledThemes:()=>({}),...t,getInternalContext:()=>t}}function Zt(e){if([...e].length!==1)throw new Error(`Expected \"${e}\" to be a single code point`);return e.codePointAt(0)}function Of(e,t,n){return e.has(t)||e.set(t,n),e.get(t)}const Oi=new Set([\"alnum\",\"alpha\",\"ascii\",\"blank\",\"cntrl\",\"digit\",\"graph\",\"lower\",\"print\",\"punct\",\"space\",\"upper\",\"word\",\"xdigit\"]),X=String.raw;function Yt(e,t){if(e==null)throw new Error(t??\"Value expected\");return e}const _l=X`\\[\\^?`,yl=`c.? | C(?:-.?)?|${X`[pP]\\{(?:\\^?[-\\x20_]*[A-Za-z][-\\x20\\w]*\\})?`}|${X`x[89A-Fa-f]\\p{AHex}(?:\\\\x[89A-Fa-f]\\p{AHex})*`}|${X`u(?:\\p{AHex}{4})? | x\\{[^\\}]*\\}? | x\\p{AHex}{0,2}`}|${X`o\\{[^\\}]*\\}?`}|${X`\\d{1,3}`}`,Ni=/[?*+][?+]?|\\{(?:\\d+(?:,\\d*)?|,\\d+)\\}\\??/,ta=new RegExp(X`\n  \\\\ (?:\n    ${yl}\n    | [gk]<[^>]*>?\n    | [gk]'[^']*'?\n    | .\n  )\n  | \\( (?:\n    \\? (?:\n      [:=!>({]\n      | <[=!]\n      | <[^>]*>\n      | '[^']*'\n      | ~\\|?\n      | #(?:[^)\\\\]|\\\\.?)*\n      | [^:)]*[:)]\n    )?\n    | \\*[^\\)]*\\)?\n  )?\n  | (?:${Ni.source})+\n  | ${_l}\n  | .\n`.replace(/\\s+/g,\"\"),\"gsu\"),nr=new RegExp(X`\n  \\\\ (?:\n    ${yl}\n    | .\n  )\n  | \\[:(?:\\^?\\p{Alpha}+|\\^):\\]\n  | ${_l}\n  | &&\n  | .\n`.replace(/\\s+/g,\"\"),\"gsu\");function Nf(e,t={}){const n={flags:\"\",...t,rules:{captureGroup:!1,singleline:!1,...t.rules}};if(typeof e!=\"string\")throw new Error(\"String expected as pattern\");const a=Jf(n.flags),r=[a.extended],i={captureGroup:n.rules.captureGroup,getCurrentModX(){return r.at(-1)},numOpenGroups:0,popModX(){r.pop()},pushModX(p){r.push(p)},replaceCurrentModX(p){r[r.length-1]=p},singleline:n.rules.singleline};let s=[],o;for(ta.lastIndex=0;o=ta.exec(e);){const p=If(i,e,o[0],ta.lastIndex);p.tokens?s.push(...p.tokens):p.token&&s.push(p.token),p.lastIndex!==void 0&&(ta.lastIndex=p.lastIndex)}const c=[];let l=0;s.filter(p=>p.type===\"GroupOpen\").forEach(p=>{p.kind===\"capturing\"?p.number=++l:p.raw===\"(\"&&c.push(p)}),l||c.forEach((p,m)=>{p.kind=\"capturing\",p.number=m+1});const u=l||c.length;return{tokens:s.map(p=>p.type===\"EscapedNumber\"?tb(p,u):p).flat(),flags:a}}function If(e,t,n,a){const[r,i]=n;if(n===\"[\"||n===\"[^\"){const s=Lf(t,n,a);return{tokens:s.tokens,lastIndex:s.lastIndex}}if(r===\"\\\\\"){if(\"AbBGyYzZ\".includes(i))return{token:Ms(n,n)};if(/^\\\\g[<']/.test(n)){if(!/^\\\\g(?:<[^>]+>|'[^']+')$/.test(n))throw new Error(`Invalid group name \"${n}\"`);return{token:Wf(n)}}if(/^\\\\k[<']/.test(n)){if(!/^\\\\k(?:<[^>]+>|'[^']+')$/.test(n))throw new Error(`Invalid group name \"${n}\"`);return{token:wl(n)}}if(i===\"K\")return{token:xl(\"keep\",n)};if(i===\"N\"||i===\"R\")return{token:st(\"newline\",n,{negate:i===\"N\"})};if(i===\"O\")return{token:st(\"any\",n)};if(i===\"X\")return{token:st(\"text_segment\",n)};const s=vl(n,{inCharClass:!1});return Array.isArray(s)?{tokens:s}:{token:s}}if(r===\"(\"){if(i===\"*\")return{token:Xf(n)};if(n===\"(?{\")throw new Error(`Unsupported callout \"${n}\"`);if(n.startsWith(\"(?#\")){if(t[a]!==\")\")throw new Error('Unclosed comment group \"(?#\"');return{lastIndex:a+1}}if(/^\\(\\?[-imx]+[:)]$/.test(n))return{token:Yf(n,e)};if(e.pushModX(e.getCurrentModX()),e.numOpenGroups++,n===\"(\"&&!e.captureGroup||n===\"(?:\")return{token:St(\"group\",n)};if(n===\"(?>\")return{token:St(\"atomic\",n)};if(n===\"(?=\"||n===\"(?!\"||n===\"(?<=\"||n===\"(?<!\")return{token:St(n[2]===\"<\"?\"lookbehind\":\"lookahead\",n,{negate:n.endsWith(\"!\")})};if(n===\"(\"&&e.captureGroup||n.startsWith(\"(?<\")&&n.endsWith(\">\")||n.startsWith(\"(?'\")&&n.endsWith(\"'\"))return{token:St(\"capturing\",n,{...n!==\"(\"&&{name:n.slice(3,-1)}})};if(n.startsWith(\"(?~\")){if(n===\"(?~|\")throw new Error(`Unsupported absence function kind \"${n}\"`);return{token:St(\"absence_repeater\",n)}}throw n===\"(?(\"?new Error(`Unsupported conditional \"${n}\"`):new Error(`Invalid or unsupported group option \"${n}\"`)}if(n===\")\"){if(e.popModX(),e.numOpenGroups--,e.numOpenGroups<0)throw new Error('Unmatched \")\"');return{token:Uf(n)}}if(e.getCurrentModX()){if(n===\"#\"){const s=t.indexOf(`\n`,a);return{lastIndex:s===-1?t.length:s}}if(/^\\s$/.test(n)){const s=/\\s+/y;return s.lastIndex=a,{lastIndex:s.exec(t)?s.lastIndex:a}}}if(n===\".\")return{token:st(\"dot\",n)};if(n===\"^\"||n===\"$\"){const s=e.singleline?{\"^\":X`\\A`,$:X`\\Z`}[n]:n;return{token:Ms(s,n)}}return n===\"|\"?{token:Df(n)}:Ni.test(n)?{tokens:nb(n)}:{token:Ie(Zt(n),n)}}function Lf(e,t,n){const a=[qs(t[1]===\"^\",t)];let r=1,i;for(nr.lastIndex=n;i=nr.exec(e);){const s=i[0];if(s[0]===\"[\"&&s[1]!==\":\")r++,a.push(qs(s[1]===\"^\",s));else if(s===\"]\"){if(a.at(-1).type===\"CharacterClassOpen\")a.push(Ie(93,s));else if(r--,a.push(Mf(s)),!r)break}else{const o=Pf(s);Array.isArray(o)?a.push(...o):a.push(o)}}return{tokens:a,lastIndex:nr.lastIndex||e.length}}function Pf(e){if(e[0]===\"\\\\\")return vl(e,{inCharClass:!0});if(e[0]===\"[\"){const t=/\\[:(?<negate>\\^?)(?<name>[a-z]+):\\]/.exec(e);if(!t||!Oi.has(t.groups.name))throw new Error(`Invalid POSIX class \"${e}\"`);return st(\"posix\",e,{value:t.groups.name,negate:!!t.groups.negate})}return e===\"-\"?qf(e):e===\"&&\"?zf(e):Ie(Zt(e),e)}function vl(e,{inCharClass:t}){const n=e[1];if(n===\"c\"||n===\"C\")return Zf(e);if(\"dDhHsSwW\".includes(n))return Kf(e);if(e.startsWith(X`\\o{`))throw new Error(`Incomplete, invalid, or unsupported octal code point \"${e}\"`);if(/^\\\\[pP]\\{/.test(e)){if(e.length===3)throw new Error(`Incomplete or invalid Unicode property \"${e}\"`);return Qf(e)}if(new RegExp(\"^\\\\\\\\x[89A-Fa-f]\\\\p{AHex}\",\"u\").test(e))try{const a=e.split(/\\\\x/).slice(1).map(s=>parseInt(s,16)),r=new TextDecoder(\"utf-8\",{ignoreBOM:!0,fatal:!0}).decode(new Uint8Array(a)),i=new TextEncoder;return[...r].map(s=>{const o=[...i.encode(s)].map(c=>`\\\\x${c.toString(16)}`).join(\"\");return Ie(Zt(s),o)})}catch{throw new Error(`Multibyte code \"${e}\" incomplete or invalid in Oniguruma`)}if(n===\"u\"||n===\"x\")return Ie(eb(e),e);if(zs.has(n))return Ie(zs.get(n),e);if(/\\d/.test(n))return Bf(t,e);if(e===\"\\\\\")throw new Error(X`Incomplete escape \"\\\"`);if(n===\"M\")throw new Error(`Unsupported meta \"${e}\"`);if([...e].length===2)return Ie(e.codePointAt(1),e);throw new Error(`Unexpected escape \"${e}\"`)}function Df(e){return{type:\"Alternator\",raw:e}}function Ms(e,t){return{type:\"Assertion\",kind:e,raw:t}}function wl(e){return{type:\"Backreference\",raw:e}}function Ie(e,t){return{type:\"Character\",value:e,raw:t}}function Mf(e){return{type:\"CharacterClassClose\",raw:e}}function qf(e){return{type:\"CharacterClassHyphen\",raw:e}}function zf(e){return{type:\"CharacterClassIntersector\",raw:e}}function qs(e,t){return{type:\"CharacterClassOpen\",negate:e,raw:t}}function st(e,t,n={}){return{type:\"CharacterSet\",kind:e,...n,raw:t}}function xl(e,t,n={}){return e===\"keep\"?{type:\"Directive\",kind:e,raw:t}:{type:\"Directive\",kind:e,flags:Yt(n.flags),raw:t}}function Bf(e,t){return{type:\"EscapedNumber\",inCharClass:e,raw:t}}function Uf(e){return{type:\"GroupClose\",raw:e}}function St(e,t,n={}){return{type:\"GroupOpen\",kind:e,...n,raw:t}}function Gf(e,t,n,a){return{type:\"NamedCallout\",kind:e,tag:t,arguments:n,raw:a}}function Hf(e,t,n,a){return{type:\"Quantifier\",kind:e,min:t,max:n,raw:a}}function Wf(e){return{type:\"Subroutine\",raw:e}}const Vf=new Set([\"COUNT\",\"CMP\",\"ERROR\",\"FAIL\",\"MAX\",\"MISMATCH\",\"SKIP\",\"TOTAL_COUNT\"]),zs=new Map([[\"a\",7],[\"b\",8],[\"e\",27],[\"f\",12],[\"n\",10],[\"r\",13],[\"t\",9],[\"v\",11]]);function Zf(e){const t=e[1]===\"c\"?e[2]:e[3];if(!t||!/[A-Za-z]/.test(t))throw new Error(`Unsupported control character \"${e}\"`);return Ie(Zt(t.toUpperCase())-64,e)}function Yf(e,t){let{on:n,off:a}=/^\\(\\?(?<on>[imx]*)(?:-(?<off>[-imx]*))?/.exec(e).groups;a??=\"\";const r=(t.getCurrentModX()||n.includes(\"x\"))&&!a.includes(\"x\"),i=Us(n),s=Us(a),o={};if(i&&(o.enable=i),s&&(o.disable=s),e.endsWith(\")\"))return t.replaceCurrentModX(r),xl(\"flags\",e,{flags:o});if(e.endsWith(\":\"))return t.pushModX(r),t.numOpenGroups++,St(\"group\",e,{...(i||s)&&{flags:o}});throw new Error(`Unexpected flag modifier \"${e}\"`)}function Xf(e){const t=/\\(\\*(?<name>[A-Za-z_]\\w*)?(?:\\[(?<tag>(?:[A-Za-z_]\\w*)?)\\])?(?:\\{(?<args>[^}]*)\\})?\\)/.exec(e);if(!t)throw new Error(`Incomplete or invalid named callout \"${e}\"`);const{name:n,tag:a,args:r}=t.groups;if(!n)throw new Error(`Invalid named callout \"${e}\"`);if(a===\"\")throw new Error(`Named callout tag with empty value not allowed \"${e}\"`);const i=r?r.split(\",\").filter(u=>u!==\"\").map(u=>/^[+-]?\\d+$/.test(u)?+u:u):[],[s,o,c]=i,l=Vf.has(n)?n.toLowerCase():\"custom\";switch(l){case\"fail\":case\"mismatch\":case\"skip\":if(i.length>0)throw new Error(`Named callout arguments not allowed \"${i}\"`);break;case\"error\":if(i.length>1)throw new Error(`Named callout allows only one argument \"${i}\"`);if(typeof s==\"string\")throw new Error(`Named callout argument must be a number \"${s}\"`);break;case\"max\":if(!i.length||i.length>2)throw new Error(`Named callout must have one or two arguments \"${i}\"`);if(typeof s==\"string\"&&!/^[A-Za-z_]\\w*$/.test(s))throw new Error(`Named callout argument one must be a tag or number \"${s}\"`);if(i.length===2&&(typeof o==\"number\"||!/^[<>X]$/.test(o)))throw new Error(`Named callout optional argument two must be '<', '>', or 'X' \"${o}\"`);break;case\"count\":case\"total_count\":if(i.length>1)throw new Error(`Named callout allows only one argument \"${i}\"`);if(i.length===1&&(typeof s==\"number\"||!/^[<>X]$/.test(s)))throw new Error(`Named callout optional argument must be '<', '>', or 'X' \"${s}\"`);break;case\"cmp\":if(i.length!==3)throw new Error(`Named callout must have three arguments \"${i}\"`);if(typeof s==\"string\"&&!/^[A-Za-z_]\\w*$/.test(s))throw new Error(`Named callout argument one must be a tag or number \"${s}\"`);if(typeof o==\"number\"||!/^(?:[<>!=]=|[<>])$/.test(o))throw new Error(`Named callout argument two must be '==', '!=', '>', '<', '>=', or '<=' \"${o}\"`);if(typeof c==\"string\"&&!/^[A-Za-z_]\\w*$/.test(c))throw new Error(`Named callout argument three must be a tag or number \"${c}\"`);break;case\"custom\":throw new Error(`Undefined callout name \"${n}\"`);default:throw new Error(`Unexpected named callout kind \"${l}\"`)}return Gf(l,a??null,r?.split(\",\")??null,e)}function Bs(e){let t=null,n,a;if(e[0]===\"{\"){const{minStr:r,maxStr:i}=/^\\{(?<minStr>\\d*)(?:,(?<maxStr>\\d*))?/.exec(e).groups,s=1e5;if(+r>s||i&&+i>s)throw new Error(\"Quantifier value unsupported in Oniguruma\");if(n=+r,a=i===void 0?+r:i===\"\"?1/0:+i,n>a&&(t=\"possessive\",[n,a]=[a,n]),e.endsWith(\"?\")){if(t===\"possessive\")throw new Error('Unsupported possessive interval quantifier chain with \"?\"');t=\"lazy\"}else t||(t=\"greedy\")}else n=e[0]===\"+\"?1:0,a=e[0]===\"?\"?1:1/0,t=e[1]===\"+\"?\"possessive\":e[1]===\"?\"?\"lazy\":\"greedy\";return Hf(t,n,a,e)}function Kf(e){const t=e[1].toLowerCase();return st({d:\"digit\",h:\"hex\",s:\"space\",w:\"word\"}[t],e,{negate:e[1]!==t})}function Qf(e){const{p:t,neg:n,value:a}=/^\\\\(?<p>[pP])\\{(?<neg>\\^?)(?<value>[^}]+)/.exec(e).groups;return st(\"property\",e,{value:a,negate:t===\"P\"&&!n||t===\"p\"&&!!n})}function Us(e){const t={};return e.includes(\"i\")&&(t.ignoreCase=!0),e.includes(\"m\")&&(t.dotAll=!0),e.includes(\"x\")&&(t.extended=!0),Object.keys(t).length?t:null}function Jf(e){const t={ignoreCase:!1,dotAll:!1,extended:!1,digitIsAscii:!1,posixIsAscii:!1,spaceIsAscii:!1,wordIsAscii:!1,textSegmentMode:null};for(let n=0;n<e.length;n++){const a=e[n];if(!\"imxDPSWy\".includes(a))throw new Error(`Invalid flag \"${a}\"`);if(a===\"y\"){if(!/^y{[gw]}/.test(e.slice(n)))throw new Error('Invalid or unspecified flag \"y\" mode');t.textSegmentMode=e[n+2]===\"g\"?\"grapheme\":\"word\",n+=3;continue}t[{i:\"ignoreCase\",m:\"dotAll\",x:\"extended\",D:\"digitIsAscii\",P:\"posixIsAscii\",S:\"spaceIsAscii\",W:\"wordIsAscii\"}[a]]=!0}return t}function eb(e){if(new RegExp(\"^(?:\\\\\\\\u(?!\\\\p{AHex}{4})|\\\\\\\\x(?!\\\\p{AHex}{1,2}|\\\\{\\\\p{AHex}{1,8}\\\\}))\",\"u\").test(e))throw new Error(`Incomplete or invalid escape \"${e}\"`);const t=e[2]===\"{\"?new RegExp(\"^\\\\\\\\x\\\\{\\\\s*(?<hex>\\\\p{AHex}+)\",\"u\").exec(e).groups.hex:e.slice(2);return parseInt(t,16)}function tb(e,t){const{raw:n,inCharClass:a}=e,r=n.slice(1);if(!a&&(r!==\"0\"&&r.length===1||r[0]!==\"0\"&&+r<=t))return[wl(n)];const i=[],s=r.match(/^[0-7]+|\\d/g);for(let o=0;o<s.length;o++){const c=s[o];let l;if(o===0&&c!==\"8\"&&c!==\"9\"){if(l=parseInt(c,8),l>127)throw new Error(X`Octal encoded byte above 177 unsupported \"${n}\"`)}else l=Zt(c);i.push(Ie(l,(o===0?\"\\\\\":\"\")+c))}return i}function nb(e){const t=[],n=new RegExp(Ni,\"gy\");let a;for(;a=n.exec(e);){const r=a[0];if(r[0]===\"{\"){const i=/^\\{(?<min>\\d+),(?<max>\\d+)\\}\\??$/.exec(r);if(i){const{min:s,max:o}=i.groups;if(+s>+o&&r.endsWith(\"?\")){n.lastIndex--,t.push(Bs(r.slice(0,-1)));continue}}}t.push(Bs(r))}return t}function kl(e,t){if(!Array.isArray(e.body))throw new Error(\"Expected node with body array\");if(e.body.length!==1)return!1;const n=e.body[0];return!t||Object.keys(t).every(a=>t[a]===n[a])}function ab(e){return rb.has(e.type)}const rb=new Set([\"AbsenceFunction\",\"Backreference\",\"CapturingGroup\",\"Character\",\"CharacterClass\",\"CharacterSet\",\"Group\",\"Quantifier\",\"Subroutine\"]);function Cl(e,t={}){const n={flags:\"\",normalizeUnknownPropertyNames:!1,skipBackrefValidation:!1,skipLookbehindValidation:!1,skipPropertyNameValidation:!1,unicodePropertyMap:null,...t,rules:{captureGroup:!1,singleline:!1,...t.rules}},a=Nf(e,{flags:n.flags,rules:{captureGroup:n.rules.captureGroup,singleline:n.rules.singleline}}),r=(m,h)=>{const g=a.tokens[i.nextIndex];switch(i.parent=m,i.nextIndex++,g.type){case\"Alternator\":return bt();case\"Assertion\":return ib(g);case\"Backreference\":return sb(g,i);case\"Character\":return La(g.value,{useLastValid:!!h.isCheckingRangeEnd});case\"CharacterClassHyphen\":return ob(g,i,h);case\"CharacterClassOpen\":return cb(g,i,h);case\"CharacterSet\":return lb(g,i);case\"Directive\":return gb(g.kind,{flags:g.flags});case\"GroupOpen\":return ub(g,i,h);case\"NamedCallout\":return bb(g.kind,g.tag,g.arguments);case\"Quantifier\":return pb(g,i);case\"Subroutine\":return db(g,i);default:throw new Error(`Unexpected token type \"${g.type}\"`)}},i={capturingGroups:[],hasNumberedRef:!1,namedGroupsByName:new Map,nextIndex:0,normalizeUnknownPropertyNames:n.normalizeUnknownPropertyNames,parent:null,skipBackrefValidation:n.skipBackrefValidation,skipLookbehindValidation:n.skipLookbehindValidation,skipPropertyNameValidation:n.skipPropertyNameValidation,subroutines:[],tokens:a.tokens,unicodePropertyMap:n.unicodePropertyMap,walk:r},s=yb(fb(a.flags));let o=s.body[0];for(;i.nextIndex<a.tokens.length;){const m=r(o,{});m.type===\"Alternative\"?(s.body.push(m),o=m):o.body.push(m)}const{capturingGroups:c,hasNumberedRef:l,namedGroupsByName:u,subroutines:p}=i;if(l&&u.size&&!n.rules.captureGroup)throw new Error(\"Numbered backref/subroutine not allowed when using named capture\");for(const{ref:m}of p)if(typeof m==\"number\"){if(m>c.length)throw new Error(\"Subroutine uses a group number that's not defined\");m&&(c[m-1].isSubroutined=!0)}else if(u.has(m)){if(u.get(m).length>1)throw new Error(X`Subroutine uses a duplicate group name \"\\g<${m}>\"`);u.get(m)[0].isSubroutined=!0}else throw new Error(X`Subroutine uses a group name that's not defined \"\\g<${m}>\"`);return s}function ib({kind:e}){return qr(Yt({\"^\":\"line_start\",$:\"line_end\",\"\\\\A\":\"string_start\",\"\\\\b\":\"word_boundary\",\"\\\\B\":\"word_boundary\",\"\\\\G\":\"search_start\",\"\\\\y\":\"text_segment_boundary\",\"\\\\Y\":\"text_segment_boundary\",\"\\\\z\":\"string_end\",\"\\\\Z\":\"string_end_newline\"}[e],`Unexpected assertion kind \"${e}\"`),{negate:e===X`\\B`||e===X`\\Y`})}function sb({raw:e},t){const n=/^\\\\k[<']/.test(e),a=n?e.slice(3,-1):e.slice(1),r=(i,s=!1)=>{const o=t.capturingGroups.length;let c=!1;if(i>o)if(t.skipBackrefValidation)c=!0;else throw new Error(`Not enough capturing groups defined to the left \"${e}\"`);return t.hasNumberedRef=!0,zr(s?o+1-i:i,{orphan:c})};if(n){const i=/^(?<sign>-?)0*(?<num>[1-9]\\d*)$/.exec(a);if(i)return r(+i.groups.num,!!i.groups.sign);if(/[-+]/.test(a))throw new Error(`Invalid backref name \"${e}\"`);if(!t.namedGroupsByName.has(a))throw new Error(`Group name not defined to the left \"${e}\"`);return zr(a)}return r(+a)}function ob(e,t,n){const{tokens:a,walk:r}=t,i=t.parent,s=i.body.at(-1),o=a[t.nextIndex];if(!n.isCheckingRangeEnd&&s&&s.type!==\"CharacterClass\"&&s.type!==\"CharacterClassRange\"&&o&&o.type!==\"CharacterClassOpen\"&&o.type!==\"CharacterClassClose\"&&o.type!==\"CharacterClassIntersector\"){const c=r(i,{...n,isCheckingRangeEnd:!0});if(s.type===\"Character\"&&c.type===\"Character\")return i.body.pop(),hb(s,c);throw new Error(\"Invalid character class range\")}return La(Zt(\"-\"))}function cb({negate:e},t,n){const{tokens:a,walk:r}=t,i=a[t.nextIndex],s=[ca()];let o=Ws(i);for(;o.type!==\"CharacterClassClose\";){if(o.type===\"CharacterClassIntersector\")s.push(ca()),t.nextIndex++;else{const l=s.at(-1);l.body.push(r(l,n))}o=Ws(a[t.nextIndex],i)}const c=ca({negate:e});return s.length===1?c.body=s[0].body:(c.kind=\"intersection\",c.body=s.map(l=>l.body.length===1?l.body[0]:l)),t.nextIndex++,c}function lb({kind:e,negate:t,value:n},a){const{normalizeUnknownPropertyNames:r,skipPropertyNameValidation:i,unicodePropertyMap:s}=a;if(e===\"property\"){const o=Pa(n);if(Oi.has(o)&&!s?.has(o))e=\"posix\",n=o;else return At(n,{negate:t,normalizeUnknownPropertyNames:r,skipPropertyNameValidation:i,unicodePropertyMap:s})}return e===\"posix\"?_b(n,{negate:t}):Br(e,{negate:t})}function ub(e,t,n){const{tokens:a,capturingGroups:r,namedGroupsByName:i,skipLookbehindValidation:s,walk:o}=t,c=vb(e),l=c.type===\"AbsenceFunction\",u=Hs(c),p=u&&c.negate;if(c.type===\"CapturingGroup\"&&(r.push(c),c.name&&Of(i,c.name,[]).push(c)),l&&n.isInAbsenceFunction)throw new Error(\"Nested absence function not supported by Oniguruma\");let m=Vs(a[t.nextIndex]);for(;m.type!==\"GroupClose\";){if(m.type===\"Alternator\")c.body.push(bt()),t.nextIndex++;else{const h=c.body.at(-1),g=o(h,{...n,isInAbsenceFunction:n.isInAbsenceFunction||l,isInLookbehind:n.isInLookbehind||u,isInNegLookbehind:n.isInNegLookbehind||p});if(h.body.push(g),(u||n.isInLookbehind)&&!s){const _=\"Lookbehind includes a pattern not allowed by Oniguruma\";if(p||n.isInNegLookbehind){if(Gs(g)||g.type===\"CapturingGroup\")throw new Error(_)}else if(Gs(g)||Hs(g)&&g.negate)throw new Error(_)}}m=Vs(a[t.nextIndex])}return t.nextIndex++,c}function pb({kind:e,min:t,max:n},a){const r=a.parent,i=r.body.at(-1);if(!i||!ab(i))throw new Error(\"Quantifier requires a repeatable token\");const s=Fl(e,t,n,i);return r.body.pop(),s}function db({raw:e},t){const{capturingGroups:n,subroutines:a}=t;let r=e.slice(3,-1);const i=/^(?<sign>[-+]?)0*(?<num>[1-9]\\d*)$/.exec(r);if(i){const o=+i.groups.num,c=n.length;if(t.hasNumberedRef=!0,r={\"\":o,\"+\":c+o,\"-\":c+1-o}[i.groups.sign],r<1)throw new Error(\"Invalid subroutine number\")}else r===\"0\"&&(r=0);const s=$l(r);return a.push(s),s}function mb(e,t){return{type:\"AbsenceFunction\",kind:e,body:Rn(t?.body)}}function bt(e){return{type:\"Alternative\",body:jl(e?.body)}}function qr(e,t){const n={type:\"Assertion\",kind:e};return(e===\"word_boundary\"||e===\"text_segment_boundary\")&&(n.negate=!!t?.negate),n}function zr(e,t){const n=!!t?.orphan;return{type:\"Backreference\",ref:e,...n&&{orphan:n}}}function El(e,t){const n={name:void 0,isSubroutined:!1,...t};if(n.name!==void 0&&!wb(n.name))throw new Error(`Group name \"${n.name}\" invalid in Oniguruma`);return{type:\"CapturingGroup\",number:e,...n.name&&{name:n.name},...n.isSubroutined&&{isSubroutined:n.isSubroutined},body:Rn(t?.body)}}function La(e,t){const n={useLastValid:!1,...t};if(e>1114111){const a=e.toString(16);if(n.useLastValid)e=1114111;else throw e>1310719?new Error(`Invalid code point out of range \"\\\\x{${a}}\"`):new Error(`Invalid code point out of range in JS \"\\\\x{${a}}\"`)}return{type:\"Character\",value:e}}function ca(e){const t={kind:\"union\",negate:!1,...e};return{type:\"CharacterClass\",kind:t.kind,negate:t.negate,body:jl(e?.body)}}function hb(e,t){if(t.value<e.value)throw new Error(\"Character class range out of order\");return{type:\"CharacterClassRange\",min:e,max:t}}function Br(e,t){const n=!!t?.negate,a={type:\"CharacterSet\",kind:e};return(e===\"digit\"||e===\"hex\"||e===\"newline\"||e===\"space\"||e===\"word\")&&(a.negate=n),(e===\"text_segment\"||e===\"newline\"&&!n)&&(a.variableLength=!0),a}function gb(e,t={}){if(e===\"keep\")return{type:\"Directive\",kind:e};if(e===\"flags\")return{type:\"Directive\",kind:e,flags:Yt(t.flags)};throw new Error(`Unexpected directive kind \"${e}\"`)}function fb(e){return{type:\"Flags\",...e}}function be(e){const t=e?.atomic,n=e?.flags;if(t&&n)throw new Error(\"Atomic group cannot have flags\");return{type:\"Group\",...t&&{atomic:t},...n&&{flags:n},body:Rn(e?.body)}}function at(e){const t={behind:!1,negate:!1,...e};return{type:\"LookaroundAssertion\",kind:t.behind?\"lookbehind\":\"lookahead\",negate:t.negate,body:Rn(e?.body)}}function bb(e,t,n){return{type:\"NamedCallout\",kind:e,tag:t,arguments:n}}function _b(e,t){const n=!!t?.negate;if(!Oi.has(e))throw new Error(`Invalid POSIX class \"${e}\"`);return{type:\"CharacterSet\",kind:\"posix\",value:e,negate:n}}function Fl(e,t,n,a){if(t>n)throw new Error(\"Invalid reversed quantifier range\");return{type:\"Quantifier\",kind:e,min:t,max:n,body:a}}function yb(e,t){return{type:\"Regex\",body:Rn(t?.body),flags:e}}function $l(e){return{type:\"Subroutine\",ref:e}}function At(e,t){const n={negate:!1,normalizeUnknownPropertyNames:!1,skipPropertyNameValidation:!1,unicodePropertyMap:null,...t};let a=n.unicodePropertyMap?.get(Pa(e));if(!a){if(n.normalizeUnknownPropertyNames)a=xb(e);else if(n.unicodePropertyMap&&!n.skipPropertyNameValidation)throw new Error(X`Invalid Unicode property \"\\p{${e}}\"`)}return{type:\"CharacterSet\",kind:\"property\",value:a??e,negate:n.negate}}function vb({flags:e,kind:t,name:n,negate:a,number:r}){switch(t){case\"absence_repeater\":return mb(\"repeater\");case\"atomic\":return be({atomic:!0});case\"capturing\":return El(r,{name:n});case\"group\":return be({flags:e});case\"lookahead\":case\"lookbehind\":return at({behind:t===\"lookbehind\",negate:a});default:throw new Error(`Unexpected group kind \"${t}\"`)}}function Rn(e){if(e===void 0)e=[bt()];else if(!Array.isArray(e)||!e.length||!e.every(t=>t.type===\"Alternative\"))throw new Error(\"Invalid body; expected array of one or more Alternative nodes\");return e}function jl(e){if(e===void 0)e=[];else if(!Array.isArray(e)||!e.every(t=>!!t.type))throw new Error(\"Invalid body; expected array of nodes\");return e}function Gs(e){return e.type===\"LookaroundAssertion\"&&e.kind===\"lookahead\"}function Hs(e){return e.type===\"LookaroundAssertion\"&&e.kind===\"lookbehind\"}function wb(e){return/^[\\p{Alpha}\\p{Pc}][^)]*$/u.test(e)}function xb(e){return e.trim().replace(/[- _]+/g,\"_\").replace(/[A-Z][a-z]+(?=[A-Z])/g,\"$&_\").replace(/[A-Za-z]+/g,t=>t[0].toUpperCase()+t.slice(1).toLowerCase())}function Pa(e){return e.replace(/[- _]+/g,\"\").toLowerCase()}function Ws(e,t){return Yt(e,`${t?.type===\"Character\"&&t.value===93?\"Empty\":\"Unclosed\"} character class`)}function Vs(e){return Yt(e,\"Unclosed group\")}function gn(e,t,n=null){function a(i,s){for(let o=0;o<i.length;o++){const c=r(i[o],s,o,i);o=Math.max(-1,o+c)}}function r(i,s=null,o=null,c=null){let l=0,u=!1;const p={node:i,parent:s,key:o,container:c,root:e,remove(){na(c).splice(Math.max(0,Et(o)+l),1),l--,u=!0},removeAllNextSiblings(){return na(c).splice(Et(o)+1)},removeAllPrevSiblings(){const b=Et(o)+l;return l-=b,na(c).splice(0,Math.max(0,b))},replaceWith(b,w={}){const y=!!w.traverse;c?c[Math.max(0,Et(o)+l)]=b:Yt(s,\"Can't replace root node\")[o]=b,y&&r(b,s,o,c),u=!0},replaceWithMultiple(b,w={}){const y=!!w.traverse;if(na(c).splice(Math.max(0,Et(o)+l),1,...b),l+=b.length-1,y){let d=0;for(let C=0;C<b.length;C++)d+=r(b[C],s,Et(o)+C+d,c)}u=!0},skip(){u=!0}},{type:m}=i,h=t[\"*\"],g=t[m],_=typeof h==\"function\"?h:h?.enter,f=typeof g==\"function\"?g:g?.enter;if(_?.(p,n),f?.(p,n),!u)switch(m){case\"AbsenceFunction\":case\"CapturingGroup\":case\"Group\":a(i.body,i);break;case\"Alternative\":case\"CharacterClass\":a(i.body,i);break;case\"Assertion\":case\"Backreference\":case\"Character\":case\"CharacterSet\":case\"Directive\":case\"Flags\":case\"NamedCallout\":case\"Subroutine\":break;case\"CharacterClassRange\":r(i.min,i,\"min\"),r(i.max,i,\"max\");break;case\"LookaroundAssertion\":a(i.body,i);break;case\"Quantifier\":r(i.body,i,\"body\");break;case\"Regex\":a(i.body,i),r(i.flags,i,\"flags\");break;default:throw new Error(`Unexpected node type \"${m}\"`)}return g?.exit?.(p,n),h?.exit?.(p,n),l}return r(e),e}function na(e){if(!Array.isArray(e))throw new Error(\"Container expected\");return e}function Et(e){if(typeof e!=\"number\")throw new Error(\"Numeric key expected\");return e}const kb=String.raw`\\(\\?(?:[:=!>A-Za-z\\-]|<[=!]|\\(DEFINE\\))`;function Cb(e,t){for(let n=0;n<e.length;n++)e[n]>=t&&e[n]++}function Eb(e,t,n,a){return e.slice(0,t)+a+e.slice(t+n.length)}const de=Object.freeze({DEFAULT:\"DEFAULT\",CHAR_CLASS:\"CHAR_CLASS\"});function Ii(e,t,n,a){const r=new RegExp(String.raw`${t}|(?<$skip>\\[\\^?|\\\\?.)`,\"gsu\"),i=[!1];let s=0,o=\"\";for(const c of e.matchAll(r)){const{0:l,groups:{$skip:u}}=c;if(!u&&(!a||a===de.DEFAULT==!s)){n instanceof Function?o+=n(c,{context:s?de.CHAR_CLASS:de.DEFAULT,negated:i[i.length-1]}):o+=n;continue}l[0]===\"[\"?(s++,i.push(l[1]===\"^\")):l===\"]\"&&s&&(s--,i.pop()),o+=l}return o}function Sl(e,t,n,a){Ii(e,t,n,a)}function Fb(e,t,n=0,a){if(!new RegExp(t,\"su\").test(e))return null;const r=new RegExp(`${t}|(?<$skip>\\\\\\\\?.)`,\"gsu\");r.lastIndex=n;let i=0,s;for(;s=r.exec(e);){const{0:o,groups:{$skip:c}}=s;if(!c&&(!a||a===de.DEFAULT==!i))return s;o===\"[\"?i++:o===\"]\"&&i&&i--,r.lastIndex==s.index&&r.lastIndex++}return null}function aa(e,t,n){return!!Fb(e,t,0,n)}function $b(e,t){const n=/\\\\?./gsu;n.lastIndex=t;let a=e.length,r=0,i=1,s;for(;s=n.exec(e);){const[o]=s;if(o===\"[\")r++;else if(r)o===\"]\"&&r--;else if(o===\"(\")i++;else if(o===\")\"&&(i--,!i)){a=s.index;break}}return e.slice(t,a)}const Zs=new RegExp(String.raw`(?<noncapturingStart>${kb})|(?<capturingStart>\\((?:\\?<[^>]+>)?)|\\\\?.`,\"gsu\");function jb(e,t){const n=t?.hiddenCaptures??[];let a=t?.captureTransfers??new Map;if(!/\\(\\?>/.test(e))return{pattern:e,captureTransfers:a,hiddenCaptures:n};const r=\"(?>\",i=\"(?:(?=(\",s=[0],o=[];let c=0,l=0,u=NaN,p;do{p=!1;let m=0,h=0,g=!1,_;for(Zs.lastIndex=Number.isNaN(u)?0:u+i.length;_=Zs.exec(e);){const{0:f,index:b,groups:{capturingStart:w,noncapturingStart:y}}=_;if(f===\"[\")m++;else if(m)f===\"]\"&&m--;else if(f===r&&!g)u=b,g=!0;else if(g&&y)h++;else if(w)g?h++:(c++,s.push(c+l));else if(f===\")\"&&g){if(!h){l++;const d=c+l;if(e=`${e.slice(0,u)}${i}${e.slice(u+r.length,b)}))<$$${d}>)${e.slice(b+1)}`,p=!0,o.push(d),Cb(n,d),a.size){const C=new Map;a.forEach((k,$)=>{C.set($>=d?$+1:$,k.map(T=>T>=d?T+1:T))}),a=C}break}h--}}}while(p);return n.push(...o),e=Ii(e,String.raw`\\\\(?<backrefNum>[1-9]\\d*)|<\\$\\$(?<wrappedBackrefNum>\\d+)>`,({0:m,groups:{backrefNum:h,wrappedBackrefNum:g}})=>{if(h){const _=+h;if(_>s.length-1)throw new Error(`Backref \"${m}\" greater than number of captures`);return`\\\\${s[_]}`}return`\\\\${g}`},de.DEFAULT),{pattern:e,captureTransfers:a,hiddenCaptures:n}}const Al=String.raw`(?:[?*+]|\\{\\d+(?:,\\d*)?\\})`,ar=new RegExp(String.raw`\n\\\\(?: \\d+\n  | c[A-Za-z]\n  | [gk]<[^>]+>\n  | [pPu]\\{[^\\}]+\\}\n  | u[A-Fa-f\\d]{4}\n  | x[A-Fa-f\\d]{2}\n  )\n| \\((?: \\? (?: [:=!>]\n  | <(?:[=!]|[^>]+>)\n  | [A-Za-z\\-]+:\n  | \\(DEFINE\\)\n  ))?\n| (?<qBase>${Al})(?<qMod>[?+]?)(?<invalidQ>[?*+\\{]?)\n| \\\\?.\n`.replace(/\\s+/g,\"\"),\"gsu\");function Sb(e){if(!new RegExp(`${Al}\\\\+`).test(e))return{pattern:e};const t=[];let n=null,a=null,r=\"\",i=0,s;for(ar.lastIndex=0;s=ar.exec(e);){const{0:o,index:c,groups:{qBase:l,qMod:u,invalidQ:p}}=s;if(o===\"[\")i||(a=c),i++;else if(o===\"]\")i?i--:a=null;else if(!i)if(u===\"+\"&&r&&!r.startsWith(\"(\")){if(p)throw new Error(`Invalid quantifier \"${o}\"`);let m=-1;if(/^\\{\\d+\\}$/.test(l))e=Eb(e,c+l.length,u,\"\");else{if(r===\")\"||r===\"]\"){const h=r===\")\"?n:a;if(h===null)throw new Error(`Invalid unmatched \"${r}\"`);e=`${e.slice(0,h)}(?>${e.slice(h,c)}${l})${e.slice(c+o.length)}`}else e=`${e.slice(0,c-r.length)}(?>${r}${l})${e.slice(c+o.length)}`;m+=4}ar.lastIndex+=m}else o[0]===\"(\"?t.push(c):o===\")\"&&(n=t.length?t.pop():null);r=o}return{pattern:e}}const ue=String.raw,Ab=ue`\\\\g<(?<gRNameOrNum>[^>&]+)&R=(?<gRDepth>[^>]+)>`,Ur=ue`\\(\\?R=(?<rDepth>[^\\)]+)\\)|${Ab}`,Da=ue`\\(\\?<(?![=!])(?<captureName>[^>]+)>`,Tl=ue`${Da}|(?<unnamed>\\()(?!\\?)`,Je=new RegExp(ue`${Da}|${Ur}|\\(\\?|\\\\?.`,\"gsu\"),rr=\"Cannot use multiple overlapping recursions\";function Tb(e,t){const{hiddenCaptures:n,mode:a}={hiddenCaptures:[],mode:\"plugin\",...t};let r=t?.captureTransfers??new Map;if(!new RegExp(Ur,\"su\").test(e))return{pattern:e,captureTransfers:r,hiddenCaptures:n};if(a===\"plugin\"&&aa(e,ue`\\(\\?\\(DEFINE\\)`,de.DEFAULT))throw new Error(\"DEFINE groups cannot be used with recursion\");const i=[],s=aa(e,ue`\\\\[1-9]`,de.DEFAULT),o=new Map,c=[];let l=!1,u=0,p=0,m;for(Je.lastIndex=0;m=Je.exec(e);){const{0:h,groups:{captureName:g,rDepth:_,gRNameOrNum:f,gRDepth:b}}=m;if(h===\"[\")u++;else if(u)h===\"]\"&&u--;else if(_){if(Ys(_),l)throw new Error(rr);if(s)throw new Error(`${a===\"external\"?\"Backrefs\":\"Numbered backrefs\"} cannot be used with global recursion`);const w=e.slice(0,m.index),y=e.slice(Je.lastIndex);if(aa(y,Ur,de.DEFAULT))throw new Error(rr);const d=+_-1;e=Xs(w,y,d,!1,n,i,p),r=Qs(r,w,d,i.length,0,p);break}else if(f){Ys(b);let w=!1;for(const R of c)if(R.name===f||R.num===+f){if(w=!0,R.hasRecursedWithin)throw new Error(rr);break}if(!w)throw new Error(ue`Recursive \\g cannot be used outside the referenced group \"${a===\"external\"?f:ue`\\g<${f}&R=${b}>`}\"`);const y=o.get(f),d=$b(e,y);if(s&&aa(d,ue`${Da}|\\((?!\\?)`,de.DEFAULT))throw new Error(`${a===\"external\"?\"Backrefs\":\"Numbered backrefs\"} cannot be used with recursion of capturing groups`);const C=e.slice(y,m.index),k=d.slice(C.length+h.length),$=i.length,T=+b-1,I=Xs(C,k,T,!0,n,i,p);r=Qs(r,C,T,i.length-$,$,p);const N=e.slice(0,y),D=e.slice(y+d.length);e=`${N}${I}${D}`,Je.lastIndex+=I.length-h.length-C.length-k.length,c.forEach(R=>R.hasRecursedWithin=!0),l=!0}else if(g)p++,o.set(String(p),Je.lastIndex),o.set(g,Je.lastIndex),c.push({num:p,name:g});else if(h[0]===\"(\"){const w=h===\"(\";w&&(p++,o.set(String(p),Je.lastIndex)),c.push(w?{num:p}:{})}else h===\")\"&&c.pop()}return n.push(...i),{pattern:e,captureTransfers:r,hiddenCaptures:n}}function Ys(e){const t=`Max depth must be integer between 2 and 100; used ${e}`;if(!/^[1-9]\\d*$/.test(e))throw new Error(t);if(e=+e,e<2||e>100)throw new Error(t)}function Xs(e,t,n,a,r,i,s){const o=new Set;a&&Sl(e+t,Da,({groups:{captureName:l}})=>{o.add(l)},de.DEFAULT);const c=[n,a?o:null,r,i,s];return`${e}${Ks(`(?:${e}`,\"forward\",...c)}(?:)${Ks(`${t})`,\"backward\",...c)}${t}`}function Ks(e,t,n,a,r,i,s){const c=u=>t===\"forward\"?u+2:n-u+2-1;let l=\"\";for(let u=0;u<n;u++){const p=c(u);l+=Ii(e,ue`${Tl}|\\\\k<(?<backref>[^>]+)>`,({0:m,groups:{captureName:h,unnamed:g,backref:_}})=>{if(_&&a&&!a.has(_))return m;const f=`_$${p}`;if(g||h){const b=s+i.length+1;return i.push(b),Rb(r,b),g?m:`(?<${h}${f}>`}return ue`\\k<${_}${f}>`},de.DEFAULT)}return l}function Rb(e,t){for(let n=0;n<e.length;n++)e[n]>=t&&e[n]++}function Qs(e,t,n,a,r,i){if(e.size&&a){let s=0;Sl(t,Tl,()=>s++,de.DEFAULT);const o=i-s+r,c=new Map;return e.forEach((l,u)=>{const p=(a-s*n)/n,m=s*n,h=u>o+s?u+a:u,g=[];for(const _ of l)if(_<=o)g.push(_);else if(_>o+s+p)g.push(_+a);else if(_<=o+s)for(let f=0;f<=n;f++)g.push(_+s*f);else for(let f=0;f<=n;f++)g.push(_+m+p*f);c.set(h,g)}),c}return e}var V=String.fromCodePoint,j=String.raw,Le={flagGroups:(()=>{try{new RegExp(\"(?i:)\")}catch{return!1}return!0})(),unicodeSets:(()=>{try{new RegExp(\"[[]]\",\"v\")}catch{return!1}return!0})()};Le.bugFlagVLiteralHyphenIsRange=Le.unicodeSets?(()=>{try{new RegExp(j`[\\d\\-a]`,\"v\")}catch{return!0}return!1})():!1;Le.bugNestedClassIgnoresNegation=Le.unicodeSets&&new RegExp(\"[[^a]]\",\"v\").test(\"a\");function Ca(e,{enable:t,disable:n}){return{dotAll:!n?.dotAll&&!!(t?.dotAll||e.dotAll),ignoreCase:!n?.ignoreCase&&!!(t?.ignoreCase||e.ignoreCase)}}function En(e,t,n){return e.has(t)||e.set(t,n),e.get(t)}function Gr(e,t){return Js[e]>=Js[t]}function Ob(e,t){if(e==null)throw new Error(t??\"Value expected\");return e}var Js={ES2025:2025,ES2024:2024,ES2018:2018},Nb={auto:\"auto\",ES2025:\"ES2025\",ES2024:\"ES2024\",ES2018:\"ES2018\"};function Rl(e={}){if({}.toString.call(e)!==\"[object Object]\")throw new Error(\"Unexpected options\");if(e.target!==void 0&&!Nb[e.target])throw new Error(`Unexpected target \"${e.target}\"`);const t={accuracy:\"default\",avoidSubclass:!1,flags:\"\",global:!1,hasIndices:!1,lazyCompileLength:1/0,target:\"auto\",verbose:!1,...e,rules:{allowOrphanBackrefs:!1,asciiWordBoundaries:!1,captureGroup:!1,recursionLimit:20,singleline:!1,...e.rules}};return t.target===\"auto\"&&(t.target=Le.flagGroups?\"ES2025\":Le.unicodeSets?\"ES2024\":\"ES2018\"),t}var Ib=\"[\t-\\r ]\",Lb=new Set([V(304),V(305)]),Oe=j`[\\p{L}\\p{M}\\p{N}\\p{Pc}]`;function Ol(e){if(Lb.has(e))return[e];const t=new Set,n=e.toLowerCase(),a=n.toUpperCase(),r=Mb.get(n),i=Pb.get(n),s=Db.get(n);return[...a].length===1&&t.add(a),s&&t.add(s),r&&t.add(r),t.add(n),i&&t.add(i),[...t]}var Li=new Map(`C Other\nCc Control cntrl\nCf Format\nCn Unassigned\nCo Private_Use\nCs Surrogate\nL Letter\nLC Cased_Letter\nLl Lowercase_Letter\nLm Modifier_Letter\nLo Other_Letter\nLt Titlecase_Letter\nLu Uppercase_Letter\nM Mark Combining_Mark\nMc Spacing_Mark\nMe Enclosing_Mark\nMn Nonspacing_Mark\nN Number\nNd Decimal_Number digit\nNl Letter_Number\nNo Other_Number\nP Punctuation punct\nPc Connector_Punctuation\nPd Dash_Punctuation\nPe Close_Punctuation\nPf Final_Punctuation\nPi Initial_Punctuation\nPo Other_Punctuation\nPs Open_Punctuation\nS Symbol\nSc Currency_Symbol\nSk Modifier_Symbol\nSm Math_Symbol\nSo Other_Symbol\nZ Separator\nZl Line_Separator\nZp Paragraph_Separator\nZs Space_Separator\nASCII\nASCII_Hex_Digit AHex\nAlphabetic Alpha\nAny\nAssigned\nBidi_Control Bidi_C\nBidi_Mirrored Bidi_M\nCase_Ignorable CI\nCased\nChanges_When_Casefolded CWCF\nChanges_When_Casemapped CWCM\nChanges_When_Lowercased CWL\nChanges_When_NFKC_Casefolded CWKCF\nChanges_When_Titlecased CWT\nChanges_When_Uppercased CWU\nDash\nDefault_Ignorable_Code_Point DI\nDeprecated Dep\nDiacritic Dia\nEmoji\nEmoji_Component EComp\nEmoji_Modifier EMod\nEmoji_Modifier_Base EBase\nEmoji_Presentation EPres\nExtended_Pictographic ExtPict\nExtender Ext\nGrapheme_Base Gr_Base\nGrapheme_Extend Gr_Ext\nHex_Digit Hex\nIDS_Binary_Operator IDSB\nIDS_Trinary_Operator IDST\nID_Continue IDC\nID_Start IDS\nIdeographic Ideo\nJoin_Control Join_C\nLogical_Order_Exception LOE\nLowercase Lower\nMath\nNoncharacter_Code_Point NChar\nPattern_Syntax Pat_Syn\nPattern_White_Space Pat_WS\nQuotation_Mark QMark\nRadical\nRegional_Indicator RI\nSentence_Terminal STerm\nSoft_Dotted SD\nTerminal_Punctuation Term\nUnified_Ideograph UIdeo\nUppercase Upper\nVariation_Selector VS\nWhite_Space space\nXID_Continue XIDC\nXID_Start XIDS`.split(/\\s/).map(e=>[Pa(e),e])),Pb=new Map([[\"s\",V(383)],[V(383),\"s\"]]),Db=new Map([[V(223),V(7838)],[V(107),V(8490)],[V(229),V(8491)],[V(969),V(8486)]]),Mb=new Map([Be(453),Be(456),Be(459),Be(498),...ir(8072,8079),...ir(8088,8095),...ir(8104,8111),Be(8124),Be(8140),Be(8188)]),qb=new Map([[\"alnum\",j`[\\p{Alpha}\\p{Nd}]`],[\"alpha\",j`\\p{Alpha}`],[\"ascii\",j`\\p{ASCII}`],[\"blank\",j`[\\p{Zs}\\t]`],[\"cntrl\",j`\\p{Cc}`],[\"digit\",j`\\p{Nd}`],[\"graph\",j`[\\P{space}&&\\P{Cc}&&\\P{Cn}&&\\P{Cs}]`],[\"lower\",j`\\p{Lower}`],[\"print\",j`[[\\P{space}&&\\P{Cc}&&\\P{Cn}&&\\P{Cs}]\\p{Zs}]`],[\"punct\",j`[\\p{P}\\p{S}]`],[\"space\",j`\\p{space}`],[\"upper\",j`\\p{Upper}`],[\"word\",j`[\\p{Alpha}\\p{M}\\p{Nd}\\p{Pc}]`],[\"xdigit\",j`\\p{AHex}`]]);function zb(e,t){const n=[];for(let a=e;a<=t;a++)n.push(a);return n}function Be(e){const t=V(e);return[t.toLowerCase(),t]}function ir(e,t){return zb(e,t).map(n=>Be(n))}var Nl=new Set([\"Lower\",\"Lowercase\",\"Upper\",\"Uppercase\",\"Ll\",\"Lowercase_Letter\",\"Lt\",\"Titlecase_Letter\",\"Lu\",\"Uppercase_Letter\"]);function Bb(e,t){const n={accuracy:\"default\",asciiWordBoundaries:!1,avoidSubclass:!1,bestEffortTarget:\"ES2025\",...t};Il(e);const a={accuracy:n.accuracy,asciiWordBoundaries:n.asciiWordBoundaries,avoidSubclass:n.avoidSubclass,flagDirectivesByAlt:new Map,jsGroupNameMap:new Map,minTargetEs2024:Gr(n.bestEffortTarget,\"ES2024\"),passedLookbehind:!1,strategy:null,subroutineRefMap:new Map,supportedGNodes:new Set,digitIsAscii:e.flags.digitIsAscii,spaceIsAscii:e.flags.spaceIsAscii,wordIsAscii:e.flags.wordIsAscii};gn(e,Ub,a);const r={dotAll:e.flags.dotAll,ignoreCase:e.flags.ignoreCase},i={currentFlags:r,prevFlags:null,globalFlags:r,groupOriginByCopy:new Map,groupsByName:new Map,multiplexCapturesToLeftByRef:new Map,openRefs:new Map,reffedNodesByReferencer:new Map,subroutineRefMap:a.subroutineRefMap};gn(e,Gb,i);const s={groupsByName:i.groupsByName,highestOrphanBackref:0,numCapturesToLeft:0,reffedNodesByReferencer:i.reffedNodesByReferencer};return gn(e,Hb,s),e._originMap=i.groupOriginByCopy,e._strategy=a.strategy,e}var Ub={AbsenceFunction({node:e,parent:t,replaceWith:n}){const{body:a,kind:r}=e;if(r===\"repeater\"){const i=be();i.body[0].body.push(at({negate:!0,body:a}),At(\"Any\"));const s=be();s.body[0].body.push(Fl(\"greedy\",0,1/0,i)),n(B(s,t),{traverse:!0})}else throw new Error('Unsupported absence function \"(?~|\"')},Alternative:{enter({node:e,parent:t,key:n},{flagDirectivesByAlt:a}){const r=e.body.filter(i=>i.kind===\"flags\");for(let i=n+1;i<t.body.length;i++){const s=t.body[i];En(a,s,[]).push(...r)}},exit({node:e},{flagDirectivesByAlt:t}){if(t.get(e)?.length){const n=Pl(t.get(e));if(n){const a=be({flags:n});a.body[0].body=e.body,e.body=[B(a,e)]}}}},Assertion({node:e,parent:t,key:n,container:a,root:r,remove:i,replaceWith:s},o){const{kind:c,negate:l}=e,{asciiWordBoundaries:u,avoidSubclass:p,supportedGNodes:m,wordIsAscii:h}=o;if(c===\"text_segment_boundary\")throw new Error(`Unsupported text segment boundary \"\\\\${l?\"Y\":\"y\"}\"`);if(c===\"line_end\")s(B(at({body:[bt({body:[qr(\"string_end\")]}),bt({body:[La(10)]})]}),t));else if(c===\"line_start\")s(B(Ne(j`(?<=\\A|\\n(?!\\z))`,{skipLookbehindValidation:!0}),t));else if(c===\"search_start\")if(m.has(e))r.flags.sticky=!0,i();else{const g=a[n-1];if(g&&Kb(g))s(B(at({negate:!0}),t));else{if(p)throw new Error(j`Uses \"\\G\" in a way that requires a subclass`);s(Ue(qr(\"string_start\"),t)),o.strategy=\"clip_search\"}}else if(!(c===\"string_end\"||c===\"string_start\"))if(c===\"string_end_newline\")s(B(Ne(j`(?=\\n?\\z)`),t));else if(c===\"word_boundary\"){if(!h&&!u){const g=`(?:(?<=${Oe})(?!${Oe})|(?<!${Oe})(?=${Oe}))`,_=`(?:(?<=${Oe})(?=${Oe})|(?<!${Oe})(?!${Oe}))`;s(B(Ne(l?_:g),t))}}else throw new Error(`Unexpected assertion kind \"${c}\"`)},Backreference({node:e},{jsGroupNameMap:t}){let{ref:n}=e;typeof n==\"string\"&&!or(n)&&(n=sr(n,t),e.ref=n)},CapturingGroup({node:e},{jsGroupNameMap:t,subroutineRefMap:n}){let{name:a}=e;a&&!or(a)&&(a=sr(a,t),e.name=a),n.set(e.number,e),a&&n.set(a,e)},CharacterClassRange({node:e,parent:t,replaceWith:n}){if(t.kind===\"intersection\"){const a=ca({body:[e]});n(B(a,t),{traverse:!0})}},CharacterSet({node:e,parent:t,replaceWith:n},{accuracy:a,minTargetEs2024:r,digitIsAscii:i,spaceIsAscii:s,wordIsAscii:o}){const{kind:c,negate:l,value:u}=e;if(i&&(c===\"digit\"||u===\"digit\")){n(Ue(Br(\"digit\",{negate:l}),t));return}if(s&&(c===\"space\"||u===\"space\")){n(B(cr(Ne(Ib),l),t));return}if(o&&(c===\"word\"||u===\"word\")){n(Ue(Br(\"word\",{negate:l}),t));return}if(c===\"any\")n(Ue(At(\"Any\"),t));else if(c===\"digit\")n(Ue(At(\"Nd\",{negate:l}),t));else if(c!==\"dot\")if(c===\"text_segment\"){if(a===\"strict\")throw new Error(j`Use of \"\\X\" requires non-strict accuracy`);const p=\"\\\\p{Emoji}(?:\\\\p{EMod}|\\\\uFE0F\\\\u20E3?|[\\\\x{E0020}-\\\\x{E007E}]+\\\\x{E007F})?\",m=j`\\p{RI}{2}|${p}(?:\\u200D${p})*`;n(B(Ne(j`(?>\\r\\n|${r?j`\\p{RGI_Emoji}`:m}|\\P{M}\\p{M}*)`,{skipPropertyNameValidation:!0}),t))}else if(c===\"hex\")n(Ue(At(\"AHex\",{negate:l}),t));else if(c===\"newline\")n(B(Ne(l?`[^\n]`:`(?>\\r\n?|[\n\\v\\f\\u2028\\u2029])`),t));else if(c===\"posix\")if(!r&&(u===\"graph\"||u===\"print\")){if(a===\"strict\")throw new Error(`POSIX class \"${u}\" requires min target ES2024 or non-strict accuracy`);let p={graph:\"!-~\",print:\" -~\"}[u];l&&(p=`\\0-${V(p.codePointAt(0)-1)}${V(p.codePointAt(2)+1)}-􏿿`),n(B(Ne(`[${p}]`),t))}else n(B(cr(Ne(qb.get(u)),l),t));else if(c===\"property\")Li.has(Pa(u))||(e.key=\"sc\");else if(c===\"space\")n(Ue(At(\"space\",{negate:l}),t));else if(c===\"word\")n(B(cr(Ne(Oe),l),t));else throw new Error(`Unexpected character set kind \"${c}\"`)},Directive({node:e,parent:t,root:n,remove:a,replaceWith:r,removeAllPrevSiblings:i,removeAllNextSiblings:s}){const{kind:o,flags:c}=e;if(o===\"flags\")if(!c.enable&&!c.disable)a();else{const l=be({flags:c});l.body[0].body=s(),r(B(l,t),{traverse:!0})}else if(o===\"keep\"){const l=n.body[0],p=n.body.length===1&&kl(l,{type:\"Group\"})&&l.body[0].body.length===1?l.body[0]:n;if(t.parent!==p||p.body.length>1)throw new Error(j`Uses \"\\K\" in a way that's unsupported`);const m=at({behind:!0});m.body[0].body=i(),r(B(m,t))}else throw new Error(`Unexpected directive kind \"${o}\"`)},Flags({node:e,parent:t}){if(e.posixIsAscii)throw new Error('Unsupported flag \"P\"');if(e.textSegmentMode===\"word\")throw new Error('Unsupported flag \"y{w}\"');[\"digitIsAscii\",\"extended\",\"posixIsAscii\",\"spaceIsAscii\",\"wordIsAscii\",\"textSegmentMode\"].forEach(n=>delete e[n]),Object.assign(e,{global:!1,hasIndices:!1,multiline:!1,sticky:e.sticky??!1}),t.options={disable:{x:!0,n:!0},force:{v:!0}}},Group({node:e}){if(!e.flags)return;const{enable:t,disable:n}=e.flags;t?.extended&&delete t.extended,n?.extended&&delete n.extended,t?.dotAll&&n?.dotAll&&delete t.dotAll,t?.ignoreCase&&n?.ignoreCase&&delete t.ignoreCase,t&&!Object.keys(t).length&&delete e.flags.enable,n&&!Object.keys(n).length&&delete e.flags.disable,!e.flags.enable&&!e.flags.disable&&delete e.flags},LookaroundAssertion({node:e},t){const{kind:n}=e;n===\"lookbehind\"&&(t.passedLookbehind=!0)},NamedCallout({node:e,parent:t,replaceWith:n}){const{kind:a}=e;if(a===\"fail\")n(B(at({negate:!0}),t));else throw new Error(`Unsupported named callout \"(*${a.toUpperCase()}\"`)},Quantifier({node:e}){if(e.body.type===\"Quantifier\"){const t=be();t.body[0].body.push(e.body),e.body=B(t,e)}},Regex:{enter({node:e},{supportedGNodes:t}){const n=[];let a=!1,r=!1;for(const i of e.body)if(i.body.length===1&&i.body[0].kind===\"search_start\")i.body.pop();else{const s=Ml(i.body);s?(a=!0,Array.isArray(s)?n.push(...s):n.push(s)):r=!0}a&&!r&&n.forEach(i=>t.add(i))},exit(e,{accuracy:t,passedLookbehind:n,strategy:a}){if(t===\"strict\"&&n&&a)throw new Error(j`Uses \"\\G\" in a way that requires non-strict accuracy`)}},Subroutine({node:e},{jsGroupNameMap:t}){let{ref:n}=e;typeof n==\"string\"&&!or(n)&&(n=sr(n,t),e.ref=n)}},Gb={Backreference({node:e},{multiplexCapturesToLeftByRef:t,reffedNodesByReferencer:n}){const{orphan:a,ref:r}=e;a||n.set(e,[...t.get(r).map(({node:i})=>i)])},CapturingGroup:{enter({node:e,parent:t,replaceWith:n,skip:a},{groupOriginByCopy:r,groupsByName:i,multiplexCapturesToLeftByRef:s,openRefs:o,reffedNodesByReferencer:c}){const l=r.get(e);if(l&&o.has(e.number)){const p=Ue(eo(e.number),t);c.set(p,o.get(e.number)),n(p);return}o.set(e.number,e),s.set(e.number,[]),e.name&&En(s,e.name,[]);const u=s.get(e.name??e.number);for(let p=0;p<u.length;p++){const m=u[p];if(l===m.node||l&&l===m.origin||e===m.origin){u.splice(p,1);break}}if(s.get(e.number).push({node:e,origin:l}),e.name&&s.get(e.name).push({node:e,origin:l}),e.name){const p=En(i,e.name,new Map);let m=!1;if(l)m=!0;else for(const h of p.values())if(!h.hasDuplicateNameToRemove){m=!0;break}i.get(e.name).set(e,{node:e,hasDuplicateNameToRemove:m})}},exit({node:e},{openRefs:t}){t.delete(e.number)}},Group:{enter({node:e},t){t.prevFlags=t.currentFlags,e.flags&&(t.currentFlags=Ca(t.currentFlags,e.flags))},exit(e,t){t.currentFlags=t.prevFlags}},Subroutine({node:e,parent:t,replaceWith:n},a){const{isRecursive:r,ref:i}=e;if(r){let u=t;for(;(u=u.parent)&&!(u.type===\"CapturingGroup\"&&(u.name===i||u.number===i)););a.reffedNodesByReferencer.set(e,u);return}const s=a.subroutineRefMap.get(i),o=i===0,c=o?eo(0):Ll(s,a.groupOriginByCopy,null);let l=c;if(!o){const u=Pl(Zb(s,m=>m.type===\"Group\"&&!!m.flags)),p=u?Ca(a.globalFlags,u):a.globalFlags;Wb(p,a.currentFlags)||(l=be({flags:Yb(p)}),l.body[0].body.push(c))}n(B(l,t),{traverse:!o})}},Hb={Backreference({node:e,parent:t,replaceWith:n},a){if(e.orphan){a.highestOrphanBackref=Math.max(a.highestOrphanBackref,e.ref);return}const i=a.reffedNodesByReferencer.get(e).filter(s=>Vb(s,e));if(!i.length)n(B(at({negate:!0}),t));else if(i.length>1){const s=be({atomic:!0,body:i.reverse().map(o=>bt({body:[zr(o.number)]}))});n(B(s,t))}else e.ref=i[0].number},CapturingGroup({node:e},t){e.number=++t.numCapturesToLeft,e.name&&t.groupsByName.get(e.name).get(e).hasDuplicateNameToRemove&&delete e.name},Regex:{exit({node:e},t){const n=Math.max(t.highestOrphanBackref-t.numCapturesToLeft,0);for(let a=0;a<n;a++){const r=El();e.body.at(-1).body.push(r)}}},Subroutine({node:e},t){!e.isRecursive||e.ref===0||(e.ref=t.reffedNodesByReferencer.get(e).number)}};function Il(e){gn(e,{\"*\"({node:t,parent:n}){t.parent=n}})}function Wb(e,t){return e.dotAll===t.dotAll&&e.ignoreCase===t.ignoreCase}function Vb(e,t){let n=t;do{if(n.type===\"Regex\")return!1;if(n.type===\"Alternative\")continue;if(n===e)return!1;const a=Dl(n.parent);for(const r of a){if(r===n)break;if(r===e||ql(r,e))return!0}}while(n=n.parent);throw new Error(\"Unexpected path\")}function Ll(e,t,n,a){const r=Array.isArray(e)?[]:{};for(const[i,s]of Object.entries(e))i===\"parent\"?r.parent=Array.isArray(n)?a:n:s&&typeof s==\"object\"?r[i]=Ll(s,t,r,n):(i===\"type\"&&s===\"CapturingGroup\"&&t.set(r,t.get(e)??e),r[i]=s);return r}function eo(e){const t=$l(e);return t.isRecursive=!0,t}function Zb(e,t){const n=[];for(;e=e.parent;)(!t||t(e))&&n.push(e);return n}function sr(e,t){if(t.has(e))return t.get(e);const n=`$${t.size}_${e.replace(/^[^$_\\p{IDS}]|[^$\\u200C\\u200D\\p{IDC}]/ug,\"_\")}`;return t.set(e,n),n}function Pl(e){const t=[\"dotAll\",\"ignoreCase\"],n={enable:{},disable:{}};return e.forEach(({flags:a})=>{t.forEach(r=>{a.enable?.[r]&&(delete n.disable[r],n.enable[r]=!0),a.disable?.[r]&&(n.disable[r]=!0)})}),Object.keys(n.enable).length||delete n.enable,Object.keys(n.disable).length||delete n.disable,n.enable||n.disable?n:null}function Yb({dotAll:e,ignoreCase:t}){const n={};return(e||t)&&(n.enable={},e&&(n.enable.dotAll=!0),t&&(n.enable.ignoreCase=!0)),(!e||!t)&&(n.disable={},!e&&(n.disable.dotAll=!0),!t&&(n.disable.ignoreCase=!0)),n}function Dl(e){if(!e)throw new Error(\"Node expected\");const{body:t}=e;return Array.isArray(t)?t:t?[t]:null}function Ml(e){const t=e.find(n=>n.kind===\"search_start\"||Qb(n,{negate:!1})||!Xb(n));if(!t)return null;if(t.kind===\"search_start\")return t;if(t.type===\"LookaroundAssertion\")return t.body[0].body[0];if(t.type===\"CapturingGroup\"||t.type===\"Group\"){const n=[];for(const a of t.body){const r=Ml(a.body);if(!r)return null;Array.isArray(r)?n.push(...r):n.push(r)}return n}return null}function ql(e,t){const n=Dl(e)??[];for(const a of n)if(a===t||ql(a,t))return!0;return!1}function Xb({type:e}){return e===\"Assertion\"||e===\"Directive\"||e===\"LookaroundAssertion\"}function Kb(e){const t=[\"Character\",\"CharacterClass\",\"CharacterSet\"];return t.includes(e.type)||e.type===\"Quantifier\"&&e.min&&t.includes(e.body.type)}function Qb(e,t){const n={negate:null,...t};return e.type===\"LookaroundAssertion\"&&(n.negate===null||e.negate===n.negate)&&e.body.length===1&&kl(e.body[0],{type:\"Assertion\",kind:\"search_start\"})}function or(e){return/^[$_\\p{IDS}][$\\u200C\\u200D\\p{IDC}]*$/u.test(e)}function Ne(e,t){const a=Cl(e,{...t,unicodePropertyMap:Li}).body;return a.length>1||a[0].body.length>1?be({body:a}):a[0].body[0]}function cr(e,t){return e.negate=t,e}function Ue(e,t){return e.parent=t,e}function B(e,t){return Il(e),e.parent=t,e}function Jb(e,t){const n=Rl(t),a=Gr(n.target,\"ES2024\"),r=Gr(n.target,\"ES2025\"),i=n.rules.recursionLimit;if(!Number.isInteger(i)||i<2||i>20)throw new Error(\"Invalid recursionLimit; use 2-20\");let s=null,o=null;if(!r){const h=[e.flags.ignoreCase];gn(e,e_,{getCurrentModI:()=>h.at(-1),popModI(){h.pop()},pushModI(g){h.push(g)},setHasCasedChar(){h.at(-1)?s=!0:o=!0}})}const c={dotAll:e.flags.dotAll,ignoreCase:!!((e.flags.ignoreCase||s)&&!o)};let l=e;const u={accuracy:n.accuracy,appliedGlobalFlags:c,captureMap:new Map,currentFlags:{dotAll:e.flags.dotAll,ignoreCase:e.flags.ignoreCase},inCharClass:!1,lastNode:l,originMap:e._originMap,recursionLimit:i,useAppliedIgnoreCase:!!(!r&&s&&o),useFlagMods:r,useFlagV:a,verbose:n.verbose};function p(h){return u.lastNode=l,l=h,Ob(t_[h.type],`Unexpected node type \"${h.type}\"`)(h,u,p)}const m={pattern:e.body.map(p).join(\"|\"),flags:p(e.flags),options:{...e.options}};return a||(delete m.options.force.v,m.options.disable.v=!0,m.options.unicodeSetsPlugin=null),m._captureTransfers=new Map,m._hiddenCaptures=[],u.captureMap.forEach((h,g)=>{h.hidden&&m._hiddenCaptures.push(g),h.transferTo&&En(m._captureTransfers,h.transferTo,[]).push(g)}),m}var e_={\"*\":{enter({node:e},t){if(no(e)){const n=t.getCurrentModI();t.pushModI(e.flags?Ca({ignoreCase:n},e.flags).ignoreCase:n)}},exit({node:e},t){no(e)&&t.popModI()}},Backreference(e,t){t.setHasCasedChar()},Character({node:e},t){Pi(V(e.value))&&t.setHasCasedChar()},CharacterClassRange({node:e,skip:t},n){t(),zl(e,{firstOnly:!0}).length&&n.setHasCasedChar()},CharacterSet({node:e},t){e.kind===\"property\"&&Nl.has(e.value)&&t.setHasCasedChar()}},t_={Alternative({body:e},t,n){return e.map(n).join(\"\")},Assertion({kind:e,negate:t}){if(e===\"string_end\")return\"$\";if(e===\"string_start\")return\"^\";if(e===\"word_boundary\")return t?j`\\B`:j`\\b`;throw new Error(`Unexpected assertion kind \"${e}\"`)},Backreference({ref:e},t){if(typeof e!=\"number\")throw new Error(\"Unexpected named backref in transformed AST\");if(!t.useFlagMods&&t.accuracy===\"strict\"&&t.currentFlags.ignoreCase&&!t.captureMap.get(e).ignoreCase)throw new Error(\"Use of case-insensitive backref to case-sensitive group requires target ES2025 or non-strict accuracy\");return\"\\\\\"+e},CapturingGroup(e,t,n){const{body:a,name:r,number:i}=e,s={ignoreCase:t.currentFlags.ignoreCase},o=t.originMap.get(e);return o&&(s.hidden=!0,i>o.number&&(s.transferTo=o.number)),t.captureMap.set(i,s),`(${r?`?<${r}>`:\"\"}${a.map(n).join(\"|\")})`},Character({value:e},t){const n=V(e),a=Ft(e,{escDigit:t.lastNode.type===\"Backreference\",inCharClass:t.inCharClass,useFlagV:t.useFlagV});if(a!==n)return a;if(t.useAppliedIgnoreCase&&t.currentFlags.ignoreCase&&Pi(n)){const r=Ol(n);return t.inCharClass?r.join(\"\"):r.length>1?`[${r.join(\"\")}]`:r[0]}return n},CharacterClass(e,t,n){const{kind:a,negate:r,parent:i}=e;let{body:s}=e;if(a===\"intersection\"&&!t.useFlagV)throw new Error(\"Use of character class intersection requires min target ES2024\");Le.bugFlagVLiteralHyphenIsRange&&t.useFlagV&&s.some(ao)&&(s=[La(45),...s.filter(l=>!ao(l))]);const o=()=>`[${r?\"^\":\"\"}${s.map(n).join(a===\"intersection\"?\"&&\":\"\")}]`;if(!t.inCharClass){if((!t.useFlagV||Le.bugNestedClassIgnoresNegation)&&!r){const u=s.filter(p=>p.type===\"CharacterClass\"&&p.kind===\"union\"&&p.negate);if(u.length){const p=be(),m=p.body[0];return p.parent=i,m.parent=p,s=s.filter(h=>!u.includes(h)),e.body=s,s.length?(e.parent=m,m.body.push(e)):p.body.pop(),u.forEach(h=>{const g=bt({body:[h]});h.parent=g,g.parent=p,p.body.push(g)}),n(p)}}t.inCharClass=!0;const l=o();return t.inCharClass=!1,l}const c=s[0];if(a===\"union\"&&!r&&c&&((!t.useFlagV||!t.verbose)&&i.kind===\"union\"&&!(Le.bugFlagVLiteralHyphenIsRange&&t.useFlagV)||!t.verbose&&i.kind===\"intersection\"&&s.length===1&&c.type!==\"CharacterClassRange\"))return s.map(n).join(\"\");if(!t.useFlagV&&i.type===\"CharacterClass\")throw new Error(\"Uses nested character class in a way that requires min target ES2024\");return o()},CharacterClassRange(e,t){const n=e.min.value,a=e.max.value,r={escDigit:!1,inCharClass:!0,useFlagV:t.useFlagV},i=Ft(n,r),s=Ft(a,r),o=new Set;if(t.useAppliedIgnoreCase&&t.currentFlags.ignoreCase){const c=zl(e);s_(c).forEach(u=>{o.add(Array.isArray(u)?`${Ft(u[0],r)}-${Ft(u[1],r)}`:Ft(u,r))})}return`${i}-${s}${[...o].join(\"\")}`},CharacterSet({kind:e,negate:t,value:n,key:a},r){if(e===\"dot\")return r.currentFlags.dotAll?r.appliedGlobalFlags.dotAll||r.useFlagMods?\".\":\"[^]\":j`[^\\n]`;if(e===\"digit\")return t?j`\\D`:j`\\d`;if(e===\"property\"){if(r.useAppliedIgnoreCase&&r.currentFlags.ignoreCase&&Nl.has(n))throw new Error(`Unicode property \"${n}\" can't be case-insensitive when other chars have specific case`);return`${t?j`\\P`:j`\\p`}{${a?`${a}=`:\"\"}${n}}`}if(e===\"word\")return t?j`\\W`:j`\\w`;throw new Error(`Unexpected character set kind \"${e}\"`)},Flags(e,t){return(t.appliedGlobalFlags.ignoreCase?\"i\":\"\")+(e.dotAll?\"s\":\"\")+(e.sticky?\"y\":\"\")},Group({atomic:e,body:t,flags:n,parent:a},r,i){const s=r.currentFlags;n&&(r.currentFlags=Ca(s,n));const o=t.map(i).join(\"|\"),c=!r.verbose&&t.length===1&&a.type!==\"Quantifier\"&&!e&&(!r.useFlagMods||!n)?o:`(?${o_(e,n,r.useFlagMods)}${o})`;return r.currentFlags=s,c},LookaroundAssertion({body:e,kind:t,negate:n},a,r){return`(?${`${t===\"lookahead\"?\"\":\"<\"}${n?\"!\":\"=\"}`}${e.map(r).join(\"|\")})`},Quantifier(e,t,n){return n(e.body)+c_(e)},Subroutine({isRecursive:e,ref:t},n){if(!e)throw new Error(\"Unexpected non-recursive subroutine in transformed AST\");const a=n.recursionLimit;return t===0?`(?R=${a})`:j`\\g<${t}&R=${a}>`}},n_=new Set([\"$\",\"(\",\")\",\"*\",\"+\",\".\",\"?\",\"[\",\"\\\\\",\"]\",\"^\",\"{\",\"|\",\"}\"]),a_=new Set([\"-\",\"\\\\\",\"]\",\"^\",\"[\"]),r_=new Set([\"(\",\")\",\"-\",\"/\",\"[\",\"\\\\\",\"]\",\"^\",\"{\",\"|\",\"}\",\"!\",\"#\",\"$\",\"%\",\"&\",\"*\",\"+\",\",\",\".\",\":\",\";\",\"<\",\"=\",\">\",\"?\",\"@\",\"`\",\"~\"]),to=new Map([[9,j`\\t`],[10,j`\\n`],[11,j`\\v`],[12,j`\\f`],[13,j`\\r`],[8232,j`\\u2028`],[8233,j`\\u2029`],[65279,j`\\uFEFF`]]),i_=new RegExp(\"^\\\\p{Cased}$\",\"u\");function Pi(e){return i_.test(e)}function zl(e,t){const n=!!t?.firstOnly,a=e.min.value,r=e.max.value,i=[];if(a<65&&(r===65535||r>=131071)||a===65536&&r>=131071)return i;for(let s=a;s<=r;s++){const o=V(s);if(!Pi(o))continue;const c=Ol(o).filter(l=>{const u=l.codePointAt(0);return u<a||u>r});if(c.length&&(i.push(...c),n))break}return i}function Ft(e,{escDigit:t,inCharClass:n,useFlagV:a}){if(to.has(e))return to.get(e);if(e<32||e>126&&e<160||e>262143||t&&l_(e))return e>255?`\\\\u{${e.toString(16).toUpperCase()}}`:`\\\\x${e.toString(16).toUpperCase().padStart(2,\"0\")}`;const r=n?a?r_:a_:n_,i=V(e);return(r.has(i)?\"\\\\\":\"\")+i}function s_(e){const t=e.map(r=>r.codePointAt(0)).sort((r,i)=>r-i),n=[];let a=null;for(let r=0;r<t.length;r++)t[r+1]===t[r]+1?a??=t[r]:a===null?n.push(t[r]):(n.push([a,t[r]]),a=null);return n}function o_(e,t,n){if(e)return\">\";let a=\"\";if(t&&n){const{enable:r,disable:i}=t;a=(r?.ignoreCase?\"i\":\"\")+(r?.dotAll?\"s\":\"\")+(i?\"-\":\"\")+(i?.ignoreCase?\"i\":\"\")+(i?.dotAll?\"s\":\"\")}return`${a}:`}function c_({kind:e,max:t,min:n}){let a;return!n&&t===1?a=\"?\":!n&&t===1/0?a=\"*\":n===1&&t===1/0?a=\"+\":n===t?a=`{${n}}`:a=`{${n},${t===1/0?\"\":t}}`,a+{greedy:\"\",lazy:\"?\",possessive:\"+\"}[e]}function no({type:e}){return e===\"CapturingGroup\"||e===\"Group\"||e===\"LookaroundAssertion\"}function l_(e){return e>47&&e<58}function ao({type:e,value:t}){return e===\"Character\"&&t===45}var u_=class Hr extends RegExp{#t=new Map;#e=null;#a;#n=null;#r=null;rawOptions={};get source(){return this.#a||\"(?:)\"}constructor(t,n,a){const r=!!a?.lazyCompile;if(t instanceof RegExp){if(a)throw new Error(\"Cannot provide options when copying a regexp\");const i=t;super(i,n),this.#a=i.source,i instanceof Hr&&(this.#t=i.#t,this.#n=i.#n,this.#r=i.#r,this.rawOptions=i.rawOptions)}else{const i={hiddenCaptures:[],strategy:null,transfers:[],...a};super(r?\"\":t,n),this.#a=t,this.#t=d_(i.hiddenCaptures,i.transfers),this.#r=i.strategy,this.rawOptions=a??{}}r||(this.#e=this)}exec(t){if(!this.#e){const{lazyCompile:r,...i}=this.rawOptions;this.#e=new Hr(this.#a,this.flags,i)}const n=this.global||this.sticky,a=this.lastIndex;if(this.#r===\"clip_search\"&&n&&a){this.lastIndex=0;const r=this.#i(t.slice(a));return r&&(p_(r,a,t,this.hasIndices),this.lastIndex+=a),r}return this.#i(t)}#i(t){this.#e.lastIndex=this.lastIndex;const n=super.exec.call(this.#e,t);if(this.lastIndex=this.#e.lastIndex,!n||!this.#t.size)return n;const a=[...n];n.length=1;let r;this.hasIndices&&(r=[...n.indices],n.indices.length=1);const i=[0];for(let s=1;s<a.length;s++){const{hidden:o,transferTo:c}=this.#t.get(s)??{};if(o?i.push(null):(i.push(n.length),n.push(a[s]),this.hasIndices&&n.indices.push(r[s])),c&&a[s]!==void 0){const l=i[c];if(!l)throw new Error(`Invalid capture transfer to \"${l}\"`);if(n[l]=a[s],this.hasIndices&&(n.indices[l]=r[s]),n.groups){this.#n||(this.#n=m_(this.source));const u=this.#n.get(c);u&&(n.groups[u]=a[s],this.hasIndices&&(n.indices.groups[u]=r[s]))}}}return n}};function p_(e,t,n,a){if(e.index+=t,e.input=n,a){const r=e.indices;for(let s=0;s<r.length;s++){const o=r[s];o&&(r[s]=[o[0]+t,o[1]+t])}const i=r.groups;i&&Object.keys(i).forEach(s=>{const o=i[s];o&&(i[s]=[o[0]+t,o[1]+t])})}}function d_(e,t){const n=new Map;for(const a of e)n.set(a,{hidden:!0});for(const[a,r]of t)for(const i of r)En(n,i,{}).transferTo=a;return n}function m_(e){const t=/(?<capture>\\((?:\\?<(?![=!])(?<name>[^>]+)>|(?!\\?)))|\\\\?./gsu,n=new Map;let a=0,r=0,i;for(;i=t.exec(e);){const{0:s,groups:{capture:o,name:c}}=i;s===\"[\"?a++:a?s===\"]\"&&a--:o&&(r++,c&&n.set(r,c))}return n}function h_(e,t){const n=g_(e,t);return n.options?new u_(n.pattern,n.flags,n.options):new RegExp(n.pattern,n.flags)}function g_(e,t){const n=Rl(t),a=Cl(e,{flags:n.flags,normalizeUnknownPropertyNames:!0,rules:{captureGroup:n.rules.captureGroup,singleline:n.rules.singleline},skipBackrefValidation:n.rules.allowOrphanBackrefs,unicodePropertyMap:Li}),r=Bb(a,{accuracy:n.accuracy,asciiWordBoundaries:n.rules.asciiWordBoundaries,avoidSubclass:n.avoidSubclass,bestEffortTarget:n.target}),i=Jb(r,n),s=Tb(i.pattern,{captureTransfers:i._captureTransfers,hiddenCaptures:i._hiddenCaptures,mode:\"external\"}),o=Sb(s.pattern),c=jb(o.pattern,{captureTransfers:s.captureTransfers,hiddenCaptures:s.hiddenCaptures}),l={pattern:c.pattern,flags:`${n.hasIndices?\"d\":\"\"}${n.global?\"g\":\"\"}${i.flags}${i.options.disable.v?\"u\":\"v\"}`};if(n.avoidSubclass){if(n.lazyCompileLength!==1/0)throw new Error(\"Lazy compilation requires subclass\")}else{const u=c.hiddenCaptures.sort((g,_)=>g-_),p=Array.from(c.captureTransfers),m=r._strategy,h=l.pattern.length>=n.lazyCompileLength;(u.length||p.length||m||h)&&(l.options={...u.length&&{hiddenCaptures:u},...p.length&&{transfers:p},...m&&{strategy:m},...h&&{lazyCompile:h}})}return l}const ro=4294967295;class f_{constructor(t,n={}){this.patterns=t,this.options=n;const{forgiving:a=!1,cache:r,regexConstructor:i}=n;if(!i)throw new Error(\"Option `regexConstructor` is not provided\");this.regexps=t.map(s=>{if(typeof s!=\"string\")return s;const o=r?.get(s);if(o){if(o instanceof RegExp)return o;if(a)return null;throw o}try{const c=i(s);return r?.set(s,c),c}catch(c){if(r?.set(s,c),a)return null;throw c}})}regexps;findNextMatchSync(t,n,a){const r=typeof t==\"string\"?t:t.content,i=[];function s(o,c,l=0){return{index:o,captureIndices:c.indices.map(u=>u==null?{start:ro,end:ro,length:0}:{start:u[0]+l,end:u[1]+l,length:u[1]-u[0]})}}for(let o=0;o<this.regexps.length;o++){const c=this.regexps[o];if(c)try{c.lastIndex=n;const l=c.exec(r);if(!l)continue;if(l.index===n)return s(o,l,0);i.push([o,l,0])}catch(l){if(this.options.forgiving)continue;throw l}}if(i.length){const o=Math.min(...i.map(c=>c[1].index));for(const[c,l,u]of i)if(l.index===o)return s(c,l,u)}return null}}function b_(e,t){return h_(e,{global:!0,hasIndices:!0,lazyCompileLength:3e3,rules:{allowOrphanBackrefs:!0,asciiWordBoundaries:!0,captureGroup:!0,recursionLimit:5,singleline:!0},...t})}function __(e={}){const t=Object.assign({target:\"auto\",cache:new Map},e);return t.regexConstructor||=n=>b_(n,{target:t.target}),{createScanner(n){return new f_(n,t)},createString(n){return{content:n}}}}const y_=Object.freeze(JSON.parse('{\"displayName\":\"JSON\",\"name\":\"json\",\"patterns\":[{\"include\":\"#value\"}],\"repository\":{\"array\":{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.array.begin.json\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.array.end.json\"}},\"name\":\"meta.structure.array.json\",\"patterns\":[{\"include\":\"#value\"},{\"match\":\",\",\"name\":\"punctuation.separator.array.json\"},{\"match\":\"[^]\\\\\\\\s]\",\"name\":\"invalid.illegal.expected-array-separator.json\"}]},\"comments\":{\"patterns\":[{\"begin\":\"/\\\\\\\\*\\\\\\\\*(?!/)\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.json\"}},\"end\":\"\\\\\\\\*/\",\"name\":\"comment.block.documentation.json\"},{\"begin\":\"/\\\\\\\\*\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.json\"}},\"end\":\"\\\\\\\\*/\",\"name\":\"comment.block.json\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.json\"}},\"match\":\"(//).*$\\\\\\\\n?\",\"name\":\"comment.line.double-slash.js\"}]},\"constant\":{\"match\":\"\\\\\\\\b(?:true|false|null)\\\\\\\\b\",\"name\":\"constant.language.json\"},\"number\":{\"match\":\"-?(?:0|[1-9]\\\\\\\\d*)(?:(?:\\\\\\\\.\\\\\\\\d+)?(?:[Ee][-+]?\\\\\\\\d+)?)?\",\"name\":\"constant.numeric.json\"},\"object\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.dictionary.begin.json\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.dictionary.end.json\"}},\"name\":\"meta.structure.dictionary.json\",\"patterns\":[{\"include\":\"#objectkey\"},{\"include\":\"#comments\"},{\"begin\":\":\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.separator.dictionary.key-value.json\"}},\"end\":\"(,)|(?=})\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.separator.dictionary.pair.json\"}},\"name\":\"meta.structure.dictionary.value.json\",\"patterns\":[{\"include\":\"#value\"},{\"match\":\"[^,\\\\\\\\s]\",\"name\":\"invalid.illegal.expected-dictionary-separator.json\"}]},{\"match\":\"[^}\\\\\\\\s]\",\"name\":\"invalid.illegal.expected-dictionary-separator.json\"}]},\"objectkey\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.support.type.property-name.begin.json\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.support.type.property-name.end.json\"}},\"name\":\"string.json support.type.property-name.json\",\"patterns\":[{\"include\":\"#stringcontent\"}]},\"string\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.json\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.json\"}},\"name\":\"string.quoted.double.json\",\"patterns\":[{\"include\":\"#stringcontent\"}]},\"stringcontent\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\(?:[\\\\\"/\\\\\\\\\\\\\\\\bfnrt]|u\\\\\\\\h{4})\",\"name\":\"constant.character.escape.json\"},{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"invalid.illegal.unrecognized-string-escape.json\"}]},\"value\":{\"patterns\":[{\"include\":\"#constant\"},{\"include\":\"#number\"},{\"include\":\"#string\"},{\"include\":\"#array\"},{\"include\":\"#object\"},{\"include\":\"#comments\"}]}},\"scopeName\":\"source.json\"}')),Bl=[y_],v_=Object.freeze(JSON.parse(`{\"displayName\":\"JavaScript\",\"name\":\"javascript\",\"patterns\":[{\"include\":\"#directives\"},{\"include\":\"#statements\"},{\"include\":\"#shebang\"}],\"repository\":{\"access-modifier\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(abstract|declare|override|public|protected|private|readonly|static)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"storage.modifier.js\"},\"after-operator-block-as-object-literal\":{\"begin\":\"(?<!\\\\\\\\+\\\\\\\\+|--)(?<=[!(+,:=>?\\\\\\\\[]|^await|[^$._[:alnum:]]await|^return|[^$._[:alnum:]]return|^yield|[^$._[:alnum:]]yield|^throw|[^$._[:alnum:]]throw|^in|[^$._[:alnum:]]in|^of|[^$._[:alnum:]]of|^typeof|[^$._[:alnum:]]typeof|&&|\\\\\\\\|\\\\\\\\||\\\\\\\\*)\\\\\\\\s*(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"meta.objectliteral.js\",\"patterns\":[{\"include\":\"#object-member\"}]},\"array-binding-pattern\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"patterns\":[{\"include\":\"#binding-element\"},{\"include\":\"#punctuation-comma\"}]},\"array-binding-pattern-const\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"patterns\":[{\"include\":\"#binding-element-const\"},{\"include\":\"#punctuation-comma\"}]},\"array-literal\":{\"begin\":\"\\\\\\\\s*(\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"meta.brace.square.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.square.js\"}},\"name\":\"meta.array.literal.js\",\"patterns\":[{\"include\":\"#expression\"},{\"include\":\"#punctuation-comma\"}]},\"arrow-function\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.modifier.async.js\"},\"2\":{\"name\":\"variable.parameter.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))\\\\\\\\b(async)\\\\\\\\s+)?([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?==>)\",\"name\":\"meta.arrow.js\"},{\"begin\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))\\\\\\\\b(async))?((?<![]!)}])\\\\\\\\s*(?=((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"}},\"end\":\"(?==>|\\\\\\\\{|^(\\\\\\\\s*(export|function|class|interface|let|var|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|const|import|enum|namespace|module|type|abstract|declare)\\\\\\\\s+))\",\"name\":\"meta.arrow.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-parameters\"},{\"include\":\"#function-parameters\"},{\"include\":\"#arrow-return-type\"},{\"include\":\"#possibly-arrow-return-type\"}]},{\"begin\":\"=>\",\"beginCaptures\":{\"0\":{\"name\":\"storage.type.function.arrow.js\"}},\"end\":\"((?<=[}\\\\\\\\S])(?<!=>)|((?!\\\\\\\\{)(?=\\\\\\\\S)))(?!/[*/])\",\"name\":\"meta.arrow.js\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#decl-block\"},{\"include\":\"#expression\"}]}]},\"arrow-return-type\":{\"begin\":\"(?<=\\\\\\\\))\\\\\\\\s*(:)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?==>|\\\\\\\\{|^(\\\\\\\\s*(export|function|class|interface|let|var|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|const|import|enum|namespace|module|type|abstract|declare)\\\\\\\\s+))\",\"name\":\"meta.return.type.arrow.js\",\"patterns\":[{\"include\":\"#arrow-return-type-body\"}]},\"arrow-return-type-body\":{\"patterns\":[{\"begin\":\"(?<=:)(?=\\\\\\\\s*\\\\\\\\{)\",\"end\":\"(?<=})\",\"patterns\":[{\"include\":\"#type-object\"}]},{\"include\":\"#type-predicate-operator\"},{\"include\":\"#type\"}]},\"async-modifier\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(async)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"storage.modifier.async.js\"},\"binding-element\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#numeric-literal\"},{\"include\":\"#regex\"},{\"include\":\"#object-binding-pattern\"},{\"include\":\"#array-binding-pattern\"},{\"include\":\"#destructuring-variable-rest\"},{\"include\":\"#variable-initializer\"}]},\"binding-element-const\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#numeric-literal\"},{\"include\":\"#regex\"},{\"include\":\"#object-binding-pattern-const\"},{\"include\":\"#array-binding-pattern-const\"},{\"include\":\"#destructuring-variable-rest-const\"},{\"include\":\"#variable-initializer\"}]},\"boolean-literal\":{\"patterns\":[{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))true(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.boolean.true.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))false(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.boolean.false.js\"}]},\"brackets\":{\"patterns\":[{\"begin\":\"\\\\\\\\{\",\"end\":\"}|(?=\\\\\\\\*/)\",\"patterns\":[{\"include\":\"#brackets\"}]},{\"begin\":\"\\\\\\\\[\",\"end\":\"]|(?=\\\\\\\\*/)\",\"patterns\":[{\"include\":\"#brackets\"}]}]},\"cast\":{\"patterns\":[{\"include\":\"#jsx\"}]},\"class-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(?:(abstract)\\\\\\\\s+)?\\\\\\\\b(class)\\\\\\\\b(?=\\\\\\\\s+|/[*/])\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.type.class.js\"}},\"end\":\"(?<=})\",\"name\":\"meta.class.js\",\"patterns\":[{\"include\":\"#class-declaration-or-expression-patterns\"}]},\"class-declaration-or-expression-patterns\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#class-or-interface-heritage\"},{\"captures\":{\"0\":{\"name\":\"entity.name.type.class.js\"}},\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\"},{\"include\":\"#type-parameters\"},{\"include\":\"#class-or-interface-body\"}]},\"class-expression\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(abstract)\\\\\\\\s+)?(class)\\\\\\\\b(?=\\\\\\\\s+|[<{]|/[*/])\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"storage.type.class.js\"}},\"end\":\"(?<=})\",\"name\":\"meta.class.js\",\"patterns\":[{\"include\":\"#class-declaration-or-expression-patterns\"}]},\"class-or-interface-body\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#decorator\"},{\"begin\":\"(?<=:)\\\\\\\\s*\",\"end\":\"(?=[-\\\\\\\\])+,:;}\\\\\\\\s]|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"patterns\":[{\"include\":\"#expression\"}]},{\"include\":\"#method-declaration\"},{\"include\":\"#indexer-declaration\"},{\"include\":\"#field-declaration\"},{\"include\":\"#string\"},{\"include\":\"#type-annotation\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#access-modifier\"},{\"include\":\"#property-accessor\"},{\"include\":\"#async-modifier\"},{\"include\":\"#after-operator-block-as-object-literal\"},{\"include\":\"#decl-block\"},{\"include\":\"#expression\"},{\"include\":\"#punctuation-comma\"},{\"include\":\"#punctuation-semicolon\"}]},\"class-or-interface-heritage\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))\\\\\\\\b(extends|implements)\\\\\\\\b(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"end\":\"(?=\\\\\\\\{)\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#class-or-interface-heritage\"},{\"include\":\"#type-parameters\"},{\"include\":\"#expressionWithoutIdentifiers\"},{\"captures\":{\"1\":{\"name\":\"entity.name.type.module.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))(?=\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*)*\\\\\\\\s*)\"},{\"captures\":{\"1\":{\"name\":\"entity.other.inherited-class.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\"},{\"include\":\"#expressionPunctuations\"}]},\"comment\":{\"patterns\":[{\"begin\":\"/\\\\\\\\*\\\\\\\\*(?!/)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"name\":\"comment.block.documentation.js\",\"patterns\":[{\"include\":\"#docblock\"}]},{\"begin\":\"(/\\\\\\\\*)(?:\\\\\\\\s*((@)internal)(?=\\\\\\\\s|(\\\\\\\\*/)))?\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.comment.js\"},\"2\":{\"name\":\"storage.type.internaldeclaration.js\"},\"3\":{\"name\":\"punctuation.decorator.internaldeclaration.js\"}},\"end\":\"\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"name\":\"comment.block.js\"},{\"begin\":\"(^[\\\\\\\\t ]+)?((//)(?:\\\\\\\\s*((@)internal)(?=\\\\\\\\s|$))?)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.js\"},\"2\":{\"name\":\"comment.line.double-slash.js\"},\"3\":{\"name\":\"punctuation.definition.comment.js\"},\"4\":{\"name\":\"storage.type.internaldeclaration.js\"},\"5\":{\"name\":\"punctuation.decorator.internaldeclaration.js\"}},\"contentName\":\"comment.line.double-slash.js\",\"end\":\"(?=$)\"}]},\"control-statement\":{\"patterns\":[{\"include\":\"#switch-statement\"},{\"include\":\"#for-loop\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(catch|finally|throw|try)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.trycatch.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.loop.js\"},\"2\":{\"name\":\"entity.name.label.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(break|continue|goto)\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(break|continue|do|goto|while)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.loop.js\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(return)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.flow.js\"}},\"end\":\"(?=[;}]|$|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"patterns\":[{\"include\":\"#expression\"}]},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(case|default|switch)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.switch.js\"},{\"include\":\"#if-statement\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(else|if)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.conditional.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(with)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.with.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(package)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(debugger)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.other.debugger.js\"}]},\"decl-block\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"meta.block.js\",\"patterns\":[{\"include\":\"#statements\"}]},\"declaration\":{\"patterns\":[{\"include\":\"#decorator\"},{\"include\":\"#var-expr\"},{\"include\":\"#function-declaration\"},{\"include\":\"#class-declaration\"},{\"include\":\"#interface-declaration\"},{\"include\":\"#enum-declaration\"},{\"include\":\"#namespace-declaration\"},{\"include\":\"#type-alias-declaration\"},{\"include\":\"#import-equals-declaration\"},{\"include\":\"#import-declaration\"},{\"include\":\"#export-declaration\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(declare|export)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"storage.modifier.js\"}]},\"decorator\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))@\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.decorator.js\"}},\"end\":\"(?=\\\\\\\\s)\",\"name\":\"meta.decorator.js\",\"patterns\":[{\"include\":\"#expression\"}]},\"destructuring-const\":{\"patterns\":[{\"begin\":\"(?<![:=]|^of|[^$._[:alnum:]]of|^in|[^$._[:alnum:]]in)\\\\\\\\s*(?=\\\\\\\\{)\",\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))\",\"name\":\"meta.object-binding-pattern-variable.js\",\"patterns\":[{\"include\":\"#object-binding-pattern-const\"},{\"include\":\"#type-annotation\"},{\"include\":\"#comment\"}]},{\"begin\":\"(?<![:=]|^of|[^$._[:alnum:]]of|^in|[^$._[:alnum:]]in)\\\\\\\\s*(?=\\\\\\\\[)\",\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))\",\"name\":\"meta.array-binding-pattern-variable.js\",\"patterns\":[{\"include\":\"#array-binding-pattern-const\"},{\"include\":\"#type-annotation\"},{\"include\":\"#comment\"}]}]},\"destructuring-parameter\":{\"patterns\":[{\"begin\":\"(?<![:=])\\\\\\\\s*(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"name\":\"meta.parameter.object-binding-pattern.js\",\"patterns\":[{\"include\":\"#parameter-object-binding-element\"}]},{\"begin\":\"(?<![:=])\\\\\\\\s*(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"name\":\"meta.paramter.array-binding-pattern.js\",\"patterns\":[{\"include\":\"#parameter-binding-element\"},{\"include\":\"#punctuation-comma\"}]}]},\"destructuring-parameter-rest\":{\"captures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"variable.parameter.js\"}},\"match\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?([$_[:alpha:]][$_[:alnum:]]*)\"},\"destructuring-variable\":{\"patterns\":[{\"begin\":\"(?<![:=]|^of|[^$._[:alnum:]]of|^in|[^$._[:alnum:]]in)\\\\\\\\s*(?=\\\\\\\\{)\",\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))\",\"name\":\"meta.object-binding-pattern-variable.js\",\"patterns\":[{\"include\":\"#object-binding-pattern\"},{\"include\":\"#type-annotation\"},{\"include\":\"#comment\"}]},{\"begin\":\"(?<![:=]|^of|[^$._[:alnum:]]of|^in|[^$._[:alnum:]]in)\\\\\\\\s*(?=\\\\\\\\[)\",\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))\",\"name\":\"meta.array-binding-pattern-variable.js\",\"patterns\":[{\"include\":\"#array-binding-pattern\"},{\"include\":\"#type-annotation\"},{\"include\":\"#comment\"}]}]},\"destructuring-variable-rest\":{\"captures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"meta.definition.variable.js variable.other.readwrite.js\"}},\"match\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?([$_[:alpha:]][$_[:alnum:]]*)\"},\"destructuring-variable-rest-const\":{\"captures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"meta.definition.variable.js variable.other.constant.js\"}},\"match\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?([$_[:alpha:]][$_[:alnum:]]*)\"},\"directives\":{\"begin\":\"^(///)\\\\\\\\s*(?=<(reference|amd-dependency|amd-module)(\\\\\\\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\\\\\\\s*=\\\\\\\\s*(('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)))+\\\\\\\\s*/>\\\\\\\\s*$)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"(?=$)\",\"name\":\"comment.line.triple-slash.directive.js\",\"patterns\":[{\"begin\":\"(<)(reference|amd-dependency|amd-module)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.directive.js\"},\"2\":{\"name\":\"entity.name.tag.directive.js\"}},\"end\":\"/>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.directive.js\"}},\"name\":\"meta.tag.js\",\"patterns\":[{\"match\":\"path|types|no-default-lib|lib|name|resolution-mode\",\"name\":\"entity.other.attribute-name.directive.js\"},{\"match\":\"=\",\"name\":\"keyword.operator.assignment.js\"},{\"include\":\"#string\"}]}]},\"docblock\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"constant.language.access-type.jsdoc\"}},\"match\":\"((@)a(?:ccess|pi))\\\\\\\\s+(p(?:rivate|rotected|ublic))\\\\\\\\b\"},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"entity.name.type.instance.jsdoc\"},\"4\":{\"name\":\"punctuation.definition.bracket.angle.begin.jsdoc\"},\"5\":{\"name\":\"constant.other.email.link.underline.jsdoc\"},\"6\":{\"name\":\"punctuation.definition.bracket.angle.end.jsdoc\"}},\"match\":\"((@)author)\\\\\\\\s+([^*/<>@\\\\\\\\s](?:[^*/<>@]|\\\\\\\\*[^/])*)(?:\\\\\\\\s*(<)([^>\\\\\\\\s]+)(>))?\"},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"entity.name.type.instance.jsdoc\"},\"4\":{\"name\":\"keyword.operator.control.jsdoc\"},\"5\":{\"name\":\"entity.name.type.instance.jsdoc\"}},\"match\":\"((@)borrows)\\\\\\\\s+((?:[^*/@\\\\\\\\s]|\\\\\\\\*[^/])+)\\\\\\\\s+(as)\\\\\\\\s+((?:[^*/@\\\\\\\\s]|\\\\\\\\*[^/])+)\"},{\"begin\":\"((@)example)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"end\":\"(?=@|\\\\\\\\*/)\",\"name\":\"meta.example.jsdoc\",\"patterns\":[{\"match\":\"^\\\\\\\\s\\\\\\\\*\\\\\\\\s+\"},{\"begin\":\"\\\\\\\\G(<)caption(>)\",\"beginCaptures\":{\"0\":{\"name\":\"entity.name.tag.inline.jsdoc\"},\"1\":{\"name\":\"punctuation.definition.bracket.angle.begin.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.bracket.angle.end.jsdoc\"}},\"contentName\":\"constant.other.description.jsdoc\",\"end\":\"(</)caption(>)|(?=\\\\\\\\*/)\",\"endCaptures\":{\"0\":{\"name\":\"entity.name.tag.inline.jsdoc\"},\"1\":{\"name\":\"punctuation.definition.bracket.angle.begin.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.bracket.angle.end.jsdoc\"}}},{\"captures\":{\"0\":{\"name\":\"source.embedded.js\"}},\"match\":\"[^*@\\\\\\\\s](?:[^*]|\\\\\\\\*[^/])*\"}]},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"constant.language.symbol-type.jsdoc\"}},\"match\":\"((@)kind)\\\\\\\\s+(class|constant|event|external|file|function|member|mixin|module|namespace|typedef)\\\\\\\\b\"},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"variable.other.link.underline.jsdoc\"},\"4\":{\"name\":\"entity.name.type.instance.jsdoc\"}},\"match\":\"((@)see)\\\\\\\\s+(?:((?=https?://)(?:[^*\\\\\\\\s]|\\\\\\\\*[^/])+)|((?!https?://|(?:\\\\\\\\[[^]\\\\\\\\[]*])?\\\\\\\\{@(?:link|linkcode|linkplain|tutorial)\\\\\\\\b)(?:[^*/@\\\\\\\\s]|\\\\\\\\*[^/])+))\"},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"variable.other.jsdoc\"}},\"match\":\"((@)template)\\\\\\\\s+([$A-Z_a-z][]$.\\\\\\\\[\\\\\\\\w]*(?:\\\\\\\\s*,\\\\\\\\s*[$A-Z_a-z][]$.\\\\\\\\[\\\\\\\\w]*)*)\"},{\"begin\":\"((@)template)\\\\\\\\s+(?=\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"end\":\"(?=\\\\\\\\s|\\\\\\\\*/|[^]$A-\\\\\\\\[_a-{}])\",\"patterns\":[{\"include\":\"#jsdoctype\"},{\"match\":\"([$A-Z_a-z][]$.\\\\\\\\[\\\\\\\\w]*)\",\"name\":\"variable.other.jsdoc\"}]},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"variable.other.jsdoc\"}},\"match\":\"((@)(?:arg|argument|const|constant|member|namespace|param|var))\\\\\\\\s+([$A-Z_a-z][]$.\\\\\\\\[\\\\\\\\w]*)\"},{\"begin\":\"((@)typedef)\\\\\\\\s+(?=\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"end\":\"(?=\\\\\\\\s|\\\\\\\\*/|[^]$A-\\\\\\\\[_a-{}])\",\"patterns\":[{\"include\":\"#jsdoctype\"},{\"match\":\"(?:[^*/@\\\\\\\\s]|\\\\\\\\*[^/])+\",\"name\":\"entity.name.type.instance.jsdoc\"}]},{\"begin\":\"((@)(?:arg|argument|const|constant|member|namespace|param|prop|property|var))\\\\\\\\s+(?=\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"end\":\"(?=\\\\\\\\s|\\\\\\\\*/|[^]$A-\\\\\\\\[_a-{}])\",\"patterns\":[{\"include\":\"#jsdoctype\"},{\"match\":\"([$A-Z_a-z][]$.\\\\\\\\[\\\\\\\\w]*)\",\"name\":\"variable.other.jsdoc\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.optional-value.begin.bracket.square.jsdoc\"},\"2\":{\"name\":\"keyword.operator.assignment.jsdoc\"},\"3\":{\"name\":\"source.embedded.js\"},\"4\":{\"name\":\"punctuation.definition.optional-value.end.bracket.square.jsdoc\"},\"5\":{\"name\":\"invalid.illegal.syntax.jsdoc\"}},\"match\":\"(\\\\\\\\[)\\\\\\\\s*[$\\\\\\\\w]+(?:(?:\\\\\\\\[])?\\\\\\\\.[$\\\\\\\\w]+)*(?:\\\\\\\\s*(=)\\\\\\\\s*((?>\\\\\"(?:\\\\\\\\*(?!/)|\\\\\\\\\\\\\\\\(?!\\\\\")|[^*\\\\\\\\\\\\\\\\])*?\\\\\"|'(?:\\\\\\\\*(?!/)|\\\\\\\\\\\\\\\\(?!')|[^*\\\\\\\\\\\\\\\\])*?'|\\\\\\\\[(?:\\\\\\\\*(?!/)|[^*])*?]|(?:\\\\\\\\*(?!/)|\\\\\\\\s(?!\\\\\\\\s*])|\\\\\\\\[.*?(?:]|(?=\\\\\\\\*/))|[^]*\\\\\\\\[\\\\\\\\s])*)*))?\\\\\\\\s*(?:(])((?:[^*\\\\\\\\s]|\\\\\\\\*[^/\\\\\\\\s])+)?|(?=\\\\\\\\*/))\",\"name\":\"variable.other.jsdoc\"}]},{\"begin\":\"((@)(?:define|enum|exception|export|extends|lends|implements|modifies|namespace|private|protected|returns?|satisfies|suppress|this|throws|type|yields?))\\\\\\\\s+(?=\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"end\":\"(?=\\\\\\\\s|\\\\\\\\*/|[^]$A-\\\\\\\\[_a-{}])\",\"patterns\":[{\"include\":\"#jsdoctype\"}]},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"entity.name.type.instance.jsdoc\"}},\"match\":\"((@)(?:alias|augments|callback|constructs|emits|event|fires|exports?|extends|external|function|func|host|lends|listens|interface|memberof!?|method|module|mixes|mixin|name|requires|see|this|typedef|uses))\\\\\\\\s+((?:[^*@{}\\\\\\\\s]|\\\\\\\\*[^/])+)\"},{\"begin\":\"((@)(?:default(?:value)?|license|version))\\\\\\\\s+(([\\\\\"']))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"variable.other.jsdoc\"},\"4\":{\"name\":\"punctuation.definition.string.begin.jsdoc\"}},\"contentName\":\"variable.other.jsdoc\",\"end\":\"(\\\\\\\\3)|(?=$|\\\\\\\\*/)\",\"endCaptures\":{\"0\":{\"name\":\"variable.other.jsdoc\"},\"1\":{\"name\":\"punctuation.definition.string.end.jsdoc\"}}},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"},\"3\":{\"name\":\"variable.other.jsdoc\"}},\"match\":\"((@)(?:default(?:value)?|license|tutorial|variation|version))\\\\\\\\s+([^*\\\\\\\\s]+)\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"match\":\"(@)(?:abstract|access|alias|api|arg|argument|async|attribute|augments|author|beta|borrows|bubbles|callback|chainable|class|classdesc|code|config|const|constant|constructor|constructs|copyright|default|defaultvalue|define|deprecated|desc|description|dict|emits|enum|event|example|exception|exports?|extends|extension(?:_?for)?|external|externs|file|fileoverview|final|fires|for|func|function|generator|global|hideconstructor|host|ignore|implements|implicitCast|inherit[Dd]oc|inner|instance|interface|internal|kind|lends|license|listens|main|member|memberof!?|method|mixes|mixins?|modifies|module|name|namespace|noalias|nocollapse|nocompile|nosideeffects|override|overview|package|param|polymer(?:Behavior)?|preserve|private|prop|property|protected|public|read[Oo]nly|record|require[ds]|returns?|see|since|static|struct|submodule|summary|suppress|template|this|throws|todo|tutorial|type|typedef|unrestricted|uses|var|variation|version|virtual|writeOnce|yields?)\\\\\\\\b\",\"name\":\"storage.type.class.jsdoc\"},{\"include\":\"#inline-tags\"},{\"captures\":{\"1\":{\"name\":\"storage.type.class.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.block.tag.jsdoc\"}},\"match\":\"((@)[$_[:alpha:]][$_[:alnum:]]*)(?=\\\\\\\\s+)\"}]},\"enum-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?(?:\\\\\\\\b(const)\\\\\\\\s+)?\\\\\\\\b(enum)\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.type.enum.js\"},\"5\":{\"name\":\"entity.name.type.enum.js\"}},\"end\":\"(?<=})\",\"name\":\"meta.enum.declaration.js\",\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"beginCaptures\":{\"0\":{\"name\":\"variable.other.enummember.js\"}},\"end\":\"(?=[,}]|$)\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#variable-initializer\"}]},{\"begin\":\"(?=(('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+])))\",\"end\":\"(?=[,}]|$)\",\"patterns\":[{\"include\":\"#string\"},{\"include\":\"#array-literal\"},{\"include\":\"#comment\"},{\"include\":\"#variable-initializer\"}]},{\"include\":\"#punctuation-comma\"}]}]},\"export-declaration\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"keyword.control.as.js\"},\"3\":{\"name\":\"storage.type.namespace.js\"},\"4\":{\"name\":\"entity.name.type.module.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(export)\\\\\\\\s+(as)\\\\\\\\s+(namespace)\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(export)(?:\\\\\\\\s+(type))?(?:\\\\\\\\s*(=)|\\\\\\\\s+(default)(?=\\\\\\\\s+))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"keyword.control.type.js\"},\"3\":{\"name\":\"keyword.operator.assignment.js\"},\"4\":{\"name\":\"keyword.control.default.js\"}},\"end\":\"(?=$|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"name\":\"meta.export.default.js\",\"patterns\":[{\"include\":\"#interface-declaration\"},{\"include\":\"#expression\"}]},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(export)(?:\\\\\\\\s+(type))?\\\\\\\\b(?!(\\\\\\\\$)|(\\\\\\\\s*:))((?=\\\\\\\\s*[*{])|((?=\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*([,\\\\\\\\s]))(?!\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"keyword.control.type.js\"}},\"end\":\"(?=$|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"name\":\"meta.export.js\",\"patterns\":[{\"include\":\"#import-export-declaration\"}]}]},\"expression\":{\"patterns\":[{\"include\":\"#expressionWithoutIdentifiers\"},{\"include\":\"#identifiers\"},{\"include\":\"#expressionPunctuations\"}]},\"expression-inside-possibly-arrow-parens\":{\"patterns\":[{\"include\":\"#expressionWithoutIdentifiers\"},{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#decorator\"},{\"include\":\"#destructuring-parameter\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|protected|private|readonly)\\\\\\\\s+(?=(override|public|protected|private|readonly)\\\\\\\\s+)\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"entity.name.function.js variable.language.this.js\"},\"4\":{\"name\":\"entity.name.function.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*(\\\\\\\\??)(?=\\\\\\\\s*(=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))|(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))))|(:\\\\\\\\s*(=>|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(<[^<>]*>)|[^(),<=>])+=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>))))))\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"variable.parameter.js variable.language.this.js\"},\"4\":{\"name\":\"variable.parameter.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*(\\\\\\\\??)(?=\\\\\\\\s*[,:]|$)\"},{\"include\":\"#type-annotation\"},{\"include\":\"#variable-initializer\"},{\"match\":\",\",\"name\":\"punctuation.separator.parameter.js\"},{\"include\":\"#identifiers\"},{\"include\":\"#expressionPunctuations\"}]},\"expression-operators\":{\"patterns\":[{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(await)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.control.flow.js\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(yield)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))(?=\\\\\\\\s*/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*\\\\\\\\*)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.flow.js\"}},\"end\":\"\\\\\\\\*\",\"endCaptures\":{\"0\":{\"name\":\"keyword.generator.asterisk.js\"}},\"patterns\":[{\"include\":\"#comment\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.control.flow.js\"},\"2\":{\"name\":\"keyword.generator.asterisk.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(yield)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))(?:\\\\\\\\s*(\\\\\\\\*))?\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))delete(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.expression.delete.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))in(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))(?!\\\\\\\\()\",\"name\":\"keyword.operator.expression.in.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))of(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))(?!\\\\\\\\()\",\"name\":\"keyword.operator.expression.of.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))instanceof(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.expression.instanceof.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))new(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.new.js\"},{\"include\":\"#typeof-operator\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))void(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.expression.void.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.as.js\"},\"2\":{\"name\":\"storage.modifier.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(as)\\\\\\\\s+(const)(?=\\\\\\\\s*($|[]),:;}]))\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(as)|(satisfies))\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.as.js\"},\"2\":{\"name\":\"keyword.control.satisfies.js\"}},\"end\":\"(?=^|[-\\\\\\\\])+,:;>?}]|\\\\\\\\|\\\\\\\\||&&|!==|$|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(as|satisfies)\\\\\\\\s+)|(\\\\\\\\s+<))\",\"patterns\":[{\"include\":\"#type\"}]},{\"match\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"name\":\"keyword.operator.spread.js\"},{\"match\":\"(?:\\\\\\\\*|(?<!\\\\\\\\()/|[-%+])=\",\"name\":\"keyword.operator.assignment.compound.js\"},{\"match\":\"(?:[\\\\\\\\&^]|<<|>>>??|\\\\\\\\|)=\",\"name\":\"keyword.operator.assignment.compound.bitwise.js\"},{\"match\":\"<<|>>>?\",\"name\":\"keyword.operator.bitwise.shift.js\"},{\"match\":\"[!=]==?\",\"name\":\"keyword.operator.comparison.js\"},{\"match\":\"<=|>=|<>|[<>]\",\"name\":\"keyword.operator.relational.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.operator.logical.js\"},\"2\":{\"name\":\"keyword.operator.assignment.compound.js\"},\"3\":{\"name\":\"keyword.operator.arithmetic.js\"}},\"match\":\"(?<=[$_[:alnum:]])(!)\\\\\\\\s*(?:(/=)|(/)(?![*/]))\"},{\"match\":\"!|&&|\\\\\\\\|\\\\\\\\||\\\\\\\\?\\\\\\\\?\",\"name\":\"keyword.operator.logical.js\"},{\"match\":\"[\\\\\\\\&^|~]\",\"name\":\"keyword.operator.bitwise.js\"},{\"match\":\"=\",\"name\":\"keyword.operator.assignment.js\"},{\"match\":\"--\",\"name\":\"keyword.operator.decrement.js\"},{\"match\":\"\\\\\\\\+\\\\\\\\+\",\"name\":\"keyword.operator.increment.js\"},{\"match\":\"[-%*+/]\",\"name\":\"keyword.operator.arithmetic.js\"},{\"begin\":\"(?<=[]$)_[:alnum:]])\\\\\\\\s*(?=(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)+(?:(/=)|(/)(?![*/])))\",\"end\":\"(/=)|(/)(?!\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/)\",\"endCaptures\":{\"1\":{\"name\":\"keyword.operator.assignment.compound.js\"},\"2\":{\"name\":\"keyword.operator.arithmetic.js\"}},\"patterns\":[{\"include\":\"#comment\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.operator.assignment.compound.js\"},\"2\":{\"name\":\"keyword.operator.arithmetic.js\"}},\"match\":\"(?<=[]$)_[:alnum:]])\\\\\\\\s*(?:(/=)|(/)(?![*/]))\"}]},\"expressionPunctuations\":{\"patterns\":[{\"include\":\"#punctuation-comma\"},{\"include\":\"#punctuation-accessor\"}]},\"expressionWithoutIdentifiers\":{\"patterns\":[{\"include\":\"#jsx\"},{\"include\":\"#string\"},{\"include\":\"#regex\"},{\"include\":\"#comment\"},{\"include\":\"#function-expression\"},{\"include\":\"#class-expression\"},{\"include\":\"#arrow-function\"},{\"include\":\"#paren-expression-possibly-arrow\"},{\"include\":\"#cast\"},{\"include\":\"#ternary-expression\"},{\"include\":\"#new-expr\"},{\"include\":\"#instanceof-expr\"},{\"include\":\"#object-literal\"},{\"include\":\"#expression-operators\"},{\"include\":\"#function-call\"},{\"include\":\"#literal\"},{\"include\":\"#support-objects\"},{\"include\":\"#paren-expression\"}]},\"field-declaration\":{\"begin\":\"(?<!\\\\\\\\()(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(readonly)\\\\\\\\s+)?(?=\\\\\\\\s*(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|(#?[$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(?:(?:(\\\\\\\\?)|(!))\\\\\\\\s*)?([,:;=}]|$))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"end\":\"(?=[,;}]|$|^((?!\\\\\\\\s*(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|(#?[$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(?:(?:(\\\\\\\\?)|(!))\\\\\\\\s*)?([,:;=]|$))))|(?<=})\",\"name\":\"meta.field.declaration.js\",\"patterns\":[{\"include\":\"#variable-initializer\"},{\"include\":\"#type-annotation\"},{\"include\":\"#string\"},{\"include\":\"#array-literal\"},{\"include\":\"#numeric-literal\"},{\"include\":\"#comment\"},{\"captures\":{\"1\":{\"name\":\"meta.definition.property.js entity.name.function.js\"},\"2\":{\"name\":\"keyword.operator.optional.js\"},\"3\":{\"name\":\"keyword.operator.definiteassignment.js\"}},\"match\":\"(#?[$_[:alpha:]][$_[:alnum:]]*)(?:(\\\\\\\\?)|(!))?(?=\\\\\\\\s*\\\\\\\\s*(=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))|(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))))|(:\\\\\\\\s*(=>|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(<[^<>]*>)|[^(),<=>])+=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>))))))\"},{\"match\":\"#?[$_[:alpha:]][$_[:alnum:]]*\",\"name\":\"meta.definition.property.js variable.object.property.js\"},{\"match\":\"\\\\\\\\?\",\"name\":\"keyword.operator.optional.js\"},{\"match\":\"!\",\"name\":\"keyword.operator.definiteassignment.js\"}]},\"for-loop\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))for(?=((\\\\\\\\s+|(\\\\\\\\s*/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*))await)?\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)?(\\\\\\\\())\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.loop.js\"}},\"end\":\"(?<=\\\\\\\\))\",\"patterns\":[{\"include\":\"#comment\"},{\"match\":\"await\",\"name\":\"keyword.control.loop.js\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#var-expr\"},{\"include\":\"#expression\"},{\"include\":\"#punctuation-semicolon\"}]}]},\"function-body\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-parameters\"},{\"include\":\"#function-parameters\"},{\"include\":\"#return-type\"},{\"include\":\"#type-function-return-type\"},{\"include\":\"#decl-block\"},{\"match\":\"\\\\\\\\*\",\"name\":\"keyword.generator.asterisk.js\"}]},\"function-call\":{\"patterns\":[{\"begin\":\"(?=(((([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))|(?<=\\\\\\\\)))\\\\\\\\s*(?:(\\\\\\\\?\\\\\\\\.\\\\\\\\s*)|(!))?((<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)?\\\\\\\\())\",\"end\":\"(?<=\\\\\\\\))(?!(((([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))|(?<=\\\\\\\\)))\\\\\\\\s*(?:(\\\\\\\\?\\\\\\\\.\\\\\\\\s*)|(!))?((<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)?\\\\\\\\())\",\"patterns\":[{\"begin\":\"(?=(([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))\",\"end\":\"(?=\\\\\\\\s*(?:(\\\\\\\\?\\\\\\\\.\\\\\\\\s*)|(!))?((<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)?\\\\\\\\())\",\"name\":\"meta.function-call.js\",\"patterns\":[{\"include\":\"#function-call-target\"}]},{\"include\":\"#comment\"},{\"include\":\"#function-call-optionals\"},{\"include\":\"#type-arguments\"},{\"include\":\"#paren-expression\"}]},{\"begin\":\"(?=(((([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))|(?<=\\\\\\\\)))(<\\\\\\\\s*[(\\\\\\\\[{]\\\\\\\\s*)$)\",\"end\":\"(?<=>)(?!(((([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))|(?<=\\\\\\\\)))(<\\\\\\\\s*[(\\\\\\\\[{]\\\\\\\\s*)$)\",\"patterns\":[{\"begin\":\"(?=(([$_[:alpha:]][$_[:alnum:]]*)(\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*))*)|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*))\",\"end\":\"(?=(<\\\\\\\\s*[(\\\\\\\\[{]\\\\\\\\s*)$)\",\"name\":\"meta.function-call.js\",\"patterns\":[{\"include\":\"#function-call-target\"}]},{\"include\":\"#comment\"},{\"include\":\"#function-call-optionals\"},{\"include\":\"#type-arguments\"}]}]},\"function-call-optionals\":{\"patterns\":[{\"match\":\"\\\\\\\\?\\\\\\\\.\",\"name\":\"meta.function-call.js punctuation.accessor.optional.js\"},{\"match\":\"!\",\"name\":\"meta.function-call.js keyword.operator.definiteassignment.js\"}]},\"function-call-target\":{\"patterns\":[{\"include\":\"#support-function-call-identifiers\"},{\"match\":\"(#?[$_[:alpha:]][$_[:alnum:]]*)\",\"name\":\"entity.name.function.js\"}]},\"function-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?(?:(async)\\\\\\\\s+)?(function)\\\\\\\\b(?:\\\\\\\\s*(\\\\\\\\*))?(?:(?:\\\\\\\\s+|(?<=\\\\\\\\*))([$_[:alpha:]][$_[:alnum:]]*))?\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.async.js\"},\"4\":{\"name\":\"storage.type.function.js\"},\"5\":{\"name\":\"keyword.generator.asterisk.js\"},\"6\":{\"name\":\"meta.definition.function.js entity.name.function.js\"}},\"end\":\"(?=;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)|(?<=})\",\"name\":\"meta.function.js\",\"patterns\":[{\"include\":\"#function-name\"},{\"include\":\"#function-body\"}]},\"function-expression\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(async)\\\\\\\\s+)?(function)\\\\\\\\b(?:\\\\\\\\s*(\\\\\\\\*))?(?:(?:\\\\\\\\s+|(?<=\\\\\\\\*))([$_[:alpha:]][$_[:alnum:]]*))?\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"},\"2\":{\"name\":\"storage.type.function.js\"},\"3\":{\"name\":\"keyword.generator.asterisk.js\"},\"4\":{\"name\":\"meta.definition.function.js entity.name.function.js\"}},\"end\":\"(?=;)|(?<=})\",\"name\":\"meta.function.expression.js\",\"patterns\":[{\"include\":\"#function-name\"},{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#function-body\"}]},\"function-name\":{\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\",\"name\":\"meta.definition.function.js entity.name.function.js\"},\"function-parameters\":{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.begin.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.js\"}},\"name\":\"meta.parameters.js\",\"patterns\":[{\"include\":\"#function-parameters-body\"}]},\"function-parameters-body\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#decorator\"},{\"include\":\"#destructuring-parameter\"},{\"include\":\"#parameter-name\"},{\"include\":\"#parameter-type-annotation\"},{\"include\":\"#variable-initializer\"},{\"match\":\",\",\"name\":\"punctuation.separator.parameter.js\"}]},\"identifiers\":{\"patterns\":[{\"include\":\"#object-identifiers\"},{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"},\"3\":{\"name\":\"entity.name.function.js\"}},\"match\":\"(?:(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*)?([$_[:alpha:]][$_[:alnum:]]*)(?=\\\\\\\\s*=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))\"},{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"},\"3\":{\"name\":\"variable.other.constant.property.js\"}},\"match\":\"(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(#?\\\\\\\\p{upper}[$_\\\\\\\\d[:upper:]]*)(?![$_[:alnum:]])\"},{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"},\"3\":{\"name\":\"variable.other.property.js\"}},\"match\":\"(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(#?[$_[:alpha:]][$_[:alnum:]]*)\"},{\"match\":\"(\\\\\\\\p{upper}[$_\\\\\\\\d[:upper:]]*)(?![$_[:alnum:]])\",\"name\":\"variable.other.constant.js\"},{\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\",\"name\":\"variable.other.readwrite.js\"}]},\"if-statement\":{\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?=\\\\\\\\bif\\\\\\\\s*(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))\\\\\\\\s*(?!\\\\\\\\{))\",\"end\":\"(?=;|$|})\",\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(if)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.conditional.js\"},\"2\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression\"}]},{\"begin\":\"(?<=\\\\\\\\))\\\\\\\\s*/(?![*/])(?=(?:[^/\\\\\\\\[\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.|\\\\\\\\[([^]\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*])+/([dgimsuvy]+|(?![*/])|(?=/\\\\\\\\*))(?!\\\\\\\\s*[$0-9A-Z_a-z]))\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"(/)([dgimsuvy]*)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.end.js\"},\"2\":{\"name\":\"keyword.other.js\"}},\"name\":\"string.regexp.js\",\"patterns\":[{\"include\":\"#regexp\"}]},{\"include\":\"#statements\"}]}]},\"import-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(import)(?:\\\\\\\\s+(type)(?!\\\\\\\\s+from))?(?!\\\\\\\\s*[(:])(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"keyword.control.import.js\"},\"4\":{\"name\":\"keyword.control.type.js\"}},\"end\":\"(?<!(?:^|[^$._[:alnum:]])import)(?=;|$|^)\",\"name\":\"meta.import.js\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"begin\":\"(?<=(?:^|[^$._[:alnum:]])import)(?!\\\\\\\\s*[\\\\\"'])\",\"end\":\"\\\\\\\\bfrom\\\\\\\\b\",\"endCaptures\":{\"0\":{\"name\":\"keyword.control.from.js\"}},\"patterns\":[{\"include\":\"#import-export-declaration\"}]},{\"include\":\"#import-export-declaration\"}]},\"import-equals-declaration\":{\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(import)(?:\\\\\\\\s+(type))?\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(=)\\\\\\\\s*(require)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"keyword.control.import.js\"},\"4\":{\"name\":\"keyword.control.type.js\"},\"5\":{\"name\":\"variable.other.readwrite.alias.js\"},\"6\":{\"name\":\"keyword.operator.assignment.js\"},\"7\":{\"name\":\"keyword.control.require.js\"},\"8\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"name\":\"meta.import-equals.external.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"}]},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(import)(?:\\\\\\\\s+(type))?\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(=)\\\\\\\\s*(?!require\\\\\\\\b)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"keyword.control.import.js\"},\"4\":{\"name\":\"keyword.control.type.js\"},\"5\":{\"name\":\"variable.other.readwrite.alias.js\"},\"6\":{\"name\":\"keyword.operator.assignment.js\"}},\"end\":\"(?=;|$|^)\",\"name\":\"meta.import-equals.internal.js\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#comment\"},{\"captures\":{\"1\":{\"name\":\"entity.name.type.module.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\"},{\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"name\":\"variable.other.readwrite.js\"}]}]},\"import-export-assert-clause\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(with)|(assert))\\\\\\\\s*(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.with.js\"},\"2\":{\"name\":\"keyword.control.assert.js\"},\"3\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*(?=(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*:)\",\"name\":\"meta.object-literal.key.js\"},{\"match\":\":\",\"name\":\"punctuation.separator.key-value.js\"}]},\"import-export-block\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"meta.block.js\",\"patterns\":[{\"include\":\"#import-export-clause\"}]},\"import-export-clause\":{\"patterns\":[{\"include\":\"#comment\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.type.js\"},\"2\":{\"name\":\"keyword.control.default.js\"},\"3\":{\"name\":\"constant.language.import-export-all.js\"},\"4\":{\"name\":\"variable.other.readwrite.js\"},\"5\":{\"name\":\"string.quoted.alias.js\"},\"12\":{\"name\":\"keyword.control.as.js\"},\"13\":{\"name\":\"keyword.control.default.js\"},\"14\":{\"name\":\"variable.other.readwrite.alias.js\"},\"15\":{\"name\":\"string.quoted.alias.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(type)\\\\\\\\s+)?(?:\\\\\\\\b(default)|(\\\\\\\\*)|\\\\\\\\b([$_[:alpha:]][$_[:alnum:]]*)|(('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)))\\\\\\\\s+(as)\\\\\\\\s+(?:(default(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|([$_[:alpha:]][$_[:alnum:]]*)|(('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)))\"},{\"include\":\"#punctuation-comma\"},{\"match\":\"\\\\\\\\*\",\"name\":\"constant.language.import-export-all.js\"},{\"match\":\"\\\\\\\\b(default)\\\\\\\\b\",\"name\":\"keyword.control.default.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.type.js\"},\"2\":{\"name\":\"variable.other.readwrite.alias.js\"},\"3\":{\"name\":\"string.quoted.alias.js\"}},\"match\":\"(?:\\\\\\\\b(type)\\\\\\\\s+)?(?:([$_[:alpha:]][$_[:alnum:]]*)|(('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)))\"}]},\"import-export-declaration\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#import-export-block\"},{\"match\":\"\\\\\\\\bfrom\\\\\\\\b\",\"name\":\"keyword.control.from.js\"},{\"include\":\"#import-export-assert-clause\"},{\"include\":\"#import-export-clause\"}]},\"indexer-declaration\":{\"begin\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(readonly)\\\\\\\\s*)?\\\\\\\\s*(\\\\\\\\[)\\\\\\\\s*([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?=:)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"meta.brace.square.js\"},\"3\":{\"name\":\"variable.parameter.js\"}},\"end\":\"(])\\\\\\\\s*(\\\\\\\\?\\\\\\\\s*)?|$\",\"endCaptures\":{\"1\":{\"name\":\"meta.brace.square.js\"},\"2\":{\"name\":\"keyword.operator.optional.js\"}},\"name\":\"meta.indexer.declaration.js\",\"patterns\":[{\"include\":\"#type-annotation\"}]},\"indexer-mapped-type-declaration\":{\"begin\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))([-+])?(readonly)\\\\\\\\s*)?\\\\\\\\s*(\\\\\\\\[)\\\\\\\\s*([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s+(in)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.modifier.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"meta.brace.square.js\"},\"4\":{\"name\":\"entity.name.type.js\"},\"5\":{\"name\":\"keyword.operator.expression.in.js\"}},\"end\":\"(])([-+])?\\\\\\\\s*(\\\\\\\\?\\\\\\\\s*)?|$\",\"endCaptures\":{\"1\":{\"name\":\"meta.brace.square.js\"},\"2\":{\"name\":\"keyword.operator.type.modifier.js\"},\"3\":{\"name\":\"keyword.operator.optional.js\"}},\"name\":\"meta.indexer.mappedtype.declaration.js\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"keyword.control.as.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(as)\\\\\\\\s+\"},{\"include\":\"#type\"}]},\"inline-tags\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.bracket.square.begin.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.bracket.square.end.jsdoc\"}},\"match\":\"(\\\\\\\\[)[^]]+(])(?=\\\\\\\\{@(?:link|linkcode|linkplain|tutorial))\",\"name\":\"constant.other.description.jsdoc\"},{\"begin\":\"(\\\\\\\\{)((@)(?:link(?:code|plain)?|tutorial))\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.bracket.curly.begin.jsdoc\"},\"2\":{\"name\":\"storage.type.class.jsdoc\"},\"3\":{\"name\":\"punctuation.definition.inline.tag.jsdoc\"}},\"end\":\"}|(?=\\\\\\\\*/)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.bracket.curly.end.jsdoc\"}},\"name\":\"entity.name.type.instance.jsdoc\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"variable.other.link.underline.jsdoc\"},\"2\":{\"name\":\"punctuation.separator.pipe.jsdoc\"}},\"match\":\"\\\\\\\\G((?=https?://)(?:[^*|}\\\\\\\\s]|\\\\\\\\*/)+)(\\\\\\\\|)?\"},{\"captures\":{\"1\":{\"name\":\"variable.other.description.jsdoc\"},\"2\":{\"name\":\"punctuation.separator.pipe.jsdoc\"}},\"match\":\"\\\\\\\\G((?:[^*@{|}\\\\\\\\s]|\\\\\\\\*[^/])+)(\\\\\\\\|)?\"}]}]},\"instanceof-expr\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(instanceof)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.expression.instanceof.js\"}},\"end\":\"(?<=\\\\\\\\))|(?=[-\\\\\\\\])+,:;>?}]|\\\\\\\\|\\\\\\\\||&&|!==|$|([!=]==?)|(([\\\\\\\\&^|~]\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+instanceof(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))function((\\\\\\\\s+[$_[:alpha:]][$_[:alnum:]]*)|(\\\\\\\\s*\\\\\\\\())))\",\"patterns\":[{\"include\":\"#type\"}]},\"interface-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(?:(abstract)\\\\\\\\s+)?\\\\\\\\b(interface)\\\\\\\\b(?=\\\\\\\\s+|/[*/])\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.type.interface.js\"}},\"end\":\"(?<=})\",\"name\":\"meta.interface.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#class-or-interface-heritage\"},{\"captures\":{\"0\":{\"name\":\"entity.name.type.interface.js\"}},\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\"},{\"include\":\"#type-parameters\"},{\"include\":\"#class-or-interface-body\"}]},\"jsdoctype\":{\"patterns\":[{\"begin\":\"\\\\\\\\G(\\\\\\\\{)\",\"beginCaptures\":{\"0\":{\"name\":\"entity.name.type.instance.jsdoc\"},\"1\":{\"name\":\"punctuation.definition.bracket.curly.begin.jsdoc\"}},\"contentName\":\"entity.name.type.instance.jsdoc\",\"end\":\"((}))\\\\\\\\s*|(?=\\\\\\\\*/)\",\"endCaptures\":{\"1\":{\"name\":\"entity.name.type.instance.jsdoc\"},\"2\":{\"name\":\"punctuation.definition.bracket.curly.end.jsdoc\"}},\"patterns\":[{\"include\":\"#brackets\"}]}]},\"jsx\":{\"patterns\":[{\"include\":\"#jsx-tag-without-attributes-in-expression\"},{\"include\":\"#jsx-tag-in-expression\"}]},\"jsx-children\":{\"patterns\":[{\"include\":\"#jsx-tag-without-attributes\"},{\"include\":\"#jsx-tag\"},{\"include\":\"#jsx-evaluated-code\"},{\"include\":\"#jsx-entities\"}]},\"jsx-entities\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.js\"},\"3\":{\"name\":\"punctuation.definition.entity.js\"}},\"match\":\"(&)([0-9A-Za-z]+|#[0-9]+|#x\\\\\\\\h+)(;)\",\"name\":\"constant.character.entity.js\"}]},\"jsx-evaluated-code\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.js\"}},\"contentName\":\"meta.embedded.expression.js\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.js\"}},\"patterns\":[{\"include\":\"#expression\"}]},\"jsx-string-double-quoted\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.js\"}},\"name\":\"string.quoted.double.js\",\"patterns\":[{\"include\":\"#jsx-entities\"}]},\"jsx-string-single-quoted\":{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.js\"}},\"name\":\"string.quoted.single.js\",\"patterns\":[{\"include\":\"#jsx-entities\"}]},\"jsx-tag\":{\"begin\":\"(?=(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))(?=((<\\\\\\\\s*)|(\\\\\\\\s+))(?!\\\\\\\\?)|/?>))\",\"end\":\"(/>)|(</)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))?\\\\\\\\s*(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.js\"},\"2\":{\"name\":\"punctuation.definition.tag.begin.js\"},\"3\":{\"name\":\"entity.name.tag.namespace.js\"},\"4\":{\"name\":\"punctuation.separator.namespace.js\"},\"5\":{\"name\":\"entity.name.tag.js\"},\"6\":{\"name\":\"support.class.component.js\"},\"7\":{\"name\":\"punctuation.definition.tag.end.js\"}},\"name\":\"meta.tag.js\",\"patterns\":[{\"begin\":\"(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))(?=((<\\\\\\\\s*)|(\\\\\\\\s+))(?!\\\\\\\\?)|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.js\"},\"2\":{\"name\":\"entity.name.tag.namespace.js\"},\"3\":{\"name\":\"punctuation.separator.namespace.js\"},\"4\":{\"name\":\"entity.name.tag.js\"},\"5\":{\"name\":\"support.class.component.js\"}},\"end\":\"(?=/?>)\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-arguments\"},{\"include\":\"#jsx-tag-attributes\"}]},{\"begin\":\"(>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.js\"}},\"contentName\":\"meta.jsx.children.js\",\"end\":\"(?=</)\",\"patterns\":[{\"include\":\"#jsx-children\"}]}]},\"jsx-tag-attribute-assignment\":{\"match\":\"=(?=\\\\\\\\s*(?:[\\\\\"'{]|/\\\\\\\\*|//|\\\\\\\\n))\",\"name\":\"keyword.operator.assignment.js\"},\"jsx-tag-attribute-name\":{\"captures\":{\"1\":{\"name\":\"entity.other.attribute-name.namespace.js\"},\"2\":{\"name\":\"punctuation.separator.namespace.js\"},\"3\":{\"name\":\"entity.other.attribute-name.js\"}},\"match\":\"\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(:))?([$_[:alpha:]][-$_[:alnum:]]*)(?=[=\\\\\\\\s]|/?>|/\\\\\\\\*|//)\"},\"jsx-tag-attributes\":{\"begin\":\"\\\\\\\\s+\",\"end\":\"(?=/?>)\",\"name\":\"meta.tag.attributes.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#jsx-tag-attribute-name\"},{\"include\":\"#jsx-tag-attribute-assignment\"},{\"include\":\"#jsx-string-double-quoted\"},{\"include\":\"#jsx-string-single-quoted\"},{\"include\":\"#jsx-evaluated-code\"},{\"include\":\"#jsx-tag-attributes-illegal\"}]},\"jsx-tag-attributes-illegal\":{\"match\":\"\\\\\\\\S+\",\"name\":\"invalid.illegal.attribute.js\"},\"jsx-tag-in-expression\":{\"begin\":\"(?<!\\\\\\\\+\\\\\\\\+|--)(?<=[(*,:=>?\\\\\\\\[{]|&&|\\\\\\\\|\\\\\\\\||\\\\\\\\?|\\\\\\\\*/|^await|[^$._[:alnum:]]await|^return|[^$._[:alnum:]]return|^default|[^$._[:alnum:]]default|^yield|[^$._[:alnum:]]yield|^)\\\\\\\\s*(?!<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*((\\\\\\\\s+extends\\\\\\\\s+[^=>])|,))(?=(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))(?=((<\\\\\\\\s*)|(\\\\\\\\s+))(?!\\\\\\\\?)|/?>))\",\"end\":\"(?!(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))(?=((<\\\\\\\\s*)|(\\\\\\\\s+))(?!\\\\\\\\?)|/?>))\",\"patterns\":[{\"include\":\"#jsx-tag\"}]},\"jsx-tag-without-attributes\":{\"begin\":\"(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))?\\\\\\\\s*(>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.js\"},\"2\":{\"name\":\"entity.name.tag.namespace.js\"},\"3\":{\"name\":\"punctuation.separator.namespace.js\"},\"4\":{\"name\":\"entity.name.tag.js\"},\"5\":{\"name\":\"support.class.component.js\"},\"6\":{\"name\":\"punctuation.definition.tag.end.js\"}},\"contentName\":\"meta.jsx.children.js\",\"end\":\"(</)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))?\\\\\\\\s*(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.js\"},\"2\":{\"name\":\"entity.name.tag.namespace.js\"},\"3\":{\"name\":\"punctuation.separator.namespace.js\"},\"4\":{\"name\":\"entity.name.tag.js\"},\"5\":{\"name\":\"support.class.component.js\"},\"6\":{\"name\":\"punctuation.definition.tag.end.js\"}},\"name\":\"meta.tag.without-attributes.js\",\"patterns\":[{\"include\":\"#jsx-children\"}]},\"jsx-tag-without-attributes-in-expression\":{\"begin\":\"(?<!\\\\\\\\+\\\\\\\\+|--)(?<=[(*,:=>?\\\\\\\\[{]|&&|\\\\\\\\|\\\\\\\\||\\\\\\\\?|\\\\\\\\*/|^await|[^$._[:alnum:]]await|^return|[^$._[:alnum:]]return|^default|[^$._[:alnum:]]default|^yield|[^$._[:alnum:]]yield|^)\\\\\\\\s*(?=(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))?\\\\\\\\s*(>))\",\"end\":\"(?!(<)\\\\\\\\s*(?:([$_[:alpha:]][-$._[:alnum:]]*)(?<![-.])(:))?((?:[a-z][0-9a-z]*|([$_[:alpha:]][-$._[:alnum:]]*))(?<![-.]))?\\\\\\\\s*(>))\",\"patterns\":[{\"include\":\"#jsx-tag-without-attributes\"}]},\"label\":{\"patterns\":[{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(:)(?=\\\\\\\\s*\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.label.js\"},\"2\":{\"name\":\"punctuation.separator.label.js\"}},\"end\":\"(?<=})\",\"patterns\":[{\"include\":\"#decl-block\"}]},{\"captures\":{\"1\":{\"name\":\"entity.name.label.js\"},\"2\":{\"name\":\"punctuation.separator.label.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(:)\"}]},\"literal\":{\"patterns\":[{\"include\":\"#numeric-literal\"},{\"include\":\"#boolean-literal\"},{\"include\":\"#null-literal\"},{\"include\":\"#undefined-literal\"},{\"include\":\"#numericConstant-literal\"},{\"include\":\"#array-literal\"},{\"include\":\"#this-literal\"},{\"include\":\"#super-literal\"}]},\"method-declaration\":{\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(override)\\\\\\\\s+)?(?:\\\\\\\\b(p(?:ublic|rivate|rotected))\\\\\\\\s+)?(?:\\\\\\\\b(abstract)\\\\\\\\s+)?(?:\\\\\\\\b(async)\\\\\\\\s+)?\\\\\\\\s*\\\\\\\\b(constructor)\\\\\\\\b(?!:)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.modifier.async.js\"},\"5\":{\"name\":\"storage.type.js\"}},\"end\":\"(?=[,;}]|$)|(?<=})\",\"name\":\"meta.method.declaration.js\",\"patterns\":[{\"include\":\"#method-declaration-name\"},{\"include\":\"#function-body\"}]},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(override)\\\\\\\\s+)?(?:\\\\\\\\b(p(?:ublic|rivate|rotected))\\\\\\\\s+)?(?:\\\\\\\\b(abstract)\\\\\\\\s+)?(?:\\\\\\\\b(async)\\\\\\\\s+)?(?:\\\\\\\\s*\\\\\\\\b(new)\\\\\\\\b(?!:)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))|(?:(\\\\\\\\*)\\\\\\\\s*)?)(?=\\\\\\\\s*((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.modifier.async.js\"},\"5\":{\"name\":\"keyword.operator.new.js\"},\"6\":{\"name\":\"keyword.generator.asterisk.js\"}},\"end\":\"(?=[,;}]|$)|(?<=})\",\"name\":\"meta.method.declaration.js\",\"patterns\":[{\"include\":\"#method-declaration-name\"},{\"include\":\"#function-body\"}]},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(override)\\\\\\\\s+)?(?:\\\\\\\\b(p(?:ublic|rivate|rotected))\\\\\\\\s+)?(?:\\\\\\\\b(abstract)\\\\\\\\s+)?(?:\\\\\\\\b(async)\\\\\\\\s+)?(?:\\\\\\\\b([gs]et)\\\\\\\\s+)?(?:(\\\\\\\\*)\\\\\\\\s*)?(?=\\\\\\\\s*((\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(\\\\\\\\??))\\\\\\\\s*((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.modifier.js\"},\"4\":{\"name\":\"storage.modifier.async.js\"},\"5\":{\"name\":\"storage.type.property.js\"},\"6\":{\"name\":\"keyword.generator.asterisk.js\"}},\"end\":\"(?=[,;}]|$)|(?<=})\",\"name\":\"meta.method.declaration.js\",\"patterns\":[{\"include\":\"#method-declaration-name\"},{\"include\":\"#function-body\"}]}]},\"method-declaration-name\":{\"begin\":\"(?=(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(\\\\\\\\??)\\\\\\\\s*[(<])\",\"end\":\"(?=[(<])\",\"patterns\":[{\"include\":\"#string\"},{\"include\":\"#array-literal\"},{\"include\":\"#numeric-literal\"},{\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\",\"name\":\"meta.definition.method.js entity.name.function.js\"},{\"match\":\"\\\\\\\\?\",\"name\":\"keyword.operator.optional.js\"}]},\"namespace-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(namespace|module)\\\\\\\\s+(?=[\\\\\"$'_\\`[:alpha:]])\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.namespace.js\"}},\"end\":\"(?<=})|(?=;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"name\":\"meta.namespace.declaration.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"name\":\"entity.name.type.module.js\"},{\"include\":\"#punctuation-accessor\"},{\"include\":\"#decl-block\"}]},\"new-expr\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(new)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.new.js\"}},\"end\":\"(?<=\\\\\\\\))|(?=[-\\\\\\\\])+,:;>?}]|\\\\\\\\|\\\\\\\\||&&|!==|$|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))new(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))function((\\\\\\\\s+[$_[:alpha:]][$_[:alnum:]]*)|(\\\\\\\\s*\\\\\\\\())))\",\"name\":\"new.expr.js\",\"patterns\":[{\"include\":\"#expression\"}]},\"null-literal\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))null(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.null.js\"},\"numeric-literal\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.type.numeric.bigint.js\"}},\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.hex.js\"},{\"captures\":{\"1\":{\"name\":\"storage.type.numeric.bigint.js\"}},\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.binary.js\"},{\"captures\":{\"1\":{\"name\":\"storage.type.numeric.bigint.js\"}},\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.octal.js\"},{\"captures\":{\"0\":{\"name\":\"constant.numeric.decimal.js\"},\"1\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"2\":{\"name\":\"storage.type.numeric.bigint.js\"},\"3\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"4\":{\"name\":\"storage.type.numeric.bigint.js\"},\"5\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"6\":{\"name\":\"storage.type.numeric.bigint.js\"},\"7\":{\"name\":\"storage.type.numeric.bigint.js\"},\"8\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"9\":{\"name\":\"storage.type.numeric.bigint.js\"},\"10\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"11\":{\"name\":\"storage.type.numeric.bigint.js\"},\"12\":{\"name\":\"meta.delimiter.decimal.period.js\"},\"13\":{\"name\":\"storage.type.numeric.bigint.js\"},\"14\":{\"name\":\"storage.type.numeric.bigint.js\"}},\"match\":\"(?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$)\"}]},\"numericConstant-literal\":{\"patterns\":[{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))NaN(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.nan.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Infinity(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.infinity.js\"}]},\"object-binding-element\":{\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?=(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(:))\",\"end\":\"(?=[,}])\",\"patterns\":[{\"include\":\"#object-binding-element-propertyName\"},{\"include\":\"#binding-element\"}]},{\"include\":\"#object-binding-pattern\"},{\"include\":\"#destructuring-variable-rest\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#punctuation-comma\"}]},\"object-binding-element-const\":{\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?=(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(:))\",\"end\":\"(?=[,}])\",\"patterns\":[{\"include\":\"#object-binding-element-propertyName\"},{\"include\":\"#binding-element-const\"}]},{\"include\":\"#object-binding-pattern-const\"},{\"include\":\"#destructuring-variable-rest-const\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#punctuation-comma\"}]},\"object-binding-element-propertyName\":{\"begin\":\"(?=(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(:))\",\"end\":\"(:)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.destructuring.js\"}},\"patterns\":[{\"include\":\"#string\"},{\"include\":\"#array-literal\"},{\"include\":\"#numeric-literal\"},{\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"name\":\"variable.object.property.js\"}]},\"object-binding-pattern\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"patterns\":[{\"include\":\"#object-binding-element\"}]},\"object-binding-pattern-const\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"patterns\":[{\"include\":\"#object-binding-element-const\"}]},\"object-identifiers\":{\"patterns\":[{\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)(?=\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*prototype\\\\\\\\b(?!\\\\\\\\$))\",\"name\":\"support.class.js\"},{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"},\"3\":{\"name\":\"variable.other.constant.object.property.js\"},\"4\":{\"name\":\"variable.other.object.property.js\"}},\"match\":\"(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(?:(#?\\\\\\\\p{upper}[$_\\\\\\\\d[:upper:]]*)|(#?[$_[:alpha:]][$_[:alnum:]]*))(?=\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*)\"},{\"captures\":{\"1\":{\"name\":\"variable.other.constant.object.js\"},\"2\":{\"name\":\"variable.other.object.js\"}},\"match\":\"(?:(\\\\\\\\p{upper}[$_\\\\\\\\d[:upper:]]*)|([$_[:alpha:]][$_[:alnum:]]*))(?=\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*#?[$_[:alpha:]][$_[:alnum:]]*)\"}]},\"object-literal\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"meta.objectliteral.js\",\"patterns\":[{\"include\":\"#object-member\"}]},\"object-literal-method-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(async)\\\\\\\\s+)?(?:\\\\\\\\b([gs]et)\\\\\\\\s+)?(?:(\\\\\\\\*)\\\\\\\\s*)?(?=\\\\\\\\s*((\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(\\\\\\\\??))\\\\\\\\s*((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"},\"2\":{\"name\":\"storage.type.property.js\"},\"3\":{\"name\":\"keyword.generator.asterisk.js\"}},\"end\":\"(?=[,;}])|(?<=})\",\"name\":\"meta.method.declaration.js\",\"patterns\":[{\"include\":\"#method-declaration-name\"},{\"include\":\"#function-body\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(async)\\\\\\\\s+)?(?:\\\\\\\\b([gs]et)\\\\\\\\s+)?(?:(\\\\\\\\*)\\\\\\\\s*)?(?=\\\\\\\\s*((\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(\\\\\\\\??))\\\\\\\\s*((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"},\"2\":{\"name\":\"storage.type.property.js\"},\"3\":{\"name\":\"keyword.generator.asterisk.js\"}},\"end\":\"(?=[(<])\",\"patterns\":[{\"include\":\"#method-declaration-name\"}]}]},\"object-member\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#object-literal-method-declaration\"},{\"begin\":\"(?=\\\\\\\\[)\",\"end\":\"(?=:)|((?<=])(?=\\\\\\\\s*[(<]))\",\"name\":\"meta.object.member.js meta.object-literal.key.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#array-literal\"}]},{\"begin\":\"(?=[\\\\\"'\\`])\",\"end\":\"(?=:)|((?<=[\\\\\"'\\`])(?=((\\\\\\\\s*[(,<}])|(\\\\\\\\s+(as|satisifies)\\\\\\\\s+))))\",\"name\":\"meta.object.member.js meta.object-literal.key.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"}]},{\"begin\":\"(?=\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$)))\",\"end\":\"(?=:)|(?=\\\\\\\\s*([(,<}])|(\\\\\\\\s+as|satisifies\\\\\\\\s+))\",\"name\":\"meta.object.member.js meta.object-literal.key.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#numeric-literal\"}]},{\"begin\":\"(?<=[]\\\\\"'\\`])(?=\\\\\\\\s*[(<])\",\"end\":\"(?=[,;}])|(?<=})\",\"name\":\"meta.method.declaration.js\",\"patterns\":[{\"include\":\"#function-body\"}]},{\"captures\":{\"0\":{\"name\":\"meta.object-literal.key.js\"},\"1\":{\"name\":\"constant.numeric.decimal.js\"}},\"match\":\"(?![$_[:alpha:]])(\\\\\\\\d+)\\\\\\\\s*(?=(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*:)\",\"name\":\"meta.object.member.js\"},{\"captures\":{\"0\":{\"name\":\"meta.object-literal.key.js\"},\"1\":{\"name\":\"entity.name.function.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?=(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*:(\\\\\\\\s*/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/)*\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))\",\"name\":\"meta.object.member.js\"},{\"captures\":{\"0\":{\"name\":\"meta.object-literal.key.js\"}},\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*(?=(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*:)\",\"name\":\"meta.object.member.js\"},{\"begin\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.spread.js\"}},\"end\":\"(?=[,}])\",\"name\":\"meta.object.member.js\",\"patterns\":[{\"include\":\"#expression\"}]},{\"captures\":{\"1\":{\"name\":\"variable.other.readwrite.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?=[,}]|$|//|/\\\\\\\\*)\",\"name\":\"meta.object.member.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.as.js\"},\"2\":{\"name\":\"storage.modifier.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(as)\\\\\\\\s+(const)(?=\\\\\\\\s*([,}]|$))\",\"name\":\"meta.object.member.js\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(as)|(satisfies))\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.as.js\"},\"2\":{\"name\":\"keyword.control.satisfies.js\"}},\"end\":\"(?=[-\\\\\\\\])+,:;>?}]|\\\\\\\\|\\\\\\\\||&&|!==|$|^|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(as|satisifies)\\\\\\\\s+))\",\"name\":\"meta.object.member.js\",\"patterns\":[{\"include\":\"#type\"}]},{\"begin\":\"(?=[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=)\",\"end\":\"(?=[,}]|$|//|/\\\\\\\\*)\",\"name\":\"meta.object.member.js\",\"patterns\":[{\"include\":\"#expression\"}]},{\"begin\":\":\",\"beginCaptures\":{\"0\":{\"name\":\"meta.object-literal.key.js punctuation.separator.key-value.js\"}},\"end\":\"(?=[,}])\",\"name\":\"meta.object.member.js\",\"patterns\":[{\"begin\":\"(?<=:)\\\\\\\\s*(async)?(?=\\\\\\\\s*(<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"}},\"end\":\"(?<=\\\\\\\\))\",\"patterns\":[{\"include\":\"#type-parameters\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression-inside-possibly-arrow-parens\"}]}]},{\"begin\":\"(?<=:)\\\\\\\\s*(async)?\\\\\\\\s*(\\\\\\\\()(?=\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"},\"2\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression-inside-possibly-arrow-parens\"}]},{\"begin\":\"(?<=:)\\\\\\\\s*(async)?\\\\\\\\s*(?=<\\\\\\\\s*$)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"}},\"end\":\"(?<=>)\",\"patterns\":[{\"include\":\"#type-parameters\"}]},{\"begin\":\"(?<=>)\\\\\\\\s*(\\\\\\\\()(?=\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))\",\"beginCaptures\":{\"1\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression-inside-possibly-arrow-parens\"}]},{\"include\":\"#possibly-arrow-return-type\"},{\"include\":\"#expression\"}]},{\"include\":\"#punctuation-comma\"},{\"include\":\"#decl-block\"}]},\"parameter-array-binding-pattern\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.array.js\"}},\"patterns\":[{\"include\":\"#parameter-binding-element\"},{\"include\":\"#punctuation-comma\"}]},\"parameter-binding-element\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#string\"},{\"include\":\"#numeric-literal\"},{\"include\":\"#regex\"},{\"include\":\"#parameter-object-binding-pattern\"},{\"include\":\"#parameter-array-binding-pattern\"},{\"include\":\"#destructuring-parameter-rest\"},{\"include\":\"#variable-initializer\"}]},\"parameter-name\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|protected|private|readonly)\\\\\\\\s+(?=(override|public|protected|private|readonly)\\\\\\\\s+)\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"entity.name.function.js variable.language.this.js\"},\"4\":{\"name\":\"entity.name.function.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*(\\\\\\\\??)(?=\\\\\\\\s*(=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))|(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))))|(:\\\\\\\\s*(=>|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(<[^<>]*>)|[^(),<=>])+=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>))))))\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"variable.parameter.js variable.language.this.js\"},\"4\":{\"name\":\"variable.parameter.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(override|public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*(\\\\\\\\??)\"}]},\"parameter-object-binding-element\":{\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?=(\\\\\\\\b((?<!\\\\\\\\$)0[Xx]\\\\\\\\h[_\\\\\\\\h]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Bb][01][01_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|\\\\\\\\b((?<!\\\\\\\\$)0[Oo]?[0-7][0-7_]*(n)?\\\\\\\\b(?!\\\\\\\\$))|((?<!\\\\\\\\$)(?:\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*[Ee][-+]?[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(\\\\\\\\.)(n)?\\\\\\\\B|\\\\\\\\B(\\\\\\\\.)[0-9][0-9_]*(n)?\\\\\\\\b|\\\\\\\\b[0-9][0-9_]*(n)?\\\\\\\\b(?!\\\\\\\\.))(?!\\\\\\\\$))|([$_[:alpha:]][$_[:alnum:]]*)|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`)|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])+]))\\\\\\\\s*(:))\",\"end\":\"(?=[,}])\",\"patterns\":[{\"include\":\"#object-binding-element-propertyName\"},{\"include\":\"#parameter-binding-element\"},{\"include\":\"#paren-expression\"}]},{\"include\":\"#parameter-object-binding-pattern\"},{\"include\":\"#destructuring-parameter-rest\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#punctuation-comma\"}]},\"parameter-object-binding-pattern\":{\"begin\":\"(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.rest.js\"},\"2\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.binding-pattern.object.js\"}},\"patterns\":[{\"include\":\"#parameter-object-binding-element\"}]},\"parameter-type-annotation\":{\"patterns\":[{\"begin\":\"(:)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?=[),])|(?==[^>])\",\"name\":\"meta.type.annotation.js\",\"patterns\":[{\"include\":\"#type\"}]}]},\"paren-expression\":{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression\"}]},\"paren-expression-possibly-arrow\":{\"patterns\":[{\"begin\":\"(?<=[(,=])\\\\\\\\s*(async)?(?=\\\\\\\\s*((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"}},\"end\":\"(?<=\\\\\\\\))\",\"patterns\":[{\"include\":\"#paren-expression-possibly-arrow-with-typeparameters\"}]},{\"begin\":\"(?<=[(,=]|=>|^return|[^$._[:alnum:]]return)\\\\\\\\s*(async)?(?=\\\\\\\\s*((((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*))?\\\\\\\\()|(<)|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)))\\\\\\\\s*$)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.async.js\"}},\"end\":\"(?<=\\\\\\\\))\",\"patterns\":[{\"include\":\"#paren-expression-possibly-arrow-with-typeparameters\"}]},{\"include\":\"#possibly-arrow-return-type\"}]},\"paren-expression-possibly-arrow-with-typeparameters\":{\"patterns\":[{\"include\":\"#type-parameters\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"patterns\":[{\"include\":\"#expression-inside-possibly-arrow-parens\"}]}]},\"possibly-arrow-return-type\":{\"begin\":\"(?<=\\\\\\\\)|^)\\\\\\\\s*(:)(?=\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*=>)\",\"beginCaptures\":{\"1\":{\"name\":\"meta.arrow.js meta.return.type.arrow.js keyword.operator.type.annotation.js\"}},\"contentName\":\"meta.arrow.js meta.return.type.arrow.js\",\"end\":\"(?==>|\\\\\\\\{|^(\\\\\\\\s*(export|function|class|interface|let|var|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|const|import|enum|namespace|module|type|abstract|declare)\\\\\\\\s+))\",\"patterns\":[{\"include\":\"#arrow-return-type-body\"}]},\"property-accessor\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(accessor|get|set)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"storage.type.property.js\"},\"punctuation-accessor\":{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"}},\"match\":\"(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d))\"},\"punctuation-comma\":{\"match\":\",\",\"name\":\"punctuation.separator.comma.js\"},\"punctuation-semicolon\":{\"match\":\";\",\"name\":\"punctuation.terminator.statement.js\"},\"qstring-double\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"(\\\\\")|([^\\\\\\\\n\\\\\\\\\\\\\\\\])$\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.end.js\"},\"2\":{\"name\":\"invalid.illegal.newline.js\"}},\"name\":\"string.quoted.double.js\",\"patterns\":[{\"include\":\"#string-character-escape\"}]},\"qstring-single\":{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"(')|([^\\\\\\\\n\\\\\\\\\\\\\\\\])$\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.end.js\"},\"2\":{\"name\":\"invalid.illegal.newline.js\"}},\"name\":\"string.quoted.single.js\",\"patterns\":[{\"include\":\"#string-character-escape\"}]},\"regex\":{\"patterns\":[{\"begin\":\"(?<!\\\\\\\\+\\\\\\\\+|--|})(?<=[!(+,:=?\\\\\\\\[]|^return|[^$._[:alnum:]]return|^case|[^$._[:alnum:]]case|=>|&&|\\\\\\\\|\\\\\\\\||\\\\\\\\*/)\\\\\\\\s*(/)(?![*/])(?=(?:[^()/\\\\\\\\[\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.|\\\\\\\\[([^]\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)+]|\\\\\\\\(([^)\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)+\\\\\\\\))+/([dgimsuvy]+|(?![*/])|(?=/\\\\\\\\*))(?!\\\\\\\\s*[$0-9A-Z_a-z]))\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"(/)([dgimsuvy]*)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.end.js\"},\"2\":{\"name\":\"keyword.other.js\"}},\"name\":\"string.regexp.js\",\"patterns\":[{\"include\":\"#regexp\"}]},{\"begin\":\"((?<![]$)_[:alnum:]]|\\\\\\\\+\\\\\\\\+|--|}|\\\\\\\\*/)|((?<=^return|[^$._[:alnum:]]return|^case|[^$._[:alnum:]]case))\\\\\\\\s*)/(?![*/])(?=(?:[^/\\\\\\\\[\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.|\\\\\\\\[([^]\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*])+/([dgimsuvy]+|(?![*/])|(?=/\\\\\\\\*))(?!\\\\\\\\s*[$0-9A-Z_a-z]))\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.js\"}},\"end\":\"(/)([dgimsuvy]*)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.end.js\"},\"2\":{\"name\":\"keyword.other.js\"}},\"name\":\"string.regexp.js\",\"patterns\":[{\"include\":\"#regexp\"}]}]},\"regex-character-class\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\[DSWdfnrstvw]|\\\\\\\\.\",\"name\":\"constant.other.character-class.regexp\"},{\"match\":\"\\\\\\\\\\\\\\\\([0-7]{3}|x\\\\\\\\h{2}|u\\\\\\\\h{4})\",\"name\":\"constant.character.numeric.regexp\"},{\"match\":\"\\\\\\\\\\\\\\\\c[A-Z]\",\"name\":\"constant.character.control.regexp\"},{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"constant.character.escape.backslash.regexp\"}]},\"regexp\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\[Bb]|[$^]\",\"name\":\"keyword.control.anchor.regexp\"},{\"captures\":{\"0\":{\"name\":\"keyword.other.back-reference.regexp\"},\"1\":{\"name\":\"variable.other.regexp\"}},\"match\":\"\\\\\\\\\\\\\\\\(?:[1-9]\\\\\\\\d*|k<([$A-Z_a-z][$\\\\\\\\w]*)>)\"},{\"match\":\"[*+?]|\\\\\\\\{(\\\\\\\\d+,\\\\\\\\d+|\\\\\\\\d+,|,\\\\\\\\d+|\\\\\\\\d+)}\\\\\\\\??\",\"name\":\"keyword.operator.quantifier.regexp\"},{\"match\":\"\\\\\\\\|\",\"name\":\"keyword.operator.or.regexp\"},{\"begin\":\"(\\\\\\\\()((\\\\\\\\?=)|(\\\\\\\\?!)|(\\\\\\\\?<=)|(\\\\\\\\?<!))\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.group.regexp\"},\"2\":{\"name\":\"punctuation.definition.group.assertion.regexp\"},\"3\":{\"name\":\"meta.assertion.look-ahead.regexp\"},\"4\":{\"name\":\"meta.assertion.negative-look-ahead.regexp\"},\"5\":{\"name\":\"meta.assertion.look-behind.regexp\"},\"6\":{\"name\":\"meta.assertion.negative-look-behind.regexp\"}},\"end\":\"(\\\\\\\\))\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.group.regexp\"}},\"name\":\"meta.group.assertion.regexp\",\"patterns\":[{\"include\":\"#regexp\"}]},{\"begin\":\"\\\\\\\\((?:(\\\\\\\\?:)|\\\\\\\\?<([$A-Z_a-z][$\\\\\\\\w]*)>)?\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.group.regexp\"},\"1\":{\"name\":\"punctuation.definition.group.no-capture.regexp\"},\"2\":{\"name\":\"variable.other.regexp\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.group.regexp\"}},\"name\":\"meta.group.regexp\",\"patterns\":[{\"include\":\"#regexp\"}]},{\"begin\":\"(\\\\\\\\[)(\\\\\\\\^)?\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.character-class.regexp\"},\"2\":{\"name\":\"keyword.operator.negation.regexp\"}},\"end\":\"(])\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.character-class.regexp\"}},\"name\":\"constant.other.character-class.set.regexp\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"constant.character.numeric.regexp\"},\"2\":{\"name\":\"constant.character.control.regexp\"},\"3\":{\"name\":\"constant.character.escape.backslash.regexp\"},\"4\":{\"name\":\"constant.character.numeric.regexp\"},\"5\":{\"name\":\"constant.character.control.regexp\"},\"6\":{\"name\":\"constant.character.escape.backslash.regexp\"}},\"match\":\"(?:.|(\\\\\\\\\\\\\\\\(?:[0-7]{3}|x\\\\\\\\h{2}|u\\\\\\\\h{4}))|(\\\\\\\\\\\\\\\\c[A-Z])|(\\\\\\\\\\\\\\\\.))-(?:[^]\\\\\\\\\\\\\\\\]|(\\\\\\\\\\\\\\\\(?:[0-7]{3}|x\\\\\\\\h{2}|u\\\\\\\\h{4}))|(\\\\\\\\\\\\\\\\c[A-Z])|(\\\\\\\\\\\\\\\\.))\",\"name\":\"constant.other.character-class.range.regexp\"},{\"include\":\"#regex-character-class\"}]},{\"include\":\"#regex-character-class\"}]},\"return-type\":{\"patterns\":[{\"begin\":\"(?<=\\\\\\\\))\\\\\\\\s*(:)(?=\\\\\\\\s*\\\\\\\\S)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?<![\\\\\\\\&:|])(?=$|^|[,;{}]|//)\",\"name\":\"meta.return.type.js\",\"patterns\":[{\"include\":\"#return-type-core\"}]},{\"begin\":\"(?<=\\\\\\\\))\\\\\\\\s*(:)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?<![\\\\\\\\&:|])((?=[,;{}]|//|^\\\\\\\\s*$)|((?<=\\\\\\\\S)(?=\\\\\\\\s*$)))\",\"name\":\"meta.return.type.js\",\"patterns\":[{\"include\":\"#return-type-core\"}]}]},\"return-type-core\":{\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?<=[\\\\\\\\&:|])(?=\\\\\\\\s*\\\\\\\\{)\",\"end\":\"(?<=})\",\"patterns\":[{\"include\":\"#type-object\"}]},{\"include\":\"#type-predicate-operator\"},{\"include\":\"#type\"}]},\"shebang\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.js\"}},\"match\":\"\\\\\\\\A(#!).*(?=$)\",\"name\":\"comment.line.shebang.js\"},\"single-line-comment-consuming-line-ending\":{\"begin\":\"(^[\\\\\\\\t ]+)?((//)(?:\\\\\\\\s*((@)internal)(?=\\\\\\\\s|$))?)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.js\"},\"2\":{\"name\":\"comment.line.double-slash.js\"},\"3\":{\"name\":\"punctuation.definition.comment.js\"},\"4\":{\"name\":\"storage.type.internaldeclaration.js\"},\"5\":{\"name\":\"punctuation.decorator.internaldeclaration.js\"}},\"contentName\":\"comment.line.double-slash.js\",\"end\":\"(?=^)\"},\"statements\":{\"patterns\":[{\"include\":\"#declaration\"},{\"include\":\"#control-statement\"},{\"include\":\"#after-operator-block-as-object-literal\"},{\"include\":\"#decl-block\"},{\"include\":\"#label\"},{\"include\":\"#expression\"},{\"include\":\"#punctuation-semicolon\"},{\"include\":\"#string\"},{\"include\":\"#comment\"}]},\"string\":{\"patterns\":[{\"include\":\"#qstring-single\"},{\"include\":\"#qstring-double\"},{\"include\":\"#template\"}]},\"string-character-escape\":{\"match\":\"\\\\\\\\\\\\\\\\(x\\\\\\\\h{2}|u\\\\\\\\h{4}|u\\\\\\\\{\\\\\\\\h+}|[012][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)\",\"name\":\"constant.character.escape.js\"},\"super-literal\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))super\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"variable.language.super.js\"},\"support-function-call-identifiers\":{\"patterns\":[{\"include\":\"#literal\"},{\"include\":\"#support-objects\"},{\"include\":\"#object-identifiers\"},{\"include\":\"#punctuation-accessor\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))import(?=\\\\\\\\s*\\\\\\\\(\\\\\\\\s*[\\\\\"'\\`])\",\"name\":\"keyword.operator.expression.import.js\"}]},\"support-objects\":{\"patterns\":[{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(arguments)\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"variable.language.arguments.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(Promise)\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"support.class.promise.js\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.import.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"},\"4\":{\"name\":\"support.variable.property.importmeta.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(import)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(meta)\\\\\\\\b(?!\\\\\\\\$)\"},{\"captures\":{\"1\":{\"name\":\"keyword.operator.new.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"},\"4\":{\"name\":\"support.variable.property.target.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(new)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(target)\\\\\\\\b(?!\\\\\\\\$)\"},{\"captures\":{\"1\":{\"name\":\"punctuation.accessor.js\"},\"2\":{\"name\":\"punctuation.accessor.optional.js\"},\"3\":{\"name\":\"support.variable.property.js\"},\"4\":{\"name\":\"support.constant.js\"}},\"match\":\"(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(?:(constructor|length|prototype|__proto__)\\\\\\\\b(?!\\\\\\\\$|\\\\\\\\s*(<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\()|(EPSILON|MAX_SAFE_INTEGER|MAX_VALUE|MIN_SAFE_INTEGER|MIN_VALUE|NEGATIVE_INFINITY|POSITIVE_INFINITY)\\\\\\\\b(?!\\\\\\\\$))\"},{\"captures\":{\"1\":{\"name\":\"support.type.object.module.js\"},\"2\":{\"name\":\"support.type.object.module.js\"},\"3\":{\"name\":\"punctuation.accessor.js\"},\"4\":{\"name\":\"punctuation.accessor.optional.js\"},\"5\":{\"name\":\"support.type.object.module.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(exports)|(module)(?:(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))(exports|id|filename|loaded|parent|children))?)\\\\\\\\b(?!\\\\\\\\$)\"}]},\"switch-statement\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?=\\\\\\\\bswitch\\\\\\\\s*\\\\\\\\()\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"switch-statement.expr.js\",\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(switch)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.switch.js\"},\"2\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"name\":\"switch-expression.expr.js\",\"patterns\":[{\"include\":\"#expression\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"(?=})\",\"name\":\"switch-block.expr.js\",\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(case|default(?=:))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.switch.js\"}},\"end\":\"(?=:)\",\"name\":\"case-clause.expr.js\",\"patterns\":[{\"include\":\"#expression\"}]},{\"begin\":\"(:)\\\\\\\\s*(\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"case-clause.expr.js punctuation.definition.section.case-statement.js\"},\"2\":{\"name\":\"meta.block.js punctuation.definition.block.js\"}},\"contentName\":\"meta.block.js\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"meta.block.js punctuation.definition.block.js\"}},\"patterns\":[{\"include\":\"#statements\"}]},{\"captures\":{\"0\":{\"name\":\"case-clause.expr.js punctuation.definition.section.case-statement.js\"}},\"match\":\"(:)\"},{\"include\":\"#statements\"}]}]},\"template\":{\"patterns\":[{\"include\":\"#template-call\"},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)?(\\`)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.tagged-template.js\"},\"2\":{\"name\":\"string.template.js punctuation.definition.string.template.begin.js\"}},\"contentName\":\"string.template.js\",\"end\":\"\\`\",\"endCaptures\":{\"0\":{\"name\":\"string.template.js punctuation.definition.string.template.end.js\"}},\"patterns\":[{\"include\":\"#template-substitution-element\"},{\"include\":\"#string-character-escape\"}]}]},\"template-call\":{\"patterns\":[{\"begin\":\"(?=(([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*)*|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*)?)([$_[:alpha:]][$_[:alnum:]]*)(<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)?\\`)\",\"end\":\"(?=\\`)\",\"patterns\":[{\"begin\":\"(?=(([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*\\\\\\\\??\\\\\\\\.\\\\\\\\s*)*|(\\\\\\\\??\\\\\\\\.\\\\\\\\s*)?)([$_[:alpha:]][$_[:alnum:]]*))\",\"end\":\"(?=(<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)?\\`)\",\"patterns\":[{\"include\":\"#support-function-call-identifiers\"},{\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"name\":\"entity.name.function.tagged-template.js\"}]},{\"include\":\"#type-arguments\"}]},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)?\\\\\\\\s*(?=(<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))(([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>|<\\\\\\\\s*(((keyof|infer|typeof|readonly)\\\\\\\\s+)|(([$_[:alpha:]][$_[:alnum:]]*|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))(?=\\\\\\\\s*([,.<>\\\\\\\\[]|=>|&(?!&)|\\\\\\\\|(?!\\\\\\\\|)))))([^(<>]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(?<==)>)*(?<!=)>))*(?<!=)>)*(?<!=)>\\\\\\\\s*)\\`)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.tagged-template.js\"}},\"end\":\"(?=\\`)\",\"patterns\":[{\"include\":\"#type-arguments\"}]}]},\"template-substitution-element\":{\"begin\":\"\\\\\\\\$\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.template-expression.begin.js\"}},\"contentName\":\"meta.embedded.line.js\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.template-expression.end.js\"}},\"name\":\"meta.template.expression.js\",\"patterns\":[{\"include\":\"#expression\"}]},\"template-type\":{\"patterns\":[{\"include\":\"#template-call\"},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)?(\\`)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.tagged-template.js\"},\"2\":{\"name\":\"string.template.js punctuation.definition.string.template.begin.js\"}},\"contentName\":\"string.template.js\",\"end\":\"\\`\",\"endCaptures\":{\"0\":{\"name\":\"string.template.js punctuation.definition.string.template.end.js\"}},\"patterns\":[{\"include\":\"#template-type-substitution-element\"},{\"include\":\"#string-character-escape\"}]}]},\"template-type-substitution-element\":{\"begin\":\"\\\\\\\\$\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.template-expression.begin.js\"}},\"contentName\":\"meta.embedded.line.js\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.template-expression.end.js\"}},\"name\":\"meta.template.expression.js\",\"patterns\":[{\"include\":\"#type\"}]},\"ternary-expression\":{\"begin\":\"(?!\\\\\\\\?\\\\\\\\.\\\\\\\\s*\\\\\\\\D)(\\\\\\\\?)(?!\\\\\\\\?)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.ternary.js\"}},\"end\":\"\\\\\\\\s*(:)\",\"endCaptures\":{\"1\":{\"name\":\"keyword.operator.ternary.js\"}},\"patterns\":[{\"include\":\"#expression\"}]},\"this-literal\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))this\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"variable.language.this.js\"},\"type\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-string\"},{\"include\":\"#numeric-literal\"},{\"include\":\"#type-primitive\"},{\"include\":\"#type-builtin-literals\"},{\"include\":\"#type-parameters\"},{\"include\":\"#type-tuple\"},{\"include\":\"#type-object\"},{\"include\":\"#type-operators\"},{\"include\":\"#type-conditional\"},{\"include\":\"#type-fn-type-parameters\"},{\"include\":\"#type-paren-or-function-parameters\"},{\"include\":\"#type-function-return-type\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(readonly)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*\"},{\"include\":\"#type-name\"}]},\"type-alias-declaration\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(type)\\\\\\\\b\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.type.js\"},\"4\":{\"name\":\"entity.name.type.alias.js\"}},\"end\":\"(?=[;}]|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"name\":\"meta.type.declaration.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-parameters\"},{\"begin\":\"(=)\\\\\\\\s*(intrinsic)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.assignment.js\"},\"2\":{\"name\":\"keyword.control.intrinsic.js\"}},\"end\":\"(?=[;}]|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"patterns\":[{\"include\":\"#type\"}]},{\"begin\":\"(=)\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.assignment.js\"}},\"end\":\"(?=[;}]|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"patterns\":[{\"include\":\"#type\"}]}]},\"type-annotation\":{\"patterns\":[{\"begin\":\"(:)(?=\\\\\\\\s*\\\\\\\\S)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?<![\\\\\\\\&:|])(?!\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s+)((?=^|[]),;}]|//)|(?==[^>])|((?<=[]$)>_}[:alpha:]])\\\\\\\\s*(?=\\\\\\\\{)))\",\"name\":\"meta.type.annotation.js\",\"patterns\":[{\"include\":\"#type\"}]},{\"begin\":\"(:)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.annotation.js\"}},\"end\":\"(?<![\\\\\\\\&:|])((?=[]),;}]|//)|(?==[^>])|(?=^\\\\\\\\s*$)|((?<=[]$)>_}[:alpha:]])\\\\\\\\s*(?=\\\\\\\\{)))\",\"name\":\"meta.type.annotation.js\",\"patterns\":[{\"include\":\"#type\"}]}]},\"type-arguments\":{\"begin\":\"<\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.typeparameters.begin.js\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.typeparameters.end.js\"}},\"name\":\"meta.type.parameters.js\",\"patterns\":[{\"include\":\"#type-arguments-body\"}]},\"type-arguments-body\":{\"patterns\":[{\"captures\":{\"0\":{\"name\":\"keyword.operator.type.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(_)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\"},{\"include\":\"#type\"},{\"include\":\"#punctuation-comma\"}]},\"type-builtin-literals\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(this|true|false|undefined|null|object)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"support.type.builtin.js\"},\"type-conditional\":{\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(extends)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"}},\"end\":\"(?<=:)\",\"patterns\":[{\"begin\":\"\\\\\\\\?\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.ternary.js\"}},\"end\":\":\",\"endCaptures\":{\"0\":{\"name\":\"keyword.operator.ternary.js\"}},\"patterns\":[{\"include\":\"#type\"}]},{\"include\":\"#type\"}]}]},\"type-fn-type-parameters\":{\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(abstract)\\\\\\\\s+)?(new)\\\\\\\\b(?=\\\\\\\\s*<)\",\"beginCaptures\":{\"1\":{\"name\":\"meta.type.constructor.js storage.modifier.js\"},\"2\":{\"name\":\"meta.type.constructor.js keyword.control.new.js\"}},\"end\":\"(?<=>)\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#type-parameters\"}]},{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(abstract)\\\\\\\\s+)?(new)\\\\\\\\b\\\\\\\\s*(?=\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.control.new.js\"}},\"end\":\"(?<=\\\\\\\\))\",\"name\":\"meta.type.constructor.js\",\"patterns\":[{\"include\":\"#function-parameters\"}]},{\"begin\":\"((?=\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>))))))\",\"end\":\"(?<=\\\\\\\\))\",\"name\":\"meta.type.function.js\",\"patterns\":[{\"include\":\"#function-parameters\"}]}]},\"type-function-return-type\":{\"patterns\":[{\"begin\":\"(=>)(?=\\\\\\\\s*\\\\\\\\S)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.arrow.js\"}},\"end\":\"(?<!=>)(?<![\\\\\\\\&|])(?=[]),:;=>?{}]|//|$)\",\"name\":\"meta.type.function.return.js\",\"patterns\":[{\"include\":\"#type-function-return-type-core\"}]},{\"begin\":\"=>\",\"beginCaptures\":{\"0\":{\"name\":\"storage.type.function.arrow.js\"}},\"end\":\"(?<!=>)(?<![\\\\\\\\&|])((?=[]),:;=>?{}]|//|^\\\\\\\\s*$)|((?<=\\\\\\\\S)(?=\\\\\\\\s*$)))\",\"name\":\"meta.type.function.return.js\",\"patterns\":[{\"include\":\"#type-function-return-type-core\"}]}]},\"type-function-return-type-core\":{\"patterns\":[{\"include\":\"#comment\"},{\"begin\":\"(?<==>)(?=\\\\\\\\s*\\\\\\\\{)\",\"end\":\"(?<=})\",\"patterns\":[{\"include\":\"#type-object\"}]},{\"include\":\"#type-predicate-operator\"},{\"include\":\"#type\"}]},\"type-infer\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"keyword.operator.expression.infer.js\"},\"2\":{\"name\":\"entity.name.type.js\"},\"3\":{\"name\":\"keyword.operator.expression.extends.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(infer)\\\\\\\\s+([$_[:alpha:]][$_[:alnum:]]*)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))(?:\\\\\\\\s+(extends)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))?\",\"name\":\"meta.type.infer.js\"}]},\"type-name\":{\"patterns\":[{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\\\\\\\\s*(<)\",\"captures\":{\"1\":{\"name\":\"entity.name.type.module.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"},\"4\":{\"name\":\"meta.type.parameters.js punctuation.definition.typeparameters.begin.js\"}},\"contentName\":\"meta.type.parameters.js\",\"end\":\"(>)\",\"endCaptures\":{\"1\":{\"name\":\"meta.type.parameters.js punctuation.definition.typeparameters.end.js\"}},\"patterns\":[{\"include\":\"#type-arguments-body\"}]},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(<)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.type.js\"},\"2\":{\"name\":\"meta.type.parameters.js punctuation.definition.typeparameters.begin.js\"}},\"contentName\":\"meta.type.parameters.js\",\"end\":\"(>)\",\"endCaptures\":{\"1\":{\"name\":\"meta.type.parameters.js punctuation.definition.typeparameters.end.js\"}},\"patterns\":[{\"include\":\"#type-arguments-body\"}]},{\"captures\":{\"1\":{\"name\":\"entity.name.type.module.js\"},\"2\":{\"name\":\"punctuation.accessor.js\"},\"3\":{\"name\":\"punctuation.accessor.optional.js\"}},\"match\":\"([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(?:(\\\\\\\\.)|(\\\\\\\\?\\\\\\\\.(?!\\\\\\\\s*\\\\\\\\d)))\"},{\"match\":\"[$_[:alpha:]][$_[:alnum:]]*\",\"name\":\"entity.name.type.js\"}]},\"type-object\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.block.js\"}},\"name\":\"meta.object.type.js\",\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#method-declaration\"},{\"include\":\"#indexer-declaration\"},{\"include\":\"#indexer-mapped-type-declaration\"},{\"include\":\"#field-declaration\"},{\"include\":\"#type-annotation\"},{\"begin\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.spread.js\"}},\"end\":\"(?=[,;}]|$)|(?<=})\",\"patterns\":[{\"include\":\"#type\"}]},{\"include\":\"#punctuation-comma\"},{\"include\":\"#punctuation-semicolon\"},{\"include\":\"#type\"}]},\"type-operators\":{\"patterns\":[{\"include\":\"#typeof-operator\"},{\"include\":\"#type-infer\"},{\"begin\":\"([\\\\\\\\&|])(?=\\\\\\\\s*\\\\\\\\{)\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.type.js\"}},\"end\":\"(?<=})\",\"patterns\":[{\"include\":\"#type-object\"}]},{\"begin\":\"[\\\\\\\\&|]\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.type.js\"}},\"end\":\"(?=\\\\\\\\S)\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))keyof(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.expression.keyof.js\"},{\"match\":\"([:?])\",\"name\":\"keyword.operator.ternary.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))import(?=\\\\\\\\s*\\\\\\\\()\",\"name\":\"keyword.operator.expression.import.js\"}]},\"type-parameters\":{\"begin\":\"(<)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.typeparameters.begin.js\"}},\"end\":\"(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.typeparameters.end.js\"}},\"name\":\"meta.type.parameters.js\",\"patterns\":[{\"include\":\"#comment\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(extends|in|out|const)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"storage.modifier.js\"},{\"include\":\"#type\"},{\"include\":\"#punctuation-comma\"},{\"match\":\"(=)(?!>)\",\"name\":\"keyword.operator.assignment.js\"}]},\"type-paren-or-function-parameters\":{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.round.js\"}},\"name\":\"meta.type.paren.cover.js\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"entity.name.function.js variable.language.this.js\"},\"4\":{\"name\":\"entity.name.function.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))\\\\\\\\s*(\\\\\\\\??)(?=\\\\\\\\s*(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))))\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.js\"},\"2\":{\"name\":\"keyword.operator.rest.js\"},\"3\":{\"name\":\"variable.parameter.js variable.language.this.js\"},\"4\":{\"name\":\"variable.parameter.js\"},\"5\":{\"name\":\"keyword.operator.optional.js\"}},\"match\":\"(?:(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(public|private|protected|readonly)\\\\\\\\s+)?(?:(\\\\\\\\.\\\\\\\\.\\\\\\\\.)\\\\\\\\s*)?(?<![:=])(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))\\\\\\\\s*(\\\\\\\\??)(?=:)\"},{\"include\":\"#type-annotation\"},{\"match\":\",\",\"name\":\"punctuation.separator.parameter.js\"},{\"include\":\"#type\"}]},\"type-predicate-operator\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"keyword.operator.type.asserts.js\"},\"2\":{\"name\":\"variable.parameter.js variable.language.this.js\"},\"3\":{\"name\":\"variable.parameter.js\"},\"4\":{\"name\":\"keyword.operator.expression.is.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:(asserts)\\\\\\\\s+)?(?!asserts)(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))\\\\\\\\s(is)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\"},{\"captures\":{\"1\":{\"name\":\"keyword.operator.type.asserts.js\"},\"2\":{\"name\":\"variable.parameter.js variable.language.this.js\"},\"3\":{\"name\":\"variable.parameter.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(asserts)\\\\\\\\s+(?!is)(?:(this)|([$_[:alpha:]][$_[:alnum:]]*))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))asserts(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.type.asserts.js\"},{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))is(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"keyword.operator.expression.is.js\"}]},\"type-primitive\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(string|number|bigint|boolean|symbol|any|void|never|unknown)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"support.type.primitive.js\"},\"type-string\":{\"patterns\":[{\"include\":\"#qstring-single\"},{\"include\":\"#qstring-double\"},{\"include\":\"#template-type\"}]},\"type-tuple\":{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"meta.brace.square.js\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"meta.brace.square.js\"}},\"name\":\"meta.type.tuple.js\",\"patterns\":[{\"match\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"name\":\"keyword.operator.rest.js\"},{\"captures\":{\"1\":{\"name\":\"entity.name.label.js\"},\"2\":{\"name\":\"keyword.operator.optional.js\"},\"3\":{\"name\":\"punctuation.separator.label.js\"}},\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))([$_[:alpha:]][$_[:alnum:]]*)\\\\\\\\s*(\\\\\\\\?)?\\\\\\\\s*(:)\"},{\"include\":\"#type\"},{\"include\":\"#punctuation-comma\"}]},\"typeof-operator\":{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))typeof(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.expression.typeof.js\"}},\"end\":\"(?=[]\\\\\\\\&),:;=>?{|}]|(extends\\\\\\\\s+)|$|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)\",\"patterns\":[{\"include\":\"#type-arguments\"},{\"include\":\"#expression\"}]},\"undefined-literal\":{\"match\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))undefined(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\",\"name\":\"constant.language.undefined.js\"},\"var-expr\":{\"patterns\":[{\"begin\":\"(?=(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(var|let)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))\",\"end\":\"(?!(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(var|let)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))((?=^|[;}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)|((?<!^let|[^$._[:alnum:]]let|^var|[^$._[:alnum:]]var)(?=\\\\\\\\s*$)))\",\"name\":\"meta.var.expr.js\",\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(var|let)(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.js\"}},\"end\":\"(?=\\\\\\\\S)\"},{\"include\":\"#destructuring-variable\"},{\"include\":\"#var-single-variable\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#comment\"},{\"begin\":\"(,)\\\\\\\\s*(?=$|//)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.separator.comma.js\"}},\"end\":\"(?<!,)(((?=[;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|^\\\\\\\\s*$))|((?<=\\\\\\\\S)(?=\\\\\\\\s*$)))\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#comment\"},{\"include\":\"#destructuring-variable\"},{\"include\":\"#var-single-variable\"},{\"include\":\"#punctuation-comma\"}]},{\"include\":\"#punctuation-comma\"}]},{\"begin\":\"(?=(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(const(?!\\\\\\\\s+enum\\\\\\\\b))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.js\"}},\"end\":\"(?!(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(const(?!\\\\\\\\s+enum\\\\\\\\b))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))((?=^|[;}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)|((?<!(?:^|[^$._[:alnum:]])const)(?=\\\\\\\\s*$)))\",\"name\":\"meta.var.expr.js\",\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b(const(?!\\\\\\\\s+enum\\\\\\\\b))(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.js\"}},\"end\":\"(?=\\\\\\\\S)\"},{\"include\":\"#destructuring-const\"},{\"include\":\"#var-single-const\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#comment\"},{\"begin\":\"(,)\\\\\\\\s*(?=$|//)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.separator.comma.js\"}},\"end\":\"(?<!,)(((?=[;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|^\\\\\\\\s*$))|((?<=\\\\\\\\S)(?=\\\\\\\\s*$)))\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#comment\"},{\"include\":\"#destructuring-const\"},{\"include\":\"#var-single-const\"},{\"include\":\"#punctuation-comma\"}]},{\"include\":\"#punctuation-comma\"}]},{\"begin\":\"(?=(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b\\\\\\\\b(using(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])|await\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b)\\\\\\\\b(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.js\"}},\"end\":\"(?!(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b\\\\\\\\b(using(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])|await\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b)\\\\\\\\b(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))((?=[;}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b)|((?<!(?:^|[^$._[:alnum:]]|^await\\\\\\\\s+|[^$._[:alnum:]]await\\\\\\\\s+)using)(?=\\\\\\\\s*$)))\",\"name\":\"meta.var.expr.js\",\"patterns\":[{\"begin\":\"(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(?:\\\\\\\\b(export)\\\\\\\\s+)?(?:\\\\\\\\b(declare)\\\\\\\\s+)?\\\\\\\\b\\\\\\\\b(using(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])|await\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b)\\\\\\\\b(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.))\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.export.js\"},\"2\":{\"name\":\"storage.modifier.js\"},\"3\":{\"name\":\"storage.type.js\"}},\"end\":\"(?=\\\\\\\\S)\"},{\"include\":\"#var-single-const\"},{\"include\":\"#variable-initializer\"},{\"include\":\"#comment\"},{\"begin\":\"(,)\\\\\\\\s*((?!\\\\\\\\S)|(?=//))\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.separator.comma.js\"}},\"end\":\"(?<!,)(((?=[;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|^\\\\\\\\s*$))|((?<=\\\\\\\\S)(?=\\\\\\\\s*$)))\",\"patterns\":[{\"include\":\"#single-line-comment-consuming-line-ending\"},{\"include\":\"#comment\"},{\"include\":\"#var-single-const\"},{\"include\":\"#punctuation-comma\"}]},{\"include\":\"#punctuation-comma\"}]}]},\"var-single-const\":{\"patterns\":[{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)(?=\\\\\\\\s*(=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))|(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))))|(:\\\\\\\\s*(=>|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(<[^<>]*>)|[^(),<=>])+=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>))))))\",\"beginCaptures\":{\"1\":{\"name\":\"meta.definition.variable.js variable.other.constant.js entity.name.function.js\"}},\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|(;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b))\",\"name\":\"meta.var-single-variable.expr.js\",\"patterns\":[{\"include\":\"#var-single-variable-type-annotation\"}]},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)\",\"beginCaptures\":{\"1\":{\"name\":\"meta.definition.variable.js variable.other.constant.js\"}},\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|(;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b))\",\"name\":\"meta.var-single-variable.expr.js\",\"patterns\":[{\"include\":\"#var-single-variable-type-annotation\"}]}]},\"var-single-variable\":{\"patterns\":[{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)(!)?(?=\\\\\\\\s*(=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>)))))|(:\\\\\\\\s*((<)|(\\\\\\\\(\\\\\\\\s*((\\\\\\\\))|(\\\\\\\\.\\\\\\\\.\\\\\\\\.)|([$_[:alnum:]]+\\\\\\\\s*(([,:=?])|(\\\\\\\\)\\\\\\\\s*=>)))))))|(:\\\\\\\\s*(?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))Function(?![$_[:alnum:]])(?:(?=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?!\\\\\\\\.)))|(:\\\\\\\\s*((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))))))|(:\\\\\\\\s*(=>|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(<[^<>]*>)|[^(),<=>])+=\\\\\\\\s*(((async\\\\\\\\s+)?((function\\\\\\\\s*[(*<])|(function\\\\\\\\s+)|([$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*=>)))|((async\\\\\\\\s*)?(((<\\\\\\\\s*)$|(\\\\\\\\(\\\\\\\\s*((([\\\\\\\\[{]\\\\\\\\s*)?)$|((\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\{?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*)))|((\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])\\\\\\\\s*((:\\\\\\\\s*\\\\\\\\[?)$|((\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+\\\\\\\\s*)?=\\\\\\\\s*))))))|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*((\\\\\\\\)\\\\\\\\s*:)|((\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*)?[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s*:)))|(<\\\\\\\\s*[$_[:alpha:]][$_[:alnum:]]*\\\\\\\\s+extends\\\\\\\\s*[^=>])|((<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<]|<\\\\\\\\s*(((const\\\\\\\\s+)?[$_[:alpha:]])|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*]))([^<=>]|=[^<])*>)*>)*>\\\\\\\\s*)?\\\\\\\\(\\\\\\\\s*(/\\\\\\\\*([^*]|(\\\\\\\\*[^/]))*\\\\\\\\*/\\\\\\\\s*)*(([$_[:alpha:]]|(\\\\\\\\{([^{}]|(\\\\\\\\{([^{}]|\\\\\\\\{[^{}]*})*}))*})|(\\\\\\\\[([^]\\\\\\\\[]|(\\\\\\\\[([^]\\\\\\\\[]|\\\\\\\\[[^]\\\\\\\\[]*])*]))*])|(\\\\\\\\.\\\\\\\\.\\\\\\\\.\\\\\\\\s*[$_[:alpha:]]))([^\\\\\"'()\\`]|(\\\\\\\\(([^()]|(\\\\\\\\(([^()]|\\\\\\\\([^()]*\\\\\\\\))*\\\\\\\\)))*\\\\\\\\))|('([^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*')|(\\\\\"([^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)*\\\\\")|(\\`([^\\\\\\\\\\\\\\\\\\`]|\\\\\\\\\\\\\\\\.)*\\`))*)?\\\\\\\\)(\\\\\\\\s*:\\\\\\\\s*([^()<>{}]|<([^<>]|<([^<>]|<[^<>]+>)+>)+>|\\\\\\\\([^()]+\\\\\\\\)|\\\\\\\\{[^{}]+})+)?\\\\\\\\s*=>))))))\",\"beginCaptures\":{\"1\":{\"name\":\"meta.definition.variable.js entity.name.function.js\"},\"2\":{\"name\":\"keyword.operator.definiteassignment.js\"}},\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|(;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b))\",\"name\":\"meta.var-single-variable.expr.js\",\"patterns\":[{\"include\":\"#var-single-variable-type-annotation\"}]},{\"begin\":\"(\\\\\\\\p{upper}[$_\\\\\\\\d[:upper:]]*)(?![$_[:alnum:]])(!)?\",\"beginCaptures\":{\"1\":{\"name\":\"meta.definition.variable.js variable.other.constant.js\"},\"2\":{\"name\":\"keyword.operator.definiteassignment.js\"}},\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|(;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b))\",\"name\":\"meta.var-single-variable.expr.js\",\"patterns\":[{\"include\":\"#var-single-variable-type-annotation\"}]},{\"begin\":\"([$_[:alpha:]][$_[:alnum:]]*)(!)?\",\"beginCaptures\":{\"1\":{\"name\":\"meta.definition.variable.js variable.other.readwrite.js\"},\"2\":{\"name\":\"keyword.operator.definiteassignment.js\"}},\"end\":\"(?=$|^|[,;=}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+)|(;|^\\\\\\\\s*$|^\\\\\\\\s*(?:abstract|async|\\\\\\\\bawait\\\\\\\\s+\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b\\\\\\\\b|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|\\\\\\\\busing(?=\\\\\\\\s+(?!in\\\\\\\\b|of\\\\\\\\b(?!\\\\\\\\s*(?:of\\\\\\\\b|=)))[$_[:alpha:]])\\\\\\\\b|var|while)\\\\\\\\b))\",\"name\":\"meta.var-single-variable.expr.js\",\"patterns\":[{\"include\":\"#var-single-variable-type-annotation\"}]}]},\"var-single-variable-type-annotation\":{\"patterns\":[{\"include\":\"#type-annotation\"},{\"include\":\"#string\"},{\"include\":\"#comment\"}]},\"variable-initializer\":{\"patterns\":[{\"begin\":\"(?<![!=])(=)(?!=)(?=\\\\\\\\s*\\\\\\\\S)(?!\\\\\\\\s*.*=>\\\\\\\\s*$)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.assignment.js\"}},\"end\":\"(?=$|^|[]),;}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))\",\"patterns\":[{\"include\":\"#expression\"}]},{\"begin\":\"(?<![!=])(=)(?!=)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.assignment.js\"}},\"end\":\"(?=[]),;}]|((?<![$_[:alnum:]])(?:(?<=\\\\\\\\.\\\\\\\\.\\\\\\\\.)|(?<!\\\\\\\\.))(of|in)\\\\\\\\s+))|(?=^\\\\\\\\s*$)|(?<![-\\\\\\\\&*+/|])(?<=\\\\\\\\S)(?<!=)(?=\\\\\\\\s*$)\",\"patterns\":[{\"include\":\"#expression\"}]}]}},\"scopeName\":\"source.js\",\"aliases\":[\"js\",\"cjs\",\"mjs\"]}`)),Ul=[v_],w_=Object.freeze(JSON.parse(`{\"displayName\":\"CSS\",\"name\":\"css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#combinators\"},{\"include\":\"#selector\"},{\"include\":\"#at-rules\"},{\"include\":\"#rule-list\"}],\"repository\":{\"at-rules\":{\"patterns\":[{\"begin\":\"\\\\\\\\A\\\\\\\\uFEFF?(?i:(?=\\\\\\\\s*@charset\\\\\\\\b))\",\"end\":\";|(?=$)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.terminator.rule.css\"}},\"name\":\"meta.at-rule.charset.css\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"invalid.illegal.not-lowercase.charset.css\"},\"2\":{\"name\":\"invalid.illegal.leading-whitespace.charset.css\"},\"3\":{\"name\":\"invalid.illegal.no-whitespace.charset.css\"},\"4\":{\"name\":\"invalid.illegal.whitespace.charset.css\"},\"5\":{\"name\":\"invalid.illegal.not-double-quoted.charset.css\"},\"6\":{\"name\":\"invalid.illegal.unclosed-string.charset.css\"},\"7\":{\"name\":\"invalid.illegal.unexpected-characters.charset.css\"}},\"match\":\"\\\\\\\\G((?!@charset)@\\\\\\\\w+)|\\\\\\\\G(\\\\\\\\s+)|(@charset\\\\\\\\S[^;]*)|(?<=@charset)( {2,}|\\\\\\\\t+)|(?<=@charset )([^\\\\\";]+)|(\\\\\"[^\\\\\"]+)$|(?<=\\\\\")([^;]+)\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.at-rule.charset.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"match\":\"((@)charset)(?=\\\\\\\\s)\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.css\"}},\"end\":\"\\\\\"|$\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.css\"}},\"name\":\"string.quoted.double.css\",\"patterns\":[{\"begin\":\"(?:\\\\\\\\G|^)(?=[^\\\\\"]+$)\",\"end\":\"$\",\"name\":\"invalid.illegal.unclosed.string.css\"}]}]},{\"begin\":\"(?i)((@)import)(?:\\\\\\\\s+|$|(?=[\\\\\"']|/\\\\\\\\*))\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.import.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\";\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.terminator.rule.css\"}},\"name\":\"meta.at-rule.import.css\",\"patterns\":[{\"begin\":\"\\\\\\\\G\\\\\\\\s*(?=/\\\\\\\\*)\",\"end\":\"(?<=\\\\\\\\*/)\\\\\\\\s*\",\"patterns\":[{\"include\":\"#comment-block\"}]},{\"include\":\"#string\"},{\"include\":\"#url\"},{\"include\":\"#media-query-list\"}]},{\"begin\":\"(?i)((@)font-face)(?=\\\\\\\\s*|\\\\\\\\{|/\\\\\\\\*|$)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.font-face.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?!\\\\\\\\G)\",\"name\":\"meta.at-rule.font-face.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#rule-list\"}]},{\"begin\":\"(?i)(@)page(?=[:{\\\\\\\\s]|/\\\\\\\\*|$)\",\"captures\":{\"0\":{\"name\":\"keyword.control.at-rule.page.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*($|[:;{]))\",\"name\":\"meta.at-rule.page.css\",\"patterns\":[{\"include\":\"#rule-list\"}]},{\"begin\":\"(?i)(?=@media([(\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)media\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.media.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*[;{])\",\"name\":\"meta.at-rule.media.header.css\",\"patterns\":[{\"include\":\"#media-query-list\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.media.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.media.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.media.body.css\",\"patterns\":[{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)(?=@counter-style([\\\\\"';{\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)counter-style\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.counter-style.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*\\\\\\\\{)\",\"name\":\"meta.at-rule.counter-style.header.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"captures\":{\"0\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*\",\"name\":\"variable.parameter.style-name.css\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.counter-style.body.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#rule-list-innards\"}]}]},{\"begin\":\"(?i)(?=@document([\\\\\"';{\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)document\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.document.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*[;{])\",\"name\":\"meta.at-rule.document.header.css\",\"patterns\":[{\"begin\":\"(?i)(?<![-\\\\\\\\w])(url-prefix|domain|regexp)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.document-rule.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.document-rule.css\",\"patterns\":[{\"include\":\"#string\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"match\":\"[^\\\\\"')\\\\\\\\s]+\",\"name\":\"variable.parameter.document-rule.css\"}]},{\"include\":\"#url\"},{\"include\":\"#commas\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.document.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.document.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.document.body.css\",\"patterns\":[{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)(?=@(?:-(?:webkit|moz|o|ms)-)?keyframes([\\\\\"';{\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)(?:-(?:webkit|moz|o|ms)-)?keyframes\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.keyframes.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*\\\\\\\\{)\",\"name\":\"meta.at-rule.keyframes.header.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"captures\":{\"0\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*\",\"name\":\"variable.parameter.keyframe-list.css\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.keyframes.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.keyframes.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.keyframes.body.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"captures\":{\"1\":{\"name\":\"entity.other.keyframe-offset.css\"},\"2\":{\"name\":\"entity.other.keyframe-offset.percentage.css\"}},\"match\":\"(?i)(?<![-\\\\\\\\w])(from|to)(?![-\\\\\\\\w])|([-+]?(?:\\\\\\\\d+(?:\\\\\\\\.\\\\\\\\d+)?|\\\\\\\\.\\\\\\\\d+)%)\"},{\"include\":\"#rule-list\"}]}]},{\"begin\":\"(?i)(?=@supports([(\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)|(?=;)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)supports\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.supports.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*[;{])\",\"name\":\"meta.at-rule.supports.header.css\",\"patterns\":[{\"include\":\"#feature-query-operators\"},{\"include\":\"#feature-query\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.supports.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.supports.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.supports.body.css\",\"patterns\":[{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)((@)(-(ms|o)-)?viewport)(?=[\\\\\"';{\\\\\\\\s]|/\\\\\\\\*|$)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.viewport.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*[;@{])\",\"name\":\"meta.at-rule.viewport.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"}]},{\"begin\":\"(?i)((@)font-feature-values)(?=[\\\\\"';{\\\\\\\\s]|/\\\\\\\\*|$)\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.font-feature-values.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"contentName\":\"variable.parameter.font-name.css\",\"end\":\"(?=\\\\\\\\s*[;@{])\",\"name\":\"meta.at-rule.font-features.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"}]},{\"include\":\"#font-features\"},{\"begin\":\"(?i)((@)namespace)(?=[\\\\\"';\\\\\\\\s]|/\\\\\\\\*|$)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.namespace.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\";|(?=[@{])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.terminator.rule.css\"}},\"name\":\"meta.at-rule.namespace.css\",\"patterns\":[{\"include\":\"#url\"},{\"captures\":{\"1\":{\"patterns\":[{\"include\":\"#comment-block\"}]},\"2\":{\"name\":\"entity.name.function.namespace-prefix.css\",\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(?i)(?:\\\\\\\\G|^|(?<=\\\\\\\\s))(?=(?<=\\\\\\\\s|^)[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\s*/\\\\\\\\*(?:[^*]|\\\\\\\\*[^/])*\\\\\\\\*/)(.*?)([-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*)\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#string\"}]},{\"begin\":\"(?i)(?=@[-\\\\\\\\w]+[^;]+;s*$)\",\"end\":\"(?<=;)(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)[-\\\\\\\\w]+\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\";\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.terminator.rule.css\"}},\"name\":\"meta.at-rule.header.css\"}]},{\"begin\":\"(?i)(?=@[-\\\\\\\\w]+([({\\\\\\\\s]|/\\\\\\\\*|$))\",\"end\":\"(?<=})(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"(?i)\\\\\\\\G(@)[-\\\\\\\\w]+\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.at-rule.css\"},\"1\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?=\\\\\\\\s*[;{])\",\"name\":\"meta.at-rule.header.css\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.end.bracket.curly.css\"}},\"name\":\"meta.at-rule.body.css\",\"patterns\":[{\"include\":\"$self\"}]}]}]},\"color-keywords\":{\"patterns\":[{\"match\":\"(?i)(?<![-\\\\\\\\w])(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)(?![-\\\\\\\\w])\",\"name\":\"support.constant.color.w3c-standard-color-name.css\"},{\"match\":\"(?i)(?<![-\\\\\\\\w])(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rebeccapurple|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|transparent|turquoise|violet|wheat|whitesmoke|yellowgreen)(?![-\\\\\\\\w])\",\"name\":\"support.constant.color.w3c-extended-color-name.css\"},{\"match\":\"(?i)(?<![-\\\\\\\\w])currentColor(?![-\\\\\\\\w])\",\"name\":\"support.constant.color.current.css\"},{\"match\":\"(?i)(?<![-\\\\\\\\w])(ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)(?![-\\\\\\\\w])\",\"name\":\"invalid.deprecated.color.system.css\"}]},\"combinators\":{\"patterns\":[{\"match\":\"/deep/|>>>\",\"name\":\"invalid.deprecated.combinator.css\"},{\"match\":\">>|[+>~]\",\"name\":\"keyword.operator.combinator.css\"}]},\"commas\":{\"match\":\",\",\"name\":\"punctuation.separator.list.comma.css\"},\"comment-block\":{\"begin\":\"/\\\\\\\\*\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.begin.css\"}},\"end\":\"\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.end.css\"}},\"name\":\"comment.block.css\"},\"escapes\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\\\\\\\\h{1,6}\",\"name\":\"constant.character.escape.codepoint.css\"},{\"begin\":\"\\\\\\\\\\\\\\\\$\\\\\\\\s*\",\"end\":\"^(?<!\\\\\\\\G)\",\"name\":\"constant.character.escape.newline.css\"},{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"constant.character.escape.css\"}]},\"feature-query\":{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.condition.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.condition.end.bracket.round.css\"}},\"name\":\"meta.feature-query.css\",\"patterns\":[{\"include\":\"#feature-query-operators\"},{\"include\":\"#feature-query\"}]},\"feature-query-operators\":{\"patterns\":[{\"match\":\"(?i)(?<=[()\\\\\\\\s]|^|\\\\\\\\*/)(and|not|or)(?=[()\\\\\\\\s]|/\\\\\\\\*|$)\",\"name\":\"keyword.operator.logical.feature.$1.css\"},{\"include\":\"#rule-list-innards\"}]},\"font-features\":{\"begin\":\"(?i)((@)(annotation|character-variant|ornaments|styleset|stylistic|swash))(?=[\\\\\"';@{\\\\\\\\s]|/\\\\\\\\*|$)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.at-rule.\\${3:/downcase}.css\"},\"2\":{\"name\":\"punctuation.definition.keyword.css\"}},\"end\":\"(?<=})\",\"name\":\"meta.at-rule.\\${3:/downcase}.css\",\"patterns\":[{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.end.bracket.curly.css\"}},\"name\":\"meta.property-list.font-feature.css\",\"patterns\":[{\"captures\":{\"0\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*\",\"name\":\"variable.font-feature.css\"},{\"include\":\"#rule-list-innards\"}]}]},\"functional-pseudo-classes\":{\"patterns\":[{\"begin\":\"(?i)((:)dir)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.other.attribute-name.pseudo-class.css\"},\"2\":{\"name\":\"punctuation.definition.entity.css\"},\"3\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"match\":\"(?i)(?<![-\\\\\\\\w])(ltr|rtl)(?![-\\\\\\\\w])\",\"name\":\"support.constant.text-direction.css\"},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)((:)lang)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.other.attribute-name.pseudo-class.css\"},\"2\":{\"name\":\"punctuation.definition.entity.css\"},\"3\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"match\":\"(?<=[(,\\\\\\\\s])[A-Za-z]+(-[0-9A-Za-z]*|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*(?=[),\\\\\\\\s])\",\"name\":\"support.constant.language-range.css\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.css\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.css\"}},\"name\":\"string.quoted.double.css\",\"patterns\":[{\"include\":\"#escapes\"},{\"match\":\"(?<=[\\\\\"\\\\\\\\s])[*A-Za-z]+(-[*0-9A-Za-z]*)*(?=[\\\\\"\\\\\\\\s])\",\"name\":\"support.constant.language-range.css\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.css\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.css\"}},\"name\":\"string.quoted.single.css\",\"patterns\":[{\"include\":\"#escapes\"},{\"match\":\"(?<=['\\\\\\\\s])[*A-Za-z]+(-[*0-9A-Za-z]*)*(?=['\\\\\\\\s])\",\"name\":\"support.constant.language-range.css\"}]},{\"include\":\"#commas\"}]},{\"begin\":\"(?i)((:)(?:not|has|matches|where|is))(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.other.attribute-name.pseudo-class.css\"},\"2\":{\"name\":\"punctuation.definition.entity.css\"},\"3\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"include\":\"#selector-innards\"}]},{\"begin\":\"(?i)((:)nth-(?:last-)?(?:child|of-type))(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.other.attribute-name.pseudo-class.css\"},\"2\":{\"name\":\"punctuation.definition.entity.css\"},\"3\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"match\":\"(?i)[-+]?(\\\\\\\\d+n?|n)(\\\\\\\\s*[-+]\\\\\\\\s*\\\\\\\\d+)?\",\"name\":\"constant.numeric.css\"},{\"match\":\"(?i)even|odd\",\"name\":\"support.constant.parity.css\"}]}]},\"functions\":{\"patterns\":[{\"begin\":\"(?i)(?<![-\\\\\\\\w])(calc)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.calc.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.calc.css\",\"patterns\":[{\"match\":\"[*/]|(?<=\\\\\\\\s|^)[-+](?=\\\\\\\\s|$)\",\"name\":\"keyword.operator.arithmetic.css\"},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(rgba?|hsla?|hwb|lab|oklab|lch|oklch|color)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.misc.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.color.css\",\"patterns\":[{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])((?:-(?:webkit-|moz-|o-))?(?:repeating-)?(?:linear|radial|conic)-gradient)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.gradient.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.gradient.css\",\"patterns\":[{\"match\":\"(?i)(?<![-\\\\\\\\w])(from|to|at|in|hue)(?![-\\\\\\\\w])\",\"name\":\"keyword.operator.gradient.css\"},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(-webkit-gradient)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"invalid.deprecated.gradient.function.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.gradient.invalid.deprecated.gradient.css\",\"patterns\":[{\"begin\":\"(?i)(?<![-\\\\\\\\w])(from|to|color-stop)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"invalid.deprecated.function.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"include\":\"#property-values\"}]},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(annotation|attr|blur|brightness|character-variant|clamp|contrast|counters?|cross-fade|drop-shadow|element|fit-content|format|grayscale|hue-rotate|color-mix|image-set|invert|local|max|min|minmax|opacity|ornaments|repeat|saturate|sepia|styleset|stylistic|swash|symbols|cos|sin|tan|acos|asin|atan2??|hypot|sqrt|pow|log|exp|abs|sign)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.misc.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.misc.css\",\"patterns\":[{\"match\":\"(?i)(?<=[\\\\\",\\\\\\\\s]|\\\\\\\\*/|^)\\\\\\\\d+x(?=[\\\\\"'),\\\\\\\\s]|/\\\\\\\\*|$)\",\"name\":\"constant.numeric.other.density.css\"},{\"include\":\"#property-values\"},{\"match\":\"[^\\\\\"'),\\\\\\\\s]+\",\"name\":\"variable.parameter.misc.css\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(circle|ellipse|inset|polygon|rect)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.shape.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.shape.css\",\"patterns\":[{\"match\":\"(?i)(?<=\\\\\\\\s|^|\\\\\\\\*/)(at|round)(?=\\\\\\\\s|/\\\\\\\\*|$)\",\"name\":\"keyword.operator.shape.css\"},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(cubic-bezier|steps)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.timing-function.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.timing-function.css\",\"patterns\":[{\"match\":\"(?i)(?<![-\\\\\\\\w])(start|end)(?=\\\\\\\\s*\\\\\\\\)|$)\",\"name\":\"support.constant.step-direction.css\"},{\"include\":\"#property-values\"}]},{\"begin\":\"(?i)(?<![-\\\\\\\\w])((?:translate|scale|rotate)(?:[XYZ]|3D)?|matrix(?:3D)?|skew[XY]?|perspective)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.transform.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"patterns\":[{\"include\":\"#property-values\"}]},{\"include\":\"#url\"},{\"begin\":\"(?i)(?<![-\\\\\\\\w])(var)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.misc.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.variable.css\",\"patterns\":[{\"match\":\"--[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*\",\"name\":\"variable.argument.css\"},{\"include\":\"#property-values\"}]}]},\"media-feature-keywords\":{\"match\":\"(?i)(?<=^|[:\\\\\\\\s]|\\\\\\\\*/)(?:portrait|landscape|progressive|interlace|fullscreen|standalone|minimal-ui|browser|hover)(?=[)\\\\\\\\s]|$)\",\"name\":\"support.constant.property-value.css\"},\"media-features\":{\"captures\":{\"1\":{\"name\":\"support.type.property-name.media.css\"},\"2\":{\"name\":\"support.type.property-name.media.css\"},\"3\":{\"name\":\"support.type.vendored.property-name.media.css\"}},\"match\":\"(?i)(?<=^|[(\\\\\\\\s]|\\\\\\\\*/)(?:((?:m(?:in-|ax-))?(?:height|width|aspect-ratio|color|color-index|monochrome|resolution)|grid|scan|orientation|display-mode|hover)|((?:m(?:in-|ax-))?device-(?:height|width|aspect-ratio))|((?:[-_](?:webkit|apple|khtml|epub|moz|ms|o|xv|ah|rim|atsc|hp|tc|wap|ro)|(?:mso|prince))-[-\\\\\\\\w]+(?=\\\\\\\\s*(?:/\\\\\\\\*(?:[^*]|\\\\\\\\*[^/])*\\\\\\\\*/)?\\\\\\\\s*[):])))(?=\\\\\\\\s|$|[):<=>]|/\\\\\\\\*)\"},\"media-query\":{\"begin\":\"\\\\\\\\G\",\"end\":\"(?=\\\\\\\\s*[;{])\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#media-types\"},{\"match\":\"(?i)(?<=\\\\\\\\s|^|,|\\\\\\\\*/)(only|not)(?=[{\\\\\\\\s]|/\\\\\\\\*|$)\",\"name\":\"keyword.operator.logical.$1.media.css\"},{\"match\":\"(?i)(?<=\\\\\\\\s|^|\\\\\\\\*/|\\\\\\\\))and(?=\\\\\\\\s|/\\\\\\\\*|$)\",\"name\":\"keyword.operator.logical.and.media.css\"},{\"match\":\",(?:(?:\\\\\\\\s*,)+|(?=\\\\\\\\s*[);{]))\",\"name\":\"invalid.illegal.comma.css\"},{\"include\":\"#commas\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.css\"}},\"patterns\":[{\"include\":\"#media-features\"},{\"include\":\"#media-feature-keywords\"},{\"match\":\":\",\"name\":\"punctuation.separator.key-value.css\"},{\"match\":\">=|<=|[<=>]\",\"name\":\"keyword.operator.comparison.css\"},{\"captures\":{\"1\":{\"name\":\"constant.numeric.css\"},\"2\":{\"name\":\"keyword.operator.arithmetic.css\"},\"3\":{\"name\":\"constant.numeric.css\"}},\"match\":\"(\\\\\\\\d+)\\\\\\\\s*(/)\\\\\\\\s*(\\\\\\\\d+)\",\"name\":\"meta.ratio.css\"},{\"include\":\"#numeric-values\"},{\"include\":\"#comment-block\"}]}]},\"media-query-list\":{\"begin\":\"(?=\\\\\\\\s*[^;{])\",\"end\":\"(?=\\\\\\\\s*[;{])\",\"patterns\":[{\"include\":\"#media-query\"}]},\"media-types\":{\"captures\":{\"1\":{\"name\":\"support.constant.media.css\"},\"2\":{\"name\":\"invalid.deprecated.constant.media.css\"}},\"match\":\"(?i)(?<=^|[,\\\\\\\\s]|\\\\\\\\*/)(?:(all|print|screen|speech)|(aural|braille|embossed|handheld|projection|tty|tv))(?=$|[,;{\\\\\\\\s]|/\\\\\\\\*)\"},\"numeric-values\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.constant.css\"}},\"match\":\"(#)(?:\\\\\\\\h{3,4}|\\\\\\\\h{6}|\\\\\\\\h{8})\\\\\\\\b\",\"name\":\"constant.other.color.rgb-value.hex.css\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.unit.percentage.css\"},\"2\":{\"name\":\"keyword.other.unit.\\${2:/downcase}.css\"}},\"match\":\"(?i)(?<![-\\\\\\\\w])[-+]?(?:[0-9]+(?:\\\\\\\\.[0-9]+)?|\\\\\\\\.[0-9]+)(?:(?<=[0-9])E[-+]?[0-9]+)?(?:(%)|(deg|grad|rad|turn|Hz|kHz|ch|cm|em|ex|fr|in|mm|mozmm|pc|pt|px|q|rem|rch|rex|rlh|ic|ric|rcap|vh|vw|vb|vi|svh|svw|svb|svi|dvh|dvw|dvb|dvi|lvh|lvw|lvb|lvi|vmax|vmin|cqw|cqi|cqh|cqb|cqmin|cqmax|dpi|dpcm|dppx|s|ms)\\\\\\\\b)?\",\"name\":\"constant.numeric.css\"}]},\"property-keywords\":{\"patterns\":[{\"match\":\"(?i)(?<![-\\\\\\\\w])(above|absolute|active|add|additive|after-edge|alias|all|all-petite-caps|all-scroll|all-small-caps|alpha|alphabetic|alternate|alternate-reverse|always|antialiased|auto|auto-fill|auto-fit|auto-pos|available|avoid|avoid-column|avoid-page|avoid-region|backwards|balance|baseline|before-edge|below|bevel|bidi-override|blink|block|block-axis|block-start|block-end|bold|bolder|border|border-box|both|bottom|bottom-outside|break-all|break-word|bullets|butt|capitalize|caption|cell|center|central|char|circle|clip|clone|close-quote|closest-corner|closest-side|col-resize|collapse|color|color-burn|color-dodge|column|column-reverse|common-ligatures|compact|condensed|contain|content|content-box|contents|context-menu|contextual|copy|cover|crisp-edges|crispEdges|crosshair|cyclic|dark|darken|dashed|decimal|default|dense|diagonal-fractions|difference|digits|disabled|disc|discretionary-ligatures|distribute|distribute-all-lines|distribute-letter|distribute-space|dot|dotted|double|double-circle|downleft|downright|e-resize|each-line|ease|ease-in|ease-in-out|ease-out|economy|ellipse|ellipsis|embed|end|evenodd|ew-resize|exact|exclude|exclusion|expanded|extends|extra-condensed|extra-expanded|fallback|farthest-corner|farthest-side|fill|fill-available|fill-box|filled|fit-content|fixed|flat|flex|flex-end|flex-start|flip|flow-root|forwards|freeze|from-image|full-width|geometricPrecision|georgian|grab|grabbing|grayscale|grid|groove|hand|hanging|hard-light|help|hidden|hide|historical-forms|historical-ligatures|horizontal|horizontal-tb|hue|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|infinite|inherit|initial|inline|inline-axis|inline-block|inline-end|inline-flex|inline-grid|inline-list-item|inline-start|inline-table|inset|inside|inter-character|inter-ideograph|inter-word|intersect|invert|isolate|isolate-override|italic|jis04|jis78|jis83|jis90|justify|justify-all|kannada|keep-all|landscape|larger??|left|light|lighten|lighter|line|line-edge|line-through|linear|linearRGB|lining-nums|list-item|local|loose|lowercase|lr|lr-tb|ltr|luminance|luminosity|main-size|mandatory|manipulation|manual|margin-box|match-parent|match-source|mathematical|max-content|medium|menu|message-box|middle|min-content|miter|mixed|move|multiply|n-resize|narrower|ne-resize|nearest-neighbor|nesw-resize|newspaper|no-change|no-clip|no-close-quote|no-common-ligatures|no-contextual|no-discretionary-ligatures|no-drop|no-historical-ligatures|no-open-quote|no-repeat|none|nonzero|normal|not-allowed|nowrap|ns-resize|numbers|numeric|nw-resize|nwse-resize|oblique|oldstyle-nums|open|open-quote|optimizeLegibility|optimizeQuality|optimizeSpeed|optional|ordinal|outset|outside|over|overlay|overline|padding|padding-box|page|painted|pan-down|pan-left|pan-right|pan-up|pan-x|pan-y|paused|petite-caps|pixelated|plaintext|pointer|portrait|pre|pre-line|pre-wrap|preserve-3d|progress|progressive|proportional-nums|proportional-width|proximity|radial|recto|region|relative|remove|repeat|repeat-[xy]|reset-size|reverse|revert|ridge|right|rl|rl-tb|round|row|row-resize|row-reverse|row-severse|rtl|ruby|ruby-base|ruby-base-container|ruby-text|ruby-text-container|run-in|running|s-resize|saturation|scale-down|screen|scroll|scroll-position|se-resize|semi-condensed|semi-expanded|separate|sesame|show|sideways|sideways-left|sideways-lr|sideways-right|sideways-rl|simplified|slashed-zero|slice|small|small-caps|small-caption|smaller|smooth|soft-light|solid|space|space-around|space-between|space-evenly|spell-out|square|sRGB|stacked-fractions|start|static|status-bar|swap|step-end|step-start|sticky|stretch|strict|stroke|stroke-box|style|sub|subgrid|subpixel-antialiased|subtract|super|sw-resize|symbolic|table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|tabular-nums|tb|tb-rl|text|text-after-edge|text-before-edge|text-bottom|text-top|thick|thin|titling-caps|top|top-outside|touch|traditional|transparent|triangle|ultra-condensed|ultra-expanded|under|underline|unicase|unset|upleft|uppercase|upright|use-glyph-orientation|use-script|verso|vertical|vertical-ideographic|vertical-lr|vertical-rl|vertical-text|view-box|visible|visibleFill|visiblePainted|visibleStroke|w-resize|wait|wavy|weight|whitespace|wider|words|wrap|wrap-reverse|x|x-large|x-small|xx-large|xx-small|y|zero|zoom-in|zoom-out)(?![-\\\\\\\\w])\",\"name\":\"support.constant.property-value.css\"},{\"match\":\"(?i)(?<![-\\\\\\\\w])(arabic-indic|armenian|bengali|cambodian|circle|cjk-decimal|cjk-earthly-branch|cjk-heavenly-stem|cjk-ideographic|decimal|decimal-leading-zero|devanagari|disc|disclosure-closed|disclosure-open|ethiopic-halehame-am|ethiopic-halehame-ti-e[rt]|ethiopic-numeric|georgian|gujarati|gurmukhi|hangul|hangul-consonant|hebrew|hiragana|hiragana-iroha|japanese-formal|japanese-informal|kannada|katakana|katakana-iroha|khmer|korean-hangul-formal|korean-hanja-formal|korean-hanja-informal|lao|lower-alpha|lower-armenian|lower-greek|lower-latin|lower-roman|malayalam|mongolian|myanmar|oriya|persian|simp-chinese-formal|simp-chinese-informal|square|tamil|telugu|thai|tibetan|trad-chinese-formal|trad-chinese-informal|upper-alpha|upper-armenian|upper-latin|upper-roman|urdu)(?![-\\\\\\\\w])\",\"name\":\"support.constant.property-value.list-style-type.css\"},{\"match\":\"(?<![-\\\\\\\\w])(?i:-(?:ah|apple|atsc|epub|hp|khtml|moz|ms|o|rim|ro|tc|wap|webkit|xv)|(?:mso|prince))-[-A-Za-z]+\",\"name\":\"support.constant.vendored.property-value.css\"},{\"match\":\"(?<![-\\\\\\\\w])(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system-ui|system|tahoma|times|trebuchet|ui-monospace|ui-rounded|ui-sans-serif|ui-serif|utopia|verdana|webdings|sans-serif|serif|monospace)(?![-\\\\\\\\w])\",\"name\":\"support.constant.font-name.css\"}]},\"property-names\":{\"patterns\":[{\"match\":\"(?i)(?<![-\\\\\\\\w])(?:accent-color|additive-symbols|align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|aspect-ratio|backdrop-filter|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-position-[xy]|background-repeat|background-size|bleed|block-size|border|border-block-end|border-block-end-color|border-block-end-style|border-block-end-width|border-block-start|border-block-start-color|border-block-start-style|border-block-start-width|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-end-end-radius|border-end-start-radius|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-inline-end|border-inline-end-color|border-inline-end-style|border-inline-end-width|border-inline-start|border-inline-start-color|border-inline-start-style|border-inline-start-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-start-end-radius|border-start-start-radius|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-decoration-break|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|caret-color|clear|clip|clip-path|clip-rule|color|color-adjust|color-interpolation-filters|color-scheme|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|contain|container|container-name|container-type|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|enable-background|fallback|fill|fill-opacity|fill-rule|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|flood-color|flood-opacity|font|font-display|font-family|font-feature-settings|font-kerning|font-language-override|font-optical-sizing|font-size|font-size-adjust|font-stretch|font-style|font-synthesis|font-variant|font-variant-alternates|font-variant-caps|font-variant-east-asian|font-variant-ligatures|font-variant-numeric|font-variant-position|font-variation-settings|font-weight|gap|glyph-orientation-horizontal|glyph-orientation-vertical|grid|grid-area|grid-auto-columns|grid-auto-flow|grid-auto-rows|grid-column|grid-column-end|grid-column-gap|grid-column-start|grid-gap|grid-row|grid-row-end|grid-row-gap|grid-row-start|grid-template|grid-template-areas|grid-template-columns|grid-template-rows|hanging-punctuation|height|hyphens|image-orientation|image-rendering|image-resolution|ime-mode|initial-letter|initial-letter-align|inline-size|inset|inset-block|inset-block-end|inset-block-start|inset-inline|inset-inline-end|inset-inline-start|isolation|justify-content|justify-items|justify-self|kerning|left|letter-spacing|lighting-color|line-break|line-clamp|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-block|margin-block-end|margin-block-start|margin-bottom|margin-inline|margin-inline-end|margin-inline-start|margin-left|margin-right|margin-top|marker-end|marker-mid|marker-start|marks|mask|mask-border|mask-border-mode|mask-border-outset|mask-border-repeat|mask-border-slice|mask-border-source|mask-border-width|mask-clip|mask-composite|mask-image|mask-mode|mask-origin|mask-position|mask-repeat|mask-size|mask-type|max-block-size|max-height|max-inline-size|max-lines|max-width|max-zoom|min-block-size|min-height|min-inline-size|min-width|min-zoom|mix-blend-mode|negative|object-fit|object-position|offset|offset-anchor|offset-distance|offset-path|offset-position|offset-rotation|opacity|order|orientation|orphans|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-anchor|overflow-block|overflow-inline|overflow-wrap|overflow-[xy]|overscroll-behavior|overscroll-behavior-block|overscroll-behavior-inline|overscroll-behavior-[xy]|pad|padding|padding-block|padding-block-end|padding-block-start|padding-bottom|padding-inline|padding-inline-end|padding-inline-start|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|paint-order|perspective|perspective-origin|place-content|place-items|place-self|pointer-events|position|prefix|quotes|range|resize|right|rotate|row-gap|ruby-align|ruby-merge|ruby-position|scale|scroll-behavior|scroll-margin|scroll-margin-block|scroll-margin-block-end|scroll-margin-block-start|scroll-margin-bottom|scroll-margin-inline|scroll-margin-inline-end|scroll-margin-inline-start|scroll-margin-left|scroll-margin-right|scroll-margin-top|scroll-padding|scroll-padding-block|scroll-padding-block-end|scroll-padding-block-start|scroll-padding-bottom|scroll-padding-inline|scroll-padding-inline-end|scroll-padding-inline-start|scroll-padding-left|scroll-padding-right|scroll-padding-top|scroll-snap-align|scroll-snap-coordinate|scroll-snap-destination|scroll-snap-stop|scroll-snap-type|scrollbar-color|scrollbar-gutter|scrollbar-width|shape-image-threshold|shape-margin|shape-outside|shape-rendering|size|speak-as|src|stop-color|stop-opacity|stroke|stroke-dasharray|stroke-dashoffset|stroke-linecap|stroke-linejoin|stroke-miterlimit|stroke-opacity|stroke-width|suffix|symbols|system|tab-size|table-layout|text-align|text-align-last|text-anchor|text-combine-upright|text-decoration|text-decoration-color|text-decoration-line|text-decoration-skip|text-decoration-skip-ink|text-decoration-style|text-decoration-thickness|text-emphasis|text-emphasis-color|text-emphasis-position|text-emphasis-style|text-indent|text-justify|text-orientation|text-overflow|text-rendering|text-shadow|text-size-adjust|text-transform|text-underline-offset|text-underline-position|top|touch-action|transform|transform-box|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|translate|unicode-bidi|unicode-range|user-select|user-zoom|vertical-align|visibility|white-space|widows|width|will-change|word-break|word-spacing|word-wrap|writing-mode|z-index|zoom|alignment-baseline|baseline-shift|clip-rule|color-interpolation|color-interpolation-filters|color-profile|color-rendering|cx|cy|dominant-baseline|enable-background|fill|fill-opacity|fill-rule|flood-color|flood-opacity|glyph-orientation-horizontal|glyph-orientation-vertical|height|kerning|lighting-color|marker-end|marker-mid|marker-start|rx??|ry|shape-rendering|stop-color|stop-opacity|stroke|stroke-dasharray|stroke-dashoffset|stroke-linecap|stroke-linejoin|stroke-miterlimit|stroke-opacity|stroke-width|text-anchor|width|[xy]|adjust|after|align|align-last|alignment|alignment-adjust|appearance|attachment|azimuth|background-break|balance|baseline|before|bidi|binding|bookmark|bookmark-label|bookmark-level|bookmark-target|border-length|bottom-color|bottom-left-radius|bottom-right-radius|bottom-style|bottom-width|box|box-align|box-direction|box-flex|box-flex-group|box-lines|box-ordinal-group|box-orient|box-pack|break|character|collapse|column|column-break-after|column-break-before|count|counter|crop|cue|cue-after|cue-before|decoration|decoration-break|delay|display-model|display-role|down|drop|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|duration|elevation|emphasis|family|fit|fit-position|flex-group|float-offset|gap|grid-columns|grid-rows|hanging-punctuation|header|hyphenate|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|icon|image|increment|indent|index|initial-after-adjust|initial-after-align|initial-before-adjust|initial-before-align|initial-size|initial-value|inline-box-align|iteration-count|justify|label|left-color|left-style|left-width|length|level|line|line-stacking|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|lines|list|mark|mark-after|mark-before|marks|marquee|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max|min|model|move-to|name|nav|nav-down|nav-index|nav-left|nav-right|nav-up|new|numeral|offset|ordinal-group|orient|origin|overflow-style|overhang|pack|page|page-policy|pause|pause-after|pause-before|phonemes|pitch|pitch-range|play-count|play-during|play-state|point|presentation|presentation-level|profile|property|punctuation|punctuation-trim|radius|rate|rendering-intent|repeat|replace|reset|resolution|resource|respond-to|rest|rest-after|rest-before|richness|right-color|right-style|right-width|role|rotation|rotation-point|rows|ruby|ruby-overhang|ruby-span|rule|rule-color|rule-style|rule-width|shadow|size|size-adjust|sizing|space|space-collapse|spacing|span|speak|speak-header|speak-numeral|speak-punctuation|speech|speech-rate|speed|stacking|stacking-ruby|stacking-shift|stacking-strategy|stress|stretch|string-set|style|style-image|style-position|style-type|target|target-name|target-new|target-position|text|text-height|text-justify|text-outline|text-replace|text-wrap|timing-function|top-color|top-left-radius|top-right-radius|top-style|top-width|trim|unicode|up|user-select|variant|voice|voice-balance|voice-duration|voice-family|voice-pitch|voice-pitch-range|voice-rate|voice-stress|voice-volume|volume|weight|white|white-space-collapse|word|wrap)(?![-\\\\\\\\w])\",\"name\":\"support.type.property-name.css\"},{\"match\":\"(?<![-\\\\\\\\w])(?i:-(?:ah|apple|atsc|epub|hp|khtml|moz|ms|o|rim|ro|tc|wap|webkit|xv)|(?:mso|prince))-[-A-Za-z]+\",\"name\":\"support.type.vendored.property-name.css\"}]},\"property-values\":{\"patterns\":[{\"include\":\"#commas\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#functions\"},{\"include\":\"#property-keywords\"},{\"include\":\"#unicode-range\"},{\"include\":\"#numeric-values\"},{\"include\":\"#color-keywords\"},{\"include\":\"#string\"},{\"match\":\"!\\\\\\\\s*important(?![-\\\\\\\\w])\",\"name\":\"keyword.other.important.css\"}]},\"pseudo-classes\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.css\"},\"2\":{\"name\":\"invalid.illegal.colon.css\"}},\"match\":\"(?i)(:)(:*)(?:active|any-link|checked|default|disabled|empty|enabled|first|(?:first|last|only)-(?:child|of-type)|focus|focus-visible|focus-within|fullscreen|host|hover|in-range|indeterminate|invalid|left|link|optional|out-of-range|read-only|read-write|required|right|root|scope|target|unresolved|valid|visited)(?![-\\\\\\\\w]|\\\\\\\\s*[;}])\",\"name\":\"entity.other.attribute-name.pseudo-class.css\"},\"pseudo-elements\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.css\"},\"2\":{\"name\":\"punctuation.definition.entity.css\"}},\"match\":\"(?i)(?:(::?)(?:after|before|first-letter|first-line|(?:-(?:ah|apple|atsc|epub|hp|khtml|moz|ms|o|rim|ro|tc|wap|webkit|xv)|(?:mso|prince))-[-a-z]+)|(::)(?:backdrop|content|grammar-error|marker|placeholder|selection|shadow|spelling-error))(?![-\\\\\\\\w]|\\\\\\\\s*[;}])\",\"name\":\"entity.other.attribute-name.pseudo-element.css\"},\"rule-list\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.begin.bracket.curly.css\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.property-list.end.bracket.curly.css\"}},\"name\":\"meta.property-list.css\",\"patterns\":[{\"include\":\"#rule-list-innards\"}]},\"rule-list-innards\":{\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"},{\"include\":\"#font-features\"},{\"match\":\"(?<![-\\\\\\\\w])--[-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*\",\"name\":\"variable.css\"},{\"begin\":\"(?<![-A-Za-z])(?=[-A-Za-z])\",\"end\":\"$|(?![-A-Za-z])\",\"name\":\"meta.property-name.css\",\"patterns\":[{\"include\":\"#property-names\"}]},{\"begin\":\"(:)\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.separator.key-value.css\"}},\"contentName\":\"meta.property-value.css\",\"end\":\"\\\\\\\\s*(;)|\\\\\\\\s*(?=[)}])\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.terminator.rule.css\"}},\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#property-values\"}]},{\"match\":\";\",\"name\":\"punctuation.terminator.rule.css\"}]},\"selector\":{\"begin\":\"(?=\\\\\\\\|?(?:[-#*.:A-\\\\\\\\[_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.)))\",\"end\":\"(?=\\\\\\\\s*[)/@{])\",\"name\":\"meta.selector.css\",\"patterns\":[{\"include\":\"#selector-innards\"}]},\"selector-innards\":{\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#commas\"},{\"include\":\"#escapes\"},{\"include\":\"#combinators\"},{\"captures\":{\"1\":{\"name\":\"entity.other.namespace-prefix.css\"},\"2\":{\"name\":\"punctuation.separator.css\"}},\"match\":\"(?:^|(?<=[(,;}\\\\\\\\s]))(?![-*\\\\\\\\w]+\\\\\\\\|(?![-#*.:A-\\\\\\\\[_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]))([-A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]](?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*|\\\\\\\\*)?(\\\\\\\\|)\"},{\"include\":\"#tag-names\"},{\"match\":\"\\\\\\\\*\",\"name\":\"entity.name.tag.wildcard.css\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.css\"},\"2\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(?<![-@\\\\\\\\w])([#.])((?:-?[0-9]|-(?=$|[#)+,.:>\\\\\\\\[{|~\\\\\\\\s]|/\\\\\\\\*)|(?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*(?:[]!\\\\\"%-(*;<?@^\\`|}]|/(?!\\\\\\\\*))+)(?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))*)\",\"name\":\"invalid.illegal.bad-identifier.css\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.css\"},\"2\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(\\\\\\\\.)((?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))+)(?=$|[#)+,.:>\\\\\\\\[{|~\\\\\\\\s]|/\\\\\\\\*)\",\"name\":\"entity.other.attribute-name.class.css\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.css\"},\"2\":{\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(#)(-?(?![0-9])(?:[-0-9A-Z_a-z[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))+)(?=$|[#)+,.:>\\\\\\\\[{|~\\\\\\\\s]|/\\\\\\\\*)\",\"name\":\"entity.other.attribute-name.id.css\"},{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.entity.begin.bracket.square.css\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.entity.end.bracket.square.css\"}},\"name\":\"meta.attribute-selector.css\",\"patterns\":[{\"include\":\"#comment-block\"},{\"include\":\"#string\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.ignore-case.css\"}},\"match\":\"(?<=[\\\\\"'\\\\\\\\s]|^|\\\\\\\\*/)\\\\\\\\s*([Ii])\\\\\\\\s*(?=[]\\\\\\\\s]|/\\\\\\\\*|$)\"},{\"captures\":{\"1\":{\"name\":\"string.unquoted.attribute-value.css\",\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(?<==)\\\\\\\\s*((?!/\\\\\\\\*)(?:[^]\\\\\"'\\\\\\\\\\\\\\\\\\\\\\\\s]|\\\\\\\\\\\\\\\\.)+)\"},{\"include\":\"#escapes\"},{\"match\":\"[$*^|~]?=\",\"name\":\"keyword.operator.pattern.css\"},{\"match\":\"\\\\\\\\|\",\"name\":\"punctuation.separator.css\"},{\"captures\":{\"1\":{\"name\":\"entity.other.namespace-prefix.css\",\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(-?(?!\\\\\\\\d)(?:[-\\\\\\\\w[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))+|\\\\\\\\*)(?=\\\\\\\\|(?![=\\\\\\\\s]|$|])(?:-?(?!\\\\\\\\d)|[-\\\\\\\\\\\\\\\\\\\\\\\\w[^\\\\\\\\x00-\\\\\\\\x7F]]))\"},{\"captures\":{\"1\":{\"name\":\"entity.other.attribute-name.css\",\"patterns\":[{\"include\":\"#escapes\"}]}},\"match\":\"(-?(?!\\\\\\\\d)(?>[-\\\\\\\\w[^\\\\\\\\x00-\\\\\\\\x7F]]|\\\\\\\\\\\\\\\\(?:\\\\\\\\h{1,6}|.))+)\\\\\\\\s*(?=[]$*=^|~]|/\\\\\\\\*)\"}]},{\"include\":\"#pseudo-classes\"},{\"include\":\"#pseudo-elements\"},{\"include\":\"#functional-pseudo-classes\"},{\"match\":\"(?<![-@\\\\\\\\w])(?=[a-z]\\\\\\\\w*-)(?:(?![A-Z])[-\\\\\\\\w])+(?![-(\\\\\\\\w])\",\"name\":\"entity.name.tag.custom.css\"}]},\"string\":{\"patterns\":[{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.css\"}},\"end\":\"\\\\\"|(?<!\\\\\\\\\\\\\\\\)(?=$|\\\\\\\\n)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.css\"}},\"name\":\"string.quoted.double.css\",\"patterns\":[{\"begin\":\"(?:\\\\\\\\G|^)(?=(?:[^\\\\\"\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)+$)\",\"end\":\"$\",\"name\":\"invalid.illegal.unclosed.string.css\",\"patterns\":[{\"include\":\"#escapes\"}]},{\"include\":\"#escapes\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.css\"}},\"end\":\"'|(?<!\\\\\\\\\\\\\\\\)(?=$|\\\\\\\\n)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.css\"}},\"name\":\"string.quoted.single.css\",\"patterns\":[{\"begin\":\"(?:\\\\\\\\G|^)(?=(?:[^'\\\\\\\\\\\\\\\\]|\\\\\\\\\\\\\\\\.)+$)\",\"end\":\"$\",\"name\":\"invalid.illegal.unclosed.string.css\",\"patterns\":[{\"include\":\"#escapes\"}]},{\"include\":\"#escapes\"}]}]},\"tag-names\":{\"match\":\"(?i)(?<![-:\\\\\\\\w])(?:a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdi|bdo|bgsound|big|blink|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|content|data|datalist|dd|del|details|dfn|dialog|dir|div|dl|dt|element|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h[1-6]|head|header|hgroup|hr|html|i|iframe|image|img|input|ins|isindex|kbd|keygen|label|legend|li|link|listing|main|map|mark|marquee|math|menu|menuitem|meta|meter|multicol|nav|nextid|nobr|noembed|noframes|noscript|object|ol|optgroup|option|output|p|param|picture|plaintext|pre|progress|q|rb|rp|rtc??|ruby|s|samp|script|section|select|shadow|slot|small|source|spacer|span|strike|strong|style|sub|summary|sup|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|tt|ul??|var|video|wbr|xmp|altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|use|view|vkern|annotation|annotation-xml|maction|maligngroup|malignmark|math|menclose|merror|mfenced|mfrac|mglyph|mi|mlabeledtr|mlongdiv|mmultiscripts|mn|mo|mover|mpadded|mphantom|mroot|mrow|ms|mscarries|mscarry|msgroup|msline|mspace|msqrt|msrow|mstack|mstyle|msub|msubsup|msup|mtable|mtd|mtext|mtr|munder|munderover|semantics)(?=[#)+,.:>\\\\\\\\[{|~\\\\\\\\s]|/\\\\\\\\*|$)\",\"name\":\"entity.name.tag.css\"},\"unicode-range\":{\"captures\":{\"0\":{\"name\":\"constant.other.unicode-range.css\"},\"1\":{\"name\":\"punctuation.separator.dash.unicode-range.css\"}},\"match\":\"(?<![-\\\\\\\\w])[Uu]\\\\\\\\+[?\\\\\\\\h]{1,6}(?:(-)\\\\\\\\h{1,6})?(?![-\\\\\\\\w])\"},\"url\":{\"begin\":\"(?i)(?<![-@\\\\\\\\w])(url)(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.url.css\"},\"2\":{\"name\":\"punctuation.section.function.begin.bracket.round.css\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.function.end.bracket.round.css\"}},\"name\":\"meta.function.url.css\",\"patterns\":[{\"match\":\"[^\\\\\"')\\\\\\\\s]+\",\"name\":\"variable.parameter.url.css\"},{\"include\":\"#string\"},{\"include\":\"#comment-block\"},{\"include\":\"#escapes\"}]}},\"scopeName\":\"source.css\"}`)),Gl=[w_],x_=Object.freeze(JSON.parse(`{\"displayName\":\"HTML\",\"injections\":{\"R:text.html - (comment.block, text.html meta.embedded, meta.tag.*.*.html, meta.tag.*.*.*.html, meta.tag.*.*.*.*.html)\":{\"patterns\":[{\"match\":\"<\",\"name\":\"invalid.illegal.bad-angle-bracket.html\"}]}},\"name\":\"html\",\"patterns\":[{\"include\":\"#xml-processing\"},{\"include\":\"#comment\"},{\"include\":\"#doctype\"},{\"include\":\"#cdata\"},{\"include\":\"#tags-valid\"},{\"include\":\"#tags-invalid\"},{\"include\":\"#entities\"}],\"repository\":{\"attribute\":{\"patterns\":[{\"begin\":\"(s(hape|cope|t(ep|art)|ize(s)?|p(ellcheck|an)|elected|lot|andbox|rc(set|doc|lang)?)|h(ttp-equiv|i(dden|gh)|e(ight|aders)|ref(lang)?)|n(o(nce|validate|module)|ame)|c(h(ecked|arset)|ite|o(nt(ent(editable)?|rols)|ords|l(s(pan)?|or))|lass|rossorigin)|t(ype(mustmatch)?|itle|a(rget|bindex)|ranslate)|i(s(map)?|n(tegrity|putmode)|tem(scope|type|id|prop|ref)|d)|op(timum|en)|d(i(sabled|r(name)?)|ownload|e(coding|f(er|ault))|at(etime|a)|raggable)|usemap|p(ing|oster|la(ysinline|ceholder)|attern|reload)|enctype|value|kind|for(m(novalidate|target|enctype|action|method)?)?|w(idth|rap)|l(ist|o(op|w)|a(ng|bel))|a(s(ync)?|c(ce(sskey|pt(-charset)?)|tion)|uto(c(omplete|apitalize)|play|focus)|l(t|low(usermedia|paymentrequest|fullscreen))|bbr)|r(ows(pan)?|e(versed|quired|ferrerpolicy|l|adonly))|m(in(length)?|u(ted|ltiple)|e(thod|dia)|a(nifest|x(length)?)))(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"begin\":\"style(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.style.html\",\"patterns\":[{\"begin\":\"=\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.separator.key-value.html\"}},\"end\":\"(?<=[^=\\\\\\\\s])(?!\\\\\\\\s*=)|(?=/?>)\",\"patterns\":[{\"begin\":\"(?=[^/<=>\\`\\\\\\\\s]|/(?!>))\",\"end\":\"(?!\\\\\\\\G)\",\"name\":\"meta.embedded.line.css\",\"patterns\":[{\"captures\":{\"0\":{\"name\":\"source.css\"}},\"match\":\"([^\\\\\"'/<=>\\`\\\\\\\\s]|/(?!>))+\",\"name\":\"string.unquoted.html\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"contentName\":\"source.css\",\"end\":\"(\\\\\")\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"},\"1\":{\"name\":\"source.css\"}},\"name\":\"string.quoted.double.html\",\"patterns\":[{\"include\":\"#entities\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"contentName\":\"source.css\",\"end\":\"(')\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"},\"1\":{\"name\":\"source.css\"}},\"name\":\"string.quoted.single.html\",\"patterns\":[{\"include\":\"#entities\"}]}]},{\"match\":\"=\",\"name\":\"invalid.illegal.unexpected-equals-sign.html\"}]}]},{\"begin\":\"on(s(croll|t(orage|alled)|u(spend|bmit)|e(curitypolicyviolation|ek(ing|ed)|lect))|hashchange|c(hange|o(ntextmenu|py)|u(t|echange)|l(ick|ose)|an(cel|play(through)?))|t(imeupdate|oggle)|in(put|valid)|o((?:n|ff)line)|d(urationchange|r(op|ag(start|over|e(n(ter|d)|xit)|leave)?)|blclick)|un(handledrejection|load)|p(opstate|lay(ing)?|a(ste|use|ge(show|hide))|rogress)|e(nded|rror|mptied)|volumechange|key(down|up|press)|focus|w(heel|aiting)|l(oad(start|e(nd|d((?:|meta)data)))?|anguagechange)|a(uxclick|fterprint|bort)|r(e(s(ize|et)|jectionhandled)|atechange)|m(ouse(o(ut|ver)|down|up|enter|leave|move)|essage(error)?)|b(efore(unload|print)|lur))(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.event-handler.$1.html\",\"patterns\":[{\"begin\":\"=\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.separator.key-value.html\"}},\"end\":\"(?<=[^=\\\\\\\\s])(?!\\\\\\\\s*=)|(?=/?>)\",\"patterns\":[{\"begin\":\"(?=[^/<=>\\`\\\\\\\\s]|/(?!>))\",\"end\":\"(?!\\\\\\\\G)\",\"name\":\"meta.embedded.line.js\",\"patterns\":[{\"captures\":{\"0\":{\"name\":\"source.js\"},\"1\":{\"patterns\":[{\"include\":\"source.js\"}]}},\"match\":\"(([^\\\\\"'/<=>\\`\\\\\\\\s]|/(?!>))+)\",\"name\":\"string.unquoted.html\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"contentName\":\"source.js\",\"end\":\"(\\\\\")\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"},\"1\":{\"name\":\"source.js\"}},\"name\":\"string.quoted.double.html\",\"patterns\":[{\"captures\":{\"0\":{\"patterns\":[{\"include\":\"source.js\"}]}},\"match\":\"([^\\\\\\\\n\\\\\"/]|/(?![*/]))+\"},{\"begin\":\"//\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"(?=\\\\\")|\\\\\\\\n\",\"name\":\"comment.line.double-slash.js\"},{\"begin\":\"/\\\\\\\\*\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.begin.js\"}},\"end\":\"(?=\\\\\")|\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.end.js\"}},\"name\":\"comment.block.js\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"contentName\":\"source.js\",\"end\":\"(')\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"},\"1\":{\"name\":\"source.js\"}},\"name\":\"string.quoted.single.html\",\"patterns\":[{\"captures\":{\"0\":{\"patterns\":[{\"include\":\"source.js\"}]}},\"match\":\"([^\\\\\\\\n'/]|/(?![*/]))+\"},{\"begin\":\"//\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"(?=')|\\\\\\\\n\",\"name\":\"comment.line.double-slash.js\"},{\"begin\":\"/\\\\\\\\*\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.begin.js\"}},\"end\":\"(?=')|\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.end.js\"}},\"name\":\"comment.block.js\"}]}]},{\"match\":\"=\",\"name\":\"invalid.illegal.unexpected-equals-sign.html\"}]}]},{\"begin\":\"(data-[-a-z]+)(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.data-x.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"begin\":\"(align|bgcolor|border)(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"invalid.deprecated.entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"begin\":\"([^\\\\\\\\x00- \\\\\"'/<=>\\\\\\\\x7F-\\\\\\\\x{9F}﷐-﷯￾￿🿾🿿𯿾𯿿𿿾𿿿\\\\\\\\x{4FFFE}\\\\\\\\x{4FFFF}\\\\\\\\x{5FFFE}\\\\\\\\x{5FFFF}\\\\\\\\x{6FFFE}\\\\\\\\x{6FFFF}\\\\\\\\x{7FFFE}\\\\\\\\x{7FFFF}\\\\\\\\x{8FFFE}\\\\\\\\x{8FFFF}\\\\\\\\x{9FFFE}\\\\\\\\x{9FFFF}\\\\\\\\x{AFFFE}\\\\\\\\x{AFFFF}\\\\\\\\x{BFFFE}\\\\\\\\x{BFFFF}\\\\\\\\x{CFFFE}\\\\\\\\x{CFFFF}\\\\\\\\x{DFFFE}\\\\\\\\x{DFFFF}\\\\\\\\x{EFFFE}\\\\\\\\x{EFFFF}\\\\\\\\x{FFFFE}\\\\\\\\x{FFFFF}\\\\\\\\x{10FFFE}\\\\\\\\x{10FFFF}]+)\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.unrecognized.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"match\":\"[^>\\\\\\\\s]+\",\"name\":\"invalid.illegal.character-not-allowed-here.html\"}]},\"attribute-interior\":{\"patterns\":[{\"begin\":\"=\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.separator.key-value.html\"}},\"end\":\"(?<=[^=\\\\\\\\s])(?!\\\\\\\\s*=)|(?=/?>)\",\"patterns\":[{\"match\":\"([^\\\\\"'/<=>\\`\\\\\\\\s]|/(?!>))+\",\"name\":\"string.unquoted.html\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"}},\"name\":\"string.quoted.double.html\",\"patterns\":[{\"include\":\"#entities\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.html\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.html\"}},\"name\":\"string.quoted.single.html\",\"patterns\":[{\"include\":\"#entities\"}]},{\"match\":\"=\",\"name\":\"invalid.illegal.unexpected-equals-sign.html\"}]}]},\"cdata\":{\"begin\":\"<!\\\\\\\\[CDATA\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.begin.html\"}},\"contentName\":\"string.other.inline-data.html\",\"end\":\"]]>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.cdata.html\"},\"comment\":{\"begin\":\"<!--\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.html\"}},\"end\":\"-->\",\"name\":\"comment.block.html\",\"patterns\":[{\"match\":\"\\\\\\\\G-?>\",\"name\":\"invalid.illegal.characters-not-allowed-here.html\"},{\"match\":\"<!-(?:-(?!>)|(?=-->))\",\"name\":\"invalid.illegal.characters-not-allowed-here.html\"},{\"match\":\"--!>\",\"name\":\"invalid.illegal.characters-not-allowed-here.html\"}]},\"core-minus-invalid\":{\"patterns\":[{\"include\":\"#xml-processing\"},{\"include\":\"#comment\"},{\"include\":\"#doctype\"},{\"include\":\"#cdata\"},{\"include\":\"#tags-valid\"},{\"include\":\"#entities\"}]},\"doctype\":{\"begin\":\"<!(?=(?i:DOCTYPE\\\\\\\\s))\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.begin.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.doctype.html\",\"patterns\":[{\"match\":\"\\\\\\\\G(?i:DOCTYPE)\",\"name\":\"entity.name.tag.html\"},{\"begin\":\"\\\\\"\",\"end\":\"\\\\\"\",\"name\":\"string.quoted.double.html\"},{\"match\":\"[^>\\\\\\\\s]+\",\"name\":\"entity.other.attribute-name.html\"}]},\"entities\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.html\"},\"912\":{\"name\":\"punctuation.definition.entity.html\"}},\"match\":\"(&)(?=[A-Za-z])((a(s(ymp(eq)?|cr|t)|n(d(slope|[dv]|and)?|g(s(t|ph)|zarr|e|le|rt(vb(d)?)?|msd(a([a-h]))?)?)|c(y|irc|d|ute|E)?|tilde|o(pf|gon)|uml|p(id|os|prox(eq)?|[Ee]|acir)?|elig|f(r)?|w((?:con|)int)|l(pha|e(ph|fsym))|acute|ring|grave|m(p|a(cr|lg))|breve)|A(s(sign|cr)|nd|MP|c(y|irc)|tilde|o(pf|gon)|uml|pplyFunction|fr|Elig|lpha|acute|ring|grave|macr|breve))|(B(scr|cy|opf|umpeq|e(cause|ta|rnoullis)|fr|a(ckslash|r(v|wed))|reve)|b(s(cr|im(e)?|ol(hsub|b)?|emi)|n(ot|e(quiv)?)|c(y|ong)|ig(s(tar|qcup)|c(irc|up|ap)|triangle(down|up)|o(times|dot|plus)|uplus|vee|wedge)|o(t(tom)?|pf|wtie|x(h([DUdu])?|times|H([DUdu])?|d([LRlr])|u([LRlr])|plus|D([LRlr])|v([HLRhlr])?|U([LRlr])|V([HLRhlr])?|minus|box))|Not|dquo|u(ll(et)?|mp(e(q)?|E)?)|prime|e(caus(e)?|t(h|ween|a)|psi|rnou|mptyv)|karow|fr|l(ock|k(1([24])|34)|a(nk|ck(square|triangle(down|left|right)?|lozenge)))|a(ck(sim(eq)?|cong|prime|epsilon)|r(vee|wed(ge)?))|r(eve|vbar)|brk(tbrk)?))|(c(s(cr|u(p(e)?|b(e)?))|h(cy|i|eck(mark)?)|ylcty|c(irc|ups(sm)?|edil|a(ps|ron))|tdot|ir(scir|c(eq|le(d(R|circ|S|dash|ast)|arrow(left|right)))?|e|fnint|E|mid)?|o(n(int|g(dot)?)|p(y(sr)?|f|rod)|lon(e(q)?)?|m(p(fn|le(xes|ment))?|ma(t)?))|dot|u(darr([lr])|p(s|c([au]p)|or|dot|brcap)?|e(sc|pr)|vee|wed|larr(p)?|r(vearrow(left|right)|ly(eq(succ|prec)|vee|wedge)|arr(m)?|ren))|e(nt(erdot)?|dil|mptyv)|fr|w((?:con|)int)|lubs(uit)?|a(cute|p(s|c([au]p)|dot|and|brcup)?|r(on|et))|r(oss|arr))|C(scr|hi|c(irc|onint|edil|aron)|ircle(Minus|Times|Dot|Plus)|Hcy|o(n(tourIntegral|int|gruent)|unterClockwiseContourIntegral|p(f|roduct)|lon(e)?)|dot|up(Cap)?|OPY|e(nterDot|dilla)|fr|lo(seCurly((?:Double|)Quote)|ckwiseContourIntegral)|a(yleys|cute|p(italDifferentialD)?)|ross))|(d(s(c([ry])|trok|ol)|har([lr])|c(y|aron)|t(dot|ri(f)?)|i(sin|e|v(ide(ontimes)?|onx)?|am(s|ond(suit)?)?|gamma)|Har|z(cy|igrarr)|o(t(square|plus|eq(dot)?|minus)?|ublebarwedge|pf|wn(harpoon(left|right)|downarrows|arrow)|llar)|d(otseq|a(rr|gger))?|u(har|arr)|jcy|e(lta|g|mptyv)|f(isht|r)|wangle|lc(orn|rop)|a(sh(v)?|leth|rr|gger)|r(c(orn|rop)|bkarow)|b(karow|lac)|Arr)|D(s(cr|trok)|c(y|aron)|Scy|i(fferentialD|a(critical(Grave|Tilde|Do(t|ubleAcute)|Acute)|mond))|o(t(Dot|Equal)?|uble(Right(Tee|Arrow)|ContourIntegral|Do(t|wnArrow)|Up((?:Down|)Arrow)|VerticalBar|L(ong(RightArrow|Left((?:Right|)Arrow))|eft(RightArrow|Tee|Arrow)))|pf|wn(Right(TeeVector|Vector(Bar)?)|Breve|Tee(Arrow)?|arrow|Left(RightVector|TeeVector|Vector(Bar)?)|Arrow(Bar|UpArrow)?))|Zcy|el(ta)?|D(otrahd)?|Jcy|fr|a(shv|rr|gger)))|(e(s(cr|im|dot)|n(sp|g)|c(y|ir(c)?|olon|aron)|t([ah])|o(pf|gon)|dot|u(ro|ml)|p(si(v|lon)?|lus|ar(sl)?)|e|D(D??ot)|q(s(im|lant(less|gtr))|c(irc|olon)|u(iv(DD)?|est|als)|vparsl)|f(Dot|r)|l(s(dot)?|inters|l)?|a(ster|cute)|r(Dot|arr)|g(s(dot)?|rave)?|x(cl|ist|p(onentiale|ectation))|m(sp(1([34]))?|pty(set|v)?|acr))|E(s(cr|im)|c(y|irc|aron)|ta|o(pf|gon)|NG|dot|uml|TH|psilon|qu(ilibrium|al(Tilde)?)|fr|lement|acute|grave|x(ists|ponentialE)|m(pty((?:|Very)SmallSquare)|acr)))|(f(scr|nof|cy|ilig|o(pf|r(k(v)?|all))|jlig|partint|emale|f(ilig|l(l??ig)|r)|l(tns|lig|at)|allingdotseq|r(own|a(sl|c(1([2-68])|78|2([35])|3([458])|45|5([68])))))|F(scr|cy|illed((?:|Very)SmallSquare)|o(uriertrf|pf|rAll)|fr))|(G(scr|c(y|irc|edil)|t|opf|dot|T|Jcy|fr|amma(d)?|reater(Greater|SlantEqual|Tilde|Equal(Less)?|FullEqual|Less)|g|breve)|g(s(cr|im([el])?)|n(sim|e(q(q)?)?|E|ap(prox)?)|c(y|irc)|t(c(c|ir)|dot|quest|lPar|r(sim|dot|eq(q?less)|less|a(pprox|rr)))?|imel|opf|dot|jcy|e(s(cc|dot(o(l)?)?|l(es)?)?|q(slant|q)?|l)?|v(nE|ertneqq)|fr|E(l)?|l([Eaj])?|a(cute|p|mma(d)?)|rave|g(g)?|breve))|(h(s(cr|trok|lash)|y(phen|bull)|circ|o(ok((?:lef|righ)tarrow)|pf|arr|rbar|mtht)|e(llip|arts(uit)?|rcon)|ks([ew]arow)|fr|a(irsp|lf|r(dcy|r(cir|w)?)|milt)|bar|Arr)|H(s(cr|trok)|circ|ilbertSpace|o(pf|rizontalLine)|ump(DownHump|Equal)|fr|a(cek|t)|ARDcy))|(i(s(cr|in(s(v)?|dot|[Ev])?)|n(care|t(cal|prod|e(rcal|gers)|larhk)?|odot|fin(tie)?)?|c(y|irc)?|t(ilde)?|i(nfin|i(i??nt)|ota)?|o(cy|ta|pf|gon)|u(kcy|ml)|jlig|prod|e(cy|xcl)|quest|f([fr])|acute|grave|m(of|ped|a(cr|th|g(part|e|line))))|I(scr|n(t(e(rsection|gral))?|visible(Comma|Times))|c(y|irc)|tilde|o(ta|pf|gon)|dot|u(kcy|ml)|Ocy|Jlig|fr|Ecy|acute|grave|m(plies|a(cr|ginaryI))?))|(j(s(cr|ercy)|c(y|irc)|opf|ukcy|fr|math)|J(s(cr|ercy)|c(y|irc)|opf|ukcy|fr))|(k(scr|hcy|c(y|edil)|opf|jcy|fr|appa(v)?|green)|K(scr|c(y|edil)|Hcy|opf|Jcy|fr|appa))|(l(s(h|cr|trok|im([eg])?|q(uo(r)?|b)|aquo)|h(ar(d|u(l)?)|blk)|n(sim|e(q(q)?)?|E|ap(prox)?)|c(y|ub|e(d??il)|aron)|Barr|t(hree|c(c|ir)|imes|dot|quest|larr|r(i([ef])?|Par))?|Har|o(ng(left((?:|right)arrow)|rightarrow|mapsto)|times|z(enge|f)?|oparrow(left|right)|p(f|lus|ar)|w(ast|bar)|a(ng|rr)|brk)|d(sh|ca|quo(r)?|r((?:d|us)har))|ur((?:ds|u)har)|jcy|par(lt)?|e(s(s(sim|dot|eq(q?gtr)|approx|gtr)|cc|dot(o(r)?)?|g(es)?)?|q(slant|q)?|ft(harpoon(down|up)|threetimes|leftarrows|arrow(tail)?|right(squigarrow|harpoons|arrow(s)?))|g)?|v(nE|ertneqq)|f(isht|loor|r)|E(g)?|l(hard|corner|tri|arr)?|a(ng(d|le)?|cute|t(e(s)?|ail)?|p|emptyv|quo|rr(sim|hk|tl|pl|fs|lp|b(fs)?)?|gran|mbda)|r(har(d)?|corner|tri|arr|m)|g(E)?|m(idot|oust(ache)?)|b(arr|r(k(sl([du])|e)|ac([ek]))|brk)|A(tail|arr|rr))|L(s(h|cr|trok)|c(y|edil|aron)|t|o(ng(RightArrow|left((?:|right)arrow)|rightarrow|Left((?:Right|)Arrow))|pf|wer((?:Righ|Lef)tArrow))|T|e(ss(Greater|SlantEqual|Tilde|EqualGreater|FullEqual|Less)|ft(Right(Vector|Arrow)|Ceiling|T(ee(Vector|Arrow)?|riangle(Bar|Equal)?)|Do(ubleBracket|wn(TeeVector|Vector(Bar)?))|Up(TeeVector|DownVector|Vector(Bar)?)|Vector(Bar)?|arrow|rightarrow|Floor|A(ngleBracket|rrow(RightArrow|Bar)?)))|Jcy|fr|l(eftarrow)?|a(ng|cute|placetrf|rr|mbda)|midot))|(M(scr|cy|inusPlus|opf|u|e(diumSpace|llintrf)|fr|ap)|m(s(cr|tpos)|ho|nplus|c(y|omma)|i(nus(d(u)?|b)?|cro|d(cir|dot|ast)?)|o(dels|pf)|dash|u((?:lti|)map)?|p|easuredangle|DDot|fr|l(cp|dr)|a(cr|p(sto(down|up|left)?)?|l(t(ese)?|e)|rker)))|(n(s(hort(parallel|mid)|c(cue|[er])?|im(e(q)?)?|u(cc(eq)?|p(set(eq(q)?)?|[Ee])?|b(set(eq(q)?)?|[Ee])?)|par|qsu([bp]e)|mid)|Rightarrow|h(par|arr|Arr)|G(t(v)?|g)|c(y|ong(dot)?|up|edil|a(p|ron))|t(ilde|lg|riangle(left(eq)?|right(eq)?)|gl)|i(s(d)?|v)?|o(t(ni(v([abc]))?|in(dot|v([abc])|E)?)?|pf)|dash|u(m(sp|ero)?)?|jcy|p(olint|ar(sl|t|allel)?|r(cue|e(c(eq)?)?)?)|e(s(im|ear)|dot|quiv|ar(hk|r(ow)?)|xist(s)?|Arr)?|v(sim|infin|Harr|dash|Dash|l(t(rie)?|e|Arr)|ap|r(trie|Arr)|g([et]))|fr|w(near|ar(hk|r(ow)?)|Arr)|V([Dd]ash)|l(sim|t(ri(e)?)?|dr|e(s(s)?|q(slant|q)?|ft((?:|right)arrow))?|E|arr|Arr)|a(ng|cute|tur(al(s)?)?|p(id|os|prox|E)?|bla)|r(tri(e)?|ightarrow|arr([cw])?|Arr)|g(sim|t(r)?|e(s|q(slant|q)?)?|E)|mid|L(t(v)?|eft((?:|right)arrow)|l)|b(sp|ump(e)?))|N(scr|c(y|edil|aron)|tilde|o(nBreakingSpace|Break|t(R(ightTriangle(Bar|Equal)?|everseElement)|Greater(Greater|SlantEqual|Tilde|Equal|FullEqual|Less)?|S(u(cceeds(SlantEqual|Tilde|Equal)?|perset(Equal)?|bset(Equal)?)|quareSu(perset(Equal)?|bset(Equal)?))|Hump(DownHump|Equal)|Nested(GreaterGreater|LessLess)|C(ongruent|upCap)|Tilde(Tilde|Equal|FullEqual)?|DoubleVerticalBar|Precedes((?:Slant|)Equal)?|E(qual(Tilde)?|lement|xists)|VerticalBar|Le(ss(Greater|SlantEqual|Tilde|Equal|Less)?|ftTriangle(Bar|Equal)?))?|pf)|u|e(sted(GreaterGreater|LessLess)|wLine|gative(MediumSpace|Thi((?:n|ck)Space)|VeryThinSpace))|Jcy|fr|acute))|(o(s(cr|ol|lash)|h(m|bar)|c(y|ir(c)?)|ti(lde|mes(as)?)|S|int|opf|d(sold|iv|ot|ash|blac)|uml|p(erp|lus|ar)|elig|vbar|f(cir|r)|l(c(ir|ross)|t|ine|arr)|a(st|cute)|r(slope|igof|or|d(er(of)?|[fm])?|v|arr)?|g(t|on|rave)|m(i(nus|cron|d)|ega|acr))|O(s(cr|lash)|c(y|irc)|ti(lde|mes)|opf|dblac|uml|penCurly((?:Double|)Quote)|ver(B(ar|rac(e|ket))|Parenthesis)|fr|Elig|acute|r|grave|m(icron|ega|acr)))|(p(s(cr|i)|h(i(v)?|one|mmat)|cy|i(tchfork|v)?|o(intint|und|pf)|uncsp|er(cnt|tenk|iod|p|mil)|fr|l(us(sim|cir|two|d([ou])|e|acir|mn|b)?|an(ck(h)?|kv))|ar(s(im|l)|t|a(llel)?)?|r(sim|n(sim|E|ap)|cue|ime(s)?|o(d|p(to)?|f(surf|line|alar))|urel|e(c(sim|n(sim|eqq|approx)|curlyeq|eq|approx)?)?|E|ap)?|m)|P(s(cr|i)|hi|cy|i|o(incareplane|pf)|fr|lusMinus|artialD|r(ime|o(duct|portion(al)?)|ecedes(SlantEqual|Tilde|Equal)?)?))|(q(scr|int|opf|u(ot|est(eq)?|at(int|ernions))|prime|fr)|Q(scr|opf|UOT|fr))|(R(s(h|cr)|ho|c(y|edil|aron)|Barr|ight(Ceiling|T(ee(Vector|Arrow)?|riangle(Bar|Equal)?)|Do(ubleBracket|wn(TeeVector|Vector(Bar)?))|Up(TeeVector|DownVector|Vector(Bar)?)|Vector(Bar)?|arrow|Floor|A(ngleBracket|rrow(Bar|LeftArrow)?))|o(undImplies|pf)|uleDelayed|e(verse(UpEquilibrium|E(quilibrium|lement)))?|fr|EG|a(ng|cute|rr(tl)?)|rightarrow)|r(s(h|cr|q(uo(r)?|b)|aquo)|h(o(v)?|ar(d|u(l)?))|nmid|c(y|ub|e(d??il)|aron)|Barr|t(hree|imes|ri([ef]|ltri)?)|i(singdotseq|ng|ght(squigarrow|harpoon(down|up)|threetimes|left(harpoons|arrows)|arrow(tail)?|rightarrows))|Har|o(times|p(f|lus|ar)|a(ng|rr)|brk)|d(sh|ca|quo(r)?|ldhar)|uluhar|p(polint|ar(gt)?)|e(ct|al(s|ine|part)?|g)|f(isht|loor|r)|l(har|arr|m)|a(ng([de]|le)?|c(ute|e)|t(io(nals)?|ail)|dic|emptyv|quo|rr(sim|hk|c|tl|pl|fs|w|lp|ap|b(fs)?)?)|rarr|x|moust(ache)?|b(arr|r(k(sl([du])|e)|ac([ek]))|brk)|A(tail|arr|rr)))|(s(s(cr|tarf|etmn|mile)|h(y|c(hcy|y)|ort(parallel|mid)|arp)|c(sim|y|n(sim|E|ap)|cue|irc|polint|e(dil)?|E|a(p|ron))?|t(ar(f)?|r(ns|aight(phi|epsilon)))|i(gma([fv])?|m(ne|dot|plus|e(q)?|l(E)?|rarr|g(E)?)?)|zlig|o(pf|ftcy|l(b(ar)?)?)|dot([be])?|u(ng|cc(sim|n(sim|eqq|approx)|curlyeq|eq|approx)?|p(s(im|u([bp])|et(neq(q)?|eq(q)?)?)|hs(ol|ub)|1|n([Ee])|2|d(sub|ot)|3|plus|e(dot)?|E|larr|mult)?|m|b(s(im|u([bp])|et(neq(q)?|eq(q)?)?)|n([Ee])|dot|plus|e(dot)?|E|rarr|mult)?)|pa(des(uit)?|r)|e(swar|ct|tm(n|inus)|ar(hk|r(ow)?)|xt|mi|Arr)|q(su(p(set(eq)?|e)?|b(set(eq)?|e)?)|c(up(s)?|ap(s)?)|u(f|ar([ef]))?)|fr(own)?|w(nwar|ar(hk|r(ow)?)|Arr)|larr|acute|rarr|m(t(e(s)?)?|i(d|le)|eparsl|a(shp|llsetminus))|bquo)|S(scr|hort((?:Right|Down|Up|Left)Arrow)|c(y|irc|edil|aron)?|tar|igma|H(cy|CHcy)|opf|u(c(hThat|ceeds(SlantEqual|Tilde|Equal)?)|p(set|erset(Equal)?)?|m|b(set(Equal)?)?)|OFTcy|q(uare(Su(perset(Equal)?|bset(Equal)?)|Intersection|Union)?|rt)|fr|acute|mallCircle))|(t(s(hcy|c([ry])|trok)|h(i(nsp|ck(sim|approx))|orn|e(ta(sym|v)?|re(4|fore))|k(sim|ap))|c(y|edil|aron)|i(nt|lde|mes(d|b(ar)?)?)|o(sa|p(cir|f(ork)?|bot)?|ea)|dot|prime|elrec|fr|w(ixt|ohead((?:lef|righ)tarrow))|a(u|rget)|r(i(sb|time|dot|plus|e|angle(down|q|left(eq)?|right(eq)?)?|minus)|pezium|ade)|brk)|T(s(cr|trok)|RADE|h(i((?:n|ck)Space)|e(ta|refore))|c(y|edil|aron)|S(H??cy)|ilde(Tilde|Equal|FullEqual)?|HORN|opf|fr|a([bu])|ripleDot))|(u(scr|h(ar([lr])|blk)|c(y|irc)|t(ilde|dot|ri(f)?)|Har|o(pf|gon)|d(har|arr|blac)|u(arr|ml)|p(si(h|lon)?|harpoon(left|right)|downarrow|uparrows|lus|arrow)|f(isht|r)|wangle|l(c(orn(er)?|rop)|tri)|a(cute|rr)|r(c(orn(er)?|rop)|tri|ing)|grave|m(l|acr)|br(cy|eve)|Arr)|U(scr|n(ion(Plus)?|der(B(ar|rac(e|ket))|Parenthesis))|c(y|irc)|tilde|o(pf|gon)|dblac|uml|p(si(lon)?|downarrow|Tee(Arrow)?|per((?:Righ|Lef)tArrow)|DownArrow|Equilibrium|arrow|Arrow(Bar|DownArrow)?)|fr|a(cute|rr(ocir)?)|ring|grave|macr|br(cy|eve)))|(v(s(cr|u(pn([Ee])|bn([Ee])))|nsu([bp])|cy|Bar(v)?|zigzag|opf|dash|prop|e(e(eq|bar)?|llip|r(t|bar))|Dash|fr|ltri|a(ngrt|r(s(igma|u(psetneq(q)?|bsetneq(q)?))|nothing|t(heta|riangle(left|right))|p(hi|i|ropto)|epsilon|kappa|r(ho)?))|rtri|Arr)|V(scr|cy|opf|dash(l)?|e(e|r(yThinSpace|t(ical(Bar|Separator|Tilde|Line))?|bar))|Dash|vdash|fr|bar))|(w(scr|circ|opf|p|e(ierp|d(ge(q)?|bar))|fr|r(eath)?)|W(scr|circ|opf|edge|fr))|(X(scr|i|opf|fr)|x(s(cr|qcup)|h([Aa]rr)|nis|c(irc|up|ap)|i|o(time|dot|p(f|lus))|dtri|u(tri|plus)|vee|fr|wedge|l([Aa]rr)|r([Aa]rr)|map))|(y(scr|c(y|irc)|icy|opf|u(cy|ml)|en|fr|ac(y|ute))|Y(scr|c(y|irc)|opf|uml|Icy|Ucy|fr|acute|Acy))|(z(scr|hcy|c(y|aron)|igrarr|opf|dot|e(ta|etrf)|fr|w(n?j)|acute)|Z(scr|c(y|aron)|Hcy|opf|dot|e(ta|roWidthSpace)|fr|acute)))(;)\",\"name\":\"constant.character.entity.named.$2.html\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.html\"},\"3\":{\"name\":\"punctuation.definition.entity.html\"}},\"match\":\"(&)#[0-9]+(;)\",\"name\":\"constant.character.entity.numeric.decimal.html\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.entity.html\"},\"3\":{\"name\":\"punctuation.definition.entity.html\"}},\"match\":\"(&)#[Xx]\\\\\\\\h+(;)\",\"name\":\"constant.character.entity.numeric.hexadecimal.html\"},{\"match\":\"&(?=[0-9A-Za-z]+;)\",\"name\":\"invalid.illegal.ambiguous-ampersand.html\"}]},\"math\":{\"patterns\":[{\"begin\":\"(?i)(<)(math)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.structure.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.structure.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.structure.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]}],\"repository\":{\"attribute\":{\"patterns\":[{\"begin\":\"(s(hift|ymmetric|cript(sizemultiplier|level|minsize)|t(ackalign|retchy)|ide|u([bp]scriptshift)|e(parator(s)?|lection)|rc)|h(eight|ref)|n(otation|umalign)|c(haralign|olumn(spa(n|cing)|width|lines|align)|lose|rossout)|i(n(dent(shift(first|last)?|target|align(first|last)?)|fixlinebreakstyle)|d)|o(pen|verflow)|d(i(splay(style)?|r)|e(nomalign|cimalpoint|pth))|position|e(dge|qual(columns|rows))|voffset|f(orm|ence|rame(spacing)?)|width|l(space|ine(thickness|leading|break(style|multchar)?)|o(ngdivstyle|cation)|ength|quote|argeop)|a(c(cent(under)?|tiontype)|l(t(text|img(-(height|valign|width))?)|ign(mentscope)?))|r(space|ow(spa(n|cing)|lines|align)|quote)|groupalign|x(link:href|mlns)|m(in(size|labelspacing)|ovablelimits|a(th(size|color|variant|background)|xsize))|bevelled)(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"begin\":\"([^\\\\\\\\x00- \\\\\"'/<=>\\\\\\\\x7F-\\\\\\\\x{9F}﷐-﷯￾￿🿾🿿𯿾𯿿𿿾𿿿\\\\\\\\x{4FFFE}\\\\\\\\x{4FFFF}\\\\\\\\x{5FFFE}\\\\\\\\x{5FFFF}\\\\\\\\x{6FFFE}\\\\\\\\x{6FFFF}\\\\\\\\x{7FFFE}\\\\\\\\x{7FFFF}\\\\\\\\x{8FFFE}\\\\\\\\x{8FFFF}\\\\\\\\x{9FFFE}\\\\\\\\x{9FFFF}\\\\\\\\x{AFFFE}\\\\\\\\x{AFFFF}\\\\\\\\x{BFFFE}\\\\\\\\x{BFFFF}\\\\\\\\x{CFFFE}\\\\\\\\x{CFFFF}\\\\\\\\x{DFFFE}\\\\\\\\x{DFFFF}\\\\\\\\x{EFFFE}\\\\\\\\x{EFFFF}\\\\\\\\x{FFFFE}\\\\\\\\x{FFFFF}\\\\\\\\x{10FFFE}\\\\\\\\x{10FFFF}]+)\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.unrecognized.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"match\":\"[^>\\\\\\\\s]+\",\"name\":\"invalid.illegal.character-not-allowed-here.html\"}]},\"tags\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#cdata\"},{\"captures\":{\"0\":{\"name\":\"meta.tag.structure.math.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(annotation|annotation-xml|semantics|menclose|merror|mfenced|mfrac|mpadded|mphantom|mroot|mrow|msqrt|mstyle|mmultiscripts|mover|mprescripts|msub|msubsup|msup|munder|munderover|none|mlabeledtr|mtable|mtd|mtr|mlongdiv|mscarries|mscarry|msgroup|msline|msrow|mstack|maction)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.structure.math.$2.html\"},{\"begin\":\"(?i)(<)(annotation|annotation-xml|semantics|menclose|merror|mfenced|mfrac|mpadded|mphantom|mroot|mrow|msqrt|mstyle|mmultiscripts|mover|mprescripts|msub|msubsup|msup|munder|munderover|none|mlabeledtr|mtable|mtd|mtr|mlongdiv|mscarries|mscarry|msgroup|msline|msrow|mstack|maction)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.structure.math.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.structure.math.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.structure.math.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.inline.math.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(m(?:[inos]|space|text|aligngroup|alignmark))(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.inline.math.$2.html\"},{\"begin\":\"(?i)(<)(m(?:[inos]|space|text|aligngroup|alignmark))(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.inline.math.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.inline.math.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.inline.math.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.object.math.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(mglyph)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.object.math.$2.html\"},{\"begin\":\"(?i)(<)(mglyph)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.object.math.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.object.math.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.object.math.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.other.invalid.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(([:\\\\\\\\w]+))(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.other.invalid.html\"},{\"begin\":\"(?i)(<)((\\\\\\\\w[^>\\\\\\\\s]*))(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.other.invalid.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)((\\\\\\\\2))\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.other.invalid.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.other.invalid.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.invalid.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"include\":\"#tags-invalid\"}]}}},\"svg\":{\"patterns\":[{\"begin\":\"(?i)(<)(svg)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.structure.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.structure.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.structure.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]}],\"repository\":{\"attribute\":{\"patterns\":[{\"begin\":\"(s(hape-rendering|ystemLanguage|cale|t(yle|itchTiles|op-(color|opacity)|dDeviation|em([hv])|artOffset|r(i(ng|kethrough-(thickness|position))|oke(-(opacity|dash(offset|array)|width|line(cap|join)|miterlimit))?))|urfaceScale|p(e(cular(Constant|Exponent)|ed)|acing|readMethod)|eed|lope)|h(oriz-(origin-x|adv-x)|eight|anging|ref(lang)?)|y([12]|ChannelSelector)?|n(umOctaves|ame)|c(y|o(ntentS((?:cript|tyle)Type)|lor(-(interpolation(-filters)?|profile|rendering))?)|ursor|l(ip(-(path|rule)|PathUnits)?|ass)|a(p-height|lcMode)|x)|t(ype|o|ext(-(decoration|anchor|rendering)|Length)|a(rget([XY])?|b(index|leValues))|ransform)|i(n(tercept|2)?|d(eographic)?|mage-rendering)|z(oomAndPan)?|o(p(erator|acity)|ver(flow|line-(thickness|position))|ffset|r(i(ent(ation)?|gin)|der))|d(y|i(splay|visor|ffuseConstant|rection)|ominant-baseline|ur|e(scent|celerate)|x)?|u(1|n(i(code(-(range|bidi))?|ts-per-em)|derline-(thickness|position))|2)|p(ing|oint(s(At([XYZ]))?|er-events)|a(nose-1|t(h(Length)?|tern(ContentUnits|Transform|Units))|int-order)|r(imitiveUnits|eserveA(spectRatio|lpha)))|e(n(d|able-background)|dgeMode|levation|x(ternalResourcesRequired|ponent))|v(i(sibility|ew(Box|Target))|-(hanging|ideographic|alphabetic|mathematical)|e(ctor-effect|r(sion|t-(origin-([xy])|adv-y)))|alues)|k([123]|e(y(Splines|Times|Points)|rn(ing|el(Matrix|UnitLength)))|4)?|f(y|il(ter(Res|Units)?|l(-(opacity|rule))?)|o(nt-(s(t(yle|retch)|ize(-adjust)?)|variant|family|weight)|rmat)|lood-(color|opacity)|r(om)?|x)|w(idth(s)?|ord-spacing|riting-mode)|l(i(ghting-color|mitingConeAngle)|ocal|e(ngthAdjust|tter-spacing)|ang)|a(scent|cc(umulate|ent-height)|ttribute(Name|Type)|zimuth|dditive|utoReverse|l(ignment-baseline|phabetic|lowReorder)|rabic-form|mplitude)|r(y|otate|e(s(tart|ult)|ndering-intent|peat(Count|Dur)|quired(Extensions|Features)|f([XY]|errerPolicy)|l)|adius|x)?|g([12]|lyph(Ref|-(name|orientation-(horizontal|vertical)))|radient(Transform|Units))|x([12]|ChannelSelector|-height|link:(show|href|t(ype|itle)|a(ctuate|rcrole)|role)|ml:(space|lang|base))?|m(in|ode|e(thod|dia)|a(sk((?:Content|)Units)?|thematical|rker(Height|-(start|end|mid)|Units|Width)|x))|b(y|ias|egin|ase(Profile|line-shift|Frequency)|box))(?![-:\\\\\\\\w])\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"begin\":\"([^\\\\\\\\x00- \\\\\"'/<=>\\\\\\\\x7F-\\\\\\\\x{9F}﷐-﷯￾￿🿾🿿𯿾𯿿𿿾𿿿\\\\\\\\x{4FFFE}\\\\\\\\x{4FFFF}\\\\\\\\x{5FFFE}\\\\\\\\x{5FFFF}\\\\\\\\x{6FFFE}\\\\\\\\x{6FFFF}\\\\\\\\x{7FFFE}\\\\\\\\x{7FFFF}\\\\\\\\x{8FFFE}\\\\\\\\x{8FFFF}\\\\\\\\x{9FFFE}\\\\\\\\x{9FFFF}\\\\\\\\x{AFFFE}\\\\\\\\x{AFFFF}\\\\\\\\x{BFFFE}\\\\\\\\x{BFFFF}\\\\\\\\x{CFFFE}\\\\\\\\x{CFFFF}\\\\\\\\x{DFFFE}\\\\\\\\x{DFFFF}\\\\\\\\x{EFFFE}\\\\\\\\x{EFFFF}\\\\\\\\x{FFFFE}\\\\\\\\x{FFFFF}\\\\\\\\x{10FFFE}\\\\\\\\x{10FFFF}]+)\",\"beginCaptures\":{\"0\":{\"name\":\"entity.other.attribute-name.html\"}},\"end\":\"(?=\\\\\\\\s*+[^=\\\\\\\\s])\",\"name\":\"meta.attribute.unrecognized.$1.html\",\"patterns\":[{\"include\":\"#attribute-interior\"}]},{\"match\":\"[^>\\\\\\\\s]+\",\"name\":\"invalid.illegal.character-not-allowed-here.html\"}]},\"tags\":{\"patterns\":[{\"include\":\"#comment\"},{\"include\":\"#cdata\"},{\"captures\":{\"0\":{\"name\":\"meta.tag.metadata.svg.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(color-profile|desc|metadata|script|style|title)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.metadata.svg.$2.html\"},{\"begin\":\"(?i)(<)(color-profile|desc|metadata|script|style|title)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.svg.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.svg.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.metadata.svg.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.structure.svg.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(animateMotion|clipPath|defs|feComponentTransfer|feDiffuseLighting|feMerge|feSpecularLighting|filter|g|hatch|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|pattern|radialGradient|switch|text|textPath)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.structure.svg.$2.html\"},{\"begin\":\"(?i)(<)(animateMotion|clipPath|defs|feComponentTransfer|feDiffuseLighting|feMerge|feSpecularLighting|filter|g|hatch|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|pattern|radialGradient|switch|text|textPath)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.structure.svg.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.structure.svg.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.structure.svg.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.inline.svg.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(a|animate|discard|feBlend|feColorMatrix|feComposite|feConvolveMatrix|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feMergeNode|feMorphology|feOffset|fePointLight|feSpotLight|feTile|feTurbulence|hatchPath|mpath|set|solidcolor|stop|tspan)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.inline.svg.$2.html\"},{\"begin\":\"(?i)(<)(a|animate|discard|feBlend|feColorMatrix|feComposite|feConvolveMatrix|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feMergeNode|feMorphology|feOffset|fePointLight|feSpotLight|feTile|feTurbulence|hatchPath|mpath|set|solidcolor|stop|tspan)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.inline.svg.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.inline.svg.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.inline.svg.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.object.svg.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(circle|ellipse|feImage|foreignObject|image|line|path|polygon|polyline|rect|symbol|use|view)(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.object.svg.$2.html\"},{\"begin\":\"(?i)(<)(a|circle|ellipse|feImage|foreignObject|image|line|path|polygon|polyline|rect|symbol|use|view)(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.object.svg.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)(\\\\\\\\2)\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.object.svg.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.object.svg.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.other.svg.$2.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)((altGlyph|altGlyphDef|altGlyphItem|animateColor|animateTransform|cursor|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|glyph|glyphRef|hkern|missing-glyph|tref|vkern))(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.other.svg.$2.html\"},{\"begin\":\"(?i)(<)((altGlyph|altGlyphDef|altGlyphItem|animateColor|animateTransform|cursor|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|glyph|glyphRef|hkern|missing-glyph|tref|vkern))(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.other.svg.$2.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)((\\\\\\\\2))\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.other.svg.$2.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.other.svg.$2.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"captures\":{\"0\":{\"name\":\"meta.tag.other.invalid.void.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"match\":\"(?i)(<)(([:\\\\\\\\w]+))(?=\\\\\\\\s|/?>)(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(/>)\",\"name\":\"meta.element.other.invalid.html\"},{\"begin\":\"(?i)(<)((\\\\\\\\w[^>\\\\\\\\s]*))(?=\\\\\\\\s|/?>)(?:(([^\\\\\"'>]|\\\\\"[^\\\\\"]*\\\\\"|'[^']*')*)(>))?\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.other.invalid.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(?i)(</)((\\\\\\\\2))\\\\\\\\s*(>)|(/>)|(?=</\\\\\\\\w+)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.other.invalid.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"},\"5\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.element.other.invalid.html\",\"patterns\":[{\"begin\":\"(?<!>)\\\\\\\\G\",\"end\":\"(?=/>)|>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.invalid.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#tags\"}]},{\"include\":\"#tags-invalid\"}]}}},\"tags-invalid\":{\"patterns\":[{\"begin\":\"(</?)((\\\\\\\\w[^>\\\\\\\\s]*))(?<!/)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.unrecognized-tag.html\"}},\"end\":\"((?: ?/)?>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.$2.html\",\"patterns\":[{\"include\":\"#attribute\"}]}]},\"tags-valid\":{\"patterns\":[{\"begin\":\"(^[\\\\\\\\t ]+)?(?=<(?i:style)\\\\\\\\b(?!-))\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.embedded.leading.html\"}},\"end\":\"(?!\\\\\\\\G)([\\\\\\\\t ]*$\\\\\\\\n?)?\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.embedded.trailing.html\"}},\"patterns\":[{\"begin\":\"(?i)(<)(style)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.style.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"(?i)((<)/)(style)\\\\\\\\s*(>)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.style.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"source.css-ignored-vscode\"},\"3\":{\"name\":\"entity.name.tag.html\"},\"4\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.embedded.block.html\",\"patterns\":[{\"begin\":\"\\\\\\\\G\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"(>)\",\"name\":\"meta.tag.metadata.style.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?!\\\\\\\\G)\",\"end\":\"(?=</(?i:style))\",\"name\":\"source.css\",\"patterns\":[{\"include\":\"source.css\"}]}]}]},{\"begin\":\"(^[\\\\\\\\t ]+)?(?=<(?i:script)\\\\\\\\b(?!-))\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.embedded.leading.html\"}},\"end\":\"(?!\\\\\\\\G)([\\\\\\\\t ]*$\\\\\\\\n?)?\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.embedded.trailing.html\"}},\"patterns\":[{\"begin\":\"(<)((?i:script))\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"(/)((?i:script))(>)\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.embedded.block.html\",\"patterns\":[{\"begin\":\"\\\\\\\\G\",\"end\":\"(?=/)\",\"patterns\":[{\"begin\":\"(>)\",\"beginCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.start.html\"},\"1\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"end\":\"((<))(?=/(?i:script))\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"source.js-ignored-vscode\"}},\"patterns\":[{\"begin\":\"\\\\\\\\G\",\"end\":\"(?=</(?i:script))\",\"name\":\"source.js\",\"patterns\":[{\"begin\":\"(^[\\\\\\\\t ]+)?(?=//)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.js\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"//\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"(?=<\\/script)|\\\\\\\\n\",\"name\":\"comment.line.double-slash.js\"}]},{\"begin\":\"/\\\\\\\\*\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.js\"}},\"end\":\"\\\\\\\\*/|(?=<\\/script)\",\"name\":\"comment.block.js\"},{\"include\":\"source.js\"}]}]},{\"begin\":\"\\\\\\\\G\",\"end\":\"(?i:(?=>|type(?=[=\\\\\\\\s])(?!\\\\\\\\s*=\\\\\\\\s*(''|\\\\\"\\\\\"|([\\\\\"']?)(text/(javascript(1\\\\\\\\.[0-5])?|x-javascript|jscript|livescript|(x-)?ecmascript|babel)|application/((?:(x-)?jav|(x-)?ecm)ascript)|module)[\\\\\"'>\\\\\\\\s]))))\",\"name\":\"meta.tag.metadata.script.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i:(?=type\\\\\\\\s*=\\\\\\\\s*([\\\\\"']?)text/(x-handlebars|(x-(handlebars-)?|ng-)?template|html)[\\\\\"'>\\\\\\\\s]))\",\"end\":\"((<))(?=/(?i:script))\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"text.html.basic\"}},\"patterns\":[{\"begin\":\"\\\\\\\\G\",\"end\":\"(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.script.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?!\\\\\\\\G)\",\"end\":\"(?=</(?i:script))\",\"name\":\"text.html.basic\",\"patterns\":[{\"include\":\"text.html.basic\"}]}]},{\"begin\":\"(?=(?i:type))\",\"end\":\"(<)(?=/(?i:script))\",\"endCaptures\":{\"0\":{\"name\":\"meta.tag.metadata.script.end.html\"},\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"}},\"patterns\":[{\"begin\":\"\\\\\\\\G\",\"end\":\"(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.script.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?!\\\\\\\\G)\",\"end\":\"(?=</(?i:script))\",\"name\":\"source.unknown\"}]}]}]}]},{\"begin\":\"(?i)(<)(base|link|meta)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(noscript|title)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)(noscript|title)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(col|hr|input)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(address|article|aside|blockquote|body|button|caption|colgroup|datalist|dd|details|dialog|div|dl|dt|fieldset|figcaption|figure|footer|form|head|header|hgroup|html|h[1-6]|label|legend|li|main|map|menu|meter|nav|ol|optgroup|option|output|p|pre|progress|section|select|slot|summary|table|tbody|td|template|textarea|tfoot|th|thead|tr|ul)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)(address|article|aside|blockquote|body|button|caption|colgroup|datalist|dd|details|dialog|div|dl|dt|fieldset|figcaption|figure|footer|form|head|header|hgroup|html|h[1-6]|label|legend|li|main|map|menu|meter|nav|ol|optgroup|option|output|p|pre|progress|section|select|slot|summary|table|tbody|td|template|textarea|tfoot|th|thead|tr|ul)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(area|br|wbr)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(a|abbr|b|bdi|bdo|cite|code|data|del|dfn|em|i|ins|kbd|mark|q|rp|rt|ruby|s|samp|small|span|strong|sub|sup|time|u|var)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)(a|abbr|b|bdi|bdo|cite|code|data|del|dfn|em|i|ins|kbd|mark|q|rp|rt|ruby|s|samp|small|span|strong|sub|sup|time|u|var)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(embed|img|param|source|track)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)(audio|canvas|iframe|object|picture|video)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)(audio|canvas|iframe|object|picture|video)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((basefont|isindex))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.metadata.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((center|frameset|noembed|noframes))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)((center|frameset|noembed|noframes))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.structure.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((acronym|big|blink|font|strike|tt|xmp))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)((acronym|big|blink|font|strike|tt|xmp))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.inline.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((frame))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.void.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((applet))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)((applet))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.deprecated.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.object.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(<)((dir|keygen|listing|menuitem|plaintext|spacer))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.no-longer-supported.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.$2.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(?i)(</)((dir|keygen|listing|menuitem|plaintext|spacer))(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"},\"3\":{\"name\":\"invalid.illegal.no-longer-supported.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.other.$2.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"include\":\"#math\"},{\"include\":\"#svg\"},{\"begin\":\"(<)([A-Za-z][.0-9A-Z_a-z·À-ÖØ-öø-ͽͿ-῿‌‍‿⁀⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-\\\\\\\\x{EFFFF}]*-[-.0-9A-Z_a-z·À-ÖØ-öø-ͽͿ-῿‌‍‿⁀⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-\\\\\\\\x{EFFFF}]*)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"/?>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.custom.start.html\",\"patterns\":[{\"include\":\"#attribute\"}]},{\"begin\":\"(</)([A-Za-z][.0-9A-Z_a-z·À-ÖØ-öø-ͽͿ-῿‌‍‿⁀⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-\\\\\\\\x{EFFFF}]*-[-.0-9A-Z_a-z·À-ÖØ-öø-ͽͿ-῿‌‍‿⁀⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-\\\\\\\\x{EFFFF}]*)(?=\\\\\\\\s|/?>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.begin.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.tag.end.html\"}},\"name\":\"meta.tag.custom.end.html\",\"patterns\":[{\"include\":\"#attribute\"}]}]},\"xml-processing\":{\"begin\":\"(<\\\\\\\\?)(xml)\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.html\"},\"2\":{\"name\":\"entity.name.tag.html\"}},\"end\":\"(\\\\\\\\?>)\",\"name\":\"meta.tag.metadata.processing.xml.html\",\"patterns\":[{\"include\":\"#attribute\"}]}},\"scopeName\":\"text.html.basic\",\"embeddedLangs\":[\"javascript\",\"css\"]}`)),k_=[...Ul,...Gl,x_],C_=Object.freeze(JSON.parse(`{\"displayName\":\"Java\",\"name\":\"java\",\"patterns\":[{\"begin\":\"\\\\\\\\b(package)\\\\\\\\b\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.package.java\"}},\"contentName\":\"storage.modifier.package.java\",\"end\":\"\\\\\\\\s*(;)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.terminator.java\"}},\"name\":\"meta.package.java\",\"patterns\":[{\"include\":\"#comments\"},{\"match\":\"(?<=\\\\\\\\.)\\\\\\\\s*\\\\\\\\.|\\\\\\\\.(?=\\\\\\\\s*;)\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"(?<!_)_(?=\\\\\\\\s*([.;]))|\\\\\\\\b\\\\\\\\d+|-+\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"[A-Z]+\",\"name\":\"invalid.deprecated.package_name_not_lowercase.java\"},{\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\\\\\b\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.java\"}]},{\"begin\":\"\\\\\\\\b(import)\\\\\\\\b\\\\\\\\s*\\\\\\\\b(static)?\\\\\\\\b\\\\\\\\s\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.import.java\"},\"2\":{\"name\":\"storage.modifier.java\"}},\"contentName\":\"storage.modifier.import.java\",\"end\":\"\\\\\\\\s*(;)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.terminator.java\"}},\"name\":\"meta.import.java\",\"patterns\":[{\"include\":\"#comments\"},{\"match\":\"(?<=\\\\\\\\.)\\\\\\\\s*\\\\\\\\.|\\\\\\\\.(?=\\\\\\\\s*;)\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"(?<!\\\\\\\\.)\\\\\\\\s*\\\\\\\\*\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"(?<!_)_(?=\\\\\\\\s*([.;]))|\\\\\\\\b\\\\\\\\d+|-+\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\\\\\b\",\"name\":\"invalid.illegal.character_not_allowed_here.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.java\"},{\"match\":\"\\\\\\\\*\",\"name\":\"variable.language.wildcard.java\"}]},{\"include\":\"#comments-javadoc\"},{\"include\":\"#code\"},{\"include\":\"#module\"}],\"repository\":{\"all-types\":{\"patterns\":[{\"include\":\"#primitive-arrays\"},{\"include\":\"#primitive-types\"},{\"include\":\"#object-types\"}]},\"annotations\":{\"patterns\":[{\"begin\":\"((@)\\\\\\\\s*([^(\\\\\\\\s]+))(\\\\\\\\()\",\"beginCaptures\":{\"2\":{\"name\":\"punctuation.definition.annotation.java\"},\"3\":{\"name\":\"storage.type.annotation.java\"},\"4\":{\"name\":\"punctuation.definition.annotation-arguments.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.annotation-arguments.end.bracket.round.java\"}},\"name\":\"meta.declaration.annotation.java\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"constant.other.key.java\"},\"2\":{\"name\":\"keyword.operator.assignment.java\"}},\"match\":\"(\\\\\\\\w*)\\\\\\\\s*(=)\"},{\"include\":\"#code\"}]},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.annotation.java\"},\"2\":{\"name\":\"storage.modifier.java\"},\"3\":{\"name\":\"storage.type.annotation.java\"},\"5\":{\"name\":\"punctuation.definition.annotation.java\"},\"6\":{\"name\":\"storage.type.annotation.java\"}},\"match\":\"(@)(interface)\\\\\\\\s+(\\\\\\\\w*)|((@)\\\\\\\\s*(\\\\\\\\w+))\",\"name\":\"meta.declaration.annotation.java\"}]},\"anonymous-block-and-instance-initializer\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.block.begin.bracket.curly.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.block.end.bracket.curly.java\"}},\"patterns\":[{\"include\":\"#code\"}]},\"anonymous-classes-and-new\":{\"begin\":\"\\\\\\\\bnew\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.new.java\"}},\"end\":\"(?=[])-.:;?}]|/(?![*/])|[!%\\\\\\\\&=^|])\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#function-call\"},{\"include\":\"#all-types\"},{\"begin\":\"(?<=\\\\\\\\))\",\"end\":\"(?=[])-.:;?}]|/(?![*/])|[!%\\\\\\\\&=^|])\",\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.inner-class.begin.bracket.curly.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.inner-class.end.bracket.curly.java\"}},\"name\":\"meta.inner-class.java\",\"patterns\":[{\"include\":\"#class-body\"}]}]},{\"begin\":\"(?<=])\",\"end\":\"(?=[])-.:;?}]|/(?![*/])|[!%\\\\\\\\&=^|])\",\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.array-initializer.begin.bracket.curly.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.array-initializer.end.bracket.curly.java\"}},\"name\":\"meta.array-initializer.java\",\"patterns\":[{\"include\":\"#code\"}]}]},{\"include\":\"#parens\"}]},\"assertions\":{\"patterns\":[{\"begin\":\"\\\\\\\\b(assert)\\\\\\\\s\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.assert.java\"}},\"end\":\"$\",\"name\":\"meta.declaration.assertion.java\",\"patterns\":[{\"match\":\":\",\"name\":\"keyword.operator.assert.expression-separator.java\"},{\"include\":\"#code\"}]}]},\"class\":{\"begin\":\"(?=\\\\\\\\w?[-\\\\\\\\w\\\\\\\\s]*\\\\\\\\b(?:class|(?<!@)interface|enum)\\\\\\\\s+[$\\\\\\\\w]+)\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.class.end.bracket.curly.java\"}},\"name\":\"meta.class.java\",\"patterns\":[{\"include\":\"#storage-modifiers\"},{\"include\":\"#generics\"},{\"include\":\"#comments\"},{\"captures\":{\"1\":{\"name\":\"storage.modifier.java\"},\"2\":{\"name\":\"entity.name.type.class.java\"}},\"match\":\"(class|(?<!@)interface|enum)\\\\\\\\s+([$\\\\\\\\w]+)\",\"name\":\"meta.class.identifier.java\"},{\"begin\":\"extends\",\"beginCaptures\":{\"0\":{\"name\":\"storage.modifier.extends.java\"}},\"end\":\"(?=\\\\\\\\{|implements|permits)\",\"name\":\"meta.definition.class.inherited.classes.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"begin\":\"(implements)\\\\\\\\s\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.implements.java\"}},\"end\":\"(?=\\\\\\\\s*extends|permits|\\\\\\\\{)\",\"name\":\"meta.definition.class.implemented.interfaces.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"begin\":\"(permits)\\\\\\\\s\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.permits.java\"}},\"end\":\"(?=\\\\\\\\s*extends|implements|\\\\\\\\{)\",\"name\":\"meta.definition.class.permits.classes.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.class.begin.bracket.curly.java\"}},\"contentName\":\"meta.class.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#class-body\"}]}]},\"class-body\":{\"patterns\":[{\"include\":\"#comments-javadoc\"},{\"include\":\"#comments\"},{\"include\":\"#enums\"},{\"include\":\"#class\"},{\"include\":\"#generics\"},{\"include\":\"#static-initializer\"},{\"include\":\"#class-fields-and-methods\"},{\"include\":\"#annotations\"},{\"include\":\"#storage-modifiers\"},{\"include\":\"#member-variables\"},{\"include\":\"#code\"}]},\"class-fields-and-methods\":{\"patterns\":[{\"begin\":\"(?==)\",\"end\":\"(?=;)\",\"patterns\":[{\"include\":\"#code\"}]},{\"include\":\"#methods\"}]},\"code\":{\"patterns\":[{\"include\":\"#annotations\"},{\"include\":\"#comments\"},{\"include\":\"#enums\"},{\"include\":\"#class\"},{\"include\":\"#record\"},{\"include\":\"#anonymous-block-and-instance-initializer\"},{\"include\":\"#try-catch-finally\"},{\"include\":\"#assertions\"},{\"include\":\"#parens\"},{\"include\":\"#constants-and-special-vars\"},{\"include\":\"#numbers\"},{\"include\":\"#anonymous-classes-and-new\"},{\"include\":\"#lambda-expression\"},{\"include\":\"#keywords\"},{\"include\":\"#storage-modifiers\"},{\"include\":\"#method-call\"},{\"include\":\"#function-call\"},{\"include\":\"#variables\"},{\"include\":\"#variables-local\"},{\"include\":\"#objects\"},{\"include\":\"#properties\"},{\"include\":\"#strings\"},{\"include\":\"#all-types\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.period.java\"},{\"match\":\";\",\"name\":\"punctuation.terminator.java\"}]},\"comments\":{\"patterns\":[{\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.java\"}},\"match\":\"/\\\\\\\\*\\\\\\\\*/\",\"name\":\"comment.block.empty.java\"},{\"include\":\"#comments-inline\"}]},\"comments-inline\":{\"patterns\":[{\"begin\":\"/\\\\\\\\*\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.java\"}},\"end\":\"\\\\\\\\*/\",\"name\":\"comment.block.java\"},{\"begin\":\"(^[\\\\\\\\t ]+)?(?=//)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.java\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"//\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.java\"}},\"end\":\"\\\\\\\\n\",\"name\":\"comment.line.double-slash.java\"}]}]},\"comments-javadoc\":{\"patterns\":[{\"begin\":\"^\\\\\\\\s*(/\\\\\\\\*\\\\\\\\*)(?!/)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.comment.java\"}},\"end\":\"\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.java\"}},\"name\":\"comment.block.javadoc.java\",\"patterns\":[{\"match\":\"@(author|deprecated|return|see|serial|since|version)\\\\\\\\b\",\"name\":\"keyword.other.documentation.javadoc.java\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.documentation.javadoc.java\"},\"2\":{\"name\":\"variable.parameter.java\"}},\"match\":\"(@param)\\\\\\\\s+(\\\\\\\\S+)\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.documentation.javadoc.java\"},\"2\":{\"name\":\"entity.name.type.class.java\"}},\"match\":\"(@(?:exception|throws))\\\\\\\\s+(\\\\\\\\S+)\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.documentation.javadoc.java\"},\"2\":{\"name\":\"entity.name.type.class.java\"},\"3\":{\"name\":\"variable.parameter.java\"}},\"match\":\"\\\\\\\\{(@link)\\\\\\\\s+(\\\\\\\\S+)?#([$\\\\\\\\w]+\\\\\\\\s*\\\\\\\\([^()]*\\\\\\\\)).*?}\"}]}]},\"constants-and-special-vars\":{\"patterns\":[{\"match\":\"\\\\\\\\b(true|false|null)\\\\\\\\b\",\"name\":\"constant.language.java\"},{\"match\":\"\\\\\\\\bthis\\\\\\\\b\",\"name\":\"variable.language.this.java\"},{\"match\":\"\\\\\\\\bsuper\\\\\\\\b\",\"name\":\"variable.language.java\"}]},\"enums\":{\"begin\":\"^\\\\\\\\s*([\\\\\\\\w\\\\\\\\s]*)(enum)\\\\\\\\s+(\\\\\\\\w+)\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"include\":\"#storage-modifiers\"}]},\"2\":{\"name\":\"storage.modifier.java\"},\"3\":{\"name\":\"entity.name.type.enum.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.enum.end.bracket.curly.java\"}},\"name\":\"meta.enum.java\",\"patterns\":[{\"begin\":\"\\\\\\\\b(extends)\\\\\\\\b\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.extends.java\"}},\"end\":\"(?=\\\\\\\\{|\\\\\\\\bimplements\\\\\\\\b)\",\"name\":\"meta.definition.class.inherited.classes.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"begin\":\"\\\\\\\\b(implements)\\\\\\\\b\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.implements.java\"}},\"end\":\"(?=\\\\\\\\{|\\\\\\\\bextends\\\\\\\\b)\",\"name\":\"meta.definition.class.implemented.interfaces.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.enum.begin.bracket.curly.java\"}},\"end\":\"(?=})\",\"patterns\":[{\"begin\":\"(?<=\\\\\\\\{)\",\"end\":\"(?=[;}])\",\"patterns\":[{\"include\":\"#comments-javadoc\"},{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\b(\\\\\\\\w+)\\\\\\\\b\",\"beginCaptures\":{\"1\":{\"name\":\"constant.other.enum.java\"}},\"end\":\"(,)|(?=[;}])\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.separator.delimiter.java\"}},\"patterns\":[{\"include\":\"#comments-javadoc\"},{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.round.java\"}},\"patterns\":[{\"include\":\"#code\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.curly.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.curly.java\"}},\"patterns\":[{\"include\":\"#class-body\"}]}]}]},{\"include\":\"#class-body\"}]}]},\"function-call\":{\"begin\":\"([$A-Z_a-z][$\\\\\\\\w]*)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.java\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.java\"}},\"name\":\"meta.function-call.java\",\"patterns\":[{\"include\":\"#code\"}]},\"generics\":{\"begin\":\"<\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.angle.java\"}},\"end\":\">\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.angle.java\"}},\"patterns\":[{\"match\":\"\\\\\\\\b(extends|super)\\\\\\\\b\",\"name\":\"storage.modifier.$1.java\"},{\"captures\":{\"1\":{\"name\":\"storage.type.java\"}},\"match\":\"(?<!\\\\\\\\.)([$A-Z_a-z][$0-9A-Z_a-z]*)(?=\\\\\\\\s*<)\"},{\"include\":\"#primitive-arrays\"},{\"match\":\"[$A-Z_a-z][$0-9A-Z_a-z]*\",\"name\":\"storage.type.generic.java\"},{\"match\":\"\\\\\\\\?\",\"name\":\"storage.type.generic.wildcard.java\"},{\"match\":\"&\",\"name\":\"punctuation.separator.types.java\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.period.java\"},{\"include\":\"#parens\"},{\"include\":\"#generics\"},{\"include\":\"#comments\"}]},\"keywords\":{\"patterns\":[{\"match\":\"\\\\\\\\bthrow\\\\\\\\b\",\"name\":\"keyword.control.throw.java\"},{\"match\":\"[:?]\",\"name\":\"keyword.control.ternary.java\"},{\"match\":\"\\\\\\\\b(return|yield|break|case|continue|default|do|while|for|switch|if|else)\\\\\\\\b\",\"name\":\"keyword.control.java\"},{\"match\":\"\\\\\\\\b(instanceof)\\\\\\\\b\",\"name\":\"keyword.operator.instanceof.java\"},{\"match\":\"(<<|>>>?|[\\\\\\\\^~])\",\"name\":\"keyword.operator.bitwise.java\"},{\"match\":\"(([\\\\\\\\&^|]|<<|>>>?)=)\",\"name\":\"keyword.operator.assignment.bitwise.java\"},{\"match\":\"(===?|!=|<=|>=|<>|[<>])\",\"name\":\"keyword.operator.comparison.java\"},{\"match\":\"([-%*+/]=)\",\"name\":\"keyword.operator.assignment.arithmetic.java\"},{\"match\":\"(=)\",\"name\":\"keyword.operator.assignment.java\"},{\"match\":\"(--|\\\\\\\\+\\\\\\\\+)\",\"name\":\"keyword.operator.increment-decrement.java\"},{\"match\":\"([-%*+/])\",\"name\":\"keyword.operator.arithmetic.java\"},{\"match\":\"(!|&&|\\\\\\\\|\\\\\\\\|)\",\"name\":\"keyword.operator.logical.java\"},{\"match\":\"([\\\\\\\\&|])\",\"name\":\"keyword.operator.bitwise.java\"},{\"match\":\"\\\\\\\\b(const|goto)\\\\\\\\b\",\"name\":\"keyword.reserved.java\"}]},\"lambda-expression\":{\"patterns\":[{\"match\":\"->\",\"name\":\"storage.type.function.arrow.java\"}]},\"member-variables\":{\"begin\":\"(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)\",\"end\":\"(?=[;=])\",\"patterns\":[{\"include\":\"#storage-modifiers\"},{\"include\":\"#variables\"},{\"include\":\"#primitive-arrays\"},{\"include\":\"#object-types\"}]},\"method-call\":{\"begin\":\"(\\\\\\\\.)\\\\\\\\s*([$A-Z_a-z][$\\\\\\\\w]*)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"},\"2\":{\"name\":\"entity.name.function.java\"},\"3\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.java\"}},\"name\":\"meta.method-call.java\",\"patterns\":[{\"include\":\"#code\"}]},\"methods\":{\"begin\":\"(?!new)(?=[<\\\\\\\\w].*\\\\\\\\s+)(?=([^/=]|/(?!/))+\\\\\\\\()\",\"end\":\"(})|(?=;)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.section.method.end.bracket.curly.java\"}},\"name\":\"meta.method.java\",\"patterns\":[{\"include\":\"#storage-modifiers\"},{\"begin\":\"(\\\\\\\\w+)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.java\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.java\"}},\"name\":\"meta.method.identifier.java\",\"patterns\":[{\"include\":\"#parameters\"},{\"include\":\"#parens\"},{\"include\":\"#comments\"}]},{\"include\":\"#generics\"},{\"begin\":\"(?=\\\\\\\\w.*\\\\\\\\s+\\\\\\\\w+\\\\\\\\s*\\\\\\\\()\",\"end\":\"(?=\\\\\\\\s+\\\\\\\\w+\\\\\\\\s*\\\\\\\\()\",\"name\":\"meta.method.return-type.java\",\"patterns\":[{\"include\":\"#all-types\"},{\"include\":\"#parens\"},{\"include\":\"#comments\"}]},{\"include\":\"#throws\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.method.begin.bracket.curly.java\"}},\"contentName\":\"meta.method.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#code\"}]},{\"include\":\"#comments\"}]},\"module\":{\"begin\":\"((open)\\\\\\\\s)?(module)\\\\\\\\s+(\\\\\\\\w+)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.java\"},\"3\":{\"name\":\"storage.modifier.java\"},\"4\":{\"name\":\"entity.name.type.module.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.module.end.bracket.curly.java\"}},\"name\":\"meta.module.java\",\"patterns\":[{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.module.begin.bracket.curly.java\"}},\"contentName\":\"meta.module.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#comments-javadoc\"},{\"match\":\"\\\\\\\\b(requires|transitive|exports|opens|to|uses|provides|with)\\\\\\\\b\",\"name\":\"keyword.module.java\"}]}]},\"numbers\":{\"patterns\":[{\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0([Xx])((?<!\\\\\\\\.)\\\\\\\\h([_\\\\\\\\h]*\\\\\\\\h)?[Ll]?(?!\\\\\\\\.)|(\\\\\\\\h([_\\\\\\\\h]*\\\\\\\\h)?\\\\\\\\.?|(\\\\\\\\h([_\\\\\\\\h]*\\\\\\\\h)?)?\\\\\\\\.\\\\\\\\h([_\\\\\\\\h]*\\\\\\\\h)?)[Pp][-+]?[0-9]([0-9_]*[0-9])?[DFdf]?)\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.hex.java\"},{\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0([Bb])[01]([01_]*[01])?[Ll]?\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.binary.java\"},{\"match\":\"\\\\\\\\b(?<!\\\\\\\\$)0[0-7]([0-7_]*[0-7])?[Ll]?\\\\\\\\b(?!\\\\\\\\$)\",\"name\":\"constant.numeric.octal.java\"},{\"match\":\"(?<!\\\\\\\\$)(\\\\\\\\b[0-9]([0-9_]*[0-9])?\\\\\\\\.\\\\\\\\B(?!\\\\\\\\.)|\\\\\\\\b[0-9]([0-9_]*[0-9])?\\\\\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\\\\\b|\\\\\\\\b[0-9]([0-9_]*[0-9])?\\\\\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\\\\\b|\\\\\\\\b[0-9]([0-9_]*[0-9])?\\\\\\\\.([0-9]([0-9_]*[0-9])?)([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\\\\\b|(?<!\\\\\\\\.)\\\\\\\\B\\\\\\\\.[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\\\\\b|\\\\\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\\\\\b|\\\\\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\\\\\b|\\\\\\\\b(0|[1-9]([0-9_]*[0-9])?)(?!\\\\\\\\.)[Ll]?\\\\\\\\b)(?!\\\\\\\\$)\",\"name\":\"constant.numeric.decimal.java\"}]},\"object-types\":{\"patterns\":[{\"include\":\"#generics\"},{\"begin\":\"\\\\\\\\b((?:[A-Z_a-z]\\\\\\\\w*\\\\\\\\s*\\\\\\\\.\\\\\\\\s*)*)([A-Z_]\\\\\\\\w*)\\\\\\\\s*(?=\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"match\":\"[A-Z_a-z]\\\\\\\\w*\",\"name\":\"storage.type.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.period.java\"}]},\"2\":{\"name\":\"storage.type.object.array.java\"}},\"end\":\"(?!\\\\\\\\s*\\\\\\\\[)\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#parens\"}]},{\"captures\":{\"1\":{\"patterns\":[{\"match\":\"[A-Z_a-z]\\\\\\\\w*\",\"name\":\"storage.type.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.period.java\"}]}},\"match\":\"\\\\\\\\b((?:[A-Z_a-z]\\\\\\\\w*\\\\\\\\s*\\\\\\\\.\\\\\\\\s*)*[A-Z_]\\\\\\\\w*)\\\\\\\\s*(?=<)\"},{\"captures\":{\"1\":{\"patterns\":[{\"match\":\"[A-Z_a-z]\\\\\\\\w*\",\"name\":\"storage.type.java\"},{\"match\":\"\\\\\\\\.\",\"name\":\"punctuation.separator.period.java\"}]}},\"match\":\"\\\\\\\\b((?:[A-Z_a-z]\\\\\\\\w*\\\\\\\\s*\\\\\\\\.\\\\\\\\s*)*[A-Z_]\\\\\\\\w*)\\\\\\\\b((?=\\\\\\\\s*[\\\\\\\\n$A-Z_a-z])|(?=\\\\\\\\s*\\\\\\\\.\\\\\\\\.\\\\\\\\.))\"}]},\"object-types-inherited\":{\"patterns\":[{\"include\":\"#generics\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"}},\"match\":\"\\\\\\\\b(?:[A-Z]\\\\\\\\w*\\\\\\\\s*(\\\\\\\\.)\\\\\\\\s*)*[A-Z]\\\\\\\\w*\\\\\\\\b\",\"name\":\"entity.other.inherited-class.java\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.java\"}]},\"objects\":{\"match\":\"(?<![$\\\\\\\\w])[$A-Z_a-z][$\\\\\\\\w]*(?=\\\\\\\\s*\\\\\\\\.\\\\\\\\s*[$\\\\\\\\w]+)\",\"name\":\"variable.other.object.java\"},\"parameters\":{\"patterns\":[{\"match\":\"\\\\\\\\bfinal\\\\\\\\b\",\"name\":\"storage.modifier.java\"},{\"include\":\"#annotations\"},{\"include\":\"#all-types\"},{\"include\":\"#strings\"},{\"match\":\"\\\\\\\\w+\",\"name\":\"variable.parameter.java\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.java\"},{\"match\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"name\":\"punctuation.definition.parameters.varargs.java\"}]},\"parens\":{\"patterns\":[{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.round.java\"}},\"patterns\":[{\"include\":\"#code\"}]},{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.square.java\"}},\"end\":\"]\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.square.java\"}},\"patterns\":[{\"include\":\"#code\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.bracket.curly.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.bracket.curly.java\"}},\"patterns\":[{\"include\":\"#code\"}]}]},\"primitive-arrays\":{\"patterns\":[{\"begin\":\"\\\\\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\\\\\b\\\\\\\\s*(?=\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.primitive.array.java\"}},\"end\":\"(?!\\\\\\\\s*\\\\\\\\[)\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#parens\"}]}]},\"primitive-types\":{\"match\":\"\\\\\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\\\\\b\",\"name\":\"storage.type.primitive.java\"},\"properties\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"},\"2\":{\"name\":\"keyword.control.new.java\"}},\"match\":\"(\\\\\\\\.)\\\\\\\\s*(new)\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"},\"2\":{\"name\":\"variable.other.object.property.java\"}},\"match\":\"(\\\\\\\\.)\\\\\\\\s*([$A-Z_a-z][$\\\\\\\\w]*)(?=\\\\\\\\s*\\\\\\\\.\\\\\\\\s*[$A-Z_a-z][$\\\\\\\\w]*)\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"},\"2\":{\"name\":\"variable.other.object.property.java\"}},\"match\":\"(\\\\\\\\.)\\\\\\\\s*([$A-Z_a-z][$\\\\\\\\w]*)\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.period.java\"},\"2\":{\"name\":\"invalid.illegal.identifier.java\"}},\"match\":\"(\\\\\\\\.)\\\\\\\\s*([0-9][$\\\\\\\\w]*)\"}]},\"record\":{\"begin\":\"(?=\\\\\\\\w?[\\\\\\\\w\\\\\\\\s]*\\\\\\\\brecord\\\\\\\\s+[$\\\\\\\\w]+)\",\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.class.end.bracket.curly.java\"}},\"name\":\"meta.record.java\",\"patterns\":[{\"include\":\"#storage-modifiers\"},{\"include\":\"#generics\"},{\"include\":\"#comments\"},{\"begin\":\"(record)\\\\\\\\s+([$\\\\\\\\w]+)(<[$\\\\\\\\w]+>)?(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.java\"},\"2\":{\"name\":\"entity.name.type.record.java\"},\"3\":{\"patterns\":[{\"include\":\"#generics\"}]},\"4\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.java\"}},\"name\":\"meta.record.identifier.java\",\"patterns\":[{\"include\":\"#code\"}]},{\"begin\":\"(implements)\\\\\\\\s\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.implements.java\"}},\"end\":\"(?=\\\\\\\\s*\\\\\\\\{)\",\"name\":\"meta.definition.class.implemented.interfaces.java\",\"patterns\":[{\"include\":\"#object-types-inherited\"},{\"include\":\"#comments\"}]},{\"include\":\"#record-body\"}]},\"record-body\":{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.class.begin.bracket.curly.java\"}},\"end\":\"(?=})\",\"name\":\"meta.record.body.java\",\"patterns\":[{\"include\":\"#record-constructor\"},{\"include\":\"#class-body\"}]},\"record-constructor\":{\"begin\":\"(?!new)(?=[<\\\\\\\\w].*\\\\\\\\s+)(?=([^(/=]|/(?!/))+(?=\\\\\\\\{))\",\"end\":\"(})|(?=;)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.section.method.end.bracket.curly.java\"}},\"name\":\"meta.method.java\",\"patterns\":[{\"include\":\"#storage-modifiers\"},{\"begin\":\"(\\\\\\\\w+)\",\"beginCaptures\":{\"1\":{\"name\":\"entity.name.function.java\"}},\"end\":\"(?=\\\\\\\\s*\\\\\\\\{)\",\"name\":\"meta.method.identifier.java\",\"patterns\":[{\"include\":\"#comments\"}]},{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.method.begin.bracket.curly.java\"}},\"contentName\":\"meta.method.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#code\"}]}]},\"static-initializer\":{\"patterns\":[{\"include\":\"#anonymous-block-and-instance-initializer\"},{\"match\":\"static\",\"name\":\"storage.modifier.java\"}]},\"storage-modifiers\":{\"match\":\"\\\\\\\\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient|volatile|default|strictfp|sealed|non-sealed)\\\\\\\\b\",\"name\":\"storage.modifier.java\"},\"strings\":{\"patterns\":[{\"begin\":\"\\\\\"\\\\\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.java\"}},\"end\":\"\\\\\"\\\\\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.java\"}},\"name\":\"string.quoted.triple.java\",\"patterns\":[{\"match\":\"(\\\\\\\\\\\\\\\\\\\\\"\\\\\"\\\\\")(?!\\\\\")|(\\\\\\\\\\\\\\\\.)\",\"name\":\"constant.character.escape.java\"}]},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.java\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.java\"}},\"name\":\"string.quoted.double.java\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"constant.character.escape.java\"}]},{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.java\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.java\"}},\"name\":\"string.quoted.single.java\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"constant.character.escape.java\"}]}]},\"throws\":{\"begin\":\"throws\",\"beginCaptures\":{\"0\":{\"name\":\"storage.modifier.java\"}},\"end\":\"(?=[;{])\",\"name\":\"meta.throwables.java\",\"patterns\":[{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.java\"},{\"match\":\"[$A-Z_a-z][$.0-9A-Z_a-z]*\",\"name\":\"storage.type.java\"},{\"include\":\"#comments\"}]},\"try-catch-finally\":{\"patterns\":[{\"begin\":\"\\\\\\\\btry\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.try.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.try.end.bracket.curly.java\"}},\"name\":\"meta.try.java\",\"patterns\":[{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.try.resources.begin.bracket.round.java\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.try.resources.end.bracket.round.java\"}},\"name\":\"meta.try.resources.java\",\"patterns\":[{\"include\":\"#code\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.try.begin.bracket.curly.java\"}},\"contentName\":\"meta.try.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#code\"}]}]},{\"begin\":\"\\\\\\\\b(catch)\\\\\\\\b\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.catch.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.catch.end.bracket.curly.java\"}},\"name\":\"meta.catch.java\",\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.java\"}},\"contentName\":\"meta.catch.parameters.java\",\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.java\"}},\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#storage-modifiers\"},{\"begin\":\"[$A-Z_a-z][$.0-9A-Z_a-z]*\",\"beginCaptures\":{\"0\":{\"name\":\"storage.type.java\"}},\"end\":\"(\\\\\\\\|)|(?=\\\\\\\\))\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.catch.separator.java\"}},\"patterns\":[{\"include\":\"#comments\"},{\"captures\":{\"0\":{\"name\":\"variable.parameter.java\"}},\"match\":\"\\\\\\\\w+\"}]}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.catch.begin.bracket.curly.java\"}},\"contentName\":\"meta.catch.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#code\"}]}]},{\"begin\":\"\\\\\\\\bfinally\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.finally.java\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.finally.end.bracket.curly.java\"}},\"name\":\"meta.finally.java\",\"patterns\":[{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.finally.begin.bracket.curly.java\"}},\"contentName\":\"meta.finally.body.java\",\"end\":\"(?=})\",\"patterns\":[{\"include\":\"#code\"}]}]}]},\"variables\":{\"begin\":\"(?=\\\\\\\\b((void|boolean|byte|char|short|int|float|long|double)|(?>(\\\\\\\\w+\\\\\\\\.)*[A-Z_]+\\\\\\\\w*))\\\\\\\\b\\\\\\\\s*(<[],.<>?\\\\\\\\[\\\\\\\\w\\\\\\\\s]*>)?\\\\\\\\s*((\\\\\\\\[])*)?\\\\\\\\s+[$A-Z_a-z][$\\\\\\\\w]*([]$,\\\\\\\\[\\\\\\\\w][],\\\\\\\\[\\\\\\\\w\\\\\\\\s]*)?\\\\\\\\s*([:;=]))\",\"end\":\"(?=[:;=])\",\"name\":\"meta.definition.variable.java\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"variable.other.definition.java\"}},\"match\":\"([$A-Z_a-z][$\\\\\\\\w]*)(?=\\\\\\\\s*(\\\\\\\\[])*\\\\\\\\s*([,:;=]))\"},{\"include\":\"#all-types\"},{\"include\":\"#code\"}]},\"variables-local\":{\"begin\":\"(?=\\\\\\\\b(var)\\\\\\\\b\\\\\\\\s+[$A-Z_a-z][$\\\\\\\\w]*\\\\\\\\s*([:;=]))\",\"end\":\"(?=[:;=])\",\"name\":\"meta.definition.variable.local.java\",\"patterns\":[{\"match\":\"\\\\\\\\bvar\\\\\\\\b\",\"name\":\"storage.type.local.java\"},{\"captures\":{\"1\":{\"name\":\"variable.other.definition.java\"}},\"match\":\"([$A-Z_a-z][$\\\\\\\\w]*)(?=\\\\\\\\s*(\\\\\\\\[])*\\\\\\\\s*([:;=]))\"},{\"include\":\"#code\"}]}},\"scopeName\":\"source.java\"}`)),E_=[C_],F_=Object.freeze(JSON.parse(`{\"displayName\":\"XML\",\"name\":\"xml\",\"patterns\":[{\"begin\":\"(<\\\\\\\\?)\\\\\\\\s*([-0-9A-Z_a-z]+)\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"entity.name.tag.xml\"}},\"end\":\"(\\\\\\\\?>)\",\"name\":\"meta.tag.preprocessor.xml\",\"patterns\":[{\"match\":\" ([-A-Za-z]+)\",\"name\":\"entity.other.attribute-name.xml\"},{\"include\":\"#doublequotedString\"},{\"include\":\"#singlequotedString\"}]},{\"begin\":\"(<!)(DOCTYPE)\\\\\\\\s+([:A-Z_a-z][-.0-:A-Z_a-z]*)\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"keyword.other.doctype.xml\"},\"3\":{\"name\":\"variable.language.documentroot.xml\"}},\"end\":\"\\\\\\\\s*(>)\",\"name\":\"meta.tag.sgml.doctype.xml\",\"patterns\":[{\"include\":\"#internalSubset\"}]},{\"include\":\"#comments\"},{\"begin\":\"(<)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(?=(\\\\\\\\s[^>]*)?></\\\\\\\\2>)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"entity.name.tag.xml\"},\"3\":{\"name\":\"entity.name.tag.namespace.xml\"},\"4\":{\"name\":\"punctuation.separator.namespace.xml\"},\"5\":{\"name\":\"entity.name.tag.localname.xml\"}},\"end\":\"(>)(</)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(>)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"punctuation.definition.tag.xml\"},\"3\":{\"name\":\"entity.name.tag.xml\"},\"4\":{\"name\":\"entity.name.tag.namespace.xml\"},\"5\":{\"name\":\"punctuation.separator.namespace.xml\"},\"6\":{\"name\":\"entity.name.tag.localname.xml\"},\"7\":{\"name\":\"punctuation.definition.tag.xml\"}},\"name\":\"meta.tag.no-content.xml\",\"patterns\":[{\"include\":\"#tagStuff\"}]},{\"begin\":\"(</?)(?:([-.\\\\\\\\w]+)((:)))?([-.:\\\\\\\\w]+)\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"entity.name.tag.namespace.xml\"},\"3\":{\"name\":\"entity.name.tag.xml\"},\"4\":{\"name\":\"punctuation.separator.namespace.xml\"},\"5\":{\"name\":\"entity.name.tag.localname.xml\"}},\"end\":\"(/?>)\",\"name\":\"meta.tag.xml\",\"patterns\":[{\"include\":\"#tagStuff\"}]},{\"include\":\"#entity\"},{\"include\":\"#bare-ampersand\"},{\"begin\":\"<%@\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.xml\"}},\"end\":\"%>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.xml\"}},\"name\":\"source.java-props.embedded.xml\",\"patterns\":[{\"match\":\"page|include|taglib\",\"name\":\"keyword.other.page-props.xml\"}]},{\"begin\":\"<%[!=]?(?!--)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.xml\"}},\"end\":\"(?!--)%>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.xml\"}},\"name\":\"source.java.embedded.xml\",\"patterns\":[{\"include\":\"source.java\"}]},{\"begin\":\"<!\\\\\\\\[CDATA\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.xml\"}},\"end\":\"]]>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.xml\"}},\"name\":\"string.unquoted.cdata.xml\"}],\"repository\":{\"EntityDecl\":{\"begin\":\"(<!)(ENTITY)\\\\\\\\s+(%\\\\\\\\s+)?([:A-Z_a-z][-.0-:A-Z_a-z]*)(\\\\\\\\s+(?:SYSTEM|PUBLIC)\\\\\\\\s+)?\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.tag.xml\"},\"2\":{\"name\":\"keyword.other.entity.xml\"},\"3\":{\"name\":\"punctuation.definition.entity.xml\"},\"4\":{\"name\":\"variable.language.entity.xml\"},\"5\":{\"name\":\"keyword.other.entitytype.xml\"}},\"end\":\"(>)\",\"patterns\":[{\"include\":\"#doublequotedString\"},{\"include\":\"#singlequotedString\"}]},\"bare-ampersand\":{\"match\":\"&\",\"name\":\"invalid.illegal.bad-ampersand.xml\"},\"comments\":{\"patterns\":[{\"begin\":\"<%--\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.xml\"},\"end\":\"--%>\",\"name\":\"comment.block.xml\"}},{\"begin\":\"<!--\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.xml\"}},\"end\":\"-->\",\"name\":\"comment.block.xml\",\"patterns\":[{\"begin\":\"--(?!>)\",\"captures\":{\"0\":{\"name\":\"invalid.illegal.bad-comments-or-CDATA.xml\"}}}]}]},\"doublequotedString\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.xml\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.xml\"}},\"name\":\"string.quoted.double.xml\",\"patterns\":[{\"include\":\"#entity\"},{\"include\":\"#bare-ampersand\"}]},\"entity\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.constant.xml\"},\"3\":{\"name\":\"punctuation.definition.constant.xml\"}},\"match\":\"(&)([:A-Z_a-z][-.0-:A-Z_a-z]*|#[0-9]+|#x\\\\\\\\h+)(;)\",\"name\":\"constant.character.entity.xml\"},\"internalSubset\":{\"begin\":\"(\\\\\\\\[)\",\"captures\":{\"1\":{\"name\":\"punctuation.definition.constant.xml\"}},\"end\":\"(])\",\"name\":\"meta.internalsubset.xml\",\"patterns\":[{\"include\":\"#EntityDecl\"},{\"include\":\"#parameterEntity\"},{\"include\":\"#comments\"}]},\"parameterEntity\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.constant.xml\"},\"3\":{\"name\":\"punctuation.definition.constant.xml\"}},\"match\":\"(%)([:A-Z_a-z][-.0-:A-Z_a-z]*)(;)\",\"name\":\"constant.character.parameter-entity.xml\"},\"singlequotedString\":{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.xml\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.xml\"}},\"name\":\"string.quoted.single.xml\",\"patterns\":[{\"include\":\"#entity\"},{\"include\":\"#bare-ampersand\"}]},\"tagStuff\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"entity.other.attribute-name.namespace.xml\"},\"2\":{\"name\":\"entity.other.attribute-name.xml\"},\"3\":{\"name\":\"punctuation.separator.namespace.xml\"},\"4\":{\"name\":\"entity.other.attribute-name.localname.xml\"}},\"match\":\"(?:^|\\\\\\\\s+)(?:([-.\\\\\\\\w]+)((:)))?([-.:\\\\\\\\w]+)\\\\\\\\s*=\"},{\"include\":\"#doublequotedString\"},{\"include\":\"#singlequotedString\"}]}},\"scopeName\":\"text.xml\",\"embeddedLangs\":[\"java\"]}`)),$_=[...E_,F_],j_=Object.freeze(JSON.parse('{\"displayName\":\"SQL\",\"name\":\"sql\",\"patterns\":[{\"match\":\"((?<!@)@)\\\\\\\\b(\\\\\\\\w+)\\\\\\\\b\",\"name\":\"text.variable\"},{\"match\":\"(\\\\\\\\[)[^]]*(])\",\"name\":\"text.bracketed\"},{\"include\":\"#comments\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.create.sql\"},\"2\":{\"name\":\"keyword.other.sql\"},\"5\":{\"name\":\"entity.name.function.sql\"}},\"match\":\"(?i:^\\\\\\\\s*(create(?:\\\\\\\\s+or\\\\\\\\s+replace)?)\\\\\\\\s+(aggregate|conversion|database|domain|function|group|(unique\\\\\\\\s+)?index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view)\\\\\\\\s+)([\\\\\"\\'`]?)(\\\\\\\\w+)\\\\\\\\4\",\"name\":\"meta.create.sql\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.create.sql\"},\"2\":{\"name\":\"keyword.other.sql\"}},\"match\":\"(?i:^\\\\\\\\s*(drop)\\\\\\\\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view))\",\"name\":\"meta.drop.sql\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.create.sql\"},\"2\":{\"name\":\"keyword.other.table.sql\"},\"3\":{\"name\":\"entity.name.function.sql\"},\"4\":{\"name\":\"keyword.other.cascade.sql\"}},\"match\":\"(?i:\\\\\\\\s*(drop)\\\\\\\\s+(table)\\\\\\\\s+(\\\\\\\\w+)(\\\\\\\\s+cascade)?\\\\\\\\b)\",\"name\":\"meta.drop.sql\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.create.sql\"},\"2\":{\"name\":\"keyword.other.table.sql\"}},\"match\":\"(?i:^\\\\\\\\s*(alter)\\\\\\\\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|proc(edure)?|rule|schema|sequence|table|tablespace|trigger|type|user|view)\\\\\\\\s+)\",\"name\":\"meta.alter.sql\"},{\"captures\":{\"1\":{\"name\":\"storage.type.sql\"},\"2\":{\"name\":\"storage.type.sql\"},\"3\":{\"name\":\"constant.numeric.sql\"},\"4\":{\"name\":\"storage.type.sql\"},\"5\":{\"name\":\"constant.numeric.sql\"},\"6\":{\"name\":\"storage.type.sql\"},\"7\":{\"name\":\"constant.numeric.sql\"},\"8\":{\"name\":\"constant.numeric.sql\"},\"9\":{\"name\":\"storage.type.sql\"},\"10\":{\"name\":\"constant.numeric.sql\"},\"11\":{\"name\":\"storage.type.sql\"},\"12\":{\"name\":\"storage.type.sql\"},\"13\":{\"name\":\"storage.type.sql\"},\"14\":{\"name\":\"constant.numeric.sql\"},\"15\":{\"name\":\"storage.type.sql\"}},\"match\":\"(?i)\\\\\\\\b(bigint|bigserial|bit|boolean|box|bytea|cidr|circle|date|double\\\\\\\\sprecision|inet|int|integer|line|lseg|macaddr|money|oid|path|point|polygon|real|serial|smallint|sysdate|text)\\\\\\\\b|\\\\\\\\b(bit\\\\\\\\svarying|character\\\\\\\\s(?:varying)?|tinyint|var\\\\\\\\schar|float|interval)\\\\\\\\((\\\\\\\\d+)\\\\\\\\)|\\\\\\\\b(char|number|varchar\\\\\\\\d?)\\\\\\\\b(?:\\\\\\\\((\\\\\\\\d+)\\\\\\\\))?|\\\\\\\\b(numeric|decimal)\\\\\\\\b(?:\\\\\\\\((\\\\\\\\d+),(\\\\\\\\d+)\\\\\\\\))?|\\\\\\\\b(times?)\\\\\\\\b(?:\\\\\\\\((\\\\\\\\d+)\\\\\\\\))?(\\\\\\\\swith(?:out)?\\\\\\\\stime\\\\\\\\szone\\\\\\\\b)?|\\\\\\\\b(timestamp)(s|tz)?\\\\\\\\b(?:\\\\\\\\((\\\\\\\\d+)\\\\\\\\))?(\\\\\\\\s(with(?:|out))\\\\\\\\stime\\\\\\\\szone\\\\\\\\b)?\"},{\"match\":\"(?i:\\\\\\\\b((?:primary|foreign)\\\\\\\\s+key|references|on\\\\\\\\s+(delete|update)(\\\\\\\\s+cascade)?|nocheck|check|constraint|collate|default)\\\\\\\\b)\",\"name\":\"storage.modifier.sql\"},{\"match\":\"\\\\\\\\b\\\\\\\\d+\\\\\\\\b\",\"name\":\"constant.numeric.sql\"},{\"match\":\"(?i:\\\\\\\\b(select(\\\\\\\\s+(all|distinct))?|insert\\\\\\\\s+(ignore\\\\\\\\s+)?into|update|delete|from|set|where|group\\\\\\\\s+by|or|like|and|union(\\\\\\\\s+all)?|having|order\\\\\\\\s+by|limit|cross\\\\\\\\s+join|join|straight_join|(inner|(left|right|full)(\\\\\\\\s+outer)?)\\\\\\\\s+join|natural(\\\\\\\\s+(inner|(left|right|full)(\\\\\\\\s+outer)?))?\\\\\\\\s+join)\\\\\\\\b)\",\"name\":\"keyword.other.DML.sql\"},{\"match\":\"(?i:\\\\\\\\b(on|off|((is\\\\\\\\s+)?not\\\\\\\\s+)?null)\\\\\\\\b)\",\"name\":\"keyword.other.DDL.create.II.sql\"},{\"match\":\"(?i:\\\\\\\\bvalues\\\\\\\\b)\",\"name\":\"keyword.other.DML.II.sql\"},{\"match\":\"(?i:\\\\\\\\b(begin(\\\\\\\\s+work)?|start\\\\\\\\s+transaction|commit(\\\\\\\\s+work)?|rollback(\\\\\\\\s+work)?)\\\\\\\\b)\",\"name\":\"keyword.other.LUW.sql\"},{\"match\":\"(?i:\\\\\\\\b(grant(\\\\\\\\swith\\\\\\\\sgrant\\\\\\\\soption)?|revoke)\\\\\\\\b)\",\"name\":\"keyword.other.authorization.sql\"},{\"match\":\"(?i:\\\\\\\\bin\\\\\\\\b)\",\"name\":\"keyword.other.data-integrity.sql\"},{\"match\":\"(?i:^\\\\\\\\s*(comment\\\\\\\\s+on\\\\\\\\s+(table|column|aggregate|constraint|database|domain|function|index|operator|rule|schema|sequence|trigger|type|view))\\\\\\\\s+)\",\"name\":\"keyword.other.object-comments.sql\"},{\"match\":\"(?i)\\\\\\\\bAS\\\\\\\\b\",\"name\":\"keyword.other.alias.sql\"},{\"match\":\"(?i)\\\\\\\\b(DESC|ASC)\\\\\\\\b\",\"name\":\"keyword.other.order.sql\"},{\"match\":\"\\\\\\\\*\",\"name\":\"keyword.operator.star.sql\"},{\"match\":\"[!<>]?=|<>|[<>]\",\"name\":\"keyword.operator.comparison.sql\"},{\"match\":\"[-+/]\",\"name\":\"keyword.operator.math.sql\"},{\"match\":\"\\\\\\\\|\\\\\\\\|\",\"name\":\"keyword.operator.concatenator.sql\"},{\"captures\":{\"1\":{\"name\":\"support.function.aggregate.sql\"}},\"match\":\"(?i)\\\\\\\\b(approx_count_distinct|approx_percentile_cont|approx_percentile_disc|avg|checksum_agg|count|count_big|group|grouping|grouping_id|max|min|sum|stdevp??|varp??)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.analytic.sql\"}},\"match\":\"(?i)\\\\\\\\b(cume_dist|first_value|lag|last_value|lead|percent_rank|percentile_cont|percentile_disc)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.bitmanipulation.sql\"}},\"match\":\"(?i)\\\\\\\\b((?:bit_coun|get_bi|left_shif|right_shif|set_bi)t)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.conversion.sql\"}},\"match\":\"(?i)\\\\\\\\b(cast|convert|parse|try_cast|try_convert|try_parse)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.collation.sql\"}},\"match\":\"(?i)\\\\\\\\b(collationproperty|tertiary_weights)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.cryptographic.sql\"}},\"match\":\"(?i)\\\\\\\\b(asymkey_id|asymkeyproperty|certproperty|cert_id|crypt_gen_random|decryptbyasymkey|decryptbycert|decryptbykey|decryptbykeyautoasymkey|decryptbykeyautocert|decryptbypassphrase|encryptbyasymkey|encryptbycert|encryptbykey|encryptbypassphrase|hashbytes|is_objectsigned|key_guid|key_id|key_name|signbyasymkey|signbycert|symkeyproperty|verifysignedbycert|verifysignedbyasymkey)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.cursor.sql\"}},\"match\":\"(?i)\\\\\\\\b(cursor_status)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.datetime.sql\"}},\"match\":\"(?i)\\\\\\\\b(sysdatetime|sysdatetimeoffset|sysutcdatetime|current_time(stamp)?|getdate|getutcdate|datename|datepart|day|month|year|datefromparts|datetime2fromparts|datetimefromparts|datetimeoffsetfromparts|smalldatetimefromparts|timefromparts|datediff|dateadd|datetrunc|eomonth|switchoffset|todatetimeoffset|isdate|date_bucket)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.datatype.sql\"}},\"match\":\"(?i)\\\\\\\\b(datalength|ident_current|ident_incr|ident_seed|identity|sql_variant_property)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.expression.sql\"}},\"match\":\"(?i)\\\\\\\\b(coalesce|nullif)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.globalvar.sql\"}},\"match\":\"(?<!@)@@(?i)\\\\\\\\b(cursor_rows|connections|cpu_busy|datefirst|dbts|error|fetch_status|identity|idle|io_busy|langid|language|lock_timeout|max_connections|max_precision|nestlevel|options|packet_errors|pack_received|pack_sent|procid|remserver|rowcount|servername|servicename|spid|textsize|timeticks|total_errors|total_read|total_write|trancount|version)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.json.sql\"}},\"match\":\"(?i)\\\\\\\\b(json|isjson|json_object|json_array|json_value|json_query|json_modify|json_path_exists)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.logical.sql\"}},\"match\":\"(?i)\\\\\\\\b(choose|iif|greatest|least)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.mathematical.sql\"}},\"match\":\"(?i)\\\\\\\\b(abs|acos|asin|atan|atn2|ceiling|cos|cot|degrees|exp|floor|log|log10|pi|power|radians|rand|round|sign|sin|sqrt|square|tan)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.metadata.sql\"}},\"match\":\"(?i)\\\\\\\\b(app_name|applock_mode|applock_test|assemblyproperty|col_length|col_name|columnproperty|database_principal_id|databasepropertyex|db_id|db_name|file_id|file_idex|file_name|filegroup_id|filegroup_name|filegroupproperty|fileproperty|fulltextcatalogproperty|fulltextserviceproperty|index_col|indexkey_property|indexproperty|object_definition|object_id|object_name|object_schema_name|objectproperty|objectpropertyex|original_db_name|parsename|schema_id|schema_name|scope_identity|serverproperty|stats_date|type_id|type_name|typeproperty)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.ranking.sql\"}},\"match\":\"(?i)\\\\\\\\b(rank|dense_rank|ntile|row_number)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.rowset.sql\"}},\"match\":\"(?i)\\\\\\\\b(generate_series|opendatasource|openjson|openrowset|openquery|openxml|predict|string_split)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.security.sql\"}},\"match\":\"(?i)\\\\\\\\b(certencoded|certprivatekey|current_user|database_principal_id|has_perms_by_name|is_member|is_rolemember|is_srvrolemember|original_login|permissions|pwdcompare|pwdencrypt|schema_id|schema_name|session_user|suser_id|suser_sid|suser_sname|system_user|suser_name|user_id|user_name)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.string.sql\"}},\"match\":\"(?i)\\\\\\\\b(ascii|char|charindex|concat|difference|format|left|len|lower|ltrim|nchar|nodes|patindex|quotename|replace|replicate|reverse|right|rtrim|soundex|space|str|string_agg|string_escape|string_split|stuff|substring|translate|trim|unicode|upper)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.system.sql\"}},\"match\":\"(?i)\\\\\\\\b(binary_checksum|checksum|compress|connectionproperty|context_info|current_request_id|current_transaction_id|decompress|error_line|error_message|error_number|error_procedure|error_severity|error_state|formatmessage|get_filestream_transaction_context|getansinull|host_id|host_name|isnull|isnumeric|min_active_rowversion|newid|newsequentialid|rowcount_big|session_context|session_id|xact_state)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.textimage.sql\"}},\"match\":\"(?i)\\\\\\\\b(patindex|textptr|textvalid)\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"support.function.vector.sql\"}},\"match\":\"(?i)\\\\\\\\b(vector_(?:distance|norm|normalize))\\\\\\\\b\\\\\\\\s*\\\\\\\\(\"},{\"captures\":{\"1\":{\"name\":\"constant.other.database-name.sql\"},\"2\":{\"name\":\"constant.other.table-name.sql\"}},\"match\":\"(\\\\\\\\w+?)\\\\\\\\.(\\\\\\\\w+)\"},{\"include\":\"#strings\"},{\"include\":\"#regexps\"},{\"match\":\"\\\\\\\\b(?i)(abort|abort_after_wait|absent|absolute|accent_sensitivity|acceptable_cursopt|acp|action|activation|add|address|admin|aes_128|aes_192|aes_256|affinity|after|aggregate|algorithm|all_constraints|all_errormsgs|all_indexes|all_levels|all_results|allow_connections|allow_dup_row|allow_encrypted_value_modifications|allow_page_locks|allow_row_locks|allow_snapshot_isolation|alter|altercolumn|always|anonymous|ansi_defaults|ansi_null_default|ansi_null_dflt_off|ansi_null_dflt_on|ansi_nulls|ansi_padding|ansi_warnings|appdomain|append|application|apply|arithabort|arithignore|array|assembly|asymmetric|asynchronous_commit|at|atan2|atomic|attach|attach_force_rebuild_log|attach_rebuild_log|audit|auth_realm|authentication|auto|auto_cleanup|auto_close|auto_create_statistics|auto_drop|auto_shrink|auto_update_statistics|auto_update_statistics_async|automated_backup_preference|automatic|autopilot|availability|availability_mode|backup|backup_priority|base64|basic|batches|batchsize|before|between|bigint|binary|binding|bit|block|blockers|blocksize|bmk|both|break|broker|broker_instance|bucket_count|buffer|buffercount|bulk_logged|by|call|caller|card|case|catalog|catch|cert|certificate|change_retention|change_tracking|change_tracking_context|changes|char|character|character_set|check_expiration|check_policy|checkconstraints|checkindex|checkpoint|checksum|cleanup_policy|clear|clear_port|close|clustered|codepage|collection|column_encryption_key|column_master_key|columnstore|columnstore_archive|colv_80_to_100|colv_100_to_80|commit_differential_base|committed|compatibility_level|compress_all_row_groups|compression|compression_delay|concat_null_yields_null|concatenate|configuration|connect|connection|containment|continue|continue_after_error|contract|contract_name|control|conversation|conversation_group_id|conversation_handle|copy|copy_only|count_rows|counter|create(\\\\\\\\\\\\\\\\s+or\\\\\\\\\\\\\\\\s+alter)?|credential|cross|cryptographic|cryptographic_provider|cube|cursor|cursor_close_on_commit|cursor_default|data|data_compression|data_flush_interval_seconds|data_mirroring|data_purity|data_source|database|database_name|database_snapshot|datafiletype|date_correlation_optimization|date|datefirst|dateformat|date_format|datetime2??|datetimeoffset|day(s)?|db_chaining|dbid|dbidexec|dbo_only|deadlock_priority|deallocate|dec|decimal|declare|decrypt|decrypt_a|decryption|default_database|default_fulltext_language|default_language|default_logon_domain|default_schema|definition|delay|delayed_durability|delimitedtext|density_vector|dependent|des|description|desired_state|desx|differential|digest|disable|disable_broker|disable_def_cnst_chk|disabled|disk|distinct|distributed|distribution|drop|drop_existing|dts_buffers|dump|durability|dynamic|edition|elements|else|emergency|empty|enable|enable_broker|enabled|encoding|encrypted|encrypted_value|encryption|encryption_type|end|endpoint|endpoint_url|enhancedintegrity|entry|error_broker_conversations|errorfile|estimateonly|event|except|exec|executable|execute|exists|expand|expiredate|expiry_date|explicit|external|external_access|failover|failover_mode|failure_condition_level|fast|fast_forward|fastfirstrow|federated_service_account|fetch|field_terminator|fieldterminator|file|filelistonly|filegroup|filegrowth|filename|filestream|filestream_log|filestream_on|filetable|file_format|filter|first_row|fips_flagger|fire_triggers|first|firstrow|float|flush_interval_seconds|fmtonly|following|for|force|force_failover_allow_data_loss|force_service_allow_data_loss|forced|forceplan|formatfile|format_options|format_type|formsof|forward_only|free_cursors|free_exec_context|fullscan|fulltext|fulltextall|fulltextkey|function|generated|get|geography|geometry|global|go|goto|governor|guid|hadoop|hardening|hash|hashed|header_limit|headeronly|health_check_timeout|hidden|hierarchyid|histogram|histogram_steps|hits_cursors|hits_exec_context|hour(s)?|http|identity|identity_value|if|ifnull|ignore|ignore_constraints|ignore_dup_key|ignore_dup_row|ignore_triggers|image|immediate|implicit_transactions|include|include_null_values|incremental|index|inflectional|init|initiator|insensitive|insert|instead|int|integer|integrated|intersect|intermediate|interval_length_minutes|into|inuse_cursors|inuse_exec_context|io|is|isabout|iso_week|isolation|job_tracker_location|json|keep|keep_nulls|keep_replication|keepdefaults|keepfixed|keepidentity|keepnulls|kerberos|key|key_path|key_source|key_store_provider_name|keyset|kill|kilobytes_per_batch|labelonly|langid|language|last|lastrow|leading|legacy_cardinality_estimation|length|level|lifetime|lineage_80_to_100|lineage_100_to_80|listener_ip|listener_port|load|loadhistory|lob_compaction|local|local_service_name|locate|location|lock_escalation|lock_timeout|lockres|log|login|login_type|loop|manual|mark_in_use_for_removal|masked|master|match|matched|max_queue_readers|max_duration|max_outstanding_io_per_volume|maxdop|maxerrors|maxlength|maxtransfersize|max_plans_per_query|max_storage_size_mb|mediadescription|medianame|mediapassword|memogroup|memory_optimized|merge|message|message_forward_size|message_forwarding|microsecond|millisecond|minute(s)?|mirror_address|misses_cursors|misses_exec_context|mixed|modify|money|month|move|multi_user|must_change|name|namespace|nanosecond|native|native_compilation|nchar|ncharacter|nested_triggers|never|new_account|new_broker|newname|next|no|no_browsetable|no_checksum|no_compression|no_infomsgs|no_triggers|no_truncate|nocount|noexec|noexpand|noformat|noinit|nolock|nonatomic|nonclustered|nondurable|none|norecompute|norecovery|noreset|norewind|noskip|not|notification|nounload|now|nowait|ntext|ntlm|nulls|numeric|numeric_roundabort|nvarchar|object|objid|oem|offline|old_account|online|operation_mode|open|openjson|optimistic|option|orc|out|outer|output|over|override|owner|ownership|pad_index|page|page_checksum|page_verify|pagecount|paglock|param|parameter_sniffing|parameter_type_expansion|parameterization|parquet|parseonly|partial|partition|partner|password|path|pause|percentage|permission_set|persisted|period|physical_only|plan_forcing_mode|policy|pool|population|ports|preceding|precision|predicate|presume_abort|primary|primary_role|print|prior|priority |priority_level|private|proc(edure)?|procedure_name|profile|provider|quarter|query_capture_mode|query_governor_cost_limit|query_optimizer_hotfixes|query_store|queue|quoted_identifier|raiserror|range|raw|rcfile|rc2|rc4|rc4_128|rdbms|read_committed_snapshot|read|read_only|read_write|readcommitted|readcommittedlock|readonly|readpast|readuncommitted|readwrite|real|rebuild|receive|recmodel_70backcomp|recompile|reconfigure|recovery|recursive|recursive_triggers|redo_queue|reject_sample_value|reject_type|reject_value|relative|remote|remote_data_archive|remote_proc_transactions|remote_service_name|remove|removed_cursors|removed_exec_context|reorganize|repeat|repeatable|repeatableread|replace|replica|replicated|replnick_100_to_80|replnickarray_80_to_100|replnickarray_100_to_80|required|required_cursopt|resample|reset|resource|resource_manager_location|respect|restart|restore|restricted_user|resume|retaindays|retention|return|revert|rewind|rewindonly|returns|robust|role|rollup|root|round_robin|route|row|rowdump|rowguidcol|rowlock|row_terminator|rows|rows_per_batch|rowsets_only|rowterminator|rowversion|rsa_1024|rsa_2048|rsa_3072|rsa_4096|rsa_512|safe|safety|sample|save|scalar|schema|schemabinding|scoped|scroll|scroll_locks|sddl|second|secexpr|seconds|secondary|secondary_only|secondary_role|secret|security|securityaudit|selective|self|send|sent|sequence|serde_method|serializable|server|service|service_broker|service_name|service_objective|session_timeout|sessions??|seterror|setopts|sets|shard_map_manager|shard_map_name|sharded|shared_memory|shortest_path|show_statistics|showplan_all|showplan_text|showplan_xml|showplan_xml_with_recompile|shrinkdb|shutdown|sid|signature|simple|single_blob|single_clob|single_nclob|single_user|singleton|site|size|size_based_cleanup_mode|skip|smalldatetime|smallint|smallmoney|snapshot|snapshot_import|snapshotrestorephase|soap|softnuma|sort_in_tempdb|sorted_data|sorted_data_reorg|spatial|sql|sql_bigint|sql_binary|sql_bit|sql_char|sql_date|sql_decimal|sql_double|sql_float|sql_guid|sql_handle|sql_longvarbinary|sql_longvarchar|sql_numeric|sql_real|sql_smallint|sql_time|sql_timestamp|sql_tinyint|sql_tsi_day|sql_tsi_frac_second|sql_tsi_hour|sql_tsi_minute|sql_tsi_month|sql_tsi_quarter|sql_tsi_second|sql_tsi_week|sql_tsi_year|sql_type_date|sql_type_time|sql_type_timestamp|sql_varbinary|sql_varchar|sql_variant|sql_wchar|sql_wlongvarchar|ssl|ssl_port|standard|standby|start|start_date|started|stat_header|state|statement|static|statistics|statistics_incremental|statistics_norecompute|statistics_only|statman|stats|stats_stream|status|stop|stop_on_error|stopat|stopatmark|stopbeforemark|stoplist|stopped|string_delimiter|subject|supplemental_logging|supported|suspend|symmetric|synchronous_commit|synonym|sysname|system|system_time|system_versioning|table|tableresults|tablockx??|take|tape|target|target_index|target_partition|target_recovery_time|tcp|temporal_history_retention|text|textimage_on|then|thesaurus|throw|time|timeout|timestamp|tinyint|top??|torn_page_detection|track_columns_updated|trailing|tran|transaction|transfer|transform_noise_words|triple_des|triple_des_3key|truncate|trustworthy|try|tsql|two_digit_year_cutoff|type|type_desc|type_warning|tzoffset|uid|unbounded|uncommitted|unique|uniqueidentifier|unlimited|unload|unlock|unsafe|updlock|url|use|useplan|useroptions|use_type_default|using|utcdatetime|valid_xml|validation|values??|varbinary|varchar|vector|verbose|verifyonly|version|view_metadata|virtual_device|visiblity|wait_at_low_priority|waitfor|webmethod|week|weekday|weight|well_formed_xml|when|while|widechar|widechar_ansi|widenative|windows??|with|within|within group|witness|without|without_array_wrapper|workload|wsdl|xact_abort|xlock|xml|xmlschema|xquery|xsinil|year|zone)\\\\\\\\b\",\"name\":\"keyword.other.sql\"},{\"captures\":{\"1\":{\"name\":\"punctuation.section.scope.begin.sql\"},\"2\":{\"name\":\"punctuation.section.scope.end.sql\"}},\"match\":\"(\\\\\\\\()(\\\\\\\\))\",\"name\":\"meta.block.sql\"}],\"repository\":{\"comment-block\":{\"begin\":\"/\\\\\\\\*\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.sql\"}},\"end\":\"\\\\\\\\*/\",\"name\":\"comment.block\",\"patterns\":[{\"include\":\"#comment-block\"}]},\"comments\":{\"patterns\":[{\"begin\":\"(^[\\\\\\\\t ]+)?(?=--)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.sql\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"--\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.sql\"}},\"end\":\"\\\\\\\\n\",\"name\":\"comment.line.double-dash.sql\"}]},{\"begin\":\"(^[\\\\\\\\t ]+)?(?=#)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.sql\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[]},{\"include\":\"#comment-block\"}]},\"regexps\":{\"patterns\":[{\"begin\":\"/(?=\\\\\\\\S.*/)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.regexp.sql\",\"patterns\":[{\"include\":\"#string_interpolation\"},{\"match\":\"\\\\\\\\\\\\\\\\/\",\"name\":\"constant.character.escape.slash.sql\"}]},{\"begin\":\"%r\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.regexp.modr.sql\",\"patterns\":[{\"include\":\"#string_interpolation\"}]}]},\"string_escape\":{\"match\":\"\\\\\\\\\\\\\\\\.\",\"name\":\"constant.character.escape.sql\"},\"string_interpolation\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.string.begin.sql\"},\"3\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"match\":\"(#\\\\\\\\{)([^}]*)(})\",\"name\":\"string.interpolated.sql\"},\"strings\":{\"patterns\":[{\"captures\":{\"2\":{\"name\":\"punctuation.definition.string.begin.sql\"},\"3\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"match\":\"(N)?(\\')[^\\']*(\\')\",\"name\":\"string.quoted.single.sql\"},{\"begin\":\"\\'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"\\'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.quoted.single.sql\",\"patterns\":[{\"include\":\"#string_escape\"}]},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.string.begin.sql\"},\"2\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"match\":\"(`)[^\\\\\\\\\\\\\\\\`]*(`)\",\"name\":\"string.quoted.other.backtick.sql\"},{\"begin\":\"`\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"`\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.quoted.other.backtick.sql\",\"patterns\":[{\"include\":\"#string_escape\"}]},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.string.begin.sql\"},\"2\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"match\":\"(\\\\\")[^\\\\\"#]*(\\\\\")\",\"name\":\"string.quoted.double.sql\"},{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.quoted.double.sql\",\"patterns\":[{\"include\":\"#string_interpolation\"}]},{\"begin\":\"%\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.sql\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.sql\"}},\"name\":\"string.other.quoted.brackets.sql\",\"patterns\":[{\"include\":\"#string_interpolation\"}]}]}},\"scopeName\":\"source.sql\"}')),Hl=[j_],S_=Object.freeze(JSON.parse(`{\"displayName\":\"PHP\",\"name\":\"php\",\"patterns\":[{\"include\":\"#attribute\"},{\"include\":\"#comments\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.namespace.php\"},\"2\":{\"name\":\"entity.name.type.namespace.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\",\"name\":\"punctuation.separator.inheritance.php\"}]}},\"match\":\"(?i)(?:^|(?<=<\\\\\\\\?php))\\\\\\\\s*(namespace)\\\\\\\\s+([0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)(?=\\\\\\\\s*;)\",\"name\":\"meta.namespace.php\"},{\"begin\":\"(?i)(?:^|(?<=<\\\\\\\\?php))\\\\\\\\s*(namespace)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.namespace.php\"}},\"end\":\"(?<=})|(?=\\\\\\\\?>)\",\"name\":\"meta.namespace.php\",\"patterns\":[{\"include\":\"#comments\"},{\"captures\":{\"0\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\",\"name\":\"punctuation.separator.inheritance.php\"}]}},\"match\":\"(?i)[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+\",\"name\":\"entity.name.type.namespace.php\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.namespace.begin.bracket.curly.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.namespace.end.bracket.curly.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"match\":\"\\\\\\\\S+\",\"name\":\"invalid.illegal.identifier.php\"}]},{\"match\":\"\\\\\\\\s+(?=use\\\\\\\\b)\"},{\"begin\":\"(?i)\\\\\\\\buse\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.other.use.php\"}},\"end\":\"(?<=})|(?=;)|(?=\\\\\\\\?>)\",\"name\":\"meta.use.php\",\"patterns\":[{\"match\":\"\\\\\\\\b(const|function)\\\\\\\\b\",\"name\":\"storage.type.\\${1:/downcase}.php\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.use.begin.bracket.curly.php\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.use.end.bracket.curly.php\"}},\"patterns\":[{\"include\":\"#scope-resolution\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.use-as.php\"},\"2\":{\"name\":\"storage.modifier.php\"},\"3\":{\"name\":\"entity.other.alias.php\"}},\"match\":\"(?i)\\\\\\\\b(as)\\\\\\\\s+(final|abstract|public|private|protected|static)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.use-as.php\"},\"2\":{\"patterns\":[{\"match\":\"^(?:final|abstract|public|private|protected|static)$\",\"name\":\"storage.modifier.php\"},{\"match\":\".+\",\"name\":\"entity.other.alias.php\"}]}},\"match\":\"(?i)\\\\\\\\b(as)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.use-insteadof.php\"},\"2\":{\"name\":\"support.class.php\"}},\"match\":\"(?i)\\\\\\\\b(insteadof)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"match\":\";\",\"name\":\"punctuation.terminator.expression.php\"},{\"include\":\"#use-inner\"}]},{\"include\":\"#use-inner\"}]},{\"begin\":\"(?i)\\\\\\\\b(trait)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.trait.php\"},\"2\":{\"name\":\"entity.name.type.trait.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.trait.end.bracket.curly.php\"}},\"name\":\"meta.trait.php\",\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.trait.begin.bracket.curly.php\"}},\"contentName\":\"meta.trait.body.php\",\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)\\\\\\\\b(interface)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.interface.php\"},\"2\":{\"name\":\"entity.name.type.interface.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.interface.end.bracket.curly.php\"}},\"name\":\"meta.interface.php\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#interface-extends\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.interface.begin.bracket.curly.php\"}},\"contentName\":\"meta.interface.body.php\",\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"include\":\"#class-constant\"},{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)\\\\\\\\b(enum)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?:\\\\\\\\s*(:)\\\\\\\\s*(int|string)\\\\\\\\b)?\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.enum.php\"},\"2\":{\"name\":\"entity.name.type.enum.php\"},\"3\":{\"name\":\"keyword.operator.return-value.php\"},\"4\":{\"name\":\"keyword.other.type.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.enum.end.bracket.curly.php\"}},\"name\":\"meta.enum.php\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#class-implements\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.enum.begin.bracket.curly.php\"}},\"contentName\":\"meta.enum.body.php\",\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.modifier.php\"},\"2\":{\"name\":\"constant.enum.php\"}},\"match\":\"(?i)\\\\\\\\b(case)\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"include\":\"#class-constant\"},{\"include\":\"$self\"}]}]},{\"begin\":\"(?i)\\\\\\\\b(?:((?:(?:final|abstract|readonly)\\\\\\\\s+)*)(class)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)|(new)\\\\\\\\b\\\\\\\\s*(#\\\\\\\\[.*])?\\\\\\\\s*(?:(readonly)\\\\\\\\s+)?\\\\\\\\b(class)\\\\\\\\b)\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"match\":\"final|abstract\",\"name\":\"storage.modifier.\\${0:/downcase}.php\"},{\"match\":\"readonly\",\"name\":\"storage.modifier.php\"}]},\"2\":{\"name\":\"storage.type.class.php\"},\"3\":{\"name\":\"entity.name.type.class.php\"},\"4\":{\"name\":\"keyword.other.new.php\"},\"5\":{\"patterns\":[{\"include\":\"#attribute\"}]},\"6\":{\"name\":\"storage.modifier.php\"},\"7\":{\"name\":\"storage.type.class.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.class.end.bracket.curly.php\"}},\"name\":\"meta.class.php\",\"patterns\":[{\"begin\":\"(?<=class)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"name\":\"meta.function-call.php\",\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"include\":\"#comments\"},{\"include\":\"#class-extends\"},{\"include\":\"#class-implements\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.class.begin.bracket.curly.php\"}},\"contentName\":\"meta.class.body.php\",\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"include\":\"#class-constant\"},{\"include\":\"$self\"}]}]},{\"include\":\"#match_statement\"},{\"include\":\"#switch_statement\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.yield-from.php\"}},\"match\":\"\\\\\\\\s*\\\\\\\\b(yield\\\\\\\\s+from)\\\\\\\\b\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.\\${1:/downcase}.php\"}},\"match\":\"\\\\\\\\b(break|case|continue|declare|default|die|do|else(if)?|end(declare|for(each)?|if|switch|while)|exit|for(each)?|if|return|switch|use|while|yield)\\\\\\\\b\"},{\"begin\":\"(?i)\\\\\\\\b((?:require|include)(?:_once)?)(\\\\\\\\s+|(?=\\\\\\\\())\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.import.include.php\"}},\"end\":\"(?=[;\\\\\\\\s]|$|\\\\\\\\?>)\",\"name\":\"meta.include.php\",\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"\\\\\\\\b(catch)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.control.exception.catch.php\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"}},\"name\":\"meta.catch.php\",\"patterns\":[{\"captures\":{\"1\":{\"patterns\":[{\"match\":\"\\\\\\\\|\",\"name\":\"punctuation.separator.delimiter.php\"},{\"begin\":\"(?i)(?=[\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?![0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"support.class.exception.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]}]},\"2\":{\"name\":\"variable.other.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)([0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*\\\\\\\\|\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)*)\\\\\\\\s*((\\\\\\\\$+)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?\"}]},{\"match\":\"\\\\\\\\b(catch|try|throw|exception|finally)\\\\\\\\b\",\"name\":\"keyword.control.exception.php\"},{\"begin\":\"(?i)\\\\\\\\b(function)\\\\\\\\s*(?=&?\\\\\\\\s*\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.php\"}},\"end\":\"(?=\\\\\\\\s*\\\\\\\\{)\",\"name\":\"meta.function.closure.php\",\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"(&)?\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.reference.php\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"contentName\":\"meta.function.parameters.php\",\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"#function-parameters\"}]},{\"begin\":\"(?i)(use)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.function.use.php\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"}},\"name\":\"meta.function.closure.use.php\",\"patterns\":[{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"},{\"captures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"storage.modifier.reference.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)((?:(&)\\\\\\\\s*)?(\\\\\\\\$+)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(?=[),])\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.operator.return-value.php\"},\"2\":{\"patterns\":[{\"include\":\"#php-types\"}]}},\"match\":\"(?i)(:)\\\\\\\\s*((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)(?=\\\\\\\\s*(?:\\\\\\\\{|/[*/]|#|$))\"}]},{\"begin\":\"(?i)\\\\\\\\b(fn)\\\\\\\\s*(?=&?\\\\\\\\s*\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.type.function.php\"}},\"end\":\"=>\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arrow.php\"}},\"name\":\"meta.function.closure.php\",\"patterns\":[{\"begin\":\"(?:(&)\\\\\\\\s*)?(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.reference.php\"},\"2\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"contentName\":\"meta.function.parameters.php\",\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"#function-parameters\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.operator.return-value.php\"},\"2\":{\"patterns\":[{\"include\":\"#php-types\"}]}},\"match\":\"(?i)(:)\\\\\\\\s*((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)(?=\\\\\\\\s*(?:=>|/[*/]|#|$))\"}]},{\"begin\":\"((?:(?:final|abstract|public|private|protected)\\\\\\\\s+)*)(function)\\\\\\\\s+(__construct)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"match\":\"final|abstract|public|private|protected\",\"name\":\"storage.modifier.php\"}]},\"2\":{\"name\":\"storage.type.function.php\"},\"3\":{\"name\":\"support.function.constructor.php\"},\"4\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"contentName\":\"meta.function.parameters.php\",\"end\":\"(?i)(\\\\\\\\))\\\\\\\\s*(:\\\\\\\\s*(?:\\\\\\\\?\\\\\\\\s*)?(?!\\\\\\\\s)[\\\\\\\\&()0-9\\\\\\\\\\\\\\\\_a-z|\\\\\\\\x7F-\\\\\\\\x{10FFFF}\\\\\\\\s]+(?<!\\\\\\\\s))?(?=\\\\\\\\s*(?:\\\\\\\\{|/[*/]|#|$|;))\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"},\"2\":{\"name\":\"invalid.illegal.return-type.php\"}},\"name\":\"meta.function.php\",\"patterns\":[{\"include\":\"#comments\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"},{\"begin\":\"(?i)((?:(?:p(?:ublic|rivate|rotected)(?:\\\\\\\\(set\\\\\\\\))?|readonly)(?:\\\\\\\\s+|(?=\\\\\\\\?)))++)(?:((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)\\\\\\\\s+)?((?:(&)\\\\\\\\s*)?(\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"match\":\"p(?:ublic|rivate|rotected)(?:\\\\\\\\(set\\\\\\\\))?|readonly\",\"name\":\"storage.modifier.php\"}]},\"2\":{\"patterns\":[{\"include\":\"#php-types\"}]},\"3\":{\"name\":\"variable.other.php\"},\"4\":{\"name\":\"storage.modifier.reference.php\"},\"5\":{\"name\":\"punctuation.definition.variable.php\"}},\"end\":\"(?=\\\\\\\\s*(?:[),]|/[*/]|#))\",\"name\":\"meta.function.parameter.promoted-property.php\",\"patterns\":[{\"begin\":\"=\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.assignment.php\"}},\"end\":\"(?=\\\\\\\\s*(?:[),]|/[*/]|#))\",\"patterns\":[{\"include\":\"#parameter-default-types\"}]}]},{\"include\":\"#function-parameters\"}]},{\"begin\":\"((?:(?:final|abstract|public|private|protected|static)\\\\\\\\s+)*)(function)\\\\\\\\s+(?i:(__(?:call|construct|debugInfo|destruct|get|set|isset|unset|toString|clone|set_state|sleep|wakeup|autoload|invoke|callStatic|serialize|unserialize))|(&)?\\\\\\\\s*([A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*))\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"match\":\"final|abstract|public|private|protected|static\",\"name\":\"storage.modifier.php\"}]},\"2\":{\"name\":\"storage.type.function.php\"},\"3\":{\"name\":\"support.function.magic.php\"},\"4\":{\"name\":\"storage.modifier.reference.php\"},\"5\":{\"name\":\"entity.name.function.php\"},\"6\":{\"name\":\"punctuation.definition.parameters.begin.bracket.round.php\"}},\"contentName\":\"meta.function.parameters.php\",\"end\":\"(?i)(\\\\\\\\))(?:\\\\\\\\s*(:)\\\\\\\\s*((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+))?(?=\\\\\\\\s*(?:\\\\\\\\{|/[*/]|#|$|;))\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.parameters.end.bracket.round.php\"},\"2\":{\"name\":\"keyword.operator.return-value.php\"},\"3\":{\"patterns\":[{\"match\":\"\\\\\\\\b(static)\\\\\\\\b\",\"name\":\"storage.type.php\"},{\"match\":\"\\\\\\\\b(never)\\\\\\\\b\",\"name\":\"keyword.other.type.never.php\"},{\"include\":\"#php-types\"}]}},\"name\":\"meta.function.php\",\"patterns\":[{\"include\":\"#function-parameters\"}]},{\"captures\":{\"1\":{\"patterns\":[{\"match\":\"p(?:ublic|rivate|rotected)(?:\\\\\\\\(set\\\\\\\\))?|static|readonly\",\"name\":\"storage.modifier.php\"}]},\"2\":{\"patterns\":[{\"include\":\"#php-types\"}]},\"3\":{\"name\":\"variable.other.php\"},\"4\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)((?:(?:p(?:ublic|rivate|rotected)(?:\\\\\\\\(set\\\\\\\\))?|static|readonly)(?:\\\\\\\\s+|(?=\\\\\\\\?)))++)((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)?\\\\\\\\s+((\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"include\":\"#invoke-call\"},{\"include\":\"#scope-resolution\"},{\"include\":\"#variables\"},{\"include\":\"#strings\"},{\"captures\":{\"1\":{\"name\":\"support.function.construct.php\"},\"2\":{\"name\":\"punctuation.definition.array.begin.bracket.round.php\"},\"3\":{\"name\":\"punctuation.definition.array.end.bracket.round.php\"}},\"match\":\"(array)(\\\\\\\\()(\\\\\\\\))\",\"name\":\"meta.array.empty.php\"},{\"begin\":\"(array)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.construct.php\"},\"2\":{\"name\":\"punctuation.definition.array.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.array.end.bracket.round.php\"}},\"name\":\"meta.array.php\",\"patterns\":[{\"include\":\"$self\"}]},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.storage-type.begin.bracket.round.php\"},\"2\":{\"name\":\"storage.type.php\"},\"3\":{\"name\":\"punctuation.definition.storage-type.end.bracket.round.php\"}},\"match\":\"(?i)(\\\\\\\\()\\\\\\\\s*(array|real|double|float|int(?:eger)?|bool(?:ean)?|string|object|binary|unset)\\\\\\\\s*(\\\\\\\\))\"},{\"match\":\"(?i)\\\\\\\\b(array|real|double|float|int(eger)?|bool(ean)?|string|class|var|function|interface|trait|parent|self|object|mixed)\\\\\\\\b\",\"name\":\"storage.type.php\"},{\"match\":\"(?i)\\\\\\\\bconst\\\\\\\\b\",\"name\":\"storage.type.const.php\"},{\"match\":\"(?i)\\\\\\\\b(global|abstract|final|private|protected|public|static)\\\\\\\\b\",\"name\":\"storage.modifier.php\"},{\"include\":\"#object\"},{\"match\":\";\",\"name\":\"punctuation.terminator.expression.php\"},{\"match\":\":\",\"name\":\"punctuation.terminator.statement.php\"},{\"include\":\"#heredoc\"},{\"include\":\"#numbers\"},{\"match\":\"(?i)\\\\\\\\bclone\\\\\\\\b\",\"name\":\"keyword.other.clone.php\"},{\"match\":\"\\\\\\\\.\\\\\\\\.\\\\\\\\.\",\"name\":\"keyword.operator.spread.php\"},{\"match\":\"\\\\\\\\.=?\",\"name\":\"keyword.operator.string.php\"},{\"match\":\"=>\",\"name\":\"keyword.operator.key.php\"},{\"captures\":{\"1\":{\"name\":\"keyword.operator.assignment.php\"},\"2\":{\"name\":\"storage.modifier.reference.php\"},\"3\":{\"name\":\"storage.modifier.reference.php\"}},\"match\":\"(?i)(=)(&)|(&)(?=[$_a-z])\"},{\"match\":\"@\",\"name\":\"keyword.operator.error-control.php\"},{\"match\":\"===?|!==?|<>\",\"name\":\"keyword.operator.comparison.php\"},{\"match\":\"(?:|[-+]|\\\\\\\\*\\\\\\\\*?|[%\\\\\\\\&/^|]|<<|>>|\\\\\\\\?\\\\\\\\?)=\",\"name\":\"keyword.operator.assignment.php\"},{\"match\":\"<=>?|>=|[<>]\",\"name\":\"keyword.operator.comparison.php\"},{\"match\":\"--|\\\\\\\\+\\\\\\\\+\",\"name\":\"keyword.operator.increment-decrement.php\"},{\"match\":\"[-+]|\\\\\\\\*\\\\\\\\*?|[%/]\",\"name\":\"keyword.operator.arithmetic.php\"},{\"match\":\"(?i)(!|&&|\\\\\\\\|\\\\\\\\|)|\\\\\\\\b(and|or|xor)\\\\\\\\b\",\"name\":\"keyword.operator.logical.php\"},{\"match\":\"(?i)\\\\\\\\bas\\\\\\\\b\",\"name\":\"keyword.operator.as.php\"},{\"include\":\"#function-call\"},{\"match\":\"<<|>>|[\\\\\\\\&^|~]\",\"name\":\"keyword.operator.bitwise.php\"},{\"begin\":\"(?i)\\\\\\\\b(instanceof)\\\\\\\\s+(?=[$\\\\\\\\\\\\\\\\_a-z])\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.type.php\"}},\"end\":\"(?i)(?=[^$0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"patterns\":[{\"include\":\"#class-name\"},{\"include\":\"#variable-name\"}]},{\"include\":\"#instantiation\"},{\"captures\":{\"1\":{\"name\":\"keyword.control.goto.php\"},\"2\":{\"name\":\"support.other.php\"}},\"match\":\"(?i)(goto)\\\\\\\\s+([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"},{\"captures\":{\"1\":{\"name\":\"entity.name.goto-label.php\"}},\"match\":\"(?i)^\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*(?<!default|else))\\\\\\\\s*:(?!:)\"},{\"include\":\"#string-backtick\"},{\"include\":\"#ternary_shorthand\"},{\"include\":\"#null_coalescing\"},{\"include\":\"#ternary_expression\"},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.begin.bracket.curly.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.end.bracket.curly.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.array.begin.php\"}},\"end\":\"]|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.array.end.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"include\":\"#constants\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"}],\"repository\":{\"attribute\":{\"begin\":\"#\\\\\\\\[\",\"end\":\"]\",\"name\":\"meta.attribute.php\",\"patterns\":[{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"},{\"begin\":\"([0-9A-Z\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"include\":\"#attribute-name\"}]},\"2\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"include\":\"#attribute-name\"}]},\"attribute-name\":{\"patterns\":[{\"begin\":\"(?i)(?=\\\\\\\\\\\\\\\\?[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\\\\\\\\\\\\\\\\)\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(?![0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"support.attribute.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(?i)(\\\\\\\\\\\\\\\\)?\\\\\\\\b(Attribute|SensitiveParameter|AllowDynamicProperties|ReturnTypeWillChange|Override|Deprecated)\\\\\\\\b\",\"name\":\"support.attribute.builtin.php\"},{\"begin\":\"(?i)(?=[\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(?![0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"support.attribute.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]}]},\"class-builtin\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(?i)(\\\\\\\\\\\\\\\\)?\\\\\\\\b(Attribute|(A(?:PC|ppend))Iterator|Array(Access|Iterator|Object)|Bad(Function|Method)CallException|(Ca(?:ching|llbackFilter))Iterator|Collator|Collectable|Cond|Countable|CURLFile|Date(Interval|Period|Time(Interface|Immutable|Zone)?)?|Directory(Iterator)?|DomainException|DOM(Attr|CdataSection|CharacterData|Comment|Document(Fragment)?|Element|EntityReference|Implementation|NamedNodeMap|Node(list)?|ProcessingInstruction|Text|XPath)|(Error)?Exception|EmptyIterator|finfo|Ev(Check|Child|Embed|Fork|Idle|Io|Loop|Periodic|Prepare|Signal|Stat|Timer|Watcher)?|Event(Base|Buffer(Event)?|SslContext|Http(Request|Connection)?|Config|DnsBase|Util|Listener)?|FANNConnection|(Fil(?:ter|esystem))Iterator|Gender\\\\\\\\\\\\\\\\Gender|GlobIterator|Gmagick(Draw|Pixel)?|Haru(Annotation|Destination|Doc|Encoder|Font|Image|Outline|Page)|Http(((?:In|De)flate)?Stream|Message|Request(Pool)?|Response|QueryString)|HRTime\\\\\\\\\\\\\\\\(PerformanceCounter|StopWatch)|Intl(Calendar|((CodePoint|RuleBased)?Break|Parts)?Iterator|DateFormatter|TimeZone)|Imagick(Draw|Pixel(Iterator)?)?|InfiniteIterator|InvalidArgumentException|Iterator(Aggregate|Iterator)?|JsonSerializable|KTaglib_(MPEG_(File|AudioProperties)|Tag|ID3v2_(Tag|(AttachedPicture)?Frame))|Lapack|(L(?:ength|ocale|ogic))Exception|LimitIterator|Lua(Closure)?|Mongo(BinData|Client|Code|Collection|CommandCursor|Cursor(Exception)?|Date|DB(Ref)?|DeleteBatch|Grid(FS(Cursor|File)?)|Id|InsertBatch|Int(32|64)|Log|Pool|Regex|ResultException|Timestamp|UpdateBatch|Write(Batch|ConcernException))?|Memcache(d)?|MessageFormatter|MultipleIterator|Mutex|mysqli(_(driver|stmt|warning|result))?|MysqlndUh(Connection|PreparedStatement)|NoRewindIterator|Normalizer|NumberFormatter|OCI-(Collection|Lob)|OuterIterator|(O(?:utOf(Bounds|Range)|verflow))Exception|ParentIterator|PDO(Statement)?|Phar(Data|FileInfo)?|php_user_filter|Pool|QuickHash(Int(S(?:et|tringHash))|StringIntHash)|Recursive(Array|Caching|Directory|Fallback|Filter|Iterator|Regex|Tree)?Iterator|Reflection(Attribute|Class(Constant)?|Constant|Enum((?:Unit|Backed)Case)?|Fiber|Function(Abstract)?|Generator|(Named|Union|Intersection)?Type|Method|Object|Parameter|Property|Reference|(Zend)?Extension)?|RangeException|Reflector|RegexIterator|ResourceBundle|RuntimeException|RRD(Creator|Graph|Updater)|SAM(Connection|Message)|SCA(_((?:Soap|Local)Proxy))?|SDO_(DAS_(ChangeSummary|Data(Factory|Object)|Relational|Setting|XML(_Document)?)|Data(Factory|Object)|Exception|List|Model_(Property|ReflectionDataObject|Type)|Sequence)|SeekableIterator|Serializable|SessionHandler(Interface)?|SimpleXML(Iterator|Element)|SNMP|Soap(Client|Fault|Header|Param|Server|Var)|SphinxClient|Spoofchecker|Spl(DoublyLinkedList|Enum|File(Info|Object)|FixedArray|(M(?:ax|in))?Heap|Observer|ObjectStorage|(Priority)?Queue|Stack|Subject|Type|TempFileObject)|SQLite(3(Result|Stmt)?|Database|Result|Unbuffered)|stdClass|streamWrapper|SVM(Model)?|Swish(Result(s)?|Search)?|Sync(Event|Mutex|ReaderWriter|Semaphore)|Thread(ed)?|tidy(Node)?|TokyoTyrant(Table|Iterator|Query)?|Transliterator|Traversable|UConverter|(Un(?:derflow|expectedValue))Exception|V8Js(Exception)?|Varnish(Admin|Log|Stat)|Worker|Weak(Map|Ref)|XML(Diff\\\\\\\\\\\\\\\\(Base|DOM|File|Memory)|Reader|Writer)|XsltProcessor|Yaf_(Route_(Interface|Map|Regex|Rewrite|Simple|Supervar)|Action_Abstract|Application|Config_(Simple|Ini|Abstract)|Controller_Abstract|Dispatcher|Exception|Loader|Plugin_Abstract|Registry|Request_(Abstract|Simple|Http)|Response_Abstract|Router|Session|View_(Simple|Interface))|Yar_(Client(_Exception)?|Concurrent_Client|Server(_Exception)?)|ZipArchive|ZMQ(Context|Device|Poll|Socket)?)\\\\\\\\b\",\"name\":\"support.class.builtin.php\"}]},\"class-constant\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"storage.type.const.php\"},\"2\":{\"patterns\":[{\"include\":\"#php-types\"}]},\"3\":{\"name\":\"constant.other.php\"}},\"match\":\"(?i)\\\\\\\\b(const)\\\\\\\\s+(?:((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)\\\\\\\\s+)?([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\"}]},\"class-extends\":{\"patterns\":[{\"begin\":\"(?i)(extends)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.extends.php\"}},\"end\":\"(?i)(?=[^0-9A-Z\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"patterns\":[{\"include\":\"#comments\"},{\"include\":\"#inheritance-single\"}]}]},\"class-implements\":{\"patterns\":[{\"begin\":\"(?i)(implements)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.implements.php\"}},\"end\":\"(?i)(?=\\\\\\\\{)\",\"patterns\":[{\"include\":\"#comments\"},{\"match\":\",\",\"name\":\"punctuation.separator.classes.php\"},{\"include\":\"#inheritance-single\"}]}]},\"class-name\":{\"patterns\":[{\"begin\":\"(?i)(?=\\\\\\\\\\\\\\\\?[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\\\\\\\\\\\\\\\\)\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(?![0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"support.class.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]},{\"include\":\"#class-builtin\"},{\"begin\":\"(?i)(?=[\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(?![0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"support.class.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]}]},\"comments\":{\"patterns\":[{\"begin\":\"/\\\\\\\\*\\\\\\\\*(?=\\\\\\\\s)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"\\\\\\\\*/\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"name\":\"comment.block.documentation.phpdoc.php\",\"patterns\":[{\"include\":\"#php_doc\"}]},{\"begin\":\"/\\\\\\\\*\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"\\\\\\\\*/\",\"name\":\"comment.block.php\"},{\"begin\":\"(^\\\\\\\\s+)?(?=//)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.php\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"//\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"\\\\\\\\n|(?=\\\\\\\\?>)\",\"name\":\"comment.line.double-slash.php\"}]},{\"begin\":\"(^\\\\\\\\s+)?(?=#)(?!#\\\\\\\\[)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.whitespace.comment.leading.php\"}},\"end\":\"(?!\\\\\\\\G)\",\"patterns\":[{\"begin\":\"#\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"\\\\\\\\n|(?=\\\\\\\\?>)\",\"name\":\"comment.line.number-sign.php\"}]}]},\"constants\":{\"patterns\":[{\"match\":\"(?i)\\\\\\\\b(TRUE|FALSE|NULL|__(FILE|DIR|FUNCTION|CLASS|METHOD|LINE|NAMESPACE)__|ON|OFF|YES|NO|NL|BR|TAB)\\\\\\\\b\",\"name\":\"constant.language.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(\\\\\\\\\\\\\\\\)?\\\\\\\\b(DEFAULT_INCLUDE_PATH|EAR_(INSTALL|EXTENSION)_DIR|E_(ALL|COMPILE_(ERROR|WARNING)|CORE_(ERROR|WARNING)|DEPRECATED|ERROR|NOTICE|PARSE|RECOVERABLE_ERROR|STRICT|USER_(DEPRECATED|ERROR|NOTICE|WARNING)|WARNING)|PHP_(ROUND_HALF_(DOWN|EVEN|ODD|UP)|(MAJOR|MINOR|RELEASE)_VERSION|MAXPATHLEN|BINDIR|SHLIB_SUFFIX|SYSCONFDIR|SAPI|CONFIG_FILE_(PATH|SCAN_DIR)|INT_(MAX|SIZE)|ZTS|OS|OUTPUT_HANDLER_(START|CONT|END)|DEBUG|DATADIR|URL_(SCHEME|HOST|USER|PORT|PASS|PATH|QUERY|FRAGMENT)|PREFIX|EXTRA_VERSION|EXTENSION_DIR|EOL|VERSION(_ID)?|WINDOWS_(NT_(SERVER|DOMAIN_CONTROLLER|WORKSTATION)|VERSION_(M(?:AJOR|INOR))|BUILD|SUITEMASK|SP_(M(?:AJOR|INOR))|PRODUCTTYPE|PLATFORM)|LIBDIR|LOCALSTATEDIR)|STD(ERR|IN|OUT)|ZEND_(DEBUG_BUILD|THREAD_SAFE))\\\\\\\\b\",\"name\":\"support.constant.core.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(\\\\\\\\\\\\\\\\)?\\\\\\\\b(__COMPILER_HALT_OFFSET__|AB(MON_([1-9]|10|11|12)|DAY[1-7])|AM_STR|ASSERT_(ACTIVE|BAIL|CALLBACK_QUIET_EVAL|WARNING)|ALT_DIGITS|CASE_(UPPER|LOWER)|CHAR_MAX|CONNECTION_(ABORTED|NORMAL|TIMEOUT)|CODESET|COUNT_(NORMAL|RECURSIVE)|CREDITS_(ALL|DOCS|FULLPAGE|GENERAL|GROUP|MODULES|QA|SAPI)|CRYPT_(BLOWFISH|EXT_DES|MD5|SHA(256|512)|SALT_LENGTH|STD_DES)|CURRENCY_SYMBOL|D_(T_)?FMT|DATE_(ATOM|COOKIE|ISO8601|RFC(822|850|1036|1123|2822|3339)|RSS|W3C)|DAY_[1-7]|DECIMAL_POINT|DIRECTORY_SEPARATOR|ENT_(COMPAT|IGNORE|(NO)?QUOTES)|EXTR_(IF_EXISTS|OVERWRITE|PREFIX_(ALL|IF_EXISTS|INVALID|SAME)|REFS|SKIP)|ERA(_(D_(T_)?FMT)|T_FMT|YEAR)?|FRAC_DIGITS|GROUPING|HASH_HMAC|HTML_(ENTITIES|SPECIALCHARS)|INF|INFO_(ALL|CREDITS|CONFIGURATION|ENVIRONMENT|GENERAL|LICENSEMODULES|VARIABLES)|INI_(ALL|CANNER_(NORMAL|RAW)|PERDIR|SYSTEM|USER)|INT_(CURR_SYMBOL|FRAC_DIGITS)|LC_(ALL|COLLATE|CTYPE|MESSAGES|MONETARY|NUMERIC|TIME)|LOCK_(EX|NB|SH|UN)|LOG_(ALERT|AUTH(PRIV)?|CRIT|CRON|CONS|DAEMON|DEBUG|EMERG|ERR|INFO|LOCAL[1-7]|LPR|KERN|MAIL|NEWS|NODELAY|NOTICE|NOWAIT|ODELAY|PID|PERROR|WARNING|SYSLOG|UCP|USER)|M_(1_PI|SQRT(1_2|[23]|PI)|2_(SQRT)?PI|PI(_([24]))?|E(ULER)?|LN(10|2|PI)|LOG(10|2)E)|MON_([1-9]|10|11|12|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|N_(CS_PRECEDES|SEP_BY_SPACE|SIGN_POSN)|NAN|NEGATIVE_SIGN|NO(EXPR|STR)|P_(CS_PRECEDES|SEP_BY_SPACE|SIGN_POSN)|PM_STR|POSITIVE_SIGN|PATH(_SEPARATOR|INFO_(EXTENSION|(BASE|DIR|FILE)NAME))|RADIXCHAR|SEEK_(CUR|END|SET)|SORT_(ASC|DESC|LOCALE_STRING|REGULAR|STRING)|STR_PAD_(BOTH|LEFT|RIGHT)|T_FMT(_AMPM)?|THOUSEP|THOUSANDS_SEP|UPLOAD_ERR_(CANT_WRITE|EXTENSION|(FORM|INI)_SIZE|NO_(FILE|TMP_DIR)|OK|PARTIAL)|YES(EXPR|STR))\\\\\\\\b\",\"name\":\"support.constant.std.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(\\\\\\\\\\\\\\\\)?\\\\\\\\b(GLOB_(MARK|BRACE|NO(SORT|CHECK|ESCAPE)|ONLYDIR|ERR|AVAILABLE_FLAGS)|XML_(SAX_IMPL|(DTD|DOCUMENT(_(FRAG|TYPE))?|HTML_DOCUMENT|NOTATION|NAMESPACE_DECL|PI|COMMENT|DATA_SECTION|TEXT)_NODE|OPTION_(SKIP_(TAGSTART|WHITE)|CASE_FOLDING|TARGET_ENCODING)|ERROR_((BAD_CHAR|(ATTRIBUTE_EXTERNAL|BINARY|PARAM|RECURSIVE)_ENTITY)_REF|MISPLACED_XML_PI|SYNTAX|NONE|NO_(MEMORY|ELEMENTS)|TAG_MISMATCH|INCORRECT_ENCODING|INVALID_TOKEN|DUPLICATE_ATTRIBUTE|UNCLOSED_(CDATA_SECTION|TOKEN)|UNDEFINED_ENTITY|UNKNOWN_ENCODING|JUNK_AFTER_DOC_ELEMENT|PARTIAL_CHAR|EXTERNAL_ENTITY_HANDLING|ASYNC_ENTITY)|ENTITY_(((REF|DECL)_)?NODE)|ELEMENT(_DECL)?_NODE|LOCAL_NAMESPACE|ATTRIBUTE_(N(?:MTOKEN(S)?|OTATION|ODE))|CDATA|ID(REF(S)?)?|DECL_NODE|ENTITY|ENUMERATION)|MHASH_(RIPEMD(128|160|256|320)|GOST|MD([245])|SHA(1|224|256|384|512)|SNEFRU256|HAVAL(128|160|192|224|256)|CRC23(B)?|TIGER(1(?:28|60))?|WHIRLPOOL|ADLER32)|MYSQL_(BOTH|NUM|CLIENT_(SSL|COMPRESS|IGNORE_SPACE|INTERACTIVE|ASSOC))|MYSQLI_(REPORT_(STRICT|INDEX|OFF|ERROR|ALL)|REFRESH_(GRANT|MASTER|BACKUP_LOG|STATUS|SLAVE|HOSTS|THREADS|TABLES|LOG)|READ_DEFAULT_(FILE|GROUP)|(GROUP|MULTIPLE_KEY|BINARY|BLOB)_FLAG|BOTH|STMT_ATTR_(CURSOR_TYPE|UPDATE_MAX_LENGTH|PREFETCH_ROWS)|STORE_RESULT|SERVER_QUERY_(NO_((GOOD_)?INDEX_USED)|WAS_SLOW)|SET_(CHARSET_NAME|FLAG)|NO_(D(?:EFAULT_VALUE_FLAG|ATA))|NOT_NULL_FLAG|NUM(_FLAG)?|CURSOR_TYPE_(READ_ONLY|SCROLLABLE|NO_CURSOR|FOR_UPDATE)|CLIENT_(SSL|NO_SCHEMA|COMPRESS|IGNORE_SPACE|INTERACTIVE|FOUND_ROWS)|TYPE_(GEOMETRY|((MEDIUM|LONG|TINY)_)?BLOB|BIT|SHORT|STRING|SET|YEAR|NULL|NEWDECIMAL|NEWDATE|CHAR|TIME(STAMP)?|TINY|INT24|INTERVAL|DOUBLE|DECIMAL|DATE(TIME)?|ENUM|VAR_STRING|FLOAT|LONG(LONG)?)|TIME_STAMP_FLAG|INIT_COMMAND|ZEROFILL_FLAG|ON_UPDATE_NOW_FLAG|OPT_(NET_((CMD|READ)_BUFFER_SIZE)|CONNECT_TIMEOUT|INT_AND_FLOAT_NATIVE|LOCAL_INFILE)|DEBUG_TRACE_ENABLED|DATA_TRUNCATED|USE_RESULT|(ENUM|(PART|PRI|UNIQUE)_KEY|UNSIGNED)_FLAG|ASSOC|ASYNC|AUTO_INCREMENT_FLAG)|MCRYPT_(RC([26])|RIJNDAEL_(128|192|256)|RAND|GOST|XTEA|MODE_(STREAM|NOFB|CBC|CFB|OFB|ECB)|MARS|BLOWFISH(_COMPAT)?|SERPENT|SKIPJACK|SAFER(64|128|PLUS)|CRYPT|CAST_(128|256)|TRIPLEDES|THREEWAY|TWOFISH|IDEA|(3)?DES|DECRYPT|DEV_(U)?RANDOM|PANAMA|ENCRYPT|ENIGNA|WAKE|LOKI97|ARCFOUR(_IV)?)|STREAM_(REPORT_ERRORS|MUST_SEEK|MKDIR_RECURSIVE|BUFFER_(NONE|FULL|LINE)|SHUT_(RD)?WR|SOCK_(RDM|RAW|STREAM|SEQPACKET|DGRAM)|SERVER_(BIND|LISTEN)|NOTIFY_(REDIRECTED|RESOLVE|MIME_TYPE_IS|SEVERITY_(INFO|ERR|WARN)|COMPLETED|CONNECT|PROGRESS|FILE_SIZE_IS|FAILURE|AUTH_(RE(?:QUIRED|SULT)))|CRYPTO_METHOD_((SSLv2(3)?|SSLv3|TLS)_(CLIENT|SERVER))|CLIENT_((ASYNC_)?CONNECT|PERSISTENT)|CAST_(AS_STREAM|FOR_SELECT)|(I(?:GNORE|S))_URL|IPPROTO_(RAW|TCP|ICMP|IP|UDP)|OOB|OPTION_(READ_(BUFFER|TIMEOUT)|BLOCKING|WRITE_BUFFER)|URL_STAT_(LINK|QUIET)|USE_PATH|PEEK|PF_(INET(6)?|UNIX)|ENFORCE_SAFE_MODE|FILTER_(ALL|READ|WRITE))|SUNFUNCS_RET_(DOUBLE|STRING|TIMESTAMP)|SQLITE_(READONLY|ROW|MISMATCH|MISUSE|BOTH|BUSY|SCHEMA|NOMEM|NOTFOUND|NOTADB|NOLFS|NUM|CORRUPT|CONSTRAINT|CANTOPEN|TOOBIG|INTERRUPT|INTERNAL|IOERR|OK|DONE|PROTOCOL|PERM|ERROR|EMPTY|FORMAT|FULL|LOCKED|ABORT|ASSOC|AUTH)|SQLITE3_(BOTH|BLOB|NUM|NULL|TEXT|INTEGER|OPEN_(READ(ONLY|WRITE)|CREATE)|FLOAT_ASSOC)|CURL(M_(BAD_((EASY)?HANDLE)|CALL_MULTI_PERFORM|INTERNAL_ERROR|OUT_OF_MEMORY|OK)|MSG_DONE|SSH_AUTH_(HOST|NONE|DEFAULT|PUBLICKEY|PASSWORD|KEYBOARD)|CLOSEPOLICY_(SLOWEST|CALLBACK|OLDEST|LEAST_(RECENTLY_USED|TRAFFIC)|INFO_(REDIRECT_(COUNT|TIME)|REQUEST_SIZE|SSL_VERIFYRESULT|STARTTRANSFER_TIME|(S(?:IZE|PEED))_((?:DOWN|UP)LOAD)|HTTP_CODE|HEADER_(OUT|SIZE)|NAMELOOKUP_TIME|CONNECT_TIME|CONTENT_(TYPE|LENGTH_((?:DOWN|UP)LOAD))|CERTINFO|TOTAL_TIME|PRIVATE|PRETRANSFER_TIME|EFFECTIVE_URL|FILETIME)|OPT_(RESUME_FROM|RETURNTRANSFER|REDIR_PROTOCOLS|REFERER|READ(DATA|FUNCTION)|RANGE|RANDOM_FILE|MAX(CONNECTS|REDIRS)|BINARYTRANSFER|BUFFERSIZE|SSH_(HOST_PUBLIC_KEY_MD5|(P(?:RIVATE|UBLIC))_KEYFILE)|AUTH_TYPES)|SSL(CERT(TYPE|PASSWD)?|ENGINE(_DEFAULT)?|VERSION|KEY(TYPE|PASSWD)?)|SSL_(CIPHER_LIST|VERIFY(HOST|PEER))|STDERR|HTTP(GET|HEADER|200ALIASES|_VERSION|PROXYTUNNEL|AUTH)|HEADER(FUNCTION)?|NO(BODY|SIGNAL|PROGRESS)|NETRC|CRLF|CONNECTTIMEOUT(_MS)?|COOKIE(SESSION|JAR|FILE)?|CUSTOMREQUEST|CERTINFO|CLOSEPOLICY|CA(INFO|PATH)|TRANSFERTEXT|TCP_NODELAY|TIME(CONDITION|OUT(_MS)?|VALUE)|INTERFACE|INFILE(SIZE)?|IPRESOLVE|DNS_(CACHE_TIMEOUT|USE_GLOBAL_CACHE)|URL|USER(AGENT|PWD)|UNRESTRICTED_AUTH|UPLOAD|PRIVATE|PROGRESSFUNCTION|PROXY(TYPE|USERPWD|PORT|AUTH)?|PROTOCOLS|PORT|POST(REDIR|QUOTE|FIELDS)?|PUT|EGDSOCKET|ENCODING|VERBOSE|KRB4LEVEL|KEYPASSWD|QUOTE|FRESH_CONNECT|FTP(APPEND|LISTONLY|PORT|SSLAUTH)|FTP_(SSL|SKIP_PASV_IP|CREATE_MISSING_DIRS|USE_EP(RT|SV)|FILEMETHOD)|FILE(TIME)?|FORBID_REUSE|FOLLOWLOCATION|FAILONERROR|WRITE(FUNCTION|HEADER)|LOW_SPEED_(LIMIT|TIME)|AUTOREFERER)|PROXY_(HTTP|SOCKS([45]))|PROTO_(SCP|SFTP|HTTP(S)?|TELNET|TFTP|DICT|FTP(S)?|FILE|LDAP(S)?|ALL)|E_((RE(?:CV|AD))_ERROR|GOT_NOTHING|MALFORMAT_USER|BAD_(CONTENT_ENCODING|CALLING_ORDER|PASSWORD_ENTERED|FUNCTION_ARGUMENT)|SSH|SSL_(CIPHER|CONNECT_ERROR|CERTPROBLEM|CACERT|PEER_CERTIFICATE|ENGINE_(NOTFOUND|SETFAILED))|SHARE_IN_USE|SEND_ERROR|HTTP_(RANGE_ERROR|NOT_FOUND|PORT_FAILED|POST_ERROR)|COULDNT_(RESOLVE_(HOST|PROXY)|CONNECT)|TOO_MANY_REDIRECTS|TELNET_OPTION_SYNTAX|OBSOLETE|OUT_OF_MEMORY|OPERATION|TIMEOUTED|OK|URL_MALFORMAT(_USER)?|UNSUPPORTED_PROTOCOL|UNKNOWN_TELNET_OPTION|PARTIAL_FILE|FTP_(BAD_DOWNLOAD_RESUME|SSL_FAILED|COULDNT_(RETR_FILE|GET_SIZE|STOR_FILE|SET_(BINARY|ASCII)|USE_REST)|CANT_(GET_HOST|RECONNECT)|USER_PASSWORD_INCORRECT|PORT_FAILED|QUOTE_ERROR|WRITE_ERROR|WEIRD_((PASS|PASV|SERVER|USER)_REPLY|227_FORMAT)|ACCESS_DENIED)|FILESIZE_EXCEEDED|FILE_COULDNT_READ_FILE|FUNCTION_NOT_FOUND|FAILED_INIT|WRITE_ERROR|LIBRARY_NOT_FOUND|LDAP_(SEARCH_FAILED|CANNOT_BIND|INVALID_URL)|ABORTED_BY_CALLBACK)|VERSION_NOW|FTP(METHOD_(MULTI|SINGLE|NO)CWD|SSL_(ALL|NONE|CONTROL|TRY)|AUTH_(DEFAULT|SSL|TLS))|AUTH_(ANY(SAFE)?|BASIC|DIGEST|GSSNEGOTIATE|NTLM))|CURL_(HTTP_VERSION_(1_([01])|NONE)|NETRC_(REQUIRED|IGNORED|OPTIONAL)|TIMECOND_(IF(UN)?MODSINCE|LASTMOD)|IPRESOLVE_(V([46])|WHATEVER)|VERSION_(SSL|IPV6|KERBEROS4|LIBZ))|IMAGETYPE_(GIF|XBM|BMP|SWF|COUNT|TIFF_(MM|II)|ICO|IFF|UNKNOWN|JB2|JPX|JP2|JPC|JPEG(2000)?|PSD|PNG|WBMP)|INPUT_(REQUEST|GET|SERVER|SESSION|COOKIE|POST|ENV)|ICONV_(MIME_DECODE_(STRICT|CONTINUE_ON_ERROR)|IMPL|VERSION)|DNS_(MX|SRV|SOA|HINFO|NS|NAPTR|CNAME|TXT|PTR|ANY|ALL|AAAA|A(6)?)|DOM(STRING_SIZE_ERR)|DOM_((SYNTAX|HIERARCHY_REQUEST|NO_((?:MODIFICATION|DATA)_ALLOWED)|NOT_(FOUND|SUPPORTED)|NAMESPACE|INDEX_SIZE|USE_ATTRIBUTE|VALID_(MODIFICATION|STATE|CHARACTER|ACCESS)|PHP|VALIDATION|WRONG_DOCUMENT)_ERR)|JSON_(HEX_(TAG|QUOT|AMP|APOS)|NUMERIC_CHECK|ERROR_(SYNTAX|STATE_MISMATCH|NONE|CTRL_CHAR|DEPTH|UTF8)|FORCE_OBJECT)|PREG_((D_UTF8(_OFFSET)?|NO|INTERNAL|(BACKTRACK|RECURSION)_LIMIT)_ERROR|GREP_INVERT|SPLIT_(NO_EMPTY|(DELIM|OFFSET)_CAPTURE)|SET_ORDER|OFFSET_CAPTURE|PATTERN_ORDER)|PSFS_(PASS_ON|ERR_FATAL|FEED_ME|FLAG_(NORMAL|FLUSH_(CLOSE|INC)))|PCRE_VERSION|POSIX_(([FRWX])_OK|S_IF(REG|BLK|SOCK|CHR|IFO))|FNM_(NOESCAPE|CASEFOLD|PERIOD|PATHNAME)|FILTER_(REQUIRE_(SCALAR|ARRAY)|NULL_ON_FAILURE|CALLBACK|DEFAULT|UNSAFE_RAW|SANITIZE_(MAGIC_QUOTES|STRING|STRIPPED|SPECIAL_CHARS|NUMBER_(INT|FLOAT)|URL|EMAIL|ENCODED|FULL_SPCIAL_CHARS)|VALIDATE_(REGEXP|BOOLEAN|INT|IP|URL|EMAIL|FLOAT)|FORCE_ARRAY|FLAG_(SCHEME_REQUIRED|STRIP_(BACKTICK|HIGH|LOW)|HOST_REQUIRED|NONE|NO_(RES|PRIV)_RANGE|ENCODE_QUOTES|IPV([46])|PATH_REQUIRED|EMPTY_STRING_NULL|ENCODE_(HIGH|LOW|AMP)|QUERY_REQUIRED|ALLOW_(SCIENTIFIC|HEX|THOUSAND|OCTAL|FRACTION)))|FILE_(BINARY|SKIP_EMPTY_LINES|NO_DEFAULT_CONTEXT|TEXT|IGNORE_NEW_LINES|USE_INCLUDE_PATH|APPEND)|FILEINFO_(RAW|MIME(_(ENCODING|TYPE))?|SYMLINK|NONE|CONTINUE|DEVICES|PRESERVE_ATIME)|FORCE_(DEFLATE|GZIP)|LIBXML_(XINCLUDE|NSCLEAN|NO(XMLDECL|BLANKS|NET|CDATA|ERROR|EMPTYTAG|ENT|WARNING)|COMPACT|DTD(VALID|LOAD|ATTR)|((DOTTED|LOADED)_)?VERSION|PARSEHUGE|ERR_(NONE|ERROR|FATAL|WARNING)))\\\\\\\\b\",\"name\":\"support.constant.ext.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"match\":\"(\\\\\\\\\\\\\\\\)?\\\\\\\\b(T_(RETURN|REQUIRE(_ONCE)?|GOTO|GLOBAL|(MINUS|MOD|MUL|XOR)_EQUAL|METHOD_C|ML_COMMENT|BREAK|BOOL_CAST|BOOLEAN_(AND|OR)|BAD_CHARACTER|SR(_EQUAL)?|STRING(_CAST|VARNAME)?|START_HEREDOC|STATIC|SWITCH|SL(_EQUAL)?|HALT_COMPILER|NS_(C|SEPARATOR)|NUM_STRING|NEW|NAMESPACE|CHARACTER|COMMENT|CONSTANT(_ENCAPSED_STRING)?|CONCAT_EQUAL|CONTINUE|CURLY_OPEN|CLOSE_TAG|CLONE|CLASS(_C)?|CASE|CATCH|TRY|THROW|IMPLEMENTS|ISSET|IS_((GREATER|SMALLER)_OR_EQUAL|(NOT_)?(IDENTICAL|EQUAL))|INSTANCEOF|INCLUDE(_ONCE)?|INC|INT_CAST|INTERFACE|INLINE_HTML|IF|OR_EQUAL|OBJECT_(CAST|OPERATOR)|OPEN_TAG(_WITH_ECHO)?|OLD_FUNCTION|DNUMBER|DIR|DIV_EQUAL|DOC_COMMENT|DOUBLE_(ARROW|CAST|COLON)|DOLLAR_OPEN_CURLY_BRACES|DO|DEC|DECLARE|DEFAULT|USE|UNSET(_CAST)?|PRINT|PRIVATE|PROTECTED|PUBLIC|PLUS_EQUAL|PAAMAYIM_NEKUDOTAYIM|EXTENDS|EXIT|EMPTY|ENCAPSED_AND_WHITESPACE|END(SWITCH|IF|DECLARE|FOR(EACH)?|WHILE)|END_HEREDOC|ECHO|EVAL|ELSE(IF)?|VAR(IABLE)?|FINAL|FILE|FOR(EACH)?|FUNC_C|FUNCTION|WHITESPACE|WHILE|LNUMBER|LIST|LINE|LOGICAL_(AND|OR|XOR)|ARRAY_(CAST)?|ABSTRACT|AS|AND_EQUAL))\\\\\\\\b\",\"name\":\"support.constant.parser-token.php\"},{\"match\":\"(?i)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"name\":\"constant.other.php\"}]},\"function-call\":{\"patterns\":[{\"begin\":\"(\\\\\\\\\\\\\\\\?(?<![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])[A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*(?:\\\\\\\\\\\\\\\\[A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)+)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"include\":\"#namespace\"},{\"match\":\"(?i)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"name\":\"entity.name.function.php\"}]},\"2\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"name\":\"meta.function-call.php\",\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"begin\":\"(\\\\\\\\\\\\\\\\)?(?<![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])([A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"include\":\"#namespace\"}]},\"2\":{\"patterns\":[{\"include\":\"#support\"},{\"match\":\"(?i)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"name\":\"entity.name.function.php\"}]},\"3\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"name\":\"meta.function-call.php\",\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"match\":\"(?i)\\\\\\\\b(print|echo)\\\\\\\\b\",\"name\":\"support.function.construct.output.php\"}]},\"function-parameters\":{\"patterns\":[{\"include\":\"#attribute\"},{\"include\":\"#comments\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"},{\"captures\":{\"1\":{\"patterns\":[{\"include\":\"#php-types\"}]},\"2\":{\"name\":\"variable.other.php\"},\"3\":{\"name\":\"storage.modifier.reference.php\"},\"4\":{\"name\":\"keyword.operator.variadic.php\"},\"5\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)(?:((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)\\\\\\\\s+)?((?:(&)\\\\\\\\s*)?(\\\\\\\\.\\\\\\\\.\\\\\\\\.)(\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?=\\\\\\\\s*(?:[),]|/[*/]|#|$))\",\"name\":\"meta.function.parameter.variadic.php\"},{\"begin\":\"(?i)((?:\\\\\\\\?\\\\\\\\s*)?[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\))(?:\\\\\\\\s*[\\\\\\\\&|]\\\\\\\\s*(?:[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+|\\\\\\\\(\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(?:\\\\\\\\s*&\\\\\\\\s*[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)+\\\\\\\\s*\\\\\\\\)))+)\\\\\\\\s+((?:(&)\\\\\\\\s*)?(\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\",\"beginCaptures\":{\"1\":{\"patterns\":[{\"include\":\"#php-types\"}]},\"2\":{\"name\":\"variable.other.php\"},\"3\":{\"name\":\"storage.modifier.reference.php\"},\"4\":{\"name\":\"punctuation.definition.variable.php\"}},\"end\":\"(?=\\\\\\\\s*(?:[),]|/[*/]|#))\",\"name\":\"meta.function.parameter.typehinted.php\",\"patterns\":[{\"begin\":\"=\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.assignment.php\"}},\"end\":\"(?=\\\\\\\\s*(?:[),]|/[*/]|#))\",\"patterns\":[{\"include\":\"#parameter-default-types\"}]}]},{\"captures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"storage.modifier.reference.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)((?:(&)\\\\\\\\s*)?(\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?=\\\\\\\\s*(?:[),]|/[*/]|#|$))\",\"name\":\"meta.function.parameter.no-default.php\"},{\"begin\":\"(?i)((?:(&)\\\\\\\\s*)?(\\\\\\\\$)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(=)\\\\\\\\s*\",\"beginCaptures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"storage.modifier.reference.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"},\"4\":{\"name\":\"keyword.operator.assignment.php\"}},\"end\":\"(?=\\\\\\\\s*(?:[),]|/[*/]|#))\",\"name\":\"meta.function.parameter.default.php\",\"patterns\":[{\"include\":\"#parameter-default-types\"}]}]},\"heredoc\":{\"patterns\":[{\"begin\":\"(?i)(?=<<<\\\\\\\\s*(\\\\\"?)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(\\\\\\\\1)\\\\\\\\s*$)\",\"end\":\"(?!\\\\\\\\G)\",\"name\":\"string.unquoted.heredoc.php\",\"patterns\":[{\"include\":\"#heredoc_interior\"}]},{\"begin\":\"(?=<<<\\\\\\\\s*'([A-Z_a-z]+[0-9A-Z_a-z]*)'\\\\\\\\s*$)\",\"end\":\"(?!\\\\\\\\G)\",\"name\":\"string.unquoted.nowdoc.php\",\"patterns\":[{\"include\":\"#nowdoc_interior\"}]}]},\"heredoc_interior\":{\"patterns\":[{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(HTML)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.html\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.html\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"text.html.basic\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(XML)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.xml\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.xml\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"text.xml\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)([DS]QL)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.sql\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.sql\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"source.sql\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(J(?:AVASCRIPT|S))(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.js\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.js\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"source.js\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(JSON)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.json\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.json\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"source.json\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(CSS)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.css\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.css\",\"patterns\":[{\"include\":\"#interpolation\"},{\"include\":\"source.css\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(REGEXP?)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"string.regexp.heredoc.php\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"patterns\":[{\"include\":\"#interpolation\"},{\"match\":\"(\\\\\\\\\\\\\\\\){1,2}[]$.\\\\\\\\[^{}]\",\"name\":\"constant.character.escape.regex.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.arbitrary-repitition.php\"},\"3\":{\"name\":\"punctuation.definition.arbitrary-repitition.php\"}},\"match\":\"(\\\\\\\\{)\\\\\\\\d+(,\\\\\\\\d+)?(})\",\"name\":\"string.regexp.arbitrary-repitition.php\"},{\"begin\":\"\\\\\\\\[(?:\\\\\\\\^?])?\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.character-class.php\"}},\"end\":\"]\",\"name\":\"string.regexp.character-class.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\[]'\\\\\\\\[\\\\\\\\\\\\\\\\]\",\"name\":\"constant.character.escape.php\"}]},{\"match\":\"[$*+^]\",\"name\":\"keyword.operator.regexp.php\"},{\"begin\":\"(?i)(?<=^|\\\\\\\\s)(#)\\\\\\\\s(?=[-\\\\\\\\t !,.0-9?_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}[^\\\\\\\\x00-\\\\\\\\x7F]]*$)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"$\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"name\":\"comment.line.number-sign.php\"}]},{\"begin\":\"(<<<)\\\\\\\\s*(\\\\\"?)(BLADE)(\\\\\\\\2)(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.html.php.blade\",\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"name\":\"meta.embedded.php.blade\",\"patterns\":[{\"include\":\"#interpolation\"}]},{\"begin\":\"(?i)(<<<)\\\\\\\\s*(\\\\\"?)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+[0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(\\\\\\\\2)(\\\\\\\\s*)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.php\"},\"3\":{\"name\":\"keyword.operator.heredoc.php\"},\"5\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"end\":\"^\\\\\\\\s*(\\\\\\\\3)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"keyword.operator.heredoc.php\"}},\"patterns\":[{\"include\":\"#interpolation\"}]}]},\"inheritance-single\":{\"patterns\":[{\"begin\":\"(?i)(?=\\\\\\\\\\\\\\\\?[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\\\\\\\\\\\\\\\\)\",\"end\":\"(?i)([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(?=[^0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"entity.other.inherited-class.php\"}},\"patterns\":[{\"include\":\"#namespace\"}]},{\"include\":\"#class-builtin\"},{\"include\":\"#namespace\"},{\"match\":\"(?i)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"name\":\"entity.other.inherited-class.php\"}]},\"instantiation\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"keyword.other.new.php\"},\"2\":{\"patterns\":[{\"match\":\"(?i)(parent|static|self)(?![0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"name\":\"storage.type.php\"},{\"include\":\"#class-name\"},{\"include\":\"#variable-name\"}]}},\"match\":\"(?i)(new)\\\\\\\\s+(?!class\\\\\\\\b)([$0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)(?![(0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\"},{\"begin\":\"(?i)(new)\\\\\\\\s+(?!class\\\\\\\\b)([$0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.new.php\"},\"2\":{\"patterns\":[{\"match\":\"(?i)(parent|static|self)(?![0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"name\":\"storage.type.php\"},{\"include\":\"#class-name\"},{\"include\":\"#variable-name\"}]},\"3\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"contentName\":\"meta.function-call.php\",\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]}]},\"interface-extends\":{\"patterns\":[{\"begin\":\"(?i)(extends)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"storage.modifier.extends.php\"}},\"end\":\"(?i)(?=\\\\\\\\{)\",\"patterns\":[{\"include\":\"#comments\"},{\"match\":\",\",\"name\":\"punctuation.separator.classes.php\"},{\"include\":\"#inheritance-single\"}]}]},\"interpolation\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\[0-7]{1,3}\",\"name\":\"constant.character.escape.octal.php\"},{\"match\":\"\\\\\\\\\\\\\\\\x\\\\\\\\h{1,2}\",\"name\":\"constant.character.escape.hex.php\"},{\"match\":\"\\\\\\\\\\\\\\\\u\\\\\\\\{\\\\\\\\h+}\",\"name\":\"constant.character.escape.unicode.php\"},{\"match\":\"\\\\\\\\\\\\\\\\[$\\\\\\\\\\\\\\\\efnrtv]\",\"name\":\"constant.character.escape.php\"},{\"begin\":\"\\\\\\\\{(?=\\\\\\\\$.*?})\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.variable.php\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.variable.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"include\":\"#variable-name\"}]},\"interpolation_double_quoted\":{\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\\\\\"\",\"name\":\"constant.character.escape.php\"},{\"include\":\"#interpolation\"}]},\"invoke-call\":{\"captures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)((\\\\\\\\$+)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?=\\\\\\\\s*\\\\\\\\()\",\"name\":\"meta.function-call.invoke.php\"},\"match_statement\":{\"patterns\":[{\"match\":\"\\\\\\\\s+(?=match\\\\\\\\b)\"},{\"begin\":\"\\\\\\\\bmatch\\\\\\\\b\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.match.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.section.match-block.end.bracket.curly.php\"}},\"name\":\"meta.match-statement.php\",\"patterns\":[{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.match-expression.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.match-expression.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.section.match-block.begin.bracket.curly.php\"}},\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"match\":\"=>\",\"name\":\"keyword.definition.arrow.php\"},{\"include\":\"$self\"}]}]}]},\"named-arguments\":{\"captures\":{\"1\":{\"name\":\"entity.name.variable.parameter.php\"},\"2\":{\"name\":\"punctuation.separator.colon.php\"}},\"match\":\"(?i)(?<=^|[(,])\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(:)(?!:)\"},\"namespace\":{\"begin\":\"(?i)(?:(namespace)|[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?(\\\\\\\\\\\\\\\\)\",\"beginCaptures\":{\"1\":{\"name\":\"variable.language.namespace.php\"},\"2\":{\"name\":\"punctuation.separator.inheritance.php\"}},\"end\":\"(?i)(?![0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\\\\\\\\\\\\\\\\)\",\"name\":\"support.other.namespace.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\",\"name\":\"punctuation.separator.inheritance.php\"}]},\"nowdoc_interior\":{\"patterns\":[{\"begin\":\"(<<<)\\\\\\\\s*'(HTML)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.html\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.html\",\"patterns\":[{\"include\":\"text.html.basic\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(XML)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.xml\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.xml\",\"patterns\":[{\"include\":\"text.xml\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'([DS]QL)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.sql\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.sql\",\"patterns\":[{\"include\":\"source.sql\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(J(?:AVASCRIPT|S))'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.js\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.js\",\"patterns\":[{\"include\":\"source.js\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(JSON)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.json\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.json\",\"patterns\":[{\"include\":\"source.json\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(CSS)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"source.css\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.css\",\"patterns\":[{\"include\":\"source.css\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(REGEXP?)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"string.regexp.nowdoc.php\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"patterns\":[{\"match\":\"(\\\\\\\\\\\\\\\\){1,2}[]$.\\\\\\\\[^{}]\",\"name\":\"constant.character.escape.regex.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.arbitrary-repitition.php\"},\"3\":{\"name\":\"punctuation.definition.arbitrary-repitition.php\"}},\"match\":\"(\\\\\\\\{)\\\\\\\\d+(,\\\\\\\\d+)?(})\",\"name\":\"string.regexp.arbitrary-repitition.php\"},{\"begin\":\"\\\\\\\\[(?:\\\\\\\\^?])?\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.character-class.php\"}},\"end\":\"]\",\"name\":\"string.regexp.character-class.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\[]'\\\\\\\\[\\\\\\\\\\\\\\\\]\",\"name\":\"constant.character.escape.php\"}]},{\"match\":\"[$*+^]\",\"name\":\"keyword.operator.regexp.php\"},{\"begin\":\"(?i)(?<=^|\\\\\\\\s)(#)\\\\\\\\s(?=[-\\\\\\\\t !,.0-9?_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}[^\\\\\\\\x00-\\\\\\\\x7F]]*$)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.comment.php\"}},\"end\":\"$\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.comment.php\"}},\"name\":\"comment.line.number-sign.php\"}]},{\"begin\":\"(<<<)\\\\\\\\s*'(BLADE)'(\\\\\\\\s*)$\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.begin.php\"},\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"contentName\":\"text.html.php.blade\",\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.embedded.end.php\"},\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}},\"name\":\"meta.embedded.php.blade\"},{\"begin\":\"(?i)(<<<)\\\\\\\\s*'([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+[0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)'(\\\\\\\\s*)\",\"beginCaptures\":{\"1\":{\"name\":\"punctuation.definition.string.php\"},\"2\":{\"name\":\"keyword.operator.nowdoc.php\"},\"3\":{\"name\":\"invalid.illegal.trailing-whitespace.php\"}},\"end\":\"^\\\\\\\\s*(\\\\\\\\2)(?![0-9A-Z_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"endCaptures\":{\"1\":{\"name\":\"keyword.operator.nowdoc.php\"}}}]},\"null_coalescing\":{\"match\":\"\\\\\\\\?\\\\\\\\?\",\"name\":\"keyword.operator.null-coalescing.php\"},\"numbers\":{\"patterns\":[{\"match\":\"0[Xx]\\\\\\\\h+(?:_\\\\\\\\h+)*\",\"name\":\"constant.numeric.hex.php\"},{\"match\":\"0[Bb][01]+(?:_[01]+)*\",\"name\":\"constant.numeric.binary.php\"},{\"match\":\"0[Oo][0-7]+(?:_[0-7]+)*\",\"name\":\"constant.numeric.octal.php\"},{\"match\":\"0(?:_?[0-7]+)+\",\"name\":\"constant.numeric.octal.php\"},{\"captures\":{\"1\":{\"name\":\"punctuation.separator.decimal.period.php\"},\"2\":{\"name\":\"punctuation.separator.decimal.period.php\"}},\"match\":\"(?:[0-9]+(?:_[0-9]+)*)?(\\\\\\\\.)[0-9]+(?:_[0-9]+)*(?:[Ee][-+]?[0-9]+(?:_[0-9]+)*)?|[0-9]+(?:_[0-9]+)*(\\\\\\\\.)(?:[0-9]+(?:_[0-9]+)*)?(?:[Ee][-+]?[0-9]+(?:_[0-9]+)*)?|[0-9]+(?:_[0-9]+)*[Ee][-+]?[0-9]+(?:_[0-9]+)*\",\"name\":\"constant.numeric.decimal.php\"},{\"match\":\"0|[1-9](?:_?[0-9]+)*\",\"name\":\"constant.numeric.decimal.php\"}]},\"object\":{\"patterns\":[{\"begin\":\"(\\\\\\\\??->)\\\\\\\\s*(\\\\\\\\$?\\\\\\\\{)\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"punctuation.definition.variable.php\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.variable.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"(?i)(\\\\\\\\??->)\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"entity.name.function.php\"},\"3\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"name\":\"meta.method-call.php\",\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"variable.other.property.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)(\\\\\\\\??->)\\\\\\\\s*((\\\\\\\\$+)?[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?\"}]},\"parameter-default-types\":{\"patterns\":[{\"include\":\"#strings\"},{\"include\":\"#numbers\"},{\"include\":\"#string-backtick\"},{\"include\":\"#variables\"},{\"match\":\"=>\",\"name\":\"keyword.operator.key.php\"},{\"match\":\"=\",\"name\":\"keyword.operator.assignment.php\"},{\"match\":\"&(?=\\\\\\\\s*\\\\\\\\$)\",\"name\":\"storage.modifier.reference.php\"},{\"begin\":\"(array)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"support.function.construct.php\"},\"2\":{\"name\":\"punctuation.definition.array.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.array.end.bracket.round.php\"}},\"name\":\"meta.array.php\",\"patterns\":[{\"include\":\"#parameter-default-types\"}]},{\"begin\":\"\\\\\\\\[\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.section.array.begin.php\"}},\"end\":\"]|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.section.array.end.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"include\":\"#instantiation\"},{\"begin\":\"(?i)(?=[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+(::)\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?)\",\"end\":\"(?i)(::)\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)?\",\"endCaptures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"constant.other.class.php\"}},\"patterns\":[{\"include\":\"#class-name\"}]},{\"include\":\"#constants\"}]},\"php-types\":{\"patterns\":[{\"match\":\"\\\\\\\\?\",\"name\":\"keyword.operator.nullable-type.php\"},{\"match\":\"[\\\\\\\\&|]\",\"name\":\"punctuation.separator.delimiter.php\"},{\"match\":\"(?i)\\\\\\\\b(null|int|float|bool|string|array|object|callable|iterable|true|false|mixed|void)\\\\\\\\b\",\"name\":\"keyword.other.type.php\"},{\"match\":\"(?i)\\\\\\\\b(parent|self)\\\\\\\\b\",\"name\":\"storage.type.php\"},{\"match\":\"\\\\\\\\(\",\"name\":\"punctuation.definition.type.begin.bracket.round.php\"},{\"match\":\"\\\\\\\\)\",\"name\":\"punctuation.definition.type.end.bracket.round.php\"},{\"include\":\"#class-name\"}]},\"php_doc\":{\"patterns\":[{\"match\":\"^(?!\\\\\\\\s*\\\\\\\\*).*?(?:(?=\\\\\\\\*/)|$\\\\\\\\n?)\",\"name\":\"invalid.illegal.missing-asterisk.phpdoc.php\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.phpdoc.php\"},\"3\":{\"name\":\"storage.modifier.php\"},\"4\":{\"name\":\"invalid.illegal.wrong-access-type.phpdoc.php\"}},\"match\":\"^\\\\\\\\s*\\\\\\\\*\\\\\\\\s*(@access)\\\\\\\\s+((p(?:ublic|rivate|rotected))|(.+))\\\\\\\\s*$\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.phpdoc.php\"},\"2\":{\"name\":\"markup.underline.link.php\"}},\"match\":\"(@xlink)\\\\\\\\s+(.+)\\\\\\\\s*$\"},{\"begin\":\"(@(?:global|param|property(-(read|write))?|return|throws|var))\\\\\\\\s+(?=[(?A-Z\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}])\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.phpdoc.php\"}},\"contentName\":\"meta.other.type.phpdoc.php\",\"end\":\"(?=\\\\\\\\s|\\\\\\\\*/)\",\"patterns\":[{\"include\":\"#php_doc_types_array_multiple\"},{\"include\":\"#php_doc_types_array_single\"},{\"include\":\"#php_doc_types\"},{\"match\":\"[\\\\\\\\&|]\",\"name\":\"punctuation.separator.delimiter.php\"}]},{\"match\":\"@(api|abstract|author|category|copyright|example|global|inherit[Dd]oc|internal|license|link|method|property(-(read|write))?|package|param|return|see|since|source|static|subpackage|throws|todo|var|version|uses|deprecated|final|ignore)\\\\\\\\b\",\"name\":\"keyword.other.phpdoc.php\"},{\"captures\":{\"1\":{\"name\":\"keyword.other.phpdoc.php\"}},\"match\":\"\\\\\\\\{(@(link|inherit[Dd]oc)).+?}\",\"name\":\"meta.tag.inline.phpdoc.php\"}]},\"php_doc_types\":{\"captures\":{\"0\":{\"patterns\":[{\"match\":\"\\\\\\\\?\",\"name\":\"keyword.operator.nullable-type.php\"},{\"match\":\"\\\\\\\\b(string|integer|int|boolean|bool|float|double|object|mixed|array|resource|void|null|callback|false|true|self|static)\\\\\\\\b\",\"name\":\"keyword.other.type.php\"},{\"include\":\"#class-name\"},{\"match\":\"[\\\\\\\\&|]\",\"name\":\"punctuation.separator.delimiter.php\"}]}},\"match\":\"(?i)\\\\\\\\??[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+([\\\\\\\\&|]\\\\\\\\??[0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)*\"},\"php_doc_types_array_multiple\":{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.type.begin.bracket.round.phpdoc.php\"}},\"end\":\"(\\\\\\\\))(\\\\\\\\[])?|(?=\\\\\\\\*/)\",\"endCaptures\":{\"1\":{\"name\":\"punctuation.definition.type.end.bracket.round.phpdoc.php\"},\"2\":{\"name\":\"keyword.other.array.phpdoc.php\"}},\"patterns\":[{\"include\":\"#php_doc_types_array_multiple\"},{\"include\":\"#php_doc_types_array_single\"},{\"include\":\"#php_doc_types\"},{\"match\":\"[\\\\\\\\&|]\",\"name\":\"punctuation.separator.delimiter.php\"}]},\"php_doc_types_array_single\":{\"captures\":{\"1\":{\"patterns\":[{\"include\":\"#php_doc_types\"}]},\"2\":{\"name\":\"keyword.other.array.phpdoc.php\"}},\"match\":\"(?i)([0-9\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]+)(\\\\\\\\[])\"},\"regex-double-quoted\":{\"begin\":\"\\\\\"/(?=(\\\\\\\\\\\\\\\\.|[^\\\\\"/])++/[ADSUXeimsux]*\\\\\")\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"end\":\"(/)([ADSUXeimsux]*)(\\\\\")\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.regexp.double-quoted.php\",\"patterns\":[{\"match\":\"(\\\\\\\\\\\\\\\\){1,2}[]$.\\\\\\\\[^{}]\",\"name\":\"constant.character.escape.regex.php\"},{\"include\":\"#interpolation_double_quoted\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.arbitrary-repetition.php\"},\"3\":{\"name\":\"punctuation.definition.arbitrary-repetition.php\"}},\"match\":\"(\\\\\\\\{)\\\\\\\\d+(,\\\\\\\\d+)?(})\",\"name\":\"string.regexp.arbitrary-repetition.php\"},{\"begin\":\"\\\\\\\\[(?:\\\\\\\\^?])?\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.character-class.php\"}},\"end\":\"]\",\"name\":\"string.regexp.character-class.php\",\"patterns\":[{\"include\":\"#interpolation_double_quoted\"}]},{\"match\":\"[$*+^]\",\"name\":\"keyword.operator.regexp.php\"}]},\"regex-single-quoted\":{\"begin\":\"'/(?=(\\\\\\\\\\\\\\\\(?:\\\\\\\\\\\\\\\\(?:\\\\\\\\\\\\\\\\['\\\\\\\\\\\\\\\\]?|[^'])|.)|[^'/])++/[ADSUXeimsux]*')\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"end\":\"(/)([ADSUXeimsux]*)(')\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.regexp.single-quoted.php\",\"patterns\":[{\"include\":\"#single_quote_regex_escape\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.arbitrary-repetition.php\"},\"3\":{\"name\":\"punctuation.definition.arbitrary-repetition.php\"}},\"match\":\"(\\\\\\\\{)\\\\\\\\d+(,\\\\\\\\d+)?(})\",\"name\":\"string.regexp.arbitrary-repetition.php\"},{\"begin\":\"\\\\\\\\[(?:\\\\\\\\^?])?\",\"captures\":{\"0\":{\"name\":\"punctuation.definition.character-class.php\"}},\"end\":\"]\",\"name\":\"string.regexp.character-class.php\"},{\"match\":\"[$*+^]\",\"name\":\"keyword.operator.regexp.php\"}]},\"scope-resolution\":{\"patterns\":[{\"captures\":{\"1\":{\"patterns\":[{\"match\":\"\\\\\\\\b(self|static|parent)\\\\\\\\b\",\"name\":\"storage.type.php\"},{\"include\":\"#class-name\"},{\"include\":\"#variable-name\"}]}},\"match\":\"([A-Z\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9A-Z\\\\\\\\\\\\\\\\_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(?=\\\\\\\\s*::)\"},{\"begin\":\"(?i)(::)\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(\\\\\\\\()\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"entity.name.function.php\"},\"3\":{\"name\":\"punctuation.definition.arguments.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.arguments.end.bracket.round.php\"}},\"name\":\"meta.method-call.static.php\",\"patterns\":[{\"include\":\"#named-arguments\"},{\"include\":\"$self\"}]},{\"captures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"keyword.other.class.php\"}},\"match\":\"(?i)(::)\\\\\\\\s*(class)\\\\\\\\b\"},{\"captures\":{\"1\":{\"name\":\"keyword.operator.class.php\"},\"2\":{\"name\":\"variable.other.class.php\"},\"3\":{\"name\":\"punctuation.definition.variable.php\"},\"4\":{\"name\":\"constant.other.class.php\"}},\"match\":\"(?i)(::)\\\\\\\\s*(?:((\\\\\\\\$+)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)|([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*))?\"}]},\"single_quote_regex_escape\":{\"match\":\"\\\\\\\\\\\\\\\\(?:\\\\\\\\\\\\\\\\(?:\\\\\\\\\\\\\\\\['\\\\\\\\\\\\\\\\]?|[^'])|.)\",\"name\":\"constant.character.escape.php\"},\"sql-string-double-quoted\":{\"begin\":\"\\\\\"\\\\\\\\s*(?=(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|AND|WITH)\\\\\\\\b)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"contentName\":\"source.sql.embedded.php\",\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.quoted.double.sql.php\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.sql\"}},\"match\":\"(#)(\\\\\\\\\\\\\\\\\\\\\"|[^\\\\\"])*(?=\\\\\"|$)\",\"name\":\"comment.line.number-sign.sql\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.sql\"}},\"match\":\"(--)(\\\\\\\\\\\\\\\\\\\\\"|[^\\\\\"])*(?=\\\\\"|$)\",\"name\":\"comment.line.double-dash.sql\"},{\"match\":\"\\\\\\\\\\\\\\\\[\\\\\"'\\\\\\\\\\\\\\\\\\`]\",\"name\":\"constant.character.escape.php\"},{\"match\":\"'(?=((\\\\\\\\\\\\\\\\')|[^\\\\\"'])*(\\\\\"|$))\",\"name\":\"string.quoted.single.unclosed.sql\"},{\"match\":\"\\`(?=((\\\\\\\\\\\\\\\\\\`)|[^\\\\\"\\`])*(\\\\\"|$))\",\"name\":\"string.quoted.other.backtick.unclosed.sql\"},{\"begin\":\"'\",\"end\":\"'\",\"name\":\"string.quoted.single.sql\",\"patterns\":[{\"include\":\"#interpolation_double_quoted\"}]},{\"begin\":\"\\`\",\"end\":\"\\`\",\"name\":\"string.quoted.other.backtick.sql\",\"patterns\":[{\"include\":\"#interpolation_double_quoted\"}]},{\"include\":\"#interpolation_double_quoted\"},{\"include\":\"source.sql\"}]},\"sql-string-single-quoted\":{\"begin\":\"'\\\\\\\\s*(?=(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|AND|WITH)\\\\\\\\b)\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"contentName\":\"source.sql.embedded.php\",\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.quoted.single.sql.php\",\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.sql\"}},\"match\":\"(#)(\\\\\\\\\\\\\\\\'|[^'])*(?='|$)\",\"name\":\"comment.line.number-sign.sql\"},{\"captures\":{\"1\":{\"name\":\"punctuation.definition.comment.sql\"}},\"match\":\"(--)(\\\\\\\\\\\\\\\\'|[^'])*(?='|$)\",\"name\":\"comment.line.double-dash.sql\"},{\"match\":\"\\\\\\\\\\\\\\\\[\\\\\"'\\\\\\\\\\\\\\\\\\`]\",\"name\":\"constant.character.escape.php\"},{\"match\":\"\\`(?=((\\\\\\\\\\\\\\\\\\`)|[^'\\`])*('|$))\",\"name\":\"string.quoted.other.backtick.unclosed.sql\"},{\"match\":\"\\\\\"(?=((\\\\\\\\\\\\\\\\\\\\\")|[^\\\\\"'])*('|$))\",\"name\":\"string.quoted.double.unclosed.sql\"},{\"include\":\"source.sql\"}]},\"string-backtick\":{\"begin\":\"\\`\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"end\":\"\\`\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.interpolated.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\\\`\",\"name\":\"constant.character.escape.php\"},{\"include\":\"#interpolation\"}]},\"string-double-quoted\":{\"begin\":\"\\\\\"\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"end\":\"\\\\\"\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.quoted.double.php\",\"patterns\":[{\"include\":\"#interpolation_double_quoted\"}]},\"string-single-quoted\":{\"begin\":\"'\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.begin.php\"}},\"end\":\"'\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.string.end.php\"}},\"name\":\"string.quoted.single.php\",\"patterns\":[{\"match\":\"\\\\\\\\\\\\\\\\['\\\\\\\\\\\\\\\\]\",\"name\":\"constant.character.escape.php\"}]},\"strings\":{\"patterns\":[{\"include\":\"#regex-double-quoted\"},{\"include\":\"#sql-string-double-quoted\"},{\"include\":\"#string-double-quoted\"},{\"include\":\"#regex-single-quoted\"},{\"include\":\"#sql-string-single-quoted\"},{\"include\":\"#string-single-quoted\"}]},\"support\":{\"patterns\":[{\"match\":\"(?i)\\\\\\\\bapc_(store|sma_info|compile_file|clear_cache|cas|cache_info|inc|dec|define_constants|delete(_file)?|exists|fetch|load_constants|add|bin_(dump|load)(file)?)\\\\\\\\b\",\"name\":\"support.function.apc.php\"},{\"match\":\"(?i)\\\\\\\\b(compact|count|current|end|extract|in_array|key(_exists)?|list|nat(case)?sort|next|pos|prev|range|reset|shuffle|sizeof|[ak]?r?sort|u[ak]?sort|array_(all|any|change_key_case|chunk|column|combine|count_values|fill(_keys)?|filter|find(_key)?|flip|is_list|key_(exists|first|last)|keys|map|multisort|pad|pop|product|push|rand|reduce|reverse|search|shift|slice|splice|sum|unique|unshift|values|u?(diff|intersect)(_u?(key|assoc))?|(walk|replace|merge)(_recursive)?))\\\\\\\\b\",\"name\":\"support.function.array.php\"},{\"match\":\"(?i)\\\\\\\\b(connection_(aborted|status)|constant|defined?|die|eval|exit|get_browser|__halt_compiler|highlight_(file|string)|hrtime|ignore_user_abort|pack|php_strip_whitespace|show_source|u?sleep|sys_getloadavg|time_(nanosleep|sleep_until)|uniqid|unpack)\\\\\\\\b\",\"name\":\"support.function.basic_functions.php\"},{\"match\":\"(?i)\\\\\\\\bbc(add|ceil|comp|(div|pow)(mod)?|floor|mod|mul|round|scale|sqrt|sub)\\\\\\\\b\",\"name\":\"support.function.bcmath.php\"},{\"match\":\"(?i)\\\\\\\\bblenc_encrypt\\\\\\\\b\",\"name\":\"support.function.blenc.php\"},{\"match\":\"(?i)\\\\\\\\bbz(compress|close|open|decompress|errstr|errno|error|flush|write|read)\\\\\\\\b\",\"name\":\"support.function.bz2.php\"},{\"match\":\"(?i)\\\\\\\\b((French|Gregorian|Jewish|Julian)ToJD|cal_(to_jd|info|days_in_month|from_jd)|unixtojd|jdto(unix|jewish)|easter_(da(?:te|ys))|JD(MonthName|To(Gregorian|Julian|French)|DayOfWeek))\\\\\\\\b\",\"name\":\"support.function.calendar.php\"},{\"match\":\"(?i)\\\\\\\\b(__autoload|class_alias|(class|interface|method|property|trait|enum)_exists|is_(a|subclass_of)|get_(class(_(vars|methods))?|(called|parent)_class|(mangled_)?object_vars|declared_(classes|interfaces|traits)))\\\\\\\\b\",\"name\":\"support.function.classobj.php\"},{\"match\":\"(?i)\\\\\\\\b(com_(create_guid|print_typeinfo|event_sink|load_typelib|get_active_object|message_pump)|variant_(sub|set(_type)?|not|neg|cast|cat|cmp|int|idiv|imp|or|div|date_(from|to)_timestamp|pow|eqv|fix|and|add|abs|round|get_type|xor|mod|mul))\\\\\\\\b\",\"name\":\"support.function.com.php\"},{\"match\":\"(?i)\\\\\\\\b(isset|unset|eval|empty|list)\\\\\\\\b\",\"name\":\"support.function.construct.php\"},{\"match\":\"(?i)\\\\\\\\b(print|echo)\\\\\\\\b\",\"name\":\"support.function.construct.output.php\"},{\"match\":\"(?i)\\\\\\\\bctype_(space|cntrl|digit|upper|punct|print|lower|alnum|alpha|graph|xdigit)\\\\\\\\b\",\"name\":\"support.function.ctype.php\"},{\"match\":\"(?i)\\\\\\\\bcurl_(close|copy_handle|errno|error|escape|exec|getinfo|init|pause|reset|setopt(_array)?|strerror|unescape|upkeep|version|multi_((add|remove)_handle|close|errno|exec|getcontent|info_read|init|select|setopt|strerror)|share_(close|errno|init(_persistent)?|setopt|strerror))\\\\\\\\b\",\"name\":\"support.function.curl.php\"},{\"match\":\"(?i)\\\\\\\\b(strtotime|str[fp]time|checkdate|time|timezone_name_(from_abbr|get)|idate|timezone_((location|offset|transitions|version)_get|(abbreviations|identifiers)_list|open)|date(_(sun(rise|set)|sun_info|sub|create(_immutable)?(_from_format)?|timestamp_[gs]et|timezone_[gs]et|time_set|isodate_set|interval_(create_from_date_string|format)|offset_get|diff|default_timezone_[gs]et|date_set|parse(_from_format)?|format|add|get_last_errors|modify))?|localtime|get(date|timeofday)|gm(strftime|date|mktime)|microtime|mktime)\\\\\\\\b\",\"name\":\"support.function.datetime.php\"},{\"match\":\"(?i)\\\\\\\\bdba_(sync|handlers|nextkey|close|insert|optimize|open|delete|popen|exists|key_split|firstkey|fetch|list|replace)\\\\\\\\b\",\"name\":\"support.function.dba.php\"},{\"match\":\"(?i)\\\\\\\\bdbx_(sort|connect|compare|close|escape_string|error|query|fetch_row)\\\\\\\\b\",\"name\":\"support.function.dbx.php\"},{\"match\":\"(?i)\\\\\\\\b(scandir|chdir|chroot|closedir|opendir|dir|rewinddir|readdir|getcwd)\\\\\\\\b\",\"name\":\"support.function.dir.php\"},{\"match\":\"(?i)\\\\\\\\beio_(sync(fs)?|sync_file_range|symlink|stat(vfs)?|sendfile|set_min_parallel|set_max_(idle|poll_(reqs|time)|parallel)|seek|n(threads|op|pending|reqs|ready)|chown|chmod|custom|close|cancel|truncate|init|open|dup2|unlink|utime|poll|event_loop|f(sync|stat(vfs)?|chown|chmod|truncate|datasync|utime|allocate)|write|lstat|link|rename|realpath|read(ahead|dir|link)?|rmdir|get_(event_stream|last_error)|grp(_(add|cancel|limit))?|mknod|mkdir|busy)\\\\\\\\b\",\"name\":\"support.function.eio.php\"},{\"match\":\"(?i)\\\\\\\\benchant_(dict_(store_replacement|suggest|check|is_in_session|describe|quick_check|add_to_(personal|session)|get_error)|broker_(set_ordering|init|dict_exists|describe|free(_dict)?|list_dicts|request_(pwl_)?dict|get_error))\\\\\\\\b\",\"name\":\"support.function.enchant.php\"},{\"match\":\"(?i)\\\\\\\\b(split(i)?|sql_regcase|ereg(i)?(_replace)?)\\\\\\\\b\",\"name\":\"support.function.ereg.php\"},{\"match\":\"(?i)\\\\\\\\b((restore|set)_(e(?:rror|xception))_handler|trigger_error|debug_(print_)?backtrace|user_error|error_(log|reporting|(clear|get)_last))\\\\\\\\b\",\"name\":\"support.function.errorfunc.php\"},{\"match\":\"(?i)\\\\\\\\b(shell_exec|system|passthru|proc_(nice|close|terminate|open|get_status)|escapeshell(arg|cmd)|exec)\\\\\\\\b\",\"name\":\"support.function.exec.php\"},{\"match\":\"(?i)\\\\\\\\b(exif_(thumbnail|tagname|imagetype|read_data)|read_exif_data)\\\\\\\\b\",\"name\":\"support.function.exif.php\"},{\"match\":\"(?i)\\\\\\\\bfann_((duplicate|length|merge|shuffle|subset)_train_data|scale_(train(_data)?|((?:in|out)put)(_train_data)?)|set_(scaling_params|sarprop_(step_error_(shift|threshold_factor)|temperature|weight_decay_shift)|cascade_(num_candidate_groups|candidate_(change_fraction|limit|stagnation_epochs)|output_(change_fraction|stagnation_epochs)|weight_multiplier|activation_(functions|steepnesses)|(m(?:ax|in))_(cand|out)_epochs)|callback|training_algorithm|train_(error|stop)_function|((?:in|out)put)_scaling_params|error_log|quickprop_(decay|mu)|weight(_array)?|learning_(momentum|rate)|bit_fail_limit|activation_(function|steepness)(_(hidden|layer|output))?|rprop_(((?:de|in)crease)_factor|delta_(max|min|zero)))|save(_train)?|num_((?:in|out)put)_train_data|copy|clear_scaling_params|cascadetrain_on_(file|data)|create_((s(?:parse|hortcut|tandard))(_array)?|train(_from_callback)?|from_file)|test(_data)?|train(_(on_(file|data)|epoch))?|init_weights|descale_(input|output|train)|destroy(_train)?|print_error|run|reset_(MSE|err(no|str))|read_train_from_file|randomize_weights|get_(sarprop_(step_error_(shift|threshold_factor)|temperature|weight_decay_shift)|num_(input|output|layers)|network_type|MSE|connection_(array|rate)|bias_array|bit_fail(_limit)?|cascade_(num_(candidate(?:s|_groups))|(candidate|output)_(change_fraction|limit|stagnation_epochs)|weight_multiplier|activation_(functions|steepnesses)(_count)?|(m(?:ax|in))_(cand|out)_epochs)|total_((?:connecti|neur)ons)|training_algorithm|train_(error|stop)_function|err(no|str)|quickprop_(decay|mu)|learning_(momentum|rate)|layer_array|activation_(function|steepness)|rprop_(((?:de|in)crease)_factor|delta_(max|min|zero))))\\\\\\\\b\",\"name\":\"support.function.fann.php\"},{\"match\":\"(?i)\\\\\\\\b(symlink|stat|set_file_buffer|chown|chgrp|chmod|copy|clearstatcache|touch|tempnam|tmpfile|is_(dir|(uploaded_)?file|executable|link|readable|writ(e)?able)|disk_(free|total)_space|diskfreespace|dirname|delete|unlink|umask|pclose|popen|pathinfo|parse_ini_(file|string)|fscanf|fstat|fseek|fnmatch|fclose|ftell|ftruncate|file(size|[acm]time|type|inode|owner|perms|group)?|file_(exists|(get|put)_contents)|f(open|puts|putcsv|passthru|eof|flush|write|lock|read|gets(s)?|getc(sv)?)|lstat|lchown|lchgrp|link(info)?|rename|rewind|read(file|link)|realpath(_cache_(get|size))?|rmdir|glob|move_uploaded_file|mkdir|basename|f(data)?sync)\\\\\\\\b\",\"name\":\"support.function.file.php\"},{\"match\":\"(?i)\\\\\\\\b(finfo_(set_flags|close|open|file|buffer)|mime_content_type)\\\\\\\\b\",\"name\":\"support.function.fileinfo.php\"},{\"match\":\"(?i)\\\\\\\\bfilter_(has_var|input(_array)?|id|var(_array)?|list)\\\\\\\\b\",\"name\":\"support.function.filter.php\"},{\"match\":\"(?i)\\\\\\\\b(f(?:astcgi_finish_request|pm_get_status))\\\\\\\\b\",\"name\":\"support.function.fpm.php\"},{\"match\":\"(?i)\\\\\\\\b(call_user_(func|method)(_array)?|create_function|unregister_tick_function|forward_static_call(_array)?|function_exists|func_(num_args|get_arg(s)?)|register_(shutdown|tick)_function|get_defined_functions)\\\\\\\\b\",\"name\":\"support.function.funchand.php\"},{\"match\":\"(?i)\\\\\\\\b((n)?gettext|textdomain|d((?:(n)?|c(n)?)gettext)|bind(textdomain|_textdomain_codeset))\\\\\\\\b\",\"name\":\"support.function.gettext.php\"},{\"match\":\"(?i)\\\\\\\\bgmp_(scan[01]|strval|sign|sub|setbit|sqrt(rem)?|hamdist|neg|nextprime|com|clrbit|cmp|testbit|intval|init|invert|import|or|div(exact)?|div_(qr??|r)|jacobi|popcount|pow(m)?|perfect_(square|power)|prob_prime|export|fact|legendre|and|add|abs|root(rem)?|random(_(bits|range|seed))?|gcd(ext)?|xor|mod|mul|binomial|kronecker|lcm)\\\\\\\\b\",\"name\":\"support.function.gmp.php\"},{\"match\":\"(?i)\\\\\\\\bhash(_(algos|copy|equals|file|final|hkdf|hmac(_(file|algos)?)?|init|pbkdf2|update(_(file|stream))?))?\\\\\\\\b\",\"name\":\"support.function.hash.php\"},{\"match\":\"(?i)\\\\\\\\b(http_(support|send_(status|stream|content_(disposition|type)|data|file|last_modified)|head|negotiate_(charset|content_type|language)|chunked_decode|cache_(etag|last_modified)|throttle|inflate|deflate|date|post_(data|fields)|put_(data|file|stream)|persistent_handles_(count|clean|ident)|parse_(cookie|headers|message|params)|redirect|request(_(method_(exists|name|(un)?register)|body_encode))?|get(_request_(headers|body(_stream)?))?|match_(etag|modified|request_header)|build_(cookie|str|url))|ob_(etag|deflate|inflate)handler)\\\\\\\\b\",\"name\":\"support.function.http.php\"},{\"match\":\"(?i)\\\\\\\\b(iconv(_(str(pos|len|rpos)|substr|[gs]et_encoding|mime_(decode(_headers)?|encode)))?|ob_iconv_handler)\\\\\\\\b\",\"name\":\"support.function.iconv.php\"},{\"match\":\"(?i)\\\\\\\\biis_((st(?:art|op))_(serv(?:ice|er))|set_(script_map|server_rights|dir_security|app_settings)|(add|remove)_server|get_(script_map|service_state|server_(rights|by_(comment|path))|dir_security))\\\\\\\\b\",\"name\":\"support.function.iisfunc.php\"},{\"match\":\"(?i)\\\\\\\\b(iptc(embed|parse)|(jpeg|png)2wbmp|gd_info|getimagesize(fromstring)?|image(s[xy]|scale|(char|string)(up)?|set(clip|style|thickness|tile|interpolation|pixel|brush)|savealpha|convolution|copy(resampled|resized|merge(gray)?)?|colors(forindex|total)|color(set|closest(alpha|hwb)?|transparent|deallocate|(allocate|exact|resolve)(alpha)?|at|match)|crop(auto)?|create(truecolor|from(avif|bmp|string|jpeg|png|wbmp|webp|gif|gd(2(part)?)?|tga|xpm|xbm))?|types|ttf(bbox|text)|truecolortopalette|istruecolor|interlace|2wbmp|destroy|dashedline|jpeg|_type_to_(extension|mime_type)|ps(slantfont|text|(encode|extend|free|load)font|bbox)|png|polygon|palette(copy|totruecolor)|ellipse|ft(text|bbox)|filter|fill|filltoborder|filled(arc|ellipse|polygon|rectangle)|font(height|width)|flip|webp|wbmp|line|loadfont|layereffect|antialias|affine(matrix(concat|get))?|alphablending|arc|rotate|rectangle|gif|gd2?|gammacorrect|grab(screen|window)|xbm|resolution|openpolygon|get(clip|interpolation)|avif|bmp))\\\\\\\\b\",\"name\":\"support.function.image.php\"},{\"match\":\"(?i)\\\\\\\\b(sys_get_temp_dir|set_(time_limit|include_path|magic_quotes_runtime)|cli_[gs]et_process_title|ini_(alter|get(_all)?|restore|set)|zend_(thread_id|version|logo_guid)|dl|php(credits|info|version)|php_(sapi_name|ini_(scanned_files|loaded_file)|uname|logo_guid)|putenv|extension_loaded|version_compare|assert(_options)?|restore_include_path|gc_(collect_cycles|disable|enable(d)?)|getopt|get_(cfg_var|current_user|defined_constants|extension_funcs|include_path|included_files|loaded_extensions|magic_quotes_(gpc|runtime)|required_files|resources)|get(env|lastmod|rusage|my(inode|[gpu]id))|memory_get_(peak_)?usage|main|magic_quotes_runtime)\\\\\\\\b\",\"name\":\"support.function.info.php\"},{\"match\":\"(?i)\\\\\\\\bibase_(set_event_handler|service_((?:at|de)tach)|server_info|num_(fields|params)|name_result|connect|commit(_ret)?|close|trans|delete_user|drop_db|db_info|pconnect|param_info|prepare|err(code|msg)|execute|query|field_info|fetch_(assoc|object|row)|free_(event_handler|query|result)|wait_event|add_user|affected_rows|rollback(_ret)?|restore|gen_id|modify_user|maintain_db|backup|blob_(cancel|close|create|import|info|open|echo|add|get))\\\\\\\\b\",\"name\":\"support.function.interbase.php\"},{\"match\":\"(?i)\\\\\\\\b(normalizer_(normalize|is_normalized)|idn_to_(unicode|utf8|ascii)|numfmt_(set_(symbol|(text_)?attribute|pattern)|create|(parse|format)(_currency)?|get_(symbol|(text_)?attribute|pattern|error_(code|message)|locale))|collator_(sort(_with_sort_keys)?|set_(attribute|strength)|compare|create|asort|get_(strength|sort_key|error_(code|message)|locale|attribute))|transliterator_(create(_(inverse|from_rules))?|transliterate|list_ids|get_error_(code|message))|intl(cal|tz)_get_error_(code|message)|intl_(is_failure|error_name|get_error_(code|message))|datefmt_(set_(calendar|lenient|pattern|timezone(_id)?)|create|is_lenient|parse|format(_object)?|localtime|get_(calendar(_object)?|time(type|zone(_id)?)|datetype|pattern|error_(code|message)|locale))|locale_(set_default|compose|canonicalize|parse|filter_matches|lookup|accept_from_http|get_(script|display_(script|name|variant|language|region)|default|primary_language|keywords|all_variants|region))|resourcebundle_(create|count|locales|get(_(error_(code|message)))?)|grapheme_(str(i?str|r?i?pos|len|_split)|substr|extract)|msgfmt_(set_pattern|create|(format|parse)(_message)?|get_(pattern|error_(code|message)|locale)))\\\\\\\\b\",\"name\":\"support.function.intl.php\"},{\"match\":\"(?i)\\\\\\\\bjson_(decode|encode|last_error(_msg)?|validate)\\\\\\\\b\",\"name\":\"support.function.json.php\"},{\"match\":\"(?i)\\\\\\\\bldap_(start|tls|sort|search|sasl_bind|set_(option|rebind_proc)|(first|next)_(attribute|entry|reference)|connect|control_paged_result(_response)?|count_entries|compare|close|t61_to_8859|8859_to_t61|dn2ufn|delete|unbind|parse_(re(?:ference|sult))|escape|errno|err2str|error|explode_dn|bind|free_result|list|add|rename|read|get_(option|dn|entries|values(_len)?|attributes)|modify(_batch)?|mod_(add|del|replace))\\\\\\\\b\",\"name\":\"support.function.ldap.php\"},{\"match\":\"(?i)\\\\\\\\blibxml_(set_(streams_context|external_entity_loader)|clear_errors|disable_entity_loader|use_internal_errors|get_(errors|last_error))\\\\\\\\b\",\"name\":\"support.function.libxml.php\"},{\"match\":\"(?i)\\\\\\\\b(ezmlm_hash|mail)\\\\\\\\b\",\"name\":\"support.function.mail.php\"},{\"match\":\"(?i)\\\\\\\\b(a?(cos|sin|tan)h?|sqrt|srand|hypot|hexdec|ceil|is_(nan|(in)?finite)|octdec|dec(hex|oct|bin)|deg2rad|pi|pow|exp(m1)?|floor|f(div|mod|pow)|lcg_value|log(1[0p])?|atan2|abs|round|rand|rad2deg|getrandmax|mt_(srand|rand|getrandmax)|max|min|bindec|base_convert|intdiv)\\\\\\\\b\",\"name\":\"support.function.math.php\"},{\"match\":\"(?i)\\\\\\\\bmb_(str(cut|str|to(lower|upper)|istr|ipos|imwidth|pos|width|len|rchr|richr|ripos|rpos|_pad|_split)|substitute_character|substr(_count)?|split|send_mail|http_((?:in|out)put)|check_encoding|convert_(case|encoding|kana|variables)|internal_encoding|output_handler|decode_(numericentity|mimeheader)|detect_(encoding|order)|parse_str|preferred_mime_name|encoding_aliases|encode_(numericentity|mimeheader)|ereg(i(_replace)?)?|ereg_(search(_(get(pos|regs)|init|regs|(set)?pos))?|replace(_callback)?|match)|list_encodings|language|regex_(set_options|encoding)|get_info|[lr]?trim|[lu]cfirst|ord|chr|scrub)\\\\\\\\b\",\"name\":\"support.function.mbstring.php\"},{\"match\":\"(?i)\\\\\\\\b(m(?:crypt_(cfb|create_iv|cbc|ofb|decrypt|encrypt|ecb|list_(algorithms|modes)|generic(_((de)?init|end))?|enc_(self_test|is_block_(algorithm|algorithm_mode|mode)|get_(supported_key_sizes|(block|iv|key)_size|(algorithms|modes)_name))|get_(cipher_name|(block|iv|key)_size)|module_(close|self_test|is_block_(algorithm|algorithm_mode|mode)|open|get_(supported_key_sizes|algo_(block|key)_size)))|decrypt_generic))\\\\\\\\b\",\"name\":\"support.function.mcrypt.php\"},{\"match\":\"(?i)\\\\\\\\bmemcache_debug\\\\\\\\b\",\"name\":\"support.function.memcache.php\"},{\"match\":\"(?i)\\\\\\\\bmhash(_(count|keygen_s2k|get_(hash_name|block_size)))?\\\\\\\\b\",\"name\":\"support.function.mhash.php\"},{\"match\":\"(?i)\\\\\\\\b(log_(cmd_(insert|delete|update)|killcursor|write_batch|reply|getmore)|bson_((?:de|en)code))\\\\\\\\b\",\"name\":\"support.function.mongo.php\"},{\"match\":\"(?i)\\\\\\\\bmysql_(stat|set_charset|select_db|num_(fields|rows)|connect|client_encoding|close|create_db|escape_string|thread_id|tablename|insert_id|info|data_seek|drop_db|db_(name|query)|unbuffered_query|pconnect|ping|errno|error|query|field_(seek|name|type|table|flags|len)|fetch_(object|field|lengths|assoc|array|row)|free_result|list_(tables|dbs|processes|fields)|affected_rows|result|real_escape_string|get_(client|host|proto|server)_info)\\\\\\\\b\",\"name\":\"support.function.mysql.php\"},{\"match\":\"(?i)\\\\\\\\bmysqli_(ssl_set|store_result|stat|send_(query|long_data)|set_(charset|opt|local_infile_(default|handler))|stmt_(store_result|send_long_data|next_result|close|init|data_seek|prepare|execute|fetch|free_result|attr_[gs]et|result_metadata|reset|get_(result|warnings)|more_results|bind_(param|result))|select_db|slave_query|savepoint|next_result|change_user|character_set_name|connect|commit|client_encoding|close|thread_safe|init|options|((?:en|dis)able)_(r(?:eads_from_master|pl_parse))|dump_debug_info|debug|data_seek|use_result|ping|poll|param_count|prepare|escape_string|execute|embedded_server_(start|end)|kill|query|field_seek|free_result|autocommit|rollback|report|refresh|fetch(_(object|fields|field(_direct)?|assoc|all|array|row))?|rpl_(parse_enabled|probe|query_type)|release_savepoint|reap_async_query|real_(connect|escape_string|query)|more_results|multi_query|get_(charset|connection_stats|client_(stats|info|version)|cache_stats|warnings|links_stats|metadata)|master_query|bind_(param|result)|begin_transaction)\\\\\\\\b\",\"name\":\"support.function.mysqli.php\"},{\"match\":\"(?i)\\\\\\\\bmysqlnd_memcache_(set|get_config)\\\\\\\\b\",\"name\":\"support.function.mysqlnd-memcache.php\"},{\"match\":\"(?i)\\\\\\\\bmysqlnd_ms_(set_(user_pick_server|qos)|dump_servers|query_is_select|fabric_select_(shard|global)|get_(stats|last_(used_connection|gtid))|xa_(commit|rollback|gc|begin)|match_wild)\\\\\\\\b\",\"name\":\"support.function.mysqlnd-ms.php\"},{\"match\":\"(?i)\\\\\\\\bmysqlnd_qc_(set_(storage_handler|cache_condition|is_select|user_handlers)|clear_cache|get_(normalized_query_trace_log|core_stats|cache_info|query_trace_log|available_handlers))\\\\\\\\b\",\"name\":\"support.function.mysqlnd-qc.php\"},{\"match\":\"(?i)\\\\\\\\bmysqlnd_uh_(set_(statement|connection)_proxy|convert_to_mysqlnd)\\\\\\\\b\",\"name\":\"support.function.mysqlnd-uh.php\"},{\"match\":\"(?i)\\\\\\\\b(syslog|socket_(set_(blocking|timeout)|get_status)|set(raw)?cookie|http_response_code|openlog|headers_(list|sent)|header(_(re(?:gister_callback|move)))?|checkdnsrr|closelog|inet_(ntop|pton)|ip2long|openlog|dns_(check_record|get_(record|mx))|define_syslog_variables|(p)?fsockopen|long2ip|get(servby(name|port)|host(name|by(name(l)?|addr))|protoby(n(?:ame|umber))|mxrr)|http_(clear|get)_last_response_headers|net_get_interfaces|request_parse_body)\\\\\\\\b\",\"name\":\"support.function.network.php\"},{\"match\":\"(?i)\\\\\\\\bnsapi_(virtual|response_headers|request_headers)\\\\\\\\b\",\"name\":\"support.function.nsapi.php\"},{\"match\":\"(?i)\\\\\\\\b(oci(?:(statementtype|setprefetch|serverversion|savelob(file)?|numcols|new(collection|cursor|descriptor)|nlogon|column(scale|size|name|type(raw)?|isnull|precision)|coll(size|trim|assign(elem)?|append|getelem|max)|commit|closelob|cancel|internaldebug|definebyname|plogon|parse|error|execute|fetch(statement|into)?|free(statement|collection|cursor|desc)|write(temporarylob|lobtofile)|loadlob|log(o(?:n|ff))|rowcount|rollback|result|bindbyname)|_(statement_type|set_(client_(i(?:nfo|dentifier))|prefetch|edition|action|module_name)|server_version|num_(fields|rows)|new_(connect|collection|cursor|descriptor)|connect|commit|client_version|close|cancel|internal_debug|define_by_name|pconnect|password_change|parse|error|execute|bind_(array_)?by_name|field_(scale|size|name|type(_raw)?|is_null|precision)|fetch(_(object|assoc|all|array|row))?|free_(statement|descriptor)|lob_(copy|is_equal)|rollback|result|get_implicit_resultset)))\\\\\\\\b\",\"name\":\"support.function.oci8.php\"},{\"match\":\"(?i)\\\\\\\\bopcache_(compile_file|invalidate|is_script_cached|reset|get_(status|configuration))\\\\\\\\b\",\"name\":\"support.function.opcache.php\"},{\"match\":\"(?i)\\\\\\\\bopenssl_(sign|spki_(new|export(_challenge)?|verify)|seal|csr_(sign|new|export(_to_file)?|get_(subject|public_key))|cipher_(iv|key)_length|open|dh_compute_key|digest|decrypt|public_((?:de|en)crypt)|encrypt|error_string|pkcs12_(export(_to_file)?|read)|(cms|pkcs7)_(sign|decrypt|encrypt|verify|read)|verify|free_key|random_pseudo_bytes|pkey_(derive|new|export(_to_file)?|free|get_(details|public|private))|private_((?:de|en)crypt)|pbkdf2|get_((cipher|md)_methods|cert_locations|curve_names|(p(?:ublic|rivate))key)|x509_(check_private_key|checkpurpose|parse|export(_to_file)?|fingerprint|free|read|verify))\\\\\\\\b\",\"name\":\"support.function.openssl.php\"},{\"match\":\"(?i)\\\\\\\\b(output_(add_rewrite_var|reset_rewrite_vars)|flush|ob_(start|clean|implicit_flush|end_(clean|flush)|flush|list_handlers|gzhandler|get_(status|contents|clean|flush|length|level)))\\\\\\\\b\",\"name\":\"support.function.output.php\"},{\"match\":\"(?i)\\\\\\\\bpassword_(algos|hash|needs_rehash|verify|get_info)\\\\\\\\b\",\"name\":\"support.function.password.php\"},{\"match\":\"(?i)\\\\\\\\bpcntl_(alarm|async_signals|errno|exec|r?fork|get_last_error|[gs]et((?:cpuaffin|prior)ity)|signal(_(dispatch|get_handler))?|sig(procmask|timedwait|waitinfo)|strerror|unshare|wait(p?id)?|wexitstatus|wif((?:exit|signal|stopp)ed)|w(stop|term)sig)\\\\\\\\b\",\"name\":\"support.function.pcntl.php\"},{\"match\":\"(?i)\\\\\\\\bpg_(socket|send_(prepare|execute|query(_params)?)|set_(client_encoding|error_verbosity)|select|host|num_(fields|rows)|consume_input|connection_(status|reset|busy)|connect(_poll)?|convert|copy_(from|to)|client_encoding|close|cancel_query|tty|transaction_status|trace|insert|options|delete|dbname|untrace|unescape_bytea|update|pconnect|ping|port|put_line|parameter_status|prepare|version|query(_params)?|escape_(string|identifier|literal|bytea)|end_copy|execute|flush|free_result|last_(notice|error|oid)|field_(size|num|name|type(_oid)?|table|is_null|prtlen)|affected_rows|result_(status|seek|error(_field)?)|fetch_(object|assoc|all(_columns)?|array|row|result)|get_(notify|pid|result)|meta_data|lo_(seek|close|create|tell|truncate|import|open|unlink|export|write|read(_all)?)|)\\\\\\\\b\",\"name\":\"support.function.pgsql.php\"},{\"match\":\"(?i)\\\\\\\\b(virtual|getallheaders|apache_([gs]etenv|note|child_terminate|lookup_uri|response_headers|reset_timeout|request_headers|get_(version|modules)))\\\\\\\\b\",\"name\":\"support.function.php_apache.php\"},{\"match\":\"(?i)\\\\\\\\bdom_import_simplexml\\\\\\\\b\",\"name\":\"support.function.php_dom.php\"},{\"match\":\"(?i)\\\\\\\\bftp_(ssl_connect|systype|site|size|set_option|nlist|nb_(continue|f?(put|get))|ch(dir|mod)|connect|cdup|close|delete|put|pwd|pasv|exec|quit|f(put|get)|login|alloc|rename|raw(list)?|rmdir|get(_option)?|mdtm|mkdir)\\\\\\\\b\",\"name\":\"support.function.php_ftp.php\"},{\"match\":\"(?i)\\\\\\\\bimap_((create|delete|list|rename|scan)(mailbox)?|status|sort|subscribe|set_quota|set(flag_full|acl)|search|savebody|num_(recent|msg)|check|close|clearflag_full|thread|timeout|open|header(info)?|headers|append|alerts|reopen|8bit|unsubscribe|undelete|utf7_((?:de|en)code)|utf8|uid|ping|errors|expunge|qprint|gc|fetch(structure|header|text|mime|body)|fetch_overview|lsub|list(s(?:can|ubscribed))|last_error|rfc822_(parse_(headers|adrlist)|write_address)|get(subscribed|acl|mailboxes)|get_quota(root)?|msgno|mime_header_decode|mail_(copy|compose|move)|mail|mailboxmsginfo|binary|body(struct)?|base64)\\\\\\\\b\",\"name\":\"support.function.php_imap.php\"},{\"match\":\"(?i)\\\\\\\\bmssql_(select_db|num_(fields|rows)|next_result|connect|close|init|data_seek|pconnect|execute|query|field_(seek|name|type|length)|fetch_(object|field|assoc|array|row|batch)|free_(statement|result)|rows_affected|result|guid_string|get_last_message|min_(error|message)_severity|bind)\\\\\\\\b\",\"name\":\"support.function.php_mssql.php\"},{\"match\":\"(?i)\\\\\\\\bodbc_(statistics|specialcolumns|setoption|num_(fields|rows)|next_result|connect|columns|columnprivileges|commit|cursor|close(_all)?|tables|tableprivileges|do|data_source|pconnect|primarykeys|procedures|procedurecolumns|prepare|error(msg)?|exec(ute)?|field_(scale|num|name|type|precision|len)|foreignkeys|free_result|fetch_(into|object|array|row)|longreadlen|autocommit|rollback|result(_all)?|gettypeinfo|binmode)\\\\\\\\b\",\"name\":\"support.function.php_odbc.php\"},{\"match\":\"(?i)\\\\\\\\bpreg_(split|quote|filter|last_error(_msg)?|replace(_callback(_array)?)?|grep|match(_all)?)\\\\\\\\b\",\"name\":\"support.function.php_pcre.php\"},{\"match\":\"(?i)\\\\\\\\b(spl_(classes|object_hash|autoload(_(call|unregister|extensions|functions|register))?)|class_(implements|uses|parents)|iterator_(count|to_array|apply))\\\\\\\\b\",\"name\":\"support.function.php_spl.php\"},{\"match\":\"(?i)\\\\\\\\bzip_(close|open|entry_(name|compressionmethod|compressedsize|close|open|filesize|read)|read)\\\\\\\\b\",\"name\":\"support.function.php_zip.php\"},{\"match\":\"(?i)\\\\\\\\bposix_(strerror|set(s|e?u|[ep]?g)id|ctermid|ttyname|times|isatty|initgroups|uname|errno|kill|e?access|get(sid|cwd|uid|pid|ppid|pwnam|pwuid|pgid|pgrp|euid|egid|login|rlimit|gid|grnam|groups|grgid)|get_last_error|mknod|mkfifo|(sys|f?path)conf|setrlimit)\\\\\\\\b\",\"name\":\"support.function.posix.php\"},{\"match\":\"(?i)\\\\\\\\bset(thread|proc)title\\\\\\\\b\",\"name\":\"support.function.proctitle.php\"},{\"match\":\"(?i)\\\\\\\\bpspell_(store_replacement|suggest|save_wordlist|new(_(config|personal))?|check|clear_session|config_(save_repl|create|ignore|(d(?:ata|ict))_dir|personal|runtogether|repl|mode)|add_to_(session|personal))\\\\\\\\b\",\"name\":\"support.function.pspell.php\"},{\"match\":\"(?i)\\\\\\\\breadline(_(completion_function|clear_history|callback_(handler_(install|remove)|read_char)|info|on_new_line|write_history|list_history|add_history|redisplay|read_history))?\\\\\\\\b\",\"name\":\"support.function.readline.php\"},{\"match\":\"(?i)\\\\\\\\brecode(_(string|file))?\\\\\\\\b\",\"name\":\"support.function.recode.php\"},{\"match\":\"(?i)\\\\\\\\brrd(c_disconnect|_(create|tune|info|update|error|version|first|fetch|last(update)?|restore|graph|xport))\\\\\\\\b\",\"name\":\"support.function.rrd.php\"},{\"match\":\"(?i)\\\\\\\\b(shm_((get|has|remove|put)_var|detach|attach|remove)|sem_(acquire|release|remove|get)|ftok|msg_((get|remove|set|stat)_queue|send|queue_exists|receive))\\\\\\\\b\",\"name\":\"support.function.sem.php\"},{\"match\":\"(?i)\\\\\\\\bsession_(status|start|set_(save_handler|cookie_params)|save_path|name|commit|cache_(expire|limiter)|is_registered|id|destroy|decode|unset|unregister|encode|write_close|abort|reset|register(_shutdown)?|((?:regener|cre)ate)_id|get_cookie_params|module_name|gc)\\\\\\\\b\",\"name\":\"support.function.session.php\"},{\"match\":\"(?i)\\\\\\\\bshmop_(size|close|open|delete|write|read)\\\\\\\\b\",\"name\":\"support.function.shmop.php\"},{\"match\":\"(?i)\\\\\\\\bsimplexml_(import_dom|load_(string|file))\\\\\\\\b\",\"name\":\"support.function.simplexml.php\"},{\"match\":\"(?i)\\\\\\\\b(snmp(?:(walk(oid)?|realwalk|get(next)?|set)|_(set_(valueretrieval|quick_print|enum_print|oid_(numeric_print|output_format))|read_mib|get_(valueretrieval|quick_print))|[23]_(set|walk|real_walk|get(next)?)))\\\\\\\\b\",\"name\":\"support.function.snmp.php\"},{\"match\":\"(?i)\\\\\\\\b(is_soap_fault|use_soap_error_handler)\\\\\\\\b\",\"name\":\"support.function.soap.php\"},{\"match\":\"(?i)\\\\\\\\bsocket_(accept|addrinfo_(bind|connect|explain|lookup)|atmark|bind|(clear|last)_error|close|cmsg_space|connect|create(_(listen|pair))?|(ex|im)port_stream|[gs]et_option|[gs]etopt|get(peer|sock)name|listen|read|recv(from|msg)?|select|send(msg|to)?|set_(non)?block|shutdown|strerror|write|wsaprotocol_info_(export|import|release))\\\\\\\\b\",\"name\":\"support.function.sockets.php\"},{\"match\":\"(?i)\\\\\\\\bsqlite_(single_query|seek|has_(more|prev)|num_(fields|rows)|next|changes|column|current|close|create_(aggregate|function)|open|unbuffered_query|udf_((?:de|en)code)_binary|popen|prev|escape_string|error_string|exec|valid|key|query|field_name|factory|fetch_(string|single|column_types|object|all|array)|lib(encoding|version)|last_(insert_rowid|error)|array_query|rewind|busy_timeout)\\\\\\\\b\",\"name\":\"support.function.sqlite.php\"},{\"match\":\"(?i)\\\\\\\\bsqlsrv_(send_stream_data|server_info|has_rows|num_(fields|rows)|next_result|connect|configure|commit|client_info|close|cancel|prepare|errors|execute|query|field_metadata|fetch(_(array|object))?|free_stmt|rows_affected|rollback|get_(config|field)|begin_transaction)\\\\\\\\b\",\"name\":\"support.function.sqlsrv.php\"},{\"match\":\"(?i)\\\\\\\\bstats_(harmonic_mean|covariance|standard_deviation|skew|cdf_(noncentral_(chisquare|f)|negative_binomial|chisquare|cauchy|t|uniform|poisson|exponential|f|weibull|logistic|laplace|gamma|binomial|beta)|stat_(noncentral_t|correlation|innerproduct|independent_t|powersum|percentile|paired_t|gennch|binomial_coef)|dens_(normal|negative_binomial|chisquare|cauchy|t|pmf_(hypergeometric|poisson|binomial)|exponential|f|weibull|logistic|laplace|gamma|beta)|den_uniform|variance|kurtosis|absolute_deviation|rand_(setall|phrase_to_seeds|ranf|get_seeds|gen_(noncentral_[ft]|noncenral_chisquare|normal|chisquare|t|int|i(uniform|poisson|binomial(_negative)?)|exponential|f(uniform)?|gamma|beta)))\\\\\\\\b\",\"name\":\"support.function.stats.php\"},{\"match\":\"(?i)\\\\\\\\bstream_(bucket_(new|prepend|append|make_writeable)|context_(create|[gs]et_(options?|default|params))|copy_to_stream|filter_((ap|pre)pend|register|remove)|get_(contents|filters|line|meta_data|transports|wrappers)|is(atty|_local)|notification_callback|register_wrapper|resolve_include_path|select|set_(blocking|chunk_size|(read|write)_buffer|timeout)|socket_(accept|client|enable_crypto|get_name|pair|recvfrom|sendto|server|shutdown)|supports_lock|wrapper_((un)?register|restore))\\\\\\\\b\",\"name\":\"support.function.streamsfuncs.php\"},{\"match\":\"(?i)\\\\\\\\b(money_format|md5(_file)?|metaphone|bin2hex|sscanf|sha1(_file)?|str(str|c?spn|n(at)?(case)?cmp|chr|coll|(case)?cmp|to(upper|lower)|tok|tr|istr|pos|pbrk|len|rchr|ri?pos|rev)|str_(getcsv|i?replace|pad|repeat|rot13|shuffle|split|word_count|contains|(starts|ends)_with|(in|de)crement)|strip(c?slashes|os)|strip_tags|similar_text|soundex|substr(_(count|compare|replace))?|setlocale|html(specialchars(_decode)?|entities)|html_entity_decode|hex2bin|hebrev(c)?|number_format|nl2br|nl_langinfo|chop|chunk_split|chr|convert_(cyr_string|uu((?:de|en)code))|count_chars|crypt|crc32|trim|implode|ord|uc(first|words)|join|parse_str|print(f)?|echo|explode|v?[fs]?printf|quoted_printable_((?:de|en)code)|quotemeta|wordwrap|lcfirst|[lr]trim|localeconv|levenshtein|addc?slashes|get_html_translation_table)\\\\\\\\b\",\"name\":\"support.function.string.php\"},{\"match\":\"(?i)\\\\\\\\bsybase_(set_message_handler|select_db|num_(fields|rows)|connect|close|deadlock_retry_count|data_seek|unbuffered_query|pconnect|query|field_seek|fetch_(object|field|assoc|array|row)|free_result|affected_rows|result|get_last_message|min_(client|error|message|server)_severity)\\\\\\\\b\",\"name\":\"support.function.sybase.php\"},{\"match\":\"(?i)\\\\\\\\b(taint|is_tainted|untaint)\\\\\\\\b\",\"name\":\"support.function.taint.php\"},{\"match\":\"(?i)\\\\\\\\b(tidy_([gs]etopt|set_encoding|save_config|config_count|clean_repair|is_(x(?:html|ml))|diagnose|(access|error|warning)_count|load_config|reset_config|(parse|repair)_(string|file)|get_(status|html(_ver)?|head|config|output|opt_doc|root|release|body))|ob_tidyhandler)\\\\\\\\b\",\"name\":\"support.function.tidy.php\"},{\"match\":\"(?i)\\\\\\\\btoken_(name|get_all)\\\\\\\\b\",\"name\":\"support.function.tokenizer.php\"},{\"match\":\"(?i)\\\\\\\\btrader_(stoch([fr]|rsi)?|stddev|sin(h)?|sum|sub|set_(compat|unstable_period)|sqrt|sar(ext)?|sma|ht_(sine|trend(line|mode)|dc(p(?:eriod|hase))|phasor)|natr|cci|cos(h)?|correl|cdl(shootingstar|shortline|sticksandwich|stalledpattern|spinningtop|separatinglines|hikkake(mod)?|highwave|homingpigeon|hangingman|harami(cross)?|hammer|concealbabyswall|counterattack|closingmarubozu|thrusting|tasukigap|takuri|tristar|inneck|invertedhammer|identical3crows|2crows|onneck|doji(star)?|darkcloudcover|dragonflydoji|unique3river|upsidegap2crows|3(starsinsouth|inside|outside|whitesoldiers|linestrike|blackcrows)|piercing|engulfing|evening(doji)?star|kicking(bylength)?|longline|longleggeddoji|ladderbottom|advanceblock|abandonedbaby|risefall3methods|rickshawman|gapsidesidewhite|gravestonedoji|xsidegap3methods|morning(doji)?star|mathold|matchinglow|marubozu|belthold|breakaway)|ceil|cmo|tsf|typprice|t3|tema|tan(h)?|trix|trima|trange|obv|div|dema|dx|ultosc|ppo|plus_d[im]|errno|exp|ema|var|kama|floor|wclprice|willr|wma|ln|log10|bop|beta|bbands|linearreg(_(slope|intercept|angle))?|asin|acos|atan|atr|adosc|add??|adx(r)?|apo|avgprice|aroon(osc)?|rsi|rocp??|rocr(100)?|get_(compat|unstable_period)|min(index)?|minus_d[im]|minmax(index)?|mid(p(?:oint|rice))|mom|mult|medprice|mfi|macd(ext|fix)?|mavp|max(index)?|ma(ma)?)\\\\\\\\b\",\"name\":\"support.function.trader.php\"},{\"match\":\"(?i)\\\\\\\\buopz_(copy|compose|implement|overload|delete|undefine|extend|function|flags|restore|rename|redefine|backup)\\\\\\\\b\",\"name\":\"support.function.uopz.php\"},{\"match\":\"(?i)\\\\\\\\b(http_build_query|(raw)?url((?:de|en)code)|parse_url|get_(headers|meta_tags)|base64_((?:de|en)code))\\\\\\\\b\",\"name\":\"support.function.url.php\"},{\"match\":\"(?i)\\\\\\\\b((bool|double|float|int|str)val|debug_zval_dump|empty|get_(debug_type|defined_vars|resource_(id|type))|[gs]ettype|is_(array|bool|callable|countable|double|float|int(eger)?|iterable|long|null|numeric|object|real|resource|scalar|string)|isset|print_r|(un)?serialize|unset|var_(dump|export))\\\\\\\\b\",\"name\":\"support.function.var.php\"},{\"match\":\"(?i)\\\\\\\\bwddx_(serialize_(va(?:lue|rs))|deserialize|packet_(start|end)|add_vars)\\\\\\\\b\",\"name\":\"support.function.wddx.php\"},{\"match\":\"(?i)\\\\\\\\bxhprof_(sample_)?((?:dis|en)able)\\\\\\\\b\",\"name\":\"support.function.xhprof.php\"},{\"match\":\"(?i)\\\\\\\\b(utf8_((?:de|en)code)|xml_(set_((notation|(end|start)_namespace|unparsed_entity)_decl_handler|(character_data|default|element|external_entity_ref|processing_instruction)_handler|object)|parse(_into_struct)?|parser_([gs]et_option|create(_ns)?|free)|error_string|get_(current_((column|line)_number|byte_index)|error_code)))\\\\\\\\b\",\"name\":\"support.function.xml.php\"},{\"match\":\"(?i)\\\\\\\\bxmlrpc_(server_(call_method|create|destroy|add_introspection_data|register_(introspection_callback|method))|is_fault|decode(_request)?|parse_method_descriptions|encode(_request)?|[gs]et_type)\\\\\\\\b\",\"name\":\"support.function.xmlrpc.php\"},{\"match\":\"(?i)\\\\\\\\bxmlwriter_((end|start|write)_(comment|cdata|dtd(_(attlist|entity|element))?|document|pi|attribute|element)|(start|write)_(attribute|element)_ns|write_raw|set_indent(_string)?|text|output_memory|open_(memory|uri)|full_end_element|flush|)\\\\\\\\b\",\"name\":\"support.function.xmlwriter.php\"},{\"match\":\"(?i)\\\\\\\\b(zlib_(decode|encode|get_coding_type)|readgzfile|gz(seek|compress|close|tell|inflate|open|decode|deflate|uncompress|puts|passthru|encode|eof|file|write|rewind|read|getc|getss?)|deflate_(add|init)|inflate_(add|get_(read_len|status)|init))\\\\\\\\b\",\"name\":\"support.function.zlib.php\"}]},\"switch_statement\":{\"patterns\":[{\"match\":\"\\\\\\\\s+(?=switch\\\\\\\\b)\"},{\"begin\":\"\\\\\\\\bswitch\\\\\\\\b(?!\\\\\\\\s*\\\\\\\\(.*\\\\\\\\)\\\\\\\\s*:)\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.control.switch.php\"}},\"end\":\"}|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.section.switch-block.end.bracket.curly.php\"}},\"name\":\"meta.switch-statement.php\",\"patterns\":[{\"begin\":\"\\\\\\\\(\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.switch-expression.begin.bracket.round.php\"}},\"end\":\"\\\\\\\\)|(?=\\\\\\\\?>)\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.switch-expression.end.bracket.round.php\"}},\"patterns\":[{\"include\":\"$self\"}]},{\"begin\":\"\\\\\\\\{\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.section.switch-block.begin.bracket.curly.php\"}},\"end\":\"(?=}|\\\\\\\\?>)\",\"patterns\":[{\"include\":\"$self\"}]}]}]},\"ternary_expression\":{\"begin\":\"\\\\\\\\?\",\"beginCaptures\":{\"0\":{\"name\":\"keyword.operator.ternary.php\"}},\"end\":\"(?<!:):(?!:)\",\"endCaptures\":{\"0\":{\"name\":\"keyword.operator.ternary.php\"}},\"patterns\":[{\"captures\":{\"1\":{\"patterns\":[{\"include\":\"$self\"}]}},\"match\":\"(?i)^\\\\\\\\s*([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)\\\\\\\\s*(?=:(?!:))\"},{\"include\":\"$self\"}]},\"ternary_shorthand\":{\"match\":\"\\\\\\\\?:\",\"name\":\"keyword.operator.ternary.php\"},\"use-inner\":{\"patterns\":[{\"include\":\"#comments\"},{\"begin\":\"(?i)\\\\\\\\b(as)\\\\\\\\s+\",\"beginCaptures\":{\"1\":{\"name\":\"keyword.other.use-as.php\"}},\"end\":\"(?i)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"endCaptures\":{\"0\":{\"name\":\"entity.other.alias.php\"}}},{\"include\":\"#class-name\"},{\"match\":\",\",\"name\":\"punctuation.separator.delimiter.php\"}]},\"var_basic\":{\"patterns\":[{\"captures\":{\"1\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)(\\\\\\\\$+)[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*\",\"name\":\"variable.other.php\"}]},\"var_global\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(\\\\\\\\$)((_(COOKIE|FILES|GET|POST|REQUEST))|arg([cv]))\\\\\\\\b\",\"name\":\"variable.other.global.php\"},\"var_global_safer\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(\\\\\\\\$)((GLOBALS|_(ENV|SERVER|SESSION)))\",\"name\":\"variable.other.global.safer.php\"},\"var_language\":{\"captures\":{\"1\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(\\\\\\\\$)this\\\\\\\\b\",\"name\":\"variable.language.this.php\"},\"variable-name\":{\"patterns\":[{\"include\":\"#var_global\"},{\"include\":\"#var_global_safer\"},{\"captures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"punctuation.definition.variable.php\"},\"4\":{\"name\":\"keyword.operator.class.php\"},\"5\":{\"name\":\"variable.other.property.php\"},\"6\":{\"name\":\"punctuation.section.array.begin.php\"},\"7\":{\"name\":\"constant.numeric.index.php\"},\"8\":{\"name\":\"variable.other.index.php\"},\"9\":{\"name\":\"punctuation.definition.variable.php\"},\"10\":{\"name\":\"string.unquoted.index.php\"},\"11\":{\"name\":\"punctuation.section.array.end.php\"}},\"match\":\"(?i)((\\\\\\\\$)(?<name>[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*))\\\\\\\\s*(?:(\\\\\\\\??->)\\\\\\\\s*(\\\\\\\\g<name>)|(\\\\\\\\[)(?:(\\\\\\\\d+)|((\\\\\\\\$)\\\\\\\\g<name>)|([_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*))(]))?\"},{\"captures\":{\"1\":{\"name\":\"variable.other.php\"},\"2\":{\"name\":\"punctuation.definition.variable.php\"},\"4\":{\"name\":\"punctuation.definition.variable.php\"}},\"match\":\"(?i)((\\\\\\\\$\\\\\\\\{)(?<name>[_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}][0-9_a-z\\\\\\\\x7F-\\\\\\\\x{10FFFF}]*)(}))\"}]},\"variables\":{\"patterns\":[{\"include\":\"#var_language\"},{\"include\":\"#var_global\"},{\"include\":\"#var_global_safer\"},{\"include\":\"#var_basic\"},{\"begin\":\"\\\\\\\\$\\\\\\\\{(?=.*?})\",\"beginCaptures\":{\"0\":{\"name\":\"punctuation.definition.variable.php\"}},\"end\":\"}\",\"endCaptures\":{\"0\":{\"name\":\"punctuation.definition.variable.php\"}},\"patterns\":[{\"include\":\"$self\"}]}]}},\"scopeName\":\"source.php\",\"embeddedLangs\":[\"html\",\"xml\",\"sql\",\"javascript\",\"json\",\"css\"]}`)),A_=[...k_,...$_,...Hl,...Ul,...Bl,...Gl,S_],T_=Object.freeze(JSON.parse('{\"colors\":{\"actionBar.toggledBackground\":\"#383a49\",\"activityBarBadge.background\":\"#007ACC\",\"checkbox.border\":\"#6B6B6B\",\"editor.background\":\"#1E1E1E\",\"editor.foreground\":\"#D4D4D4\",\"editor.inactiveSelectionBackground\":\"#3A3D41\",\"editor.selectionHighlightBackground\":\"#ADD6FF26\",\"editorIndentGuide.activeBackground1\":\"#707070\",\"editorIndentGuide.background1\":\"#404040\",\"input.placeholderForeground\":\"#A6A6A6\",\"list.activeSelectionIconForeground\":\"#FFF\",\"list.dropBackground\":\"#383B3D\",\"menu.background\":\"#252526\",\"menu.border\":\"#454545\",\"menu.foreground\":\"#CCCCCC\",\"menu.selectionBackground\":\"#0078d4\",\"menu.separatorBackground\":\"#454545\",\"ports.iconRunningProcessForeground\":\"#369432\",\"sideBarSectionHeader.background\":\"#0000\",\"sideBarSectionHeader.border\":\"#ccc3\",\"sideBarTitle.foreground\":\"#BBBBBB\",\"statusBarItem.remoteBackground\":\"#16825D\",\"statusBarItem.remoteForeground\":\"#FFF\",\"tab.lastPinnedBorder\":\"#ccc3\",\"tab.selectedBackground\":\"#222222\",\"tab.selectedForeground\":\"#ffffffa0\",\"terminal.inactiveSelectionBackground\":\"#3A3D41\",\"widget.border\":\"#303031\"},\"displayName\":\"Dark Plus\",\"name\":\"dark-plus\",\"semanticHighlighting\":true,\"semanticTokenColors\":{\"customLiteral\":\"#DCDCAA\",\"newOperator\":\"#C586C0\",\"numberLiteral\":\"#b5cea8\",\"stringLiteral\":\"#ce9178\"},\"tokenColors\":[{\"scope\":[\"meta.embedded\",\"source.groovy.embedded\",\"string meta.image.inline.markdown\",\"variable.legacy.builtin.python\"],\"settings\":{\"foreground\":\"#D4D4D4\"}},{\"scope\":\"emphasis\",\"settings\":{\"fontStyle\":\"italic\"}},{\"scope\":\"strong\",\"settings\":{\"fontStyle\":\"bold\"}},{\"scope\":\"header\",\"settings\":{\"foreground\":\"#000080\"}},{\"scope\":\"comment\",\"settings\":{\"foreground\":\"#6A9955\"}},{\"scope\":\"constant.language\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"constant.numeric\",\"variable.other.enummember\",\"keyword.operator.plus.exponent\",\"keyword.operator.minus.exponent\"],\"settings\":{\"foreground\":\"#b5cea8\"}},{\"scope\":\"constant.regexp\",\"settings\":{\"foreground\":\"#646695\"}},{\"scope\":\"entity.name.tag\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#d7ba7d\"}},{\"scope\":\"entity.other.attribute-name\",\"settings\":{\"foreground\":\"#9cdcfe\"}},{\"scope\":[\"entity.other.attribute-name.class.css\",\"source.css entity.other.attribute-name.class\",\"entity.other.attribute-name.id.css\",\"entity.other.attribute-name.parent-selector.css\",\"entity.other.attribute-name.parent.less\",\"source.css entity.other.attribute-name.pseudo-class\",\"entity.other.attribute-name.pseudo-element.css\",\"source.css.less entity.other.attribute-name.id\",\"entity.other.attribute-name.scss\"],\"settings\":{\"foreground\":\"#d7ba7d\"}},{\"scope\":\"invalid\",\"settings\":{\"foreground\":\"#f44747\"}},{\"scope\":\"markup.underline\",\"settings\":{\"fontStyle\":\"underline\"}},{\"scope\":\"markup.bold\",\"settings\":{\"fontStyle\":\"bold\",\"foreground\":\"#569cd6\"}},{\"scope\":\"markup.heading\",\"settings\":{\"fontStyle\":\"bold\",\"foreground\":\"#569cd6\"}},{\"scope\":\"markup.italic\",\"settings\":{\"fontStyle\":\"italic\"}},{\"scope\":\"markup.strikethrough\",\"settings\":{\"fontStyle\":\"strikethrough\"}},{\"scope\":\"markup.inserted\",\"settings\":{\"foreground\":\"#b5cea8\"}},{\"scope\":\"markup.deleted\",\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"markup.changed\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"punctuation.definition.quote.begin.markdown\",\"settings\":{\"foreground\":\"#6A9955\"}},{\"scope\":\"punctuation.definition.list.begin.markdown\",\"settings\":{\"foreground\":\"#6796e6\"}},{\"scope\":\"markup.inline.raw\",\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"punctuation.definition.tag\",\"settings\":{\"foreground\":\"#808080\"}},{\"scope\":[\"meta.preprocessor\",\"entity.name.function.preprocessor\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"meta.preprocessor.string\",\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"meta.preprocessor.numeric\",\"settings\":{\"foreground\":\"#b5cea8\"}},{\"scope\":\"meta.structure.dictionary.key.python\",\"settings\":{\"foreground\":\"#9cdcfe\"}},{\"scope\":\"meta.diff.header\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"storage\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"storage.type\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"storage.modifier\",\"keyword.operator.noexcept\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"string\",\"meta.embedded.assembly\"],\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"string.tag\",\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"string.value\",\"settings\":{\"foreground\":\"#ce9178\"}},{\"scope\":\"string.regexp\",\"settings\":{\"foreground\":\"#d16969\"}},{\"scope\":[\"punctuation.definition.template-expression.begin\",\"punctuation.definition.template-expression.end\",\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"meta.template.expression\"],\"settings\":{\"foreground\":\"#d4d4d4\"}},{\"scope\":[\"support.type.vendored.property-name\",\"support.type.property-name\",\"source.css variable\",\"source.coffee.embedded\"],\"settings\":{\"foreground\":\"#9cdcfe\"}},{\"scope\":\"keyword\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"keyword.control\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"keyword.operator\",\"settings\":{\"foreground\":\"#d4d4d4\"}},{\"scope\":[\"keyword.operator.new\",\"keyword.operator.expression\",\"keyword.operator.cast\",\"keyword.operator.sizeof\",\"keyword.operator.alignof\",\"keyword.operator.typeid\",\"keyword.operator.alignas\",\"keyword.operator.instanceof\",\"keyword.operator.logical.python\",\"keyword.operator.wordlike\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"keyword.other.unit\",\"settings\":{\"foreground\":\"#b5cea8\"}},{\"scope\":[\"punctuation.section.embedded.begin.php\",\"punctuation.section.embedded.end.php\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"support.function.git-rebase\",\"settings\":{\"foreground\":\"#9cdcfe\"}},{\"scope\":\"constant.sha.git-rebase\",\"settings\":{\"foreground\":\"#b5cea8\"}},{\"scope\":[\"storage.modifier.import.java\",\"variable.language.wildcard.java\",\"storage.modifier.package.java\"],\"settings\":{\"foreground\":\"#d4d4d4\"}},{\"scope\":\"variable.language\",\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":[\"entity.name.function\",\"support.function\",\"support.constant.handlebars\",\"source.powershell variable.other.member\",\"entity.name.operator.custom-literal\"],\"settings\":{\"foreground\":\"#DCDCAA\"}},{\"scope\":[\"support.class\",\"support.type\",\"entity.name.type\",\"entity.name.namespace\",\"entity.other.attribute\",\"entity.name.scope-resolution\",\"entity.name.class\",\"storage.type.numeric.go\",\"storage.type.byte.go\",\"storage.type.boolean.go\",\"storage.type.string.go\",\"storage.type.uintptr.go\",\"storage.type.error.go\",\"storage.type.rune.go\",\"storage.type.cs\",\"storage.type.generic.cs\",\"storage.type.modifier.cs\",\"storage.type.variable.cs\",\"storage.type.annotation.java\",\"storage.type.generic.java\",\"storage.type.java\",\"storage.type.object.array.java\",\"storage.type.primitive.array.java\",\"storage.type.primitive.java\",\"storage.type.token.java\",\"storage.type.groovy\",\"storage.type.annotation.groovy\",\"storage.type.parameters.groovy\",\"storage.type.generic.groovy\",\"storage.type.object.array.groovy\",\"storage.type.primitive.array.groovy\",\"storage.type.primitive.groovy\"],\"settings\":{\"foreground\":\"#4EC9B0\"}},{\"scope\":[\"meta.type.cast.expr\",\"meta.type.new.expr\",\"support.constant.math\",\"support.constant.dom\",\"support.constant.json\",\"entity.other.inherited-class\",\"punctuation.separator.namespace.ruby\"],\"settings\":{\"foreground\":\"#4EC9B0\"}},{\"scope\":[\"keyword.control\",\"source.cpp keyword.operator.new\",\"keyword.operator.delete\",\"keyword.other.using\",\"keyword.other.directive.using\",\"keyword.other.operator\",\"entity.name.operator\"],\"settings\":{\"foreground\":\"#C586C0\"}},{\"scope\":[\"variable\",\"meta.definition.variable.name\",\"support.variable\",\"entity.name.variable\",\"constant.other.placeholder\"],\"settings\":{\"foreground\":\"#9CDCFE\"}},{\"scope\":[\"variable.other.constant\",\"variable.other.enummember\"],\"settings\":{\"foreground\":\"#4FC1FF\"}},{\"scope\":[\"meta.object-literal.key\"],\"settings\":{\"foreground\":\"#9CDCFE\"}},{\"scope\":[\"support.constant.property-value\",\"support.constant.font-name\",\"support.constant.media-type\",\"support.constant.media\",\"constant.other.color.rgb-value\",\"constant.other.rgb-value\",\"support.constant.color\"],\"settings\":{\"foreground\":\"#CE9178\"}},{\"scope\":[\"punctuation.definition.group.regexp\",\"punctuation.definition.group.assertion.regexp\",\"punctuation.definition.character-class.regexp\",\"punctuation.character.set.begin.regexp\",\"punctuation.character.set.end.regexp\",\"keyword.operator.negation.regexp\",\"support.other.parenthesis.regexp\"],\"settings\":{\"foreground\":\"#CE9178\"}},{\"scope\":[\"constant.character.character-class.regexp\",\"constant.other.character-class.set.regexp\",\"constant.other.character-class.regexp\",\"constant.character.set.regexp\"],\"settings\":{\"foreground\":\"#d16969\"}},{\"scope\":[\"keyword.operator.or.regexp\",\"keyword.control.anchor.regexp\"],\"settings\":{\"foreground\":\"#DCDCAA\"}},{\"scope\":\"keyword.operator.quantifier.regexp\",\"settings\":{\"foreground\":\"#d7ba7d\"}},{\"scope\":[\"constant.character\",\"constant.other.option\"],\"settings\":{\"foreground\":\"#569cd6\"}},{\"scope\":\"constant.character.escape\",\"settings\":{\"foreground\":\"#d7ba7d\"}},{\"scope\":\"entity.name.label\",\"settings\":{\"foreground\":\"#C8C8C8\"}}],\"type\":\"dark\"}')),R_=Object.freeze(JSON.parse('{\"colors\":{\"actionBar.toggledBackground\":\"#dddddd\",\"activityBarBadge.background\":\"#007ACC\",\"checkbox.border\":\"#919191\",\"diffEditor.unchangedRegionBackground\":\"#f8f8f8\",\"editor.background\":\"#FFFFFF\",\"editor.foreground\":\"#000000\",\"editor.inactiveSelectionBackground\":\"#E5EBF1\",\"editor.selectionHighlightBackground\":\"#ADD6FF80\",\"editorIndentGuide.activeBackground1\":\"#939393\",\"editorIndentGuide.background1\":\"#D3D3D3\",\"editorSuggestWidget.background\":\"#F3F3F3\",\"input.placeholderForeground\":\"#767676\",\"list.activeSelectionIconForeground\":\"#FFF\",\"list.focusAndSelectionOutline\":\"#90C2F9\",\"list.hoverBackground\":\"#E8E8E8\",\"menu.border\":\"#D4D4D4\",\"notebook.cellBorderColor\":\"#E8E8E8\",\"notebook.selectedCellBackground\":\"#c8ddf150\",\"ports.iconRunningProcessForeground\":\"#369432\",\"searchEditor.textInputBorder\":\"#CECECE\",\"settings.numberInputBorder\":\"#CECECE\",\"settings.textInputBorder\":\"#CECECE\",\"sideBarSectionHeader.background\":\"#0000\",\"sideBarSectionHeader.border\":\"#61616130\",\"sideBarTitle.foreground\":\"#6F6F6F\",\"statusBarItem.errorBackground\":\"#c72e0f\",\"statusBarItem.remoteBackground\":\"#16825D\",\"statusBarItem.remoteForeground\":\"#FFF\",\"tab.lastPinnedBorder\":\"#61616130\",\"tab.selectedBackground\":\"#ffffffa5\",\"tab.selectedForeground\":\"#333333b3\",\"terminal.inactiveSelectionBackground\":\"#E5EBF1\",\"widget.border\":\"#d4d4d4\"},\"displayName\":\"Light Plus\",\"name\":\"light-plus\",\"semanticHighlighting\":true,\"semanticTokenColors\":{\"customLiteral\":\"#795E26\",\"newOperator\":\"#AF00DB\",\"numberLiteral\":\"#098658\",\"stringLiteral\":\"#a31515\"},\"tokenColors\":[{\"scope\":[\"meta.embedded\",\"source.groovy.embedded\",\"string meta.image.inline.markdown\",\"variable.legacy.builtin.python\"],\"settings\":{\"foreground\":\"#000000ff\"}},{\"scope\":\"emphasis\",\"settings\":{\"fontStyle\":\"italic\"}},{\"scope\":\"strong\",\"settings\":{\"fontStyle\":\"bold\"}},{\"scope\":\"meta.diff.header\",\"settings\":{\"foreground\":\"#000080\"}},{\"scope\":\"comment\",\"settings\":{\"foreground\":\"#008000\"}},{\"scope\":\"constant.language\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":[\"constant.numeric\",\"variable.other.enummember\",\"keyword.operator.plus.exponent\",\"keyword.operator.minus.exponent\"],\"settings\":{\"foreground\":\"#098658\"}},{\"scope\":\"constant.regexp\",\"settings\":{\"foreground\":\"#811f3f\"}},{\"scope\":\"entity.name.tag\",\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":\"entity.name.selector\",\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":\"entity.other.attribute-name\",\"settings\":{\"foreground\":\"#e50000\"}},{\"scope\":[\"entity.other.attribute-name.class.css\",\"source.css entity.other.attribute-name.class\",\"entity.other.attribute-name.id.css\",\"entity.other.attribute-name.parent-selector.css\",\"entity.other.attribute-name.parent.less\",\"source.css entity.other.attribute-name.pseudo-class\",\"entity.other.attribute-name.pseudo-element.css\",\"source.css.less entity.other.attribute-name.id\",\"entity.other.attribute-name.scss\"],\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":\"invalid\",\"settings\":{\"foreground\":\"#cd3131\"}},{\"scope\":\"markup.underline\",\"settings\":{\"fontStyle\":\"underline\"}},{\"scope\":\"markup.bold\",\"settings\":{\"fontStyle\":\"bold\",\"foreground\":\"#000080\"}},{\"scope\":\"markup.heading\",\"settings\":{\"fontStyle\":\"bold\",\"foreground\":\"#800000\"}},{\"scope\":\"markup.italic\",\"settings\":{\"fontStyle\":\"italic\"}},{\"scope\":\"markup.strikethrough\",\"settings\":{\"fontStyle\":\"strikethrough\"}},{\"scope\":\"markup.inserted\",\"settings\":{\"foreground\":\"#098658\"}},{\"scope\":\"markup.deleted\",\"settings\":{\"foreground\":\"#a31515\"}},{\"scope\":\"markup.changed\",\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":[\"punctuation.definition.quote.begin.markdown\",\"punctuation.definition.list.begin.markdown\"],\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":\"markup.inline.raw\",\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":\"punctuation.definition.tag\",\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":[\"meta.preprocessor\",\"entity.name.function.preprocessor\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"meta.preprocessor.string\",\"settings\":{\"foreground\":\"#a31515\"}},{\"scope\":\"meta.preprocessor.numeric\",\"settings\":{\"foreground\":\"#098658\"}},{\"scope\":\"meta.structure.dictionary.key.python\",\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":\"storage\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"storage.type\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":[\"storage.modifier\",\"keyword.operator.noexcept\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":[\"string\",\"meta.embedded.assembly\"],\"settings\":{\"foreground\":\"#a31515\"}},{\"scope\":[\"string.comment.buffered.block.pug\",\"string.quoted.pug\",\"string.interpolated.pug\",\"string.unquoted.plain.in.yaml\",\"string.unquoted.plain.out.yaml\",\"string.unquoted.block.yaml\",\"string.quoted.single.yaml\",\"string.quoted.double.xml\",\"string.quoted.single.xml\",\"string.unquoted.cdata.xml\",\"string.quoted.double.html\",\"string.quoted.single.html\",\"string.unquoted.html\",\"string.quoted.single.handlebars\",\"string.quoted.double.handlebars\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"string.regexp\",\"settings\":{\"foreground\":\"#811f3f\"}},{\"scope\":[\"punctuation.definition.template-expression.begin\",\"punctuation.definition.template-expression.end\",\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":[\"meta.template.expression\"],\"settings\":{\"foreground\":\"#000000\"}},{\"scope\":[\"support.constant.property-value\",\"support.constant.font-name\",\"support.constant.media-type\",\"support.constant.media\",\"constant.other.color.rgb-value\",\"constant.other.rgb-value\",\"support.constant.color\"],\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":[\"support.type.vendored.property-name\",\"support.type.property-name\",\"source.css variable\",\"source.coffee.embedded\"],\"settings\":{\"foreground\":\"#e50000\"}},{\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":\"keyword\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"keyword.control\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"keyword.operator\",\"settings\":{\"foreground\":\"#000000\"}},{\"scope\":[\"keyword.operator.new\",\"keyword.operator.expression\",\"keyword.operator.cast\",\"keyword.operator.sizeof\",\"keyword.operator.alignof\",\"keyword.operator.typeid\",\"keyword.operator.alignas\",\"keyword.operator.instanceof\",\"keyword.operator.logical.python\",\"keyword.operator.wordlike\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"keyword.other.unit\",\"settings\":{\"foreground\":\"#098658\"}},{\"scope\":[\"punctuation.section.embedded.begin.php\",\"punctuation.section.embedded.end.php\"],\"settings\":{\"foreground\":\"#800000\"}},{\"scope\":\"support.function.git-rebase\",\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":\"constant.sha.git-rebase\",\"settings\":{\"foreground\":\"#098658\"}},{\"scope\":[\"storage.modifier.import.java\",\"variable.language.wildcard.java\",\"storage.modifier.package.java\"],\"settings\":{\"foreground\":\"#000000\"}},{\"scope\":\"variable.language\",\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":[\"entity.name.function\",\"support.function\",\"support.constant.handlebars\",\"source.powershell variable.other.member\",\"entity.name.operator.custom-literal\"],\"settings\":{\"foreground\":\"#795E26\"}},{\"scope\":[\"support.class\",\"support.type\",\"entity.name.type\",\"entity.name.namespace\",\"entity.other.attribute\",\"entity.name.scope-resolution\",\"entity.name.class\",\"storage.type.numeric.go\",\"storage.type.byte.go\",\"storage.type.boolean.go\",\"storage.type.string.go\",\"storage.type.uintptr.go\",\"storage.type.error.go\",\"storage.type.rune.go\",\"storage.type.cs\",\"storage.type.generic.cs\",\"storage.type.modifier.cs\",\"storage.type.variable.cs\",\"storage.type.annotation.java\",\"storage.type.generic.java\",\"storage.type.java\",\"storage.type.object.array.java\",\"storage.type.primitive.array.java\",\"storage.type.primitive.java\",\"storage.type.token.java\",\"storage.type.groovy\",\"storage.type.annotation.groovy\",\"storage.type.parameters.groovy\",\"storage.type.generic.groovy\",\"storage.type.object.array.groovy\",\"storage.type.primitive.array.groovy\",\"storage.type.primitive.groovy\"],\"settings\":{\"foreground\":\"#267f99\"}},{\"scope\":[\"meta.type.cast.expr\",\"meta.type.new.expr\",\"support.constant.math\",\"support.constant.dom\",\"support.constant.json\",\"entity.other.inherited-class\",\"punctuation.separator.namespace.ruby\"],\"settings\":{\"foreground\":\"#267f99\"}},{\"scope\":[\"keyword.control\",\"source.cpp keyword.operator.new\",\"source.cpp keyword.operator.delete\",\"keyword.other.using\",\"keyword.other.directive.using\",\"keyword.other.operator\",\"entity.name.operator\"],\"settings\":{\"foreground\":\"#AF00DB\"}},{\"scope\":[\"variable\",\"meta.definition.variable.name\",\"support.variable\",\"entity.name.variable\",\"constant.other.placeholder\"],\"settings\":{\"foreground\":\"#001080\"}},{\"scope\":[\"variable.other.constant\",\"variable.other.enummember\"],\"settings\":{\"foreground\":\"#0070C1\"}},{\"scope\":[\"meta.object-literal.key\"],\"settings\":{\"foreground\":\"#001080\"}},{\"scope\":[\"support.constant.property-value\",\"support.constant.font-name\",\"support.constant.media-type\",\"support.constant.media\",\"constant.other.color.rgb-value\",\"constant.other.rgb-value\",\"support.constant.color\"],\"settings\":{\"foreground\":\"#0451a5\"}},{\"scope\":[\"punctuation.definition.group.regexp\",\"punctuation.definition.group.assertion.regexp\",\"punctuation.definition.character-class.regexp\",\"punctuation.character.set.begin.regexp\",\"punctuation.character.set.end.regexp\",\"keyword.operator.negation.regexp\",\"support.other.parenthesis.regexp\"],\"settings\":{\"foreground\":\"#d16969\"}},{\"scope\":[\"constant.character.character-class.regexp\",\"constant.other.character-class.set.regexp\",\"constant.other.character-class.regexp\",\"constant.character.set.regexp\"],\"settings\":{\"foreground\":\"#811f3f\"}},{\"scope\":\"keyword.operator.quantifier.regexp\",\"settings\":{\"foreground\":\"#000000\"}},{\"scope\":[\"keyword.operator.or.regexp\",\"keyword.control.anchor.regexp\"],\"settings\":{\"foreground\":\"#EE0000\"}},{\"scope\":[\"constant.character\",\"constant.other.option\"],\"settings\":{\"foreground\":\"#0000ff\"}},{\"scope\":\"constant.character.escape\",\"settings\":{\"foreground\":\"#EE0000\"}},{\"scope\":\"entity.name.label\",\"settings\":{\"foreground\":\"#000000\"}}],\"type\":\"light\"}'));Sn(\"[data-tippy-content]\",{arrow:!1,allowHTML:!0,animation:\"shift-away\",delay:[300,0],duration:200,theme:\"laravel\"});window.copyToClipboard=async function(e){if(navigator.clipboard)await navigator.clipboard.writeText(e);else{const t=document.createElement(\"textarea\");t.value=e,t.style.position=\"fixed\",t.style.opacity=\"0\",t.style.pointerEvents=\"none\",document.body.appendChild(t),t.select();const n=document.execCommand(\"copy\");if(document.body.removeChild(t),!n)throw new Error(\"Failed to copy text to clipboard\")}};const O_=Rf({themes:[R_,T_],langs:[A_,Hl,Bl],engine:__()});window.highlight=function(e,t,n=!1,a=!1,r=1,i=null){return O_.codeToHtml(e,{lang:t,themes:{light:\"light-plus\",dark:\"dark-plus\"},transformers:[{pre(s){this.addClassToHast(s,[\"bg-transparent!\",n?\"truncate\":\"w-fit min-w-full\"])},line(s,o){if(!a)return;const c=r+o-1,l=i===o-1,u={type:\"element\",tagName:\"span\",properties:{className:[\"mr-6 text-neutral-500! dark:text-neutral-600!\",l?\"dark:text-white!\":\"\"]},children:[{type:\"text\",value:c.toString()}]};s.children.unshift(u),this.addClassToHast(s,[\"inline-block w-full px-4 py-1 h-7 even:bg-white odd:bg-white/2 even:dark:bg-white/2 odd:dark:bg-white/4\",l?\"bg-rose-200! dark:bg-rose-900!\":\"\"])}}]})};window.Alpine=yc;yc.start();\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/dist/styles.css",
    "content": "@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-800:oklch(43.2% .095 166.913);--color-emerald-900:oklch(37.8% .077 168.94);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-blue-950:oklch(28.2% .091 267.935);--color-rose-100:oklch(94.1% .03 12.58);--color-rose-200:oklch(89.2% .058 10.001);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-rose-900:oklch(41% .159 10.272);--color-rose-950:oklch(27.1% .105 12.094);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-neutral-950:oklch(14.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4,0,.2,1);--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-\\[-1px\\]{top:-1px}.right-0{right:calc(var(--spacing)*0)}.bottom-0{bottom:calc(var(--spacing)*0)}.left-0{left:calc(var(--spacing)*0)}.-z-10{z-index:-10}.z-50{z-index:50}.mx-auto{margin-inline:auto}.my-1\\.5{margin-block:calc(var(--spacing)*1.5)}.-mt-3{margin-top:calc(var(--spacing)*-3)}.-mt-5{margin-top:calc(var(--spacing)*-5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mr-6{margin-right:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-\\[9px\\]{width:9px;height:9px}.h-0{height:calc(var(--spacing)*0)}.h-2\\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[18px\\]{height:18px}.h-\\[23\\.5px\\]{height:23.5px}.h-\\[56px\\]{height:56px}.min-h-dvh{min-height:100dvh}.w-2\\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-\\[18px\\]{width:18px}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-7xl{max-width:var(--container-7xl)}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-5{min-width:calc(var(--spacing)*5)}.min-w-6{min-width:calc(var(--spacing)*6)}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.transform\\!{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)!important}.cursor-not-allowed\\!{cursor:not-allowed!important}.cursor-pointer{cursor:pointer}.resize{resize:both}.flex-col{flex-direction:column}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.gap-12{gap:calc(var(--spacing)*12)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px*var(--tw-divide-x-reverse));border-inline-end-width:calc(1px*calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-neutral-200>:not(:last-child)){border-color:var(--color-neutral-200)}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-emerald-900{border-color:var(--color-emerald-900)}.border-neutral-100{border-color:var(--color-neutral-100)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-300{border-color:var(--color-neutral-300)}.bg-amber-200{background-color:var(--color-amber-200)}.bg-amber-600{background-color:var(--color-amber-600)}.bg-black\\/8{background-color:#00000014}@supports (color:color-mix(in lab,red,red)){.bg-black\\/8{background-color:color-mix(in oklab,var(--color-black)8%,transparent)}}.bg-black\\/10{background-color:#0000001a}@supports (color:color-mix(in lab,red,red)){.bg-black\\/10{background-color:color-mix(in oklab,var(--color-black)10%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-blue-700{background-color:var(--color-blue-700)}.bg-emerald-200{background-color:var(--color-emerald-200)}.bg-emerald-600{background-color:var(--color-emerald-600)}.bg-emerald-800{background-color:var(--color-emerald-800)}.bg-neutral-50{background-color:var(--color-neutral-50)}.bg-neutral-600{background-color:var(--color-neutral-600)}.bg-rose-200{background-color:var(--color-rose-200)}.bg-rose-200\\!{background-color:var(--color-rose-200)!important}.bg-rose-500{background-color:var(--color-rose-500)}.bg-rose-600{background-color:var(--color-rose-600)}.bg-transparent\\!{background-color:#0000!important}.bg-white{background-color:var(--color-white)}.bg-white\\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.bg-white\\/5{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.bg-white\\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-white\\/\\[2\\%\\]{background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.bg-white\\/\\[2\\%\\]{background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-2\\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-\\[6px\\]{padding-inline:6px}.py-0{padding-block:calc(var(--spacing)*0)}.py-1{padding-block:calc(var(--spacing)*1)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-8{padding-top:calc(var(--spacing)*8)}.pt-14{padding-top:calc(var(--spacing)*14)}.pr-2\\.5{padding-right:calc(var(--spacing)*2.5)}.pb-0{padding-bottom:calc(var(--spacing)*0)}.pl-4{padding-left:calc(var(--spacing)*4)}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\\/none{font-size:var(--text-xs);line-height:1}.text-\\[13px\\]{font-size:13px}.leading-3{--tw-leading:calc(var(--spacing)*3);line-height:calc(var(--spacing)*3)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.text-amber-900{color:var(--color-amber-900)}.text-blue-500{color:var(--color-blue-500)}.text-blue-900{color:var(--color-blue-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-900{color:var(--color-emerald-900)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-500\\!{color:var(--color-neutral-500)!important}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-800{color:var(--color-neutral-800)}.text-neutral-900{color:var(--color-neutral-900)}.text-neutral-950{color:var(--color-neutral-950)}.text-rose-900{color:var(--color-rose-900)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.decoration-neutral-400{-webkit-text-decoration-color:var(--color-neutral-400);text-decoration-color:var(--color-neutral-400)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.scheme-light-dark{color-scheme:light dark}.opacity-90{opacity:.9}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter\\!{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)!important}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}@media(hover:hover){.group-hover\\:text-blue-500:is(:where(.group):hover *),.group-hover\\/exception\\:text-blue-500:is(:where(.group\\/exception):hover *){color:var(--color-blue-500)}}.odd\\:bg-white\\/2:nth-child(odd){background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.odd\\:bg-white\\/2:nth-child(odd){background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}.even\\:bg-white:nth-child(2n){background-color:var(--color-white)}@media(hover:hover){.hover\\:border:hover{border-style:var(--tw-border-style);border-width:1px}.hover\\:border-neutral-200:hover{border-color:var(--color-neutral-200)}.hover\\:bg-neutral-100:hover{background-color:var(--color-neutral-100)}.hover\\:bg-neutral-200:hover{background-color:var(--color-neutral-200)}.hover\\:bg-white\\/50:hover{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.hover\\:bg-white\\/50:hover{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.hover\\:text-blue-500:hover{color:var(--color-blue-500)}.hover\\:underline:hover{text-decoration-line:underline}}@media(min-width:40rem){.sm\\:mb-16{margin-bottom:calc(var(--spacing)*16)}.sm\\:p-14{padding:calc(var(--spacing)*14)}.sm\\:py-0{padding-block:calc(var(--spacing)*0)}.sm\\:pt-16{padding-top:calc(var(--spacing)*16)}.sm\\:pb-0{padding-bottom:calc(var(--spacing)*0)}}@media(prefers-color-scheme:dark){:where(.dark\\:divide-white\\/5>:not(:last-child)){border-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){:where(.dark\\:divide-white\\/5>:not(:last-child)){border-color:color-mix(in oklab,var(--color-white)5%,transparent)}}:where(.dark\\:divide-white\\/10>:not(:last-child)){border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){:where(.dark\\:divide-white\\/10>:not(:last-child)){border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\\:border{border-style:var(--tw-border-style);border-width:1px}.dark\\:border-none{--tw-border-style:none;border-style:none}.dark\\:border-amber-500{border-color:var(--color-amber-500)}.dark\\:border-amber-800{border-color:var(--color-amber-800)}.dark\\:border-blue-600{border-color:var(--color-blue-600)}.dark\\:border-blue-800{border-color:var(--color-blue-800)}.dark\\:border-emerald-500{border-color:var(--color-emerald-500)}.dark\\:border-emerald-600{border-color:var(--color-emerald-600)}.dark\\:border-neutral-500{border-color:var(--color-neutral-500)}.dark\\:border-neutral-700{border-color:var(--color-neutral-700)}.dark\\:border-neutral-800{border-color:var(--color-neutral-800)}.dark\\:border-rose-500{border-color:var(--color-rose-500)}.dark\\:border-rose-900{border-color:var(--color-rose-900)}.dark\\:border-transparent{border-color:#0000}.dark\\:border-white\\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.dark\\:border-white\\/5{border-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\\:border-white\\/8{border-color:#ffffff14}@supports (color:color-mix(in lab,red,red)){.dark\\:border-white\\/8{border-color:color-mix(in oklab,var(--color-white)8%,transparent)}}.dark\\:border-white\\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.dark\\:border-white\\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\\:border-white\\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.dark\\:border-white\\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.dark\\:border-white\\/\\[9\\%\\]{border-color:#ffffff17}@supports (color:color-mix(in lab,red,red)){.dark\\:border-white\\/\\[9\\%\\]{border-color:color-mix(in oklab,var(--color-white)9%,transparent)}}.dark\\:bg-\\[\\#1a1a1a\\]{background-color:#1a1a1a}.dark\\:bg-amber-600{background-color:var(--color-amber-600)}.dark\\:bg-amber-950{background-color:var(--color-amber-950)}.dark\\:bg-blue-700{background-color:var(--color-blue-700)}.dark\\:bg-blue-950{background-color:var(--color-blue-950)}.dark\\:bg-emerald-600{background-color:var(--color-emerald-600)}.dark\\:bg-emerald-900\\/70{background-color:#004e3bb3}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-emerald-900\\/70{background-color:color-mix(in oklab,var(--color-emerald-900)70%,transparent)}}.dark\\:bg-neutral-400{background-color:var(--color-neutral-400)}.dark\\:bg-neutral-600{background-color:var(--color-neutral-600)}.dark\\:bg-neutral-700{background-color:var(--color-neutral-700)}.dark\\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\\:bg-neutral-900{background-color:var(--color-neutral-900)}.dark\\:bg-rose-600{background-color:var(--color-rose-600)}.dark\\:bg-rose-900\\!{background-color:var(--color-rose-900)!important}.dark\\:bg-rose-950{background-color:var(--color-rose-950)}.dark\\:bg-transparent{background-color:#0000}.dark\\:bg-white{background-color:var(--color-white)}.dark\\:bg-white\\/1{background-color:#ffffff03}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/1{background-color:color-mix(in oklab,var(--color-white)1%,transparent)}}.dark\\:bg-white\\/2{background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/2{background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}.dark\\:bg-white\\/3{background-color:#ffffff08}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/3{background-color:color-mix(in oklab,var(--color-white)3%,transparent)}}.dark\\:bg-white\\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/5{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\\:bg-white\\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.dark\\:bg-white\\/\\[2\\%\\]{background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/\\[2\\%\\]{background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}.dark\\:bg-white\\/\\[3\\%\\]{background-color:#ffffff08}@supports (color:color-mix(in lab,red,red)){.dark\\:bg-white\\/\\[3\\%\\]{background-color:color-mix(in oklab,var(--color-white)3%,transparent)}}.dark\\:text-amber-300{color:var(--color-amber-300)}.dark\\:text-blue-300{color:var(--color-blue-300)}.dark\\:text-emerald-400{color:var(--color-emerald-400)}.dark\\:text-emerald-500{color:var(--color-emerald-500)}.dark\\:text-neutral-100{color:var(--color-neutral-100)}.dark\\:text-neutral-200{color:var(--color-neutral-200)}.dark\\:text-neutral-300{color:var(--color-neutral-300)}.dark\\:text-neutral-400{color:var(--color-neutral-400)}.dark\\:text-neutral-500{color:var(--color-neutral-500)}.dark\\:text-neutral-600{color:var(--color-neutral-600)}.dark\\:text-neutral-600\\!{color:var(--color-neutral-600)!important}.dark\\:text-neutral-900{color:var(--color-neutral-900)}.dark\\:text-rose-100{color:var(--color-rose-100)}.dark\\:text-white{color:var(--color-white)}.dark\\:text-white\\!{color:var(--color-white)!important}}@media(hover:hover){@media(prefers-color-scheme:dark){.group-hover\\:dark\\:text-emerald-500:is(:where(.group):hover *),.group-hover\\/exception\\:dark\\:text-emerald-500:is(:where(.group\\/exception):hover *){color:var(--color-emerald-500)}}}@media(prefers-color-scheme:dark){.odd\\:dark\\:bg-white\\/4:nth-child(odd){background-color:#ffffff0a}@supports (color:color-mix(in lab,red,red)){.odd\\:dark\\:bg-white\\/4:nth-child(odd){background-color:color-mix(in oklab,var(--color-white)4%,transparent)}}.even\\:dark\\:bg-white\\/2:nth-child(2n){background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.even\\:dark\\:bg-white\\/2:nth-child(2n){background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}@media(hover:hover){.dark\\:hover\\:border-none:hover{--tw-border-style:none;border-style:none}.dark\\:hover\\:bg-white\\/2:hover{background-color:#ffffff05}@supports (color:color-mix(in lab,red,red)){.dark\\:hover\\:bg-white\\/2:hover{background-color:color-mix(in oklab,var(--color-white)2%,transparent)}}.dark\\:hover\\:bg-white\\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.dark\\:hover\\:bg-white\\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.dark\\:hover\\:bg-white\\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.dark\\:hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}}}@media(hover:hover){@media(prefers-color-scheme:dark){.hover\\:dark\\:bg-white\\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\\:dark\\:bg-white\\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}}}@media(prefers-color-scheme:dark){@media(hover:hover){.dark\\:hover\\:text-emerald-500:hover{color:var(--color-emerald-500)}}}@media(hover:hover){@media(prefers-color-scheme:dark){.hover\\:dark\\:text-white:hover{color:var(--color-white)}}}.\\[\\&_svg\\]\\:size-2\\.5 svg{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.\\[\\&_svg\\]\\:\\!text-white svg{color:var(--color-white)!important}@media(hover:hover){.hover\\:\\[\\&_svg\\]\\:stroke-emerald-500:hover svg{stroke:var(--color-emerald-500)}}@media(prefers-color-scheme:dark){.dark\\:\\[\\&_svg\\]\\:\\!text-white svg{color:var(--color-white)!important}}}@property --tw-animation-delay{syntax:\"*\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\"*\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\"*\";inherits:false}@property --tw-animation-fill-mode{syntax:\"*\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\"*\";inherits:false;initial-value:0}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{color:#fff;white-space:normal;background-color:#333;border-radius:4px;outline:0;font-size:14px;line-height:1.4;transition-property:transform,visibility,opacity;position:relative}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{border-width:8px 8px 0;border-top-color:initial;transform-origin:top;bottom:-7px;left:0}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{border-width:0 8px 8px;border-bottom-color:initial;transform-origin:bottom;top:-7px;left:0}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;transform-origin:0;right:-7px}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:100%;left:-7px}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{color:#333;width:16px;height:16px}.tippy-arrow:before{content:\"\";border-style:solid;border-color:#0000;position:absolute}.tippy-content{z-index:1;padding:5px 9px;position:relative}.tippy-box[data-animation=shift-away][data-state=hidden]{opacity:0}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=top]{transform:translateY(10px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=bottom]{transform:translateY(-10px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=left]{transform:translate(10px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=right]{transform:translate(-10px)}[x-cloak]{display:none!important}.tippy-box[data-theme~=laravel]{border-radius:var(--radius-md);border-style:var(--tw-border-style);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);border-width:1px;border-color:var(--color-neutral-800);background-color:var(--color-neutral-900);color:var(--color-white);overflow-x:auto;max-width:var(--container-7xl)!important}@media(prefers-color-scheme:dark){.tippy-box[data-theme~=laravel]{border-color:var(--color-neutral-700);background-color:var(--color-neutral-800);color:var(--color-neutral-100)}}.tippy-content[data-theme~=laravel]{padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*1)}@media(prefers-color-scheme:dark){.shiki,.shiki span{color:var(--shiki-dark)!important;font-style:var(--shiki-dark-font-style)!important;font-weight:var(--shiki-dark-font-weight)!important;-webkit-text-decoration:var(--shiki-dark-text-decoration)!important;text-decoration:var(--shiki-dark-text-decoration)!important}}@property --tw-rotate-x{syntax:\"*\";inherits:false}@property --tw-rotate-y{syntax:\"*\";inherits:false}@property --tw-rotate-z{syntax:\"*\";inherits:false}@property --tw-skew-x{syntax:\"*\";inherits:false}@property --tw-skew-y{syntax:\"*\";inherits:false}@property --tw-divide-x-reverse{syntax:\"*\";inherits:false;initial-value:0}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:\"*\";inherits:false;initial-value:0}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:\"*\";inherits:false}@property --tw-brightness{syntax:\"*\";inherits:false}@property --tw-contrast{syntax:\"*\";inherits:false}@property --tw-grayscale{syntax:\"*\";inherits:false}@property --tw-hue-rotate{syntax:\"*\";inherits:false}@property --tw-invert{syntax:\"*\";inherits:false}@property --tw-opacity{syntax:\"*\";inherits:false}@property --tw-saturate{syntax:\"*\";inherits:false}@property --tw-sepia{syntax:\"*\";inherits:false}@property --tw-drop-shadow{syntax:\"*\";inherits:false}@property --tw-drop-shadow-color{syntax:\"*\";inherits:false}@property --tw-drop-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:\"*\";inherits:false}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-ease{syntax:\"*\";inherits:false}@property --tw-backdrop-blur{syntax:\"*\";inherits:false}@property --tw-backdrop-brightness{syntax:\"*\";inherits:false}@property --tw-backdrop-contrast{syntax:\"*\";inherits:false}@property --tw-backdrop-grayscale{syntax:\"*\";inherits:false}@property --tw-backdrop-hue-rotate{syntax:\"*\";inherits:false}@property --tw-backdrop-invert{syntax:\"*\";inherits:false}@property --tw-backdrop-opacity{syntax:\"*\";inherits:false}@property --tw-backdrop-saturate{syntax:\"*\";inherits:false}@property --tw-backdrop-sepia{syntax:\"*\";inherits:false}\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/markdown.blade.php",
    "content": "# {{ $exception->class() }} - {!! $exception->title() !!}\n\n{!! $exception->message() !!}\n\nPHP {{ PHP_VERSION }}\nLaravel {{ app()->version() }}\n{{ $exception->request()->httpHost() }}\n\n## Stack Trace\n\n@foreach($exception->frames() as $index => $frame)\n{{ $index }} - {{ $frame->file() }}:{{ $frame->line() }}\n@endforeach\n\n@if ($exception->previousExceptions()->isNotEmpty())\n## Previous {{ Str::plural('exception', $exception->previousExceptions()->count()) }}\n@foreach ($exception->previousExceptions() as $index => $previous)\n\n### {{ $index + 1 }}. {{ $previous->class() }}\n\n{!! $previous->message() !!}\n\n@foreach($previous->frames() as $index => $frame)\n{{ $index }} - {{ $frame->file() }}:{{ $frame->line() }}\n@endforeach\n@endforeach\n@endif\n\n## Request\n\n{{ $exception->request()->method() }} {{ \\Illuminate\\Support\\Str::start($exception->request()->path(), '/') }}\n\n## Headers\n\n@forelse ($exception->requestHeaders() as $key => $value)\n* **{{ $key }}**: {!! $value !!}\n@empty\nNo header data available.\n@endforelse\n\n## Route Context\n\n@forelse($exception->applicationRouteContext() as $name => $value)\n{{ $name }}: {!! $value !!}\n@empty\nNo routing data available.\n@endforelse\n\n## Route Parameters\n\n@if ($routeParametersContext = $exception->applicationRouteParametersContext())\n{!! $routeParametersContext !!}\n@else\nNo route parameter data available.\n@endif\n\n## Database Queries\n\n@forelse ($exception->applicationQueries() as ['connectionName' => $connectionName, 'sql' => $sql, 'time' => $time])\n* {{ $connectionName }} - {!! $sql !!} ({{ $time }} ms)\n@empty\nNo database queries detected.\n@endforelse\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/package.json",
    "content": "{\n    \"private\": true,\n    \"type\": \"module\",\n    \"engines\": {\n        \"node\": \">=22.19.0\"\n    },\n    \"scripts\": {\n        \"dev\": \"vite\",\n        \"build\": \"vite build\",\n        \"watch\": \"vite build --watch\"\n    },\n    \"dependencies\": {\n        \"alpinejs\": \"^3.14.9\",\n        \"shiki\": \"^3.13.0\",\n        \"tailwindcss\": \"^4.1.12\",\n        \"tippy.js\": \"^6.3.7\",\n        \"tw-animate-css\": \"^1.3.7\"\n    },\n    \"devDependencies\": {\n        \"@tailwindcss/vite\": \"^4.1.12\",\n        \"vite\": \"^7.1.11\"\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/scripts.js",
    "content": "import Alpine from 'alpinejs';\nimport tippy from 'tippy.js';\nimport { createHighlighterCoreSync } from 'shiki/core';\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript';\nimport json from '@shikijs/langs/json';\nimport php from '@shikijs/langs/php';\nimport sql from '@shikijs/langs/sql';\nimport darkPlus from '@shikijs/themes/dark-plus';\nimport lightPlus from '@shikijs/themes/light-plus';\n\ntippy('[data-tippy-content]', {\n    arrow: false,\n    allowHTML: true,\n    animation: 'shift-away',\n    delay: [300, 0],\n    duration: 200,\n    theme: 'laravel',\n});\n\nwindow.copyToClipboard = async function (text) {\n    if (navigator.clipboard) {\n        await navigator.clipboard.writeText(text);\n    } else {\n        const textarea = document.createElement('textarea');\n        textarea.value = text;\n        textarea.style.position = 'fixed';\n        textarea.style.opacity = '0';\n        textarea.style.pointerEvents = 'none';\n        document.body.appendChild(textarea);\n        textarea.select();\n\n        const result = document.execCommand('copy');\n        document.body.removeChild(textarea);\n\n        if (!result) {\n            throw new Error('Failed to copy text to clipboard');\n        }\n    }\n};\n\nconst highlighter = createHighlighterCoreSync({\n    themes: [lightPlus, darkPlus],\n    langs: [php, sql, json],\n    engine: createJavaScriptRegexEngine(),\n});\n\nwindow.highlight = function (\n    code,\n    language,\n    truncate = false,\n    editor = false,\n    startingLine = 1,\n    highlightedLine = null\n) {\n    return highlighter.codeToHtml(code, {\n        lang: language,\n        themes: {\n            light: 'light-plus',\n            dark: 'dark-plus',\n        },\n        transformers: [\n            {\n                pre(node) {\n                    this.addClassToHast(node, ['bg-transparent!', truncate ? 'truncate' : 'w-fit min-w-full']);\n                },\n                line(node, line) {\n                    if (!editor) {\n                        return;\n                    }\n\n                    const lineNumber = startingLine + line - 1;\n                    const highlight = highlightedLine === line - 1;\n\n                    const lineNumberSpan = {\n                        type: 'element',\n                        tagName: 'span',\n                        properties: {\n                            className: [\n                                'mr-6 text-neutral-500! dark:text-neutral-600!',\n                                highlight ? 'dark:text-white!' : '',\n                            ],\n                        },\n                        children: [{ type: 'text', value: lineNumber.toString() }],\n                    };\n\n                    node.children.unshift(lineNumberSpan);\n\n                    this.addClassToHast(node, [\n                        'inline-block w-full px-4 py-1 h-7 even:bg-white odd:bg-white/2 even:dark:bg-white/2 odd:dark:bg-white/4',\n                        highlight ? 'bg-rose-200! dark:bg-rose-900!' : '',\n                    ]);\n                },\n            },\n        ],\n    });\n};\n\nwindow.Alpine = Alpine;\n\nAlpine.start();\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/show.blade.php",
    "content": "<x-laravel-exceptions-renderer::layout>\n    <x-laravel-exceptions-renderer::section-container class=\"px-6 py-0 sm:py-0\">\n        <x-laravel-exceptions-renderer::topbar :title=\"$exception->title()\" :markdown=\"$exceptionAsMarkdown\" />\n    </x-laravel-exceptions-renderer::section-container>\n\n    <x-laravel-exceptions-renderer::separator />\n\n    <x-laravel-exceptions-renderer::section-container class=\"flex flex-col gap-8 py-0 sm:py-0\">\n        <x-laravel-exceptions-renderer::header :$exception />\n    </x-laravel-exceptions-renderer::section-container>\n\n    <x-laravel-exceptions-renderer::separator class=\"-mt-5 -z-10\" />\n\n    <x-laravel-exceptions-renderer::section-container class=\"flex flex-col gap-8 pt-14\">\n        <x-laravel-exceptions-renderer::trace :$exception />\n\n        @if ($exception->previousExceptions()->isNotEmpty())\n            <x-laravel-exceptions-renderer::previous-exceptions :$exception />\n        @endif\n\n        <x-laravel-exceptions-renderer::query :queries=\"$exception->applicationQueries()\" />\n    </x-laravel-exceptions-renderer::section-container>\n\n    <x-laravel-exceptions-renderer::separator />\n\n    <x-laravel-exceptions-renderer::section-container class=\"flex flex-col gap-12\">\n        <x-laravel-exceptions-renderer::request-header :headers=\"$exception->requestHeaders()\" />\n\n        <x-laravel-exceptions-renderer::request-body :body=\"$exception->requestBody()\" />\n\n        <x-laravel-exceptions-renderer::routing :routing=\"$exception->applicationRouteContext()\" />\n\n        <x-laravel-exceptions-renderer::routing-parameter :routeParameters=\"$exception->applicationRouteParametersContext()\" />\n    </x-laravel-exceptions-renderer::section-container>\n\n    <x-laravel-exceptions-renderer::separator />\n\n    @if (! app()->runningUnitTests() && ! app()->runningInConsole())\n        <x-laravel-exceptions-renderer::section-container class=\"pb-0 sm:pb-0\">\n            <x-laravel-exceptions-renderer::laravel-ascii-spotlight />\n        </x-laravel-exceptions-renderer::section-container>\n    @endif\n</x-laravel-exceptions-renderer::layout>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/styles.css",
    "content": "@import 'tailwindcss';\n@import 'tw-animate-css';\n@import 'tippy.js/dist/tippy.css';\n@import 'tippy.js/animations/shift-away.css';\n\n[x-cloak] {\n    display: none !important;\n}\n\n.tippy-box[data-theme~='laravel'] {\n    @apply max-w-7xl! rounded-md border text-xs shadow-md backdrop-blur-md overflow-x-auto;\n    @apply border-neutral-800 bg-neutral-900 text-white;\n    @apply dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100;\n}\n\n.tippy-content[data-theme~='laravel'] {\n    @apply px-2 py-1;\n}\n\n@media (prefers-color-scheme: dark) {\n    .shiki,\n    .shiki span {\n        color: var(--shiki-dark) !important;\n        font-style: var(--shiki-dark-font-style) !important;\n        font-weight: var(--shiki-dark-font-weight) !important;\n        text-decoration: var(--shiki-dark-text-decoration) !important;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/exceptions/renderer/vite.config.js",
    "content": "import { defineConfig } from 'vite';\nimport tailwindcss from '@tailwindcss/vite';\nexport default defineConfig({\n    plugins: [tailwindcss()],\n    build: {\n        rollupOptions: {\n            input: ['styles.css', 'scripts.js'],\n            output: {\n                assetFileNames: '[name][extname]',\n                entryFileNames: '[name].js',\n            },\n        },\n    },\n});\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/health-up.blade.php",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n    <title>{{ config('app.name', 'Laravel') }}</title>\n\n    <!-- Fonts -->\n    <link rel=\"preconnect\" href=\"https://fonts.bunny.net\">\n    <link href=\"https://fonts.bunny.net/css?family=figtree:400,600&display=swap\" rel=\"stylesheet\" />\n\n    <!-- Styles -->\n    <script src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4\"></script>\n\n    <style type=\"text/tailwindcss\">\n        @theme {\n            --font-sans: 'Figtree', 'ui-sans-serif', 'system-ui', 'sans-serif', \"Apple Color Emoji\", \"Segoe UI Emoji\";\n        }\n    </style>\n</head>\n<body class=\"antialiased\">\n<div class=\"relative flex justify-center items-center min-h-screen bg-gray-100 selection:bg-red-500 selection:text-white\">\n    <div class=\"w-full sm:w-3/4 xl:w-1/2 mx-auto p-6\">\n        <div class=\"px-6 py-4 bg-white from-gray-700/50 via-transparent rounded-lg shadow-2xl shadow-gray-500/20 flex items-center focus:outline focus:outline-2 focus:outline-red-500\">\n            <div class=\"relative flex h-3 w-3 group {{ $exception ? 'status-down' : null }}\">\n                <span class=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 group-[.status-down]:bg-red-600 opacity-75\"></span>\n                <span class=\"relative inline-flex rounded-full h-3 w-3 bg-green-400 group-[.status-down]:bg-red-600\"></span>\n            </div>\n\n            <div class=\"ml-6\">\n                <h2 class=\"text-xl font-semibold text-gray-900\">Application {{ $exception ? 'experiencing problems' : 'up' }}</h2>\n\n                <p class=\"mt-2 text-gray-500 dark:text-gray-400 text-sm leading-relaxed\">\n                    HTTP request received.\n\n                    @if (defined('LARAVEL_START'))\n                        Response rendered in {{ round((microtime(true) - LARAVEL_START) * 1000) }}ms.\n                    @endif\n                </p>\n            </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Foundation/resources/server.php",
    "content": "<?php\n\n$publicPath = getcwd();\n\n$uri = urldecode(\n    parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? ''\n);\n\n// This file allows us to emulate Apache's \"mod_rewrite\" functionality from the\n// built-in PHP web server. This provides a convenient way to test a Laravel\n// application without having installed a \"real\" web server software here.\nif ($uri !== '/' && file_exists($publicPath.$uri)) {\n    return false;\n}\n\n$formattedDateTime = date('D M j H:i:s Y');\n\n$requestMethod = $_SERVER['REQUEST_METHOD'];\n$remoteAddress = $_SERVER['REMOTE_ADDR'].':'.$_SERVER['REMOTE_PORT'];\n\nfile_put_contents('php://stdout', \"[$formattedDateTime] $remoteAddress [$requestMethod] URI: $uri\\n\");\n\nrequire_once $publicPath.'/index.php';\n"
  },
  {
    "path": "src/Illuminate/Foundation/stubs/facade.stub",
    "content": "<?php\n\nnamespace DummyNamespace;\n\nuse Illuminate\\Support\\Facades\\Facade;\n\n/**\n * @mixin \\DummyTarget\n */\nclass DummyClass extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     */\n    protected static function getFacadeAccessor(): string\n    {\n        return 'DummyTarget';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Hashing/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Hashing/AbstractHasher.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nabstract class AbstractHasher\n{\n    /**\n     * Get information about the given hashed value.\n     *\n     * @param  string  $hashedValue\n     * @return array\n     */\n    public function info($hashedValue)\n    {\n        return password_get_info($hashedValue);\n    }\n\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = [])\n    {\n        if (is_null($hashedValue) || strlen($hashedValue) === 0) {\n            return false;\n        }\n\n        return password_verify($value, $hashedValue);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/Argon2IdHasher.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nuse RuntimeException;\n\nclass Argon2IdHasher extends ArgonHasher\n{\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = [])\n    {\n        if (is_null($hashedValue) || strlen($hashedValue) === 0) {\n            return false;\n        }\n\n        if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {\n            throw new RuntimeException('This password does not use the Argon2id algorithm.');\n        }\n\n        return password_verify($value, $hashedValue);\n    }\n\n    /**\n     * Verify the hashed value's algorithm.\n     *\n     * @param  string  $hashedValue\n     * @return bool\n     */\n    protected function isUsingCorrectAlgorithm($hashedValue)\n    {\n        return $this->info($hashedValue)['algoName'] === 'argon2id';\n    }\n\n    /**\n     * Get the algorithm that should be used for hashing.\n     *\n     * @return int\n     */\n    protected function algorithm()\n    {\n        return PASSWORD_ARGON2ID;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/ArgonHasher.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nuse Error;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse RuntimeException;\n\nclass ArgonHasher extends AbstractHasher implements HasherContract\n{\n    /**\n     * The default memory cost factor.\n     *\n     * @var int\n     */\n    protected $memory = 1024;\n\n    /**\n     * The default time cost factor.\n     *\n     * @var int\n     */\n    protected $time = 2;\n\n    /**\n     * The default threads factor.\n     *\n     * @var int\n     */\n    protected $threads = 2;\n\n    /**\n     * Indicates whether to perform an algorithm check.\n     *\n     * @var bool\n     */\n    protected $verifyAlgorithm = false;\n\n    /**\n     * Create a new hasher instance.\n     *\n     * @param  array  $options\n     */\n    public function __construct(array $options = [])\n    {\n        $this->time = $options['time'] ?? $this->time;\n        $this->memory = $options['memory'] ?? $this->memory;\n        $this->threads = $this->threads($options);\n        $this->verifyAlgorithm = $options['verify'] ?? $this->verifyAlgorithm;\n    }\n\n    /**\n     * Hash the given value.\n     *\n     * @param  string  $value\n     * @param  array  $options\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function make(#[\\SensitiveParameter] $value, array $options = [])\n    {\n        try {\n            $hash = password_hash($value, $this->algorithm(), [\n                'memory_cost' => $this->memory($options),\n                'time_cost' => $this->time($options),\n                'threads' => $this->threads($options),\n            ]);\n        } catch (Error) {\n            throw new RuntimeException('Argon2 hashing not supported.');\n        }\n\n        return $hash;\n    }\n\n    /**\n     * Get the algorithm that should be used for hashing.\n     *\n     * @return int\n     */\n    protected function algorithm()\n    {\n        return PASSWORD_ARGON2I;\n    }\n\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = [])\n    {\n        if (is_null($hashedValue) || strlen($hashedValue) === 0) {\n            return false;\n        }\n\n        if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {\n            throw new RuntimeException('This password does not use the Argon2i algorithm.');\n        }\n\n        return parent::check($value, $hashedValue, $options);\n    }\n\n    /**\n     * Check if the given hash has been hashed using the given options.\n     *\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function needsRehash($hashedValue, array $options = [])\n    {\n        return password_needs_rehash($hashedValue, $this->algorithm(), [\n            'memory_cost' => $this->memory($options),\n            'time_cost' => $this->time($options),\n            'threads' => $this->threads($options),\n        ]);\n    }\n\n    /**\n     * Verifies that the configuration is less than or equal to what is configured.\n     *\n     * @internal\n     */\n    public function verifyConfiguration($value)\n    {\n        return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value);\n    }\n\n    /**\n     * Verify the hashed value's algorithm.\n     *\n     * @param  string  $hashedValue\n     * @return bool\n     */\n    protected function isUsingCorrectAlgorithm($hashedValue)\n    {\n        return $this->info($hashedValue)['algoName'] === 'argon2i';\n    }\n\n    /**\n     * Verify the hashed value's options.\n     *\n     * @param  string  $hashedValue\n     * @return bool\n     */\n    protected function isUsingValidOptions($hashedValue)\n    {\n        ['options' => $options] = $this->info($hashedValue);\n\n        if (\n            ! is_int($options['memory_cost'] ?? null) ||\n            ! is_int($options['time_cost'] ?? null) ||\n            ! is_int($options['threads'] ?? null)\n        ) {\n            return false;\n        }\n\n        if (\n            $options['memory_cost'] > $this->memory ||\n            $options['time_cost'] > $this->time ||\n            $options['threads'] > $this->threads\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Set the default password memory factor.\n     *\n     * @param  int  $memory\n     * @return $this\n     */\n    public function setMemory(int $memory)\n    {\n        $this->memory = $memory;\n\n        return $this;\n    }\n\n    /**\n     * Set the default password timing factor.\n     *\n     * @param  int  $time\n     * @return $this\n     */\n    public function setTime(int $time)\n    {\n        $this->time = $time;\n\n        return $this;\n    }\n\n    /**\n     * Set the default password threads factor.\n     *\n     * @param  int  $threads\n     * @return $this\n     */\n    public function setThreads(int $threads)\n    {\n        $this->threads = $threads;\n\n        return $this;\n    }\n\n    /**\n     * Extract the memory cost value from the options array.\n     *\n     * @param  array  $options\n     * @return int\n     */\n    protected function memory(array $options)\n    {\n        return $options['memory'] ?? $this->memory;\n    }\n\n    /**\n     * Extract the time cost value from the options array.\n     *\n     * @param  array  $options\n     * @return int\n     */\n    protected function time(array $options)\n    {\n        return $options['time'] ?? $this->time;\n    }\n\n    /**\n     * Extract the thread's value from the options array.\n     *\n     * @param  array  $options\n     * @return int\n     */\n    protected function threads(array $options)\n    {\n        if (defined('PASSWORD_ARGON2_PROVIDER') && PASSWORD_ARGON2_PROVIDER === 'sodium') {\n            return 1;\n        }\n\n        return $options['threads'] ?? $this->threads;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/BcryptHasher.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nuse Error;\nuse Illuminate\\Contracts\\Hashing\\Hasher as HasherContract;\nuse InvalidArgumentException;\nuse RuntimeException;\n\nclass BcryptHasher extends AbstractHasher implements HasherContract\n{\n    /**\n     * The default cost factor.\n     *\n     * @var int\n     */\n    protected $rounds = 12;\n\n    /**\n     * Indicates whether to perform an algorithm check.\n     *\n     * @var bool\n     */\n    protected $verifyAlgorithm = false;\n\n    /**\n     * The maximum allowed length of strings that can be hashed.\n     *\n     * @var int|null\n     */\n    protected $limit;\n\n    /**\n     * Create a new hasher instance.\n     *\n     * @param  array  $options\n     */\n    public function __construct(array $options = [])\n    {\n        $this->rounds = $options['rounds'] ?? $this->rounds;\n        $this->verifyAlgorithm = $options['verify'] ?? $this->verifyAlgorithm;\n        $this->limit = $options['limit'] ?? $this->limit;\n    }\n\n    /**\n     * Hash the given value.\n     *\n     * @param  string  $value\n     * @param  array  $options\n     * @return string\n     *\n     * @throws \\RuntimeException\n     * @throws \\InvalidArgumentException\n     */\n    public function make(#[\\SensitiveParameter] $value, array $options = [])\n    {\n        try {\n            if ($this->limit && strlen($value) > $this->limit) {\n                throw new InvalidArgumentException('Value is too long to hash. Value must be less than '.$this->limit.' bytes.');\n            }\n\n            $hash = password_hash($value, PASSWORD_BCRYPT, [\n                'cost' => $this->cost($options),\n            ]);\n        } catch (Error) {\n            throw new RuntimeException('Bcrypt hashing not supported.');\n        }\n\n        return $hash;\n    }\n\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = [])\n    {\n        if (is_null($hashedValue) || strlen($hashedValue) === 0) {\n            return false;\n        }\n\n        if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) {\n            throw new RuntimeException('This password does not use the Bcrypt algorithm.');\n        }\n\n        return parent::check($value, $hashedValue, $options);\n    }\n\n    /**\n     * Check if the given hash has been hashed using the given options.\n     *\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function needsRehash($hashedValue, array $options = [])\n    {\n        return password_needs_rehash($hashedValue, PASSWORD_BCRYPT, [\n            'cost' => $this->cost($options),\n        ]);\n    }\n\n    /**\n     * Verifies that the configuration is less than or equal to what is configured.\n     *\n     * @internal\n     */\n    public function verifyConfiguration($value)\n    {\n        return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value);\n    }\n\n    /**\n     * Verify the hashed value's algorithm.\n     *\n     * @param  string  $hashedValue\n     * @return bool\n     */\n    protected function isUsingCorrectAlgorithm($hashedValue)\n    {\n        return $this->info($hashedValue)['algoName'] === 'bcrypt';\n    }\n\n    /**\n     * Verify the hashed value's options.\n     *\n     * @param  string  $hashedValue\n     * @return bool\n     */\n    protected function isUsingValidOptions($hashedValue)\n    {\n        ['options' => $options] = $this->info($hashedValue);\n\n        if (! is_int($options['cost'] ?? null)) {\n            return false;\n        }\n\n        if ($options['cost'] > $this->rounds) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Set the default password work factor.\n     *\n     * @param  int  $rounds\n     * @return $this\n     */\n    public function setRounds($rounds)\n    {\n        $this->rounds = (int) $rounds;\n\n        return $this;\n    }\n\n    /**\n     * Extract the cost value from the options array.\n     *\n     * @param  array  $options\n     * @return int\n     */\n    protected function cost(array $options = [])\n    {\n        return $options['rounds'] ?? $this->rounds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/HashManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nuse Illuminate\\Contracts\\Hashing\\Hasher;\nuse Illuminate\\Support\\Manager;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Hashing\\Hasher\n */\nclass HashManager extends Manager implements Hasher\n{\n    /**\n     * Create an instance of the Bcrypt hash Driver.\n     *\n     * @return \\Illuminate\\Hashing\\BcryptHasher\n     */\n    public function createBcryptDriver()\n    {\n        return new BcryptHasher($this->config->get('hashing.bcrypt') ?? []);\n    }\n\n    /**\n     * Create an instance of the Argon2i hash Driver.\n     *\n     * @return \\Illuminate\\Hashing\\ArgonHasher\n     */\n    public function createArgonDriver()\n    {\n        return new ArgonHasher($this->config->get('hashing.argon') ?? []);\n    }\n\n    /**\n     * Create an instance of the Argon2id hash Driver.\n     *\n     * @return \\Illuminate\\Hashing\\Argon2IdHasher\n     */\n    public function createArgon2idDriver()\n    {\n        return new Argon2IdHasher($this->config->get('hashing.argon') ?? []);\n    }\n\n    /**\n     * Get information about the given hashed value.\n     *\n     * @param  string  $hashedValue\n     * @return array\n     */\n    public function info($hashedValue)\n    {\n        return $this->driver()->info($hashedValue);\n    }\n\n    /**\n     * Hash the given value.\n     *\n     * @param  string  $value\n     * @param  array  $options\n     * @return string\n     */\n    public function make(#[\\SensitiveParameter] $value, array $options = [])\n    {\n        return $this->driver()->make($value, $options);\n    }\n\n    /**\n     * Check the given plain value against a hash.\n     *\n     * @param  string  $value\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function check(#[\\SensitiveParameter] $value, $hashedValue, array $options = [])\n    {\n        return $this->driver()->check($value, $hashedValue, $options);\n    }\n\n    /**\n     * Check if the given hash has been hashed using the given options.\n     *\n     * @param  string  $hashedValue\n     * @param  array  $options\n     * @return bool\n     */\n    public function needsRehash($hashedValue, array $options = [])\n    {\n        return $this->driver()->needsRehash($hashedValue, $options);\n    }\n\n    /**\n     * Determine if a given string is already hashed.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    public function isHashed(#[\\SensitiveParameter] $value)\n    {\n        return $this->driver()->info($value)['algo'] !== null;\n    }\n\n    /**\n     * Get the default driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->config->get('hashing.driver', 'bcrypt');\n    }\n\n    /**\n     * Verifies that the configuration is less than or equal to what is configured.\n     *\n     * @param  array  $value\n     * @return bool\n     *\n     * @internal\n     */\n    public function verifyConfiguration($value)\n    {\n        if (method_exists($driver = $this->driver(), 'verifyConfiguration')) {\n            return $driver->verifyConfiguration($value);\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/HashServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Hashing;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass HashServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('hash', function ($app) {\n            return new HashManager($app);\n        });\n\n        $this->app->singleton('hash.driver', function ($app) {\n            return $app['hash']->driver();\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['hash', 'hash.driver'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Hashing/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Hashing/composer.json",
    "content": "{\n    \"name\": \"illuminate/hashing\",\n    \"description\": \"The Illuminate Hashing package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Hashing\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Http/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Batch.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse Carbon\\CarbonImmutable;\nuse Closure;\nuse GuzzleHttp\\Exception\\RequestException;\nuse GuzzleHttp\\Promise\\EachPromise;\nuse GuzzleHttp\\Utils;\nuse Illuminate\\Http\\Client\\Promises\\LazyPromise;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\n\nuse function Illuminate\\Support\\defer;\n\n/**\n * @mixin \\Illuminate\\Http\\Client\\Factory\n */\nclass Batch\n{\n    /**\n     * The factory instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The array of requests.\n     *\n     * @var array<array-key, \\Illuminate\\Http\\Client\\PendingRequest>\n     */\n    protected $requests = [];\n\n    /**\n     * The total number of requests that belong to the batch.\n     *\n     * @var non-negative-int\n     */\n    public $totalRequests = 0;\n\n    /**\n     * The total number of requests that are still pending.\n     *\n     * @var non-negative-int\n     */\n    public $pendingRequests = 0;\n\n    /**\n     * The total number of requests that have failed.\n     *\n     * @var non-negative-int\n     */\n    public $failedRequests = 0;\n\n    /**\n     * The handler function for the Guzzle client.\n     *\n     * @var callable\n     */\n    protected $handler;\n\n    /**\n     * The callback to run before the first request from the batch runs.\n     *\n     * @var (\\Closure($this): void)|null\n     */\n    protected $beforeCallback = null;\n\n    /**\n     * The callback to run after a request from the batch succeeds.\n     *\n     * @var (\\Closure($this, int|string, \\Illuminate\\Http\\Client\\Response): void)|null\n     */\n    protected $progressCallback = null;\n\n    /**\n     * The callback to run after a request from the batch fails.\n     *\n     * @var (\\Closure($this, int|string, \\Illuminate\\Http\\Client\\Response|\\Illuminate\\Http\\Client\\RequestException|\\Illuminate\\Http\\Client\\ConnectionException): void)|null\n     */\n    protected $catchCallback = null;\n\n    /**\n     * The callback to run if all the requests from the batch succeeded.\n     *\n     * @var (\\Closure($this, array<int|string, \\Illuminate\\Http\\Client\\Response>): void)|null\n     */\n    protected $thenCallback = null;\n\n    /**\n     * The callback to run after all the requests from the batch finish.\n     *\n     * @var (\\Closure($this, array<int|string, \\Illuminate\\Http\\Client\\Response>): void)|null\n     */\n    protected $finallyCallback = null;\n\n    /**\n     * If the batch already was sent.\n     *\n     * @var bool\n     */\n    protected $inProgress = false;\n\n    /**\n     * The date when the batch was created.\n     *\n     * @var \\Carbon\\CarbonImmutable|null\n     */\n    public $createdAt = null;\n\n    /**\n     * The date when the batch finished.\n     *\n     * @var \\Carbon\\CarbonImmutable|null\n     */\n    public $finishedAt = null;\n\n    /**\n     * The maximum number of concurrent requests.\n     *\n     * @var int|null\n     */\n    protected $concurrencyLimit = null;\n\n    /**\n     * Create a new request batch instance.\n     */\n    public function __construct(?Factory $factory = null)\n    {\n        $this->factory = $factory ?: new Factory;\n        $this->handler = Utils::chooseHandler();\n        $this->createdAt = new CarbonImmutable;\n    }\n\n    /**\n     * Add a request to the batch with a key.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     *\n     * @throws \\Illuminate\\Http\\Client\\BatchInProgressException\n     */\n    public function as(string $key)\n    {\n        if ($this->inProgress) {\n            throw new BatchInProgressException();\n        }\n\n        $this->incrementPendingRequests();\n\n        return $this->requests[$key] = $this->asyncRequest();\n    }\n\n    /**\n     * Add a request to the batch with a numeric index.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest|\\GuzzleHttp\\Promise\\Promise\n     *\n     * @throws \\Illuminate\\Http\\Client\\BatchInProgressException\n     */\n    public function newRequest()\n    {\n        if ($this->inProgress) {\n            throw new BatchInProgressException();\n        }\n\n        $this->incrementPendingRequests();\n\n        return $this->requests[] = $this->asyncRequest();\n    }\n\n    /**\n     * Register a callback to run before the first request from the batch runs.\n     *\n     * @param  (\\Closure($this): void)  $callback\n     * @return Batch\n     */\n    public function before(Closure $callback): self\n    {\n        $this->beforeCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run after a request from the batch succeeds.\n     *\n     * @param  (\\Closure($this, int|string, \\Illuminate\\Http\\Client\\Response): void)  $callback\n     * @return Batch\n     */\n    public function progress(Closure $callback): self\n    {\n        $this->progressCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run after a request from the batch fails.\n     *\n     * @param  (\\Closure($this, int|string, \\Illuminate\\Http\\Client\\Response|\\Illuminate\\Http\\Client\\RequestException|\\Illuminate\\Http\\Client\\ConnectionException): void)  $callback\n     * @return Batch\n     */\n    public function catch(Closure $callback): self\n    {\n        $this->catchCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run after all the requests from the batch succeed.\n     *\n     * @param  (\\Closure($this, array<int|string, \\Illuminate\\Http\\Client\\Response>): void)  $callback\n     * @return Batch\n     */\n    public function then(Closure $callback): self\n    {\n        $this->thenCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to run after all the requests from the batch finish.\n     *\n     * @param  (\\Closure($this, array<int|string, \\Illuminate\\Http\\Client\\Response>): void)  $callback\n     * @return Batch\n     */\n    public function finally(Closure $callback): self\n    {\n        $this->finallyCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum number of concurrent requests.\n     *\n     * @param  int  $limit\n     * @return Batch\n     */\n    public function concurrency(int $limit): self\n    {\n        $this->concurrencyLimit = $limit;\n\n        return $this;\n    }\n\n    /**\n     * Defer the batch to run in the background after the current task has finished.\n     *\n     * @return \\Illuminate\\Support\\Defer\\DeferredCallback\n     */\n    public function defer(): DeferredCallback\n    {\n        return defer(fn () => $this->send());\n    }\n\n    /**\n     * Send all of the requests in the batch.\n     *\n     * @return array<int|string, \\Illuminate\\Http\\Client\\Response|\\Illuminate\\Http\\Client\\RequestException>\n     */\n    public function send(): array\n    {\n        $this->inProgress = true;\n\n        if ($this->beforeCallback !== null) {\n            call_user_func($this->beforeCallback, $this);\n        }\n\n        $results = [];\n\n        if (! empty($this->requests)) {\n            $eachPromiseOptions = [\n                'fulfilled' => function ($result, $key) use (&$results) {\n                    $results[$key] = $result;\n\n                    $this->decrementPendingRequests();\n\n                    if ($result instanceof Response && $result->successful()) {\n                        if ($this->progressCallback !== null) {\n                            call_user_func($this->progressCallback, $this, $key, $result);\n                        }\n\n                        return $result;\n                    }\n\n                    if (\n                        ($result instanceof Response && $result->failed()) ||\n                        $result instanceof RequestException ||\n                        $result instanceof ConnectionException\n                    ) {\n                        $this->incrementFailedRequests();\n\n                        if ($this->catchCallback !== null) {\n                            call_user_func($this->catchCallback, $this, $key, $result);\n                        }\n                    }\n\n                    return $result;\n                },\n                'rejected' => function ($reason, $key) {\n                    $this->decrementPendingRequests();\n\n                    if ($reason instanceof RequestException || $reason instanceof ConnectionException) {\n                        $this->incrementFailedRequests();\n\n                        if ($this->catchCallback !== null) {\n                            call_user_func($this->catchCallback, $this, $key, $reason);\n                        }\n                    }\n\n                    return $reason;\n                },\n            ];\n\n            if ($this->concurrencyLimit !== null) {\n                $eachPromiseOptions['concurrency'] = $this->concurrencyLimit;\n            }\n\n            $promiseGenerator = function () {\n                foreach ($this->requests as $key => $item) {\n                    $promise = $item instanceof PendingRequest ? $item->getPromise() : $item;\n                    yield $key => $promise instanceof LazyPromise ? $promise->buildPromise() : $promise;\n                }\n            };\n\n            (new EachPromise($promiseGenerator(), $eachPromiseOptions))\n                ->promise()\n                ->wait();\n        }\n\n        // Before returning the results, we must ensure that the results are sorted\n        // in the same order as the requests were defined, respecting any custom\n        // key names that were assigned to this request using the \"as\" method.\n        uksort($results, function ($key1, $key2) {\n            return array_search($key1, array_keys($this->requests), true) <=>\n                   array_search($key2, array_keys($this->requests), true);\n        });\n\n        if (! $this->hasFailures() && $this->thenCallback !== null) {\n            call_user_func($this->thenCallback, $this, $results);\n        }\n\n        if ($this->finallyCallback !== null) {\n            call_user_func($this->finallyCallback, $this, $results);\n        }\n\n        $this->finishedAt = new CarbonImmutable;\n        $this->inProgress = false;\n\n        return $results;\n    }\n\n    /**\n     * Retrieve a new async pending request.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     */\n    protected function asyncRequest()\n    {\n        return $this->factory->setHandler($this->handler)->async();\n    }\n\n    /**\n     * Get the total number of requests that have been processed by the batch thus far.\n     *\n     * @return non-negative-int\n     */\n    public function processedRequests(): int\n    {\n        return $this->totalRequests - $this->pendingRequests;\n    }\n\n    /**\n     * Determine if the batch has finished executing.\n     *\n     * @return bool\n     */\n    public function finished(): bool\n    {\n        return ! is_null($this->finishedAt);\n    }\n\n    /**\n     * Increment the count of total and pending requests in the batch.\n     *\n     * @return void\n     */\n    protected function incrementPendingRequests(): void\n    {\n        $this->totalRequests++;\n        $this->pendingRequests++;\n    }\n\n    /**\n     * Decrement the count of pending requests in the batch.\n     *\n     * @return void\n     */\n    protected function decrementPendingRequests(): void\n    {\n        $this->pendingRequests--;\n    }\n\n    /**\n     * Determine if the batch has job failures.\n     *\n     * @return bool\n     */\n    public function hasFailures(): bool\n    {\n        return $this->failedRequests > 0;\n    }\n\n    /**\n     * Increment the count of failed requests in the batch.\n     *\n     * @return void\n     */\n    protected function incrementFailedRequests(): void\n    {\n        $this->failedRequests++;\n    }\n\n    /**\n     * Get the requests in the batch.\n     *\n     * @return array<array-key, \\Illuminate\\Http\\Client\\PendingRequest>\n     */\n    public function getRequests(): array\n    {\n        return $this->requests;\n    }\n\n    /**\n     * Add a request to the batch with a numeric index.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\Http\\Client\\PendingRequest|\\GuzzleHttp\\Promise\\Promise\n     *\n     * @throws \\Illuminate\\Http\\Client\\BatchInProgressException\n     */\n    public function __call(string $method, array $parameters)\n    {\n        return $this->newRequest()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/BatchInProgressException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nclass BatchInProgressException extends HttpClientException\n{\n    public function __construct()\n    {\n        parent::__construct('You cannot add requests to a batch that is already in progress.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Concerns/DeterminesStatusCode.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Concerns;\n\ntrait DeterminesStatusCode\n{\n    /**\n     * Determine if the response code was 200 \"OK\" response.\n     *\n     * @return bool\n     */\n    public function ok()\n    {\n        return $this->status() === 200;\n    }\n\n    /**\n     * Determine if the response code was 201 \"Created\" response.\n     *\n     * @return bool\n     */\n    public function created()\n    {\n        return $this->status() === 201;\n    }\n\n    /**\n     * Determine if the response code was 202 \"Accepted\" response.\n     *\n     * @return bool\n     */\n    public function accepted()\n    {\n        return $this->status() === 202;\n    }\n\n    /**\n     * Determine if the response code was the given status code and the body has no content.\n     *\n     * @param  int  $status\n     * @return bool\n     */\n    public function noContent($status = 204)\n    {\n        return $this->status() === $status && $this->body() === '';\n    }\n\n    /**\n     * Determine if the response code was a 301 \"Moved Permanently\".\n     *\n     * @return bool\n     */\n    public function movedPermanently()\n    {\n        return $this->status() === 301;\n    }\n\n    /**\n     * Determine if the response code was a 302 \"Found\" response.\n     *\n     * @return bool\n     */\n    public function found()\n    {\n        return $this->status() === 302;\n    }\n\n    /**\n     * Determine if the response code was a 304 \"Not Modified\" response.\n     *\n     * @return bool\n     */\n    public function notModified()\n    {\n        return $this->status() === 304;\n    }\n\n    /**\n     * Determine if the response was a 400 \"Bad Request\" response.\n     *\n     * @return bool\n     */\n    public function badRequest()\n    {\n        return $this->status() === 400;\n    }\n\n    /**\n     * Determine if the response was a 401 \"Unauthorized\" response.\n     *\n     * @return bool\n     */\n    public function unauthorized()\n    {\n        return $this->status() === 401;\n    }\n\n    /**\n     * Determine if the response was a 402 \"Payment Required\" response.\n     *\n     * @return bool\n     */\n    public function paymentRequired()\n    {\n        return $this->status() === 402;\n    }\n\n    /**\n     * Determine if the response was a 403 \"Forbidden\" response.\n     *\n     * @return bool\n     */\n    public function forbidden()\n    {\n        return $this->status() === 403;\n    }\n\n    /**\n     * Determine if the response was a 404 \"Not Found\" response.\n     *\n     * @return bool\n     */\n    public function notFound()\n    {\n        return $this->status() === 404;\n    }\n\n    /**\n     * Determine if the response was a 408 \"Request Timeout\" response.\n     *\n     * @return bool\n     */\n    public function requestTimeout()\n    {\n        return $this->status() === 408;\n    }\n\n    /**\n     * Determine if the response was a 409 \"Conflict\" response.\n     *\n     * @return bool\n     */\n    public function conflict()\n    {\n        return $this->status() === 409;\n    }\n\n    /**\n     * Determine if the response was a 422 \"Unprocessable Content\" response.\n     *\n     * @return bool\n     */\n    public function unprocessableContent()\n    {\n        return $this->status() === 422;\n    }\n\n    /**\n     * Determine if the response was a 422 \"Unprocessable Content\" response.\n     *\n     * @return bool\n     */\n    public function unprocessableEntity()\n    {\n        return $this->unprocessableContent();\n    }\n\n    /**\n     * Determine if the response was a 429 \"Too Many Requests\" response.\n     *\n     * @return bool\n     */\n    public function tooManyRequests()\n    {\n        return $this->status() === 429;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/ConnectionException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nclass ConnectionException extends HttpClientException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Events/ConnectionFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Events;\n\nuse Illuminate\\Http\\Client\\ConnectionException;\nuse Illuminate\\Http\\Client\\Request;\n\nclass ConnectionFailed\n{\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Request\n     */\n    public $request;\n\n    /**\n     * The exception instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public $exception;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     * @param  \\Illuminate\\Http\\Client\\ConnectionException  $exception\n     */\n    public function __construct(Request $request, ConnectionException $exception)\n    {\n        $this->request = $request;\n        $this->exception = $exception;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Events/RequestSending.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Events;\n\nuse Illuminate\\Http\\Client\\Request;\n\nclass RequestSending\n{\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Request\n     */\n    public $request;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     */\n    public function __construct(Request $request)\n    {\n        $this->request = $request;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Events/ResponseReceived.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Events;\n\nuse Illuminate\\Http\\Client\\Request;\nuse Illuminate\\Http\\Client\\Response;\n\nclass ResponseReceived\n{\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Request\n     */\n    public $request;\n\n    /**\n     * The response instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Response\n     */\n    public $response;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     */\n    public function __construct(Request $request, Response $response)\n    {\n        $this->request = $request;\n        $this->response = $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse Closure;\nuse GuzzleHttp\\Exception\\ConnectException;\nuse GuzzleHttp\\Middleware;\nuse GuzzleHttp\\Promise\\Create;\nuse GuzzleHttp\\Promise\\PromiseInterface;\nuse GuzzleHttp\\Psr7\\Response as Psr7Response;\nuse GuzzleHttp\\TransferStats;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\n/**\n * @mixin \\Illuminate\\Http\\Client\\PendingRequest\n */\nclass Factory\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The event dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $dispatcher;\n\n    /**\n     * The middleware to apply to every request.\n     *\n     * @var array\n     */\n    protected $globalMiddleware = [];\n\n    /**\n     * The options to apply to every request.\n     *\n     * @var \\Closure|array\n     */\n    protected $globalOptions = [];\n\n    /**\n     * The stub callables that will handle requests.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $stubCallbacks;\n\n    /**\n     * Indicates if the factory is recording requests and responses.\n     *\n     * @var bool\n     */\n    protected $recording = false;\n\n    /**\n     * The recorded response array.\n     *\n     * @var list<array{0: \\Illuminate\\Http\\Client\\Request, 1: \\Illuminate\\Http\\Client\\Response|null}>\n     */\n    protected $recorded = [];\n\n    /**\n     * All created response sequences.\n     *\n     * @var list<\\Illuminate\\Http\\Client\\ResponseSequence>\n     */\n    protected $responseSequences = [];\n\n    /**\n     * Indicates that an exception should be thrown if any request is not faked.\n     *\n     * @var bool\n     */\n    protected $preventStrayRequests = false;\n\n    /**\n     * A list of URL patterns that are allowed to bypass the stray request guard.\n     *\n     * @var array<int, string>\n     */\n    protected $allowedStrayRequestUrls = [];\n\n    /**\n     * Create a new factory instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher|null  $dispatcher\n     */\n    public function __construct(?Dispatcher $dispatcher = null)\n    {\n        $this->dispatcher = $dispatcher;\n\n        $this->stubCallbacks = new Collection;\n    }\n\n    /**\n     * Add middleware to apply to every request.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function globalMiddleware($middleware)\n    {\n        $this->globalMiddleware[] = $middleware;\n\n        return $this;\n    }\n\n    /**\n     * Add request middleware to apply to every request.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function globalRequestMiddleware($middleware)\n    {\n        $this->globalMiddleware[] = Middleware::mapRequest($middleware);\n\n        return $this;\n    }\n\n    /**\n     * Add response middleware to apply to every request.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function globalResponseMiddleware($middleware)\n    {\n        $this->globalMiddleware[] = Middleware::mapResponse($middleware);\n\n        return $this;\n    }\n\n    /**\n     * Set the options to apply to every request.\n     *\n     * @param  \\Closure|array  $options\n     * @return $this\n     */\n    public function globalOptions($options)\n    {\n        $this->globalOptions = $options;\n\n        return $this;\n    }\n\n    /**\n     * Create a new response instance for use during stubbing.\n     *\n     * @param  array|string|null  $body\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    public static function response($body = null, $status = 200, $headers = [])\n    {\n        return Create::promiseFor(\n            static::psr7Response($body, $status, $headers)\n        );\n    }\n\n    /**\n     * Create a new PSR-7 response instance for use during stubbing.\n     *\n     * @param  array|string|null  $body\n     * @param  int  $status\n     * @param  array<string, mixed>  $headers\n     * @return \\GuzzleHttp\\Psr7\\Response\n     */\n    public static function psr7Response($body = null, $status = 200, $headers = [])\n    {\n        if (is_array($body)) {\n            $body = json_encode($body);\n\n            $headers['Content-Type'] = 'application/json';\n        }\n\n        return new Psr7Response($status, $headers, $body);\n    }\n\n    /**\n     * Create a new RequestException instance for use during stubbing.\n     *\n     * @param  array|string|null  $body\n     * @param  int  $status\n     * @param  array<string, mixed>  $headers\n     * @return \\Illuminate\\Http\\Client\\RequestException\n     */\n    public static function failedRequest($body = null, $status = 200, $headers = [])\n    {\n        return new RequestException(new Response(static::psr7Response($body, $status, $headers)));\n    }\n\n    /**\n     * Create a new connection exception for use during stubbing.\n     *\n     * @param  string|null  $message\n     * @return \\Closure(\\Illuminate\\Http\\Client\\Request): \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    public static function failedConnection($message = null)\n    {\n        return function ($request) use ($message) {\n            return Create::rejectionFor(new ConnectException(\n                $message ?? \"cURL error 6: Could not resolve host: {$request->toPsrRequest()->getUri()->getHost()} (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for {$request->toPsrRequest()->getUri()}.\",\n                $request->toPsrRequest(),\n            ));\n        };\n    }\n\n    /**\n     * Get an invokable object that returns a sequence of responses in order for use during stubbing.\n     *\n     * @param  array  $responses\n     * @return \\Illuminate\\Http\\Client\\ResponseSequence\n     */\n    public function sequence(array $responses = [])\n    {\n        return $this->responseSequences[] = new ResponseSequence($responses);\n    }\n\n    /**\n     * Register a stub callable that will intercept requests and be able to return stub responses.\n     *\n     * @param  callable|array<string, mixed>|null  $callback\n     * @return $this\n     */\n    public function fake($callback = null)\n    {\n        $this->record();\n\n        $this->recorded = [];\n\n        if (is_null($callback)) {\n            $callback = function () {\n                return static::response();\n            };\n        }\n\n        if (is_array($callback)) {\n            foreach ($callback as $url => $callable) {\n                $this->stubUrl($url, $callable);\n            }\n\n            return $this;\n        }\n\n        $this->stubCallbacks = $this->stubCallbacks->merge(new Collection([\n            function ($request, $options) use ($callback) {\n                $response = $callback;\n\n                while ($response instanceof Closure) {\n                    $response = $response($request, $options);\n                }\n\n                if ($response instanceof PromiseInterface) {\n                    $options['on_stats'](new TransferStats(\n                        $request->toPsrRequest(),\n                        $response->wait(),\n                    ));\n                }\n\n                return $response;\n            },\n        ]));\n\n        return $this;\n    }\n\n    /**\n     * Register a response sequence for the given URL pattern.\n     *\n     * @param  string  $url\n     * @return \\Illuminate\\Http\\Client\\ResponseSequence\n     */\n    public function fakeSequence($url = '*')\n    {\n        return tap($this->sequence(), function ($sequence) use ($url) {\n            $this->fake([$url => $sequence]);\n        });\n    }\n\n    /**\n     * Stub the given URL using the given callback.\n     *\n     * @param  string  $url\n     * @param  \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface|callable|int|string|array|\\Illuminate\\Http\\Client\\ResponseSequence  $callback\n     * @return $this\n     */\n    public function stubUrl($url, $callback)\n    {\n        return $this->fake(function ($request, $options) use ($url, $callback) {\n            if (! Str::is(Str::start($url, '*'), $request->url())) {\n                return;\n            }\n\n            if (is_int($callback) && $callback >= 100 && $callback < 600) {\n                return static::response(status: $callback);\n            }\n\n            if (is_int($callback) || is_string($callback)) {\n                return static::response($callback);\n            }\n\n            if ($callback instanceof Closure || $callback instanceof ResponseSequence) {\n                return $callback($request, $options);\n            }\n\n            return $callback;\n        });\n    }\n\n    /**\n     * Indicate that an exception should be thrown if any request is not faked.\n     *\n     * @param  bool  $prevent\n     * @return $this\n     */\n    public function preventStrayRequests($prevent = true)\n    {\n        $this->preventStrayRequests = $prevent;\n\n        return $this;\n    }\n\n    /**\n     * Determine if stray requests are being prevented.\n     *\n     * @return bool\n     */\n    public function preventingStrayRequests()\n    {\n        return $this->preventStrayRequests;\n    }\n\n    /**\n     * Allow stray, unfaked requests entirely, or optionally allow only specific URLs.\n     *\n     * @param  array<int, string>|null  $only\n     * @return $this\n     */\n    public function allowStrayRequests(?array $only = null)\n    {\n        if (is_null($only)) {\n            $this->preventStrayRequests(false);\n\n            $this->allowedStrayRequestUrls = [];\n        } else {\n            $this->allowedStrayRequestUrls = array_values($only);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Begin recording request / response pairs.\n     *\n     * @return $this\n     */\n    public function record()\n    {\n        $this->recording = true;\n\n        return $this;\n    }\n\n    /**\n     * Record a request response pair.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     * @param  \\Illuminate\\Http\\Client\\Response|null  $response\n     * @return void\n     */\n    public function recordRequestResponsePair($request, $response)\n    {\n        if ($this->recording) {\n            $this->recorded[] = [$request, $response];\n        }\n    }\n\n    /**\n     * Assert that a request / response pair was recorded matching a given truth test.\n     *\n     * @param  callable|(\\Closure(\\Illuminate\\Http\\Client\\Request, \\Illuminate\\Http\\Client\\Response|null): bool)  $callback\n     * @return void\n     */\n    public function assertSent($callback)\n    {\n        PHPUnit::assertTrue(\n            $this->recorded($callback)->count() > 0,\n            'An expected request was not recorded.'\n        );\n    }\n\n    /**\n     * Assert that the given request was sent in the given order.\n     *\n     * @param  list<string|(\\Closure(\\Illuminate\\Http\\Client\\Request, \\Illuminate\\Http\\Client\\Response|null): bool)|callable>  $callbacks\n     * @return void\n     */\n    public function assertSentInOrder($callbacks)\n    {\n        $this->assertSentCount(count($callbacks));\n\n        foreach ($callbacks as $index => $url) {\n            $callback = is_callable($url) ? $url : function ($request) use ($url) {\n                return $request->url() == $url;\n            };\n\n            PHPUnit::assertTrue($callback(\n                $this->recorded[$index][0],\n                $this->recorded[$index][1]\n            ), 'An expected request (#'.($index + 1).') was not recorded.');\n        }\n    }\n\n    /**\n     * Assert that a request / response pair was not recorded matching a given truth test.\n     *\n     * @param  callable|(\\Closure(\\Illuminate\\Http\\Client\\Request, \\Illuminate\\Http\\Client\\Response|null): bool)  $callback\n     * @return void\n     */\n    public function assertNotSent($callback)\n    {\n        PHPUnit::assertFalse(\n            $this->recorded($callback)->count() > 0,\n            'Unexpected request was recorded.'\n        );\n    }\n\n    /**\n     * Assert that no request / response pair was recorded.\n     *\n     * @return void\n     */\n    public function assertNothingSent()\n    {\n        PHPUnit::assertEmpty(\n            $this->recorded,\n            'Requests were recorded.'\n        );\n    }\n\n    /**\n     * Assert how many requests have been recorded.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertSentCount($count)\n    {\n        PHPUnit::assertCount($count, $this->recorded);\n    }\n\n    /**\n     * Assert that every created response sequence is empty.\n     *\n     * @return void\n     */\n    public function assertSequencesAreEmpty()\n    {\n        foreach ($this->responseSequences as $responseSequence) {\n            PHPUnit::assertTrue(\n                $responseSequence->isEmpty(),\n                'Not all response sequences are empty.'\n            );\n        }\n    }\n\n    /**\n     * Get a collection of the request / response pairs matching the given truth test.\n     *\n     * @param  (\\Closure(\\Illuminate\\Http\\Client\\Request, \\Illuminate\\Http\\Client\\Response|null): bool)|callable  $callback\n     * @return \\Illuminate\\Support\\Collection<int, array{0: \\Illuminate\\Http\\Client\\Request, 1: \\Illuminate\\Http\\Client\\Response|null}>\n     */\n    public function recorded($callback = null)\n    {\n        if (empty($this->recorded)) {\n            return new Collection;\n        }\n\n        $collect = new Collection($this->recorded);\n\n        if ($callback) {\n            return $collect->filter(fn ($pair) => $callback($pair[0], $pair[1]));\n        }\n\n        return $collect;\n    }\n\n    /**\n     * Create a new pending request instance for this factory.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     */\n    public function createPendingRequest()\n    {\n        return tap($this->newPendingRequest(), function ($request) {\n            $request\n                ->stub($this->stubCallbacks)\n                ->preventStrayRequests($this->preventStrayRequests)\n                ->allowStrayRequests($this->allowedStrayRequestUrls);\n        });\n    }\n\n    /**\n     * Instantiate a new pending request instance for this factory.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     */\n    protected function newPendingRequest()\n    {\n        return (new PendingRequest($this, $this->globalMiddleware))->withOptions(value($this->globalOptions));\n    }\n\n    /**\n     * Get the current event dispatcher implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getDispatcher()\n    {\n        return $this->dispatcher;\n    }\n\n    /**\n     * Get the array of global middleware.\n     *\n     * @return array\n     */\n    public function getGlobalMiddleware()\n    {\n        return $this->globalMiddleware;\n    }\n\n    /**\n     * Execute a method against a new pending request instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->createPendingRequest()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/HttpClientException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse Exception;\n\nclass HttpClientException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/PendingRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse Closure;\nuse Exception;\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\Cookie\\CookieJar;\nuse GuzzleHttp\\Exception\\ConnectException;\nuse GuzzleHttp\\Exception\\RequestException;\nuse GuzzleHttp\\Exception\\TransferException;\nuse GuzzleHttp\\HandlerStack;\nuse GuzzleHttp\\Middleware;\nuse GuzzleHttp\\Promise\\EachPromise;\nuse GuzzleHttp\\Promise\\PromiseInterface;\nuse GuzzleHttp\\UriTemplate\\UriTemplate;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Http\\Client\\Events\\ConnectionFailed;\nuse Illuminate\\Http\\Client\\Events\\RequestSending;\nuse Illuminate\\Http\\Client\\Events\\ResponseReceived;\nuse Illuminate\\Http\\Client\\Promises\\FluentPromise;\nuse Illuminate\\Http\\Client\\Promises\\LazyPromise;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse JsonSerializable;\nuse Psr\\Http\\Message\\MessageInterface;\nuse Psr\\Http\\Message\\RequestInterface;\nuse Symfony\\Component\\VarDumper\\VarDumper;\nuse Throwable;\n\n/**\n * @template TAsync of bool = false\n */\nclass PendingRequest\n{\n    use Conditionable, Macroable;\n\n    /**\n     * The factory instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Factory|null\n     */\n    protected $factory;\n\n    /**\n     * The Guzzle client instance.\n     *\n     * @var \\GuzzleHttp\\Client\n     */\n    protected $client;\n\n    /**\n     * The Guzzle HTTP handler.\n     *\n     * @var callable\n     */\n    protected $handler;\n\n    /**\n     * The base URL for the request.\n     *\n     * @var string\n     */\n    protected $baseUrl = '';\n\n    /**\n     * The parameters that can be substituted into the URL.\n     *\n     * @var array\n     */\n    protected $urlParameters = [];\n\n    /**\n     * The request body format.\n     *\n     * @var string\n     */\n    protected $bodyFormat;\n\n    /**\n     * The raw body for the request.\n     *\n     * @var \\Psr\\Http\\Message\\StreamInterface|string\n     */\n    protected $pendingBody;\n\n    /**\n     * The pending files for the request.\n     *\n     * @var array\n     */\n    protected $pendingFiles = [];\n\n    /**\n     * The request cookies.\n     *\n     * @var array\n     */\n    protected $cookies;\n\n    /**\n     * The transfer stats for the request.\n     *\n     * @var \\GuzzleHttp\\TransferStats\n     */\n    protected $transferStats;\n\n    /**\n     * The request options.\n     *\n     * @var array\n     */\n    protected $options = [];\n\n    /**\n     * A callback to run when throwing if a server or client error occurs.\n     *\n     * @var \\Closure\n     */\n    protected $throwCallback;\n\n    /**\n     * A callback to check if an exception should be thrown when a server or client error occurs.\n     *\n     * @var \\Closure\n     */\n    protected $throwIfCallback;\n\n    /**\n     * The number of times to try the request.\n     *\n     * @var int\n     */\n    protected $tries = 1;\n\n    /**\n     * The number of milliseconds to wait between retries.\n     *\n     * @var (Closure(int, mixed): int)|int\n     */\n    protected $retryDelay = 100;\n\n    /**\n     * Whether to throw an exception when all retries fail.\n     *\n     * @var bool\n     */\n    protected $retryThrow = true;\n\n    /**\n     * The callback that will determine if the request should be retried.\n     *\n     * @var (callable(\\Throwable, static, string|null): bool)|null\n     */\n    protected $retryWhenCallback = null;\n\n    /**\n     * The callbacks that should execute before the request is sent.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $beforeSendingCallbacks;\n\n    /**\n     * The callbacks that should execute after the Laravel Response is built.\n     *\n     * @var \\Illuminate\\Support\\Collection<int, (callable(\\Illuminate\\Http\\Client\\Response): \\Illuminate\\Http\\Client\\Response|null)>\n     */\n    protected $afterResponseCallbacks;\n\n    /**\n     * The stub callables that will handle requests.\n     *\n     * @var \\Illuminate\\Support\\Collection|null\n     */\n    protected $stubCallbacks;\n\n    /**\n     * Indicates that an exception should be thrown if any request is not faked.\n     *\n     * @var bool\n     */\n    protected $preventStrayRequests = false;\n\n    /**\n     * A list of URL patterns that are allowed to bypass the stray request guard.\n     *\n     * @var array<int, string>\n     */\n    protected $allowedStrayRequestUrls = [];\n\n    /**\n     * The middleware callables added by users that will handle requests.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $middleware;\n\n    /**\n     * Whether the requests should be asynchronous.\n     *\n     * @var TAsync\n     */\n    protected $async = false;\n\n    /**\n     * The attributes to track with the request.\n     *\n     * @var array<array-key, mixed>\n     */\n    protected $attributes = [];\n\n    /**\n     * The pending request promise.\n     *\n     * @var \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    protected $promise;\n\n    /**\n     * The sent request object, if a request has been made.\n     *\n     * @var \\Illuminate\\Http\\Client\\Request|null\n     */\n    protected $request;\n\n    /**\n     * The Guzzle request options that are mergeable via array_merge_recursive.\n     *\n     * @var array\n     */\n    protected $mergeableOptions = [\n        'cookies',\n        'form_params',\n        'headers',\n        'json',\n        'multipart',\n        'query',\n    ];\n\n    /**\n     * The length at which request exceptions will be truncated.\n     *\n     * @var int<1, max>|false|null\n     */\n    protected $truncateExceptionsAt = null;\n\n    /**\n     * Create a new HTTP Client instance.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Factory|null  $factory\n     * @param  array  $middleware\n     */\n    public function __construct(?Factory $factory = null, $middleware = [])\n    {\n        $this->factory = $factory;\n        $this->middleware = new Collection($middleware);\n\n        $this->asJson();\n\n        $this->options = [\n            'connect_timeout' => 10,\n            'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,\n            'http_errors' => false,\n            'timeout' => 30,\n        ];\n\n        $this->beforeSendingCallbacks = new Collection([function (Request $request, array $options, PendingRequest $pendingRequest) {\n            $pendingRequest->request = $request;\n            $pendingRequest->cookies = $options['cookies'];\n\n            $pendingRequest->dispatchRequestSendingEvent();\n        }]);\n\n        $this->afterResponseCallbacks = new Collection();\n    }\n\n    /**\n     * Set the base URL for the pending request.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function baseUrl(string $url)\n    {\n        $this->baseUrl = $url;\n\n        return $this;\n    }\n\n    /**\n     * Attach a raw body to the request.\n     *\n     * @param  \\Psr\\Http\\Message\\StreamInterface|string  $content\n     * @param  string  $contentType\n     * @return $this\n     */\n    public function withBody($content, $contentType = 'application/json')\n    {\n        $this->bodyFormat('body');\n\n        $this->pendingBody = $content;\n\n        $this->contentType($contentType);\n\n        return $this;\n    }\n\n    /**\n     * Indicate the request contains JSON.\n     *\n     * @return $this\n     */\n    public function asJson()\n    {\n        return $this->bodyFormat('json')->contentType('application/json');\n    }\n\n    /**\n     * Indicate the request contains form parameters.\n     *\n     * @return $this\n     */\n    public function asForm()\n    {\n        return $this->bodyFormat('form_params')->contentType('application/x-www-form-urlencoded');\n    }\n\n    /**\n     * Attach a file to the request.\n     *\n     * @param  string|array  $name\n     * @param  string|resource  $contents\n     * @param  string|null  $filename\n     * @param  array  $headers\n     * @return $this\n     */\n    public function attach($name, $contents = '', $filename = null, array $headers = [])\n    {\n        if (is_array($name)) {\n            foreach ($name as $file) {\n                $this->attach(...$file);\n            }\n\n            return $this;\n        }\n\n        $this->asMultipart();\n\n        $this->pendingFiles[] = array_filter([\n            'name' => $name,\n            'contents' => $contents,\n            'headers' => $headers,\n            'filename' => $filename,\n        ]);\n\n        return $this;\n    }\n\n    /**\n     * Indicate the request is a multi-part form request.\n     *\n     * @return $this\n     */\n    public function asMultipart()\n    {\n        return $this->bodyFormat('multipart');\n    }\n\n    /**\n     * Specify the body format of the request.\n     *\n     * @param  string  $format\n     * @return $this\n     */\n    public function bodyFormat(string $format)\n    {\n        $this->bodyFormat = $format;\n\n        return $this;\n    }\n\n    /**\n     * Set the given query parameters in the request URI.\n     *\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function withQueryParameters(array $parameters)\n    {\n        $this->options = array_merge_recursive($this->options, [\n            'query' => $parameters,\n        ]);\n\n        return $this;\n    }\n\n    /**\n     * Specify the request's content type.\n     *\n     * @param  string  $contentType\n     * @return $this\n     */\n    public function contentType(string $contentType)\n    {\n        $this->options['headers']['Content-Type'] = $contentType;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that JSON should be returned by the server.\n     *\n     * @return $this\n     */\n    public function acceptJson()\n    {\n        return $this->accept('application/json');\n    }\n\n    /**\n     * Indicate the type of content that should be returned by the server.\n     *\n     * @param  string  $contentType\n     * @return $this\n     */\n    public function accept($contentType)\n    {\n        return $this->withHeaders(['Accept' => $contentType]);\n    }\n\n    /**\n     * Add the given headers to the request.\n     *\n     * @param  array  $headers\n     * @return $this\n     */\n    public function withHeaders(array $headers)\n    {\n        $this->options = array_merge_recursive($this->options, [\n            'headers' => $headers,\n        ]);\n\n        return $this;\n    }\n\n    /**\n     * Add the given header to the request.\n     *\n     * @param  string  $name\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function withHeader($name, $value)\n    {\n        return $this->withHeaders([$name => $value]);\n    }\n\n    /**\n     * Replace the given headers on the request.\n     *\n     * @param  array  $headers\n     * @return $this\n     */\n    public function replaceHeaders(array $headers)\n    {\n        $this->options['headers'] = array_merge($this->options['headers'] ?? [], $headers);\n\n        return $this;\n    }\n\n    /**\n     * Specify the basic authentication username and password for the request.\n     *\n     * @param  string  $username\n     * @param  string  $password\n     * @return $this\n     */\n    public function withBasicAuth(string $username, string $password)\n    {\n        $this->options['auth'] = [$username, $password];\n\n        return $this;\n    }\n\n    /**\n     * Specify the digest authentication username and password for the request.\n     *\n     * @param  string  $username\n     * @param  string  $password\n     * @return $this\n     */\n    public function withDigestAuth($username, $password)\n    {\n        $this->options['auth'] = [$username, $password, 'digest'];\n\n        return $this;\n    }\n\n    /**\n     * Specify the NTLM authentication username and password for the request.\n     *\n     * @param  string  $username\n     * @param  string  $password\n     * @return $this\n     */\n    public function withNtlmAuth($username, $password)\n    {\n        $this->options['auth'] = [$username, $password, 'ntlm'];\n\n        return $this;\n    }\n\n    /**\n     * Specify an authorization token for the request.\n     *\n     * @param  string  $token\n     * @param  string  $type\n     * @return $this\n     */\n    public function withToken($token, $type = 'Bearer')\n    {\n        $this->options['headers']['Authorization'] = trim($type.' '.$token);\n\n        return $this;\n    }\n\n    /**\n     * Specify the user agent for the request.\n     *\n     * @param  string|bool  $userAgent\n     * @return $this\n     */\n    public function withUserAgent($userAgent)\n    {\n        $this->options['headers']['User-Agent'] = trim($userAgent);\n\n        return $this;\n    }\n\n    /**\n     * Specify the URL parameters that can be substituted into the request URL.\n     *\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function withUrlParameters(array $parameters = [])\n    {\n        $this->urlParameters = array_merge($this->urlParameters, $parameters);\n\n        return $this;\n    }\n\n    /**\n     * Specify the cookies that should be included with the request.\n     *\n     * @param  array  $cookies\n     * @param  string  $domain\n     * @return $this\n     */\n    public function withCookies(array $cookies, string $domain)\n    {\n        $this->options = array_merge_recursive($this->options, [\n            'cookies' => CookieJar::fromArray($cookies, $domain),\n        ]);\n\n        return $this;\n    }\n\n    /**\n     * Specify the maximum number of redirects to allow.\n     *\n     * @param  int  $max\n     * @return $this\n     */\n    public function maxRedirects(int $max)\n    {\n        $this->options['allow_redirects']['max'] = $max;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that redirects should not be followed.\n     *\n     * @return $this\n     */\n    public function withoutRedirecting()\n    {\n        $this->options['allow_redirects'] = false;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that TLS certificates should not be verified.\n     *\n     * @return $this\n     */\n    public function withoutVerifying()\n    {\n        $this->options['verify'] = false;\n\n        return $this;\n    }\n\n    /**\n     * Specify the path where the body of the response should be stored.\n     *\n     * @param  string|resource  $to\n     * @return $this\n     */\n    public function sink($to)\n    {\n        $this->options['sink'] = $to;\n\n        return $this;\n    }\n\n    /**\n     * Specify the timeout (in seconds) for the request.\n     *\n     * @param  int|float  $seconds\n     * @return $this\n     */\n    public function timeout(int|float $seconds)\n    {\n        $this->options['timeout'] = $seconds;\n\n        return $this;\n    }\n\n    /**\n     * Specify the connect timeout (in seconds) for the request.\n     *\n     * @param  int|float  $seconds\n     * @return $this\n     */\n    public function connectTimeout(int|float $seconds)\n    {\n        $this->options['connect_timeout'] = $seconds;\n\n        return $this;\n    }\n\n    /**\n     * Specify the number of times the request should be attempted.\n     *\n     * @param  array|int  $times\n     * @param  (Closure(int, mixed): int)|int  $sleepMilliseconds\n     * @param  (callable(\\Throwable, static, string|null): bool)|null  $when\n     * @param  bool  $throw\n     * @return $this\n     */\n    public function retry(array|int $times, Closure|int $sleepMilliseconds = 0, ?callable $when = null, bool $throw = true)\n    {\n        $this->tries = $times;\n        $this->retryDelay = $sleepMilliseconds;\n        $this->retryWhenCallback = $when;\n        $this->retryThrow = $throw;\n\n        return $this;\n    }\n\n    /**\n     * Replace the specified options on the request.\n     *\n     * @param  array  $options\n     * @return $this\n     */\n    public function withOptions(array $options)\n    {\n        $this->options = array_replace_recursive(\n            array_merge_recursive($this->options, Arr::only($options, $this->mergeableOptions)),\n            $options\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add new middleware the client handler stack.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function withMiddleware(callable $middleware)\n    {\n        $this->middleware->push($middleware);\n\n        return $this;\n    }\n\n    /**\n     * Add new request middleware the client handler stack.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function withRequestMiddleware(callable $middleware)\n    {\n        $this->middleware->push(Middleware::mapRequest($middleware));\n\n        return $this;\n    }\n\n    /**\n     * Add new response middleware the client handler stack.\n     *\n     * @param  callable  $middleware\n     * @return $this\n     */\n    public function withResponseMiddleware(callable $middleware)\n    {\n        $this->middleware->push(Middleware::mapResponse($middleware));\n\n        return $this;\n    }\n\n    /**\n     * Set arbitrary attributes to store with the request.\n     *\n     * @param  array<array-key, mixed>  $attributes\n     * @return $this\n     */\n    public function withAttributes($attributes)\n    {\n        $this->attributes = array_merge_recursive($this->attributes, $attributes);\n\n        return $this;\n    }\n\n    /**\n     * Add a new \"before sending\" callback to the request.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function beforeSending($callback)\n    {\n        $this->beforeSendingCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Add a new callback to execute after the response is built.\n     *\n     * @param  (callable(\\Illuminate\\Http\\Client\\Response): \\Illuminate\\Http\\Client\\Response|null)  $callback\n     * @return $this\n     */\n    public function afterResponse(callable $callback)\n    {\n        $this->afterResponseCallbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Throw an exception if a server or client error occurs.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     */\n    public function throw(?callable $callback = null)\n    {\n        $this->throwCallback = $callback ?: fn () => null;\n\n        return $this;\n    }\n\n    /**\n     * Throw an exception if a server or client error occurred and the given condition evaluates to true.\n     *\n     * @param  callable|bool  $condition\n     * @return $this\n     */\n    public function throwIf($condition)\n    {\n        if (is_callable($condition)) {\n            $this->throwIfCallback = $condition;\n        }\n\n        return $condition ? $this->throw(func_get_args()[1] ?? null) : $this;\n    }\n\n    /**\n     * Throw an exception if a server or client error occurred and the given condition evaluates to false.\n     *\n     * @param  callable|bool  $condition\n     * @return $this\n     */\n    public function throwUnless($condition)\n    {\n        return $this->throwIf(! $condition);\n    }\n\n    /**\n     * Dump the request before sending.\n     *\n     * @return $this\n     */\n    public function dump()\n    {\n        $values = func_get_args();\n\n        return $this->beforeSending(function (Request $request, array $options) use ($values) {\n            foreach (array_merge($values, [$request, $options]) as $value) {\n                VarDumper::dump($value);\n            }\n        });\n    }\n\n    /**\n     * Dump the request before sending and end the script.\n     *\n     * @return $this\n     */\n    public function dd()\n    {\n        $values = func_get_args();\n\n        return $this->beforeSending(function (Request $request, array $options) use ($values) {\n            foreach (array_merge($values, [$request, $options]) as $value) {\n                VarDumper::dump($value);\n            }\n\n            exit(1);\n        });\n    }\n\n    /**\n     * Issue a GET request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|string|null  $query\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function get(string $url, $query = null)\n    {\n        return $this->send('GET', $url, func_num_args() === 1 ? [] : [\n            'query' => $query,\n        ]);\n    }\n\n    /**\n     * Issue a HEAD request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|string|null  $query\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function head(string $url, $query = null)\n    {\n        return $this->send('HEAD', $url, func_num_args() === 1 ? [] : [\n            'query' => $query,\n        ]);\n    }\n\n    /**\n     * Issue a POST request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable  $data\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function post(string $url, $data = [])\n    {\n        return $this->send('POST', $url, [\n            $this->bodyFormat => $data,\n        ]);\n    }\n\n    /**\n     * Issue a PATCH request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable  $data\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function patch(string $url, $data = [])\n    {\n        return $this->send('PATCH', $url, [\n            $this->bodyFormat => $data,\n        ]);\n    }\n\n    /**\n     * Issue a PUT request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable  $data\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function put(string $url, $data = [])\n    {\n        return $this->send('PUT', $url, [\n            $this->bodyFormat => $data,\n        ]);\n    }\n\n    /**\n     * Issue a DELETE request to the given URL.\n     *\n     * @param  string  $url\n     * @param  array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable  $data\n     * @return \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @phpstan-return (TAsync is false ?  \\Illuminate\\Http\\Client\\Response : \\GuzzleHttp\\Promise\\PromiseInterface)\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function delete(string $url, $data = [])\n    {\n        return $this->send('DELETE', $url, empty($data) ? [] : [\n            $this->bodyFormat => $data,\n        ]);\n    }\n\n    /**\n     * Send a pool of asynchronous requests concurrently.\n     *\n     * @param  (callable(\\Illuminate\\Http\\Client\\Pool): mixed)  $callback\n     * @param  non-negative-int|null  $concurrency\n     * @return array<array-key, \\Illuminate\\Http\\Client\\Response|\\Throwable>\n     */\n    public function pool(callable $callback, ?int $concurrency = 0)\n    {\n        $results = [];\n\n        $requests = tap(new Pool($this->factory), $callback)->getRequests();\n\n        if ($concurrency === null) {\n            (new Collection($requests))->each(static function ($item) {\n                if ($item instanceof static) {\n                    $item = $item->getPromise();\n                }\n\n                if ($item instanceof LazyPromise) {\n                    $item->buildPromise();\n                }\n            });\n\n            foreach ($requests as $key => $item) {\n                $results[$key] = $item instanceof static ? $item->getPromise()->wait() : $item->wait();\n            }\n\n            return $results;\n        }\n\n        $concurrency = $concurrency === 0 ? count($requests) : $concurrency;\n\n        $promiseGenerator = static function () use ($requests) {\n            foreach ($requests as $key => $item) {\n                $promise = $item instanceof static ? $item->getPromise() : $item;\n                yield $key => $promise instanceof LazyPromise ? $promise->buildPromise() : $promise;\n            }\n        };\n\n        (new EachPromise($promiseGenerator(), [\n            'fulfilled' => function ($result, $key) use (&$results) {\n                $results[$key] = $result;\n            },\n            'rejected' => function ($reason, $key) use (&$results) {\n                $results[$key] = $reason;\n            },\n            'concurrency' => $concurrency,\n        ]))->promise()->wait();\n\n        return $results;\n    }\n\n    /**\n     * Send a pool of asynchronous requests concurrently, with callbacks for introspection.\n     *\n     * @param  callable  $callback\n     * @return \\Illuminate\\Http\\Client\\Batch\n     */\n    public function batch(callable $callback): Batch\n    {\n        return tap(new Batch($this->factory), $callback);\n    }\n\n    /**\n     * Send the request to the given URL.\n     *\n     * @param  string  $method\n     * @param  string  $url\n     * @param  array  $options\n     * @return \\Illuminate\\Http\\Client\\Response|\\Illuminate\\Http\\Client\\Promises\\LazyPromise\n     *\n     * @phpstan-return (TAsync is false ? \\Illuminate\\Http\\Client\\Response : \\Illuminate\\Http\\Client\\Promises\\LazyPromise)\n     *\n     * @throws \\Exception\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    public function send(string $method, string $url, array $options = [])\n    {\n        if (! Str::startsWith($url, ['http://', 'https://'])) {\n            $url = ltrim(rtrim($this->baseUrl, '/').'/'.ltrim($url, '/'), '/');\n        }\n\n        $url = $this->expandUrlParameters($url);\n\n        $options = $this->parseHttpOptions($options);\n\n        [$this->pendingBody, $this->pendingFiles] = [null, []];\n\n        if ($this->async) {\n            return $this->promise = new LazyPromise(\n                fn () => $this->makePromise($method, $url, $options)\n            );\n        }\n\n        $shouldRetry = null;\n\n        return retry($this->tries ?? 1, function ($attempt) use ($method, $url, $options, &$shouldRetry) {\n            try {\n                return tap($this->newResponse($this->sendRequest($method, $url, $options)), function (&$response) use ($attempt, &$shouldRetry) {\n                    $this->populateResponse($response);\n\n                    $this->dispatchResponseReceivedEvent($response);\n                    $response = $this->runAfterResponseCallbacks($response);\n\n                    if ($response->successful()) {\n                        return;\n                    }\n\n                    try {\n                        $shouldRetry = $this->retryWhenCallback ? call_user_func($this->retryWhenCallback, $response->toException(), $this, $this->request->toPsrRequest()->getMethod()) : true;\n                    } catch (Exception $exception) {\n                        $shouldRetry = false;\n\n                        throw $exception;\n                    }\n\n                    if ($this->throwCallback &&\n                        ($this->throwIfCallback === null ||\n                         call_user_func($this->throwIfCallback, $response))) {\n                        $response->throw($this->throwCallback);\n                    }\n\n                    $potentialTries = is_array($this->tries)\n                        ? count($this->tries) + 1\n                        : $this->tries;\n\n                    if ($attempt < $potentialTries && $shouldRetry) {\n                        $response->throw();\n                    }\n\n                    if ($potentialTries > 1 && $this->retryThrow) {\n                        $response->throw();\n                    }\n                });\n            } catch (TransferException $e) {\n                if ($e instanceof ConnectException) {\n                    $this->marshalConnectionException($e);\n                }\n\n                if ($e instanceof RequestException && ! $e->hasResponse()) {\n                    $this->marshalRequestExceptionWithoutResponse($e);\n                }\n\n                if ($e instanceof RequestException && $e->hasResponse()) {\n                    $this->marshalRequestExceptionWithResponse($e);\n                }\n\n                throw $e;\n            }\n        }, $this->retryDelay ?? 100, function ($exception) use (&$shouldRetry) {\n            $result = $shouldRetry !== null ? $shouldRetry : ($this->retryWhenCallback ? call_user_func($this->retryWhenCallback, $exception, $this, $this->request?->toPsrRequest()->getMethod()) : true);\n\n            $shouldRetry = null;\n\n            return $result;\n        });\n    }\n\n    /**\n     * Substitute the URL parameters in the given URL.\n     *\n     * @param  string  $url\n     * @return string\n     */\n    protected function expandUrlParameters(string $url)\n    {\n        return UriTemplate::expand($url, $this->urlParameters);\n    }\n\n    /**\n     * Parse the given HTTP options and set the appropriate additional options.\n     *\n     * @param  array  $options\n     * @return array\n     */\n    protected function parseHttpOptions(array $options)\n    {\n        if (isset($options[$this->bodyFormat])) {\n            if ($this->bodyFormat === 'multipart') {\n                $options[$this->bodyFormat] = $this->parseMultipartBodyFormat($options[$this->bodyFormat]);\n            } elseif ($this->bodyFormat === 'body') {\n                $options[$this->bodyFormat] = $this->pendingBody;\n            }\n\n            if (is_array($options[$this->bodyFormat])) {\n                $options[$this->bodyFormat] = array_merge(\n                    $options[$this->bodyFormat], $this->pendingFiles\n                );\n            }\n        } else {\n            $options[$this->bodyFormat] = $this->pendingBody;\n        }\n\n        return (new Collection($options))\n            ->map(function ($value, $key) {\n                if ($key === 'json' && $value instanceof JsonSerializable) {\n                    return $value;\n                }\n\n                return $value instanceof Arrayable ? $value->toArray() : $value;\n            })\n            ->all();\n    }\n\n    /**\n     * Parse multi-part form data.\n     *\n     * @param  array  $data\n     * @return array|array[]\n     */\n    protected function parseMultipartBodyFormat(array $data)\n    {\n        return (new Collection($data))\n            ->flatMap(function ($value, $key) {\n                if (is_array($value)) {\n                    // If the array has 'name' and 'contents' keys, it's already formatted for multipart...\n                    if (isset($value['name']) && isset($value['contents'])) {\n                        return [$value];\n                    }\n\n                    // Otherwise, treat it as multiple values for the same field name...\n                    return (new Collection($value))->map(function ($item) use ($key) {\n                        return ['name' => $key.'[]', 'contents' => $item];\n                    });\n                }\n\n                return [['name' => $key, 'contents' => $value]];\n            })\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Send an asynchronous request to the given URL.\n     *\n     * @param  string  $method\n     * @param  string  $url\n     * @param  array  $options\n     * @param  int  $attempt\n     * @return \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    protected function makePromise(string $method, string $url, array $options = [], int $attempt = 1)\n    {\n        return $this->promise = $this->sendRequest($method, $url, $options)\n            ->then(function (MessageInterface $message) {\n                $response = $this->newResponse($message);\n\n                $this->populateResponse($response);\n                $this->dispatchResponseReceivedEvent($response);\n\n                return $this->runAfterResponseCallbacks($response);\n            })\n            ->otherwise(function (Throwable $e) {\n                if ($e instanceof StrayRequestException) {\n                    throw $e;\n                }\n\n                if ($e instanceof ConnectException || ($e instanceof RequestException && ! $e->hasResponse())) {\n                    $exception = new ConnectionException($e->getMessage(), 0, $e);\n\n                    $this->dispatchConnectionFailedEvent(\n                        (new Request($e->getRequest()))->setRequestAttributes($this->attributes),\n                        $exception\n                    );\n\n                    return $exception;\n                }\n\n                return $e instanceof RequestException && $e->hasResponse() ? $this->populateResponse($this->newResponse($e->getResponse())) : $e;\n            })\n            ->then(function (Response|Throwable $response) use ($method, $url, $options, $attempt) {\n                return $this->handlePromiseResponse($response, $method, $url, $options, $attempt);\n            });\n    }\n\n    /**\n     * Handle the response of an asynchronous request.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response|\\Throwable  $response\n     * @param  string  $method\n     * @param  string  $url\n     * @param  array  $options\n     * @param  int  $attempt\n     * @return mixed\n     */\n    protected function handlePromiseResponse(Response|Throwable $response, $method, $url, $options, $attempt)\n    {\n        if ($response instanceof Response && $response->successful()) {\n            return $response;\n        }\n\n        if ($response instanceof RequestException) {\n            $response = $this->populateResponse($this->newResponse($response->getResponse()));\n        }\n\n        try {\n            $shouldRetry = $this->retryWhenCallback ? call_user_func(\n                $this->retryWhenCallback,\n                $response instanceof Response ? $response->toException() : $response,\n                $this\n            ) : true;\n        } catch (Exception $exception) {\n            return $exception;\n        }\n\n        if ($attempt < $this->tries && $shouldRetry) {\n            $options['delay'] = value(\n                $this->retryDelay,\n                $attempt,\n                $response instanceof Response ? $response->toException() : $response\n            );\n\n            return $this->makePromise($method, $url, $options, $attempt + 1);\n        }\n\n        if ($response instanceof Response &&\n            $this->throwCallback &&\n            ($this->throwIfCallback === null || call_user_func($this->throwIfCallback, $response))) {\n            try {\n                $response->throw($this->throwCallback);\n            } catch (Exception $exception) {\n                return $exception;\n            }\n        }\n\n        if ($this->tries > 1 && $this->retryThrow) {\n            return $response instanceof Response ? $response->toException() : $response;\n        }\n\n        return $response;\n    }\n\n    /**\n     * Send a request either synchronously or asynchronously.\n     *\n     * @param  string  $method\n     * @param  string  $url\n     * @param  array  $options\n     * @return \\Psr\\Http\\Message\\MessageInterface|\\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @throws \\Exception\n     */\n    protected function sendRequest(string $method, string $url, array $options = [])\n    {\n        $clientMethod = $this->async ? 'requestAsync' : 'request';\n\n        $laravelData = $this->parseRequestData($method, $url, $options);\n\n        $onStats = function ($transferStats) {\n            if (($callback = ($this->options['on_stats'] ?? false)) instanceof Closure) {\n                $transferStats = $callback($transferStats) ?: $transferStats;\n            }\n\n            $this->transferStats = $transferStats;\n        };\n\n        $mergedOptions = $this->normalizeRequestOptions($this->mergeOptions([\n            'laravel_data' => $laravelData,\n            'on_stats' => $onStats,\n        ], $options));\n\n        $result = $this->buildClient()->$clientMethod($method, $url, $mergedOptions);\n\n        if ($result instanceof PromiseInterface && ! $result instanceof FluentPromise) {\n            $result = new FluentPromise($result);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get the request data as an array so that we can attach it to the request for convenient assertions.\n     *\n     * @param  string  $method\n     * @param  string  $url\n     * @param  array  $options\n     * @return array\n     */\n    protected function parseRequestData($method, $url, array $options)\n    {\n        if ($this->bodyFormat === 'body') {\n            return [];\n        }\n\n        $laravelData = $options[$this->bodyFormat] ?? $options['query'] ?? [];\n\n        $urlString = (new Stringable($url));\n\n        if (empty($laravelData) && $method === 'GET' && $urlString->contains('?')) {\n            $laravelData = (string) $urlString->after('?');\n        }\n\n        if (is_string($laravelData)) {\n            parse_str($laravelData, $parsedData);\n\n            $laravelData = is_array($parsedData) ? $parsedData : [];\n        }\n\n        if ($laravelData instanceof JsonSerializable) {\n            $laravelData = $laravelData->jsonSerialize();\n        }\n\n        return is_array($laravelData) ? $laravelData : [];\n    }\n\n    /**\n     * Normalize the given request options.\n     *\n     * @param  array  $options\n     * @return array\n     */\n    protected function normalizeRequestOptions(array $options)\n    {\n        foreach ($options as $key => $value) {\n            $options[$key] = match (true) {\n                is_array($value) => $this->normalizeRequestOptions($value),\n                $value instanceof Stringable => $value->toString(),\n                default => $value,\n            };\n        }\n\n        return $options;\n    }\n\n    /**\n     * Populate the given response with additional data.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     * @return \\Illuminate\\Http\\Client\\Response\n     */\n    protected function populateResponse(Response $response)\n    {\n        $response->cookies = $this->cookies;\n\n        $response->transferStats = $this->transferStats;\n\n        return $response;\n    }\n\n    /**\n     * Build the Guzzle client.\n     *\n     * @return \\GuzzleHttp\\Client\n     */\n    public function buildClient()\n    {\n        return $this->client ?? $this->createClient($this->buildHandlerStack());\n    }\n\n    /**\n     * Determine if a reusable client is required.\n     *\n     * @return bool\n     */\n    protected function requestsReusableClient()\n    {\n        return ! is_null($this->client) || $this->async;\n    }\n\n    /**\n     * Retrieve a reusable Guzzle client.\n     *\n     * @return \\GuzzleHttp\\Client\n     */\n    protected function getReusableClient()\n    {\n        return $this->client ??= $this->createClient($this->buildHandlerStack());\n    }\n\n    /**\n     * Create new Guzzle client.\n     *\n     * @param  \\GuzzleHttp\\HandlerStack  $handlerStack\n     * @return \\GuzzleHttp\\Client\n     */\n    public function createClient($handlerStack)\n    {\n        return new Client([\n            'handler' => $handlerStack,\n            'cookies' => true,\n        ]);\n    }\n\n    /**\n     * Build the Guzzle client handler stack.\n     *\n     * @return \\GuzzleHttp\\HandlerStack\n     */\n    public function buildHandlerStack()\n    {\n        return $this->pushHandlers(HandlerStack::create($this->handler));\n    }\n\n    /**\n     * Add the necessary handlers to the given handler stack.\n     *\n     * @param  \\GuzzleHttp\\HandlerStack  $handlerStack\n     * @return \\GuzzleHttp\\HandlerStack\n     */\n    public function pushHandlers($handlerStack)\n    {\n        return tap($handlerStack, function ($stack) {\n            $this->middleware->each(function ($middleware) use ($stack) {\n                $stack->push($middleware);\n            });\n\n            $stack->push($this->buildBeforeSendingHandler());\n            $stack->push($this->buildRecorderHandler());\n            $stack->push($this->buildStubHandler());\n        });\n    }\n\n    /**\n     * Build the before sending handler.\n     *\n     * @return \\Closure\n     */\n    public function buildBeforeSendingHandler()\n    {\n        return function ($handler) {\n            return function ($request, $options) use ($handler) {\n                return $handler($this->runBeforeSendingCallbacks($request, $options), $options);\n            };\n        };\n    }\n\n    /**\n     * Build the recorder handler.\n     *\n     * @return \\Closure\n     */\n    public function buildRecorderHandler()\n    {\n        return function ($handler) {\n            return function ($request, $options) use ($handler) {\n                $promise = $handler($request, $options);\n\n                return $promise->then(function ($response) use ($request, $options) {\n                    $this->factory?->recordRequestResponsePair(\n                        (new Request($request))\n                            ->withData($options['laravel_data'])\n                            ->setRequestAttributes($this->attributes),\n                        $this->newResponse($response)\n                    );\n\n                    return $response;\n                });\n            };\n        };\n    }\n\n    /**\n     * Build the stub handler.\n     *\n     * @return \\Closure\n     *\n     * @throws \\Illuminate\\Http\\Client\\Exceptions\\StrayRequestException\n     */\n    public function buildStubHandler()\n    {\n        return function ($handler) {\n            return function ($request, $options) use ($handler) {\n                $response = ($this->stubCallbacks ?? new Collection)\n                    ->map\n                    ->__invoke(\n                        (new Request($request))\n                            ->withData($options['laravel_data'])\n                            ->setRequestAttributes($this->attributes),\n                        $options\n                    )\n                    ->filter()\n                    ->first();\n\n                if (is_null($response)) {\n                    if (! $this->isAllowedRequestUrl((string) $request->getUri())) {\n                        throw new StrayRequestException((string) $request->getUri());\n                    }\n\n                    return $handler($request, $options);\n                }\n\n                $response = is_array($response) ? Factory::response($response) : $response;\n\n                $sink = $options['sink'] ?? null;\n\n                if ($sink) {\n                    $response->then($this->sinkStubHandler($sink));\n                }\n\n                return $response;\n            };\n        };\n    }\n\n    /**\n     * Get the sink stub handler callback.\n     *\n     * @param  string  $sink\n     * @return \\Closure\n     */\n    protected function sinkStubHandler($sink)\n    {\n        return function ($response) use ($sink) {\n            $body = $response->getBody()->getContents();\n\n            if (is_string($sink)) {\n                file_put_contents($sink, $body);\n\n                return;\n            }\n\n            fwrite($sink, $body);\n            rewind($sink);\n        };\n    }\n\n    /**\n     * Execute the \"before sending\" callbacks.\n     *\n     * @param  \\Psr\\Http\\Message\\RequestInterface  $request\n     * @param  array  $options\n     * @return \\Psr\\Http\\Message\\RequestInterface\n     */\n    public function runBeforeSendingCallbacks($request, array $options)\n    {\n        return tap($request, function (&$request) use ($options) {\n            $this->beforeSendingCallbacks->each(function ($callback) use (&$request, $options) {\n                $callbackResult = call_user_func(\n                    $callback,\n                    (new Request($request))\n                        ->withData($options['laravel_data'])\n                        ->setRequestAttributes($this->attributes),\n                    $options,\n                    $this\n                );\n\n                if ($callbackResult instanceof RequestInterface) {\n                    $request = $callbackResult;\n                } elseif ($callbackResult instanceof Request) {\n                    $request = $callbackResult->toPsrRequest();\n                }\n            });\n        });\n    }\n\n    /**\n     * Replace the given options with the current request options.\n     *\n     * @param  array  ...$options\n     * @return array\n     */\n    public function mergeOptions(...$options)\n    {\n        return array_replace_recursive(\n            array_merge_recursive($this->options, Arr::only($options, $this->mergeableOptions)),\n            ...$options\n        );\n    }\n\n    /**\n     * Create a new response instance using the given PSR response.\n     *\n     * @param  \\Psr\\Http\\Message\\MessageInterface  $response\n     * @return Response\n     */\n    protected function newResponse($response)\n    {\n        return tap(new Response($response), function (Response $laravelResponse) {\n            if ($this->truncateExceptionsAt === null) {\n                return;\n            }\n\n            $this->truncateExceptionsAt === false\n                ? $laravelResponse->dontTruncateExceptions()\n                : $laravelResponse->truncateExceptionsAt($this->truncateExceptionsAt);\n        });\n    }\n\n    /**\n     * Execute the \"after response\" callbacks.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     * @return \\Illuminate\\Http\\Client\\Response\n     */\n    protected function runAfterResponseCallbacks(Response $response)\n    {\n        foreach ($this->afterResponseCallbacks as $callback) {\n            $returnedResponse = $callback($response);\n\n            if ($returnedResponse instanceof Response) {\n                $response = $returnedResponse;\n            }\n        }\n\n        return $response;\n    }\n\n    /**\n     * Register a stub callable that will intercept requests and be able to return stub responses.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function stub($callback)\n    {\n        $this->stubCallbacks = new Collection($callback);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that an exception should be thrown if any request is not faked.\n     *\n     * @param  bool  $prevent\n     * @return $this\n     */\n    public function preventStrayRequests($prevent = true)\n    {\n        $this->preventStrayRequests = $prevent;\n\n        return $this;\n    }\n\n    /**\n     * Allow stray, unfaked requests entirely, or optionally allow only specific URLs.\n     *\n     * @param  array<int, string>  $only\n     * @return $this\n     */\n    public function allowStrayRequests(array $only)\n    {\n        $this->allowedStrayRequestUrls = array_values($only);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given URL is allowed as a stray request.\n     *\n     * @param  string  $url\n     * @return bool\n     */\n    public function isAllowedRequestUrl($url)\n    {\n        if (! $this->preventStrayRequests) {\n            return true;\n        }\n\n        foreach ($this->allowedStrayRequestUrls as $pattern) {\n            if (Str::is($pattern, $url)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Toggle asynchronicity in requests.\n     *\n     * @template T of bool = true\n     *\n     * @param  T  $async\n     * @return self<T>\n     *\n     * @phpstan-self-out self<T>\n     */\n    public function async(bool $async = true)\n    {\n        $this->async = $async;\n\n        return $this;\n    }\n\n    /**\n     * Retrieve the pending request promise.\n     *\n     * @return \\GuzzleHttp\\Promise\\PromiseInterface|null\n     */\n    public function getPromise()\n    {\n        return $this->promise;\n    }\n\n    /**\n     * Dispatch the RequestSending event if a dispatcher is available.\n     *\n     * @return void\n     */\n    protected function dispatchRequestSendingEvent()\n    {\n        if ($dispatcher = $this->factory?->getDispatcher()) {\n            $dispatcher->dispatch(new RequestSending($this->request));\n        }\n    }\n\n    /**\n     * Dispatch the ResponseReceived event if a dispatcher is available.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     * @return void\n     */\n    protected function dispatchResponseReceivedEvent(Response $response)\n    {\n        if (! ($dispatcher = $this->factory?->getDispatcher()) || ! $this->request) {\n            return;\n        }\n\n        $dispatcher->dispatch(new ResponseReceived($this->request, $response));\n    }\n\n    /**\n     * Dispatch the ConnectionFailed event if a dispatcher is available.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     * @param  \\Illuminate\\Http\\Client\\ConnectionException  $exception\n     * @return void\n     */\n    protected function dispatchConnectionFailedEvent(Request $request, ConnectionException $exception)\n    {\n        if ($dispatcher = $this->factory?->getDispatcher()) {\n            $dispatcher->dispatch(new ConnectionFailed($request, $exception));\n        }\n    }\n\n    /**\n     * Indicate that request exceptions should be truncated to the given length.\n     *\n     * @param  int<1, max>  $length\n     * @return $this\n     */\n    public function truncateExceptionsAt(int $length)\n    {\n        $this->truncateExceptionsAt = $length;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that request exceptions should not be truncated.\n     *\n     * @return $this\n     */\n    public function dontTruncateExceptions()\n    {\n        $this->truncateExceptionsAt = false;\n\n        return $this;\n    }\n\n    /**\n     * Handle the given connection exception.\n     *\n     * @param  \\GuzzleHttp\\Exception\\ConnectException  $e\n     * @return void\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    protected function marshalConnectionException(ConnectException $e)\n    {\n        $exception = new ConnectionException($e->getMessage(), 0, $e);\n\n        $request = (new Request($e->getRequest()))->setRequestAttributes($this->attributes);\n\n        $this->factory?->recordRequestResponsePair(\n            $request, null\n        );\n\n        $this->dispatchConnectionFailedEvent($request, $exception);\n\n        throw $exception;\n    }\n\n    /**\n     * Handle the given request exception.\n     *\n     * @param  \\GuzzleHttp\\Exception\\RequestException  $e\n     * @return void\n     *\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    protected function marshalRequestExceptionWithoutResponse(RequestException $e)\n    {\n        $exception = new ConnectionException($e->getMessage(), 0, $e);\n\n        $request = (new Request($e->getRequest()))->setRequestAttributes($this->attributes);\n\n        $this->factory?->recordRequestResponsePair(\n            $request, null\n        );\n\n        $this->dispatchConnectionFailedEvent($request, $exception);\n\n        throw $exception;\n    }\n\n    /**\n     * Handle the given request exception.\n     *\n     * @param  \\GuzzleHttp\\Exception\\RequestException  $e\n     * @return void\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     * @throws \\Illuminate\\Http\\Client\\ConnectionException\n     */\n    protected function marshalRequestExceptionWithResponse(RequestException $e)\n    {\n        $response = $this->populateResponse($this->newResponse($e->getResponse()));\n\n        $this->factory?->recordRequestResponsePair(\n            (new Request($e->getRequest()))->setRequestAttributes($this->attributes),\n            $response\n        );\n\n        throw $response->toException() ?? new ConnectionException($e->getMessage(), 0, $e);\n    }\n\n    /**\n     * Set the client instance.\n     *\n     * @param  \\GuzzleHttp\\Client  $client\n     * @return $this\n     */\n    public function setClient(Client $client)\n    {\n        $this->client = $client;\n\n        return $this;\n    }\n\n    /**\n     * Create a new client instance using the given handler.\n     *\n     * @param  callable  $handler\n     * @return $this\n     */\n    public function setHandler($handler)\n    {\n        $this->handler = $handler;\n\n        return $this;\n    }\n\n    /**\n     * Get the pending request options.\n     *\n     * @return array\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Pool.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse GuzzleHttp\\Utils;\n\n/**\n * @mixin \\Illuminate\\Http\\Client\\Factory\n */\nclass Pool\n{\n    /**\n     * The factory instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The handler function for the Guzzle client.\n     *\n     * @var callable\n     */\n    protected $handler;\n\n    /**\n     * The pool of requests.\n     *\n     * @var array<array-key, \\Illuminate\\Http\\Client\\PendingRequest>\n     */\n    protected $pool = [];\n\n    /**\n     * Create a new requests pool.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Factory|null  $factory\n     */\n    public function __construct(?Factory $factory = null)\n    {\n        $this->factory = $factory ?: new Factory();\n        $this->handler = Utils::chooseHandler();\n    }\n\n    /**\n     * Add a request to the pool with a numeric index.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest|\\GuzzleHttp\\Promise\\Promise\n     */\n    public function newRequest()\n    {\n        return $this->pool[] = $this->asyncRequest();\n    }\n\n    /**\n     * Add a request to the pool with a key.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     */\n    public function as(string $key)\n    {\n        return $this->pool[$key] = $this->asyncRequest();\n    }\n\n    /**\n     * Retrieve a new async pending request.\n     *\n     * @return \\Illuminate\\Http\\Client\\PendingRequest\n     */\n    protected function asyncRequest()\n    {\n        return $this->factory->setHandler($this->handler)->async();\n    }\n\n    /**\n     * Retrieve the requests in the pool.\n     *\n     * @return array<array-key, \\Illuminate\\Http\\Client\\PendingRequest>\n     */\n    public function getRequests()\n    {\n        return $this->pool;\n    }\n\n    /**\n     * Add a request to the pool with a numeric index and forward the method call to the request.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\Http\\Client\\PendingRequest|\\GuzzleHttp\\Promise\\Promise\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->newRequest()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Promises/FluentPromise.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Promises;\n\nuse GuzzleHttp\\Promise\\PromiseInterface;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\n\n/**\n * A decorated Promise which allows for chaining callbacks.\n */\nclass FluentPromise implements PromiseInterface\n{\n    use ForwardsCalls;\n\n    /**\n     * Create a new fluent promise instance.\n     *\n     * @param  \\GuzzleHttp\\Promise\\PromiseInterface  $guzzlePromise\n     */\n    public function __construct(protected PromiseInterface $guzzlePromise)\n    {\n    }\n\n    #[\\Override]\n    public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface\n    {\n        return $this->__call('then', [$onFulfilled, $onRejected]);\n    }\n\n    #[\\Override]\n    public function otherwise(callable $onRejected): PromiseInterface\n    {\n        return $this->__call('otherwise', [$onRejected]);\n    }\n\n    #[\\Override]\n    public function resolve($value): void\n    {\n        $this->guzzlePromise->resolve($value);\n    }\n\n    #[\\Override]\n    public function reject($reason): void\n    {\n        $this->guzzlePromise->reject($reason);\n    }\n\n    #[\\Override]\n    public function cancel(): void\n    {\n        $this->guzzlePromise->cancel();\n    }\n\n    #[\\Override]\n    public function wait(bool $unwrap = true)\n    {\n        return $this->__call('wait', [$unwrap]);\n    }\n\n    #[\\Override]\n    public function getState(): string\n    {\n        return $this->guzzlePromise->getState();\n    }\n\n    /**\n     * Get the underlying Guzzle promise.\n     *\n     * @return \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    public function getGuzzlePromise(): PromiseInterface\n    {\n        return $this->guzzlePromise;\n    }\n\n    /**\n     * Proxy requests to the underlying promise interface and update the local promise.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        $result = $this->forwardCallTo($this->guzzlePromise, $method, $parameters);\n\n        if (! $result instanceof PromiseInterface) {\n            return $result;\n        }\n\n        $this->guzzlePromise = $result;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Promises/LazyPromise.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client\\Promises;\n\nuse Closure;\nuse GuzzleHttp\\Promise\\PromiseInterface;\nuse RuntimeException;\n\nclass LazyPromise implements PromiseInterface\n{\n    /**\n     * The callbacks to execute after the Guzzle Promise has been built.\n     *\n     * @var list<callable>\n     */\n    protected array $pending = [];\n\n    /**\n     * The promise built by the creator.\n     *\n     * @var \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    protected PromiseInterface $guzzlePromise;\n\n    /**\n     * Create a new lazy promise instance.\n     *\n     * @param  (\\Closure(): \\GuzzleHttp\\Promise\\PromiseInterface)  $promiseBuilder  The callback to build a new PromiseInterface.\n     */\n    public function __construct(protected Closure $promiseBuilder)\n    {\n    }\n\n    /**\n     * Build the promise from the promise builder.\n     *\n     * @return \\GuzzleHttp\\Promise\\PromiseInterface\n     *\n     * @throws \\RuntimeException If the promise has already been built\n     */\n    public function buildPromise(): PromiseInterface\n    {\n        if (! $this->promiseNeedsBuilt()) {\n            throw new RuntimeException('Promise already built');\n        }\n\n        $this->guzzlePromise = call_user_func($this->promiseBuilder);\n\n        foreach ($this->pending as $pendingCallback) {\n            $pendingCallback($this->guzzlePromise);\n        }\n\n        $this->pending = [];\n\n        return $this->guzzlePromise;\n    }\n\n    #[\\Override]\n    public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface\n    {\n        if ($this->promiseNeedsBuilt()) {\n            $this->pending[] = static fn (PromiseInterface $promise) => $promise->then($onFulfilled, $onRejected);\n\n            return $this;\n        }\n\n        return $this->guzzlePromise->then($onFulfilled, $onRejected);\n    }\n\n    #[\\Override]\n    public function otherwise(callable $onRejected): PromiseInterface\n    {\n        if ($this->promiseNeedsBuilt()) {\n            $this->pending[] = static fn (PromiseInterface $promise) => $promise->otherwise($onRejected);\n\n            return $this;\n        }\n\n        return $this->guzzlePromise->otherwise($onRejected);\n    }\n\n    #[\\Override]\n    public function getState(): string\n    {\n        if ($this->promiseNeedsBuilt()) {\n            return PromiseInterface::PENDING;\n        }\n\n        return $this->guzzlePromise->getState();\n    }\n\n    #[\\Override]\n    public function resolve($value): void\n    {\n        throw new \\LogicException('Cannot resolve a lazy promise.');\n    }\n\n    #[\\Override]\n    public function reject($reason): void\n    {\n        throw new \\LogicException('Cannot reject a lazy promise.');\n    }\n\n    #[\\Override]\n    public function cancel(): void\n    {\n        throw new \\LogicException('Cannot cancel a lazy promise.');\n    }\n\n    #[\\Override]\n    public function wait(bool $unwrap = true)\n    {\n        if ($this->promiseNeedsBuilt()) {\n            $this->buildPromise();\n        }\n\n        return $this->guzzlePromise->wait($unwrap);\n    }\n\n    /**\n     * Determine if the promise has been created from the promise builder.\n     *\n     * @return bool\n     */\n    public function promiseNeedsBuilt(): bool\n    {\n        return ! isset($this->guzzlePromise);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Request.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse ArrayAccess;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse LogicException;\n\nclass Request implements ArrayAccess\n{\n    use Macroable;\n\n    /**\n     * The underlying PSR request.\n     *\n     * @var \\Psr\\Http\\Message\\RequestInterface\n     */\n    protected $request;\n\n    /**\n     * The decoded payload for the request.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The attribute data passed when building the PendingRequest.\n     *\n     * @var array<array-key, mixed>\n     */\n    protected $attributes = [];\n\n    /**\n     * Create a new request instance.\n     *\n     * @param  \\Psr\\Http\\Message\\RequestInterface  $request\n     */\n    public function __construct($request)\n    {\n        $this->request = $request;\n    }\n\n    /**\n     * Get the request method.\n     *\n     * @return string\n     */\n    public function method()\n    {\n        return $this->request->getMethod();\n    }\n\n    /**\n     * Get the URL of the request.\n     *\n     * @return string\n     */\n    public function url()\n    {\n        return (string) $this->request->getUri();\n    }\n\n    /**\n     * Determine if the request has a given header.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasHeader($key, $value = null)\n    {\n        if (is_null($value)) {\n            return ! empty($this->request->getHeaders()[$key]);\n        }\n\n        $headers = $this->headers();\n\n        if (! Arr::has($headers, $key)) {\n            return false;\n        }\n\n        $value = is_array($value) ? $value : [$value];\n\n        return empty(array_diff($value, $headers[$key]));\n    }\n\n    /**\n     * Determine if the request has the given headers.\n     *\n     * @param  array|string  $headers\n     * @return bool\n     */\n    public function hasHeaders($headers)\n    {\n        if (is_string($headers)) {\n            $headers = [$headers => null];\n        }\n\n        foreach ($headers as $key => $value) {\n            if (! $this->hasHeader($key, $value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the values for the header with the given name.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    public function header($key)\n    {\n        return Arr::get($this->headers(), $key, []);\n    }\n\n    /**\n     * Get the request headers.\n     *\n     * @return array\n     */\n    public function headers()\n    {\n        return $this->request->getHeaders();\n    }\n\n    /**\n     * Get the body of the request.\n     *\n     * @return string\n     */\n    public function body()\n    {\n        return (string) $this->request->getBody();\n    }\n\n    /**\n     * Determine if the request contains the given file.\n     *\n     * @param  string  $name\n     * @param  string|null  $value\n     * @param  string|null  $filename\n     * @return bool\n     */\n    public function hasFile($name, $value = null, $filename = null)\n    {\n        if (! $this->isMultipart()) {\n            return false;\n        }\n\n        return (new Collection($this->data))->reject(function ($file) use ($name, $value, $filename) {\n            return $file['name'] != $name ||\n                ($value && $file['contents'] != $value) ||\n                ($filename && $file['filename'] != $filename);\n        })->count() > 0;\n    }\n\n    /**\n     * Get the request's data (form parameters or JSON).\n     *\n     * @return array\n     */\n    public function data()\n    {\n        if ($this->isForm()) {\n            return $this->parameters();\n        } elseif ($this->isJson()) {\n            return $this->json();\n        }\n\n        return $this->data ?? [];\n    }\n\n    /**\n     * Get the request's form parameters.\n     *\n     * @return array\n     */\n    protected function parameters()\n    {\n        if (! $this->data) {\n            parse_str($this->body(), $parameters);\n\n            $this->data = $parameters;\n        }\n\n        return $this->data;\n    }\n\n    /**\n     * Get the decoded JSON body of the request.\n     *\n     * @return array\n     */\n    protected function json()\n    {\n        if (! $this->data) {\n            $this->data = json_decode($this->body(), true) ?? [];\n        }\n\n        return $this->data;\n    }\n\n    /**\n     * Determine if the request is simple form data.\n     *\n     * @return bool\n     */\n    public function isForm()\n    {\n        return $this->hasHeader('Content-Type', 'application/x-www-form-urlencoded');\n    }\n\n    /**\n     * Determine if the request is JSON.\n     *\n     * @return bool\n     */\n    public function isJson()\n    {\n        return $this->hasHeader('Content-Type') &&\n               str_contains($this->header('Content-Type')[0], 'json');\n    }\n\n    /**\n     * Determine if the request is multipart.\n     *\n     * @return bool\n     */\n    public function isMultipart()\n    {\n        return $this->hasHeader('Content-Type') &&\n               str_contains($this->header('Content-Type')[0], 'multipart');\n    }\n\n    /**\n     * Set the decoded data on the request.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function withData(array $data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n\n    /**\n     * Get the attribute data from the request.\n     *\n     * @return array<array-key, mixed>\n     */\n    public function attributes()\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Set the request's attribute data.\n     *\n     * @param  array<array-key, mixed>  $attributes\n     * @return $this\n     */\n    public function setRequestAttributes($attributes)\n    {\n        $this->attributes = $attributes;\n\n        return $this;\n    }\n\n    /**\n     * Get the underlying PSR compliant request instance.\n     *\n     * @return \\Psr\\Http\\Message\\RequestInterface\n     */\n    public function toPsrRequest()\n    {\n        return $this->request;\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->data()[$offset]);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->data()[$offset];\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetSet($offset, $value): void\n    {\n        throw new LogicException('Request data may not be mutated using array access.');\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetUnset($offset): void\n    {\n        throw new LogicException('Request data may not be mutated using array access.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/RequestException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse GuzzleHttp\\Psr7\\Message;\n\nclass RequestException extends HttpClientException\n{\n    /**\n     * The response instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Response\n     */\n    public $response;\n\n    /**\n     * The current truncation length for the exception message.\n     *\n     * @var int|false|null\n     */\n    public $truncateExceptionsAt;\n\n    /**\n     * The global truncation length for the exception message.\n     *\n     * @var int|false\n     */\n    public static $truncateAt = 120;\n\n    /**\n     * Whether the response has been summarized in the message.\n     *\n     * @var bool\n     */\n    public $hasBeenSummarized = false;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     * @param  int|false|null  $truncateExceptionsAt\n     */\n    public function __construct(Response $response, $truncateExceptionsAt = null)\n    {\n        $this->truncateExceptionsAt = $truncateExceptionsAt;\n\n        $this->response = $response;\n\n        parent::__construct($this->prepareMessage($response), $response->status());\n    }\n\n    /**\n     * Enable truncation of request exception messages.\n     *\n     * @return void\n     */\n    public static function truncate()\n    {\n        static::$truncateAt = 120;\n    }\n\n    /**\n     * Set the truncation length for request exception messages.\n     *\n     * @param  int  $length\n     * @return void\n     */\n    public static function truncateAt(int $length)\n    {\n        static::$truncateAt = $length;\n    }\n\n    /**\n     * Disable truncation of request exception messages.\n     *\n     * @return void\n     */\n    public static function dontTruncate()\n    {\n        static::$truncateAt = false;\n    }\n\n    /**\n     * Prepare the exception message.\n     *\n     * @return bool\n     */\n    public function report()\n    {\n        if (! $this->hasBeenSummarized) {\n            $this->message = $this->prepareMessage($this->response);\n\n            $this->hasBeenSummarized = true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Prepare the exception message.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Response  $response\n     * @return string\n     */\n    protected function prepareMessage(Response $response)\n    {\n        $message = \"HTTP request returned status code {$response->status()}\";\n\n        $truncateExceptionsAt = $this->truncateExceptionsAt ?? static::$truncateAt;\n\n        $psrResponse = $response->toPsrResponse();\n\n        $summary = null;\n\n        if (is_int($truncateExceptionsAt)) {\n            $summary = Message::bodySummary($psrResponse, $truncateExceptionsAt);\n        } elseif (($body = $psrResponse->getBody())->isSeekable() && $body->isReadable()) {\n            $summary = Message::toString($psrResponse);\n        }\n\n        return is_null($summary) ? $message : $message.\":\\n{$summary}\\n\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/Response.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse ArrayAccess;\nuse GuzzleHttp\\Psr7\\StreamWrapper;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse LogicException;\nuse Stringable;\n\n/**\n * @mixin \\Psr\\Http\\Message\\ResponseInterface\n */\nclass Response implements ArrayAccess, Stringable\n{\n    use Concerns\\DeterminesStatusCode, Tappable, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The underlying PSR response.\n     *\n     * @var \\Psr\\Http\\Message\\ResponseInterface\n     */\n    protected $response;\n\n    /**\n     * The decoded JSON response.\n     *\n     * @var array\n     */\n    protected $decoded;\n\n    /**\n     * The flags that were used when decoding the JSON response.\n     *\n     * @var int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>\n     */\n    protected int $decodingFlags;\n\n    /**\n     * The request cookies.\n     *\n     * @var \\GuzzleHttp\\Cookie\\CookieJar\n     */\n    public $cookies;\n\n    /**\n     * The transfer stats for the request.\n     *\n     * @var \\GuzzleHttp\\TransferStats|null\n     */\n    public $transferStats;\n\n    /**\n     * The length at which request exceptions will be truncated.\n     *\n     * @var int<1, max>|false|null\n     */\n    protected $truncateExceptionsAt = null;\n\n    /**\n     * The flags passed to `json_decode` by default.\n     *\n     * @var int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>\n     */\n    public static int $defaultJsonDecodingFlags = 0;\n\n    /**\n     * Create a new response instance.\n     *\n     * @param  \\Psr\\Http\\Message\\MessageInterface  $response\n     */\n    public function __construct($response)\n    {\n        $this->response = $response;\n    }\n\n    /**\n     * Get the body of the response.\n     *\n     * @return string\n     */\n    public function body()\n    {\n        return (string) $this->response->getBody();\n    }\n\n    /**\n     * Get the decoded JSON body of the response as an array or scalar value.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @param  int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>|null  $flags\n     * @return mixed\n     */\n    public function json($key = null, $default = null, $flags = null)\n    {\n        $flags = $flags ?? self::$defaultJsonDecodingFlags;\n\n        if (! $this->decoded || (isset($this->decodingFlags) && $this->decodingFlags !== $flags)) {\n            $this->decoded = json_decode(\n                $this->body(), true, flags: $flags\n            );\n\n            $this->decodingFlags = $flags;\n        }\n\n        if (is_null($key)) {\n            return $this->decoded;\n        }\n\n        return data_get($this->decoded, $key, $default);\n    }\n\n    /**\n     * Get the decoded JSON body of the response as an object.\n     *\n     * @param  int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>|null  $flags\n     * @return object|null\n     */\n    public function object($flags = null)\n    {\n        return json_decode($this->body(), false, flags: $flags ?? self::$defaultJsonDecodingFlags);\n    }\n\n    /**\n     * Get the decoded JSON body of the response as a collection.\n     *\n     * @param  string|null  $key\n     * @param  int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>|null  $flags\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function collect($key = null, $flags = null)\n    {\n        return new Collection($this->json($key, flags: $flags));\n    }\n\n    /**\n     * Get the decoded JSON body of the response as a fluent object.\n     *\n     * @param  string|null  $key\n     * @param  int-mask<JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR>|null  $flags\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function fluent($key = null, $flags = null)\n    {\n        return new Fluent((array) $this->json($key, flags: $flags));\n    }\n\n    /**\n     * Get the body of the response as a PHP resource.\n     *\n     * @return resource\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function resource()\n    {\n        return StreamWrapper::getResource($this->response->getBody());\n    }\n\n    /**\n     * Get a header from the response.\n     *\n     * @param  string  $header\n     * @return string\n     */\n    public function header(string $header)\n    {\n        return $this->response->getHeaderLine($header);\n    }\n\n    /**\n     * Get the headers from the response.\n     *\n     * @return array\n     */\n    public function headers()\n    {\n        return $this->response->getHeaders();\n    }\n\n    /**\n     * Get the status code of the response.\n     *\n     * @return int\n     */\n    public function status()\n    {\n        return (int) $this->response->getStatusCode();\n    }\n\n    /**\n     * Get the reason phrase of the response.\n     *\n     * @return string\n     */\n    public function reason()\n    {\n        return $this->response->getReasonPhrase();\n    }\n\n    /**\n     * Get the effective URI of the response.\n     *\n     * @return \\Psr\\Http\\Message\\UriInterface|null\n     */\n    public function effectiveUri()\n    {\n        return $this->transferStats?->getEffectiveUri();\n    }\n\n    /**\n     * Determine if the request was successful.\n     *\n     * @return bool\n     */\n    public function successful()\n    {\n        return $this->status() >= 200 && $this->status() < 300;\n    }\n\n    /**\n     * Determine if the response was a redirect.\n     *\n     * @return bool\n     */\n    public function redirect()\n    {\n        return $this->status() >= 300 && $this->status() < 400;\n    }\n\n    /**\n     * Determine if the response indicates a client or server error occurred.\n     *\n     * @return bool\n     */\n    public function failed()\n    {\n        return $this->serverError() || $this->clientError();\n    }\n\n    /**\n     * Determine if the response indicates a client error occurred.\n     *\n     * @return bool\n     */\n    public function clientError()\n    {\n        return $this->status() >= 400 && $this->status() < 500;\n    }\n\n    /**\n     * Determine if the response indicates a server error occurred.\n     *\n     * @return bool\n     */\n    public function serverError()\n    {\n        return $this->status() >= 500;\n    }\n\n    /**\n     * Execute the given callback if there was a server or client error.\n     *\n     * @param  callable|(\\Closure(\\Illuminate\\Http\\Client\\Response): mixed)  $callback\n     * @return $this\n     */\n    public function onError(callable $callback)\n    {\n        if ($this->failed()) {\n            $callback($this);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the response cookies.\n     *\n     * @return \\GuzzleHttp\\Cookie\\CookieJar\n     */\n    public function cookies()\n    {\n        return $this->cookies;\n    }\n\n    /**\n     * Get the handler stats of the response.\n     *\n     * @return array\n     */\n    public function handlerStats()\n    {\n        return $this->transferStats?->getHandlerStats() ?? [];\n    }\n\n    /**\n     * Close the stream and any underlying resources.\n     *\n     * @return $this\n     */\n    public function close()\n    {\n        $this->response->getBody()->close();\n\n        return $this;\n    }\n\n    /**\n     * Get the underlying PSR response for the response.\n     *\n     * @return \\Psr\\Http\\Message\\ResponseInterface\n     */\n    public function toPsrResponse()\n    {\n        return $this->response;\n    }\n\n    /**\n     * Create an exception if a server or client error occurred.\n     *\n     * @return \\Illuminate\\Http\\Client\\RequestException|null\n     */\n    public function toException()\n    {\n        if ($this->failed()) {\n            return new RequestException($this, $this->truncateExceptionsAt);\n        }\n    }\n\n    /**\n     * Throw an exception if a server or client error occurred.\n     *\n     * @param  null|(\\Closure(\\Illuminate\\Http\\Client\\Response, \\Illuminate\\Http\\Client\\RequestException): mixed)  $callback\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throw($callback = null)\n    {\n        if ($this->failed()) {\n            throw tap($this->toException(), function ($exception) use ($callback) {\n                if ($callback && is_callable($callback)) {\n                    $callback($this, $exception);\n                }\n            });\n        }\n\n        return $this;\n    }\n\n    /**\n     * Throw an exception if a server or client error occurred and the given condition evaluates to true.\n     *\n     * @param  \\Closure|bool  $condition\n     * @param  null|(\\Closure(\\Illuminate\\Http\\Client\\Response, \\Illuminate\\Http\\Client\\RequestException): mixed)  $callback\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwIf($condition, $callback = null)\n    {\n        return value($condition, $this) ? $this->throw($callback) : $this;\n    }\n\n    /**\n     * Throw an exception if a server or client error occurred and the given condition evaluates to false.\n     *\n     * @param  \\Closure|bool  $condition\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwUnless($condition)\n    {\n        return $this->throwIf(! $condition);\n    }\n\n    /**\n     * Throw an exception if the response status code matches the given code.\n     *\n     * @param  int|(\\Closure(int, \\Illuminate\\Http\\Client\\Response): bool)|callable  $statusCode\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwIfStatus($statusCode)\n    {\n        if (is_callable($statusCode) &&\n            $statusCode($this->status(), $this)) {\n            throw new RequestException($this, $this->truncateExceptionsAt);\n        }\n\n        return $this->status() === $statusCode ? throw new RequestException($this, $this->truncateExceptionsAt) : $this;\n    }\n\n    /**\n     * Throw an exception unless the response status code matches the given code.\n     *\n     * @param  int|(\\Closure(int, \\Illuminate\\Http\\Client\\Response): bool)|callable  $statusCode\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwUnlessStatus($statusCode)\n    {\n        if (is_callable($statusCode)) {\n            return $statusCode($this->status(), $this) ? $this : throw new RequestException($this, $this->truncateExceptionsAt);\n        }\n\n        return $this->status() === $statusCode ? $this : throw new RequestException($this, $this->truncateExceptionsAt);\n    }\n\n    /**\n     * Throw an exception if the response status code is a 4xx level code.\n     *\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwIfClientError()\n    {\n        return $this->clientError() ? $this->throw() : $this;\n    }\n\n    /**\n     * Throw an exception if the response status code is a 5xx level code.\n     *\n     * @return $this\n     *\n     * @throws \\Illuminate\\Http\\Client\\RequestException\n     */\n    public function throwIfServerError()\n    {\n        return $this->serverError() ? $this->throw() : $this;\n    }\n\n    /**\n     * Indicate that request exceptions should be truncated to the given length.\n     *\n     * @param  int<1, max>  $length\n     * @return $this\n     */\n    public function truncateExceptionsAt(int $length)\n    {\n        $this->truncateExceptionsAt = $length;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that request exceptions should not be truncated.\n     *\n     * @return $this\n     */\n    public function dontTruncateExceptions()\n    {\n        $this->truncateExceptionsAt = false;\n\n        return $this;\n    }\n\n    /**\n     * Dump the content from the response.\n     *\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function dump($key = null)\n    {\n        $content = $this->body();\n\n        $json = json_decode($content);\n\n        if (json_last_error() === JSON_ERROR_NONE) {\n            $content = $json;\n        }\n\n        if ($request = $this->transferStats?->getRequest()) {\n            dump('\"'.$request->getMethod().' '.$request->getUri().'\" '.$this->status());\n        }\n\n        dump(is_null($key) ? $content : data_get($content, $key));\n\n        return $this;\n    }\n\n    /**\n     * Dump the content from the response and end the script.\n     *\n     * @param  string|null  $key\n     * @return never\n     */\n    public function dd($key = null)\n    {\n        $this->dump($key);\n\n        exit(1);\n    }\n\n    /**\n     * Dump the headers from the response.\n     *\n     * @return $this\n     */\n    public function dumpHeaders()\n    {\n        dump($this->headers());\n\n        return $this;\n    }\n\n    /**\n     * Dump the headers from the response and end the script.\n     *\n     * @return never\n     */\n    public function ddHeaders()\n    {\n        $this->dumpHeaders();\n\n        exit(1);\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->json()[$offset]);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->json()[$offset];\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetSet($offset, $value): void\n    {\n        throw new LogicException('Response data may not be mutated using array access.');\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetUnset($offset): void\n    {\n        throw new LogicException('Response data may not be mutated using array access.');\n    }\n\n    /**\n     * Get the body of the response.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->body();\n    }\n\n    /**\n     * Dynamically proxy other methods to the underlying response.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return static::hasMacro($method)\n            ? $this->macroCall($method, $parameters)\n            : $this->response->{$method}(...$parameters);\n    }\n\n    /**\n     * Flush the global state of the Response.\n     */\n    public static function flushState(): void\n    {\n        self::$defaultJsonDecodingFlags = 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/ResponseSequence.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse Closure;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse OutOfBoundsException;\n\nclass ResponseSequence\n{\n    use Macroable;\n\n    /**\n     * The responses in the sequence.\n     *\n     * @var array\n     */\n    protected $responses;\n\n    /**\n     * Indicates that invoking this sequence when it is empty should throw an exception.\n     *\n     * @var bool\n     */\n    protected $failWhenEmpty = true;\n\n    /**\n     * The response that should be returned when the sequence is empty.\n     *\n     * @var \\GuzzleHttp\\Promise\\PromiseInterface\n     */\n    protected $emptyResponse;\n\n    /**\n     * Create a new response sequence.\n     *\n     * @param  array  $responses\n     */\n    public function __construct(array $responses)\n    {\n        $this->responses = $responses;\n    }\n\n    /**\n     * Push a response to the sequence.\n     *\n     * @param  string|array|null  $body\n     * @param  int  $status\n     * @param  array  $headers\n     * @return $this\n     */\n    public function push($body = null, int $status = 200, array $headers = [])\n    {\n        return $this->pushResponse(\n            Factory::response($body, $status, $headers)\n        );\n    }\n\n    /**\n     * Push a response with the given status code to the sequence.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @return $this\n     */\n    public function pushStatus(int $status, array $headers = [])\n    {\n        return $this->pushResponse(\n            Factory::response('', $status, $headers)\n        );\n    }\n\n    /**\n     * Push a response with the contents of a file as the body to the sequence.\n     *\n     * @param  string  $filePath\n     * @param  int  $status\n     * @param  array  $headers\n     * @return $this\n     */\n    public function pushFile(string $filePath, int $status = 200, array $headers = [])\n    {\n        $string = file_get_contents($filePath);\n\n        return $this->pushResponse(\n            Factory::response($string, $status, $headers)\n        );\n    }\n\n    /**\n     * Push a connection exception to the sequence.\n     *\n     * @param  string|null  $message\n     * @return $this\n     */\n    public function pushFailedConnection($message = null)\n    {\n        return $this->pushResponse(\n            Factory::failedConnection($message)\n        );\n    }\n\n    /**\n     * Push a response to the sequence.\n     *\n     * @param  mixed  $response\n     * @return $this\n     */\n    public function pushResponse($response)\n    {\n        $this->responses[] = $response;\n\n        return $this;\n    }\n\n    /**\n     * Make the sequence return a default response when it is empty.\n     *\n     * @param  \\GuzzleHttp\\Promise\\PromiseInterface|\\Closure  $response\n     * @return $this\n     */\n    public function whenEmpty($response)\n    {\n        $this->failWhenEmpty = false;\n        $this->emptyResponse = $response;\n\n        return $this;\n    }\n\n    /**\n     * Make the sequence return a default response when it is empty.\n     *\n     * @return $this\n     */\n    public function dontFailWhenEmpty()\n    {\n        return $this->whenEmpty(Factory::response());\n    }\n\n    /**\n     * Indicate that this sequence has depleted all of its responses.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return count($this->responses) === 0;\n    }\n\n    /**\n     * Get the next response in the sequence.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Request  $request\n     * @return mixed\n     *\n     * @throws \\OutOfBoundsException\n     */\n    public function __invoke($request)\n    {\n        if ($this->failWhenEmpty && $this->isEmpty()) {\n            throw new OutOfBoundsException('A request was made, but the response sequence is empty.');\n        }\n\n        if (! $this->failWhenEmpty && $this->isEmpty()) {\n            return value($this->emptyResponse ?? Factory::response());\n        }\n\n        $response = array_shift($this->responses);\n\n        return $response instanceof Closure ? $response($request) : $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Client/StrayRequestException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Client;\n\nuse RuntimeException;\n\nclass StrayRequestException extends RuntimeException\n{\n    public function __construct(string $uri)\n    {\n        parent::__construct('Attempted request to ['.$uri.'] without a matching fake.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Concerns/CanBePrecognitive.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Concerns;\n\nuse Illuminate\\Support\\Collection;\n\ntrait CanBePrecognitive\n{\n    /**\n     * Filter the given array of rules into an array of rules that are included in precognitive headers.\n     *\n     * @param  array  $rules\n     * @return array\n     */\n    public function filterPrecognitiveRules($rules)\n    {\n        if (! $this->headers->has('Precognition-Validate-Only')) {\n            return $rules;\n        }\n\n        $validateOnly = explode(',', $this->header('Precognition-Validate-Only'));\n\n        return (new Collection($rules))\n            ->filter(fn ($rule, $attribute) => $this->shouldValidatePrecognitiveAttribute($attribute, $validateOnly))\n            ->all();\n    }\n\n    /**\n     * Determine if the given attribute should be validated.\n     *\n     * @param  string  $attribute\n     * @param  array  $validateOnly\n     * @return bool\n     */\n    protected function shouldValidatePrecognitiveAttribute($attribute, $validateOnly)\n    {\n        foreach ($validateOnly as $pattern) {\n            $regex = '/^'.str_replace('\\*', '[^.]+', preg_quote($pattern, '/')).'$/';\n\n            if (preg_match($regex, $attribute)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the request is attempting to be precognitive.\n     *\n     * @return bool\n     */\n    public function isAttemptingPrecognition()\n    {\n        return $this->header('Precognition') === 'true';\n    }\n\n    /**\n     * Determine if the request is precognitive.\n     *\n     * @return bool\n     */\n    public function isPrecognitive()\n    {\n        return $this->attributes->get('precognitive', false);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Concerns/InteractsWithContentTypes.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait InteractsWithContentTypes\n{\n    /**\n     * Determine if the request is sending JSON.\n     *\n     * @return bool\n     */\n    public function isJson()\n    {\n        return Str::contains($this->header('CONTENT_TYPE') ?? '', ['/json', '+json']);\n    }\n\n    /**\n     * Determine if the current request probably expects a JSON response.\n     *\n     * @return bool\n     */\n    public function expectsJson()\n    {\n        return ($this->ajax() && ! $this->pjax() && $this->acceptsAnyContentType()) || $this->wantsJson();\n    }\n\n    /**\n     * Determine if the current request is asking for JSON.\n     *\n     * @return bool\n     */\n    public function wantsJson()\n    {\n        $acceptable = $this->getAcceptableContentTypes();\n\n        return isset($acceptable[0]) && Str::contains(strtolower($acceptable[0]), ['/json', '+json']);\n    }\n\n    /**\n     * Determine if the current request is asking for Markdown.\n     *\n     * @return bool\n     */\n    public function wantsMarkdown()\n    {\n        $acceptable = $this->getAcceptableContentTypes();\n\n        return isset($acceptable[0]) && str_starts_with(strtolower($acceptable[0]), 'text/markdown');\n    }\n\n    /**\n     * Determines whether the current requests accepts a given content type.\n     *\n     * @param  string|array  $contentTypes\n     * @return bool\n     */\n    public function accepts($contentTypes)\n    {\n        $accepts = $this->getAcceptableContentTypes();\n\n        if (count($accepts) === 0) {\n            return true;\n        }\n\n        $types = (array) $contentTypes;\n\n        foreach ($accepts as $accept) {\n            if ($accept && $pos = strpos($accept, ';')) {\n                $accept = trim(substr($accept, 0, $pos));\n            }\n\n            if ($accept === '*/*' || $accept === '*') {\n                return true;\n            }\n\n            foreach ($types as $type) {\n                $accept = strtolower($accept);\n\n                $type = strtolower($type);\n\n                if ($this->matchesType($accept, $type) || $accept === strtok($type, '/').'/*') {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Return the most suitable content type from the given array based on content negotiation.\n     *\n     * @param  string|array  $contentTypes\n     * @return string|null\n     */\n    public function prefers($contentTypes)\n    {\n        $accepts = $this->getAcceptableContentTypes();\n\n        $contentTypes = (array) $contentTypes;\n\n        foreach ($accepts as $accept) {\n            if ($accept && $pos = strpos($accept, ';')) {\n                $accept = trim(substr($accept, 0, $pos));\n            }\n\n            if (in_array($accept, ['*/*', '*'])) {\n                return $contentTypes[0];\n            }\n\n            foreach ($contentTypes as $contentType) {\n                $type = $contentType;\n\n                if (! is_null($mimeType = $this->getMimeType($contentType))) {\n                    $type = $mimeType;\n                }\n\n                $accept = strtolower($accept);\n\n                $type = strtolower($type);\n\n                if ($this->matchesType($type, $accept) || $accept === strtok($type, '/').'/*') {\n                    return $contentType;\n                }\n            }\n        }\n    }\n\n    /**\n     * Determine if the current request accepts any content type.\n     *\n     * @return bool\n     */\n    public function acceptsAnyContentType()\n    {\n        $acceptable = $this->getAcceptableContentTypes();\n\n        return count($acceptable) === 0 || (\n            isset($acceptable[0]) && ($acceptable[0] === '*/*' || $acceptable[0] === '*')\n        );\n    }\n\n    /**\n     * Determines whether a request accepts JSON.\n     *\n     * @return bool\n     */\n    public function acceptsJson()\n    {\n        return $this->accepts('application/json');\n    }\n\n    /**\n     * Determines whether a request accepts Markdown.\n     *\n     * @return bool\n     */\n    public function acceptsMarkdown()\n    {\n        return $this->accepts('text/markdown');\n    }\n\n    /**\n     * Determines whether a request accepts HTML.\n     *\n     * @return bool\n     */\n    public function acceptsHtml()\n    {\n        return $this->accepts('text/html');\n    }\n\n    /**\n     * Determine if the given content types match.\n     *\n     * @param  string  $actual\n     * @param  string  $type\n     * @return bool\n     */\n    public static function matchesType($actual, $type)\n    {\n        if ($actual === $type) {\n            return true;\n        }\n\n        $split = explode('/', $actual);\n\n        return isset($split[1]) && preg_match('#'.preg_quote($split[0], '#').'/.+\\+'.preg_quote($split[1], '#').'#', $type);\n    }\n\n    /**\n     * Get the data format expected in the response.\n     *\n     * @param  string  $default\n     * @return string\n     */\n    public function format($default = 'html')\n    {\n        foreach ($this->getAcceptableContentTypes() as $type) {\n            if ($format = $this->getFormat($type)) {\n                return $format;\n            }\n        }\n\n        return $default;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Concerns/InteractsWithFlashData.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Concerns;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\ntrait InteractsWithFlashData\n{\n    /**\n     * Retrieve an old input item.\n     *\n     * @param  string|null  $key\n     * @param  \\Illuminate\\Database\\Eloquent\\Model|string|array|null  $default\n     * @return string|array|null\n     */\n    public function old($key = null, $default = null)\n    {\n        $default = $default instanceof Model ? $default->getAttribute($key) : $default;\n\n        return $this->hasSession() ? $this->session()->getOldInput($key, $default) : $default;\n    }\n\n    /**\n     * Flash the input for the current request to the session.\n     *\n     * @return void\n     */\n    public function flash()\n    {\n        $this->session()->flashInput($this->input());\n    }\n\n    /**\n     * Flash only some of the input to the session.\n     *\n     * @param  mixed  $keys\n     * @return void\n     */\n    public function flashOnly($keys)\n    {\n        $this->session()->flashInput(\n            $this->only(is_array($keys) ? $keys : func_get_args())\n        );\n    }\n\n    /**\n     * Flash only some of the input to the session.\n     *\n     * @param  mixed  $keys\n     * @return void\n     */\n    public function flashExcept($keys)\n    {\n        $this->session()->flashInput(\n            $this->except(is_array($keys) ? $keys : func_get_args())\n        );\n    }\n\n    /**\n     * Flush all of the old input from the session.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        $this->session()->flashInput([]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Concerns/InteractsWithInput.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Concerns;\n\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Illuminate\\Support\\Traits\\InteractsWithData;\nuse SplFileInfo;\nuse Symfony\\Component\\HttpFoundation\\InputBag;\n\ntrait InteractsWithInput\n{\n    use Dumpable, InteractsWithData;\n\n    /**\n     * Retrieve a server variable from the request.\n     *\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    public function server($key = null, $default = null)\n    {\n        return $this->retrieveItem('server', $key, $default);\n    }\n\n    /**\n     * Determine if a header is set on the request.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasHeader($key)\n    {\n        return ! is_null($this->header($key));\n    }\n\n    /**\n     * Retrieve a header from the request.\n     *\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    public function header($key = null, $default = null)\n    {\n        return $this->retrieveItem('headers', $key, $default);\n    }\n\n    /**\n     * Get the bearer token from the request headers.\n     *\n     * @return string|null\n     */\n    public function bearerToken()\n    {\n        $header = $this->header('Authorization', '');\n\n        $position = strripos($header, 'Bearer ');\n\n        if ($position !== false) {\n            $header = substr($header, $position + 7);\n\n            return str_contains($header, ',') ? strstr($header, ',', true) : $header;\n        }\n    }\n\n    /**\n     * Get the keys for all of the input and files.\n     *\n     * @return array\n     */\n    public function keys()\n    {\n        return array_merge(array_keys($this->input()), $this->files->keys());\n    }\n\n    /**\n     * Get all of the input and files for the request.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function all($keys = null)\n    {\n        $input = array_replace_recursive($this->input(), $this->allFiles());\n\n        if (! $keys) {\n            return $input;\n        }\n\n        $results = [];\n\n        foreach (is_array($keys) ? $keys : func_get_args() as $key) {\n            Arr::set($results, $key, Arr::get($input, $key));\n        }\n\n        return $results;\n    }\n\n    /**\n     * Retrieve an input item from the request.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function input($key = null, $default = null)\n    {\n        return data_get(\n            $this->getInputSource()->all() + $this->query->all(), $key, $default\n        );\n    }\n\n    /**\n     * Retrieve input from the request as a Fluent object instance.\n     *\n     * @param  array|string|null  $key\n     * @param  array  $default\n     * @return \\Illuminate\\Support\\Fluent\n     */\n    public function fluent($key = null, array $default = [])\n    {\n        $value = is_array($key) ? $this->only($key) : $this->input($key);\n\n        return new Fluent($value ?? $default);\n    }\n\n    /**\n     * Retrieve a query string item from the request.\n     *\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    public function query($key = null, $default = null)\n    {\n        return $this->retrieveItem('query', $key, $default);\n    }\n\n    /**\n     * Retrieve a request payload item from the request.\n     *\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    public function post($key = null, $default = null)\n    {\n        return $this->retrieveItem('request', $key, $default);\n    }\n\n    /**\n     * Determine if a cookie is set on the request.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasCookie($key)\n    {\n        return ! is_null($this->cookie($key));\n    }\n\n    /**\n     * Retrieve a cookie from the request.\n     *\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    public function cookie($key = null, $default = null)\n    {\n        return $this->retrieveItem('cookies', $key, $default);\n    }\n\n    /**\n     * Get an array of all of the files on the request.\n     *\n     * @return array<string, \\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]>\n     */\n    public function allFiles()\n    {\n        $files = $this->files->all();\n\n        return $this->convertedFiles = $this->convertedFiles ?? $this->convertUploadedFiles($files);\n    }\n\n    /**\n     * Convert the given array of Symfony UploadedFiles to custom Laravel UploadedFiles.\n     *\n     * @param  array<string, \\Symfony\\Component\\HttpFoundation\\File\\UploadedFile|\\Symfony\\Component\\HttpFoundation\\File\\UploadedFile[]>  $files\n     * @return array<string, \\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]>\n     */\n    protected function convertUploadedFiles(array $files)\n    {\n        return array_map(function ($file) {\n            if (is_null($file) || (is_array($file) && empty(array_filter($file)))) {\n                return $file;\n            }\n\n            return is_array($file)\n                ? $this->convertUploadedFiles($file)\n                : UploadedFile::createFromBase($file);\n        }, $files);\n    }\n\n    /**\n     * Determine if the uploaded data contains a file.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasFile($key)\n    {\n        if (! is_array($files = $this->file($key))) {\n            $files = [$files];\n        }\n\n        foreach ($files as $file) {\n            if ($this->isValidFile($file)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Check that the given file is a valid file instance.\n     *\n     * @param  mixed  $file\n     * @return bool\n     */\n    protected function isValidFile($file)\n    {\n        return $file instanceof SplFileInfo && $file->getPath() !== '';\n    }\n\n    /**\n     * Retrieve a file from the request.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? array<string, \\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]> : \\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]|null)\n     */\n    public function file($key = null, $default = null)\n    {\n        return data_get($this->allFiles(), $key, $default);\n    }\n\n    /**\n     * Retrieve data from the instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function data($key = null, $default = null)\n    {\n        return $this->input($key, $default);\n    }\n\n    /**\n     * Retrieve a parameter item from a given source.\n     *\n     * @param  string  $source\n     * @param  string|null  $key\n     * @param  string|array|null  $default\n     * @return string|array|null\n     */\n    protected function retrieveItem($source, $key, $default)\n    {\n        if (is_null($key)) {\n            return $this->$source->all();\n        }\n\n        if ($this->$source instanceof InputBag) {\n            return $this->$source->all()[$key] ?? $default;\n        }\n\n        return $this->$source->get($key, $default);\n    }\n\n    /**\n     * Dump the items.\n     *\n     * @param  mixed  $keys\n     * @return $this\n     */\n    public function dump($keys = [])\n    {\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        dump(count($keys) > 0 ? $this->only($keys) : $this->all());\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Exceptions/HttpResponseException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Exceptions;\n\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Throwable;\n\nclass HttpResponseException extends RuntimeException\n{\n    /**\n     * The underlying response instance.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected $response;\n\n    /**\n     * Create a new HTTP response exception instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @param  \\Throwable|null  $previous\n     */\n    public function __construct(Response $response, ?Throwable $previous = null)\n    {\n        parent::__construct($previous?->getMessage() ?? '', $previous?->getCode() ?? 0, $previous);\n\n        $this->response = $response;\n    }\n\n    /**\n     * Get the underlying response instance.\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function getResponse()\n    {\n        return $this->response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Exceptions/MalformedUrlException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Exceptions;\n\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass MalformedUrlException extends HttpException\n{\n    /**\n     * Create a new exception instance.\n     */\n    public function __construct()\n    {\n        parent::__construct(400, 'Malformed URL.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Exceptions/OriginMismatchException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Exceptions;\n\nuse Exception;\n\nclass OriginMismatchException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Exceptions/PostTooLargeException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Exceptions;\n\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Throwable;\n\nclass PostTooLargeException extends HttpException\n{\n    /**\n     * Create a new \"post too large\" exception instance.\n     *\n     * @param  string  $message\n     * @param  \\Throwable|null  $previous\n     * @param  array  $headers\n     * @param  int  $code\n     */\n    public function __construct($message = '', ?Throwable $previous = null, array $headers = [], $code = 0)\n    {\n        parent::__construct(413, $message, $previous, $headers, $code);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Exceptions/ThrottleRequestsException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Exceptions;\n\nuse Symfony\\Component\\HttpKernel\\Exception\\TooManyRequestsHttpException;\nuse Throwable;\n\nclass ThrottleRequestsException extends TooManyRequestsHttpException\n{\n    /**\n     * Create a new throttle requests exception instance.\n     *\n     * @param  string  $message\n     * @param  \\Throwable|null  $previous\n     * @param  array  $headers\n     * @param  int  $code\n     */\n    public function __construct($message = '', ?Throwable $previous = null, array $headers = [], $code = 0)\n    {\n        parent::__construct(null, $message, $previous, $code, $headers);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/File.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Symfony\\Component\\HttpFoundation\\File\\File as SymfonyFile;\n\nclass File extends SymfonyFile\n{\n    use FileHelpers;\n}\n"
  },
  {
    "path": "src/Illuminate/Http/FileHelpers.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Illuminate\\Support\\Str;\n\ntrait FileHelpers\n{\n    /**\n     * The cache copy of the file's hash name.\n     *\n     * @var string|null\n     */\n    protected $hashName = null;\n\n    /**\n     * Get the fully-qualified path to the file.\n     *\n     * @return string\n     */\n    public function path()\n    {\n        return $this->getRealPath();\n    }\n\n    /**\n     * Get the file's extension.\n     *\n     * @return string\n     */\n    public function extension()\n    {\n        return $this->guessExtension();\n    }\n\n    /**\n     * Get a filename for the file.\n     *\n     * @param  string|null  $path\n     * @return string\n     */\n    public function hashName($path = null)\n    {\n        if ($path) {\n            $path = rtrim($path, '/').'/';\n        }\n\n        $hash = $this->hashName ?: $this->hashName = Str::random(40);\n\n        if ($extension = $this->guessExtension()) {\n            $extension = '.'.$extension;\n        }\n\n        return $path.$hash.$extension;\n    }\n\n    /**\n     * Get the dimensions of the image (if applicable).\n     *\n     * @return array|null\n     */\n    public function dimensions()\n    {\n        return @getimagesize($this->getRealPath());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/JsonResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse JsonSerializable;\nuse Symfony\\Component\\HttpFoundation\\JsonResponse as BaseJsonResponse;\n\nclass JsonResponse extends BaseJsonResponse\n{\n    use ResponseTrait, Macroable {\n        Macroable::__call as macroCall;\n    }\n\n    /**\n     * Create a new JSON response instance.\n     *\n     * @param  mixed  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $options\n     * @param  bool  $json\n     */\n    public function __construct($data = null, $status = 200, $headers = [], $options = 0, $json = false)\n    {\n        $this->encodingOptions = $options;\n\n        parent::__construct($data, $status, $headers, $json);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return static\n     */\n    #[\\Override]\n    public static function fromJsonString(?string $data = null, int $status = 200, array $headers = []): static\n    {\n        return new static($data, $status, $headers, 0, true);\n    }\n\n    /**\n     * Sets the JSONP callback.\n     *\n     * @param  string|null  $callback\n     * @return $this\n     */\n    public function withCallback($callback = null)\n    {\n        return $this->setCallback($callback);\n    }\n\n    /**\n     * Get the decoded JSON data from the response.\n     *\n     * @param  bool  $assoc\n     * @param  int  $depth\n     * @return mixed\n     */\n    public function getData($assoc = false, $depth = 512)\n    {\n        return json_decode($this->data, $assoc, $depth);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return static\n     *\n     * @throws \\InvalidArgumentException\n     */\n    #[\\Override]\n    public function setData($data = []): static\n    {\n        $this->original = $data;\n\n        // Ensure json_last_error() is cleared...\n        json_decode('[]');\n\n        $this->data = match (true) {\n            $data instanceof Jsonable => $data->toJson($this->encodingOptions),\n            $data instanceof JsonSerializable => json_encode($data->jsonSerialize(), $this->encodingOptions),\n            $data instanceof Arrayable => json_encode($data->toArray(), $this->encodingOptions),\n            default => json_encode($data, $this->encodingOptions),\n        };\n\n        if (! $this->hasValidJson(json_last_error())) {\n            throw new InvalidArgumentException(json_last_error_msg());\n        }\n\n        return $this->update();\n    }\n\n    /**\n     * Determine if an error occurred during JSON encoding.\n     *\n     * @param  int  $jsonError\n     * @return bool\n     */\n    protected function hasValidJson($jsonError)\n    {\n        if ($jsonError === JSON_ERROR_NONE) {\n            return true;\n        }\n\n        return $this->hasEncodingOption(JSON_PARTIAL_OUTPUT_ON_ERROR) &&\n                    in_array($jsonError, [\n                        JSON_ERROR_RECURSION,\n                        JSON_ERROR_INF_OR_NAN,\n                        JSON_ERROR_UNSUPPORTED_TYPE,\n                    ]);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return static\n     */\n    #[\\Override]\n    public function setEncodingOptions($options): static\n    {\n        $this->encodingOptions = (int) $options;\n\n        return $this->setData($this->getData());\n    }\n\n    /**\n     * Determine if a JSON encoding option is set.\n     *\n     * @param  int  $option\n     * @return bool\n     */\n    public function hasEncodingOption($option)\n    {\n        return (bool) ($this->encodingOptions & $option);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/AddLinkHeadersForPreloadedAssets.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Vite;\n\nclass AddLinkHeadersForPreloadedAssets\n{\n    /**\n     * Configure the middleware.\n     *\n     * @param  int  $limit\n     * @return string\n     */\n    public static function using($limit)\n    {\n        return static::class.':'.$limit;\n    }\n\n    /**\n     * Handle the incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  int|null  $limit\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function handle($request, $next, $limit = null)\n    {\n        return tap($next($request), function ($response) use ($limit) {\n            if ($response instanceof Response && Vite::preloadedAssets() !== []) {\n                $response->header('Link', (new Collection(Vite::preloadedAssets()))\n                    ->when($limit, fn ($assets, $limit) => $assets->take($limit))\n                    ->map(fn ($attributes, $url) => \"<{$url}>; \".implode('; ', $attributes))\n                    ->join(', '), false);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/CheckResponseForModifications.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass CheckResponseForModifications\n{\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        $response = $next($request);\n\n        if ($response instanceof Response) {\n            $response->isNotModified($request);\n        }\n\n        return $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/FrameGuard.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\n\nclass FrameGuard\n{\n    /**\n     * Handle the given request and get the response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function handle($request, Closure $next)\n    {\n        $response = $next($request);\n\n        $response->headers->set('X-Frame-Options', 'SAMEORIGIN', false);\n\n        return $response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/HandleCors.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Fruitcake\\Cors\\CorsService;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Http\\Request;\n\nclass HandleCors\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The CORS service instance.\n     *\n     * @var \\Fruitcake\\Cors\\CorsService\n     */\n    protected $cors;\n\n    /**\n     * All of the registered skip callbacks.\n     *\n     * @var array<int, \\Closure(\\Illuminate\\Http\\Request): bool>\n     */\n    protected static $skipCallbacks = [];\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @param  \\Fruitcake\\Cors\\CorsService  $cors\n     */\n    public function __construct(Container $container, CorsService $cors)\n    {\n        $this->container = $container;\n        $this->cors = $cors;\n    }\n\n    /**\n     * Handle the incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function handle($request, Closure $next)\n    {\n        foreach (static::$skipCallbacks as $callback) {\n            if ($callback($request)) {\n                return $next($request);\n            }\n        }\n\n        if (! $this->hasMatchingPath($request)) {\n            return $next($request);\n        }\n\n        $this->cors->setOptions($this->container['config']->get('cors', []));\n\n        if ($this->cors->isPreflightRequest($request)) {\n            $response = $this->cors->handlePreflightRequest($request);\n\n            $this->cors->varyHeader($response, 'Access-Control-Request-Method');\n\n            return $response;\n        }\n\n        $response = $next($request);\n\n        if ($request->getMethod() === 'OPTIONS') {\n            $this->cors->varyHeader($response, 'Access-Control-Request-Method');\n        }\n\n        return $this->cors->addActualRequestHeaders($response, $request);\n    }\n\n    /**\n     * Get the path from the configuration to determine if the CORS service should run.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    protected function hasMatchingPath(Request $request): bool\n    {\n        $paths = $this->getPathsByHost($request->getHost());\n\n        foreach ($paths as $path) {\n            if ($path !== '/') {\n                $path = trim($path, '/');\n            }\n\n            if ($request->fullUrlIs($path) || $request->is($path)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the CORS paths for the given host.\n     *\n     * @param  string  $host\n     * @return array\n     */\n    protected function getPathsByHost(string $host)\n    {\n        $paths = $this->container['config']->get('cors.paths', []);\n\n        if (isset($paths[$host])) {\n            return $paths[$host];\n        }\n\n        return array_filter($paths, function ($path) {\n            return is_string($path);\n        });\n    }\n\n    /**\n     * Register a callback that instructs the middleware to be skipped.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function skipWhen(Closure $callback)\n    {\n        static::$skipCallbacks[] = $callback;\n    }\n\n    /**\n     * Flush the middleware's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$skipCallbacks = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/SetCacheHeaders.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass SetCacheHeaders\n{\n    /**\n     * Specify the options for the middleware.\n     *\n     * @param  array|string  $options\n     * @return string\n     */\n    public static function using($options)\n    {\n        if (is_string($options)) {\n            return static::class.':'.$options;\n        }\n\n        return (new Collection($options))\n            ->map(function ($value, $key) {\n                if (is_bool($value)) {\n                    return $value ? $key : null;\n                }\n\n                return is_int($key) ? $value : \"{$key}={$value}\";\n            })\n            ->filter()\n            ->map(fn ($value) => Str::finish($value, ';'))\n            ->pipe(fn ($options) => rtrim(static::class.':'.$options->implode(''), ';'));\n    }\n\n    /**\n     * Add cache related HTTP headers.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string|array  $options\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function handle($request, Closure $next, $options = [])\n    {\n        $response = $next($request);\n\n        if (! $request->isMethodCacheable() || (! $response->getContent() && ! $response instanceof BinaryFileResponse && ! $response instanceof StreamedResponse)) {\n            return $response;\n        }\n\n        if (is_string($options)) {\n            $options = $this->parseOptions($options);\n        }\n\n        if (! $response->isSuccessful()) {\n            return $response;\n        }\n\n        if (isset($options['etag']) && $options['etag'] === true) {\n            $options['etag'] = $response->getEtag() ?? ($response->getContent() ? hash('xxh128', $response->getContent()) : null);\n        }\n\n        if (isset($options['last_modified'])) {\n            if (is_numeric($options['last_modified'])) {\n                $options['last_modified'] = Carbon::createFromTimestamp($options['last_modified'], date_default_timezone_get());\n            } else {\n                $options['last_modified'] = Carbon::parse($options['last_modified']);\n            }\n        }\n\n        $response->setCache($options);\n        $response->isNotModified($request);\n\n        return $response;\n    }\n\n    /**\n     * Parse the given header options.\n     *\n     * @param  string  $options\n     * @return array\n     */\n    protected function parseOptions($options)\n    {\n        return (new Collection(explode(';', rtrim($options, ';'))))->mapWithKeys(function ($option) {\n            $data = explode('=', $option, 2);\n\n            return [$data[0] => $data[1] ?? true];\n        })->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/TrustHosts.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Http\\Request;\n\nclass TrustHosts\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The trusted hosts that have been configured to always be trusted.\n     *\n     * @var array<int, string>|(callable(): array<int, string>)|null\n     */\n    protected static $alwaysTrust;\n\n    /**\n     * Indicates whether subdomains of the application URL should be trusted.\n     *\n     * @var bool|null\n     */\n    protected static $subdomains;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct(Application $app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Get the host patterns that should be trusted.\n     *\n     * @return array\n     */\n    public function hosts()\n    {\n        if (is_null(static::$alwaysTrust)) {\n            return [$this->allSubdomainsOfApplicationUrl()];\n        }\n\n        $hosts = match (true) {\n            is_array(static::$alwaysTrust) => static::$alwaysTrust,\n            is_callable(static::$alwaysTrust) => call_user_func(static::$alwaysTrust),\n            default => [],\n        };\n\n        if (static::$subdomains) {\n            $hosts[] = $this->allSubdomainsOfApplicationUrl();\n        }\n\n        return $hosts;\n    }\n\n    /**\n     * Handle the incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function handle(Request $request, $next)\n    {\n        if ($this->shouldSpecifyTrustedHosts()) {\n            Request::setTrustedHosts(array_filter($this->hosts()));\n        }\n\n        return $next($request);\n    }\n\n    /**\n     * Specify the hosts that should always be trusted.\n     *\n     * @param  array<int, string>|(callable(): array<int, string>)  $hosts\n     * @param  bool  $subdomains\n     * @return void\n     */\n    public static function at(array|callable $hosts, bool $subdomains = true)\n    {\n        static::$alwaysTrust = $hosts;\n        static::$subdomains = $subdomains;\n    }\n\n    /**\n     * Determine if the application should specify trusted hosts.\n     *\n     * @return bool\n     */\n    protected function shouldSpecifyTrustedHosts()\n    {\n        return ! $this->app->environment('local') &&\n               ! $this->app->runningUnitTests();\n    }\n\n    /**\n     * Get a regular expression matching the application URL and all of its subdomains.\n     *\n     * @return string|null\n     */\n    protected function allSubdomainsOfApplicationUrl()\n    {\n        if ($host = parse_url($this->app['config']->get('app.url'), PHP_URL_HOST)) {\n            return '^(.+\\.)?'.preg_quote($host).'$';\n        }\n    }\n\n    /**\n     * Flush the state of the middleware.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$alwaysTrust = null;\n        static::$subdomains = null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/TrustProxies.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Request;\n\nclass TrustProxies\n{\n    /**\n     * The trusted proxies for the application.\n     *\n     * @var array<int, string>|string|null\n     */\n    protected $proxies;\n\n    /**\n     * The trusted proxies headers for the application.\n     *\n     * @var int\n     */\n    protected $headers = Request::HEADER_X_FORWARDED_FOR |\n        Request::HEADER_X_FORWARDED_HOST |\n        Request::HEADER_X_FORWARDED_PORT |\n        Request::HEADER_X_FORWARDED_PROTO |\n        Request::HEADER_X_FORWARDED_PREFIX |\n        Request::HEADER_X_FORWARDED_AWS_ELB;\n\n    /**\n     * The proxies that have been configured to always be trusted.\n     *\n     * @var array<int, string>|string|null\n     */\n    protected static $alwaysTrustProxies;\n\n    /**\n     * The proxies headers that have been configured to always be trusted.\n     *\n     * @var int|null\n     */\n    protected static $alwaysTrustHeaders;\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\HttpException\n     */\n    public function handle(Request $request, Closure $next)\n    {\n        $request::setTrustedProxies([], $this->getTrustedHeaderNames());\n\n        $this->setTrustedProxyIpAddresses($request);\n\n        return $next($request);\n    }\n\n    /**\n     * Sets the trusted proxies on the request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function setTrustedProxyIpAddresses(Request $request)\n    {\n        $trustedIps = $this->proxies() ?: config('trustedproxy.proxies');\n\n        if (is_null($trustedIps) &&\n            (laravel_cloud() ||\n             str_ends_with($request->host(), '.on-forge.com') ||\n             str_ends_with($request->host(), '.on-vapor.com'))) {\n            $trustedIps = '*';\n        }\n\n        if (str_ends_with($request->host(), '.on-forge.com') ||\n            str_ends_with($request->host(), '.on-vapor.com')) {\n            $request->headers->remove('X-Forwarded-Host');\n        }\n\n        if ($trustedIps === '*' || $trustedIps === '**') {\n            return $this->setTrustedProxyIpAddressesToTheCallingIp($request);\n        }\n\n        $trustedIps = is_string($trustedIps)\n            ? array_map(trim(...), explode(',', $trustedIps))\n            : $trustedIps;\n\n        if (is_array($trustedIps)) {\n            return $this->setTrustedProxyIpAddressesToSpecificIps($request, $trustedIps);\n        }\n    }\n\n    /**\n     * Specify the IP addresses to trust explicitly.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $trustedIps\n     * @return void\n     */\n    protected function setTrustedProxyIpAddressesToSpecificIps(Request $request, array $trustedIps)\n    {\n        $request->setTrustedProxies(array_reduce($trustedIps, function ($ips, $trustedIp) use ($request) {\n            $ips[] = $trustedIp === 'REMOTE_ADDR'\n                ? $request->server->get('REMOTE_ADDR')\n                : $trustedIp;\n\n            return $ips;\n        }, []), $this->getTrustedHeaderNames());\n    }\n\n    /**\n     * Set the trusted proxy to be the IP address calling this servers.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function setTrustedProxyIpAddressesToTheCallingIp(Request $request)\n    {\n        $request->setTrustedProxies([$request->server->get('REMOTE_ADDR')], $this->getTrustedHeaderNames());\n    }\n\n    /**\n     * Retrieve trusted header name(s), falling back to defaults if config not set.\n     *\n     * @return int A bit field of Request::HEADER_*, to set which headers to trust from your proxies.\n     */\n    protected function getTrustedHeaderNames()\n    {\n        $headers = $this->headers();\n\n        if (is_int($headers)) {\n            return $headers;\n        }\n\n        return match ($headers) {\n            'HEADER_X_FORWARDED_AWS_ELB' => Request::HEADER_X_FORWARDED_AWS_ELB,\n            'HEADER_FORWARDED' => Request::HEADER_FORWARDED,\n            'HEADER_X_FORWARDED_FOR' => Request::HEADER_X_FORWARDED_FOR,\n            'HEADER_X_FORWARDED_HOST' => Request::HEADER_X_FORWARDED_HOST,\n            'HEADER_X_FORWARDED_PORT' => Request::HEADER_X_FORWARDED_PORT,\n            'HEADER_X_FORWARDED_PROTO' => Request::HEADER_X_FORWARDED_PROTO,\n            'HEADER_X_FORWARDED_PREFIX' => Request::HEADER_X_FORWARDED_PREFIX,\n            default => Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_PREFIX | Request::HEADER_X_FORWARDED_AWS_ELB,\n        };\n    }\n\n    /**\n     * Get the trusted headers.\n     *\n     * @return int\n     */\n    protected function headers()\n    {\n        return static::$alwaysTrustHeaders ?: $this->headers;\n    }\n\n    /**\n     * Get the trusted proxies.\n     *\n     * @return array|string|null\n     */\n    protected function proxies()\n    {\n        return static::$alwaysTrustProxies ?: $this->proxies;\n    }\n\n    /**\n     * Specify the IP addresses of proxies that should always be trusted.\n     *\n     * @param  array|string  $proxies\n     * @return void\n     */\n    public static function at(array|string $proxies)\n    {\n        static::$alwaysTrustProxies = $proxies;\n    }\n\n    /**\n     * Specify the proxy headers that should always be trusted.\n     *\n     * @param  int  $headers\n     * @return void\n     */\n    public static function withHeaders(int $headers)\n    {\n        static::$alwaysTrustHeaders = $headers;\n    }\n\n    /**\n     * Flush the state of the middleware.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$alwaysTrustHeaders = null;\n        static::$alwaysTrustProxies = null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/ValidatePathEncoding.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Exceptions\\MalformedUrlException;\nuse Illuminate\\Http\\Request;\n\nclass ValidatePathEncoding\n{\n    /**\n     * Validate that the incoming request has a valid UTF-8 encoded path.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\MalformedUrlException\n     */\n    public function handle(Request $request, Closure $next)\n    {\n        $decodedPath = rawurldecode($request->path());\n\n        if (! mb_check_encoding($decodedPath, 'UTF-8')) {\n            throw new MalformedUrlException;\n        }\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Middleware/ValidatePostSize.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Exceptions\\PostTooLargeException;\n\nclass ValidatePostSize\n{\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\PostTooLargeException\n     */\n    public function handle($request, Closure $next)\n    {\n        $max = $this->getPostMaxSize();\n\n        if ($max > 0 && $request->server('CONTENT_LENGTH') > $max) {\n            throw new PostTooLargeException('The POST data is too large.');\n        }\n\n        return $next($request);\n    }\n\n    /**\n     * Determine the server 'post_max_size' as bytes.\n     *\n     * @return int\n     */\n    protected function getPostMaxSize()\n    {\n        if (is_numeric($postMaxSize = ini_get('post_max_size'))) {\n            return (int) $postMaxSize;\n        }\n\n        $metric = strtoupper(substr($postMaxSize, -1));\n\n        $postMaxSize = (int) $postMaxSize;\n\n        return match ($metric) {\n            'K' => $postMaxSize * 1024,\n            'M' => $postMaxSize * 1048576,\n            'G' => $postMaxSize * 1073741824,\n            default => $postMaxSize,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/RedirectResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Illuminate\\Contracts\\Support\\MessageProvider;\nuse Illuminate\\Session\\Store as SessionStore;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile as SymfonyUploadedFile;\nuse Symfony\\Component\\HttpFoundation\\RedirectResponse as BaseRedirectResponse;\n\nclass RedirectResponse extends BaseRedirectResponse\n{\n    use ForwardsCalls, ResponseTrait, Macroable {\n        Macroable::__call as macroCall;\n    }\n\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * The session store instance.\n     *\n     * @var \\Illuminate\\Session\\Store\n     */\n    protected $session;\n\n    /**\n     * Flash a piece of data to the session.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function with($key, $value = null)\n    {\n        $key = is_array($key) ? $key : [$key => $value];\n\n        foreach ($key as $k => $v) {\n            $this->session->flash($k, $v);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add multiple cookies to the response.\n     *\n     * @param  array  $cookies\n     * @return $this\n     */\n    public function withCookies(array $cookies)\n    {\n        foreach ($cookies as $cookie) {\n            $this->headers->setCookie($cookie);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Flash an array of input to the session.\n     *\n     * @param  array|null  $input\n     * @return $this\n     */\n    public function withInput(?array $input = null)\n    {\n        $this->session->flashInput($this->removeFilesFromInput(\n            ! is_null($input) ? $input : $this->request->input()\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Remove all uploaded files form the given input array.\n     *\n     * @param  array  $input\n     * @return array\n     */\n    protected function removeFilesFromInput(array $input)\n    {\n        foreach ($input as $key => $value) {\n            if (is_array($value)) {\n                $input[$key] = $this->removeFilesFromInput($value);\n            }\n\n            if ($value instanceof SymfonyUploadedFile) {\n                unset($input[$key]);\n            }\n        }\n\n        return $input;\n    }\n\n    /**\n     * Flash an array of input to the session.\n     *\n     * @return $this\n     */\n    public function onlyInput()\n    {\n        return $this->withInput($this->request->only(func_get_args()));\n    }\n\n    /**\n     * Flash an array of input to the session.\n     *\n     * @return $this\n     */\n    public function exceptInput()\n    {\n        return $this->withInput($this->request->except(func_get_args()));\n    }\n\n    /**\n     * Flash a container of errors to the session.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array|string  $provider\n     * @param  string  $key\n     * @return $this\n     */\n    public function withErrors($provider, $key = 'default')\n    {\n        $value = $this->parseErrors($provider);\n\n        $errors = $this->session->get('errors', new ViewErrorBag);\n\n        if (! $errors instanceof ViewErrorBag) {\n            $errors = new ViewErrorBag;\n        }\n\n        $this->session->flash(\n            'errors', $errors->put($key, $value)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Parse the given errors into an appropriate value.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array|string  $provider\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    protected function parseErrors($provider)\n    {\n        if ($provider instanceof MessageProvider) {\n            return $provider->getMessageBag();\n        }\n\n        return new MessageBag((array) $provider);\n    }\n\n    /**\n     * Add a fragment identifier to the URL.\n     *\n     * @param  string  $fragment\n     * @return $this\n     */\n    public function withFragment($fragment)\n    {\n        return $this->withoutFragment()\n            ->setTargetUrl($this->getTargetUrl().'#'.Str::after($fragment, '#'));\n    }\n\n    /**\n     * Remove any fragment identifier from the response URL.\n     *\n     * @return $this\n     */\n    public function withoutFragment()\n    {\n        return $this->setTargetUrl(Str::before($this->getTargetUrl(), '#'));\n    }\n\n    /**\n     * Enforce that the redirect target must have the same host as the current request.\n     */\n    public function enforceSameOrigin(\n        string $fallback,\n        bool $validateScheme = true,\n        bool $validatePort = true,\n    ): static {\n        $target = Uri::of($this->targetUrl);\n        $current = Uri::of($this->request->getSchemeAndHttpHost());\n\n        if ($target->host() !== $current->host() ||\n            ($validateScheme && $target->scheme() !== $current->scheme()) ||\n            ($validatePort && $target->port() !== $current->port())) {\n            $this->setTargetUrl($fallback);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the original response content.\n     *\n     * @return null\n     */\n    public function getOriginalContent()\n    {\n        //\n    }\n\n    /**\n     * Get the request instance.\n     *\n     * @return \\Illuminate\\Http\\Request|null\n     */\n    public function getRequest()\n    {\n        return $this->request;\n    }\n\n    /**\n     * Set the request instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return $this\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n\n        return $this;\n    }\n\n    /**\n     * Get the session store instance.\n     *\n     * @return \\Illuminate\\Session\\Store|null\n     */\n    public function getSession()\n    {\n        return $this->session;\n    }\n\n    /**\n     * Set the session store instance.\n     *\n     * @param  \\Illuminate\\Session\\Store  $session\n     * @return $this\n     */\n    public function setSession(SessionStore $session)\n    {\n        $this->session = $session;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically bind flash data in the session.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (str_starts_with($method, 'with')) {\n            return $this->with(Str::snake(substr($method, 4)), $parameters[0]);\n        }\n\n        static::throwBadMethodCallException($method);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Request.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse ArrayAccess;\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Session\\SymfonySessionDecorator;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Uri;\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\Exception\\SessionNotFoundException;\nuse Symfony\\Component\\HttpFoundation\\InputBag;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\nuse Symfony\\Component\\HttpFoundation\\Session\\SessionInterface;\n\n/**\n * @method array validate(array $rules, ...$params)\n * @method array validateWithBag(string $errorBag, array $rules, ...$params)\n * @method bool hasValidSignature(bool $absolute = true)\n * @method bool hasValidRelativeSignature()\n * @method bool hasValidSignatureWhileIgnoring($ignoreQuery = [], $absolute = true)\n * @method bool hasValidRelativeSignatureWhileIgnoring($ignoreQuery = [])\n */\nclass Request extends SymfonyRequest implements Arrayable, ArrayAccess\n{\n    use Concerns\\CanBePrecognitive,\n        Concerns\\InteractsWithContentTypes,\n        Concerns\\InteractsWithFlashData,\n        Concerns\\InteractsWithInput,\n        Conditionable,\n        Macroable;\n\n    /**\n     * The decoded JSON content for the request.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\InputBag|null\n     */\n    protected $json;\n\n    /**\n     * All of the converted files for the request.\n     *\n     * @var array<int, \\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]>\n     */\n    protected $convertedFiles;\n\n    /**\n     * The user resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected $userResolver;\n\n    /**\n     * The route resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected $routeResolver;\n\n    /**\n     * The cached \"Accept\" header value.\n     *\n     * @var string|null\n     */\n    protected $cachedAcceptHeader;\n\n    /**\n     * Create a new Illuminate HTTP request from server variables.\n     *\n     * @return static\n     */\n    public static function capture()\n    {\n        static::enableHttpMethodParameterOverride();\n\n        return static::createFromBase(SymfonyRequest::createFromGlobals());\n    }\n\n    /**\n     * Return the Request instance.\n     *\n     * @return $this\n     */\n    public function instance()\n    {\n        return $this;\n    }\n\n    /**\n     * Get the request method.\n     *\n     * @return string\n     */\n    public function method()\n    {\n        return $this->getMethod();\n    }\n\n    /**\n     * Get a URI instance for the request.\n     *\n     * @return \\Illuminate\\Support\\Uri\n     */\n    public function uri()\n    {\n        return Uri::of($this->fullUrl());\n    }\n\n    /**\n     * Get the root URL for the application.\n     *\n     * @return string\n     */\n    public function root()\n    {\n        return rtrim($this->getSchemeAndHttpHost().$this->getBaseUrl(), '/');\n    }\n\n    /**\n     * Get the URL (no query string) for the request.\n     *\n     * @return string\n     */\n    public function url()\n    {\n        return rtrim(preg_replace('/\\?.*/', '', $this->getUri()), '/');\n    }\n\n    /**\n     * Get the full URL for the request.\n     *\n     * @return string\n     */\n    public function fullUrl()\n    {\n        $query = $this->getQueryString();\n\n        $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?';\n\n        return $query ? $this->url().$question.$query : $this->url();\n    }\n\n    /**\n     * Get the full URL for the request with the added query string parameters.\n     *\n     * @param  array  $query\n     * @return string\n     */\n    public function fullUrlWithQuery(array $query)\n    {\n        $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?';\n\n        return count($this->query()) > 0\n            ? $this->url().$question.Arr::query(array_merge($this->query(), $query))\n            : $this->fullUrl().$question.Arr::query($query);\n    }\n\n    /**\n     * Get the full URL for the request without the given query string parameters.\n     *\n     * @param  array|string  $keys\n     * @return string\n     */\n    public function fullUrlWithoutQuery($keys)\n    {\n        $query = Arr::except($this->query(), $keys);\n\n        $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?';\n\n        return count($query) > 0\n            ? $this->url().$question.Arr::query($query)\n            : $this->url();\n    }\n\n    /**\n     * Get the current path info for the request.\n     *\n     * @return string\n     */\n    public function path()\n    {\n        $pattern = trim($this->getPathInfo(), '/');\n\n        return $pattern === '' ? '/' : $pattern;\n    }\n\n    /**\n     * Get the current decoded path info for the request.\n     *\n     * @return string\n     */\n    public function decodedPath()\n    {\n        return rawurldecode($this->path());\n    }\n\n    /**\n     * Get a segment from the URI (1 based index).\n     *\n     * @param  int  $index\n     * @param  string|null  $default\n     * @return string|null\n     */\n    public function segment($index, $default = null)\n    {\n        return Arr::get($this->segments(), $index - 1, $default);\n    }\n\n    /**\n     * Get all of the segments for the request path.\n     *\n     * @return array\n     */\n    public function segments()\n    {\n        $segments = explode('/', $this->decodedPath());\n\n        return array_values(array_filter($segments, function ($value) {\n            return $value !== '';\n        }));\n    }\n\n    /**\n     * Determine if the current request URI matches a pattern.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function is(...$patterns)\n    {\n        return (new Collection($patterns))\n            ->contains(fn ($pattern) => Str::is($pattern, $this->decodedPath()));\n    }\n\n    /**\n     * Determine if the route name matches a given pattern.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function routeIs(...$patterns)\n    {\n        return $this->route() && $this->route()->named(...$patterns);\n    }\n\n    /**\n     * Determine if the current request URL and query string match a pattern.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function fullUrlIs(...$patterns)\n    {\n        return (new Collection($patterns))\n            ->contains(fn ($pattern) => Str::is($pattern, $this->fullUrl()));\n    }\n\n    /**\n     * Get the host name.\n     *\n     * @return string\n     */\n    public function host()\n    {\n        return $this->getHost();\n    }\n\n    /**\n     * Get the HTTP host being requested.\n     *\n     * @return string\n     */\n    public function httpHost()\n    {\n        return $this->getHttpHost();\n    }\n\n    /**\n     * Get the scheme and HTTP host.\n     *\n     * @return string\n     */\n    public function schemeAndHttpHost()\n    {\n        return $this->getSchemeAndHttpHost();\n    }\n\n    /**\n     * Determine if the request is the result of an AJAX call.\n     *\n     * @return bool\n     */\n    public function ajax()\n    {\n        return $this->isXmlHttpRequest();\n    }\n\n    /**\n     * Determine if the request is the result of a PJAX call.\n     *\n     * @return bool\n     */\n    public function pjax()\n    {\n        return $this->headers->get('X-PJAX') == true;\n    }\n\n    /**\n     * Determine if the request is the result of a prefetch call.\n     *\n     * @return bool\n     */\n    public function prefetch()\n    {\n        return strcasecmp($this->server->get('HTTP_X_MOZ') ?? '', 'prefetch') === 0 ||\n               strcasecmp($this->headers->get('Purpose') ?? '', 'prefetch') === 0 ||\n               strcasecmp($this->headers->get('Sec-Purpose') ?? '', 'prefetch') === 0;\n    }\n\n    /**\n     * Determine if the request is over HTTPS.\n     *\n     * @return bool\n     */\n    public function secure()\n    {\n        return $this->isSecure();\n    }\n\n    /**\n     * Get the client IP address.\n     *\n     * @return string|null\n     */\n    public function ip()\n    {\n        return $this->getClientIp();\n    }\n\n    /**\n     * Get the client IP addresses.\n     *\n     * @return array\n     */\n    public function ips()\n    {\n        return $this->getClientIps();\n    }\n\n    /**\n     * Get the client user agent.\n     *\n     * @return string|null\n     */\n    public function userAgent()\n    {\n        return $this->headers->get('User-Agent');\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function getAcceptableContentTypes(): array\n    {\n        $currentAcceptHeader = $this->headers->get('Accept');\n\n        if ($this->cachedAcceptHeader !== $currentAcceptHeader) {\n            // Flush acceptable content types so Symfony re-calculates them...\n            $this->acceptableContentTypes = null;\n            $this->cachedAcceptHeader = $currentAcceptHeader;\n        }\n\n        return parent::getAcceptableContentTypes();\n    }\n\n    /**\n     * Merge new input into the current request's input array.\n     *\n     * @param  array  $input\n     * @return $this\n     */\n    public function merge(array $input)\n    {\n        return tap($this, function (Request $request) use ($input) {\n            $request->getInputSource()\n                ->replace((new Collection($input))->reduce(\n                    fn ($requestInput, $value, $key) => data_set($requestInput, $key, $value),\n                    $this->getInputSource()->all()\n                ));\n        });\n    }\n\n    /**\n     * Merge new input into the request's input, but only when that key is missing from the request.\n     *\n     * @param  array  $input\n     * @return $this\n     */\n    public function mergeIfMissing(array $input)\n    {\n        return $this->merge((new Collection($input))\n            ->filter(fn ($value, $key) => $this->missing($key))\n            ->toArray()\n        );\n    }\n\n    /**\n     * Replace the input values for the current request.\n     *\n     * @param  array  $input\n     * @return $this\n     */\n    public function replace(array $input)\n    {\n        $this->getInputSource()->replace($input);\n\n        return $this;\n    }\n\n    /**\n     * This method belongs to Symfony HttpFoundation and is not usually needed when using Laravel.\n     *\n     * Instead, you may use the \"input\" method.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     *\n     * @deprecated use ->input() instead\n     */\n    public function get(string $key, mixed $default = null): mixed\n    {\n        if ($this !== $result = $this->attributes->get($key, $this)) {\n            return $result;\n        }\n\n        if ($this->query->has($key)) {\n            return $this->query->all()[$key];\n        }\n\n        if ($this->request->has($key)) {\n            return $this->request->all()[$key];\n        }\n\n        return $default;\n    }\n\n    /**\n     * Get the JSON payload for the request.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is null ? \\Symfony\\Component\\HttpFoundation\\InputBag : mixed)\n     */\n    public function json($key = null, $default = null)\n    {\n        if (! isset($this->json)) {\n            $this->json = new InputBag((array) json_decode($this->getContent() ?: '[]', true));\n        }\n\n        if (is_null($key)) {\n            return $this->json;\n        }\n\n        return data_get($this->json->all(), $key, $default);\n    }\n\n    /**\n     * Get the input source for the request.\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\InputBag\n     */\n    protected function getInputSource()\n    {\n        if ($this->isJson()) {\n            return $this->json();\n        }\n\n        return in_array($this->getRealMethod(), ['GET', 'HEAD']) ? $this->query : $this->request;\n    }\n\n    /**\n     * Create a new request instance from the given Laravel request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $from\n     * @param  \\Illuminate\\Http\\Request|null  $to\n     * @return static\n     */\n    public static function createFrom(self $from, $to = null)\n    {\n        $request = $to ?: new static;\n\n        $files = array_filter($from->files->all());\n\n        $request->initialize(\n            $from->query->all(),\n            $from->request->all(),\n            $from->attributes->all(),\n            $from->cookies->all(),\n            $files,\n            $from->server->all(),\n            $from->getContent()\n        );\n\n        $request->headers->replace($from->headers->all());\n\n        $request->setRequestLocale($from->getLocale());\n\n        $request->setDefaultRequestLocale($from->getDefaultLocale());\n\n        $request->setJson($from->json());\n\n        if ($from->hasSession() && $session = $from->session()) {\n            $request->setLaravelSession($session);\n        }\n\n        $request->setUserResolver($from->getUserResolver());\n\n        $request->setRouteResolver($from->getRouteResolver());\n\n        return $request;\n    }\n\n    /**\n     * Create an Illuminate request from a Symfony instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @return static\n     */\n    public static function createFromBase(SymfonyRequest $request)\n    {\n        $newRequest = new static(\n            $request->query->all(), $request->request->all(), $request->attributes->all(),\n            $request->cookies->all(), (new static)->filterFiles($request->files->all()) ?? [], $request->server->all()\n        );\n\n        $newRequest->headers->replace($request->headers->all());\n\n        $newRequest->content = $request->content;\n\n        if ($newRequest->isJson()) {\n            $newRequest->request = $newRequest->json();\n        }\n\n        return $newRequest;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return static\n     */\n    #[\\Override]\n    public function duplicate(?array $query = null, ?array $request = null, ?array $attributes = null, ?array $cookies = null, ?array $files = null, ?array $server = null): static\n    {\n        return parent::duplicate($query, $request, $attributes, $cookies, $this->filterFiles($files), $server);\n    }\n\n    /**\n     * Filter the given array of files, removing any empty values.\n     *\n     * @param  mixed  $files\n     * @return mixed\n     */\n    protected function filterFiles($files)\n    {\n        if (! $files) {\n            return;\n        }\n\n        foreach ($files as $key => $file) {\n            if (is_array($file)) {\n                $files[$key] = $this->filterFiles($files[$key]);\n            }\n\n            if (empty($files[$key])) {\n                unset($files[$key]);\n            }\n        }\n\n        return $files;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    #[\\Override]\n    public function hasSession(bool $skipIfUninitialized = false): bool\n    {\n        return $this->session instanceof SymfonySessionDecorator;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @throws \\Symfony\\Component\\HttpFoundation\\Exception\\SessionNotFoundException\n     */\n    #[\\Override]\n    public function getSession(): SessionInterface\n    {\n        return $this->hasSession()\n            ? $this->session\n            : throw new SessionNotFoundException;\n    }\n\n    /**\n     * Get the session associated with the request.\n     *\n     * @return \\Illuminate\\Contracts\\Session\\Session\n     *\n     * @throws \\RuntimeException\n     */\n    public function session()\n    {\n        if (! $this->hasSession()) {\n            throw new RuntimeException('Session store not set on request.');\n        }\n\n        return $this->session->store;\n    }\n\n    /**\n     * Set the session instance on the request.\n     *\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @return void\n     */\n    public function setLaravelSession($session)\n    {\n        $this->session = new SymfonySessionDecorator($session);\n    }\n\n    /**\n     * Set the locale for the request instance.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public function setRequestLocale(string $locale)\n    {\n        $this->locale = $locale;\n    }\n\n    /**\n     * Set the default locale for the request instance.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public function setDefaultRequestLocale(string $locale)\n    {\n        $this->defaultLocale = $locale;\n    }\n\n    /**\n     * Get the user making the request.\n     *\n     * @param  string|null  $guard\n     * @return mixed\n     */\n    public function user($guard = null)\n    {\n        return call_user_func($this->getUserResolver(), $guard);\n    }\n\n    /**\n     * Get the route handling the request.\n     *\n     * @param  string|null  $param\n     * @param  mixed  $default\n     * @return ($param is null ? \\Illuminate\\Routing\\Route : object|string|null)\n     */\n    public function route($param = null, $default = null)\n    {\n        $route = call_user_func($this->getRouteResolver());\n\n        if (is_null($route) || is_null($param)) {\n            return $route;\n        }\n\n        return $route->parameter($param, $default);\n    }\n\n    /**\n     * Get a unique fingerprint for the request / route / IP address.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    public function fingerprint()\n    {\n        if (! $route = $this->route()) {\n            throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');\n        }\n\n        return sha1(implode('|', array_merge(\n            $route->methods(),\n            [$route->getDomain(), $route->uri(), $this->ip()]\n        )));\n    }\n\n    /**\n     * Set the JSON payload for the request.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\InputBag  $json\n     * @return $this\n     */\n    public function setJson($json)\n    {\n        $this->json = $json;\n\n        return $this;\n    }\n\n    /**\n     * Get the user resolver callback.\n     *\n     * @return \\Closure\n     */\n    public function getUserResolver()\n    {\n        return $this->userResolver ?: function () {\n            //\n        };\n    }\n\n    /**\n     * Set the user resolver callback.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function setUserResolver(Closure $callback)\n    {\n        $this->userResolver = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the route resolver callback.\n     *\n     * @return \\Closure\n     */\n    public function getRouteResolver()\n    {\n        return $this->routeResolver ?: function () {\n            //\n        };\n    }\n\n    /**\n     * Set the route resolver callback.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function setRouteResolver(Closure $callback)\n    {\n        $this->routeResolver = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get all of the input and files for the request.\n     *\n     * @return array\n     */\n    public function toArray(): array\n    {\n        return $this->all();\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        $route = $this->route();\n\n        return Arr::has(\n            $this->all() + ($route ? $route->parameters() : []),\n            $offset\n        );\n    }\n\n    /**\n     * Get the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->__get($offset);\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->getInputSource()->set($offset, $value);\n    }\n\n    /**\n     * Remove the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        $this->getInputSource()->remove($offset);\n    }\n\n    /**\n     * Check if an input element is set on the request.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return ! is_null($this->__get($key));\n    }\n\n    /**\n     * Get an input element from the request.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return Arr::get($this->all(), $key, fn () => $this->route($key));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Attributes/Collects.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Collects\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $class\n     */\n    public function __construct(public string $class)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Attributes/PreserveKeys.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass PreserveKeys\n{\n    /**\n     * Create a new attribute instance.\n     */\n    public function __construct()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/CollectsResources.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\nuse Illuminate\\Http\\Resources\\Attributes\\Collects;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Pagination\\AbstractCursorPaginator;\nuse Illuminate\\Pagination\\AbstractPaginator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse LogicException;\nuse ReflectionClass;\nuse Traversable;\n\ntrait CollectsResources\n{\n    /**\n     * The cached Collects attribute values.\n     *\n     * @var array<class-string, class-string|false>\n     */\n    protected static $cachedCollectsAttributes = [];\n\n    /**\n     * Map the given collection resource into its individual resources.\n     *\n     * @param  mixed  $resource\n     * @return mixed\n     */\n    protected function collectResource($resource)\n    {\n        if ($resource instanceof MissingValue) {\n            return $resource;\n        }\n\n        if (is_array($resource)) {\n            $resource = new Collection($resource);\n        }\n\n        $collects = $this->collects();\n\n        $this->collection = $collects && ! $resource->first() instanceof $collects\n            ? $resource->mapInto($collects)\n            : $resource->toBase();\n\n        return ($resource instanceof AbstractPaginator || $resource instanceof AbstractCursorPaginator)\n            ? $resource->setCollection($this->collection)\n            : $this->collection;\n    }\n\n    /**\n     * Get the resource that this resource collects.\n     *\n     * @return class-string<\\Illuminate\\Http\\Resources\\Json\\JsonResource>|null\n     *\n     * @throws \\LogicException\n     */\n    protected function collects()\n    {\n        $collects = null;\n\n        if (! array_key_exists(static::class, static::$cachedCollectsAttributes)) {\n            $attribute = (new ReflectionClass($this))->getAttributes(Collects::class);\n\n            static::$cachedCollectsAttributes[static::class] = count($attribute) > 0\n                ? $attribute[0]->newInstance()->class\n                : false;\n        }\n\n        if (static::$cachedCollectsAttributes[static::class]) {\n            $collects = static::$cachedCollectsAttributes[static::class];\n        } elseif ($this->collects) {\n            $collects = $this->collects;\n        } elseif (str_ends_with(class_basename($this), 'Collection') &&\n            (class_exists($class = Str::replaceLast('Collection', '', get_class($this))) ||\n             class_exists($class = Str::replaceLast('Collection', 'Resource', get_class($this))))) {\n            $collects = $class;\n        }\n\n        if (! $collects || is_a($collects, JsonResource::class, true)) {\n            return $collects;\n        }\n\n        throw new LogicException('Resource collections must collect instances of '.JsonResource::class.'.');\n    }\n\n    /**\n     * Get the JSON serialization options that should be applied to the resource response.\n     *\n     * @return int\n     *\n     * @throws \\ReflectionException\n     */\n    public function jsonOptions()\n    {\n        $collects = $this->collects();\n\n        if (! $collects) {\n            return 0;\n        }\n\n        return (new ReflectionClass($collects))\n            ->newInstanceWithoutConstructor()\n            ->jsonOptions();\n    }\n\n    /**\n     * Get an iterator for the resource collection.\n     *\n     * @return \\ArrayIterator\n     */\n    public function getIterator(): Traversable\n    {\n        return $this->collection->getIterator();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\nuse Illuminate\\Http\\Resources\\Attributes\\PreserveKeys;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Stringable;\nuse ReflectionClass;\n\ntrait ConditionallyLoadsAttributes\n{\n    /**\n     * The cached preserve keys attribute values.\n     *\n     * @var array<class-string, bool>\n     */\n    protected static $cachedPreserveKeysAttributes = [];\n\n    /**\n     * Filter the given data, removing any optional values.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function filter($data)\n    {\n        $index = -1;\n\n        foreach ($data as $key => $value) {\n            $index++;\n\n            if (is_array($value)) {\n                $data[$key] = $this->filter($value);\n\n                continue;\n            }\n\n            if (is_numeric($key) && $value instanceof MergeValue) {\n                return $this->mergeData(\n                    $data, $index, $this->filter($value->data),\n                    array_values($value->data) === $value->data\n                );\n            }\n\n            if ($value instanceof self && is_null($value->resource)) {\n                $data[$key] = null;\n            }\n        }\n\n        return $this->removeMissingValues($data);\n    }\n\n    /**\n     * Merge the given data in at the given index.\n     *\n     * @param  array  $data\n     * @param  int  $index\n     * @param  array  $merge\n     * @param  bool  $numericKeys\n     * @return array\n     */\n    protected function mergeData($data, $index, $merge, $numericKeys)\n    {\n        if ($numericKeys) {\n            return $this->removeMissingValues(array_merge(\n                array_merge(array_slice($data, 0, $index, true), $merge),\n                $this->filter(array_values(array_slice($data, $index + 1, null, true)))\n            ));\n        }\n\n        return $this->removeMissingValues(array_slice($data, 0, $index, true) +\n                $merge +\n                $this->filter(array_slice($data, $index + 1, null, true)));\n    }\n\n    /**\n     * Remove the missing values from the filtered data.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function removeMissingValues($data)\n    {\n        $numericKeys = true;\n\n        foreach ($data as $key => $value) {\n            if (($value instanceof PotentiallyMissing && $value->isMissing()) ||\n                ($value instanceof self &&\n                $value->resource instanceof PotentiallyMissing &&\n                $value->isMissing())) {\n                unset($data[$key]);\n            } else {\n                $numericKeys = $numericKeys && is_numeric($key);\n            }\n        }\n\n        if (! array_key_exists(static::class, static::$cachedPreserveKeysAttributes)) {\n            static::$cachedPreserveKeysAttributes[static::class] = count(\n                (new ReflectionClass($this))->getAttributes(PreserveKeys::class)\n            ) > 0;\n        }\n\n        if (static::$cachedPreserveKeysAttributes[static::class]) {\n            return $data;\n        }\n\n        if (property_exists($this, 'preserveKeys') && $this->preserveKeys === true) {\n            return $data;\n        }\n\n        return $numericKeys ? array_values($data) : $data;\n    }\n\n    /**\n     * Retrieve a value if the given \"condition\" is truthy.\n     *\n     * @param  bool  $condition\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function when($condition, $value, $default = new MissingValue)\n    {\n        if ($condition) {\n            return value($value);\n        }\n\n        return func_num_args() === 3 ? value($default) : $default;\n    }\n\n    /**\n     * Retrieve a value if the given \"condition\" is falsy.\n     *\n     * @param  bool  $condition\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    public function unless($condition, $value, $default = new MissingValue)\n    {\n        $arguments = func_num_args() === 2 ? [$value] : [$value, $default];\n\n        return $this->when(! $condition, ...$arguments);\n    }\n\n    /**\n     * Merge a value into the array.\n     *\n     * @param  mixed  $value\n     * @return \\Illuminate\\Http\\Resources\\MergeValue|mixed\n     */\n    protected function merge($value)\n    {\n        return $this->mergeWhen(true, $value);\n    }\n\n    /**\n     * Merge a value if the given condition is truthy.\n     *\n     * @param  bool  $condition\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MergeValue|mixed\n     */\n    protected function mergeWhen($condition, $value, $default = new MissingValue)\n    {\n        if ($condition) {\n            return new MergeValue(value($value));\n        }\n\n        return func_num_args() === 3 ? new MergeValue(value($default)) : $default;\n    }\n\n    /**\n     * Merge a value unless the given condition is truthy.\n     *\n     * @param  bool  $condition\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MergeValue|mixed\n     */\n    protected function mergeUnless($condition, $value, $default = new MissingValue)\n    {\n        $arguments = func_num_args() === 2 ? [$value] : [$value, $default];\n\n        return $this->mergeWhen(! $condition, ...$arguments);\n    }\n\n    /**\n     * Merge the given attributes.\n     *\n     * @param  array  $attributes\n     * @return \\Illuminate\\Http\\Resources\\MergeValue\n     */\n    protected function attributes($attributes)\n    {\n        return new MergeValue(\n            Arr::only($this->resource->toArray(), $attributes)\n        );\n    }\n\n    /**\n     * Retrieve an attribute if it exists on the resource.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    public function whenHas($attribute, $value = null, $default = new MissingValue)\n    {\n        if (! array_key_exists($attribute, $this->resource->getAttributes())) {\n            return value($default);\n        }\n\n        return func_num_args() === 1\n            ? $this->resource->{$attribute}\n            : value($value, $this->resource->{$attribute});\n    }\n\n    /**\n     * Retrieve a model attribute if it is null.\n     *\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenNull($value, $default = new MissingValue)\n    {\n        $arguments = func_num_args() == 1 ? [$value] : [$value, $default];\n\n        return $this->when(is_null($value), ...$arguments);\n    }\n\n    /**\n     * Retrieve a model attribute if it is not null.\n     *\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenNotNull($value, $default = new MissingValue)\n    {\n        $arguments = func_num_args() == 1 ? [$value] : [$value, $default];\n\n        return $this->when(! is_null($value), ...$arguments);\n    }\n\n    /**\n     * Retrieve an accessor when it has been appended.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenAppended($attribute, $value = null, $default = new MissingValue)\n    {\n        if ($this->resource->hasAppended($attribute)) {\n            return func_num_args() >= 2 ? value($value) : $this->resource->$attribute;\n        }\n\n        return func_num_args() === 3 ? value($default) : $default;\n    }\n\n    /**\n     * Retrieve a relationship if it has been loaded.\n     *\n     * @param  string  $relationship\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenLoaded($relationship, $value = null, $default = new MissingValue)\n    {\n        if (! $this->resource->relationLoaded($relationship)) {\n            return value($default);\n        }\n\n        $loadedValue = $this->resource->{$relationship};\n\n        if (func_num_args() === 1) {\n            return $loadedValue;\n        }\n\n        if ($loadedValue === null) {\n            return;\n        }\n\n        if ($value === null) {\n            $value = value(...);\n        }\n\n        return value($value, $loadedValue);\n    }\n\n    /**\n     * Retrieve a relationship count if it exists.\n     *\n     * @param  string  $relationship\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    public function whenCounted($relationship, $value = null, $default = new MissingValue)\n    {\n        $attribute = (new Stringable($relationship))->snake()->finish('_count')->value();\n\n        if (! array_key_exists($attribute, $this->resource->getAttributes())) {\n            return value($default);\n        }\n\n        if (func_num_args() === 1) {\n            return $this->resource->{$attribute};\n        }\n\n        if ($this->resource->{$attribute} === null) {\n            return;\n        }\n\n        if ($value === null) {\n            $value = value(...);\n        }\n\n        return value($value, $this->resource->{$attribute});\n    }\n\n    /**\n     * Retrieve a relationship aggregated value if it exists.\n     *\n     * @param  string  $relationship\n     * @param  string  $column\n     * @param  string  $aggregate\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    public function whenAggregated($relationship, $column, $aggregate, $value = null, $default = new MissingValue)\n    {\n        $attribute = (new Stringable($relationship))->snake()->append('_')->append($aggregate)->append('_')->finish($column)->value();\n\n        if (! array_key_exists($attribute, $this->resource->getAttributes())) {\n            return value($default);\n        }\n\n        if (func_num_args() === 3) {\n            return $this->resource->{$attribute};\n        }\n\n        if ($this->resource->{$attribute} === null) {\n            return;\n        }\n\n        if ($value === null) {\n            $value = value(...);\n        }\n\n        return value($value, $this->resource->{$attribute});\n    }\n\n    /**\n     * Retrieve a relationship existence check if it exists.\n     *\n     * @param  string  $relationship\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    public function whenExistsLoaded($relationship, $value = null, $default = new MissingValue)\n    {\n        $attribute = (new Stringable($relationship))->snake()->finish('_exists')->value();\n\n        if (! array_key_exists($attribute, $this->resource->getAttributes())) {\n            return value($default);\n        }\n\n        if (func_num_args() === 1) {\n            return $this->resource->{$attribute};\n        }\n\n        if ($this->resource->{$attribute} === null) {\n            return;\n        }\n\n        return value($value, $this->resource->{$attribute});\n    }\n\n    /**\n     * Execute a callback if the given pivot table has been loaded.\n     *\n     * @param  string  $table\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenPivotLoaded($table, $value, $default = new MissingValue)\n    {\n        return $this->whenPivotLoadedAs('pivot', ...func_get_args());\n    }\n\n    /**\n     * Execute a callback if the given pivot table with a custom accessor has been loaded.\n     *\n     * @param  string  $accessor\n     * @param  string  $table\n     * @param  mixed  $value\n     * @param  mixed  $default\n     * @return \\Illuminate\\Http\\Resources\\MissingValue|mixed\n     */\n    protected function whenPivotLoadedAs($accessor, $table, $value, $default = new MissingValue)\n    {\n        return $this->when(\n            $this->hasPivotLoadedAs($accessor, $table),\n            $value,\n            $default,\n        );\n    }\n\n    /**\n     * Determine if the resource has the specified pivot table loaded.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function hasPivotLoaded($table)\n    {\n        return $this->hasPivotLoadedAs('pivot', $table);\n    }\n\n    /**\n     * Determine if the resource has the specified pivot table loaded with a custom accessor.\n     *\n     * @param  string  $accessor\n     * @param  string  $table\n     * @return bool\n     */\n    protected function hasPivotLoadedAs($accessor, $table)\n    {\n        return isset($this->resource->$accessor) &&\n            ($this->resource->$accessor instanceof $table ||\n                $this->resource->$accessor->getTable() === $table);\n    }\n\n    /**\n     * Transform the given value if it is present.\n     *\n     * @param  mixed  $value\n     * @param  callable  $callback\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function transform($value, callable $callback, $default = new MissingValue)\n    {\n        return transform(\n            $value, $callback, $default\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/DelegatesToResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\nuse Exception;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Macroable;\n\ntrait DelegatesToResource\n{\n    use ForwardsCalls, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * Get the value of the resource's route key.\n     *\n     * @return mixed\n     */\n    public function getRouteKey()\n    {\n        return $this->resource->getRouteKey();\n    }\n\n    /**\n     * Get the route key for the resource.\n     *\n     * @return string\n     */\n    public function getRouteKeyName()\n    {\n        return $this->resource->getRouteKeyName();\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function resolveRouteBinding($value, $field = null)\n    {\n        throw new Exception('Resources may not be implicitly resolved from route bindings.');\n    }\n\n    /**\n     * Retrieve the model for a bound value.\n     *\n     * @param  string  $childType\n     * @param  mixed  $value\n     * @param  string|null  $field\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function resolveChildRouteBinding($childType, $value, $field = null)\n    {\n        throw new Exception('Resources may not be implicitly resolved from child route bindings.');\n    }\n\n    /**\n     * Determine if the given attribute exists.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->resource[$offset]);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->resource[$offset];\n    }\n\n    /**\n     * Set the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->resource[$offset] = $value;\n    }\n\n    /**\n     * Unset the value for a given offset.\n     *\n     * @param  mixed  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->resource[$offset]);\n    }\n\n    /**\n     * Determine if an attribute exists on the resource.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return isset($this->resource->{$key});\n    }\n\n    /**\n     * Unset an attribute on the resource.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function __unset($key)\n    {\n        unset($this->resource->{$key});\n    }\n\n    /**\n     * Dynamically get properties from the underlying resource.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->resource->{$key};\n    }\n\n    /**\n     * Dynamically pass method calls to the underlying resource.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->forwardCallTo($this->resource, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Json/AnonymousResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Json;\n\nclass AnonymousResourceCollection extends ResourceCollection\n{\n    /**\n     * The name of the resource being collected.\n     *\n     * @var string\n     */\n    public $collects;\n\n    /**\n     * Indicates if the collection keys should be preserved.\n     *\n     * @var bool\n     */\n    public $preserveKeys = false;\n\n    /**\n     * Create a new anonymous resource collection.\n     *\n     * @param  mixed  $resource\n     * @param  string  $collects\n     */\n    public function __construct($resource, $collects)\n    {\n        $this->collects = $collects;\n\n        parent::__construct($resource);\n    }\n\n    /**\n     * Indicate that the collection keys should be preserved.\n     */\n    public function preserveKeys(bool $value = true): static\n    {\n        $this->preserveKeys = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Json/JsonResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Json;\n\nuse ArrayAccess;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Database\\Eloquent\\JsonEncodingException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Attributes\\PreserveKeys;\nuse Illuminate\\Http\\Resources\\ConditionallyLoadsAttributes;\nuse Illuminate\\Http\\Resources\\DelegatesToResource;\nuse JsonException;\nuse JsonSerializable;\nuse ReflectionClass;\n\nclass JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRoutable\n{\n    use ConditionallyLoadsAttributes, DelegatesToResource;\n\n    /**\n     * The resource instance.\n     *\n     * @var mixed\n     */\n    public $resource;\n\n    /**\n     * The additional data that should be added to the top-level resource array.\n     *\n     * @var array\n     */\n    public $with = [];\n\n    /**\n     * The additional metadata that should be added to the resource response.\n     *\n     * Added during response construction by the developer.\n     *\n     * @var array\n     */\n    public $additional = [];\n\n    /**\n     * The \"data\" wrapper that should be applied.\n     *\n     * @var string|null\n     */\n    public static $wrap = 'data';\n\n    /**\n     * Whether to force wrapping even if the $wrap key exists in underlying resource data.\n     *\n     * @var bool\n     */\n    public static bool $forceWrapping = false;\n\n    /**\n     * Create a new resource instance.\n     *\n     * @param  mixed  $resource\n     */\n    public function __construct($resource)\n    {\n        $this->resource = $resource;\n    }\n\n    /**\n     * Create a new resource instance.\n     *\n     * @param  mixed  ...$parameters\n     * @return static\n     */\n    public static function make(...$parameters)\n    {\n        return new static(...$parameters);\n    }\n\n    /**\n     * Create a new anonymous resource collection.\n     *\n     * @param  mixed  $resource\n     * @return \\Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection\n     */\n    public static function collection($resource)\n    {\n        return tap(static::newCollection($resource), function ($collection) {\n            if (! array_key_exists(static::class, static::$cachedPreserveKeysAttributes)) {\n                static::$cachedPreserveKeysAttributes[static::class] = count(\n                    (new ReflectionClass(static::class))->getAttributes(PreserveKeys::class)\n                ) > 0;\n            }\n\n            if (static::$cachedPreserveKeysAttributes[static::class]) {\n                $collection->preserveKeys = true;\n            } elseif (property_exists(static::class, 'preserveKeys')) {\n                $collection->preserveKeys = (new static([]))->preserveKeys === true;\n            }\n        });\n    }\n\n    /**\n     * Create a new resource collection instance.\n     *\n     * @param  mixed  $resource\n     * @return \\Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection\n     */\n    protected static function newCollection($resource)\n    {\n        return new AnonymousResourceCollection($resource, static::class);\n    }\n\n    /**\n     * Resolve the resource to an array.\n     *\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return array\n     */\n    public function resolve($request = null)\n    {\n        $data = $this->resolveResourceData(\n            $request ?: $this->resolveRequestFromContainer()\n        );\n\n        if ($data instanceof Arrayable) {\n            $data = $data->toArray();\n        } elseif ($data instanceof JsonSerializable) {\n            $data = $data->jsonSerialize();\n        }\n\n        return $this->filter((array) $data);\n    }\n\n    /**\n     * Transform the resource into an array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|\\Illuminate\\Contracts\\Support\\Arrayable|\\JsonSerializable\n     */\n    public function toAttributes(Request $request)\n    {\n        if (property_exists($this, 'attributes')) {\n            return $this->attributes;\n        }\n\n        return $this->toArray($request);\n    }\n\n    /**\n     * Resolve the resource data to an array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    public function resolveResourceData(Request $request)\n    {\n        return $this->toAttributes($request);\n    }\n\n    /**\n     * Transform the resource into an array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|\\Illuminate\\Contracts\\Support\\Arrayable|\\JsonSerializable\n     */\n    public function toArray(Request $request)\n    {\n        if (is_null($this->resource)) {\n            return [];\n        }\n\n        return is_array($this->resource)\n            ? $this->resource\n            : $this->resource->toArray();\n    }\n\n    /**\n     * Convert the resource to JSON.\n     *\n     * @param  int  $options\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\JsonEncodingException\n     */\n    public function toJson($options = 0)\n    {\n        try {\n            $json = json_encode($this->jsonSerialize(), $options | JSON_THROW_ON_ERROR);\n        } catch (JsonException $e) {\n            throw JsonEncodingException::forResource($this, $e->getMessage());\n        }\n\n        return $json;\n    }\n\n    /**\n     * Convert the resource to pretty print formatted JSON.\n     *\n     * @param  int  $options\n     * @return string\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\JsonEncodingException\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n\n    /**\n     * Get any additional data that should be returned with the resource array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    public function with(Request $request)\n    {\n        return $this->with;\n    }\n\n    /**\n     * Add additional metadata to the resource response.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function additional(array $data)\n    {\n        $this->additional = $data;\n\n        return $this;\n    }\n\n    /**\n     * Get the JSON serialization options that should be applied to the resource response.\n     *\n     * @return int\n     */\n    public function jsonOptions()\n    {\n        return 0;\n    }\n\n    /**\n     * Customize the response for a request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\JsonResponse  $response\n     * @return void\n     */\n    public function withResponse(Request $request, JsonResponse $response)\n    {\n        //\n    }\n\n    /**\n     * Resolve the HTTP request instance from container.\n     *\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function resolveRequestFromContainer()\n    {\n        return Container::getInstance()->make('request');\n    }\n\n    /**\n     * Set the string that should wrap the outer-most resource array.\n     *\n     * @param  string  $value\n     * @return void\n     */\n    public static function wrap($value)\n    {\n        static::$wrap = $value;\n    }\n\n    /**\n     * Disable wrapping of the outer-most resource array.\n     *\n     * @return void\n     */\n    public static function withoutWrapping()\n    {\n        static::$wrap = null;\n    }\n\n    /**\n     * Transform the resource into an HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function response($request = null)\n    {\n        return $this->toResponse(\n            $request ?: $this->resolveRequestFromContainer()\n        );\n    }\n\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function toResponse($request)\n    {\n        return (new ResourceResponse($this))->toResponse($request);\n    }\n\n    /**\n     * Prepare the resource for JSON serialization.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->resolve($this->resolveRequestFromContainer());\n    }\n\n    /**\n     * Flush the resource's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$wrap = 'data';\n        static::$forceWrapping = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Json;\n\nuse Illuminate\\Support\\Arr;\n\nclass PaginatedResourceResponse extends ResourceResponse\n{\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function toResponse($request)\n    {\n        return tap(response()->json(\n            $this->wrap(\n                $this->resource->resolve($request),\n                array_merge_recursive(\n                    $this->paginationInformation($request),\n                    $this->resource->with($request),\n                    $this->resource->additional\n                )\n            ),\n            $this->calculateStatus(),\n            [],\n            $this->resource->jsonOptions()\n        ), function ($response) use ($request) {\n            $response->original = $this->resource->resource->map(function ($item) {\n                if (is_array($item)) {\n                    return Arr::get($item, 'resource');\n                } elseif (is_object($item)) {\n                    return $item->resource ?? null;\n                }\n\n                return null;\n            });\n\n            $this->resource->withResponse($request, $response);\n        });\n    }\n\n    /**\n     * Add the pagination information to the response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    protected function paginationInformation($request)\n    {\n        $paginated = $this->resource->resource->toArray();\n\n        $default = [\n            'links' => $this->paginationLinks($paginated),\n            'meta' => $this->meta($paginated),\n        ];\n\n        if (method_exists($this->resource, 'paginationInformation') ||\n            $this->resource->hasMacro('paginationInformation')) {\n            return $this->resource->paginationInformation($request, $paginated, $default);\n        }\n\n        return $default;\n    }\n\n    /**\n     * Get the pagination links for the response.\n     *\n     * @param  array  $paginated\n     * @return array\n     */\n    protected function paginationLinks($paginated)\n    {\n        return [\n            'first' => $paginated['first_page_url'] ?? null,\n            'last' => $paginated['last_page_url'] ?? null,\n            'prev' => $paginated['prev_page_url'] ?? null,\n            'next' => $paginated['next_page_url'] ?? null,\n        ];\n    }\n\n    /**\n     * Gather the metadata for the response.\n     *\n     * @param  array  $paginated\n     * @return array\n     */\n    protected function meta($paginated)\n    {\n        return Arr::except($paginated, [\n            'data',\n            'first_page_url',\n            'last_page_url',\n            'prev_page_url',\n            'next_page_url',\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Json/ResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Json;\n\nuse Countable;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\CollectsResources;\nuse Illuminate\\Pagination\\AbstractCursorPaginator;\nuse Illuminate\\Pagination\\AbstractPaginator;\nuse IteratorAggregate;\n\nclass ResourceCollection extends JsonResource implements Countable, IteratorAggregate\n{\n    use CollectsResources;\n\n    /**\n     * The resource that this resource collects.\n     *\n     * @var string\n     */\n    public $collects;\n\n    /**\n     * The mapped collection instance.\n     *\n     * @var \\Illuminate\\Support\\Collection|null\n     */\n    public $collection;\n\n    /**\n     * Indicates if all existing request query parameters should be added to pagination links.\n     *\n     * @var bool\n     */\n    protected $preserveAllQueryParameters = false;\n\n    /**\n     * The query parameters that should be added to the pagination links.\n     *\n     * @var array|null\n     */\n    protected $queryParameters;\n\n    /**\n     * Create a new resource instance.\n     *\n     * @param  mixed  $resource\n     */\n    public function __construct($resource)\n    {\n        parent::__construct($resource);\n\n        $this->resource = $this->collectResource($resource);\n    }\n\n    /**\n     * Indicate that all current query parameters should be appended to pagination links.\n     *\n     * @return $this\n     */\n    public function preserveQuery()\n    {\n        $this->preserveAllQueryParameters = true;\n\n        return $this;\n    }\n\n    /**\n     * Specify the query string parameters that should be present on pagination links.\n     *\n     * @param  array  $query\n     * @return $this\n     */\n    public function withQuery(array $query)\n    {\n        $this->preserveAllQueryParameters = false;\n\n        $this->queryParameters = $query;\n\n        return $this;\n    }\n\n    /**\n     * Return the count of items in the resource collection.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return $this->collection->count();\n    }\n\n    /**\n     * Transform the resource into a JSON array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array|\\Illuminate\\Contracts\\Support\\Arrayable|\\JsonSerializable\n     */\n    #[\\Override]\n    public function toArray(Request $request)\n    {\n        if ($this->collection->first() instanceof JsonResource) {\n            return $this->collection->map->resolve($request)->all();\n        }\n\n        return $this->collection->map->toArray($request)->all();\n    }\n\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function toResponse($request)\n    {\n        if ($this->resource instanceof AbstractPaginator || $this->resource instanceof AbstractCursorPaginator) {\n            return $this->preparePaginatedResponse($request);\n        }\n\n        return parent::toResponse($request);\n    }\n\n    /**\n     * Create a paginate-aware HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    protected function preparePaginatedResponse($request)\n    {\n        if ($this->preserveAllQueryParameters) {\n            $this->resource->appends($request->query());\n        } elseif (! is_null($this->queryParameters)) {\n            $this->resource->appends($this->queryParameters);\n        }\n\n        return (new PaginatedResourceResponse($this))->toResponse($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/Json/ResourceResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\Json;\n\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\n\nclass ResourceResponse implements Responsable\n{\n    /**\n     * The underlying resource.\n     *\n     * @var mixed\n     */\n    public $resource;\n\n    /**\n     * Create a new resource response.\n     *\n     * @param  mixed  $resource\n     */\n    public function __construct($resource)\n    {\n        $this->resource = $resource;\n    }\n\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function toResponse($request)\n    {\n        return tap(response()->json(\n            $this->wrap(\n                $this->resource->resolve($request),\n                $this->resource->with($request),\n                $this->resource->additional\n            ),\n            $this->calculateStatus(),\n            [],\n            $this->resource->jsonOptions()\n        ), function ($response) use ($request) {\n            $response->original = $this->resource->resource;\n\n            $this->resource->withResponse($request, $response);\n        });\n    }\n\n    /**\n     * Wrap the given data if necessary.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array  $data\n     * @param  array  $with\n     * @param  array  $additional\n     * @return array\n     */\n    protected function wrap($data, $with = [], $additional = [])\n    {\n        if ($data instanceof Collection) {\n            $data = $data->all();\n        }\n\n        if ($this->haveDefaultWrapperAndDataIsUnwrapped($data)) {\n            $data = [$this->wrapper() => $data];\n        } elseif ($this->haveAdditionalInformationAndDataIsUnwrapped($data, $with, $additional)) {\n            $data = [($this->wrapper() ?? 'data') => $data];\n        }\n\n        return array_merge_recursive($data, $with, $additional);\n    }\n\n    /**\n     * Determine if we have a default wrapper and the given data is unwrapped.\n     *\n     * @param  array  $data\n     * @return bool\n     */\n    protected function haveDefaultWrapperAndDataIsUnwrapped($data)\n    {\n        if ($this->resource instanceof JsonResource && $this->resource::$forceWrapping) {\n            return $this->wrapper() !== null;\n        }\n\n        return $this->wrapper() && ! array_key_exists($this->wrapper(), $data);\n    }\n\n    /**\n     * Determine if \"with\" data has been added and our data is unwrapped.\n     *\n     * @param  array  $data\n     * @param  array  $with\n     * @param  array  $additional\n     * @return bool\n     */\n    protected function haveAdditionalInformationAndDataIsUnwrapped($data, $with, $additional)\n    {\n        return (! empty($with) || ! empty($additional)) &&\n               (! $this->wrapper() ||\n                ! array_key_exists($this->wrapper(), $data));\n    }\n\n    /**\n     * Get the default data wrapper for the resource.\n     *\n     * @return string\n     */\n    protected function wrapper()\n    {\n        return get_class($this->resource)::$wrap;\n    }\n\n    /**\n     * Calculate the appropriate status code for the response.\n     *\n     * @return int\n     */\n    protected function calculateStatus()\n    {\n        return $this->resource->resource instanceof Model &&\n               $this->resource->resource->wasRecentlyCreated ? 201 : 200;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/AnonymousResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection as BaseAnonymousResourceCollection;\nuse Illuminate\\Support\\Arr;\n\nclass AnonymousResourceCollection extends BaseAnonymousResourceCollection\n{\n    use Concerns\\ResolvesJsonApiRequest;\n\n    /**\n     * Get any additional data that should be returned with the resource array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    #[\\Override]\n    public function with($request)\n    {\n        return array_filter([\n            'included' => $this->collection\n                ->map(fn ($resource) => $resource->resolveIncludedResourceObjects($request))\n                ->flatten(depth: 1)\n                ->uniqueStrict('_uniqueKey')\n                ->map(fn ($included) => Arr::except($included, ['_uniqueKey']))\n                ->values()\n                ->all(),\n            ...($implementation = JsonApiResource::$jsonApiInformation)\n                ? ['jsonapi' => $implementation]\n                : [],\n        ]);\n    }\n\n    /**\n     * Transform the resource into a JSON array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    #[\\Override]\n    public function toAttributes(Request $request)\n    {\n        return $this->collection\n            ->map(fn ($resource) => $resource->resolveResourceData($request))\n            ->all();\n    }\n\n    /**\n     * Customize the outgoing response for the resource.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Http\\JsonResponse  $response\n     * @return void\n     */\n    #[\\Override]\n    public function withResponse(Request $request, JsonResponse $response): void\n    {\n        $response->header('Content-Type', 'application/vnd.api+json');\n    }\n\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    #[\\Override]\n    public function toResponse($request)\n    {\n        return parent::toResponse($this->resolveJsonApiRequestFrom($request));\n    }\n\n    /**\n     * Resolve the HTTP request instance from container.\n     *\n     * @return \\Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest\n     */\n    #[\\Override]\n    protected function resolveRequestFromContainer()\n    {\n        return $this->resolveJsonApiRequestFrom(Container::getInstance()->make('request'));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiElements.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi\\Concerns;\n\nuse Generator;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Http\\Resources\\JsonApi\\Exceptions\\ResourceIdentificationException;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\nuse Illuminate\\Http\\Resources\\JsonApi\\RelationResolver;\nuse Illuminate\\Http\\Resources\\MissingValue;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Str;\nuse JsonSerializable;\nuse WeakMap;\n\ntrait ResolvesJsonApiElements\n{\n    /**\n     * Determine whether resources respect inclusions and fields from the request.\n     */\n    protected bool $usesRequestQueryString = true;\n\n    /**\n     * Determine whether included relationship for the resource from eager loaded relationship.\n     */\n    protected bool $includesPreviouslyLoadedRelationships = false;\n\n    /**\n     * Cached loaded relationships map.\n     *\n     * @var array<int, array{0: \\Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource, 1: string, 2: string, 3: bool}|null\n     */\n    public $loadedRelationshipsMap;\n\n    /**\n     * Cached loaded relationships identifiers.\n     */\n    protected array $loadedRelationshipIdentifiers = [];\n\n    /**\n     * The maximum relationship depth.\n     */\n    public static int $maxRelationshipDepth = 5;\n\n    /**\n     * Specify the maximum relationship depth.\n     *\n     * @param  non-negative-int  $depth\n     */\n    public static function maxRelationshipDepth(int $depth): void\n    {\n        static::$maxRelationshipDepth = max(0, $depth);\n    }\n\n    /**\n     * Resolves `data` for the resource.\n     */\n    protected function resolveResourceObject(JsonApiRequest $request): array\n    {\n        $resourceType = $this->resolveResourceType($request);\n\n        return [\n            'id' => $this->resolveResourceIdentifier($request),\n            'type' => $resourceType,\n            ...(new Collection([\n                'attributes' => $this->resolveResourceAttributes($request, $resourceType),\n                'relationships' => $this->resolveResourceRelationshipIdentifiers($request),\n                'links' => $this->resolveResourceLinks($request),\n                'meta' => $this->resolveResourceMetaInformation($request),\n            ]))->filter()->map(fn ($value) => (object) $value),\n        ];\n    }\n\n    /**\n     * Resolve the resource's identifier.\n     *\n     * @return string\n     *\n     * @throws ResourceIdentificationException\n     */\n    public function resolveResourceIdentifier(JsonApiRequest $request): string\n    {\n        if (! is_null($resourceId = $this->toId($request))) {\n            return (string) $resourceId;\n        }\n\n        if (! ($this->resource instanceof Model || method_exists($this->resource, 'getKey'))) {\n            throw ResourceIdentificationException::attemptingToDetermineIdFor($this);\n        }\n\n        return (string) $this->resource->getKey();\n    }\n\n    /**\n     * Resolve the resource's type.\n     *\n     * @throws ResourceIdentificationException\n     */\n    public function resolveResourceType(JsonApiRequest $request): string\n    {\n        if (! is_null($resourceType = $this->toType($request))) {\n            return $resourceType;\n        }\n\n        if (static::class !== JsonApiResource::class) {\n            return Str::of(static::class)->classBasename()->basename('Resource')->snake()->pluralStudly();\n        }\n\n        if (! $this->resource instanceof Model) {\n            throw ResourceIdentificationException::attemptingToDetermineTypeFor($this);\n        }\n\n        $modelClassName = $this->resource::class;\n\n        $morphMap = Relation::getMorphAlias($modelClassName);\n\n        return Str::of(\n            $morphMap !== $modelClassName ? $morphMap : class_basename($modelClassName)\n        )->snake()->pluralStudly();\n    }\n\n    /**\n     * Resolve the resource's attributes.\n     *\n     * @throws \\RuntimeException\n     */\n    protected function resolveResourceAttributes(JsonApiRequest $request, string $resourceType): array\n    {\n        $data = $this->toAttributes($request);\n\n        if ($data instanceof Arrayable) {\n            $data = $data->toArray();\n        } elseif ($data instanceof JsonSerializable) {\n            $data = $data->jsonSerialize();\n        }\n\n        $sparseFieldset = match ($this->usesRequestQueryString) {\n            true => $request->sparseFields($resourceType),\n            default => [],\n        };\n\n        $data = (new Collection($data))\n            ->mapWithKeys(fn ($value, $key) => is_int($key) ? [$value => $this->resource->{$value}] : [$key => $value])\n            ->when(! empty($sparseFieldset), fn ($attributes) => $attributes->only($sparseFieldset))\n            ->transform(fn ($value) => value($value, $request))\n            ->all();\n\n        return $this->filter($data);\n    }\n\n    /**\n     * Resolves `relationships` for the resource's data object.\n     *\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    protected function resolveResourceRelationshipIdentifiers(JsonApiRequest $request): array\n    {\n        if (! $this->resource instanceof Model) {\n            return [];\n        }\n\n        $this->compileResourceRelationships($request);\n\n        return [\n            ...(new Collection($this->filter($this->loadedRelationshipIdentifiers)))\n                ->map(function ($relation) {\n                    return ! is_null($relation) ? $relation : ['data' => null];\n                })->all(),\n        ];\n    }\n\n    /**\n     * Compile resource relationships.\n     */\n    protected function compileResourceRelationships(JsonApiRequest $request): void\n    {\n        if (! is_null($this->loadedRelationshipsMap)) {\n            return;\n        }\n\n        $sparseIncluded = match (true) {\n            $this->includesPreviouslyLoadedRelationships => array_keys($this->resource->getRelations()),\n            default => $request->sparseIncluded(),\n        };\n\n        $resourceRelationships = (new Collection($this->toRelationships($request)))\n            ->transform(fn ($value, $key) => is_int($key) ? new RelationResolver($value) : new RelationResolver($key, $value))\n            ->mapWithKeys(fn ($relationResolver) => [$relationResolver->relationName => $relationResolver])\n            ->filter(fn ($value, $key) => in_array($key, $sparseIncluded));\n\n        $resourceRelationshipKeys = $resourceRelationships->keys();\n\n        $this->resource->loadMissing($resourceRelationshipKeys->all() ?? []);\n\n        $this->loadedRelationshipsMap = [];\n\n        $this->loadedRelationshipIdentifiers = (new LazyCollection(function () use ($request, $resourceRelationships) {\n            foreach ($resourceRelationships as $relationName => $relationResolver) {\n                $relatedModels = $relationResolver->handle($this->resource);\n\n                if (! is_null($relatedModels) && $this->includesPreviouslyLoadedRelationships === false) {\n                    if (! empty($relations = $request->sparseIncluded($relationName))) {\n                        $relatedModels->loadMissing($relations);\n                    }\n                }\n\n                yield from $this->compileResourceRelationshipUsingResolver(\n                    $request,\n                    $this->resource,\n                    $relationResolver,\n                    $relatedModels,\n                );\n            }\n        }))->all();\n    }\n\n    /**\n     * Compile resource relations.\n     */\n    protected function compileResourceRelationshipUsingResolver(\n        JsonApiRequest $request,\n        mixed $resource,\n        RelationResolver $relationResolver,\n        Collection|Model|null $relatedModels\n    ): Generator {\n        $relationName = $relationResolver->relationName;\n        $resourceClass = $relationResolver->resourceClass();\n\n        // Relationship is a collection of models...\n        if ($relatedModels instanceof Collection) {\n            $relatedModels = $relatedModels->values();\n\n            if ($relatedModels->isEmpty()) {\n                yield $relationName => ['data' => $relatedModels];\n\n                return;\n            }\n\n            $relationship = $resource->{$relationName}();\n\n            $isUnique = ! $relationship instanceof BelongsToMany;\n\n            yield $relationName => ['data' => $relatedModels->map(function ($relatedModel) use ($request, $resourceClass, $isUnique) {\n                $relatedResource = rescue(fn () => $relatedModel->toResource($resourceClass), new JsonApiResource($relatedModel));\n\n                return transform(\n                    [$relatedResource->resolveResourceType($request), $relatedResource->resolveResourceIdentifier($request)],\n                    function ($uniqueKey) use ($request, $relatedModel, $relatedResource, $isUnique) {\n                        $this->loadedRelationshipsMap[] = [$relatedResource, ...$uniqueKey, $isUnique];\n\n                        $this->compileIncludedNestedRelationshipsMap($request, $relatedModel, $relatedResource);\n\n                        return [\n                            'id' => $uniqueKey[1],\n                            'type' => $uniqueKey[0],\n                        ];\n                    }\n                );\n            })->all()];\n\n            return;\n        }\n\n        // Relationship is a single model...\n        $relatedModel = $relatedModels;\n\n        if (is_null($relatedModel)) {\n            yield $relationName => null;\n\n            return;\n        } elseif ($relatedModel instanceof Pivot ||\n            in_array(AsPivot::class, class_uses_recursive($relatedModel), true)) {\n            yield $relationName => new MissingValue;\n\n            return;\n        }\n\n        $relatedResource = rescue(fn () => $relatedModel->toResource($resourceClass), new JsonApiResource($relatedModel));\n\n        yield $relationName => ['data' => transform(\n            [$relatedResource->resolveResourceType($request), $relatedResource->resolveResourceIdentifier($request)],\n            function ($uniqueKey) use ($relatedModel, $relatedResource, $request) {\n                $this->loadedRelationshipsMap[] = [$relatedResource, ...$uniqueKey, true];\n\n                $this->compileIncludedNestedRelationshipsMap($request, $relatedModel, $relatedResource);\n\n                return [\n                    'id' => $uniqueKey[1],\n                    'type' => $uniqueKey[0],\n                ];\n            }\n        )];\n    }\n\n    /**\n     * Compile included relationships map.\n     */\n    protected function compileIncludedNestedRelationshipsMap(JsonApiRequest $request, Model $relation, JsonApiResource $resource): void\n    {\n        (new Collection($resource->toRelationships($request)))\n            ->transform(fn ($value, $key) => is_int($key) ? new RelationResolver($value) : new RelationResolver($key, $value))\n            ->mapWithKeys(fn ($relationResolver) => [$relationResolver->relationName => $relationResolver])\n            ->filter(fn ($value, $key) => in_array($key, array_keys($relation->getRelations())))\n            ->each(function ($relationResolver, $key) use ($relation, $request) {\n                $this->compileResourceRelationshipUsingResolver($request, $relation, $relationResolver, $relation->getRelation($key));\n            });\n    }\n\n    /**\n     * Resolves `included` for the resource.\n     */\n    public function resolveIncludedResourceObjects(JsonApiRequest $request): Collection\n    {\n        if (! $this->resource instanceof Model) {\n            return new Collection;\n        }\n\n        $this->compileResourceRelationships($request);\n\n        $relations = new Collection;\n        $index = 0;\n\n        // Track visited objects by instance + type to prevent infinite loops from circular\n        // references created by \"chaperone()\". We use object instances rather than type\n        // and ID for any possible cases like BelongsToMany with different pivot data.\n        // We'll track types to allow the same models with different resource types.\n        $visitedObjects = new WeakMap;\n\n        $visitedObjects[$this->resource] = [\n            $this->resolveResourceType($request) => true,\n        ];\n\n        while ($index < count($this->loadedRelationshipsMap)) {\n            [$resourceInstance, $type, $id, $isUnique] = $this->loadedRelationshipsMap[$index];\n\n            $underlyingResource = $resourceInstance->resource;\n\n            if (is_object($underlyingResource)) {\n                if (isset($visitedObjects[$underlyingResource][$type])) {\n                    $index++;\n                    continue;\n                }\n\n                $visitedObjects[$underlyingResource] ??= [];\n                $visitedObjects[$underlyingResource][$type] = true;\n            }\n\n            if (! $resourceInstance instanceof JsonApiResource &&\n                $resourceInstance instanceof JsonResource) {\n                $resourceInstance = new JsonApiResource($resourceInstance->resource);\n            }\n\n            $relationsData = $resourceInstance\n                ->includePreviouslyLoadedRelationships()\n                ->resolve($request);\n\n            array_push($this->loadedRelationshipsMap, ...($resourceInstance->loadedRelationshipsMap ?? []));\n\n            $relations->push(array_filter([\n                'id' => $id,\n                'type' => $type,\n                '_uniqueKey' => implode(':', $isUnique === true ? [$id, $type] : [$id, $type, (string) Str::random()]),\n                'attributes' => Arr::get($relationsData, 'data.attributes'),\n                'relationships' => Arr::get($relationsData, 'data.relationships'),\n                'links' => Arr::get($relationsData, 'data.links'),\n                'meta' => Arr::get($relationsData, 'data.meta'),\n            ]));\n\n            $index++;\n        }\n\n        return $relations;\n    }\n\n    /**\n     * Resolve the links for the resource.\n     *\n     * @return array<string, mixed>\n     */\n    protected function resolveResourceLinks(JsonApiRequest $request): array\n    {\n        return $this->toLinks($request);\n    }\n\n    /**\n     * Resolve the meta information for the resource.\n     *\n     * @return array<string, mixed>\n     */\n    protected function resolveResourceMetaInformation(JsonApiRequest $request): array\n    {\n        return $this->toMeta($request);\n    }\n\n    /**\n     * Indicate that relationship loading should respect the request's \"includes\" query string.\n     *\n     * @return $this\n     */\n    public function respectFieldsAndIncludesInQueryString(bool $value = true)\n    {\n        $this->usesRequestQueryString = $value;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that relationship loading should not rely on the request's \"includes\" query string.\n     *\n     * @return $this\n     */\n    public function ignoreFieldsAndIncludesInQueryString()\n    {\n        return $this->respectFieldsAndIncludesInQueryString(false);\n    }\n\n    /**\n     * Determine relationship should include loaded relationships.\n     *\n     * @return $this\n     */\n    public function includePreviouslyLoadedRelationships()\n    {\n        $this->includesPreviouslyLoadedRelationships = true;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi\\Concerns;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest;\n\ntrait ResolvesJsonApiRequest\n{\n    /**\n     * Resolve a JSON API request instance from the given HTTP request.\n     *\n     * @return \\Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest\n     */\n    protected function resolveJsonApiRequestFrom(Request $request)\n    {\n        return $request instanceof JsonApiRequest\n            ? $request\n            : JsonApiRequest::createFrom($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/Exceptions/ResourceIdentificationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi\\Exceptions;\n\nuse RuntimeException;\n\nclass ResourceIdentificationException extends RuntimeException\n{\n    /**\n     * Create an exception indicating we were unable to determine the resource ID for the given resource.\n     *\n     * @param  mixed  $resource\n     * @return self\n     */\n    public static function attemptingToDetermineIdFor($resource)\n    {\n        $resourceType = is_object($resource) ? $resource::class : gettype($resource);\n\n        return new self(sprintf(\n            'Unable to resolve resource object ID for [%s].', $resourceType\n        ));\n    }\n\n    /**\n     * Create an exception indicating we were unable to determine the resource type for the given resource.\n     *\n     * @param  mixed  $resource\n     * @return self\n     */\n    public static function attemptingToDetermineTypeFor($resource)\n    {\n        $resourceType = is_object($resource) ? $resource::class : gettype($resource);\n\n        return new self(sprintf(\n            'Unable to resolve resource object type for [%s].', $resourceType\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/JsonApiRequest.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nclass JsonApiRequest extends Request\n{\n    /**\n     * Cached sparse fieldset.\n     */\n    protected ?array $cachedSparseFields = null;\n\n    /**\n     * Cached sparse included.\n     */\n    protected ?array $cachedSparseIncluded = null;\n\n    /**\n     * Get the request's included fields.\n     */\n    public function sparseFields(string $key): array\n    {\n        if (is_null($this->cachedSparseFields)) {\n            $this->cachedSparseFields = (new Collection($this->array('fields')))\n                ->transform(fn ($fieldsets) => empty($fieldsets) ? [] : explode(',', $fieldsets))\n                ->all();\n        }\n\n        return $this->cachedSparseFields[$key] ?? [];\n    }\n\n    /**\n     * Get the request's included relationships.\n     */\n    public function sparseIncluded(?string $key = null): ?array\n    {\n        if (is_null($this->cachedSparseIncluded)) {\n            $included = (string) $this->string('include', '');\n\n            $this->cachedSparseIncluded = (new Collection(empty($included) ? [] : explode(',', $included)))\n                ->transform(function ($item) {\n                    $with = null;\n\n                    if (str_contains($item, '.')) {\n                        [$relation, $with] = explode('.', $item, 2);\n                    } else {\n                        $relation = $item;\n                    }\n\n                    return ['relation' => $relation, 'with' => $with];\n                })->mapToGroups(fn ($item) => [$item['relation'] => $item['with']])\n                ->toArray();\n        }\n\n        if (is_null($key)) {\n            return array_keys($this->cachedSparseIncluded);\n        }\n\n        return transform($this->cachedSparseIncluded[$key] ?? null, function ($value) {\n            return Collection::wrap($value)\n                ->transform(function ($item) {\n                    $item = implode('.', Arr::take(explode('.', $item), JsonApiResource::$maxRelationshipDepth - 1));\n\n                    return ! empty($item) ? $item : null;\n                })->filter()->all();\n        }) ?? [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/JsonApiResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi;\n\nuse BadMethodCallException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Support\\Arr;\n\nclass JsonApiResource extends JsonResource\n{\n    use Concerns\\ResolvesJsonApiElements,\n        Concerns\\ResolvesJsonApiRequest;\n\n    /**\n     * The \"data\" wrapper that should be applied.\n     *\n     * @var string|null\n     */\n    public static $wrap = 'data';\n\n    /**\n     * The resource's \"version\" for JSON:API.\n     *\n     * @var array{version?: string, ext?: array, profile?: array, meta?: array}\n     */\n    public static $jsonApiInformation = [];\n\n    /**\n     * The resource's \"links\" for JSON:API.\n     */\n    protected array $jsonApiLinks = [];\n\n    /**\n     * The resource's \"meta\" for JSON:API.\n     */\n    protected array $jsonApiMeta = [];\n\n    /**\n     * Set the JSON:API version for the request.\n     *\n     * @return void\n     */\n    public static function configure(?string $version = null, array $ext = [], array $profile = [], array $meta = [])\n    {\n        static::$jsonApiInformation = array_filter([\n            'version' => $version,\n            'ext' => $ext,\n            'profile' => $profile,\n            'meta' => $meta,\n        ]);\n    }\n\n    /**\n     * Get the resource's ID.\n     *\n     * @return string|null\n     */\n    public function toId(Request $request)\n    {\n        return null;\n    }\n\n    /**\n     * Get the resource's type.\n     *\n     * @return string|null\n     */\n    public function toType(Request $request)\n    {\n        return null;\n    }\n\n    /**\n     * Transform the resource into an array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Contracts\\Support\\Arrayable|\\JsonSerializable|array\n     */\n    #[\\Override]\n    public function toAttributes(Request $request)\n    {\n        if (property_exists($this, 'attributes')) {\n            return $this->attributes;\n        }\n\n        return $this->toArray($request);\n    }\n\n    /**\n     * Get the resource's relationships.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Contracts\\Support\\Arrayable|array\n     */\n    public function toRelationships(Request $request)\n    {\n        if (property_exists($this, 'relationships')) {\n            return $this->relationships;\n        }\n\n        return [];\n    }\n\n    /**\n     * Get the resource's links.\n     *\n     * @return array\n     */\n    public function toLinks(Request $request)\n    {\n        return $this->jsonApiLinks;\n    }\n\n    /**\n     * Get the resource's meta information.\n     *\n     * @return array\n     */\n    public function toMeta(Request $request)\n    {\n        return $this->jsonApiMeta;\n    }\n\n    /**\n     * Get any additional data that should be returned with the resource array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    #[\\Override]\n    public function with($request)\n    {\n        return array_filter([\n            'included' => $this->resolveIncludedResourceObjects($request)\n                ->uniqueStrict('_uniqueKey')\n                ->map(fn ($included) => Arr::except($included, ['_uniqueKey']))\n                ->values()\n                ->all(),\n            ...($implementation = static::$jsonApiInformation)\n                ? ['jsonapi' => $implementation]\n                : [],\n        ]);\n    }\n\n    /**\n     * Resolve the resource to an array.\n     *\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return array\n     */\n    #[\\Override]\n    public function resolve($request = null)\n    {\n        return [\n            'data' => $this->resolveResourceData($this->resolveJsonApiRequestFrom($request ?? $this->resolveRequestFromContainer())),\n        ];\n    }\n\n    /**\n     * Resolve the resource data to an array.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    #[\\Override]\n    public function resolveResourceData(Request $request)\n    {\n        return $this->resolveResourceObject($request);\n    }\n\n    /**\n     * Customize the outgoing response for the resource.\n     */\n    #[\\Override]\n    public function withResponse(Request $request, JsonResponse $response): void\n    {\n        $response->header('Content-Type', 'application/vnd.api+json');\n    }\n\n    /**\n     * Create an HTTP response that represents the object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    #[\\Override]\n    public function toResponse($request)\n    {\n        return parent::toResponse($this->resolveJsonApiRequestFrom($request));\n    }\n\n    /**\n     * Resolve the HTTP request instance from container.\n     *\n     * @return \\Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest\n     */\n    #[\\Override]\n    protected function resolveRequestFromContainer()\n    {\n        return $this->resolveJsonApiRequestFrom(parent::resolveRequestFromContainer());\n    }\n\n    /**\n     * Create a new resource collection instance.\n     *\n     * @param  mixed  $resource\n     * @return \\Illuminate\\Http\\Resources\\JsonApi\\AnonymousResourceCollection\n     */\n    #[\\Override]\n    protected static function newCollection($resource)\n    {\n        return new AnonymousResourceCollection($resource, static::class);\n    }\n\n    /**\n     * Set the string that should wrap the outer-most resource array.\n     *\n     * @param  string  $value\n     * @return never\n     *\n     * @throws \\RuntimeException\n     */\n    #[\\Override]\n    public static function wrap($value)\n    {\n        throw new BadMethodCallException(sprintf('Using %s() method is not allowed.', __METHOD__));\n    }\n\n    /**\n     * Disable wrapping of the outer-most resource array.\n     *\n     * @return never\n     */\n    #[\\Override]\n    public static function withoutWrapping()\n    {\n        throw new BadMethodCallException(sprintf('Using %s() method is not allowed.', __METHOD__));\n    }\n\n    /**\n     * Flush the resource's global state.\n     *\n     * @return void\n     */\n    #[\\Override]\n    public static function flushState()\n    {\n        parent::flushState();\n\n        static::$jsonApiInformation = [];\n        static::$maxRelationshipDepth = 5;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/JsonApi/RelationResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources\\JsonApi;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\n\n/**\n * @internal\n */\nclass RelationResolver\n{\n    /**\n     * The relation resolver.\n     *\n     * @var \\Closure(mixed):(\\Illuminate\\Database\\Eloquent\\Collection|\\Illuminate\\Database\\Eloquent\\Model|null)\n     */\n    public Closure $relationResolver;\n\n    /**\n     * The relation resource class.\n     *\n     * @var class-string<\\Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource>|null\n     */\n    public ?string $relationResourceClass = null;\n\n    /**\n     * Construct a new resource relationship resolver.\n     *\n     * @param  \\Closure(mixed):(\\Illuminate\\Database\\Eloquent\\Collection|\\Illuminate\\Database\\Eloquent\\Model|null)|class-string<\\Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource>|null  $resolver\n     */\n    public function __construct(public string $relationName, Closure|string|null $resolver = null)\n    {\n        $this->relationResolver = match (true) {\n            $resolver instanceof Closure => $resolver,\n            default => fn ($resource) => $resource->getRelation($this->relationName),\n        };\n\n        if (is_string($resolver) && class_exists($resolver)) {\n            $this->relationResourceClass = $resolver;\n        }\n    }\n\n    /**\n     * Resolve the relation for a resource.\n     */\n    public function handle(mixed $resource): Collection|Model|null\n    {\n        return value($this->relationResolver, $resource);\n    }\n\n    /**\n     * Get the resource class.\n     *\n     * @return class-string<\\Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource>|null\n     */\n    public function resourceClass(): ?string\n    {\n        return $this->relationResourceClass;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/MergeValue.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\nuse Illuminate\\Support\\Collection;\nuse JsonSerializable;\n\nclass MergeValue\n{\n    /**\n     * The data to be merged.\n     *\n     * @var array\n     */\n    public $data;\n\n    /**\n     * Create a new merge value instance.\n     *\n     * @param  \\Illuminate\\Support\\Collection|\\JsonSerializable|array  $data\n     */\n    public function __construct($data)\n    {\n        $this->data = match (true) {\n            $data instanceof Collection => $data->all(),\n            $data instanceof JsonSerializable => $data->jsonSerialize(),\n            default => $data,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/MissingValue.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\nclass MissingValue implements PotentiallyMissing\n{\n    /**\n     * Determine if the object should be considered \"missing\".\n     *\n     * @return bool\n     */\n    public function isMissing()\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Resources/PotentiallyMissing.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Resources;\n\ninterface PotentiallyMissing\n{\n    /**\n     * Determine if the object should be considered \"missing\".\n     *\n     * @return bool\n     */\n    public function isMissing();\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Response.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse ArrayObject;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Contracts\\Support\\Renderable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse JsonSerializable;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\nuse Symfony\\Component\\HttpFoundation\\ResponseHeaderBag;\n\nclass Response extends SymfonyResponse\n{\n    use ResponseTrait, Macroable {\n        Macroable::__call as macroCall;\n    }\n\n    /**\n     * Create a new HTTP response.\n     *\n     * @param  mixed  $content\n     * @param  int  $status\n     * @param  array  $headers\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($content = '', $status = 200, array $headers = [])\n    {\n        $this->headers = new ResponseHeaderBag($headers);\n\n        $this->setContent($content);\n        $this->setStatusCode($status);\n        $this->setProtocolVersion('1.0');\n    }\n\n    /**\n     * Get the response content.\n     */\n    #[\\Override]\n    public function getContent(): string|false\n    {\n        return transform(parent::getContent(), fn ($content) => $content, '');\n    }\n\n    /**\n     * Set the content on the response.\n     *\n     * @param  mixed  $content\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    #[\\Override]\n    public function setContent(mixed $content): static\n    {\n        $this->original = $content;\n\n        // If the content is \"JSONable\" we will set the appropriate header and convert\n        // the content to JSON. This is useful when returning something like models\n        // from routes that will be automatically transformed to their JSON form.\n        if ($this->shouldBeJson($content)) {\n            $this->header('Content-Type', 'application/json');\n\n            $content = $this->morphToJson($content);\n\n            if ($content === false) {\n                throw new InvalidArgumentException(json_last_error_msg());\n            }\n        }\n\n        // If this content implements the \"Renderable\" interface then we will call the\n        // render method on the object so we will avoid any \"__toString\" exceptions\n        // that might be thrown and have their errors obscured by PHP's handling.\n        elseif ($content instanceof Renderable) {\n            $content = $content->render();\n        }\n\n        parent::setContent($content);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given content should be turned into JSON.\n     *\n     * @param  mixed  $content\n     * @return bool\n     */\n    protected function shouldBeJson($content)\n    {\n        return $content instanceof Arrayable ||\n               $content instanceof Jsonable ||\n               $content instanceof ArrayObject ||\n               $content instanceof JsonSerializable ||\n               is_array($content);\n    }\n\n    /**\n     * Morph the given content into JSON.\n     *\n     * @param  mixed  $content\n     * @return string|false\n     */\n    protected function morphToJson($content)\n    {\n        if ($content instanceof Jsonable) {\n            return $content->toJson();\n        } elseif ($content instanceof Arrayable) {\n            return json_encode($content->toArray());\n        }\n\n        return json_encode($content);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/ResponseTrait.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Symfony\\Component\\HttpFoundation\\HeaderBag;\nuse Throwable;\n\ntrait ResponseTrait\n{\n    /**\n     * The original content of the response.\n     *\n     * @var mixed\n     */\n    public $original;\n\n    /**\n     * The exception that triggered the error response (if applicable).\n     *\n     * @var \\Throwable|null\n     */\n    public $exception;\n\n    /**\n     * Get the status code for the response.\n     *\n     * @return int\n     */\n    public function status()\n    {\n        return $this->getStatusCode();\n    }\n\n    /**\n     * Get the status text for the response.\n     *\n     * @return string\n     */\n    public function statusText()\n    {\n        return $this->statusText;\n    }\n\n    /**\n     * Get the content of the response.\n     *\n     * @return string\n     */\n    public function content()\n    {\n        return $this->getContent();\n    }\n\n    /**\n     * Get the original response content.\n     *\n     * @return mixed\n     */\n    public function getOriginalContent()\n    {\n        $original = $this->original;\n\n        return $original instanceof self ? $original->{__FUNCTION__}() : $original;\n    }\n\n    /**\n     * Set a header on the Response.\n     *\n     * @param  string  $key\n     * @param  array|string  $values\n     * @param  bool  $replace\n     * @return $this\n     */\n    public function header($key, $values, $replace = true)\n    {\n        $this->headers->set($key, $values, $replace);\n\n        return $this;\n    }\n\n    /**\n     * Add an array of headers to the response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\HeaderBag|array  $headers\n     * @return $this\n     */\n    public function withHeaders($headers)\n    {\n        if ($headers instanceof HeaderBag) {\n            $headers = $headers->all();\n        }\n\n        foreach ($headers as $key => $value) {\n            $this->headers->set($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Remove a header(s) from the response.\n     *\n     * @param  array|string  $key\n     * @return $this\n     */\n    public function withoutHeader($key)\n    {\n        foreach ((array) $key as $header) {\n            $this->headers->remove($header);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a cookie to the response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Cookie|mixed  $cookie\n     * @return $this\n     */\n    public function cookie($cookie)\n    {\n        return $this->withCookie(...func_get_args());\n    }\n\n    /**\n     * Add a cookie to the response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Cookie|mixed  $cookie\n     * @return $this\n     */\n    public function withCookie($cookie)\n    {\n        if (is_string($cookie) && function_exists('cookie')) {\n            $cookie = cookie(...func_get_args());\n        }\n\n        $this->headers->setCookie($cookie);\n\n        return $this;\n    }\n\n    /**\n     * Expire a cookie when sending the response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Cookie|mixed  $cookie\n     * @param  string|null  $path\n     * @param  string|null  $domain\n     * @return $this\n     */\n    public function withoutCookie($cookie, $path = null, $domain = null)\n    {\n        if (is_string($cookie) && function_exists('cookie')) {\n            $cookie = cookie($cookie, null, -2628000, $path, $domain);\n        }\n\n        $this->headers->setCookie($cookie);\n\n        return $this;\n    }\n\n    /**\n     * Get the callback of the response.\n     *\n     * @return string|null\n     */\n    public function getCallback()\n    {\n        return $this->callback ?? null;\n    }\n\n    /**\n     * Set the exception to attach to the response.\n     *\n     * @param  \\Throwable  $e\n     * @return $this\n     */\n    public function withException(Throwable $e)\n    {\n        $this->exception = $e;\n\n        return $this;\n    }\n\n    /**\n     * Throws the response in a HttpResponseException instance.\n     *\n     * @return never\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\HttpResponseException\n     */\n    public function throwResponse()\n    {\n        throw new HttpResponseException($this);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/StreamedEvent.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nclass StreamedEvent\n{\n    /**\n     * The name of the event.\n     */\n    public string $event;\n\n    /**\n     * The data of the stream.\n     */\n    public mixed $data;\n\n    /**\n     * Create a new streamed event instance.\n     */\n    public function __construct(string $event, mixed $data)\n    {\n        $this->event = $event;\n        $this->data = $data;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Testing/File.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Testing;\n\nuse Illuminate\\Http\\UploadedFile;\n\nclass File extends UploadedFile\n{\n    /**\n     * The name of the file.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The temporary file resource.\n     *\n     * @var resource\n     */\n    public $tempFile;\n\n    /**\n     * The \"size\" to report.\n     *\n     * @var int\n     */\n    public $sizeToReport;\n\n    /**\n     * The MIME type to report.\n     *\n     * @var string|null\n     */\n    public $mimeTypeToReport;\n\n    /**\n     * Create a new file instance.\n     *\n     * @param  string  $name\n     * @param  resource  $tempFile\n     */\n    public function __construct($name, $tempFile)\n    {\n        $this->name = $name;\n        $this->tempFile = $tempFile;\n\n        parent::__construct(\n            $this->tempFilePath(), $name, $this->getMimeType(),\n            null, true\n        );\n    }\n\n    /**\n     * Create a new fake file.\n     *\n     * @param  string  $name\n     * @param  string|int  $kilobytes\n     * @return \\Illuminate\\Http\\Testing\\File\n     */\n    public static function create($name, $kilobytes = 0)\n    {\n        return (new FileFactory)->create($name, $kilobytes);\n    }\n\n    /**\n     * Create a new fake file with content.\n     *\n     * @param  string  $name\n     * @param  string  $content\n     * @return \\Illuminate\\Http\\Testing\\File\n     */\n    public static function createWithContent($name, $content)\n    {\n        return (new FileFactory)->createWithContent($name, $content);\n    }\n\n    /**\n     * Create a new fake image.\n     *\n     * @param  string  $name\n     * @param  int  $width\n     * @param  int  $height\n     * @return \\Illuminate\\Http\\Testing\\File\n     */\n    public static function image($name, $width = 10, $height = 10)\n    {\n        return (new FileFactory)->image($name, $width, $height);\n    }\n\n    /**\n     * Set the \"size\" of the file in kilobytes.\n     *\n     * @param  int  $kilobytes\n     * @return $this\n     */\n    public function size($kilobytes)\n    {\n        $this->sizeToReport = $kilobytes * 1024;\n\n        return $this;\n    }\n\n    /**\n     * Get the size of the file.\n     *\n     * @return int\n     */\n    public function getSize(): int\n    {\n        return $this->sizeToReport ?: parent::getSize();\n    }\n\n    /**\n     * Set the MIME type for the file.\n     *\n     * @param  string  $mimeType\n     * @return $this\n     */\n    public function mimeType($mimeType)\n    {\n        $this->mimeTypeToReport = $mimeType;\n\n        return $this;\n    }\n\n    /**\n     * Get the MIME type of the file.\n     *\n     * @return string\n     */\n    public function getMimeType(): string\n    {\n        return $this->mimeTypeToReport ?: MimeType::from($this->name);\n    }\n\n    /**\n     * Get the path to the temporary file.\n     *\n     * @return string\n     */\n    protected function tempFilePath()\n    {\n        return stream_get_meta_data($this->tempFile)['uri'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Testing/FileFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Testing;\n\nuse LogicException;\n\nclass FileFactory\n{\n    /**\n     * Create a new fake file.\n     *\n     * @param  string  $name\n     * @param  string|int  $kilobytes\n     * @param  string|null  $mimeType\n     * @return \\Illuminate\\Http\\Testing\\File\n     */\n    public function create($name, $kilobytes = 0, $mimeType = null)\n    {\n        if (is_string($kilobytes)) {\n            return $this->createWithContent($name, $kilobytes);\n        }\n\n        return tap(new File($name, tmpfile()), function ($file) use ($kilobytes, $mimeType) {\n            $file->sizeToReport = $kilobytes * 1024;\n            $file->mimeTypeToReport = $mimeType;\n        });\n    }\n\n    /**\n     * Create a new fake file with content.\n     *\n     * @param  string  $name\n     * @param  string  $content\n     * @return \\Illuminate\\Http\\Testing\\File\n     */\n    public function createWithContent($name, $content)\n    {\n        $tmpfile = tmpfile();\n\n        fwrite($tmpfile, $content);\n\n        return tap(new File($name, $tmpfile), function ($file) use ($tmpfile) {\n            $file->sizeToReport = fstat($tmpfile)['size'];\n        });\n    }\n\n    /**\n     * Create a new fake image.\n     *\n     * @param  string  $name\n     * @param  int  $width\n     * @param  int  $height\n     * @return \\Illuminate\\Http\\Testing\\File\n     *\n     * @throws \\LogicException\n     */\n    public function image($name, $width = 10, $height = 10)\n    {\n        return new File($name, $this->generateImage(\n            $width, $height, pathinfo($name, PATHINFO_EXTENSION)\n        ));\n    }\n\n    /**\n     * Generate a dummy image of the given width and height.\n     *\n     * @param  int  $width\n     * @param  int  $height\n     * @param  string  $extension\n     * @return resource\n     *\n     * @throws \\LogicException\n     */\n    protected function generateImage($width, $height, $extension)\n    {\n        if (! function_exists('imagecreatetruecolor')) {\n            throw new LogicException('GD extension is not installed.');\n        }\n\n        return tap(tmpfile(), function ($temp) use ($width, $height, $extension) {\n            ob_start();\n\n            $extension = in_array($extension, ['jpeg', 'png', 'gif', 'webp', 'wbmp', 'bmp'])\n                ? strtolower($extension)\n                : 'jpeg';\n\n            $image = imagecreatetruecolor($width, $height);\n\n            if (! function_exists($functionName = \"image{$extension}\")) {\n                ob_get_clean();\n\n                throw new LogicException(\"{$functionName} function is not defined and image cannot be generated.\");\n            }\n\n            call_user_func($functionName, $image);\n\n            fwrite($temp, ob_get_clean());\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/Testing/MimeType.php",
    "content": "<?php\n\nnamespace Illuminate\\Http\\Testing;\n\nuse Illuminate\\Support\\Arr;\nuse Symfony\\Component\\Mime\\MimeTypes;\n\nclass MimeType\n{\n    /**\n     * The MIME types instance.\n     *\n     * @var \\Symfony\\Component\\Mime\\MimeTypes|null\n     */\n    private static $mime;\n\n    /**\n     * Get the MIME types instance.\n     *\n     * @return \\Symfony\\Component\\Mime\\MimeTypesInterface\n     */\n    public static function getMimeTypes()\n    {\n        if (self::$mime === null) {\n            self::$mime = new MimeTypes;\n        }\n\n        return self::$mime;\n    }\n\n    /**\n     * Get the MIME type for a file based on the file's extension.\n     *\n     * @param  string  $filename\n     * @return string\n     */\n    public static function from($filename)\n    {\n        $extension = pathinfo($filename, PATHINFO_EXTENSION);\n\n        return self::get($extension);\n    }\n\n    /**\n     * Get the MIME type for a given extension or return all MIME types.\n     *\n     * @param  string  $extension\n     * @return string\n     */\n    public static function get($extension)\n    {\n        return Arr::first(self::getMimeTypes()->getMimeTypes($extension)) ?? 'application/octet-stream';\n    }\n\n    /**\n     * Search for the extension of a given MIME type.\n     *\n     * @param  string  $mimeType\n     * @return string|null\n     */\n    public static function search($mimeType)\n    {\n        return Arr::first(self::getMimeTypes()->getExtensions($mimeType));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/UploadedFile.php",
    "content": "<?php\n\nnamespace Illuminate\\Http;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Filesystem\\Factory as FilesystemFactory;\nuse Illuminate\\Contracts\\Filesystem\\FileNotFoundException;\nuse Illuminate\\Http\\Testing\\FileFactory;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile as SymfonyUploadedFile;\n\nclass UploadedFile extends SymfonyUploadedFile\n{\n    use FileHelpers, Macroable;\n\n    /**\n     * Begin creating a new file fake.\n     *\n     * @return \\Illuminate\\Http\\Testing\\FileFactory\n     */\n    public static function fake()\n    {\n        return new FileFactory;\n    }\n\n    /**\n     * Store the uploaded file on a filesystem disk.\n     *\n     * @param  string  $path\n     * @param  array|string  $options\n     * @return string|false\n     */\n    public function store($path = '', $options = [])\n    {\n        return $this->storeAs($path, $this->hashName(), $this->parseOptions($options));\n    }\n\n    /**\n     * Store the uploaded file on a filesystem disk with public visibility.\n     *\n     * @param  string  $path\n     * @param  array|string  $options\n     * @return string|false\n     */\n    public function storePublicly($path = '', $options = [])\n    {\n        $options = $this->parseOptions($options);\n\n        $options['visibility'] = 'public';\n\n        return $this->storeAs($path, $this->hashName(), $options);\n    }\n\n    /**\n     * Store the uploaded file on a filesystem disk with public visibility.\n     *\n     * @param  string  $path\n     * @param  array|string|null  $name\n     * @param  array|string  $options\n     * @return string|false\n     */\n    public function storePubliclyAs($path, $name = null, $options = [])\n    {\n        if (is_null($name) || is_array($name)) {\n            [$path, $name, $options] = ['', $path, $name ?? []];\n        }\n\n        $options = $this->parseOptions($options);\n\n        $options['visibility'] = 'public';\n\n        return $this->storeAs($path, $name, $options);\n    }\n\n    /**\n     * Store the uploaded file on a filesystem disk.\n     *\n     * @param  string  $path\n     * @param  array|string|null  $name\n     * @param  array|string  $options\n     * @return string|false\n     */\n    public function storeAs($path, $name = null, $options = [])\n    {\n        if (is_null($name) || is_array($name)) {\n            [$path, $name, $options] = ['', $path, $name ?? []];\n        }\n\n        $options = $this->parseOptions($options);\n\n        $disk = Arr::pull($options, 'disk');\n\n        return Container::getInstance()->make(FilesystemFactory::class)->disk($disk)->putFileAs(\n            $path, $this, $name, $options\n        );\n    }\n\n    /**\n     * Get the contents of the uploaded file.\n     *\n     * @return false|string\n     *\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public function get()\n    {\n        if (! $this->isValid()) {\n            throw new FileNotFoundException(\"File does not exist at path {$this->getPathname()}.\");\n        }\n\n        return file_get_contents($this->getPathname());\n    }\n\n    /**\n     * Get the file's extension supplied by the client.\n     *\n     * @return string\n     */\n    public function clientExtension()\n    {\n        return $this->guessClientExtension();\n    }\n\n    /**\n     * Create a new file instance from a base instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\File\\UploadedFile  $file\n     * @param  bool  $test\n     * @return static\n     */\n    public static function createFromBase(SymfonyUploadedFile $file, $test = false)\n    {\n        return $file instanceof static ? $file : new static(\n            $file->getPathname(),\n            $file->getClientOriginalPath(),\n            $file->getClientMimeType(),\n            $file->getError(),\n            $test\n        );\n    }\n\n    /**\n     * Parse and format the given options.\n     *\n     * @param  array|string  $options\n     * @return array\n     */\n    protected function parseOptions($options)\n    {\n        if (is_string($options)) {\n            $options = ['disk' => $options];\n        }\n\n        return $options;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Http/composer.json",
    "content": "{\n    \"name\": \"illuminate/http\",\n    \"description\": \"The Illuminate Http package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-filter\": \"*\",\n        \"fruitcake/php-cors\": \"^1.3\",\n        \"guzzlehttp/guzzle\": \"^7.8.2\",\n        \"guzzlehttp/uri-template\": \"^1.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/session\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-kernel\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/mime\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/polyfill-php85\": \"^1.33\"\n    },\n    \"suggest\": {\n        \"ext-gd\": \"Required to use Illuminate\\\\Http\\\\Testing\\\\FileFactory::image().\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Http\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/JsonSchema.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema;\n\nuse Closure;\nuse Illuminate\\JsonSchema\\Types\\Type;\n\n/**\n * @method static Types\\ObjectType object(Closure|array<string, Types\\Type> $properties = [])\n * @method static Types\\IntegerType integer()\n * @method static Types\\NumberType number()\n * @method static Types\\StringType string()\n * @method static Types\\BooleanType boolean()\n * @method static Types\\ArrayType array()\n */\nclass JsonSchema\n{\n    /**\n     * Dynamically pass static methods to the schema instance.\n     */\n    public static function __callStatic(string $name, mixed $arguments): Type\n    {\n        return (new JsonSchemaTypeFactory)->$name(...$arguments);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/JsonSchemaTypeFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema;\n\nuse Closure;\nuse Illuminate\\Contracts\\JsonSchema\\JsonSchema as JsonSchemaContract;\n\nclass JsonSchemaTypeFactory extends JsonSchema implements JsonSchemaContract\n{\n    /**\n     * Create a new object schema instance.\n     *\n     * @param  (Closure(JsonSchemaTypeFactory): array<string, Types\\Type>)|array<string, Types\\Type>  $properties\n     */\n    public function object(Closure|array $properties = []): Types\\ObjectType\n    {\n        if ($properties instanceof Closure) {\n            $properties = $properties($this);\n        }\n\n        return new Types\\ObjectType($properties);\n    }\n\n    /**\n     * Create a new array property instance.\n     */\n    public function array(): Types\\ArrayType\n    {\n        return new Types\\ArrayType;\n    }\n\n    /**\n     * Create a new string property instance.\n     */\n    public function string(): Types\\StringType\n    {\n        return new Types\\StringType;\n    }\n\n    /**\n     * Create a new integer property instance.\n     */\n    public function integer(): Types\\IntegerType\n    {\n        return new Types\\IntegerType;\n    }\n\n    /**\n     * Create a new number property instance.\n     */\n    public function number(): Types\\NumberType\n    {\n        return new Types\\NumberType;\n    }\n\n    /**\n     * Create a new boolean property instance.\n     */\n    public function boolean(): Types\\BooleanType\n    {\n        return new Types\\BooleanType;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Serializer.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema;\n\nuse RuntimeException;\n\nclass Serializer\n{\n    /**\n     * The properties to ignore when serializing.\n     *\n     * @var array<int, string>\n     */\n    protected static array $ignore = ['required', 'nullable'];\n\n    /**\n     * Serialize the given property to an array.\n     *\n     * @return array<string, mixed>\n     *\n     * @throws \\RuntimeException\n     */\n    public static function serialize(Types\\Type $type): array\n    {\n        /** @var array<string, mixed> $attributes */\n        $attributes = (fn () => get_object_vars($type))->call($type);\n\n        $attributes['type'] = match (get_class($type)) {\n            Types\\ArrayType::class => 'array',\n            Types\\BooleanType::class => 'boolean',\n            Types\\IntegerType::class => 'integer',\n            Types\\NumberType::class => 'number',\n            Types\\ObjectType::class => 'object',\n            Types\\StringType::class => 'string',\n            default => throw new RuntimeException('Unsupported ['.get_class($type).'] type.'),\n        };\n\n        $nullable = static::isNullable($type);\n\n        if ($nullable) {\n            $attributes['type'] = [$attributes['type'], 'null'];\n        }\n\n        $attributes = array_filter($attributes, static function (mixed $value, string $key) {\n            if (in_array($key, static::$ignore, true)) {\n                return false;\n            }\n\n            return $value !== null;\n        }, ARRAY_FILTER_USE_BOTH);\n\n        if ($type instanceof Types\\ObjectType) {\n            if (count($attributes['properties']) === 0) {\n                unset($attributes['properties']);\n            } else {\n                $required = array_keys(array_filter(\n                    $attributes['properties'],\n                    static fn (Types\\Type $property) => static::isRequired($property),\n                ));\n\n                if (count($required) > 0) {\n                    $attributes['required'] = $required;\n                }\n\n                $attributes['properties'] = array_map(\n                    static fn (Types\\Type $property) => static::serialize($property),\n                    $attributes['properties'],\n                );\n            }\n        }\n\n        if ($type instanceof Types\\ArrayType) {\n            if (isset($attributes['items']) && $attributes['items'] instanceof Types\\Type) {\n                $attributes['items'] = static::serialize($attributes['items']);\n            }\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Determine if the given type is required.\n     */\n    protected static function isRequired(Types\\Type $type): bool\n    {\n        $attributes = (fn () => get_object_vars($type))->call($type);\n\n        return isset($attributes['required']) && $attributes['required'] === true;\n    }\n\n    /**\n     * Determine if the given type is nullable.\n     */\n    protected static function isNullable(Types\\Type $type): bool\n    {\n        $attributes = (fn () => get_object_vars($type))->call($type);\n\n        return isset($attributes['nullable']) && $attributes['nullable'] === true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/ArrayType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass ArrayType extends Type\n{\n    /**\n     * The minimum number of items (inclusive).\n     */\n    protected ?int $minItems = null;\n\n    /**\n     * The maximum number of items (inclusive).\n     */\n    protected ?int $maxItems = null;\n\n    /**\n     * The schema of the items contained in the array.\n     */\n    protected ?Type $items = null;\n\n    /**\n     * Whether the array items must be unique.\n     */\n    protected ?bool $uniqueItems = null;\n\n    /**\n     * Set the minimum number of items (inclusive).\n     */\n    public function min(int $value): static\n    {\n        $this->minItems = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum number of items (inclusive).\n     */\n    public function max(int $value): static\n    {\n        $this->maxItems = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the schema for array items.\n     */\n    public function items(Type $type): static\n    {\n        $this->items = $type;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the array items must be unique.\n     */\n    public function unique(bool $unique = true): static\n    {\n        if ($unique) {\n            $this->uniqueItems = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the type's default value.\n     *\n     * @param  array<int, mixed>  $value\n     */\n    public function default(array $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/BooleanType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass BooleanType extends Type\n{\n    /**\n     * Set the type's default value.\n     */\n    public function default(bool $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/IntegerType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass IntegerType extends Type\n{\n    /**\n     * The minimum value (inclusive).\n     */\n    protected ?int $minimum = null;\n\n    /**\n     * The maximum value (inclusive).\n     */\n    protected ?int $maximum = null;\n\n    /**\n     * The number the value must be a multiple of.\n     */\n    protected ?int $multipleOf = null;\n\n    /**\n     * Set the minimum value (inclusive).\n     */\n    public function min(int $value): static\n    {\n        $this->minimum = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum value (inclusive).\n     */\n    public function max(int $value): static\n    {\n        $this->maximum = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the number the value must be a multiple of.\n     */\n    public function multipleOf(int $value): static\n    {\n        $this->multipleOf = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the type's default value.\n     */\n    public function default(int $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/NumberType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass NumberType extends Type\n{\n    /**\n     * The minimum value (inclusive).\n     */\n    protected int|float|null $minimum = null;\n\n    /**\n     * The maximum value (inclusive).\n     */\n    protected int|float|null $maximum = null;\n\n    /**\n     * The number the value must be a multiple of.\n     */\n    protected int|float|null $multipleOf = null;\n\n    /**\n     * Set the minimum value (inclusive).\n     */\n    public function min(int|float $value): static\n    {\n        $this->minimum = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum value (inclusive).\n     */\n    public function max(int|float $value): static\n    {\n        $this->maximum = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the number the value must be a multiple of.\n     */\n    public function multipleOf(int|float $value): static\n    {\n        $this->multipleOf = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the type's default value.\n     */\n    public function default(int|float $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/ObjectType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass ObjectType extends Type\n{\n    /**\n     * Whether additional properties are allowed.\n     */\n    protected ?bool $additionalProperties = null;\n\n    /**\n     * Create a new object type instance.\n     *\n     * @param  array<string, Type>  $properties\n     */\n    public function __construct(protected array $properties = [])\n    {\n        //\n    }\n\n    /**\n     * Disallow additional properties.\n     */\n    public function withoutAdditionalProperties(): static\n    {\n        $this->additionalProperties = false;\n\n        return $this;\n    }\n\n    /**\n     * Set the type's default value.\n     *\n     * @param  array<string, mixed>  $value\n     */\n    public function default(array $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/StringType.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nclass StringType extends Type\n{\n    /**\n     * The minimum length (inclusive).\n     */\n    protected ?int $minLength = null;\n\n    /**\n     * The maximum length (inclusive).\n     */\n    protected ?int $maxLength = null;\n\n    /**\n     * A regular expression the value must match.\n     */\n    protected ?string $pattern = null;\n\n    /**\n     * The format of the string.\n     */\n    protected ?string $format = null;\n\n    /**\n     * Set the minimum length (inclusive).\n     */\n    public function min(int $value): static\n    {\n        $this->minLength = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum length (inclusive).\n     */\n    public function max(int $value): static\n    {\n        $this->maxLength = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the pattern the value must satisfy.\n     */\n    public function pattern(string $value): static\n    {\n        $this->pattern = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the format of the string.\n     *\n     * {@link https://json-schema.org/understanding-json-schema/reference/type#built-in-formats}\n     */\n    public function format(string $value): static\n    {\n        $this->format = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the type's default value.\n     */\n    public function default(string $value): static\n    {\n        $this->default = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/Types/Type.php",
    "content": "<?php\n\nnamespace Illuminate\\JsonSchema\\Types;\n\nuse BackedEnum;\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse Illuminate\\JsonSchema\\Serializer;\nuse InvalidArgumentException;\n\nabstract class Type extends JsonSchema\n{\n    /**\n     * Whether the type is required.\n     */\n    protected ?bool $required = null;\n\n    /**\n     * The type's title.\n     */\n    protected ?string $title = null;\n\n    /**\n     * The type's description.\n     */\n    protected ?string $description = null;\n\n    /**\n     * The default value for the type.\n     */\n    protected mixed $default = null;\n\n    /**\n     * The set of allowed values for the type.\n     *\n     * @var array<int, mixed>|null\n     */\n    protected ?array $enum = null;\n\n    /**\n     * Indicates if the type is nullable.\n     */\n    protected ?bool $nullable = null;\n\n    /**\n     * Indicate that the type is required.\n     */\n    public function required(bool $required = true): static\n    {\n        if ($required) {\n            $this->required = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the type is optional.\n     */\n    public function nullable(bool $nullable = true): static\n    {\n        if ($nullable) {\n            $this->nullable = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the type's title.\n     */\n    public function title(string $value): static\n    {\n        $this->title = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the type's description.\n     */\n    public function description(string $value): static\n    {\n        $this->description = $value;\n\n        return $this;\n    }\n\n    /**\n     * Restrict the value to one of the provided enumerated values.\n     *\n     * @param  class-string<\\BackedEnum>|array<int, mixed>  $values\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function enum(array|string $values): static\n    {\n        if (is_string($values)) {\n            if (! is_subclass_of($values, BackedEnum::class)) {\n                throw new InvalidArgumentException('The provided class must be a BackedEnum.');\n            }\n\n            $values = array_column($values::cases(), 'value');\n        }\n\n        // Keep order and allow complex values (arrays / objects) without forcing uniqueness...\n        $this->enum = array_values($values);\n\n        return $this;\n    }\n\n    /**\n     * Convert the type to an array.\n     *\n     * @return array<string, mixed>\n     */\n    public function toArray(): array\n    {\n        return Serializer::serialize($this);\n    }\n\n    /**\n     * Convert the type to its string representation.\n     */\n    public function toString(): string\n    {\n        return json_encode($this->toArray(), JSON_PRETTY_PRINT) ?: '';\n    }\n\n    /**\n     * Convert the type to its string representation.\n     */\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/JsonSchema/composer.json",
    "content": "{\n    \"name\": \"illuminate/json-schema\",\n    \"description\": \"The Illuminate Json Schema package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/contracts\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\JsonSchema\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Log/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Log/Context/ContextLogProcessor.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Context;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Log\\ContextLogProcessor as ContextLogProcessorContract;\nuse Illuminate\\Log\\Context\\Repository as ContextRepository;\nuse Monolog\\LogRecord;\n\nclass ContextLogProcessor implements ContextLogProcessorContract\n{\n    /**\n     * Add contextual data to the log's \"extra\" parameter.\n     *\n     * @param  \\Monolog\\LogRecord  $record\n     * @return \\Monolog\\LogRecord\n     */\n    public function __invoke(LogRecord $record): LogRecord\n    {\n        $app = Container::getInstance();\n\n        if (! $app->bound(ContextRepository::class)) {\n            return $record;\n        }\n\n        return $record->with(extra: [\n            ...$record->extra,\n            ...$app->get(ContextRepository::class)->all(),\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Context/ContextServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Context;\n\nuse Illuminate\\Contracts\\Log\\ContextLogProcessor as ContextLogProcessorContract;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Illuminate\\Queue\\Queue;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Facades\\Context;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ContextServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->scoped(Repository::class);\n\n        if ($this->app->runningInConsole()) {\n            $this->app->resolving(Repository::class, function (Repository $repository) {\n                $context = Env::get('__LARAVEL_CONTEXT');\n\n                if ($context && $context = json_decode($context, associative: true)) {\n                    $repository->hydrate($context);\n                }\n            });\n        }\n\n        $this->app->bind(ContextLogProcessorContract::class, fn () => new ContextLogProcessor());\n    }\n\n    /**\n     * Boot the application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        Queue::createPayloadUsing(function ($connection, $queue, $payload) {\n            /** @phpstan-ignore staticMethod.notFound */\n            $context = Context::dehydrate();\n\n            return $context === null ? $payload : [\n                ...$payload,\n                'illuminate:log:context' => $context,\n            ];\n        });\n\n        $this->app['events']->listen(function (JobProcessing $event) {\n            /** @phpstan-ignore staticMethod.notFound */\n            Context::hydrate($event->job->payload()['illuminate:log:context'] ?? null);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Context/Events/ContextDehydrating.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Context\\Events;\n\nclass ContextDehydrating\n{\n    /**\n     * The context instance.\n     *\n     * @var \\Illuminate\\Log\\Context\\Repository\n     */\n    public $context;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Log\\Context\\Repository  $context\n     */\n    public function __construct($context)\n    {\n        $this->context = $context;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Context/Events/ContextHydrated.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Context\\Events;\n\nclass ContextHydrated\n{\n    /**\n     * The context instance.\n     *\n     * @var \\Illuminate\\Log\\Context\\Repository\n     */\n    public $context;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Log\\Context\\Repository  $context\n     */\n    public function __construct($context)\n    {\n        $this->context = $context;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Context/Repository.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Context;\n\nuse __PHP_Incomplete_Class;\nuse Closure;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Log\\Context\\Events\\ContextDehydrating as Dehydrating;\nuse Illuminate\\Log\\Context\\Events\\ContextHydrated as Hydrated;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\nuse Throwable;\n\nclass Repository\n{\n    use Conditionable, Macroable, SerializesModels;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The contextual data.\n     *\n     * @var array<string, mixed>\n     */\n    protected $data = [];\n\n    /**\n     * The hidden contextual data.\n     *\n     * @var array<string, mixed>\n     */\n    protected $hidden = [];\n\n    /**\n     * The callback that should handle unserialize exceptions.\n     *\n     * @var callable|null\n     */\n    protected static $handleUnserializeExceptionsUsing;\n\n    /**\n     * Create a new Context instance.\n     */\n    public function __construct(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Determine if the given key exists.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        return array_key_exists($key, $this->data);\n    }\n\n    /**\n     * Determine if the given key is missing.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function missing($key)\n    {\n        return ! $this->has($key);\n    }\n\n    /**\n     * Determine if the given key exists within the hidden context data.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasHidden($key)\n    {\n        return array_key_exists($key, $this->hidden);\n    }\n\n    /**\n     * Determine if the given key is missing within the hidden context data.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function missingHidden($key)\n    {\n        return ! $this->hasHidden($key);\n    }\n\n    /**\n     * Retrieve all the context data.\n     *\n     * @return array<string, mixed>\n     */\n    public function all()\n    {\n        return $this->data;\n    }\n\n    /**\n     * Retrieve all the hidden context data.\n     *\n     * @return array<string, mixed>\n     */\n    public function allHidden()\n    {\n        return $this->hidden;\n    }\n\n    /**\n     * Retrieve the given key's value.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null)\n    {\n        return $this->data[$key] ?? value($default);\n    }\n\n    /**\n     * Retrieve the given key's hidden value.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function getHidden($key, $default = null)\n    {\n        return $this->hidden[$key] ?? value($default);\n    }\n\n    /**\n     * Retrieve the given key's value and then forget it.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function pull($key, $default = null)\n    {\n        return tap($this->get($key, $default), function () use ($key) {\n            $this->forget($key);\n        });\n    }\n\n    /**\n     * Retrieve the given key's hidden value and then forget it.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function pullHidden($key, $default = null)\n    {\n        return tap($this->getHidden($key, $default), function () use ($key) {\n            $this->forgetHidden($key);\n        });\n    }\n\n    /**\n     * Retrieve only the values of the given keys.\n     *\n     * @param  array<int, string>  $keys\n     * @return array<string, mixed>\n     */\n    public function only($keys)\n    {\n        return array_intersect_key($this->data, array_flip($keys));\n    }\n\n    /**\n     * Retrieve only the hidden values of the given keys.\n     *\n     * @param  array<int, string>  $keys\n     * @return array<string, mixed>\n     */\n    public function onlyHidden($keys)\n    {\n        return array_intersect_key($this->hidden, array_flip($keys));\n    }\n\n    /**\n     * Retrieve all values except those with the given keys.\n     *\n     * @param  array<int, string>  $keys\n     * @return array<string, mixed>\n     */\n    public function except($keys)\n    {\n        return array_diff_key($this->data, array_flip($keys));\n    }\n\n    /**\n     * Retrieve all hidden values except those with the given keys.\n     *\n     * @param  array<int, string>  $keys\n     * @return array<string, mixed>\n     */\n    public function exceptHidden($keys)\n    {\n        return array_diff_key($this->hidden, array_flip($keys));\n    }\n\n    /**\n     * Add a context value.\n     *\n     * @param  string|array<string, mixed>  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function add($key, $value = null)\n    {\n        $this->data = array_merge(\n            $this->data,\n            is_array($key) ? $key : [$key => $value]\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add a hidden context value.\n     *\n     * @param  string|array<string, mixed>  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function addHidden($key, #[\\SensitiveParameter] $value = null)\n    {\n        $this->hidden = array_merge(\n            $this->hidden,\n            is_array($key) ? $key : [$key => $value]\n        );\n\n        return $this;\n    }\n\n    /**\n     * Add a context value if it does not exist yet, and return the value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function remember($key, $value)\n    {\n        if ($this->has($key)) {\n            return $this->get($key);\n        }\n\n        return tap(value($value), function ($value) use ($key) {\n            $this->add($key, $value);\n        });\n    }\n\n    /**\n     * Add a hidden context value if it does not exist yet, and return the value.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function rememberHidden($key, #[\\SensitiveParameter] $value)\n    {\n        if ($this->hasHidden($key)) {\n            return $this->getHidden($key);\n        }\n\n        return tap(value($value), function ($value) use ($key) {\n            $this->addHidden($key, $value);\n        });\n    }\n\n    /**\n     * Forget the given context key.\n     *\n     * @param  string|array<int, string>  $key\n     * @return $this\n     */\n    public function forget($key)\n    {\n        foreach ((array) $key as $k) {\n            unset($this->data[$k]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Forget the given hidden context key.\n     *\n     * @param  string|array<int, string>  $key\n     * @return $this\n     */\n    public function forgetHidden($key)\n    {\n        foreach ((array) $key as $k) {\n            unset($this->hidden[$k]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a context value if it does not exist yet.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function addIf($key, $value)\n    {\n        if (! $this->has($key)) {\n            $this->add($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a hidden context value if it does not exist yet.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function addHiddenIf($key, #[\\SensitiveParameter] $value)\n    {\n        if (! $this->hasHidden($key)) {\n            $this->addHidden($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Push the given values onto the key's stack.\n     *\n     * @param  string  $key\n     * @param  mixed  ...$values\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function push($key, ...$values)\n    {\n        if (! $this->isStackable($key)) {\n            throw new RuntimeException(\"Unable to push value onto context stack for key [{$key}].\");\n        }\n\n        $this->data[$key] = [\n            ...$this->data[$key] ?? [],\n            ...$values,\n        ];\n\n        return $this;\n    }\n\n    /**\n     * Pop the latest value from the key's stack.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public function pop($key)\n    {\n        if (! $this->isStackable($key) || ! count($this->data[$key])) {\n            throw new RuntimeException(\"Unable to pop value from context stack for key [{$key}].\");\n        }\n\n        return array_pop($this->data[$key]);\n    }\n\n    /**\n     * Push the given hidden values onto the key's stack.\n     *\n     * @param  string  $key\n     * @param  mixed  ...$values\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function pushHidden($key, ...$values)\n    {\n        if (! $this->isHiddenStackable($key)) {\n            throw new RuntimeException(\"Unable to push value onto hidden context stack for key [{$key}].\");\n        }\n\n        $this->hidden[$key] = [\n            ...$this->hidden[$key] ?? [],\n            ...$values,\n        ];\n\n        return $this;\n    }\n\n    /**\n     * Pop the latest hidden value from the key's stack.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public function popHidden($key)\n    {\n        if (! $this->isHiddenStackable($key) || ! count($this->hidden[$key])) {\n            throw new RuntimeException(\"Unable to pop value from hidden context stack for key [{$key}].\");\n        }\n\n        return array_pop($this->hidden[$key]);\n    }\n\n    /**\n     * Increment a context counter.\n     *\n     * @param  string  $key\n     * @param  int  $amount\n     * @return $this\n     */\n    public function increment(string $key, int $amount = 1)\n    {\n        $this->add(\n            $key,\n            (int) $this->get($key, 0) + $amount,\n        );\n\n        return $this;\n    }\n\n    /**\n     * Decrement a context counter.\n     *\n     * @param  string  $key\n     * @param  int  $amount\n     * @return $this\n     */\n    public function decrement(string $key, int $amount = 1)\n    {\n        return $this->increment($key, $amount * -1);\n    }\n\n    /**\n     * Determine if the given value is in the given stack.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  bool  $strict\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function stackContains(string $key, mixed $value, bool $strict = false): bool\n    {\n        if (! $this->isStackable($key)) {\n            throw new RuntimeException(\"Given key [{$key}] is not a stack.\");\n        }\n\n        if (! array_key_exists($key, $this->data)) {\n            return false;\n        }\n\n        if ($value instanceof Closure) {\n            return (new Collection($this->data[$key]))->contains($value);\n        }\n\n        return in_array($value, $this->data[$key], $strict);\n    }\n\n    /**\n     * Determine if the given value is in the given hidden stack.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  bool  $strict\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function hiddenStackContains(string $key, mixed $value, bool $strict = false): bool\n    {\n        if (! $this->isHiddenStackable($key)) {\n            throw new RuntimeException(\"Given key [{$key}] is not a stack.\");\n        }\n\n        if (! array_key_exists($key, $this->hidden)) {\n            return false;\n        }\n\n        if ($value instanceof Closure) {\n            return (new Collection($this->hidden[$key]))->contains($value);\n        }\n\n        return in_array($value, $this->hidden[$key], $strict);\n    }\n\n    /**\n     * Determine if a given key can be used as a stack.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isStackable($key)\n    {\n        return ! $this->has($key) ||\n            (is_array($this->data[$key]) && array_is_list($this->data[$key]));\n    }\n\n    /**\n     * Determine if a given key can be used as a hidden stack.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isHiddenStackable($key)\n    {\n        return ! $this->hasHidden($key) ||\n            (is_array($this->hidden[$key]) && array_is_list($this->hidden[$key]));\n    }\n\n    /**\n     * @template TReturn of mixed\n     *\n     * Run the callback function with the given context values and restore the original context state when complete.\n     *\n     * @param  (callable(): TReturn)  $callback\n     * @param  array<string, mixed>  $data\n     * @param  array<string, mixed>  $hidden\n     * @return TReturn\n     *\n     * @throws \\Throwable\n     */\n    public function scope(callable $callback, array $data = [], array $hidden = [])\n    {\n        $dataBefore = $this->data;\n        $hiddenBefore = $this->hidden;\n\n        if ($data !== []) {\n            $this->add($data);\n        }\n\n        if ($hidden !== []) {\n            $this->addHidden($hidden);\n        }\n\n        try {\n            return $callback();\n        } finally {\n            $this->data = $dataBefore;\n            $this->hidden = $hiddenBefore;\n        }\n    }\n\n    /**\n     * Determine if the repository is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return $this->all() === [] && $this->allHidden() === [];\n    }\n\n    /**\n     * Execute the given callback when context is about to be dehydrated.\n     *\n     * @param  (callable(static): void)  $callback\n     * @return $this\n     */\n    public function dehydrating($callback)\n    {\n        $this->events->listen(fn (Dehydrating $event) => $callback($event->context));\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback when context has been hydrated.\n     *\n     * @param  (callable(static): void)  $callback\n     * @return $this\n     */\n    public function hydrated($callback)\n    {\n        $this->events->listen(fn (Hydrated $event) => $callback($event->context));\n\n        return $this;\n    }\n\n    /**\n     * Handle unserialize exceptions using the given callback.\n     *\n     * @param  callable|null  $callback\n     * @return static\n     */\n    public function handleUnserializeExceptionsUsing($callback)\n    {\n        static::$handleUnserializeExceptionsUsing = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Flush all context data.\n     *\n     * @return $this\n     */\n    public function flush()\n    {\n        $this->data = [];\n        $this->hidden = [];\n\n        return $this;\n    }\n\n    /**\n     * Dehydrate the context data.\n     *\n     * @internal\n     *\n     * @return ?array\n     */\n    public function dehydrate()\n    {\n        $instance = (new static($this->events))\n            ->add($this->all())\n            ->addHidden($this->allHidden());\n\n        $instance->events->dispatch(new Dehydrating($instance));\n\n        $serialize = fn ($value) => serialize($instance->getSerializedPropertyValue($value, withRelations: false));\n\n        return $instance->isEmpty() ? null : [\n            'data' => array_map($serialize, $instance->all()),\n            'hidden' => array_map($serialize, $instance->allHidden()),\n        ];\n    }\n\n    /**\n     * Hydrate the context instance.\n     *\n     * @internal\n     *\n     * @param  ?array  $context\n     * @return $this\n     *\n     * @throws \\RuntimeException\n     */\n    public function hydrate($context)\n    {\n        $unserialize = function ($value, $key, $hidden) {\n            try {\n                return tap($this->getRestoredPropertyValue(unserialize($value)), function ($value) {\n                    if ($value instanceof __PHP_Incomplete_Class) {\n                        throw new RuntimeException('Value is incomplete class: '.json_encode($value));\n                    }\n                });\n            } catch (Throwable $e) {\n                if (static::$handleUnserializeExceptionsUsing !== null) {\n                    return (static::$handleUnserializeExceptionsUsing)($e, $key, $value, $hidden);\n                }\n\n                if ($e instanceof ModelNotFoundException) {\n                    if (function_exists('report')) {\n                        report($e);\n                    }\n\n                    return null;\n                }\n\n                throw $e;\n            }\n        };\n\n        [$data, $hidden] = [\n            (new Collection($context['data'] ?? []))->map(fn ($value, $key) => $unserialize($value, $key, false))->all(),\n            (new Collection($context['hidden'] ?? []))->map(fn ($value, $key) => $unserialize($value, $key, true))->all(),\n        ];\n\n        $this->events->dispatch(new Hydrated(\n            $this->flush()->add($data)->addHidden($hidden)\n        ));\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Events/MessageLogged.php",
    "content": "<?php\n\nnamespace Illuminate\\Log\\Events;\n\nclass MessageLogged\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \"emergency\"|\"alert\"|\"critical\"|\"error\"|\"warning\"|\"notice\"|\"info\"|\"debug\"  $level  The log \"level\".\n     * @param  string  $message  The log message.\n     * @param  array  $context  The log context.\n     */\n    public function __construct(\n        public $level,\n        public $message,\n        public array $context = [],\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Log/LogManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Log;\n\nuse Closure;\nuse Illuminate\\Contracts\\Log\\ContextLogProcessor;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse Monolog\\Formatter\\LineFormatter;\nuse Monolog\\Handler\\ErrorLogHandler;\nuse Monolog\\Handler\\FingersCrossedHandler;\nuse Monolog\\Handler\\FormattableHandlerInterface;\nuse Monolog\\Handler\\HandlerInterface;\nuse Monolog\\Handler\\RotatingFileHandler;\nuse Monolog\\Handler\\SlackWebhookHandler;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\SyslogHandler;\nuse Monolog\\Handler\\WhatFailureGroupHandler;\nuse Monolog\\Logger as Monolog;\nuse Monolog\\Processor\\ProcessorInterface;\nuse Monolog\\Processor\\PsrLogMessageProcessor;\nuse Psr\\Log\\LoggerInterface;\nuse Throwable;\n\n/**\n * @mixin \\Illuminate\\Log\\Logger\n */\nclass LogManager implements LoggerInterface\n{\n    use ParsesLogConfiguration;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of resolved channels.\n     *\n     * @var array\n     */\n    protected $channels = [];\n\n    /**\n     * The context shared across channels and stacks.\n     *\n     * @var array\n     */\n    protected $sharedContext = [];\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * The standard date format to use when writing logs.\n     *\n     * @var string\n     */\n    protected $dateFormat = 'Y-m-d H:i:s';\n\n    /**\n     * Create a new Log manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Build an on-demand log channel.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function build(array $config)\n    {\n        unset($this->channels['ondemand']);\n\n        return $this->get('ondemand', $config);\n    }\n\n    /**\n     * Create a new, on-demand aggregate logger instance.\n     *\n     * @param  array  $channels\n     * @param  string|null  $channel\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function stack(array $channels, $channel = null)\n    {\n        return (new Logger(\n            $this->createStackDriver(compact('channels', 'channel')),\n            $this->app['events']\n        ))->withContext($this->sharedContext);\n    }\n\n    /**\n     * Get a log channel instance.\n     *\n     * @param  string|null  $channel\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function channel($channel = null)\n    {\n        return $this->driver($channel);\n    }\n\n    /**\n     * Get a log driver instance.\n     *\n     * @param  string|null  $driver\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function driver($driver = null)\n    {\n        return $this->get($this->parseDriver($driver));\n    }\n\n    /**\n     * Attempt to get the log from the local cache.\n     *\n     * @param  string  $name\n     * @param  array|null  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function get($name, ?array $config = null)\n    {\n        try {\n            return $this->channels[$name] ?? with($this->resolve($name, $config), function ($logger) use ($name) {\n                $loggerWithContext = $this->tap(\n                    $name,\n                    new Logger($logger, $this->app['events'])\n                )->withContext($this->sharedContext);\n\n                if (method_exists($loggerWithContext->getLogger(), 'pushProcessor')) {\n                    $loggerWithContext->pushProcessor($this->app->make(ContextLogProcessor::class));\n                }\n\n                return $this->channels[$name] = $loggerWithContext;\n            });\n        } catch (Throwable $e) {\n            return tap($this->createEmergencyLogger(), function ($logger) use ($e) {\n                $logger->emergency('Unable to create configured logger. Using emergency logger.', [\n                    'exception' => $e,\n                ]);\n            });\n        }\n    }\n\n    /**\n     * Apply the configured taps for the logger.\n     *\n     * @param  string  $name\n     * @param  \\Illuminate\\Log\\Logger  $logger\n     * @return \\Illuminate\\Log\\Logger\n     */\n    protected function tap($name, Logger $logger)\n    {\n        foreach ($this->configurationFor($name)['tap'] ?? [] as $tap) {\n            [$class, $arguments] = $this->parseTap($tap);\n\n            $this->app->make($class)->__invoke($logger, ...explode(',', $arguments));\n        }\n\n        return $logger;\n    }\n\n    /**\n     * Parse the given tap class string into a class name and arguments string.\n     *\n     * @param  string  $tap\n     * @return array\n     */\n    protected function parseTap($tap)\n    {\n        return str_contains($tap, ':') ? explode(':', $tap, 2) : [$tap, ''];\n    }\n\n    /**\n     * Create an emergency log handler to avoid white screens of death.\n     *\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createEmergencyLogger()\n    {\n        $config = $this->configurationFor('emergency');\n\n        $handler = new StreamHandler(\n            $config['path'] ?? $this->app->storagePath().'/logs/laravel.log',\n            $this->level(['level' => 'debug'])\n        );\n\n        return new Logger(\n            new Monolog('laravel', $this->prepareHandlers([$handler])),\n            $this->app['events']\n        );\n    }\n\n    /**\n     * Resolve the given log instance by name.\n     *\n     * @param  string  $name\n     * @param  array|null  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name, ?array $config = null)\n    {\n        $config ??= $this->configurationFor($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Log [{$name}] is not defined.\");\n        }\n\n        if (isset($this->customCreators[$config['driver']])) {\n            return $this->callCustomCreator($config);\n        }\n\n        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';\n\n        if (method_exists($this, $driverMethod)) {\n            return $this->{$driverMethod}($config);\n        }\n\n        throw new InvalidArgumentException(\"Driver [{$config['driver']}] is not supported.\");\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  array  $config\n     * @return mixed\n     */\n    protected function callCustomCreator(array $config)\n    {\n        return $this->customCreators[$config['driver']]($this->app, $config);\n    }\n\n    /**\n     * Create a custom log driver instance.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createCustomDriver(array $config)\n    {\n        $factory = is_callable($via = $config['via']) ? $via : $this->app->make($via);\n\n        return $factory($config);\n    }\n\n    /**\n     * Create an aggregate log driver instance.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createStackDriver(array $config)\n    {\n        if (is_string($config['channels'])) {\n            $config['channels'] = explode(',', $config['channels']);\n        }\n\n        $handlers = (new Collection($config['channels']))\n            ->flatMap(function ($channel) {\n                return $channel instanceof LoggerInterface\n                    ? $channel->getHandlers()\n                    : $this->channel($channel)->getHandlers();\n            })\n            ->all();\n\n        $processors = (new Collection($config['channels']))\n            ->flatMap(function ($channel) {\n                return $channel instanceof LoggerInterface\n                    ? $channel->getProcessors()\n                    : $this->channel($channel)->getProcessors();\n            })\n            ->all();\n\n        if ($config['ignore_exceptions'] ?? false) {\n            $handlers = [new WhatFailureGroupHandler($handlers)];\n        }\n\n        return new Monolog($this->parseChannel($config), $handlers, $processors);\n    }\n\n    /**\n     * Create an instance of the single file log driver.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createSingleDriver(array $config)\n    {\n        return new Monolog($this->parseChannel($config), [\n            $this->prepareHandler(\n                new StreamHandler(\n                    $config['path'], $this->level($config),\n                    $config['bubble'] ?? true, $config['permission'] ?? null, $config['locking'] ?? false\n                ), $config\n            ),\n        ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []);\n    }\n\n    /**\n     * Create an instance of the daily file log driver.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createDailyDriver(array $config)\n    {\n        return new Monolog($this->parseChannel($config), [\n            $this->prepareHandler(new RotatingFileHandler(\n                $config['path'], $config['days'] ?? 7, $this->level($config),\n                $config['bubble'] ?? true, $config['permission'] ?? null, $config['locking'] ?? false\n            ), $config),\n        ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []);\n    }\n\n    /**\n     * Create an instance of the Slack log driver.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createSlackDriver(array $config)\n    {\n        return new Monolog($this->parseChannel($config), [\n            $this->prepareHandler(new SlackWebhookHandler(\n                $config['url'],\n                $config['channel'] ?? null,\n                $config['username'] ?? 'Laravel',\n                $config['attachment'] ?? true,\n                $config['emoji'] ?? ':boom:',\n                $config['short'] ?? false,\n                $config['context'] ?? true,\n                $this->level($config),\n                $config['bubble'] ?? true,\n                $config['exclude_fields'] ?? []\n            ), $config),\n        ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []);\n    }\n\n    /**\n     * Create an instance of the syslog log driver.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createSyslogDriver(array $config)\n    {\n        return new Monolog($this->parseChannel($config), [\n            $this->prepareHandler(new SyslogHandler(\n                Str::snake($this->app['config']['app.name'], '-'),\n                $config['facility'] ?? LOG_USER, $this->level($config)\n            ), $config),\n        ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []);\n    }\n\n    /**\n     * Create an instance of the \"error log\" log driver.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    protected function createErrorlogDriver(array $config)\n    {\n        return new Monolog($this->parseChannel($config), [\n            $this->prepareHandler(new ErrorLogHandler(\n                $config['type'] ?? ErrorLogHandler::OPERATING_SYSTEM, $this->level($config)\n            )),\n        ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []);\n    }\n\n    /**\n     * Create an instance of any handler available in Monolog.\n     *\n     * @param  array  $config\n     * @return \\Psr\\Log\\LoggerInterface\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function createMonologDriver(array $config)\n    {\n        if (! is_a($config['handler'], HandlerInterface::class, true)) {\n            throw new InvalidArgumentException(\n                $config['handler'].' must be an instance of '.HandlerInterface::class\n            );\n        }\n\n        (new Collection($config['processors'] ?? []))->each(function ($processor) {\n            $processor = $processor['processor'] ?? $processor;\n\n            if (! is_a($processor, ProcessorInterface::class, true)) {\n                throw new InvalidArgumentException(\n                    $processor.' must be an instance of '.ProcessorInterface::class\n                );\n            }\n        });\n\n        $with = array_merge(\n            ['level' => $this->level($config)],\n            $config['with'] ?? [],\n            $config['handler_with'] ?? []\n        );\n\n        $handler = $this->prepareHandler(\n            $this->app->make($config['handler'], $with), $config\n        );\n\n        $processors = (new Collection($config['processors'] ?? []))\n            ->map(fn ($processor) => $this->app->make($processor['processor'] ?? $processor, $processor['with'] ?? []))\n            ->toArray();\n\n        return new Monolog(\n            $this->parseChannel($config),\n            [$handler],\n            $processors,\n        );\n    }\n\n    /**\n     * Prepare the handlers for usage by Monolog.\n     *\n     * @param  array  $handlers\n     * @return array\n     */\n    protected function prepareHandlers(array $handlers)\n    {\n        foreach ($handlers as $key => $handler) {\n            $handlers[$key] = $this->prepareHandler($handler);\n        }\n\n        return $handlers;\n    }\n\n    /**\n     * Prepare the handler for usage by Monolog.\n     *\n     * @param  \\Monolog\\Handler\\HandlerInterface  $handler\n     * @param  array  $config\n     * @return \\Monolog\\Handler\\HandlerInterface\n     */\n    protected function prepareHandler(HandlerInterface $handler, array $config = [])\n    {\n        if (isset($config['action_level'])) {\n            $handler = new FingersCrossedHandler(\n                $handler,\n                $this->actionLevel($config),\n                0,\n                true,\n                $config['stop_buffering'] ?? true\n            );\n        }\n\n        if (! $handler instanceof FormattableHandlerInterface) {\n            return $handler;\n        }\n\n        if (! isset($config['formatter'])) {\n            $handler->setFormatter($this->formatter());\n        } elseif ($config['formatter'] !== 'default') {\n            $handler->setFormatter($this->app->make($config['formatter'], $config['formatter_with'] ?? []));\n        }\n\n        return $handler;\n    }\n\n    /**\n     * Get a Monolog formatter instance.\n     *\n     * @return \\Monolog\\Formatter\\FormatterInterface\n     */\n    protected function formatter()\n    {\n        return new LineFormatter(null, $this->dateFormat, true, true, true);\n    }\n\n    /**\n     * Share context across channels and stacks.\n     *\n     * @param  array  $context\n     * @return $this\n     */\n    public function shareContext(array $context)\n    {\n        foreach ($this->channels as $channel) {\n            $channel->withContext($context);\n        }\n\n        $this->sharedContext = array_merge($this->sharedContext, $context);\n\n        return $this;\n    }\n\n    /**\n     * The context shared across channels and stacks.\n     *\n     * @return array\n     */\n    public function sharedContext()\n    {\n        return $this->sharedContext;\n    }\n\n    /**\n     * Flush the log context on all currently resolved channels.\n     *\n     * @param  string[]|null  $keys\n     * @return $this\n     */\n    public function withoutContext(?array $keys = null)\n    {\n        foreach ($this->channels as $channel) {\n            if (method_exists($channel, 'withoutContext')) {\n                $channel->withoutContext($keys);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Flush the shared context.\n     *\n     * @return $this\n     */\n    public function flushSharedContext()\n    {\n        $this->sharedContext = [];\n\n        return $this;\n    }\n\n    /**\n     * Get fallback log channel name.\n     *\n     * @return string\n     */\n    protected function getFallbackChannelName()\n    {\n        return $this->app->bound('env') ? $this->app->environment() : 'production';\n    }\n\n    /**\n     * Get the log connection configuration.\n     *\n     * @param  string  $name\n     * @return array|null\n     */\n    protected function configurationFor($name)\n    {\n        return $this->app['config'][\"logging.channels.{$name}\"];\n    }\n\n    /**\n     * Get the default log driver name.\n     *\n     * @return string|null\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['logging.default'];\n    }\n\n    /**\n     * Set the default log driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['logging.default'] = $name;\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Unset the given channel instance.\n     *\n     * @param  string|null  $driver\n     * @return void\n     */\n    public function forgetChannel($driver = null)\n    {\n        $driver = $this->parseDriver($driver);\n\n        if (isset($this->channels[$driver])) {\n            unset($this->channels[$driver]);\n        }\n    }\n\n    /**\n     * Parse the driver name.\n     *\n     * @param  string|null  $driver\n     * @return string|null\n     */\n    protected function parseDriver($driver)\n    {\n        $driver ??= $this->getDefaultDriver();\n\n        if ($this->app->runningUnitTests()) {\n            $driver ??= 'null';\n        }\n\n        if ($driver === null) {\n            return null;\n        }\n\n        return trim($driver);\n    }\n\n    /**\n     * Get all of the resolved log channels.\n     *\n     * @return array\n     */\n    public function getChannels()\n    {\n        return $this->channels;\n    }\n\n    /**\n     * System is unusable.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function emergency($message, array $context = []): void\n    {\n        $this->driver()->emergency($message, $context);\n    }\n\n    /**\n     * Action must be taken immediately.\n     *\n     * Example: Entire website down, database unavailable, etc. This should\n     * trigger the SMS alerts and wake you up.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function alert($message, array $context = []): void\n    {\n        $this->driver()->alert($message, $context);\n    }\n\n    /**\n     * Critical conditions.\n     *\n     * Example: Application component unavailable, unexpected exception.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function critical($message, array $context = []): void\n    {\n        $this->driver()->critical($message, $context);\n    }\n\n    /**\n     * Runtime errors that do not require immediate action but should typically\n     * be logged and monitored.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function error($message, array $context = []): void\n    {\n        $this->driver()->error($message, $context);\n    }\n\n    /**\n     * Exceptional occurrences that are not errors.\n     *\n     * Example: Use of deprecated APIs, poor use of an API, undesirable things\n     * that are not necessarily wrong.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function warning($message, array $context = []): void\n    {\n        $this->driver()->warning($message, $context);\n    }\n\n    /**\n     * Normal but significant events.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function notice($message, array $context = []): void\n    {\n        $this->driver()->notice($message, $context);\n    }\n\n    /**\n     * Interesting events.\n     *\n     * Example: User logs in, SQL logs.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function info($message, array $context = []): void\n    {\n        $this->driver()->info($message, $context);\n    }\n\n    /**\n     * Detailed debug information.\n     *\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function debug($message, array $context = []): void\n    {\n        $this->driver()->debug($message, $context);\n    }\n\n    /**\n     * Logs with an arbitrary level.\n     *\n     * @param  mixed  $level\n     * @param  string|\\Stringable  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function log($level, $message, array $context = []): void\n    {\n        $this->driver()->log($level, $message, $context);\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->driver()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/LogServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Log;\n\nuse Illuminate\\Support\\ServiceProvider;\n\nclass LogServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('log', fn ($app) => new LogManager($app));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/Logger.php",
    "content": "<?php\n\nnamespace Illuminate\\Log;\n\nuse Closure;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Log\\Events\\MessageLogged;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Psr\\Log\\LoggerInterface;\nuse RuntimeException;\n\nclass Logger implements LoggerInterface\n{\n    use Conditionable;\n\n    /**\n     * The underlying logger implementation.\n     *\n     * @var \\Psr\\Log\\LoggerInterface\n     */\n    protected $logger;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $dispatcher;\n\n    /**\n     * Any context to be added to logs.\n     *\n     * @var array\n     */\n    protected $context = [];\n\n    /**\n     * Create a new log writer instance.\n     *\n     * @param  \\Psr\\Log\\LoggerInterface  $logger\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher|null  $dispatcher\n     */\n    public function __construct(LoggerInterface $logger, ?Dispatcher $dispatcher = null)\n    {\n        $this->logger = $logger;\n        $this->dispatcher = $dispatcher;\n    }\n\n    /**\n     * Log an emergency message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function emergency($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log an alert message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function alert($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log a critical message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function critical($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log an error message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function error($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log a warning message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function warning($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log a notice to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function notice($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log an informational message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function info($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log a debug message to the logs.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function debug($message, array $context = []): void\n    {\n        $this->writeLog(__FUNCTION__, $message, $context);\n    }\n\n    /**\n     * Log a message to the logs.\n     *\n     * @param  string  $level\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function log($level, $message, array $context = []): void\n    {\n        $this->writeLog($level, $message, $context);\n    }\n\n    /**\n     * Dynamically pass log calls into the writer.\n     *\n     * @param  string  $level\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    public function write($level, $message, array $context = []): void\n    {\n        $this->writeLog($level, $message, $context);\n    }\n\n    /**\n     * Write a message to the log.\n     *\n     * @param  string  $level\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @param  array  $context\n     * @return void\n     */\n    protected function writeLog($level, $message, $context): void\n    {\n        if (method_exists($this->logger, 'isHandling') && ! $this->logger->isHandling($level)) {\n            return;\n        }\n\n        $this->logger->{$level}(\n            $message = $this->formatMessage($message),\n            $context = array_merge($this->context, $context)\n        );\n\n        $this->fireLogEvent($level, $message, $context);\n    }\n\n    /**\n     * Add context to all future logs.\n     *\n     * @param  array  $context\n     * @return $this\n     */\n    public function withContext(array $context = [])\n    {\n        $this->context = array_merge($this->context, $context);\n\n        return $this;\n    }\n\n    /**\n     * Flush the log context on all currently resolved channels.\n     *\n     * @param  string[]|null  $keys\n     * @return $this\n     */\n    public function withoutContext(?array $keys = null)\n    {\n        if (is_array($keys)) {\n            $this->context = array_diff_key($this->context, array_flip($keys));\n        } else {\n            $this->context = [];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Register a new callback handler for when a log event is triggered.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function listen(Closure $callback)\n    {\n        if (! isset($this->dispatcher)) {\n            throw new RuntimeException('Events dispatcher has not been set.');\n        }\n\n        $this->dispatcher->listen(MessageLogged::class, $callback);\n    }\n\n    /**\n     * Fires a log event.\n     *\n     * @param  string  $level\n     * @param  string  $message\n     * @param  array  $context\n     * @return void\n     */\n    protected function fireLogEvent($level, $message, array $context = [])\n    {\n        // Avoid dispatching the event multiple times if our logger instance is the LogManager...\n        if ($this->logger instanceof LogManager &&\n            $this->logger->getEventDispatcher() !== null) {\n            return;\n        }\n\n        // If the event dispatcher is set, we will pass along the parameters to the\n        // log listeners. These are useful for building profilers or other tools\n        // that aggregate all of the log messages for a given \"request\" cycle.\n        $this->dispatcher?->dispatch(new MessageLogged($level, $message, $context));\n    }\n\n    /**\n     * Format the parameters for the logger.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string  $message\n     * @return string\n     */\n    protected function formatMessage($message)\n    {\n        return match (true) {\n            is_array($message) => var_export($message, true),\n            $message instanceof Jsonable => $message->toJson(),\n            $message instanceof Arrayable => var_export($message->toArray(), true),\n            default => (string) $message,\n        };\n    }\n\n    /**\n     * Get the underlying logger implementation.\n     *\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function getLogger()\n    {\n        return $this->logger;\n    }\n\n    /**\n     * Get the event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getEventDispatcher()\n    {\n        return $this->dispatcher;\n    }\n\n    /**\n     * Set the event dispatcher instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @return void\n     */\n    public function setEventDispatcher(Dispatcher $dispatcher)\n    {\n        $this->dispatcher = $dispatcher;\n    }\n\n    /**\n     * Dynamically proxy method calls to the underlying logger.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->logger->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/ParsesLogConfiguration.php",
    "content": "<?php\n\nnamespace Illuminate\\Log;\n\nuse InvalidArgumentException;\nuse Monolog\\Level;\n\ntrait ParsesLogConfiguration\n{\n    /**\n     * The Log levels.\n     *\n     * @var array\n     */\n    protected $levels = [\n        'debug' => Level::Debug,\n        'info' => Level::Info,\n        'notice' => Level::Notice,\n        'warning' => Level::Warning,\n        'error' => Level::Error,\n        'critical' => Level::Critical,\n        'alert' => Level::Alert,\n        'emergency' => Level::Emergency,\n    ];\n\n    /**\n     * Get fallback log channel name.\n     *\n     * @return string\n     */\n    abstract protected function getFallbackChannelName();\n\n    /**\n     * Parse the string level into a Monolog constant.\n     *\n     * @param  array  $config\n     * @return int\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function level(array $config)\n    {\n        $level = $config['level'] ?? 'debug';\n\n        if (isset($this->levels[$level])) {\n            return $this->levels[$level];\n        }\n\n        throw new InvalidArgumentException('Invalid log level.');\n    }\n\n    /**\n     * Parse the action level from the given configuration.\n     *\n     * @param  array  $config\n     * @return int\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function actionLevel(array $config)\n    {\n        $level = $config['action_level'] ?? 'debug';\n\n        if (isset($this->levels[$level])) {\n            return $this->levels[$level];\n        }\n\n        throw new InvalidArgumentException('Invalid log action level.');\n    }\n\n    /**\n     * Extract the log channel from the given configuration.\n     *\n     * @param  array  $config\n     * @return string\n     */\n    protected function parseChannel(array $config)\n    {\n        return $config['name'] ?? $this->getFallbackChannelName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/composer.json",
    "content": "{\n    \"name\": \"illuminate/log\",\n    \"description\": \"The Illuminate Log package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"monolog/monolog\": \"^3.0\",\n        \"psr/log\": \"^1.0 || ^2.0 || ^3.0\"\n    },\n    \"provide\": {\n        \"psr/log-implementation\": \"1.0 || 2.0 || 3.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Log\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Log/functions.php",
    "content": "<?php\n\nnamespace Illuminate\\Log;\n\nuse Psr\\Log\\LoggerInterface;\n\nif (! function_exists('Illuminate\\Log\\log')) {\n    /**\n     * Log a debug message to the logs.\n     *\n     * @param  string|null  $message\n     * @param  array  $context\n     * @return ($message is null ? \\Psr\\Log\\LoggerInterface: null)\n     */\n    function log($message = null, array $context = []): ?LoggerInterface\n    {\n        return logger($message, $context);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Macroable/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Macroable/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Macroable/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Macroable/Traits/Macroable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse BadMethodCallException;\nuse Closure;\nuse ReflectionClass;\nuse ReflectionMethod;\n\ntrait Macroable\n{\n    /**\n     * The registered string macros.\n     *\n     * @var array\n     */\n    protected static $macros = [];\n\n    /**\n     * Register a custom macro.\n     *\n     * @param  string  $name\n     * @param  object|callable  $macro\n     *\n     * @param-closure-this static  $macro\n     *\n     * @return void\n     */\n    public static function macro($name, $macro)\n    {\n        static::$macros[$name] = $macro;\n    }\n\n    /**\n     * Mix another object into the class.\n     *\n     * @param  object  $mixin\n     * @param  bool  $replace\n     * @return void\n     *\n     * @throws \\ReflectionException\n     */\n    public static function mixin($mixin, $replace = true)\n    {\n        $methods = (new ReflectionClass($mixin))->getMethods(\n            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED\n        );\n\n        foreach ($methods as $method) {\n            if ($replace || ! static::hasMacro($method->name)) {\n                static::macro($method->name, $method->invoke($mixin));\n            }\n        }\n    }\n\n    /**\n     * Checks if macro is registered.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public static function hasMacro($name)\n    {\n        return isset(static::$macros[$name]);\n    }\n\n    /**\n     * Flush the existing macros.\n     *\n     * @return void\n     */\n    public static function flushMacros()\n    {\n        static::$macros = [];\n    }\n\n    /**\n     * Dynamically handle calls to the class.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public static function __callStatic($method, $parameters)\n    {\n        if (! static::hasMacro($method)) {\n            throw new BadMethodCallException(sprintf(\n                'Method %s::%s does not exist.', static::class, $method\n            ));\n        }\n\n        $macro = static::$macros[$method];\n\n        if ($macro instanceof Closure) {\n            $macro = $macro->bindTo(null, static::class);\n        }\n\n        return $macro(...$parameters);\n    }\n\n    /**\n     * Dynamically handle calls to the class.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (! static::hasMacro($method)) {\n            throw new BadMethodCallException(sprintf(\n                'Method %s::%s does not exist.', static::class, $method\n            ));\n        }\n\n        $macro = static::$macros[$method];\n\n        if ($macro instanceof Closure) {\n            $macro = $macro->bindTo($this, static::class);\n        }\n\n        return $macro(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Macroable/composer.json",
    "content": "{\n    \"name\": \"illuminate/macroable\",\n    \"description\": \"The Illuminate Macroable package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.2\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Support\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Mail/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Mail/Attachment.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Filesystem\\Factory as FilesystemFactory;\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\n\nclass Attachment\n{\n    use Macroable;\n\n    /**\n     * The attached file's filename.\n     *\n     * @var string|null\n     */\n    public $as;\n\n    /**\n     * The attached file's MIME type.\n     *\n     * @var string|null\n     */\n    public $mime;\n\n    /**\n     * A callback that attaches the attachment to the mail message.\n     *\n     * @var \\Closure\n     */\n    protected $resolver;\n\n    /**\n     * Create a mail attachment.\n     *\n     * @param  \\Closure  $resolver\n     */\n    private function __construct(Closure $resolver)\n    {\n        $this->resolver = $resolver;\n    }\n\n    /**\n     * Create a mail attachment from a path.\n     *\n     * @param  string  $path\n     * @return static\n     */\n    public static function fromPath($path)\n    {\n        return new static(fn ($attachment, $pathStrategy) => $pathStrategy($path, $attachment));\n    }\n\n    /**\n     * Create a mail attachment from a URL.\n     *\n     * @param  string  $url\n     * @return static\n     */\n    public static function fromUrl($url)\n    {\n        return static::fromPath($url);\n    }\n\n    /**\n     * Create a mail attachment from in-memory data.\n     *\n     * @param  \\Closure  $data\n     * @param  string|null  $name\n     * @return static\n     */\n    public static function fromData(Closure $data, $name = null)\n    {\n        return (new static(\n            fn ($attachment, $pathStrategy, $dataStrategy) => $dataStrategy($data, $attachment)\n        ))->as($name);\n    }\n\n    /**\n     * Create a mail attachment from an UploadedFile instance.\n     *\n     * @param  \\Illuminate\\Http\\UploadedFile  $file\n     * @return static\n     */\n    public static function fromUploadedFile(UploadedFile $file)\n    {\n        return new static(function ($attachment, $pathStrategy, $dataStrategy) use ($file) {\n            $attachment\n                ->as($file->getClientOriginalName())\n                ->withMime($file->getMimeType() ?? $file->getClientMimeType());\n\n            return $dataStrategy(fn () => $file->get(), $attachment);\n        });\n    }\n\n    /**\n     * Create a mail attachment from a file on the default storage disk.\n     *\n     * @param  string  $path\n     * @return static\n     */\n    public static function fromStorage($path)\n    {\n        return static::fromStorageDisk(null, $path);\n    }\n\n    /**\n     * Create a mail attachment from a file on the specified storage disk.\n     *\n     * @param  string|null  $disk\n     * @param  string  $path\n     * @return static\n     */\n    public static function fromStorageDisk($disk, $path)\n    {\n        return new static(function ($attachment, $pathStrategy, $dataStrategy) use ($disk, $path) {\n            $storage = Container::getInstance()->make(\n                FilesystemFactory::class\n            )->disk($disk);\n\n            $attachment\n                ->as($attachment->as ?? basename($path))\n                ->withMime($attachment->mime ?? $storage->mimeType($path));\n\n            return $dataStrategy(fn () => $storage->get($path), $attachment);\n        });\n    }\n\n    /**\n     * Create a mail attachment from a file on the cloud storage disk.\n     *\n     * @param  string  $path\n     * @return static\n     */\n    public static function fromCloudStorage($path)\n    {\n        return self::fromStorageDisk(Storage::getDefaultCloudDriver(), $path);\n    }\n\n    /**\n     * Set the attached file's filename.\n     *\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function as($name)\n    {\n        $this->as = $name;\n\n        return $this;\n    }\n\n    /**\n     * Set the attached file's MIME type.\n     *\n     * @param  string  $mime\n     * @return $this\n     */\n    public function withMime($mime)\n    {\n        $this->mime = $mime;\n\n        return $this;\n    }\n\n    /**\n     * Attach the attachment with the given strategies.\n     *\n     * @param  \\Closure  $pathStrategy\n     * @param  \\Closure  $dataStrategy\n     * @return mixed\n     */\n    public function attachWith(Closure $pathStrategy, Closure $dataStrategy)\n    {\n        return ($this->resolver)($this, $pathStrategy, $dataStrategy);\n    }\n\n    /**\n     * Attach the attachment to a built-in mail type.\n     *\n     * @param  \\Illuminate\\Mail\\Mailable|\\Illuminate\\Mail\\Message|\\Illuminate\\Notifications\\Messages\\MailMessage  $mail\n     * @param  array  $options\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public function attachTo($mail, $options = [])\n    {\n        return $this->attachWith(\n            fn ($path) => $mail->attach($path, [\n                'as' => $options['as'] ?? $this->as,\n                'mime' => $options['mime'] ?? $this->mime,\n            ]),\n            function ($data) use ($mail, $options) {\n                $options = [\n                    'as' => $options['as'] ?? $this->as,\n                    'mime' => $options['mime'] ?? $this->mime,\n                ];\n\n                if ($options['as'] === null) {\n                    throw new RuntimeException('Attachment requires a filename to be specified.');\n                }\n\n                return $mail->attachData($data(), $options['as'], ['mime' => $options['mime']]);\n            }\n        );\n    }\n\n    /**\n     * Determine if the given attachment is equivalent to this attachment.\n     *\n     * @param  \\Illuminate\\Mail\\Attachment  $attachment\n     * @param  array  $options\n     * @return bool\n     */\n    public function isEquivalent(Attachment $attachment, $options = [])\n    {\n        $newOptions = [\n            'as' => $options['as'] ?? $attachment->as,\n            'mime' => $options['mime'] ?? $attachment->mime,\n        ];\n\n        return $this->attachWith(\n            fn ($path) => [$path, ['as' => $this->as, 'mime' => $this->mime]],\n            fn ($data) => [$data(), ['as' => $this->as, 'mime' => $this->mime]],\n        ) === $attachment->attachWith(\n            fn ($path) => [$path, $newOptions],\n            fn ($data) => [$data(), $newOptions],\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Events/MessageSending.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Events;\n\nuse Symfony\\Component\\Mime\\Email;\n\nclass MessageSending\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Symfony\\Component\\Mime\\Email  $message  The Symfony Email instance.\n     * @param  array  $data  The message data.\n     */\n    public function __construct(\n        public Email $message,\n        public array $data = [],\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Events/MessageSent.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Events;\n\nuse Exception;\nuse Illuminate\\Mail\\SentMessage;\nuse Illuminate\\Support\\Collection;\n\n/**\n * @property \\Symfony\\Component\\Mime\\Email $message\n */\nclass MessageSent\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Mail\\SentMessage  $sent  The message that was sent.\n     * @param  array  $data  The message data.\n     */\n    public function __construct(\n        public SentMessage $sent,\n        public array $data = [],\n    ) {\n    }\n\n    /**\n     * Get the serializable representation of the object.\n     *\n     * @return array\n     */\n    public function __serialize()\n    {\n        $hasAttachments = (new Collection($this->message->getAttachments()))->isNotEmpty();\n\n        return [\n            'sent' => $this->sent,\n            'data' => $hasAttachments ? base64_encode(serialize($this->data)) : $this->data,\n            'hasAttachments' => $hasAttachments,\n        ];\n    }\n\n    /**\n     * Marshal the object from its serialized data.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    public function __unserialize(array $data)\n    {\n        $this->sent = $data['sent'];\n\n        $this->data = (($data['hasAttachments'] ?? false) === true)\n            ? unserialize(base64_decode($data['data']))\n            : $data['data'];\n    }\n\n    /**\n     * Dynamically get the original message.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\Exception\n     */\n    public function __get($key)\n    {\n        if ($key === 'message') {\n            return $this->sent->getOriginalMessage();\n        }\n\n        throw new Exception('Unable to access undefined property on '.__CLASS__.': '.$key);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Mail/MailManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Aws\\Ses\\SesClient;\nuse Aws\\SesV2\\SesV2Client;\nuse Closure;\nuse Illuminate\\Contracts\\Mail\\Factory as FactoryContract;\nuse Illuminate\\Log\\LogManager;\nuse Illuminate\\Mail\\Transport\\ArrayTransport;\nuse Illuminate\\Mail\\Transport\\LogTransport;\nuse Illuminate\\Mail\\Transport\\ResendTransport;\nuse Illuminate\\Mail\\Transport\\SesTransport;\nuse Illuminate\\Mail\\Transport\\SesV2Transport;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\ConfigurationUrlParser;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse Psr\\Log\\LoggerInterface;\nuse Resend;\nuse Symfony\\Component\\HttpClient\\HttpClient;\nuse Symfony\\Component\\Mailer\\Bridge\\Mailgun\\Transport\\MailgunTransportFactory;\nuse Symfony\\Component\\Mailer\\Bridge\\Postmark\\Transport\\PostmarkTransportFactory;\nuse Symfony\\Component\\Mailer\\Transport\\Dsn;\nuse Symfony\\Component\\Mailer\\Transport\\FailoverTransport;\nuse Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport;\nuse Symfony\\Component\\Mailer\\Transport\\SendmailTransport;\nuse Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport;\nuse Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransportFactory;\nuse Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\SocketStream;\n\n/**\n * @mixin \\Illuminate\\Mail\\Mailer\n */\nclass MailManager implements FactoryContract\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of resolved mailers.\n     *\n     * @var array\n     */\n    protected $mailers = [];\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * Create a new Mail manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Get a mailer instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Mail\\Mailer\n     */\n    public function mailer($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        return $this->mailers[$name] = $this->get($name);\n    }\n\n    /**\n     * Get a mailer driver instance.\n     *\n     * @param  string|null  $driver\n     * @return \\Illuminate\\Mail\\Mailer\n     */\n    public function driver($driver = null)\n    {\n        return $this->mailer($driver);\n    }\n\n    /**\n     * Attempt to get the mailer from the local cache.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Mail\\Mailer\n     */\n    protected function get($name)\n    {\n        return $this->mailers[$name] ?? $this->resolve($name);\n    }\n\n    /**\n     * Resolve the given mailer.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Mail\\Mailer\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Mailer [{$name}] is not defined.\");\n        }\n\n        // Once we have created the mailer instance we will set a container instance\n        // on the mailer. This allows us to resolve mailer classes via containers\n        // for maximum testability on said classes instead of passing Closures.\n        $mailer = $this->build(['name' => $name, ...$config]);\n\n        // Next we will set all of the global addresses on this mailer, which allows\n        // for easy unification of all \"from\" addresses as well as easy debugging\n        // of sent messages since these will be sent to a single email address.\n        foreach (['from', 'reply_to', 'to', 'return_path'] as $type) {\n            $this->setGlobalAddress($mailer, $config, $type);\n        }\n\n        return $mailer;\n    }\n\n    /**\n     * Build a new mailer instance.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Mail\\Mailer\n     */\n    public function build($config)\n    {\n        $mailer = new Mailer(\n            $config['name'] ?? 'ondemand',\n            $this->app['view'],\n            $this->createSymfonyTransport($config),\n            $this->app['events']\n        );\n\n        if ($this->app->bound('queue')) {\n            $mailer->setQueue($this->app['queue']);\n        }\n\n        return $mailer;\n    }\n\n    /**\n     * Create a new transport instance.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\TransportInterface\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function createSymfonyTransport(array $config)\n    {\n        // Here we will check if the \"transport\" key exists and if it doesn't we will\n        // assume an application is still using the legacy mail configuration file\n        // format and use the \"mail.driver\" configuration option instead for BC.\n        $transport = $config['transport'] ?? $this->app['config']['mail.driver'];\n\n        if (isset($this->customCreators[$transport])) {\n            return call_user_func($this->customCreators[$transport], $config);\n        }\n\n        if (trim($transport ?? '') === '' ||\n            ! method_exists($this, $method = 'create'.ucfirst(Str::camel($transport)).'Transport')) {\n            throw new InvalidArgumentException(\"Unsupported mail transport [{$transport}].\");\n        }\n\n        return $this->{$method}($config);\n    }\n\n    /**\n     * Create an instance of the Symfony SMTP Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport\n     */\n    protected function createSmtpTransport(array $config)\n    {\n        $factory = new EsmtpTransportFactory;\n\n        $scheme = $config['scheme'] ?? null;\n\n        if (! $scheme) {\n            $scheme = ($config['port'] == 465) ? 'smtps' : 'smtp';\n        }\n\n        $transport = $factory->create(new Dsn(\n            $scheme,\n            $config['host'],\n            $config['username'] ?? null,\n            $config['password'] ?? null,\n            $config['port'] ?? null,\n            $config\n        ));\n\n        return $this->configureSmtpTransport($transport, $config);\n    }\n\n    /**\n     * Configure the additional SMTP driver options.\n     *\n     * @param  \\Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport  $transport\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport\n     */\n    protected function configureSmtpTransport(EsmtpTransport $transport, array $config)\n    {\n        $stream = $transport->getStream();\n\n        if ($stream instanceof SocketStream) {\n            if (isset($config['source_ip'])) {\n                $stream->setSourceIp($config['source_ip']);\n            }\n\n            if (isset($config['timeout'])) {\n                $stream->setTimeout($config['timeout']);\n            }\n        }\n\n        return $transport;\n    }\n\n    /**\n     * Create an instance of the Symfony Sendmail Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\SendmailTransport\n     */\n    protected function createSendmailTransport(array $config)\n    {\n        return new SendmailTransport(\n            $config['path'] ?? $this->app['config']->get('mail.sendmail')\n        );\n    }\n\n    /**\n     * Create an instance of the Symfony Amazon SES Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Mail\\Transport\\SesTransport\n     */\n    protected function createSesTransport(array $config)\n    {\n        $config = array_merge(\n            $this->app['config']->get('services.ses', []),\n            ['version' => 'latest', 'service' => 'email'],\n            $config\n        );\n\n        $config = Arr::except($config, ['transport']);\n\n        return new SesTransport(\n            new SesClient($this->addSesCredentials($config)),\n            $config['options'] ?? []\n        );\n    }\n\n    /**\n     * Create an instance of the Symfony Amazon SES V2 Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Mail\\Transport\\SesV2Transport\n     */\n    protected function createSesV2Transport(array $config)\n    {\n        $config = array_merge(\n            $this->app['config']->get('services.ses', []),\n            ['version' => 'latest'],\n            $config\n        );\n\n        $config = Arr::except($config, ['transport']);\n\n        return new SesV2Transport(\n            new SesV2Client($this->addSesCredentials($config)),\n            $config['options'] ?? []\n        );\n    }\n\n    /**\n     * Add the SES credentials to the configuration array.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function addSesCredentials(array $config)\n    {\n        if (! empty($config['key']) && ! empty($config['secret'])) {\n            $config['credentials'] = Arr::only($config, ['key', 'secret']);\n\n            if (! empty($config['token'])) {\n                $config['credentials']['token'] = $config['token'];\n            }\n        }\n\n        return Arr::except($config, ['token']);\n    }\n\n    /**\n     * Create an instance of the Resend Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Mail\\Transport\\ResendTransport\n     */\n    protected function createResendTransport(array $config)\n    {\n        return new ResendTransport(\n            Resend::client($config['key'] ?? $this->app['config']->get('services.resend.key')),\n        );\n    }\n\n    /**\n     * Create an instance of the Symfony Mail Transport driver.\n     *\n     * @return \\Symfony\\Component\\Mailer\\Transport\\SendmailTransport\n     */\n    protected function createMailTransport()\n    {\n        return new SendmailTransport;\n    }\n\n    /**\n     * Create an instance of the Symfony Mailgun Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\TransportInterface\n     */\n    protected function createMailgunTransport(array $config)\n    {\n        $factory = new MailgunTransportFactory(null, $this->getHttpClient($config));\n\n        if (! isset($config['secret'])) {\n            $config = $this->app['config']->get('services.mailgun', []);\n        }\n\n        return $factory->create(new Dsn(\n            'mailgun+'.($config['scheme'] ?? 'https'),\n            $config['endpoint'] ?? 'default',\n            $config['secret'],\n            $config['domain']\n        ));\n    }\n\n    /**\n     * Create an instance of the Symfony Postmark Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Bridge\\Postmark\\Transport\\PostmarkApiTransport\n     */\n    protected function createPostmarkTransport(array $config)\n    {\n        $factory = new PostmarkTransportFactory(null, $this->getHttpClient($config));\n\n        $options = isset($config['message_stream_id'])\n            ? ['message_stream' => $config['message_stream_id']]\n            : [];\n\n        return $factory->create(new Dsn(\n            'postmark+api',\n            'default',\n            $config['token']\n                ?? $config['key']\n                ?? $this->app['config']->get('services.postmark.token')\n                ?? $this->app['config']->get('services.postmark.key'),\n            null,\n            null,\n            $options\n        ));\n    }\n\n    /**\n     * Create an instance of the Symfony Failover Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\FailoverTransport\n     */\n    protected function createFailoverTransport(array $config)\n    {\n        return $this->createRoundrobinTransportOfClass($config, FailoverTransport::class);\n    }\n\n    /**\n     * Create an instance of the Symfony Roundrobin Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport\n     */\n    protected function createRoundrobinTransport(array $config)\n    {\n        return $this->createRoundrobinTransportOfClass($config, RoundRobinTransport::class);\n    }\n\n    /**\n     * Create an instance of supplied class extending the Symfony Roundrobin Transport driver.\n     *\n     * @template TClass of \\Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport\n     *\n     * @param  array  $config\n     * @param  class-string<TClass>  $class\n     * @return TClass\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function createRoundrobinTransportOfClass(array $config, string $class)\n    {\n        $transports = [];\n\n        foreach ($config['mailers'] as $name) {\n            $config = $this->getConfig($name);\n\n            if (is_null($config)) {\n                throw new InvalidArgumentException(\"Mailer [{$name}] is not defined.\");\n            }\n\n            // Now, we will check if the \"driver\" key exists and if it does we will set\n            // the transport configuration parameter in order to offer compatibility\n            // with any Laravel <= 6.x application style mail configuration files.\n            $transports[] = $this->app['config']['mail.driver']\n                ? $this->createSymfonyTransport(array_merge($config, ['transport' => $name]))\n                : $this->createSymfonyTransport($config);\n        }\n\n        return new $class($transports, $config['retry_after'] ?? 60, $this->app->make(LoggerInterface::class));\n    }\n\n    /**\n     * Create an instance of the Log Transport driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Mail\\Transport\\LogTransport\n     */\n    protected function createLogTransport(array $config)\n    {\n        $logger = $this->app->make(LoggerInterface::class);\n\n        if ($logger instanceof LogManager) {\n            $logger = $logger->channel(\n                $config['channel'] ?? $this->app['config']->get('mail.log_channel')\n            );\n        }\n\n        return new LogTransport($logger);\n    }\n\n    /**\n     * Create an instance of the Array Transport Driver.\n     *\n     * @return \\Illuminate\\Mail\\Transport\\ArrayTransport\n     */\n    protected function createArrayTransport()\n    {\n        return new ArrayTransport;\n    }\n\n    /**\n     * Get a configured Symfony HTTP client instance.\n     *\n     * @return \\Symfony\\Contracts\\HttpClient\\HttpClientInterface|null\n     */\n    protected function getHttpClient(array $config)\n    {\n        if ($options = ($config['client'] ?? false)) {\n            $maxHostConnections = Arr::pull($options, 'max_host_connections', 6);\n            $maxPendingPushes = Arr::pull($options, 'max_pending_pushes', 50);\n\n            return HttpClient::create($options, $maxHostConnections, $maxPendingPushes);\n        }\n    }\n\n    /**\n     * Set a global address on the mailer by type.\n     *\n     * @param  \\Illuminate\\Mail\\Mailer  $mailer\n     * @param  array  $config\n     * @param  string  $type\n     * @return void\n     */\n    protected function setGlobalAddress($mailer, array $config, string $type)\n    {\n        $address = Arr::get($config, $type, $this->app['config']['mail.'.$type]);\n\n        if (is_array($address) && isset($address['address'])) {\n            $mailer->{'always'.Str::studly($type)}($address['address'], $address['name']);\n        }\n    }\n\n    /**\n     * Get the mail connection configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function getConfig(string $name)\n    {\n        // Here we will check if the \"driver\" key exists and if it does we will use\n        // the entire mail configuration file as the \"driver\" config in order to\n        // provide \"BC\" for any Laravel <= 6.x style mail configuration files.\n        $config = $this->app['config']['mail.driver']\n            ? $this->app['config']['mail']\n            : $this->app['config'][\"mail.mailers.{$name}\"];\n\n        if (isset($config['url'])) {\n            $config = array_merge($config, (new ConfigurationUrlParser)->parseConfiguration($config));\n\n            $config['transport'] = Arr::pull($config, 'driver');\n        }\n\n        return $config;\n    }\n\n    /**\n     * Get the default mail driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        // Here we will check if the \"driver\" key exists and if it does we will use\n        // that as the default driver in order to provide support for old styles\n        // of the Laravel mail configuration file for backwards compatibility.\n        return $this->app['config']['mail.driver'] ??\n            $this->app['config']['mail.default'];\n    }\n\n    /**\n     * Set the default mail driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver(string $name)\n    {\n        if ($this->app['config']['mail.driver']) {\n            $this->app['config']['mail.driver'] = $name;\n        }\n\n        $this->app['config']['mail.default'] = $name;\n    }\n\n    /**\n     * Disconnect the given mailer and remove from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        unset($this->mailers[$name]);\n    }\n\n    /**\n     * Register a custom transport creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the application instance used by the manager.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getApplication()\n    {\n        return $this->app;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Forget all of the resolved mailer instances.\n     *\n     * @return $this\n     */\n    public function forgetMailers()\n    {\n        $this->mailers = [];\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->mailer()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/MailServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass MailServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerIlluminateMailer();\n        $this->registerMarkdownRenderer();\n    }\n\n    /**\n     * Register the Illuminate mailer instance.\n     *\n     * @return void\n     */\n    protected function registerIlluminateMailer()\n    {\n        $this->app->singleton('mail.manager', function ($app) {\n            return new MailManager($app);\n        });\n\n        $this->app->bind('mailer', function ($app) {\n            return $app->make('mail.manager')->mailer();\n        });\n    }\n\n    /**\n     * Register the Markdown renderer instance.\n     *\n     * @return void\n     */\n    protected function registerMarkdownRenderer()\n    {\n        if ($this->app->runningInConsole()) {\n            $this->publishes([\n                __DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/mail'),\n            ], 'laravel-mail');\n        }\n\n        $this->app->singleton(Markdown::class, function ($app) {\n            $config = $app->make('config');\n\n            return new Markdown($app->make('view'), [\n                'theme' => $config->get('mail.markdown.theme', 'default'),\n                'paths' => $config->get('mail.markdown.paths', []),\n                'extensions' => $config->get('mail.markdown.extensions', []),\n            ]);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            'mail.manager',\n            'mailer',\n            Markdown::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailable.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Config\\Repository as ConfigRepository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Filesystem\\Factory as FilesystemFactory;\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Contracts\\Mail\\Factory as MailFactory;\nuse Illuminate\\Contracts\\Mail\\Mailable as MailableContract;\nuse Illuminate\\Contracts\\Queue\\Factory as Queue;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\Support\\Renderable;\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\EncodedHtmlString;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Localizable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Illuminate\\Testing\\Constraints\\SeeInOrder;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse ReflectionClass;\nuse ReflectionProperty;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mailer\\Header\\TagHeader;\nuse Symfony\\Component\\Mime\\Address;\n\nclass Mailable implements MailableContract, Renderable\n{\n    use Conditionable, ForwardsCalls, Localizable, Tappable, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The locale of the message.\n     *\n     * @var string\n     */\n    public $locale;\n\n    /**\n     * The person the message is from.\n     *\n     * @var array\n     */\n    public $from = [];\n\n    /**\n     * The \"to\" recipients of the message.\n     *\n     * @var array\n     */\n    public $to = [];\n\n    /**\n     * The \"cc\" recipients of the message.\n     *\n     * @var array\n     */\n    public $cc = [];\n\n    /**\n     * The \"bcc\" recipients of the message.\n     *\n     * @var array\n     */\n    public $bcc = [];\n\n    /**\n     * The \"reply to\" recipients of the message.\n     *\n     * @var array\n     */\n    public $replyTo = [];\n\n    /**\n     * The subject of the message.\n     *\n     * @var string\n     */\n    public $subject;\n\n    /**\n     * The Markdown template for the message (if applicable).\n     *\n     * @var string\n     */\n    public $markdown;\n\n    /**\n     * The HTML to use for the message.\n     *\n     * @var string\n     */\n    protected $html;\n\n    /**\n     * The view to use for the message.\n     *\n     * @var string\n     */\n    public $view;\n\n    /**\n     * The plain text view to use for the message.\n     *\n     * @var string\n     */\n    public $textView;\n\n    /**\n     * The view data for the message.\n     *\n     * @var array\n     */\n    public $viewData = [];\n\n    /**\n     * The attachments for the message.\n     *\n     * @var array\n     */\n    public $attachments = [];\n\n    /**\n     * The raw attachments for the message.\n     *\n     * @var array\n     */\n    public $rawAttachments = [];\n\n    /**\n     * The attachments from a storage disk.\n     *\n     * @var array\n     */\n    public $diskAttachments = [];\n\n    /**\n     * The tags for the message.\n     *\n     * @var array\n     */\n    protected $tags = [];\n\n    /**\n     * The metadata for the message.\n     *\n     * @var array\n     */\n    protected $metadata = [];\n\n    /**\n     * The callbacks for the message.\n     *\n     * @var array\n     */\n    public $callbacks = [];\n\n    /**\n     * The name of the theme that should be used when formatting the message.\n     *\n     * @var string|null\n     */\n    public $theme;\n\n    /**\n     * The name of the mailer that should send the message.\n     *\n     * @var string\n     */\n    public $mailer;\n\n    /**\n     * The rendered mailable views for testing / assertions.\n     *\n     * @var array\n     */\n    protected $assertionableRenderStrings;\n\n    /**\n     * The callback that should be invoked while building the view data.\n     *\n     * @var callable\n     */\n    public static $viewDataCallback;\n\n    /**\n     * Send the message using the given mailer.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Factory|\\Illuminate\\Contracts\\Mail\\Mailer  $mailer\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send($mailer)\n    {\n        return $this->withLocale($this->locale, function () use ($mailer) {\n            $this->prepareMailableForDelivery();\n\n            $mailer = $mailer instanceof MailFactory\n                ? $mailer->mailer($this->mailer)\n                : $mailer;\n\n            return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) {\n                $this->buildFrom($message)\n                    ->buildRecipients($message)\n                    ->buildSubject($message)\n                    ->buildTags($message)\n                    ->buildMetadata($message)\n                    ->runCallbacks($message)\n                    ->buildAttachments($message);\n            });\n        });\n    }\n\n    /**\n     * Queue the message for sending.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     * @return mixed\n     */\n    public function queue(Queue $queue)\n    {\n        if (isset($this->delay)) {\n            return $this->later($this->delay, $queue);\n        }\n\n        $connection = property_exists($this, 'connection') ? $this->connection : null;\n\n        if (is_null($connection) && method_exists($queue, 'resolveConnectionFromQueueRoute')) {\n            $connection = $queue->resolveConnectionFromQueueRoute($this);\n        }\n\n        $queueName = property_exists($this, 'queue')\n            ? $this->queue\n            : null;\n\n        if (is_null($queueName) && method_exists($queue, 'resolveQueueFromQueueRoute')) {\n            $queueName = $queue->resolveQueueFromQueueRoute($this);\n        }\n\n        return $queue->connection($connection)->pushOn(\n            $queueName ?: null, $this->newQueuedJob()\n        );\n    }\n\n    /**\n     * Deliver the queued message after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     * @return mixed\n     */\n    public function later($delay, Queue $queue)\n    {\n        $connection = property_exists($this, 'connection') ? $this->connection : null;\n\n        $queueName = property_exists($this, 'queue')\n            ? $this->queue\n            : null;\n\n        if (is_null($connection) && method_exists($queue, 'resolveConnectionFromQueueRoute')) {\n            $connection = $queue->resolveConnectionFromQueueRoute($this);\n        }\n\n        if (is_null($queueName) && method_exists($queue, 'resolveQueueFromQueueRoute')) {\n            $queueName = $queue->resolveQueueFromQueueRoute($this);\n        }\n\n        $job = $this->newQueuedJob();\n\n        $job->delay($delay);\n\n        return $queue->connection($connection)->laterOn(\n            $queueName ?: null, $delay, $job\n        );\n    }\n\n    /**\n     * Make the queued mailable job instance.\n     *\n     * @return mixed\n     */\n    protected function newQueuedJob()\n    {\n        $messageGroup = $this->messageGroup ?? (method_exists($this, 'messageGroup') ? $this->messageGroup() : null);\n\n        $deduplicator = $this->deduplicator ?? (method_exists($this, 'deduplicationId') ? $this->deduplicationId(...) : null);\n\n        return Container::getInstance()->make(SendQueuedMailable::class, ['mailable' => $this])\n            ->onGroup($messageGroup)\n            ->withDeduplicator($deduplicator)\n            ->through(array_merge(\n                method_exists($this, 'middleware') ? $this->middleware() : [],\n                $this->middleware ?? []\n            ));\n    }\n\n    /**\n     * Render the mailable into a view.\n     *\n     * @return string\n     *\n     * @throws \\ReflectionException\n     */\n    public function render()\n    {\n        return $this->withLocale($this->locale, function () {\n            $this->prepareMailableForDelivery();\n\n            return Container::getInstance()->make('mailer')->render(\n                $this->buildView(), $this->buildViewData()\n            );\n        });\n    }\n\n    /**\n     * Build the view for the message.\n     *\n     * @return array|string\n     *\n     * @throws \\ReflectionException\n     */\n    protected function buildView()\n    {\n        if (isset($this->html)) {\n            return array_filter([\n                'html' => new HtmlString($this->html),\n                'text' => $this->textView ?? null,\n            ]);\n        }\n\n        if (isset($this->markdown)) {\n            return $this->buildMarkdownView();\n        }\n\n        if (isset($this->view, $this->textView)) {\n            return [$this->view, $this->textView];\n        } elseif (isset($this->textView)) {\n            return ['text' => $this->textView];\n        }\n\n        return $this->view;\n    }\n\n    /**\n     * Build the Markdown view for the message.\n     *\n     * @return array\n     *\n     * @throws \\ReflectionException\n     */\n    protected function buildMarkdownView()\n    {\n        $data = $this->buildViewData();\n\n        return [\n            'html' => $this->buildMarkdownHtml($data),\n            'text' => $this->buildMarkdownText($data),\n        ];\n    }\n\n    /**\n     * Build the view data for the message.\n     *\n     * @return array\n     *\n     * @throws \\ReflectionException\n     */\n    public function buildViewData()\n    {\n        $data = $this->viewData;\n\n        if (static::$viewDataCallback) {\n            $data = array_merge($data, call_user_func(static::$viewDataCallback, $this));\n        }\n\n        foreach ((new ReflectionClass($this))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {\n            if ($property->isInitialized($this) && $property->getDeclaringClass()->getName() !== self::class) {\n                $data[$property->getName()] = $property->getValue($this);\n            }\n        }\n\n        return array_merge($data, $this->additionalMessageData());\n    }\n\n    /**\n     * Get additional meta-data to pass along with the view data.\n     *\n     * @return array<string, mixed>\n     */\n    protected function additionalMessageData(): array\n    {\n        return [\n            '__laravel_mailable' => get_class($this),\n        ];\n    }\n\n    /**\n     * Build the HTML view for a Markdown message.\n     *\n     * @param  array  $viewData\n     * @return \\Closure\n     */\n    protected function buildMarkdownHtml($viewData)\n    {\n        return fn ($data) => $this->markdownRenderer()->render(\n            $this->markdown,\n            array_merge($data, $viewData),\n        );\n    }\n\n    /**\n     * Build the text view for a Markdown message.\n     *\n     * @param  array  $viewData\n     * @return \\Closure\n     */\n    protected function buildMarkdownText($viewData)\n    {\n        return function ($data) use ($viewData) {\n            if (isset($data['message'])) {\n                $data = array_merge($data, [\n                    'message' => new TextMessage($data['message']),\n                ]);\n            }\n\n            return $this->textView ?? $this->markdownRenderer()->renderText(\n                $this->markdown,\n                array_merge($data, $viewData)\n            );\n        };\n    }\n\n    /**\n     * Resolves a Markdown instance with the mail's theme.\n     *\n     * @return \\Illuminate\\Mail\\Markdown\n     */\n    protected function markdownRenderer()\n    {\n        return tap(Container::getInstance()->make(Markdown::class), function ($markdown) {\n            $markdown->theme($this->theme ?: Container::getInstance()->get(ConfigRepository::class)->get(\n                'mail.markdown.theme', 'default')\n            );\n        });\n    }\n\n    /**\n     * Add the sender to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildFrom($message)\n    {\n        if (! empty($this->from)) {\n            $message->from($this->from[0]['address'], $this->from[0]['name']);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add all of the recipients to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildRecipients($message)\n    {\n        foreach (['to', 'cc', 'bcc', 'replyTo'] as $type) {\n            foreach ($this->{$type} as $recipient) {\n                $message->{$type}($recipient['address'], $recipient['name']);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the subject for the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildSubject($message)\n    {\n        if ($this->subject) {\n            $message->subject($this->subject);\n        } else {\n            $message->subject(Str::title(Str::snake(class_basename($this), ' ')));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add all of the attachments to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildAttachments($message)\n    {\n        foreach ($this->attachments as $attachment) {\n            $message->attach($attachment['file'], $attachment['options']);\n        }\n\n        foreach ($this->rawAttachments as $attachment) {\n            $message->attachData(\n                $attachment['data'], $attachment['name'], $attachment['options']\n            );\n        }\n\n        $this->buildDiskAttachments($message);\n\n        return $this;\n    }\n\n    /**\n     * Add all of the disk attachments to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return void\n     */\n    protected function buildDiskAttachments($message)\n    {\n        foreach ($this->diskAttachments as $attachment) {\n            $storage = Container::getInstance()->make(\n                FilesystemFactory::class\n            )->disk($attachment['disk']);\n\n            $message->attachData(\n                $storage->get($attachment['path']),\n                $attachment['name'] ?? basename($attachment['path']),\n                array_merge(['mime' => $storage->mimeType($attachment['path'])], $attachment['options'])\n            );\n        }\n    }\n\n    /**\n     * Add all defined tags to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildTags($message)\n    {\n        if ($this->tags) {\n            foreach ($this->tags as $tag) {\n                $message->getHeaders()->add(new TagHeader($tag));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add all defined metadata to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function buildMetadata($message)\n    {\n        if ($this->metadata) {\n            foreach ($this->metadata as $key => $value) {\n                $message->getHeaders()->add(new MetadataHeader($key, $value));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Run the callbacks for the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return $this\n     */\n    protected function runCallbacks($message)\n    {\n        foreach ($this->callbacks as $callback) {\n            $callback($message->getSymfonyMessage());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the locale of the message.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale)\n    {\n        $this->locale = $locale;\n\n        return $this;\n    }\n\n    /**\n     * Set the priority of this message.\n     *\n     * The value is an integer where 1 is the highest priority and 5 is the lowest.\n     *\n     * @param  int  $level\n     * @return $this\n     */\n    public function priority($level = 3)\n    {\n        $this->callbacks[] = function ($message) use ($level) {\n            $message->priority($level);\n        };\n\n        return $this;\n    }\n\n    /**\n     * Set the sender of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function from($address, $name = null)\n    {\n        return $this->setAddress($address, $name, 'from');\n    }\n\n    /**\n     * Determine if the given recipient is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasFrom($address, $name = null)\n    {\n        return $this->hasRecipient($address, $name, 'from');\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function to($address, $name = null)\n    {\n        if (! $this->locale && $address instanceof HasLocalePreference) {\n            $this->locale($address->preferredLocale());\n        }\n\n        return $this->setAddress($address, $name, 'to');\n    }\n\n    /**\n     * Determine if the given recipient is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasTo($address, $name = null)\n    {\n        return $this->hasRecipient($address, $name, 'to');\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function cc($address, $name = null)\n    {\n        return $this->setAddress($address, $name, 'cc');\n    }\n\n    /**\n     * Determine if the given recipient is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasCc($address, $name = null)\n    {\n        return $this->hasRecipient($address, $name, 'cc');\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function bcc($address, $name = null)\n    {\n        return $this->setAddress($address, $name, 'bcc');\n    }\n\n    /**\n     * Determine if the given recipient is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasBcc($address, $name = null)\n    {\n        return $this->hasRecipient($address, $name, 'bcc');\n    }\n\n    /**\n     * Set the \"reply to\" address of the message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function replyTo($address, $name = null)\n    {\n        return $this->setAddress($address, $name, 'replyTo');\n    }\n\n    /**\n     * Determine if the given replyTo is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasReplyTo($address, $name = null)\n    {\n        return $this->hasRecipient($address, $name, 'replyTo');\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * All recipients are stored internally as [['name' => ?, 'address' => ?]]\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @param  string  $property\n     * @return $this\n     */\n    protected function setAddress($address, $name = null, $property = 'to')\n    {\n        if (empty($address)) {\n            return $this;\n        }\n\n        foreach ($this->addressesToArray($address, $name) as $recipient) {\n            $recipient = $this->normalizeRecipient($recipient);\n\n            $this->{$property}[] = [\n                'name' => $recipient->name ?? null,\n                'address' => $recipient->email,\n            ];\n        }\n\n        $this->{$property} = (new Collection($this->{$property}))\n            ->reverse()\n            ->unique('address')\n            ->reverse()\n            ->values()\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Convert the given recipient arguments to an array.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return array\n     */\n    protected function addressesToArray($address, $name)\n    {\n        if (! is_array($address) && ! $address instanceof Collection) {\n            $address = is_string($name) ? [['name' => $name, 'email' => $address]] : [$address];\n        }\n\n        return $address;\n    }\n\n    /**\n     * Convert the given recipient into an object.\n     *\n     * @param  mixed  $recipient\n     * @return object\n     */\n    protected function normalizeRecipient($recipient)\n    {\n        if (is_array($recipient)) {\n            if (array_values($recipient) === $recipient) {\n                return (object) array_map(function ($email) {\n                    return compact('email');\n                }, $recipient);\n            }\n\n            return (object) $recipient;\n        } elseif (is_string($recipient)) {\n            return (object) ['email' => $recipient];\n        } elseif ($recipient instanceof Address) {\n            return (object) ['email' => $recipient->getAddress(), 'name' => $recipient->getName()];\n        } elseif ($recipient instanceof Mailables\\Address) {\n            return (object) ['email' => $recipient->address, 'name' => $recipient->name];\n        }\n\n        return $recipient;\n    }\n\n    /**\n     * Determine if the given recipient is set on the mailable.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @param  string  $property\n     * @return bool\n     */\n    protected function hasRecipient($address, $name = null, $property = 'to')\n    {\n        if (empty($address)) {\n            return false;\n        }\n\n        $expected = $this->normalizeRecipient(\n            $this->addressesToArray($address, $name)[0]\n        );\n\n        $expected = [\n            'name' => $expected->name ?? null,\n            'address' => $expected->email,\n        ];\n\n        if ($this->hasEnvelopeRecipient($expected['address'], $expected['name'], $property)) {\n            return true;\n        }\n\n        return (new Collection($this->{$property}))->contains(function ($actual) use ($expected) {\n            if (! isset($expected['name'])) {\n                return $actual['address'] == $expected['address'];\n            }\n\n            return $actual == $expected;\n        });\n    }\n\n    /**\n     * Determine if the mailable \"envelope\" method defines a recipient.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @param  string  $property\n     * @return bool\n     */\n    private function hasEnvelopeRecipient($address, $name, $property)\n    {\n        return method_exists($this, 'envelope') && match ($property) {\n            'from' => $this->envelope()->isFrom($address, $name),\n            'to' => $this->envelope()->hasTo($address, $name),\n            'cc' => $this->envelope()->hasCc($address, $name),\n            'bcc' => $this->envelope()->hasBcc($address, $name),\n            'replyTo' => $this->envelope()->hasReplyTo($address, $name),\n        };\n    }\n\n    /**\n     * Set the subject of the message.\n     *\n     * @param  string  $subject\n     * @return $this\n     */\n    public function subject($subject)\n    {\n        $this->subject = $subject;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given subject.\n     *\n     * @param  string  $subject\n     * @return bool\n     */\n    public function hasSubject($subject)\n    {\n        return $this->subject === $subject ||\n               (method_exists($this, 'envelope') && $this->envelope()->hasSubject($subject));\n    }\n\n    /**\n     * Set the Markdown template for the message.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @return $this\n     */\n    public function markdown($view, array $data = [])\n    {\n        $this->markdown = $view;\n        $this->viewData = array_merge($this->viewData, $data);\n\n        return $this;\n    }\n\n    /**\n     * Set the view and view data for the message.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @return $this\n     */\n    public function view($view, array $data = [])\n    {\n        $this->view = $view;\n        $this->viewData = array_merge($this->viewData, $data);\n\n        return $this;\n    }\n\n    /**\n     * Set the rendered HTML content for the message.\n     *\n     * @param  string  $html\n     * @return $this\n     */\n    public function html($html)\n    {\n        $this->html = $html;\n\n        return $this;\n    }\n\n    /**\n     * Set the plain text view for the message.\n     *\n     * @param  string  $textView\n     * @param  array  $data\n     * @return $this\n     */\n    public function text($textView, array $data = [])\n    {\n        $this->textView = $textView;\n        $this->viewData = array_merge($this->viewData, $data);\n\n        return $this;\n    }\n\n    /**\n     * Set the view data for the message.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function with($key, $value = null)\n    {\n        if (is_array($key)) {\n            $this->viewData = array_merge($this->viewData, $key);\n        } else {\n            $this->viewData[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Attach a file to the message.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @param  array  $options\n     * @return $this\n     */\n    public function attach($file, array $options = [])\n    {\n        if ($file instanceof Attachable) {\n            $file = $file->toMailAttachment();\n        }\n\n        if ($file instanceof Attachment) {\n            return $file->attachTo($this, $options);\n        }\n\n        $this->attachments = (new Collection($this->attachments))\n            ->push(compact('file', 'options'))\n            ->unique('file')\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Attach multiple files to the message.\n     *\n     * @param  array  $files\n     * @return $this\n     */\n    public function attachMany($files)\n    {\n        foreach ($files as $file => $options) {\n            if (is_int($file)) {\n                $this->attach($options);\n            } else {\n                $this->attach($file, $options);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given attachment.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @param  array  $options\n     * @return bool\n     */\n    public function hasAttachment($file, array $options = [])\n    {\n        if ($file instanceof Attachable) {\n            $file = $file->toMailAttachment();\n        }\n\n        if ($file instanceof Attachment && $this->hasEnvelopeAttachment($file, $options)) {\n            return true;\n        }\n\n        if ($file instanceof Attachment) {\n            $parts = $file->attachWith(\n                fn ($path) => [$path, [\n                    'as' => $options['as'] ?? $file->as,\n                    'mime' => $options['mime'] ?? $file->mime,\n                ]],\n                fn ($data) => $this->hasAttachedData($data(), $options['as'] ?? $file->as, ['mime' => $options['mime'] ?? $file->mime])\n            );\n\n            if ($parts === true) {\n                return true;\n            }\n\n            [$file, $options] = $parts === false\n                ? [null, []]\n                : $parts;\n        }\n\n        return (new Collection($this->attachments))->contains(\n            fn ($attachment) => $attachment['file'] === $file && array_filter($attachment['options']) === array_filter($options)\n        );\n    }\n\n    /**\n     * Determine if the mailable has the given envelope attachment.\n     *\n     * @param  \\Illuminate\\Mail\\Attachment  $attachment\n     * @param  array  $options\n     * @return bool\n     */\n    private function hasEnvelopeAttachment($attachment, $options = [])\n    {\n        if (! method_exists($this, 'envelope')) {\n            return false;\n        }\n\n        $attachments = $this->attachments();\n\n        return (new Collection(is_object($attachments) ? [$attachments] : $attachments))\n            ->map(fn ($attached) => $attached instanceof Attachable ? $attached->toMailAttachment() : $attached)\n            ->contains(fn ($attached) => $attached->isEquivalent($attachment, $options));\n    }\n\n    /**\n     * Attach a file to the message from storage.\n     *\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function attachFromStorage($path, $name = null, array $options = [])\n    {\n        return $this->attachFromStorageDisk(null, $path, $name, $options);\n    }\n\n    /**\n     * Attach a file to the message from storage.\n     *\n     * @param  string  $disk\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function attachFromStorageDisk($disk, $path, $name = null, array $options = [])\n    {\n        $this->diskAttachments = (new Collection($this->diskAttachments))->push([\n            'disk' => $disk,\n            'path' => $path,\n            'name' => $name ?? basename($path),\n            'options' => $options,\n        ])\n            ->unique(fn ($file) => $file['name'].$file['disk'].$file['path'])\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given attachment from storage.\n     *\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return bool\n     */\n    public function hasAttachmentFromStorage($path, $name = null, array $options = [])\n    {\n        return $this->hasAttachmentFromStorageDisk(null, $path, $name, $options);\n    }\n\n    /**\n     * Determine if the mailable has the given attachment from a specific storage disk.\n     *\n     * @param  string  $disk\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return bool\n     */\n    public function hasAttachmentFromStorageDisk($disk, $path, $name = null, array $options = [])\n    {\n        return (new Collection($this->diskAttachments))->contains(\n            fn ($attachment) => $attachment['disk'] === $disk\n                && $attachment['path'] === $path\n                && $attachment['name'] === ($name ?? basename($path))\n                && $attachment['options'] === $options\n        );\n    }\n\n    /**\n     * Attach in-memory data as an attachment.\n     *\n     * @param  string  $data\n     * @param  string  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function attachData($data, $name, array $options = [])\n    {\n        $this->rawAttachments = (new Collection($this->rawAttachments))\n            ->push(compact('data', 'name', 'options'))\n            ->unique(fn ($file) => $file['name'].$file['data'])\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given data as an attachment.\n     *\n     * @param  string  $data\n     * @param  string  $name\n     * @param  array  $options\n     * @return bool\n     */\n    public function hasAttachedData($data, $name, array $options = [])\n    {\n        return (new Collection($this->rawAttachments))->contains(\n            fn ($attachment) => $attachment['data'] === $data\n                && $attachment['name'] === $name\n                && array_filter($attachment['options']) === array_filter($options)\n        );\n    }\n\n    /**\n     * Add a tag header to the message when supported by the underlying transport.\n     *\n     * @param  string  $value\n     * @return $this\n     */\n    public function tag($value)\n    {\n        $this->tags[] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given tag.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    public function hasTag($value)\n    {\n        return in_array($value, $this->tags) ||\n               (method_exists($this, 'envelope') && in_array($value, $this->envelope()->tags));\n    }\n\n    /**\n     * Add a metadata header to the message when supported by the underlying transport.\n     *\n     * @param  array|string  $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function metadata($key, $value = null)\n    {\n        if (is_array($key)) {\n            $this->metadata = array_merge($this->metadata, $key);\n        } else {\n            $this->metadata[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the mailable has the given metadata.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return bool\n     */\n    public function hasMetadata($key, $value)\n    {\n        return (isset($this->metadata[$key]) && $this->metadata[$key] === $value) ||\n               (method_exists($this, 'envelope') && $this->envelope()->hasMetadata($key, $value));\n    }\n\n    /**\n     * Assert that the mailable is from the given address.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertFrom($address, $name = null)\n    {\n        $this->renderForAssertions();\n\n        $expected = $this->formatAssertionRecipient($address, $name);\n        $actual = $this->formatActualRecipients($this->from);\n\n        PHPUnit::assertTrue(\n            $this->hasFrom($address, $name),\n            \"Email was not from expected address.\\nExpected: [{$expected}]\\nActual: [{$actual}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given recipient.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertTo($address, $name = null)\n    {\n        $this->renderForAssertions();\n\n        $expected = $this->formatAssertionRecipient($address, $name);\n        $actual = $this->formatActualRecipients($this->to);\n\n        PHPUnit::assertTrue(\n            $this->hasTo($address, $name),\n            \"Did not see expected recipient in email 'to' recipients.\\nExpected: [{$expected}]\\nActual: [{$actual}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given recipient.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertHasTo($address, $name = null)\n    {\n        return $this->assertTo($address, $name);\n    }\n\n    /**\n     * Assert that the mailable has the given recipient.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertHasCc($address, $name = null)\n    {\n        $this->renderForAssertions();\n\n        $expected = $this->formatAssertionRecipient($address, $name);\n        $actual = $this->formatActualRecipients($this->cc);\n\n        PHPUnit::assertTrue(\n            $this->hasCc($address, $name),\n            \"Did not see expected recipient in email 'cc' recipients.\\nExpected: [{$expected}]\\nActual: [{$actual}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given recipient.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertHasBcc($address, $name = null)\n    {\n        $this->renderForAssertions();\n\n        $expected = $this->formatAssertionRecipient($address, $name);\n        $actual = $this->formatActualRecipients($this->bcc);\n\n        PHPUnit::assertTrue(\n            $this->hasBcc($address, $name),\n            \"Did not see expected recipient in email 'bcc' recipients.\\nExpected: [{$expected}]\\nActual: [{$actual}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given \"reply to\" address.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function assertHasReplyTo($address, $name = null)\n    {\n        $this->renderForAssertions();\n\n        $expected = $this->formatAssertionRecipient($address, $name);\n        $actual = $this->formatActualRecipients($this->replyTo);\n\n        PHPUnit::assertTrue(\n            $this->hasReplyTo($address, $name),\n            \"Did not see expected address as email 'reply to' recipient.\\nExpected: [{$expected}]\\nActual: [{$actual}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Format the mailable recipient for display in an assertion message.\n     *\n     * @param  object|array|string  $address\n     * @param  string|null  $name\n     * @return string\n     */\n    private function formatAssertionRecipient($address, $name = null)\n    {\n        if (! is_string($address)) {\n            $address = json_encode($address);\n        }\n\n        if (filled($name)) {\n            $address .= ' ('.$name.')';\n        }\n\n        return $address;\n    }\n\n    /**\n     * Format actual recipients for display in assertion messages.\n     *\n     * @param  array  $recipients\n     * @return string\n     */\n    private function formatActualRecipients($recipients)\n    {\n        if (empty($recipients)) {\n            return 'none';\n        }\n\n        return (new Collection($recipients))->map(function ($recipient) {\n            $formatted = $recipient['address'];\n            if (! empty($recipient['name'])) {\n                $formatted .= ' ('.$recipient['name'].')';\n            }\n\n            return $formatted;\n        })->implode(', ');\n    }\n\n    /**\n     * Assert that the mailable has the given subject.\n     *\n     * @param  string  $subject\n     * @return $this\n     */\n    public function assertHasSubject($subject)\n    {\n        $this->renderForAssertions();\n\n        $actualSubject = $this->subject ?: (method_exists($this, 'envelope') ? $this->envelope()->subject : null) ?: Str::title(Str::snake(class_basename($this), ' '));\n\n        PHPUnit::assertTrue(\n            $this->hasSubject($subject),\n            \"Email subject does not match expected value.\\nExpected: [{$subject}]\\nActual: [{$actualSubject}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text is present in the HTML email body.\n     *\n     * @param  string  $string\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeInHtml($string, $escape = true)\n    {\n        $string = $escape ? EncodedHtmlString::convert($string, withQuote: true) : $string;\n\n        [$html] = $this->renderForAssertions();\n\n        PHPUnit::assertStringContainsString(\n            $string,\n            $html,\n            \"Did not see expected text [{$string}] within email body.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text is not present in the HTML email body.\n     *\n     * @param  string  $string\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSeeInHtml($string, $escape = true)\n    {\n        $string = $escape ? EncodedHtmlString::convert($string, withQuote: true) : $string;\n\n        [$html] = $this->renderForAssertions();\n\n        PHPUnit::assertStringNotContainsString(\n            $string,\n            $html,\n            \"Saw unexpected text [{$string}] within email body.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text strings are present in order in the HTML email body.\n     *\n     * @param  array  $strings\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeInOrderInHtml($strings, $escape = true)\n    {\n        $strings = $escape ? array_map(function ($string) {\n            return EncodedHtmlString::convert($string, withQuote: true);\n        }, $strings) : $strings;\n\n        [$html] = $this->renderForAssertions();\n\n        PHPUnit::assertThat($strings, new SeeInOrder($html));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text is present in the plain-text email body.\n     *\n     * @param  string  $string\n     * @return $this\n     */\n    public function assertSeeInText($string)\n    {\n        [, $text] = $this->renderForAssertions();\n\n        PHPUnit::assertStringContainsString(\n            $string,\n            $text,\n            \"Did not see expected text [{$string}] within text email body.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text is not present in the plain-text email body.\n     *\n     * @param  string  $string\n     * @return $this\n     */\n    public function assertDontSeeInText($string)\n    {\n        [, $text] = $this->renderForAssertions();\n\n        PHPUnit::assertStringNotContainsString(\n            $string,\n            $text,\n            \"Saw unexpected text [{$string}] within text email body.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given text strings are present in order in the plain-text email body.\n     *\n     * @param  array  $strings\n     * @return $this\n     */\n    public function assertSeeInOrderInText($strings)\n    {\n        [, $text] = $this->renderForAssertions();\n\n        PHPUnit::assertThat($strings, new SeeInOrder($text));\n\n        return $this;\n    }\n\n    /**\n     * Assert the mailable has the given attachment.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @param  array  $options\n     * @return $this\n     */\n    public function assertHasAttachment($file, array $options = [])\n    {\n        $this->renderForAssertions();\n\n        PHPUnit::assertTrue(\n            $this->hasAttachment($file, $options),\n            'Did not find the expected attachment.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the mailable has the given data as an attachment.\n     *\n     * @param  string  $data\n     * @param  string  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function assertHasAttachedData($data, $name, array $options = [])\n    {\n        $this->renderForAssertions();\n\n        PHPUnit::assertTrue(\n            $this->hasAttachedData($data, $name, $options),\n            'Did not find the expected attachment.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the mailable has the given attachment from storage.\n     *\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function assertHasAttachmentFromStorage($path, $name = null, array $options = [])\n    {\n        $this->renderForAssertions();\n\n        PHPUnit::assertTrue(\n            $this->hasAttachmentFromStorage($path, $name, $options),\n            'Did not find the expected attachment.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the mailable has the given attachment from a specific storage disk.\n     *\n     * @param  string  $disk\n     * @param  string  $path\n     * @param  string|null  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function assertHasAttachmentFromStorageDisk($disk, $path, $name = null, array $options = [])\n    {\n        $this->renderForAssertions();\n\n        PHPUnit::assertTrue(\n            $this->hasAttachmentFromStorageDisk($disk, $path, $name, $options),\n            'Did not find the expected attachment.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given tag.\n     *\n     * @param  string  $tag\n     * @return $this\n     */\n    public function assertHasTag($tag)\n    {\n        $this->renderForAssertions();\n\n        $actualTags = method_exists($this, 'envelope') ? array_merge($this->tags, $this->envelope()->tags) : $this->tags;\n        $actualTagsString = empty($actualTags) ? 'none' : implode(', ', $actualTags);\n\n        PHPUnit::assertTrue(\n            $this->hasTag($tag),\n            \"Did not see expected tag in email tags.\\nExpected: [{$tag}]\\nActual: [{$actualTagsString}]\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the mailable has the given metadata.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return $this\n     */\n    public function assertHasMetadata($key, $value)\n    {\n        $this->renderForAssertions();\n\n        $actualMetadata = method_exists($this, 'envelope') ? array_merge($this->metadata, $this->envelope()->metadata) : $this->metadata;\n        $actualValue = $actualMetadata[$key] ?? null;\n        $actualString = $actualValue !== null ? \"[{$key}] => [{$actualValue}]\" : \"key [{$key}] not found\";\n\n        PHPUnit::assertTrue(\n            $this->hasMetadata($key, $value),\n            \"Email metadata does not match expected value.\\nExpected: [{$key}] => [{$value}]\\nActual: {$actualString}\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Render the HTML and plain-text version of the mailable into views for assertions.\n     *\n     * @return array\n     *\n     * @throws \\ReflectionException\n     */\n    protected function renderForAssertions()\n    {\n        if ($this->assertionableRenderStrings) {\n            return $this->assertionableRenderStrings;\n        }\n\n        return $this->assertionableRenderStrings = $this->withLocale($this->locale, function () {\n            $this->prepareMailableForDelivery();\n\n            $html = Container::getInstance()->make('mailer')->render(\n                $view = $this->buildView(), $this->buildViewData()\n            );\n\n            if (is_array($view) && isset($view[1])) {\n                $text = $view[1];\n            }\n\n            $text ??= $view['text'] ?? '';\n\n            if (! empty($text) && ! $text instanceof Htmlable) {\n                $text = Container::getInstance()->make('mailer')->render(\n                    $text, $this->buildViewData()\n                );\n            }\n\n            return [(string) $html, (string) $text];\n        });\n    }\n\n    /**\n     * Prepare the mailable instance for delivery.\n     *\n     * @return void\n     */\n    protected function prepareMailableForDelivery()\n    {\n        if (method_exists($this, 'build')) {\n            Container::getInstance()->call([$this, 'build']);\n        }\n\n        $this->ensureHeadersAreHydrated();\n        $this->ensureEnvelopeIsHydrated();\n        $this->ensureContentIsHydrated();\n        $this->ensureAttachmentsAreHydrated();\n    }\n\n    /**\n     * Ensure the mailable's headers are hydrated from the \"headers\" method.\n     *\n     * @return void\n     */\n    private function ensureHeadersAreHydrated()\n    {\n        if (! method_exists($this, 'headers')) {\n            return;\n        }\n\n        $headers = $this->headers();\n\n        $this->withSymfonyMessage(function ($message) use ($headers) {\n            if ($headers->messageId) {\n                $message->getHeaders()->addIdHeader('Message-Id', $headers->messageId);\n            }\n\n            if (count($headers->references) > 0) {\n                $message->getHeaders()->addTextHeader('References', $headers->referencesString());\n            }\n\n            foreach ($headers->text as $key => $value) {\n                $message->getHeaders()->addTextHeader($key, $value);\n            }\n        });\n    }\n\n    /**\n     * Ensure the mailable's \"envelope\" data is hydrated from the \"envelope\" method.\n     *\n     * @return void\n     */\n    private function ensureEnvelopeIsHydrated()\n    {\n        if (! method_exists($this, 'envelope')) {\n            return;\n        }\n\n        $envelope = $this->envelope();\n\n        if (isset($envelope->from)) {\n            $this->from($envelope->from->address, $envelope->from->name);\n        }\n\n        foreach (['to', 'cc', 'bcc', 'replyTo'] as $type) {\n            foreach ($envelope->{$type} as $address) {\n                $this->{$type}($address->address, $address->name);\n            }\n        }\n\n        if ($envelope->subject) {\n            $this->subject($envelope->subject);\n        }\n\n        foreach ($envelope->tags as $tag) {\n            $this->tag($tag);\n        }\n\n        foreach ($envelope->metadata as $key => $value) {\n            $this->metadata($key, $value);\n        }\n\n        foreach ($envelope->using as $callback) {\n            $this->withSymfonyMessage($callback);\n        }\n    }\n\n    /**\n     * Ensure the mailable's content is hydrated from the \"content\" method.\n     *\n     * @return void\n     */\n    private function ensureContentIsHydrated()\n    {\n        if (! method_exists($this, 'content')) {\n            return;\n        }\n\n        $content = $this->content();\n\n        if ($content->view) {\n            $this->view($content->view);\n        }\n\n        if ($content->html) {\n            $this->view($content->html);\n        }\n\n        if ($content->text) {\n            $this->text($content->text);\n        }\n\n        if ($content->markdown) {\n            $this->markdown($content->markdown);\n        }\n\n        if ($content->htmlString) {\n            $this->html($content->htmlString);\n        }\n\n        foreach ($content->with as $key => $value) {\n            $this->with($key, $value);\n        }\n    }\n\n    /**\n     * Ensure the mailable's attachments are hydrated from the \"attachments\" method.\n     *\n     * @return void\n     */\n    private function ensureAttachmentsAreHydrated()\n    {\n        if (! method_exists($this, 'attachments')) {\n            return;\n        }\n\n        $attachments = $this->attachments();\n\n        (new Collection(is_object($attachments) ? [$attachments] : $attachments))\n            ->each(function ($attachment) {\n                $this->attach($attachment);\n            });\n    }\n\n    /**\n     * Determine if the mailable will be sent by the given mailer.\n     *\n     * @param  string  $mailer\n     * @return bool\n     */\n    public function usesMailer($mailer)\n    {\n        return $this->mailer === $mailer;\n    }\n\n    /**\n     * Set the name of the mailer that should send the message.\n     *\n     * @param  string  $mailer\n     * @return $this\n     */\n    public function mailer($mailer)\n    {\n        $this->mailer = $mailer;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be called with the Symfony message instance.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function withSymfonyMessage($callback)\n    {\n        $this->callbacks[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be called while building the view data.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function buildViewDataUsing(callable $callback)\n    {\n        static::$viewDataCallback = $callback;\n    }\n\n    /**\n     * Dynamically bind parameters to the message.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return $this\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (str_starts_with($method, 'with')) {\n            return $this->with(Str::camel(substr($method, 4)), $parameters[0]);\n        }\n\n        static::throwBadMethodCallException($method);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailables/Address.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Mailables;\n\nclass Address\n{\n    /**\n     * The recipient's email address.\n     *\n     * @var string\n     */\n    public $address;\n\n    /**\n     * The recipient's name.\n     *\n     * @var string|null\n     */\n    public $name;\n\n    /**\n     * Create a new address instance.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     */\n    public function __construct(string $address, ?string $name = null)\n    {\n        $this->address = $address;\n        $this->name = $name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailables/Attachment.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Mailables;\n\nuse Illuminate\\Mail\\Attachment as BaseAttachment;\n\nclass Attachment extends BaseAttachment\n{\n    // Here for namespace consistency...\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailables/Content.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Mailables;\n\nuse Illuminate\\Support\\Traits\\Conditionable;\n\nclass Content\n{\n    use Conditionable;\n\n    /**\n     * The Blade view that should be rendered for the mailable.\n     *\n     * @var string|null\n     */\n    public $view;\n\n    /**\n     * The Blade view that should be rendered for the mailable.\n     *\n     * Alternative syntax for \"view\".\n     *\n     * @var string|null\n     */\n    public $html;\n\n    /**\n     * The Blade view that represents the text version of the message.\n     *\n     * @var string|null\n     */\n    public $text;\n\n    /**\n     * The Blade view that represents the Markdown version of the message.\n     *\n     * @var string|null\n     */\n    public $markdown;\n\n    /**\n     * The pre-rendered HTML of the message.\n     *\n     * @var string|null\n     */\n    public $htmlString;\n\n    /**\n     * The message's view data.\n     *\n     * @var array\n     */\n    public $with;\n\n    /**\n     * Create a new content definition.\n     *\n     * @param  string|null  $view\n     * @param  string|null  $html\n     * @param  string|null  $text\n     * @param  string|null  $markdown\n     * @param  array  $with\n     * @param  string|null  $htmlString\n     *\n     * @named-arguments-supported\n     */\n    public function __construct(?string $view = null, ?string $html = null, ?string $text = null, $markdown = null, array $with = [], ?string $htmlString = null)\n    {\n        $this->view = $view;\n        $this->html = $html;\n        $this->text = $text;\n        $this->markdown = $markdown;\n        $this->with = $with;\n        $this->htmlString = $htmlString;\n    }\n\n    /**\n     * Set the view for the message.\n     *\n     * @param  string  $view\n     * @return $this\n     */\n    public function view(string $view)\n    {\n        $this->view = $view;\n\n        return $this;\n    }\n\n    /**\n     * Set the view for the message.\n     *\n     * @param  string  $view\n     * @return $this\n     */\n    public function html(string $view)\n    {\n        return $this->view($view);\n    }\n\n    /**\n     * Set the plain text view for the message.\n     *\n     * @param  string  $view\n     * @return $this\n     */\n    public function text(string $view)\n    {\n        $this->text = $view;\n\n        return $this;\n    }\n\n    /**\n     * Set the Markdown view for the message.\n     *\n     * @param  string  $view\n     * @return $this\n     */\n    public function markdown(string $view)\n    {\n        $this->markdown = $view;\n\n        return $this;\n    }\n\n    /**\n     * Set the pre-rendered HTML for the message.\n     *\n     * @param  string  $html\n     * @return $this\n     */\n    public function htmlString(string $html)\n    {\n        $this->htmlString = $html;\n\n        return $this;\n    }\n\n    /**\n     * Add a piece of view data to the message.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function with($key, $value = null)\n    {\n        if (is_array($key)) {\n            $this->with = array_merge($this->with, $key);\n        } else {\n            $this->with[$key] = $value;\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailables/Envelope.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Mailables;\n\nuse Closure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\n\nclass Envelope\n{\n    use Conditionable;\n\n    /**\n     * The address sending the message.\n     *\n     * @var \\Illuminate\\Mail\\Mailables\\Address|string|null\n     */\n    public $from;\n\n    /**\n     * The recipients of the message.\n     *\n     * @var array\n     */\n    public $to;\n\n    /**\n     * The recipients receiving a copy of the message.\n     *\n     * @var array\n     */\n    public $cc;\n\n    /**\n     * The recipients receiving a blind copy of the message.\n     *\n     * @var array\n     */\n    public $bcc;\n\n    /**\n     * The recipients that should be replied to.\n     *\n     * @var array\n     */\n    public $replyTo;\n\n    /**\n     * The subject of the message.\n     *\n     * @var string|null\n     */\n    public $subject;\n\n    /**\n     * The message's tags.\n     *\n     * @var array\n     */\n    public $tags = [];\n\n    /**\n     * The message's metadata.\n     *\n     * @var array\n     */\n    public $metadata = [];\n\n    /**\n     * The message's Symfony Message customization callbacks.\n     *\n     * @var array\n     */\n    public $using = [];\n\n    /**\n     * Create a new message envelope instance.\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|string|null  $from\n     * @param  array<int, \\Illuminate\\Mail\\Mailables\\Address|string>  $to\n     * @param  array<int, \\Illuminate\\Mail\\Mailables\\Address|string>  $cc\n     * @param  array<int, \\Illuminate\\Mail\\Mailables\\Address|string>  $bcc\n     * @param  array<int, \\Illuminate\\Mail\\Mailables\\Address|string>  $replyTo\n     * @param  string|null  $subject\n     * @param  array  $tags\n     * @param  array  $metadata\n     * @param  \\Closure|array  $using\n     *\n     * @named-arguments-supported\n     */\n    public function __construct(Address|string|null $from = null, $to = [], $cc = [], $bcc = [], $replyTo = [], ?string $subject = null, array $tags = [], array $metadata = [], Closure|array $using = [])\n    {\n        $this->from = is_string($from) ? new Address($from) : $from;\n        $this->to = $this->normalizeAddresses($to);\n        $this->cc = $this->normalizeAddresses($cc);\n        $this->bcc = $this->normalizeAddresses($bcc);\n        $this->replyTo = $this->normalizeAddresses($replyTo);\n        $this->subject = $subject;\n        $this->tags = $tags;\n        $this->metadata = $metadata;\n        $this->using = Arr::wrap($using);\n    }\n\n    /**\n     * Normalize the given array of addresses.\n     *\n     * @param  array<int, \\Illuminate\\Mail\\Mailables\\Address|string>  $addresses\n     * @return array<int, \\Illuminate\\Mail\\Mailables\\Address>\n     */\n    protected function normalizeAddresses($addresses)\n    {\n        return (new Collection($addresses))\n            ->map(fn ($address) => is_string($address) ? new Address($address) : $address)\n            ->all();\n    }\n\n    /**\n     * Specify who the message will be \"from\".\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function from(Address|string $address, $name = null)\n    {\n        $this->from = is_string($address) ? new Address($address, $name) : $address;\n\n        return $this;\n    }\n\n    /**\n     * Add a \"to\" recipient to the message envelope.\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|array<int, \\Illuminate\\Mail\\Mailables\\Address|string>|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function to(Address|array|string $address, $name = null)\n    {\n        $this->to = array_merge($this->to, $this->normalizeAddresses(\n            is_string($name) ? [new Address($address, $name)] : Arr::wrap($address),\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Add a \"cc\" recipient to the message envelope.\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|array<int, \\Illuminate\\Mail\\Mailables\\Address|string>|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function cc(Address|array|string $address, $name = null)\n    {\n        $this->cc = array_merge($this->cc, $this->normalizeAddresses(\n            is_string($name) ? [new Address($address, $name)] : Arr::wrap($address),\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Add a \"bcc\" recipient to the message envelope.\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|array<int, \\Illuminate\\Mail\\Mailables\\Address|string>|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function bcc(Address|array|string $address, $name = null)\n    {\n        $this->bcc = array_merge($this->bcc, $this->normalizeAddresses(\n            is_string($name) ? [new Address($address, $name)] : Arr::wrap($address),\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Add a \"reply to\" recipient to the message envelope.\n     *\n     * @param  \\Illuminate\\Mail\\Mailables\\Address|array<int, \\Illuminate\\Mail\\Mailables\\Address|string>|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function replyTo(Address|array|string $address, $name = null)\n    {\n        $this->replyTo = array_merge($this->replyTo, $this->normalizeAddresses(\n            is_string($name) ? [new Address($address, $name)] : Arr::wrap($address),\n        ));\n\n        return $this;\n    }\n\n    /**\n     * Set the subject of the message.\n     *\n     * @param  string  $subject\n     * @return $this\n     */\n    public function subject(string $subject)\n    {\n        $this->subject = $subject;\n\n        return $this;\n    }\n\n    /**\n     * Add \"tags\" to the message.\n     *\n     * @param  array  $tags\n     * @return $this\n     */\n    public function tags(array $tags)\n    {\n        $this->tags = array_merge($this->tags, $tags);\n\n        return $this;\n    }\n\n    /**\n     * Add a \"tag\" to the message.\n     *\n     * @param  string  $tag\n     * @return $this\n     */\n    public function tag(string $tag)\n    {\n        $this->tags[] = $tag;\n\n        return $this;\n    }\n\n    /**\n     * Add metadata to the message.\n     *\n     * @param  string  $key\n     * @param  string|int  $value\n     * @return $this\n     */\n    public function metadata(string $key, string|int $value)\n    {\n        $this->metadata[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Add a Symfony Message customization callback to the message.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function using(Closure $callback)\n    {\n        $this->using[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the message is from the given address.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function isFrom(string $address, ?string $name = null)\n    {\n        if (is_null($name)) {\n            return $this->from->address === $address;\n        }\n\n        return $this->from->address === $address &&\n               $this->from->name === $name;\n    }\n\n    /**\n     * Determine if the message has the given address as a recipient.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasTo(string $address, ?string $name = null)\n    {\n        return $this->hasRecipient($this->to, $address, $name);\n    }\n\n    /**\n     * Determine if the message has the given address as a \"cc\" recipient.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasCc(string $address, ?string $name = null)\n    {\n        return $this->hasRecipient($this->cc, $address, $name);\n    }\n\n    /**\n     * Determine if the message has the given address as a \"bcc\" recipient.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasBcc(string $address, ?string $name = null)\n    {\n        return $this->hasRecipient($this->bcc, $address, $name);\n    }\n\n    /**\n     * Determine if the message has the given address as a \"reply to\" recipient.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function hasReplyTo(string $address, ?string $name = null)\n    {\n        return $this->hasRecipient($this->replyTo, $address, $name);\n    }\n\n    /**\n     * Determine if the message has the given recipient.\n     *\n     * @param  array  $recipients\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return bool\n     */\n    protected function hasRecipient(array $recipients, string $address, ?string $name = null)\n    {\n        return (new Collection($recipients))->contains(function ($recipient) use ($address, $name) {\n            if (is_null($name)) {\n                return $recipient->address === $address;\n            }\n\n            return $recipient->address === $address &&\n                   $recipient->name === $name;\n        });\n    }\n\n    /**\n     * Determine if the message has the given subject.\n     *\n     * @param  string  $subject\n     * @return bool\n     */\n    public function hasSubject(string $subject)\n    {\n        return $this->subject === $subject;\n    }\n\n    /**\n     * Determine if the message has the given metadata.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return bool\n     */\n    public function hasMetadata(string $key, string $value)\n    {\n        return isset($this->metadata[$key]) && (string) $this->metadata[$key] === $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailables/Headers.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Mailables;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\n\nclass Headers\n{\n    use Conditionable;\n\n    /**\n     * The message's message ID.\n     *\n     * @var string|null\n     */\n    public $messageId;\n\n    /**\n     * The message IDs that are referenced by the message.\n     *\n     * @var array\n     */\n    public $references;\n\n    /**\n     * The message's text headers.\n     *\n     * @var array\n     */\n    public $text;\n\n    /**\n     * Create a new instance of headers for a message.\n     *\n     * @param  string|null  $messageId\n     * @param  array  $references\n     * @param  array  $text\n     *\n     * @named-arguments-supported\n     */\n    public function __construct(?string $messageId = null, array $references = [], array $text = [])\n    {\n        $this->messageId = $messageId;\n        $this->references = $references;\n        $this->text = $text;\n    }\n\n    /**\n     * Set the message ID.\n     *\n     * @param  string  $messageId\n     * @return $this\n     */\n    public function messageId(string $messageId)\n    {\n        $this->messageId = $messageId;\n\n        return $this;\n    }\n\n    /**\n     * Set the message IDs referenced by this message.\n     *\n     * @param  array  $references\n     * @return $this\n     */\n    public function references(array $references)\n    {\n        $this->references = array_merge($this->references, $references);\n\n        return $this;\n    }\n\n    /**\n     * Set the headers for this message.\n     *\n     * @param  array  $text\n     * @return $this\n     */\n    public function text(array $text)\n    {\n        $this->text = array_merge($this->text, $text);\n\n        return $this;\n    }\n\n    /**\n     * Get the references header as a string.\n     *\n     * @return string\n     */\n    public function referencesString(): string\n    {\n        return (new Collection($this->references))\n            ->map(fn ($messageId) => Str::of($messageId)->start('<')->finish('>')->value())\n            ->implode(' ');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Mailer.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Closure;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Mail\\Mailable as MailableContract;\nuse Illuminate\\Contracts\\Mail\\Mailer as MailerContract;\nuse Illuminate\\Contracts\\Mail\\MailQueue as MailQueueContract;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueContract;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Mail\\Events\\MessageSending;\nuse Illuminate\\Mail\\Events\\MessageSent;\nuse Illuminate\\Mail\\Mailables\\Address;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse Symfony\\Component\\Mailer\\Envelope;\nuse Symfony\\Component\\Mailer\\Transport\\TransportInterface;\nuse Symfony\\Component\\Mime\\Email;\n\nclass Mailer implements MailerContract, MailQueueContract\n{\n    use Macroable;\n\n    /**\n     * The name that is configured for the mailer.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The view factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $views;\n\n    /**\n     * The Symfony Transport instance.\n     *\n     * @var \\Symfony\\Component\\Mailer\\Transport\\TransportInterface\n     */\n    protected $transport;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $events;\n\n    /**\n     * The global from address and name.\n     *\n     * @var array\n     */\n    protected $from;\n\n    /**\n     * The global reply-to address and name.\n     *\n     * @var array\n     */\n    protected $replyTo;\n\n    /**\n     * The global return path address.\n     *\n     * @var array\n     */\n    protected $returnPath;\n\n    /**\n     * The global to address and name.\n     *\n     * @var array\n     */\n    protected $to;\n\n    /**\n     * The queue factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    protected $queue;\n\n    /**\n     * Create a new Mailer instance.\n     *\n     * @param  string  $name\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $views\n     * @param  \\Symfony\\Component\\Mailer\\Transport\\TransportInterface  $transport\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher|null  $events\n     */\n    public function __construct(string $name, Factory $views, TransportInterface $transport, ?Dispatcher $events = null)\n    {\n        $this->name = $name;\n        $this->views = $views;\n        $this->events = $events;\n        $this->transport = $transport;\n    }\n\n    /**\n     * Set the global from address and name.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return void\n     */\n    public function alwaysFrom($address, $name = null)\n    {\n        $this->from = compact('address', 'name');\n    }\n\n    /**\n     * Set the global reply-to address and name.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return void\n     */\n    public function alwaysReplyTo($address, $name = null)\n    {\n        $this->replyTo = compact('address', 'name');\n    }\n\n    /**\n     * Set the global return path address.\n     *\n     * @param  string  $address\n     * @return void\n     */\n    public function alwaysReturnPath($address)\n    {\n        $this->returnPath = compact('address');\n    }\n\n    /**\n     * Set the global to address and name.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return void\n     */\n    public function alwaysTo($address, $name = null)\n    {\n        $this->to = compact('address', 'name');\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @param  string|null  $name\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function to($users, $name = null)\n    {\n        if (! is_null($name) && is_string($users)) {\n            $users = new Address($users, $name);\n        }\n\n        return (new PendingMail($this))->to($users);\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @param  string|null  $name\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function cc($users, $name = null)\n    {\n        if (! is_null($name) && is_string($users)) {\n            $users = new Address($users, $name);\n        }\n\n        return (new PendingMail($this))->cc($users);\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @param  string|null  $name\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function bcc($users, $name = null)\n    {\n        if (! is_null($name) && is_string($users)) {\n            $users = new Address($users, $name);\n        }\n\n        return (new PendingMail($this))->bcc($users);\n    }\n\n    /**\n     * Send a new message with only an HTML part.\n     *\n     * @param  string  $html\n     * @param  mixed  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function html($html, $callback)\n    {\n        return $this->send(['html' => new HtmlString($html)], [], $callback);\n    }\n\n    /**\n     * Send a new message with only a raw text part.\n     *\n     * @param  string  $text\n     * @param  mixed  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function raw($text, $callback)\n    {\n        return $this->send(['raw' => $text], [], $callback);\n    }\n\n    /**\n     * Send a new message with only a plain part.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @param  mixed  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function plain($view, array $data, $callback)\n    {\n        return $this->send(['text' => $view], $data, $callback);\n    }\n\n    /**\n     * Render the given message as a view.\n     *\n     * @param  string|array  $view\n     * @param  array  $data\n     * @return string\n     */\n    public function render($view, array $data = [])\n    {\n        // First we need to parse the view, which could either be a string or an array\n        // containing both an HTML and plain text versions of the view which should\n        // be used when sending an e-mail. We will extract both of them out here.\n        [$view, $plain] = $this->parseView($view);\n\n        $data['message'] = $this->createMessage();\n\n        return $this->replaceEmbeddedAttachments(\n            $this->renderView($view ?: $plain, $data),\n            $data['message']->getSymfonyMessage()->getAttachments()\n        );\n    }\n\n    /**\n     * Replace the embedded image attachments with raw, inline image data for browser rendering.\n     *\n     * @param  string  $renderedView\n     * @param  array  $attachments\n     * @return string\n     */\n    protected function replaceEmbeddedAttachments(string $renderedView, array $attachments)\n    {\n        if (preg_match_all('/<img.+?src=[\\'\"]cid:([^\\'\"]+)[\\'\"].*?>/is', $renderedView, $matches)) {\n            foreach (array_unique($matches[1]) as $image) {\n                foreach ($attachments as $attachment) {\n                    if ($attachment->getContentId() === $image || $attachment->getFilename() === $image) {\n                        $renderedView = str_replace(\n                            'cid:'.$image,\n                            'data:'.$attachment->getContentType().';base64,'.$attachment->bodyToString(),\n                            $renderedView\n                        );\n\n                        break;\n                    }\n                }\n            }\n        }\n\n        return $renderedView;\n    }\n\n    /**\n     * Send a new message using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send($view, array $data = [], $callback = null)\n    {\n        if ($view instanceof MailableContract) {\n            return $this->sendMailable($view);\n        }\n\n        $data['mailer'] = $this->name;\n\n        // Once we have retrieved the view content for the e-mail we will set the body\n        // of this message using the HTML type, which will provide a simple wrapper\n        // to creating view based emails that are able to receive arrays of data.\n        [$view, $plain, $raw] = $this->parseView($view);\n\n        $data['message'] = $message = $this->createMessage();\n\n        $this->addContent($message, $view, $plain, $raw, $data);\n\n        if (! is_null($callback)) {\n            $callback($message);\n        }\n\n        // If a global \"to\" address has been set, we will set that address on the mail\n        // message. This is primarily useful during local development in which each\n        // message should be delivered into a single mail address for inspection.\n        if (isset($this->to['address'])) {\n            $this->setGlobalToAndRemoveCcAndBcc($message);\n        }\n\n        // Next we will determine if the message should be sent. We give the developer\n        // one final chance to stop this message and then we will send it to all of\n        // its recipients. We will then fire the sent event for the sent message.\n        $symfonyMessage = $message->getSymfonyMessage();\n\n        if ($this->shouldSendMessage($symfonyMessage, $data)) {\n            $symfonySentMessage = $this->sendSymfonyMessage($symfonyMessage);\n\n            if ($symfonySentMessage) {\n                $sentMessage = new SentMessage($symfonySentMessage);\n\n                $this->dispatchSentEvent($sentMessage, $data);\n\n                return $sentMessage;\n            }\n        }\n    }\n\n    /**\n     * Send the given mailable.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    protected function sendMailable(MailableContract $mailable)\n    {\n        return $mailable instanceof ShouldQueue\n            ? $mailable->mailer($this->name)->queue($this->queue)\n            : $mailable->mailer($this->name)->send($this);\n    }\n\n    /**\n     * Send a new message synchronously using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $mailable\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function sendNow($mailable, array $data = [], $callback = null)\n    {\n        return $mailable instanceof MailableContract\n            ? $mailable->mailer($this->name)->send($this)\n            : $this->send($mailable, $data, $callback);\n    }\n\n    /**\n     * Parse the given view name or array.\n     *\n     * @param  \\Closure|array|string  $view\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseView($view)\n    {\n        if (is_string($view) || $view instanceof Closure) {\n            return [$view, null, null];\n        }\n\n        // If the given view is an array with numeric keys, we will just assume that\n        // both a \"pretty\" and \"plain\" view were provided, so we will return this\n        // array as is, since it should contain both views with numerical keys.\n        if (is_array($view) && isset($view[0])) {\n            return [$view[0], $view[1], null];\n        }\n\n        // If this view is an array but doesn't contain numeric keys, we will assume\n        // the views are being explicitly specified and will extract them via the\n        // named keys instead, allowing the developers to use one or the other.\n        if (is_array($view)) {\n            return [\n                $view['html'] ?? null,\n                $view['text'] ?? null,\n                $view['raw'] ?? null,\n            ];\n        }\n\n        throw new InvalidArgumentException('Invalid view.');\n    }\n\n    /**\n     * Add the content to a given message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @param  string|null  $view\n     * @param  string|null  $plain\n     * @param  string|null  $raw\n     * @param  array  $data\n     * @return void\n     */\n    protected function addContent($message, $view, $plain, $raw, $data)\n    {\n        if (isset($view)) {\n            $message->html($this->renderView($view, $data) ?: ' ');\n        }\n\n        if (isset($plain)) {\n            $message->text($this->renderView($plain, $data) ?: ' ');\n        }\n\n        if (isset($raw)) {\n            $message->text($raw);\n        }\n    }\n\n    /**\n     * Render the given view.\n     *\n     * @param  \\Closure|string  $view\n     * @param  array  $data\n     * @return string\n     */\n    protected function renderView($view, $data)\n    {\n        $view = value($view, $data);\n\n        return $view instanceof Htmlable\n            ? $view->toHtml()\n            : $this->views->make($view, $data)->render();\n    }\n\n    /**\n     * Set the global \"to\" address on the given message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     * @return void\n     */\n    protected function setGlobalToAndRemoveCcAndBcc($message)\n    {\n        $message->forgetTo();\n\n        $message->to($this->to['address'], $this->to['name'], true);\n\n        $message->forgetCc();\n        $message->forgetBcc();\n    }\n\n    /**\n     * Queue a new mail message for sending.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $view\n     * @param  \\BackedEnum|string|null  $queue\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function queue($view, $queue = null)\n    {\n        if (! $view instanceof MailableContract) {\n            throw new InvalidArgumentException('Only mailables may be queued.');\n        }\n\n        if (is_string($queue)) {\n            $view->onQueue($queue);\n        }\n\n        return $view->mailer($this->name)->queue($this->queue);\n    }\n\n    /**\n     * Queue a new mail message for sending on the given queue.\n     *\n     * @param  \\BackedEnum|string|null  $queue\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $view\n     * @return mixed\n     */\n    public function onQueue($queue, $view)\n    {\n        return $this->queue($view, $queue);\n    }\n\n    /**\n     * Queue a new mail message for sending on the given queue.\n     *\n     * This method didn't match rest of framework's \"onQueue\" phrasing. Added \"onQueue\".\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $view\n     * @return mixed\n     */\n    public function queueOn($queue, $view)\n    {\n        return $this->onQueue($queue, $view);\n    }\n\n    /**\n     * Queue a new mail message for sending after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $view\n     * @param  string|null  $queue\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function later($delay, $view, $queue = null)\n    {\n        if (! $view instanceof MailableContract) {\n            throw new InvalidArgumentException('Only mailables may be queued.');\n        }\n\n        return $view->mailer($this->name)->later(\n            $delay, is_null($queue) ? $this->queue : $queue\n        );\n    }\n\n    /**\n     * Queue a new mail message for sending after (n) seconds on the given queue.\n     *\n     * @param  string  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $view\n     * @return mixed\n     */\n    public function laterOn($queue, $delay, $view)\n    {\n        return $this->later($delay, $view, $queue);\n    }\n\n    /**\n     * Create a new message instance.\n     *\n     * @return \\Illuminate\\Mail\\Message\n     */\n    protected function createMessage()\n    {\n        $message = new Message(new Email());\n\n        // If a global from address has been specified we will set it on every message\n        // instance so the developer does not have to repeat themselves every time\n        // they create a new message. We'll just go ahead and push this address.\n        if (! empty($this->from['address'])) {\n            $message->from($this->from['address'], $this->from['name']);\n        }\n\n        // When a global reply address was specified we will set this on every message\n        // instance so the developer does not have to repeat themselves every time\n        // they create a new message. We will just go ahead and push this address.\n        if (! empty($this->replyTo['address'])) {\n            $message->replyTo($this->replyTo['address'], $this->replyTo['name']);\n        }\n\n        if (! empty($this->returnPath['address'])) {\n            $message->returnPath($this->returnPath['address']);\n        }\n\n        return $message;\n    }\n\n    /**\n     * Send a Symfony Email instance.\n     *\n     * @param  \\Symfony\\Component\\Mime\\Email  $message\n     * @return \\Symfony\\Component\\Mailer\\SentMessage|null\n     */\n    protected function sendSymfonyMessage(Email $message)\n    {\n        try {\n            return $this->transport->send($message, Envelope::create($message));\n        } finally {\n            //\n        }\n    }\n\n    /**\n     * Determines if the email can be sent.\n     *\n     * @param  \\Symfony\\Component\\Mime\\Email  $message\n     * @param  array  $data\n     * @return bool\n     */\n    protected function shouldSendMessage($message, $data = [])\n    {\n        if (! $this->events) {\n            return true;\n        }\n\n        return $this->events->until(\n            new MessageSending($message, $data)\n        ) !== false;\n    }\n\n    /**\n     * Dispatch the message sent event.\n     *\n     * @param  \\Illuminate\\Mail\\SentMessage  $message\n     * @param  array  $data\n     * @return void\n     */\n    protected function dispatchSentEvent($message, $data = [])\n    {\n        $this->events?->dispatch(\n            new MessageSent($message, $data)\n        );\n    }\n\n    /**\n     * Get the Symfony Transport instance.\n     *\n     * @return \\Symfony\\Component\\Mailer\\Transport\\TransportInterface\n     */\n    public function getSymfonyTransport()\n    {\n        return $this->transport;\n    }\n\n    /**\n     * Get the view factory instance.\n     *\n     * @return \\Illuminate\\Contracts\\View\\Factory\n     */\n    public function getViewFactory()\n    {\n        return $this->views;\n    }\n\n    /**\n     * Set the Symfony Transport instance.\n     *\n     * @param  \\Symfony\\Component\\Mailer\\Transport\\TransportInterface  $transport\n     * @return void\n     */\n    public function setSymfonyTransport(TransportInterface $transport)\n    {\n        $this->transport = $transport;\n    }\n\n    /**\n     * Set the queue manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $queue\n     * @return $this\n     */\n    public function setQueue(QueueContract $queue)\n    {\n        $this->queue = $queue;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Markdown.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Support\\EncodedHtmlString;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Str;\nuse League\\CommonMark\\Environment\\Environment;\nuse League\\CommonMark\\Extension\\CommonMark\\CommonMarkCoreExtension;\nuse League\\CommonMark\\Extension\\Table\\TableExtension;\nuse League\\CommonMark\\MarkdownConverter;\nuse TijsVerkoyen\\CssToInlineStyles\\CssToInlineStyles;\n\nclass Markdown\n{\n    /**\n     * The view factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $view;\n\n    /**\n     * The current theme being used when generating emails.\n     *\n     * @var string\n     */\n    protected $theme = 'default';\n\n    /**\n     * The registered component paths.\n     *\n     * @var array\n     */\n    protected $componentPaths = [];\n\n    /**\n     * Indicates if secure encoding should be enabled.\n     *\n     * @var bool\n     */\n    protected static $withSecuredEncoding = false;\n\n    /**\n     * The registered CommonMark extensions.\n     *\n     * @var array<int, class-string<\\League\\CommonMark\\Extension\\ExtensionInterface>>\n     */\n    protected static $extensions = [];\n\n    /**\n     * Create a new Markdown renderer instance.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $view\n     * @param  array  $options\n     */\n    public function __construct(ViewFactory $view, array $options = [])\n    {\n        $this->view = $view;\n        $this->theme = $options['theme'] ?? 'default';\n        $this->loadComponentsFrom($options['paths'] ?? []);\n\n        static::$extensions = $options['extensions'] ?? [];\n    }\n\n    /**\n     * Render the Markdown template into HTML.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @param  \\TijsVerkoyen\\CssToInlineStyles\\CssToInlineStyles|null  $inliner\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public function render($view, array $data = [], $inliner = null)\n    {\n        $this->view->flushFinderCache();\n\n        $bladeCompiler = $this->view\n            ->getEngineResolver()\n            ->resolve('blade')\n            ->getCompiler();\n\n        $contents = $bladeCompiler->usingEchoFormat(\n            'new \\Illuminate\\Support\\EncodedHtmlString(%s)',\n            function () use ($view, $data) {\n                if (static::$withSecuredEncoding === true) {\n                    EncodedHtmlString::encodeUsing(function ($value) {\n                        $replacements = [\n                            '[' => '\\[',\n                            '<' => '&lt;',\n                            '>' => '&gt;',\n                        ];\n\n                        return str_replace(array_keys($replacements), array_values($replacements), $value);\n                    });\n                }\n\n                try {\n                    $contents = $this->view->replaceNamespace(\n                        'mail', $this->htmlComponentPaths()\n                    )->make($view, $data)->render();\n                } finally {\n                    EncodedHtmlString::flushState();\n                }\n\n                return $contents;\n            }\n        );\n\n        if ($this->view->exists($customTheme = Str::start($this->theme, 'mail.'))) {\n            $theme = $customTheme;\n        } else {\n            $theme = str_contains($this->theme, '::')\n                ? $this->theme\n                : 'mail::themes.'.$this->theme;\n        }\n\n        return new HtmlString(($inliner ?: new CssToInlineStyles)->convert(\n            str_replace('\\[', '[', $contents), $this->view->make($theme, $data)->render()\n        ));\n    }\n\n    /**\n     * Render the Markdown template into text.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public function renderText($view, array $data = [])\n    {\n        $this->view->flushFinderCache();\n\n        $contents = $this->view->replaceNamespace(\n            'mail', $this->textComponentPaths()\n        )->make($view, $data)->render();\n\n        return new HtmlString(\n            html_entity_decode(preg_replace(\"/[\\r\\n]{2,}/\", \"\\n\\n\", $contents), ENT_QUOTES, 'UTF-8')\n        );\n    }\n\n    /**\n     * Parse the given Markdown text into HTML.\n     *\n     * @param  string  $text\n     * @param  bool  $encoded\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public static function parse($text, bool $encoded = false)\n    {\n        if ($encoded === false) {\n            return new HtmlString(static::converter()->convert($text)->getContent());\n        }\n\n        if (static::$withSecuredEncoding === true || $encoded === true) {\n            EncodedHtmlString::encodeUsing(function ($value) {\n                $replacements = [\n                    '[' => '\\[',\n                    '<' => '\\<',\n                ];\n\n                $html = str_replace(array_keys($replacements), array_values($replacements), $value);\n\n                return static::converter([\n                    'html_input' => 'escape',\n                ])->convert($html)->getContent();\n            });\n        }\n\n        $html = '';\n\n        try {\n            $html = static::converter()->convert($text)->getContent();\n        } finally {\n            EncodedHtmlString::flushState();\n        }\n\n        return new HtmlString($html);\n    }\n\n    /**\n     * Get a Markdown converter instance.\n     *\n     * @internal\n     *\n     * @param  array<string, mixed>  $config\n     * @return \\League\\CommonMark\\MarkdownConverter\n     */\n    public static function converter(array $config = [])\n    {\n        $environment = new Environment(array_merge([\n            'allow_unsafe_links' => false,\n        ], $config));\n\n        $environment->addExtension(new CommonMarkCoreExtension);\n        $environment->addExtension(new TableExtension);\n\n        foreach (static::$extensions as $extensionClass) {\n            $environment->addExtension(new $extensionClass);\n        }\n\n        return new MarkdownConverter($environment);\n    }\n\n    /**\n     * Get the HTML component paths.\n     *\n     * @return array\n     */\n    public function htmlComponentPaths()\n    {\n        return array_map(function ($path) {\n            return $path.'/html';\n        }, $this->componentPaths());\n    }\n\n    /**\n     * Get the text component paths.\n     *\n     * @return array\n     */\n    public function textComponentPaths()\n    {\n        return array_map(function ($path) {\n            return $path.'/text';\n        }, $this->componentPaths());\n    }\n\n    /**\n     * Get the component paths.\n     *\n     * @return array\n     */\n    protected function componentPaths()\n    {\n        return array_unique(array_merge($this->componentPaths, [\n            __DIR__.'/resources/views',\n        ]));\n    }\n\n    /**\n     * Register new mail component paths.\n     *\n     * @param  array  $paths\n     * @return void\n     */\n    public function loadComponentsFrom(array $paths = [])\n    {\n        $this->componentPaths = $paths;\n    }\n\n    /**\n     * Set the default theme to be used.\n     *\n     * @param  string  $theme\n     * @return $this\n     */\n    public function theme($theme)\n    {\n        $this->theme = $theme;\n\n        return $this;\n    }\n\n    /**\n     * Get the theme currently being used by the renderer.\n     *\n     * @return string\n     */\n    public function getTheme()\n    {\n        return $this->theme;\n    }\n\n    /**\n     * Enable secured encoding when parsing Markdown.\n     *\n     * @return void\n     */\n    public static function withSecuredEncoding()\n    {\n        static::$withSecuredEncoding = true;\n    }\n\n    /**\n     * Disable secured encoding when parsing Markdown.\n     *\n     * @return void\n     */\n    public static function withoutSecuredEncoding()\n    {\n        static::$withSecuredEncoding = false;\n    }\n\n    /**\n     * Flush the class's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$withSecuredEncoding = false;\n        static::$extensions = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Message.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Symfony\\Component\\Mime\\Address;\nuse Symfony\\Component\\Mime\\Email;\nuse Symfony\\Component\\Mime\\Part\\DataPart;\nuse Symfony\\Component\\Mime\\Part\\File;\n\n/**\n * @mixin \\Symfony\\Component\\Mime\\Email\n */\nclass Message\n{\n    use ForwardsCalls;\n\n    /**\n     * The Symfony Email instance.\n     *\n     * @var \\Symfony\\Component\\Mime\\Email\n     */\n    protected $message;\n\n    /**\n     * CIDs of files embedded in the message.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @var array\n     */\n    protected $embeddedFiles = [];\n\n    /**\n     * Create a new message instance.\n     *\n     * @param  \\Symfony\\Component\\Mime\\Email  $message\n     */\n    public function __construct(Email $message)\n    {\n        $this->message = $message;\n    }\n\n    /**\n     * Add a \"from\" address to the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function from($address, $name = null)\n    {\n        is_array($address)\n            ? $this->message->from(...$address)\n            : $this->message->from(new Address($address, (string) $name));\n\n        return $this;\n    }\n\n    /**\n     * Set the \"sender\" of the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function sender($address, $name = null)\n    {\n        is_array($address)\n            ? $this->message->sender(...$address)\n            : $this->message->sender(new Address($address, (string) $name));\n\n        return $this;\n    }\n\n    /**\n     * Set the \"return path\" of the message.\n     *\n     * @param  string  $address\n     * @return $this\n     */\n    public function returnPath($address)\n    {\n        $this->message->returnPath($address);\n\n        return $this;\n    }\n\n    /**\n     * Add a recipient to the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @param  bool  $override\n     * @return $this\n     */\n    public function to($address, $name = null, $override = false)\n    {\n        if ($override) {\n            is_array($address)\n                ? $this->message->to(...$address)\n                : $this->message->to(new Address($address, (string) $name));\n\n            return $this;\n        }\n\n        return $this->addAddresses($address, $name, 'To');\n    }\n\n    /**\n     * Remove all \"to\" addresses from the message.\n     *\n     * @return $this\n     */\n    public function forgetTo()\n    {\n        if ($header = $this->message->getHeaders()->get('To')) {\n            $this->addAddressDebugHeader('X-To', $this->message->getTo());\n\n            $header->setAddresses([]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a carbon copy to the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @param  bool  $override\n     * @return $this\n     */\n    public function cc($address, $name = null, $override = false)\n    {\n        if ($override) {\n            is_array($address)\n                ? $this->message->cc(...$address)\n                : $this->message->cc(new Address($address, (string) $name));\n\n            return $this;\n        }\n\n        return $this->addAddresses($address, $name, 'Cc');\n    }\n\n    /**\n     * Remove all carbon copy addresses from the message.\n     *\n     * @return $this\n     */\n    public function forgetCc()\n    {\n        if ($header = $this->message->getHeaders()->get('Cc')) {\n            $this->addAddressDebugHeader('X-Cc', $this->message->getCC());\n\n            $header->setAddresses([]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a blind carbon copy to the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @param  bool  $override\n     * @return $this\n     */\n    public function bcc($address, $name = null, $override = false)\n    {\n        if ($override) {\n            is_array($address)\n                ? $this->message->bcc(...$address)\n                : $this->message->bcc(new Address($address, (string) $name));\n\n            return $this;\n        }\n\n        return $this->addAddresses($address, $name, 'Bcc');\n    }\n\n    /**\n     * Remove all of the blind carbon copy addresses from the message.\n     *\n     * @return $this\n     */\n    public function forgetBcc()\n    {\n        if ($header = $this->message->getHeaders()->get('Bcc')) {\n            $this->addAddressDebugHeader('X-Bcc', $this->message->getBcc());\n\n            $header->setAddresses([]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a \"reply to\" address to the message.\n     *\n     * @param  string|array  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function replyTo($address, $name = null)\n    {\n        return $this->addAddresses($address, $name, 'ReplyTo');\n    }\n\n    /**\n     * Add a recipient to the message.\n     *\n     * @param  string|array  $address\n     * @param  string  $name\n     * @param  string  $type\n     * @return $this\n     */\n    protected function addAddresses($address, $name, $type)\n    {\n        if (is_array($address)) {\n            $type = lcfirst($type);\n\n            $addresses = (new Collection($address))->map(function ($address, $key) {\n                if (is_string($key) && is_string($address)) {\n                    return new Address($key, $address);\n                }\n\n                if (is_array($address)) {\n                    return new Address($address['email'] ?? $address['address'], $address['name'] ?? null);\n                }\n\n                if (is_null($address)) {\n                    return new Address($key);\n                }\n\n                return $address;\n            })->all();\n\n            $this->message->{\"{$type}\"}(...$addresses);\n        } else {\n            $this->message->{\"add{$type}\"}(new Address($address, (string) $name));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add an address debug header for a list of recipients.\n     *\n     * @param  string  $header\n     * @param  \\Symfony\\Component\\Mime\\Address[]  $addresses\n     * @return $this\n     */\n    protected function addAddressDebugHeader(string $header, array $addresses)\n    {\n        $this->message->getHeaders()->addTextHeader(\n            $header,\n            implode(', ', array_map(fn ($a) => $a->toString(), $addresses)),\n        );\n\n        return $this;\n    }\n\n    /**\n     * Set the subject of the message.\n     *\n     * @param  string  $subject\n     * @return $this\n     */\n    public function subject($subject)\n    {\n        $this->message->subject($subject);\n\n        return $this;\n    }\n\n    /**\n     * Set the message priority level.\n     *\n     * @param  int  $level\n     * @return $this\n     */\n    public function priority($level)\n    {\n        $this->message->priority($level);\n\n        return $this;\n    }\n\n    /**\n     * Attach a file to the message.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @param  array  $options\n     * @return $this\n     */\n    public function attach($file, array $options = [])\n    {\n        if ($file instanceof Attachable) {\n            $file = $file->toMailAttachment();\n        }\n\n        if ($file instanceof Attachment) {\n            return $file->attachTo($this);\n        }\n\n        $this->message->attachFromPath($file, $options['as'] ?? null, $options['mime'] ?? null);\n\n        return $this;\n    }\n\n    /**\n     * Attach in-memory data as an attachment.\n     *\n     * @param  string|resource  $data\n     * @param  string  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function attachData($data, $name, array $options = [])\n    {\n        $this->message->attach($data, $name, $options['mime'] ?? null);\n\n        return $this;\n    }\n\n    /**\n     * Embed a file in the message and get the CID.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @return string\n     */\n    public function embed($file)\n    {\n        if ($file instanceof Attachable) {\n            $file = $file->toMailAttachment();\n        }\n\n        if ($file instanceof Attachment) {\n            return $file->attachWith(\n                function ($path) use ($file) {\n                    $part = (new DataPart(new File($path), $file->as, $file->mime))->asInline();\n\n                    $this->message->addPart($part);\n\n                    return \"cid:{$part->getContentId()}\";\n                },\n                function ($data) use ($file) {\n                    $this->message->addPart(\n                        $part = $part = (new DataPart($data(), $file->as, $file->mime))->asInline()\n                    );\n\n                    return \"cid:{$part->getContentId()}\";\n                }\n            );\n        }\n\n        $fileObject = new File($file);\n\n        $this->message->addPart(\n            $part = (new DataPart($fileObject, $fileObject->getFilename()))->asInline()\n        );\n\n        return \"cid:{$part->getContentId()}\";\n    }\n\n    /**\n     * Embed in-memory data in the message and get the CID.\n     *\n     * @param  string|resource  $data\n     * @param  string  $name\n     * @param  string|null  $contentType\n     * @return string\n     */\n    public function embedData($data, $name, $contentType = null)\n    {\n        $part = (new DataPart($data, $name, $contentType))->asInline();\n\n        $this->message->addPart($part);\n\n        return \"cid:{$part->getContentId()}\";\n    }\n\n    /**\n     * Get the underlying Symfony Email instance.\n     *\n     * @return \\Symfony\\Component\\Mime\\Email\n     */\n    public function getSymfonyMessage()\n    {\n        return $this->message;\n    }\n\n    /**\n     * Dynamically pass missing methods to the Symfony instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardDecoratedCallTo($this->message, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/PendingMail.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Contracts\\Mail\\Mailable as MailableContract;\nuse Illuminate\\Contracts\\Mail\\Mailer as MailerContract;\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Support\\Traits\\Conditionable;\n\nclass PendingMail\n{\n    use Conditionable;\n\n    /**\n     * The mailer instance.\n     *\n     * @var \\Illuminate\\Contracts\\Mail\\Mailer\n     */\n    protected $mailer;\n\n    /**\n     * The locale of the message.\n     *\n     * @var string\n     */\n    protected $locale;\n\n    /**\n     * The \"to\" recipients of the message.\n     *\n     * @var array\n     */\n    protected $to = [];\n\n    /**\n     * The \"cc\" recipients of the message.\n     *\n     * @var array\n     */\n    protected $cc = [];\n\n    /**\n     * The \"bcc\" recipients of the message.\n     *\n     * @var array\n     */\n    protected $bcc = [];\n\n    /**\n     * Create a new mailable mailer instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailer  $mailer\n     */\n    public function __construct(MailerContract $mailer)\n    {\n        $this->mailer = $mailer;\n    }\n\n    /**\n     * Set the locale of the message.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale)\n    {\n        $this->locale = $locale;\n\n        return $this;\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  mixed  $users\n     * @return $this\n     */\n    public function to($users)\n    {\n        $this->to = $users;\n\n        if (! $this->locale && $users instanceof HasLocalePreference) {\n            $this->locale($users->preferredLocale());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  mixed  $users\n     * @return $this\n     */\n    public function cc($users)\n    {\n        $this->cc = $users;\n\n        return $this;\n    }\n\n    /**\n     * Set the recipients of the message.\n     *\n     * @param  mixed  $users\n     * @return $this\n     */\n    public function bcc($users)\n    {\n        $this->bcc = $users;\n\n        return $this;\n    }\n\n    /**\n     * Send a new mailable message instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send(MailableContract $mailable)\n    {\n        return $this->mailer->send($this->fill($mailable));\n    }\n\n    /**\n     * Send a new mailable message instance synchronously.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function sendNow(MailableContract $mailable)\n    {\n        return $this->mailer->sendNow($this->fill($mailable));\n    }\n\n    /**\n     * Push the given mailable onto the queue.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return mixed\n     */\n    public function queue(MailableContract $mailable)\n    {\n        return $this->mailer->queue($this->fill($mailable));\n    }\n\n    /**\n     * Deliver the queued message after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return mixed\n     */\n    public function later($delay, MailableContract $mailable)\n    {\n        return $this->mailer->later($delay, $this->fill($mailable));\n    }\n\n    /**\n     * Populate the mailable with the addresses.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return \\Illuminate\\Mail\\Mailable\n     */\n    protected function fill(MailableContract $mailable)\n    {\n        return tap($mailable->to($this->to)\n            ->cc($this->cc)\n            ->bcc($this->bcc), function (MailableContract $mailable) {\n                if ($this->locale) {\n                    $mailable->locale($this->locale);\n                }\n            });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/SendQueuedMailable.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Mail\\Factory as MailFactory;\nuse Illuminate\\Contracts\\Mail\\Mailable as MailableContract;\nuse Illuminate\\Contracts\\Queue\\ShouldBeEncrypted;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Queue\\Attributes\\Backoff;\nuse Illuminate\\Queue\\Attributes\\Connection;\nuse Illuminate\\Queue\\Attributes\\MaxExceptions;\nuse Illuminate\\Queue\\Attributes\\Queue as QueueAttribute;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\Attributes\\Timeout;\nuse Illuminate\\Queue\\Attributes\\Tries;\nuse Illuminate\\Queue\\InteractsWithQueue;\n\nclass SendQueuedMailable\n{\n    use InteractsWithQueue, Queueable, ReadsQueueAttributes;\n\n    /**\n     * The mailable message instance.\n     *\n     * @var \\Illuminate\\Contracts\\Mail\\Mailable\n     */\n    public $mailable;\n\n    /**\n     * The number of times the job may be attempted.\n     *\n     * @var int\n     */\n    public $tries;\n\n    /**\n     * The number of seconds the job can run before timing out.\n     *\n     * @var int\n     */\n    public $timeout;\n\n    /**\n     * The maximum number of unhandled exceptions to allow before failing.\n     *\n     * @return int|null\n     */\n    public $maxExceptions;\n\n    /**\n     * Indicates if the job should be encrypted.\n     *\n     * @var bool\n     */\n    public $shouldBeEncrypted = false;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     */\n    public function __construct(MailableContract $mailable)\n    {\n        $this->mailable = $mailable;\n\n        if ($mailable instanceof ShouldQueueAfterCommit) {\n            $this->afterCommit = true;\n        } else {\n            $this->afterCommit = property_exists($mailable, 'afterCommit') ? $mailable->afterCommit : null;\n        }\n\n        $this->connection = $this->getAttributeValue($mailable, Connection::class, 'connection');\n        $this->maxExceptions = $this->getAttributeValue($mailable, MaxExceptions::class, 'maxExceptions');\n        $this->queue = $this->getAttributeValue($mailable, QueueAttribute::class, 'queue');\n        $this->shouldBeEncrypted = $mailable instanceof ShouldBeEncrypted;\n        $this->timeout = $this->getAttributeValue($mailable, Timeout::class, 'timeout');\n        $this->tries = $this->getAttributeValue($mailable, Tries::class, 'tries');\n    }\n\n    /**\n     * Handle the queued job.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Factory  $factory\n     * @return void\n     */\n    public function handle(MailFactory $factory)\n    {\n        $this->mailable->send($factory);\n    }\n\n    /**\n     * Get the number of seconds before a released mailable will be available.\n     *\n     * @return mixed\n     */\n    public function backoff()\n    {\n        $backoff = $this->getAttributeValue($this->mailable, Backoff::class, 'backoff');\n\n        if (method_exists($this->mailable, 'backoff')) {\n            $backoff = $this->mailable->backoff();\n        }\n\n        return $backoff;\n    }\n\n    /**\n     * Determine the time at which the job should timeout.\n     *\n     * @return \\DateTime|null\n     */\n    public function retryUntil()\n    {\n        if (! method_exists($this->mailable, 'retryUntil') && ! isset($this->mailable->retryUntil)) {\n            return;\n        }\n\n        return $this->mailable->retryUntil ?? $this->mailable->retryUntil();\n    }\n\n    /**\n     * Call the failed method on the mailable instance.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function failed($e)\n    {\n        if (method_exists($this->mailable, 'failed')) {\n            $this->mailable->failed($e);\n        }\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        return get_class($this->mailable);\n    }\n\n    /**\n     * Prepare the instance for cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->mailable = clone $this->mailable;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/SentMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Symfony\\Component\\Mailer\\SentMessage as SymfonySentMessage;\n\n/**\n * @mixin \\Symfony\\Component\\Mailer\\SentMessage\n */\nclass SentMessage\n{\n    use ForwardsCalls;\n\n    /**\n     * The Symfony SentMessage instance.\n     *\n     * @var \\Symfony\\Component\\Mailer\\SentMessage\n     */\n    protected $sentMessage;\n\n    /**\n     * Create a new SentMessage instance.\n     *\n     * @param  \\Symfony\\Component\\Mailer\\SentMessage  $sentMessage\n     */\n    public function __construct(SymfonySentMessage $sentMessage)\n    {\n        $this->sentMessage = $sentMessage;\n    }\n\n    /**\n     * Get the underlying Symfony Email instance.\n     *\n     * @return \\Symfony\\Component\\Mailer\\SentMessage\n     */\n    public function getSymfonySentMessage()\n    {\n        return $this->sentMessage;\n    }\n\n    /**\n     * Dynamically pass missing methods to the Symfony instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->sentMessage, $method, $parameters);\n    }\n\n    /**\n     * Get the serializable representation of the object.\n     *\n     * @return array\n     */\n    public function __serialize()\n    {\n        $hasAttachments = (new Collection($this->sentMessage->getOriginalMessage()->getAttachments()))->isNotEmpty();\n\n        return [\n            'hasAttachments' => $hasAttachments,\n            'sentMessage' => $hasAttachments ? base64_encode(serialize($this->sentMessage)) : $this->sentMessage,\n        ];\n    }\n\n    /**\n     * Marshal the object from its serialized data.\n     *\n     * @param  array  $data\n     * @return void\n     */\n    public function __unserialize(array $data)\n    {\n        $hasAttachments = ($data['hasAttachments'] ?? false) === true;\n\n        $this->sentMessage = $hasAttachments ? unserialize(base64_decode($data['sentMessage'])) : $data['sentMessage'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/TextMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail;\n\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\n\n/**\n * @mixin \\Illuminate\\Mail\\Message\n */\nclass TextMessage\n{\n    use ForwardsCalls;\n\n    /**\n     * The underlying message instance.\n     *\n     * @var \\Illuminate\\Mail\\Message\n     */\n    protected $message;\n\n    /**\n     * Create a new text message instance.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $message\n     */\n    public function __construct($message)\n    {\n        $this->message = $message;\n    }\n\n    /**\n     * Embed a file in the message and get the CID.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @return string\n     */\n    public function embed($file)\n    {\n        return '';\n    }\n\n    /**\n     * Embed in-memory data in the message and get the CID.\n     *\n     * @param  string|resource  $data\n     * @param  string  $name\n     * @param  string|null  $contentType\n     * @return string\n     */\n    public function embedData($data, $name, $contentType = null)\n    {\n        return '';\n    }\n\n    /**\n     * Dynamically pass missing methods to the underlying message instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardDecoratedCallTo($this->message, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Transport/ArrayTransport.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Transport;\n\nuse Illuminate\\Support\\Collection;\nuse Stringable;\nuse Symfony\\Component\\Mailer\\Envelope;\nuse Symfony\\Component\\Mailer\\SentMessage;\nuse Symfony\\Component\\Mailer\\Transport\\TransportInterface;\nuse Symfony\\Component\\Mime\\RawMessage;\n\nclass ArrayTransport implements Stringable, TransportInterface\n{\n    /**\n     * The collection of Symfony Messages.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $messages;\n\n    /**\n     * Create a new array transport instance.\n     */\n    public function __construct()\n    {\n        $this->messages = new Collection;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage\n    {\n        return $this->messages[] = new SentMessage($message, $envelope ?? Envelope::create($message));\n    }\n\n    /**\n     * Retrieve the collection of messages.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function messages()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Clear all of the messages from the local collection.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function flush()\n    {\n        return $this->messages = new Collection;\n    }\n\n    /**\n     * Get the string representation of the transport.\n     *\n     * @return string\n     */\n    public function __toString(): string\n    {\n        return 'array';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Transport/LogTransport.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Transport;\n\nuse Illuminate\\Support\\Str;\nuse Psr\\Log\\LoggerInterface;\nuse Stringable;\nuse Symfony\\Component\\Mailer\\Envelope;\nuse Symfony\\Component\\Mailer\\SentMessage;\nuse Symfony\\Component\\Mailer\\Transport\\TransportInterface;\nuse Symfony\\Component\\Mime\\RawMessage;\n\nclass LogTransport implements Stringable, TransportInterface\n{\n    /**\n     * The Logger instance.\n     *\n     * @var \\Psr\\Log\\LoggerInterface\n     */\n    protected $logger;\n\n    /**\n     * Create a new log transport instance.\n     *\n     * @param  \\Psr\\Log\\LoggerInterface  $logger\n     */\n    public function __construct(LoggerInterface $logger)\n    {\n        $this->logger = $logger;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage\n    {\n        $string = Str::of($message->toString());\n\n        if ($string->contains('Content-Type: multipart/')) {\n            $boundary = $string\n                ->after('boundary=')\n                ->before(\"\\r\\n\")\n                ->prepend('--')\n                ->append(\"\\r\\n\");\n\n            $string = $string\n                ->explode($boundary)\n                ->map($this->decodeQuotedPrintableContent(...))\n                ->implode($boundary);\n        } elseif ($string->contains('Content-Transfer-Encoding: quoted-printable')) {\n            $string = $this->decodeQuotedPrintableContent($string);\n        }\n\n        $this->logger->debug((string) $string);\n\n        return new SentMessage($message, $envelope ?? Envelope::create($message));\n    }\n\n    /**\n     * Decode the given quoted printable content.\n     *\n     * @param  string  $part\n     * @return string\n     */\n    protected function decodeQuotedPrintableContent(string $part)\n    {\n        if (! str_contains($part, 'Content-Transfer-Encoding: quoted-printable')) {\n            return $part;\n        }\n\n        [$headers, $content] = explode(\"\\r\\n\\r\\n\", $part, 2);\n\n        return implode(\"\\r\\n\\r\\n\", [\n            $headers,\n            quoted_printable_decode($content),\n        ]);\n    }\n\n    /**\n     * Get the logger for the LogTransport instance.\n     *\n     * @return \\Psr\\Log\\LoggerInterface\n     */\n    public function logger()\n    {\n        return $this->logger;\n    }\n\n    /**\n     * Get the string representation of the transport.\n     *\n     * @return string\n     */\n    public function __toString(): string\n    {\n        return 'log';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Transport/ResendTransport.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Transport;\n\nuse Exception;\nuse Resend\\Contracts\\Client;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Mailer\\Envelope;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Component\\Mailer\\SentMessage;\nuse Symfony\\Component\\Mailer\\Transport\\AbstractTransport;\nuse Symfony\\Component\\Mime\\Address;\nuse Symfony\\Component\\Mime\\Email;\nuse Symfony\\Component\\Mime\\MessageConverter;\n\n/*\nMIT License\n\nCopyright (c) 2023 Jayan Ratna\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*/\nclass ResendTransport extends AbstractTransport\n{\n    /**\n     * Create a new Resend transport instance.\n     */\n    public function __construct(protected Client $resend)\n    {\n        parent::__construct();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @throws \\Symfony\\Component\\Mailer\\Exception\\TransportException\n     * @throws \\Throwable\n     */\n    protected function doSend(SentMessage $message): void\n    {\n        $email = MessageConverter::toEmail($message->getOriginalMessage());\n\n        $envelope = $message->getEnvelope();\n\n        $headers = [];\n\n        $headersToBypass = ['from', 'to', 'cc', 'bcc', 'reply-to', 'sender', 'subject', 'content-type'];\n\n        foreach ($email->getHeaders()->all() as $name => $header) {\n            if (in_array($name, $headersToBypass, true)) {\n                continue;\n            }\n\n            $headers[$header->getName()] = $header->getBodyAsString();\n        }\n\n        $attachments = [];\n\n        if ($email->getAttachments()) {\n            foreach ($email->getAttachments() as $attachment) {\n                $attachmentHeaders = $attachment->getPreparedHeaders();\n                $contentType = $attachmentHeaders->get('Content-Type')->getBody();\n                $disposition = $attachmentHeaders->getHeaderBody('Content-Disposition');\n                $filename = $attachmentHeaders->getHeaderParameter('Content-Disposition', 'filename');\n\n                if ($contentType == 'text/calendar') {\n                    $content = $attachment->getBody();\n                } else {\n                    $content = str_replace(\"\\r\\n\", '', $attachment->bodyToString());\n                }\n\n                $item = [\n                    'content_type' => $contentType,\n                    'content' => $content,\n                    'filename' => $filename,\n                ];\n\n                if ($disposition === 'inline') {\n                    $item['content_id'] = $attachment->hasContentId() ? $attachment->getContentId() : $filename;\n                }\n\n                $attachments[] = $item;\n            }\n        }\n\n        try {\n            $result = $this->resend->emails->send([\n                'from' => $envelope->getSender()->toString(),\n                'to' => $this->stringifyAddresses($this->getRecipients($email, $envelope)),\n                'cc' => $this->stringifyAddresses($email->getCc()),\n                'bcc' => $this->stringifyAddresses($email->getBcc()),\n                'reply_to' => $this->stringifyAddresses($email->getReplyTo()),\n                'headers' => $headers,\n                'subject' => $email->getSubject(),\n                'html' => $email->getHtmlBody(),\n                'text' => $email->getTextBody(),\n                'attachments' => $attachments,\n            ]);\n\n            throw_if(isset($result['statusCode']) && $result['statusCode'] != Response::HTTP_OK, Exception::class, $result['message']);\n        } catch (Exception $exception) {\n            throw new TransportException(\n                sprintf('Request to Resend API failed. Reason: %s.', $exception->getMessage()),\n                is_int($exception->getCode()) ? $exception->getCode() : 0,\n                $exception\n            );\n        }\n\n        $messageId = $result->id;\n\n        $email->getHeaders()->addHeader('X-Resend-Email-ID', $messageId);\n    }\n\n    /**\n     * Get the recipients without CC or BCC.\n     */\n    protected function getRecipients(Email $email, Envelope $envelope): array\n    {\n        return array_filter($envelope->getRecipients(), function (Address $address) use ($email) {\n            return in_array($address, array_merge($email->getCc(), $email->getBcc()), true) === false;\n        });\n    }\n\n    /**\n     * Get the string representation of the transport.\n     */\n    public function __toString(): string\n    {\n        return 'resend';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Transport/SesTransport.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Transport;\n\nuse Aws\\Exception\\AwsException;\nuse Aws\\Ses\\SesClient;\nuse Illuminate\\Support\\Collection;\nuse Stringable;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mailer\\SentMessage;\nuse Symfony\\Component\\Mailer\\Transport\\AbstractTransport;\nuse Symfony\\Component\\Mime\\Message;\n\nclass SesTransport extends AbstractTransport implements Stringable\n{\n    /**\n     * The Amazon SES instance.\n     *\n     * @var \\Aws\\Ses\\SesClient\n     */\n    protected $ses;\n\n    /**\n     * The Amazon SES transmission options.\n     *\n     * @var array\n     */\n    protected $options = [];\n\n    /**\n     * Create a new SES transport instance.\n     *\n     * @param  \\Aws\\Ses\\SesClient  $ses\n     * @param  array  $options\n     */\n    public function __construct(SesClient $ses, $options = [])\n    {\n        $this->ses = $ses;\n        $this->options = $options;\n\n        parent::__construct();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @throws \\Symfony\\Component\\Mailer\\Exception\\TransportException\n     */\n    protected function doSend(SentMessage $message): void\n    {\n        $options = $this->options;\n\n        if ($message->getOriginalMessage() instanceof Message) {\n            if ($listManagementOptions = $this->listManagementOptions($message)) {\n                $options['ListManagementOptions'] = $listManagementOptions;\n            }\n\n            foreach ($message->getOriginalMessage()->getHeaders()->all() as $header) {\n                if ($header instanceof MetadataHeader) {\n                    $options['Tags'][] = ['Name' => $header->getKey(), 'Value' => $header->getValue()];\n                }\n            }\n        }\n\n        try {\n            $result = $this->ses->sendRawEmail(\n                array_merge(\n                    $options, [\n                        'Source' => $message->getEnvelope()->getSender()->toString(),\n                        'Destinations' => (new Collection($message->getEnvelope()->getRecipients()))\n                            ->map\n                            ->toString()\n                            ->values()\n                            ->all(),\n                        'RawMessage' => [\n                            'Data' => $message->toString(),\n                        ],\n                    ]\n                )\n            );\n        } catch (AwsException $e) {\n            $reason = $e->getAwsErrorMessage() ?? $e->getMessage();\n\n            throw new TransportException(\n                sprintf('Request to AWS SES API failed. Reason: %s.', $reason),\n                is_int($e->getCode()) ? $e->getCode() : 0,\n                $e\n            );\n        }\n\n        $messageId = $result->get('MessageId');\n\n        $message->getOriginalMessage()->getHeaders()->addHeader('X-Message-ID', $messageId);\n        $message->getOriginalMessage()->getHeaders()->addHeader('X-SES-Message-ID', $messageId);\n    }\n\n    /**\n     * Extract the SES list management options, if applicable.\n     *\n     * @param  \\Symfony\\Component\\Mailer\\SentMessage  $message\n     * @return array|null\n     */\n    protected function listManagementOptions(SentMessage $message)\n    {\n        if ($header = $message->getOriginalMessage()->getHeaders()->get('X-SES-LIST-MANAGEMENT-OPTIONS')) {\n            if (preg_match(\"/^(contactListName=)*(?<ContactListName>[^;]+)(;\\s?topicName=(?<TopicName>.+))?$/ix\", $header->getBodyAsString(), $listManagementOptions)) {\n                return array_filter($listManagementOptions, fn ($e) => in_array($e, ['ContactListName', 'TopicName']), ARRAY_FILTER_USE_KEY);\n            }\n        }\n    }\n\n    /**\n     * Get the Amazon SES client for the SesTransport instance.\n     *\n     * @return \\Aws\\Ses\\SesClient\n     */\n    public function ses()\n    {\n        return $this->ses;\n    }\n\n    /**\n     * Get the transmission options being used by the transport.\n     *\n     * @return array\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * Set the transmission options being used by the transport.\n     *\n     * @param  array  $options\n     * @return array\n     */\n    public function setOptions(array $options)\n    {\n        return $this->options = $options;\n    }\n\n    /**\n     * Get the string representation of the transport.\n     *\n     * @return string\n     */\n    public function __toString(): string\n    {\n        return 'ses';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/Transport/SesV2Transport.php",
    "content": "<?php\n\nnamespace Illuminate\\Mail\\Transport;\n\nuse Aws\\Exception\\AwsException;\nuse Aws\\SesV2\\SesV2Client;\nuse Illuminate\\Support\\Collection;\nuse Stringable;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mailer\\SentMessage;\nuse Symfony\\Component\\Mailer\\Transport\\AbstractTransport;\nuse Symfony\\Component\\Mime\\Message;\n\nclass SesV2Transport extends AbstractTransport implements Stringable\n{\n    /**\n     * The Amazon SES V2 instance.\n     *\n     * @var \\Aws\\SesV2\\SesV2Client\n     */\n    protected $ses;\n\n    /**\n     * The Amazon SES transmission options.\n     *\n     * @var array\n     */\n    protected $options = [];\n\n    /**\n     * Create a new SES V2 transport instance.\n     *\n     * @param  \\Aws\\SesV2\\SesV2Client  $ses\n     * @param  array  $options\n     */\n    public function __construct(SesV2Client $ses, $options = [])\n    {\n        $this->ses = $ses;\n        $this->options = $options;\n\n        parent::__construct();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @throws \\Symfony\\Component\\Mailer\\Exception\\TransportException\n     */\n    protected function doSend(SentMessage $message): void\n    {\n        $options = $this->options;\n\n        if ($message->getOriginalMessage() instanceof Message) {\n            if ($listManagementOptions = $this->listManagementOptions($message)) {\n                $options['ListManagementOptions'] = $listManagementOptions;\n            }\n\n            foreach ($message->getOriginalMessage()->getHeaders()->all() as $header) {\n                if ($header instanceof MetadataHeader) {\n                    $options['EmailTags'][] = ['Name' => $header->getKey(), 'Value' => $header->getValue()];\n                }\n            }\n        }\n\n        try {\n            $result = $this->ses->sendEmail(\n                array_merge(\n                    $options, [\n                        'Source' => $message->getEnvelope()->getSender()->toString(),\n                        'Destination' => [\n                            'ToAddresses' => (new Collection($message->getEnvelope()->getRecipients()))\n                                ->map\n                                ->toString()\n                                ->values()\n                                ->all(),\n                        ],\n                        'Content' => [\n                            'Raw' => [\n                                'Data' => $message->toString(),\n                            ],\n                        ],\n                    ]\n                )\n            );\n        } catch (AwsException $e) {\n            $reason = $e->getAwsErrorMessage() ?? $e->getMessage();\n\n            throw new TransportException(\n                sprintf('Request to AWS SES V2 API failed. Reason: %s.', $reason),\n                is_int($e->getCode()) ? $e->getCode() : 0,\n                $e\n            );\n        }\n\n        $messageId = $result->get('MessageId');\n\n        $message->getOriginalMessage()->getHeaders()->addHeader('X-Message-ID', $messageId);\n        $message->getOriginalMessage()->getHeaders()->addHeader('X-SES-Message-ID', $messageId);\n    }\n\n    /**\n     * Extract the SES list managenent options, if applicable.\n     *\n     * @param  \\Symfony\\Component\\Mailer\\SentMessage  $message\n     * @return array|null\n     */\n    protected function listManagementOptions(SentMessage $message)\n    {\n        if ($header = $message->getOriginalMessage()->getHeaders()->get('X-SES-LIST-MANAGEMENT-OPTIONS')) {\n            if (preg_match(\"/^(contactListName=)*(?<ContactListName>[^;]+)(;\\s?topicName=(?<TopicName>.+))?$/ix\", $header->getBodyAsString(), $listManagementOptions)) {\n                return array_filter($listManagementOptions, fn ($e) => in_array($e, ['ContactListName', 'TopicName']), ARRAY_FILTER_USE_KEY);\n            }\n        }\n    }\n\n    /**\n     * Get the Amazon SES V2 client for the SesV2Transport instance.\n     *\n     * @return \\Aws\\SesV2\\SesV2Client\n     */\n    public function ses()\n    {\n        return $this->ses;\n    }\n\n    /**\n     * Get the transmission options being used by the transport.\n     *\n     * @return array\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * Set the transmission options being used by the transport.\n     *\n     * @param  array  $options\n     * @return array\n     */\n    public function setOptions(array $options)\n    {\n        return $this->options = $options;\n    }\n\n    /**\n     * Get the string representation of the transport.\n     *\n     * @return string\n     */\n    public function __toString(): string\n    {\n        return 'ses-v2';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/composer.json",
    "content": "{\n    \"name\": \"illuminate/mail\",\n    \"description\": \"The Illuminate Mail package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"league/commonmark\": \"^2.7\",\n        \"psr/log\": \"^1.0 || ^2.0 || ^3.0\",\n        \"symfony/mailer\": \"^7.4.0 || ^8.0.0\",\n        \"tijsverkoyen/css-to-inline-styles\": \"^2.2.5\"\n    },\n    \"suggest\": {\n        \"aws/aws-sdk-php\": \"Required to use the SES mail driver (^3.322.9).\",\n        \"illuminate/http\": \"Required to create an attachment from an UploadedFile instance (^13.0).\",\n        \"resend/resend-php\": \"Required to enable support for the Resend mail transport (^1.0).\",\n        \"symfony/http-client\": \"Required to use the Symfony API mail transports (^7.4 || ^8.0).\",\n        \"symfony/mailgun-mailer\": \"Required to enable support for the Mailgun mail transport (^7.4 || ^8.0).\",\n        \"symfony/postmark-mailer\": \"Required to enable support for the Postmark mail transport (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Mail\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/button.blade.php",
    "content": "@props([\n    'url',\n    'color' => 'primary',\n    'align' => 'center',\n])\n<table class=\"action\" align=\"{{ $align }}\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td align=\"{{ $align }}\">\n<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td align=\"{{ $align }}\">\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td>\n<a href=\"{{ $url }}\" class=\"button button-{{ $color }}\" target=\"_blank\" rel=\"noopener\">{!! $slot !!}</a>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/footer.blade.php",
    "content": "<tr>\n<td>\n<table class=\"footer\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td class=\"content-cell\" align=\"center\">\n{{ Illuminate\\Mail\\Markdown::parse($slot) }}\n</td>\n</tr>\n</table>\n</td>\n</tr>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/header.blade.php",
    "content": "@props(['url'])\n<tr>\n<td class=\"header\">\n<a href=\"{{ $url }}\" style=\"display: inline-block;\">\n@if (trim($slot) === 'Laravel')\n<img src=\"https://laravel.com/img/notification-logo-v2.1.png\" class=\"logo\" alt=\"Laravel Logo\">\n@else\n{!! $slot !!}\n@endif\n</a>\n</td>\n</tr>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/layout.blade.php",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"{{ str_replace('_', '-', app()->getLocale()) }}\">\n<head>\n<title>{{ config('app.name') }}</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n<meta name=\"color-scheme\" content=\"light\">\n<meta name=\"supported-color-schemes\" content=\"light\">\n<style>\n@media only screen and (max-width: 600px) {\n.inner-body {\nwidth: 100% !important;\n}\n\n.footer {\nwidth: 100% !important;\n}\n}\n\n@media only screen and (max-width: 500px) {\n.button {\nwidth: 100% !important;\n}\n}\n</style>\n{!! $head ?? '' !!}\n</head>\n<body>\n\n<table class=\"wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td align=\"center\">\n<table class=\"content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n{!! $header ?? '' !!}\n\n<!-- Email Body -->\n<tr>\n<td class=\"body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: hidden !important;\">\n<table class=\"inner-body\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<!-- Body content -->\n<tr>\n<td class=\"content-cell\">\n{!! Illuminate\\Mail\\Markdown::parse($slot) !!}\n\n{!! $subcopy ?? '' !!}\n</td>\n</tr>\n</table>\n</td>\n</tr>\n\n{!! $footer ?? '' !!}\n</table>\n</td>\n</tr>\n</table>\n</body>\n</html>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/message.blade.php",
    "content": "<x-mail::layout>\n{{-- Header --}}\n<x-slot:header>\n<x-mail::header :url=\"config('app.url')\">\n{{ config('app.name') }}\n</x-mail::header>\n</x-slot:header>\n\n{{-- Body --}}\n{!! $slot !!}\n\n{{-- Subcopy --}}\n@isset($subcopy)\n<x-slot:subcopy>\n<x-mail::subcopy>\n{!! $subcopy !!}\n</x-mail::subcopy>\n</x-slot:subcopy>\n@endisset\n\n{{-- Footer --}}\n<x-slot:footer>\n<x-mail::footer>\n© {{ date('Y') }} {{ config('app.name') }}. {{ __('All rights reserved.') }}\n</x-mail::footer>\n</x-slot:footer>\n</x-mail::layout>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/panel.blade.php",
    "content": "<table class=\"panel\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td class=\"panel-content\">\n<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td class=\"panel-item\">\n{{ Illuminate\\Mail\\Markdown::parse($slot) }}\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/subcopy.blade.php",
    "content": "<table class=\"subcopy\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" role=\"presentation\">\n<tr>\n<td>\n{{ Illuminate\\Mail\\Markdown::parse($slot) }}\n</td>\n</tr>\n</table>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/table.blade.php",
    "content": "<div class=\"table\">\n{{ Illuminate\\Mail\\Markdown::parse($slot) }}\n</div>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/html/themes/default.css",
    "content": "/* Base */\n\nbody,\nbody *:not(html):not(style):not(br):not(tr):not(code) {\n    box-sizing: border-box;\n    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,\n        'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n    position: relative;\n}\n\nbody {\n    -webkit-text-size-adjust: none;\n    background-color: #ffffff;\n    color: #52525b;\n    height: 100%;\n    line-height: 1.4;\n    margin: 0;\n    padding: 0;\n    width: 100% !important;\n}\n\np,\nul,\nol,\nblockquote {\n    line-height: 1.4;\n    text-align: start;\n}\n\na {\n    color: #18181b;\n}\n\na img {\n    border: none;\n}\n\n/* Typography */\n\nh1 {\n    color: #18181b;\n    font-size: 18px;\n    font-weight: bold;\n    margin-top: 0;\n    text-align: start;\n}\n\nh2 {\n    font-size: 16px;\n    font-weight: bold;\n    margin-top: 0;\n    text-align: start;\n}\n\nh3 {\n    font-size: 14px;\n    font-weight: bold;\n    margin-top: 0;\n    text-align: left;\n}\n\np {\n    font-size: 16px;\n    line-height: 1.5em;\n    margin-top: 0;\n    text-align: left;\n}\n\np.sub {\n    font-size: 12px;\n}\n\nimg {\n    max-width: 100%;\n}\n\n/* Layout */\n\n.wrapper {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 100%;\n    background-color: #fafafa;\n    margin: 0;\n    padding: 0;\n    width: 100%;\n}\n\n.content {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 100%;\n    margin: 0;\n    padding: 0;\n    width: 100%;\n}\n\n/* Header */\n\n.header {\n    padding: 25px 0;\n    text-align: center;\n}\n\n.header a {\n    color: #18181b;\n    font-size: 19px;\n    font-weight: bold;\n    text-decoration: none;\n}\n\n/* Logo */\n\n.logo {\n    height: 75px;\n    margin-top: 15px;\n    margin-bottom: 10px;\n    max-height: 75px;\n    width: 75px;\n}\n\n/* Body */\n\n.body {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 100%;\n    background-color: #fafafa;\n    border-bottom: 1px solid #fafafa;\n    border-top: 1px solid #fafafa;\n    margin: 0;\n    padding: 0;\n    width: 100%;\n}\n\n.inner-body {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 570px;\n    background-color: #ffffff;\n    border-color: #e4e4e7;\n    border-radius: 4px;\n    border-width: 1px;\n    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);\n    margin: 0 auto;\n    padding: 0;\n    width: 570px;\n}\n\n.inner-body a {\n    word-break: break-all;\n}\n\n/* Subcopy */\n\n.subcopy {\n    border-top: 1px solid #e4e4e7;\n    margin-top: 25px;\n    padding-top: 25px;\n}\n\n.subcopy p {\n    font-size: 14px;\n}\n\n/* Footer */\n\n.footer {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 570px;\n    margin: 0 auto;\n    padding: 0;\n    text-align: center;\n    width: 570px;\n}\n\n.footer p {\n    color: #a1a1aa;\n    font-size: 12px;\n    text-align: center;\n}\n\n.footer a {\n    color: #a1a1aa;\n    text-decoration: underline;\n}\n\n/* Tables */\n\n.table table {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 100%;\n    margin: 30px auto;\n    width: 100%;\n}\n\n.table th {\n    border-bottom: 1px solid #e4e4e7;\n    margin: 0;\n    padding-bottom: 8px;\n}\n\n.table td {\n    color: #52525b;\n    font-size: 15px;\n    line-height: 18px;\n    margin: 0;\n    padding: 10px 0;\n}\n\n.content-cell {\n    max-width: 100vw;\n    padding: 32px;\n}\n\n/* Buttons */\n\n.action {\n    -premailer-cellpadding: 0;\n    -premailer-cellspacing: 0;\n    -premailer-width: 100%;\n    margin: 30px auto;\n    padding: 0;\n    text-align: center;\n    width: 100%;\n    float: unset;\n}\n\n.button {\n    -webkit-text-size-adjust: none;\n    border-radius: 4px;\n    color: #fff;\n    display: inline-block;\n    overflow: hidden;\n    text-decoration: none;\n}\n\n.button-blue,\n.button-primary {\n    background-color: #18181b;\n    border-bottom: 8px solid #18181b;\n    border-left: 18px solid #18181b;\n    border-right: 18px solid #18181b;\n    border-top: 8px solid #18181b;\n}\n\n.button-green,\n.button-success {\n    background-color: #16a34a;\n    border-bottom: 8px solid #16a34a;\n    border-left: 18px solid #16a34a;\n    border-right: 18px solid #16a34a;\n    border-top: 8px solid #16a34a;\n}\n\n.button-red,\n.button-error {\n    background-color: #dc2626;\n    border-bottom: 8px solid #dc2626;\n    border-left: 18px solid #dc2626;\n    border-right: 18px solid #dc2626;\n    border-top: 8px solid #dc2626;\n}\n\n/* Panels */\n\n.panel {\n    border-left: #18181b solid 4px;\n    margin: 21px 0;\n}\n\n.panel-content {\n    background-color: #fafafa;\n    color: #52525b;\n    padding: 16px;\n}\n\n.panel-content p {\n    color: #52525b;\n}\n\n.panel-item {\n    padding: 0;\n}\n\n.panel-item p:last-of-type {\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\n/* Utilities */\n\n.break-all {\n    word-break: break-all;\n}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/button.blade.php",
    "content": "{{ $slot }}: {{ $url }}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/footer.blade.php",
    "content": "{{ $slot }}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/header.blade.php",
    "content": "{{ $slot }}: {{ $url }}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/layout.blade.php",
    "content": "{!! strip_tags($header ?? '') !!}\n\n{!! strip_tags($slot) !!}\n@isset($subcopy)\n\n{!! strip_tags($subcopy) !!}\n@endisset\n\n{!! strip_tags($footer ?? '') !!}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/message.blade.php",
    "content": "<x-mail::layout>\n    {{-- Header --}}\n    <x-slot:header>\n        <x-mail::header :url=\"config('app.url')\">\n            {{ config('app.name') }}\n        </x-mail::header>\n    </x-slot:header>\n\n    {{-- Body --}}\n    {{ $slot }}\n\n    {{-- Subcopy --}}\n    @isset($subcopy)\n        <x-slot:subcopy>\n            <x-mail::subcopy>\n                {{ $subcopy }}\n            </x-mail::subcopy>\n        </x-slot:subcopy>\n    @endisset\n\n    {{-- Footer --}}\n    <x-slot:footer>\n        <x-mail::footer>\n            © {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')\n        </x-mail::footer>\n    </x-slot:footer>\n</x-mail::layout>\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/panel.blade.php",
    "content": "{{ $slot }}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/subcopy.blade.php",
    "content": "{{ $slot }}\n"
  },
  {
    "path": "src/Illuminate/Mail/resources/views/text/table.blade.php",
    "content": "{{ $slot }}\n"
  },
  {
    "path": "src/Illuminate/Notifications/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Notifications/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Notifications/Action.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nclass Action\n{\n    /**\n     * The action text.\n     *\n     * @var string\n     */\n    public $text;\n\n    /**\n     * The action URL.\n     *\n     * @var string\n     */\n    public $url;\n\n    /**\n     * Create a new action instance.\n     *\n     * @param  string  $text\n     * @param  string  $url\n     */\n    public function __construct($text, $url)\n    {\n        $this->url = $url;\n        $this->text = $text;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/AnonymousNotifiable.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Contracts\\Notifications\\Dispatcher;\nuse InvalidArgumentException;\n\nclass AnonymousNotifiable\n{\n    /**\n     * All of the notification routing information.\n     *\n     * @var array\n     */\n    public $routes = [];\n\n    /**\n     * Add routing information to the target.\n     *\n     * @param  string  $channel\n     * @param  mixed  $route\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function route($channel, $route)\n    {\n        if ($channel === 'database') {\n            throw new InvalidArgumentException('The database channel does not support on-demand notifications.');\n        }\n\n        $this->routes[$channel] = $route;\n\n        return $this;\n    }\n\n    /**\n     * Send the given notification.\n     *\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function notify($notification)\n    {\n        app(Dispatcher::class)->send($this, $notification);\n    }\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function notifyNow($notification)\n    {\n        app(Dispatcher::class)->sendNow($this, $notification);\n    }\n\n    /**\n     * Get the notification routing information for the given driver.\n     *\n     * @param  string  $driver\n     * @return mixed\n     */\n    public function routeNotificationFor($driver)\n    {\n        return $this->routes[$driver] ?? null;\n    }\n\n    /**\n     * Get the value of the notifiable's primary key.\n     *\n     * @return mixed\n     */\n    public function getKey()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/ChannelManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Contracts\\Bus\\Dispatcher as Bus;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Notifications\\Dispatcher as DispatcherContract;\nuse Illuminate\\Contracts\\Notifications\\Factory as FactoryContract;\nuse Illuminate\\Support\\Manager;\nuse Illuminate\\Support\\Queue\\Concerns\\ResolvesQueueRoutes;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\nclass ChannelManager extends Manager implements DispatcherContract, FactoryContract\n{\n    use Macroable, ResolvesQueueRoutes;\n\n    /**\n     * The resolved notification sender instance.\n     *\n     * @var \\Illuminate\\Notifications\\NotificationSender|null\n     */\n    protected $notificationSender;\n\n    /**\n     * The default channel used to deliver messages.\n     *\n     * @var string\n     */\n    protected $defaultChannel = 'mail';\n\n    /**\n     * The locale used when sending notifications.\n     *\n     * @var string|null\n     */\n    protected $locale;\n\n    /**\n     * Send the given notification to the given notifiable entities.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function send($notifiables, $notification)\n    {\n        $this->resolveNotificationSender()->send($notifiables, $notification);\n    }\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @param  array|null  $channels\n     * @return void\n     */\n    public function sendNow($notifiables, $notification, ?array $channels = null)\n    {\n        $this->resolveNotificationSender()->sendNow($notifiables, $notification, $channels);\n    }\n\n    /**\n     * Get a channel instance.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function channel($name = null)\n    {\n        return $this->driver($name);\n    }\n\n    /**\n     * Create an instance of the database driver.\n     *\n     * @return \\Illuminate\\Notifications\\Channels\\DatabaseChannel\n     */\n    protected function createDatabaseDriver()\n    {\n        return $this->container->make(Channels\\DatabaseChannel::class);\n    }\n\n    /**\n     * Create an instance of the broadcast driver.\n     *\n     * @return \\Illuminate\\Notifications\\Channels\\BroadcastChannel\n     */\n    protected function createBroadcastDriver()\n    {\n        return $this->container->make(Channels\\BroadcastChannel::class);\n    }\n\n    /**\n     * Create an instance of the mail driver.\n     *\n     * @return \\Illuminate\\Notifications\\Channels\\MailChannel\n     */\n    protected function createMailDriver()\n    {\n        return $this->container->make(Channels\\MailChannel::class);\n    }\n\n    /**\n     * Create a new driver instance.\n     *\n     * @param  string  $driver\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function createDriver($driver)\n    {\n        try {\n            return parent::createDriver($driver);\n        } catch (InvalidArgumentException $e) {\n            if (class_exists($driver)) {\n                return $this->container->make($driver);\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Resolve the NotificationSender instance.\n     *\n     * @return \\Illuminate\\Notifications\\NotificationSender\n     */\n    protected function resolveNotificationSender()\n    {\n        return $this->notificationSender ??= new NotificationSender(\n            $this, $this->container->make(Bus::class), $this->container->make(Dispatcher::class), $this->locale\n        );\n    }\n\n    /**\n     * Get the default channel driver name.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->defaultChannel;\n    }\n\n    /**\n     * Get the default channel driver name.\n     *\n     * @return string\n     */\n    public function deliversVia()\n    {\n        return $this->getDefaultDriver();\n    }\n\n    /**\n     * Set the default channel driver name.\n     *\n     * @param  string  $channel\n     * @return void\n     */\n    public function deliverVia($channel)\n    {\n        $this->defaultChannel = $channel;\n    }\n\n    /**\n     * Set the locale of notifications.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale)\n    {\n        $this->locale = $locale;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Channels/BroadcastChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Channels;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Notifications\\Events\\BroadcastNotificationCreated;\nuse Illuminate\\Notifications\\Messages\\BroadcastMessage;\nuse Illuminate\\Notifications\\Notification;\nuse RuntimeException;\n\nclass BroadcastChannel\n{\n    /**\n     * The event dispatcher.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * Create a new broadcast channel.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     */\n    public function __construct(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Send the given notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return array|null\n     */\n    public function send($notifiable, Notification $notification)\n    {\n        $message = $this->getData($notifiable, $notification);\n\n        $event = new BroadcastNotificationCreated(\n            $notifiable, $notification, is_array($message) ? $message : $message->data\n        );\n\n        if ($message instanceof BroadcastMessage) {\n            $event->onConnection($message->connection)\n                ->onQueue($message->queue);\n        }\n\n        return $this->events->dispatch($event);\n    }\n\n    /**\n     * Get the data for the notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getData($notifiable, Notification $notification)\n    {\n        if (method_exists($notification, 'toBroadcast')) {\n            return $notification->toBroadcast($notifiable);\n        }\n\n        if (method_exists($notification, 'toArray')) {\n            return $notification->toArray($notifiable);\n        }\n\n        throw new RuntimeException('Notification is missing toBroadcast / toArray method.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Channels/DatabaseChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Channels;\n\nuse Illuminate\\Notifications\\Notification;\nuse RuntimeException;\n\nclass DatabaseChannel\n{\n    /**\n     * Send the given notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return \\Illuminate\\Database\\Eloquent\\Model\n     */\n    public function send($notifiable, Notification $notification)\n    {\n        return $notifiable->routeNotificationFor('database', $notification)->create(\n            $this->buildPayload($notifiable, $notification)\n        );\n    }\n\n    /**\n     * Build an array payload for the DatabaseNotification Model.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return array\n     */\n    protected function buildPayload($notifiable, Notification $notification)\n    {\n        return [\n            'id' => $notification->id,\n            'type' => method_exists($notification, 'databaseType')\n                ? $notification->databaseType($notifiable)\n                : get_class($notification),\n            'data' => $this->getData($notifiable, $notification),\n            'read_at' => method_exists($notification, 'initialDatabaseReadAtValue')\n                ? $notification->initialDatabaseReadAtValue($notifiable)\n                : null,\n        ];\n    }\n\n    /**\n     * Get the data for the notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getData($notifiable, Notification $notification)\n    {\n        if (method_exists($notification, 'toDatabase')) {\n            return is_array($data = $notification->toDatabase($notifiable))\n                ? $data\n                : $data->data;\n        }\n\n        if (method_exists($notification, 'toArray')) {\n            return $notification->toArray($notifiable);\n        }\n\n        throw new RuntimeException('Notification is missing toDatabase / toArray method.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Channels/MailChannel.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Channels;\n\nuse Illuminate\\Config\\Repository as ConfigRepository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Mail\\Factory as MailFactory;\nuse Illuminate\\Contracts\\Mail\\Mailable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mailer\\Header\\TagHeader;\n\nclass MailChannel\n{\n    /**\n     * The mailer implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Mail\\Factory\n     */\n    protected $mailer;\n\n    /**\n     * The markdown implementation.\n     *\n     * @var \\Illuminate\\Mail\\Markdown\n     */\n    protected $markdown;\n\n    /**\n     * Create a new mail channel instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Factory  $mailer\n     * @param  \\Illuminate\\Mail\\Markdown  $markdown\n     */\n    public function __construct(MailFactory $mailer, Markdown $markdown)\n    {\n        $this->mailer = $mailer;\n        $this->markdown = $markdown;\n    }\n\n    /**\n     * Send the given notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return \\Illuminate\\Mail\\SentMessage|null\n     */\n    public function send($notifiable, Notification $notification)\n    {\n        $message = $notification->toMail($notifiable);\n\n        if (! $notifiable->routeNotificationFor('mail', $notification) &&\n            ! $message instanceof Mailable) {\n            return;\n        }\n\n        if ($message instanceof Mailable) {\n            return $message->send($this->mailer);\n        }\n\n        return $this->mailer->mailer($message->mailer ?? null)->send(\n            $this->buildView($message),\n            array_merge($message->data(), $this->additionalMessageData($notification)),\n            $this->messageBuilder($notifiable, $notification, $message)\n        );\n    }\n\n    /**\n     * Get the mailer Closure for the message.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return \\Closure\n     */\n    protected function messageBuilder($notifiable, $notification, $message)\n    {\n        return function ($mailMessage) use ($notifiable, $notification, $message) {\n            $this->buildMessage($mailMessage, $notifiable, $notification, $message);\n        };\n    }\n\n    /**\n     * Build the notification's view.\n     *\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return string|array\n     */\n    protected function buildView($message)\n    {\n        if ($message->view) {\n            return $message->view;\n        }\n\n        return [\n            'html' => $this->buildMarkdownHtml($message),\n            'text' => $this->buildMarkdownText($message),\n        ];\n    }\n\n    /**\n     * Build the HTML view for a Markdown message.\n     *\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return \\Closure\n     */\n    protected function buildMarkdownHtml($message)\n    {\n        return fn ($data) => $this->markdownRenderer($message)->render(\n            $message->markdown, array_merge($data, $message->data()),\n        );\n    }\n\n    /**\n     * Build the text view for a Markdown message.\n     *\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return \\Closure\n     */\n    protected function buildMarkdownText($message)\n    {\n        return fn ($data) => $this->markdownRenderer($message)->renderText(\n            $message->markdown, array_merge($data, $message->data()),\n        );\n    }\n\n    /**\n     * Get the Markdown implementation.\n     *\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return \\Illuminate\\Mail\\Markdown\n     */\n    protected function markdownRenderer($message)\n    {\n        $config = Container::getInstance()->get(ConfigRepository::class);\n\n        $theme = $message->theme ?? $config->get('mail.markdown.theme', 'default');\n\n        return $this->markdown->theme($theme);\n    }\n\n    /**\n     * Get additional meta-data to pass along with the view data.\n     *\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return array\n     */\n    protected function additionalMessageData($notification)\n    {\n        return [\n            '__laravel_notification_id' => $notification->id,\n            '__laravel_notification' => get_class($notification),\n            '__laravel_notification_queued' => in_array(\n                ShouldQueue::class,\n                class_implements($notification)\n            ),\n        ];\n    }\n\n    /**\n     * Build the mail message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $mailMessage\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return void\n     */\n    protected function buildMessage($mailMessage, $notifiable, $notification, $message)\n    {\n        $this->addressMessage($mailMessage, $notifiable, $notification, $message);\n\n        $mailMessage->subject($message->subject ?: Str::title(\n            Str::snake(class_basename($notification), ' ')\n        ));\n\n        $this->addAttachments($mailMessage, $message);\n\n        if (! is_null($message->priority)) {\n            $mailMessage->priority($message->priority);\n        }\n\n        if ($message->tags) {\n            foreach ($message->tags as $tag) {\n                $mailMessage->getHeaders()->add(new TagHeader($tag));\n            }\n        }\n\n        if ($message->metadata) {\n            foreach ($message->metadata as $key => $value) {\n                $mailMessage->getHeaders()->add(new MetadataHeader($key, $value));\n            }\n        }\n\n        $this->runCallbacks($mailMessage, $message);\n    }\n\n    /**\n     * Address the mail message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $mailMessage\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return void\n     */\n    protected function addressMessage($mailMessage, $notifiable, $notification, $message)\n    {\n        $this->addSender($mailMessage, $message);\n\n        $mailMessage->to($this->getRecipients($notifiable, $notification, $message));\n\n        if (! empty($message->cc)) {\n            foreach ($message->cc as $cc) {\n                $mailMessage->cc($cc[0], Arr::get($cc, 1));\n            }\n        }\n\n        if (! empty($message->bcc)) {\n            foreach ($message->bcc as $bcc) {\n                $mailMessage->bcc($bcc[0], Arr::get($bcc, 1));\n            }\n        }\n    }\n\n    /**\n     * Add the \"from\" and \"reply to\" addresses to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $mailMessage\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return void\n     */\n    protected function addSender($mailMessage, $message)\n    {\n        if (! empty($message->from)) {\n            $mailMessage->from($message->from[0], Arr::get($message->from, 1));\n        }\n\n        if (! empty($message->replyTo)) {\n            foreach ($message->replyTo as $replyTo) {\n                $mailMessage->replyTo($replyTo[0], Arr::get($replyTo, 1));\n            }\n        }\n    }\n\n    /**\n     * Get the recipients of the given message.\n     *\n     * @param  mixed  $notifiable\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return mixed\n     */\n    protected function getRecipients($notifiable, $notification, $message)\n    {\n        if (is_string($recipients = $notifiable->routeNotificationFor('mail', $notification))) {\n            $recipients = [$recipients];\n        }\n\n        return (new Collection($recipients))\n            ->mapWithKeys(function ($recipient, $email) {\n                return is_numeric($email)\n                    ? [$email => (is_string($recipient) ? $recipient : $recipient->email)]\n                    : [$email => $recipient];\n            })\n            ->all();\n    }\n\n    /**\n     * Add the attachments to the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $mailMessage\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return void\n     */\n    protected function addAttachments($mailMessage, $message)\n    {\n        foreach ($message->attachments as $attachment) {\n            $mailMessage->attach($attachment['file'], $attachment['options']);\n        }\n\n        foreach ($message->rawAttachments as $attachment) {\n            $mailMessage->attachData($attachment['data'], $attachment['name'], $attachment['options']);\n        }\n    }\n\n    /**\n     * Run the callbacks for the message.\n     *\n     * @param  \\Illuminate\\Mail\\Message  $mailMessage\n     * @param  \\Illuminate\\Notifications\\Messages\\MailMessage  $message\n     * @return $this\n     */\n    protected function runCallbacks($mailMessage, $message)\n    {\n        foreach ($message->callbacks as $callback) {\n            $callback($mailMessage->getSymfonyMessage());\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Console/NotificationTableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'make:notifications-table', aliases: ['notifications:table'])]\nclass NotificationTableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:notifications-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['notifications:table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the notifications table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return 'notifications';\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/notifications.stub';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Console/stubs/notifications.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('notifications', function (Blueprint $table) {\n            $table->uuid('id')->primary();\n            $table->string('type');\n            $table->morphs('notifiable');\n            $table->text('data');\n            $table->timestamp('read_at')->nullable();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('notifications');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Notifications/DatabaseNotification.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\HasCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass DatabaseNotification extends Model\n{\n    /** @use HasCollection<DatabaseNotificationCollection> */\n    use HasCollection;\n\n    /**\n     * The \"type\" of the primary key ID.\n     *\n     * @var string\n     */\n    protected $keyType = 'string';\n\n    /**\n     * Indicates if the IDs are auto-incrementing.\n     *\n     * @var bool\n     */\n    public $incrementing = false;\n\n    /**\n     * The table associated with the model.\n     *\n     * @var string\n     */\n    protected $table = 'notifications';\n\n    /**\n     * The guarded attributes on the model.\n     *\n     * @var array\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be cast to native types.\n     *\n     * @var array\n     */\n    protected $casts = [\n        'data' => 'array',\n        'read_at' => 'datetime',\n    ];\n\n    /**\n     * The type of collection that should be used for the model.\n     */\n    protected static string $collectionClass = DatabaseNotificationCollection::class;\n\n    /**\n     * Get the notifiable entity that the notification belongs to.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo<\\Illuminate\\Database\\Eloquent\\Model, $this>\n     */\n    public function notifiable()\n    {\n        return $this->morphTo();\n    }\n\n    /**\n     * Mark the notification as read.\n     *\n     * @return void\n     */\n    public function markAsRead()\n    {\n        if (is_null($this->read_at)) {\n            $this->forceFill(['read_at' => $this->freshTimestamp()])->save();\n        }\n    }\n\n    /**\n     * Mark the notification as unread.\n     *\n     * @return void\n     */\n    public function markAsUnread()\n    {\n        if (! is_null($this->read_at)) {\n            $this->forceFill(['read_at' => null])->save();\n        }\n    }\n\n    /**\n     * Determine if a notification has been read.\n     *\n     * @return bool\n     */\n    public function read()\n    {\n        return $this->read_at !== null;\n    }\n\n    /**\n     * Determine if a notification has not been read.\n     *\n     * @return bool\n     */\n    public function unread()\n    {\n        return $this->read_at === null;\n    }\n\n    /**\n     * Scope a query to only include read notifications.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function scopeRead(Builder $query)\n    {\n        return $query->whereNotNull('read_at');\n    }\n\n    /**\n     * Scope a query to only include unread notifications.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Builder<static>  $query\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<static>\n     */\n    public function scopeUnread(Builder $query)\n    {\n        return $query->whereNull('read_at');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/DatabaseNotificationCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\n\n/**\n * @template TKey of array-key\n * @template TModel of DatabaseNotification\n *\n * @extends \\Illuminate\\Database\\Eloquent\\Collection<TKey, TModel>\n */\nclass DatabaseNotificationCollection extends EloquentCollection\n{\n    /**\n     * Mark all notifications as read.\n     *\n     * @return void\n     */\n    public function markAsRead()\n    {\n        $this->each->markAsRead();\n    }\n\n    /**\n     * Mark all notifications as unread.\n     *\n     * @return void\n     */\n    public function markAsUnread()\n    {\n        $this->each->markAsUnread();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Events/BroadcastNotificationCreated.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Events;\n\nuse Illuminate\\Broadcasting\\PrivateChannel;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nclass BroadcastNotificationCreated implements ShouldBroadcast\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  mixed  $notifiable  The notifiable entity who received the notification.\n     * @param  \\Illuminate\\Notifications\\Notification  $notification  The notification instance.\n     * @param  array  $data  The notification data.\n     */\n    public function __construct(\n        public $notifiable,\n        public $notification,\n        public $data = [],\n    ) {\n    }\n\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return array\n     */\n    public function broadcastOn()\n    {\n        if ($this->notifiable instanceof AnonymousNotifiable &&\n            $this->notifiable->routeNotificationFor('broadcast')) {\n            $channels = Arr::wrap($this->notifiable->routeNotificationFor('broadcast'));\n        } else {\n            $channels = $this->notification->broadcastOn();\n        }\n\n        if (! empty($channels)) {\n            return $channels;\n        }\n\n        if (is_string($channels = $this->channelName())) {\n            return [new PrivateChannel($channels)];\n        }\n\n        return (new Collection($channels))\n            ->map(fn ($channel) => new PrivateChannel($channel))\n            ->all();\n    }\n\n    /**\n     * Get the broadcast channel name for the event.\n     *\n     * @return array|string\n     */\n    protected function channelName()\n    {\n        if (method_exists($this->notifiable, 'receivesBroadcastNotificationsOn')) {\n            return $this->notifiable->receivesBroadcastNotificationsOn($this->notification);\n        }\n\n        $class = str_replace('\\\\', '.', get_class($this->notifiable));\n\n        return $class.'.'.$this->notifiable->getKey();\n    }\n\n    /**\n     * Get the data that should be sent with the broadcasted event.\n     *\n     * @return array\n     */\n    public function broadcastWith()\n    {\n        if (method_exists($this->notification, 'broadcastWith')) {\n            return $this->notification->broadcastWith();\n        }\n\n        return array_merge($this->data, [\n            'id' => $this->notification->id,\n            'type' => $this->broadcastType(),\n        ]);\n    }\n\n    /**\n     * Get the type of the notification being broadcast.\n     *\n     * @return string\n     */\n    public function broadcastType()\n    {\n        return method_exists($this->notification, 'broadcastType')\n            ? $this->notification->broadcastType()\n            : get_class($this->notification);\n    }\n\n    /**\n     * Get the event name of the notification being broadcast.\n     *\n     * @return string\n     */\n    public function broadcastAs()\n    {\n        return method_exists($this->notification, 'broadcastAs')\n            ? $this->notification->broadcastAs()\n            : __CLASS__;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Events/NotificationFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Events;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass NotificationFailed\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  mixed  $notifiable  The notifiable entity who received the notification.\n     * @param  \\Illuminate\\Notifications\\Notification  $notification  The notification instance.\n     * @param  string  $channel  The channel name.\n     * @param  array  $data  The data needed to process this failure.\n     */\n    public function __construct(\n        public $notifiable,\n        public $notification,\n        public $channel,\n        public $data = [],\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Events/NotificationSending.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Events;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass NotificationSending\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  mixed  $notifiable  The notifiable entity who received the notification.\n     * @param  \\Illuminate\\Notifications\\Notification  $notification  The notification instance.\n     * @param  string  $channel  The channel name.\n     */\n    public function __construct(\n        public $notifiable,\n        public $notification,\n        public $channel,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Events/NotificationSent.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Events;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass NotificationSent\n{\n    use Queueable, SerializesModels;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  mixed  $notifiable  The notifiable entity who received the notification.\n     * @param  \\Illuminate\\Notifications\\Notification  $notification  The notification instance.\n     * @param  string  $channel  The channel name.\n     * @param  mixed  $response  The channel's response.\n     */\n    public function __construct(\n        public $notifiable,\n        public $notification,\n        public $channel,\n        public $response = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/HasDatabaseNotifications.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\ntrait HasDatabaseNotifications\n{\n    /**\n     * Get the entity's notifications.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany<DatabaseNotification, $this>\n     */\n    public function notifications()\n    {\n        return $this->morphMany(DatabaseNotification::class, 'notifiable')->latest();\n    }\n\n    /**\n     * Get the entity's read notifications.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany<DatabaseNotification, $this>\n     */\n    public function readNotifications()\n    {\n        return $this->notifications()->read();\n    }\n\n    /**\n     * Get the entity's unread notifications.\n     *\n     * @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany<DatabaseNotification, $this>\n     */\n    public function unreadNotifications()\n    {\n        return $this->notifications()->unread();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Notifications/Messages/BroadcastMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Messages;\n\nuse Illuminate\\Bus\\Queueable;\n\nclass BroadcastMessage\n{\n    use Queueable;\n\n    /**\n     * The data for the notification.\n     *\n     * @var array\n     */\n    public $data;\n\n    /**\n     * Create a new message instance.\n     *\n     * @param  array  $data\n     */\n    public function __construct(array $data)\n    {\n        $this->data = $data;\n    }\n\n    /**\n     * Set the message data.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function data($data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Messages/DatabaseMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Messages;\n\nclass DatabaseMessage\n{\n    /**\n     * The data that should be stored with the notification.\n     *\n     * @var array\n     */\n    public $data = [];\n\n    /**\n     * Create a new database message.\n     *\n     * @param  array  $data\n     */\n    public function __construct(array $data = [])\n    {\n        $this->data = $data;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Messages/MailMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Messages;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Renderable;\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\n\nclass MailMessage extends SimpleMessage implements Renderable\n{\n    use Conditionable;\n\n    /**\n     * The view to be rendered.\n     *\n     * @var array|string\n     */\n    public $view;\n\n    /**\n     * The view data for the message.\n     *\n     * @var array\n     */\n    public $viewData = [];\n\n    /**\n     * The Markdown template to render (if applicable).\n     *\n     * @var string|null\n     */\n    public $markdown = 'notifications::email';\n\n    /**\n     * The current theme being used when generating emails.\n     *\n     * @var string|null\n     */\n    public $theme;\n\n    /**\n     * The \"from\" information for the message.\n     *\n     * @var array\n     */\n    public $from = [];\n\n    /**\n     * The \"reply to\" information for the message.\n     *\n     * @var array\n     */\n    public $replyTo = [];\n\n    /**\n     * The \"cc\" information for the message.\n     *\n     * @var array\n     */\n    public $cc = [];\n\n    /**\n     * The \"bcc\" information for the message.\n     *\n     * @var array\n     */\n    public $bcc = [];\n\n    /**\n     * The attachments for the message.\n     *\n     * @var array\n     */\n    public $attachments = [];\n\n    /**\n     * The raw attachments for the message.\n     *\n     * @var array\n     */\n    public $rawAttachments = [];\n\n    /**\n     * The tags for the message.\n     *\n     * @var array\n     */\n    public $tags = [];\n\n    /**\n     * The metadata for the message.\n     *\n     * @var array\n     */\n    public $metadata = [];\n\n    /**\n     * Priority level of the message.\n     *\n     * @var int\n     */\n    public $priority;\n\n    /**\n     * The callbacks for the message.\n     *\n     * @var array\n     */\n    public $callbacks = [];\n\n    /**\n     * Set the view for the mail message.\n     *\n     * @param  array|string  $view\n     * @param  array  $data\n     * @return $this\n     */\n    public function view($view, array $data = [])\n    {\n        $this->view = $view;\n        $this->viewData = $data;\n\n        $this->markdown = null;\n\n        return $this;\n    }\n\n    /**\n     * Set the plain text view for the mail message.\n     *\n     * @param  string  $textView\n     * @param  array  $data\n     * @return $this\n     */\n    public function text($textView, array $data = [])\n    {\n        return $this->view([\n            'html' => is_array($this->view) ? ($this->view['html'] ?? null) : $this->view,\n            'text' => $textView,\n        ], $data);\n    }\n\n    /**\n     * Set the Markdown template for the notification.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @return $this\n     */\n    public function markdown($view, array $data = [])\n    {\n        $this->markdown = $view;\n        $this->viewData = $data;\n\n        $this->view = null;\n\n        return $this;\n    }\n\n    /**\n     * Set the default markdown template.\n     *\n     * @param  string  $template\n     * @return $this\n     */\n    public function template($template)\n    {\n        $this->markdown = $template;\n\n        return $this;\n    }\n\n    /**\n     * Set the theme to use with the Markdown template.\n     *\n     * @param  string  $theme\n     * @return $this\n     */\n    public function theme($theme)\n    {\n        $this->theme = $theme;\n\n        return $this;\n    }\n\n    /**\n     * Set the from address for the mail message.\n     *\n     * @param  string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function from($address, $name = null)\n    {\n        $this->from = [$address, $name];\n\n        return $this;\n    }\n\n    /**\n     * Set the \"reply to\" address of the message.\n     *\n     * @param  array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function replyTo($address, $name = null)\n    {\n        if ($this->arrayOfAddresses($address)) {\n            $this->replyTo = array_merge($this->replyTo, $this->parseAddresses($address));\n        } else {\n            $this->replyTo[] = [$address, $name];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the cc address for the mail message.\n     *\n     * @param  array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function cc($address, $name = null)\n    {\n        if ($this->arrayOfAddresses($address)) {\n            $this->cc = array_merge($this->cc, $this->parseAddresses($address));\n        } else {\n            $this->cc[] = [$address, $name];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set the bcc address for the mail message.\n     *\n     * @param  array|string  $address\n     * @param  string|null  $name\n     * @return $this\n     */\n    public function bcc($address, $name = null)\n    {\n        if ($this->arrayOfAddresses($address)) {\n            $this->bcc = array_merge($this->bcc, $this->parseAddresses($address));\n        } else {\n            $this->bcc[] = [$address, $name];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Attach a file to the message.\n     *\n     * @param  string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment  $file\n     * @param  array  $options\n     * @return $this\n     */\n    public function attach($file, array $options = [])\n    {\n        if ($file instanceof Attachable) {\n            $file = $file->toMailAttachment();\n        }\n\n        if ($file instanceof Attachment) {\n            return $file->attachTo($this);\n        }\n\n        $this->attachments[] = compact('file', 'options');\n\n        return $this;\n    }\n\n    /**\n     * Attach multiple files to the message.\n     *\n     * @param  array<string|\\Illuminate\\Contracts\\Mail\\Attachable|\\Illuminate\\Mail\\Attachment|array>  $files\n     * @return $this\n     */\n    public function attachMany($files)\n    {\n        foreach ($files as $file => $options) {\n            if (is_int($file)) {\n                $this->attach($options);\n            } else {\n                $this->attach($file, $options);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Attach in-memory data as an attachment.\n     *\n     * @param  string  $data\n     * @param  string  $name\n     * @param  array  $options\n     * @return $this\n     */\n    public function attachData($data, $name, array $options = [])\n    {\n        $this->rawAttachments[] = compact('data', 'name', 'options');\n\n        return $this;\n    }\n\n    /**\n     * Add a tag header to the message when supported by the underlying transport.\n     *\n     * @param  string  $value\n     * @return $this\n     */\n    public function tag($value)\n    {\n        $this->tags[] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Add a metadata header to the message when supported by the underlying transport.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return $this\n     */\n    public function metadata($key, $value)\n    {\n        $this->metadata[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the priority of this message.\n     *\n     * The value is an integer where 1 is the highest priority and 5 is the lowest.\n     *\n     * @param  int  $level\n     * @return $this\n     */\n    public function priority($level)\n    {\n        $this->priority = $level;\n\n        return $this;\n    }\n\n    /**\n     * Get the data array for the mail message.\n     *\n     * @return array\n     */\n    public function data()\n    {\n        return array_merge($this->toArray(), $this->viewData);\n    }\n\n    /**\n     * Parse the multi-address array into the necessary format.\n     *\n     * @param  array  $value\n     * @return array\n     */\n    protected function parseAddresses($value)\n    {\n        return (new Collection($value))\n            ->map(fn ($address, $name) => [$address, is_numeric($name) ? null : $name])\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Determine if the given \"address\" is actually an array of addresses.\n     *\n     * @param  mixed  $address\n     * @return bool\n     */\n    protected function arrayOfAddresses($address)\n    {\n        return is_iterable($address) || $address instanceof Arrayable;\n    }\n\n    /**\n     * Render the mail notification message into an HTML string.\n     *\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public function render()\n    {\n        if (isset($this->view)) {\n            return Container::getInstance()->make('mailer')->render(\n                $this->view, $this->data()\n            );\n        }\n\n        $markdown = Container::getInstance()->make(Markdown::class);\n\n        return $markdown->theme($this->theme ?: $markdown->getTheme())\n            ->render($this->markdown, $this->data());\n    }\n\n    /**\n     * Register a callback to be called with the Symfony message instance.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function withSymfonyMessage($callback)\n    {\n        $this->callbacks[] = $callback;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Messages/SimpleMessage.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications\\Messages;\n\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Notifications\\Action;\n\nclass SimpleMessage\n{\n    /**\n     * The \"level\" of the notification (info, success, error).\n     *\n     * @var string\n     */\n    public $level = 'info';\n\n    /**\n     * The subject of the notification.\n     *\n     * @var string\n     */\n    public $subject;\n\n    /**\n     * The notification's greeting.\n     *\n     * @var string\n     */\n    public $greeting;\n\n    /**\n     * The notification's salutation.\n     *\n     * @var string\n     */\n    public $salutation;\n\n    /**\n     * The \"intro\" lines of the notification.\n     *\n     * @var array\n     */\n    public $introLines = [];\n\n    /**\n     * The \"outro\" lines of the notification.\n     *\n     * @var array\n     */\n    public $outroLines = [];\n\n    /**\n     * The text / label for the action.\n     *\n     * @var string\n     */\n    public $actionText;\n\n    /**\n     * The action URL.\n     *\n     * @var string\n     */\n    public $actionUrl;\n\n    /**\n     * The name of the mailer that should send the notification.\n     *\n     * @var string\n     */\n    public $mailer;\n\n    /**\n     * Indicate that the notification gives information about a successful operation.\n     *\n     * @return $this\n     */\n    public function success()\n    {\n        $this->level = 'success';\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the notification gives information about an error.\n     *\n     * @return $this\n     */\n    public function error()\n    {\n        $this->level = 'error';\n\n        return $this;\n    }\n\n    /**\n     * Set the \"level\" of the notification (success, error, etc.).\n     *\n     * @param  string  $level\n     * @return $this\n     */\n    public function level($level)\n    {\n        $this->level = $level;\n\n        return $this;\n    }\n\n    /**\n     * Set the subject of the notification.\n     *\n     * @param  string  $subject\n     * @return $this\n     */\n    public function subject($subject)\n    {\n        $this->subject = $subject;\n\n        return $this;\n    }\n\n    /**\n     * Set the greeting of the notification.\n     *\n     * @param  string  $greeting\n     * @return $this\n     */\n    public function greeting($greeting)\n    {\n        $this->greeting = $greeting;\n\n        return $this;\n    }\n\n    /**\n     * Set the salutation of the notification.\n     *\n     * @param  string  $salutation\n     * @return $this\n     */\n    public function salutation($salutation)\n    {\n        $this->salutation = $salutation;\n\n        return $this;\n    }\n\n    /**\n     * Add a line of text to the notification.\n     *\n     * @param  mixed  $line\n     * @return $this\n     */\n    public function line($line)\n    {\n        return $this->with($line);\n    }\n\n    /**\n     * Add a line of text to the notification if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  mixed  $line\n     * @return $this\n     */\n    public function lineIf($boolean, $line)\n    {\n        if ($boolean) {\n            return $this->line($line);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add lines of text to the notification.\n     *\n     * @param  iterable  $lines\n     * @return $this\n     */\n    public function lines($lines)\n    {\n        foreach ($lines as $line) {\n            $this->line($line);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add lines of text to the notification if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  iterable  $lines\n     * @return $this\n     */\n    public function linesIf($boolean, $lines)\n    {\n        if ($boolean) {\n            return $this->lines($lines);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a line of text to the notification.\n     *\n     * @param  mixed  $line\n     * @return $this\n     */\n    public function with($line)\n    {\n        if ($line instanceof Action) {\n            $this->action($line->text, $line->url);\n        } elseif (! $this->actionText) {\n            $this->introLines[] = $this->formatLine($line);\n        } else {\n            $this->outroLines[] = $this->formatLine($line);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Format the given line of text.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Htmlable|string|array|null  $line\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable|string\n     */\n    protected function formatLine($line)\n    {\n        if ($line instanceof Htmlable) {\n            return $line;\n        }\n\n        if (is_array($line)) {\n            return implode(' ', array_map(trim(...), $line));\n        }\n\n        return trim(implode(' ', array_map(trim(...), preg_split('/\\\\r\\\\n|\\\\r|\\\\n/', $line ?? ''))));\n    }\n\n    /**\n     * Configure the \"call to action\" button.\n     *\n     * @param  string  $text\n     * @param  string  $url\n     * @return $this\n     */\n    public function action($text, $url)\n    {\n        $this->actionText = $text;\n        $this->actionUrl = $url;\n\n        return $this;\n    }\n\n    /**\n     * Set the name of the mailer that should send the notification.\n     *\n     * @param  string  $mailer\n     * @return $this\n     */\n    public function mailer($mailer)\n    {\n        $this->mailer = $mailer;\n\n        return $this;\n    }\n\n    /**\n     * Get an array representation of the message.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'level' => $this->level,\n            'subject' => $this->subject,\n            'greeting' => $this->greeting,\n            'salutation' => $this->salutation,\n            'introLines' => $this->introLines,\n            'outroLines' => $this->outroLines,\n            'actionText' => $this->actionText,\n            'actionUrl' => $this->actionUrl,\n            'displayableActionUrl' => str_replace(['mailto:', 'tel:'], '', $this->actionUrl ?? ''),\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Notifiable.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\ntrait Notifiable\n{\n    use HasDatabaseNotifications, RoutesNotifications;\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/Notification.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Queue\\SerializesModels;\n\nclass Notification\n{\n    use SerializesModels;\n\n    /**\n     * The unique identifier for the notification.\n     *\n     * @var string\n     */\n    public $id;\n\n    /**\n     * The locale to be used when sending the notification.\n     *\n     * @var string|null\n     */\n    public $locale;\n\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return array\n     */\n    public function broadcastOn()\n    {\n        return [];\n    }\n\n    /**\n     * Set the locale to send this notification in.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale)\n    {\n        $this->locale = $locale;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/NotificationSender.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Notifications\\Events\\NotificationFailed;\nuse Illuminate\\Notifications\\Events\\NotificationSending;\nuse Illuminate\\Notifications\\Events\\NotificationSent;\nuse Illuminate\\Queue\\Attributes\\Connection;\nuse Illuminate\\Queue\\Attributes\\Queue as QueueAttribute;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Localizable;\nuse Symfony\\Component\\Mailer\\Exception\\HttpTransportException;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Throwable;\n\nclass NotificationSender\n{\n    use Localizable, ReadsQueueAttributes;\n\n    /**\n     * The notification manager instance.\n     *\n     * @var \\Illuminate\\Notifications\\ChannelManager\n     */\n    protected $manager;\n\n    /**\n     * The Bus dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Bus\\Dispatcher\n     */\n    protected $bus;\n\n    /**\n     * The event dispatcher.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The locale to be used when sending notifications.\n     *\n     * @var string|null\n     */\n    protected $locale;\n\n    /**\n     * Indicates whether a NotificationFailed event has been dispatched.\n     *\n     * @var bool\n     */\n    protected $failedEventWasDispatched = false;\n\n    /**\n     * Create a new notification sender instance.\n     *\n     * @param  \\Illuminate\\Notifications\\ChannelManager  $manager\n     * @param  \\Illuminate\\Contracts\\Bus\\Dispatcher  $bus\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @param  string|null  $locale\n     */\n    public function __construct($manager, $bus, $events, $locale = null)\n    {\n        $this->bus = $bus;\n        $this->events = $events;\n        $this->locale = $locale;\n        $this->manager = $manager;\n\n        $this->events->listen(NotificationFailed::class, fn () => $this->failedEventWasDispatched = true);\n    }\n\n    /**\n     * Send the given notification to the given notifiable entities.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function send($notifiables, $notification)\n    {\n        if ($notification instanceof ShouldQueue) {\n            return $this->queueNotification($notifiables, $notification);\n        }\n\n        $this->sendNow($notifiables, $notification);\n    }\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @param  array|null  $channels\n     * @return void\n     */\n    public function sendNow($notifiables, $notification, ?array $channels = null)\n    {\n        $notifiables = $this->formatNotifiables($notifiables);\n\n        $original = clone $notification;\n\n        foreach ($notifiables as $notifiable) {\n            if (empty($viaChannels = $channels ?: $original->via($notifiable))) {\n                continue;\n            }\n\n            $this->withLocale($this->preferredLocale($notifiable, $original), function () use ($viaChannels, $notifiable, $original) {\n                $notificationId = (string) Str::uuid();\n\n                foreach ((array) $viaChannels as $channel) {\n                    if (! ($notifiable instanceof AnonymousNotifiable && $channel === 'database')) {\n                        $this->sendToNotifiable($notifiable, $notificationId, clone $original, $channel);\n                    }\n                }\n            });\n        }\n    }\n\n    /**\n     * Get the notifiable's preferred locale for the notification.\n     *\n     * @param  mixed  $notifiable\n     * @param  mixed  $notification\n     * @return string|null\n     */\n    protected function preferredLocale($notifiable, $notification)\n    {\n        return $notification->locale ?? $this->locale ?? value(function () use ($notifiable) {\n            if ($notifiable instanceof HasLocalePreference) {\n                return $notifiable->preferredLocale();\n            }\n        });\n    }\n\n    /**\n     * Send the given notification to the given notifiable via a channel.\n     *\n     * @param  mixed  $notifiable\n     * @param  string  $id\n     * @param  mixed  $notification\n     * @param  string  $channel\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function sendToNotifiable($notifiable, $id, $notification, $channel)\n    {\n        if (! $notification->id) {\n            $notification->id = $id;\n        }\n\n        if (! $this->shouldSendNotification($notifiable, $notification, $channel)) {\n            return;\n        }\n\n        try {\n            $response = $this->manager->driver($channel)->send($notifiable, $notification);\n        } catch (Throwable $exception) {\n            if (! $this->failedEventWasDispatched) {\n                if ($exception instanceof HttpTransportException) {\n                    $exception = new TransportException($exception->getMessage(), $exception->getCode());\n                }\n\n                $this->events->dispatch(\n                    new NotificationFailed($notifiable, $notification, $channel, ['exception' => $exception])\n                );\n            }\n\n            $this->failedEventWasDispatched = false;\n\n            throw $exception;\n        }\n\n        if (method_exists($notification, 'afterSending')) {\n            $notification->afterSending($notifiable, $channel, $response);\n        }\n\n        $this->events->dispatch(\n            new NotificationSent($notifiable, $notification, $channel, $response)\n        );\n    }\n\n    /**\n     * Determines if the notification can be sent.\n     *\n     * @param  mixed  $notifiable\n     * @param  mixed  $notification\n     * @param  string  $channel\n     * @return bool\n     */\n    protected function shouldSendNotification($notifiable, $notification, $channel)\n    {\n        if (method_exists($notification, 'shouldSend') &&\n            $notification->shouldSend($notifiable, $channel) === false) {\n            return false;\n        }\n\n        return $this->events->until(\n            new NotificationSending($notifiable, $notification, $channel)\n        ) !== false;\n    }\n\n    /**\n     * Queue the given notification instances.\n     *\n     * @param  mixed  $notifiables\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @return void\n     */\n    protected function queueNotification($notifiables, $notification)\n    {\n        $notifiables = $this->formatNotifiables($notifiables);\n\n        $original = clone $notification;\n\n        foreach ($notifiables as $notifiable) {\n            $notificationId = (string) Str::uuid();\n\n            foreach ((array) $original->via($notifiable) as $channel) {\n                $notification = clone $original;\n\n                if (! $notification->id) {\n                    $notification->id = $notificationId;\n                }\n\n                if (! is_null($this->locale)) {\n                    $notification->locale = $this->locale;\n                }\n\n                $connection = $this->getAttributeValue($notification, Connection::class, 'connection')\n                    ?? $this->manager->resolveConnectionFromQueueRoute($notification)\n                    ?? null;\n\n                if (method_exists($notification, 'viaConnections')) {\n                    $connection = $notification->viaConnections()[$channel] ?? $connection;\n                }\n\n                $queue = $this->getAttributeValue($notification, QueueAttribute::class, 'queue')\n                    ?? $this->manager->resolveQueueFromQueueRoute($notification)\n                    ?? null;\n\n                if (method_exists($notification, 'viaQueues')) {\n                    $queue = $notification->viaQueues()[$channel] ?? $queue;\n                }\n\n                $delay = $notification->delay;\n\n                if (method_exists($notification, 'withDelay')) {\n                    $delay = $notification->withDelay($notifiable, $channel) ?? null;\n                }\n\n                $messageGroup = $notification->messageGroup ?? (method_exists($notification, 'messageGroup') ? $notification->messageGroup() : null);\n\n                if (method_exists($notification, 'withMessageGroups')) {\n                    $messageGroup = $notification->withMessageGroups($notifiable, $channel) ?? null;\n                }\n\n                $deduplicator = $notification->deduplicator ?? (method_exists($notification, 'deduplicationId') ? $notification->deduplicationId(...) : null);\n\n                if (method_exists($notification, 'withDeduplicators')) {\n                    $deduplicator = $notification->withDeduplicators($notifiable, $channel) ?? null;\n                }\n\n                $middleware = $notification->middleware ?? [];\n\n                if (method_exists($notification, 'middleware')) {\n                    $middleware = array_merge(\n                        $notification->middleware($notifiable, $channel),\n                        $middleware\n                    );\n                }\n\n                $this->bus->dispatch(\n                    $this->manager->getContainer()->make(SendQueuedNotifications::class, [\n                        'notifiables' => $notifiable,\n                        'notification' => $notification,\n                        'channels' => [$channel],\n                    ])\n                        ->onConnection($connection)\n                        ->onQueue($queue)\n                        ->delay(is_array($delay) ? ($delay[$channel] ?? null) : $delay)\n                        ->onGroup(is_array($messageGroup) ? ($messageGroup[$channel] ?? null) : $messageGroup)\n                        ->withDeduplicator(is_array($deduplicator) ? ($deduplicator[$channel] ?? null) : $deduplicator)\n                        ->through($middleware)\n                );\n            }\n        }\n    }\n\n    /**\n     * Format the notifiables into a Collection / array if necessary.\n     *\n     * @param  mixed  $notifiables\n     * @return \\Illuminate\\Database\\Eloquent\\Collection|array\n     */\n    protected function formatNotifiables($notifiables)\n    {\n        if (! $notifiables instanceof Collection && ! is_array($notifiables)) {\n            return $notifiables instanceof Model\n                ? new EloquentCollection([$notifiables])\n                : [$notifiables];\n        }\n\n        return $notifiables;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/NotificationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Contracts\\Notifications\\Dispatcher as DispatcherContract;\nuse Illuminate\\Contracts\\Notifications\\Factory as FactoryContract;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass NotificationServiceProvider extends ServiceProvider\n{\n    /**\n     * Boot the application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        $this->loadViewsFrom(__DIR__.'/resources/views', 'notifications');\n\n        if ($this->app->runningInConsole()) {\n            $this->publishes([\n                __DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/notifications'),\n            ], 'laravel-notifications');\n        }\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton(ChannelManager::class, fn ($app) => new ChannelManager($app));\n\n        $this->app->alias(\n            ChannelManager::class, DispatcherContract::class\n        );\n\n        $this->app->alias(\n            ChannelManager::class, FactoryContract::class\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/RoutesNotifications.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Contracts\\Notifications\\Dispatcher;\nuse Illuminate\\Support\\Str;\n\ntrait RoutesNotifications\n{\n    /**\n     * Send the given notification.\n     *\n     * @param  mixed  $instance\n     * @return void\n     */\n    public function notify($instance)\n    {\n        app(Dispatcher::class)->send($this, $instance);\n    }\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  mixed  $instance\n     * @param  array|null  $channels\n     * @return void\n     */\n    public function notifyNow($instance, ?array $channels = null)\n    {\n        app(Dispatcher::class)->sendNow($this, $instance, $channels);\n    }\n\n    /**\n     * Get the notification routing information for the given driver.\n     *\n     * @param  string  $driver\n     * @param  \\Illuminate\\Notifications\\Notification|null  $notification\n     * @return mixed\n     */\n    public function routeNotificationFor($driver, $notification = null)\n    {\n        if (method_exists($this, $method = 'routeNotificationFor'.Str::studly($driver))) {\n            return $this->{$method}($notification);\n        }\n\n        return match ($driver) {\n            'database' => $this->notifications(),\n            'mail' => $this->email,\n            default => null,\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/SendQueuedNotifications.php",
    "content": "<?php\n\nnamespace Illuminate\\Notifications;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldBeEncrypted;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Queue\\Attributes\\Backoff;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\Attributes\\MaxExceptions;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\Attributes\\Timeout;\nuse Illuminate\\Queue\\Attributes\\Tries;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Collection;\n\nclass SendQueuedNotifications implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable, ReadsQueueAttributes, SerializesModels;\n\n    /**\n     * The notifiable entities that should receive the notification.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    public $notifiables;\n\n    /**\n     * The notification to be sent.\n     *\n     * @var \\Illuminate\\Notifications\\Notification\n     */\n    public $notification;\n\n    /**\n     * All of the channels to send the notification to.\n     *\n     * @var array\n     */\n    public $channels;\n\n    /**\n     * The number of times the job may be attempted.\n     *\n     * @var int\n     */\n    public $tries;\n\n    /**\n     * The number of seconds the job can run before timing out.\n     *\n     * @var int\n     */\n    public $timeout;\n\n    /**\n     * The maximum number of unhandled exceptions to allow before failing.\n     *\n     * @var int\n     */\n    public $maxExceptions;\n\n    /**\n     * Indicates if the job should be encrypted.\n     *\n     * @var bool\n     */\n    public $shouldBeEncrypted = false;\n\n    /**\n     * Indicates if the job should be deleted when models are missing.\n     */\n    public bool $deleteWhenMissingModels = false;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Notifications\\Notifiable|\\Illuminate\\Support\\Collection  $notifiables\n     * @param  \\Illuminate\\Notifications\\Notification  $notification\n     * @param  array|null  $channels\n     */\n    public function __construct($notifiables, $notification, ?array $channels = null)\n    {\n        $this->channels = $channels;\n        $this->notification = $notification;\n        $this->notifiables = $this->wrapNotifiables($notifiables);\n        $this->tries = $this->getAttributeValue($notification, Tries::class, 'tries');\n        $this->timeout = $this->getAttributeValue($notification, Timeout::class, 'timeout');\n        $this->maxExceptions = $this->getAttributeValue($notification, MaxExceptions::class, 'maxExceptions');\n        $this->deleteWhenMissingModels = $this->getAttributeValue($notification, DeleteWhenMissingModels::class, 'deleteWhenMissingModels') ?? false;\n\n        if ($notification instanceof ShouldQueueAfterCommit) {\n            $this->afterCommit = true;\n        } else {\n            $this->afterCommit = property_exists($notification, 'afterCommit') ? $notification->afterCommit : null;\n        }\n\n        $this->shouldBeEncrypted = $notification instanceof ShouldBeEncrypted;\n    }\n\n    /**\n     * Wrap the notifiable(s) in a collection.\n     *\n     * @param  \\Illuminate\\Notifications\\Notifiable|\\Illuminate\\Support\\Collection  $notifiables\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function wrapNotifiables($notifiables)\n    {\n        if ($notifiables instanceof Collection) {\n            return $notifiables;\n        } elseif ($notifiables instanceof Model) {\n            return EloquentCollection::wrap($notifiables);\n        }\n\n        return Collection::wrap($notifiables);\n    }\n\n    /**\n     * Send the notifications.\n     *\n     * @param  \\Illuminate\\Notifications\\ChannelManager  $manager\n     * @return void\n     */\n    public function handle(ChannelManager $manager)\n    {\n        $manager->sendNow($this->notifiables, $this->notification, $this->channels);\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        return get_class($this->notification);\n    }\n\n    /**\n     * Call the failed method on the notification instance.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function failed($e)\n    {\n        if (method_exists($this->notification, 'failed')) {\n            $this->notification->failed($e);\n        }\n    }\n\n    /**\n     * Get the number of seconds before a released notification will be available.\n     *\n     * @return mixed\n     */\n    public function backoff()\n    {\n        $backoff = $this->getAttributeValue($this->notification, Backoff::class, 'backoff');\n\n        if (method_exists($this->notification, 'backoff')) {\n            $backoff = $this->notification->backoff();\n        }\n\n        return $backoff;\n    }\n\n    /**\n     * Determine the time at which the job should timeout.\n     *\n     * @return \\DateTime|null\n     */\n    public function retryUntil()\n    {\n        if (! method_exists($this->notification, 'retryUntil') && ! isset($this->notification->retryUntil)) {\n            return;\n        }\n\n        return $this->notification->retryUntil ?? $this->notification->retryUntil();\n    }\n\n    /**\n     * Prepare the instance for cloning.\n     *\n     * @return void\n     */\n    public function __clone()\n    {\n        $this->notifiables = clone $this->notifiables;\n        $this->notification = clone $this->notification;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/composer.json",
    "content": "{\n    \"name\": \"illuminate/notifications\",\n    \"description\": \"The Illuminate Notifications package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/broadcasting\": \"^13.0\",\n        \"illuminate/bus\": \"^13.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/filesystem\": \"^13.0\",\n        \"illuminate/mail\": \"^13.0\",\n        \"illuminate/queue\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"illuminate/database\": \"Required to use the database transport (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Notifications\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Notifications/resources/views/email.blade.php",
    "content": "<x-mail::message>\n{{-- Greeting --}}\n@if (! empty($greeting))\n# {{ $greeting }}\n@else\n@if ($level === 'error')\n# @lang('Whoops!')\n@else\n# @lang('Hello!')\n@endif\n@endif\n\n{{-- Intro Lines --}}\n@foreach ($introLines as $line)\n{{ $line }}\n\n@endforeach\n\n{{-- Action Button --}}\n@isset($actionText)\n<?php\n    $color = match ($level) {\n        'success', 'error' => $level,\n        default => 'primary',\n    };\n?>\n<x-mail::button :url=\"$actionUrl\" :color=\"$color\">\n{{ $actionText }}\n</x-mail::button>\n@endisset\n\n{{-- Outro Lines --}}\n@foreach ($outroLines as $line)\n{{ $line }}\n\n@endforeach\n\n{{-- Salutation --}}\n@if (! empty($salutation))\n{{ $salutation }}\n@else\n@lang('Regards,')<br>\n{{ config('app.name') }}\n@endif\n\n{{-- Subcopy --}}\n@isset($actionText)\n<x-slot:subcopy>\n@lang(\n    \"If you're having trouble clicking the \\\":actionText\\\" button, copy and paste the URL below\\n\".\n    'into your web browser:',\n    [\n        'actionText' => $actionText,\n    ]\n) <span class=\"break-all\">[{{ $displayableActionUrl }}]({{ $actionUrl }})</span>\n</x-slot:subcopy>\n@endisset\n</x-mail::message>\n"
  },
  {
    "path": "src/Illuminate/Pagination/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Pagination/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Pagination/AbstractCursorPaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse ArrayAccess;\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Illuminate\\Support\\Traits\\TransformsToResourceCollection;\nuse Stringable;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @mixin \\Illuminate\\Support\\Collection<TKey, TValue>\n */\nabstract class AbstractCursorPaginator implements Htmlable, Stringable\n{\n    use ForwardsCalls, Tappable, TransformsToResourceCollection;\n\n    /**\n     * All of the items being paginated.\n     *\n     * @var \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    protected $items;\n\n    /**\n     * The number of items to be shown per page.\n     *\n     * @var int\n     */\n    protected $perPage;\n\n    /**\n     * The base path to assign to all URLs.\n     *\n     * @var string\n     */\n    protected $path = '/';\n\n    /**\n     * The query parameters to add to all URLs.\n     *\n     * @var array\n     */\n    protected $query = [];\n\n    /**\n     * The URL fragment to add to all URLs.\n     *\n     * @var string|null\n     */\n    protected $fragment;\n\n    /**\n     * The cursor string variable used to store the page.\n     *\n     * @var string\n     */\n    protected $cursorName = 'cursor';\n\n    /**\n     * The current cursor.\n     *\n     * @var \\Illuminate\\Pagination\\Cursor|null\n     */\n    protected $cursor;\n\n    /**\n     * The paginator parameters for the cursor.\n     *\n     * @var array\n     */\n    protected $parameters;\n\n    /**\n     * The paginator options.\n     *\n     * @var array\n     */\n    protected $options;\n\n    /**\n     * The current cursor resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected static $currentCursorResolver;\n\n    /**\n     * Get the URL for a given cursor.\n     *\n     * @param  \\Illuminate\\Pagination\\Cursor|null  $cursor\n     * @return string\n     */\n    public function url($cursor)\n    {\n        // If we have any extra query string key / value pairs that need to be added\n        // onto the URL, we will put them in query string form and then attach it\n        // to the URL. This allows for extra information like sortings storage.\n        $parameters = is_null($cursor) ? [] : [$this->cursorName => $cursor->encode()];\n\n        if (count($this->query) > 0) {\n            $parameters = array_merge($this->query, $parameters);\n        }\n\n        return $this->path()\n            .(str_contains($this->path(), '?') ? '&' : '?')\n            .Arr::query($parameters)\n            .$this->buildFragment();\n    }\n\n    /**\n     * Get the URL for the previous page.\n     *\n     * @return string|null\n     */\n    public function previousPageUrl()\n    {\n        if (is_null($previousCursor = $this->previousCursor())) {\n            return null;\n        }\n\n        return $this->url($previousCursor);\n    }\n\n    /**\n     * The URL for the next page, or null.\n     *\n     * @return string|null\n     */\n    public function nextPageUrl()\n    {\n        if (is_null($nextCursor = $this->nextCursor())) {\n            return null;\n        }\n\n        return $this->url($nextCursor);\n    }\n\n    /**\n     * Get the \"cursor\" that points to the previous set of items.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function previousCursor()\n    {\n        if (is_null($this->cursor) ||\n            ($this->cursor->pointsToPreviousItems() && ! $this->hasMore)) {\n            return null;\n        }\n\n        if ($this->items->isEmpty()) {\n            return null;\n        }\n\n        return $this->getCursorForItem($this->items->first(), false);\n    }\n\n    /**\n     * Get the \"cursor\" that points to the next set of items.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function nextCursor()\n    {\n        if ((is_null($this->cursor) && ! $this->hasMore) ||\n            (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && ! $this->hasMore)) {\n            return null;\n        }\n\n        if ($this->items->isEmpty()) {\n            return null;\n        }\n\n        return $this->getCursorForItem($this->items->last(), true);\n    }\n\n    /**\n     * Get a cursor instance for the given item.\n     *\n     * @param  \\ArrayAccess|\\stdClass  $item\n     * @param  bool  $isNext\n     * @return \\Illuminate\\Pagination\\Cursor\n     */\n    public function getCursorForItem($item, $isNext = true)\n    {\n        return new Cursor($this->getParametersForItem($item), $isNext);\n    }\n\n    /**\n     * Get the cursor parameters for a given object.\n     *\n     * @param  \\ArrayAccess|\\stdClass  $item\n     * @return array\n     *\n     * @throws \\Exception\n     */\n    public function getParametersForItem($item)\n    {\n        return (new Collection($this->parameters))\n            ->filter()\n            ->flip()\n            ->map(function ($_, $parameterName) use ($item) {\n                if ($item instanceof JsonResource) {\n                    $item = $item->resource;\n                }\n\n                if ($item instanceof Model &&\n                    ! is_null($parameter = $this->getPivotParameterForItem($item, $parameterName))) {\n                    return $parameter;\n                } elseif ($item instanceof ArrayAccess || is_array($item)) {\n                    return $this->ensureParameterIsPrimitive(\n                        $item[$parameterName] ?? $item[Str::afterLast($parameterName, '.')]\n                    );\n                } elseif (is_object($item)) {\n                    return $this->ensureParameterIsPrimitive(\n                        $item->{$parameterName} ?? $item->{Str::afterLast($parameterName, '.')}\n                    );\n                }\n\n                throw new Exception('Only arrays and objects are supported when cursor paginating items.');\n            })->toArray();\n    }\n\n    /**\n     * Get the cursor parameter value from a pivot model if applicable.\n     *\n     * @param  \\ArrayAccess|\\stdClass  $item\n     * @param  string  $parameterName\n     * @return string|null\n     */\n    protected function getPivotParameterForItem($item, $parameterName)\n    {\n        $table = Str::beforeLast($parameterName, '.');\n\n        foreach ($item->getRelations() as $relation) {\n            if ($relation instanceof Pivot && $relation->getTable() === $table) {\n                return $this->ensureParameterIsPrimitive(\n                    $relation->getAttribute(Str::afterLast($parameterName, '.'))\n                );\n            }\n        }\n    }\n\n    /**\n     * Ensure the parameter is a primitive type.\n     *\n     * This can resolve issues that arise the developer uses a value object for an attribute.\n     *\n     * @param  mixed  $parameter\n     * @return mixed\n     */\n    protected function ensureParameterIsPrimitive($parameter)\n    {\n        return is_object($parameter) && method_exists($parameter, '__toString')\n            ? (string) $parameter\n            : $parameter;\n    }\n\n    /**\n     * Get / set the URL fragment to be appended to URLs.\n     *\n     * @param  string|null  $fragment\n     * @return $this|string|null\n     */\n    public function fragment($fragment = null)\n    {\n        if (is_null($fragment)) {\n            return $this->fragment;\n        }\n\n        $this->fragment = $fragment;\n\n        return $this;\n    }\n\n    /**\n     * Add a set of query string values to the paginator.\n     *\n     * @param  array|string|null  $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function appends($key, $value = null)\n    {\n        if (is_null($key)) {\n            return $this;\n        }\n\n        if (is_array($key)) {\n            return $this->appendArray($key);\n        }\n\n        return $this->addQuery($key, $value);\n    }\n\n    /**\n     * Add an array of query string values.\n     *\n     * @param  array  $keys\n     * @return $this\n     */\n    protected function appendArray(array $keys)\n    {\n        foreach ($keys as $key => $value) {\n            $this->addQuery($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add all current query string values to the paginator.\n     *\n     * @return $this\n     */\n    public function withQueryString()\n    {\n        if (! is_null($query = Paginator::resolveQueryString())) {\n            return $this->appends($query);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a query string value to the paginator.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return $this\n     */\n    protected function addQuery($key, $value)\n    {\n        if ($key !== $this->cursorName) {\n            $this->query[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Build the full fragment portion of a URL.\n     *\n     * @return string\n     */\n    protected function buildFragment()\n    {\n        return $this->fragment ? '#'.$this->fragment : '';\n    }\n\n    /**\n     * Load a set of relationships onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorph($relation, $relations)\n    {\n        $this->getCollection()->loadMorph($relation, $relations);\n\n        return $this;\n    }\n\n    /**\n     * Load a set of relationship counts onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorphCount($relation, $relations)\n    {\n        $this->getCollection()->loadMorphCount($relation, $relations);\n\n        return $this;\n    }\n\n    /**\n     * Get the slice of items being paginated.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function items()\n    {\n        return $this->items->all();\n    }\n\n    /**\n     * Transform each item in the slice of items using a callback.\n     *\n     * @template TThroughValue\n     *\n     * @param  callable(TValue, TKey): TThroughValue  $callback\n     * @return $this\n     *\n     * @phpstan-this-out static<TKey, TThroughValue>\n     */\n    public function through(callable $callback)\n    {\n        $this->items->transform($callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the number of items shown per page.\n     *\n     * @return int\n     */\n    public function perPage()\n    {\n        return $this->perPage;\n    }\n\n    /**\n     * Get the current cursor being paginated.\n     *\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public function cursor()\n    {\n        return $this->cursor;\n    }\n\n    /**\n     * Get the query string variable used to store the cursor.\n     *\n     * @return string\n     */\n    public function getCursorName()\n    {\n        return $this->cursorName;\n    }\n\n    /**\n     * Set the query string variable used to store the cursor.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setCursorName($name)\n    {\n        $this->cursorName = $name;\n\n        return $this;\n    }\n\n    /**\n     * Set the base path to assign to all URLs.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function withPath($path)\n    {\n        return $this->setPath($path);\n    }\n\n    /**\n     * Set the base path to assign to all URLs.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function setPath($path)\n    {\n        $this->path = $path;\n\n        return $this;\n    }\n\n    /**\n     * Get the base path for paginator generated URLs.\n     *\n     * @return string|null\n     */\n    public function path()\n    {\n        return $this->path;\n    }\n\n    /**\n     * Resolve the current cursor or return the default value.\n     *\n     * @param  string  $cursorName\n     * @param  \\Illuminate\\Pagination\\Cursor|null  $default\n     * @return \\Illuminate\\Pagination\\Cursor|null\n     */\n    public static function resolveCurrentCursor($cursorName = 'cursor', $default = null)\n    {\n        if (isset(static::$currentCursorResolver)) {\n            return call_user_func(static::$currentCursorResolver, $cursorName);\n        }\n\n        return $default;\n    }\n\n    /**\n     * Set the current cursor resolver callback.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public static function currentCursorResolver(Closure $resolver)\n    {\n        static::$currentCursorResolver = $resolver;\n    }\n\n    /**\n     * Get an instance of the view factory from the resolver.\n     *\n     * @return \\Illuminate\\Contracts\\View\\Factory\n     */\n    public static function viewFactory()\n    {\n        return Paginator::viewFactory();\n    }\n\n    /**\n     * Get an iterator for the items.\n     *\n     * @return \\ArrayIterator<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return $this->items->getIterator();\n    }\n\n    /**\n     * Determine if the list of items is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return $this->items->isEmpty();\n    }\n\n    /**\n     * Determine if the list of items is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return $this->items->isNotEmpty();\n    }\n\n    /**\n     * Get the number of items for the current page.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return $this->items->count();\n    }\n\n    /**\n     * Get the paginator's underlying collection.\n     *\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    public function getCollection()\n    {\n        return $this->items;\n    }\n\n    /**\n     * Set the paginator's underlying collection.\n     *\n     * @template TSetKey of array-key\n     * @template TSetValue\n     *\n     * @param  \\Illuminate\\Support\\Collection<TSetKey, TSetValue>  $collection\n     * @return $this\n     *\n     * @phpstan-this-out static<TSetKey, TSetValue>\n     */\n    public function setCollection(Collection $collection)\n    {\n        $this->items = $collection;\n\n        return $this;\n    }\n\n    /**\n     * Get the paginator options.\n     *\n     * @return array\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * Determine if the given item exists.\n     *\n     * @param  TKey  $key\n     * @return bool\n     */\n    public function offsetExists($key): bool\n    {\n        return $this->items->has($key);\n    }\n\n    /**\n     * Get the item at the given offset.\n     *\n     * @param  TKey  $key\n     * @return TValue|null\n     */\n    public function offsetGet($key): mixed\n    {\n        return $this->items->get($key);\n    }\n\n    /**\n     * Set the item at the given offset.\n     *\n     * @param  TKey|null  $key\n     * @param  TValue  $value\n     * @return void\n     */\n    public function offsetSet($key, $value): void\n    {\n        $this->items->put($key, $value);\n    }\n\n    /**\n     * Unset the item at the given key.\n     *\n     * @param  TKey  $key\n     * @return void\n     */\n    public function offsetUnset($key): void\n    {\n        $this->items->forget($key);\n    }\n\n    /**\n     * Render the contents of the paginator to HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return (string) $this->render();\n    }\n\n    /**\n     * Make dynamic calls into the collection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->getCollection(), $method, $parameters);\n    }\n\n    /**\n     * Render the contents of the paginator when casting to a string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->render();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/AbstractPaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Illuminate\\Support\\Traits\\TransformsToResourceCollection;\nuse Stringable;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @mixin \\Illuminate\\Support\\Collection<TKey, TValue>\n */\nabstract class AbstractPaginator implements CanBeEscapedWhenCastToString, Htmlable, Stringable\n{\n    use ForwardsCalls, Tappable, TransformsToResourceCollection;\n\n    /**\n     * All of the items being paginated.\n     *\n     * @var \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    protected $items;\n\n    /**\n     * The number of items to be shown per page.\n     *\n     * @var int\n     */\n    protected $perPage;\n\n    /**\n     * The current page being \"viewed\".\n     *\n     * @var int\n     */\n    protected $currentPage;\n\n    /**\n     * The base path to assign to all URLs.\n     *\n     * @var string\n     */\n    protected $path = '/';\n\n    /**\n     * The query parameters to add to all URLs.\n     *\n     * @var array\n     */\n    protected $query = [];\n\n    /**\n     * The URL fragment to add to all URLs.\n     *\n     * @var string|null\n     */\n    protected $fragment;\n\n    /**\n     * The query string variable used to store the page.\n     *\n     * @var string\n     */\n    protected $pageName = 'page';\n\n    /**\n     * Indicates that the paginator's string representation should be escaped when __toString is invoked.\n     *\n     * @var bool\n     */\n    protected $escapeWhenCastingToString = false;\n\n    /**\n     * The number of links to display on each side of current page link.\n     *\n     * @var int\n     */\n    public $onEachSide = 3;\n\n    /**\n     * The paginator options.\n     *\n     * @var array\n     */\n    protected $options;\n\n    /**\n     * The current path resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected static $currentPathResolver;\n\n    /**\n     * The current page resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected static $currentPageResolver;\n\n    /**\n     * The query string resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected static $queryStringResolver;\n\n    /**\n     * The view factory resolver callback.\n     *\n     * @var \\Closure\n     */\n    protected static $viewFactoryResolver;\n\n    /**\n     * The default pagination view.\n     *\n     * @var string\n     */\n    public static $defaultView = 'pagination::tailwind';\n\n    /**\n     * The default \"simple\" pagination view.\n     *\n     * @var string\n     */\n    public static $defaultSimpleView = 'pagination::simple-tailwind';\n\n    /**\n     * Determine if the given value is a valid page number.\n     *\n     * @param  int  $page\n     * @return bool\n     */\n    protected function isValidPageNumber($page)\n    {\n        return $page >= 1 && filter_var($page, FILTER_VALIDATE_INT) !== false;\n    }\n\n    /**\n     * Get the URL for the previous page.\n     *\n     * @return string|null\n     */\n    public function previousPageUrl()\n    {\n        if ($this->currentPage() > 1) {\n            return $this->url($this->currentPage() - 1);\n        }\n    }\n\n    /**\n     * Create a range of pagination URLs.\n     *\n     * @param  int  $start\n     * @param  int  $end\n     * @return array\n     */\n    public function getUrlRange($start, $end)\n    {\n        return Collection::range($start, $end)\n            ->mapWithKeys(fn ($page) => [$page => $this->url($page)])\n            ->all();\n    }\n\n    /**\n     * Get the URL for a given page number.\n     *\n     * @param  int  $page\n     * @return string\n     */\n    public function url($page)\n    {\n        if ($page <= 0) {\n            $page = 1;\n        }\n\n        // If we have any extra query string key / value pairs that need to be added\n        // onto the URL, we will put them in query string form and then attach it\n        // to the URL. This allows for extra information like sortings storage.\n        $parameters = [$this->pageName => $page];\n\n        if (count($this->query) > 0) {\n            $parameters = array_merge($this->query, $parameters);\n        }\n\n        return $this->path()\n                        .(str_contains($this->path(), '?') ? '&' : '?')\n                        .Arr::query($parameters)\n                        .$this->buildFragment();\n    }\n\n    /**\n     * Get / set the URL fragment to be appended to URLs.\n     *\n     * @param  string|null  $fragment\n     * @return $this|string|null\n     */\n    public function fragment($fragment = null)\n    {\n        if (is_null($fragment)) {\n            return $this->fragment;\n        }\n\n        $this->fragment = $fragment;\n\n        return $this;\n    }\n\n    /**\n     * Add a set of query string values to the paginator.\n     *\n     * @param  array|string|null  $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function appends($key, $value = null)\n    {\n        if (is_null($key)) {\n            return $this;\n        }\n\n        if (is_array($key)) {\n            return $this->appendArray($key);\n        }\n\n        return $this->addQuery($key, $value);\n    }\n\n    /**\n     * Add an array of query string values.\n     *\n     * @param  array  $keys\n     * @return $this\n     */\n    protected function appendArray(array $keys)\n    {\n        foreach ($keys as $key => $value) {\n            $this->addQuery($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add all current query string values to the paginator.\n     *\n     * @return $this\n     */\n    public function withQueryString()\n    {\n        if (isset(static::$queryStringResolver)) {\n            return $this->appends(call_user_func(static::$queryStringResolver));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a query string value to the paginator.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return $this\n     */\n    protected function addQuery($key, $value)\n    {\n        if ($key !== $this->pageName) {\n            $this->query[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Build the full fragment portion of a URL.\n     *\n     * @return string\n     */\n    protected function buildFragment()\n    {\n        return $this->fragment ? '#'.$this->fragment : '';\n    }\n\n    /**\n     * Load a set of relationships onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorph($relation, $relations)\n    {\n        $this->getCollection()->loadMorph($relation, $relations);\n\n        return $this;\n    }\n\n    /**\n     * Load a set of relationship counts onto the mixed relationship collection.\n     *\n     * @param  string  $relation\n     * @param  array  $relations\n     * @return $this\n     */\n    public function loadMorphCount($relation, $relations)\n    {\n        $this->getCollection()->loadMorphCount($relation, $relations);\n\n        return $this;\n    }\n\n    /**\n     * Get the slice of items being paginated.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function items()\n    {\n        return $this->items->all();\n    }\n\n    /**\n     * Get the number of the first item in the slice.\n     *\n     * @return int|null\n     */\n    public function firstItem()\n    {\n        return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null;\n    }\n\n    /**\n     * Get the number of the last item in the slice.\n     *\n     * @return int|null\n     */\n    public function lastItem()\n    {\n        return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null;\n    }\n\n    /**\n     * Transform each item in the slice of items using a callback.\n     *\n     * @template TMapValue\n     *\n     * @param  callable(TValue, TKey): TMapValue  $callback\n     * @return $this\n     *\n     * @phpstan-this-out static<TKey, TMapValue>\n     */\n    public function through(callable $callback)\n    {\n        $this->items->transform($callback);\n\n        return $this;\n    }\n\n    /**\n     * Get the number of items shown per page.\n     *\n     * @return int\n     */\n    public function perPage()\n    {\n        return $this->perPage;\n    }\n\n    /**\n     * Determine if there are enough items to split into multiple pages.\n     *\n     * @return bool\n     */\n    public function hasPages()\n    {\n        return $this->currentPage() != 1 || $this->hasMorePages();\n    }\n\n    /**\n     * Determine if the paginator is on the first page.\n     *\n     * @return bool\n     */\n    public function onFirstPage()\n    {\n        return $this->currentPage() <= 1;\n    }\n\n    /**\n     * Determine if the paginator is on the last page.\n     *\n     * @return bool\n     */\n    public function onLastPage()\n    {\n        return ! $this->hasMorePages();\n    }\n\n    /**\n     * Get the current page.\n     *\n     * @return int\n     */\n    public function currentPage()\n    {\n        return $this->currentPage;\n    }\n\n    /**\n     * Get the query string variable used to store the page.\n     *\n     * @return string\n     */\n    public function getPageName()\n    {\n        return $this->pageName;\n    }\n\n    /**\n     * Set the query string variable used to store the page.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setPageName($name)\n    {\n        $this->pageName = $name;\n\n        return $this;\n    }\n\n    /**\n     * Set the base path to assign to all URLs.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function withPath($path)\n    {\n        return $this->setPath($path);\n    }\n\n    /**\n     * Set the base path to assign to all URLs.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function setPath($path)\n    {\n        $this->path = $path;\n\n        return $this;\n    }\n\n    /**\n     * Set the number of links to display on each side of current page link.\n     *\n     * @param  int  $count\n     * @return $this\n     */\n    public function onEachSide($count)\n    {\n        $this->onEachSide = $count;\n\n        return $this;\n    }\n\n    /**\n     * Get the base path for paginator generated URLs.\n     *\n     * @return string|null\n     */\n    public function path()\n    {\n        return $this->path;\n    }\n\n    /**\n     * Resolve the current request path or return the default value.\n     *\n     * @param  string  $default\n     * @return string\n     */\n    public static function resolveCurrentPath($default = '/')\n    {\n        if (isset(static::$currentPathResolver)) {\n            return call_user_func(static::$currentPathResolver);\n        }\n\n        return $default;\n    }\n\n    /**\n     * Set the current request path resolver callback.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public static function currentPathResolver(Closure $resolver)\n    {\n        static::$currentPathResolver = $resolver;\n    }\n\n    /**\n     * Resolve the current page or return the default value.\n     *\n     * @param  string  $pageName\n     * @param  int  $default\n     * @return int\n     */\n    public static function resolveCurrentPage($pageName = 'page', $default = 1)\n    {\n        if (isset(static::$currentPageResolver)) {\n            return (int) call_user_func(static::$currentPageResolver, $pageName);\n        }\n\n        return $default;\n    }\n\n    /**\n     * Set the current page resolver callback.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public static function currentPageResolver(Closure $resolver)\n    {\n        static::$currentPageResolver = $resolver;\n    }\n\n    /**\n     * Resolve the query string or return the default value.\n     *\n     * @param  string|array|null  $default\n     * @return string\n     */\n    public static function resolveQueryString($default = null)\n    {\n        if (isset(static::$queryStringResolver)) {\n            return (static::$queryStringResolver)();\n        }\n\n        return $default;\n    }\n\n    /**\n     * Set with query string resolver callback.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public static function queryStringResolver(Closure $resolver)\n    {\n        static::$queryStringResolver = $resolver;\n    }\n\n    /**\n     * Get an instance of the view factory from the resolver.\n     *\n     * @return \\Illuminate\\Contracts\\View\\Factory\n     */\n    public static function viewFactory()\n    {\n        return call_user_func(static::$viewFactoryResolver);\n    }\n\n    /**\n     * Set the view factory resolver callback.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public static function viewFactoryResolver(Closure $resolver)\n    {\n        static::$viewFactoryResolver = $resolver;\n    }\n\n    /**\n     * Set the default pagination view.\n     *\n     * @param  string  $view\n     * @return void\n     */\n    public static function defaultView($view)\n    {\n        static::$defaultView = $view;\n    }\n\n    /**\n     * Set the default \"simple\" pagination view.\n     *\n     * @param  string  $view\n     * @return void\n     */\n    public static function defaultSimpleView($view)\n    {\n        static::$defaultSimpleView = $view;\n    }\n\n    /**\n     * Indicate that Tailwind styling should be used for generated links.\n     *\n     * @return void\n     */\n    public static function useTailwind()\n    {\n        static::defaultView('pagination::tailwind');\n        static::defaultSimpleView('pagination::simple-tailwind');\n    }\n\n    /**\n     * Indicate that Bootstrap 4 styling should be used for generated links.\n     *\n     * @return void\n     */\n    public static function useBootstrap()\n    {\n        static::useBootstrapFour();\n    }\n\n    /**\n     * Indicate that Bootstrap 3 styling should be used for generated links.\n     *\n     * @return void\n     */\n    public static function useBootstrapThree()\n    {\n        static::defaultView('pagination::bootstrap-3');\n        static::defaultSimpleView('pagination::simple-bootstrap-3');\n    }\n\n    /**\n     * Indicate that Bootstrap 4 styling should be used for generated links.\n     *\n     * @return void\n     */\n    public static function useBootstrapFour()\n    {\n        static::defaultView('pagination::bootstrap-4');\n        static::defaultSimpleView('pagination::simple-bootstrap-4');\n    }\n\n    /**\n     * Indicate that Bootstrap 5 styling should be used for generated links.\n     *\n     * @return void\n     */\n    public static function useBootstrapFive()\n    {\n        static::defaultView('pagination::bootstrap-5');\n        static::defaultSimpleView('pagination::simple-bootstrap-5');\n    }\n\n    /**\n     * Get an iterator for the items.\n     *\n     * @return \\ArrayIterator<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return $this->items->getIterator();\n    }\n\n    /**\n     * Determine if the list of items is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return $this->items->isEmpty();\n    }\n\n    /**\n     * Determine if the list of items is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return $this->items->isNotEmpty();\n    }\n\n    /**\n     * Get the number of items for the current page.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return $this->items->count();\n    }\n\n    /**\n     * Get the paginator's underlying collection.\n     *\n     * @return \\Illuminate\\Support\\Collection<TKey, TValue>\n     */\n    public function getCollection()\n    {\n        return $this->items;\n    }\n\n    /**\n     * Set the paginator's underlying collection.\n     *\n     * @param  \\Illuminate\\Support\\Collection<TKey, TValue>  $collection\n     * @return $this\n     */\n    public function setCollection(Collection $collection)\n    {\n        $this->items = $collection;\n\n        return $this;\n    }\n\n    /**\n     * Get the paginator options.\n     *\n     * @return array\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * Determine if the given item exists.\n     *\n     * @param  TKey  $key\n     * @return bool\n     */\n    public function offsetExists($key): bool\n    {\n        return $this->items->has($key);\n    }\n\n    /**\n     * Get the item at the given offset.\n     *\n     * @param  TKey  $key\n     * @return TValue|null\n     */\n    public function offsetGet($key): mixed\n    {\n        return $this->items->get($key);\n    }\n\n    /**\n     * Set the item at the given offset.\n     *\n     * @param  TKey|null  $key\n     * @param  TValue  $value\n     * @return void\n     */\n    public function offsetSet($key, $value): void\n    {\n        $this->items->put($key, $value);\n    }\n\n    /**\n     * Unset the item at the given key.\n     *\n     * @param  TKey  $key\n     * @return void\n     */\n    public function offsetUnset($key): void\n    {\n        $this->items->forget($key);\n    }\n\n    /**\n     * Render the contents of the paginator to HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return (string) $this->render();\n    }\n\n    /**\n     * Make dynamic calls into the collection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->getCollection(), $method, $parameters);\n    }\n\n    /**\n     * Render the contents of the paginator when casting to a string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->escapeWhenCastingToString\n            ? e((string) $this->render())\n            : (string) $this->render();\n    }\n\n    /**\n     * Indicate that the paginator's string representation should be escaped when __toString is invoked.\n     *\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function escapeWhenCastingToString($escape = true)\n    {\n        $this->escapeWhenCastingToString = $escape;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/Cursor.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Collection;\nuse UnexpectedValueException;\n\n/** @implements Arrayable<array-key, mixed> */\nclass Cursor implements Arrayable\n{\n    /**\n     * The parameters associated with the cursor.\n     *\n     * @var array\n     */\n    protected $parameters;\n\n    /**\n     * Determine whether the cursor points to the next or previous set of items.\n     *\n     * @var bool\n     */\n    protected $pointsToNextItems;\n\n    /**\n     * Create a new cursor instance.\n     *\n     * @param  array  $parameters\n     * @param  bool  $pointsToNextItems\n     */\n    public function __construct(array $parameters, $pointsToNextItems = true)\n    {\n        $this->parameters = $parameters;\n        $this->pointsToNextItems = $pointsToNextItems;\n    }\n\n    /**\n     * Get the given parameter from the cursor.\n     *\n     * @param  string  $parameterName\n     * @return string|null\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function parameter(string $parameterName)\n    {\n        if (! array_key_exists($parameterName, $this->parameters)) {\n            throw new UnexpectedValueException(\"Unable to find parameter [{$parameterName}] in pagination item.\");\n        }\n\n        return $this->parameters[$parameterName];\n    }\n\n    /**\n     * Get the given parameters from the cursor.\n     *\n     * @param  array  $parameterNames\n     * @return array\n     */\n    public function parameters(array $parameterNames)\n    {\n        return (new Collection($parameterNames))\n            ->map(fn ($parameterName) => $this->parameter($parameterName))\n            ->toArray();\n    }\n\n    /**\n     * Determine whether the cursor points to the next set of items.\n     *\n     * @return bool\n     */\n    public function pointsToNextItems()\n    {\n        return $this->pointsToNextItems;\n    }\n\n    /**\n     * Determine whether the cursor points to the previous set of items.\n     *\n     * @return bool\n     */\n    public function pointsToPreviousItems()\n    {\n        return ! $this->pointsToNextItems;\n    }\n\n    /**\n     * Get the array representation of the cursor.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return array_merge($this->parameters, [\n            '_pointsToNextItems' => $this->pointsToNextItems,\n        ]);\n    }\n\n    /**\n     * Get the encoded string representation of the cursor to construct a URL.\n     *\n     * @return string\n     */\n    public function encode()\n    {\n        return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(json_encode($this->toArray())));\n    }\n\n    /**\n     * Get a cursor instance from the encoded string representation.\n     *\n     * @param  string|null  $encodedString\n     * @return static|null\n     */\n    public static function fromEncoded($encodedString)\n    {\n        if (! is_string($encodedString)) {\n            return null;\n        }\n\n        $parameters = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $encodedString)), true);\n\n        if (json_last_error() !== JSON_ERROR_NONE) {\n            return null;\n        }\n\n        $pointsToNextItems = $parameters['_pointsToNextItems'];\n\n        unset($parameters['_pointsToNextItems']);\n\n        return new static($parameters, $pointsToNextItems);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/CursorPaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse ArrayAccess;\nuse Countable;\nuse Illuminate\\Contracts\\Pagination\\CursorPaginator as PaginatorContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Collection;\nuse IteratorAggregate;\nuse JsonSerializable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @extends AbstractCursorPaginator<TKey, TValue>\n *\n * @implements Arrayable<TKey, TValue>\n * @implements ArrayAccess<TKey, TValue>\n * @implements IteratorAggregate<TKey, TValue>\n * @implements PaginatorContract<TKey, TValue>\n */\nclass CursorPaginator extends AbstractCursorPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, PaginatorContract\n{\n    /**\n     * Indicates whether there are more items in the data source.\n     *\n     * @return bool\n     */\n    protected $hasMore;\n\n    /**\n     * Create a new paginator instance.\n     *\n     * @param  Collection<TKey, TValue>|Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items\n     * @param  int  $perPage\n     * @param  \\Illuminate\\Pagination\\Cursor|null  $cursor\n     * @param  array  $options  (path, query, fragment, pageName)\n     */\n    public function __construct($items, $perPage, $cursor = null, array $options = [])\n    {\n        $this->options = $options;\n\n        foreach ($options as $key => $value) {\n            $this->{$key} = $value;\n        }\n\n        $this->perPage = (int) $perPage;\n        $this->cursor = $cursor;\n        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;\n\n        $this->setItems($items);\n    }\n\n    /**\n     * Set the items for the paginator.\n     *\n     * @param  Collection<TKey, TValue>|Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items\n     * @return void\n     */\n    protected function setItems($items)\n    {\n        $this->items = $items instanceof Collection ? $items : new Collection($items);\n\n        $this->hasMore = $this->items->count() > $this->perPage;\n\n        $this->items = $this->items->slice(0, $this->perPage);\n\n        if (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems()) {\n            $this->items = $this->items->reverse()->values();\n        }\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable\n     */\n    public function links($view = null, $data = [])\n    {\n        return $this->render($view, $data);\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable\n     */\n    public function render($view = null, $data = [])\n    {\n        return static::viewFactory()->make($view ?: Paginator::$defaultSimpleView, array_merge($data, [\n            'paginator' => $this,\n        ]));\n    }\n\n    /**\n     * Determine if there are more items in the data source.\n     *\n     * @return bool\n     */\n    public function hasMorePages()\n    {\n        return (is_null($this->cursor) && $this->hasMore) ||\n            (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && $this->hasMore) ||\n            (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems());\n    }\n\n    /**\n     * Determine if there are enough items to split into multiple pages.\n     *\n     * @return bool\n     */\n    public function hasPages()\n    {\n        return ! $this->onFirstPage() || $this->hasMorePages();\n    }\n\n    /**\n     * Determine if the paginator is on the first page.\n     *\n     * @return bool\n     */\n    public function onFirstPage()\n    {\n        return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore);\n    }\n\n    /**\n     * Determine if the paginator is on the last page.\n     *\n     * @return bool\n     */\n    public function onLastPage()\n    {\n        return ! $this->hasMorePages();\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'data' => $this->items->toArray(),\n            'path' => $this->path(),\n            'per_page' => $this->perPage(),\n            'next_cursor' => $this->nextCursor()?->encode(),\n            'next_page_url' => $this->nextPageUrl(),\n            'prev_cursor' => $this->previousCursor()?->encode(),\n            'prev_page_url' => $this->previousPageUrl(),\n        ];\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Convert the object to its JSON representation.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Convert the object to pretty print formatted JSON.\n     *\n     * @params int $options\n     *\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Pagination/LengthAwarePaginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse ArrayAccess;\nuse Countable;\nuse Illuminate\\Contracts\\Pagination\\LengthAwarePaginator as LengthAwarePaginatorContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Collection;\nuse IteratorAggregate;\nuse JsonSerializable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @extends AbstractPaginator<TKey, TValue>\n *\n * @implements Arrayable<TKey, TValue>\n * @implements ArrayAccess<TKey, TValue>\n * @implements IteratorAggregate<TKey, TValue>\n * @implements LengthAwarePaginatorContract<TKey, TValue>\n */\nclass LengthAwarePaginator extends AbstractPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, LengthAwarePaginatorContract\n{\n    /**\n     * The total number of items before slicing.\n     *\n     * @var int\n     */\n    protected $total;\n\n    /**\n     * The last available page.\n     *\n     * @var int\n     */\n    protected $lastPage;\n\n    /**\n     * Create a new paginator instance.\n     *\n     * @param  Collection<TKey, TValue>|Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items\n     * @param  int  $total\n     * @param  int  $perPage\n     * @param  int|null  $currentPage\n     * @param  array  $options  (path, query, fragment, pageName)\n     */\n    public function __construct($items, $total, $perPage, $currentPage = null, array $options = [])\n    {\n        $this->options = $options;\n\n        foreach ($options as $key => $value) {\n            $this->{$key} = $value;\n        }\n\n        $this->total = $total;\n        $this->perPage = (int) $perPage;\n        $this->lastPage = max((int) ceil($total / $perPage), 1);\n        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;\n        $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName);\n        $this->items = $items instanceof Collection ? $items : new Collection($items);\n    }\n\n    /**\n     * Get the current page for the request.\n     *\n     * @param  int  $currentPage\n     * @param  string  $pageName\n     * @return int\n     */\n    protected function setCurrentPage($currentPage, $pageName)\n    {\n        $currentPage = $currentPage ?: static::resolveCurrentPage($pageName);\n\n        return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable\n     */\n    public function links($view = null, $data = [])\n    {\n        return $this->render($view, $data);\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable\n     */\n    public function render($view = null, $data = [])\n    {\n        return static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [\n            'paginator' => $this,\n            'elements' => $this->elements(),\n        ]));\n    }\n\n    /**\n     * Get the paginator links as a collection (for JSON responses).\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function linkCollection()\n    {\n        return (new Collection($this->elements()))->flatMap(function ($item) {\n            if (! is_array($item)) {\n                return [['url' => null, 'label' => '...', 'active' => false]];\n            }\n\n            return (new Collection($item))->map(function ($url, $page) {\n                return [\n                    'url' => $url,\n                    'label' => (string) $page,\n                    'page' => $page,\n                    'active' => $this->currentPage() === $page,\n                ];\n            });\n        })->prepend([\n            'url' => $this->previousPageUrl(),\n            'label' => function_exists('__') ? __('pagination.previous') : 'Previous',\n            'page' => $this->currentPage() > 1 ? $this->currentPage() - 1 : null,\n            'active' => false,\n        ])->push([\n            'url' => $this->nextPageUrl(),\n            'label' => function_exists('__') ? __('pagination.next') : 'Next',\n            'page' => $this->hasMorePages() ? $this->currentPage() + 1 : null,\n            'active' => false,\n        ]);\n    }\n\n    /**\n     * Get the array of elements to pass to the view.\n     *\n     * @return array\n     */\n    protected function elements()\n    {\n        $window = UrlWindow::make($this);\n\n        return array_filter([\n            $window['first'],\n            is_array($window['slider']) ? '...' : null,\n            $window['slider'],\n            is_array($window['last']) ? '...' : null,\n            $window['last'],\n        ]);\n    }\n\n    /**\n     * Get the total number of items being paginated.\n     *\n     * @return int\n     */\n    public function total()\n    {\n        return $this->total;\n    }\n\n    /**\n     * Determine if there are more items in the data source.\n     *\n     * @return bool\n     */\n    public function hasMorePages()\n    {\n        return $this->currentPage() < $this->lastPage();\n    }\n\n    /**\n     * Get the URL for the next page.\n     *\n     * @return string|null\n     */\n    public function nextPageUrl()\n    {\n        if ($this->hasMorePages()) {\n            return $this->url($this->currentPage() + 1);\n        }\n    }\n\n    /**\n     * Get the last page.\n     *\n     * @return int\n     */\n    public function lastPage()\n    {\n        return $this->lastPage;\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'current_page' => $this->currentPage(),\n            'data' => $this->items->toArray(),\n            'first_page_url' => $this->url(1),\n            'from' => $this->firstItem(),\n            'last_page' => $this->lastPage(),\n            'last_page_url' => $this->url($this->lastPage()),\n            'links' => $this->linkCollection()->toArray(),\n            'next_page_url' => $this->nextPageUrl(),\n            'path' => $this->path(),\n            'per_page' => $this->perPage(),\n            'prev_page_url' => $this->previousPageUrl(),\n            'to' => $this->lastItem(),\n            'total' => $this->total(),\n        ];\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Convert the object to its JSON representation.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Convert the object to pretty print formatted JSON.\n     *\n     * @params int $options\n     *\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/PaginationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse Illuminate\\Support\\ServiceProvider;\n\nclass PaginationServiceProvider extends ServiceProvider\n{\n    /**\n     * Bootstrap any application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        $this->loadViewsFrom(__DIR__.'/resources/views', 'pagination');\n\n        if ($this->app->runningInConsole()) {\n            $this->publishes([\n                __DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/pagination'),\n            ], 'laravel-pagination');\n        }\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        PaginationState::resolveUsing($this->app);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/PaginationState.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nclass PaginationState\n{\n    /**\n     * Bind the pagination state resolvers using the given application container as a base.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return void\n     */\n    public static function resolveUsing($app)\n    {\n        Paginator::viewFactoryResolver(fn () => $app['view']);\n\n        Paginator::currentPathResolver(fn () => $app['request']->url());\n\n        Paginator::currentPageResolver(function ($pageName = 'page') use ($app) {\n            $page = $app['request']->input($pageName);\n\n            if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {\n                return (int) $page;\n            }\n\n            return 1;\n        });\n\n        Paginator::queryStringResolver(fn () => $app['request']->query());\n\n        CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) {\n            return Cursor::fromEncoded($app['request']->input($cursorName));\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/Paginator.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse ArrayAccess;\nuse Countable;\nuse Illuminate\\Contracts\\Pagination\\Paginator as PaginatorContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Collection;\nuse IteratorAggregate;\nuse JsonSerializable;\n\n/**\n * @template TKey of array-key\n *\n * @template-covariant TValue\n *\n * @extends AbstractPaginator<TKey, TValue>\n *\n * @implements Arrayable<TKey, TValue>\n * @implements ArrayAccess<TKey, TValue>\n * @implements IteratorAggregate<TKey, TValue>\n * @implements PaginatorContract<TKey, TValue>\n */\nclass Paginator extends AbstractPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, PaginatorContract\n{\n    /**\n     * Determine if there are more items in the data source.\n     *\n     * @return bool\n     */\n    protected $hasMore;\n\n    /**\n     * Create a new paginator instance.\n     *\n     * @param  Collection<TKey, TValue>|Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items\n     * @param  int  $perPage\n     * @param  int|null  $currentPage\n     * @param  array  $options  (path, query, fragment, pageName)\n     */\n    public function __construct($items, $perPage, $currentPage = null, array $options = [])\n    {\n        $this->options = $options;\n\n        foreach ($options as $key => $value) {\n            $this->{$key} = $value;\n        }\n\n        $this->perPage = $perPage;\n        $this->currentPage = $this->setCurrentPage($currentPage);\n        $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;\n\n        $this->setItems($items);\n    }\n\n    /**\n     * Get the current page for the request.\n     *\n     * @param  int  $currentPage\n     * @return int\n     */\n    protected function setCurrentPage($currentPage)\n    {\n        $currentPage = $currentPage ?: static::resolveCurrentPage();\n\n        return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;\n    }\n\n    /**\n     * Set the items for the paginator.\n     *\n     * @param  Collection<TKey, TValue>|Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items\n     * @return void\n     */\n    protected function setItems($items)\n    {\n        $this->items = $items instanceof Collection ? $items : new Collection($items);\n\n        $this->hasMore = $this->items->count() > $this->perPage;\n\n        $this->items = $this->items->slice(0, $this->perPage);\n    }\n\n    /**\n     * Get the URL for the next page.\n     *\n     * @return string|null\n     */\n    public function nextPageUrl()\n    {\n        if ($this->hasMorePages()) {\n            return $this->url($this->currentPage() + 1);\n        }\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return string\n     */\n    public function links($view = null, $data = [])\n    {\n        return $this->render($view, $data);\n    }\n\n    /**\n     * Render the paginator using the given view.\n     *\n     * @param  string|null  $view\n     * @param  array  $data\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable\n     */\n    public function render($view = null, $data = [])\n    {\n        return static::viewFactory()->make($view ?: static::$defaultSimpleView, array_merge($data, [\n            'paginator' => $this,\n        ]));\n    }\n\n    /**\n     * Manually indicate that the paginator does have more pages.\n     *\n     * @param  bool  $hasMore\n     * @return $this\n     */\n    public function hasMorePagesWhen($hasMore = true)\n    {\n        $this->hasMore = $hasMore;\n\n        return $this;\n    }\n\n    /**\n     * Determine if there are more items in the data source.\n     *\n     * @return bool\n     */\n    public function hasMorePages()\n    {\n        return $this->hasMore;\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return [\n            'current_page' => $this->currentPage(),\n            'current_page_url' => $this->url($this->currentPage()),\n            'data' => $this->items->toArray(),\n            'first_page_url' => $this->url(1),\n            'from' => $this->firstItem(),\n            'next_page_url' => $this->nextPageUrl(),\n            'path' => $this->path(),\n            'per_page' => $this->perPage(),\n            'prev_page_url' => $this->previousPageUrl(),\n            'to' => $this->lastItem(),\n        ];\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Convert the object to its JSON representation.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Convert the object to pretty print formatted JSON.\n     *\n     * @params int $options\n     *\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/UrlWindow.php",
    "content": "<?php\n\nnamespace Illuminate\\Pagination;\n\nuse Illuminate\\Contracts\\Pagination\\LengthAwarePaginator as PaginatorContract;\n\nclass UrlWindow\n{\n    /**\n     * The paginator implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Pagination\\LengthAwarePaginator\n     */\n    protected $paginator;\n\n    /**\n     * Create a new URL window instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Pagination\\LengthAwarePaginator  $paginator\n     */\n    public function __construct(PaginatorContract $paginator)\n    {\n        $this->paginator = $paginator;\n    }\n\n    /**\n     * Create a new URL window instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Pagination\\LengthAwarePaginator  $paginator\n     * @return array\n     */\n    public static function make(PaginatorContract $paginator)\n    {\n        return (new static($paginator))->get();\n    }\n\n    /**\n     * Get the window of URLs to be shown.\n     *\n     * @return array\n     */\n    public function get()\n    {\n        $onEachSide = $this->paginator->onEachSide;\n\n        if ($this->paginator->lastPage() < ($onEachSide * 2) + 8) {\n            return $this->getSmallSlider();\n        }\n\n        return $this->getUrlSlider($onEachSide);\n    }\n\n    /**\n     * Get the slider of URLs there are not enough pages to slide.\n     *\n     * @return array\n     */\n    protected function getSmallSlider()\n    {\n        return [\n            'first' => $this->paginator->getUrlRange(1, $this->lastPage()),\n            'slider' => null,\n            'last' => null,\n        ];\n    }\n\n    /**\n     * Create a URL slider links.\n     *\n     * @param  int  $onEachSide\n     * @return array\n     */\n    protected function getUrlSlider($onEachSide)\n    {\n        $window = $onEachSide + 4;\n\n        if (! $this->hasPages()) {\n            return ['first' => null, 'slider' => null, 'last' => null];\n        }\n\n        // If the current page is very close to the beginning of the page range, we will\n        // just render the beginning of the page range, followed by the last 2 of the\n        // links in this list, since we will not have room to create a full slider.\n        if ($this->currentPage() <= $window) {\n            return $this->getSliderTooCloseToBeginning($window, $onEachSide);\n        }\n\n        // If the current page is close to the ending of the page range we will just get\n        // this first couple pages, followed by a larger window of these ending pages\n        // since we're too close to the end of the list to create a full on slider.\n        elseif ($this->currentPage() > ($this->lastPage() - $window)) {\n            return $this->getSliderTooCloseToEnding($window, $onEachSide);\n        }\n\n        // If we have enough room on both sides of the current page to build a slider we\n        // will surround it with both the beginning and ending caps, with this window\n        // of pages in the middle providing a Google style sliding paginator setup.\n        return $this->getFullSlider($onEachSide);\n    }\n\n    /**\n     * Get the slider of URLs when too close to the beginning of the window.\n     *\n     * @param  int  $window\n     * @param  int  $onEachSide\n     * @return array\n     */\n    protected function getSliderTooCloseToBeginning($window, $onEachSide)\n    {\n        return [\n            'first' => $this->paginator->getUrlRange(1, $window + $onEachSide),\n            'slider' => null,\n            'last' => $this->getFinish(),\n        ];\n    }\n\n    /**\n     * Get the slider of URLs when too close to the ending of the window.\n     *\n     * @param  int  $window\n     * @param  int  $onEachSide\n     * @return array\n     */\n    protected function getSliderTooCloseToEnding($window, $onEachSide)\n    {\n        $last = $this->paginator->getUrlRange(\n            $this->lastPage() - ($window + ($onEachSide - 1)),\n            $this->lastPage()\n        );\n\n        return [\n            'first' => $this->getStart(),\n            'slider' => null,\n            'last' => $last,\n        ];\n    }\n\n    /**\n     * Get the slider of URLs when a full slider can be made.\n     *\n     * @param  int  $onEachSide\n     * @return array\n     */\n    protected function getFullSlider($onEachSide)\n    {\n        return [\n            'first' => $this->getStart(),\n            'slider' => $this->getAdjacentUrlRange($onEachSide),\n            'last' => $this->getFinish(),\n        ];\n    }\n\n    /**\n     * Get the page range for the current page window.\n     *\n     * @param  int  $onEachSide\n     * @return array\n     */\n    public function getAdjacentUrlRange($onEachSide)\n    {\n        return $this->paginator->getUrlRange(\n            $this->currentPage() - $onEachSide,\n            $this->currentPage() + $onEachSide\n        );\n    }\n\n    /**\n     * Get the starting URLs of a pagination slider.\n     *\n     * @return array\n     */\n    public function getStart()\n    {\n        return $this->paginator->getUrlRange(1, 2);\n    }\n\n    /**\n     * Get the ending URLs of a pagination slider.\n     *\n     * @return array\n     */\n    public function getFinish()\n    {\n        return $this->paginator->getUrlRange(\n            $this->lastPage() - 1,\n            $this->lastPage()\n        );\n    }\n\n    /**\n     * Determine if the underlying paginator being presented has pages to show.\n     *\n     * @return bool\n     */\n    public function hasPages()\n    {\n        return $this->paginator->lastPage() > 1;\n    }\n\n    /**\n     * Get the current page from the paginator.\n     *\n     * @return int\n     */\n    protected function currentPage()\n    {\n        return $this->paginator->currentPage();\n    }\n\n    /**\n     * Get the last page from the paginator.\n     *\n     * @return int\n     */\n    protected function lastPage()\n    {\n        return $this->paginator->lastPage();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/composer.json",
    "content": "{\n    \"name\": \"illuminate/pagination\",\n    \"description\": \"The Illuminate Pagination package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-filter\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Pagination\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/bootstrap-3.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav>\n        <ul class=\"pagination\">\n            {{-- Previous Page Link --}}\n            @if ($paginator->onFirstPage())\n                <li class=\"disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.previous')\">\n                    <span aria-hidden=\"true\">&lsaquo;</span>\n                </li>\n            @else\n                <li>\n                    <a href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" aria-label=\"@lang('pagination.previous')\">&lsaquo;</a>\n                </li>\n            @endif\n\n            {{-- Pagination Elements --}}\n            @foreach ($elements as $element)\n                {{-- \"Three Dots\" Separator --}}\n                @if (is_string($element))\n                    <li class=\"disabled\" aria-disabled=\"true\"><span>{{ $element }}</span></li>\n                @endif\n\n                {{-- Array Of Links --}}\n                @if (is_array($element))\n                    @foreach ($element as $page => $url)\n                        @if ($page == $paginator->currentPage())\n                            <li class=\"active\" aria-current=\"page\"><span>{{ $page }}</span></li>\n                        @else\n                            <li><a href=\"{{ $url }}\">{{ $page }}</a></li>\n                        @endif\n                    @endforeach\n                @endif\n            @endforeach\n\n            {{-- Next Page Link --}}\n            @if ($paginator->hasMorePages())\n                <li>\n                    <a href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" aria-label=\"@lang('pagination.next')\">&rsaquo;</a>\n                </li>\n            @else\n                <li class=\"disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.next')\">\n                    <span aria-hidden=\"true\">&rsaquo;</span>\n                </li>\n            @endif\n        </ul>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/bootstrap-4.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav>\n        <ul class=\"pagination\">\n            {{-- Previous Page Link --}}\n            @if ($paginator->onFirstPage())\n                <li class=\"page-item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.previous')\">\n                    <span class=\"page-link\" aria-hidden=\"true\">&lsaquo;</span>\n                </li>\n            @else\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" aria-label=\"@lang('pagination.previous')\">&lsaquo;</a>\n                </li>\n            @endif\n\n            {{-- Pagination Elements --}}\n            @foreach ($elements as $element)\n                {{-- \"Three Dots\" Separator --}}\n                @if (is_string($element))\n                    <li class=\"page-item disabled\" aria-disabled=\"true\"><span class=\"page-link\">{{ $element }}</span></li>\n                @endif\n\n                {{-- Array Of Links --}}\n                @if (is_array($element))\n                    @foreach ($element as $page => $url)\n                        @if ($page == $paginator->currentPage())\n                            <li class=\"page-item active\" aria-current=\"page\"><span class=\"page-link\">{{ $page }}</span></li>\n                        @else\n                            <li class=\"page-item\"><a class=\"page-link\" href=\"{{ $url }}\">{{ $page }}</a></li>\n                        @endif\n                    @endforeach\n                @endif\n            @endforeach\n\n            {{-- Next Page Link --}}\n            @if ($paginator->hasMorePages())\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" aria-label=\"@lang('pagination.next')\">&rsaquo;</a>\n                </li>\n            @else\n                <li class=\"page-item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.next')\">\n                    <span class=\"page-link\" aria-hidden=\"true\">&rsaquo;</span>\n                </li>\n            @endif\n        </ul>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/bootstrap-5.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav class=\"d-flex justify-items-center justify-content-between\">\n        <div class=\"d-flex justify-content-between flex-fill d-sm-none\">\n            <ul class=\"pagination\">\n                {{-- Previous Page Link --}}\n                @if ($paginator->onFirstPage())\n                    <li class=\"page-item disabled\" aria-disabled=\"true\">\n                        <span class=\"page-link\">@lang('pagination.previous')</span>\n                    </li>\n                @else\n                    <li class=\"page-item\">\n                        <a class=\"page-link\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\">@lang('pagination.previous')</a>\n                    </li>\n                @endif\n\n                {{-- Next Page Link --}}\n                @if ($paginator->hasMorePages())\n                    <li class=\"page-item\">\n                        <a class=\"page-link\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\">@lang('pagination.next')</a>\n                    </li>\n                @else\n                    <li class=\"page-item disabled\" aria-disabled=\"true\">\n                        <span class=\"page-link\">@lang('pagination.next')</span>\n                    </li>\n                @endif\n            </ul>\n        </div>\n\n        <div class=\"d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between\">\n            <div class=\"small text-muted\">\n                {!! __('Showing') !!}\n                <span class=\"fw-semibold\">{{ $paginator->firstItem() }}</span>\n                {!! __('to') !!}\n                <span class=\"fw-semibold\">{{ $paginator->lastItem() }}</span>\n                {!! __('of') !!}\n                <span class=\"fw-semibold\">{{ $paginator->total() }}</span>\n                {!! __('results') !!}\n            </div>\n\n            <div>\n                <ul class=\"pagination\">\n                    {{-- Previous Page Link --}}\n                    @if ($paginator->onFirstPage())\n                        <li class=\"page-item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.previous')\">\n                            <span class=\"page-link\" aria-hidden=\"true\">&lsaquo;</span>\n                        </li>\n                    @else\n                        <li class=\"page-item\">\n                            <a class=\"page-link\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" aria-label=\"@lang('pagination.previous')\">&lsaquo;</a>\n                        </li>\n                    @endif\n\n                    {{-- Pagination Elements --}}\n                    @foreach ($elements as $element)\n                        {{-- \"Three Dots\" Separator --}}\n                        @if (is_string($element))\n                            <li class=\"page-item disabled\" aria-disabled=\"true\"><span class=\"page-link\">{{ $element }}</span></li>\n                        @endif\n\n                        {{-- Array Of Links --}}\n                        @if (is_array($element))\n                            @foreach ($element as $page => $url)\n                                @if ($page == $paginator->currentPage())\n                                    <li class=\"page-item active\" aria-current=\"page\"><span class=\"page-link\">{{ $page }}</span></li>\n                                @else\n                                    <li class=\"page-item\"><a class=\"page-link\" href=\"{{ $url }}\">{{ $page }}</a></li>\n                                @endif\n                            @endforeach\n                        @endif\n                    @endforeach\n\n                    {{-- Next Page Link --}}\n                    @if ($paginator->hasMorePages())\n                        <li class=\"page-item\">\n                            <a class=\"page-link\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" aria-label=\"@lang('pagination.next')\">&rsaquo;</a>\n                        </li>\n                    @else\n                        <li class=\"page-item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.next')\">\n                            <span class=\"page-link\" aria-hidden=\"true\">&rsaquo;</span>\n                        </li>\n                    @endif\n                </ul>\n            </div>\n        </div>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/semantic-ui.blade.php",
    "content": "@if ($paginator->hasPages())\n    <div class=\"ui pagination menu\" role=\"navigation\">\n        {{-- Previous Page Link --}}\n        @if ($paginator->onFirstPage())\n            <a class=\"icon item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.previous')\"> <i class=\"left chevron icon\"></i> </a>\n        @else\n            <a class=\"icon item\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" aria-label=\"@lang('pagination.previous')\"> <i class=\"left chevron icon\"></i> </a>\n        @endif\n\n        {{-- Pagination Elements --}}\n        @foreach ($elements as $element)\n            {{-- \"Three Dots\" Separator --}}\n            @if (is_string($element))\n                <a class=\"icon item disabled\" aria-disabled=\"true\">{{ $element }}</a>\n            @endif\n\n            {{-- Array Of Links --}}\n            @if (is_array($element))\n                @foreach ($element as $page => $url)\n                    @if ($page == $paginator->currentPage())\n                        <a class=\"item active\" href=\"{{ $url }}\" aria-current=\"page\">{{ $page }}</a>\n                    @else\n                        <a class=\"item\" href=\"{{ $url }}\">{{ $page }}</a>\n                    @endif\n                @endforeach\n            @endif\n        @endforeach\n\n        {{-- Next Page Link --}}\n        @if ($paginator->hasMorePages())\n            <a class=\"icon item\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" aria-label=\"@lang('pagination.next')\"> <i class=\"right chevron icon\"></i> </a>\n        @else\n            <a class=\"icon item disabled\" aria-disabled=\"true\" aria-label=\"@lang('pagination.next')\"> <i class=\"right chevron icon\"></i> </a>\n        @endif\n    </div>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/simple-bootstrap-3.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav>\n        <ul class=\"pagination\">\n            {{-- Previous Page Link --}}\n            @if ($paginator->onFirstPage())\n                <li class=\"disabled\" aria-disabled=\"true\"><span>@lang('pagination.previous')</span></li>\n            @else\n                <li><a href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\">@lang('pagination.previous')</a></li>\n            @endif\n\n            {{-- Next Page Link --}}\n            @if ($paginator->hasMorePages())\n                <li><a href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\">@lang('pagination.next')</a></li>\n            @else\n                <li class=\"disabled\" aria-disabled=\"true\"><span>@lang('pagination.next')</span></li>\n            @endif\n        </ul>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/simple-bootstrap-4.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav>\n        <ul class=\"pagination\">\n            {{-- Previous Page Link --}}\n            @if ($paginator->onFirstPage())\n                <li class=\"page-item disabled\" aria-disabled=\"true\">\n                    <span class=\"page-link\">@lang('pagination.previous')</span>\n                </li>\n            @else\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\">@lang('pagination.previous')</a>\n                </li>\n            @endif\n\n            {{-- Next Page Link --}}\n            @if ($paginator->hasMorePages())\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\">@lang('pagination.next')</a>\n                </li>\n            @else\n                <li class=\"page-item disabled\" aria-disabled=\"true\">\n                    <span class=\"page-link\">@lang('pagination.next')</span>\n                </li>\n            @endif\n        </ul>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/simple-bootstrap-5.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav role=\"navigation\" aria-label=\"{!! __('Pagination Navigation') !!}\">\n        <ul class=\"pagination\">\n            {{-- Previous Page Link --}}\n            @if ($paginator->onFirstPage())\n                <li class=\"page-item disabled\" aria-disabled=\"true\">\n                    <span class=\"page-link\">{!! __('pagination.previous') !!}</span>\n                </li>\n            @else\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\">\n                        {!! __('pagination.previous') !!}\n                    </a>\n                </li>\n            @endif\n\n            {{-- Next Page Link --}}\n            @if ($paginator->hasMorePages())\n                <li class=\"page-item\">\n                    <a class=\"page-link\" href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\">{!! __('pagination.next') !!}</a>\n                </li>\n            @else\n                <li class=\"page-item disabled\" aria-disabled=\"true\">\n                    <span class=\"page-link\">{!! __('pagination.next') !!}</span>\n                </li>\n            @endif\n        </ul>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/simple-tailwind.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav role=\"navigation\" aria-label=\"{{ __('Pagination Navigation') }}\" class=\"flex gap-2 items-center justify-between\">\n\n        @if ($paginator->onFirstPage())\n            <span class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600\">\n                {!! __('pagination.previous') !!}\n            </span>\n        @else\n            <a href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200\">\n                {!! __('pagination.previous') !!}\n            </a>\n        @endif\n\n        @if ($paginator->hasMorePages())\n            <a href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200\">\n                {!! __('pagination.next') !!}\n            </a>\n        @else\n            <span class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600\">\n                {!! __('pagination.next') !!}\n            </span>\n        @endif\n\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pagination/resources/views/tailwind.blade.php",
    "content": "@if ($paginator->hasPages())\n    <nav role=\"navigation\" aria-label=\"{{ __('Pagination Navigation') }}\">\n\n        <div class=\"flex gap-2 items-center justify-between sm:hidden\">\n\n            @if ($paginator->onFirstPage())\n                <span class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600\">\n                    {!! __('pagination.previous') !!}\n                </span>\n            @else\n                <a href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200\">\n                    {!! __('pagination.previous') !!}\n                </a>\n            @endif\n\n            @if ($paginator->hasMorePages())\n                <a href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200\">\n                    {!! __('pagination.next') !!}\n                </a>\n            @else\n                <span class=\"inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600\">\n                    {!! __('pagination.next') !!}\n                </span>\n            @endif\n\n        </div>\n\n        <div class=\"hidden sm:flex-1 sm:flex sm:gap-2 sm:items-center sm:justify-between\">\n\n            <div>\n                <p class=\"text-sm text-gray-700 leading-5 dark:text-gray-600\">\n                    {!! __('Showing') !!}\n                    @if ($paginator->firstItem())\n                        <span class=\"font-medium\">{{ $paginator->firstItem() }}</span>\n                        {!! __('to') !!}\n                        <span class=\"font-medium\">{{ $paginator->lastItem() }}</span>\n                    @else\n                        {{ $paginator->count() }}\n                    @endif\n                    {!! __('of') !!}\n                    <span class=\"font-medium\">{{ $paginator->total() }}</span>\n                    {!! __('results') !!}\n                </p>\n            </div>\n\n            <div>\n                <span class=\"inline-flex rtl:flex-row-reverse shadow-sm rounded-md\">\n\n                    {{-- Previous Page Link --}}\n                    @if ($paginator->onFirstPage())\n                        <span aria-disabled=\"true\" aria-label=\"{{ __('pagination.previous') }}\">\n                            <span class=\"inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-not-allowed rounded-l-md leading-5 dark:bg-gray-700 dark:border-gray-600 dark:text-gray-400\" aria-hidden=\"true\">\n                                <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                                    <path fill-rule=\"evenodd\" d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\" clip-rule=\"evenodd\" />\n                                </svg>\n                            </span>\n                        </span>\n                    @else\n                        <a href=\"{{ $paginator->previousPageUrl() }}\" rel=\"prev\" class=\"inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:active:bg-gray-700 dark:focus:border-blue-800 dark:text-gray-300 dark:hover:bg-gray-900 dark:hover:text-gray-300\" aria-label=\"{{ __('pagination.previous') }}\">\n                            <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                                <path fill-rule=\"evenodd\" d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\" clip-rule=\"evenodd\" />\n                            </svg>\n                        </a>\n                    @endif\n\n                    {{-- Pagination Elements --}}\n                    @foreach ($elements as $element)\n                        {{-- \"Three Dots\" Separator --}}\n                        @if (is_string($element))\n                            <span aria-disabled=\"true\">\n                                <span class=\"inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300\">{{ $element }}</span>\n                            </span>\n                        @endif\n\n                        {{-- Array Of Links --}}\n                        @if (is_array($element))\n                            @foreach ($element as $page => $url)\n                                @if ($page == $paginator->currentPage())\n                                    <span aria-current=\"page\">\n                                        <span class=\"inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-gray-200 border border-gray-300 cursor-default leading-5 dark:bg-gray-700 dark:border-gray-600 dark:text-gray-300\">{{ $page }}</span>\n                                    </span>\n                                @else\n                                    <a href=\"{{ $url }}\" class=\"inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:hover:text-gray-300 dark:active:bg-gray-700 dark:focus:border-blue-800 hover:bg-gray-100 dark:hover:bg-gray-900\" aria-label=\"{{ __('Go to page :page', ['page' => $page]) }}\">\n                                        {{ $page }}\n                                    </a>\n                                @endif\n                            @endforeach\n                        @endif\n                    @endforeach\n\n                    {{-- Next Page Link --}}\n                    @if ($paginator->hasMorePages())\n                        <a href=\"{{ $paginator->nextPageUrl() }}\" rel=\"next\" class=\"inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:active:bg-gray-700 dark:focus:border-blue-800 dark:text-gray-300 dark:hover:bg-gray-900 dark:hover:text-gray-300\" aria-label=\"{{ __('pagination.next') }}\">\n                            <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                                <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\" />\n                            </svg>\n                        </a>\n                    @else\n                        <span aria-disabled=\"true\" aria-label=\"{{ __('pagination.next') }}\">\n                            <span class=\"inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-not-allowed rounded-r-md leading-5 dark:bg-gray-700 dark:border-gray-600 dark:text-gray-400\" aria-hidden=\"true\">\n                                <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                                    <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\" />\n                                </svg>\n                            </span>\n                        </span>\n                    @endif\n                </span>\n            </div>\n        </div>\n    </nav>\n@endif\n"
  },
  {
    "path": "src/Illuminate/Pipeline/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Pipeline/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Pipeline/Hub.php",
    "content": "<?php\n\nnamespace Illuminate\\Pipeline;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Pipeline\\Hub as HubContract;\n\nclass Hub implements HubContract\n{\n    /**\n     * The container implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container|null\n     */\n    protected $container;\n\n    /**\n     * All of the available pipelines.\n     *\n     * @var array\n     */\n    protected $pipelines = [];\n\n    /**\n     * Create a new Hub instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container|null  $container\n     */\n    public function __construct(?Container $container = null)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Define the default named pipeline.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function defaults(Closure $callback)\n    {\n        $this->pipeline('default', $callback);\n    }\n\n    /**\n     * Define a new named pipeline.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function pipeline($name, Closure $callback)\n    {\n        $this->pipelines[$name] = $callback;\n    }\n\n    /**\n     * Send an object through one of the available pipelines.\n     *\n     * @param  mixed  $object\n     * @param  string|null  $pipeline\n     * @return mixed\n     */\n    public function pipe($object, $pipeline = null)\n    {\n        $pipeline = $pipeline ?: 'default';\n\n        return call_user_func(\n            $this->pipelines[$pipeline], new Pipeline($this->container), $object\n        );\n    }\n\n    /**\n     * Get the container instance used by the hub.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the container instance used by the hub.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pipeline/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Pipeline/Pipeline.php",
    "content": "<?php\n\nnamespace Illuminate\\Pipeline;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Pipeline\\Pipeline as PipelineContract;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse RuntimeException;\nuse Throwable;\n\nclass Pipeline implements PipelineContract\n{\n    use Conditionable;\n    use Macroable;\n\n    /**\n     * The container implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container|null\n     */\n    protected $container;\n\n    /**\n     * The object being passed through the pipeline.\n     *\n     * @var mixed\n     */\n    protected $passable;\n\n    /**\n     * The array of class pipes.\n     *\n     * @var array\n     */\n    protected $pipes = [];\n\n    /**\n     * The method to call on each pipe.\n     *\n     * @var string\n     */\n    protected $method = 'handle';\n\n    /**\n     * The final callback to be executed after the pipeline ends regardless of the outcome.\n     *\n     * @var \\Closure|null\n     */\n    protected $finally;\n\n    /**\n     * Indicates whether to wrap the pipeline in a database transaction.\n     *\n     * @var string|null|\\UnitEnum|false\n     */\n    protected $withinTransaction = false;\n\n    /**\n     * Create a new class instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container|null  $container\n     */\n    public function __construct(?Container $container = null)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Set the object being sent through the pipeline.\n     *\n     * @param  mixed  $passable\n     * @return $this\n     */\n    public function send($passable)\n    {\n        $this->passable = $passable;\n\n        return $this;\n    }\n\n    /**\n     * Set the array of pipes.\n     *\n     * @param  mixed  $pipes\n     * @return $this\n     */\n    public function through($pipes)\n    {\n        $this->pipes = is_array($pipes) ? $pipes : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Push additional pipes onto the pipeline.\n     *\n     * @param  mixed  $pipes\n     * @return $this\n     */\n    public function pipe($pipes)\n    {\n        array_push($this->pipes, ...(is_array($pipes) ? $pipes : func_get_args()));\n\n        return $this;\n    }\n\n    /**\n     * Set the method to call on the pipes.\n     *\n     * @param  string  $method\n     * @return $this\n     */\n    public function via($method)\n    {\n        $this->method = $method;\n\n        return $this;\n    }\n\n    /**\n     * Run the pipeline with a final destination callback.\n     *\n     * @param  \\Closure  $destination\n     * @return mixed\n     */\n    public function then(Closure $destination)\n    {\n        $pipeline = array_reduce(\n            array_reverse($this->pipes()), $this->carry(), $this->prepareDestination($destination)\n        );\n\n        try {\n            return $this->withinTransaction !== false\n                ? $this->getContainer()->make('db')->connection($this->withinTransaction)->transaction(fn () => $pipeline($this->passable))\n                : $pipeline($this->passable);\n        } finally {\n            if ($this->finally) {\n                ($this->finally)($this->passable);\n            }\n        }\n    }\n\n    /**\n     * Run the pipeline and return the result.\n     *\n     * @return mixed\n     */\n    public function thenReturn()\n    {\n        return $this->then(function ($passable) {\n            return $passable;\n        });\n    }\n\n    /**\n     * Set a final callback to be executed after the pipeline ends regardless of the outcome.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function finally(Closure $callback)\n    {\n        $this->finally = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the final piece of the Closure onion.\n     *\n     * @param  \\Closure  $destination\n     * @return \\Closure\n     */\n    protected function prepareDestination(Closure $destination)\n    {\n        return function ($passable) use ($destination) {\n            try {\n                return $destination($passable);\n            } catch (Throwable $e) {\n                return $this->handleException($passable, $e);\n            }\n        };\n    }\n\n    /**\n     * Get a Closure that represents a slice of the application onion.\n     *\n     * @return \\Closure\n     */\n    protected function carry()\n    {\n        return function ($stack, $pipe) {\n            return function ($passable) use ($stack, $pipe) {\n                try {\n                    if (is_callable($pipe)) {\n                        // If the pipe is a callable, then we will call it directly, but otherwise we\n                        // will resolve the pipes out of the dependency container and call it with\n                        // the appropriate method and arguments, returning the results back out.\n                        return $pipe($passable, $stack);\n                    } elseif (! is_object($pipe)) {\n                        [$name, $parameters] = $this->parsePipeString($pipe);\n\n                        // If the pipe is a string we will parse the string and resolve the class out\n                        // of the dependency injection container. We can then build a callable and\n                        // execute the pipe function giving in the parameters that are required.\n                        $pipe = $this->getContainer()->make($name);\n\n                        $parameters = array_merge([$passable, $stack], $parameters);\n                    } else {\n                        // If the pipe is already an object we'll just make a callable and pass it to\n                        // the pipe as-is. There is no need to do any extra parsing and formatting\n                        // since the object we're given was already a fully instantiated object.\n                        $parameters = [$passable, $stack];\n                    }\n\n                    $carry = method_exists($pipe, $this->method)\n                        ? $pipe->{$this->method}(...$parameters)\n                        : $pipe(...$parameters);\n\n                    return $this->handleCarry($carry);\n                } catch (Throwable $e) {\n                    return $this->handleException($passable, $e);\n                }\n            };\n        };\n    }\n\n    /**\n     * Parse full pipe string to get name and parameters.\n     *\n     * @param  string  $pipe\n     * @return array\n     */\n    protected function parsePipeString($pipe)\n    {\n        [$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, null);\n\n        if (! is_null($parameters)) {\n            $parameters = explode(',', $parameters);\n        } else {\n            $parameters = [];\n        }\n\n        return [$name, $parameters];\n    }\n\n    /**\n     * Get the array of configured pipes.\n     *\n     * @return array\n     */\n    protected function pipes()\n    {\n        return $this->pipes;\n    }\n\n    /**\n     * Execute each pipeline step within a database transaction.\n     *\n     * @param  string|null|\\UnitEnum|false  $withinTransaction\n     * @return $this\n     */\n    public function withinTransaction($withinTransaction = null)\n    {\n        $this->withinTransaction = $withinTransaction;\n\n        return $this;\n    }\n\n    /**\n     * Get the container instance.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getContainer()\n    {\n        if (! $this->container) {\n            throw new RuntimeException('A container instance has not been passed to the Pipeline.');\n        }\n\n        return $this->container;\n    }\n\n    /**\n     * Set the container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Handle the value returned from each pipe before passing it to the next.\n     *\n     * @param  mixed  $carry\n     * @return mixed\n     */\n    protected function handleCarry($carry)\n    {\n        return $carry;\n    }\n\n    /**\n     * Handle the given exception.\n     *\n     * @param  mixed  $passable\n     * @param  \\Throwable  $e\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    protected function handleException($passable, Throwable $e)\n    {\n        throw $e;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pipeline/PipelineServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Pipeline;\n\nuse Illuminate\\Contracts\\Pipeline\\Hub as PipelineHubContract;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass PipelineServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton(\n            PipelineHubContract::class,\n            Hub::class\n        );\n\n        $this->app->bind('pipeline', fn ($app) => new Pipeline($app));\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            PipelineHubContract::class,\n            'pipeline',\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Pipeline/composer.json",
    "content": "{\n    \"name\": \"illuminate/pipeline\",\n    \"description\": \"The Illuminate Pipeline package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"illuminate/database\": \"Required to use database transactions (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Pipeline\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Process/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Process/Exceptions/ProcessFailedException.php",
    "content": "<?php\n\nnamespace Illuminate\\Process\\Exceptions;\n\nuse Illuminate\\Contracts\\Process\\ProcessResult;\nuse RuntimeException;\n\nclass ProcessFailedException extends RuntimeException\n{\n    /**\n     * The process result instance.\n     *\n     * @var \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public $result;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult  $result\n     */\n    public function __construct(ProcessResult $result)\n    {\n        $this->result = $result;\n\n        $error = sprintf('The command \"%s\" failed.'.\"\\n\\nExit Code: %s\",\n            $result->command(),\n            $result->exitCode(),\n        );\n\n        if (! empty($result->output())) {\n            $error .= sprintf(\"\\n\\nOutput:\\n================\\n%s\", $result->output());\n        }\n\n        if (! empty($result->errorOutput())) {\n            $error .= sprintf(\"\\n\\nError Output:\\n================\\n%s\", $result->errorOutput());\n        }\n\n        parent::__construct($error, $result->exitCode() ?? 1);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/Exceptions/ProcessTimedOutException.php",
    "content": "<?php\n\nnamespace Illuminate\\Process\\Exceptions;\n\nuse Illuminate\\Contracts\\Process\\ProcessResult;\nuse Symfony\\Component\\Process\\Exception\\ProcessTimedOutException as SymfonyTimeoutException;\nuse Symfony\\Component\\Process\\Exception\\RuntimeException;\n\nclass ProcessTimedOutException extends RuntimeException\n{\n    /**\n     * The process result instance.\n     *\n     * @var \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public $result;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  \\Symfony\\Component\\Process\\Exception\\ProcessTimedOutException  $original\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult  $result\n     */\n    public function __construct(SymfonyTimeoutException $original, ProcessResult $result)\n    {\n        $this->result = $result;\n\n        parent::__construct($original->getMessage(), $original->getCode(), $original);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Closure;\nuse Illuminate\\Contracts\\Process\\ProcessResult as ProcessResultContract;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\nclass Factory\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * Indicates if the process factory has faked process handlers.\n     *\n     * @var bool\n     */\n    protected $recording = false;\n\n    /**\n     * All of the recorded processes.\n     *\n     * @var array\n     */\n    protected $recorded = [];\n\n    /**\n     * The registered fake handler callbacks.\n     *\n     * @var array\n     */\n    protected $fakeHandlers = [];\n\n    /**\n     * Indicates that an exception should be thrown if any process is not faked.\n     *\n     * @var bool\n     */\n    protected $preventStrayProcesses = false;\n\n    /**\n     * Create a new fake process response for testing purposes.\n     *\n     * @param  array|string  $output\n     * @param  array|string  $errorOutput\n     * @param  int  $exitCode\n     * @return \\Illuminate\\Process\\FakeProcessResult\n     */\n    public function result(array|string $output = '', array|string $errorOutput = '', int $exitCode = 0)\n    {\n        return new FakeProcessResult(\n            output: $output,\n            errorOutput: $errorOutput,\n            exitCode: $exitCode,\n        );\n    }\n\n    /**\n     * Begin describing a fake process lifecycle.\n     *\n     * @return \\Illuminate\\Process\\FakeProcessDescription\n     */\n    public function describe()\n    {\n        return new FakeProcessDescription;\n    }\n\n    /**\n     * Begin describing a fake process sequence.\n     *\n     * @param  array  $processes\n     * @return \\Illuminate\\Process\\FakeProcessSequence\n     */\n    public function sequence(array $processes = [])\n    {\n        return new FakeProcessSequence($processes);\n    }\n\n    /**\n     * Indicate that the process factory should fake processes.\n     *\n     * @param  \\Closure|array|null  $callback\n     * @return $this\n     */\n    public function fake(Closure|array|null $callback = null)\n    {\n        $this->recording = true;\n\n        if (is_null($callback)) {\n            $this->fakeHandlers = ['*' => fn () => new FakeProcessResult];\n\n            return $this;\n        }\n\n        if ($callback instanceof Closure) {\n            $this->fakeHandlers = ['*' => $callback];\n\n            return $this;\n        }\n\n        foreach ($callback as $command => $handler) {\n            $this->fakeHandlers[is_numeric($command) ? '*' : $command] = $handler instanceof Closure\n                ? $handler\n                : fn () => $handler;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the process factory has fake process handlers and is recording processes.\n     *\n     * @return bool\n     */\n    public function isRecording()\n    {\n        return $this->recording;\n    }\n\n    /**\n     * Record the given process if processes should be recorded.\n     *\n     * @param  \\Illuminate\\Process\\PendingProcess  $process\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult  $result\n     * @return $this\n     */\n    public function recordIfRecording(PendingProcess $process, ProcessResultContract $result)\n    {\n        if ($this->isRecording()) {\n            $this->record($process, $result);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Record the given process.\n     *\n     * @param  \\Illuminate\\Process\\PendingProcess  $process\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult  $result\n     * @return $this\n     */\n    public function record(PendingProcess $process, ProcessResultContract $result)\n    {\n        $this->recorded[] = [$process, $result];\n\n        return $this;\n    }\n\n    /**\n     * Indicate that an exception should be thrown if any process is not faked.\n     *\n     * @param  bool  $prevent\n     * @return $this\n     */\n    public function preventStrayProcesses(bool $prevent = true)\n    {\n        $this->preventStrayProcesses = $prevent;\n\n        return $this;\n    }\n\n    /**\n     * Determine if stray processes are being prevented.\n     *\n     * @return bool\n     */\n    public function preventingStrayProcesses()\n    {\n        return $this->preventStrayProcesses;\n    }\n\n    /**\n     * Assert that a process was recorded matching a given truth test.\n     *\n     * @param  \\Closure|string  $callback\n     * @return $this\n     */\n    public function assertRan(Closure|string $callback)\n    {\n        $callback = is_string($callback) ? fn ($process) => $process->command === $callback : $callback;\n\n        PHPUnit::assertTrue(\n            (new Collection($this->recorded))->filter(function ($pair) use ($callback) {\n                return $callback($pair[0], $pair[1]);\n            })->count() > 0,\n            'An expected process was not invoked.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that a process was recorded a given number of times matching a given truth test.\n     *\n     * @param  \\Closure|string  $callback\n     * @param  int  $times\n     * @return $this\n     */\n    public function assertRanTimes(Closure|string $callback, int $times = 1)\n    {\n        $callback = is_string($callback) ? fn ($process) => $process->command === $callback : $callback;\n\n        $count = (new Collection($this->recorded))\n            ->filter(fn ($pair) => $callback($pair[0], $pair[1]))\n            ->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            \"An expected process ran {$count} times instead of {$times} times.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that a process was not recorded matching a given truth test.\n     *\n     * @param  \\Closure|string  $callback\n     * @return $this\n     */\n    public function assertNotRan(Closure|string $callback)\n    {\n        $callback = is_string($callback) ? fn ($process) => $process->command === $callback : $callback;\n\n        PHPUnit::assertTrue(\n            (new Collection($this->recorded))->filter(function ($pair) use ($callback) {\n                return $callback($pair[0], $pair[1]);\n            })->count() === 0,\n            'An unexpected process was invoked.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that a process was not recorded matching a given truth test.\n     *\n     * @param  \\Closure|string  $callback\n     * @return $this\n     */\n    public function assertDidntRun(Closure|string $callback)\n    {\n        return $this->assertNotRan($callback);\n    }\n\n    /**\n     * Assert that no processes were recorded.\n     *\n     * @return $this\n     */\n    public function assertNothingRan()\n    {\n        PHPUnit::assertEmpty(\n            $this->recorded,\n            'An unexpected process was invoked.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Start defining a pool of processes.\n     *\n     * @param  callable  $callback\n     * @return \\Illuminate\\Process\\Pool\n     */\n    public function pool(callable $callback)\n    {\n        return new Pool($this, $callback);\n    }\n\n    /**\n     * Start defining a series of piped processes.\n     *\n     * @param  callable|array  $callback\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public function pipe(callable|array $callback, ?callable $output = null)\n    {\n        return is_array($callback)\n            ? (new Pipe($this, fn ($pipe) => (new Collection($callback))->each(\n                fn ($command) => $pipe->command($command)\n            )))->run(output: $output)\n            : (new Pipe($this, $callback))->run(output: $output);\n    }\n\n    /**\n     * Run a pool of processes and wait for them to finish executing.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\ProcessPoolResults\n     */\n    public function concurrently(callable $callback, ?callable $output = null)\n    {\n        return (new Pool($this, $callback))->start($output)->wait();\n    }\n\n    /**\n     * Create a new pending process associated with this factory.\n     *\n     * @return \\Illuminate\\Process\\PendingProcess\n     */\n    public function newPendingProcess()\n    {\n        return (new PendingProcess($this))->withFakeHandlers($this->fakeHandlers);\n    }\n\n    /**\n     * Dynamically proxy methods to a new pending process instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->newPendingProcess()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/FakeInvokedProcess.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Contracts\\Process\\InvokedProcess as InvokedProcessContract;\n\nclass FakeInvokedProcess implements InvokedProcessContract\n{\n    /**\n     * The command being faked.\n     *\n     * @var string\n     */\n    protected $command;\n\n    /**\n     * The underlying process description.\n     *\n     * @var \\Illuminate\\Process\\FakeProcessDescription\n     */\n    protected $process;\n\n    /**\n     * The signals that have been received.\n     *\n     * @var array\n     */\n    protected $receivedSignals = [];\n\n    /**\n     * The number of times the process should indicate that it is \"running\".\n     *\n     * @var int|null\n     */\n    protected $remainingRunIterations;\n\n    /**\n     * The general output handler callback.\n     *\n     * @var callable|null\n     */\n    protected $outputHandler;\n\n    /**\n     * The current output's index.\n     *\n     * @var int\n     */\n    protected $nextOutputIndex = 0;\n\n    /**\n     * The current error output's index.\n     *\n     * @var int\n     */\n    protected $nextErrorOutputIndex = 0;\n\n    /**\n     * Create a new invoked process instance.\n     *\n     * @param  string  $command\n     * @param  \\Illuminate\\Process\\FakeProcessDescription  $process\n     */\n    public function __construct(string $command, FakeProcessDescription $process)\n    {\n        $this->command = $command;\n        $this->process = $process;\n    }\n\n    /**\n     * Get the process ID if the process is still running.\n     *\n     * @return int|null\n     */\n    public function id()\n    {\n        $this->invokeOutputHandlerWithNextLineOfOutput();\n\n        return $this->process->processId;\n    }\n\n    /**\n     * Get the command line for the process.\n     *\n     * @return string\n     */\n    public function command()\n    {\n        return $this->command;\n    }\n\n    /**\n     * Send a signal to the process.\n     *\n     * @param  int  $signal\n     * @return $this\n     */\n    public function signal(int $signal)\n    {\n        $this->invokeOutputHandlerWithNextLineOfOutput();\n\n        $this->receivedSignals[] = $signal;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the process has received the given signal.\n     *\n     * @param  int  $signal\n     * @return bool\n     */\n    public function hasReceivedSignal(int $signal)\n    {\n        return in_array($signal, $this->receivedSignals);\n    }\n\n    /**\n     * Determine if the process is still running.\n     *\n     * @return bool\n     */\n    public function running()\n    {\n        $this->invokeOutputHandlerWithNextLineOfOutput();\n\n        $this->remainingRunIterations = is_null($this->remainingRunIterations)\n            ? $this->process->runIterations\n            : $this->remainingRunIterations;\n\n        if ($this->remainingRunIterations === 0) {\n            while ($this->invokeOutputHandlerWithNextLineOfOutput()) {\n            }\n\n            return false;\n        }\n\n        $this->remainingRunIterations = $this->remainingRunIterations - 1;\n\n        return true;\n    }\n\n    /**\n     * Invoke the asynchronous output handler with the next single line of output if necessary.\n     *\n     * @return array|false\n     */\n    protected function invokeOutputHandlerWithNextLineOfOutput()\n    {\n        if (! $this->outputHandler) {\n            return false;\n        }\n\n        [$outputCount, $outputStartingPoint] = [\n            count($this->process->output),\n            min($this->nextOutputIndex, $this->nextErrorOutputIndex),\n        ];\n\n        for ($i = $outputStartingPoint; $i < $outputCount; $i++) {\n            $currentOutput = $this->process->output[$i];\n\n            if ($currentOutput['type'] === 'out' && $i >= $this->nextOutputIndex) {\n                call_user_func($this->outputHandler, 'out', $currentOutput['buffer']);\n                $this->nextOutputIndex = $i + 1;\n\n                return $currentOutput;\n            } elseif ($currentOutput['type'] === 'err' && $i >= $this->nextErrorOutputIndex) {\n                call_user_func($this->outputHandler, 'err', $currentOutput['buffer']);\n                $this->nextErrorOutputIndex = $i + 1;\n\n                return $currentOutput;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the standard output for the process.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        $this->latestOutput();\n\n        $output = [];\n\n        for ($i = 0; $i < $this->nextOutputIndex; $i++) {\n            if ($this->process->output[$i]['type'] === 'out') {\n                $output[] = $this->process->output[$i]['buffer'];\n            }\n        }\n\n        return rtrim(implode('', $output), \"\\n\").\"\\n\";\n    }\n\n    /**\n     * Get the error output for the process.\n     *\n     * @return string\n     */\n    public function errorOutput()\n    {\n        $this->latestErrorOutput();\n\n        $output = [];\n\n        for ($i = 0; $i < $this->nextErrorOutputIndex; $i++) {\n            if ($this->process->output[$i]['type'] === 'err') {\n                $output[] = $this->process->output[$i]['buffer'];\n            }\n        }\n\n        return rtrim(implode('', $output), \"\\n\").\"\\n\";\n    }\n\n    /**\n     * Get the latest standard output for the process.\n     *\n     * @return string\n     */\n    public function latestOutput()\n    {\n        $outputCount = count($this->process->output);\n\n        for ($i = $this->nextOutputIndex; $i < $outputCount; $i++) {\n            if ($this->process->output[$i]['type'] === 'out') {\n                $output = $this->process->output[$i]['buffer'];\n                $this->nextOutputIndex = $i + 1;\n\n                break;\n            }\n\n            $this->nextOutputIndex = $i + 1;\n        }\n\n        return $output ?? '';\n    }\n\n    /**\n     * Get the latest error output for the process.\n     *\n     * @return string\n     */\n    public function latestErrorOutput()\n    {\n        $outputCount = count($this->process->output);\n\n        for ($i = $this->nextErrorOutputIndex; $i < $outputCount; $i++) {\n            if ($this->process->output[$i]['type'] === 'err') {\n                $output = $this->process->output[$i]['buffer'];\n                $this->nextErrorOutputIndex = $i + 1;\n\n                break;\n            }\n\n            $this->nextErrorOutputIndex = $i + 1;\n        }\n\n        return $output ?? '';\n    }\n\n    /**\n     * Wait for the process to finish.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public function wait(?callable $output = null)\n    {\n        $this->outputHandler = $output ?: $this->outputHandler;\n\n        if (! $this->outputHandler) {\n            $this->remainingRunIterations = 0;\n\n            return $this->predictProcessResult();\n        }\n\n        while ($this->invokeOutputHandlerWithNextLineOfOutput()) {\n            //\n        }\n\n        $this->remainingRunIterations = 0;\n\n        return $this->process->toProcessResult($this->command);\n    }\n\n    /**\n     * Wait until the given callback returns true.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public function waitUntil(?callable $output = null)\n    {\n        $shouldStop = false;\n\n        $this->outputHandler = $output\n            ? function ($type, $buffer) use ($output, &$shouldStop) {\n                $shouldStop = call_user_func($output, $type, $buffer);\n            }\n        : $this->outputHandler;\n\n        if (! $this->outputHandler) {\n            $this->remainingRunIterations = 0;\n\n            return $this->predictProcessResult();\n        }\n\n        while ($this->running() && ! $shouldStop) {\n            //\n        }\n\n        $this->remainingRunIterations = 0;\n\n        return $this->process->toProcessResult($this->command);\n    }\n\n    /**\n     * Get the ultimate process result that will be returned by this \"process\".\n     *\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public function predictProcessResult()\n    {\n        return $this->process->toProcessResult($this->command);\n    }\n\n    /**\n     * Set the general output handler for the fake invoked process.\n     *\n     * @param  callable|null  $outputHandler\n     * @return $this\n     */\n    public function withOutputHandler(?callable $outputHandler)\n    {\n        $this->outputHandler = $outputHandler;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/FakeProcessDescription.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Process\\Process;\n\nclass FakeProcessDescription\n{\n    /**\n     * The process' ID.\n     *\n     * @var int|null\n     */\n    public $processId = 1000;\n\n    /**\n     * All of the process' output in the order it was described.\n     *\n     * @var array\n     */\n    public $output = [];\n\n    /**\n     * The process' exit code.\n     *\n     * @var int\n     */\n    public $exitCode = 0;\n\n    /**\n     * The number of times the process should indicate that it is \"running\".\n     *\n     * @var int\n     */\n    public $runIterations = 0;\n\n    /**\n     * Specify the process ID that should be assigned to the process.\n     *\n     * @param  int  $processId\n     * @return $this\n     */\n    public function id(int $processId)\n    {\n        $this->processId = $processId;\n\n        return $this;\n    }\n\n    /**\n     * Describe a line of standard output.\n     *\n     * @param  array|string  $output\n     * @return $this\n     */\n    public function output(array|string $output)\n    {\n        if (is_array($output)) {\n            (new Collection($output))->each(fn ($line) => $this->output($line));\n\n            return $this;\n        }\n\n        $this->output[] = ['type' => 'out', 'buffer' => rtrim($output, \"\\n\").\"\\n\"];\n\n        return $this;\n    }\n\n    /**\n     * Describe a line of error output.\n     *\n     * @param  array|string  $output\n     * @return $this\n     */\n    public function errorOutput(array|string $output)\n    {\n        if (is_array($output)) {\n            (new Collection($output))->each(fn ($line) => $this->errorOutput($line));\n\n            return $this;\n        }\n\n        $this->output[] = ['type' => 'err', 'buffer' => rtrim($output, \"\\n\").\"\\n\"];\n\n        return $this;\n    }\n\n    /**\n     * Replace the entire output buffer with the given string.\n     *\n     * @param  string  $output\n     * @return $this\n     */\n    public function replaceOutput(string $output)\n    {\n        $this->output = (new Collection($this->output))\n            ->reject(fn ($output) => $output['type'] === 'out')\n            ->values()\n            ->all();\n\n        if (strlen($output) > 0) {\n            $this->output[] = [\n                'type' => 'out',\n                'buffer' => rtrim($output, \"\\n\").\"\\n\",\n            ];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Replace the entire error output buffer with the given string.\n     *\n     * @param  string  $output\n     * @return $this\n     */\n    public function replaceErrorOutput(string $output)\n    {\n        $this->output = (new Collection($this->output))\n            ->reject(fn ($output) => $output['type'] === 'err')\n            ->values()\n            ->all();\n\n        if (strlen($output) > 0) {\n            $this->output[] = [\n                'type' => 'err',\n                'buffer' => rtrim($output, \"\\n\").\"\\n\",\n            ];\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify the process exit code.\n     *\n     * @param  int  $exitCode\n     * @return $this\n     */\n    public function exitCode(int $exitCode)\n    {\n        $this->exitCode = $exitCode;\n\n        return $this;\n    }\n\n    /**\n     * Specify how many times the \"isRunning\" method should return \"true\".\n     *\n     * @param  int  $iterations\n     * @return $this\n     */\n    public function iterations(int $iterations)\n    {\n        return $this->runsFor(iterations: $iterations);\n    }\n\n    /**\n     * Specify how many times the \"isRunning\" method should return \"true\".\n     *\n     * @param  int  $iterations\n     * @return $this\n     */\n    public function runsFor(int $iterations)\n    {\n        $this->runIterations = $iterations;\n\n        return $this;\n    }\n\n    /**\n     * Turn the fake process description into an actual process.\n     *\n     * @param  string  $command\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    public function toSymfonyProcess(string $command)\n    {\n        return Process::fromShellCommandline($command);\n    }\n\n    /**\n     * Convert the process description into a process result.\n     *\n     * @param  string  $command\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     */\n    public function toProcessResult(string $command)\n    {\n        return new FakeProcessResult(\n            command: $command,\n            exitCode: $this->exitCode,\n            output: $this->resolveOutput(),\n            errorOutput: $this->resolveErrorOutput(),\n        );\n    }\n\n    /**\n     * Resolve the standard output as a string.\n     *\n     * @return string\n     */\n    protected function resolveOutput()\n    {\n        $output = (new Collection($this->output))\n            ->filter(fn ($output) => $output['type'] === 'out');\n\n        return $output->isNotEmpty()\n            ? rtrim($output->map->buffer->implode(''), \"\\n\").\"\\n\"\n            : '';\n    }\n\n    /**\n     * Resolve the error output as a string.\n     *\n     * @return string\n     */\n    protected function resolveErrorOutput()\n    {\n        $output = (new Collection($this->output))\n            ->filter(fn ($output) => $output['type'] === 'err');\n\n        return $output->isNotEmpty()\n            ? rtrim($output->map->buffer->implode(''), \"\\n\").\"\\n\"\n            : '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/FakeProcessResult.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Contracts\\Process\\ProcessResult as ProcessResultContract;\nuse Illuminate\\Process\\Exceptions\\ProcessFailedException;\nuse Illuminate\\Support\\Collection;\n\nclass FakeProcessResult implements ProcessResultContract\n{\n    /**\n     * The command string.\n     *\n     * @var string\n     */\n    protected $command;\n\n    /**\n     * The process exit code.\n     *\n     * @var int\n     */\n    protected $exitCode;\n\n    /**\n     * The process output.\n     *\n     * @var string\n     */\n    protected $output = '';\n\n    /**\n     * The process error output.\n     *\n     * @var string\n     */\n    protected $errorOutput = '';\n\n    /**\n     * Create a new process result instance.\n     *\n     * @param  string  $command\n     * @param  int  $exitCode\n     * @param  array|string  $output\n     * @param  array|string  $errorOutput\n     */\n    public function __construct(string $command = '', int $exitCode = 0, array|string $output = '', array|string $errorOutput = '')\n    {\n        $this->command = $command;\n        $this->exitCode = $exitCode;\n        $this->output = $this->normalizeOutput($output);\n        $this->errorOutput = $this->normalizeOutput($errorOutput);\n    }\n\n    /**\n     * Normalize the given output into a string with newlines.\n     *\n     * @param  array|string  $output\n     * @return string\n     */\n    protected function normalizeOutput(array|string $output)\n    {\n        if (empty($output)) {\n            return '';\n        } elseif (is_string($output)) {\n            return rtrim($output, \"\\n\").\"\\n\";\n        } elseif (is_array($output)) {\n            return rtrim(\n                (new Collection($output))\n                    ->map(fn ($line) => rtrim($line, \"\\n\").\"\\n\")\n                    ->implode(''),\n                \"\\n\"\n            );\n        }\n    }\n\n    /**\n     * Get the original command executed by the process.\n     *\n     * @return string\n     */\n    public function command()\n    {\n        return $this->command;\n    }\n\n    /**\n     * Create a new fake process result with the given command.\n     *\n     * @param  string  $command\n     * @return self\n     */\n    public function withCommand(string $command)\n    {\n        return new FakeProcessResult($command, $this->exitCode, $this->output, $this->errorOutput);\n    }\n\n    /**\n     * Determine if the process was successful.\n     *\n     * @return bool\n     */\n    public function successful()\n    {\n        return $this->exitCode === 0;\n    }\n\n    /**\n     * Determine if the process failed.\n     *\n     * @return bool\n     */\n    public function failed()\n    {\n        return ! $this->successful();\n    }\n\n    /**\n     * Get the exit code of the process.\n     *\n     * @return int\n     */\n    public function exitCode()\n    {\n        return $this->exitCode;\n    }\n\n    /**\n     * Get the standard output of the process.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        return $this->output;\n    }\n\n    /**\n     * Determine if the output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInOutput(string $output)\n    {\n        return str_contains($this->output(), $output);\n    }\n\n    /**\n     * Get the error output of the process.\n     *\n     * @return string\n     */\n    public function errorOutput()\n    {\n        return $this->errorOutput;\n    }\n\n    /**\n     * Determine if the error output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInErrorOutput(string $output)\n    {\n        return str_contains($this->errorOutput(), $output);\n    }\n\n    /**\n     * Throw an exception if the process failed.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessFailedException\n     */\n    public function throw(?callable $callback = null)\n    {\n        if ($this->successful()) {\n            return $this;\n        }\n\n        $exception = new ProcessFailedException($this);\n\n        if ($callback) {\n            $callback($this, $exception);\n        }\n\n        throw $exception;\n    }\n\n    /**\n     * Throw an exception if the process failed and the given condition is true.\n     *\n     * @param  bool  $condition\n     * @param  callable|null  $callback\n     * @return $this\n     *\n     * @throws \\Throwable\n     */\n    public function throwIf(bool $condition, ?callable $callback = null)\n    {\n        if ($condition) {\n            return $this->throw($callback);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/FakeProcessSequence.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Contracts\\Process\\ProcessResult as ProcessResultContract;\nuse OutOfBoundsException;\n\nclass FakeProcessSequence\n{\n    /**\n     * The fake process results and descriptions.\n     *\n     * @var array\n     */\n    protected $processes = [];\n\n    /**\n     * Indicates that invoking this sequence when it is empty should throw an exception.\n     *\n     * @var bool\n     */\n    protected $failWhenEmpty = true;\n\n    /**\n     * The response that should be returned when the sequence is empty.\n     *\n     * @var \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription\n     */\n    protected $emptyProcess;\n\n    /**\n     * Create a new fake process sequence instance.\n     *\n     * @param  array  $processes\n     */\n    public function __construct(array $processes = [])\n    {\n        $this->processes = $processes;\n    }\n\n    /**\n     * Push a new process result or description onto the sequence.\n     *\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription|array|string  $process\n     * @return $this\n     */\n    public function push(ProcessResultContract|FakeProcessDescription|array|string $process)\n    {\n        $this->processes[] = $this->toProcessResult($process);\n\n        return $this;\n    }\n\n    /**\n     * Make the sequence return a default result when it is empty.\n     *\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription|array|string  $process\n     * @return $this\n     */\n    public function whenEmpty(ProcessResultContract|FakeProcessDescription|array|string $process)\n    {\n        $this->failWhenEmpty = false;\n        $this->emptyProcess = $this->toProcessResult($process);\n\n        return $this;\n    }\n\n    /**\n     * Convert the given result into an actual process result or description.\n     *\n     * @param  \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription|array|string  $process\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription\n     */\n    protected function toProcessResult(ProcessResultContract|FakeProcessDescription|array|string $process)\n    {\n        return is_array($process) || is_string($process)\n            ? new FakeProcessResult(output: $process)\n            : $process;\n    }\n\n    /**\n     * Make the sequence return a default result when it is empty.\n     *\n     * @return $this\n     */\n    public function dontFailWhenEmpty()\n    {\n        return $this->whenEmpty(new FakeProcessResult);\n    }\n\n    /**\n     * Indicate that this sequence has depleted all of its process results.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return count($this->processes) === 0;\n    }\n\n    /**\n     * Get the next process in the sequence.\n     *\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult|\\Illuminate\\Process\\FakeProcessDescription\n     *\n     * @throws \\OutOfBoundsException\n     */\n    public function __invoke()\n    {\n        if ($this->failWhenEmpty && count($this->processes) === 0) {\n            throw new OutOfBoundsException('A process was invoked, but the process result sequence is empty.');\n        }\n\n        if (! $this->failWhenEmpty && count($this->processes) === 0) {\n            return value($this->emptyProcess ?? new FakeProcessResult);\n        }\n\n        return array_shift($this->processes);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/InvokedProcess.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Contracts\\Process\\InvokedProcess as InvokedProcessContract;\nuse Illuminate\\Process\\Exceptions\\ProcessTimedOutException;\nuse Symfony\\Component\\Process\\Exception\\ProcessTimedOutException as SymfonyTimeoutException;\nuse Symfony\\Component\\Process\\Process;\n\nclass InvokedProcess implements InvokedProcessContract\n{\n    /**\n     * The underlying process instance.\n     *\n     * @var \\Symfony\\Component\\Process\\Process\n     */\n    protected $process;\n\n    /**\n     * Create a new invoked process instance.\n     *\n     * @param  \\Symfony\\Component\\Process\\Process  $process\n     */\n    public function __construct(Process $process)\n    {\n        $this->process = $process;\n    }\n\n    /**\n     * Get the process ID if the process is still running.\n     *\n     * @return int|null\n     */\n    public function id()\n    {\n        return $this->process->getPid();\n    }\n\n    /**\n     * Get the command line for the process.\n     *\n     * @return string\n     */\n    public function command()\n    {\n        return $this->process->getCommandLine();\n    }\n\n    /**\n     * Send a signal to the process.\n     *\n     * @param  int  $signal\n     * @return $this\n     */\n    public function signal(int $signal)\n    {\n        $this->process->signal($signal);\n\n        return $this;\n    }\n\n    /**\n     * Stop the process if it is still running.\n     *\n     * @param  float  $timeout\n     * @param  int|null  $signal\n     * @return int|null\n     */\n    public function stop(float $timeout = 10, ?int $signal = null)\n    {\n        return $this->process->stop($timeout, $signal);\n    }\n\n    /**\n     * Determine if the process is still running.\n     *\n     * @return bool\n     */\n    public function running()\n    {\n        return $this->process->isRunning();\n    }\n\n    /**\n     * Get the standard output for the process.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        return $this->process->getOutput();\n    }\n\n    /**\n     * Get the error output for the process.\n     *\n     * @return string\n     */\n    public function errorOutput()\n    {\n        return $this->process->getErrorOutput();\n    }\n\n    /**\n     * Get the latest standard output for the process.\n     *\n     * @return string\n     */\n    public function latestOutput()\n    {\n        return $this->process->getIncrementalOutput();\n    }\n\n    /**\n     * Get the latest error output for the process.\n     *\n     * @return string\n     */\n    public function latestErrorOutput()\n    {\n        return $this->process->getIncrementalErrorOutput();\n    }\n\n    /**\n     * Ensure that the process has not timed out.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessTimedOutException\n     */\n    public function ensureNotTimedOut()\n    {\n        try {\n            $this->process->checkTimeout();\n        } catch (SymfonyTimeoutException $e) {\n            throw new ProcessTimedOutException($e, new ProcessResult($this->process));\n        }\n    }\n\n    /**\n     * Wait for the process to finish.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\ProcessResult\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessTimedOutException\n     */\n    public function wait(?callable $output = null)\n    {\n        try {\n            $this->process->wait($output);\n\n            return new ProcessResult($this->process);\n        } catch (SymfonyTimeoutException $e) {\n            throw new ProcessTimedOutException($e, new ProcessResult($this->process));\n        }\n    }\n\n    /**\n     * Wait until the given callback returns true.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\ProcessResult\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessTimedOutException\n     */\n    public function waitUntil(?callable $output = null)\n    {\n        try {\n            $this->process->waitUntil($output);\n\n            return new ProcessResult($this->process);\n        } catch (SymfonyTimeoutException $e) {\n            throw new ProcessTimedOutException($e, new ProcessResult($this->process));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/InvokedProcessPool.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Countable;\nuse Illuminate\\Support\\Collection;\n\nclass InvokedProcessPool implements Countable\n{\n    /**\n     * The array of invoked processes.\n     *\n     * @var array\n     */\n    protected $invokedProcesses;\n\n    /**\n     * Create a new invoked process pool.\n     *\n     * @param  array  $invokedProcesses\n     */\n    public function __construct(array $invokedProcesses)\n    {\n        $this->invokedProcesses = $invokedProcesses;\n    }\n\n    /**\n     * Send a signal to each running process in the pool, returning the processes that were signalled.\n     *\n     * @param  int  $signal\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function signal(int $signal)\n    {\n        return $this->running()->each->signal($signal);\n    }\n\n    /**\n     * Stop all processes that are still running.\n     *\n     * @param  float  $timeout\n     * @param  int|null  $signal\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function stop(float $timeout = 10, ?int $signal = null)\n    {\n        return $this->running()->each->stop($timeout, $signal);\n    }\n\n    /**\n     * Get the processes in the pool that are still currently running.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function running()\n    {\n        return (new Collection($this->invokedProcesses))->filter->running()->values();\n    }\n\n    /**\n     * Wait for the processes to finish.\n     *\n     * @return \\Illuminate\\Process\\ProcessPoolResults\n     */\n    public function wait()\n    {\n        return new ProcessPoolResults((new Collection($this->invokedProcesses))->map->wait()->all());\n    }\n\n    /**\n     * Get the total number of processes.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return count($this->invokedProcesses);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Process/PendingProcess.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Carbon\\CarbonInterval;\nuse Closure;\nuse Illuminate\\Process\\Exceptions\\ProcessTimedOutException;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse LogicException;\nuse RuntimeException;\nuse Symfony\\Component\\Process\\Exception\\ProcessTimedOutException as SymfonyTimeoutException;\nuse Symfony\\Component\\Process\\Process;\n\nclass PendingProcess\n{\n    use Conditionable;\n\n    /**\n     * The process factory instance.\n     *\n     * @var \\Illuminate\\Process\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The command to invoke the process.\n     *\n     * @var array<array-key, string>|string|null\n     */\n    public $command;\n\n    /**\n     * The working directory of the process.\n     *\n     * @var string|null\n     */\n    public $path;\n\n    /**\n     * The maximum number of seconds the process may run.\n     *\n     * @var int|null\n     */\n    public $timeout = 60;\n\n    /**\n     * The maximum number of seconds the process may go without returning output.\n     *\n     * @var int\n     */\n    public $idleTimeout;\n\n    /**\n     * The additional environment variables for the process.\n     *\n     * @var array\n     */\n    public $environment = [];\n\n    /**\n     * The standard input data that should be piped into the command.\n     *\n     * @var string|int|float|bool|resource|\\Traversable|null\n     */\n    public $input;\n\n    /**\n     * Indicates whether output should be disabled for the process.\n     *\n     * @var bool\n     */\n    public $quietly = false;\n\n    /**\n     * Indicates if TTY mode should be enabled.\n     *\n     * @var bool\n     */\n    public $tty = false;\n\n    /**\n     * The options that will be passed to \"proc_open\".\n     *\n     * @var array\n     */\n    public $options = [];\n\n    /**\n     * The registered fake handler callbacks.\n     *\n     * @var array\n     */\n    protected $fakeHandlers = [];\n\n    /**\n     * Create a new pending process instance.\n     *\n     * @param  \\Illuminate\\Process\\Factory  $factory\n     */\n    public function __construct(Factory $factory)\n    {\n        $this->factory = $factory;\n    }\n\n    /**\n     * Specify the command that will invoke the process.\n     *\n     * @param  array<array-key, string>|string  $command\n     * @return $this\n     */\n    public function command(array|string $command)\n    {\n        $this->command = $command;\n\n        return $this;\n    }\n\n    /**\n     * Specify the working directory of the process.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function path(string $path)\n    {\n        $this->path = $path;\n\n        return $this;\n    }\n\n    /**\n     * Specify the maximum number of seconds the process may run.\n     *\n     * @param  CarbonInterval|int  $timeout\n     * @return $this\n     */\n    public function timeout(CarbonInterval|int $timeout)\n    {\n        $this->timeout = $timeout instanceof CarbonInterval ? (int) $timeout->totalSeconds : $timeout;\n\n        return $this;\n    }\n\n    /**\n     * Specify the maximum number of seconds a process may go without returning output.\n     *\n     * @param  CarbonInterval|int  $timeout\n     * @return $this\n     */\n    public function idleTimeout(CarbonInterval|int $timeout)\n    {\n        $this->idleTimeout = $timeout instanceof CarbonInterval ? (int) $timeout->totalSeconds : $timeout;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the process may run forever without timing out.\n     *\n     * @return $this\n     */\n    public function forever()\n    {\n        $this->timeout = null;\n\n        return $this;\n    }\n\n    /**\n     * Set the additional environment variables for the process.\n     *\n     * @param  array  $environment\n     * @return $this\n     */\n    public function env(array $environment)\n    {\n        $this->environment = $environment;\n\n        return $this;\n    }\n\n    /**\n     * Set the standard input that should be provided when invoking the process.\n     *\n     * @param  \\Traversable|resource|string|int|float|bool|null  $input\n     * @return $this\n     */\n    public function input($input)\n    {\n        $this->input = $input;\n\n        return $this;\n    }\n\n    /**\n     * Disable output for the process.\n     *\n     * @return $this\n     */\n    public function quietly()\n    {\n        $this->quietly = true;\n\n        return $this;\n    }\n\n    /**\n     * Enable TTY mode for the process.\n     *\n     * @param  bool  $tty\n     * @return $this\n     */\n    public function tty(bool $tty = true)\n    {\n        $this->tty = $tty;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"proc_open\" options that should be used when invoking the process.\n     *\n     * @param  array  $options\n     * @return $this\n     */\n    public function options(array $options)\n    {\n        $this->options = $options;\n\n        return $this;\n    }\n\n    /**\n     * Run the process.\n     *\n     * @param  array<array-key, string>|string|null  $command\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessTimedOutException\n     * @throws \\RuntimeException\n     */\n    public function run(array|string|null $command = null, ?callable $output = null)\n    {\n        $this->command = $command ?: $this->command;\n\n        $process = $this->toSymfonyProcess($command);\n\n        try {\n            if ($fake = $this->fakeFor($command = $process->getCommandline())) {\n                return tap($this->resolveSynchronousFake($command, $fake), function ($result) {\n                    $this->factory->recordIfRecording($this, $result);\n                });\n            } elseif ($this->factory->isRecording() && $this->factory->preventingStrayProcesses()) {\n                throw new RuntimeException('Attempted process ['.$command.'] without a matching fake.');\n            }\n\n            return new ProcessResult(tap($process)->run($output));\n        } catch (SymfonyTimeoutException $e) {\n            throw new ProcessTimedOutException($e, new ProcessResult($process));\n        }\n    }\n\n    /**\n     * Start the process in the background.\n     *\n     * @param  array<array-key, string>|string|null  $command\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\InvokedProcess\n     *\n     * @throws \\RuntimeException\n     */\n    public function start(array|string|null $command = null, ?callable $output = null)\n    {\n        $this->command = $command ?: $this->command;\n\n        $process = $this->toSymfonyProcess($command);\n\n        if ($fake = $this->fakeFor($command = $process->getCommandline())) {\n            return tap($this->resolveAsynchronousFake($command, $output, $fake), function (FakeInvokedProcess $process) {\n                $this->factory->recordIfRecording($this, $process->predictProcessResult());\n            });\n        } elseif ($this->factory->isRecording() && $this->factory->preventingStrayProcesses()) {\n            throw new RuntimeException('Attempted process ['.$command.'] without a matching fake.');\n        }\n\n        return new InvokedProcess(tap($process)->start($output));\n    }\n\n    /**\n     * Get a Symfony Process instance from the current pending command.\n     *\n     * @param  array<array-key, string>|string|null  $command\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    protected function toSymfonyProcess(array|string|null $command)\n    {\n        $command = $command ?? $this->command;\n\n        $process = is_iterable($command)\n            ? new Process($command, null, $this->environment)\n            : Process::fromShellCommandline((string) $command, null, $this->environment);\n\n        $process->setWorkingDirectory((string) ($this->path ?? getcwd()));\n        $process->setTimeout($this->timeout);\n\n        if ($this->idleTimeout) {\n            $process->setIdleTimeout($this->idleTimeout);\n        }\n\n        if ($this->input) {\n            $process->setInput($this->input);\n        }\n\n        if ($this->quietly) {\n            $process->disableOutput();\n        }\n\n        if ($this->tty) {\n            $process->setTty(true);\n        }\n\n        if (! empty($this->options)) {\n            $process->setOptions($this->options);\n        }\n\n        return $process;\n    }\n\n    /**\n     * Determine whether TTY is supported on the current operating system.\n     *\n     * @return bool\n     */\n    public function supportsTty()\n    {\n        return Process::isTtySupported();\n    }\n\n    /**\n     * Specify the fake process result handlers for the pending process.\n     *\n     * @param  array  $fakeHandlers\n     * @return $this\n     */\n    public function withFakeHandlers(array $fakeHandlers)\n    {\n        $this->fakeHandlers = $fakeHandlers;\n\n        return $this;\n    }\n\n    /**\n     * Get the fake handler for the given command, if applicable.\n     *\n     * @param  string  $command\n     * @return \\Closure|null\n     */\n    protected function fakeFor(string $command)\n    {\n        return (new Collection($this->fakeHandlers))\n            ->first(fn ($handler, $pattern) => $pattern === '*' || Str::is($pattern, $command));\n    }\n\n    /**\n     * Resolve the given fake handler for a synchronous process.\n     *\n     * @param  string  $command\n     * @param  \\Closure  $fake\n     * @return mixed\n     *\n     * @throws \\LogicException\n     * @throws \\Throwable\n     */\n    protected function resolveSynchronousFake(string $command, Closure $fake)\n    {\n        $result = $fake($this);\n\n        if (is_int($result)) {\n            return (new FakeProcessResult(exitCode: $result))->withCommand($command);\n        }\n\n        if (is_string($result) || is_array($result)) {\n            return (new FakeProcessResult(output: $result))->withCommand($command);\n        }\n\n        return match (true) {\n            $result instanceof ProcessResult => $result,\n            $result instanceof FakeProcessResult => $result->withCommand($command),\n            $result instanceof FakeProcessDescription => $result->toProcessResult($command),\n            $result instanceof FakeProcessSequence => $this->resolveSynchronousFake($command, fn () => $result()),\n            $result instanceof \\Throwable => throw $result,\n            default => throw new LogicException('Unsupported synchronous process fake result provided.'),\n        };\n    }\n\n    /**\n     * Resolve the given fake handler for an asynchronous process.\n     *\n     * @param  string  $command\n     * @param  callable|null  $output\n     * @param  \\Closure  $fake\n     * @return \\Illuminate\\Process\\FakeInvokedProcess\n     *\n     * @throws \\LogicException\n     */\n    protected function resolveAsynchronousFake(string $command, ?callable $output, Closure $fake)\n    {\n        $result = $fake($this);\n\n        if (is_string($result) || is_array($result)) {\n            $result = new FakeProcessResult(output: $result);\n        }\n\n        if ($result instanceof ProcessResult) {\n            return (new FakeInvokedProcess(\n                $command,\n                (new FakeProcessDescription)\n                    ->replaceOutput($result->output())\n                    ->replaceErrorOutput($result->errorOutput())\n                    ->runsFor(iterations: 0)\n                    ->exitCode($result->exitCode())\n            ))->withOutputHandler($output);\n        } elseif ($result instanceof FakeProcessResult) {\n            return (new FakeInvokedProcess(\n                $command,\n                (new FakeProcessDescription)\n                    ->replaceOutput($result->output())\n                    ->replaceErrorOutput($result->errorOutput())\n                    ->runsFor(iterations: 0)\n                    ->exitCode($result->exitCode())\n            ))->withOutputHandler($output);\n        } elseif ($result instanceof FakeProcessDescription) {\n            return (new FakeInvokedProcess($command, $result))->withOutputHandler($output);\n        } elseif ($result instanceof FakeProcessSequence) {\n            return $this->resolveAsynchronousFake($command, $output, fn () => $result());\n        }\n\n        throw new LogicException('Unsupported asynchronous process fake result provided.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/Pipe.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\n\n/**\n * @mixin \\Illuminate\\Process\\Factory\n * @mixin \\Illuminate\\Process\\PendingProcess\n */\nclass Pipe\n{\n    /**\n     * The process factory instance.\n     *\n     * @var \\Illuminate\\Process\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The callback that resolves the pending processes.\n     *\n     * @var callable\n     */\n    protected $callback;\n\n    /**\n     * The array of pending processes.\n     *\n     * @var array\n     */\n    protected $pendingProcesses = [];\n\n    /**\n     * Create a new series of piped processes.\n     *\n     * @param  \\Illuminate\\Process\\Factory  $factory\n     * @param  callable  $callback\n     */\n    public function __construct(Factory $factory, callable $callback)\n    {\n        $this->factory = $factory;\n        $this->callback = $callback;\n    }\n\n    /**\n     * Add a process to the pipe with a key.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Process\\PendingProcess\n     */\n    public function as(string $key)\n    {\n        return tap($this->factory->newPendingProcess(), function ($pendingProcess) use ($key) {\n            $this->pendingProcesses[$key] = $pendingProcess;\n        });\n    }\n\n    /**\n     * Runs the processes in the pipe.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Contracts\\Process\\ProcessResult\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function run(?callable $output = null)\n    {\n        call_user_func($this->callback, $this);\n\n        return (new Collection($this->pendingProcesses))\n            ->reduce(function ($previousProcessResult, $pendingProcess, $key) use ($output) {\n                if (! $pendingProcess instanceof PendingProcess) {\n                    throw new InvalidArgumentException('Process pipe must only contain pending processes.');\n                }\n\n                if ($previousProcessResult && $previousProcessResult->failed()) {\n                    return $previousProcessResult;\n                }\n\n                return $pendingProcess->when(\n                    $previousProcessResult,\n                    fn () => $pendingProcess->input($previousProcessResult->output())\n                )->run(output: $output ? function ($type, $buffer) use ($key, $output) {\n                    $output($type, $buffer, $key);\n                } : null);\n            });\n    }\n\n    /**\n     * Dynamically proxy methods calls to a new pending process.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\Process\\PendingProcess\n     */\n    public function __call($method, $parameters)\n    {\n        return tap($this->factory->{$method}(...$parameters), function ($pendingProcess) {\n            $this->pendingProcesses[] = $pendingProcess;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/Pool.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\n\n/**\n * @mixin \\Illuminate\\Process\\Factory\n * @mixin \\Illuminate\\Process\\PendingProcess\n */\nclass Pool\n{\n    /**\n     * The process factory instance.\n     *\n     * @var \\Illuminate\\Process\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The callback that resolves the pending processes.\n     *\n     * @var callable\n     */\n    protected $callback;\n\n    /**\n     * The array of pending processes.\n     *\n     * @var array\n     */\n    protected $pendingProcesses = [];\n\n    /**\n     * Create a new process pool.\n     *\n     * @param  \\Illuminate\\Process\\Factory  $factory\n     * @param  callable  $callback\n     */\n    public function __construct(Factory $factory, callable $callback)\n    {\n        $this->factory = $factory;\n        $this->callback = $callback;\n    }\n\n    /**\n     * Add a process to the pool with a key.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Process\\PendingProcess\n     */\n    public function as(string $key)\n    {\n        return tap($this->factory->newPendingProcess(), function ($pendingProcess) use ($key) {\n            $this->pendingProcesses[$key] = $pendingProcess;\n        });\n    }\n\n    /**\n     * Start all of the processes in the pool.\n     *\n     * @param  callable|null  $output\n     * @return \\Illuminate\\Process\\InvokedProcessPool\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function start(?callable $output = null)\n    {\n        call_user_func($this->callback, $this);\n\n        return new InvokedProcessPool(\n            (new Collection($this->pendingProcesses))\n                ->each(function ($pendingProcess) {\n                    if (! $pendingProcess instanceof PendingProcess) {\n                        throw new InvalidArgumentException('Process pool must only contain pending processes.');\n                    }\n                })\n                ->mapWithKeys(function ($pendingProcess, $key) use ($output) {\n                    return [$key => $pendingProcess->start(output: $output ? function ($type, $buffer) use ($key, $output) {\n                        $output($type, $buffer, $key);\n                    } : null)];\n                })\n                ->all()\n        );\n    }\n\n    /**\n     * Start and wait for the processes to finish.\n     *\n     * @return \\Illuminate\\Process\\ProcessPoolResults\n     */\n    public function run()\n    {\n        return $this->wait();\n    }\n\n    /**\n     * Start and wait for the processes to finish.\n     *\n     * @return \\Illuminate\\Process\\ProcessPoolResults\n     */\n    public function wait()\n    {\n        return $this->start()->wait();\n    }\n\n    /**\n     * Dynamically proxy methods calls to a new pending process.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\Process\\PendingProcess\n     */\n    public function __call($method, $parameters)\n    {\n        return tap($this->factory->{$method}(...$parameters), function ($pendingProcess) {\n            $this->pendingProcesses[] = $pendingProcess;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/ProcessPoolResults.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse ArrayAccess;\nuse Illuminate\\Support\\Collection;\n\nclass ProcessPoolResults implements ArrayAccess\n{\n    /**\n     * The results of the processes.\n     *\n     * @var array\n     */\n    protected $results = [];\n\n    /**\n     * Create a new process pool result set.\n     *\n     * @param  array  $results\n     */\n    public function __construct(array $results)\n    {\n        $this->results = $results;\n    }\n\n    /**\n     * Determine if all of the processes in the pool were successful.\n     *\n     * @return bool\n     */\n    public function successful()\n    {\n        return $this->collect()->every(fn ($p) => $p->successful());\n    }\n\n    /**\n     * Determine if any of the processes in the pool failed.\n     *\n     * @return bool\n     */\n    public function failed()\n    {\n        return ! $this->successful();\n    }\n\n    /**\n     * Get the results as a collection.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function collect()\n    {\n        return new Collection($this->results);\n    }\n\n    /**\n     * Determine if the given array offset exists.\n     *\n     * @param  int  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->results[$offset]);\n    }\n\n    /**\n     * Get the result at the given offset.\n     *\n     * @param  int  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->results[$offset];\n    }\n\n    /**\n     * Set the result at the given offset.\n     *\n     * @param  int  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->results[$offset] = $value;\n    }\n\n    /**\n     * Unset the result at the given offset.\n     *\n     * @param  int  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->results[$offset]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/ProcessResult.php",
    "content": "<?php\n\nnamespace Illuminate\\Process;\n\nuse Illuminate\\Contracts\\Process\\ProcessResult as ProcessResultContract;\nuse Illuminate\\Process\\Exceptions\\ProcessFailedException;\nuse Symfony\\Component\\Process\\Process;\n\nclass ProcessResult implements ProcessResultContract\n{\n    /**\n     * The underlying process instance.\n     *\n     * @var \\Symfony\\Component\\Process\\Process\n     */\n    protected $process;\n\n    /**\n     * Create a new process result instance.\n     *\n     * @param  \\Symfony\\Component\\Process\\Process  $process\n     */\n    public function __construct(Process $process)\n    {\n        $this->process = $process;\n    }\n\n    /**\n     * Get the original command executed by the process.\n     *\n     * @return string\n     */\n    public function command()\n    {\n        return $this->process->getCommandLine();\n    }\n\n    /**\n     * Determine if the process was successful.\n     *\n     * @return bool\n     */\n    public function successful()\n    {\n        return $this->process->isSuccessful();\n    }\n\n    /**\n     * Determine if the process failed.\n     *\n     * @return bool\n     */\n    public function failed()\n    {\n        return ! $this->successful();\n    }\n\n    /**\n     * Get the exit code of the process.\n     *\n     * @return int|null\n     */\n    public function exitCode()\n    {\n        return $this->process->getExitCode();\n    }\n\n    /**\n     * Get the standard output of the process.\n     *\n     * @return string\n     */\n    public function output()\n    {\n        return $this->process->getOutput();\n    }\n\n    /**\n     * Determine if the output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInOutput(string $output)\n    {\n        return str_contains($this->output(), $output);\n    }\n\n    /**\n     * Get the error output of the process.\n     *\n     * @return string\n     */\n    public function errorOutput()\n    {\n        return $this->process->getErrorOutput();\n    }\n\n    /**\n     * Determine if the error output contains the given string.\n     *\n     * @param  string  $output\n     * @return bool\n     */\n    public function seeInErrorOutput(string $output)\n    {\n        return str_contains($this->errorOutput(), $output);\n    }\n\n    /**\n     * Throw an exception if the process failed.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     *\n     * @throws \\Illuminate\\Process\\Exceptions\\ProcessFailedException\n     */\n    public function throw(?callable $callback = null)\n    {\n        if ($this->successful()) {\n            return $this;\n        }\n\n        $exception = new ProcessFailedException($this);\n\n        if ($callback) {\n            $callback($this, $exception);\n        }\n\n        throw $exception;\n    }\n\n    /**\n     * Throw an exception if the process failed and the given condition is true.\n     *\n     * @param  bool  $condition\n     * @param  callable|null  $callback\n     * @return $this\n     *\n     * @throws \\Throwable\n     */\n    public function throwIf(bool $condition, ?callable $callback = null)\n    {\n        if ($condition) {\n            return $this->throw($callback);\n        }\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Process/composer.json",
    "content": "{\n    \"name\": \"illuminate/process\",\n    \"description\": \"The Illuminate Process package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/process\": \"^7.4.5 || ^8.0.5\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Process\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Queue/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/Backoff.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Backoff\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  array<int>|int  $backoff\n     */\n    public function __construct(public array|int $backoff)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/Connection.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\nuse BackedEnum;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Connection\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $connection\n     */\n    public function __construct(public BackedEnum|string $connection)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/DeleteWhenMissingModels.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass DeleteWhenMissingModels\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/FailOnTimeout.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass FailOnTimeout\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/MaxExceptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass MaxExceptions\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  int  $maxExceptions\n     */\n    public function __construct(public int $maxExceptions)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/Queue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\nuse BackedEnum;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Queue\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  string  $queue\n     */\n    public function __construct(public BackedEnum|string $queue)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/ReadsQueueAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Illuminate\\Support\\Traits\\ReadsClassAttributes;\n\ntrait ReadsQueueAttributes\n{\n    use ReadsClassAttributes;\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/Timeout.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Timeout\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  int  $timeout\n     */\n    public function __construct(public int $timeout)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/Tries.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass Tries\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  int  $tries\n     */\n    public function __construct(public int $tries)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/UniqueFor.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS)]\nclass UniqueFor\n{\n    /**\n     * Create a new attribute instance.\n     *\n     * @param  int  $uniqueFor\n     */\n    public function __construct(public int $uniqueFor)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Attributes/WithoutRelations.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Attributes;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]\nclass WithoutRelations\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/BackgroundQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Support\\Facades\\Concurrency;\n\nclass BackgroundQueue extends SyncQueue\n{\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        Concurrency::driver('process')->defer(\n            fn () => \\Illuminate\\Support\\Facades\\Queue::connection('sync')->push($job, $data, $queue)\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/BeanstalkdQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Queue\\Jobs\\BeanstalkdJob;\nuse Pheanstalk\\Contract\\JobIdInterface;\nuse Pheanstalk\\Pheanstalk;\nuse Pheanstalk\\Values\\Job;\nuse Pheanstalk\\Values\\JobId;\nuse Pheanstalk\\Values\\TubeName;\n\nclass BeanstalkdQueue extends Queue implements QueueContract\n{\n    /**\n     * The Pheanstalk instance.\n     *\n     * @var \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface\n     */\n    protected $pheanstalk;\n\n    /**\n     * The name of the default tube.\n     *\n     * @var string\n     */\n    protected $default;\n\n    /**\n     * The \"time to run\" for all pushed jobs.\n     *\n     * @var int\n     */\n    protected $timeToRun;\n\n    /**\n     * The maximum number of seconds to block for a job.\n     *\n     * @var int\n     */\n    protected $blockFor;\n\n    /**\n     * Create a new Beanstalkd queue instance.\n     *\n     * @param  \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface  $pheanstalk\n     * @param  string  $default\n     * @param  int  $timeToRun\n     * @param  int  $blockFor\n     * @param  bool  $dispatchAfterCommit\n     */\n    public function __construct(\n        $pheanstalk,\n        $default,\n        $timeToRun,\n        $blockFor = 0,\n        $dispatchAfterCommit = false,\n    ) {\n        $this->default = $default;\n        $this->blockFor = $blockFor;\n        $this->timeToRun = $timeToRun;\n        $this->pheanstalk = $pheanstalk;\n        $this->dispatchAfterCommit = $dispatchAfterCommit;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        $stats = $this->pheanstalk->statsTube(new TubeName($this->getQueue($queue)));\n\n        return $stats->currentJobsReady\n            + $stats->currentJobsDelayed\n            + $stats->currentJobsReserved;\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return $this->pheanstalk->statsTube(new TubeName($this->getQueue($queue)))->currentJobsReady;\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return $this->pheanstalk->statsTube(new TubeName($this->getQueue($queue)))->currentJobsDelayed;\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return $this->pheanstalk->statsTube(new TubeName($this->getQueue($queue)))->currentJobsReserved;\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        // Not supported by Beanstalkd...\n        return null;\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data),\n            $queue,\n            null,\n            function ($payload, $queue) {\n                return $this->pushRaw($payload, $queue);\n            }\n        );\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        $this->pheanstalk->useTube(new TubeName($this->getQueue($queue)));\n\n        return $this->pheanstalk->put(\n            $payload, Pheanstalk::DEFAULT_PRIORITY, Pheanstalk::DEFAULT_DELAY, $this->timeToRun\n        );\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data, $delay),\n            $queue,\n            $delay,\n            function ($payload, $queue, $delay) {\n                $this->pheanstalk->useTube(new TubeName($this->getQueue($queue)));\n\n                return $this->pheanstalk->put(\n                    $payload,\n                    Pheanstalk::DEFAULT_PRIORITY,\n                    $this->secondsUntil($delay),\n                    $this->timeToRun\n                );\n            }\n        );\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return void\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        foreach ((array) $jobs as $job) {\n            if (isset($job->delay)) {\n                $this->later($job->delay, $job, $data, $queue);\n            } else {\n                $this->push($job, $data, $queue);\n            }\n        }\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        $this->pheanstalk->watch(\n            $tube = new TubeName($queue = $this->getQueue($queue))\n        );\n\n        foreach ($this->pheanstalk->listTubesWatched() as $watched) {\n            if ($watched->value !== $tube->value) {\n                $this->pheanstalk->ignore($watched);\n            }\n        }\n\n        $job = $this->pheanstalk->reserveWithTimeout($this->blockFor);\n\n        if ($job instanceof JobIdInterface) {\n            return new BeanstalkdJob(\n                $this->container, $this->pheanstalk, $job, $this->connectionName, $queue\n            );\n        }\n    }\n\n    /**\n     * Delete a message from the Beanstalk queue.\n     *\n     * @param  string  $queue\n     * @param  string|int  $id\n     * @return void\n     */\n    public function deleteMessage($queue, $id)\n    {\n        $this->pheanstalk->useTube(new TubeName($this->getQueue($queue)));\n\n        $this->pheanstalk->delete(new Job(new JobId($id), ''));\n    }\n\n    /**\n     * Get the queue or return the default.\n     *\n     * @param  string|null  $queue\n     * @return string\n     */\n    public function getQueue($queue)\n    {\n        return $queue ?: $this->default;\n    }\n\n    /**\n     * Get the underlying Pheanstalk instance.\n     *\n     * @return \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface\n     */\n    public function getPheanstalk()\n    {\n        return $this->pheanstalk;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/CallQueuedClosure.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Closure;\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse ReflectionFunction;\n\nclass CallQueuedClosure implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;\n\n    /**\n     * The serializable Closure instance.\n     *\n     * @var \\Laravel\\SerializableClosure\\SerializableClosure\n     */\n    public $closure;\n\n    /**\n     * The name assigned to the job.\n     *\n     * @var string|null\n     */\n    public $name = null;\n\n    /**\n     * The callbacks that should be executed on failure.\n     *\n     * @var array\n     */\n    public $failureCallbacks = [];\n\n    /**\n     * Indicate if the job should be deleted when models are missing.\n     *\n     * @var bool\n     */\n    public $deleteWhenMissingModels = true;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Laravel\\SerializableClosure\\SerializableClosure  $closure\n     */\n    public function __construct($closure)\n    {\n        $this->closure = $closure;\n    }\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Closure  $job\n     * @return self\n     */\n    public static function create(Closure $job)\n    {\n        return new self(new SerializableClosure($job));\n    }\n\n    /**\n     * Execute the job.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function handle(Container $container)\n    {\n        $container->call($this->closure->getClosure(), ['job' => $this]);\n    }\n\n    /**\n     * Add a callback to be executed if the job fails.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function onFailure($callback)\n    {\n        $this->failureCallbacks[] = $callback instanceof Closure\n            ? new SerializableClosure($callback)\n            : $callback;\n\n        return $this;\n    }\n\n    /**\n     * Handle a job failure.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function failed($e)\n    {\n        foreach ($this->failureCallbacks as $callback) {\n            $callback($e);\n        }\n    }\n\n    /**\n     * Get the display name for the queued job.\n     *\n     * @return string\n     */\n    public function displayName()\n    {\n        $closure = $this->closure instanceof SerializableClosure\n                    ? $this->closure->getClosure()\n                    : $this->closure;\n\n        $reflection = new ReflectionFunction($closure);\n\n        $prefix = is_null($this->name) ? '' : \"{$this->name} - \";\n\n        return $prefix.'Closure ('.basename($reflection->getFileName()).':'.$reflection->getStartLine().')';\n    }\n\n    /**\n     * Assign a name to the job.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function name($name)\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/CallQueuedHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Exception;\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Cache\\Factory as CacheFactory;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Events\\CallQueuedListener;\nuse Illuminate\\Log\\Context\\Repository as ContextRepository;\nuse Illuminate\\Pipeline\\Pipeline;\nuse RuntimeException;\n\nclass CallQueuedHandler\n{\n    /**\n     * The bus dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Bus\\Dispatcher\n     */\n    protected $dispatcher;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Create a new handler instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Bus\\Dispatcher  $dispatcher\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     */\n    public function __construct(Dispatcher $dispatcher, Container $container)\n    {\n        $this->container = $container;\n        $this->dispatcher = $dispatcher;\n    }\n\n    /**\n     * Handle the queued job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  array  $data\n     * @return void\n     */\n    public function call(Job $job, array $data)\n    {\n        try {\n            $command = $this->setJobInstanceIfNecessary(\n                $job, $this->getCommand($data)\n            );\n        } catch (ModelNotFoundException $e) {\n            return $this->handleModelNotFound($job, $e);\n        }\n\n        $this->dispatchThroughMiddleware($job, $command);\n\n        if (! $job->isReleased() && ! $this->commandShouldBeUniqueUntilProcessing($command)) {\n            $this->ensureUniqueJobLockIsReleased($command);\n        }\n\n        if (! $job->hasFailed() && ! $job->isReleased()) {\n            $this->ensureNextJobInChainIsDispatched($command);\n            $this->ensureSuccessfulBatchJobIsRecorded($command);\n        }\n\n        if (! $job->isDeletedOrReleased()) {\n            $job->delete();\n        }\n    }\n\n    /**\n     * Get the command from the given payload.\n     *\n     * @param  array  $data\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getCommand(array $data)\n    {\n        if (str_starts_with($data['command'], 'O:')) {\n            return unserialize($data['command']);\n        }\n\n        if ($this->container->bound(Encrypter::class)) {\n            return unserialize($this->container[Encrypter::class]->decrypt($data['command']));\n        }\n\n        throw new RuntimeException('Unable to extract job payload.');\n    }\n\n    /**\n     * Dispatch the given job / command through its specified middleware.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  mixed  $command\n     * @return mixed\n     */\n    protected function dispatchThroughMiddleware(Job $job, $command)\n    {\n        if ($command instanceof \\__PHP_Incomplete_Class) {\n            throw new Exception('Job is incomplete class: '.json_encode($command));\n        }\n\n        $lockReleased = false;\n\n        return (new Pipeline($this->container))->send($command)\n            ->through(array_merge(method_exists($command, 'middleware') ? $command->middleware() : [], $command->middleware ?? []))\n            ->finally(function ($command) use (&$lockReleased) {\n                if (! $lockReleased && $this->commandShouldBeUniqueUntilProcessing($command) && ! $command->job->isReleased()) {\n                    $this->ensureUniqueJobLockIsReleased($command);\n                }\n            })\n            ->then(function ($command) use ($job, &$lockReleased) {\n                if ($this->commandShouldBeUniqueUntilProcessing($command)) {\n                    $this->ensureUniqueJobLockIsReleased($command);\n\n                    $lockReleased = true;\n                }\n\n                return $this->dispatcher->dispatchNow(\n                    $command, $this->resolveHandler($job, $command)\n                );\n            });\n    }\n\n    /**\n     * Resolve the handler for the given command.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  mixed  $command\n     * @return mixed\n     */\n    protected function resolveHandler($job, $command)\n    {\n        $handler = $this->dispatcher->getCommandHandler($command) ?: null;\n\n        if ($handler) {\n            $this->setJobInstanceIfNecessary($job, $handler);\n        }\n\n        return $handler;\n    }\n\n    /**\n     * Set the job instance of the given class if necessary.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  mixed  $instance\n     * @return mixed\n     */\n    protected function setJobInstanceIfNecessary(Job $job, $instance)\n    {\n        if (in_array(InteractsWithQueue::class, class_uses_recursive($instance))) {\n            $instance->setJob($job);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Ensure the next job in the chain is dispatched if applicable.\n     *\n     * @param  mixed  $command\n     * @return void\n     */\n    protected function ensureNextJobInChainIsDispatched($command)\n    {\n        if (method_exists($command, 'dispatchNextJobInChain')) {\n            $command->dispatchNextJobInChain();\n        }\n    }\n\n    /**\n     * Ensure the batch is notified of the successful job completion.\n     *\n     * @param  mixed  $command\n     * @return void\n     */\n    protected function ensureSuccessfulBatchJobIsRecorded($command)\n    {\n        $uses = class_uses_recursive($command);\n\n        if (! in_array(Batchable::class, $uses) ||\n            ! in_array(InteractsWithQueue::class, $uses)) {\n            return;\n        }\n\n        if ($batch = $command->batch()) {\n            $batch->recordSuccessfulJob($command->job->uuid());\n        }\n    }\n\n    /**\n     * Ensure the lock for a unique job is released.\n     *\n     * @param  mixed  $command\n     * @return void\n     */\n    protected function ensureUniqueJobLockIsReleased($command)\n    {\n        if ($this->commandShouldBeUnique($command)) {\n            (new UniqueLock($this->container->make(Cache::class)))->release($command);\n        }\n    }\n\n    /**\n     * Determine if the given command should be unique.\n     */\n    protected function commandShouldBeUnique(mixed $command): bool\n    {\n        return $command instanceof ShouldBeUnique ||\n            ($command instanceof CallQueuedListener && $command->shouldBeUnique());\n    }\n\n    /**\n     * Determine if the given command should be unique until processing begins.\n     */\n    protected function commandShouldBeUniqueUntilProcessing(mixed $command): bool\n    {\n        return $command instanceof ShouldBeUniqueUntilProcessing ||\n            ($command instanceof CallQueuedListener && $command->shouldBeUniqueUntilProcessing());\n    }\n\n    /**\n     * Handle a model not found exception.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function handleModelNotFound(Job $job, $e)\n    {\n        $this->ensureUniqueJobLockIsReleasedViaContext();\n\n        if ($job->payload()['deleteWhenMissingModels'] ?? false) {\n            $this->ensureSuccessfulBatchJobIsRecordedForMissingModel($job, $job->resolveQueuedJobClass());\n\n            return $job->delete();\n        }\n\n        return $job->fail($e);\n    }\n\n    /**\n     * Ensure the lock for a unique job is released via context.\n     *\n     * This is required when we can't unserialize the job due to missing models.\n     *\n     * @return void\n     */\n    protected function ensureUniqueJobLockIsReleasedViaContext()\n    {\n        if (! $this->container->bound(ContextRepository::class) ||\n            ! $this->container->bound(CacheFactory::class)) {\n            return;\n        }\n\n        $context = $this->container->make(ContextRepository::class);\n\n        [$store, $key] = [\n            $context->getHidden('laravel_unique_job_cache_store'),\n            $context->getHidden('laravel_unique_job_key'),\n        ];\n\n        if ($store && $key) {\n            $this->container->make(CacheFactory::class)\n                ->store($store)\n                ->lock($key)\n                ->forceRelease();\n        }\n    }\n\n    /**\n     * Record a potentially batched job as successful when deleted because models were missing.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  string  $class\n     * @return void\n     */\n    protected function ensureSuccessfulBatchJobIsRecordedForMissingModel(Job $job, string $class)\n    {\n        if (! in_array(Batchable::class, class_uses_recursive($class), true)) {\n            return;\n        }\n\n        if (! $this->container->bound(BatchRepository::class)) {\n            return;\n        }\n\n        $batchId = $job->payload()['data']['batchId'] ?? null;\n\n        if ((! is_string($batchId) || $batchId === '') ||\n             ! is_string($job->uuid()) || $job->uuid() === '') {\n            return;\n        }\n\n        if ($batch = $this->container->make(BatchRepository::class)->find($batchId)) {\n            $batch->recordSuccessfulJob($job->uuid());\n        }\n    }\n\n    /**\n     * Call the failed method on the job instance.\n     *\n     * The exception that caused the failure will be passed.\n     *\n     * @param  array  $data\n     * @param  \\Throwable|null  $e\n     * @param  string  $uuid\n     * @param  \\Illuminate\\Contracts\\Queue\\Job|null  $job\n     * @return void\n     */\n    public function failed(array $data, $e, string $uuid, ?Job $job = null)\n    {\n        $command = $this->getCommand($data);\n\n        if (! is_null($job)) {\n            $command = $this->setJobInstanceIfNecessary($job, $command);\n        }\n\n        if (! $this->commandShouldBeUniqueUntilProcessing($command)) {\n            $this->ensureUniqueJobLockIsReleased($command);\n        }\n\n        if ($command instanceof \\__PHP_Incomplete_Class) {\n            return;\n        }\n\n        $this->ensureFailedBatchJobIsRecorded($uuid, $command, $e);\n        $this->ensureChainCatchCallbacksAreInvoked($uuid, $command, $e);\n\n        if (method_exists($command, 'failed')) {\n            $command->failed($e);\n        }\n    }\n\n    /**\n     * Ensure the batch is notified of the failed job.\n     *\n     * @param  string  $uuid\n     * @param  mixed  $command\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function ensureFailedBatchJobIsRecorded(string $uuid, $command, $e)\n    {\n        if (! in_array(Batchable::class, class_uses_recursive($command))) {\n            return;\n        }\n\n        if ($batch = $command->batch()) {\n            $batch->recordFailedJob($uuid, $e);\n        }\n    }\n\n    /**\n     * Ensure the chained job catch callbacks are invoked.\n     *\n     * @param  string  $uuid\n     * @param  mixed  $command\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function ensureChainCatchCallbacksAreInvoked(string $uuid, $command, $e)\n    {\n        if (method_exists($command, 'invokeChainCatchCallbacks')) {\n            $command->invokeChainCatchCallbacks($e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Capsule/Manager.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Capsule;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Queue\\QueueManager;\nuse Illuminate\\Queue\\QueueServiceProvider;\nuse Illuminate\\Support\\Traits\\CapsuleManagerTrait;\n\n/**\n * @mixin \\Illuminate\\Queue\\QueueManager\n * @mixin \\Illuminate\\Contracts\\Queue\\Queue\n */\nclass Manager\n{\n    use CapsuleManagerTrait;\n\n    /**\n     * The queue manager instance.\n     *\n     * @var \\Illuminate\\Queue\\QueueManager\n     */\n    protected $manager;\n\n    /**\n     * Create a new queue capsule manager.\n     *\n     * @param  \\Illuminate\\Container\\Container|null  $container\n     */\n    public function __construct(?Container $container = null)\n    {\n        $this->setupContainer($container ?: new Container);\n\n        // Once we have the container setup, we will set up the default configuration\n        // options in the container \"config\" bindings. This'll just make the queue\n        // manager behave correctly since all the correct bindings are in place.\n        $this->setupDefaultConfiguration();\n\n        $this->setupManager();\n\n        $this->registerConnectors();\n    }\n\n    /**\n     * Setup the default queue configuration options.\n     *\n     * @return void\n     */\n    protected function setupDefaultConfiguration()\n    {\n        $this->container['config']['queue.default'] = 'default';\n    }\n\n    /**\n     * Build the queue manager instance.\n     *\n     * @return void\n     */\n    protected function setupManager()\n    {\n        $this->manager = new QueueManager($this->container);\n    }\n\n    /**\n     * Register the default connectors that the component ships with.\n     *\n     * @return void\n     */\n    protected function registerConnectors()\n    {\n        $provider = new QueueServiceProvider($this->container);\n\n        $provider->registerConnectors($this->manager);\n    }\n\n    /**\n     * Get a connection instance from the global manager.\n     *\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public static function connection($connection = null)\n    {\n        return static::$instance->getConnection($connection);\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return mixed\n     */\n    public static function push($job, $data = '', $queue = null, $connection = null)\n    {\n        return static::$instance->connection($connection)->push($job, $data, $queue);\n    }\n\n    /**\n     * Push a new an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return mixed\n     */\n    public static function bulk($jobs, $data = '', $queue = null, $connection = null)\n    {\n        return static::$instance->connection($connection)->bulk($jobs, $data, $queue);\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return mixed\n     */\n    public static function later($delay, $job, $data = '', $queue = null, $connection = null)\n    {\n        return static::$instance->connection($connection)->later($delay, $job, $data, $queue);\n    }\n\n    /**\n     * Get a registered connection instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function getConnection($name = null)\n    {\n        return $this->manager->connection($name);\n    }\n\n    /**\n     * Register a connection with the manager.\n     *\n     * @param  array  $config\n     * @param  string  $name\n     * @return void\n     */\n    public function addConnection(array $config, $name = 'default')\n    {\n        $this->container['config'][\"queue.connections.{$name}\"] = $config;\n    }\n\n    /**\n     * Get the queue manager instance.\n     *\n     * @return \\Illuminate\\Queue\\QueueManager\n     */\n    public function getQueueManager()\n    {\n        return $this->manager;\n    }\n\n    /**\n     * Pass dynamic instance methods to the manager.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->manager->$method(...$parameters);\n    }\n\n    /**\n     * Dynamically pass methods to the default connection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public static function __callStatic($method, $parameters)\n    {\n        return static::connection()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/BackgroundConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Queue\\BackgroundQueue;\n\nclass BackgroundConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new BackgroundQueue($config['after_commit'] ?? null);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/BeanstalkdConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Queue\\BeanstalkdQueue;\nuse Pheanstalk\\Contract\\SocketFactoryInterface;\nuse Pheanstalk\\Pheanstalk;\nuse Pheanstalk\\Values\\Timeout;\n\nclass BeanstalkdConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new BeanstalkdQueue(\n            $this->pheanstalk($config),\n            $config['queue'],\n            $config['retry_after'] ?? Pheanstalk::DEFAULT_TTR,\n            $config['block_for'] ?? 0,\n            $config['after_commit'] ?? null\n        );\n    }\n\n    /**\n     * Create a Pheanstalk instance.\n     *\n     * @param  array  $config\n     * @return \\Pheanstalk\\Pheanstalk\n     */\n    protected function pheanstalk(array $config)\n    {\n        return Pheanstalk::create(\n            $config['host'],\n            $config['port'] ?? SocketFactoryInterface::DEFAULT_PORT,\n            isset($config['timeout']) ? new Timeout($config['timeout']) : null,\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/ConnectorInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\ninterface ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config);\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/DatabaseConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Queue\\DatabaseQueue;\n\nclass DatabaseConnector implements ConnectorInterface\n{\n    /**\n     * Database connections.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $connections;\n\n    /**\n     * Create a new connector instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $connections\n     */\n    public function __construct(ConnectionResolverInterface $connections)\n    {\n        $this->connections = $connections;\n    }\n\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new DatabaseQueue(\n            $this->connections->connection($config['connection'] ?? null),\n            $config['table'],\n            $config['queue'],\n            $config['retry_after'] ?? 60,\n            $config['after_commit'] ?? null\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/DeferredConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Queue\\DeferredQueue;\n\nclass DeferredConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new DeferredQueue($config['after_commit'] ?? null);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/FailoverConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Queue\\FailoverQueue;\nuse Illuminate\\Queue\\QueueManager;\n\nclass FailoverConnector implements ConnectorInterface\n{\n    /**\n     * Create a new connector instance.\n     */\n    public function __construct(\n        protected QueueManager $manager,\n        protected Dispatcher $events\n    ) {\n    }\n\n    /**\n     * Establish a queue connection.\n     *\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new FailoverQueue(\n            $this->manager,\n            $this->events,\n            $config['connections'],\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/NullConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Queue\\NullQueue;\n\nclass NullConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new NullQueue;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/RedisConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Queue\\RedisQueue;\n\nclass RedisConnector implements ConnectorInterface\n{\n    /**\n     * The Redis database instance.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    protected $redis;\n\n    /**\n     * The connection name.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * Create a new Redis queue connector instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Redis\\Factory  $redis\n     * @param  string|null  $connection\n     */\n    public function __construct(Redis $redis, $connection = null)\n    {\n        $this->redis = $redis;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new RedisQueue(\n            $this->redis, $config['queue'],\n            $config['connection'] ?? $this->connection,\n            $config['retry_after'] ?? 60,\n            $config['block_for'] ?? null,\n            $config['after_commit'] ?? null,\n            $config['migration_batch_size'] ?? -1\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/SqsConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Aws\\Sqs\\SqsClient;\nuse Illuminate\\Queue\\SqsQueue;\nuse Illuminate\\Support\\Arr;\n\nclass SqsConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        $config = $this->getDefaultConfiguration($config);\n\n        if (! empty($config['key']) && ! empty($config['secret'])) {\n            $config['credentials'] = Arr::only($config, ['key', 'secret']);\n\n            if (! empty($config['token'])) {\n                $config['credentials']['token'] = $config['token'];\n            }\n        }\n\n        return new SqsQueue(\n            new SqsClient(\n                Arr::except($config, ['token'])\n            ),\n            $config['queue'],\n            $config['prefix'] ?? '',\n            $config['suffix'] ?? '',\n            $config['after_commit'] ?? null\n        );\n    }\n\n    /**\n     * Get the default configuration for SQS.\n     *\n     * @param  array  $config\n     * @return array\n     */\n    protected function getDefaultConfiguration(array $config)\n    {\n        return array_merge([\n            'version' => 'latest',\n            'http' => [\n                'timeout' => 60,\n                'connect_timeout' => 60,\n            ],\n        ], $config);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Connectors/SyncConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Connectors;\n\nuse Illuminate\\Queue\\SyncQueue;\n\nclass SyncConnector implements ConnectorInterface\n{\n    /**\n     * Establish a queue connection.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connect(array $config)\n    {\n        return new SyncQueue($config['after_commit'] ?? null);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/BatchesTableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[AsCommand(name: 'make:queue-batches-table', aliases: ['queue:batches-table'])]\nclass BatchesTableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:queue-batches-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['queue:batches-table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the batches database table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return $this->laravel['config']['queue.batching.table'] ?? 'job_batches';\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/batches.stub';\n    }\n\n    /**\n     * Determine whether a migration for the table already exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function migrationExists($table)\n    {\n        if ($table !== 'job_batches') {\n            return parent::migrationExists($table);\n        }\n\n        foreach ([\n            join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php'),\n            join_paths($this->laravel->databasePath('migrations'), '0001_01_01_000002_create_jobs_table.php'),\n        ] as $path) {\n            if (count($this->files->glob($path)) !== 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/ClearCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ConfirmableTrait;\nuse Illuminate\\Contracts\\Queue\\ClearableQueue;\nuse Illuminate\\Support\\Str;\nuse ReflectionClass;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputOption;\n\n#[AsCommand(name: 'queue:clear')]\nclass ClearCommand extends Command\n{\n    use ConfirmableTrait;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'queue:clear';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Delete all of the jobs from the specified queue';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int|null\n     */\n    public function handle()\n    {\n        if (! $this->confirmToProceed()) {\n            return 1;\n        }\n\n        $connection = $this->argument('connection')\n            ?: $this->laravel['config']['queue.default'];\n\n        // We need to get the right queue for the connection which is set in the queue\n        // configuration file for the application. We will pull it based on the set\n        // connection being run for the queue operation currently being executed.\n        $queueName = $this->getQueue($connection);\n\n        $queue = $this->laravel['queue']->connection($connection);\n\n        if ($queue instanceof ClearableQueue) {\n            $count = $queue->clear($queueName);\n\n            $this->components->info('Cleared '.$count.' '.Str::plural('job', $count).' from the ['.$queueName.'] queue');\n        } else {\n            $this->components->error('Clearing queues is not supported on ['.(new ReflectionClass($queue))->getShortName().']');\n\n            return 1;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Get the queue name to clear.\n     *\n     * @param  string  $connection\n     * @return string\n     */\n    protected function getQueue($connection)\n    {\n        return $this->option('queue') ?: $this->laravel['config']->get(\n            \"queue.connections.{$connection}.queue\", 'default'\n        );\n    }\n\n    /**\n     *  Get the console command arguments.\n     *\n     * @return array\n     */\n    protected function getArguments()\n    {\n        return [\n            ['connection', InputArgument::OPTIONAL, 'The name of the queue connection to clear'],\n        ];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['queue', null, InputOption::VALUE_OPTIONAL, 'The name of the queue to clear'],\n\n            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/Concerns/ParsesQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console\\Concerns;\n\ntrait ParsesQueue\n{\n    /**\n     * Parse the queue argument into connection and queue name.\n     *\n     * @param  string  $queue\n     * @return array{string, string}\n     */\n    protected function parseQueue($queue)\n    {\n        [$connection, $queue] = array_pad(explode(':', $queue, 2), -2, null);\n\n        return [\n            $connection ?? $this->laravel['config']['queue.default'],\n            $queue ?: 'default',\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/FailedTableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[AsCommand(name: 'make:queue-failed-table', aliases: ['queue:failed-table'])]\nclass FailedTableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:queue-failed-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['queue:failed-table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the failed queue jobs database table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return $this->laravel['config']['queue.failed.table'];\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/failed_jobs.stub';\n    }\n\n    /**\n     * Determine whether a migration for the table already exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function migrationExists($table)\n    {\n        if ($table !== 'failed_jobs') {\n            return parent::migrationExists($table);\n        }\n\n        foreach ([\n            join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php'),\n            join_paths($this->laravel->databasePath('migrations'), '0001_01_01_000002_create_jobs_table.php'),\n        ] as $path) {\n            if (count($this->files->glob($path)) !== 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/FlushFailedCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:flush')]\nclass FlushFailedCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:flush {--hours= : The number of hours to retain failed job data}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Flush all of the failed queue jobs';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->laravel['queue.failer']->flush($this->option('hours'));\n\n        if ($this->option('hours')) {\n            $this->components->info(\"All jobs that failed more than {$this->option('hours')} hours ago have been deleted successfully.\");\n\n            return;\n        }\n\n        $this->components->info('All failed jobs deleted successfully.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/ForgetFailedCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:forget')]\nclass ForgetFailedCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:forget {id : The ID of the failed job}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Delete a failed queue job';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int|null\n     */\n    public function handle()\n    {\n        if ($this->laravel['queue.failer']->forget($this->argument('id'))) {\n            $this->components->info('Failed job deleted successfully.');\n        } else {\n            $this->components->error('No failed job matches the given ID.');\n\n            return 1;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/ListFailedCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:failed')]\nclass ListFailedCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'queue:failed';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'List all of the failed queue jobs';\n\n    /**\n     * The table headers for the command.\n     *\n     * @var string[]\n     */\n    protected $headers = ['ID', 'Connection', 'Queue', 'Class', 'Failed At'];\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        if (count($jobs = $this->getFailedJobs()) === 0) {\n            return $this->components->info('No failed jobs found.');\n        }\n\n        $this->newLine();\n        $this->displayFailedJobs($jobs);\n        $this->newLine();\n    }\n\n    /**\n     * Compile the failed jobs into a displayable format.\n     *\n     * @return array\n     */\n    protected function getFailedJobs()\n    {\n        $failed = $this->laravel['queue.failer']->all();\n\n        return (new Collection($failed))\n            ->map(fn ($failed) => $this->parseFailedJob((array) $failed))\n            ->filter()\n            ->all();\n    }\n\n    /**\n     * Parse the failed job row.\n     *\n     * @param  array  $failed\n     * @return array\n     */\n    protected function parseFailedJob(array $failed)\n    {\n        $row = array_values(Arr::except($failed, ['payload', 'exception']));\n\n        array_splice($row, 3, 0, $this->extractJobName($failed['payload']) ?: '');\n\n        return $row;\n    }\n\n    /**\n     * Extract the failed job name from payload.\n     *\n     * @param  string  $payload\n     * @return string|null\n     */\n    private function extractJobName($payload)\n    {\n        $payload = json_decode($payload, true);\n\n        if ($payload && (! isset($payload['data']['command']))) {\n            return $payload['job'] ?? null;\n        } elseif ($payload && isset($payload['data']['command'])) {\n            return $this->matchJobName($payload);\n        }\n    }\n\n    /**\n     * Match the job name from the payload.\n     *\n     * @param  array  $payload\n     * @return string|null\n     */\n    protected function matchJobName($payload)\n    {\n        preg_match('/\"([^\"]+)\"/', $payload['data']['command'], $matches);\n\n        return $matches[1] ?? $payload['job'] ?? null;\n    }\n\n    /**\n     * Display the failed jobs in the console.\n     *\n     * @param  array  $jobs\n     * @return void\n     */\n    protected function displayFailedJobs(array $jobs)\n    {\n        (new Collection($jobs))->each(\n            fn ($job) => $this->components->twoColumnDetail(\n                sprintf('<fg=gray>%s</> %s</>', $job[4], $job[0]),\n                sprintf('<fg=gray>%s@%s</> %s', $job[1], $job[2], $job[3])\n            ),\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/ListenCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Queue\\Listener;\nuse Illuminate\\Queue\\ListenerOptions;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:listen')]\nclass ListenCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:listen\n                            {connection? : The name of connection}\n                            {--name=default : The name of the worker}\n                            {--delay=0 : The number of seconds to delay failed jobs (Deprecated)}\n                            {--backoff=0 : The number of seconds to wait before retrying a job that encountered an uncaught exception}\n                            {--force : Force the worker to run even in maintenance mode}\n                            {--memory=128 : The memory limit in megabytes}\n                            {--queue= : The queue to listen on}\n                            {--sleep=3 : The number of seconds to sleep when no job is available}\n                            {--rest=0 : The number of seconds to rest between jobs}\n                            {--timeout=60 : The number of seconds a child process can run}\n                            {--tries=1 : The number of times to attempt a job before logging it failed}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Listen to a given queue';\n\n    /**\n     * The queue listener instance.\n     *\n     * @var \\Illuminate\\Queue\\Listener\n     */\n    protected $listener;\n\n    /**\n     * Create a new queue listen command.\n     *\n     * @param  \\Illuminate\\Queue\\Listener  $listener\n     */\n    public function __construct(Listener $listener)\n    {\n        parent::__construct();\n\n        $this->setOutputHandler($this->listener = $listener);\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        // We need to get the right queue for the connection which is set in the queue\n        // configuration file for the application. We will pull it based on the set\n        // connection being run for the queue operation currently being executed.\n        $queue = $this->getQueue(\n            $connection = $this->input->getArgument('connection')\n        );\n\n        $this->components->info(sprintf('Processing jobs from the [%s] %s.', $queue, (new Stringable('queue'))->plural(explode(',', $queue))));\n\n        $this->listener->listen(\n            $connection, $queue, $this->gatherOptions()\n        );\n    }\n\n    /**\n     * Get the name of the queue connection to listen on.\n     *\n     * @param  string  $connection\n     * @return string\n     */\n    protected function getQueue($connection)\n    {\n        $connection = $connection ?: $this->laravel['config']['queue.default'];\n\n        return $this->input->getOption('queue') ?: $this->laravel['config']->get(\n            \"queue.connections.{$connection}.queue\", 'default'\n        );\n    }\n\n    /**\n     * Get the listener options for the command.\n     *\n     * @return \\Illuminate\\Queue\\ListenerOptions\n     */\n    protected function gatherOptions()\n    {\n        $backoff = $this->hasOption('backoff')\n            ? $this->option('backoff')\n            : $this->option('delay');\n\n        return new ListenerOptions(\n            name: $this->option('name'),\n            environment: $this->option('env'),\n            backoff: $backoff,\n            memory: $this->option('memory'),\n            timeout: $this->option('timeout'),\n            sleep: $this->option('sleep'),\n            rest: $this->option('rest'),\n            maxTries: $this->option('tries'),\n            force: $this->option('force')\n        );\n    }\n\n    /**\n     * Set the options on the queue listener.\n     *\n     * @param  \\Illuminate\\Queue\\Listener  $listener\n     * @return void\n     */\n    protected function setOutputHandler(Listener $listener)\n    {\n        $listener->setOutputHandler(function ($type, $line) {\n            $this->output->write($line);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/MonitorCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\Factory;\nuse Illuminate\\Queue\\Events\\QueueBusy;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:monitor')]\nclass MonitorCommand extends Command\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:monitor\n                       {queues : The names of the queues to monitor}\n                       {--max=1000 : The maximum number of jobs that can be on the queue before an event is dispatched}\n                       {--json : Output the queue size as JSON}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Monitor the size of the specified queues';\n\n    /**\n     * The queue manager instance.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    protected $manager;\n\n    /**\n     * The events dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * Create a new queue monitor command.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $manager\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     */\n    public function __construct(Factory $manager, Dispatcher $events)\n    {\n        parent::__construct();\n\n        $this->manager = $manager;\n        $this->events = $events;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $queues = $this->parseQueues($this->argument('queues'));\n\n        if ($this->option('json')) {\n            $this->output->writeln((new Collection($queues))->map(function ($queue) {\n                return array_merge($queue, [\n                    'status' => str_contains($queue['status'], 'ALERT') ? 'ALERT' : 'OK',\n                ]);\n            })->toJson());\n        } else {\n            $this->displaySizes($queues);\n        }\n\n        $this->dispatchEvents($queues);\n    }\n\n    /**\n     * Parse the queues into an array of the connections and queues.\n     *\n     * @param  string  $queues\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function parseQueues($queues)\n    {\n        return (new Collection(explode(',', $queues)))->map(function ($queue) {\n            [$connection, $queue] = array_pad(explode(':', $queue, 2), 2, null);\n\n            if (! isset($queue)) {\n                $queue = $connection;\n                $connection = $this->laravel['config']['queue.default'];\n            }\n\n            return [\n                'connection' => $connection,\n                'queue' => $queue,\n                'size' => $size = $this->manager->connection($connection)->size($queue),\n                'pending' => $this->manager->connection($connection)->pendingSize($queue),\n                'delayed' => $this->manager->connection($connection)->delayedSize($queue),\n                'reserved' => $this->manager->connection($connection)->reservedSize($queue),\n                'oldest_pending' => $this->manager->connection($connection)->creationTimeOfOldestPendingJob($queue),\n                'status' => $size >= $this->option('max') ? '<fg=yellow;options=bold>ALERT</>' : '<fg=green;options=bold>OK</>',\n            ];\n        });\n    }\n\n    /**\n     * Display the queue sizes in the console.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $queues\n     * @return void\n     */\n    protected function displaySizes(Collection $queues)\n    {\n        $this->newLine();\n\n        $this->components->twoColumnDetail('<fg=gray>Queue name</>', '<fg=gray>Size / Status</>');\n\n        $queues->each(function ($queue) {\n            $name = '['.$queue['connection'].'] '.$queue['queue'];\n            $status = '['.$queue['size'].'] '.$queue['status'];\n\n            $this->components->twoColumnDetail($name, $status);\n            $this->components->twoColumnDetail('Pending jobs', $queue['pending'] ?? 'N/A');\n            $this->components->twoColumnDetail('Delayed jobs', $queue['delayed'] ?? 'N/A');\n            $this->components->twoColumnDetail('Reserved jobs', $queue['reserved'] ?? 'N/A');\n            $this->components->twoColumnDetail('Oldest pending job', $queue['oldest_pending']\n                ? Carbon::createFromTimestamp($queue['oldest_pending'])->diffForHumans()\n                : 'N/A'\n            );\n            $this->line('');\n        });\n\n        $this->newLine();\n    }\n\n    /**\n     * Fire the monitoring events.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $queues\n     * @return void\n     */\n    protected function dispatchEvents(Collection $queues)\n    {\n        foreach ($queues as $queue) {\n            if ($queue['status'] == '<fg=green;options=bold>OK</>') {\n                continue;\n            }\n\n            $this->events->dispatch(\n                new QueueBusy(\n                    $queue['connection'],\n                    $queue['queue'],\n                    $queue['size'],\n                )\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/PauseCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueManager;\nuse Illuminate\\Queue\\Console\\Concerns\\ParsesQueue;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:pause')]\nclass PauseCommand extends Command\n{\n    use ParsesQueue;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:pause {queue : The name of the queue to pause}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Pause job processing for a specific queue';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(QueueManager $manager)\n    {\n        [$connection, $queue] = $this->parseQueue($this->argument('queue'));\n\n        $manager->pause($connection, $queue);\n\n        $this->components->info(\"Job processing on queue [{$connection}:{$queue}] has been paused.\");\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/PruneBatchesCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\DatabaseBatchRepository;\nuse Illuminate\\Bus\\PrunableBatchRepository;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Carbon;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:prune-batches')]\nclass PruneBatchesCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:prune-batches\n                {--hours=24 : The number of hours to retain batch data}\n                {--unfinished= : The number of hours to retain unfinished batch data }\n                {--cancelled= : The number of hours to retain cancelled batch data }';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Prune stale entries from the batches database';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $repository = $this->laravel[BatchRepository::class];\n\n        $count = 0;\n\n        if ($repository instanceof PrunableBatchRepository) {\n            $count = $repository->prune(Carbon::now()->subHours($this->option('hours')));\n        }\n\n        $this->components->info(\"{$count} entries deleted.\");\n\n        if ($this->option('unfinished') !== null) {\n            $count = 0;\n\n            if ($repository instanceof DatabaseBatchRepository) {\n                $count = $repository->pruneUnfinished(Carbon::now()->subHours($this->option('unfinished')));\n            }\n\n            $this->components->info(\"{$count} unfinished entries deleted.\");\n        }\n\n        if ($this->option('cancelled') !== null) {\n            $count = 0;\n\n            if ($repository instanceof DatabaseBatchRepository) {\n                $count = $repository->pruneCancelled(Carbon::now()->subHours($this->option('cancelled')));\n            }\n\n            $this->components->info(\"{$count} cancelled entries deleted.\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/PruneFailedJobsCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Queue\\Failed\\PrunableFailedJobProvider;\nuse Illuminate\\Support\\Carbon;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:prune-failed')]\nclass PruneFailedJobsCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:prune-failed\n                {--hours=24 : The number of hours to retain failed jobs data}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Prune stale entries from the failed jobs table';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int|null\n     */\n    public function handle()\n    {\n        $failer = $this->laravel['queue.failer'];\n\n        if ($failer instanceof PrunableFailedJobProvider) {\n            $count = $failer->prune(Carbon::now()->subHours($this->option('hours')));\n        } else {\n            $this->components->error('The ['.class_basename($failer).'] failed job storage driver does not support pruning.');\n\n            return 1;\n        }\n\n        $this->components->info(\"{$count} entries deleted.\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/RestartCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:restart')]\nclass RestartCommand extends Command\n{\n    use InteractsWithTime;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'queue:restart';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Restart queue worker daemons after their current job';\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * Create a new queue restart command.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     */\n    public function __construct(Cache $cache)\n    {\n        parent::__construct();\n\n        $this->cache = $cache;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $this->cache->forever('illuminate:queue:restart', $this->currentTime());\n\n        $this->components->info('Broadcasting queue restart signal.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/ResumeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueManager;\nuse Illuminate\\Queue\\Console\\Concerns\\ParsesQueue;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:resume', aliases: ['queue:continue'])]\nclass ResumeCommand extends Command\n{\n    use ParsesQueue;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:resume {queue : The name of the queue that should resume processing}';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var list<string>\n     */\n    protected $aliases = ['queue:continue'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Resume job processing for a paused queue';\n\n    /**\n     * Execute the console command.\n     *\n     * @return int\n     */\n    public function handle(QueueManager $manager)\n    {\n        [$connection, $queue] = $this->parseQueue($this->argument('queue'));\n\n        $manager->resume($connection, $queue);\n\n        $this->components->info(\"Job processing on queue [{$connection}:{$queue}] has been resumed.\");\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/RetryBatchCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\Isolatable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:retry-batch')]\nclass RetryBatchCommand extends Command implements Isolatable\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:retry-batch\n                            {id?* : The ID of the batch whose failed jobs should be retried}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Retry the failed jobs for a batch';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $batchesFound = count($ids = $this->getBatchJobIds()) > 0;\n\n        if ($batchesFound) {\n            $this->components->info('Pushing failed batch jobs back onto the queue.');\n        }\n\n        foreach ($ids as $batchId) {\n            $batch = $this->laravel[BatchRepository::class]->find($batchId);\n\n            if (! $batch) {\n                $this->components->error(\"Unable to find a batch with ID [{$batchId}].\");\n            } elseif (empty($batch->failedJobIds)) {\n                $this->components->error('The given batch does not contain any failed jobs.');\n            }\n\n            $this->components->info(\"Pushing failed queue jobs of the batch [$batchId] back onto the queue.\");\n\n            foreach ($batch->failedJobIds as $failedJobId) {\n                $this->components->task(\n                    $failedJobId,\n                    fn () => $this->callSilent('queue:retry', ['id' => $failedJobId]) == 0\n                );\n            }\n\n            $this->newLine();\n        }\n    }\n\n    /**\n     * Get the custom mutex name for an isolated command.\n     *\n     * @return string\n     */\n    public function isolatableId()\n    {\n        return $this->argument('id');\n    }\n\n    /**\n     * Get the batch IDs to be retried.\n     *\n     * @return array\n     */\n    protected function getBatchJobIds()\n    {\n        $ids = (array) $this->argument('id');\n\n        return array_values(array_filter(array_unique($ids)));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/RetryCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse DateTimeInterface;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Queue\\Events\\JobRetryRequested;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'queue:retry')]\nclass RetryCommand extends Command\n{\n    /**\n     * The console command signature.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:retry\n                            {id?* : The ID of the failed job or \"all\" to retry all jobs}\n                            {--queue= : Retry all of the failed jobs for the specified queue}\n                            {--range=* : Range of job IDs (numeric) to be retried (e.g. 1-5)}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Retry a failed queue job';\n\n    /**\n     * Execute the console command.\n     *\n     * @return void\n     */\n    public function handle()\n    {\n        $jobsFound = count($ids = $this->getJobIds()) > 0;\n\n        if ($jobsFound) {\n            $this->components->info('Pushing failed queue jobs back onto the queue.');\n        }\n\n        foreach ($ids as $id) {\n            $job = $this->laravel['queue.failer']->find($id);\n\n            if (is_null($job)) {\n                $this->components->error(\"Unable to find failed job with ID [{$id}].\");\n            } else {\n                $this->laravel['events']->dispatch(new JobRetryRequested($job));\n\n                $this->components->task($id, fn () => $this->retryJob($job));\n\n                $this->laravel['queue.failer']->forget($id);\n            }\n        }\n\n        $jobsFound ? $this->newLine() : $this->components->info('No retryable jobs found.');\n    }\n\n    /**\n     * Get the job IDs to be retried.\n     *\n     * @return array\n     */\n    protected function getJobIds()\n    {\n        $ids = (array) $this->argument('id');\n\n        if (count($ids) === 1 && $ids[0] === 'all') {\n            $failer = $this->laravel['queue.failer'];\n\n            return method_exists($failer, 'ids')\n                ? $failer->ids()\n                : Arr::pluck($failer->all(), 'id');\n        }\n\n        if ($queue = $this->option('queue')) {\n            return $this->getJobIdsByQueue($queue);\n        }\n\n        if ($ranges = (array) $this->option('range')) {\n            $ids = array_merge($ids, $this->getJobIdsByRanges($ranges));\n        }\n\n        return array_values(array_filter(array_unique($ids)));\n    }\n\n    /**\n     * Get the job IDs by queue, if applicable.\n     *\n     * @param  string  $queue\n     * @return array\n     */\n    protected function getJobIdsByQueue($queue)\n    {\n        $failer = $this->laravel['queue.failer'];\n\n        $ids = method_exists($failer, 'ids')\n            ? $failer->ids($queue)\n            : (new Collection($failer->all()))\n                ->where('queue', $queue)\n                ->pluck('id')\n                ->toArray();\n\n        if (count($ids) === 0) {\n            $this->components->error(\"Unable to find failed jobs for queue [{$queue}].\");\n        }\n\n        return $ids;\n    }\n\n    /**\n     * Get the job IDs ranges, if applicable.\n     *\n     * @param  array  $ranges\n     * @return array\n     */\n    protected function getJobIdsByRanges(array $ranges)\n    {\n        $ids = [];\n\n        foreach ($ranges as $range) {\n            if (preg_match('/^[0-9]+\\-[0-9]+$/', $range)) {\n                $ids = array_merge($ids, range(...explode('-', $range)));\n            }\n        }\n\n        return $ids;\n    }\n\n    /**\n     * Retry the queue job.\n     *\n     * @param  \\stdClass  $job\n     * @return void\n     */\n    protected function retryJob($job)\n    {\n        $queue = $this->laravel['queue']->connection($job->connection);\n\n        $this->laravel['queue']->connection($job->connection)->pushRaw(\n            $this->refreshRetryUntil($this->resetAttempts($job->payload)),\n            $job->queue,\n            $this->getQueueableOptions($queue, $job)\n        );\n    }\n\n    /**\n     * Reset the payload attempts.\n     *\n     * Applicable to Redis and other jobs which store attempts in their payload.\n     *\n     * @param  string  $payload\n     * @return string\n     */\n    protected function resetAttempts($payload)\n    {\n        $payload = json_decode($payload, true);\n\n        if (isset($payload['attempts'])) {\n            $payload['attempts'] = 0;\n        }\n\n        return json_encode($payload);\n    }\n\n    /**\n     * Refresh the \"retry until\" timestamp for the job.\n     *\n     * @param  string  $payload\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function refreshRetryUntil($payload)\n    {\n        $payload = json_decode($payload, true);\n\n        if (! isset($payload['data']['command'])) {\n            return json_encode($payload);\n        }\n\n        $instance = $this->getInstanceFromPayload($payload);\n\n        if (is_object($instance) && ! $instance instanceof \\__PHP_Incomplete_Class && method_exists($instance, 'retryUntil')) {\n            $retryUntil = $instance->retryUntil();\n\n            $payload['retryUntil'] = $retryUntil instanceof DateTimeInterface\n                ? $retryUntil->getTimestamp()\n                : $retryUntil;\n        }\n\n        return json_encode($payload);\n    }\n\n    /**\n     * Get the queueable options from the job.\n     *\n     * @param  $queue\n     * @param  \\stdClass  $job\n     * @return array\n     */\n    protected function getQueueableOptions($queue, $job)\n    {\n        if (! method_exists($queue, 'getQueueableOptions')) {\n            return [];\n        }\n\n        $payload = json_decode($job->payload, true);\n\n        if (! isset($payload['data']['command'])) {\n            return [];\n        }\n\n        return $queue->getQueueableOptions($this->getInstanceFromPayload($payload), $job->queue, $job->payload);\n    }\n\n    /**\n     * Get the job instance from the given payload.\n     *\n     * @param  array  $payload\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    protected function getInstanceFromPayload($payload)\n    {\n        if (str_starts_with($payload['data']['command'], 'O:')) {\n            return unserialize($payload['data']['command']);\n        }\n\n        if ($this->laravel->bound(Encrypter::class)) {\n            return unserialize($this->laravel->make(Encrypter::class)->decrypt($payload['data']['command']));\n        }\n\n        throw new RuntimeException('Unable to extract job payload.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/TableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[AsCommand(name: 'make:queue-table', aliases: ['queue:table'])]\nclass TableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:queue-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['queue:table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the queue jobs database table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return $this->laravel['config']['queue.connections.database.table'];\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/jobs.stub';\n    }\n\n    /**\n     * Determine whether a migration for the table already exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function migrationExists($table)\n    {\n        if ($table !== 'jobs') {\n            return parent::migrationExists($table);\n        }\n\n        foreach ([\n            join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php'),\n            join_paths($this->laravel->databasePath('migrations'), '0001_01_01_000002_create_jobs_table.php'),\n        ] as $path) {\n            if (count($this->files->glob($path)) !== 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/WorkCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\Events\\JobFailed;\nuse Illuminate\\Queue\\Events\\JobProcessed;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Illuminate\\Queue\\Events\\JobReleasedAfterException;\nuse Illuminate\\Queue\\Worker;\nuse Illuminate\\Queue\\WorkerOptions;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Stringable;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Terminal;\nuse Throwable;\n\nuse function Termwind\\terminal;\n\n#[AsCommand(name: 'queue:work')]\nclass WorkCommand extends Command\n{\n    use InteractsWithTime;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $signature = 'queue:work\n                            {connection? : The name of the queue connection to work}\n                            {--name=default : The name of the worker}\n                            {--queue= : The names of the queues to work}\n                            {--daemon : Run the worker in daemon mode (Deprecated)}\n                            {--once : Only process the next job on the queue}\n                            {--stop-when-empty : Stop when the queue is empty}\n                            {--delay=0 : The number of seconds to delay failed jobs (Deprecated)}\n                            {--backoff=0 : The number of seconds to wait before retrying a job that encountered an uncaught exception}\n                            {--max-jobs=0 : The number of jobs to process before stopping}\n                            {--max-time=0 : The maximum number of seconds the worker should run}\n                            {--force : Force the worker to run even in maintenance mode}\n                            {--memory=128 : The memory limit in megabytes}\n                            {--sleep=3 : The number of seconds to sleep when no job is available}\n                            {--rest=0 : The number of seconds to rest between jobs}\n                            {--timeout=60 : The number of seconds a child process can run}\n                            {--tries=1 : The number of times to attempt a job before logging it failed}\n                            {--json : Output the queue worker information as JSON}';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Start processing jobs on the queue as a daemon';\n\n    /**\n     * The queue worker instance.\n     *\n     * @var \\Illuminate\\Queue\\Worker\n     */\n    protected $worker;\n\n    /**\n     * The cache store implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * Holds the start time of the last processed job, if any.\n     *\n     * @var float|null\n     */\n    protected $latestStartedAt;\n\n    /**\n     * Indicates if the worker's event listeners have been registered.\n     *\n     * @var bool\n     */\n    private static $hasRegisteredListeners = false;\n\n    /**\n     * Create a new queue work command.\n     *\n     * @param  \\Illuminate\\Queue\\Worker  $worker\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     */\n    public function __construct(Worker $worker, Cache $cache)\n    {\n        parent::__construct();\n\n        $this->cache = $cache;\n        $this->worker = $worker;\n    }\n\n    /**\n     * Execute the console command.\n     *\n     * @return int|null\n     */\n    public function handle()\n    {\n        if ($this->downForMaintenance() && $this->option('once')) {\n            return $this->worker->sleep($this->option('sleep'));\n        }\n\n        // We'll listen to the processed and failed events so we can write information\n        // to the console as jobs are processed, which will let the developer watch\n        // which jobs are coming through a queue and be informed on its progress.\n        $this->listenForEvents();\n\n        $connection = $this->argument('connection')\n            ?: $this->laravel['config']['queue.default'];\n\n        // We need to get the right queue for the connection which is set in the queue\n        // configuration file for the application. We will pull it based on the set\n        // connection being run for the queue operation currently being executed.\n        $queue = $this->getQueue($connection);\n\n        if (! $this->outputUsingJson() && Terminal::hasSttyAvailable()) {\n            $this->components->info(\n                sprintf('Processing jobs from the [%s] %s.', $queue, (new Stringable('queue'))->plural(explode(',', $queue)))\n            );\n        }\n\n        return $this->runWorker(\n            $connection, $queue\n        );\n    }\n\n    /**\n     * Run the worker instance.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @return int|null\n     */\n    protected function runWorker($connection, $queue)\n    {\n        return $this->worker\n            ->setName($this->option('name'))\n            ->setCache($this->cache)\n            ->{$this->option('once') ? 'runNextJob' : 'daemon'}(\n                $connection, $queue, $this->gatherWorkerOptions()\n            );\n    }\n\n    /**\n     * Gather all of the queue worker options as a single object.\n     *\n     * @return \\Illuminate\\Queue\\WorkerOptions\n     */\n    protected function gatherWorkerOptions()\n    {\n        return new WorkerOptions(\n            $this->option('name'),\n            max($this->option('backoff'), $this->option('delay')),\n            $this->option('memory'),\n            $this->option('timeout'),\n            $this->option('sleep'),\n            $this->option('tries'),\n            $this->option('force'),\n            $this->option('stop-when-empty'),\n            $this->option('max-jobs'),\n            $this->option('max-time'),\n            $this->option('rest'),\n        );\n    }\n\n    /**\n     * Listen for the queue events in order to update the console output.\n     *\n     * @return void\n     */\n    protected function listenForEvents()\n    {\n        if (static::$hasRegisteredListeners) {\n            return;\n        }\n\n        $this->laravel['events']->listen(JobProcessing::class, function ($event) {\n            $this->writeOutput($event->job, 'starting');\n        });\n\n        $this->laravel['events']->listen(JobProcessed::class, function ($event) {\n            $this->writeOutput($event->job, 'success');\n        });\n\n        $this->laravel['events']->listen(JobReleasedAfterException::class, function ($event) {\n            $this->writeOutput($event->job, 'released_after_exception');\n        });\n\n        $this->laravel['events']->listen(JobFailed::class, function ($event) {\n            $this->writeOutput($event->job, 'failed', $event->exception);\n\n            $this->logFailedJob($event);\n        });\n\n        static::$hasRegisteredListeners = true;\n    }\n\n    /**\n     * Write the status output for the queue worker for JSON or TTY.\n     *\n     * @param  Job  $job\n     * @param  string  $status\n     * @param  \\Throwable|null  $exception\n     * @return void\n     */\n    protected function writeOutput(Job $job, $status, ?Throwable $exception = null)\n    {\n        if ($this->output->isQuiet() || $this->output->isSilent()) {\n            return;\n        }\n\n        $this->outputUsingJson()\n            ? $this->writeOutputAsJson($job, $status, $exception)\n            : $this->writeOutputForCli($job, $status);\n    }\n\n    /**\n     * Write the status output for the queue worker.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  string  $status\n     * @return void\n     */\n    protected function writeOutputForCli(Job $job, $status)\n    {\n        $isVerbose = $this->output->isVerbose();\n\n        $this->output->write(rtrim(sprintf(\n            '  <fg=gray>%s</> %s %s',\n            $this->now()->format('Y-m-d H:i:s'),\n            $job->resolveName(),\n            $isVerbose\n                ? sprintf('<fg=gray>%s</> <fg=blue>%s</> <fg=blue>%s</>', $job->getJobId(), $job->getConnectionName(), $job->getQueue())\n                : ''\n        )));\n\n        if ($status == 'starting') {\n            $this->latestStartedAt = microtime(true);\n\n            $dots = max(terminal()->width() - mb_strlen($job->resolveName()) - (\n                $isVerbose ? mb_strlen($job->getJobId()) + mb_strlen($job->getConnectionName()) + mb_strlen($job->getQueue()) + 2 : 0\n            ) - 33, 0);\n\n            $this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));\n\n            return $this->output->writeln(' <fg=yellow;options=bold>RUNNING</>');\n        }\n\n        $runTime = $this->runTimeForHumans($this->latestStartedAt);\n\n        $dots = max(terminal()->width() - mb_strlen($job->resolveName()) - (\n            $isVerbose ? mb_strlen($job->getJobId()) + mb_strlen($job->getConnectionName()) + mb_strlen($job->getQueue()) + 2 : 0\n        ) - mb_strlen($runTime) - 31, 0);\n\n        $this->output->write(' '.str_repeat('<fg=gray>.</>', $dots));\n        $this->output->write(\" <fg=gray>$runTime</>\");\n\n        $this->output->writeln(match ($status) {\n            'success' => ' <fg=green;options=bold>DONE</>',\n            'released_after_exception' => ' <fg=yellow;options=bold>FAIL</>',\n            default => ' <fg=red;options=bold>FAIL</>',\n        });\n    }\n\n    /**\n     * Write the status output for the queue worker in JSON format.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  string  $status\n     * @param  \\Throwable|null  $exception\n     * @return void\n     */\n    protected function writeOutputAsJson(Job $job, $status, ?Throwable $exception = null)\n    {\n        $log = array_filter([\n            'level' => $status === 'starting' || $status === 'success' ? 'info' : 'warning',\n            'id' => $job->getJobId(),\n            'uuid' => $job->uuid(),\n            'connection' => $job->getConnectionName(),\n            'queue' => $job->getQueue(),\n            'job' => $job->resolveName(),\n            'status' => $status,\n            'result' => match (true) {\n                $job->isDeleted() => 'deleted',\n                $job->isReleased() => 'released',\n                $job->hasFailed() => 'failed',\n                default => '',\n            },\n            'attempts' => $job->attempts(),\n            'exception' => $exception ? $exception::class : '',\n            'message' => $exception?->getMessage(),\n            'timestamp' => $this->now()->format('Y-m-d\\TH:i:s.uP'),\n        ]);\n\n        if ($status === 'starting') {\n            $this->latestStartedAt = microtime(true);\n        } else {\n            $log['duration'] = round(microtime(true) - $this->latestStartedAt, 6);\n        }\n\n        $this->output->writeln(json_encode($log));\n    }\n\n    /**\n     * Get the current date / time.\n     *\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    protected function now()\n    {\n        $queueTimezone = $this->laravel['config']->get('queue.output_timezone');\n\n        if ($queueTimezone &&\n            $queueTimezone !== $this->laravel['config']->get('app.timezone')) {\n            return Carbon::now()->setTimezone($queueTimezone);\n        }\n\n        return Carbon::now();\n    }\n\n    /**\n     * Store a failed job event.\n     *\n     * @param  \\Illuminate\\Queue\\Events\\JobFailed  $event\n     * @return void\n     */\n    protected function logFailedJob(JobFailed $event)\n    {\n        $this->laravel['queue.failer']->log(\n            $event->connectionName,\n            $event->job->getQueue(),\n            $event->job->getRawBody(),\n            $event->exception\n        );\n    }\n\n    /**\n     * Get the queue name for the worker.\n     *\n     * @param  string  $connection\n     * @return string\n     */\n    protected function getQueue($connection)\n    {\n        return $this->option('queue') ?: $this->laravel['config']->get(\n            \"queue.connections.{$connection}.queue\", 'default'\n        );\n    }\n\n    /**\n     * Determine if the worker should run in maintenance mode.\n     *\n     * @return bool\n     */\n    protected function downForMaintenance()\n    {\n        return $this->option('force') ? false : $this->laravel->isDownForMaintenance();\n    }\n\n    /**\n     * Determine if the worker should output using JSON.\n     *\n     * @return bool\n     */\n    protected function outputUsingJson()\n    {\n        if (! $this->hasOption('json')) {\n            return false;\n        }\n\n        return $this->option('json');\n    }\n\n    /**\n     * Reset static variables.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$hasRegisteredListeners = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/stubs/batches.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('{{table}}', function (Blueprint $table) {\n            $table->string('id')->primary();\n            $table->string('name');\n            $table->integer('total_jobs');\n            $table->integer('pending_jobs');\n            $table->integer('failed_jobs');\n            $table->longText('failed_job_ids');\n            $table->mediumText('options')->nullable();\n            $table->integer('cancelled_at')->nullable();\n            $table->integer('created_at');\n            $table->integer('finished_at')->nullable();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('{{table}}');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/stubs/failed_jobs.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('{{table}}', function (Blueprint $table) {\n            $table->id();\n            $table->string('uuid')->unique();\n            $table->text('connection');\n            $table->text('queue');\n            $table->longText('payload');\n            $table->longText('exception');\n            $table->timestamp('failed_at')->useCurrent();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('{{table}}');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Queue/Console/stubs/jobs.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('{{table}}', function (Blueprint $table) {\n            $table->bigIncrements('id');\n            $table->string('queue')->index();\n            $table->longText('payload');\n            $table->unsignedTinyInteger('attempts');\n            $table->unsignedInteger('reserved_at')->nullable();\n            $table->unsignedInteger('available_at');\n            $table->unsignedInteger('created_at');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('{{table}}');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Queue/DatabaseQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Queue\\ClearableQueue;\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Queue\\Jobs\\DatabaseJob;\nuse Illuminate\\Queue\\Jobs\\DatabaseJobRecord;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse PDO;\nuse Throwable;\n\nclass DatabaseQueue extends Queue implements QueueContract, ClearableQueue\n{\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $database;\n\n    /**\n     * The database table that holds the jobs.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The name of the default queue.\n     *\n     * @var string\n     */\n    protected $default;\n\n    /**\n     * The expiration time of a job.\n     *\n     * @var int|null\n     */\n    protected $retryAfter = 60;\n\n    /**\n     * Create a new database queue instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $database\n     * @param  string  $table\n     * @param  string  $default\n     * @param  int  $retryAfter\n     * @param  bool  $dispatchAfterCommit\n     */\n    public function __construct(\n        Connection $database,\n        $table,\n        $default = 'default',\n        $retryAfter = 60,\n        $dispatchAfterCommit = false,\n    ) {\n        $this->table = $table;\n        $this->default = $default;\n        $this->database = $database;\n        $this->retryAfter = $retryAfter;\n        $this->dispatchAfterCommit = $dispatchAfterCommit;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->count();\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->whereNull('reserved_at')\n            ->where('available_at', '<=', $this->currentTime())\n            ->count();\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->whereNull('reserved_at')\n            ->where('available_at', '>', $this->currentTime())\n            ->count();\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->whereNotNull('reserved_at')\n            ->count();\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->whereNull('reserved_at')\n            ->where('available_at', '<=', $this->currentTime())\n            ->oldest('available_at')\n            ->value('available_at');\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data),\n            $queue,\n            null,\n            function ($payload, $queue) {\n                return $this->pushToDatabase($queue, $payload);\n            }\n        );\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        return $this->pushToDatabase($queue, $payload);\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data, $delay),\n            $queue,\n            $delay,\n            function ($payload, $queue, $delay) {\n                return $this->pushToDatabase($queue, $payload, $delay);\n            }\n        );\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        $queue = $this->getQueue($queue);\n\n        $now = $this->availableAt();\n\n        return $this->database->table($this->table)->insert((new Collection((array) $jobs))->map(\n            function ($job) use ($queue, $data, $now) {\n                return $this->buildDatabaseRecord(\n                    $queue,\n                    $this->createPayload($job, $this->getQueue($queue), $data),\n                    isset($job->delay) ? $this->availableAt($job->delay) : $now,\n                );\n            }\n        )->all());\n    }\n\n    /**\n     * Release a reserved job back onto the queue after (n) seconds.\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord  $job\n     * @param  int  $delay\n     * @return mixed\n     */\n    public function release($queue, $job, $delay)\n    {\n        return $this->pushToDatabase($queue, $job->payload, $delay, $job->attempts);\n    }\n\n    /**\n     * Push a raw payload to the database with a given delay of (n) seconds.\n     *\n     * @param  string|null  $queue\n     * @param  string  $payload\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  int  $attempts\n     * @return mixed\n     */\n    protected function pushToDatabase($queue, $payload, $delay = 0, $attempts = 0)\n    {\n        return $this->database->table($this->table)->insertGetId($this->buildDatabaseRecord(\n            $this->getQueue($queue),\n            $payload,\n            $this->availableAt($delay),\n            $attempts\n        ));\n    }\n\n    /**\n     * Create an array to insert for the given job.\n     *\n     * @param  string|null  $queue\n     * @param  string  $payload\n     * @param  int  $availableAt\n     * @param  int  $attempts\n     * @return array\n     */\n    protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)\n    {\n        return [\n            'queue' => $queue,\n            'attempts' => $attempts,\n            'reserved_at' => null,\n            'available_at' => $availableAt,\n            'created_at' => $this->currentTime(),\n            'payload' => $payload,\n        ];\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     *\n     * @throws \\Throwable\n     */\n    public function pop($queue = null)\n    {\n        $queue = $this->getQueue($queue);\n\n        $jobRecord = null;\n\n        try {\n            return $this->database->transaction(function () use ($queue, &$jobRecord) {\n                if ($jobRecord = $this->getNextAvailableJob($queue)) {\n                    return $this->marshalJob($queue, $jobRecord);\n                }\n            });\n        } catch (Throwable $e) {\n            // Potentially invalid job that we need to fail (#58978)...\n            if ($jobRecord) {\n                try {\n                    (new DatabaseJob(\n                        $this->container, $this, $jobRecord, $this->connectionName, $queue\n                    ))->fail($e);\n                } catch (Throwable) {\n                    // Ignore and throw the original exception...\n                }\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Get the next available job for the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord|null\n     */\n    protected function getNextAvailableJob($queue)\n    {\n        $job = $this->database->table($this->table)\n            ->lock($this->getLockForPopping())\n            ->where('queue', $this->getQueue($queue))\n            ->where(function ($query) {\n                $this->isAvailable($query);\n                $this->isReservedButExpired($query);\n            })\n            ->orderBy('id', 'asc')\n            ->first();\n\n        return $job ? new DatabaseJobRecord((object) $job) : null;\n    }\n\n    /**\n     * Get the lock required for popping the next job.\n     *\n     * @return string|bool\n     */\n    protected function getLockForPopping()\n    {\n        $databaseEngine = $this->database->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME);\n        $databaseVersion = $this->database->getConfig('version') ?? $this->database->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);\n\n        if ((new Stringable($databaseVersion))->contains('MariaDB')) {\n            $databaseEngine = 'mariadb';\n            $databaseVersion = Str::before(Str::after($databaseVersion, '5.5.5-'), '-');\n        } elseif ((new Stringable($databaseVersion))->contains(['vitess', 'PlanetScale'])) {\n            $databaseEngine = 'vitess';\n            $databaseVersion = Str::before($databaseVersion, '-');\n        }\n\n        if (($databaseEngine === 'mysql' && version_compare($databaseVersion, '8.0.1', '>=')) ||\n            ($databaseEngine === 'mariadb' && version_compare($databaseVersion, '10.6.0', '>=')) ||\n            ($databaseEngine === 'pgsql' && version_compare($databaseVersion, '9.5', '>=')) ||\n            ($databaseEngine === 'vitess' && version_compare($databaseVersion, '19.0', '>='))\n        ) {\n            return 'FOR UPDATE SKIP LOCKED';\n        }\n\n        if ($databaseEngine === 'sqlsrv') {\n            return 'with(rowlock,updlock,readpast)';\n        }\n\n        return true;\n    }\n\n    /**\n     * Modify the query to check for available jobs.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return void\n     */\n    protected function isAvailable($query)\n    {\n        $query->where(function ($query) {\n            $query->whereNull('reserved_at')\n                ->where('available_at', '<=', $this->currentTime());\n        });\n    }\n\n    /**\n     * Modify the query to check for jobs that are reserved but have expired.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @return void\n     */\n    protected function isReservedButExpired($query)\n    {\n        $expiration = Carbon::now()->subSeconds($this->retryAfter)->getTimestamp();\n\n        $query->orWhere(function ($query) use ($expiration) {\n            $query->where('reserved_at', '<=', $expiration);\n        });\n    }\n\n    /**\n     * Marshal the reserved job into a DatabaseJob instance.\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord  $job\n     * @return \\Illuminate\\Queue\\Jobs\\DatabaseJob\n     */\n    protected function marshalJob($queue, $job)\n    {\n        return new DatabaseJob(\n            $this->container,\n            $this,\n            $this->markJobAsReserved($job),\n            $this->connectionName,\n            $queue,\n        );\n    }\n\n    /**\n     * Mark the given job ID as reserved.\n     *\n     * @param  \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord  $job\n     * @return \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord\n     */\n    protected function markJobAsReserved($job)\n    {\n        $this->database->table($this->table)->where('id', $job->id)->update([\n            'reserved_at' => $job->touch(),\n            'attempts' => $job->increment(),\n        ]);\n\n        return $job;\n    }\n\n    /**\n     * Delete a reserved job from the queue.\n     *\n     * @param  string  $queue\n     * @param  string  $id\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function deleteReserved($queue, $id)\n    {\n        $this->database->transaction(function () use ($id) {\n            if ($this->database->table($this->table)->lockForUpdate()->find($id)) {\n                $this->database->table($this->table)->where('id', $id)->delete();\n            }\n        });\n    }\n\n    /**\n     * Delete a reserved job from the reserved queue and release it.\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\Jobs\\DatabaseJob  $job\n     * @param  int  $delay\n     * @return void\n     */\n    public function deleteAndRelease($queue, $job, $delay)\n    {\n        $this->database->transaction(function () use ($queue, $job, $delay) {\n            if ($this->database->table($this->table)->lockForUpdate()->find($job->getJobId())) {\n                $this->database->table($this->table)->where('id', $job->getJobId())->delete();\n            }\n\n            $this->release($queue, $job->getJobRecord(), $delay);\n        });\n    }\n\n    /**\n     * Delete all of the jobs from the queue.\n     *\n     * @param  string  $queue\n     * @return int\n     */\n    public function clear($queue)\n    {\n        return $this->database->table($this->table)\n            ->where('queue', $this->getQueue($queue))\n            ->delete();\n    }\n\n    /**\n     * Get the queue or return the default.\n     *\n     * @param  string|null  $queue\n     * @return string\n     */\n    public function getQueue($queue)\n    {\n        return $queue ?: $this->default;\n    }\n\n    /**\n     * Get the underlying database instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    public function getDatabase()\n    {\n        return $this->database;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/DeferredQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass DeferredQueue extends SyncQueue\n{\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return \\Illuminate\\Support\\defer(fn () => parent::push($job, $data, $queue));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobAttempted.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobAttempted\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     * @param  \\Throwable|null  $exception  The exception, if one occurred while processing the job.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n        public $exception = null,\n    ) {\n    }\n\n    /**\n     * Determine if the job completed with failing or an unhandled exception occurring.\n     *\n     * @return bool\n     */\n    public function successful(): bool\n    {\n        return ! $this->job->hasFailed() && is_null($this->exception);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobExceptionOccurred.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobExceptionOccurred\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     * @param  \\Throwable  $exception  The exception instance.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n        public $exception,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobFailed\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     * @param  \\Throwable  $exception  The exception that caused the job to fail.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n        public $exception,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobPopped.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobPopped\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job|null  $job  The job instance.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobPopping.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobPopping\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  string|null  $queue  The queue name.\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue = null\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobProcessed.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobProcessed\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobProcessing.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobProcessing\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobQueued.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobQueued\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  string|null  $queue  The queue name.\n     * @param  string|int|null  $id  The job ID.\n     * @param  \\Closure|string|object  $job  The job instance.\n     * @param  string  $payload  The job payload.\n     * @param  int|null  $delay  The amount of time the job was delayed.\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue,\n        public $id,\n        public $job,\n        public $payload,\n        public $delay,\n    ) {\n    }\n\n    /**\n     * Get the decoded job payload.\n     *\n     * @return array\n     */\n    public function payload()\n    {\n        return json_decode($this->payload, true, flags: JSON_THROW_ON_ERROR);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobQueueing.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobQueueing\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  string|null  $queue  The queue name.\n     * @param  \\Closure|string|object  $job  The job instance.\n     * @param  string  $payload  The job payload.\n     * @param  int|null  $delay  The number of seconds the job was delayed.\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue,\n        public $job,\n        public $payload,\n        public $delay,\n    ) {\n    }\n\n    /**\n     * Get the decoded job payload.\n     *\n     * @return array\n     */\n    public function payload()\n    {\n        return json_decode($this->payload, true, flags: JSON_THROW_ON_ERROR);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobReleasedAfterException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobReleasedAfterException\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     * @param  int|null  $backoff  The backoff delay.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n        public $backoff = null\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobRetryRequested.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobRetryRequested\n{\n    /**\n     * The decoded job payload.\n     *\n     * @var array|null\n     */\n    protected $payload = null;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\stdClass  $job  The job instance.\n     */\n    public function __construct(\n        public $job,\n    ) {\n    }\n\n    /**\n     * The job payload.\n     *\n     * @return array\n     */\n    public function payload()\n    {\n        if (is_null($this->payload)) {\n            $this->payload = json_decode($this->job->payload, true);\n        }\n\n        return $this->payload;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/JobTimedOut.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass JobTimedOut\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job  The job instance.\n     */\n    public function __construct(\n        public $connectionName,\n        public $job,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/Looping.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass Looping\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  string  $queue  The queue name.\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/QueueBusy.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass QueueBusy\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName  The connection name.\n     * @param  string  $queue  The queue name.\n     * @param  int  $size  The size of the queue.\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue,\n        public $size,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/QueueFailedOver.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nuse Throwable;\n\nclass QueueFailedOver\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string|null  $connectionName  The queue connection that failed.\n     * @param  \\Closure|string|object  $command  The job instance.\n     * @param  \\Throwable  $exception  The exception that was thrown.\n     */\n    public function __construct(\n        public ?string $connectionName,\n        public mixed $command,\n        public Throwable $exception,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/QueuePaused.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass QueuePaused\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connection  The connection name.\n     * @param  string  $queue  The queue name.\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $ttl\n     */\n    public function __construct(\n        public $connection,\n        public $queue,\n        public $ttl = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/QueueResumed.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass QueueResumed\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connection  The connection name.\n     * @param  string  $queue  The queue name.\n     */\n    public function __construct(\n        public $connection,\n        public $queue,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/WorkerStarting.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass WorkerStarting\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $workerOptions\n     */\n    public function __construct(\n        public $connectionName,\n        public $queue,\n        public $workerOptions,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Events/WorkerStopping.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Events;\n\nclass WorkerStopping\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  int  $status  The worker exit status.\n     * @param  \\Illuminate\\Queue\\WorkerOptions|null  $workerOptions  The worker options.\n     * @param  \\Illuminate\\Queue\\WorkerStopReason|null  $reason  The reason why the worker is stopping.\n     */\n    public function __construct(\n        public $status = 0,\n        public $workerOptions = null,\n        public $reason = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/CountableFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\ninterface CountableFailedJobProvider\n{\n    /**\n     * Count the failed jobs.\n     *\n     * @param  string|null  $connection\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function count($connection = null, $queue = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/DatabaseFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nuse DateTimeInterface;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Support\\Facades\\Date;\n\nclass DatabaseFailedJobProvider implements CountableFailedJobProvider, FailedJobProviderInterface, PrunableFailedJobProvider\n{\n    /**\n     * The connection resolver implementation.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $resolver;\n\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    protected $database;\n\n    /**\n     * The database table.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * Create a new database failed job provider.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     * @param  string  $database\n     * @param  string  $table\n     */\n    public function __construct(ConnectionResolverInterface $resolver, $database, $table)\n    {\n        $this->table = $table;\n        $this->resolver = $resolver;\n        $this->database = $database;\n    }\n\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return int|null\n     */\n    public function log($connection, $queue, $payload, $exception)\n    {\n        $failed_at = Date::now();\n\n        $exception = (string) mb_convert_encoding($exception, 'UTF-8');\n\n        return $this->getTable()->insertGetId(compact(\n            'connection', 'queue', 'payload', 'exception', 'failed_at'\n        ));\n    }\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null)\n    {\n        return $this->getTable()\n            ->when(! is_null($queue), fn ($query) => $query->where('queue', $queue))\n            ->orderBy('id', 'desc')\n            ->pluck('id')\n            ->all();\n    }\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->getTable()->orderBy('id', 'desc')->get()->all();\n    }\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id)\n    {\n        return $this->getTable()->find($id);\n    }\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id)\n    {\n        return $this->getTable()->where('id', $id)->delete() > 0;\n    }\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     */\n    public function flush($hours = null)\n    {\n        $this->getTable()->when($hours, function ($query, $hours) {\n            $query->where('failed_at', '<=', Date::now()->subHours($hours));\n        })->delete();\n    }\n\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before)\n    {\n        $query = $this->getTable()->where('failed_at', '<', $before);\n\n        $totalDeleted = 0;\n\n        do {\n            $deleted = $query->limit(1000)->delete();\n\n            $totalDeleted += $deleted;\n        } while ($deleted !== 0);\n\n        return $totalDeleted;\n    }\n\n    /**\n     * Count the failed jobs.\n     *\n     * @param  string|null  $connection\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function count($connection = null, $queue = null)\n    {\n        return $this->getTable()\n            ->when($connection, fn ($builder) => $builder->whereConnection($connection))\n            ->when($queue, fn ($builder) => $builder->whereQueue($queue))\n            ->count();\n    }\n\n    /**\n     * Get a new query builder instance for the table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function getTable()\n    {\n        return $this->resolver->connection($this->database)->table($this->table);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/DatabaseUuidFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nuse DateTimeInterface;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Support\\Facades\\Date;\n\nclass DatabaseUuidFailedJobProvider implements CountableFailedJobProvider, FailedJobProviderInterface, PrunableFailedJobProvider\n{\n    /**\n     * The connection resolver implementation.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $resolver;\n\n    /**\n     * The database connection name.\n     *\n     * @var string\n     */\n    protected $database;\n\n    /**\n     * The database table.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * Create a new database failed job provider.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $resolver\n     * @param  string  $database\n     * @param  string  $table\n     */\n    public function __construct(ConnectionResolverInterface $resolver, $database, $table)\n    {\n        $this->table = $table;\n        $this->resolver = $resolver;\n        $this->database = $database;\n    }\n\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return string|null\n     */\n    public function log($connection, $queue, $payload, $exception)\n    {\n        $this->getTable()->insert([\n            'uuid' => $uuid = json_decode($payload, true)['uuid'],\n            'connection' => $connection,\n            'queue' => $queue,\n            'payload' => $payload,\n            'exception' => (string) mb_convert_encoding($exception, 'UTF-8'),\n            'failed_at' => Date::now(),\n        ]);\n\n        return $uuid;\n    }\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null)\n    {\n        return $this->getTable()\n            ->when(! is_null($queue), fn ($query) => $query->where('queue', $queue))\n            ->orderBy('id', 'desc')\n            ->pluck('uuid')\n            ->all();\n    }\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->getTable()->orderBy('id', 'desc')->get()->map(function ($record) {\n            $record->id = $record->uuid;\n            unset($record->uuid);\n\n            return $record;\n        })->all();\n    }\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id)\n    {\n        if ($record = $this->getTable()->where('uuid', $id)->first()) {\n            $record->id = $record->uuid;\n            unset($record->uuid);\n        }\n\n        return $record;\n    }\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id)\n    {\n        return $this->getTable()->where('uuid', $id)->delete() > 0;\n    }\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     */\n    public function flush($hours = null)\n    {\n        $this->getTable()->when($hours, function ($query, $hours) {\n            $query->where('failed_at', '<=', Date::now()->subHours($hours));\n        })->delete();\n    }\n\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before)\n    {\n        $query = $this->getTable()->where('failed_at', '<', $before);\n\n        $totalDeleted = 0;\n\n        do {\n            $deleted = $query->limit(1000)->delete();\n\n            $totalDeleted += $deleted;\n        } while ($deleted !== 0);\n\n        return $totalDeleted;\n    }\n\n    /**\n     * Count the failed jobs.\n     *\n     * @param  string|null  $connection\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function count($connection = null, $queue = null)\n    {\n        return $this->getTable()\n            ->when($connection, fn ($builder) => $builder->whereConnection($connection))\n            ->when($queue, fn ($builder) => $builder->whereQueue($queue))\n            ->count();\n    }\n\n    /**\n     * Get a new query builder instance for the table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    public function getTable()\n    {\n        return $this->resolver->connection($this->database)->table($this->table);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/DynamoDbFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Date;\n\nclass DynamoDbFailedJobProvider implements FailedJobProviderInterface\n{\n    /**\n     * The DynamoDB client instance.\n     *\n     * @var \\Aws\\DynamoDb\\DynamoDbClient\n     */\n    protected $dynamo;\n\n    /**\n     * The application name.\n     *\n     * @var string\n     */\n    protected $applicationName;\n\n    /**\n     * The table name.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * Create a new DynamoDb failed job provider.\n     *\n     * @param  \\Aws\\DynamoDb\\DynamoDbClient  $dynamo\n     * @param  string  $applicationName\n     * @param  string  $table\n     */\n    public function __construct(DynamoDbClient $dynamo, $applicationName, $table)\n    {\n        $this->table = $table;\n        $this->dynamo = $dynamo;\n        $this->applicationName = $applicationName;\n    }\n\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return string|int|null\n     */\n    public function log($connection, $queue, $payload, $exception)\n    {\n        $id = json_decode($payload, true)['uuid'];\n\n        $failedAt = Date::now();\n\n        $this->dynamo->putItem([\n            'TableName' => $this->table,\n            'Item' => [\n                'application' => ['S' => $this->applicationName],\n                'uuid' => ['S' => $id],\n                'connection' => ['S' => $connection],\n                'queue' => ['S' => $queue],\n                'payload' => ['S' => $payload],\n                'exception' => ['S' => (string) $exception],\n                'failed_at' => ['N' => (string) $failedAt->getTimestamp()],\n                'expires_at' => ['N' => (string) $failedAt->addDays(7)->getTimestamp()],\n            ],\n        ]);\n\n        return $id;\n    }\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null)\n    {\n        return (new Collection($this->all()))\n            ->when(! is_null($queue), fn ($collect) => $collect->where('queue', $queue))\n            ->pluck('id')\n            ->all();\n    }\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        $results = $this->dynamo->query([\n            'TableName' => $this->table,\n            'Select' => 'ALL_ATTRIBUTES',\n            'KeyConditionExpression' => 'application = :application',\n            'ExpressionAttributeValues' => [\n                ':application' => ['S' => $this->applicationName],\n            ],\n            'ScanIndexForward' => false,\n        ]);\n\n        return (new Collection($results['Items']))\n            ->sortByDesc(fn ($result) => (int) $result['failed_at']['N'])\n            ->map(function ($result) {\n                return (object) [\n                    'id' => $result['uuid']['S'],\n                    'connection' => $result['connection']['S'],\n                    'queue' => $result['queue']['S'],\n                    'payload' => $result['payload']['S'],\n                    'exception' => $result['exception']['S'],\n                    'failed_at' => Carbon::createFromTimestamp(\n                        (int) $result['failed_at']['N'], date_default_timezone_get()\n                    )->format(DateTimeInterface::ISO8601),\n                ];\n            })\n            ->all();\n    }\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id)\n    {\n        $result = $this->dynamo->getItem([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'uuid' => ['S' => $id],\n            ],\n        ]);\n\n        if (! isset($result['Item'])) {\n            return;\n        }\n\n        return (object) [\n            'id' => $result['Item']['uuid']['S'],\n            'connection' => $result['Item']['connection']['S'],\n            'queue' => $result['Item']['queue']['S'],\n            'payload' => $result['Item']['payload']['S'],\n            'exception' => $result['Item']['exception']['S'],\n            'failed_at' => Carbon::createFromTimestamp(\n                (int) $result['Item']['failed_at']['N'], date_default_timezone_get()\n            )->format(DateTimeInterface::ISO8601),\n        ];\n    }\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id)\n    {\n        $this->dynamo->deleteItem([\n            'TableName' => $this->table,\n            'Key' => [\n                'application' => ['S' => $this->applicationName],\n                'uuid' => ['S' => $id],\n            ],\n        ]);\n\n        return true;\n    }\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function flush($hours = null)\n    {\n        throw new Exception(\"DynamoDb failed job storage may not be flushed. Please use DynamoDb's TTL features on your expires_at attribute.\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/FailedJobProviderInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\ninterface FailedJobProviderInterface\n{\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return string|int|null\n     */\n    public function log($connection, $queue, $payload, $exception);\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null);\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all();\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id);\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id);\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     */\n    public function flush($hours = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/FileFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Date;\n\nclass FileFailedJobProvider implements CountableFailedJobProvider, FailedJobProviderInterface, PrunableFailedJobProvider\n{\n    /**\n     * The file path where the failed job file should be stored.\n     *\n     * @var string\n     */\n    protected $path;\n\n    /**\n     * The maximum number of failed jobs to retain.\n     *\n     * @var int\n     */\n    protected $limit;\n\n    /**\n     * The lock provider resolver.\n     *\n     * @var \\Closure\n     */\n    protected $lockProviderResolver;\n\n    /**\n     * Create a new file failed job provider.\n     *\n     * @param  string  $path\n     * @param  int  $limit\n     * @param  \\Closure|null  $lockProviderResolver\n     */\n    public function __construct($path, $limit = 100, ?Closure $lockProviderResolver = null)\n    {\n        $this->path = $path;\n        $this->limit = $limit;\n        $this->lockProviderResolver = $lockProviderResolver;\n    }\n\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return int|null\n     */\n    public function log($connection, $queue, $payload, $exception)\n    {\n        return $this->lock(function () use ($connection, $queue, $payload, $exception) {\n            $id = json_decode($payload, true)['uuid'];\n\n            $jobs = $this->read();\n\n            $failedAt = Date::now();\n\n            array_unshift($jobs, [\n                'id' => $id,\n                'connection' => $connection,\n                'queue' => $queue,\n                'payload' => $payload,\n                'exception' => (string) mb_convert_encoding($exception, 'UTF-8'),\n                'failed_at' => $failedAt->format('Y-m-d H:i:s'),\n                'failed_at_timestamp' => $failedAt->getTimestamp(),\n            ]);\n\n            $this->write(array_slice($jobs, 0, $this->limit));\n\n            return $id;\n        });\n    }\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null)\n    {\n        return (new Collection($this->all()))\n            ->when(! is_null($queue), fn ($collect) => $collect->where('queue', $queue))\n            ->pluck('id')\n            ->all();\n    }\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->read();\n    }\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id)\n    {\n        return (new Collection($this->read()))\n            ->first(fn ($job) => $job->id === $id);\n    }\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id)\n    {\n        return $this->lock(function () use ($id) {\n            $this->write($pruned = (new Collection($jobs = $this->read()))\n                ->reject(fn ($job) => $job->id === $id)\n                ->values()\n                ->all());\n\n            return count($jobs) !== count($pruned);\n        });\n    }\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     */\n    public function flush($hours = null)\n    {\n        $this->prune(Date::now()->subHours($hours ?: 0));\n    }\n\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before)\n    {\n        return $this->lock(function () use ($before) {\n            $jobs = $this->read();\n\n            $this->write($prunedJobs = (new Collection($jobs))\n                ->reject(fn ($job) => $job->failed_at_timestamp <= $before->getTimestamp())\n                ->values()\n                ->all()\n            );\n\n            return count($jobs) - count($prunedJobs);\n        });\n    }\n\n    /**\n     * Execute the given callback while holding a lock.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    protected function lock(Closure $callback)\n    {\n        if (! $this->lockProviderResolver) {\n            return $callback();\n        }\n\n        return ($this->lockProviderResolver)()\n            ->lock('laravel-failed-jobs', 5)\n            ->block(10, function () use ($callback) {\n                return $callback();\n            });\n    }\n\n    /**\n     * Read the failed jobs file.\n     *\n     * @return array\n     */\n    protected function read()\n    {\n        if (! file_exists($this->path)) {\n            return [];\n        }\n\n        $content = file_get_contents($this->path);\n\n        if (empty(trim($content))) {\n            return [];\n        }\n\n        $content = json_decode($content);\n\n        return is_array($content) ? $content : [];\n    }\n\n    /**\n     * Write the given array of jobs to the failed jobs file.\n     *\n     * @param  array  $jobs\n     * @return void\n     */\n    protected function write(array $jobs)\n    {\n        file_put_contents(\n            $this->path,\n            json_encode($jobs, JSON_PRETTY_PRINT)\n        );\n    }\n\n    /**\n     * Count the failed jobs.\n     *\n     * @param  string|null  $connection\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function count($connection = null, $queue = null)\n    {\n        if (($connection ?? $queue) === null) {\n            return count($this->read());\n        }\n\n        return (new Collection($this->read()))\n            ->filter(fn ($job) => $job->connection === ($connection ?? $job->connection) && $job->queue === ($queue ?? $job->queue))\n            ->count();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/NullFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nclass NullFailedJobProvider implements CountableFailedJobProvider, FailedJobProviderInterface\n{\n    /**\n     * Log a failed job into storage.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  string  $payload\n     * @param  \\Throwable  $exception\n     * @return int|null\n     */\n    public function log($connection, $queue, $payload, $exception)\n    {\n        //\n    }\n\n    /**\n     * Get the IDs of all of the failed jobs.\n     *\n     * @param  string|null  $queue\n     * @return array\n     */\n    public function ids($queue = null)\n    {\n        return [];\n    }\n\n    /**\n     * Get a list of all of the failed jobs.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return [];\n    }\n\n    /**\n     * Get a single failed job.\n     *\n     * @param  mixed  $id\n     * @return object|null\n     */\n    public function find($id)\n    {\n        //\n    }\n\n    /**\n     * Delete a single failed job from storage.\n     *\n     * @param  mixed  $id\n     * @return bool\n     */\n    public function forget($id)\n    {\n        return true;\n    }\n\n    /**\n     * Flush all of the failed jobs from storage.\n     *\n     * @param  int|null  $hours\n     * @return void\n     */\n    public function flush($hours = null)\n    {\n        //\n    }\n\n    /**\n     * Count the failed jobs.\n     *\n     * @param  string|null  $connection\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function count($connection = null, $queue = null)\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Failed/PrunableFailedJobProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Failed;\n\nuse DateTimeInterface;\n\ninterface PrunableFailedJobProvider\n{\n    /**\n     * Prune all of the entries older than the given date.\n     *\n     * @param  \\DateTimeInterface  $before\n     * @return int\n     */\n    public function prune(DateTimeInterface $before);\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/FailoverQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher as EventDispatcher;\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Queue\\Events\\QueueFailedOver;\nuse RuntimeException;\nuse Throwable;\n\nclass FailoverQueue extends Queue implements QueueContract\n{\n    /**\n     * The queues which failed on the last action.\n     *\n     * @var list<string>\n     */\n    protected array $failingQueues = [];\n\n    /**\n     * Create a new failover queue instance.\n     */\n    public function __construct(\n        public QueueManager $manager,\n        public EventDispatcher $events,\n        public array $connections\n    ) {\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        return $this->manager->connection($this->connections[0])->size($queue);\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return $this->manager->connection($this->connections[0])->pendingSize($queue);\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return $this->manager->connection($this->connections[0])->delayedSize($queue);\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return $this->manager->connection($this->connections[0])->reservedSize($queue);\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        return $this->manager\n            ->connection($this->connections[0])\n            ->creationTimeOfOldestPendingJob($queue);\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  object|string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return $this->attemptOnAllConnections(__FUNCTION__, func_get_args(), $job);\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        return $this->attemptOnAllConnections(__FUNCTION__, func_get_args());\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->attemptOnAllConnections(__FUNCTION__, func_get_args(), $job);\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        return $this->manager->connection($this->connections[0])->pop($queue);\n    }\n\n    /**\n     * Attempt the given method on all connections.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    protected function attemptOnAllConnections(string $method, array $arguments, $job = null)\n    {\n        [$lastException, $failedQueues] = [null, []];\n\n        try {\n            foreach ($this->connections as $connection) {\n                try {\n                    return $this->manager->connection($connection)->{$method}(...$arguments);\n                } catch (Throwable $e) {\n                    $lastException = $e;\n\n                    $failedQueues[] = $connection;\n\n                    if ($job !== null && ! in_array($connection, $this->failingQueues)) {\n                        $this->events->dispatch(new QueueFailedOver($connection, $job, $e));\n                    }\n                }\n            }\n        } finally {\n            $this->failingQueues = $failedQueues;\n        }\n\n        throw $lastException ?? new RuntimeException('All failover queue connections failed.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/InteractsWithQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse DateTimeInterface;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\nuse Illuminate\\Queue\\Jobs\\FakeJob;\nuse Illuminate\\Support\\InteractsWithTime;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse RuntimeException;\nuse Throwable;\n\ntrait InteractsWithQueue\n{\n    use InteractsWithTime;\n\n    /**\n     * The underlying queue job instance.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public $job;\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return $this->job ? $this->job->attempts() : 1;\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        if ($this->job) {\n            return $this->job->delete();\n        }\n    }\n\n    /**\n     * Fail the job from the queue.\n     *\n     * @param  \\Throwable|string|null  $exception\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function fail($exception = null)\n    {\n        if (is_string($exception)) {\n            $exception = new ManuallyFailedException($exception);\n        }\n\n        if ($exception instanceof Throwable || is_null($exception)) {\n            if ($this->job) {\n                return $this->job->fail($exception);\n            }\n        } else {\n            throw new InvalidArgumentException('The fail method requires a string or an instance of Throwable.');\n        }\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        $delay = $delay instanceof DateTimeInterface\n            ? $this->secondsUntil($delay)\n            : $delay;\n\n        if ($this->job) {\n            return $this->job->release($delay);\n        }\n    }\n\n    /**\n     * Indicate that queue interactions like fail, delete, and release should be faked.\n     *\n     * @return $this\n     */\n    public function withFakeQueueInteractions()\n    {\n        $this->job = new FakeJob;\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was deleted from the queue.\n     *\n     * @return $this\n     */\n    public function assertDeleted()\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        PHPUnit::assertTrue(\n            $this->job->isDeleted(),\n            'Job was expected to be deleted, but was not.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was not deleted from the queue.\n     *\n     * @return $this\n     */\n    public function assertNotDeleted()\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        PHPUnit::assertTrue(\n            ! $this->job->isDeleted(),\n            'Job was unexpectedly deleted.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was manually failed.\n     *\n     * @return $this\n     */\n    public function assertFailed()\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        PHPUnit::assertTrue(\n            $this->job->hasFailed(),\n            'Job was expected to be manually failed, but was not.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was manually failed with a specific exception.\n     *\n     * @param  \\Throwable|string  $exception\n     * @return $this\n     */\n    public function assertFailedWith($exception)\n    {\n        $this->assertFailed();\n\n        if (is_string($exception) && class_exists($exception)) {\n            PHPUnit::assertInstanceOf(\n                $exception,\n                $this->job->failedWith,\n                'Expected job to be manually failed with ['.$exception.'] but job failed with ['.get_class($this->job->failedWith).'].'\n            );\n\n            return $this;\n        }\n\n        if (is_string($exception)) {\n            $exception = new ManuallyFailedException($exception);\n        }\n\n        if ($exception instanceof Throwable) {\n            PHPUnit::assertInstanceOf(\n                get_class($exception),\n                $this->job->failedWith,\n                'Expected job to be manually failed with ['.get_class($exception).'] but job failed with ['.get_class($this->job->failedWith).'].'\n            );\n\n            PHPUnit::assertEquals(\n                $exception->getCode(),\n                $this->job->failedWith->getCode(),\n                'Expected exception code ['.$exception->getCode().'] but job failed with exception code ['.$this->job->failedWith->getCode().'].'\n            );\n\n            PHPUnit::assertEquals(\n                $exception->getMessage(),\n                $this->job->failedWith->getMessage(),\n                'Expected exception message ['.$exception->getMessage().'] but job failed with exception message ['.$this->job->failedWith->getMessage().'].');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was not manually failed.\n     *\n     * @return $this\n     */\n    public function assertNotFailed()\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        PHPUnit::assertTrue(\n            ! $this->job->hasFailed(),\n            'Job was unexpectedly failed manually.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was released back onto the queue.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return $this\n     */\n    public function assertReleased($delay = null)\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        $delay = $delay instanceof DateTimeInterface\n            ? $this->secondsUntil($delay)\n            : $delay;\n\n        PHPUnit::assertTrue(\n            $this->job->isReleased(),\n            'Job was expected to be released, but was not.'\n        );\n\n        if (! is_null($delay)) {\n            PHPUnit::assertSame(\n                $delay,\n                $this->job->releaseDelay,\n                \"Expected job to be released with delay of [{$delay}] seconds, but was released with delay of [{$this->job->releaseDelay}] seconds.\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the job was not released back onto the queue.\n     *\n     * @return $this\n     */\n    public function assertNotReleased()\n    {\n        $this->ensureQueueInteractionsHaveBeenFaked();\n\n        PHPUnit::assertTrue(\n            ! $this->job->isReleased(),\n            'Job was unexpectedly released.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Ensure that queue interactions have been faked.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    private function ensureQueueInteractionsHaveBeenFaked()\n    {\n        if (! $this->job instanceof FakeJob) {\n            throw new RuntimeException('Queue interactions have not been faked.');\n        }\n    }\n\n    /**\n     * Set the base queue job instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return $this\n     */\n    public function setJob(JobContract $job)\n    {\n        $this->job = $job;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/InvalidPayloadException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse InvalidArgumentException;\n\nclass InvalidPayloadException extends InvalidArgumentException\n{\n    /**\n     * The value that failed to decode.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  string|null  $message\n     * @param  mixed  $value\n     */\n    public function __construct($message = null, $value = null)\n    {\n        parent::__construct($message ?: json_last_error());\n\n        $this->value = $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/BeanstalkdJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\nuse Pheanstalk\\Contract\\JobIdInterface;\nuse Pheanstalk\\Pheanstalk;\n\nclass BeanstalkdJob extends Job implements JobContract\n{\n    /**\n     * The Pheanstalk instance.\n     *\n     * @var \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface\n     */\n    protected $pheanstalk;\n\n    /**\n     * The Pheanstalk job instance.\n     *\n     * @var \\Pheanstalk\\Job\n     */\n    protected $job;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface  $pheanstalk\n     * @param  \\Pheanstalk\\Contract\\JobIdInterface  $job\n     * @param  string  $connectionName\n     * @param  string  $queue\n     */\n    public function __construct(Container $container, $pheanstalk, JobIdInterface $job, $connectionName, $queue)\n    {\n        $this->job = $job;\n        $this->queue = $queue;\n        $this->container = $container;\n        $this->pheanstalk = $pheanstalk;\n        $this->connectionName = $connectionName;\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        parent::release($delay);\n\n        $priority = Pheanstalk::DEFAULT_PRIORITY;\n\n        $this->pheanstalk->release($this->job, $priority, $delay);\n    }\n\n    /**\n     * Bury the job in the queue.\n     *\n     * @return void\n     */\n    public function bury()\n    {\n        parent::release();\n\n        $this->pheanstalk->bury($this->job);\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        parent::delete();\n\n        $this->pheanstalk->delete($this->job);\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        $stats = $this->pheanstalk->statsJob($this->job);\n\n        return (int) $stats->reserves;\n    }\n\n    /**\n     * Get the job identifier.\n     *\n     * @return int\n     */\n    public function getJobId()\n    {\n        return $this->job->getId();\n    }\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return $this->job->getData();\n    }\n\n    /**\n     * Get the underlying Pheanstalk instance.\n     *\n     * @return \\Pheanstalk\\Contract\\PheanstalkManagerInterface&\\Pheanstalk\\Contract\\PheanstalkPublisherInterface&\\Pheanstalk\\Contract\\PheanstalkSubscriberInterface\n     */\n    public function getPheanstalk()\n    {\n        return $this->pheanstalk;\n    }\n\n    /**\n     * Get the underlying Pheanstalk job.\n     *\n     * @return \\Pheanstalk\\Contract\\JobIdInterface\n     */\n    public function getPheanstalkJob()\n    {\n        return $this->job;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/DatabaseJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\nuse Illuminate\\Queue\\DatabaseQueue;\n\nclass DatabaseJob extends Job implements JobContract\n{\n    /**\n     * The database queue instance.\n     *\n     * @var \\Illuminate\\Queue\\DatabaseQueue\n     */\n    protected $database;\n\n    /**\n     * The database job payload.\n     *\n     * @var \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord\n     */\n    protected $job;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Illuminate\\Queue\\DatabaseQueue  $database\n     * @param  \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord  $job\n     * @param  string  $connectionName\n     * @param  string  $queue\n     */\n    public function __construct(Container $container, DatabaseQueue $database, $job, $connectionName, $queue)\n    {\n        $this->job = $job;\n        $this->queue = $queue;\n        $this->database = $database;\n        $this->container = $container;\n        $this->connectionName = $connectionName;\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        parent::release($delay);\n\n        $this->database->deleteAndRelease($this->queue, $this, $delay);\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        parent::delete();\n\n        $this->database->deleteReserved($this->queue, $this->job->id);\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return (int) $this->job->attempts;\n    }\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string|int\n     */\n    public function getJobId()\n    {\n        return $this->job->id;\n    }\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return $this->job->payload;\n    }\n\n    /**\n     * Get the database job record.\n     *\n     * @return \\Illuminate\\Queue\\Jobs\\DatabaseJobRecord\n     */\n    public function getJobRecord()\n    {\n        return $this->job;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/DatabaseJobRecord.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass DatabaseJobRecord\n{\n    use InteractsWithTime;\n\n    /**\n     * The underlying job record.\n     *\n     * @var \\stdClass\n     */\n    protected $record;\n\n    /**\n     * Create a new job record instance.\n     *\n     * @param  \\stdClass  $record\n     */\n    public function __construct($record)\n    {\n        $this->record = $record;\n    }\n\n    /**\n     * Increment the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function increment()\n    {\n        $this->record->attempts++;\n\n        return $this->record->attempts;\n    }\n\n    /**\n     * Update the \"reserved at\" timestamp of the job.\n     *\n     * @return int\n     */\n    public function touch()\n    {\n        $this->record->reserved_at = $this->currentTime();\n\n        return $this->record->reserved_at;\n    }\n\n    /**\n     * Dynamically access the underlying job information.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->record->{$key};\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/FakeJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\nuse Illuminate\\Support\\Str;\n\nclass FakeJob extends Job implements JobContract\n{\n    /**\n     * The number of seconds the released job was delayed.\n     *\n     * @var int\n     */\n    public $releaseDelay;\n\n    /**\n     * The number of attempts made to process the job.\n     *\n     * @var int\n     */\n    public $attempts = 1;\n\n    /**\n     * The exception the job failed with.\n     *\n     * @var \\Throwable\n     */\n    public $failedWith;\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string\n     */\n    public function getJobId()\n    {\n        return once(fn () => (string) Str::uuid());\n    }\n\n    /**\n     * Get the raw body of the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return '';\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        $this->released = true;\n        $this->releaseDelay = $delay;\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return $this->attempts;\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        $this->deleted = true;\n    }\n\n    /**\n     * Delete the job, call the \"failed\" method, and raise the failed job event.\n     *\n     * @param  \\Throwable|null  $e\n     * @return void\n     */\n    public function fail($e = null)\n    {\n        $this->failed = true;\n        $this->failedWith = $e;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/Job.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Queue\\Events\\JobFailed;\nuse Illuminate\\Queue\\ManuallyFailedException;\nuse Illuminate\\Queue\\TimeoutExceededException;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Throwable;\n\nabstract class Job\n{\n    use InteractsWithTime;\n\n    /**\n     * The job handler instance.\n     *\n     * @var mixed\n     */\n    protected $instance;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Indicates if the job has been deleted.\n     *\n     * @var bool\n     */\n    protected $deleted = false;\n\n    /**\n     * Indicates if the job has been released.\n     *\n     * @var bool\n     */\n    protected $released = false;\n\n    /**\n     * Indicates if the job has failed.\n     *\n     * @var bool\n     */\n    protected $failed = false;\n\n    /**\n     * The name of the connection the job belongs to.\n     *\n     * @var string\n     */\n    protected $connectionName;\n\n    /**\n     * The name of the queue the job belongs to.\n     *\n     * @var string\n     */\n    protected $queue;\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string|int|null\n     */\n    abstract public function getJobId();\n\n    /**\n     * Get the raw body of the job.\n     *\n     * @return string\n     */\n    abstract public function getRawBody();\n\n    /**\n     * Get the UUID of the job.\n     *\n     * @return string|null\n     */\n    public function uuid()\n    {\n        return $this->payload()['uuid'] ?? null;\n    }\n\n    /**\n     * Fire the job.\n     *\n     * @return void\n     */\n    public function fire()\n    {\n        $payload = $this->payload();\n\n        [$class, $method] = JobName::parse($payload['job']);\n\n        ($this->instance = $this->resolve($class))->{$method}($this, $payload['data']);\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        $this->deleted = true;\n    }\n\n    /**\n     * Determine if the job has been deleted.\n     *\n     * @return bool\n     */\n    public function isDeleted()\n    {\n        return $this->deleted;\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        $this->released = true;\n    }\n\n    /**\n     * Determine if the job was released back into the queue.\n     *\n     * @return bool\n     */\n    public function isReleased()\n    {\n        return $this->released;\n    }\n\n    /**\n     * Determine if the job has been deleted or released.\n     *\n     * @return bool\n     */\n    public function isDeletedOrReleased()\n    {\n        return $this->isDeleted() || $this->isReleased();\n    }\n\n    /**\n     * Determine if the job has been marked as a failure.\n     *\n     * @return bool\n     */\n    public function hasFailed()\n    {\n        return $this->failed;\n    }\n\n    /**\n     * Mark the job as \"failed\".\n     *\n     * @return void\n     */\n    public function markAsFailed()\n    {\n        $this->failed = true;\n    }\n\n    /**\n     * Delete the job, call the \"failed\" method, and raise the failed job event.\n     *\n     * @param  \\Throwable|null  $e\n     * @return void\n     */\n    public function fail($e = null)\n    {\n        $this->markAsFailed();\n\n        if ($this->isDeleted()) {\n            return;\n        }\n\n        $commandName = $this->payload()['data']['commandName'] ?? false;\n\n        // If the exception is due to a job timing out, we need to rollback the current\n        // database transaction so that the failed job count can be incremented with\n        // the proper value. Otherwise, the current transaction will never commit.\n        if ($e instanceof TimeoutExceededException &&\n            $commandName &&\n            in_array(Batchable::class, class_uses_recursive($commandName))) {\n            $batchRepository = $this->resolve(BatchRepository::class);\n\n            try {\n                $batchRepository->rollBack();\n            } catch (Throwable $e) {\n                // ...\n            }\n        }\n\n        if ($this->shouldRollBackDatabaseTransaction($e)) {\n            $this->container->make('db')\n                ->connection($this->container['config']['queue.failed.database'])\n                ->rollBack(toLevel: 0);\n        }\n\n        try {\n            // If the job has failed, we will delete it, call the \"failed\" method and then call\n            // an event indicating the job has failed so it can be logged if needed. This is\n            // to allow every developer to better keep monitor of their failed queue jobs.\n            $this->delete();\n\n            $this->failed($e);\n        } finally {\n            $this->resolve(Dispatcher::class)->dispatch(new JobFailed(\n                $this->connectionName, $this, $e ?: new ManuallyFailedException\n            ));\n        }\n    }\n\n    /**\n     * Determine if the current database transaction should be rolled back to level zero.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function shouldRollBackDatabaseTransaction($e)\n    {\n        return $e instanceof TimeoutExceededException &&\n            $this->container['config']['queue.failed.database'] &&\n            in_array($this->container['config']['queue.failed.driver'], ['database', 'database-uuids']) &&\n            $this->container->bound('db');\n    }\n\n    /**\n     * Process an exception that caused the job to fail.\n     *\n     * @param  \\Throwable|null  $e\n     * @return void\n     */\n    protected function failed($e)\n    {\n        $payload = $this->payload();\n\n        [$class] = JobName::parse($payload['job']);\n\n        if (method_exists($this->instance = $this->resolve($class), 'failed')) {\n            $this->instance->failed($payload['data'], $e, $payload['uuid'] ?? '', $this);\n        }\n    }\n\n    /**\n     * Resolve the given class.\n     *\n     * @param  string  $class\n     * @return mixed\n     */\n    protected function resolve($class)\n    {\n        return $this->container->make($class);\n    }\n\n    /**\n     * Get the resolved job handler instance.\n     *\n     * @return mixed\n     */\n    public function getResolvedJob()\n    {\n        return $this->instance;\n    }\n\n    /**\n     * Get the decoded body of the job.\n     *\n     * @return array\n     */\n    public function payload()\n    {\n        return json_decode($this->getRawBody(), true);\n    }\n\n    /**\n     * Get the number of times to attempt a job.\n     *\n     * @return int|null\n     */\n    public function maxTries()\n    {\n        return $this->payload()['maxTries'] ?? null;\n    }\n\n    /**\n     * Get the number of times to attempt a job after an exception.\n     *\n     * @return int|null\n     */\n    public function maxExceptions()\n    {\n        return $this->payload()['maxExceptions'] ?? null;\n    }\n\n    /**\n     * Determine if the job should fail when it timeouts.\n     *\n     * @return bool\n     */\n    public function shouldFailOnTimeout()\n    {\n        return $this->payload()['failOnTimeout'] ?? false;\n    }\n\n    /**\n     * The number of seconds to wait before retrying a job that encountered an uncaught exception.\n     *\n     * @return int|int[]|null\n     */\n    public function backoff()\n    {\n        return $this->payload()['backoff'] ?? $this->payload()['delay'] ?? null;\n    }\n\n    /**\n     * Get the number of seconds the job can run.\n     *\n     * @return int|null\n     */\n    public function timeout()\n    {\n        return $this->payload()['timeout'] ?? null;\n    }\n\n    /**\n     * Get the timestamp indicating when the job should timeout.\n     *\n     * @return int|null\n     */\n    public function retryUntil()\n    {\n        return $this->payload()['retryUntil'] ?? null;\n    }\n\n    /**\n     * Get the name of the queued job class.\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->payload()['job'];\n    }\n\n    /**\n     * Get the resolved display name of the queued job class.\n     *\n     * Resolves the name of \"wrapped\" jobs such as class-based handlers.\n     *\n     * @return string\n     */\n    public function resolveName()\n    {\n        return JobName::resolve($this->getName(), $this->payload());\n    }\n\n    /**\n     * Get the class of the queued job.\n     *\n     * Resolves the class of \"wrapped\" jobs such as class-based handlers.\n     *\n     * @return string\n     */\n    public function resolveQueuedJobClass()\n    {\n        return JobName::resolveClassName($this->getName(), $this->payload());\n    }\n\n    /**\n     * Get the name of the connection the job belongs to.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n\n    /**\n     * Get the name of the queue the job belongs to.\n     *\n     * @return string\n     */\n    public function getQueue()\n    {\n        return $this->queue;\n    }\n\n    /**\n     * Get the service container instance.\n     *\n     * @return \\Illuminate\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/JobName.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Support\\Str;\n\nclass JobName\n{\n    /**\n     * Parse the given job name into a class / method array.\n     *\n     * @param  string  $job\n     * @return array\n     */\n    public static function parse($job)\n    {\n        return Str::parseCallback($job, 'fire');\n    }\n\n    /**\n     * Get the resolved name of the queued job class.\n     *\n     * @param  string  $name\n     * @param  array  $payload\n     * @return string\n     */\n    public static function resolve($name, $payload)\n    {\n        if (! empty($payload['displayName'])) {\n            return $payload['displayName'];\n        }\n\n        return $name;\n    }\n\n    /**\n     * Get the class name for queued job class.\n     *\n     * @param  string  $name\n     * @param  array<string, mixed>  $payload\n     * @return string\n     */\n    public static function resolveClassName($name, $payload)\n    {\n        if (is_string($payload['data']['commandName'] ?? null)) {\n            return $payload['data']['commandName'];\n        }\n\n        return $name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/RedisJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\nuse Illuminate\\Queue\\RedisQueue;\n\nclass RedisJob extends Job implements JobContract\n{\n    /**\n     * The Redis queue instance.\n     *\n     * @var \\Illuminate\\Queue\\RedisQueue\n     */\n    protected $redis;\n\n    /**\n     * The Redis raw job payload.\n     *\n     * @var string\n     */\n    protected $job;\n\n    /**\n     * The decoded JSON version of \"$job\".\n     *\n     * @var array\n     */\n    protected $decoded;\n\n    /**\n     * The Redis job payload inside the reserved queue.\n     *\n     * @var string\n     */\n    protected $reserved;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Illuminate\\Queue\\RedisQueue  $redis\n     * @param  string  $job\n     * @param  string  $reserved\n     * @param  string  $connectionName\n     * @param  string  $queue\n     */\n    public function __construct(Container $container, RedisQueue $redis, $job, $reserved, $connectionName, $queue)\n    {\n        // The $job variable is the original job JSON as it existed in the ready queue while\n        // the $reserved variable is the raw JSON in the reserved queue. The exact format\n        // of the reserved job is required in order for us to properly delete its data.\n        $this->job = $job;\n        $this->redis = $redis;\n        $this->queue = $queue;\n        $this->reserved = $reserved;\n        $this->container = $container;\n        $this->connectionName = $connectionName;\n\n        $this->decoded = $this->payload();\n    }\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return $this->job;\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        parent::delete();\n\n        $this->redis->deleteReserved($this->queue, $this);\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        parent::release($delay);\n\n        $this->redis->deleteAndRelease($this->queue, $this, $delay);\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return ($this->decoded['attempts'] ?? null) + 1;\n    }\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string|null\n     */\n    public function getJobId()\n    {\n        return $this->decoded['id'] ?? null;\n    }\n\n    /**\n     * Get the underlying Redis factory implementation.\n     *\n     * @return \\Illuminate\\Queue\\RedisQueue\n     */\n    public function getRedisQueue()\n    {\n        return $this->redis;\n    }\n\n    /**\n     * Get the underlying reserved Redis job.\n     *\n     * @return string\n     */\n    public function getReservedJob()\n    {\n        return $this->reserved;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/SqsJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Aws\\Sqs\\SqsClient;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\n\nclass SqsJob extends Job implements JobContract\n{\n    /**\n     * The Amazon SQS client instance.\n     *\n     * @var \\Aws\\Sqs\\SqsClient\n     */\n    protected $sqs;\n\n    /**\n     * The Amazon SQS job instance.\n     *\n     * @var array\n     */\n    protected $job;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Aws\\Sqs\\SqsClient  $sqs\n     * @param  array  $job\n     * @param  string  $connectionName\n     * @param  string  $queue\n     */\n    public function __construct(Container $container, SqsClient $sqs, array $job, $connectionName, $queue)\n    {\n        $this->sqs = $sqs;\n        $this->job = $job;\n        $this->queue = $queue;\n        $this->container = $container;\n        $this->connectionName = $connectionName;\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        parent::release($delay);\n\n        $this->sqs->changeMessageVisibility([\n            'QueueUrl' => $this->queue,\n            'ReceiptHandle' => $this->job['ReceiptHandle'],\n            'VisibilityTimeout' => $delay,\n        ]);\n    }\n\n    /**\n     * Delete the job from the queue.\n     *\n     * @return void\n     */\n    public function delete()\n    {\n        parent::delete();\n\n        $this->sqs->deleteMessage([\n            'QueueUrl' => $this->queue, 'ReceiptHandle' => $this->job['ReceiptHandle'],\n        ]);\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return (int) $this->job['Attributes']['ApproximateReceiveCount'];\n    }\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string\n     */\n    public function getJobId()\n    {\n        return $this->job['MessageId'];\n    }\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return $this->job['Body'];\n    }\n\n    /**\n     * Get the underlying SQS client instance.\n     *\n     * @return \\Aws\\Sqs\\SqsClient\n     */\n    public function getSqs()\n    {\n        return $this->sqs;\n    }\n\n    /**\n     * Get the underlying raw SQS job.\n     *\n     * @return array\n     */\n    public function getSqsJob()\n    {\n        return $this->job;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Jobs/SyncJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Jobs;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Job as JobContract;\n\nclass SyncJob extends Job implements JobContract\n{\n    /**\n     * The class name of the job.\n     *\n     * @var string\n     */\n    protected $job;\n\n    /**\n     * The queue message data.\n     *\n     * @var string\n     */\n    protected $payload;\n\n    /**\n     * Create a new job instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  string  $payload\n     * @param  string  $connectionName\n     * @param  string  $queue\n     */\n    public function __construct(Container $container, $payload, $connectionName, $queue)\n    {\n        $this->queue = $queue;\n        $this->payload = $payload;\n        $this->container = $container;\n        $this->connectionName = $connectionName;\n    }\n\n    /**\n     * Release the job back into the queue after (n) seconds.\n     *\n     * @param  int  $delay\n     * @return void\n     */\n    public function release($delay = 0)\n    {\n        parent::release($delay);\n    }\n\n    /**\n     * Get the number of times the job has been attempted.\n     *\n     * @return int\n     */\n    public function attempts()\n    {\n        return 1;\n    }\n\n    /**\n     * Get the job identifier.\n     *\n     * @return string\n     */\n    public function getJobId()\n    {\n        return '';\n    }\n\n    /**\n     * Get the raw body string for the job.\n     *\n     * @return string\n     */\n    public function getRawBody()\n    {\n        return $this->payload;\n    }\n\n    /**\n     * Get the name of the queue the job belongs to.\n     *\n     * @return string\n     */\n    public function getQueue()\n    {\n        return 'sync';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Queue/Listener.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Closure;\nuse Symfony\\Component\\Process\\Process;\n\nuse function Illuminate\\Support\\artisan_binary;\nuse function Illuminate\\Support\\php_binary;\n\nclass Listener\n{\n    /**\n     * The command working path.\n     *\n     * @var string\n     */\n    protected $commandPath;\n\n    /**\n     * The environment the workers should run under.\n     *\n     * @var string\n     */\n    protected $environment;\n\n    /**\n     * The amount of seconds to wait before polling the queue.\n     *\n     * @var int\n     */\n    protected $sleep = 3;\n\n    /**\n     * The number of times to try a job before logging it failed.\n     *\n     * @var int\n     */\n    protected $maxTries = 0;\n\n    /**\n     * The output handler callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $outputHandler;\n\n    /**\n     * Create a new queue listener.\n     *\n     * @param  string  $commandPath\n     */\n    public function __construct($commandPath)\n    {\n        $this->commandPath = $commandPath;\n    }\n\n    /**\n     * Get the PHP binary.\n     *\n     * @return string\n     */\n    protected function phpBinary()\n    {\n        return php_binary();\n    }\n\n    /**\n     * Get the Artisan binary.\n     *\n     * @return string\n     */\n    protected function artisanBinary()\n    {\n        return artisan_binary();\n    }\n\n    /**\n     * Listen to the given queue connection.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\ListenerOptions  $options\n     * @return void\n     */\n    public function listen($connection, $queue, ListenerOptions $options)\n    {\n        $process = $this->makeProcess($connection, $queue, $options);\n\n        while (true) {\n            $this->runProcess($process, $options->memory);\n\n            if ($options->rest) {\n                sleep($options->rest);\n            }\n        }\n    }\n\n    /**\n     * Create a new Symfony process for the worker.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\ListenerOptions  $options\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    public function makeProcess($connection, $queue, ListenerOptions $options)\n    {\n        $command = $this->createCommand(\n            $connection,\n            $queue,\n            $options\n        );\n\n        // If the environment is set, we will append it to the command array so the\n        // workers will run under the specified environment. Otherwise, they will\n        // just run under the production environment which is not always right.\n        if (isset($options->environment)) {\n            $command = $this->addEnvironment($command, $options);\n        }\n\n        return new Process(\n            $command,\n            $this->commandPath,\n            null,\n            null,\n            $options->timeout\n        );\n    }\n\n    /**\n     * Add the environment option to the given command.\n     *\n     * @param  array  $command\n     * @param  \\Illuminate\\Queue\\ListenerOptions  $options\n     * @return array\n     */\n    protected function addEnvironment($command, ListenerOptions $options)\n    {\n        return array_merge($command, [\"--env={$options->environment}\"]);\n    }\n\n    /**\n     * Create the command with the listener options.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\ListenerOptions  $options\n     * @return array\n     */\n    protected function createCommand($connection, $queue, ListenerOptions $options)\n    {\n        return array_filter([\n            $this->phpBinary(),\n            $this->artisanBinary(),\n            'queue:work',\n            $connection,\n            '--once',\n            \"--name={$options->name}\",\n            \"--queue={$queue}\",\n            \"--backoff={$options->backoff}\",\n            \"--memory={$options->memory}\",\n            \"--sleep={$options->sleep}\",\n            \"--tries={$options->maxTries}\",\n            $options->force ? '--force' : null,\n        ], function ($value) {\n            return ! is_null($value);\n        });\n    }\n\n    /**\n     * Run the given process.\n     *\n     * @param  \\Symfony\\Component\\Process\\Process  $process\n     * @param  int  $memory\n     * @return void\n     */\n    public function runProcess(Process $process, $memory)\n    {\n        $process->run(function ($type, $line) {\n            $this->handleWorkerOutput($type, $line);\n        });\n\n        // Once we have run the job we'll go check if the memory limit has been exceeded\n        // for the script. If it has, we will kill this script so the process manager\n        // will restart this with a clean slate of memory automatically on exiting.\n        if ($this->memoryExceeded($memory)) {\n            $this->stop();\n        }\n    }\n\n    /**\n     * Handle output from the worker process.\n     *\n     * @param  int  $type\n     * @param  string  $line\n     * @return void\n     */\n    protected function handleWorkerOutput($type, $line)\n    {\n        if (isset($this->outputHandler)) {\n            call_user_func($this->outputHandler, $type, $line);\n        }\n    }\n\n    /**\n     * Determine if the memory limit has been exceeded.\n     *\n     * @param  int  $memoryLimit\n     * @return bool\n     */\n    public function memoryExceeded($memoryLimit)\n    {\n        return (memory_get_usage(true) / 1024 / 1024) >= $memoryLimit;\n    }\n\n    /**\n     * Stop listening and bail out of the script.\n     *\n     * @return never\n     */\n    public function stop()\n    {\n        exit;\n    }\n\n    /**\n     * Set the output handler callback.\n     *\n     * @param  \\Closure  $outputHandler\n     * @return void\n     */\n    public function setOutputHandler(Closure $outputHandler)\n    {\n        $this->outputHandler = $outputHandler;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/ListenerOptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass ListenerOptions extends WorkerOptions\n{\n    /**\n     * The environment the worker should run in.\n     *\n     * @var string\n     */\n    public $environment;\n\n    /**\n     * Create a new listener options instance.\n     *\n     * @param  string  $name\n     * @param  string|null  $environment\n     * @param  int|int[]  $backoff\n     * @param  int  $memory\n     * @param  int  $timeout\n     * @param  int  $sleep\n     * @param  int  $maxTries\n     * @param  bool  $force\n     * @param  int  $rest\n     */\n    public function __construct($name = 'default', $environment = null, $backoff = 0, $memory = 128, $timeout = 60, $sleep = 3, $maxTries = 1, $force = false, $rest = 0)\n    {\n        $this->environment = $environment;\n\n        parent::__construct($name, $backoff, $memory, $timeout, $sleep, $maxTries, $force, false, 0, 0, $rest);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/LuaScripts.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass LuaScripts\n{\n    /**\n     * Get the Lua script for computing the size of queue.\n     *\n     * KEYS[1] - The name of the primary queue\n     * KEYS[2] - The name of the \"delayed\" queue\n     * KEYS[3] - The name of the \"reserved\" queue\n     *\n     * @return string\n     */\n    public static function size()\n    {\n        return <<<'LUA'\nreturn redis.call('llen', KEYS[1]) + redis.call('zcard', KEYS[2]) + redis.call('zcard', KEYS[3])\nLUA;\n    }\n\n    /**\n     * Get the Lua script for pushing jobs onto the queue.\n     *\n     * KEYS[1] - The queue to push the job onto, for example: queues:foo\n     * KEYS[2] - The notification list for the queue we are pushing jobs onto, for example: queues:foo:notify\n     * ARGV[1] - The job payload\n     *\n     * @return string\n     */\n    public static function push()\n    {\n        return <<<'LUA'\n-- Push the job onto the queue...\nredis.call('rpush', KEYS[1], ARGV[1])\n-- Push a notification onto the \"notify\" queue...\nredis.call('rpush', KEYS[2], 1)\nLUA;\n    }\n\n    /**\n     * Get the Lua script for pushing delayed jobs onto the queue.\n     *\n     * KEYS[1] - The delayed queue to push the job onto, for example: queues:foo:delayed\n     * ARGV[1] - The UNIX timestamp at which the job should become available\n     * ARGV[2] - The job payload\n     *\n     * @return string\n     */\n    public static function later()\n    {\n        return <<<'LUA'\n-- Push the job onto the delayed queue...\nredis.call('zadd', KEYS[1], ARGV[1], ARGV[2])\nLUA;\n    }\n\n    /**\n     * Get the Lua script for popping the next job off of the queue.\n     *\n     * KEYS[1] - The queue to pop jobs from, for example: queues:foo\n     * KEYS[2] - The queue to place reserved jobs on, for example: queues:foo:reserved\n     * KEYS[3] - The notify queue\n     * ARGV[1] - The time at which the reserved job will expire\n     *\n     * @return string\n     */\n    public static function pop()\n    {\n        return <<<'LUA'\n-- Pop the first job off of the queue...\nlocal job = redis.call('lpop', KEYS[1])\nlocal reserved = false\n\nif(job ~= false) then\n    -- Increment the attempt count and place job on the reserved queue...\n    reserved = cjson.decode(job)\n    reserved['attempts'] = reserved['attempts'] + 1\n    reserved = cjson.encode(reserved)\n    redis.call('zadd', KEYS[2], ARGV[1], reserved)\n    redis.call('lpop', KEYS[3])\nend\n\nreturn {job, reserved}\nLUA;\n    }\n\n    /**\n     * Get the Lua script for releasing reserved jobs.\n     *\n     * KEYS[1] - The \"delayed\" queue we release jobs onto, for example: queues:foo:delayed\n     * KEYS[2] - The queue the jobs are currently on, for example: queues:foo:reserved\n     * ARGV[1] - The raw payload of the job to add to the \"delayed\" queue\n     * ARGV[2] - The UNIX timestamp at which the job should become available\n     *\n     * @return string\n     */\n    public static function release()\n    {\n        return <<<'LUA'\n-- Remove the job from the current queue...\nredis.call('zrem', KEYS[2], ARGV[1])\n\n-- Add the job onto the \"delayed\" queue...\nredis.call('zadd', KEYS[1], ARGV[2], ARGV[1])\n\nreturn true\nLUA;\n    }\n\n    /**\n     * Get the Lua script to migrate expired jobs back onto the queue.\n     *\n     * KEYS[1] - The queue we are removing jobs from, for example: queues:foo:reserved\n     * KEYS[2] - The queue we are moving jobs to, for example: queues:foo\n     * KEYS[3] - The notification list for the queue we are moving jobs to, for example queues:foo:notify\n     * ARGV[1] - The current UNIX timestamp\n     *\n     * @return string\n     */\n    public static function migrateExpiredJobs()\n    {\n        return <<<'LUA'\n-- Get all of the jobs with an expired \"score\"...\nlocal val = redis.call('zrangebyscore', KEYS[1], '-inf', ARGV[1], 'limit', 0, ARGV[2])\n\n-- If we have values in the array, we will remove them from the first queue\n-- and add them onto the destination queue in chunks of 100, which moves\n-- all of the appropriate jobs onto the destination queue very safely.\nif(next(val) ~= nil) then\n    redis.call('zremrangebyrank', KEYS[1], 0, #val - 1)\n\n    for i = 1, #val, 100 do\n        redis.call('rpush', KEYS[2], unpack(val, i, math.min(i+99, #val)))\n        -- Push a notification for every job that was migrated...\n        for j = i, math.min(i+99, #val) do\n            redis.call('rpush', KEYS[3], 1)\n        end\n    end\nend\n\nreturn val\nLUA;\n    }\n\n    /**\n     * Get the Lua script for removing all jobs from the queue.\n     *\n     * KEYS[1] - The name of the primary queue\n     * KEYS[2] - The name of the \"delayed\" queue\n     * KEYS[3] - The name of the \"reserved\" queue\n     * KEYS[4] - The name of the \"notify\" queue\n     *\n     * @return string\n     */\n    public static function clear()\n    {\n        return <<<'LUA'\nlocal size = redis.call('llen', KEYS[1]) + redis.call('zcard', KEYS[2]) + redis.call('zcard', KEYS[3])\nredis.call('del', KEYS[1], KEYS[2], KEYS[3], KEYS[4])\nreturn size\nLUA;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/ManuallyFailedException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse RuntimeException;\n\nclass ManuallyFailedException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/MaxAttemptsExceededException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse RuntimeException;\n\nclass MaxAttemptsExceededException extends RuntimeException\n{\n    /**\n     * The job instance.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public $job;\n\n    /**\n     * Create a new instance for the job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return static\n     */\n    public static function forJob($job)\n    {\n        return tap(new static($job->resolveName().' has been attempted too many times.'), function ($e) use ($job) {\n            $e->job = $job;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/FailOnException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Closure;\nuse Throwable;\n\nclass FailOnException\n{\n    /**\n     * The truth-test callback to determine if the job should fail.\n     *\n     * @var \\Closure(\\Throwable, mixed): bool\n     */\n    protected Closure $callback;\n\n    /**\n     * Create a middleware instance.\n     *\n     * @param  (\\Closure(\\Throwable, mixed): bool)|array<array-key, class-string<\\Throwable>>  $callback\n     */\n    public function __construct($callback)\n    {\n        if (is_array($callback)) {\n            $callback = $this->failForExceptions($callback);\n        }\n\n        $this->callback = $callback;\n    }\n\n    /**\n     * Indicate that the job should fail if it encounters the given exceptions.\n     *\n     * @param  array<array-key, class-string<\\Throwable>>  $exceptions\n     * @return \\Closure(\\Throwable, mixed): bool\n     */\n    protected function failForExceptions(array $exceptions)\n    {\n        return static function (Throwable $throwable) use ($exceptions) {\n            foreach ($exceptions as $exception) {\n                if ($throwable instanceof $exception) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    /**\n     * Mark the job as failed if an exception is thrown that passes a truth-test callback.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function handle($job, callable $next)\n    {\n        try {\n            return $next($job);\n        } catch (Throwable $e) {\n            if (call_user_func($this->callback, $e, $job) === true) {\n                $job->fail($e);\n            }\n\n            throw $e;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/RateLimited.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Unlimited;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass RateLimited\n{\n    /**\n     * The rate limiter instance.\n     *\n     * @var \\Illuminate\\Cache\\RateLimiter\n     */\n    protected $limiter;\n\n    /**\n     * The name of the rate limiter.\n     *\n     * @var string\n     */\n    protected $limiterName;\n\n    /**\n     * The number of seconds before a job should be available again if the limit is exceeded.\n     *\n     * @var \\DateTimeInterface|int|null\n     */\n    public $releaseAfter;\n\n    /**\n     * Indicates if the job should be released if the limit is exceeded.\n     *\n     * @var bool\n     */\n    public $shouldRelease = true;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\UnitEnum|string  $limiterName\n     */\n    public function __construct($limiterName)\n    {\n        $this->limiter = Container::getInstance()->make(RateLimiter::class);\n\n        $this->limiterName = (string) enum_value($limiterName);\n    }\n\n    /**\n     * Process the job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     */\n    public function handle($job, $next)\n    {\n        if (is_null($limiter = $this->limiter->limiter($this->limiterName))) {\n            return $next($job);\n        }\n\n        $limiterResponse = $limiter($job);\n\n        if ($limiterResponse instanceof Unlimited) {\n            return $next($job);\n        }\n\n        return $this->handleJob(\n            $job,\n            $next,\n            Collection::wrap($limiterResponse)->map(function ($limit) {\n                return (object) [\n                    'key' => md5($this->limiterName.$limit->key),\n                    'maxAttempts' => $limit->maxAttempts,\n                    'decaySeconds' => $limit->decaySeconds,\n                ];\n            })->all()\n        );\n    }\n\n    /**\n     * Handle a rate limited job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @param  array  $limits\n     * @return mixed\n     */\n    protected function handleJob($job, $next, array $limits)\n    {\n        foreach ($limits as $limit) {\n            if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {\n                return $this->shouldRelease\n                    ? $job->release($this->releaseAfter ?: $this->getTimeUntilNextRetry($limit->key))\n                    : false;\n            }\n\n            $this->limiter->hit($limit->key, $limit->decaySeconds);\n        }\n\n        return $next($job);\n    }\n\n    /**\n     * Set the delay (in seconds) to release the job back to the queue.\n     *\n     * @param  \\DateTimeInterface|int  $releaseAfter\n     * @return $this\n     */\n    public function releaseAfter($releaseAfter)\n    {\n        $this->releaseAfter = $releaseAfter;\n\n        return $this;\n    }\n\n    /**\n     * Do not release the job back to the queue if the limit is exceeded.\n     *\n     * @return $this\n     */\n    public function dontRelease()\n    {\n        $this->shouldRelease = false;\n\n        return $this;\n    }\n\n    /**\n     * Get the number of seconds that should elapse before the job is retried.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getTimeUntilNextRetry($key)\n    {\n        return $this->limiter->availableIn($key) + 3;\n    }\n\n    /**\n     * Prepare the object for serialization.\n     *\n     * @return array\n     */\n    public function __sleep()\n    {\n        return [\n            'limiterName',\n            'shouldRelease',\n        ];\n    }\n\n    /**\n     * Prepare the object after unserialization.\n     *\n     * @return void\n     */\n    public function __wakeup()\n    {\n        $this->limiter = Container::getInstance()->make(RateLimiter::class);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/RateLimitedWithRedis.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Redis\\Limiters\\DurationLimiter;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass RateLimitedWithRedis extends RateLimited\n{\n    use InteractsWithTime;\n\n    /**\n     * The name of the Redis connection that should be used.\n     *\n     * @var string|null\n     */\n    protected $connectionName = null;\n\n    /**\n     * The timestamp of the end of the current duration by key.\n     *\n     * @var array\n     */\n    public $decaysAt = [];\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  string  $limiterName\n     */\n    public function __construct($limiterName, ?string $connection = null)\n    {\n        parent::__construct($limiterName);\n\n        $this->connectionName = $connection;\n    }\n\n    /**\n     * Handle a rate limited job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @param  array  $limits\n     * @return mixed\n     */\n    protected function handleJob($job, $next, array $limits)\n    {\n        foreach ($limits as $limit) {\n            if ($this->tooManyAttempts($limit->key, $limit->maxAttempts, $limit->decaySeconds)) {\n                return $this->shouldRelease\n                    ? $job->release($this->releaseAfter ?: $this->getTimeUntilNextRetry($limit->key))\n                    : false;\n            }\n        }\n\n        return $next($job);\n    }\n\n    /**\n     * Determine if the given key has been \"accessed\" too many times.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     * @return bool\n     */\n    protected function tooManyAttempts($key, $maxAttempts, $decaySeconds)\n    {\n        $redis = Container::getInstance()\n            ->make(Redis::class)\n            ->connection($this->connectionName);\n\n        $limiter = new DurationLimiter(\n            $redis, $key, $maxAttempts, $decaySeconds\n        );\n\n        return tap(! $limiter->acquire(), function () use ($key, $limiter) {\n            $this->decaysAt[$key] = $limiter->decaysAt;\n        });\n    }\n\n    /**\n     * Get the number of seconds that should elapse before the job is retried.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getTimeUntilNextRetry($key)\n    {\n        return ($this->decaysAt[$key] - $this->currentTime()) + 3;\n    }\n\n    /**\n     * Specify the Redis connection that should be used.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function connection(string $name)\n    {\n        $this->connectionName = $name;\n\n        return $this;\n    }\n\n    /**\n     * Prepare the object for serialization.\n     *\n     * @return array\n     */\n    public function __sleep()\n    {\n        return array_merge(parent::__sleep(), ['connectionName']);\n    }\n\n    /**\n     * Prepare the object after unserialization.\n     *\n     * @return void\n     */\n    public function __wakeup()\n    {\n        parent::__wakeup();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/Skip.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Closure;\n\nclass Skip\n{\n    public function __construct(protected bool $skip = false)\n    {\n    }\n\n    /**\n     * Apply the middleware if the given condition is truthy.\n     *\n     * @param  bool|Closure(): bool  $condition\n     */\n    public static function when(Closure|bool $condition): self\n    {\n        return new self(value($condition));\n    }\n\n    /**\n     * Apply the middleware unless the given condition is truthy.\n     *\n     * @param  bool|Closure(): bool  $condition\n     */\n    public static function unless(Closure|bool $condition): self\n    {\n        return new self(! value($condition));\n    }\n\n    /**\n     * Handle the job.\n     */\n    public function handle(mixed $job, callable $next): mixed\n    {\n        if ($this->skip) {\n            return false;\n        }\n\n        return $next($job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/SkipIfBatchCancelled.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nclass SkipIfBatchCancelled\n{\n    /**\n     * Process the job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     */\n    public function handle($job, $next)\n    {\n        if (method_exists($job, 'batch') && $job->batch()?->cancelled()) {\n            return;\n        }\n\n        $next($job);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/ThrottlesExceptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Container\\Container;\nuse Throwable;\n\nclass ThrottlesExceptions\n{\n    /**\n     * The developer specified key that the rate limiter should use.\n     *\n     * @var string\n     */\n    protected $key;\n\n    /**\n     * Indicates whether the throttle key should use the job's UUID.\n     *\n     * @var bool\n     */\n    protected $byJob = false;\n\n    /**\n     * The maximum number of attempts allowed before rate limiting applies.\n     *\n     * @var int\n     */\n    protected $maxAttempts;\n\n    /**\n     * The number of seconds until the maximum attempts are reset.\n     *\n     * @var int\n     */\n    protected $decaySeconds;\n\n    /**\n     * The number of minutes to wait before retrying the job after an exception.\n     *\n     * @var int\n     */\n    protected $retryAfterMinutes = 0;\n\n    /**\n     * The callback that determines if the exception should be reported.\n     *\n     * @var callable\n     */\n    protected $reportCallback;\n\n    /**\n     * The callback that determines if rate limiting should apply.\n     *\n     * @var callable\n     */\n    protected $whenCallback;\n\n    /**\n     * The callbacks that determine if the job should be deleted.\n     *\n     * @var callable[]\n     */\n    protected array $deleteWhenCallbacks = [];\n\n    /**\n     * The callbacks that determine if the job should be failed.\n     *\n     * @var callable[]\n     */\n    protected array $failWhenCallbacks = [];\n\n    /**\n     * The prefix of the rate limiter key.\n     *\n     * @var string\n     */\n    protected $prefix = 'laravel_throttles_exceptions:';\n\n    /**\n     * The rate limiter instance.\n     *\n     * @var \\Illuminate\\Cache\\RateLimiter\n     */\n    protected $limiter;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     */\n    public function __construct($maxAttempts = 10, $decaySeconds = 600)\n    {\n        $this->maxAttempts = $maxAttempts;\n        $this->decaySeconds = $decaySeconds;\n    }\n\n    /**\n     * Process the job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function handle($job, $next)\n    {\n        $this->limiter = Container::getInstance()->make(RateLimiter::class);\n\n        if ($this->limiter->tooManyAttempts($jobKey = $this->getKey($job), $this->maxAttempts)) {\n            return $job->release($this->getTimeUntilNextRetry($jobKey));\n        }\n\n        try {\n            $next($job);\n\n            $this->limiter->clear($jobKey);\n        } catch (Throwable $throwable) {\n            if ($this->whenCallback && ! call_user_func($this->whenCallback, $throwable, $this->limiter)) {\n                throw $throwable;\n            }\n\n            if ($this->reportCallback && call_user_func($this->reportCallback, $throwable, $this->limiter)) {\n                report($throwable);\n            }\n\n            if ($this->shouldDelete($throwable)) {\n                return $job->delete();\n            }\n\n            if ($this->shouldFail($throwable)) {\n                return $job->fail($throwable);\n            }\n\n            $this->limiter->hit($jobKey, $this->decaySeconds);\n\n            return $job->release($this->retryAfterMinutes * 60);\n        }\n    }\n\n    /**\n     * Specify a callback that should determine if rate limiting behavior should apply.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function when(callable $callback)\n    {\n        $this->whenCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Add a callback that should determine if the job should be deleted.\n     *\n     * @param  callable|string  $callback\n     * @return $this\n     */\n    public function deleteWhen(callable|string $callback)\n    {\n        $this->deleteWhenCallbacks[] = is_string($callback)\n            ? fn (Throwable $e) => $e instanceof $callback\n            : $callback;\n\n        return $this;\n    }\n\n    /**\n     * Add a callback that should determine if the job should be failed.\n     *\n     * @param  callable|string  $callback\n     * @return $this\n     */\n    public function failWhen(callable|string $callback)\n    {\n        $this->failWhenCallbacks[] = is_string($callback)\n            ? fn (Throwable $e) => $e instanceof $callback\n            : $callback;\n\n        return $this;\n    }\n\n    /**\n     * Run the skip / delete callbacks to determine if the job should be deleted for the given exception.\n     *\n     * @param  \\Throwable  $throwable\n     * @return bool\n     */\n    protected function shouldDelete(Throwable $throwable): bool\n    {\n        foreach ($this->deleteWhenCallbacks as $callback) {\n            if (call_user_func($callback, $throwable)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Run the skip / fail callbacks to determine if the job should be failed for the given exception.\n     *\n     * @param  \\Throwable  $throwable\n     * @return bool\n     */\n    protected function shouldFail(Throwable $throwable): bool\n    {\n        foreach ($this->failWhenCallbacks as $callback) {\n            if (call_user_func($callback, $throwable)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Set the prefix of the rate limiter key.\n     *\n     * @param  string  $prefix\n     * @return $this\n     */\n    public function withPrefix(string $prefix)\n    {\n        $this->prefix = $prefix;\n\n        return $this;\n    }\n\n    /**\n     * Specify the number of minutes a job should be delayed when it is released (before it has reached its max exceptions).\n     *\n     * @param  int  $backoff\n     * @return $this\n     */\n    public function backoff($backoff)\n    {\n        $this->retryAfterMinutes = $backoff;\n\n        return $this;\n    }\n\n    /**\n     * Get the cache key associated for the rate limiter.\n     *\n     * @param  mixed  $job\n     * @return string\n     */\n    protected function getKey($job)\n    {\n        if ($this->key) {\n            return $this->prefix.$this->key;\n        } elseif ($this->byJob) {\n            return $this->prefix.$job->job->uuid();\n        }\n\n        $jobName = method_exists($job, 'displayName')\n            ? $job->displayName()\n            : get_class($job);\n\n        return $this->prefix.hash('xxh128', $jobName);\n    }\n\n    /**\n     * Set the value that the rate limiter should be keyed by.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function by($key)\n    {\n        $this->key = $key;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the throttle key should use the job's UUID.\n     *\n     * @return $this\n     */\n    public function byJob()\n    {\n        $this->byJob = true;\n\n        return $this;\n    }\n\n    /**\n     * Report exceptions and optionally specify a callback that determines if the exception should be reported.\n     *\n     * @param  callable|null  $callback\n     * @return $this\n     */\n    public function report(?callable $callback = null)\n    {\n        $this->reportCallback = $callback ?? fn () => true;\n\n        return $this;\n    }\n\n    /**\n     * Get the number of seconds that should elapse before the job is retried.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getTimeUntilNextRetry($key)\n    {\n        return $this->limiter->availableIn($key) + 3;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/ThrottlesExceptionsWithRedis.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Redis\\Connection;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Redis\\Limiters\\DurationLimiter;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Throwable;\n\nclass ThrottlesExceptionsWithRedis extends ThrottlesExceptions\n{\n    use InteractsWithTime;\n\n    /**\n     * The Redis connection instance.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Connection\n     */\n    protected $redis;\n\n    /**\n     * The Redis connection that should be used.\n     *\n     * @var string|null\n     */\n    protected $connectionName = null;\n\n    /**\n     * The rate limiter instance.\n     *\n     * @var \\Illuminate\\Redis\\Limiters\\DurationLimiter\n     */\n    protected $limiter;\n\n    /**\n     * Process the job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function handle($job, $next)\n    {\n        $this->redis = Container::getInstance()\n            ->make(Redis::class)\n            ->connection($this->connectionName);\n\n        $this->limiter = new DurationLimiter(\n            $this->redis, $this->getKey($job), $this->maxAttempts, $this->decaySeconds\n        );\n\n        if ($this->limiter->tooManyAttempts()) {\n            return $job->release($this->limiter->decaysAt - $this->currentTime());\n        }\n\n        try {\n            $next($job);\n\n            $this->limiter->clear();\n        } catch (Throwable $throwable) {\n            if ($this->whenCallback && ! call_user_func($this->whenCallback, $throwable, $this->limiter)) {\n                throw $throwable;\n            }\n\n            if ($this->reportCallback && call_user_func($this->reportCallback, $throwable, $this->limiter)) {\n                report($throwable);\n            }\n\n            if ($this->shouldDelete($throwable)) {\n                return $job->delete();\n            }\n\n            if ($this->shouldFail($throwable)) {\n                return $job->fail($throwable);\n            }\n\n            $this->limiter->acquire();\n\n            return $job->release($this->retryAfterMinutes * 60);\n        }\n    }\n\n    /**\n     * Specify the Redis connection that should be used.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function connection(string $name)\n    {\n        $this->connectionName = $name;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Middleware/WithoutOverlapping.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass WithoutOverlapping\n{\n    use InteractsWithTime;\n\n    /**\n     * The job's unique key used for preventing overlaps.\n     *\n     * @var string\n     */\n    public $key;\n\n    /**\n     * The number of seconds before a job should be available again if no lock was acquired.\n     *\n     * @var \\DateTimeInterface|int|null\n     */\n    public $releaseAfter;\n\n    /**\n     * The number of seconds before the lock should expire.\n     *\n     * @var int\n     */\n    public $expiresAfter;\n\n    /**\n     * The prefix of the lock key.\n     *\n     * @var string\n     */\n    public $prefix = 'laravel-queue-overlap:';\n\n    /**\n     * Share the key across different jobs.\n     *\n     * @var bool\n     */\n    public $shareKey = false;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  string  $key\n     * @param  \\DateTimeInterface|int|null  $releaseAfter\n     * @param  \\DateTimeInterface|int  $expiresAfter\n     */\n    public function __construct($key = '', $releaseAfter = 0, $expiresAfter = 0)\n    {\n        $this->key = $key;\n        $this->releaseAfter = $releaseAfter;\n        $this->expiresAfter = $this->secondsUntil($expiresAfter);\n    }\n\n    /**\n     * Process the job.\n     *\n     * @param  mixed  $job\n     * @param  callable  $next\n     * @return mixed\n     */\n    public function handle($job, $next)\n    {\n        $lock = Container::getInstance()->make(Cache::class)->lock(\n            $this->getLockKey($job), $this->expiresAfter\n        );\n\n        if ($lock->get()) {\n            try {\n                $next($job);\n            } finally {\n                $lock->release();\n            }\n        } elseif (! is_null($this->releaseAfter)) {\n            $job->release($this->releaseAfter);\n        }\n    }\n\n    /**\n     * Set the delay (in seconds) to release the job back to the queue.\n     *\n     * @param  \\DateTimeInterface|int  $releaseAfter\n     * @return $this\n     */\n    public function releaseAfter($releaseAfter)\n    {\n        $this->releaseAfter = $releaseAfter;\n\n        return $this;\n    }\n\n    /**\n     * Do not release the job back to the queue if no lock can be acquired.\n     *\n     * @return $this\n     */\n    public function dontRelease()\n    {\n        $this->releaseAfter = null;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum number of seconds that can elapse before the lock is released.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $expiresAfter\n     * @return $this\n     */\n    public function expireAfter($expiresAfter)\n    {\n        $this->expiresAfter = $this->secondsUntil($expiresAfter);\n\n        return $this;\n    }\n\n    /**\n     * Set the prefix of the lock key.\n     *\n     * @param  string  $prefix\n     * @return $this\n     */\n    public function withPrefix(string $prefix)\n    {\n        $this->prefix = $prefix;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the lock key should be shared across job classes.\n     *\n     * @return $this\n     */\n    public function shared()\n    {\n        $this->shareKey = true;\n\n        return $this;\n    }\n\n    /**\n     * Get the lock key for the given job.\n     *\n     * @param  mixed  $job\n     * @return string\n     */\n    public function getLockKey($job)\n    {\n        if ($this->shareKey) {\n            return $this->prefix.$this->key;\n        }\n\n        $jobName = method_exists($job, 'displayName')\n            ? hash('xxh128', $job->displayName())\n            : get_class($job);\n\n        return $this->prefix.$jobName.':'.$this->key;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/NullQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\n\nclass NullQueue extends Queue implements QueueContract\n{\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        return null;\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        //\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        //\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        //\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Queue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Closure;\nuse DateTimeInterface;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Contracts\\Queue\\ShouldBeEncrypted;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Queue\\Attributes\\Backoff;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\Attributes\\FailOnTimeout;\nuse Illuminate\\Queue\\Attributes\\MaxExceptions;\nuse Illuminate\\Queue\\Attributes\\ReadsQueueAttributes;\nuse Illuminate\\Queue\\Attributes\\Timeout;\nuse Illuminate\\Queue\\Attributes\\Tries;\nuse Illuminate\\Queue\\Events\\JobQueued;\nuse Illuminate\\Queue\\Events\\JobQueueing;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse RuntimeException;\nuse Throwable;\n\nabstract class Queue\n{\n    use InteractsWithTime, ReadsQueueAttributes;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The connection name for the queue.\n     *\n     * @var string\n     */\n    protected $connectionName;\n\n    /**\n     * The original configuration for the queue.\n     *\n     * @var array\n     */\n    protected $config;\n\n    /**\n     * Indicates that jobs should be dispatched after all database transactions have committed.\n     *\n     * @var bool\n     */\n    protected $dispatchAfterCommit;\n\n    /**\n     * The create payload callbacks.\n     *\n     * @var callable[]\n     */\n    protected static $createPayloadCallbacks = [];\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $queue\n     * @param  string  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function pushOn($queue, $job, $data = '')\n    {\n        return $this->push($job, $data, $queue);\n    }\n\n    /**\n     * Push a new job onto a specific queue after (n) seconds.\n     *\n     * @param  string  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function laterOn($queue, $delay, $job, $data = '')\n    {\n        return $this->later($delay, $job, $data, $queue);\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return void\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        foreach ((array) $jobs as $job) {\n            $this->push($job, $data, $queue);\n        }\n    }\n\n    /**\n     * Create a payload string from the given job and data.\n     *\n     * @param  \\Closure|string|object  $job\n     * @param  string  $queue\n     * @param  mixed  $data\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return string\n     *\n     * @throws \\Illuminate\\Queue\\InvalidPayloadException\n     */\n    protected function createPayload($job, $queue, $data = '', $delay = null)\n    {\n        if ($job instanceof Closure) {\n            $job = CallQueuedClosure::create($job);\n        }\n\n        $value = $this->createPayloadArray($job, $queue, $data);\n\n        $value['delay'] = isset($delay)\n            ? $this->secondsUntil($delay)\n            : null;\n\n        $payload = json_encode($value, \\JSON_UNESCAPED_UNICODE);\n\n        if (json_last_error() !== JSON_ERROR_NONE) {\n            throw new InvalidPayloadException(\n                'Unable to JSON encode payload. Error ('.json_last_error().'): '.json_last_error_msg(), $value\n            );\n        }\n\n        return $payload;\n    }\n\n    /**\n     * Create a payload array from the given job and data.\n     *\n     * @param  string|object  $job\n     * @param  string  $queue\n     * @param  mixed  $data\n     * @return array\n     */\n    protected function createPayloadArray($job, $queue, $data = '')\n    {\n        return is_object($job)\n            ? $this->createObjectPayload($job, $queue)\n            : $this->createStringPayload($job, $queue, $data);\n    }\n\n    /**\n     * Create a payload for an object-based queue handler.\n     *\n     * @param  object  $job\n     * @param  string  $queue\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    protected function createObjectPayload($job, $queue)\n    {\n        $payload = $this->withCreatePayloadHooks($queue, [\n            'uuid' => (string) Str::uuid(),\n            'displayName' => $this->getDisplayName($job),\n            'job' => 'Illuminate\\Queue\\CallQueuedHandler@call',\n            'maxTries' => $this->getJobTries($job),\n            'maxExceptions' => $this->getAttributeValue($job, MaxExceptions::class, 'maxExceptions'),\n            'failOnTimeout' => $this->getAttributeValue($job, FailOnTimeout::class, 'failOnTimeout') ?? false,\n            'backoff' => $this->getJobBackoff($job),\n            'timeout' => $this->getAttributeValue($job, Timeout::class, 'timeout'),\n            'retryUntil' => $this->getJobExpiration($job),\n            'deleteWhenMissingModels' => $this->getAttributeValue($job, DeleteWhenMissingModels::class, 'deleteWhenMissingModels') ?? false,\n            'data' => [\n                'commandName' => $job,\n                'command' => $job,\n                'batchId' => $job->batchId ?? null,\n            ],\n            'createdAt' => Carbon::now()->getTimestamp(),\n        ]);\n\n        try {\n            $command = $this->jobShouldBeEncrypted($job) && $this->container->bound(Encrypter::class)\n                ? $this->container[Encrypter::class]->encrypt(serialize(clone $job))\n                : serialize(clone $job);\n        } catch (Throwable $e) {\n            throw new RuntimeException(\n                sprintf('Failed to serialize job of type [%s]: %s', get_class($job), $e->getMessage()),\n                0,\n                $e\n            );\n        }\n\n        return array_merge($payload, [\n            'data' => array_merge($payload['data'], [\n                'commandName' => get_class($job),\n                'command' => $command,\n            ]),\n        ]);\n    }\n\n    /**\n     * Get the display name for the given job.\n     *\n     * @param  object  $job\n     * @return string\n     */\n    protected function getDisplayName($job)\n    {\n        return method_exists($job, 'displayName')\n            ? $job->displayName()\n            : get_class($job);\n    }\n\n    /**\n     * Get the maximum number of attempts for an object-based queue handler.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    public function getJobTries($job)\n    {\n        $tries = $this->getAttributeValue($job, Tries::class, 'tries');\n\n        if (method_exists($job, 'tries')) {\n            $tries = $job->tries();\n        }\n\n        return $tries;\n    }\n\n    /**\n     * Get the backoff for an object-based queue handler.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    public function getJobBackoff($job)\n    {\n        $backoff = $this->getAttributeValue($job, Backoff::class, 'backoff');\n\n        if (method_exists($job, 'backoff')) {\n            $backoff = $job->backoff();\n        }\n\n        if (is_null($backoff)) {\n            return;\n        }\n\n        return Collection::wrap($backoff)\n            ->map(fn ($backoff) => $backoff instanceof DateTimeInterface ? $this->secondsUntil($backoff) : $backoff)\n            ->implode(',');\n    }\n\n    /**\n     * Get the expiration timestamp for an object-based queue handler.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    public function getJobExpiration($job)\n    {\n        if (! method_exists($job, 'retryUntil') && ! isset($job->retryUntil)) {\n            return;\n        }\n\n        $expiration = $job->retryUntil ?? $job->retryUntil();\n\n        return $expiration instanceof DateTimeInterface\n            ? $expiration->getTimestamp()\n            : $expiration;\n    }\n\n    /**\n     * Determine if the job should be encrypted.\n     *\n     * @param  object  $job\n     * @return bool\n     */\n    protected function jobShouldBeEncrypted($job)\n    {\n        if ($job instanceof ShouldBeEncrypted) {\n            return true;\n        }\n\n        return isset($job->shouldBeEncrypted) && $job->shouldBeEncrypted;\n    }\n\n    /**\n     * Create a typical, string based queue payload array.\n     *\n     * @param  string  $job\n     * @param  string  $queue\n     * @param  mixed  $data\n     * @return array\n     */\n    protected function createStringPayload($job, $queue, $data)\n    {\n        return $this->withCreatePayloadHooks($queue, [\n            'uuid' => (string) Str::uuid(),\n            'displayName' => is_string($job) ? explode('@', $job)[0] : null,\n            'job' => $job,\n            'maxTries' => null,\n            'maxExceptions' => null,\n            'failOnTimeout' => false,\n            'backoff' => null,\n            'timeout' => null,\n            'data' => $data,\n            'createdAt' => Carbon::now()->getTimestamp(),\n        ]);\n    }\n\n    /**\n     * Register a callback to be executed when creating job payloads.\n     *\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public static function createPayloadUsing($callback)\n    {\n        if (is_null($callback)) {\n            static::$createPayloadCallbacks = [];\n        } else {\n            static::$createPayloadCallbacks[] = $callback;\n        }\n    }\n\n    /**\n     * Create the given payload using any registered payload hooks.\n     *\n     * @param  string  $queue\n     * @return array\n     */\n    protected function withCreatePayloadHooks($queue, array $payload)\n    {\n        if (! empty(static::$createPayloadCallbacks)) {\n            foreach (static::$createPayloadCallbacks as $callback) {\n                $payload = array_merge($payload, $callback($this->getConnectionName(), $queue, $payload));\n            }\n        }\n\n        return $payload;\n    }\n\n    /**\n     * Enqueue a job using the given callback.\n     *\n     * @param  \\Closure|string|object  $job\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @param  callable  $callback\n     * @return mixed\n     */\n    protected function enqueueUsing($job, $payload, $queue, $delay, $callback)\n    {\n        if ($this->shouldDispatchAfterCommit($job) &&\n            $this->container->bound('db.transactions')) {\n            if ($job instanceof ShouldBeUnique) {\n                $this->container->make('db.transactions')->addCallbackForRollback(\n                    function () use ($job) {\n                        (new UniqueLock($this->container->make(Cache::class)))->release($job);\n                    }\n                );\n            }\n\n            return $this->container->make('db.transactions')->addCallback(\n                function () use ($queue, $job, $payload, $delay, $callback) {\n                    $this->raiseJobQueueingEvent($queue, $job, $payload, $delay);\n\n                    return tap($callback($payload, $queue, $delay), function ($jobId) use ($queue, $job, $payload, $delay) {\n                        $this->raiseJobQueuedEvent($queue, $jobId, $job, $payload, $delay);\n                    });\n                }\n            );\n        }\n\n        $this->raiseJobQueueingEvent($queue, $job, $payload, $delay);\n\n        return tap($callback($payload, $queue, $delay), function ($jobId) use ($queue, $job, $payload, $delay) {\n            $this->raiseJobQueuedEvent($queue, $jobId, $job, $payload, $delay);\n        });\n    }\n\n    /**\n     * Determine if the job should be dispatched after all database transactions have committed.\n     *\n     * @param  \\Closure|string|object  $job\n     * @return bool\n     */\n    protected function shouldDispatchAfterCommit($job)\n    {\n        if ($job instanceof ShouldQueueAfterCommit) {\n            return ! (isset($job->afterCommit) && $job->afterCommit === false);\n        }\n\n        if (! $job instanceof Closure && is_object($job) && isset($job->afterCommit)) {\n            return $job->afterCommit;\n        }\n\n        return $this->dispatchAfterCommit ?? false;\n    }\n\n    /**\n     * Raise the job queueing event.\n     *\n     * @param  string  $queue\n     * @param  \\Closure|string|object  $job\n     * @param  string  $payload\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return void\n     */\n    protected function raiseJobQueueingEvent($queue, $job, $payload, $delay)\n    {\n        if ($this->container->bound('events')) {\n            $delay = ! is_null($delay) ? $this->secondsUntil($delay) : $delay;\n\n            $this->container['events']->dispatch(new JobQueueing($this->connectionName, $queue, $job, $payload, $delay));\n        }\n    }\n\n    /**\n     * Raise the job queued event.\n     *\n     * @param  string|null  $queue\n     * @param  string|int|null  $jobId\n     * @param  \\Closure|string|object  $job\n     * @param  string  $payload\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return void\n     */\n    protected function raiseJobQueuedEvent($queue, $jobId, $job, $payload, $delay)\n    {\n        if ($this->container->bound('events')) {\n            $delay = ! is_null($delay) ? $this->secondsUntil($delay) : $delay;\n\n            $this->container['events']->dispatch(new JobQueued($this->connectionName, $queue, $jobId, $job, $payload, $delay));\n        }\n    }\n\n    /**\n     * Get the connection name for the queue.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n\n    /**\n     * Set the connection name for the queue.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setConnectionName($name)\n    {\n        $this->connectionName = $name;\n\n        return $this;\n    }\n\n    /**\n     * Get the queue configuration array.\n     *\n     * @return array\n     */\n    public function getConfig()\n    {\n        return $this->config;\n    }\n\n    /**\n     * Set the queue configuration array.\n     *\n     * @return $this\n     */\n    public function setConfig(array $config)\n    {\n        $this->config = $config;\n\n        return $this;\n    }\n\n    /**\n     * Get the container instance being used by the connection.\n     *\n     * @return \\Illuminate\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the IoC container instance.\n     *\n     * @return void\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/QueueManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Closure;\nuse Illuminate\\Contracts\\Queue\\Factory as FactoryContract;\nuse Illuminate\\Contracts\\Queue\\Monitor as MonitorContract;\nuse Illuminate\\Support\\Queue\\Concerns\\ResolvesQueueRoutes;\nuse InvalidArgumentException;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Queue\\Queue\n */\nclass QueueManager implements FactoryContract, MonitorContract\n{\n    use ResolvesQueueRoutes;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The array of resolved queue connections.\n     *\n     * @var array\n     */\n    protected $connections = [];\n\n    /**\n     * The array of resolved queue connectors.\n     *\n     * @var array\n     */\n    protected $connectors = [];\n\n    /**\n     * Create a new queue manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Register an event listener for the before job event.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function before($callback)\n    {\n        $this->app['events']->listen(Events\\JobProcessing::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the after job event.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function after($callback)\n    {\n        $this->app['events']->listen(Events\\JobProcessed::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the exception occurred job event.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function exceptionOccurred($callback)\n    {\n        $this->app['events']->listen(Events\\JobExceptionOccurred::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the daemon queue loop.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function looping($callback)\n    {\n        $this->app['events']->listen(Events\\Looping::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the failed job event.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function failing($callback)\n    {\n        $this->app['events']->listen(Events\\JobFailed::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the daemon queue starting.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function starting($callback)\n    {\n        $this->app['events']->listen(Events\\WorkerStarting::class, $callback);\n    }\n\n    /**\n     * Register an event listener for the daemon queue stopping.\n     *\n     * @param  mixed  $callback\n     * @return void\n     */\n    public function stopping($callback)\n    {\n        $this->app['events']->listen(Events\\WorkerStopping::class, $callback);\n    }\n\n    /**\n     * Set the queue route for the given class.\n     *\n     * @param  array|class-string  $class\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return void\n     */\n    public function route(array|string $class, $queue = null, $connection = null)\n    {\n        $this->queueRoutes()->set($class, $queue, $connection);\n    }\n\n    /**\n     * Determine if the driver is connected.\n     *\n     * @param  string|null  $name\n     * @return bool\n     */\n    public function connected($name = null)\n    {\n        return isset($this->connections[$name ?: $this->getDefaultDriver()]);\n    }\n\n    /**\n     * Resolve a queue connection instance.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connection($name = null)\n    {\n        $name = $name ?: $this->getDefaultDriver();\n\n        // If the connection has not been resolved yet we will resolve it now as all\n        // of the connections are resolved when they are actually needed so we do\n        // not make any unnecessary connection to the various queue end-points.\n        if (! isset($this->connections[$name])) {\n            $this->connections[$name] = $this->resolve($name);\n\n            $this->connections[$name]->setContainer($this->app);\n        }\n\n        return $this->connections[$name];\n    }\n\n    /**\n     * Resolve a queue connection.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"The [{$name}] queue connection has not been configured.\");\n        }\n\n        $queue = $this->getConnector($config['driver'])\n            ->connect($config)\n            ->setConnectionName($name);\n\n        if (method_exists($queue, 'setConfig')) {\n            $queue->setConfig($config);\n        }\n\n        return $queue;\n    }\n\n    /**\n     * Get the connector for a given driver.\n     *\n     * @param  string  $driver\n     * @return \\Illuminate\\Queue\\Connectors\\ConnectorInterface\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function getConnector($driver)\n    {\n        if (! isset($this->connectors[$driver])) {\n            throw new InvalidArgumentException(\"No connector for [$driver].\");\n        }\n\n        return call_user_func($this->connectors[$driver]);\n    }\n\n    /**\n     * Pause a queue by its connection and name.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @return void\n     */\n    public function pause($connection, $queue)\n    {\n        $this->app['cache']\n            ->store()\n            ->forever(\"illuminate:queue:paused:{$connection}:{$queue}\", true);\n\n        $this->app['events']->dispatch(\n            new Events\\QueuePaused($connection, $queue)\n        );\n    }\n\n    /**\n     * Pause a queue by its connection and name for a given amount of time.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int  $ttl\n     * @return void\n     */\n    public function pauseFor($connection, $queue, $ttl)\n    {\n        $this->app['cache']\n            ->store()\n            ->put(\"illuminate:queue:paused:{$connection}:{$queue}\", true, $ttl);\n\n        $this->app['events']->dispatch(\n            new Events\\QueuePaused($connection, $queue, $ttl)\n        );\n    }\n\n    /**\n     * Resume a paused queue by its connection and name.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @return void\n     */\n    public function resume($connection, $queue)\n    {\n        $this->app['cache']\n            ->store()\n            ->forget(\"illuminate:queue:paused:{$connection}:{$queue}\");\n\n        $this->app['events']->dispatch(\n            new Events\\QueueResumed($connection, $queue)\n        );\n    }\n\n    /**\n     * Determine if a queue is paused.\n     *\n     * @param  string  $connection\n     * @param  string  $queue\n     * @return bool\n     */\n    public function isPaused($connection, $queue)\n    {\n        return (bool) $this->app['cache']\n            ->store()\n            ->get(\"illuminate:queue:paused:{$connection}:{$queue}\", false);\n    }\n\n    /**\n     * Indicate that queue workers should not poll for restart or pause signals.\n     *\n     * This prevents the workers from hitting the application cache to determine if they need to pause or restart.\n     *\n     * @return void\n     */\n    public function withoutInterruptionPolling()\n    {\n        Worker::$restartable = false;\n        Worker::$pausable = false;\n    }\n\n    /**\n     * Add a queue connection resolver.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public function extend($driver, Closure $resolver)\n    {\n        $this->addConnector($driver, $resolver);\n    }\n\n    /**\n     * Add a queue connection resolver.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public function addConnector($driver, Closure $resolver)\n    {\n        $this->connectors[$driver] = $resolver;\n    }\n\n    /**\n     * Get the queue connection configuration.\n     *\n     * @param  string  $name\n     * @return array|null\n     */\n    protected function getConfig($name)\n    {\n        if (! is_null($name) && $name !== 'null') {\n            return $this->app['config'][\"queue.connections.{$name}\"];\n        }\n\n        return ['driver' => 'null'];\n    }\n\n    /**\n     * Get the name of the default queue connection.\n     *\n     * @return string\n     */\n    public function getDefaultDriver()\n    {\n        return $this->app['config']['queue.default'];\n    }\n\n    /**\n     * Set the name of the default queue connection.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->app['config']['queue.default'] = $name;\n    }\n\n    /**\n     * Get the full name for the given connection.\n     *\n     * @param  string|null  $connection\n     * @return string\n     */\n    public function getName($connection = null)\n    {\n        return $connection ?: $this->getDefaultDriver();\n    }\n\n    /**\n     * Get the application instance used by the manager.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    public function getApplication()\n    {\n        return $this->app;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        foreach ($this->connections as $connection) {\n            $connection->setContainer($app);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Dynamically pass calls to the default connection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->connection()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/QueueRoutes.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass QueueRoutes\n{\n    /**\n     * The mapping of class names to their default routes.\n     *\n     * @var array<class-string, array|string>\n     */\n    protected $routes = [];\n\n    /**\n     * Get the queue connection that a given queueable instance should be routed to.\n     *\n     * @param  object  $queueable\n     * @return string|null\n     */\n    public function getConnection($queueable)\n    {\n        $route = $this->getRoute($queueable);\n\n        if (is_null($route)) {\n            return;\n        }\n\n        return is_string($route)\n            ? $route\n            : $route[0];\n    }\n\n    /**\n     * Get the queue that a given queueable instance should be routed to.\n     *\n     * @param  object  $queueable\n     * @return string|null\n     */\n    public function getQueue($queueable)\n    {\n        $route = $this->getRoute($queueable);\n\n        if (is_null($route)) {\n            return;\n        }\n\n        return is_string($route)\n            ? $route\n            : $route[1];\n    }\n\n    /**\n     * Get the route for a given queueable instance.\n     *\n     * @param  object  $queueable\n     * @return array|string|null\n     */\n    public function getRoute($queueable)\n    {\n        if (empty($this->routes)) {\n            return null;\n        }\n\n        $classes = array_merge(\n            [get_class($queueable)],\n            class_parents($queueable) ?: [],\n            class_implements($queueable) ?: [],\n            class_uses_recursive($queueable)\n        );\n\n        foreach ($classes as $class) {\n            if (isset($this->routes[$class])) {\n                return $this->routes[$class];\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Register the queue route for the given class.\n     *\n     * @param  array|class-string  $class\n     * @param  string|null  $queue\n     * @param  string|null  $connection\n     * @return void\n     */\n    public function set(array|string $class, $queue = null, $connection = null)\n    {\n        $routes = is_array($class) ? $class : [$class => [$connection, $queue]];\n\n        foreach ($routes as $from => $to) {\n            $this->routes[$from] = $to;\n        }\n    }\n\n    /**\n     * Get all registered queue routes.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->routes;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/QueueServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Events\\Dispatcher as EventDispatcher;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Queue\\Connectors\\BackgroundConnector;\nuse Illuminate\\Queue\\Connectors\\BeanstalkdConnector;\nuse Illuminate\\Queue\\Connectors\\DatabaseConnector;\nuse Illuminate\\Queue\\Connectors\\DeferredConnector;\nuse Illuminate\\Queue\\Connectors\\FailoverConnector;\nuse Illuminate\\Queue\\Connectors\\NullConnector;\nuse Illuminate\\Queue\\Connectors\\RedisConnector;\nuse Illuminate\\Queue\\Connectors\\SqsConnector;\nuse Illuminate\\Queue\\Connectors\\SyncConnector;\nuse Illuminate\\Queue\\Failed\\DatabaseFailedJobProvider;\nuse Illuminate\\Queue\\Failed\\DatabaseUuidFailedJobProvider;\nuse Illuminate\\Queue\\Failed\\DynamoDbFailedJobProvider;\nuse Illuminate\\Queue\\Failed\\FileFailedJobProvider;\nuse Illuminate\\Queue\\Failed\\NullFailedJobProvider;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\ServiceProvider;\nuse Laravel\\SerializableClosure\\SerializableClosure;\n\nclass QueueServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    use SerializesAndRestoresModelIdentifiers;\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->configureSerializableClosureUses();\n\n        $this->registerManager();\n        $this->registerConnection();\n        $this->registerWorker();\n        $this->registerListener();\n        $this->registerRoutes();\n        $this->registerFailedJobServices();\n    }\n\n    /**\n     * Configure serializable closures uses.\n     *\n     * @return void\n     */\n    protected function configureSerializableClosureUses()\n    {\n        SerializableClosure::transformUseVariablesUsing(function ($data) {\n            foreach ($data as $key => $value) {\n                $data[$key] = $this->getSerializedPropertyValue($value);\n            }\n\n            return $data;\n        });\n\n        SerializableClosure::resolveUseVariablesUsing(function ($data) {\n            foreach ($data as $key => $value) {\n                $data[$key] = $this->getRestoredPropertyValue($value);\n            }\n\n            return $data;\n        });\n    }\n\n    /**\n     * Register the queue manager.\n     *\n     * @return void\n     */\n    protected function registerManager()\n    {\n        $this->app->singleton('queue', function ($app) {\n            // Once we have an instance of the queue manager, we will register the various\n            // resolvers for the queue connectors. These connectors are responsible for\n            // creating the classes that accept queue configs and instantiate queues.\n            return tap(new QueueManager($app), function ($manager) {\n                $this->registerConnectors($manager);\n            });\n        });\n    }\n\n    /**\n     * Register the default queue connection binding.\n     *\n     * @return void\n     */\n    protected function registerConnection()\n    {\n        $this->app->singleton('queue.connection', function ($app) {\n            return $app['queue']->connection();\n        });\n    }\n\n    /**\n     * Register the connectors on the queue manager.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    public function registerConnectors($manager)\n    {\n        foreach (['Null', 'Sync', 'Deferred', 'Background', 'Failover', 'Database', 'Redis', 'Beanstalkd', 'Sqs'] as $connector) {\n            $this->{\"register{$connector}Connector\"}($manager);\n        }\n    }\n\n    /**\n     * Register the Null queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerNullConnector($manager)\n    {\n        $manager->addConnector('null', function () {\n            return new NullConnector;\n        });\n    }\n\n    /**\n     * Register the Sync queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerSyncConnector($manager)\n    {\n        $manager->addConnector('sync', function () {\n            return new SyncConnector;\n        });\n    }\n\n    /**\n     * Register the Deferred queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerDeferredConnector($manager)\n    {\n        $manager->addConnector('deferred', function () {\n            return new DeferredConnector;\n        });\n    }\n\n    /**\n     * Register the Background queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerBackgroundConnector($manager)\n    {\n        $manager->addConnector('background', function () {\n            return new BackgroundConnector;\n        });\n    }\n\n    /**\n     * Register the Failover queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerFailoverConnector($manager)\n    {\n        $manager->addConnector('failover', function () use ($manager) {\n            return new FailoverConnector(\n                $manager,\n                $this->app->make(EventDispatcher::class)\n            );\n        });\n    }\n\n    /**\n     * Register the database queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerDatabaseConnector($manager)\n    {\n        $manager->addConnector('database', function () {\n            return new DatabaseConnector($this->app['db']);\n        });\n    }\n\n    /**\n     * Register the Redis queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerRedisConnector($manager)\n    {\n        $manager->addConnector('redis', function () {\n            return new RedisConnector($this->app['redis']);\n        });\n    }\n\n    /**\n     * Register the Beanstalkd queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerBeanstalkdConnector($manager)\n    {\n        $manager->addConnector('beanstalkd', function () {\n            return new BeanstalkdConnector;\n        });\n    }\n\n    /**\n     * Register the Amazon SQS queue connector.\n     *\n     * @param  \\Illuminate\\Queue\\QueueManager  $manager\n     * @return void\n     */\n    protected function registerSqsConnector($manager)\n    {\n        $manager->addConnector('sqs', function () {\n            return new SqsConnector;\n        });\n    }\n\n    /**\n     * Register the queue worker.\n     *\n     * @return void\n     */\n    protected function registerWorker()\n    {\n        $this->app->singleton('queue.worker', function ($app) {\n            $isDownForMaintenance = function () {\n                return $this->app->isDownForMaintenance();\n            };\n\n            $resetScope = function () use ($app) {\n                if (method_exists($app['log'], 'flushSharedContext')) {\n                    $app['log']->flushSharedContext();\n                }\n\n                if (method_exists($app['log'], 'withoutContext')) {\n                    $app['log']->withoutContext();\n                }\n\n                if (method_exists($app['db'], 'getConnections')) {\n                    foreach ($app['db']->getConnections() as $connection) {\n                        $connection->resetTotalQueryDuration();\n                        $connection->allowQueryDurationHandlersToRunAgain();\n                    }\n                }\n\n                $app->forgetScopedInstances();\n\n                Facade::clearResolvedInstances();\n\n                memory_reset_peak_usage();\n            };\n\n            return new Worker(\n                $app['queue'],\n                $app['events'],\n                $app[ExceptionHandler::class],\n                $isDownForMaintenance,\n                $resetScope\n            );\n        });\n    }\n\n    /**\n     * Register the queue listener.\n     *\n     * @return void\n     */\n    protected function registerListener()\n    {\n        $this->app->singleton('queue.listener', function ($app) {\n            return new Listener($app->basePath());\n        });\n    }\n\n    /**\n     * Register the default queue routes binding.\n     *\n     * @return void\n     */\n    protected function registerRoutes()\n    {\n        $this->app->singleton('queue.routes', function () {\n            return new QueueRoutes;\n        });\n    }\n\n    /**\n     * Register the failed job services.\n     *\n     * @return void\n     */\n    protected function registerFailedJobServices()\n    {\n        $this->app->singleton('queue.failer', function ($app) {\n            $config = $app['config']['queue.failed'];\n\n            if (array_key_exists('driver', $config) &&\n                (is_null($config['driver']) || $config['driver'] === 'null')) {\n                return new NullFailedJobProvider;\n            }\n\n            if (isset($config['driver']) && $config['driver'] === 'file') {\n                return new FileFailedJobProvider(\n                    $config['path'] ?? $this->app->storagePath('framework/cache/failed-jobs.json'),\n                    $config['limit'] ?? 100,\n                    fn () => $app['cache']->store('file'),\n                );\n            } elseif (isset($config['driver']) && $config['driver'] === 'dynamodb') {\n                return $this->dynamoFailedJobProvider($config);\n            } elseif (isset($config['driver']) && $config['driver'] === 'database-uuids') {\n                return $this->databaseUuidFailedJobProvider($config);\n            } elseif (isset($config['table'])) {\n                return $this->databaseFailedJobProvider($config);\n            } else {\n                return new NullFailedJobProvider;\n            }\n        });\n    }\n\n    /**\n     * Create a new database failed job provider.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Queue\\Failed\\DatabaseFailedJobProvider\n     */\n    protected function databaseFailedJobProvider($config)\n    {\n        return new DatabaseFailedJobProvider(\n            $this->app['db'], $config['database'], $config['table']\n        );\n    }\n\n    /**\n     * Create a new database failed job provider that uses UUIDs as IDs.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Queue\\Failed\\DatabaseUuidFailedJobProvider\n     */\n    protected function databaseUuidFailedJobProvider($config)\n    {\n        return new DatabaseUuidFailedJobProvider(\n            $this->app['db'], $config['database'], $config['table']\n        );\n    }\n\n    /**\n     * Create a new DynamoDb failed job provider.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Queue\\Failed\\DynamoDbFailedJobProvider\n     */\n    protected function dynamoFailedJobProvider($config)\n    {\n        $dynamoConfig = [\n            'region' => $config['region'],\n            'version' => 'latest',\n            'endpoint' => $config['endpoint'] ?? null,\n        ];\n\n        if (! empty($config['key']) && ! empty($config['secret'])) {\n            $dynamoConfig['credentials'] = Arr::only($config, ['key', 'secret']);\n\n            if (! empty($config['token'])) {\n                $dynamoConfig['credentials']['token'] = $config['token'];\n            }\n        }\n\n        return new DynamoDbFailedJobProvider(\n            new DynamoDbClient($dynamoConfig),\n            $this->app['config']['app.name'],\n            $config['table']\n        );\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [\n            'queue',\n            'queue.connection',\n            'queue.failer',\n            'queue.listener',\n            'queue.routes',\n            'queue.worker',\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/README.md",
    "content": "## Illuminate Queue\n\nThe Laravel Queue component provides a unified API across a variety of different queue services. Queues allow you to defer the processing of a time consuming task, such as sending an e-mail, until a later time, thus drastically speeding up the web requests to your application.\n\n### Usage Instructions\n\nFirst, create a new Queue `Capsule` manager instance. Similar to the \"Capsule\" provided for the Eloquent ORM, the queue Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible.\n\n```PHP\nuse Illuminate\\Queue\\Capsule\\Manager as Queue;\n\n$queue = new Queue;\n\n$queue->addConnection([\n    'driver' => 'beanstalkd',\n    'host' => 'localhost',\n    'queue' => 'default',\n]);\n\n// Make this Capsule instance available globally via static methods... (optional)\n$queue->setAsGlobal();\n```\n\nOnce the Capsule instance has been registered. You may use it like so:\n\n```PHP\n// As an instance...\n$queue->push('SendEmail', ['message' => $message]);\n\n// If setAsGlobal has been called...\nQueue::push('SendEmail', ['message' => $message]);\n```\n\nFor further documentation on using the queue, consult the [Laravel framework documentation](https://laravel.com/docs).\n"
  },
  {
    "path": "src/Illuminate/Queue/RedisQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Queue\\ClearableQueue;\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Queue\\Jobs\\RedisJob;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisClusterConnection;\nuse Illuminate\\Support\\Str;\n\nclass RedisQueue extends Queue implements QueueContract, ClearableQueue\n{\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    protected $redis;\n\n    /**\n     * The connection name.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * The name of the default queue.\n     *\n     * @var string\n     */\n    protected $default;\n\n    /**\n     * The expiration time of a job.\n     *\n     * @var int|null\n     */\n    protected $retryAfter = 60;\n\n    /**\n     * The maximum number of seconds to block for a job.\n     *\n     * @var int|null\n     */\n    protected $blockFor = null;\n\n    /**\n     * The batch size to use when migrating delayed / expired jobs onto the primary queue.\n     *\n     * Negative values are infinite.\n     *\n     * @var int\n     */\n    protected $migrationBatchSize = -1;\n\n    /**\n     * Indicates if a secondary queue had a job available between checks of the primary queue.\n     *\n     * Only applicable when monitoring multiple named queues with a single instance.\n     *\n     * @var bool\n     */\n    protected $secondaryQueueHadJob = false;\n\n    /**\n     * Create a new Redis queue instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Redis\\Factory  $redis\n     * @param  string  $default\n     * @param  string|null  $connection\n     * @param  int  $retryAfter\n     * @param  int|null  $blockFor\n     * @param  bool  $dispatchAfterCommit\n     * @param  int  $migrationBatchSize\n     */\n    public function __construct(\n        Redis $redis,\n        $default = 'default',\n        $connection = null,\n        $retryAfter = 60,\n        $blockFor = null,\n        $dispatchAfterCommit = false,\n        $migrationBatchSize = -1,\n    ) {\n        $this->redis = $redis;\n        $this->default = $default;\n        $this->blockFor = $blockFor;\n        $this->connection = $connection;\n        $this->retryAfter = $retryAfter;\n        $this->dispatchAfterCommit = $dispatchAfterCommit;\n        $this->migrationBatchSize = $migrationBatchSize;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        $queue = $this->getQueue($queue);\n\n        return $this->getConnection()->eval(\n            LuaScripts::size(), 3, $queue, $queue.':delayed', $queue.':reserved'\n        );\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return $this->getConnection()->llen($this->getQueue($queue));\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return $this->getConnection()->zcard($this->getQueue($queue).':delayed');\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return $this->getConnection()->zcard($this->getQueue($queue).':reserved');\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        $payload = $this->getConnection()->lindex($this->getQueue($queue), 0);\n\n        if (! $payload) {\n            return null;\n        }\n\n        $data = json_decode($payload, true);\n\n        return $data['createdAt'] ?? null;\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return void\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        $connection = $this->getConnection();\n\n        $bulk = function () use ($jobs, $data, $queue) {\n            foreach ((array) $jobs as $job) {\n                if (isset($job->delay)) {\n                    $this->later($job->delay, $job, $data, $queue);\n                } else {\n                    $this->push($job, $data, $queue);\n                }\n            }\n        };\n\n        if ($connection instanceof PhpRedisClusterConnection) {\n            $connection->transaction($bulk);\n        } elseif ($connection instanceof PredisClusterConnection) {\n            $connection->pipeline($bulk);\n        } else {\n            $connection->pipeline(fn () => $connection->transaction($bulk));\n        }\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  object|string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data),\n            $queue,\n            null,\n            function ($payload, $queue) {\n                return $this->pushRaw($payload, $queue);\n            }\n        );\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        $this->getConnection()->eval(\n            LuaScripts::push(), 2, $this->getQueue($queue),\n            $this->getQueue($queue).':notify', $payload\n        );\n\n        return json_decode($payload, true)['id'] ?? null;\n    }\n\n    /**\n     * Push a new job onto the queue after a delay.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  object|string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $this->getQueue($queue), $data, $delay),\n            $queue,\n            $delay,\n            function ($payload, $queue, $delay) {\n                return $this->laterRaw($delay, $payload, $queue);\n            }\n        );\n    }\n\n    /**\n     * Push a raw job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    protected function laterRaw($delay, $payload, $queue = null)\n    {\n        $this->getConnection()->eval(\n            LuaScripts::later(), 1, $this->getQueue($queue).':delayed',\n            $this->availableAt($delay), $payload\n        );\n\n        return json_decode($payload, true)['id'] ?? null;\n    }\n\n    /**\n     * Create a payload string from the given job and data.\n     *\n     * @param  string  $job\n     * @param  string  $queue\n     * @param  mixed  $data\n     * @return array\n     */\n    protected function createPayloadArray($job, $queue, $data = '')\n    {\n        return array_merge(parent::createPayloadArray($job, $queue, $data), [\n            'id' => $this->getRandomId(),\n            'attempts' => 0,\n        ]);\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @param  int  $index\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null, $index = 0)\n    {\n        $this->migrate($prefixed = $this->getQueue($queue));\n\n        $block = ! $this->secondaryQueueHadJob && $index == 0;\n\n        [$job, $reserved] = $this->retrieveNextJob($prefixed, $block);\n\n        if ($index == 0) {\n            $this->secondaryQueueHadJob = false;\n        }\n\n        if ($reserved) {\n            if ($index > 0) {\n                $this->secondaryQueueHadJob = true;\n            }\n\n            return new RedisJob(\n                $this->container, $this, $job,\n                $reserved, $this->connectionName, $queue ?: $this->default\n            );\n        }\n    }\n\n    /**\n     * Migrate any delayed or expired jobs onto the primary queue.\n     *\n     * @param  string  $queue\n     * @return void\n     */\n    protected function migrate($queue)\n    {\n        $this->migrateExpiredJobs($queue.':delayed', $queue);\n\n        if (! is_null($this->retryAfter)) {\n            $this->migrateExpiredJobs($queue.':reserved', $queue);\n        }\n    }\n\n    /**\n     * Migrate the delayed jobs that are ready to the regular queue.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return array\n     */\n    public function migrateExpiredJobs($from, $to)\n    {\n        return $this->getConnection()->eval(\n            LuaScripts::migrateExpiredJobs(), 3, $from, $to, $to.':notify', $this->currentTime(), $this->migrationBatchSize\n        );\n    }\n\n    /**\n     * Retrieve the next job from the queue.\n     *\n     * @param  string  $queue\n     * @param  bool  $block\n     * @return array\n     */\n    protected function retrieveNextJob($queue, $block = true)\n    {\n        $nextJob = $this->getConnection()->eval(\n            LuaScripts::pop(), 3, $queue, $queue.':reserved', $queue.':notify',\n            $this->availableAt($this->retryAfter)\n        );\n\n        if (empty($nextJob)) {\n            return [null, null];\n        }\n\n        [$job, $reserved] = $nextJob;\n\n        if (! $job && ! is_null($this->blockFor) && $block &&\n            $this->getConnection()->blpop([$queue.':notify'], $this->blockFor)) {\n            return $this->retrieveNextJob($queue, false);\n        }\n\n        return [$job, $reserved];\n    }\n\n    /**\n     * Delete a reserved job from the queue.\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\Jobs\\RedisJob  $job\n     * @return void\n     */\n    public function deleteReserved($queue, $job)\n    {\n        $this->getConnection()->zrem($this->getQueue($queue).':reserved', $job->getReservedJob());\n    }\n\n    /**\n     * Delete a reserved job from the reserved queue and release it.\n     *\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\Jobs\\RedisJob  $job\n     * @param  int  $delay\n     * @return void\n     */\n    public function deleteAndRelease($queue, $job, $delay)\n    {\n        $queue = $this->getQueue($queue);\n\n        $this->getConnection()->eval(\n            LuaScripts::release(), 2, $queue.':delayed', $queue.':reserved',\n            $job->getReservedJob(), $this->availableAt($delay)\n        );\n    }\n\n    /**\n     * Delete all of the jobs from the queue.\n     *\n     * @param  string  $queue\n     * @return int\n     */\n    public function clear($queue)\n    {\n        $queue = $this->getQueue($queue);\n\n        return $this->getConnection()->eval(\n            LuaScripts::clear(), 4, $queue, $queue.':delayed',\n            $queue.':reserved', $queue.':notify'\n        );\n    }\n\n    /**\n     * Get a random ID string.\n     *\n     * @return string\n     */\n    protected function getRandomId()\n    {\n        return Str::random(32);\n    }\n\n    /**\n     * Get the queue or return the default.\n     *\n     * @param  string|null  $queue\n     * @return string\n     */\n    public function getQueue($queue)\n    {\n        return 'queues:'.($queue ?: $this->default);\n    }\n\n    /**\n     * Get the connection for the queue.\n     *\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function getConnection()\n    {\n        return $this->redis->connection($this->connection);\n    }\n\n    /**\n     * Get the underlying Redis instance.\n     *\n     * @return \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    public function getRedis()\n    {\n        return $this->redis;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Database\\ModelIdentifier;\nuse Illuminate\\Contracts\\Queue\\QueueableCollection;\nuse Illuminate\\Contracts\\Queue\\QueueableEntity;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Support\\Collection;\n\ntrait SerializesAndRestoresModelIdentifiers\n{\n    /**\n     * Get the property value prepared for serialization.\n     *\n     * @param  mixed  $value\n     * @param  bool  $withRelations\n     * @return mixed\n     */\n    protected function getSerializedPropertyValue($value, $withRelations = true)\n    {\n        if ($value instanceof QueueableCollection) {\n            return (new ModelIdentifier(\n                $value->getQueueableClass(),\n                $value->getQueueableIds(),\n                $withRelations ? $value->getQueueableRelations() : [],\n                $value->getQueueableConnection()\n            ))->useCollectionClass(\n                ($collectionClass = get_class($value)) !== EloquentCollection::class\n                    ? $collectionClass\n                    : null\n            );\n        }\n\n        if ($value instanceof QueueableEntity) {\n            return new ModelIdentifier(\n                get_class($value),\n                $value->getQueueableId(),\n                $withRelations ? $value->getQueueableRelations() : [],\n                $value->getQueueableConnection()\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the restored property value after deserialization.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function getRestoredPropertyValue($value)\n    {\n        if (! $value instanceof ModelIdentifier) {\n            return $value;\n        }\n\n        return is_array($value->id)\n            ? $this->restoreCollection($value)\n            : $this->restoreModel($value);\n    }\n\n    /**\n     * Restore a queueable collection instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\ModelIdentifier  $value\n     * @return \\Illuminate\\Database\\Eloquent\\Collection\n     */\n    protected function restoreCollection($value)\n    {\n        $class = $value->getClass();\n\n        if (! $class || count($value->id) === 0) {\n            return ! is_null($value->collectionClass ?? null)\n                ? new $value->collectionClass\n                : new EloquentCollection;\n        }\n\n        $collection = $this->getQueryForModelRestoration(\n            (new $class)->setConnection($value->connection), $value->id\n        )->useWritePdo()->get();\n\n        if (is_a($class, Pivot::class, true) ||\n            in_array(AsPivot::class, class_uses($class))) {\n            return $collection;\n        }\n\n        $collection = $collection->keyBy->getKey();\n\n        $collectionClass = get_class($collection);\n\n        return (new $collectionClass(\n            (new Collection($value->id))\n                ->map(fn ($id) => $collection[$id] ?? null)\n                ->filter()\n        ))->loadMissing($value->relations ?? []);\n    }\n\n    /**\n     * Restore the model from the model identifier instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\ModelIdentifier  $value\n     * @return \\Illuminate\\Database\\Eloquent\\Model\n     */\n    public function restoreModel($value)\n    {\n        return $this->getQueryForModelRestoration(\n            (new ($value->getClass()))->setConnection($value->connection), $value->id\n        )->useWritePdo()->firstOrFail()->loadMissing($value->relations ?? []);\n    }\n\n    /**\n     * Get the query for model restoration.\n     *\n     * @template TModel of \\Illuminate\\Database\\Eloquent\\Model\n     *\n     * @param  TModel  $model\n     * @param  array|int  $ids\n     * @return \\Illuminate\\Database\\Eloquent\\Builder<TModel>\n     */\n    protected function getQueryForModelRestoration($model, $ids)\n    {\n        return $model->newQueryForRestoration($ids);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/SerializesModels.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Queue\\Attributes\\WithoutRelations;\nuse ReflectionClass;\nuse ReflectionProperty;\n\ntrait SerializesModels\n{\n    use SerializesAndRestoresModelIdentifiers;\n\n    /**\n     * Prepare the instance values for serialization.\n     *\n     * @return array\n     */\n    public function __serialize()\n    {\n        $values = [];\n\n        $reflectionClass = new ReflectionClass($this);\n\n        [$class, $properties, $classLevelWithoutRelations] = [\n            get_class($this),\n            $reflectionClass->getProperties(),\n            ! empty($reflectionClass->getAttributes(WithoutRelations::class)),\n        ];\n\n        foreach ($properties as $property) {\n            if ($property->isStatic()) {\n                continue;\n            }\n\n            if (! $property->isInitialized($this)) {\n                continue;\n            }\n\n            if (method_exists($property, 'isVirtual') && $property->isVirtual()) {\n                continue;\n            }\n\n            $value = $this->getPropertyValue($property);\n\n            if ($property->hasDefaultValue() && $value === $property->getDefaultValue()) {\n                continue;\n            }\n\n            $name = $property->getName();\n\n            if ($property->isPrivate()) {\n                $name = \"\\0{$class}\\0{$name}\";\n            } elseif ($property->isProtected()) {\n                $name = \"\\0*\\0{$name}\";\n            }\n\n            $values[$name] = $this->getSerializedPropertyValue(\n                $value,\n                ! $classLevelWithoutRelations &&\n                    empty($property->getAttributes(WithoutRelations::class))\n            );\n        }\n\n        return $values;\n    }\n\n    /**\n     * Restore the model after serialization.\n     *\n     * @param  array  $values\n     * @return void\n     */\n    public function __unserialize(array $values)\n    {\n        $properties = (new ReflectionClass($this))->getProperties();\n\n        $class = get_class($this);\n\n        foreach ($properties as $property) {\n            if ($property->isStatic()) {\n                continue;\n            }\n\n            $name = $property->getName();\n\n            if ($property->isPrivate()) {\n                $name = \"\\0{$class}\\0{$name}\";\n            } elseif ($property->isProtected()) {\n                $name = \"\\0*\\0{$name}\";\n            }\n\n            if (! array_key_exists($name, $values)) {\n                continue;\n            }\n\n            $property->setValue(\n                $this, $this->getRestoredPropertyValue($values[$name])\n            );\n        }\n    }\n\n    /**\n     * Get the property value for the given property.\n     *\n     * @param  \\ReflectionProperty  $property\n     * @return mixed\n     */\n    protected function getPropertyValue(ReflectionProperty $property)\n    {\n        return $property->getValue($this);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/SqsQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Aws\\Sqs\\SqsClient;\nuse Illuminate\\Contracts\\Queue\\ClearableQueue;\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Queue\\Jobs\\SqsJob;\nuse Illuminate\\Support\\Str;\n\nclass SqsQueue extends Queue implements QueueContract, ClearableQueue\n{\n    /**\n     * The Amazon SQS instance.\n     *\n     * @var \\Aws\\Sqs\\SqsClient\n     */\n    protected $sqs;\n\n    /**\n     * The name of the default queue.\n     *\n     * @var string\n     */\n    protected $default;\n\n    /**\n     * The queue URL prefix.\n     *\n     * @var string\n     */\n    protected $prefix;\n\n    /**\n     * The queue name suffix.\n     *\n     * @var string\n     */\n    protected $suffix;\n\n    /**\n     * Create a new Amazon SQS queue instance.\n     *\n     * @param  \\Aws\\Sqs\\SqsClient  $sqs\n     * @param  string  $default\n     * @param  string  $prefix\n     * @param  string  $suffix\n     * @param  bool  $dispatchAfterCommit\n     */\n    public function __construct(\n        SqsClient $sqs,\n        $default,\n        $prefix = '',\n        $suffix = '',\n        $dispatchAfterCommit = false,\n    ) {\n        $this->sqs = $sqs;\n        $this->prefix = $prefix;\n        $this->default = $default;\n        $this->suffix = $suffix;\n        $this->dispatchAfterCommit = $dispatchAfterCommit;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        $response = $this->sqs->getQueueAttributes([\n            'QueueUrl' => $this->getQueue($queue),\n            'AttributeNames' => [\n                'ApproximateNumberOfMessages',\n                'ApproximateNumberOfMessagesDelayed',\n                'ApproximateNumberOfMessagesNotVisible',\n            ],\n        ]);\n\n        $a = $response['Attributes'];\n\n        return (int) $a['ApproximateNumberOfMessages']\n            + (int) $a['ApproximateNumberOfMessagesDelayed']\n            + (int) $a['ApproximateNumberOfMessagesNotVisible'];\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        $response = $this->sqs->getQueueAttributes([\n            'QueueUrl' => $this->getQueue($queue),\n            'AttributeNames' => ['ApproximateNumberOfMessages'],\n        ]);\n\n        return (int) $response['Attributes']['ApproximateNumberOfMessages'] ?? 0;\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        $response = $this->sqs->getQueueAttributes([\n            'QueueUrl' => $this->getQueue($queue),\n            'AttributeNames' => ['ApproximateNumberOfMessagesDelayed'],\n        ]);\n\n        return (int) $response['Attributes']['ApproximateNumberOfMessagesDelayed'] ?? 0;\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        $response = $this->sqs->getQueueAttributes([\n            'QueueUrl' => $this->getQueue($queue),\n            'AttributeNames' => ['ApproximateNumberOfMessagesNotVisible'],\n        ]);\n\n        return (int) $response['Attributes']['ApproximateNumberOfMessagesNotVisible'] ?? 0;\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * Not supported by SQS, returns null.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        // Not supported by SQS...\n        return null;\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $queue ?: $this->default, $data),\n            $queue,\n            null,\n            function ($payload, $queue) use ($job) {\n                return $this->pushRaw($payload, $queue, $this->getQueueableOptions($job, $queue, $payload));\n            }\n        );\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        return $this->sqs->sendMessage([\n            'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, ...$options,\n        ])->get('MessageId');\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->enqueueUsing(\n            $job,\n            $this->createPayload($job, $queue ?: $this->default, $data, $delay),\n            $queue,\n            $delay,\n            function ($payload, $queue, $delay) use ($job) {\n                return $this->pushRaw($payload, $queue, $this->getQueueableOptions($job, $queue, $payload, $delay));\n            }\n        );\n    }\n\n    /**\n     * Get the queueable options from the job.\n     *\n     * @param  mixed  $job\n     * @param  string|null  $queue\n     * @param  string  $payload\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $delay\n     * @return array{DelaySeconds?: int, MessageGroupId?: string, MessageDeduplicationId?: string}\n     */\n    public function getQueueableOptions($job, $queue, $payload, $delay = null): array\n    {\n        // Make sure we have a queue name to properly determine if it's a FIFO queue...\n        $queue ??= $this->default;\n\n        $isObject = is_object($job);\n        $isFifo = str_ends_with((string) $queue, '.fifo');\n\n        $options = [];\n\n        // DelaySeconds cannot be used with FIFO queues. AWS will return an error...\n        if (! empty($delay) && ! $isFifo) {\n            $options['DelaySeconds'] = $this->secondsUntil($delay);\n        }\n\n        // If the job is a string job on a standard queue, there are no more options...\n        if (! $isObject && ! $isFifo) {\n            return $options;\n        }\n\n        $transformToString = fn ($value) => (string) $value;\n\n        // The message group ID is required for FIFO queues and is optional for\n        // standard queues. Job objects contain a group ID. With string jobs\n        // sent to FIFO queues, assign these to the same message group ID.\n        $messageGroupId = null;\n\n        if ($isObject) {\n            $messageGroupId = transform($job->messageGroup ?? (method_exists($job, 'messageGroup') ? $job->messageGroup() : null), $transformToString);\n        } elseif ($isFifo) {\n            $messageGroupId = transform($queue, $transformToString);\n        }\n\n        $options['MessageGroupId'] = $messageGroupId;\n\n        // The message deduplication ID is only valid for FIFO queues. Every job\n        // without the method will be considered unique. To use content-based\n        // deduplication enable it in AWS and have the method return empty.\n        $messageDeduplicationId = null;\n\n        if ($isFifo) {\n            $messageDeduplicationId = match (true) {\n                $isObject && isset($job->deduplicator) && is_callable($job->deduplicator) => transform(call_user_func($job->deduplicator, $payload, $queue), $transformToString),\n                $isObject && method_exists($job, 'deduplicationId') => transform($job->deduplicationId($payload, $queue), $transformToString),\n                default => (string) Str::orderedUuid(),\n            };\n        }\n\n        $options['MessageDeduplicationId'] = $messageDeduplicationId;\n\n        return array_filter($options);\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return void\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        foreach ((array) $jobs as $job) {\n            if (isset($job->delay)) {\n                $this->later($job->delay, $job, $data, $queue);\n            } else {\n                $this->push($job, $data, $queue);\n            }\n        }\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        $response = $this->sqs->receiveMessage([\n            'QueueUrl' => $queue = $this->getQueue($queue),\n            'AttributeNames' => ['ApproximateReceiveCount'],\n        ]);\n\n        if (! is_null($response['Messages']) && count($response['Messages']) > 0) {\n            return new SqsJob(\n                $this->container, $this->sqs, $response['Messages'][0],\n                $this->connectionName, $queue\n            );\n        }\n    }\n\n    /**\n     * Delete all of the jobs from the queue.\n     *\n     * @param  string  $queue\n     * @return int\n     */\n    public function clear($queue)\n    {\n        return tap($this->size($queue), function () use ($queue) {\n            $this->sqs->purgeQueue([\n                'QueueUrl' => $this->getQueue($queue),\n            ]);\n        });\n    }\n\n    /**\n     * Get the queue or return the default.\n     *\n     * @param  string|null  $queue\n     * @return string\n     */\n    public function getQueue($queue)\n    {\n        $queue = $queue ?: $this->default;\n\n        return filter_var($queue, FILTER_VALIDATE_URL) === false\n            ? $this->suffixQueue($queue, $this->suffix)\n            : $queue;\n    }\n\n    /**\n     * Add the given suffix to the given queue name.\n     *\n     * @param  string  $queue\n     * @param  string  $suffix\n     * @return string\n     */\n    protected function suffixQueue($queue, $suffix = '')\n    {\n        if (str_ends_with($queue, '.fifo')) {\n            $queue = Str::beforeLast($queue, '.fifo');\n\n            return rtrim($this->prefix, '/').'/'.Str::finish($queue, $suffix).'.fifo';\n        }\n\n        return rtrim($this->prefix, '/').'/'.Str::finish($queue, $this->suffix);\n    }\n\n    /**\n     * Get the underlying SQS instance.\n     *\n     * @return \\Aws\\Sqs\\SqsClient\n     */\n    public function getSqs()\n    {\n        return $this->sqs;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/SyncQueue.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Contracts\\Queue\\Queue as QueueContract;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Queue\\Events\\JobAttempted;\nuse Illuminate\\Queue\\Events\\JobExceptionOccurred;\nuse Illuminate\\Queue\\Events\\JobProcessed;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Illuminate\\Queue\\Jobs\\SyncJob;\nuse Throwable;\n\nclass SyncQueue extends Queue implements QueueContract\n{\n    /**\n     * Create a new sync queue instance.\n     *\n     * @param  bool  $dispatchAfterCommit\n     */\n    public function __construct($dispatchAfterCommit = false)\n    {\n        $this->dispatchAfterCommit = $dispatchAfterCommit;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        return null;\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        if ($this->shouldDispatchAfterCommit($job) &&\n            $this->container->bound('db.transactions')) {\n            if ($job instanceof ShouldBeUnique) {\n                $this->container->make('db.transactions')->addCallbackForRollback(\n                    function () use ($job) {\n                        (new UniqueLock($this->container->make(Cache::class)))->release($job);\n                    }\n                );\n            }\n\n            return $this->container->make('db.transactions')->addCallback(\n                fn () => $this->executeJob($job, $data, $queue)\n            );\n        }\n\n        return $this->executeJob($job, $data, $queue);\n    }\n\n    /**\n     * Execute a given job synchronously.\n     *\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return int\n     *\n     * @throws \\Throwable\n     */\n    protected function executeJob($job, $data = '', $queue = null)\n    {\n        $queueJob = $this->resolveJob($this->createPayload($job, $queue, $data), $queue);\n\n        try {\n            $this->raiseBeforeJobEvent($queueJob);\n\n            $queueJob->fire();\n\n            $this->raiseAfterJobEvent($queueJob);\n        } catch (Throwable $e) {\n            $exceptionOccurred = $e;\n\n            $this->handleException($queueJob, $e);\n        } finally {\n            $this->raiseJobAttemptedEvent($queueJob, $exceptionOccurred ?? null);\n        }\n\n        return 0;\n    }\n\n    /**\n     * Resolve a Sync job instance.\n     *\n     * @param  string  $payload\n     * @param  string  $queue\n     * @return \\Illuminate\\Queue\\Jobs\\SyncJob\n     */\n    protected function resolveJob($payload, $queue)\n    {\n        return new SyncJob($this->container, $payload, $this->connectionName, $queue);\n    }\n\n    /**\n     * Raise the before queue job event.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return void\n     */\n    protected function raiseBeforeJobEvent(Job $job)\n    {\n        if ($this->container->bound('events')) {\n            $this->container['events']->dispatch(new JobProcessing($this->connectionName, $job));\n        }\n    }\n\n    /**\n     * Raise the after queue job event.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return void\n     */\n    protected function raiseAfterJobEvent(Job $job)\n    {\n        if ($this->container->bound('events')) {\n            $this->container['events']->dispatch(new JobProcessed($this->connectionName, $job));\n        }\n    }\n\n    /**\n     * Raise the job attempted event.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable|null  $exception\n     * @return void\n     */\n    protected function raiseJobAttemptedEvent(Job $job, ?Throwable $exceptionOccurred = null)\n    {\n        if ($this->container->bound('events')) {\n            $this->container['events']->dispatch(new JobAttempted($this->connectionName, $job, $exceptionOccurred));\n        }\n    }\n\n    /**\n     * Raise the exception occurred queue job event.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function raiseExceptionOccurredJobEvent(Job $job, Throwable $e)\n    {\n        if ($this->container->bound('events')) {\n            $this->container['events']->dispatch(new JobExceptionOccurred($this->connectionName, $job, $e));\n        }\n    }\n\n    /**\n     * Handle an exception that occurred while processing a job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $queueJob\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleException(Job $queueJob, Throwable $e)\n    {\n        $this->raiseExceptionOccurredJobEvent($queueJob, $e);\n\n        $queueJob->fail($e);\n\n        throw $e;\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        //\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->push($job, $data, $queue);\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/TimeoutExceededException.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass TimeoutExceededException extends MaxAttemptsExceededException\n{\n    /**\n     * Create a new instance for the job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return static\n     */\n    public static function forJob($job)\n    {\n        return tap(new static($job->resolveName().' has timed out.'), function ($e) use ($job) {\n            $e->job = $job;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/Worker.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nuse Illuminate\\Contracts\\Cache\\Repository as CacheContract;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueManager;\nuse Illuminate\\Database\\DetectsLostConnections;\nuse Illuminate\\Queue\\Events\\JobAttempted;\nuse Illuminate\\Queue\\Events\\JobExceptionOccurred;\nuse Illuminate\\Queue\\Events\\JobPopped;\nuse Illuminate\\Queue\\Events\\JobPopping;\nuse Illuminate\\Queue\\Events\\JobProcessed;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Illuminate\\Queue\\Events\\JobReleasedAfterException;\nuse Illuminate\\Queue\\Events\\JobTimedOut;\nuse Illuminate\\Queue\\Events\\Looping;\nuse Illuminate\\Queue\\Events\\WorkerStarting;\nuse Illuminate\\Queue\\Events\\WorkerStopping;\nuse Illuminate\\Support\\Carbon;\nuse Throwable;\n\nclass Worker\n{\n    use DetectsLostConnections;\n\n    const EXIT_SUCCESS = 0;\n    const EXIT_ERROR = 1;\n    const EXIT_MEMORY_LIMIT = 12;\n\n    /**\n     * The name of the worker.\n     *\n     * @var string|null\n     */\n    protected $name;\n\n    /**\n     * The queue manager instance.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    protected $manager;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The cache repository implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * The exception handler instance.\n     *\n     * @var \\Illuminate\\Contracts\\Debug\\ExceptionHandler\n     */\n    protected $exceptions;\n\n    /**\n     * The callback used to determine if the application is in maintenance mode.\n     *\n     * @var callable\n     */\n    protected $isDownForMaintenance;\n\n    /**\n     * The callback used to reset the application's scope.\n     *\n     * @var callable\n     */\n    protected $resetScope;\n\n    /**\n     * Indicates if the worker should exit.\n     *\n     * @var bool\n     */\n    public $shouldQuit = false;\n\n    /**\n     * Indicates if the worker is paused.\n     *\n     * @var bool\n     */\n    public $paused = false;\n\n    /**\n     * The callbacks used to pop jobs from queues.\n     *\n     * @var callable[]\n     */\n    protected static $popCallbacks = [];\n\n    /**\n     * The custom exit code to be used when memory is exceeded.\n     *\n     * @var int|null\n     */\n    public static $memoryExceededExitCode;\n\n    /**\n     * Indicates if the worker should check for the restart signal in the cache.\n     *\n     * @var bool\n     */\n    public static $restartable = true;\n\n    /**\n     * Indicates if the worker should check for the paused signal in the cache.\n     *\n     * @var bool\n     */\n    public static $pausable = true;\n\n    /**\n     * Create a new queue worker.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $manager\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @param  \\Illuminate\\Contracts\\Debug\\ExceptionHandler  $exceptions\n     * @param  callable  $isDownForMaintenance\n     * @param  callable|null  $resetScope\n     */\n    public function __construct(\n        QueueManager $manager,\n        Dispatcher $events,\n        ExceptionHandler $exceptions,\n        callable $isDownForMaintenance,\n        ?callable $resetScope = null,\n    ) {\n        $this->events = $events;\n        $this->manager = $manager;\n        $this->exceptions = $exceptions;\n        $this->isDownForMaintenance = $isDownForMaintenance;\n        $this->resetScope = $resetScope;\n    }\n\n    /**\n     * Listen to the given queue in a loop.\n     *\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return int\n     */\n    public function daemon($connectionName, $queue, WorkerOptions $options)\n    {\n        if ($supportsAsyncSignals = $this->supportsAsyncSignals()) {\n            $this->listenForSignals();\n        }\n\n        $lastRestart = $this->getTimestampOfLastQueueRestart();\n\n        [$startTime, $jobsProcessed] = [hrtime(true) / 1e9, 0];\n\n        $this->raiseWorkerStartingEvent($connectionName, $queue, $options);\n\n        while (true) {\n            // Before reserving any jobs, we will make sure this queue is not paused and\n            // if it is we will just pause this worker for a given amount of time and\n            // make sure we do not need to kill this worker process off completely.\n            if (! $this->daemonShouldRun($options, $connectionName, $queue)) {\n                [$status, $reason] = $this->pauseWorker($options, $lastRestart);\n\n                if (! is_null($status)) {\n                    return $this->stop($status, $options, $reason);\n                }\n\n                continue;\n            }\n\n            if (isset($this->resetScope)) {\n                ($this->resetScope)();\n            }\n\n            // First, we will attempt to get the next job off of the queue. We will also\n            // register the timeout handler and reset the alarm for this job so it is\n            // not stuck in a frozen state forever. Then, we can fire off this job.\n            $job = $this->getNextJob(\n                $this->manager->connection($connectionName), $queue\n            );\n\n            if ($supportsAsyncSignals) {\n                $this->registerTimeoutHandler($job, $options);\n            }\n\n            // If the daemon should run (not in maintenance mode, etc.), then we can run\n            // fire off this job for processing. Otherwise, we will need to sleep the\n            // worker so no more jobs are processed until they should be processed.\n            if ($job) {\n                $jobsProcessed++;\n\n                $this->runJob($job, $connectionName, $options);\n\n                if ($options->rest > 0) {\n                    $this->sleep($options->rest);\n                }\n            } else {\n                $this->sleep($options->sleep);\n            }\n\n            if ($supportsAsyncSignals) {\n                $this->resetTimeoutHandler();\n            }\n\n            // Finally, we will check to see if we have exceeded our memory limits or if\n            // the queue should restart based on other indications. If so, we'll stop\n            // this worker and let whatever is \"monitoring\" it restart the process.\n            [$status, $reason] = $this->stopIfNecessary(\n                $options, $lastRestart, $startTime, $jobsProcessed, $job\n            );\n\n            if (! is_null($status)) {\n                return $this->stop($status, $options, $reason);\n            }\n        }\n    }\n\n    /**\n     * Register the worker timeout handler.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job|null  $job\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return void\n     */\n    protected function registerTimeoutHandler($job, WorkerOptions $options)\n    {\n        // We will register a signal handler for the alarm signal so that we can kill this\n        // process if it is running too long because it has frozen. This uses the async\n        // signals supported in recent versions of PHP to accomplish it conveniently.\n        pcntl_signal(SIGALRM, function () use ($job, $options) {\n            if ($job) {\n                $this->markJobAsFailedIfWillExceedMaxAttempts(\n                    $job->getConnectionName(), $job, (int) $options->maxTries, $e = $this->timeoutExceededException($job)\n                );\n\n                $this->markJobAsFailedIfWillExceedMaxExceptions(\n                    $job->getConnectionName(), $job, $e\n                );\n\n                $this->markJobAsFailedIfItShouldFailOnTimeout(\n                    $job->getConnectionName(), $job, $e\n                );\n\n                $this->events->dispatch(new JobTimedOut(\n                    $job->getConnectionName(), $job\n                ));\n            }\n\n            $this->kill(static::EXIT_ERROR, $options);\n        }, true);\n\n        pcntl_alarm(\n            max($this->timeoutForJob($job, $options), 0)\n        );\n    }\n\n    /**\n     * Reset the worker timeout handler.\n     *\n     * @return void\n     */\n    protected function resetTimeoutHandler()\n    {\n        pcntl_alarm(0);\n    }\n\n    /**\n     * Get the appropriate timeout for the given job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job|null  $job\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return int\n     */\n    protected function timeoutForJob($job, WorkerOptions $options)\n    {\n        return $job && ! is_null($job->timeout()) ? $job->timeout() : $options->timeout;\n    }\n\n    /**\n     * Determine if the daemon should process on this iteration.\n     *\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @return bool\n     */\n    protected function daemonShouldRun(WorkerOptions $options, $connectionName, $queue)\n    {\n        return ! ((($this->isDownForMaintenance)() && ! $options->force) ||\n            $this->paused ||\n            $this->events->until(new Looping($connectionName, $queue)) === false);\n    }\n\n    /**\n     * Pause the worker for the current loop.\n     *\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @param  int  $lastRestart\n     * @return array|null\n     */\n    protected function pauseWorker(WorkerOptions $options, $lastRestart)\n    {\n        $this->sleep($options->sleep > 0 ? $options->sleep : 1);\n\n        return $this->stopIfNecessary($options, $lastRestart);\n    }\n\n    /**\n     * Determine the exit code to stop the process if necessary.\n     *\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @param  int  $lastRestart\n     * @param  int  $startTime\n     * @param  int  $jobsProcessed\n     * @param  mixed  $job\n     * @return array|null\n     */\n    protected function stopIfNecessary(WorkerOptions $options, $lastRestart, $startTime = 0, $jobsProcessed = 0, $job = null)\n    {\n        return match (true) {\n            $this->shouldQuit => [static::EXIT_SUCCESS, WorkerStopReason::Interrupted],\n            $this->memoryExceeded($options->memory) => [static::$memoryExceededExitCode ?? static::EXIT_MEMORY_LIMIT, WorkerStopReason::MaxMemoryExceeded],\n            $this->queueShouldRestart($lastRestart) => [static::EXIT_SUCCESS, WorkerStopReason::ReceivedRestartSignal],\n            $options->stopWhenEmpty && is_null($job) => [static::EXIT_SUCCESS, WorkerStopReason::QueueEmpty],\n            $options->maxTime && hrtime(true) / 1e9 - $startTime >= $options->maxTime => [static::EXIT_SUCCESS, WorkerStopReason::MaxTimeExceeded],\n            $options->maxJobs && $jobsProcessed >= $options->maxJobs => [static::EXIT_SUCCESS, WorkerStopReason::MaxJobsExceeded],\n            default => null\n        };\n    }\n\n    /**\n     * Process the next job on the queue.\n     *\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return void\n     */\n    public function runNextJob($connectionName, $queue, WorkerOptions $options)\n    {\n        $job = $this->getNextJob(\n            $this->manager->connection($connectionName), $queue\n        );\n\n        // If we're able to pull a job off of the stack, we will process it and then return\n        // from this method. If there is no job on the queue, we will \"sleep\" the worker\n        // for the specified number of seconds, then keep processing jobs after sleep.\n        if ($job) {\n            return $this->runJob($job, $connectionName, $options);\n        }\n\n        $this->sleep($options->sleep);\n    }\n\n    /**\n     * Get the next job from the queue connection.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Queue  $connection\n     * @param  string  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    protected function getNextJob($connection, $queue)\n    {\n        $popJobCallback = function ($queue, $index = 0) use ($connection) {\n            return $connection->pop($queue, $index);\n        };\n\n        $this->raiseBeforeJobPopEvent($connection->getConnectionName(), $queue);\n\n        try {\n            if (isset(static::$popCallbacks[$this->name ?? ''])) {\n                if (! is_null($job = (static::$popCallbacks[$this->name ?? ''])($popJobCallback, $queue))) {\n                    $this->raiseAfterJobPopEvent($connection->getConnectionName(), $job);\n                }\n\n                return $job;\n            }\n\n            foreach (explode(',', $queue) as $index => $queue) {\n                if ($this->queuePaused($connection->getConnectionName(), $queue)) {\n                    continue;\n                }\n\n                if (! is_null($job = $popJobCallback($queue, $index))) {\n                    $this->raiseAfterJobPopEvent($connection->getConnectionName(), $job);\n\n                    return $job;\n                }\n            }\n        } catch (Throwable $e) {\n            $this->exceptions->report($e);\n\n            $this->stopWorkerIfLostConnection($e);\n\n            $this->sleep(1);\n        }\n    }\n\n    /**\n     * Determine if a given connection and queue is paused.\n     *\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @return bool\n     */\n    protected function queuePaused($connectionName, $queue)\n    {\n        if (! static::$pausable) {\n            return false;\n        }\n\n        return $this->cache && $this->manager->isPaused($connectionName, $queue);\n    }\n\n    /**\n     * Process the given job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return void\n     */\n    protected function runJob($job, $connectionName, WorkerOptions $options)\n    {\n        try {\n            return $this->process($connectionName, $job, $options);\n        } catch (Throwable $e) {\n            $this->exceptions->report($e);\n\n            $this->stopWorkerIfLostConnection($e);\n        }\n    }\n\n    /**\n     * Stop the worker if we have lost connection to a database.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function stopWorkerIfLostConnection($e)\n    {\n        if ($this->causedByLostConnection($e)) {\n            $this->shouldQuit = true;\n        }\n    }\n\n    /**\n     * Process the given job from the queue.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function process($connectionName, $job, WorkerOptions $options)\n    {\n        try {\n            // First we will raise the before job event and determine if the job has already run\n            // over its maximum attempt limits, which could primarily happen when this job is\n            // continually timing out and not actually throwing any exceptions from itself.\n            $this->raiseBeforeJobEvent($connectionName, $job);\n\n            $this->markJobAsFailedIfAlreadyExceedsMaxAttempts(\n                $connectionName, $job, (int) $options->maxTries\n            );\n\n            if ($job->isDeleted()) {\n                return $this->raiseAfterJobEvent($connectionName, $job);\n            }\n\n            // Here we will fire off the job and let it process. We will catch any exceptions, so\n            // they can be reported to the developer's logs, etc. Once the job is finished the\n            // proper events will be fired to let any listeners know this job has completed.\n            $job->fire();\n\n            $this->raiseAfterJobEvent($connectionName, $job);\n        } catch (Throwable $e) {\n            $exceptionOccurred = $e;\n\n            $this->handleJobException($connectionName, $job, $options, $e);\n        } finally {\n            $this->events->dispatch(new JobAttempted(\n                $connectionName, $job, $exceptionOccurred ?? null\n            ));\n        }\n    }\n\n    /**\n     * Handle an exception that occurred while the job was running.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleJobException($connectionName, $job, WorkerOptions $options, Throwable $e)\n    {\n        try {\n            // First, we will go ahead and mark the job as failed if it will exceed the maximum\n            // attempts it is allowed to run the next time we process it. If so we will just\n            // go ahead and mark it as failed now so we do not have to release this again.\n            if (! $job->hasFailed()) {\n                $this->markJobAsFailedIfWillExceedMaxAttempts(\n                    $connectionName, $job, (int) $options->maxTries, $e\n                );\n\n                $this->markJobAsFailedIfWillExceedMaxExceptions(\n                    $connectionName, $job, $e\n                );\n            }\n\n            $this->raiseExceptionOccurredJobEvent(\n                $connectionName, $job, $e\n            );\n        } finally {\n            // If we catch an exception, we will attempt to release the job back onto the queue\n            // so it is not lost entirely. This'll let the job be retried at a later time by\n            // another listener (or this same one). We will re-throw this exception after.\n            if (! $job->isDeleted() && ! $job->isReleased() && ! $job->hasFailed()) {\n                $backoff = $this->calculateBackoff($job, $options);\n\n                $job->release($backoff);\n\n                $this->events->dispatch(new JobReleasedAfterException(\n                    $connectionName, $job, $backoff\n                ));\n            }\n        }\n\n        throw $e;\n    }\n\n    /**\n     * Mark the given job as failed if it has exceeded the maximum allowed attempts.\n     *\n     * This will likely be because the job previously exceeded a timeout.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  int  $maxTries\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function markJobAsFailedIfAlreadyExceedsMaxAttempts($connectionName, $job, $maxTries)\n    {\n        $maxTries = ! is_null($job->maxTries()) ? $job->maxTries() : $maxTries;\n\n        $retryUntil = $job->retryUntil();\n\n        if ($retryUntil && Carbon::now()->getTimestamp() <= $retryUntil) {\n            return;\n        }\n\n        if (! $retryUntil && ($maxTries === 0 || $job->attempts() <= $maxTries)) {\n            return;\n        }\n\n        $this->failJob($job, $e = $this->maxAttemptsExceededException($job));\n\n        throw $e;\n    }\n\n    /**\n     * Mark the given job as failed if it has exceeded the maximum allowed attempts.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  int  $maxTries\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function markJobAsFailedIfWillExceedMaxAttempts($connectionName, $job, $maxTries, Throwable $e)\n    {\n        $maxTries = ! is_null($job->maxTries()) ? $job->maxTries() : $maxTries;\n\n        if ($job->retryUntil() && $job->retryUntil() <= Carbon::now()->getTimestamp()) {\n            $this->failJob($job, $e);\n        }\n\n        if (! $job->retryUntil() && $maxTries > 0 && $job->attempts() >= $maxTries) {\n            $this->failJob($job, $e);\n        }\n    }\n\n    /**\n     * Mark the given job as failed if it has exceeded the maximum allowed attempts.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function markJobAsFailedIfWillExceedMaxExceptions($connectionName, $job, Throwable $e)\n    {\n        if (! $this->cache || is_null($uuid = $job->uuid()) ||\n            is_null($maxExceptions = $job->maxExceptions())) {\n            return;\n        }\n\n        if (! $this->cache->get('job-exceptions:'.$uuid)) {\n            $this->cache->put('job-exceptions:'.$uuid, 0, Carbon::now()->addDay());\n        }\n\n        if ($maxExceptions <= $this->cache->increment('job-exceptions:'.$uuid)) {\n            $this->cache->forget('job-exceptions:'.$uuid);\n\n            $this->failJob($job, $e);\n        }\n    }\n\n    /**\n     * Mark the given job as failed if it should fail on timeouts.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function markJobAsFailedIfItShouldFailOnTimeout($connectionName, $job, Throwable $e)\n    {\n        if (method_exists($job, 'shouldFailOnTimeout') ? $job->shouldFailOnTimeout() : false) {\n            $this->failJob($job, $e);\n        }\n    }\n\n    /**\n     * Mark the given job as failed and raise the relevant event.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function failJob($job, Throwable $e)\n    {\n        $job->fail($e);\n    }\n\n    /**\n     * Calculate the backoff for the given job.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return int\n     */\n    protected function calculateBackoff($job, WorkerOptions $options)\n    {\n        $backoff = explode(\n            ',',\n            method_exists($job, 'backoff') && ! is_null($job->backoff())\n                ? $job->backoff()\n                : $options->backoff\n        );\n\n        return (int) ($backoff[$job->attempts() - 1] ?? last($backoff));\n    }\n\n    /**\n     * Raise an event indicating the worker is starting.\n     *\n     * @param  string  $connectionName\n     * @param  string  $queue\n     * @param  \\Illuminate\\Queue\\WorkerOptions  $options\n     * @return void\n     */\n    protected function raiseWorkerStartingEvent($connectionName, $queue, $options)\n    {\n        $this->events->dispatch(new WorkerStarting($connectionName, $queue, $options));\n    }\n\n    /**\n     * Raise an event indicating a job is being popped from the queue.\n     *\n     * @param  string  $connectionName\n     * @param  string|null  $queue\n     * @return void\n     */\n    protected function raiseBeforeJobPopEvent($connectionName, $queue = null)\n    {\n        $this->events->dispatch(new JobPopping($connectionName, $queue));\n    }\n\n    /**\n     * Raise an event indicating a job has been popped from the queue.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job|null  $job\n     * @return void\n     */\n    protected function raiseAfterJobPopEvent($connectionName, $job)\n    {\n        $this->events->dispatch(new JobPopped(\n            $connectionName, $job\n        ));\n    }\n\n    /**\n     * Raise an event indicating a job is being processed.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return void\n     */\n    protected function raiseBeforeJobEvent($connectionName, $job)\n    {\n        $this->events->dispatch(new JobProcessing(\n            $connectionName, $job\n        ));\n    }\n\n    /**\n     * Raise an event indicating a job has been processed.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return void\n     */\n    protected function raiseAfterJobEvent($connectionName, $job)\n    {\n        $this->events->dispatch(new JobProcessed(\n            $connectionName, $job\n        ));\n    }\n\n    /**\n     * Raise the exception occurred queue job event.\n     *\n     * @param  string  $connectionName\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    protected function raiseExceptionOccurredJobEvent($connectionName, $job, Throwable $e)\n    {\n        $this->events->dispatch(new JobExceptionOccurred(\n            $connectionName, $job, $e\n        ));\n    }\n\n    /**\n     * Determine if the queue worker should restart.\n     *\n     * @param  int|null  $lastRestart\n     * @return bool\n     */\n    protected function queueShouldRestart($lastRestart)\n    {\n        if (! static::$restartable) {\n            return false;\n        }\n\n        return $this->getTimestampOfLastQueueRestart() != $lastRestart;\n    }\n\n    /**\n     * Get the last queue restart timestamp, or null.\n     *\n     * @return int|null\n     */\n    protected function getTimestampOfLastQueueRestart()\n    {\n        if (! static::$restartable) {\n            return null;\n        }\n\n        if ($this->cache) {\n            return $this->cache->get('illuminate:queue:restart');\n        }\n    }\n\n    /**\n     * Enable async signals for the process.\n     *\n     * @return void\n     */\n    protected function listenForSignals()\n    {\n        pcntl_async_signals(true);\n\n        pcntl_signal(SIGQUIT, fn () => $this->shouldQuit = true);\n        pcntl_signal(SIGTERM, fn () => $this->shouldQuit = true);\n        pcntl_signal(SIGINT, fn () => $this->shouldQuit = true);\n        pcntl_signal(SIGUSR2, fn () => $this->paused = true);\n        pcntl_signal(SIGCONT, fn () => $this->paused = false);\n    }\n\n    /**\n     * Determine if \"async\" signals are supported.\n     *\n     * @return bool\n     */\n    protected function supportsAsyncSignals()\n    {\n        return extension_loaded('pcntl');\n    }\n\n    /**\n     * Determine if the memory limit has been exceeded.\n     *\n     * @param  int  $memoryLimit\n     * @return bool\n     */\n    public function memoryExceeded($memoryLimit)\n    {\n        return ((int) $memoryLimit) > 0 && (memory_get_usage(true) / 1024 / 1024) >= ((int) $memoryLimit);\n    }\n\n    /**\n     * Stop listening and bail out of the script.\n     *\n     * @param  int  $status\n     * @param  WorkerOptions|null  $options\n     * @param  WorkerStopReason|null  $reason\n     * @return int\n     */\n    public function stop($status = 0, $options = null, $reason = null)\n    {\n        $this->events->dispatch(new WorkerStopping($status, $options, $reason));\n\n        return $status;\n    }\n\n    /**\n     * Kill the process.\n     *\n     * @param  int  $status\n     * @param  \\Illuminate\\Queue\\WorkerOptions|null  $options\n     * @return never\n     */\n    public function kill($status = 0, $options = null)\n    {\n        $this->events->dispatch(new WorkerStopping($status, $options));\n\n        if (extension_loaded('posix')) {\n            posix_kill(getmypid(), SIGKILL);\n        }\n\n        exit($status);\n    }\n\n    /**\n     * Create an instance of MaxAttemptsExceededException.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return \\Illuminate\\Queue\\MaxAttemptsExceededException\n     */\n    protected function maxAttemptsExceededException($job)\n    {\n        return MaxAttemptsExceededException::forJob($job);\n    }\n\n    /**\n     * Create an instance of TimeoutExceededException.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Job  $job\n     * @return \\Illuminate\\Queue\\TimeoutExceededException\n     */\n    protected function timeoutExceededException($job)\n    {\n        return TimeoutExceededException::forJob($job);\n    }\n\n    /**\n     * Sleep the script for a given number of seconds.\n     *\n     * @param  int|float  $seconds\n     * @return void\n     */\n    public function sleep($seconds)\n    {\n        if ($seconds < 1) {\n            usleep($seconds * 1_000_000);\n        } else {\n            sleep($seconds);\n        }\n    }\n\n    /**\n     * Set the cache repository implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     * @return $this\n     */\n    public function setCache(CacheContract $cache)\n    {\n        $this->cache = $cache;\n\n        return $this;\n    }\n\n    /**\n     * Set the name of the worker.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setName($name)\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Register a callback to be executed to pick jobs.\n     *\n     * @param  string  $workerName\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function popUsing($workerName, $callback)\n    {\n        if (is_null($callback)) {\n            unset(static::$popCallbacks[$workerName]);\n        } else {\n            static::$popCallbacks[$workerName] = $callback;\n        }\n    }\n\n    /**\n     * Get the queue manager instance.\n     *\n     * @return \\Illuminate\\Contracts\\Queue\\Factory\n     */\n    public function getManager()\n    {\n        return $this->manager;\n    }\n\n    /**\n     * Set the queue manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Queue\\Factory  $manager\n     * @return void\n     */\n    public function setManager(QueueManager $manager)\n    {\n        $this->manager = $manager;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/WorkerOptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nclass WorkerOptions\n{\n    /**\n     * The name of the worker.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The number of seconds to wait before retrying a job that encountered an uncaught exception.\n     *\n     * @var int|int[]\n     */\n    public $backoff;\n\n    /**\n     * The maximum amount of RAM the worker may consume.\n     *\n     * @var int\n     */\n    public $memory;\n\n    /**\n     * The maximum number of seconds a child worker may run.\n     *\n     * @var int\n     */\n    public $timeout;\n\n    /**\n     * The number of seconds to wait in between polling the queue.\n     *\n     * @var int\n     */\n    public $sleep;\n\n    /**\n     * The number of seconds to rest between jobs.\n     *\n     * @var int\n     */\n    public $rest;\n\n    /**\n     * The maximum number of times a job may be attempted.\n     *\n     * @var int\n     */\n    public $maxTries;\n\n    /**\n     * Indicates if the worker should run in maintenance mode.\n     *\n     * @var bool\n     */\n    public $force;\n\n    /**\n     * Indicates if the worker should stop when the queue is empty.\n     *\n     * @var bool\n     */\n    public $stopWhenEmpty;\n\n    /**\n     * The maximum number of jobs to run.\n     *\n     * @var int\n     */\n    public $maxJobs;\n\n    /**\n     * The maximum number of seconds a worker may live.\n     *\n     * @var int\n     */\n    public $maxTime;\n\n    /**\n     * Create a new worker options instance.\n     *\n     * @param  string  $name\n     * @param  int|int[]  $backoff\n     * @param  int  $memory\n     * @param  int  $timeout\n     * @param  int  $sleep\n     * @param  int  $maxTries\n     * @param  bool  $force\n     * @param  bool  $stopWhenEmpty\n     * @param  int  $maxJobs\n     * @param  int  $maxTime\n     * @param  int  $rest\n     */\n    public function __construct(\n        $name = 'default',\n        $backoff = 0,\n        $memory = 128,\n        $timeout = 60,\n        $sleep = 3,\n        $maxTries = 1,\n        $force = false,\n        $stopWhenEmpty = false,\n        $maxJobs = 0,\n        $maxTime = 0,\n        $rest = 0,\n    ) {\n        $this->name = $name;\n        $this->backoff = $backoff;\n        $this->sleep = $sleep;\n        $this->rest = $rest;\n        $this->force = $force;\n        $this->memory = $memory;\n        $this->timeout = $timeout;\n        $this->maxTries = $maxTries;\n        $this->stopWhenEmpty = $stopWhenEmpty;\n        $this->maxJobs = $maxJobs;\n        $this->maxTime = $maxTime;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/WorkerStopReason.php",
    "content": "<?php\n\nnamespace Illuminate\\Queue;\n\nenum WorkerStopReason: string\n{\n    case Interrupted = 'interrupted';\n    case MaxJobsExceeded = 'max_jobs';\n    case MaxMemoryExceeded = 'memory';\n    case MaxTimeExceeded = 'max_time';\n    case QueueEmpty = 'empty';\n    case ReceivedRestartSignal = 'restart_signal';\n}\n"
  },
  {
    "path": "src/Illuminate/Queue/composer.json",
    "content": "{\n    \"name\": \"illuminate/queue\",\n    \"description\": \"The Illuminate Queue package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/console\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/database\": \"^13.0\",\n        \"illuminate/filesystem\": \"^13.0\",\n        \"illuminate/pipeline\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"laravel/serializable-closure\": \"^2.0.10\",\n        \"ramsey/uuid\": \"^4.7\",\n        \"symfony/process\": \"^7.4.5 || ^8.0.5\"\n    },\n    \"suggest\": {\n        \"ext-filter\": \"Required to use the SQS queue worker.\",\n        \"ext-mbstring\": \"Required to use the database failed job providers.\",\n        \"ext-pcntl\": \"Required to use all features of the queue worker.\",\n        \"ext-pdo\": \"Required to use the database queue worker.\",\n        \"ext-posix\": \"Required to use all features of the queue worker.\",\n        \"aws/aws-sdk-php\": \"Required to use the SQS queue driver and DynamoDb failed job storage (^3.322.9).\",\n        \"illuminate/redis\": \"Required to use the Redis queue driver (^13.0).\",\n        \"pda/pheanstalk\": \"Required to use the Beanstalk queue driver (^7.0 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Queue\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Redis/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/Connection.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse Closure;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Redis\\Events\\CommandExecuted;\nuse Illuminate\\Redis\\Events\\CommandFailed;\nuse Illuminate\\Redis\\Limiters\\ConcurrencyLimiterBuilder;\nuse Illuminate\\Redis\\Limiters\\DurationLimiterBuilder;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Throwable;\n\nabstract class Connection\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The Redis client.\n     *\n     * @var \\Redis\n     */\n    protected $client;\n\n    /**\n     * The Redis connection name.\n     *\n     * @var string|null\n     */\n    protected $name;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    protected $events;\n\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @param  string  $method\n     * @return void\n     */\n    abstract public function createSubscription($channels, Closure $callback, $method = 'subscribe');\n\n    /**\n     * Funnel a callback for a maximum number of simultaneous executions.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Redis\\Limiters\\ConcurrencyLimiterBuilder\n     */\n    public function funnel($name)\n    {\n        return new ConcurrencyLimiterBuilder($this, $name);\n    }\n\n    /**\n     * Throttle a callback for a maximum number of executions over a given duration.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Redis\\Limiters\\DurationLimiterBuilder\n     */\n    public function throttle($name)\n    {\n        return new DurationLimiterBuilder($this, $name);\n    }\n\n    /**\n     * Get the underlying Redis client.\n     *\n     * @return mixed\n     */\n    public function client()\n    {\n        return $this->client;\n    }\n\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function subscribe($channels, Closure $callback)\n    {\n        $this->createSubscription($channels, $callback, __FUNCTION__);\n    }\n\n    /**\n     * Subscribe to a set of given channels with wildcards.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function psubscribe($channels, Closure $callback)\n    {\n        $this->createSubscription($channels, $callback, __FUNCTION__);\n    }\n\n    /**\n     * Run a command against the Redis database.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    public function command($method, array $parameters = [])\n    {\n        $start = microtime(true);\n\n        try {\n            $result = $this->client->{$method}(...$parameters);\n        } catch (Throwable $e) {\n            $this->events?->dispatch(new CommandFailed(\n                $method, $this->parseParametersForEvent($parameters), $e, $this\n            ));\n\n            throw $e;\n        }\n\n        $time = round((microtime(true) - $start) * 1000, 2);\n\n        $this->events?->dispatch(new CommandExecuted(\n            $method, $this->parseParametersForEvent($parameters), $time, $this\n        ));\n\n        return $result;\n    }\n\n    /**\n     * Parse the command's parameters for event dispatching.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function parseParametersForEvent(array $parameters)\n    {\n        return $parameters;\n    }\n\n    /**\n     * Fire the given event if possible.\n     *\n     * @param  mixed  $event\n     * @return void\n     *\n     * @deprecated since Laravel 11.x\n     */\n    protected function event($event)\n    {\n        $this->events?->dispatch($event);\n    }\n\n    /**\n     * Register a Redis command listener with the connection.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function listen(Closure $callback)\n    {\n        $this->events?->listen(CommandExecuted::class, $callback);\n    }\n\n    /**\n     * Register a Redis command failure listener with the connection.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function listenForFailures(Closure $callback)\n    {\n        $this->events?->listen(CommandFailed::class, $callback);\n    }\n\n    /**\n     * Get the connection name.\n     *\n     * @return string|null\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * Set the connection's name.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setName($name)\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Get the event dispatcher used by the connection.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher|null\n     */\n    public function getEventDispatcher()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Set the event dispatcher instance on the connection.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return void\n     */\n    public function setEventDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Unset the event dispatcher instance on the connection.\n     *\n     * @return void\n     */\n    public function unsetEventDispatcher()\n    {\n        $this->events = null;\n    }\n\n    /**\n     * Pass other method calls down to the underlying client.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->command($method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/PacksPhpRedisValues.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse Redis;\nuse RuntimeException;\nuse UnexpectedValueException;\n\ntrait PacksPhpRedisValues\n{\n    /**\n     * Indicates if Redis supports packing.\n     *\n     * @var bool|null\n     */\n    protected $supportsPacking;\n\n    /**\n     * Indicates if Redis supports LZF compression.\n     *\n     * @var bool|null\n     */\n    protected $supportsLzf;\n\n    /**\n     * Indicates if Redis supports Zstd compression.\n     *\n     * @var bool|null\n     */\n    protected $supportsZstd;\n\n    /**\n     * Prepares the given values to be used with the `eval` command, including serialization and compression.\n     *\n     * @param  array<int|string,string>  $values\n     * @return array<int|string,string>\n     *\n     * @throws \\RuntimeException\n     * @throws \\UnexpectedValueException\n     */\n    public function pack(array $values): array\n    {\n        if (empty($values)) {\n            return $values;\n        }\n\n        if ($this->supportsPacking()) {\n            return array_map($this->client->_pack(...), $values);\n        }\n\n        if ($this->compressed()) {\n            if ($this->supportsLzf() && $this->lzfCompressed()) {\n                if (! function_exists('lzf_compress')) {\n                    throw new RuntimeException(\"'lzf' extension required to call 'lzf_compress'.\");\n                }\n\n                $processor = function ($value) {\n                    return \\lzf_compress($this->client->_serialize($value));\n                };\n            } elseif ($this->supportsZstd() && $this->zstdCompressed()) {\n                if (! function_exists('zstd_compress')) {\n                    throw new RuntimeException(\"'zstd' extension required to call 'zstd_compress'.\");\n                }\n\n                $compressionLevel = $this->client->getOption(Redis::OPT_COMPRESSION_LEVEL);\n\n                $processor = function ($value) use ($compressionLevel) {\n                    return \\zstd_compress(\n                        $this->client->_serialize($value),\n                        $compressionLevel === 0 ? Redis::COMPRESSION_ZSTD_DEFAULT : $compressionLevel\n                    );\n                };\n            } else {\n                throw new UnexpectedValueException(sprintf(\n                    'Unsupported phpredis compression in use [%d].',\n                    $this->client->getOption(Redis::OPT_COMPRESSION)\n                ));\n            }\n        } else {\n            $processor = function ($value) {\n                return $this->client->_serialize($value);\n            };\n        }\n\n        return array_map($processor, $values);\n    }\n\n    /**\n     * Execute the given callback without serialization or compression when applicable.\n     *\n     * @param  callable  $callback\n     * @return mixed\n     */\n    public function withoutSerializationOrCompression(callable $callback)\n    {\n        $client = $this->client;\n\n        $oldSerializer = null;\n\n        if ($this->serialized()) {\n            $oldSerializer = $client->getOption(Redis::OPT_SERIALIZER);\n            $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);\n        }\n\n        $oldCompressor = null;\n\n        if ($this->compressed()) {\n            $oldCompressor = $client->getOption(Redis::OPT_COMPRESSION);\n            $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_NONE);\n        }\n\n        try {\n            return $callback();\n        } finally {\n            if ($oldSerializer !== null) {\n                $client->setOption(Redis::OPT_SERIALIZER, $oldSerializer);\n            }\n\n            if ($oldCompressor !== null) {\n                $client->setOption(Redis::OPT_COMPRESSION, $oldCompressor);\n            }\n        }\n    }\n\n    /**\n     * Determine if serialization is enabled.\n     *\n     * @return bool\n     */\n    public function serialized(): bool\n    {\n        return defined('Redis::OPT_SERIALIZER') &&\n               $this->client->getOption(Redis::OPT_SERIALIZER) !== Redis::SERIALIZER_NONE;\n    }\n\n    /**\n     * Determine if compression is enabled.\n     *\n     * @return bool\n     */\n    public function compressed(): bool\n    {\n        return defined('Redis::OPT_COMPRESSION') &&\n               $this->client->getOption(Redis::OPT_COMPRESSION) !== Redis::COMPRESSION_NONE;\n    }\n\n    /**\n     * Determine if LZF compression is enabled.\n     *\n     * @return bool\n     */\n    public function lzfCompressed(): bool\n    {\n        return defined('Redis::COMPRESSION_LZF') &&\n               $this->client->getOption(Redis::OPT_COMPRESSION) === Redis::COMPRESSION_LZF;\n    }\n\n    /**\n     * Determine if ZSTD compression is enabled.\n     *\n     * @return bool\n     */\n    public function zstdCompressed(): bool\n    {\n        return defined('Redis::COMPRESSION_ZSTD') &&\n               $this->client->getOption(Redis::OPT_COMPRESSION) === Redis::COMPRESSION_ZSTD;\n    }\n\n    /**\n     * Determine if LZ4 compression is enabled.\n     *\n     * @return bool\n     */\n    public function lz4Compressed(): bool\n    {\n        return defined('Redis::COMPRESSION_LZ4') &&\n               $this->client->getOption(Redis::OPT_COMPRESSION) === Redis::COMPRESSION_LZ4;\n    }\n\n    /**\n     * Determine if the current PhpRedis extension version supports packing.\n     *\n     * @return bool\n     */\n    protected function supportsPacking(): bool\n    {\n        if ($this->supportsPacking === null) {\n            $this->supportsPacking = $this->phpRedisVersionAtLeast('5.3.5');\n        }\n\n        return $this->supportsPacking;\n    }\n\n    /**\n     * Determine if the current PhpRedis extension version supports LZF compression.\n     *\n     * @return bool\n     */\n    protected function supportsLzf(): bool\n    {\n        if ($this->supportsLzf === null) {\n            $this->supportsLzf = $this->phpRedisVersionAtLeast('4.3.0');\n        }\n\n        return $this->supportsLzf;\n    }\n\n    /**\n     * Determine if the current PhpRedis extension version supports Zstd compression.\n     *\n     * @return bool\n     */\n    protected function supportsZstd(): bool\n    {\n        if ($this->supportsZstd === null) {\n            $this->supportsZstd = $this->phpRedisVersionAtLeast('5.1.0');\n        }\n\n        return $this->supportsZstd;\n    }\n\n    /**\n     * Determine if the PhpRedis extension version is at least the given version.\n     *\n     * @param  string  $version\n     * @return bool\n     */\n    protected function phpRedisVersionAtLeast(string $version): bool\n    {\n        $phpredisVersion = phpversion('redis');\n\n        return $phpredisVersion !== false && version_compare($phpredisVersion, $version, '>=');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/PhpRedisClusterConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse InvalidArgumentException;\n\nclass PhpRedisClusterConnection extends PhpRedisConnection\n{\n    /**\n     * The RedisCluster client.\n     *\n     * @var \\RedisCluster\n     */\n    protected $client;\n\n    /**\n     * The default node to use from the cluster.\n     *\n     * @var string|array\n     */\n    protected $defaultNode;\n\n    /**\n     * Scan all keys based on the given options.\n     *\n     * @param  mixed  $cursor\n     * @param  array  $options\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    #[\\Override]\n    public function scan($cursor, $options = [])\n    {\n        $result = $this->client->scan($cursor,\n            $options['node'] ?? $this->defaultNode(),\n            $options['match'] ?? '*',\n            $options['count'] ?? 10\n        );\n\n        if ($result === false) {\n            $result = [];\n        }\n\n        return $cursor === 0 && empty($result) ? false : [$cursor, $result];\n    }\n\n    /**\n     * Flush the selected Redis database on all master nodes.\n     *\n     * @return void\n     */\n    public function flushdb()\n    {\n        $arguments = func_get_args();\n\n        $async = strtoupper((string) ($arguments[0] ?? null)) === 'ASYNC';\n\n        foreach ($this->client->_masters() as $master) {\n            $async\n                ? $this->command('rawCommand', [$master, 'flushdb', 'async'])\n                : $this->command('flushdb', [$master]);\n        }\n    }\n\n    /**\n     * Return default node to use for cluster.\n     *\n     * @return string|array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    private function defaultNode()\n    {\n        if (! isset($this->defaultNode)) {\n            $this->defaultNode = $this->client->_masters()[0] ?? throw new InvalidArgumentException('Unable to determine default node. No master nodes found in the cluster.');\n        }\n\n        return $this->defaultNode;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/PhpRedisConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse Closure;\nuse Illuminate\\Contracts\\Redis\\Connection as ConnectionContract;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse RedisException;\n\n/**\n * @mixin \\Redis\n */\nclass PhpRedisConnection extends Connection implements ConnectionContract\n{\n    use PacksPhpRedisValues;\n\n    /**\n     * The connection creation callback.\n     *\n     * @var callable\n     */\n    protected $connector;\n\n    /**\n     * The connection configuration array.\n     *\n     * @var array\n     */\n    protected $config;\n\n    /**\n     * Create a new PhpRedis connection.\n     *\n     * @param  \\Redis  $client\n     * @param  callable|null  $connector\n     * @param  array  $config\n     */\n    public function __construct($client, ?callable $connector = null, array $config = [])\n    {\n        $this->client = $client;\n        $this->config = $config;\n        $this->connector = $connector;\n    }\n\n    /**\n     * Returns the value of the given key.\n     *\n     * @param  string  $key\n     * @return string|null\n     */\n    public function get($key)\n    {\n        $result = $this->command('get', [$key]);\n\n        return $result !== false ? $result : null;\n    }\n\n    /**\n     * Get the values of all the given keys.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function mget(array $keys)\n    {\n        return array_map(function ($value) {\n            return $value !== false ? $value : null;\n        }, $this->command('mget', [$keys]));\n    }\n\n    /**\n     * Set the string value in the argument as the value of the key.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  string|null  $expireResolution\n     * @param  int|null  $expireTTL\n     * @param  string|null  $flag\n     * @return bool\n     */\n    public function set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)\n    {\n        return $this->command('set', [\n            $key,\n            $value,\n            $expireResolution ? [$flag, $expireResolution => $expireTTL] : null,\n        ]);\n    }\n\n    /**\n     * Set the given key if it doesn't exist.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return int\n     */\n    public function setnx($key, $value)\n    {\n        return (int) $this->command('setnx', [$key, $value]);\n    }\n\n    /**\n     * Get the value of the given hash fields.\n     *\n     * @param  string  $key\n     * @param  mixed  ...$dictionary\n     * @return array\n     */\n    public function hmget($key, ...$dictionary)\n    {\n        if (count($dictionary) === 1) {\n            $dictionary = $dictionary[0];\n        }\n\n        return array_values($this->command('hmget', [$key, $dictionary]));\n    }\n\n    /**\n     * Set the given hash fields to their respective values.\n     *\n     * @param  string  $key\n     * @param  mixed  ...$dictionary\n     * @return int\n     */\n    public function hmset($key, ...$dictionary)\n    {\n        if (count($dictionary) === 1) {\n            $dictionary = $dictionary[0];\n        } else {\n            $input = new Collection($dictionary);\n\n            $dictionary = $input->nth(2)->combine($input->nth(2, 1))->toArray();\n        }\n\n        return $this->command('hmset', [$key, $dictionary]);\n    }\n\n    /**\n     * Set the given hash field if it doesn't exist.\n     *\n     * @param  string  $hash\n     * @param  string  $key\n     * @param  string  $value\n     * @return int\n     */\n    public function hsetnx($hash, $key, $value)\n    {\n        return (int) $this->command('hsetnx', [$hash, $key, $value]);\n    }\n\n    /**\n     * Removes the first count occurrences of the value element from the list.\n     *\n     * @param  string  $key\n     * @param  int  $count\n     * @param  mixed  $value\n     * @return int|false\n     */\n    public function lrem($key, $count, $value)\n    {\n        return $this->command('lrem', [$key, $value, $count]);\n    }\n\n    /**\n     * Removes and returns the first element of the list stored at key.\n     *\n     * @param  mixed  ...$arguments\n     * @return array|null\n     */\n    public function blpop(...$arguments)\n    {\n        $result = $this->command('blpop', $arguments);\n\n        return empty($result) ? null : $result;\n    }\n\n    /**\n     * Removes and returns the last element of the list stored at key.\n     *\n     * @param  mixed  ...$arguments\n     * @return array|null\n     */\n    public function brpop(...$arguments)\n    {\n        $result = $this->command('brpop', $arguments);\n\n        return empty($result) ? null : $result;\n    }\n\n    /**\n     * Removes and returns a random element from the set value at key.\n     *\n     * @param  string  $key\n     * @param  int|null  $count\n     * @return mixed|false\n     */\n    public function spop($key, $count = 1)\n    {\n        return $this->command('spop', func_get_args());\n    }\n\n    /**\n     * Add one or more members to a sorted set or update its score if it already exists.\n     *\n     * @param  string  $key\n     * @param  mixed  ...$dictionary\n     * @return int\n     */\n    public function zadd($key, ...$dictionary)\n    {\n        if (is_array(end($dictionary))) {\n            foreach (array_pop($dictionary) as $member => $score) {\n                $dictionary[] = $score;\n                $dictionary[] = $member;\n            }\n        }\n\n        $options = [];\n\n        foreach (array_slice($dictionary, 0, 3) as $i => $value) {\n            if (in_array($value, ['nx', 'xx', 'ch', 'incr', 'gt', 'lt', 'NX', 'XX', 'CH', 'INCR', 'GT', 'LT'], true)) {\n                $options[] = $value;\n\n                unset($dictionary[$i]);\n            }\n        }\n\n        return $this->command('zadd', array_merge([$key], [$options], array_values($dictionary)));\n    }\n\n    /**\n     * Return elements with score between $min and $max.\n     *\n     * @param  string  $key\n     * @param  mixed  $min\n     * @param  mixed  $max\n     * @param  array  $options\n     * @return array\n     */\n    public function zrangebyscore($key, $min, $max, $options = [])\n    {\n        if (isset($options['limit']) && ! array_is_list($options['limit'])) {\n            $options['limit'] = [\n                $options['limit']['offset'],\n                $options['limit']['count'],\n            ];\n        }\n\n        return $this->command('zRangeByScore', [$key, $min, $max, $options]);\n    }\n\n    /**\n     * Return elements with score between $min and $max.\n     *\n     * @param  string  $key\n     * @param  mixed  $min\n     * @param  mixed  $max\n     * @param  array  $options\n     * @return array\n     */\n    public function zrevrangebyscore($key, $min, $max, $options = [])\n    {\n        if (isset($options['limit']) && ! array_is_list($options['limit'])) {\n            $options['limit'] = [\n                $options['limit']['offset'],\n                $options['limit']['count'],\n            ];\n        }\n\n        return $this->command('zRevRangeByScore', [$key, $min, $max, $options]);\n    }\n\n    /**\n     * Find the intersection between sets and store in a new set.\n     *\n     * @param  string  $output\n     * @param  array  $keys\n     * @param  array  $options\n     * @return int\n     */\n    public function zinterstore($output, $keys, $options = [])\n    {\n        return $this->command('zinterstore', [$output, $keys,\n            $options['weights'] ?? null,\n            $options['aggregate'] ?? 'sum',\n        ]);\n    }\n\n    /**\n     * Find the union between sets and store in a new set.\n     *\n     * @param  string  $output\n     * @param  array  $keys\n     * @param  array  $options\n     * @return int\n     */\n    public function zunionstore($output, $keys, $options = [])\n    {\n        return $this->command('zunionstore', [$output, $keys,\n            $options['weights'] ?? null,\n            $options['aggregate'] ?? 'sum',\n        ]);\n    }\n\n    /**\n     * Scans all keys based on options.\n     *\n     * @param  mixed  $cursor\n     * @param  array  $options\n     * @return mixed\n     */\n    public function scan($cursor, $options = [])\n    {\n        $result = $this->client->scan($cursor,\n            $options['match'] ?? '*',\n            $options['count'] ?? 10\n        );\n\n        if ($result === false) {\n            $result = [];\n        }\n\n        return $cursor === 0 && empty($result) ? false : [$cursor, $result];\n    }\n\n    /**\n     * Scans the given set for all values based on options.\n     *\n     * @param  string  $key\n     * @param  mixed  $cursor\n     * @param  array  $options\n     * @return mixed\n     */\n    public function zscan($key, $cursor, $options = [])\n    {\n        $result = $this->client->zscan($key, $cursor,\n            $options['match'] ?? '*',\n            $options['count'] ?? 10\n        );\n\n        if ($result === false) {\n            $result = [];\n        }\n\n        return $cursor === 0 && empty($result) ? false : [$cursor, $result];\n    }\n\n    /**\n     * Scans the given hash for all values based on options.\n     *\n     * @param  string  $key\n     * @param  mixed  $cursor\n     * @param  array  $options\n     * @return mixed\n     */\n    public function hscan($key, $cursor, $options = [])\n    {\n        $result = $this->client->hscan($key, $cursor,\n            $options['match'] ?? '*',\n            $options['count'] ?? 10\n        );\n\n        if ($result === false) {\n            $result = [];\n        }\n\n        return $cursor === 0 && empty($result) ? false : [$cursor, $result];\n    }\n\n    /**\n     * Scans the given set for all values based on options.\n     *\n     * @param  string  $key\n     * @param  mixed  $cursor\n     * @param  array  $options\n     * @return mixed\n     */\n    public function sscan($key, $cursor, $options = [])\n    {\n        $result = $this->client->sscan($key, $cursor,\n            $options['match'] ?? '*',\n            $options['count'] ?? 10\n        );\n\n        if ($result === false) {\n            $result = [];\n        }\n\n        return $cursor === 0 && empty($result) ? false : [$cursor, $result];\n    }\n\n    /**\n     * Execute commands in a pipeline.\n     *\n     * @param  callable|null  $callback\n     * @return \\Redis|array\n     */\n    public function pipeline(?callable $callback = null)\n    {\n        $pipeline = $this->client()->pipeline();\n\n        return is_null($callback)\n            ? $pipeline\n            : tap($pipeline, $callback)->exec();\n    }\n\n    /**\n     * Execute commands in a transaction.\n     *\n     * @param  callable|null  $callback\n     * @return \\Redis|array\n     */\n    public function transaction(?callable $callback = null)\n    {\n        $transaction = $this->client()->multi();\n\n        return is_null($callback)\n            ? $transaction\n            : tap($transaction, $callback)->exec();\n    }\n\n    /**\n     * Evaluate a LUA script serverside, from the SHA1 hash of the script instead of the script itself.\n     *\n     * @param  string  $script\n     * @param  int  $numkeys\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public function evalsha($script, $numkeys, ...$arguments)\n    {\n        return $this->command('evalsha', [\n            $this->script('load', $script), $arguments, $numkeys,\n        ]);\n    }\n\n    /**\n     * Evaluate a script and return its result.\n     *\n     * @param  string  $script\n     * @param  int  $numberOfKeys\n     * @param  mixed  ...$arguments\n     * @return mixed\n     */\n    public function eval($script, $numberOfKeys, ...$arguments)\n    {\n        return $this->command('eval', [$script, $arguments, $numberOfKeys]);\n    }\n\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function subscribe($channels, Closure $callback)\n    {\n        $this->client->subscribe((array) $channels, function ($redis, $channel, $message) use ($callback) {\n            $callback($message, $channel);\n        });\n    }\n\n    /**\n     * Subscribe to a set of given channels with wildcards.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function psubscribe($channels, Closure $callback)\n    {\n        $this->client->psubscribe((array) $channels, function ($redis, $pattern, $channel, $message) use ($callback) {\n            $callback($message, $channel);\n        });\n    }\n\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @param  string  $method\n     * @return void\n     */\n    public function createSubscription($channels, Closure $callback, $method = 'subscribe')\n    {\n        //\n    }\n\n    /**\n     * Flush the selected Redis database.\n     *\n     * @return mixed\n     */\n    public function flushdb()\n    {\n        $arguments = func_get_args();\n\n        if (strtoupper((string) ($arguments[0] ?? null)) === 'ASYNC') {\n            return $this->command('flushdb', [true]);\n        }\n\n        return $this->command('flushdb');\n    }\n\n    /**\n     * Execute a raw command.\n     *\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function executeRaw(array $parameters)\n    {\n        return $this->command('rawCommand', $parameters);\n    }\n\n    /**\n     * Run a command against the Redis database.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\RedisException\n     */\n    public function command($method, array $parameters = [])\n    {\n        try {\n            return parent::command($method, $parameters);\n        } catch (RedisException $e) {\n            if (Str::contains($e->getMessage(), ['went away', 'socket', 'Error while reading', 'read error on connection', 'READONLY', 'Connection lost'])) {\n                $this->client = $this->connector ? call_user_func($this->connector) : $this->client;\n            }\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Disconnects from the Redis instance.\n     *\n     * @return void\n     */\n    public function disconnect()\n    {\n        $this->client->close();\n    }\n\n    /**\n     * Pass other method calls down to the underlying client.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return parent::__call(strtolower($method), $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/PredisClusterConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse Predis\\Command\\Redis\\FLUSHDB;\nuse Predis\\Command\\ServerFlushDatabase;\n\nclass PredisClusterConnection extends PredisConnection\n{\n    /**\n     * Get the keys that match the given pattern.\n     *\n     * @param  string  $pattern\n     * @return array\n     */\n    public function keys(string $pattern)\n    {\n        $keys = [];\n\n        foreach ($this->client as $node) {\n            $keys[] = $node->keys($pattern);\n        }\n\n        return array_merge(...$keys);\n    }\n\n    /**\n     * Flush the selected Redis database on all cluster nodes.\n     *\n     * @return void\n     */\n    public function flushdb()\n    {\n        $command = class_exists(ServerFlushDatabase::class)\n            ? ServerFlushDatabase::class\n            : FLUSHDB::class;\n\n        foreach ($this->client as $node) {\n            $node->executeCommand(tap(new $command)->setArguments(func_get_args()));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connections/PredisConnection.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connections;\n\nuse Closure;\nuse Illuminate\\Contracts\\Redis\\Connection as ConnectionContract;\nuse Illuminate\\Support\\Collection;\nuse Predis\\Command\\Argument\\ArrayableArgument;\n\n/**\n * @mixin \\Predis\\Client\n */\nclass PredisConnection extends Connection implements ConnectionContract\n{\n    /**\n     * The Predis client.\n     *\n     * @var \\Predis\\Client\n     */\n    protected $client;\n\n    /**\n     * Create a new Predis connection.\n     *\n     * @param  \\Predis\\Client  $client\n     */\n    public function __construct($client)\n    {\n        $this->client = $client;\n    }\n\n    /**\n     * Subscribe to a set of given channels for messages.\n     *\n     * @param  array|string  $channels\n     * @param  \\Closure  $callback\n     * @param  string  $method\n     * @return void\n     */\n    public function createSubscription($channels, Closure $callback, $method = 'subscribe')\n    {\n        $loop = $this->pubSubLoop();\n\n        $loop->{$method}(...array_values((array) $channels));\n\n        foreach ($loop as $message) {\n            if ($message->kind === 'message' || $message->kind === 'pmessage') {\n                $callback($message->payload, $message->channel);\n            }\n        }\n\n        unset($loop);\n    }\n\n    /**\n     * Parse the command's parameters for event dispatching.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function parseParametersForEvent(array $parameters)\n    {\n        return (new Collection($parameters))\n            ->transform(function ($parameter) {\n                return $parameter instanceof ArrayableArgument\n                    ? $parameter->toArray()\n                    : $parameter;\n            })->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connectors;\n\nuse Illuminate\\Contracts\\Redis\\Connector;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Redis as RedisFacade;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\nuse LogicException;\nuse Redis;\nuse RedisCluster;\n\nclass PhpRedisConnector implements Connector\n{\n    /**\n     * Create a new connection.\n     *\n     * @param  array  $config\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\PhpRedisConnection\n     */\n    public function connect(array $config, array $options)\n    {\n        $formattedOptions = Arr::pull($config, 'options', []);\n\n        if (isset($config['prefix'])) {\n            $formattedOptions['prefix'] = $config['prefix'];\n        }\n\n        $connector = function () use ($config, $options, $formattedOptions) {\n            return $this->createClient(array_merge(\n                $config, $options, $formattedOptions\n            ));\n        };\n\n        return new PhpRedisConnection($connector(), $connector, $config);\n    }\n\n    /**\n     * Create a new clustered PhpRedis connection.\n     *\n     * @param  array  $config\n     * @param  array  $clusterOptions\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\PhpRedisClusterConnection\n     */\n    public function connectToCluster(array $config, array $clusterOptions, array $options)\n    {\n        $options = array_merge($options, $clusterOptions, Arr::pull($config, 'options', []));\n\n        return new PhpRedisClusterConnection($this->createRedisClusterInstance(\n            array_map($this->buildClusterConnectionString(...), $config), $options\n        ));\n    }\n\n    /**\n     * Build a single cluster seed string from an array.\n     *\n     * @param  array  $server\n     * @return string\n     */\n    protected function buildClusterConnectionString(array $server)\n    {\n        return $this->formatHost($server).':'.$server['port'];\n    }\n\n    /**\n     * Create the Redis client instance.\n     *\n     * @param  array  $config\n     * @return \\Redis\n     *\n     * @throws \\LogicException\n     */\n    protected function createClient(array $config)\n    {\n        return tap(new Redis, function ($client) use ($config) {\n            if ($client instanceof RedisFacade) {\n                throw new LogicException(\n                    extension_loaded('redis')\n                        ? 'Please remove or rename the Redis facade alias in your \"app\" configuration file in order to avoid collision with the PHP Redis extension.'\n                        : 'Please make sure the PHP Redis extension is installed and enabled.'\n                );\n            }\n\n            $this->establishConnection($client, $config);\n\n            if (array_key_exists('max_retries', $config)) {\n                $client->setOption(Redis::OPT_MAX_RETRIES, $config['max_retries']);\n            }\n\n            if (array_key_exists('backoff_algorithm', $config)) {\n                $client->setOption(Redis::OPT_BACKOFF_ALGORITHM, $this->parseBackoffAlgorithm($config['backoff_algorithm']));\n            }\n\n            if (array_key_exists('backoff_base', $config)) {\n                $client->setOption(Redis::OPT_BACKOFF_BASE, $config['backoff_base']);\n            }\n\n            if (array_key_exists('backoff_cap', $config)) {\n                $client->setOption(Redis::OPT_BACKOFF_CAP, $config['backoff_cap']);\n            }\n\n            if (! empty($config['password'])) {\n                if (isset($config['username']) && $config['username'] !== '' && is_string($config['password'])) {\n                    $client->auth([$config['username'], $config['password']]);\n                } else {\n                    $client->auth($config['password']);\n                }\n            }\n\n            if (isset($config['database'])) {\n                $client->select((int) $config['database']);\n            }\n\n            if (! empty($config['prefix'])) {\n                $client->setOption(Redis::OPT_PREFIX, $config['prefix']);\n            }\n\n            if (! empty($config['read_timeout'])) {\n                $client->setOption(Redis::OPT_READ_TIMEOUT, $config['read_timeout']);\n            }\n\n            if (! empty($config['scan'])) {\n                $client->setOption(Redis::OPT_SCAN, $config['scan']);\n            }\n\n            if (! empty($config['name'])) {\n                $client->client('SETNAME', $config['name']);\n            }\n\n            if (array_key_exists('serializer', $config)) {\n                $client->setOption(Redis::OPT_SERIALIZER, $config['serializer']);\n            }\n\n            if (array_key_exists('compression', $config)) {\n                $client->setOption(Redis::OPT_COMPRESSION, $config['compression']);\n            }\n\n            if (array_key_exists('compression_level', $config)) {\n                $client->setOption(Redis::OPT_COMPRESSION_LEVEL, $config['compression_level']);\n            }\n\n            if (! empty($config['tcp_keepalive'])) {\n                $client->setOption(Redis::OPT_TCP_KEEPALIVE, $config['tcp_keepalive']);\n            }\n\n            if (defined('Redis::OPT_PACK_IGNORE_NUMBERS') &&\n                array_key_exists('pack_ignore_numbers', $config)) {\n                $client->setOption(Redis::OPT_PACK_IGNORE_NUMBERS, $config['pack_ignore_numbers']);\n            }\n        });\n    }\n\n    /**\n     * Establish a connection with the Redis host.\n     *\n     * @param  \\Redis  $client\n     * @param  array  $config\n     * @return void\n     */\n    protected function establishConnection($client, array $config)\n    {\n        $persistent = $config['persistent'] ?? false;\n\n        $parameters = [\n            $this->formatHost($config),\n            $config['port'],\n            Arr::get($config, 'timeout', 0.0),\n            $persistent ? Arr::get($config, 'persistent_id', null) : null,\n            Arr::get($config, 'retry_interval', 0),\n        ];\n\n        if (version_compare(phpversion('redis'), '3.1.3', '>=')) {\n            $parameters[] = Arr::get($config, 'read_timeout', 0.0);\n        }\n\n        if (version_compare(phpversion('redis'), '5.3.0', '>=') && ! is_null($context = Arr::get($config, 'context'))) {\n            $parameters[] = $context;\n        }\n\n        $client->{$persistent ? 'pconnect' : 'connect'}(...$parameters);\n    }\n\n    /**\n     * Create a new redis cluster instance.\n     *\n     * @param  array  $servers\n     * @param  array  $options\n     * @return \\RedisCluster\n     */\n    protected function createRedisClusterInstance(array $servers, array $options)\n    {\n        $parameters = [\n            null,\n            array_values($servers),\n            $options['timeout'] ?? 0,\n            $options['read_timeout'] ?? 0,\n            isset($options['persistent']) && $options['persistent'],\n        ];\n\n        if (version_compare(phpversion('redis'), '4.3.0', '>=')) {\n            $parameters[] = $options['password'] ?? null;\n        }\n\n        if (version_compare(phpversion('redis'), '5.3.2', '>=') && ! is_null($context = Arr::get($options, 'context'))) {\n            $parameters[] = $context;\n        }\n\n        return tap(new RedisCluster(...$parameters), function ($client) use ($options) {\n            if (! empty($options['prefix'])) {\n                $client->setOption(Redis::OPT_PREFIX, $options['prefix']);\n            }\n\n            if (! empty($options['scan'])) {\n                $client->setOption(Redis::OPT_SCAN, $options['scan']);\n            }\n\n            if (! empty($options['failover'])) {\n                $client->setOption(RedisCluster::OPT_SLAVE_FAILOVER, $options['failover']);\n            }\n\n            if (array_key_exists('serializer', $options)) {\n                $client->setOption(Redis::OPT_SERIALIZER, $options['serializer']);\n            }\n\n            if (array_key_exists('compression', $options)) {\n                $client->setOption(Redis::OPT_COMPRESSION, $options['compression']);\n            }\n\n            if (array_key_exists('compression_level', $options)) {\n                $client->setOption(Redis::OPT_COMPRESSION_LEVEL, $options['compression_level']);\n            }\n\n            if (! empty($options['tcp_keepalive'])) {\n                $client->setOption(Redis::OPT_TCP_KEEPALIVE, $options['tcp_keepalive']);\n            }\n        });\n    }\n\n    /**\n     * Format the host using the scheme if available.\n     *\n     * @param  array  $options\n     * @return string\n     */\n    protected function formatHost(array $options)\n    {\n        if (isset($options['scheme'])) {\n            return Str::start($options['host'], \"{$options['scheme']}://\");\n        }\n\n        return $options['host'];\n    }\n\n    /**\n     * Parse a \"friendly\" backoff algorithm name into an integer.\n     *\n     * @param  mixed  $algorithm\n     * @return int\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseBackoffAlgorithm(mixed $algorithm)\n    {\n        if (is_int($algorithm)) {\n            return $algorithm;\n        }\n\n        return match ($algorithm) {\n            'default' => Redis::BACKOFF_ALGORITHM_DEFAULT,\n            'decorrelated_jitter' => Redis::BACKOFF_ALGORITHM_DECORRELATED_JITTER,\n            'equal_jitter' => Redis::BACKOFF_ALGORITHM_EQUAL_JITTER,\n            'exponential' => Redis::BACKOFF_ALGORITHM_EXPONENTIAL,\n            'uniform' => Redis::BACKOFF_ALGORITHM_UNIFORM,\n            'constant' => Redis::BACKOFF_ALGORITHM_CONSTANT,\n            default => throw new InvalidArgumentException(\"Algorithm [{$algorithm}] is not a valid PhpRedis backoff algorithm.\")\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Connectors/PredisConnector.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Connectors;\n\nuse Illuminate\\Contracts\\Redis\\Connector;\nuse Illuminate\\Redis\\Connections\\PredisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PredisConnection;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\nuse Predis\\Client;\n\nclass PredisConnector implements Connector\n{\n    /**\n     * Create a new connection.\n     *\n     * @param  array  $config\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\PredisConnection\n     */\n    public function connect(array $config, array $options)\n    {\n        $formattedOptions = array_merge(\n            ['timeout' => 10.0], $options, Arr::pull($config, 'options', [])\n        );\n\n        if (isset($config['prefix'])) {\n            $formattedOptions['prefix'] = $config['prefix'];\n        }\n\n        if (isset($config['host']) && str_starts_with($config['host'], 'tls://')) {\n            $config['scheme'] = 'tls';\n            $config['host'] = Str::after($config['host'], 'tls://');\n        }\n\n        return new PredisConnection(new Client($config, $formattedOptions));\n    }\n\n    /**\n     * Create a new clustered Predis connection.\n     *\n     * @param  array  $config\n     * @param  array  $clusterOptions\n     * @param  array  $options\n     * @return \\Illuminate\\Redis\\Connections\\PredisClusterConnection\n     */\n    public function connectToCluster(array $config, array $clusterOptions, array $options)\n    {\n        $clusterSpecificOptions = Arr::pull($config, 'options', []);\n\n        if (isset($config['prefix'])) {\n            $clusterSpecificOptions['prefix'] = $config['prefix'];\n        }\n\n        return new PredisClusterConnection(new Client(array_values($config), array_merge(\n            $options, $clusterOptions, $clusterSpecificOptions\n        )));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Events/CommandExecuted.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Events;\n\nclass CommandExecuted\n{\n    /**\n     * The Redis command that was executed.\n     *\n     * @var string\n     */\n    public $command;\n\n    /**\n     * The array of command parameters.\n     *\n     * @var array\n     */\n    public $parameters;\n\n    /**\n     * The number of milliseconds it took to execute the command.\n     *\n     * @var float\n     */\n    public $time;\n\n    /**\n     * The Redis connection instance.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public $connection;\n\n    /**\n     * The Redis connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @param  float|null  $time\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     */\n    public function __construct($command, $parameters, $time, $connection)\n    {\n        $this->time = $time;\n        $this->command = $command;\n        $this->parameters = $parameters;\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Events/CommandFailed.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Events;\n\nuse Throwable;\n\nclass CommandFailed\n{\n    /**\n     * The Redis command that failed.\n     *\n     * @var string\n     */\n    public $command;\n\n    /**\n     * The array of command parameters.\n     *\n     * @var array\n     */\n    public $parameters;\n\n    /**\n     * The exception that was thrown.\n     *\n     * @var \\Throwable\n     */\n    public $exception;\n\n    /**\n     * The Redis connection instance.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public $connection;\n\n    /**\n     * The Redis connection name.\n     *\n     * @var string\n     */\n    public $connectionName;\n\n    /**\n     * Create a new event instance.\n     *\n     * @param  string  $command\n     * @param  array  $parameters\n     * @param  \\Throwable  $exception\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     */\n    public function __construct($command, $parameters, Throwable $exception, $connection)\n    {\n        $this->command = $command;\n        $this->parameters = $parameters;\n        $this->exception = $exception;\n        $this->connection = $connection;\n        $this->connectionName = $connection->getName();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Redis/Limiters/ConcurrencyLimiter.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Limiters;\n\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\nuse Throwable;\n\nclass ConcurrencyLimiter\n{\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    protected $redis;\n\n    /**\n     * The name of the limiter.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The allowed number of concurrent tasks.\n     *\n     * @var int\n     */\n    protected $maxLocks;\n\n    /**\n     * The number of seconds a slot should be maintained.\n     *\n     * @var int\n     */\n    protected $releaseAfter;\n\n    /**\n     * Create a new concurrency limiter instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $redis\n     * @param  string  $name\n     * @param  int  $maxLocks\n     * @param  int  $releaseAfter\n     */\n    public function __construct($redis, $name, $maxLocks, $releaseAfter)\n    {\n        $this->name = $name;\n        $this->redis = $redis;\n        $this->maxLocks = $maxLocks;\n        $this->releaseAfter = $releaseAfter;\n    }\n\n    /**\n     * Attempt to acquire the lock for the given number of seconds.\n     *\n     * @param  int  $timeout\n     * @param  callable|null  $callback\n     * @param  int  $sleep\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Redis\\LimiterTimeoutException\n     * @throws \\Throwable\n     */\n    public function block($timeout, $callback = null, $sleep = 250)\n    {\n        $starting = time();\n\n        $id = Str::random(20);\n\n        while (! $slot = $this->acquire($id)) {\n            if (time() - $timeout >= $starting) {\n                throw new LimiterTimeoutException;\n            }\n\n            Sleep::usleep($sleep * 1000);\n        }\n\n        if (is_callable($callback)) {\n            try {\n                return tap($callback(), function () use ($slot, $id) {\n                    $this->release($slot, $id);\n                });\n            } catch (Throwable $exception) {\n                $this->release($slot, $id);\n\n                throw $exception;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @param  string  $id  A unique identifier for this lock\n     * @return mixed\n     */\n    protected function acquire($id)\n    {\n        $slots = array_map(function ($i) {\n            return $this->name.$i;\n        }, range(1, $this->maxLocks));\n\n        return $this->redis->eval(...array_merge(\n            [$this->lockScript(), count($slots)],\n            array_merge($slots, [$this->name, $this->releaseAfter, $id])\n        ));\n    }\n\n    /**\n     * Get the Lua script for acquiring a lock.\n     *\n     * KEYS    - The keys that represent available slots\n     * ARGV[1] - The limiter name\n     * ARGV[2] - The number of seconds the slot should be reserved\n     * ARGV[3] - The unique identifier for this lock\n     *\n     * @return string\n     */\n    protected function lockScript()\n    {\n        return <<<'LUA'\nfor index, value in pairs(redis.call('mget', unpack(KEYS))) do\n    if not value then\n        redis.call('set', KEYS[index], ARGV[3], \"EX\", ARGV[2])\n        return ARGV[1]..index\n    end\nend\nLUA;\n    }\n\n    /**\n     * Release the lock.\n     *\n     * @param  string  $key\n     * @param  string  $id\n     * @return void\n     */\n    protected function release($key, $id)\n    {\n        $this->redis->eval($this->releaseScript(), 1, $key, $id);\n    }\n\n    /**\n     * Get the Lua script to atomically release a lock.\n     *\n     * KEYS[1] - The name of the lock\n     * ARGV[1] - The unique identifier for this lock\n     *\n     * @return string\n     */\n    protected function releaseScript()\n    {\n        return <<<'LUA'\nif redis.call('get', KEYS[1]) == ARGV[1]\nthen\n    return redis.call('del', KEYS[1])\nelse\n    return 0\nend\nLUA;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Limiters/ConcurrencyLimiterBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Limiters;\n\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass ConcurrencyLimiterBuilder\n{\n    use InteractsWithTime;\n\n    /**\n     * The Redis connection.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public $connection;\n\n    /**\n     * The name of the lock.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The maximum number of entities that can hold the lock at the same time.\n     *\n     * @var int\n     */\n    public $maxLocks;\n\n    /**\n     * The number of seconds to maintain the lock until it is automatically released.\n     *\n     * @var int\n     */\n    public $releaseAfter = 60;\n\n    /**\n     * The amount of time to block until a lock is available.\n     *\n     * @var int\n     */\n    public $timeout = 3;\n\n    /**\n     * The number of milliseconds to wait between attempts to acquire the lock.\n     *\n     * @var int\n     */\n    public $sleep = 250;\n\n    /**\n     * Create a new builder instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @param  string  $name\n     */\n    public function __construct($connection, $name)\n    {\n        $this->name = $name;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Set the maximum number of locks that can be obtained per time window.\n     *\n     * @param  int  $maxLocks\n     * @return $this\n     */\n    public function limit($maxLocks)\n    {\n        $this->maxLocks = $maxLocks;\n\n        return $this;\n    }\n\n    /**\n     * Set the number of seconds until the lock will be released.\n     *\n     * @param  int  $releaseAfter\n     * @return $this\n     */\n    public function releaseAfter($releaseAfter)\n    {\n        $this->releaseAfter = $this->secondsUntil($releaseAfter);\n\n        return $this;\n    }\n\n    /**\n     * Set the amount of time to block until a lock is available.\n     *\n     * @param  int  $timeout\n     * @return $this\n     */\n    public function block($timeout)\n    {\n        $this->timeout = $timeout;\n\n        return $this;\n    }\n\n    /**\n     * The number of milliseconds to wait between lock acquisition attempts.\n     *\n     * @param  int  $sleep\n     * @return $this\n     */\n    public function sleep($sleep)\n    {\n        $this->sleep = $sleep;\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback if a lock is obtained, otherwise call the failure callback.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $failure\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Redis\\LimiterTimeoutException\n     */\n    public function then(callable $callback, ?callable $failure = null)\n    {\n        try {\n            return (new ConcurrencyLimiter(\n                $this->connection, $this->name, $this->maxLocks, $this->releaseAfter\n            ))->block($this->timeout, $callback, $this->sleep);\n        } catch (LimiterTimeoutException $e) {\n            if ($failure) {\n                return $failure($e);\n            }\n\n            throw $e;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Limiters/DurationLimiter.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Limiters;\n\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Support\\Sleep;\n\nclass DurationLimiter\n{\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    private $redis;\n\n    /**\n     * The unique name of the lock.\n     *\n     * @var string\n     */\n    private $name;\n\n    /**\n     * The allowed number of concurrent tasks.\n     *\n     * @var int\n     */\n    private $maxLocks;\n\n    /**\n     * The number of seconds a slot should be maintained.\n     *\n     * @var int\n     */\n    private $decay;\n\n    /**\n     * The timestamp of the end of the current duration.\n     *\n     * @var int\n     */\n    public $decaysAt;\n\n    /**\n     * The number of remaining slots.\n     *\n     * @var int\n     */\n    public $remaining;\n\n    /**\n     * Create a new duration limiter instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $redis\n     * @param  string  $name\n     * @param  int  $maxLocks\n     * @param  int  $decay\n     */\n    public function __construct($redis, $name, $maxLocks, $decay)\n    {\n        $this->name = $name;\n        $this->decay = $decay;\n        $this->redis = $redis;\n        $this->maxLocks = $maxLocks;\n    }\n\n    /**\n     * Attempt to acquire the lock for the given number of seconds.\n     *\n     * @param  int  $timeout\n     * @param  callable|null  $callback\n     * @param  int  $sleep\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Redis\\LimiterTimeoutException\n     */\n    public function block($timeout, $callback = null, $sleep = 750)\n    {\n        $starting = time();\n\n        while (! $this->acquire()) {\n            if (time() - $timeout >= $starting) {\n                throw new LimiterTimeoutException;\n            }\n\n            Sleep::usleep($sleep * 1000);\n        }\n\n        if (is_callable($callback)) {\n            return $callback();\n        }\n\n        return true;\n    }\n\n    /**\n     * Attempt to acquire the lock.\n     *\n     * @return bool\n     */\n    public function acquire()\n    {\n        $results = $this->redis->eval(\n            $this->luaScript(), 1, $this->name, microtime(true), time(), $this->decay, $this->maxLocks\n        );\n\n        $this->decaysAt = $results[1];\n\n        $this->remaining = max(0, $results[2]);\n\n        return (bool) $results[0];\n    }\n\n    /**\n     * Determine if the key has been \"accessed\" too many times.\n     *\n     * @return bool\n     */\n    public function tooManyAttempts()\n    {\n        [$this->decaysAt, $this->remaining] = $this->redis->eval(\n            $this->tooManyAttemptsLuaScript(), 1, $this->name, microtime(true), time(), $this->decay, $this->maxLocks\n        );\n\n        return $this->remaining <= 0;\n    }\n\n    /**\n     * Clear the limiter.\n     *\n     * @return void\n     */\n    public function clear()\n    {\n        $this->redis->del($this->name);\n    }\n\n    /**\n     * Get the Lua script for acquiring a lock.\n     *\n     * KEYS[1] - The limiter name\n     * ARGV[1] - Current time in microseconds\n     * ARGV[2] - Current time in seconds\n     * ARGV[3] - Duration of the bucket\n     * ARGV[4] - Allowed number of tasks\n     *\n     * @return string\n     */\n    protected function luaScript()\n    {\n        return <<<'LUA'\nlocal function reset()\n    redis.call('HMSET', KEYS[1], 'start', ARGV[2], 'end', ARGV[2] + ARGV[3], 'count', 1)\n    return redis.call('EXPIRE', KEYS[1], ARGV[3] * 2)\nend\n\nif redis.call('EXISTS', KEYS[1]) == 0 then\n    return {reset(), ARGV[2] + ARGV[3], ARGV[4] - 1}\nend\n\nif ARGV[1] >= redis.call('HGET', KEYS[1], 'start') and ARGV[1] <= redis.call('HGET', KEYS[1], 'end') then\n    return {\n        tonumber(redis.call('HINCRBY', KEYS[1], 'count', 1)) <= tonumber(ARGV[4]),\n        redis.call('HGET', KEYS[1], 'end'),\n        ARGV[4] - redis.call('HGET', KEYS[1], 'count')\n    }\nend\n\nreturn {reset(), ARGV[2] + ARGV[3], ARGV[4] - 1}\nLUA;\n    }\n\n    /**\n     * Get the Lua script to determine if the key has been \"accessed\" too many times.\n     *\n     * KEYS[1] - The limiter name\n     * ARGV[1] - Current time in microseconds\n     * ARGV[2] - Current time in seconds\n     * ARGV[3] - Duration of the bucket\n     * ARGV[4] - Allowed number of tasks\n     *\n     * @return string\n     */\n    protected function tooManyAttemptsLuaScript()\n    {\n        return <<<'LUA'\n\nif redis.call('EXISTS', KEYS[1]) == 0 then\n    return {0, ARGV[2] + ARGV[3]}\nend\n\nif ARGV[1] >= redis.call('HGET', KEYS[1], 'start') and ARGV[1] <= redis.call('HGET', KEYS[1], 'end') then\n    return {\n        redis.call('HGET', KEYS[1], 'end'),\n        ARGV[4] - redis.call('HGET', KEYS[1], 'count')\n    }\nend\n\nreturn {0, ARGV[2] + ARGV[3]}\nLUA;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/Limiters/DurationLimiterBuilder.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis\\Limiters;\n\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Support\\InteractsWithTime;\n\nclass DurationLimiterBuilder\n{\n    use InteractsWithTime;\n\n    /**\n     * The Redis connection.\n     *\n     * @var \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public $connection;\n\n    /**\n     * The name of the lock.\n     *\n     * @var string\n     */\n    public $name;\n\n    /**\n     * The maximum number of locks that can be obtained per time window.\n     *\n     * @var int\n     */\n    public $maxLocks;\n\n    /**\n     * The amount of time the lock window is maintained.\n     *\n     * @var int\n     */\n    public $decay;\n\n    /**\n     * The amount of time to block until a lock is available.\n     *\n     * @var int\n     */\n    public $timeout = 3;\n\n    /**\n     * The number of milliseconds to wait between attempts to acquire the lock.\n     *\n     * @var int\n     */\n    public $sleep = 750;\n\n    /**\n     * Create a new builder instance.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @param  string  $name\n     */\n    public function __construct($connection, $name)\n    {\n        $this->name = $name;\n        $this->connection = $connection;\n    }\n\n    /**\n     * Set the maximum number of locks that can be obtained per time window.\n     *\n     * @param  int  $maxLocks\n     * @return $this\n     */\n    public function allow($maxLocks)\n    {\n        $this->maxLocks = $maxLocks;\n\n        return $this;\n    }\n\n    /**\n     * Set the amount of time the lock window is maintained.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $decay\n     * @return $this\n     */\n    public function every($decay)\n    {\n        $this->decay = $this->secondsUntil($decay);\n\n        return $this;\n    }\n\n    /**\n     * Set the amount of time to block until a lock is available.\n     *\n     * @param  int  $timeout\n     * @return $this\n     */\n    public function block($timeout)\n    {\n        $this->timeout = $timeout;\n\n        return $this;\n    }\n\n    /**\n     * The number of milliseconds to wait between lock acquisition attempts.\n     *\n     * @param  int  $sleep\n     * @return $this\n     */\n    public function sleep($sleep)\n    {\n        $this->sleep = $sleep;\n\n        return $this;\n    }\n\n    /**\n     * Execute the given callback if a lock is obtained, otherwise call the failure callback.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $failure\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Redis\\LimiterTimeoutException\n     */\n    public function then(callable $callback, ?callable $failure = null)\n    {\n        try {\n            return (new DurationLimiter(\n                $this->connection, $this->name, $this->maxLocks, $this->decay\n            ))->block($this->timeout, $callback, $this->sleep);\n        } catch (LimiterTimeoutException $e) {\n            if ($failure) {\n                return $failure($e);\n            }\n\n            throw $e;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/RedisManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis;\n\nuse Closure;\nuse Illuminate\\Contracts\\Redis\\Factory;\nuse Illuminate\\Redis\\Connections\\Connection;\nuse Illuminate\\Redis\\Connectors\\PhpRedisConnector;\nuse Illuminate\\Redis\\Connectors\\PredisConnector;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\ConfigurationUrlParser;\nuse InvalidArgumentException;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @mixin \\Illuminate\\Redis\\Connections\\Connection\n */\nclass RedisManager implements Factory\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The name of the default driver.\n     *\n     * @var string\n     */\n    protected $driver;\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * The Redis server configurations.\n     *\n     * @var array\n     */\n    protected $config;\n\n    /**\n     * The Redis connections.\n     *\n     * @var mixed\n     */\n    protected $connections;\n\n    /**\n     * Indicates whether event dispatcher is set on connections.\n     *\n     * @var bool\n     */\n    protected $events = false;\n\n    /**\n     * Create a new Redis manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  string  $driver\n     * @param  array  $config\n     */\n    public function __construct($app, $driver, array $config)\n    {\n        $this->app = $app;\n        $this->driver = $driver;\n        $this->config = $config;\n    }\n\n    /**\n     * Get a Redis connection by name.\n     *\n     * @param  \\UnitEnum|string|null  $name\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    public function connection($name = null)\n    {\n        $name = enum_value($name) ?: 'default';\n\n        if (isset($this->connections[$name])) {\n            return $this->connections[$name];\n        }\n\n        return $this->connections[$name] = $this->configure(\n            $this->resolve($name), $name\n        );\n    }\n\n    /**\n     * Resolve the given connection by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function resolve($name = null)\n    {\n        $name = $name ?: 'default';\n\n        $options = $this->config['options'] ?? [];\n\n        if (isset($this->config[$name])) {\n            return $this->connector()->connect(\n                $this->parseConnectionConfiguration($this->config[$name]),\n                array_merge(Arr::except($options, 'parameters'), ['parameters' => Arr::get($options, 'parameters.'.$name, Arr::get($options, 'parameters', []))])\n            );\n        }\n\n        if (isset($this->config['clusters'][$name])) {\n            return $this->resolveCluster($name);\n        }\n\n        throw new InvalidArgumentException(\"Redis connection [{$name}] not configured.\");\n    }\n\n    /**\n     * Resolve the given cluster connection by name.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    protected function resolveCluster($name)\n    {\n        return $this->connector()->connectToCluster(\n            array_map(function ($config) {\n                return $this->parseConnectionConfiguration($config);\n            }, $this->config['clusters'][$name]),\n            $this->config['clusters']['options'] ?? [],\n            $this->config['options'] ?? []\n        );\n    }\n\n    /**\n     * Configure the given connection to prepare it for commands.\n     *\n     * @param  \\Illuminate\\Redis\\Connections\\Connection  $connection\n     * @param  string  $name\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    protected function configure(Connection $connection, $name)\n    {\n        $connection->setName($name);\n\n        if ($this->events && $this->app->bound('events')) {\n            $connection->setEventDispatcher($this->app->make('events'));\n        }\n\n        return $connection;\n    }\n\n    /**\n     * Get the connector instance for the current driver.\n     *\n     * @return \\Illuminate\\Contracts\\Redis\\Connector|null\n     */\n    protected function connector()\n    {\n        $customCreator = $this->customCreators[$this->driver] ?? null;\n\n        if ($customCreator) {\n            return $customCreator();\n        }\n\n        return match ($this->driver) {\n            'predis' => new PredisConnector,\n            'phpredis' => new PhpRedisConnector,\n            default => null,\n        };\n    }\n\n    /**\n     * Parse the Redis connection configuration.\n     *\n     * @param  mixed  $config\n     * @return array\n     */\n    protected function parseConnectionConfiguration($config)\n    {\n        $parsed = (new ConfigurationUrlParser)->parseConfiguration($config);\n\n        $driver = strtolower($parsed['driver'] ?? '');\n\n        if (in_array($driver, ['tcp', 'tls'])) {\n            $parsed['scheme'] = $driver;\n        }\n\n        return array_filter($parsed, function ($key) {\n            return $key !== 'driver';\n        }, ARRAY_FILTER_USE_KEY);\n    }\n\n    /**\n     * Return all of the created connections.\n     *\n     * @return array\n     */\n    public function connections()\n    {\n        return $this->connections;\n    }\n\n    /**\n     * Enable the firing of Redis command events.\n     *\n     * @return void\n     */\n    public function enableEvents()\n    {\n        $this->events = true;\n    }\n\n    /**\n     * Disable the firing of Redis command events.\n     *\n     * @return void\n     */\n    public function disableEvents()\n    {\n        $this->events = false;\n    }\n\n    /**\n     * Set the default driver.\n     *\n     * @param  string  $driver\n     * @return void\n     */\n    public function setDriver($driver)\n    {\n        $this->driver = $driver;\n    }\n\n    /**\n     * Disconnect the given connection and remove from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name = $name ?: 'default';\n\n        unset($this->connections[$name]);\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Pass methods onto the default Redis connection.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->connection()->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/RedisServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Redis;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass RedisServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->app->singleton('redis', function ($app) {\n            $config = $app->make('config')->get('database.redis', []);\n\n            return new RedisManager($app, Arr::pull($config, 'client', 'phpredis'), $config);\n        });\n\n        $this->app->bind('redis.connection', function ($app) {\n            return $app['redis']->connection();\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['redis', 'redis.connection'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Redis/composer.json",
    "content": "{\n    \"name\": \"illuminate/redis\",\n    \"description\": \"The Illuminate Redis package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"ext-redis\": \"Required to use the phpredis connector (^4.0 || ^5.0 || ^6.0).\",\n        \"predis/predis\": \"Required to use the predis connector (^2.3 || ^3.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Redis\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Reflection/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Reflection/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Reflection/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Reflection/Reflector.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ReflectionAttribute;\nuse ReflectionClass;\nuse ReflectionEnum;\nuse ReflectionMethod;\nuse ReflectionNamedType;\nuse ReflectionUnionType;\n\nclass Reflector\n{\n    /**\n     * This is a PHP 7.4 compatible implementation of is_callable.\n     *\n     * @param  mixed  $var\n     * @param  bool  $syntaxOnly\n     * @return bool\n     */\n    public static function isCallable($var, $syntaxOnly = false)\n    {\n        if (! is_array($var)) {\n            return is_callable($var, $syntaxOnly);\n        }\n\n        if (! isset($var[0], $var[1]) || ! is_string($var[1] ?? null)) {\n            return false;\n        }\n\n        if ($syntaxOnly &&\n            (is_string($var[0]) || is_object($var[0])) &&\n            is_string($var[1])) {\n            return true;\n        }\n\n        $class = is_object($var[0]) ? get_class($var[0]) : $var[0];\n\n        $method = $var[1];\n\n        if (! class_exists($class)) {\n            return false;\n        }\n\n        if (method_exists($class, $method)) {\n            return (new ReflectionMethod($class, $method))->isPublic();\n        }\n\n        if (is_object($var[0]) && method_exists($class, '__call')) {\n            return (new ReflectionMethod($class, '__call'))->isPublic();\n        }\n\n        if (! is_object($var[0]) && method_exists($class, '__callStatic')) {\n            return (new ReflectionMethod($class, '__callStatic'))->isPublic();\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the specified class attribute, optionally following an inheritance chain.\n     *\n     * @template TAttribute of object\n     *\n     * @param  object|class-string  $objectOrClass\n     * @param  class-string<TAttribute>  $attribute\n     * @param  bool  $ascend\n     * @return TAttribute|null\n     */\n    public static function getClassAttribute($objectOrClass, $attribute, $ascend = false)\n    {\n        return static::getClassAttributes($objectOrClass, $attribute, $ascend)->flatten()->first();\n    }\n\n    /**\n     * Get the specified class attribute(s), optionally following an inheritance chain.\n     *\n     * @template TTarget of object\n     * @template TAttribute of object\n     *\n     * @param  TTarget|class-string<TTarget>  $objectOrClass\n     * @param  class-string<TAttribute>  $attribute\n     * @param  bool  $includeParents\n     * @return ($includeParents is true ? Collection<class-string<contravariant TTarget>, Collection<int, TAttribute>> : Collection<int, TAttribute>)\n     */\n    public static function getClassAttributes($objectOrClass, $attribute, $includeParents = false)\n    {\n        $reflectionClass = new ReflectionClass($objectOrClass);\n\n        $attributes = [];\n\n        do {\n            $attributes[$reflectionClass->name] = new Collection(array_map(\n                fn (ReflectionAttribute $reflectionAttribute) => $reflectionAttribute->newInstance(),\n                $reflectionClass->getAttributes($attribute)\n            ));\n        } while ($includeParents && false !== $reflectionClass = $reflectionClass->getParentClass());\n\n        return $includeParents ? new Collection($attributes) : array_first($attributes);\n    }\n\n    /**\n     * Get the class name of the given parameter's type, if possible.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @return string|null\n     */\n    public static function getParameterClassName($parameter)\n    {\n        $type = $parameter->getType();\n\n        if (! $type instanceof ReflectionNamedType || $type->isBuiltin()) {\n            return;\n        }\n\n        return static::getTypeName($parameter, $type);\n    }\n\n    /**\n     * Get the class names of the given parameter's type, including union types.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @return array\n     */\n    public static function getParameterClassNames($parameter)\n    {\n        $type = $parameter->getType();\n\n        if (! $type instanceof ReflectionUnionType) {\n            return array_filter([static::getParameterClassName($parameter)]);\n        }\n\n        $unionTypes = [];\n\n        foreach ($type->getTypes() as $listedType) {\n            if (! $listedType instanceof ReflectionNamedType || $listedType->isBuiltin()) {\n                continue;\n            }\n\n            $unionTypes[] = static::getTypeName($parameter, $listedType);\n        }\n\n        return array_filter($unionTypes);\n    }\n\n    /**\n     * Get the given type's class name.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @param  \\ReflectionNamedType  $type\n     * @return string\n     */\n    protected static function getTypeName($parameter, $type)\n    {\n        $name = $type->getName();\n\n        if (! is_null($class = $parameter->getDeclaringClass())) {\n            if ($name === 'self') {\n                return $class->getName();\n            }\n\n            if ($name === 'parent' && $parent = $class->getParentClass()) {\n                return $parent->getName();\n            }\n        }\n\n        return $name;\n    }\n\n    /**\n     * Determine if the parameter's type is a subclass of the given type.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @param  string  $className\n     * @return bool\n     */\n    public static function isParameterSubclassOf($parameter, $className)\n    {\n        $paramClassName = static::getParameterClassName($parameter);\n\n        return $paramClassName\n            && (class_exists($paramClassName) || interface_exists($paramClassName))\n            && (new ReflectionClass($paramClassName))->isSubclassOf($className);\n    }\n\n    /**\n     * Determine if the parameter's type is a Backed Enum with a string backing type.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @return bool\n     */\n    public static function isParameterBackedEnumWithStringBackingType($parameter)\n    {\n        if (! $parameter->getType() instanceof ReflectionNamedType) {\n            return false;\n        }\n\n        $backedEnumClass = $parameter->getType()?->getName();\n\n        if (is_null($backedEnumClass)) {\n            return false;\n        }\n\n        if (enum_exists($backedEnumClass)) {\n            $reflectionBackedEnum = new ReflectionEnum($backedEnumClass);\n\n            return $reflectionBackedEnum->isBacked()\n                && $reflectionBackedEnum->getBackingType()->getName() == 'string';\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Reflection/Traits/ReflectsClosures.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Closure;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Reflector;\nuse ReflectionFunction;\nuse ReflectionIntersectionType;\nuse ReflectionUnionType;\nuse RuntimeException;\n\ntrait ReflectsClosures\n{\n    /**\n     * Get the class name of the first parameter of the given Closure.\n     *\n     * @param  \\Closure  $closure\n     * @return string\n     *\n     * @throws \\ReflectionException\n     * @throws \\RuntimeException\n     */\n    protected function firstClosureParameterType(Closure $closure)\n    {\n        $types = array_values($this->closureParameterTypes($closure));\n\n        if (! $types) {\n            throw new RuntimeException('The given Closure has no parameters.');\n        }\n\n        if ($types[0] === null) {\n            throw new RuntimeException('The first parameter of the given Closure is missing a type hint.');\n        }\n\n        return $types[0];\n    }\n\n    /**\n     * Get the class names of the first parameter of the given Closure, including union types.\n     *\n     * @param  \\Closure  $closure\n     * @return array\n     *\n     * @throws \\ReflectionException\n     * @throws \\RuntimeException\n     */\n    protected function firstClosureParameterTypes(Closure $closure)\n    {\n        $reflection = new ReflectionFunction($closure);\n\n        $types = (new Collection($reflection->getParameters()))\n            ->mapWithKeys(function ($parameter) {\n                if ($parameter->isVariadic()) {\n                    return [$parameter->getName() => null];\n                }\n\n                return [$parameter->getName() => Reflector::getParameterClassNames($parameter)];\n            })\n            ->filter()\n            ->values()\n            ->all();\n\n        if (empty($types)) {\n            throw new RuntimeException('The given Closure has no parameters.');\n        }\n\n        if (isset($types[0]) && empty($types[0])) {\n            throw new RuntimeException('The first parameter of the given Closure is missing a type hint.');\n        }\n\n        return $types[0];\n    }\n\n    /**\n     * Get the class names / types of the parameters of the given Closure.\n     *\n     * @param  \\Closure  $closure\n     * @return array\n     *\n     * @throws \\ReflectionException\n     */\n    protected function closureParameterTypes(Closure $closure)\n    {\n        $reflection = new ReflectionFunction($closure);\n\n        return (new Collection($reflection->getParameters()))\n            ->mapWithKeys(function ($parameter) {\n                if ($parameter->isVariadic()) {\n                    return [$parameter->getName() => null];\n                }\n\n                return [$parameter->getName() => Reflector::getParameterClassName($parameter)];\n            })\n            ->all();\n    }\n\n    /**\n     * Get the class names / types of the return type of the given Closure.\n     *\n     * @param  \\Closure  $closure\n     * @return list<class-string>\n     *\n     * @throws \\ReflectionException\n     */\n    protected function closureReturnTypes(Closure $closure)\n    {\n        $reflection = new ReflectionFunction($closure);\n\n        if ($reflection->getReturnType() === null ||\n            $reflection->getReturnType() instanceof ReflectionIntersectionType) {\n            return [];\n        }\n\n        $types = $reflection->getReturnType() instanceof ReflectionUnionType\n            ? $reflection->getReturnType()->getTypes()\n            : [$reflection->getReturnType()];\n\n        return (new Collection($types))\n            ->reject(fn ($type) => $type->isBuiltin())\n            ->reject(fn ($type) => in_array($type->getName(), ['static', 'self']))\n            ->map(fn ($type) => $type->getName())\n            ->values()\n            ->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Reflection/composer.json",
    "content": "{\n    \"name\": \"illuminate/reflection\",\n    \"description\": \"The Illuminate Reflection package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Support\\\\\": \"\"\n        },\n        \"files\": [\n            \"helpers.php\"\n        ]\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Reflection/helpers.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\n\nif (! function_exists('lazy')) {\n    /**\n     * Create a lazy instance.\n     *\n     * @template TValue of object\n     *\n     * @param  class-string<TValue>|(\\Closure(TValue): mixed)  $class\n     * @param  (\\Closure(TValue): mixed)|int  $callback\n     * @param  int  $options\n     * @param  array<string, mixed>  $eager\n     * @return TValue\n     */\n    function lazy($class, $callback = 0, $options = 0, $eager = [])\n    {\n        static $closureReflector;\n\n        $closureReflector ??= new class\n        {\n            use ReflectsClosures;\n\n            public function typeFromParameter($callback)\n            {\n                return $this->firstClosureParameterType($callback);\n            }\n        };\n\n        [$class, $callback, $options] = is_string($class)\n            ? [$class, $callback, $options]\n            : [$closureReflector->typeFromParameter($class), $class, $callback ?: $options];\n\n        $reflectionClass = new ReflectionClass($class);\n\n        $instance = $reflectionClass->newLazyGhost(function ($instance) use ($callback) {\n            $result = $callback($instance);\n\n            if (is_array($result)) {\n                $instance->__construct(...$result);\n            }\n        }, $options);\n\n        foreach ($eager as $property => $value) {\n            $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($instance, $value);\n        }\n\n        return $instance;\n    }\n}\n\nif (! function_exists('proxy')) {\n    /**\n     * Create a lazy proxy instance.\n     *\n     * @template TValue of object\n     *\n     * @param  class-string<TValue>|(\\Closure(TValue): TValue)  $class\n     * @param  (\\Closure(TValue): TValue)|int  $callback\n     * @param  int  $options\n     * @param  array<string, mixed>  $eager\n     * @return TValue\n     */\n    function proxy($class, $callback = 0, $options = 0, $eager = [])\n    {\n        static $closureReflector;\n\n        $closureReflector = new class\n        {\n            use ReflectsClosures;\n\n            public function get($callback)\n            {\n                return $this->closureReturnTypes($callback)[0] ?? $this->firstClosureParameterType($callback);\n            }\n        };\n\n        [$class, $callback, $options] = is_string($class)\n            ? [$class, $callback, $options]\n            : [$closureReflector->get($class), $class, $callback ?: $options];\n\n        $reflectionClass = new ReflectionClass($class);\n\n        $proxy = $reflectionClass->newLazyProxy(function () use ($callback, $eager, &$proxy) {\n            $instance = $callback($proxy, $eager);\n\n            return $instance;\n        }, $options);\n\n        foreach ($eager as $property => $value) {\n            $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($proxy, $value);\n        }\n\n        return $proxy;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Routing/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Routing/AbstractRouteCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse ArrayIterator;\nuse Countable;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Str;\nuse IteratorAggregate;\nuse LogicException;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\nuse Symfony\\Component\\Routing\\RouteCollection as SymfonyRouteCollection;\nuse Traversable;\n\nabstract class AbstractRouteCollection implements Countable, IteratorAggregate, RouteCollectionInterface\n{\n    /**\n     * Handle the matched route.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Routing\\Route|null  $route\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    protected function handleMatchedRoute(Request $request, $route)\n    {\n        if (! is_null($route)) {\n            return $route->bind($request);\n        }\n\n        // If no route was found we will now check if a matching route is specified by\n        // another HTTP verb. If it is we will need to throw a MethodNotAllowed and\n        // inform the user agent of which HTTP verb it should use for this route.\n        $others = $this->checkForAlternateVerbs($request);\n\n        if (count($others) > 0) {\n            return $this->getRouteForMethods($request, $others);\n        }\n\n        throw new NotFoundHttpException(sprintf(\n            'The route %s could not be found.',\n            $request->path()\n        ));\n    }\n\n    /**\n     * Determine if any routes match on another HTTP verb.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    protected function checkForAlternateVerbs($request)\n    {\n        $methods = array_diff(Router::$verbs, [$request->getMethod()]);\n\n        // Here we will spin through all verbs except for the current request verb and\n        // check to see if any routes respond to them. If they do, we will return a\n        // proper error response with the correct headers on the response string.\n        return array_values(array_filter(\n            $methods,\n            function ($method) use ($request) {\n                return ! is_null($this->matchAgainstRoutes($this->get($method), $request, false));\n            }\n        ));\n    }\n\n    /**\n     * Determine if a route in the array matches the request.\n     *\n     * @param  \\Illuminate\\Routing\\Route[]  $routes\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  bool  $includingMethod\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    protected function matchAgainstRoutes(array $routes, $request, $includingMethod = true)\n    {\n        $fallbackRoute = null;\n\n        foreach ($routes as $route) {\n            if ($route->matches($request, $includingMethod)) {\n                if ($route->isFallback) {\n                    $fallbackRoute ??= $route;\n\n                    continue;\n                }\n\n                return $route;\n            }\n        }\n\n        return $fallbackRoute;\n    }\n\n    /**\n     * Get a route (if necessary) that responds when other available methods are present.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string[]  $methods\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     */\n    protected function getRouteForMethods($request, array $methods)\n    {\n        if ($request->isMethod('OPTIONS')) {\n            return (new Route('OPTIONS', $request->path(), function () use ($methods) {\n                return new Response('', 200, ['Allow' => implode(',', $methods)]);\n            }))->bind($request);\n        }\n\n        $this->requestMethodNotAllowed($request, $methods, $request->method());\n    }\n\n    /**\n     * Throw a method not allowed HTTP exception.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $others\n     * @param  string  $method\n     * @return never\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     */\n    protected function requestMethodNotAllowed($request, array $others, $method)\n    {\n        throw new MethodNotAllowedHttpException(\n            $others,\n            sprintf(\n                'The %s method is not supported for route %s. Supported methods: %s.',\n                $method,\n                $request->path(),\n                implode(', ', $others)\n            )\n        );\n    }\n\n    /**\n     * Throw a method not allowed HTTP exception.\n     *\n     * @param  array  $others\n     * @param  string  $method\n     * @return void\n     *\n     * @deprecated use requestMethodNotAllowed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     */\n    protected function methodNotAllowed(array $others, $method)\n    {\n        throw new MethodNotAllowedHttpException(\n            $others,\n            sprintf(\n                'The %s method is not supported for this route. Supported methods: %s.',\n                $method,\n                implode(', ', $others)\n            )\n        );\n    }\n\n    /**\n     * Compile the routes for caching.\n     *\n     * @return array\n     */\n    public function compile()\n    {\n        $compiled = $this->dumper()->getCompiledRoutes();\n\n        $attributes = [];\n\n        foreach ($this->getRoutes() as $route) {\n            $attributes[$route->getName()] = [\n                'methods' => $route->methods(),\n                'uri' => $route->uri(),\n                'action' => $route->getAction(),\n                'fallback' => $route->isFallback,\n                'defaults' => $route->defaults,\n                'wheres' => $route->wheres,\n                'bindingFields' => $route->bindingFields(),\n                'lockSeconds' => $route->locksFor(),\n                'waitSeconds' => $route->waitsFor(),\n                'withTrashed' => $route->allowsTrashedBindings(),\n            ];\n        }\n\n        return compact('compiled', 'attributes');\n    }\n\n    /**\n     * Return the CompiledUrlMatcherDumper instance for the route collection.\n     *\n     * @return \\Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper\n     */\n    public function dumper()\n    {\n        return new CompiledUrlMatcherDumper($this->toSymfonyRouteCollection());\n    }\n\n    /**\n     * Convert the collection to a Symfony RouteCollection instance.\n     *\n     * @return \\Symfony\\Component\\Routing\\RouteCollection\n     */\n    public function toSymfonyRouteCollection()\n    {\n        $symfonyRoutes = new SymfonyRouteCollection;\n\n        $fallbackRoutes = [];\n\n        foreach ($this->getRoutes() as $route) {\n            if ($route->isFallback) {\n                $fallbackRoutes[] = $route;\n\n                continue;\n            }\n\n            $symfonyRoutes = $this->addToSymfonyRoutesCollection($symfonyRoutes, $route);\n        }\n\n        foreach ($fallbackRoutes as $route) {\n            $symfonyRoutes = $this->addToSymfonyRoutesCollection($symfonyRoutes, $route);\n        }\n\n        return $symfonyRoutes;\n    }\n\n    /**\n     * Add a route to the SymfonyRouteCollection instance.\n     *\n     * @param  \\Symfony\\Component\\Routing\\RouteCollection  $symfonyRoutes\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Symfony\\Component\\Routing\\RouteCollection\n     *\n     * @throws \\LogicException\n     */\n    protected function addToSymfonyRoutesCollection(SymfonyRouteCollection $symfonyRoutes, Route $route)\n    {\n        $name = $route->getName();\n\n        if (\n            ! is_null($name)\n            && str_ends_with($name, '.')\n            && ! is_null($symfonyRoutes->get($name))\n        ) {\n            $name = null;\n        }\n\n        if (! $name) {\n            $route->name($this->generateRouteName());\n\n            $this->add($route);\n        } elseif (! is_null($symfonyRoutes->get($name))) {\n            throw new LogicException(\"Unable to prepare route [{$route->uri}] for serialization. Another route has already been assigned name [{$name}].\");\n        }\n\n        $symfonyRoutes->add($route->getName(), $route->toSymfonyRoute());\n\n        return $symfonyRoutes;\n    }\n\n    /**\n     * Get a randomly generated route name.\n     *\n     * @return string\n     */\n    protected function generateRouteName()\n    {\n        return 'generated::'.Str::random();\n    }\n\n    /**\n     * Get an iterator for the items.\n     *\n     * @return \\ArrayIterator\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->getRoutes());\n    }\n\n    /**\n     * Count the number of items in the collection.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return count($this->getRoutes());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Attributes/Controllers/Authorize.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Attributes\\Controllers;\n\nuse Attribute;\nuse Illuminate\\Auth\\Middleware\\Authorize as AuthorizeMiddleware;\nuse Illuminate\\Support\\Arr;\nuse UnitEnum;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]\nclass Authorize extends Middleware\n{\n    /**\n     * @param  array<string>|string|null  $models\n     */\n    public function __construct(\n        UnitEnum|string $ability,\n        array|string|null $models = null,\n        ?array $only = null,\n        ?array $except = null,\n    ) {\n        $middleware = AuthorizeMiddleware::using($ability, ...Arr::wrap($models));\n\n        parent::__construct($middleware, $only, $except);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Attributes/Controllers/Middleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Attributes\\Controllers;\n\nuse Attribute;\nuse Closure;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]\nclass Middleware\n{\n    /**\n     * @param  array<string>|null  $only\n     * @param  array<string>|null  $except\n     */\n    public function __construct(\n        public Closure|string $middleware,\n        public ?array $only = null,\n        public ?array $except = null,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/CallableDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse ReflectionFunction;\n\nclass CallableDispatcher implements CallableDispatcherContract\n{\n    use ResolvesRouteDependencies;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Create a new callable dispatcher instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Dispatch a request to a given callable.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  callable  $callable\n     * @return mixed\n     */\n    public function dispatch(Route $route, $callable)\n    {\n        return $callable(...array_values($this->resolveParameters($route, $callable)));\n    }\n\n    /**\n     * Resolve the parameters for the callable.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  callable  $callable\n     * @return array\n     */\n    protected function resolveParameters(Route $route, $callable)\n    {\n        return $this->resolveMethodDependencies($route->parametersWithoutNulls(), new ReflectionFunction($callable));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/CompiledRouteCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\Matcher\\CompiledUrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\n\nclass CompiledRouteCollection extends AbstractRouteCollection\n{\n    /**\n     * The compiled routes collection.\n     *\n     * @var array\n     */\n    protected $compiled = [];\n\n    /**\n     * An array of the route attributes keyed by name.\n     *\n     * @var array\n     */\n    protected $attributes = [];\n\n    /**\n     * The dynamically added routes that were added after loading the cached, compiled routes.\n     *\n     * @var \\Illuminate\\Routing\\RouteCollection|null\n     */\n    protected $routes;\n\n    /**\n     * The router instance used by the route.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The container instance used by the route.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * A cache of resolved Route instances keyed by route name.\n     *\n     * @var array<string, \\Illuminate\\Routing\\Route>\n     */\n    protected $nameCache = [];\n\n    /**\n     * Create a new CompiledRouteCollection instance.\n     *\n     * @param  array  $compiled\n     * @param  array  $attributes\n     */\n    public function __construct(array $compiled, array $attributes)\n    {\n        $this->compiled = $compiled;\n        $this->attributes = $attributes;\n        $this->routes = new RouteCollection;\n    }\n\n    /**\n     * Add a Route instance to the collection.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function add(Route $route)\n    {\n        return $this->routes->add($route);\n    }\n\n    /**\n     * Refresh the name look-up table.\n     *\n     * This is done in case any names are fluently defined or if routes are overwritten.\n     *\n     * @return void\n     */\n    public function refreshNameLookups()\n    {\n        //\n    }\n\n    /**\n     * Refresh the action look-up table.\n     *\n     * This is done in case any actions are overwritten with new controllers.\n     *\n     * @return void\n     */\n    public function refreshActionLookups()\n    {\n        //\n    }\n\n    /**\n     * Find the first route matching a given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    public function match(Request $request)\n    {\n        $matcher = new CompiledUrlMatcher(\n            $this->compiled, (new RequestContext)->fromRequest(\n                $trimmedRequest = $this->requestWithoutTrailingSlash($request)\n            )\n        );\n\n        $route = null;\n\n        try {\n            if ($result = $matcher->matchRequest($trimmedRequest)) {\n                $route = $this->getByName($result['_route']);\n            }\n        } catch (ResourceNotFoundException|MethodNotAllowedException) {\n            try {\n                return $this->routes->match($request);\n            } catch (NotFoundHttpException) {\n                //\n            }\n        }\n\n        if ($route && $route->isFallback) {\n            try {\n                $dynamicRoute = $this->routes->match($request);\n\n                if (! $dynamicRoute->isFallback) {\n                    $route = $dynamicRoute;\n                }\n            } catch (NotFoundHttpException|MethodNotAllowedHttpException) {\n                //\n            }\n        }\n\n        return $this->handleMatchedRoute($request, $route);\n    }\n\n    /**\n     * Get a cloned instance of the given request without any trailing slash on the URI.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function requestWithoutTrailingSlash(Request $request)\n    {\n        $trimmedRequest = $request->duplicate();\n\n        $parts = explode('?', $request->server->get('REQUEST_URI'), 2);\n\n        $trimmedRequest->server->set(\n            'REQUEST_URI', rtrim($parts[0], '/').(isset($parts[1]) ? '?'.$parts[1] : '')\n        );\n\n        return $trimmedRequest;\n    }\n\n    /**\n     * Get routes from the collection by method.\n     *\n     * @param  string|null  $method\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function get($method = null)\n    {\n        return $this->getRoutesByMethod()[$method] ?? [];\n    }\n\n    /**\n     * Determine if the route collection contains a given named route.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasNamedRoute($name)\n    {\n        return isset($this->attributes[$name]) || $this->routes->hasNamedRoute($name);\n    }\n\n    /**\n     * Get a route instance by its name.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByName($name)\n    {\n        if (isset($this->nameCache[$name])) {\n            return $this->nameCache[$name];\n        }\n\n        if (isset($this->attributes[$name])) {\n            return $this->nameCache[$name] = $this->newRoute($this->attributes[$name]);\n        }\n\n        return $this->routes->getByName($name);\n    }\n\n    /**\n     * Get a route instance by its controller action.\n     *\n     * @param  string  $action\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByAction($action)\n    {\n        $attributes = (new Collection($this->attributes))->first(function (array $attributes) use ($action) {\n            if (isset($attributes['action']['controller'])) {\n                return trim($attributes['action']['controller'], '\\\\') === $action;\n            }\n\n            return $attributes['action']['uses'] === $action;\n        });\n\n        if ($attributes) {\n            return $this->newRoute($attributes);\n        }\n\n        return $this->routes->getByAction($action);\n    }\n\n    /**\n     * Get all of the routes in the collection.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutes()\n    {\n        return (new Collection($this->attributes))\n            ->map(function (array $attributes) {\n                return $this->newRoute($attributes);\n            })\n            ->merge($this->routes->getRoutes())\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Get all of the routes keyed by their HTTP verb / method.\n     *\n     * @return array\n     */\n    public function getRoutesByMethod()\n    {\n        return (new Collection($this->getRoutes()))\n            ->groupBy(function (Route $route) {\n                return $route->methods();\n            })\n            ->map(function (Collection $routes) {\n                return $routes->mapWithKeys(function (Route $route) {\n                    return [$route->getDomain().$route->uri => $route];\n                })->all();\n            })\n            ->all();\n    }\n\n    /**\n     * Get all of the routes keyed by their name.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutesByName()\n    {\n        return (new Collection($this->getRoutes()))\n            ->keyBy(function (Route $route) {\n                return $route->getName();\n            })\n            ->all();\n    }\n\n    /**\n     * Resolve an array of attributes to a Route instance.\n     *\n     * @param  array  $attributes\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function newRoute(array $attributes)\n    {\n        if (empty($attributes['action']['prefix'] ?? '')) {\n            $baseUri = $attributes['uri'];\n        } else {\n            $prefix = trim($attributes['action']['prefix'], '/');\n\n            $baseUri = trim(implode(\n                '/', array_slice(\n                    explode('/', trim($attributes['uri'], '/')),\n                    count($prefix !== '' ? explode('/', $prefix) : [])\n                )\n            ), '/');\n        }\n\n        return $this->router->newRoute($attributes['methods'], $baseUri === '' ? '/' : $baseUri, $attributes['action'])\n            ->setFallback($attributes['fallback'])\n            ->setDefaults($attributes['defaults'])\n            ->setWheres($attributes['wheres'])\n            ->setBindingFields($attributes['bindingFields'])\n            ->block($attributes['lockSeconds'] ?? null, $attributes['waitSeconds'] ?? null)\n            ->withTrashed($attributes['withTrashed'] ?? false);\n    }\n\n    /**\n     * Set the router instance on the route.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     * @return $this\n     */\n    public function setRouter(Router $router)\n    {\n        $this->router = $router;\n\n        return $this;\n    }\n\n    /**\n     * Set the container instance on the route.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/ControllerMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse InvalidArgumentException;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nuse function Laravel\\Prompts\\confirm;\nuse function Laravel\\Prompts\\select;\nuse function Laravel\\Prompts\\suggest;\n\n#[AsCommand(name: 'make:controller')]\nclass ControllerMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:controller';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new controller class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Controller';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        $stub = null;\n\n        if ($type = $this->option('type')) {\n            $stub = \"/stubs/controller.{$type}.stub\";\n        } elseif ($this->option('parent')) {\n            $stub = $this->option('singleton')\n                ? '/stubs/controller.nested.singleton.stub'\n                : '/stubs/controller.nested.stub';\n        } elseif ($this->option('model')) {\n            $stub = '/stubs/controller.model.stub';\n        } elseif ($this->option('invokable')) {\n            $stub = '/stubs/controller.invokable.stub';\n        } elseif ($this->option('singleton')) {\n            $stub = '/stubs/controller.singleton.stub';\n        } elseif ($this->option('resource')) {\n            $stub = '/stubs/controller.stub';\n        }\n\n        if ($this->option('api') && is_null($stub)) {\n            $stub = '/stubs/controller.api.stub';\n        } elseif ($this->option('api') && ! is_null($stub) && ! $this->option('invokable')) {\n            $stub = str_replace('.stub', '.api.stub', $stub);\n        }\n\n        $stub ??= '/stubs/controller.plain.stub';\n\n        return $this->resolveStubPath($stub);\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Http\\Controllers';\n    }\n\n    /**\n     * Build the class with the given name.\n     *\n     * Remove the base controller import if we are already in the base namespace.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function buildClass($name)\n    {\n        $rootNamespace = $this->rootNamespace();\n        $controllerNamespace = $this->getNamespace($name);\n\n        $replace = [];\n\n        if ($this->option('parent')) {\n            $replace = $this->buildParentReplacements();\n        }\n\n        if ($this->option('model')) {\n            $replace = $this->buildModelReplacements($replace);\n        }\n\n        if ($this->option('creatable')) {\n            $replace['abort(404);'] = '//';\n        }\n\n        $baseControllerExists = file_exists($this->getPath(\"{$rootNamespace}Http\\Controllers\\Controller\"));\n\n        if ($baseControllerExists) {\n            $replace[\"use {$controllerNamespace}\\Controller;\\n\"] = '';\n        } else {\n            $replace[' extends Controller'] = '';\n            $replace[\"use {$rootNamespace}Http\\Controllers\\Controller;\\n\"] = '';\n        }\n\n        return str_replace(\n            array_keys($replace), array_values($replace), parent::buildClass($name)\n        );\n    }\n\n    /**\n     * Build the replacements for a parent controller.\n     *\n     * @return array\n     */\n    protected function buildParentReplacements()\n    {\n        $parentModelClass = $this->parseModel($this->option('parent'));\n\n        if (! class_exists($parentModelClass) &&\n            confirm(\"A {$parentModelClass} model does not exist. Do you want to generate it?\", default: true)) {\n            $this->call('make:model', ['name' => $parentModelClass]);\n        }\n\n        return [\n            'ParentDummyFullModelClass' => $parentModelClass,\n            '{{ namespacedParentModel }}' => $parentModelClass,\n            '{{namespacedParentModel}}' => $parentModelClass,\n            'ParentDummyModelClass' => class_basename($parentModelClass),\n            '{{ parentModel }}' => class_basename($parentModelClass),\n            '{{parentModel}}' => class_basename($parentModelClass),\n            'ParentDummyModelVariable' => lcfirst(class_basename($parentModelClass)),\n            '{{ parentModelVariable }}' => lcfirst(class_basename($parentModelClass)),\n            '{{parentModelVariable}}' => lcfirst(class_basename($parentModelClass)),\n        ];\n    }\n\n    /**\n     * Build the model replacement values.\n     *\n     * @param  array  $replace\n     * @return array\n     */\n    protected function buildModelReplacements(array $replace)\n    {\n        $modelClass = $this->parseModel($this->option('model'));\n\n        if (! class_exists($modelClass) && confirm(\"A {$modelClass} model does not exist. Do you want to generate it?\", default: true)) {\n            $this->call('make:model', ['name' => $modelClass]);\n        }\n\n        $replace = $this->buildFormRequestReplacements($replace, $modelClass);\n\n        return array_merge($replace, [\n            'DummyFullModelClass' => $modelClass,\n            '{{ namespacedModel }}' => $modelClass,\n            '{{namespacedModel}}' => $modelClass,\n            'DummyModelClass' => class_basename($modelClass),\n            '{{ model }}' => class_basename($modelClass),\n            '{{model}}' => class_basename($modelClass),\n            'DummyModelVariable' => lcfirst(class_basename($modelClass)),\n            '{{ modelVariable }}' => lcfirst(class_basename($modelClass)),\n            '{{modelVariable}}' => lcfirst(class_basename($modelClass)),\n        ]);\n    }\n\n    /**\n     * Get the fully-qualified model class name.\n     *\n     * @param  string  $model\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseModel($model)\n    {\n        if (preg_match('/[^A-Za-z0-9_\\/\\\\\\\\]/', $model)) {\n            throw new InvalidArgumentException('Model name contains invalid characters.');\n        }\n\n        return $this->qualifyModel($model);\n    }\n\n    /**\n     * Build the model replacement values.\n     *\n     * @param  array  $replace\n     * @param  string  $modelClass\n     * @return array\n     */\n    protected function buildFormRequestReplacements(array $replace, $modelClass)\n    {\n        [$namespace, $storeRequestClass, $updateRequestClass] = [\n            'Illuminate\\\\Http', 'Request', 'Request',\n        ];\n\n        if ($this->option('requests')) {\n            $namespace = 'App\\\\Http\\\\Requests';\n\n            [$storeRequestClass, $updateRequestClass] = $this->generateFormRequests(\n                $modelClass, $storeRequestClass, $updateRequestClass\n            );\n        }\n\n        $namespacedRequests = $namespace.'\\\\'.$storeRequestClass.';';\n\n        if ($storeRequestClass !== $updateRequestClass) {\n            $namespacedRequests .= PHP_EOL.'use '.$namespace.'\\\\'.$updateRequestClass.';';\n        }\n\n        return array_merge($replace, [\n            '{{ storeRequest }}' => $storeRequestClass,\n            '{{storeRequest}}' => $storeRequestClass,\n            '{{ updateRequest }}' => $updateRequestClass,\n            '{{updateRequest}}' => $updateRequestClass,\n            '{{ namespacedStoreRequest }}' => $namespace.'\\\\'.$storeRequestClass,\n            '{{namespacedStoreRequest}}' => $namespace.'\\\\'.$storeRequestClass,\n            '{{ namespacedUpdateRequest }}' => $namespace.'\\\\'.$updateRequestClass,\n            '{{namespacedUpdateRequest}}' => $namespace.'\\\\'.$updateRequestClass,\n            '{{ namespacedRequests }}' => $namespacedRequests,\n            '{{namespacedRequests}}' => $namespacedRequests,\n        ]);\n    }\n\n    /**\n     * Generate the form requests for the given model and classes.\n     *\n     * @param  string  $modelClass\n     * @param  string  $storeRequestClass\n     * @param  string  $updateRequestClass\n     * @return array\n     */\n    protected function generateFormRequests($modelClass, $storeRequestClass, $updateRequestClass)\n    {\n        $storeRequestClass = 'Store'.class_basename($modelClass).'Request';\n\n        $this->call('make:request', [\n            'name' => $storeRequestClass,\n        ]);\n\n        $updateRequestClass = 'Update'.class_basename($modelClass).'Request';\n\n        $this->call('make:request', [\n            'name' => $updateRequestClass,\n        ]);\n\n        return [$storeRequestClass, $updateRequestClass];\n    }\n\n    /**\n     * Get the console command options.\n     *\n     * @return array\n     */\n    protected function getOptions()\n    {\n        return [\n            ['api', null, InputOption::VALUE_NONE, 'Exclude the create and edit methods from the controller'],\n            ['type', null, InputOption::VALUE_REQUIRED, 'Manually specify the controller stub file to use'],\n            ['force', null, InputOption::VALUE_NONE, 'Create the class even if the controller already exists'],\n            ['invokable', 'i', InputOption::VALUE_NONE, 'Generate a single method, invokable controller class'],\n            ['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate a resource controller for the given model'],\n            ['parent', 'p', InputOption::VALUE_OPTIONAL, 'Generate a nested resource controller class'],\n            ['resource', 'r', InputOption::VALUE_NONE, 'Generate a resource controller class'],\n            ['requests', 'R', InputOption::VALUE_NONE, 'Generate FormRequest classes for store and update'],\n            ['singleton', 's', InputOption::VALUE_NONE, 'Generate a singleton resource controller class'],\n            ['creatable', null, InputOption::VALUE_NONE, 'Indicate that a singleton resource should be creatable'],\n        ];\n    }\n\n    /**\n     * Interact further with the user if they were prompted for missing arguments.\n     *\n     * @param  \\Symfony\\Component\\Console\\Input\\InputInterface  $input\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @return void\n     */\n    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)\n    {\n        if ($this->didReceiveOptions($input)) {\n            return;\n        }\n\n        $type = select('Which type of controller would you like?', [\n            'empty' => 'Empty',\n            'resource' => 'Resource',\n            'singleton' => 'Singleton',\n            'api' => 'API',\n            'invokable' => 'Invokable',\n        ]);\n\n        if ($type !== 'empty') {\n            $input->setOption($type, true);\n        }\n\n        if (in_array($type, ['api', 'resource', 'singleton'])) {\n            $model = suggest(\n                \"What model is this $type controller for? (Optional)\",\n                $this->findAvailableModels()\n            );\n\n            if ($model) {\n                $input->setOption('model', $model);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/MiddlewareMakeCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Console;\n\nuse Illuminate\\Console\\Concerns\\CreatesMatchingTest;\nuse Illuminate\\Console\\GeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\n#[AsCommand(name: 'make:middleware')]\nclass MiddlewareMakeCommand extends GeneratorCommand\n{\n    use CreatesMatchingTest;\n\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:middleware';\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a new HTTP middleware class';\n\n    /**\n     * The type of class being generated.\n     *\n     * @var string\n     */\n    protected $type = 'Middleware';\n\n    /**\n     * Get the stub file for the generator.\n     *\n     * @return string\n     */\n    protected function getStub()\n    {\n        return $this->resolveStubPath('/stubs/middleware.stub');\n    }\n\n    /**\n     * Resolve the fully-qualified path to the stub.\n     *\n     * @param  string  $stub\n     * @return string\n     */\n    protected function resolveStubPath($stub)\n    {\n        return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))\n            ? $customPath\n            : __DIR__.$stub;\n    }\n\n    /**\n     * Get the default namespace for the class.\n     *\n     * @param  string  $rootNamespace\n     * @return string\n     */\n    protected function getDefaultNamespace($rootNamespace)\n    {\n        return $rootNamespace.'\\Http\\Middleware';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store(Request $request)\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show(string $id)\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update(Request $request, string $id)\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy(string $id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.invokable.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Handle the incoming request.\n     */\n    public function __invoke(Request $request)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.model.api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse {{ namespacedRequests }}\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store({{ storeRequest }} $request)\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show({{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update({{ updateRequest }} $request, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy({{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.model.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse {{ namespacedRequests }}\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Show the form for creating a new resource.\n     */\n    public function create()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store({{ storeRequest }} $request)\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show({{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the specified resource.\n     */\n    public function edit({{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update({{ updateRequest }} $request, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy({{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.nested.api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse {{ namespacedParentModel }};\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store(Request $request, {{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show({{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update(Request $request, {{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy({{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.nested.singleton.api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\nuse {{ namespacedParentModel }};\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Store the newly created resource in storage.\n     */\n    public function store(Request $request, {{ parentModel }} ${{ parentModelVariable }}): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Display the resource.\n     */\n    public function show({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the resource in storage.\n     */\n    public function update(Request $request, {{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the resource from storage.\n     */\n    public function destroy({{ parentModel }} ${{ parentModelVariable }}): never\n    {\n        abort(404);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.nested.singleton.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\nuse {{ namespacedParentModel }};\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Show the form for creating the new resource.\n     */\n    public function create({{ parentModel }} ${{ parentModelVariable }}): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Store the newly created resource in storage.\n     */\n    public function store(Request $request, {{ parentModel }} ${{ parentModelVariable }}): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Display the resource.\n     */\n    public function show({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the resource.\n     */\n    public function edit({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the resource in storage.\n     */\n    public function update(Request $request, {{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the resource from storage.\n     */\n    public function destroy({{ parentModel }} ${{ parentModelVariable }}): never\n    {\n        abort(404);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.nested.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ namespacedModel }};\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse {{ namespacedParentModel }};\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Show the form for creating a new resource.\n     */\n    public function create({{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store(Request $request, {{ parentModel }} ${{ parentModelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show({{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the specified resource.\n     */\n    public function edit({{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update(Request $request, {{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy({{ parentModel }} ${{ parentModelVariable }}, {{ model }} ${{ modelVariable }})\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.plain.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.singleton.api.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Store the newly created resource in storage.\n     */\n    public function store(Request $request): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Display the resource.\n     */\n    public function show()\n    {\n        //\n    }\n\n    /**\n     * Update the resource in storage.\n     */\n    public function update(Request $request)\n    {\n        //\n    }\n\n    /**\n     * Remove the resource from storage.\n     */\n    public function destroy(): never\n    {\n        abort(404);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.singleton.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Show the form for creating the resource.\n     */\n    public function create(): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Store the newly created resource in storage.\n     */\n    public function store(Request $request): never\n    {\n        abort(404);\n    }\n\n    /**\n     * Display the resource.\n     */\n    public function show()\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the resource.\n     */\n    public function edit()\n    {\n        //\n    }\n\n    /**\n     * Update the resource in storage.\n     */\n    public function update(Request $request)\n    {\n        //\n    }\n\n    /**\n     * Remove the resource from storage.\n     */\n    public function destroy(): never\n    {\n        abort(404);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/controller.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse {{ rootNamespace }}Http\\Controllers\\Controller;\nuse Illuminate\\Http\\Request;\n\nclass {{ class }} extends Controller\n{\n    /**\n     * Display a listing of the resource.\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Show the form for creating a new resource.\n     */\n    public function create()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     */\n    public function store(Request $request)\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     */\n    public function show(string $id)\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the specified resource.\n     */\n    public function edit(string $id)\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     */\n    public function update(Request $request, string $id)\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     */\n    public function destroy(string $id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Console/stubs/middleware.stub",
    "content": "<?php\n\nnamespace {{ namespace }};\n\nuse Closure;\nuse Illuminate\\Http\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass {{ class }}\n{\n    /**\n     * Handle an incoming request.\n     *\n     * @param  Closure(Request): (Response)  $next\n     */\n    public function handle(Request $request, Closure $next): Response\n    {\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Contracts/CallableDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Contracts;\n\nuse Illuminate\\Routing\\Route;\n\ninterface CallableDispatcher\n{\n    /**\n     * Dispatch a request to a given callable.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  callable  $callable\n     * @return mixed\n     */\n    public function dispatch(Route $route, $callable);\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Contracts/ControllerDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Contracts;\n\nuse Illuminate\\Routing\\Route;\n\ninterface ControllerDispatcher\n{\n    /**\n     * Dispatch a request to a given controller and method.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $controller\n     * @param  string  $method\n     * @return mixed\n     */\n    public function dispatch(Route $route, $controller, $method);\n\n    /**\n     * Get the middleware for the controller instance.\n     *\n     * @param  \\Illuminate\\Routing\\Controller  $controller\n     * @param  string  $method\n     * @return array\n     */\n    public function getMiddleware($controller, $method);\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Controller.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse BadMethodCallException;\n\nabstract class Controller\n{\n    /**\n     * The middleware registered on the controller.\n     *\n     * @var array\n     */\n    protected $middleware = [];\n\n    /**\n     * Register middleware on the controller.\n     *\n     * @param  \\Closure|array|string  $middleware\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\ControllerMiddlewareOptions\n     */\n    public function middleware($middleware, array $options = [])\n    {\n        foreach ((array) $middleware as $m) {\n            $this->middleware[] = [\n                'middleware' => $m,\n                'options' => &$options,\n            ];\n        }\n\n        return new ControllerMiddlewareOptions($options);\n    }\n\n    /**\n     * Get the middleware assigned to the controller.\n     *\n     * @return array\n     */\n    public function getMiddleware()\n    {\n        return $this->middleware;\n    }\n\n    /**\n     * Execute an action on the controller.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function callAction($method, $parameters)\n    {\n        return $this->{$method}(...array_values($parameters));\n    }\n\n    /**\n     * Handle calls to missing methods on the controller.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        throw new BadMethodCallException(sprintf(\n            'Method %s::%s does not exist.',\n            static::class,\n            $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ControllerDispatcher.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\nuse Illuminate\\Support\\Collection;\n\nclass ControllerDispatcher implements ControllerDispatcherContract\n{\n    use FiltersControllerMiddleware, ResolvesRouteDependencies;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Create a new controller dispatcher instance.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Dispatch a request to a given controller and method.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $controller\n     * @param  string  $method\n     * @return mixed\n     */\n    public function dispatch(Route $route, $controller, $method)\n    {\n        $parameters = $this->resolveParameters($route, $controller, $method);\n\n        if (method_exists($controller, 'callAction')) {\n            return $controller->callAction($method, $parameters);\n        }\n\n        return $controller->{$method}(...array_values($parameters));\n    }\n\n    /**\n     * Resolve the parameters for the controller.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $controller\n     * @param  string  $method\n     * @return array\n     */\n    protected function resolveParameters(Route $route, $controller, $method)\n    {\n        return $this->resolveClassMethodDependencies(\n            $route->parametersWithoutNulls(), $controller, $method\n        );\n    }\n\n    /**\n     * Get the middleware for the controller instance.\n     *\n     * @param  \\Illuminate\\Routing\\Controller  $controller\n     * @param  string  $method\n     * @return array\n     */\n    public function getMiddleware($controller, $method)\n    {\n        if (! method_exists($controller, 'getMiddleware')) {\n            return [];\n        }\n\n        return (new Collection($controller->getMiddleware()))\n            ->reject(fn ($data) => static::methodExcludedByOptions($method, $data['options']))\n            ->pluck('middleware')\n            ->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ControllerMiddlewareOptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nclass ControllerMiddlewareOptions\n{\n    /**\n     * The middleware options.\n     *\n     * @var array\n     */\n    protected $options;\n\n    /**\n     * Create a new middleware option instance.\n     *\n     * @param  array  $options\n     */\n    public function __construct(array &$options)\n    {\n        $this->options = &$options;\n    }\n\n    /**\n     * Set the controller methods the middleware should apply to.\n     *\n     * @param  mixed  $methods\n     * @return $this\n     */\n    public function only($methods)\n    {\n        $this->options['only'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Set the controller methods the middleware should exclude.\n     *\n     * @param  mixed  $methods\n     * @return $this\n     */\n    public function except($methods)\n    {\n        $this->options['except'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Controllers/HasMiddleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Controllers;\n\ninterface HasMiddleware\n{\n    /**\n     * Get the middleware that should be assigned to the controller.\n     *\n     * @return array<int,\\Illuminate\\Routing\\Controllers\\Middleware|\\Closure|string>\n     */\n    public static function middleware();\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Controllers/Middleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Controllers;\n\nuse Closure;\nuse Illuminate\\Support\\Arr;\n\n/**\n * @phpstan-type NextClosure \\Closure(\\Illuminate\\Http\\Request): \\Symfony\\Component\\HttpFoundation\\Response\n */\nclass Middleware\n{\n    /**\n     * Create a new controller middleware definition.\n     *\n     * @param  (\\Closure(\\Illuminate\\Http\\Request, NextClosure): \\Symfony\\Component\\HttpFoundation\\Response)|string|array  $middleware\n     * @param  array<string>|null  $only\n     * @param  array<string>|null  $except\n     */\n    public function __construct(public Closure|string|array $middleware, public ?array $only = null, public ?array $except = null)\n    {\n    }\n\n    /**\n     * Specify the only controller methods the middleware should apply to.\n     *\n     * @param  array|string  $only\n     * @return $this\n     */\n    public function only(array|string $only)\n    {\n        $this->only = Arr::wrap($only);\n\n        return $this;\n    }\n\n    /**\n     * Specify the controller methods the middleware should not apply to.\n     *\n     * @param  array|string  $except\n     * @return $this\n     */\n    public function except(array|string $except)\n    {\n        $this->except = Arr::wrap($except);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/CreatesRegularExpressionRouteConstraints.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait CreatesRegularExpressionRouteConstraints\n{\n    /**\n     * Specify that the given route parameters must be alphabetic.\n     *\n     * @param  array|string  $parameters\n     * @return $this\n     */\n    public function whereAlpha($parameters)\n    {\n        return $this->assignExpressionToParameters($parameters, '[a-zA-Z]+');\n    }\n\n    /**\n     * Specify that the given route parameters must be alphanumeric.\n     *\n     * @param  array|string  $parameters\n     * @return $this\n     */\n    public function whereAlphaNumeric($parameters)\n    {\n        return $this->assignExpressionToParameters($parameters, '[a-zA-Z0-9]+');\n    }\n\n    /**\n     * Specify that the given route parameters must be numeric.\n     *\n     * @param  array|string  $parameters\n     * @return $this\n     */\n    public function whereNumber($parameters)\n    {\n        return $this->assignExpressionToParameters($parameters, '[0-9]+');\n    }\n\n    /**\n     * Specify that the given route parameters must be ULIDs.\n     *\n     * @param  array|string  $parameters\n     * @return $this\n     */\n    public function whereUlid($parameters)\n    {\n        return $this->assignExpressionToParameters($parameters, '[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}');\n    }\n\n    /**\n     * Specify that the given route parameters must be UUIDs.\n     *\n     * @param  array|string  $parameters\n     * @return $this\n     */\n    public function whereUuid($parameters)\n    {\n        return $this->assignExpressionToParameters($parameters, '[\\da-fA-F]{8}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{12}');\n    }\n\n    /**\n     * Specify that the given route parameters must be one of the given values.\n     *\n     * @param  array|string  $parameters\n     * @param  array  $values\n     * @return $this\n     */\n    public function whereIn($parameters, array $values)\n    {\n        return $this->assignExpressionToParameters(\n            $parameters,\n            (new Collection($values))\n                ->map(fn ($value) => enum_value($value))\n                ->implode('|')\n        );\n    }\n\n    /**\n     * Apply the given regular expression to the given parameters.\n     *\n     * @param  array|string  $parameters\n     * @param  string  $expression\n     * @return $this\n     */\n    protected function assignExpressionToParameters($parameters, $expression)\n    {\n        return $this->where(Collection::wrap($parameters)\n            ->mapWithKeys(fn ($parameter) => [$parameter => $expression])\n            ->all());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Events/PreparingResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Events;\n\nclass PreparingResponse\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request  The request instance.\n     * @param  mixed  $response  The response instance.\n     */\n    public function __construct(\n        public $request,\n        public $response,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Events/ResponsePrepared.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Events;\n\nclass ResponsePrepared\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request  The request instance.\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response  The response instance.\n     */\n    public function __construct(\n        public $request,\n        public $response,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Events/RouteMatched.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Events;\n\nclass RouteMatched\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route  The route instance.\n     * @param  \\Illuminate\\Http\\Request  $request  The request instance.\n     */\n    public function __construct(\n        public $route,\n        public $request,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Events/Routing.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Events;\n\nclass Routing\n{\n    /**\n     * Create a new event instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request  The request instance.\n     */\n    public function __construct(\n        public $request,\n    ) {\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Exceptions/BackedEnumCaseNotFoundException.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Exceptions;\n\nuse RuntimeException;\n\nclass BackedEnumCaseNotFoundException extends RuntimeException\n{\n    /**\n     * Create a new exception instance.\n     *\n     * @param  string  $backedEnumClass\n     * @param  string  $case\n     */\n    public function __construct($backedEnumClass, $case)\n    {\n        parent::__construct(\"Case [{$case}] not found on Backed Enum [{$backedEnumClass}].\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Exceptions/InvalidSignatureException.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Exceptions;\n\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass InvalidSignatureException extends HttpException\n{\n    /**\n     * Create a new exception instance.\n     */\n    public function __construct()\n    {\n        parent::__construct(403, 'Invalid signature.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Exceptions/MissingRateLimiterException.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Exceptions;\n\nuse Exception;\n\nclass MissingRateLimiterException extends Exception\n{\n    /**\n     * Create a new exception for invalid named rate limiter.\n     *\n     * @param  string  $limiter\n     * @return static\n     */\n    public static function forLimiter(string $limiter)\n    {\n        return new static(\"Rate limiter [{$limiter}] is not defined.\");\n    }\n\n    /**\n     * Create a new exception for an invalid rate limiter based on a model property.\n     *\n     * @param  string  $limiter\n     * @param  class-string  $model\n     * @return static\n     */\n    public static function forLimiterAndUser(string $limiter, string $model)\n    {\n        return new static(\"Rate limiter [{$model}::{$limiter}] is not defined.\");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Exceptions/StreamedResponseException.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Exceptions;\n\nuse Illuminate\\Http\\Response;\nuse RuntimeException;\nuse Throwable;\n\nclass StreamedResponseException extends RuntimeException\n{\n    /**\n     * The actual exception thrown during the stream.\n     *\n     * @var \\Throwable\n     */\n    public $originalException;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  \\Throwable  $originalException\n     */\n    public function __construct(Throwable $originalException)\n    {\n        $this->originalException = $originalException;\n\n        parent::__construct($originalException->getMessage());\n    }\n\n    /**\n     * Render the exception.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function render()\n    {\n        return new Response('');\n    }\n\n    /**\n     * Get the actual exception thrown during the stream.\n     *\n     * @return \\Throwable\n     */\n    public function getInnerException()\n    {\n        return $this->originalException;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Exceptions/UrlGenerationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Exceptions;\n\nuse Exception;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Support\\Str;\n\nclass UrlGenerationException extends Exception\n{\n    /**\n     * Create a new exception for missing route parameters.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $parameters\n     * @return static\n     */\n    public static function forMissingParameters(Route $route, array $parameters = [])\n    {\n        $parameterLabel = Str::plural('parameter', count($parameters));\n\n        $message = sprintf(\n            'Missing required %s for [Route: %s] [URI: %s]',\n            $parameterLabel,\n            $route->getName(),\n            $route->uri()\n        );\n\n        if (count($parameters) > 0) {\n            $message .= sprintf(' [Missing %s: %s]', $parameterLabel, implode(', ', $parameters));\n        }\n\n        $message .= '.';\n\n        return new static($message);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/FiltersControllerMiddleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\ntrait FiltersControllerMiddleware\n{\n    /**\n     * Determine if the given options exclude a particular method.\n     *\n     * @param  string  $method\n     * @param  array  $options\n     * @return bool\n     */\n    public static function methodExcludedByOptions($method, array $options)\n    {\n        return (isset($options['only']) && ! in_array($method, (array) $options['only'])) ||\n               (! empty($options['except']) && in_array($method, (array) $options['except']));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ImplicitRouteBinding.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Str;\n\nclass ImplicitRouteBinding\n{\n    /**\n     * Resolve the implicit route bindings for the given route.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<\\Illuminate\\Database\\Eloquent\\Model>\n     * @throws \\Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException\n     */\n    public static function resolveForRoute($container, $route)\n    {\n        $parameters = $route->parameters();\n\n        $route = static::resolveBackedEnumsForRoute($route, $parameters);\n\n        foreach ($route->signatureParameters(['subClass' => UrlRoutable::class]) as $parameter) {\n            if (! $parameterName = static::getParameterName($parameter->getName(), $parameters)) {\n                continue;\n            }\n\n            $parameterValue = $parameters[$parameterName];\n\n            if ($parameterValue instanceof UrlRoutable) {\n                continue;\n            }\n\n            $instance = $container->make(Reflector::getParameterClassName($parameter));\n\n            $parent = $route->parentOfParameter($parameterName);\n\n            $routeBindingMethod = $route->allowsTrashedBindings() && $instance::isSoftDeletable()\n                ? 'resolveSoftDeletableRouteBinding'\n                : 'resolveRouteBinding';\n\n            if ($parent instanceof UrlRoutable &&\n                ! $route->preventsScopedBindings() &&\n                ($route->enforcesScopedBindings() || array_key_exists($parameterName, $route->bindingFields()))) {\n                $childRouteBindingMethod = $route->allowsTrashedBindings() && $instance::isSoftDeletable()\n                    ? 'resolveSoftDeletableChildRouteBinding'\n                    : 'resolveChildRouteBinding';\n\n                if (! $model = $parent->{$childRouteBindingMethod}(\n                    $parameterName, $parameterValue, $route->bindingFieldFor($parameterName)\n                )) {\n                    throw (new ModelNotFoundException)->setModel(get_class($instance), [$parameterValue]);\n                }\n            } elseif (! $model = $instance->{$routeBindingMethod}($parameterValue, $route->bindingFieldFor($parameterName))) {\n                throw (new ModelNotFoundException)->setModel(get_class($instance), [$parameterValue]);\n            }\n\n            $route->setParameter($parameterName, $model);\n        }\n    }\n\n    /**\n     * Resolve the Backed Enums route bindings for the route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $parameters\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException\n     */\n    protected static function resolveBackedEnumsForRoute($route, $parameters)\n    {\n        foreach ($route->signatureParameters(['backedEnum' => true]) as $parameter) {\n            if (! $parameterName = static::getParameterName($parameter->getName(), $parameters)) {\n                continue;\n            }\n\n            $parameterValue = $parameters[$parameterName];\n\n            if ($parameterValue === null) {\n                continue;\n            }\n\n            $backedEnumClass = $parameter->getType()?->getName();\n\n            $backedEnum = $parameterValue instanceof $backedEnumClass\n                ? $parameterValue\n                : $backedEnumClass::tryFrom((string) $parameterValue);\n\n            if (is_null($backedEnum)) {\n                throw new BackedEnumCaseNotFoundException($backedEnumClass, $parameterValue);\n            }\n\n            $route->setParameter($parameterName, $backedEnum);\n        }\n\n        return $route;\n    }\n\n    /**\n     * Return the parameter name if it exists in the given parameters.\n     *\n     * @param  string  $name\n     * @param  array  $parameters\n     * @return string|null\n     */\n    protected static function getParameterName($name, $parameters)\n    {\n        if (array_key_exists($name, $parameters)) {\n            return $name;\n        }\n\n        if (array_key_exists($snakedName = Str::snake($name), $parameters)) {\n            return $snakedName;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Routing/Matching/HostValidator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Matching;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\n\nclass HostValidator implements ValidatorInterface\n{\n    /**\n     * Validate a given rule against a route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function matches(Route $route, Request $request)\n    {\n        $hostRegex = $route->getCompiled()->getHostRegex();\n\n        if (is_null($hostRegex)) {\n            return true;\n        }\n\n        return preg_match($hostRegex, $request->getHost());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Matching/MethodValidator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Matching;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\n\nclass MethodValidator implements ValidatorInterface\n{\n    /**\n     * Validate a given rule against a route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function matches(Route $route, Request $request)\n    {\n        return in_array($request->getMethod(), $route->methods());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Matching/SchemeValidator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Matching;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\n\nclass SchemeValidator implements ValidatorInterface\n{\n    /**\n     * Validate a given rule against a route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function matches(Route $route, Request $request)\n    {\n        if ($route->httpOnly()) {\n            return ! $request->secure();\n        } elseif ($route->secure()) {\n            return $request->secure();\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Matching/UriValidator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Matching;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\n\nclass UriValidator implements ValidatorInterface\n{\n    /**\n     * Validate a given rule against a route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function matches(Route $route, Request $request)\n    {\n        $path = rtrim($request->getPathInfo(), '/') ?: '/';\n\n        return preg_match($route->getCompiled()->getRegex(), rawurldecode($path));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Matching/ValidatorInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Matching;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\n\ninterface ValidatorInterface\n{\n    /**\n     * Validate a given rule against a route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function matches(Route $route, Request $request);\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Middleware/SubstituteBindings.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\n\nclass SubstituteBindings\n{\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Contracts\\Routing\\Registrar\n     */\n    protected $router;\n\n    /**\n     * Create a new bindings substitutor.\n     *\n     * @param  \\Illuminate\\Contracts\\Routing\\Registrar  $router\n     */\n    public function __construct(Registrar $router)\n    {\n        $this->router = $router;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException\n     */\n    public function handle($request, Closure $next)\n    {\n        $route = $request->route();\n\n        try {\n            $this->router->substituteBindings($route);\n            $this->router->substituteImplicitBindings($route);\n        } catch (ModelNotFoundException $exception) {\n            if ($route->getMissing()) {\n                return $route->getMissing()($request, $exception);\n            }\n\n            throw $exception;\n        }\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Middleware/ThrottleRequests.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Middleware;\n\nuse Closure;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Unlimited;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\Exceptions\\ThrottleRequestsException;\nuse Illuminate\\Routing\\Exceptions\\MissingRateLimiterException;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass ThrottleRequests\n{\n    use InteractsWithTime;\n\n    /**\n     * The rate limiter instance.\n     *\n     * @var \\Illuminate\\Cache\\RateLimiter\n     */\n    protected $limiter;\n\n    /**\n     * Indicates if the rate limiter keys should be hashed.\n     *\n     * @var bool\n     */\n    protected static $shouldHashKeys = true;\n\n    /**\n     * Create a new request throttler.\n     *\n     * @param  \\Illuminate\\Cache\\RateLimiter  $limiter\n     */\n    public function __construct(RateLimiter $limiter)\n    {\n        $this->limiter = $limiter;\n    }\n\n    /**\n     * Specify the named rate limiter to use for the middleware.\n     *\n     * @param  \\UnitEnum|string  $name\n     * @return string\n     */\n    public static function using($name)\n    {\n        return static::class.':'.enum_value($name);\n    }\n\n    /**\n     * Specify the rate limiter configuration for the middleware.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $decayMinutes\n     * @param  string  $prefix\n     * @return string\n     *\n     * @named-arguments-supported\n     */\n    public static function with($maxAttempts = 60, $decayMinutes = 1, $prefix = '')\n    {\n        return static::class.':'.implode(',', func_get_args());\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  int|string  $maxAttempts\n     * @param  float|int  $decayMinutes\n     * @param  string  $prefix\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\ThrottleRequestsException\n     * @throws \\Illuminate\\Routing\\Exceptions\\MissingRateLimiterException\n     */\n    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1, $prefix = '')\n    {\n        if (is_string($maxAttempts)\n            && func_num_args() === 3\n            && ! is_null($limiter = $this->limiter->limiter($maxAttempts))) {\n            return $this->handleRequestUsingNamedLimiter($request, $next, $maxAttempts, $limiter);\n        }\n\n        return $this->handleRequest(\n            $request,\n            $next,\n            [\n                (object) [\n                    'key' => $prefix.$this->resolveRequestSignature($request),\n                    'maxAttempts' => $this->resolveMaxAttempts($request, $maxAttempts),\n                    'decaySeconds' => 60 * $decayMinutes,\n                    'afterCallback' => null,\n                    'responseCallback' => null,\n                ],\n            ]\n        );\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  string  $limiterName\n     * @param  \\Closure  $limiter\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\ThrottleRequestsException\n     */\n    protected function handleRequestUsingNamedLimiter($request, Closure $next, $limiterName, Closure $limiter)\n    {\n        $limiterResponse = $limiter($request);\n\n        if ($limiterResponse instanceof Response) {\n            return $limiterResponse;\n        } elseif ($limiterResponse instanceof Unlimited) {\n            return $next($request);\n        }\n\n        return $this->handleRequest(\n            $request,\n            $next,\n            Collection::wrap($limiterResponse)->map(function ($limit) use ($limiterName) {\n                return (object) [\n                    'key' => self::$shouldHashKeys ? md5($limiterName.$limit->key) : $limiterName.':'.$limit->key,\n                    'maxAttempts' => $limit->maxAttempts,\n                    'decaySeconds' => $limit->decaySeconds,\n                    'afterCallback' => $limit->afterCallback,\n                    'responseCallback' => $limit->responseCallback,\n                ];\n            })->all()\n        );\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  array  $limits\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\ThrottleRequestsException\n     */\n    protected function handleRequest($request, Closure $next, array $limits)\n    {\n        foreach ($limits as $limit) {\n            if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {\n                throw $this->buildException($request, $limit->key, $limit->maxAttempts, $limit->responseCallback);\n            }\n        }\n\n        foreach ($limits as $limit) {\n            if (! $limit->afterCallback) {\n                $this->limiter->hit($limit->key, $limit->decaySeconds);\n            }\n        }\n\n        $response = $next($request);\n\n        foreach ($limits as $limit) {\n            if ($limit->afterCallback && ($limit->afterCallback)($response)) {\n                $this->limiter->hit($limit->key, $limit->decaySeconds);\n            }\n\n            $response = $this->addHeaders(\n                $response,\n                $limit->maxAttempts,\n                $this->calculateRemainingAttempts($limit->key, $limit->maxAttempts)\n            );\n        }\n\n        return $response;\n    }\n\n    /**\n     * Resolve the number of attempts if the user is authenticated or not.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  int|string  $maxAttempts\n     * @return int\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\MissingRateLimiterException\n     */\n    protected function resolveMaxAttempts($request, $maxAttempts)\n    {\n        if (str_contains($maxAttempts, '|')) {\n            $maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0];\n        }\n\n        if (! is_numeric($maxAttempts) &&\n            $request->user()?->hasAttribute($maxAttempts)\n        ) {\n            $maxAttempts = $request->user()->{$maxAttempts};\n        }\n\n        // If we still don't have a numeric value, there was no matching rate limiter...\n        if (! is_numeric($maxAttempts)) {\n            is_null($request->user())\n                ? throw MissingRateLimiterException::forLimiter($maxAttempts)\n                : throw MissingRateLimiterException::forLimiterAndUser($maxAttempts, get_class($request->user()));\n        }\n\n        return (int) $maxAttempts;\n    }\n\n    /**\n     * Resolve request signature.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function resolveRequestSignature($request)\n    {\n        if ($user = $request->user()) {\n            return $this->formatIdentifier($user->getAuthIdentifier());\n        } elseif ($route = $request->route()) {\n            return $this->formatIdentifier($route->getDomain().'|'.$request->ip());\n        }\n\n        throw new RuntimeException('Unable to generate the request signature. Route unavailable.');\n    }\n\n    /**\n     * Create a 'too many attempts' exception.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  callable|null  $responseCallback\n     * @return \\Illuminate\\Http\\Exceptions\\ThrottleRequestsException|\\Illuminate\\Http\\Exceptions\\HttpResponseException\n     */\n    protected function buildException($request, $key, $maxAttempts, $responseCallback = null)\n    {\n        $retryAfter = $this->getTimeUntilNextRetry($key);\n\n        $headers = $this->getHeaders(\n            $maxAttempts,\n            $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter),\n            $retryAfter\n        );\n\n        return is_callable($responseCallback)\n            ? new HttpResponseException($responseCallback($request, $headers))\n            : new ThrottleRequestsException('Too Many Attempts.', null, $headers);\n    }\n\n    /**\n     * Get the number of seconds until the next retry.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getTimeUntilNextRetry($key)\n    {\n        return $this->limiter->availableIn($key);\n    }\n\n    /**\n     * Add the limit header information to the given response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @param  int  $maxAttempts\n     * @param  int  $remainingAttempts\n     * @param  int|null  $retryAfter\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function addHeaders(Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null)\n    {\n        $response->headers->add(\n            $this->getHeaders($maxAttempts, $remainingAttempts, $retryAfter, $response)\n        );\n\n        return $response;\n    }\n\n    /**\n     * Get the limit headers information.\n     *\n     * @param  int  $maxAttempts\n     * @param  int  $remainingAttempts\n     * @param  int|null  $retryAfter\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response|null  $response\n     * @return array\n     */\n    protected function getHeaders($maxAttempts,\n        $remainingAttempts,\n        $retryAfter = null,\n        ?Response $response = null)\n    {\n        if ($response &&\n            ! is_null($response->headers->get('X-RateLimit-Remaining')) &&\n            (int) $response->headers->get('X-RateLimit-Remaining') <= (int) $remainingAttempts) {\n            return [];\n        }\n\n        $headers = [\n            'X-RateLimit-Limit' => $maxAttempts,\n            'X-RateLimit-Remaining' => $remainingAttempts,\n        ];\n\n        if (! is_null($retryAfter)) {\n            $headers['Retry-After'] = $retryAfter;\n            $headers['X-RateLimit-Reset'] = $this->availableAt($retryAfter);\n        }\n\n        return $headers;\n    }\n\n    /**\n     * Calculate the number of remaining attempts.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  int|null  $retryAfter\n     * @return int\n     */\n    protected function calculateRemainingAttempts($key, $maxAttempts, $retryAfter = null)\n    {\n        return is_null($retryAfter) ? $this->limiter->retriesLeft($key, $maxAttempts) : 0;\n    }\n\n    /**\n     * Format the given identifier based on the configured hashing settings.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    private function formatIdentifier($value)\n    {\n        return self::$shouldHashKeys ? sha1($value) : $value;\n    }\n\n    /**\n     * Specify whether rate limiter keys should be hashed.\n     *\n     * @param  bool  $shouldHashKeys\n     * @return void\n     */\n    public static function shouldHashKeys(bool $shouldHashKeys = true)\n    {\n        self::$shouldHashKeys = $shouldHashKeys;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Middleware;\n\nuse Closure;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Contracts\\Redis\\Factory as Redis;\nuse Illuminate\\Redis\\Limiters\\DurationLimiter;\n\nclass ThrottleRequestsWithRedis extends ThrottleRequests\n{\n    /**\n     * The Redis factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Redis\\Factory\n     */\n    protected $redis;\n\n    /**\n     * The timestamp of the end of the current duration by key.\n     *\n     * @var array\n     */\n    public $decaysAt = [];\n\n    /**\n     * The number of remaining slots by key.\n     *\n     * @var array\n     */\n    public $remaining = [];\n\n    /**\n     * Create a new request throttler.\n     *\n     * @param  \\Illuminate\\Cache\\RateLimiter  $limiter\n     * @param  \\Illuminate\\Contracts\\Redis\\Factory  $redis\n     */\n    public function __construct(RateLimiter $limiter, Redis $redis)\n    {\n        parent::__construct($limiter);\n\n        $this->redis = $redis;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  array  $limits\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     *\n     * @throws \\Illuminate\\Http\\Exceptions\\ThrottleRequestsException\n     */\n    protected function handleRequest($request, Closure $next, array $limits)\n    {\n        foreach ($limits as $limit) {\n            if ($this->tooManyAttempts($limit->key, $limit->maxAttempts, $limit->decaySeconds)) {\n                throw $this->buildException($request, $limit->key, $limit->maxAttempts, $limit->responseCallback);\n            }\n\n            if (! $limit->afterCallback) {\n                $this->hit($limit->key, $limit->maxAttempts, $limit->decaySeconds);\n            }\n        }\n\n        $response = $next($request);\n\n        foreach ($limits as $limit) {\n            if ($limit->afterCallback && ($limit->afterCallback)($response)) {\n                $this->hit($limit->key, $limit->maxAttempts, $limit->decaySeconds);\n            }\n\n            $response = $this->addHeaders(\n                $response,\n                $limit->maxAttempts,\n                $this->calculateRemainingAttempts($limit->key, $limit->maxAttempts)\n            );\n        }\n\n        return $response;\n    }\n\n    /**\n     * Determine if the given key has been \"accessed\" too many times.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     * @return bool\n     */\n    protected function tooManyAttempts($key, $maxAttempts, $decaySeconds)\n    {\n        $limiter = new DurationLimiter(\n            $this->getRedisConnection(), $key, $maxAttempts, $decaySeconds\n        );\n\n        return tap($limiter->tooManyAttempts(), function () use ($key, $limiter) {\n            [$this->decaysAt[$key], $this->remaining[$key]] = [\n                $limiter->decaysAt, $limiter->remaining,\n            ];\n        });\n    }\n\n    /**\n     * Increment the counter for the given key.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  int  $decaySeconds\n     * @return void\n     */\n    protected function hit($key, $maxAttempts, $decaySeconds)\n    {\n        $limiter = new DurationLimiter(\n            $this->getRedisConnection(), $key, $maxAttempts, $decaySeconds\n        );\n\n        $limiter->acquire();\n\n        [$this->decaysAt[$key], $this->remaining[$key]] = [\n            $limiter->decaysAt, $limiter->remaining,\n        ];\n    }\n\n    /**\n     * Calculate the number of remaining attempts.\n     *\n     * @param  string  $key\n     * @param  int  $maxAttempts\n     * @param  int|null  $retryAfter\n     * @return int\n     */\n    protected function calculateRemainingAttempts($key, $maxAttempts, $retryAfter = null)\n    {\n        return is_null($retryAfter) ? $this->remaining[$key] : 0;\n    }\n\n    /**\n     * Get the number of seconds until the lock is released.\n     *\n     * @param  string  $key\n     * @return int\n     */\n    protected function getTimeUntilNextRetry($key)\n    {\n        return $this->decaysAt[$key] - $this->currentTime();\n    }\n\n    /**\n     * Get the Redis connection that should be used for throttling.\n     *\n     * @return \\Illuminate\\Redis\\Connections\\Connection\n     */\n    protected function getRedisConnection()\n    {\n        return $this->redis->connection();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Middleware/ValidateSignature.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing\\Middleware;\n\nuse Closure;\nuse Illuminate\\Routing\\Exceptions\\InvalidSignatureException;\nuse Illuminate\\Support\\Arr;\n\nclass ValidateSignature\n{\n    /**\n     * The names of the parameters that should be ignored.\n     *\n     * @var array<int, string>\n     */\n    protected $ignore = [\n        //\n    ];\n\n    /**\n     * The globally ignored parameters.\n     *\n     * @var array\n     */\n    protected static $neverValidate = [];\n\n    /**\n     * Specify that the URL signature is for a relative URL.\n     *\n     * @param  array|string  $ignore\n     * @return string\n     */\n    public static function relative($ignore = [])\n    {\n        $ignore = Arr::wrap($ignore);\n\n        return static::class.':'.implode(',', empty($ignore) ? ['relative'] : ['relative',  ...$ignore]);\n    }\n\n    /**\n     * Specify that the URL signature is for an absolute URL.\n     *\n     * @param  array|string  $ignore\n     * @return class-string\n     */\n    public static function absolute($ignore = [])\n    {\n        $ignore = Arr::wrap($ignore);\n\n        return empty($ignore)\n            ? static::class\n            : static::class.':'.implode(',', $ignore);\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @param  array|null  $args\n     * @return \\Illuminate\\Http\\Response\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\InvalidSignatureException\n     */\n    public function handle($request, Closure $next, ...$args)\n    {\n        [$relative, $ignore] = $this->parseArguments($args);\n\n        if ($request->hasValidSignatureWhileIgnoring($ignore, ! $relative)) {\n            return $next($request);\n        }\n\n        throw new InvalidSignatureException;\n    }\n\n    /**\n     * Parse the additional arguments given to the middleware.\n     *\n     * @param  array  $args\n     * @return array\n     */\n    protected function parseArguments(array $args)\n    {\n        $relative = ! empty($args) && $args[0] === 'relative';\n\n        if ($relative) {\n            array_shift($args);\n        }\n\n        $ignore = array_merge(\n            property_exists($this, 'except') ? $this->except : $this->ignore,\n            $args\n        );\n\n        return [$relative, array_merge($ignore, static::$neverValidate)];\n    }\n\n    /**\n     * Indicate that the given parameters should be ignored during signature validation.\n     *\n     * @param  array|string  $parameters\n     * @return void\n     */\n    public static function except($parameters)\n    {\n        static::$neverValidate = array_values(array_unique(\n            array_merge(static::$neverValidate, Arr::wrap($parameters))\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/MiddlewareNameResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Closure;\n\nclass MiddlewareNameResolver\n{\n    /**\n     * Resolve the middleware name to a class name(s) preserving passed parameters.\n     *\n     * @param  \\Closure|string  $name\n     * @param  array  $map\n     * @param  array  $middlewareGroups\n     * @return \\Closure|string|array\n     */\n    public static function resolve($name, $map, $middlewareGroups)\n    {\n        // When the middleware is simply a Closure, we will return this Closure instance\n        // directly so that Closures can be registered as middleware inline, which is\n        // convenient on occasions when the developers are experimenting with them.\n        if ($name instanceof Closure) {\n            return $name;\n        }\n\n        if (isset($map[$name]) && $map[$name] instanceof Closure) {\n            return $map[$name];\n        }\n\n        // If the middleware is the name of a middleware group, we will return the array\n        // of middlewares that belong to the group. This allows developers to group a\n        // set of middleware under single keys that can be conveniently referenced.\n        if (isset($middlewareGroups[$name])) {\n            return static::parseMiddlewareGroup($name, $map, $middlewareGroups);\n        }\n\n        // Finally, when the middleware is simply a string mapped to a class name the\n        // middleware name will get parsed into the full class name and parameters\n        // which may be run using the Pipeline which accepts this string format.\n        [$name, $parameters] = array_pad(explode(':', $name, 2), 2, null);\n\n        return ($map[$name] ?? $name).(! is_null($parameters) ? ':'.$parameters : '');\n    }\n\n    /**\n     * Parse the middleware group and format it for usage.\n     *\n     * @param  string  $name\n     * @param  array  $map\n     * @param  array  $middlewareGroups\n     * @return array\n     */\n    protected static function parseMiddlewareGroup($name, $map, $middlewareGroups)\n    {\n        $results = [];\n\n        foreach ($middlewareGroups[$name] as $middleware) {\n            // If the middleware is another middleware group we will pull in the group and\n            // merge its middleware into the results. This allows groups to conveniently\n            // reference other groups without needing to repeat all their middlewares.\n            if (isset($middlewareGroups[$middleware])) {\n                $results = array_merge($results, static::parseMiddlewareGroup(\n                    $middleware, $map, $middlewareGroups\n                ));\n\n                continue;\n            }\n\n            [$middleware, $parameters] = array_pad(\n                explode(':', $middleware, 2), 2, null\n            );\n\n            // If this middleware is actually a route middleware, we will extract the full\n            // class name out of the middleware list now. Then we'll add the parameters\n            // back onto this class' name so the pipeline will properly extract them.\n            if (isset($map[$middleware])) {\n                $middleware = $map[$middleware];\n            }\n\n            $results[] = $middleware.($parameters ? ':'.$parameters : '');\n        }\n\n        return $results;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/PendingResourceRegistration.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass PendingResourceRegistration\n{\n    use CreatesRegularExpressionRouteConstraints, Macroable;\n\n    /**\n     * The resource registrar.\n     *\n     * @var \\Illuminate\\Routing\\ResourceRegistrar\n     */\n    protected $registrar;\n\n    /**\n     * The resource name.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The resource controller.\n     *\n     * @var string\n     */\n    protected $controller;\n\n    /**\n     * The resource options.\n     *\n     * @var array\n     */\n    protected $options = [];\n\n    /**\n     * The resource's registration status.\n     *\n     * @var bool\n     */\n    protected $registered = false;\n\n    /**\n     * Create a new pending resource registration instance.\n     *\n     * @param  \\Illuminate\\Routing\\ResourceRegistrar  $registrar\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     */\n    public function __construct(ResourceRegistrar $registrar, $name, $controller, array $options)\n    {\n        $this->name = $name;\n        $this->options = $options;\n        $this->registrar = $registrar;\n        $this->controller = $controller;\n    }\n\n    /**\n     * Set the methods the controller should apply to.\n     *\n     * @param  mixed  $methods\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function only($methods)\n    {\n        $this->options['only'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Set the methods the controller should exclude.\n     *\n     * @param  mixed  $methods\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function except($methods)\n    {\n        $this->options['except'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Set the route names for controller actions.\n     *\n     * @param  array|string  $names\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function names($names)\n    {\n        $this->options['names'] = $names;\n\n        return $this;\n    }\n\n    /**\n     * Set the route name for a controller action.\n     *\n     * @param  string  $method\n     * @param  string  $name\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function name($method, $name)\n    {\n        $this->options['names'][$method] = $name;\n\n        return $this;\n    }\n\n    /**\n     * Override the route parameter names.\n     *\n     * @param  array|string  $parameters\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function parameters($parameters)\n    {\n        $this->options['parameters'] = $parameters;\n\n        return $this;\n    }\n\n    /**\n     * Override a route parameter's name.\n     *\n     * @param  string  $previous\n     * @param  string  $new\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function parameter($previous, $new)\n    {\n        $this->options['parameters'][$previous] = $new;\n\n        return $this;\n    }\n\n    /**\n     * Add middleware to the resource routes.\n     *\n     * @param  mixed  $middleware\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function middleware($middleware)\n    {\n        $middleware = Arr::wrap($middleware);\n\n        foreach ($middleware as $key => $value) {\n            $middleware[$key] = (string) $value;\n        }\n\n        $this->options['middleware'] = $middleware;\n\n        if (isset($this->options['middleware_for'])) {\n            foreach ($this->options['middleware_for'] as $method => $value) {\n                $this->options['middleware_for'][$method] = Router::uniqueMiddleware(array_merge(\n                    Arr::wrap($value),\n                    $middleware\n                ));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be added to the specified resource routes.\n     *\n     * @param  array|string  $methods\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function middlewareFor($methods, $middleware)\n    {\n        $methods = Arr::wrap($methods);\n        $middleware = Arr::wrap($middleware);\n\n        if (isset($this->options['middleware'])) {\n            $middleware = Router::uniqueMiddleware(array_merge(\n                $this->options['middleware'],\n                $middleware\n            ));\n        }\n\n        foreach ($methods as $method) {\n            $this->options['middleware_for'][$method] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be removed from the resource routes.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function withoutMiddleware($middleware)\n    {\n        $this->options['excluded_middleware'] = array_merge(\n            (array) ($this->options['excluded_middleware'] ?? []), Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be removed from the specified resource routes.\n     *\n     * @param  array|string  $methods\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function withoutMiddlewareFor($methods, $middleware)\n    {\n        $methods = Arr::wrap($methods);\n        $middleware = Arr::wrap($middleware);\n\n        foreach ($methods as $method) {\n            $this->options['excluded_middleware_for'][$method] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add \"where\" constraints to the resource routes.\n     *\n     * @param  mixed  $wheres\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function where($wheres)\n    {\n        $this->options['wheres'] = $wheres;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the resource routes should have \"shallow\" nesting.\n     *\n     * @param  bool  $shallow\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function shallow($shallow = true)\n    {\n        $this->options['shallow'] = $shallow;\n\n        return $this;\n    }\n\n    /**\n     * Define the callable that should be invoked on a missing model exception.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function missing($callback)\n    {\n        $this->options['missing'] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the resource routes should be scoped using the given binding fields.\n     *\n     * @param  array  $fields\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function scoped(array $fields = [])\n    {\n        $this->options['bindingFields'] = $fields;\n\n        return $this;\n    }\n\n    /**\n     * Define which routes should allow \"trashed\" models to be retrieved when resolving implicit model bindings.\n     *\n     * @param  array  $methods\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function withTrashed(array $methods = [])\n    {\n        $this->options['trashed'] = $methods;\n\n        return $this;\n    }\n\n    /**\n     * Register the resource route.\n     *\n     * @return \\Illuminate\\Routing\\RouteCollection\n     */\n    public function register()\n    {\n        $this->registered = true;\n\n        return $this->registrar->register(\n            $this->name, $this->controller, $this->options\n        );\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        if (! $this->registered) {\n            $this->register();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/PendingSingletonResourceRegistration.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass PendingSingletonResourceRegistration\n{\n    use CreatesRegularExpressionRouteConstraints, Macroable;\n\n    /**\n     * The resource registrar.\n     *\n     * @var \\Illuminate\\Routing\\ResourceRegistrar\n     */\n    protected $registrar;\n\n    /**\n     * The resource name.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The resource controller.\n     *\n     * @var string\n     */\n    protected $controller;\n\n    /**\n     * The resource options.\n     *\n     * @var array\n     */\n    protected $options = [];\n\n    /**\n     * The resource's registration status.\n     *\n     * @var bool\n     */\n    protected $registered = false;\n\n    /**\n     * Create a new pending singleton resource registration instance.\n     *\n     * @param  \\Illuminate\\Routing\\ResourceRegistrar  $registrar\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     */\n    public function __construct(ResourceRegistrar $registrar, $name, $controller, array $options)\n    {\n        $this->name = $name;\n        $this->options = $options;\n        $this->registrar = $registrar;\n        $this->controller = $controller;\n    }\n\n    /**\n     * Set the methods the controller should apply to.\n     *\n     * @param  mixed  $methods\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function only($methods)\n    {\n        $this->options['only'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Set the methods the controller should exclude.\n     *\n     * @param  mixed  $methods\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function except($methods)\n    {\n        $this->options['except'] = is_array($methods) ? $methods : func_get_args();\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the resource should have creation and storage routes.\n     *\n     * @return $this\n     */\n    public function creatable()\n    {\n        $this->options['creatable'] = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the resource should have a deletion route.\n     *\n     * @return $this\n     */\n    public function destroyable()\n    {\n        $this->options['destroyable'] = true;\n\n        return $this;\n    }\n\n    /**\n     * Set the route names for controller actions.\n     *\n     * @param  array|string  $names\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function names($names)\n    {\n        $this->options['names'] = $names;\n\n        return $this;\n    }\n\n    /**\n     * Set the route name for a controller action.\n     *\n     * @param  string  $method\n     * @param  string  $name\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function name($method, $name)\n    {\n        $this->options['names'][$method] = $name;\n\n        return $this;\n    }\n\n    /**\n     * Override the route parameter names.\n     *\n     * @param  array|string  $parameters\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function parameters($parameters)\n    {\n        $this->options['parameters'] = $parameters;\n\n        return $this;\n    }\n\n    /**\n     * Override a route parameter's name.\n     *\n     * @param  string  $previous\n     * @param  string  $new\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function parameter($previous, $new)\n    {\n        $this->options['parameters'][$previous] = $new;\n\n        return $this;\n    }\n\n    /**\n     * Add middleware to the resource routes.\n     *\n     * @param  mixed  $middleware\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function middleware($middleware)\n    {\n        $middleware = Arr::wrap($middleware);\n\n        foreach ($middleware as $key => $value) {\n            $middleware[$key] = (string) $value;\n        }\n\n        $this->options['middleware'] = $middleware;\n\n        if (isset($this->options['middleware_for'])) {\n            foreach ($this->options['middleware_for'] as $method => $value) {\n                $this->options['middleware_for'][$method] = Router::uniqueMiddleware(array_merge(\n                    Arr::wrap($value),\n                    $middleware\n                ));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be added to the specified resource routes.\n     *\n     * @param  array|string  $methods\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function middlewareFor($methods, $middleware)\n    {\n        $methods = Arr::wrap($methods);\n        $middleware = Arr::wrap($middleware);\n\n        if (isset($this->options['middleware'])) {\n            $middleware = Router::uniqueMiddleware(array_merge(\n                $this->options['middleware'],\n                $middleware\n            ));\n        }\n\n        foreach ($methods as $method) {\n            $this->options['middleware_for'][$method] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be removed from the resource routes.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function withoutMiddleware($middleware)\n    {\n        $this->options['excluded_middleware'] = array_merge(\n            (array) ($this->options['excluded_middleware'] ?? []), Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify middleware that should be removed from the specified resource routes.\n     *\n     * @param  array|string  $methods\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function withoutMiddlewareFor($methods, $middleware)\n    {\n        $methods = Arr::wrap($methods);\n        $middleware = Arr::wrap($middleware);\n\n        foreach ($methods as $method) {\n            $this->options['excluded_middleware_for'][$method] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add \"where\" constraints to the resource routes.\n     *\n     * @param  mixed  $wheres\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function where($wheres)\n    {\n        $this->options['wheres'] = $wheres;\n\n        return $this;\n    }\n\n    /**\n     * Register the singleton resource route.\n     *\n     * @return \\Illuminate\\Routing\\RouteCollection\n     */\n    public function register()\n    {\n        $this->registered = true;\n\n        return $this->registrar->singleton(\n            $this->name, $this->controller, $this->options\n        );\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        if (! $this->registered) {\n            $this->register();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Pipeline.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Pipeline\\Pipeline as BasePipeline;\nuse Throwable;\n\n/**\n * This extended pipeline catches any exceptions that occur during each slice.\n *\n * The exceptions are converted to HTTP responses for proper middleware handling.\n */\nclass Pipeline extends BasePipeline\n{\n    /**\n     * Handles the value returned from each pipe before passing it to the next.\n     *\n     * @param  mixed  $carry\n     * @return mixed\n     */\n    protected function handleCarry($carry)\n    {\n        return $carry instanceof Responsable\n            ? $carry->toResponse($this->getContainer()->make(Request::class))\n            : $carry;\n    }\n\n    /**\n     * Handle the given exception.\n     *\n     * @param  mixed  $passable\n     * @param  \\Throwable  $e\n     * @return mixed\n     *\n     * @throws \\Throwable\n     */\n    protected function handleException($passable, Throwable $e)\n    {\n        if (! $this->container->bound(ExceptionHandler::class) ||\n            ! $passable instanceof Request) {\n            throw $e;\n        }\n\n        $handler = $this->container->make(ExceptionHandler::class);\n\n        $handler->report($e);\n\n        $response = $handler->render($passable, $e);\n\n        if (is_object($response) && method_exists($response, 'withException')) {\n            $response->withException($e);\n        }\n\n        return $this->handleCarry($response);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RedirectController.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\n\nclass RedirectController extends Controller\n{\n    /**\n     * Invoke the controller method.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Routing\\UrlGenerator  $url\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function __invoke(Request $request, UrlGenerator $url)\n    {\n        $parameters = new Collection($request->route()->parameters());\n\n        $status = $parameters->get('status');\n\n        $destination = $parameters->get('destination');\n\n        $parameters->forget('status')->forget('destination');\n\n        $route = (new Route('GET', $destination, [\n            'as' => 'laravel_route_redirect_destination',\n        ]))->bind($request);\n\n        $parameters = $parameters->only(\n            $route->getCompiled()->getPathVariables()\n        )->all();\n\n        $url = $url->toRoute($route, $parameters, false);\n\n        if (! str_starts_with($destination, '/') && str_starts_with($url, '/')) {\n            $url = Str::after($url, '/');\n        }\n\n        return new RedirectResponse($url, $status);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Redirector.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Session\\Store as SessionStore;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass Redirector\n{\n    use Macroable;\n\n    /**\n     * The URL generator instance.\n     *\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    protected $generator;\n\n    /**\n     * The session store instance.\n     *\n     * @var \\Illuminate\\Session\\Store\n     */\n    protected $session;\n\n    /**\n     * Create a new Redirector instance.\n     *\n     * @param  \\Illuminate\\Routing\\UrlGenerator  $generator\n     */\n    public function __construct(UrlGenerator $generator)\n    {\n        $this->generator = $generator;\n    }\n\n    /**\n     * Create a new redirect response to the previous location.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  mixed  $fallback\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function back($status = 302, $headers = [], $fallback = false)\n    {\n        return $this->createRedirect($this->generator->previous($fallback), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to the current URI.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function refresh($status = 302, $headers = [])\n    {\n        return $this->to($this->generator->getRequest()->path(), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response, while putting the current URL in the session.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function guest($path, $status = 302, $headers = [], $secure = null)\n    {\n        $request = $this->generator->getRequest();\n\n        $intended = $request->isMethod('GET') && $request->route() && ! $request->expectsJson()\n            ? $this->generator->full()\n            : $this->generator->previous();\n\n        if ($intended) {\n            $this->setIntendedUrl($intended);\n        }\n\n        return $this->to($path, $status, $headers, $secure);\n    }\n\n    /**\n     * Create a new redirect response to the previously intended location.\n     *\n     * @param  mixed  $default\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function intended($default = '/', $status = 302, $headers = [], $secure = null)\n    {\n        $path = $this->session->pull('url.intended', $default);\n\n        return $this->to($path, $status, $headers, $secure);\n    }\n\n    /**\n     * Create a new redirect response to the given path.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function to($path, $status = 302, $headers = [], $secure = null)\n    {\n        return $this->createRedirect($this->generator->to($path, [], $secure), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to an external URL (no validation).\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function away($path, $status = 302, $headers = [])\n    {\n        return $this->createRedirect($path, $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to the given HTTPS path.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function secure($path, $status = 302, $headers = [])\n    {\n        return $this->to($path, $status, $headers, true);\n    }\n\n    /**\n     * Create a new redirect response to a named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function route($route, $parameters = [], $status = 302, $headers = [])\n    {\n        return $this->to($this->generator->route($route, $parameters), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to a signed named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  mixed  $parameters\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $expiration\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function signedRoute($route, $parameters = [], $expiration = null, $status = 302, $headers = [])\n    {\n        return $this->to($this->generator->signedRoute($route, $parameters, $expiration), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to a signed named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $expiration\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function temporarySignedRoute($route, $expiration, $parameters = [], $status = 302, $headers = [])\n    {\n        return $this->to($this->generator->temporarySignedRoute($route, $expiration, $parameters), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to a controller action.\n     *\n     * @param  string|array  $action\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function action($action, $parameters = [], $status = 302, $headers = [])\n    {\n        return $this->to($this->generator->action($action, $parameters), $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    protected function createRedirect($path, $status, $headers)\n    {\n        return tap(new RedirectResponse($path, $status, $headers), function ($redirect) {\n            if (isset($this->session)) {\n                $redirect->setSession($this->session);\n            }\n\n            $redirect->setRequest($this->generator->getRequest());\n        });\n    }\n\n    /**\n     * Get the URL generator instance.\n     *\n     * @return \\Illuminate\\Routing\\UrlGenerator\n     */\n    public function getUrlGenerator()\n    {\n        return $this->generator;\n    }\n\n    /**\n     * Set the active session store.\n     *\n     * @param  \\Illuminate\\Session\\Store  $session\n     * @return void\n     */\n    public function setSession(SessionStore $session)\n    {\n        $this->session = $session;\n    }\n\n    /**\n     * Get the \"intended\" URL from the session.\n     *\n     * @return string|null\n     */\n    public function getIntendedUrl()\n    {\n        return $this->session->get('url.intended');\n    }\n\n    /**\n     * Set the \"intended\" URL in the session.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function setIntendedUrl($url)\n    {\n        $this->session->put('url.intended', $url);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ResolvesRouteDependencies.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Container\\Util;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Reflector;\nuse ReflectionClass;\nuse ReflectionFunctionAbstract;\nuse ReflectionMethod;\nuse ReflectionParameter;\nuse stdClass;\n\ntrait ResolvesRouteDependencies\n{\n    /**\n     * Resolve the object method's type-hinted dependencies.\n     *\n     * @param  array  $parameters\n     * @param  object  $instance\n     * @param  string  $method\n     * @return array\n     */\n    protected function resolveClassMethodDependencies(array $parameters, $instance, $method)\n    {\n        if (! method_exists($instance, $method)) {\n            return $parameters;\n        }\n\n        return $this->resolveMethodDependencies(\n            $parameters, new ReflectionMethod($instance, $method)\n        );\n    }\n\n    /**\n     * Resolve the given method's type-hinted dependencies.\n     *\n     * @param  array  $parameters\n     * @param  \\ReflectionFunctionAbstract  $reflector\n     * @return array\n     */\n    public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)\n    {\n        $instanceCount = 0;\n\n        $values = array_values($parameters);\n\n        $skippableValue = new stdClass;\n\n        foreach ($reflector->getParameters() as $key => $parameter) {\n            $instance = $this->transformDependency($parameter, $parameters, $skippableValue);\n\n            if ($instance !== $skippableValue) {\n                $instanceCount++;\n\n                $this->spliceIntoParameters($parameters, $key, $instance);\n            } elseif (! isset($values[$key - $instanceCount]) &&\n                      $parameter->isDefaultValueAvailable()) {\n                $this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue());\n            }\n\n            $this->container->fireAfterResolvingAttributeCallbacks($parameter->getAttributes(), $instance);\n        }\n\n        return $parameters;\n    }\n\n    /**\n     * Attempt to transform the given parameter into a class instance.\n     *\n     * @param  \\ReflectionParameter  $parameter\n     * @param  array  $parameters\n     * @param  object  $skippableValue\n     * @return mixed\n     */\n    protected function transformDependency(ReflectionParameter $parameter, $parameters, $skippableValue)\n    {\n        if ($attribute = Util::getContextualAttributeFromDependency($parameter)) {\n            return $this->container->resolveFromAttribute($attribute);\n        }\n\n        $className = Reflector::getParameterClassName($parameter);\n\n        // If the parameter has a type-hinted class, we will check to see if it is already in\n        // the list of parameters. If it is we will just skip it as it is probably a model\n        // binding and we do not want to mess with those; otherwise, we resolve it here.\n        if ($className && ! $this->alreadyInParameters($className, $parameters)) {\n            $isEnum = (new ReflectionClass($className))->isEnum();\n\n            return $parameter->isDefaultValueAvailable()\n                ? ($isEnum ? $parameter->getDefaultValue() : null)\n                : $this->container->make($className);\n        }\n\n        return $skippableValue;\n    }\n\n    /**\n     * Determine if an object of the given class is in a list of parameters.\n     *\n     * @param  string  $class\n     * @param  array  $parameters\n     * @return bool\n     */\n    protected function alreadyInParameters($class, array $parameters)\n    {\n        return ! is_null(Arr::first($parameters, fn ($value) => $value instanceof $class));\n    }\n\n    /**\n     * Splice the given value into the parameter list.\n     *\n     * @param  array  $parameters\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    protected function spliceIntoParameters(array &$parameters, $offset, $value)\n    {\n        array_splice(\n            $parameters, $offset, 0, [$value]\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ResourceRegistrar.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Str;\n\nclass ResourceRegistrar\n{\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The default actions for a resourceful controller.\n     *\n     * @var string[]\n     */\n    protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];\n\n    /**\n     * The default actions for a singleton resource controller.\n     *\n     * @var string[]\n     */\n    protected $singletonResourceDefaults = ['show', 'edit', 'update'];\n\n    /**\n     * The parameters set for this resource instance.\n     *\n     * @var array|string\n     */\n    protected $parameters;\n\n    /**\n     * The global parameter mapping.\n     *\n     * @var array\n     */\n    protected static $parameterMap = [];\n\n    /**\n     * Singular global parameters.\n     *\n     * @var bool\n     */\n    protected static $singularParameters = true;\n\n    /**\n     * The verbs used in the resource URIs.\n     *\n     * @var array\n     */\n    protected static $verbs = [\n        'create' => 'create',\n        'edit' => 'edit',\n    ];\n\n    /**\n     * Create a new resource registrar instance.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     */\n    public function __construct(Router $router)\n    {\n        $this->router = $router;\n    }\n\n    /**\n     * Route a resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\RouteCollection\n     */\n    public function register($name, $controller, array $options = [])\n    {\n        if (isset($options['parameters']) && ! isset($this->parameters)) {\n            $this->parameters = $options['parameters'];\n        }\n\n        // If the resource name contains a slash, we will assume the developer wishes to\n        // register these resource routes with a prefix so we will set that up out of\n        // the box so they don't have to mess with it. Otherwise, we will continue.\n        if (str_contains($name, '/')) {\n            $this->prefixedResource($name, $controller, $options);\n\n            return;\n        }\n\n        // We need to extract the base resource from the resource name. Nested resources\n        // are supported in the framework, but we need to know what name to use for a\n        // place-holder on the route parameters, which should be the base resources.\n        $base = $this->getResourceWildcard(last(explode('.', $name)));\n\n        $defaults = $this->resourceDefaults;\n\n        $collection = new RouteCollection;\n\n        $resourceMethods = $this->getResourceMethods($defaults, $options);\n\n        foreach ($resourceMethods as $m) {\n            $optionsForMethod = $options;\n\n            if (isset($optionsForMethod['middleware_for'][$m])) {\n                $optionsForMethod['middleware'] = $optionsForMethod['middleware_for'][$m];\n            }\n\n            if (isset($optionsForMethod['excluded_middleware_for'][$m])) {\n                $optionsForMethod['excluded_middleware'] = Router::uniqueMiddleware(array_merge(\n                    $optionsForMethod['excluded_middleware'] ?? [],\n                    $optionsForMethod['excluded_middleware_for'][$m]\n                ));\n            }\n\n            $route = $this->{'addResource'.ucfirst($m)}(\n                $name, $base, $controller, $optionsForMethod\n            );\n\n            if (isset($options['bindingFields'])) {\n                $this->setResourceBindingFields($route, $options['bindingFields']);\n            }\n\n            if (isset($options['trashed']) &&\n                in_array($m, ! empty($options['trashed']) ? $options['trashed'] : array_intersect($resourceMethods, ['show', 'edit', 'update']))) {\n                $route->withTrashed();\n            }\n\n            $collection->add($route);\n        }\n\n        return $collection;\n    }\n\n    /**\n     * Route a singleton resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\RouteCollection\n     */\n    public function singleton($name, $controller, array $options = [])\n    {\n        if (isset($options['parameters']) && ! isset($this->parameters)) {\n            $this->parameters = $options['parameters'];\n        }\n\n        // If the resource name contains a slash, we will assume the developer wishes to\n        // register these singleton routes with a prefix so we will set that up out of\n        // the box so they don't have to mess with it. Otherwise, we will continue.\n        if (str_contains($name, '/')) {\n            $this->prefixedSingleton($name, $controller, $options);\n\n            return;\n        }\n\n        $defaults = $this->singletonResourceDefaults;\n\n        if (isset($options['creatable'])) {\n            $defaults = array_merge($defaults, ['create', 'store', 'destroy']);\n        } elseif (isset($options['destroyable'])) {\n            $defaults = array_merge($defaults, ['destroy']);\n        }\n\n        $collection = new RouteCollection;\n\n        $resourceMethods = $this->getResourceMethods($defaults, $options);\n\n        foreach ($resourceMethods as $m) {\n            $optionsForMethod = $options;\n\n            if (isset($optionsForMethod['middleware_for'][$m])) {\n                $optionsForMethod['middleware'] = $optionsForMethod['middleware_for'][$m];\n            }\n\n            if (isset($optionsForMethod['excluded_middleware_for'][$m])) {\n                $optionsForMethod['excluded_middleware'] = Router::uniqueMiddleware(array_merge(\n                    $optionsForMethod['excluded_middleware'] ?? [],\n                    $optionsForMethod['excluded_middleware_for'][$m]\n                ));\n            }\n\n            $route = $this->{'addSingleton'.ucfirst($m)}(\n                $name, $controller, $optionsForMethod\n            );\n\n            if (isset($options['bindingFields'])) {\n                $this->setResourceBindingFields($route, $options['bindingFields']);\n            }\n\n            $collection->add($route);\n        }\n\n        return $collection;\n    }\n\n    /**\n     * Build a set of prefixed resource routes.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Router\n     */\n    protected function prefixedResource($name, $controller, array $options)\n    {\n        [$name, $prefix] = $this->getResourcePrefix($name);\n\n        // We need to extract the base resource from the resource name. Nested resources\n        // are supported in the framework, but we need to know what name to use for a\n        // place-holder on the route parameters, which should be the base resources.\n        $callback = function ($me) use ($name, $controller, $options) {\n            $me->resource($name, $controller, $options);\n        };\n\n        return $this->router->group(compact('prefix'), $callback);\n    }\n\n    /**\n     * Build a set of prefixed singleton routes.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Router\n     */\n    protected function prefixedSingleton($name, $controller, array $options)\n    {\n        [$name, $prefix] = $this->getResourcePrefix($name);\n\n        // We need to extract the base resource from the resource name. Nested resources\n        // are supported in the framework, but we need to know what name to use for a\n        // place-holder on the route parameters, which should be the base resources.\n        $callback = function ($me) use ($name, $controller, $options) {\n            $me->singleton($name, $controller, $options);\n        };\n\n        return $this->router->group(compact('prefix'), $callback);\n    }\n\n    /**\n     * Extract the resource and prefix from a resource name.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    protected function getResourcePrefix($name)\n    {\n        $segments = explode('/', $name);\n\n        // To get the prefix, we will take all of the name segments and implode them on\n        // a slash. This will generate a proper URI prefix for us. Then we take this\n        // last segment, which will be considered the final resources name we use.\n        $prefix = implode('/', array_slice($segments, 0, -1));\n\n        return [end($segments), $prefix];\n    }\n\n    /**\n     * Get the applicable resource methods.\n     *\n     * @param  array  $defaults\n     * @param  array  $options\n     * @return array\n     */\n    protected function getResourceMethods($defaults, $options)\n    {\n        $methods = $defaults;\n\n        if (isset($options['only'])) {\n            $methods = array_intersect($methods, (array) $options['only']);\n        }\n\n        if (isset($options['except'])) {\n            $methods = array_diff($methods, (array) $options['except']);\n        }\n\n        return array_values($methods);\n    }\n\n    /**\n     * Add the index method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceIndex($name, $base, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name);\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'index', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the create method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceCreate($name, $base, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name).'/'.static::$verbs['create'];\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'create', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the store method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceStore($name, $base, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name);\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'store', $options);\n\n        return $this->router->post($uri, $action);\n    }\n\n    /**\n     * Add the show method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceShow($name, $base, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name).'/{'.$base.'}';\n\n        $action = $this->getResourceAction($name, $controller, 'show', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the edit method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceEdit($name, $base, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name).'/{'.$base.'}/'.static::$verbs['edit'];\n\n        $action = $this->getResourceAction($name, $controller, 'edit', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the update method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceUpdate($name, $base, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name).'/{'.$base.'}';\n\n        $action = $this->getResourceAction($name, $controller, 'update', $options);\n\n        return $this->router->match(['PUT', 'PATCH'], $uri, $action);\n    }\n\n    /**\n     * Add the destroy method for a resourceful route.\n     *\n     * @param  string  $name\n     * @param  string  $base\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addResourceDestroy($name, $base, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name).'/{'.$base.'}';\n\n        $action = $this->getResourceAction($name, $controller, 'destroy', $options);\n\n        return $this->router->delete($uri, $action);\n    }\n\n    /**\n     * Add the create method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonCreate($name, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name).'/'.static::$verbs['create'];\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'create', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the store method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonStore($name, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name);\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'store', $options);\n\n        return $this->router->post($uri, $action);\n    }\n\n    /**\n     * Add the show method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonShow($name, $controller, $options)\n    {\n        $uri = $this->getResourceUri($name);\n\n        unset($options['missing']);\n\n        $action = $this->getResourceAction($name, $controller, 'show', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the edit method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonEdit($name, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name).'/'.static::$verbs['edit'];\n\n        $action = $this->getResourceAction($name, $controller, 'edit', $options);\n\n        return $this->router->get($uri, $action);\n    }\n\n    /**\n     * Add the update method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonUpdate($name, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name);\n\n        $action = $this->getResourceAction($name, $controller, 'update', $options);\n\n        return $this->router->match(['PUT', 'PATCH'], $uri, $action);\n    }\n\n    /**\n     * Add the destroy method for a singleton route.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addSingletonDestroy($name, $controller, $options)\n    {\n        $name = $this->getShallowName($name, $options);\n\n        $uri = $this->getResourceUri($name);\n\n        $action = $this->getResourceAction($name, $controller, 'destroy', $options);\n\n        return $this->router->delete($uri, $action);\n    }\n\n    /**\n     * Get the name for a given resource with shallowness applied when applicable.\n     *\n     * @param  string  $name\n     * @param  array  $options\n     * @return string\n     */\n    protected function getShallowName($name, $options)\n    {\n        return isset($options['shallow']) && $options['shallow']\n            ? last(explode('.', $name))\n            : $name;\n    }\n\n    /**\n     * Set the route's binding fields if the resource is scoped.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $bindingFields\n     * @return void\n     */\n    protected function setResourceBindingFields($route, $bindingFields)\n    {\n        preg_match_all('/(?<={).*?(?=})/', $route->uri, $matches);\n\n        $fields = array_fill_keys($matches[0], null);\n\n        $route->setBindingFields(array_replace(\n            $fields, array_intersect_key($bindingFields, $fields)\n        ));\n    }\n\n    /**\n     * Get the base resource URI for a given resource.\n     *\n     * @param  string  $resource\n     * @return string\n     */\n    public function getResourceUri($resource)\n    {\n        if (! str_contains($resource, '.')) {\n            return $resource;\n        }\n\n        // Once we have built the base URI, we'll remove the parameter holder for this\n        // base resource name so that the individual route adders can suffix these\n        // paths however they need to, as some do not have any parameters at all.\n        $segments = explode('.', $resource);\n\n        $uri = $this->getNestedResourceUri($segments);\n\n        return str_replace('/{'.$this->getResourceWildcard(end($segments)).'}', '', $uri);\n    }\n\n    /**\n     * Get the URI for a nested resource segment array.\n     *\n     * @param  array  $segments\n     * @return string\n     */\n    protected function getNestedResourceUri(array $segments)\n    {\n        // We will spin through the segments and create a place-holder for each of the\n        // resource segments, as well as the resource itself. Then we should get an\n        // entire string for the resource URI that contains all nested resources.\n        return implode('/', array_map(function ($s) {\n            return $s.'/{'.$this->getResourceWildcard($s).'}';\n        }, $segments));\n    }\n\n    /**\n     * Format a resource parameter for usage.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function getResourceWildcard($value)\n    {\n        if (isset($this->parameters[$value])) {\n            $value = $this->parameters[$value];\n        } elseif (isset(static::$parameterMap[$value])) {\n            $value = static::$parameterMap[$value];\n        } elseif ($this->parameters === 'singular' || static::$singularParameters) {\n            $value = Str::singular($value);\n        }\n\n        return str_replace('-', '_', $value);\n    }\n\n    /**\n     * Get the action array for a resource route.\n     *\n     * @param  string  $resource\n     * @param  string  $controller\n     * @param  string  $method\n     * @param  array  $options\n     * @return array\n     */\n    protected function getResourceAction($resource, $controller, $method, $options)\n    {\n        $name = $this->getResourceRouteName($resource, $method, $options);\n\n        $action = ['as' => $name, 'uses' => $controller.'@'.$method];\n\n        if (isset($options['middleware'])) {\n            $action['middleware'] = $options['middleware'];\n        }\n\n        if (isset($options['excluded_middleware'])) {\n            $action['excluded_middleware'] = $options['excluded_middleware'];\n        }\n\n        if (isset($options['wheres'])) {\n            $action['where'] = $options['wheres'];\n        }\n\n        if (isset($options['missing'])) {\n            $action['missing'] = $options['missing'];\n        }\n\n        return $action;\n    }\n\n    /**\n     * Get the name for a given resource.\n     *\n     * @param  string  $resource\n     * @param  string  $method\n     * @param  array  $options\n     * @return string\n     */\n    protected function getResourceRouteName($resource, $method, $options)\n    {\n        $name = $resource;\n\n        // If the names array has been provided to us we will check for an entry in the\n        // array first. We will also check for the specific method within this array\n        // so the names may be specified on a more \"granular\" level using methods.\n        if (isset($options['names'])) {\n            if (is_string($options['names'])) {\n                $name = $options['names'];\n            } elseif (isset($options['names'][$method])) {\n                return $options['names'][$method];\n            }\n        }\n\n        // If a global prefix has been assigned to all names for this resource, we will\n        // grab that so we can prepend it onto the name when we create this name for\n        // the resource action. Otherwise we'll just use an empty string for here.\n        $prefix = isset($options['as']) ? $options['as'].'.' : '';\n\n        return trim(sprintf('%s%s.%s', $prefix, $name, $method), '.');\n    }\n\n    /**\n     * Set or unset the unmapped global parameters to singular.\n     *\n     * @param  bool  $singular\n     * @return void\n     */\n    public static function singularParameters($singular = true)\n    {\n        static::$singularParameters = (bool) $singular;\n    }\n\n    /**\n     * Get the global parameter map.\n     *\n     * @return array\n     */\n    public static function getParameters()\n    {\n        return static::$parameterMap;\n    }\n\n    /**\n     * Set the global parameter mapping.\n     *\n     * @param  array  $parameters\n     * @return void\n     */\n    public static function setParameters(array $parameters = [])\n    {\n        static::$parameterMap = $parameters;\n    }\n\n    /**\n     * Get or set the action verbs used in the resource URIs.\n     *\n     * @param  array  $verbs\n     * @return array\n     */\n    public static function verbs(array $verbs = [])\n    {\n        if (empty($verbs)) {\n            return static::$verbs;\n        }\n\n        static::$verbs = array_merge(static::$verbs, $verbs);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ResponseFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory as FactoryContract;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Http\\StreamedEvent;\nuse Illuminate\\Routing\\Exceptions\\StreamedResponseException;\nuse Illuminate\\Support\\Js;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse ReflectionFunction;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedJsonResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\nuse Throwable;\n\nclass ResponseFactory implements FactoryContract\n{\n    use Macroable;\n\n    /**\n     * The view factory instance.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $view;\n\n    /**\n     * The redirector instance.\n     *\n     * @var \\Illuminate\\Routing\\Redirector\n     */\n    protected $redirector;\n\n    /**\n     * Create a new response factory instance.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $view\n     * @param  \\Illuminate\\Routing\\Redirector  $redirector\n     */\n    public function __construct(ViewFactory $view, Redirector $redirector)\n    {\n        $this->view = $view;\n        $this->redirector = $redirector;\n    }\n\n    /**\n     * Create a new response instance.\n     *\n     * @param  mixed  $content\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function make($content = '', $status = 200, array $headers = [])\n    {\n        return new Response($content, $status, $headers);\n    }\n\n    /**\n     * Create a new \"no content\" response.\n     *\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function noContent($status = 204, array $headers = [])\n    {\n        return $this->make('', $status, $headers);\n    }\n\n    /**\n     * Create a new response for a given view.\n     *\n     * @param  string|array  $view\n     * @param  array  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function view($view, $data = [], $status = 200, array $headers = [])\n    {\n        if (is_array($view)) {\n            return $this->make($this->view->first($view, $data), $status, $headers);\n        }\n\n        return $this->make($this->view->make($view, $data), $status, $headers);\n    }\n\n    /**\n     * Create a new JSON response instance.\n     *\n     * @param  mixed  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function json($data = [], $status = 200, array $headers = [], $options = 0)\n    {\n        return new JsonResponse($data, $status, $headers, $options);\n    }\n\n    /**\n     * Create a new JSONP response instance.\n     *\n     * @param  string  $callback\n     * @param  mixed  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $options\n     * @return \\Illuminate\\Http\\JsonResponse\n     */\n    public function jsonp($callback, $data = [], $status = 200, array $headers = [], $options = 0)\n    {\n        return $this->json($data, $status, $headers, $options)->setCallback($callback);\n    }\n\n    /**\n     * Create a new event stream response.\n     *\n     * @param  \\Closure  $callback\n     * @param  array  $headers\n     * @param  \\Illuminate\\Http\\StreamedEvent|string|null  $endStreamWith\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function eventStream(Closure $callback, array $headers = [], StreamedEvent|string|null $endStreamWith = '</stream>')\n    {\n        return $this->stream(function () use ($callback, $endStreamWith) {\n            foreach ($callback() as $message) {\n                if (connection_aborted()) {\n                    break;\n                }\n\n                $event = 'update';\n\n                if ($message instanceof StreamedEvent) {\n                    $event = $message->event;\n                    $message = $message->data;\n                }\n\n                if (! is_string($message) && ! is_numeric($message)) {\n                    $message = Js::encode($message);\n                }\n\n                echo \"event: $event\\n\";\n                echo 'data: '.$message;\n                echo \"\\n\\n\";\n\n                if (ob_get_level() > 0) {\n                    ob_flush();\n                }\n\n                flush();\n            }\n\n            if (filled($endStreamWith)) {\n                $endEvent = 'update';\n\n                if ($endStreamWith instanceof StreamedEvent) {\n                    $endEvent = $endStreamWith->event;\n                    $endStreamWith = $endStreamWith->data;\n                }\n\n                echo \"event: $endEvent\\n\";\n                echo 'data: '.$endStreamWith;\n                echo \"\\n\\n\";\n\n                if (ob_get_level() > 0) {\n                    ob_flush();\n                }\n\n                flush();\n            }\n        }, 200, array_merge($headers, [\n            'Content-Type' => 'text/event-stream',\n            'Cache-Control' => 'no-cache',\n            'X-Accel-Buffering' => 'no',\n        ]));\n    }\n\n    /**\n     * Create a new streamed response instance.\n     *\n     * @param  callable|null  $callback\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     */\n    public function stream($callback, $status = 200, array $headers = [])\n    {\n        if (! is_null($callback) && (new ReflectionFunction($callback))->isGenerator()) {\n            if (isset($_SERVER['LARAVEL_OCTANE'])) {\n                return (new StreamedResponse(\n                    null, $status, array_merge($headers, ['X-Accel-Buffering' => 'no'])\n                ))->setCallback($callback);\n            }\n\n            return new StreamedResponse(function () use ($callback) {\n                foreach ($callback() as $chunk) {\n                    echo $chunk;\n                    when(ob_get_level() > 0, fn () => ob_flush());\n                    flush();\n                }\n            }, $status, array_merge($headers, ['X-Accel-Buffering' => 'no']));\n        }\n\n        return new StreamedResponse($callback, $status, $headers);\n    }\n\n    /**\n     * Create a new streamed JSON response instance.\n     *\n     * @param  array  $data\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  int  $encodingOptions\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedJsonResponse\n     */\n    public function streamJson($data, $status = 200, $headers = [], $encodingOptions = JsonResponse::DEFAULT_ENCODING_OPTIONS)\n    {\n        return new StreamedJsonResponse($data, $status, $headers, $encodingOptions);\n    }\n\n    /**\n     * Create a new streamed response instance as a file download.\n     *\n     * @param  callable  $callback\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @param  string|null  $disposition\n     * @return \\Symfony\\Component\\HttpFoundation\\StreamedResponse\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\StreamedResponseException\n     */\n    public function streamDownload($callback, $name = null, array $headers = [], $disposition = 'attachment')\n    {\n        $withWrappedException = function () use ($callback) {\n            try {\n                $callback();\n            } catch (Throwable $e) {\n                throw new StreamedResponseException($e);\n            }\n        };\n\n        $response = new StreamedResponse($withWrappedException, 200, $headers);\n\n        if (! is_null($name)) {\n            $response->headers->set('Content-Disposition', $response->headers->makeDisposition(\n                $disposition,\n                $name,\n                $this->fallbackName($name)\n            ));\n        }\n\n        return $response;\n    }\n\n    /**\n     * Create a new file download response.\n     *\n     * @param  \\SplFileInfo|string  $file\n     * @param  string|null  $name\n     * @param  array  $headers\n     * @param  string|null  $disposition\n     * @return \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse\n     */\n    public function download($file, $name = null, array $headers = [], $disposition = 'attachment')\n    {\n        $response = new BinaryFileResponse($file, 200, $headers, true, $disposition);\n\n        if (! is_null($name)) {\n            return $response->setContentDisposition($disposition, $name, $this->fallbackName($name));\n        }\n\n        return $response;\n    }\n\n    /**\n     * Convert the string to ASCII characters that are equivalent to the given name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function fallbackName($name)\n    {\n        return str_replace('%', '', Str::ascii($name));\n    }\n\n    /**\n     * Return the raw contents of a binary file.\n     *\n     * @param  \\SplFileInfo|string  $file\n     * @param  array  $headers\n     * @return \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse\n     */\n    public function file($file, array $headers = [])\n    {\n        return new BinaryFileResponse($file, 200, $headers);\n    }\n\n    /**\n     * Create a new redirect response to the given path.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectTo($path, $status = 302, $headers = [], $secure = null)\n    {\n        return $this->redirector->to($path, $status, $headers, $secure);\n    }\n\n    /**\n     * Create a new redirect response to a named route.\n     *\n     * @param  \\BackedEnum|string  $route\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToRoute($route, $parameters = [], $status = 302, $headers = [])\n    {\n        return $this->redirector->route($route, $parameters, $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response to a controller action.\n     *\n     * @param  array|string  $action\n     * @param  mixed  $parameters\n     * @param  int  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToAction($action, $parameters = [], $status = 302, $headers = [])\n    {\n        return $this->redirector->action($action, $parameters, $status, $headers);\n    }\n\n    /**\n     * Create a new redirect response, while putting the current URL in the session.\n     *\n     * @param  string  $path\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectGuest($path, $status = 302, $headers = [], $secure = null)\n    {\n        return $this->redirector->guest($path, $status, $headers, $secure);\n    }\n\n    /**\n     * Create a new redirect response to the previously intended location.\n     *\n     * @param  string  $default\n     * @param  int  $status\n     * @param  array  $headers\n     * @param  bool|null  $secure\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    public function redirectToIntended($default = '/', $status = 302, $headers = [], $secure = null)\n    {\n        return $this->redirector->intended($default, $status, $headers, $secure);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Route.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse BackedEnum;\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Attributes\\Controllers\\Middleware as MiddlewareAttribute;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\nuse Illuminate\\Routing\\Controllers\\HasMiddleware;\nuse Illuminate\\Routing\\Controllers\\Middleware;\nuse Illuminate\\Routing\\Matching\\HostValidator;\nuse Illuminate\\Routing\\Matching\\MethodValidator;\nuse Illuminate\\Routing\\Matching\\SchemeValidator;\nuse Illuminate\\Routing\\Matching\\UriValidator;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse LogicException;\nuse ReflectionAttribute;\nuse ReflectionClass;\nuse ReflectionException;\nuse Symfony\\Component\\Routing\\Route as SymfonyRoute;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Route\n{\n    use Conditionable, CreatesRegularExpressionRouteConstraints, FiltersControllerMiddleware, Macroable, ResolvesRouteDependencies;\n\n    /**\n     * The URI pattern the route responds to.\n     *\n     * @var string\n     */\n    public $uri;\n\n    /**\n     * The HTTP methods the route responds to.\n     *\n     * @var array\n     */\n    public $methods;\n\n    /**\n     * The route action array.\n     *\n     * @var array\n     */\n    public $action;\n\n    /**\n     * Indicates whether the route is a fallback route.\n     *\n     * @var bool\n     */\n    public $isFallback = false;\n\n    /**\n     * The controller instance.\n     *\n     * @var mixed\n     */\n    public $controller;\n\n    /**\n     * The default values for the route.\n     *\n     * @var array\n     */\n    public $defaults = [];\n\n    /**\n     * The regular expression requirements.\n     *\n     * @var array\n     */\n    public $wheres = [];\n\n    /**\n     * The array of matched parameters.\n     *\n     * @var array|null\n     */\n    public $parameters;\n\n    /**\n     * The parameter names for the route.\n     *\n     * @var array|null\n     */\n    public $parameterNames;\n\n    /**\n     * The array of the matched parameters' original values.\n     *\n     * @var array\n     */\n    protected $originalParameters;\n\n    /**\n     * Indicates \"trashed\" models can be retrieved when resolving implicit model bindings for this route.\n     *\n     * @var bool\n     */\n    protected $withTrashedBindings = false;\n\n    /**\n     * Indicates the maximum number of seconds the route should acquire a session lock for.\n     *\n     * @var int|null\n     */\n    protected $lockSeconds;\n\n    /**\n     * Indicates the maximum number of seconds the route should wait while attempting to acquire a session lock.\n     *\n     * @var int|null\n     */\n    protected $waitSeconds;\n\n    /**\n     * The computed gathered middleware.\n     *\n     * @var array|null\n     */\n    public $computedMiddleware;\n\n    /**\n     * The compiled version of the route.\n     *\n     * @var \\Symfony\\Component\\Routing\\CompiledRoute\n     */\n    public $compiled;\n\n    /**\n     * The router instance used by the route.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The container instance used by the route.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The fields that implicit binding should use for a given parameter.\n     *\n     * @var array\n     */\n    protected $bindingFields = [];\n\n    /**\n     * The validators used by the routes.\n     *\n     * @var array\n     */\n    public static $validators;\n\n    /**\n     * Create a new Route instance.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  \\Closure|array  $action\n     */\n    public function __construct($methods, $uri, $action)\n    {\n        $this->uri = $uri;\n        $this->methods = (array) $methods;\n        $this->action = Arr::except($this->parseAction($action), ['prefix']);\n\n        if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {\n            $this->methods[] = 'HEAD';\n        }\n\n        $this->prefix(is_array($action) ? Arr::get($action, 'prefix') : '');\n    }\n\n    /**\n     * Parse the route action into a standard array.\n     *\n     * @param  callable|array|null  $action\n     * @return array\n     *\n     * @throws \\UnexpectedValueException\n     */\n    protected function parseAction($action)\n    {\n        return RouteAction::parse($this->uri, $action);\n    }\n\n    /**\n     * Run the route action and return the response.\n     *\n     * @return mixed\n     */\n    public function run()\n    {\n        $this->container = $this->container ?: new Container;\n\n        try {\n            if ($this->isControllerAction()) {\n                return $this->runController();\n            }\n\n            return $this->runCallable();\n        } catch (HttpResponseException $e) {\n            return $e->getResponse();\n        }\n    }\n\n    /**\n     * Checks whether the route's action is a controller.\n     *\n     * @return bool\n     */\n    protected function isControllerAction()\n    {\n        return is_string($this->action['uses']) && ! $this->isSerializedClosure();\n    }\n\n    /**\n     * Run the route action and return the response.\n     *\n     * @return mixed\n     */\n    protected function runCallable()\n    {\n        $callable = $this->action['uses'];\n\n        if ($this->isSerializedClosure()) {\n            $callable = unserialize($this->action['uses'])->getClosure();\n        }\n\n        return $this->container[CallableDispatcher::class]->dispatch($this, $callable);\n    }\n\n    /**\n     * Determine if the route action is a serialized Closure.\n     *\n     * @return bool\n     */\n    protected function isSerializedClosure()\n    {\n        return RouteAction::containsSerializedClosure($this->action);\n    }\n\n    /**\n     * Run the route action and return the response.\n     *\n     * @return mixed\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    protected function runController()\n    {\n        return $this->controllerDispatcher()->dispatch(\n            $this, $this->getController(), $this->getControllerMethod()\n        );\n    }\n\n    /**\n     * Get the controller instance for the route.\n     *\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function getController()\n    {\n        if (! $this->isControllerAction()) {\n            return null;\n        }\n\n        if (! $this->controller) {\n            $class = $this->getControllerClass();\n\n            $this->controller = $this->container->make(ltrim($class, '\\\\'));\n        }\n\n        return $this->controller;\n    }\n\n    /**\n     * Get the controller class used for the route.\n     *\n     * @return string|null\n     */\n    public function getControllerClass()\n    {\n        return $this->isControllerAction() ? $this->parseControllerCallback()[0] : null;\n    }\n\n    /**\n     * Get the controller method used for the route.\n     *\n     * @return string\n     */\n    protected function getControllerMethod()\n    {\n        return $this->parseControllerCallback()[1];\n    }\n\n    /**\n     * Parse the controller.\n     *\n     * @return array\n     */\n    protected function parseControllerCallback()\n    {\n        return Str::parseCallback($this->action['uses']);\n    }\n\n    /**\n     * Flush the cached container instance on the route.\n     *\n     * @return void\n     */\n    public function flushController()\n    {\n        $this->computedMiddleware = null;\n        $this->controller = null;\n    }\n\n    /**\n     * Determine if the route matches a given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  bool  $includingMethod\n     * @return bool\n     */\n    public function matches(Request $request, $includingMethod = true)\n    {\n        $this->compileRoute();\n\n        foreach (self::getValidators() as $validator) {\n            if (! $includingMethod && $validator instanceof MethodValidator) {\n                continue;\n            }\n\n            if (! $validator->matches($this, $request)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Compile the route into a Symfony CompiledRoute instance.\n     *\n     * @return \\Symfony\\Component\\Routing\\CompiledRoute\n     */\n    protected function compileRoute()\n    {\n        if (! $this->compiled) {\n            $this->compiled = $this->toSymfonyRoute()->compile();\n        }\n\n        return $this->compiled;\n    }\n\n    /**\n     * Bind the route to a given request for execution.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return $this\n     */\n    public function bind(Request $request)\n    {\n        $this->compileRoute();\n\n        $this->parameters = (new RouteParameterBinder($this))\n            ->parameters($request);\n\n        $this->originalParameters = $this->parameters;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the route has parameters.\n     *\n     * @return bool\n     */\n    public function hasParameters()\n    {\n        return isset($this->parameters);\n    }\n\n    /**\n     * Determine a given parameter exists from the route.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasParameter($name)\n    {\n        if ($this->hasParameters()) {\n            return array_key_exists($name, $this->parameters());\n        }\n\n        return false;\n    }\n\n    /**\n     * Get a given parameter from the route.\n     *\n     * @param  string  $name\n     * @param  string|object|null  $default\n     * @return string|object|null\n     */\n    public function parameter($name, $default = null)\n    {\n        return Arr::get($this->parameters(), $name, $default);\n    }\n\n    /**\n     * Get original value of a given parameter from the route.\n     *\n     * @param  string  $name\n     * @param  string|null  $default\n     * @return string|null\n     */\n    public function originalParameter($name, $default = null)\n    {\n        return Arr::get($this->originalParameters(), $name, $default);\n    }\n\n    /**\n     * Set a parameter to the given value.\n     *\n     * @param  string  $name\n     * @param  string|object|null  $value\n     * @return void\n     */\n    public function setParameter($name, $value)\n    {\n        $this->parameters();\n\n        $this->parameters[$name] = $value;\n    }\n\n    /**\n     * Unset a parameter on the route if it is set.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function forgetParameter($name)\n    {\n        $this->parameters();\n\n        unset($this->parameters[$name]);\n    }\n\n    /**\n     * Get the key / value list of parameters for the route.\n     *\n     * @return array\n     *\n     * @throws \\LogicException\n     */\n    public function parameters()\n    {\n        if (isset($this->parameters)) {\n            return $this->parameters;\n        }\n\n        throw new LogicException('Route is not bound.');\n    }\n\n    /**\n     * Get the key / value list of original parameters for the route.\n     *\n     * @return array\n     *\n     * @throws \\LogicException\n     */\n    public function originalParameters()\n    {\n        if (isset($this->originalParameters)) {\n            return $this->originalParameters;\n        }\n\n        throw new LogicException('Route is not bound.');\n    }\n\n    /**\n     * Get the key / value list of parameters without null values.\n     *\n     * @return array\n     */\n    public function parametersWithoutNulls()\n    {\n        return array_filter($this->parameters(), fn ($p) => ! is_null($p));\n    }\n\n    /**\n     * Get all of the parameter names for the route.\n     *\n     * @return array\n     */\n    public function parameterNames()\n    {\n        if (isset($this->parameterNames)) {\n            return $this->parameterNames;\n        }\n\n        return $this->parameterNames = $this->compileParameterNames();\n    }\n\n    /**\n     * Get the parameter names for the route.\n     *\n     * @return array\n     */\n    protected function compileParameterNames()\n    {\n        preg_match_all('/\\{(.*?)\\}/', $this->getDomain().$this->uri, $matches);\n\n        return array_map(fn ($m) => trim($m, '?'), $matches[1]);\n    }\n\n    /**\n     * Get the parameters that are listed in the route / controller signature.\n     *\n     * @param  array  $conditions\n     * @return array\n     */\n    public function signatureParameters($conditions = [])\n    {\n        if (is_string($conditions)) {\n            $conditions = ['subClass' => $conditions];\n        }\n\n        return RouteSignatureParameters::fromAction($this->action, $conditions);\n    }\n\n    /**\n     * Get the binding field for the given parameter.\n     *\n     * @param  string|int  $parameter\n     * @return string|null\n     */\n    public function bindingFieldFor($parameter)\n    {\n        $fields = is_int($parameter) ? array_values($this->bindingFields) : $this->bindingFields;\n\n        return $fields[$parameter] ?? null;\n    }\n\n    /**\n     * Get the binding fields for the route.\n     *\n     * @return array\n     */\n    public function bindingFields()\n    {\n        return $this->bindingFields ?? [];\n    }\n\n    /**\n     * Set the binding fields for the route.\n     *\n     * @param  array  $bindingFields\n     * @return $this\n     */\n    public function setBindingFields(array $bindingFields)\n    {\n        $this->bindingFields = $bindingFields;\n\n        return $this;\n    }\n\n    /**\n     * Get the parent parameter of the given parameter.\n     *\n     * @param  string  $parameter\n     * @return string|null\n     */\n    public function parentOfParameter($parameter)\n    {\n        $key = array_search($parameter, array_keys($this->parameters));\n\n        if ($key === 0 || $key === false) {\n            return;\n        }\n\n        return array_values($this->parameters)[$key - 1];\n    }\n\n    /**\n     * Allow \"trashed\" models to be retrieved when resolving implicit model bindings for this route.\n     *\n     * @param  bool  $withTrashed\n     * @return $this\n     */\n    public function withTrashed($withTrashed = true)\n    {\n        $this->withTrashedBindings = $withTrashed;\n\n        return $this;\n    }\n\n    /**\n     * Determines if the route allows \"trashed\" models to be retrieved when resolving implicit model bindings.\n     *\n     * @return bool\n     */\n    public function allowsTrashedBindings()\n    {\n        return $this->withTrashedBindings;\n    }\n\n    /**\n     * Set a default value for the route.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function defaults($key, $value)\n    {\n        $this->defaults[$key] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the default values for the route.\n     *\n     * @param  array  $defaults\n     * @return $this\n     */\n    public function setDefaults(array $defaults)\n    {\n        $this->defaults = $defaults;\n\n        return $this;\n    }\n\n    /**\n     * Set a regular expression requirement on the route.\n     *\n     * @param  array|string  $name\n     * @param  string|null  $expression\n     * @return $this\n     */\n    public function where($name, $expression = null)\n    {\n        foreach ($this->parseWhere($name, $expression) as $name => $expression) {\n            $this->wheres[$name] = $expression;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Parse arguments to the where method into an array.\n     *\n     * @param  array|string  $name\n     * @param  string  $expression\n     * @return array\n     */\n    protected function parseWhere($name, $expression)\n    {\n        return is_array($name) ? $name : [$name => $expression];\n    }\n\n    /**\n     * Set a list of regular expression requirements on the route.\n     *\n     * @param  array  $wheres\n     * @return $this\n     */\n    public function setWheres(array $wheres)\n    {\n        foreach ($wheres as $name => $expression) {\n            $this->where($name, $expression);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Mark this route as a fallback route.\n     *\n     * @return $this\n     */\n    public function fallback()\n    {\n        $this->isFallback = true;\n\n        return $this;\n    }\n\n    /**\n     * Set the fallback value.\n     *\n     * @param  bool  $isFallback\n     * @return $this\n     */\n    public function setFallback($isFallback)\n    {\n        $this->isFallback = $isFallback;\n\n        return $this;\n    }\n\n    /**\n     * Get the HTTP verbs the route responds to.\n     *\n     * @return array\n     */\n    public function methods()\n    {\n        return $this->methods;\n    }\n\n    /**\n     * Determine if the route only responds to HTTP requests.\n     *\n     * @return bool\n     */\n    public function httpOnly()\n    {\n        return in_array('http', $this->action, true);\n    }\n\n    /**\n     * Determine if the route only responds to HTTPS requests.\n     *\n     * @return bool\n     */\n    public function httpsOnly()\n    {\n        return $this->secure();\n    }\n\n    /**\n     * Determine if the route only responds to HTTPS requests.\n     *\n     * @return bool\n     */\n    public function secure()\n    {\n        return in_array('https', $this->action, true);\n    }\n\n    /**\n     * Get or set the domain for the route.\n     *\n     * @param  \\BackedEnum|string|null  $domain\n     * @return $this|string|null\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function domain($domain = null)\n    {\n        if (is_null($domain)) {\n            return $this->getDomain();\n        }\n\n        if ($domain instanceof BackedEnum && ! is_string($domain = $domain->value)) {\n            throw new InvalidArgumentException('Enum must be string backed.');\n        }\n\n        $parsed = RouteUri::parse($domain);\n\n        $this->action['domain'] = $parsed->uri;\n\n        $this->bindingFields = array_merge(\n            $this->bindingFields, $parsed->bindingFields\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get the domain defined for the route.\n     *\n     * @return string|null\n     */\n    public function getDomain()\n    {\n        return isset($this->action['domain'])\n            ? str_replace(['http://', 'https://'], '', $this->action['domain'])\n            : null;\n    }\n\n    /**\n     * Get the prefix of the route instance.\n     *\n     * @return string|null\n     */\n    public function getPrefix()\n    {\n        return $this->action['prefix'] ?? null;\n    }\n\n    /**\n     * Add a prefix to the route URI.\n     *\n     * @param  string|null  $prefix\n     * @return $this\n     */\n    public function prefix($prefix)\n    {\n        $prefix ??= '';\n\n        $this->updatePrefixOnAction($prefix);\n\n        $uri = rtrim($prefix, '/').'/'.ltrim($this->uri, '/');\n\n        return $this->setUri($uri !== '/' ? trim($uri, '/') : $uri);\n    }\n\n    /**\n     * Update the \"prefix\" attribute on the action array.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    protected function updatePrefixOnAction($prefix)\n    {\n        if (! empty($newPrefix = trim(rtrim($prefix, '/').'/'.ltrim($this->action['prefix'] ?? '', '/'), '/'))) {\n            $this->action['prefix'] = $newPrefix;\n        }\n    }\n\n    /**\n     * Get the URI associated with the route.\n     *\n     * @return string\n     */\n    public function uri()\n    {\n        return $this->uri;\n    }\n\n    /**\n     * Set the URI that the route responds to.\n     *\n     * @param  string  $uri\n     * @return $this\n     */\n    public function setUri($uri)\n    {\n        $this->uri = $this->parseUri($uri);\n\n        return $this;\n    }\n\n    /**\n     * Parse the route URI and normalize / store any implicit binding fields.\n     *\n     * @param  string  $uri\n     * @return string\n     */\n    protected function parseUri($uri)\n    {\n        $this->bindingFields = [];\n\n        return tap(RouteUri::parse($uri), function ($uri) {\n            $this->bindingFields = $uri->bindingFields;\n        })->uri;\n    }\n\n    /**\n     * Get the name of the route instance.\n     *\n     * @return string|null\n     */\n    public function getName()\n    {\n        return $this->action['as'] ?? null;\n    }\n\n    /**\n     * Add or change the route name.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function name($name)\n    {\n        if ($name instanceof BackedEnum && ! is_string($name = $name->value)) {\n            throw new InvalidArgumentException('Enum must be string backed.');\n        }\n\n        $this->action['as'] = isset($this->action['as']) ? $this->action['as'].$name : $name;\n\n        return $this;\n    }\n\n    /**\n     * Determine whether the route's name matches the given patterns.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function named(...$patterns)\n    {\n        if (is_null($routeName = $this->getName())) {\n            return false;\n        }\n\n        foreach ($patterns as $pattern) {\n            if (Str::is($pattern, $routeName)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Set the handler for the route.\n     *\n     * @param  \\Closure|array|string  $action\n     * @return $this\n     */\n    public function uses($action)\n    {\n        if (is_array($action)) {\n            $action = $action[0].'@'.$action[1];\n        }\n\n        $action = is_string($action) ? $this->addGroupNamespaceToStringUses($action) : $action;\n\n        return $this->setAction(array_merge($this->action, $this->parseAction([\n            'uses' => $action,\n            'controller' => $action,\n        ])));\n    }\n\n    /**\n     * Parse a string based action for the \"uses\" fluent method.\n     *\n     * @param  string  $action\n     * @return string\n     */\n    protected function addGroupNamespaceToStringUses($action)\n    {\n        $groupStack = last($this->router->getGroupStack());\n\n        if (isset($groupStack['namespace']) && ! str_starts_with($action, '\\\\')) {\n            return $groupStack['namespace'].'\\\\'.$action;\n        }\n\n        return $action;\n    }\n\n    /**\n     * Get the action name for the route.\n     *\n     * @return string\n     */\n    public function getActionName()\n    {\n        return $this->action['controller'] ?? 'Closure';\n    }\n\n    /**\n     * Get the method name of the route action.\n     *\n     * @return string\n     */\n    public function getActionMethod()\n    {\n        return Arr::last(explode('@', $this->getActionName()));\n    }\n\n    /**\n     * Get the action array or one of its properties for the route.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    public function getAction($key = null)\n    {\n        return Arr::get($this->action, $key);\n    }\n\n    /**\n     * Set the action array for the route.\n     *\n     * @param  array  $action\n     * @return $this\n     */\n    public function setAction(array $action)\n    {\n        $this->action = $action;\n\n        if (isset($this->action['domain'])) {\n            $this->domain($this->action['domain']);\n        }\n\n        if (isset($this->action['can'])) {\n            foreach ($this->action['can'] as $can) {\n                $this->can($can[0], $can[1] ?? []);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the value of the action that should be taken on a missing model exception.\n     *\n     * @return \\Closure|null\n     */\n    public function getMissing()\n    {\n        $missing = $this->action['missing'] ?? null;\n\n        return is_string($missing) &&\n            Str::startsWith($missing, [\n                'O:47:\"Laravel\\\\SerializableClosure\\\\SerializableClosure',\n                'O:55:\"Laravel\\\\SerializableClosure\\\\UnsignedSerializableClosure',\n            ]) ? unserialize($missing) : $missing;\n    }\n\n    /**\n     * Define the callable that should be invoked on a missing model exception.\n     *\n     * @param  \\Closure  $missing\n     * @return $this\n     */\n    public function missing($missing)\n    {\n        $this->action['missing'] = $missing;\n\n        return $this;\n    }\n\n    /**\n     * Get all middleware, including the ones from the controller.\n     *\n     * @return array\n     */\n    public function gatherMiddleware()\n    {\n        if (! is_null($this->computedMiddleware)) {\n            return $this->computedMiddleware;\n        }\n\n        $this->computedMiddleware = [];\n\n        return $this->computedMiddleware = Router::uniqueMiddleware(array_merge(\n            $this->middleware(), $this->controllerMiddleware()\n        ));\n    }\n\n    /**\n     * Get or set the middlewares attached to the route.\n     *\n     * @param  array|string|null  $middleware\n     * @return ($middleware is null ? array : $this)\n     */\n    public function middleware($middleware = null)\n    {\n        if (is_null($middleware)) {\n            return (array) ($this->action['middleware'] ?? []);\n        }\n\n        if (! is_array($middleware)) {\n            $middleware = func_get_args();\n        }\n\n        foreach ($middleware as $index => $value) {\n            $middleware[$index] = (string) $value;\n        }\n\n        $this->action['middleware'] = array_merge(\n            (array) ($this->action['middleware'] ?? []), $middleware\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the \"Authorize\" / \"can\" middleware should be applied to the route with the given options.\n     *\n     * @param  \\UnitEnum|string  $ability\n     * @param  array|string  $models\n     * @return $this\n     */\n    public function can($ability, $models = [])\n    {\n        $ability = enum_value($ability);\n\n        return empty($models)\n            ? $this->middleware(['can:'.$ability])\n            : $this->middleware(['can:'.$ability.','.implode(',', Arr::wrap($models))]);\n    }\n\n    /**\n     * Get the middleware for the route's controller.\n     *\n     * @return array\n     */\n    public function controllerMiddleware()\n    {\n        if (! $this->isControllerAction()) {\n            return [];\n        }\n\n        [$controllerClass, $controllerMethod] = [\n            $this->getControllerClass(),\n            $this->getControllerMethod(),\n        ];\n\n        if (is_a($controllerClass, HasMiddleware::class, true)) {\n            return $this->staticallyProvidedControllerMiddleware(\n                $controllerClass, $controllerMethod\n            );\n        }\n\n        if (method_exists($controllerClass, 'getMiddleware')) {\n            return $this->controllerDispatcher()->getMiddleware(\n                $this->getController(), $controllerMethod\n            );\n        }\n\n        return $this->attributeProvidedControllerMiddleware(\n            $controllerClass, $controllerMethod\n        );\n    }\n\n    /**\n     * Get the statically provided controller middleware for the given class and method.\n     *\n     * @param  string  $class\n     * @param  string  $method\n     * @return array\n     */\n    protected function staticallyProvidedControllerMiddleware(string $class, string $method)\n    {\n        return (new Collection($class::middleware()))\n            ->map(function ($middleware) {\n                return $middleware instanceof Middleware\n                    ? $middleware\n                    : new Middleware($middleware);\n            })\n            ->reject(function ($middleware) use ($method) {\n                return static::methodExcludedByOptions(\n                    $method, ['only' => $middleware->only, 'except' => $middleware->except],\n                );\n            })\n            ->map\n            ->middleware\n            ->flatten()\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Get the attribute provided controller middleware for the given class and method.\n     *\n     * @return array\n     */\n    protected function attributeProvidedControllerMiddleware(string $class, string $method)\n    {\n        try {\n            $reflectionClass = new ReflectionClass($class);\n\n            $reflectionMethod = $reflectionClass->getMethod($method);\n        } catch (ReflectionException) {\n            return [];\n        }\n\n        return (new Collection(array_merge(\n            $reflectionClass->getAttributes(MiddlewareAttribute::class, ReflectionAttribute::IS_INSTANCEOF),\n            $reflectionMethod->getAttributes(MiddlewareAttribute::class, ReflectionAttribute::IS_INSTANCEOF),\n        )))->map(function (ReflectionAttribute $attribute) use ($method) {\n            $instance = $attribute->newInstance();\n\n            return static::methodExcludedByOptions(\n                $method, ['only' => $instance->only, 'except' => $instance->except],\n            ) ? null : $instance->middleware;\n        })\n            ->filter()\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Specify middleware that should be removed from the given route.\n     *\n     * @param  array|string  $middleware\n     * @return $this\n     */\n    public function withoutMiddleware($middleware)\n    {\n        $this->action['excluded_middleware'] = array_merge(\n            (array) ($this->action['excluded_middleware'] ?? []), Arr::wrap($middleware)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get the middleware that should be removed from the route.\n     *\n     * @return array\n     */\n    public function excludedMiddleware()\n    {\n        return (array) ($this->action['excluded_middleware'] ?? []);\n    }\n\n    /**\n     * Indicate that the route should enforce scoping of multiple implicit Eloquent bindings.\n     *\n     * @return $this\n     */\n    public function scopeBindings()\n    {\n        $this->action['scope_bindings'] = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the route should not enforce scoping of multiple implicit Eloquent bindings.\n     *\n     * @return $this\n     */\n    public function withoutScopedBindings()\n    {\n        $this->action['scope_bindings'] = false;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the route should enforce scoping of multiple implicit Eloquent bindings.\n     *\n     * @return bool\n     */\n    public function enforcesScopedBindings()\n    {\n        return (bool) ($this->action['scope_bindings'] ?? false);\n    }\n\n    /**\n     * Determine if the route should prevent scoping of multiple implicit Eloquent bindings.\n     *\n     * @return bool\n     */\n    public function preventsScopedBindings()\n    {\n        return isset($this->action['scope_bindings']) && $this->action['scope_bindings'] === false;\n    }\n\n    /**\n     * Specify that the route should not allow concurrent requests from the same session.\n     *\n     * @param  int|null  $lockSeconds\n     * @param  int|null  $waitSeconds\n     * @return $this\n     */\n    public function block($lockSeconds = 10, $waitSeconds = 10)\n    {\n        $this->lockSeconds = $lockSeconds;\n        $this->waitSeconds = $waitSeconds;\n\n        return $this;\n    }\n\n    /**\n     * Specify that the route should allow concurrent requests from the same session.\n     *\n     * @return $this\n     */\n    public function withoutBlocking()\n    {\n        return $this->block(null, null);\n    }\n\n    /**\n     * Get the maximum number of seconds the route's session lock should be held for.\n     *\n     * @return int|null\n     */\n    public function locksFor()\n    {\n        return $this->lockSeconds;\n    }\n\n    /**\n     * Get the maximum number of seconds to wait while attempting to acquire a session lock.\n     *\n     * @return int|null\n     */\n    public function waitsFor()\n    {\n        return $this->waitSeconds;\n    }\n\n    /**\n     * Get the dispatcher for the route's controller.\n     *\n     * @return \\Illuminate\\Routing\\Contracts\\ControllerDispatcher\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    public function controllerDispatcher()\n    {\n        if ($this->container->bound(ControllerDispatcherContract::class)) {\n            return $this->container->make(ControllerDispatcherContract::class);\n        }\n\n        return new ControllerDispatcher($this->container);\n    }\n\n    /**\n     * Get the route validators for the instance.\n     *\n     * @return array\n     */\n    public static function getValidators()\n    {\n        if (isset(static::$validators)) {\n            return static::$validators;\n        }\n\n        // To match the route, we will use a chain of responsibility pattern with the\n        // validator implementations. We will spin through each one making sure it\n        // passes and then we will know if the route as a whole matches request.\n        return static::$validators = [\n            new UriValidator, new MethodValidator,\n            new SchemeValidator, new HostValidator,\n        ];\n    }\n\n    /**\n     * Convert the route to a Symfony route.\n     *\n     * @return \\Symfony\\Component\\Routing\\Route\n     */\n    public function toSymfonyRoute()\n    {\n        return new SymfonyRoute(\n            preg_replace('/\\{(\\w+?)\\?\\}/', '{$1}', $this->uri()), $this->getOptionalParameterNames(),\n            $this->wheres, ['utf8' => true],\n            $this->getDomain() ?: '', [], $this->methods\n        );\n    }\n\n    /**\n     * Get the optional parameter names for the route.\n     *\n     * @return array<string, null>\n     */\n    public function getOptionalParameterNames()\n    {\n        preg_match_all('/\\{(\\w+?)\\?\\}/', $this->uri(), $matches);\n\n        return isset($matches[1]) ? array_fill_keys($matches[1], null) : [];\n    }\n\n    /**\n     * Get the compiled version of the route.\n     *\n     * @return \\Symfony\\Component\\Routing\\CompiledRoute\n     */\n    public function getCompiled()\n    {\n        return $this->compiled;\n    }\n\n    /**\n     * Set the router instance on the route.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     * @return $this\n     */\n    public function setRouter(Router $router)\n    {\n        $this->router = $router;\n\n        return $this;\n    }\n\n    /**\n     * Set the container instance on the route.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Prepare the route instance for serialization.\n     *\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function prepareForSerialization()\n    {\n        if ($this->action['uses'] instanceof Closure) {\n            $this->action['uses'] = serialize(\n                SerializableClosure::unsigned($this->action['uses'])\n            );\n        }\n\n        if (isset($this->action['missing']) && $this->action['missing'] instanceof Closure) {\n            $this->action['missing'] = serialize(\n                SerializableClosure::unsigned($this->action['missing'])\n            );\n        }\n\n        $this->compileRoute();\n\n        unset($this->router, $this->container);\n    }\n\n    /**\n     * Dynamically access route parameters.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->parameter($key);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteAction.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Str;\nuse LogicException;\nuse UnexpectedValueException;\n\nclass RouteAction\n{\n    /**\n     * Parse the given action into an array.\n     *\n     * @param  string  $uri\n     * @param  mixed  $action\n     * @return array\n     */\n    public static function parse($uri, $action)\n    {\n        // If no action is passed in right away, we assume the user will make use of\n        // fluent routing. In that case, we set a default closure, to be executed\n        // if the user never explicitly sets an action to handle the given uri.\n        if (is_null($action)) {\n            return static::missingAction($uri);\n        }\n\n        // If the action is already a Closure instance, we will just set that instance\n        // as the \"uses\" property, because there is nothing else we need to do when\n        // it is available. Otherwise we will need to find it in the action list.\n        if (Reflector::isCallable($action, true)) {\n            return ! is_array($action) ? ['uses' => $action] : [\n                'uses' => $action[0].'@'.$action[1],\n                'controller' => $action[0].'@'.$action[1],\n            ];\n        }\n\n        // If no \"uses\" property has been set, we will dig through the array to find a\n        // Closure instance within this list. We will set the first Closure we come\n        // across into the \"uses\" property that will get fired off by this route.\n        elseif (! isset($action['uses'])) {\n            $action['uses'] = static::findCallable($action);\n        }\n\n        if (! static::containsSerializedClosure($action) && is_string($action['uses']) && ! str_contains($action['uses'], '@')) {\n            $action['uses'] = static::makeInvokable($action['uses']);\n        }\n\n        return $action;\n    }\n\n    /**\n     * Get an action for a route that has no action.\n     *\n     * @param  string  $uri\n     * @return array\n     *\n     * @throws \\LogicException\n     */\n    protected static function missingAction($uri)\n    {\n        return ['uses' => function () use ($uri) {\n            throw new LogicException(\"Route for [{$uri}] has no action.\");\n        }];\n    }\n\n    /**\n     * Find the callable in an action array.\n     *\n     * @param  array  $action\n     * @return callable\n     */\n    protected static function findCallable(array $action)\n    {\n        return Arr::first($action, function ($value, $key) {\n            return Reflector::isCallable($value) && is_numeric($key);\n        });\n    }\n\n    /**\n     * Make an action for an invokable controller.\n     *\n     * @param  string  $action\n     * @return string\n     *\n     * @throws \\UnexpectedValueException\n     */\n    protected static function makeInvokable($action)\n    {\n        if (! method_exists($action, '__invoke')) {\n            throw new UnexpectedValueException(\"Invalid route action: [{$action}].\");\n        }\n\n        return $action.'@__invoke';\n    }\n\n    /**\n     * Determine if the given array actions contain a serialized Closure.\n     *\n     * @param  array  $action\n     * @return bool\n     */\n    public static function containsSerializedClosure(array $action)\n    {\n        return is_string($action['uses']) && Str::startsWith($action['uses'], [\n            'O:47:\"Laravel\\\\SerializableClosure\\\\SerializableClosure',\n            'O:55:\"Laravel\\\\SerializableClosure\\\\UnsignedSerializableClosure',\n        ]) !== false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteBinding.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Support\\Str;\n\nclass RouteBinding\n{\n    /**\n     * Create a Route model binding for a given callback.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  \\Closure|string  $binder\n     * @return \\Closure\n     */\n    public static function forCallback($container, $binder)\n    {\n        if (is_string($binder)) {\n            return static::createClassBinding($container, $binder);\n        }\n\n        return $binder;\n    }\n\n    /**\n     * Create a class based binding using the IoC container.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  string  $binding\n     * @return \\Closure\n     */\n    protected static function createClassBinding($container, $binding)\n    {\n        return function ($value, $route) use ($container, $binding) {\n            // If the binding has an @ sign, we will assume it's being used to delimit\n            // the class name from the bind method name. This allows for bindings\n            // to run multiple bind methods in a single class for convenience.\n            [$class, $method] = Str::parseCallback($binding, 'bind');\n\n            $callable = [$container->make($class), $method];\n\n            return $callable($value, $route);\n        };\n    }\n\n    /**\n     * Create a Route model binding for a model.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @param  string  $class\n     * @param  \\Closure|null  $callback\n     * @return \\Closure\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<\\Illuminate\\Database\\Eloquent\\Model>\n     */\n    public static function forModel($container, $class, $callback = null)\n    {\n        return function ($value, $route = null) use ($container, $class, $callback) {\n            if (is_null($value)) {\n                return;\n            }\n\n            // For model binders, we will attempt to retrieve the models using the first\n            // method on the model instance. If we cannot retrieve the models we'll\n            // throw a not found exception otherwise we will return the instance.\n            $instance = $container->make($class);\n\n            $routeBindingMethod = $route?->allowsTrashedBindings() && $instance::isSoftDeletable()\n                ? 'resolveSoftDeletableRouteBinding'\n                : 'resolveRouteBinding';\n\n            if ($model = $instance->{$routeBindingMethod}($value)) {\n                return $model;\n            }\n\n            // If a callback was supplied to the method we will call that to determine\n            // what we should do when the model is not found. This just gives these\n            // developer a little greater flexibility to decide what will happen.\n            if ($callback instanceof Closure) {\n                return $callback($value);\n            }\n\n            throw (new ModelNotFoundException)->setModel($class);\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\n\nclass RouteCollection extends AbstractRouteCollection\n{\n    /**\n     * An array of the routes keyed by method.\n     *\n     * @var array\n     */\n    protected $routes = [];\n\n    /**\n     * A flattened array of all of the routes.\n     *\n     * @var \\Illuminate\\Routing\\Route[]\n     */\n    protected $allRoutes = [];\n\n    /**\n     * A look-up table of routes by their names.\n     *\n     * @var \\Illuminate\\Routing\\Route[]\n     */\n    protected $nameList = [];\n\n    /**\n     * A look-up table of routes by controller action.\n     *\n     * @var \\Illuminate\\Routing\\Route[]\n     */\n    protected $actionList = [];\n\n    /**\n     * Add a Route instance to the collection.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function add(Route $route)\n    {\n        $this->addToCollections($route);\n\n        $this->addLookups($route);\n\n        return $route;\n    }\n\n    /**\n     * Add the given route to the arrays of routes.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     */\n    protected function addToCollections($route)\n    {\n        $methods = $route->methods();\n        $domainAndUri = $route->getDomain().$route->uri();\n\n        foreach ($methods as $method) {\n            if ($route->getDomain()) {\n                $domainRoutes = array_filter($this->routes[$method] ?? [], fn ($route) => $route->getDomain() !== null);\n\n                $this->routes[$method] = $domainRoutes + [$domainAndUri => $route] + ($this->routes[$method] ?? []);\n            } else {\n                $this->routes[$method][$domainAndUri] = $route;\n            }\n        }\n\n        if ($route->getDomain()) {\n            $domainRoutes = array_filter($this->allRoutes, fn ($route) => $route->getDomain() !== null);\n\n            $this->allRoutes = $domainRoutes + [implode('|', $methods).$domainAndUri => $route] + $this->allRoutes;\n        } else {\n            $this->allRoutes[implode('|', $methods).$domainAndUri] = $route;\n        }\n    }\n\n    /**\n     * Add the route to any look-up tables if necessary.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     */\n    protected function addLookups($route)\n    {\n        // If the route has a name, we will add it to the name look-up table, so that we\n        // will quickly be able to find the route associated with a name and not have\n        // to iterate through every route every time we need to find a named route.\n        if (($name = $route->getName()) && ! $this->inNameLookup($name)) {\n            $this->nameList[$name] = $route;\n        }\n\n        // When the route is routing to a controller we will also store the action that\n        // is used by the route. This will let us reverse route to controllers while\n        // processing a request and easily generate URLs to the given controllers.\n        $action = $route->getAction();\n\n        if (($controller = $action['controller'] ?? null) && ! $this->inActionLookup($controller)) {\n            $this->addToActionList($action, $route);\n        }\n    }\n\n    /**\n     * Add a route to the controller action dictionary.\n     *\n     * @param  array  $action\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     */\n    protected function addToActionList($action, $route)\n    {\n        $this->actionList[trim($action['controller'], '\\\\')] = $route;\n    }\n\n    /**\n     * Determine if the given controller is in the action lookup table.\n     *\n     * @param  string  $controller\n     * @return bool\n     */\n    protected function inActionLookup($controller)\n    {\n        return array_key_exists($controller, $this->actionList);\n    }\n\n    /**\n     * Determine if the given name is in the name lookup table.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    protected function inNameLookup($name)\n    {\n        return array_key_exists($name, $this->nameList);\n    }\n\n    /**\n     * Refresh the name look-up table.\n     *\n     * This is done in case any names are fluently defined or if routes are overwritten.\n     *\n     * @return void\n     */\n    public function refreshNameLookups()\n    {\n        $this->nameList = [];\n\n        foreach ($this->allRoutes as $route) {\n            if (($name = $route->getName()) && ! $this->inNameLookup($name)) {\n                $this->nameList[$name] = $route;\n            }\n        }\n    }\n\n    /**\n     * Refresh the action look-up table.\n     *\n     * This is done in case any actions are overwritten with new controllers.\n     *\n     * @return void\n     */\n    public function refreshActionLookups()\n    {\n        $this->actionList = [];\n\n        foreach ($this->allRoutes as $route) {\n            if (($controller = $route->getAction()['controller'] ?? null) && ! $this->inActionLookup($controller)) {\n                $this->addToActionList($route->getAction(), $route);\n            }\n        }\n    }\n\n    /**\n     * Find the first route matching a given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    public function match(Request $request)\n    {\n        $routes = $this->get($request->getMethod());\n\n        // First, we will see if we can find a matching route for this current request\n        // method. If we can, great, we can just return it so that it can be called\n        // by the consumer. Otherwise we will check for routes with another verb.\n        $route = $this->matchAgainstRoutes($routes, $request);\n\n        return $this->handleMatchedRoute($request, $route);\n    }\n\n    /**\n     * Get routes from the collection by method.\n     *\n     * @param  string|null  $method\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function get($method = null)\n    {\n        return is_null($method) ? $this->getRoutes() : ($this->routes[$method] ?? []);\n    }\n\n    /**\n     * Determine if the route collection contains a given named route.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasNamedRoute($name)\n    {\n        return ! is_null($this->getByName($name));\n    }\n\n    /**\n     * Get a route instance by its name.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByName($name)\n    {\n        return $this->nameList[$name] ?? null;\n    }\n\n    /**\n     * Get a route instance by its controller action.\n     *\n     * @param  string  $action\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByAction($action)\n    {\n        return $this->actionList[$action] ?? null;\n    }\n\n    /**\n     * Get all of the routes in the collection.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutes()\n    {\n        return array_values($this->allRoutes);\n    }\n\n    /**\n     * Get all of the routes keyed by their HTTP verb / method.\n     *\n     * @return array\n     */\n    public function getRoutesByMethod()\n    {\n        return $this->routes;\n    }\n\n    /**\n     * Get all of the routes keyed by their name.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutesByName()\n    {\n        return $this->nameList;\n    }\n\n    /**\n     * Convert the collection to a Symfony RouteCollection instance.\n     *\n     * @return \\Symfony\\Component\\Routing\\RouteCollection\n     */\n    public function toSymfonyRouteCollection()\n    {\n        $symfonyRoutes = parent::toSymfonyRouteCollection();\n\n        $this->refreshNameLookups();\n\n        return $symfonyRoutes;\n    }\n\n    /**\n     * Convert the collection to a CompiledRouteCollection instance.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return \\Illuminate\\Routing\\CompiledRouteCollection\n     */\n    public function toCompiledRouteCollection(Router $router, Container $container)\n    {\n        ['compiled' => $compiled, 'attributes' => $attributes] = $this->compile();\n\n        return (new CompiledRouteCollection($compiled, $attributes))\n            ->setRouter($router)\n            ->setContainer($container);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteCollectionInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Http\\Request;\n\ninterface RouteCollectionInterface\n{\n    /**\n     * Add a Route instance to the collection.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function add(Route $route);\n\n    /**\n     * Refresh the name look-up table.\n     *\n     * This is done in case any names are fluently defined or if routes are overwritten.\n     *\n     * @return void\n     */\n    public function refreshNameLookups();\n\n    /**\n     * Refresh the action look-up table.\n     *\n     * This is done in case any actions are overwritten with new controllers.\n     *\n     * @return void\n     */\n    public function refreshActionLookups();\n\n    /**\n     * Find the first route matching a given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException\n     * @throws \\Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException\n     */\n    public function match(Request $request);\n\n    /**\n     * Get routes from the collection by method.\n     *\n     * @param  string|null  $method\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function get($method = null);\n\n    /**\n     * Determine if the route collection contains a given named route.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasNamedRoute($name);\n\n    /**\n     * Get a route instance by its name.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByName($name);\n\n    /**\n     * Get a route instance by its controller action.\n     *\n     * @param  string  $action\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getByAction($action);\n\n    /**\n     * Get all of the routes in the collection.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutes();\n\n    /**\n     * Get all of the routes keyed by their HTTP verb / method.\n     *\n     * @return array\n     */\n    public function getRoutesByMethod();\n\n    /**\n     * Get all of the routes keyed by their name.\n     *\n     * @return \\Illuminate\\Routing\\Route[]\n     */\n    public function getRoutesByName();\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteDependencyResolverTrait.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\n/**\n * @deprecated\n */\ntrait RouteDependencyResolverTrait\n{\n    use ResolvesRouteDependencies;\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteFileRegistrar.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nclass RouteFileRegistrar\n{\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * Create a new route file registrar instance.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     */\n    public function __construct(Router $router)\n    {\n        $this->router = $router;\n    }\n\n    /**\n     * Require the given routes file.\n     *\n     * @param  string  $routes\n     * @return void\n     */\n    public function register($routes)\n    {\n        $router = $this->router;\n\n        require $routes;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteGroup.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Arr;\n\nclass RouteGroup\n{\n    /**\n     * Merge route groups into a new array.\n     *\n     * @param  array  $new\n     * @param  array  $old\n     * @param  bool  $prependExistingPrefix\n     * @return array\n     */\n    public static function merge($new, $old, $prependExistingPrefix = true)\n    {\n        if (isset($new['domain'])) {\n            unset($old['domain']);\n        }\n\n        if (isset($new['controller'])) {\n            unset($old['controller']);\n        }\n\n        $new = array_merge(static::formatAs($new, $old), [\n            'namespace' => static::formatNamespace($new, $old),\n            'prefix' => static::formatPrefix($new, $old, $prependExistingPrefix),\n            'where' => static::formatWhere($new, $old),\n        ]);\n\n        return array_merge_recursive(Arr::except(\n            $old, ['namespace', 'prefix', 'where', 'as']\n        ), $new);\n    }\n\n    /**\n     * Format the namespace for the new group attributes.\n     *\n     * @param  array  $new\n     * @param  array  $old\n     * @return string|null\n     */\n    protected static function formatNamespace($new, $old)\n    {\n        if (isset($new['namespace'])) {\n            return isset($old['namespace']) && ! str_starts_with($new['namespace'], '\\\\')\n                ? trim($old['namespace'], '\\\\').'\\\\'.trim($new['namespace'], '\\\\')\n                : trim($new['namespace'], '\\\\');\n        }\n\n        return $old['namespace'] ?? null;\n    }\n\n    /**\n     * Format the prefix for the new group attributes.\n     *\n     * @param  array  $new\n     * @param  array  $old\n     * @param  bool  $prependExistingPrefix\n     * @return string|null\n     */\n    protected static function formatPrefix($new, $old, $prependExistingPrefix = true)\n    {\n        $old = $old['prefix'] ?? '';\n\n        if ($prependExistingPrefix) {\n            return isset($new['prefix']) ? trim($old, '/').'/'.trim($new['prefix'], '/') : $old;\n        }\n\n        return isset($new['prefix']) ? trim($new['prefix'], '/').'/'.trim($old, '/') : $old;\n    }\n\n    /**\n     * Format the \"wheres\" for the new group attributes.\n     *\n     * @param  array  $new\n     * @param  array  $old\n     * @return array\n     */\n    protected static function formatWhere($new, $old)\n    {\n        return array_merge(\n            $old['where'] ?? [],\n            $new['where'] ?? []\n        );\n    }\n\n    /**\n     * Format the \"as\" clause of the new group attributes.\n     *\n     * @param  array  $new\n     * @param  array  $old\n     * @return array\n     */\n    protected static function formatAs($new, $old)\n    {\n        if (isset($old['as'])) {\n            $new['as'] = $old['as'].($new['as'] ?? '');\n        }\n\n        return $new;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteParameterBinder.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Arr;\n\nclass RouteParameterBinder\n{\n    /**\n     * The route instance.\n     *\n     * @var \\Illuminate\\Routing\\Route\n     */\n    protected $route;\n\n    /**\n     * Create a new Route parameter binder instance.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     */\n    public function __construct($route)\n    {\n        $this->route = $route;\n    }\n\n    /**\n     * Get the parameters for the route.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    public function parameters($request)\n    {\n        $parameters = $this->bindPathParameters($request);\n\n        // If the route has a regular expression for the host part of the URI, we will\n        // compile that and get the parameter matches for this domain. We will then\n        // merge them into this parameters array so that this array is completed.\n        if (! is_null($this->route->compiled->getHostRegex())) {\n            $parameters = $this->bindHostParameters(\n                $request, $parameters\n            );\n        }\n\n        return $this->replaceDefaults($parameters);\n    }\n\n    /**\n     * Get the parameter matches for the path portion of the URI.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\n     */\n    protected function bindPathParameters($request)\n    {\n        $path = '/'.ltrim($request->decodedPath(), '/');\n\n        preg_match($this->route->compiled->getRegex(), $path, $matches);\n\n        return $this->matchToKeys(array_slice($matches, 1));\n    }\n\n    /**\n     * Extract the parameter list from the host part of the request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function bindHostParameters($request, $parameters)\n    {\n        preg_match($this->route->compiled->getHostRegex(), $request->getHost(), $matches);\n\n        return array_merge($this->matchToKeys(array_slice($matches, 1)), $parameters);\n    }\n\n    /**\n     * Combine a set of parameter matches with the route's keys.\n     *\n     * @param  array  $matches\n     * @return array\n     */\n    protected function matchToKeys(array $matches)\n    {\n        if (empty($parameterNames = $this->route->parameterNames())) {\n            return [];\n        }\n\n        $parameters = array_intersect_key($matches, array_flip($parameterNames));\n\n        return array_filter($parameters, function ($value) {\n            return is_string($value) && strlen($value) > 0;\n        });\n    }\n\n    /**\n     * Replace null parameters with their defaults.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function replaceDefaults(array $parameters)\n    {\n        foreach ($parameters as $key => $value) {\n            $parameters[$key] = $value ?? Arr::get($this->route->defaults, $key);\n        }\n\n        foreach ($this->route->defaults as $key => $value) {\n            if (! isset($parameters[$key])) {\n                $parameters[$key] = $value;\n            }\n        }\n\n        return $parameters;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteRegistrar.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse BackedEnum;\nuse BadMethodCallException;\nuse Closure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\n/**\n * @method \\Illuminate\\Routing\\Route any(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route delete(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route get(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route options(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route patch(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route post(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\Route put(string $uri, \\Closure|array|string|null $action = null)\n * @method \\Illuminate\\Routing\\RouteRegistrar as(string $value)\n * @method \\Illuminate\\Routing\\RouteRegistrar can(\\UnitEnum|string  $ability, array|string $models = [])\n * @method \\Illuminate\\Routing\\RouteRegistrar controller(string $controller)\n * @method \\Illuminate\\Routing\\RouteRegistrar domain(\\BackedEnum|string $value)\n * @method \\Illuminate\\Routing\\RouteRegistrar middleware(array|string|null $middleware)\n * @method \\Illuminate\\Routing\\RouteRegistrar missing(\\Closure $missing)\n * @method \\Illuminate\\Routing\\RouteRegistrar name(\\BackedEnum|string $value)\n * @method \\Illuminate\\Routing\\RouteRegistrar namespace(string|null $value)\n * @method \\Illuminate\\Routing\\RouteRegistrar prefix(string $prefix)\n * @method \\Illuminate\\Routing\\RouteRegistrar scopeBindings()\n * @method \\Illuminate\\Routing\\RouteRegistrar where(array $where)\n * @method \\Illuminate\\Routing\\RouteRegistrar withoutMiddleware(array|string $middleware)\n * @method \\Illuminate\\Routing\\RouteRegistrar withoutScopedBindings()\n */\nclass RouteRegistrar\n{\n    use CreatesRegularExpressionRouteConstraints;\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The router instance.\n     *\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    /**\n     * The attributes to pass on to the router.\n     *\n     * @var array\n     */\n    protected $attributes = [];\n\n    /**\n     * The methods to dynamically pass through to the router.\n     *\n     * @var string[]\n     */\n    protected $passthru = [\n        'get', 'post', 'put', 'patch', 'delete', 'options', 'any',\n    ];\n\n    /**\n     * The attributes that can be set through this class.\n     *\n     * @var string[]\n     */\n    protected $allowedAttributes = [\n        'as',\n        'can',\n        'controller',\n        'domain',\n        'middleware',\n        'missing',\n        'name',\n        'namespace',\n        'prefix',\n        'scopeBindings',\n        'where',\n        'withoutMiddleware',\n        'withoutScopedBindings',\n    ];\n\n    /**\n     * The attributes that are aliased.\n     *\n     * @var array\n     */\n    protected $aliases = [\n        'name' => 'as',\n        'scopeBindings' => 'scope_bindings',\n        'withoutScopedBindings' => 'scope_bindings',\n        'withoutMiddleware' => 'excluded_middleware',\n    ];\n\n    /**\n     * Create a new route registrar instance.\n     *\n     * @param  \\Illuminate\\Routing\\Router  $router\n     */\n    public function __construct(Router $router)\n    {\n        $this->router = $router;\n    }\n\n    /**\n     * Set the value for a given attribute.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function attribute($key, $value)\n    {\n        if (! in_array($key, $this->allowedAttributes)) {\n            throw new InvalidArgumentException(\"Attribute [{$key}] does not exist.\");\n        }\n\n        if ($key === 'middleware') {\n            $value = array_filter(Arr::wrap($value));\n\n            foreach ($value as $index => $middleware) {\n                $value[$index] = (string) $middleware;\n            }\n        }\n\n        $attributeKey = Arr::get($this->aliases, $key, $key);\n\n        if ($key === 'withoutMiddleware') {\n            $value = array_merge(\n                (array) ($this->attributes[$attributeKey] ?? []), Arr::wrap($value)\n            );\n        }\n\n        if ($key === 'withoutScopedBindings') {\n            $value = false;\n        }\n\n        if ($value instanceof BackedEnum && ! is_string($value = $value->value)) {\n            throw new InvalidArgumentException(\"Attribute [{$key}] expects a string backed enum.\");\n        }\n\n        $this->attributes[$attributeKey] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Route a resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function resource($name, $controller, array $options = [])\n    {\n        return $this->router->resource($name, $controller, $this->attributes + $options);\n    }\n\n    /**\n     * Route an API resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function apiResource($name, $controller, array $options = [])\n    {\n        return $this->router->apiResource($name, $controller, $this->attributes + $options);\n    }\n\n    /**\n     * Route a singleton resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function singleton($name, $controller, array $options = [])\n    {\n        return $this->router->singleton($name, $controller, $this->attributes + $options);\n    }\n\n    /**\n     * Route an API singleton resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function apiSingleton($name, $controller, array $options = [])\n    {\n        return $this->router->apiSingleton($name, $controller, $this->attributes + $options);\n    }\n\n    /**\n     * Create a route group with shared attributes.\n     *\n     * @param  \\Closure|array|string  $callback\n     * @return $this\n     */\n    public function group($callback)\n    {\n        $this->router->group($this->attributes, $callback);\n\n        return $this;\n    }\n\n    /**\n     * Register a new route with the given verbs.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  \\Closure|array|string|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function match($methods, $uri, $action = null)\n    {\n        return $this->router->match($methods, $uri, $this->compileAction($action));\n    }\n\n    /**\n     * Register a new route with the router.\n     *\n     * @param  string  $method\n     * @param  string  $uri\n     * @param  \\Closure|array|string|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function registerRoute($method, $uri, $action = null)\n    {\n        if (! is_array($action)) {\n            $action = array_merge($this->attributes, $action ? ['uses' => $action] : []);\n        }\n\n        return $this->router->{$method}($uri, $this->compileAction($action));\n    }\n\n    /**\n     * Compile the action into an array including the attributes.\n     *\n     * @param  \\Closure|array|string|null  $action\n     * @return array\n     */\n    protected function compileAction($action)\n    {\n        if (is_null($action)) {\n            return $this->attributes;\n        }\n\n        if (is_string($action) || $action instanceof Closure) {\n            $action = ['uses' => $action];\n        }\n\n        if (is_array($action) &&\n            array_is_list($action) &&\n            Reflector::isCallable($action)) {\n            if (strncmp($action[0], '\\\\', 1)) {\n                $action[0] = '\\\\'.$action[0];\n            }\n            $action = [\n                'uses' => $action[0].'@'.$action[1],\n                'controller' => $action[0].'@'.$action[1],\n            ];\n        }\n\n        return array_merge($this->attributes, $action);\n    }\n\n    /**\n     * Dynamically handle calls into the route registrar.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\Routing\\Route|$this\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (in_array($method, $this->passthru)) {\n            return $this->registerRoute($method, ...$parameters);\n        }\n\n        if (in_array($method, $this->allowedAttributes)) {\n            if ($method === 'middleware') {\n                return $this->attribute($method, is_array($parameters[0]) ? $parameters[0] : $parameters);\n            }\n\n            if ($method === 'can') {\n                return $this->attribute($method, [$parameters]);\n            }\n\n            return $this->attribute($method, array_key_exists(0, $parameters) ? $parameters[0] : true);\n        }\n\n        throw new BadMethodCallException(sprintf(\n            'Method %s::%s does not exist.', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteSignatureParameters.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Str;\nuse ReflectionFunction;\nuse ReflectionMethod;\n\nclass RouteSignatureParameters\n{\n    /**\n     * Extract the route action's signature parameters.\n     *\n     * @param  array  $action\n     * @param  array  $conditions\n     * @return array\n     */\n    public static function fromAction(array $action, $conditions = [])\n    {\n        $callback = RouteAction::containsSerializedClosure($action)\n            ? unserialize($action['uses'])->getClosure()\n            : $action['uses'];\n\n        $parameters = is_string($callback)\n            ? static::fromClassMethodString($callback)\n            : (new ReflectionFunction($callback))->getParameters();\n\n        return match (true) {\n            ! empty($conditions['subClass']) => array_filter($parameters, fn ($p) => Reflector::isParameterSubclassOf($p, $conditions['subClass'])),\n            ! empty($conditions['backedEnum']) => array_filter($parameters, fn ($p) => Reflector::isParameterBackedEnumWithStringBackingType($p)),\n            default => $parameters,\n        };\n    }\n\n    /**\n     * Get the parameters for the given class / method by string.\n     *\n     * @param  string  $uses\n     * @return array\n     */\n    protected static function fromClassMethodString($uses)\n    {\n        [$class, $method] = Str::parseCallback($uses);\n\n        if (! method_exists($class, $method) && Reflector::isCallable($class, $method)) {\n            return [];\n        }\n\n        return (new ReflectionMethod($class, $method))->getParameters();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteUri.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nclass RouteUri\n{\n    /**\n     * The route URI.\n     *\n     * @var string\n     */\n    public $uri;\n\n    /**\n     * The fields that should be used when resolving bindings.\n     *\n     * @var array\n     */\n    public $bindingFields = [];\n\n    /**\n     * Create a new route URI instance.\n     *\n     * @param  string  $uri\n     * @param  array  $bindingFields\n     */\n    public function __construct(string $uri, array $bindingFields = [])\n    {\n        $this->uri = $uri;\n        $this->bindingFields = $bindingFields;\n    }\n\n    /**\n     * Parse the given URI.\n     *\n     * @param  string  $uri\n     * @return static\n     */\n    public static function parse($uri)\n    {\n        preg_match_all('/\\{([\\w\\:]+?)\\??\\}/', $uri, $matches);\n\n        $bindingFields = [];\n\n        foreach ($matches[0] as $match) {\n            if (! str_contains($match, ':')) {\n                continue;\n            }\n\n            $segments = explode(':', trim($match, '{}?'));\n\n            $bindingFields[$segments[0]] = $segments[1];\n\n            $uri = str_contains($match, '?')\n                ? str_replace($match, '{'.$segments[0].'?}', $uri)\n                : str_replace($match, '{'.$segments[0].'}', $uri);\n        }\n\n        return new static($uri, $bindingFields);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RouteUrlGenerator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse BackedEnum;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Routing\\Exceptions\\UrlGenerationException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\n\nclass RouteUrlGenerator\n{\n    /**\n     * The URL generator instance.\n     *\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    protected $url;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * The named parameter defaults.\n     *\n     * @var array\n     */\n    public $defaultParameters = [];\n\n    /**\n     * Characters that should not be URL encoded.\n     *\n     * @var array\n     */\n    public $dontEncode = [\n        '%2F' => '/',\n        '%40' => '@',\n        '%3A' => ':',\n        '%3B' => ';',\n        '%2C' => ',',\n        '%3D' => '=',\n        '%2B' => '+',\n        '%21' => '!',\n        '%2A' => '*',\n        '%7C' => '|',\n        '%3F' => '?',\n        '%26' => '&',\n        '%23' => '#',\n        '%25' => '%',\n    ];\n\n    /**\n     * Create a new Route URL generator.\n     *\n     * @param  \\Illuminate\\Routing\\UrlGenerator  $url\n     * @param  \\Illuminate\\Http\\Request  $request\n     */\n    public function __construct($url, $request)\n    {\n        $this->url = $url;\n        $this->request = $request;\n    }\n\n    /**\n     * Generate a URL for the given route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $parameters\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\UrlGenerationException\n     */\n    public function to($route, $parameters = [], $absolute = false)\n    {\n        $parameters = $this->formatParameters($route, $parameters);\n\n        $domain = $this->getRouteDomain($route, $parameters);\n\n        // First we will construct the entire URI including the root and query string. Once it\n        // has been constructed, we'll make sure we don't have any missing parameters or we\n        // will need to throw the exception to let the developers know one was not given.\n        $uri = $this->addQueryString($this->url->format(\n            $root = $this->replaceRootParameters($route, $domain, $parameters),\n            $this->replaceRouteParameters($route->uri(), $parameters),\n            $route\n        ), $parameters);\n\n        if (preg_match_all('/{(.*?)}/', $uri, $matchedMissingParameters)) {\n            throw UrlGenerationException::forMissingParameters($route, $matchedMissingParameters[1]);\n        }\n\n        // Once we have ensured that there are no missing parameters in the URI we will encode\n        // the URI and prepare it for returning to the developer. If the URI is supposed to\n        // be absolute, we will return it as-is. Otherwise we will remove the URL's root.\n        $uri = strtr(rawurlencode($uri), $this->dontEncode);\n\n        if (! $absolute) {\n            $uri = preg_replace('#^(//|[^/?])+#', '', $uri);\n\n            if ($base = $this->request->getBaseUrl()) {\n                $uri = preg_replace('#^'.$base.'#i', '', $uri);\n            }\n\n            return '/'.ltrim($uri, '/');\n        }\n\n        return $uri;\n    }\n\n    /**\n     * Get the formatted domain for a given route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $parameters\n     * @return string|null\n     */\n    protected function getRouteDomain($route, &$parameters)\n    {\n        return $route->getDomain() ? $this->formatDomain($route, $parameters) : null;\n    }\n\n    /**\n     * Format the domain and port for the route and request.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function formatDomain($route, &$parameters)\n    {\n        return $this->addPortToDomain(\n            $this->getRouteScheme($route).$route->getDomain()\n        );\n    }\n\n    /**\n     * Get the scheme for the given route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return string\n     */\n    protected function getRouteScheme($route)\n    {\n        if ($route->httpOnly()) {\n            return 'http://';\n        } elseif ($route->httpsOnly()) {\n            return 'https://';\n        }\n\n        return $this->url->formatScheme();\n    }\n\n    /**\n     * Add the port to the domain if necessary.\n     *\n     * @param  string  $domain\n     * @return string\n     */\n    protected function addPortToDomain($domain)\n    {\n        $secure = $this->request->isSecure();\n\n        $port = (int) $this->request->getPort();\n\n        return ($secure && $port === 443) || (! $secure && $port === 80)\n            ? $domain\n            : $domain.':'.$port;\n    }\n\n    /**\n     * Format the array of route parameters.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $parameters\n     * @return array\n     */\n    protected function formatParameters(Route $route, $parameters)\n    {\n        $parameters = Arr::wrap($parameters);\n\n        $namedParameters = [];\n        $namedQueryParameters = [];\n        $requiredRouteParametersWithoutDefaultsOrNamedParameters = [];\n\n        $routeParameters = $route->parameterNames();\n        $optionalParameters = $route->getOptionalParameterNames();\n\n        foreach ($routeParameters as $name) {\n            if (isset($parameters[$name])) {\n                // Named parameters don't need any special handling...\n                $namedParameters[$name] = $parameters[$name];\n                unset($parameters[$name]);\n\n                continue;\n            } else {\n                $bindingField = $route->bindingFieldFor($name);\n                $defaultParameterKey = $bindingField ? \"$name:$bindingField\" : $name;\n\n                if (! isset($this->defaultParameters[$defaultParameterKey]) && ! isset($optionalParameters[$name])) {\n                    // No named parameter or default value for a required parameter, try to match to positional parameter below...\n                    array_push($requiredRouteParametersWithoutDefaultsOrNamedParameters, $name);\n                }\n            }\n\n            $namedParameters[$name] = '';\n        }\n\n        // Named parameters that don't have route parameters will be used for query string...\n        foreach ($parameters as $key => $value) {\n            if (is_string($key)) {\n                $namedQueryParameters[$key] = $value;\n\n                unset($parameters[$key]);\n            }\n        }\n\n        // Match positional parameters to the route parameters that didn't have a value in order...\n        if (count($parameters) == count($requiredRouteParametersWithoutDefaultsOrNamedParameters)) {\n            foreach (array_reverse($requiredRouteParametersWithoutDefaultsOrNamedParameters) as $name) {\n                if (count($parameters) === 0) {\n                    break;\n                }\n\n                $namedParameters[$name] = array_pop($parameters);\n            }\n        }\n\n        $offset = 0;\n        $emptyParameters = array_filter($namedParameters, static fn ($val) => $val === '');\n\n        if (count($requiredRouteParametersWithoutDefaultsOrNamedParameters) !== 0 &&\n            count($parameters) !== count($emptyParameters)) {\n            // Find the index of the first required parameter...\n            $offset = array_search($requiredRouteParametersWithoutDefaultsOrNamedParameters[0], array_keys($namedParameters));\n\n            // If more empty parameters remain, adjust the offset...\n            $remaining = count($emptyParameters) - $offset - count($parameters);\n\n            if ($remaining < 0) {\n                // Effectively subtract the remaining count since it's negative...\n                $offset += $remaining;\n            }\n\n            // Correct offset if it goes below zero...\n            if ($offset < 0) {\n                $offset = 0;\n            }\n        } elseif (count($requiredRouteParametersWithoutDefaultsOrNamedParameters) === 0 && count($parameters) !== 0) {\n            // Handle the case where all passed parameters are for parameters that have default values...\n            $remainingCount = count($parameters);\n\n            // Loop over empty parameters backwards and stop when we run out of passed parameters...\n            for ($i = count($namedParameters) - 1; $i >= 0; $i--) {\n                if ($namedParameters[array_keys($namedParameters)[$i]] === '') {\n                    $offset = $i;\n                    $remainingCount--;\n\n                    if ($remainingCount === 0) {\n                        // If there are no more passed parameters, we stop here...\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Starting from the offset, match any passed parameters from left to right...\n        for ($i = $offset; $i < count($namedParameters); $i++) {\n            $key = array_keys($namedParameters)[$i];\n\n            if ($namedParameters[$key] !== '') {\n                continue;\n            } elseif (! empty($parameters)) {\n                $namedParameters[$key] = array_shift($parameters);\n            }\n        }\n\n        // Fill leftmost parameters with defaults if the loop above was offset...\n        foreach ($namedParameters as $key => $value) {\n            $bindingField = $route->bindingFieldFor($key);\n            $defaultParameterKey = $bindingField ? \"$key:$bindingField\" : $key;\n\n            if ($value === '' && isset($this->defaultParameters[$defaultParameterKey])) {\n                $namedParameters[$key] = $this->defaultParameters[$defaultParameterKey];\n            }\n        }\n\n        // Any remaining values in $parameters are unnamed query string parameters...\n        $parameters = array_merge($namedParameters, $namedQueryParameters, $parameters);\n\n        $parameters = Collection::wrap($parameters)->map(function ($value, $key) use ($route) {\n            return $value instanceof UrlRoutable && $route->bindingFieldFor($key)\n                    ? $value->{$route->bindingFieldFor($key)}\n                    : $value;\n        })->all();\n\n        array_walk_recursive($parameters, function (&$item) {\n            if ($item instanceof BackedEnum) {\n                $item = $item->value;\n            }\n        });\n\n        return $this->url->formatParameters($parameters);\n    }\n\n    /**\n     * Replace the parameters on the root path.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  string  $domain\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function replaceRootParameters($route, $domain, &$parameters)\n    {\n        $scheme = $this->getRouteScheme($route);\n\n        return $this->replaceRouteParameters(\n            $this->url->formatRoot($scheme, $domain), $parameters\n        );\n    }\n\n    /**\n     * Replace all of the wildcard parameters for a route path.\n     *\n     * @param  string  $path\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function replaceRouteParameters($path, array &$parameters)\n    {\n        $path = $this->replaceNamedParameters($path, $parameters);\n\n        $path = preg_replace_callback('/\\{.*?\\}/', function ($match) use (&$parameters) {\n            // Reset only the numeric keys...\n            $parameters = array_merge($parameters);\n\n            return (! isset($parameters[0]) && ! str_ends_with($match[0], '?}'))\n                ? $match[0]\n                : Arr::pull($parameters, 0);\n        }, $path);\n\n        return trim(preg_replace('/\\{.*?\\?\\}/', '', $path), '/');\n    }\n\n    /**\n     * Replace all of the named parameters in the path.\n     *\n     * @param  string  $path\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function replaceNamedParameters($path, &$parameters)\n    {\n        return preg_replace_callback('/\\{(.*?)(\\?)?\\}/', function ($m) use (&$parameters) {\n            if (isset($parameters[$m[1]]) && $parameters[$m[1]] !== '') {\n                return Arr::pull($parameters, $m[1]);\n            } elseif (isset($this->defaultParameters[$m[1]])) {\n                return $this->defaultParameters[$m[1]];\n            } elseif (isset($parameters[$m[1]])) {\n                Arr::pull($parameters, $m[1]);\n            }\n\n            return $m[0];\n        }, $path);\n    }\n\n    /**\n     * Add a query string to the URI.\n     *\n     * @param  string  $uri\n     * @param  array  $parameters\n     * @return mixed\n     */\n    protected function addQueryString($uri, array $parameters)\n    {\n        // If the URI has a fragment we will move it to the end of this URI since it will\n        // need to come after any query string that may be added to the URL else it is\n        // not going to be available. We will remove it then append it back on here.\n        if (! is_null($fragment = parse_url($uri, PHP_URL_FRAGMENT))) {\n            $uri = preg_replace('/#.*/', '', $uri);\n        }\n\n        $uri .= $this->getRouteQueryString($parameters);\n\n        return is_null($fragment) ? $uri : $uri.\"#{$fragment}\";\n    }\n\n    /**\n     * Get the query string for a given route.\n     *\n     * @param  array  $parameters\n     * @return string\n     */\n    protected function getRouteQueryString(array $parameters)\n    {\n        // First we will get all of the string parameters that are remaining after we\n        // have replaced the route wildcards. We'll then build a query string from\n        // these string parameters then use it as a starting point for the rest.\n        if (count($parameters) === 0) {\n            return '';\n        }\n\n        $query = Arr::query(\n            $keyed = $this->getStringParameters($parameters)\n        );\n\n        // Lastly, if there are still parameters remaining, we will fetch the numeric\n        // parameters that are in the array and add them to the query string or we\n        // will make the initial query string if it wasn't started with strings.\n        if (count($keyed) < count($parameters)) {\n            $query .= '&'.implode(\n                '&', $this->getNumericParameters($parameters)\n            );\n        }\n\n        $query = trim($query, '&');\n\n        return $query === '' ? '' : \"?{$query}\";\n    }\n\n    /**\n     * Get the string parameters from a given list.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function getStringParameters(array $parameters)\n    {\n        return array_filter($parameters, 'is_string', ARRAY_FILTER_USE_KEY);\n    }\n\n    /**\n     * Get the numeric parameters from a given list.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function getNumericParameters(array $parameters)\n    {\n        return array_filter($parameters, 'is_numeric', ARRAY_FILTER_USE_KEY);\n    }\n\n    /**\n     * Set the default named parameters used by the URL generator.\n     *\n     * @param  array  $defaults\n     * @return void\n     */\n    public function defaults(array $defaults)\n    {\n        $this->defaultParameters = array_merge(\n            $this->defaultParameters, $defaults\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/Router.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse ArrayObject;\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Routing\\BindingRegistrar;\nuse Illuminate\\Contracts\\Routing\\Registrar as RegistrarContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\Events\\PreparingResponse;\nuse Illuminate\\Routing\\Events\\ResponsePrepared;\nuse Illuminate\\Routing\\Events\\RouteMatched;\nuse Illuminate\\Routing\\Events\\Routing;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse JsonSerializable;\nuse Psr\\Http\\Message\\ResponseInterface as PsrResponseInterface;\nuse ReflectionClass;\nuse stdClass;\nuse Symfony\\Bridge\\PsrHttpMessage\\Factory\\HttpFoundationFactory;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\n\n/**\n * @mixin \\Illuminate\\Routing\\RouteRegistrar\n */\nclass Router implements BindingRegistrar, RegistrarContract\n{\n    use Macroable {\n        __call as macroCall;\n    }\n    use Tappable;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The route collection instance.\n     *\n     * @var \\Illuminate\\Routing\\RouteCollectionInterface\n     */\n    protected $routes;\n\n    /**\n     * The currently dispatched route instance.\n     *\n     * @var \\Illuminate\\Routing\\Route|null\n     */\n    protected $current;\n\n    /**\n     * The request currently being dispatched.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $currentRequest;\n\n    /**\n     * All of the short-hand keys for middlewares.\n     *\n     * @var array\n     */\n    protected $middleware = [];\n\n    /**\n     * All of the middleware groups.\n     *\n     * @var array\n     */\n    protected $middlewareGroups = [];\n\n    /**\n     * The priority-sorted list of middleware.\n     *\n     * Forces the listed middleware to always be in the given order.\n     *\n     * @var array\n     */\n    public $middlewarePriority = [];\n\n    /**\n     * The registered route value binders.\n     *\n     * @var array\n     */\n    protected $binders = [];\n\n    /**\n     * The globally available parameter patterns.\n     *\n     * @var array\n     */\n    protected $patterns = [];\n\n    /**\n     * The route group attribute stack.\n     *\n     * @var array\n     */\n    protected $groupStack = [];\n\n    /**\n     * The registered custom implicit binding callback.\n     *\n     * @var array\n     */\n    protected $implicitBindingCallback;\n\n    /**\n     * All of the verbs supported by the router.\n     *\n     * @var string[]\n     */\n    public static $verbs = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];\n\n    /**\n     * Create a new Router instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @param  \\Illuminate\\Container\\Container|null  $container\n     */\n    public function __construct(Dispatcher $events, ?Container $container = null)\n    {\n        $this->events = $events;\n        $this->routes = new RouteCollection;\n        $this->container = $container ?: new Container;\n    }\n\n    /**\n     * Register a new GET route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function get($uri, $action = null)\n    {\n        return $this->addRoute(['GET', 'HEAD'], $uri, $action);\n    }\n\n    /**\n     * Register a new POST route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function post($uri, $action = null)\n    {\n        return $this->addRoute('POST', $uri, $action);\n    }\n\n    /**\n     * Register a new PUT route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function put($uri, $action = null)\n    {\n        return $this->addRoute('PUT', $uri, $action);\n    }\n\n    /**\n     * Register a new PATCH route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function patch($uri, $action = null)\n    {\n        return $this->addRoute('PATCH', $uri, $action);\n    }\n\n    /**\n     * Register a new DELETE route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function delete($uri, $action = null)\n    {\n        return $this->addRoute('DELETE', $uri, $action);\n    }\n\n    /**\n     * Register a new OPTIONS route with the router.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function options($uri, $action = null)\n    {\n        return $this->addRoute('OPTIONS', $uri, $action);\n    }\n\n    /**\n     * Register a new route responding to all verbs.\n     *\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function any($uri, $action = null)\n    {\n        return $this->addRoute(self::$verbs, $uri, $action);\n    }\n\n    /**\n     * Register a new fallback route with the router.\n     *\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function fallback($action)\n    {\n        $placeholder = 'fallbackPlaceholder';\n\n        return $this->addRoute(\n            'GET', \"{{$placeholder}}\", $action\n        )->where($placeholder, '.*')->fallback();\n    }\n\n    /**\n     * Create a redirect from one URI to another.\n     *\n     * @param  string  $uri\n     * @param  string  $destination\n     * @param  int  $status\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function redirect($uri, $destination, $status = 302)\n    {\n        return $this->any($uri, '\\Illuminate\\Routing\\RedirectController')\n            ->defaults('destination', $destination)\n            ->defaults('status', $status);\n    }\n\n    /**\n     * Create a permanent redirect from one URI to another.\n     *\n     * @param  string  $uri\n     * @param  string  $destination\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function permanentRedirect($uri, $destination)\n    {\n        return $this->redirect($uri, $destination, 301);\n    }\n\n    /**\n     * Register a new route that returns a view.\n     *\n     * @param  string  $uri\n     * @param  string  $view\n     * @param  array  $data\n     * @param  int|array  $status\n     * @param  array  $headers\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function view($uri, $view, $data = [], $status = 200, array $headers = [])\n    {\n        return $this->match(['GET', 'HEAD'], $uri, '\\Illuminate\\Routing\\ViewController')\n            ->setDefaults([\n                'view' => $view,\n                'data' => $data,\n                'status' => is_array($status) ? 200 : $status,\n                'headers' => is_array($status) ? $status : $headers,\n            ]);\n    }\n\n    /**\n     * Register a new route with the given verbs.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function match($methods, $uri, $action = null)\n    {\n        return $this->addRoute(array_map(strtoupper(...), (array) $methods), $uri, $action);\n    }\n\n    /**\n     * Register an array of resource controllers.\n     *\n     * @param  array  $resources\n     * @param  array  $options\n     * @return void\n     */\n    public function resources(array $resources, array $options = [])\n    {\n        foreach ($resources as $name => $controller) {\n            $this->resource($name, $controller, $options);\n        }\n    }\n\n    /**\n     * Register an array of resource controllers that can be soft deleted.\n     *\n     * @param  array  $resources\n     * @param  array  $options\n     * @return void\n     */\n    public function softDeletableResources(array $resources, array $options = [])\n    {\n        foreach ($resources as $name => $controller) {\n            $this->resource($name, $controller, $options)->withTrashed();\n        }\n    }\n\n    /**\n     * Route a resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function resource($name, $controller, array $options = [])\n    {\n        if ($this->container && $this->container->bound(ResourceRegistrar::class)) {\n            $registrar = $this->container->make(ResourceRegistrar::class);\n        } else {\n            $registrar = new ResourceRegistrar($this);\n        }\n\n        return new PendingResourceRegistration(\n            $registrar, $name, $controller, $options\n        );\n    }\n\n    /**\n     * Register an array of API resource controllers.\n     *\n     * @param  array  $resources\n     * @param  array  $options\n     * @return void\n     */\n    public function apiResources(array $resources, array $options = [])\n    {\n        foreach ($resources as $name => $controller) {\n            $this->apiResource($name, $controller, $options);\n        }\n    }\n\n    /**\n     * Route an API resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingResourceRegistration\n     */\n    public function apiResource($name, $controller, array $options = [])\n    {\n        $only = ['index', 'show', 'store', 'update', 'destroy'];\n\n        if (isset($options['except'])) {\n            $only = array_diff($only, (array) $options['except']);\n        }\n\n        return $this->resource($name, $controller, array_merge([\n            'only' => $only,\n        ], $options));\n    }\n\n    /**\n     * Register an array of singleton resource controllers.\n     *\n     * @param  array  $singletons\n     * @param  array  $options\n     * @return void\n     */\n    public function singletons(array $singletons, array $options = [])\n    {\n        foreach ($singletons as $name => $controller) {\n            $this->singleton($name, $controller, $options);\n        }\n    }\n\n    /**\n     * Route a singleton resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function singleton($name, $controller, array $options = [])\n    {\n        if ($this->container && $this->container->bound(ResourceRegistrar::class)) {\n            $registrar = $this->container->make(ResourceRegistrar::class);\n        } else {\n            $registrar = new ResourceRegistrar($this);\n        }\n\n        return new PendingSingletonResourceRegistration(\n            $registrar, $name, $controller, $options\n        );\n    }\n\n    /**\n     * Register an array of API singleton resource controllers.\n     *\n     * @param  array  $singletons\n     * @param  array  $options\n     * @return void\n     */\n    public function apiSingletons(array $singletons, array $options = [])\n    {\n        foreach ($singletons as $name => $controller) {\n            $this->apiSingleton($name, $controller, $options);\n        }\n    }\n\n    /**\n     * Route an API singleton resource to a controller.\n     *\n     * @param  string  $name\n     * @param  string  $controller\n     * @param  array  $options\n     * @return \\Illuminate\\Routing\\PendingSingletonResourceRegistration\n     */\n    public function apiSingleton($name, $controller, array $options = [])\n    {\n        $only = ['store', 'show', 'update', 'destroy'];\n\n        if (isset($options['except'])) {\n            $only = array_diff($only, (array) $options['except']);\n        }\n\n        return $this->singleton($name, $controller, array_merge([\n            'only' => $only,\n        ], $options));\n    }\n\n    /**\n     * Create a route group with shared attributes.\n     *\n     * @param  array  $attributes\n     * @param  \\Closure|array|string  $routes\n     * @return $this\n     */\n    public function group(array $attributes, $routes)\n    {\n        foreach (Arr::wrap($routes) as $groupRoutes) {\n            $this->updateGroupStack($attributes);\n\n            // Once we have updated the group stack, we'll load the provided routes and\n            // merge in the group's attributes when the routes are created. After we\n            // have created the routes, we will pop the attributes off the stack.\n            $this->loadRoutes($groupRoutes);\n\n            array_pop($this->groupStack);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Update the group stack with the given attributes.\n     *\n     * @param  array  $attributes\n     * @return void\n     */\n    protected function updateGroupStack(array $attributes)\n    {\n        if ($this->hasGroupStack()) {\n            $attributes = $this->mergeWithLastGroup($attributes);\n        }\n\n        $this->groupStack[] = $attributes;\n    }\n\n    /**\n     * Merge the given array with the last group stack.\n     *\n     * @param  array  $new\n     * @param  bool  $prependExistingPrefix\n     * @return array\n     */\n    public function mergeWithLastGroup($new, $prependExistingPrefix = true)\n    {\n        return RouteGroup::merge($new, array_last($this->groupStack), $prependExistingPrefix);\n    }\n\n    /**\n     * Load the provided routes.\n     *\n     * @param  \\Closure|string  $routes\n     * @return void\n     */\n    protected function loadRoutes($routes)\n    {\n        if ($routes instanceof Closure) {\n            $routes($this);\n        } else {\n            (new RouteFileRegistrar($this))->register($routes);\n        }\n    }\n\n    /**\n     * Get the prefix from the last group on the stack.\n     *\n     * @return string\n     */\n    public function getLastGroupPrefix()\n    {\n        if ($this->hasGroupStack()) {\n            $last = array_last($this->groupStack);\n\n            return $last['prefix'] ?? '';\n        }\n\n        return '';\n    }\n\n    /**\n     * Add a route to the underlying route collection.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  array|string|callable|null  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function addRoute($methods, $uri, $action)\n    {\n        return $this->routes->add($this->createRoute($methods, $uri, $action));\n    }\n\n    /**\n     * Create a new route instance.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  mixed  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function createRoute($methods, $uri, $action)\n    {\n        // If the route is routing to a controller we will parse the route action into\n        // an acceptable array format before registering it and creating this route\n        // instance itself. We need to build the Closure that will call this out.\n        if ($this->actionReferencesController($action)) {\n            $action = $this->convertToControllerAction($action);\n        }\n\n        $route = $this->newRoute(\n            $methods, $this->prefix($uri), $action\n        );\n\n        // If we have groups that need to be merged, we will merge them now after this\n        // route has already been created and is ready to go. After we're done with\n        // the merge we will be ready to return the route back out to the caller.\n        if ($this->hasGroupStack()) {\n            $this->mergeGroupAttributesIntoRoute($route);\n        }\n\n        $this->addWhereClausesToRoute($route);\n\n        return $route;\n    }\n\n    /**\n     * Determine if the action is routing to a controller.\n     *\n     * @param  mixed  $action\n     * @return bool\n     */\n    protected function actionReferencesController($action)\n    {\n        if (! $action instanceof Closure) {\n            return is_string($action) || (isset($action['uses']) && is_string($action['uses']));\n        }\n\n        return false;\n    }\n\n    /**\n     * Add a controller based route action to the action array.\n     *\n     * @param  array|string  $action\n     * @return array\n     */\n    protected function convertToControllerAction($action)\n    {\n        if (is_string($action)) {\n            $action = ['uses' => $action];\n        }\n\n        // Here we'll merge any group \"controller\" and \"uses\" statements if necessary so that\n        // the action has the proper clause for this property. Then, we can simply set the\n        // name of this controller on the action plus return the action array for usage.\n        if ($this->hasGroupStack()) {\n            $action['uses'] = $this->prependGroupController($action['uses']);\n            $action['uses'] = $this->prependGroupNamespace($action['uses']);\n        }\n\n        // Here we will set this controller name on the action array just so we always\n        // have a copy of it for reference if we need it. This can be used while we\n        // search for a controller name or do some other type of fetch operation.\n        $action['controller'] = $action['uses'];\n\n        return $action;\n    }\n\n    /**\n     * Prepend the last group namespace onto the use clause.\n     *\n     * @param  string  $class\n     * @return string\n     */\n    protected function prependGroupNamespace($class)\n    {\n        $group = array_last($this->groupStack);\n\n        return isset($group['namespace']) && ! str_starts_with($class, '\\\\') && ! str_starts_with($class, $group['namespace'])\n            ? $group['namespace'].'\\\\'.$class\n            : $class;\n    }\n\n    /**\n     * Prepend the last group controller onto the use clause.\n     *\n     * @param  string  $class\n     * @return string\n     */\n    protected function prependGroupController($class)\n    {\n        $group = array_last($this->groupStack);\n\n        if (! isset($group['controller'])) {\n            return $class;\n        }\n\n        if (class_exists($class)) {\n            return $class;\n        }\n\n        if (str_contains($class, '@')) {\n            return $class;\n        }\n\n        return $group['controller'].'@'.$class;\n    }\n\n    /**\n     * Create a new Route object.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  mixed  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    public function newRoute($methods, $uri, $action)\n    {\n        return (new Route($methods, $uri, $action))\n            ->setRouter($this)\n            ->setContainer($this->container);\n    }\n\n    /**\n     * Prefix the given URI with the last prefix.\n     *\n     * @param  string  $uri\n     * @return string\n     */\n    protected function prefix($uri)\n    {\n        return trim(trim($this->getLastGroupPrefix(), '/').'/'.trim($uri, '/'), '/') ?: '/';\n    }\n\n    /**\n     * Add the necessary where clauses to the route based on its initial registration.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function addWhereClausesToRoute($route)\n    {\n        $route->where(array_merge(\n            $this->patterns, $route->getAction()['where'] ?? []\n        ));\n\n        return $route;\n    }\n\n    /**\n     * Merge the group stack with the controller action.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     */\n    protected function mergeGroupAttributesIntoRoute($route)\n    {\n        $route->setAction($this->mergeWithLastGroup(\n            $route->getAction(),\n            prependExistingPrefix: false\n        ));\n    }\n\n    /**\n     * Return the response returned by the given route.\n     *\n     * @param  string  $name\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function respondWithRoute($name)\n    {\n        $route = tap($this->routes->getByName($name))->bind($this->currentRequest);\n\n        return $this->runRoute($this->currentRequest, $route);\n    }\n\n    /**\n     * Dispatch the request to the application.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function dispatch(Request $request)\n    {\n        $this->currentRequest = $request;\n\n        return $this->dispatchToRoute($request);\n    }\n\n    /**\n     * Dispatch the request to a route and return the response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function dispatchToRoute(Request $request)\n    {\n        return $this->runRoute($request, $this->findRoute($request));\n    }\n\n    /**\n     * Find the route matching a given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function findRoute($request)\n    {\n        $this->events->dispatch(new Routing($request));\n\n        $this->current = $route = $this->routes->match($request);\n\n        $route->setContainer($this->container);\n\n        $this->container->instance(Route::class, $route);\n\n        return $route;\n    }\n\n    /**\n     * Return the response for the given route.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    protected function runRoute(Request $request, Route $route)\n    {\n        $request->setRouteResolver(fn () => $route);\n\n        $this->events->dispatch(new RouteMatched($route, $request));\n\n        return $this->prepareResponse($request,\n            $this->runRouteWithinStack($route, $request)\n        );\n    }\n\n    /**\n     * Run the given route within a Stack \"onion\" instance.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return mixed\n     */\n    protected function runRouteWithinStack(Route $route, Request $request)\n    {\n        $shouldSkipMiddleware = $this->container->bound('middleware.disable') &&\n                                $this->container->make('middleware.disable') === true;\n\n        $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route);\n\n        return (new Pipeline($this->container))\n            ->send($request)\n            ->through($middleware)\n            ->then(fn ($request) => $this->prepareResponse(\n                $request, $route->run()\n            ));\n    }\n\n    /**\n     * Gather the middleware for the given route with resolved class names.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return array\n     */\n    public function gatherRouteMiddleware(Route $route)\n    {\n        return $this->resolveMiddleware($route->gatherMiddleware(), $route->excludedMiddleware());\n    }\n\n    /**\n     * Resolve a flat array of middleware classes from the provided array.\n     *\n     * @param  array  $middleware\n     * @param  array  $excluded\n     * @return array\n     */\n    public function resolveMiddleware(array $middleware, array $excluded = [])\n    {\n        $excluded = $excluded === []\n            ? $excluded\n            : (new Collection($excluded))\n                ->map(fn ($name) => (array) MiddlewareNameResolver::resolve($name, $this->middleware, $this->middlewareGroups))\n                ->flatten()\n                ->values()\n                ->all();\n\n        $middleware = (new Collection($middleware))\n            ->map(fn ($name) => (array) MiddlewareNameResolver::resolve($name, $this->middleware, $this->middlewareGroups))\n            ->flatten()\n            ->when(\n                ! empty($excluded),\n                fn ($collection) => $collection->reject(function ($name) use ($excluded) {\n                    if ($name instanceof Closure) {\n                        return false;\n                    }\n\n                    if (in_array($name, $excluded, true)) {\n                        return true;\n                    }\n\n                    if (! class_exists($name)) {\n                        return false;\n                    }\n\n                    $reflection = new ReflectionClass($name);\n\n                    return (new Collection($excluded))->contains(\n                        fn ($exclude) => class_exists($exclude) && $reflection->isSubclassOf($exclude)\n                    );\n                })\n            )\n            ->values();\n\n        return $this->sortMiddleware($middleware);\n    }\n\n    /**\n     * Sort the given middleware by priority.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $middlewares\n     * @return array\n     */\n    protected function sortMiddleware(Collection $middlewares)\n    {\n        return (new SortedMiddleware($this->middlewarePriority, $middlewares))->all();\n    }\n\n    /**\n     * Create a response instance from the given value.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @param  mixed  $response\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function prepareResponse($request, $response)\n    {\n        $this->events->dispatch(new PreparingResponse($request, $response));\n\n        return tap(static::toResponse($request, $response), function ($response) use ($request) {\n            $this->events->dispatch(new ResponsePrepared($request, $response));\n        });\n    }\n\n    /**\n     * Static version of prepareResponse.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @param  mixed  $response\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public static function toResponse($request, $response)\n    {\n        if ($response instanceof Responsable) {\n            $response = $response->toResponse($request);\n        }\n\n        if ($response instanceof PsrResponseInterface) {\n            $response = (new HttpFoundationFactory)->createResponse($response);\n        } elseif ($response instanceof Model && $response->wasRecentlyCreated) {\n            $response = new JsonResponse($response, 201);\n        } elseif ($response instanceof Stringable) {\n            $response = new Response($response->__toString(), 200, ['Content-Type' => 'text/html']);\n        } elseif (! $response instanceof SymfonyResponse &&\n                   ($response instanceof Arrayable ||\n                    $response instanceof Jsonable ||\n                    $response instanceof ArrayObject ||\n                    $response instanceof JsonSerializable ||\n                    $response instanceof stdClass ||\n                    is_array($response))) {\n            $response = new JsonResponse($response);\n        } elseif (! $response instanceof SymfonyResponse) {\n            $response = new Response($response, 200, ['Content-Type' => 'text/html']);\n        }\n\n        if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) {\n            $response->setNotModified();\n        }\n\n        return $response->prepare($request);\n    }\n\n    /**\n     * Substitute the route bindings onto the route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return \\Illuminate\\Routing\\Route\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<\\Illuminate\\Database\\Eloquent\\Model>\n     * @throws \\Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException\n     */\n    public function substituteBindings($route)\n    {\n        foreach ($route->parameters() as $key => $value) {\n            if (isset($this->binders[$key])) {\n                $route->setParameter($key, $this->performBinding($key, $value, $route));\n            }\n        }\n\n        return $route;\n    }\n\n    /**\n     * Substitute the implicit route bindings for the given route.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return void\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<\\Illuminate\\Database\\Eloquent\\Model>\n     * @throws \\Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException\n     */\n    public function substituteImplicitBindings($route)\n    {\n        $default = fn () => ImplicitRouteBinding::resolveForRoute($this->container, $route);\n\n        return call_user_func(\n            $this->implicitBindingCallback ?? $default, $this->container, $route, $default\n        );\n    }\n\n    /**\n     * Register a callback to run after implicit bindings are substituted.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function substituteImplicitBindingsUsing($callback)\n    {\n        $this->implicitBindingCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Call the binding callback for the given key.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<\\Illuminate\\Database\\Eloquent\\Model>\n     */\n    protected function performBinding($key, $value, $route)\n    {\n        return call_user_func($this->binders[$key], $value, $route);\n    }\n\n    /**\n     * Register a route matched event listener.\n     *\n     * @param  string|callable  $callback\n     * @return void\n     */\n    public function matched($callback)\n    {\n        $this->events->listen(Events\\RouteMatched::class, $callback);\n    }\n\n    /**\n     * Get all of the defined middleware short-hand names.\n     *\n     * @return array\n     */\n    public function getMiddleware()\n    {\n        return $this->middleware;\n    }\n\n    /**\n     * Register a short-hand name for a middleware.\n     *\n     * @param  string  $name\n     * @param  string  $class\n     * @return $this\n     */\n    public function aliasMiddleware($name, $class)\n    {\n        $this->middleware[$name] = $class;\n\n        return $this;\n    }\n\n    /**\n     * Check if a middlewareGroup with the given name exists.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasMiddlewareGroup($name)\n    {\n        return array_key_exists($name, $this->middlewareGroups);\n    }\n\n    /**\n     * Get all of the defined middleware groups.\n     *\n     * @return array\n     */\n    public function getMiddlewareGroups()\n    {\n        return $this->middlewareGroups;\n    }\n\n    /**\n     * Register a group of middleware.\n     *\n     * @param  string  $name\n     * @param  array  $middleware\n     * @return $this\n     */\n    public function middlewareGroup($name, array $middleware)\n    {\n        $this->middlewareGroups[$name] = $middleware;\n\n        return $this;\n    }\n\n    /**\n     * Add a middleware to the beginning of a middleware group.\n     *\n     * If the middleware is already in the group, it will not be added again.\n     *\n     * @param  string  $group\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function prependMiddlewareToGroup($group, $middleware)\n    {\n        if (isset($this->middlewareGroups[$group]) && ! in_array($middleware, $this->middlewareGroups[$group])) {\n            array_unshift($this->middlewareGroups[$group], $middleware);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a middleware to the end of a middleware group.\n     *\n     * If the middleware is already in the group, it will not be added again.\n     *\n     * @param  string  $group\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function pushMiddlewareToGroup($group, $middleware)\n    {\n        if (! array_key_exists($group, $this->middlewareGroups)) {\n            $this->middlewareGroups[$group] = [];\n        }\n\n        if (! in_array($middleware, $this->middlewareGroups[$group])) {\n            $this->middlewareGroups[$group][] = $middleware;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Remove the given middleware from the specified group.\n     *\n     * @param  string  $group\n     * @param  string  $middleware\n     * @return $this\n     */\n    public function removeMiddlewareFromGroup($group, $middleware)\n    {\n        if (! $this->hasMiddlewareGroup($group)) {\n            return $this;\n        }\n\n        $reversedMiddlewaresArray = array_flip($this->middlewareGroups[$group]);\n\n        if (! array_key_exists($middleware, $reversedMiddlewaresArray)) {\n            return $this;\n        }\n\n        $middlewareKey = $reversedMiddlewaresArray[$middleware];\n\n        unset($this->middlewareGroups[$group][$middlewareKey]);\n\n        return $this;\n    }\n\n    /**\n     * Flush the router's middleware groups.\n     *\n     * @return $this\n     */\n    public function flushMiddlewareGroups()\n    {\n        $this->middlewareGroups = [];\n\n        return $this;\n    }\n\n    /**\n     * Add a new route parameter binder.\n     *\n     * @param  string  $key\n     * @param  string|callable  $binder\n     * @return void\n     */\n    public function bind($key, $binder)\n    {\n        $this->binders[str_replace('-', '_', $key)] = RouteBinding::forCallback(\n            $this->container, $binder\n        );\n    }\n\n    /**\n     * Register a model binder for a wildcard.\n     *\n     * @param  string  $key\n     * @param  string  $class\n     * @param  \\Closure|null  $callback\n     * @return void\n     */\n    public function model($key, $class, ?Closure $callback = null)\n    {\n        $this->bind($key, RouteBinding::forModel($this->container, $class, $callback));\n    }\n\n    /**\n     * Get the binding callback for a given binding.\n     *\n     * @param  string  $key\n     * @return \\Closure|null\n     */\n    public function getBindingCallback($key)\n    {\n        if (isset($this->binders[$key = str_replace('-', '_', $key)])) {\n            return $this->binders[$key];\n        }\n    }\n\n    /**\n     * Get the global \"where\" patterns.\n     *\n     * @return array\n     */\n    public function getPatterns()\n    {\n        return $this->patterns;\n    }\n\n    /**\n     * Set a global where pattern on all routes.\n     *\n     * @param  string  $key\n     * @param  string  $pattern\n     * @return void\n     */\n    public function pattern($key, $pattern)\n    {\n        $this->patterns[$key] = $pattern;\n    }\n\n    /**\n     * Set a group of global where patterns on all routes.\n     *\n     * @param  array  $patterns\n     * @return void\n     */\n    public function patterns($patterns)\n    {\n        foreach ($patterns as $key => $pattern) {\n            $this->pattern($key, $pattern);\n        }\n    }\n\n    /**\n     * Determine if the router currently has a group stack.\n     *\n     * @return bool\n     */\n    public function hasGroupStack()\n    {\n        return ! empty($this->groupStack);\n    }\n\n    /**\n     * Get the current group stack for the router.\n     *\n     * @return array\n     */\n    public function getGroupStack()\n    {\n        return $this->groupStack;\n    }\n\n    /**\n     * Get a route parameter for the current route.\n     *\n     * @param  string  $key\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function input($key, $default = null)\n    {\n        return $this->current()->parameter($key, $default);\n    }\n\n    /**\n     * Get the request currently being dispatched.\n     *\n     * @return \\Illuminate\\Http\\Request\n     */\n    public function getCurrentRequest()\n    {\n        return $this->currentRequest;\n    }\n\n    /**\n     * Get the currently dispatched route instance.\n     *\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function getCurrentRoute()\n    {\n        return $this->current();\n    }\n\n    /**\n     * Get the currently dispatched route instance.\n     *\n     * @return \\Illuminate\\Routing\\Route|null\n     */\n    public function current()\n    {\n        return $this->current;\n    }\n\n    /**\n     * Check if a route with the given name exists.\n     *\n     * @param  string|array  $name\n     * @return bool\n     */\n    public function has($name)\n    {\n        $names = is_array($name) ? $name : func_get_args();\n\n        foreach ($names as $value) {\n            if (! $this->routes->hasNamedRoute($value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the current route name.\n     *\n     * @return string|null\n     */\n    public function currentRouteName()\n    {\n        return $this->current() ? $this->current()->getName() : null;\n    }\n\n    /**\n     * Alias for the \"currentRouteNamed\" method.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function is(...$patterns)\n    {\n        return $this->currentRouteNamed(...$patterns);\n    }\n\n    /**\n     * Determine if the current route matches a pattern.\n     *\n     * @param  mixed  ...$patterns\n     * @return bool\n     */\n    public function currentRouteNamed(...$patterns)\n    {\n        return $this->current() && $this->current()->named(...$patterns);\n    }\n\n    /**\n     * Get the current route action.\n     *\n     * @return string|null\n     */\n    public function currentRouteAction()\n    {\n        if ($this->current()) {\n            return $this->current()->getAction()['controller'] ?? null;\n        }\n    }\n\n    /**\n     * Alias for the \"currentRouteUses\" method.\n     *\n     * @param  array|string  ...$patterns\n     * @return bool\n     */\n    public function uses(...$patterns)\n    {\n        foreach ($patterns as $pattern) {\n            if (Str::is($pattern, $this->currentRouteAction())) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the current route action matches a given action.\n     *\n     * @param  string  $action\n     * @return bool\n     */\n    public function currentRouteUses($action)\n    {\n        return $this->currentRouteAction() == $action;\n    }\n\n    /**\n     * Set the unmapped global resource parameters to singular.\n     *\n     * @param  bool  $singular\n     * @return void\n     */\n    public function singularResourceParameters($singular = true)\n    {\n        ResourceRegistrar::singularParameters($singular);\n    }\n\n    /**\n     * Set the global resource parameter mapping.\n     *\n     * @param  array  $parameters\n     * @return void\n     */\n    public function resourceParameters(array $parameters = [])\n    {\n        ResourceRegistrar::setParameters($parameters);\n    }\n\n    /**\n     * Get or set the verbs used in the resource URIs.\n     *\n     * @param  array  $verbs\n     * @return array|null\n     */\n    public function resourceVerbs(array $verbs = [])\n    {\n        return ResourceRegistrar::verbs($verbs);\n    }\n\n    /**\n     * Get the underlying route collection.\n     *\n     * @return \\Illuminate\\Routing\\RouteCollectionInterface\n     */\n    public function getRoutes()\n    {\n        return $this->routes;\n    }\n\n    /**\n     * Set the route collection instance.\n     *\n     * @param  \\Illuminate\\Routing\\RouteCollection  $routes\n     * @return void\n     */\n    public function setRoutes(RouteCollection $routes)\n    {\n        foreach ($routes as $route) {\n            $route->setRouter($this)->setContainer($this->container);\n        }\n\n        $this->routes = $routes;\n\n        $this->container->instance('routes', $this->routes);\n    }\n\n    /**\n     * Set the compiled route collection instance.\n     *\n     * @param  array  $routes\n     * @return void\n     */\n    public function setCompiledRoutes(array $routes)\n    {\n        $this->routes = (new CompiledRouteCollection($routes['compiled'], $routes['attributes']))\n            ->setRouter($this)\n            ->setContainer($this->container);\n\n        $this->container->instance('routes', $this->routes);\n    }\n\n    /**\n     * Remove any duplicate middleware from the given array.\n     *\n     * @param  array  $middleware\n     * @return array\n     */\n    public static function uniqueMiddleware(array $middleware)\n    {\n        $seen = [];\n        $result = [];\n\n        foreach ($middleware as $value) {\n            $key = \\is_object($value) ? \\spl_object_id($value) : $value;\n\n            if (! isset($seen[$key])) {\n                $seen[$key] = true;\n                $result[] = $value;\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Set the container instance used by the router.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically handle calls into the router instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if ($method === 'middleware') {\n            return (new RouteRegistrar($this))->attribute($method, is_array($parameters[0]) ? $parameters[0] : $parameters);\n        }\n\n        if ($method === 'can') {\n            return (new RouteRegistrar($this))->attribute($method, [$parameters]);\n        }\n\n        if ($method !== 'where' && Str::startsWith($method, 'where')) {\n            return (new RouteRegistrar($this))->{$method}(...$parameters);\n        }\n\n        return (new RouteRegistrar($this))->attribute($method, array_key_exists(0, $parameters) ? $parameters[0] : true);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/RoutingServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory as ResponseFactoryContract;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator as UrlGeneratorContract;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactoryContract;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\nuse Illuminate\\Support\\ServiceProvider;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse Psr\\Http\\Message\\ServerRequestInterface;\nuse Symfony\\Bridge\\PsrHttpMessage\\Factory\\PsrHttpFactory;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass RoutingServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerRouter();\n        $this->registerUrlGenerator();\n        $this->registerRedirector();\n        $this->registerPsrRequest();\n        $this->registerPsrResponse();\n        $this->registerResponseFactory();\n        $this->registerCallableDispatcher();\n        $this->registerControllerDispatcher();\n    }\n\n    /**\n     * Register the router instance.\n     *\n     * @return void\n     */\n    protected function registerRouter()\n    {\n        $this->app->singleton('router', function ($app) {\n            return new Router($app['events'], $app);\n        });\n    }\n\n    /**\n     * Register the URL generator service.\n     *\n     * @return void\n     */\n    protected function registerUrlGenerator()\n    {\n        $this->app->singleton('url', function ($app) {\n            $routes = $app['router']->getRoutes();\n\n            // The URL generator needs the route collection that exists on the router.\n            // Keep in mind this is an object, so we're passing by references here\n            // and all the registered routes will be available to the generator.\n            $app->instance('routes', $routes);\n\n            return new UrlGenerator(\n                $routes, $app->rebinding(\n                    'request', $this->requestRebinder()\n                ), $app['config']['app.asset_url']\n            );\n        });\n\n        $this->app->extend('url', function (UrlGeneratorContract $url, $app) {\n            // Next we will set a few service resolvers on the URL generator so it can\n            // get the information it needs to function. This just provides some of\n            // the convenience features to this URL generator like \"signed\" URLs.\n            $url->setSessionResolver(function () {\n                return $this->app['session'] ?? null;\n            });\n\n            $url->setKeyResolver(function () {\n                $config = $this->app->make('config');\n\n                return [$config->get('app.key'), ...($config->get('app.previous_keys') ?? [])];\n            });\n\n            // If the route collection is \"rebound\", for example, when the routes stay\n            // cached for the application, we will need to rebind the routes on the\n            // URL generator instance so it has the latest version of the routes.\n            $app->rebinding('routes', function ($app, $routes) {\n                $app['url']->setRoutes($routes);\n            });\n\n            return $url;\n        });\n    }\n\n    /**\n     * Get the URL generator request rebinder.\n     *\n     * @return \\Closure\n     */\n    protected function requestRebinder()\n    {\n        return function ($app, $request) {\n            $app['url']->setRequest($request);\n        };\n    }\n\n    /**\n     * Register the Redirector service.\n     *\n     * @return void\n     */\n    protected function registerRedirector()\n    {\n        $this->app->singleton('redirect', function ($app) {\n            $redirector = new Redirector($app['url']);\n\n            // If the session is set on the application instance, we'll inject it into\n            // the redirector instance. This allows the redirect responses to allow\n            // for the quite convenient \"with\" methods that flash to the session.\n            if (isset($app['session.store'])) {\n                $redirector->setSession($app['session.store']);\n            }\n\n            return $redirector;\n        });\n    }\n\n    /**\n     * Register a binding for the PSR-7 request implementation.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function registerPsrRequest()\n    {\n        $this->app->bind(ServerRequestInterface::class, function ($app) {\n            if (class_exists(PsrHttpFactory::class)) {\n                $illuminateRequest = $app->make('request');\n                $request = (new PsrHttpFactory)->createRequest($illuminateRequest);\n\n                if ($illuminateRequest->getContentTypeFormat() !== 'json' && $illuminateRequest->request->count() === 0) {\n                    return $request;\n                }\n\n                return $request->withParsedBody(\n                    array_merge($request->getParsedBody() ?? [], $illuminateRequest->getPayload()->all())\n                );\n            }\n\n            throw new BindingResolutionException('Unable to resolve PSR request. Please install the \"symfony/psr-http-message-bridge\" package.');\n        });\n    }\n\n    /**\n     * Register a binding for the PSR-7 response implementation.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     */\n    protected function registerPsrResponse()\n    {\n        $this->app->bind(ResponseInterface::class, function () {\n            if (class_exists(PsrHttpFactory::class)) {\n                return (new PsrHttpFactory)->createResponse(new Response);\n            }\n\n            throw new BindingResolutionException('Unable to resolve PSR response. Please install the \"symfony/psr-http-message-bridge\" package.');\n        });\n    }\n\n    /**\n     * Register the response factory implementation.\n     *\n     * @return void\n     */\n    protected function registerResponseFactory()\n    {\n        $this->app->singleton(ResponseFactoryContract::class, function ($app) {\n            return new ResponseFactory($app[ViewFactoryContract::class], $app['redirect']);\n        });\n    }\n\n    /**\n     * Register the callable dispatcher.\n     *\n     * @return void\n     */\n    protected function registerCallableDispatcher()\n    {\n        $this->app->singleton(CallableDispatcherContract::class, function ($app) {\n            return new CallableDispatcher($app);\n        });\n    }\n\n    /**\n     * Register the controller dispatcher.\n     *\n     * @return void\n     */\n    protected function registerControllerDispatcher()\n    {\n        $this->app->singleton(ControllerDispatcherContract::class, function ($app) {\n            return new ControllerDispatcher($app);\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/SortedMiddleware.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Support\\Collection;\n\nclass SortedMiddleware extends Collection\n{\n    /**\n     * Create a new Sorted Middleware container.\n     *\n     * @param  array  $priorityMap\n     * @param  \\Illuminate\\Support\\Collection|array  $middlewares\n     */\n    public function __construct(array $priorityMap, $middlewares)\n    {\n        if ($middlewares instanceof Collection) {\n            $middlewares = $middlewares->all();\n        }\n\n        $this->items = $this->sortMiddleware($priorityMap, $middlewares);\n    }\n\n    /**\n     * Sort the middlewares by the given priority map.\n     *\n     * Each call to this method makes one discrete middleware movement if necessary.\n     *\n     * @param  array  $priorityMap\n     * @param  array  $middlewares\n     * @return array\n     */\n    protected function sortMiddleware($priorityMap, $middlewares)\n    {\n        $lastIndex = 0;\n\n        foreach ($middlewares as $index => $middleware) {\n            if (! is_string($middleware)) {\n                continue;\n            }\n\n            $priorityIndex = $this->priorityMapIndex($priorityMap, $middleware);\n\n            if (! is_null($priorityIndex)) {\n                // This middleware is in the priority map. If we have encountered another middleware\n                // that was also in the priority map and was at a lower priority than the current\n                // middleware, we will move this middleware to be above the previous encounter.\n                if (isset($lastPriorityIndex) && $priorityIndex < $lastPriorityIndex) {\n                    return $this->sortMiddleware(\n                        $priorityMap, array_values($this->moveMiddleware($middlewares, $index, $lastIndex))\n                    );\n                }\n\n                // This middleware is in the priority map; but, this is the first middleware we have\n                // encountered from the map thus far. We'll save its current index plus its index\n                // from the priority map so we can compare against them on the next iterations.\n                $lastIndex = $index;\n\n                $lastPriorityIndex = $priorityIndex;\n            }\n        }\n\n        return Router::uniqueMiddleware($middlewares);\n    }\n\n    /**\n     * Calculate the priority map index of the middleware.\n     *\n     * @param  array  $priorityMap\n     * @param  string  $middleware\n     * @return int|null\n     */\n    protected function priorityMapIndex($priorityMap, $middleware)\n    {\n        foreach ($this->middlewareNames($middleware) as $name) {\n            $priorityIndex = array_search($name, $priorityMap);\n\n            if ($priorityIndex !== false) {\n                return $priorityIndex;\n            }\n        }\n    }\n\n    /**\n     * Resolve the middleware names to look for in the priority array.\n     *\n     * @param  string  $middleware\n     * @return \\Generator\n     */\n    protected function middlewareNames($middleware)\n    {\n        $stripped = head(explode(':', $middleware));\n\n        yield $stripped;\n\n        $interfaces = @class_implements($stripped);\n\n        if ($interfaces !== false) {\n            foreach ($interfaces as $interface) {\n                yield $interface;\n            }\n        }\n\n        $parents = @class_parents($stripped);\n\n        if ($parents !== false) {\n            foreach ($parents as $parent) {\n                yield $parent;\n            }\n        }\n    }\n\n    /**\n     * Splice a middleware into a new position and remove the old entry.\n     *\n     * @param  array  $middlewares\n     * @param  int  $from\n     * @param  int  $to\n     * @return array\n     */\n    protected function moveMiddleware($middlewares, $from, $to)\n    {\n        array_splice($middlewares, $to, 0, $middlewares[$from]);\n\n        unset($middlewares[$from + 1]);\n\n        return $middlewares;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/UrlGenerator.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse BackedEnum;\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator as UrlGeneratorContract;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\n\nclass UrlGenerator implements UrlGeneratorContract\n{\n    use InteractsWithTime, Macroable;\n\n    /**\n     * The route collection.\n     *\n     * @var \\Illuminate\\Routing\\RouteCollectionInterface\n     */\n    protected $routes;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Illuminate\\Http\\Request\n     */\n    protected $request;\n\n    /**\n     * The asset root URL.\n     *\n     * @var string\n     */\n    protected $assetRoot;\n\n    /**\n     * The forced URL root.\n     *\n     * @var string\n     */\n    protected $forcedRoot;\n\n    /**\n     * The forced scheme for URLs.\n     *\n     * @var string\n     */\n    protected $forceScheme;\n\n    /**\n     * A cached copy of the URL root for the current request.\n     *\n     * @var string|null\n     */\n    protected $cachedRoot;\n\n    /**\n     * A cached copy of the URL scheme for the current request.\n     *\n     * @var string|null\n     */\n    protected $cachedScheme;\n\n    /**\n     * The root namespace being applied to controller actions.\n     *\n     * @var string\n     */\n    protected $rootNamespace;\n\n    /**\n     * The session resolver callable.\n     *\n     * @var callable\n     */\n    protected $sessionResolver;\n\n    /**\n     * The encryption key resolver callable.\n     *\n     * @var callable\n     */\n    protected $keyResolver;\n\n    /**\n     * The missing named route resolver callable.\n     *\n     * @var callable\n     */\n    protected $missingNamedRouteResolver;\n\n    /**\n     * The callback to use to format hosts.\n     *\n     * @var \\Closure\n     */\n    protected $formatHostUsing;\n\n    /**\n     * The callback to use to format paths.\n     *\n     * @var \\Closure\n     */\n    protected $formatPathUsing;\n\n    /**\n     * The route URL generator instance.\n     *\n     * @var \\Illuminate\\Routing\\RouteUrlGenerator|null\n     */\n    protected $routeGenerator;\n\n    /**\n     * Create a new URL Generator instance.\n     *\n     * @param  \\Illuminate\\Routing\\RouteCollectionInterface  $routes\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  string|null  $assetRoot\n     */\n    public function __construct(RouteCollectionInterface $routes, Request $request, $assetRoot = null)\n    {\n        $this->routes = $routes;\n        $this->assetRoot = $assetRoot;\n\n        $this->setRequest($request);\n    }\n\n    /**\n     * Get the full URL for the current request.\n     *\n     * @return string\n     */\n    public function full()\n    {\n        return $this->request->fullUrl();\n    }\n\n    /**\n     * Get the current URL for the request.\n     *\n     * @return string\n     */\n    public function current()\n    {\n        return $this->to($this->request->getPathInfo());\n    }\n\n    /**\n     * Get the URL for the previous request.\n     *\n     * @param  mixed  $fallback\n     * @return string\n     */\n    public function previous($fallback = false)\n    {\n        $referrer = $this->request->headers->get('referer');\n\n        $url = $referrer ? $this->to($referrer) : $this->getPreviousUrlFromSession();\n\n        if ($url) {\n            return $url;\n        } elseif ($fallback) {\n            return $this->to($fallback);\n        }\n\n        return $this->to('/');\n    }\n\n    /**\n     * Get the previous path info for the request.\n     *\n     * @param  mixed  $fallback\n     * @return string\n     */\n    public function previousPath($fallback = false)\n    {\n        $previousPath = parse_url($this->previous($fallback), PHP_URL_PATH);\n\n        if (! is_string($previousPath) || $previousPath === '') {\n            return '/';\n        }\n\n        $basePath = parse_url($this->to('/'), PHP_URL_PATH) ?: '';\n\n        $previousPath = $basePath !== '/' ? preg_replace('#^'.preg_quote($basePath, '#').'#', '', $previousPath) : $previousPath;\n\n        return rtrim($previousPath, '/') ?: '/';\n    }\n\n    /**\n     * Get the previous URL from the session if possible.\n     *\n     * @return string|null\n     */\n    protected function getPreviousUrlFromSession()\n    {\n        return $this->getSession()?->previousUrl();\n    }\n\n    /**\n     * Generate an absolute URL to the given path.\n     *\n     * @param  string  $path\n     * @param  mixed  $extra\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function to($path, $extra = [], $secure = null)\n    {\n        // First we will check if the URL is already a valid URL. If it is we will not\n        // try to generate a new one but will simply return the URL as is, which is\n        // convenient since developers do not always have to check if it's valid.\n        if ($this->isValidUrl($path)) {\n            return $path;\n        }\n\n        $tail = implode('/', array_map(\n            'rawurlencode', (array) $this->formatParameters($extra))\n        );\n\n        // Once we have the scheme we will compile the \"tail\" by collapsing the values\n        // into a single string delimited by slashes. This just makes it convenient\n        // for passing the array of parameters to this URL as a list of segments.\n        $root = $this->formatRoot($this->formatScheme($secure));\n\n        [$path, $query] = $this->extractQueryString($path);\n\n        return $this->format(\n            $root, '/'.trim($path.'/'.$tail, '/')\n        ).$query;\n    }\n\n    /**\n     * Generate an absolute URL with the given query parameters.\n     *\n     * @param  string  $path\n     * @param  array  $query\n     * @param  mixed  $extra\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function query($path, $query = [], $extra = [], $secure = null)\n    {\n        [$path, $existingQueryString] = $this->extractQueryString($path);\n\n        parse_str(Str::after($existingQueryString, '?'), $existingQueryArray);\n\n        return rtrim($this->to($path.'?'.Arr::query(\n            array_merge($existingQueryArray, $query)\n        ), $extra, $secure), '?');\n    }\n\n    /**\n     * Generate a secure, absolute URL to the given path.\n     *\n     * @param  string  $path\n     * @param  array  $parameters\n     * @return string\n     */\n    public function secure($path, $parameters = [])\n    {\n        return $this->to($path, $parameters, true);\n    }\n\n    /**\n     * Generate the URL to an application asset.\n     *\n     * @param  string  $path\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function asset($path, $secure = null)\n    {\n        if ($this->isValidUrl($path)) {\n            return $path;\n        }\n\n        // Once we get the root URL, we will check to see if it contains an index.php\n        // file in the paths. If it does, we will remove it since it is not needed\n        // for asset paths, but only for routes to endpoints in the application.\n        $root = $this->assetRoot ?: $this->formatRoot($this->formatScheme($secure));\n\n        return Str::finish($this->removeIndex($root), '/').trim($path, '/');\n    }\n\n    /**\n     * Generate the URL to a secure asset.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function secureAsset($path)\n    {\n        return $this->asset($path, true);\n    }\n\n    /**\n     * Generate the URL to an asset from a custom root domain such as CDN, etc.\n     *\n     * @param  string  $root\n     * @param  string  $path\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function assetFrom($root, $path, $secure = null)\n    {\n        // Once we get the root URL, we will check to see if it contains an index.php\n        // file in the paths. If it does, we will remove it since it is not needed\n        // for asset paths, but only for routes to endpoints in the application.\n        $root = $this->formatRoot($this->formatScheme($secure), $root);\n\n        return $this->removeIndex($root).'/'.trim($path, '/');\n    }\n\n    /**\n     * Remove the index.php file from a path.\n     *\n     * @param  string  $root\n     * @return string\n     */\n    protected function removeIndex($root)\n    {\n        $i = 'index.php';\n\n        return str_contains($root, $i) ? str_replace('/'.$i, '', $root) : $root;\n    }\n\n    /**\n     * Get the default scheme for a raw URL.\n     *\n     * @param  bool|null  $secure\n     * @return string\n     */\n    public function formatScheme($secure = null)\n    {\n        if (! is_null($secure)) {\n            return $secure ? 'https://' : 'http://';\n        }\n\n        if (is_null($this->cachedScheme)) {\n            $this->cachedScheme = $this->forceScheme ?: $this->request->getScheme().'://';\n        }\n\n        return $this->cachedScheme;\n    }\n\n    /**\n     * Create a signed route URL for a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $expiration\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true)\n    {\n        $this->ensureSignedRouteParametersAreNotReserved(\n            $parameters = Arr::wrap($parameters)\n        );\n\n        if ($expiration) {\n            $parameters = $parameters + ['expires' => $this->availableAt($expiration)];\n        }\n\n        ksort($parameters);\n\n        $key = call_user_func($this->keyResolver);\n\n        return $this->route($name, $parameters + [\n            'signature' => hash_hmac(\n                'sha256',\n                $this->route($name, $parameters, $absolute),\n                is_array($key) ? $key[0] : $key\n            ),\n        ], $absolute);\n    }\n\n    /**\n     * Ensure the given signed route parameters are not reserved.\n     *\n     * @param  mixed  $parameters\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function ensureSignedRouteParametersAreNotReserved($parameters)\n    {\n        if (array_key_exists('signature', $parameters)) {\n            throw new InvalidArgumentException(\n                '\"Signature\" is a reserved parameter when generating signed routes. Please rename your route parameter.'\n            );\n        }\n\n        if (array_key_exists('expires', $parameters)) {\n            throw new InvalidArgumentException(\n                '\"Expires\" is a reserved parameter when generating signed routes. Please rename your route parameter.'\n            );\n        }\n    }\n\n    /**\n     * Create a temporary signed route URL for a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  \\DateTimeInterface|\\DateInterval|int  $expiration\n     * @param  array  $parameters\n     * @param  bool  $absolute\n     * @return string\n     */\n    public function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true)\n    {\n        return $this->signedRoute($name, $parameters, $expiration, $absolute);\n    }\n\n    /**\n     * Determine if the given request has a valid signature.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  bool  $absolute\n     * @param  \\Closure|array  $ignoreQuery\n     * @return bool\n     */\n    public function hasValidSignature(Request $request, $absolute = true, Closure|array $ignoreQuery = [])\n    {\n        return $this->hasCorrectSignature($request, $absolute, $ignoreQuery)\n            && $this->signatureHasNotExpired($request);\n    }\n\n    /**\n     * Determine if the given request has a valid signature for a relative URL.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure|array  $ignoreQuery\n     * @return bool\n     */\n    public function hasValidRelativeSignature(Request $request, Closure|array $ignoreQuery = [])\n    {\n        return $this->hasValidSignature($request, false, $ignoreQuery);\n    }\n\n    /**\n     * Determine if the signature from the given request matches the URL.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  bool  $absolute\n     * @param  \\Closure|array  $ignoreQuery\n     * @return bool\n     */\n    public function hasCorrectSignature(Request $request, $absolute = true, Closure|array $ignoreQuery = [])\n    {\n        $url = $absolute ? $request->url() : '/'.$request->path();\n\n        $queryString = (new Collection(explode('&', (string) $request->server->get('QUERY_STRING'))))\n            ->reject(function ($parameter) use ($ignoreQuery) {\n                $parameter = Str::before($parameter, '=');\n\n                if ($parameter === 'signature') {\n                    return true;\n                }\n\n                if ($ignoreQuery instanceof Closure) {\n                    return $ignoreQuery($parameter);\n                }\n\n                return in_array($parameter, $ignoreQuery);\n            })\n            ->join('&');\n\n        $original = rtrim($url.'?'.$queryString, '?');\n\n        $keys = call_user_func($this->keyResolver);\n\n        $keys = is_array($keys) ? $keys : [$keys];\n\n        foreach ($keys as $key) {\n            if (hash_equals(\n                hash_hmac('sha256', $original, $key),\n                (string) $request->query('signature', '')\n            )) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if the expires timestamp from the given request is not from the past.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return bool\n     */\n    public function signatureHasNotExpired(Request $request)\n    {\n        $expires = $request->query('expires');\n\n        return ! ($expires && Carbon::now()->getTimestamp() > $expires);\n    }\n\n    /**\n     * Get the URL to a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\Symfony\\Component\\Routing\\Exception\\RouteNotFoundException|\\InvalidArgumentException\n     */\n    public function route($name, $parameters = [], $absolute = true)\n    {\n        if ($name instanceof BackedEnum && ! is_string($name = $name->value)) {\n            throw new InvalidArgumentException('Attribute [name] expects a string backed enum.');\n        }\n\n        if (! is_null($route = $this->routes->getByName($name))) {\n            return $this->toRoute($route, $parameters, $absolute);\n        }\n\n        if (! is_null($this->missingNamedRouteResolver) &&\n            ! is_null($url = call_user_func($this->missingNamedRouteResolver, $name, $parameters, $absolute))) {\n            return $url;\n        }\n\n        throw new RouteNotFoundException(\"Route [{$name}] not defined.\");\n    }\n\n    /**\n     * Get the URL for a given route instance.\n     *\n     * @param  \\Illuminate\\Routing\\Route  $route\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\Illuminate\\Routing\\Exceptions\\UrlGenerationException\n     */\n    public function toRoute($route, $parameters, $absolute)\n    {\n        return $this->routeUrl()->to(\n            $route, $parameters, $absolute\n        );\n    }\n\n    /**\n     * Get the URL to a controller action.\n     *\n     * @param  string|array  $action\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function action($action, $parameters = [], $absolute = true)\n    {\n        if (is_null($route = $this->routes->getByAction($action = $this->formatAction($action)))) {\n            throw new InvalidArgumentException(\"Action {$action} not defined.\");\n        }\n\n        return $this->toRoute($route, $parameters, $absolute);\n    }\n\n    /**\n     * Format the given controller action.\n     *\n     * @param  string|array  $action\n     * @return string\n     */\n    protected function formatAction($action)\n    {\n        if (is_array($action)) {\n            $action = '\\\\'.implode('@', $action);\n        }\n\n        if ($this->rootNamespace && ! str_starts_with($action, '\\\\')) {\n            return $this->rootNamespace.'\\\\'.$action;\n        }\n\n        return trim($action, '\\\\');\n    }\n\n    /**\n     * Format the array of URL parameters.\n     *\n     * @param  mixed  $parameters\n     * @return array\n     */\n    public function formatParameters($parameters)\n    {\n        $parameters = Arr::wrap($parameters);\n\n        foreach ($parameters as $key => $parameter) {\n            if ($parameter instanceof UrlRoutable) {\n                $parameters[$key] = $parameter->getRouteKey();\n            }\n        }\n\n        return $parameters;\n    }\n\n    /**\n     * Extract the query string from the given path.\n     *\n     * @param  string  $path\n     * @return array\n     */\n    protected function extractQueryString($path)\n    {\n        if (($queryPosition = strpos($path, '?')) !== false) {\n            return [\n                substr($path, 0, $queryPosition),\n                substr($path, $queryPosition),\n            ];\n        }\n\n        return [$path, ''];\n    }\n\n    /**\n     * Get the base URL for the request.\n     *\n     * @param  string  $scheme\n     * @param  string|null  $root\n     * @return string\n     */\n    public function formatRoot($scheme, $root = null)\n    {\n        if (is_null($root)) {\n            if (is_null($this->cachedRoot)) {\n                $this->cachedRoot = $this->forcedRoot ?: $this->request->root();\n            }\n\n            $root = $this->cachedRoot;\n        }\n\n        $start = str_starts_with($root, 'http://') ? 'http://' : 'https://';\n\n        return preg_replace('~'.$start.'~', $scheme, $root, 1);\n    }\n\n    /**\n     * Format the given URL segments into a single URL.\n     *\n     * @param  string  $root\n     * @param  string  $path\n     * @param  \\Illuminate\\Routing\\Route|null  $route\n     * @return string\n     */\n    public function format($root, $path, $route = null)\n    {\n        $path = '/'.trim($path, '/');\n\n        if ($this->formatHostUsing) {\n            $root = call_user_func($this->formatHostUsing, $root, $route);\n        }\n\n        if ($this->formatPathUsing) {\n            $path = call_user_func($this->formatPathUsing, $path, $route);\n        }\n\n        return trim($root.$path, '/');\n    }\n\n    /**\n     * Determine if the given path is a valid URL.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function isValidUrl($path)\n    {\n        if (! preg_match('~^(#|//|https?://|(mailto|tel|sms):)~', $path)) {\n            return filter_var($path, FILTER_VALIDATE_URL) !== false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the Route URL generator instance.\n     *\n     * @return \\Illuminate\\Routing\\RouteUrlGenerator\n     */\n    protected function routeUrl()\n    {\n        if (! $this->routeGenerator) {\n            $this->routeGenerator = new RouteUrlGenerator($this, $this->request);\n        }\n\n        return $this->routeGenerator;\n    }\n\n    /**\n     * Set the default named parameters used by the URL generator.\n     *\n     * @param  array  $defaults\n     * @return void\n     */\n    public function defaults(array $defaults)\n    {\n        $this->routeUrl()->defaults($defaults);\n    }\n\n    /**\n     * Get the default named parameters used by the URL generator.\n     *\n     * @return array\n     */\n    public function getDefaultParameters()\n    {\n        return $this->routeUrl()->defaultParameters;\n    }\n\n    /**\n     * Force the scheme for URLs.\n     *\n     * @param  string|null  $scheme\n     * @return void\n     */\n    public function forceScheme($scheme)\n    {\n        $this->cachedScheme = null;\n\n        $this->forceScheme = $scheme ? $scheme.'://' : null;\n    }\n\n    /**\n     * Force the use of the HTTPS scheme for all generated URLs.\n     *\n     * @param  bool  $force\n     * @return void\n     */\n    public function forceHttps($force = true)\n    {\n        if ($force) {\n            $this->forceScheme('https');\n        }\n    }\n\n    /**\n     * Set the URL origin for all generated URLs.\n     *\n     * @param  string|null  $root\n     * @return void\n     */\n    public function useOrigin(?string $root)\n    {\n        $this->forceRootUrl($root);\n    }\n\n    /**\n     * Set the forced root URL.\n     *\n     * @param  string|null  $root\n     * @return void\n     *\n     * @deprecated Use useOrigin\n     */\n    public function forceRootUrl($root)\n    {\n        $this->forcedRoot = $root ? rtrim($root, '/') : null;\n\n        $this->cachedRoot = null;\n    }\n\n    /**\n     * Set the URL origin for all generated asset URLs.\n     *\n     * @param  string|null  $root\n     * @return void\n     */\n    public function useAssetOrigin(?string $root)\n    {\n        $this->assetRoot = $root ? rtrim($root, '/') : null;\n    }\n\n    /**\n     * Set a callback to be used to format the host of generated URLs.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function formatHostUsing(Closure $callback)\n    {\n        $this->formatHostUsing = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Set a callback to be used to format the path of generated URLs.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function formatPathUsing(Closure $callback)\n    {\n        $this->formatPathUsing = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the path formatter being used by the URL generator.\n     *\n     * @return \\Closure\n     */\n    public function pathFormatter()\n    {\n        return $this->formatPathUsing ?: function ($path) {\n            return $path;\n        };\n    }\n\n    /**\n     * Get the request instance.\n     *\n     * @return \\Illuminate\\Http\\Request\n     */\n    public function getRequest()\n    {\n        return $this->request;\n    }\n\n    /**\n     * Set the current request instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n\n        $this->cachedRoot = null;\n        $this->cachedScheme = null;\n\n        tap($this->routeGenerator?->defaultParameters ?: [], function ($defaults) {\n            $this->routeGenerator = null;\n\n            if (! empty($defaults)) {\n                $this->defaults($defaults);\n            }\n        });\n    }\n\n    /**\n     * Set the route collection.\n     *\n     * @param  \\Illuminate\\Routing\\RouteCollectionInterface  $routes\n     * @return $this\n     */\n    public function setRoutes(RouteCollectionInterface $routes)\n    {\n        $this->routes = $routes;\n\n        return $this;\n    }\n\n    /**\n     * Get the session implementation from the resolver.\n     *\n     * @return \\Illuminate\\Session\\Store|null\n     */\n    protected function getSession()\n    {\n        if ($this->sessionResolver) {\n            return call_user_func($this->sessionResolver);\n        }\n    }\n\n    /**\n     * Set the session resolver for the generator.\n     *\n     * @param  callable  $sessionResolver\n     * @return $this\n     */\n    public function setSessionResolver(callable $sessionResolver)\n    {\n        $this->sessionResolver = $sessionResolver;\n\n        return $this;\n    }\n\n    /**\n     * Set the encryption key resolver.\n     *\n     * @param  callable  $keyResolver\n     * @return $this\n     */\n    public function setKeyResolver(callable $keyResolver)\n    {\n        $this->keyResolver = $keyResolver;\n\n        return $this;\n    }\n\n    /**\n     * Clone a new instance of the URL generator with a different encryption key resolver.\n     *\n     * @param  callable  $keyResolver\n     * @return \\Illuminate\\Routing\\UrlGenerator\n     */\n    public function withKeyResolver(callable $keyResolver)\n    {\n        return (clone $this)->setKeyResolver($keyResolver);\n    }\n\n    /**\n     * Set the callback that should be used to attempt to resolve missing named routes.\n     *\n     * @param  callable  $missingNamedRouteResolver\n     * @return $this\n     */\n    public function resolveMissingNamedRoutesUsing(callable $missingNamedRouteResolver)\n    {\n        $this->missingNamedRouteResolver = $missingNamedRouteResolver;\n\n        return $this;\n    }\n\n    /**\n     * Get the root controller namespace.\n     *\n     * @return string\n     */\n    public function getRootControllerNamespace()\n    {\n        return $this->rootNamespace;\n    }\n\n    /**\n     * Set the root controller namespace.\n     *\n     * @param  string  $rootNamespace\n     * @return $this\n     */\n    public function setRootControllerNamespace($rootNamespace)\n    {\n        $this->rootNamespace = $rootNamespace;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/ViewController.php",
    "content": "<?php\n\nnamespace Illuminate\\Routing;\n\nuse Illuminate\\Contracts\\Routing\\ResponseFactory;\n\nclass ViewController extends Controller\n{\n    /**\n     * The response factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Routing\\ResponseFactory\n     */\n    protected $response;\n\n    /**\n     * Create a new controller instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Routing\\ResponseFactory  $response\n     */\n    public function __construct(ResponseFactory $response)\n    {\n        $this->response = $response;\n    }\n\n    /**\n     * Invoke the controller method.\n     *\n     * @param  mixed  ...$args\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function __invoke(...$args)\n    {\n        $routeParameters = array_filter($args, function ($key) {\n            return ! in_array($key, ['view', 'data', 'status', 'headers']);\n        }, ARRAY_FILTER_USE_KEY);\n\n        $args['data'] = array_merge($args['data'], $routeParameters);\n\n        return $this->response->view(\n            $args['view'],\n            $args['data'],\n            $args['status'],\n            $args['headers']\n        );\n    }\n\n    /**\n     * Execute an action on the controller.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function callAction($method, $parameters)\n    {\n        return $this->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Routing/composer.json",
    "content": "{\n    \"name\": \"illuminate/routing\",\n    \"description\": \"The Illuminate Routing package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-filter\": \"*\",\n        \"ext-hash\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/http\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/pipeline\": \"^13.0\",\n        \"illuminate/session\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-kernel\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/polyfill-php84\": \"^1.33\",\n        \"symfony/polyfill-php85\": \"^1.33\",\n        \"symfony/routing\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"suggest\": {\n        \"illuminate/console\": \"Required to use the make commands (^13.0).\",\n        \"php-http/discovery\": \"Required to use PSR-7 bridging features (^1.15).\",\n        \"symfony/psr-http-message-bridge\": \"Required to use PSR-7 bridging features (^7.4 || ^8.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Routing\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"allow-plugins\": {\n            \"php-http/discovery\": false\n        },\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Session/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Session/ArraySessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Support\\InteractsWithTime;\nuse SessionHandlerInterface;\n\nclass ArraySessionHandler implements SessionHandlerInterface\n{\n    use InteractsWithTime;\n\n    /**\n     * The array of stored values.\n     *\n     * @var array\n     */\n    protected $storage = [];\n\n    /**\n     * The number of minutes the session should be valid.\n     *\n     * @var int\n     */\n    protected $minutes;\n\n    /**\n     * Create a new array driven handler instance.\n     *\n     * @param  int  $minutes\n     */\n    public function __construct($minutes)\n    {\n        $this->minutes = $minutes;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string|false\n     */\n    public function read($sessionId): string|false\n    {\n        if (! isset($this->storage[$sessionId])) {\n            return '';\n        }\n\n        $session = $this->storage[$sessionId];\n\n        $expiration = $this->calculateExpiration($this->minutes * 60);\n\n        if (isset($session['time']) && $session['time'] >= $expiration) {\n            return $session['data'];\n        }\n\n        return '';\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        $this->storage[$sessionId] = [\n            'data' => $data,\n            'time' => $this->currentTime(),\n        ];\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        if (isset($this->storage[$sessionId])) {\n            unset($this->storage[$sessionId]);\n        }\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        $expiration = $this->calculateExpiration($lifetime);\n\n        $deletedSessions = 0;\n\n        foreach ($this->storage as $sessionId => $session) {\n            if ($session['time'] < $expiration) {\n                unset($this->storage[$sessionId]);\n                $deletedSessions++;\n            }\n        }\n\n        return $deletedSessions;\n    }\n\n    /**\n     * Get the expiration time of the session.\n     *\n     * @param  int  $seconds\n     * @return int\n     */\n    protected function calculateExpiration($seconds)\n    {\n        return $this->currentTime() - $seconds;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/CacheBasedSessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Contracts\\Cache\\Repository as CacheContract;\nuse SessionHandlerInterface;\n\nclass CacheBasedSessionHandler implements SessionHandlerInterface\n{\n    /**\n     * The cache repository instance.\n     *\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cache;\n\n    /**\n     * The number of minutes to store the data in the cache.\n     *\n     * @var int\n     */\n    protected $minutes;\n\n    /**\n     * Create a new cache driven handler instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cache\\Repository  $cache\n     * @param  int  $minutes\n     */\n    public function __construct(CacheContract $cache, $minutes)\n    {\n        $this->cache = $cache;\n        $this->minutes = $minutes;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string\n     */\n    public function read($sessionId): string\n    {\n        return $this->cache->get($sessionId, '');\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        return $this->cache->put($sessionId, $data, $this->minutes * 60);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        return $this->cache->forget($sessionId);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        return 0;\n    }\n\n    /**\n     * Get the underlying cache repository.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function getCache()\n    {\n        return $this->cache;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/Console/SessionTableCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Session\\Console;\n\nuse Illuminate\\Console\\MigrationGeneratorCommand;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[AsCommand(name: 'make:session-table', aliases: ['session:table'])]\nclass SessionTableCommand extends MigrationGeneratorCommand\n{\n    /**\n     * The console command name.\n     *\n     * @var string\n     */\n    protected $name = 'make:session-table';\n\n    /**\n     * The console command name aliases.\n     *\n     * @var array\n     */\n    protected $aliases = ['session:table'];\n\n    /**\n     * The console command description.\n     *\n     * @var string\n     */\n    protected $description = 'Create a migration for the session database table';\n\n    /**\n     * Get the migration table name.\n     *\n     * @return string\n     */\n    protected function migrationTableName()\n    {\n        return 'sessions';\n    }\n\n    /**\n     * Get the path to the migration stub file.\n     *\n     * @return string\n     */\n    protected function migrationStubFile()\n    {\n        return __DIR__.'/stubs/database.stub';\n    }\n\n    /**\n     * Determine whether a migration for the table already exists.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    protected function migrationExists($table)\n    {\n        foreach ([\n            join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php'),\n            join_paths($this->laravel->databasePath('migrations'), '0001_01_01_000000_create_users_table.php'),\n        ] as $path) {\n            if (count($this->files->glob($path)) !== 0) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/Console/stubs/database.stub",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     */\n    public function up(): void\n    {\n        Schema::create('sessions', function (Blueprint $table) {\n            $table->string('id')->primary();\n            $table->foreignId('user_id')->nullable()->index();\n            $table->string('ip_address', 45)->nullable();\n            $table->text('user_agent')->nullable();\n            $table->longText('payload');\n            $table->integer('last_activity')->index();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('sessions');\n    }\n};\n"
  },
  {
    "path": "src/Illuminate/Session/CookieSessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Contracts\\Cookie\\QueueingFactory as CookieJar;\nuse Illuminate\\Support\\InteractsWithTime;\nuse SessionHandlerInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass CookieSessionHandler implements SessionHandlerInterface\n{\n    use InteractsWithTime;\n\n    /**\n     * The cookie jar instance.\n     *\n     * @var \\Illuminate\\Contracts\\Cookie\\Factory\n     */\n    protected $cookie;\n\n    /**\n     * The request instance.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\Request\n     */\n    protected $request;\n\n    /**\n     * The number of minutes the session should be valid.\n     *\n     * @var int\n     */\n    protected $minutes;\n\n    /**\n     * Indicates whether the session should be expired when the browser closes.\n     *\n     * @var bool\n     */\n    protected $expireOnClose;\n\n    /**\n     * Create a new cookie driven handler instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Cookie\\QueueingFactory  $cookie\n     * @param  int  $minutes\n     * @param  bool  $expireOnClose\n     */\n    public function __construct(CookieJar $cookie, $minutes, $expireOnClose = false)\n    {\n        $this->cookie = $cookie;\n        $this->minutes = $minutes;\n        $this->expireOnClose = $expireOnClose;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string|false\n     */\n    public function read($sessionId): string|false\n    {\n        $value = $this->request->cookies->get($sessionId) ?: '';\n\n        if (! is_null($decoded = json_decode($value, true)) && is_array($decoded) &&\n            isset($decoded['expires']) && $this->currentTime() <= $decoded['expires']) {\n            return $decoded['data'];\n        }\n\n        return '';\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        $this->cookie->queue($sessionId, json_encode([\n            'data' => $data,\n            'expires' => $this->availableAt($this->minutes * 60),\n        ]), $this->expireOnClose ? 0 : $this->minutes);\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        $this->cookie->queue($this->cookie->forget($sessionId));\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        return 0;\n    }\n\n    /**\n     * Set the request instance.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Request  $request\n     * @return void\n     */\n    public function setRequest(Request $request)\n    {\n        $this->request = $request;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/DatabaseSessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Contracts\\Auth\\Guard;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\InteractsWithTime;\nuse SessionHandlerInterface;\n\nclass DatabaseSessionHandler implements ExistenceAwareInterface, SessionHandlerInterface\n{\n    use InteractsWithTime;\n\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected $connection;\n\n    /**\n     * The name of the session table.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The number of minutes the session should be valid.\n     *\n     * @var int\n     */\n    protected $minutes;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container|null\n     */\n    protected $container;\n\n    /**\n     * The existence state of the session.\n     *\n     * @var bool\n     */\n    protected $exists;\n\n    /**\n     * Create a new database session handler instance.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionInterface  $connection\n     * @param  string  $table\n     * @param  int  $minutes\n     * @param  \\Illuminate\\Contracts\\Container\\Container|null  $container\n     */\n    public function __construct(ConnectionInterface $connection, $table, $minutes, ?Container $container = null)\n    {\n        $this->table = $table;\n        $this->minutes = $minutes;\n        $this->container = $container;\n        $this->connection = $connection;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string|false\n     */\n    public function read($sessionId): string|false\n    {\n        $session = (object) $this->getQuery()->find($sessionId);\n\n        if ($this->expired($session)) {\n            $this->exists = true;\n\n            return '';\n        }\n\n        if (isset($session->payload)) {\n            $this->exists = true;\n\n            return base64_decode($session->payload);\n        }\n\n        return '';\n    }\n\n    /**\n     * Determine if the session is expired.\n     *\n     * @param  \\stdClass  $session\n     * @return bool\n     */\n    protected function expired($session)\n    {\n        return isset($session->last_activity) &&\n            $session->last_activity < Carbon::now()->subMinutes($this->minutes)->getTimestamp();\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        $payload = $this->getDefaultPayload($data);\n\n        if (! $this->exists) {\n            $this->read($sessionId);\n        }\n\n        if ($this->exists) {\n            $this->performUpdate($sessionId, $payload);\n        } else {\n            $this->performInsert($sessionId, $payload);\n        }\n\n        return $this->exists = true;\n    }\n\n    /**\n     * Perform an insert operation on the session ID.\n     *\n     * @param  string  $sessionId\n     * @param  array<string, mixed>  $payload\n     * @return bool|null\n     */\n    protected function performInsert($sessionId, $payload)\n    {\n        try {\n            return $this->getQuery()->insert(Arr::set($payload, 'id', $sessionId));\n        } catch (QueryException) {\n            $this->performUpdate($sessionId, $payload);\n        }\n    }\n\n    /**\n     * Perform an update operation on the session ID.\n     *\n     * @param  string  $sessionId\n     * @param  array<string, mixed>  $payload\n     * @return int\n     */\n    protected function performUpdate($sessionId, $payload)\n    {\n        return $this->getQuery()->where('id', $sessionId)->update($payload);\n    }\n\n    /**\n     * Get the default payload for the session.\n     *\n     * @param  string  $data\n     * @return array\n     */\n    protected function getDefaultPayload($data)\n    {\n        $payload = [\n            'payload' => base64_encode($data),\n            'last_activity' => $this->currentTime(),\n        ];\n\n        if (! $this->container) {\n            return $payload;\n        }\n\n        return tap($payload, function (&$payload) {\n            $this->addUserInformation($payload)\n                ->addRequestInformation($payload);\n        });\n    }\n\n    /**\n     * Add the user information to the session payload.\n     *\n     * @param  array  $payload\n     * @return $this\n     */\n    protected function addUserInformation(&$payload)\n    {\n        if ($this->container->bound(Guard::class)) {\n            $payload['user_id'] = $this->userId();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the currently authenticated user's ID.\n     *\n     * @return mixed\n     */\n    protected function userId()\n    {\n        return $this->container->make(Guard::class)->id();\n    }\n\n    /**\n     * Add the request information to the session payload.\n     *\n     * @param  array  $payload\n     * @return $this\n     */\n    protected function addRequestInformation(&$payload)\n    {\n        if ($this->container->bound('request')) {\n            $payload = array_merge($payload, [\n                'ip_address' => $this->ipAddress(),\n                'user_agent' => $this->userAgent(),\n            ]);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the IP address for the current request.\n     *\n     * @return string|null\n     */\n    protected function ipAddress()\n    {\n        return $this->container->make('request')->ip();\n    }\n\n    /**\n     * Get the user agent for the current request.\n     *\n     * @return string\n     */\n    protected function userAgent()\n    {\n        return mb_substr(mb_convert_encoding((string) $this->container->make('request')->header('User-Agent'), 'UTF-8'), 0, 500);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        $this->getQuery()->where('id', $sessionId)->delete();\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        return $this->getQuery()->where('last_activity', '<=', $this->currentTime() - $lifetime)->delete();\n    }\n\n    /**\n     * Get a fresh query builder instance for the table.\n     *\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function getQuery()\n    {\n        return $this->connection->table($this->table)->useWritePdo();\n    }\n\n    /**\n     * Set the application instance used by the handler.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $container\n     * @return $this\n     */\n    public function setContainer($container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Set the existence state for the session.\n     *\n     * @param  bool  $value\n     * @return $this\n     */\n    public function setExists($value)\n    {\n        $this->exists = $value;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/EncryptedStore.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Contracts\\Encryption\\Encrypter as EncrypterContract;\nuse SessionHandlerInterface;\n\nclass EncryptedStore extends Store\n{\n    /**\n     * The encrypter instance.\n     *\n     * @var \\Illuminate\\Contracts\\Encryption\\Encrypter\n     */\n    protected $encrypter;\n\n    /**\n     * Create a new session instance.\n     *\n     * @param  string  $name\n     * @param  \\SessionHandlerInterface  $handler\n     * @param  \\Illuminate\\Contracts\\Encryption\\Encrypter  $encrypter\n     * @param  string|null  $id\n     * @param  string  $serialization\n     */\n    public function __construct($name, SessionHandlerInterface $handler, EncrypterContract $encrypter, $id = null, $serialization = 'php')\n    {\n        $this->encrypter = $encrypter;\n\n        parent::__construct($name, $handler, $id, $serialization);\n    }\n\n    /**\n     * Prepare the raw string data from the session for unserialization.\n     *\n     * @param  string  $data\n     * @return string\n     */\n    protected function prepareForUnserialize($data)\n    {\n        try {\n            return $this->encrypter->decrypt($data);\n        } catch (DecryptException) {\n            return $this->serialization === 'json' ? json_encode([]) : serialize([]);\n        }\n    }\n\n    /**\n     * Prepare the serialized session data for storage.\n     *\n     * @param  string  $data\n     * @return string\n     */\n    protected function prepareForStorage($data)\n    {\n        return $this->encrypter->encrypt($data);\n    }\n\n    /**\n     * Get the encrypter instance.\n     *\n     * @return \\Illuminate\\Contracts\\Encryption\\Encrypter\n     */\n    public function getEncrypter()\n    {\n        return $this->encrypter;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/ExistenceAwareInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\ninterface ExistenceAwareInterface\n{\n    /**\n     * Set the existence state for the session.\n     *\n     * @param  bool  $value\n     * @return \\SessionHandlerInterface\n     */\n    public function setExists($value);\n}\n"
  },
  {
    "path": "src/Illuminate/Session/FileSessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Carbon;\nuse SessionHandlerInterface;\nuse Symfony\\Component\\Finder\\Finder;\n\nclass FileSessionHandler implements SessionHandlerInterface\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The path where sessions should be stored.\n     *\n     * @var string\n     */\n    protected $path;\n\n    /**\n     * The number of minutes the session should be valid.\n     *\n     * @var int\n     */\n    protected $minutes;\n\n    /**\n     * Create a new file driven handler instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $path\n     * @param  int  $minutes\n     */\n    public function __construct(Filesystem $files, $path, $minutes)\n    {\n        $this->path = $path;\n        $this->files = $files;\n        $this->minutes = $minutes;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string|false\n     */\n    public function read($sessionId): string|false\n    {\n        if ($this->files->isFile($path = $this->path.'/'.$sessionId) &&\n            $this->files->lastModified($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {\n            return $this->files->sharedGet($path);\n        }\n\n        return '';\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        $this->files->put($this->path.'/'.$sessionId, $data, true);\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        $this->files->delete($this->path.'/'.$sessionId);\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        $files = Finder::create()\n            ->in($this->path)\n            ->files()\n            ->ignoreDotFiles(true)\n            ->date('<= now - '.$lifetime.' seconds');\n\n        $deletedSessions = 0;\n\n        foreach ($files as $file) {\n            $this->files->delete($file->getRealPath());\n            $deletedSessions++;\n        }\n\n        return $deletedSessions;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Session/Middleware/AuthenticateSession.php",
    "content": "<?php\n\nnamespace Illuminate\\Session\\Middleware;\n\nuse BadMethodCallException;\nuse Closure;\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Contracts\\Auth\\Factory as AuthFactory;\nuse Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions;\nuse Illuminate\\Http\\Request;\n\nclass AuthenticateSession implements AuthenticatesSessions\n{\n    /**\n     * The authentication factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Auth\\Factory\n     */\n    protected $auth;\n\n    /**\n     * The callback that should be used to generate the authentication redirect path.\n     *\n     * @var callable\n     */\n    protected static $redirectToCallback;\n\n    /**\n     * Create a new middleware instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Auth\\Factory  $auth\n     */\n    public function __construct(AuthFactory $auth)\n    {\n        $this->auth = $auth;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        if (! $request->hasSession() || ! $request->user() || ! $request->user()->getAuthPassword()) {\n            return $next($request);\n        }\n\n        if ($this->guard()->viaRemember()) {\n            $passwordHashFromCookie = explode('|', $request->cookies->get($this->guard()->getRecallerName()))[2] ?? null;\n\n            if (! $passwordHashFromCookie ||\n                ! $this->validatePasswordHash($request->user()->getAuthPassword(), $passwordHashFromCookie)) {\n                $this->logout($request);\n            }\n        }\n\n        if (! $request->session()->has('password_hash_'.$this->auth->getDefaultDriver())) {\n            $this->storePasswordHashInSession($request);\n        }\n\n        $sessionPasswordHash = $request->session()->get('password_hash_'.$this->auth->getDefaultDriver());\n\n        if (! $this->validatePasswordHash($request->user()->getAuthPassword(), $sessionPasswordHash)) {\n            $this->logout($request);\n        }\n\n        return tap($next($request), function () use ($request) {\n            if (! is_null($this->guard()->user())) {\n                $this->storePasswordHashInSession($request);\n            }\n        });\n    }\n\n    /**\n     * Store the user's current password hash in the session.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function storePasswordHashInSession($request)\n    {\n        if (! $request->user()) {\n            return;\n        }\n\n        $passwordHash = $request->user()->getAuthPassword();\n\n        try {\n            $passwordHash = $this->guard()->hashPasswordForCookie($passwordHash);\n        } catch (BadMethodCallException) {\n        }\n\n        $request->session()->put([\n            'password_hash_'.$this->auth->getDefaultDriver() => $passwordHash,\n        ]);\n    }\n\n    /**\n     * Validate the password hash against the stored value.\n     *\n     * @param  string  $passwordHash\n     * @param  string  $storedValue\n     * @return bool\n     */\n    protected function validatePasswordHash($passwordHash, $storedValue)\n    {\n        try {\n            // Try new HMAC format first, then fall back to raw password hash format for backward compatibility\n            return hash_equals($this->guard()->hashPasswordForCookie($passwordHash), $storedValue)\n                || hash_equals($passwordHash, $storedValue);\n        } catch (BadMethodCallException) {\n            return hash_equals($passwordHash, $storedValue);\n        }\n    }\n\n    /**\n     * Log the user out of the application.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    protected function logout($request)\n    {\n        $this->guard()->logoutCurrentDevice();\n\n        $request->session()->flush();\n\n        throw new AuthenticationException(\n            'Unauthenticated.', [$this->auth->getDefaultDriver()], $this->redirectTo($request)\n        );\n    }\n\n    /**\n     * Get the guard instance that should be used by the middleware.\n     *\n     * @return \\Illuminate\\Contracts\\Auth\\Factory|\\Illuminate\\Contracts\\Auth\\Guard\n     */\n    protected function guard()\n    {\n        return $this->auth;\n    }\n\n    /**\n     * Get the path the user should be redirected to when their session is not authenticated.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return string|null\n     */\n    protected function redirectTo(Request $request)\n    {\n        if (static::$redirectToCallback) {\n            return call_user_func(static::$redirectToCallback, $request);\n        }\n    }\n\n    /**\n     * Specify the callback that should be used to generate the redirect path.\n     *\n     * @param  callable  $redirectToCallback\n     * @return void\n     */\n    public static function redirectUsing(callable $redirectToCallback)\n    {\n        static::$redirectToCallback = $redirectToCallback;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/Middleware/StartSession.php",
    "content": "<?php\n\nnamespace Illuminate\\Session\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Session\\SessionManager;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nclass StartSession\n{\n    /**\n     * The session manager.\n     *\n     * @var \\Illuminate\\Session\\SessionManager\n     */\n    protected $manager;\n\n    /**\n     * The callback that can resolve an instance of the cache factory.\n     *\n     * @var callable|null\n     */\n    protected $cacheFactoryResolver;\n\n    /**\n     * Create a new session middleware.\n     *\n     * @param  \\Illuminate\\Session\\SessionManager  $manager\n     * @param  callable|null  $cacheFactoryResolver\n     */\n    public function __construct(SessionManager $manager, ?callable $cacheFactoryResolver = null)\n    {\n        $this->manager = $manager;\n        $this->cacheFactoryResolver = $cacheFactoryResolver;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        if (! $this->sessionConfigured()) {\n            return $next($request);\n        }\n\n        $session = $this->getSession($request);\n\n        if ($this->manager->shouldBlock() ||\n            ($request->route() instanceof Route && $request->route()->locksFor())) {\n            return $this->handleRequestWhileBlocking($request, $session, $next);\n        }\n\n        return $this->handleStatefulRequest($request, $session, $next);\n    }\n\n    /**\n     * Handle the given request within session state.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    protected function handleRequestWhileBlocking(Request $request, $session, Closure $next)\n    {\n        if (! $request->route() instanceof Route) {\n            return;\n        }\n\n        $lockFor = $request->route() && $request->route()->locksFor()\n            ? $request->route()->locksFor()\n            : $this->manager->defaultRouteBlockLockSeconds();\n\n        $lock = $this->cache($this->manager->blockDriver())\n            ->lock('session:'.$session->getId(), $lockFor)\n            ->betweenBlockedAttemptsSleepFor(50);\n\n        try {\n            $lock->block(\n                ! is_null($request->route()->waitsFor())\n                    ? $request->route()->waitsFor()\n                    : $this->manager->defaultRouteBlockWaitSeconds()\n            );\n\n            return $this->handleStatefulRequest($request, $session, $next);\n        } finally {\n            $lock?->release();\n        }\n    }\n\n    /**\n     * Handle the given request within session state.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    protected function handleStatefulRequest(Request $request, $session, Closure $next)\n    {\n        // If a session driver has been configured, we will need to start the session here\n        // so that the data is ready for an application. Note that the Laravel sessions\n        // do not make use of PHP \"native\" sessions in any way since they are crappy.\n        $request->setLaravelSession(\n            $this->startSession($request, $session)\n        );\n\n        $this->collectGarbage($session);\n\n        $response = $next($request);\n\n        $this->storeCurrentUrl($request, $session);\n\n        $this->addCookieToResponse($response, $session);\n\n        // Again, if the session has been configured we will need to close out the session\n        // so that the attributes may be persisted to some storage medium. We will also\n        // add the session identifier cookie to the application response headers now.\n        $this->saveSession($request);\n\n        return $response;\n    }\n\n    /**\n     * Start the session for the given request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @return \\Illuminate\\Contracts\\Session\\Session\n     */\n    protected function startSession(Request $request, $session)\n    {\n        return tap($session, function ($session) use ($request) {\n            $session->setRequestOnHandler($request);\n\n            $session->start();\n        });\n    }\n\n    /**\n     * Get the session implementation from the manager.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Contracts\\Session\\Session\n     */\n    public function getSession(Request $request)\n    {\n        return tap($this->manager->driver(), function ($session) use ($request) {\n            $session->setId($request->cookies->get($session->getName()));\n        });\n    }\n\n    /**\n     * Remove the garbage from the session if necessary.\n     *\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @return void\n     */\n    protected function collectGarbage(Session $session)\n    {\n        $config = $this->manager->getSessionConfig();\n\n        // Here we will see if this request hits the garbage collection lottery by hitting\n        // the odds needed to perform garbage collection on any given request. If we do\n        // hit it, we'll call this handler to let it delete all the expired sessions.\n        if ($this->configHitsLottery($config)) {\n            $session->getHandler()->gc($this->getSessionLifetimeInSeconds());\n        }\n    }\n\n    /**\n     * Determine if the configuration odds hit the lottery.\n     *\n     * @param  array  $config\n     * @return bool\n     */\n    protected function configHitsLottery(array $config)\n    {\n        return random_int(1, $config['lottery'][1]) <= $config['lottery'][0];\n    }\n\n    /**\n     * Store the current URL for the request if necessary.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @return void\n     */\n    protected function storeCurrentUrl(Request $request, $session)\n    {\n        if ($request->isMethod('GET') &&\n            $request->route() instanceof Route &&\n            ! $request->ajax() &&\n            ! $request->prefetch() &&\n            ! $request->isPrecognitive()) {\n            $session->setPreviousUrl($request->fullUrl());\n\n            if (method_exists($session, 'setPreviousRoute')) {\n                $session->setPreviousRoute($request->route()->getName());\n            }\n        }\n    }\n\n    /**\n     * Add the session cookie to the application response.\n     *\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response  $response\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $session\n     * @return void\n     */\n    protected function addCookieToResponse(Response $response, Session $session)\n    {\n        if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) {\n            $response->headers->setCookie(new Cookie(\n                $session->getName(),\n                $session->getId(),\n                $this->getCookieExpirationDate(),\n                $config['path'],\n                $config['domain'],\n                $config['secure'],\n                $config['http_only'] ?? true,\n                false,\n                $config['same_site'] ?? null,\n                $config['partitioned'] ?? false\n            ));\n        }\n    }\n\n    /**\n     * Save the session data to storage.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function saveSession($request)\n    {\n        if (! $request->isPrecognitive()) {\n            $this->manager->driver()->save();\n        }\n    }\n\n    /**\n     * Get the session lifetime in seconds.\n     *\n     * @return int\n     */\n    protected function getSessionLifetimeInSeconds()\n    {\n        return ($this->manager->getSessionConfig()['lifetime'] ?? null) * 60;\n    }\n\n    /**\n     * Get the cookie lifetime in seconds.\n     *\n     * @return \\DateTimeInterface|int\n     */\n    protected function getCookieExpirationDate()\n    {\n        $expiresOnClose = $this->manager->getSessionConfig()['expire_on_close'];\n\n        return $expiresOnClose ? 0 : Date::instance(\n            Carbon::now()->addSeconds($this->getSessionLifetimeInSeconds())\n        );\n    }\n\n    /**\n     * Determine if a session driver has been configured.\n     *\n     * @return bool\n     */\n    protected function sessionConfigured()\n    {\n        return ! is_null($this->manager->getSessionConfig()['driver'] ?? null);\n    }\n\n    /**\n     * Determine if the configured session driver is persistent.\n     *\n     * @param  array|null  $config\n     * @return bool\n     */\n    protected function sessionIsPersistent(?array $config = null)\n    {\n        $config = $config ?: $this->manager->getSessionConfig();\n\n        return ! is_null($config['driver'] ?? null);\n    }\n\n    /**\n     * Resolve the given cache driver.\n     *\n     * @param  string  $driver\n     * @return \\Illuminate\\Cache\\Store\n     */\n    protected function cache($driver)\n    {\n        return call_user_func($this->cacheFactoryResolver)->driver($driver);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/NullSessionHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse SessionHandlerInterface;\n\nclass NullSessionHandler implements SessionHandlerInterface\n{\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function open($savePath, $sessionName): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function close(): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return string\n     */\n    public function read($sessionId): string\n    {\n        return '';\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function write($sessionId, $data): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return bool\n     */\n    public function destroy($sessionId): bool\n    {\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @return int\n     */\n    public function gc($lifetime): int\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/SessionManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Support\\Manager;\n\n/**\n * @mixin \\Illuminate\\Session\\Store\n */\nclass SessionManager extends Manager\n{\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  string  $driver\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function callCustomCreator($driver)\n    {\n        return $this->buildSession(parent::callCustomCreator($driver));\n    }\n\n    /**\n     * Create an instance of the \"null\" session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createNullDriver()\n    {\n        return $this->buildSession(new NullSessionHandler);\n    }\n\n    /**\n     * Create an instance of the \"array\" session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createArrayDriver()\n    {\n        return $this->buildSession(new ArraySessionHandler(\n            $this->config->get('session.lifetime')\n        ));\n    }\n\n    /**\n     * Create an instance of the \"cookie\" session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createCookieDriver()\n    {\n        return $this->buildSession(new CookieSessionHandler(\n            $this->container->make('cookie'),\n            $this->config->get('session.lifetime'),\n            $this->config->get('session.expire_on_close')\n        ));\n    }\n\n    /**\n     * Create an instance of the file session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createFileDriver()\n    {\n        return $this->createNativeDriver();\n    }\n\n    /**\n     * Create an instance of the file session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createNativeDriver()\n    {\n        $lifetime = $this->config->get('session.lifetime');\n\n        return $this->buildSession(new FileSessionHandler(\n            $this->container->make('files'), $this->config->get('session.files'), $lifetime\n        ));\n    }\n\n    /**\n     * Create an instance of the database session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createDatabaseDriver()\n    {\n        $table = $this->config->get('session.table');\n\n        $lifetime = $this->config->get('session.lifetime');\n\n        return $this->buildSession(new DatabaseSessionHandler(\n            $this->getDatabaseConnection(), $table, $lifetime, $this->container\n        ));\n    }\n\n    /**\n     * Get the database connection for the database driver.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function getDatabaseConnection()\n    {\n        $connection = $this->config->get('session.connection');\n\n        return $this->container->make('db')->connection($connection);\n    }\n\n    /**\n     * Create an instance of the APC session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createApcDriver()\n    {\n        return $this->createCacheBased('apc');\n    }\n\n    /**\n     * Create an instance of the Memcached session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createMemcachedDriver()\n    {\n        return $this->createCacheBased('memcached');\n    }\n\n    /**\n     * Create an instance of the Redis session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createRedisDriver()\n    {\n        $handler = $this->createCacheHandler('redis');\n\n        $handler->getCache()->getStore()->setConnection(\n            $this->config->get('session.connection')\n        );\n\n        return $this->buildSession($handler);\n    }\n\n    /**\n     * Create an instance of the DynamoDB session driver.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createDynamodbDriver()\n    {\n        return $this->createCacheBased('dynamodb');\n    }\n\n    /**\n     * Create an instance of a cache driven driver.\n     *\n     * @param  string  $driver\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function createCacheBased($driver)\n    {\n        return $this->buildSession($this->createCacheHandler($driver));\n    }\n\n    /**\n     * Create the cache based session handler instance.\n     *\n     * @param  string  $driver\n     * @return \\Illuminate\\Session\\CacheBasedSessionHandler\n     */\n    protected function createCacheHandler($driver)\n    {\n        $store = $this->config->get('session.store') ?: $driver;\n\n        return new CacheBasedSessionHandler(\n            clone $this->container->make('cache')->store($store),\n            $this->config->get('session.lifetime')\n        );\n    }\n\n    /**\n     * Build the session instance.\n     *\n     * @param  \\SessionHandlerInterface  $handler\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function buildSession($handler)\n    {\n        return $this->config->get('session.encrypt')\n            ? $this->buildEncryptedSession($handler)\n            : new Store(\n                $this->config->get('session.cookie'),\n                $handler,\n                $id = null,\n                $this->config->get('session.serialization', 'php')\n            );\n    }\n\n    /**\n     * Build the encrypted session instance.\n     *\n     * @param  \\SessionHandlerInterface  $handler\n     * @return \\Illuminate\\Session\\EncryptedStore\n     */\n    protected function buildEncryptedSession($handler)\n    {\n        return new EncryptedStore(\n            $this->config->get('session.cookie'),\n            $handler,\n            $this->container['encrypter'],\n            $id = null,\n            $this->config->get('session.serialization', 'php'),\n        );\n    }\n\n    /**\n     * Determine if requests for the same session should wait for each to finish before executing.\n     *\n     * @return bool\n     */\n    public function shouldBlock()\n    {\n        return $this->config->get('session.block', false);\n    }\n\n    /**\n     * Get the name of the cache store / driver that should be used to acquire session locks.\n     *\n     * @return string|null\n     */\n    public function blockDriver()\n    {\n        return $this->config->get('session.block_store');\n    }\n\n    /**\n     * Get the maximum number of seconds the session lock should be held for.\n     *\n     * @return int\n     */\n    public function defaultRouteBlockLockSeconds()\n    {\n        return $this->config->get('session.block_lock_seconds', 10);\n    }\n\n    /**\n     * Get the maximum number of seconds to wait while attempting to acquire a route block session lock.\n     *\n     * @return int\n     */\n    public function defaultRouteBlockWaitSeconds()\n    {\n        return $this->config->get('session.block_wait_seconds', 10);\n    }\n\n    /**\n     * Get the session configuration.\n     *\n     * @return array\n     */\n    public function getSessionConfig()\n    {\n        return $this->config->get('session');\n    }\n\n    /**\n     * Get the default session driver name.\n     *\n     * @return string|null\n     */\n    public function getDefaultDriver()\n    {\n        return $this->config->get('session.driver');\n    }\n\n    /**\n     * Set the default session driver name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultDriver($name)\n    {\n        $this->config->set('session.driver', $name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/SessionServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Illuminate\\Contracts\\Cache\\Factory as CacheFactory;\nuse Illuminate\\Session\\Middleware\\StartSession;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass SessionServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerSessionManager();\n\n        $this->registerSessionDriver();\n\n        $this->app->singleton(StartSession::class, function ($app) {\n            return new StartSession($app->make(SessionManager::class), function () use ($app) {\n                return $app->make(CacheFactory::class);\n            });\n        });\n    }\n\n    /**\n     * Register the session manager instance.\n     *\n     * @return void\n     */\n    protected function registerSessionManager()\n    {\n        $this->app->singleton('session', function ($app) {\n            return new SessionManager($app);\n        });\n    }\n\n    /**\n     * Register the session driver instance.\n     *\n     * @return void\n     */\n    protected function registerSessionDriver()\n    {\n        $this->app->singleton('session.store', function ($app) {\n            // First, we will create the session manager which is responsible for the\n            // creation of the various session drivers when they are needed by the\n            // application instance, and will resolve them on a lazy load basis.\n            return $app->make('session')->driver();\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/Store.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse BackedEnum;\nuse Closure;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Support\\ViewErrorBag;\nuse RuntimeException;\nuse SessionHandlerInterface;\nuse stdClass;\nuse UnitEnum;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Store implements Session\n{\n    use Macroable;\n\n    /**\n     * The length of session ID strings.\n     *\n     * @var int\n     */\n    protected const SESSION_ID_LENGTH = 40;\n\n    /**\n     * The session ID.\n     *\n     * @var string\n     */\n    protected $id;\n\n    /**\n     * The session name.\n     *\n     * @var string\n     */\n    protected $name;\n\n    /**\n     * The session attributes.\n     *\n     * @var array\n     */\n    protected $attributes = [];\n\n    /**\n     * The session handler implementation.\n     *\n     * @var \\SessionHandlerInterface\n     */\n    protected $handler;\n\n    /**\n     * The session store's serialization strategy.\n     *\n     * @var string\n     */\n    protected $serialization = 'php';\n\n    /**\n     * Session store started status.\n     *\n     * @var bool\n     */\n    protected $started = false;\n\n    /**\n     * Create a new session instance.\n     *\n     * @param  string  $name\n     * @param  \\SessionHandlerInterface  $handler\n     * @param  string|null  $id\n     * @param  string  $serialization\n     */\n    public function __construct($name, SessionHandlerInterface $handler, $id = null, $serialization = 'php')\n    {\n        $this->setId($id);\n        $this->name = $name;\n        $this->handler = $handler;\n        $this->serialization = $serialization;\n    }\n\n    /**\n     * Start the session, reading the data from a handler.\n     *\n     * @return bool\n     */\n    public function start()\n    {\n        $this->loadSession();\n\n        if (! $this->has('_token')) {\n            $this->regenerateToken();\n        }\n\n        return $this->started = true;\n    }\n\n    /**\n     * Load the session data from the handler.\n     *\n     * @return void\n     */\n    protected function loadSession()\n    {\n        $this->attributes = array_replace($this->attributes, $this->readFromHandler());\n\n        $this->marshalErrorBag();\n    }\n\n    /**\n     * Read the session data from the handler.\n     *\n     * @return array\n     */\n    protected function readFromHandler()\n    {\n        if ($data = $this->handler->read($this->getId())) {\n            if ($this->serialization === 'json') {\n                $data = json_decode($this->prepareForUnserialize($data), true);\n            } else {\n                $data = @unserialize($this->prepareForUnserialize($data));\n            }\n\n            if ($data !== false && is_array($data)) {\n                return $data;\n            }\n        }\n\n        return [];\n    }\n\n    /**\n     * Prepare the raw string data from the session for unserialization.\n     *\n     * @param  string  $data\n     * @return string\n     */\n    protected function prepareForUnserialize($data)\n    {\n        return $data;\n    }\n\n    /**\n     * Marshal the ViewErrorBag when using JSON serialization for sessions.\n     *\n     * @return void\n     */\n    protected function marshalErrorBag()\n    {\n        if ($this->serialization !== 'json' || $this->missing('errors')) {\n            return;\n        }\n\n        $errorBag = new ViewErrorBag;\n\n        foreach ($this->get('errors') as $key => $value) {\n            $messageBag = new MessageBag($value['messages']);\n\n            $errorBag->put($key, $messageBag->setFormat($value['format']));\n        }\n\n        $this->put('errors', $errorBag);\n    }\n\n    /**\n     * Save the session data to storage.\n     *\n     * @return void\n     */\n    public function save()\n    {\n        $this->ageFlashData();\n\n        $this->prepareErrorBagForSerialization();\n\n        $this->handler->write($this->getId(), $this->prepareForStorage(\n            $this->serialization === 'json' ? json_encode($this->attributes) : serialize($this->attributes)\n        ));\n\n        $this->started = false;\n    }\n\n    /**\n     * Prepare the ViewErrorBag instance for JSON serialization.\n     *\n     * @return void\n     */\n    protected function prepareErrorBagForSerialization()\n    {\n        if ($this->serialization !== 'json' || $this->missing('errors')) {\n            return;\n        }\n\n        $errors = [];\n\n        foreach ($this->attributes['errors']->getBags() as $key => $value) {\n            $errors[$key] = [\n                'format' => $value->getFormat(),\n                'messages' => $value->getMessages(),\n            ];\n        }\n\n        $this->attributes['errors'] = $errors;\n    }\n\n    /**\n     * Prepare the serialized session data for storage.\n     *\n     * @param  string  $data\n     * @return string\n     */\n    protected function prepareForStorage($data)\n    {\n        return $data;\n    }\n\n    /**\n     * Age the flash data for the session.\n     *\n     * @return void\n     */\n    public function ageFlashData()\n    {\n        $this->forget($this->get('_flash.old', []));\n\n        $this->put('_flash.old', $this->get('_flash.new', []));\n\n        $this->put('_flash.new', []);\n    }\n\n    /**\n     * Get all of the session data.\n     *\n     * @return array\n     */\n    public function all()\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Get a subset of the session data.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function only(array $keys)\n    {\n        return Arr::only($this->attributes, $keys);\n    }\n\n    /**\n     * Get all the session data except for a specified array of items.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public function except(array $keys)\n    {\n        return Arr::except($this->attributes, $keys);\n    }\n\n    /**\n     * Checks if a key exists.\n     *\n     * @param  \\UnitEnum|string|array  $key\n     * @return bool\n     */\n    public function exists($key)\n    {\n        $placeholder = new stdClass;\n\n        return ! (new Collection(is_array($key) ? $key : func_get_args()))->contains(function ($key) use ($placeholder) {\n            return $this->get($key, $placeholder) === $placeholder;\n        });\n    }\n\n    /**\n     * Determine if the given key is missing from the session data.\n     *\n     * @param  \\UnitEnum|string|array  $key\n     * @return bool\n     */\n    public function missing($key)\n    {\n        return ! $this->exists($key);\n    }\n\n    /**\n     * Determine if a key is present and not null.\n     *\n     * @param  \\UnitEnum|string|array  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        return ! (new Collection(is_array($key) ? $key : func_get_args()))->contains(function ($key) {\n            return is_null($this->get($key));\n        });\n    }\n\n    /**\n     * Determine if any of the given keys are present and not null.\n     *\n     * @param  \\UnitEnum|string|array  $key\n     * @return bool\n     */\n    public function hasAny($key)\n    {\n        return (new Collection(is_array($key) ? $key : func_get_args()))->filter(function ($key) {\n            return ! is_null($this->get($key));\n        })->count() >= 1;\n    }\n\n    /**\n     * Get an item from the session.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null)\n    {\n        return Arr::get($this->attributes, enum_value($key), $default);\n    }\n\n    /**\n     * Get the value of a given key and then forget it.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function pull($key, $default = null)\n    {\n        return Arr::pull($this->attributes, enum_value($key), $default);\n    }\n\n    /**\n     * Determine if the session contains old input.\n     *\n     * @param  string|null  $key\n     * @return bool\n     */\n    public function hasOldInput($key = null)\n    {\n        $old = $this->getOldInput($key);\n\n        return is_null($key) ? count($old) > 0 : ! is_null($old);\n    }\n\n    /**\n     * Get the requested item from the flashed input array.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function getOldInput($key = null, $default = null)\n    {\n        return Arr::get($this->get('_old_input', []), $key, $default);\n    }\n\n    /**\n     * Replace the given session attributes entirely.\n     *\n     * @param  array  $attributes\n     * @return void\n     */\n    public function replace(array $attributes)\n    {\n        $this->put($attributes);\n    }\n\n    /**\n     * Put a key / value pair or array of key / value pairs in the session.\n     *\n     * @param  \\UnitEnum|string|array  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function put($key, $value = null)\n    {\n        if (! is_array($key)) {\n            $key = [enum_value($key) => $value];\n        }\n\n        foreach ($key as $arrayKey => $arrayValue) {\n            Arr::set($this->attributes, enum_value($arrayKey), $arrayValue);\n        }\n    }\n\n    /**\n     * Get an item from the session, or store the default value.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function remember($key, Closure $callback)\n    {\n        if (! is_null($value = $this->get($key))) {\n            return $value;\n        }\n\n        return tap($callback(), function ($value) use ($key) {\n            $this->put($key, $value);\n        });\n    }\n\n    /**\n     * Push a value onto a session array.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function push($key, $value)\n    {\n        $array = $this->get($key, []);\n\n        $array[] = $value;\n\n        $this->put($key, $array);\n    }\n\n    /**\n     * Increment the value of an item in the session.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  int  $amount\n     * @return mixed\n     */\n    public function increment($key, $amount = 1)\n    {\n        $this->put($key, $value = $this->get($key, 0) + $amount);\n\n        return $value;\n    }\n\n    /**\n     * Decrement the value of an item in the session.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  int  $amount\n     * @return int\n     */\n    public function decrement($key, $amount = 1)\n    {\n        return $this->increment($key, $amount * -1);\n    }\n\n    /**\n     * Flash a key / value pair to the session.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function flash(BackedEnum|UnitEnum|string $key, $value = true)\n    {\n        $key = enum_value($key);\n\n        $this->put($key, $value);\n\n        $this->push('_flash.new', $key);\n\n        $this->removeFromOldFlashData([$key]);\n    }\n\n    /**\n     * Flash a key / value pair to the session for immediate use.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function now($key, $value)\n    {\n        $key = enum_value($key);\n\n        $this->put($key, $value);\n\n        $this->push('_flash.old', $key);\n    }\n\n    /**\n     * Reflash all of the session flash data.\n     *\n     * @return void\n     */\n    public function reflash()\n    {\n        $this->mergeNewFlashes($this->get('_flash.old', []));\n\n        $this->put('_flash.old', []);\n    }\n\n    /**\n     * Reflash a subset of the current flash data.\n     *\n     * @param  mixed  $keys\n     * @return void\n     */\n    public function keep($keys = null)\n    {\n        $this->mergeNewFlashes($keys = is_array($keys) ? $keys : func_get_args());\n\n        $this->removeFromOldFlashData($keys);\n    }\n\n    /**\n     * Merge new flash keys into the new flash array.\n     *\n     * @param  array  $keys\n     * @return void\n     */\n    protected function mergeNewFlashes(array $keys)\n    {\n        $values = array_unique(array_merge($this->get('_flash.new', []), $keys));\n\n        $this->put('_flash.new', $values);\n    }\n\n    /**\n     * Remove the given keys from the old flash data.\n     *\n     * @param  array  $keys\n     * @return void\n     */\n    protected function removeFromOldFlashData(array $keys)\n    {\n        $this->put('_flash.old', array_diff($this->get('_flash.old', []), $keys));\n    }\n\n    /**\n     * Flash an input array to the session.\n     *\n     * @param  array  $value\n     * @return void\n     */\n    public function flashInput(array $value)\n    {\n        $this->flash('_old_input', $value);\n    }\n\n    /**\n     * Get the session cache instance.\n     *\n     * @return \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    public function cache()\n    {\n        return Cache::store('session');\n    }\n\n    /**\n     * Remove an item from the session, returning its value.\n     *\n     * @param  \\UnitEnum|string  $key\n     * @return mixed\n     */\n    public function remove($key)\n    {\n        return Arr::pull($this->attributes, enum_value($key));\n    }\n\n    /**\n     * Remove one or many items from the session.\n     *\n     * @param  \\UnitEnum|string|array  $keys\n     * @return void\n     */\n    public function forget($keys)\n    {\n        Arr::forget($this->attributes, (new Collection((array) $keys))->map(fn ($key) => enum_value($key))->all());\n    }\n\n    /**\n     * Remove all of the items from the session.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        $this->attributes = [];\n    }\n\n    /**\n     * Flush the session data and regenerate the ID.\n     *\n     * @return bool\n     */\n    public function invalidate()\n    {\n        $this->flush();\n\n        return $this->migrate(true);\n    }\n\n    /**\n     * Generate a new session identifier.\n     *\n     * @param  bool  $destroy\n     * @return bool\n     */\n    public function regenerate($destroy = false)\n    {\n        return tap($this->migrate($destroy), function () {\n            $this->regenerateToken();\n        });\n    }\n\n    /**\n     * Generate a new session ID for the session.\n     *\n     * @param  bool  $destroy\n     * @return bool\n     */\n    public function migrate($destroy = false)\n    {\n        if ($destroy) {\n            $this->handler->destroy($this->getId());\n        }\n\n        $this->setExists(false);\n\n        $this->setId($this->generateSessionId());\n\n        return true;\n    }\n\n    /**\n     * Determine if the session has been started.\n     *\n     * @return bool\n     */\n    public function isStarted()\n    {\n        return $this->started;\n    }\n\n    /**\n     * Get the name of the session.\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * Set the name of the session.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setName($name)\n    {\n        $this->name = $name;\n    }\n\n    /**\n     * Get the current session ID.\n     *\n     * @return string\n     */\n    public function id()\n    {\n        return $this->getId();\n    }\n\n    /**\n     * Get the current session ID.\n     *\n     * @return string\n     */\n    public function getId()\n    {\n        return $this->id;\n    }\n\n    /**\n     * Set the session ID.\n     *\n     * @param  string|null  $id\n     * @return void\n     */\n    public function setId($id)\n    {\n        $this->id = $this->isValidId($id) ? $id : $this->generateSessionId();\n    }\n\n    /**\n     * Determine if this is a valid session ID.\n     *\n     * @param  string|null  $id\n     * @return bool\n     */\n    public function isValidId($id)\n    {\n        return is_string($id) && ctype_alnum($id) && strlen($id) === self::SESSION_ID_LENGTH;\n    }\n\n    /**\n     * Get a new, random session ID.\n     *\n     * @return string\n     */\n    protected function generateSessionId()\n    {\n        return Str::random(self::SESSION_ID_LENGTH);\n    }\n\n    /**\n     * Set the existence of the session on the handler if applicable.\n     *\n     * @param  bool  $value\n     * @return void\n     */\n    public function setExists($value)\n    {\n        if ($this->handler instanceof ExistenceAwareInterface) {\n            $this->handler->setExists($value);\n        }\n    }\n\n    /**\n     * Get the CSRF token value.\n     *\n     * @return string\n     */\n    public function token()\n    {\n        return $this->get('_token');\n    }\n\n    /**\n     * Regenerate the CSRF token value.\n     *\n     * @return void\n     */\n    public function regenerateToken()\n    {\n        $this->put('_token', Str::random(self::SESSION_ID_LENGTH));\n    }\n\n    /**\n     * Determine if the previous URI is available.\n     *\n     * @return bool\n     */\n    public function hasPreviousUri()\n    {\n        return ! is_null($this->previousUrl());\n    }\n\n    /**\n     * Get the previous URL from the session as a URI instance.\n     *\n     * @return \\Illuminate\\Support\\Uri\n     *\n     * @throws \\RuntimeException\n     */\n    public function previousUri()\n    {\n        if ($previousUrl = $this->previousUrl()) {\n            return Uri::of($previousUrl);\n        }\n\n        throw new RuntimeException('Unable to generate URI instance for previous URL. No previous URL detected.');\n    }\n\n    /**\n     * Get the previous URL from the session.\n     *\n     * @return string|null\n     */\n    public function previousUrl()\n    {\n        return $this->get('_previous.url');\n    }\n\n    /**\n     * Set the \"previous\" URL in the session.\n     *\n     * @param  string  $url\n     * @return void\n     */\n    public function setPreviousUrl($url)\n    {\n        $this->put('_previous.url', $url);\n    }\n\n    /**\n     * Get the previous route name from the session.\n     *\n     * @return string|null\n     */\n    public function previousRoute()\n    {\n        return $this->get('_previous.route');\n    }\n\n    /**\n     * Set the \"previous\" route name in the session.\n     *\n     * @param  string|null  $route\n     * @return void\n     */\n    public function setPreviousRoute($route)\n    {\n        $this->put('_previous.route', $route);\n    }\n\n    /**\n     * Specify that the user has confirmed their password.\n     *\n     * @return void\n     */\n    public function passwordConfirmed()\n    {\n        $this->put('auth.password_confirmed_at', Date::now()->unix());\n    }\n\n    /**\n     * Get the underlying session handler implementation.\n     *\n     * @return \\SessionHandlerInterface\n     */\n    public function getHandler()\n    {\n        return $this->handler;\n    }\n\n    /**\n     * Set the underlying session handler implementation.\n     *\n     * @param  \\SessionHandlerInterface  $handler\n     * @return \\SessionHandlerInterface\n     */\n    public function setHandler(SessionHandlerInterface $handler)\n    {\n        return $this->handler = $handler;\n    }\n\n    /**\n     * Determine if the session handler needs a request.\n     *\n     * @return bool\n     */\n    public function handlerNeedsRequest()\n    {\n        return $this->handler instanceof CookieSessionHandler;\n    }\n\n    /**\n     * Set the request on the handler instance.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    public function setRequestOnHandler($request)\n    {\n        if ($this->handlerNeedsRequest()) {\n            $this->handler->setRequest($request);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/SymfonySessionDecorator.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface;\nuse Symfony\\Component\\HttpFoundation\\Session\\SessionInterface;\nuse Symfony\\Component\\HttpFoundation\\Session\\Storage\\MetadataBag;\n\nclass SymfonySessionDecorator implements SessionInterface\n{\n    /**\n     * The underlying Laravel session store.\n     *\n     * @var \\Illuminate\\Contracts\\Session\\Session\n     */\n    public readonly Session $store;\n\n    /**\n     * Create a new session decorator.\n     *\n     * @param  \\Illuminate\\Contracts\\Session\\Session  $store\n     */\n    public function __construct(Session $store)\n    {\n        $this->store = $store;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function start(): bool\n    {\n        return $this->store->start();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getId(): string\n    {\n        return $this->store->getId();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function setId(string $id): void\n    {\n        $this->store->setId($id);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getName(): string\n    {\n        return $this->store->getName();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function setName(string $name): void\n    {\n        $this->store->setName($name);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function invalidate(?int $lifetime = null): bool\n    {\n        $this->store->invalidate();\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function migrate(bool $destroy = false, ?int $lifetime = null): bool\n    {\n        $this->store->migrate($destroy);\n\n        return true;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function save(): void\n    {\n        $this->store->save();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function has(string $name): bool\n    {\n        return $this->store->has($name);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function get(string $name, mixed $default = null): mixed\n    {\n        return $this->store->get($name, $default);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function set(string $name, mixed $value): void\n    {\n        $this->store->put($name, $value);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function all(): array\n    {\n        return $this->store->all();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function replace(array $attributes): void\n    {\n        $this->store->replace($attributes);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function remove(string $name): mixed\n    {\n        return $this->store->remove($name);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function clear(): void\n    {\n        $this->store->flush();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function isStarted(): bool\n    {\n        return $this->store->isStarted();\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function registerBag(SessionBagInterface $bag): void\n    {\n        throw new BadMethodCallException('Method not implemented by Laravel.');\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function getBag(string $name): SessionBagInterface\n    {\n        throw new BadMethodCallException('Method not implemented by Laravel.');\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function getMetadataBag(): MetadataBag\n    {\n        throw new BadMethodCallException('Method not implemented by Laravel.');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Session/TokenMismatchException.php",
    "content": "<?php\n\nnamespace Illuminate\\Session;\n\nuse Exception;\n\nclass TokenMismatchException extends Exception\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Session/composer.json",
    "content": "{\n    \"name\": \"illuminate/session\",\n    \"description\": \"The Illuminate Session package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-ctype\": \"*\",\n        \"ext-session\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/filesystem\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"symfony/finder\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"suggest\": {\n        \"illuminate/console\": \"Required to use the session:table command (^13.0).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Session\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Support/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Support/AggregateServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nclass AggregateServiceProvider extends ServiceProvider\n{\n    /**\n     * The provider class names.\n     *\n     * @var array<int, class-string<\\Illuminate\\Support\\ServiceProvider>>\n     */\n    protected $providers = [];\n\n    /**\n     * An array of the service provider instances.\n     *\n     * @var array<int, \\Illuminate\\Support\\ServiceProvider>\n     */\n    protected $instances = [];\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->instances = [];\n\n        foreach ($this->providers as $provider) {\n            $this->instances[] = $this->app->register($provider);\n        }\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array<int, string>\n     */\n    public function provides()\n    {\n        $provides = [];\n\n        foreach ($this->providers as $provider) {\n            $instance = $this->app->resolveProvider($provider);\n\n            $provides = array_merge($provides, $instance->provides());\n        }\n\n        return $provides;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Benchmark.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass Benchmark\n{\n    use Macroable;\n\n    /**\n     * Measure a callable or array of callables over the given number of iterations.\n     *\n     * @param  \\Closure|array  $benchmarkables\n     * @param  int  $iterations\n     * @return array|float\n     */\n    public static function measure(Closure|array $benchmarkables, int $iterations = 1): array|float\n    {\n        return Collection::wrap($benchmarkables)->map(function ($callback) use ($iterations) {\n            return Collection::range(1, $iterations)->map(function () use ($callback) {\n                gc_collect_cycles();\n\n                $start = hrtime(true);\n\n                $callback();\n\n                return (hrtime(true) - $start) / 1_000_000;\n            })->average();\n        })->when(\n            $benchmarkables instanceof Closure,\n            fn ($c) => $c->first(),\n            fn ($c) => $c->all(),\n        );\n    }\n\n    /**\n     * Measure a callable once and return the result and duration in milliseconds.\n     *\n     * @template TReturn of mixed\n     *\n     * @param  (callable(): TReturn)  $callback\n     * @return array{0: TReturn, 1: float}\n     */\n    public static function value(callable $callback): array\n    {\n        gc_collect_cycles();\n\n        $start = hrtime(true);\n\n        $result = $callback();\n\n        return [$result, (hrtime(true) - $start) / 1_000_000];\n    }\n\n    /**\n     * Measure a callable or array of callables over the given number of iterations, then dump and die.\n     *\n     * @param  \\Closure|array  $benchmarkables\n     * @param  int  $iterations\n     * @return never\n     */\n    public static function dd(Closure|array $benchmarkables, int $iterations = 1): never\n    {\n        $result = (new Collection(static::measure(Arr::wrap($benchmarkables), $iterations)))\n            ->map(fn ($average) => number_format($average, 3).'ms')\n            ->when($benchmarkables instanceof Closure, fn ($c) => $c->first(), fn ($c) => $c->all());\n\n        dd($result);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/BinaryCodec.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse InvalidArgumentException;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidInterface;\nuse Symfony\\Component\\Uid\\Ulid;\n\nclass BinaryCodec\n{\n    /** @var array<string, array{encode: callable(UuidInterface|Ulid|string|null): ?string, decode: callable(?string): ?string}> */\n    protected static array $customCodecs = [];\n\n    /**\n     * Register a custom codec.\n     */\n    public static function register(string $name, callable $encode, callable $decode): void\n    {\n        self::$customCodecs[$name] = [\n            'encode' => $encode,\n            'decode' => $decode,\n        ];\n    }\n\n    /**\n     * Encode a value to binary.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function encode(UuidInterface|Ulid|string|null $value, string $format): ?string\n    {\n        if (blank($value)) {\n            return null;\n        }\n\n        if (isset(self::$customCodecs[$format])) {\n            return (self::$customCodecs[$format]['encode'])($value);\n        }\n\n        return match ($format) {\n            'uuid' => match (true) {\n                $value instanceof UuidInterface => $value->getBytes(),\n                self::isBinary($value) => $value,\n                default => Uuid::fromString($value)->getBytes(),\n            },\n            'ulid' => match (true) {\n                $value instanceof Ulid => $value->toBinary(),\n                self::isBinary($value) => $value,\n                default => Ulid::fromString($value)->toBinary(),\n            },\n            default => throw new InvalidArgumentException(\"Format [$format] is invalid.\"),\n        };\n    }\n\n    /**\n     * Decode a binary value to string.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function decode(?string $value, string $format): ?string\n    {\n        if (blank($value)) {\n            return null;\n        }\n\n        if (isset(self::$customCodecs[$format])) {\n            return (self::$customCodecs[$format]['decode'])($value);\n        }\n\n        return match ($format) {\n            'uuid' => (self::isBinary($value) ? Uuid::fromBytes($value) : Uuid::fromString($value))->toString(),\n            'ulid' => (self::isBinary($value) ? Ulid::fromBinary($value) : Ulid::fromString($value))->toString(),\n            default => throw new InvalidArgumentException(\"Format [$format] is invalid.\"),\n        };\n    }\n\n    /**\n     * Get all available format names.\n     *\n     * @return list<string>\n     */\n    public static function formats(): array\n    {\n        return array_unique([...['uuid', 'ulid'], ...array_keys(self::$customCodecs)]);\n    }\n\n    /**\n     * Determine if the given value is binary data.\n     */\n    public static function isBinary(mixed $value): bool\n    {\n        if (! is_string($value) || $value === '') {\n            return false;\n        }\n\n        if (str_contains($value, \"\\0\")) {\n            return true;\n        }\n\n        return ! mb_check_encoding($value, 'UTF-8');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Carbon.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Carbon\\Carbon as BaseCarbon;\nuse Carbon\\CarbonImmutable as BaseCarbonImmutable;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Ramsey\\Uuid\\Uuid;\nuse Symfony\\Component\\Uid\\Ulid;\n\nclass Carbon extends BaseCarbon\n{\n    use Conditionable, Dumpable;\n\n    /**\n     * {@inheritdoc}\n     */\n    public static function setTestNow(mixed $testNow = null): void\n    {\n        BaseCarbon::setTestNow($testNow);\n        BaseCarbonImmutable::setTestNow($testNow);\n    }\n\n    /**\n     * Create a Carbon instance from a given ordered UUID or ULID.\n     */\n    public static function createFromId(Uuid|Ulid|string $id): static\n    {\n        if (is_string($id)) {\n            $id = Ulid::isValid($id) ? Ulid::fromString($id) : Uuid::fromString($id);\n        }\n\n        return static::createFromInterface($id->getDateTime());\n    }\n\n    /**\n     * Get the current date / time plus a given amount of time.\n     */\n    public function plus(\n        int $years = 0,\n        int $months = 0,\n        int $weeks = 0,\n        int $days = 0,\n        int $hours = 0,\n        int $minutes = 0,\n        int $seconds = 0,\n        int $microseconds = 0\n    ): static {\n        return $this->add(\"\n            $years years $months months $weeks weeks $days days\n            $hours hours $minutes minutes $seconds seconds $microseconds microseconds\n        \");\n    }\n\n    /**\n     * Get the current date / time minus a given amount of time.\n     */\n    public function minus(\n        int $years = 0,\n        int $months = 0,\n        int $weeks = 0,\n        int $days = 0,\n        int $hours = 0,\n        int $minutes = 0,\n        int $seconds = 0,\n        int $microseconds = 0\n    ): static {\n        return $this->sub(\"\n            $years years $months months $weeks weeks $days days\n            $hours hours $minutes minutes $seconds seconds $microseconds microseconds\n        \");\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Composer.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Filesystem\\Filesystem;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Process\\Process;\n\nclass Composer\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The working path to regenerate from.\n     *\n     * @var string|null\n     */\n    protected $workingPath;\n\n    /**\n     * Create a new Composer manager instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string|null  $workingPath\n     */\n    public function __construct(Filesystem $files, $workingPath = null)\n    {\n        $this->files = $files;\n        $this->workingPath = $workingPath;\n    }\n\n    /**\n     * Determine if the given Composer package is installed.\n     *\n     * @param  string  $package\n     * @return bool\n     *\n     * @throws \\RuntimeException\n     */\n    public function hasPackage($package)\n    {\n        $composer = json_decode(file_get_contents($this->findComposerFile()), true);\n\n        return array_key_exists($package, $composer['require'] ?? [])\n            || array_key_exists($package, $composer['require-dev'] ?? []);\n    }\n\n    /**\n     * Install the given Composer packages into the application.\n     *\n     * @param  array<int, string>  $packages\n     * @param  bool  $dev\n     * @param  \\Closure|\\Symfony\\Component\\Console\\Output\\OutputInterface|null  $output\n     * @param  string|null  $composerBinary\n     * @return bool\n     */\n    public function requirePackages(array $packages, bool $dev = false, Closure|OutputInterface|null $output = null, $composerBinary = null)\n    {\n        $command = (new Collection([\n            ...$this->findComposer($composerBinary),\n            'require',\n            ...$packages,\n        ]))\n            ->when($dev, function ($command) {\n                $command->push('--dev');\n            })->all();\n\n        return 0 === $this->getProcess($command, ['COMPOSER_MEMORY_LIMIT' => '-1'])\n            ->run(\n                $output instanceof OutputInterface\n                    ? function ($type, $line) use ($output) {\n                        $output->write('    '.$line);\n                    } : $output\n            );\n    }\n\n    /**\n     * Remove the given Composer packages from the application.\n     *\n     * @param  array<int, string>  $packages\n     * @param  bool  $dev\n     * @param  \\Closure|\\Symfony\\Component\\Console\\Output\\OutputInterface|null  $output\n     * @param  string|null  $composerBinary\n     * @return bool\n     */\n    public function removePackages(array $packages, bool $dev = false, Closure|OutputInterface|null $output = null, $composerBinary = null)\n    {\n        $command = (new Collection([\n            ...$this->findComposer($composerBinary),\n            'remove',\n            ...$packages,\n        ]))\n            ->when($dev, function ($command) {\n                $command->push('--dev');\n            })->all();\n\n        return 0 === $this->getProcess($command, ['COMPOSER_MEMORY_LIMIT' => '-1'])\n            ->run(\n                $output instanceof OutputInterface\n                    ? function ($type, $line) use ($output) {\n                        $output->write('    '.$line);\n                    } : $output\n            );\n    }\n\n    /**\n     * Modify the \"composer.json\" file contents using the given callback.\n     *\n     * @param  callable(array):array  $callback\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function modify(callable $callback)\n    {\n        $composerFile = $this->findComposerFile();\n\n        $composer = json_decode(file_get_contents($composerFile), true, 512, JSON_THROW_ON_ERROR);\n\n        file_put_contents(\n            $composerFile,\n            json_encode(\n                call_user_func($callback, $composer),\n                JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE\n            )\n        );\n    }\n\n    /**\n     * Regenerate the Composer autoloader files.\n     *\n     * @param  string|array  $extra\n     * @param  string|null  $composerBinary\n     * @return int\n     */\n    public function dumpAutoloads($extra = '', $composerBinary = null)\n    {\n        $extra = $extra ? (array) $extra : [];\n\n        $command = array_merge($this->findComposer($composerBinary), ['dump-autoload'], $extra);\n\n        return $this->getProcess($command)->run();\n    }\n\n    /**\n     * Regenerate the optimized Composer autoloader files.\n     *\n     * @param  string|null  $composerBinary\n     * @return int\n     */\n    public function dumpOptimized($composerBinary = null)\n    {\n        return $this->dumpAutoloads('--optimize', $composerBinary);\n    }\n\n    /**\n     * Get the Composer binary / command for the environment.\n     *\n     * @param  string|null  $composerBinary\n     * @return array\n     */\n    public function findComposer($composerBinary = null)\n    {\n        if (! is_null($composerBinary) && $this->files->exists($composerBinary)) {\n            return [$this->phpBinary(), $composerBinary];\n        } elseif ($this->files->exists($this->workingPath.'/composer.phar')) {\n            return [$this->phpBinary(), 'composer.phar'];\n        }\n\n        return ['composer'];\n    }\n\n    /**\n     * Get the path to the \"composer.json\" file.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected function findComposerFile()\n    {\n        $composerFile = \"{$this->workingPath}/composer.json\";\n\n        if (! file_exists($composerFile)) {\n            throw new RuntimeException(\"Unable to locate `composer.json` file at [{$this->workingPath}].\");\n        }\n\n        return $composerFile;\n    }\n\n    /**\n     * Get the PHP binary.\n     *\n     * @return string\n     */\n    protected function phpBinary()\n    {\n        return php_binary();\n    }\n\n    /**\n     * Get a new Symfony process instance.\n     *\n     * @param  array  $command\n     * @param  array  $env\n     * @return \\Symfony\\Component\\Process\\Process\n     */\n    protected function getProcess(array $command, array $env = [])\n    {\n        return (new Process($command, $this->workingPath, $env))->setTimeout(null);\n    }\n\n    /**\n     * Set the working path used by the class.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function setWorkingPath($path)\n    {\n        $this->workingPath = realpath($path);\n\n        return $this;\n    }\n\n    /**\n     * Get the version of Composer.\n     *\n     * @return string|null\n     */\n    public function getVersion()\n    {\n        $command = array_merge($this->findComposer(), ['-V', '--no-ansi']);\n\n        $process = $this->getProcess($command);\n\n        $process->run();\n\n        $output = $process->getOutput();\n\n        if (preg_match('/(\\d+(\\.\\d+){2})/', $output, $version)) {\n            return $version[1];\n        }\n\n        return explode(' ', $output)[2] ?? null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/ConfigurationUrlParser.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse InvalidArgumentException;\n\nclass ConfigurationUrlParser\n{\n    /**\n     * The drivers aliases map.\n     *\n     * @var array\n     */\n    protected static $driverAliases = [\n        'mssql' => 'sqlsrv',\n        'mysql2' => 'mysql', // RDS\n        'postgres' => 'pgsql',\n        'postgresql' => 'pgsql',\n        'sqlite3' => 'sqlite',\n        'redis' => 'tcp',\n        'rediss' => 'tls',\n    ];\n\n    /**\n     * Parse the database configuration, hydrating options using a database configuration URL if possible.\n     *\n     * @param  array|string  $config\n     * @return array\n     */\n    public function parseConfiguration($config)\n    {\n        if (is_string($config)) {\n            $config = ['url' => $config];\n        }\n\n        $url = Arr::pull($config, 'url');\n\n        if (! $url) {\n            return $config;\n        }\n\n        $rawComponents = $this->parseUrl($url);\n\n        $decodedComponents = $this->parseStringsToNativeTypes(\n            array_map(rawurldecode(...), $rawComponents)\n        );\n\n        return array_merge(\n            $config,\n            $this->getPrimaryOptions($decodedComponents),\n            $this->getQueryOptions($rawComponents)\n        );\n    }\n\n    /**\n     * Get the primary database connection options.\n     *\n     * @param  array  $url\n     * @return array\n     */\n    protected function getPrimaryOptions($url)\n    {\n        return array_filter([\n            'driver' => $this->getDriver($url),\n            'database' => $this->getDatabase($url),\n            'host' => $url['host'] ?? null,\n            'port' => $url['port'] ?? null,\n            'username' => $url['user'] ?? null,\n            'password' => $url['pass'] ?? null,\n        ], fn ($value) => ! is_null($value));\n    }\n\n    /**\n     * Get the database driver from the URL.\n     *\n     * @param  array  $url\n     * @return string|null\n     */\n    protected function getDriver($url)\n    {\n        $alias = $url['scheme'] ?? null;\n\n        if (! $alias) {\n            return;\n        }\n\n        return static::$driverAliases[$alias] ?? $alias;\n    }\n\n    /**\n     * Get the database name from the URL.\n     *\n     * @param  array  $url\n     * @return string|null\n     */\n    protected function getDatabase($url)\n    {\n        $path = $url['path'] ?? null;\n\n        return $path && $path !== '/' ? substr($path, 1) : null;\n    }\n\n    /**\n     * Get all of the additional database options from the query string.\n     *\n     * @param  array  $url\n     * @return array\n     */\n    protected function getQueryOptions($url)\n    {\n        $queryString = $url['query'] ?? null;\n\n        if (! $queryString) {\n            return [];\n        }\n\n        $query = [];\n\n        parse_str($queryString, $query);\n\n        return $this->parseStringsToNativeTypes($query);\n    }\n\n    /**\n     * Parse the string URL to an array of components.\n     *\n     * @param  string  $url\n     * @return array\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseUrl($url)\n    {\n        $url = preg_replace('#^(sqlite3?):///#', '$1://null/', $url);\n\n        $parsedUrl = parse_url($url);\n\n        if ($parsedUrl === false) {\n            throw new InvalidArgumentException('The database configuration URL is malformed.');\n        }\n\n        return $parsedUrl;\n    }\n\n    /**\n     * Convert string casted values to their native types.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    protected function parseStringsToNativeTypes($value)\n    {\n        if (is_array($value)) {\n            return array_map($this->parseStringsToNativeTypes(...), $value);\n        }\n\n        if (! is_string($value)) {\n            return $value;\n        }\n\n        $parsedValue = json_decode($value, true);\n\n        if (json_last_error() === JSON_ERROR_NONE) {\n            return $parsedValue;\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get all of the current drivers' aliases.\n     *\n     * @return array\n     */\n    public static function getDriverAliases()\n    {\n        return static::$driverAliases;\n    }\n\n    /**\n     * Add the given driver alias to the driver aliases array.\n     *\n     * @param  string  $alias\n     * @param  string  $driver\n     * @return void\n     */\n    public static function addDriverAlias($alias, $driver)\n    {\n        static::$driverAliases[$alias] = $driver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/DateFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Carbon\\Factory;\nuse InvalidArgumentException;\n\n/**\n * @see https://carbon.nesbot.com/docs/\n * @see https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Factory.php\n *\n * @method bool canBeCreatedFromFormat(?string $date, string $format)\n * @method \\Illuminate\\Support\\Carbon|null create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromDate($year = null, $month = null, $day = null, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon|null createFromFormat($format, $time, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon|null createFromIsoFormat(string $format, string $time, $timezone = null, ?string $locale = 'en', ?\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator = null)\n * @method \\Illuminate\\Support\\Carbon|null createFromLocaleFormat(string $format, string $locale, string $time, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon|null createFromLocaleIsoFormat(string $format, string $locale, string $time, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromTimeString(string $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromTimestamp(string|int|float $timestamp, \\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromTimestampMs(string|int|float $timestamp, \\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createFromTimestampMsUTC($timestamp)\n * @method \\Illuminate\\Support\\Carbon createFromTimestampUTC(string|int|float $timestamp)\n * @method \\Illuminate\\Support\\Carbon createMidnightDate($year = null, $month = null, $day = null, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon|null createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $timezone = null)\n * @method void disableHumanDiffOption($humanDiffOption)\n * @method void enableHumanDiffOption($humanDiffOption)\n * @method mixed executeWithLocale(string $locale, callable $func)\n * @method \\Illuminate\\Support\\Carbon fromSerialized($value)\n * @method array getAvailableLocales()\n * @method array getAvailableLocalesInfo()\n * @method array getDays()\n * @method ?string getFallbackLocale()\n * @method array getFormatsToIsoReplacements()\n * @method int getHumanDiffOptions()\n * @method array getIsoUnits()\n * @method array|false getLastErrors()\n * @method string getLocale()\n * @method int getMidDayAt()\n * @method string getTimeFormatByPrecision(string $unitPrecision)\n * @method string|\\Closure|null getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null)\n * @method \\Illuminate\\Support\\Carbon|null getTestNow()\n * @method \\Symfony\\Contracts\\Translation\\TranslatorInterface getTranslator()\n * @method int getWeekEndsAt(?string $locale = null)\n * @method int getWeekStartsAt(?string $locale = null)\n * @method array getWeekendDays()\n * @method bool hasFormat(string $date, string $format)\n * @method bool hasFormatWithModifiers(string $date, string $format)\n * @method bool hasMacro($name)\n * @method bool hasRelativeKeywords(?string $time)\n * @method bool hasTestNow()\n * @method \\Illuminate\\Support\\Carbon instance(\\DateTimeInterface $date)\n * @method bool isImmutable()\n * @method bool isModifiableUnit($unit)\n * @method bool isMutable()\n * @method bool isStrictModeEnabled()\n * @method bool localeHasDiffOneDayWords(string $locale)\n * @method bool localeHasDiffSyntax(string $locale)\n * @method bool localeHasDiffTwoDayWords(string $locale)\n * @method bool localeHasPeriodSyntax($locale)\n * @method bool localeHasShortUnits(string $locale)\n * @method void macro(string $name, ?callable $macro)\n * @method \\Illuminate\\Support\\Carbon|null make($var, \\DateTimeZone|string|null $timezone = null)\n * @method void mixin(object|string $mixin)\n * @method \\Illuminate\\Support\\Carbon now(\\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon parse(\\DateTimeInterface|\\Carbon\\WeekDay|\\Carbon\\Month|string|int|float|null $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon parseFromLocale(string $time, ?string $locale = null, \\DateTimeZone|string|int|null $timezone = null)\n * @method string pluralUnit(string $unit)\n * @method \\Illuminate\\Support\\Carbon|null rawCreateFromFormat(string $format, string $time, $timezone = null)\n * @method \\Illuminate\\Support\\Carbon rawParse(\\DateTimeInterface|\\Carbon\\WeekDay|\\Carbon\\Month|string|int|float|null $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method void resetMonthsOverflow()\n * @method void resetToStringFormat()\n * @method void resetYearsOverflow()\n * @method void serializeUsing($callback)\n * @method void setFallbackLocale(string $locale)\n * @method void setHumanDiffOptions($humanDiffOptions)\n * @method void setLocale(string $locale)\n * @method void setMidDayAt($hour)\n * @method void setTestNow(mixed $testNow = null)\n * @method void setTestNowAndTimezone(mixed $testNow = null, $timezone = null)\n * @method void setToStringFormat(string|\\Closure|null $format)\n * @method void setTranslator(\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator)\n * @method void setWeekEndsAt($day)\n * @method void setWeekStartsAt($day)\n * @method void setWeekendDays($days)\n * @method bool shouldOverflowMonths()\n * @method bool shouldOverflowYears()\n * @method string singularUnit(string $unit)\n * @method void sleep(int|float $seconds)\n * @method \\Illuminate\\Support\\Carbon today(\\DateTimeZone|string|int|null $timezone = null)\n * @method \\Illuminate\\Support\\Carbon tomorrow(\\DateTimeZone|string|int|null $timezone = null)\n * @method string translateTimeString(string $timeString, ?string $from = null, ?string $to = null, int $mode = \\Carbon\\CarbonInterface::TRANSLATE_ALL)\n * @method string translateWith(\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator, string $key, array $parameters = [], $number = null)\n * @method void useMonthsOverflow($monthsOverflow = true)\n * @method void useStrictMode($strictModeEnabled = true)\n * @method void useYearsOverflow($yearsOverflow = true)\n * @method mixed withTestNow(mixed $testNow, callable $callback)\n * @method static withTimeZone(\\DateTimeZone|string|int|null $timezone)\n * @method \\Illuminate\\Support\\Carbon yesterday(\\DateTimeZone|string|int|null $timezone = null)\n */\nclass DateFactory\n{\n    /**\n     * The default class that will be used for all created dates.\n     *\n     * @var string\n     */\n    const DEFAULT_CLASS_NAME = Carbon::class;\n\n    /**\n     * The type (class) of dates that should be created.\n     *\n     * @var string\n     */\n    protected static $dateClass;\n\n    /**\n     * This callable may be used to intercept date creation.\n     *\n     * @var callable\n     */\n    protected static $callable;\n\n    /**\n     * The Carbon factory that should be used when creating dates.\n     *\n     * @var object\n     */\n    protected static $factory;\n\n    /**\n     * Use the given handler when generating dates (class name, callable, or factory).\n     *\n     * @param  mixed  $handler\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function use($handler)\n    {\n        if (is_callable($handler) && is_object($handler)) {\n            return static::useCallable($handler);\n        } elseif (is_string($handler)) {\n            return static::useClass($handler);\n        } elseif ($handler instanceof Factory) {\n            return static::useFactory($handler);\n        }\n\n        throw new InvalidArgumentException('Invalid date creation handler. Please provide a class name, callable, or Carbon factory.');\n    }\n\n    /**\n     * Use the default date class when generating dates.\n     *\n     * @return void\n     */\n    public static function useDefault()\n    {\n        static::$dateClass = null;\n        static::$callable = null;\n        static::$factory = null;\n    }\n\n    /**\n     * Execute the given callable on each date creation.\n     *\n     * @param  callable  $callable\n     * @return void\n     */\n    public static function useCallable(callable $callable)\n    {\n        static::$callable = $callable;\n\n        static::$dateClass = null;\n        static::$factory = null;\n    }\n\n    /**\n     * Use the given date type (class) when generating dates.\n     *\n     * @param  string  $dateClass\n     * @return void\n     */\n    public static function useClass($dateClass)\n    {\n        static::$dateClass = $dateClass;\n\n        static::$factory = null;\n        static::$callable = null;\n    }\n\n    /**\n     * Use the given Carbon factory when generating dates.\n     *\n     * @param  object  $factory\n     * @return void\n     */\n    public static function useFactory($factory)\n    {\n        static::$factory = $factory;\n\n        static::$dateClass = null;\n        static::$callable = null;\n    }\n\n    /**\n     * Handle dynamic calls to generate dates.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public function __call($method, $parameters)\n    {\n        $defaultClassName = static::DEFAULT_CLASS_NAME;\n\n        // Using callable to generate dates...\n        if (static::$callable) {\n            return call_user_func(static::$callable, $defaultClassName::$method(...$parameters));\n        }\n\n        // Using Carbon factory to generate dates...\n        if (static::$factory) {\n            return static::$factory->$method(...$parameters);\n        }\n\n        $dateClass = static::$dateClass ?: $defaultClassName;\n\n        // Check if the date can be created using the public class method...\n        if (method_exists($dateClass, $method) ||\n            method_exists($dateClass, 'hasMacro') && $dateClass::hasMacro($method)) {\n            return $dateClass::$method(...$parameters);\n        }\n\n        // If that fails, create the date with the default class...\n        $date = $defaultClassName::$method(...$parameters);\n\n        // If the configured class has an \"instance\" method, we'll try to pass our date into there...\n        if (method_exists($dateClass, 'instance')) {\n            return $dateClass::instance($date);\n        }\n\n        // Otherwise, assume the configured class has a DateTime compatible constructor...\n        return new $dateClass($date->format('Y-m-d H:i:s.u'), $date->getTimezone());\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/DefaultProviders.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nclass DefaultProviders\n{\n    /**\n     * The current providers.\n     *\n     * @var array\n     */\n    protected $providers;\n\n    /**\n     * Create a new default provider collection.\n     */\n    public function __construct(?array $providers = null)\n    {\n        $this->providers = $providers ?: [\n            \\Illuminate\\Auth\\AuthServiceProvider::class,\n            \\Illuminate\\Broadcasting\\BroadcastServiceProvider::class,\n            \\Illuminate\\Bus\\BusServiceProvider::class,\n            \\Illuminate\\Cache\\CacheServiceProvider::class,\n            \\Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider::class,\n            \\Illuminate\\Concurrency\\ConcurrencyServiceProvider::class,\n            \\Illuminate\\Cookie\\CookieServiceProvider::class,\n            \\Illuminate\\Database\\DatabaseServiceProvider::class,\n            \\Illuminate\\Encryption\\EncryptionServiceProvider::class,\n            \\Illuminate\\Filesystem\\FilesystemServiceProvider::class,\n            \\Illuminate\\Foundation\\Providers\\FoundationServiceProvider::class,\n            \\Illuminate\\Hashing\\HashServiceProvider::class,\n            \\Illuminate\\Mail\\MailServiceProvider::class,\n            \\Illuminate\\Notifications\\NotificationServiceProvider::class,\n            \\Illuminate\\Pagination\\PaginationServiceProvider::class,\n            \\Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider::class,\n            \\Illuminate\\Pipeline\\PipelineServiceProvider::class,\n            \\Illuminate\\Queue\\QueueServiceProvider::class,\n            \\Illuminate\\Redis\\RedisServiceProvider::class,\n            \\Illuminate\\Session\\SessionServiceProvider::class,\n            \\Illuminate\\Translation\\TranslationServiceProvider::class,\n            \\Illuminate\\Validation\\ValidationServiceProvider::class,\n            \\Illuminate\\View\\ViewServiceProvider::class,\n        ];\n    }\n\n    /**\n     * Merge the given providers into the provider collection.\n     *\n     * @param  array  $providers\n     * @return static\n     */\n    public function merge(array $providers)\n    {\n        $this->providers = array_merge($this->providers, $providers);\n\n        return new static($this->providers);\n    }\n\n    /**\n     * Replace the given providers with other providers.\n     *\n     * @param  array  $replacements\n     * @return static\n     */\n    public function replace(array $replacements)\n    {\n        $current = new Collection($this->providers);\n\n        foreach ($replacements as $from => $to) {\n            $key = $current->search($from);\n\n            $current = is_int($key) ? $current->replace([$key => $to]) : $current;\n        }\n\n        return new static($current->values()->toArray());\n    }\n\n    /**\n     * Disable the given providers.\n     *\n     * @param  array  $providers\n     * @return static\n     */\n    public function except(array $providers)\n    {\n        return new static((new Collection($this->providers))\n            ->reject(fn ($p) => in_array($p, $providers))\n            ->values()\n            ->toArray());\n    }\n\n    /**\n     * Convert the provider collection to an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->providers;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Defer/DeferredCallback.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Defer;\n\nuse Illuminate\\Support\\Str;\n\nclass DeferredCallback\n{\n    /**\n     * Create a new deferred callback instance.\n     *\n     * @param  callable  $callback\n     */\n    public function __construct(public $callback, public ?string $name = null, public bool $always = false)\n    {\n        $this->name = $name ?? (string) Str::uuid();\n    }\n\n    /**\n     * Specify the name of the deferred callback so it can be cancelled later.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function name(string $name): static\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the deferred callback should run even on unsuccessful requests and jobs.\n     *\n     * @param  bool  $always\n     * @return $this\n     */\n    public function always(bool $always = true): static\n    {\n        $this->always = $always;\n\n        return $this;\n    }\n\n    /**\n     * Invoke the deferred callback.\n     *\n     * @return void\n     */\n    public function __invoke(): void\n    {\n        call_user_func($this->callback);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Defer/DeferredCallbackCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Defer;\n\nuse ArrayAccess;\nuse Closure;\nuse Countable;\nuse Illuminate\\Support\\Collection;\n\nclass DeferredCallbackCollection implements ArrayAccess, Countable\n{\n    /**\n     * All of the deferred callbacks.\n     *\n     * @var array\n     */\n    protected array $callbacks = [];\n\n    /**\n     * Get the first callback in the collection.\n     *\n     * @return callable\n     */\n    public function first()\n    {\n        return array_values($this->callbacks)[0];\n    }\n\n    /**\n     * Invoke the deferred callbacks.\n     *\n     * @return void\n     */\n    public function invoke(): void\n    {\n        $this->invokeWhen(fn () => true);\n    }\n\n    /**\n     * Invoke the deferred callbacks if the given truth test evaluates to true.\n     *\n     * @param  \\Closure|null  $when\n     * @return void\n     */\n    public function invokeWhen(?Closure $when = null): void\n    {\n        $when ??= fn () => true;\n\n        $this->forgetDuplicates();\n\n        foreach ($this->callbacks as $index => $callback) {\n            if ($when($callback)) {\n                rescue($callback);\n            }\n\n            unset($this->callbacks[$index]);\n        }\n    }\n\n    /**\n     * Remove any deferred callbacks with the given name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function forget(string $name): void\n    {\n        $this->callbacks = (new Collection($this->callbacks))\n            ->reject(fn ($callback) => $callback->name === $name)\n            ->values()\n            ->all();\n    }\n\n    /**\n     * Remove any duplicate callbacks.\n     *\n     * @return $this\n     */\n    protected function forgetDuplicates(): static\n    {\n        $this->callbacks = (new Collection($this->callbacks))\n            ->reverse()\n            ->unique(fn ($c) => $c->name)\n            ->reverse()\n            ->values()\n            ->all();\n\n        return $this;\n    }\n\n    /**\n     * Determine if the collection has a callback with the given key.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists(mixed $offset): bool\n    {\n        $this->forgetDuplicates();\n\n        return isset($this->callbacks[$offset]);\n    }\n\n    /**\n     * Get the callback with the given key.\n     *\n     * @param  mixed  $offset\n     * @return mixed\n     */\n    public function offsetGet(mixed $offset): mixed\n    {\n        $this->forgetDuplicates();\n\n        return $this->callbacks[$offset];\n    }\n\n    /**\n     * Set the callback with the given key.\n     *\n     * @param  mixed  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet(mixed $offset, mixed $value): void\n    {\n        if (is_null($offset)) {\n            $this->callbacks[] = $value;\n        } else {\n            $this->callbacks[$offset] = $value;\n        }\n    }\n\n    /**\n     * Remove the callback with the given key from the collection.\n     *\n     * @param  mixed  $offset\n     * @return void\n     */\n    public function offsetUnset(mixed $offset): void\n    {\n        $this->forgetDuplicates();\n\n        unset($this->callbacks[$offset]);\n    }\n\n    /**\n     * Determine how many callbacks are in the collection.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        $this->forgetDuplicates();\n\n        return count($this->callbacks);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/EncodedHtmlString.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse BackedEnum;\nuse Illuminate\\Contracts\\Support\\DeferringDisplayableValue;\nuse Illuminate\\Contracts\\Support\\Htmlable;\n\nclass EncodedHtmlString extends HtmlString\n{\n    /**\n     * The HTML string.\n     *\n     * @var \\Illuminate\\Contracts\\Support\\DeferringDisplayableValue|\\Illuminate\\Contracts\\Support\\Htmlable|\\BackedEnum|string|int|float|null\n     */\n    protected $html;\n\n    /**\n     * The callback that should be used to encode the HTML strings.\n     *\n     * @var callable|null\n     */\n    protected static $encodeUsingFactory;\n\n    /**\n     * Create a new encoded HTML string instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\DeferringDisplayableValue|\\Illuminate\\Contracts\\Support\\Htmlable|\\BackedEnum|string|int|float|null  $html\n     * @param  bool  $doubleEncode\n     */\n    public function __construct($html = '', protected bool $doubleEncode = true)\n    {\n        parent::__construct($html);\n    }\n\n    /**\n     * Convert the special characters in the given value.\n     *\n     * @internal\n     *\n     * @param  string|null  $value\n     * @param  int  $withQuote\n     * @param  bool  $doubleEncode\n     * @return string\n     */\n    public static function convert($value, bool $withQuote = true, bool $doubleEncode = true)\n    {\n        $flag = $withQuote ? ENT_QUOTES : ENT_NOQUOTES;\n\n        return htmlspecialchars($value ?? '', $flag | ENT_SUBSTITUTE, 'UTF-8', $doubleEncode);\n    }\n\n    /**\n     * Get the HTML string.\n     *\n     * @return string\n     */\n    #[\\Override]\n    public function toHtml()\n    {\n        $value = $this->html;\n\n        if ($value instanceof DeferringDisplayableValue) {\n            $value = $value->resolveDisplayableValue();\n        }\n\n        if ($value instanceof Htmlable) {\n            return $value->toHtml();\n        }\n\n        if ($value instanceof BackedEnum) {\n            $value = $value->value;\n        }\n\n        return (static::$encodeUsingFactory ?? function ($value, $doubleEncode) {\n            return static::convert($value, doubleEncode: $doubleEncode);\n        })($value, $this->doubleEncode);\n    }\n\n    /**\n     * Set the callable that will be used to encode the HTML strings.\n     *\n     * @param  callable|null  $factory\n     * @return void\n     */\n    public static function encodeUsing(?callable $factory = null)\n    {\n        static::$encodeUsingFactory = $factory;\n    }\n\n    /**\n     * Flush the class's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$encodeUsingFactory = null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Env.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Dotenv\\Repository\\Adapter\\PutenvAdapter;\nuse Dotenv\\Repository\\RepositoryBuilder;\nuse Illuminate\\Filesystem\\Filesystem;\nuse PhpOption\\Option;\nuse RuntimeException;\n\nclass Env\n{\n    /**\n     * Indicates if the putenv adapter is enabled.\n     *\n     * @var bool\n     */\n    protected static $putenv = true;\n\n    /**\n     * The environment repository instance.\n     *\n     * @var \\Dotenv\\Repository\\RepositoryInterface|null\n     */\n    protected static $repository;\n\n    /**\n     * The list of custom adapters for loading environment variables.\n     *\n     * @var array<Closure>\n     */\n    protected static $customAdapters = [];\n\n    /**\n     * Enable the putenv adapter.\n     *\n     * @return void\n     */\n    public static function enablePutenv()\n    {\n        static::$putenv = true;\n        static::$repository = null;\n    }\n\n    /**\n     * Disable the putenv adapter.\n     *\n     * @return void\n     */\n    public static function disablePutenv()\n    {\n        static::$putenv = false;\n        static::$repository = null;\n    }\n\n    /**\n     * Register a custom adapter creator Closure.\n     */\n    public static function extend(Closure $callback, ?string $name = null): void\n    {\n        if (! is_null($name)) {\n            static::$customAdapters[$name] = $callback;\n        } else {\n            static::$customAdapters[] = $callback;\n        }\n\n        static::$repository = null;\n    }\n\n    /**\n     * Get the environment repository instance.\n     *\n     * @return \\Dotenv\\Repository\\RepositoryInterface\n     */\n    public static function getRepository()\n    {\n        if (static::$repository === null) {\n            $builder = RepositoryBuilder::createWithDefaultAdapters();\n\n            if (static::$putenv) {\n                $builder = $builder->addAdapter(PutenvAdapter::class);\n            }\n\n            foreach (static::$customAdapters as $adapter) {\n                $builder = $builder->addAdapter($adapter());\n            }\n\n            static::$repository = $builder->immutable()->make();\n        }\n\n        return static::$repository;\n    }\n\n    /**\n     * Get the value of an environment variable.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public static function get($key, $default = null)\n    {\n        return self::getOption($key)->getOrCall(fn () => value($default));\n    }\n\n    /**\n     * Get the value of a required environment variable.\n     *\n     * @param  string  $key\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public static function getOrFail($key)\n    {\n        return self::getOption($key)->getOrThrow(new RuntimeException(\"Environment variable [$key] has no value.\"));\n    }\n\n    /**\n     * Write an array of key-value pairs to the environment file.\n     *\n     * @param  array  $variables\n     * @param  string  $pathToFile\n     * @param  bool  $overwrite\n     * @return void\n     *\n     * @throws \\RuntimeException\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public static function writeVariables(array $variables, string $pathToFile, bool $overwrite = false): void\n    {\n        $filesystem = new Filesystem;\n\n        if ($filesystem->missing($pathToFile)) {\n            throw new RuntimeException(\"The file [{$pathToFile}] does not exist.\");\n        }\n\n        $lines = explode(PHP_EOL, $filesystem->get($pathToFile));\n\n        foreach ($variables as $key => $value) {\n            $lines = self::addVariableToEnvContents($key, $value, $lines, $overwrite);\n        }\n\n        $filesystem->put($pathToFile, implode(PHP_EOL, $lines));\n    }\n\n    /**\n     * Write a single key-value pair to the environment file.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  string  $pathToFile\n     * @param  bool  $overwrite\n     * @return void\n     *\n     * @throws \\RuntimeException\n     * @throws \\Illuminate\\Contracts\\Filesystem\\FileNotFoundException\n     */\n    public static function writeVariable(string $key, mixed $value, string $pathToFile, bool $overwrite = false): void\n    {\n        $filesystem = new Filesystem;\n\n        if ($filesystem->missing($pathToFile)) {\n            throw new RuntimeException(\"The file [{$pathToFile}] does not exist.\");\n        }\n\n        $envContent = $filesystem->get($pathToFile);\n\n        $lines = explode(PHP_EOL, $envContent);\n        $lines = self::addVariableToEnvContents($key, $value, $lines, $overwrite);\n\n        $filesystem->put($pathToFile, implode(PHP_EOL, $lines));\n    }\n\n    /**\n     * Add a variable to the environment file contents.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $envLines\n     * @param  bool  $overwrite\n     * @return array\n     */\n    protected static function addVariableToEnvContents(string $key, mixed $value, array $envLines, bool $overwrite): array\n    {\n        $prefix = explode('_', $key)[0].'_';\n        $lastPrefixIndex = -1;\n\n        $shouldQuote = preg_match('/^[a-zA-z0-9]+$/', $value) === 0;\n\n        $lineToAddVariations = [\n            $key.'='.(is_string($value) ? self::prepareQuotedValue($value) : $value),\n            $key.'='.$value,\n        ];\n\n        $lineToAdd = $shouldQuote ? $lineToAddVariations[0] : $lineToAddVariations[1];\n\n        if ($value === '') {\n            $lineToAdd = $key.'=';\n        }\n\n        foreach ($envLines as $index => $line) {\n            if (str_starts_with($line, $prefix)) {\n                $lastPrefixIndex = $index;\n            }\n\n            if (in_array($line, $lineToAddVariations)) {\n                // This exact line already exists, so we don't need to add it again.\n                return $envLines;\n            }\n\n            if ($line === $key.'=') {\n                // If the value is empty, we can replace it with the new value.\n                $envLines[$index] = $lineToAdd;\n\n                return $envLines;\n            }\n\n            if (str_starts_with($line, $key.'=')) {\n                if (! $overwrite) {\n                    return $envLines;\n                }\n\n                $envLines[$index] = $lineToAdd;\n\n                return $envLines;\n            }\n        }\n\n        if ($lastPrefixIndex === -1) {\n            if (count($envLines) && $envLines[count($envLines) - 1] !== '') {\n                $envLines[] = '';\n            }\n\n            return array_merge($envLines, [$lineToAdd]);\n        }\n\n        return array_merge(\n            array_slice($envLines, 0, $lastPrefixIndex + 1),\n            [$lineToAdd],\n            array_slice($envLines, $lastPrefixIndex + 1)\n        );\n    }\n\n    /**\n     * Get the possible option for this environment variable.\n     *\n     * @param  string  $key\n     * @return \\PhpOption\\Option|\\PhpOption\\Some\n     */\n    protected static function getOption($key)\n    {\n        return Option::fromValue(static::getRepository()->get($key))\n            ->map(function ($value) {\n                switch (strtolower($value)) {\n                    case 'true':\n                    case '(true)':\n                        return true;\n                    case 'false':\n                    case '(false)':\n                        return false;\n                    case 'empty':\n                    case '(empty)':\n                        return '';\n                    case 'null':\n                    case '(null)':\n                        return;\n                }\n\n                if (preg_match('/\\A([\\'\"])(.*)\\1\\z/', $value, $matches)) {\n                    return $matches[2];\n                }\n\n                return $value;\n            });\n    }\n\n    /**\n     * Wrap a string in quotes, choosing double or single quotes.\n     *\n     * @param  string  $input\n     * @return string\n     */\n    protected static function prepareQuotedValue(string $input)\n    {\n        return str_contains($input, '\"')\n            ? \"'\".self::addSlashesExceptFor($input, ['\"']).\"'\"\n            : '\"'.self::addSlashesExceptFor($input, [\"'\"]).'\"';\n    }\n\n    /**\n     * Escape a string using addslashes, excluding the specified characters from being escaped.\n     *\n     * @param  string  $value\n     * @param  array  $except\n     * @return string\n     */\n    protected static function addSlashesExceptFor(string $value, array $except = [])\n    {\n        $escaped = addslashes($value);\n\n        foreach ($except as $character) {\n            $escaped = str_replace('\\\\'.$character, $character, $escaped);\n        }\n\n        return $escaped;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Exceptions/MathException.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Exceptions;\n\nuse RuntimeException;\n\nclass MathException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/App.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Foundation\\Configuration\\ApplicationBuilder configure(string|null $basePath = null)\n * @method static string inferBasePath()\n * @method static string version()\n * @method static void bootstrapWith(string[] $bootstrappers)\n * @method static void afterLoadingEnvironment(\\Closure $callback)\n * @method static void beforeBootstrapping(string $bootstrapper, \\Closure $callback)\n * @method static void afterBootstrapping(string $bootstrapper, \\Closure $callback)\n * @method static bool hasBeenBootstrapped()\n * @method static \\Illuminate\\Foundation\\Application setBasePath(string $basePath)\n * @method static string path(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application useAppPath(string $path)\n * @method static string basePath(string $path = '')\n * @method static string bootstrapPath(string $path = '')\n * @method static string getBootstrapProvidersPath()\n * @method static \\Illuminate\\Foundation\\Application useBootstrapPath(string $path)\n * @method static string configPath(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application useConfigPath(string $path)\n * @method static string databasePath(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application useDatabasePath(string $path)\n * @method static string langPath(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application useLangPath(string $path)\n * @method static string publicPath(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application usePublicPath(string $path)\n * @method static string storagePath(string $path = '')\n * @method static \\Illuminate\\Foundation\\Application useStoragePath(string $path)\n * @method static string resourcePath(string $path = '')\n * @method static string viewPath(string $path = '')\n * @method static string joinPaths(string $basePath, string $path = '')\n * @method static string environmentPath()\n * @method static \\Illuminate\\Foundation\\Application useEnvironmentPath(string $path)\n * @method static \\Illuminate\\Foundation\\Application loadEnvironmentFrom(string $file)\n * @method static string environmentFile()\n * @method static string environmentFilePath()\n * @method static string|bool environment(string|array ...$environments)\n * @method static bool isLocal()\n * @method static bool isProduction()\n * @method static string detectEnvironment(\\Closure $callback)\n * @method static bool runningInConsole()\n * @method static bool runningConsoleCommand(string|array ...$commands)\n * @method static bool runningUnitTests()\n * @method static bool hasDebugModeEnabled()\n * @method static void registered(callable $callback)\n * @method static void registerConfiguredProviders()\n * @method static \\Illuminate\\Support\\ServiceProvider register(\\Illuminate\\Support\\ServiceProvider|string $provider, bool $force = false)\n * @method static \\Illuminate\\Support\\ServiceProvider|null getProvider(\\Illuminate\\Support\\ServiceProvider|string $provider)\n * @method static array getProviders(\\Illuminate\\Support\\ServiceProvider|string $provider)\n * @method static \\Illuminate\\Support\\ServiceProvider resolveProvider(string $provider)\n * @method static void loadDeferredProviders()\n * @method static void loadDeferredProvider(string $service)\n * @method static void registerDeferredProvider(string $provider, string|null $service = null)\n * @method static object|mixed make(string $abstract, array $parameters = [])\n * @method static bool bound(string $abstract)\n * @method static bool isBooted()\n * @method static void boot()\n * @method static void booting(callable $callback)\n * @method static void booted(callable $callback)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response handle(\\Symfony\\Component\\HttpFoundation\\Request $request, int $type = 1, bool $catch = true)\n * @method static void handleRequest(\\Illuminate\\Http\\Request $request)\n * @method static int handleCommand(\\Symfony\\Component\\Console\\Input\\InputInterface $input)\n * @method static bool shouldMergeFrameworkConfiguration()\n * @method static \\Illuminate\\Foundation\\Application dontMergeFrameworkConfiguration()\n * @method static bool shouldSkipMiddleware()\n * @method static string getCachedServicesPath()\n * @method static string getCachedPackagesPath()\n * @method static bool configurationIsCached()\n * @method static string getCachedConfigPath()\n * @method static bool routesAreCached()\n * @method static string getCachedRoutesPath()\n * @method static bool eventsAreCached()\n * @method static string getCachedEventsPath()\n * @method static \\Illuminate\\Foundation\\Application addAbsoluteCachePathPrefix(string $prefix)\n * @method static \\Illuminate\\Contracts\\Foundation\\MaintenanceMode maintenanceMode()\n * @method static bool isDownForMaintenance()\n * @method static never abort(int $code, string $message = '', array $headers = [])\n * @method static \\Illuminate\\Foundation\\Application terminating(callable|string $callback)\n * @method static void terminate()\n * @method static array getLoadedProviders()\n * @method static bool providerIsLoaded(string $provider)\n * @method static array getDeferredServices()\n * @method static void setDeferredServices(array $services)\n * @method static bool isDeferredService(string $service)\n * @method static void addDeferredServices(array $services)\n * @method static void removeDeferredServices(array $services)\n * @method static void provideFacades(string $namespace)\n * @method static string getLocale()\n * @method static string currentLocale()\n * @method static string getFallbackLocale()\n * @method static void setLocale(string $locale)\n * @method static void setFallbackLocale(string $fallbackLocale)\n * @method static bool isLocale(string $locale)\n * @method static void registerCoreContainerAliases()\n * @method static void flush()\n * @method static string getNamespace()\n * @method static \\Illuminate\\Contracts\\Container\\ContextualBindingBuilder when(array|string $concrete)\n * @method static void whenHasAttribute(string $attribute, \\Closure $handler)\n * @method static bool has(string $id)\n * @method static bool isShared(string $abstract)\n * @method static bool isAlias(string $name)\n * @method static void bind(\\Closure|string $abstract, \\Closure|string|null $concrete = null, bool $shared = false)\n * @method static bool hasMethodBinding(string $method)\n * @method static void bindMethod(array|string $method, \\Closure $callback)\n * @method static mixed callMethodBinding(string $method, mixed $instance)\n * @method static void addContextualBinding(string $concrete, \\Closure|string $abstract, \\Closure|string $implementation)\n * @method static void bindIf(\\Closure|string $abstract, \\Closure|string|null $concrete = null, bool $shared = false)\n * @method static void singleton(\\Closure|string $abstract, \\Closure|string|null $concrete = null)\n * @method static void singletonIf(\\Closure|string $abstract, \\Closure|string|null $concrete = null)\n * @method static void scoped(\\Closure|string $abstract, \\Closure|string|null $concrete = null)\n * @method static void scopedIf(\\Closure|string $abstract, \\Closure|string|null $concrete = null)\n * @method static void extend(string $abstract, \\Closure $closure)\n * @method static mixed instance(string $abstract, mixed $instance)\n * @method static void tag(array|string $abstracts, mixed $tags)\n * @method static iterable tagged(string $tag)\n * @method static void alias(string $abstract, string $alias)\n * @method static mixed rebinding(string $abstract, \\Closure $callback)\n * @method static mixed refresh(string $abstract, mixed $target, string $method)\n * @method static \\Closure wrap(\\Closure $callback, array $parameters = [])\n * @method static mixed call(callable|string $callback, array $parameters = [], string|null $defaultMethod = null)\n * @method static \\Closure|\\Closure factory(string $abstract)\n * @method static object|mixed makeWith(string|callable $abstract, array $parameters = [])\n * @method static object|mixed get(string $id)\n * @method static object build(\\Closure|string $concrete)\n * @method static mixed resolveFromAttribute(\\ReflectionAttribute $attribute)\n * @method static void beforeResolving(\\Closure|string $abstract, \\Closure|null $callback = null)\n * @method static void resolving(\\Closure|string $abstract, \\Closure|null $callback = null)\n * @method static void afterResolving(\\Closure|string $abstract, \\Closure|null $callback = null)\n * @method static void afterResolvingAttribute(string $attribute, \\Closure $callback)\n * @method static void fireAfterResolvingAttributeCallbacks(\\ReflectionAttribute[] $attributes, mixed $object)\n * @method static string|null currentlyResolving()\n * @method static array getBindings()\n * @method static string getAlias(string $abstract)\n * @method static void forgetExtenders(string $abstract)\n * @method static void forgetInstance(string $abstract)\n * @method static void forgetInstances()\n * @method static void forgetScopedInstances()\n * @method static void resolveEnvironmentUsing(callable|string|null $callback)\n * @method static bool currentEnvironmentIs(array|string $environments)\n * @method static \\Illuminate\\Foundation\\Application getInstance()\n * @method static \\Illuminate\\Contracts\\Container\\Container|\\Illuminate\\Foundation\\Application setInstance(\\Illuminate\\Contracts\\Container\\Container|null $container = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Foundation\\Application\n */\nclass App extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'app';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Artisan.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\n\n/**\n * @method static int handle(\\Symfony\\Component\\Console\\Input\\InputInterface $input, \\Symfony\\Component\\Console\\Output\\OutputInterface|null $output = null)\n * @method static void terminate(\\Symfony\\Component\\Console\\Input\\InputInterface $input, int $status)\n * @method static void whenCommandLifecycleIsLongerThan(\\DateTimeInterface|\\Carbon\\CarbonInterval|float|int $threshold, callable $handler)\n * @method static \\Illuminate\\Support\\Carbon|null commandStartedAt()\n * @method static \\Illuminate\\Console\\Scheduling\\Schedule resolveConsoleSchedule()\n * @method static \\Illuminate\\Foundation\\Console\\ClosureCommand command(string $signature, \\Closure $callback)\n * @method static void registerCommand(\\Symfony\\Component\\Console\\Command\\Command $command)\n * @method static int call(\\Symfony\\Component\\Console\\Command\\Command|string $command, array $parameters = [], \\Symfony\\Component\\Console\\Output\\OutputInterface|null $outputBuffer = null)\n * @method static \\Illuminate\\Foundation\\Bus\\PendingDispatch queue(string $command, array $parameters = [])\n * @method static array all()\n * @method static string output()\n * @method static void bootstrap()\n * @method static void bootstrapWithoutBootingProviders()\n * @method static void setArtisan(\\Illuminate\\Console\\Application|null $artisan)\n * @method static \\Illuminate\\Foundation\\Console\\Kernel addCommands(array $commands)\n * @method static \\Illuminate\\Foundation\\Console\\Kernel addCommandPaths(array $paths)\n * @method static \\Illuminate\\Foundation\\Console\\Kernel addCommandRoutePaths(array $paths)\n *\n * @see \\Illuminate\\Foundation\\Console\\Kernel\n */\nclass Artisan extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ConsoleKernelContract::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Auth.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Laravel\\Ui\\UiServiceProvider;\nuse RuntimeException;\n\n/**\n * @method static \\Illuminate\\Contracts\\Auth\\Guard|\\Illuminate\\Contracts\\Auth\\StatefulGuard guard(string|null $name = null)\n * @method static \\Illuminate\\Auth\\SessionGuard createSessionDriver(string $name, array $config)\n * @method static \\Illuminate\\Auth\\TokenGuard createTokenDriver(string $name, array $config)\n * @method static string getDefaultDriver()\n * @method static void shouldUse(string $name)\n * @method static void setDefaultDriver(string $name)\n * @method static \\Illuminate\\Auth\\AuthManager viaRequest(string $driver, callable $callback)\n * @method static \\Closure userResolver()\n * @method static \\Illuminate\\Auth\\AuthManager resolveUsersUsing(\\Closure $userResolver)\n * @method static \\Illuminate\\Auth\\AuthManager extend(string $driver, \\Closure $callback)\n * @method static \\Illuminate\\Auth\\AuthManager provider(string $name, \\Closure $callback)\n * @method static bool hasResolvedGuards()\n * @method static \\Illuminate\\Auth\\AuthManager forgetGuards()\n * @method static \\Illuminate\\Auth\\AuthManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static \\Illuminate\\Contracts\\Auth\\UserProvider|null createUserProvider(string|null $provider = null)\n * @method static string getDefaultUserProvider()\n * @method static bool check()\n * @method static bool guest()\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable|null user()\n * @method static int|string|null id()\n * @method static bool validate(array $credentials = [])\n * @method static bool hasUser()\n * @method static \\Illuminate\\Contracts\\Auth\\Guard setUser(\\Illuminate\\Contracts\\Auth\\Authenticatable $user)\n * @method static bool attempt(array $credentials = [], bool $remember = false)\n * @method static bool once(array $credentials = [])\n * @method static void login(\\Illuminate\\Contracts\\Auth\\Authenticatable $user, bool $remember = false)\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable|false loginUsingId(mixed $id, bool $remember = false)\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable|false onceUsingId(mixed $id)\n * @method static bool viaRemember()\n * @method static void logout()\n * @method static \\Symfony\\Component\\HttpFoundation\\Response|null basic(string $field = 'email', array $extraConditions = [])\n * @method static \\Symfony\\Component\\HttpFoundation\\Response|null onceBasic(string $field = 'email', array $extraConditions = [])\n * @method static bool attemptWhen(array $credentials = [], array|callable|null $callbacks = null, bool $remember = false)\n * @method static string hashPasswordForCookie(string $passwordHash)\n * @method static void logoutCurrentDevice()\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable|null logoutOtherDevices(string $password)\n * @method static void attempting(mixed $callback)\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable getLastAttempted()\n * @method static string getName()\n * @method static string getRecallerName()\n * @method static \\Illuminate\\Auth\\SessionGuard setRememberDuration(int $minutes)\n * @method static \\Illuminate\\Contracts\\Cookie\\QueueingFactory getCookieJar()\n * @method static void setCookieJar(\\Illuminate\\Contracts\\Cookie\\QueueingFactory $cookie)\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher getDispatcher()\n * @method static void setDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $events)\n * @method static \\Illuminate\\Contracts\\Session\\Session getSession()\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable|null getUser()\n * @method static \\Symfony\\Component\\HttpFoundation\\Request getRequest()\n * @method static \\Illuminate\\Auth\\SessionGuard setRequest(\\Symfony\\Component\\HttpFoundation\\Request $request)\n * @method static \\Illuminate\\Support\\Timebox getTimebox()\n * @method static \\Illuminate\\Contracts\\Auth\\Authenticatable authenticate()\n * @method static \\Illuminate\\Auth\\SessionGuard forgetUser()\n * @method static \\Illuminate\\Contracts\\Auth\\UserProvider getProvider()\n * @method static void setProvider(\\Illuminate\\Contracts\\Auth\\UserProvider $provider)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Auth\\AuthManager\n * @see \\Illuminate\\Auth\\SessionGuard\n */\nclass Auth extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'auth';\n    }\n\n    /**\n     * Register the typical authentication routes for an application.\n     *\n     * @param  array  $options\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public static function routes(array $options = [])\n    {\n        if (! static::$app->providerIsLoaded(UiServiceProvider::class)) {\n            throw new RuntimeException('In order to use the Auth::routes() method, please install the laravel/ui package.');\n        }\n\n        static::$app->make('router')->auth($options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Blade.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static void compile(string|null $path = null)\n * @method static string getPath()\n * @method static void setPath(string $path)\n * @method static string compileString(string $value)\n * @method static string render(string $string, array $data = [], bool $deleteCachedView = false)\n * @method static string renderComponent(\\Illuminate\\View\\Component $component)\n * @method static string stripParentheses(string $expression)\n * @method static void extend(callable $compiler)\n * @method static array getExtensions()\n * @method static void if(string $name, callable $callback)\n * @method static bool check(string $name, mixed ...$parameters)\n * @method static void component(string $class, string|null $alias = null, string $prefix = '')\n * @method static void components(array $components, string $prefix = '')\n * @method static array getClassComponentAliases()\n * @method static void anonymousComponentPath(string $path, string|null $prefix = null)\n * @method static void anonymousComponentNamespace(string $directory, string|null $prefix = null)\n * @method static void componentNamespace(string $namespace, string $prefix)\n * @method static array getAnonymousComponentPaths()\n * @method static array getAnonymousComponentNamespaces()\n * @method static array getClassComponentNamespaces()\n * @method static void aliasComponent(string $path, string|null $alias = null)\n * @method static void include(string $path, string|null $alias = null)\n * @method static void aliasInclude(string $path, string|null $alias = null)\n * @method static void bindDirective(string $name, callable $handler)\n * @method static void directive(string $name, \\Closure|callable $handler, bool $bind = false)\n * @method static array getCustomDirectives()\n * @method static \\Illuminate\\View\\Compilers\\BladeCompiler prepareStringsForCompilationUsing(callable $callback)\n * @method static void precompiler(callable $precompiler)\n * @method static string usingEchoFormat(string $format, callable $callback)\n * @method static void setEchoFormat(string $format)\n * @method static void withDoubleEncoding()\n * @method static void withoutDoubleEncoding()\n * @method static void withoutComponentTags()\n * @method static string getCompiledPath(string $path)\n * @method static bool isExpired(string $path)\n * @method static string newComponentHash(string $component)\n * @method static string compileClassComponentOpening(string $component, string $alias, string $data, string $hash)\n * @method static string compileEndComponentClass()\n * @method static mixed sanitizeComponentAttribute(mixed $value)\n * @method static string compileEndOnce()\n * @method static void stringable(string|callable $class, callable|null $handler = null)\n * @method static string compileEchos(string $value)\n * @method static string applyEchoHandler(string $value)\n *\n * @see \\Illuminate\\View\\Compilers\\BladeCompiler\n */\nclass Blade extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'blade.compiler';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Broadcast.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastingFactoryContract;\n\n/**\n * @method static void routes(array|null $attributes = null)\n * @method static void userRoutes(array|null $attributes = null)\n * @method static void channelRoutes(array|null $attributes = null)\n * @method static string|null socket(\\Illuminate\\Http\\Request|null $request = null)\n * @method static \\Illuminate\\Broadcasting\\AnonymousEvent on(\\Illuminate\\Broadcasting\\Channel|array|string $channels)\n * @method static \\Illuminate\\Broadcasting\\AnonymousEvent private(string $channel)\n * @method static \\Illuminate\\Broadcasting\\AnonymousEvent presence(string $channel)\n * @method static \\Illuminate\\Broadcasting\\PendingBroadcast event(mixed $event = null)\n * @method static void queue(mixed $event)\n * @method static mixed connection(string|null $name = null)\n * @method static mixed driver(string|null $name = null)\n * @method static \\Pusher\\Pusher pusher(array $config)\n * @method static \\Ably\\AblyRest ably(array $config)\n * @method static string getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Broadcasting\\BroadcastManager extend(string $driver, \\Closure $callback)\n * @method static \\Illuminate\\Contracts\\Foundation\\Application getApplication()\n * @method static \\Illuminate\\Broadcasting\\BroadcastManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static \\Illuminate\\Broadcasting\\BroadcastManager forgetDrivers()\n * @method static string|null resolveConnectionFromQueueRoute(object $queueable)\n * @method static string|null resolveQueueFromQueueRoute(object $queueable)\n * @method static mixed auth(\\Illuminate\\Http\\Request $request)\n * @method static mixed validAuthenticationResponse(\\Illuminate\\Http\\Request $request, mixed $result)\n * @method static void broadcast(array $channels, string $event, array $payload = [])\n * @method static array|null resolveAuthenticatedUser(\\Illuminate\\Http\\Request $request)\n * @method static void resolveAuthenticatedUserUsing(\\Closure $callback)\n * @method static \\Illuminate\\Broadcasting\\Broadcasters\\Broadcaster channel(\\Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel|string $channel, callable|string $callback, array $options = [])\n * @method static \\Illuminate\\Support\\Collection getChannels()\n *\n * @see \\Illuminate\\Broadcasting\\BroadcastManager\n * @see \\Illuminate\\Broadcasting\\Broadcasters\\Broadcaster\n */\nclass Broadcast extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return BroadcastingFactoryContract::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Bus.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcherContract;\nuse Illuminate\\Foundation\\Bus\\PendingChain;\nuse Illuminate\\Support\\Testing\\Fakes\\BusFake;\n\n/**\n * @method static mixed dispatch(mixed $command)\n * @method static mixed dispatchSync(mixed $command, mixed $handler = null)\n * @method static mixed dispatchNow(mixed $command, mixed $handler = null)\n * @method static \\Illuminate\\Bus\\Batch|null findBatch(string $batchId)\n * @method static \\Illuminate\\Bus\\PendingBatch batch(\\Illuminate\\Support\\Collection|mixed $jobs)\n * @method static \\Illuminate\\Foundation\\Bus\\PendingChain chain(\\Illuminate\\Support\\Collection|array|null $jobs = null)\n * @method static bool hasCommandHandler(mixed $command)\n * @method static mixed getCommandHandler(mixed $command)\n * @method static mixed dispatchToQueue(mixed $command)\n * @method static void dispatchAfterResponse(mixed $command, mixed $handler = null)\n * @method static \\Illuminate\\Bus\\Dispatcher pipeThrough(array $pipes)\n * @method static \\Illuminate\\Bus\\Dispatcher map(array $map)\n * @method static \\Illuminate\\Bus\\Dispatcher withDispatchingAfterResponses()\n * @method static \\Illuminate\\Bus\\Dispatcher withoutDispatchingAfterResponses()\n * @method static string|null resolveConnectionFromQueueRoute(object $queueable)\n * @method static string|null resolveQueueFromQueueRoute(object $queueable)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\BusFake except(array|string $jobsToDispatch)\n * @method static void assertDispatched(string|\\Closure $command, callable|int|null $callback = null)\n * @method static void assertDispatchedOnce(string|\\Closure $command)\n * @method static void assertDispatchedTimes(string|\\Closure $command, int $times = 1)\n * @method static void assertNotDispatched(string|\\Closure $command, callable|null $callback = null)\n * @method static void assertNothingDispatched()\n * @method static void assertDispatchedSync(string|\\Closure $command, callable|int|null $callback = null)\n * @method static void assertDispatchedSyncTimes(string|\\Closure $command, int $times = 1)\n * @method static void assertNotDispatchedSync(string|\\Closure $command, callable|null $callback = null)\n * @method static void assertDispatchedAfterResponse(string|\\Closure $command, callable|int|null $callback = null)\n * @method static void assertDispatchedAfterResponseTimes(string|\\Closure $command, int $times = 1)\n * @method static void assertNotDispatchedAfterResponse(string|\\Closure $command, callable|null $callback = null)\n * @method static void assertChained(array $expectedChain)\n * @method static void assertNothingChained()\n * @method static void assertDispatchedWithoutChain(string|\\Closure $command, callable|null $callback = null)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\ChainedBatchTruthTest chainedBatch(\\Closure $callback)\n * @method static void assertBatched(array|callable $callback)\n * @method static void assertBatchCount(int $count)\n * @method static void assertNothingBatched()\n * @method static void assertNothingPlaced()\n * @method static \\Illuminate\\Support\\Collection dispatched(string $command, callable|null $callback = null)\n * @method static \\Illuminate\\Support\\Collection dispatchedSync(string $command, callable|null $callback = null)\n * @method static \\Illuminate\\Support\\Collection dispatchedAfterResponse(string $command, callable|null $callback = null)\n * @method static \\Illuminate\\Support\\Collection batched(callable $callback)\n * @method static bool hasDispatched(string $command)\n * @method static bool hasDispatchedSync(string $command)\n * @method static bool hasDispatchedAfterResponse(string $command)\n * @method static \\Illuminate\\Bus\\Batch dispatchFakeBatch(string $name = '')\n * @method static \\Illuminate\\Bus\\Batch recordPendingBatch(\\Illuminate\\Bus\\PendingBatch $pendingBatch)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\BusFake serializeAndRestore(bool $serializeAndRestore = true)\n * @method static array dispatchedBatches()\n *\n * @see \\Illuminate\\Bus\\Dispatcher\n * @see \\Illuminate\\Support\\Testing\\Fakes\\BusFake\n */\nclass Bus extends Facade\n{\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @param  array|string  $jobsToFake\n     * @param  \\Illuminate\\Bus\\BatchRepository|null  $batchRepository\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\BusFake\n     */\n    public static function fake($jobsToFake = [], ?BatchRepository $batchRepository = null)\n    {\n        $actualDispatcher = static::isFake()\n            ? static::getFacadeRoot()->dispatcher\n            : static::getFacadeRoot();\n\n        return tap(new BusFake($actualDispatcher, $jobsToFake, $batchRepository), function ($fake) {\n            static::swap($fake);\n        });\n    }\n\n    /**\n     * Dispatch the given chain of jobs.\n     *\n     * @param  mixed  $jobs\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public static function dispatchChain($jobs)\n    {\n        $jobs = is_array($jobs) ? $jobs : func_get_args();\n\n        return (new PendingChain(array_shift($jobs), $jobs))\n            ->dispatch();\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return BusDispatcherContract::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Cache.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Mockery;\n\n/**\n * @method static \\Illuminate\\Contracts\\Cache\\Repository store(string|null $name = null)\n * @method static \\Illuminate\\Contracts\\Cache\\Repository driver(string|null $driver = null)\n * @method static \\Illuminate\\Contracts\\Cache\\Repository memo(string|null $driver = null)\n * @method static \\Illuminate\\Contracts\\Cache\\Repository resolve(string $name)\n * @method static \\Illuminate\\Cache\\Repository build(array $config)\n * @method static \\Illuminate\\Cache\\Repository repository(\\Illuminate\\Contracts\\Cache\\Store $store, array $config = [])\n * @method static void refreshEventDispatcher()\n * @method static string getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static \\Illuminate\\Cache\\CacheManager forgetDriver(array|string|null $name = null)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Cache\\CacheManager extend(string $driver, \\Closure $callback)\n * @method static \\Illuminate\\Cache\\CacheManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static bool has(\\UnitEnum|array|string $key)\n * @method static bool missing(\\UnitEnum|string $key)\n * @method static mixed get(\\UnitEnum|array|string $key, mixed $default = null)\n * @method static array many(array $keys)\n * @method static iterable getMultiple(iterable $keys, mixed $default = null)\n * @method static mixed pull(\\UnitEnum|array|string $key, mixed $default = null)\n * @method static string string(\\UnitEnum|string $key, \\Closure|string|null $default = null)\n * @method static int integer(\\UnitEnum|string $key, \\Closure|int|null $default = null)\n * @method static float float(\\UnitEnum|string $key, \\Closure|float|null $default = null)\n * @method static bool boolean(\\UnitEnum|string $key, \\Closure|bool|null $default = null)\n * @method static array array(\\UnitEnum|string $key, \\Closure|array|null $default = null)\n * @method static bool put(\\UnitEnum|array|string $key, mixed $value, \\DateTimeInterface|\\DateInterval|int|null $ttl = null)\n * @method static bool set(\\UnitEnum|array|string $key, mixed $value, \\DateTimeInterface|\\DateInterval|int|null $ttl = null)\n * @method static bool putMany(array $values, \\DateTimeInterface|\\DateInterval|int|null $ttl = null)\n * @method static bool setMultiple(iterable $values, null|int|\\DateInterval $ttl = null)\n * @method static bool add(\\UnitEnum|array|string $key, mixed $value, \\DateTimeInterface|\\DateInterval|int|null $ttl = null)\n * @method static int|bool increment(\\UnitEnum|string $key, mixed $value = 1)\n * @method static int|bool decrement(\\UnitEnum|string $key, mixed $value = 1)\n * @method static bool forever(\\UnitEnum|string $key, mixed $value)\n * @method static mixed remember(\\UnitEnum|string $key, \\Closure|\\DateTimeInterface|\\DateInterval|int|null $ttl, \\Closure $callback)\n * @method static mixed sear(\\UnitEnum|string $key, \\Closure $callback)\n * @method static mixed rememberForever(\\UnitEnum|string $key, \\Closure $callback)\n * @method static mixed flexible(\\UnitEnum|string $key, array $ttl, callable $callback, array|null $lock = null, bool $alwaysDefer = false)\n * @method static bool touch(string $key, \\DateTimeInterface|\\DateInterval|int $ttl)\n * @method static mixed withoutOverlapping(\\UnitEnum|string $key, callable $callback, int $lockFor = 0, int $waitFor = 10, string|null $owner = null)\n * @method static \\Illuminate\\Cache\\Limiters\\ConcurrencyLimiterBuilder funnel(\\UnitEnum|string $name)\n * @method static bool forget(\\UnitEnum|array|string $key)\n * @method static bool delete(\\UnitEnum|array|string $key)\n * @method static bool deleteMultiple(iterable $keys)\n * @method static bool clear()\n * @method static bool flushLocks()\n * @method static \\Illuminate\\Cache\\TaggedCache tags(mixed $names)\n * @method static string|null getName()\n * @method static bool supportsTags()\n * @method static bool supportsFlushingLocks()\n * @method static int|null getDefaultCacheTime()\n * @method static \\Illuminate\\Cache\\Repository setDefaultCacheTime(int|null $seconds)\n * @method static \\Illuminate\\Contracts\\Cache\\Store getStore()\n * @method static \\Illuminate\\Cache\\Repository setStore(\\Illuminate\\Contracts\\Cache\\Store $store)\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher|null getEventDispatcher()\n * @method static void setEventDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $events)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static bool flush()\n * @method static string getPrefix()\n * @method static \\Illuminate\\Contracts\\Cache\\Lock lock(string $name, int $seconds = 0, string|null $owner = null)\n * @method static \\Illuminate\\Contracts\\Cache\\Lock restoreLock(string $name, string $owner)\n *\n * @see \\Illuminate\\Cache\\CacheManager\n * @see \\Illuminate\\Cache\\Repository\n */\nclass Cache extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'cache';\n    }\n\n    /**\n     * Convert the facade into a Mockery spy.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    public static function spy()\n    {\n        if (! static::isMock()) {\n            $class = static::getMockableClass();\n            $instance = static::getFacadeRoot();\n\n            if ($class && $instance) {\n                return tap(Mockery::spy($instance)->makePartial(), function ($spy) {\n                    static::swap($spy);\n                });\n            }\n\n            return tap($class ? Mockery::spy($class) : Mockery::spy(), function ($spy) {\n                static::swap($spy);\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Concurrency.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Concurrency\\ConcurrencyManager;\n\n/**\n * @method static mixed driver(string|null $name = null)\n * @method static \\Illuminate\\Concurrency\\ProcessDriver createProcessDriver()\n * @method static \\Illuminate\\Concurrency\\ForkDriver createForkDriver()\n * @method static \\Illuminate\\Concurrency\\SyncDriver createSyncDriver()\n * @method static string getDefaultInstance()\n * @method static void setDefaultInstance(string $name)\n * @method static array getInstanceConfig(string $name)\n * @method static mixed instance(string|null $name = null)\n * @method static \\Illuminate\\Concurrency\\ConcurrencyManager forgetInstance(array|string|null $name = null)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Concurrency\\ConcurrencyManager extend(string $name, \\Closure $callback)\n * @method static \\Illuminate\\Concurrency\\ConcurrencyManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static array run(\\Closure|array $tasks)\n * @method static \\Illuminate\\Support\\Defer\\DeferredCallback defer(\\Closure|array $tasks)\n *\n * @see \\Illuminate\\Concurrency\\ConcurrencyManager\n */\nclass Concurrency extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ConcurrencyManager::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Config.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool has(string $key)\n * @method static mixed get(array|string $key, mixed $default = null)\n * @method static array getMany(array $keys)\n * @method static string string(string $key, \\Closure|string|null $default = null)\n * @method static int integer(string $key, \\Closure|int|null $default = null)\n * @method static float float(string $key, \\Closure|float|null $default = null)\n * @method static bool boolean(string $key, \\Closure|bool|null $default = null)\n * @method static array array(string $key, \\Closure|array|null $default = null)\n * @method static \\Illuminate\\Support\\Collection collection(string $key, \\Closure|array|null $default = null)\n * @method static void set(array|string $key, mixed $value = null)\n * @method static void prepend(string $key, mixed $value)\n * @method static void push(string $key, mixed $value)\n * @method static array all()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Config\\Repository\n */\nclass Config extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'config';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Context.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool has(string $key)\n * @method static bool missing(string $key)\n * @method static bool hasHidden(string $key)\n * @method static bool missingHidden(string $key)\n * @method static array all()\n * @method static array allHidden()\n * @method static mixed get(string $key, mixed $default = null)\n * @method static mixed getHidden(string $key, mixed $default = null)\n * @method static mixed pull(string $key, mixed $default = null)\n * @method static mixed pullHidden(string $key, mixed $default = null)\n * @method static array only(array $keys)\n * @method static array onlyHidden(array $keys)\n * @method static array except(array $keys)\n * @method static array exceptHidden(array $keys)\n * @method static \\Illuminate\\Log\\Context\\Repository add(string|array $key, mixed $value = null)\n * @method static \\Illuminate\\Log\\Context\\Repository addHidden(string|array $key, mixed $value = null)\n * @method static mixed remember(string $key, mixed $value)\n * @method static mixed rememberHidden(string $key, mixed $value)\n * @method static \\Illuminate\\Log\\Context\\Repository forget(string|array $key)\n * @method static \\Illuminate\\Log\\Context\\Repository forgetHidden(string|array $key)\n * @method static \\Illuminate\\Log\\Context\\Repository addIf(string $key, mixed $value)\n * @method static \\Illuminate\\Log\\Context\\Repository addHiddenIf(string $key, mixed $value)\n * @method static \\Illuminate\\Log\\Context\\Repository push(string $key, mixed ...$values)\n * @method static mixed pop(string $key)\n * @method static \\Illuminate\\Log\\Context\\Repository pushHidden(string $key, mixed ...$values)\n * @method static mixed popHidden(string $key)\n * @method static \\Illuminate\\Log\\Context\\Repository increment(string $key, int $amount = 1)\n * @method static \\Illuminate\\Log\\Context\\Repository decrement(string $key, int $amount = 1)\n * @method static bool stackContains(string $key, mixed $value, bool $strict = false)\n * @method static bool hiddenStackContains(string $key, mixed $value, bool $strict = false)\n * @method static mixed scope(callable $callback, array $data = [], array $hidden = [])\n * @method static bool isEmpty()\n * @method static \\Illuminate\\Log\\Context\\Repository dehydrating(callable $callback)\n * @method static \\Illuminate\\Log\\Context\\Repository hydrated(callable $callback)\n * @method static \\Illuminate\\Log\\Context\\Repository handleUnserializeExceptionsUsing(callable|null $callback)\n * @method static \\Illuminate\\Log\\Context\\Repository flush()\n * @method static \\Illuminate\\Log\\Context\\Repository|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Log\\Context\\Repository|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static \\Illuminate\\Database\\Eloquent\\Model restoreModel(\\Illuminate\\Contracts\\Database\\ModelIdentifier $value)\n *\n * @see \\Illuminate\\Log\\Context\\Repository\n */\nclass Context extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return \\Illuminate\\Log\\Context\\Repository::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Cookie.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Symfony\\Component\\HttpFoundation\\Cookie make(string $name, string $value, int $minutes = 0, string|null $path = null, string|null $domain = null, bool|null $secure = null, bool $httpOnly = true, bool $raw = false, string|null $sameSite = null)\n * @method static \\Symfony\\Component\\HttpFoundation\\Cookie forever(string $name, string $value, string|null $path = null, string|null $domain = null, bool|null $secure = null, bool $httpOnly = true, bool $raw = false, string|null $sameSite = null)\n * @method static \\Symfony\\Component\\HttpFoundation\\Cookie forget(string $name, string|null $path = null, string|null $domain = null)\n * @method static bool hasQueued(string $key, string|null $path = null)\n * @method static \\Symfony\\Component\\HttpFoundation\\Cookie|null queued(string $key, mixed $default = null, string|null $path = null)\n * @method static void queue(mixed ...$parameters)\n * @method static void expire(string $name, string|null $path = null, string|null $domain = null)\n * @method static void unqueue(string $name, string|null $path = null)\n * @method static \\Illuminate\\Cookie\\CookieJar setDefaultPathAndDomain(string $path, string|null $domain, bool|null $secure = false, string|null $sameSite = null)\n * @method static \\Symfony\\Component\\HttpFoundation\\Cookie[] getQueuedCookies()\n * @method static \\Illuminate\\Cookie\\CookieJar flushQueuedCookies()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Cookie\\CookieJar\n */\nclass Cookie extends Facade\n{\n    /**\n     * Determine if a cookie exists on the request.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public static function has($key)\n    {\n        return ! is_null(static::$app['request']->cookie($key, null));\n    }\n\n    /**\n     * Retrieve a cookie from the request.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return string|array|null\n     */\n    public static function get($key = null, $default = null)\n    {\n        return static::$app['request']->cookie($key, $default);\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'cookie';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Crypt.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool supported(string $key, string $cipher)\n * @method static string generateKey(string $cipher)\n * @method static string encrypt(mixed $value, bool $serialize = true)\n * @method static string encryptString(string $value)\n * @method static mixed decrypt(string $payload, bool $unserialize = true)\n * @method static string decryptString(string $payload)\n * @method static bool appearsEncrypted(mixed $value)\n * @method static string getKey()\n * @method static array getAllKeys()\n * @method static array getPreviousKeys()\n * @method static \\Illuminate\\Encryption\\Encrypter previousKeys(array $keys)\n *\n * @see \\Illuminate\\Encryption\\Encrypter\n */\nclass Crypt extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'encrypter';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/DB.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Database\\Console\\Migrations\\FreshCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RefreshCommand;\nuse Illuminate\\Database\\Console\\Migrations\\ResetCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RollbackCommand;\nuse Illuminate\\Database\\Console\\WipeCommand;\n\n/**\n * @method static \\Illuminate\\Database\\Connection connection(\\UnitEnum|string|null $name = null)\n * @method static \\Illuminate\\Database\\ConnectionInterface build(array $config)\n * @method static string calculateDynamicConnectionName(array $config)\n * @method static \\Illuminate\\Database\\ConnectionInterface connectUsing(\\UnitEnum|string $name, array $config, bool $force = false)\n * @method static void purge(\\UnitEnum|string|null $name = null)\n * @method static void disconnect(\\UnitEnum|string|null $name = null)\n * @method static \\Illuminate\\Database\\Connection reconnect(\\UnitEnum|string|null $name = null)\n * @method static mixed usingConnection(\\UnitEnum|string $name, callable $callback)\n * @method static string getDefaultConnection()\n * @method static void setDefaultConnection(string $name)\n * @method static string[] supportedDrivers()\n * @method static string[] availableDrivers()\n * @method static void extend(string $name, callable $resolver)\n * @method static void forgetExtension(string $name)\n * @method static array getConnections()\n * @method static void setReconnector(callable $reconnector)\n * @method static \\Illuminate\\Database\\DatabaseManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static void useDefaultQueryGrammar()\n * @method static void useDefaultSchemaGrammar()\n * @method static void useDefaultPostProcessor()\n * @method static \\Illuminate\\Database\\Schema\\Builder getSchemaBuilder()\n * @method static \\Illuminate\\Database\\Query\\Builder table(\\Closure|\\Illuminate\\Database\\Query\\Builder|\\Illuminate\\Contracts\\Database\\Query\\Expression|\\UnitEnum|string $table, string|null $as = null)\n * @method static \\Illuminate\\Database\\Query\\Builder query()\n * @method static mixed selectOne(string $query, array $bindings = [], bool $useReadPdo = true)\n * @method static mixed scalar(string $query, array $bindings = [], bool $useReadPdo = true)\n * @method static array selectFromWriteConnection(string $query, array $bindings = [])\n * @method static array select(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = [])\n * @method static array selectResultSets(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = [])\n * @method static \\Generator cursor(string $query, array $bindings = [], bool $useReadPdo = true, array $fetchUsing = [])\n * @method static bool insert(string $query, array $bindings = [])\n * @method static int update(string $query, array $bindings = [])\n * @method static int delete(string $query, array $bindings = [])\n * @method static bool statement(string $query, array $bindings = [])\n * @method static int affectingStatement(string $query, array $bindings = [])\n * @method static bool unprepared(mixed $query)\n * @method static int|null threadCount()\n * @method static array[] pretend(\\Closure $callback)\n * @method static mixed withoutPretending(\\Closure $callback)\n * @method static void bindValues(\\PDOStatement $statement, array $bindings)\n * @method static array prepareBindings(array $bindings)\n * @method static void logQuery(string $query, array $bindings, float|null $time = null)\n * @method static void whenQueryingForLongerThan(\\DateTimeInterface|\\Carbon\\CarbonInterval|float|int $threshold, callable $handler)\n * @method static void allowQueryDurationHandlersToRunAgain()\n * @method static float totalQueryDuration()\n * @method static void resetTotalQueryDuration()\n * @method static void reconnectIfMissingConnection()\n * @method static \\Illuminate\\Database\\Connection beforeStartingTransaction(\\Closure $callback)\n * @method static \\Illuminate\\Database\\Connection beforeExecuting(\\Closure $callback)\n * @method static void listen(\\Closure $callback)\n * @method static \\Illuminate\\Contracts\\Database\\Query\\Expression raw(mixed|int|float $value)\n * @method static string escape(string|float|int|bool|null $value, bool $binary = false)\n * @method static bool hasModifiedRecords()\n * @method static void recordsHaveBeenModified(bool $value = true)\n * @method static \\Illuminate\\Database\\Connection setRecordModificationState(bool $value)\n * @method static void forgetRecordModificationState()\n * @method static \\Illuminate\\Database\\Connection useWriteConnectionWhenReading(bool $value = true)\n * @method static \\PDO getPdo()\n * @method static \\PDO|\\Closure|null getRawPdo()\n * @method static \\PDO getReadPdo()\n * @method static \\PDO|\\Closure|null getRawReadPdo()\n * @method static \\Illuminate\\Database\\Connection setPdo(\\PDO|\\Closure|null $pdo)\n * @method static \\Illuminate\\Database\\Connection setReadPdo(\\PDO|\\Closure|null $pdo)\n * @method static \\Illuminate\\Database\\Connection setReadPdoConfig(array $config)\n * @method static string|null getName()\n * @method static string|null getNameWithReadWriteType()\n * @method static mixed getConfig(string|null $option = null)\n * @method static string getDriverName()\n * @method static string getDriverTitle()\n * @method static \\Illuminate\\Database\\Query\\Grammars\\Grammar getQueryGrammar()\n * @method static \\Illuminate\\Database\\Connection setQueryGrammar(\\Illuminate\\Database\\Query\\Grammars\\Grammar $grammar)\n * @method static \\Illuminate\\Database\\Schema\\Grammars\\Grammar getSchemaGrammar()\n * @method static \\Illuminate\\Database\\Connection setSchemaGrammar(\\Illuminate\\Database\\Schema\\Grammars\\Grammar $grammar)\n * @method static \\Illuminate\\Database\\Query\\Processors\\Processor getPostProcessor()\n * @method static \\Illuminate\\Database\\Connection setPostProcessor(\\Illuminate\\Database\\Query\\Processors\\Processor $processor)\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher|null getEventDispatcher()\n * @method static \\Illuminate\\Database\\Connection setEventDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $events)\n * @method static void unsetEventDispatcher()\n * @method static \\Illuminate\\Database\\Connection setTransactionManager(\\Illuminate\\Database\\DatabaseTransactionsManager $manager)\n * @method static void unsetTransactionManager()\n * @method static bool pretending()\n * @method static array[] getQueryLog()\n * @method static array getRawQueryLog()\n * @method static void flushQueryLog()\n * @method static void enableQueryLog()\n * @method static void disableQueryLog()\n * @method static bool logging()\n * @method static string getDatabaseName()\n * @method static \\Illuminate\\Database\\Connection setDatabaseName(string $database)\n * @method static \\Illuminate\\Database\\Connection setReadWriteType(string|null $readWriteType)\n * @method static string getTablePrefix()\n * @method static \\Illuminate\\Database\\Connection setTablePrefix(string $prefix)\n * @method static mixed withoutTablePrefix(\\Closure $callback)\n * @method static string getServerVersion()\n * @method static void resolverFor(string $driver, \\Closure $callback)\n * @method static \\Closure|null getResolver(string $driver)\n * @method static mixed transaction(\\Closure $callback, int $attempts = 1)\n * @method static void beginTransaction()\n * @method static void commit()\n * @method static void rollBack(int|null $toLevel = null)\n * @method static int transactionLevel()\n * @method static void afterCommit(callable $callback)\n * @method static void afterRollBack(callable $callback)\n *\n * @see \\Illuminate\\Database\\DatabaseManager\n */\nclass DB extends Facade\n{\n    /**\n     * Indicate if destructive Artisan commands should be prohibited.\n     *\n     * Prohibits: db:wipe, migrate:fresh, migrate:refresh, migrate:reset, and migrate:rollback\n     *\n     * @param  bool  $prohibit\n     * @return void\n     */\n    public static function prohibitDestructiveCommands(bool $prohibit = true)\n    {\n        FreshCommand::prohibit($prohibit);\n        RefreshCommand::prohibit($prohibit);\n        ResetCommand::prohibit($prohibit);\n        RollbackCommand::prohibit($prohibit);\n        WipeCommand::prohibit($prohibit);\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'db';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Date.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Support\\DateFactory;\n\n/**\n * @see https://carbon.nesbot.com/docs/\n * @see https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Factory.php\n *\n * @method static mixed use(mixed $handler)\n * @method static void useDefault()\n * @method static void useCallable(callable $callable)\n * @method static void useClass(string $dateClass)\n * @method static void useFactory(object $factory)\n * @method static bool canBeCreatedFromFormat(?string $date, string $format)\n * @method static \\Illuminate\\Support\\Carbon|null create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromDate($year = null, $month = null, $day = null, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon|null createFromFormat($format, $time, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon|null createFromIsoFormat(string $format, string $time, $timezone = null, ?string $locale = 'en', ?\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator = null)\n * @method static \\Illuminate\\Support\\Carbon|null createFromLocaleFormat(string $format, string $locale, string $time, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon|null createFromLocaleIsoFormat(string $format, string $locale, string $time, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromTimeString(string $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromTimestamp(string|int|float $timestamp, \\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromTimestampMs(string|int|float $timestamp, \\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createFromTimestampMsUTC($timestamp)\n * @method static \\Illuminate\\Support\\Carbon createFromTimestampUTC(string|int|float $timestamp)\n * @method static \\Illuminate\\Support\\Carbon createMidnightDate($year = null, $month = null, $day = null, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon|null createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $timezone = null)\n * @method static void disableHumanDiffOption($humanDiffOption)\n * @method static void enableHumanDiffOption($humanDiffOption)\n * @method static mixed executeWithLocale(string $locale, callable $func)\n * @method static \\Illuminate\\Support\\Carbon fromSerialized($value)\n * @method static array getAvailableLocales()\n * @method static array getAvailableLocalesInfo()\n * @method static array getDays()\n * @method static ?string getFallbackLocale()\n * @method static array getFormatsToIsoReplacements()\n * @method static int getHumanDiffOptions()\n * @method static array getIsoUnits()\n * @method static array|false getLastErrors()\n * @method static string getLocale()\n * @method static int getMidDayAt()\n * @method static string getTimeFormatByPrecision(string $unitPrecision)\n * @method static string|\\Closure|null getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null)\n * @method static \\Illuminate\\Support\\Carbon|null getTestNow()\n * @method static \\Symfony\\Contracts\\Translation\\TranslatorInterface getTranslator()\n * @method static int getWeekEndsAt(?string $locale = null)\n * @method static int getWeekStartsAt(?string $locale = null)\n * @method static array getWeekendDays()\n * @method static bool hasFormat(string $date, string $format)\n * @method static bool hasFormatWithModifiers(string $date, string $format)\n * @method static bool hasMacro($name)\n * @method static bool hasRelativeKeywords(?string $time)\n * @method static bool hasTestNow()\n * @method static \\Illuminate\\Support\\Carbon instance(\\DateTimeInterface $date)\n * @method static bool isImmutable()\n * @method static bool isModifiableUnit($unit)\n * @method static bool isMutable()\n * @method static bool isStrictModeEnabled()\n * @method static bool localeHasDiffOneDayWords(string $locale)\n * @method static bool localeHasDiffSyntax(string $locale)\n * @method static bool localeHasDiffTwoDayWords(string $locale)\n * @method static bool localeHasPeriodSyntax($locale)\n * @method static bool localeHasShortUnits(string $locale)\n * @method static void macro(string $name, ?callable $macro)\n * @method static \\Illuminate\\Support\\Carbon|null make($var, \\DateTimeZone|string|null $timezone = null)\n * @method static void mixin(object|string $mixin)\n * @method static \\Illuminate\\Support\\Carbon now(\\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon parse(\\DateTimeInterface|\\Carbon\\WeekDay|\\Carbon\\Month|string|int|float|null $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon parseFromLocale(string $time, ?string $locale = null, \\DateTimeZone|string|int|null $timezone = null)\n * @method static string pluralUnit(string $unit)\n * @method static \\Illuminate\\Support\\Carbon|null rawCreateFromFormat(string $format, string $time, $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon rawParse(\\DateTimeInterface|\\Carbon\\WeekDay|\\Carbon\\Month|string|int|float|null $time, \\DateTimeZone|string|int|null $timezone = null)\n * @method static void resetMonthsOverflow()\n * @method static void resetToStringFormat()\n * @method static void resetYearsOverflow()\n * @method static void serializeUsing($callback)\n * @method static void setFallbackLocale(string $locale)\n * @method static void setHumanDiffOptions($humanDiffOptions)\n * @method static void setLocale(string $locale)\n * @method static void setMidDayAt($hour)\n * @method static void setTestNow(mixed $testNow = null)\n * @method static void setTestNowAndTimezone(mixed $testNow = null, $timezone = null)\n * @method static void setToStringFormat(string|\\Closure|null $format)\n * @method static void setTranslator(\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator)\n * @method static void setWeekEndsAt($day)\n * @method static void setWeekStartsAt($day)\n * @method static void setWeekendDays($days)\n * @method static bool shouldOverflowMonths()\n * @method static bool shouldOverflowYears()\n * @method static string singularUnit(string $unit)\n * @method static void sleep(int|float $seconds)\n * @method static \\Illuminate\\Support\\Carbon today(\\DateTimeZone|string|int|null $timezone = null)\n * @method static \\Illuminate\\Support\\Carbon tomorrow(\\DateTimeZone|string|int|null $timezone = null)\n * @method static string translateTimeString(string $timeString, ?string $from = null, ?string $to = null, int $mode = \\Carbon\\CarbonInterface::TRANSLATE_ALL)\n * @method static string translateWith(\\Symfony\\Contracts\\Translation\\TranslatorInterface $translator, string $key, array $parameters = [], $number = null)\n * @method static void useMonthsOverflow($monthsOverflow = true)\n * @method static void useStrictMode($strictModeEnabled = true)\n * @method static void useYearsOverflow($yearsOverflow = true)\n * @method static mixed withTestNow(mixed $testNow, callable $callback)\n * @method static static withTimeZone(\\DateTimeZone|string|int|null $timezone)\n * @method static \\Illuminate\\Support\\Carbon yesterday(\\DateTimeZone|string|int|null $timezone = null)\n *\n * @see \\Illuminate\\Support\\DateFactory\n */\nclass Date extends Facade\n{\n    const DEFAULT_FACADE = DateFactory::class;\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'date';\n    }\n\n    /**\n     * Resolve the facade root instance from the container.\n     *\n     * @param  string  $name\n     * @return mixed\n     */\n    protected static function resolveFacadeInstance($name)\n    {\n        if (! isset(static::$resolvedInstance[$name]) && ! isset(static::$app, static::$app[$name])) {\n            $class = static::DEFAULT_FACADE;\n\n            static::swap(new $class);\n        }\n\n        return parent::resolveFacadeInstance($name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Event.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Testing\\Fakes\\EventFake;\n\n/**\n * @method static void listen(\\Illuminate\\Events\\QueuedClosure|callable|array|string $events, \\Illuminate\\Events\\QueuedClosure|callable|array|string|null $listener = null)\n * @method static bool hasListeners(string $eventName)\n * @method static bool hasWildcardListeners(string $eventName)\n * @method static void push(string $event, object|array $payload = [])\n * @method static void flush(string $event)\n * @method static void subscribe(object|string $subscriber)\n * @method static array|null until(string|object $event, mixed $payload = [])\n * @method static array|null dispatch(string|object $event, mixed $payload = [], bool $halt = false)\n * @method static array getListeners(string $eventName)\n * @method static \\Closure makeListener(\\Closure|string|array $listener, bool $wildcard = false)\n * @method static \\Closure createClassListener(string $listener, bool $wildcard = false)\n * @method static void forget(string $event)\n * @method static void forgetPushed()\n * @method static \\Illuminate\\Events\\Dispatcher setQueueResolver(callable $resolver)\n * @method static \\Illuminate\\Events\\Dispatcher setTransactionManagerResolver(callable $resolver)\n * @method static mixed defer(callable $callback, string[]|null $events = null)\n * @method static array getRawListeners()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static string|null resolveConnectionFromQueueRoute(object $queueable)\n * @method static string|null resolveQueueFromQueueRoute(object $queueable)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\EventFake except(array|string $eventsToDispatch)\n * @method static void assertListening(string $expectedEvent, string|array $expectedListener)\n * @method static void assertDispatched(string|\\Closure $event, callable|int|null $callback = null)\n * @method static void assertDispatchedOnce(string $event)\n * @method static void assertDispatchedTimes(string $event, int $times = 1)\n * @method static void assertNotDispatched(string|\\Closure $event, callable|null $callback = null)\n * @method static void assertNothingDispatched()\n * @method static \\Illuminate\\Support\\Collection dispatched(string $event, callable|null $callback = null)\n * @method static bool hasDispatched(string $event)\n * @method static array dispatchedEvents()\n *\n * @see \\Illuminate\\Events\\Dispatcher\n * @see \\Illuminate\\Support\\Testing\\Fakes\\EventFake\n */\nclass Event extends Facade\n{\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @param  array|string  $eventsToFake\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\EventFake\n     */\n    public static function fake($eventsToFake = [])\n    {\n        $actualDispatcher = static::isFake()\n            ? static::getFacadeRoot()->dispatcher\n            : static::getFacadeRoot();\n\n        return tap(new EventFake($actualDispatcher, $eventsToFake), function ($fake) {\n            static::swap($fake);\n\n            Model::setEventDispatcher($fake);\n            Cache::refreshEventDispatcher();\n        });\n    }\n\n    /**\n     * Replace the bound instance with a fake that fakes all events except the given events.\n     *\n     * @param  string[]|string  $eventsToAllow\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\EventFake\n     */\n    public static function fakeExcept($eventsToAllow)\n    {\n        return static::fake([\n            function ($eventName) use ($eventsToAllow) {\n                return ! in_array($eventName, (array) $eventsToAllow);\n            },\n        ]);\n    }\n\n    /**\n     * Replace the bound instance with a fake during the given callable's execution.\n     *\n     * @param  callable  $callable\n     * @param  array  $eventsToFake\n     * @return mixed\n     */\n    public static function fakeFor(callable $callable, array $eventsToFake = [])\n    {\n        $originalDispatcher = static::getFacadeRoot();\n\n        static::fake($eventsToFake);\n\n        try {\n            return $callable();\n        } finally {\n            static::swap($originalDispatcher);\n\n            Model::setEventDispatcher($originalDispatcher);\n            Cache::refreshEventDispatcher();\n        }\n    }\n\n    /**\n     * Replace the bound instance with a fake during the given callable's execution.\n     *\n     * @param  callable  $callable\n     * @param  array  $eventsToAllow\n     * @return mixed\n     */\n    public static function fakeExceptFor(callable $callable, array $eventsToAllow = [])\n    {\n        $originalDispatcher = static::getFacadeRoot();\n\n        static::fakeExcept($eventsToAllow);\n\n        try {\n            return $callable();\n        } finally {\n            static::swap($originalDispatcher);\n\n            Model::setEventDispatcher($originalDispatcher);\n            Cache::refreshEventDispatcher();\n        }\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'events';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Exceptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake;\n\n/**\n * @method static void register()\n * @method static \\Illuminate\\Foundation\\Exceptions\\ReportableHandler reportable(callable $reportUsing)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler renderable(callable $renderUsing)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler map(\\Closure|string $from, \\Closure|string|null $to = null)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler dontReport(array|string $exceptions)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler dontReportWhen(callable $dontReportWhen)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler ignore(array|string $exceptions)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler dontFlash(array|string $attributes)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler level(string $type, string $level)\n * @method static void report(\\Throwable $e)\n * @method static bool shouldReport(\\Throwable $e)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler throttleUsing(callable $throttleUsing)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler stopIgnoring(array|string $exceptions)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler buildContextUsing(\\Closure $contextCallback)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response render(\\Illuminate\\Http\\Request $request, \\Throwable $e)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler respondUsing(callable $callback)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler shouldRenderJsonWhen(callable $callback)\n * @method static \\Illuminate\\Foundation\\Exceptions\\Handler dontReportDuplicates()\n * @method static \\Illuminate\\Contracts\\Debug\\ExceptionHandler handler()\n * @method static void assertReported(\\Closure|string $exception)\n * @method static void assertReportedCount(int $count)\n * @method static void assertNotReported(\\Closure|string $exception)\n * @method static void assertNothingReported()\n * @method static void renderForConsole(\\Symfony\\Component\\Console\\Output\\OutputInterface $output, \\Throwable $e)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake throwOnReport()\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake throwFirstReported()\n * @method static array reported()\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake setHandler(\\Illuminate\\Contracts\\Debug\\ExceptionHandler $handler)\n *\n * @see \\Illuminate\\Foundation\\Exceptions\\Handler\n * @see \\Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake\n */\nclass Exceptions extends Facade\n{\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @param  array<int, class-string<\\Throwable>>|class-string<\\Throwable>  $exceptions\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake\n     */\n    public static function fake(array|string $exceptions = [])\n    {\n        $exceptionHandler = static::isFake()\n            ? static::getFacadeRoot()->handler()\n            : static::getFacadeRoot();\n\n        return tap(new ExceptionHandlerFake($exceptionHandler, Arr::wrap($exceptions)), function ($fake) {\n            static::swap($fake);\n        });\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ExceptionHandler::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Facade.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Benchmark;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Js;\nuse Illuminate\\Support\\Number;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Testing\\Fakes\\Fake;\nuse Illuminate\\Support\\Uri;\nuse Mockery;\nuse Mockery\\LegacyMockInterface;\nuse RuntimeException;\n\nabstract class Facade\n{\n    /**\n     * The application instance being facaded.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application|null\n     */\n    protected static $app;\n\n    /**\n     * The resolved object instances.\n     *\n     * @var array\n     */\n    protected static $resolvedInstance;\n\n    /**\n     * Indicates if the resolved instance should be cached.\n     *\n     * @var bool\n     */\n    protected static $cached = true;\n\n    /**\n     * Run a Closure when the facade has been resolved.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public static function resolved(Closure $callback)\n    {\n        $accessor = static::getFacadeAccessor();\n\n        if (static::$app->resolved($accessor) === true) {\n            $callback(static::getFacadeRoot(), static::$app);\n        }\n\n        static::$app->afterResolving($accessor, function ($service, $app) use ($callback) {\n            $callback($service, $app);\n        });\n    }\n\n    /**\n     * Convert the facade into a Mockery spy.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    public static function spy()\n    {\n        if (! static::isMock()) {\n            $class = static::getMockableClass();\n\n            return tap($class ? Mockery::spy($class) : Mockery::spy(), function ($spy) {\n                static::swap($spy);\n            });\n        }\n    }\n\n    /**\n     * Initiate a partial mock on the facade.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    public static function partialMock()\n    {\n        $name = static::getFacadeAccessor();\n\n        $mock = static::isMock()\n            ? static::$resolvedInstance[$name]\n            : static::createFreshMockInstance();\n\n        return $mock->makePartial();\n    }\n\n    /**\n     * Initiate a mock expectation on the facade.\n     *\n     * @return \\Mockery\\Expectation\n     */\n    public static function shouldReceive()\n    {\n        $name = static::getFacadeAccessor();\n\n        $mock = static::isMock()\n            ? static::$resolvedInstance[$name]\n            : static::createFreshMockInstance();\n\n        return $mock->shouldReceive(...func_get_args());\n    }\n\n    /**\n     * Initiate a mock expectation on the facade.\n     *\n     * @return \\Mockery\\Expectation\n     */\n    public static function expects()\n    {\n        $name = static::getFacadeAccessor();\n\n        $mock = static::isMock()\n            ? static::$resolvedInstance[$name]\n            : static::createFreshMockInstance();\n\n        return $mock->expects(...func_get_args());\n    }\n\n    /**\n     * Create a fresh mock instance for the given class.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    protected static function createFreshMockInstance()\n    {\n        return tap(static::createMock(), function ($mock) {\n            static::swap($mock);\n\n            $mock->shouldAllowMockingProtectedMethods();\n        });\n    }\n\n    /**\n     * Create a fresh mock instance for the given class.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    protected static function createMock()\n    {\n        $class = static::getMockableClass();\n\n        return $class ? Mockery::mock($class) : Mockery::mock();\n    }\n\n    /**\n     * Determines whether a mock is set as the instance of the facade.\n     *\n     * @return bool\n     */\n    protected static function isMock()\n    {\n        $name = static::getFacadeAccessor();\n\n        return isset(static::$resolvedInstance[$name]) &&\n               static::$resolvedInstance[$name] instanceof LegacyMockInterface;\n    }\n\n    /**\n     * Get the mockable class for the bound instance.\n     *\n     * @return string|null\n     */\n    protected static function getMockableClass()\n    {\n        if ($root = static::getFacadeRoot()) {\n            return get_class($root);\n        }\n    }\n\n    /**\n     * Hotswap the underlying instance behind the facade.\n     *\n     * @param  mixed  $instance\n     * @return void\n     */\n    public static function swap($instance)\n    {\n        static::$resolvedInstance[static::getFacadeAccessor()] = $instance;\n\n        if (isset(static::$app)) {\n            static::$app->instance(static::getFacadeAccessor(), $instance);\n        }\n    }\n\n    /**\n     * Determines whether a \"fake\" has been set as the facade instance.\n     *\n     * @return bool\n     */\n    public static function isFake()\n    {\n        $name = static::getFacadeAccessor();\n\n        return isset(static::$resolvedInstance[$name]) &&\n               static::$resolvedInstance[$name] instanceof Fake;\n    }\n\n    /**\n     * Get the root object behind the facade.\n     *\n     * @return mixed\n     */\n    public static function getFacadeRoot()\n    {\n        return static::resolveFacadeInstance(static::getFacadeAccessor());\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     *\n     * @throws \\RuntimeException\n     */\n    protected static function getFacadeAccessor()\n    {\n        throw new RuntimeException('Facade does not implement getFacadeAccessor method.');\n    }\n\n    /**\n     * Resolve the facade root instance from the container.\n     *\n     * @param  string  $name\n     * @return mixed\n     */\n    protected static function resolveFacadeInstance($name)\n    {\n        if (isset(static::$resolvedInstance[$name])) {\n            return static::$resolvedInstance[$name];\n        }\n\n        if (static::$app) {\n            if (static::$cached) {\n                return static::$resolvedInstance[$name] = static::$app[$name];\n            }\n\n            return static::$app[$name];\n        }\n    }\n\n    /**\n     * Clear a resolved facade instance.\n     *\n     * @param  ?string  $name\n     * @return void\n     */\n    public static function clearResolvedInstance($name = null)\n    {\n        unset(static::$resolvedInstance[$name ?? static::getFacadeAccessor()]);\n    }\n\n    /**\n     * Clear all of the resolved instances.\n     *\n     * @return void\n     */\n    public static function clearResolvedInstances()\n    {\n        static::$resolvedInstance = [];\n    }\n\n    /**\n     * Get the application default aliases.\n     *\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public static function defaultAliases()\n    {\n        return new Collection([\n            'App' => App::class,\n            'Arr' => Arr::class,\n            'Artisan' => Artisan::class,\n            'Auth' => Auth::class,\n            'Benchmark' => Benchmark::class,\n            'Blade' => Blade::class,\n            'Broadcast' => Broadcast::class,\n            'Bus' => Bus::class,\n            'Cache' => Cache::class,\n            'Concurrency' => Concurrency::class,\n            'Config' => Config::class,\n            'Context' => Context::class,\n            'Cookie' => Cookie::class,\n            'Crypt' => Crypt::class,\n            'Date' => Date::class,\n            'DB' => DB::class,\n            'Eloquent' => Model::class,\n            'Event' => Event::class,\n            'File' => File::class,\n            'Gate' => Gate::class,\n            'Hash' => Hash::class,\n            'Http' => Http::class,\n            'Js' => Js::class,\n            'Lang' => Lang::class,\n            'Log' => Log::class,\n            'Mail' => Mail::class,\n            'Notification' => Notification::class,\n            'Number' => Number::class,\n            'Password' => Password::class,\n            'Process' => Process::class,\n            'Queue' => Queue::class,\n            'RateLimiter' => RateLimiter::class,\n            'Redirect' => Redirect::class,\n            'Request' => Request::class,\n            'Response' => Response::class,\n            'Route' => Route::class,\n            'Schedule' => Schedule::class,\n            'Schema' => Schema::class,\n            'Session' => Session::class,\n            'Storage' => Storage::class,\n            'Str' => Str::class,\n            'Uri' => Uri::class,\n            'URL' => URL::class,\n            'Validator' => Validator::class,\n            'View' => View::class,\n            'Vite' => Vite::class,\n        ]);\n    }\n\n    /**\n     * Get the application instance behind the facade.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application|null\n     */\n    public static function getFacadeApplication()\n    {\n        return static::$app;\n    }\n\n    /**\n     * Set the application instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application|null  $app\n     * @return void\n     */\n    public static function setFacadeApplication($app)\n    {\n        static::$app = $app;\n    }\n\n    /**\n     * Handle dynamic, static calls to the object.\n     *\n     * @param  string  $method\n     * @param  array  $args\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public static function __callStatic($method, $args)\n    {\n        $instance = static::getFacadeRoot();\n\n        if (! $instance) {\n            throw new RuntimeException('A facade root has not been set.');\n        }\n\n        return $instance->$method(...$args);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/File.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool exists(string $path)\n * @method static bool missing(string $path)\n * @method static string get(string $path, bool $lock = false)\n * @method static array json(string $path, int $flags = 0, bool $lock = false)\n * @method static string sharedGet(string $path)\n * @method static mixed getRequire(string $path, array $data = [])\n * @method static mixed requireOnce(string $path, array $data = [])\n * @method static \\Illuminate\\Support\\LazyCollection lines(string $path)\n * @method static string|false hash(string $path, string $algorithm = 'md5')\n * @method static int|bool put(string $path, string $contents, bool $lock = false)\n * @method static void replace(string $path, string $content, int|null $mode = null)\n * @method static void replaceInFile(array|string $search, array|string $replace, string $path)\n * @method static int prepend(string $path, string $data)\n * @method static int append(string $path, string $data, bool $lock = false)\n * @method static mixed chmod(string $path, int|null $mode = null)\n * @method static bool delete(string|array $paths)\n * @method static bool move(string $path, string $target)\n * @method static bool copy(string $path, string $target)\n * @method static bool|null link(string $target, string $link)\n * @method static void relativeLink(string $target, string $link)\n * @method static string name(string $path)\n * @method static string basename(string $path)\n * @method static string dirname(string $path)\n * @method static string extension(string $path)\n * @method static string|null guessExtension(string $path)\n * @method static string|false type(string $path)\n * @method static string|false mimeType(string $path)\n * @method static int size(string $path)\n * @method static int lastModified(string $path)\n * @method static bool isDirectory(string $directory)\n * @method static bool isEmptyDirectory(string $directory, bool $ignoreDotFiles = false)\n * @method static bool isReadable(string $path)\n * @method static bool isWritable(string $path)\n * @method static bool hasSameHash(string $firstFile, string $secondFile)\n * @method static bool isFile(string $file)\n * @method static array glob(string $pattern, int $flags = 0)\n * @method static \\Symfony\\Component\\Finder\\SplFileInfo[] files(string $directory, bool $hidden = false, array|string|int $depth = 0)\n * @method static \\Symfony\\Component\\Finder\\SplFileInfo[] allFiles(string $directory, bool $hidden = false)\n * @method static array directories(string $directory, array|string|int $depth = 0)\n * @method static array allDirectories(string $directory)\n * @method static void ensureDirectoryExists(string $path, int $mode = 0755, bool $recursive = true)\n * @method static bool makeDirectory(string $path, int $mode = 0755, bool $recursive = false, bool $force = false)\n * @method static bool moveDirectory(string $from, string $to, bool $overwrite = false)\n * @method static bool copyDirectory(string $directory, string $destination, int|null $options = null)\n * @method static bool deleteDirectory(string $directory, bool $preserve = false)\n * @method static bool deleteDirectories(string $directory)\n * @method static bool cleanDirectory(string $directory)\n * @method static \\Illuminate\\Filesystem\\Filesystem|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Filesystem\\Filesystem|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Filesystem\\Filesystem\n */\nclass File extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'files';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Gate.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Auth\\Access\\Gate as GateContract;\n\n/**\n * @method static bool has(\\UnitEnum|array|string $ability)\n * @method static \\Illuminate\\Auth\\Access\\Response allowIf(\\Illuminate\\Auth\\Access\\Response|\\Closure|bool $condition, string|null $message = null, string|null $code = null)\n * @method static \\Illuminate\\Auth\\Access\\Response denyIf(\\Illuminate\\Auth\\Access\\Response|\\Closure|bool $condition, string|null $message = null, string|null $code = null)\n * @method static \\Illuminate\\Auth\\Access\\Gate define(\\UnitEnum|string $ability, callable|array|string $callback)\n * @method static \\Illuminate\\Auth\\Access\\Gate resource(string $name, string $class, array|null $abilities = null)\n * @method static \\Illuminate\\Auth\\Access\\Gate policy(string $class, string $policy)\n * @method static \\Illuminate\\Auth\\Access\\Gate before(callable $callback)\n * @method static \\Illuminate\\Auth\\Access\\Gate after(callable $callback)\n * @method static bool allows(iterable|\\UnitEnum|string $ability, mixed $arguments = [])\n * @method static bool denies(iterable|\\UnitEnum|string $ability, mixed $arguments = [])\n * @method static bool check(iterable|\\UnitEnum|string $abilities, mixed $arguments = [])\n * @method static bool any(iterable|\\UnitEnum|string $abilities, mixed $arguments = [])\n * @method static bool none(iterable|\\UnitEnum|string $abilities, mixed $arguments = [])\n * @method static \\Illuminate\\Auth\\Access\\Response authorize(\\UnitEnum|string $ability, mixed $arguments = [])\n * @method static \\Illuminate\\Auth\\Access\\Response inspect(\\UnitEnum|string $ability, mixed $arguments = [])\n * @method static mixed raw(string $ability, mixed $arguments = [])\n * @method static mixed getPolicyFor(object|string $class)\n * @method static \\Illuminate\\Auth\\Access\\Gate guessPolicyNamesUsing(callable $callback)\n * @method static mixed resolvePolicy(object|string $class)\n * @method static \\Illuminate\\Auth\\Access\\Gate forUser(\\Illuminate\\Contracts\\Auth\\Authenticatable|mixed $user)\n * @method static array abilities()\n * @method static array policies()\n * @method static \\Illuminate\\Auth\\Access\\Gate defaultDenialResponse(\\Illuminate\\Auth\\Access\\Response $response)\n * @method static \\Illuminate\\Auth\\Access\\Gate setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Auth\\Access\\Response denyWithStatus(int $status, string|null $message = null, int|null $code = null)\n * @method static \\Illuminate\\Auth\\Access\\Response denyAsNotFound(string|null $message = null, int|null $code = null)\n *\n * @see \\Illuminate\\Auth\\Access\\Gate\n */\nclass Gate extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return GateContract::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Hash.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Hashing\\BcryptHasher createBcryptDriver()\n * @method static \\Illuminate\\Hashing\\ArgonHasher createArgonDriver()\n * @method static \\Illuminate\\Hashing\\Argon2IdHasher createArgon2idDriver()\n * @method static array info(string $hashedValue)\n * @method static string make(string $value, array $options = [])\n * @method static bool check(string $value, string $hashedValue, array $options = [])\n * @method static bool needsRehash(string $hashedValue, array $options = [])\n * @method static bool isHashed(string $value)\n * @method static string getDefaultDriver()\n * @method static mixed driver(string|null $driver = null)\n * @method static \\Illuminate\\Hashing\\HashManager extend(string $driver, \\Closure $callback)\n * @method static array getDrivers()\n * @method static \\Illuminate\\Contracts\\Container\\Container getContainer()\n * @method static \\Illuminate\\Hashing\\HashManager setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Hashing\\HashManager forgetDrivers()\n *\n * @see \\Illuminate\\Hashing\\HashManager\n * @see \\Illuminate\\Hashing\\AbstractHasher\n */\nclass Hash extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'hash';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Http.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Http\\Client\\Factory;\n\n/**\n * @method static \\Illuminate\\Http\\Client\\Factory globalMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\Factory globalRequestMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\Factory globalResponseMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\Factory globalOptions(\\Closure|array $options)\n * @method static \\GuzzleHttp\\Promise\\PromiseInterface response(array|string|null $body = null, int $status = 200, array $headers = [])\n * @method static \\GuzzleHttp\\Psr7\\Response psr7Response(array|string|null $body = null, int $status = 200, array $headers = [])\n * @method static \\Illuminate\\Http\\Client\\RequestException failedRequest(array|string|null $body = null, int $status = 200, array $headers = [])\n * @method static \\Closure failedConnection(string|null $message = null)\n * @method static \\Illuminate\\Http\\Client\\ResponseSequence sequence(array $responses = [])\n * @method static bool preventingStrayRequests()\n * @method static \\Illuminate\\Http\\Client\\Factory allowStrayRequests(array|null $only = null)\n * @method static \\Illuminate\\Http\\Client\\Factory record()\n * @method static void recordRequestResponsePair(\\Illuminate\\Http\\Client\\Request $request, \\Illuminate\\Http\\Client\\Response|null $response)\n * @method static void assertSent(callable|\\Closure $callback)\n * @method static void assertSentInOrder(array $callbacks)\n * @method static void assertNotSent(callable|\\Closure $callback)\n * @method static void assertNothingSent()\n * @method static void assertSentCount(int $count)\n * @method static void assertSequencesAreEmpty()\n * @method static \\Illuminate\\Support\\Collection recorded(\\Closure|callable $callback = null)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest createPendingRequest()\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher|null getDispatcher()\n * @method static array getGlobalMiddleware()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest baseUrl(string $url)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withBody(\\Psr\\Http\\Message\\StreamInterface|string $content, string $contentType = 'application/json')\n * @method static \\Illuminate\\Http\\Client\\PendingRequest asJson()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest asForm()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest attach(string|array $name, string|resource $contents = '', string|null $filename = null, array $headers = [])\n * @method static \\Illuminate\\Http\\Client\\PendingRequest asMultipart()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest bodyFormat(string $format)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withQueryParameters(array $parameters)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest contentType(string $contentType)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest acceptJson()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest accept(string $contentType)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withHeaders(array $headers)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withHeader(string $name, mixed $value)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest replaceHeaders(array $headers)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withBasicAuth(string $username, string $password)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withDigestAuth(string $username, string $password)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withNtlmAuth(string $username, string $password)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withToken(string $token, string $type = 'Bearer')\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withUserAgent(string|bool $userAgent)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withUrlParameters(array $parameters = [])\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withCookies(array $cookies, string $domain)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest maxRedirects(int $max)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withoutRedirecting()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withoutVerifying()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest sink(string|resource $to)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest timeout(int|float $seconds)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest connectTimeout(int|float $seconds)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest retry(array|int $times, \\Closure|int $sleepMilliseconds = 0, callable|null $when = null, bool $throw = true)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withOptions(array $options)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withRequestMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withResponseMiddleware(callable $middleware)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest withAttributes(array $attributes)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest beforeSending(callable $callback)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest afterResponse(callable|null $callback)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest throw(callable|null $callback = null)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest throwIf(callable|bool $condition)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest throwUnless(callable|bool $condition)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest dump()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest dd()\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface get(string $url, array|string|null $query = null)\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface head(string $url, array|string|null $query = null)\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface post(string $url, array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable $data = [])\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface patch(string $url, array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable $data = [])\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface put(string $url, array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable $data = [])\n * @method static \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface delete(string $url, array|\\JsonSerializable|\\Illuminate\\Contracts\\Support\\Arrayable $data = [])\n * @method static array pool(callable $callback, int|null $concurrency = 0)\n * @method static \\Illuminate\\Http\\Client\\Batch batch(callable $callback)\n * @method static \\Illuminate\\Http\\Client\\Response|\\Illuminate\\Http\\Client\\Promises\\LazyPromise send(string $method, string $url, array $options = [])\n * @method static \\GuzzleHttp\\Client buildClient()\n * @method static \\GuzzleHttp\\Client createClient(\\GuzzleHttp\\HandlerStack $handlerStack)\n * @method static \\GuzzleHttp\\HandlerStack buildHandlerStack()\n * @method static \\GuzzleHttp\\HandlerStack pushHandlers(\\GuzzleHttp\\HandlerStack $handlerStack)\n * @method static \\Closure buildBeforeSendingHandler()\n * @method static \\Closure buildRecorderHandler()\n * @method static \\Closure buildStubHandler()\n * @method static \\Psr\\Http\\Message\\RequestInterface runBeforeSendingCallbacks(\\Psr\\Http\\Message\\RequestInterface $request, array $options)\n * @method static array mergeOptions(array ...$options)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest stub(callable $callback)\n * @method static bool isAllowedRequestUrl(string $url)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest async(bool $async = true)\n * @method static \\GuzzleHttp\\Promise\\PromiseInterface|null getPromise()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest truncateExceptionsAt(int $length)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest dontTruncateExceptions()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest setClient(\\GuzzleHttp\\Client $client)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest setHandler(callable $handler)\n * @method static array getOptions()\n * @method static \\Illuminate\\Http\\Client\\PendingRequest|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Http\\Client\\PendingRequest|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n *\n * @see \\Illuminate\\Http\\Client\\Factory\n */\nclass Http extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return Factory::class;\n    }\n\n    /**\n     * Register a stub callable that will intercept requests and be able to return stub responses.\n     *\n     * @param  \\Closure|array|null  $callback\n     * @return \\Illuminate\\Http\\Client\\Factory\n     */\n    public static function fake($callback = null)\n    {\n        return tap(static::getFacadeRoot(), function ($fake) use ($callback) {\n            static::swap($fake->fake($callback));\n        });\n    }\n\n    /**\n     * Register a response sequence for the given URL pattern.\n     *\n     * @param  string  $urlPattern\n     * @return \\Illuminate\\Http\\Client\\ResponseSequence\n     */\n    public static function fakeSequence(string $urlPattern = '*')\n    {\n        $fake = tap(static::getFacadeRoot(), function ($fake) {\n            static::swap($fake);\n        });\n\n        return $fake->fakeSequence($urlPattern);\n    }\n\n    /**\n     * Indicate that an exception should be thrown if any request is not faked.\n     *\n     * @param  bool  $prevent\n     * @return \\Illuminate\\Http\\Client\\Factory\n     */\n    public static function preventStrayRequests($prevent = true)\n    {\n        return tap(static::getFacadeRoot(), function ($fake) use ($prevent) {\n            static::swap($fake->preventStrayRequests($prevent));\n        });\n    }\n\n    /**\n     * Stub the given URL using the given callback.\n     *\n     * @param  string  $url\n     * @param  \\Illuminate\\Http\\Client\\Response|\\GuzzleHttp\\Promise\\PromiseInterface|callable  $callback\n     * @return \\Illuminate\\Http\\Client\\Factory\n     */\n    public static function stubUrl($url, $callback)\n    {\n        return tap(static::getFacadeRoot(), function ($fake) use ($url, $callback) {\n            static::swap($fake->stubUrl($url, $callback));\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Lang.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool hasForLocale(string $key, string|null $locale = null)\n * @method static bool has(string $key, string|null $locale = null, bool $fallback = true)\n * @method static string|array get(string $key, array $replace = [], string|null $locale = null, bool $fallback = true)\n * @method static string choice(string $key, \\Countable|int|float|array $number, array $replace = [], string|null $locale = null)\n * @method static void addLines(array $lines, string $locale, string $namespace = '*')\n * @method static void load(string $namespace, string $group, string $locale)\n * @method static \\Illuminate\\Translation\\Translator handleMissingKeysUsing(callable|null $callback)\n * @method static void addNamespace(string $namespace, string $hint)\n * @method static void addPath(string $path)\n * @method static void addJsonPath(string $path)\n * @method static array parseKey(string $key)\n * @method static void determineLocalesUsing(callable $callback)\n * @method static \\Illuminate\\Translation\\MessageSelector getSelector()\n * @method static void setSelector(\\Illuminate\\Translation\\MessageSelector $selector)\n * @method static \\Illuminate\\Contracts\\Translation\\Loader getLoader()\n * @method static string locale()\n * @method static string getLocale()\n * @method static void setLocale(string $locale)\n * @method static string getFallback()\n * @method static void setFallback(string $fallback)\n * @method static void setLoaded(array $loaded)\n * @method static void stringable(callable|string $class, callable|null $handler = null)\n * @method static void setParsedKey(string $key, array $parsed)\n * @method static void flushParsedKeys()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Translation\\Translator\n */\nclass Lang extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'translator';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Log.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Psr\\Log\\LoggerInterface build(array $config)\n * @method static \\Psr\\Log\\LoggerInterface stack(array $channels, string|null $channel = null)\n * @method static \\Psr\\Log\\LoggerInterface channel(string|null $channel = null)\n * @method static \\Psr\\Log\\LoggerInterface driver(string|null $driver = null)\n * @method static \\Illuminate\\Log\\LogManager shareContext(array $context)\n * @method static array sharedContext()\n * @method static \\Illuminate\\Log\\LogManager withoutContext(string[]|null $keys = null)\n * @method static \\Illuminate\\Log\\LogManager flushSharedContext()\n * @method static string|null getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static \\Illuminate\\Log\\LogManager extend(string $driver, \\Closure $callback)\n * @method static void forgetChannel(string|null $driver = null)\n * @method static array getChannels()\n * @method static void emergency(string|\\Stringable $message, array $context = [])\n * @method static void alert(string|\\Stringable $message, array $context = [])\n * @method static void critical(string|\\Stringable $message, array $context = [])\n * @method static void error(string|\\Stringable $message, array $context = [])\n * @method static void warning(string|\\Stringable $message, array $context = [])\n * @method static void notice(string|\\Stringable $message, array $context = [])\n * @method static void info(string|\\Stringable $message, array $context = [])\n * @method static void debug(string|\\Stringable $message, array $context = [])\n * @method static void log(mixed $level, string|\\Stringable $message, array $context = [])\n * @method static \\Illuminate\\Log\\LogManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static void write(string $level, \\Illuminate\\Contracts\\Support\\Arrayable|\\Illuminate\\Contracts\\Support\\Jsonable|\\Illuminate\\Support\\Stringable|array|string $message, array $context = [])\n * @method static \\Illuminate\\Log\\Logger withContext(array $context = [])\n * @method static void listen(\\Closure $callback)\n * @method static \\Psr\\Log\\LoggerInterface getLogger()\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher|null getEventDispatcher()\n * @method static void setEventDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $dispatcher)\n * @method static \\Illuminate\\Log\\Logger|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Log\\Logger|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n *\n * @see \\Illuminate\\Log\\LogManager\n */\nclass Log extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'log';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Mail.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Support\\Testing\\Fakes\\MailFake;\n\n/**\n * @method static \\Illuminate\\Contracts\\Mail\\Mailer mailer(string|null $name = null)\n * @method static \\Illuminate\\Mail\\Mailer driver(string|null $driver = null)\n * @method static \\Illuminate\\Mail\\Mailer build(array $config)\n * @method static \\Symfony\\Component\\Mailer\\Transport\\TransportInterface createSymfonyTransport(array $config)\n * @method static string getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Mail\\MailManager extend(string $driver, \\Closure $callback)\n * @method static \\Illuminate\\Contracts\\Foundation\\Application getApplication()\n * @method static \\Illuminate\\Mail\\MailManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static \\Illuminate\\Mail\\MailManager forgetMailers()\n * @method static void alwaysFrom(string $address, string|null $name = null)\n * @method static void alwaysReplyTo(string $address, string|null $name = null)\n * @method static void alwaysReturnPath(string $address)\n * @method static void alwaysTo(string $address, string|null $name = null)\n * @method static \\Illuminate\\Mail\\PendingMail to(mixed $users, string|null $name = null)\n * @method static \\Illuminate\\Mail\\PendingMail cc(mixed $users, string|null $name = null)\n * @method static \\Illuminate\\Mail\\PendingMail bcc(mixed $users, string|null $name = null)\n * @method static \\Illuminate\\Mail\\SentMessage|null html(string $html, mixed $callback)\n * @method static \\Illuminate\\Mail\\SentMessage|null raw(string $text, mixed $callback)\n * @method static \\Illuminate\\Mail\\SentMessage|null plain(string $view, array $data, mixed $callback)\n * @method static string render(string|array $view, array $data = [])\n * @method static \\Illuminate\\Mail\\SentMessage|null send(\\Illuminate\\Contracts\\Mail\\Mailable|string|array $view, array $data = [], \\Closure|string|null $callback = null)\n * @method static \\Illuminate\\Mail\\SentMessage|null sendNow(\\Illuminate\\Contracts\\Mail\\Mailable|string|array $mailable, array $data = [], \\Closure|string|null $callback = null)\n * @method static mixed queue(\\Illuminate\\Contracts\\Mail\\Mailable $view, \\BackedEnum|string|null $queue = null)\n * @method static mixed onQueue(\\BackedEnum|string|null $queue, \\Illuminate\\Contracts\\Mail\\Mailable $view)\n * @method static mixed queueOn(string $queue, \\Illuminate\\Contracts\\Mail\\Mailable $view)\n * @method static mixed later(\\DateTimeInterface|\\DateInterval|int $delay, \\Illuminate\\Contracts\\Mail\\Mailable $view, string|null $queue = null)\n * @method static mixed laterOn(string $queue, \\DateTimeInterface|\\DateInterval|int $delay, \\Illuminate\\Contracts\\Mail\\Mailable $view)\n * @method static \\Symfony\\Component\\Mailer\\Transport\\TransportInterface getSymfonyTransport()\n * @method static \\Illuminate\\Contracts\\View\\Factory getViewFactory()\n * @method static void setSymfonyTransport(\\Symfony\\Component\\Mailer\\Transport\\TransportInterface $transport)\n * @method static \\Illuminate\\Mail\\Mailer setQueue(\\Illuminate\\Contracts\\Queue\\Factory $queue)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static void assertSent(string|\\Closure $mailable, callable|array|string|int|null $callback = null)\n * @method static void assertSentTimes(string $mailable, int $times = 1)\n * @method static void assertNotOutgoing(string|\\Closure $mailable, callable|null $callback = null)\n * @method static void assertNotSent(string|\\Closure $mailable, callable|array|string|null $callback = null)\n * @method static void assertNothingOutgoing()\n * @method static void assertNothingSent()\n * @method static void assertQueued(string|\\Closure $mailable, callable|array|string|int|null $callback = null)\n * @method static void assertNotQueued(string|\\Closure $mailable, callable|array|string|null $callback = null)\n * @method static void assertNothingQueued()\n * @method static void assertSentCount(int $count)\n * @method static void assertQueuedCount(int $count)\n * @method static void assertOutgoingCount(int $count)\n * @method static \\Illuminate\\Support\\Collection sent(string|\\Closure $mailable, callable|null $callback = null)\n * @method static bool hasSent(string $mailable)\n * @method static \\Illuminate\\Support\\Collection queued(string|\\Closure $mailable, callable|null $callback = null)\n * @method static bool hasQueued(string $mailable)\n *\n * @see \\Illuminate\\Mail\\MailManager\n * @see \\Illuminate\\Support\\Testing\\Fakes\\MailFake\n */\nclass Mail extends Facade\n{\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\MailFake\n     */\n    public static function fake()\n    {\n        $actualMailManager = static::isFake()\n            ? static::getFacadeRoot()->manager\n            : static::getFacadeRoot();\n\n        return tap(new MailFake($actualMailManager), function ($fake) {\n            static::swap($fake);\n        });\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'mail.manager';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/MaintenanceMode.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Foundation\\MaintenanceModeManager;\n\n/**\n * @method static string getDefaultDriver()\n * @method static mixed driver(string|null $driver = null)\n * @method static \\Illuminate\\Foundation\\MaintenanceModeManager extend(string $driver, \\Closure $callback)\n * @method static array getDrivers()\n * @method static \\Illuminate\\Contracts\\Container\\Container getContainer()\n * @method static \\Illuminate\\Foundation\\MaintenanceModeManager setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Foundation\\MaintenanceModeManager forgetDrivers()\n *\n * @see \\Illuminate\\Foundation\\MaintenanceModeManager\n */\nclass MaintenanceMode extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return MaintenanceModeManager::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Notification.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Notifications\\ChannelManager;\nuse Illuminate\\Support\\Testing\\Fakes\\NotificationFake;\n\n/**\n * @method static void send(\\Illuminate\\Support\\Collection|mixed $notifiables, mixed $notification)\n * @method static void sendNow(\\Illuminate\\Support\\Collection|mixed $notifiables, mixed $notification, array|null $channels = null)\n * @method static mixed channel(string|null $name = null)\n * @method static string getDefaultDriver()\n * @method static string deliversVia()\n * @method static void deliverVia(string $channel)\n * @method static \\Illuminate\\Notifications\\ChannelManager locale(string $locale)\n * @method static mixed driver(string|null $driver = null)\n * @method static \\Illuminate\\Notifications\\ChannelManager extend(string $driver, \\Closure $callback)\n * @method static array getDrivers()\n * @method static \\Illuminate\\Contracts\\Container\\Container getContainer()\n * @method static \\Illuminate\\Notifications\\ChannelManager setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Notifications\\ChannelManager forgetDrivers()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static string|null resolveConnectionFromQueueRoute(object $queueable)\n * @method static string|null resolveQueueFromQueueRoute(object $queueable)\n * @method static void assertSentOnDemand(string|\\Closure $notification, callable|null $callback = null)\n * @method static void assertSentTo(mixed $notifiable, string|\\Closure $notification, callable|null $callback = null)\n * @method static void assertSentOnDemandTimes(string $notification, int $times = 1)\n * @method static void assertSentToTimes(mixed $notifiable, string $notification, int $times = 1)\n * @method static void assertNotSentTo(mixed $notifiable, string|\\Closure $notification, callable|null $callback = null)\n * @method static void assertNothingSent()\n * @method static void assertNothingSentTo(mixed $notifiable)\n * @method static void assertSentTimes(string $notification, int $expectedCount)\n * @method static void assertCount(int $expectedCount)\n * @method static \\Illuminate\\Support\\Collection sent(mixed $notifiable, string $notification, callable|null $callback = null)\n * @method static bool hasSent(mixed $notifiable, string $notification)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\NotificationFake serializeAndRestore(bool $serializeAndRestore = true)\n * @method static array sentNotifications()\n *\n * @see \\Illuminate\\Notifications\\ChannelManager\n * @see \\Illuminate\\Support\\Testing\\Fakes\\NotificationFake\n */\nclass Notification extends Facade\n{\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\NotificationFake\n     */\n    public static function fake()\n    {\n        return tap(new NotificationFake, function ($fake) {\n            static::swap($fake);\n        });\n    }\n\n    /**\n     * Begin sending a notification to an anonymous notifiable on the given channels.\n     *\n     * @param  array  $channels\n     * @return \\Illuminate\\Notifications\\AnonymousNotifiable\n     */\n    public static function routes(array $channels)\n    {\n        $notifiable = new AnonymousNotifiable;\n\n        foreach ($channels as $channel => $route) {\n            $notifiable->route($channel, $route);\n        }\n\n        return $notifiable;\n    }\n\n    /**\n     * Begin sending a notification to an anonymous notifiable.\n     *\n     * @param  string  $channel\n     * @param  mixed  $route\n     * @return \\Illuminate\\Notifications\\AnonymousNotifiable\n     */\n    public static function route($channel, $route)\n    {\n        return (new AnonymousNotifiable)->route($channel, $route);\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ChannelManager::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/ParallelTesting.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static void resolveOptionsUsing(\\Closure|null $resolver)\n * @method static void resolveTokenUsing(\\Closure|null $resolver)\n * @method static void setUpProcess(callable $callback)\n * @method static void setUpTestCase(callable $callback)\n * @method static void setUpTestDatabaseBeforeMigrating(callable $callback)\n * @method static void setUpTestDatabase(callable $callback)\n * @method static void tearDownProcess(callable $callback)\n * @method static void tearDownTestCase(callable $callback)\n * @method static void callSetUpProcessCallbacks()\n * @method static void callSetUpTestCaseCallbacks(\\Illuminate\\Foundation\\Testing\\TestCase $testCase)\n * @method static void callSetUpTestDatabaseBeforeMigratingCallbacks(string $database)\n * @method static void callSetUpTestDatabaseCallbacks(string $database)\n * @method static void callTearDownProcessCallbacks()\n * @method static void callTearDownTestCaseCallbacks(\\Illuminate\\Foundation\\Testing\\TestCase $testCase)\n * @method static mixed option(string $option)\n * @method static string|false token()\n *\n * @see \\Illuminate\\Testing\\ParallelTesting\n */\nclass ParallelTesting extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return \\Illuminate\\Testing\\ParallelTesting::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Password.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Auth\\PasswordBroker;\n\n/**\n * @method static \\Illuminate\\Contracts\\Auth\\PasswordBroker broker(string|null $name = null)\n * @method static string getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static string sendResetLink(array $credentials, \\Closure|null $callback = null)\n * @method static mixed reset(array $credentials, \\Closure $callback)\n * @method static \\Illuminate\\Contracts\\Auth\\CanResetPassword|null getUser(array $credentials)\n * @method static string createToken(\\Illuminate\\Contracts\\Auth\\CanResetPassword $user)\n * @method static void deleteToken(\\Illuminate\\Contracts\\Auth\\CanResetPassword $user)\n * @method static bool tokenExists(\\Illuminate\\Contracts\\Auth\\CanResetPassword $user, string $token)\n * @method static \\Illuminate\\Auth\\Passwords\\TokenRepositoryInterface getRepository()\n * @method static \\Illuminate\\Support\\Timebox getTimebox()\n *\n * @see \\Illuminate\\Auth\\Passwords\\PasswordBrokerManager\n * @see \\Illuminate\\Auth\\Passwords\\PasswordBroker\n */\nclass Password extends Facade\n{\n    /**\n     * Constant representing a successfully sent password reset email.\n     *\n     * @var string\n     */\n    const ResetLinkSent = PasswordBroker::RESET_LINK_SENT;\n\n    /**\n     * Constant representing a successfully reset password.\n     *\n     * @var string\n     */\n    const PasswordReset = PasswordBroker::PASSWORD_RESET;\n\n    /**\n     * Constant indicating the user could not be found when attempting a password reset.\n     *\n     * @var string\n     */\n    const InvalidUser = PasswordBroker::INVALID_USER;\n\n    /**\n     * Constant representing an invalid password reset token.\n     *\n     * @var string\n     */\n    const InvalidToken = PasswordBroker::INVALID_TOKEN;\n\n    /**\n     * Constant representing a throttled password reset attempt.\n     *\n     * @var string\n     */\n    const ResetThrottled = PasswordBroker::RESET_THROTTLED;\n\n    const RESET_LINK_SENT = PasswordBroker::RESET_LINK_SENT;\n    const PASSWORD_RESET = PasswordBroker::PASSWORD_RESET;\n    const INVALID_USER = PasswordBroker::INVALID_USER;\n    const INVALID_TOKEN = PasswordBroker::INVALID_TOKEN;\n    const RESET_THROTTLED = PasswordBroker::RESET_THROTTLED;\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'auth.password';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Pipeline.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Pipeline\\Pipeline send(mixed $passable)\n * @method static \\Illuminate\\Pipeline\\Pipeline through(mixed $pipes)\n * @method static \\Illuminate\\Pipeline\\Pipeline pipe(mixed $pipes)\n * @method static \\Illuminate\\Pipeline\\Pipeline via(string $method)\n * @method static mixed then(\\Closure $destination)\n * @method static mixed thenReturn()\n * @method static \\Illuminate\\Pipeline\\Pipeline finally(\\Closure $callback)\n * @method static \\Illuminate\\Pipeline\\Pipeline withinTransaction(string|null|\\UnitEnum|false $withinTransaction = null)\n * @method static \\Illuminate\\Pipeline\\Pipeline setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Pipeline\\Pipeline|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Pipeline\\Pipeline|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Pipeline\\Pipeline\n */\nclass Pipeline extends Facade\n{\n    /**\n     * Indicates if the resolved instance should be cached.\n     *\n     * @var bool\n     */\n    protected static $cached = false;\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'pipeline';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Process.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Closure;\nuse Illuminate\\Process\\Factory;\n\n/**\n * @method static \\Illuminate\\Process\\PendingProcess command(array|string $command)\n * @method static \\Illuminate\\Process\\PendingProcess path(string $path)\n * @method static \\Illuminate\\Process\\PendingProcess timeout(\\Carbon\\CarbonInterval|int $timeout)\n * @method static \\Illuminate\\Process\\PendingProcess idleTimeout(\\Carbon\\CarbonInterval|int $timeout)\n * @method static \\Illuminate\\Process\\PendingProcess forever()\n * @method static \\Illuminate\\Process\\PendingProcess env(array $environment)\n * @method static \\Illuminate\\Process\\PendingProcess input(\\Traversable|resource|string|int|float|bool|null $input)\n * @method static \\Illuminate\\Process\\PendingProcess quietly()\n * @method static \\Illuminate\\Process\\PendingProcess tty(bool $tty = true)\n * @method static \\Illuminate\\Process\\PendingProcess options(array $options)\n * @method static \\Illuminate\\Contracts\\Process\\ProcessResult run(array|string|null $command = null, callable|null $output = null)\n * @method static \\Illuminate\\Process\\InvokedProcess start(array|string|null $command = null, callable|null $output = null)\n * @method static bool supportsTty()\n * @method static \\Illuminate\\Process\\PendingProcess withFakeHandlers(array $fakeHandlers)\n * @method static \\Illuminate\\Process\\PendingProcess|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Process\\PendingProcess|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Process\\FakeProcessResult result(array|string $output = '', array|string $errorOutput = '', int $exitCode = 0)\n * @method static \\Illuminate\\Process\\FakeProcessDescription describe()\n * @method static \\Illuminate\\Process\\FakeProcessSequence sequence(array $processes = [])\n * @method static bool isRecording()\n * @method static \\Illuminate\\Process\\Factory recordIfRecording(\\Illuminate\\Process\\PendingProcess $process, \\Illuminate\\Contracts\\Process\\ProcessResult $result)\n * @method static \\Illuminate\\Process\\Factory record(\\Illuminate\\Process\\PendingProcess $process, \\Illuminate\\Contracts\\Process\\ProcessResult $result)\n * @method static \\Illuminate\\Process\\Factory preventStrayProcesses(bool $prevent = true)\n * @method static bool preventingStrayProcesses()\n * @method static \\Illuminate\\Process\\Factory assertRan(\\Closure|string $callback)\n * @method static \\Illuminate\\Process\\Factory assertRanTimes(\\Closure|string $callback, int $times = 1)\n * @method static \\Illuminate\\Process\\Factory assertNotRan(\\Closure|string $callback)\n * @method static \\Illuminate\\Process\\Factory assertDidntRun(\\Closure|string $callback)\n * @method static \\Illuminate\\Process\\Factory assertNothingRan()\n * @method static \\Illuminate\\Process\\Pool pool(callable $callback)\n * @method static \\Illuminate\\Contracts\\Process\\ProcessResult pipe(callable|array $callback, callable|null $output = null)\n * @method static \\Illuminate\\Process\\ProcessPoolResults concurrently(callable $callback, callable|null $output = null)\n * @method static \\Illuminate\\Process\\PendingProcess newPendingProcess()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n *\n * @see \\Illuminate\\Process\\PendingProcess\n * @see \\Illuminate\\Process\\Factory\n */\nclass Process extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return Factory::class;\n    }\n\n    /**\n     * Indicate that the process factory should fake processes.\n     *\n     * @param  \\Closure|array|null  $callback\n     * @return \\Illuminate\\Process\\Factory\n     */\n    public static function fake(Closure|array|null $callback = null)\n    {\n        return tap(static::getFacadeRoot(), function ($fake) use ($callback) {\n            static::swap($fake->fake($callback));\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Queue.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Queue\\Worker;\nuse Illuminate\\Support\\Testing\\Fakes\\QueueFake;\n\n/**\n * @method static void before(mixed $callback)\n * @method static void after(mixed $callback)\n * @method static void exceptionOccurred(mixed $callback)\n * @method static void looping(mixed $callback)\n * @method static void failing(mixed $callback)\n * @method static void starting(mixed $callback)\n * @method static void stopping(mixed $callback)\n * @method static void route(array|string $class, string|null $queue = null, string|null $connection = null)\n * @method static bool connected(string|null $name = null)\n * @method static \\Illuminate\\Contracts\\Queue\\Queue connection(string|null $name = null)\n * @method static void pause(string $connection, string $queue)\n * @method static void pauseFor(string $connection, string $queue, \\DateTimeInterface|\\DateInterval|int $ttl)\n * @method static void resume(string $connection, string $queue)\n * @method static bool isPaused(string $connection, string $queue)\n * @method static void withoutInterruptionPolling()\n * @method static void extend(string $driver, \\Closure $resolver)\n * @method static void addConnector(string $driver, \\Closure $resolver)\n * @method static string getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static string getName(string|null $connection = null)\n * @method static \\Illuminate\\Contracts\\Foundation\\Application getApplication()\n * @method static \\Illuminate\\Queue\\QueueManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static string|null resolveConnectionFromQueueRoute(object $queueable)\n * @method static string|null resolveQueueFromQueueRoute(object $queueable)\n * @method static int size(string|null $queue = null)\n * @method static int pendingSize(string|null $queue = null)\n * @method static int delayedSize(string|null $queue = null)\n * @method static int reservedSize(string|null $queue = null)\n * @method static int|null creationTimeOfOldestPendingJob(string|null $queue = null)\n * @method static mixed push(string|object $job, mixed $data = '', string|null $queue = null)\n * @method static mixed pushOn(string $queue, string|object $job, mixed $data = '')\n * @method static mixed pushRaw(string $payload, string|null $queue = null, array $options = [])\n * @method static mixed later(\\DateTimeInterface|\\DateInterval|int $delay, string|object $job, mixed $data = '', string|null $queue = null)\n * @method static mixed laterOn(string $queue, \\DateTimeInterface|\\DateInterval|int $delay, string|object $job, mixed $data = '')\n * @method static mixed bulk(array $jobs, mixed $data = '', string|null $queue = null)\n * @method static \\Illuminate\\Contracts\\Queue\\Job|null pop(string|null $queue = null)\n * @method static string getConnectionName()\n * @method static \\Illuminate\\Contracts\\Queue\\Queue setConnectionName(string $name)\n * @method static mixed getJobTries(mixed $job)\n * @method static mixed getJobBackoff(mixed $job)\n * @method static mixed getJobExpiration(mixed $job)\n * @method static void createPayloadUsing(callable|null $callback)\n * @method static array getConfig()\n * @method static \\Illuminate\\Queue\\Queue setConfig(array $config)\n * @method static \\Illuminate\\Container\\Container getContainer()\n * @method static void setContainer(\\Illuminate\\Container\\Container $container)\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\QueueFake except(array|string $jobsToBeQueued)\n * @method static void assertPushed(string|\\Closure $job, callable|int|null $callback = null)\n * @method static void assertPushedTimes(string $job, int $times = 1)\n * @method static void assertPushedOn(string $queue, string|\\Closure $job, callable|null $callback = null)\n * @method static void assertPushedWithChain(string $job, array $expectedChain = [], callable|null $callback = null)\n * @method static void assertPushedWithoutChain(string $job, callable|null $callback = null)\n * @method static void assertClosurePushed(callable|int|null $callback = null)\n * @method static void assertClosureNotPushed(callable|null $callback = null)\n * @method static void assertNotPushed(string|\\Closure $job, callable|null $callback = null)\n * @method static void assertCount(int $expectedCount)\n * @method static void assertNothingPushed()\n * @method static \\Illuminate\\Support\\Collection pushed(string $job, callable|null $callback = null)\n * @method static \\Illuminate\\Support\\Collection pushedRaw(null|\\Closure $callback = null)\n * @method static \\Illuminate\\Support\\Collection listenersPushed(string $listenerClass, \\Closure|null $callback = null)\n * @method static bool hasPushed(string $job)\n * @method static bool shouldFakeJob(object $job)\n * @method static array pushedJobs()\n * @method static array rawPushes()\n * @method static \\Illuminate\\Support\\Testing\\Fakes\\QueueFake serializeAndRestore(bool $serializeAndRestore = true)\n * @method static void releaseUniqueJobLocks()\n *\n * @see \\Illuminate\\Queue\\QueueManager\n * @see \\Illuminate\\Queue\\Queue\n * @see \\Illuminate\\Support\\Testing\\Fakes\\QueueFake\n */\nclass Queue extends Facade\n{\n    /**\n     * Register a callback to be executed to pick jobs.\n     *\n     * @param  string  $workerName\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function popUsing($workerName, $callback)\n    {\n        Worker::popUsing($workerName, $callback);\n    }\n\n    /**\n     * Replace the bound instance with a fake.\n     *\n     * @param  array|string  $jobsToFake\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\QueueFake\n     */\n    public static function fake($jobsToFake = [])\n    {\n        $actualQueueManager = static::isFake()\n            ? tap(static::getFacadeRoot(), fn ($fake) => $fake->releaseUniqueJobLocks())->queue\n            : static::getFacadeRoot();\n\n        return tap(new QueueFake(static::getFacadeApplication(), $jobsToFake, $actualQueueManager), function ($fake) {\n            static::swap($fake);\n        });\n    }\n\n    /**\n     * Replace the bound instance with a fake that fakes all jobs except the given jobs.\n     *\n     * @param  string[]|string  $jobsToAllow\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\QueueFake\n     */\n    public static function fakeExcept($jobsToAllow)\n    {\n        return static::fake()->except($jobsToAllow);\n    }\n\n    /**\n     * Replace the bound instance with a fake during the given callable's execution.\n     *\n     * @param  callable  $callable\n     * @param  array  $jobsToFake\n     * @return mixed\n     */\n    public static function fakeFor(callable $callable, array $jobsToFake = [])\n    {\n        $originalQueueManager = static::getFacadeRoot();\n\n        static::fake($jobsToFake);\n\n        try {\n            return $callable();\n        } finally {\n            static::swap($originalQueueManager);\n        }\n    }\n\n    /**\n     * Replace the bound instance with a fake during the given callable's execution.\n     *\n     * @param  callable  $callable\n     * @param  array  $jobsToAllow\n     * @return mixed\n     */\n    public static function fakeExceptFor(callable $callable, array $jobsToAllow = [])\n    {\n        $originalQueueManager = static::getFacadeRoot();\n\n        static::fakeExcept($jobsToAllow);\n\n        try {\n            return $callable();\n        } finally {\n            static::swap($originalQueueManager);\n        }\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'queue';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/RateLimiter.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Cache\\RateLimiter for(\\UnitEnum|string $name, \\Closure $callback)\n * @method static \\Closure|null limiter(\\UnitEnum|string $name)\n * @method static mixed attempt(string $key, int $maxAttempts, \\Closure $callback, \\DateTimeInterface|\\DateInterval|int $decaySeconds = 60)\n * @method static bool tooManyAttempts(string $key, int $maxAttempts)\n * @method static int hit(string $key, \\DateTimeInterface|\\DateInterval|int $decaySeconds = 60)\n * @method static int increment(string $key, \\DateTimeInterface|\\DateInterval|int $decaySeconds = 60, int $amount = 1)\n * @method static int decrement(string $key, \\DateTimeInterface|\\DateInterval|int $decaySeconds = 60, int $amount = 1)\n * @method static mixed attempts(string $key)\n * @method static bool resetAttempts(string $key)\n * @method static int remaining(string $key, int $maxAttempts)\n * @method static int retriesLeft(string $key, int $maxAttempts)\n * @method static void clear(string $key)\n * @method static int availableIn(string $key)\n * @method static string cleanRateLimiterKey(string $key)\n *\n * @see \\Illuminate\\Cache\\RateLimiter\n */\nclass RateLimiter extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return \\Illuminate\\Cache\\RateLimiter::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Redirect.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Http\\RedirectResponse back(int $status = 302, array $headers = [], mixed $fallback = false)\n * @method static \\Illuminate\\Http\\RedirectResponse refresh(int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse guest(string $path, int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static \\Illuminate\\Http\\RedirectResponse intended(mixed $default = '/', int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static \\Illuminate\\Http\\RedirectResponse to(string $path, int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static \\Illuminate\\Http\\RedirectResponse away(string $path, int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse secure(string $path, int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse route(\\BackedEnum|string $route, mixed $parameters = [], int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse signedRoute(\\BackedEnum|string $route, mixed $parameters = [], \\DateTimeInterface|\\DateInterval|int|null $expiration = null, int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse temporarySignedRoute(\\BackedEnum|string $route, \\DateTimeInterface|\\DateInterval|int|null $expiration, mixed $parameters = [], int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse action(string|array $action, mixed $parameters = [], int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Routing\\UrlGenerator getUrlGenerator()\n * @method static void setSession(\\Illuminate\\Session\\Store $session)\n * @method static string|null getIntendedUrl()\n * @method static \\Illuminate\\Routing\\Redirector setIntendedUrl(string $url)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Routing\\Redirector\n */\nclass Redirect extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'redirect';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Redis.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Redis\\Connections\\Connection connection(\\UnitEnum|string|null $name = null)\n * @method static \\Illuminate\\Redis\\Connections\\Connection resolve(string|null $name = null)\n * @method static array connections()\n * @method static void enableEvents()\n * @method static void disableEvents()\n * @method static void setDriver(string $driver)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Redis\\RedisManager extend(string $driver, \\Closure $callback)\n * @method static void createSubscription(array|string $channels, \\Closure $callback, string $method = 'subscribe')\n * @method static \\Illuminate\\Redis\\Limiters\\ConcurrencyLimiterBuilder funnel(string $name)\n * @method static \\Illuminate\\Redis\\Limiters\\DurationLimiterBuilder throttle(string $name)\n * @method static mixed client()\n * @method static void subscribe(array|string $channels, \\Closure $callback)\n * @method static void psubscribe(array|string $channels, \\Closure $callback)\n * @method static mixed command(string $method, array $parameters = [])\n * @method static void listen(\\Closure $callback)\n * @method static void listenForFailures(\\Closure $callback)\n * @method static string|null getName()\n * @method static \\Illuminate\\Redis\\Connections\\Connection setName(string $name)\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher|null getEventDispatcher()\n * @method static void setEventDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $events)\n * @method static void unsetEventDispatcher()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n *\n * @see \\Illuminate\\Redis\\RedisManager\n */\nclass Redis extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'redis';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Request.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Http\\Request capture()\n * @method static \\Illuminate\\Http\\Request instance()\n * @method static string method()\n * @method static \\Illuminate\\Support\\Uri uri()\n * @method static string root()\n * @method static string url()\n * @method static string fullUrl()\n * @method static string fullUrlWithQuery(array $query)\n * @method static string fullUrlWithoutQuery(array|string $keys)\n * @method static string path()\n * @method static string decodedPath()\n * @method static string|null segment(int $index, string|null $default = null)\n * @method static array segments()\n * @method static bool is(mixed ...$patterns)\n * @method static bool routeIs(mixed ...$patterns)\n * @method static bool fullUrlIs(mixed ...$patterns)\n * @method static string host()\n * @method static string httpHost()\n * @method static string schemeAndHttpHost()\n * @method static bool ajax()\n * @method static bool pjax()\n * @method static bool prefetch()\n * @method static bool secure()\n * @method static string|null ip()\n * @method static array ips()\n * @method static string|null userAgent()\n * @method static array getAcceptableContentTypes()\n * @method static \\Illuminate\\Http\\Request merge(array $input)\n * @method static \\Illuminate\\Http\\Request mergeIfMissing(array $input)\n * @method static \\Illuminate\\Http\\Request replace(array $input)\n * @method static \\Symfony\\Component\\HttpFoundation\\InputBag|mixed json(string|null $key = null, mixed $default = null)\n * @method static \\Illuminate\\Http\\Request createFrom(\\Illuminate\\Http\\Request $from, \\Illuminate\\Http\\Request|null $to = null)\n * @method static \\Illuminate\\Http\\Request createFromBase(\\Symfony\\Component\\HttpFoundation\\Request $request)\n * @method static \\Illuminate\\Http\\Request duplicate(array|null $query = null, array|null $request = null, array|null $attributes = null, array|null $cookies = null, array|null $files = null, array|null $server = null)\n * @method static bool hasSession(bool $skipIfUninitialized = false)\n * @method static \\Symfony\\Component\\HttpFoundation\\Session\\SessionInterface getSession()\n * @method static \\Illuminate\\Contracts\\Session\\Session session()\n * @method static void setLaravelSession(\\Illuminate\\Contracts\\Session\\Session $session)\n * @method static void setRequestLocale(string $locale)\n * @method static void setDefaultRequestLocale(string $locale)\n * @method static mixed user(string|null $guard = null)\n * @method static \\Illuminate\\Routing\\Route|object|string|null route(string|null $param = null, mixed $default = null)\n * @method static string fingerprint()\n * @method static \\Illuminate\\Http\\Request setJson(\\Symfony\\Component\\HttpFoundation\\InputBag $json)\n * @method static \\Closure getUserResolver()\n * @method static \\Illuminate\\Http\\Request setUserResolver(\\Closure $callback)\n * @method static \\Closure getRouteResolver()\n * @method static \\Illuminate\\Http\\Request setRouteResolver(\\Closure $callback)\n * @method static array toArray()\n * @method static void initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], string|resource|null $content = null)\n * @method static \\Illuminate\\Http\\Request createFromGlobals()\n * @method static \\Illuminate\\Http\\Request create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], string|resource|null $content = null)\n * @method static void setFactory(callable|null $callable)\n * @method static void overrideGlobals()\n * @method static void setTrustedProxies(array $proxies, int $trustedHeaderSet)\n * @method static string[] getTrustedProxies()\n * @method static int getTrustedHeaderSet()\n * @method static void setTrustedHosts(array $hostPatterns)\n * @method static string[] getTrustedHosts()\n * @method static string normalizeQueryString(string|null $qs)\n * @method static void enableHttpMethodParameterOverride()\n * @method static bool getHttpMethodParameterOverride()\n * @method static void setAllowedHttpMethodOverride(string[]|null $methods)\n * @method static string[]|null getAllowedHttpMethodOverride()\n * @method static bool hasPreviousSession()\n * @method static void setSession(\\Symfony\\Component\\HttpFoundation\\Session\\SessionInterface $session)\n * @method static array getClientIps()\n * @method static string|null getClientIp()\n * @method static string getScriptName()\n * @method static string getPathInfo()\n * @method static string getBasePath()\n * @method static string getBaseUrl()\n * @method static string getScheme()\n * @method static int|string|null getPort()\n * @method static string|null getUser()\n * @method static string|null getPassword()\n * @method static string|null getUserInfo()\n * @method static string getHttpHost()\n * @method static string getRequestUri()\n * @method static string getSchemeAndHttpHost()\n * @method static string getUri()\n * @method static string getUriForPath(string $path)\n * @method static string getRelativeUriForPath(string $path)\n * @method static string|null getQueryString()\n * @method static bool isSecure()\n * @method static string getHost()\n * @method static void setMethod(string $method)\n * @method static string getMethod()\n * @method static string getRealMethod()\n * @method static string|null getMimeType(string $format)\n * @method static string[] getMimeTypes(string $format)\n * @method static string|null getFormat(string|null $mimeType, bool $subtypeFallback = null)\n * @method static void setFormat(string $format, string|string[] $mimeTypes)\n * @method static string|null getRequestFormat(string|null $default = 'html')\n * @method static void setRequestFormat(string|null $format)\n * @method static string|null getContentTypeFormat()\n * @method static void setDefaultLocale(string $locale)\n * @method static string getDefaultLocale()\n * @method static void setLocale(string $locale)\n * @method static string getLocale()\n * @method static bool isMethod(string $method)\n * @method static bool isMethodSafe()\n * @method static bool isMethodIdempotent()\n * @method static bool isMethodCacheable()\n * @method static string|null getProtocolVersion()\n * @method static string|resource getContent(bool $asResource = false)\n * @method static \\Symfony\\Component\\HttpFoundation\\InputBag getPayload()\n * @method static array getETags()\n * @method static bool isNoCache()\n * @method static string|null getPreferredFormat(string|null $default = 'html')\n * @method static string|null getPreferredLanguage(string[] $locales = null)\n * @method static string[] getLanguages()\n * @method static string[] getCharsets()\n * @method static string[] getEncodings()\n * @method static bool isXmlHttpRequest()\n * @method static bool preferSafeContent()\n * @method static bool isFromTrustedProxy()\n * @method static array filterPrecognitiveRules(array $rules)\n * @method static bool isAttemptingPrecognition()\n * @method static bool isPrecognitive()\n * @method static bool isJson()\n * @method static bool expectsJson()\n * @method static bool wantsJson()\n * @method static bool wantsMarkdown()\n * @method static bool accepts(string|array $contentTypes)\n * @method static string|null prefers(string|array $contentTypes)\n * @method static bool acceptsAnyContentType()\n * @method static bool acceptsJson()\n * @method static bool acceptsMarkdown()\n * @method static bool acceptsHtml()\n * @method static bool matchesType(string $actual, string $type)\n * @method static string format(string $default = 'html')\n * @method static string|array|null old(string|null $key = null, \\Illuminate\\Database\\Eloquent\\Model|string|array|null $default = null)\n * @method static void flash()\n * @method static void flashOnly(mixed $keys)\n * @method static void flashExcept(mixed $keys)\n * @method static void flush()\n * @method static string|array|null server(string|null $key = null, string|array|null $default = null)\n * @method static bool hasHeader(string $key)\n * @method static string|array|null header(string|null $key = null, string|array|null $default = null)\n * @method static string|null bearerToken()\n * @method static array keys()\n * @method static array all(mixed $keys = null)\n * @method static mixed input(string|null $key = null, mixed $default = null)\n * @method static \\Illuminate\\Support\\Fluent fluent(array|string|null $key = null, array $default = [])\n * @method static string|array|null query(string|null $key = null, string|array|null $default = null)\n * @method static string|array|null post(string|null $key = null, string|array|null $default = null)\n * @method static bool hasCookie(string $key)\n * @method static string|array|null cookie(string|null $key = null, string|array|null $default = null)\n * @method static array allFiles()\n * @method static bool hasFile(string $key)\n * @method static array|\\Illuminate\\Http\\UploadedFile|\\Illuminate\\Http\\UploadedFile[]|null file(string|null $key = null, mixed $default = null)\n * @method static \\Illuminate\\Http\\Request dump(mixed $keys = [])\n * @method static never dd(mixed ...$args)\n * @method static bool exists(string|array $key)\n * @method static bool has(string|array $key)\n * @method static bool hasAny(string|array $keys)\n * @method static \\Illuminate\\Http\\Request|mixed whenHas(string $key, callable $callback, callable|null $default = null)\n * @method static bool filled(string|array $key)\n * @method static bool isNotFilled(string|array $key)\n * @method static bool anyFilled(string|array $keys)\n * @method static \\Illuminate\\Http\\Request|mixed whenFilled(string $key, callable $callback, callable|null $default = null)\n * @method static bool missing(string|array $key)\n * @method static \\Illuminate\\Http\\Request|mixed whenMissing(string $key, callable $callback, callable|null $default = null)\n * @method static \\Illuminate\\Support\\Stringable str(string $key, mixed $default = null)\n * @method static \\Illuminate\\Support\\Stringable string(string $key, mixed $default = null)\n * @method static bool boolean(string|null $key = null, bool $default = false)\n * @method static int integer(string $key, int $default = 0)\n * @method static float float(string $key, float $default = 0)\n * @method static float|int clamp(string $key, int|float $min, int|float $max, int|float $default = 0)\n * @method static \\Illuminate\\Support\\Carbon|null date(string $key, string|null $format = null, \\UnitEnum|string|null $tz = null)\n * @method static \\Carbon\\CarbonInterval|null interval(string $key, \\Carbon\\Unit|string|null $unit = null)\n * @method static \\BackedEnum|(\\BackedEnum|null enum(string $key, string $enumClass, \\BackedEnum|null $default = null)\n * @method static \\BackedEnum[] enums(string $key, string $enumClass)\n * @method static array array(array|string|null $key = null)\n * @method static \\Illuminate\\Support\\Collection collect(array|string|null $key = null)\n * @method static array only(mixed $keys)\n * @method static array except(mixed $keys)\n * @method static \\Illuminate\\Http\\Request|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Http\\Request|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static array validate(array $rules, ...$params)\n * @method static array validateWithBag(string $errorBag, array $rules, ...$params)\n * @method static bool hasValidSignature(bool $absolute = true)\n * @method static bool hasValidRelativeSignature()\n * @method static bool hasValidSignatureWhileIgnoring($ignoreQuery = [], $absolute = true)\n * @method static bool hasValidRelativeSignatureWhileIgnoring($ignoreQuery = [])\n *\n * @see \\Illuminate\\Http\\Request\n */\nclass Request extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'request';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Response.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Contracts\\Routing\\ResponseFactory as ResponseFactoryContract;\n\n/**\n * @method static \\Illuminate\\Http\\Response make(mixed $content = '', int $status = 200, array $headers = [])\n * @method static \\Illuminate\\Http\\Response noContent(int $status = 204, array $headers = [])\n * @method static \\Illuminate\\Http\\Response view(string|array $view, array $data = [], int $status = 200, array $headers = [])\n * @method static \\Illuminate\\Http\\JsonResponse json(mixed $data = [], int $status = 200, array $headers = [], int $options = 0)\n * @method static \\Illuminate\\Http\\JsonResponse jsonp(string $callback, mixed $data = [], int $status = 200, array $headers = [], int $options = 0)\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse eventStream(\\Closure $callback, array $headers = [], \\Illuminate\\Http\\StreamedEvent|string|null $endStreamWith = '</stream>')\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse stream(callable|null $callback, int $status = 200, array $headers = [])\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedJsonResponse streamJson(array $data, int $status = 200, array $headers = [], int $encodingOptions = 15)\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse streamDownload(callable $callback, string|null $name = null, array $headers = [], string|null $disposition = 'attachment')\n * @method static \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse download(\\SplFileInfo|string $file, string|null $name = null, array $headers = [], string|null $disposition = 'attachment')\n * @method static \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse file(\\SplFileInfo|string $file, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse redirectTo(string $path, int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static \\Illuminate\\Http\\RedirectResponse redirectToRoute(\\BackedEnum|string $route, mixed $parameters = [], int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse redirectToAction(array|string $action, mixed $parameters = [], int $status = 302, array $headers = [])\n * @method static \\Illuminate\\Http\\RedirectResponse redirectGuest(string $path, int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static \\Illuminate\\Http\\RedirectResponse redirectToIntended(string $default = '/', int $status = 302, array $headers = [], bool|null $secure = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Routing\\ResponseFactory\n */\nclass Response extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ResponseFactoryContract::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Route.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Routing\\Route get(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route post(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route put(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route patch(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route delete(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route options(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route any(string $uri, array|string|callable|null $action = null)\n * @method static \\Illuminate\\Routing\\Route fallback(array|string|callable|null $action)\n * @method static \\Illuminate\\Routing\\Route redirect(string $uri, string $destination, int $status = 302)\n * @method static \\Illuminate\\Routing\\Route permanentRedirect(string $uri, string $destination)\n * @method static \\Illuminate\\Routing\\Route view(string $uri, string $view, array $data = [], int|array $status = 200, array $headers = [])\n * @method static \\Illuminate\\Routing\\Route match(array|string $methods, string $uri, array|string|callable|null $action = null)\n * @method static void resources(array $resources, array $options = [])\n * @method static void softDeletableResources(array $resources, array $options = [])\n * @method static \\Illuminate\\Routing\\PendingResourceRegistration resource(string $name, string $controller, array $options = [])\n * @method static void apiResources(array $resources, array $options = [])\n * @method static \\Illuminate\\Routing\\PendingResourceRegistration apiResource(string $name, string $controller, array $options = [])\n * @method static void singletons(array $singletons, array $options = [])\n * @method static \\Illuminate\\Routing\\PendingSingletonResourceRegistration singleton(string $name, string $controller, array $options = [])\n * @method static void apiSingletons(array $singletons, array $options = [])\n * @method static \\Illuminate\\Routing\\PendingSingletonResourceRegistration apiSingleton(string $name, string $controller, array $options = [])\n * @method static \\Illuminate\\Routing\\Router group(array $attributes, \\Closure|array|string $routes)\n * @method static array mergeWithLastGroup(array $new, bool $prependExistingPrefix = true)\n * @method static string getLastGroupPrefix()\n * @method static \\Illuminate\\Routing\\Route addRoute(array|string $methods, string $uri, array|string|callable|null $action)\n * @method static \\Illuminate\\Routing\\Route newRoute(array|string $methods, string $uri, mixed $action)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response respondWithRoute(string $name)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response dispatch(\\Illuminate\\Http\\Request $request)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response dispatchToRoute(\\Illuminate\\Http\\Request $request)\n * @method static array gatherRouteMiddleware(\\Illuminate\\Routing\\Route $route)\n * @method static array resolveMiddleware(array $middleware, array $excluded = [])\n * @method static \\Symfony\\Component\\HttpFoundation\\Response prepareResponse(\\Symfony\\Component\\HttpFoundation\\Request $request, mixed $response)\n * @method static \\Symfony\\Component\\HttpFoundation\\Response toResponse(\\Symfony\\Component\\HttpFoundation\\Request $request, mixed $response)\n * @method static \\Illuminate\\Routing\\Route substituteBindings(\\Illuminate\\Routing\\Route $route)\n * @method static void substituteImplicitBindings(\\Illuminate\\Routing\\Route $route)\n * @method static \\Illuminate\\Routing\\Router substituteImplicitBindingsUsing(callable $callback)\n * @method static void matched(string|callable $callback)\n * @method static array getMiddleware()\n * @method static \\Illuminate\\Routing\\Router aliasMiddleware(string $name, string $class)\n * @method static bool hasMiddlewareGroup(string $name)\n * @method static array getMiddlewareGroups()\n * @method static \\Illuminate\\Routing\\Router middlewareGroup(string $name, array $middleware)\n * @method static \\Illuminate\\Routing\\Router prependMiddlewareToGroup(string $group, string $middleware)\n * @method static \\Illuminate\\Routing\\Router pushMiddlewareToGroup(string $group, string $middleware)\n * @method static \\Illuminate\\Routing\\Router removeMiddlewareFromGroup(string $group, string $middleware)\n * @method static \\Illuminate\\Routing\\Router flushMiddlewareGroups()\n * @method static void bind(string $key, string|callable $binder)\n * @method static void model(string $key, string $class, \\Closure|null $callback = null)\n * @method static \\Closure|null getBindingCallback(string $key)\n * @method static array getPatterns()\n * @method static void pattern(string $key, string $pattern)\n * @method static void patterns(array $patterns)\n * @method static bool hasGroupStack()\n * @method static array getGroupStack()\n * @method static mixed input(string $key, string|null $default = null)\n * @method static \\Illuminate\\Http\\Request getCurrentRequest()\n * @method static \\Illuminate\\Routing\\Route|null getCurrentRoute()\n * @method static \\Illuminate\\Routing\\Route|null current()\n * @method static bool has(string|array $name)\n * @method static string|null currentRouteName()\n * @method static bool is(mixed ...$patterns)\n * @method static bool currentRouteNamed(mixed ...$patterns)\n * @method static string|null currentRouteAction()\n * @method static bool uses(array|string ...$patterns)\n * @method static bool currentRouteUses(string $action)\n * @method static void singularResourceParameters(bool $singular = true)\n * @method static void resourceParameters(array $parameters = [])\n * @method static array|null resourceVerbs(array $verbs = [])\n * @method static \\Illuminate\\Routing\\RouteCollectionInterface getRoutes()\n * @method static void setRoutes(\\Illuminate\\Routing\\RouteCollection $routes)\n * @method static void setCompiledRoutes(array $routes)\n * @method static array uniqueMiddleware(array $middleware)\n * @method static \\Illuminate\\Routing\\Router setContainer(\\Illuminate\\Container\\Container $container)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static \\Illuminate\\Support\\HigherOrderTapProxy|\\Illuminate\\Routing\\Router tap(callable|null $callback = null)\n * @method static \\Illuminate\\Routing\\RouteRegistrar attribute(string $key, mixed $value)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereAlpha(array|string $parameters)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereAlphaNumeric(array|string $parameters)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereNumber(array|string $parameters)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereUlid(array|string $parameters)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereUuid(array|string $parameters)\n * @method static \\Illuminate\\Routing\\RouteRegistrar whereIn(array|string $parameters, array $values)\n * @method static \\Illuminate\\Routing\\RouteRegistrar as(string $value)\n * @method static \\Illuminate\\Routing\\RouteRegistrar can(\\UnitEnum|string $ability, array|string $models = [])\n * @method static \\Illuminate\\Routing\\RouteRegistrar controller(string $controller)\n * @method static \\Illuminate\\Routing\\RouteRegistrar domain(\\BackedEnum|string $value)\n * @method static \\Illuminate\\Routing\\RouteRegistrar middleware(array|string|null $middleware)\n * @method static \\Illuminate\\Routing\\RouteRegistrar missing(\\Closure $missing)\n * @method static \\Illuminate\\Routing\\RouteRegistrar name(\\BackedEnum|string $value)\n * @method static \\Illuminate\\Routing\\RouteRegistrar namespace(string|null $value)\n * @method static \\Illuminate\\Routing\\RouteRegistrar prefix(string $prefix)\n * @method static \\Illuminate\\Routing\\RouteRegistrar scopeBindings()\n * @method static \\Illuminate\\Routing\\RouteRegistrar where(array $where)\n * @method static \\Illuminate\\Routing\\RouteRegistrar withoutMiddleware(array|string $middleware)\n * @method static \\Illuminate\\Routing\\RouteRegistrar withoutScopedBindings()\n *\n * @see \\Illuminate\\Routing\\Router\n */\nclass Route extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'router';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Schedule.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Console\\Scheduling\\Schedule as ConsoleSchedule;\n\n/**\n * @method static \\Illuminate\\Console\\Scheduling\\CallbackEvent call(string|callable $callback, array $parameters = [])\n * @method static \\Illuminate\\Console\\Scheduling\\Event command(\\Symfony\\Component\\Console\\Command\\Command|string $command, array $parameters = [])\n * @method static \\Illuminate\\Console\\Scheduling\\CallbackEvent job(object|string $job, \\UnitEnum|string|null $queue = null, \\UnitEnum|string|null $connection = null)\n * @method static \\Illuminate\\Console\\Scheduling\\Event exec(string $command, array $parameters = [])\n * @method static void group(\\Closure $events)\n * @method static string compileArrayInput(string|int $key, array $value)\n * @method static bool serverShouldRun(\\Illuminate\\Console\\Scheduling\\Event $event, \\DateTimeInterface $time)\n * @method static \\Illuminate\\Support\\Collection dueEvents(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static \\Illuminate\\Console\\Scheduling\\Event[] events()\n * @method static \\Illuminate\\Console\\Scheduling\\Schedule useCache(\\UnitEnum|string $store)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes withoutOverlapping(int $expiresAt = 1440)\n * @method static void mergeAttributes(\\Illuminate\\Console\\Scheduling\\Event $event)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes user(string $user)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes environments(mixed $environments)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes evenInMaintenanceMode()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes evenWhenPaused()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes onOneServer()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes runInBackground()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes when(\\Closure|bool $callback)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes skip(\\Closure|bool $callback)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes name(string $description)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes description(string $description)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes cron(string $expression)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes between(string $startTime, string $endTime)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes unlessBetween(string $startTime, string $endTime)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everySecond()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTwoSeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFiveSeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTenSeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFifteenSeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTwentySeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyThirtySeconds()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyMinute()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTwoMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyThreeMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFourMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFiveMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTenMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFifteenMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyThirtyMinutes()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes hourly()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes hourlyAt(array|string|int|int[] $offset)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyOddHour(array|string|int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyTwoHours(array|string|int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyThreeHours(array|string|int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everyFourHours(array|string|int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes everySixHours(array|string|int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes daily()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes at(string $time)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes dailyAt(string $time)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes twiceDaily(int $first = 1, int $second = 13)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes twiceDailyAt(int $first = 1, int $second = 13, int $offset = 0)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes weekdays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes weekends()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes mondays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes tuesdays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes wednesdays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes thursdays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes fridays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes saturdays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes sundays()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes weekly()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes weeklyOn(mixed $dayOfWeek, string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes monthly()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes monthlyOn(int $dayOfMonth = 1, string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes twiceMonthly(int $first = 1, int $second = 16, string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes lastDayOfMonth(string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes daysOfMonth(array|int ...$days)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes quarterly()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes quarterlyOn(int $dayOfQuarter = 1, string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes yearly()\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes yearlyOn(int $month = 1, int|string $dayOfMonth = 1, string $time = '0:0')\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes days(mixed $days)\n * @method static \\Illuminate\\Console\\Scheduling\\PendingEventAttributes timezone(\\UnitEnum|\\DateTimeZone|string $timezone)\n *\n * @see \\Illuminate\\Console\\Scheduling\\Schedule\n */\nclass Schedule extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return ConsoleSchedule::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Schema.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static void defaultStringLength(int $length)\n * @method static void defaultTimePrecision(int|null $precision)\n * @method static void defaultMorphKeyType(string $type)\n * @method static void morphUsingUuids()\n * @method static void morphUsingUlids()\n * @method static bool createDatabase(string $name)\n * @method static bool dropDatabaseIfExists(string $name)\n * @method static array getSchemas()\n * @method static bool hasTable(string $table)\n * @method static bool hasView(string $view)\n * @method static array getTables(string|string[]|null $schema = null)\n * @method static array getTableListing(string|string[]|null $schema = null, bool $schemaQualified = true)\n * @method static array getViews(string|string[]|null $schema = null)\n * @method static array getTypes(string|string[]|null $schema = null)\n * @method static bool hasColumn(string $table, string $column)\n * @method static bool hasColumns(string $table, array $columns)\n * @method static void whenTableHasColumn(string $table, string $column, \\Closure $callback)\n * @method static void whenTableDoesntHaveColumn(string $table, string $column, \\Closure $callback)\n * @method static void whenTableHasIndex(string $table, string|array $index, \\Closure $callback, string|null $type = null)\n * @method static void whenTableDoesntHaveIndex(string $table, string|array $index, \\Closure $callback, string|null $type = null)\n * @method static string getColumnType(string $table, string $column, bool $fullDefinition = false)\n * @method static array getColumnListing(string $table)\n * @method static array getColumns(string $table)\n * @method static array getIndexes(string $table)\n * @method static array getIndexListing(string $table)\n * @method static bool hasIndex(string $table, string|array $index, string|null $type = null)\n * @method static array getForeignKeys(string $table)\n * @method static void table(string $table, \\Closure $callback)\n * @method static void create(string $table, \\Closure $callback)\n * @method static void drop(string $table)\n * @method static void dropIfExists(string $table)\n * @method static void dropColumns(string $table, string|array $columns)\n * @method static void dropAllTables()\n * @method static void dropAllViews()\n * @method static void dropAllTypes()\n * @method static void rename(string $from, string $to)\n * @method static bool enableForeignKeyConstraints()\n * @method static bool disableForeignKeyConstraints()\n * @method static mixed withoutForeignKeyConstraints(\\Closure $callback)\n * @method static void ensureVectorExtensionExists(string|null $schema = null)\n * @method static void ensureExtensionExists(string $name, string|null $schema = null)\n * @method static string[]|null getCurrentSchemaListing()\n * @method static string|null getCurrentSchemaName()\n * @method static array parseSchemaAndTable(string $reference, string|bool|null $withDefaultSchema = null)\n * @method static \\Illuminate\\Database\\Connection getConnection()\n * @method static void blueprintResolver(\\Closure $resolver)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Database\\Schema\\Builder\n */\nclass Schema extends Facade\n{\n    /**\n     * Indicates if the resolved facade should be cached.\n     *\n     * @var bool\n     */\n    protected static $cached = false;\n\n    /**\n     * Get a schema builder instance for a connection.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    public static function connection($name)\n    {\n        return static::$app['db']->connection($name)->getSchemaBuilder();\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'db.schema';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Session.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static bool shouldBlock()\n * @method static string|null blockDriver()\n * @method static int defaultRouteBlockLockSeconds()\n * @method static int defaultRouteBlockWaitSeconds()\n * @method static array getSessionConfig()\n * @method static string|null getDefaultDriver()\n * @method static void setDefaultDriver(string $name)\n * @method static mixed driver(string|null $driver = null)\n * @method static \\Illuminate\\Session\\SessionManager extend(string $driver, \\Closure $callback)\n * @method static array getDrivers()\n * @method static \\Illuminate\\Contracts\\Container\\Container getContainer()\n * @method static \\Illuminate\\Session\\SessionManager setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static \\Illuminate\\Session\\SessionManager forgetDrivers()\n * @method static bool start()\n * @method static void save()\n * @method static void ageFlashData()\n * @method static array all()\n * @method static array only(array $keys)\n * @method static array except(array $keys)\n * @method static bool exists(\\UnitEnum|string|array $key)\n * @method static bool missing(\\UnitEnum|string|array $key)\n * @method static bool has(\\UnitEnum|string|array $key)\n * @method static bool hasAny(\\UnitEnum|string|array $key)\n * @method static mixed get(\\UnitEnum|string $key, mixed $default = null)\n * @method static mixed pull(\\UnitEnum|string $key, mixed $default = null)\n * @method static bool hasOldInput(string|null $key = null)\n * @method static mixed getOldInput(string|null $key = null, mixed $default = null)\n * @method static void replace(array $attributes)\n * @method static void put(\\UnitEnum|string|array $key, mixed $value = null)\n * @method static mixed remember(\\UnitEnum|string $key, \\Closure $callback)\n * @method static void push(\\UnitEnum|string $key, mixed $value)\n * @method static mixed increment(\\UnitEnum|string $key, int $amount = 1)\n * @method static int decrement(\\UnitEnum|string $key, int $amount = 1)\n * @method static void flash(\\UnitEnum|string $key, mixed $value = true)\n * @method static void now(\\UnitEnum|string $key, mixed $value)\n * @method static void reflash()\n * @method static void keep(mixed $keys = null)\n * @method static void flashInput(array $value)\n * @method static \\Illuminate\\Contracts\\Cache\\Repository cache()\n * @method static mixed remove(\\UnitEnum|string $key)\n * @method static void forget(\\UnitEnum|string|array $keys)\n * @method static void flush()\n * @method static bool invalidate()\n * @method static bool regenerate(bool $destroy = false)\n * @method static bool migrate(bool $destroy = false)\n * @method static bool isStarted()\n * @method static string getName()\n * @method static void setName(string $name)\n * @method static string id()\n * @method static string getId()\n * @method static void setId(string|null $id)\n * @method static bool isValidId(string|null $id)\n * @method static void setExists(bool $value)\n * @method static string token()\n * @method static void regenerateToken()\n * @method static bool hasPreviousUri()\n * @method static \\Illuminate\\Support\\Uri previousUri()\n * @method static string|null previousUrl()\n * @method static void setPreviousUrl(string $url)\n * @method static string|null previousRoute()\n * @method static void setPreviousRoute(string|null $route)\n * @method static void passwordConfirmed()\n * @method static \\SessionHandlerInterface getHandler()\n * @method static \\SessionHandlerInterface setHandler(\\SessionHandlerInterface $handler)\n * @method static bool handlerNeedsRequest()\n * @method static void setRequestOnHandler(\\Illuminate\\Http\\Request $request)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Session\\SessionManager\n */\nclass Session extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'session';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Storage.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\nuse Illuminate\\Filesystem\\Filesystem;\n\nuse function Illuminate\\Support\\enum_value;\n\n/**\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem drive(string|null $name = null)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem disk(\\UnitEnum|string|null $name = null)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Cloud cloud()\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem build(string|array $config)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem createLocalDriver(array $config, string $name = 'local')\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem createFtpDriver(array $config)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem createSftpDriver(array $config)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Cloud createS3Driver(array $config)\n * @method static \\Illuminate\\Contracts\\Filesystem\\Filesystem createScopedDriver(array $config)\n * @method static \\Illuminate\\Filesystem\\FilesystemManager set(string $name, mixed $disk)\n * @method static string getDefaultDriver()\n * @method static string getDefaultCloudDriver()\n * @method static \\Illuminate\\Filesystem\\FilesystemManager forgetDisk(array|string $disk)\n * @method static void purge(string|null $name = null)\n * @method static \\Illuminate\\Filesystem\\FilesystemManager extend(string $driver, \\Closure $callback)\n * @method static \\Illuminate\\Filesystem\\FilesystemManager setApplication(\\Illuminate\\Contracts\\Foundation\\Application $app)\n * @method static string path(string $path)\n * @method static bool exists(string $path)\n * @method static string|null get(string $path)\n * @method static resource|null readStream(string $path)\n * @method static bool put(string $path, \\Psr\\Http\\Message\\StreamInterface|\\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|resource $contents, mixed $options = [])\n * @method static string|false putFile(\\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string $path, \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null $file = null, mixed $options = [])\n * @method static string|false putFileAs(\\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string $path, \\Illuminate\\Http\\File|\\Illuminate\\Http\\UploadedFile|string|array|null $file, string|array|null $name = null, mixed $options = [])\n * @method static bool writeStream(string $path, resource $resource, array $options = [])\n * @method static string getVisibility(string $path)\n * @method static bool setVisibility(string $path, string $visibility)\n * @method static bool prepend(string $path, string $data)\n * @method static bool append(string $path, string $data)\n * @method static bool delete(string|array $paths)\n * @method static bool copy(string $from, string $to)\n * @method static bool move(string $from, string $to)\n * @method static int size(string $path)\n * @method static int lastModified(string $path)\n * @method static array files(string|null $directory = null, bool $recursive = false)\n * @method static array allFiles(string|null $directory = null)\n * @method static array directories(string|null $directory = null, bool $recursive = false)\n * @method static array allDirectories(string|null $directory = null)\n * @method static bool makeDirectory(string $path)\n * @method static bool deleteDirectory(string $directory)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter assertExists(string|array $path, string|null $content = null)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter assertCount(string $path, int $count, bool $recursive = false)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter assertMissing(string|array $path)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter assertDirectoryEmpty(string $path)\n * @method static bool missing(string $path)\n * @method static bool fileExists(string $path)\n * @method static bool fileMissing(string $path)\n * @method static bool directoryExists(string $path)\n * @method static bool directoryMissing(string $path)\n * @method static array|null json(string $path, int $flags = 0)\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse response(string $path, string|null $name = null, array $headers = [], string|null $disposition = 'inline')\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse serve(\\Illuminate\\Http\\Request $request, string $path, string|null $name = null, array $headers = [])\n * @method static \\Symfony\\Component\\HttpFoundation\\StreamedResponse download(string $path, string|null $name = null, array $headers = [])\n * @method static string|false checksum(string $path, array $options = [])\n * @method static string|false mimeType(string $path)\n * @method static string url(string $path)\n * @method static bool providesTemporaryUrls()\n * @method static bool providesTemporaryUploadUrls()\n * @method static string temporaryUrl(string $path, \\DateTimeInterface $expiration, array $options = [])\n * @method static array temporaryUploadUrl(string $path, \\DateTimeInterface $expiration, array $options = [])\n * @method static \\League\\Flysystem\\FilesystemOperator getDriver()\n * @method static \\League\\Flysystem\\FilesystemAdapter getAdapter()\n * @method static array getConfig()\n * @method static void serveUsing(\\Closure $callback)\n * @method static void buildTemporaryUrlsUsing(\\Closure $callback)\n * @method static void buildTemporaryUploadUrlsUsing(\\Closure $callback)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter|mixed when(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static \\Illuminate\\Filesystem\\FilesystemAdapter|mixed unless(\\Closure|mixed|null $value = null, callable|null $callback = null, callable|null $default = null)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static mixed macroCall(string $method, array $parameters)\n * @method static bool has(string $location)\n * @method static string read(string $location)\n * @method static \\League\\Flysystem\\DirectoryListing listContents(string $location, bool $deep = false)\n * @method static int fileSize(string $path)\n * @method static string visibility(string $path)\n * @method static void write(string $location, string $contents, array $config = [])\n * @method static void createDirectory(string $location, array $config = [])\n *\n * @see \\Illuminate\\Filesystem\\FilesystemManager\n */\nclass Storage extends Facade\n{\n    /**\n     * Replace the given disk with a local testing disk.\n     *\n     * @param  \\UnitEnum|string|null  $disk\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public static function fake($disk = null, array $config = [])\n    {\n        $root = self::getRootPath($disk = enum_value($disk) ?: static::$app['config']->get('filesystems.default'));\n\n        if ($token = ParallelTesting::token()) {\n            $root = \"{$root}_test_{$token}\";\n        }\n\n        (new Filesystem)->cleanDirectory($root);\n\n        static::set($disk, $fake = static::createLocalDriver(\n            self::buildDiskConfiguration($disk, $config, root: $root)\n        ));\n\n        return tap($fake, function ($fake) {\n            $fake->buildTemporaryUrlsUsing(function ($path, $expiration) {\n                return URL::to($path.'?expiration='.$expiration->getTimestamp());\n            });\n\n            $fake->buildTemporaryUploadUrlsUsing(function ($path, $expiration) {\n                return ['url' => URL::to($path.'?expiration='.$expiration->getTimestamp()), 'headers' => []];\n            });\n        });\n    }\n\n    /**\n     * Replace the given disk with a persistent local testing disk.\n     *\n     * @param  \\UnitEnum|string|null  $disk\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     */\n    public static function persistentFake($disk = null, array $config = [])\n    {\n        $disk = enum_value($disk) ?: static::$app['config']->get('filesystems.default');\n\n        static::set($disk, $fake = static::createLocalDriver(\n            self::buildDiskConfiguration($disk, $config, root: self::getRootPath($disk))\n        ));\n\n        return $fake;\n    }\n\n    /**\n     * Get the root path of the given disk.\n     *\n     * @param  string  $disk\n     * @return string\n     */\n    protected static function getRootPath(string $disk): string\n    {\n        return storage_path('framework/testing/disks/'.$disk);\n    }\n\n    /**\n     * Assemble the configuration of the given disk.\n     *\n     * @param  string  $disk\n     * @param  array  $config\n     * @param  string  $root\n     * @return array\n     */\n    protected static function buildDiskConfiguration(string $disk, array $config, string $root): array\n    {\n        $originalConfig = static::$app['config'][\"filesystems.disks.{$disk}\"] ?? [];\n\n        return array_merge([\n            'throw' => $originalConfig['throw'] ?? false],\n            $config,\n            ['root' => $root]\n        );\n    }\n\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'filesystem';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/URL.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static string full()\n * @method static string current()\n * @method static string previous(mixed $fallback = false)\n * @method static string previousPath(mixed $fallback = false)\n * @method static string to(string $path, mixed $extra = [], bool|null $secure = null)\n * @method static string query(string $path, array $query = [], mixed $extra = [], bool|null $secure = null)\n * @method static string secure(string $path, array $parameters = [])\n * @method static string asset(string $path, bool|null $secure = null)\n * @method static string secureAsset(string $path)\n * @method static string assetFrom(string $root, string $path, bool|null $secure = null)\n * @method static string formatScheme(bool|null $secure = null)\n * @method static string signedRoute(\\BackedEnum|string $name, mixed $parameters = [], \\DateTimeInterface|\\DateInterval|int|null $expiration = null, bool $absolute = true)\n * @method static string temporarySignedRoute(\\BackedEnum|string $name, \\DateTimeInterface|\\DateInterval|int $expiration, array $parameters = [], bool $absolute = true)\n * @method static bool hasValidSignature(\\Illuminate\\Http\\Request $request, bool $absolute = true, \\Closure|array $ignoreQuery = [])\n * @method static bool hasValidRelativeSignature(\\Illuminate\\Http\\Request $request, \\Closure|array $ignoreQuery = [])\n * @method static bool hasCorrectSignature(\\Illuminate\\Http\\Request $request, bool $absolute = true, \\Closure|array $ignoreQuery = [])\n * @method static bool signatureHasNotExpired(\\Illuminate\\Http\\Request $request)\n * @method static string route(\\BackedEnum|string $name, mixed $parameters = [], bool $absolute = true)\n * @method static string toRoute(\\Illuminate\\Routing\\Route $route, mixed $parameters, bool $absolute)\n * @method static string action(string|array $action, mixed $parameters = [], bool $absolute = true)\n * @method static array formatParameters(mixed $parameters)\n * @method static string formatRoot(string $scheme, string|null $root = null)\n * @method static string format(string $root, string $path, \\Illuminate\\Routing\\Route|null $route = null)\n * @method static bool isValidUrl(string $path)\n * @method static void defaults(array $defaults)\n * @method static array getDefaultParameters()\n * @method static void forceScheme(string|null $scheme)\n * @method static void forceHttps(bool $force = true)\n * @method static void useOrigin(string|null $root)\n * @method static void useAssetOrigin(string|null $root)\n * @method static \\Illuminate\\Routing\\UrlGenerator formatHostUsing(\\Closure $callback)\n * @method static \\Illuminate\\Routing\\UrlGenerator formatPathUsing(\\Closure $callback)\n * @method static \\Closure pathFormatter()\n * @method static \\Illuminate\\Http\\Request getRequest()\n * @method static void setRequest(\\Illuminate\\Http\\Request $request)\n * @method static \\Illuminate\\Routing\\UrlGenerator setRoutes(\\Illuminate\\Routing\\RouteCollectionInterface $routes)\n * @method static \\Illuminate\\Routing\\UrlGenerator setSessionResolver(callable $sessionResolver)\n * @method static \\Illuminate\\Routing\\UrlGenerator setKeyResolver(callable $keyResolver)\n * @method static \\Illuminate\\Routing\\UrlGenerator withKeyResolver(callable $keyResolver)\n * @method static \\Illuminate\\Routing\\UrlGenerator resolveMissingNamedRoutesUsing(callable $missingNamedRouteResolver)\n * @method static string getRootControllerNamespace()\n * @method static \\Illuminate\\Routing\\UrlGenerator setRootControllerNamespace(string $rootNamespace)\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Routing\\UrlGenerator\n */\nclass URL extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'url';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Validator.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Validation\\Validator make(array $data, array $rules, array $messages = [], array $attributes = [])\n * @method static array validate(array $data, array $rules, array $messages = [], array $attributes = [])\n * @method static void extend(string $rule, \\Closure|string $extension, string|null $message = null)\n * @method static void extendImplicit(string $rule, \\Closure|string $extension, string|null $message = null)\n * @method static void extendDependent(string $rule, \\Closure|string $extension, string|null $message = null)\n * @method static void replacer(string $rule, \\Closure|string $replacer)\n * @method static void includeUnvalidatedArrayKeys()\n * @method static void excludeUnvalidatedArrayKeys()\n * @method static void resolver(\\Closure $resolver)\n * @method static \\Illuminate\\Contracts\\Translation\\Translator getTranslator()\n * @method static \\Illuminate\\Validation\\PresenceVerifierInterface getPresenceVerifier()\n * @method static void setPresenceVerifier(\\Illuminate\\Validation\\PresenceVerifierInterface $presenceVerifier)\n * @method static \\Illuminate\\Contracts\\Container\\Container|null getContainer()\n * @method static \\Illuminate\\Validation\\Factory setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n *\n * @see \\Illuminate\\Validation\\Factory\n */\nclass Validator extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'validator';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/View.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static \\Illuminate\\Contracts\\View\\View file(string $path, \\Illuminate\\Contracts\\Support\\Arrayable|array $data = [], array $mergeData = [])\n * @method static \\Illuminate\\Contracts\\View\\View make(string $view, \\Illuminate\\Contracts\\Support\\Arrayable|array $data = [], array $mergeData = [])\n * @method static \\Illuminate\\Contracts\\View\\View first(array $views, \\Illuminate\\Contracts\\Support\\Arrayable|array $data = [], array $mergeData = [])\n * @method static string renderWhen(bool $condition, string $view, \\Illuminate\\Contracts\\Support\\Arrayable|array $data = [], array $mergeData = [])\n * @method static string renderUnless(bool $condition, string $view, \\Illuminate\\Contracts\\Support\\Arrayable|array $data = [], array $mergeData = [])\n * @method static string renderEach(string $view, array $data, string $iterator, string $empty = 'raw|')\n * @method static bool exists(string $view)\n * @method static \\Illuminate\\Contracts\\View\\Engine getEngineFromPath(string $path)\n * @method static mixed share(array|string $key, mixed $value = null)\n * @method static void incrementRender()\n * @method static void decrementRender()\n * @method static bool doneRendering()\n * @method static bool hasRenderedOnce(string $id)\n * @method static void markAsRenderedOnce(string $id)\n * @method static void addLocation(string $location)\n * @method static void prependLocation(string $location)\n * @method static \\Illuminate\\View\\Factory addNamespace(string $namespace, string|array $hints)\n * @method static \\Illuminate\\View\\Factory prependNamespace(string $namespace, string|array $hints)\n * @method static \\Illuminate\\View\\Factory replaceNamespace(string $namespace, string|array $hints)\n * @method static void addExtension(string $extension, string $engine, \\Closure|null $resolver = null)\n * @method static void flushState()\n * @method static void flushStateIfDoneRendering()\n * @method static array getExtensions()\n * @method static \\Illuminate\\View\\Engines\\EngineResolver getEngineResolver()\n * @method static \\Illuminate\\View\\ViewFinderInterface getFinder()\n * @method static void setFinder(\\Illuminate\\View\\ViewFinderInterface $finder)\n * @method static void flushFinderCache()\n * @method static \\Illuminate\\Contracts\\Events\\Dispatcher getDispatcher()\n * @method static void setDispatcher(\\Illuminate\\Contracts\\Events\\Dispatcher $events)\n * @method static \\Illuminate\\Contracts\\Container\\Container getContainer()\n * @method static void setContainer(\\Illuminate\\Contracts\\Container\\Container $container)\n * @method static mixed shared(string $key, mixed $default = null)\n * @method static array getShared()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n * @method static void startComponent(\\Illuminate\\Contracts\\View\\View|\\Illuminate\\Contracts\\Support\\Htmlable|\\Closure|string $view, array $data = [])\n * @method static void startComponentFirst(array $names, array $data = [])\n * @method static string renderComponent()\n * @method static mixed getConsumableComponentData(string $key, mixed $default = null)\n * @method static void slot(string $name, string|null $content = null, array $attributes = [])\n * @method static void endSlot()\n * @method static array creator(array|string $views, \\Closure|string $callback)\n * @method static array composers(array $composers)\n * @method static array composer(array|string $views, \\Closure|string $callback)\n * @method static void callComposer(\\Illuminate\\Contracts\\View\\View $view)\n * @method static void callCreator(\\Illuminate\\Contracts\\View\\View $view)\n * @method static void startFragment(string $fragment)\n * @method static string stopFragment()\n * @method static mixed getFragment(string $name, string|null $default = null)\n * @method static array getFragments()\n * @method static void flushFragments()\n * @method static void startSection(string $section, string|null $content = null)\n * @method static void inject(string $section, string $content)\n * @method static string yieldSection()\n * @method static string stopSection(bool $overwrite = false)\n * @method static string appendSection()\n * @method static string yieldContent(string $section, string $default = '')\n * @method static string parentPlaceholder(string $section = '')\n * @method static bool hasSection(string $name)\n * @method static bool sectionMissing(string $name)\n * @method static mixed getSection(string $name, string|null $default = null)\n * @method static array getSections()\n * @method static void flushSections()\n * @method static void addLoop(\\Countable|array $data)\n * @method static void incrementLoopIndices()\n * @method static void popLoop()\n * @method static \\stdClass|null getLastLoop()\n * @method static array getLoopStack()\n * @method static void startPush(string $section, string $content = '')\n * @method static string stopPush()\n * @method static void startPrepend(string $section, string $content = '')\n * @method static string stopPrepend()\n * @method static string yieldPushContent(string $section, string $default = '')\n * @method static bool isStackEmpty(string $section)\n * @method static void flushStacks()\n * @method static void startTranslation(array $replacements = [])\n * @method static string renderTranslation()\n *\n * @see \\Illuminate\\View\\Factory\n */\nclass View extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'view';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Facades/Vite.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Facades;\n\n/**\n * @method static array preloadedAssets()\n * @method static string|null cspNonce()\n * @method static string useCspNonce(string|null $nonce = null)\n * @method static \\Illuminate\\Foundation\\Vite useIntegrityKey(string|false $key)\n * @method static \\Illuminate\\Foundation\\Vite withEntryPoints(array $entryPoints)\n * @method static \\Illuminate\\Foundation\\Vite mergeEntryPoints(array $entryPoints)\n * @method static \\Illuminate\\Foundation\\Vite useManifestFilename(string $filename)\n * @method static \\Illuminate\\Foundation\\Vite createAssetPathsUsing(callable|null $resolver)\n * @method static string hotFile()\n * @method static \\Illuminate\\Foundation\\Vite useHotFile(string $path)\n * @method static \\Illuminate\\Foundation\\Vite useBuildDirectory(string $path)\n * @method static \\Illuminate\\Foundation\\Vite useScriptTagAttributes(callable|array $attributes)\n * @method static \\Illuminate\\Foundation\\Vite useStyleTagAttributes(callable|array $attributes)\n * @method static \\Illuminate\\Foundation\\Vite usePreloadTagAttributes(callable|array|false $attributes)\n * @method static \\Illuminate\\Foundation\\Vite prefetch(int|null $concurrency = null, string $event = 'load')\n * @method static \\Illuminate\\Foundation\\Vite useWaterfallPrefetching(int|null $concurrency = null)\n * @method static \\Illuminate\\Foundation\\Vite useAggressivePrefetching()\n * @method static \\Illuminate\\Foundation\\Vite usePrefetchStrategy(string|null $strategy, array $config = [])\n * @method static \\Illuminate\\Support\\HtmlString|void reactRefresh()\n * @method static string asset(string $asset, string|null $buildDirectory = null)\n * @method static string content(string $asset, string|null $buildDirectory = null)\n * @method static string|null manifestHash(string|null $buildDirectory = null)\n * @method static bool isRunningHot()\n * @method static string toHtml()\n * @method static void flush()\n * @method static void macro(string $name, object|callable $macro)\n * @method static void mixin(object $mixin, bool $replace = true)\n * @method static bool hasMacro(string $name)\n * @method static void flushMacros()\n *\n * @see \\Illuminate\\Foundation\\Vite\n */\nclass Vite extends Facade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return \\Illuminate\\Foundation\\Vite::class;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Fluent.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\InteractsWithData;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse IteratorAggregate;\nuse JsonSerializable;\nuse Traversable;\n\n/**\n * @template TKey of array-key\n * @template TValue\n *\n * @implements \\Illuminate\\Contracts\\Support\\Arrayable<TKey, TValue>\n * @implements \\ArrayAccess<TKey, TValue>\n */\nclass Fluent implements Arrayable, ArrayAccess, IteratorAggregate, Jsonable, JsonSerializable\n{\n    use Conditionable, InteractsWithData, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * All of the attributes set on the fluent instance.\n     *\n     * @var array<TKey, TValue>\n     */\n    protected $attributes = [];\n\n    /**\n     * Create a new fluent instance.\n     *\n     * @param  iterable<TKey, TValue>  $attributes\n     */\n    public function __construct($attributes = [])\n    {\n        $this->fill($attributes);\n    }\n\n    /**\n     * Create a new fluent instance.\n     *\n     * @param  iterable<TKey, TValue>  $attributes\n     * @return static\n     */\n    public static function make($attributes = [])\n    {\n        return new static($attributes);\n    }\n\n    /**\n     * Get an attribute from the fluent instance using \"dot\" notation.\n     *\n     * @template TGetDefault\n     *\n     * @param  TKey  $key\n     * @param  TGetDefault|(\\Closure(): TGetDefault)  $default\n     * @return TValue|TGetDefault\n     */\n    public function get($key, $default = null)\n    {\n        return data_get($this->attributes, $key, $default);\n    }\n\n    /**\n     * Set an attribute on the fluent instance using \"dot\" notation.\n     *\n     * @param  TKey  $key\n     * @param  TValue  $value\n     * @return $this\n     */\n    public function set($key, $value)\n    {\n        data_set($this->attributes, $key, $value);\n\n        return $this;\n    }\n\n    /**\n     * Fill the fluent instance with an array of attributes.\n     *\n     * @param  iterable<TKey, TValue>  $attributes\n     * @return $this\n     */\n    public function fill($attributes)\n    {\n        foreach ($attributes as $key => $value) {\n            $this->attributes[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get an attribute from the fluent instance.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function value($key, $default = null)\n    {\n        if (array_key_exists($key, $this->attributes)) {\n            return $this->attributes[$key];\n        }\n\n        return value($default);\n    }\n\n    /**\n     * Get the value of the given key as a new Fluent instance.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return static\n     */\n    public function scope($key, $default = null)\n    {\n        return new static(\n            (array) $this->get($key, $default)\n        );\n    }\n\n    /**\n     * Get all of the attributes from the fluent instance.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function all($keys = null)\n    {\n        $data = $this->data();\n\n        if (! $keys) {\n            return $data;\n        }\n\n        $results = [];\n\n        foreach (is_array($keys) ? $keys : func_get_args() as $key) {\n            Arr::set($results, $key, Arr::get($data, $key));\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get data from the fluent instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function data($key = null, $default = null)\n    {\n        return $this->get($key, $default);\n    }\n\n    /**\n     * Get the attributes from the fluent instance.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function getAttributes()\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Convert the fluent instance to an array.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function toArray()\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array<TKey, TValue>\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Convert the fluent instance to JSON.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Convert the fluent instance to pretty print formatted JSON.\n     *\n     * @params int $options\n     *\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n\n    /**\n     * Determine if the fluent instance is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty(): bool\n    {\n        return empty($this->attributes);\n    }\n\n    /**\n     * Determine if the fluent instance is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty(): bool\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  TKey  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->attributes[$offset]);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  TKey  $offset\n     * @return TValue|null\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->value($offset);\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  TKey  $offset\n     * @param  TValue  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->attributes[$offset] = $value;\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  TKey  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->attributes[$offset]);\n    }\n\n    /**\n     * Get an iterator for the attributes.\n     *\n     * @return ArrayIterator<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->attributes);\n    }\n\n    /**\n     * Handle dynamic calls to the fluent instance to set attributes.\n     *\n     * @param  TKey  $method\n     * @param  array{0: ?TValue}  $parameters\n     * @return $this\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        $this->attributes[$method] = count($parameters) > 0 ? array_first($parameters) : true;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically retrieve the value of an attribute.\n     *\n     * @param  TKey  $key\n     * @return TValue|null\n     */\n    public function __get($key)\n    {\n        return $this->value($key);\n    }\n\n    /**\n     * Dynamically set the value of an attribute.\n     *\n     * @param  TKey  $key\n     * @param  TValue  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this->offsetSet($key, $value);\n    }\n\n    /**\n     * Dynamically check if an attribute is set.\n     *\n     * @param  TKey  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return $this->offsetExists($key);\n    }\n\n    /**\n     * Dynamically unset an attribute.\n     *\n     * @param  TKey  $key\n     * @return void\n     */\n    public function __unset($key)\n    {\n        $this->offsetUnset($key);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/HigherOrderTapProxy.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nclass HigherOrderTapProxy\n{\n    /**\n     * The target being tapped.\n     *\n     * @var mixed\n     */\n    public $target;\n\n    /**\n     * Create a new tap proxy instance.\n     *\n     * @param  mixed  $target\n     */\n    public function __construct($target)\n    {\n        $this->target = $target;\n    }\n\n    /**\n     * Dynamically pass method calls to the target.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        $this->target->{$method}(...$parameters);\n\n        return $this->target;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/HtmlString.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Stringable;\n\nclass HtmlString implements Htmlable, Stringable\n{\n    /**\n     * The HTML string.\n     *\n     * @var string\n     */\n    protected $html;\n\n    /**\n     * Create a new HTML string instance.\n     *\n     * @param  string  $html\n     */\n    public function __construct($html = '')\n    {\n        $this->html = $html;\n    }\n\n    /**\n     * Get the HTML string.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->html;\n    }\n\n    /**\n     * Determine if the given HTML string is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return ($this->html ?? '') === '';\n    }\n\n    /**\n     * Determine if the given HTML string is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Get the HTML string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->toHtml() ?? '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/InteractsWithTime.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Carbon\\CarbonInterval;\nuse DateInterval;\nuse DateTimeInterface;\n\ntrait InteractsWithTime\n{\n    /**\n     * Get the number of seconds until the given DateTime.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @return int\n     */\n    protected function secondsUntil($delay)\n    {\n        $delay = $this->parseDateInterval($delay);\n\n        return $delay instanceof DateTimeInterface\n            ? max(0, $delay->getTimestamp() - $this->currentTime())\n            : (int) $delay;\n    }\n\n    /**\n     * Get the \"available at\" UNIX timestamp.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @return int\n     */\n    protected function availableAt($delay = 0)\n    {\n        $delay = $this->parseDateInterval($delay);\n\n        return $delay instanceof DateTimeInterface\n            ? $delay->getTimestamp()\n            : Carbon::now()->addSeconds($delay)->getTimestamp();\n    }\n\n    /**\n     * If the given value is an interval, convert it to a DateTime instance.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @return \\DateTimeInterface|int\n     */\n    protected function parseDateInterval($delay)\n    {\n        if ($delay instanceof DateInterval) {\n            $delay = Carbon::now()->add($delay);\n        }\n\n        return $delay;\n    }\n\n    /**\n     * Get the current system time as a UNIX timestamp.\n     *\n     * @return int\n     */\n    protected function currentTime()\n    {\n        return Carbon::now()->getTimestamp();\n    }\n\n    /**\n     * Given a start time, format the total run time for human readability.\n     *\n     * @param  float  $startTime\n     * @param  float|null  $endTime\n     * @return string\n     */\n    protected function runTimeForHumans($startTime, $endTime = null)\n    {\n        $endTime ??= microtime(true);\n\n        $runTime = ($endTime - $startTime) * 1000;\n\n        return $runTime > 1000\n            ? CarbonInterval::milliseconds($runTime)->cascade()->forHumans(short: true)\n            : number_format($runTime, 2).'ms';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Js.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse JsonSerializable;\nuse Stringable;\nuse UnitEnum;\n\nclass Js implements Htmlable, Stringable\n{\n    /**\n     * The JavaScript string.\n     *\n     * @var string\n     */\n    protected $js;\n\n    /**\n     * Flags that should be used when encoding to JSON.\n     *\n     * @var int\n     */\n    protected const REQUIRED_FLAGS = 0\n        | JSON_HEX_TAG\n        | JSON_HEX_APOS\n        | JSON_HEX_AMP\n        | JSON_HEX_QUOT\n        | JSON_UNESCAPED_UNICODE\n        | JSON_THROW_ON_ERROR;\n\n    /**\n     * Create a new class instance.\n     *\n     * @param  mixed  $data\n     * @param  int|null  $flags\n     * @param  int  $depth\n     *\n     * @throws \\JsonException\n     */\n    public function __construct($data, $flags = 0, $depth = 512)\n    {\n        $this->js = $this->convertDataToJavaScriptExpression($data, $flags, $depth);\n    }\n\n    /**\n     * Create a new JavaScript string from the given data.\n     *\n     * @param  mixed  $data\n     * @param  int  $flags\n     * @param  int  $depth\n     * @return static\n     *\n     * @throws \\JsonException\n     */\n    public static function from($data, $flags = 0, $depth = 512)\n    {\n        return new static($data, $flags, $depth);\n    }\n\n    /**\n     * Convert the given data to a JavaScript expression.\n     *\n     * @param  mixed  $data\n     * @param  int  $flags\n     * @param  int  $depth\n     * @return string\n     *\n     * @throws \\JsonException\n     */\n    protected function convertDataToJavaScriptExpression($data, $flags = 0, $depth = 512)\n    {\n        if ($data instanceof self) {\n            return $data->toHtml();\n        }\n\n        if ($data instanceof Htmlable &&\n            ! $data instanceof Arrayable &&\n            ! $data instanceof Jsonable &&\n            ! $data instanceof JsonSerializable) {\n            $data = $data->toHtml();\n        }\n\n        if ($data instanceof UnitEnum) {\n            $data = enum_value($data);\n        }\n\n        $json = static::encode($data, $flags, $depth);\n\n        if (is_string($data)) {\n            return \"'\".substr($json, 1, -1).\"'\";\n        }\n\n        return $this->convertJsonToJavaScriptExpression($json, $flags);\n    }\n\n    /**\n     * Encode the given data as JSON.\n     *\n     * Invalid UTF-8 sequences are replaced with � instead of throwing.\n     *\n     * @param  mixed  $data\n     * @param  int  $flags\n     * @param  int  $depth\n     * @return string\n     *\n     * @throws \\JsonException\n     */\n    public static function encode($data, $flags = 0, $depth = 512)\n    {\n        if ($data instanceof Jsonable) {\n            return $data->toJson($flags | static::REQUIRED_FLAGS);\n        }\n\n        if ($data instanceof Arrayable && ! ($data instanceof JsonSerializable)) {\n            $data = $data->toArray();\n        }\n\n        return json_encode($data, $flags | static::REQUIRED_FLAGS | JSON_INVALID_UTF8_SUBSTITUTE, $depth);\n    }\n\n    /**\n     * Convert the given JSON to a JavaScript expression.\n     *\n     * @param  string  $json\n     * @param  int  $flags\n     * @return string\n     *\n     * @throws \\JsonException\n     */\n    protected function convertJsonToJavaScriptExpression($json, $flags = 0)\n    {\n        if ($json === '[]' || $json === '{}') {\n            return $json;\n        }\n\n        if (Str::startsWith($json, ['\"', '{', '['])) {\n            return \"JSON.parse('\".substr(json_encode($json, $flags | static::REQUIRED_FLAGS), 1, -1).\"')\";\n        }\n\n        return $json;\n    }\n\n    /**\n     * Get the string representation of the data for use in HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->js;\n    }\n\n    /**\n     * Get the string representation of the data for use in HTML.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->toHtml();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Support/Lottery.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse RuntimeException;\n\nclass Lottery\n{\n    /**\n     * The number of expected wins.\n     *\n     * @var int|float\n     */\n    protected $chances;\n\n    /**\n     * The number of potential opportunities to win.\n     *\n     * @var int|null\n     */\n    protected $outOf;\n\n    /**\n     * The winning callback.\n     *\n     * @var null|callable\n     */\n    protected $winner;\n\n    /**\n     * The losing callback.\n     *\n     * @var null|callable\n     */\n    protected $loser;\n\n    /**\n     * The factory that should be used to generate results.\n     *\n     * @var callable|null\n     */\n    protected static $resultFactory;\n\n    /**\n     * Create a new Lottery instance.\n     *\n     * @param  int|float  $chances\n     * @param  int<1, max>|null  $outOf\n     *\n     * @throws \\RuntimeException\n     */\n    public function __construct($chances, $outOf = null)\n    {\n        if ($outOf === null && is_float($chances) && $chances > 1) {\n            throw new RuntimeException('Float must not be greater than 1.');\n        }\n\n        if ($outOf !== null && $outOf < 1) {\n            throw new RuntimeException('Lottery \"out of\" value must be greater than or equal to 1.');\n        }\n\n        $this->chances = $chances;\n\n        $this->outOf = $outOf;\n    }\n\n    /**\n     * Create a new Lottery instance.\n     *\n     * @param  int|float  $chances\n     * @param  int|null  $outOf\n     * @return static\n     */\n    public static function odds($chances, $outOf = null)\n    {\n        return new static($chances, $outOf);\n    }\n\n    /**\n     * Set the winner callback.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function winner($callback)\n    {\n        $this->winner = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Set the loser callback.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function loser($callback)\n    {\n        $this->loser = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Run the lottery.\n     *\n     * @param  mixed  ...$args\n     * @return mixed\n     */\n    public function __invoke(...$args)\n    {\n        return $this->runCallback(...$args);\n    }\n\n    /**\n     * Run the lottery.\n     *\n     * @param  null|int  $times\n     * @return mixed\n     */\n    public function choose($times = null)\n    {\n        if ($times === null) {\n            return $this->runCallback();\n        }\n\n        $results = [];\n\n        for ($i = 0; $i < $times; $i++) {\n            $results[] = $this->runCallback();\n        }\n\n        return $results;\n    }\n\n    /**\n     * Run the winner or loser callback, randomly.\n     *\n     * @param  mixed  ...$args\n     * @return callable\n     */\n    protected function runCallback(...$args)\n    {\n        return $this->wins()\n            ? ($this->winner ?? fn () => true)(...$args)\n            : ($this->loser ?? fn () => false)(...$args);\n    }\n\n    /**\n     * Determine if the lottery \"wins\" or \"loses\".\n     *\n     * @return bool\n     */\n    protected function wins()\n    {\n        return static::resultFactory()($this->chances, $this->outOf);\n    }\n\n    /**\n     * The factory that determines the lottery result.\n     *\n     * @return callable\n     */\n    protected static function resultFactory()\n    {\n        return static::$resultFactory ?? fn ($chances, $outOf) => $outOf === null\n            ? random_int(0, PHP_INT_MAX) / PHP_INT_MAX <= $chances\n            : random_int(1, $outOf) <= $chances;\n    }\n\n    /**\n     * Force the lottery to always result in a win.\n     *\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public static function alwaysWin($callback = null)\n    {\n        self::setResultFactory(fn () => true);\n\n        if ($callback === null) {\n            return;\n        }\n\n        $callback();\n\n        static::determineResultNormally();\n    }\n\n    /**\n     * Force the lottery to always result in a lose.\n     *\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public static function alwaysLose($callback = null)\n    {\n        self::setResultFactory(fn () => false);\n\n        if ($callback === null) {\n            return;\n        }\n\n        $callback();\n\n        static::determineResultNormally();\n    }\n\n    /**\n     * Set the sequence that will be used to determine lottery results.\n     *\n     * @param  array  $sequence\n     * @param  callable|null  $whenMissing\n     * @return void\n     */\n    public static function fix($sequence, $whenMissing = null)\n    {\n        static::forceResultWithSequence($sequence, $whenMissing);\n    }\n\n    /**\n     * Set the sequence that will be used to determine lottery results.\n     *\n     * @param  array  $sequence\n     * @param  callable|null  $whenMissing\n     * @return void\n     */\n    public static function forceResultWithSequence($sequence, $whenMissing = null)\n    {\n        $next = 0;\n\n        $whenMissing ??= function ($chances, $outOf) use (&$next) {\n            $factoryCache = static::$resultFactory;\n\n            static::$resultFactory = null;\n\n            $result = static::resultFactory()($chances, $outOf);\n\n            static::$resultFactory = $factoryCache;\n\n            $next++;\n\n            return $result;\n        };\n\n        static::setResultFactory(function ($chances, $outOf) use (&$next, $sequence, $whenMissing) {\n            if (array_key_exists($next, $sequence)) {\n                return $sequence[$next++];\n            }\n\n            return $whenMissing($chances, $outOf);\n        });\n    }\n\n    /**\n     * Indicate that the lottery results should be determined normally.\n     *\n     * @return void\n     */\n    public static function determineResultsNormally()\n    {\n        static::determineResultNormally();\n    }\n\n    /**\n     * Indicate that the lottery results should be determined normally.\n     *\n     * @return void\n     */\n    public static function determineResultNormally()\n    {\n        static::$resultFactory = null;\n    }\n\n    /**\n     * Set the factory that should be used to determine the lottery results.\n     *\n     * @param  callable  $factory\n     * @return void\n     */\n    public static function setResultFactory($factory)\n    {\n        self::$resultFactory = $factory;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Manager.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\Container;\nuse InvalidArgumentException;\n\nabstract class Manager\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The configuration repository instance.\n     *\n     * @var \\Illuminate\\Contracts\\Config\\Repository\n     */\n    protected $config;\n\n    /**\n     * The registered custom driver creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * The array of created \"drivers\".\n     *\n     * @var array\n     */\n    protected $drivers = [];\n\n    /**\n     * Create a new manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n        $this->config = $container->make('config');\n    }\n\n    /**\n     * Get the default driver name.\n     *\n     * @return string|null\n     */\n    abstract public function getDefaultDriver();\n\n    /**\n     * Get a driver instance.\n     *\n     * @param  string|null  $driver\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function driver($driver = null)\n    {\n        $driver = $driver ?: $this->getDefaultDriver();\n\n        if (is_null($driver)) {\n            throw new InvalidArgumentException(sprintf(\n                'Unable to resolve NULL driver for [%s].', static::class\n            ));\n        }\n\n        // If the given driver has not been created before, we will create the instances\n        // here and cache it so we can return it next time very quickly. If there is\n        // already a driver created by this name, we'll just return that instance.\n        return $this->drivers[$driver] ??= $this->createDriver($driver);\n    }\n\n    /**\n     * Create a new driver instance.\n     *\n     * @param  string  $driver\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function createDriver($driver)\n    {\n        // First, we will determine if a custom driver creator exists for the given driver and\n        // if it does not we will check for a creator method for the driver. Custom creator\n        // callbacks allow developers to build their own \"drivers\" easily using Closures.\n        if (isset($this->customCreators[$driver])) {\n            return $this->callCustomCreator($driver);\n        }\n\n        $method = 'create'.Str::studly($driver).'Driver';\n\n        if (method_exists($this, $method)) {\n            return $this->$method();\n        }\n\n        throw new InvalidArgumentException(\"Driver [$driver] not supported.\");\n    }\n\n    /**\n     * Call a custom driver creator.\n     *\n     * @param  string  $driver\n     * @return mixed\n     */\n    protected function callCustomCreator($driver)\n    {\n        return $this->customCreators[$driver]($this->container);\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        $this->customCreators[$driver] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Get all of the created \"drivers\".\n     *\n     * @return array\n     */\n    public function getDrivers()\n    {\n        return $this->drivers;\n    }\n\n    /**\n     * Get the container instance used by the manager.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the container instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n\n    /**\n     * Forget all of the resolved driver instances.\n     *\n     * @return $this\n     */\n    public function forgetDrivers()\n    {\n        $this->drivers = [];\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default driver instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->driver()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/MessageBag.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Contracts\\Support\\MessageBag as MessageBagContract;\nuse Illuminate\\Contracts\\Support\\MessageProvider;\nuse JsonSerializable;\nuse Stringable;\n\nclass MessageBag implements Jsonable, JsonSerializable, MessageBagContract, MessageProvider, Stringable\n{\n    /**\n     * All of the registered messages.\n     *\n     * @var array<string, array<string>>\n     */\n    protected $messages = [];\n\n    /**\n     * Default format for message output.\n     *\n     * @var string\n     */\n    protected $format = ':message';\n\n    /**\n     * Create a new message bag instance.\n     *\n     * @param  array<string, Arrayable|string|array<string>>  $messages\n     */\n    public function __construct(array $messages = [])\n    {\n        foreach ($messages as $key => $value) {\n            $value = $value instanceof Arrayable ? $value->toArray() : (array) $value;\n\n            $this->messages[$key] = array_unique($value);\n        }\n    }\n\n    /**\n     * Get the keys present in the message bag.\n     *\n     * @return array<string>\n     */\n    public function keys()\n    {\n        return array_keys($this->messages);\n    }\n\n    /**\n     * Add a message to the message bag.\n     *\n     * @param  string  $key\n     * @param  string  $message\n     * @return $this\n     */\n    public function add($key, $message)\n    {\n        if ($this->isUnique($key, $message)) {\n            $this->messages[$key][] = $message;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a message to the message bag if the given conditional is \"true\".\n     *\n     * @param  bool  $boolean\n     * @param  string  $key\n     * @param  string  $message\n     * @return $this\n     */\n    public function addIf($boolean, $key, $message)\n    {\n        return $boolean ? $this->add($key, $message) : $this;\n    }\n\n    /**\n     * Determine if a key and message combination already exists.\n     *\n     * @param  string  $key\n     * @param  string  $message\n     * @return bool\n     */\n    protected function isUnique($key, $message)\n    {\n        $messages = (array) $this->messages;\n\n        return ! isset($messages[$key]) || ! in_array($message, $messages[$key]);\n    }\n\n    /**\n     * Merge a new array of messages into the message bag.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array<string, array<string>>  $messages\n     * @return $this\n     */\n    public function merge($messages)\n    {\n        if ($messages instanceof MessageProvider) {\n            $messages = $messages->getMessageBag()->getMessages();\n        }\n\n        $this->messages = array_merge_recursive($this->messages, $messages);\n\n        return $this;\n    }\n\n    /**\n     * Determine if messages exist for all of the given keys.\n     *\n     * @param  array|string|null  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        if ($this->isEmpty()) {\n            return false;\n        }\n\n        if (is_null($key)) {\n            return $this->any();\n        }\n\n        $keys = is_array($key) ? $key : func_get_args();\n\n        foreach ($keys as $key) {\n            if ($this->first($key) === '') {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if messages exist for any of the given keys.\n     *\n     * @param  array|string|null  $keys\n     * @return bool\n     */\n    public function hasAny($keys = [])\n    {\n        if ($this->isEmpty()) {\n            return false;\n        }\n\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        foreach ($keys as $key) {\n            if ($this->has($key)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if messages don't exist for all of the given keys.\n     *\n     * @param  array|string|null  $key\n     * @return bool\n     */\n    public function missing($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        return ! $this->hasAny($keys);\n    }\n\n    /**\n     * Get the first message from the message bag for a given key.\n     *\n     * @param  string|null  $key\n     * @param  string|null  $format\n     * @return string\n     */\n    public function first($key = null, $format = null)\n    {\n        $messages = is_null($key) ? $this->all($format) : $this->get($key, $format);\n\n        $firstMessage = Arr::first($messages, null, '');\n\n        return is_array($firstMessage) ? Arr::first($firstMessage) : $firstMessage;\n    }\n\n    /**\n     * Get all of the messages from the message bag for a given key.\n     *\n     * @param  string  $key\n     * @param  string|null  $format\n     * @return array<string>|array<string, array<string>>\n     */\n    public function get($key, $format = null)\n    {\n        // If the message exists in the message bag, we will transform it and return\n        // the message. Otherwise, we will check if the key is implicit & collect\n        // all the messages that match the given key and output it as an array.\n        if (array_key_exists($key, $this->messages)) {\n            return $this->transform(\n                $this->messages[$key], $this->checkFormat($format), $key\n            );\n        }\n\n        if (str_contains($key, '*')) {\n            return $this->getMessagesForWildcardKey($key, $format);\n        }\n\n        return [];\n    }\n\n    /**\n     * Get the messages for a wildcard key.\n     *\n     * @param  string  $key\n     * @param  string|null  $format\n     * @return array<string, array<string>>\n     */\n    protected function getMessagesForWildcardKey($key, $format)\n    {\n        return (new Collection($this->messages))\n            ->filter(fn ($messages, $messageKey) => Str::is($key, $messageKey))\n            ->map(function ($messages, $messageKey) use ($format) {\n                return $this->transform($messages, $this->checkFormat($format), $messageKey);\n            })\n            ->all();\n    }\n\n    /**\n     * Get all of the messages for every key in the message bag.\n     *\n     * @param  string|null  $format\n     * @return array<string>\n     */\n    public function all($format = null)\n    {\n        $format = $this->checkFormat($format);\n\n        $all = [];\n\n        foreach ($this->messages as $key => $messages) {\n            array_push($all, ...$this->transform($messages, $format, $key));\n        }\n\n        return $all;\n    }\n\n    /**\n     * Get all of the unique messages for every key in the message bag.\n     *\n     * @param  string|null  $format\n     * @return array\n     */\n    public function unique($format = null)\n    {\n        return array_unique($this->all($format));\n    }\n\n    /**\n     * Remove a message from the message bag.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function forget($key)\n    {\n        unset($this->messages[$key]);\n\n        return $this;\n    }\n\n    /**\n     * Format an array of messages.\n     *\n     * @param  array<string>  $messages\n     * @param  string  $format\n     * @param  string  $messageKey\n     * @return array<string>\n     */\n    protected function transform($messages, $format, $messageKey)\n    {\n        if ($format == ':message') {\n            return (array) $messages;\n        }\n\n        return (new Collection((array) $messages))\n            ->map(function ($message) use ($format, $messageKey) {\n                // We will simply spin through the given messages and transform each one\n                // replacing the :message place holder with the real message allowing\n                // the messages to be easily formatted to each developer's desires.\n                return str_replace([':message', ':key'], [$message, $messageKey], $format);\n            })->all();\n    }\n\n    /**\n     * Get the appropriate format based on the given format.\n     *\n     * @param  string  $format\n     * @return string\n     */\n    protected function checkFormat($format)\n    {\n        return $format ?: $this->format;\n    }\n\n    /**\n     * Get the raw messages in the message bag.\n     *\n     * @return array<string, array<string>>\n     */\n    public function messages()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Get the raw messages in the message bag.\n     *\n     * @return array<string, array<string>>\n     */\n    public function getMessages()\n    {\n        return $this->messages();\n    }\n\n    /**\n     * Get the messages for the instance.\n     *\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function getMessageBag()\n    {\n        return $this;\n    }\n\n    /**\n     * Get the default message format.\n     *\n     * @return string\n     */\n    public function getFormat()\n    {\n        return $this->format;\n    }\n\n    /**\n     * Set the default message format.\n     *\n     * @param  string  $format\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function setFormat($format = ':message')\n    {\n        $this->format = $format;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the message bag has any messages.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return ! $this->any();\n    }\n\n    /**\n     * Determine if the message bag has any messages.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return $this->any();\n    }\n\n    /**\n     * Determine if the message bag has any messages.\n     *\n     * @return bool\n     */\n    public function any()\n    {\n        return $this->count() > 0;\n    }\n\n    /**\n     * Get the number of messages in the message bag.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return count($this->messages, COUNT_RECURSIVE) - count($this->messages);\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->getMessages();\n    }\n\n    /**\n     * Convert the object into something JSON serializable.\n     *\n     * @return array\n     */\n    public function jsonSerialize(): array\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * Convert the object to its JSON representation.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toJson($options = 0)\n    {\n        return json_encode($this->jsonSerialize(), $options);\n    }\n\n    /**\n     * Convert the object to pretty print formatted JSON.\n     *\n     * @params int $options\n     *\n     * @return string\n     */\n    public function toPrettyJson(int $options = 0)\n    {\n        return $this->toJson(JSON_PRETTY_PRINT | $options);\n    }\n\n    /**\n     * Convert the message bag to its string representation.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->toJson();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/MultipleInstanceManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse InvalidArgumentException;\nuse RuntimeException;\n\nabstract class MultipleInstanceManager\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * The configuration repository instance.\n     *\n     * @var \\Illuminate\\Contracts\\Config\\Repository\n     */\n    protected $config;\n\n    /**\n     * The array of resolved instances.\n     *\n     * @var array\n     */\n    protected $instances = [];\n\n    /**\n     * The registered custom instance creators.\n     *\n     * @var array\n     */\n    protected $customCreators = [];\n\n    /**\n     * The key name of the \"driver\" equivalent configuration option.\n     *\n     * @var string\n     */\n    protected $driverKey = 'driver';\n\n    /**\n     * Create a new manager instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n        $this->config = $app->make('config');\n    }\n\n    /**\n     * Get the default instance name.\n     *\n     * @return string\n     */\n    abstract public function getDefaultInstance();\n\n    /**\n     * Set the default instance name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    abstract public function setDefaultInstance($name);\n\n    /**\n     * Get the instance specific configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    abstract public function getInstanceConfig($name);\n\n    /**\n     * Get an instance by name.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function instance($name = null)\n    {\n        $name = $name ?: $this->getDefaultInstance();\n\n        return $this->instances[$name] = $this->get($name);\n    }\n\n    /**\n     * Attempt to get an instance from the local cache.\n     *\n     * @param  string  $name\n     * @return mixed\n     */\n    protected function get($name)\n    {\n        return $this->instances[$name] ?? $this->resolve($name);\n    }\n\n    /**\n     * Resolve the given instance.\n     *\n     * @param  string  $name\n     * @return mixed\n     *\n     * @throws \\InvalidArgumentException\n     * @throws \\RuntimeException\n     */\n    protected function resolve($name)\n    {\n        $config = $this->getInstanceConfig($name);\n\n        if (is_null($config)) {\n            throw new InvalidArgumentException(\"Instance [{$name}] is not defined.\");\n        }\n\n        if (! array_key_exists($this->driverKey, $config)) {\n            throw new RuntimeException(\"Instance [{$name}] does not specify a {$this->driverKey}.\");\n        }\n\n        $driverName = $config[$this->driverKey];\n\n        if (isset($this->customCreators[$driverName])) {\n            return $this->callCustomCreator($config);\n        } else {\n            $createMethod = 'create'.ucfirst($driverName).ucfirst($this->driverKey);\n\n            if (method_exists($this, $createMethod)) {\n                return $this->{$createMethod}($config);\n            }\n\n            $createMethod = 'create'.Str::studly($driverName).ucfirst($this->driverKey);\n\n            if (method_exists($this, $createMethod)) {\n                return $this->{$createMethod}($config);\n            }\n\n            throw new InvalidArgumentException(\"Instance {$this->driverKey} [{$config[$this->driverKey]}] is not supported.\");\n        }\n    }\n\n    /**\n     * Call a custom instance creator.\n     *\n     * @param  array  $config\n     * @return mixed\n     */\n    protected function callCustomCreator(array $config)\n    {\n        return $this->customCreators[$config[$this->driverKey]]($this->app, $config);\n    }\n\n    /**\n     * Unset the given instances.\n     *\n     * @param  array|string|null  $name\n     * @return $this\n     */\n    public function forgetInstance($name = null)\n    {\n        $name ??= $this->getDefaultInstance();\n\n        foreach ((array) $name as $instanceName) {\n            if (isset($this->instances[$instanceName])) {\n                unset($this->instances[$instanceName]);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Disconnect the given instance and remove from local cache.\n     *\n     * @param  string|null  $name\n     * @return void\n     */\n    public function purge($name = null)\n    {\n        $name ??= $this->getDefaultInstance();\n\n        unset($this->instances[$name]);\n    }\n\n    /**\n     * Register a custom instance creator Closure.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($name, Closure $callback)\n    {\n        $this->customCreators[$name] = $callback->bindTo($this, $this);\n\n        return $this;\n    }\n\n    /**\n     * Set the application instance used by the manager.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @return $this\n     */\n    public function setApplication($app)\n    {\n        $this->app = $app;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically call the default instance.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->instance()->$method(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/NamespacedItemResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nclass NamespacedItemResolver\n{\n    /**\n     * A cache of the parsed items.\n     *\n     * @var array\n     */\n    protected $parsed = [];\n\n    /**\n     * Parse a key into namespace, group, and item.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    public function parseKey($key)\n    {\n        // If we've already parsed the given key, we'll return the cached version we\n        // already have, as this will save us some processing. We cache off every\n        // key we parse so we can quickly return it on all subsequent requests.\n        if (isset($this->parsed[$key])) {\n            return $this->parsed[$key];\n        }\n\n        // If the key does not contain a double colon, it means the key is not in a\n        // namespace, and is just a regular configuration item. Namespaces are a\n        // tool for organizing configuration items for things such as modules.\n        if (! str_contains($key, '::')) {\n            $segments = explode('.', $key);\n\n            $parsed = $this->parseBasicSegments($segments);\n        } else {\n            $parsed = $this->parseNamespacedSegments($key);\n        }\n\n        // Once we have the parsed array of this key's elements, such as its groups\n        // and namespace, we will cache each array inside a simple list that has\n        // the key and the parsed array for quick look-ups for later requests.\n        return $this->parsed[$key] = $parsed;\n    }\n\n    /**\n     * Parse an array of basic segments.\n     *\n     * @param  array  $segments\n     * @return array\n     */\n    protected function parseBasicSegments(array $segments)\n    {\n        // The first segment in a basic array will always be the group, so we can go\n        // ahead and grab that segment. If there is only one total segment we are\n        // just pulling an entire group out of the array and not a single item.\n        $group = $segments[0];\n\n        // If there is more than one segment in this group, it means we are pulling\n        // a specific item out of a group and will need to return this item name\n        // as well as the group so we know which item to pull from the arrays.\n        $item = count($segments) === 1\n            ? null\n            : implode('.', array_slice($segments, 1));\n\n        return [null, $group, $item];\n    }\n\n    /**\n     * Parse an array of namespaced segments.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    protected function parseNamespacedSegments($key)\n    {\n        [$namespace, $item] = explode('::', $key);\n\n        // First we'll just explode the first segment to get the namespace and group\n        // since the item should be in the remaining segments. Once we have these\n        // two pieces of data we can proceed with parsing out the item's value.\n        $itemSegments = explode('.', $item);\n\n        $groupAndItem = array_slice(\n            $this->parseBasicSegments($itemSegments), 1\n        );\n\n        return array_merge([$namespace], $groupAndItem);\n    }\n\n    /**\n     * Set the parsed value of a key.\n     *\n     * @param  string  $key\n     * @param  array  $parsed\n     * @return void\n     */\n    public function setParsedKey($key, $parsed)\n    {\n        $this->parsed[$key] = $parsed;\n    }\n\n    /**\n     * Flush the cache of parsed keys.\n     *\n     * @return void\n     */\n    public function flushParsedKeys()\n    {\n        $this->parsed = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Number.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Illuminate\\Support\\Traits\\Macroable;\nuse NumberFormatter;\nuse RuntimeException;\n\nclass Number\n{\n    use Macroable;\n\n    /**\n     * The current default locale.\n     *\n     * @var string\n     */\n    protected static $locale = 'en';\n\n    /**\n     * The current default currency.\n     *\n     * @var string\n     */\n    protected static $currency = 'USD';\n\n    /**\n     * Format the given number according to the current locale.\n     *\n     * @param  int|float  $number\n     * @param  int|null  $precision\n     * @param  int|null  $maxPrecision\n     * @param  string|null  $locale\n     * @return string|false\n     */\n    public static function format(int|float $number, ?int $precision = null, ?int $maxPrecision = null, ?string $locale = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::DECIMAL);\n\n        if (! is_null($maxPrecision)) {\n            $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxPrecision);\n        } elseif (! is_null($precision)) {\n            $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);\n        }\n\n        return $formatter->format($number);\n    }\n\n    /**\n     * Parse the given string according to the specified format type.\n     *\n     * @param  string  $string\n     * @param  int|null  $type\n     * @param  string|null  $locale\n     * @return int|float|false\n     */\n    public static function parse(string $string, ?int $type = NumberFormatter::TYPE_DOUBLE, ?string $locale = null): int|float|false\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::DECIMAL);\n\n        return $formatter->parse($string, $type);\n    }\n\n    /**\n     * Parse a string into an integer according to the specified locale.\n     *\n     * @param  string  $string\n     * @param  string|null  $locale\n     * @return int|false\n     */\n    public static function parseInt(string $string, ?string $locale = null): int|false\n    {\n        return self::parse($string, NumberFormatter::TYPE_INT32, $locale);\n    }\n\n    /**\n     * Parse a string into a float according to the specified locale.\n     *\n     * @param  string  $string\n     * @param  string|null  $locale\n     * @return float|false\n     */\n    public static function parseFloat(string $string, ?string $locale = null): float|false\n    {\n        return self::parse($string, NumberFormatter::TYPE_DOUBLE, $locale);\n    }\n\n    /**\n     * Spell out the given number in the given locale.\n     *\n     * @param  int|float  $number\n     * @param  string|null  $locale\n     * @param  int|null  $after\n     * @param  int|null  $until\n     * @return string\n     */\n    public static function spell(int|float $number, ?string $locale = null, ?int $after = null, ?int $until = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        if (! is_null($after) && $number <= $after) {\n            return static::format($number, locale: $locale);\n        }\n\n        if (! is_null($until) && $number >= $until) {\n            return static::format($number, locale: $locale);\n        }\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::SPELLOUT);\n\n        return $formatter->format($number);\n    }\n\n    /**\n     * Convert the given number to ordinal form.\n     *\n     * @param  int|float  $number\n     * @param  string|null  $locale\n     * @return string\n     */\n    public static function ordinal(int|float $number, ?string $locale = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::ORDINAL);\n\n        return $formatter->format($number);\n    }\n\n    /**\n     * Spell out the given number in the given locale in ordinal form.\n     *\n     * @param  int|float  $number\n     * @param  string|null  $locale\n     * @return string\n     */\n    public static function spellOrdinal(int|float $number, ?string $locale = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::SPELLOUT);\n\n        $formatter->setTextAttribute(NumberFormatter::DEFAULT_RULESET, '%spellout-ordinal');\n\n        return $formatter->format($number);\n    }\n\n    /**\n     * Convert the given number to its percentage equivalent.\n     *\n     * @param  int|float  $number\n     * @param  int  $precision\n     * @param  int|null  $maxPrecision\n     * @param  string|null  $locale\n     * @return string|false\n     */\n    public static function percentage(int|float $number, int $precision = 0, ?int $maxPrecision = null, ?string $locale = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::PERCENT);\n\n        if (! is_null($maxPrecision)) {\n            $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxPrecision);\n        } else {\n            $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);\n        }\n\n        return $formatter->format($number / 100);\n    }\n\n    /**\n     * Convert the given number to its currency equivalent.\n     *\n     * @param  int|float  $number\n     * @param  string  $in\n     * @param  string|null  $locale\n     * @param  int|null  $precision\n     * @return string|false\n     */\n    public static function currency(int|float $number, string $in = '', ?string $locale = null, ?int $precision = null)\n    {\n        static::ensureIntlExtensionIsInstalled();\n\n        $formatter = new NumberFormatter($locale ?? static::$locale, NumberFormatter::CURRENCY);\n\n        if (! is_null($precision)) {\n            $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);\n        }\n\n        return $formatter->formatCurrency($number, ! empty($in) ? $in : static::$currency);\n    }\n\n    /**\n     * Convert the given number to its file size equivalent.\n     *\n     * @param  int|float  $bytes\n     * @param  int  $precision\n     * @param  int|null  $maxPrecision\n     * @return string\n     */\n    public static function fileSize(int|float $bytes, int $precision = 0, ?int $maxPrecision = null)\n    {\n        $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\n        $unitCount = count($units);\n\n        for ($i = 0; ($bytes / 1024) > 0.9 && ($i < $unitCount - 1); $i++) {\n            $bytes /= 1024;\n        }\n\n        return sprintf('%s %s', static::format($bytes, $precision, $maxPrecision), $units[$i]);\n    }\n\n    /**\n     * Convert the number to its human-readable equivalent.\n     *\n     * @param  int|float  $number\n     * @param  int  $precision\n     * @param  int|null  $maxPrecision\n     * @return string|false\n     */\n    public static function abbreviate(int|float $number, int $precision = 0, ?int $maxPrecision = null)\n    {\n        return static::forHumans($number, $precision, $maxPrecision, abbreviate: true);\n    }\n\n    /**\n     * Convert the number to its human-readable equivalent.\n     *\n     * @param  int|float  $number\n     * @param  int  $precision\n     * @param  int|null  $maxPrecision\n     * @param  bool  $abbreviate\n     * @return string|false\n     */\n    public static function forHumans(int|float $number, int $precision = 0, ?int $maxPrecision = null, bool $abbreviate = false)\n    {\n        return static::summarize($number, $precision, $maxPrecision, $abbreviate ? [\n            3 => 'K',\n            6 => 'M',\n            9 => 'B',\n            12 => 'T',\n            15 => 'Q',\n        ] : [\n            3 => ' thousand',\n            6 => ' million',\n            9 => ' billion',\n            12 => ' trillion',\n            15 => ' quadrillion',\n        ]);\n    }\n\n    /**\n     * Convert the number to its human-readable equivalent.\n     *\n     * @param  int|float  $number\n     * @param  int  $precision\n     * @param  int|null  $maxPrecision\n     * @param  array  $units\n     * @return string|false\n     */\n    protected static function summarize(int|float $number, int $precision = 0, ?int $maxPrecision = null, array $units = [])\n    {\n        if (empty($units)) {\n            $units = [\n                3 => 'K',\n                6 => 'M',\n                9 => 'B',\n                12 => 'T',\n                15 => 'Q',\n            ];\n        }\n\n        switch (true) {\n            case (float) $number === 0.0:\n                return $precision > 0 ? static::format(0, $precision, $maxPrecision) : '0';\n            case $number < 0:\n                return sprintf('-%s', static::summarize(abs($number), $precision, $maxPrecision, $units));\n            case $number >= 1e15:\n                return sprintf('%s'.end($units), static::summarize($number / 1e15, $precision, $maxPrecision, $units));\n        }\n\n        $numberExponent = floor(log10($number));\n        $displayExponent = $numberExponent - ($numberExponent % 3);\n        $number /= pow(10, $displayExponent);\n\n        return trim(sprintf('%s%s', static::format($number, $precision, $maxPrecision), $units[$displayExponent] ?? ''));\n    }\n\n    /**\n     * Clamp the given number between the given minimum and maximum.\n     *\n     * @param  int|float  $number\n     * @param  int|float  $min\n     * @param  int|float  $max\n     * @return int|float\n     */\n    public static function clamp(int|float $number, int|float $min, int|float $max)\n    {\n        return min(max($number, $min), $max);\n    }\n\n    /**\n     * Split the given number into pairs of min/max values.\n     *\n     * @param  int|float  $to\n     * @param  int|float  $by\n     * @param  int|float  $start\n     * @param  int|float  $offset\n     * @return list<array{int|float, int|float}>\n     */\n    public static function pairs(int|float $to, int|float $by, int|float $start = 0, int|float $offset = 1)\n    {\n        $output = [];\n\n        for ($lower = $start; $lower < $to; $lower += $by) {\n            $upper = $lower + $by - $offset;\n\n            if ($upper > $to) {\n                $upper = $to;\n            }\n\n            $output[] = [$lower, $upper];\n        }\n\n        return $output;\n    }\n\n    /**\n     * Remove any trailing zero digits after the decimal point of the given number.\n     *\n     * @param  int|float  $number\n     * @return int|float\n     */\n    public static function trim(int|float $number)\n    {\n        return json_decode(json_encode($number));\n    }\n\n    /**\n     * Execute the given callback using the given locale.\n     *\n     * @template TReturn\n     *\n     * @param  string  $locale\n     * @param  callable(): TReturn  $callback\n     * @return TReturn\n     */\n    public static function withLocale(string $locale, callable $callback)\n    {\n        $previousLocale = static::$locale;\n\n        static::useLocale($locale);\n\n        try {\n            return $callback();\n        } finally {\n            static::useLocale($previousLocale);\n        }\n    }\n\n    /**\n     * Execute the given callback using the given currency.\n     *\n     * @template TReturn\n     *\n     * @param  string  $currency\n     * @param  callable(): TReturn  $callback\n     * @return TReturn\n     */\n    public static function withCurrency(string $currency, callable $callback)\n    {\n        $previousCurrency = static::$currency;\n\n        static::useCurrency($currency);\n\n        try {\n            return $callback();\n        } finally {\n            static::useCurrency($previousCurrency);\n        }\n    }\n\n    /**\n     * Set the default locale.\n     *\n     * @param  string  $locale\n     * @return void\n     */\n    public static function useLocale(string $locale)\n    {\n        static::$locale = $locale;\n    }\n\n    /**\n     * Set the default currency.\n     *\n     * @param  string  $currency\n     * @return void\n     */\n    public static function useCurrency(string $currency)\n    {\n        static::$currency = $currency;\n    }\n\n    /**\n     * Get the default locale.\n     *\n     * @return string\n     */\n    public static function defaultLocale()\n    {\n        return static::$locale;\n    }\n\n    /**\n     * Get the default currency.\n     *\n     * @return string\n     */\n    public static function defaultCurrency()\n    {\n        return static::$currency;\n    }\n\n    /**\n     * Ensure the \"intl\" PHP extension is installed.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected static function ensureIntlExtensionIsInstalled()\n    {\n        if (! extension_loaded('intl')) {\n            $method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'];\n\n            throw new RuntimeException('The \"intl\" PHP extension is required to use the ['.$method.'] method.');\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Once.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse WeakMap;\n\nclass Once\n{\n    /**\n     * The current globally used instance.\n     *\n     * @var static|null\n     */\n    protected static ?self $instance = null;\n\n    /**\n     * Indicates if the once instance is enabled.\n     *\n     * @var bool\n     */\n    protected static bool $enabled = true;\n\n    /**\n     * Create a new once instance.\n     *\n     * @param  \\WeakMap<object, array<string, mixed>>  $values\n     */\n    protected function __construct(protected WeakMap $values)\n    {\n        //\n    }\n\n    /**\n     * Create a new once instance.\n     *\n     * @return static\n     */\n    public static function instance()\n    {\n        return static::$instance ??= new static(new WeakMap);\n    }\n\n    /**\n     * Get the value of the given onceable.\n     *\n     * @param  Onceable  $onceable\n     * @return mixed\n     */\n    public function value(Onceable $onceable)\n    {\n        if (! static::$enabled) {\n            return call_user_func($onceable->callable);\n        }\n\n        $object = $onceable->object ?: $this;\n\n        $hash = $onceable->hash;\n\n        if (! isset($this->values[$object])) {\n            $this->values[$object] = [];\n        }\n\n        if (array_key_exists($hash, $this->values[$object])) {\n            return $this->values[$object][$hash];\n        }\n\n        return $this->values[$object][$hash] = call_user_func($onceable->callable);\n    }\n\n    /**\n     * Re-enable the once instance if it was disabled.\n     *\n     * @return void\n     */\n    public static function enable()\n    {\n        static::$enabled = true;\n    }\n\n    /**\n     * Disable the once instance.\n     *\n     * @return void\n     */\n    public static function disable()\n    {\n        static::$enabled = false;\n    }\n\n    /**\n     * Flush the once instance.\n     *\n     * @return void\n     */\n    public static function flush()\n    {\n        static::$instance = null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Onceable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\HasOnceHash;\nuse Laravel\\SerializableClosure\\Support\\ReflectionClosure;\n\nclass Onceable\n{\n    /**\n     * Create a new onceable instance.\n     *\n     * @param  string  $hash\n     * @param  object|null  $object\n     * @param  callable  $callable\n     */\n    public function __construct(\n        public string $hash,\n        public ?object $object,\n        public $callable,\n    ) {\n        //\n    }\n\n    /**\n     * Tries to create a new onceable instance from the given trace.\n     *\n     * @param  array<int, array<string, mixed>>  $trace\n     * @return static|null\n     */\n    public static function tryFromTrace(array $trace, callable $callable)\n    {\n        if (! is_null($hash = static::hashFromTrace($trace, $callable))) {\n            $object = static::objectFromTrace($trace);\n\n            return new static($hash, $object, $callable);\n        }\n    }\n\n    /**\n     * Computes the object of the onceable from the given trace, if any.\n     *\n     * @param  array<int, array<string, mixed>>  $trace\n     * @return object|null\n     */\n    protected static function objectFromTrace(array $trace)\n    {\n        return $trace[1]['object'] ?? null;\n    }\n\n    /**\n     * Computes the hash of the onceable from the given trace.\n     *\n     * @param  array<int, array<string, mixed>>  $trace\n     * @return string|null\n     */\n    protected static function hashFromTrace(array $trace, callable $callable)\n    {\n        if (str_contains($trace[0]['file'] ?? '', 'eval()\\'d code')) {\n            return null;\n        }\n\n        $uses = array_map(\n            static function (mixed $argument) {\n                if ($argument instanceof HasOnceHash) {\n                    return $argument->onceHash();\n                }\n\n                if (is_object($argument)) {\n                    return spl_object_hash($argument);\n                }\n\n                return $argument;\n            },\n            $callable instanceof Closure ? (new ReflectionClosure($callable))->getClosureUsedVariables() : [],\n        );\n\n        $class = $callable instanceof Closure ? (new ReflectionClosure($callable))->getClosureCalledClass()?->getName() : null;\n\n        $class ??= isset($trace[1]['class']) ? $trace[1]['class'] : null;\n\n        return hash('xxh128', sprintf(\n            '%s@%s%s:%s (%s)',\n            $trace[0]['file'],\n            $class ? $class.'@' : '',\n            $trace[1]['function'],\n            $trace[0]['line'],\n            serialize($uses),\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Optional.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayAccess;\nuse ArrayObject;\nuse Illuminate\\Support\\Traits\\Macroable;\n\nclass Optional implements ArrayAccess\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The underlying object.\n     *\n     * @var mixed\n     */\n    protected $value;\n\n    /**\n     * Create a new optional instance.\n     *\n     * @param  mixed  $value\n     */\n    public function __construct($value)\n    {\n        $this->value = $value;\n    }\n\n    /**\n     * Dynamically access a property on the underlying object.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        if (is_object($this->value)) {\n            return $this->value->{$key} ?? null;\n        }\n    }\n\n    /**\n     * Dynamically check a property exists on the underlying object.\n     *\n     * @param  mixed  $name\n     * @return bool\n     */\n    public function __isset($name)\n    {\n        if (is_object($this->value)) {\n            return isset($this->value->{$name});\n        }\n\n        if (is_array($this->value) || $this->value instanceof ArrayObject) {\n            return isset($this->value[$name]);\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if an item exists at an offset.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return Arr::accessible($this->value) && Arr::exists($this->value, $offset);\n    }\n\n    /**\n     * Get an item at a given offset.\n     *\n     * @param  mixed  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return Arr::get($this->value, $offset);\n    }\n\n    /**\n     * Set the item at a given offset.\n     *\n     * @param  mixed  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        if (Arr::accessible($this->value)) {\n            $this->value[$offset] = $value;\n        }\n    }\n\n    /**\n     * Unset the item at a given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        if (Arr::accessible($this->value)) {\n            unset($this->value[$offset]);\n        }\n    }\n\n    /**\n     * Dynamically pass a method to the underlying object.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (is_object($this->value)) {\n            return $this->value->{$method}(...$parameters);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Pluralizer.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Doctrine\\Inflector\\InflectorFactory;\n\nclass Pluralizer\n{\n    /**\n     * The cached inflector instance.\n     *\n     * @var static\n     */\n    protected static $inflector;\n\n    /**\n     * The language that should be used by the inflector.\n     *\n     * @var string\n     */\n    protected static $language = 'english';\n\n    /**\n     * Uncountable non-nouns word forms.\n     *\n     * Contains words supported by Doctrine/Inflector/Rules/English/Uninflected.php\n     *\n     * @var string[]\n     */\n    public static $uncountable = [\n        'recommended',\n        'related',\n    ];\n\n    /**\n     * Get the plural form of an English word.\n     *\n     * @param  string  $value\n     * @param  int|array|\\Countable  $count\n     * @return string\n     */\n    public static function plural($value, $count = 2)\n    {\n        if (is_countable($count)) {\n            $count = count($count);\n        }\n\n        if ((int) abs($count) === 1 || static::uncountable($value) || preg_match('/^(.*)[A-Za-z0-9\\x{0080}-\\x{FFFF}]$/u', $value) == 0) {\n            return $value;\n        }\n\n        $plural = static::inflector()->pluralize($value);\n\n        return static::matchCase($plural, $value);\n    }\n\n    /**\n     * Get the singular form of an English word.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function singular($value)\n    {\n        $singular = static::inflector()->singularize($value);\n\n        return static::matchCase($singular, $value);\n    }\n\n    /**\n     * Determine if the given value is uncountable.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    protected static function uncountable($value)\n    {\n        return in_array(strtolower($value), static::$uncountable);\n    }\n\n    /**\n     * Attempt to match the case on two strings.\n     *\n     * @param  string  $value\n     * @param  string  $comparison\n     * @return string\n     */\n    protected static function matchCase($value, $comparison)\n    {\n        $functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords'];\n\n        foreach ($functions as $function) {\n            if ($function($comparison) === $comparison) {\n                return $function($value);\n            }\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the inflector instance.\n     *\n     * @return \\Doctrine\\Inflector\\Inflector\n     */\n    public static function inflector()\n    {\n        if (is_null(static::$inflector)) {\n            static::$inflector = InflectorFactory::createForLanguage(static::$language)->build();\n        }\n\n        return static::$inflector;\n    }\n\n    /**\n     * Specify the language that should be used by the inflector.\n     *\n     * @param  string  $language\n     * @return void\n     */\n    public static function useLanguage(string $language)\n    {\n        static::$language = $language;\n\n        static::$inflector = null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/ProcessUtils.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\n/**\n * ProcessUtils is a bunch of utility methods.\n *\n * This class was originally copied from Symfony 3.\n */\nclass ProcessUtils\n{\n    /**\n     * Escapes a string to be used as a shell argument.\n     *\n     * @param  string  $argument\n     * @return string\n     */\n    public static function escapeArgument($argument)\n    {\n        // Fix for PHP bug #43784 escapeshellarg removes % from given string\n        // Fix for PHP bug #49446 escapeshellarg doesn't work on Windows\n        // @see https://bugs.php.net/bug.php?id=43784\n        // @see https://bugs.php.net/bug.php?id=49446\n        if ('\\\\' === DIRECTORY_SEPARATOR) {\n            if ($argument === '') {\n                return '\"\"';\n            }\n\n            $escapedArgument = '';\n            $quote = false;\n\n            foreach (preg_split('/(\")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {\n                if ($part === '\"') {\n                    $escapedArgument .= '\\\\\"';\n                } elseif (self::isSurroundedBy($part, '%')) {\n                    // Avoid environment variable expansion\n                    $escapedArgument .= '^%\"'.substr($part, 1, -1).'\"^%';\n                } else {\n                    // escape trailing backslash\n                    if (str_ends_with($part, '\\\\')) {\n                        $part .= '\\\\';\n                    }\n                    $quote = true;\n                    $escapedArgument .= $part;\n                }\n            }\n\n            if ($quote) {\n                $escapedArgument = '\"'.$escapedArgument.'\"';\n            }\n\n            return $escapedArgument;\n        }\n\n        return \"'\".str_replace(\"'\", \"'\\\\''\", $argument).\"'\";\n    }\n\n    /**\n     * Is the given string surrounded by the given character?\n     *\n     * @param  string  $arg\n     * @param  string  $char\n     * @return bool\n     */\n    protected static function isSurroundedBy($arg, $char)\n    {\n        return strlen($arg) > 2 && $char === $arg[0] && $char === $arg[strlen($arg) - 1];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Queue/Concerns/ResolvesQueueRoutes.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Queue\\Concerns;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Queue\\QueueRoutes;\n\ntrait ResolvesQueueRoutes\n{\n    /**\n     * Resolve the default connection name for a given queueable instance.\n     *\n     * @param  object  $queueable\n     * @return string|null\n     */\n    public function resolveConnectionFromQueueRoute($queueable)\n    {\n        return $this->queueRoutes()->getConnection($queueable);\n    }\n\n    /**\n     * Resolve the default queue name for a given queueable instance.\n     *\n     * @param  object  $queueable\n     * @return string|null\n     */\n    public function resolveQueueFromQueueRoute($queueable)\n    {\n        return $this->queueRoutes()->getQueue($queueable);\n    }\n\n    /**\n     * Get the queue routes manager instance.\n     *\n     * @return \\Illuminate\\Queue\\QueueRoutes\n     */\n    protected function queueRoutes()\n    {\n        $container = Container::getInstance();\n\n        return $container->bound('queue.routes')\n            ? $container->make('queue.routes')\n            : new QueueRoutes;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/ServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Contracts\\Foundation\\CachesConfiguration;\nuse Illuminate\\Contracts\\Foundation\\CachesRoutes;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Database\\Eloquent\\Factory as ModelFactory;\nuse Illuminate\\View\\Compilers\\BladeCompiler;\n\n/**\n * @property array<string, string> $bindings All of the container bindings that should be registered.\n * @property array<array-key, string> $singletons All of the singletons that should be registered.\n */\nabstract class ServiceProvider\n{\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected $app;\n\n    /**\n     * All of the registered booting callbacks.\n     *\n     * @var array\n     */\n    protected $bootingCallbacks = [];\n\n    /**\n     * All of the registered booted callbacks.\n     *\n     * @var array\n     */\n    protected $bootedCallbacks = [];\n\n    /**\n     * The paths that should be published.\n     *\n     * @var array\n     */\n    public static $publishes = [];\n\n    /**\n     * The paths that should be published by group.\n     *\n     * @var array\n     */\n    public static $publishGroups = [];\n\n    /**\n     * The migration paths available for publishing.\n     *\n     * @var array\n     */\n    protected static $publishableMigrationPaths = [];\n\n    /**\n     * Commands that should be run during the \"optimize\" command.\n     *\n     * @var array<string, string>\n     */\n    public static array $optimizeCommands = [];\n\n    /**\n     * Commands that should be run during the \"optimize:clear\" command.\n     *\n     * @var array<string, string>\n     */\n    public static array $optimizeClearCommands = [];\n\n    /**\n     * Commands that should be run during the \"reload\" command.\n     *\n     * @var array<string, string>\n     */\n    public static array $reloadCommands = [];\n\n    /**\n     * Create a new service provider instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     */\n    public function __construct($app)\n    {\n        $this->app = $app;\n    }\n\n    /**\n     * Register any application services.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        //\n    }\n\n    /**\n     * Register a booting callback to be run before the \"boot\" method is called.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function booting(Closure $callback)\n    {\n        $this->bootingCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a booted callback to be run after the \"boot\" method is called.\n     *\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    public function booted(Closure $callback)\n    {\n        $this->bootedCallbacks[] = $callback;\n    }\n\n    /**\n     * Call the registered booting callbacks.\n     *\n     * @return void\n     */\n    public function callBootingCallbacks()\n    {\n        $index = 0;\n\n        while ($index < count($this->bootingCallbacks)) {\n            $this->app->call($this->bootingCallbacks[$index]);\n\n            $index++;\n        }\n    }\n\n    /**\n     * Call the registered booted callbacks.\n     *\n     * @return void\n     */\n    public function callBootedCallbacks()\n    {\n        $index = 0;\n\n        while ($index < count($this->bootedCallbacks)) {\n            $this->app->call($this->bootedCallbacks[$index]);\n\n            $index++;\n        }\n    }\n\n    /**\n     * Merge the given configuration with the existing configuration.\n     *\n     * @param  string  $path\n     * @param  string  $key\n     * @return void\n     */\n    protected function mergeConfigFrom($path, $key)\n    {\n        if (! ($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {\n            $config = $this->app->make('config');\n\n            $config->set($key, array_merge(\n                require $path, $config->get($key, [])\n            ));\n        }\n    }\n\n    /**\n     * Replace the given configuration with the existing configuration recursively.\n     *\n     * @param  string  $path\n     * @param  string  $key\n     * @return void\n     */\n    protected function replaceConfigRecursivelyFrom($path, $key)\n    {\n        if (! ($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {\n            $config = $this->app->make('config');\n\n            $config->set($key, array_replace_recursive(\n                require $path, $config->get($key, [])\n            ));\n        }\n    }\n\n    /**\n     * Load the given routes file if routes are not already cached.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function loadRoutesFrom($path)\n    {\n        if (! ($this->app instanceof CachesRoutes && $this->app->routesAreCached())) {\n            require $path;\n        }\n    }\n\n    /**\n     * Register a view file namespace.\n     *\n     * @param  string|array  $path\n     * @param  string  $namespace\n     * @return void\n     */\n    protected function loadViewsFrom($path, $namespace)\n    {\n        $this->callAfterResolving('view', function ($view) use ($path, $namespace) {\n            if (isset($this->app->config['view']['paths']) &&\n                is_array($this->app->config['view']['paths'])) {\n                foreach ($this->app->config['view']['paths'] as $viewPath) {\n                    if (is_dir($appPath = $viewPath.'/vendor/'.$namespace)) {\n                        $view->addNamespace($namespace, $appPath);\n                    }\n                }\n            }\n\n            $view->addNamespace($namespace, $path);\n        });\n    }\n\n    /**\n     * Register the given view components with a custom prefix.\n     *\n     * @param  string  $prefix\n     * @param  array  $components\n     * @return void\n     */\n    protected function loadViewComponentsAs($prefix, array $components)\n    {\n        $this->callAfterResolving(BladeCompiler::class, function ($blade) use ($prefix, $components) {\n            foreach ($components as $alias => $component) {\n                $blade->component($component, is_string($alias) ? $alias : null, $prefix);\n            }\n        });\n    }\n\n    /**\n     * Register a translation file namespace or path.\n     *\n     * @param  string  $path\n     * @param  string|null  $namespace\n     * @return void\n     */\n    protected function loadTranslationsFrom($path, $namespace = null)\n    {\n        $this->callAfterResolving('translator', fn ($translator) => is_null($namespace)\n            ? $translator->addPath($path)\n            : $translator->addNamespace($namespace, $path));\n    }\n\n    /**\n     * Register a JSON translation file path.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function loadJsonTranslationsFrom($path)\n    {\n        $this->callAfterResolving('translator', function ($translator) use ($path) {\n            $translator->addJsonPath($path);\n        });\n    }\n\n    /**\n     * Register database migration paths.\n     *\n     * @param  array|string  $paths\n     * @return void\n     */\n    protected function loadMigrationsFrom($paths)\n    {\n        $this->callAfterResolving('migrator', function ($migrator) use ($paths) {\n            foreach ((array) $paths as $path) {\n                $migrator->path($path);\n            }\n        });\n    }\n\n    /**\n     * Register Eloquent model factory paths.\n     *\n     * @deprecated Will be removed in a future Laravel version.\n     *\n     * @param  array|string  $paths\n     * @return void\n     */\n    protected function loadFactoriesFrom($paths)\n    {\n        $this->callAfterResolving(ModelFactory::class, function ($factory) use ($paths) {\n            foreach ((array) $paths as $path) {\n                $factory->load($path);\n            }\n        });\n    }\n\n    /**\n     * Setup an after resolving listener, or fire immediately if already resolved.\n     *\n     * @param  string  $name\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function callAfterResolving($name, $callback)\n    {\n        $this->app->afterResolving($name, $callback);\n\n        if ($this->app->resolved($name)) {\n            $callback($this->app->make($name), $this->app);\n        }\n    }\n\n    /**\n     * Register migration paths to be published by the publish command.\n     *\n     * @param  array  $paths\n     * @param  mixed  $groups\n     * @return void\n     */\n    protected function publishesMigrations(array $paths, $groups = null)\n    {\n        $this->publishes($paths, $groups);\n\n        if ($this->app->config->get('database.migrations.update_date_on_publish', false)) {\n            static::$publishableMigrationPaths = array_unique(array_merge(static::$publishableMigrationPaths, array_keys($paths)));\n        }\n    }\n\n    /**\n     * Register paths to be published by the publish command.\n     *\n     * @param  array  $paths\n     * @param  mixed  $groups\n     * @return void\n     */\n    protected function publishes(array $paths, $groups = null)\n    {\n        $this->ensurePublishArrayInitialized($class = static::class);\n\n        static::$publishes[$class] = array_merge(static::$publishes[$class], $paths);\n\n        foreach ((array) $groups as $group) {\n            $this->addPublishGroup($group, $paths);\n        }\n    }\n\n    /**\n     * Ensure the publish array for the service provider is initialized.\n     *\n     * @param  string  $class\n     * @return void\n     */\n    protected function ensurePublishArrayInitialized($class)\n    {\n        if (! array_key_exists($class, static::$publishes)) {\n            static::$publishes[$class] = [];\n        }\n    }\n\n    /**\n     * Add a publish group / tag to the service provider.\n     *\n     * @param  string  $group\n     * @param  array  $paths\n     * @return void\n     */\n    protected function addPublishGroup($group, $paths)\n    {\n        if (! array_key_exists($group, static::$publishGroups)) {\n            static::$publishGroups[$group] = [];\n        }\n\n        static::$publishGroups[$group] = array_merge(\n            static::$publishGroups[$group], $paths\n        );\n    }\n\n    /**\n     * Get the paths to publish.\n     *\n     * @param  string|null  $provider\n     * @param  string|null  $group\n     * @return array\n     */\n    public static function pathsToPublish($provider = null, $group = null)\n    {\n        if (! is_null($paths = static::pathsForProviderOrGroup($provider, $group))) {\n            return $paths;\n        }\n\n        return (new Collection(static::$publishes))->reduce(function ($paths, $p) {\n            return array_merge($paths, $p);\n        }, []);\n    }\n\n    /**\n     * Get the paths for the provider or group (or both).\n     *\n     * @param  string|null  $provider\n     * @param  string|null  $group\n     * @return array\n     */\n    protected static function pathsForProviderOrGroup($provider, $group)\n    {\n        if ($provider && $group) {\n            return static::pathsForProviderAndGroup($provider, $group);\n        } elseif ($group && array_key_exists($group, static::$publishGroups)) {\n            return static::$publishGroups[$group];\n        } elseif ($provider && array_key_exists($provider, static::$publishes)) {\n            return static::$publishes[$provider];\n        } elseif ($group || $provider) {\n            return [];\n        }\n    }\n\n    /**\n     * Get the paths for the provider and group.\n     *\n     * @param  string  $provider\n     * @param  string  $group\n     * @return array\n     */\n    protected static function pathsForProviderAndGroup($provider, $group)\n    {\n        if (! empty(static::$publishes[$provider]) && ! empty(static::$publishGroups[$group])) {\n            return array_intersect_key(static::$publishes[$provider], static::$publishGroups[$group]);\n        }\n\n        return [];\n    }\n\n    /**\n     * Get the service providers available for publishing.\n     *\n     * @return array\n     */\n    public static function publishableProviders()\n    {\n        return array_keys(static::$publishes);\n    }\n\n    /**\n     * Get the migration paths available for publishing.\n     *\n     * @return array\n     */\n    public static function publishableMigrationPaths()\n    {\n        return static::$publishableMigrationPaths;\n    }\n\n    /**\n     * Get the groups available for publishing.\n     *\n     * @return array\n     */\n    public static function publishableGroups()\n    {\n        return array_keys(static::$publishGroups);\n    }\n\n    /**\n     * Register the package's custom Artisan commands.\n     *\n     * @param  mixed  $commands\n     * @return void\n     */\n    public function commands($commands)\n    {\n        $commands = is_array($commands) ? $commands : func_get_args();\n\n        Artisan::starting(function ($artisan) use ($commands) {\n            $artisan->resolveCommands($commands);\n        });\n    }\n\n    /**\n     * Register commands that should run on \"optimize\" or \"optimize:clear\".\n     *\n     * @param  string|null  $optimize\n     * @param  string|null  $clear\n     * @param  string|null  $key\n     * @return void\n     */\n    protected function optimizes(?string $optimize = null, ?string $clear = null, ?string $key = null)\n    {\n        $key = $this->getProviderKey($key);\n\n        if ($optimize) {\n            static::$optimizeCommands[$key] = $optimize;\n        }\n\n        if ($clear) {\n            static::$optimizeClearCommands[$key] = $clear;\n        }\n    }\n\n    /**\n     * Register commands that should run on \"reload\".\n     *\n     * @param  string|null  $reload\n     * @param  string|null  $key\n     * @return void\n     */\n    protected function reloads(string $reload, ?string $key = null)\n    {\n        $key = $this->getProviderKey($key);\n\n        static::$reloadCommands[$key] = $reload;\n    }\n\n    /**\n     * Get a short descriptive key for the current service provider.\n     *\n     * @param  string|null  $key\n     * @return string\n     */\n    protected function getProviderKey(?string $key = null): string\n    {\n        $key ??= (string) Str::of(get_class($this))\n            ->classBasename()\n            ->before('ServiceProvider')\n            ->kebab()\n            ->lower()\n            ->trim();\n\n        if (empty($key)) {\n            $key = class_basename(get_class($this));\n        }\n\n        return $key;\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return [];\n    }\n\n    /**\n     * Get the events that trigger this service provider to register.\n     *\n     * @return array\n     */\n    public function when()\n    {\n        return [];\n    }\n\n    /**\n     * Determine if the provider is deferred.\n     *\n     * @return bool\n     */\n    public function isDeferred()\n    {\n        return $this instanceof DeferrableProvider;\n    }\n\n    /**\n     * Get the default providers for a Laravel application.\n     *\n     * @return \\Illuminate\\Support\\DefaultProviders\n     */\n    public static function defaultProviders()\n    {\n        return new DefaultProviders;\n    }\n\n    /**\n     * Add the given provider to the application's provider bootstrap file.\n     *\n     * @param  string  $provider\n     * @param  string|null  $path\n     * @return bool\n     */\n    public static function addProviderToBootstrapFile(string $provider, ?string $path = null)\n    {\n        $path ??= app()->getBootstrapProvidersPath();\n\n        if (! file_exists($path)) {\n            return false;\n        }\n\n        if (function_exists('opcache_invalidate')) {\n            opcache_invalidate($path, true);\n        }\n\n        $providers = (new Collection(require $path))\n            ->merge([$provider])\n            ->unique()\n            ->sort()\n            ->values()\n            ->map(fn ($p) => '    '.$p.'::class,')\n            ->implode(PHP_EOL);\n\n        $content = '<?php\n\nreturn [\n'.$providers.'\n];';\n\n        file_put_contents($path, $content.PHP_EOL);\n\n        return true;\n    }\n\n    /**\n     * Remove a provider from the application's provider bootstrap file.\n     *\n     * @param  string|array  $providersToRemove\n     * @param  string|null  $path\n     * @param  bool  $strict\n     * @return bool\n     */\n    public static function removeProviderFromBootstrapFile(string|array $providersToRemove, ?string $path = null, bool $strict = false)\n    {\n        $path ??= app()->getBootstrapProvidersPath();\n\n        if (! file_exists($path)) {\n            return false;\n        }\n\n        if (function_exists('opcache_invalidate')) {\n            opcache_invalidate($path, true);\n        }\n\n        $providersToRemove = Arr::wrap($providersToRemove);\n\n        $providers = (new Collection(require $path))\n            ->unique()\n            ->sort()\n            ->values()\n            ->when(\n                $strict,\n                static fn (Collection $providerCollection) => $providerCollection->reject(fn (string $p) => in_array($p, $providersToRemove, true)),\n                static fn (Collection $providerCollection) => $providerCollection->reject(fn (string $p) => Str::contains($p, $providersToRemove))\n            )\n            ->map(fn ($p) => '    '.$p.'::class,')\n            ->implode(PHP_EOL);\n\n        $content = '<?php\n\nreturn [\n'.$providers.'\n];';\n\n        file_put_contents($path, $content.PHP_EOL);\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Sleep.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Carbon\\CarbonInterval;\nuse Closure;\nuse DateInterval;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse RuntimeException;\n\nclass Sleep\n{\n    use Macroable;\n\n    /**\n     * The fake sleep callbacks.\n     *\n     * @var array\n     */\n    public static $fakeSleepCallbacks = [];\n\n    /**\n     * Keep Carbon's \"now\" in sync when sleeping.\n     *\n     * @var bool\n     */\n    protected static $syncWithCarbon = false;\n\n    /**\n     * The total duration to sleep.\n     *\n     * @var \\Carbon\\CarbonInterval\n     */\n    public $duration;\n\n    /**\n     * The callback that determines if sleeping should continue.\n     *\n     * @var \\Closure\n     */\n    public $while;\n\n    /**\n     * The pending duration to sleep.\n     *\n     * @var int|float|null\n     */\n    protected $pending = null;\n\n    /**\n     * Indicates that all sleeping should be faked.\n     *\n     * @var bool\n     */\n    protected static $fake = false;\n\n    /**\n     * The sequence of sleep durations encountered while faking.\n     *\n     * @var array<int, \\Carbon\\CarbonInterval>\n     */\n    protected static $sequence = [];\n\n    /**\n     * Indicates if the instance should sleep.\n     *\n     * @var bool\n     */\n    protected $shouldSleep = true;\n\n    /**\n     * Indicates if the instance already slept via `then()`.\n     *\n     * @var bool\n     */\n    protected $alreadySlept = false;\n\n    /**\n     * Create a new class instance.\n     *\n     * @param  int|float|\\DateInterval  $duration\n     */\n    public function __construct($duration)\n    {\n        $this->duration($duration);\n    }\n\n    /**\n     * Sleep for the given duration.\n     *\n     * @param  \\DateInterval|int|float  $duration\n     * @return static\n     */\n    public static function for($duration)\n    {\n        return new static($duration);\n    }\n\n    /**\n     * Sleep until the given timestamp.\n     *\n     * @param  \\DateTimeInterface|int|float|numeric-string  $timestamp\n     * @return static\n     */\n    public static function until($timestamp)\n    {\n        if (is_numeric($timestamp)) {\n            $timestamp = Carbon::createFromTimestamp($timestamp, date_default_timezone_get());\n        }\n\n        return new static(Carbon::now()->diff($timestamp));\n    }\n\n    /**\n     * Sleep for the given number of microseconds.\n     *\n     * @param  int  $duration\n     * @return static\n     */\n    public static function usleep($duration)\n    {\n        return (new static($duration))->microseconds();\n    }\n\n    /**\n     * Sleep for the given number of seconds.\n     *\n     * @param  int|float  $duration\n     * @return static\n     */\n    public static function sleep($duration)\n    {\n        return (new static($duration))->seconds();\n    }\n\n    /**\n     * Sleep for the given duration. Replaces any previously defined duration.\n     *\n     * @param  \\DateInterval|int|float  $duration\n     * @return $this\n     */\n    protected function duration($duration)\n    {\n        if (! $duration instanceof DateInterval) {\n            $this->duration = CarbonInterval::microsecond(0);\n\n            $this->pending = $duration;\n        } else {\n            $duration = CarbonInterval::instance($duration);\n\n            if ($duration->totalMicroseconds < 0) {\n                $duration = CarbonInterval::seconds(0);\n            }\n\n            $this->duration = $duration;\n            $this->pending = null;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Sleep for the given number of minutes.\n     *\n     * @return $this\n     */\n    public function minutes()\n    {\n        $this->duration->add('minutes', $this->pullPending());\n\n        return $this;\n    }\n\n    /**\n     * Sleep for one minute.\n     *\n     * @return $this\n     */\n    public function minute()\n    {\n        return $this->minutes();\n    }\n\n    /**\n     * Sleep for the given number of seconds.\n     *\n     * @return $this\n     */\n    public function seconds()\n    {\n        $this->duration->add('seconds', $this->pullPending());\n\n        return $this;\n    }\n\n    /**\n     * Sleep for one second.\n     *\n     * @return $this\n     */\n    public function second()\n    {\n        return $this->seconds();\n    }\n\n    /**\n     * Sleep for the given number of milliseconds.\n     *\n     * @return $this\n     */\n    public function milliseconds()\n    {\n        $this->duration->add('milliseconds', $this->pullPending());\n\n        return $this;\n    }\n\n    /**\n     * Sleep for one millisecond.\n     *\n     * @return $this\n     */\n    public function millisecond()\n    {\n        return $this->milliseconds();\n    }\n\n    /**\n     * Sleep for the given number of microseconds.\n     *\n     * @return $this\n     */\n    public function microseconds()\n    {\n        $this->duration->add('microseconds', $this->pullPending());\n\n        return $this;\n    }\n\n    /**\n     * Sleep for on microsecond.\n     *\n     * @return $this\n     */\n    public function microsecond()\n    {\n        return $this->microseconds();\n    }\n\n    /**\n     * Add additional time to sleep for.\n     *\n     * @param  int|float  $duration\n     * @return $this\n     */\n    public function and($duration)\n    {\n        $this->pending = $duration;\n\n        return $this;\n    }\n\n    /**\n     * Sleep while a given callback returns \"true\".\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function while(Closure $callback)\n    {\n        $this->while = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Specify a callback that should be executed after sleeping.\n     *\n     * @param  callable  $then\n     * @return mixed\n     */\n    public function then(callable $then)\n    {\n        $this->goodnight();\n\n        $this->alreadySlept = true;\n\n        return $then();\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        $this->goodnight();\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function goodnight()\n    {\n        if ($this->alreadySlept || ! $this->shouldSleep) {\n            return;\n        }\n\n        if ($this->pending !== null) {\n            throw new RuntimeException('Unknown duration unit.');\n        }\n\n        if (static::$fake) {\n            static::$sequence[] = $this->duration;\n\n            if (static::$syncWithCarbon) {\n                Carbon::setTestNow(Carbon::now()->add($this->duration));\n            }\n\n            foreach (static::$fakeSleepCallbacks as $callback) {\n                $callback($this->duration);\n            }\n\n            return;\n        }\n\n        $remaining = $this->duration->copy();\n\n        $seconds = (int) $remaining->totalSeconds;\n\n        $while = $this->while ?: function () {\n            static $return = [true, false];\n\n            return array_shift($return);\n        };\n\n        while ($while()) {\n            if ($seconds > 0) {\n                sleep($seconds);\n\n                $remaining = $remaining->subSeconds($seconds);\n            }\n\n            $microseconds = (int) $remaining->totalMicroseconds;\n\n            if ($microseconds > 0) {\n                usleep($microseconds);\n            }\n        }\n    }\n\n    /**\n     * Resolve the pending duration.\n     *\n     * @return int|float\n     *\n     * @throws \\RuntimeException\n     */\n    protected function pullPending()\n    {\n        if ($this->pending === null) {\n            $this->shouldNotSleep();\n\n            throw new RuntimeException('No duration specified.');\n        }\n\n        if ($this->pending < 0) {\n            $this->pending = 0;\n        }\n\n        return tap($this->pending, function () {\n            $this->pending = null;\n        });\n    }\n\n    /**\n     * Stay awake and capture any attempts to sleep.\n     *\n     * @param  bool  $value\n     * @param  bool  $syncWithCarbon\n     * @return void\n     */\n    public static function fake($value = true, $syncWithCarbon = false)\n    {\n        static::$fake = $value;\n\n        static::$sequence = [];\n        static::$fakeSleepCallbacks = [];\n        static::$syncWithCarbon = $syncWithCarbon;\n    }\n\n    /**\n     * Assert a given amount of sleeping occurred a specific number of times.\n     *\n     * @param  \\Closure  $expected\n     * @param  int  $times\n     * @return void\n     */\n    public static function assertSlept($expected, $times = 1)\n    {\n        $count = (new Collection(static::$sequence))->filter($expected)->count();\n\n        PHPUnit::assertSame(\n            $times,\n            $count,\n            \"The expected sleep was found [{$count}] times instead of [{$times}].\"\n        );\n    }\n\n    /**\n     * Assert sleeping occurred a given number of times.\n     *\n     * @param  int  $expected\n     * @return void\n     */\n    public static function assertSleptTimes($expected)\n    {\n        PHPUnit::assertSame($expected, $count = count(static::$sequence), \"Expected [{$expected}] sleeps but found [{$count}].\");\n    }\n\n    /**\n     * Assert the given sleep sequence was encountered.\n     *\n     * @param  array  $sequence\n     * @return void\n     */\n    public static function assertSequence($sequence)\n    {\n        try {\n            static::assertSleptTimes(count($sequence));\n\n            (new Collection($sequence))\n                ->zip(static::$sequence)\n                ->eachSpread(function (?Sleep $expected, CarbonInterval $actual) {\n                    if ($expected === null) {\n                        return;\n                    }\n\n                    PHPUnit::assertTrue(\n                        $expected->shouldNotSleep()->duration->equalTo($actual),\n                        vsprintf('Expected sleep duration of [%s] but actually slept for [%s].', [\n                            $expected->duration->cascade()->forHumans([\n                                'options' => 0,\n                                'minimumUnit' => 'microsecond',\n                            ]),\n                            $actual->cascade()->forHumans([\n                                'options' => 0,\n                                'minimumUnit' => 'microsecond',\n                            ]),\n                        ])\n                    );\n                });\n        } finally {\n            foreach ($sequence as $expected) {\n                if ($expected instanceof self) {\n                    $expected->shouldNotSleep();\n                }\n            }\n        }\n    }\n\n    /**\n     * Assert that no sleeping occurred.\n     *\n     * @return void\n     */\n    public static function assertNeverSlept()\n    {\n        static::assertSleptTimes(0);\n    }\n\n    /**\n     * Assert that no sleeping occurred.\n     *\n     * @return void\n     */\n    public static function assertInsomniac()\n    {\n        if (static::$sequence === []) {\n            PHPUnit::assertTrue(true);\n        }\n\n        foreach (static::$sequence as $duration) {\n            PHPUnit::assertSame(0, (int) $duration->totalMicroseconds, vsprintf('Unexpected sleep duration of [%s] found.', [\n                $duration->cascade()->forHumans([\n                    'options' => 0,\n                    'minimumUnit' => 'microsecond',\n                ]),\n            ]));\n        }\n    }\n\n    /**\n     * Indicate that the instance should not sleep.\n     *\n     * @return $this\n     */\n    protected function shouldNotSleep()\n    {\n        $this->shouldSleep = false;\n\n        return $this;\n    }\n\n    /**\n     * Only sleep when the given condition is true.\n     *\n     * @param  (\\Closure($this): bool)|bool  $condition\n     * @return $this\n     */\n    public function when($condition)\n    {\n        $this->shouldSleep = (bool) value($condition, $this);\n\n        return $this;\n    }\n\n    /**\n     * Don't sleep when the given condition is true.\n     *\n     * @param  (\\Closure($this): bool)|bool  $condition\n     * @return $this\n     */\n    public function unless($condition)\n    {\n        return $this->when(! value($condition, $this));\n    }\n\n    /**\n     * Specify a callback that should be invoked when faking sleep within a test.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public static function whenFakingSleep($callback)\n    {\n        static::$fakeSleepCallbacks[] = $callback;\n    }\n\n    /**\n     * Indicate that Carbon's \"now\" should be kept in sync when sleeping.\n     *\n     * @return void\n     */\n    public static function syncWithCarbon($value = true)\n    {\n        static::$syncWithCarbon = $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Str.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse League\\CommonMark\\Environment\\Environment;\nuse League\\CommonMark\\Extension\\GithubFlavoredMarkdownExtension;\nuse League\\CommonMark\\Extension\\InlinesOnly\\InlinesOnlyExtension;\nuse League\\CommonMark\\GithubFlavoredMarkdownConverter;\nuse League\\CommonMark\\MarkdownConverter;\nuse Ramsey\\Uuid\\Codec\\TimestampFirstCombCodec;\nuse Ramsey\\Uuid\\Exception\\InvalidUuidStringException;\nuse Ramsey\\Uuid\\Generator\\CombGenerator;\nuse Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Ramsey\\Uuid\\UuidFactory;\nuse Symfony\\Component\\Uid\\Ulid;\nuse Throwable;\nuse Traversable;\nuse voku\\helper\\ASCII;\n\nclass Str\n{\n    use Macroable;\n\n    /**\n     * The list of characters that are considered \"invisible\" in strings.\n     *\n     * @var string\n     */\n    const INVISIBLE_CHARACTERS = '\\x{0009}\\x{0020}\\x{00A0}\\x{00AD}\\x{034F}\\x{061C}\\x{115F}\\x{1160}\\x{17B4}\\x{17B5}\\x{180E}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200A}\\x{200B}\\x{200C}\\x{200D}\\x{200E}\\x{200F}\\x{202F}\\x{205F}\\x{2060}\\x{2061}\\x{2062}\\x{2063}\\x{2064}\\x{2065}\\x{206A}\\x{206B}\\x{206C}\\x{206D}\\x{206E}\\x{206F}\\x{3000}\\x{2800}\\x{3164}\\x{FEFF}\\x{FFA0}\\x{1D159}\\x{1D173}\\x{1D174}\\x{1D175}\\x{1D176}\\x{1D177}\\x{1D178}\\x{1D179}\\x{1D17A}\\x{E0020}';\n\n    /**\n     * The cache of snake-cased words.\n     *\n     * @var array<string, string>\n     */\n    protected static $snakeCache = [];\n\n    /**\n     * The cache of camel-cased words.\n     *\n     * @var array<string, string>\n     */\n    protected static $camelCache = [];\n\n    /**\n     * The cache of studly-cased words.\n     *\n     * @var array<string, string>\n     */\n    protected static $studlyCache = [];\n\n    /**\n     * The callback that should be used to generate UUIDs.\n     *\n     * @var (callable(): \\Ramsey\\Uuid\\UuidInterface)|null\n     */\n    protected static $uuidFactory;\n\n    /**\n     * The callback that should be used to generate ULIDs.\n     *\n     * @var (callable(): \\Symfony\\Component\\Uid\\Ulid)|null\n     */\n    protected static $ulidFactory;\n\n    /**\n     * The callback that should be used to generate random strings.\n     *\n     * @var (callable(int): string)|null\n     */\n    protected static $randomStringFactory;\n\n    /**\n     * Get a new stringable object from the given string.\n     *\n     * @param  string  $string\n     * @return \\Illuminate\\Support\\Stringable\n     */\n    public static function of($string)\n    {\n        return new Stringable($string);\n    }\n\n    /**\n     * Return the remainder of a string after the first occurrence of a given value.\n     *\n     * @param  string  $subject\n     * @param  string  $search\n     * @return string\n     */\n    public static function after($subject, $search)\n    {\n        return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];\n    }\n\n    /**\n     * Return the remainder of a string after the last occurrence of a given value.\n     *\n     * @param  string  $subject\n     * @param  string  $search\n     * @return string\n     */\n    public static function afterLast($subject, $search)\n    {\n        if ($search === '') {\n            return $subject;\n        }\n\n        $position = mb_strrpos($subject, $search);\n\n        if ($position === false) {\n            return $subject;\n        }\n\n        return static::substr($subject, $position + static::length($search));\n    }\n\n    /**\n     * Transliterate a UTF-8 value to ASCII.\n     *\n     * @param  string  $value\n     * @param  string  $language\n     * @return string\n     */\n    public static function ascii($value, $language = 'en')\n    {\n        return ASCII::to_ascii((string) $value, $language, replace_single_chars_only: false);\n    }\n\n    /**\n     * Transliterate a string to its closest ASCII representation.\n     *\n     * @param  string  $string\n     * @param  string|null  $unknown\n     * @param  bool|null  $strict\n     * @return string\n     */\n    public static function transliterate($string, $unknown = '?', $strict = false)\n    {\n        return ASCII::to_transliterate($string, $unknown, $strict);\n    }\n\n    /**\n     * Get the portion of a string before the first occurrence of a given value.\n     *\n     * @param  string  $subject\n     * @param  string  $search\n     * @return string\n     */\n    public static function before($subject, $search)\n    {\n        if ($search === '') {\n            return $subject;\n        }\n\n        $result = strstr($subject, (string) $search, true);\n\n        return $result === false ? $subject : $result;\n    }\n\n    /**\n     * Get the portion of a string before the last occurrence of a given value.\n     *\n     * @param  string  $subject\n     * @param  string  $search\n     * @return string\n     */\n    public static function beforeLast($subject, $search)\n    {\n        if ($search === '') {\n            return $subject;\n        }\n\n        $pos = mb_strrpos($subject, $search);\n\n        if ($pos === false) {\n            return $subject;\n        }\n\n        return static::substr($subject, 0, $pos);\n    }\n\n    /**\n     * Get the portion of a string between two given values.\n     *\n     * @param  string  $subject\n     * @param  string  $from\n     * @param  string  $to\n     * @return string\n     */\n    public static function between($subject, $from, $to)\n    {\n        if ($from === '' || $to === '') {\n            return $subject;\n        }\n\n        return static::beforeLast(static::after($subject, $from), $to);\n    }\n\n    /**\n     * Get the smallest possible portion of a string between two given values.\n     *\n     * @param  string  $subject\n     * @param  string  $from\n     * @param  string  $to\n     * @return string\n     */\n    public static function betweenFirst($subject, $from, $to)\n    {\n        if ($from === '' || $to === '') {\n            return $subject;\n        }\n\n        return static::before(static::after($subject, $from), $to);\n    }\n\n    /**\n     * Convert a value to camel case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : string)\n     */\n    public static function camel($value)\n    {\n        if (isset(static::$camelCache[$value])) {\n            return static::$camelCache[$value];\n        }\n\n        return static::$camelCache[$value] = lcfirst(static::studly($value));\n    }\n\n    /**\n     * Get the character at the specified index.\n     *\n     * @param  string  $subject\n     * @param  int  $index\n     * @return string|false\n     */\n    public static function charAt($subject, $index)\n    {\n        $length = mb_strlen($subject);\n\n        if ($index < 0 ? $index < -$length : $index > $length - 1) {\n            return false;\n        }\n\n        return mb_substr($subject, $index, 1);\n    }\n\n    /**\n     * Remove the given string(s) if it exists at the start of the haystack.\n     *\n     * @param  string  $subject\n     * @param  string|string[]  $needle\n     * @return string\n     */\n    public static function chopStart($subject, $needle)\n    {\n        foreach ((array) $needle as $n) {\n            if ($n !== '' && str_starts_with($subject, $n)) {\n                return mb_substr($subject, mb_strlen($n));\n            }\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Remove the given string(s) if it exists at the end of the haystack.\n     *\n     * @param  string  $subject\n     * @param  string|string[]  $needle\n     * @return string\n     */\n    public static function chopEnd($subject, $needle)\n    {\n        foreach ((array) $needle as $n) {\n            if ($n !== '' && str_ends_with($subject, $n)) {\n                return mb_substr($subject, 0, -mb_strlen($n));\n            }\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Determine if a given string contains a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return ($needles is array{} ? false : ($haystack is non-empty-string ? bool : false))\n     */\n    public static function contains($haystack, $needles, $ignoreCase = false)\n    {\n        if (is_null($haystack)) {\n            return false;\n        }\n\n        if ($ignoreCase) {\n            $haystack = mb_strtolower($haystack);\n        }\n\n        if (! is_iterable($needles)) {\n            $needles = (array) $needles;\n        }\n\n        foreach ($needles as $needle) {\n            if ($ignoreCase) {\n                $needle = mb_strtolower($needle);\n            }\n\n            if ($needle !== '' && str_contains($haystack, $needle)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if a given string contains all array values.\n     *\n     * @param  string  $haystack\n     * @param  iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return ($needles is array{} ? false : ($haystack is non-empty-string ? bool : false))\n     */\n    public static function containsAll($haystack, $needles, $ignoreCase = false)\n    {\n        foreach ($needles as $needle) {\n            if (! static::contains($haystack, $needle, $ignoreCase)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if a given string doesn't contain a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return ($needles is array{} ? true : ($haystack is non-empty-string ? bool : true))\n     */\n    public static function doesntContain($haystack, $needles, $ignoreCase = false)\n    {\n        return ! static::contains($haystack, $needles, $ignoreCase);\n    }\n\n    /**\n     * Convert the case of a string.\n     *\n     * @param  string  $string\n     * @param  MB_CASE_UPPER|MB_CASE_LOWER|MB_CASE_TITLE|MB_CASE_FOLD|MB_CASE_UPPER_SIMPLE|MB_CASE_LOWER_SIMPLE|MB_CASE_TITLE_SIMPLE|MB_CASE_FOLD_SIMPLE  $mode\n     * @param  string|null  $encoding\n     * @return ($string is '' ? '' : string)\n     */\n    public static function convertCase(string $string, int $mode = MB_CASE_FOLD, ?string $encoding = 'UTF-8')\n    {\n        return mb_convert_case($string, $mode, $encoding);\n    }\n\n    /**\n     * Replace consecutive instances of a given character with a single character in the given string.\n     *\n     * @param  string  $string\n     * @param  array<string>|string  $characters\n     * @return ($string is '' ? '' : string)\n     */\n    public static function deduplicate(string $string, array|string $characters = ' ')\n    {\n        if (is_string($characters)) {\n            return preg_replace('/'.preg_quote($characters, '/').'+/u', $characters, $string);\n        }\n\n        return array_reduce(\n            $characters,\n            fn ($carry, $character) => preg_replace('/'.preg_quote($character, '/').'+/u', $character, $carry),\n            $string\n        );\n    }\n\n    /**\n     * Determine if a given string ends with a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @return ($needles is array{} ? false : ($haystack is non-empty-string ? bool : false))\n     */\n    public static function endsWith($haystack, $needles)\n    {\n        if (is_null($haystack)) {\n            return false;\n        }\n\n        if (! is_iterable($needles)) {\n            $needles = (array) $needles;\n        }\n\n        foreach ($needles as $needle) {\n            if ((string) $needle !== '' && str_ends_with($haystack, $needle)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if a given string doesn't end with a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @return ($needles is array{} ? true : ($haystack is non-empty-string ? bool : true))\n     */\n    public static function doesntEndWith($haystack, $needles)\n    {\n        return ! static::endsWith($haystack, $needles);\n    }\n\n    /**\n     * Extracts an excerpt from text that matches the first instance of a phrase.\n     *\n     * @param  string  $text\n     * @param  string  $phrase\n     * @param  array{radius?: int|float, omission?: string}  $options\n     * @return string|null\n     */\n    public static function excerpt($text, $phrase = '', $options = [])\n    {\n        $radius = $options['radius'] ?? 100;\n        $omission = $options['omission'] ?? '...';\n\n        preg_match('/^(.*?)('.preg_quote((string) $phrase, '/').')(.*)$/iu', (string) $text, $matches);\n\n        if (empty($matches)) {\n            return null;\n        }\n\n        $start = ltrim($matches[1]);\n\n        $start = Str::of(mb_substr($start, max(mb_strlen($start, 'UTF-8') - $radius, 0), $radius, 'UTF-8'))->ltrim()->unless(\n            fn ($startWithRadius) => $startWithRadius->exactly($start),\n            fn ($startWithRadius) => $startWithRadius->prepend($omission),\n        );\n\n        $end = rtrim($matches[3]);\n\n        $end = Str::of(mb_substr($end, 0, $radius, 'UTF-8'))->rtrim()->unless(\n            fn ($endWithRadius) => $endWithRadius->exactly($end),\n            fn ($endWithRadius) => $endWithRadius->append($omission),\n        );\n\n        return $start->append($matches[2], $end)->toString();\n    }\n\n    /**\n     * Cap a string with a single instance of a given value.\n     *\n     * @param  string  $value\n     * @param  string  $cap\n     * @return ($value is '' ? ($cap is '' ? '' : non-empty-string) : non-empty-string)\n     */\n    public static function finish($value, $cap)\n    {\n        $quoted = preg_quote($cap, '/');\n\n        return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap;\n    }\n\n    /**\n     * Wrap the string with the given strings.\n     *\n     * @param  string  $value\n     * @param  string  $before\n     * @param  string|null  $after\n     * @return ($value is '' ? ($before is '' ? ($after is '' ? '' : ($after is null ? '' : non-empty-string)) : non-empty-string) : non-empty-string)\n     */\n    public static function wrap($value, $before, $after = null)\n    {\n        return $before.$value.($after ?? $before);\n    }\n\n    /**\n     * Unwrap the string with the given strings.\n     *\n     * @param  string  $value\n     * @param  string  $before\n     * @param  string|null  $after\n     * @return string\n     */\n    public static function unwrap($value, $before, $after = null)\n    {\n        if (static::startsWith($value, $before)) {\n            $value = static::substr($value, static::length($before));\n        }\n\n        if (static::endsWith($value, $after ??= $before)) {\n            $value = static::substr($value, 0, -static::length($after));\n        }\n\n        return $value;\n    }\n\n    /**\n     * Determine if a given string matches a given pattern.\n     *\n     * @param  string|iterable<string>  $pattern\n     * @param  string  $value\n     * @param  bool  $ignoreCase\n     * @return bool\n     */\n    public static function is($pattern, $value, $ignoreCase = false)\n    {\n        $value = (string) $value;\n\n        if (! is_iterable($pattern)) {\n            $pattern = [$pattern];\n        }\n\n        foreach ($pattern as $pattern) {\n            $pattern = (string) $pattern;\n\n            // If the given value is an exact match we can of course return true right\n            // from the beginning. Otherwise, we will translate asterisks and do an\n            // actual pattern match against the two strings to see if they match.\n            if ($pattern === '*' || $pattern === $value) {\n                return true;\n            }\n\n            if ($ignoreCase && mb_strtolower($pattern) === mb_strtolower($value)) {\n                return true;\n            }\n\n            $pattern = preg_quote($pattern, '#');\n\n            // Asterisks are translated into zero-or-more regular expression wildcards\n            // to make it convenient to check if the strings starts with the given\n            // pattern such as \"library/*\", making any string check convenient.\n            $pattern = str_replace('\\*', '.*', $pattern);\n\n            if (preg_match('#^'.$pattern.'\\z#'.($ignoreCase ? 'isu' : 'su'), $value) === 1) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if a given string is 7 bit ASCII.\n     *\n     * @param  string  $value\n     * @return bool\n     */\n    public static function isAscii($value)\n    {\n        return ASCII::is_ascii((string) $value);\n    }\n\n    /**\n     * Determine if a given value is valid JSON.\n     *\n     * @param  mixed  $value\n     * @return bool\n     *\n     * @phpstan-assert-if-true =non-empty-string $value\n     */\n    public static function isJson($value)\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        return json_validate($value, 512);\n    }\n\n    /**\n     * Determine if a given value is a valid URL.\n     *\n     * @param  mixed  $value\n     * @param  string[]  $protocols\n     * @return bool\n     *\n     * @phpstan-assert-if-true =non-empty-string $value\n     */\n    public static function isUrl($value, array $protocols = [])\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        $protocolList = empty($protocols)\n            ? 'aaa|aaas|about|acap|acct|acd|acr|adiumxtra|adt|afp|afs|aim|amss|android|appdata|apt|ark|attachment|aw|barion|beshare|bitcoin|bitcoincash|blob|bolo|browserext|calculator|callto|cap|cast|casts|chrome|chrome-extension|cid|coap|coap\\+tcp|coap\\+ws|coaps|coaps\\+tcp|coaps\\+ws|com-eventbrite-attendee|content|conti|crid|cvs|dab|data|dav|diaspora|dict|did|dis|dlna-playcontainer|dlna-playsingle|dns|dntp|dpp|drm|drop|dtn|dvb|ed2k|elsi|example|facetime|fax|feed|feedready|file|filesystem|finger|first-run-pen-experience|fish|fm|ftp|fuchsia-pkg|geo|gg|git|gizmoproject|go|gopher|graph|gtalk|h323|ham|hcap|hcp|http|https|hxxp|hxxps|hydrazone|iax|icap|icon|im|imap|info|iotdisco|ipn|ipp|ipps|irc|irc6|ircs|iris|iris\\.beep|iris\\.lwz|iris\\.xpc|iris\\.xpcs|isostore|itms|jabber|jar|jms|keyparc|lastfm|ldap|ldaps|leaptofrogans|lorawan|lvlt|magnet|mailserver|mailto|maps|market|message|mid|mms|modem|mongodb|moz|ms-access|ms-browser-extension|ms-calculator|ms-drive-to|ms-enrollment|ms-excel|ms-eyecontrolspeech|ms-gamebarservices|ms-gamingoverlay|ms-getoffice|ms-help|ms-infopath|ms-inputapp|ms-lockscreencomponent-config|ms-media-stream-id|ms-mixedrealitycapture|ms-mobileplans|ms-officeapp|ms-people|ms-project|ms-powerpoint|ms-publisher|ms-restoretabcompanion|ms-screenclip|ms-screensketch|ms-search|ms-search-repair|ms-secondary-screen-controller|ms-secondary-screen-setup|ms-settings|ms-settings-airplanemode|ms-settings-bluetooth|ms-settings-camera|ms-settings-cellular|ms-settings-cloudstorage|ms-settings-connectabledevices|ms-settings-displays-topology|ms-settings-emailandaccounts|ms-settings-language|ms-settings-location|ms-settings-lock|ms-settings-nfctransactions|ms-settings-notifications|ms-settings-power|ms-settings-privacy|ms-settings-proximity|ms-settings-screenrotation|ms-settings-wifi|ms-settings-workplace|ms-spd|ms-sttoverlay|ms-transit-to|ms-useractivityset|ms-virtualtouchpad|ms-visio|ms-walk-to|ms-whiteboard|ms-whiteboard-cmd|ms-word|msnim|msrp|msrps|mss|mtqp|mumble|mupdate|mvn|news|nfs|ni|nih|nntp|notes|ocf|oid|onenote|onenote-cmd|opaquelocktoken|openpgp4fpr|pack|palm|paparazzi|payto|pkcs11|platform|pop|pres|prospero|proxy|pwid|psyc|pttp|qb|query|redis|rediss|reload|res|resource|rmi|rsync|rtmfp|rtmp|rtsp|rtsps|rtspu|s3|secondlife|service|session|sftp|sgn|shttp|sieve|simpleledger|sip|sips|skype|smb|sms|smtp|snews|snmp|soap\\.beep|soap\\.beeps|soldat|spiffe|spotify|ssh|steam|stun|stuns|submit|svn|tag|teamspeak|tel|teliaeid|telnet|tftp|tg|things|thismessage|tip|tn3270|tool|ts3server|turn|turns|tv|udp|unreal|urn|ut2004|v-event|vemmi|ventrilo|videotex|vnc|view-source|wais|webcal|wpid|ws|wss|wtai|wyciwyg|xcon|xcon-userid|xfire|xmlrpc\\.beep|xmlrpc\\.beeps|xmpp|xri|ymsgr|z39\\.50|z39\\.50r|z39\\.50s'\n            : implode('|', $protocols);\n\n        /*\n         * This pattern is derived from Symfony\\Component\\Validator\\Constraints\\UrlValidator (5.0.7).\n         *\n         * (c) Fabien Potencier <fabien@symfony.com> http://symfony.com\n         */\n        $pattern = '~^\n            (LARAVEL_PROTOCOLS)://                                 # protocol\n            (((?:[\\_\\.\\pL\\pN-]|%[0-9A-Fa-f]{2})+:)?((?:[\\_\\.\\pL\\pN-]|%[0-9A-Fa-f]{2})+)@)?  # basic auth\n            (\n                (?:\n                    (?:\n                        (?:[\\pL\\pN\\pS\\pM\\-\\_]++\\.)+\n                        (?:\n                            (?:xn--[a-z0-9-]++)     # punycode in tld\n                            |\n                            (?:[\\pL\\pN\\pM]++)       # no punycode in tld\n                        )\n                    )                               # a multi-level domain name\n                        |\n                    [a-z0-9\\-\\_]++                  # a single-level domain name\n                )\\.?\n                    |                               # or\n                \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}  # an IP address\n                    |                               # or\n                \\[\n                    (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))\n                \\]  # an IPv6 address\n            )\n            (:[0-9]+)?                              # a port (optional)\n            (?:/ (?:[\\pL\\pN\\-._\\~!$&\\'()*+,;=:@]|%[0-9A-Fa-f]{2})* )*          # a path\n            (?:\\? (?:[\\pL\\pN\\-._\\~!$&\\'\\[\\]()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )?   # a query (optional)\n            (?:\\# (?:[\\pL\\pN\\-._\\~!$&\\'()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )?       # a fragment (optional)\n        $~ixu';\n\n        return preg_match(str_replace('LARAVEL_PROTOCOLS', $protocolList, $pattern), $value) > 0;\n    }\n\n    /**\n     * Determine if a given value is a valid UUID.\n     *\n     * @param  mixed  $value\n     * @param  int<0, 8>|'nil'|'max'|null  $version\n     * @return bool\n     *\n     * @phpstan-assert-if-true =non-empty-string $value\n     */\n    public static function isUuid($value, $version = null)\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        if ($version === null) {\n            return preg_match('/^[\\da-fA-F]{8}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{12}$/D', $value) > 0;\n        }\n\n        $factory = new UuidFactory;\n\n        try {\n            $factoryUuid = $factory->fromString($value);\n        } catch (InvalidUuidStringException) {\n            return false;\n        }\n\n        $fields = $factoryUuid->getFields();\n\n        if (! ($fields instanceof FieldsInterface)) {\n            return false;\n        }\n\n        if ($version === 0 || $version === 'nil') {\n            return $fields->isNil();\n        }\n\n        if ($version === 'max') {\n            return $fields->isMax();\n        }\n\n        return $fields->getVersion() === $version;\n    }\n\n    /**\n     * Determine if a given value is a valid ULID.\n     *\n     * @param  mixed  $value\n     * @return bool\n     *\n     * @phpstan-assert-if-true =non-empty-string $value\n     */\n    public static function isUlid($value)\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        return Ulid::isValid($value);\n    }\n\n    /**\n     * Convert a string to kebab case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : string)\n     */\n    public static function kebab($value)\n    {\n        return static::snake($value, '-');\n    }\n\n    /**\n     * Return the length of the given string.\n     *\n     * @param  string  $value\n     * @param  string|null  $encoding\n     * @return non-negative-int\n     */\n    public static function length($value, $encoding = null)\n    {\n        return mb_strlen($value, $encoding);\n    }\n\n    /**\n     * Limit the number of characters in a string.\n     *\n     * @param  string  $value\n     * @param  int  $limit\n     * @param  string  $end\n     * @param  bool  $preserveWords\n     * @return string\n     */\n    public static function limit($value, $limit = 100, $end = '...', $preserveWords = false)\n    {\n        if (mb_strwidth($value, 'UTF-8') <= $limit) {\n            return $value;\n        }\n\n        if (! $preserveWords) {\n            return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end;\n        }\n\n        $value = trim(preg_replace('/[\\n\\r]+/', ' ', strip_tags($value)));\n\n        $trimmed = rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8'));\n\n        if (mb_substr($value, $limit, 1, 'UTF-8') === ' ') {\n            return $trimmed.$end;\n        }\n\n        return preg_replace(\"/(.*)\\s.*/\", '$1', $trimmed).$end;\n    }\n\n    /**\n     * Convert the given string to lower-case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : non-empty-string&lowercase-string)\n     */\n    public static function lower($value)\n    {\n        return mb_strtolower($value, 'UTF-8');\n    }\n\n    /**\n     * Limit the number of words in a string.\n     *\n     * @param  string  $value\n     * @param  int  $words\n     * @param  string  $end\n     * @return string\n     */\n    public static function words($value, $words = 100, $end = '...')\n    {\n        preg_match('/^\\s*+(?:\\S++\\s*+){1,'.$words.'}/u', $value, $matches);\n\n        if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) {\n            return $value;\n        }\n\n        return rtrim($matches[0]).$end;\n    }\n\n    /**\n     * Converts GitHub flavored Markdown into HTML.\n     *\n     * @param  string  $string\n     * @param  array  $options\n     * @param  \\League\\CommonMark\\Extension\\ExtensionInterface[]  $extensions\n     * @return ($string is '' ? '' : string)\n     */\n    public static function markdown($string, array $options = [], array $extensions = [])\n    {\n        $converter = new GithubFlavoredMarkdownConverter($options);\n\n        $environment = $converter->getEnvironment();\n\n        foreach ($extensions as $extension) {\n            $environment->addExtension($extension);\n        }\n\n        return (string) $converter->convert($string);\n    }\n\n    /**\n     * Converts inline Markdown into HTML.\n     *\n     * @param  string  $string\n     * @param  array  $options\n     * @param  \\League\\CommonMark\\Extension\\ExtensionInterface[]  $extensions\n     * @return ($string is '' ? '' : string)\n     */\n    public static function inlineMarkdown($string, array $options = [], array $extensions = [])\n    {\n        $environment = new Environment($options);\n\n        $environment->addExtension(new GithubFlavoredMarkdownExtension());\n        $environment->addExtension(new InlinesOnlyExtension());\n\n        foreach ($extensions as $extension) {\n            $environment->addExtension($extension);\n        }\n\n        $converter = new MarkdownConverter($environment);\n\n        return (string) $converter->convert($string);\n    }\n\n    /**\n     * Masks a portion of a string with a repeated character.\n     *\n     * @param  string  $string\n     * @param  string  $character\n     * @param  int  $index\n     * @param  int|null  $length\n     * @param  string  $encoding\n     * @return string\n     */\n    public static function mask($string, $character, $index, $length = null, $encoding = 'UTF-8')\n    {\n        if ($character === '') {\n            return $string;\n        }\n\n        $segment = mb_substr($string, $index, $length, $encoding);\n\n        if ($segment === '') {\n            return $string;\n        }\n\n        $strlen = mb_strlen($string, $encoding);\n        $startIndex = $index;\n\n        if ($index < 0) {\n            $startIndex = $index < -$strlen ? 0 : $strlen + $index;\n        }\n\n        $start = mb_substr($string, 0, $startIndex, $encoding);\n        $segmentLen = mb_strlen($segment, $encoding);\n        $end = mb_substr($string, $startIndex + $segmentLen);\n\n        return $start.str_repeat(mb_substr($character, 0, 1, $encoding), $segmentLen).$end;\n    }\n\n    /**\n     * Get the string matching the given pattern.\n     *\n     * @param  string  $pattern\n     * @param  string  $subject\n     * @return string\n     */\n    public static function match($pattern, $subject)\n    {\n        preg_match($pattern, $subject, $matches);\n\n        if (! $matches) {\n            return '';\n        }\n\n        return $matches[1] ?? $matches[0];\n    }\n\n    /**\n     * Determine if a given string matches a given pattern.\n     *\n     * @param  string|iterable<string>  $pattern\n     * @param  string  $value\n     * @return ($pattern is array{} ? false : bool)\n     */\n    public static function isMatch($pattern, $value)\n    {\n        $value = (string) $value;\n\n        if (! is_iterable($pattern)) {\n            $pattern = [$pattern];\n        }\n\n        foreach ($pattern as $pattern) {\n            $pattern = (string) $pattern;\n\n            if (preg_match($pattern, $value) === 1) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the string matching the given pattern.\n     *\n     * @param  string  $pattern\n     * @param  string  $subject\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public static function matchAll($pattern, $subject)\n    {\n        preg_match_all($pattern, $subject, $matches);\n\n        if (empty($matches[0])) {\n            return new Collection;\n        }\n\n        return new Collection($matches[1] ?? $matches[0]);\n    }\n\n    /**\n     * Remove all non-numeric characters from a string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function numbers($value)\n    {\n        return preg_replace('/[^0-9]/', '', $value);\n    }\n\n    /**\n     * Pad both sides of a string with another.\n     *\n     * @param  string  $value\n     * @param  int  $length\n     * @param  string  $pad\n     * @return string\n     */\n    public static function padBoth($value, $length, $pad = ' ')\n    {\n        return mb_str_pad($value, $length, $pad, STR_PAD_BOTH);\n    }\n\n    /**\n     * Pad the left side of a string with another.\n     *\n     * @param  string  $value\n     * @param  int  $length\n     * @param  string  $pad\n     * @return string\n     */\n    public static function padLeft($value, $length, $pad = ' ')\n    {\n        return mb_str_pad($value, $length, $pad, STR_PAD_LEFT);\n    }\n\n    /**\n     * Pad the right side of a string with another.\n     *\n     * @param  string  $value\n     * @param  int  $length\n     * @param  string  $pad\n     * @return string\n     */\n    public static function padRight($value, $length, $pad = ' ')\n    {\n        return mb_str_pad($value, $length, $pad, STR_PAD_RIGHT);\n    }\n\n    /**\n     * Parse a Class[@]method style callback into class and method.\n     *\n     * @param  string  $callback\n     * @param  string|null  $default\n     * @return array<int, string|null>\n     */\n    public static function parseCallback($callback, $default = null)\n    {\n        if (static::contains($callback, \"@anonymous\\0\")) {\n            if (static::substrCount($callback, '@') > 1) {\n                return [\n                    static::beforeLast($callback, '@'),\n                    static::afterLast($callback, '@'),\n                ];\n            }\n\n            return [$callback, $default];\n        }\n\n        return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];\n    }\n\n    /**\n     * Get the plural form of an English word.\n     *\n     * @param  string  $value\n     * @param  int|array|\\Countable  $count\n     * @param  bool  $prependCount\n     * @return string\n     */\n    public static function plural($value, $count = 2, $prependCount = false)\n    {\n        if (is_countable($count)) {\n            $count = count($count);\n        }\n\n        return ($prependCount ? Number::format($count).' ' : '').Pluralizer::plural($value, $count);\n    }\n\n    /**\n     * Pluralize the last word of an English, studly caps case string.\n     *\n     * @param  string  $value\n     * @param  int|array|\\Countable  $count\n     * @return string\n     */\n    public static function pluralStudly($value, $count = 2)\n    {\n        $parts = preg_split('/(.)(?=[A-Z])/u', $value, -1, PREG_SPLIT_DELIM_CAPTURE);\n\n        $lastWord = array_pop($parts);\n\n        return implode('', $parts).self::plural($lastWord, $count);\n    }\n\n    /**\n     * Pluralize the last word of an English, Pascal caps case string.\n     *\n     * @param  string  $value\n     * @param  int|array|\\Countable  $count\n     * @return string\n     */\n    public static function pluralPascal($value, $count = 2)\n    {\n        return static::pluralStudly($value, $count);\n    }\n\n    /**\n     * Generate a random, secure password.\n     *\n     * @param  int  $length\n     * @param  bool  $letters\n     * @param  bool  $numbers\n     * @param  bool  $symbols\n     * @param  bool  $spaces\n     * @return ($letters is false ? ($numbers is true ? ($symbols is false ? ($spaces is false ? numeric-string : string) : string) : string) : string)\n     */\n    public static function password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false)\n    {\n        $password = new Collection();\n\n        $options = (new Collection([\n            'letters' => $letters === true ? [\n                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',\n                'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',\n                'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',\n                'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',\n                'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n            ] : null,\n            'numbers' => $numbers === true ? [\n                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n            ] : null,\n            'symbols' => $symbols === true ? [\n                '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-',\n                '_', '.', ',', '<', '>', '?', '/', '\\\\', '{', '}', '[',\n                ']', '|', ':', ';',\n            ] : null,\n            'spaces' => $spaces === true ? [' '] : null,\n        ]))\n            ->filter()\n            ->each(fn ($c) => $password->push($c[random_int(0, count($c) - 1)]))\n            ->flatten();\n\n        $length = $length - $password->count();\n\n        return $password->merge($options->pipe(\n            fn ($c) => Collection::times($length, fn () => $c[random_int(0, $c->count() - 1)])\n        ))->shuffle()->implode('');\n    }\n\n    /**\n     * Find the multi-byte safe position of the first occurrence of a given substring in a string.\n     *\n     * @param  string  $haystack\n     * @param  string  $needle\n     * @param  int  $offset\n     * @param  string|null  $encoding\n     * @return ($haystack is '' ? false : ($needle is '' ? false : int|false))\n     */\n    public static function position($haystack, $needle, $offset = 0, $encoding = null)\n    {\n        return mb_strpos($haystack, (string) $needle, $offset, $encoding);\n    }\n\n    /**\n     * Generate a more truly \"random\" alpha-numeric string.\n     *\n     * @param  int  $length\n     * @return string\n     */\n    public static function random($length = 16)\n    {\n        return (static::$randomStringFactory ?? function ($length) {\n            $string = '';\n\n            while (($len = strlen($string)) < $length) {\n                $size = $length - $len;\n\n                $bytesSize = (int) ceil($size / 3) * 3;\n\n                $bytes = random_bytes($bytesSize);\n\n                $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);\n            }\n\n            return $string;\n        })($length);\n    }\n\n    /**\n     * Set the callable that will be used to generate random strings.\n     *\n     * @param  (callable(int): string)|null  $factory\n     * @return void\n     */\n    public static function createRandomStringsUsing(?callable $factory = null)\n    {\n        static::$randomStringFactory = $factory;\n    }\n\n    /**\n     * Set the sequence that will be used to generate random strings.\n     *\n     * @param  string[]  $sequence\n     * @param  (callable(int): string)|null  $whenMissing\n     * @return void\n     */\n    public static function createRandomStringsUsingSequence(array $sequence, $whenMissing = null)\n    {\n        $next = 0;\n\n        $whenMissing ??= function ($length) use (&$next) {\n            $factoryCache = static::$randomStringFactory;\n\n            static::$randomStringFactory = null;\n\n            $randomString = static::random($length);\n\n            static::$randomStringFactory = $factoryCache;\n\n            $next++;\n\n            return $randomString;\n        };\n\n        static::createRandomStringsUsing(function ($length) use (&$next, $sequence, $whenMissing) {\n            if (array_key_exists($next, $sequence)) {\n                return $sequence[$next++];\n            }\n\n            return $whenMissing($length);\n        });\n    }\n\n    /**\n     * Indicate that random strings should be created normally and not using a custom factory.\n     *\n     * @return void\n     */\n    public static function createRandomStringsNormally()\n    {\n        static::$randomStringFactory = null;\n    }\n\n    /**\n     * Repeat the given string.\n     *\n     * @param  string  $string\n     * @param  int  $times\n     * @return string\n     */\n    public static function repeat(string $string, int $times)\n    {\n        return str_repeat($string, $times);\n    }\n\n    /**\n     * Replace a given value in the string sequentially with an array.\n     *\n     * @param  string  $search\n     * @param  iterable<string>  $replace\n     * @param  string  $subject\n     * @return string\n     */\n    public static function replaceArray($search, $replace, $subject)\n    {\n        if ($replace instanceof Traversable) {\n            $replace = Arr::from($replace);\n        }\n\n        $segments = explode($search, $subject);\n\n        $result = array_shift($segments);\n\n        foreach ($segments as $segment) {\n            $result .= self::toStringOr(array_shift($replace) ?? $search, $search).$segment;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Convert the given value to a string or return the given fallback on failure.\n     *\n     * @param  mixed  $value\n     * @param  string  $fallback\n     * @return string\n     */\n    private static function toStringOr($value, $fallback)\n    {\n        try {\n            return (string) $value;\n        } catch (Throwable $e) {\n            return $fallback;\n        }\n    }\n\n    /**\n     * Replace the given value in the given string.\n     *\n     * @param  string|iterable<string>  $search\n     * @param  string|iterable<string>  $replace\n     * @param  string|iterable<string>  $subject\n     * @param  bool  $caseSensitive\n     * @return ($subject is string ? string : string[])\n     */\n    public static function replace($search, $replace, $subject, $caseSensitive = true)\n    {\n        if ($search instanceof Traversable) {\n            $search = Arr::from($search);\n        }\n\n        if ($replace instanceof Traversable) {\n            $replace = Arr::from($replace);\n        }\n\n        if ($subject instanceof Traversable) {\n            $subject = Arr::from($subject);\n        }\n\n        return $caseSensitive\n            ? str_replace($search, $replace, $subject)\n            : str_ireplace($search, $replace, $subject);\n    }\n\n    /**\n     * Replace the first occurrence of a given value in the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @param  string  $subject\n     * @return string\n     */\n    public static function replaceFirst($search, $replace, $subject)\n    {\n        $search = (string) $search;\n\n        if ($search === '') {\n            return $subject;\n        }\n\n        $position = strpos($subject, $search);\n\n        if ($position !== false) {\n            return substr_replace($subject, $replace, $position, strlen($search));\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Replace the first occurrence of the given value if it appears at the start of the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @param  string  $subject\n     * @return string\n     */\n    public static function replaceStart($search, $replace, $subject)\n    {\n        $search = (string) $search;\n\n        if ($search === '') {\n            return $subject;\n        }\n\n        if (static::startsWith($subject, $search)) {\n            return static::replaceFirst($search, $replace, $subject);\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Replace the last occurrence of a given value in the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @param  string  $subject\n     * @return string\n     */\n    public static function replaceLast($search, $replace, $subject)\n    {\n        $search = (string) $search;\n\n        if ($search === '') {\n            return $subject;\n        }\n\n        $position = strrpos($subject, $search);\n\n        if ($position !== false) {\n            return substr_replace($subject, $replace, $position, strlen($search));\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Replace the last occurrence of a given value if it appears at the end of the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @param  string  $subject\n     * @return string\n     */\n    public static function replaceEnd($search, $replace, $subject)\n    {\n        $search = (string) $search;\n\n        if ($search === '') {\n            return $subject;\n        }\n\n        if (static::endsWith($subject, $search)) {\n            return static::replaceLast($search, $replace, $subject);\n        }\n\n        return $subject;\n    }\n\n    /**\n     * Replace the patterns matching the given regular expression.\n     *\n     * @param  string|string[]  $pattern\n     * @param  (\\Closure(array): string)|string[]|string  $replace\n     * @param  string[]|string  $subject\n     * @param  int  $limit\n     * @return ($subject is array ? string[]|null : string|null)\n     */\n    public static function replaceMatches($pattern, $replace, $subject, $limit = -1)\n    {\n        if ($replace instanceof Closure) {\n            return preg_replace_callback($pattern, $replace, $subject, $limit);\n        }\n\n        return preg_replace($pattern, $replace, $subject, $limit);\n    }\n\n    /**\n     * Remove any occurrence of the given string in the subject.\n     *\n     * @param  string|iterable<string>  $search\n     * @param  string|iterable<string>  $subject\n     * @param  bool  $caseSensitive\n     * @return string\n     */\n    public static function remove($search, $subject, $caseSensitive = true)\n    {\n        if ($search instanceof Traversable) {\n            $search = Arr::from($search);\n        }\n\n        return $caseSensitive\n            ? str_replace($search, '', $subject)\n            : str_ireplace($search, '', $subject);\n    }\n\n    /**\n     * Reverse the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function reverse(string $value)\n    {\n        return implode(array_reverse(mb_str_split($value)));\n    }\n\n    /**\n     * Begin a string with a single instance of a given value.\n     *\n     * @param  string  $value\n     * @param  string  $prefix\n     * @return ($value is '' ? ($prefix is '' ? '' : non-empty-string): non-empty-string)\n     */\n    public static function start($value, $prefix)\n    {\n        $quoted = preg_quote($prefix, '/');\n\n        return $prefix.preg_replace('/^(?:'.$quoted.')+/u', '', $value);\n    }\n\n    /**\n     * Convert the given string to upper-case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : non-empty-string&uppercase-string)\n     */\n    public static function upper($value)\n    {\n        return mb_strtoupper($value, 'UTF-8');\n    }\n\n    /**\n     * Convert the given string to proper case.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function title($value)\n    {\n        return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');\n    }\n\n    /**\n     * Convert the given string to proper case for each word.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function headline($value)\n    {\n        $parts = mb_split('\\s+', $value);\n\n        $parts = count($parts) > 1\n            ? array_map(static::title(...), $parts)\n            : array_map(static::title(...), static::ucsplit(implode('_', $parts)));\n\n        $collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts));\n\n        return implode(' ', array_filter(explode('_', $collapsed)));\n    }\n\n    /**\n     * Get the \"initials\" representing each word in the provided string, optionally capitalizing.\n     *\n     * @param  string  $value\n     * @param  bool  $capitalize\n     * @return string\n     */\n    public static function initials($value, $capitalize = false)\n    {\n        $parts = mb_split(\"\\s+\", $value);\n\n        $parts = array_map(fn ($part) => mb_substr($part, 0, 1), $parts);\n\n        $initials = implode('', $parts);\n\n        return $capitalize ? static::upper($initials) : $initials;\n    }\n\n    /**\n     * Convert the given string to APA-style title case.\n     *\n     * See: https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function apa($value)\n    {\n        if (trim($value) === '') {\n            return $value;\n        }\n\n        $minorWords = [\n            'and', 'as', 'but', 'for', 'if', 'nor', 'or', 'so', 'yet', 'a', 'an',\n            'the', 'at', 'by', 'in', 'of', 'off', 'on', 'per', 'to', 'up', 'via',\n            'et', 'ou', 'un', 'une', 'la', 'le', 'les', 'de', 'du', 'des', 'par', 'à',\n        ];\n\n        $endPunctuation = ['.', '!', '?', ':', '—', ','];\n\n        $words = mb_split('\\s+', $value);\n        $wordCount = count($words);\n\n        for ($i = 0; $i < $wordCount; $i++) {\n            $lowercaseWord = mb_strtolower($words[$i]);\n\n            if (str_contains($lowercaseWord, '-')) {\n                $hyphenatedWords = explode('-', $lowercaseWord);\n\n                $hyphenatedWords = array_map(function ($part) use ($minorWords) {\n                    return (in_array($part, $minorWords) && mb_strlen($part) <= 3)\n                        ? $part\n                        : mb_strtoupper(mb_substr($part, 0, 1)).mb_substr($part, 1);\n                }, $hyphenatedWords);\n\n                $words[$i] = implode('-', $hyphenatedWords);\n            } else {\n                if (in_array($lowercaseWord, $minorWords) &&\n                    mb_strlen($lowercaseWord) <= 3 &&\n                    ! ($i === 0 || in_array(mb_substr($words[$i - 1], -1), $endPunctuation))) {\n                    $words[$i] = $lowercaseWord;\n                } else {\n                    $words[$i] = mb_strtoupper(mb_substr($lowercaseWord, 0, 1)).mb_substr($lowercaseWord, 1);\n                }\n            }\n        }\n\n        return implode(' ', $words);\n    }\n\n    /**\n     * Get the singular form of an English word.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function singular($value)\n    {\n        return Pluralizer::singular($value);\n    }\n\n    /**\n     * Generate a URL friendly \"slug\" from a given string.\n     *\n     * @param  string  $title\n     * @param  string  $separator\n     * @param  string|null  $language\n     * @param  array<string, string>  $dictionary\n     * @return string\n     */\n    public static function slug($title, $separator = '-', $language = 'en', $dictionary = ['@' => 'at'])\n    {\n        $title = $language ? static::ascii($title, $language) : $title;\n\n        // Convert all dashes/underscores into separator\n        $flip = $separator === '-' ? '_' : '-';\n\n        $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);\n\n        // Replace dictionary words\n        foreach ($dictionary as $key => $value) {\n            $dictionary[$key] = $separator.$value.$separator;\n        }\n\n        $title = str_replace(array_keys($dictionary), array_values($dictionary), $title);\n\n        // Remove all characters that are not the separator, letters, numbers, or whitespace\n        $title = preg_replace('![^'.preg_quote($separator).'\\pL\\pN\\s]+!u', '', static::lower($title));\n\n        // Replace all separator characters and whitespace by a single separator\n        $title = preg_replace('!['.preg_quote($separator).'\\s]+!u', $separator, $title);\n\n        return trim($title, $separator);\n    }\n\n    /**\n     * Convert a string to snake case.\n     *\n     * @param  string  $value\n     * @param  string  $delimiter\n     * @return string\n     */\n    public static function snake($value, $delimiter = '_')\n    {\n        $key = $value;\n\n        if (isset(static::$snakeCache[$key][$delimiter])) {\n            return static::$snakeCache[$key][$delimiter];\n        }\n\n        if (! ctype_lower($value)) {\n            $value = preg_replace('/\\s+/u', '', ucwords($value));\n\n            $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));\n        }\n\n        return static::$snakeCache[$key][$delimiter] = $value;\n    }\n\n    /**\n     * Remove all whitespace from both ends of a string.\n     *\n     * @param  string  $value\n     * @param  string|null  $charlist\n     * @return string\n     */\n    public static function trim($value, $charlist = null)\n    {\n        if ($charlist === null) {\n            $trimDefaultCharacters = \" \\n\\r\\t\\v\\0\";\n\n            return preg_replace('~^[\\s'.self::INVISIBLE_CHARACTERS.$trimDefaultCharacters.']+|[\\s'.self::INVISIBLE_CHARACTERS.$trimDefaultCharacters.']+$~u', '', $value) ?? trim($value);\n        }\n\n        return trim($value, $charlist);\n    }\n\n    /**\n     * Remove all whitespace from the beginning of a string.\n     *\n     * @param  string  $value\n     * @param  string|null  $charlist\n     * @return string\n     */\n    public static function ltrim($value, $charlist = null)\n    {\n        if ($charlist === null) {\n            $ltrimDefaultCharacters = \" \\n\\r\\t\\v\\0\";\n\n            return preg_replace('~^[\\s'.self::INVISIBLE_CHARACTERS.$ltrimDefaultCharacters.']+~u', '', $value) ?? ltrim($value);\n        }\n\n        return ltrim($value, $charlist);\n    }\n\n    /**\n     * Remove all whitespace from the end of a string.\n     *\n     * @param  string  $value\n     * @param  string|null  $charlist\n     * @return string\n     */\n    public static function rtrim($value, $charlist = null)\n    {\n        if ($charlist === null) {\n            $rtrimDefaultCharacters = \" \\n\\r\\t\\v\\0\";\n\n            return preg_replace('~[\\s'.self::INVISIBLE_CHARACTERS.$rtrimDefaultCharacters.']+$~u', '', $value) ?? rtrim($value);\n        }\n\n        return rtrim($value, $charlist);\n    }\n\n    /**\n     * Remove all \"extra\" blank space from the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public static function squish($value)\n    {\n        return preg_replace('~(\\s|\\x{3164}|\\x{1160})+~u', ' ', static::trim($value));\n    }\n\n    /**\n     * Determine if a given string starts with a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @return ($needles is array{} ? false : ($haystack is non-empty-string ? bool : false))\n     *\n     * @phpstan-assert-if-true =non-empty-string $haystack\n     */\n    public static function startsWith($haystack, $needles)\n    {\n        if (is_null($haystack)) {\n            return false;\n        }\n\n        if (! is_iterable($needles)) {\n            $needles = [$needles];\n        }\n\n        foreach ($needles as $needle) {\n            if ((string) $needle !== '' && str_starts_with($haystack, $needle)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if a given string doesn't start with a given substring.\n     *\n     * @param  string  $haystack\n     * @param  string|iterable<string>  $needles\n     * @return ($needles is array{} ? true : ($haystack is non-empty-string ? bool : true))\n     *\n     * @phpstan-assert-if-false =non-empty-string $haystack\n     */\n    public static function doesntStartWith($haystack, $needles)\n    {\n        return ! static::startsWith($haystack, $needles);\n    }\n\n    /**\n     * Convert a value to studly caps case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : string)\n     */\n    public static function studly($value)\n    {\n        $key = $value;\n\n        if (isset(static::$studlyCache[$key])) {\n            return static::$studlyCache[$key];\n        }\n\n        $words = mb_split('\\s+', static::replace(['-', '_'], ' ', $value));\n\n        $studlyWords = array_map(fn ($word) => static::ucfirst($word), $words);\n\n        return static::$studlyCache[$key] = implode($studlyWords);\n    }\n\n    /**\n     * Convert a value to Pascal case.\n     *\n     * @param  string  $value\n     * @return ($value is '' ? '' : string)\n     */\n    public static function pascal($value)\n    {\n        return static::studly($value);\n    }\n\n    /**\n     * Returns the portion of the string specified by the start and length parameters.\n     *\n     * @param  string  $string\n     * @param  int  $start\n     * @param  int|null  $length\n     * @param  string  $encoding\n     * @return string\n     */\n    public static function substr($string, $start, $length = null, $encoding = 'UTF-8')\n    {\n        return mb_substr($string, $start, $length, $encoding);\n    }\n\n    /**\n     * Returns the number of substring occurrences.\n     *\n     * @param  string  $haystack\n     * @param  string  $needle\n     * @param  int  $offset\n     * @param  int|null  $length\n     * @return int\n     */\n    public static function substrCount($haystack, $needle, $offset = 0, $length = null)\n    {\n        if (! is_null($length)) {\n            return substr_count($haystack, $needle, $offset, $length);\n        }\n\n        return substr_count($haystack, $needle, $offset);\n    }\n\n    /**\n     * Replace text within a portion of a string.\n     *\n     * @param  string|string[]  $string\n     * @param  string|string[]  $replace\n     * @param  int|int[]  $offset\n     * @param  int|int[]|null  $length\n     * @return string|string[]\n     */\n    public static function substrReplace($string, $replace, $offset = 0, $length = null)\n    {\n        if ($length === null) {\n            $length = static::length($string);\n        }\n\n        return mb_substr($string, 0, $offset)\n            .$replace\n            .mb_substr(mb_substr($string, $offset), $length);\n    }\n\n    /**\n     * Swap multiple keywords in a string with other keywords.\n     *\n     * @param  array<string, string>  $map\n     * @param  string  $subject\n     * @return string\n     */\n    public static function swap(array $map, $subject)\n    {\n        return strtr($subject, $map);\n    }\n\n    /**\n     * Take the first or last {$limit} characters of a string.\n     *\n     * @param  string  $string\n     * @param  int  $limit\n     * @return string\n     */\n    public static function take($string, int $limit): string\n    {\n        if ($limit < 0) {\n            return static::substr($string, $limit);\n        }\n\n        return static::substr($string, 0, $limit);\n    }\n\n    /**\n     * Convert the given string to Base64 encoding.\n     *\n     * @param  string  $string\n     * @return ($string is '' ? '' : string)\n     */\n    public static function toBase64($string): string\n    {\n        return base64_encode($string);\n    }\n\n    /**\n     * Decode the given Base64 encoded string.\n     *\n     * @param  string  $string\n     * @param  bool  $strict\n     * @return ($strict is true ? ($string is '' ? '' : string|false) : ($string is '' ? '' : string))\n     */\n    public static function fromBase64($string, $strict = false)\n    {\n        return base64_decode($string, $strict);\n    }\n\n    /**\n     * Make a string's first character lowercase.\n     *\n     * @param  string  $string\n     * @return ($string is '' ? '' : non-empty-string)\n     */\n    public static function lcfirst($string)\n    {\n        return static::lower(static::substr($string, 0, 1)).static::substr($string, 1);\n    }\n\n    /**\n     * Make a string's first character uppercase.\n     *\n     * @param  string  $string\n     * @return ($string is '' ? '' : non-empty-string)\n     */\n    public static function ucfirst($string)\n    {\n        return static::upper(static::substr($string, 0, 1)).static::substr($string, 1);\n    }\n\n    /**\n     * Capitalize the first character of each word in a string.\n     *\n     * @param  string  $string\n     * @param  string  $separators\n     * @return ($string is '' ? '' : non-empty-string)\n     */\n    public static function ucwords($string, $separators = \" \\t\\r\\n\\f\\v\")\n    {\n        $pattern = '/(^|['.preg_quote($separators, '/').'])(\\p{Ll})/u';\n\n        return preg_replace_callback($pattern, function ($matches) {\n            return $matches[1].mb_strtoupper($matches[2]);\n        }, $string);\n    }\n\n    /**\n     * Split a string into pieces by uppercase characters.\n     *\n     * @param  string  $string\n     * @return ($string is '' ? array{} : string[])\n     */\n    public static function ucsplit($string)\n    {\n        return preg_split('/(?=\\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY);\n    }\n\n    /**\n     * Get the number of words a string contains.\n     *\n     * @param  string  $string\n     * @param  string|null  $characters\n     * @return non-negative-int\n     */\n    public static function wordCount($string, $characters = null)\n    {\n        return str_word_count($string, 0, $characters);\n    }\n\n    /**\n     * Wrap a string to a given number of characters.\n     *\n     * @param  string  $string\n     * @param  int  $characters\n     * @param  string  $break\n     * @param  bool  $cutLongWords\n     * @return string\n     */\n    public static function wordWrap($string, $characters = 75, $break = \"\\n\", $cutLongWords = false)\n    {\n        return wordwrap($string, $characters, $break, $cutLongWords);\n    }\n\n    /**\n     * Generate a UUID (version 4).\n     *\n     * @return \\Ramsey\\Uuid\\UuidInterface\n     */\n    public static function uuid()\n    {\n        return static::$uuidFactory\n            ? call_user_func(static::$uuidFactory)\n            : Uuid::uuid4();\n    }\n\n    /**\n     * Generate a UUID (version 7).\n     *\n     * @param  \\DateTimeInterface|null  $time\n     * @return \\Ramsey\\Uuid\\UuidInterface\n     */\n    public static function uuid7($time = null)\n    {\n        return static::$uuidFactory\n            ? call_user_func(static::$uuidFactory)\n            : Uuid::uuid7($time);\n    }\n\n    /**\n     * Generate a time-ordered UUID.\n     *\n     * @return \\Ramsey\\Uuid\\UuidInterface\n     */\n    public static function orderedUuid()\n    {\n        if (static::$uuidFactory) {\n            return call_user_func(static::$uuidFactory);\n        }\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        return $factory->uuid4();\n    }\n\n    /**\n     * Set the callable that will be used to generate UUIDs.\n     *\n     * @param  (callable(): \\Ramsey\\Uuid\\UuidInterface)|null  $factory\n     * @return void\n     */\n    public static function createUuidsUsing(?callable $factory = null)\n    {\n        static::$uuidFactory = $factory;\n    }\n\n    /**\n     * Set the sequence that will be used to generate UUIDs.\n     *\n     * @param  \\Ramsey\\Uuid\\UuidInterface[]  $sequence\n     * @param  (callable(): \\Ramsey\\Uuid\\UuidInterface)|null  $whenMissing\n     * @return void\n     */\n    public static function createUuidsUsingSequence(array $sequence, $whenMissing = null)\n    {\n        $next = 0;\n\n        $whenMissing ??= function () use (&$next) {\n            $factoryCache = static::$uuidFactory;\n\n            static::$uuidFactory = null;\n\n            $uuid = static::uuid();\n\n            static::$uuidFactory = $factoryCache;\n\n            $next++;\n\n            return $uuid;\n        };\n\n        static::createUuidsUsing(function () use (&$next, $sequence, $whenMissing) {\n            if (array_key_exists($next, $sequence)) {\n                return $sequence[$next++];\n            }\n\n            return $whenMissing();\n        });\n    }\n\n    /**\n     * Always return the same UUID when generating new UUIDs.\n     *\n     * @param  (\\Closure(\\Ramsey\\Uuid\\UuidInterface): mixed)|null  $callback\n     * @return \\Ramsey\\Uuid\\UuidInterface\n     */\n    public static function freezeUuids(?Closure $callback = null)\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(fn () => $uuid);\n\n        if ($callback !== null) {\n            try {\n                $callback($uuid);\n            } finally {\n                Str::createUuidsNormally();\n            }\n        }\n\n        return $uuid;\n    }\n\n    /**\n     * Indicate that UUIDs should be created normally and not using a custom factory.\n     *\n     * @return void\n     */\n    public static function createUuidsNormally()\n    {\n        static::$uuidFactory = null;\n    }\n\n    /**\n     * Generate a ULID.\n     *\n     * @param  \\DateTimeInterface|null  $time\n     * @return \\Symfony\\Component\\Uid\\Ulid\n     */\n    public static function ulid($time = null)\n    {\n        if (static::$ulidFactory) {\n            return call_user_func(static::$ulidFactory);\n        }\n\n        if ($time === null) {\n            return new Ulid();\n        }\n\n        return new Ulid(Ulid::generate($time));\n    }\n\n    /**\n     * Indicate that ULIDs should be created normally and not using a custom factory.\n     *\n     * @return void\n     */\n    public static function createUlidsNormally()\n    {\n        static::$ulidFactory = null;\n    }\n\n    /**\n     * Set the callable that will be used to generate ULIDs.\n     *\n     * @param  (callable(): \\Symfony\\Component\\Uid\\Ulid)|null  $factory\n     * @return void\n     */\n    public static function createUlidsUsing(?callable $factory = null)\n    {\n        static::$ulidFactory = $factory;\n    }\n\n    /**\n     * Set the sequence that will be used to generate ULIDs.\n     *\n     * @param  \\Symfony\\Component\\Uid\\Ulid[]  $sequence\n     * @param  (callable(): \\Symfony\\Component\\Uid\\Ulid)|null  $whenMissing\n     * @return void\n     */\n    public static function createUlidsUsingSequence(array $sequence, $whenMissing = null)\n    {\n        $next = 0;\n\n        $whenMissing ??= function () use (&$next) {\n            $factoryCache = static::$ulidFactory;\n\n            static::$ulidFactory = null;\n\n            $ulid = static::ulid();\n\n            static::$ulidFactory = $factoryCache;\n\n            $next++;\n\n            return $ulid;\n        };\n\n        static::createUlidsUsing(function () use (&$next, $sequence, $whenMissing) {\n            if (array_key_exists($next, $sequence)) {\n                return $sequence[$next++];\n            }\n\n            return $whenMissing();\n        });\n    }\n\n    /**\n     * Always return the same ULID when generating new ULIDs.\n     *\n     * @param  (Closure(Ulid): mixed)|null  $callback\n     * @return Ulid\n     */\n    public static function freezeUlids(?Closure $callback = null)\n    {\n        $ulid = Str::ulid();\n\n        Str::createUlidsUsing(fn () => $ulid);\n\n        if ($callback !== null) {\n            try {\n                $callback($ulid);\n            } finally {\n                Str::createUlidsNormally();\n            }\n        }\n\n        return $ulid;\n    }\n\n    /**\n     * Remove all strings from the casing caches.\n     *\n     * @return void\n     */\n    public static function flushCache()\n    {\n        static::$snakeCache = [];\n        static::$camelCache = [];\n        static::$studlyCache = [];\n    }\n\n    /**\n     * Return all factory functions to their default state.\n     *\n     * @return void\n     */\n    public static function resetFactoryState()\n    {\n        static::createRandomStringsNormally();\n        static::createUlidsNormally();\n        static::createUuidsNormally();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Stringable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayAccess;\nuse Closure;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse JsonSerializable;\nuse Stringable as BaseStringable;\n\nclass Stringable implements JsonSerializable, ArrayAccess, BaseStringable\n{\n    use Conditionable, Dumpable, Macroable, Tappable;\n\n    /**\n     * The underlying string value.\n     *\n     * @var string\n     */\n    protected $value;\n\n    /**\n     * Create a new instance of the class.\n     *\n     * @param  string  $value\n     */\n    public function __construct($value = '')\n    {\n        $this->value = (string) $value;\n    }\n\n    /**\n     * Return the remainder of a string after the first occurrence of a given value.\n     *\n     * @param  string  $search\n     * @return static\n     */\n    public function after($search)\n    {\n        return new static(Str::after($this->value, $search));\n    }\n\n    /**\n     * Return the remainder of a string after the last occurrence of a given value.\n     *\n     * @param  string  $search\n     * @return static\n     */\n    public function afterLast($search)\n    {\n        return new static(Str::afterLast($this->value, $search));\n    }\n\n    /**\n     * Append the given values to the string.\n     *\n     * @param  array|string  ...$values\n     * @return static\n     */\n    public function append(...$values)\n    {\n        return new static($this->value.implode('', $values));\n    }\n\n    /**\n     * Append a new line to the string.\n     *\n     * @param  int  $count\n     * @return $this\n     */\n    public function newLine($count = 1)\n    {\n        return $this->append(str_repeat(PHP_EOL, $count));\n    }\n\n    /**\n     * Transliterate a UTF-8 value to ASCII.\n     *\n     * @param  string  $language\n     * @return static\n     */\n    public function ascii($language = 'en')\n    {\n        return new static(Str::ascii($this->value, $language));\n    }\n\n    /**\n     * Get the trailing name component of the path.\n     *\n     * @param  string  $suffix\n     * @return static\n     */\n    public function basename($suffix = '')\n    {\n        return new static(basename($this->value, $suffix));\n    }\n\n    /**\n     * Get the character at the specified index.\n     *\n     * @param  int  $index\n     * @return string|false\n     */\n    public function charAt($index)\n    {\n        return Str::charAt($this->value, $index);\n    }\n\n    /**\n     * Remove the given string if it exists at the start of the current string.\n     *\n     * @param  string|array  $needle\n     * @return static\n     */\n    public function chopStart($needle)\n    {\n        return new static(Str::chopStart($this->value, $needle));\n    }\n\n    /**\n     * Remove the given string if it exists at the end of the current string.\n     *\n     * @param  string|array  $needle\n     * @return static\n     */\n    public function chopEnd($needle)\n    {\n        return new static(Str::chopEnd($this->value, $needle));\n    }\n\n    /**\n     * Get the basename of the class path.\n     *\n     * @return static\n     */\n    public function classBasename()\n    {\n        return new static(class_basename($this->value));\n    }\n\n    /**\n     * Get the portion of a string before the first occurrence of a given value.\n     *\n     * @param  string  $search\n     * @return static\n     */\n    public function before($search)\n    {\n        return new static(Str::before($this->value, $search));\n    }\n\n    /**\n     * Get the portion of a string before the last occurrence of a given value.\n     *\n     * @param  string  $search\n     * @return static\n     */\n    public function beforeLast($search)\n    {\n        return new static(Str::beforeLast($this->value, $search));\n    }\n\n    /**\n     * Get the portion of a string between two given values.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return static\n     */\n    public function between($from, $to)\n    {\n        return new static(Str::between($this->value, $from, $to));\n    }\n\n    /**\n     * Get the smallest possible portion of a string between two given values.\n     *\n     * @param  string  $from\n     * @param  string  $to\n     * @return static\n     */\n    public function betweenFirst($from, $to)\n    {\n        return new static(Str::betweenFirst($this->value, $from, $to));\n    }\n\n    /**\n     * Convert a value to camel case.\n     *\n     * @return static\n     */\n    public function camel()\n    {\n        return new static(Str::camel($this->value));\n    }\n\n    /**\n     * Determine if a given string contains a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return bool\n     */\n    public function contains($needles, $ignoreCase = false)\n    {\n        return Str::contains($this->value, $needles, $ignoreCase);\n    }\n\n    /**\n     * Determine if a given string contains all array values.\n     *\n     * @param  iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return bool\n     */\n    public function containsAll($needles, $ignoreCase = false)\n    {\n        return Str::containsAll($this->value, $needles, $ignoreCase);\n    }\n\n    /**\n     * Determine if a given string doesn't contain a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  bool  $ignoreCase\n     * @return bool\n     */\n    public function doesntContain($needles, $ignoreCase = false)\n    {\n        return Str::doesntContain($this->value, $needles, $ignoreCase);\n    }\n\n    /**\n     * Convert the case of a string.\n     *\n     * @param  int  $mode\n     * @param  string|null  $encoding\n     * @return static\n     */\n    public function convertCase(int $mode = MB_CASE_FOLD, ?string $encoding = 'UTF-8')\n    {\n        return new static(Str::convertCase($this->value, $mode, $encoding));\n    }\n\n    /**\n     * Replace consecutive instances of a given character with a single character.\n     *\n     * @param  array<string>|string  $characters\n     * @return static\n     */\n    public function deduplicate(array|string $characters = ' ')\n    {\n        return new static(Str::deduplicate($this->value, $characters));\n    }\n\n    /**\n     * Get the parent directory's path.\n     *\n     * @param  int  $levels\n     * @return static\n     */\n    public function dirname($levels = 1)\n    {\n        return new static(dirname($this->value, $levels));\n    }\n\n    /**\n     * Determine if a given string ends with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @return bool\n     */\n    public function endsWith($needles)\n    {\n        return Str::endsWith($this->value, $needles);\n    }\n\n    /**\n     * Determine if a given string doesn't end with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @return bool\n     */\n    public function doesntEndWith($needles)\n    {\n        return Str::doesntEndWith($this->value, $needles);\n    }\n\n    /**\n     * Determine if the string is an exact match with the given value.\n     *\n     * @param  \\Illuminate\\Support\\Stringable|string  $value\n     * @return bool\n     */\n    public function exactly($value)\n    {\n        if ($value instanceof Stringable) {\n            $value = $value->toString();\n        }\n\n        return $this->value === $value;\n    }\n\n    /**\n     * Extracts an excerpt from text that matches the first instance of a phrase.\n     *\n     * @param  string  $phrase\n     * @param  array  $options\n     * @return string|null\n     */\n    public function excerpt($phrase = '', $options = [])\n    {\n        return Str::excerpt($this->value, $phrase, $options);\n    }\n\n    /**\n     * Explode the string into a collection.\n     *\n     * @param  string  $delimiter\n     * @param  int  $limit\n     * @return \\Illuminate\\Support\\Collection<int, string>\n     */\n    public function explode($delimiter, $limit = PHP_INT_MAX)\n    {\n        return new Collection(explode($delimiter, $this->value, $limit));\n    }\n\n    /**\n     * Split a string using a regular expression or by length.\n     *\n     * @param  string|int  $pattern\n     * @param  int  $limit\n     * @param  int  $flags\n     * @return \\Illuminate\\Support\\Collection<int, string>\n     */\n    public function split($pattern, $limit = -1, $flags = 0)\n    {\n        if (filter_var($pattern, FILTER_VALIDATE_INT) !== false) {\n            return new Collection(mb_str_split($this->value, $pattern));\n        }\n\n        $segments = preg_split($pattern, $this->value, $limit, $flags);\n\n        return ! empty($segments) ? new Collection($segments) : new Collection;\n    }\n\n    /**\n     * Cap a string with a single instance of a given value.\n     *\n     * @param  string  $cap\n     * @return static\n     */\n    public function finish($cap)\n    {\n        return new static(Str::finish($this->value, $cap));\n    }\n\n    /**\n     * Determine if a given string matches a given pattern.\n     *\n     * @param  string|iterable<string>  $pattern\n     * @param  bool  $ignoreCase\n     * @return bool\n     */\n    public function is($pattern, $ignoreCase = false)\n    {\n        return Str::is($pattern, $this->value, $ignoreCase);\n    }\n\n    /**\n     * Determine if a given string is 7 bit ASCII.\n     *\n     * @return bool\n     */\n    public function isAscii()\n    {\n        return Str::isAscii($this->value);\n    }\n\n    /**\n     * Determine if a given string is valid JSON.\n     *\n     * @return bool\n     */\n    public function isJson()\n    {\n        return Str::isJson($this->value);\n    }\n\n    /**\n     * Determine if a given value is a valid URL.\n     *\n     * @param  array  $protocols\n     * @return bool\n     */\n    public function isUrl(array $protocols = [])\n    {\n        return Str::isUrl($this->value, $protocols);\n    }\n\n    /**\n     * Determine if a given string is a valid UUID.\n     *\n     * @param  int<0, 8>|'max'|null  $version\n     * @return bool\n     */\n    public function isUuid($version = null)\n    {\n        return Str::isUuid($this->value, $version);\n    }\n\n    /**\n     * Determine if a given string is a valid ULID.\n     *\n     * @return bool\n     */\n    public function isUlid()\n    {\n        return Str::isUlid($this->value);\n    }\n\n    /**\n     * Determine if the given string is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return $this->value === '';\n    }\n\n    /**\n     * Determine if the given string is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Convert a string to kebab case.\n     *\n     * @return static\n     */\n    public function kebab()\n    {\n        return new static(Str::kebab($this->value));\n    }\n\n    /**\n     * Return the length of the given string.\n     *\n     * @param  string|null  $encoding\n     * @return int\n     */\n    public function length($encoding = null)\n    {\n        return Str::length($this->value, $encoding);\n    }\n\n    /**\n     * Limit the number of characters in a string.\n     *\n     * @param  int  $limit\n     * @param  string  $end\n     * @param  bool  $preserveWords\n     * @return static\n     */\n    public function limit($limit = 100, $end = '...', $preserveWords = false)\n    {\n        return new static(Str::limit($this->value, $limit, $end, $preserveWords));\n    }\n\n    /**\n     * Convert the given string to lower-case.\n     *\n     * @return static\n     */\n    public function lower()\n    {\n        return new static(Str::lower($this->value));\n    }\n\n    /**\n     * Convert GitHub flavored Markdown into HTML.\n     *\n     * @param  array  $options\n     * @param  array  $extensions\n     * @return static\n     */\n    public function markdown(array $options = [], array $extensions = [])\n    {\n        return new static(Str::markdown($this->value, $options, $extensions));\n    }\n\n    /**\n     * Convert inline Markdown into HTML.\n     *\n     * @param  array  $options\n     * @param  array  $extensions\n     * @return static\n     */\n    public function inlineMarkdown(array $options = [], array $extensions = [])\n    {\n        return new static(Str::inlineMarkdown($this->value, $options, $extensions));\n    }\n\n    /**\n     * Masks a portion of a string with a repeated character.\n     *\n     * @param  string  $character\n     * @param  int  $index\n     * @param  int|null  $length\n     * @param  string  $encoding\n     * @return static\n     */\n    public function mask($character, $index, $length = null, $encoding = 'UTF-8')\n    {\n        return new static(Str::mask($this->value, $character, $index, $length, $encoding));\n    }\n\n    /**\n     * Get the string matching the given pattern.\n     *\n     * @param  string  $pattern\n     * @return static\n     */\n    public function match($pattern)\n    {\n        return new static(Str::match($pattern, $this->value));\n    }\n\n    /**\n     * Determine if a given string matches a given pattern.\n     *\n     * @param  string|iterable<string>  $pattern\n     * @return bool\n     */\n    public function isMatch($pattern)\n    {\n        return Str::isMatch($pattern, $this->value);\n    }\n\n    /**\n     * Get the string matching the given pattern.\n     *\n     * @param  string  $pattern\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function matchAll($pattern)\n    {\n        return Str::matchAll($pattern, $this->value);\n    }\n\n    /**\n     * Determine if the string matches the given pattern.\n     *\n     * @param  string  $pattern\n     * @return bool\n     */\n    public function test($pattern)\n    {\n        return $this->isMatch($pattern);\n    }\n\n    /**\n     * Remove all non-numeric characters from a string.\n     *\n     * @return static\n     */\n    public function numbers()\n    {\n        return new static(Str::numbers($this->value));\n    }\n\n    /**\n     * Pad both sides of the string with another.\n     *\n     * @param  int  $length\n     * @param  string  $pad\n     * @return static\n     */\n    public function padBoth($length, $pad = ' ')\n    {\n        return new static(Str::padBoth($this->value, $length, $pad));\n    }\n\n    /**\n     * Pad the left side of the string with another.\n     *\n     * @param  int  $length\n     * @param  string  $pad\n     * @return static\n     */\n    public function padLeft($length, $pad = ' ')\n    {\n        return new static(Str::padLeft($this->value, $length, $pad));\n    }\n\n    /**\n     * Pad the right side of the string with another.\n     *\n     * @param  int  $length\n     * @param  string  $pad\n     * @return static\n     */\n    public function padRight($length, $pad = ' ')\n    {\n        return new static(Str::padRight($this->value, $length, $pad));\n    }\n\n    /**\n     * Parse a Class@method style callback into class and method.\n     *\n     * @param  string|null  $default\n     * @return array<int, string|null>\n     */\n    public function parseCallback($default = null)\n    {\n        return Str::parseCallback($this->value, $default);\n    }\n\n    /**\n     * Call the given callback and return a new string.\n     *\n     * @param  callable  $callback\n     * @return static\n     */\n    public function pipe(callable $callback)\n    {\n        return new static($callback($this));\n    }\n\n    /**\n     * Get the plural form of an English word.\n     *\n     * @param  int|array|\\Countable  $count\n     * @param  bool  $prependCount\n     * @return static\n     */\n    public function plural($count = 2, $prependCount = false)\n    {\n        return new static(Str::plural($this->value, $count, $prependCount));\n    }\n\n    /**\n     * Pluralize the last word of an English, studly caps case string.\n     *\n     * @param  int|array|\\Countable  $count\n     * @return static\n     */\n    public function pluralStudly($count = 2)\n    {\n        return new static(Str::pluralStudly($this->value, $count));\n    }\n\n    /**\n     * Pluralize the last word of an English, Pascal caps case string.\n     *\n     * @param  int|array|\\Countable  $count\n     * @return static\n     */\n    public function pluralPascal($count = 2)\n    {\n        return new static(Str::pluralStudly($this->value, $count));\n    }\n\n    /**\n     * Find the multi-byte safe position of the first occurrence of the given substring.\n     *\n     * @param  string  $needle\n     * @param  int  $offset\n     * @param  string|null  $encoding\n     * @return int|false\n     */\n    public function position($needle, $offset = 0, $encoding = null)\n    {\n        return Str::position($this->value, $needle, $offset, $encoding);\n    }\n\n    /**\n     * Prepend the given values to the string.\n     *\n     * @param  string  ...$values\n     * @return static\n     */\n    public function prepend(...$values)\n    {\n        return new static(implode('', $values).$this->value);\n    }\n\n    /**\n     * Remove any occurrence of the given string in the subject.\n     *\n     * @param  string|iterable<string>  $search\n     * @param  bool  $caseSensitive\n     * @return static\n     */\n    public function remove($search, $caseSensitive = true)\n    {\n        return new static(Str::remove($search, $this->value, $caseSensitive));\n    }\n\n    /**\n     * Reverse the string.\n     *\n     * @return static\n     */\n    public function reverse()\n    {\n        return new static(Str::reverse($this->value));\n    }\n\n    /**\n     * Repeat the string.\n     *\n     * @param  int  $times\n     * @return static\n     */\n    public function repeat(int $times)\n    {\n        return new static(str_repeat($this->value, $times));\n    }\n\n    /**\n     * Replace the given value in the given string.\n     *\n     * @param  string|iterable<string>  $search\n     * @param  string|iterable<string>  $replace\n     * @param  bool  $caseSensitive\n     * @return static\n     */\n    public function replace($search, $replace, $caseSensitive = true)\n    {\n        return new static(Str::replace($search, $replace, $this->value, $caseSensitive));\n    }\n\n    /**\n     * Replace a given value in the string sequentially with an array.\n     *\n     * @param  string  $search\n     * @param  iterable<string>  $replace\n     * @return static\n     */\n    public function replaceArray($search, $replace)\n    {\n        return new static(Str::replaceArray($search, $replace, $this->value));\n    }\n\n    /**\n     * Replace the first occurrence of a given value in the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @return static\n     */\n    public function replaceFirst($search, $replace)\n    {\n        return new static(Str::replaceFirst($search, $replace, $this->value));\n    }\n\n    /**\n     * Replace the first occurrence of the given value if it appears at the start of the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @return static\n     */\n    public function replaceStart($search, $replace)\n    {\n        return new static(Str::replaceStart($search, $replace, $this->value));\n    }\n\n    /**\n     * Replace the last occurrence of a given value in the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @return static\n     */\n    public function replaceLast($search, $replace)\n    {\n        return new static(Str::replaceLast($search, $replace, $this->value));\n    }\n\n    /**\n     * Replace the last occurrence of a given value if it appears at the end of the string.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @return static\n     */\n    public function replaceEnd($search, $replace)\n    {\n        return new static(Str::replaceEnd($search, $replace, $this->value));\n    }\n\n    /**\n     * Replace the patterns matching the given regular expression.\n     *\n     * @param  array|string  $pattern\n     * @param  \\Closure|string[]|string  $replace\n     * @param  int  $limit\n     * @return static\n     */\n    public function replaceMatches($pattern, $replace, $limit = -1)\n    {\n        if ($replace instanceof Closure) {\n            return new static(preg_replace_callback($pattern, $replace, $this->value, $limit));\n        }\n\n        return new static(preg_replace($pattern, $replace, $this->value, $limit));\n    }\n\n    /**\n     * Parse input from a string to a collection, according to a format.\n     *\n     * @param  string  $format\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function scan($format)\n    {\n        return new Collection(sscanf($this->value, $format));\n    }\n\n    /**\n     * Remove all \"extra\" blank space from the given string.\n     *\n     * @return static\n     */\n    public function squish()\n    {\n        return new static(Str::squish($this->value));\n    }\n\n    /**\n     * Begin a string with a single instance of a given value.\n     *\n     * @param  string  $prefix\n     * @return static\n     */\n    public function start($prefix)\n    {\n        return new static(Str::start($this->value, $prefix));\n    }\n\n    /**\n     * Strip HTML and PHP tags from the given string.\n     *\n     * @param  string[]|string|null  $allowedTags\n     * @return static\n     */\n    public function stripTags($allowedTags = null)\n    {\n        return new static(strip_tags($this->value, $allowedTags));\n    }\n\n    /**\n     * Convert the given string to upper-case.\n     *\n     * @return static\n     */\n    public function upper()\n    {\n        return new static(Str::upper($this->value));\n    }\n\n    /**\n     * Convert the given string to proper case.\n     *\n     * @return static\n     */\n    public function title()\n    {\n        return new static(Str::title($this->value));\n    }\n\n    /**\n     * Convert the given string to proper case for each word.\n     *\n     * @return static\n     */\n    public function headline()\n    {\n        return new static(Str::headline($this->value));\n    }\n\n    /**\n     * Convert the given string to only its initials.\n     *\n     * @return static\n     */\n    public function initials()\n    {\n        return new static(Str::initials($this->value));\n    }\n\n    /**\n     * Convert the given string to APA-style title case.\n     *\n     * @return static\n     */\n    public function apa()\n    {\n        return new static(Str::apa($this->value));\n    }\n\n    /**\n     * Transliterate a string to its closest ASCII representation.\n     *\n     * @param  string|null  $unknown\n     * @param  bool|null  $strict\n     * @return static\n     */\n    public function transliterate($unknown = '?', $strict = false)\n    {\n        return new static(Str::transliterate($this->value, $unknown, $strict));\n    }\n\n    /**\n     * Get the singular form of an English word.\n     *\n     * @return static\n     */\n    public function singular()\n    {\n        return new static(Str::singular($this->value));\n    }\n\n    /**\n     * Generate a URL friendly \"slug\" from a given string.\n     *\n     * @param  string  $separator\n     * @param  string|null  $language\n     * @param  array<string, string>  $dictionary\n     * @return static\n     */\n    public function slug($separator = '-', $language = 'en', $dictionary = ['@' => 'at'])\n    {\n        return new static(Str::slug($this->value, $separator, $language, $dictionary));\n    }\n\n    /**\n     * Convert a string to snake case.\n     *\n     * @param  string  $delimiter\n     * @return static\n     */\n    public function snake($delimiter = '_')\n    {\n        return new static(Str::snake($this->value, $delimiter));\n    }\n\n    /**\n     * Determine if a given string starts with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @return bool\n     */\n    public function startsWith($needles)\n    {\n        return Str::startsWith($this->value, $needles);\n    }\n\n    /**\n     * Determine if a given string doesn't start with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @return bool\n     */\n    public function doesntStartWith($needles)\n    {\n        return Str::doesntStartWith($this->value, $needles);\n    }\n\n    /**\n     * Convert a value to studly caps case.\n     *\n     * @return static\n     */\n    public function studly()\n    {\n        return new static(Str::studly($this->value));\n    }\n\n    /**\n     * Convert the string to Pascal case.\n     *\n     * @return static\n     */\n    public function pascal()\n    {\n        return new static(Str::pascal($this->value));\n    }\n\n    /**\n     * Returns the portion of the string specified by the start and length parameters.\n     *\n     * @param  int  $start\n     * @param  int|null  $length\n     * @param  string  $encoding\n     * @return static\n     */\n    public function substr($start, $length = null, $encoding = 'UTF-8')\n    {\n        return new static(Str::substr($this->value, $start, $length, $encoding));\n    }\n\n    /**\n     * Returns the number of substring occurrences.\n     *\n     * @param  string  $needle\n     * @param  int  $offset\n     * @param  int|null  $length\n     * @return int\n     */\n    public function substrCount($needle, $offset = 0, $length = null)\n    {\n        return Str::substrCount($this->value, $needle, $offset, $length);\n    }\n\n    /**\n     * Replace text within a portion of a string.\n     *\n     * @param  string|string[]  $replace\n     * @param  int|int[]  $offset\n     * @param  int|int[]|null  $length\n     * @return static\n     */\n    public function substrReplace($replace, $offset = 0, $length = null)\n    {\n        return new static(Str::substrReplace($this->value, $replace, $offset, $length));\n    }\n\n    /**\n     * Swap multiple keywords in a string with other keywords.\n     *\n     * @param  array  $map\n     * @return static\n     */\n    public function swap(array $map)\n    {\n        return new static(strtr($this->value, $map));\n    }\n\n    /**\n     * Take the first or last {$limit} characters.\n     *\n     * @param  int  $limit\n     * @return static\n     */\n    public function take(int $limit)\n    {\n        if ($limit < 0) {\n            return $this->substr($limit);\n        }\n\n        return $this->substr(0, $limit);\n    }\n\n    /**\n     * Trim the string of the given characters.\n     *\n     * @param  string|null  $characters\n     * @return static\n     */\n    public function trim($characters = null)\n    {\n        return new static(Str::trim(...array_merge([$this->value], func_get_args())));\n    }\n\n    /**\n     * Left trim the string of the given characters.\n     *\n     * @param  string|null  $characters\n     * @return static\n     */\n    public function ltrim($characters = null)\n    {\n        return new static(Str::ltrim(...array_merge([$this->value], func_get_args())));\n    }\n\n    /**\n     * Right trim the string of the given characters.\n     *\n     * @param  string|null  $characters\n     * @return static\n     */\n    public function rtrim($characters = null)\n    {\n        return new static(Str::rtrim(...array_merge([$this->value], func_get_args())));\n    }\n\n    /**\n     * Make a string's first character lowercase.\n     *\n     * @return static\n     */\n    public function lcfirst()\n    {\n        return new static(Str::lcfirst($this->value));\n    }\n\n    /**\n     * Make a string's first character uppercase.\n     *\n     * @return static\n     */\n    public function ucfirst()\n    {\n        return new static(Str::ucfirst($this->value));\n    }\n\n    /**\n     * Capitalize the first character of each word in a string.\n     *\n     * @param  string  $separators\n     * @return static\n     */\n    public function ucwords($separators = \" \\t\\r\\n\\f\\v\")\n    {\n        return new static(Str::ucwords($this->value, $separators));\n    }\n\n    /**\n     * Split a string by uppercase characters.\n     *\n     * @return \\Illuminate\\Support\\Collection<int, string>\n     */\n    public function ucsplit()\n    {\n        return new Collection(Str::ucsplit($this->value));\n    }\n\n    /**\n     * Execute the given callback if the string contains a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenContains($needles, $callback, $default = null)\n    {\n        return $this->when($this->contains($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string contains all array values.\n     *\n     * @param  iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenContainsAll(array $needles, $callback, $default = null)\n    {\n        return $this->when($this->containsAll($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is empty.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenEmpty($callback, $default = null)\n    {\n        return $this->when($this->isEmpty(), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is not empty.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenNotEmpty($callback, $default = null)\n    {\n        return $this->when($this->isNotEmpty(), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string ends with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenEndsWith($needles, $callback, $default = null)\n    {\n        return $this->when($this->endsWith($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string doesn't end with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenDoesntEndWith($needles, $callback, $default = null)\n    {\n        return $this->when($this->doesntEndWith($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is an exact match with the given value.\n     *\n     * @param  string  $value\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenExactly($value, $callback, $default = null)\n    {\n        return $this->when($this->exactly($value), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is not an exact match with the given value.\n     *\n     * @param  string  $value\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenNotExactly($value, $callback, $default = null)\n    {\n        return $this->when(! $this->exactly($value), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string matches a given pattern.\n     *\n     * @param  string|iterable<string>  $pattern\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenIs($pattern, $callback, $default = null)\n    {\n        return $this->when($this->is($pattern), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is 7 bit ASCII.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenIsAscii($callback, $default = null)\n    {\n        return $this->when($this->isAscii(), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is a valid UUID.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenIsUuid($callback, $default = null)\n    {\n        return $this->when($this->isUuid(), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string is a valid ULID.\n     *\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenIsUlid($callback, $default = null)\n    {\n        return $this->when($this->isUlid(), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string starts with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenStartsWith($needles, $callback, $default = null)\n    {\n        return $this->when($this->startsWith($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string doesn't start with a given substring.\n     *\n     * @param  string|iterable<string>  $needles\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenDoesntStartWith($needles, $callback, $default = null)\n    {\n        return $this->when($this->doesntStartWith($needles), $callback, $default);\n    }\n\n    /**\n     * Execute the given callback if the string matches the given pattern.\n     *\n     * @param  string  $pattern\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return static\n     */\n    public function whenTest($pattern, $callback, $default = null)\n    {\n        return $this->when($this->test($pattern), $callback, $default);\n    }\n\n    /**\n     * Limit the number of words in a string.\n     *\n     * @param  int  $words\n     * @param  string  $end\n     * @return static\n     */\n    public function words($words = 100, $end = '...')\n    {\n        return new static(Str::words($this->value, $words, $end));\n    }\n\n    /**\n     * Get the number of words a string contains.\n     *\n     * @param  string|null  $characters\n     * @return int\n     */\n    public function wordCount($characters = null)\n    {\n        return Str::wordCount($this->value, $characters);\n    }\n\n    /**\n     * Wrap a string to a given number of characters.\n     *\n     * @param  int  $characters\n     * @param  string  $break\n     * @param  bool  $cutLongWords\n     * @return static\n     */\n    public function wordWrap($characters = 75, $break = \"\\n\", $cutLongWords = false)\n    {\n        return new static(Str::wordWrap($this->value, $characters, $break, $cutLongWords));\n    }\n\n    /**\n     * Wrap the string with the given strings.\n     *\n     * @param  string  $before\n     * @param  string|null  $after\n     * @return static\n     */\n    public function wrap($before, $after = null)\n    {\n        return new static(Str::wrap($this->value, $before, $after));\n    }\n\n    /**\n     * Unwrap the string with the given strings.\n     *\n     * @param  string  $before\n     * @param  string|null  $after\n     * @return static\n     */\n    public function unwrap($before, $after = null)\n    {\n        return new static(Str::unwrap($this->value, $before, $after));\n    }\n\n    /**\n     * Convert the string into a `HtmlString` instance.\n     *\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public function toHtmlString()\n    {\n        return new HtmlString($this->value);\n    }\n\n    /**\n     * Convert the string to Base64 encoding.\n     *\n     * @return static\n     */\n    public function toBase64()\n    {\n        return new static(base64_encode($this->value));\n    }\n\n    /**\n     * Decode the Base64 encoded string.\n     *\n     * @param  bool  $strict\n     * @return static\n     */\n    public function fromBase64($strict = false)\n    {\n        return new static(base64_decode($this->value, $strict));\n    }\n\n    /**\n     * Hash the string using the given algorithm.\n     *\n     * @param  string  $algorithm\n     * @return static\n     */\n    public function hash(string $algorithm)\n    {\n        return new static(hash($algorithm, $this->value));\n    }\n\n    /**\n     * Encrypt the string.\n     *\n     * @param  bool  $serialize\n     * @return static\n     */\n    public function encrypt(bool $serialize = false)\n    {\n        return new static(encrypt($this->value, $serialize));\n    }\n\n    /**\n     * Decrypt the string.\n     *\n     * @param  bool  $serialize\n     * @return static\n     */\n    public function decrypt(bool $serialize = false)\n    {\n        return new static(decrypt($this->value, $serialize));\n    }\n\n    /**\n     * Dump the string.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args)\n    {\n        dump($this->value, ...$args);\n\n        return $this;\n    }\n\n    /**\n     * Get the underlying string value.\n     *\n     * @return string\n     */\n    public function value()\n    {\n        return $this->toString();\n    }\n\n    /**\n     * Get the underlying string value.\n     *\n     * @return string\n     */\n    public function toString()\n    {\n        return $this->value;\n    }\n\n    /**\n     * Get the underlying string value as an integer.\n     *\n     * @param  int  $base\n     * @return int\n     */\n    public function toInteger($base = 10)\n    {\n        return intval($this->value, $base);\n    }\n\n    /**\n     * Get the underlying string value as a float.\n     *\n     * @return float\n     */\n    public function toFloat()\n    {\n        return (float) $this->value;\n    }\n\n    /**\n     * Get the underlying string value as a boolean.\n     *\n     * Returns true when value is \"1\", \"true\", \"on\", and \"yes\". Otherwise, returns false.\n     *\n     * @return bool\n     */\n    public function toBoolean()\n    {\n        return filter_var($this->value, FILTER_VALIDATE_BOOLEAN);\n    }\n\n    /**\n     * Get the underlying string value as a Carbon instance.\n     *\n     * @param  string|null  $format\n     * @param  string|null  $tz\n     * @return \\Illuminate\\Support\\Carbon\n     *\n     * @throws \\Carbon\\Exceptions\\InvalidFormatException\n     */\n    public function toDate($format = null, $tz = null)\n    {\n        if (is_null($format)) {\n            return Date::parse($this->value, $tz);\n        }\n\n        return Date::createFromFormat($format, $this->value, $tz);\n    }\n\n    /**\n     * Get the underlying string value as a Uri instance.\n     *\n     * @return \\Illuminate\\Support\\Uri\n     */\n    public function toUri()\n    {\n        return Uri::of($this->value);\n    }\n\n    /**\n     * Convert the object to a string when JSON encoded.\n     *\n     * @return string\n     */\n    public function jsonSerialize(): string\n    {\n        return $this->__toString();\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists(mixed $offset): bool\n    {\n        return isset($this->value[$offset]);\n    }\n\n    /**\n     * Get the value at the given offset.\n     *\n     * @param  mixed  $offset\n     * @return string\n     */\n    public function offsetGet(mixed $offset): string\n    {\n        return $this->value[$offset];\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  mixed  $offset\n     * @return void\n     */\n    public function offsetSet(mixed $offset, mixed $value): void\n    {\n        $this->value[$offset] = $value;\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  mixed  $offset\n     * @return void\n     */\n    public function offsetUnset(mixed $offset): void\n    {\n        unset($this->value[$offset]);\n    }\n\n    /**\n     * Proxy dynamic properties onto methods.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->{$key}();\n    }\n\n    /**\n     * Get the raw string value.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/BatchFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\UpdatedBatchJobCounts;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Throwable;\n\nclass BatchFake extends Batch\n{\n    /**\n     * The jobs that have been added to the batch.\n     *\n     * @var array\n     */\n    public $added = [];\n\n    /**\n     * Indicates if the batch has been deleted.\n     *\n     * @var bool\n     */\n    public $deleted = false;\n\n    /**\n     * Create a new batch instance.\n     *\n     * @param  string  $id\n     * @param  string  $name\n     * @param  int  $totalJobs\n     * @param  int  $pendingJobs\n     * @param  int  $failedJobs\n     * @param  array  $failedJobIds\n     * @param  array  $options\n     * @param  \\Carbon\\CarbonImmutable  $createdAt\n     * @param  \\Carbon\\CarbonImmutable|null  $cancelledAt\n     * @param  \\Carbon\\CarbonImmutable|null  $finishedAt\n     */\n    public function __construct(\n        string $id,\n        string $name,\n        int $totalJobs,\n        int $pendingJobs,\n        int $failedJobs,\n        array $failedJobIds,\n        array $options,\n        CarbonImmutable $createdAt,\n        ?CarbonImmutable $cancelledAt = null,\n        ?CarbonImmutable $finishedAt = null,\n    ) {\n        $this->id = $id;\n        $this->name = $name;\n        $this->totalJobs = $totalJobs;\n        $this->pendingJobs = $pendingJobs;\n        $this->failedJobs = $failedJobs;\n        $this->failedJobIds = $failedJobIds;\n        $this->options = $options;\n        $this->createdAt = $createdAt;\n        $this->cancelledAt = $cancelledAt;\n        $this->finishedAt = $finishedAt;\n    }\n\n    /**\n     * Get a fresh instance of the batch represented by this ID.\n     *\n     * @return self\n     */\n    #[\\Override]\n    public function fresh()\n    {\n        return $this;\n    }\n\n    /**\n     * Add additional jobs to the batch.\n     *\n     * @param  \\Illuminate\\Support\\Enumerable|object|array  $jobs\n     * @return self\n     */\n    #[\\Override]\n    public function add($jobs)\n    {\n        $jobs = Collection::wrap($jobs);\n\n        foreach ($jobs as $job) {\n            $this->added[] = $job;\n        }\n\n        $this->totalJobs += $jobs->count();\n\n        return $this;\n    }\n\n    /**\n     * Record that a job within the batch finished successfully, executing any callbacks if necessary.\n     *\n     * @param  string  $jobId\n     * @return void\n     */\n    #[\\Override]\n    public function recordSuccessfulJob(string $jobId)\n    {\n        //\n    }\n\n    /**\n     * Decrement the pending jobs for the batch.\n     *\n     * @param  string  $jobId\n     * @return void\n     */\n    #[\\Override]\n    public function decrementPendingJobs(string $jobId)\n    {\n        //\n    }\n\n    /**\n     * Record that a job within the batch failed to finish successfully, executing any callbacks if necessary.\n     *\n     * @param  string  $jobId\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    #[\\Override]\n    public function recordFailedJob(string $jobId, $e)\n    {\n        //\n    }\n\n    /**\n     * Increment the failed jobs for the batch.\n     *\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    #[\\Override]\n    public function incrementFailedJobs(string $jobId)\n    {\n        return new UpdatedBatchJobCounts;\n    }\n\n    /**\n     * Cancel the batch.\n     *\n     * @return void\n     */\n    #[\\Override]\n    public function cancel(?Throwable $exception = null)\n    {\n        $this->cancelledAt = Carbon::now();\n    }\n\n    /**\n     * Delete the batch from storage.\n     *\n     * @return void\n     */\n    #[\\Override]\n    public function delete()\n    {\n        $this->deleted = true;\n    }\n\n    /**\n     * Determine if the batch has been deleted.\n     *\n     * @return bool\n     */\n    public function deleted()\n    {\n        return $this->deleted;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/BatchRepositoryFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Closure;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Bus\\UpdatedBatchJobCounts;\nuse Illuminate\\Support\\Str;\n\nclass BatchRepositoryFake implements BatchRepository\n{\n    /**\n     * The batches stored in the repository.\n     *\n     * @var \\Illuminate\\Bus\\Batch[]\n     */\n    protected $batches = [];\n\n    /**\n     * Retrieve a list of batches.\n     *\n     * @param  int  $limit\n     * @param  mixed  $before\n     * @return \\Illuminate\\Bus\\Batch[]\n     */\n    public function get($limit, $before)\n    {\n        return $this->batches;\n    }\n\n    /**\n     * Retrieve information about an existing batch.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function find(string $batchId)\n    {\n        return $this->batches[$batchId] ?? null;\n    }\n\n    /**\n     * Store a new pending batch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $batch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function store(PendingBatch $batch)\n    {\n        $id = (string) Str::orderedUuid();\n\n        $this->batches[$id] = new BatchFake(\n            $id,\n            $batch->name,\n            count($batch->jobs),\n            count($batch->jobs),\n            0,\n            [],\n            $batch->options,\n            CarbonImmutable::now(),\n            null,\n            null\n        );\n\n        return $this->batches[$id];\n    }\n\n    /**\n     * Increment the total number of jobs within the batch.\n     *\n     * @param  string  $batchId\n     * @param  int  $amount\n     * @return void\n     */\n    public function incrementTotalJobs(string $batchId, int $amount)\n    {\n        //\n    }\n\n    /**\n     * Decrement the total number of pending jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function decrementPendingJobs(string $batchId, string $jobId)\n    {\n        return new UpdatedBatchJobCounts;\n    }\n\n    /**\n     * Increment the total number of failed jobs for the batch.\n     *\n     * @param  string  $batchId\n     * @param  string  $jobId\n     * @return \\Illuminate\\Bus\\UpdatedBatchJobCounts\n     */\n    public function incrementFailedJobs(string $batchId, string $jobId)\n    {\n        return new UpdatedBatchJobCounts;\n    }\n\n    /**\n     * Mark the batch that has the given ID as finished.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function markAsFinished(string $batchId)\n    {\n        if (isset($this->batches[$batchId])) {\n            $this->batches[$batchId]->finishedAt = Carbon::now();\n        }\n    }\n\n    /**\n     * Cancel the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function cancel(string $batchId)\n    {\n        if (isset($this->batches[$batchId])) {\n            $this->batches[$batchId]->cancel();\n        }\n    }\n\n    /**\n     * Delete the batch that has the given ID.\n     *\n     * @param  string  $batchId\n     * @return void\n     */\n    public function delete(string $batchId)\n    {\n        unset($this->batches[$batchId]);\n    }\n\n    /**\n     * Execute the given Closure within a storage specific transaction.\n     *\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function transaction(Closure $callback)\n    {\n        return $callback();\n    }\n\n    /**\n     * Rollback the last database transaction for the connection.\n     *\n     * @return void\n     */\n    public function rollBack()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/BusFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\ChainedBatch;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Contracts\\Bus\\QueueingDispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse RuntimeException;\n\nclass BusFake implements Fake, QueueingDispatcher\n{\n    use ReflectsClosures;\n\n    /**\n     * The original Bus dispatcher implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Bus\\QueueingDispatcher\n     */\n    public $dispatcher;\n\n    /**\n     * The job types that should be intercepted instead of dispatched.\n     *\n     * @var array\n     */\n    protected $jobsToFake = [];\n\n    /**\n     * The job types that should be dispatched instead of faked.\n     *\n     * @var array\n     */\n    protected $jobsToDispatch = [];\n\n    /**\n     * The fake repository to track batched jobs.\n     *\n     * @var \\Illuminate\\Bus\\BatchRepository\n     */\n    protected $batchRepository;\n\n    /**\n     * The commands that have been dispatched.\n     *\n     * @var array\n     */\n    protected $commands = [];\n\n    /**\n     * The commands that have been dispatched synchronously.\n     *\n     * @var array\n     */\n    protected $commandsSync = [];\n\n    /**\n     * The commands that have been dispatched after the response has been sent.\n     *\n     * @var array\n     */\n    protected $commandsAfterResponse = [];\n\n    /**\n     * The batches that have been dispatched.\n     *\n     * @var array\n     */\n    protected $batches = [];\n\n    /**\n     * Indicates if commands should be serialized and restored when pushed to the Bus.\n     *\n     * @var bool\n     */\n    protected bool $serializeAndRestore = false;\n\n    /**\n     * Create a new bus fake instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Bus\\QueueingDispatcher  $dispatcher\n     * @param  array|string  $jobsToFake\n     * @param  \\Illuminate\\Bus\\BatchRepository|null  $batchRepository\n     */\n    public function __construct(QueueingDispatcher $dispatcher, $jobsToFake = [], ?BatchRepository $batchRepository = null)\n    {\n        $this->dispatcher = $dispatcher;\n        $this->jobsToFake = Arr::wrap($jobsToFake);\n        $this->batchRepository = $batchRepository ?: new BatchRepositoryFake;\n    }\n\n    /**\n     * Specify the jobs that should be dispatched instead of faked.\n     *\n     * @param  array|string  $jobsToDispatch\n     * @return $this\n     */\n    public function except($jobsToDispatch)\n    {\n        $this->jobsToDispatch = array_merge($this->jobsToDispatch, Arr::wrap($jobsToDispatch));\n\n        return $this;\n    }\n\n    /**\n     * Assert if a job was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertDispatched($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        if (is_numeric($callback)) {\n            return $this->assertDispatchedTimes($command, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatched($command, $callback)->count() > 0 ||\n            $this->dispatchedAfterResponse($command, $callback)->count() > 0 ||\n            $this->dispatchedSync($command, $callback)->count() > 0,\n            \"The expected [{$command}] job was not dispatched.\"\n        );\n    }\n\n    /**\n     * Assert if a job was pushed exactly once.\n     *\n     * @param  string|\\Closure  $command\n     * @return void\n     */\n    public function assertDispatchedOnce($command)\n    {\n        $this->assertDispatchedTimes($command, 1);\n    }\n\n    /**\n     * Assert if a job was pushed a number of times.\n     *\n     * @param  string|\\Closure  $command\n     * @param  int  $times\n     * @return void\n     */\n    public function assertDispatchedTimes($command, $times = 1)\n    {\n        $callback = null;\n\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        $count = $this->dispatched($command, $callback)->count() +\n                 $this->dispatchedAfterResponse($command, $callback)->count() +\n                 $this->dispatchedSync($command, $callback)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$command}] job was pushed {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if a job was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotDispatched($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatched($command, $callback)->count() === 0 &&\n            $this->dispatchedAfterResponse($command, $callback)->count() === 0 &&\n            $this->dispatchedSync($command, $callback)->count() === 0,\n            \"The unexpected [{$command}] job was dispatched.\"\n        );\n    }\n\n    /**\n     * Assert that no jobs were dispatched.\n     *\n     * @return void\n     */\n    public function assertNothingDispatched()\n    {\n        $dispatchedCommands = $this->commands + $this->commandsSync + $this->commandsAfterResponse;\n\n        $commandNames = implode(\"\\n- \", array_keys($dispatchedCommands));\n\n        PHPUnit::assertEmpty($dispatchedCommands, \"The following jobs were dispatched unexpectedly:\\n\\n- $commandNames\\n\");\n    }\n\n    /**\n     * Assert if a job was explicitly dispatched synchronously based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertDispatchedSync($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        if (is_numeric($callback)) {\n            return $this->assertDispatchedSyncTimes($command, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatchedSync($command, $callback)->count() > 0,\n            \"The expected [{$command}] job was not dispatched synchronously.\"\n        );\n    }\n\n    /**\n     * Assert if a job was pushed synchronously a number of times.\n     *\n     * @param  string|\\Closure  $command\n     * @param  int  $times\n     * @return void\n     */\n    public function assertDispatchedSyncTimes($command, $times = 1)\n    {\n        $callback = null;\n\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        $count = $this->dispatchedSync($command, $callback)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$command}] job was synchronously pushed {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if a job was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotDispatchedSync($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        PHPUnit::assertCount(\n            0, $this->dispatchedSync($command, $callback),\n            \"The unexpected [{$command}] job was dispatched synchronously.\"\n        );\n    }\n\n    /**\n     * Assert if a job was dispatched after the response was sent based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertDispatchedAfterResponse($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        if (is_numeric($callback)) {\n            return $this->assertDispatchedAfterResponseTimes($command, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatchedAfterResponse($command, $callback)->count() > 0,\n            \"The expected [{$command}] job was not dispatched after sending the response.\"\n        );\n    }\n\n    /**\n     * Assert if a job was pushed after the response was sent a number of times.\n     *\n     * @param  string|\\Closure  $command\n     * @param  int  $times\n     * @return void\n     */\n    public function assertDispatchedAfterResponseTimes($command, $times = 1)\n    {\n        $callback = null;\n\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        $count = $this->dispatchedAfterResponse($command, $callback)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$command}] job was pushed {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if a job was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotDispatchedAfterResponse($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        PHPUnit::assertCount(\n            0, $this->dispatchedAfterResponse($command, $callback),\n            \"The unexpected [{$command}] job was dispatched after sending the response.\"\n        );\n    }\n\n    /**\n     * Assert if a chain of jobs was dispatched.\n     *\n     * @param  array  $expectedChain\n     * @return void\n     */\n    public function assertChained(array $expectedChain)\n    {\n        $command = $expectedChain[0];\n\n        $expectedChain = array_slice($expectedChain, 1);\n\n        $callback = null;\n\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        } elseif ($command instanceof ChainedBatchTruthTest) {\n            $instance = $command;\n\n            $command = ChainedBatch::class;\n\n            $callback = fn ($job) => $instance($job->toPendingBatch());\n        } elseif (! is_string($command)) {\n            $instance = $command;\n\n            $command = get_class($instance);\n\n            $callback = function ($job) use ($instance) {\n                return serialize($this->resetChainPropertiesToDefaults($job)) === serialize($instance);\n            };\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatched($command, $callback)->isNotEmpty(),\n            \"The expected [{$command}] job was not dispatched.\"\n        );\n\n        $this->assertDispatchedWithChainOfObjects($command, $expectedChain, $callback);\n    }\n\n    /**\n     * Assert no chained jobs was dispatched.\n     *\n     * @return void\n     */\n    public function assertNothingChained()\n    {\n        $this->assertNothingDispatched();\n    }\n\n    /**\n     * Reset the chain properties to their default values on the job.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    protected function resetChainPropertiesToDefaults($job)\n    {\n        return tap(clone $job, function ($job) {\n            $job->chainConnection = null;\n            $job->chainQueue = null;\n            $job->chainCatchCallbacks = null;\n            $job->chained = [];\n        });\n    }\n\n    /**\n     * Assert if a job was dispatched with an empty chain based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $command\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertDispatchedWithoutChain($command, $callback = null)\n    {\n        if ($command instanceof Closure) {\n            [$command, $callback] = [$this->firstClosureParameterType($command), $command];\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatched($command, $callback)->isNotEmpty(),\n            \"The expected [{$command}] job was not dispatched.\"\n        );\n\n        $this->assertDispatchedWithChainOfObjects($command, [], $callback);\n    }\n\n    /**\n     * Assert if a job was dispatched with chained jobs based on a truth-test callback.\n     *\n     * @param  string  $command\n     * @param  array  $expectedChain\n     * @param  callable|null  $callback\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    protected function assertDispatchedWithChainOfObjects($command, $expectedChain, $callback)\n    {\n        $chain = $expectedChain;\n\n        PHPUnit::assertTrue(\n            $this->dispatched($command, $callback)->filter(function ($job) use ($chain) {\n                if (count($chain) !== count($job->chained)) {\n                    return false;\n                }\n\n                foreach ($job->chained as $index => $serializedChainedJob) {\n                    if ($chain[$index] instanceof ChainedBatchTruthTest) {\n                        $chainedBatch = unserialize($serializedChainedJob);\n\n                        if (! $chainedBatch instanceof ChainedBatch ||\n                            ! $chain[$index]($chainedBatch->toPendingBatch())) {\n                            return false;\n                        }\n                    } elseif ($chain[$index] instanceof Closure) {\n                        [$expectedType, $callback] = [$this->firstClosureParameterType($chain[$index]), $chain[$index]];\n\n                        $chainedJob = unserialize($serializedChainedJob);\n\n                        if (! $chainedJob instanceof $expectedType) {\n                            throw new RuntimeException('The chained job was expected to be of type '.$expectedType.', '.$chainedJob::class.' chained.');\n                        }\n\n                        if (! $callback($chainedJob)) {\n                            return false;\n                        }\n                    } elseif (is_string($chain[$index])) {\n                        if ($chain[$index] != get_class(unserialize($serializedChainedJob))) {\n                            return false;\n                        }\n                    } elseif (serialize($chain[$index]) != $serializedChainedJob) {\n                        return false;\n                    }\n                }\n\n                return true;\n            })->isNotEmpty(),\n            'The expected chain was not dispatched.'\n        );\n    }\n\n    /**\n     * Create a new assertion about a chained batch.\n     *\n     * @param  \\Closure(\\Illuminate\\Bus\\PendingBatch): bool  $callback\n     * @return \\Illuminate\\Support\\Testing\\Fakes\\ChainedBatchTruthTest\n     */\n    public function chainedBatch(Closure $callback)\n    {\n        return new ChainedBatchTruthTest($callback);\n    }\n\n    /**\n     * Assert if a batch was dispatched based on a truth-test callback.\n     *\n     * @param  array|callable(\\Illuminate\\Bus\\PendingBatch): bool  $callback\n     * @return void\n     */\n    public function assertBatched(callable|array $callback)\n    {\n        $callback = is_array($callback) ? fn (PendingBatchFake $batch) => $batch->hasJobs($callback) : $callback;\n\n        PHPUnit::assertTrue(\n            $this->batched($callback)->count() > 0,\n            'The expected batch was not dispatched.'\n        );\n    }\n\n    /**\n     * Assert the number of batches that have been dispatched.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertBatchCount($count)\n    {\n        PHPUnit::assertCount(\n            $count, $this->batches,\n        );\n    }\n\n    /**\n     * Assert that no batched jobs were dispatched.\n     *\n     * @return void\n     */\n    public function assertNothingBatched()\n    {\n        $jobNames = (new Collection($this->batches))\n            ->map(fn ($batch) => $batch->jobs->map(fn ($job) => get_class($job)))\n            ->flatten()\n            ->join(\"\\n- \");\n\n        PHPUnit::assertEmpty($this->batches, \"The following batched jobs were dispatched unexpectedly:\\n\\n- $jobNames\\n\");\n    }\n\n    /**\n     * Assert that no jobs were dispatched, chained, or batched.\n     *\n     * @return void\n     */\n    public function assertNothingPlaced()\n    {\n        $this->assertNothingDispatched();\n        $this->assertNothingBatched();\n    }\n\n    /**\n     * Get all of the jobs matching a truth-test callback.\n     *\n     * @param  string  $command\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function dispatched($command, $callback = null)\n    {\n        if (! $this->hasDispatched($command)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return (new Collection($this->commands[$command]))->filter(fn ($command) => $callback($command));\n    }\n\n    /**\n     * Get all of the jobs dispatched synchronously matching a truth-test callback.\n     *\n     * @param  string  $command\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function dispatchedSync(string $command, $callback = null)\n    {\n        if (! $this->hasDispatchedSync($command)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return (new Collection($this->commandsSync[$command]))->filter(fn ($command) => $callback($command));\n    }\n\n    /**\n     * Get all of the jobs dispatched after the response was sent matching a truth-test callback.\n     *\n     * @param  string  $command\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function dispatchedAfterResponse(string $command, $callback = null)\n    {\n        if (! $this->hasDispatchedAfterResponse($command)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return (new Collection($this->commandsAfterResponse[$command]))->filter(fn ($command) => $callback($command));\n    }\n\n    /**\n     * Get all of the pending batches matching a truth-test callback.\n     *\n     * @param  callable(\\Illuminate\\Bus\\PendingBatch): bool  $callback\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Bus\\PendingBatch>\n     */\n    public function batched(callable $callback)\n    {\n        if (empty($this->batches)) {\n            return new Collection;\n        }\n\n        return (new Collection($this->batches))->filter(fn ($batch) => $callback($batch));\n    }\n\n    /**\n     * Determine if there are any stored commands for a given class.\n     *\n     * @param  string  $command\n     * @return bool\n     */\n    public function hasDispatched($command)\n    {\n        return isset($this->commands[$command]) && ! empty($this->commands[$command]);\n    }\n\n    /**\n     * Determine if there are any stored commands for a given class.\n     *\n     * @param  string  $command\n     * @return bool\n     */\n    public function hasDispatchedSync($command)\n    {\n        return isset($this->commandsSync[$command]) && ! empty($this->commandsSync[$command]);\n    }\n\n    /**\n     * Determine if there are any stored commands for a given class.\n     *\n     * @param  string  $command\n     * @return bool\n     */\n    public function hasDispatchedAfterResponse($command)\n    {\n        return isset($this->commandsAfterResponse[$command]) && ! empty($this->commandsAfterResponse[$command]);\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function dispatch($command)\n    {\n        if ($this->shouldFakeJob($command)) {\n            $this->commands[get_class($command)][] = $this->getCommandRepresentation($command);\n        } else {\n            return $this->dispatcher->dispatch($command);\n        }\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * Queueable jobs will be dispatched to the \"sync\" queue.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchSync($command, $handler = null)\n    {\n        if ($this->shouldFakeJob($command)) {\n            $this->commandsSync[get_class($command)][] = $this->getCommandRepresentation($command);\n        } else {\n            return $this->dispatcher->dispatchSync($command, $handler);\n        }\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler in the current process.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return mixed\n     */\n    public function dispatchNow($command, $handler = null)\n    {\n        if ($this->shouldFakeJob($command)) {\n            $this->commands[get_class($command)][] = $this->getCommandRepresentation($command);\n        } else {\n            return $this->dispatcher->dispatchNow($command, $handler);\n        }\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler behind a queue.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function dispatchToQueue($command)\n    {\n        if ($this->shouldFakeJob($command)) {\n            $this->commands[get_class($command)][] = $this->getCommandRepresentation($command);\n        } else {\n            return $this->dispatcher->dispatchToQueue($command);\n        }\n    }\n\n    /**\n     * Dispatch a command to its appropriate handler after the current process.\n     *\n     * @param  mixed  $command\n     * @param  mixed  $handler\n     * @return void\n     */\n    public function dispatchAfterResponse($command, $handler = null)\n    {\n        if ($this->shouldFakeJob($command)) {\n            $this->commandsAfterResponse[get_class($command)][] = $this->getCommandRepresentation($command);\n        } else {\n            $this->dispatcher->dispatchAfterResponse($command, $handler);\n        }\n    }\n\n    /**\n     * Create a new chain of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array|null  $jobs\n     * @return \\Illuminate\\Foundation\\Bus\\PendingChain\n     */\n    public function chain($jobs = null)\n    {\n        $jobs = Collection::wrap($jobs);\n        $jobs = ChainedBatch::prepareNestedBatches($jobs);\n\n        return new PendingChainFake($this, $jobs->shift(), $jobs->toArray());\n    }\n\n    /**\n     * Attempt to find the batch with the given ID.\n     *\n     * @param  string  $batchId\n     * @return \\Illuminate\\Bus\\Batch|null\n     */\n    public function findBatch(string $batchId)\n    {\n        return $this->batchRepository->find($batchId);\n    }\n\n    /**\n     * Create a new batch of queueable jobs.\n     *\n     * @param  \\Illuminate\\Support\\Collection|array  $jobs\n     * @return \\Illuminate\\Bus\\PendingBatch\n     */\n    public function batch($jobs)\n    {\n        return new PendingBatchFake($this, Collection::wrap($jobs));\n    }\n\n    /**\n     * Dispatch an empty job batch for testing.\n     *\n     * @param  string  $name\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function dispatchFakeBatch($name = '')\n    {\n        return $this->batch([])->name($name)->dispatch();\n    }\n\n    /**\n     * Record the fake pending batch dispatch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $pendingBatch\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function recordPendingBatch(PendingBatch $pendingBatch)\n    {\n        $this->batches[] = $pendingBatch;\n\n        return $this->batchRepository->store($pendingBatch);\n    }\n\n    /**\n     * Determine if a command should be faked or actually dispatched.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    protected function shouldFakeJob($command)\n    {\n        if ($this->shouldDispatchCommand($command)) {\n            return false;\n        }\n\n        if (empty($this->jobsToFake)) {\n            return true;\n        }\n\n        return (new Collection($this->jobsToFake))\n            ->filter(function ($job) use ($command) {\n                return $job instanceof Closure\n                    ? $job($command)\n                    : $job === get_class($command);\n            })->isNotEmpty();\n    }\n\n    /**\n     * Determine if a command should be dispatched or not.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    protected function shouldDispatchCommand($command)\n    {\n        return (new Collection($this->jobsToDispatch))\n            ->filter(function ($job) use ($command) {\n                return $job instanceof Closure\n                    ? $job($command)\n                    : $job === get_class($command);\n            })->isNotEmpty();\n    }\n\n    /**\n     * Specify if commands should be serialized and restored when being batched.\n     *\n     * @param  bool  $serializeAndRestore\n     * @return $this\n     */\n    public function serializeAndRestore(bool $serializeAndRestore = true)\n    {\n        $this->serializeAndRestore = $serializeAndRestore;\n\n        return $this;\n    }\n\n    /**\n     * Serialize and unserialize the command to simulate the queueing process.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    protected function serializeAndRestoreCommand($command)\n    {\n        return unserialize(serialize($command));\n    }\n\n    /**\n     * Return the command representation that should be stored.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    protected function getCommandRepresentation($command)\n    {\n        return $this->serializeAndRestore ? $this->serializeAndRestoreCommand($command) : $command;\n    }\n\n    /**\n     * Set the pipes commands should be piped through before dispatching.\n     *\n     * @param  array  $pipes\n     * @return $this\n     */\n    public function pipeThrough(array $pipes)\n    {\n        $this->dispatcher->pipeThrough($pipes);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given command has a handler.\n     *\n     * @param  mixed  $command\n     * @return bool\n     */\n    public function hasCommandHandler($command)\n    {\n        return $this->dispatcher->hasCommandHandler($command);\n    }\n\n    /**\n     * Retrieve the handler for a command.\n     *\n     * @param  mixed  $command\n     * @return mixed\n     */\n    public function getCommandHandler($command)\n    {\n        return $this->dispatcher->getCommandHandler($command);\n    }\n\n    /**\n     * Map a command to a handler.\n     *\n     * @param  array  $map\n     * @return $this\n     */\n    public function map(array $map)\n    {\n        $this->dispatcher->map($map);\n\n        return $this;\n    }\n\n    /**\n     * Get the batches that have been dispatched.\n     *\n     * @return array\n     */\n    public function dispatchedBatches()\n    {\n        return $this->batches;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/ChainedBatchTruthTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\n\nclass ChainedBatchTruthTest\n{\n    /**\n     * The underlying truth test.\n     *\n     * @var \\Closure(\\Illuminate\\Bus\\PendingBatch): bool\n     */\n    protected $callback;\n\n    /**\n     * Create a new truth test instance.\n     *\n     * @param  \\Closure(\\Illuminate\\Bus\\PendingBatch): bool  $callback\n     */\n    public function __construct(Closure $callback)\n    {\n        $this->callback = $callback;\n    }\n\n    /**\n     * Invoke the truth test with the given pending batch.\n     *\n     * @param  \\Illuminate\\Bus\\PendingBatch  $pendingBatch\n     * @return bool\n     */\n    public function __invoke($pendingBatch)\n    {\n        return call_user_func($this->callback, $pendingBatch);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/EventFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse ReflectionFunction;\n\nclass EventFake implements Dispatcher, Fake\n{\n    use ForwardsCalls, ReflectsClosures;\n\n    /**\n     * The original event dispatcher.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    public $dispatcher;\n\n    /**\n     * The event types that should be intercepted instead of dispatched.\n     *\n     * @var array\n     */\n    protected $eventsToFake = [];\n\n    /**\n     * The event types that should be dispatched instead of intercepted.\n     *\n     * @var array\n     */\n    protected $eventsToDispatch = [];\n\n    /**\n     * All of the events that have been intercepted keyed by type.\n     *\n     * @var array\n     */\n    protected $events = [];\n\n    /**\n     * Create a new event fake instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $dispatcher\n     * @param  array|string  $eventsToFake\n     */\n    public function __construct(Dispatcher $dispatcher, $eventsToFake = [])\n    {\n        $this->dispatcher = $dispatcher;\n\n        $this->eventsToFake = Arr::wrap($eventsToFake);\n    }\n\n    /**\n     * Specify the events that should be dispatched instead of faked.\n     *\n     * @param  array|string  $eventsToDispatch\n     * @return $this\n     */\n    public function except($eventsToDispatch)\n    {\n        $this->eventsToDispatch = array_merge(\n            $this->eventsToDispatch,\n            Arr::wrap($eventsToDispatch)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert if an event has a listener attached to it.\n     *\n     * @param  string  $expectedEvent\n     * @param  string|array  $expectedListener\n     * @return void\n     */\n    public function assertListening($expectedEvent, $expectedListener)\n    {\n        foreach ($this->dispatcher->getListeners($expectedEvent) as $listenerClosure) {\n            $actualListener = (new ReflectionFunction($listenerClosure))\n                ->getStaticVariables()['listener'];\n\n            $normalizedListener = $expectedListener;\n\n            if (is_string($actualListener) && Str::contains($actualListener, '@')) {\n                $actualListener = Str::parseCallback($actualListener);\n\n                if (is_string($expectedListener)) {\n                    if (Str::contains($expectedListener, '@')) {\n                        $normalizedListener = Str::parseCallback($expectedListener);\n                    } else {\n                        $normalizedListener = [\n                            $expectedListener,\n                            method_exists($expectedListener, 'handle') ? 'handle' : '__invoke',\n                        ];\n                    }\n                }\n            }\n\n            if ($actualListener === $normalizedListener ||\n                ($actualListener instanceof Closure &&\n                $normalizedListener === Closure::class)) {\n                PHPUnit::assertTrue(true);\n\n                return;\n            }\n        }\n\n        PHPUnit::assertTrue(\n            false,\n            sprintf(\n                'Event [%s] does not have the [%s] listener attached to it',\n                $expectedEvent,\n                print_r($expectedListener, true)\n            )\n        );\n    }\n\n    /**\n     * Assert if an event was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $event\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertDispatched($event, $callback = null)\n    {\n        if ($event instanceof Closure) {\n            [$event, $callback] = [$this->firstClosureParameterType($event), $event];\n        }\n\n        if (is_int($callback)) {\n            return $this->assertDispatchedTimes($event, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->dispatched($event, $callback)->count() > 0,\n            \"The expected [{$event}] event was not dispatched.\"\n        );\n    }\n\n    /**\n     * Assert if an event was dispatched exactly once.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function assertDispatchedOnce($event)\n    {\n        $this->assertDispatchedTimes($event, 1);\n    }\n\n    /**\n     * Assert if an event was dispatched a number of times.\n     *\n     * @param  string  $event\n     * @param  int  $times\n     * @return void\n     */\n    public function assertDispatchedTimes($event, $times = 1)\n    {\n        $count = $this->dispatched($event)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$event}] event was dispatched {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if an event was dispatched based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $event\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotDispatched($event, $callback = null)\n    {\n        if ($event instanceof Closure) {\n            [$event, $callback] = [$this->firstClosureParameterType($event), $event];\n        }\n\n        PHPUnit::assertCount(\n            0, $this->dispatched($event, $callback),\n            \"The unexpected [{$event}] event was dispatched.\"\n        );\n    }\n\n    /**\n     * Assert that no events were dispatched.\n     *\n     * @return void\n     */\n    public function assertNothingDispatched()\n    {\n        $count = count(Arr::flatten($this->events));\n\n        $eventNames = (new Collection($this->events))\n            ->map(fn ($events, $eventName) => sprintf(\n                '%s dispatched %s %s',\n                $eventName,\n                count($events),\n                Str::plural('time', count($events)),\n            ))\n            ->join(\"\\n- \");\n\n        PHPUnit::assertSame(\n            0, $count,\n            \"{$count} unexpected events were dispatched:\\n\\n- $eventNames\\n\"\n        );\n    }\n\n    /**\n     * Get all of the events matching a truth-test callback.\n     *\n     * @param  string  $event\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function dispatched($event, $callback = null)\n    {\n        if (! $this->hasDispatched($event)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return (new Collection($this->events[$event]))->filter(\n            fn ($arguments) => $callback(...$arguments)\n        );\n    }\n\n    /**\n     * Determine if the given event has been dispatched.\n     *\n     * @param  string  $event\n     * @return bool\n     */\n    public function hasDispatched($event)\n    {\n        return isset($this->events[$event]) && ! empty($this->events[$event]);\n    }\n\n    /**\n     * Register an event listener with the dispatcher.\n     *\n     * @param  \\Closure|string|array  $events\n     * @param  mixed  $listener\n     * @return void\n     */\n    public function listen($events, $listener = null)\n    {\n        $this->dispatcher->listen($events, $listener);\n    }\n\n    /**\n     * Determine if a given event has listeners.\n     *\n     * @param  string  $eventName\n     * @return bool\n     */\n    public function hasListeners($eventName)\n    {\n        return $this->dispatcher->hasListeners($eventName);\n    }\n\n    /**\n     * Register an event and payload to be dispatched later.\n     *\n     * @param  string  $event\n     * @param  array  $payload\n     * @return void\n     */\n    public function push($event, $payload = [])\n    {\n        //\n    }\n\n    /**\n     * Register an event subscriber with the dispatcher.\n     *\n     * @param  object|string  $subscriber\n     * @return void\n     */\n    public function subscribe($subscriber)\n    {\n        $this->dispatcher->subscribe($subscriber);\n    }\n\n    /**\n     * Flush a set of pushed events.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function flush($event)\n    {\n        //\n    }\n\n    /**\n     * Fire an event and call the listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @param  bool  $halt\n     * @return array|null\n     */\n    public function dispatch($event, $payload = [], $halt = false)\n    {\n        $name = is_object($event) ? get_class($event) : (string) $event;\n\n        if ($this->shouldFakeEvent($name, $payload)) {\n            $this->fakeEvent($event, $name, func_get_args());\n        } else {\n            return $this->dispatcher->dispatch($event, $payload, $halt);\n        }\n    }\n\n    /**\n     * Determine if an event should be faked or actually dispatched.\n     *\n     * @param  string  $eventName\n     * @param  mixed  $payload\n     * @return bool\n     */\n    protected function shouldFakeEvent($eventName, $payload)\n    {\n        if ($this->shouldDispatchEvent($eventName, $payload)) {\n            return false;\n        }\n\n        if (empty($this->eventsToFake)) {\n            return true;\n        }\n\n        return (new Collection($this->eventsToFake))\n            ->filter(function ($event) use ($eventName, $payload) {\n                return $event instanceof Closure\n                    ? $event($eventName, $payload)\n                    : $event === $eventName;\n            })\n            ->isNotEmpty();\n    }\n\n    /**\n     * Push the event onto the fake events array immediately or after the next database transaction.\n     *\n     * @param  string|object  $event\n     * @param  string  $name\n     * @param  array  $arguments\n     * @return void\n     */\n    protected function fakeEvent($event, $name, $arguments)\n    {\n        if ($event instanceof ShouldDispatchAfterCommit && Container::getInstance()->bound('db.transactions')) {\n            return Container::getInstance()->make('db.transactions')\n                ->addCallback(fn () => $this->events[$name][] = $arguments);\n        }\n\n        $this->events[$name][] = $arguments;\n    }\n\n    /**\n     * Determine whether an event should be dispatched or not.\n     *\n     * @param  string  $eventName\n     * @param  mixed  $payload\n     * @return bool\n     */\n    protected function shouldDispatchEvent($eventName, $payload)\n    {\n        if (empty($this->eventsToDispatch)) {\n            return false;\n        }\n\n        return (new Collection($this->eventsToDispatch))\n            ->filter(function ($event) use ($eventName, $payload) {\n                return $event instanceof Closure\n                    ? $event($eventName, $payload)\n                    : $event === $eventName;\n            })\n            ->isNotEmpty();\n    }\n\n    /**\n     * Remove a set of listeners from the dispatcher.\n     *\n     * @param  string  $event\n     * @return void\n     */\n    public function forget($event)\n    {\n        //\n    }\n\n    /**\n     * Forget all of the queued listeners.\n     *\n     * @return void\n     */\n    public function forgetPushed()\n    {\n        //\n    }\n\n    /**\n     * Dispatch an event and call the listeners.\n     *\n     * @param  string|object  $event\n     * @param  mixed  $payload\n     * @return mixed\n     */\n    public function until($event, $payload = [])\n    {\n        return $this->dispatch($event, $payload, true);\n    }\n\n    /**\n     * Get the events that have been dispatched.\n     *\n     * @return array\n     */\n    public function dispatchedEvents()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Handle dynamic method calls to the dispatcher.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->dispatcher, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/ExceptionHandlerFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Foundation\\Testing\\Concerns\\WithoutExceptionHandlingHandler;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Illuminate\\Testing\\Assert;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse Throwable;\n\n/**\n * @mixin \\Illuminate\\Foundation\\Exceptions\\Handler\n */\nclass ExceptionHandlerFake implements ExceptionHandler, Fake\n{\n    use ForwardsCalls, ReflectsClosures;\n\n    /**\n     * All of the exceptions that have been reported.\n     *\n     * @var list<\\Throwable>\n     */\n    protected $reported = [];\n\n    /**\n     * If the fake should throw exceptions when they are reported.\n     *\n     * @var bool\n     */\n    protected $throwOnReport = false;\n\n    /**\n     * Create a new exception handler fake.\n     *\n     * @param  \\Illuminate\\Contracts\\Debug\\ExceptionHandler  $handler\n     * @param  list<class-string<\\Throwable>>  $exceptions\n     */\n    public function __construct(\n        protected ExceptionHandler $handler,\n        protected array $exceptions = [],\n    ) {\n        //\n    }\n\n    /**\n     * Get the underlying handler implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Debug\\ExceptionHandler\n     */\n    public function handler()\n    {\n        return $this->handler;\n    }\n\n    /**\n     * Assert if an exception of the given type has been reported.\n     *\n     * @param  (\\Closure(\\Throwable): bool)|class-string<\\Throwable>  $exception\n     * @return void\n     */\n    public function assertReported(Closure|string $exception)\n    {\n        $message = sprintf(\n            'The expected [%s] exception was not reported.',\n            is_string($exception) ? $exception : $this->firstClosureParameterType($exception)\n        );\n\n        if (is_string($exception)) {\n            Assert::assertTrue(\n                in_array($exception, array_map(get_class(...), $this->reported), true),\n                $message,\n            );\n\n            return;\n        }\n\n        Assert::assertTrue(\n            (new Collection($this->reported))->contains(\n                fn (Throwable $e) => $this->firstClosureParameterType($exception) === get_class($e)\n                    && $exception($e) === true,\n            ), $message,\n        );\n    }\n\n    /**\n     * Assert the number of exceptions that have been reported.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertReportedCount(int $count)\n    {\n        $total = (new Collection($this->reported))->count();\n\n        PHPUnit::assertSame(\n            $count, $total,\n            \"The total number of exceptions reported was {$total} instead of {$count}.\"\n        );\n    }\n\n    /**\n     * Assert if an exception of the given type has not been reported.\n     *\n     * @param  (\\Closure(\\Throwable): bool)|class-string<\\Throwable>  $exception\n     * @return void\n     *\n     * @throws \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    public function assertNotReported(Closure|string $exception)\n    {\n        try {\n            $this->assertReported($exception);\n        } catch (ExpectationFailedException) {\n            return;\n        }\n\n        throw new ExpectationFailedException(sprintf(\n            'The expected [%s] exception was reported.',\n            is_string($exception) ? $exception : $this->firstClosureParameterType($exception)\n        ));\n    }\n\n    /**\n     * Assert nothing has been reported.\n     *\n     * @return void\n     */\n    public function assertNothingReported()\n    {\n        Assert::assertEmpty(\n            $this->reported,\n            sprintf(\n                'The following exceptions were reported: %s.',\n                implode(', ', array_map(get_class(...), $this->reported)),\n            ),\n        );\n    }\n\n    /**\n     * Report or log an exception.\n     *\n     * @param  \\Throwable  $e\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    public function report($e)\n    {\n        if (! $this->isFakedException($e)) {\n            $this->handler->report($e);\n\n            return;\n        }\n\n        if (! $this->shouldReport($e)) {\n            return;\n        }\n\n        $this->reported[] = $e;\n\n        if ($this->throwOnReport) {\n            throw $e;\n        }\n    }\n\n    /**\n     * Determine if the given exception is faked.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    protected function isFakedException(Throwable $e)\n    {\n        return count($this->exceptions) === 0 || in_array(get_class($e), $this->exceptions, true);\n    }\n\n    /**\n     * Determine if the exception should be reported.\n     *\n     * @param  \\Throwable  $e\n     * @return bool\n     */\n    public function shouldReport($e)\n    {\n        return $this->runningWithoutExceptionHandling() || $this->handler->shouldReport($e);\n    }\n\n    /**\n     * Determine if the handler is running without exception handling.\n     *\n     * @return bool\n     */\n    protected function runningWithoutExceptionHandling()\n    {\n        return $this->handler instanceof WithoutExceptionHandlingHandler;\n    }\n\n    /**\n     * Render an exception into an HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Throwable  $e\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function render($request, $e)\n    {\n        return $this->handler->render($request, $e);\n    }\n\n    /**\n     * Render an exception to the console.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     * @param  \\Throwable  $e\n     * @return void\n     */\n    public function renderForConsole($output, Throwable $e)\n    {\n        $this->handler->renderForConsole($output, $e);\n    }\n\n    /**\n     * Throw exceptions when they are reported.\n     *\n     * @return $this\n     */\n    public function throwOnReport()\n    {\n        $this->throwOnReport = true;\n\n        return $this;\n    }\n\n    /**\n     * Throw the first reported exception.\n     *\n     * @return $this\n     *\n     * @throws \\Throwable\n     */\n    public function throwFirstReported()\n    {\n        foreach ($this->reported as $e) {\n            throw $e;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the exceptions that have been reported.\n     *\n     * @return list<\\Throwable>\n     */\n    public function reported()\n    {\n        return $this->reported;\n    }\n\n    /**\n     * Set the \"original\" handler that should be used by the fake.\n     *\n     * @param  \\Illuminate\\Contracts\\Debug\\ExceptionHandler  $handler\n     * @return $this\n     */\n    public function setHandler(ExceptionHandler $handler)\n    {\n        $this->handler = $handler;\n\n        return $this;\n    }\n\n    /**\n     * Handle dynamic method calls to the handler.\n     *\n     * @param  string  $method\n     * @param  array<string, mixed>  $parameters\n     * @return mixed\n     */\n    public function __call(string $method, array $parameters)\n    {\n        return $this->forwardCallTo($this->handler, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/Fake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\ninterface Fake\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/MailFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Contracts\\Mail\\Factory;\nuse Illuminate\\Contracts\\Mail\\Mailable;\nuse Illuminate\\Contracts\\Mail\\Mailer;\nuse Illuminate\\Contracts\\Mail\\MailQueue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Mail\\MailManager;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\nclass MailFake implements Factory, Fake, Mailer, MailQueue\n{\n    use ForwardsCalls, ReflectsClosures;\n\n    /**\n     * The mailer instance.\n     *\n     * @var MailManager\n     */\n    public $manager;\n\n    /**\n     * The mailer currently being used to send a message.\n     *\n     * @var string\n     */\n    protected $currentMailer;\n\n    /**\n     * All of the mailables that have been sent.\n     *\n     * @var array\n     */\n    protected $mailables = [];\n\n    /**\n     * All of the mailables that have been queued.\n     *\n     * @var array\n     */\n    protected $queuedMailables = [];\n\n    /**\n     * Create a new mail fake.\n     *\n     * @param  MailManager  $manager\n     */\n    public function __construct(MailManager $manager)\n    {\n        $this->manager = $manager;\n        $this->currentMailer = $manager->getDefaultDriver();\n    }\n\n    /**\n     * Assert if a mailable was sent based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|array|string|int|null  $callback\n     * @return void\n     */\n    public function assertSent($mailable, $callback = null)\n    {\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        if (is_numeric($callback)) {\n            return $this->assertSentTimes($mailable, $callback);\n        }\n\n        $suggestion = count($this->queuedMailables) ? ' Did you mean to use assertQueued() instead?' : '';\n\n        if (is_array($callback) || is_string($callback)) {\n            foreach (Arr::wrap($callback) as $address) {\n                $callback = fn ($mail) => $mail->hasTo($address);\n\n                PHPUnit::assertTrue(\n                    $this->sent($mailable, $callback)->count() > 0,\n                    \"The expected [{$mailable}] mailable was not sent to address [{$address}].\".$suggestion\n                );\n            }\n\n            return;\n        }\n\n        PHPUnit::assertTrue(\n            $this->sent($mailable, $callback)->count() > 0,\n            \"The expected [{$mailable}] mailable was not sent.\".$suggestion\n        );\n    }\n\n    /**\n     * Assert if a mailable was sent a number of times.\n     *\n     * @param  string  $mailable\n     * @param  int  $times\n     * @return void\n     */\n    public function assertSentTimes($mailable, $times = 1)\n    {\n        $count = $this->sent($mailable)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$mailable}] mailable was sent {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if a mailable was not sent or queued to be sent based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotOutgoing($mailable, $callback = null)\n    {\n        $this->assertNotSent($mailable, $callback);\n        $this->assertNotQueued($mailable, $callback);\n    }\n\n    /**\n     * Determine if a mailable was not sent based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|array|string|null  $callback\n     * @return void\n     */\n    public function assertNotSent($mailable, $callback = null)\n    {\n        if (is_string($callback) || is_array($callback)) {\n            foreach (Arr::wrap($callback) as $address) {\n                $callback = fn ($mail) => $mail->hasTo($address);\n\n                PHPUnit::assertCount(\n                    0, $this->sent($mailable, $callback),\n                    \"The unexpected [{$mailable}] mailable was sent to address [{$address}].\"\n                );\n            }\n\n            return;\n        }\n\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        PHPUnit::assertCount(\n            0, $this->sent($mailable, $callback),\n            \"The unexpected [{$mailable}] mailable was sent.\"\n        );\n    }\n\n    /**\n     * Assert that no mailables were sent or queued to be sent.\n     *\n     * @return void\n     */\n    public function assertNothingOutgoing()\n    {\n        $this->assertNothingSent();\n        $this->assertNothingQueued();\n    }\n\n    /**\n     * Assert that no mailables were sent.\n     *\n     * @return void\n     */\n    public function assertNothingSent()\n    {\n        $mailableNames = (new Collection($this->mailables))->map(\n            fn ($mailable) => get_class($mailable)\n        )->join(\"\\n- \");\n\n        PHPUnit::assertEmpty($this->mailables, \"The following mailables were sent unexpectedly:\\n\\n- $mailableNames\\n\");\n    }\n\n    /**\n     * Assert if a mailable was queued based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|array|string|int|null  $callback\n     * @return void\n     */\n    public function assertQueued($mailable, $callback = null)\n    {\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        if (is_numeric($callback)) {\n            return $this->assertQueuedTimes($mailable, $callback);\n        }\n\n        if (is_string($callback) || is_array($callback)) {\n            foreach (Arr::wrap($callback) as $address) {\n                $callback = fn ($mail) => $mail->hasTo($address);\n\n                PHPUnit::assertTrue(\n                    $this->queued($mailable, $callback)->count() > 0,\n                    \"The expected [{$mailable}] mailable was not queued to address [{$address}].\"\n                );\n            }\n\n            return;\n        }\n\n        PHPUnit::assertTrue(\n            $this->queued($mailable, $callback)->count() > 0,\n            \"The expected [{$mailable}] mailable was not queued.\"\n        );\n    }\n\n    /**\n     * Assert if a mailable was queued a number of times.\n     *\n     * @param  string  $mailable\n     * @param  int  $times\n     * @return void\n     */\n    protected function assertQueuedTimes($mailable, $times = 1)\n    {\n        $count = $this->queued($mailable)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$mailable}] mailable was queued {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Determine if a mailable was not queued based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|array|string|null  $callback\n     * @return void\n     */\n    public function assertNotQueued($mailable, $callback = null)\n    {\n        if (is_string($callback) || is_array($callback)) {\n            foreach (Arr::wrap($callback) as $address) {\n                $callback = fn ($mail) => $mail->hasTo($address);\n\n                PHPUnit::assertCount(\n                    0, $this->queued($mailable, $callback),\n                    \"The unexpected [{$mailable}] mailable was queued to address [{$address}].\"\n                );\n            }\n\n            return;\n        }\n\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        PHPUnit::assertCount(\n            0, $this->queued($mailable, $callback),\n            \"The unexpected [{$mailable}] mailable was queued.\"\n        );\n    }\n\n    /**\n     * Assert that no mailables were queued.\n     *\n     * @return void\n     */\n    public function assertNothingQueued()\n    {\n        $mailableNames = (new Collection($this->queuedMailables))->map(\n            fn ($mailable) => get_class($mailable)\n        )->join(\"\\n- \");\n\n        PHPUnit::assertEmpty($this->queuedMailables, \"The following mailables were queued unexpectedly:\\n\\n- $mailableNames\\n\");\n    }\n\n    /**\n     * Assert the total number of mailables that were sent.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertSentCount($count)\n    {\n        $total = (new Collection($this->mailables))->count();\n\n        PHPUnit::assertSame(\n            $count, $total,\n            \"The total number of mailables sent was {$total} instead of {$count}.\"\n        );\n    }\n\n    /**\n     * Assert the total number of mailables that were queued.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertQueuedCount($count)\n    {\n        $total = (new Collection($this->queuedMailables))->count();\n\n        PHPUnit::assertSame(\n            $count, $total,\n            \"The total number of mailables queued was {$total} instead of {$count}.\"\n        );\n    }\n\n    /**\n     * Assert the total number of mailables that were sent or queued.\n     *\n     * @param  int  $count\n     * @return void\n     */\n    public function assertOutgoingCount($count)\n    {\n        $total = (new Collection($this->mailables))\n            ->concat($this->queuedMailables)\n            ->count();\n\n        PHPUnit::assertSame(\n            $count, $total,\n            \"The total number of outgoing mailables was {$total} instead of {$count}.\"\n        );\n    }\n\n    /**\n     * Get all of the mailables matching a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function sent($mailable, $callback = null)\n    {\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        if (! $this->hasSent($mailable)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return $this->mailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable));\n    }\n\n    /**\n     * Determine if the given mailable has been sent.\n     *\n     * @param  string  $mailable\n     * @return bool\n     */\n    public function hasSent($mailable)\n    {\n        return $this->mailablesOf($mailable)->count() > 0;\n    }\n\n    /**\n     * Get all of the queued mailables matching a truth-test callback.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function queued($mailable, $callback = null)\n    {\n        [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);\n\n        if (! $this->hasQueued($mailable)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return $this->queuedMailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable));\n    }\n\n    /**\n     * Determine if the given mailable has been queued.\n     *\n     * @param  string  $mailable\n     * @return bool\n     */\n    public function hasQueued($mailable)\n    {\n        return $this->queuedMailablesOf($mailable)->count() > 0;\n    }\n\n    /**\n     * Get all of the mailed mailables for a given type.\n     *\n     * @param  string  $type\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function mailablesOf($type)\n    {\n        return (new Collection($this->mailables))->filter(fn ($mailable) => $mailable instanceof $type);\n    }\n\n    /**\n     * Get all of the mailed mailables for a given type.\n     *\n     * @param  string  $type\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function queuedMailablesOf($type)\n    {\n        return (new Collection($this->queuedMailables))->filter(fn ($mailable) => $mailable instanceof $type);\n    }\n\n    /**\n     * Get a mailer instance by name.\n     *\n     * @param  string|null  $name\n     * @return \\Illuminate\\Contracts\\Mail\\Mailer\n     */\n    public function mailer($name = null)\n    {\n        $this->currentMailer = $name;\n\n        return $this;\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function to($users)\n    {\n        return (new PendingMailFake($this))->to($users);\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function cc($users)\n    {\n        return (new PendingMailFake($this))->cc($users);\n    }\n\n    /**\n     * Begin the process of mailing a mailable class instance.\n     *\n     * @param  mixed  $users\n     * @return \\Illuminate\\Mail\\PendingMail\n     */\n    public function bcc($users)\n    {\n        return (new PendingMailFake($this))->bcc($users);\n    }\n\n    /**\n     * Send a new message with only a raw text part.\n     *\n     * @param  string  $text\n     * @param  \\Closure|string  $callback\n     * @return void\n     */\n    public function raw($text, $callback)\n    {\n        //\n    }\n\n    /**\n     * Send a new message using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return mixed|void\n     */\n    public function send($view, array $data = [], $callback = null)\n    {\n        return $this->sendMail($view, $view instanceof ShouldQueue);\n    }\n\n    /**\n     * Send a new message synchronously using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $mailable\n     * @param  array  $data\n     * @param  \\Closure|string|null  $callback\n     * @return void\n     */\n    public function sendNow($mailable, array $data = [], $callback = null)\n    {\n        $this->sendMail($mailable, shouldQueue: false);\n    }\n\n    /**\n     * Send a new message using a view.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  bool  $shouldQueue\n     * @return mixed|void\n     */\n    protected function sendMail($view, $shouldQueue = false)\n    {\n        if (! $view instanceof Mailable) {\n            return;\n        }\n\n        $view->mailer($this->currentMailer);\n\n        if ($shouldQueue) {\n            return $this->queue($view);\n        }\n\n        $this->currentMailer = null;\n\n        $this->mailables[] = $view;\n    }\n\n    /**\n     * Queue a new message for sending.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function queue($view, $queue = null)\n    {\n        if (! $view instanceof Mailable) {\n            return;\n        }\n\n        $view->mailer($this->currentMailer);\n\n        $this->currentMailer = null;\n\n        $this->queuedMailables[] = $view;\n    }\n\n    /**\n     * Queue a new e-mail message for sending after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable|string|array  $view\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $view, $queue = null)\n    {\n        $this->queue($view, $queue);\n    }\n\n    /**\n     * Infer mailable class using reflection if a typehinted closure is passed to assertion.\n     *\n     * @param  string|\\Closure  $mailable\n     * @param  callable|null  $callback\n     * @return array\n     */\n    protected function prepareMailableAndCallback($mailable, $callback)\n    {\n        if ($mailable instanceof Closure) {\n            return [$this->firstClosureParameterType($mailable), $mailable];\n        }\n\n        return [$mailable, $callback];\n    }\n\n    /**\n     * Forget all of the resolved mailer instances.\n     *\n     * @return $this\n     */\n    public function forgetMailers()\n    {\n        $this->currentMailer = null;\n\n        return $this;\n    }\n\n    /**\n     * Handle dynamic method calls to the mailer.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo($this->manager, $method, $parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/NotificationFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Notifications\\Dispatcher as NotificationDispatcher;\nuse Illuminate\\Contracts\\Notifications\\Factory as NotificationFactory;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\nclass NotificationFake implements Fake, NotificationDispatcher, NotificationFactory\n{\n    use Macroable, ReflectsClosures;\n\n    /**\n     * All of the notifications that have been sent.\n     *\n     * @var array\n     */\n    protected $notifications = [];\n\n    /**\n     * Locale used when sending notifications.\n     *\n     * @var string|null\n     */\n    public $locale;\n\n    /**\n     * Indicates if notifications should be serialized and restored when pushed to the queue.\n     *\n     * @var bool\n     */\n    protected $serializeAndRestore = false;\n\n    /**\n     * Assert if a notification was sent on-demand based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $notification\n     * @param  callable|null  $callback\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function assertSentOnDemand($notification, $callback = null)\n    {\n        $this->assertSentTo(new AnonymousNotifiable, $notification, $callback);\n    }\n\n    /**\n     * Assert if a notification was sent based on a truth-test callback.\n     *\n     * @param  mixed  $notifiable\n     * @param  string|\\Closure  $notification\n     * @param  callable|null  $callback\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function assertSentTo($notifiable, $notification, $callback = null)\n    {\n        if (is_array($notifiable) || $notifiable instanceof Collection) {\n            if (count($notifiable) === 0) {\n                throw new Exception('No notifiable given.');\n            }\n\n            foreach ($notifiable as $singleNotifiable) {\n                $this->assertSentTo($singleNotifiable, $notification, $callback);\n            }\n\n            return;\n        }\n\n        if ($notification instanceof Closure) {\n            [$notification, $callback] = [$this->firstClosureParameterType($notification), $notification];\n        }\n\n        if (is_numeric($callback)) {\n            return $this->assertSentToTimes($notifiable, $notification, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->sent($notifiable, $notification, $callback)->count() > 0,\n            \"The expected [{$notification}] notification was not sent.\"\n        );\n    }\n\n    /**\n     * Assert if a notification was sent on-demand a number of times.\n     *\n     * @param  string  $notification\n     * @param  int  $times\n     * @return void\n     */\n    public function assertSentOnDemandTimes($notification, $times = 1)\n    {\n        $this->assertSentToTimes(new AnonymousNotifiable, $notification, $times);\n    }\n\n    /**\n     * Assert if a notification was sent a number of times.\n     *\n     * @param  mixed  $notifiable\n     * @param  string  $notification\n     * @param  int  $times\n     * @return void\n     */\n    public function assertSentToTimes($notifiable, $notification, $times = 1)\n    {\n        $count = $this->sent($notifiable, $notification)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            \"Expected [{$notification}] to be sent {$times} times, but was sent {$count} times.\"\n        );\n    }\n\n    /**\n     * Determine if a notification was sent based on a truth-test callback.\n     *\n     * @param  mixed  $notifiable\n     * @param  string|\\Closure  $notification\n     * @param  callable|null  $callback\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function assertNotSentTo($notifiable, $notification, $callback = null)\n    {\n        if (is_array($notifiable) || $notifiable instanceof Collection) {\n            if (count($notifiable) === 0) {\n                throw new Exception('No notifiable given.');\n            }\n\n            foreach ($notifiable as $singleNotifiable) {\n                $this->assertNotSentTo($singleNotifiable, $notification, $callback);\n            }\n\n            return;\n        }\n\n        if ($notification instanceof Closure) {\n            [$notification, $callback] = [$this->firstClosureParameterType($notification), $notification];\n        }\n\n        PHPUnit::assertCount(\n            0, $this->sent($notifiable, $notification, $callback),\n            \"The unexpected [{$notification}] notification was sent.\"\n        );\n    }\n\n    /**\n     * Assert that no notifications were sent.\n     *\n     * @return void\n     */\n    public function assertNothingSent()\n    {\n        $notificationNames = (new Collection($this->notifications))\n            ->map(fn ($notifiableModels) => (new Collection($notifiableModels))\n                ->map(fn ($notifiables) => (new Collection($notifiables))->keys())\n            )\n            ->flatten()->join(\"\\n- \");\n\n        PHPUnit::assertEmpty($this->notifications, \"The following notifications were sent unexpectedly:\\n\\n- $notificationNames\\n\");\n    }\n\n    /**\n     * Assert that no notifications were sent to the given notifiable.\n     *\n     * @param  mixed  $notifiable\n     * @return void\n     *\n     * @throws \\Exception\n     */\n    public function assertNothingSentTo($notifiable)\n    {\n        if (is_array($notifiable) || $notifiable instanceof Collection) {\n            if (count($notifiable) === 0) {\n                throw new Exception('No notifiable given.');\n            }\n\n            foreach ($notifiable as $singleNotifiable) {\n                $this->assertNothingSentTo($singleNotifiable);\n            }\n\n            return;\n        }\n\n        PHPUnit::assertEmpty(\n            $this->notifications[get_class($notifiable)][$notifiable->getKey() ?? ''] ?? [],\n            'Notifications were sent unexpectedly.',\n        );\n    }\n\n    /**\n     * Assert the total amount of times a notification was sent.\n     *\n     * @param  string  $notification\n     * @param  int  $expectedCount\n     * @return void\n     */\n    public function assertSentTimes($notification, $expectedCount)\n    {\n        $actualCount = (new Collection($this->notifications))\n            ->flatten(1)\n            ->reduce(fn ($count, $sent) => $count + count($sent[$notification] ?? []), 0);\n\n        PHPUnit::assertSame(\n            $expectedCount, $actualCount,\n            sprintf(\n                \"Expected [{$notification}] to be sent {$expectedCount} %s, but was sent {$actualCount} %s.\",\n                Str::plural('time', $expectedCount),\n                Str::plural('time', $actualCount)\n            )\n        );\n    }\n\n    /**\n     * Assert the total count of notification that were sent.\n     *\n     * @param  int  $expectedCount\n     * @return void\n     */\n    public function assertCount($expectedCount)\n    {\n        $actualCount = (new Collection($this->notifications))->flatten(3)->count();\n\n        PHPUnit::assertSame(\n            $expectedCount, $actualCount,\n            \"Expected {$expectedCount} notifications to be sent, but {$actualCount} were sent.\"\n        );\n    }\n\n    /**\n     * Get all of the notifications matching a truth-test callback.\n     *\n     * @param  mixed  $notifiable\n     * @param  string  $notification\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function sent($notifiable, $notification, $callback = null)\n    {\n        if (! $this->hasSent($notifiable, $notification)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        $notifications = new Collection($this->notificationsFor($notifiable, $notification));\n\n        return $notifications->filter(\n            fn ($arguments) => $callback(...array_values($arguments))\n        )->pluck('notification');\n    }\n\n    /**\n     * Determine if there are more notifications left to inspect.\n     *\n     * @param  mixed  $notifiable\n     * @param  string  $notification\n     * @return bool\n     */\n    public function hasSent($notifiable, $notification)\n    {\n        return ! empty($this->notificationsFor($notifiable, $notification));\n    }\n\n    /**\n     * Get all of the notifications for a notifiable entity by type.\n     *\n     * @param  mixed  $notifiable\n     * @param  string  $notification\n     * @return array\n     */\n    protected function notificationsFor($notifiable, $notification)\n    {\n        return $this->notifications[get_class($notifiable)][(string) $notifiable->getKey()][$notification] ?? [];\n    }\n\n    /**\n     * Send the given notification to the given notifiable entities.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @return void\n     */\n    public function send($notifiables, $notification)\n    {\n        $this->sendNow($notifiables, $notification);\n    }\n\n    /**\n     * Send the given notification immediately.\n     *\n     * @param  \\Illuminate\\Support\\Collection|mixed  $notifiables\n     * @param  mixed  $notification\n     * @param  array|null  $channels\n     * @return void\n     */\n    public function sendNow($notifiables, $notification, ?array $channels = null)\n    {\n        if (! $notifiables instanceof Collection && ! is_array($notifiables)) {\n            $notifiables = [$notifiables];\n        }\n\n        foreach ($notifiables as $notifiable) {\n            if (! $notification->id) {\n                $notification->id = (string) Str::uuid();\n            }\n\n            $notifiableChannels = $channels ?: $notification->via($notifiable);\n\n            if (method_exists($notification, 'shouldSend')) {\n                $notifiableChannels = array_filter(\n                    $notifiableChannels,\n                    fn ($channel) => $notification->shouldSend($notifiable, $channel) !== false\n                );\n            }\n\n            if (empty($notifiableChannels)) {\n                continue;\n            }\n\n            $this->notifications[get_class($notifiable)][(string) $notifiable->getKey()][get_class($notification)][] = [\n                'notification' => $this->serializeAndRestore && $notification instanceof ShouldQueue\n                    ? $this->serializeAndRestoreNotification($notification)\n                    : $notification,\n                'channels' => $notifiableChannels,\n                'notifiable' => $notifiable,\n                'locale' => $notification->locale ?? $this->locale ?? value(function () use ($notifiable) {\n                    if ($notifiable instanceof HasLocalePreference) {\n                        return $notifiable->preferredLocale();\n                    }\n                }),\n            ];\n        }\n    }\n\n    /**\n     * Get a channel instance by name.\n     *\n     * @param  string|null  $name\n     * @return mixed\n     */\n    public function channel($name = null)\n    {\n        //\n    }\n\n    /**\n     * Set the locale of notifications.\n     *\n     * @param  string  $locale\n     * @return $this\n     */\n    public function locale($locale)\n    {\n        $this->locale = $locale;\n\n        return $this;\n    }\n\n    /**\n     * Specify if notification should be serialized and restored when being \"pushed\" to the queue.\n     *\n     * @param  bool  $serializeAndRestore\n     * @return $this\n     */\n    public function serializeAndRestore(bool $serializeAndRestore = true)\n    {\n        $this->serializeAndRestore = $serializeAndRestore;\n\n        return $this;\n    }\n\n    /**\n     * Serialize and unserialize the notification to simulate the queueing process.\n     *\n     * @param  mixed  $notification\n     * @return mixed\n     */\n    protected function serializeAndRestoreNotification($notification)\n    {\n        return unserialize(serialize($notification));\n    }\n\n    /**\n     * Get the notifications that have been sent.\n     *\n     * @return array\n     */\n    public function sentNotifications()\n    {\n        return $this->notifications;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/PendingBatchFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\n\nclass PendingBatchFake extends PendingBatch\n{\n    use ReflectsClosures;\n\n    /**\n     * The fake bus instance.\n     *\n     * @var \\Illuminate\\Support\\Testing\\Fakes\\BusFake\n     */\n    protected $bus;\n\n    /**\n     * Create a new pending batch instance.\n     *\n     * @param  \\Illuminate\\Support\\Testing\\Fakes\\BusFake  $bus\n     * @param  \\Illuminate\\Support\\Collection  $jobs\n     */\n    public function __construct(BusFake $bus, Collection $jobs)\n    {\n        $this->bus = $bus;\n        $this->jobs = $jobs->filter()->values();\n    }\n\n    /**\n     * Dispatch the batch.\n     *\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function dispatch()\n    {\n        return $this->bus->recordPendingBatch($this);\n    }\n\n    /**\n     * Dispatch the batch after the response is sent to the browser.\n     *\n     * @return \\Illuminate\\Bus\\Batch\n     */\n    public function dispatchAfterResponse()\n    {\n        return $this->bus->recordPendingBatch($this);\n    }\n\n    /**\n     * Determine if the jobs in the batch match the given jobs.\n     *\n     * @param  array  $expectedJobs\n     * @return bool\n     */\n    public function hasJobs(array $expectedJobs)\n    {\n        if (count($this->jobs) !== count($expectedJobs)) {\n            return false;\n        }\n\n        foreach ($expectedJobs as $index => $expectedJob) {\n            if ($expectedJob instanceof Closure) {\n                $expectedType = $this->firstClosureParameterType($expectedJob);\n\n                if (! $this->jobs[$index] instanceof $expectedType) {\n                    return false;\n                }\n\n                if (! $expectedJob($this->jobs[$index])) {\n                    return false;\n                }\n            } elseif (is_string($expectedJob)) {\n                if ($expectedJob != get_class($this->jobs[$index])) {\n                    return false;\n                }\n            } elseif (serialize($expectedJob) != serialize($this->jobs[$index])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/PendingChainFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Closure;\nuse Illuminate\\Foundation\\Bus\\PendingChain;\nuse Illuminate\\Queue\\CallQueuedClosure;\n\nclass PendingChainFake extends PendingChain\n{\n    /**\n     * The fake bus instance.\n     *\n     * @var \\Illuminate\\Support\\Testing\\Fakes\\BusFake\n     */\n    protected $bus;\n\n    /**\n     * Create a new pending chain instance.\n     *\n     * @param  \\Illuminate\\Support\\Testing\\Fakes\\BusFake  $bus\n     * @param  mixed  $job\n     * @param  array  $chain\n     */\n    public function __construct(BusFake $bus, $job, $chain)\n    {\n        $this->bus = $bus;\n        $this->job = $job;\n        $this->chain = $chain;\n    }\n\n    /**\n     * Dispatch the job with the given arguments.\n     *\n     * @return \\Illuminate\\Foundation\\Bus\\PendingDispatch\n     */\n    public function dispatch()\n    {\n        if (is_string($this->job)) {\n            $firstJob = new $this->job(...func_get_args());\n        } elseif ($this->job instanceof Closure) {\n            $firstJob = CallQueuedClosure::create($this->job);\n        } else {\n            $firstJob = $this->job;\n        }\n\n        $firstJob->allOnConnection($this->connection);\n        $firstJob->allOnQueue($this->queue);\n        $firstJob->chain($this->chain);\n        $firstJob->delay($this->delay);\n        $firstJob->chainCatchCallbacks = $this->catchCallbacks();\n\n        return $this->bus->dispatch($firstJob);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/PendingMailFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse Illuminate\\Contracts\\Mail\\Mailable;\nuse Illuminate\\Mail\\PendingMail;\n\nclass PendingMailFake extends PendingMail\n{\n    /**\n     * Create a new instance.\n     *\n     * @param  \\Illuminate\\Support\\Testing\\Fakes\\MailFake  $mailer\n     */\n    public function __construct($mailer)\n    {\n        $this->mailer = $mailer;\n    }\n\n    /**\n     * Send a new mailable message instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return void\n     */\n    public function send(Mailable $mailable)\n    {\n        $this->mailer->send($this->fill($mailable));\n    }\n\n    /**\n     * Send a new mailable message instance synchronously.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return void\n     */\n    public function sendNow(Mailable $mailable)\n    {\n        $this->mailer->sendNow($this->fill($mailable));\n    }\n\n    /**\n     * Push the given mailable onto the queue.\n     *\n     * @param  \\Illuminate\\Contracts\\Mail\\Mailable  $mailable\n     * @return mixed\n     */\n    public function queue(Mailable $mailable)\n    {\n        return $this->mailer->queue($this->fill($mailable));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Testing/Fakes/QueueFake.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Testing\\Fakes;\n\nuse BadMethodCallException;\nuse Closure;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Queue;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Events\\CallQueuedListener;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Queue\\QueueManager;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\n/**\n * @phpstan-type RawPushType array{\"payload\": string, \"queue\": string|null, \"options\": array<array-key, mixed>}\n */\nclass QueueFake extends QueueManager implements Fake, Queue\n{\n    use ReflectsClosures;\n\n    /**\n     * The original queue manager.\n     *\n     * @var \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public $queue;\n\n    /**\n     * The job types that should be intercepted instead of pushed to the queue.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $jobsToFake;\n\n    /**\n     * The job types that should be pushed to the queue and not intercepted.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    protected $jobsToBeQueued;\n\n    /**\n     * All of the jobs that have been pushed.\n     *\n     * @var array\n     */\n    protected $jobs = [];\n\n    /**\n     * All of the payloads that have been raw pushed.\n     *\n     * @var list<RawPushType>\n     */\n    protected $rawPushes = [];\n\n    /**\n     * All of the unique jobs that were pushed.\n     *\n     * @var array\n     */\n    private $uniqueJobs = [];\n\n    /**\n     * Indicates if items should be serialized and restored when pushed to the queue.\n     *\n     * @var bool\n     */\n    protected bool $serializeAndRestore = false;\n\n    /**\n     * Create a new fake queue instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Foundation\\Application  $app\n     * @param  array  $jobsToFake\n     * @param  \\Illuminate\\Queue\\QueueManager|null  $queue\n     */\n    public function __construct($app, $jobsToFake = [], $queue = null)\n    {\n        parent::__construct($app);\n\n        $this->jobsToFake = Collection::wrap($jobsToFake);\n        $this->jobsToBeQueued = new Collection;\n        $this->queue = $queue;\n    }\n\n    /**\n     * Specify the jobs that should be queued instead of faked.\n     *\n     * @param  array|string  $jobsToBeQueued\n     * @return $this\n     */\n    public function except($jobsToBeQueued)\n    {\n        $this->jobsToBeQueued = Collection::wrap($jobsToBeQueued)->merge($this->jobsToBeQueued);\n\n        return $this;\n    }\n\n    /**\n     * Assert if a job was pushed based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $job\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertPushed($job, $callback = null)\n    {\n        if ($job instanceof Closure) {\n            [$job, $callback] = [$this->firstClosureParameterType($job), $job];\n        }\n\n        if (is_numeric($callback)) {\n            return $this->assertPushedTimes($job, $callback);\n        }\n\n        PHPUnit::assertTrue(\n            $this->pushed($job, $callback)->count() > 0,\n            \"The expected [{$job}] job was not pushed.\"\n        );\n    }\n\n    /**\n     * Assert if a job was pushed a number of times.\n     *\n     * @param  string  $job\n     * @param  int  $times\n     * @return void\n     */\n    public function assertPushedTimes($job, $times = 1)\n    {\n        $count = $this->pushed($job)->count();\n\n        PHPUnit::assertSame(\n            $times, $count,\n            sprintf(\n                \"The expected [{$job}] job was pushed {$count} %s instead of {$times} %s.\",\n                Str::plural('time', $count),\n                Str::plural('time', $times)\n            )\n        );\n    }\n\n    /**\n     * Assert if a job was pushed based on a truth-test callback.\n     *\n     * @param  string  $queue\n     * @param  string|\\Closure  $job\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertPushedOn($queue, $job, $callback = null)\n    {\n        if ($job instanceof Closure) {\n            [$job, $callback] = [$this->firstClosureParameterType($job), $job];\n        }\n\n        $this->assertPushed($job, function ($job, $pushedQueue) use ($callback, $queue) {\n            if ($pushedQueue !== $queue) {\n                return false;\n            }\n\n            return $callback ? $callback(...func_get_args()) : true;\n        });\n    }\n\n    /**\n     * Assert if a job was pushed with chained jobs based on a truth-test callback.\n     *\n     * @param  string  $job\n     * @param  array  $expectedChain\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertPushedWithChain($job, $expectedChain = [], $callback = null)\n    {\n        PHPUnit::assertTrue(\n            $this->pushed($job, $callback)->isNotEmpty(),\n            \"The expected [{$job}] job was not pushed.\"\n        );\n\n        PHPUnit::assertTrue(\n            (new Collection($expectedChain))->isNotEmpty(),\n            'The expected chain can not be empty.'\n        );\n\n        $this->isChainOfObjects($expectedChain)\n            ? $this->assertPushedWithChainOfObjects($job, $expectedChain, $callback)\n            : $this->assertPushedWithChainOfClasses($job, $expectedChain, $callback);\n    }\n\n    /**\n     * Assert if a job was pushed with an empty chain based on a truth-test callback.\n     *\n     * @param  string  $job\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertPushedWithoutChain($job, $callback = null)\n    {\n        PHPUnit::assertTrue(\n            $this->pushed($job, $callback)->isNotEmpty(),\n            \"The expected [{$job}] job was not pushed.\"\n        );\n\n        $this->assertPushedWithChainOfClasses($job, [], $callback);\n    }\n\n    /**\n     * Assert if a job was pushed with chained jobs based on a truth-test callback.\n     *\n     * @param  string  $job\n     * @param  array  $expectedChain\n     * @param  callable|null  $callback\n     * @return void\n     */\n    protected function assertPushedWithChainOfObjects($job, $expectedChain, $callback)\n    {\n        $chain = (new Collection($expectedChain))->map(fn ($job) => serialize($job))->all();\n\n        PHPUnit::assertTrue(\n            $this->pushed($job, $callback)->filter(fn ($job) => $job->chained == $chain)->isNotEmpty(),\n            'The expected chain was not pushed.'\n        );\n    }\n\n    /**\n     * Assert if a job was pushed with chained jobs based on a truth-test callback.\n     *\n     * @param  string  $job\n     * @param  array  $expectedChain\n     * @param  callable|null  $callback\n     * @return void\n     */\n    protected function assertPushedWithChainOfClasses($job, $expectedChain, $callback)\n    {\n        $matching = $this->pushed($job, $callback)->map->chained->map(function ($chain) {\n            return (new Collection($chain))->map(function ($job) {\n                return get_class(unserialize($job));\n            });\n        })->filter(function ($chain) use ($expectedChain) {\n            return $chain->all() === $expectedChain;\n        });\n\n        PHPUnit::assertTrue(\n            $matching->isNotEmpty(), 'The expected chain was not pushed.'\n        );\n    }\n\n    /**\n     * Assert if a closure was pushed based on a truth-test callback.\n     *\n     * @param  callable|int|null  $callback\n     * @return void\n     */\n    public function assertClosurePushed($callback = null)\n    {\n        $this->assertPushed(CallQueuedClosure::class, $callback);\n    }\n\n    /**\n     * Assert that a closure was not pushed based on a truth-test callback.\n     *\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertClosureNotPushed($callback = null)\n    {\n        $this->assertNotPushed(CallQueuedClosure::class, $callback);\n    }\n\n    /**\n     * Determine if the given chain is entirely composed of objects.\n     *\n     * @param  array  $chain\n     * @return bool\n     */\n    protected function isChainOfObjects($chain)\n    {\n        return ! (new Collection($chain))->contains(fn ($job) => ! is_object($job));\n    }\n\n    /**\n     * Determine if a job was pushed based on a truth-test callback.\n     *\n     * @param  string|\\Closure  $job\n     * @param  callable|null  $callback\n     * @return void\n     */\n    public function assertNotPushed($job, $callback = null)\n    {\n        if ($job instanceof Closure) {\n            [$job, $callback] = [$this->firstClosureParameterType($job), $job];\n        }\n\n        PHPUnit::assertCount(\n            0, $this->pushed($job, $callback),\n            \"The unexpected [{$job}] job was pushed.\"\n        );\n    }\n\n    /**\n     * Assert the total count of jobs that were pushed.\n     *\n     * @param  int  $expectedCount\n     * @return void\n     */\n    public function assertCount($expectedCount)\n    {\n        $actualCount = (new Collection($this->jobs))->flatten(1)->count();\n\n        PHPUnit::assertSame(\n            $expectedCount, $actualCount,\n            \"Expected {$expectedCount} jobs to be pushed, but found {$actualCount} instead.\"\n        );\n    }\n\n    /**\n     * Assert that no jobs were pushed.\n     *\n     * @return void\n     */\n    public function assertNothingPushed()\n    {\n        $pushedJobs = implode(\"\\n- \", array_keys($this->jobs));\n\n        PHPUnit::assertEmpty($this->jobs, \"The following jobs were pushed unexpectedly:\\n\\n- $pushedJobs\\n\");\n    }\n\n    /**\n     * Get all of the jobs matching a truth-test callback.\n     *\n     * @param  string  $job\n     * @param  callable|null  $callback\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function pushed($job, $callback = null)\n    {\n        if (! $this->hasPushed($job)) {\n            return new Collection;\n        }\n\n        $callback = $callback ?: fn () => true;\n\n        return (new Collection($this->jobs[$job]))->filter(\n            fn ($data) => $callback($data['job'], $data['queue'], $data['data'])\n        )->pluck('job');\n    }\n\n    /**\n     * Get all of the raw pushes matching a truth-test callback.\n     *\n     * @param  null|\\Closure(string, ?string, array): bool  $callback\n     * @return \\Illuminate\\Support\\Collection<int, RawPushType>\n     */\n    public function pushedRaw($callback = null)\n    {\n        $callback ??= static fn () => true;\n\n        return (new Collection($this->rawPushes))->filter(fn ($data) => $callback($data['payload'], $data['queue'], $data['options']));\n    }\n\n    /**\n     * Get all of the jobs by listener class, passing an optional truth-test callback.\n     *\n     * @param  class-string  $listenerClass\n     * @param  (\\Closure(mixed, \\Illuminate\\Events\\CallQueuedListener, string|null, mixed): bool)|null  $callback\n     * @return \\Illuminate\\Support\\Collection<int, \\Illuminate\\Events\\CallQueuedListener>\n     */\n    public function listenersPushed($listenerClass, $callback = null)\n    {\n        if (! $this->hasPushed(CallQueuedListener::class)) {\n            return new Collection;\n        }\n\n        $collection = (new Collection($this->jobs[CallQueuedListener::class]))\n            ->filter(fn ($data) => $data['job']->class === $listenerClass);\n\n        if ($callback) {\n            $collection = $collection->filter(fn ($data) => $callback($data['job']->data[0] ?? null, $data['job'], $data['queue'], $data['data']));\n        }\n\n        return $collection->pluck('job');\n    }\n\n    /**\n     * Determine if there are any stored jobs for a given class.\n     *\n     * @param  string  $job\n     * @return bool\n     */\n    public function hasPushed($job)\n    {\n        return isset($this->jobs[$job]) && ! empty($this->jobs[$job]);\n    }\n\n    /**\n     * Resolve a queue connection instance.\n     *\n     * @param  mixed  $value\n     * @return \\Illuminate\\Contracts\\Queue\\Queue\n     */\n    public function connection($value = null)\n    {\n        return $this;\n    }\n\n    /**\n     * Get the size of the queue.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function size($queue = null)\n    {\n        return (new Collection($this->jobs))\n            ->flatten(1)\n            ->filter(fn ($job) => $job['queue'] === $queue)\n            ->count();\n    }\n\n    /**\n     * Get the number of pending jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function pendingSize($queue = null)\n    {\n        return $this->size($queue);\n    }\n\n    /**\n     * Get the number of delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function delayedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the number of reserved jobs.\n     *\n     * @param  string|null  $queue\n     * @return int\n     */\n    public function reservedSize($queue = null)\n    {\n        return 0;\n    }\n\n    /**\n     * Get the creation timestamp of the oldest pending job, excluding delayed jobs.\n     *\n     * @param  string|null  $queue\n     * @return int|null\n     */\n    public function creationTimeOfOldestPendingJob($queue = null)\n    {\n        return null;\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function push($job, $data = '', $queue = null)\n    {\n        if ($this->shouldFakeJob($job)) {\n            if ($job instanceof Closure) {\n                $job = CallQueuedClosure::create($job);\n            }\n\n            $this->jobs[is_object($job) ? get_class($job) : $job][] = [\n                'job' => $this->serializeAndRestore ? $this->serializeAndRestoreJob($job) : $job,\n                'queue' => $queue,\n                'data' => $data,\n            ];\n\n            if ($job instanceof ShouldBeUnique) {\n                $this->uniqueJobs[] = $job;\n            }\n        } else {\n            is_object($job) && isset($job->connection)\n                ? $this->queue->connection($job->connection)->push($job, $data, $queue)\n                : $this->queue->push($job, $data, $queue);\n        }\n    }\n\n    /**\n     * Determine if a job should be faked or actually dispatched.\n     *\n     * @param  object  $job\n     * @return bool\n     */\n    public function shouldFakeJob($job)\n    {\n        if ($this->shouldDispatchJob($job)) {\n            return false;\n        }\n\n        if ($this->jobsToFake->isEmpty()) {\n            return true;\n        }\n\n        return $this->jobsToFake->contains(\n            fn ($jobToFake) => $job instanceof ((string) $jobToFake) || $job === (string) $jobToFake\n        );\n    }\n\n    /**\n     * Determine if a job should be pushed to the queue instead of faked.\n     *\n     * @param  object  $job\n     * @return bool\n     */\n    protected function shouldDispatchJob($job)\n    {\n        if ($this->jobsToBeQueued->isEmpty()) {\n            return false;\n        }\n\n        return $this->jobsToBeQueued->contains(\n            fn ($jobToQueue) => $job instanceof ((string) $jobToQueue)\n        );\n    }\n\n    /**\n     * Push a raw payload onto the queue.\n     *\n     * @param  string  $payload\n     * @param  string|null  $queue\n     * @param  array  $options\n     * @return mixed\n     */\n    public function pushRaw($payload, $queue = null, array $options = [])\n    {\n        $this->rawPushes[] = [\n            'payload' => $payload,\n            'queue' => $queue,\n            'options' => $options,\n        ];\n    }\n\n    /**\n     * Push a new job onto the queue after (n) seconds.\n     *\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function later($delay, $job, $data = '', $queue = null)\n    {\n        return $this->push($job, $data, $queue);\n    }\n\n    /**\n     * Push a new job onto the queue.\n     *\n     * @param  string  $queue\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function pushOn($queue, $job, $data = '')\n    {\n        return $this->push($job, $data, $queue);\n    }\n\n    /**\n     * Push a new job onto a specific queue after (n) seconds.\n     *\n     * @param  string  $queue\n     * @param  \\DateTimeInterface|\\DateInterval|int  $delay\n     * @param  string|object  $job\n     * @param  mixed  $data\n     * @return mixed\n     */\n    public function laterOn($queue, $delay, $job, $data = '')\n    {\n        return $this->push($job, $data, $queue);\n    }\n\n    /**\n     * Pop the next job off of the queue.\n     *\n     * @param  string|null  $queue\n     * @return \\Illuminate\\Contracts\\Queue\\Job|null\n     */\n    public function pop($queue = null)\n    {\n        //\n    }\n\n    /**\n     * Push an array of jobs onto the queue.\n     *\n     * @param  array  $jobs\n     * @param  mixed  $data\n     * @param  string|null  $queue\n     * @return mixed\n     */\n    public function bulk($jobs, $data = '', $queue = null)\n    {\n        foreach ($jobs as $job) {\n            $this->push($job, $data, $queue);\n        }\n    }\n\n    /**\n     * Get the jobs that have been pushed.\n     *\n     * @return array\n     */\n    public function pushedJobs()\n    {\n        return $this->jobs;\n    }\n\n    /**\n     * Get the payloads that were pushed raw.\n     *\n     * @return list<RawPushType>\n     */\n    public function rawPushes()\n    {\n        return $this->rawPushes;\n    }\n\n    /**\n     * Specify if jobs should be serialized and restored when being \"pushed\" to the queue.\n     *\n     * @param  bool  $serializeAndRestore\n     * @return $this\n     */\n    public function serializeAndRestore(bool $serializeAndRestore = true)\n    {\n        $this->serializeAndRestore = $serializeAndRestore;\n\n        return $this;\n    }\n\n    /**\n     * Serialize and unserialize the job to simulate the queueing process.\n     *\n     * @param  mixed  $job\n     * @return mixed\n     */\n    protected function serializeAndRestoreJob($job)\n    {\n        return unserialize(serialize($job));\n    }\n\n    /**\n     * Release the locks for all unique jobs that were pushed.\n     *\n     * @return void\n     */\n    public function releaseUniqueJobLocks()\n    {\n        $lock = new UniqueLock($this->app->make(Cache::class));\n\n        foreach ($this->uniqueJobs as $job) {\n            $lock->release($job);\n        }\n\n        $this->uniqueJobs = [];\n    }\n\n    /**\n     * Get the connection name for the queue.\n     *\n     * @return string\n     */\n    public function getConnectionName()\n    {\n        //\n    }\n\n    /**\n     * Set the connection name for the queue.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function setConnectionName($name)\n    {\n        return $this;\n    }\n\n    /**\n     * Override the QueueManager to prevent circular dependency.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        throw new BadMethodCallException(sprintf(\n            'Call to undefined method %s::%s()', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Timebox.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Throwable;\n\nclass Timebox\n{\n    /**\n     * Indicates if the timebox is allowed to return early.\n     *\n     * @var bool\n     */\n    public $earlyReturn = false;\n\n    /**\n     * Invoke the given callback within the specified timebox minimum.\n     *\n     * @template TCallReturnType\n     *\n     * @param  (callable($this): TCallReturnType)  $callback\n     * @param  int  $microseconds\n     * @return TCallReturnType\n     *\n     * @throws \\Throwable\n     */\n    public function call(callable $callback, int $microseconds)\n    {\n        $exception = null;\n\n        $start = microtime(true);\n\n        try {\n            $result = $callback($this);\n        } catch (Throwable $caught) {\n            $exception = $caught;\n        }\n\n        $remainder = (int) ($microseconds - ((microtime(true) - $start) * 1_000_000));\n\n        if (! $this->earlyReturn && $remainder > 0) {\n            $this->usleep($remainder);\n        }\n\n        if ($exception) {\n            throw $exception;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Indicate that the timebox can return early.\n     *\n     * @return $this\n     */\n    public function returnEarly()\n    {\n        $this->earlyReturn = true;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the timebox cannot return early.\n     *\n     * @return $this\n     */\n    public function dontReturnEarly()\n    {\n        $this->earlyReturn = false;\n\n        return $this;\n    }\n\n    /**\n     * Sleep for the specified number of microseconds.\n     *\n     * @param  int  $microseconds\n     * @return void\n     */\n    protected function usleep(int $microseconds)\n    {\n        Sleep::usleep($microseconds);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/CapsuleManagerTrait.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Fluent;\n\ntrait CapsuleManagerTrait\n{\n    /**\n     * The current globally used instance.\n     *\n     * @var object\n     */\n    protected static $instance;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Setup the IoC container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    protected function setupContainer(Container $container)\n    {\n        $this->container = $container;\n\n        if (! $this->container->bound('config')) {\n            $this->container->instance('config', new Fluent);\n        }\n    }\n\n    /**\n     * Make this capsule instance available globally.\n     *\n     * @return void\n     */\n    public function setAsGlobal()\n    {\n        static::$instance = $this;\n    }\n\n    /**\n     * Get the IoC container instance.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the IoC container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/Dumpable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\ntrait Dumpable\n{\n    /**\n     * Dump the given arguments and terminate execution.\n     *\n     * @param  mixed  ...$args\n     * @return never\n     */\n    public function dd(...$args)\n    {\n        dd($this, ...$args);\n    }\n\n    /**\n     * Dump the given arguments.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args)\n    {\n        dump($this, ...$args);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/ForwardsCalls.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse BadMethodCallException;\nuse Error;\n\ntrait ForwardsCalls\n{\n    /**\n     * Forward a method call to the given object.\n     *\n     * @param  mixed  $object\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    protected function forwardCallTo($object, $method, $parameters)\n    {\n        try {\n            return $object->{$method}(...$parameters);\n        } catch (Error|BadMethodCallException $e) {\n            $pattern = '~^Call to undefined method (?P<class>[^:]+)::(?P<method>[^\\(]+)\\(\\)$~';\n\n            if (! preg_match($pattern, $e->getMessage(), $matches)) {\n                throw $e;\n            }\n\n            if ($matches['class'] != get_class($object) ||\n                $matches['method'] != $method) {\n                throw $e;\n            }\n\n            static::throwBadMethodCallException($method);\n        }\n    }\n\n    /**\n     * Forward a method call to the given object, returning $this if the forwarded call returned itself.\n     *\n     * @param  mixed  $object\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    protected function forwardDecoratedCallTo($object, $method, $parameters)\n    {\n        $result = $this->forwardCallTo($object, $method, $parameters);\n\n        return $result === $object ? $this : $result;\n    }\n\n    /**\n     * Throw a bad method call exception for the given method.\n     *\n     * @param  string  $method\n     * @return never\n     *\n     * @throws \\BadMethodCallException\n     */\n    protected static function throwBadMethodCallException($method)\n    {\n        throw new BadMethodCallException(sprintf(\n            'Call to undefined method %s::%s()', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/InteractsWithData.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Carbon\\CarbonInterval;\nuse Carbon\\Unit;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Number;\nuse Illuminate\\Support\\Str;\nuse stdClass;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait InteractsWithData\n{\n    /**\n     * Retrieve all data from the instance.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    abstract public function all($keys = null);\n\n    /**\n     * Retrieve data from the instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    abstract protected function data($key = null, $default = null);\n\n    /**\n     * Determine if the data contains a given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function exists($key)\n    {\n        return $this->has($key);\n    }\n\n    /**\n     * Determine if the data contains a given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function has($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        $data = $this->all();\n\n        foreach ($keys as $value) {\n            if (! Arr::has($data, $value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if the instance contains any of the given keys.\n     *\n     * @param  string|array  $keys\n     * @return bool\n     */\n    public function hasAny($keys)\n    {\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        $data = $this->all();\n\n        return Arr::hasAny($data, $keys);\n    }\n\n    /**\n     * Apply the callback if the instance contains the given key.\n     *\n     * @param  string  $key\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return $this|mixed\n     */\n    public function whenHas($key, callable $callback, ?callable $default = null)\n    {\n        if ($this->has($key)) {\n            return $callback(data_get($this->all(), $key)) ?: $this;\n        }\n\n        if ($default) {\n            return $default();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the instance contains a non-empty value for the given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function filled($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        foreach ($keys as $value) {\n            if ($this->isEmptyString($value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if the instance contains an empty value for the given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function isNotFilled($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        foreach ($keys as $value) {\n            if (! $this->isEmptyString($value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if the instance contains a non-empty value for any of the given keys.\n     *\n     * @param  string|array  $keys\n     * @return bool\n     */\n    public function anyFilled($keys)\n    {\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        foreach ($keys as $key) {\n            if ($this->filled($key)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Apply the callback if the instance contains a non-empty value for the given key.\n     *\n     * @param  string  $key\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return $this|mixed\n     */\n    public function whenFilled($key, callable $callback, ?callable $default = null)\n    {\n        if ($this->filled($key)) {\n            return $callback(data_get($this->all(), $key)) ?: $this;\n        }\n\n        if ($default) {\n            return $default();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the instance is missing a given key.\n     *\n     * @param  string|array  $key\n     * @return bool\n     */\n    public function missing($key)\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        return ! $this->has($keys);\n    }\n\n    /**\n     * Apply the callback if the instance is missing the given key.\n     *\n     * @param  string  $key\n     * @param  callable  $callback\n     * @param  callable|null  $default\n     * @return $this|mixed\n     */\n    public function whenMissing($key, callable $callback, ?callable $default = null)\n    {\n        if ($this->missing($key)) {\n            return $callback(data_get($this->all(), $key)) ?: $this;\n        }\n\n        if ($default) {\n            return $default();\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given key is an empty string for \"filled\".\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    protected function isEmptyString($key)\n    {\n        $value = $this->data($key);\n\n        return ! is_bool($value) && ! is_array($value) && trim((string) $value) === '';\n    }\n\n    /**\n     * Retrieve data from the instance as a Stringable instance.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return \\Illuminate\\Support\\Stringable\n     */\n    public function str($key, $default = null)\n    {\n        return $this->string($key, $default);\n    }\n\n    /**\n     * Retrieve data from the instance as a Stringable instance.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return \\Illuminate\\Support\\Stringable\n     */\n    public function string($key, $default = null)\n    {\n        return Str::of($this->data($key, $default));\n    }\n\n    /**\n     * Retrieve data as a boolean value.\n     *\n     * Returns true when value is \"1\", \"true\", \"on\", and \"yes\". Otherwise, returns false.\n     *\n     * @param  string|null  $key\n     * @param  bool  $default\n     * @return bool\n     */\n    public function boolean($key = null, $default = false)\n    {\n        return filter_var($this->data($key, $default), FILTER_VALIDATE_BOOLEAN);\n    }\n\n    /**\n     * Retrieve data as an integer value.\n     *\n     * @param  string  $key\n     * @param  int  $default\n     * @return int\n     */\n    public function integer($key, $default = 0)\n    {\n        return (int) $this->data($key, $default);\n    }\n\n    /**\n     * Retrieve data as a float value.\n     *\n     * @param  string  $key\n     * @param  float  $default\n     * @return float\n     */\n    public function float($key, $default = 0.0)\n    {\n        return (float) $this->data($key, $default);\n    }\n\n    /**\n     * Retrieve data clamped between min and max values.\n     *\n     * @param  string  $key\n     * @param  int|float  $min\n     * @param  int|float  $max\n     * @param  int|float  $default\n     * @return float|int\n     */\n    public function clamp($key, $min, $max, $default = 0)\n    {\n        return Number::clamp($this->data($key, $default), $min, $max);\n    }\n\n    /**\n     * Retrieve data from the instance as a Carbon instance.\n     *\n     * @param  string  $key\n     * @param  string|null  $format\n     * @param  \\UnitEnum|string|null  $tz\n     * @return \\Illuminate\\Support\\Carbon|null\n     *\n     * @throws \\Carbon\\Exceptions\\InvalidFormatException\n     */\n    public function date($key, $format = null, $tz = null)\n    {\n        $tz = enum_value($tz);\n\n        if ($this->isNotFilled($key)) {\n            return null;\n        }\n\n        if (is_null($format)) {\n            return Date::parse($this->data($key), $tz);\n        }\n\n        return Date::createFromFormat($format, $this->data($key), $tz);\n    }\n\n    /**\n     * Retrieve data from the instance as a CarbonInterval instance.\n     *\n     * @param  string  $key\n     * @param  \\Carbon\\Unit|string|null  $unit\n     * @return \\Carbon\\CarbonInterval|null\n     */\n    public function interval($key, $unit = null)\n    {\n        if ($this->isNotFilled($key)) {\n            return null;\n        }\n\n        $value = $this->data($key);\n\n        if (is_null($unit)) {\n            return CarbonInterval::make($value);\n        }\n\n        $unit = $unit instanceof Unit ? $unit : Unit::fromName($unit);\n\n        return $unit->interval((float) $value);\n    }\n\n    /**\n     * Retrieve data from the instance as an enum.\n     *\n     * @template TEnum of \\BackedEnum\n     * @template TDefault of TEnum|null\n     *\n     * @param  string  $key\n     * @param  class-string<TEnum>  $enumClass\n     * @param  TDefault  $default\n     * @return TEnum|TDefault\n     */\n    public function enum($key, $enumClass, $default = null)\n    {\n        if ($this->isNotFilled($key) || ! $this->isBackedEnum($enumClass)) {\n            return value($default);\n        }\n\n        return $enumClass::tryFrom($this->data($key)) ?: value($default);\n    }\n\n    /**\n     * Retrieve data from the instance as an array of enums.\n     *\n     * @template TEnum of \\BackedEnum\n     *\n     * @param  string  $key\n     * @param  class-string<TEnum>  $enumClass\n     * @return TEnum[]\n     */\n    public function enums($key, $enumClass)\n    {\n        if ($this->isNotFilled($key) || ! $this->isBackedEnum($enumClass)) {\n            return [];\n        }\n\n        return $this->collect($key)\n            ->map(fn ($value) => $enumClass::tryFrom($value))\n            ->filter()\n            ->all();\n    }\n\n    /**\n     * Determine if the given enum class is backed.\n     *\n     * @param  class-string  $enumClass\n     * @return bool\n     */\n    protected function isBackedEnum($enumClass)\n    {\n        return is_a($enumClass, \\BackedEnum::class, true);\n    }\n\n    /**\n     * Retrieve data from the instance as an array.\n     *\n     * @param  array|string|null  $key\n     * @return array\n     */\n    public function array($key = null)\n    {\n        return (array) (is_array($key) ? $this->only($key) : $this->data($key));\n    }\n\n    /**\n     * Retrieve data from the instance as a collection.\n     *\n     * @param  array|string|null  $key\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function collect($key = null)\n    {\n        return new Collection(is_array($key) ? $this->only($key) : $this->data($key));\n    }\n\n    /**\n     * Get a subset containing the provided keys with values from the instance data.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function only($keys)\n    {\n        $results = [];\n\n        $data = $this->all();\n\n        $placeholder = new stdClass;\n\n        foreach (is_array($keys) ? $keys : func_get_args() as $key) {\n            $value = data_get($data, $key, $placeholder);\n\n            if ($value !== $placeholder) {\n                Arr::set($results, $key, $value);\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get all of the data except for a specified array of items.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function except($keys)\n    {\n        $keys = is_array($keys) ? $keys : func_get_args();\n\n        $results = $this->all();\n\n        Arr::forget($results, $keys);\n\n        return $results;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/Localizable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Illuminate\\Container\\Container;\n\ntrait Localizable\n{\n    /**\n     * Run the callback with the given locale.\n     *\n     * @param  string  $locale\n     * @param  \\Closure  $callback\n     * @return mixed\n     */\n    public function withLocale($locale, $callback)\n    {\n        if (! $locale) {\n            return $callback();\n        }\n\n        $app = Container::getInstance();\n\n        $original = $app->getLocale();\n\n        try {\n            $app->setLocale($locale);\n\n            return $callback();\n        } finally {\n            $app->setLocale($original);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/ReadsClassAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\nuse Exception;\nuse ReflectionClass;\n\ntrait ReadsClassAttributes\n{\n    /**\n     * Get a configuration value from an attribute, falling back to a property.\n     *\n     * @param  object  $target\n     * @param  string  $attributeClass\n     * @param  string|null  $property\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function getAttributeValue($target, string $attributeClass, ?string $property = null, $default = null)\n    {\n        try {\n            $reflection = new ReflectionClass($target);\n\n            do {\n                $attributes = $reflection->getAttributes($attributeClass);\n\n                if (count($attributes) > 0) {\n                    return $this->extractAttributeValue($attributes[0]->newInstance());\n                }\n            } while ($reflection = $reflection->getParentClass());\n        } catch (Exception) {\n            //\n        }\n\n        if ($property !== null) {\n            return $target->{$property} ?? $default;\n        }\n\n        return $default;\n    }\n\n    /**\n     * Extract the value from an attribute instance.\n     *\n     * @param  object  $instance\n     * @return mixed\n     */\n    protected function extractAttributeValue($instance)\n    {\n        $properties = get_object_vars($instance);\n\n        return count($properties) === 0 ? true : reset($properties);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Traits/Tappable.php",
    "content": "<?php\n\nnamespace Illuminate\\Support\\Traits;\n\ntrait Tappable\n{\n    /**\n     * Call the given Closure with this instance then return the instance.\n     *\n     * @param  (callable($this): mixed)|null  $callback\n     * @return ($callback is null ? \\Illuminate\\Support\\HigherOrderTapProxy : $this)\n     */\n    public function tap($callback = null)\n    {\n        return tap($this, $callback);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/Uri.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Closure;\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse JsonSerializable;\nuse League\\Uri\\Contracts\\UriInterface;\nuse League\\Uri\\Uri as LeagueUri;\nuse SensitiveParameter;\nuse Stringable;\n\nclass Uri implements Htmlable, JsonSerializable, Responsable, Stringable\n{\n    use Conditionable, Dumpable, Macroable, Tappable;\n\n    /**\n     * The URI instance.\n     */\n    protected UriInterface $uri;\n\n    /**\n     * The URL generator resolver.\n     */\n    protected static ?Closure $urlGeneratorResolver = null;\n\n    /**\n     * Create a new parsed URI instance.\n     */\n    public function __construct(UriInterface|Stringable|string $uri = '')\n    {\n        $this->uri = $uri instanceof UriInterface ? $uri : LeagueUri::new((string) $uri);\n    }\n\n    /**\n     * Create a new URI instance.\n     */\n    public static function of(UriInterface|Stringable|string $uri = ''): static\n    {\n        return new static($uri);\n    }\n\n    /**\n     * Get a URI instance of an absolute URL for the given path.\n     */\n    public static function to(string $path): static\n    {\n        return new static(call_user_func(static::$urlGeneratorResolver)->to($path));\n    }\n\n    /**\n     * Get a URI instance for a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return static\n     *\n     * @throws \\Symfony\\Component\\Routing\\Exception\\RouteNotFoundException|\\InvalidArgumentException\n     */\n    public static function route($name, $parameters = [], $absolute = true): static\n    {\n        return new static(call_user_func(static::$urlGeneratorResolver)->route($name, $parameters, $absolute));\n    }\n\n    /**\n     * Create a signed route URI instance for a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @param  \\DateTimeInterface|\\DateInterval|int|null  $expiration\n     * @param  bool  $absolute\n     * @return static\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function signedRoute($name, $parameters = [], $expiration = null, $absolute = true): static\n    {\n        return new static(call_user_func(static::$urlGeneratorResolver)->signedRoute($name, $parameters, $expiration, $absolute));\n    }\n\n    /**\n     * Create a temporary signed route URI instance for a named route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  \\DateTimeInterface|\\DateInterval|int  $expiration\n     * @param  array  $parameters\n     * @param  bool  $absolute\n     * @return static\n     */\n    public static function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true): static\n    {\n        return static::signedRoute($name, $parameters, $expiration, $absolute);\n    }\n\n    /**\n     * Get a URI instance for a controller action.\n     *\n     * @param  string|array  $action\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return static\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function action($action, $parameters = [], $absolute = true): static\n    {\n        return new static(call_user_func(static::$urlGeneratorResolver)->action($action, $parameters, $absolute));\n    }\n\n    /**\n     * Get the URI's authority.\n     */\n    public function authority(): ?string\n    {\n        return $this->uri->getAuthority();\n    }\n\n    /**\n     * Get the URI's scheme.\n     */\n    public function scheme(): ?string\n    {\n        return $this->uri->getScheme();\n    }\n\n    /**\n     * Get the user from the URI.\n     */\n    public function user(bool $withPassword = false): ?string\n    {\n        return $withPassword\n            ? $this->uri->getUserInfo()\n            : $this->uri->getUsername();\n    }\n\n    /**\n     * Get the password from the URI.\n     */\n    public function password(): ?string\n    {\n        return $this->uri->getPassword();\n    }\n\n    /**\n     * Get the URI's host.\n     */\n    public function host(): ?string\n    {\n        return $this->uri->getHost();\n    }\n\n    /**\n     * Get the URI's port.\n     */\n    public function port(): ?int\n    {\n        return $this->uri->getPort();\n    }\n\n    /**\n     * Get the URI's path.\n     *\n     * Empty or missing paths are returned as a single \"/\".\n     *\n     * @return non-empty-string\n     */\n    public function path(): string\n    {\n        $path = trim((string) $this->uri->getPath(), '/');\n\n        return $path === '' ? '/' : $path;\n    }\n\n    /**\n     * Get the URI's path segments.\n     *\n     * Empty or missing paths are returned as an empty collection.\n     */\n    public function pathSegments(): Collection\n    {\n        $path = $this->path();\n\n        return $path === '/' ? new Collection : new Collection(explode('/', $path));\n    }\n\n    /**\n     * Get the URI's query string.\n     */\n    public function query(): UriQueryString\n    {\n        return new UriQueryString($this);\n    }\n\n    /**\n     * Get the URI's fragment.\n     */\n    public function fragment(): ?string\n    {\n        return $this->uri->getFragment();\n    }\n\n    /**\n     * Specify the scheme of the URI.\n     */\n    public function withScheme(Stringable|string $scheme): static\n    {\n        return new static($this->uri->withScheme($scheme));\n    }\n\n    /**\n     * Specify the user and password for the URI.\n     */\n    public function withUser(Stringable|string|null $user, #[SensitiveParameter] Stringable|string|null $password = null): static\n    {\n        return new static($this->uri->withUserInfo($user, $password));\n    }\n\n    /**\n     * Specify the host of the URI.\n     */\n    public function withHost(Stringable|string $host): static\n    {\n        return new static($this->uri->withHost($host));\n    }\n\n    /**\n     * Specify the port of the URI.\n     */\n    public function withPort(?int $port): static\n    {\n        return new static($this->uri->withPort($port));\n    }\n\n    /**\n     * Specify the path of the URI.\n     */\n    public function withPath(Stringable|string $path): static\n    {\n        return new static($this->uri->withPath(Str::start((string) $path, '/')));\n    }\n\n    /**\n     * Merge new query parameters into the URI.\n     */\n    public function withQuery(array $query, bool $merge = true): static\n    {\n        foreach ($query as $key => $value) {\n            if ($value instanceof UrlRoutable) {\n                $query[$key] = $value->getRouteKey();\n            }\n        }\n\n        if ($merge) {\n            $mergedQuery = $this->query()->all();\n\n            foreach ($query as $key => $value) {\n                data_set($mergedQuery, $key, $value);\n            }\n\n            $newQuery = $mergedQuery;\n        } else {\n            $newQuery = [];\n\n            foreach ($query as $key => $value) {\n                data_set($newQuery, $key, $value);\n            }\n        }\n\n        return new static($this->uri->withQuery(Arr::query($newQuery) ?: null));\n    }\n\n    /**\n     * Merge new query parameters into the URI if they are not already in the query string.\n     */\n    public function withQueryIfMissing(array $query): static\n    {\n        $currentQuery = $this->query();\n\n        foreach ($query as $key => $value) {\n            if (! $currentQuery->missing($key)) {\n                Arr::forget($query, $key);\n            }\n        }\n\n        return $this->withQuery($query);\n    }\n\n    /**\n     * Push a value onto the end of a query string parameter that is a list.\n     */\n    public function pushOntoQuery(string $key, mixed $value): static\n    {\n        $currentValue = data_get($this->query()->all(), $key);\n\n        $values = Arr::wrap($value);\n\n        return $this->withQuery([$key => match (true) {\n            is_array($currentValue) && array_is_list($currentValue) => array_values(array_unique([...$currentValue, ...$values])),\n            is_array($currentValue) => [...$currentValue, ...$values],\n            ! is_null($currentValue) => [$currentValue, ...$values],\n            default => $values,\n        }]);\n    }\n\n    /**\n     * Remove the given query parameters from the URI.\n     */\n    public function withoutQuery(array|string $keys): static\n    {\n        return $this->replaceQuery(Arr::except($this->query()->all(), $keys));\n    }\n\n    /**\n     * Specify new query parameters for the URI.\n     */\n    public function replaceQuery(array $query): static\n    {\n        return $this->withQuery($query, merge: false);\n    }\n\n    /**\n     * Specify the fragment of the URI.\n     */\n    public function withFragment(string $fragment): static\n    {\n        return new static($this->uri->withFragment($fragment));\n    }\n\n    /**\n     * Create a redirect HTTP response for the given URI.\n     */\n    public function redirect(int $status = 302, array $headers = []): RedirectResponse\n    {\n        return new RedirectResponse($this->value(), $status, $headers);\n    }\n\n    /**\n     * Get the URI as a Stringable instance.\n     *\n     * @return \\Illuminate\\Support\\Stringable\n     */\n    public function toStringable()\n    {\n        return Str::of($this->value());\n    }\n\n    /**\n     * Create an HTTP response that represents the URI object.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Symfony\\Component\\HttpFoundation\\Response\n     */\n    public function toResponse($request)\n    {\n        return new RedirectResponse($this->value());\n    }\n\n    /**\n     * Get the URI as a string of HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->value();\n    }\n\n    /**\n     * Get the decoded string representation of the URI.\n     */\n    public function decode(): string\n    {\n        if (empty($this->query()->toArray())) {\n            return $this->value();\n        }\n\n        return Str::replace(Str::after($this->value(), '?'), $this->query()->decode(), $this->value());\n    }\n\n    /**\n     * Get the string representation of the URI.\n     */\n    public function value(): string\n    {\n        return $this->toString();\n    }\n\n    /**\n     * Get the string representation of the URI.\n     */\n    public function toString(): string\n    {\n        return $this->uri->toString();\n    }\n\n    /**\n     * Determine if the URI is currently an empty string.\n     */\n    public function isEmpty(): bool\n    {\n        return trim($this->value()) === '';\n    }\n\n    /**\n     * Dump the string representation of the URI.\n     *\n     * @param  mixed  ...$args\n     * @return $this\n     */\n    public function dump(...$args)\n    {\n        dump($this->value(), ...$args);\n\n        return $this;\n    }\n\n    /**\n     * Set the URL generator resolver.\n     */\n    public static function setUrlGeneratorResolver(Closure $urlGeneratorResolver): void\n    {\n        static::$urlGeneratorResolver = $urlGeneratorResolver;\n    }\n\n    /**\n     * Get the underlying URI instance.\n     */\n    public function getUri(): UriInterface\n    {\n        return $this->uri;\n    }\n\n    /**\n     * Convert the object into a value that is JSON serializable.\n     *\n     * @return string\n     */\n    public function jsonSerialize(): string\n    {\n        return $this->value();\n    }\n\n    /**\n     * Get the string representation of the URI.\n     */\n    public function __toString(): string\n    {\n        return $this->toString();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/UriQueryString.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Traits\\InteractsWithData;\nuse League\\Uri\\QueryString;\nuse Stringable;\n\nclass UriQueryString implements Arrayable, Stringable\n{\n    use InteractsWithData;\n\n    /**\n     * Create a new URI query string instance.\n     */\n    public function __construct(protected Uri $uri)\n    {\n        //\n    }\n\n    /**\n     * Retrieve all data from the instance.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function all($keys = null)\n    {\n        $query = $this->toArray();\n\n        if (! $keys) {\n            return $query;\n        }\n\n        $results = [];\n\n        foreach (is_array($keys) ? $keys : func_get_args() as $key) {\n            Arr::set($results, $key, Arr::get($query, $key));\n        }\n\n        return $results;\n    }\n\n    /**\n     * Retrieve data from the instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function data($key = null, $default = null)\n    {\n        return $this->get($key, $default);\n    }\n\n    /**\n     * Get a query string parameter.\n     */\n    public function get(?string $key = null, mixed $default = null): mixed\n    {\n        return data_get($this->toArray(), $key, $default);\n    }\n\n    /**\n     * Get the URL decoded version of the query string.\n     */\n    public function decode(): string\n    {\n        return rawurldecode((string) $this);\n    }\n\n    /**\n     * Get the string representation of the query string.\n     */\n    public function value(): string\n    {\n        return (string) $this;\n    }\n\n    /**\n     * Convert the query string into an array.\n     */\n    public function toArray()\n    {\n        return QueryString::extract($this->value());\n    }\n\n    /**\n     * Get the string representation of the query string.\n     */\n    public function __toString(): string\n    {\n        return (string) $this->uri->getUri()->getQuery();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/ValidatedInput.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse ArrayIterator;\nuse Illuminate\\Contracts\\Support\\ValidatedData;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Illuminate\\Support\\Traits\\InteractsWithData;\nuse Traversable;\n\nclass ValidatedInput implements ValidatedData\n{\n    use Dumpable, InteractsWithData;\n\n    /**\n     * The underlying input.\n     *\n     * @var array\n     */\n    protected $input;\n\n    /**\n     * Create a new validated input container.\n     *\n     * @param  array  $input\n     */\n    public function __construct(array $input)\n    {\n        $this->input = $input;\n    }\n\n    /**\n     * Merge the validated input with the given array of additional data.\n     *\n     * @param  array  $items\n     * @return static\n     */\n    public function merge(array $items)\n    {\n        return new static(array_merge($this->all(), $items));\n    }\n\n    /**\n     * Get the raw, underlying input array.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function all($keys = null)\n    {\n        if (! $keys) {\n            return $this->input;\n        }\n\n        $input = [];\n\n        foreach (is_array($keys) ? $keys : func_get_args() as $key) {\n            Arr::set($input, $key, Arr::get($this->input, $key));\n        }\n\n        return $input;\n    }\n\n    /**\n     * Retrieve data from the instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function data($key = null, $default = null)\n    {\n        return $this->input($key, $default);\n    }\n\n    /**\n     * Get the keys for all of the input.\n     *\n     * @return array\n     */\n    public function keys()\n    {\n        return array_keys($this->input());\n    }\n\n    /**\n     * Retrieve an input item from the validated inputs.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function input($key = null, $default = null)\n    {\n        return data_get(\n            $this->all(), $key, $default\n        );\n    }\n\n    /**\n     * Dump the items.\n     *\n     * @param  mixed  ...$keys\n     * @return $this\n     */\n    public function dump(...$keys)\n    {\n        dump(count($keys) > 0 ? $this->only($keys) : $this->all());\n\n        return $this;\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->all();\n    }\n\n    /**\n     * Dynamically access input data.\n     *\n     * @param  string  $name\n     * @return mixed\n     */\n    public function __get($name)\n    {\n        return $this->input($name);\n    }\n\n    /**\n     * Dynamically set input data.\n     *\n     * @param  string  $name\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function __set($name, $value)\n    {\n        $this->input[$name] = $value;\n    }\n\n    /**\n     * Determine if an input item is set.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function __isset($name)\n    {\n        return $this->exists($name);\n    }\n\n    /**\n     * Remove an input item.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function __unset($name)\n    {\n        unset($this->input[$name]);\n    }\n\n    /**\n     * Determine if an item exists at an offset.\n     *\n     * @param  mixed  $key\n     * @return bool\n     */\n    public function offsetExists($key): bool\n    {\n        return $this->exists($key);\n    }\n\n    /**\n     * Get an item at a given offset.\n     *\n     * @param  mixed  $key\n     * @return mixed\n     */\n    public function offsetGet($key): mixed\n    {\n        return $this->input($key);\n    }\n\n    /**\n     * Set the item at a given offset.\n     *\n     * @param  mixed  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($key, $value): void\n    {\n        if (is_null($key)) {\n            $this->input[] = $value;\n        } else {\n            $this->input[$key] = $value;\n        }\n    }\n\n    /**\n     * Unset the item at a given offset.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function offsetUnset($key): void\n    {\n        unset($this->input[$key]);\n    }\n\n    /**\n     * Get an iterator for the input.\n     *\n     * @return \\ArrayIterator\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->input);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/ViewErrorBag.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Countable;\nuse Illuminate\\Contracts\\Support\\MessageBag as MessageBagContract;\nuse Stringable;\n\n/**\n * @mixin \\Illuminate\\Contracts\\Support\\MessageBag\n */\nclass ViewErrorBag implements Countable, Stringable\n{\n    /**\n     * The array of the view error bags.\n     *\n     * @var array<string, \\Illuminate\\Contracts\\Support\\MessageBag>\n     */\n    protected $bags = [];\n\n    /**\n     * Checks if a named MessageBag exists in the bags.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function hasBag($key = 'default')\n    {\n        return isset($this->bags[$key]);\n    }\n\n    /**\n     * Get a MessageBag instance from the bags.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Contracts\\Support\\MessageBag\n     */\n    public function getBag($key)\n    {\n        return Arr::get($this->bags, $key) ?: new MessageBag;\n    }\n\n    /**\n     * Get all the bags.\n     *\n     * @return array<string, \\Illuminate\\Contracts\\Support\\MessageBag>\n     */\n    public function getBags()\n    {\n        return $this->bags;\n    }\n\n    /**\n     * Add a new MessageBag instance to the bags.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\MessageBag  $bag\n     * @return $this\n     */\n    public function put($key, MessageBagContract $bag)\n    {\n        $this->bags[$key] = $bag;\n\n        return $this;\n    }\n\n    /**\n     * Determine if the default message bag has any messages.\n     *\n     * @return bool\n     */\n    public function any()\n    {\n        return $this->count() > 0;\n    }\n\n    /**\n     * Get the number of messages in the default bag.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return $this->getBag('default')->count();\n    }\n\n    /**\n     * Dynamically call methods on the default bag.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->getBag('default')->$method(...$parameters);\n    }\n\n    /**\n     * Dynamically access a view error bag.\n     *\n     * @param  string  $key\n     * @return \\Illuminate\\Contracts\\Support\\MessageBag\n     */\n    public function __get($key)\n    {\n        return $this->getBag($key);\n    }\n\n    /**\n     * Dynamically set a view error bag.\n     *\n     * @param  string  $key\n     * @param  \\Illuminate\\Contracts\\Support\\MessageBag  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this->put($key, $value);\n    }\n\n    /**\n     * Convert the default bag to its string representation.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->getBag('default');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/composer.json",
    "content": "{\n    \"name\": \"illuminate/support\",\n    \"description\": \"The Illuminate Support package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-ctype\": \"*\",\n        \"ext-filter\": \"*\",\n        \"ext-mbstring\": \"*\",\n        \"doctrine/inflector\": \"^2.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/conditionable\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/reflection\": \"^13.0\",\n        \"nesbot/carbon\": \"^3.8.4\",\n        \"symfony/polyfill-php85\": \"^1.33\",\n        \"voku/portable-ascii\": \"^2.0.2\"\n    },\n    \"replace\": {\n        \"spatie/once\": \"*\"\n    },\n    \"conflict\": {\n        \"tightenco/collect\": \"<5.5.33\"\n    },\n    \"suggest\": {\n        \"illuminate/filesystem\": \"Required to use the Composer class (^13.0).\",\n        \"laravel/serializable-closure\": \"Required to use the once function (^2.0.10).\",\n        \"league/commonmark\": \"Required to use Str::markdown() and Stringable::markdown() (^2.7).\",\n        \"league/uri\": \"Required to use the Uri class (^7.5.1).\",\n        \"ramsey/uuid\": \"Required to use Str::uuid() (^4.7).\",\n        \"symfony/process\": \"Required to use the Composer class (^7.4 || ^8.0).\",\n        \"symfony/uid\": \"Required to use Str::ulid() (^7.4 || ^8.0).\",\n        \"symfony/var-dumper\": \"Required to use the dd function (^7.4 || ^8.0).\",\n        \"vlucas/phpdotenv\": \"Required to use the Env class and env helper (^5.6.1).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Support\\\\\": \"\"\n        },\n        \"files\": [\n            \"functions.php\",\n            \"helpers.php\"\n        ]\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/functions.php",
    "content": "<?php\n\nnamespace Illuminate\\Support;\n\nuse Carbon\\CarbonInterface;\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Illuminate\\Support\\Facades\\Date;\nuse Symfony\\Component\\Process\\PhpExecutableFinder;\n\nif (! function_exists('Illuminate\\Support\\defer')) {\n    /**\n     * Defer execution of the given callback.\n     *\n     * @param  callable|null  $callback\n     * @param  string|null  $name\n     * @param  bool  $always\n     * @return ($callback is null ? \\Illuminate\\Support\\Defer\\DeferredCallbackCollection : \\Illuminate\\Support\\Defer\\DeferredCallback)\n     */\n    function defer(?callable $callback = null, ?string $name = null, bool $always = false): DeferredCallback|DeferredCallbackCollection\n    {\n        if ($callback === null) {\n            return app(DeferredCallbackCollection::class);\n        }\n\n        return tap(\n            new DeferredCallback($callback, $name, $always),\n            fn ($deferred) => app(DeferredCallbackCollection::class)[] = $deferred\n        );\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\php_binary')) {\n    /**\n     * Determine the PHP Binary.\n     */\n    function php_binary(): string\n    {\n        return (new PhpExecutableFinder)->find(false) ?: 'php';\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\artisan_binary')) {\n    /**\n     * Determine the proper Artisan executable.\n     */\n    function artisan_binary(): string\n    {\n        return defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan';\n    }\n}\n\n// Time functions...\n\nif (! function_exists('Illuminate\\Support\\now')) {\n    /**\n     * Create a new Carbon instance for the current time.\n     *\n     * @param  \\DateTimeZone|\\UnitEnum|string|null  $tz\n     * @return \\Illuminate\\Support\\Carbon\n     */\n    function now($tz = null): CarbonInterface\n    {\n        return Date::now(enum_value($tz));\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\microseconds')) {\n    /**\n     * Get the current date / time plus the given number of microseconds.\n     */\n    function microseconds(int|float $microseconds): CarbonInterval\n    {\n        return CarbonInterval::microseconds($microseconds);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\milliseconds')) {\n    /**\n     * Get the current date / time plus the given number of milliseconds.\n     */\n    function milliseconds(int|float $milliseconds): CarbonInterval\n    {\n        return CarbonInterval::milliseconds($milliseconds);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\seconds')) {\n    /**\n     * Get the current date / time plus the given number of seconds.\n     */\n    function seconds(int|float $seconds): CarbonInterval\n    {\n        return CarbonInterval::seconds($seconds);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\minutes')) {\n    /**\n     * Get the current date / time plus the given number of minutes.\n     */\n    function minutes(int|float $minutes): CarbonInterval\n    {\n        return CarbonInterval::minutes($minutes);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\hours')) {\n    /**\n     * Get the current date / time plus the given number of hours.\n     */\n    function hours(int|float $hours): CarbonInterval\n    {\n        return CarbonInterval::hours($hours);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\days')) {\n    /**\n     * Get the current date / time plus the given number of days.\n     */\n    function days(int|float $days): CarbonInterval\n    {\n        return CarbonInterval::days($days);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\weeks')) {\n    /**\n     * Get the current date / time plus the given number of weeks.\n     */\n    function weeks(int $weeks): CarbonInterval\n    {\n        return CarbonInterval::weeks($weeks);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\months')) {\n    /**\n     * Get the current date / time plus the given number of months.\n     */\n    function months(int $months): CarbonInterval\n    {\n        return CarbonInterval::months($months);\n    }\n}\n\nif (! function_exists('Illuminate\\Support\\years')) {\n    /**\n     * Get the current date / time plus the given number of years.\n     */\n    function years(int $years): CarbonInterval\n    {\n        return CarbonInterval::years($years);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Support/helpers.php",
    "content": "<?php\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Contracts\\Support\\DeferringDisplayableValue;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\HigherOrderTapProxy;\nuse Illuminate\\Support\\Once;\nuse Illuminate\\Support\\Onceable;\nuse Illuminate\\Support\\Optional;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable as SupportStringable;\n\nif (! function_exists('append_config')) {\n    /**\n     * Assign high numeric IDs to a config item to force appending.\n     *\n     * @param  array  $array\n     */\n    function append_config(array $array): array\n    {\n        $start = 9999;\n\n        foreach ($array as $key => $value) {\n            if (is_numeric($key)) {\n                $start++;\n\n                $array[$start] = Arr::pull($array, $key);\n            }\n        }\n\n        return $array;\n    }\n}\n\nif (! function_exists('blank')) {\n    /**\n     * Determine if the given value is \"blank\".\n     *\n     * @phpstan-assert-if-false !=null|'' $value\n     *\n     * @phpstan-assert-if-true !=numeric|bool $value\n     *\n     * @param  mixed  $value\n     */\n    function blank($value): bool\n    {\n        if (is_null($value)) {\n            return true;\n        }\n\n        if (is_string($value)) {\n            return trim($value) === '';\n        }\n\n        if (is_numeric($value) || is_bool($value)) {\n            return false;\n        }\n\n        if ($value instanceof Model) {\n            return false;\n        }\n\n        if ($value instanceof Countable) {\n            return count($value) === 0;\n        }\n\n        if ($value instanceof Stringable) {\n            return trim((string) $value) === '';\n        }\n\n        return empty($value);\n    }\n}\n\nif (! function_exists('class_basename')) {\n    /**\n     * Get the class \"basename\" of the given object / class.\n     *\n     * @param  string|object  $class\n     */\n    function class_basename($class): string\n    {\n        $class = is_object($class) ? get_class($class) : $class;\n\n        return basename(str_replace('\\\\', '/', $class));\n    }\n}\n\nif (! function_exists('class_uses_recursive')) {\n    /**\n     * Returns all traits used by a class, its parent classes and trait of their traits.\n     *\n     * @param  object|string  $class\n     * @return array<string, string>\n     */\n    function class_uses_recursive($class): array\n    {\n        if (is_object($class)) {\n            $class = get_class($class);\n        }\n\n        $results = [];\n\n        foreach (array_reverse(class_parents($class) ?: []) + [$class => $class] as $class) {\n            $results += trait_uses_recursive($class);\n        }\n\n        return array_unique($results);\n    }\n}\n\nif (! function_exists('e')) {\n    /**\n     * Encode HTML special characters in a string.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\DeferringDisplayableValue|\\Illuminate\\Contracts\\Support\\Htmlable|\\BackedEnum|string|int|float|null  $value\n     * @param  bool  $doubleEncode\n     */\n    function e($value, $doubleEncode = true): string\n    {\n        if ($value instanceof DeferringDisplayableValue) {\n            $value = $value->resolveDisplayableValue();\n        }\n\n        if ($value instanceof Htmlable) {\n            return $value->toHtml() ?? '';\n        }\n\n        if ($value instanceof BackedEnum) {\n            $value = $value->value;\n        }\n\n        return htmlspecialchars($value ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', $doubleEncode);\n    }\n}\n\nif (! function_exists('env')) {\n    /**\n     * Gets the value of an environment variable.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    function env($key, $default = null)\n    {\n        return Env::get($key, $default);\n    }\n}\n\nif (! function_exists('filled')) {\n    /**\n     * Determine if a value is \"filled\".\n     *\n     * @phpstan-assert-if-true !=null|'' $value\n     *\n     * @phpstan-assert-if-false !=numeric|bool $value\n     *\n     * @param  mixed  $value\n     */\n    function filled($value): bool\n    {\n        return ! blank($value);\n    }\n}\n\nif (! function_exists('fluent')) {\n    /**\n     * Create a Fluent object from the given value.\n     *\n     * @param  iterable|object|null  $value\n     */\n    function fluent($value = null): Fluent\n    {\n        return new Fluent($value ?? []);\n    }\n}\n\nif (! function_exists('literal')) {\n    /**\n     * Return a new literal or anonymous object using named arguments.\n     *\n     * @return mixed\n     */\n    function literal(...$arguments)\n    {\n        if (count($arguments) === 1 && array_is_list($arguments)) {\n            return $arguments[0];\n        }\n\n        return (object) $arguments;\n    }\n}\n\nif (! function_exists('object_get')) {\n    /**\n     * Get an item from an object using \"dot\" notation.\n     *\n     * @template TValue of object\n     *\n     * @param  TValue  $object\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return ($key is empty ? TValue : mixed)\n     */\n    function object_get($object, $key, $default = null)\n    {\n        if (is_null($key) || trim($key) === '') {\n            return $object;\n        }\n\n        foreach (explode('.', $key) as $segment) {\n            if (! is_object($object) || ! isset($object->{$segment})) {\n                return value($default);\n            }\n\n            $object = $object->{$segment};\n        }\n\n        return $object;\n    }\n}\n\nif (! function_exists('laravel_cloud')) {\n    /**\n     * Determine if the application is running on Laravel Cloud.\n     */\n    function laravel_cloud(): bool\n    {\n        return ($_ENV['LARAVEL_CLOUD'] ?? false) === '1' ||\n            ($_SERVER['LARAVEL_CLOUD'] ?? false) === '1';\n    }\n}\n\nif (! function_exists('once')) {\n    /**\n     * Ensures a callable is only called once, and returns the result on subsequent calls.\n     *\n     * @template  TReturnType\n     *\n     * @param  callable(): TReturnType  $callback\n     * @return TReturnType\n     */\n    function once(callable $callback)\n    {\n        $onceable = Onceable::tryFromTrace(\n            debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2),\n            $callback,\n        );\n\n        return $onceable ? Once::instance()->value($onceable) : call_user_func($callback);\n    }\n}\n\nif (! function_exists('optional')) {\n    /**\n     * Provide access to optional objects.\n     *\n     * @template TValue\n     * @template TReturn\n     *\n     * @param  TValue  $value\n     * @param  (callable(TValue): TReturn)|null  $callback\n     * @return ($callback is null ? \\Illuminate\\Support\\Optional : ($value is null ? null : TReturn))\n     */\n    function optional($value = null, ?callable $callback = null)\n    {\n        if (is_null($callback)) {\n            return new Optional($value);\n        } elseif (! is_null($value)) {\n            return $callback($value);\n        }\n    }\n}\n\nif (! function_exists('preg_replace_array')) {\n    /**\n     * Replace a given pattern with each value in the array in sequentially.\n     *\n     * @param  string  $pattern\n     * @param  array  $replacements\n     * @param  string  $subject\n     */\n    function preg_replace_array($pattern, array $replacements, $subject): string\n    {\n        return preg_replace_callback($pattern, function () use (&$replacements) {\n            return array_shift($replacements);\n        }, $subject);\n    }\n}\n\nif (! function_exists('retry')) {\n    /**\n     * Retry an operation a given number of times.\n     *\n     * @template TValue\n     *\n     * @param  int|array<int, int>  $times\n     * @param  callable(int): TValue  $callback\n     * @param  CarbonInterval|int|\\Closure(int, \\Throwable): CarbonInterval|int  $sleepMilliseconds\n     * @param  (callable(\\Throwable): bool)|null  $when\n     * @return TValue\n     *\n     * @throws \\Throwable\n     */\n    function retry($times, callable $callback, $sleepMilliseconds = 0, $when = null)\n    {\n        $attempts = 0;\n\n        $backoff = [];\n\n        if (is_array($times)) {\n            $backoff = $times;\n\n            $times = count($times) + 1;\n        }\n\n        beginning:\n        $attempts++;\n        $times--;\n\n        try {\n            return $callback($attempts);\n        } catch (Throwable $e) {\n            if ($times < 1 || ($when && ! $when($e))) {\n                throw $e;\n            }\n\n            $sleepMilliseconds = $backoff[$attempts - 1] ?? $sleepMilliseconds;\n\n            if ($sleepMilliseconds) {\n                $duration = value($sleepMilliseconds, $attempts, $e);\n\n                $duration instanceof CarbonInterval\n                    ? Sleep::usleep($duration->totalMicroseconds)\n                    : Sleep::usleep($duration * 1000);\n            }\n\n            goto beginning;\n        }\n    }\n}\n\nif (! function_exists('str')) {\n    /**\n     * Get a new stringable object from the given string.\n     *\n     * @param  string|null  $string\n     * @return ($string is null ? object : \\Illuminate\\Support\\Stringable)\n     */\n    function str($string = null)\n    {\n        if (func_num_args() === 0) {\n            return new class\n            {\n                public function __call($method, $parameters)\n                {\n                    return Str::$method(...$parameters);\n                }\n\n                public function __toString()\n                {\n                    return '';\n                }\n            };\n        }\n\n        return new SupportStringable($string);\n    }\n}\n\nif (! function_exists('tap')) {\n    /**\n     * Call the given Closure with the given value then return the value.\n     *\n     * @template TValue\n     *\n     * @param  TValue  $value\n     * @param  (callable(TValue): mixed)|null  $callback\n     * @return ($callback is null ? \\Illuminate\\Support\\HigherOrderTapProxy : TValue)\n     */\n    function tap($value, $callback = null)\n    {\n        if (is_null($callback)) {\n            return new HigherOrderTapProxy($value);\n        }\n\n        $callback($value);\n\n        return $value;\n    }\n}\n\nif (! function_exists('throw_if')) {\n    /**\n     * Throw the given exception if the given condition is true.\n     *\n     * @template TValue\n     * @template TParams of mixed\n     * @template TException of \\Throwable\n     * @template TExceptionValue of TException|class-string<TException>|string\n     *\n     * @param  TValue  $condition\n     * @param  Closure(TParams): TExceptionValue|TExceptionValue  $exception\n     * @param  TParams  ...$parameters\n     * @return ($condition is true ? never : ($condition is non-empty-mixed ? never : TValue))\n     *\n     * @throws TException\n     */\n    function throw_if($condition, $exception = 'RuntimeException', ...$parameters)\n    {\n        if ($condition) {\n            if ($exception instanceof Closure) {\n                $exception = $exception(...$parameters);\n            }\n\n            if (is_string($exception) && class_exists($exception)) {\n                $exception = new $exception(...$parameters);\n            }\n\n            throw is_string($exception) ? new RuntimeException($exception) : $exception;\n        }\n\n        return $condition;\n    }\n}\n\nif (! function_exists('throw_unless')) {\n    /**\n     * Throw the given exception unless the given condition is true.\n     *\n     * @template TValue\n     * @template TParams of mixed\n     * @template TException of \\Throwable\n     * @template TExceptionValue of TException|class-string<TException>|string\n     *\n     * @param  TValue  $condition\n     * @param  Closure(TParams): TExceptionValue|TExceptionValue  $exception\n     * @param  TParams  ...$parameters\n     * @return ($condition is false ? never : ($condition is non-empty-mixed ? TValue : never))\n     *\n     * @throws TException\n     */\n    function throw_unless($condition, $exception = 'RuntimeException', ...$parameters)\n    {\n        throw_if(! $condition, $exception, ...$parameters);\n\n        return $condition;\n    }\n}\n\nif (! function_exists('trait_uses_recursive')) {\n    /**\n     * Returns all traits used by a trait and its traits.\n     *\n     * @param  object|string  $trait\n     * @return array<string, string>\n     */\n    function trait_uses_recursive($trait): array\n    {\n        $traits = class_uses($trait) ?: [];\n\n        foreach ($traits as $trait) {\n            $traits += trait_uses_recursive($trait);\n        }\n\n        return $traits;\n    }\n}\n\nif (! function_exists('transform')) {\n    /**\n     * Transform the given value if it is present.\n     *\n     * @template TValue\n     * @template TReturn\n     * @template TDefault\n     *\n     * @param  TValue  $value\n     * @param  callable(TValue): TReturn  $callback\n     * @param  TDefault|callable(TValue): TDefault  $default\n     * @return ($value is empty ? TDefault : TReturn)\n     */\n    function transform($value, callable $callback, $default = null)\n    {\n        if (filled($value)) {\n            return $callback($value);\n        }\n\n        if (is_callable($default)) {\n            return $default($value);\n        }\n\n        return $default;\n    }\n}\n\nif (! function_exists('windows_os')) {\n    /**\n     * Determine whether the current environment is Windows based.\n     */\n    function windows_os(): bool\n    {\n        return PHP_OS_FAMILY === 'Windows';\n    }\n}\n\nif (! function_exists('with')) {\n    /**\n     * Return the given value, optionally passed through the given callback.\n     *\n     * @template TValue\n     * @template TReturn\n     *\n     * @param  TValue  $value\n     * @param  (callable(TValue): (TReturn))|null  $callback\n     * @return ($callback is null ? TValue : TReturn)\n     */\n    function with($value, ?callable $callback = null)\n    {\n        return is_null($callback) ? $value : $callback($value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Testing/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Testing/Assert.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse ArrayAccess;\nuse Illuminate\\Testing\\Constraints\\ArraySubset;\nuse Illuminate\\Testing\\Exceptions\\InvalidArgumentException;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\n/**\n * @internal This class is not meant to be used or overwritten outside the framework itself.\n */\nabstract class Assert extends PHPUnit\n{\n    /**\n     * Asserts that an array has a specified subset.\n     *\n     * @param  \\ArrayAccess|array  $subset\n     * @param  \\ArrayAccess|array  $array\n     * @param  bool  $checkForIdentity\n     * @param  string  $msg\n     * @return void\n     */\n    public static function assertArraySubset($subset, $array, bool $checkForIdentity = false, string $msg = ''): void\n    {\n        if (! (is_array($subset) || $subset instanceof ArrayAccess)) {\n            throw InvalidArgumentException::create(1, 'array or ArrayAccess');\n        }\n\n        if (! (is_array($array) || $array instanceof ArrayAccess)) {\n            throw InvalidArgumentException::create(2, 'array or ArrayAccess');\n        }\n\n        $constraint = new ArraySubset($subset, $checkForIdentity);\n\n        PHPUnit::assertThat($array, $constraint, $msg);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/AssertableJsonString.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse ArrayAccess;\nuse Closure;\nuse Countable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Testing\\Assert as PHPUnit;\nuse JsonSerializable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass AssertableJsonString implements ArrayAccess, Countable\n{\n    /**\n     * The original encoded json.\n     *\n     * @var \\Illuminate\\Contracts\\Support\\Jsonable|\\JsonSerializable|array|string\n     */\n    public $json;\n\n    /**\n     * The decoded json contents.\n     *\n     * @var array|null\n     */\n    protected $decoded;\n\n    /**\n     * Create a new assertable JSON string instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Jsonable|\\JsonSerializable|array|string  $jsonable\n     */\n    public function __construct($jsonable)\n    {\n        $this->json = $jsonable;\n\n        if ($jsonable instanceof JsonSerializable) {\n            $this->decoded = $jsonable->jsonSerialize();\n        } elseif ($jsonable instanceof Jsonable) {\n            $this->decoded = json_decode($jsonable->toJson(), true);\n        } elseif (is_array($jsonable)) {\n            $this->decoded = $jsonable;\n        } else {\n            $this->decoded = json_decode($jsonable, true);\n        }\n    }\n\n    /**\n     * Validate and return the decoded response JSON.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    public function json($key = null)\n    {\n        return data_get($this->decoded, $key);\n    }\n\n    /**\n     * Assert that the response JSON has the expected count of items at the given key.\n     *\n     * @param  int  $count\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function assertCount(int $count, $key = null)\n    {\n        if (! is_null($key)) {\n            PHPUnit::assertCount(\n                $count, data_get($this->decoded, $key),\n                \"Failed to assert that the response count matched the expected {$count}\"\n            );\n\n            return $this;\n        }\n\n        PHPUnit::assertCount($count,\n            $this->decoded,\n            \"Failed to assert that the response count matched the expected {$count}\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the exact given JSON.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertExact(array $data)\n    {\n        $actual = $this->reorderAssocKeys((array) $this->decoded);\n\n        $expected = $this->reorderAssocKeys($data);\n\n        PHPUnit::assertEquals(\n            json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),\n            json_encode($actual, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the similar JSON as given.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertSimilar(array $data)\n    {\n        $actual = json_encode(\n            Arr::sortRecursive((array) $this->decoded),\n            JSON_UNESCAPED_UNICODE\n        );\n\n        PHPUnit::assertEquals(json_encode(Arr::sortRecursive($data), JSON_UNESCAPED_UNICODE), $actual);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response contains the given JSON fragment.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertFragment(array $data)\n    {\n        $actual = json_encode(\n            Arr::sortRecursive((array) $this->decoded),\n            JSON_UNESCAPED_UNICODE\n        );\n\n        foreach (Arr::sortRecursive($data) as $key => $value) {\n            $expected = $this->jsonSearchStrings($key, $value);\n\n            PHPUnit::assertTrue(\n                Str::contains($actual, $expected),\n                'Unable to find JSON fragment: '.PHP_EOL.PHP_EOL.\n                '['.json_encode([$key => $value], JSON_UNESCAPED_UNICODE).']'.PHP_EOL.PHP_EOL.\n                'within'.PHP_EOL.PHP_EOL.\n                \"[{$actual}].\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response does not contain the given JSON fragment.\n     *\n     * @param  array  $data\n     * @param  bool  $exact\n     * @return $this\n     */\n    public function assertMissing(array $data, $exact = false)\n    {\n        if ($exact) {\n            return $this->assertMissingExact($data);\n        }\n\n        $actual = json_encode(\n            Arr::sortRecursive((array) $this->decoded),\n            JSON_UNESCAPED_UNICODE\n        );\n\n        foreach (Arr::sortRecursive($data) as $key => $value) {\n            $unexpected = $this->jsonSearchStrings($key, $value);\n\n            PHPUnit::assertFalse(\n                Str::contains($actual, $unexpected),\n                'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.\n                '['.json_encode([$key => $value], JSON_UNESCAPED_UNICODE).']'.PHP_EOL.PHP_EOL.\n                'within'.PHP_EOL.PHP_EOL.\n                \"[{$actual}].\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response does not contain the exact JSON fragment.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertMissingExact(array $data)\n    {\n        $actual = json_encode(\n            Arr::sortRecursive((array) $this->decoded),\n            JSON_UNESCAPED_UNICODE\n        );\n\n        foreach (Arr::sortRecursive($data) as $key => $value) {\n            $unexpected = $this->jsonSearchStrings($key, $value);\n\n            if (! Str::contains($actual, $unexpected)) {\n                return $this;\n            }\n        }\n\n        PHPUnit::fail(\n            'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.\n            '['.json_encode($data, JSON_UNESCAPED_UNICODE).']'.PHP_EOL.PHP_EOL.\n            'within'.PHP_EOL.PHP_EOL.\n            \"[{$actual}].\"\n        );\n    }\n\n    /**\n     * Assert that the response does not contain the given path.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function assertMissingPath($path)\n    {\n        PHPUnit::assertFalse(Arr::has($this->json(), $path));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the expected value and type exists at the given path in the response.\n     *\n     * @param  string  $path\n     * @param  mixed  $expect\n     * @return $this\n     */\n    public function assertPath($path, $expect)\n    {\n        if ($expect instanceof Closure) {\n            PHPUnit::assertTrue($expect($this->json($path)));\n        } else {\n            PHPUnit::assertSame(enum_value($expect), $this->json($path));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given path in the response contains all of the expected values without looking at the order.\n     *\n     * @param  string  $path\n     * @param  array  $expect\n     * @return $this\n     */\n    public function assertPathCanonicalizing($path, $expect)\n    {\n        PHPUnit::assertEqualsCanonicalizing($expect, $this->json($path));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has a given JSON structure.\n     *\n     * @param  array|null  $structure\n     * @param  array|null  $responseData\n     * @param  bool  $exact\n     * @return $this\n     */\n    public function assertStructure(?array $structure = null, $responseData = null, bool $exact = false)\n    {\n        if (is_null($structure)) {\n            return $this->assertSimilar($this->decoded);\n        }\n\n        if (! is_null($responseData)) {\n            return (new static($responseData))->assertStructure($structure, null, $exact);\n        }\n\n        if ($exact) {\n            PHPUnit::assertIsArray($this->decoded);\n\n            $keys = (new Collection($structure))->map(fn ($value, $key) => is_array($value) ? $key : $value)->values();\n\n            if ($keys->all() !== ['*']) {\n                PHPUnit::assertEquals($keys->sort()->values()->all(), (new Collection($this->decoded))->keys()->sort()->values()->all());\n            }\n        }\n\n        foreach ($structure as $key => $value) {\n            if (is_array($value) && $key === '*') {\n                PHPUnit::assertIsArray($this->decoded);\n\n                foreach ($this->decoded as $responseDataItem) {\n                    $this->assertStructure($structure['*'], $responseDataItem, $exact);\n                }\n            } elseif (is_array($value)) {\n                PHPUnit::assertArrayHasKey($key, $this->decoded);\n\n                $this->assertStructure($structure[$key], $this->decoded[$key], $exact);\n            } else {\n                PHPUnit::assertArrayHasKey($value, $this->decoded);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response is a superset of the given JSON.\n     *\n     * @param  array  $data\n     * @param  bool  $strict\n     * @return $this\n     */\n    public function assertSubset(array $data, $strict = false)\n    {\n        PHPUnit::assertArraySubset(\n            $data, $this->decoded, $strict, $this->assertJsonMessage($data)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Reorder associative array keys to make it easy to compare arrays.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function reorderAssocKeys(array $data)\n    {\n        $data = Arr::dot($data);\n        ksort($data);\n\n        $result = [];\n\n        foreach ($data as $key => $value) {\n            Arr::set($result, $key, $value);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get the assertion message for assertJson.\n     *\n     * @param  array  $data\n     * @return string\n     */\n    protected function assertJsonMessage(array $data)\n    {\n        $expected = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);\n\n        $actual = json_encode($this->decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);\n\n        return 'Unable to find JSON: '.PHP_EOL.PHP_EOL.\n            \"[{$expected}]\".PHP_EOL.PHP_EOL.\n            'within response JSON:'.PHP_EOL.PHP_EOL.\n            \"[{$actual}].\".PHP_EOL.PHP_EOL;\n    }\n\n    /**\n     * Get the strings we need to search for when examining the JSON.\n     *\n     * @param  string  $key\n     * @param  string  $value\n     * @return array\n     */\n    protected function jsonSearchStrings($key, $value)\n    {\n        $needle = Str::substr(json_encode([$key => $value], JSON_UNESCAPED_UNICODE), 1, -1);\n\n        return [\n            $needle.']',\n            $needle.'}',\n            $needle.',',\n        ];\n    }\n\n    /**\n     * Get the total number of items in the underlying JSON array.\n     *\n     * @return int\n     */\n    public function count(): int\n    {\n        return count($this->decoded);\n    }\n\n    /**\n     * Determine whether an offset exists.\n     *\n     * @param  mixed  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->decoded[$offset]);\n    }\n\n    /**\n     * Get the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->decoded[$offset];\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->decoded[$offset] = $value;\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->decoded[$offset]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Concerns/AssertsStatusCodes.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Concerns;\n\nuse Illuminate\\Testing\\Assert as PHPUnit;\n\ntrait AssertsStatusCodes\n{\n    /**\n     * Assert that the response has a 200 \"OK\" status code.\n     *\n     * @return $this\n     */\n    public function assertOk()\n    {\n        return $this->assertStatus(200);\n    }\n\n    /**\n     * Assert that the response has a 201 \"Created\" status code.\n     *\n     * @return $this\n     */\n    public function assertCreated()\n    {\n        return $this->assertStatus(201);\n    }\n\n    /**\n     * Assert that the response has a 202 \"Accepted\" status code.\n     *\n     * @return $this\n     */\n    public function assertAccepted()\n    {\n        return $this->assertStatus(202);\n    }\n\n    /**\n     * Assert that the response has the given status code and no content.\n     *\n     * @param  int  $status\n     * @return $this\n     */\n    public function assertNoContent($status = 204)\n    {\n        $this->assertStatus($status);\n\n        PHPUnit::assertEmpty($this->getContent(), 'Response content is not empty.');\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has a 301 \"Moved Permanently\" status code.\n     *\n     * @return $this\n     */\n    public function assertMovedPermanently()\n    {\n        return $this->assertStatus(301);\n    }\n\n    /**\n     * Assert that the response has a 302 \"Found\" status code.\n     *\n     * @return $this\n     */\n    public function assertFound()\n    {\n        return $this->assertStatus(302);\n    }\n\n    /**\n     * Assert that the response has a 304 \"Not Modified\" status code.\n     *\n     * @return $this\n     */\n    public function assertNotModified()\n    {\n        return $this->assertStatus(304);\n    }\n\n    /**\n     * Assert that the response has a 307 \"Temporary Redirect\" status code.\n     *\n     * @return $this\n     */\n    public function assertTemporaryRedirect()\n    {\n        return $this->assertStatus(307);\n    }\n\n    /**\n     * Assert that the response has a 308 \"Permanent Redirect\" status code.\n     *\n     * @return $this\n     */\n    public function assertPermanentRedirect()\n    {\n        return $this->assertStatus(308);\n    }\n\n    /**\n     * Assert that the response has a 400 \"Bad Request\" status code.\n     *\n     * @return $this\n     */\n    public function assertBadRequest()\n    {\n        return $this->assertStatus(400);\n    }\n\n    /**\n     * Assert that the response has a 401 \"Unauthorized\" status code.\n     *\n     * @return $this\n     */\n    public function assertUnauthorized()\n    {\n        return $this->assertStatus(401);\n    }\n\n    /**\n     * Assert that the response has a 402 \"Payment Required\" status code.\n     *\n     * @return $this\n     */\n    public function assertPaymentRequired()\n    {\n        return $this->assertStatus(402);\n    }\n\n    /**\n     * Assert that the response has a 403 \"Forbidden\" status code.\n     *\n     * @return $this\n     */\n    public function assertForbidden()\n    {\n        return $this->assertStatus(403);\n    }\n\n    /**\n     * Assert that the response has a 404 \"Not Found\" status code.\n     *\n     * @return $this\n     */\n    public function assertNotFound()\n    {\n        return $this->assertStatus(404);\n    }\n\n    /**\n     * Assert that the response has a 405 \"Method Not Allowed\" status code.\n     *\n     * @return $this\n     */\n    public function assertMethodNotAllowed()\n    {\n        return $this->assertStatus(405);\n    }\n\n    /**\n     * Assert that the response has a 406 \"Not Acceptable\" status code.\n     *\n     * @return $this\n     */\n    public function assertNotAcceptable()\n    {\n        return $this->assertStatus(406);\n    }\n\n    /**\n     * Assert that the response has a 408 \"Request Timeout\" status code.\n     *\n     * @return $this\n     */\n    public function assertRequestTimeout()\n    {\n        return $this->assertStatus(408);\n    }\n\n    /**\n     * Assert that the response has a 409 \"Conflict\" status code.\n     *\n     * @return $this\n     */\n    public function assertConflict()\n    {\n        return $this->assertStatus(409);\n    }\n\n    /**\n     * Assert that the response has a 410 \"Gone\" status code.\n     *\n     * @return $this\n     */\n    public function assertGone()\n    {\n        return $this->assertStatus(410);\n    }\n\n    /**\n     * Assert that the response has a 415 \"Unsupported Media Type\" status code.\n     *\n     * @return $this\n     */\n    public function assertUnsupportedMediaType()\n    {\n        return $this->assertStatus(415);\n    }\n\n    /**\n     * Assert that the response has a 422 \"Unprocessable Content\" status code.\n     *\n     * @return $this\n     */\n    public function assertUnprocessable()\n    {\n        return $this->assertStatus(422);\n    }\n\n    /**\n     * Assert that the response has a 424 \"Failed Dependency\" status code.\n     *\n     * @return $this\n     */\n    public function assertFailedDependency()\n    {\n        return $this->assertStatus(424);\n    }\n\n    /**\n     * Assert that the response has a 429 \"Too Many Requests\" status code.\n     *\n     * @return $this\n     */\n    public function assertTooManyRequests()\n    {\n        return $this->assertStatus(429);\n    }\n\n    /**\n     * Assert that the response has a 500 \"Internal Server Error\" status code.\n     *\n     * @return $this\n     */\n    public function assertInternalServerError()\n    {\n        return $this->assertStatus(500);\n    }\n\n    /**\n     * Assert that the response has a 503 \"Service Unavailable\" status code.\n     *\n     * @return $this\n     */\n    public function assertServiceUnavailable()\n    {\n        return $this->assertStatus(503);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Concerns/RunsInParallel.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Concerns;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\ParallelTesting;\nuse Illuminate\\Testing\\ParallelConsoleOutput;\nuse PHPUnit\\TextUI\\Configuration\\PhpHandler;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\ntrait RunsInParallel\n{\n    /**\n     * The application resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $applicationResolver;\n\n    /**\n     * The runner resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected static $runnerResolver;\n\n    /**\n     * The original test runner options.\n     *\n     * @var \\ParaTest\\Runners\\PHPUnit\\Options|\\ParaTest\\Options\n     */\n    protected $options;\n\n    /**\n     * The output instance.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    protected $output;\n\n    /**\n     * The original test runner.\n     *\n     * @var \\ParaTest\\Runners\\PHPUnit\\RunnerInterface|\\ParaTest\\RunnerInterface\n     */\n    protected $runner;\n\n    /**\n     * Creates a new test runner instance.\n     *\n     * @param  \\ParaTest\\Runners\\PHPUnit\\Options|\\ParaTest\\Options  $options\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     */\n    public function __construct($options, OutputInterface $output)\n    {\n        $this->options = $options;\n\n        if ($output instanceof ConsoleOutput) {\n            $output = new ParallelConsoleOutput($output);\n        }\n\n        $runnerResolver = static::$runnerResolver ?: function ($options, OutputInterface $output) {\n            $wrapperRunnerClass = class_exists(\\ParaTest\\WrapperRunner\\WrapperRunner::class)\n                ? \\ParaTest\\WrapperRunner\\WrapperRunner::class\n                : \\ParaTest\\Runners\\PHPUnit\\WrapperRunner::class;\n\n            return new $wrapperRunnerClass($options, $output);\n        };\n\n        $this->runner = $runnerResolver($options, $output);\n    }\n\n    /**\n     * Set the application resolver callback.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveApplicationUsing($resolver)\n    {\n        static::$applicationResolver = $resolver;\n    }\n\n    /**\n     * Set the runner resolver callback.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public static function resolveRunnerUsing($resolver)\n    {\n        static::$runnerResolver = $resolver;\n    }\n\n    /**\n     * Runs the test suite.\n     *\n     * @return int\n     */\n    public function execute(): int\n    {\n        $configuration = $this->options instanceof \\ParaTest\\Options\n            ? $this->options->configuration\n            : $this->options->configuration();\n\n        (new PhpHandler())->handle($configuration->php());\n\n        $this->forEachProcess(function () {\n            ParallelTesting::callSetUpProcessCallbacks();\n        });\n\n        try {\n            $potentialExitCode = $this->runner->run();\n        } finally {\n            $this->forEachProcess(function () {\n                ParallelTesting::callTearDownProcessCallbacks();\n            });\n        }\n\n        return $potentialExitCode ?? $this->getExitCode();\n    }\n\n    /**\n     * Returns the highest exit code encountered throughout the course of test execution.\n     *\n     * @return int\n     */\n    public function getExitCode(): int\n    {\n        return $this->runner->getExitCode();\n    }\n\n    /**\n     * Apply the given callback for each process.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function forEachProcess($callback)\n    {\n        $processes = $this->options instanceof \\ParaTest\\Options\n            ? $this->options->processes\n            : $this->options->processes();\n\n        Collection::range(1, $processes)->each(function ($token) use ($callback) {\n            tap($this->createApplication(), function ($app) use ($callback, $token) {\n                ParallelTesting::resolveTokenUsing(fn () => $token);\n\n                $callback($app);\n            })->flush();\n        });\n    }\n\n    /**\n     * Creates the application.\n     *\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     *\n     * @throws \\RuntimeException\n     */\n    protected function createApplication()\n    {\n        $applicationResolver = static::$applicationResolver ?: function () {\n            if (trait_exists(\\Tests\\CreatesApplication::class)) {\n                $applicationCreator = new class\n                {\n                    use \\Tests\\CreatesApplication;\n                };\n\n                return $applicationCreator->createApplication();\n            } elseif (file_exists($path = (Application::inferBasePath().'/bootstrap/app.php'))) {\n                $app = require $path;\n\n                $app->make(Kernel::class)->bootstrap();\n\n                return $app;\n            }\n\n            throw new RuntimeException('Parallel Runner unable to resolve application.');\n        };\n\n        return $applicationResolver();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Concerns/TestCaches.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Concerns;\n\nuse Illuminate\\Support\\Facades\\ParallelTesting;\n\ntrait TestCaches\n{\n    /**\n     * The original cache prefix prior to appending the token.\n     *\n     * @var string|null\n     */\n    protected static $originalCachePrefix = null;\n\n    /**\n     * Boot test cache for parallel testing.\n     *\n     * @return void\n     */\n    protected function bootTestCache()\n    {\n        ParallelTesting::setUpTestCase(function () {\n            if (ParallelTesting::option('without_cache')) {\n                return;\n            }\n\n            $this->switchToCachePrefix($this->parallelSafeCachePrefix());\n        });\n    }\n\n    /**\n     * Get the test cache prefix.\n     *\n     * @return string\n     */\n    protected function parallelSafeCachePrefix()\n    {\n        self::$originalCachePrefix ??= $this->app['config']->get('cache.prefix', '');\n\n        return self::$originalCachePrefix.'test_'.ParallelTesting::token().'_';\n    }\n\n    /**\n     * Switch to the given cache prefix.\n     *\n     * @param  string  $prefix\n     * @return void\n     */\n    protected function switchToCachePrefix($prefix)\n    {\n        $this->app['config']->set('cache.prefix', $prefix);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Concerns/TestDatabases.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Concerns;\n\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Foundation\\Testing;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\ParallelTesting;\nuse Illuminate\\Support\\Facades\\Schema;\n\ntrait TestDatabases\n{\n    /**\n     * Indicates if the test database schema is up to date.\n     *\n     * @var bool\n     */\n    protected static $schemaIsUpToDate = false;\n\n    /**\n     * The root database name prior to concatenating the token.\n     *\n     * @var null|string\n     */\n    protected static $originalDatabaseName = null;\n\n    /**\n     * Boot a test database.\n     *\n     * @return void\n     */\n    protected function bootTestDatabase()\n    {\n        ParallelTesting::setUpProcess(function () {\n            $this->whenNotUsingInMemoryDatabase(function ($database) {\n                if (ParallelTesting::option('recreate_databases')) {\n                    Schema::dropDatabaseIfExists(\n                        $this->testDatabase($database)\n                    );\n                }\n            });\n        });\n\n        ParallelTesting::setUpTestCase(function ($testCase) {\n            $uses = array_flip(class_uses_recursive(get_class($testCase)));\n\n            $databaseTraits = [\n                Testing\\DatabaseMigrations::class,\n                Testing\\DatabaseTransactions::class,\n                Testing\\DatabaseTruncation::class,\n                Testing\\RefreshDatabase::class,\n            ];\n\n            if (Arr::hasAny($uses, $databaseTraits) && ! ParallelTesting::option('without_databases')) {\n                $this->whenNotUsingInMemoryDatabase(function ($database) use ($uses) {\n                    [$testDatabase, $created] = $this->ensureTestDatabaseExists($database);\n\n                    $this->switchToDatabase($testDatabase);\n\n                    if ($created) {\n                        ParallelTesting::callSetUpTestDatabaseBeforeMigratingCallbacks($testDatabase);\n                    }\n\n                    if (isset($uses[Testing\\DatabaseTransactions::class])) {\n                        $this->ensureSchemaIsUpToDate();\n                    }\n\n                    if ($created) {\n                        ParallelTesting::callSetUpTestDatabaseCallbacks($testDatabase);\n                    }\n                });\n            }\n        });\n\n        ParallelTesting::tearDownProcess(function () {\n            $this->whenNotUsingInMemoryDatabase(function ($database) {\n                if (ParallelTesting::option('drop_databases')) {\n                    Schema::dropDatabaseIfExists(\n                        $this->testDatabase($database)\n                    );\n                }\n            });\n        });\n    }\n\n    /**\n     * Ensure a test database exists and returns its name.\n     *\n     * @param  string  $database\n     * @return array\n     */\n    protected function ensureTestDatabaseExists($database)\n    {\n        $testDatabase = $this->testDatabase($database);\n\n        try {\n            $this->usingDatabase($testDatabase, function () {\n                Schema::hasTable('dummy');\n            });\n        } catch (QueryException) {\n            $this->usingDatabase($database, function () use ($testDatabase) {\n                Schema::dropDatabaseIfExists($testDatabase);\n                Schema::createDatabase($testDatabase);\n            });\n\n            return [$testDatabase, true];\n        }\n\n        return [$testDatabase, false];\n    }\n\n    /**\n     * Ensure the current database test schema is up to date.\n     *\n     * @return void\n     */\n    protected function ensureSchemaIsUpToDate()\n    {\n        if (! static::$schemaIsUpToDate) {\n            Artisan::call('migrate');\n\n            static::$schemaIsUpToDate = true;\n        }\n    }\n\n    /**\n     * Runs the given callable using the given database.\n     *\n     * @param  string  $database\n     * @param  callable  $callable\n     * @return void\n     */\n    protected function usingDatabase($database, $callable)\n    {\n        $original = DB::getConfig('database');\n\n        try {\n            $this->switchToDatabase($database);\n            $callable();\n        } finally {\n            $this->switchToDatabase($original);\n        }\n    }\n\n    /**\n     * Apply the given callback when tests are not using in memory database.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function whenNotUsingInMemoryDatabase($callback)\n    {\n        if (ParallelTesting::option('without_databases')) {\n            return;\n        }\n\n        $database = DB::getConfig('database');\n\n        if ($database !== ':memory:') {\n            $callback($database);\n        }\n    }\n\n    /**\n     * Switch to the given database.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    protected function switchToDatabase($database)\n    {\n        DB::purge();\n\n        $default = config('database.default');\n\n        $url = config(\"database.connections.{$default}.url\");\n\n        if ($url) {\n            config()->set(\n                \"database.connections.{$default}.url\",\n                preg_replace('/^(.*)(\\/[\\w-]*)(\\??.*)$/', \"$1/{$database}$3\", $url),\n            );\n        } else {\n            config()->set(\n                \"database.connections.{$default}.database\",\n                $database,\n            );\n        }\n    }\n\n    /**\n     * Returns the test database name.\n     *\n     * @return string\n     */\n    protected function testDatabase($database)\n    {\n        if (! isset(self::$originalDatabaseName)) {\n            self::$originalDatabaseName = $database;\n        } else {\n            $database = self::$originalDatabaseName;\n        }\n\n        $token = ParallelTesting::token();\n\n        return \"{$database}_test_{$token}\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Concerns/TestViews.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Concerns;\n\nuse Illuminate\\Support\\Facades\\File;\nuse Illuminate\\Support\\Facades\\ParallelTesting;\n\ntrait TestViews\n{\n    /**\n     * The original compiled view path prior to appending the token.\n     *\n     * @var string|null\n     */\n    protected static $originalCompiledViewPath = null;\n\n    /**\n     * Boot test views for parallel testing.\n     *\n     * @return void\n     */\n    protected function bootTestViews()\n    {\n        ParallelTesting::setUpProcess(function () {\n            if ($path = $this->parallelSafeCompiledViewPath()) {\n                File::ensureDirectoryExists($path);\n            }\n        });\n\n        ParallelTesting::setUpTestCase(function () {\n            if ($path = $this->parallelSafeCompiledViewPath()) {\n                $this->switchToCompiledViewPath($path);\n            }\n        });\n\n        ParallelTesting::tearDownProcess(function () {\n            if ($path = $this->parallelSafeCompiledViewPath()) {\n                File::deleteDirectory($path);\n            }\n        });\n    }\n\n    /**\n     * Get the test compiled view path.\n     *\n     * @return string|null\n     */\n    protected function parallelSafeCompiledViewPath()\n    {\n        self::$originalCompiledViewPath ??= $this->app['config']->get('view.compiled', '');\n\n        if (! self::$originalCompiledViewPath) {\n            return null;\n        }\n\n        return rtrim(self::$originalCompiledViewPath, '\\/')\n            .'/test_'\n            .ParallelTesting::token();\n    }\n\n    /**\n     * Switch to the given compiled view path.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function switchToCompiledViewPath($path)\n    {\n        $this->app['config']->set('view.compiled', $path);\n\n        if ($this->app->resolved('blade.compiler')) {\n            $compiler = $this->app['blade.compiler'];\n\n            (function () use ($path) {\n                $this->cachePath = $path;\n            })->bindTo($compiler, $compiler)();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/ArraySubset.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse ArrayObject;\nuse PHPUnit\\Framework\\Constraint\\Constraint;\nuse SebastianBergmann\\Comparator\\ComparisonFailure;\nuse SebastianBergmann\\Exporter\\Exporter;\nuse Traversable;\n\nclass ArraySubset extends Constraint\n{\n    /**\n     * @var iterable\n     */\n    protected $subset;\n\n    /**\n     * @var bool\n     */\n    protected $strict;\n\n    /**\n     * Create a new array subset constraint instance.\n     *\n     * @param  iterable  $subset\n     * @param  bool  $strict\n     */\n    public function __construct(iterable $subset, bool $strict = false)\n    {\n        $this->strict = $strict;\n        $this->subset = $subset;\n    }\n\n    /**\n     * Evaluates the constraint for parameter $other.\n     *\n     * If $returnResult is set to false (the default), an exception is thrown\n     * in case of a failure. null is returned otherwise.\n     *\n     * If $returnResult is true, the result of the evaluation is returned as\n     * a boolean value instead: true in case of success, false in case of a\n     * failure.\n     *\n     * @param  mixed  $other\n     * @param  string  $description\n     * @param  bool  $returnResult\n     * @return bool|null\n     *\n     * @throws \\PHPUnit\\Framework\\ExpectationFailedException\n     * @throws \\SebastianBergmann\\RecursionContext\\InvalidArgumentException\n     */\n    public function evaluate($other, string $description = '', bool $returnResult = false): ?bool\n    {\n        // type cast $other & $this->subset as an array to allow\n        // support in standard array functions.\n        $other = $this->toArray($other);\n        $this->subset = $this->toArray($this->subset);\n\n        $patched = array_replace_recursive($other, $this->subset);\n\n        if ($this->strict) {\n            $result = $other === $patched;\n        } else {\n            $result = $other == $patched;\n        }\n\n        if ($returnResult) {\n            return $result;\n        }\n\n        if (! $result) {\n            $f = new ComparisonFailure(\n                $patched,\n                $other,\n                var_export($patched, true),\n                var_export($other, true)\n            );\n\n            $this->fail($other, $description, $f);\n        }\n\n        return null;\n    }\n\n    /**\n     * Returns a string representation of the constraint.\n     *\n     * @return string\n     *\n     * @throws \\SebastianBergmann\\RecursionContext\\InvalidArgumentException\n     */\n    public function toString(): string\n    {\n        return 'has the subset '.(new Exporter)->export($this->subset);\n    }\n\n    /**\n     * Returns the description of the failure.\n     *\n     * The beginning of failure messages is \"Failed asserting that\" in most\n     * cases. This method should return the second part of that sentence.\n     *\n     * @param  mixed  $other\n     * @return string\n     *\n     * @throws \\SebastianBergmann\\RecursionContext\\InvalidArgumentException\n     */\n    protected function failureDescription($other): string\n    {\n        return 'an array '.$this->toString();\n    }\n\n    /**\n     * Returns the description of the failure.\n     *\n     * The beginning of failure messages is \"Failed asserting that\" in most\n     * cases. This method should return the second part of that sentence.\n     *\n     * @param  iterable  $other\n     * @return array\n     */\n    protected function toArray(iterable $other): array\n    {\n        if (is_array($other)) {\n            return $other;\n        }\n\n        if ($other instanceof ArrayObject) {\n            return $other->getArrayCopy();\n        }\n\n        if ($other instanceof Traversable) {\n            return iterator_to_array($other);\n        }\n\n        return (array) $other;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/CountInDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse Illuminate\\Database\\Connection;\nuse PHPUnit\\Framework\\Constraint\\Constraint;\nuse ReflectionClass;\n\nclass CountInDatabase extends Constraint\n{\n    /**\n     * The database connection.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $database;\n\n    /**\n     * The expected table entries count that will be checked against the actual count.\n     *\n     * @var int\n     */\n    protected $expectedCount;\n\n    /**\n     * The actual table entries count that will be checked against the expected count.\n     *\n     * @var int\n     */\n    protected $actualCount;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $database\n     * @param  int  $expectedCount\n     */\n    public function __construct(Connection $database, int $expectedCount)\n    {\n        $this->expectedCount = $expectedCount;\n\n        $this->database = $database;\n    }\n\n    /**\n     * Check if the expected and actual count are equal.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    public function matches($table): bool\n    {\n        $this->actualCount = $this->database->table($table)->count();\n\n        return $this->actualCount === $this->expectedCount;\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    public function failureDescription($table): string\n    {\n        return sprintf(\n            \"table [%s] matches expected entries count of %s. Entries found: %s.\\n\",\n            $table, $this->expectedCount, $this->actualCount\n        );\n    }\n\n    /**\n     * Get a string representation of the object.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toString($options = 0): string\n    {\n        return (new ReflectionClass($this))->name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/HasInDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Connection;\nuse PHPUnit\\Framework\\Constraint\\Constraint;\n\nclass HasInDatabase extends Constraint\n{\n    /**\n     * Number of records that will be shown in the console in case of failure.\n     *\n     * @var int\n     */\n    protected $show = 3;\n\n    /**\n     * The database connection.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $database;\n\n    /**\n     * The data that will be used to narrow the search in the database table.\n     *\n     * @var array<string, mixed>\n     */\n    protected $data;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $database\n     * @param  array<string, mixed>  $data\n     */\n    public function __construct(Connection $database, array $data)\n    {\n        $this->data = $data;\n\n        $this->database = $database;\n    }\n\n    /**\n     * Check if the data is found in the given table.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    public function matches($table): bool\n    {\n        return $this->database->table($table)\n            ->where($this->data)\n            ->exists();\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    public function failureDescription($table): string\n    {\n        return sprintf(\n            \"a row in the table [%s] matches the attributes %s.\\n\\n%s\",\n            $table, $this->toString(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), $this->getAdditionalInfo($table)\n        );\n    }\n\n    /**\n     * Get additional info about the records found in the database table.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function getAdditionalInfo($table)\n    {\n        $query = $this->database->table($table);\n\n        $similarResults = $query->where(\n            array_key_first($this->data),\n            array_first($this->data),\n        )->select(array_keys($this->data))->limit($this->show)->get();\n\n        if ($similarResults->isNotEmpty()) {\n            $description = 'Found similar results: '.json_encode($similarResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n        } else {\n            $query = $this->database->table($table);\n\n            $results = $query->select(array_keys($this->data))->limit($this->show)->get();\n\n            if ($results->isEmpty()) {\n                return 'The table is empty';\n            }\n\n            $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n        }\n\n        if ($query->count() > $this->show) {\n            $description .= sprintf(' and %s others', $query->count() - $this->show);\n        }\n\n        return $description;\n    }\n\n    /**\n     * Get a string representation of the object.\n     *\n     * @param  int  $options\n     * @return string\n     */\n    public function toString($options = 0): string\n    {\n        foreach ($this->data as $key => $data) {\n            $output[$key] = $data instanceof Expression ? $data->getValue($this->database->getQueryGrammar()) : $data;\n        }\n\n        return json_encode($output ?? [], $options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/NotSoftDeletedInDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse Illuminate\\Database\\Connection;\nuse PHPUnit\\Framework\\Constraint\\Constraint;\n\nclass NotSoftDeletedInDatabase extends Constraint\n{\n    /**\n     * Number of records that will be shown in the console in case of failure.\n     *\n     * @var int\n     */\n    protected $show = 3;\n\n    /**\n     * The database connection.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $database;\n\n    /**\n     * The data that will be used to narrow the search in the database table.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The name of the column that indicates soft deletion has occurred.\n     *\n     * @var string\n     */\n    protected $deletedAtColumn;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $database\n     * @param  array  $data\n     * @param  string  $deletedAtColumn\n     */\n    public function __construct(Connection $database, array $data, string $deletedAtColumn)\n    {\n        $this->database = $database;\n        $this->data = $data;\n        $this->deletedAtColumn = $deletedAtColumn;\n    }\n\n    /**\n     * Check if the data is found in the given table.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    public function matches($table): bool\n    {\n        return $this->database->table($table)\n            ->where($this->data)\n            ->whereNull($this->deletedAtColumn)\n            ->exists();\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    public function failureDescription($table): string\n    {\n        return sprintf(\n            \"any existing row in the table [%s] matches the attributes %s.\\n\\n%s\",\n            $table, $this->toString(), $this->getAdditionalInfo($table)\n        );\n    }\n\n    /**\n     * Get additional info about the records found in the database table.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function getAdditionalInfo($table)\n    {\n        $query = $this->database->table($table);\n\n        $results = $query->limit($this->show)->get();\n\n        if ($results->isEmpty()) {\n            return 'The table is empty';\n        }\n\n        $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT);\n\n        if ($query->count() > $this->show) {\n            $description .= sprintf(' and %s others', $query->count() - $this->show);\n        }\n\n        return $description;\n    }\n\n    /**\n     * Get a string representation of the object.\n     *\n     * @return string\n     */\n    public function toString(): string\n    {\n        return json_encode($this->data);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/SeeInHtml.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse PHPUnit\\Framework\\Constraint\\Constraint;\nuse ReflectionClass;\n\nclass SeeInHtml extends Constraint\n{\n    /**\n     * The string under validation.\n     *\n     * @var string\n     */\n    protected $content;\n\n    /**\n     * Indicates the values must appear in order.\n     *\n     * @var bool\n     */\n    protected $ordered;\n\n    /**\n     * Indicates whether to negate the assertion.\n     *\n     * @var bool\n     */\n    protected $negate;\n\n    /**\n     * The last value that failed to pass validation.\n     *\n     * @var string\n     */\n    protected $failedValue;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  string  $content\n     */\n    public function __construct($content, $ordered = false, $negate = false)\n    {\n        $this->content = $content;\n        $this->ordered = $ordered;\n        $this->negate = $negate;\n    }\n\n    /**\n     * Determine if the rule passes validation.\n     *\n     * @param  array  $values\n     */\n    public function matches($values): bool\n    {\n        $normalizedContent = $this->normalize($this->content);\n\n        $position = 0;\n\n        foreach ($values as $value) {\n            if (empty($value)) {\n                continue;\n            }\n\n            $normalizedValue = $this->normalize($value);\n\n            $valuePosition = mb_strpos($normalizedContent, $normalizedValue, $position);\n\n            if ($this->negate) {\n                if ($valuePosition !== false) {\n                    $this->failedValue = $value;\n\n                    return false;\n                }\n\n                continue;\n            }\n\n            if ($valuePosition === false || $valuePosition < $position) {\n                $this->failedValue = $value;\n\n                return false;\n            }\n\n            if ($this->ordered) {\n                $position = $valuePosition + mb_strlen($normalizedValue);\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  array  $values\n     */\n    public function failureDescription($values): string\n    {\n        if ($this->negate) {\n            return sprintf(\n                '\\'%s\\' does not contain \"%s\".',\n                $this->content,\n                $this->failedValue\n            );\n        }\n\n        return sprintf(\n            '\\'%s\\' contains \"%s\"%s',\n            $this->content,\n            $this->failedValue,\n            $this->ordered ? ' in specified order.' : '.'\n        );\n    }\n\n    /**\n     * Normalize the given value.\n     */\n    protected function normalize(string $value): ?string\n    {\n        $value = strip_tags($value);\n        $value = html_entity_decode($value, ENT_QUOTES, 'UTF-8');\n        $value = trim($value);\n        $value = preg_replace('/\\s+/', ' ', $value);\n\n        return $value;\n    }\n\n    /**\n     * Get a string representation of the object.\n     */\n    public function toString(): string\n    {\n        return (new ReflectionClass($this))->name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/SeeInOrder.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse PHPUnit\\Framework\\Constraint\\Constraint;\nuse ReflectionClass;\n\nclass SeeInOrder extends Constraint\n{\n    /**\n     * The string under validation.\n     *\n     * @var string\n     */\n    protected $content;\n\n    /**\n     * The last value that failed to pass validation.\n     *\n     * @var string\n     */\n    protected $failedValue;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  string  $content\n     */\n    public function __construct($content)\n    {\n        $this->content = $content;\n    }\n\n    /**\n     * Determine if the rule passes validation.\n     *\n     * @param  array  $values\n     * @return bool\n     */\n    public function matches($values): bool\n    {\n        $decodedContent = html_entity_decode($this->content, ENT_QUOTES, 'UTF-8');\n\n        $position = 0;\n\n        foreach ($values as $value) {\n            if (empty($value)) {\n                continue;\n            }\n\n            $decodedValue = html_entity_decode($value, ENT_QUOTES, 'UTF-8');\n\n            $valuePosition = mb_strpos($decodedContent, $decodedValue, $position);\n\n            if ($valuePosition === false || $valuePosition < $position) {\n                $this->failedValue = $value;\n\n                return false;\n            }\n\n            $position = $valuePosition + mb_strlen($decodedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  array  $values\n     * @return string\n     */\n    public function failureDescription($values): string\n    {\n        return sprintf(\n            '\\'%s\\' contains \"%s\" in specified order.',\n            $this->content,\n            $this->failedValue\n        );\n    }\n\n    /**\n     * Get a string representation of the object.\n     *\n     * @return string\n     */\n    public function toString(): string\n    {\n        return (new ReflectionClass($this))->name;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Constraints/SoftDeletedInDatabase.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Constraints;\n\nuse Illuminate\\Database\\Connection;\nuse PHPUnit\\Framework\\Constraint\\Constraint;\n\nclass SoftDeletedInDatabase extends Constraint\n{\n    /**\n     * Number of records that will be shown in the console in case of failure.\n     *\n     * @var int\n     */\n    protected $show = 3;\n\n    /**\n     * The database connection.\n     *\n     * @var \\Illuminate\\Database\\Connection\n     */\n    protected $database;\n\n    /**\n     * The data that will be used to narrow the search in the database table.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The name of the column that indicates soft deletion has occurred.\n     *\n     * @var string\n     */\n    protected $deletedAtColumn;\n\n    /**\n     * Create a new constraint instance.\n     *\n     * @param  \\Illuminate\\Database\\Connection  $database\n     * @param  array  $data\n     * @param  string  $deletedAtColumn\n     */\n    public function __construct(Connection $database, array $data, string $deletedAtColumn)\n    {\n        $this->data = $data;\n\n        $this->database = $database;\n\n        $this->deletedAtColumn = $deletedAtColumn;\n    }\n\n    /**\n     * Check if the data is found in the given table.\n     *\n     * @param  string  $table\n     * @return bool\n     */\n    public function matches($table): bool\n    {\n        return $this->database->table($table)\n            ->where($this->data)\n            ->whereNotNull($this->deletedAtColumn)\n            ->exists();\n    }\n\n    /**\n     * Get the description of the failure.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    public function failureDescription($table): string\n    {\n        return sprintf(\n            \"any soft deleted row in the table [%s] matches the attributes %s.\\n\\n%s\",\n            $table, $this->toString(), $this->getAdditionalInfo($table)\n        );\n    }\n\n    /**\n     * Get additional info about the records found in the database table.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    protected function getAdditionalInfo($table)\n    {\n        $query = $this->database->table($table);\n\n        $results = $query->limit($this->show)->get();\n\n        if ($results->isEmpty()) {\n            return 'The table is empty';\n        }\n\n        $description = 'Found: '.json_encode($results, JSON_PRETTY_PRINT);\n\n        if ($query->count() > $this->show) {\n            $description .= sprintf(' and %s others', $query->count() - $this->show);\n        }\n\n        return $description;\n    }\n\n    /**\n     * Get a string representation of the object.\n     *\n     * @return string\n     */\n    public function toString(): string\n    {\n        return json_encode($this->data);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Exceptions/InvalidArgumentException.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Exceptions;\n\nuse PHPUnit\\Framework\\Exception;\n\nclass InvalidArgumentException extends Exception\n{\n    /**\n     * Creates a new exception for an invalid argument.\n     *\n     * @param  int  $argument\n     * @param  string  $type\n     * @return static\n     */\n    public static function create(int $argument, string $type): static\n    {\n        $stack = debug_backtrace();\n\n        $function = $stack[1]['function'];\n\n        if (isset($stack[1]['class'])) {\n            $function = sprintf('%s::%s', $stack[1]['class'], $stack[1]['function']);\n        }\n\n        return new static(\n            sprintf(\n                'Argument #%d of %s() must be %s %s',\n                $argument,\n                $function,\n                in_array(lcfirst($type)[0], ['a', 'e', 'i', 'o', 'u'], true) ? 'an' : 'a',\n                $type\n            )\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Fluent/AssertableJson.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Fluent;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Illuminate\\Testing\\AssertableJsonString;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\nclass AssertableJson implements Arrayable\n{\n    use Concerns\\Has,\n        Concerns\\Matching,\n        Concerns\\Debugging,\n        Concerns\\Interaction,\n        Conditionable,\n        Macroable,\n        Tappable;\n\n    /**\n     * The properties in the current scope.\n     *\n     * @var array\n     */\n    private $props;\n\n    /**\n     * The \"dot\" path to the current scope.\n     *\n     * @var string|null\n     */\n    private $path;\n\n    /**\n     * Create a new fluent, assertable JSON data instance.\n     *\n     * @param  array  $props\n     * @param  string|null  $path\n     */\n    protected function __construct(array $props, ?string $path = null)\n    {\n        $this->path = $path;\n        $this->props = $props;\n    }\n\n    /**\n     * Compose the absolute \"dot\" path to the given key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    protected function dotPath(string $key = ''): string\n    {\n        if (is_null($this->path)) {\n            return $key;\n        }\n\n        return rtrim(implode('.', [$this->path, $key]), '.');\n    }\n\n    /**\n     * Retrieve a prop within the current scope using \"dot\" notation.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    protected function prop(?string $key = null)\n    {\n        return Arr::get($this->props, $key);\n    }\n\n    /**\n     * Instantiate a new \"scope\" at the path of the given key.\n     *\n     * @param  string  $key\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    protected function scope(string $key, Closure $callback): static\n    {\n        $props = $this->prop($key);\n        $path = $this->dotPath($key);\n\n        PHPUnit::assertIsArray($props, sprintf('Property [%s] is not scopeable.', $path));\n\n        $scope = new static($props, $path);\n        $callback($scope);\n        $scope->interacted();\n\n        return $this;\n    }\n\n    /**\n     * Instantiate a new \"scope\" on the first child element.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function first(Closure $callback): static\n    {\n        $props = $this->prop();\n\n        $path = $this->dotPath();\n\n        PHPUnit::assertNotEmpty($props, $path === ''\n            ? 'Cannot scope directly onto the first element of the root level because it is empty.'\n            : sprintf('Cannot scope directly onto the first element of property [%s] because it is empty.', $path)\n        );\n\n        $key = array_keys($props)[0];\n\n        $this->interactsWith($key);\n\n        return $this->scope($key, $callback);\n    }\n\n    /**\n     * Instantiate a new \"scope\" on each child element.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function each(Closure $callback): static\n    {\n        $props = $this->prop();\n\n        $path = $this->dotPath();\n\n        PHPUnit::assertNotEmpty($props, $path === ''\n            ? 'Cannot scope directly onto each element of the root level because it is empty.'\n            : sprintf('Cannot scope directly onto each element of property [%s] because it is empty.', $path)\n        );\n\n        foreach (array_keys($props) as $key) {\n            $this->interactsWith($key);\n\n            $this->scope($key, $callback);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Create a new instance from an array.\n     *\n     * @param  array  $data\n     * @return static\n     */\n    public static function fromArray(array $data): static\n    {\n        return new static($data);\n    }\n\n    /**\n     * Create a new instance from an AssertableJsonString.\n     *\n     * @param  \\Illuminate\\Testing\\AssertableJsonString  $json\n     * @return static\n     */\n    public static function fromAssertableJsonString(AssertableJsonString $json): static\n    {\n        return static::fromArray($json->json());\n    }\n\n    /**\n     * Get the instance as an array.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->props;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Fluent/Concerns/Debugging.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Fluent\\Concerns;\n\nuse Illuminate\\Support\\Traits\\Dumpable;\n\ntrait Debugging\n{\n    use Dumpable;\n\n    /**\n     * Dumps the given props.\n     *\n     * @param  string|null  $prop\n     * @return $this\n     */\n    public function dump(?string $prop = null): static\n    {\n        dump($this->prop($prop));\n\n        return $this;\n    }\n\n    /**\n     * Retrieve a prop within the current scope using \"dot\" notation.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    abstract protected function prop(?string $key = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Fluent/Concerns/Has.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Fluent\\Concerns;\n\nuse Closure;\nuse Illuminate\\Support\\Arr;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\ntrait Has\n{\n    /**\n     * Assert that the prop is of the expected size.\n     *\n     * @param  string|int  $key\n     * @param  int|null  $length\n     * @return $this\n     */\n    public function count($key, ?int $length = null): static\n    {\n        if (is_null($length)) {\n            $path = $this->dotPath();\n\n            PHPUnit::assertCount(\n                $key,\n                $this->prop(),\n                $path\n                    ? sprintf('Property [%s] does not have the expected size.', $path)\n                    : sprintf('Root level does not have the expected size.')\n            );\n\n            return $this;\n        }\n\n        PHPUnit::assertCount(\n            $length,\n            $this->prop($key),\n            sprintf('Property [%s] does not have the expected size.', $this->dotPath($key))\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the prop size is between a given minimum and maximum.\n     *\n     * @param  int|string  $min\n     * @param  int|string  $max\n     * @return $this\n     */\n    public function countBetween(int|string $min, int|string $max): static\n    {\n        $path = $this->dotPath();\n\n        $prop = $this->prop();\n\n        PHPUnit::assertGreaterThanOrEqual(\n            $min,\n            count($prop),\n            $path\n                ? sprintf('Property [%s] size is not greater than or equal to [%s].', $path, $min)\n                : sprintf('Root level size is not greater than or equal to [%s].', $min)\n        );\n\n        PHPUnit::assertLessThanOrEqual(\n            $max,\n            count($prop),\n            $path\n                ? sprintf('Property [%s] size is not less than or equal to [%s].', $path, $max)\n                : sprintf('Root level size is not less than or equal to [%s].', $max)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Ensure that the given prop exists.\n     *\n     * @param  string|int  $key\n     * @param  int|\\Closure|null  $length\n     * @param  \\Closure|null  $callback\n     * @return $this\n     */\n    public function has($key, $length = null, ?Closure $callback = null): static\n    {\n        $prop = $this->prop();\n\n        if (is_int($key) && is_null($length)) {\n            return $this->count($key);\n        }\n\n        PHPUnit::assertTrue(\n            Arr::has($prop, $key),\n            sprintf('Property [%s] does not exist.', $this->dotPath($key))\n        );\n\n        $this->interactsWith($key);\n\n        if (! is_null($callback)) {\n            return $this->has($key, function (self $scope) use ($length, $callback) {\n                return $scope\n                    ->tap(function (self $scope) use ($length) {\n                        if (! is_null($length)) {\n                            $scope->count($length);\n                        }\n                    })\n                    ->first($callback)\n                    ->etc();\n            });\n        }\n\n        if (is_callable($length)) {\n            return $this->scope($key, $length);\n        }\n\n        if (! is_null($length)) {\n            return $this->count($key, $length);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that all of the given props exist.\n     *\n     * @param  array|string  $key\n     * @return $this\n     */\n    public function hasAll($key): static\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        foreach ($keys as $prop => $count) {\n            if (is_int($prop)) {\n                $this->has($count);\n            } else {\n                $this->has($prop, $count);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that at least one of the given props exists.\n     *\n     * @param  array|string  $key\n     * @return $this\n     */\n    public function hasAny($key): static\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        PHPUnit::assertTrue(\n            Arr::hasAny($this->prop(), $keys),\n            sprintf('None of properties [%s] exist.', implode(', ', $keys))\n        );\n\n        foreach ($keys as $key) {\n            $this->interactsWith($key);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that none of the given props exist.\n     *\n     * @param  array|string  $key\n     * @return $this\n     */\n    public function missingAll($key): static\n    {\n        $keys = is_array($key) ? $key : func_get_args();\n\n        foreach ($keys as $prop) {\n            $this->missing($prop);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given prop does not exist.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function missing(string $key): static\n    {\n        PHPUnit::assertNotTrue(\n            Arr::has($this->prop(), $key),\n            sprintf('Property [%s] was found while it was expected to be missing.', $this->dotPath($key))\n        );\n\n        return $this;\n    }\n\n    /**\n     * Compose the absolute \"dot\" path to the given key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    abstract protected function dotPath(string $key = ''): string;\n\n    /**\n     * Marks the property as interacted.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    abstract protected function interactsWith(string $key): void;\n\n    /**\n     * Retrieve a prop within the current scope using \"dot\" notation.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    abstract protected function prop(?string $key = null);\n\n    /**\n     * Instantiate a new \"scope\" at the path of the given key.\n     *\n     * @param  string  $key\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    abstract protected function scope(string $key, Closure $callback);\n\n    /**\n     * Disables the interaction check.\n     *\n     * @return $this\n     */\n    abstract public function etc();\n\n    /**\n     * Instantiate a new \"scope\" on the first element.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    abstract public function first(Closure $callback);\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Fluent/Concerns/Interaction.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Fluent\\Concerns;\n\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\ntrait Interaction\n{\n    /**\n     * The list of interacted properties.\n     *\n     * @var array\n     */\n    protected $interacted = [];\n\n    /**\n     * Marks the property as interacted.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    protected function interactsWith(string $key): void\n    {\n        $prop = Str::before($key, '.');\n\n        if (! in_array($prop, $this->interacted, true)) {\n            $this->interacted[] = $prop;\n        }\n    }\n\n    /**\n     * Asserts that all properties have been interacted with.\n     *\n     * @return void\n     */\n    public function interacted(): void\n    {\n        PHPUnit::assertSame(\n            [],\n            array_diff(array_keys($this->prop()), $this->interacted),\n            $this->path\n                ? sprintf('Unexpected properties were found in scope [%s].', $this->path)\n                : 'Unexpected properties were found on the root level.'\n        );\n    }\n\n    /**\n     * Disables the interaction check.\n     *\n     * @return $this\n     */\n    public function etc(): static\n    {\n        $this->interacted = array_keys($this->prop());\n\n        return $this;\n    }\n\n    /**\n     * Retrieve a prop within the current scope using \"dot\" notation.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    abstract protected function prop(?string $key = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/Fluent/Concerns/Matching.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing\\Fluent\\Concerns;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Collection;\nuse PHPUnit\\Framework\\Assert as PHPUnit;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait Matching\n{\n    /**\n     * Asserts that the property matches the expected value.\n     *\n     * @param  string  $key\n     * @param  mixed|\\Closure  $expected\n     * @return $this\n     */\n    public function where(string $key, $expected): static\n    {\n        $this->has($key);\n\n        $actual = $this->prop($key);\n\n        if ($expected instanceof Closure) {\n            PHPUnit::assertTrue(\n                $expected(is_array($actual) ? new Collection($actual) : $actual),\n                sprintf('Property [%s] was marked as invalid using a closure.', $this->dotPath($key))\n            );\n\n            return $this;\n        }\n\n        $expected = $expected instanceof Arrayable\n            ? $expected->toArray()\n            : enum_value($expected);\n\n        $this->ensureSorted($expected);\n        $this->ensureSorted($actual);\n\n        PHPUnit::assertSame(\n            $expected,\n            $actual,\n            sprintf('Property [%s] does not match the expected value.', $this->dotPath($key))\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the property does not match the expected value.\n     *\n     * @param  string  $key\n     * @param  mixed|\\Closure  $expected\n     * @return $this\n     */\n    public function whereNot(string $key, $expected): static\n    {\n        $this->has($key);\n\n        $actual = $this->prop($key);\n\n        if ($expected instanceof Closure) {\n            PHPUnit::assertFalse(\n                $expected(is_array($actual) ? new Collection($actual) : $actual),\n                sprintf('Property [%s] was marked as invalid using a closure.', $this->dotPath($key))\n            );\n\n            return $this;\n        }\n\n        $expected = $expected instanceof Arrayable\n            ? $expected->toArray()\n            : enum_value($expected);\n\n        $this->ensureSorted($expected);\n        $this->ensureSorted($actual);\n\n        PHPUnit::assertNotSame(\n            $expected,\n            $actual,\n            sprintf(\n                'Property [%s] contains a value that should be missing: [%s, %s]',\n                $this->dotPath($key),\n                $key,\n                $expected\n            )\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the property is null.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function whereNull(string $key): static\n    {\n        $this->has($key);\n\n        $actual = $this->prop($key);\n\n        PHPUnit::assertNull(\n            $actual,\n            sprintf(\n                'Property [%s] should be null.',\n                $this->dotPath($key),\n            )\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the property is not null.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function whereNotNull(string $key): static\n    {\n        $this->has($key);\n\n        $actual = $this->prop($key);\n\n        PHPUnit::assertNotNull(\n            $actual,\n            sprintf(\n                'Property [%s] should not be null.',\n                $this->dotPath($key),\n            )\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that all properties match their expected values.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function whereAll(array $bindings): static\n    {\n        foreach ($bindings as $key => $value) {\n            $this->where($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the property is of the expected type.\n     *\n     * @param  string  $key\n     * @param  string|array  $expected\n     * @return $this\n     */\n    public function whereType(string $key, $expected): static\n    {\n        $this->has($key);\n\n        $actual = $this->prop($key);\n\n        if (! is_array($expected)) {\n            $expected = explode('|', $expected);\n        }\n\n        PHPUnit::assertContains(\n            strtolower(gettype($actual)),\n            $expected,\n            sprintf('Property [%s] is not of expected type [%s].', $this->dotPath($key), implode('|', $expected))\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that all properties are of their expected types.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function whereAllType(array $bindings): static\n    {\n        foreach ($bindings as $key => $value) {\n            $this->whereType($key, $value);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the property contains the expected values.\n     *\n     * @param  string  $key\n     * @param  mixed  $expected\n     * @return $this\n     */\n    public function whereContains(string $key, $expected)\n    {\n        $actual = new Collection(\n            $this->prop($key) ?? $this->prop()\n        );\n\n        $missing = (new Collection($expected))\n            ->map(fn ($search) => enum_value($search))\n            ->reject(function ($search) use ($key, $actual) {\n                if ($actual->containsStrict($key, $search)) {\n                    return true;\n                }\n\n                return $actual->containsStrict($search);\n            });\n\n        if ($missing->whereInstanceOf('Closure')->isNotEmpty()) {\n            PHPUnit::assertEmpty(\n                $missing->toArray(),\n                sprintf(\n                    'Property [%s] does not contain a value that passes the truth test within the given closure.',\n                    $key,\n                )\n            );\n        } else {\n            PHPUnit::assertEmpty(\n                $missing->toArray(),\n                sprintf(\n                    'Property [%s] does not contain [%s].',\n                    $key,\n                    implode(', ', array_values($missing->toArray()))\n                )\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Ensures that all properties are sorted the same way, recursively.\n     *\n     * @param  mixed  $value\n     * @return void\n     */\n    protected function ensureSorted(&$value): void\n    {\n        if (! is_array($value)) {\n            return;\n        }\n\n        foreach ($value as &$arg) {\n            $this->ensureSorted($arg);\n        }\n\n        ksort($value);\n    }\n\n    /**\n     * Compose the absolute \"dot\" path to the given key.\n     *\n     * @param  string  $key\n     * @return string\n     */\n    abstract protected function dotPath(string $key = ''): string;\n\n    /**\n     * Ensure that the given prop exists.\n     *\n     * @param  string  $key\n     * @param  null  $value\n     * @param  \\Closure|null  $scope\n     * @return $this\n     */\n    abstract public function has(string $key, $value = null, ?Closure $scope = null);\n\n    /**\n     * Retrieve a prop within the current scope using \"dot\" notation.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    abstract protected function prop(?string $key = null);\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Testing/LoggedExceptionCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Support\\Collection;\n\nclass LoggedExceptionCollection extends Collection\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/ParallelConsoleOutput.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\n\nclass ParallelConsoleOutput extends ConsoleOutput\n{\n    /**\n     * The original output instance.\n     *\n     * @var \\Symfony\\Component\\Console\\Output\\OutputInterface\n     */\n    protected $output;\n\n    /**\n     * The output that should be ignored.\n     *\n     * @var array\n     */\n    protected $ignore = [\n        'Running phpunit in',\n        'Configuration read from',\n    ];\n\n    /**\n     * Create a new Parallel ConsoleOutput instance.\n     *\n     * @param  \\Symfony\\Component\\Console\\Output\\OutputInterface  $output\n     */\n    public function __construct($output)\n    {\n        parent::__construct(\n            $output->getVerbosity(),\n            $output->isDecorated(),\n            $output->getFormatter(),\n        );\n\n        $this->output = $output;\n    }\n\n    /**\n     * Writes a message to the output.\n     *\n     * @param  string|iterable  $messages\n     * @param  bool  $newline\n     * @param  int  $options\n     * @return void\n     */\n    public function write($messages, bool $newline = false, int $options = 0): void\n    {\n        $messages = (new Collection($messages))\n            ->filter(fn ($message) => ! Str::contains($message, $this->ignore));\n\n        $this->output->write($messages->toArray(), $newline, $options);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/ParallelRunner.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Testing\\Concerns\\RunsInParallel;\n\nif (interface_exists(\\ParaTest\\RunnerInterface::class)) {\n    class ParallelRunner implements \\ParaTest\\RunnerInterface\n    {\n        use RunsInParallel;\n\n        /**\n         * Runs the test suite.\n         *\n         * @return int\n         */\n        public function run(): int\n        {\n            return $this->execute();\n        }\n    }\n} else {\n    class ParallelRunner implements \\ParaTest\\Runners\\PHPUnit\\RunnerInterface\n    {\n        use RunsInParallel;\n\n        /**\n         * Runs the test suite.\n         *\n         * @return void\n         */\n        public function run(): void\n        {\n            $this->execute();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/ParallelTesting.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Support\\Str;\n\nclass ParallelTesting\n{\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The options resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $optionsResolver;\n\n    /**\n     * The token resolver callback.\n     *\n     * @var \\Closure|null\n     */\n    protected $tokenResolver;\n\n    /**\n     * All of the registered \"setUp\" process callbacks.\n     *\n     * @var array\n     */\n    protected $setUpProcessCallbacks = [];\n\n    /**\n     * All of the registered \"setUp\" test case callbacks.\n     *\n     * @var array\n     */\n    protected $setUpTestCaseCallbacks = [];\n\n    /**\n     * All of the registered \"setUp\" test database callbacks prior to the migrations.\n     *\n     * @var array\n     */\n    protected $setUpTestDatabaseBeforeMigratingCallbacks = [];\n\n    /**\n     * All of the registered \"setUp\" test database callbacks.\n     *\n     * @var array\n     */\n    protected $setUpTestDatabaseCallbacks = [];\n\n    /**\n     * All of the registered \"tearDown\" process callbacks.\n     *\n     * @var array\n     */\n    protected $tearDownProcessCallbacks = [];\n\n    /**\n     * All of the registered \"tearDown\" test case callbacks.\n     *\n     * @var array\n     */\n    protected $tearDownTestCaseCallbacks = [];\n\n    /**\n     * Create a new parallel testing instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     */\n    public function __construct(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Set a callback that should be used when resolving options.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public function resolveOptionsUsing($resolver)\n    {\n        $this->optionsResolver = $resolver;\n    }\n\n    /**\n     * Set a callback that should be used when resolving the unique process token.\n     *\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public function resolveTokenUsing($resolver)\n    {\n        $this->tokenResolver = $resolver;\n    }\n\n    /**\n     * Register a \"setUp\" process callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function setUpProcess($callback)\n    {\n        $this->setUpProcessCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a \"setUp\" test case callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function setUpTestCase($callback)\n    {\n        $this->setUpTestCaseCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a \"setUp\" test database callback that runs prior to the migrations.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function setUpTestDatabaseBeforeMigrating($callback)\n    {\n        $this->setUpTestDatabaseBeforeMigratingCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a \"setUp\" test database callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function setUpTestDatabase($callback)\n    {\n        $this->setUpTestDatabaseCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a \"tearDown\" process callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function tearDownProcess($callback)\n    {\n        $this->tearDownProcessCallbacks[] = $callback;\n    }\n\n    /**\n     * Register a \"tearDown\" test case callback.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function tearDownTestCase($callback)\n    {\n        $this->tearDownTestCaseCallbacks[] = $callback;\n    }\n\n    /**\n     * Call all of the \"setUp\" process callbacks.\n     *\n     * @return void\n     */\n    public function callSetUpProcessCallbacks()\n    {\n        $this->whenRunningInParallel(function () {\n            foreach ($this->setUpProcessCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Call all of the \"setUp\" test case callbacks.\n     *\n     * @param  \\Illuminate\\Foundation\\Testing\\TestCase  $testCase\n     * @return void\n     */\n    public function callSetUpTestCaseCallbacks($testCase)\n    {\n        $this->whenRunningInParallel(function () use ($testCase) {\n            foreach ($this->setUpTestCaseCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'testCase' => $testCase,\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Call all of the \"setUp\" test database callbacks that run prior to migrations.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    public function callSetUpTestDatabaseBeforeMigratingCallbacks($database)\n    {\n        $this->whenRunningInParallel(function () use ($database) {\n            foreach ($this->setUpTestDatabaseBeforeMigratingCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'database' => $database,\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Call all of the \"setUp\" test database callbacks.\n     *\n     * @param  string  $database\n     * @return void\n     */\n    public function callSetUpTestDatabaseCallbacks($database)\n    {\n        $this->whenRunningInParallel(function () use ($database) {\n            foreach ($this->setUpTestDatabaseCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'database' => $database,\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Call all of the \"tearDown\" process callbacks.\n     *\n     * @return void\n     */\n    public function callTearDownProcessCallbacks()\n    {\n        $this->whenRunningInParallel(function () {\n            foreach ($this->tearDownProcessCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Call all of the \"tearDown\" test case callbacks.\n     *\n     * @param  \\Illuminate\\Foundation\\Testing\\TestCase  $testCase\n     * @return void\n     */\n    public function callTearDownTestCaseCallbacks($testCase)\n    {\n        $this->whenRunningInParallel(function () use ($testCase) {\n            foreach ($this->tearDownTestCaseCallbacks as $callback) {\n                $this->container->call($callback, [\n                    'testCase' => $testCase,\n                    'token' => $this->token(),\n                ]);\n            }\n        });\n    }\n\n    /**\n     * Get a parallel testing option.\n     *\n     * @param  string  $option\n     * @return mixed\n     */\n    public function option($option)\n    {\n        $optionsResolver = $this->optionsResolver ?: function ($option) {\n            $option = 'LARAVEL_PARALLEL_TESTING_'.Str::upper($option);\n\n            return $_SERVER[$option] ?? false;\n        };\n\n        return $optionsResolver($option);\n    }\n\n    /**\n     * Gets a unique test token.\n     *\n     * @return string|false\n     */\n    public function token()\n    {\n        return $this->tokenResolver\n            ? call_user_func($this->tokenResolver)\n            : ($_SERVER['TEST_TOKEN'] ?? false);\n    }\n\n    /**\n     * Apply the callback if tests are running in parallel.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function whenRunningInParallel($callback)\n    {\n        if ($this->inParallel()) {\n            $callback();\n        }\n    }\n\n    /**\n     * Indicates if the current tests are been run in parallel.\n     *\n     * @return bool\n     */\n    protected function inParallel()\n    {\n        return ! empty($_SERVER['LARAVEL_PARALLEL_TESTING']) && $this->token();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/ParallelTestingServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Testing\\Concerns\\TestCaches;\nuse Illuminate\\Testing\\Concerns\\TestDatabases;\nuse Illuminate\\Testing\\Concerns\\TestViews;\n\nclass ParallelTestingServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    use TestCaches, TestDatabases, TestViews;\n\n    /**\n     * Boot the application's service providers.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        if ($this->app->runningInConsole()) {\n            $this->bootTestCache();\n            $this->bootTestDatabase();\n            $this->bootTestViews();\n        }\n    }\n\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        if ($this->app->runningInConsole()) {\n            $this->app->singleton(ParallelTesting::class, function () {\n                return new ParallelTesting($this->app);\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/PendingCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\PromptValidationException;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Laravel\\Prompts\\Note as PromptsNote;\nuse Laravel\\Prompts\\Prompt as BasePrompt;\nuse Laravel\\Prompts\\Table as PromptsTable;\nuse Mockery;\nuse Mockery\\Exception\\NoMatchingExpectationException;\nuse PHPUnit\\Framework\\TestCase as PHPUnitTestCase;\nuse Symfony\\Component\\Console\\Command\\Command;\nuse Symfony\\Component\\Console\\Helper\\Table;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\n\nclass PendingCommand\n{\n    use Conditionable, Macroable, Tappable;\n\n    /**\n     * The test being run.\n     *\n     * @var \\Illuminate\\Foundation\\Testing\\TestCase\n     */\n    public $test;\n\n    /**\n     * The application instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $app;\n\n    /**\n     * The command to run.\n     *\n     * @var string\n     */\n    protected $command;\n\n    /**\n     * The parameters to pass to the command.\n     *\n     * @var array\n     */\n    protected $parameters;\n\n    /**\n     * The expected exit code.\n     *\n     * @var int\n     */\n    protected $expectedExitCode;\n\n    /**\n     * The unexpected exit code.\n     *\n     * @var int\n     */\n    protected $unexpectedExitCode;\n\n    /**\n     * Determine if the command has executed.\n     *\n     * @var bool\n     */\n    protected $hasExecuted = false;\n\n    /**\n     * Create a new pending console command run.\n     *\n     * @param  \\PHPUnit\\Framework\\TestCase  $test\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $app\n     * @param  string  $command\n     * @param  array  $parameters\n     */\n    public function __construct(PHPUnitTestCase $test, Container $app, $command, $parameters)\n    {\n        $this->app = $app;\n        $this->test = $test;\n        $this->command = $command;\n        $this->parameters = $parameters;\n    }\n\n    /**\n     * Specify an expected question that will be asked when the command runs.\n     *\n     * @param  string  $question\n     * @param  string|bool  $answer\n     * @return $this\n     */\n    public function expectsQuestion($question, $answer)\n    {\n        $this->test->expectedQuestions[] = [$question, $answer];\n\n        return $this;\n    }\n\n    /**\n     * Specify an expected confirmation question that will be asked when the command runs.\n     *\n     * @param  string  $question\n     * @param  string  $answer\n     * @return $this\n     */\n    public function expectsConfirmation($question, $answer = 'no')\n    {\n        return $this->expectsQuestion($question, strtolower($answer) === 'yes');\n    }\n\n    /**\n     * Specify an expected choice question with expected answers that will be asked/shown when the command runs.\n     *\n     * @param  string  $question\n     * @param  string|array  $answer\n     * @param  array  $answers\n     * @param  bool  $strict\n     * @return $this\n     */\n    public function expectsChoice($question, $answer, $answers, $strict = false)\n    {\n        $this->test->expectedChoices[$question] = [\n            'expected' => $answers,\n            'strict' => $strict,\n        ];\n\n        return $this->expectsQuestion($question, $answer);\n    }\n\n    /**\n     * Specify an expected search question with an expected search string, followed by an expected choice question with expected answers.\n     *\n     * @param  string  $question\n     * @param  string|array  $answer\n     * @param  string  $search\n     * @param  array  $answers\n     * @return $this\n     */\n    public function expectsSearch($question, $answer, $search, $answers)\n    {\n        return $this\n            ->expectsQuestion($question, $search)\n            ->expectsChoice($question, $answer, $answers);\n    }\n\n    /**\n     * Specify output that should be printed when the command runs.\n     *\n     * @param  string|null  $output\n     * @return $this\n     */\n    public function expectsOutput($output = null)\n    {\n        if ($output === null) {\n            $this->test->expectsOutput = true;\n\n            return $this;\n        }\n\n        $this->test->expectedOutput[] = $output;\n\n        return $this;\n    }\n\n    /**\n     * Specify output that should never be printed when the command runs.\n     *\n     * @param  string|null  $output\n     * @return $this\n     */\n    public function doesntExpectOutput($output = null)\n    {\n        if ($output === null) {\n            $this->test->expectsOutput = false;\n\n            return $this;\n        }\n\n        $this->test->unexpectedOutput[$output] = false;\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given string should be contained in the command output.\n     *\n     * @param  string  $string\n     * @return $this\n     */\n    public function expectsOutputToContain($string)\n    {\n        $this->test->expectedOutputSubstrings[] = $string;\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given string shouldn't be contained in the command output.\n     *\n     * @param  string  $string\n     * @return $this\n     */\n    public function doesntExpectOutputToContain($string)\n    {\n        $this->test->unexpectedOutputSubstrings[$string] = false;\n\n        return $this;\n    }\n\n    /**\n     * Specify a table that should be printed when the command runs.\n     *\n     * @param  array  $headers\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $rows\n     * @param  string  $tableStyle\n     * @param  array  $columnStyles\n     * @return $this\n     */\n    public function expectsTable($headers, $rows, $tableStyle = 'default', array $columnStyles = [])\n    {\n        $table = (new Table($output = new BufferedOutput))\n            ->setHeaders((array) $headers)\n            ->setRows($rows instanceof Arrayable ? $rows->toArray() : $rows)\n            ->setStyle($tableStyle);\n\n        foreach ($columnStyles as $columnIndex => $columnStyle) {\n            $table->setColumnStyle($columnIndex, $columnStyle);\n        }\n\n        $table->render();\n\n        $lines = array_filter(\n            explode(PHP_EOL, $output->fetch())\n        );\n\n        foreach ($lines as $line) {\n            $this->expectsOutput($line);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts info message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsInfo(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'info')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts warning message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsWarning(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'warning')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts error message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsError(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'error')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts alert message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsAlert(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'alert')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts intro message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsIntro(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'intro')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify that the given Prompts outro message should be contained in the command output.\n     *\n     * @return $this\n     */\n    public function expectsPromptsOutro(string $message)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsNote($message, 'outro')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Specify a Prompts table that should be printed when the command runs.\n     *\n     * @param  array<int, string|array<int, string>>|Collection<int, string|array<int, string>>  $headers\n     * @param  array<int, array<int, string>>|Collection<int, array<int, string>>|null  $rows\n     * @return $this\n     *\n     * @phpstan-param ($rows is null ? list<list<string>>|Collection<int, list<string>> : list<string|list<string>>|Collection<int, string|list<string>>) $headers\n     */\n    public function expectsPromptsTable(array|Collection $headers, array|Collection|null $rows)\n    {\n        $this->expectOutputToContainPrompt(\n            new PromptsTable($headers, $rows)\n        );\n\n        return $this;\n    }\n\n    /**\n     * Render the given prompt and add the output to the expectations.\n     *\n     * @return void\n     */\n    protected function expectOutputToContainPrompt(BasePrompt $prompt)\n    {\n        $prompt->setOutput($output = new BufferedOutput);\n\n        $prompt->display();\n\n        $this->expectsOutputToContain(trim($output->fetch()));\n    }\n\n    /**\n     * Assert that the command has the given exit code.\n     *\n     * @param  int  $exitCode\n     * @return $this\n     */\n    public function assertExitCode($exitCode)\n    {\n        $this->expectedExitCode = $exitCode;\n\n        return $this;\n    }\n\n    /**\n     * Assert that the command does not have the given exit code.\n     *\n     * @param  int  $exitCode\n     * @return $this\n     */\n    public function assertNotExitCode($exitCode)\n    {\n        $this->unexpectedExitCode = $exitCode;\n\n        return $this;\n    }\n\n    /**\n     * Assert that the command has the success exit code.\n     *\n     * @return $this\n     */\n    public function assertSuccessful()\n    {\n        return $this->assertExitCode(Command::SUCCESS);\n    }\n\n    /**\n     * Assert that the command has the success exit code.\n     *\n     * @return $this\n     */\n    public function assertOk()\n    {\n        return $this->assertSuccessful();\n    }\n\n    /**\n     * Assert that the command does not have the success exit code.\n     *\n     * @return $this\n     */\n    public function assertFailed()\n    {\n        return $this->assertNotExitCode(Command::SUCCESS);\n    }\n\n    /**\n     * Execute the command.\n     *\n     * @return int\n     */\n    public function execute()\n    {\n        return $this->run();\n    }\n\n    /**\n     * Execute the command.\n     *\n     * @return int\n     *\n     * @throws \\Mockery\\Exception\\NoMatchingExpectationException\n     */\n    public function run()\n    {\n        $this->hasExecuted = true;\n\n        $mock = $this->mockConsoleOutput();\n\n        try {\n            $exitCode = $this->app->make(Kernel::class)->call($this->command, $this->parameters, $mock);\n        } catch (NoMatchingExpectationException $e) {\n            if ($e->getMethodName() === 'askQuestion') {\n                $this->test->fail('Unexpected question \"'.$e->getActualArguments()[0]->getQuestion().'\" was asked.');\n            }\n\n            throw $e;\n        } catch (PromptValidationException) {\n            $exitCode = Command::FAILURE;\n        }\n\n        if ($this->expectedExitCode !== null) {\n            $this->test->assertEquals(\n                $this->expectedExitCode, $exitCode,\n                \"Expected status code {$this->expectedExitCode} but received {$exitCode}.\"\n            );\n        } elseif (! is_null($this->unexpectedExitCode)) {\n            $this->test->assertNotEquals(\n                $this->unexpectedExitCode, $exitCode,\n                \"Unexpected status code {$this->unexpectedExitCode} was received.\"\n            );\n        }\n\n        $this->verifyExpectations();\n        $this->flushExpectations();\n\n        $this->app->offsetUnset(OutputStyle::class);\n\n        return $exitCode;\n    }\n\n    /**\n     * Debug the command.\n     *\n     * @return never\n     */\n    public function dd()\n    {\n        $consoleOutput = new OutputStyle(new ArrayInput($this->parameters), new ConsoleOutput());\n        $exitCode = $this->app->make(Kernel::class)->call($this->command, $this->parameters, $consoleOutput);\n\n        $streamOutput = $consoleOutput->getOutput()->getStream();\n        $output = stream_get_contents($streamOutput);\n\n        fclose($streamOutput);\n\n        dd([\n            'exitCode' => $exitCode,\n            'output' => $output,\n        ]);\n    }\n\n    /**\n     * Determine if expected questions / choices / outputs are fulfilled.\n     *\n     * @return void\n     */\n    protected function verifyExpectations()\n    {\n        if (count($this->test->expectedQuestions)) {\n            $this->test->fail('Question \"'.Arr::first($this->test->expectedQuestions)[0].'\" was not asked.');\n        }\n\n        if (count($this->test->expectedChoices) > 0) {\n            foreach ($this->test->expectedChoices as $question => $answers) {\n                $assertion = $answers['strict'] ? 'assertEquals' : 'assertEqualsCanonicalizing';\n\n                $this->test->{$assertion}(\n                    $answers['expected'],\n                    $answers['actual'],\n                    'Question \"'.$question.'\" has different options.'\n                );\n            }\n        }\n\n        if (count($this->test->expectedOutput)) {\n            $this->test->fail('Output \"'.Arr::first($this->test->expectedOutput).'\" was not printed.');\n        }\n\n        if (count($this->test->expectedOutputSubstrings)) {\n            $this->test->fail('Output does not contain \"'.Arr::first($this->test->expectedOutputSubstrings).'\".');\n        }\n\n        if ($output = array_search(true, $this->test->unexpectedOutput)) {\n            $this->test->fail('Output \"'.$output.'\" was printed.');\n        }\n\n        if ($output = array_search(true, $this->test->unexpectedOutputSubstrings)) {\n            $this->test->fail('Output \"'.$output.'\" was printed.');\n        }\n    }\n\n    /**\n     * Mock the application's console output.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    protected function mockConsoleOutput()\n    {\n        $mock = Mockery::mock(OutputStyle::class.'[askQuestion]', [\n            new ArrayInput($this->parameters), $this->createABufferedOutputMock(),\n        ]);\n\n        foreach ($this->test->expectedQuestions as $i => $question) {\n            $mock->shouldReceive('askQuestion')\n                ->once()\n                ->ordered()\n                ->with(Mockery::on(function ($argument) use ($question) {\n                    if (isset($this->test->expectedChoices[$question[0]])) {\n                        $this->test->expectedChoices[$question[0]]['actual'] = $argument instanceof ChoiceQuestion && ! array_is_list($this->test->expectedChoices[$question[0]]['expected'])\n                            ? $argument->getChoices()\n                            : $argument->getAutocompleterValues();\n                    }\n\n                    return $argument->getQuestion() == $question[0];\n                }))\n                ->andReturnUsing(function () use ($question, $i) {\n                    unset($this->test->expectedQuestions[$i]);\n\n                    return $question[1];\n                });\n        }\n\n        $this->app->bind(OutputStyle::class, function () use ($mock) {\n            return $mock;\n        });\n\n        return $mock;\n    }\n\n    /**\n     * Create a mock for the buffered output.\n     *\n     * @return \\Mockery\\MockInterface\n     */\n    private function createABufferedOutputMock()\n    {\n        $mock = Mockery::mock(BufferedOutput::class.'[doWrite]')\n            ->shouldAllowMockingProtectedMethods()\n            ->shouldIgnoreMissing();\n\n        if ($this->test->expectsOutput === false) {\n            $mock->shouldReceive('doWrite')->never();\n\n            return $mock;\n        }\n\n        if ($this->test->expectsOutput === true\n            && count($this->test->expectedOutput) === 0\n            && count($this->test->expectedOutputSubstrings) === 0) {\n            $mock->shouldReceive('doWrite')->atLeast()->once();\n        }\n\n        foreach ($this->test->expectedOutput as $i => $output) {\n            $mock->shouldReceive('doWrite')\n                ->once()\n                ->ordered()\n                ->with($output, Mockery::any())\n                ->andReturnUsing(function () use ($i) {\n                    unset($this->test->expectedOutput[$i]);\n                });\n        }\n\n        foreach ($this->test->expectedOutputSubstrings as $i => $text) {\n            $mock->shouldReceive('doWrite')\n                ->atLeast()\n                ->times(0)\n                ->withArgs(fn ($output) => str_contains($output, $text))\n                ->andReturnUsing(function () use ($i) {\n                    unset($this->test->expectedOutputSubstrings[$i]);\n                });\n        }\n\n        foreach ($this->test->unexpectedOutput as $output => $displayed) {\n            $mock->shouldReceive('doWrite')\n                ->atLeast()\n                ->times(0)\n                ->ordered()\n                ->with($output, Mockery::any())\n                ->andReturnUsing(function () use ($output) {\n                    $this->test->unexpectedOutput[$output] = true;\n                });\n        }\n\n        foreach ($this->test->unexpectedOutputSubstrings as $text => $displayed) {\n            $mock->shouldReceive('doWrite')\n                ->atLeast()\n                ->times(0)\n                ->withArgs(fn ($output) => str_contains($output, $text))\n                ->andReturnUsing(function () use ($text) {\n                    $this->test->unexpectedOutputSubstrings[$text] = true;\n                });\n        }\n\n        return $mock;\n    }\n\n    /**\n     * Flush the expectations from the test case.\n     *\n     * @return void\n     */\n    protected function flushExpectations()\n    {\n        $this->test->expectedOutput = [];\n        $this->test->expectedOutputSubstrings = [];\n        $this->test->unexpectedOutput = [];\n        $this->test->unexpectedOutputSubstrings = [];\n        $this->test->expectedTables = [];\n        $this->test->expectedQuestions = [];\n        $this->test->expectedChoices = [];\n    }\n\n    /**\n     * Handle the object's destruction.\n     *\n     * @return void\n     */\n    public function __destruct()\n    {\n        if ($this->hasExecuted) {\n            return;\n        }\n\n        $this->run();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/TestComponent.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Testing\\Assert as PHPUnit;\nuse Illuminate\\Testing\\Constraints\\SeeInHtml;\nuse Illuminate\\Testing\\Constraints\\SeeInOrder;\nuse Stringable;\n\nclass TestComponent implements Stringable\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The original component.\n     *\n     * @var \\Illuminate\\View\\Component\n     */\n    public $component;\n\n    /**\n     * The rendered component contents.\n     *\n     * @var string\n     */\n    protected $rendered;\n\n    /**\n     * Create a new test component instance.\n     *\n     * @param  \\Illuminate\\View\\Component  $component\n     * @param  \\Illuminate\\View\\View  $view\n     */\n    public function __construct($component, $view)\n    {\n        $this->component = $component;\n\n        $this->rendered = $view->render();\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the rendered component.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::assertStringContainsString((string) $value, $this->rendered);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are contained within the rendered component.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertSeeHtml($value)\n    {\n        return $this->assertSee($value, false);\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the rendered component.\n     *\n     * @param  array  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::assertThat($values, new SeeInOrder($this->rendered));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML strings are contained in order within the rendered component.\n     *\n     * @param  list<string>  $values\n     * @return $this\n     */\n    public function assertSeeHtmlInOrder(array $values)\n    {\n        return $this->assertSeeInOrder($values, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the rendered component text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        PHPUnit::assertThat($values, new SeeInHtml($this->rendered));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the rendered component text.\n     *\n     * @param  list<string>  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeTextInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::assertThat($values, new SeeInHtml($this->rendered, true));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the rendered component.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::assertStringNotContainsString((string) $value, $this->rendered);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are not contained within the rendered component.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertDontSeeHtml($value)\n    {\n        return $this->assertDontSee($value, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the rendered component text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        $rendered = strip_tags($this->rendered);\n\n        foreach ($values as $value) {\n            PHPUnit::assertStringNotContainsString((string) $value, $rendered);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the string contents of the rendered component.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->rendered;\n    }\n\n    /**\n     * Dynamically access properties on the underlying component.\n     *\n     * @param  string  $attribute\n     * @return mixed\n     */\n    public function __get($attribute)\n    {\n        return $this->component->{$attribute};\n    }\n\n    /**\n     * Dynamically call methods on the underlying component.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        return $this->component->{$method}(...$parameters);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/TestResponse.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse ArrayAccess;\nuse Closure;\nuse Illuminate\\Contracts\\Support\\MessageBag;\nuse Illuminate\\Contracts\\View\\View;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Dumpable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\Tappable;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Illuminate\\Testing\\Constraints\\SeeInHtml;\nuse Illuminate\\Testing\\Constraints\\SeeInOrder;\nuse Illuminate\\Testing\\Fluent\\AssertableJson;\nuse Illuminate\\Testing\\TestResponseAssert as PHPUnit;\nuse LogicException;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\StreamedJsonResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\n/**\n * @template TResponse of \\Symfony\\Component\\HttpFoundation\\Response\n *\n * @mixin \\Illuminate\\Http\\Response\n */\nclass TestResponse implements ArrayAccess\n{\n    use Concerns\\AssertsStatusCodes, Conditionable, Dumpable, Tappable, Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The original request.\n     *\n     * @var \\Illuminate\\Http\\Request|null\n     */\n    public $baseRequest;\n\n    /**\n     * The response to delegate to.\n     *\n     * @var TResponse\n     */\n    public $baseResponse;\n\n    /**\n     * The collection of logged exceptions for the request.\n     *\n     * @var \\Illuminate\\Support\\Collection\n     */\n    public $exceptions;\n\n    /**\n     * The streamed content of the response.\n     *\n     * @var string\n     */\n    protected $streamedContent;\n\n    /**\n     * Create a new test response instance.\n     *\n     * @param  TResponse  $response\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     */\n    public function __construct($response, $request = null)\n    {\n        $this->baseResponse = $response;\n        $this->baseRequest = $request;\n        $this->exceptions = new Collection;\n    }\n\n    /**\n     * Create a new TestResponse from another response.\n     *\n     * @template R of TResponse\n     *\n     * @param  R  $response\n     * @param  \\Illuminate\\Http\\Request|null  $request\n     * @return static<R>\n     */\n    public static function fromBaseResponse($response, $request = null)\n    {\n        return new static($response, $request);\n    }\n\n    /**\n     * Assert that the response has a successful status code.\n     *\n     * @return $this\n     */\n    public function assertSuccessful()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isSuccessful(),\n            $this->statusMessageWithDetails('>=200, <300', $this->getStatusCode())\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the Precognition request was successful.\n     *\n     * @return $this\n     */\n    public function assertSuccessfulPrecognition()\n    {\n        $this->assertNoContent();\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->headers->has('Precognition-Success'),\n            'Header [Precognition-Success] not present on response.'\n        );\n\n        PHPUnit::withResponse($this)->assertSame(\n            'true',\n            $this->headers->get('Precognition-Success'),\n            'The Precognition-Success header was found, but the value is not `true`.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response is a client error.\n     *\n     * @return $this\n     */\n    public function assertClientError()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isClientError(),\n            $this->statusMessageWithDetails('>=400, < 500', $this->getStatusCode())\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response is a server error.\n     *\n     * @return $this\n     */\n    public function assertServerError()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isServerError(),\n            $this->statusMessageWithDetails('>=500, < 600', $this->getStatusCode())\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the given status code.\n     *\n     * @param  int  $status\n     * @return $this\n     */\n    public function assertStatus($status)\n    {\n        $message = $this->statusMessageWithDetails($status, $actual = $this->getStatusCode());\n\n        PHPUnit::withResponse($this)->assertSame($status, $actual, $message);\n\n        return $this;\n    }\n\n    /**\n     * Get an assertion message for a status assertion containing extra details when available.\n     *\n     * @param  string|int  $expected\n     * @param  string|int  $actual\n     * @return string\n     */\n    protected function statusMessageWithDetails($expected, $actual)\n    {\n        return \"Expected response status code [{$expected}] but received {$actual}.\";\n    }\n\n    /**\n     * Assert whether the response is redirecting to a given URI.\n     *\n     * @param  string|null  $uri\n     * @return $this\n     */\n    public function assertRedirect($uri = null)\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        if (! is_null($uri)) {\n            $this->assertLocation($uri);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting to a URI that contains the given URI.\n     *\n     * @param  string  $uri\n     * @return $this\n     */\n    public function assertRedirectContains($uri)\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        PHPUnit::withResponse($this)->assertTrue(\n            Str::contains($this->headers->get('Location'), $uri), 'Redirect location ['.$this->headers->get('Location').'] does not contain ['.$uri.'].'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting back to the previous location.\n     *\n     * @return $this\n     */\n    public function assertRedirectBack()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        $this->assertLocation(app('url')->previous());\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting back to the previous location with the given errors in the session.\n     *\n     * @param  string|array  $keys\n     * @param  mixed  $format\n     * @param  string  $errorBag\n     * @return $this\n     */\n    public function assertRedirectBackWithErrors($keys = [], $format = null, $errorBag = 'default')\n    {\n        $this->assertRedirectBack();\n\n        $this->assertSessionHasErrors($keys, $format, $errorBag);\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting back to the previous location with no errors in the session.\n     *\n     * @return $this\n     */\n    public function assertRedirectBackWithoutErrors()\n    {\n        $this->assertRedirectBack();\n\n        $this->assertSessionHasNoErrors();\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting to a given route.\n     *\n     * @param  \\BackedEnum|string  $name\n     * @param  mixed  $parameters\n     * @return $this\n     */\n    public function assertRedirectToRoute($name, $parameters = [])\n    {\n        $uri = route($name, $parameters);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        $this->assertLocation($uri);\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting to a given signed route.\n     *\n     * @param  \\BackedEnum|string|null  $name\n     * @param  mixed  $parameters\n     * @param  bool  $absolute\n     * @return $this\n     */\n    public function assertRedirectToSignedRoute($name = null, $parameters = [], $absolute = true)\n    {\n        if (! is_null($name)) {\n            $uri = route($name, $parameters);\n        }\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        $request = Request::create($this->headers->get('Location'));\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $request->hasValidSignature($absolute), 'The response is not a redirect to a signed route.'\n        );\n\n        if (! is_null($name)) {\n            $expectedUri = rtrim($request->fullUrlWithQuery([\n                'signature' => null,\n                'expires' => null,\n            ]), '?');\n\n            PHPUnit::withResponse($this)->assertEquals(\n                app('url')->to($uri), $expectedUri\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert whether the response is redirecting to a given controller action.\n     *\n     * @param  string|array  $name\n     * @param  array  $parameters\n     * @return $this\n     */\n    public function assertRedirectToAction($name, $parameters = [])\n    {\n        $uri = action($name, $parameters);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->isRedirect(),\n            $this->statusMessageWithDetails('201, 301, 302, 303, 307, 308', $this->getStatusCode()),\n        );\n\n        $this->assertLocation($uri);\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response contains the given header and equals the optional value.\n     *\n     * @param  string  $headerName\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertHeader($headerName, $value = null)\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->headers->has($headerName), \"Header [{$headerName}] not present on response.\"\n        );\n\n        $actual = $this->headers->get($headerName);\n\n        if (! is_null($value)) {\n            PHPUnit::withResponse($this)->assertEqualsIgnoringCase(\n                $value, $this->headers->get($headerName),\n                \"Header [{$headerName}] was found, but value [{$actual}] does not match [{$value}].\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response contains the given header and that its value contains the given string.\n     *\n     * @param  string  $headerName\n     * @param  string  $value\n     * @return $this\n     */\n    public function assertHeaderContains($headerName, $value)\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->headers->has($headerName), \"Header [{$headerName}] not present on response.\"\n        );\n\n        $actual = $this->headers->get($headerName, '');\n\n        PHPUnit::withResponse($this)->assertTrue(\n            Str::contains($actual, $value),\n            \"Header [{$headerName}] was found, but [{$actual}] does not contain [{$value}].\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response does not contain the given header.\n     *\n     * @param  string  $headerName\n     * @return $this\n     */\n    public function assertHeaderMissing($headerName)\n    {\n        PHPUnit::withResponse($this)->assertFalse(\n            $this->headers->has($headerName), \"Unexpected header [{$headerName}] is present on response.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the current location header matches the given URI.\n     *\n     * @param  string  $uri\n     * @return $this\n     */\n    public function assertLocation($uri)\n    {\n        PHPUnit::withResponse($this)->assertEquals(\n            app('url')->to($uri), app('url')->to($this->headers->get('Location', ''))\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response offers a file download.\n     *\n     * @param  string|null  $filename\n     * @return $this\n     */\n    public function assertDownload($filename = null)\n    {\n        $contentDisposition = explode(';', $this->headers->get('content-disposition', ''));\n\n        if (trim($contentDisposition[0]) !== 'attachment') {\n            PHPUnit::withResponse($this)->fail(\n                'Response does not offer a file download.'.PHP_EOL.\n                'Disposition ['.trim($contentDisposition[0]).'] found in header, [attachment] expected.'\n            );\n        }\n\n        if (! is_null($filename)) {\n            if (isset($contentDisposition[1]) &&\n                trim(explode('=', $contentDisposition[1])[0]) !== 'filename') {\n                PHPUnit::withResponse($this)->fail(\n                    'Unsupported Content-Disposition header provided.'.PHP_EOL.\n                    'Disposition ['.trim(explode('=', $contentDisposition[1])[0]).'] found in header, [filename] expected.'\n                );\n            }\n\n            $message = \"Expected file [{$filename}] is not present in Content-Disposition header.\";\n\n            if (! isset($contentDisposition[1])) {\n                PHPUnit::withResponse($this)->fail($message);\n            } else {\n                PHPUnit::withResponse($this)->assertSame(\n                    $filename,\n                    isset(explode('=', $contentDisposition[1])[1])\n                        ? trim(explode('=', $contentDisposition[1])[1], \" \\\"'\")\n                        : '',\n                    $message\n                );\n\n                return $this;\n            }\n        } else {\n            PHPUnit::withResponse($this)->assertTrue(true);\n\n            return $this;\n        }\n    }\n\n    /**\n     * Asserts that the response contains the given cookie and equals the optional value.\n     *\n     * @param  string  $cookieName\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertPlainCookie($cookieName, $value = null)\n    {\n        $this->assertCookie($cookieName, $value, false);\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response contains the given cookie and equals the optional value.\n     *\n     * @param  string  $cookieName\n     * @param  mixed  $value\n     * @param  bool  $encrypted\n     * @param  bool  $unserialize\n     * @return $this\n     */\n    public function assertCookie($cookieName, $value = null, $encrypted = true, $unserialize = false)\n    {\n        PHPUnit::withResponse($this)->assertNotNull(\n            $cookie = $this->getCookie($cookieName, $encrypted && ! is_null($value), $unserialize),\n            \"Cookie [{$cookieName}] not present on response.\"\n        );\n\n        if (! $cookie || is_null($value)) {\n            return $this;\n        }\n\n        $cookieValue = $cookie->getValue();\n\n        PHPUnit::withResponse($this)->assertEquals(\n            $value, $cookieValue,\n            \"Cookie [{$cookieName}] was found, but value [{$cookieValue}] does not match [{$value}].\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response contains the given cookie and is expired.\n     *\n     * @param  string  $cookieName\n     * @return $this\n     */\n    public function assertCookieExpired($cookieName)\n    {\n        PHPUnit::withResponse($this)->assertNotNull(\n            $cookie = $this->getCookie($cookieName, false),\n            \"Cookie [{$cookieName}] not present on response.\"\n        );\n\n        $expiresAt = Carbon::createFromTimestamp($cookie->getExpiresTime(), date_default_timezone_get());\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $cookie->getExpiresTime() !== 0 && $expiresAt->lessThan(Carbon::now()),\n            \"Cookie [{$cookieName}] is not expired, it expires at [{$expiresAt}].\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response contains the given cookie and is not expired.\n     *\n     * @param  string  $cookieName\n     * @return $this\n     */\n    public function assertCookieNotExpired($cookieName)\n    {\n        PHPUnit::withResponse($this)->assertNotNull(\n            $cookie = $this->getCookie($cookieName, false),\n            \"Cookie [{$cookieName}] not present on response.\"\n        );\n\n        $expiresAt = Carbon::createFromTimestamp($cookie->getExpiresTime(), date_default_timezone_get());\n\n        PHPUnit::withResponse($this)->assertTrue(\n            $cookie->getExpiresTime() === 0 || $expiresAt->greaterThan(Carbon::now()),\n            \"Cookie [{$cookieName}] is expired, it expired at [{$expiresAt}].\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Asserts that the response does not contain the given cookie.\n     *\n     * @param  string  $cookieName\n     * @return $this\n     */\n    public function assertCookieMissing($cookieName)\n    {\n        PHPUnit::withResponse($this)->assertNull(\n            $this->getCookie($cookieName, false),\n            \"Cookie [{$cookieName}] is present on response.\"\n        );\n\n        return $this;\n    }\n\n    /**\n     * Get the given cookie from the response.\n     *\n     * @param  string  $cookieName\n     * @param  bool  $decrypt\n     * @param  bool  $unserialize\n     * @return \\Symfony\\Component\\HttpFoundation\\Cookie|null\n     */\n    public function getCookie($cookieName, $decrypt = true, $unserialize = false)\n    {\n        foreach ($this->headers->getCookies() as $cookie) {\n            if ($cookie->getName() === $cookieName) {\n                if (! $decrypt) {\n                    return $cookie;\n                }\n\n                $decryptedValue = CookieValuePrefix::remove(\n                    app('encrypter')->decrypt($cookie->getValue(), $unserialize)\n                );\n\n                return new Cookie(\n                    $cookie->getName(),\n                    $decryptedValue,\n                    $cookie->getExpiresTime(),\n                    $cookie->getPath(),\n                    $cookie->getDomain(),\n                    $cookie->isSecure(),\n                    $cookie->isHttpOnly(),\n                    $cookie->isRaw(),\n                    $cookie->getSameSite(),\n                    $cookie->isPartitioned()\n                );\n            }\n        }\n    }\n\n    /**\n     * Assert that the given string matches the response content.\n     *\n     * @param  string  $value\n     * @return $this\n     */\n    public function assertContent($value)\n    {\n        PHPUnit::withResponse($this)->assertSame($value, $this->getContent());\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response was streamed.\n     *\n     * @return $this\n     */\n    public function assertStreamed()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            $this->baseResponse instanceof StreamedResponse || $this->baseResponse instanceof StreamedJsonResponse,\n            'Expected the response to be streamed, but it wasn\\'t.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response was not streamed.\n     *\n     * @return $this\n     */\n    public function assertNotStreamed()\n    {\n        PHPUnit::withResponse($this)->assertTrue(\n            ! $this->baseResponse instanceof StreamedResponse && ! $this->baseResponse instanceof StreamedJsonResponse,\n            'Response was unexpectedly streamed.'\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given string matches the streamed response content.\n     *\n     * @param  string  $value\n     * @return $this\n     */\n    public function assertStreamedContent($value)\n    {\n        PHPUnit::withResponse($this)->assertSame($value, $this->streamedContent());\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given array matches the streamed JSON response content.\n     *\n     * @param  array  $value\n     * @return $this\n     */\n    public function assertStreamedJsonContent($value)\n    {\n        return $this->assertStreamedContent(json_encode($value, JSON_THROW_ON_ERROR));\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the response.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::withResponse($this)->assertStringContainsString((string) $value, $this->getContent());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are contained within the response.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertSeeHtml($value)\n    {\n        return $this->assertSee($value, false);\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the response.\n     *\n     * @param  list<string>  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::withResponse($this)->assertThat($values, new SeeInOrder($this->getContent()));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML strings are contained in order within the response.\n     *\n     * @param  list<string>  $values\n     * @return $this\n     */\n    public function assertSeeHtmlInOrder(array $values)\n    {\n        return $this->assertSeeInOrder($values, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the response text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        PHPUnit::withResponse($this)->assertThat($values, new SeeInHtml($this->getContent()));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the response text.\n     *\n     * @param  list<string>  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeTextInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::withResponse($this)->assertThat($values, new SeeInHtml($this->getContent(), true));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the response.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::withResponse($this)->assertStringNotContainsString((string) $value, $this->getContent());\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are not contained within the response.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertDontSeeHtml($value)\n    {\n        return $this->assertDontSee($value, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the response text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        PHPUnit::withResponse($this)->assertThat($values, new SeeInHtml($this->getContent(), negate: true));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response is a superset of the given JSON.\n     *\n     * @param  array|callable  $value\n     * @param  bool  $strict\n     * @return $this\n     */\n    public function assertJson($value, $strict = false)\n    {\n        $json = $this->decodeResponseJson();\n\n        if (is_array($value)) {\n            $json->assertSubset($value, $strict);\n        } else {\n            $assert = AssertableJson::fromAssertableJsonString($json);\n\n            $value($assert);\n\n            if (Arr::isAssoc($assert->toArray())) {\n                $assert->interacted();\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the expected value and type exists at the given path in the response.\n     *\n     * @param  string  $path\n     * @param  mixed  $expect\n     * @return $this\n     */\n    public function assertJsonPath($path, $expect)\n    {\n        $this->decodeResponseJson()->assertPath($path, $expect);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given path in the response contains all of the expected values without looking at the order.\n     *\n     * @param  string  $path\n     * @param  array  $expect\n     * @return $this\n     */\n    public function assertJsonPathCanonicalizing($path, array $expect)\n    {\n        $this->decodeResponseJson()->assertPathCanonicalizing($path, $expect);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the exact given JSON.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertExactJson(array $data)\n    {\n        $this->decodeResponseJson()->assertExact($data);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the similar JSON as given.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertSimilarJson(array $data)\n    {\n        $this->decodeResponseJson()->assertSimilar($data);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response contains the given JSON fragments.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertJsonFragments(array $data)\n    {\n        foreach ($data as $fragment) {\n            $this->assertJsonFragment($fragment);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response contains the given JSON fragment.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertJsonFragment(array $data)\n    {\n        $this->decodeResponseJson()->assertFragment($data);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response does not contain the given JSON fragment.\n     *\n     * @param  array  $data\n     * @param  bool  $exact\n     * @return $this\n     */\n    public function assertJsonMissing(array $data, $exact = false)\n    {\n        $this->decodeResponseJson()->assertMissing($data, $exact);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response does not contain the exact JSON fragment.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function assertJsonMissingExact(array $data)\n    {\n        $this->decodeResponseJson()->assertMissingExact($data);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response does not contain the given path.\n     *\n     * @param  string  $path\n     * @return $this\n     */\n    public function assertJsonMissingPath(string $path)\n    {\n        $this->decodeResponseJson()->assertMissingPath($path);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has a given JSON structure.\n     *\n     * @param  array|null  $structure\n     * @param  array|null  $responseData\n     * @return $this\n     */\n    public function assertJsonStructure(?array $structure = null, ?array $responseData = null)\n    {\n        $this->decodeResponseJson()->assertStructure($structure, $responseData);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the exact JSON structure.\n     *\n     * @param  array|null  $structure\n     * @param  array|null  $responseData\n     * @return $this\n     */\n    public function assertExactJsonStructure(?array $structure = null, ?array $responseData = null)\n    {\n        $this->decodeResponseJson()->assertStructure($structure, $responseData, true);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response JSON has the expected count of items at the given key.\n     *\n     * @param  int  $count\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function assertJsonCount(int $count, $key = null)\n    {\n        $this->decodeResponseJson()->assertCount($count, $key);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the given JSON validation errors.\n     *\n     * @param  string|array  $errors\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertJsonValidationErrors($errors, $responseKey = 'errors')\n    {\n        $errors = Arr::wrap($errors);\n\n        PHPUnit::withResponse($this)->assertNotEmpty($errors, 'No validation errors were provided.');\n\n        $jsonErrors = Arr::get($this->json(), $responseKey) ?? [];\n\n        $errorMessage = $jsonErrors\n            ? 'Response has the following JSON validation errors:'.\n                    PHP_EOL.PHP_EOL.json_encode($jsonErrors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL\n            : 'Response does not have JSON validation errors.';\n\n        foreach ($errors as $key => $value) {\n            if (is_int($key)) {\n                $this->assertJsonValidationErrorFor($value, $responseKey);\n\n                continue;\n            }\n\n            $this->assertJsonValidationErrorFor($key, $responseKey);\n\n            foreach (Arr::wrap($value) as $expectedMessage) {\n                $errorMissing = true;\n\n                foreach (Arr::wrap($jsonErrors[$key]) as $jsonErrorMessage) {\n                    if (Str::contains($jsonErrorMessage, $expectedMessage)) {\n                        $errorMissing = false;\n\n                        break;\n                    }\n                }\n\n                if ($errorMissing) {\n                    PHPUnit::withResponse($this)->fail(\n                        \"Failed to find a validation error in the response for key and message: '$key' => '$expectedMessage'\".PHP_EOL.PHP_EOL.$errorMessage\n                    );\n                }\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the given JSON validation errors but does not have any other JSON validation errors.\n     *\n     * @param  string|array  $errors\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertOnlyJsonValidationErrors($errors, $responseKey = 'errors')\n    {\n        $this->assertJsonValidationErrors($errors, $responseKey);\n\n        $jsonErrors = Arr::get($this->json(), $responseKey) ?? [];\n\n        $expectedErrorKeys = (new Collection($errors))\n            ->map(fn ($value, $key) => is_int($key) ? $value : $key)\n            ->all();\n\n        $unexpectedErrorKeys = Arr::except($jsonErrors, $expectedErrorKeys);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            count($unexpectedErrorKeys) === 0,\n            'Response has unexpected validation errors: '.(new Collection($unexpectedErrorKeys))->keys()->map(fn ($key) => \"'{$key}'\")->join(', ')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert the response has any JSON validation errors for the given key.\n     *\n     * @param  string  $key\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertJsonValidationErrorFor($key, $responseKey = 'errors')\n    {\n        $jsonErrors = Arr::get($this->json(), $responseKey) ?? [];\n\n        $errorMessage = $jsonErrors\n            ? 'Response has the following JSON validation errors:'.\n            PHP_EOL.PHP_EOL.json_encode($jsonErrors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL\n            : 'Response does not have JSON validation errors.';\n\n        PHPUnit::withResponse($this)->assertArrayHasKey(\n            $key,\n            $jsonErrors,\n            \"Failed to find a validation error in the response for key: '{$key}'\".PHP_EOL.PHP_EOL.$errorMessage\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has no JSON validation errors for the given keys.\n     *\n     * @param  string|array|null  $keys\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertJsonMissingValidationErrors($keys = null, $responseKey = 'errors')\n    {\n        if ($this->getContent() === '') {\n            PHPUnit::withResponse($this)->assertTrue(true);\n\n            return $this;\n        }\n\n        $json = $this->json();\n\n        if (! Arr::has($json, $responseKey)) {\n            PHPUnit::withResponse($this)->assertTrue(true);\n\n            return $this;\n        }\n\n        $errors = Arr::get($json, $responseKey, []);\n\n        if (is_null($keys) && count($errors) > 0) {\n            PHPUnit::withResponse($this)->fail(\n                'Response has unexpected validation errors: '.PHP_EOL.PHP_EOL.\n                json_encode($errors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)\n            );\n        }\n\n        foreach (Arr::wrap($keys) as $key) {\n            PHPUnit::withResponse($this)->assertFalse(\n                isset($errors[$key]),\n                \"Found unexpected validation error for key: '{$key}'\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given key is a JSON array.\n     *\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function assertJsonIsArray($key = null)\n    {\n        $data = $this->json($key);\n\n        $encodedData = json_encode($data);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            is_array($data)\n            && str_starts_with($encodedData, '[')\n            && str_ends_with($encodedData, ']')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given key is a JSON object.\n     *\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function assertJsonIsObject($key = null)\n    {\n        $data = $this->json($key);\n\n        $encodedData = json_encode($data);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            is_array($data)\n            && str_starts_with($encodedData, '{')\n            && str_ends_with($encodedData, '}')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Validate the decoded response JSON.\n     *\n     * @return \\Illuminate\\Testing\\AssertableJsonString\n     *\n     * @throws \\Throwable\n     */\n    public function decodeResponseJson()\n    {\n        if ($this->baseResponse instanceof StreamedResponse ||\n            $this->baseResponse instanceof StreamedJsonResponse) {\n            $testJson = new AssertableJsonString($this->streamedContent());\n        } else {\n            $testJson = new AssertableJsonString($this->getContent());\n        }\n\n        $decodedResponse = $testJson->json();\n\n        if (is_null($decodedResponse) || $decodedResponse === false) {\n            if ($this->exception) {\n                throw $this->exception;\n            } else {\n                PHPUnit::withResponse($this)->fail('Invalid JSON was returned from the route.');\n            }\n        }\n\n        return $testJson;\n    }\n\n    /**\n     * Return the decoded response JSON.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    public function json($key = null)\n    {\n        return $this->decodeResponseJson()->json($key);\n    }\n\n    /**\n     * Get the decoded JSON body of the response as a collection.\n     *\n     * @param  string|null  $key\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function collect($key = null)\n    {\n        return new Collection($this->json($key));\n    }\n\n    /**\n     * Assert that the response view equals the given value.\n     *\n     * @param  string  $value\n     * @return $this\n     */\n    public function assertViewIs($value)\n    {\n        $this->ensureResponseHasView();\n\n        PHPUnit::withResponse($this)->assertEquals($value, $this->original->name());\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response view has a given piece of bound data.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertViewHas($key, $value = null)\n    {\n        if (is_array($key)) {\n            return $this->assertViewHasAll($key);\n        }\n\n        $this->ensureResponseHasView();\n\n        $actual = Arr::get($this->original->gatherData(), $key);\n\n        if (is_null($value)) {\n            PHPUnit::withResponse($this)->assertTrue(Arr::has($this->original->gatherData(), $key), \"Failed asserting that the data contains the key [{$key}].\");\n        } elseif ($value instanceof Closure) {\n            PHPUnit::withResponse($this)->assertTrue($value($actual), \"Failed asserting that the value at [{$key}] fulfills the expectations defined by the closure.\");\n        } elseif ($value instanceof Model) {\n            PHPUnit::withResponse($this)->assertTrue($value->is($actual), \"Failed asserting that the model at [{$key}] matches the given model.\");\n        } elseif ($value instanceof EloquentCollection) {\n            PHPUnit::withResponse($this)->assertInstanceOf(EloquentCollection::class, $actual);\n            PHPUnit::withResponse($this)->assertSameSize($value, $actual);\n\n            $value->each(fn ($item, $index) => PHPUnit::withResponse($this)->assertTrue($actual->get($index)->is($item), \"Failed asserting that the collection at [{$key}.[{$index}]]' matches the given collection.\"));\n        } else {\n            PHPUnit::withResponse($this)->assertEquals($value, $actual, \"Failed asserting that [{$key}] matches the expected value.\");\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response view has a given list of bound data.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function assertViewHasAll(array $bindings)\n    {\n        foreach ($bindings as $key => $value) {\n            if (is_int($key)) {\n                $this->assertViewHas($value);\n            } else {\n                $this->assertViewHas($key, $value);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get a piece of data from the original view.\n     *\n     * @param  string|null  $key\n     * @return mixed\n     */\n    public function viewData($key = null)\n    {\n        $this->ensureResponseHasView();\n\n        $data = $this->original->gatherData();\n\n        if (is_null($key)) {\n            return $data;\n        }\n\n        return $data[$key];\n    }\n\n    /**\n     * Assert that the response view is missing a piece of bound data.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function assertViewMissing($key)\n    {\n        $this->ensureResponseHasView();\n\n        PHPUnit::withResponse($this)->assertFalse(Arr::has($this->original->gatherData(), $key));\n\n        return $this;\n    }\n\n    /**\n     * Ensure that the response has a view as its original content.\n     *\n     * @return $this\n     */\n    protected function ensureResponseHasView()\n    {\n        if (! $this->responseHasView()) {\n            return PHPUnit::withResponse($this)->fail('The response is not a view.');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the original response is a view.\n     *\n     * @return bool\n     */\n    protected function responseHasView()\n    {\n        return isset($this->original) && $this->original instanceof View;\n    }\n\n    /**\n     * Assert that the given keys do not have validation errors.\n     *\n     * @param  string|array|null  $keys\n     * @param  string  $errorBag\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertValid($keys = null, $errorBag = 'default', $responseKey = 'errors')\n    {\n        if ($this->baseResponse->headers->get('Content-Type') === 'application/json') {\n            return $this->assertJsonMissingValidationErrors($keys, $responseKey);\n        }\n\n        if ($this->session()->get('errors')) {\n            $errors = $this->session()->get('errors')->getBag($errorBag)->getMessages();\n        } else {\n            $errors = [];\n        }\n\n        if (empty($errors)) {\n            PHPUnit::withResponse($this)->assertTrue(true);\n\n            return $this;\n        }\n\n        if (is_null($keys) && count($errors) > 0) {\n            PHPUnit::withResponse($this)->fail(\n                'Response has unexpected validation errors: '.PHP_EOL.PHP_EOL.\n                json_encode($errors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)\n            );\n        }\n\n        foreach (Arr::wrap($keys) as $key) {\n            PHPUnit::withResponse($this)->assertFalse(\n                isset($errors[$key]),\n                \"Found unexpected validation error for key: '{$key}'\"\n            );\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the given validation errors.\n     *\n     * @param  string|array|null  $errors\n     * @param  string  $errorBag\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertInvalid($errors = null,\n                                  $errorBag = 'default',\n                                  $responseKey = 'errors')\n    {\n        if ($this->baseResponse->headers->get('Content-Type') === 'application/json') {\n            return $this->assertJsonValidationErrors($errors, $responseKey);\n        }\n\n        $this->assertSessionHas('errors');\n\n        $sessionErrors = $this->session()->get('errors')->getBag($errorBag)->getMessages();\n\n        $errorMessage = $sessionErrors\n            ? 'Response has the following validation errors in the session:'.\n                    PHP_EOL.PHP_EOL.json_encode($sessionErrors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL\n            : 'Response does not have validation errors in the session.';\n\n        foreach (Arr::wrap($errors) as $key => $value) {\n            PHPUnit::withResponse($this)->assertArrayHasKey(\n                $resolvedKey = (is_int($key)) ? $value : $key,\n                $sessionErrors,\n                \"Failed to find a validation error in session for key: '{$resolvedKey}'\".PHP_EOL.PHP_EOL.$errorMessage\n            );\n\n            foreach (Arr::wrap($value) as $message) {\n                if (! is_int($key)) {\n                    $hasError = false;\n\n                    foreach (Arr::wrap($sessionErrors[$key]) as $sessionErrorMessage) {\n                        if (Str::contains($sessionErrorMessage, $message)) {\n                            $hasError = true;\n\n                            break;\n                        }\n                    }\n\n                    if (! $hasError) {\n                        PHPUnit::withResponse($this)->fail(\n                            \"Failed to find a validation error for key and message: '$key' => '$message'\".PHP_EOL.PHP_EOL.$errorMessage\n                        );\n                    }\n                }\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response has the given validation errors but does not have any other validation errors.\n     *\n     * @param  string|array|null  $errors\n     * @param  string  $errorBag\n     * @param  string  $responseKey\n     * @return $this\n     */\n    public function assertOnlyInvalid($errors = null, $errorBag = 'default', $responseKey = 'errors')\n    {\n        if ($this->baseResponse->headers->get('Content-Type') === 'application/json') {\n            return $this->assertOnlyJsonValidationErrors($errors, $responseKey);\n        }\n\n        $this->assertSessionHas('errors');\n\n        $sessionErrors = $this->session()->get('errors')\n            ->getBag($errorBag)\n            ->getMessages();\n\n        $expectedErrorKeys = (new Collection($errors))\n            ->map(fn ($value, $key) => is_int($key) ? $value : $key)\n            ->all();\n\n        $unexpectedErrorKeys = Arr::except($sessionErrors, $expectedErrorKeys);\n\n        PHPUnit::withResponse($this)->assertTrue(\n            count($unexpectedErrorKeys) === 0,\n            'Response has unexpected validation errors: '.(new Collection($unexpectedErrorKeys))->keys()->map(fn ($key) => \"'{$key}'\")->join(', ')\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has a given value.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertSessionHas($key, $value = null)\n    {\n        if (is_array($key)) {\n            return $this->assertSessionHasAll($key);\n        }\n\n        if (is_null($value)) {\n            PHPUnit::withResponse($this)->assertTrue(\n                $this->session()->has($key),\n                \"Session is missing expected key [{$key}].\"\n            );\n        } elseif ($value instanceof Closure) {\n            PHPUnit::withResponse($this)->assertTrue($value($this->session()->get($key)));\n        } else {\n            PHPUnit::withResponse($this)->assertEquals($value, $this->session()->get($key));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has a given list of values.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function assertSessionHasAll(array $bindings)\n    {\n        $actual = [];\n        $expected = [];\n\n        foreach ($bindings as $key => $value) {\n            if (is_int($key)) {\n                $this->assertSessionHas($value);\n            } elseif ($value instanceof Closure) {\n                $this->assertSessionHas($key, $value);\n            } else {\n                $expected[$key] = $value;\n                $actual[$key] = $this->session()->get($key);\n            }\n        }\n\n        if (! empty($expected)) {\n            PHPUnit::withResponse($this)->assertEquals($expected, $actual);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has a given value in the flashed input array.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertSessionHasInput($key, $value = null)\n    {\n        if (is_array($key)) {\n            foreach ($key as $k => $v) {\n                if (is_int($k)) {\n                    $this->assertSessionHasInput($v);\n                } else {\n                    $this->assertSessionHasInput($k, $v);\n                }\n            }\n\n            return $this;\n        }\n\n        if (is_null($value)) {\n            PHPUnit::withResponse($this)->assertTrue(\n                $this->session()->hasOldInput($key),\n                \"Session is missing expected key [{$key}].\"\n            );\n        } elseif ($value instanceof Closure) {\n            PHPUnit::withResponse($this)->assertTrue($value($this->session()->getOldInput($key)));\n        } else {\n            PHPUnit::withResponse($this)->assertEquals($value, $this->session()->getOldInput($key));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has the given errors.\n     *\n     * @param  string|array  $keys\n     * @param  mixed  $format\n     * @param  string  $errorBag\n     * @return $this\n     */\n    public function assertSessionHasErrors($keys = [], $format = null, $errorBag = 'default')\n    {\n        $this->assertSessionHas('errors');\n\n        $keys = (array) $keys;\n\n        $errors = $this->session()->get('errors')->getBag($errorBag);\n\n        foreach ($keys as $key => $value) {\n            if (is_int($key)) {\n                PHPUnit::withResponse($this)->assertTrue($errors->has($value), \"Session missing error: $value\");\n            } else {\n                PHPUnit::withResponse($this)->assertContains(is_bool($value) ? (string) $value : $value, $errors->get($key, $format));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session is missing the given errors.\n     *\n     * @param  string|array  $keys\n     * @param  string|null  $format\n     * @param  string  $errorBag\n     * @return $this\n     */\n    public function assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default')\n    {\n        $keys = (array) $keys;\n\n        if (empty($keys)) {\n            return $this->assertSessionHasNoErrors();\n        }\n\n        if (is_null($this->session()->get('errors'))) {\n            PHPUnit::withResponse($this)->assertTrue(true);\n\n            return $this;\n        }\n\n        $errors = $this->session()->get('errors')->getBag($errorBag);\n\n        foreach ($keys as $key => $value) {\n            if (is_int($key)) {\n                PHPUnit::withResponse($this)->assertFalse($errors->has($value), \"Session has unexpected error: $value\");\n            } else {\n                PHPUnit::withResponse($this)->assertNotContains($value, $errors->get($key, $format));\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has no errors.\n     *\n     * @return $this\n     */\n    public function assertSessionHasNoErrors()\n    {\n        $hasErrors = $this->session()->has('errors');\n\n        PHPUnit::withResponse($this)->assertFalse(\n            $hasErrors,\n            'Session has unexpected errors: '.PHP_EOL.PHP_EOL.\n            json_encode((function () use ($hasErrors) {\n                $errors = [];\n\n                $sessionErrors = $this->session()->get('errors');\n\n                if ($hasErrors && is_a($sessionErrors, ViewErrorBag::class)) {\n                    foreach ($sessionErrors->getBags() as $bag => $messages) {\n                        if (is_a($messages, MessageBag::class)) {\n                            $errors[$bag] = $messages->all();\n                        }\n                    }\n                }\n\n                return $errors;\n            })(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),\n        );\n\n        return $this;\n    }\n\n    /**\n     * Assert that the session has the given errors.\n     *\n     * @param  string  $errorBag\n     * @param  string|array  $keys\n     * @param  mixed  $format\n     * @return $this\n     */\n    public function assertSessionHasErrorsIn($errorBag, $keys = [], $format = null)\n    {\n        return $this->assertSessionHasErrors($keys, $format, $errorBag);\n    }\n\n    /**\n     * Assert that the session does not have a given key.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertSessionMissing($key, $value = null)\n    {\n        if (is_array($key)) {\n            foreach ($key as $value) {\n                $this->assertSessionMissing($value);\n            }\n\n            return $this;\n        }\n\n        if (is_null($value)) {\n            PHPUnit::withResponse($this)->assertFalse(\n                $this->session()->has($key),\n                \"Session has unexpected key [{$key}].\"\n            );\n        } elseif ($value instanceof Closure) {\n            PHPUnit::withResponse($this)->assertFalse($value($this->session()->get($key)));\n        } else {\n            PHPUnit::withResponse($this)->assertNotEquals($value, $this->session()->get($key));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the current session store.\n     *\n     * @return \\Illuminate\\Session\\Store\n     */\n    protected function session()\n    {\n        $session = app('session.store');\n\n        if (! $session->isStarted()) {\n            $session->start();\n        }\n\n        return $session;\n    }\n\n    /**\n     * Dump the headers from the response and end the script.\n     *\n     * @return never\n     */\n    public function ddHeaders()\n    {\n        $this->dumpHeaders();\n\n        exit(1);\n    }\n\n    /**\n     * Dump the body of the response and end the script.\n     *\n     * @param  string|null  $key\n     * @return never\n     */\n    public function ddBody($key = null)\n    {\n        $content = $this->content();\n\n        if (json_validate($content)) {\n            $this->ddJson($key);\n        }\n\n        dd($content);\n    }\n\n    /**\n     * Dump the JSON payload from the response and end the script.\n     *\n     * @param  string|null  $key\n     * @return never\n     */\n    public function ddJson($key = null)\n    {\n        dd($this->json($key));\n    }\n\n    /**\n     * Dump the session from the response and end the script.\n     *\n     * @param  string|array  $keys\n     * @return never\n     */\n    public function ddSession($keys = [])\n    {\n        $this->dumpSession($keys);\n\n        exit(1);\n    }\n\n    /**\n     * Dump the content from the response.\n     *\n     * @param  string|null  $key\n     * @return $this\n     */\n    public function dump($key = null)\n    {\n        $content = $this->getContent();\n\n        $json = json_decode($content);\n\n        if (json_last_error() === JSON_ERROR_NONE) {\n            $content = $json;\n        }\n\n        if (! is_null($key)) {\n            dump(data_get($content, $key));\n        } else {\n            dump($content);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Dump the headers from the response.\n     *\n     * @return $this\n     */\n    public function dumpHeaders()\n    {\n        dump($this->headers->all());\n\n        return $this;\n    }\n\n    /**\n     * Dump the session from the response.\n     *\n     * @param  string|array  $keys\n     * @return $this\n     */\n    public function dumpSession($keys = [])\n    {\n        $keys = (array) $keys;\n\n        if (empty($keys)) {\n            dump($this->session()->all());\n        } else {\n            dump($this->session()->only($keys));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the streamed content from the response.\n     *\n     * @return string\n     */\n    public function streamedContent()\n    {\n        if (! is_null($this->streamedContent)) {\n            return $this->streamedContent;\n        }\n\n        if (! $this->baseResponse instanceof StreamedResponse\n            && ! $this->baseResponse instanceof BinaryFileResponse) {\n            PHPUnit::withResponse($this)->fail('The response is not a streamed response.');\n        }\n\n        ob_start(function (string $buffer): string {\n            $this->streamedContent .= $buffer;\n\n            return '';\n        });\n\n        $this->sendContent();\n\n        ob_end_clean();\n\n        return $this->streamedContent;\n    }\n\n    /**\n     * Set the previous exceptions on the response.\n     *\n     * @param  \\Illuminate\\Support\\Collection  $exceptions\n     * @return $this\n     */\n    public function withExceptions(Collection $exceptions)\n    {\n        $this->exceptions = $exceptions;\n\n        return $this;\n    }\n\n    /**\n     * Dynamically access base response parameters.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->baseResponse->{$key};\n    }\n\n    /**\n     * Proxy isset() checks to the underlying base response.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return isset($this->baseResponse->{$key});\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return $this->responseHasView()\n            ? isset($this->original->gatherData()[$offset])\n            : isset($this->json()[$offset]);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->responseHasView()\n            ? $this->viewData($offset)\n            : $this->json()[$offset];\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetSet($offset, $value): void\n    {\n        throw new LogicException('Response data may not be mutated using array access.');\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     *\n     * @throws \\LogicException\n     */\n    public function offsetUnset($offset): void\n    {\n        throw new LogicException('Response data may not be mutated using array access.');\n    }\n\n    /**\n     * Handle dynamic calls into macros or pass missing methods to the base response.\n     *\n     * @param  string  $method\n     * @param  array  $args\n     * @return mixed\n     */\n    public function __call($method, $args)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $args);\n        }\n\n        return $this->baseResponse->{$method}(...$args);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/TestResponseAssert.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Support\\Arr;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse ReflectionProperty;\n\n/**\n * @internal\n *\n * @mixin Assert\n */\nclass TestResponseAssert\n{\n    /**\n     * Create a new TestResponse assertion helper.\n     */\n    private function __construct(protected TestResponse $response)\n    {\n        //\n    }\n\n    /**\n     * Create a new TestResponse assertion helper.\n     */\n    public static function withResponse(TestResponse $response): static\n    {\n        return new static($response);\n    }\n\n    /**\n     * Pass method calls to the Assert class and decorate the exception message.\n     *\n     * @param  string  $name\n     * @param  array  $arguments\n     * @return void\n     *\n     * @throws \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    public function __call($name, $arguments)\n    {\n        try {\n            Assert::$name(...$arguments);\n        } catch (ExpectationFailedException $e) {\n            throw $this->injectResponseContext($e);\n        }\n    }\n\n    /**\n     * Pass static method calls to the Assert class.\n     *\n     * @param  string  $name\n     * @param  array  $arguments\n     * @return void\n     *\n     * @throws \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    public static function __callStatic($name, $arguments)\n    {\n        Assert::$name(...$arguments);\n    }\n\n    /**\n     * Inject additional context from the response into the exception message.\n     *\n     * @param  \\PHPUnit\\Framework\\ExpectationFailedException  $exception\n     * @return \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    protected function injectResponseContext($exception)\n    {\n        if ($lastException = $this->response->exceptions->last()) {\n            return $this->appendExceptionToException($lastException, $exception);\n        }\n\n        if ($this->response->baseResponse instanceof RedirectResponse) {\n            $session = $this->response->baseResponse->getSession();\n\n            if (! is_null($session) && $session->has('errors')) {\n                return $this->appendErrorsToException($session->get('errors')->all(), $exception);\n            }\n        }\n\n        if ($this->response->baseResponse->headers->get('Content-Type') === 'application/json') {\n            $testJson = new AssertableJsonString($this->response->getContent());\n\n            if (isset($testJson['errors'])) {\n                return $this->appendErrorsToException($testJson->json(), $exception, true);\n            }\n        }\n\n        return $exception;\n    }\n\n    /**\n     * Append an exception to the message of another exception.\n     *\n     * @param  \\Throwable  $exceptionToAppend\n     * @param  \\PHPUnit\\Framework\\ExpectationFailedException  $exception\n     * @return \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    protected function appendExceptionToException($exceptionToAppend, $exception)\n    {\n        $exceptionMessage = is_string($exceptionToAppend) ? $exceptionToAppend : $exceptionToAppend->getMessage();\n\n        $exceptionToAppend = (string) $exceptionToAppend;\n\n        $message = <<<\"EOF\"\n            The following exception occurred during the last request:\n\n            $exceptionToAppend\n\n            ----------------------------------------------------------------------------------\n\n            $exceptionMessage\n            EOF;\n\n        return $this->appendMessageToException($message, $exception);\n    }\n\n    /**\n     * Append errors to an exception message.\n     *\n     * @param  array  $errors\n     * @param  \\PHPUnit\\Framework\\ExpectationFailedException  $exception\n     * @param  bool  $json\n     * @return \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    protected function appendErrorsToException($errors, $exception, $json = false)\n    {\n        $errors = $json\n            ? json_encode($errors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)\n            : implode(PHP_EOL, Arr::flatten($errors));\n\n        // JSON error messages may already contain the errors, so we shouldn't duplicate them...\n        if (str_contains($exception->getMessage(), $errors)) {\n            return $exception;\n        }\n\n        $message = <<<\"EOF\"\n            The following errors occurred during the last request:\n\n            $errors\n            EOF;\n\n        return $this->appendMessageToException($message, $exception);\n    }\n\n    /**\n     * Append a message to an exception.\n     *\n     * @param  string  $message\n     * @param  \\PHPUnit\\Framework\\ExpectationFailedException  $exception\n     * @return \\PHPUnit\\Framework\\ExpectationFailedException\n     */\n    protected function appendMessageToException($message, $exception)\n    {\n        $property = new ReflectionProperty($exception, 'message');\n\n        $property->setValue(\n            $exception,\n            $exception->getMessage().PHP_EOL.PHP_EOL.$message.PHP_EOL\n        );\n\n        return $exception;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/TestView.php",
    "content": "<?php\n\nnamespace Illuminate\\Testing;\n\nuse Closure;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Testing\\Assert as PHPUnit;\nuse Illuminate\\Testing\\Constraints\\SeeInHtml;\nuse Illuminate\\Testing\\Constraints\\SeeInOrder;\nuse Illuminate\\View\\View;\nuse Stringable;\n\nclass TestView implements Stringable\n{\n    use Macroable;\n\n    /**\n     * The original view.\n     *\n     * @var \\Illuminate\\View\\View\n     */\n    protected $view;\n\n    /**\n     * The rendered view contents.\n     *\n     * @var string\n     */\n    protected $rendered;\n\n    /**\n     * Create a new test view instance.\n     *\n     * @param  \\Illuminate\\View\\View  $view\n     */\n    public function __construct(View $view)\n    {\n        $this->view = $view;\n        $this->rendered = $view->render();\n    }\n\n    /**\n     * Assert that the response view has a given piece of bound data.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function assertViewHas($key, $value = null)\n    {\n        if (is_array($key)) {\n            return $this->assertViewHasAll($key);\n        }\n\n        if (is_null($value)) {\n            PHPUnit::assertTrue(Arr::has($this->view->gatherData(), $key));\n        } elseif ($value instanceof Closure) {\n            PHPUnit::assertTrue($value(Arr::get($this->view->gatherData(), $key)));\n        } elseif ($value instanceof Model) {\n            PHPUnit::assertTrue($value->is(Arr::get($this->view->gatherData(), $key)));\n        } elseif ($value instanceof EloquentCollection) {\n            $actual = Arr::get($this->view->gatherData(), $key);\n\n            PHPUnit::assertInstanceOf(EloquentCollection::class, $actual);\n            PHPUnit::assertSameSize($value, $actual);\n\n            $value->each(fn ($item, $index) => PHPUnit::assertTrue($actual->get($index)->is($item)));\n        } else {\n            PHPUnit::assertEquals($value, Arr::get($this->view->gatherData(), $key));\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response view has a given list of bound data.\n     *\n     * @param  array  $bindings\n     * @return $this\n     */\n    public function assertViewHasAll(array $bindings)\n    {\n        foreach ($bindings as $key => $value) {\n            if (is_int($key)) {\n                $this->assertViewHas($value);\n            } else {\n                $this->assertViewHas($key, $value);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the response view is missing a piece of bound data.\n     *\n     * @param  string  $key\n     * @return $this\n     */\n    public function assertViewMissing($key)\n    {\n        PHPUnit::assertFalse(Arr::has($this->view->gatherData(), $key));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the view's rendered content is empty.\n     *\n     * @return $this\n     */\n    public function assertViewEmpty()\n    {\n        PHPUnit::assertEmpty($this->rendered);\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the view.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::assertStringContainsString((string) $value, $this->rendered);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are contained within the view.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertSeeHtml($value)\n    {\n        return $this->assertSee($value, false);\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the view.\n     *\n     * @param  list<string>  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::assertThat($values, new SeeInOrder($this->rendered));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML strings are contained in order within the view.\n     *\n     * @param  list<string>  $values\n     * @return $this\n     */\n    public function assertSeeHtmlInOrder(array $values)\n    {\n        return $this->assertSeeInOrder($values, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are contained within the view text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        PHPUnit::assertThat($values, new SeeInHtml($this->rendered));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given strings are contained in order within the view text.\n     *\n     * @param  list<string>  $values\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertSeeTextInOrder(array $values, $escape = true)\n    {\n        $values = $escape ? array_map(e(...), $values) : $values;\n\n        PHPUnit::assertThat($values, new SeeInHtml($this->rendered, true));\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the view.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSee($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        foreach ($values as $value) {\n            PHPUnit::assertStringNotContainsString((string) $value, $this->rendered);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Assert that the given HTML string or array of HTML strings are not contained within the view.\n     *\n     * @param  string|list<string>  $value\n     * @return $this\n     */\n    public function assertDontSeeHtml($value)\n    {\n        return $this->assertDontSee($value, false);\n    }\n\n    /**\n     * Assert that the given string or array of strings are not contained within the view text.\n     *\n     * @param  string|list<string>  $value\n     * @param  bool  $escape\n     * @return $this\n     */\n    public function assertDontSeeText($value, $escape = true)\n    {\n        $value = Arr::wrap($value);\n\n        $values = $escape ? array_map(e(...), $value) : $value;\n\n        PHPUnit::assertThat($values, new SeeInHtml($this->rendered));\n\n        return $this;\n    }\n\n    /**\n     * Get the string contents of the rendered view.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->rendered;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Testing/composer.json",
    "content": "{\n    \"name\": \"illuminate/testing\",\n    \"description\": \"The Illuminate Testing package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-mbstring\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"suggest\": {\n        \"brianium/paratest\": \"Required to run tests in parallel (^7.0 || ^8.0).\",\n        \"illuminate/console\": \"Required to assert console commands (^13.0).\",\n        \"illuminate/database\": \"Required to assert databases (^13.0).\",\n        \"illuminate/http\": \"Required to assert responses (^13.0).\",\n        \"mockery/mockery\": \"Required to use mocking (^1.6).\",\n        \"phpunit/phpunit\": \"Required to use assertions and run tests (^11.5.50 || ^12.5.8).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Testing\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Translation/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Translation/ArrayLoader.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Illuminate\\Contracts\\Translation\\Loader;\n\nclass ArrayLoader implements Loader\n{\n    /**\n     * All of the translation messages.\n     *\n     * @var array\n     */\n    protected $messages = [];\n\n    /**\n     * Load the messages for the given locale.\n     *\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  string|null  $namespace\n     * @return array\n     */\n    public function load($locale, $group, $namespace = null)\n    {\n        $namespace = $namespace ?: '*';\n\n        return $this->messages[$namespace][$locale][$group] ?? [];\n    }\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string  $hint\n     * @return void\n     */\n    public function addNamespace($namespace, $hint)\n    {\n        //\n    }\n\n    /**\n     * Add a new JSON path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addJsonPath($path)\n    {\n        //\n    }\n\n    /**\n     * Add messages to the loader.\n     *\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  array  $messages\n     * @param  string|null  $namespace\n     * @return $this\n     */\n    public function addMessages($locale, $group, array $messages, $namespace = null)\n    {\n        $namespace = $namespace ?: '*';\n\n        $this->messages[$namespace][$locale][$group] = $messages;\n\n        return $this;\n    }\n\n    /**\n     * Get an array of all the registered namespaces.\n     *\n     * @return array\n     */\n    public function namespaces()\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/CreatesPotentiallyTranslatedStrings.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\ntrait CreatesPotentiallyTranslatedStrings\n{\n    /**\n     * Create a pending potentially translated string.\n     *\n     * @param  string  $attribute\n     * @param  string|null  $message\n     * @return \\Illuminate\\Translation\\PotentiallyTranslatedString\n     */\n    protected function pendingPotentiallyTranslatedString($attribute, $message)\n    {\n        $destructor = $message === null\n            ? fn ($message) => $this->messages[] = $message\n            : fn ($message) => $this->messages[$attribute] = $message;\n\n        return new class($message ?? $attribute, $this->validator->getTranslator(), $destructor) extends PotentiallyTranslatedString\n        {\n            /**\n             * The callback to call when the object destructs.\n             *\n             * @var \\Closure\n             */\n            protected $destructor;\n\n            /**\n             * Create a new pending potentially translated string.\n             *\n             * @param  string  $message\n             * @param  \\Illuminate\\Contracts\\Translation\\Translator  $translator\n             * @param  \\Closure  $destructor\n             */\n            public function __construct($message, $translator, $destructor)\n            {\n                parent::__construct($message, $translator);\n\n                $this->destructor = $destructor;\n            }\n\n            /**\n             * Handle the object's destruction.\n             *\n             * @return void\n             */\n            public function __destruct()\n            {\n                ($this->destructor)($this->toString());\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/FileLoader.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Illuminate\\Contracts\\Translation\\Loader;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse RuntimeException;\n\nclass FileLoader implements Loader\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The default paths for the loader.\n     *\n     * @var array\n     */\n    protected $paths;\n\n    /**\n     * All of the registered paths to JSON translation files.\n     *\n     * @var array\n     */\n    protected $jsonPaths = [];\n\n    /**\n     * All of the namespace hints.\n     *\n     * @var array\n     */\n    protected $hints = [];\n\n    /**\n     * Create a new file loader instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  array|string  $path\n     */\n    public function __construct(Filesystem $files, array|string $path)\n    {\n        $this->files = $files;\n\n        $this->paths = is_string($path) ? [$path] : $path;\n    }\n\n    /**\n     * Load the messages for the given locale.\n     *\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  string|null  $namespace\n     * @return array\n     */\n    public function load($locale, $group, $namespace = null)\n    {\n        if ($group === '*' && $namespace === '*') {\n            return $this->loadJsonPaths($locale);\n        }\n\n        if (is_null($namespace) || $namespace === '*') {\n            return $this->loadPaths($this->paths, $locale, $group);\n        }\n\n        return $this->loadNamespaced($locale, $group, $namespace);\n    }\n\n    /**\n     * Load a namespaced translation group.\n     *\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  string  $namespace\n     * @return array\n     */\n    protected function loadNamespaced($locale, $group, $namespace)\n    {\n        if (isset($this->hints[$namespace])) {\n            $lines = $this->loadPaths([$this->hints[$namespace]], $locale, $group);\n\n            return $this->loadNamespaceOverrides($lines, $locale, $group, $namespace);\n        }\n\n        return [];\n    }\n\n    /**\n     * Load a local namespaced translation group for overrides.\n     *\n     * @param  array  $lines\n     * @param  string  $locale\n     * @param  string  $group\n     * @param  string  $namespace\n     * @return array\n     */\n    protected function loadNamespaceOverrides(array $lines, $locale, $group, $namespace)\n    {\n        return (new Collection($this->paths))\n            ->reduce(function ($output, $path) use ($locale, $group, $namespace) {\n                $file = \"{$path}/vendor/{$namespace}/{$locale}/{$group}.php\";\n\n                if ($this->files->exists($file)) {\n                    $output = array_replace_recursive($output, $this->files->getRequire($file));\n                }\n\n                return $output;\n            }, $lines);\n    }\n\n    /**\n     * Load a locale from a given path.\n     *\n     * @param  array  $paths\n     * @param  string  $locale\n     * @param  string  $group\n     * @return array\n     */\n    protected function loadPaths(array $paths, $locale, $group)\n    {\n        return (new Collection($paths))\n            ->reduce(function ($output, $path) use ($locale, $group) {\n                if ($this->files->exists($full = \"{$path}/{$locale}/{$group}.php\")) {\n                    $output = array_replace_recursive($output, $this->files->getRequire($full));\n                }\n\n                return $output;\n            }, []);\n    }\n\n    /**\n     * Load a locale from the given JSON file path.\n     *\n     * @param  string  $locale\n     * @return array\n     *\n     * @throws \\RuntimeException\n     */\n    protected function loadJsonPaths($locale)\n    {\n        return (new Collection(array_merge($this->jsonPaths, $this->paths)))\n            ->reduce(function ($output, $path) use ($locale) {\n                if ($this->files->exists($full = \"{$path}/{$locale}.json\")) {\n                    $decoded = json_decode($this->files->get($full), true);\n\n                    if (is_null($decoded) || json_last_error() !== JSON_ERROR_NONE) {\n                        throw new RuntimeException(\"Translation file [{$full}] contains an invalid JSON structure.\");\n                    }\n\n                    $output = array_merge($output, $decoded);\n                }\n\n                return $output;\n            }, []);\n    }\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string  $hint\n     * @return void\n     */\n    public function addNamespace($namespace, $hint)\n    {\n        $this->hints[$namespace] = $hint;\n    }\n\n    /**\n     * Get an array of all the registered namespaces.\n     *\n     * @return array\n     */\n    public function namespaces()\n    {\n        return $this->hints;\n    }\n\n    /**\n     * Add a new path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addPath($path)\n    {\n        $this->paths[] = $path;\n    }\n\n    /**\n     * Add a new JSON path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addJsonPath($path)\n    {\n        $this->jsonPaths[] = $path;\n    }\n\n    /**\n     * Get an array of all the registered paths to translation files.\n     *\n     * @return array\n     */\n    public function paths()\n    {\n        return $this->paths;\n    }\n\n    /**\n     * Get an array of all the registered paths to JSON translation files.\n     *\n     * @return array\n     */\n    public function jsonPaths()\n    {\n        return $this->jsonPaths;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Translation/MessageSelector.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Illuminate\\Support\\Collection;\n\nclass MessageSelector\n{\n    /**\n     * Select a proper translation string based on the given number.\n     *\n     * @param  string  $line\n     * @param  int|float  $number\n     * @param  string  $locale\n     * @return mixed\n     */\n    public function choose($line, $number, $locale)\n    {\n        $segments = explode('|', $line);\n\n        if (($value = $this->extract($segments, $number)) !== null) {\n            return trim($value);\n        }\n\n        $segments = $this->stripConditions($segments);\n\n        $pluralIndex = $this->getPluralIndex($locale, $number);\n\n        if (count($segments) === 1 || ! isset($segments[$pluralIndex])) {\n            return $segments[0];\n        }\n\n        return $segments[$pluralIndex];\n    }\n\n    /**\n     * Extract a translation string using inline conditions.\n     *\n     * @param  array  $segments\n     * @param  int|float  $number\n     * @return mixed\n     */\n    private function extract($segments, $number)\n    {\n        foreach ($segments as $part) {\n            if (! is_null($line = $this->extractFromString($part, $number))) {\n                return $line;\n            }\n        }\n    }\n\n    /**\n     * Get the translation string if the condition matches.\n     *\n     * @param  string  $part\n     * @param  int  $number\n     * @return mixed\n     */\n    private function extractFromString($part, $number)\n    {\n        preg_match('/^[\\{\\[]([-?\\d|*,\\.*]*)[\\}\\]](.*)/s', $part, $matches);\n\n        if (count($matches) !== 3) {\n            return null;\n        }\n\n        $condition = $matches[1];\n\n        $value = $matches[2];\n\n        if (str_contains($condition, ',')) {\n            [$from, $to] = explode(',', $condition, 2);\n\n            if ($to === '*' && $number >= $from) {\n                return $value;\n            } elseif ($from === '*' && $number <= $to) {\n                return $value;\n            } elseif ($number >= $from && $number <= $to) {\n                return $value;\n            }\n        }\n\n        return $condition == $number ? $value : null;\n    }\n\n    /**\n     * Strip the inline conditions from each segment, just leaving the text.\n     *\n     * @param  array  $segments\n     * @return array\n     */\n    private function stripConditions($segments)\n    {\n        return (new Collection($segments))\n            ->map(fn ($part) => preg_replace('/^[\\{\\[][-?\\d|*,\\.*]*[\\}\\]]/', '', $part))\n            ->all();\n    }\n\n    /**\n     * Get the index to use for pluralization.\n     *\n     * The plural rules are derived from code of the Zend Framework (2010-09-25), which\n     * is subject to the new BSD license (https://framework.zend.com/license)\n     * Copyright (c) 2005-2010 - Zend Technologies USA Inc. (http://www.zend.com)\n     *\n     * @param  string  $locale\n     * @param  int|float  $number\n     * @return int\n     */\n    public function getPluralIndex($locale, $number)\n    {\n        switch ($locale) {\n            case 'az':\n            case 'az_AZ':\n            case 'bo':\n            case 'bo_CN':\n            case 'bo_IN':\n            case 'dz':\n            case 'dz_BT':\n            case 'id':\n            case 'id_ID':\n            case 'ja':\n            case 'ja_JP':\n            case 'jv':\n            case 'ka':\n            case 'ka_GE':\n            case 'km':\n            case 'km_KH':\n            case 'kn':\n            case 'kn_IN':\n            case 'ko':\n            case 'ko_KR':\n            case 'ms':\n            case 'ms_MY':\n            case 'th':\n            case 'th_TH':\n            case 'tr':\n            case 'tr_CY':\n            case 'tr_TR':\n            case 'vi':\n            case 'vi_VN':\n            case 'zh':\n            case 'zh_CN':\n            case 'zh_HK':\n            case 'zh_SG':\n            case 'zh_TW':\n                return 0;\n            case 'af':\n            case 'af_ZA':\n            case 'bn':\n            case 'bn_BD':\n            case 'bn_IN':\n            case 'bg':\n            case 'bg_BG':\n            case 'ca':\n            case 'ca_AD':\n            case 'ca_ES':\n            case 'ca_FR':\n            case 'ca_IT':\n            case 'da':\n            case 'da_DK':\n            case 'de':\n            case 'de_AT':\n            case 'de_BE':\n            case 'de_CH':\n            case 'de_DE':\n            case 'de_LI':\n            case 'de_LU':\n            case 'el':\n            case 'el_CY':\n            case 'el_GR':\n            case 'en':\n            case 'en_AG':\n            case 'en_AU':\n            case 'en_BW':\n            case 'en_CA':\n            case 'en_DK':\n            case 'en_GB':\n            case 'en_HK':\n            case 'en_IE':\n            case 'en_IN':\n            case 'en_NG':\n            case 'en_NZ':\n            case 'en_PH':\n            case 'en_SG':\n            case 'en_US':\n            case 'en_ZA':\n            case 'en_ZM':\n            case 'en_ZW':\n            case 'eo':\n            case 'eo_US':\n            case 'es':\n            case 'es_AR':\n            case 'es_BO':\n            case 'es_CL':\n            case 'es_CO':\n            case 'es_CR':\n            case 'es_CU':\n            case 'es_DO':\n            case 'es_EC':\n            case 'es_ES':\n            case 'es_GT':\n            case 'es_HN':\n            case 'es_MX':\n            case 'es_NI':\n            case 'es_PA':\n            case 'es_PE':\n            case 'es_PR':\n            case 'es_PY':\n            case 'es_SV':\n            case 'es_US':\n            case 'es_UY':\n            case 'es_VE':\n            case 'et':\n            case 'et_EE':\n            case 'eu':\n            case 'eu_ES':\n            case 'eu_FR':\n            case 'fa':\n            case 'fa_IR':\n            case 'fi':\n            case 'fi_FI':\n            case 'fo':\n            case 'fo_FO':\n            case 'fur':\n            case 'fur_IT':\n            case 'fy':\n            case 'fy_DE':\n            case 'fy_NL':\n            case 'gl':\n            case 'gl_ES':\n            case 'gu':\n            case 'gu_IN':\n            case 'ha':\n            case 'ha_NG':\n            case 'he':\n            case 'he_IL':\n            case 'hu':\n            case 'hu_HU':\n            case 'is':\n            case 'is_IS':\n            case 'it':\n            case 'it_CH':\n            case 'it_IT':\n            case 'ku':\n            case 'ku_TR':\n            case 'lb':\n            case 'lb_LU':\n            case 'ml':\n            case 'ml_IN':\n            case 'mn':\n            case 'mn_MN':\n            case 'mr':\n            case 'mr_IN':\n            case 'nah':\n            case 'nb':\n            case 'nb_NO':\n            case 'ne':\n            case 'ne_NP':\n            case 'nl':\n            case 'nl_AW':\n            case 'nl_BE':\n            case 'nl_NL':\n            case 'nn':\n            case 'nn_NO':\n            case 'no':\n            case 'om':\n            case 'om_ET':\n            case 'om_KE':\n            case 'or':\n            case 'or_IN':\n            case 'pa':\n            case 'pa_IN':\n            case 'pa_PK':\n            case 'pap':\n            case 'pap_AN':\n            case 'pap_AW':\n            case 'pap_CW':\n            case 'ps':\n            case 'ps_AF':\n            case 'pt':\n            case 'pt_BR':\n            case 'pt_PT':\n            case 'so':\n            case 'so_DJ':\n            case 'so_ET':\n            case 'so_KE':\n            case 'so_SO':\n            case 'sq':\n            case 'sq_AL':\n            case 'sq_MK':\n            case 'sv':\n            case 'sv_FI':\n            case 'sv_SE':\n            case 'sw':\n            case 'sw_KE':\n            case 'sw_TZ':\n            case 'ta':\n            case 'ta_IN':\n            case 'ta_LK':\n            case 'te':\n            case 'te_IN':\n            case 'tk':\n            case 'tk_TM':\n            case 'ur':\n            case 'ur_IN':\n            case 'ur_PK':\n            case 'zu':\n            case 'zu_ZA':\n                return ($number == 1) ? 0 : 1;\n            case 'am':\n            case 'am_ET':\n            case 'bh':\n            case 'fil':\n            case 'fil_PH':\n            case 'fr':\n            case 'fr_BE':\n            case 'fr_CA':\n            case 'fr_CH':\n            case 'fr_FR':\n            case 'fr_LU':\n            case 'gun':\n            case 'hi':\n            case 'hi_IN':\n            case 'hy':\n            case 'hy_AM':\n            case 'ln':\n            case 'ln_CD':\n            case 'mg':\n            case 'mg_MG':\n            case 'nso':\n            case 'nso_ZA':\n            case 'ti':\n            case 'ti_ER':\n            case 'ti_ET':\n            case 'wa':\n            case 'wa_BE':\n            case 'xbr':\n                return (($number == 0) || ($number == 1)) ? 0 : 1;\n            case 'be':\n            case 'be_BY':\n            case 'bs':\n            case 'bs_BA':\n            case 'hr':\n            case 'hr_HR':\n            case 'ru':\n            case 'ru_RU':\n            case 'ru_UA':\n            case 'sr':\n            case 'sr_ME':\n            case 'sr_RS':\n            case 'uk':\n            case 'uk_UA':\n                return (((int) $number % 10 == 1) && ((int) $number % 100 != 11)) ? 0 : ((((int) $number % 10 >= 2) && ((int) $number % 10 <= 4) && (((int) $number % 100 < 10) || ((int) $number % 100 >= 20))) ? 1 : 2);\n            case 'cs':\n            case 'cs_CZ':\n            case 'sk':\n            case 'sk_SK':\n                return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);\n            case 'ga':\n            case 'ga_IE':\n                return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);\n            case 'lt':\n            case 'lt_LT':\n                return (((int) $number % 10 == 1) && ((int) $number % 100 != 11)) ? 0 : ((((int) $number % 10 >= 2) && (((int) $number % 100 < 10) || ((int) $number % 100 >= 20))) ? 1 : 2);\n            case 'sl':\n            case 'sl_SI':\n                return ((int) $number % 100 == 1) ? 0 : (((int) $number % 100 == 2) ? 1 : ((((int) $number % 100 == 3) || ((int) $number % 100 == 4)) ? 2 : 3));\n            case 'mk':\n            case 'mk_MK':\n                return ((int) $number % 10 == 1) ? 0 : 1;\n            case 'mt':\n            case 'mt_MT':\n                return ($number == 1) ? 0 : ((($number == 0) || (((int) $number % 100 > 1) && ((int) $number % 100 < 11))) ? 1 : ((((int) $number % 100 > 10) && ((int) $number % 100 < 20)) ? 2 : 3));\n            case 'lv':\n            case 'lv_LV':\n                return ($number == 0) ? 0 : ((((int) $number % 10 == 1) && ((int) $number % 100 != 11)) ? 1 : 2);\n            case 'pl':\n            case 'pl_PL':\n                return ($number == 1) ? 0 : ((((int) $number % 10 >= 2) && ((int) $number % 10 <= 4) && (((int) $number % 100 < 12) || ((int) $number % 100 > 14))) ? 1 : 2);\n            case 'cy':\n            case 'cy_GB':\n                return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));\n            case 'ro':\n            case 'ro_RO':\n                return ($number == 1) ? 0 : ((($number == 0) || (((int) $number % 100 > 0) && ((int) $number % 100 < 20))) ? 1 : 2);\n            case 'ar':\n            case 'ar_AE':\n            case 'ar_BH':\n            case 'ar_DZ':\n            case 'ar_EG':\n            case 'ar_IN':\n            case 'ar_IQ':\n            case 'ar_JO':\n            case 'ar_KW':\n            case 'ar_LB':\n            case 'ar_LY':\n            case 'ar_MA':\n            case 'ar_OM':\n            case 'ar_QA':\n            case 'ar_SA':\n            case 'ar_SD':\n            case 'ar_SS':\n            case 'ar_SY':\n            case 'ar_TN':\n            case 'ar_YE':\n                return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((((int) $number % 100 >= 3) && ((int) $number % 100 <= 10)) ? 3 : ((((int) $number % 100 >= 11) && ((int) $number % 100 <= 99)) ? 4 : 5))));\n            default:\n                return 0;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/PotentiallyTranslatedString.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Stringable;\n\nclass PotentiallyTranslatedString implements Stringable\n{\n    /**\n     * The string that may be translated.\n     *\n     * @var string\n     */\n    protected $string;\n\n    /**\n     * The translated string.\n     *\n     * @var string|null\n     */\n    protected $translation;\n\n    /**\n     * The validator that may perform the translation.\n     *\n     * @var \\Illuminate\\Contracts\\Translation\\Translator\n     */\n    protected $translator;\n\n    /**\n     * Create a new potentially translated string.\n     *\n     * @param  string  $string\n     * @param  \\Illuminate\\Contracts\\Translation\\Translator  $translator\n     */\n    public function __construct($string, $translator)\n    {\n        $this->string = $string;\n\n        $this->translator = $translator;\n    }\n\n    /**\n     * Translate the string.\n     *\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return $this\n     */\n    public function translate($replace = [], $locale = null)\n    {\n        $this->translation = $this->translator->get($this->string, $replace, $locale);\n\n        return $this;\n    }\n\n    /**\n     * Translates the string based on a count.\n     *\n     * @param  \\Countable|int|float|array  $number\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return $this\n     */\n    public function translateChoice($number, array $replace = [], $locale = null)\n    {\n        $this->translation = $this->translator->choice($this->string, $number, $replace, $locale);\n\n        return $this;\n    }\n\n    /**\n     * Get the original string.\n     *\n     * @return string\n     */\n    public function original()\n    {\n        return $this->string;\n    }\n\n    /**\n     * Get the potentially translated string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->translation ?? $this->string;\n    }\n\n    /**\n     * Get the potentially translated string.\n     *\n     * @return string\n     */\n    public function toString()\n    {\n        return (string) $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/TranslationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass TranslationServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerLoader();\n\n        $this->app->singleton('translator', function ($app) {\n            $loader = $app['translation.loader'];\n\n            // When registering the translator component, we'll need to set the default\n            // locale as well as the fallback locale. So, we'll grab the application\n            // configuration so we can easily get both of these values from there.\n            $locale = $app->getLocale();\n\n            $trans = new Translator($loader, $locale);\n\n            $trans->setFallback($app->getFallbackLocale());\n\n            return $trans;\n        });\n    }\n\n    /**\n     * Register the translation line loader.\n     *\n     * @return void\n     */\n    protected function registerLoader()\n    {\n        $this->app->singleton('translation.loader', function ($app) {\n            return new FileLoader($app['files'], [__DIR__.'/lang', $app['path.lang']]);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['translator', 'translation.loader'];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/Translator.php",
    "content": "<?php\n\nnamespace Illuminate\\Translation;\n\nuse Closure;\nuse Illuminate\\Contracts\\Translation\\Loader;\nuse Illuminate\\Contracts\\Translation\\Translator as TranslatorContract;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\NamespacedItemResolver;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse InvalidArgumentException;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Translator extends NamespacedItemResolver implements TranslatorContract\n{\n    use Macroable, ReflectsClosures;\n\n    /**\n     * The loader implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Translation\\Loader\n     */\n    protected $loader;\n\n    /**\n     * The default locale being used by the translator.\n     *\n     * @var string\n     */\n    protected $locale;\n\n    /**\n     * The fallback locale used by the translator.\n     *\n     * @var string\n     */\n    protected $fallback;\n\n    /**\n     * The array of loaded translation groups.\n     *\n     * @var array\n     */\n    protected $loaded = [];\n\n    /**\n     * The message selector.\n     *\n     * @var \\Illuminate\\Translation\\MessageSelector\n     */\n    protected $selector;\n\n    /**\n     * The callable that should be invoked to determine applicable locales.\n     *\n     * @var callable\n     */\n    protected $determineLocalesUsing;\n\n    /**\n     * The custom rendering callbacks for stringable objects.\n     *\n     * @var array\n     */\n    protected $stringableHandlers = [];\n\n    /**\n     * The callback that is responsible for handling missing translation keys.\n     *\n     * @var callable|null\n     */\n    protected $missingTranslationKeyCallback;\n\n    /**\n     * Indicates whether missing translation keys should be handled.\n     *\n     * @var bool\n     */\n    protected $handleMissingTranslationKeys = true;\n\n    /**\n     * Create a new translator instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Translation\\Loader  $loader\n     * @param  string  $locale\n     */\n    public function __construct(Loader $loader, $locale)\n    {\n        $this->loader = $loader;\n\n        $this->setLocale($locale);\n    }\n\n    /**\n     * Determine if a translation exists for a given locale.\n     *\n     * @param  string  $key\n     * @param  string|null  $locale\n     * @return bool\n     */\n    public function hasForLocale($key, $locale = null)\n    {\n        return $this->has($key, $locale, false);\n    }\n\n    /**\n     * Determine if a translation exists.\n     *\n     * @param  string  $key\n     * @param  string|null  $locale\n     * @param  bool  $fallback\n     * @return bool\n     */\n    public function has($key, $locale = null, $fallback = true)\n    {\n        $locale = $locale ?: $this->locale;\n\n        // We should temporarily disable the handling of missing translation keys\n        // while performing the existence check. After the check, we will turn\n        // the missing translation keys handling back to its original value.\n        $handleMissingTranslationKeys = $this->handleMissingTranslationKeys;\n\n        $this->handleMissingTranslationKeys = false;\n\n        $line = $this->get($key, [], $locale, $fallback);\n\n        $this->handleMissingTranslationKeys = $handleMissingTranslationKeys;\n\n        // For JSON translations, the loaded files will contain the correct line.\n        // Otherwise, we must assume we are handling typical translation file\n        // and check if the returned line is not the same as the given key.\n        if (! is_null($this->loaded['*']['*'][$locale][$key] ?? null)) {\n            return true;\n        }\n\n        return $line !== $key;\n    }\n\n    /**\n     * Get the translation for the given key.\n     *\n     * @param  string  $key\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @param  bool  $fallback\n     * @return string|array\n     */\n    public function get($key, array $replace = [], $locale = null, $fallback = true)\n    {\n        $locale = $locale ?: $this->locale;\n\n        // For JSON translations, there is only one file per locale, so we will simply load\n        // that file and then we will be ready to check the array for the key. These are\n        // only one level deep so we do not need to do any fancy searching through it.\n        $this->load('*', '*', $locale);\n\n        $line = $this->loaded['*']['*'][$locale][$key] ?? null;\n\n        // If we can't find a translation for the JSON key, we will attempt to translate it\n        // using the typical translation file. This way developers can always just use a\n        // helper such as __ instead of having to pick between trans or __ with views.\n        if (! isset($line)) {\n            [$namespace, $group, $item] = $this->parseKey($key);\n\n            // Here we will get the locale that should be used for the language line. If one\n            // was not passed, we will use the default locales which was given to us when\n            // the translator was instantiated. Then, we can load the lines and return.\n            $locales = $fallback ? $this->localeArray($locale) : [$locale];\n\n            foreach ($locales as $languageLineLocale) {\n                if (! is_null($line = $this->getLine(\n                    $namespace, $group, $languageLineLocale, $item, $replace\n                ))) {\n                    return $line;\n                }\n            }\n\n            $key = $this->handleMissingTranslationKey(\n                $key, $replace, $locale, $fallback\n            );\n        }\n\n        // If the line doesn't exist, we will return back the key which was requested as\n        // that will be quick to spot in the UI if language keys are wrong or missing\n        // from the application's language files. Otherwise we can return the line.\n        return $this->makeReplacements($line ?: $key, $replace);\n    }\n\n    /**\n     * Get a translation according to an integer value.\n     *\n     * @param  string  $key\n     * @param  \\Countable|int|float|array  $number\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @return string\n     */\n    public function choice($key, $number, array $replace = [], $locale = null)\n    {\n        $line = $this->get(\n            $key, [], $locale = $this->localeForChoice($key, $locale)\n        );\n\n        // If the given \"number\" is actually an array or countable we will simply count the\n        // number of elements in an instance. This allows developers to pass an array of\n        // items without having to count it on their end first which gives bad syntax.\n        if (is_countable($number)) {\n            $number = count($number);\n        }\n\n        if (! isset($replace['count'])) {\n            $replace['count'] = $number;\n        }\n\n        return $this->makeReplacements(\n            $this->getSelector()->choose($line, $number, $locale), $replace\n        );\n    }\n\n    /**\n     * Get the proper locale for a choice operation.\n     *\n     * @param  string  $key\n     * @param  string|null  $locale\n     * @return string\n     */\n    protected function localeForChoice($key, $locale)\n    {\n        $locale = $locale ?: $this->locale;\n\n        return $this->hasForLocale($key, $locale) ? $locale : $this->fallback;\n    }\n\n    /**\n     * Retrieve a language line out the loaded array.\n     *\n     * @param  string  $namespace\n     * @param  string  $group\n     * @param  string  $locale\n     * @param  string  $item\n     * @param  array  $replace\n     * @return string|array|null\n     */\n    protected function getLine($namespace, $group, $locale, $item, array $replace)\n    {\n        $this->load($namespace, $group, $locale);\n\n        $line = Arr::get($this->loaded[$namespace][$group][$locale], $item);\n\n        if (is_string($line)) {\n            return $this->makeReplacements($line, $replace);\n        } elseif (is_array($line) && count($line) > 0) {\n            array_walk_recursive($line, function (&$value, $key) use ($replace) {\n                $value = $this->makeReplacements($value, $replace);\n            });\n\n            return $line;\n        }\n    }\n\n    /**\n     * Make the place-holder replacements on a line.\n     *\n     * @param  string  $line\n     * @param  array  $replace\n     * @return string\n     */\n    protected function makeReplacements($line, array $replace)\n    {\n        if (empty($replace)) {\n            return $line;\n        }\n\n        $shouldReplace = [];\n\n        foreach ($replace as $key => $value) {\n            if ($value instanceof Closure) {\n                $line = preg_replace_callback(\n                    '/<'.$key.'>(.*?)<\\/'.$key.'>/',\n                    fn ($args) => $value($args[1]),\n                    $line\n                );\n\n                continue;\n            }\n\n            if (is_object($value)) {\n                $value = isset($this->stringableHandlers[get_class($value)])\n                    ? call_user_func($this->stringableHandlers[get_class($value)], $value)\n                    : enum_value($value);\n            }\n\n            $shouldReplace[':'.Str::ucfirst($key)] = Str::ucfirst($value ?? '');\n            $shouldReplace[':'.Str::upper($key)] = Str::upper($value ?? '');\n            $shouldReplace[':'.$key] = $value;\n        }\n\n        return strtr($line, $shouldReplace);\n    }\n\n    /**\n     * Add translation lines to the given locale.\n     *\n     * @param  array  $lines\n     * @param  string  $locale\n     * @param  string  $namespace\n     * @return void\n     */\n    public function addLines(array $lines, $locale, $namespace = '*')\n    {\n        foreach ($lines as $key => $value) {\n            [$group, $item] = explode('.', $key, 2);\n\n            Arr::set($this->loaded, \"$namespace.$group.$locale.$item\", $value);\n        }\n    }\n\n    /**\n     * Load the specified language group.\n     *\n     * @param  string  $namespace\n     * @param  string  $group\n     * @param  string  $locale\n     * @return void\n     */\n    public function load($namespace, $group, $locale)\n    {\n        if ($this->isLoaded($namespace, $group, $locale)) {\n            return;\n        }\n\n        // The loader is responsible for returning the array of language lines for the\n        // given namespace, group, and locale. We'll set the lines in this array of\n        // lines that have already been loaded so that we can easily access them.\n        $lines = $this->loader->load($locale, $group, $namespace);\n\n        $this->loaded[$namespace][$group][$locale] = $lines;\n    }\n\n    /**\n     * Determine if the given group has been loaded.\n     *\n     * @param  string  $namespace\n     * @param  string  $group\n     * @param  string  $locale\n     * @return bool\n     */\n    protected function isLoaded($namespace, $group, $locale)\n    {\n        return isset($this->loaded[$namespace][$group][$locale]);\n    }\n\n    /**\n     * Handle a missing translation key.\n     *\n     * @param  string  $key\n     * @param  array  $replace\n     * @param  string|null  $locale\n     * @param  bool  $fallback\n     * @return string\n     */\n    protected function handleMissingTranslationKey($key, $replace, $locale, $fallback)\n    {\n        if (! $this->handleMissingTranslationKeys ||\n            ! isset($this->missingTranslationKeyCallback)) {\n            return $key;\n        }\n\n        // Prevent infinite loops...\n        $this->handleMissingTranslationKeys = false;\n\n        $key = call_user_func(\n            $this->missingTranslationKeyCallback,\n            $key, $replace, $locale, $fallback\n        ) ?? $key;\n\n        $this->handleMissingTranslationKeys = true;\n\n        return $key;\n    }\n\n    /**\n     * Register a callback that is responsible for handling missing translation keys.\n     *\n     * @param  callable|null  $callback\n     * @return static\n     */\n    public function handleMissingKeysUsing(?callable $callback)\n    {\n        $this->missingTranslationKeyCallback = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string  $hint\n     * @return void\n     */\n    public function addNamespace($namespace, $hint)\n    {\n        $this->loader->addNamespace($namespace, $hint);\n    }\n\n    /**\n     * Add a new path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addPath($path)\n    {\n        $this->loader->addPath($path);\n    }\n\n    /**\n     * Add a new JSON path to the loader.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function addJsonPath($path)\n    {\n        $this->loader->addJsonPath($path);\n    }\n\n    /**\n     * Parse a key into namespace, group, and item.\n     *\n     * @param  string  $key\n     * @return array\n     */\n    public function parseKey($key)\n    {\n        $segments = parent::parseKey($key);\n\n        if (is_null($segments[0])) {\n            $segments[0] = '*';\n        }\n\n        return $segments;\n    }\n\n    /**\n     * Get the array of locales to be checked.\n     *\n     * @param  string|null  $locale\n     * @return array\n     */\n    protected function localeArray($locale)\n    {\n        $locales = array_filter([$locale ?: $this->locale, $this->fallback]);\n\n        $determined = call_user_func($this->determineLocalesUsing ?: fn () => $locales, $locales);\n\n        return array_values(array_unique($determined));\n    }\n\n    /**\n     * Specify a callback that should be invoked to determined the applicable locale array.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    public function determineLocalesUsing($callback)\n    {\n        $this->determineLocalesUsing = $callback;\n    }\n\n    /**\n     * Get the message selector instance.\n     *\n     * @return \\Illuminate\\Translation\\MessageSelector\n     */\n    public function getSelector()\n    {\n        if (! isset($this->selector)) {\n            $this->selector = new MessageSelector;\n        }\n\n        return $this->selector;\n    }\n\n    /**\n     * Set the message selector instance.\n     *\n     * @param  \\Illuminate\\Translation\\MessageSelector  $selector\n     * @return void\n     */\n    public function setSelector(MessageSelector $selector)\n    {\n        $this->selector = $selector;\n    }\n\n    /**\n     * Get the language line loader implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Translation\\Loader\n     */\n    public function getLoader()\n    {\n        return $this->loader;\n    }\n\n    /**\n     * Get the default locale being used.\n     *\n     * @return string\n     */\n    public function locale()\n    {\n        return $this->getLocale();\n    }\n\n    /**\n     * Get the default locale being used.\n     *\n     * @return string\n     */\n    public function getLocale()\n    {\n        return $this->locale;\n    }\n\n    /**\n     * Set the default locale.\n     *\n     * @param  string  $locale\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setLocale($locale)\n    {\n        if (Str::contains($locale, ['/', '\\\\'])) {\n            throw new InvalidArgumentException('Invalid characters present in locale.');\n        }\n\n        $this->locale = $locale;\n    }\n\n    /**\n     * Get the fallback locale being used.\n     *\n     * @return string\n     */\n    public function getFallback()\n    {\n        return $this->fallback;\n    }\n\n    /**\n     * Set the fallback locale being used.\n     *\n     * @param  string  $fallback\n     * @return void\n     */\n    public function setFallback($fallback)\n    {\n        $this->fallback = $fallback;\n    }\n\n    /**\n     * Set the loaded translation groups.\n     *\n     * @param  array  $loaded\n     * @return void\n     */\n    public function setLoaded(array $loaded)\n    {\n        $this->loaded = $loaded;\n    }\n\n    /**\n     * Add a handler to be executed in order to format a given class to a string during translation replacements.\n     *\n     * @param  callable|string  $class\n     * @param  callable|null  $handler\n     * @return void\n     */\n    public function stringable($class, $handler = null)\n    {\n        if ($class instanceof Closure) {\n            [$class, $handler] = [\n                $this->firstClosureParameterType($class),\n                $class,\n            ];\n        }\n\n        $this->stringableHandlers[$class] = $handler;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/composer.json",
    "content": "{\n    \"name\": \"illuminate/translation\",\n    \"description\": \"The Illuminate Translation package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/filesystem\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Translation\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Translation/lang/en/auth.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Authentication Language Lines\n    |--------------------------------------------------------------------------\n    |\n    | The following language lines are used during authentication for various\n    | messages that we need to display to the user. You are free to modify\n    | these language lines according to your application's requirements.\n    |\n    */\n\n    'failed' => 'These credentials do not match our records.',\n    'password' => 'The provided password is incorrect.',\n    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',\n\n];\n"
  },
  {
    "path": "src/Illuminate/Translation/lang/en/pagination.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Pagination Language Lines\n    |--------------------------------------------------------------------------\n    |\n    | The following language lines are used by the paginator library to build\n    | the simple pagination links. You are free to change them to anything\n    | you want to customize your views to better match your application.\n    |\n    */\n\n    'previous' => '&laquo; Previous',\n    'next' => 'Next &raquo;',\n\n];\n"
  },
  {
    "path": "src/Illuminate/Translation/lang/en/passwords.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Password Reset Language Lines\n    |--------------------------------------------------------------------------\n    |\n    | The following language lines are the default lines which match reasons\n    | that are given by the password broker for a password update attempt\n    | outcome such as failure due to an invalid password / reset token.\n    |\n    */\n\n    'reset' => 'Your password has been reset.',\n    'sent' => 'We have emailed your password reset link.',\n    'throttled' => 'Please wait before retrying.',\n    'token' => 'This password reset token is invalid.',\n    'user' => \"We can't find a user with that email address.\",\n\n];\n"
  },
  {
    "path": "src/Illuminate/Translation/lang/en/validation.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Validation Language Lines\n    |--------------------------------------------------------------------------\n    |\n    | The following language lines contain the default error messages used by\n    | the validator class. Some of these rules have multiple versions such\n    | as the size rules. Feel free to tweak each of these messages here.\n    |\n    */\n\n    'accepted' => 'The :attribute field must be accepted.',\n    'accepted_if' => 'The :attribute field must be accepted when :other is :value.',\n    'active_url' => 'The :attribute field must be a valid URL.',\n    'after' => 'The :attribute field must be a date after :date.',\n    'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',\n    'alpha' => 'The :attribute field must only contain letters.',\n    'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',\n    'alpha_num' => 'The :attribute field must only contain letters and numbers.',\n    'any_of' => 'The :attribute field is invalid.',\n    'array' => 'The :attribute field must be an array.',\n    'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',\n    'before' => 'The :attribute field must be a date before :date.',\n    'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',\n    'between' => [\n        'array' => 'The :attribute field must have between :min and :max items.',\n        'file' => 'The :attribute field must be between :min and :max kilobytes.',\n        'numeric' => 'The :attribute field must be between :min and :max.',\n        'string' => 'The :attribute field must be between :min and :max characters.',\n    ],\n    'boolean' => 'The :attribute field must be true or false.',\n    'can' => 'The :attribute field contains an unauthorized value.',\n    'confirmed' => 'The :attribute field confirmation does not match.',\n    'contains' => 'The :attribute field is missing a required value.',\n    'current_password' => 'The password is incorrect.',\n    'date' => 'The :attribute field must be a valid date.',\n    'date_equals' => 'The :attribute field must be a date equal to :date.',\n    'date_format' => 'The :attribute field must match the format :format.',\n    'decimal' => 'The :attribute field must have :decimal decimal places.',\n    'declined' => 'The :attribute field must be declined.',\n    'declined_if' => 'The :attribute field must be declined when :other is :value.',\n    'different' => 'The :attribute field and :other must be different.',\n    'digits' => 'The :attribute field must be :digits digits.',\n    'digits_between' => 'The :attribute field must be between :min and :max digits.',\n    'dimensions' => 'The :attribute field has invalid image dimensions.',\n    'distinct' => 'The :attribute field has a duplicate value.',\n    'doesnt_contain' => 'The :attribute field must not contain any of the following: :values.',\n    'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',\n    'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',\n    'email' => 'The :attribute field must be a valid email address.',\n    'encoding' => 'The :attribute field must be encoded in :encoding.',\n    'ends_with' => 'The :attribute field must end with one of the following: :values.',\n    'enum' => 'The selected :attribute is invalid.',\n    'exists' => 'The selected :attribute is invalid.',\n    'extensions' => 'The :attribute field must have one of the following extensions: :values.',\n    'file' => 'The :attribute field must be a file.',\n    'filled' => 'The :attribute field must have a value.',\n    'gt' => [\n        'array' => 'The :attribute field must have more than :value items.',\n        'file' => 'The :attribute field must be greater than :value kilobytes.',\n        'numeric' => 'The :attribute field must be greater than :value.',\n        'string' => 'The :attribute field must be greater than :value characters.',\n    ],\n    'gte' => [\n        'array' => 'The :attribute field must have :value items or more.',\n        'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',\n        'numeric' => 'The :attribute field must be greater than or equal to :value.',\n        'string' => 'The :attribute field must be greater than or equal to :value characters.',\n    ],\n    'hex_color' => 'The :attribute field must be a valid hexadecimal color.',\n    'image' => 'The :attribute field must be an image.',\n    'in' => 'The selected :attribute is invalid.',\n    'in_array' => 'The :attribute field must exist in :other.',\n    'in_array_keys' => 'The :attribute field must contain at least one of the following keys: :values.',\n    'integer' => 'The :attribute field must be an integer.',\n    'ip' => 'The :attribute field must be a valid IP address.',\n    'ipv4' => 'The :attribute field must be a valid IPv4 address.',\n    'ipv6' => 'The :attribute field must be a valid IPv6 address.',\n    'json' => 'The :attribute field must be a valid JSON string.',\n    'list' => 'The :attribute field must be a list.',\n    'lowercase' => 'The :attribute field must be lowercase.',\n    'lt' => [\n        'array' => 'The :attribute field must have less than :value items.',\n        'file' => 'The :attribute field must be less than :value kilobytes.',\n        'numeric' => 'The :attribute field must be less than :value.',\n        'string' => 'The :attribute field must be less than :value characters.',\n    ],\n    'lte' => [\n        'array' => 'The :attribute field must not have more than :value items.',\n        'file' => 'The :attribute field must be less than or equal to :value kilobytes.',\n        'numeric' => 'The :attribute field must be less than or equal to :value.',\n        'string' => 'The :attribute field must be less than or equal to :value characters.',\n    ],\n    'mac_address' => 'The :attribute field must be a valid MAC address.',\n    'max' => [\n        'array' => 'The :attribute field must not have more than :max items.',\n        'file' => 'The :attribute field must not be greater than :max kilobytes.',\n        'numeric' => 'The :attribute field must not be greater than :max.',\n        'string' => 'The :attribute field must not be greater than :max characters.',\n    ],\n    'max_digits' => 'The :attribute field must not have more than :max digits.',\n    'mimes' => 'The :attribute field must be a file of type: :values.',\n    'mimetypes' => 'The :attribute field must be a file of type: :values.',\n    'min' => [\n        'array' => 'The :attribute field must have at least :min items.',\n        'file' => 'The :attribute field must be at least :min kilobytes.',\n        'numeric' => 'The :attribute field must be at least :min.',\n        'string' => 'The :attribute field must be at least :min characters.',\n    ],\n    'min_digits' => 'The :attribute field must have at least :min digits.',\n    'missing' => 'The :attribute field must be missing.',\n    'missing_if' => 'The :attribute field must be missing when :other is :value.',\n    'missing_unless' => 'The :attribute field must be missing unless :other is :value.',\n    'missing_with' => 'The :attribute field must be missing when :values is present.',\n    'missing_with_all' => 'The :attribute field must be missing when :values are present.',\n    'multiple_of' => 'The :attribute field must be a multiple of :value.',\n    'not_in' => 'The selected :attribute is invalid.',\n    'not_regex' => 'The :attribute field format is invalid.',\n    'numeric' => 'The :attribute field must be a number.',\n    'password' => [\n        'letters' => 'The :attribute field must contain at least one letter.',\n        'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',\n        'numbers' => 'The :attribute field must contain at least one number.',\n        'symbols' => 'The :attribute field must contain at least one symbol.',\n        'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',\n    ],\n    'present' => 'The :attribute field must be present.',\n    'present_if' => 'The :attribute field must be present when :other is :value.',\n    'present_unless' => 'The :attribute field must be present unless :other is :value.',\n    'present_with' => 'The :attribute field must be present when :values is present.',\n    'present_with_all' => 'The :attribute field must be present when :values are present.',\n    'prohibited' => 'The :attribute field is prohibited.',\n    'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',\n    'prohibited_if_accepted' => 'The :attribute field is prohibited when :other is accepted.',\n    'prohibited_if_declined' => 'The :attribute field is prohibited when :other is declined.',\n    'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',\n    'prohibits' => 'The :attribute field prohibits :other from being present.',\n    'regex' => 'The :attribute field format is invalid.',\n    'required' => 'The :attribute field is required.',\n    'required_array_keys' => 'The :attribute field must contain entries for: :values.',\n    'required_if' => 'The :attribute field is required when :other is :value.',\n    'required_if_accepted' => 'The :attribute field is required when :other is accepted.',\n    'required_if_declined' => 'The :attribute field is required when :other is declined.',\n    'required_unless' => 'The :attribute field is required unless :other is in :values.',\n    'required_with' => 'The :attribute field is required when :values is present.',\n    'required_with_all' => 'The :attribute field is required when :values are present.',\n    'required_without' => 'The :attribute field is required when :values is not present.',\n    'required_without_all' => 'The :attribute field is required when none of :values are present.',\n    'same' => 'The :attribute field must match :other.',\n    'size' => [\n        'array' => 'The :attribute field must contain :size items.',\n        'file' => 'The :attribute field must be :size kilobytes.',\n        'numeric' => 'The :attribute field must be :size.',\n        'string' => 'The :attribute field must be :size characters.',\n    ],\n    'starts_with' => 'The :attribute field must start with one of the following: :values.',\n    'string' => 'The :attribute field must be a string.',\n    'timezone' => 'The :attribute field must be a valid timezone.',\n    'unique' => 'The :attribute has already been taken.',\n    'uploaded' => 'The :attribute failed to upload.',\n    'uppercase' => 'The :attribute field must be uppercase.',\n    'url' => 'The :attribute field must be a valid URL.',\n    'ulid' => 'The :attribute field must be a valid ULID.',\n    'uuid' => 'The :attribute field must be a valid UUID.',\n\n    /*\n    |--------------------------------------------------------------------------\n    | Custom Validation Language Lines\n    |--------------------------------------------------------------------------\n    |\n    | Here you may specify custom validation messages for attributes using the\n    | convention \"attribute.rule\" to name the lines. This makes it quick to\n    | specify a specific custom language line for a given attribute rule.\n    |\n    */\n\n    'custom' => [\n        'attribute-name' => [\n            'rule-name' => 'custom-message',\n        ],\n    ],\n\n    /*\n    |--------------------------------------------------------------------------\n    | Custom Validation Attributes\n    |--------------------------------------------------------------------------\n    |\n    | The following language lines are used to swap our attribute placeholder\n    | with something more reader friendly such as \"E-Mail Address\" instead\n    | of \"email\". This simply helps us make our message more expressive.\n    |\n    */\n\n    'attributes' => [],\n\n];\n"
  },
  {
    "path": "src/Illuminate/Validation/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/Validation/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/Validation/ClosureValidationRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Contracts\\Validation\\Rule as RuleContract;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Translation\\CreatesPotentiallyTranslatedStrings;\n\nclass ClosureValidationRule implements RuleContract, ValidatorAwareRule\n{\n    use CreatesPotentiallyTranslatedStrings;\n\n    /**\n     * The callback that validates the attribute.\n     *\n     * @var \\Closure\n     */\n    public $callback;\n\n    /**\n     * Indicates if the validation callback failed.\n     *\n     * @var bool\n     */\n    public $failed = false;\n\n    /**\n     * The validation error messages.\n     *\n     * @var array\n     */\n    public $messages = [];\n\n    /**\n     * The current validator.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * Create a new Closure based validation rule.\n     *\n     * @param  \\Closure  $callback\n     */\n    public function __construct($callback)\n    {\n        $this->callback = $callback;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $this->failed = false;\n\n        $this->callback->__invoke($attribute, $value, function ($attribute, $message = null) {\n            $this->failed = true;\n\n            return $this->pendingPotentiallyTranslatedString($attribute, $message);\n        }, $this->validator);\n\n        return ! $this->failed;\n    }\n\n    /**\n     * Get the validation error messages.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Concerns/FilterEmailValidation.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Concerns;\n\nuse Egulias\\EmailValidator\\EmailLexer;\nuse Egulias\\EmailValidator\\Result\\InvalidEmail;\nuse Egulias\\EmailValidator\\Validation\\EmailValidation;\n\nclass FilterEmailValidation implements EmailValidation\n{\n    /**\n     * The flags to pass to the filter_var function.\n     *\n     * @var int|null\n     */\n    protected $flags;\n\n    /**\n     * Create a new validation instance.\n     *\n     * @param  int|null  $flags\n     */\n    public function __construct($flags = null)\n    {\n        $this->flags = $flags;\n    }\n\n    /**\n     * Create a new instance which allows any unicode characters in local-part.\n     *\n     * @return static\n     */\n    public static function unicode()\n    {\n        return new static(FILTER_FLAG_EMAIL_UNICODE);\n    }\n\n    /**\n     * Returns true if the given email is valid.\n     *\n     * @param  string  $email\n     * @param  \\Egulias\\EmailValidator\\EmailLexer  $emailLexer\n     * @return bool\n     */\n    public function isValid(string $email, EmailLexer $emailLexer): bool\n    {\n        return is_null($this->flags)\n            ? filter_var($email, FILTER_VALIDATE_EMAIL) !== false\n            : filter_var($email, FILTER_VALIDATE_EMAIL, $this->flags) !== false;\n    }\n\n    /**\n     * Returns the validation error.\n     *\n     * @return \\Egulias\\EmailValidator\\Result\\InvalidEmail|null\n     */\n    public function getError(): ?InvalidEmail\n    {\n        return null;\n    }\n\n    /**\n     * Returns the validation warnings.\n     *\n     * @return \\Egulias\\EmailValidator\\Warning\\Warning[]\n     */\n    public function getWarnings(): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Concerns/FormatsMessages.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Concerns;\n\nuse Closure;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Number;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\HttpFoundation\\File\\File;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile;\n\ntrait FormatsMessages\n{\n    use ReplacesAttributes;\n\n    /**\n     * Get the validation message for an attribute and rule.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @return string\n     */\n    protected function getMessage($attribute, $rule)\n    {\n        $attributeWithPlaceholders = $attribute;\n\n        $attribute = $this->replacePlaceholderInString($attribute);\n\n        $inlineMessage = $this->getInlineMessage($attribute, $rule);\n\n        // First we will retrieve the custom message for the validation rule if one\n        // exists. If a custom validation message is being used we'll return the\n        // custom message, otherwise we'll keep searching for a valid message.\n        if (! is_null($inlineMessage)) {\n            return $inlineMessage;\n        }\n\n        $lowerRule = Str::snake($rule);\n\n        $customKey = \"validation.custom.{$attribute}.{$lowerRule}\";\n\n        $customMessage = $this->getCustomMessageFromTranslator(\n            in_array($rule, $this->sizeRules)\n                ? [$customKey.\".{$this->getAttributeType($attribute)}\", $customKey]\n                : $customKey\n        );\n\n        // First we check for a custom defined validation message for the attribute\n        // and rule. This allows the developer to specify specific messages for\n        // only some attributes and rules that need to get specially formed.\n        if ($customMessage !== $customKey) {\n            return $customMessage;\n        }\n\n        // If the rule being validated is a \"size\" rule, we will need to gather the\n        // specific error message for the type of attribute being validated such\n        // as a number, file or string which all have different message types.\n        elseif (in_array($rule, $this->sizeRules)) {\n            return $this->getSizeMessage($attributeWithPlaceholders, $rule);\n        }\n\n        // Finally, if no developer specified messages have been set, and no other\n        // special messages apply for this rule, we will just pull the default\n        // messages out of the translator service for this validation rule.\n        $key = \"validation.{$lowerRule}\";\n\n        if ($key !== ($value = $this->translator->get($key))) {\n            return $value;\n        }\n\n        return $this->getFromLocalArray(\n            $attribute, $lowerRule, $this->fallbackMessages\n        ) ?: $key;\n    }\n\n    /**\n     * Get the proper inline error message for standard and size rules.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @return string|null\n     */\n    protected function getInlineMessage($attribute, $rule)\n    {\n        $inlineEntry = $this->getFromLocalArray($attribute, Str::snake($rule));\n\n        return is_array($inlineEntry) && in_array($rule, $this->sizeRules)\n            ? ($inlineEntry[$this->getAttributeType($attribute)] ?? null)\n            : $inlineEntry;\n    }\n\n    /**\n     * Get the inline message for a rule if it exists.\n     *\n     * @param  string  $attribute\n     * @param  string  $lowerRule\n     * @param  array|null  $source\n     * @return string|null\n     */\n    protected function getFromLocalArray($attribute, $lowerRule, $source = null)\n    {\n        $source = $source ?: $this->customMessages;\n\n        $keys = [\"{$attribute}.{$lowerRule}\", $lowerRule, $attribute];\n\n        if ($this->getAttributeType($attribute) !== 'file') {\n            $shortRule = \"{$attribute}.\".Str::snake(class_basename($lowerRule));\n\n            if (! in_array($shortRule, $keys)) {\n                $keys[] = $shortRule;\n            }\n        }\n\n        // First we will check for a custom message for an attribute specific rule\n        // message for the fields, then we will check for a general custom line\n        // that is not attribute specific. If we find either we'll return it.\n        foreach ($keys as $key) {\n            foreach (array_keys($source) as $sourceKey) {\n                if (str_contains($sourceKey, '*')) {\n                    $pattern = str_replace('\\*', '([^.]*)', preg_quote($sourceKey, '#'));\n\n                    if (preg_match('#^'.$pattern.'\\z#u', $key) === 1) {\n                        $message = $source[$sourceKey];\n\n                        if (is_array($message) && isset($message[$lowerRule])) {\n                            return $message[$lowerRule];\n                        }\n\n                        return $message;\n                    }\n\n                    continue;\n                }\n\n                if (Str::is($sourceKey, $key)) {\n                    $message = $source[$sourceKey];\n\n                    if ($sourceKey === $attribute && is_array($message)) {\n                        return $message[$lowerRule] ?? null;\n                    }\n\n                    return $message;\n                }\n            }\n        }\n    }\n\n    /**\n     * Get the custom error message from the translator.\n     *\n     * @param  array|string  $keys\n     * @return string\n     */\n    protected function getCustomMessageFromTranslator($keys)\n    {\n        foreach (Arr::wrap($keys) as $key) {\n            if (($message = $this->translator->get($key)) !== $key) {\n                return $message;\n            }\n\n            // If an exact match was not found for the key, we will collapse all of these\n            // messages and loop through them and try to find a wildcard match for the\n            // given key. Otherwise, we will simply return the key's value back out.\n            $shortKey = preg_replace(\n                '/^validation\\.custom\\./', '', $key\n            );\n\n            $message = $this->getWildcardCustomMessages(Arr::dot(\n                (array) $this->translator->get('validation.custom')\n            ), $shortKey, $key);\n\n            if ($message !== $key) {\n                return $message;\n            }\n        }\n\n        return Arr::last(Arr::wrap($keys));\n    }\n\n    /**\n     * Check the given messages for a wildcard key.\n     *\n     * @param  array  $messages\n     * @param  string  $search\n     * @param  string  $default\n     * @return string\n     */\n    protected function getWildcardCustomMessages($messages, $search, $default)\n    {\n        foreach ($messages as $key => $message) {\n            if ($search === $key || (Str::contains($key, ['*']) && Str::is($key, $search))) {\n                return $message;\n            }\n        }\n\n        return $default;\n    }\n\n    /**\n     * Get the proper error message for an attribute and size rule.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @return string\n     */\n    protected function getSizeMessage($attribute, $rule)\n    {\n        $lowerRule = Str::snake($rule);\n\n        // There are three different types of size validations. The attribute may be\n        // either a number, file, or string so we will check a few things to know\n        // which type of value it is and return the correct line for that type.\n        $type = $this->getAttributeType($attribute);\n\n        $key = \"validation.{$lowerRule}.{$type}\";\n\n        return $this->translator->get($key);\n    }\n\n    /**\n     * Get the data type of the given attribute.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function getAttributeType($attribute)\n    {\n        // We assume that the attributes present in the file array are files so that\n        // means that if the attribute does not have a numeric rule and the files\n        // list doesn't have it we'll just consider it a string by elimination.\n        return match (true) {\n            $this->hasRule($attribute, $this->numericRules) => 'numeric',\n            $this->hasRule($attribute, ['Array', 'List']) => 'array',\n            $this->getValue($attribute) instanceof UploadedFile,\n            $this->getValue($attribute) instanceof File => 'file',\n            default => 'string',\n        };\n    }\n\n    /**\n     * Replace all error message place-holders with actual values.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array  $parameters\n     * @return string\n     */\n    public function makeReplacements($message, $attribute, $rule, $parameters)\n    {\n        $message = $this->replaceAttributePlaceholder(\n            $message, $this->getDisplayableAttribute($attribute)\n        );\n\n        $message = $this->replaceInputPlaceholder($message, $attribute);\n        $message = $this->replaceIndexPlaceholder($message, $attribute);\n        $message = $this->replacePositionPlaceholder($message, $attribute);\n        $message = $this->replaceOrdinalPositionPlaceholder($message, $attribute);\n\n        if (isset($this->replacers[Str::snake($rule)])) {\n            return $this->callReplacer($message, $attribute, Str::snake($rule), $parameters, $this);\n        } elseif (method_exists($this, $replacer = \"replace{$rule}\")) {\n            return $this->$replacer($message, $attribute, $rule, $parameters);\n        }\n\n        return $message;\n    }\n\n    /**\n     * Get the displayable name of the attribute.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    public function getDisplayableAttribute($attribute)\n    {\n        $primaryAttribute = $this->getPrimaryAttribute($attribute);\n\n        $expectedAttributes = $attribute != $primaryAttribute\n            ? [$attribute, $primaryAttribute]\n            : [$attribute];\n\n        foreach ($expectedAttributes as $name) {\n            // The developer may dynamically specify the array of custom attributes on this\n            // validator instance. If the attribute exists in this array it is used over\n            // the other ways of pulling the attribute name for this given attributes.\n            if ($inlineAttribute = $this->getAttributeFromLocalArray($name)) {\n                return $inlineAttribute;\n            }\n\n            // We allow for a developer to specify language lines for any attribute in this\n            // application, which allows flexibility for displaying a unique displayable\n            // version of the attribute name instead of the name used in an HTTP POST.\n            if ($translatedAttribute = $this->getAttributeFromTranslations($name)) {\n                return $translatedAttribute;\n            }\n        }\n\n        // When no language line has been specified for the attribute and it is also\n        // an implicit attribute we will display the raw attribute's name and not\n        // modify it with any of these replacements before we display the name.\n        if (isset($this->implicitAttributes[$primaryAttribute])) {\n            return ($formatter = $this->implicitAttributesFormatter)\n                ? $formatter($attribute)\n                : $attribute;\n        }\n\n        return str_replace('_', ' ', Str::snake($attribute));\n    }\n\n    /**\n     * Get the given attribute from the attribute translations.\n     *\n     * @param  string  $name\n     * @return string|null\n     */\n    protected function getAttributeFromTranslations($name)\n    {\n        if (! is_array($attributes = $this->translator->get('validation.attributes'))) {\n            return null;\n        }\n\n        return $this->getAttributeFromLocalArray($name, Arr::dot($attributes));\n    }\n\n    /**\n     * Get the custom name for an attribute if it exists in the given array.\n     *\n     * @param  string  $attribute\n     * @param  array|null  $source\n     * @return string|null\n     */\n    protected function getAttributeFromLocalArray($attribute, $source = null)\n    {\n        $source = $source ?: $this->customAttributes;\n\n        if (isset($source[$attribute])) {\n            return $source[$attribute];\n        }\n\n        foreach (array_keys($source) as $sourceKey) {\n            if (str_contains($sourceKey, '*')) {\n                $pattern = str_replace('\\*', '([^.]*)', preg_quote($sourceKey, '#'));\n\n                if (preg_match('#^'.$pattern.'\\z#u', $attribute) === 1) {\n                    return $source[$sourceKey];\n                }\n            }\n        }\n    }\n\n    /**\n     * Replace the :attribute placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $value\n     * @return string\n     */\n    protected function replaceAttributePlaceholder($message, $value)\n    {\n        return str_replace(\n            [':attribute', ':ATTRIBUTE', ':Attribute'],\n            [$value, Str::upper($value), Str::ucfirst($value)],\n            $message\n        );\n    }\n\n    /**\n     * Replace the :index placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function replaceIndexPlaceholder($message, $attribute)\n    {\n        return $this->replaceIndexOrPositionPlaceholder(\n            $message, $attribute, 'index'\n        );\n    }\n\n    /**\n     * Replace the :position placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function replacePositionPlaceholder($message, $attribute)\n    {\n        return $this->replaceIndexOrPositionPlaceholder(\n            $message, $attribute, 'position', fn ($segment) => $segment + 1\n        );\n    }\n\n    /**\n     * Replace the :ordinal-position placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function replaceOrdinalPositionPlaceholder($message, $attribute)\n    {\n        if (! extension_loaded('intl')) {\n            return $message;\n        }\n\n        return $this->replaceIndexOrPositionPlaceholder(\n            $message, $attribute, 'ordinal-position', fn ($segment) => Number::ordinal($segment + 1)\n        );\n    }\n\n    /**\n     * Replace the :index or :position placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $placeholder\n     * @param  \\Closure|null  $modifier\n     * @return string\n     */\n    protected function replaceIndexOrPositionPlaceholder($message, $attribute, $placeholder, ?Closure $modifier = null)\n    {\n        if (! str_contains(strtolower($message), ':'.$placeholder) &&\n            ! str_contains(strtolower($message), '-'.$placeholder)) {\n            return $message;\n        }\n\n        $segments = explode('.', $attribute);\n\n        $modifier ??= fn ($value) => $value;\n\n        $numericIndex = 1;\n\n        foreach ($segments as $segment) {\n            if (is_numeric($segment)) {\n                if ($numericIndex === 1) {\n                    $message = str_ireplace(':'.$placeholder, $modifier((int) $segment), $message);\n                }\n\n                $message = str_ireplace(\n                    ':'.$this->numberToIndexOrPositionWord($numericIndex).'-'.$placeholder,\n                    $modifier((int) $segment),\n                    $message\n                );\n\n                $numericIndex++;\n            }\n        }\n\n        return $message;\n    }\n\n    /**\n     * Get the word for a index or position segment.\n     *\n     * @param  int  $value\n     * @return string\n     */\n    protected function numberToIndexOrPositionWord(int $value)\n    {\n        return [\n            1 => 'first',\n            2 => 'second',\n            3 => 'third',\n            4 => 'fourth',\n            5 => 'fifth',\n            6 => 'sixth',\n            7 => 'seventh',\n            8 => 'eighth',\n            9 => 'ninth',\n            10 => 'tenth',\n        ][(int) $value] ?? 'other';\n    }\n\n    /**\n     * Replace the :input placeholder in the given message.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function replaceInputPlaceholder($message, $attribute)\n    {\n        if (! str_contains($message, ':input')) {\n            return $message;\n        }\n\n        $actualValue = $this->getValue($attribute);\n\n        if (is_scalar($actualValue) || is_null($actualValue)) {\n            $message = str_replace(':input', $this->getDisplayableValue($attribute, $actualValue), $message);\n        }\n\n        return $message;\n    }\n\n    /**\n     * Get the displayable name of the value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return string\n     */\n    public function getDisplayableValue($attribute, $value)\n    {\n        if (isset($this->customValues[$attribute][$value])) {\n            return $this->customValues[$attribute][$value];\n        }\n\n        if (is_array($value)) {\n            return 'array';\n        }\n\n        $key = \"validation.values.{$attribute}.{$value}\";\n\n        if (($line = $this->translator->get($key)) !== $key) {\n            return $line;\n        }\n\n        if (is_bool($value)) {\n            return $value ? 'true' : 'false';\n        }\n\n        if (is_null($value)) {\n            return 'empty';\n        }\n\n        return (string) $value;\n    }\n\n    /**\n     * Transform an array of attributes to their displayable form.\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function getAttributeList(array $values)\n    {\n        $attributes = [];\n\n        // For each attribute in the list we will simply get its displayable form as\n        // this is convenient when replacing lists of parameters like some of the\n        // replacement functions do when formatting out the validation message.\n        foreach ($values as $key => $value) {\n            $attributes[$key] = $this->getDisplayableAttribute($value);\n        }\n\n        return $attributes;\n    }\n\n    /**\n     * Call a custom validator message replacer.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array  $parameters\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return string|null\n     */\n    protected function callReplacer($message, $attribute, $rule, $parameters, $validator)\n    {\n        $callback = $this->replacers[$rule];\n\n        if ($callback instanceof Closure) {\n            return $callback(...func_get_args());\n        } elseif (is_string($callback)) {\n            return $this->callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters, $validator);\n        }\n    }\n\n    /**\n     * Call a class based validator message replacer.\n     *\n     * @param  string  $callback\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array  $parameters\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return string\n     */\n    protected function callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters, $validator)\n    {\n        [$class, $method] = Str::parseCallback($callback, 'replace');\n\n        return $this->container->make($class)->{$method}(...array_slice(func_get_args(), 1));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Concerns/ReplacesAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Concerns;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Str;\n\ntrait ReplacesAttributes\n{\n    /**\n     * Replace all place-holders for the accepted_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceAcceptedIf($message, $attribute, $rule, $parameters)\n    {\n        $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0]));\n\n        $parameters[0] = $this->getDisplayableAttribute($parameters[0]);\n\n        return $this->replaceWhileKeepingCase($message, ['other' => $parameters[0], 'value' => $parameters[1]]);\n    }\n\n    /**\n     * Replace all place-holders for the declined_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDeclinedIf($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceAcceptedIf($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the between rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceBetween($message, $attribute, $rule, $parameters)\n    {\n        return str_replace([':min', ':max'], $parameters, $message);\n    }\n\n    /**\n     * Replace all place-holders for the date_format rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDateFormat($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':format', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the decimal rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,int>  $parameters\n     * @return string\n     */\n    protected function replaceDecimal($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(\n            ':decimal',\n            isset($parameters[1])\n                ? $parameters[0].'-'.$parameters[1]\n                : $parameters[0],\n            $message\n        );\n    }\n\n    /**\n     * Replace all place-holders for the different rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDifferent($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceSame($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the digits rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDigits($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':digits', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the digits (between) rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDigitsBetween($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceBetween($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the encoding rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceEncoding($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':encoding', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the extensions rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceExtensions($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':values', implode(', ', $parameters), $message);\n    }\n\n    /**\n     * Replace all place-holders for the min rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMin($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':min', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the min digits rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMinDigits($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':min', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the max rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMax($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':max', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the max digits rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMaxDigits($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':max', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the missing_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMissingIf($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceAcceptedIf($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the missing_unless rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMissingUnless($message, $attribute, $rule, $parameters)\n    {\n        return str_replace([':other', ':value'], [\n            $this->getDisplayableAttribute($parameters[0]),\n            $this->getDisplayableValue($parameters[0], $parameters[1]),\n        ], $message);\n    }\n\n    /**\n     * Replace all place-holders for the missing_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMissingWith($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(\n            [':values', ':VALUES', ':Values'],\n            [\n                implode(' / ', $this->getAttributeList($parameters)),\n                Str::upper(implode(' / ', $this->getAttributeList($parameters))),\n                implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),\n            ],\n            $message\n        );\n    }\n\n    /**\n     * Replace all place-holders for the missing_with_all rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMissingWithAll($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceMissingWith($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the multiple_of rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMultipleOf($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':value', $parameters[0] ?? '', $message);\n    }\n\n    /**\n     * Replace all place-holders for the in rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceIn($message, $attribute, $rule, $parameters)\n    {\n        foreach ($parameters as &$parameter) {\n            $parameter = $this->getDisplayableValue($attribute, $parameter);\n        }\n\n        return str_replace(\n            [':values', ':VALUES', ':Values'],\n            [\n                implode(', ', $parameters),\n                Str::upper(implode(', ', $parameters)),\n                implode(', ', array_map(Str::ucfirst(...), $parameters)),\n            ],\n            $message,\n        );\n    }\n\n    /**\n     * Replace all place-holders for the not_in rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceNotIn($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the in_array rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceInArray($message, $attribute, $rule, $parameters)\n    {\n        $value = $this->getDisplayableAttribute($parameters[0]);\n\n        return $this->replaceWhileKeepingCase($message, ['other' => $value]);\n    }\n\n    /**\n     * Replace all place-holders for the in_array_keys rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceInArrayKeys($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_array_keys rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredArrayKeys($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the mimetypes rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMimetypes($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':values', implode(', ', $parameters), $message);\n    }\n\n    /**\n     * Replace all place-holders for the mimes rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceMimes($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':values', implode(', ', $parameters), $message);\n    }\n\n    /**\n     * Replace all place-holders for the present_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replacePresentIf($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceAcceptedIf($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the present_unless rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replacePresentUnless($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceMissingUnless($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the present_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replacePresentWith($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(\n            [':values', ':VALUES', ':Values'],\n            [\n                implode(' / ', $this->getAttributeList($parameters)),\n                Str::upper(implode(' / ', $this->getAttributeList($parameters))),\n                implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),\n            ],\n            $message,\n        );\n    }\n\n    /**\n     * Replace all place-holders for the present_with_all rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replacePresentWithAll($message, $attribute, $rule, $parameters)\n    {\n        return $this->replacePresentWith($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredWith($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(\n            [':values', ':VALUES', ':Values'],\n            [\n                implode(' / ', $this->getAttributeList($parameters)),\n                Str::upper(implode(' / ', $this->getAttributeList($parameters))),\n                implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),\n            ],\n            $message,\n        );\n    }\n\n    /**\n     * Replace all place-holders for the required_with_all rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredWithAll($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredWith($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_without rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredWithout($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredWith($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_without_all rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredWithoutAll($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredWith($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the size rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceSize($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(':size', $parameters[0], $message);\n    }\n\n    /**\n     * Replace all place-holders for the gt rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceGt($message, $attribute, $rule, $parameters)\n    {\n        if (is_null($value = $this->getValue($parameters[0]))) {\n            return str_replace(':value', $this->getDisplayableAttribute($parameters[0]), $message);\n        }\n\n        return str_replace(':value', $this->getSize($attribute, $value), $message);\n    }\n\n    /**\n     * Replace all place-holders for the lt rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceLt($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceGt($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the gte rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceGte($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceGt($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the lte rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceLte($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceGt($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredIf($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceAcceptedIf($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_if_accepted rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredIfAccepted($message, $attribute, $rule, $parameters)\n    {\n        $value = $this->getDisplayableAttribute($parameters[0]);\n\n        return $this->replaceWhileKeepingCase($message, ['other' => $value]);\n    }\n\n    /**\n     * Replace all place-holders for the required_if_declined rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredIfDeclined($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredIfAccepted($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the required_unless rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceRequiredUnless($message, $attribute, $rule, $parameters)\n    {\n        $other = $this->getDisplayableAttribute($parameters[0]);\n\n        $values = [];\n\n        foreach (array_slice($parameters, 1) as $value) {\n            $values[] = $this->getDisplayableValue($parameters[0], $value);\n        }\n\n        return str_replace(\n            [':other', ':OTHER', ':Other', ':values', ':VALUES', ':Values'],\n            [\n                $other,\n                Str::upper($other),\n                Str::ucfirst($other),\n                implode(', ', $values),\n                Str::upper(implode(', ', $values)),\n                implode(', ', array_map(Str::ucfirst(...), $values)),\n            ],\n            $message\n        );\n    }\n\n    /**\n     * Replace all place-holders for the prohibited_if rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceProhibitedIf($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceAcceptedIf($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the prohibited_if_accepted rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceProhibitedIfAccepted($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredIfAccepted($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the prohibited_if_declined rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceProhibitedIfDeclined($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredIfAccepted($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the prohibited_unless rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceProhibitedUnless($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceRequiredUnless($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the prohibited_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceProhibits($message, $attribute, $rule, $parameters)\n    {\n        return str_replace(\n            [':other', ':OTHER', ':Other'],\n            [\n                implode(' / ', $this->getAttributeList($parameters)),\n                Str::upper(implode(' / ', $this->getAttributeList($parameters))),\n                implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),\n            ],\n            $message\n        );\n    }\n\n    /**\n     * Replace all place-holders for the same rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceSame($message, $attribute, $rule, $parameters)\n    {\n        $value = $this->getDisplayableAttribute($parameters[0]);\n\n        return $this->replaceWhileKeepingCase($message, ['other' => $value]);\n    }\n\n    /**\n     * Replace all place-holders for the before rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceBefore($message, $attribute, $rule, $parameters)\n    {\n        if (! strtotime($parameters[0])) {\n            return str_replace(':date', $this->getDisplayableAttribute($parameters[0]), $message);\n        }\n\n        return str_replace(':date', $this->getDisplayableValue($attribute, $parameters[0]), $message);\n    }\n\n    /**\n     * Replace all place-holders for the before_or_equal rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceBeforeOrEqual($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceBefore($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the after rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceAfter($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceBefore($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the after_or_equal rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceAfterOrEqual($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceBefore($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the date_equals rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDateEquals($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceBefore($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the dimensions rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDimensions($message, $attribute, $rule, $parameters)\n    {\n        $parameters = $this->parseNamedParameters($parameters);\n\n        if (is_array($parameters)) {\n            foreach ($parameters as $key => $value) {\n                $message = str_replace(':'.$key, $value, $message);\n            }\n        }\n\n        return $message;\n    }\n\n    /**\n     * Replace all place-holders for the ends_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceEndsWith($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the doesnt_end_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDoesntEndWith($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the starts_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceStartsWith($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the doesnt_start_with rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDoesntStartWith($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace all place-holders for the doesnt_contain rule.\n     *\n     * @param  string  $message\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array<int,string>  $parameters\n     * @return string\n     */\n    protected function replaceDoesntContain($message, $attribute, $rule, $parameters)\n    {\n        return $this->replaceIn($message, $attribute, $rule, $parameters);\n    }\n\n    /**\n     * Replace the given string while maintaining different casing variants.\n     *\n     * @param  array<string, string>  $mapping\n     */\n    private function replaceWhileKeepingCase(string $message, array $mapping): string\n    {\n        $fn = [fn ($v) => $v, Str::upper(...), Str::ucfirst(...)];\n\n        $cases = array_reduce(\n            array_keys($mapping),\n            fn (array $carry, string $placeholder) => [...$carry, ...array_map(fn (callable $fn) => ':'.$fn($placeholder), $fn)],\n            [],\n        );\n\n        $replacements = array_reduce(\n            array_values($mapping),\n            fn (array $carry, string $parameter) => [...$carry, ...array_map(fn (callable $fn) => $fn($parameter), $fn)],\n            [],\n        );\n\n        return str_replace($cases, $replacements, $message);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Concerns/ValidatesAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Concerns;\n\nuse Brick\\Math\\BigDecimal;\nuse Brick\\Math\\BigNumber;\nuse Brick\\Math\\Exception\\MathException as BrickMathException;\nuse DateTime;\nuse DateTimeInterface;\nuse DateTimeZone;\nuse Egulias\\EmailValidator\\EmailValidator;\nuse Egulias\\EmailValidator\\Validation\\DNSCheckValidation;\nuse Egulias\\EmailValidator\\Validation\\Extra\\SpoofCheckValidation;\nuse Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd;\nuse Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation;\nuse Egulias\\EmailValidator\\Validation\\RFCValidation;\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Exceptions\\MathException;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Validation\\Rules\\Exists;\nuse Illuminate\\Validation\\Rules\\Unique;\nuse Illuminate\\Validation\\ValidationData;\nuse InvalidArgumentException;\nuse Symfony\\Component\\HttpFoundation\\File\\File;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile;\nuse ValueError;\n\ntrait ValidatesAttributes\n{\n    /**\n     * Validate that an attribute was \"accepted\".\n     *\n     * This validation rule implies the attribute is \"required\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateAccepted($attribute, $value)\n    {\n        $acceptable = ['yes', 'on', '1', 1, true, 'true'];\n\n        return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);\n    }\n\n    /**\n     * Validate that an attribute was \"accepted\" when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateAcceptedIf($attribute, $value, $parameters)\n    {\n        $acceptable = ['yes', 'on', '1', 1, true, 'true'];\n\n        $this->requireParameterCount(2, $parameters, 'accepted_if');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute was \"declined\".\n     *\n     * This validation rule implies the attribute is \"required\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateDeclined($attribute, $value)\n    {\n        $acceptable = ['no', 'off', '0', 0, false, 'false'];\n\n        return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);\n    }\n\n    /**\n     * Validate that an attribute was \"declined\" when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateDeclinedIf($attribute, $value, $parameters)\n    {\n        $acceptable = ['no', 'off', '0', 0, false, 'false'];\n\n        $this->requireParameterCount(2, $parameters, 'declined_if');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is an active URL.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateActiveUrl($attribute, $value)\n    {\n        if (! is_string($value)) {\n            return false;\n        }\n\n        if ($url = parse_url($value, PHP_URL_HOST)) {\n            try {\n                $records = $this->getDnsRecords($url.'.', DNS_A | DNS_AAAA);\n\n                if (is_array($records) && count($records) > 0) {\n                    return true;\n                }\n            } catch (Exception) {\n                return false;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the DNS records for the given hostname.\n     *\n     * @param  string  $hostname\n     * @param  int  $type\n     * @return array|false\n     */\n    protected function getDnsRecords($hostname, $type)\n    {\n        return dns_get_record($hostname, $type);\n    }\n\n    /**\n     * Validate that an attribute is 7 bit ASCII.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateAscii($attribute, $value)\n    {\n        return Str::isAscii($value);\n    }\n\n    /**\n     * \"Break\" on first validation fail.\n     *\n     * Always returns true, just lets us put \"bail\" in rules.\n     *\n     * @return bool\n     */\n    public function validateBail()\n    {\n        return true;\n    }\n\n    /**\n     * Validate the date is before a given date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateBefore($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'before');\n\n        return $this->compareDates($attribute, $value, $parameters, '<');\n    }\n\n    /**\n     * Validate the date is before or equal a given date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateBeforeOrEqual($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'before_or_equal');\n\n        return $this->compareDates($attribute, $value, $parameters, '<=');\n    }\n\n    /**\n     * Validate the date is after a given date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateAfter($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'after');\n\n        return $this->compareDates($attribute, $value, $parameters, '>');\n    }\n\n    /**\n     * Validate the date is equal or after a given date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateAfterOrEqual($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'after_or_equal');\n\n        return $this->compareDates($attribute, $value, $parameters, '>=');\n    }\n\n    /**\n     * Compare a given date against another using an operator.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @param  string  $operator\n     * @return bool\n     */\n    protected function compareDates($attribute, $value, $parameters, $operator)\n    {\n        if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) {\n            return false;\n        }\n\n        if ($format = $this->getDateFormat($attribute)) {\n            return $this->checkDateTimeOrder($format, $value, $parameters[0], $operator);\n        }\n\n        if (is_null($date = $this->getDateTimestamp($parameters[0]))) {\n            $date = $this->getDateTimestamp($this->getValue($parameters[0]));\n        }\n\n        return $this->compare($this->getDateTimestamp($value), $date, $operator);\n    }\n\n    /**\n     * Get the date format for an attribute if it has one.\n     *\n     * @param  string  $attribute\n     * @return string|null\n     */\n    protected function getDateFormat($attribute)\n    {\n        if ($result = $this->getRule($attribute, 'DateFormat')) {\n            return $result[1][0];\n        }\n    }\n\n    /**\n     * Get the date timestamp.\n     *\n     * @param  mixed  $value\n     * @return int|null\n     */\n    protected function getDateTimestamp($value)\n    {\n        $date = is_null($value) ? null : $this->getDateTime($value);\n\n        return $date?->getTimestamp();\n    }\n\n    /**\n     * Given two date/time strings, check that one is after the other.\n     *\n     * @param  string  $format\n     * @param  string  $first\n     * @param  string  $second\n     * @param  string  $operator\n     * @return bool\n     */\n    protected function checkDateTimeOrder($format, $first, $second, $operator)\n    {\n        $firstDate = $this->getDateTimeWithOptionalFormat($format, $first);\n\n        $format = $this->getDateFormat($second) ?: $format;\n\n        if (! $secondDate = $this->getDateTimeWithOptionalFormat($format, $second)) {\n            if (is_null($second = $this->getValue($second))) {\n                return true;\n            }\n\n            $secondDate = $this->getDateTimeWithOptionalFormat($format, $second);\n        }\n\n        return ($firstDate && $secondDate) && $this->compare($firstDate, $secondDate, $operator);\n    }\n\n    /**\n     * Get a DateTime instance from a string.\n     *\n     * @param  string  $format\n     * @param  string  $value\n     * @return \\DateTime|null\n     */\n    protected function getDateTimeWithOptionalFormat($format, $value)\n    {\n        if ($date = DateTime::createFromFormat('!'.$format, $value)) {\n            return $date;\n        }\n\n        return $this->getDateTime($value);\n    }\n\n    /**\n     * Get a DateTime instance from a string with no format.\n     *\n     * @param  string  $value\n     * @return \\DateTime|null\n     */\n    protected function getDateTime($value)\n    {\n        try {\n            return @Date::parse($value) ?: null;\n        } catch (Exception) {\n            //\n        }\n    }\n\n    /**\n     * Validate that an attribute contains only alphabetic characters.\n     * If the 'ascii' option is passed, validate that an attribute contains only ascii alphabetic characters.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateAlpha($attribute, $value, $parameters)\n    {\n        if (isset($parameters[0]) && $parameters[0] === 'ascii') {\n            return is_string($value) && preg_match('/\\A[a-zA-Z]+\\z/u', $value);\n        }\n\n        return is_string($value) && preg_match('/\\A[\\pL\\pM]+\\z/u', $value);\n    }\n\n    /**\n     * Validate that an attribute contains only alpha-numeric characters, dashes, and underscores.\n     * If the 'ascii' option is passed, validate that an attribute contains only ascii alpha-numeric characters,\n     * dashes, and underscores.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateAlphaDash($attribute, $value, $parameters)\n    {\n        if (! is_string($value) && ! is_numeric($value)) {\n            return false;\n        }\n\n        if (isset($parameters[0]) && $parameters[0] === 'ascii') {\n            return preg_match('/\\A[a-zA-Z0-9_-]+\\z/u', $value) > 0;\n        }\n\n        return preg_match('/\\A[\\pL\\pM\\pN_-]+\\z/u', $value) > 0;\n    }\n\n    /**\n     * Validate that an attribute contains only alpha-numeric characters.\n     * If the 'ascii' option is passed, validate that an attribute contains only ascii alpha-numeric characters.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateAlphaNum($attribute, $value, $parameters)\n    {\n        if (! is_string($value) && ! is_numeric($value)) {\n            return false;\n        }\n\n        if (isset($parameters[0]) && $parameters[0] === 'ascii') {\n            return preg_match('/\\A[a-zA-Z0-9]+\\z/u', $value) > 0;\n        }\n\n        return preg_match('/\\A[\\pL\\pM\\pN]+\\z/u', $value) > 0;\n    }\n\n    /**\n     * Validate that an attribute is an array.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateArray($attribute, $value, $parameters = [])\n    {\n        if (! is_array($value)) {\n            return false;\n        }\n\n        if (empty($parameters)) {\n            return true;\n        }\n\n        return empty(array_diff_key($value, array_fill_keys($parameters, '')));\n    }\n\n    /**\n     * Validate that an attribute is a list.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateList($attribute, $value)\n    {\n        return is_array($value) && array_is_list($value);\n    }\n\n    /**\n     * Validate that an array has all of the given keys.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateRequiredArrayKeys($attribute, $value, $parameters)\n    {\n        if (! is_array($value)) {\n            return false;\n        }\n\n        foreach ($parameters as $param) {\n            if (! Arr::exists($value, $param)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate the size of an attribute is between a set of values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateBetween($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'between');\n\n        try {\n            $size = BigNumber::of($this->getSize($attribute, $value));\n\n            return $size->isGreaterThanOrEqualTo($this->trim($parameters[0])) && $size->isLessThanOrEqualTo($this->trim($parameters[1]));\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute is a boolean.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array{0: 'strict'}  $parameters\n     * @return bool\n     */\n    public function validateBoolean($attribute, $value, $parameters)\n    {\n        $acceptable = [true, false, 0, 1, '0', '1'];\n\n        if (($parameters[0] ?? null) === 'strict') {\n            $acceptable = [true, false];\n        }\n\n        return in_array($value, $acceptable, true);\n    }\n\n    /**\n     * Validate that an attribute has a matching confirmation.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array{0: string}  $parameters\n     * @return bool\n     */\n    public function validateConfirmed($attribute, $value, $parameters)\n    {\n        return $this->validateSame($attribute, $value, [$parameters[0] ?? $attribute.'_confirmation']);\n    }\n\n    /**\n     * Validate an attribute contains a list of values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateContains($attribute, $value, $parameters)\n    {\n        if (! is_array($value)) {\n            return false;\n        }\n\n        foreach ($parameters as $parameter) {\n            if (! in_array($parameter, $value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate an attribute does not contain a list of values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDoesntContain($attribute, $value, $parameters)\n    {\n        if (! is_array($value)) {\n            return false;\n        }\n\n        foreach ($parameters as $parameter) {\n            if (in_array($parameter, $value)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that the password of the currently authenticated user matches the given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    protected function validateCurrentPassword($attribute, $value, $parameters)\n    {\n        $auth = $this->container->make('auth');\n        $hasher = $this->container->make('hash');\n\n        $guard = $auth->guard(Arr::first($parameters));\n\n        if ($guard->guest()) {\n            return false;\n        }\n\n        return $hasher->check($value, $guard->user()->getAuthPassword());\n    }\n\n    /**\n     * Validate that an attribute is a valid date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateDate($attribute, $value)\n    {\n        if ($value instanceof DateTimeInterface) {\n            return true;\n        }\n\n        try {\n            if ((! is_string($value) && ! is_numeric($value)) || strtotime($value) === false) {\n                return false;\n            }\n        } catch (Exception) {\n            return false;\n        }\n\n        $date = date_parse($value);\n\n        return checkdate($date['month'], $date['day'], $date['year']);\n    }\n\n    /**\n     * Validate that an attribute matches a date format.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDateFormat($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'date_format');\n\n        if (! is_string($value) && ! is_numeric($value)) {\n            return false;\n        }\n\n        foreach ($parameters as $format) {\n            try {\n                $date = DateTime::createFromFormat('!'.$format, $value, new DateTimeZone('UTC'));\n\n                if ($date && $date->format($format) == $value) {\n                    return true;\n                }\n            } catch (ValueError) {\n                return false;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Validate that an attribute is equal to another date.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDateEquals($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'date_equals');\n\n        return $this->compareDates($attribute, $value, $parameters, '=');\n    }\n\n    /**\n     * Validate that an attribute has a given number of decimal places.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDecimal($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'decimal');\n\n        if (! $this->validateNumeric($attribute, $value, [])) {\n            return false;\n        }\n\n        $matches = [];\n\n        if (preg_match('/^[+-]?\\d*\\.?(\\d*)$/', $value, $matches) !== 1) {\n            return false;\n        }\n\n        $decimals = strlen(end($matches));\n\n        if (! isset($parameters[1])) {\n            return $decimals == $parameters[0];\n        }\n\n        return $decimals >= $parameters[0] &&\n               $decimals <= $parameters[1];\n    }\n\n    /**\n     * Validate that an attribute is different from another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDifferent($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'different');\n\n        foreach ($parameters as $parameter) {\n            if (Arr::has($this->data, $parameter)) {\n                $other = Arr::get($this->data, $parameter);\n\n                if ($value === $other) {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute has a given number of digits.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDigits($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'digits');\n\n        return (is_numeric($value) || is_string($value)) &&\n            ! preg_match('/[^0-9]/', $value) &&\n            strlen((string) $value) == $parameters[0];\n    }\n\n    /**\n     * Validate that an attribute is between a given number of digits.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDigitsBetween($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'digits_between');\n\n        $length = strlen((string) $value);\n\n        return ! preg_match('/[^0-9]/', $value)\n                    && $length >= $parameters[0] && $length <= $parameters[1];\n    }\n\n    /**\n     * Validate the dimensions of an image matches the given values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDimensions($attribute, $value, $parameters)\n    {\n        if ($this->isValidFileInstance($value) && in_array($value->getMimeType(), ['image/svg+xml', 'image/svg'])) {\n            return true;\n        }\n\n        if (! $this->isValidFileInstance($value)) {\n            return false;\n        }\n\n        $dimensions = method_exists($value, 'dimensions')\n            ? $value->dimensions()\n            : @getimagesize($value->getRealPath());\n\n        if (! $dimensions) {\n            return false;\n        }\n\n        $this->requireParameterCount(1, $parameters, 'dimensions');\n\n        [$width, $height] = $dimensions;\n\n        $parameters = $this->parseNamedParameters($parameters);\n\n        return ! (\n            $this->failsBasicDimensionChecks($parameters, $width, $height) ||\n            $this->failsRatioCheck($parameters, $width, $height) ||\n            $this->failsMinRatioCheck($parameters, $width, $height) ||\n            $this->failsMaxRatioCheck($parameters, $width, $height)\n        );\n    }\n\n    /**\n     * Test if the given width and height fail any conditions.\n     *\n     * @param  array<string,string>  $parameters\n     * @param  int  $width\n     * @param  int  $height\n     * @return bool\n     */\n    protected function failsBasicDimensionChecks($parameters, $width, $height)\n    {\n        return (isset($parameters['width']) && $parameters['width'] != $width) ||\n               (isset($parameters['min_width']) && $parameters['min_width'] > $width) ||\n               (isset($parameters['max_width']) && $parameters['max_width'] < $width) ||\n               (isset($parameters['height']) && $parameters['height'] != $height) ||\n               (isset($parameters['min_height']) && $parameters['min_height'] > $height) ||\n               (isset($parameters['max_height']) && $parameters['max_height'] < $height);\n    }\n\n    /**\n     * Determine if the given parameters fail a dimension ratio check.\n     *\n     * @param  array<string,string>  $parameters\n     * @param  int  $width\n     * @param  int  $height\n     * @return bool\n     */\n    protected function failsRatioCheck($parameters, $width, $height)\n    {\n        if (! isset($parameters['ratio'])) {\n            return false;\n        }\n\n        [$numerator, $denominator] = array_replace(\n            [1, 1], array_filter(sscanf($parameters['ratio'], '%f/%d'))\n        );\n\n        $precision = 1 / (max(($width + $height) / 2, $height) + 1);\n\n        return abs($numerator / $denominator - $width / $height) > $precision;\n    }\n\n    /**\n     * Determine if the given parameters fail a dimension minimum ratio check.\n     *\n     * @param  array<string,string>  $parameters\n     * @param  int  $width\n     * @param  int  $height\n     * @return bool\n     */\n    private function failsMinRatioCheck($parameters, $width, $height)\n    {\n        if (! isset($parameters['min_ratio'])) {\n            return false;\n        }\n\n        [$minNumerator, $minDenominator] = array_replace(\n            [1, 1], array_filter(sscanf($parameters['min_ratio'], '%f/%d'))\n        );\n\n        return ($width / $height) > ($minNumerator / $minDenominator);\n    }\n\n    /**\n     * Determine if the given parameters fail a dimension maximum ratio check.\n     *\n     * @param  array<string,string>  $parameters\n     * @param  int  $width\n     * @param  int  $height\n     * @return bool\n     */\n    private function failsMaxRatioCheck($parameters, $width, $height)\n    {\n        if (! isset($parameters['max_ratio'])) {\n            return false;\n        }\n\n        [$maxNumerator, $maxDenominator] = array_replace(\n            [1, 1], array_filter(sscanf($parameters['max_ratio'], '%f/%d'))\n        );\n\n        return ($width / $height) < ($maxNumerator / $maxDenominator);\n    }\n\n    /**\n     * Validate an attribute is unique among other values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDistinct($attribute, $value, $parameters)\n    {\n        $data = Arr::except($this->getDistinctValues($attribute), $attribute);\n\n        if (in_array('ignore_case', $parameters)) {\n            return empty(preg_grep('/^'.preg_quote($value, '/').'$/iu', $data));\n        }\n\n        return ! in_array($value, array_values($data), in_array('strict', $parameters));\n    }\n\n    /**\n     * Get the values to distinct between.\n     *\n     * @param  string  $attribute\n     * @return array\n     */\n    protected function getDistinctValues($attribute)\n    {\n        $attributeName = $this->getPrimaryAttribute($attribute);\n\n        if (! property_exists($this, 'distinctValues')) {\n            return $this->extractDistinctValues($attributeName);\n        }\n\n        if (! array_key_exists($attributeName, $this->distinctValues)) {\n            $this->distinctValues[$attributeName] = $this->extractDistinctValues($attributeName);\n        }\n\n        return $this->distinctValues[$attributeName];\n    }\n\n    /**\n     * Extract the distinct values from the data.\n     *\n     * @param  string  $attribute\n     * @return array\n     */\n    protected function extractDistinctValues($attribute)\n    {\n        $attributeData = ValidationData::extractDataFromPath(\n            ValidationData::getLeadingExplicitAttributePath($attribute), $this->data\n        );\n\n        $pattern = str_replace('\\*', '[^.]+', preg_quote($attribute, '#'));\n\n        return Arr::where(Arr::dot($attributeData), function ($value, $key) use ($pattern) {\n            return (bool) preg_match('#^'.$pattern.'\\z#u', $key);\n        });\n    }\n\n    /**\n     * Validate that an attribute is a valid e-mail address.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateEmail($attribute, $value, $parameters)\n    {\n        if (! is_string($value) && ! (is_object($value) && method_exists($value, '__toString'))) {\n            return false;\n        }\n\n        $validations = (new Collection($parameters))\n            ->unique()\n            ->map(fn ($validation) => match (true) {\n                $validation === 'strict' => new NoRFCWarningsValidation(),\n                $validation === 'dns' => new DNSCheckValidation(),\n                $validation === 'spoof' => new SpoofCheckValidation(),\n                $validation === 'filter' => new FilterEmailValidation(),\n                $validation === 'filter_unicode' => FilterEmailValidation::unicode(),\n                is_string($validation) && class_exists($validation) => $this->container->make($validation),\n                default => new RFCValidation(),\n            })\n            ->values()\n            ->all() ?: [new RFCValidation];\n\n        $emailValidator = Container::getInstance()->make(EmailValidator::class);\n\n        return $emailValidator->isValid($value, new MultipleValidationWithAnd($validations));\n    }\n\n    /**\n     * Validate the encoding of an attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function validateEncoding($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'encoding');\n\n        if (! in_array(mb_strtolower($parameters[0]), array_map(mb_strtolower(...), mb_list_encodings()))) {\n            throw new InvalidArgumentException(\"Validation rule encoding parameter [{$parameters[0]}] is not a valid encoding.\");\n        }\n\n        return mb_check_encoding($value instanceof File ? $value->getContent() : $value, $parameters[0]);\n    }\n\n    /**\n     * Validate the existence of an attribute value in a database table.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateExists($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'exists');\n\n        [$connection, $table] = $this->parseTable($parameters[0]);\n\n        // The second parameter position holds the name of the column that should be\n        // verified as existing. If this parameter is not specified we will guess\n        // that the columns being \"verified\" shares the given attribute's name.\n        $column = $this->getQueryColumn($parameters, $attribute);\n\n        $expected = is_array($value) ? count(array_unique($value)) : 1;\n\n        if ($expected === 0) {\n            return true;\n        }\n\n        return $this->getExistCount(\n            $connection, $table, $column, $value, $parameters\n        ) >= $expected;\n    }\n\n    /**\n     * Get the number of records that exist in storage.\n     *\n     * @param  mixed  $connection\n     * @param  string  $table\n     * @param  string  $column\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return int\n     */\n    protected function getExistCount($connection, $table, $column, $value, $parameters)\n    {\n        $verifier = $this->getPresenceVerifier($connection);\n\n        $extra = $this->getExtraConditions(\n            array_values(array_slice($parameters, 2))\n        );\n\n        if ($this->currentRule instanceof Exists) {\n            $extra = array_merge($extra, $this->currentRule->queryCallbacks());\n        }\n\n        return is_array($value)\n            ? $verifier->getMultiCount($table, $column, $value, $extra)\n            : $verifier->getCount($table, $column, $value, null, null, $extra);\n    }\n\n    /**\n     * Validate the uniqueness of an attribute value on a given database table.\n     *\n     * If a database column is not specified, the attribute will be used.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateUnique($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'unique');\n\n        [$connection, $table, $idColumn] = $this->parseTable($parameters[0]);\n\n        // The second parameter position holds the name of the column that needs to\n        // be verified as unique. If this parameter isn't specified we will just\n        // assume that this column to be verified shares the attribute's name.\n        $column = $this->getQueryColumn($parameters, $attribute);\n\n        $id = null;\n\n        if (isset($parameters[2])) {\n            [$idColumn, $id] = $this->getUniqueIds($idColumn, $parameters);\n\n            if (! is_null($id)) {\n                $id = stripslashes($id);\n            }\n        }\n\n        // The presence verifier is responsible for counting rows within this store\n        // mechanism which might be a relational database or any other permanent\n        // data store like Redis, etc. We will use it to determine uniqueness.\n        $verifier = $this->getPresenceVerifier($connection);\n\n        $extra = $this->getUniqueExtra($parameters);\n\n        if ($this->currentRule instanceof Unique) {\n            $extra = array_merge($extra, $this->currentRule->queryCallbacks());\n        }\n\n        return $verifier->getCount(\n            $table, $column, $value, $id, $idColumn, $extra\n        ) == 0;\n    }\n\n    /**\n     * Get the excluded ID column and value for the unique rule.\n     *\n     * @param  string|null  $idColumn\n     * @param  array<int, int|string>  $parameters\n     * @return array\n     */\n    protected function getUniqueIds($idColumn, $parameters)\n    {\n        $idColumn ??= $parameters[3] ?? 'id';\n\n        return [$idColumn, $this->prepareUniqueId($parameters[2])];\n    }\n\n    /**\n     * Prepare the given ID for querying.\n     *\n     * @param  mixed  $id\n     * @return int\n     */\n    protected function prepareUniqueId($id)\n    {\n        if (preg_match('/\\[(.*)\\]/', $id, $matches)) {\n            $id = $this->getValue($matches[1]);\n        }\n\n        if (strtolower($id) === 'null') {\n            $id = null;\n        }\n\n        if (filter_var($id, FILTER_VALIDATE_INT) !== false) {\n            $id = (int) $id;\n        }\n\n        return $id;\n    }\n\n    /**\n     * Get the extra conditions for a unique rule.\n     *\n     * @param  array<int, int|string>  $parameters\n     * @return array\n     */\n    protected function getUniqueExtra($parameters)\n    {\n        if (isset($parameters[4])) {\n            return $this->getExtraConditions(array_slice($parameters, 4));\n        }\n\n        return [];\n    }\n\n    /**\n     * Parse the connection / table for the unique / exists rules.\n     *\n     * @param  string  $table\n     * @return array\n     */\n    public function parseTable($table)\n    {\n        [$connection, $table] = str_contains($table, '.') ? explode('.', $table, 2) : [null, $table];\n\n        if (str_contains($table, '\\\\') && class_exists($table) && is_a($table, Model::class, true)) {\n            $model = new $table;\n\n            $table = $model->getTable();\n            $connection ??= $model->getConnectionName();\n\n            if (str_contains($table, '.') && Str::startsWith($table, $connection)) {\n                $connection = null;\n            }\n\n            $idColumn = $model->getKeyName();\n        }\n\n        return [$connection, $table, $idColumn ?? null];\n    }\n\n    /**\n     * Get the column name for an exists / unique query.\n     *\n     * @param  array<int, int|string>  $parameters\n     * @param  string  $attribute\n     * @return int|string\n     */\n    public function getQueryColumn($parameters, $attribute)\n    {\n        return isset($parameters[1]) && $parameters[1] !== 'NULL'\n            ? $parameters[1]\n            : $this->guessColumnForQuery($attribute);\n    }\n\n    /**\n     * Guess the database column from the given attribute name.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    public function guessColumnForQuery($attribute)\n    {\n        if (in_array($attribute, Arr::collapse($this->implicitAttributes))\n                && ! is_numeric($last = last(explode('.', $attribute)))) {\n            return $last;\n        }\n\n        return $attribute;\n    }\n\n    /**\n     * Get the extra conditions for a unique / exists rule.\n     *\n     * @param  array  $segments\n     * @return array\n     */\n    protected function getExtraConditions(array $segments)\n    {\n        $extra = [];\n\n        $count = count($segments);\n\n        for ($i = 0; $i < $count; $i += 2) {\n            $extra[$segments[$i]] = $segments[$i + 1];\n        }\n\n        return $extra;\n    }\n\n    /**\n     * Validate the extension of a file upload attribute is in a set of defined extensions.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateExtensions($attribute, $value, $parameters)\n    {\n        if (! $this->isValidFileInstance($value)) {\n            return false;\n        }\n\n        if ($this->shouldBlockPhpUpload($value, $parameters)) {\n            return false;\n        }\n\n        return in_array(strtolower($value->getClientOriginalExtension()), $parameters);\n    }\n\n    /**\n     * Validate the given value is a valid file.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateFile($attribute, $value)\n    {\n        return $this->isValidFileInstance($value);\n    }\n\n    /**\n     * Validate the given attribute is filled if it is present.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateFilled($attribute, $value)\n    {\n        if (Arr::has($this->data, $attribute)) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is greater than another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateGt($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'gt');\n\n        $comparedToValue = $this->getValue($parameters[0]);\n\n        $this->shouldBeNumeric($attribute, 'Gt');\n\n        if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) {\n            try {\n                return BigNumber::of($this->getSize($attribute, $value))->isGreaterThan($this->trim($parameters[0]));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (is_numeric($parameters[0])) {\n            return false;\n        }\n\n        if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) {\n            try {\n                return BigNumber::of($this->trim($value))->isGreaterThan($this->trim($comparedToValue));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (! $this->isSameType($value, $comparedToValue)) {\n            return false;\n        }\n\n        try {\n            return $this->getSize($attribute, $value) > $this->getSize($attribute, $comparedToValue);\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute is less than another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateLt($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'lt');\n\n        $comparedToValue = $this->getValue($parameters[0]);\n\n        $this->shouldBeNumeric($attribute, 'Lt');\n\n        if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) {\n            try {\n                return BigNumber::of($this->getSize($attribute, $value))->isLessThan($this->trim($parameters[0]));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (is_numeric($parameters[0])) {\n            return false;\n        }\n\n        if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) {\n            return BigNumber::of($this->trim($value))->isLessThan($this->trim($comparedToValue));\n        }\n\n        if (! $this->isSameType($value, $comparedToValue)) {\n            return false;\n        }\n\n        try {\n            return $this->getSize($attribute, $value) < $this->getSize($attribute, $comparedToValue);\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute is greater than or equal another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateGte($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'gte');\n\n        $comparedToValue = $this->getValue($parameters[0]);\n\n        $this->shouldBeNumeric($attribute, 'Gte');\n\n        if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) {\n            try {\n                return BigNumber::of($this->getSize($attribute, $value))->isGreaterThanOrEqualTo($this->trim($parameters[0]));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (is_numeric($parameters[0])) {\n            return false;\n        }\n\n        if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) {\n            try {\n                return BigNumber::of($this->trim($value))->isGreaterThanOrEqualTo($this->trim($comparedToValue));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (! $this->isSameType($value, $comparedToValue)) {\n            return false;\n        }\n\n        try {\n            return $this->getSize($attribute, $value) >= $this->getSize($attribute, $comparedToValue);\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute is less than or equal another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateLte($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'lte');\n\n        $comparedToValue = $this->getValue($parameters[0]);\n\n        $this->shouldBeNumeric($attribute, 'Lte');\n\n        if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) {\n            try {\n                return BigNumber::of($this->getSize($attribute, $value))->isLessThanOrEqualTo($this->trim($parameters[0]));\n            } catch (MathException) {\n                return false;\n            }\n        }\n\n        if (is_numeric($parameters[0])) {\n            return false;\n        }\n\n        if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) {\n            return BigNumber::of($this->trim($value))->isLessThanOrEqualTo($this->trim($comparedToValue));\n        }\n\n        if (! $this->isSameType($value, $comparedToValue)) {\n            return false;\n        }\n\n        try {\n            return $this->getSize($attribute, $value) <= $this->getSize($attribute, $comparedToValue);\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute is lowercase.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateLowercase($attribute, $value, $parameters)\n    {\n        return Str::lower($value) === $value;\n    }\n\n    /**\n     * Validate that an attribute is uppercase.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateUppercase($attribute, $value, $parameters)\n    {\n        return Str::upper($value) === $value;\n    }\n\n    /**\n     * Validate that an attribute is a valid HEX color.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateHexColor($attribute, $value)\n    {\n        return preg_match('/^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i', $value) === 1;\n    }\n\n    /**\n     * Validate the MIME type of a file is an image MIME type.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, string>  $parameters\n     * @return bool\n     */\n    public function validateImage($attribute, $value, $parameters = [])\n    {\n        $mimes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];\n\n        if (is_array($parameters) && in_array('allow_svg', $parameters)) {\n            $mimes[] = 'svg';\n        }\n\n        return $this->validateMimes($attribute, $value, $mimes);\n    }\n\n    /**\n     * Validate an attribute is contained within a list of values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateIn($attribute, $value, $parameters)\n    {\n        if (is_array($value) && $this->hasRule($attribute, 'Array')) {\n            foreach ($value as $element) {\n                if (is_array($element)) {\n                    return false;\n                }\n            }\n\n            return count(array_diff($value, $parameters)) === 0;\n        }\n\n        return ! is_array($value) && in_array((string) $value, $parameters);\n    }\n\n    /**\n     * Validate that the values of an attribute are in another attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateInArray($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'in_array');\n\n        $explicitPath = ValidationData::getLeadingExplicitAttributePath($parameters[0]);\n\n        $attributeData = ValidationData::extractDataFromPath($explicitPath, $this->data);\n\n        $otherValues = Arr::where(Arr::dot($attributeData), function ($value, $key) use ($parameters) {\n            return Str::is($parameters[0], $key);\n        });\n\n        return in_array($value, $otherValues);\n    }\n\n    /**\n     * Validate that an array has at least one of the given keys.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateInArrayKeys($attribute, $value, $parameters)\n    {\n        if (! is_array($value)) {\n            return false;\n        }\n\n        if (empty($parameters)) {\n            return false;\n        }\n\n        foreach ($parameters as $param) {\n            if (Arr::exists($value, $param)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Validate that an attribute is an integer.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array{0?: 'strict'}  $parameters\n     * @return bool\n     */\n    public function validateInteger($attribute, $value, array $parameters = [])\n    {\n        if (($parameters[0] ?? null) === 'strict') {\n            return is_int($value);\n        }\n\n        return filter_var($value, FILTER_VALIDATE_INT) !== false;\n    }\n\n    /**\n     * Validate that an attribute is a valid IP.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateIp($attribute, $value)\n    {\n        return filter_var($value, FILTER_VALIDATE_IP) !== false;\n    }\n\n    /**\n     * Validate that an attribute is a valid IPv4.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateIpv4($attribute, $value)\n    {\n        return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;\n    }\n\n    /**\n     * Validate that an attribute is a valid IPv6.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateIpv6($attribute, $value)\n    {\n        return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;\n    }\n\n    /**\n     * Validate that an attribute is a valid MAC address.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateMacAddress($attribute, $value)\n    {\n        return filter_var($value, FILTER_VALIDATE_MAC) !== false;\n    }\n\n    /**\n     * Validate the attribute is a valid JSON string.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateJson($attribute, $value)\n    {\n        if (is_array($value) || is_null($value)) {\n            return false;\n        }\n\n        if (! is_scalar($value) && ! method_exists($value, '__toString')) {\n            return false;\n        }\n\n        return json_validate($value);\n    }\n\n    /**\n     * Validate the size of an attribute is less than or equal to a maximum value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMax($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'max');\n\n        if ($value instanceof UploadedFile && ! $value->isValid()) {\n            return false;\n        }\n\n        try {\n            return BigNumber::of($this->getSize($attribute, $value))->isLessThanOrEqualTo($this->trim($parameters[0]));\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute has a maximum number of digits.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMaxDigits($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'max_digits');\n\n        $length = strlen((string) $value);\n\n        return ! preg_match('/[^0-9]/', $value) && $length <= $parameters[0];\n    }\n\n    /**\n     * Validate the guessed extension of a file upload is in a set of file extensions.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMimes($attribute, $value, $parameters)\n    {\n        if (! $this->isValidFileInstance($value)) {\n            return false;\n        }\n\n        if ($this->shouldBlockPhpUpload($value, $parameters)) {\n            return false;\n        }\n\n        if (in_array('jpg', $parameters) || in_array('jpeg', $parameters)) {\n            $parameters = array_unique(array_merge($parameters, ['jpg', 'jpeg']));\n        }\n\n        return $value->getPath() !== '' && in_array($value->guessExtension(), $parameters);\n    }\n\n    /**\n     * Validate the MIME type of a file upload attribute is in a set of MIME types.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMimetypes($attribute, $value, $parameters)\n    {\n        if (! $this->isValidFileInstance($value)) {\n            return false;\n        }\n\n        if ($this->shouldBlockPhpUpload($value, $parameters)) {\n            return false;\n        }\n\n        return $value->getPath() !== '' &&\n                (in_array($value->getMimeType(), $parameters) ||\n                 in_array(explode('/', $value->getMimeType())[0].'/*', $parameters));\n    }\n\n    /**\n     * Check if PHP uploads are explicitly allowed.\n     *\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    protected function shouldBlockPhpUpload($value, $parameters)\n    {\n        if (in_array('php', $parameters)) {\n            return false;\n        }\n\n        $phpExtensions = [\n            'php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar',\n        ];\n\n        return ($value instanceof UploadedFile)\n            ? in_array(trim(strtolower($value->getClientOriginalExtension())), $phpExtensions)\n            : in_array(trim(strtolower($value->getExtension())), $phpExtensions);\n    }\n\n    /**\n     * Validate the size of an attribute is greater than or equal to a minimum value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMin($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'min');\n\n        try {\n            return BigNumber::of($this->getSize($attribute, $value))->isGreaterThanOrEqualTo($this->trim($parameters[0]));\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * Validate that an attribute has a minimum number of digits.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMinDigits($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'min_digits');\n\n        $length = strlen((string) $value);\n\n        return ! preg_match('/[^0-9]/', $value) && $length >= $parameters[0];\n    }\n\n    /**\n     * Validate that an attribute is missing.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMissing($attribute, $value, $parameters)\n    {\n        return ! Arr::has($this->data, $attribute);\n    }\n\n    /**\n     * Validate that an attribute is missing when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMissingIf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'missing_if');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateMissing($attribute, $value, $parameters);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is missing unless another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMissingUnless($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'missing_unless');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (! in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateMissing($attribute, $value, $parameters);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is missing when any given attribute is present.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMissingWith($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'missing_with');\n\n        if (Arr::hasAny($this->data, $parameters)) {\n            return $this->validateMissing($attribute, $value, $parameters);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is missing when all given attributes are present.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateMissingWithAll($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'missing_with_all');\n\n        if (Arr::has($this->data, $parameters)) {\n            return $this->validateMissing($attribute, $value, $parameters);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate the value of an attribute is a multiple of a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     *\n     * @throws \\Illuminate\\Support\\Exceptions\\MathException\n     */\n    public function validateMultipleOf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'multiple_of');\n\n        if (! $this->validateNumeric($attribute, $value, []) || ! $this->validateNumeric($attribute, $parameters[0], [])) {\n            return false;\n        }\n\n        try {\n            $numerator = BigDecimal::of($this->trim($value));\n            $denominator = BigDecimal::of($this->trim($parameters[0]));\n\n            if ($numerator->isZero() && $denominator->isZero()) {\n                return false;\n            }\n\n            if ($numerator->isZero()) {\n                return true;\n            }\n\n            if ($denominator->isZero()) {\n                return false;\n            }\n\n            return $numerator->remainder($denominator)->isZero();\n        } catch (BrickMathException $e) {\n            throw new MathException('An error occurred while handling the multiple_of input values.', previous: $e);\n        }\n    }\n\n    /**\n     * \"Indicate\" validation should pass if value is null.\n     *\n     * Always returns true, just lets us put \"nullable\" in rules.\n     *\n     * @return bool\n     */\n    public function validateNullable()\n    {\n        return true;\n    }\n\n    /**\n     * Validate an attribute is not contained within a list of values.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateNotIn($attribute, $value, $parameters)\n    {\n        return ! $this->validateIn($attribute, $value, $parameters);\n    }\n\n    /**\n     * Validate that an attribute is numeric.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array{0: 'strict'}  $parameters\n     * @return bool\n     */\n    public function validateNumeric($attribute, $value, array $parameters)\n    {\n        if (($parameters[0] ?? null) === 'strict' && is_string($value)) {\n            return false;\n        }\n\n        return is_numeric($value);\n    }\n\n    /**\n     * Validate that an attribute exists even if not filled.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validatePresent($attribute, $value)\n    {\n        return Arr::has($this->data, $attribute);\n    }\n\n    /**\n     * Validate that an attribute is present when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validatePresentIf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'present_if');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validatePresent($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is present unless another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validatePresentUnless($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'present_unless');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (! in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validatePresent($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is present when any given attribute is present.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validatePresentWith($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'present_with');\n\n        if (Arr::hasAny($this->data, $parameters)) {\n            return $this->validatePresent($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute is present when all given attributes are present.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validatePresentWithAll($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'present_with_all');\n\n        if (Arr::has($this->data, $parameters)) {\n            return $this->validatePresent($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute passes a regular expression check.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateRegex($attribute, $value, $parameters)\n    {\n        if (! is_string($value) && ! is_numeric($value)) {\n            return false;\n        }\n\n        $this->requireParameterCount(1, $parameters, 'regex');\n\n        return preg_match($parameters[0], $value) > 0;\n    }\n\n    /**\n     * Validate that an attribute does not pass a regular expression check.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateNotRegex($attribute, $value, $parameters)\n    {\n        if (! is_string($value) && ! is_numeric($value)) {\n            return false;\n        }\n\n        $this->requireParameterCount(1, $parameters, 'not_regex');\n\n        return preg_match($parameters[0], $value) < 1;\n    }\n\n    /**\n     * Validate that a required attribute exists.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateRequired($attribute, $value)\n    {\n        if (is_null($value)) {\n            return false;\n        } elseif (is_string($value) && trim($value) === '') {\n            return false;\n        } elseif (is_countable($value) && count($value) < 1) {\n            return false;\n        } elseif ($value instanceof File) {\n            return (string) $value->getPath() !== '';\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredIf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'required_if');\n\n        if (! Arr::has($this->data, $parameters[0])) {\n            return true;\n        }\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when another attribute was \"accepted\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredIfAccepted($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'required_if_accepted');\n\n        if ($this->validateAccepted($parameters[0], $this->getValue($parameters[0]))) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when another attribute was \"declined\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredIfDeclined($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'required_if_declined');\n\n        if ($this->validateDeclined($parameters[0], $this->getValue($parameters[0]))) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute does not exist or is an empty string.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateProhibited($attribute, $value)\n    {\n        return ! $this->validateRequired($attribute, $value);\n    }\n\n    /**\n     * Validate that an attribute does not exist when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateProhibitedIf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'prohibited_if');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (in_array($other, $values, is_bool($other) || is_null($other))) {\n            return ! $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute does not exist when another attribute was \"accepted\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateProhibitedIfAccepted($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'prohibited_if_accepted');\n\n        if ($this->validateAccepted($parameters[0], $this->getValue($parameters[0]))) {\n            return $this->validateProhibited($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute does not exist when another attribute was \"declined\".\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateProhibitedIfDeclined($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'prohibited_if_declined');\n\n        if ($this->validateDeclined($parameters[0], $this->getValue($parameters[0]))) {\n            return $this->validateProhibited($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute does not exist unless another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateProhibitedUnless($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'prohibited_unless');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (! in_array($other, $values, is_bool($other) || is_null($other))) {\n            return ! $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that other attributes do not exist when this attribute exists.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateProhibits($attribute, $value, $parameters)\n    {\n        if ($this->validateRequired($attribute, $value)) {\n            foreach ($parameters as $parameter) {\n                if ($this->validateRequired($parameter, Arr::get($this->data, $parameter))) {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Indicate that an attribute is excluded.\n     *\n     * @return bool\n     */\n    public function validateExclude()\n    {\n        return false;\n    }\n\n    /**\n     * Indicate that an attribute should be excluded when another attribute has a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateExcludeIf($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'exclude_if');\n\n        if (! Arr::has($this->data, $parameters[0])) {\n            return true;\n        }\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        return ! in_array($other, $values, is_bool($other) || is_null($other));\n    }\n\n    /**\n     * Indicate that an attribute should be excluded when another attribute does not have a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateExcludeUnless($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'exclude_unless');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        return in_array($other, $values, is_bool($other) || is_null($other));\n    }\n\n    /**\n     * Validate that an attribute exists when another attribute does not have a given value.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredUnless($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(2, $parameters, 'required_unless');\n\n        [$values, $other] = $this->parseDependentRuleParameters($parameters);\n\n        if (! in_array($other, $values, is_bool($other) || is_null($other))) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Indicate that an attribute should be excluded when another attribute presents.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateExcludeWith($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'exclude_with');\n\n        if (! Arr::has($this->data, $parameters[0])) {\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Indicate that an attribute should be excluded when another attribute is missing.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateExcludeWithout($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'exclude_without');\n\n        if ($this->anyFailingRequired($parameters)) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Prepare the values and the other value for validation.\n     *\n     * @param  array<int, int|string>  $parameters\n     * @return array\n     */\n    public function parseDependentRuleParameters($parameters)\n    {\n        $other = Arr::get($this->data, $parameters[0]);\n\n        $values = array_slice($parameters, 1);\n\n        if ($this->shouldConvertToBoolean($parameters[0]) || is_bool($other)) {\n            $values = $this->convertValuesToBoolean($values);\n        }\n\n        if (is_null($other)) {\n            $values = $this->convertValuesToNull($values);\n        }\n\n        return [$values, $other];\n    }\n\n    /**\n     * Check if parameter should be converted to boolean.\n     *\n     * @param  string  $parameter\n     * @return bool\n     */\n    protected function shouldConvertToBoolean($parameter)\n    {\n        return in_array('boolean', $this->rules[$parameter] ?? []);\n    }\n\n    /**\n     * Convert the given values to boolean if they are string \"true\" / \"false\".\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function convertValuesToBoolean($values)\n    {\n        return array_map(fn ($value) => match ($value) {\n            'true' => true,\n            'false' => false,\n            default => $value,\n        }, $values);\n    }\n\n    /**\n     * Convert the given values to null if they are string \"null\".\n     *\n     * @param  array  $values\n     * @return array\n     */\n    protected function convertValuesToNull($values)\n    {\n        return array_map(function ($value) {\n            return Str::lower($value) === 'null' ? null : $value;\n        }, $values);\n    }\n\n    /**\n     * Validate that an attribute exists when any other attribute exists.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredWith($attribute, $value, $parameters)\n    {\n        if (! $this->allFailingRequired($parameters)) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when all other attributes exist.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredWithAll($attribute, $value, $parameters)\n    {\n        if (! $this->anyFailingRequired($parameters)) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when another attribute does not.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredWithout($attribute, $value, $parameters)\n    {\n        if ($this->anyFailingRequired($parameters)) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that an attribute exists when all other attributes do not.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $parameters\n     * @return bool\n     */\n    public function validateRequiredWithoutAll($attribute, $value, $parameters)\n    {\n        if ($this->allFailingRequired($parameters)) {\n            return $this->validateRequired($attribute, $value);\n        }\n\n        return true;\n    }\n\n    /**\n     * Determine if any of the given attributes fail the required test.\n     *\n     * @param  array  $attributes\n     * @return bool\n     */\n    protected function anyFailingRequired(array $attributes)\n    {\n        foreach ($attributes as $key) {\n            if (! $this->validateRequired($key, $this->getValue($key))) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Determine if all of the given attributes fail the required test.\n     *\n     * @param  array  $attributes\n     * @return bool\n     */\n    protected function allFailingRequired(array $attributes)\n    {\n        foreach ($attributes as $key) {\n            if ($this->validateRequired($key, $this->getValue($key))) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate that two attributes match.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateSame($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'same');\n\n        $other = Arr::get($this->data, $parameters[0]);\n\n        return $value === $other;\n    }\n\n    /**\n     * Validate the size of an attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateSize($attribute, $value, $parameters)\n    {\n        $this->requireParameterCount(1, $parameters, 'size');\n\n        try {\n            return BigNumber::of($this->getSize($attribute, $value))->isEqualTo($this->trim($parameters[0]));\n        } catch (MathException) {\n            return false;\n        }\n    }\n\n    /**\n     * \"Validate\" optional attributes.\n     *\n     * Always returns true, just lets us put sometimes in rules.\n     *\n     * @return bool\n     */\n    public function validateSometimes()\n    {\n        return true;\n    }\n\n    /**\n     * Validate the attribute starts with a given substring.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateStartsWith($attribute, $value, $parameters)\n    {\n        return Str::startsWith($value, $parameters);\n    }\n\n    /**\n     * Validate the attribute does not start with a given substring.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDoesntStartWith($attribute, $value, $parameters)\n    {\n        return ! Str::startsWith($value, $parameters);\n    }\n\n    /**\n     * Validate the attribute ends with a given substring.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateEndsWith($attribute, $value, $parameters)\n    {\n        return Str::endsWith($value, $parameters);\n    }\n\n    /**\n     * Validate the attribute does not end with a given substring.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int|string>  $parameters\n     * @return bool\n     */\n    public function validateDoesntEndWith($attribute, $value, $parameters)\n    {\n        return ! Str::endsWith($value, $parameters);\n    }\n\n    /**\n     * Validate that an attribute is a string.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateString($attribute, $value)\n    {\n        return is_string($value);\n    }\n\n    /**\n     * Validate that an attribute is a valid timezone.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<string, null|string>  $parameters\n     * @return bool\n     */\n    public function validateTimezone($attribute, $value, $parameters = [])\n    {\n        return in_array($value, timezone_identifiers_list(\n            constant(DateTimeZone::class.'::'.Str::upper($parameters[0] ?? 'ALL')),\n            isset($parameters[1]) ? Str::upper($parameters[1]) : null,\n        ), true);\n    }\n\n    /**\n     * Validate that an attribute is a valid URL.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, string>  $parameters\n     * @return bool\n     */\n    public function validateUrl($attribute, $value, $parameters = [])\n    {\n        return Str::isUrl($value, $parameters);\n    }\n\n    /**\n     * Validate that an attribute is a valid ULID.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function validateUlid($attribute, $value)\n    {\n        return Str::isUlid($value);\n    }\n\n    /**\n     * Validate that an attribute is a valid UUID.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  array<int, int<0, 8>|'max'>  $parameters\n     * @return bool\n     */\n    public function validateUuid($attribute, $value, $parameters)\n    {\n        $version = null;\n\n        if ($parameters !== null && count($parameters) === 1) {\n            $version = $parameters[0];\n\n            if ($version !== 'max') {\n                $version = (int) $parameters[0];\n            }\n        }\n\n        return Str::isUuid($value, $version);\n    }\n\n    /**\n     * Get the size of an attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return int|string\n     */\n    protected function getSize($attribute, $value)\n    {\n        $hasNumeric = $this->hasRule($attribute, $this->numericRules);\n\n        // This method will determine if the attribute is a number, string, or file and\n        // return the proper size accordingly. If it is a number, then number itself\n        // is the size. If it is a file, we take kilobytes, and for a string the\n        // entire length of the string will be considered the attribute size.\n        if (is_numeric($value) && $hasNumeric) {\n            return (string) $this->ensureExponentWithinAllowedRange($attribute, $this->trim($value));\n        } elseif (is_array($value)) {\n            return count($value);\n        } elseif ($value instanceof File) {\n            return (string) ($value->getSize() / 1024);\n        }\n\n        return mb_strlen($value ?? '');\n    }\n\n    /**\n     * Check that the given value is a valid file instance.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function isValidFileInstance($value)\n    {\n        if ($value instanceof UploadedFile && ! $value->isValid()) {\n            return false;\n        }\n\n        return $value instanceof File;\n    }\n\n    /**\n     * Determine if a comparison passes between the given values.\n     *\n     * @param  mixed  $first\n     * @param  mixed  $second\n     * @param  string  $operator\n     * @return bool\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compare($first, $second, $operator)\n    {\n        return match ($operator) {\n            '<' => $first < $second,\n            '>' => $first > $second,\n            '<=' => $first <= $second,\n            '>=' => $first >= $second,\n            '=' => $first == $second,\n            default => throw new InvalidArgumentException,\n        };\n    }\n\n    /**\n     * Parse named parameters to $key => $value items.\n     *\n     * @param  array<int, int|string>  $parameters\n     * @return array\n     */\n    public function parseNamedParameters($parameters)\n    {\n        return array_reduce($parameters, function ($result, $item) {\n            [$key, $value] = array_pad(explode('=', $item, 2), 2, null);\n\n            $result[$key] = $value;\n\n            return $result;\n        });\n    }\n\n    /**\n     * Require a certain number of parameters to be present.\n     *\n     * @param  int  $count\n     * @param  array<int, int|string>  $parameters\n     * @param  string  $rule\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function requireParameterCount($count, $parameters, $rule)\n    {\n        if (count($parameters) < $count) {\n            throw new InvalidArgumentException(\"Validation rule $rule requires at least $count parameters.\");\n        }\n    }\n\n    /**\n     * Check if the parameters are of the same type.\n     *\n     * @param  mixed  $first\n     * @param  mixed  $second\n     * @return bool\n     */\n    protected function isSameType($first, $second)\n    {\n        return gettype($first) == gettype($second);\n    }\n\n    /**\n     * Adds the existing rule to the numericRules array if the attribute's value is numeric.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @return void\n     */\n    protected function shouldBeNumeric($attribute, $rule)\n    {\n        if (is_numeric($this->getValue($attribute))) {\n            $this->numericRules[] = $rule;\n        }\n    }\n\n    /**\n     * Trim the value if it is a string.\n     *\n     * @param  mixed  $value\n     * @return string\n     */\n    protected function trim($value)\n    {\n        return is_string($value) ? trim($value) : (string) $value;\n    }\n\n    /**\n     * Ensure the exponent is within the allowed range.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return mixed\n     *\n     * @throws \\Illuminate\\Support\\Exceptions\\MathException\n     */\n    protected function ensureExponentWithinAllowedRange($attribute, $value)\n    {\n        $stringValue = (string) $value;\n\n        if (! is_numeric($value) || ! Str::contains($stringValue, 'e', ignoreCase: true)) {\n            return $value;\n        }\n\n        $scale = (int) (Str::contains($stringValue, 'e')\n            ? Str::after($stringValue, 'e')\n            : Str::after($stringValue, 'E'));\n\n        $withinRange = (\n            $this->ensureExponentWithinAllowedRangeUsing ?? fn ($scale) => $scale <= 1000 && $scale >= -1000\n        )($scale, $attribute, $value);\n\n        if (! $withinRange) {\n            throw new MathException('Scientific notation exponent outside of allowed range.');\n        }\n\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ConditionalRules.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Support\\Fluent;\n\nclass ConditionalRules\n{\n    /**\n     * The boolean condition indicating if the rules should be added to the attribute.\n     *\n     * @var callable|bool\n     */\n    protected $condition;\n\n    /**\n     * The rules to be added to the attribute.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string\n     */\n    protected $rules;\n\n    /**\n     * The rules to be added to the attribute if the condition fails.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string\n     */\n    protected $defaultRules;\n\n    /**\n     * Create a new conditional rules instance.\n     *\n     * @param  callable|bool  $condition\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $rules\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $defaultRules\n     */\n    public function __construct($condition, $rules, $defaultRules = [])\n    {\n        $this->condition = $condition;\n        $this->rules = $rules;\n        $this->defaultRules = $defaultRules;\n    }\n\n    /**\n     * Determine if the conditional rules should be added.\n     *\n     * @param  array  $data\n     * @return bool\n     */\n    public function passes(array $data = [])\n    {\n        return is_callable($this->condition)\n            ? call_user_func($this->condition, new Fluent($data))\n            : $this->condition;\n    }\n\n    /**\n     * Get the rules.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    public function rules(array $data = [])\n    {\n        return is_string($this->rules)\n            ? explode('|', $this->rules)\n            : value($this->rules, new Fluent($data));\n    }\n\n    /**\n     * Get the default rules.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    public function defaultRules(array $data = [])\n    {\n        return is_string($this->defaultRules)\n            ? explode('|', $this->defaultRules)\n            : value($this->defaultRules, new Fluent($data));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/DatabasePresenceVerifier.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Closure;\nuse Illuminate\\Database\\ConnectionResolverInterface;\n\nclass DatabasePresenceVerifier implements DatabasePresenceVerifierInterface\n{\n    /**\n     * The database connection instance.\n     *\n     * @var \\Illuminate\\Database\\ConnectionResolverInterface\n     */\n    protected $db;\n\n    /**\n     * The database connection to use.\n     *\n     * @var string\n     */\n    protected $connection;\n\n    /**\n     * Create a new database presence verifier.\n     *\n     * @param  \\Illuminate\\Database\\ConnectionResolverInterface  $db\n     */\n    public function __construct(ConnectionResolverInterface $db)\n    {\n        $this->db = $db;\n    }\n\n    /**\n     * Count the number of objects in a collection having the given value.\n     *\n     * @param  string  $collection\n     * @param  string  $column\n     * @param  string  $value\n     * @param  int|null  $excludeId\n     * @param  string|null  $idColumn\n     * @param  array  $extra\n     * @return int\n     */\n    public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = [])\n    {\n        $query = $this->table($collection)->where($column, '=', $value);\n\n        if (! is_null($excludeId) && $excludeId !== 'NULL') {\n            $query->where($idColumn ?: 'id', '<>', $excludeId);\n        }\n\n        return $this->addConditions($query, $extra)->count();\n    }\n\n    /**\n     * Count the number of objects in a collection with the given values.\n     *\n     * @param  string  $collection\n     * @param  string  $column\n     * @param  array  $values\n     * @param  array  $extra\n     * @return int\n     */\n    public function getMultiCount($collection, $column, array $values, array $extra = [])\n    {\n        $query = $this->table($collection)->whereIn($column, $values);\n\n        return $this->addConditions($query, $extra)->distinct()->count($column);\n    }\n\n    /**\n     * Add the given conditions to the query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  array  $conditions\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function addConditions($query, $conditions)\n    {\n        foreach ($conditions as $key => $value) {\n            if ($value instanceof Closure) {\n                $query->where(function ($query) use ($value) {\n                    $value($query);\n                });\n            } else {\n                $this->addWhere($query, $key, $value);\n            }\n        }\n\n        return $query;\n    }\n\n    /**\n     * Add a \"where\" clause to the given query.\n     *\n     * @param  \\Illuminate\\Database\\Query\\Builder  $query\n     * @param  string  $key\n     * @param  string  $extraValue\n     * @return void\n     */\n    protected function addWhere($query, $key, $extraValue)\n    {\n        if ($extraValue === 'NULL') {\n            $query->whereNull($key);\n        } elseif ($extraValue === 'NOT_NULL') {\n            $query->whereNotNull($key);\n        } elseif (str_starts_with($extraValue, '!')) {\n            $query->where($key, '!=', mb_substr($extraValue, 1));\n        } else {\n            $query->where($key, $extraValue);\n        }\n    }\n\n    /**\n     * Get a query builder for the given table.\n     *\n     * @param  string  $table\n     * @return \\Illuminate\\Database\\Query\\Builder\n     */\n    protected function table($table)\n    {\n        return $this->db->connection($this->connection)->table($table)->useWritePdo();\n    }\n\n    /**\n     * Set the connection to be used.\n     *\n     * @param  string  $connection\n     * @return void\n     */\n    public function setConnection($connection)\n    {\n        $this->connection = $connection;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/DatabasePresenceVerifierInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\ninterface DatabasePresenceVerifierInterface extends PresenceVerifierInterface\n{\n    /**\n     * Set the connection to be used.\n     *\n     * @param  string  $connection\n     * @return void\n     */\n    public function setConnection($connection);\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Closure;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Translation\\Translator;\nuse Illuminate\\Contracts\\Validation\\Factory as FactoryContract;\nuse Illuminate\\Support\\Str;\n\nclass Factory implements FactoryContract\n{\n    /**\n     * The Translator implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Translation\\Translator\n     */\n    protected $translator;\n\n    /**\n     * The Presence Verifier implementation.\n     *\n     * @var \\Illuminate\\Validation\\PresenceVerifierInterface\n     */\n    protected $verifier;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container|null\n     */\n    protected $container;\n\n    /**\n     * All of the custom validator extensions.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $extensions = [];\n\n    /**\n     * All of the custom implicit validator extensions.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $implicitExtensions = [];\n\n    /**\n     * All of the custom dependent validator extensions.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $dependentExtensions = [];\n\n    /**\n     * All of the custom validator message replacers.\n     *\n     * @var array<string, \\Closure|string>\n     */\n    protected $replacers = [];\n\n    /**\n     * All of the fallback messages for custom rules.\n     *\n     * @var array<string, string>\n     */\n    protected $fallbackMessages = [];\n\n    /**\n     * Indicates that unvalidated array keys should be excluded, even if the parent array was validated.\n     *\n     * @var bool\n     */\n    protected $excludeUnvalidatedArrayKeys = true;\n\n    /**\n     * The Validator resolver instance.\n     *\n     * @var \\Closure\n     */\n    protected $resolver;\n\n    /**\n     * Create a new Validator factory instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Translation\\Translator  $translator\n     * @param  \\Illuminate\\Contracts\\Container\\Container|null  $container\n     */\n    public function __construct(Translator $translator, ?Container $container = null)\n    {\n        $this->container = $container;\n        $this->translator = $translator;\n    }\n\n    /**\n     * Create a new Validator instance.\n     *\n     * @param  array  $data\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return \\Illuminate\\Validation\\Validator\n     */\n    public function make(array $data, array $rules, array $messages = [], array $attributes = [])\n    {\n        $validator = $this->resolve(\n            $data, $rules, $messages, $attributes\n        );\n\n        // The presence verifier is responsible for checking the unique and exists data\n        // for the validator. It is behind an interface so that multiple versions of\n        // it may be written besides database. We'll inject it into the validator.\n        if (! is_null($this->verifier)) {\n            $validator->setPresenceVerifier($this->verifier);\n        }\n\n        // Next we'll set the IoC container instance of the validator, which is used to\n        // resolve out class based validator extensions. If it is not set then these\n        // types of extensions will not be possible on these validation instances.\n        if (! is_null($this->container)) {\n            $validator->setContainer($this->container);\n        }\n\n        $validator->excludeUnvalidatedArrayKeys = $this->excludeUnvalidatedArrayKeys;\n\n        $this->addExtensions($validator);\n\n        return $validator;\n    }\n\n    /**\n     * Validate the given data against the provided rules.\n     *\n     * @param  array  $data\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validate(array $data, array $rules, array $messages = [], array $attributes = [])\n    {\n        return $this->make($data, $rules, $messages, $attributes)->validate();\n    }\n\n    /**\n     * Resolve a new Validator instance.\n     *\n     * @param  array  $data\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     * @return \\Illuminate\\Validation\\Validator\n     */\n    protected function resolve(array $data, array $rules, array $messages, array $attributes)\n    {\n        if (is_null($this->resolver)) {\n            return new Validator($this->translator, $data, $rules, $messages, $attributes);\n        }\n\n        return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $attributes);\n    }\n\n    /**\n     * Add the extensions to a validator instance.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return void\n     */\n    protected function addExtensions(Validator $validator)\n    {\n        $validator->addExtensions($this->extensions);\n\n        // Next, we will add the implicit extensions, which are similar to the required\n        // and accepted rule in that they're run even if the attributes aren't in an\n        // array of data which is given to a validator instance via instantiation.\n        $validator->addImplicitExtensions($this->implicitExtensions);\n\n        $validator->addDependentExtensions($this->dependentExtensions);\n\n        $validator->addReplacers($this->replacers);\n\n        $validator->setFallbackMessages($this->fallbackMessages);\n    }\n\n    /**\n     * Register a custom validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @param  string|null  $message\n     * @return void\n     */\n    public function extend($rule, $extension, $message = null)\n    {\n        $this->extensions[$rule] = $extension;\n\n        if ($message) {\n            $this->fallbackMessages[Str::snake($rule)] = $message;\n        }\n    }\n\n    /**\n     * Register a custom implicit validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @param  string|null  $message\n     * @return void\n     */\n    public function extendImplicit($rule, $extension, $message = null)\n    {\n        $this->implicitExtensions[$rule] = $extension;\n\n        if ($message) {\n            $this->fallbackMessages[Str::snake($rule)] = $message;\n        }\n    }\n\n    /**\n     * Register a custom dependent validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @param  string|null  $message\n     * @return void\n     */\n    public function extendDependent($rule, $extension, $message = null)\n    {\n        $this->dependentExtensions[$rule] = $extension;\n\n        if ($message) {\n            $this->fallbackMessages[Str::snake($rule)] = $message;\n        }\n    }\n\n    /**\n     * Register a custom validator message replacer.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $replacer\n     * @return void\n     */\n    public function replacer($rule, $replacer)\n    {\n        $this->replacers[$rule] = $replacer;\n    }\n\n    /**\n     * Indicate that unvalidated array keys should be included in validated data when the parent array is validated.\n     *\n     * @return void\n     */\n    public function includeUnvalidatedArrayKeys()\n    {\n        $this->excludeUnvalidatedArrayKeys = false;\n    }\n\n    /**\n     * Indicate that unvalidated array keys should be excluded from the validated data, even if the parent array was validated.\n     *\n     * @return void\n     */\n    public function excludeUnvalidatedArrayKeys()\n    {\n        $this->excludeUnvalidatedArrayKeys = true;\n    }\n\n    /**\n     * Set the Validator instance resolver.\n     *\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public function resolver(Closure $resolver)\n    {\n        $this->resolver = $resolver;\n    }\n\n    /**\n     * Get the Translator implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Translation\\Translator\n     */\n    public function getTranslator()\n    {\n        return $this->translator;\n    }\n\n    /**\n     * Get the Presence Verifier implementation.\n     *\n     * @return \\Illuminate\\Validation\\PresenceVerifierInterface\n     */\n    public function getPresenceVerifier()\n    {\n        return $this->verifier;\n    }\n\n    /**\n     * Set the Presence Verifier implementation.\n     *\n     * @param  \\Illuminate\\Validation\\PresenceVerifierInterface  $presenceVerifier\n     * @return void\n     */\n    public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier)\n    {\n        $this->verifier = $presenceVerifier;\n    }\n\n    /**\n     * Get the container instance used by the validation factory.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container|null\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the container instance used by the validation factory.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return $this\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/InvokableValidationRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Contracts\\Validation\\DataAwareRule;\nuse Illuminate\\Contracts\\Validation\\ImplicitRule;\nuse Illuminate\\Contracts\\Validation\\InvokableRule;\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidationRule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Translation\\CreatesPotentiallyTranslatedStrings;\n\nclass InvokableValidationRule implements Rule, ValidatorAwareRule\n{\n    use CreatesPotentiallyTranslatedStrings;\n\n    /**\n     * The invokable that validates the attribute.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule\n     */\n    protected $invokable;\n\n    /**\n     * Indicates if the validation invokable failed.\n     *\n     * @var bool\n     */\n    protected $failed = false;\n\n    /**\n     * The validation error messages.\n     *\n     * @var array\n     */\n    protected $messages = [];\n\n    /**\n     * The current validator.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * The data under validation.\n     *\n     * @var array\n     */\n    protected $data = [];\n\n    /**\n     * Create a new explicit Invokable validation rule.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule  $invokable\n     */\n    protected function __construct(ValidationRule|InvokableRule $invokable)\n    {\n        $this->invokable = $invokable;\n    }\n\n    /**\n     * Create a new implicit or explicit Invokable validation rule.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule  $invokable\n     * @return \\Illuminate\\Validation\\InvokableValidationRule\n     */\n    public static function make($invokable)\n    {\n        if ($invokable->implicit ?? false) {\n            return new class($invokable) extends InvokableValidationRule implements ImplicitRule {\n            };\n        }\n\n        return new InvokableValidationRule($invokable);\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $this->failed = false;\n\n        if ($this->invokable instanceof DataAwareRule) {\n            $this->invokable->setData($this->validator->getData());\n        }\n\n        if ($this->invokable instanceof ValidatorAwareRule) {\n            $this->invokable->setValidator($this->validator);\n        }\n\n        $method = $this->invokable instanceof ValidationRule\n            ? 'validate'\n            : '__invoke';\n\n        $this->invokable->{$method}($attribute, $value, function ($attribute, $message = null) {\n            $this->failed = true;\n\n            return $this->pendingPotentiallyTranslatedString($attribute, $message);\n        });\n\n        return ! $this->failed;\n    }\n\n    /**\n     * Get the underlying invokable rule.\n     *\n     * @return \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule\n     */\n    public function invokable()\n    {\n        return $this->invokable;\n    }\n\n    /**\n     * Get the validation error messages.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Set the data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData($data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/Validation/NestedRules.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Contracts\\Validation\\CompilableRules;\n\nclass NestedRules implements CompilableRules\n{\n    /**\n     * The callback to execute.\n     *\n     * @var callable\n     */\n    protected $callback;\n\n    /**\n     * Create a new nested rule instance.\n     *\n     * @param  callable  $callback\n     */\n    public function __construct(callable $callback)\n    {\n        $this->callback = $callback;\n    }\n\n    /**\n     * Compile the callback into an array of rules.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  mixed  $data\n     * @param  mixed  $context\n     * @return \\stdClass\n     */\n    public function compile($attribute, $value, $data = null, $context = null)\n    {\n        $rules = call_user_func($this->callback, $value, $attribute, $data, $context);\n\n        return Rule::compile($attribute, $rules, $data);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/NotPwnedVerifier.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Exception;\nuse Illuminate\\Contracts\\Validation\\UncompromisedVerifier;\nuse Illuminate\\Support\\Stringable;\n\nclass NotPwnedVerifier implements UncompromisedVerifier\n{\n    /**\n     * The HTTP factory instance.\n     *\n     * @var \\Illuminate\\Http\\Client\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The number of seconds the request can run before timing out.\n     *\n     * @var int\n     */\n    protected $timeout;\n\n    /**\n     * Create a new uncompromised verifier.\n     *\n     * @param  \\Illuminate\\Http\\Client\\Factory  $factory\n     * @param  int|null  $timeout\n     */\n    public function __construct($factory, $timeout = null)\n    {\n        $this->factory = $factory;\n        $this->timeout = $timeout ?? 30;\n    }\n\n    /**\n     * Verify that the given data has not been compromised in public breaches.\n     *\n     * @param  array  $data\n     * @return bool\n     */\n    public function verify($data)\n    {\n        $value = $data['value'];\n        $threshold = $data['threshold'];\n\n        if (empty($value = (string) $value)) {\n            return false;\n        }\n\n        [$hash, $hashPrefix] = $this->getHash($value);\n\n        return ! $this->search($hashPrefix)\n            ->contains(function ($line) use ($hash, $hashPrefix, $threshold) {\n                [$hashSuffix, $count] = explode(':', $line);\n\n                return $hashPrefix.$hashSuffix == $hash && $count > $threshold;\n            });\n    }\n\n    /**\n     * Get the hash and its first 5 chars.\n     *\n     * @param  string  $value\n     * @return array\n     */\n    protected function getHash($value)\n    {\n        $hash = strtoupper(sha1((string) $value));\n\n        $hashPrefix = substr($hash, 0, 5);\n\n        return [$hash, $hashPrefix];\n    }\n\n    /**\n     * Search by the given hash prefix and returns all occurrences of leaked passwords.\n     *\n     * @param  string  $hashPrefix\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function search($hashPrefix)\n    {\n        try {\n            $response = $this->factory->withHeaders([\n                'Add-Padding' => true,\n            ])->timeout($this->timeout)->get(\n                'https://api.pwnedpasswords.com/range/'.$hashPrefix\n            );\n        } catch (Exception $e) {\n            report($e);\n        }\n\n        $body = (isset($response) && $response->successful())\n            ? $response->body()\n            : '';\n\n        return (new Stringable($body))->trim()->explode(\"\\n\")->filter(function ($line) {\n            return str_contains($line, ':');\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/PresenceVerifierInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\ninterface PresenceVerifierInterface\n{\n    /**\n     * Count the number of objects in a collection having the given value.\n     *\n     * @param  string  $collection\n     * @param  string  $column\n     * @param  string  $value\n     * @param  int|null  $excludeId\n     * @param  string|null  $idColumn\n     * @param  array  $extra\n     * @return int\n     */\n    public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = []);\n\n    /**\n     * Count the number of objects in a collection with the given values.\n     *\n     * @param  string  $collection\n     * @param  string  $column\n     * @param  array  $values\n     * @param  array  $extra\n     * @return int\n     */\n    public function getMultiCount($collection, $column, array $values, array $extra = []);\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Validation\\Rules\\AnyOf;\nuse Illuminate\\Validation\\Rules\\ArrayRule;\nuse Illuminate\\Validation\\Rules\\Can;\nuse Illuminate\\Validation\\Rules\\Date;\nuse Illuminate\\Validation\\Rules\\Dimensions;\nuse Illuminate\\Validation\\Rules\\Email;\nuse Illuminate\\Validation\\Rules\\Enum;\nuse Illuminate\\Validation\\Rules\\ExcludeIf;\nuse Illuminate\\Validation\\Rules\\ExcludeUnless;\nuse Illuminate\\Validation\\Rules\\Exists;\nuse Illuminate\\Validation\\Rules\\File;\nuse Illuminate\\Validation\\Rules\\ImageFile;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\Rules\\NotIn;\nuse Illuminate\\Validation\\Rules\\Numeric;\nuse Illuminate\\Validation\\Rules\\ProhibitedIf;\nuse Illuminate\\Validation\\Rules\\ProhibitedUnless;\nuse Illuminate\\Validation\\Rules\\RequiredIf;\nuse Illuminate\\Validation\\Rules\\RequiredUnless;\nuse Illuminate\\Validation\\Rules\\StringRule;\nuse Illuminate\\Validation\\Rules\\Unique;\n\nclass Rule\n{\n    use Macroable;\n\n    /**\n     * Get a can constraint builder instance.\n     *\n     * @param  string  $ability\n     * @param  mixed  ...$arguments\n     * @return \\Illuminate\\Validation\\Rules\\Can\n     */\n    public static function can($ability, ...$arguments)\n    {\n        return new Can($ability, $arguments);\n    }\n\n    /**\n     * Apply the given rules if the given condition is truthy.\n     *\n     * @param  callable|bool  $condition\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $rules\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $defaultRules\n     * @return \\Illuminate\\Validation\\ConditionalRules\n     */\n    public static function when($condition, $rules, $defaultRules = [])\n    {\n        return new ConditionalRules($condition, $rules, $defaultRules);\n    }\n\n    /**\n     * Apply the given rules if the given condition is falsy.\n     *\n     * @param  callable|bool  $condition\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $rules\n     * @param  \\Illuminate\\Contracts\\Validation\\ValidationRule|\\Illuminate\\Contracts\\Validation\\InvokableRule|\\Illuminate\\Contracts\\Validation\\Rule|\\Closure|array|string  $defaultRules\n     * @return \\Illuminate\\Validation\\ConditionalRules\n     */\n    public static function unless($condition, $rules, $defaultRules = [])\n    {\n        return new ConditionalRules($condition, $defaultRules, $rules);\n    }\n\n    /**\n     * Get an array rule builder instance.\n     *\n     * @param  array|null  $keys\n     * @return \\Illuminate\\Validation\\Rules\\ArrayRule\n     */\n    public static function array($keys = null)\n    {\n        return new ArrayRule(...func_get_args());\n    }\n\n    /**\n     * Create a new nested rule set.\n     *\n     * @param  callable  $callback\n     * @return \\Illuminate\\Validation\\NestedRules\n     */\n    public static function forEach($callback)\n    {\n        return new NestedRules($callback);\n    }\n\n    /**\n     * Get a unique constraint builder instance.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @return \\Illuminate\\Validation\\Rules\\Unique\n     */\n    public static function unique($table, $column = 'NULL')\n    {\n        return new Unique($table, $column);\n    }\n\n    /**\n     * Get an exists constraint builder instance.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     * @return \\Illuminate\\Validation\\Rules\\Exists\n     */\n    public static function exists($table, $column = 'NULL')\n    {\n        return new Exists($table, $column);\n    }\n\n    /**\n     * Get an in rule builder instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     * @return \\Illuminate\\Validation\\Rules\\In\n     */\n    public static function in($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        return new In(is_array($values) ? $values : func_get_args());\n    }\n\n    /**\n     * Get a not_in rule builder instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     * @return \\Illuminate\\Validation\\Rules\\NotIn\n     */\n    public static function notIn($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        return new NotIn(is_array($values) ? $values : func_get_args());\n    }\n\n    /**\n     * Get a required_if rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool  $callback\n     * @return \\Illuminate\\Validation\\Rules\\RequiredIf\n     */\n    public static function requiredIf($callback)\n    {\n        return new RequiredIf($callback);\n    }\n\n    /**\n     * Get a required_unless rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool|null  $callback\n     * @return \\Illuminate\\Validation\\Rules\\RequiredUnless\n     */\n    public static function requiredUnless($callback)\n    {\n        return new RequiredUnless($callback);\n    }\n\n    /**\n     * Get a exclude_if rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool  $callback\n     * @return \\Illuminate\\Validation\\Rules\\ExcludeIf\n     */\n    public static function excludeIf($callback)\n    {\n        return new ExcludeIf($callback);\n    }\n\n    /**\n     * Get a exclude_unless rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool  $callback\n     * @return \\Illuminate\\Validation\\Rules\\ExcludeUnless\n     */\n    public static function excludeUnless($callback)\n    {\n        return new ExcludeUnless($callback);\n    }\n\n    /**\n     * Get a prohibited_if rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool  $callback\n     * @return \\Illuminate\\Validation\\Rules\\ProhibitedIf\n     */\n    public static function prohibitedIf($callback)\n    {\n        return new ProhibitedIf($callback);\n    }\n\n    /**\n     * Get a prohibited_unless rule builder instance.\n     *\n     * @param  (\\Closure(): bool)|bool  $callback\n     * @return \\Illuminate\\Validation\\Rules\\ProhibitedUnless\n     */\n    public static function prohibitedUnless($callback)\n    {\n        return new ProhibitedUnless($callback);\n    }\n\n    /**\n     * Get a date rule builder instance.\n     *\n     * @return \\Illuminate\\Validation\\Rules\\Date\n     */\n    public static function date()\n    {\n        return new Date;\n    }\n\n    /**\n     * Get a datetime rule builder instance.\n     */\n    public static function dateTime(): Date\n    {\n        return (new Date)->format('Y-m-d H:i:s');\n    }\n\n    /**\n     * Get an email rule builder instance.\n     *\n     * @return \\Illuminate\\Validation\\Rules\\Email\n     */\n    public static function email()\n    {\n        return new Email;\n    }\n\n    /**\n     * Get an enum rule builder instance.\n     *\n     * @param  class-string  $type\n     * @return \\Illuminate\\Validation\\Rules\\Enum\n     */\n    public static function enum($type)\n    {\n        return new Enum($type);\n    }\n\n    /**\n     * Get a file rule builder instance.\n     *\n     * @return \\Illuminate\\Validation\\Rules\\File\n     */\n    public static function file()\n    {\n        return new File;\n    }\n\n    /**\n     * Get an image file rule builder instance.\n     *\n     * @param  bool  $allowSvg\n     * @return \\Illuminate\\Validation\\Rules\\ImageFile\n     */\n    public static function imageFile($allowSvg = false)\n    {\n        return new ImageFile($allowSvg);\n    }\n\n    /**\n     * Get a dimensions rule builder instance.\n     *\n     * @param  array  $constraints\n     * @return \\Illuminate\\Validation\\Rules\\Dimensions\n     */\n    public static function dimensions(array $constraints = [])\n    {\n        return new Dimensions($constraints);\n    }\n\n    /**\n     * Get a string rule builder instance.\n     *\n     * @return \\Illuminate\\Validation\\Rules\\StringRule\n     */\n    public static function string()\n    {\n        return new StringRule;\n    }\n\n    /**\n     * Get a numeric rule builder instance.\n     *\n     * @return \\Illuminate\\Validation\\Rules\\Numeric\n     */\n    public static function numeric()\n    {\n        return new Numeric;\n    }\n\n    /**\n     * Get an \"any of\" rule builder instance.\n     *\n     * @param  array  $rules\n     * @return \\Illuminate\\Validation\\Rules\\AnyOf\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function anyOf($rules)\n    {\n        return new AnyOf($rules);\n    }\n\n    /**\n     * Get a contains rule builder instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     * @return \\Illuminate\\Validation\\Rules\\Contains\n     */\n    public static function contains($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        return new Rules\\Contains(is_array($values) ? $values : func_get_args());\n    }\n\n    /**\n     * Get a \"does not contain\" rule builder instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     * @return \\Illuminate\\Validation\\Rules\\DoesntContain\n     */\n    public static function doesntContain($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        return new Rules\\DoesntContain(is_array($values) ? $values : func_get_args());\n    }\n\n    /**\n     * Compile a set of rules for an attribute.\n     *\n     * @param  string  $attribute\n     * @param  array  $rules\n     * @param  array|null  $data\n     * @return object|\\stdClass\n     */\n    public static function compile($attribute, $rules, $data = null)\n    {\n        $parser = new ValidationRuleParser(\n            Arr::undot(Arr::wrap($data))\n        );\n\n        if (is_array($rules) && ! array_is_list($rules)) {\n            $nested = [];\n\n            foreach ($rules as $key => $rule) {\n                $nested[$attribute.'.'.$key] = $rule;\n            }\n\n            $rules = $nested;\n        } else {\n            $rules = [$attribute => $rules];\n        }\n\n        return $parser->explode(ValidationRuleParser::filterConditionalRules($rules, $data));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/AnyOf.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Validator;\nuse InvalidArgumentException;\n\nclass AnyOf implements Rule, ValidatorAwareRule\n{\n    /**\n     * The rules to match against.\n     *\n     * @var array\n     */\n    protected array $rules = [];\n\n    /**\n     * The validator performing the validation.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * Sets the validation rules to match against.\n     *\n     * @param  array  $rules\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($rules)\n    {\n        if (! is_array($rules)) {\n            throw new InvalidArgumentException('The provided value must be an array of validation rules.');\n        }\n\n        $this->rules = $rules;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        foreach ($this->rules as $rule) {\n            $validator = Validator::make(\n                Arr::isAssoc(Arr::wrap($value)) ? $value : [$value],\n                Arr::isAssoc(Arr::wrap($rule)) ? $rule : [$rule],\n                $this->validator->customMessages,\n                $this->validator->customAttributes\n            );\n\n            if ($validator->passes()) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Get the validation error messages.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        $message = $this->validator->getTranslator()->get('validation.any_of');\n\n        return $message === 'validation.any_of'\n            ? ['The :attribute field is invalid.']\n            : $message;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ArrayRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass ArrayRule implements Stringable\n{\n    /**\n     * The accepted keys.\n     *\n     * @var array\n     */\n    protected $keys;\n\n    /**\n     * Create a new array rule instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array|null  $keys\n     */\n    public function __construct($keys = null)\n    {\n        if ($keys instanceof Arrayable) {\n            $keys = $keys->toArray();\n        }\n\n        $this->keys = is_array($keys) ? $keys : func_get_args();\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (empty($this->keys)) {\n            return 'array';\n        }\n\n        $keys = array_map(\n            static fn ($key) => enum_value($key),\n            $this->keys,\n        );\n\n        return 'array:'.implode(',', $keys);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Can.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Facades\\Gate;\n\nclass Can implements Rule, ValidatorAwareRule\n{\n    /**\n     * The ability to check.\n     *\n     * @var string\n     */\n    protected $ability;\n\n    /**\n     * The arguments to pass to the authorization check.\n     *\n     * @var array\n     */\n    protected $arguments;\n\n    /**\n     * The current validator instance.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * Constructor.\n     *\n     * @param  string  $ability\n     * @param  array  $arguments\n     */\n    public function __construct($ability, array $arguments = [])\n    {\n        $this->ability = $ability;\n        $this->arguments = $arguments;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $arguments = $this->arguments;\n\n        $model = array_shift($arguments);\n\n        return Gate::allows($this->ability, array_filter([$model, ...$arguments, $value]));\n    }\n\n    /**\n     * Get the validation error message.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        $message = $this->validator->getTranslator()->get('validation.can');\n\n        return $message === 'validation.can'\n            ? ['The :attribute field contains an unauthorized value.']\n            : $message;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Contains.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Contains implements Stringable\n{\n    /**\n     * The values that should be contained in the attribute.\n     *\n     * @var array\n     */\n    protected $values;\n\n    /**\n     * Create a new contains rule instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     */\n    public function __construct($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->values = is_array($values) ? $values : func_get_args();\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $values = array_map(function ($value) {\n            $value = enum_value($value);\n\n            return '\"'.str_replace('\"', '\"\"', $value).'\"';\n        }, $this->values);\n\n        return 'contains:'.implode(',', $values);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/DatabaseRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\n\nuse function Illuminate\\Support\\enum_value;\n\ntrait DatabaseRule\n{\n    /**\n     * The table to run the query against.\n     *\n     * @var string\n     */\n    protected $table;\n\n    /**\n     * The column to check on.\n     *\n     * @var string\n     */\n    protected $column;\n\n    /**\n     * The extra where clauses for the query.\n     *\n     * @var array\n     */\n    protected $wheres = [];\n\n    /**\n     * The array of custom query callbacks.\n     *\n     * @var array\n     */\n    protected $using = [];\n\n    /**\n     * Create a new rule instance.\n     *\n     * @param  string  $table\n     * @param  string  $column\n     */\n    public function __construct($table, $column = 'NULL')\n    {\n        $this->column = $column;\n\n        $this->table = $this->resolveTableName($table);\n    }\n\n    /**\n     * Resolves the name of the table from the given string.\n     *\n     * @param  string  $table\n     * @return string\n     */\n    public function resolveTableName($table)\n    {\n        if (! str_contains($table, '\\\\') || ! class_exists($table)) {\n            return $table;\n        }\n\n        if (is_subclass_of($table, Model::class)) {\n            $model = new $table;\n\n            if (str_contains($model->getTable(), '.')) {\n                return $table;\n            }\n\n            return implode('.', array_map(function (string $part) {\n                return trim($part, '.');\n            }, array_filter([$model->getConnectionName(), $model->getTable()])));\n        }\n\n        return $table;\n    }\n\n    /**\n     * Set a \"where\" constraint on the query.\n     *\n     * @param  \\Closure|string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|\\Closure|array|string|int|bool|null  $value\n     * @return $this\n     */\n    public function where($column, $value = null)\n    {\n        if ($value instanceof Arrayable || is_array($value)) {\n            return $this->whereIn($column, $value);\n        }\n\n        if ($column instanceof Closure) {\n            return $this->using($column);\n        }\n\n        if (is_null($value)) {\n            return $this->whereNull($column);\n        }\n\n        $value = enum_value($value);\n\n        $this->wheres[] = compact('column', 'value');\n\n        return $this;\n    }\n\n    /**\n     * Set a \"where not\" constraint on the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string|int  $value\n     * @return $this\n     */\n    public function whereNot($column, $value)\n    {\n        if ($value instanceof Arrayable || is_array($value)) {\n            return $this->whereNotIn($column, $value);\n        }\n\n        $value = enum_value($value);\n\n        return $this->where($column, '!'.$value);\n    }\n\n    /**\n     * Set a \"where null\" constraint on the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function whereNull($column)\n    {\n        return $this->where($column, 'NULL');\n    }\n\n    /**\n     * Set a \"where not null\" constraint on the query.\n     *\n     * @param  string  $column\n     * @return $this\n     */\n    public function whereNotNull($column)\n    {\n        return $this->where($column, 'NOT_NULL');\n    }\n\n    /**\n     * Set a \"where in\" constraint on the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\BackedEnum|array  $values\n     * @return $this\n     */\n    public function whereIn($column, $values)\n    {\n        return $this->where(function ($query) use ($column, $values) {\n            $query->whereIn($column, $values);\n        });\n    }\n\n    /**\n     * Set a \"where not in\" constraint on the query.\n     *\n     * @param  string  $column\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\BackedEnum|array  $values\n     * @return $this\n     */\n    public function whereNotIn($column, $values)\n    {\n        return $this->where(function ($query) use ($column, $values) {\n            $query->whereNotIn($column, $values);\n        });\n    }\n\n    /**\n     * Ignore soft deleted models during the existence check.\n     *\n     * @param  string  $deletedAtColumn\n     * @return $this\n     */\n    public function withoutTrashed($deletedAtColumn = 'deleted_at')\n    {\n        $this->whereNull($deletedAtColumn);\n\n        return $this;\n    }\n\n    /**\n     * Only include soft deleted models during the existence check.\n     *\n     * @param  string  $deletedAtColumn\n     * @return $this\n     */\n    public function onlyTrashed($deletedAtColumn = 'deleted_at')\n    {\n        $this->whereNotNull($deletedAtColumn);\n\n        return $this;\n    }\n\n    /**\n     * Register a custom query callback.\n     *\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function using(Closure $callback)\n    {\n        $this->using[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the custom query callbacks for the rule.\n     *\n     * @return array\n     */\n    public function queryCallbacks()\n    {\n        return $this->using;\n    }\n\n    /**\n     * Format the where clauses.\n     *\n     * @return string\n     */\n    protected function formatWheres()\n    {\n        return (new Collection($this->wheres))\n            ->map(fn ($where) => $where['column'].','.'\"'.str_replace('\"', '\"\"', $where['value']).'\"')\n            ->implode(',');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Date.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse DateTimeInterface;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Stringable;\n\nclass Date implements Stringable\n{\n    use Conditionable, Macroable;\n\n    /**\n     * The format of the date.\n     */\n    protected ?string $format = null;\n\n    /**\n     * The constraints for the date rule.\n     */\n    protected array $constraints = [];\n\n    /**\n     * Ensure the date has the given format.\n     */\n    public function format(string $format): static\n    {\n        $this->format = $format;\n\n        return $this;\n    }\n\n    /**\n     * Ensure the date is before today.\n     */\n    public function beforeToday(): static\n    {\n        return $this->before('today');\n    }\n\n    /**\n     * Ensure the date is after today.\n     */\n    public function afterToday(): static\n    {\n        return $this->after('today');\n    }\n\n    /**\n     * Ensure the date is before or equal to today.\n     */\n    public function todayOrBefore(): static\n    {\n        return $this->beforeOrEqual('today');\n    }\n\n    /**\n     * Ensure the date is after or equal to today.\n     */\n    public function todayOrAfter(): static\n    {\n        return $this->afterOrEqual('today');\n    }\n\n    /**\n     * Ensure the date is in the past.\n     */\n    public function past(): static\n    {\n        return $this->before('now');\n    }\n\n    /**\n     * Ensure the date is in the future.\n     */\n    public function future(): static\n    {\n        return $this->after('now');\n    }\n\n    /**\n     * Ensure the date is now or in the past.\n     */\n    public function nowOrPast(): static\n    {\n        return $this->beforeOrEqual('now');\n    }\n\n    /**\n     * Ensure the date is now or in the future.\n     */\n    public function nowOrFuture(): static\n    {\n        return $this->afterOrEqual('now');\n    }\n\n    /**\n     * Ensure the date is before the given date or date field.\n     */\n    public function before(DateTimeInterface|string $date): static\n    {\n        return $this->addRule('before:'.$this->formatDate($date));\n    }\n\n    /**\n     * Ensure the date is after the given date or date field.\n     */\n    public function after(DateTimeInterface|string $date): static\n    {\n        return $this->addRule('after:'.$this->formatDate($date));\n    }\n\n    /**\n     * Ensure the date is on or before the specified date or date field.\n     */\n    public function beforeOrEqual(DateTimeInterface|string $date): static\n    {\n        return $this->addRule('before_or_equal:'.$this->formatDate($date));\n    }\n\n    /**\n     * Ensure the date is on or after the given date or date field.\n     */\n    public function afterOrEqual(DateTimeInterface|string $date): static\n    {\n        return $this->addRule('after_or_equal:'.$this->formatDate($date));\n    }\n\n    /**\n     * Ensure the date is between two dates or date fields.\n     */\n    public function between(DateTimeInterface|string $from, DateTimeInterface|string $to): static\n    {\n        return $this->after($from)->before($to);\n    }\n\n    /**\n     * Ensure the date is between or equal to two dates or date fields.\n     */\n    public function betweenOrEqual(DateTimeInterface|string $from, DateTimeInterface|string $to): static\n    {\n        return $this->afterOrEqual($from)->beforeOrEqual($to);\n    }\n\n    /**\n     * Add custom rules to the validation rules array.\n     */\n    protected function addRule(array|string $rules): static\n    {\n        $this->constraints = array_merge($this->constraints, Arr::wrap($rules));\n\n        return $this;\n    }\n\n    /**\n     * Format the date for the validation rule.\n     */\n    protected function formatDate(DateTimeInterface|string $date): string\n    {\n        return $date instanceof DateTimeInterface\n            ? $date->format($this->format ?? 'Y-m-d')\n            : $date;\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     */\n    public function __toString(): string\n    {\n        return implode('|', [\n            $this->format === null ? 'date' : 'date_format:'.$this->format,\n            ...$this->constraints,\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Dimensions.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\n\nclass Dimensions implements Stringable\n{\n    use Conditionable;\n\n    /**\n     * The constraints for the dimensions rule.\n     *\n     * @var array\n     */\n    protected $constraints = [];\n\n    /**\n     * Create a new dimensions rule instance.\n     *\n     * @param  array  $constraints\n     */\n    public function __construct(array $constraints = [])\n    {\n        $this->constraints = $constraints;\n    }\n\n    /**\n     * Set the \"width\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function width($value)\n    {\n        $this->constraints['width'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"height\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function height($value)\n    {\n        $this->constraints['height'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"min width\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function minWidth($value)\n    {\n        $this->constraints['min_width'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"min height\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function minHeight($value)\n    {\n        $this->constraints['min_height'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"max width\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function maxWidth($value)\n    {\n        $this->constraints['max_width'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"max height\" constraint.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function maxHeight($value)\n    {\n        $this->constraints['max_height'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the \"ratio\" constraint.\n     *\n     * @param  float  $value\n     * @return $this\n     */\n    public function ratio($value)\n    {\n        $this->constraints['ratio'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the minimum aspect ratio.\n     *\n     * @param  float  $value\n     * @return $this\n     */\n    public function minRatio($value)\n    {\n        $this->constraints['min_ratio'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the maximum aspect ratio.\n     *\n     * @param  float  $value\n     * @return $this\n     */\n    public function maxRatio($value)\n    {\n        $this->constraints['max_ratio'] = $value;\n\n        return $this;\n    }\n\n    /**\n     * Set the aspect ratio range.\n     *\n     * @param  float  $min\n     * @param  float  $max\n     * @return $this\n     */\n    public function ratioBetween($min, $max)\n    {\n        $this->constraints['min_ratio'] = $min;\n        $this->constraints['max_ratio'] = $max;\n\n        return $this;\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $result = '';\n\n        foreach ($this->constraints as $key => $value) {\n            $result .= \"$key=$value,\";\n        }\n\n        return 'dimensions:'.substr($result, 0, -1);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/DoesntContain.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass DoesntContain implements Stringable\n{\n    /**\n     * The values that should not be contained in the attribute.\n     *\n     * @var array\n     */\n    protected $values;\n\n    /**\n     * Create a new doesntContain rule instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     */\n    public function __construct($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->values = is_array($values) ? $values : func_get_args();\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $values = array_map(function ($value) {\n            $value = enum_value($value);\n\n            return '\"'.str_replace('\"', '\"\"', $value).'\"';\n        }, $this->values);\n\n        return 'doesnt_contain:'.implode(',', $values);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Email.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Validation\\DataAwareRule;\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\nclass Email implements Rule, DataAwareRule, ValidatorAwareRule\n{\n    use Conditionable, Macroable;\n\n    public bool $validateMxRecord = false;\n    public bool $preventSpoofing = false;\n    public bool $nativeValidation = false;\n    public bool $nativeValidationWithUnicodeAllowed = false;\n    public bool $rfcCompliant = false;\n    public bool $strictRfcCompliant = false;\n\n    /**\n     * The validator performing the validation.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * The data under validation.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * An array of custom rules that will be merged into the validation rules.\n     *\n     * @var array\n     */\n    protected $customRules = [];\n\n    /**\n     * The error message after validation, if any.\n     *\n     * @var array\n     */\n    protected $messages = [];\n\n    /**\n     * The callback that will generate the \"default\" version of the email rule.\n     *\n     * @var string|array|callable|null\n     */\n    public static $defaultCallback;\n\n    /**\n     * Set the default callback to be used for determining the email default rules.\n     *\n     * If no arguments are passed, the default email rule configuration will be returned.\n     *\n     * @param  static|callable|null  $callback\n     * @return static|void\n     *\n     * @phpstan-return ($callback is null ? static : ($callback is callable ? void : ($callback is static ? void : never)))\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function defaults($callback = null)\n    {\n        if (is_null($callback)) {\n            return static::default();\n        }\n\n        if (! is_callable($callback) && ! $callback instanceof static) {\n            throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);\n        }\n\n        static::$defaultCallback = $callback;\n    }\n\n    /**\n     * Get the default configuration of the email rule.\n     *\n     * @return static\n     */\n    public static function default()\n    {\n        $email = is_callable(static::$defaultCallback)\n            ? call_user_func(static::$defaultCallback)\n            : static::$defaultCallback;\n\n        return $email instanceof static ? $email : new static;\n    }\n\n    /**\n     * Ensure that the email is an RFC compliant email address.\n     *\n     * @param  bool  $strict\n     * @return $this\n     */\n    public function rfcCompliant(bool $strict = false)\n    {\n        if ($strict) {\n            $this->strictRfcCompliant = true;\n        } else {\n            $this->rfcCompliant = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Ensure that the email is a strictly enforced RFC compliant email address.\n     *\n     * @return $this\n     */\n    public function strict()\n    {\n        return $this->rfcCompliant(true);\n    }\n\n    /**\n     * Ensure that the email address has a valid MX record.\n     *\n     * Requires the PHP intl extension.\n     *\n     * @return $this\n     */\n    public function validateMxRecord()\n    {\n        $this->validateMxRecord = true;\n\n        return $this;\n    }\n\n    /**\n     * Ensure that the email address is not attempting to spoof another email address using invalid unicode characters.\n     *\n     * @return $this\n     */\n    public function preventSpoofing()\n    {\n        $this->preventSpoofing = true;\n\n        return $this;\n    }\n\n    /**\n     * Ensure the email address is valid using PHP's native email validation functions.\n     *\n     * @param  bool  $allowUnicode\n     * @return $this\n     */\n    public function withNativeValidation(bool $allowUnicode = false)\n    {\n        if ($allowUnicode) {\n            $this->nativeValidationWithUnicodeAllowed = true;\n        } else {\n            $this->nativeValidation = true;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Specify additional validation rules that should be merged with the default rules during validation.\n     *\n     * @param  string|array  $rules\n     * @return $this\n     */\n    public function rules($rules)\n    {\n        $this->customRules = array_merge($this->customRules, Arr::wrap($rules));\n\n        return $this;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $this->messages = [];\n\n        $validator = Validator::make(\n            $this->data,\n            [$attribute => $this->buildValidationRules()],\n            $this->validator->customMessages,\n            $this->validator->customAttributes\n        );\n\n        if ($validator->fails()) {\n            $this->messages = array_merge($this->messages, $validator->messages()->all());\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Build the array of underlying validation rules based on the current state.\n     *\n     * @return array\n     */\n    protected function buildValidationRules()\n    {\n        $rules = [];\n\n        if ($this->rfcCompliant) {\n            $rules[] = 'rfc';\n        }\n\n        if ($this->strictRfcCompliant) {\n            $rules[] = 'strict';\n        }\n\n        if ($this->validateMxRecord) {\n            $rules[] = 'dns';\n        }\n\n        if ($this->preventSpoofing) {\n            $rules[] = 'spoof';\n        }\n\n        if ($this->nativeValidation) {\n            $rules[] = 'filter';\n        }\n\n        if ($this->nativeValidationWithUnicodeAllowed) {\n            $rules[] = 'filter_unicode';\n        }\n\n        if ($rules) {\n            $rules = ['email:'.implode(',', $rules)];\n        } else {\n            $rules = ['email'];\n        }\n\n        return array_merge(array_filter($rules), $this->customRules);\n    }\n\n    /**\n     * Get the validation error message.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * Set the current data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData($data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Enum.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\nuse TypeError;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass Enum implements Rule, ValidatorAwareRule, Stringable\n{\n    use Conditionable;\n\n    /**\n     * The type of the enum.\n     *\n     * @var class-string<\\UnitEnum>\n     */\n    protected $type;\n\n    /**\n     * The current validator instance.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * The cases that should be considered valid.\n     *\n     * @var array\n     */\n    protected $only = [];\n\n    /**\n     * The cases that should be considered invalid.\n     *\n     * @var array\n     */\n    protected $except = [];\n\n    /**\n     * Create a new rule instance.\n     *\n     * @param  class-string<\\UnitEnum>  $type\n     */\n    public function __construct($type)\n    {\n        $this->type = $type;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        if ($value instanceof $this->type) {\n            return $this->isDesirable($value);\n        }\n\n        if (is_null($value) || ! enum_exists($this->type) || ! method_exists($this->type, 'tryFrom')) {\n            return false;\n        }\n\n        try {\n            $value = $this->type::tryFrom($value);\n\n            return ! is_null($value) && $this->isDesirable($value);\n        } catch (TypeError) {\n            return false;\n        }\n    }\n\n    /**\n     * Specify the cases that should be considered valid.\n     *\n     * @param  \\UnitEnum[]|\\UnitEnum|\\Illuminate\\Contracts\\Support\\Arrayable<array-key, \\UnitEnum>  $values\n     * @return $this\n     */\n    public function only($values)\n    {\n        $this->only = $values instanceof Arrayable ? $values->toArray() : Arr::wrap($values);\n\n        return $this;\n    }\n\n    /**\n     * Specify the cases that should be considered invalid.\n     *\n     * @param  \\UnitEnum[]|\\UnitEnum|\\Illuminate\\Contracts\\Support\\Arrayable<array-key, \\UnitEnum>  $values\n     * @return $this\n     */\n    public function except($values)\n    {\n        $this->except = $values instanceof Arrayable ? $values->toArray() : Arr::wrap($values);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the given case is a valid case based on the only / except values.\n     *\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function isDesirable($value)\n    {\n        return match (true) {\n            ! empty($this->only) => in_array(needle: $value, haystack: $this->only, strict: true),\n            ! empty($this->except) => ! in_array(needle: $value, haystack: $this->except, strict: true),\n            default => true,\n        };\n    }\n\n    /**\n     * Get the validation error message.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        $message = $this->validator->getTranslator()->get('validation.enum');\n\n        return $message === 'validation.enum'\n            ? ['The selected :attribute is invalid.']\n            : $message;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $cases = ! empty($this->only)\n            ? $this->only\n            : array_filter($this->type::cases(), fn ($case) => ! in_array($case, $this->except, true));\n\n        $values = array_map(function ($case) {\n            $value = enum_value($case);\n\n            return '\"'.str_replace('\"', '\"\"', (string) $value).'\"';\n        }, $cases);\n\n        return 'in:'.implode(',', $values);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ExcludeIf.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass ExcludeIf implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new exclude validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? 'exclude' : '';\n        }\n\n        return $this->condition ? 'exclude' : '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ExcludeUnless.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass ExcludeUnless implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new exclude validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? '' : 'exclude';\n        }\n\n        return $this->condition ? '' : 'exclude';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Exists.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\n\nclass Exists implements Stringable\n{\n    use Conditionable, DatabaseRule;\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return rtrim(sprintf('exists:%s,%s,%s',\n            $this->table,\n            $this->column,\n            $this->formatWheres()\n        ), ',');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/File.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Validation\\DataAwareRule;\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse InvalidArgumentException;\n\nclass File implements Rule, DataAwareRule, ValidatorAwareRule\n{\n    use Conditionable, Macroable;\n\n    /**\n     * The MIME types that the given file should match. This array may also contain file extensions.\n     *\n     * @var array\n     */\n    protected $allowedMimetypes = [];\n\n    /**\n     * The extensions that the given file should match.\n     *\n     * @var array\n     */\n    protected $allowedExtensions = [];\n\n    /**\n     * The minimum size in kilobytes that the file can be.\n     *\n     * @var null|int\n     */\n    protected $minimumFileSize = null;\n\n    /**\n     * The maximum size in kilobytes that the file can be.\n     *\n     * @var null|int\n     */\n    protected $maximumFileSize = null;\n\n    /**\n     * The required file encoding.\n     *\n     * @var string|null\n     */\n    protected $encoding = null;\n\n    /**\n     * An array of custom rules that will be merged into the validation rules.\n     *\n     * @var array\n     */\n    protected $customRules = [];\n\n    /**\n     * The error message after validation, if any.\n     *\n     * @var array\n     */\n    protected $messages = [];\n\n    /**\n     * The data under validation.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The validator performing the validation.\n     *\n     * @var \\Illuminate\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * The callback that will generate the \"default\" version of the file rule.\n     *\n     * @var string|array|callable|null\n     */\n    public static $defaultCallback;\n\n    /**\n     * Set the default callback to be used for determining the file default rules.\n     *\n     * If no arguments are passed, the default file rule configuration will be returned.\n     *\n     * @param  static|callable|null  $callback\n     * @return static|void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function defaults($callback = null)\n    {\n        if (is_null($callback)) {\n            return static::default();\n        }\n\n        if (! is_callable($callback) && ! $callback instanceof static) {\n            throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);\n        }\n\n        static::$defaultCallback = $callback;\n    }\n\n    /**\n     * Get the default configuration of the file rule.\n     *\n     * @return static\n     */\n    public static function default()\n    {\n        $file = is_callable(static::$defaultCallback)\n            ? call_user_func(static::$defaultCallback)\n            : static::$defaultCallback;\n\n        return $file instanceof Rule ? $file : new self();\n    }\n\n    /**\n     * Limit the uploaded file to only image types.\n     *\n     * @param  bool  $allowSvg\n     * @return ImageFile\n     */\n    public static function image($allowSvg = false)\n    {\n        return new ImageFile($allowSvg);\n    }\n\n    /**\n     * Limit the uploaded file to the given MIME types or file extensions.\n     *\n     * @param  string|array<int, string>  $mimetypes\n     * @return static\n     */\n    public static function types($mimetypes)\n    {\n        return tap(new static(), fn ($file) => $file->allowedMimetypes = (array) $mimetypes);\n    }\n\n    /**\n     * Limit the uploaded file to the given file extensions.\n     *\n     * @param  string|array<int, string>  $extensions\n     * @return $this\n     */\n    public function extensions($extensions)\n    {\n        $this->allowedExtensions = (array) $extensions;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the uploaded file should be exactly a certain size in kilobytes.\n     *\n     * @param  string|int  $size\n     * @return $this\n     */\n    public function size($size)\n    {\n        $this->minimumFileSize = $this->toKilobytes($size);\n        $this->maximumFileSize = $this->minimumFileSize;\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the uploaded file should be between a minimum and maximum size in kilobytes.\n     *\n     * @param  string|int  $minSize\n     * @param  string|int  $maxSize\n     * @return $this\n     */\n    public function between($minSize, $maxSize)\n    {\n        $this->minimumFileSize = $this->toKilobytes($minSize);\n        $this->maximumFileSize = $this->toKilobytes($maxSize);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the uploaded file should be no less than the given number of kilobytes.\n     *\n     * @param  string|int  $size\n     * @return $this\n     */\n    public function min($size)\n    {\n        $this->minimumFileSize = $this->toKilobytes($size);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the uploaded file should be no more than the given number of kilobytes.\n     *\n     * @param  string|int  $size\n     * @return $this\n     */\n    public function max($size)\n    {\n        $this->maximumFileSize = $this->toKilobytes($size);\n\n        return $this;\n    }\n\n    /**\n     * Indicate that the uploaded file should be in the given encoding.\n     *\n     * @param  string  $encoding\n     * @return $this\n     */\n    public function encoding($encoding)\n    {\n        $this->encoding = $encoding;\n\n        return $this;\n    }\n\n    /**\n     * Convert a potentially human-friendly file size to kilobytes.\n     *\n     * @param  string|int  $size\n     * @return ($size is int ? int : int|float)\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function toKilobytes($size)\n    {\n        if (! is_string($size)) {\n            return $size;\n        }\n\n        $size = strtolower(trim($size));\n\n        $value = (float) $size;\n\n        return round(match (true) {\n            Str::endsWith($size, 'kb') => $value * 1,\n            Str::endsWith($size, 'mb') => $value * 1_000,\n            Str::endsWith($size, 'gb') => $value * 1_000_000,\n            Str::endsWith($size, 'tb') => $value * 1_000_000_000,\n            default => throw new InvalidArgumentException('Invalid file size suffix.'),\n        });\n    }\n\n    /**\n     * Specify additional validation rules that should be merged with the default rules during validation.\n     *\n     * @param  string|array  $rules\n     * @return $this\n     */\n    public function rules($rules)\n    {\n        $this->customRules = array_merge($this->customRules, Arr::wrap($rules));\n\n        return $this;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $this->messages = [];\n\n        $validator = Validator::make(\n            $this->data,\n            [$attribute => $this->buildValidationRules()],\n            $this->validator->customMessages,\n            $this->validator->customAttributes\n        );\n\n        if ($validator->fails()) {\n            return $this->fail($validator->messages()->all());\n        }\n\n        return true;\n    }\n\n    /**\n     * Build the array of underlying validation rules based on the current state.\n     *\n     * @return array\n     */\n    protected function buildValidationRules()\n    {\n        $rules = ['file'];\n\n        $rules = array_merge($rules, $this->buildMimetypes());\n\n        if (! empty($this->allowedExtensions)) {\n            $rules[] = 'extensions:'.implode(',', array_map(strtolower(...), $this->allowedExtensions));\n        }\n\n        $rules[] = match (true) {\n            is_null($this->minimumFileSize) && is_null($this->maximumFileSize) => null,\n            is_null($this->maximumFileSize) => \"min:{$this->minimumFileSize}\",\n            is_null($this->minimumFileSize) => \"max:{$this->maximumFileSize}\",\n            $this->minimumFileSize !== $this->maximumFileSize => \"between:{$this->minimumFileSize},{$this->maximumFileSize}\",\n            default => \"size:{$this->minimumFileSize}\",\n        };\n\n        if ($this->encoding) {\n            $rules[] = 'encoding:'.$this->encoding;\n        }\n\n        return array_merge(array_filter($rules), $this->customRules);\n    }\n\n    /**\n     * Separate the given MIME types from extensions and return an array of correct rules to validate against.\n     *\n     * @return array\n     */\n    protected function buildMimetypes()\n    {\n        if (count($this->allowedMimetypes) === 0) {\n            return [];\n        }\n\n        $rules = [];\n\n        $mimetypes = array_filter(\n            $this->allowedMimetypes,\n            fn ($type) => str_contains($type, '/')\n        );\n\n        $mimes = array_diff($this->allowedMimetypes, $mimetypes);\n\n        if (count($mimetypes) > 0) {\n            $rules[] = 'mimetypes:'.implode(',', $mimetypes);\n        }\n\n        if (count($mimes) > 0) {\n            $rules[] = 'mimes:'.implode(',', $mimes);\n        }\n\n        return $rules;\n    }\n\n    /**\n     * Adds the given failures, and return false.\n     *\n     * @param  array|string  $messages\n     * @return bool\n     */\n    protected function fail($messages)\n    {\n        $this->messages = array_merge($this->messages, Arr::wrap($messages));\n\n        return false;\n    }\n\n    /**\n     * Get the validation error message.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Set the current validator.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * Set the current data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData($data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ImageFile.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nclass ImageFile extends File\n{\n    /**\n     * Create a new image file rule instance.\n     *\n     * @param  bool  $allowSvg\n     */\n    public function __construct($allowSvg = false)\n    {\n        if ($allowSvg) {\n            $this->rules('image:allow_svg');\n        } else {\n            $this->rules('image');\n        }\n    }\n\n    /**\n     * The dimension constraints for the uploaded file.\n     *\n     * @param  \\Illuminate\\Validation\\Rules\\Dimensions  $dimensions\n     * @return $this\n     */\n    public function dimensions($dimensions)\n    {\n        $this->rules($dimensions);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/In.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass In implements Stringable\n{\n    /**\n     * The name of the rule.\n     *\n     * @var string\n     */\n    protected $rule = 'in';\n\n    /**\n     * The accepted values.\n     *\n     * @var array\n     */\n    protected $values;\n\n    /**\n     * Create a new in rule instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     */\n    public function __construct($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->values = is_array($values) ? $values : func_get_args();\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     *\n     * @see \\Illuminate\\Validation\\ValidationRuleParser::parseParameters\n     */\n    public function __toString()\n    {\n        $values = array_map(function ($value) {\n            $value = enum_value($value);\n\n            return '\"'.str_replace('\"', '\"\"', $value).'\"';\n        }, $this->values);\n\n        return $this->rule.':'.implode(',', $values);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/NotIn.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Stringable;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass NotIn implements Stringable\n{\n    /**\n     * The name of the rule.\n     *\n     * @var string\n     */\n    protected $rule = 'not_in';\n\n    /**\n     * The accepted values.\n     *\n     * @var array\n     */\n    protected $values;\n\n    /**\n     * Create a new \"not in\" rule instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|\\UnitEnum|array|string  $values\n     */\n    public function __construct($values)\n    {\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->values = is_array($values) ? $values : func_get_args();\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $values = array_map(function ($value) {\n            $value = enum_value($value);\n\n            return '\"'.str_replace('\"', '\"\"', $value).'\"';\n        }, $this->values);\n\n        return $this->rule.':'.implode(',', $values);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Numeric.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\n\nclass Numeric implements Stringable\n{\n    use Conditionable;\n\n    /**\n     * The constraints for the number rule.\n     */\n    protected array $constraints = ['numeric'];\n\n    /**\n     * The field under validation must have a size between the given min and max (inclusive).\n     *\n     * @param  int|float  $min\n     * @param  int|float  $max\n     * @return $this\n     */\n    public function between(int|float $min, int|float $max): Numeric\n    {\n        return $this->addRule('between:'.$min.','.$max);\n    }\n\n    /**\n     * The field under validation must contain the specified number of decimal places.\n     *\n     * @param  int  $min\n     * @param  int|null  $max\n     * @return $this\n     */\n    public function decimal(int $min, ?int $max = null): Numeric\n    {\n        $rule = 'decimal:'.$min;\n\n        if ($max !== null) {\n            $rule .= ','.$max;\n        }\n\n        return $this->addRule($rule);\n    }\n\n    /**\n     * The field under validation must have a different value than field.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function different(string $field): Numeric\n    {\n        return $this->addRule('different:'.$field);\n    }\n\n    /**\n     * The integer under validation must have an exact number of digits.\n     *\n     * @param  int  $length\n     * @return $this\n     */\n    public function digits(int $length): Numeric\n    {\n        return $this->integer()->addRule('digits:'.$length);\n    }\n\n    /**\n     * The integer under validation must between the given min and max number of digits.\n     *\n     * @param  int  $min\n     * @param  int  $max\n     * @return $this\n     */\n    public function digitsBetween(int $min, int $max): Numeric\n    {\n        return $this->integer()->addRule('digits_between:'.$min.','.$max);\n    }\n\n    /**\n     * The field under validation must be greater than the given field or value.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function greaterThan(string $field): Numeric\n    {\n        return $this->addRule('gt:'.$field);\n    }\n\n    /**\n     * The field under validation must be greater than or equal to the given field or value.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function greaterThanOrEqualTo(string $field): Numeric\n    {\n        return $this->addRule('gte:'.$field);\n    }\n\n    /**\n     * The field under validation must be an integer.\n     *\n     * @return $this\n     */\n    public function integer(bool $strict = false): Numeric\n    {\n        return $this->addRule($strict ? 'integer:strict' : 'integer');\n    }\n\n    /**\n     * The field under validation must be less than the given field.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function lessThan(string $field): Numeric\n    {\n        return $this->addRule('lt:'.$field);\n    }\n\n    /**\n     * The field under validation must be less than or equal to the given field.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function lessThanOrEqualTo(string $field): Numeric\n    {\n        return $this->addRule('lte:'.$field);\n    }\n\n    /**\n     * The field under validation must be less than or equal to a maximum value.\n     *\n     * @param  int|float  $value\n     * @return $this\n     */\n    public function max(int|float $value): Numeric\n    {\n        return $this->addRule('max:'.$value);\n    }\n\n    /**\n     * The integer under validation must have a maximum number of digits.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function maxDigits(int $value): Numeric\n    {\n        return $this->addRule('max_digits:'.$value);\n    }\n\n    /**\n     * The field under validation must have a minimum value.\n     *\n     * @param  int|float  $value\n     * @return $this\n     */\n    public function min(int|float $value): Numeric\n    {\n        return $this->addRule('min:'.$value);\n    }\n\n    /**\n     * The integer under validation must have a minimum number of digits.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function minDigits(int $value): Numeric\n    {\n        return $this->addRule('min_digits:'.$value);\n    }\n\n    /**\n     * The field under validation must be a multiple of the given value.\n     *\n     * @param  int|float  $value\n     * @return $this\n     */\n    public function multipleOf(int|float $value): Numeric\n    {\n        return $this->addRule('multiple_of:'.$value);\n    }\n\n    /**\n     * The given field must match the field under validation.\n     *\n     * @param  string  $field\n     * @return $this\n     */\n    public function same(string $field): Numeric\n    {\n        return $this->addRule('same:'.$field);\n    }\n\n    /**\n     * The field under validation must match the given value.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function exactly(int $value): Numeric\n    {\n        return $this->integer()->addRule('size:'.$value);\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     */\n    public function __toString(): string\n    {\n        return implode('|', array_unique($this->constraints));\n    }\n\n    /**\n     * Add custom rules to the validation rules array.\n     */\n    protected function addRule(array|string $rules): Numeric\n    {\n        $this->constraints = array_merge($this->constraints, Arr::wrap($rules));\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Password.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse ArrayIterator;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Validation\\DataAwareRule;\nuse Illuminate\\Contracts\\Validation\\ImplicitRule;\nuse Illuminate\\Contracts\\Validation\\Rule;\nuse Illuminate\\Contracts\\Validation\\UncompromisedVerifier;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse InvalidArgumentException;\nuse IteratorAggregate;\nuse Traversable;\n\nclass Password implements DataAwareRule, ImplicitRule, IteratorAggregate, Rule, ValidatorAwareRule\n{\n    use Conditionable;\n\n    /**\n     * The validator performing the validation.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    protected $validator;\n\n    /**\n     * The data under validation.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The minimum size of the password.\n     *\n     * @var int\n     */\n    protected $min = 8;\n\n    /**\n     * The maximum size of the password.\n     *\n     * @var int\n     */\n    protected $max;\n\n    /**\n     * If the password is required.\n     *\n     * @var bool\n     */\n    protected $required = false;\n\n    /**\n     * If the password should only be validated when present.\n     *\n     * @var bool\n     */\n    protected $sometimes = false;\n\n    /**\n     * If the password requires at least one uppercase and one lowercase letter.\n     *\n     * @var bool\n     */\n    protected $mixedCase = false;\n\n    /**\n     * If the password requires at least one letter.\n     *\n     * @var bool\n     */\n    protected $letters = false;\n\n    /**\n     * If the password requires at least one number.\n     *\n     * @var bool\n     */\n    protected $numbers = false;\n\n    /**\n     * If the password requires at least one symbol.\n     *\n     * @var bool\n     */\n    protected $symbols = false;\n\n    /**\n     * If the password should not have been compromised in data leaks.\n     *\n     * @var bool\n     */\n    protected $uncompromised = false;\n\n    /**\n     * The number of times a password can appear in data leaks before being considered compromised.\n     *\n     * @var int\n     */\n    protected $compromisedThreshold = 0;\n\n    /**\n     * Additional validation rules that should be merged into the default rules during validation.\n     *\n     * @var array\n     */\n    protected $customRules = [];\n\n    /**\n     * The failure messages, if any.\n     *\n     * @var array\n     */\n    protected $messages = [];\n\n    /**\n     * The callback that will generate the \"default\" version of the password rule.\n     *\n     * @var string|array|callable|null\n     */\n    public static $defaultCallback;\n\n    /**\n     * Create a new rule instance.\n     *\n     * @param  int  $min\n     */\n    public function __construct($min)\n    {\n        $this->min = max((int) $min, 1);\n    }\n\n    /**\n     * Set the default callback to be used for determining a password's default rules.\n     *\n     * If no arguments are passed, the default password rule configuration will be returned.\n     *\n     * @param  static|callable|null  $callback\n     * @return static|void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public static function defaults($callback = null)\n    {\n        if (is_null($callback)) {\n            return static::default();\n        }\n\n        if (! is_callable($callback) && ! $callback instanceof static) {\n            throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class);\n        }\n\n        static::$defaultCallback = $callback;\n    }\n\n    /**\n     * Get the default configuration of the password rule.\n     *\n     * @return static\n     */\n    public static function default()\n    {\n        $password = is_callable(static::$defaultCallback)\n            ? call_user_func(static::$defaultCallback)\n            : static::$defaultCallback;\n\n        return $password instanceof Rule ? $password : static::min(8);\n    }\n\n    /**\n     * Get the default configuration of the password rule and mark the field as required.\n     *\n     * @return static\n     */\n    public static function required()\n    {\n        $password = static::default();\n\n        $password->required = true;\n\n        return $password;\n    }\n\n    /**\n     * Get the default configuration of the password rule and mark the field as sometimes being required.\n     *\n     * @return static\n     */\n    public static function sometimes()\n    {\n        $password = static::default();\n\n        $password->sometimes = true;\n\n        return $password;\n    }\n\n    /**\n     * Set the performing validator.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return $this\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * Set the data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData($data)\n    {\n        $this->data = $data;\n\n        return $this;\n    }\n\n    /**\n     * Set the minimum size of the password.\n     *\n     * @param  int  $size\n     * @return $this\n     */\n    public static function min($size)\n    {\n        return new static($size);\n    }\n\n    /**\n     * Set the maximum size of the password.\n     *\n     * @param  int  $size\n     * @return $this\n     */\n    public function max($size)\n    {\n        $this->max = $size;\n\n        return $this;\n    }\n\n    /**\n     * Ensures the password has not been compromised in data leaks.\n     *\n     * @param  int  $threshold\n     * @return $this\n     */\n    public function uncompromised($threshold = 0)\n    {\n        $this->uncompromised = true;\n\n        $this->compromisedThreshold = $threshold;\n\n        return $this;\n    }\n\n    /**\n     * Makes the password require at least one uppercase and one lowercase letter.\n     *\n     * @return $this\n     */\n    public function mixedCase()\n    {\n        $this->mixedCase = true;\n\n        return $this;\n    }\n\n    /**\n     * Makes the password require at least one letter.\n     *\n     * @return $this\n     */\n    public function letters()\n    {\n        $this->letters = true;\n\n        return $this;\n    }\n\n    /**\n     * Makes the password require at least one number.\n     *\n     * @return $this\n     */\n    public function numbers()\n    {\n        $this->numbers = true;\n\n        return $this;\n    }\n\n    /**\n     * Makes the password require at least one symbol.\n     *\n     * @return $this\n     */\n    public function symbols()\n    {\n        $this->symbols = true;\n\n        return $this;\n    }\n\n    /**\n     * Specify additional validation rules that should be merged with the default rules during validation.\n     *\n     * @param  \\Closure|string|array  $rules\n     * @return $this\n     */\n    public function rules($rules)\n    {\n        $this->customRules = Arr::wrap($rules);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the validation rule passes.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function passes($attribute, $value)\n    {\n        $this->messages = [];\n\n        if (! $this->required && ! $this->sometimes && ! Arr::has($this->data ?? [], $attribute)) {\n            return true;\n        }\n\n        if (blank($value) && ! $this->required && $this->validator?->hasRule($attribute, ['Nullable'])) {\n            return true;\n        }\n\n        $validator = Validator::make(\n            $this->data,\n            [$attribute => [...$this]],\n            $this->validator->customMessages,\n            $this->validator->customAttributes\n        )->after(function ($validator) use ($attribute, $value) {\n            if (! is_string($value)) {\n                return;\n            }\n\n            if ($this->mixedCase && ! preg_match('/(\\p{Ll}+.*\\p{Lu})|(\\p{Lu}+.*\\p{Ll})/u', $value)) {\n                $validator->addFailure($attribute, 'password.mixed');\n            }\n\n            if ($this->letters && ! preg_match('/\\pL/u', $value)) {\n                $validator->addFailure($attribute, 'password.letters');\n            }\n\n            if ($this->symbols && ! preg_match('/\\p{Z}|\\p{S}|\\p{P}/u', $value)) {\n                $validator->addFailure($attribute, 'password.symbols');\n            }\n\n            if ($this->numbers && ! preg_match('/\\pN/u', $value)) {\n                $validator->addFailure($attribute, 'password.numbers');\n            }\n        });\n\n        if ($validator->fails()) {\n            return $this->fail($validator->messages()->all());\n        }\n\n        if ($this->uncompromised && ! Container::getInstance()->make(UncompromisedVerifier::class)->verify([\n            'value' => $value,\n            'threshold' => $this->compromisedThreshold,\n        ])) {\n            $validator->addFailure($attribute, 'password.uncompromised');\n\n            return $this->fail($validator->messages()->all());\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the validation error message.\n     *\n     * @return array\n     */\n    public function message()\n    {\n        return $this->messages;\n    }\n\n    /**\n     * Adds the given failures, and return false.\n     *\n     * @param  array|string  $messages\n     * @return bool\n     */\n    protected function fail($messages)\n    {\n        $this->messages = array_merge($this->messages, Arr::wrap($messages));\n\n        return false;\n    }\n\n    /**\n     * Get information about the current state of the password validation rules.\n     *\n     * @return array\n     */\n    public function appliedRules()\n    {\n        return [\n            'min' => $this->min,\n            'max' => $this->max,\n            'mixedCase' => $this->mixedCase,\n            'letters' => $this->letters,\n            'numbers' => $this->numbers,\n            'symbols' => $this->symbols,\n            'uncompromised' => $this->uncompromised,\n            'compromisedThreshold' => $this->compromisedThreshold,\n            'customRules' => $this->customRules,\n        ];\n    }\n\n    /**\n     * Get an iterator for the password validation rules.\n     *\n     * @return \\ArrayIterator<TKey, TValue>\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator([\n            ...($this->required ? ['required'] : []),\n            ...($this->sometimes ? ['sometimes'] : []),\n            'string',\n            'min:'.$this->min,\n            ...($this->max ? ['max:'.$this->max] : []),\n            ...$this->customRules,\n        ]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ProhibitedIf.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass ProhibitedIf implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new prohibited validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? 'prohibited' : '';\n        }\n\n        return $this->condition ? 'prohibited' : '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/ProhibitedUnless.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass ProhibitedUnless implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new prohibited validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? '' : 'prohibited';\n        }\n\n        return $this->condition ? '' : 'prohibited';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/RequiredIf.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass RequiredIf implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new required validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool|null  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if (is_null($condition)) {\n            $condition = false;\n        }\n\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? 'required' : '';\n        }\n\n        return $this->condition ? 'required' : '';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/RequiredUnless.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Closure;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass RequiredUnless implements Stringable\n{\n    /**\n     * The condition that validates the attribute.\n     *\n     * @var (\\Closure(): bool)|bool\n     */\n    public $condition;\n\n    /**\n     * Create a new required validation rule based on a condition.\n     *\n     * @param  (\\Closure(): bool)|bool|null  $condition\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($condition)\n    {\n        if (is_null($condition)) {\n            $condition = false;\n        }\n\n        if ($condition instanceof Closure || is_bool($condition)) {\n            $this->condition = $condition;\n        } else {\n            throw new InvalidArgumentException('The provided condition must be a callable or boolean.');\n        }\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        if (is_callable($this->condition)) {\n            return call_user_func($this->condition) ? '' : 'required';\n        }\n\n        return $this->condition ? '' : 'required';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/StringRule.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\n\nclass StringRule implements Stringable\n{\n    use Conditionable;\n\n    /**\n     * The constraints for the string rule.\n     */\n    protected array $constraints = ['string'];\n\n    /**\n     * The field under validation must be entirely alphabetic characters.\n     *\n     * @param  bool  $ascii\n     * @return $this\n     */\n    public function alpha(bool $ascii = false): static\n    {\n        return $this->addRule($ascii ? 'alpha:ascii' : 'alpha');\n    }\n\n    /**\n     * The field under validation must be entirely alpha-numeric characters, dashes, and underscores.\n     *\n     * @param  bool  $ascii\n     * @return $this\n     */\n    public function alphaDash(bool $ascii = false): static\n    {\n        return $this->addRule($ascii ? 'alpha_dash:ascii' : 'alpha_dash');\n    }\n\n    /**\n     * The field under validation must be entirely alpha-numeric characters.\n     *\n     * @param  bool  $ascii\n     * @return $this\n     */\n    public function alphaNumeric(bool $ascii = false): static\n    {\n        return $this->addRule($ascii ? 'alpha_num:ascii' : 'alpha_num');\n    }\n\n    /**\n     * The field under validation must be entirely ASCII characters.\n     *\n     * @return $this\n     */\n    public function ascii(): static\n    {\n        return $this->addRule('ascii');\n    }\n\n    /**\n     * The field under validation must have a length between the given min and max (inclusive).\n     *\n     * @param  int  $min\n     * @param  int  $max\n     * @return $this\n     */\n    public function between(int $min, int $max): static\n    {\n        return $this->addRule('between:'.$min.','.$max);\n    }\n\n    /**\n     * The field under validation must not end with any of the given values.\n     *\n     * @param  string  ...$values\n     * @return $this\n     */\n    public function doesntEndWith(string ...$values): static\n    {\n        return $this->addRule('doesnt_end_with:'.implode(',', $values));\n    }\n\n    /**\n     * The field under validation must not start with any of the given values.\n     *\n     * @param  string  ...$values\n     * @return $this\n     */\n    public function doesntStartWith(string ...$values): static\n    {\n        return $this->addRule('doesnt_start_with:'.implode(',', $values));\n    }\n\n    /**\n     * The field under validation must end with one of the given values.\n     *\n     * @param  string  ...$values\n     * @return $this\n     */\n    public function endsWith(string ...$values): static\n    {\n        return $this->addRule('ends_with:'.implode(',', $values));\n    }\n\n    /**\n     * The field under validation must have an exact length.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function exactly(int $value): static\n    {\n        return $this->addRule('size:'.$value);\n    }\n\n    /**\n     * The field under validation must be entirely lowercase.\n     *\n     * @return $this\n     */\n    public function lowercase(): static\n    {\n        return $this->addRule('lowercase');\n    }\n\n    /**\n     * The field under validation must not exceed the given length.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function max(int $value): static\n    {\n        return $this->addRule('max:'.$value);\n    }\n\n    /**\n     * The field under validation must have a minimum length.\n     *\n     * @param  int  $value\n     * @return $this\n     */\n    public function min(int $value): static\n    {\n        return $this->addRule('min:'.$value);\n    }\n\n    /**\n     * The field under validation must start with one of the given values.\n     *\n     * @param  string  ...$values\n     * @return $this\n     */\n    public function startsWith(string ...$values): static\n    {\n        return $this->addRule('starts_with:'.implode(',', $values));\n    }\n\n    /**\n     * The field under validation must be entirely uppercase.\n     *\n     * @return $this\n     */\n    public function uppercase(): static\n    {\n        return $this->addRule('uppercase');\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     */\n    public function __toString(): string\n    {\n        return implode('|', array_unique($this->constraints));\n    }\n\n    /**\n     * Add custom rules to the validation rules array.\n     */\n    protected function addRule(array|string $rules): static\n    {\n        $this->constraints = array_merge($this->constraints, Arr::wrap($rules));\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Rules/Unique.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation\\Rules;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Stringable;\n\nclass Unique implements Stringable\n{\n    use Conditionable, DatabaseRule;\n\n    /**\n     * The ID that should be ignored.\n     *\n     * @var mixed\n     */\n    protected $ignore;\n\n    /**\n     * The name of the ID column.\n     *\n     * @var string\n     */\n    protected $idColumn = 'id';\n\n    /**\n     * Ignore the given ID during the unique check.\n     *\n     * @param  mixed  $id\n     * @param  string|null  $idColumn\n     * @return $this\n     */\n    public function ignore($id, $idColumn = null)\n    {\n        if ($id instanceof Model) {\n            return $this->ignoreModel($id, $idColumn);\n        }\n\n        $this->ignore = $id;\n        $this->idColumn = $idColumn ?? 'id';\n\n        return $this;\n    }\n\n    /**\n     * Ignore the given model during the unique check.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string|null  $idColumn\n     * @return $this\n     */\n    public function ignoreModel($model, $idColumn = null)\n    {\n        $this->idColumn = $idColumn ?? $model->getKeyName();\n        $this->ignore = $model->{$this->idColumn};\n\n        return $this;\n    }\n\n    /**\n     * Convert the rule to a validation string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return rtrim(sprintf('unique:%s,%s,%s,%s,%s',\n            $this->table,\n            $this->column,\n            $this->ignore ? '\"'.addslashes($this->ignore).'\"' : 'NULL',\n            $this->idColumn,\n            $this->formatWheres()\n        ), ',');\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/UnauthorizedException.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse RuntimeException;\n\nclass UnauthorizedException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ValidatesWhenResolvedTrait.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Foundation\\Precognition;\n\n/**\n * Provides default implementation of ValidatesWhenResolved contract.\n */\ntrait ValidatesWhenResolvedTrait\n{\n    /**\n     * Validate the class instance.\n     *\n     * @return void\n     */\n    public function validateResolved()\n    {\n        $this->prepareForValidation();\n\n        if (! $this->passesAuthorization()) {\n            $this->failedAuthorization();\n        }\n\n        $instance = $this->getValidatorInstance();\n\n        if ($this->isPrecognitive()) {\n            $instance->after(Precognition::afterValidationHook($this));\n        }\n\n        if ($instance->fails()) {\n            $this->failedValidation($instance);\n        }\n\n        $this->passedValidation();\n    }\n\n    /**\n     * Prepare the data for validation.\n     *\n     * @return void\n     */\n    protected function prepareForValidation()\n    {\n        //\n    }\n\n    /**\n     * Get the validator instance for the request.\n     *\n     * @return \\Illuminate\\Validation\\Validator\n     */\n    protected function getValidatorInstance()\n    {\n        return $this->validator();\n    }\n\n    /**\n     * Handle a passed validation attempt.\n     *\n     * @return void\n     */\n    protected function passedValidation()\n    {\n        //\n    }\n\n    /**\n     * Handle a failed validation attempt.\n     *\n     * @param  \\Illuminate\\Validation\\Validator  $validator\n     * @return void\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    protected function failedValidation(Validator $validator)\n    {\n        $exception = $validator->getException();\n\n        throw new $exception($validator);\n    }\n\n    /**\n     * Determine if the request passes the authorization check.\n     *\n     * @return bool\n     */\n    protected function passesAuthorization()\n    {\n        if (method_exists($this, 'authorize')) {\n            return $this->authorize();\n        }\n\n        return true;\n    }\n\n    /**\n     * Handle a failed authorization attempt.\n     *\n     * @return void\n     *\n     * @throws \\Illuminate\\Validation\\UnauthorizedException\n     */\n    protected function failedAuthorization()\n    {\n        throw new UnauthorizedException;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ValidationData.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Support\\Arr;\n\nclass ValidationData\n{\n    /**\n     * Initialize and gather data for the given attribute.\n     *\n     * @param  string  $attribute\n     * @param  array  $masterData\n     * @return array\n     */\n    public static function initializeAndGatherData($attribute, $masterData)\n    {\n        $data = Arr::dot(static::initializeAttributeOnData($attribute, $masterData));\n\n        return array_merge($data, static::extractValuesForWildcards(\n            $masterData, $data, $attribute\n        ));\n    }\n\n    /**\n     * Gather a copy of the attribute data filled with any missing attributes.\n     *\n     * @param  string  $attribute\n     * @param  array  $masterData\n     * @return array\n     */\n    protected static function initializeAttributeOnData($attribute, $masterData)\n    {\n        $explicitPath = static::getLeadingExplicitAttributePath($attribute);\n\n        $data = static::extractDataFromPath($explicitPath, $masterData);\n\n        if (! str_contains($attribute, '*') || str_ends_with($attribute, '*')) {\n            return $data;\n        }\n\n        return data_set($data, $attribute, null, true);\n    }\n\n    /**\n     * Get all of the exact attribute values for a given wildcard attribute.\n     *\n     * @param  array  $masterData\n     * @param  array  $data\n     * @param  string  $attribute\n     * @return array\n     */\n    protected static function extractValuesForWildcards($masterData, $data, $attribute)\n    {\n        $keys = [];\n\n        $pattern = str_replace('\\*', '[^\\.]+', preg_quote($attribute, '/'));\n\n        foreach ($data as $key => $value) {\n            if ((bool) preg_match('/^'.$pattern.'/', $key, $matches)) {\n                $keys[] = $matches[0];\n            }\n        }\n\n        $keys = array_unique($keys);\n\n        $data = [];\n\n        foreach ($keys as $key) {\n            $data[$key] = Arr::get($masterData, $key);\n        }\n\n        return $data;\n    }\n\n    /**\n     * Extract data based on the given dot-notated path.\n     *\n     * Used to extract a sub-section of the data for faster iteration.\n     *\n     * @param  string  $attribute\n     * @param  array  $masterData\n     * @return array\n     */\n    public static function extractDataFromPath($attribute, $masterData)\n    {\n        $results = [];\n\n        $value = Arr::get($masterData, $attribute, '__missing__');\n\n        if ($value !== '__missing__') {\n            Arr::set($results, $attribute, $value);\n        }\n\n        return $results;\n    }\n\n    /**\n     * Get the explicit part of the attribute name.\n     *\n     * E.g. 'foo.bar.*.baz' -> 'foo.bar'\n     *\n     * Allows us to not spin through all of the flattened data for some operations.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    public static function getLeadingExplicitAttributePath($attribute)\n    {\n        return rtrim(explode('*', $attribute)[0], '.') ?: null;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ValidationException.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Exception;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Validator as ValidatorFacade;\n\nclass ValidationException extends Exception\n{\n    /**\n     * The validator instance.\n     *\n     * @var \\Illuminate\\Contracts\\Validation\\Validator\n     */\n    public $validator;\n\n    /**\n     * The recommended response to send to the client.\n     *\n     * @var \\Symfony\\Component\\HttpFoundation\\Response|null\n     */\n    public $response;\n\n    /**\n     * The status code to use for the response.\n     *\n     * @var int\n     */\n    public $status = 422;\n\n    /**\n     * The name of the error bag.\n     *\n     * @var string\n     */\n    public $errorBag;\n\n    /**\n     * The path the client should be redirected to.\n     *\n     * @var string|null\n     */\n    public $redirectTo;\n\n    /**\n     * Create a new exception instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @param  \\Symfony\\Component\\HttpFoundation\\Response|null  $response\n     * @param  string  $errorBag\n     */\n    public function __construct($validator, $response = null, $errorBag = 'default')\n    {\n        parent::__construct(static::summarize($validator));\n\n        $this->response = $response;\n        $this->errorBag = $errorBag;\n        $this->validator = $validator;\n    }\n\n    /**\n     * Create a new validation exception from a plain array of messages.\n     *\n     * @param  array  $messages\n     * @return static\n     */\n    public static function withMessages(array $messages)\n    {\n        return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) {\n            foreach ($messages as $key => $value) {\n                foreach (Arr::wrap($value) as $message) {\n                    $validator->errors()->add($key, $message);\n                }\n            }\n        }));\n    }\n\n    /**\n     * Create an error message summary from the validation errors.\n     *\n     * @param  \\Illuminate\\Contracts\\Validation\\Validator  $validator\n     * @return string\n     */\n    protected static function summarize($validator)\n    {\n        $messages = $validator->errors()->all();\n\n        if (! count($messages) || ! is_string($messages[0])) {\n            return $validator->getTranslator()->get('The given data was invalid.');\n        }\n\n        $message = array_shift($messages);\n\n        if ($count = count($messages)) {\n            $pluralized = $count === 1 ? 'error' : 'errors';\n\n            $message .= ' '.$validator->getTranslator()->choice(\"(and :count more $pluralized)\", $count, compact('count'));\n        }\n\n        return $message;\n    }\n\n    /**\n     * Get all of the validation error messages.\n     *\n     * @return array\n     */\n    public function errors()\n    {\n        return $this->validator->errors()->messages();\n    }\n\n    /**\n     * Set the HTTP status code to be used for the response.\n     *\n     * @param  int  $status\n     * @return $this\n     */\n    public function status($status)\n    {\n        $this->status = $status;\n\n        return $this;\n    }\n\n    /**\n     * Set the error bag on the exception.\n     *\n     * @param  string  $errorBag\n     * @return $this\n     */\n    public function errorBag($errorBag)\n    {\n        $this->errorBag = $errorBag;\n\n        return $this;\n    }\n\n    /**\n     * Set the URL to redirect to on a validation error.\n     *\n     * @param  string  $url\n     * @return $this\n     */\n    public function redirectTo($url)\n    {\n        $this->redirectTo = $url;\n\n        return $this;\n    }\n\n    /**\n     * Get the underlying response instance.\n     *\n     * @return \\Symfony\\Component\\HttpFoundation\\Response|null\n     */\n    public function getResponse()\n    {\n        return $this->response;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ValidationRuleParser.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Closure;\nuse Illuminate\\Contracts\\Validation\\CompilableRules;\nuse Illuminate\\Contracts\\Validation\\InvokableRule;\nuse Illuminate\\Contracts\\Validation\\Rule as RuleContract;\nuse Illuminate\\Contracts\\Validation\\ValidationRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Validation\\Rules\\Date;\nuse Illuminate\\Validation\\Rules\\Exists;\nuse Illuminate\\Validation\\Rules\\Numeric;\nuse Illuminate\\Validation\\Rules\\StringRule;\nuse Illuminate\\Validation\\Rules\\Unique;\n\nclass ValidationRuleParser\n{\n    /**\n     * The data being validated.\n     *\n     * @var array\n     */\n    public $data;\n\n    /**\n     * The implicit attributes.\n     *\n     * @var array\n     */\n    public $implicitAttributes = [];\n\n    /**\n     * Create a new validation rule parser.\n     *\n     * @param  array  $data\n     */\n    public function __construct(array $data)\n    {\n        $this->data = $data;\n    }\n\n    /**\n     * Parse the human-friendly rules into a full rules array for the validator.\n     *\n     * @param  array  $rules\n     * @return \\stdClass\n     */\n    public function explode($rules)\n    {\n        $this->implicitAttributes = [];\n\n        $rules = $this->explodeRules($rules);\n\n        return (object) [\n            'rules' => $rules,\n            'implicitAttributes' => $this->implicitAttributes,\n        ];\n    }\n\n    /**\n     * Explode the rules into an array of explicit rules.\n     *\n     * @param  array  $rules\n     * @return array\n     */\n    protected function explodeRules($rules)\n    {\n        foreach ($rules as $key => $rule) {\n            if (str_contains($key, '*')) {\n                $rules = $this->explodeWildcardRules($rules, $key, [$rule]);\n\n                unset($rules[$key]);\n            } else {\n                $rules[$key] = $this->explodeExplicitRule($rule, $key);\n            }\n        }\n\n        return $rules;\n    }\n\n    /**\n     * Explode the explicit rule into an array if necessary.\n     *\n     * @param  mixed  $rule\n     * @param  string  $attribute\n     * @return array\n     */\n    protected function explodeExplicitRule($rule, $attribute)\n    {\n        if (is_string($rule)) {\n            return explode('|', $rule);\n        }\n\n        if (is_object($rule)) {\n            if ($rule instanceof Date || $rule instanceof Numeric || $rule instanceof StringRule) {\n                return explode('|', (string) $rule);\n            }\n\n            return Arr::wrap($this->prepareRule($rule, $attribute));\n        }\n\n        $rules = [];\n\n        foreach ($rule as $value) {\n            if ($value instanceof Date || $value instanceof Numeric || $value instanceof StringRule) {\n                $rules = array_merge($rules, explode('|', (string) $value));\n            } else {\n                $rules[] = $this->prepareRule($value, $attribute);\n            }\n        }\n\n        return $rules;\n    }\n\n    /**\n     * Prepare the given rule for the Validator.\n     *\n     * @param  mixed  $rule\n     * @param  string  $attribute\n     * @return mixed\n     */\n    protected function prepareRule($rule, $attribute)\n    {\n        if ($rule instanceof Closure) {\n            $rule = new ClosureValidationRule($rule);\n        }\n\n        if ($rule instanceof InvokableRule || $rule instanceof ValidationRule) {\n            $rule = InvokableValidationRule::make($rule);\n        }\n\n        if (! is_object($rule) ||\n            $rule instanceof RuleContract ||\n            ($rule instanceof Exists && $rule->queryCallbacks()) ||\n            ($rule instanceof Unique && $rule->queryCallbacks())) {\n            return $rule;\n        }\n\n        if ($rule instanceof CompilableRules) {\n            return $rule->compile(\n                $attribute, $this->data[$attribute] ?? null, Arr::dot($this->data), $this->data\n            )->rules[$attribute];\n        }\n\n        return (string) $rule;\n    }\n\n    /**\n     * Define a set of rules that apply to each element in an array attribute.\n     *\n     * @param  array  $results\n     * @param  string  $attribute\n     * @param  string|array  $rules\n     * @return array\n     */\n    protected function explodeWildcardRules($results, $attribute, $rules)\n    {\n        $pattern = str_replace('\\*', '[^\\.]*', preg_quote($attribute, '/'));\n\n        $data = ValidationData::initializeAndGatherData($attribute, $this->data);\n\n        foreach ($data as $key => $value) {\n            if (Str::startsWith($key, $attribute) || (bool) preg_match('/^'.$pattern.'\\z/', $key)) {\n                foreach ((array) $rules as $rule) {\n                    if ($rule instanceof CompilableRules) {\n                        $context = Arr::get($this->data, Str::beforeLast($key, '.'));\n\n                        $compiled = $rule->compile($key, $value, $data, $context);\n\n                        $this->implicitAttributes = array_merge_recursive(\n                            $compiled->implicitAttributes,\n                            $this->implicitAttributes,\n                            [$attribute => [$key]]\n                        );\n\n                        $results = $this->mergeRules($results, $compiled->rules);\n                    } else {\n                        $this->implicitAttributes[$attribute][] = $key;\n\n                        $results = $this->mergeRules($results, $key, $rule);\n                    }\n                }\n            }\n        }\n\n        return $results;\n    }\n\n    /**\n     * Merge additional rules into a given attribute(s).\n     *\n     * @param  array  $results\n     * @param  string|array  $attribute\n     * @param  string|array  $rules\n     * @return array\n     */\n    public function mergeRules($results, $attribute, $rules = [])\n    {\n        if (is_array($attribute)) {\n            foreach ((array) $attribute as $innerAttribute => $innerRules) {\n                $results = $this->mergeRulesForAttribute($results, $innerAttribute, $innerRules);\n            }\n\n            return $results;\n        }\n\n        return $this->mergeRulesForAttribute(\n            $results, $attribute, $rules\n        );\n    }\n\n    /**\n     * Merge additional rules into a given attribute.\n     *\n     * @param  array  $results\n     * @param  string  $attribute\n     * @param  string|array  $rules\n     * @return array\n     */\n    protected function mergeRulesForAttribute($results, $attribute, $rules)\n    {\n        $merge = head($this->explodeRules([$rules]));\n\n        $results[$attribute] = array_merge(\n            isset($results[$attribute]) ? $this->explodeExplicitRule($results[$attribute], $attribute) : [], $merge\n        );\n\n        return $results;\n    }\n\n    /**\n     * Extract the rule name and parameters from a rule.\n     *\n     * @param  array|string  $rule\n     * @return array\n     */\n    public static function parse($rule)\n    {\n        if ($rule instanceof RuleContract || $rule instanceof CompilableRules) {\n            return [$rule, []];\n        }\n\n        if (is_array($rule)) {\n            $rule = static::parseArrayRule($rule);\n        } else {\n            $rule = static::parseStringRule($rule);\n        }\n\n        $rule[0] = static::normalizeRule($rule[0]);\n\n        return $rule;\n    }\n\n    /**\n     * Parse an array based rule.\n     *\n     * @param  array  $rule\n     * @return array\n     */\n    protected static function parseArrayRule(array $rule)\n    {\n        return [Str::studly(trim(Arr::get($rule, 0, ''))), array_slice($rule, 1)];\n    }\n\n    /**\n     * Parse a string based rule.\n     *\n     * @param  string  $rule\n     * @return array\n     */\n    protected static function parseStringRule($rule)\n    {\n        $parameters = [];\n\n        // The format for specifying validation rules and parameters follows an\n        // easy {rule}:{parameters} formatting convention. For instance the\n        // rule \"Max:3\" states that the value may only be three letters.\n        if (str_contains($rule, ':')) {\n            [$rule, $parameter] = explode(':', $rule, 2);\n\n            $parameters = static::parseParameters($rule, $parameter);\n        }\n\n        return [Str::studly(trim($rule)), $parameters];\n    }\n\n    /**\n     * Parse a parameter list.\n     *\n     * @param  string  $rule\n     * @param  string  $parameter\n     * @return array\n     */\n    protected static function parseParameters($rule, $parameter)\n    {\n        return static::ruleIsRegex($rule) ? [$parameter] : str_getcsv($parameter, escape: '\\\\');\n    }\n\n    /**\n     * Determine if the rule is a regular expression.\n     *\n     * @param  string  $rule\n     * @return bool\n     */\n    protected static function ruleIsRegex($rule)\n    {\n        return in_array(strtolower($rule), ['regex', 'not_regex', 'notregex'], true);\n    }\n\n    /**\n     * Normalizes a rule so that we can accept short types.\n     *\n     * @param  string  $rule\n     * @return string\n     */\n    protected static function normalizeRule($rule)\n    {\n        return match ($rule) {\n            'Int' => 'Integer',\n            'Bool' => 'Boolean',\n            default => $rule,\n        };\n    }\n\n    /**\n     * Expand the conditional rules in the given array of rules.\n     *\n     * @param  array  $rules\n     * @param  array  $data\n     * @return array\n     */\n    public static function filterConditionalRules($rules, array $data = [])\n    {\n        return (new Collection($rules))->mapWithKeys(function ($attributeRules, $attribute) use ($data) {\n            if (! is_array($attributeRules) &&\n                ! $attributeRules instanceof ConditionalRules) {\n                return [$attribute => $attributeRules];\n            }\n\n            if ($attributeRules instanceof ConditionalRules) {\n                return [$attribute => $attributeRules->passes($data)\n                    ? array_filter($attributeRules->rules($data))\n                    : array_filter($attributeRules->defaultRules($data)), ];\n            }\n\n            return [$attribute => (new Collection($attributeRules))->map(function ($rule) use ($data) {\n                if (! $rule instanceof ConditionalRules) {\n                    return [$rule];\n                }\n\n                return $rule->passes($data) ? $rule->rules($data) : $rule->defaultRules($data);\n            })->filter()->flatten(1)->values()->all()];\n        })->all();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/ValidationServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Contracts\\Validation\\UncompromisedVerifier;\nuse Illuminate\\Http\\Client\\Factory as HttpFactory;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass ValidationServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerPresenceVerifier();\n        $this->registerUncompromisedVerifier();\n        $this->registerValidationFactory();\n    }\n\n    /**\n     * Register the validation factory.\n     *\n     * @return void\n     */\n    protected function registerValidationFactory()\n    {\n        $this->app->singleton('validator', function ($app) {\n            $validator = new Factory($app['translator'], $app);\n\n            // The validation presence verifier is responsible for determining the existence of\n            // values in a given data collection which is typically a relational database or\n            // other persistent data stores. It is used to check for \"uniqueness\" as well.\n            if (isset($app['db'], $app['validation.presence'])) {\n                $validator->setPresenceVerifier($app['validation.presence']);\n            }\n\n            return $validator;\n        });\n    }\n\n    /**\n     * Register the database presence verifier.\n     *\n     * @return void\n     */\n    protected function registerPresenceVerifier()\n    {\n        $this->app->singleton('validation.presence', function ($app) {\n            return new DatabasePresenceVerifier($app['db']);\n        });\n    }\n\n    /**\n     * Register the uncompromised password verifier.\n     *\n     * @return void\n     */\n    protected function registerUncompromisedVerifier()\n    {\n        $this->app->singleton(UncompromisedVerifier::class, function ($app) {\n            return new NotPwnedVerifier($app[HttpFactory::class]);\n        });\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array\n     */\n    public function provides()\n    {\n        return ['validator', 'validation.presence', UncompromisedVerifier::class];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/Validator.php",
    "content": "<?php\n\nnamespace Illuminate\\Validation;\n\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Translation\\Translator;\nuse Illuminate\\Contracts\\Validation\\DataAwareRule;\nuse Illuminate\\Contracts\\Validation\\ImplicitRule;\nuse Illuminate\\Contracts\\Validation\\Rule as RuleContract;\nuse Illuminate\\Contracts\\Validation\\Validator as ValidatorContract;\nuse Illuminate\\Contracts\\Validation\\ValidatorAwareRule;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\ValidatedInput;\nuse InvalidArgumentException;\nuse RuntimeException;\nuse stdClass;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile;\n\nclass Validator implements ValidatorContract\n{\n    use Concerns\\FormatsMessages,\n        Concerns\\ValidatesAttributes;\n\n    /**\n     * The Translator implementation.\n     *\n     * @var \\Illuminate\\Contracts\\Translation\\Translator\n     */\n    protected $translator;\n\n    /**\n     * The container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * The Presence Verifier implementation.\n     *\n     * @var \\Illuminate\\Validation\\PresenceVerifierInterface\n     */\n    protected $presenceVerifier;\n\n    /**\n     * The failed validation rules.\n     *\n     * @var array\n     */\n    protected $failedRules = [];\n\n    /**\n     * Attributes that should be excluded from the validated data.\n     *\n     * @var array\n     */\n    protected $excludeAttributes = [];\n\n    /**\n     * The message bag instance.\n     *\n     * @var \\Illuminate\\Support\\MessageBag\n     */\n    protected $messages;\n\n    /**\n     * The data under validation.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The initial rules provided.\n     *\n     * @var array\n     */\n    protected $initialRules;\n\n    /**\n     * The rules to be applied to the data.\n     *\n     * @var array\n     */\n    protected $rules;\n\n    /**\n     * The current rule that is validating.\n     *\n     * @var string\n     */\n    protected $currentRule;\n\n    /**\n     * The array of wildcard attributes with their asterisks expanded.\n     *\n     * @var array\n     */\n    protected $implicitAttributes = [];\n\n    /**\n     * The callback that should be used to format the attribute.\n     *\n     * @var callable|null\n     */\n    protected $implicitAttributesFormatter;\n\n    /**\n     * The cached data for the \"distinct\" rule.\n     *\n     * @var array\n     */\n    protected $distinctValues = [];\n\n    /**\n     * All of the registered \"after\" callbacks.\n     *\n     * @var array\n     */\n    protected $after = [];\n\n    /**\n     * The array of custom error messages.\n     *\n     * @var array\n     */\n    public $customMessages = [];\n\n    /**\n     * The array of fallback error messages.\n     *\n     * @var array\n     */\n    public $fallbackMessages = [];\n\n    /**\n     * The array of custom attribute names.\n     *\n     * @var array\n     */\n    public $customAttributes = [];\n\n    /**\n     * The array of custom displayable values.\n     *\n     * @var array\n     */\n    public $customValues = [];\n\n    /**\n     * Indicates if the validator should stop on the first rule failure.\n     *\n     * @var bool\n     */\n    protected $stopOnFirstFailure = false;\n\n    /**\n     * Indicates that unvalidated array keys should be excluded, even if the parent array was validated.\n     *\n     * @var bool\n     */\n    public $excludeUnvalidatedArrayKeys = false;\n\n    /**\n     * All of the custom validator extensions.\n     *\n     * @var array\n     */\n    public $extensions = [];\n\n    /**\n     * All of the custom replacer extensions.\n     *\n     * @var array\n     */\n    public $replacers = [];\n\n    /**\n     * The validation rules that may be applied to files.\n     *\n     * @var string[]\n     */\n    protected $fileRules = [\n        'Between',\n        'Dimensions',\n        'Encoding',\n        'Extensions',\n        'File',\n        'Image',\n        'Max',\n        'Mimes',\n        'Mimetypes',\n        'Min',\n        'Size',\n    ];\n\n    /**\n     * The validation rules that imply the field is required.\n     *\n     * @var string[]\n     */\n    protected $implicitRules = [\n        'Accepted',\n        'AcceptedIf',\n        'Declined',\n        'DeclinedIf',\n        'Filled',\n        'Missing',\n        'MissingIf',\n        'MissingUnless',\n        'MissingWith',\n        'MissingWithAll',\n        'Present',\n        'PresentIf',\n        'PresentUnless',\n        'PresentWith',\n        'PresentWithAll',\n        'Required',\n        'RequiredIf',\n        'RequiredIfAccepted',\n        'RequiredIfDeclined',\n        'RequiredUnless',\n        'RequiredWith',\n        'RequiredWithAll',\n        'RequiredWithout',\n        'RequiredWithoutAll',\n    ];\n\n    /**\n     * The validation rules which depend on other fields as parameters.\n     *\n     * @var string[]\n     */\n    protected $dependentRules = [\n        'After',\n        'AfterOrEqual',\n        'Before',\n        'BeforeOrEqual',\n        'Confirmed',\n        'Different',\n        'ExcludeIf',\n        'ExcludeUnless',\n        'ExcludeWith',\n        'ExcludeWithout',\n        'Gt',\n        'Gte',\n        'Lt',\n        'Lte',\n        'AcceptedIf',\n        'DeclinedIf',\n        'RequiredIf',\n        'RequiredIfAccepted',\n        'RequiredIfDeclined',\n        'RequiredUnless',\n        'RequiredWith',\n        'RequiredWithAll',\n        'RequiredWithout',\n        'RequiredWithoutAll',\n        'PresentIf',\n        'PresentUnless',\n        'PresentWith',\n        'PresentWithAll',\n        'Prohibited',\n        'ProhibitedIf',\n        'ProhibitedIfAccepted',\n        'ProhibitedIfDeclined',\n        'ProhibitedUnless',\n        'Prohibits',\n        'MissingIf',\n        'MissingUnless',\n        'MissingWith',\n        'MissingWithAll',\n        'Same',\n        'Unique',\n    ];\n\n    /**\n     * The validation rules that can exclude an attribute.\n     *\n     * @var string[]\n     */\n    protected $excludeRules = ['Exclude', 'ExcludeIf', 'ExcludeUnless', 'ExcludeWith', 'ExcludeWithout'];\n\n    /**\n     * The size related validation rules.\n     *\n     * @var string[]\n     */\n    protected $sizeRules = ['Size', 'Between', 'Min', 'Max', 'Gt', 'Lt', 'Gte', 'Lte'];\n\n    /**\n     * The numeric related validation rules.\n     *\n     * @var string[]\n     */\n    protected $numericRules = ['Numeric', 'Integer', 'Decimal'];\n\n    /**\n     * The default numeric related validation rules.\n     *\n     * @var string[]\n     */\n    protected $defaultNumericRules = ['Numeric', 'Integer', 'Decimal'];\n\n    /**\n     * The current random hash for the validator.\n     *\n     * @var string|null\n     */\n    protected static $placeholderHash;\n\n    /**\n     * The exception to throw upon failure.\n     *\n     * @var class-string<\\Illuminate\\Validation\\ValidationException>\n     */\n    protected $exception = ValidationException::class;\n\n    /**\n     * The custom callback to determine if an exponent is within allowed range.\n     *\n     * @var callable|null\n     */\n    protected $ensureExponentWithinAllowedRangeUsing;\n\n    /**\n     * Create a new Validator instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Translation\\Translator  $translator\n     * @param  array  $data\n     * @param  array  $rules\n     * @param  array  $messages\n     * @param  array  $attributes\n     */\n    public function __construct(\n        Translator $translator,\n        array $data,\n        array $rules,\n        array $messages = [],\n        array $attributes = [],\n    ) {\n        if (! isset(static::$placeholderHash)) {\n            static::$placeholderHash = Str::random();\n        }\n\n        $this->initialRules = $rules;\n        $this->translator = $translator;\n        $this->customMessages = $messages;\n        $this->data = $this->parseData($data);\n        $this->customAttributes = $attributes;\n\n        $this->setRules($rules);\n    }\n\n    /**\n     * Parse the data array, converting dots and asterisks.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    public function parseData(array $data)\n    {\n        $newData = [];\n\n        foreach ($data as $key => $value) {\n            if (is_array($value)) {\n                $value = $this->parseData($value);\n            }\n\n            $key = str_replace(\n                ['.', '*'],\n                ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash],\n                $key\n            );\n\n            $newData[$key] = $value;\n        }\n\n        return $newData;\n    }\n\n    /**\n     * Replace the placeholders used in data keys.\n     *\n     * @param  array  $data\n     * @return array\n     */\n    protected function replacePlaceholders($data)\n    {\n        $originalData = [];\n\n        foreach ($data as $key => $value) {\n            $originalData[$this->replacePlaceholderInString($key)] = is_array($value)\n                ? $this->replacePlaceholders($value)\n                : $value;\n        }\n\n        return $originalData;\n    }\n\n    /**\n     * Replace the placeholders in the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function replacePlaceholderInString(string $value)\n    {\n        return str_replace(\n            ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash],\n            ['.', '*'],\n            $value\n        );\n    }\n\n    /**\n     * Replace each field parameter dot placeholder with dot.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function replaceDotPlaceholderInParameters(array $parameters)\n    {\n        return array_map(function ($field) {\n            return str_replace('__dot__'.static::$placeholderHash, '.', $field);\n        }, $parameters);\n    }\n\n    /**\n     * Add an after validation callback.\n     *\n     * @param  callable|array|string  $callback\n     * @return $this\n     */\n    public function after($callback)\n    {\n        if (is_array($callback) && ! is_callable($callback)) {\n            foreach ($callback as $rule) {\n                $this->after(method_exists($rule, 'after') ? $rule->after(...) : $rule);\n            }\n\n            return $this;\n        }\n\n        $this->after[] = fn () => $callback($this);\n\n        return $this;\n    }\n\n    /**\n     * Determine if the data passes the validation rules.\n     *\n     * @return bool\n     */\n    public function passes()\n    {\n        $this->messages = new MessageBag;\n\n        [$this->distinctValues, $this->failedRules] = [[], []];\n\n        // We'll spin through each rule, validating the attributes attached to that\n        // rule. Any error messages will be added to the containers with each of\n        // the other error messages, returning true if we don't have messages.\n        foreach ($this->rules as $attribute => $rules) {\n            if ($this->shouldBeExcluded($attribute)) {\n                $this->removeAttribute($attribute);\n\n                continue;\n            }\n\n            if ($this->stopOnFirstFailure && $this->messages->isNotEmpty()) {\n                break;\n            }\n\n            foreach ($rules as $rule) {\n                $this->validateAttribute($attribute, $rule);\n\n                if ($this->shouldBeExcluded($attribute)) {\n                    break;\n                }\n\n                if ($this->shouldStopValidating($attribute)) {\n                    break;\n                }\n            }\n        }\n\n        foreach ($this->rules as $attribute => $rules) {\n            if ($this->shouldBeExcluded($attribute)) {\n                $this->removeAttribute($attribute);\n            }\n        }\n\n        // Here we will spin through all of the \"after\" hooks on this validator and\n        // fire them off. This gives the callbacks a chance to perform all kinds\n        // of other validation that needs to get wrapped up in this operation.\n        foreach ($this->after as $after) {\n            $after();\n        }\n\n        return $this->messages->isEmpty();\n    }\n\n    /**\n     * Determine if the data fails the validation rules.\n     *\n     * @return bool\n     */\n    public function fails()\n    {\n        return ! $this->passes();\n    }\n\n    /**\n     * Execute the callback if the data passes the validation rules.\n     *\n     * @template TWhenReturnType\n     *\n     * @param  (callable($this): TWhenReturnType)  $callback\n     * @param  (callable($this): TWhenReturnType)|null  $default\n     * @return $this|TWhenReturnType\n     */\n    public function whenPasses(callable $callback, ?callable $default = null)\n    {\n        if ($this->passes()) {\n            return $callback($this) ?? $this;\n        } elseif ($default) {\n            return $default($this) ?? $this;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Execute the callback if the data fails the validation rules.\n     *\n     * @template TWhenReturnType\n     *\n     * @param  (callable($this): TWhenReturnType)  $callback\n     * @param  (callable($this): TWhenReturnType)|null  $default\n     * @return $this|TWhenReturnType\n     */\n    public function whenFails(callable $callback, ?callable $default = null)\n    {\n        if ($this->fails()) {\n            return $callback($this) ?? $this;\n        } elseif ($default) {\n            return $default($this) ?? $this;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Determine if the attribute should be excluded.\n     *\n     * @param  string  $attribute\n     * @return bool\n     */\n    protected function shouldBeExcluded($attribute)\n    {\n        foreach ($this->excludeAttributes as $excludeAttribute) {\n            if ($attribute === $excludeAttribute ||\n                Str::startsWith($attribute, $excludeAttribute.'.')) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Remove the given attribute.\n     *\n     * @param  string  $attribute\n     * @return void\n     */\n    protected function removeAttribute($attribute)\n    {\n        Arr::forget($this->data, $attribute);\n        Arr::forget($this->rules, $attribute);\n    }\n\n    /**\n     * Run the validator's rules against its data.\n     *\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validate()\n    {\n        throw_if($this->fails(), $this->exception, $this);\n\n        return $this->validated();\n    }\n\n    /**\n     * Run the validator's rules against its data.\n     *\n     * @param  string  $errorBag\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validateWithBag(string $errorBag)\n    {\n        try {\n            return $this->validate();\n        } catch (ValidationException $e) {\n            $e->errorBag = $errorBag;\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Get a validated input container for the validated input.\n     *\n     * @param  array|null  $keys\n     * @return \\Illuminate\\Support\\ValidatedInput|array\n     */\n    public function safe(?array $keys = null)\n    {\n        return is_array($keys)\n            ? (new ValidatedInput($this->validated()))->only($keys)\n            : new ValidatedInput($this->validated());\n    }\n\n    /**\n     * Get the attributes and values that were validated.\n     *\n     * @return array\n     *\n     * @throws \\Illuminate\\Validation\\ValidationException\n     */\n    public function validated()\n    {\n        if (! $this->messages) {\n            $this->passes();\n        }\n\n        throw_if($this->messages->isNotEmpty(), $this->exception, $this);\n\n        $results = [];\n\n        $missingValue = new stdClass;\n\n        foreach ($this->getRules() as $key => $rules) {\n            $value = data_get($this->getData(), $key, $missingValue);\n\n            if ($this->excludeUnvalidatedArrayKeys &&\n                (in_array('array', $rules) || in_array('list', $rules)) &&\n                $value !== null &&\n                ! empty(preg_grep('/^'.preg_quote($key, '/').'\\.+/', array_keys($this->getRules())))) {\n                continue;\n            }\n\n            if ($value !== $missingValue) {\n                Arr::set($results, $key, $value);\n            }\n        }\n\n        return $this->replacePlaceholders($results);\n    }\n\n    /**\n     * Validate a given attribute against a rule.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @return void\n     */\n    protected function validateAttribute($attribute, $rule)\n    {\n        $this->currentRule = $rule;\n\n        [$rule, $parameters] = ValidationRuleParser::parse($rule);\n\n        if ($rule === '') {\n            return;\n        }\n\n        // First we will get the correct keys for the given attribute in case the field is nested in\n        // an array. Then we determine if the given rule accepts other field names as parameters.\n        // If so, we will replace any asterisks found in the parameters with the correct keys.\n        if ($this->dependsOnOtherFields($rule)) {\n            $parameters = $this->replaceDotInParameters($parameters);\n\n            if ($keys = $this->getExplicitKeys($attribute)) {\n                $parameters = $this->replaceAsterisksInParameters($parameters, $keys);\n            }\n        }\n\n        $value = $this->getValue($attribute);\n\n        // If the attribute is a file, we will verify that the file upload was actually successful\n        // and if it wasn't we will add a failure for the attribute. Files may not successfully\n        // upload if they are too large based on PHP's settings so we will bail in this case.\n        if ($value instanceof UploadedFile && ! $value->isValid() &&\n            $this->hasRule($attribute, array_merge($this->fileRules, $this->implicitRules))\n        ) {\n            return $this->addFailure($attribute, 'uploaded', []);\n        }\n\n        // If we have made it this far we will make sure the attribute is validatable and if it is\n        // we will call the validation method with the attribute. If a method returns false the\n        // attribute is invalid and we will add a failure message for this failing attribute.\n        $validatable = $this->isValidatable($rule, $attribute, $value);\n\n        if ($rule instanceof RuleContract) {\n            return $validatable\n                ? $this->validateUsingCustomRule($attribute, $value, $rule)\n                : null;\n        }\n\n        $method = \"validate{$rule}\";\n\n        $this->numericRules = $this->defaultNumericRules;\n\n        if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) {\n            $this->addFailure($attribute, $rule, $parameters);\n        }\n    }\n\n    /**\n     * Determine if the given rule depends on other fields.\n     *\n     * @param  string  $rule\n     * @return bool\n     */\n    protected function dependsOnOtherFields($rule)\n    {\n        return in_array($rule, $this->dependentRules);\n    }\n\n    /**\n     * Get the explicit keys from an attribute flattened with dot notation.\n     *\n     * E.g. 'foo.1.bar.spark.baz' -> [1, 'spark'] for 'foo.*.bar.*.baz'\n     *\n     * @param  string  $attribute\n     * @return array\n     */\n    protected function getExplicitKeys($attribute)\n    {\n        $pattern = str_replace('\\*', '([^\\.]+)', preg_quote($this->getPrimaryAttribute($attribute), '/'));\n\n        if (preg_match('/^'.$pattern.'/', $attribute, $keys)) {\n            array_shift($keys);\n\n            return $keys;\n        }\n\n        return [];\n    }\n\n    /**\n     * Get the primary attribute name.\n     *\n     * For example, if \"name.0\" is given, \"name.*\" will be returned.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    protected function getPrimaryAttribute($attribute)\n    {\n        foreach ($this->implicitAttributes as $unparsed => $parsed) {\n            if (in_array($attribute, $parsed, true)) {\n                return $unparsed;\n            }\n        }\n\n        return $attribute;\n    }\n\n    /**\n     * Replace each field parameter which has an escaped dot with the dot placeholder.\n     *\n     * @param  array  $parameters\n     * @return array\n     */\n    protected function replaceDotInParameters(array $parameters)\n    {\n        return array_map(function ($field) {\n            return static::encodeAttributeWithPlaceholder((string) ($field ?? ''));\n        }, $parameters);\n    }\n\n    /**\n     * Replace each field parameter which has asterisks with the given keys.\n     *\n     * @param  array  $parameters\n     * @param  array  $keys\n     * @return array\n     */\n    protected function replaceAsterisksInParameters(array $parameters, array $keys)\n    {\n        return array_map(function ($field) use ($keys) {\n            return vsprintf(str_replace('*', '%s', $field), $keys);\n        }, $parameters);\n    }\n\n    /**\n     * Determine if the attribute is validatable.\n     *\n     * @param  object|string  $rule\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function isValidatable($rule, $attribute, $value)\n    {\n        if (in_array($rule, $this->excludeRules)) {\n            return true;\n        }\n\n        return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&\n               $this->passesOptionalCheck($attribute) &&\n               $this->isNotNullIfMarkedAsNullable($rule, $attribute) &&\n               $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute);\n    }\n\n    /**\n     * Determine if the field is present, or the rule implies required.\n     *\n     * @param  object|string  $rule\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function presentOrRuleIsImplicit($rule, $attribute, $value)\n    {\n        if (is_string($value) && trim($value) === '') {\n            return $this->isImplicit($rule);\n        }\n\n        return $this->validatePresent($attribute, $value) ||\n               $this->isImplicit($rule);\n    }\n\n    /**\n     * Determine if a given rule implies the attribute is required.\n     *\n     * @param  object|string  $rule\n     * @return bool\n     */\n    protected function isImplicit($rule)\n    {\n        return $rule instanceof ImplicitRule ||\n               in_array($rule, $this->implicitRules);\n    }\n\n    /**\n     * Determine if the attribute passes any optional check.\n     *\n     * @param  string  $attribute\n     * @return bool\n     */\n    protected function passesOptionalCheck($attribute)\n    {\n        if (! $this->hasRule($attribute, ['Sometimes'])) {\n            return true;\n        }\n\n        $data = ValidationData::initializeAndGatherData($attribute, $this->data);\n\n        return array_key_exists($attribute, $data)\n            || array_key_exists($attribute, $this->data);\n    }\n\n    /**\n     * Determine if the attribute fails the nullable check.\n     *\n     * @param  string  $rule\n     * @param  string  $attribute\n     * @return bool\n     */\n    protected function isNotNullIfMarkedAsNullable($rule, $attribute)\n    {\n        if ($this->isImplicit($rule) || ! $this->hasRule($attribute, ['Nullable'])) {\n            return true;\n        }\n\n        return ! is_null(Arr::get($this->data, $attribute, 0));\n    }\n\n    /**\n     * Determine if it's a necessary presence validation.\n     *\n     * This is to avoid possible database type comparison errors.\n     *\n     * @param  string  $rule\n     * @param  string  $attribute\n     * @return bool\n     */\n    protected function hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute)\n    {\n        return in_array($rule, ['Unique', 'Exists']) ? ! $this->messages->has($attribute) : true;\n    }\n\n    /**\n     * Validate an attribute using a custom rule object.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @param  \\Illuminate\\Contracts\\Validation\\Rule  $rule\n     * @return void\n     */\n    protected function validateUsingCustomRule($attribute, $value, $rule)\n    {\n        $originalAttribute = $this->replacePlaceholderInString($attribute);\n\n        $attribute = match (true) {\n            $rule instanceof Rules\\Email => $attribute,\n            $rule instanceof Rules\\File => $attribute,\n            $rule instanceof Rules\\Password => $attribute,\n            default => $originalAttribute,\n        };\n\n        $value = is_array($value) ? $this->replacePlaceholders($value) : $value;\n\n        if ($rule instanceof ValidatorAwareRule) {\n            if ($attribute !== $originalAttribute) {\n                $this->addCustomAttributes([\n                    $attribute => $this->customAttributes[$originalAttribute] ?? $originalAttribute,\n                ]);\n            }\n\n            $rule->setValidator($this);\n        }\n\n        if ($rule instanceof DataAwareRule) {\n            $rule->setData($this->data);\n        }\n\n        if (! $rule->passes($attribute, $value)) {\n            $ruleClass = $rule instanceof InvokableValidationRule ?\n                get_class($rule->invokable()) :\n                get_class($rule);\n\n            $this->failedRules[$originalAttribute][$ruleClass] = [];\n\n            $messages = $this->getFromLocalArray($originalAttribute, $ruleClass) ?? $rule->message();\n\n            $messages = $messages ? (array) $messages : [$ruleClass];\n\n            foreach ($messages as $key => $message) {\n                $key = is_string($key) ? $key : $originalAttribute;\n\n                $this->messages->add($key, $this->makeReplacements(\n                    $message, $key, $ruleClass, []\n                ));\n            }\n        }\n    }\n\n    /**\n     * Check if we should stop further validations on a given attribute.\n     *\n     * @param  string  $attribute\n     * @return bool\n     */\n    protected function shouldStopValidating($attribute)\n    {\n        $cleanedAttribute = $this->replacePlaceholderInString($attribute);\n\n        if ($this->hasRule($attribute, ['Bail'])) {\n            return $this->messages->has($cleanedAttribute);\n        }\n\n        if (isset($this->failedRules[$cleanedAttribute]) &&\n            array_key_exists('uploaded', $this->failedRules[$cleanedAttribute])) {\n            return true;\n        }\n\n        // In case the attribute has any rule that indicates that the field is required\n        // and that rule already failed then we should stop validation at this point\n        // as now there is no point in calling other rules with this field empty.\n        return $this->hasRule($attribute, $this->implicitRules) &&\n               isset($this->failedRules[$cleanedAttribute]) &&\n               array_intersect(array_keys($this->failedRules[$cleanedAttribute]), $this->implicitRules);\n    }\n\n    /**\n     * Add a failed rule and error message to the collection.\n     *\n     * @param  string  $attribute\n     * @param  string  $rule\n     * @param  array  $parameters\n     * @return void\n     */\n    public function addFailure($attribute, $rule, $parameters = [])\n    {\n        if (! $this->messages) {\n            $this->passes();\n        }\n\n        $attributeWithPlaceholders = $attribute;\n\n        $attribute = $this->replacePlaceholderInString($attribute);\n\n        if (in_array($rule, $this->excludeRules)) {\n            return $this->excludeAttribute($attribute);\n        }\n\n        if ($this->dependsOnOtherFields($rule)) {\n            $parameters = $this->replaceDotPlaceholderInParameters($parameters);\n        }\n\n        $this->messages->add($attribute, $this->makeReplacements(\n            $this->getMessage($attributeWithPlaceholders, $rule), $attribute, $rule, $parameters\n        ));\n\n        $this->failedRules[$attribute][$rule] = $parameters;\n    }\n\n    /**\n     * Add the given attribute to the list of excluded attributes.\n     *\n     * @param  string  $attribute\n     * @return void\n     */\n    protected function excludeAttribute(string $attribute)\n    {\n        $this->excludeAttributes[] = $attribute;\n\n        $this->excludeAttributes = array_unique($this->excludeAttributes);\n    }\n\n    /**\n     * Returns the data which was valid.\n     *\n     * @return array\n     */\n    public function valid()\n    {\n        if (! $this->messages) {\n            $this->passes();\n        }\n\n        return array_diff_key(\n            $this->data, $this->attributesThatHaveMessages()\n        );\n    }\n\n    /**\n     * Returns the data which was invalid.\n     *\n     * @return array\n     */\n    public function invalid()\n    {\n        if (! $this->messages) {\n            $this->passes();\n        }\n\n        $invalid = array_intersect_key(\n            $this->data, $this->attributesThatHaveMessages()\n        );\n\n        $result = [];\n\n        $failed = Arr::only(Arr::dot($invalid), array_keys($this->failed()));\n\n        foreach ($failed as $key => $failure) {\n            Arr::set($result, $key, $failure);\n        }\n\n        return $result;\n    }\n\n    /**\n     * Generate an array of all attributes that have messages.\n     *\n     * @return array\n     */\n    protected function attributesThatHaveMessages()\n    {\n        return (new Collection($this->messages()->toArray()))\n            ->map(fn ($message, $key) => explode('.', $key)[0])\n            ->unique()\n            ->flip()\n            ->all();\n    }\n\n    /**\n     * Get the failed validation rules.\n     *\n     * @return array\n     */\n    public function failed()\n    {\n        return $this->failedRules;\n    }\n\n    /**\n     * Get the message container for the validator.\n     *\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function messages()\n    {\n        if (! $this->messages) {\n            $this->passes();\n        }\n\n        return $this->messages;\n    }\n\n    /**\n     * An alternative more semantic shortcut to the message container.\n     *\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function errors()\n    {\n        return $this->messages();\n    }\n\n    /**\n     * Get the messages for the instance.\n     *\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    public function getMessageBag()\n    {\n        return $this->messages();\n    }\n\n    /**\n     * Determine if the given attribute has a rule in the given set.\n     *\n     * @param  string  $attribute\n     * @param  string|array  $rules\n     * @return bool\n     */\n    public function hasRule($attribute, $rules)\n    {\n        return ! is_null($this->getRule($attribute, $rules));\n    }\n\n    /**\n     * Get a rule and its parameters for a given attribute.\n     *\n     * @param  string  $attribute\n     * @param  string|array  $rules\n     * @return array|null\n     */\n    protected function getRule($attribute, $rules)\n    {\n        if (! array_key_exists($attribute, $this->rules)) {\n            return;\n        }\n\n        $rules = (array) $rules;\n\n        foreach ($this->rules[$attribute] as $rule) {\n            [$rule, $parameters] = ValidationRuleParser::parse($rule);\n\n            if (in_array($rule, $rules)) {\n                return [$rule, $parameters];\n            }\n        }\n    }\n\n    /**\n     * Get the data under validation.\n     *\n     * @return array\n     */\n    public function attributes()\n    {\n        return $this->getData();\n    }\n\n    /**\n     * Get the data under validation.\n     *\n     * @return array\n     */\n    public function getData()\n    {\n        return $this->data;\n    }\n\n    /**\n     * Set the data under validation.\n     *\n     * @param  array  $data\n     * @return $this\n     */\n    public function setData(array $data)\n    {\n        $this->data = $this->parseData($data);\n\n        $this->setRules($this->initialRules);\n\n        return $this;\n    }\n\n    /**\n     * Get the value of a given attribute.\n     *\n     * @param  string  $attribute\n     * @return mixed\n     */\n    public function getValue($attribute)\n    {\n        return Arr::get($this->data, $attribute);\n    }\n\n    /**\n     * Set the value of a given attribute.\n     *\n     * @param  string  $attribute\n     * @param  mixed  $value\n     * @return void\n     */\n    public function setValue($attribute, $value)\n    {\n        Arr::set($this->data, $attribute, $value);\n    }\n\n    /**\n     * Get the validation rules.\n     *\n     * @return array\n     */\n    public function getRules()\n    {\n        return $this->rules;\n    }\n\n    /**\n     * Get the validation rules with key placeholders removed.\n     *\n     * @return array\n     */\n    public function getRulesWithoutPlaceholders()\n    {\n        return (new Collection($this->rules))\n            ->mapWithKeys(fn ($value, $key) => [\n                static::decodeAttributeWithPlaceholder($key) => $value,\n            ])\n            ->all();\n    }\n\n    /**\n     * Set the validation rules.\n     *\n     * @param  array  $rules\n     * @return $this\n     */\n    public function setRules(array $rules)\n    {\n        $rules = (new Collection($rules))\n            ->mapWithKeys(function ($value, $key) {\n                return [static::encodeAttributeWithPlaceholder($key) => $value];\n            })\n            ->toArray();\n\n        $this->initialRules = $rules;\n\n        $this->rules = [];\n\n        $this->addRules($rules);\n\n        return $this;\n    }\n\n    /**\n     * Append new validation rules to the validator.\n     *\n     * @param  array  $rules\n     * @return $this\n     */\n    public function appendRules(array $rules)\n    {\n        $rules = (new Collection($rules))\n            ->map(function ($value) {\n                return is_string($value) ? explode('|', $value) : $value;\n            })\n            ->all();\n\n        return $this->setRules(array_merge_recursive($this->getRulesWithoutPlaceholders(), $rules));\n    }\n\n    /**\n     * Parse the given rules and merge them into current rules.\n     *\n     * @internal\n     *\n     * @param  array  $rules\n     * @return void\n     */\n    public function addRules($rules)\n    {\n        // The primary purpose of this parser is to expand any \"*\" rules to the all\n        // of the explicit rules needed for the given data. For example the rule\n        // names.* would get expanded to names.0, names.1, etc. for this data.\n        $response = (new ValidationRuleParser($this->data))\n            ->explode(ValidationRuleParser::filterConditionalRules($rules, $this->data));\n\n        foreach ($response->rules as $key => $rule) {\n            $this->rules[$key] = array_merge($this->rules[$key] ?? [], $rule);\n        }\n\n        $this->implicitAttributes = array_merge(\n            $this->implicitAttributes, $response->implicitAttributes\n        );\n    }\n\n    /**\n     * Add conditions to a given field based on a Closure.\n     *\n     * @param  string|array  $attribute\n     * @param  string|array  $rules\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function sometimes($attribute, $rules, callable $callback)\n    {\n        $payload = new Fluent($this->data);\n\n        foreach ((array) $attribute as $key) {\n            $response = (new ValidationRuleParser($this->data))->explode([$key => $rules]);\n\n            $this->implicitAttributes = array_merge($response->implicitAttributes, $this->implicitAttributes);\n\n            foreach ($response->rules as $ruleKey => $ruleValue) {\n                if ($callback($payload, $this->dataForSometimesIteration($ruleKey, ! str_ends_with($key, '.*')))) {\n                    $this->addRules([static::encodeAttributeWithPlaceholder($ruleKey) => $ruleValue]);\n                }\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get the data that should be injected into the iteration of a wildcard \"sometimes\" callback.\n     *\n     * @param  string  $attribute\n     * @param  bool  $removeLastSegmentOfAttribute\n     * @return \\Illuminate\\Support\\Fluent|mixed\n     */\n    private function dataForSometimesIteration(string $attribute, bool $removeLastSegmentOfAttribute)\n    {\n        $lastSegmentOfAttribute = strrchr($attribute, '.');\n\n        $attribute = $lastSegmentOfAttribute && $removeLastSegmentOfAttribute\n            ? Str::replaceLast($lastSegmentOfAttribute, '', $attribute)\n            : $attribute;\n\n        return is_array($data = data_get($this->data, $attribute))\n            ? new Fluent($data)\n            : $data;\n    }\n\n    /**\n     * Instruct the validator to stop validating after the first rule failure.\n     *\n     * @param  bool  $stopOnFirstFailure\n     * @return $this\n     */\n    public function stopOnFirstFailure($stopOnFirstFailure = true)\n    {\n        $this->stopOnFirstFailure = $stopOnFirstFailure;\n\n        return $this;\n    }\n\n    /**\n     * Register an array of custom validator extensions.\n     *\n     * @param  array  $extensions\n     * @return void\n     */\n    public function addExtensions(array $extensions)\n    {\n        if ($extensions) {\n            $keys = array_map(Str::snake(...), array_keys($extensions));\n\n            $extensions = array_combine($keys, array_values($extensions));\n        }\n\n        $this->extensions = array_merge($this->extensions, $extensions);\n    }\n\n    /**\n     * Register an array of custom implicit validator extensions.\n     *\n     * @param  array  $extensions\n     * @return void\n     */\n    public function addImplicitExtensions(array $extensions)\n    {\n        $this->addExtensions($extensions);\n\n        foreach ($extensions as $rule => $extension) {\n            $this->implicitRules[] = Str::studly($rule);\n        }\n    }\n\n    /**\n     * Register an array of custom dependent validator extensions.\n     *\n     * @param  array  $extensions\n     * @return void\n     */\n    public function addDependentExtensions(array $extensions)\n    {\n        $this->addExtensions($extensions);\n\n        foreach ($extensions as $rule => $extension) {\n            $this->dependentRules[] = Str::studly($rule);\n        }\n    }\n\n    /**\n     * Register a custom validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @return void\n     */\n    public function addExtension($rule, $extension)\n    {\n        $this->extensions[Str::snake($rule)] = $extension;\n    }\n\n    /**\n     * Register a custom implicit validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @return void\n     */\n    public function addImplicitExtension($rule, $extension)\n    {\n        $this->addExtension($rule, $extension);\n\n        $this->implicitRules[] = Str::studly($rule);\n    }\n\n    /**\n     * Register a custom dependent validator extension.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $extension\n     * @return void\n     */\n    public function addDependentExtension($rule, $extension)\n    {\n        $this->addExtension($rule, $extension);\n\n        $this->dependentRules[] = Str::studly($rule);\n    }\n\n    /**\n     * Register an array of custom validator message replacers.\n     *\n     * @param  array  $replacers\n     * @return void\n     */\n    public function addReplacers(array $replacers)\n    {\n        if ($replacers) {\n            $keys = array_map(Str::snake(...), array_keys($replacers));\n\n            $replacers = array_combine($keys, array_values($replacers));\n        }\n\n        $this->replacers = array_merge($this->replacers, $replacers);\n    }\n\n    /**\n     * Register a custom validator message replacer.\n     *\n     * @param  string  $rule\n     * @param  \\Closure|string  $replacer\n     * @return void\n     */\n    public function addReplacer($rule, $replacer)\n    {\n        $this->replacers[Str::snake($rule)] = $replacer;\n    }\n\n    /**\n     * Set the custom messages for the validator.\n     *\n     * @param  array  $messages\n     * @return $this\n     */\n    public function setCustomMessages(array $messages)\n    {\n        $this->customMessages = array_merge($this->customMessages, $messages);\n\n        return $this;\n    }\n\n    /**\n     * Set the custom attributes on the validator.\n     *\n     * @param  array  $attributes\n     * @return $this\n     */\n    public function setAttributeNames(array $attributes)\n    {\n        $this->customAttributes = $attributes;\n\n        return $this;\n    }\n\n    /**\n     * Add custom attributes to the validator.\n     *\n     * @param  array  $attributes\n     * @return $this\n     */\n    public function addCustomAttributes(array $attributes)\n    {\n        $this->customAttributes = array_merge($this->customAttributes, $attributes);\n\n        return $this;\n    }\n\n    /**\n     * Set the callback that used to format an implicit attribute.\n     *\n     * @param  callable|null  $formatter\n     * @return $this\n     */\n    public function setImplicitAttributesFormatter(?callable $formatter = null)\n    {\n        $this->implicitAttributesFormatter = $formatter;\n\n        return $this;\n    }\n\n    /**\n     * Set the custom values on the validator.\n     *\n     * @param  array  $values\n     * @return $this\n     */\n    public function setValueNames(array $values)\n    {\n        $this->customValues = $values;\n\n        return $this;\n    }\n\n    /**\n     * Add the custom values for the validator.\n     *\n     * @param  array  $customValues\n     * @return $this\n     */\n    public function addCustomValues(array $customValues)\n    {\n        $this->customValues = array_merge($this->customValues, $customValues);\n\n        return $this;\n    }\n\n    /**\n     * Set the fallback messages for the validator.\n     *\n     * @param  array  $messages\n     * @return void\n     */\n    public function setFallbackMessages(array $messages)\n    {\n        $this->fallbackMessages = $messages;\n    }\n\n    /**\n     * Get the Presence Verifier implementation.\n     *\n     * @param  string|null  $connection\n     * @return \\Illuminate\\Validation\\PresenceVerifierInterface\n     *\n     * @throws \\RuntimeException\n     */\n    public function getPresenceVerifier($connection = null)\n    {\n        if (! isset($this->presenceVerifier)) {\n            throw new RuntimeException('Presence verifier has not been set.');\n        }\n\n        if ($this->presenceVerifier instanceof DatabasePresenceVerifierInterface) {\n            $this->presenceVerifier->setConnection($connection);\n        }\n\n        return $this->presenceVerifier;\n    }\n\n    /**\n     * Set the Presence Verifier implementation.\n     *\n     * @param  \\Illuminate\\Validation\\PresenceVerifierInterface  $presenceVerifier\n     * @return void\n     */\n    public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier)\n    {\n        $this->presenceVerifier = $presenceVerifier;\n    }\n\n    /**\n     * Get the exception to throw upon failed validation.\n     *\n     * @return class-string<\\Illuminate\\Validation\\ValidationException>\n     */\n    public function getException()\n    {\n        return $this->exception;\n    }\n\n    /**\n     * Set the exception to throw upon failed validation.\n     *\n     * @param  class-string<\\Illuminate\\Validation\\ValidationException>  $exception\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setException($exception)\n    {\n        if (! is_a($exception, ValidationException::class, true)) {\n            throw new InvalidArgumentException(\n                sprintf('Exception [%s] is invalid. It must extend [%s].', $exception, ValidationException::class)\n            );\n        }\n\n        $this->exception = $exception;\n\n        return $this;\n    }\n\n    /**\n     * Ensure exponents are within range using the given callback.\n     *\n     * @param  callable(int $scale, string $attribute, mixed $value)  $callback\n     * @return $this\n     */\n    public function ensureExponentWithinAllowedRangeUsing($callback)\n    {\n        $this->ensureExponentWithinAllowedRangeUsing = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Get the Translator implementation.\n     *\n     * @return \\Illuminate\\Contracts\\Translation\\Translator\n     */\n    public function getTranslator()\n    {\n        return $this->translator;\n    }\n\n    /**\n     * Set the Translator implementation.\n     *\n     * @param  \\Illuminate\\Contracts\\Translation\\Translator  $translator\n     * @return void\n     */\n    public function setTranslator(Translator $translator)\n    {\n        $this->translator = $translator;\n    }\n\n    /**\n     * Set the IoC container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Call a custom validator extension.\n     *\n     * @param  string  $rule\n     * @param  array  $parameters\n     * @return bool|null\n     */\n    protected function callExtension($rule, $parameters)\n    {\n        $callback = $this->extensions[$rule];\n\n        if (is_callable($callback)) {\n            return $callback(...array_values($parameters));\n        } elseif (is_string($callback)) {\n            return $this->callClassBasedExtension($callback, $parameters);\n        }\n    }\n\n    /**\n     * Call a class based validator extension.\n     *\n     * @param  string  $callback\n     * @param  array  $parameters\n     * @return bool\n     */\n    protected function callClassBasedExtension($callback, $parameters)\n    {\n        [$class, $method] = Str::parseCallback($callback, 'validate');\n\n        return $this->container->make($class)->{$method}(...array_values($parameters));\n    }\n\n    /**\n     * Encode the attribute with the placeholder hash.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    protected static function encodeAttributeWithPlaceholder(string $attribute)\n    {\n        return str_replace('\\.', '__dot__'.static::$placeholderHash, $attribute);\n    }\n\n    /**\n     * Decode an attribute with a placeholder hash.\n     *\n     * @param  string  $attribute\n     * @return string\n     */\n    protected static function decodeAttributeWithPlaceholder(string $attribute)\n    {\n        return str_replace('__dot__'.static::$placeholderHash, '\\\\.', $attribute);\n    }\n\n    /**\n     * Flush the validator's global state.\n     *\n     * @return void\n     */\n    public static function flushState()\n    {\n        static::$placeholderHash = null;\n    }\n\n    /**\n     * Handle dynamic calls to class methods.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        $rule = Str::snake(substr($method, 8));\n\n        if (isset($this->extensions[$rule])) {\n            return $this->callExtension($rule, $parameters);\n        }\n\n        throw new BadMethodCallException(sprintf(\n            'Method %s::%s does not exist.', static::class, $method\n        ));\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/Validation/composer.json",
    "content": "{\n    \"name\": \"illuminate/validation\",\n    \"description\": \"The Illuminate Validation package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-filter\": \"*\",\n        \"ext-mbstring\": \"*\",\n        \"brick/math\": \"^0.14.2 || ^0.15 || ^0.16 || ^0.17\",\n        \"egulias/email-validator\": \"^4.0\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\",\n        \"illuminate/translation\": \"^13.0\",\n        \"symfony/http-foundation\": \"^7.4.0 || ^8.0.0\",\n        \"symfony/mime\": \"^7.4.0 || ^8.0.0\"\n    },\n    \"suggest\": {\n        \"illuminate/database\": \"Required to use the database presence verifier (^13.0).\",\n        \"ramsey/uuid\": \"Required to use Validator::validateUuid() (^4.7).\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\Validation\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/.gitattributes",
    "content": "/.github export-ignore\n.gitattributes export-ignore\n"
  },
  {
    "path": "src/Illuminate/View/.github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-24.04\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: \"Thank you for your pull request. However, you have submitted this PR on the Illuminate organization which is a read-only sub split of `laravel/framework`. Please submit your PR on the https://github.com/laravel/framework repository.<br><br>Thanks!\"\n"
  },
  {
    "path": "src/Illuminate/View/AnonymousComponent.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nclass AnonymousComponent extends Component\n{\n    /**\n     * The component view.\n     *\n     * @var string\n     */\n    protected $view;\n\n    /**\n     * The component data.\n     *\n     * @var array\n     */\n    protected $data = [];\n\n    /**\n     * Create a new anonymous component instance.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     */\n    public function __construct($view, $data)\n    {\n        $this->view = $view;\n        $this->data = $data;\n    }\n\n    /**\n     * Get the view / view contents that represent the component.\n     *\n     * @return string\n     */\n    public function render()\n    {\n        return $this->view;\n    }\n\n    /**\n     * Get the data that should be supplied to the view.\n     *\n     * @return array\n     */\n    public function data()\n    {\n        $this->attributes = $this->attributes ?: $this->newAttributeBag();\n\n        return array_merge(\n            ($this->data['attributes'] ?? null)?->getAttributes() ?: [],\n            $this->attributes->getAttributes(),\n            $this->data,\n            ['attributes' => $this->attributes]\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/AppendableAttributeValue.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Stringable;\n\nclass AppendableAttributeValue implements Stringable\n{\n    /**\n     * The attribute value.\n     *\n     * @var mixed\n     */\n    public $value;\n\n    /**\n     * Create a new appendable attribute value.\n     *\n     * @param  mixed  $value\n     */\n    public function __construct($value)\n    {\n        $this->value = $value;\n    }\n\n    /**\n     * Get the string value.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/BladeCompiler.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Contracts\\View\\View;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse Illuminate\\View\\Component;\nuse InvalidArgumentException;\nuse ParseError;\n\nclass BladeCompiler extends Compiler implements CompilerInterface\n{\n    use Concerns\\CompilesAuthorizations,\n        Concerns\\CompilesClasses,\n        Concerns\\CompilesComments,\n        Concerns\\CompilesComponents,\n        Concerns\\CompilesConditionals,\n        Concerns\\CompilesContexts,\n        Concerns\\CompilesEchos,\n        Concerns\\CompilesErrors,\n        Concerns\\CompilesFragments,\n        Concerns\\CompilesHelpers,\n        Concerns\\CompilesIncludes,\n        Concerns\\CompilesInjections,\n        Concerns\\CompilesJson,\n        Concerns\\CompilesJs,\n        Concerns\\CompilesLayouts,\n        Concerns\\CompilesLoops,\n        Concerns\\CompilesRawPhp,\n        Concerns\\CompilesSessions,\n        Concerns\\CompilesStacks,\n        Concerns\\CompilesStyles,\n        Concerns\\CompilesTranslations,\n        Concerns\\CompilesUseStatements,\n        ReflectsClosures;\n\n    /**\n     * All of the registered extensions.\n     *\n     * @var array\n     */\n    protected $extensions = [];\n\n    /**\n     * All custom \"directive\" handlers.\n     *\n     * @var array\n     */\n    protected $customDirectives = [];\n\n    /**\n     * All custom \"condition\" handlers.\n     *\n     * @var array\n     */\n    protected $conditions = [];\n\n    /**\n     * The registered string preparation callbacks.\n     *\n     * @var array\n     */\n    protected $prepareStringsForCompilationUsing = [];\n\n    /**\n     * All of the registered precompilers.\n     *\n     * @var array\n     */\n    protected $precompilers = [];\n\n    /**\n     * The file currently being compiled.\n     *\n     * @var string\n     */\n    protected $path;\n\n    /**\n     * All of the available compiler functions.\n     *\n     * @var string[]\n     */\n    protected $compilers = [\n        // 'Comments',\n        'Extensions',\n        'Statements',\n        'Echos',\n    ];\n\n    /**\n     * Array of opening and closing tags for raw echos.\n     *\n     * @var string[]\n     */\n    protected $rawTags = ['{!!', '!!}'];\n\n    /**\n     * Array of opening and closing tags for regular echos.\n     *\n     * @var string[]\n     */\n    protected $contentTags = ['{{', '}}'];\n\n    /**\n     * Array of opening and closing tags for escaped echos.\n     *\n     * @var string[]\n     */\n    protected $escapedTags = ['{{{', '}}}'];\n\n    /**\n     * The \"regular\" / legacy echo string format.\n     *\n     * @var string\n     */\n    protected $echoFormat = 'e(%s)';\n\n    /**\n     * Array of footer lines to be added to the template.\n     *\n     * @var array\n     */\n    protected $footer = [];\n\n    /**\n     * Array to temporarily store the raw blocks found in the template.\n     *\n     * @var array\n     */\n    protected $rawBlocks = [];\n\n    /**\n     * The array of anonymous component paths to search for components in.\n     *\n     * @var array\n     */\n    protected $anonymousComponentPaths = [];\n\n    /**\n     * The array of anonymous component namespaces to autoload from.\n     *\n     * @var array\n     */\n    protected $anonymousComponentNamespaces = [];\n\n    /**\n     * The array of class component aliases and their class names.\n     *\n     * @var array\n     */\n    protected $classComponentAliases = [];\n\n    /**\n     * The array of class component namespaces to autoload from.\n     *\n     * @var array\n     */\n    protected $classComponentNamespaces = [];\n\n    /**\n     * Indicates if component tags should be compiled.\n     *\n     * @var bool\n     */\n    protected $compilesComponentTags = true;\n\n    /**\n     * Compile the view at the given path.\n     *\n     * @param  string|null  $path\n     * @return void\n     */\n    public function compile($path = null)\n    {\n        if ($path) {\n            $this->setPath($path);\n        }\n\n        if (! is_null($this->cachePath)) {\n            $contents = $this->compileString($this->files->get($this->getPath()));\n\n            if (! empty($this->getPath())) {\n                $contents = $this->appendFilePath($contents);\n            }\n\n            $this->ensureCompiledDirectoryExists(\n                $compiledPath = $this->getCompiledPath($this->getPath())\n            );\n\n            if (! $this->files->exists($compiledPath)) {\n                $this->files->replace($compiledPath, $contents);\n\n                return;\n            }\n\n            $compiledHash = $this->files->hash($compiledPath, 'xxh128');\n\n            if ($compiledHash !== hash('xxh128', $contents)) {\n                $this->files->replace($compiledPath, $contents);\n            }\n        }\n    }\n\n    /**\n     * Append the file path to the compiled string.\n     *\n     * @param  string  $contents\n     * @return string\n     */\n    protected function appendFilePath($contents)\n    {\n        $tokens = $this->getOpenAndClosingPhpTokens($contents);\n\n        if ($tokens->isNotEmpty() && $tokens->last() !== T_CLOSE_TAG) {\n            $contents .= ' ?>';\n        }\n\n        return $contents.\"<?php /**PATH {$this->getPath()} ENDPATH**/ ?>\";\n    }\n\n    /**\n     * Get the open and closing PHP tag tokens from the given string.\n     *\n     * @param  string  $contents\n     * @return \\Illuminate\\Support\\Collection\n     */\n    protected function getOpenAndClosingPhpTokens($contents)\n    {\n        $tokens = [];\n\n        foreach (token_get_all($contents) as $token) {\n            if ($token[0] === T_OPEN_TAG || $token[0] === T_OPEN_TAG_WITH_ECHO || $token[0] === T_CLOSE_TAG) {\n                $tokens[] = $token[0];\n            }\n        }\n\n        return new Collection($tokens);\n    }\n\n    /**\n     * Get the path currently being compiled.\n     *\n     * @return string\n     */\n    public function getPath()\n    {\n        return $this->path;\n    }\n\n    /**\n     * Set the path currently being compiled.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function setPath($path)\n    {\n        $this->path = $path;\n    }\n\n    /**\n     * Compile the given Blade template contents.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileString($value)\n    {\n        [$this->footer, $result] = [[], ''];\n\n        foreach ($this->prepareStringsForCompilationUsing as $callback) {\n            $value = $callback($value);\n        }\n\n        $value = $this->storeUncompiledBlocks($value);\n\n        // First we will compile the Blade component tags. This is a precompile style\n        // step which compiles the component Blade tags into @component directives\n        // that may be used by Blade. Then we should call any other precompilers.\n        $value = $this->compileComponentTags(\n            $this->compileComments($value)\n        );\n\n        foreach ($this->precompilers as $precompiler) {\n            $value = $precompiler($value);\n        }\n\n        // Here we will loop through all of the tokens returned by the Zend lexer and\n        // parse each one into the corresponding valid PHP. We will then have this\n        // template as the correctly rendered PHP that can be rendered natively.\n        foreach (token_get_all($value) as $token) {\n            $result .= is_array($token) ? $this->parseToken($token) : $token;\n        }\n\n        if (! empty($this->rawBlocks)) {\n            $result = $this->restoreRawContent($result);\n        }\n\n        // If there are any footer lines that need to get added to a template we will\n        // add them here at the end of the template. This gets used mainly for the\n        // template inheritance via the extends keyword that should be appended.\n        if (count($this->footer) > 0) {\n            $result = $this->addFooters($result);\n        }\n\n        if (! empty($this->echoHandlers)) {\n            $result = $this->addBladeCompilerVariable($result);\n        }\n\n        return str_replace(\n            ['##BEGIN-COMPONENT-CLASS##', '##END-COMPONENT-CLASS##'],\n            '',\n            $result);\n    }\n\n    /**\n     * Evaluate and render a Blade string to HTML.\n     *\n     * @param  string  $string\n     * @param  array  $data\n     * @param  bool  $deleteCachedView\n     * @return string\n     */\n    public static function render($string, $data = [], $deleteCachedView = false)\n    {\n        $component = new class($string) extends Component\n        {\n            protected $template;\n\n            public function __construct($template)\n            {\n                $this->template = $template;\n            }\n\n            public function render()\n            {\n                return $this->template;\n            }\n        };\n\n        $view = Container::getInstance()\n            ->make(ViewFactory::class)\n            ->make($component->resolveView(), $data);\n\n        return tap($view->render(), function () use ($view, $deleteCachedView) {\n            if ($deleteCachedView) {\n                @unlink($view->getPath());\n            }\n        });\n    }\n\n    /**\n     * Render a component instance to HTML.\n     *\n     * @param  \\Illuminate\\View\\Component  $component\n     * @return string\n     */\n    public static function renderComponent(Component $component)\n    {\n        $data = $component->data();\n\n        $view = value($component->resolveView(), $data);\n\n        if ($view instanceof View) {\n            return $view->with($data)->render();\n        } elseif ($view instanceof Htmlable) {\n            return $view->toHtml();\n        } else {\n            return Container::getInstance()\n                ->make(ViewFactory::class)\n                ->make($view, $data)\n                ->render();\n        }\n    }\n\n    /**\n     * Store the blocks that do not receive compilation.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function storeUncompiledBlocks($value)\n    {\n        if (str_contains($value, '@verbatim')) {\n            $value = $this->storeVerbatimBlocks($value);\n        }\n\n        if (str_contains($value, '@php')) {\n            $value = $this->storePhpBlocks($value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Store the verbatim blocks and replace them with a temporary placeholder.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function storeVerbatimBlocks($value)\n    {\n        return preg_replace_callback('/(?<!@)@verbatim(\\s*)(.*?)@endverbatim/s', function ($matches) {\n            return $matches[1].$this->storeRawBlock($matches[2]);\n        }, $value);\n    }\n\n    /**\n     * Store the PHP blocks and replace them with a temporary placeholder.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function storePhpBlocks($value)\n    {\n        return preg_replace_callback('/(?<!@)@php(.*?)@endphp/s', function ($matches) {\n            return $this->storeRawBlock(\"<?php{$matches[1]}?>\");\n        }, $value);\n    }\n\n    /**\n     * Store a raw block and return a unique raw placeholder.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function storeRawBlock($value)\n    {\n        return $this->getRawPlaceholder(\n            array_push($this->rawBlocks, $value) - 1\n        );\n    }\n\n    /**\n     * Compile the component tags.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileComponentTags($value)\n    {\n        if (! $this->compilesComponentTags) {\n            return $value;\n        }\n\n        return (new ComponentTagCompiler(\n            $this->classComponentAliases, $this->classComponentNamespaces, $this\n        ))->compile($value);\n    }\n\n    /**\n     * Replace the raw placeholders with the original code stored in the raw blocks.\n     *\n     * @param  string  $result\n     * @return string\n     */\n    protected function restoreRawContent($result)\n    {\n        $result = preg_replace_callback('/'.$this->getRawPlaceholder('(\\d+)').'/', function ($matches) {\n            return $this->rawBlocks[$matches[1]];\n        }, $result);\n\n        $this->rawBlocks = [];\n\n        return $result;\n    }\n\n    /**\n     * Get a placeholder to temporarily mark the position of raw blocks.\n     *\n     * @param  int|string  $replace\n     * @return string\n     */\n    protected function getRawPlaceholder($replace)\n    {\n        return str_replace('#', $replace, '@__raw_block_#__@');\n    }\n\n    /**\n     * Add the stored footers onto the given content.\n     *\n     * @param  string  $result\n     * @return string\n     */\n    protected function addFooters($result)\n    {\n        return ltrim($result, \"\\n\")\n                .\"\\n\".implode(\"\\n\", array_reverse($this->footer));\n    }\n\n    /**\n     * Parse the tokens from the template.\n     *\n     * @param  array  $token\n     * @return string\n     */\n    protected function parseToken($token)\n    {\n        [$id, $content] = $token;\n\n        if ($id == T_INLINE_HTML) {\n            foreach ($this->compilers as $type) {\n                $content = $this->{\"compile{$type}\"}($content);\n            }\n        }\n\n        return $content;\n    }\n\n    /**\n     * Execute the user defined extensions.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileExtensions($value)\n    {\n        foreach ($this->extensions as $compiler) {\n            $value = $compiler($value, $this);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Compile Blade statements that start with \"@\".\n     *\n     * @param  string  $template\n     * @return string\n     */\n    protected function compileStatements($template)\n    {\n        preg_match_all('/\\B@(@?\\w+(?:::\\w+)?)([ \\t]*)(\\( ( [\\S\\s]*? ) \\))?/x', $template, $matches);\n\n        $offset = 0;\n\n        for ($i = 0; isset($matches[0][$i]); $i++) {\n            $match = [\n                $matches[0][$i],\n                $matches[1][$i],\n                $matches[2][$i],\n                $matches[3][$i] ?: null,\n                $matches[4][$i] ?: null,\n            ];\n\n            // Here we check to see if we have properly found the closing parenthesis by\n            // regex pattern or not, and will recursively continue on to the next \")\"\n            // then check again until the tokenizer confirms we find the right one.\n            while (isset($match[4]) &&\n                   Str::endsWith($match[0], ')') &&\n                   ! $this->hasEvenNumberOfParentheses($match[0])) {\n                if (($after = Str::after($template, $match[0])) === $template) {\n                    break;\n                }\n\n                $rest = Str::before($after, ')');\n\n                if (isset($matches[0][$i + 1]) && Str::contains($rest.')', $matches[0][$i + 1])) {\n                    unset($matches[0][$i + 1]);\n                    $i++;\n                }\n\n                $match[0] = $match[0].$rest.')';\n                $match[3] = $match[3].$rest.')';\n                $match[4] = $match[4].$rest;\n            }\n\n            [$template, $offset] = $this->replaceFirstStatement(\n                $match[0],\n                $this->compileStatement($match),\n                $template,\n                $offset\n            );\n        }\n\n        return $template;\n    }\n\n    /**\n     * Replace the first match for a statement compilation operation.\n     *\n     * @param  string  $search\n     * @param  string  $replace\n     * @param  string  $subject\n     * @param  int  $offset\n     * @return array\n     */\n    protected function replaceFirstStatement($search, $replace, $subject, $offset)\n    {\n        $search = (string) $search;\n\n        if ($search === '') {\n            return $subject;\n        }\n\n        $position = strpos($subject, $search, $offset);\n\n        if ($position !== false) {\n            return [\n                substr_replace($subject, $replace, $position, strlen($search)),\n                $position + strlen($replace),\n            ];\n        }\n\n        return [$subject, 0];\n    }\n\n    /**\n     * Determine if the given expression has the same number of opening and closing parentheses.\n     *\n     * @param  string  $expression\n     * @return bool\n     */\n    protected function hasEvenNumberOfParentheses(string $expression)\n    {\n        try {\n            $tokens = token_get_all('<?php '.$expression);\n        } catch (ParseError) {\n            return false;\n        }\n\n        if (Arr::last($tokens) !== ')') {\n            return false;\n        }\n\n        $opening = 0;\n        $closing = 0;\n\n        foreach ($tokens as $token) {\n            if ($token == ')') {\n                $closing++;\n            } elseif ($token == '(') {\n                $opening++;\n            }\n        }\n\n        return $opening === $closing;\n    }\n\n    /**\n     * Compile a single Blade @ statement.\n     *\n     * @param  array  $match\n     * @return string\n     */\n    protected function compileStatement($match)\n    {\n        if (str_contains($match[1], '@')) {\n            $match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];\n        } elseif (isset($this->customDirectives[$match[1]])) {\n            $match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));\n        } elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {\n            $match[0] = $this->$method(Arr::get($match, 3));\n        } else {\n            return $match[0];\n        }\n\n        return isset($match[3]) ? $match[0] : $match[0].$match[2];\n    }\n\n    /**\n     * Call the given directive with the given value.\n     *\n     * @param  string  $name\n     * @param  string|null  $value\n     * @return string\n     */\n    protected function callCustomDirective($name, $value)\n    {\n        $value ??= '';\n\n        if (str_starts_with($value, '(') && str_ends_with($value, ')')) {\n            $value = Str::substr($value, 1, -1);\n        }\n\n        return call_user_func($this->customDirectives[$name], trim($value));\n    }\n\n    /**\n     * Strip the parentheses from the given expression.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    public function stripParentheses($expression)\n    {\n        if (Str::startsWith($expression, '(')) {\n            $expression = substr($expression, 1, -1);\n        }\n\n        return $expression;\n    }\n\n    /**\n     * Register a custom Blade compiler.\n     *\n     * @param  callable  $compiler\n     * @return void\n     */\n    public function extend(callable $compiler)\n    {\n        $this->extensions[] = $compiler;\n    }\n\n    /**\n     * Get the extensions used by the compiler.\n     *\n     * @return array\n     */\n    public function getExtensions()\n    {\n        return $this->extensions;\n    }\n\n    /**\n     * Register an \"if\" statement directive.\n     *\n     * @param  string  $name\n     * @param  callable  $callback\n     * @return void\n     */\n    public function if($name, callable $callback)\n    {\n        $this->conditions[$name] = $callback;\n\n        $this->directive($name, function ($expression) use ($name) {\n            return $expression !== ''\n                ? \"<?php if (\\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>\"\n                : \"<?php if (\\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>\";\n        });\n\n        $this->directive('unless'.$name, function ($expression) use ($name) {\n            return $expression !== ''\n                ? \"<?php if (! \\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>\"\n                : \"<?php if (! \\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>\";\n        });\n\n        $this->directive('else'.$name, function ($expression) use ($name) {\n            return $expression !== ''\n                ? \"<?php elseif (\\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>\"\n                : \"<?php elseif (\\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>\";\n        });\n\n        $this->directive('end'.$name, function () {\n            return '<?php endif; ?>';\n        });\n    }\n\n    /**\n     * Check the result of a condition.\n     *\n     * @param  string  $name\n     * @param  mixed  ...$parameters\n     * @return bool\n     */\n    public function check($name, ...$parameters)\n    {\n        return call_user_func($this->conditions[$name], ...$parameters);\n    }\n\n    /**\n     * Register a class-based component alias directive.\n     *\n     * @param  string  $class\n     * @param  string|null  $alias\n     * @param  string  $prefix\n     * @return void\n     */\n    public function component($class, $alias = null, $prefix = '')\n    {\n        if (! is_null($alias) && str_contains($alias, '\\\\')) {\n            [$class, $alias] = [$alias, $class];\n        }\n\n        if (is_null($alias)) {\n            $alias = str_contains($class, '\\\\View\\\\Components\\\\')\n                ? (new Collection(explode('\\\\', Str::after($class, '\\\\View\\\\Components\\\\'))))\n                    ->map(fn ($segment) => Str::kebab($segment))\n                    ->implode(':')\n                : Str::kebab(class_basename($class));\n        }\n\n        if (! empty($prefix)) {\n            $alias = $prefix.'-'.$alias;\n        }\n\n        $this->classComponentAliases[$alias] = $class;\n    }\n\n    /**\n     * Register an array of class-based components.\n     *\n     * @param  array  $components\n     * @param  string  $prefix\n     * @return void\n     */\n    public function components(array $components, $prefix = '')\n    {\n        foreach ($components as $key => $value) {\n            if (is_numeric($key)) {\n                $this->component($value, null, $prefix);\n            } else {\n                $this->component($key, $value, $prefix);\n            }\n        }\n    }\n\n    /**\n     * Get the registered class component aliases.\n     *\n     * @return array\n     */\n    public function getClassComponentAliases()\n    {\n        return $this->classComponentAliases;\n    }\n\n    /**\n     * Register a new anonymous component path.\n     *\n     * @param  string  $path\n     * @param  string|null  $prefix\n     * @return void\n     */\n    public function anonymousComponentPath(string $path, ?string $prefix = null)\n    {\n        $prefixHash = hash('xxh128', $prefix ?: $path);\n\n        $this->anonymousComponentPaths[] = [\n            'path' => $path,\n            'prefix' => $prefix,\n            'prefixHash' => $prefixHash,\n        ];\n\n        Container::getInstance()\n            ->make(ViewFactory::class)\n            ->addNamespace($prefixHash, $path);\n    }\n\n    /**\n     * Register an anonymous component namespace.\n     *\n     * @param  string  $directory\n     * @param  string|null  $prefix\n     * @return void\n     */\n    public function anonymousComponentNamespace(string $directory, ?string $prefix = null)\n    {\n        $prefix ??= $directory;\n\n        $this->anonymousComponentNamespaces[$prefix] = (new Stringable($directory))\n            ->replace('/', '.')\n            ->trim('. ')\n            ->toString();\n    }\n\n    /**\n     * Register a class-based component namespace.\n     *\n     * @param  string  $namespace\n     * @param  string  $prefix\n     * @return void\n     */\n    public function componentNamespace($namespace, $prefix)\n    {\n        $this->classComponentNamespaces[$prefix] = $namespace;\n    }\n\n    /**\n     * Get the registered anonymous component paths.\n     *\n     * @return array\n     */\n    public function getAnonymousComponentPaths()\n    {\n        return $this->anonymousComponentPaths;\n    }\n\n    /**\n     * Get the registered anonymous component namespaces.\n     *\n     * @return array\n     */\n    public function getAnonymousComponentNamespaces()\n    {\n        return $this->anonymousComponentNamespaces;\n    }\n\n    /**\n     * Get the registered class component namespaces.\n     *\n     * @return array\n     */\n    public function getClassComponentNamespaces()\n    {\n        return $this->classComponentNamespaces;\n    }\n\n    /**\n     * Register a component alias directive.\n     *\n     * @param  string  $path\n     * @param  string|null  $alias\n     * @return void\n     */\n    public function aliasComponent($path, $alias = null)\n    {\n        $alias = $alias ?: Arr::last(explode('.', $path));\n\n        $this->directive($alias, function ($expression) use ($path) {\n            return $expression\n                ? \"<?php \\$__env->startComponent('{$path}', {$expression}); ?>\"\n                : \"<?php \\$__env->startComponent('{$path}'); ?>\";\n        });\n\n        $this->directive('end'.$alias, function ($expression) {\n            return '<?php echo $__env->renderComponent(); ?>';\n        });\n    }\n\n    /**\n     * Register an include alias directive.\n     *\n     * @param  string  $path\n     * @param  string|null  $alias\n     * @return void\n     */\n    public function include($path, $alias = null)\n    {\n        $this->aliasInclude($path, $alias);\n    }\n\n    /**\n     * Register an include alias directive.\n     *\n     * @param  string  $path\n     * @param  string|null  $alias\n     * @return void\n     */\n    public function aliasInclude($path, $alias = null)\n    {\n        $alias = $alias ?: Arr::last(explode('.', $path));\n\n        $this->directive($alias, function ($expression) use ($path) {\n            $expression = $this->stripParentheses($expression) ?: '[]';\n\n            return \"<?php echo \\$__env->make('{$path}', {$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n        });\n    }\n\n    /**\n     * Register a handler for custom directives, binding the handler to the compiler.\n     *\n     * @param  string  $name\n     * @param  callable  $handler\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function bindDirective($name, callable $handler)\n    {\n        $this->directive($name, $handler, bind: true);\n    }\n\n    /**\n     * Register a handler for custom directives.\n     *\n     * @param  string  $name\n     * @param  ($bind is true ? \\Closure : callable)  $handler\n     * @param  bool  $bind\n     * @return void\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function directive($name, callable $handler, bool $bind = false)\n    {\n        if (! preg_match('/^\\w+(?:::\\w+)?$/x', $name)) {\n            throw new InvalidArgumentException(\"The directive name [{$name}] is not valid. Directive names must only contain alphanumeric characters and underscores.\");\n        }\n\n        $this->customDirectives[$name] = $bind ? $handler->bindTo($this, BladeCompiler::class) : $handler;\n    }\n\n    /**\n     * Get the list of custom directives.\n     *\n     * @return array\n     */\n    public function getCustomDirectives()\n    {\n        return $this->customDirectives;\n    }\n\n    /**\n     * Indicate that the following callable should be used to prepare strings for compilation.\n     *\n     * @param  callable  $callback\n     * @return $this\n     */\n    public function prepareStringsForCompilationUsing(callable $callback)\n    {\n        $this->prepareStringsForCompilationUsing[] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a new precompiler.\n     *\n     * @param  callable  $precompiler\n     * @return void\n     */\n    public function precompiler(callable $precompiler)\n    {\n        $this->precompilers[] = $precompiler;\n    }\n\n    /**\n     * Execute the given callback using a custom echo format.\n     *\n     * @param  string  $format\n     * @param  callable  $callback\n     * @return string\n     */\n    public function usingEchoFormat($format, callable $callback)\n    {\n        $originalEchoFormat = $this->echoFormat;\n\n        $this->setEchoFormat($format);\n\n        try {\n            $output = call_user_func($callback);\n        } finally {\n            $this->setEchoFormat($originalEchoFormat);\n        }\n\n        return $output;\n    }\n\n    /**\n     * Set the echo format to be used by the compiler.\n     *\n     * @param  string  $format\n     * @return void\n     */\n    public function setEchoFormat($format)\n    {\n        $this->echoFormat = $format;\n    }\n\n    /**\n     * Set the \"echo\" format to double encode entities.\n     *\n     * @return void\n     */\n    public function withDoubleEncoding()\n    {\n        $this->setEchoFormat('e(%s, true)');\n    }\n\n    /**\n     * Set the \"echo\" format to not double encode entities.\n     *\n     * @return void\n     */\n    public function withoutDoubleEncoding()\n    {\n        $this->setEchoFormat('e(%s, false)');\n    }\n\n    /**\n     * Indicate that component tags should not be compiled.\n     *\n     * @return void\n     */\n    public function withoutComponentTags()\n    {\n        $this->compilesComponentTags = false;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Compiler.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers;\n\nuse ErrorException;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\nabstract class Compiler\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The cache path for the compiled views.\n     *\n     * @var string\n     */\n    protected $cachePath;\n\n    /**\n     * The base path that should be removed from paths before hashing.\n     *\n     * @var string\n     */\n    protected $basePath;\n\n    /**\n     * Determines if compiled views should be cached.\n     *\n     * @var bool\n     */\n    protected $shouldCache;\n\n    /**\n     * The compiled view file extension.\n     *\n     * @var string\n     */\n    protected $compiledExtension = 'php';\n\n    /**\n     * Indicates if view cache timestamps should be checked.\n     *\n     * @var bool\n     */\n    protected $shouldCheckTimestamps;\n\n    /**\n     * Create a new compiler instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string  $cachePath\n     * @param  string  $basePath\n     * @param  bool  $shouldCache\n     * @param  string  $compiledExtension\n     * @param  bool  $shouldCheckTimestamps\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct(\n        Filesystem $files,\n        $cachePath,\n        $basePath = '',\n        $shouldCache = true,\n        $compiledExtension = 'php',\n        $shouldCheckTimestamps = true,\n    ) {\n        if (! $cachePath) {\n            throw new InvalidArgumentException('Please provide a valid cache path.');\n        }\n\n        $this->files = $files;\n        $this->cachePath = $cachePath;\n        $this->basePath = $basePath;\n        $this->shouldCache = $shouldCache;\n        $this->compiledExtension = $compiledExtension;\n        $this->shouldCheckTimestamps = $shouldCheckTimestamps;\n    }\n\n    /**\n     * Get the path to the compiled version of a view.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function getCompiledPath($path)\n    {\n        return $this->cachePath.'/'.hash('xxh128', 'v2'.Str::after($path, $this->basePath)).'.'.$this->compiledExtension;\n    }\n\n    /**\n     * Determine if the view at the given path is expired.\n     *\n     * @param  string  $path\n     * @return bool\n     *\n     * @throws \\ErrorException\n     */\n    public function isExpired($path)\n    {\n        if (! $this->shouldCache) {\n            return true;\n        }\n\n        $compiled = $this->getCompiledPath($path);\n\n        // If the compiled file doesn't exist we will indicate that the view is expired\n        // so that it can be re-compiled. Else, we will verify the last modification\n        // of the views is less than the modification times of the compiled views.\n        if (! $this->files->exists($compiled)) {\n            return true;\n        }\n\n        if (! $this->shouldCheckTimestamps) {\n            return false;\n        }\n\n        try {\n            return $this->files->lastModified($path) >=\n                $this->files->lastModified($compiled);\n        } catch (ErrorException $exception) {\n            if (! $this->files->exists($compiled)) {\n                return true;\n            }\n\n            throw $exception;\n        }\n    }\n\n    /**\n     * Create the compiled file directory if necessary.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    protected function ensureCompiledDirectoryExists($path)\n    {\n        if (! $this->files->exists(dirname($path))) {\n            $this->files->makeDirectory(dirname($path), 0777, true, true);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/CompilerInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers;\n\ninterface CompilerInterface\n{\n    /**\n     * Get the path to the compiled version of a view.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    public function getCompiledPath($path);\n\n    /**\n     * Determine if the given view is expired.\n     *\n     * @param  string  $path\n     * @return bool\n     */\n    public function isExpired($path);\n\n    /**\n     * Compile the view at the given path.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function compile($path);\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/ComponentTagCompiler.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\View\\AnonymousComponent;\nuse Illuminate\\View\\DynamicComponent;\nuse Illuminate\\View\\ViewFinderInterface;\nuse InvalidArgumentException;\nuse ReflectionClass;\n\n/**\n * @author Spatie bvba <info@spatie.be>\n * @author Taylor Otwell <taylor@laravel.com>\n */\nclass ComponentTagCompiler\n{\n    /**\n     * The Blade compiler instance.\n     *\n     * @var \\Illuminate\\View\\Compilers\\BladeCompiler\n     */\n    protected $blade;\n\n    /**\n     * The component class aliases.\n     *\n     * @var array\n     */\n    protected $aliases = [];\n\n    /**\n     * The component class namespaces.\n     *\n     * @var array\n     */\n    protected $namespaces = [];\n\n    /**\n     * The \"bind:\" attributes that have been compiled for the current component.\n     *\n     * @var array\n     */\n    protected $boundAttributes = [];\n\n    /**\n     * Create a new component tag compiler.\n     *\n     * @param  array  $aliases\n     * @param  array  $namespaces\n     * @param  \\Illuminate\\View\\Compilers\\BladeCompiler|null  $blade\n     */\n    public function __construct(array $aliases = [], array $namespaces = [], ?BladeCompiler $blade = null)\n    {\n        $this->aliases = $aliases;\n        $this->namespaces = $namespaces;\n\n        $this->blade = $blade ?: new BladeCompiler(new Filesystem, sys_get_temp_dir());\n    }\n\n    /**\n     * Compile the component and slot tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compile(string $value)\n    {\n        $value = $this->compileSlots($value);\n\n        return $this->compileTags($value);\n    }\n\n    /**\n     * Compile the tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function compileTags(string $value)\n    {\n        $value = $this->compileSelfClosingTags($value);\n        $value = $this->compileOpeningTags($value);\n        $value = $this->compileClosingTags($value);\n\n        return $value;\n    }\n\n    /**\n     * Compile the opening tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileOpeningTags(string $value)\n    {\n        $pattern = \"/\n            <\n                \\s*\n                x[-\\:]([\\w\\-\\:\\.]*)\n                (?<attributes>\n                    (?:\n                        \\s+\n                        (?:\n                            (?:\n                                @(?:class)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                @(?:style)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                \\{\\{\\s*\\\\\\$attributes(?:[^}]+?)?\\s*\\}\\}\n                            )\n                            |\n                            (?:\n                                (\\:\\\\\\$)(\\w+)\n                            )\n                            |\n                            (?:\n                                [\\w\\-:.@%]+\n                                (\n                                    =\n                                    (?:\n                                        \\\\\\\"[^\\\\\\\"]*\\\\\\\"\n                                        |\n                                        \\'[^\\']*\\'\n                                        |\n                                        [^\\'\\\\\\\"=<>]+\n                                    )\n                                )?\n                            )\n                        )\n                    )*\n                    \\s*\n                )\n                (?<![\\/=\\-])\n            >\n        /x\";\n\n        return preg_replace_callback($pattern, function (array $matches) {\n            $this->boundAttributes = [];\n\n            $attributes = $this->getAttributesFromAttributeString($matches['attributes']);\n\n            return $this->componentString($matches[1], $attributes);\n        }, $value);\n    }\n\n    /**\n     * Compile the self-closing tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function compileSelfClosingTags(string $value)\n    {\n        $pattern = \"/\n            <\n                \\s*\n                x[-\\:]([\\w\\-\\:\\.]*)\n                \\s*\n                (?<attributes>\n                    (?:\n                        \\s+\n                        (?:\n                            (?:\n                                @(?:class)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                @(?:style)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                \\{\\{\\s*\\\\\\$attributes(?:[^}]+?)?\\s*\\}\\}\n                            )\n                            |\n                            (?:\n                                (\\:\\\\\\$)(\\w+)\n                            )\n                            |\n                            (?:\n                                [\\w\\-:.@%]+\n                                (\n                                    =\n                                    (?:\n                                        \\\\\\\"[^\\\\\\\"]*\\\\\\\"\n                                        |\n                                        \\'[^\\']*\\'\n                                        |\n                                        [^\\'\\\\\\\"=<>]+\n                                    )\n                                )?\n                            )\n                        )\n                    )*\n                    \\s*\n                )\n            \\/>\n        /x\";\n\n        return preg_replace_callback($pattern, function (array $matches) {\n            $this->boundAttributes = [];\n\n            $attributes = $this->getAttributesFromAttributeString($matches['attributes']);\n\n            return $this->componentString($matches[1], $attributes).\"\\n@endComponentClass##END-COMPONENT-CLASS##\";\n        }, $value);\n    }\n\n    /**\n     * Compile the Blade component string for the given component and attributes.\n     *\n     * @param  string  $component\n     * @param  array  $attributes\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function componentString(string $component, array $attributes)\n    {\n        $class = $this->componentClass($component);\n\n        [$data, $attributes] = $this->partitionDataAndAttributes($class, $attributes);\n\n        $data = $data->mapWithKeys(function ($value, $key) {\n            return [Str::camel($key) => $value];\n        });\n\n        // If the component doesn't exist as a class, we'll assume it's a class-less\n        // component and pass the component as a view parameter to the data so it\n        // can be accessed within the component and we can render out the view.\n        if (! class_exists($class)) {\n            $view = Str::startsWith($component, 'mail::')\n                ? \"\\$__env->getContainer()->make(Illuminate\\\\View\\\\Factory::class)->make('{$component}')\"\n                : \"'$class'\";\n\n            $parameters = [\n                'view' => $view,\n                'data' => '['.$this->attributesToString($data->all(), $escapeBound = false).']',\n            ];\n\n            $class = AnonymousComponent::class;\n        } else {\n            $parameters = $data->all();\n        }\n\n        return \"##BEGIN-COMPONENT-CLASS##@component('{$class}', '{$component}', [\".$this->attributesToString($parameters, $escapeBound = false).'])\n<?php if (isset($attributes) && $attributes instanceof Illuminate\\View\\ComponentAttributeBag): ?>\n<?php $attributes = $attributes->except(\\\\'.$class.'::ignoredParameterNames()); ?>\n<?php endif; ?>\n<?php $component->withAttributes(['.$this->attributesToString($attributes->all(), $escapeAttributes = $class !== DynamicComponent::class).']); ?>';\n    }\n\n    /**\n     * Get the component class for a given component alias.\n     *\n     * @param  string  $component\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function componentClass(string $component)\n    {\n        $viewFactory = Container::getInstance()->make(Factory::class);\n\n        if (isset($this->aliases[$component])) {\n            if (class_exists($alias = $this->aliases[$component])) {\n                return $alias;\n            }\n\n            if ($viewFactory->exists($alias)) {\n                return $alias;\n            }\n\n            throw new InvalidArgumentException(\n                \"Unable to locate class or view [{$alias}] for component [{$component}].\"\n            );\n        }\n\n        if ($class = $this->findClassByComponent($component)) {\n            return $class;\n        }\n\n        if (class_exists($class = $this->guessClassName($component))) {\n            return $class;\n        }\n\n        if (class_exists($class = $class.'\\\\'.Str::afterLast($class, '\\\\'))) {\n            return $class;\n        }\n\n        if (! is_null($guess = $this->guessAnonymousComponentUsingNamespaces($viewFactory, $component)) ||\n            ! is_null($guess = $this->guessAnonymousComponentUsingPaths($viewFactory, $component))) {\n            return $guess;\n        }\n\n        if (Str::startsWith($component, 'mail::')) {\n            return $component;\n        }\n\n        throw new InvalidArgumentException(\n            \"Unable to locate a class or view for component [{$component}].\"\n        );\n    }\n\n    /**\n     * Attempt to find an anonymous component using the registered anonymous component paths.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $viewFactory\n     * @param  string  $component\n     * @return string|null\n     */\n    protected function guessAnonymousComponentUsingPaths(Factory $viewFactory, string $component)\n    {\n        $delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;\n\n        foreach ($this->blade->getAnonymousComponentPaths() as $path) {\n            try {\n                if (str_contains($component, $delimiter) &&\n                    ! str_starts_with($component, $path['prefix'].$delimiter)) {\n                    continue;\n                }\n\n                $formattedComponent = str_starts_with($component, $path['prefix'].$delimiter)\n                    ? Str::after($component, $delimiter)\n                    : $component;\n\n                if (! is_null($guess = match (true) {\n                    $viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent) => $guess,\n                    $viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent.'.index') => $guess,\n                    $viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent.'.'.Str::afterLast($formattedComponent, '.')) => $guess,\n                    default => null,\n                })) {\n                    return $guess;\n                }\n            } catch (InvalidArgumentException) {\n                //\n            }\n        }\n    }\n\n    /**\n     * Attempt to find an anonymous component using the registered anonymous component namespaces.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $viewFactory\n     * @param  string  $component\n     * @return string|null\n     */\n    protected function guessAnonymousComponentUsingNamespaces(Factory $viewFactory, string $component)\n    {\n        return (new Collection($this->blade->getAnonymousComponentNamespaces()))\n            ->filter(function ($directory, $prefix) use ($component) {\n                return Str::startsWith($component, $prefix.'::');\n            })\n            ->prepend('components', $component)\n            ->reduce(function ($carry, $directory, $prefix) use ($component, $viewFactory) {\n                if (! is_null($carry)) {\n                    return $carry;\n                }\n\n                $componentName = Str::after($component, $prefix.'::');\n\n                if ($viewFactory->exists($view = $this->guessViewName($componentName, $directory))) {\n                    return $view;\n                }\n\n                if ($viewFactory->exists($view = $this->guessViewName($componentName, $directory).'.index')) {\n                    return $view;\n                }\n\n                $lastViewSegment = Str::afterLast(Str::afterLast($componentName, '.'), ':');\n\n                if ($viewFactory->exists($view = $this->guessViewName($componentName, $directory).'.'.$lastViewSegment)) {\n                    return $view;\n                }\n            });\n    }\n\n    /**\n     * Find the class for the given component using the registered namespaces.\n     *\n     * @param  string  $component\n     * @return string|null\n     */\n    public function findClassByComponent(string $component)\n    {\n        $segments = explode('::', $component);\n\n        $prefix = $segments[0];\n\n        if (! isset($this->namespaces[$prefix], $segments[1])) {\n            return;\n        }\n\n        if (class_exists($class = $this->namespaces[$prefix].'\\\\'.$this->formatClassName($segments[1]))) {\n            return $class;\n        }\n\n        if (class_exists($class = $class.'\\\\'.Str::afterLast($class, '\\\\'))) {\n            return $class;\n        }\n    }\n\n    /**\n     * Guess the class name for the given component.\n     *\n     * @param  string  $component\n     * @return string\n     */\n    public function guessClassName(string $component)\n    {\n        $namespace = Container::getInstance()\n            ->make(Application::class)\n            ->getNamespace();\n\n        $class = $this->formatClassName($component);\n\n        return $namespace.'View\\\\Components\\\\'.$class;\n    }\n\n    /**\n     * Format the class name for the given component.\n     *\n     * @param  string  $component\n     * @return string\n     */\n    public function formatClassName(string $component)\n    {\n        $componentPieces = array_map(function ($componentPiece) {\n            return ucfirst(Str::camel($componentPiece));\n        }, explode('.', $component));\n\n        return implode('\\\\', $componentPieces);\n    }\n\n    /**\n     * Guess the view name for the given component.\n     *\n     * @param  string  $name\n     * @param  string  $prefix\n     * @return string\n     */\n    public function guessViewName($name, $prefix = 'components.')\n    {\n        if (! Str::endsWith($prefix, '.')) {\n            $prefix .= '.';\n        }\n\n        $delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;\n\n        if (str_contains($name, $delimiter)) {\n            return Str::replaceFirst($delimiter, $delimiter.$prefix, $name);\n        }\n\n        return $prefix.$name;\n    }\n\n    /**\n     * Partition the data and extra attributes from the given array of attributes.\n     *\n     * @param  string  $class\n     * @param  array  $attributes\n     * @return array\n     */\n    public function partitionDataAndAttributes($class, array $attributes)\n    {\n        // If the class doesn't exist, we'll assume it is a class-less component and\n        // return all of the attributes as both data and attributes since we have\n        // now way to partition them. The user can exclude attributes manually.\n        if (! class_exists($class)) {\n            return [new Collection($attributes), new Collection($attributes)];\n        }\n\n        $constructor = (new ReflectionClass($class))->getConstructor();\n\n        $parameterNames = $constructor\n            ? (new Collection($constructor->getParameters()))->map->getName()->all()\n            : [];\n\n        return (new Collection($attributes))\n            ->partition(fn ($value, $key) => in_array(Str::camel($key), $parameterNames))\n            ->all();\n    }\n\n    /**\n     * Compile the closing tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileClosingTags(string $value)\n    {\n        return preg_replace(\"/<\\/\\s*x[-\\:][\\w\\-\\:\\.]*\\s*>/\", ' @endComponentClass##END-COMPONENT-CLASS##', $value);\n    }\n\n    /**\n     * Compile the slot tags within the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileSlots(string $value)\n    {\n        $pattern = \"/\n            <\n                \\s*\n                x[\\-\\:]slot\n                (?:\\:(?<inlineName>\\w+(?:-\\w+)*))?\n                (?:\\s+name=(?<name>(\\\"[^\\\"]+\\\"|\\\\\\'[^\\\\\\']+\\\\\\'|[^\\s>]+)))?\n                (?:\\s+\\:name=(?<boundName>(\\\"[^\\\"]+\\\"|\\\\\\'[^\\\\\\']+\\\\\\'|[^\\s>]+)))?\n                (?<attributes>\n                    (?:\n                        \\s+\n                        (?:\n                            (?:\n                                @(?:class)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                @(?:style)(\\( (?: (?>[^()]+) | (?-1) )* \\))\n                            )\n                            |\n                            (?:\n                                \\{\\{\\s*\\\\\\$attributes(?:[^}]+?)?\\s*\\}\\}\n                            )\n                            |\n                            (?:\n                                [\\w\\-:.@]+\n                                (\n                                    =\n                                    (?:\n                                        \\\\\\\"[^\\\\\\\"]*\\\\\\\"\n                                        |\n                                        \\'[^\\']*\\'\n                                        |\n                                        [^\\'\\\\\\\"=<>]+\n                                    )\n                                )?\n                            )\n                        )\n                    )*\n                    \\s*\n                )\n                (?<![\\/=\\-])\n            >\n        /x\";\n\n        $value = preg_replace_callback($pattern, function ($matches) {\n            $name = $this->stripQuotes($matches['inlineName'] ?: $matches['name'] ?: $matches['boundName']) ?: \"'slot'\";\n\n            if (Str::contains($name, '-') && ! empty($matches['inlineName'])) {\n                $name = Str::camel($name);\n            }\n\n            // If the name was given as a simple string, we will wrap it in quotes as if it was bound for convenience...\n            if (! empty($matches['inlineName']) || ! empty($matches['name'])) {\n                $name = \"'{$name}'\";\n            }\n\n            $this->boundAttributes = [];\n\n            $attributes = $this->getAttributesFromAttributeString($matches['attributes']);\n\n            // If an inline name was provided and a name or bound name was *also* provided, we will assume the name should be an attribute...\n            if (! empty($matches['inlineName']) && (! empty($matches['name']) || ! empty($matches['boundName']))) {\n                $attributes = ! empty($matches['name'])\n                    ? array_merge($attributes, $this->getAttributesFromAttributeString('name='.$matches['name']))\n                    : array_merge($attributes, $this->getAttributesFromAttributeString(':name='.$matches['boundName']));\n            }\n\n            return \" @slot({$name}, null, [\".$this->attributesToString($attributes).']) ';\n        }, $value);\n\n        return preg_replace('/<\\/\\s*x[\\-\\:]slot[^>]*>/', ' @endslot', $value);\n    }\n\n    /**\n     * Get an array of attributes from the given attribute string.\n     *\n     * @param  string  $attributeString\n     * @return array\n     */\n    protected function getAttributesFromAttributeString(string $attributeString)\n    {\n        $attributeString = $this->parseShortAttributeSyntax($attributeString);\n        $attributeString = $this->parseAttributeBag($attributeString);\n        $attributeString = $this->parseComponentTagClassStatements($attributeString);\n        $attributeString = $this->parseComponentTagStyleStatements($attributeString);\n        $attributeString = $this->parseBindAttributes($attributeString);\n\n        $pattern = '/\n            (?<attribute>[\\w\\-:.@%]+)\n            (\n                =\n                (?<value>\n                    (\n                        \\\"[^\\\"]+\\\"\n                        |\n                        \\\\\\'[^\\\\\\']+\\\\\\'\n                        |\n                        [^\\s>]+\n                    )\n                )\n            )?\n        /x';\n\n        if (! preg_match_all($pattern, $attributeString, $matches, PREG_SET_ORDER)) {\n            return [];\n        }\n\n        return (new Collection($matches))->mapWithKeys(function ($match) {\n            $attribute = $match['attribute'];\n            $value = $match['value'] ?? null;\n\n            if (is_null($value)) {\n                $value = 'true';\n\n                $attribute = Str::start($attribute, 'bind:');\n            }\n\n            $value = $this->stripQuotes($value);\n\n            if (str_starts_with($attribute, 'bind:')) {\n                $attribute = Str::after($attribute, 'bind:');\n\n                $this->boundAttributes[$attribute] = true;\n            } else {\n                $value = \"'\".$this->compileAttributeEchos($value).\"'\";\n            }\n\n            if (str_starts_with($attribute, '::')) {\n                $attribute = substr($attribute, 1);\n            }\n\n            return [$attribute => $value];\n        })->toArray();\n    }\n\n    /**\n     * Parses a short attribute syntax like :$foo into a fully-qualified syntax like :foo=\"$foo\".\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function parseShortAttributeSyntax(string $value)\n    {\n        $pattern = \"/\\s\\:\\\\\\$(\\w+)/x\";\n\n        return preg_replace_callback($pattern, function (array $matches) {\n            return \" :{$matches[1]}=\\\"\\${$matches[1]}\\\"\";\n        }, $value);\n    }\n\n    /**\n     * Parse the attribute bag in a given attribute string into its fully-qualified syntax.\n     *\n     * @param  string  $attributeString\n     * @return string\n     */\n    protected function parseAttributeBag(string $attributeString)\n    {\n        $pattern = \"/\n            (?:^|\\s+)                                        # start of the string or whitespace between attributes\n            \\{\\{\\s*(\\\\\\$attributes(?:[^}]+?(?<!\\s))?)\\s*\\}\\} # exact match of attributes variable being echoed\n        /x\";\n\n        return preg_replace($pattern, ' :attributes=\"$1\"', $attributeString);\n    }\n\n    /**\n     * Parse @class statements in a given attribute string into their fully-qualified syntax.\n     *\n     * @param  string  $attributeString\n     * @return string\n     */\n    protected function parseComponentTagClassStatements(string $attributeString)\n    {\n        return preg_replace_callback(\n            '/@(class)(\\( ( (?>[^()]+) | (?2) )* \\))/x', function ($match) {\n                if ($match[1] === 'class') {\n                    $match[2] = str_replace('\"', \"'\", $match[2]);\n\n                    return \":class=\\\"\\Illuminate\\Support\\Arr::toCssClasses{$match[2]}\\\"\";\n                }\n\n                return $match[0];\n            }, $attributeString\n        );\n    }\n\n    /**\n     * Parse @style statements in a given attribute string into their fully-qualified syntax.\n     *\n     * @param  string  $attributeString\n     * @return string\n     */\n    protected function parseComponentTagStyleStatements(string $attributeString)\n    {\n        return preg_replace_callback(\n            '/@(style)(\\( ( (?>[^()]+) | (?2) )* \\))/x', function ($match) {\n                if ($match[1] === 'style') {\n                    $match[2] = str_replace('\"', \"'\", $match[2]);\n\n                    return \":style=\\\"\\Illuminate\\Support\\Arr::toCssStyles{$match[2]}\\\"\";\n                }\n\n                return $match[0];\n            }, $attributeString\n        );\n    }\n\n    /**\n     * Parse the \"bind\" attributes in a given attribute string into their fully-qualified syntax.\n     *\n     * @param  string  $attributeString\n     * @return string\n     */\n    protected function parseBindAttributes(string $attributeString)\n    {\n        $pattern = \"/\n            (?:^|\\s+)     # start of the string or whitespace between attributes\n            :(?!:)        # attribute needs to start with a single colon\n            ([\\w\\-:.@]+)  # match the actual attribute name\n            =             # only match attributes that have a value\n        /xm\";\n\n        return preg_replace($pattern, ' bind:$1=', $attributeString);\n    }\n\n    /**\n     * Compile any Blade echo statements that are present in the attribute string.\n     *\n     * These echo statements need to be converted to string concatenation statements.\n     *\n     * @param  string  $attributeString\n     * @return string\n     */\n    protected function compileAttributeEchos(string $attributeString)\n    {\n        $value = $this->blade->compileEchos($attributeString);\n\n        $value = $this->escapeSingleQuotesOutsideOfPhpBlocks($value);\n\n        $value = str_replace('<?php echo ', '\\'.', $value);\n        $value = str_replace('; ?>', '.\\'', $value);\n\n        return $value;\n    }\n\n    /**\n     * Escape the single quotes in the given string that are outside of PHP blocks.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function escapeSingleQuotesOutsideOfPhpBlocks(string $value)\n    {\n        return (new Collection(token_get_all($value)))->map(function ($token) {\n            if (! is_array($token)) {\n                return $token;\n            }\n\n            return $token[0] === T_INLINE_HTML\n                ? str_replace(\"'\", \"\\\\'\", $token[1])\n                : $token[1];\n        })->implode('');\n    }\n\n    /**\n     * Convert an array of attributes to a string.\n     *\n     * @param  array  $attributes\n     * @param  bool  $escapeBound\n     * @return string\n     */\n    protected function attributesToString(array $attributes, $escapeBound = true)\n    {\n        return (new Collection($attributes))\n            ->map(function (string $value, string $attribute) use ($escapeBound) {\n                return $escapeBound && isset($this->boundAttributes[$attribute]) && $value !== 'true' && ! is_numeric($value)\n                    ? \"'{$attribute}' => \\Illuminate\\View\\Compilers\\BladeCompiler::sanitizeComponentAttribute({$value})\"\n                    : \"'{$attribute}' => {$value}\";\n            })\n            ->implode(',');\n    }\n\n    /**\n     * Strip any quotes from the given string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function stripQuotes(string $value)\n    {\n        return Str::startsWith($value, ['\"', '\\''])\n            ? substr($value, 1, -1)\n            : $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesAuthorizations.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesAuthorizations\n{\n    /**\n     * Compile the can statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileCan($expression)\n    {\n        return \"<?php if (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->check{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the cannot statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileCannot($expression)\n    {\n        return \"<?php if (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->denies{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the canany statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileCanany($expression)\n    {\n        return \"<?php if (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->any{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the else-can statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElsecan($expression)\n    {\n        return \"<?php elseif (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->check{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the else-cannot statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElsecannot($expression)\n    {\n        return \"<?php elseif (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->denies{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the else-canany statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElsecanany($expression)\n    {\n        return \"<?php elseif (app(\\Illuminate\\\\Contracts\\\\Auth\\\\Access\\\\Gate::class)->any{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the end-can statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndcan()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the end-cannot statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndcannot()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the end-canany statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndcanany()\n    {\n        return '<?php endif; ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesClasses.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesClasses\n{\n    /**\n     * Compile the conditional class statement into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileClass($expression)\n    {\n        $expression = is_null($expression) ? '([])' : $expression;\n\n        return \"class=\\\"<?php echo \\Illuminate\\Support\\Arr::toCssClasses{$expression}; ?>\\\"\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesComments.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesComments\n{\n    /**\n     * Compile Blade comments into an empty string.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileComments($value)\n    {\n        $pattern = sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]);\n\n        return preg_replace($pattern, '', $value);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesComponents.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\View\\AnonymousComponent;\nuse Illuminate\\View\\ComponentAttributeBag;\n\ntrait CompilesComponents\n{\n    /**\n     * The component name hash stack.\n     *\n     * @var array\n     */\n    protected static $componentHashStack = [];\n\n    /**\n     * Compile the component statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileComponent($expression)\n    {\n        [$component, $alias, $data] = str_contains($expression, ',')\n            ? array_map(trim(...), explode(',', trim($expression, '()'), 3)) + ['', '', '']\n            : [trim($expression, '()'), '', ''];\n\n        $component = trim($component, '\\'\"');\n\n        $hash = static::newComponentHash(\n            $component === AnonymousComponent::class ? $component.':'.trim($alias, '\\'\"') : $component\n        );\n\n        if (Str::contains($component, ['::class', '\\\\'])) {\n            return static::compileClassComponentOpening($component, $alias, $data, $hash);\n        }\n\n        return \"<?php \\$__env->startComponent{$expression}; ?>\";\n    }\n\n    /**\n     * Get a new component hash for a component name.\n     *\n     * @param  string  $component\n     * @return string\n     */\n    public static function newComponentHash(string $component)\n    {\n        static::$componentHashStack[] = $hash = hash('xxh128', $component);\n\n        return $hash;\n    }\n\n    /**\n     * Compile a class component opening.\n     *\n     * @param  string  $component\n     * @param  string  $alias\n     * @param  string  $data\n     * @param  string  $hash\n     * @return string\n     */\n    public static function compileClassComponentOpening(string $component, string $alias, string $data, string $hash)\n    {\n        return implode(\"\\n\", [\n            '<?php if (isset($component)) { $__componentOriginal'.$hash.' = $component; } ?>',\n            '<?php if (isset($attributes)) { $__attributesOriginal'.$hash.' = $attributes; } ?>',\n            '<?php $component = '.$component.'::resolve('.($data ?: '[]').' + (isset($attributes) && $attributes instanceof Illuminate\\View\\ComponentAttributeBag ? $attributes->all() : [])); ?>',\n            '<?php $component->withName('.$alias.'); ?>',\n            '<?php if ($component->shouldRender()): ?>',\n            '<?php $__env->startComponent($component->resolveView(), $component->data()); ?>',\n        ]);\n    }\n\n    /**\n     * Compile the end-component statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndComponent()\n    {\n        return '<?php echo $__env->renderComponent(); ?>';\n    }\n\n    /**\n     * Compile the end-component statements into valid PHP.\n     *\n     * @return string\n     */\n    public function compileEndComponentClass()\n    {\n        $hash = array_pop(static::$componentHashStack);\n\n        return $this->compileEndComponent().\"\\n\".implode(\"\\n\", [\n            '<?php endif; ?>',\n            '<?php if (isset($__attributesOriginal'.$hash.')): ?>',\n            '<?php $attributes = $__attributesOriginal'.$hash.'; ?>',\n            '<?php unset($__attributesOriginal'.$hash.'); ?>',\n            '<?php endif; ?>',\n            '<?php if (isset($__componentOriginal'.$hash.')): ?>',\n            '<?php $component = $__componentOriginal'.$hash.'; ?>',\n            '<?php unset($__componentOriginal'.$hash.'); ?>',\n            '<?php endif; ?>',\n        ]);\n    }\n\n    /**\n     * Compile the slot statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileSlot($expression)\n    {\n        return \"<?php \\$__env->slot{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the end-slot statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndSlot()\n    {\n        return '<?php $__env->endSlot(); ?>';\n    }\n\n    /**\n     * Compile the component-first statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileComponentFirst($expression)\n    {\n        return \"<?php \\$__env->startComponentFirst{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the end-component-first statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndComponentFirst()\n    {\n        return $this->compileEndComponent();\n    }\n\n    /**\n     * Compile the prop statement into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileProps($expression)\n    {\n        return \"<?php \\$attributes ??= new \\\\Illuminate\\\\View\\\\ComponentAttributeBag;\n\n\\$__newAttributes = [];\n\\$__propNames = \\Illuminate\\View\\ComponentAttributeBag::extractPropNames({$expression});\n\nforeach (\\$attributes->all() as \\$__key => \\$__value) {\n    if (in_array(\\$__key, \\$__propNames)) {\n        \\$\\$__key = \\$\\$__key ?? \\$__value;\n    } else {\n        \\$__newAttributes[\\$__key] = \\$__value;\n    }\n}\n\n\\$attributes = new \\Illuminate\\View\\ComponentAttributeBag(\\$__newAttributes);\n\nunset(\\$__propNames);\nunset(\\$__newAttributes);\n\nforeach (array_filter({$expression}, 'is_string', ARRAY_FILTER_USE_KEY) as \\$__key => \\$__value) {\n    \\$\\$__key = \\$\\$__key ?? \\$__value;\n}\n\n\\$__defined_vars = get_defined_vars();\n\nforeach (\\$attributes->all() as \\$__key => \\$__value) {\n    if (array_key_exists(\\$__key, \\$__defined_vars)) unset(\\$\\$__key);\n}\n\nunset(\\$__defined_vars, \\$__key, \\$__value); ?>\";\n    }\n\n    /**\n     * Compile the aware statement into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileAware($expression)\n    {\n        return \"<?php foreach ({$expression} as \\$__key => \\$__value) {\n    \\$__consumeVariable = is_string(\\$__key) ? \\$__key : \\$__value;\n    \\$\\$__consumeVariable = is_string(\\$__key) ? \\$__env->getConsumableComponentData(\\$__key, \\$__value) : \\$__env->getConsumableComponentData(\\$__value);\n} ?>\";\n    }\n\n    /**\n     * Sanitize the given component attribute value.\n     *\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public static function sanitizeComponentAttribute($value)\n    {\n        if ($value instanceof CanBeEscapedWhenCastToString) {\n            return $value->escapeWhenCastingToString();\n        }\n\n        return is_string($value) ||\n            (is_object($value) && ! $value instanceof ComponentAttributeBag && method_exists($value, '__toString'))\n                ? e($value)\n                : $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait CompilesConditionals\n{\n    /**\n     * Identifier for the first case in the switch statement.\n     *\n     * @var bool\n     */\n    protected $firstCaseInSwitch = true;\n\n    /**\n     * Compile the if-auth statements into valid PHP.\n     *\n     * @param  string|null  $guard\n     * @return string\n     */\n    protected function compileAuth($guard = null)\n    {\n        $guard = is_null($guard) ? '()' : $guard;\n\n        return \"<?php if(auth()->guard{$guard}->check()): ?>\";\n    }\n\n    /**\n     * Compile the else-auth statements into valid PHP.\n     *\n     * @param  string|null  $guard\n     * @return string\n     */\n    protected function compileElseAuth($guard = null)\n    {\n        $guard = is_null($guard) ? '()' : $guard;\n\n        return \"<?php elseif(auth()->guard{$guard}->check()): ?>\";\n    }\n\n    /**\n     * Compile the end-auth statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndAuth()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the env statements into valid PHP.\n     *\n     * @param  string  $environments\n     * @return string\n     */\n    protected function compileEnv($environments)\n    {\n        return \"<?php if(app()->environment{$environments}): ?>\";\n    }\n\n    /**\n     * Compile the end-env statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndEnv()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the production statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileProduction()\n    {\n        return \"<?php if(app()->environment('production')): ?>\";\n    }\n\n    /**\n     * Compile the end-production statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndProduction()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the if-guest statements into valid PHP.\n     *\n     * @param  string|null  $guard\n     * @return string\n     */\n    protected function compileGuest($guard = null)\n    {\n        $guard = is_null($guard) ? '()' : $guard;\n\n        return \"<?php if(auth()->guard{$guard}->guest()): ?>\";\n    }\n\n    /**\n     * Compile the else-guest statements into valid PHP.\n     *\n     * @param  string|null  $guard\n     * @return string\n     */\n    protected function compileElseGuest($guard = null)\n    {\n        $guard = is_null($guard) ? '()' : $guard;\n\n        return \"<?php elseif(auth()->guard{$guard}->guest()): ?>\";\n    }\n\n    /**\n     * Compile the end-guest statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndGuest()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the has-section statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileHasSection($expression)\n    {\n        return \"<?php if (! empty(trim(\\$__env->yieldContent{$expression}))): ?>\";\n    }\n\n    /**\n     * Compile the has-stack statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileHasStack($expression)\n    {\n        return \"<?php if (! \\$__env->isStackEmpty{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the section-missing statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileSectionMissing($expression)\n    {\n        return \"<?php if (empty(trim(\\$__env->yieldContent{$expression}))): ?>\";\n    }\n\n    /**\n     * Compile the if statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIf($expression)\n    {\n        return \"<?php if{$expression}: ?>\";\n    }\n\n    /**\n     * Compile the unless statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileUnless($expression)\n    {\n        return \"<?php if (! {$expression}): ?>\";\n    }\n\n    /**\n     * Compile the else-if statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElseif($expression)\n    {\n        return \"<?php elseif{$expression}: ?>\";\n    }\n\n    /**\n     * Compile the else statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileElse()\n    {\n        return '<?php else: ?>';\n    }\n\n    /**\n     * Compile the end-if statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndif()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the end-unless statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndunless()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the if-isset statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIsset($expression)\n    {\n        return \"<?php if(isset{$expression}): ?>\";\n    }\n\n    /**\n     * Compile the end-isset statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndIsset()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the switch statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileSwitch($expression)\n    {\n        $this->firstCaseInSwitch = true;\n\n        return \"<?php switch{$expression}:\";\n    }\n\n    /**\n     * Compile the case statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileCase($expression)\n    {\n        if ($this->firstCaseInSwitch) {\n            $this->firstCaseInSwitch = false;\n\n            return \"case {$expression}: ?>\";\n        }\n\n        return \"<?php case {$expression}: ?>\";\n    }\n\n    /**\n     * Compile the default statements in switch case into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileDefault()\n    {\n        return '<?php default: ?>';\n    }\n\n    /**\n     * Compile the end switch statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndSwitch()\n    {\n        return '<?php endswitch; ?>';\n    }\n\n    /**\n     * Compile a once block into valid PHP.\n     *\n     * @param  string|null  $id\n     * @return string\n     */\n    protected function compileOnce($id = null)\n    {\n        $id = $id ? $this->stripParentheses($id) : \"'\".(string) Str::uuid().\"'\";\n\n        return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.'); ?>';\n    }\n\n    /**\n     * Compile an end-once block into valid PHP.\n     *\n     * @return string\n     */\n    public function compileEndOnce()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile a boolean value into a raw true / false value for embedding into HTML attributes or JavaScript.\n     *\n     * @param  bool  $condition\n     * @return string\n     */\n    protected function compileBool($condition)\n    {\n        return \"<?php echo ($condition ? 'true' : 'false'); ?>\";\n    }\n\n    /**\n     * Compile a checked block into valid PHP.\n     *\n     * @param  string  $condition\n     * @return string\n     */\n    protected function compileChecked($condition)\n    {\n        return \"<?php if{$condition}: echo 'checked'; endif; ?>\";\n    }\n\n    /**\n     * Compile a disabled block into valid PHP.\n     *\n     * @param  string  $condition\n     * @return string\n     */\n    protected function compileDisabled($condition)\n    {\n        return \"<?php if{$condition}: echo 'disabled'; endif; ?>\";\n    }\n\n    /**\n     * Compile a required block into valid PHP.\n     *\n     * @param  string  $condition\n     * @return string\n     */\n    protected function compileRequired($condition)\n    {\n        return \"<?php if{$condition}: echo 'required'; endif; ?>\";\n    }\n\n    /**\n     * Compile a readonly block into valid PHP.\n     *\n     * @param  string  $condition\n     * @return string\n     */\n    protected function compileReadonly($condition)\n    {\n        return \"<?php if{$condition}: echo 'readonly'; endif; ?>\";\n    }\n\n    /**\n     * Compile a selected block into valid PHP.\n     *\n     * @param  string  $condition\n     * @return string\n     */\n    protected function compileSelected($condition)\n    {\n        return \"<?php if{$condition}: echo 'selected'; endif; ?>\";\n    }\n\n    /**\n     * Compile the push statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePushIf($expression)\n    {\n        $parts = explode(',', $this->stripParentheses($expression));\n\n        if (count($parts) > 2) {\n            $last = array_pop($parts);\n\n            $parts = [\n                implode(',', $parts),\n                trim($last),\n            ];\n        }\n\n        return \"<?php if({$parts[0]}): \\$__env->startPush({$parts[1]}); ?>\";\n    }\n\n    /**\n     * Compile the else-if push statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElsePushIf($expression)\n    {\n        $parts = explode(',', $this->stripParentheses($expression), 2);\n\n        return \"<?php \\$__env->stopPush(); elseif({$parts[0]}): \\$__env->startPush({$parts[1]}); ?>\";\n    }\n\n    /**\n     * Compile the else push statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileElsePush($expression)\n    {\n        return \"<?php \\$__env->stopPush(); else: \\$__env->startPush{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the end-push statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndPushIf()\n    {\n        return '<?php $__env->stopPush(); endif; ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesContexts.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesContexts\n{\n    /**\n     * Compile the context statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileContext($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return '<?php $__contextArgs = ['.$expression.'];\nif (context()->has($__contextArgs[0])) :\nif (isset($value)) { $__contextPrevious[] = $value; }\n$value = context()->get($__contextArgs[0]); ?>';\n    }\n\n    /**\n     * Compile the endcontext statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileEndcontext($expression)\n    {\n        return '<?php unset($value);\nif (isset($__contextPrevious) && !empty($__contextPrevious)) { $value = array_pop($__contextPrevious); }\nif (isset($__contextPrevious) && empty($__contextPrevious)) { unset($__contextPrevious); }\nendif;\nunset($__contextArgs); ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesEchos.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Closure;\nuse Illuminate\\Support\\Stringable;\n\ntrait CompilesEchos\n{\n    /**\n     * Custom rendering callbacks for stringable objects.\n     *\n     * @var array\n     */\n    protected $echoHandlers = [];\n\n    /**\n     * Add a handler to be executed before echoing a given class.\n     *\n     * @param  string|callable  $class\n     * @param  callable|null  $handler\n     * @return void\n     */\n    public function stringable($class, $handler = null)\n    {\n        if ($class instanceof Closure) {\n            [$class, $handler] = [$this->firstClosureParameterType($class), $class];\n        }\n\n        $this->echoHandlers[$class] = $handler;\n    }\n\n    /**\n     * Compile Blade echos into valid PHP.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function compileEchos($value)\n    {\n        foreach ($this->getEchoMethods() as $method) {\n            $value = $this->$method($value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Get the echo methods in the proper order for compilation.\n     *\n     * @return array\n     */\n    protected function getEchoMethods()\n    {\n        return [\n            'compileRawEchos',\n            'compileEscapedEchos',\n            'compileRegularEchos',\n        ];\n    }\n\n    /**\n     * Compile the \"raw\" echo statements.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileRawEchos($value)\n    {\n        $pattern = sprintf('/(@)?%s\\s*(.+?)\\s*%s(\\r?\\n)?/s', $this->rawTags[0], $this->rawTags[1]);\n\n        $callback = function ($matches) {\n            $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];\n\n            return $matches[1]\n                ? substr($matches[0], 1)\n                : \"<?php echo {$this->wrapInEchoHandler($matches[2])}; ?>{$whitespace}\";\n        };\n\n        return preg_replace_callback($pattern, $callback, $value);\n    }\n\n    /**\n     * Compile the \"regular\" echo statements.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileRegularEchos($value)\n    {\n        $pattern = sprintf('/(@)?%s\\s*(.+?)\\s*%s(\\r?\\n)?/s', $this->contentTags[0], $this->contentTags[1]);\n\n        $callback = function ($matches) {\n            $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];\n\n            $wrapped = sprintf($this->echoFormat, $this->wrapInEchoHandler($matches[2]));\n\n            return $matches[1] ? substr($matches[0], 1) : \"<?php echo {$wrapped}; ?>{$whitespace}\";\n        };\n\n        return preg_replace_callback($pattern, $callback, $value);\n    }\n\n    /**\n     * Compile the escaped echo statements.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function compileEscapedEchos($value)\n    {\n        $pattern = sprintf('/(@)?%s\\s*(.+?)\\s*%s(\\r?\\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);\n\n        $callback = function ($matches) {\n            $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];\n\n            return $matches[1]\n                ? $matches[0]\n                : \"<?php echo e({$this->wrapInEchoHandler($matches[2])}); ?>{$whitespace}\";\n        };\n\n        return preg_replace_callback($pattern, $callback, $value);\n    }\n\n    /**\n     * Add an instance of the blade echo handler to the start of the compiled string.\n     *\n     * @param  string  $result\n     * @return string\n     */\n    protected function addBladeCompilerVariable($result)\n    {\n        return \"<?php \\$__bladeCompiler = app('blade.compiler'); ?>\".$result;\n    }\n\n    /**\n     * Wrap the echoable value in an echo handler if applicable.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    protected function wrapInEchoHandler($value)\n    {\n        $value = (new Stringable($value))\n            ->trim()\n            ->when(str_ends_with($value, ';'), function ($str) {\n                return $str->beforeLast(';');\n            });\n\n        return empty($this->echoHandlers) ? $value : '$__bladeCompiler->applyEchoHandler('.$value.')';\n    }\n\n    /**\n     * Apply the echo handler for the value if it exists.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function applyEchoHandler($value)\n    {\n        if (is_object($value) && isset($this->echoHandlers[get_class($value)])) {\n            return call_user_func($this->echoHandlers[get_class($value)], $value);\n        }\n\n        if (is_iterable($value) && isset($this->echoHandlers['iterable'])) {\n            return call_user_func($this->echoHandlers['iterable'], $value);\n        }\n\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesErrors.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesErrors\n{\n    /**\n     * Compile the error statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileError($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return '<?php $__errorArgs = ['.$expression.'];\n$__bag = $errors->getBag($__errorArgs[1] ?? \\'default\\');\nif ($__bag->has($__errorArgs[0])) :\nif (isset($message)) { $__messageOriginal = $message; }\n$message = $__bag->first($__errorArgs[0]); ?>';\n    }\n\n    /**\n     * Compile the enderror statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileEnderror($expression)\n    {\n        return '<?php unset($message);\nif (isset($__messageOriginal)) { $message = $__messageOriginal; }\nendif;\nunset($__errorArgs, $__bag); ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesFragments.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesFragments\n{\n    /**\n     * The last compiled fragment.\n     *\n     * @var string\n     */\n    protected $lastFragment;\n\n    /**\n     * Compile the fragment statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileFragment($expression)\n    {\n        $this->lastFragment = trim($expression, \"()'\\\" \");\n\n        return \"<?php \\$__env->startFragment{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the end-fragment statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndfragment()\n    {\n        return '<?php echo $__env->stopFragment(); ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Foundation\\Vite;\n\ntrait CompilesHelpers\n{\n    /**\n     * Compile the CSRF statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileCsrf()\n    {\n        return '<?php echo csrf_field(); ?>';\n    }\n\n    /**\n     * Compile the \"dd\" statements into valid PHP.\n     *\n     * @param  string  $arguments\n     * @return string\n     */\n    protected function compileDd($arguments)\n    {\n        return \"<?php dd{$arguments}; ?>\";\n    }\n\n    /**\n     * Compile the \"dump\" statements into valid PHP.\n     *\n     * @param  string  $arguments\n     * @return string\n     */\n    protected function compileDump($arguments)\n    {\n        return \"<?php dump{$arguments}; ?>\";\n    }\n\n    /**\n     * Compile the method statements into valid PHP.\n     *\n     * @param  string  $method\n     * @return string\n     */\n    protected function compileMethod($method)\n    {\n        return \"<?php echo method_field{$method}; ?>\";\n    }\n\n    /**\n     * Compile the \"vite\" statements into valid PHP.\n     *\n     * @param  string|null  $arguments\n     * @return string\n     */\n    protected function compileVite($arguments)\n    {\n        $arguments ??= '()';\n\n        $class = Vite::class;\n\n        return \"<?php echo app('$class'){$arguments}; ?>\";\n    }\n\n    /**\n     * Compile the \"viteReactRefresh\" statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileViteReactRefresh()\n    {\n        $class = Vite::class;\n\n        return \"<?php echo app('$class')->reactRefresh(); ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesIncludes\n{\n    /**\n     * Compile the each statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileEach($expression)\n    {\n        return \"<?php echo \\$__env->renderEach{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the include statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileInclude($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php echo \\$__env->make({$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n    }\n\n    /**\n     * Compile the include-if statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIncludeIf($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php if (\\$__env->exists({$expression})) echo \\$__env->make({$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n    }\n\n    /**\n     * Compile the include-when statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIncludeWhen($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php echo \\$__env->renderWhen($expression, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1])); ?>\";\n    }\n\n    /**\n     * Compile the include-unless statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIncludeUnless($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php echo \\$__env->renderUnless($expression, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1])); ?>\";\n    }\n\n    /**\n     * Compile the include-first statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIncludeFirst($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php echo \\$__env->first({$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n    }\n\n    /**\n     * Compile the include-isolated statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileIncludeIsolated($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return \"<?php echo \\$__env->make({$expression})->render(); ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesInjections.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesInjections\n{\n    /**\n     * Compile the inject statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileInject($expression)\n    {\n        $segments = explode(',', preg_replace(\"/[\\(\\)]/\", '', $expression));\n\n        $variable = trim($segments[0], \" '\\\"\");\n\n        $service = trim($segments[1]);\n\n        return \"<?php \\${$variable} = app({$service}); ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesJs.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Support\\Js;\n\ntrait CompilesJs\n{\n    /**\n     * Compile the \"@js\" directive into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileJs(string $expression)\n    {\n        return sprintf(\n            \"<?php echo \\%s::from(%s)->toHtml() ?>\",\n            Js::class, $this->stripParentheses($expression)\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesJson.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesJson\n{\n    /**\n     * The default JSON encoding options.\n     *\n     * @var int\n     */\n    private $encodingOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;\n\n    /**\n     * Compile the JSON statement into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileJson($expression)\n    {\n        $parts = explode(',', $this->stripParentheses($expression));\n\n        $options = isset($parts[1]) ? trim($parts[1]) : $this->encodingOptions;\n\n        $depth = isset($parts[2]) ? trim($parts[2]) : 512;\n\n        return \"<?php echo json_encode($parts[0], $options, $depth) ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesLayouts.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesLayouts\n{\n    /**\n     * The name of the last section that was started.\n     *\n     * @var string\n     */\n    protected $lastSection;\n\n    /**\n     * Compile the extends statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileExtends($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        $echo = \"<?php echo \\$__env->make({$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n\n        $this->footer[] = $echo;\n\n        return '';\n    }\n\n    /**\n     * Compile the extends-first statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileExtendsFirst($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        $echo = \"<?php echo \\$__env->first({$expression}, array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>\";\n\n        $this->footer[] = $echo;\n\n        return '';\n    }\n\n    /**\n     * Compile the section statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileSection($expression)\n    {\n        $this->lastSection = trim($expression, \"()'\\\" \");\n\n        return \"<?php \\$__env->startSection{$expression}; ?>\";\n    }\n\n    /**\n     * Replace the @parent directive to a placeholder.\n     *\n     * @return string\n     */\n    protected function compileParent()\n    {\n        $escapedLastSection = strtr($this->lastSection, ['\\\\' => '\\\\\\\\', \"'\" => \"\\\\'\"]);\n\n        return \"<?php echo \\Illuminate\\View\\Factory::parentPlaceholder('{$escapedLastSection}'); ?>\";\n    }\n\n    /**\n     * Compile the yield statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileYield($expression)\n    {\n        return \"<?php echo \\$__env->yieldContent{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the show statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileShow()\n    {\n        return '<?php echo $__env->yieldSection(); ?>';\n    }\n\n    /**\n     * Compile the append statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileAppend()\n    {\n        return '<?php $__env->appendSection(); ?>';\n    }\n\n    /**\n     * Compile the overwrite statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileOverwrite()\n    {\n        return '<?php $__env->stopSection(true); ?>';\n    }\n\n    /**\n     * Compile the stop statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileStop()\n    {\n        return '<?php $__env->stopSection(); ?>';\n    }\n\n    /**\n     * Compile the end-section statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndsection()\n    {\n        return '<?php $__env->stopSection(); ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesLoops.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Contracts\\View\\ViewCompilationException;\n\ntrait CompilesLoops\n{\n    /**\n     * Counter to keep track of nested forelse statements.\n     *\n     * @var int\n     */\n    protected $forElseCounter = 0;\n\n    /**\n     * Compile the for-else statements into valid PHP.\n     *\n     * @param  string|null  $expression\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\View\\ViewCompilationException\n     */\n    protected function compileForelse($expression)\n    {\n        $empty = '$__empty_'.++$this->forElseCounter;\n\n        preg_match('/\\( *(.+) +as +(.+)\\)$/is', $expression ?? '', $matches);\n\n        if (count($matches) === 0) {\n            throw new ViewCompilationException('Malformed @forelse statement.');\n        }\n\n        $iteratee = trim($matches[1]);\n\n        $iteration = trim($matches[2]);\n\n        $initLoop = \"\\$__currentLoopData = {$iteratee}; \\$__env->addLoop(\\$__currentLoopData);\";\n\n        $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';\n\n        return \"<?php {$empty} = true; {$initLoop} foreach(\\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>\";\n    }\n\n    /**\n     * Compile the for-else-empty and empty statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileEmpty($expression)\n    {\n        if ($expression) {\n            return \"<?php if(empty{$expression}): ?>\";\n        }\n\n        $empty = '$__empty_'.$this->forElseCounter--;\n\n        return \"<?php endforeach; \\$__env->popLoop(); \\$loop = \\$__env->getLastLoop(); if ({$empty}): ?>\";\n    }\n\n    /**\n     * Compile the end-for-else statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndforelse()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the end-empty statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndEmpty()\n    {\n        return '<?php endif; ?>';\n    }\n\n    /**\n     * Compile the for statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileFor($expression)\n    {\n        return \"<?php for{$expression}: ?>\";\n    }\n\n    /**\n     * Compile the for-each statements into valid PHP.\n     *\n     * @param  string|null  $expression\n     * @return string\n     *\n     * @throws \\Illuminate\\Contracts\\View\\ViewCompilationException\n     */\n    protected function compileForeach($expression)\n    {\n        preg_match('/\\( *(.+) +as +(.*)\\)$/is', $expression ?? '', $matches);\n\n        if (count($matches) === 0) {\n            throw new ViewCompilationException('Malformed @foreach statement.');\n        }\n\n        $iteratee = trim($matches[1]);\n\n        $iteration = trim($matches[2]);\n\n        $initLoop = \"\\$__currentLoopData = {$iteratee}; \\$__env->addLoop(\\$__currentLoopData);\";\n\n        $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';\n\n        return \"<?php {$initLoop} foreach(\\$__currentLoopData as {$iteration}): {$iterateLoop} ?>\";\n    }\n\n    /**\n     * Compile the break statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileBreak($expression)\n    {\n        if ($expression) {\n            preg_match('/\\(\\s*(-?\\d+)\\s*\\)$/', $expression, $matches);\n\n            return $matches ? '<?php break '.max(1, $matches[1]).'; ?>' : \"<?php if{$expression} break; ?>\";\n        }\n\n        return '<?php break; ?>';\n    }\n\n    /**\n     * Compile the continue statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileContinue($expression)\n    {\n        if ($expression) {\n            preg_match('/\\(\\s*(-?\\d+)\\s*\\)$/', $expression, $matches);\n\n            return $matches ? '<?php continue '.max(1, $matches[1]).'; ?>' : \"<?php if{$expression} continue; ?>\";\n        }\n\n        return '<?php continue; ?>';\n    }\n\n    /**\n     * Compile the end-for statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndfor()\n    {\n        return '<?php endfor; ?>';\n    }\n\n    /**\n     * Compile the end-for-each statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndforeach()\n    {\n        return '<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>';\n    }\n\n    /**\n     * Compile the while statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileWhile($expression)\n    {\n        return \"<?php while{$expression}: ?>\";\n    }\n\n    /**\n     * Compile the end-while statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndwhile()\n    {\n        return '<?php endwhile; ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesRawPhp.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesRawPhp\n{\n    /**\n     * Compile the raw PHP statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePhp($expression)\n    {\n        if ($expression) {\n            return \"<?php {$expression}; ?>\";\n        }\n\n        return '@php';\n    }\n\n    /**\n     * Compile the unset statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileUnset($expression)\n    {\n        return \"<?php unset{$expression}; ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesSessions.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesSessions\n{\n    /**\n     * Compile the session statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileSession($expression)\n    {\n        $expression = $this->stripParentheses($expression);\n\n        return '<?php $__sessionArgs = ['.$expression.'];\nif (session()->has($__sessionArgs[0])) :\nif (isset($value)) { $__sessionPrevious[] = $value; }\n$value = session()->get($__sessionArgs[0]); ?>';\n    }\n\n    /**\n     * Compile the endsession statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileEndsession($expression)\n    {\n        return '<?php unset($value);\nif (isset($__sessionPrevious) && !empty($__sessionPrevious)) { $value = array_pop($__sessionPrevious); }\nif (isset($__sessionPrevious) && empty($__sessionPrevious)) { unset($__sessionPrevious); }\nendif;\nunset($__sessionArgs); ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesStacks.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\nuse Illuminate\\Support\\Str;\n\ntrait CompilesStacks\n{\n    /**\n     * Compile the stack statements into the content.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileStack($expression)\n    {\n        return \"<?php echo \\$__env->yieldPushContent{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the push statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePush($expression)\n    {\n        return \"<?php \\$__env->startPush{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the push-once statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePushOnce($expression)\n    {\n        $parts = explode(',', $this->stripParentheses($expression), 2);\n\n        [$stack, $id] = [$parts[0], $parts[1] ?? ''];\n\n        $id = trim($id) ?: \"'\".(string) Str::uuid().\"'\";\n\n        return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.');\n$__env->startPush('.$stack.'); ?>';\n    }\n\n    /**\n     * Compile the end-push statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndpush()\n    {\n        return '<?php $__env->stopPush(); ?>';\n    }\n\n    /**\n     * Compile the end-push-once statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndpushOnce()\n    {\n        return '<?php $__env->stopPush(); endif; ?>';\n    }\n\n    /**\n     * Compile the prepend statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePrepend($expression)\n    {\n        return \"<?php \\$__env->startPrepend{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the prepend-once statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compilePrependOnce($expression)\n    {\n        $parts = explode(',', $this->stripParentheses($expression), 2);\n\n        [$stack, $id] = [$parts[0], $parts[1] ?? ''];\n\n        $id = trim($id) ?: \"'\".(string) Str::uuid().\"'\";\n\n        return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.');\n$__env->startPrepend('.$stack.'); ?>';\n    }\n\n    /**\n     * Compile the end-prepend statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndprepend()\n    {\n        return '<?php $__env->stopPrepend(); ?>';\n    }\n\n    /**\n     * Compile the end-prepend-once statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndprependOnce()\n    {\n        return '<?php $__env->stopPrepend(); endif; ?>';\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesStyles.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesStyles\n{\n    /**\n     * Compile the conditional style statement into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileStyle($expression)\n    {\n        $expression = is_null($expression) ? '([])' : $expression;\n\n        return \"style=\\\"<?php echo \\Illuminate\\Support\\Arr::toCssStyles{$expression} ?>\\\"\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesTranslations.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesTranslations\n{\n    /**\n     * Compile the lang statements into valid PHP.\n     *\n     * @param  string|null  $expression\n     * @return string\n     */\n    protected function compileLang($expression)\n    {\n        if (is_null($expression)) {\n            return '<?php $__env->startTranslation(); ?>';\n        } elseif ($expression[1] === '[') {\n            return \"<?php \\$__env->startTranslation{$expression}; ?>\";\n        }\n\n        return \"<?php echo app('translator')->get{$expression}; ?>\";\n    }\n\n    /**\n     * Compile the end-lang statements into valid PHP.\n     *\n     * @return string\n     */\n    protected function compileEndlang()\n    {\n        return '<?php echo $__env->renderTranslation(); ?>';\n    }\n\n    /**\n     * Compile the choice statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileChoice($expression)\n    {\n        return \"<?php echo app('translator')->choice{$expression}; ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Compilers\\Concerns;\n\ntrait CompilesUseStatements\n{\n    /**\n     * Compile the use statements into valid PHP.\n     *\n     * @param  string  $expression\n     * @return string\n     */\n    protected function compileUse($expression)\n    {\n        $expression = trim(preg_replace('/[()]/', '', $expression), \" '\\\"\");\n\n        // Isolate alias...\n        if (str_contains($expression, '{')) {\n            $pathWithOptionalModifier = $expression;\n            $aliasWithLeadingSpace = '';\n        } else {\n            $segments = explode(',', $expression);\n            $pathWithOptionalModifier = trim($segments[0], \" '\\\"\");\n\n            $aliasWithLeadingSpace = isset($segments[1])\n                ? ' as '.trim($segments[1], \" '\\\"\")\n                : '';\n        }\n\n        // Split modifier and path...\n        if (str_starts_with($pathWithOptionalModifier, 'function ')) {\n            $modifierWithTrailingSpace = 'function ';\n            $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier;\n        } elseif (str_starts_with($pathWithOptionalModifier, 'const ')) {\n            $modifierWithTrailingSpace = 'const ';\n            $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier;\n        } else {\n            $modifierWithTrailingSpace = '';\n            $path = $pathWithOptionalModifier;\n        }\n\n        $path = ltrim($path, '\\\\');\n\n        return \"<?php use {$modifierWithTrailingSpace}\\\\{$path}{$aliasWithLeadingSpace}; ?>\";\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Component.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Closure;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\View\\View as ViewContract;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Collection;\nuse ReflectionClass;\nuse ReflectionMethod;\nuse ReflectionProperty;\n\nabstract class Component\n{\n    /**\n     * The properties / methods that should not be exposed to the component.\n     *\n     * @var array\n     */\n    protected $except = [];\n\n    /**\n     * The component alias name.\n     *\n     * @var string\n     */\n    public $componentName;\n\n    /**\n     * The component attributes.\n     *\n     * @var \\Illuminate\\View\\ComponentAttributeBag\n     */\n    public $attributes;\n\n    /**\n     * The view factory instance, if any.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory|null\n     */\n    protected static $factory;\n\n    /**\n     * The component resolver callback.\n     *\n     * @var (\\Closure(string, array): Component)|null\n     */\n    protected static $componentsResolver;\n\n    /**\n     * The cache of blade view names, keyed by contents.\n     *\n     * @var array<string, string>\n     */\n    protected static $bladeViewCache = [];\n\n    /**\n     * The cache of public property names, keyed by class.\n     *\n     * @var array\n     */\n    protected static $propertyCache = [];\n\n    /**\n     * The cache of public method names, keyed by class.\n     *\n     * @var array\n     */\n    protected static $methodCache = [];\n\n    /**\n     * The cache of constructor parameters, keyed by class.\n     *\n     * @var array<class-string, array<int, string>>\n     */\n    protected static $constructorParametersCache = [];\n\n    /**\n     * The cache of ignored parameter names.\n     *\n     * @var array\n     */\n    protected static $ignoredParameterNames = [];\n\n    /**\n     * Get the view / view contents that represent the component.\n     *\n     * @return \\Illuminate\\Contracts\\View\\View|\\Illuminate\\Contracts\\Support\\Htmlable|\\Closure|string\n     */\n    abstract public function render();\n\n    /**\n     * Resolve the component instance with the given data.\n     *\n     * @param  array  $data\n     * @return static\n     */\n    public static function resolve($data)\n    {\n        if (static::$componentsResolver) {\n            return call_user_func(static::$componentsResolver, static::class, $data);\n        }\n\n        $parameters = static::extractConstructorParameters();\n\n        $dataKeys = array_keys($data);\n\n        if (empty(array_diff($parameters, $dataKeys))) {\n            return new static(...array_intersect_key($data, array_flip($parameters)));\n        }\n\n        return Container::getInstance()->make(static::class, $data);\n    }\n\n    /**\n     * Extract the constructor parameters for the component.\n     *\n     * @return array\n     */\n    protected static function extractConstructorParameters()\n    {\n        if (! isset(static::$constructorParametersCache[static::class])) {\n            $class = new ReflectionClass(static::class);\n\n            $constructor = $class->getConstructor();\n\n            static::$constructorParametersCache[static::class] = $constructor\n                ? (new Collection($constructor->getParameters()))->map->getName()->all()\n                : [];\n        }\n\n        return static::$constructorParametersCache[static::class];\n    }\n\n    /**\n     * Resolve the Blade view or view file that should be used when rendering the component.\n     *\n     * @return \\Illuminate\\Contracts\\View\\View|\\Illuminate\\Contracts\\Support\\Htmlable|\\Closure|string\n     */\n    public function resolveView()\n    {\n        $view = $this->render();\n\n        if ($view instanceof ViewContract) {\n            return $view;\n        }\n\n        if ($view instanceof Htmlable) {\n            return $view;\n        }\n\n        $resolver = function ($view) {\n            if ($view instanceof ViewContract) {\n                return $view;\n            }\n\n            return $this->extractBladeViewFromString($view);\n        };\n\n        return $view instanceof Closure ? function (array $data = []) use ($view, $resolver) {\n            return $resolver($view($data));\n        }\n        : $resolver($view);\n    }\n\n    /**\n     * Create a Blade view with the raw component string content.\n     *\n     * @param  string  $contents\n     * @return string\n     */\n    protected function extractBladeViewFromString($contents)\n    {\n        $key = sprintf('%s::%s', static::class, $contents);\n\n        if (isset(static::$bladeViewCache[$key])) {\n            return static::$bladeViewCache[$key];\n        }\n\n        if ($this->factory()->exists($contents)) {\n            return static::$bladeViewCache[$key] = $contents;\n        }\n\n        return static::$bladeViewCache[$key] = $this->createBladeViewFromString($this->factory(), $contents);\n    }\n\n    /**\n     * Create a Blade view with the raw component string content.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $factory\n     * @param  string  $contents\n     * @return string\n     */\n    protected function createBladeViewFromString($factory, $contents)\n    {\n        $factory->addNamespace(\n            '__components',\n            $directory = Container::getInstance()['config']->get('view.compiled')\n        );\n\n        $viewFile = $directory.'/'.hash('xxh128', $contents).'.blade.php';\n\n        if (! is_file($viewFile) || filesize($viewFile) === 0) {\n            if (! is_dir($directory)) {\n                mkdir($directory, 0755, true);\n            }\n\n            (new Filesystem)->replace($viewFile, $contents);\n        }\n\n        return '__components::'.basename($viewFile, '.blade.php');\n    }\n\n    /**\n     * Get the data that should be supplied to the view.\n     *\n     * @author Freek Van der Herten\n     * @author Brent Roose\n     *\n     * @return array\n     */\n    public function data()\n    {\n        $this->attributes = $this->attributes ?: $this->newAttributeBag();\n\n        return array_merge($this->extractPublicProperties(), $this->extractPublicMethods());\n    }\n\n    /**\n     * Extract the public properties for the component.\n     *\n     * @return array\n     */\n    protected function extractPublicProperties()\n    {\n        $class = get_class($this);\n\n        if (! isset(static::$propertyCache[$class])) {\n            $reflection = new ReflectionClass($this);\n\n            static::$propertyCache[$class] = (new Collection($reflection->getProperties(ReflectionProperty::IS_PUBLIC)))\n                ->reject(fn (ReflectionProperty $property) => $property->isStatic())\n                ->reject(fn (ReflectionProperty $property) => $this->shouldIgnore($property->getName()))\n                ->map(fn (ReflectionProperty $property) => $property->getName())\n                ->all();\n        }\n\n        $values = [];\n\n        foreach (static::$propertyCache[$class] as $property) {\n            $values[$property] = $this->{$property};\n        }\n\n        return $values;\n    }\n\n    /**\n     * Extract the public methods for the component.\n     *\n     * @return array\n     */\n    protected function extractPublicMethods()\n    {\n        $class = get_class($this);\n\n        if (! isset(static::$methodCache[$class])) {\n            $reflection = new ReflectionClass($this);\n\n            static::$methodCache[$class] = (new Collection($reflection->getMethods(ReflectionMethod::IS_PUBLIC)))\n                ->reject(fn (ReflectionMethod $method) => $this->shouldIgnore($method->getName()))\n                ->map(fn (ReflectionMethod $method) => $method->getName());\n        }\n\n        $values = [];\n\n        foreach (static::$methodCache[$class] as $method) {\n            $values[$method] = $this->createVariableFromMethod(new ReflectionMethod($this, $method));\n        }\n\n        return $values;\n    }\n\n    /**\n     * Create a callable variable from the given method.\n     *\n     * @param  \\ReflectionMethod  $method\n     * @return mixed\n     */\n    protected function createVariableFromMethod(ReflectionMethod $method)\n    {\n        return $method->getNumberOfParameters() === 0\n            ? $this->createInvokableVariable($method->getName())\n            : Closure::fromCallable([$this, $method->getName()]);\n    }\n\n    /**\n     * Create an invokable, toStringable variable for the given component method.\n     *\n     * @param  string  $method\n     * @return \\Illuminate\\View\\InvokableComponentVariable\n     */\n    protected function createInvokableVariable(string $method)\n    {\n        return new InvokableComponentVariable(function () use ($method) {\n            return $this->{$method}();\n        });\n    }\n\n    /**\n     * Determine if the given property / method should be ignored.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    protected function shouldIgnore($name)\n    {\n        return str_starts_with($name, '__') ||\n               in_array($name, $this->ignoredMethods());\n    }\n\n    /**\n     * Get the methods that should be ignored.\n     *\n     * @return array\n     */\n    protected function ignoredMethods()\n    {\n        return array_merge([\n            'data',\n            'render',\n            'resolve',\n            'resolveView',\n            'shouldRender',\n            'view',\n            'withName',\n            'withAttributes',\n            'flushCache',\n            'forgetFactory',\n            'forgetComponentsResolver',\n            'resolveComponentsUsing',\n        ], $this->except);\n    }\n\n    /**\n     * Set the component alias name.\n     *\n     * @param  string  $name\n     * @return $this\n     */\n    public function withName($name)\n    {\n        $this->componentName = $name;\n\n        return $this;\n    }\n\n    /**\n     * Set the extra attributes that the component should make available.\n     *\n     * @param  array  $attributes\n     * @return $this\n     */\n    public function withAttributes(array $attributes)\n    {\n        $this->attributes = $this->attributes ?: $this->newAttributeBag();\n\n        $this->attributes->setAttributes($attributes);\n\n        return $this;\n    }\n\n    /**\n     * Get a new attribute bag instance.\n     *\n     * @param  array  $attributes\n     * @return \\Illuminate\\View\\ComponentAttributeBag\n     */\n    protected function newAttributeBag(array $attributes = [])\n    {\n        return new ComponentAttributeBag($attributes);\n    }\n\n    /**\n     * Determine if the component should be rendered.\n     *\n     * @return bool\n     */\n    public function shouldRender()\n    {\n        return true;\n    }\n\n    /**\n     * Get the evaluated view contents for the given view.\n     *\n     * @param  string|null  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    public function view($view, $data = [], $mergeData = [])\n    {\n        return $this->factory()->make($view, $data, $mergeData);\n    }\n\n    /**\n     * Get the view factory instance.\n     *\n     * @return \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected function factory()\n    {\n        if (is_null(static::$factory)) {\n            static::$factory = Container::getInstance()->make('view');\n        }\n\n        return static::$factory;\n    }\n\n    /**\n     * Get the cached set of anonymous component constructor parameter names to exclude.\n     *\n     * @return array\n     */\n    public static function ignoredParameterNames()\n    {\n        if (! isset(static::$ignoredParameterNames[static::class])) {\n            $constructor = (new ReflectionClass(\n                static::class\n            ))->getConstructor();\n\n            if (! $constructor) {\n                return static::$ignoredParameterNames[static::class] = [];\n            }\n\n            static::$ignoredParameterNames[static::class] = (new Collection($constructor->getParameters()))\n                ->map\n                ->getName()\n                ->all();\n        }\n\n        return static::$ignoredParameterNames[static::class];\n    }\n\n    /**\n     * Flush the component's cached state.\n     *\n     * @return void\n     */\n    public static function flushCache()\n    {\n        static::$bladeViewCache = [];\n        static::$constructorParametersCache = [];\n        static::$methodCache = [];\n        static::$propertyCache = [];\n    }\n\n    /**\n     * Forget the component's factory instance.\n     *\n     * @return void\n     */\n    public static function forgetFactory()\n    {\n        static::$factory = null;\n    }\n\n    /**\n     * Forget the component's resolver callback.\n     *\n     * @return void\n     *\n     * @internal\n     */\n    public static function forgetComponentsResolver()\n    {\n        static::$componentsResolver = null;\n    }\n\n    /**\n     * Set the callback that should be used to resolve components within views.\n     *\n     * @param  \\Closure(string $component, array $data): Component  $resolver\n     * @return void\n     *\n     * @internal\n     */\n    public static function resolveComponentsUsing($resolver)\n    {\n        static::$componentsResolver = $resolver;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/ComponentAttributeBag.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse Illuminate\\Support\\Traits\\InteractsWithData;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse IteratorAggregate;\nuse JsonSerializable;\nuse Stringable;\nuse Traversable;\n\nclass ComponentAttributeBag implements Arrayable, ArrayAccess, IteratorAggregate, JsonSerializable, Htmlable, Stringable\n{\n    use Conditionable, InteractsWithData, Macroable;\n\n    /**\n     * The raw array of attributes.\n     *\n     * @var array\n     */\n    protected $attributes = [];\n\n    /**\n     * Create a new component attribute bag instance.\n     *\n     * @param  array  $attributes\n     */\n    public function __construct(array $attributes = [])\n    {\n        $this->setAttributes($attributes);\n    }\n\n    /**\n     * Get all the attribute values.\n     *\n     * @param  mixed  $keys\n     * @return array\n     */\n    public function all($keys = null)\n    {\n        if (is_null($keys)) {\n            return $this->attributes;\n        }\n\n        return $this->only($keys)->toArray();\n    }\n\n    /**\n     * Get the first attribute's value.\n     *\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function first($default = null)\n    {\n        return $this->getIterator()->current() ?? value($default);\n    }\n\n    /**\n     * Get a given attribute from the attribute array.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function get($key, $default = null)\n    {\n        return $this->attributes[$key] ?? value($default);\n    }\n\n    /**\n     * Retrieve data from the instance.\n     *\n     * @param  string|null  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    protected function data($key = null, $default = null)\n    {\n        if (is_null($key)) {\n            return $this->attributes;\n        }\n\n        return $this->get($key, $default);\n    }\n\n    /**\n     * Only include the given attribute from the attribute array.\n     *\n     * @param  mixed  $keys\n     * @return static\n     */\n    public function only($keys)\n    {\n        if (is_null($keys)) {\n            $values = $this->attributes;\n        } else {\n            $keys = Arr::wrap($keys);\n\n            $values = Arr::only($this->attributes, $keys);\n        }\n\n        return new static($values);\n    }\n\n    /**\n     * Exclude the given attribute from the attribute array.\n     *\n     * @param  mixed  $keys\n     * @return static\n     */\n    public function except($keys)\n    {\n        if (is_null($keys)) {\n            $values = $this->attributes;\n        } else {\n            $keys = Arr::wrap($keys);\n\n            $values = Arr::except($this->attributes, $keys);\n        }\n\n        return new static($values);\n    }\n\n    /**\n     * Filter the attributes, returning a bag of attributes that pass the filter.\n     *\n     * @param  callable  $callback\n     * @return static\n     */\n    public function filter($callback)\n    {\n        return new static((new Collection($this->attributes))->filter($callback)->all());\n    }\n\n    /**\n     * Return a bag of attributes that have keys starting with the given value / pattern.\n     *\n     * @param  string|string[]  $needles\n     * @return static\n     */\n    public function whereStartsWith($needles)\n    {\n        return $this->filter(function ($value, $key) use ($needles) {\n            return Str::startsWith($key, $needles);\n        });\n    }\n\n    /**\n     * Return a bag of attributes with keys that do not start with the given value / pattern.\n     *\n     * @param  string|string[]  $needles\n     * @return static\n     */\n    public function whereDoesntStartWith($needles)\n    {\n        return $this->filter(function ($value, $key) use ($needles) {\n            return ! Str::startsWith($key, $needles);\n        });\n    }\n\n    /**\n     * Return a bag of attributes that have keys starting with the given value / pattern.\n     *\n     * @param  string|string[]  $needles\n     * @return static\n     */\n    public function thatStartWith($needles)\n    {\n        return $this->whereStartsWith($needles);\n    }\n\n    /**\n     * Only include the given attribute from the attribute array.\n     *\n     * @param  mixed  $keys\n     * @return static\n     */\n    public function onlyProps($keys)\n    {\n        return $this->only(static::extractPropNames($keys));\n    }\n\n    /**\n     * Exclude the given attribute from the attribute array.\n     *\n     * @param  mixed  $keys\n     * @return static\n     */\n    public function exceptProps($keys)\n    {\n        return $this->except(static::extractPropNames($keys));\n    }\n\n    /**\n     * Conditionally merge classes into the attribute bag.\n     *\n     * @param  mixed  $classList\n     * @return static\n     */\n    public function class($classList)\n    {\n        $classList = Arr::wrap($classList);\n\n        return $this->merge(['class' => Arr::toCssClasses($classList)]);\n    }\n\n    /**\n     * Conditionally merge styles into the attribute bag.\n     *\n     * @param  mixed  $styleList\n     * @return static\n     */\n    public function style($styleList)\n    {\n        $styleList = Arr::wrap($styleList);\n\n        return $this->merge(['style' => Arr::toCssStyles($styleList)]);\n    }\n\n    /**\n     * Merge additional attributes / values into the attribute bag.\n     *\n     * @param  array  $attributeDefaults\n     * @param  bool  $escape\n     * @return static\n     */\n    public function merge(array $attributeDefaults = [], $escape = true)\n    {\n        $attributeDefaults = array_map(function ($value) use ($escape) {\n            return $this->shouldEscapeAttributeValue($escape, $value)\n                ? e($value)\n                : $value;\n        }, $attributeDefaults);\n\n        [$appendableAttributes, $nonAppendableAttributes] = (new Collection($this->attributes))\n            ->partition(function ($value, $key) use ($attributeDefaults) {\n                return $key === 'class' || $key === 'style' || (\n                    isset($attributeDefaults[$key]) &&\n                    $attributeDefaults[$key] instanceof AppendableAttributeValue\n                );\n            });\n\n        $attributes = $appendableAttributes->mapWithKeys(function ($value, $key) use ($attributeDefaults, $escape) {\n            $defaultsValue = isset($attributeDefaults[$key]) && $attributeDefaults[$key] instanceof AppendableAttributeValue\n                ? $this->resolveAppendableAttributeDefault($attributeDefaults, $key, $escape)\n                : ($attributeDefaults[$key] ?? '');\n\n            if ($key === 'style') {\n                $value = Str::finish($value, ';');\n            }\n\n            return [$key => implode(' ', array_unique(array_filter([$defaultsValue, $value])))];\n        })->merge($nonAppendableAttributes)->all();\n\n        return new static(array_merge($attributeDefaults, $attributes));\n    }\n\n    /**\n     * Determine if the specific attribute value should be escaped.\n     *\n     * @param  bool  $escape\n     * @param  mixed  $value\n     * @return bool\n     */\n    protected function shouldEscapeAttributeValue($escape, $value)\n    {\n        if (! $escape) {\n            return false;\n        }\n\n        return ! is_object($value) &&\n               ! is_null($value) &&\n               ! is_bool($value);\n    }\n\n    /**\n     * Create a new appendable attribute value.\n     *\n     * @param  mixed  $value\n     * @return \\Illuminate\\View\\AppendableAttributeValue\n     */\n    public function prepends($value)\n    {\n        return new AppendableAttributeValue($value);\n    }\n\n    /**\n     * Resolve an appendable attribute value default value.\n     *\n     * @param  array  $attributeDefaults\n     * @param  string  $key\n     * @param  bool  $escape\n     * @return mixed\n     */\n    protected function resolveAppendableAttributeDefault($attributeDefaults, $key, $escape)\n    {\n        if ($this->shouldEscapeAttributeValue($escape, $value = $attributeDefaults[$key]->value)) {\n            $value = e($value);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Determine if the attribute bag is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return trim((string) $this) === '';\n    }\n\n    /**\n     * Determine if the attribute bag is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Get all of the raw attributes.\n     *\n     * @return array\n     */\n    public function getAttributes()\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Set the underlying attributes.\n     *\n     * @param  array  $attributes\n     * @return void\n     */\n    public function setAttributes(array $attributes)\n    {\n        if (isset($attributes['attributes']) &&\n            $attributes['attributes'] instanceof self) {\n            $parentBag = $attributes['attributes'];\n\n            unset($attributes['attributes']);\n\n            $attributes = $parentBag->merge($attributes, $escape = false)->getAttributes();\n        }\n\n        $this->attributes = $attributes;\n    }\n\n    /**\n     * Extract \"prop\" names from given keys.\n     *\n     * @param  array  $keys\n     * @return array\n     */\n    public static function extractPropNames(array $keys)\n    {\n        $props = [];\n\n        foreach ($keys as $key => $default) {\n            $key = is_numeric($key) ? $default : $key;\n\n            $props[] = $key;\n            $props[] = Str::kebab($key);\n        }\n\n        return $props;\n    }\n\n    /**\n     * Get content as a string of HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return (string) $this;\n    }\n\n    /**\n     * Merge additional attributes / values into the attribute bag.\n     *\n     * @param  array  $attributeDefaults\n     * @return \\Illuminate\\Support\\HtmlString\n     */\n    public function __invoke(array $attributeDefaults = [])\n    {\n        return new HtmlString((string) $this->merge($attributeDefaults));\n    }\n\n    /**\n     * Determine if the given offset exists.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return isset($this->attributes[$offset]);\n    }\n\n    /**\n     * Get the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->get($offset);\n    }\n\n    /**\n     * Set the value at a given offset.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->attributes[$offset] = $value;\n    }\n\n    /**\n     * Remove the value at the given offset.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->attributes[$offset]);\n    }\n\n    /**\n     * Get an iterator for the items.\n     *\n     * @return \\ArrayIterator\n     */\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->attributes);\n    }\n\n    /**\n     * Convert the object into a JSON serializable form.\n     *\n     * @return mixed\n     */\n    public function jsonSerialize(): mixed\n    {\n        return $this->attributes;\n    }\n\n    /**\n     * Get all the attribute values.\n     *\n     * @return array\n     */\n    public function toArray()\n    {\n        return $this->all();\n    }\n\n    /**\n     * Implode the attributes into a single HTML ready string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        $string = '';\n\n        foreach ($this->attributes as $key => $value) {\n            if ($value === false || is_null($value)) {\n                continue;\n            }\n\n            if ($value === true) {\n                $value = $key === 'x-data' || str_starts_with($key, 'wire:') ? '' : $key;\n            }\n\n            $string .= ' '.$key.'=\"'.str_replace('\"', '\\\\\"', trim($value)).'\"';\n        }\n\n        return trim($string);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/ComponentSlot.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse InvalidArgumentException;\nuse Stringable;\n\nclass ComponentSlot implements Htmlable, Stringable\n{\n    /**\n     * The slot attribute bag.\n     *\n     * @var \\Illuminate\\View\\ComponentAttributeBag\n     */\n    public $attributes;\n\n    /**\n     * The slot contents.\n     *\n     * @var string\n     */\n    protected $contents;\n\n    /**\n     * Create a new slot instance.\n     *\n     * @param  string  $contents\n     * @param  array  $attributes\n     */\n    public function __construct($contents = '', $attributes = [])\n    {\n        $this->contents = $contents;\n\n        $this->withAttributes($attributes);\n    }\n\n    /**\n     * Set the extra attributes that the slot should make available.\n     *\n     * @param  array  $attributes\n     * @return $this\n     */\n    public function withAttributes(array $attributes)\n    {\n        $this->attributes = new ComponentAttributeBag($attributes);\n\n        return $this;\n    }\n\n    /**\n     * Get the slot's HTML string.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->contents;\n    }\n\n    /**\n     * Determine if the slot is empty.\n     *\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return $this->contents === '';\n    }\n\n    /**\n     * Determine if the slot is not empty.\n     *\n     * @return bool\n     */\n    public function isNotEmpty()\n    {\n        return ! $this->isEmpty();\n    }\n\n    /**\n     * Determine if the slot has non-comment content.\n     *\n     * @param  callable|string|null  $callable\n     * @return bool\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function hasActualContent(callable|string|null $callable = null)\n    {\n        if (is_string($callable) && ! function_exists($callable)) {\n            throw new InvalidArgumentException('Callable does not exist.');\n        }\n\n        return filter_var(\n            $this->contents,\n            FILTER_CALLBACK,\n            ['options' => $callable ?? fn ($input) => trim(preg_replace(\"/<!--([\\s\\S]*?)-->/\", '', $input))]\n        ) !== '';\n    }\n\n    /**\n     * Get the slot's HTML string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->toHtml();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesComponents.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\View\\View;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\View\\ComponentSlot;\n\ntrait ManagesComponents\n{\n    /**\n     * The components being rendered.\n     *\n     * @var array\n     */\n    protected $componentStack = [];\n\n    /**\n     * The original data passed to the component.\n     *\n     * @var array\n     */\n    protected $componentData = [];\n\n    /**\n     * The component data for the component that is currently being rendered.\n     *\n     * @var array\n     */\n    protected $currentComponentData = [];\n\n    /**\n     * The slot contents for the component.\n     *\n     * @var array\n     */\n    protected $slots = [];\n\n    /**\n     * The names of the slots being rendered.\n     *\n     * @var array\n     */\n    protected $slotStack = [];\n\n    /**\n     * Start a component rendering process.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\View|\\Illuminate\\Contracts\\Support\\Htmlable|\\Closure|string  $view\n     * @param  array  $data\n     * @return void\n     */\n    public function startComponent($view, array $data = [])\n    {\n        if (ob_start()) {\n            $this->componentStack[] = $view;\n\n            $this->componentData[$this->currentComponent()] = $data;\n\n            $this->slots[$this->currentComponent()] = [];\n        }\n    }\n\n    /**\n     * Get the first view that actually exists from the given list, and start a component.\n     *\n     * @param  array  $names\n     * @param  array  $data\n     * @return void\n     */\n    public function startComponentFirst(array $names, array $data = [])\n    {\n        $name = Arr::first($names, function ($item) {\n            return $this->exists($item);\n        });\n\n        $this->startComponent($name, $data);\n    }\n\n    /**\n     * Render the current component.\n     *\n     * @return string\n     */\n    public function renderComponent()\n    {\n        $view = array_pop($this->componentStack);\n\n        $this->currentComponentData = array_merge(\n            $previousComponentData = $this->currentComponentData,\n            $data = $this->componentData()\n        );\n\n        try {\n            $view = value($view, $data);\n\n            if ($view instanceof View) {\n                return $view->with($data)->render();\n            } elseif ($view instanceof Htmlable) {\n                return $view->toHtml();\n            } else {\n                return $this->make($view, $data)->render();\n            }\n        } finally {\n            $this->currentComponentData = $previousComponentData;\n        }\n    }\n\n    /**\n     * Get the data for the given component.\n     *\n     * @return array\n     */\n    protected function componentData()\n    {\n        $defaultSlot = new ComponentSlot(trim(ob_get_clean()));\n\n        $slots = array_merge([\n            '__default' => $defaultSlot,\n        ], $this->slots[count($this->componentStack)]);\n\n        return array_merge(\n            $this->componentData[count($this->componentStack)],\n            ['slot' => $defaultSlot],\n            $this->slots[count($this->componentStack)],\n            ['__laravel_slots' => $slots]\n        );\n    }\n\n    /**\n     * Get an item from the component data that exists above the current component.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function getConsumableComponentData($key, $default = null)\n    {\n        if (array_key_exists($key, $this->currentComponentData)) {\n            return $this->currentComponentData[$key];\n        }\n\n        $currentComponent = count($this->componentStack);\n\n        if ($currentComponent === 0) {\n            return value($default);\n        }\n\n        for ($i = $currentComponent - 1; $i >= 0; $i--) {\n            $data = $this->componentData[$i] ?? [];\n\n            if (array_key_exists($key, $data)) {\n                return $data[$key];\n            }\n        }\n\n        return value($default);\n    }\n\n    /**\n     * Start the slot rendering process.\n     *\n     * @param  string  $name\n     * @param  string|null  $content\n     * @param  array  $attributes\n     * @return void\n     */\n    public function slot($name, $content = null, $attributes = [])\n    {\n        if (func_num_args() === 2 || $content !== null) {\n            $this->slots[$this->currentComponent()][$name] = $content;\n        } elseif (ob_start()) {\n            $this->slots[$this->currentComponent()][$name] = '';\n\n            $this->slotStack[$this->currentComponent()][] = [$name, $attributes];\n        }\n    }\n\n    /**\n     * Save the slot content for rendering.\n     *\n     * @return void\n     */\n    public function endSlot()\n    {\n        last($this->componentStack);\n\n        $currentSlot = array_pop(\n            $this->slotStack[$this->currentComponent()]\n        );\n\n        [$currentName, $currentAttributes] = $currentSlot;\n\n        $this->slots[$this->currentComponent()][$currentName] = new ComponentSlot(\n            trim(ob_get_clean()), $currentAttributes\n        );\n    }\n\n    /**\n     * Get the index for the current component.\n     *\n     * @return int\n     */\n    protected function currentComponent()\n    {\n        return count($this->componentStack) - 1;\n    }\n\n    /**\n     * Flush all of the component state.\n     *\n     * @return void\n     */\n    protected function flushComponents()\n    {\n        $this->componentStack = [];\n        $this->componentData = [];\n        $this->currentComponentData = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesEvents.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse Closure;\nuse Illuminate\\Contracts\\View\\View as ViewContract;\nuse Illuminate\\Support\\Str;\n\ntrait ManagesEvents\n{\n    /**\n     * Register a view creator event.\n     *\n     * @param  array|string  $views\n     * @param  \\Closure|string  $callback\n     * @return array\n     */\n    public function creator($views, $callback)\n    {\n        $creators = [];\n\n        foreach ((array) $views as $view) {\n            $creators[] = $this->addViewEvent($view, $callback, 'creating: ');\n        }\n\n        return $creators;\n    }\n\n    /**\n     * Register multiple view composers via an array.\n     *\n     * @param  array  $composers\n     * @return array\n     */\n    public function composers(array $composers)\n    {\n        $registered = [];\n\n        foreach ($composers as $callback => $views) {\n            $registered = array_merge($registered, $this->composer($views, $callback));\n        }\n\n        return $registered;\n    }\n\n    /**\n     * Register a view composer event.\n     *\n     * @param  array|string  $views\n     * @param  \\Closure|string  $callback\n     * @return array\n     */\n    public function composer($views, $callback)\n    {\n        $composers = [];\n\n        foreach ((array) $views as $view) {\n            $composers[] = $this->addViewEvent($view, $callback);\n        }\n\n        return $composers;\n    }\n\n    /**\n     * Add an event for a given view.\n     *\n     * @param  string  $view\n     * @param  \\Closure|string  $callback\n     * @param  string  $prefix\n     * @return \\Closure|null\n     */\n    protected function addViewEvent($view, $callback, $prefix = 'composing: ')\n    {\n        $view = $this->normalizeName($view);\n\n        if ($callback instanceof Closure) {\n            $this->addEventListener($prefix.$view, $callback);\n\n            return $callback;\n        } elseif (is_string($callback)) {\n            return $this->addClassEvent($view, $callback, $prefix);\n        }\n    }\n\n    /**\n     * Register a class based view composer.\n     *\n     * @param  string  $view\n     * @param  string  $class\n     * @param  string  $prefix\n     * @return \\Closure\n     */\n    protected function addClassEvent($view, $class, $prefix)\n    {\n        $name = $prefix.$view;\n\n        // When registering a class based view \"composer\", we will simply resolve the\n        // classes from the application IoC container then call the compose method\n        // on the instance. This allows for convenient, testable view composers.\n        $callback = $this->buildClassEventCallback(\n            $class, $prefix\n        );\n\n        $this->addEventListener($name, $callback);\n\n        return $callback;\n    }\n\n    /**\n     * Build a class based container callback Closure.\n     *\n     * @param  string  $class\n     * @param  string  $prefix\n     * @return \\Closure\n     */\n    protected function buildClassEventCallback($class, $prefix)\n    {\n        [$class, $method] = $this->parseClassEvent($class, $prefix);\n\n        // Once we have the class and method name, we can build the Closure to resolve\n        // the instance out of the IoC container and call the method on it with the\n        // given arguments that are passed to the Closure as the composer's data.\n        return function () use ($class, $method) {\n            return $this->container->make($class)->{$method}(...func_get_args());\n        };\n    }\n\n    /**\n     * Parse a class based composer name.\n     *\n     * @param  string  $class\n     * @param  string  $prefix\n     * @return array\n     */\n    protected function parseClassEvent($class, $prefix)\n    {\n        return Str::parseCallback($class, $this->classEventMethodForPrefix($prefix));\n    }\n\n    /**\n     * Determine the class event method based on the given prefix.\n     *\n     * @param  string  $prefix\n     * @return string\n     */\n    protected function classEventMethodForPrefix($prefix)\n    {\n        return str_contains($prefix, 'composing') ? 'compose' : 'create';\n    }\n\n    /**\n     * Add a listener to the event dispatcher.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     * @return void\n     */\n    protected function addEventListener($name, $callback)\n    {\n        if (str_contains($name, '*')) {\n            $callback = function ($name, array $data) use ($callback) {\n                return $callback($data[0]);\n            };\n        }\n\n        $this->events->listen($name, $callback);\n    }\n\n    /**\n     * Call the composer for a given view.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\View  $view\n     * @return void\n     */\n    public function callComposer(ViewContract $view)\n    {\n        if ($this->events->hasListeners($event = 'composing: '.$view->name())) {\n            $this->events->dispatch($event, [$view]);\n        }\n    }\n\n    /**\n     * Call the creator for a given view.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\View  $view\n     * @return void\n     */\n    public function callCreator(ViewContract $view)\n    {\n        if ($this->events->hasListeners($event = 'creating: '.$view->name())) {\n            $this->events->dispatch($event, [$view]);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesFragments.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse InvalidArgumentException;\n\ntrait ManagesFragments\n{\n    /**\n     * All of the captured, rendered fragments.\n     *\n     * @var array\n     */\n    protected $fragments = [];\n\n    /**\n     * The stack of in-progress fragment renders.\n     *\n     * @var array\n     */\n    protected $fragmentStack = [];\n\n    /**\n     * Start injecting content into a fragment.\n     *\n     * @param  string  $fragment\n     * @return void\n     */\n    public function startFragment($fragment)\n    {\n        if (ob_start()) {\n            $this->fragmentStack[] = $fragment;\n        }\n    }\n\n    /**\n     * Stop injecting content into a fragment.\n     *\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function stopFragment()\n    {\n        if (empty($this->fragmentStack)) {\n            throw new InvalidArgumentException('Cannot end a fragment without first starting one.');\n        }\n\n        $last = array_pop($this->fragmentStack);\n\n        $this->fragments[$last] = ob_get_clean();\n\n        return $this->fragments[$last];\n    }\n\n    /**\n     * Get the contents of a fragment.\n     *\n     * @param  string  $name\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function getFragment($name, $default = null)\n    {\n        return $this->getFragments()[$name] ?? $default;\n    }\n\n    /**\n     * Get the entire array of rendered fragments.\n     *\n     * @return array\n     */\n    public function getFragments()\n    {\n        return $this->fragments;\n    }\n\n    /**\n     * Flush all of the fragments.\n     *\n     * @return void\n     */\n    public function flushFragments()\n    {\n        $this->fragments = [];\n        $this->fragmentStack = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesLayouts.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse Illuminate\\Contracts\\View\\View;\nuse Illuminate\\Support\\Str;\nuse InvalidArgumentException;\n\ntrait ManagesLayouts\n{\n    /**\n     * All of the finished, captured sections.\n     *\n     * @var array\n     */\n    protected $sections = [];\n\n    /**\n     * The stack of in-progress sections.\n     *\n     * @var array\n     */\n    protected $sectionStack = [];\n\n    /**\n     * The parent placeholder for the request.\n     *\n     * @var mixed\n     */\n    protected static $parentPlaceholder = [];\n\n    /**\n     * The parent placeholder salt for the request.\n     *\n     * @var string\n     */\n    protected static $parentPlaceholderSalt;\n\n    /**\n     * Start injecting content into a section.\n     *\n     * @param  string  $section\n     * @param  string|null  $content\n     * @return void\n     */\n    public function startSection($section, $content = null)\n    {\n        if ($content === null) {\n            if (ob_start()) {\n                $this->sectionStack[] = $section;\n            }\n        } else {\n            $this->extendSection($section, $content instanceof View ? $content : e($content));\n        }\n    }\n\n    /**\n     * Inject inline content into a section.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    public function inject($section, $content)\n    {\n        $this->startSection($section, $content);\n    }\n\n    /**\n     * Stop injecting content into a section and return its contents.\n     *\n     * @return string\n     */\n    public function yieldSection()\n    {\n        if (empty($this->sectionStack)) {\n            return '';\n        }\n\n        return $this->yieldContent($this->stopSection());\n    }\n\n    /**\n     * Stop injecting content into a section.\n     *\n     * @param  bool  $overwrite\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function stopSection($overwrite = false)\n    {\n        if (empty($this->sectionStack)) {\n            throw new InvalidArgumentException('Cannot end a section without first starting one.');\n        }\n\n        $last = array_pop($this->sectionStack);\n\n        if ($overwrite) {\n            $this->sections[$last] = ob_get_clean();\n        } else {\n            $this->extendSection($last, ob_get_clean());\n        }\n\n        return $last;\n    }\n\n    /**\n     * Stop injecting content into a section and append it.\n     *\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function appendSection()\n    {\n        if (empty($this->sectionStack)) {\n            throw new InvalidArgumentException('Cannot end a section without first starting one.');\n        }\n\n        $last = array_pop($this->sectionStack);\n\n        if (isset($this->sections[$last])) {\n            $this->sections[$last] .= ob_get_clean();\n        } else {\n            $this->sections[$last] = ob_get_clean();\n        }\n\n        return $last;\n    }\n\n    /**\n     * Append content to a given section.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    protected function extendSection($section, $content)\n    {\n        if (isset($this->sections[$section])) {\n            $content = str_replace(static::parentPlaceholder($section), $content, $this->sections[$section]);\n        }\n\n        $this->sections[$section] = $content;\n    }\n\n    /**\n     * Get the string contents of a section.\n     *\n     * @param  string  $section\n     * @param  string  $default\n     * @return string\n     */\n    public function yieldContent($section, $default = '')\n    {\n        $sectionContent = $default instanceof View ? $default : e($default);\n\n        if (isset($this->sections[$section])) {\n            $sectionContent = $this->sections[$section];\n        }\n\n        $sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);\n\n        return str_replace(\n            '--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)\n        );\n    }\n\n    /**\n     * Get the parent placeholder for the current request.\n     *\n     * @param  string  $section\n     * @return string\n     */\n    public static function parentPlaceholder($section = '')\n    {\n        if (! isset(static::$parentPlaceholder[$section])) {\n            $salt = static::parentPlaceholderSalt();\n\n            static::$parentPlaceholder[$section] = '##parent-placeholder-'.hash('xxh128', $salt.$section).'##';\n        }\n\n        return static::$parentPlaceholder[$section];\n    }\n\n    /**\n     * Get the parent placeholder salt.\n     *\n     * @return string\n     */\n    protected static function parentPlaceholderSalt()\n    {\n        if (! static::$parentPlaceholderSalt) {\n            return static::$parentPlaceholderSalt = Str::random(40);\n        }\n\n        return static::$parentPlaceholderSalt;\n    }\n\n    /**\n     * Check if section exists.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasSection($name)\n    {\n        return array_key_exists($name, $this->sections);\n    }\n\n    /**\n     * Check if section does not exist.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function sectionMissing($name)\n    {\n        return ! $this->hasSection($name);\n    }\n\n    /**\n     * Get the contents of a section.\n     *\n     * @param  string  $name\n     * @param  string|null  $default\n     * @return mixed\n     */\n    public function getSection($name, $default = null)\n    {\n        return $this->getSections()[$name] ?? $default;\n    }\n\n    /**\n     * Get the entire array of sections.\n     *\n     * @return array\n     */\n    public function getSections()\n    {\n        return $this->sections;\n    }\n\n    /**\n     * Flush all of the sections.\n     *\n     * @return void\n     */\n    public function flushSections()\n    {\n        $this->sections = [];\n        $this->sectionStack = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesLoops.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\LazyCollection;\n\ntrait ManagesLoops\n{\n    /**\n     * The stack of in-progress loops.\n     *\n     * @var array\n     */\n    protected $loopsStack = [];\n\n    /**\n     * Add new loop to the stack.\n     *\n     * @param  \\Countable|array  $data\n     * @return void\n     */\n    public function addLoop($data)\n    {\n        $length = is_countable($data) && ! $data instanceof LazyCollection\n            ? count($data)\n            : null;\n\n        $parent = Arr::last($this->loopsStack);\n\n        $this->loopsStack[] = [\n            'iteration' => 0,\n            'index' => 0,\n            'remaining' => $length ?? null,\n            'count' => $length,\n            'first' => true,\n            'last' => isset($length) ? $length == 1 : null,\n            'odd' => false,\n            'even' => true,\n            'depth' => count($this->loopsStack) + 1,\n            'parent' => $parent ? (object) $parent : null,\n        ];\n    }\n\n    /**\n     * Increment the top loop's indices.\n     *\n     * @return void\n     */\n    public function incrementLoopIndices()\n    {\n        $loop = $this->loopsStack[$index = count($this->loopsStack) - 1];\n\n        $this->loopsStack[$index] = array_merge($this->loopsStack[$index], [\n            'iteration' => $loop['iteration'] + 1,\n            'index' => $loop['iteration'],\n            'first' => $loop['iteration'] == 0,\n            'odd' => ! $loop['odd'],\n            'even' => ! $loop['even'],\n            'remaining' => isset($loop['count']) ? $loop['remaining'] - 1 : null,\n            'last' => isset($loop['count']) ? $loop['iteration'] == $loop['count'] - 1 : null,\n        ]);\n    }\n\n    /**\n     * Pop a loop from the top of the loop stack.\n     *\n     * @return void\n     */\n    public function popLoop()\n    {\n        array_pop($this->loopsStack);\n    }\n\n    /**\n     * Get an instance of the last loop in the stack.\n     *\n     * @return \\stdClass|null\n     */\n    public function getLastLoop()\n    {\n        if ($last = Arr::last($this->loopsStack)) {\n            return (object) $last;\n        }\n    }\n\n    /**\n     * Get the entire loop stack.\n     *\n     * @return array\n     */\n    public function getLoopStack()\n    {\n        return $this->loopsStack;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesStacks.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\nuse InvalidArgumentException;\n\ntrait ManagesStacks\n{\n    /**\n     * All of the finished, captured push sections.\n     *\n     * @var array\n     */\n    protected $pushes = [];\n\n    /**\n     * All of the finished, captured prepend sections.\n     *\n     * @var array\n     */\n    protected $prepends = [];\n\n    /**\n     * The stack of in-progress push sections.\n     *\n     * @var array\n     */\n    protected $pushStack = [];\n\n    /**\n     * Start injecting content into a push section.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    public function startPush($section, $content = '')\n    {\n        if ($content === '') {\n            if (ob_start()) {\n                $this->pushStack[] = $section;\n            }\n        } else {\n            $this->extendPush($section, $content);\n        }\n    }\n\n    /**\n     * Stop injecting content into a push section.\n     *\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function stopPush()\n    {\n        if (empty($this->pushStack)) {\n            throw new InvalidArgumentException('Cannot end a push stack without first starting one.');\n        }\n\n        return tap(array_pop($this->pushStack), function ($last) {\n            $this->extendPush($last, ob_get_clean());\n        });\n    }\n\n    /**\n     * Append content to a given push section.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    protected function extendPush($section, $content)\n    {\n        if (! isset($this->pushes[$section])) {\n            $this->pushes[$section] = [];\n        }\n\n        if (! isset($this->pushes[$section][$this->renderCount])) {\n            $this->pushes[$section][$this->renderCount] = $content;\n        } else {\n            $this->pushes[$section][$this->renderCount] .= $content;\n        }\n    }\n\n    /**\n     * Start prepending content into a push section.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    public function startPrepend($section, $content = '')\n    {\n        if ($content === '') {\n            if (ob_start()) {\n                $this->pushStack[] = $section;\n            }\n        } else {\n            $this->extendPrepend($section, $content);\n        }\n    }\n\n    /**\n     * Stop prepending content into a push section.\n     *\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function stopPrepend()\n    {\n        if (empty($this->pushStack)) {\n            throw new InvalidArgumentException('Cannot end a prepend operation without first starting one.');\n        }\n\n        return tap(array_pop($this->pushStack), function ($last) {\n            $this->extendPrepend($last, ob_get_clean());\n        });\n    }\n\n    /**\n     * Prepend content to a given stack.\n     *\n     * @param  string  $section\n     * @param  string  $content\n     * @return void\n     */\n    protected function extendPrepend($section, $content)\n    {\n        if (! isset($this->prepends[$section])) {\n            $this->prepends[$section] = [];\n        }\n\n        if (! isset($this->prepends[$section][$this->renderCount])) {\n            $this->prepends[$section][$this->renderCount] = $content;\n        } else {\n            $this->prepends[$section][$this->renderCount] = $content.$this->prepends[$section][$this->renderCount];\n        }\n    }\n\n    /**\n     * Get the string contents of a push section.\n     *\n     * @param  string  $section\n     * @param  string  $default\n     * @return string\n     */\n    public function yieldPushContent($section, $default = '')\n    {\n        if ($this->isStackEmpty($section)) {\n            return $default;\n        }\n\n        $output = '';\n\n        if (isset($this->prepends[$section])) {\n            $output .= implode(array_reverse($this->prepends[$section]));\n        }\n\n        if (isset($this->pushes[$section])) {\n            $output .= implode($this->pushes[$section]);\n        }\n\n        return $output;\n    }\n\n    /**\n     * Determine if the stack has any content in it.\n     */\n    public function isStackEmpty(string $section): bool\n    {\n        return ! isset($this->pushes[$section]) && ! isset($this->prepends[$section]);\n    }\n\n    /**\n     * Flush all of the stacks.\n     *\n     * @return void\n     */\n    public function flushStacks()\n    {\n        $this->pushes = [];\n        $this->prepends = [];\n        $this->pushStack = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Concerns/ManagesTranslations.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Concerns;\n\ntrait ManagesTranslations\n{\n    /**\n     * The translation replacements for the translation being rendered.\n     *\n     * @var array\n     */\n    protected $translationReplacements = [];\n\n    /**\n     * Start a translation block.\n     *\n     * @param  array  $replacements\n     * @return void\n     */\n    public function startTranslation($replacements = [])\n    {\n        ob_start();\n\n        $this->translationReplacements = $replacements;\n    }\n\n    /**\n     * Render the current translation.\n     *\n     * @return string\n     */\n    public function renderTranslation()\n    {\n        return $this->container->make('translator')->get(\n            trim(ob_get_clean()), $this->translationReplacements\n        );\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/DynamicComponent.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse BackedEnum;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\View\\Compilers\\ComponentTagCompiler;\n\nuse function Illuminate\\Support\\enum_value;\n\nclass DynamicComponent extends Component\n{\n    /**\n     * The name of the component.\n     *\n     * @var string\n     */\n    public $component;\n\n    /**\n     * The component tag compiler instance.\n     *\n     * @var \\Illuminate\\View\\Compilers\\BladeTagCompiler\n     */\n    protected static $compiler;\n\n    /**\n     * The cached component classes.\n     *\n     * @var array\n     */\n    protected static $componentClasses = [];\n\n    /**\n     * Create a new component instance.\n     *\n     * @param  \\BackedEnum|string  $component\n     */\n    public function __construct(BackedEnum|string $component)\n    {\n        $this->component = (string) enum_value($component);\n    }\n\n    /**\n     * Get the view / contents that represent the component.\n     *\n     * @return \\Illuminate\\Contracts\\View\\View|string\n     */\n    public function render()\n    {\n        $template = <<<'EOF'\n<?php extract((new \\Illuminate\\Support\\Collection($attributes->getAttributes()))->mapWithKeys(function ($value, $key) { return [Illuminate\\Support\\Str::camel(str_replace([':', '.'], ' ', $key)) => $value]; })->all(), EXTR_SKIP); ?>\n{{ props }}\n<x-{{ component }} {{ bindings }} {{ attributes }}>\n{{ slots }}\n{{ defaultSlot }}\n</x-{{ component }}>\nEOF;\n\n        return function ($data) use ($template) {\n            $bindings = $this->bindings($class = $this->classForComponent());\n\n            return str_replace(\n                [\n                    '{{ component }}',\n                    '{{ props }}',\n                    '{{ bindings }}',\n                    '{{ attributes }}',\n                    '{{ slots }}',\n                    '{{ defaultSlot }}',\n                ],\n                [\n                    $this->component,\n                    $this->compileProps($bindings),\n                    $this->compileBindings($bindings),\n                    class_exists($class) ? '{{ $attributes }}' : '',\n                    $this->compileSlots($data['__laravel_slots']),\n                    '{{ $slot ?? \"\" }}',\n                ],\n                $template\n            );\n        };\n    }\n\n    /**\n     * Compile the @props directive for the component.\n     *\n     * @param  array  $bindings\n     * @return string\n     */\n    protected function compileProps(array $bindings)\n    {\n        if (empty($bindings)) {\n            return '';\n        }\n\n        return '@props('.'[\\''.implode('\\',\\'', (new Collection($bindings))->map(function ($dataKey) {\n            return Str::camel($dataKey);\n        })->all()).'\\']'.')';\n    }\n\n    /**\n     * Compile the bindings for the component.\n     *\n     * @param  array  $bindings\n     * @return string\n     */\n    protected function compileBindings(array $bindings)\n    {\n        return (new Collection($bindings))\n            ->map(fn ($key) => ':'.$key.'=\"$'.Str::camel(str_replace([':', '.'], ' ', $key)).'\"')\n            ->implode(' ');\n    }\n\n    /**\n     * Compile the slots for the component.\n     *\n     * @param  array  $slots\n     * @return string\n     */\n    protected function compileSlots(array $slots)\n    {\n        return (new Collection($slots))\n            ->map(fn ($slot, $name) => $name === '__default' ? null : '<x-slot name=\"'.$name.'\" '.((string) $slot->attributes).'>{{ $'.$name.' }}</x-slot>')\n            ->filter()\n            ->implode(PHP_EOL);\n    }\n\n    /**\n     * Get the class for the current component.\n     *\n     * @return string\n     */\n    protected function classForComponent()\n    {\n        if (isset(static::$componentClasses[$this->component])) {\n            return static::$componentClasses[$this->component];\n        }\n\n        return static::$componentClasses[$this->component] =\n                    $this->compiler()->componentClass($this->component);\n    }\n\n    /**\n     * Get the names of the variables that should be bound to the component.\n     *\n     * @param  string  $class\n     * @return array\n     */\n    protected function bindings(string $class)\n    {\n        [$data] = $this->compiler()->partitionDataAndAttributes($class, $this->attributes->getAttributes());\n\n        return array_keys($data->all());\n    }\n\n    /**\n     * Get an instance of the Blade tag compiler.\n     *\n     * @return \\Illuminate\\View\\Compilers\\ComponentTagCompiler\n     */\n    protected function compiler()\n    {\n        if (! static::$compiler) {\n            static::$compiler = new ComponentTagCompiler(\n                Container::getInstance()->make('blade.compiler')->getClassComponentAliases(),\n                Container::getInstance()->make('blade.compiler')->getClassComponentNamespaces(),\n                Container::getInstance()->make('blade.compiler')\n            );\n        }\n\n        return static::$compiler;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Engines/CompilerEngine.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Engines;\n\nuse Illuminate\\Database\\RecordNotFoundException;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\View\\Compilers\\CompilerInterface;\nuse Illuminate\\View\\ViewException;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Throwable;\n\nclass CompilerEngine extends PhpEngine\n{\n    /**\n     * The Blade compiler instance.\n     *\n     * @var \\Illuminate\\View\\Compilers\\CompilerInterface\n     */\n    protected $compiler;\n\n    /**\n     * A stack of the last compiled templates.\n     *\n     * @var array\n     */\n    protected $lastCompiled = [];\n\n    /**\n     * The view paths that were compiled or are not expired, keyed by the path.\n     *\n     * @var array<string, true>\n     */\n    protected $compiledOrNotExpired = [];\n\n    /**\n     * Create a new compiler engine instance.\n     *\n     * @param  \\Illuminate\\View\\Compilers\\CompilerInterface  $compiler\n     * @param  \\Illuminate\\Filesystem\\Filesystem|null  $files\n     */\n    public function __construct(CompilerInterface $compiler, ?Filesystem $files = null)\n    {\n        parent::__construct($files ?: new Filesystem);\n\n        $this->compiler = $compiler;\n    }\n\n    /**\n     * Get the evaluated contents of the view.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return string\n     *\n     * @throws \\Illuminate\\View\\ViewException\n     */\n    public function get($path, array $data = [])\n    {\n        $this->lastCompiled[] = $path;\n\n        // If this given view has expired, which means it has simply been edited since\n        // it was last compiled, we will re-compile the views so we can evaluate a\n        // fresh copy of the view. We'll pass the compiler the path of the view.\n        if (! isset($this->compiledOrNotExpired[$path]) && $this->compiler->isExpired($path)) {\n            $this->compiler->compile($path);\n        }\n\n        // Once we have the path to the compiled file, we will evaluate the paths with\n        // typical PHP just like any other templates. We also keep a stack of views\n        // which have been rendered for right exception messages to be generated.\n\n        try {\n            $results = $this->evaluatePath($this->compiler->getCompiledPath($path), $data);\n        } catch (ViewException $e) {\n            if (! Str::of($e->getMessage())->contains(['No such file or directory', 'File does not exist at path'])) {\n                throw $e;\n            }\n\n            if (! isset($this->compiledOrNotExpired[$path])) {\n                throw $e;\n            }\n\n            $this->compiler->compile($path);\n\n            $results = $this->evaluatePath($this->compiler->getCompiledPath($path), $data);\n        }\n\n        $this->compiledOrNotExpired[$path] = true;\n\n        array_pop($this->lastCompiled);\n\n        return $results;\n    }\n\n    /**\n     * Handle a view exception.\n     *\n     * @param  \\Throwable  $e\n     * @param  int  $obLevel\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleViewException(Throwable $e, $obLevel)\n    {\n        if ($e instanceof HttpException ||\n            $e instanceof HttpResponseException ||\n            $e instanceof RecordNotFoundException ||\n            $e instanceof RecordsNotFoundException) {\n            parent::handleViewException($e, $obLevel);\n        }\n\n        $e = new ViewException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);\n\n        parent::handleViewException($e, $obLevel);\n    }\n\n    /**\n     * Get the exception message for an exception.\n     *\n     * @param  \\Throwable  $e\n     * @return string\n     */\n    protected function getMessage(Throwable $e)\n    {\n        return $e->getMessage().' (View: '.realpath(last($this->lastCompiled)).')';\n    }\n\n    /**\n     * Get the compiler implementation.\n     *\n     * @return \\Illuminate\\View\\Compilers\\CompilerInterface\n     */\n    public function getCompiler()\n    {\n        return $this->compiler;\n    }\n\n    /**\n     * Clear the cache of views that were compiled or not expired.\n     *\n     * @return void\n     */\n    public function forgetCompiledOrNotExpired()\n    {\n        $this->compiledOrNotExpired = [];\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Engines/Engine.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Engines;\n\nabstract class Engine\n{\n    /**\n     * The view that was last to be rendered.\n     *\n     * @var string\n     */\n    protected $lastRendered;\n\n    /**\n     * Get the last view that was rendered.\n     *\n     * @return string\n     */\n    public function getLastRendered()\n    {\n        return $this->lastRendered;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Engines/EngineResolver.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Engines;\n\nuse Closure;\nuse InvalidArgumentException;\n\nclass EngineResolver\n{\n    /**\n     * The array of engine resolvers.\n     *\n     * @var array\n     */\n    protected $resolvers = [];\n\n    /**\n     * The resolved engine instances.\n     *\n     * @var array\n     */\n    protected $resolved = [];\n\n    /**\n     * Register a new engine resolver.\n     *\n     * The engine string typically corresponds to a file extension.\n     *\n     * @param  string  $engine\n     * @param  \\Closure  $resolver\n     * @return void\n     */\n    public function register($engine, Closure $resolver)\n    {\n        $this->forget($engine);\n\n        $this->resolvers[$engine] = $resolver;\n    }\n\n    /**\n     * Resolve an engine instance by name.\n     *\n     * @param  string  $engine\n     * @return \\Illuminate\\Contracts\\View\\Engine\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function resolve($engine)\n    {\n        if (isset($this->resolved[$engine])) {\n            return $this->resolved[$engine];\n        }\n\n        if (isset($this->resolvers[$engine])) {\n            return $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);\n        }\n\n        throw new InvalidArgumentException(\"Engine [{$engine}] not found.\");\n    }\n\n    /**\n     * Remove a resolved engine.\n     *\n     * @param  string  $engine\n     * @return void\n     */\n    public function forget($engine)\n    {\n        unset($this->resolved[$engine]);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Engines/FileEngine.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Engines;\n\nuse Illuminate\\Contracts\\View\\Engine;\nuse Illuminate\\Filesystem\\Filesystem;\n\nclass FileEngine implements Engine\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new file engine instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        $this->files = $files;\n    }\n\n    /**\n     * Get the evaluated contents of the view.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return string\n     */\n    public function get($path, array $data = [])\n    {\n        return $this->files->get($path);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Engines/PhpEngine.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Engines;\n\nuse Illuminate\\Contracts\\View\\Engine;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Throwable;\n\nclass PhpEngine implements Engine\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * Create a new file engine instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     */\n    public function __construct(Filesystem $files)\n    {\n        $this->files = $files;\n    }\n\n    /**\n     * Get the evaluated contents of the view.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return string\n     */\n    public function get($path, array $data = [])\n    {\n        return $this->evaluatePath($path, $data);\n    }\n\n    /**\n     * Get the evaluated contents of the view at the given path.\n     *\n     * @param  string  $path\n     * @param  array  $data\n     * @return string\n     */\n    protected function evaluatePath($path, $data)\n    {\n        $obLevel = ob_get_level();\n\n        ob_start();\n\n        // We'll evaluate the contents of the view inside a try/catch block so we can\n        // flush out any stray output that might get out before an error occurs or\n        // an exception is thrown. This prevents any partial views from leaking.\n        try {\n            $this->files->getRequire($path, $data);\n        } catch (Throwable $e) {\n            $this->handleViewException($e, $obLevel);\n        }\n\n        return ltrim(ob_get_clean());\n    }\n\n    /**\n     * Handle a view exception.\n     *\n     * @param  \\Throwable  $e\n     * @param  int  $obLevel\n     * @return void\n     *\n     * @throws \\Throwable\n     */\n    protected function handleViewException(Throwable $e, $obLevel)\n    {\n        while (ob_get_level() > $obLevel) {\n            ob_end_clean();\n        }\n\n        throw $e;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/Factory.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\View\\Factory as FactoryContract;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\View\\Engines\\EngineResolver;\nuse InvalidArgumentException;\n\nclass Factory implements FactoryContract\n{\n    use Macroable,\n        Concerns\\ManagesComponents,\n        Concerns\\ManagesEvents,\n        Concerns\\ManagesFragments,\n        Concerns\\ManagesLayouts,\n        Concerns\\ManagesLoops,\n        Concerns\\ManagesStacks,\n        Concerns\\ManagesTranslations;\n\n    /**\n     * The engine implementation.\n     *\n     * @var \\Illuminate\\View\\Engines\\EngineResolver\n     */\n    protected $engines;\n\n    /**\n     * The view finder implementation.\n     *\n     * @var \\Illuminate\\View\\ViewFinderInterface\n     */\n    protected $finder;\n\n    /**\n     * The event dispatcher instance.\n     *\n     * @var \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    protected $events;\n\n    /**\n     * The IoC container instance.\n     *\n     * @var \\Illuminate\\Contracts\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * Data that should be available to all templates.\n     *\n     * @var array\n     */\n    protected $shared = [];\n\n    /**\n     * The extension to engine bindings.\n     *\n     * @var array\n     */\n    protected $extensions = [\n        'blade.php' => 'blade',\n        'php' => 'php',\n        'css' => 'file',\n        'html' => 'file',\n    ];\n\n    /**\n     * The view composer events.\n     *\n     * @var array\n     */\n    protected $composers = [];\n\n    /**\n     * The number of active rendering operations.\n     *\n     * @var int\n     */\n    protected $renderCount = 0;\n\n    /**\n     * The \"once\" block IDs that have been rendered.\n     *\n     * @var array\n     */\n    protected $renderedOnce = [];\n\n    /**\n     * The cached array of engines for paths.\n     *\n     * @var array\n     */\n    protected $pathEngineCache = [];\n\n    /**\n     * The cache of normalized names for views.\n     *\n     * @var array\n     */\n    protected $normalizedNameCache = [];\n\n    /**\n     * Create a new view factory instance.\n     *\n     * @param  \\Illuminate\\View\\Engines\\EngineResolver  $engines\n     * @param  \\Illuminate\\View\\ViewFinderInterface  $finder\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     */\n    public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)\n    {\n        $this->finder = $finder;\n        $this->events = $events;\n        $this->engines = $engines;\n\n        $this->share('__env', $this);\n    }\n\n    /**\n     * Get the evaluated view contents for the given view.\n     *\n     * @param  string  $path\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    public function file($path, $data = [], $mergeData = [])\n    {\n        $data = array_merge($mergeData, $this->parseData($data));\n\n        return tap($this->viewInstance($path, $path, $data), function ($view) {\n            $this->callCreator($view);\n        });\n    }\n\n    /**\n     * Get the evaluated view contents for the given view.\n     *\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    public function make($view, $data = [], $mergeData = [])\n    {\n        $path = $this->finder->find(\n            $view = $this->normalizeName($view)\n        );\n\n        // Next, we will create the view instance and call the view creator for the view\n        // which can set any data, etc. Then we will return the view instance back to\n        // the caller for rendering or performing other view manipulations on this.\n        $data = array_merge($mergeData, $this->parseData($data));\n\n        return tap($this->viewInstance($view, $path, $data), function ($view) {\n            $this->callCreator($view);\n        });\n    }\n\n    /**\n     * Get the first view that actually exists from the given list.\n     *\n     * @param  array  $views\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return \\Illuminate\\Contracts\\View\\View\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function first(array $views, $data = [], $mergeData = [])\n    {\n        $view = Arr::first($views, function ($view) {\n            return $this->exists($view);\n        });\n\n        if (! $view) {\n            throw new InvalidArgumentException('None of the views in the given array exist.');\n        }\n\n        return $this->make($view, $data, $mergeData);\n    }\n\n    /**\n     * Get the rendered content of the view based on a given condition.\n     *\n     * @param  bool  $condition\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return string\n     */\n    public function renderWhen($condition, $view, $data = [], $mergeData = [])\n    {\n        if (! $condition) {\n            return '';\n        }\n\n        return $this->make($view, $this->parseData($data), $mergeData)->render();\n    }\n\n    /**\n     * Get the rendered content of the view based on the negation of a given condition.\n     *\n     * @param  bool  $condition\n     * @param  string  $view\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @param  array  $mergeData\n     * @return string\n     */\n    public function renderUnless($condition, $view, $data = [], $mergeData = [])\n    {\n        return $this->renderWhen(! $condition, $view, $data, $mergeData);\n    }\n\n    /**\n     * Get the rendered contents of a partial from a loop.\n     *\n     * @param  string  $view\n     * @param  array  $data\n     * @param  string  $iterator\n     * @param  string  $empty\n     * @return string\n     */\n    public function renderEach($view, $data, $iterator, $empty = 'raw|')\n    {\n        $result = '';\n\n        // If is actually data in the array, we will loop through the data and append\n        // an instance of the partial view to the final result HTML passing in the\n        // iterated value of this data array, allowing the views to access them.\n        if (count($data) > 0) {\n            foreach ($data as $key => $value) {\n                $result .= $this->make(\n                    $view, ['key' => $key, $iterator => $value]\n                )->render();\n            }\n        }\n\n        // If there is no data in the array, we will render the contents of the empty\n        // view. Alternatively, the \"empty view\" could be a raw string that begins\n        // with \"raw|\" for convenience and to let this know that it is a string.\n        else {\n            $result = str_starts_with($empty, 'raw|')\n                ? substr($empty, 4)\n                : $this->make($empty)->render();\n        }\n\n        return $result;\n    }\n\n    /**\n     * Normalize a view name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function normalizeName($name)\n    {\n        return $this->normalizedNameCache[$name] ??= ViewName::normalize($name);\n    }\n\n    /**\n     * Parse the given data into a raw array.\n     *\n     * @param  mixed  $data\n     * @return array\n     */\n    protected function parseData($data)\n    {\n        return $data instanceof Arrayable ? $data->toArray() : $data;\n    }\n\n    /**\n     * Create a new view instance from the given arguments.\n     *\n     * @param  string  $view\n     * @param  string  $path\n     * @param  \\Illuminate\\Contracts\\Support\\Arrayable|array  $data\n     * @return \\Illuminate\\Contracts\\View\\View\n     */\n    protected function viewInstance($view, $path, $data)\n    {\n        return new View($this, $this->getEngineFromPath($path), $view, $path, $data);\n    }\n\n    /**\n     * Determine if a given view exists.\n     *\n     * @param  string  $view\n     * @return bool\n     */\n    public function exists($view)\n    {\n        try {\n            $this->finder->find($view);\n        } catch (InvalidArgumentException) {\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Get the appropriate view engine for the given path.\n     *\n     * @param  string  $path\n     * @return \\Illuminate\\Contracts\\View\\Engine\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function getEngineFromPath($path)\n    {\n        if (isset($this->pathEngineCache[$path])) {\n            return $this->engines->resolve($this->pathEngineCache[$path]);\n        }\n\n        if (! $extension = $this->getExtension($path)) {\n            throw new InvalidArgumentException(\"Unrecognized extension in file: {$path}.\");\n        }\n\n        return $this->engines->resolve(\n            $this->pathEngineCache[$path] = $this->extensions[$extension]\n        );\n    }\n\n    /**\n     * Get the extension used by the view file.\n     *\n     * @param  string  $path\n     * @return string|null\n     */\n    protected function getExtension($path)\n    {\n        $extensions = array_keys($this->extensions);\n\n        return Arr::first($extensions, function ($value) use ($path) {\n            return str_ends_with($path, '.'.$value);\n        });\n    }\n\n    /**\n     * Add a piece of shared data to the environment.\n     *\n     * @param  array|string  $key\n     * @param  mixed  $value\n     * @return mixed\n     */\n    public function share($key, $value = null)\n    {\n        $keys = is_array($key) ? $key : [$key => $value];\n\n        foreach ($keys as $key => $value) {\n            $this->shared[$key] = $value;\n        }\n\n        return $value;\n    }\n\n    /**\n     * Increment the rendering counter.\n     *\n     * @return void\n     */\n    public function incrementRender()\n    {\n        $this->renderCount++;\n    }\n\n    /**\n     * Decrement the rendering counter.\n     *\n     * @return void\n     */\n    public function decrementRender()\n    {\n        $this->renderCount--;\n    }\n\n    /**\n     * Check if there are no active render operations.\n     *\n     * @return bool\n     */\n    public function doneRendering()\n    {\n        return $this->renderCount == 0;\n    }\n\n    /**\n     * Determine if the given once token has been rendered.\n     *\n     * @param  string  $id\n     * @return bool\n     */\n    public function hasRenderedOnce(string $id)\n    {\n        return isset($this->renderedOnce[$id]);\n    }\n\n    /**\n     * Mark the given once token as having been rendered.\n     *\n     * @param  string  $id\n     * @return void\n     */\n    public function markAsRenderedOnce(string $id)\n    {\n        $this->renderedOnce[$id] = true;\n    }\n\n    /**\n     * Add a location to the array of view locations.\n     *\n     * @param  string  $location\n     * @return void\n     */\n    public function addLocation($location)\n    {\n        $this->finder->addLocation($location);\n    }\n\n    /**\n     * Prepend a location to the array of view locations.\n     *\n     * @param  string  $location\n     * @return void\n     */\n    public function prependLocation($location)\n    {\n        $this->finder->prependLocation($location);\n    }\n\n    /**\n     * Add a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return $this\n     */\n    public function addNamespace($namespace, $hints)\n    {\n        $this->finder->addNamespace($namespace, $hints);\n\n        return $this;\n    }\n\n    /**\n     * Prepend a new namespace to the loader.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return $this\n     */\n    public function prependNamespace($namespace, $hints)\n    {\n        $this->finder->prependNamespace($namespace, $hints);\n\n        return $this;\n    }\n\n    /**\n     * Replace the namespace hints for the given namespace.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return $this\n     */\n    public function replaceNamespace($namespace, $hints)\n    {\n        $this->finder->replaceNamespace($namespace, $hints);\n\n        return $this;\n    }\n\n    /**\n     * Register a valid view extension and its engine.\n     *\n     * @param  string  $extension\n     * @param  string  $engine\n     * @param  \\Closure|null  $resolver\n     * @return void\n     */\n    public function addExtension($extension, $engine, $resolver = null)\n    {\n        $this->finder->addExtension($extension);\n\n        if (isset($resolver)) {\n            $this->engines->register($engine, $resolver);\n        }\n\n        unset($this->extensions[$extension]);\n\n        $this->extensions = array_merge([$extension => $engine], $this->extensions);\n\n        $this->pathEngineCache = [];\n    }\n\n    /**\n     * Flush all of the factory state like sections and stacks.\n     *\n     * @return void\n     */\n    public function flushState()\n    {\n        $this->renderCount = 0;\n        $this->renderedOnce = [];\n\n        $this->flushSections();\n        $this->flushStacks();\n        $this->flushComponents();\n        $this->flushFragments();\n    }\n\n    /**\n     * Flush all of the section contents if done rendering.\n     *\n     * @return void\n     */\n    public function flushStateIfDoneRendering()\n    {\n        if ($this->doneRendering()) {\n            $this->flushState();\n        }\n    }\n\n    /**\n     * Get the extension to engine bindings.\n     *\n     * @return array\n     */\n    public function getExtensions()\n    {\n        return $this->extensions;\n    }\n\n    /**\n     * Get the engine resolver instance.\n     *\n     * @return \\Illuminate\\View\\Engines\\EngineResolver\n     */\n    public function getEngineResolver()\n    {\n        return $this->engines;\n    }\n\n    /**\n     * Get the view finder instance.\n     *\n     * @return \\Illuminate\\View\\ViewFinderInterface\n     */\n    public function getFinder()\n    {\n        return $this->finder;\n    }\n\n    /**\n     * Set the view finder instance.\n     *\n     * @param  \\Illuminate\\View\\ViewFinderInterface  $finder\n     * @return void\n     */\n    public function setFinder(ViewFinderInterface $finder)\n    {\n        $this->finder = $finder;\n    }\n\n    /**\n     * Flush the cache of views located by the finder.\n     *\n     * @return void\n     */\n    public function flushFinderCache()\n    {\n        $this->getFinder()->flush();\n    }\n\n    /**\n     * Get the event dispatcher instance.\n     *\n     * @return \\Illuminate\\Contracts\\Events\\Dispatcher\n     */\n    public function getDispatcher()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Set the event dispatcher instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return void\n     */\n    public function setDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    /**\n     * Get the IoC container instance.\n     *\n     * @return \\Illuminate\\Contracts\\Container\\Container\n     */\n    public function getContainer()\n    {\n        return $this->container;\n    }\n\n    /**\n     * Set the IoC container instance.\n     *\n     * @param  \\Illuminate\\Contracts\\Container\\Container  $container\n     * @return void\n     */\n    public function setContainer(Container $container)\n    {\n        $this->container = $container;\n    }\n\n    /**\n     * Get an item from the shared data.\n     *\n     * @param  string  $key\n     * @param  mixed  $default\n     * @return mixed\n     */\n    public function shared($key, $default = null)\n    {\n        return Arr::get($this->shared, $key, $default);\n    }\n\n    /**\n     * Get all of the shared data for the environment.\n     *\n     * @return array\n     */\n    public function getShared()\n    {\n        return $this->shared;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/FileViewFinder.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse InvalidArgumentException;\n\nclass FileViewFinder implements ViewFinderInterface\n{\n    /**\n     * The filesystem instance.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    /**\n     * The array of active view paths.\n     *\n     * @var string[]\n     */\n    protected $paths;\n\n    /**\n     * The array of views that have been located.\n     *\n     * @var array<string, string>\n     */\n    protected $views = [];\n\n    /**\n     * The namespace to file path hints.\n     *\n     * @var array<string, array>\n     */\n    protected $hints = [];\n\n    /**\n     * Register a view extension with the finder.\n     *\n     * @var string[]\n     */\n    protected $extensions = ['blade.php', 'php', 'css', 'html'];\n\n    /**\n     * Create a new file view loader instance.\n     *\n     * @param  \\Illuminate\\Filesystem\\Filesystem  $files\n     * @param  string[]  $paths\n     * @param  string[]|null  $extensions\n     */\n    public function __construct(Filesystem $files, array $paths, ?array $extensions = null)\n    {\n        $this->files = $files;\n        $this->paths = array_map($this->resolvePath(...), $paths);\n\n        if (isset($extensions)) {\n            $this->extensions = $extensions;\n        }\n    }\n\n    /**\n     * Get the fully-qualified location of the view.\n     *\n     * @param  string  $view\n     * @return string\n     */\n    public function find($view)\n    {\n        if (isset($this->views[$view])) {\n            return $this->views[$view];\n        }\n\n        if ($this->hasHintInformation($view = trim($view))) {\n            return $this->views[$view] = $this->findNamespacedView($view);\n        }\n\n        return $this->views[$view] = $this->findInPaths($view, $this->paths);\n    }\n\n    /**\n     * Get the path to a template with a named path.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    protected function findNamespacedView($name)\n    {\n        [$namespace, $view] = $this->parseNamespaceSegments($name);\n\n        return $this->findInPaths($view, $this->hints[$namespace]);\n    }\n\n    /**\n     * Get the segments of a template with a named path.\n     *\n     * @param  string  $name\n     * @return string[]\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function parseNamespaceSegments($name)\n    {\n        $segments = explode(static::HINT_PATH_DELIMITER, $name);\n\n        if (count($segments) !== 2) {\n            throw new InvalidArgumentException(\"View [{$name}] has an invalid name.\");\n        }\n\n        if (! isset($this->hints[$segments[0]])) {\n            throw new InvalidArgumentException(\"No hint path defined for [{$segments[0]}].\");\n        }\n\n        return $segments;\n    }\n\n    /**\n     * Find the given view in the list of paths.\n     *\n     * @param  string  $name\n     * @param  string|string[]  $paths\n     * @return string\n     *\n     * @throws \\InvalidArgumentException\n     */\n    protected function findInPaths($name, $paths)\n    {\n        foreach ((array) $paths as $path) {\n            foreach ($this->getPossibleViewFiles($name) as $file) {\n                $viewPath = $path.'/'.$file;\n\n                if (strlen($viewPath) < (PHP_MAXPATHLEN - 1) && $this->files->exists($viewPath)) {\n                    return $viewPath;\n                }\n            }\n        }\n\n        throw new InvalidArgumentException(\"View [{$name}] not found.\");\n    }\n\n    /**\n     * Get an array of possible view files.\n     *\n     * @param  string  $name\n     * @return string[]\n     */\n    protected function getPossibleViewFiles($name)\n    {\n        return array_map(fn ($extension) => str_replace('.', '/', $name).'.'.$extension, $this->extensions);\n    }\n\n    /**\n     * Add a location to the finder.\n     *\n     * @param  string  $location\n     * @return void\n     */\n    public function addLocation($location)\n    {\n        $this->paths[] = $this->resolvePath($location);\n    }\n\n    /**\n     * Prepend a location to the finder.\n     *\n     * @param  string  $location\n     * @return void\n     */\n    public function prependLocation($location)\n    {\n        array_unshift($this->paths, $this->resolvePath($location));\n    }\n\n    /**\n     * Resolve the path.\n     *\n     * @param  string  $path\n     * @return string\n     */\n    protected function resolvePath($path)\n    {\n        return realpath($path) ?: $path;\n    }\n\n    /**\n     * Add a namespace hint to the finder.\n     *\n     * @param  string  $namespace\n     * @param  string|string[]  $hints\n     * @return void\n     */\n    public function addNamespace($namespace, $hints)\n    {\n        $hints = (array) $hints;\n\n        if (isset($this->hints[$namespace])) {\n            $hints = array_merge($this->hints[$namespace], $hints);\n        }\n\n        $this->hints[$namespace] = $hints;\n    }\n\n    /**\n     * Prepend a namespace hint to the finder.\n     *\n     * @param  string  $namespace\n     * @param  string|string[]  $hints\n     * @return void\n     */\n    public function prependNamespace($namespace, $hints)\n    {\n        $hints = (array) $hints;\n\n        if (isset($this->hints[$namespace])) {\n            $hints = array_merge($hints, $this->hints[$namespace]);\n        }\n\n        $this->hints[$namespace] = $hints;\n    }\n\n    /**\n     * Replace the namespace hints for the given namespace.\n     *\n     * @param  string  $namespace\n     * @param  string|string[]  $hints\n     * @return void\n     */\n    public function replaceNamespace($namespace, $hints)\n    {\n        $this->hints[$namespace] = (array) $hints;\n    }\n\n    /**\n     * Register an extension with the view finder.\n     *\n     * @param  string  $extension\n     * @return void\n     */\n    public function addExtension($extension)\n    {\n        if (($index = array_search($extension, $this->extensions)) !== false) {\n            unset($this->extensions[$index]);\n        }\n\n        array_unshift($this->extensions, $extension);\n    }\n\n    /**\n     * Returns whether or not the view name has any hint information.\n     *\n     * @param  string  $name\n     * @return bool\n     */\n    public function hasHintInformation($name)\n    {\n        return strpos($name, static::HINT_PATH_DELIMITER) > 0;\n    }\n\n    /**\n     * Flush the cache of located views.\n     *\n     * @return void\n     */\n    public function flush()\n    {\n        $this->views = [];\n    }\n\n    /**\n     * Get the filesystem instance.\n     *\n     * @return \\Illuminate\\Filesystem\\Filesystem\n     */\n    public function getFilesystem()\n    {\n        return $this->files;\n    }\n\n    /**\n     * Set the active view paths.\n     *\n     * @param  string[]  $paths\n     * @return $this\n     */\n    public function setPaths($paths)\n    {\n        $this->paths = $paths;\n\n        return $this;\n    }\n\n    /**\n     * Get the active view paths.\n     *\n     * @return string[]\n     */\n    public function getPaths()\n    {\n        return $this->paths;\n    }\n\n    /**\n     * Get the views that have been located.\n     *\n     * @return array<string, string>\n     */\n    public function getViews()\n    {\n        return $this->views;\n    }\n\n    /**\n     * Get the namespace to file path hints.\n     *\n     * @return array<string, array>\n     */\n    public function getHints()\n    {\n        return $this->hints;\n    }\n\n    /**\n     * Get registered extensions.\n     *\n     * @return string[]\n     */\n    public function getExtensions()\n    {\n        return $this->extensions;\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/InvokableComponentVariable.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse ArrayIterator;\nuse Closure;\nuse Illuminate\\Contracts\\Support\\DeferringDisplayableValue;\nuse Illuminate\\Support\\Enumerable;\nuse IteratorAggregate;\nuse Stringable;\nuse Traversable;\n\nclass InvokableComponentVariable implements DeferringDisplayableValue, IteratorAggregate, Stringable\n{\n    /**\n     * The callable instance to resolve the variable value.\n     *\n     * @var \\Closure\n     */\n    protected $callable;\n\n    /**\n     * Create a new variable instance.\n     *\n     * @param  \\Closure  $callable\n     */\n    public function __construct(Closure $callable)\n    {\n        $this->callable = $callable;\n    }\n\n    /**\n     * Resolve the displayable value that the class is deferring.\n     *\n     * @return \\Illuminate\\Contracts\\Support\\Htmlable|string\n     */\n    public function resolveDisplayableValue()\n    {\n        return $this->__invoke();\n    }\n\n    /**\n     * Get an iterator instance for the variable.\n     *\n     * @return \\ArrayIterator\n     */\n    public function getIterator(): Traversable\n    {\n        $result = $this->__invoke();\n\n        return new ArrayIterator($result instanceof Enumerable ? $result->all() : $result);\n    }\n\n    /**\n     * Dynamically proxy attribute access to the variable.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function __get($key)\n    {\n        return $this->__invoke()->{$key};\n    }\n\n    /**\n     * Dynamically proxy method access to the variable.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return mixed\n     */\n    public function __call($method, $parameters)\n    {\n        return $this->__invoke()->{$method}(...$parameters);\n    }\n\n    /**\n     * Resolve the variable.\n     *\n     * @return mixed\n     */\n    public function __invoke()\n    {\n        return call_user_func($this->callable);\n    }\n\n    /**\n     * Resolve the variable as a string.\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return (string) $this->__invoke();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) Taylor Otwell\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/Illuminate/View/Middleware/ShareErrorsFromSession.php",
    "content": "<?php\n\nnamespace Illuminate\\View\\Middleware;\n\nuse Closure;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Support\\ViewErrorBag;\n\nclass ShareErrorsFromSession\n{\n    /**\n     * The view factory implementation.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Factory\n     */\n    protected $view;\n\n    /**\n     * Create a new error binder instance.\n     *\n     * @param  \\Illuminate\\Contracts\\View\\Factory  $view\n     */\n    public function __construct(ViewFactory $view)\n    {\n        $this->view = $view;\n    }\n\n    /**\n     * Handle an incoming request.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @param  \\Closure  $next\n     * @return mixed\n     */\n    public function handle($request, Closure $next)\n    {\n        // If the current session has an \"errors\" variable bound to it, we will share\n        // its value with all view instances so the views can easily access errors\n        // without having to bind. An empty bag is set when there aren't errors.\n        $this->view->share(\n            'errors', $request->session()->get('errors') ?: new ViewErrorBag\n        );\n\n        // Putting the errors in the view for every view allows the developer to just\n        // assume that some errors are always available, which is convenient since\n        // they don't have to continually run checks for the presence of errors.\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/View.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse ArrayAccess;\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\Support\\MessageProvider;\nuse Illuminate\\Contracts\\Support\\Renderable;\nuse Illuminate\\Contracts\\View\\Engine;\nuse Illuminate\\Contracts\\View\\View as ViewContract;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Stringable;\nuse Throwable;\n\nclass View implements ArrayAccess, Htmlable, Stringable, ViewContract\n{\n    use Macroable {\n        __call as macroCall;\n    }\n\n    /**\n     * The view factory instance.\n     *\n     * @var \\Illuminate\\View\\Factory\n     */\n    protected $factory;\n\n    /**\n     * The engine implementation.\n     *\n     * @var \\Illuminate\\Contracts\\View\\Engine\n     */\n    protected $engine;\n\n    /**\n     * The name of the view.\n     *\n     * @var string\n     */\n    protected $view;\n\n    /**\n     * The array of view data.\n     *\n     * @var array\n     */\n    protected $data;\n\n    /**\n     * The path to the view file.\n     *\n     * @var string\n     */\n    protected $path;\n\n    /**\n     * Create a new view instance.\n     *\n     * @param  \\Illuminate\\View\\Factory  $factory\n     * @param  \\Illuminate\\Contracts\\View\\Engine  $engine\n     * @param  string  $view\n     * @param  string  $path\n     * @param  mixed  $data\n     */\n    public function __construct(Factory $factory, Engine $engine, $view, $path, $data = [])\n    {\n        $this->view = $view;\n        $this->path = $path;\n        $this->engine = $engine;\n        $this->factory = $factory;\n\n        $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;\n    }\n\n    /**\n     * Get the evaluated contents of a given fragment.\n     *\n     * @param  string  $fragment\n     * @return string\n     */\n    public function fragment($fragment)\n    {\n        return $this->render(function () use ($fragment) {\n            return $this->factory->getFragment($fragment);\n        });\n    }\n\n    /**\n     * Get the evaluated contents for a given array of fragments or return all fragments.\n     *\n     * @param  array|null  $fragments\n     * @return string\n     */\n    public function fragments(?array $fragments = null)\n    {\n        return is_null($fragments)\n            ? $this->allFragments()\n            : (new Collection($fragments))->map(fn ($f) => $this->fragment($f))->implode('');\n    }\n\n    /**\n     * Get the evaluated contents of a given fragment if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  string  $fragment\n     * @return string\n     */\n    public function fragmentIf($boolean, $fragment)\n    {\n        if (value($boolean)) {\n            return $this->fragment($fragment);\n        }\n\n        return $this->render();\n    }\n\n    /**\n     * Get the evaluated contents for a given array of fragments if the given condition is true.\n     *\n     * @param  bool  $boolean\n     * @param  array|null  $fragments\n     * @return string\n     */\n    public function fragmentsIf($boolean, ?array $fragments = null)\n    {\n        if (value($boolean)) {\n            return $this->fragments($fragments);\n        }\n\n        return $this->render();\n    }\n\n    /**\n     * Get all fragments as a single string.\n     *\n     * @return string\n     */\n    protected function allFragments()\n    {\n        return (new Collection($this->render(fn () => $this->factory->getFragments())))->implode('');\n    }\n\n    /**\n     * Get the string contents of the view.\n     *\n     * @param  callable|null  $callback\n     * @return string\n     *\n     * @throws \\Throwable\n     */\n    public function render(?callable $callback = null)\n    {\n        try {\n            $contents = $this->renderContents();\n\n            $response = isset($callback) ? $callback($this, $contents) : null;\n\n            // Once we have the contents of the view, we will flush the sections if we are\n            // done rendering all views so that there is nothing left hanging over when\n            // another view gets rendered in the future by the application developer.\n            $this->factory->flushStateIfDoneRendering();\n\n            return ! is_null($response) ? $response : $contents;\n        } catch (Throwable $e) {\n            $this->factory->flushState();\n\n            throw $e;\n        }\n    }\n\n    /**\n     * Get the contents of the view instance.\n     *\n     * @return string\n     */\n    protected function renderContents()\n    {\n        // We will keep track of the number of views being rendered so we can flush\n        // the section after the complete rendering operation is done. This will\n        // clear out the sections for any separate views that may be rendered.\n        $this->factory->incrementRender();\n\n        $this->factory->callComposer($this);\n\n        $contents = $this->getContents();\n\n        // Once we've finished rendering the view, we'll decrement the render count\n        // so that each section gets flushed out next time a view is created and\n        // no old sections are staying around in the memory of an environment.\n        $this->factory->decrementRender();\n\n        return $contents;\n    }\n\n    /**\n     * Get the evaluated contents of the view.\n     *\n     * @return string\n     */\n    protected function getContents()\n    {\n        return $this->engine->get($this->path, $this->gatherData());\n    }\n\n    /**\n     * Get the data bound to the view instance.\n     *\n     * @return array\n     */\n    public function gatherData()\n    {\n        $data = array_merge($this->factory->getShared(), $this->data);\n\n        foreach ($data as $key => $value) {\n            if ($value instanceof Renderable) {\n                $data[$key] = $value->render();\n            }\n        }\n\n        return $data;\n    }\n\n    /**\n     * Get the sections of the rendered view.\n     *\n     * @return array\n     *\n     * @throws \\Throwable\n     */\n    public function renderSections()\n    {\n        return $this->render(function () {\n            return $this->factory->getSections();\n        });\n    }\n\n    /**\n     * Add a piece of data to the view.\n     *\n     * @param  string|array  $key\n     * @param  mixed  $value\n     * @return $this\n     */\n    public function with($key, $value = null)\n    {\n        if (is_array($key)) {\n            $this->data = array_merge($this->data, $key);\n        } else {\n            $this->data[$key] = $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * Add a view instance to the view data.\n     *\n     * @param  string  $key\n     * @param  string  $view\n     * @param  array  $data\n     * @return $this\n     */\n    public function nest($key, $view, array $data = [])\n    {\n        return $this->with($key, $this->factory->make($view, $data));\n    }\n\n    /**\n     * Add validation errors to the view.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array|string  $provider\n     * @param  string  $bag\n     * @return $this\n     */\n    public function withErrors($provider, $bag = 'default')\n    {\n        return $this->with('errors', (new ViewErrorBag)->put(\n            $bag, $this->formatErrors($provider)\n        ));\n    }\n\n    /**\n     * Parse the given errors into an appropriate value.\n     *\n     * @param  \\Illuminate\\Contracts\\Support\\MessageProvider|array|string  $provider\n     * @return \\Illuminate\\Support\\MessageBag\n     */\n    protected function formatErrors($provider)\n    {\n        return $provider instanceof MessageProvider\n            ? $provider->getMessageBag()\n            : new MessageBag((array) $provider);\n    }\n\n    /**\n     * Get the name of the view.\n     *\n     * @return string\n     */\n    public function name()\n    {\n        return $this->getName();\n    }\n\n    /**\n     * Get the name of the view.\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->view;\n    }\n\n    /**\n     * Get the array of view data.\n     *\n     * @return array\n     */\n    public function getData()\n    {\n        return $this->data;\n    }\n\n    /**\n     * Get the path to the view file.\n     *\n     * @return string\n     */\n    public function getPath()\n    {\n        return $this->path;\n    }\n\n    /**\n     * Set the path to the view.\n     *\n     * @param  string  $path\n     * @return void\n     */\n    public function setPath($path)\n    {\n        $this->path = $path;\n    }\n\n    /**\n     * Get the view factory instance.\n     *\n     * @return \\Illuminate\\View\\Factory\n     */\n    public function getFactory()\n    {\n        return $this->factory;\n    }\n\n    /**\n     * Get the view's rendering engine.\n     *\n     * @return \\Illuminate\\Contracts\\View\\Engine\n     */\n    public function getEngine()\n    {\n        return $this->engine;\n    }\n\n    /**\n     * Determine if a piece of data is bound.\n     *\n     * @param  string  $offset\n     * @return bool\n     */\n    public function offsetExists($offset): bool\n    {\n        return array_key_exists($offset, $this->data);\n    }\n\n    /**\n     * Get a piece of bound data to the view.\n     *\n     * @param  string  $offset\n     * @return mixed\n     */\n    public function offsetGet($offset): mixed\n    {\n        return $this->data[$offset];\n    }\n\n    /**\n     * Set a piece of data on the view.\n     *\n     * @param  string  $offset\n     * @param  mixed  $value\n     * @return void\n     */\n    public function offsetSet($offset, $value): void\n    {\n        $this->with($offset, $value);\n    }\n\n    /**\n     * Unset a piece of data from the view.\n     *\n     * @param  string  $offset\n     * @return void\n     */\n    public function offsetUnset($offset): void\n    {\n        unset($this->data[$offset]);\n    }\n\n    /**\n     * Get a piece of data from the view.\n     *\n     * @param  string  $key\n     * @return mixed\n     */\n    public function &__get($key)\n    {\n        return $this->data[$key];\n    }\n\n    /**\n     * Set a piece of data on the view.\n     *\n     * @param  string  $key\n     * @param  mixed  $value\n     * @return void\n     */\n    public function __set($key, $value)\n    {\n        $this->with($key, $value);\n    }\n\n    /**\n     * Check if a piece of data is bound to the view.\n     *\n     * @param  string  $key\n     * @return bool\n     */\n    public function __isset($key)\n    {\n        return isset($this->data[$key]);\n    }\n\n    /**\n     * Remove a piece of bound data from the view.\n     *\n     * @param  string  $key\n     * @return void\n     */\n    public function __unset($key)\n    {\n        unset($this->data[$key]);\n    }\n\n    /**\n     * Dynamically bind parameters to the view.\n     *\n     * @param  string  $method\n     * @param  array  $parameters\n     * @return \\Illuminate\\View\\View\n     *\n     * @throws \\BadMethodCallException\n     */\n    public function __call($method, $parameters)\n    {\n        if (static::hasMacro($method)) {\n            return $this->macroCall($method, $parameters);\n        }\n\n        if (! str_starts_with($method, 'with')) {\n            throw new BadMethodCallException(sprintf(\n                'Method %s::%s does not exist.', static::class, $method\n            ));\n        }\n\n        return $this->with(Str::camel(substr($method, 4)), $parameters[0]);\n    }\n\n    /**\n     * Get content as a string of HTML.\n     *\n     * @return string\n     */\n    public function toHtml()\n    {\n        return $this->render();\n    }\n\n    /**\n     * Get the string contents of the view.\n     *\n     * @return string\n     *\n     * @throws \\Throwable\n     */\n    public function __toString()\n    {\n        return $this->render();\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/ViewException.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse ErrorException;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Reflector;\n\nclass ViewException extends ErrorException\n{\n    /**\n     * Report the exception.\n     *\n     * @return bool|null\n     */\n    public function report()\n    {\n        $exception = $this->getPrevious();\n\n        if (Reflector::isCallable($reportCallable = [$exception, 'report'])) {\n            return Container::getInstance()->call($reportCallable);\n        }\n\n        return false;\n    }\n\n    /**\n     * Render the exception into an HTTP response.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Http\\Response|null\n     */\n    public function render($request)\n    {\n        $exception = $this->getPrevious();\n\n        if ($exception && method_exists($exception, 'render')) {\n            return $exception->render($request);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/ViewFinderInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\ninterface ViewFinderInterface\n{\n    /**\n     * Hint path delimiter value.\n     *\n     * @var string\n     */\n    const HINT_PATH_DELIMITER = '::';\n\n    /**\n     * Get the fully-qualified location of the view.\n     *\n     * @param  string  $view\n     * @return string\n     */\n    public function find($view);\n\n    /**\n     * Add a location to the finder.\n     *\n     * @param  string  $location\n     * @return void\n     */\n    public function addLocation($location);\n\n    /**\n     * Add a namespace hint to the finder.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return void\n     */\n    public function addNamespace($namespace, $hints);\n\n    /**\n     * Prepend a namespace hint to the finder.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return void\n     */\n    public function prependNamespace($namespace, $hints);\n\n    /**\n     * Replace the namespace hints for the given namespace.\n     *\n     * @param  string  $namespace\n     * @param  string|array  $hints\n     * @return void\n     */\n    public function replaceNamespace($namespace, $hints);\n\n    /**\n     * Add a valid view extension to the finder.\n     *\n     * @param  string  $extension\n     * @return void\n     */\n    public function addExtension($extension);\n\n    /**\n     * Flush the cache of located views.\n     *\n     * @return void\n     */\n    public function flush();\n}\n"
  },
  {
    "path": "src/Illuminate/View/ViewName.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nclass ViewName\n{\n    /**\n     * Normalize the given view name.\n     *\n     * @param  string  $name\n     * @return string\n     */\n    public static function normalize($name)\n    {\n        $delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;\n\n        if (! str_contains($name, $delimiter)) {\n            return str_replace('/', '.', $name);\n        }\n\n        [$namespace, $name] = explode($delimiter, $name);\n\n        return $namespace.$delimiter.str_replace('/', '.', $name);\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/ViewServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\View;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\View\\Compilers\\BladeCompiler;\nuse Illuminate\\View\\Engines\\CompilerEngine;\nuse Illuminate\\View\\Engines\\EngineResolver;\nuse Illuminate\\View\\Engines\\FileEngine;\nuse Illuminate\\View\\Engines\\PhpEngine;\n\nclass ViewServiceProvider extends ServiceProvider\n{\n    /**\n     * Register the service provider.\n     *\n     * @return void\n     */\n    public function register()\n    {\n        $this->registerFactory();\n        $this->registerViewFinder();\n        $this->registerBladeCompiler();\n        $this->registerEngineResolver();\n\n        $this->app->terminating(static function () {\n            Component::flushCache();\n        });\n    }\n\n    /**\n     * Register the view environment.\n     *\n     * @return void\n     */\n    public function registerFactory()\n    {\n        $this->app->singleton('view', function ($app) {\n            // Next we need to grab the engine resolver instance that will be used by the\n            // environment. The resolver will be used by an environment to get each of\n            // the various engine implementations such as plain PHP or Blade engine.\n            $resolver = $app['view.engine.resolver'];\n\n            $finder = $app['view.finder'];\n\n            $factory = $this->createFactory($resolver, $finder, $app['events']);\n\n            // We will also set the container instance on this view environment since the\n            // view composers may be classes registered in the container, which allows\n            // for great testable, flexible composers for the application developer.\n            $factory->setContainer($app);\n\n            $factory->share('app', $app);\n\n            $app->terminating(static function () {\n                Component::forgetFactory();\n            });\n\n            return $factory;\n        });\n    }\n\n    /**\n     * Create a new Factory Instance.\n     *\n     * @param  \\Illuminate\\View\\Engines\\EngineResolver  $resolver\n     * @param  \\Illuminate\\View\\ViewFinderInterface  $finder\n     * @param  \\Illuminate\\Contracts\\Events\\Dispatcher  $events\n     * @return \\Illuminate\\View\\Factory\n     */\n    protected function createFactory($resolver, $finder, $events)\n    {\n        return new Factory($resolver, $finder, $events);\n    }\n\n    /**\n     * Register the view finder implementation.\n     *\n     * @return void\n     */\n    public function registerViewFinder()\n    {\n        $this->app->bind('view.finder', function ($app) {\n            return new FileViewFinder($app['files'], $app['config']['view.paths']);\n        });\n    }\n\n    /**\n     * Register the Blade compiler implementation.\n     *\n     * @return void\n     */\n    public function registerBladeCompiler()\n    {\n        $this->app->singleton('blade.compiler', function ($app) {\n            return tap(new BladeCompiler(\n                $app['files'],\n                $app['config']['view.compiled'],\n                $app['config']->get('view.relative_hash', false) ? $app->basePath() : '',\n                $app['config']->get('view.cache', true),\n                $app['config']->get('view.compiled_extension', 'php'),\n                $app['config']->get('view.check_cache_timestamps', true),\n            ), function ($blade) {\n                $blade->component('dynamic-component', DynamicComponent::class);\n            });\n        });\n    }\n\n    /**\n     * Register the engine resolver instance.\n     *\n     * @return void\n     */\n    public function registerEngineResolver()\n    {\n        $this->app->singleton('view.engine.resolver', function () {\n            $resolver = new EngineResolver;\n\n            // Next, we will register the various view engines with the resolver so that the\n            // environment will resolve the engines needed for various views based on the\n            // extension of view file. We call a method for each of the view's engines.\n            foreach (['file', 'php', 'blade'] as $engine) {\n                $this->{'register'.ucfirst($engine).'Engine'}($resolver);\n            }\n\n            return $resolver;\n        });\n    }\n\n    /**\n     * Register the file engine implementation.\n     *\n     * @param  \\Illuminate\\View\\Engines\\EngineResolver  $resolver\n     * @return void\n     */\n    public function registerFileEngine($resolver)\n    {\n        $resolver->register('file', function () {\n            return new FileEngine(Container::getInstance()->make('files'));\n        });\n    }\n\n    /**\n     * Register the PHP engine implementation.\n     *\n     * @param  \\Illuminate\\View\\Engines\\EngineResolver  $resolver\n     * @return void\n     */\n    public function registerPhpEngine($resolver)\n    {\n        $resolver->register('php', function () {\n            return new PhpEngine(Container::getInstance()->make('files'));\n        });\n    }\n\n    /**\n     * Register the Blade engine implementation.\n     *\n     * @param  \\Illuminate\\View\\Engines\\EngineResolver  $resolver\n     * @return void\n     */\n    public function registerBladeEngine($resolver)\n    {\n        $resolver->register('blade', function () {\n            $app = Container::getInstance();\n\n            $compiler = new CompilerEngine(\n                $app->make('blade.compiler'),\n                $app->make('files'),\n            );\n\n            $app->terminating(static function () use ($compiler) {\n                $compiler->forgetCompiledOrNotExpired();\n            });\n\n            return $compiler;\n        });\n    }\n}\n"
  },
  {
    "path": "src/Illuminate/View/composer.json",
    "content": "{\n    \"name\": \"illuminate/view\",\n    \"description\": \"The Illuminate View package.\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Taylor Otwell\",\n            \"email\": \"taylor@laravel.com\"\n        }\n    ],\n    \"homepage\": \"https://laravel.com\",\n    \"support\": {\n        \"issues\": \"https://github.com/laravel/framework/issues\",\n        \"source\": \"https://github.com/laravel/framework\"\n    },\n    \"require\": {\n        \"php\": \"^8.3\",\n        \"ext-tokenizer\": \"*\",\n        \"illuminate/collections\": \"^13.0\",\n        \"illuminate/container\": \"^13.0\",\n        \"illuminate/contracts\": \"^13.0\",\n        \"illuminate/events\": \"^13.0\",\n        \"illuminate/filesystem\": \"^13.0\",\n        \"illuminate/macroable\": \"^13.0\",\n        \"illuminate/support\": \"^13.0\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"autoload\": {\n        \"psr-4\": {\n            \"Illuminate\\\\View\\\\\": \"\"\n        }\n    },\n    \"config\": {\n        \"sort-packages\": true\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"13.0.x-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "tests/AfterEachTestExtension.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests;\n\nuse PHPUnit\\Runner\\Extension\\Extension;\nuse PHPUnit\\Runner\\Extension\\Facade;\nuse PHPUnit\\Runner\\Extension\\ParameterCollection;\nuse PHPUnit\\TextUI\\Configuration\\Configuration;\n\nfinal class AfterEachTestExtension implements Extension\n{\n    public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void\n    {\n        $facade->registerSubscriber(new AfterEachTestSubscriber);\n    }\n}\n"
  },
  {
    "path": "tests/AfterEachTestSubscriber.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests;\n\nuse PHPUnit\\Event\\Test\\AfterTestMethodFinished;\nuse PHPUnit\\Event\\Test\\AfterTestMethodFinishedSubscriber;\n\nfinal class AfterEachTestSubscriber implements AfterTestMethodFinishedSubscriber\n{\n    public function notify(AfterTestMethodFinished $event): void\n    {\n        if (class_exists(\\Mockery::class)) {\n            \\Mockery::close();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthAccessGateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Gate;\nuse Illuminate\\Auth\\Access\\HandlesAuthorization;\nuse Illuminate\\Auth\\Access\\Response;\nuse Illuminate\\Container\\Container;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\ninclude_once 'Enums.php';\n\nclass AuthAccessGateTest extends TestCase\n{\n    public function testBasicClosuresCanBeDefined()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function ($user) {\n            return true;\n        });\n        $gate->define('bar', function ($user) {\n            return false;\n        });\n\n        $this->assertTrue($gate->check('foo'));\n        $this->assertFalse($gate->check('bar'));\n    }\n\n    public function testBeforeCanTakeAnArrayCallbackAsObject()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->before([new AccessGateTestBeforeCallback, 'allowEverything']);\n\n        $this->assertTrue($gate->check('anything'));\n    }\n\n    public function testBeforeCanTakeAnArrayCallbackAsObjectStatic()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->before([new AccessGateTestBeforeCallback, 'allowEverythingStatically']);\n\n        $this->assertTrue($gate->check('anything'));\n    }\n\n    public function testBeforeCanTakeAnArrayCallbackWithStaticMethod()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->before([AccessGateTestBeforeCallback::class, 'allowEverythingStatically']);\n\n        $this->assertTrue($gate->check('anything'));\n    }\n\n    public function testBeforeCanAllowGuests()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->before(function (?stdClass $user) {\n            return true;\n        });\n\n        $this->assertTrue($gate->check('anything'));\n    }\n\n    public function testAfterCanAllowGuests()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->after(function (?stdClass $user) {\n            return true;\n        });\n\n        $this->assertTrue($gate->check('anything'));\n    }\n\n    public function testClosuresCanAllowGuestUsers()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->define('foo', function (?stdClass $user) {\n            return true;\n        });\n\n        $gate->define('bar', function (stdClass $user) {\n            return false;\n        });\n\n        $this->assertTrue($gate->check('foo'));\n        $this->assertFalse($gate->check('bar'));\n    }\n\n    public function testPoliciesCanAllowGuests()\n    {\n        unset($_SERVER['__laravel.testBefore']);\n\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyThatAllowsGuests::class);\n\n        $this->assertTrue($gate->check('edit', new AccessGateTestDummy));\n        $this->assertFalse($gate->check('update', new AccessGateTestDummy));\n        $this->assertTrue($_SERVER['__laravel.testBefore']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyThatAllowsGuests::class);\n\n        $this->assertTrue($gate->check('edit', new AccessGateTestDummy));\n        $this->assertTrue($gate->check('update', new AccessGateTestDummy));\n\n        unset($_SERVER['__laravel.testBefore']);\n    }\n\n    public function testPolicyBeforeNotCalledWithGuestsIfItDoesntAllowThem()\n    {\n        $_SERVER['__laravel.testBefore'] = false;\n\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithNonGuestBefore::class);\n\n        $this->assertTrue($gate->check('edit', new AccessGateTestDummy));\n        $this->assertFalse($gate->check('update', new AccessGateTestDummy));\n        $this->assertFalse($_SERVER['__laravel.testBefore']);\n\n        unset($_SERVER['__laravel.testBefore']);\n    }\n\n    public function testBeforeAndAfterCallbacksCanAllowGuests()\n    {\n        $_SERVER['__laravel.gateBefore'] = false;\n        $_SERVER['__laravel.gateBefore2'] = false;\n        $_SERVER['__laravel.gateAfter'] = false;\n        $_SERVER['__laravel.gateAfter2'] = false;\n\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->before(function (?stdClass $user) {\n            $_SERVER['__laravel.gateBefore'] = true;\n        });\n\n        $gate->after(function (?stdClass $user) {\n            $_SERVER['__laravel.gateAfter'] = true;\n        });\n\n        $gate->before(function (stdClass $user) {\n            $_SERVER['__laravel.gateBefore2'] = true;\n        });\n\n        $gate->after(function (stdClass $user) {\n            $_SERVER['__laravel.gateAfter2'] = true;\n        });\n\n        $gate->define('foo', function ($user = null) {\n            return true;\n        });\n\n        $this->assertTrue($gate->check('foo'));\n\n        $this->assertTrue($_SERVER['__laravel.gateBefore']);\n        $this->assertFalse($_SERVER['__laravel.gateBefore2']);\n        $this->assertTrue($_SERVER['__laravel.gateAfter']);\n        $this->assertFalse($_SERVER['__laravel.gateAfter2']);\n\n        unset(\n            $_SERVER['__laravel.gateBefore'],\n            $_SERVER['__laravel.gateBefore2'],\n            $_SERVER['__laravel.gateAfter'],\n            $_SERVER['__laravel.gateAfter2']\n        );\n    }\n\n    public function testResourceGatesCanBeDefined()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->resource('test', AccessGateTestResource::class);\n\n        $dummy = new AccessGateTestDummy;\n\n        $this->assertTrue($gate->check('test.view'));\n        $this->assertTrue($gate->check('test.create'));\n        $this->assertTrue($gate->check('test.update', $dummy));\n        $this->assertTrue($gate->check('test.delete', $dummy));\n    }\n\n    public function testCustomResourceGatesCanBeDefined()\n    {\n        $gate = $this->getBasicGate();\n\n        $abilities = [\n            'ability1' => 'foo',\n            'ability2' => 'bar',\n        ];\n\n        $gate->resource('test', AccessGateTestCustomResource::class, $abilities);\n\n        $this->assertTrue($gate->check('test.ability1'));\n        $this->assertTrue($gate->check('test.ability2'));\n    }\n\n    public function testBeforeCallbacksCanOverrideResultIfNecessary()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function ($user) {\n            return true;\n        });\n        $gate->before(function ($user, $ability) {\n            $this->assertSame('foo', $ability);\n\n            return false;\n        });\n\n        $this->assertFalse($gate->check('foo'));\n    }\n\n    public function testBeforeCallbacksDontInterruptGateCheckIfNoValueIsReturned()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function ($user) {\n            return true;\n        });\n        $gate->before(function () {\n            //\n        });\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testAfterCallbacksAreCalledWithResult()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function ($user) {\n            return true;\n        });\n\n        $gate->define('bar', function ($user) {\n            return false;\n        });\n\n        $gate->after(function ($user, $ability, $result) {\n            if ($ability === 'foo') {\n                $this->assertTrue($result, 'After callback on `foo` should receive true as result');\n            } elseif ($ability === 'bar') {\n                $this->assertFalse($result, 'After callback on `bar` should receive false as result');\n            } else {\n                $this->assertNull($result, 'After callback on `missing` should receive null as result');\n            }\n        });\n\n        $this->assertTrue($gate->check('foo'));\n        $this->assertFalse($gate->check('bar'));\n        $this->assertFalse($gate->check('missing'));\n    }\n\n    public function testAfterCallbacksCanAllowIfNull()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->after(function ($user, $ability, $result) {\n            return true;\n        });\n\n        $this->assertTrue($gate->allows('null'));\n    }\n\n    public function testAfterCallbacksDoNotOverridePreviousResult()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('deny', function ($user) {\n            return false;\n        });\n\n        $gate->define('allow', function ($user) {\n            return true;\n        });\n\n        $gate->after(function ($user, $ability, $result) {\n            return ! $result;\n        });\n\n        $this->assertTrue($gate->allows('allow'));\n        $this->assertTrue($gate->denies('deny'));\n    }\n\n    public function testAfterCallbacksDoNotOverrideEachOther()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->after(function ($user, $ability, $result) {\n            return $ability === 'allow';\n        });\n\n        $gate->after(function ($user, $ability, $result) {\n            return ! $result;\n        });\n\n        $this->assertTrue($gate->allows('allow'));\n        $this->assertTrue($gate->denies('deny'));\n    }\n\n    public function testCanDefineGatesUsingBackedEnum()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define(AbilitiesEnum::VIEW_DASHBOARD, function ($user) {\n            return true;\n        });\n\n        $this->assertTrue($gate->allows('view-dashboard'));\n    }\n\n    public function testBackedEnumInAllows()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define(AbilitiesEnum::VIEW_DASHBOARD, function ($user) {\n            return true;\n        });\n\n        $this->assertTrue($gate->allows(AbilitiesEnum::VIEW_DASHBOARD));\n    }\n\n    public function testBackedEnumInDenies()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define(AbilitiesEnum::VIEW_DASHBOARD, function ($user) {\n            return false;\n        });\n\n        $this->assertTrue($gate->denies(AbilitiesEnum::VIEW_DASHBOARD));\n    }\n\n    public function testArrayAbilitiesInAllows()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('allow_1', function ($user) {\n            return true;\n        });\n        $gate->define('allow_2', function ($user) {\n            return true;\n        });\n        $gate->define(AbilitiesEnum::VIEW_DASHBOARD, function ($user) {\n            return true;\n        });\n        $gate->define('deny', function ($user) {\n            return false;\n        });\n\n        $this->assertTrue($gate->allows(['allow_1']));\n        $this->assertTrue($gate->allows(['allow_1', 'allow_2', AbilitiesEnum::VIEW_DASHBOARD]));\n        $this->assertFalse($gate->allows(['allow_1', 'allow_2', 'deny']));\n        $this->assertFalse($gate->allows(['deny', 'allow_1', 'allow_2']));\n    }\n\n    public function testArrayAbilitiesInDenies()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('deny_1', function ($user) {\n            return false;\n        });\n        $gate->define('deny_2', function ($user) {\n            return false;\n        });\n        $gate->define(AbilitiesEnum::VIEW_DASHBOARD, function ($user) {\n            return false;\n        });\n        $gate->define('allow', function ($user) {\n            return true;\n        });\n\n        $this->assertTrue($gate->denies(['deny_1']));\n        $this->assertTrue($gate->denies(['deny_1', 'deny_2', AbilitiesEnum::VIEW_DASHBOARD]));\n        $this->assertTrue($gate->denies(['deny_1', 'allow']));\n        $this->assertTrue($gate->denies(['allow', 'deny_1']));\n        $this->assertFalse($gate->denies(['allow']));\n    }\n\n    public function testCurrentUserThatIsOnGateAlwaysInjectedIntoClosureCallbacks()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function ($user) {\n            $this->assertSame(1, $user->id);\n\n            return true;\n        });\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testASingleArgumentCanBePassedWhenCheckingAbilities()\n    {\n        $gate = $this->getBasicGate();\n\n        $dummy = new AccessGateTestDummy;\n\n        $gate->before(function ($user, $ability, array $arguments) use ($dummy) {\n            $this->assertCount(1, $arguments);\n            $this->assertSame($dummy, $arguments[0]);\n        });\n\n        $gate->define('foo', function ($user, $x) use ($dummy) {\n            $this->assertSame($dummy, $x);\n\n            return true;\n        });\n\n        $gate->after(function ($user, $ability, $result, array $arguments) use ($dummy) {\n            $this->assertCount(1, $arguments);\n            $this->assertSame($dummy, $arguments[0]);\n        });\n\n        $this->assertTrue($gate->check('foo', $dummy));\n    }\n\n    public function testMultipleArgumentsCanBePassedWhenCheckingAbilities()\n    {\n        $gate = $this->getBasicGate();\n\n        $dummy1 = new AccessGateTestDummy;\n        $dummy2 = new AccessGateTestDummy;\n\n        $gate->before(function ($user, $ability, array $arguments) use ($dummy1, $dummy2) {\n            $this->assertCount(2, $arguments);\n            $this->assertSame([$dummy1, $dummy2], $arguments);\n        });\n\n        $gate->define('foo', function ($user, $x, $y) use ($dummy1, $dummy2) {\n            $this->assertSame($dummy1, $x);\n            $this->assertSame($dummy2, $y);\n\n            return true;\n        });\n\n        $gate->after(function ($user, $ability, $result, array $arguments) use ($dummy1, $dummy2) {\n            $this->assertCount(2, $arguments);\n            $this->assertSame([$dummy1, $dummy2], $arguments);\n        });\n\n        $this->assertTrue($gate->check('foo', [$dummy1, $dummy2]));\n    }\n\n    public function testClassesCanBeDefinedAsCallbacksUsingAtNotation()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', AccessGateTestClass::class.'@foo');\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testInvokableClassesCanBeDefined()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', AccessGateTestInvokableClass::class);\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testGatesCanBeDefinedUsingAnArrayCallback()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', [new AccessGateTestStaticClass, 'foo']);\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testGatesCanBeDefinedUsingAnArrayCallbackWithStaticMethod()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', [AccessGateTestStaticClass::class, 'foo']);\n\n        $this->assertTrue($gate->check('foo'));\n    }\n\n    public function testPolicyClassesCanBeDefinedToHandleChecksForGivenType()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('update', new AccessGateTestDummy));\n    }\n\n    public function testPolicyClassesHandleChecksForAllSubtypes()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('update', new AccessGateTestSubDummy));\n    }\n\n    public function testPolicyClassesHandleChecksForInterfaces()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummyInterface::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('update', new AccessGateTestSubDummy));\n    }\n\n    public function testPolicyConvertsDashToCamel()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('update-dash', new AccessGateTestDummy));\n    }\n\n    public function testPolicyDefaultToFalseIfMethodDoesNotExistAndGateDoesNotExist()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertFalse($gate->check('nonexistent_method', new AccessGateTestDummy));\n    }\n\n    public function testPolicyClassesCanBeDefinedToHandleChecksForGivenClassName()\n    {\n        $gate = $this->getBasicGate(true);\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('create', [AccessGateTestDummy::class, true]));\n    }\n\n    public function testPoliciesMayHaveBeforeMethodsToOverrideChecks()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithBefore::class);\n\n        $this->assertTrue($gate->check('update', new AccessGateTestDummy));\n    }\n\n    public function testPoliciesAlwaysOverrideClosuresWithSameName()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('update', function () {\n            $this->fail();\n        });\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('update', new AccessGateTestDummy));\n    }\n\n    public function testPoliciesDeferToGatesIfMethodDoesNotExist()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('nonexistent_method', function ($user) {\n            return true;\n        });\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $this->assertTrue($gate->check('nonexistent_method', new AccessGateTestDummy));\n    }\n\n    public function testForUserMethodAttachesANewUserToANewGateInstance()\n    {\n        $gate = $this->getBasicGate();\n\n        // Assert that the callback receives the new user with ID of 2 instead of ID of 1...\n        $gate->define('foo', function ($user) {\n            $this->assertSame(2, $user->id);\n\n            return true;\n        });\n\n        $this->assertTrue($gate->forUser((object) ['id' => 2])->check('foo'));\n    }\n\n    public function testForUserMethodAttachesANewUserToANewGateInstanceWithGuessCallback()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', function () {\n            return true;\n        });\n\n        $counter = 0;\n        $guesserCallback = function () use (&$counter) {\n            $counter++;\n        };\n        $gate->guessPolicyNamesUsing($guesserCallback);\n        $gate->getPolicyFor('fooClass');\n        $this->assertSame(1, $counter);\n\n        // now the guesser callback should be present on the new gate as well\n        $newGate = $gate->forUser((object) ['id' => 1]);\n\n        $newGate->getPolicyFor('fooClass');\n        $this->assertSame(2, $counter);\n\n        $newGate->getPolicyFor('fooClass');\n        $this->assertSame(3, $counter);\n    }\n\n    #[DataProvider('notCallableDataProvider')]\n    public function testDefineSecondParameterShouldBeStringOrCallable($callback)\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $gate = $this->getBasicGate();\n\n        $gate->define('foo', $callback);\n    }\n\n    /**\n     * @return array\n     */\n    public static function notCallableDataProvider()\n    {\n        return [\n            [1],\n            [new stdClass],\n            [[]],\n            [1.1],\n        ];\n    }\n\n    public function testAuthorizeThrowsUnauthorizedException()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('You are not an admin.');\n        $this->expectExceptionCode(0);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $gate->authorize('create', new AccessGateTestDummy);\n    }\n\n    public function testAuthorizeThrowsUnauthorizedExceptionWithCustomStatusCode()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('Not allowed to view as it is not published.');\n        $this->expectExceptionCode('unpublished');\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithCode::class);\n\n        $gate->authorize('view', new AccessGateTestDummy);\n    }\n\n    public function testAuthorizeWithPolicyThatReturnsDeniedResponseObjectThrowsException()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('Not allowed.');\n        $this->expectExceptionCode('some_code');\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithDeniedResponseObject::class);\n\n        $gate->authorize('create', new AccessGateTestDummy);\n    }\n\n    public function testPolicyThatThrowsAuthorizationExceptionIsCaughtInInspect()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyThrowingAuthorizationException::class);\n\n        $response = $gate->inspect('create', new AccessGateTestDummy);\n\n        $this->assertTrue($response->denied());\n        $this->assertFalse($response->allowed());\n        $this->assertSame('Not allowed.', $response->message());\n        $this->assertSame('some_code', $response->code());\n    }\n\n    public function testAuthorizeReturnsAllowedResponse()\n    {\n        $gate = $this->getBasicGate(true);\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $check = $gate->check('create', new AccessGateTestDummy);\n        $response = $gate->authorize('create', new AccessGateTestDummy);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNull($response->message());\n        $this->assertTrue($check);\n    }\n\n    public function testResponseReturnsResponseWhenAbilityGranted()\n    {\n        $gate = $this->getBasicGate(true);\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithCode::class);\n\n        $response = $gate->inspect('view', new AccessGateTestDummy);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNull($response->message());\n        $this->assertTrue($response->allowed());\n        $this->assertFalse($response->denied());\n        $this->assertNull($response->code());\n    }\n\n    public function testResponseReturnsResponseWhenAbilityDenied()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithCode::class);\n\n        $response = $gate->inspect('view', new AccessGateTestDummy);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertSame('Not allowed to view as it is not published.', $response->message());\n        $this->assertFalse($response->allowed());\n        $this->assertTrue($response->denied());\n        $this->assertSame('unpublished', $response->code());\n    }\n\n    public function testAuthorizeReturnsAnAllowedResponseForATruthyReturn()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicy::class);\n\n        $response = $gate->authorize('update', new AccessGateTestDummy);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNull($response->message());\n    }\n\n    public function testAllowIfAuthorizesTrue()\n    {\n        $response = $this->getBasicGate()->allowIf(true);\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testAllowIfAuthorizesTruthy()\n    {\n        $response = $this->getBasicGate()->allowIf('truthy');\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testAllowIfAuthorizesIfGuest()\n    {\n        $response = $this->getBasicGate()->forUser(null)->allowIf(true);\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testAllowIfAuthorizesCallbackTrue()\n    {\n        $response = $this->getBasicGate()->allowIf(function ($user) {\n            $this->assertSame(1, $user->id);\n\n            return true;\n        }, 'foo', 'bar');\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('foo', $response->message());\n        $this->assertSame('bar', $response->code());\n    }\n\n    public function testAllowIfAuthorizesResponseAllowed()\n    {\n        $response = $this->getBasicGate()->allowIf(Response::allow('foo', 'bar'));\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('foo', $response->message());\n        $this->assertSame('bar', $response->code());\n    }\n\n    public function testAllowIfAuthorizesCallbackResponseAllowed()\n    {\n        $response = $this->getBasicGate()->allowIf(function () {\n            return Response::allow('quz', 'qux');\n        }, 'foo', 'bar');\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('quz', $response->message());\n        $this->assertSame('qux', $response->code());\n    }\n\n    public function testAllowsIfCallbackAcceptsGuestsWhenAuthenticated()\n    {\n        $response = $this->getBasicGate()->allowIf(function (?stdClass $user = null) {\n            return $user !== null;\n        });\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testAllowIfCallbackAcceptsGuestsWhenUnauthenticated()\n    {\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $response = $gate->allowIf(function (?stdClass $user = null) {\n            return $user === null;\n        });\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testAllowIfThrowsExceptionWhenFalse()\n    {\n        $this->expectException(AuthorizationException::class);\n\n        $this->getBasicGate()->allowIf(false);\n    }\n\n    public function testAllowIfThrowsExceptionWhenCallbackFalse()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $this->getBasicGate()->allowIf(function () {\n            return false;\n        }, 'foo', 'bar');\n    }\n\n    public function testAllowIfThrowsExceptionWhenResponseDenied()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $this->getBasicGate()->allowIf(Response::deny('foo', 'bar'));\n    }\n\n    public function testAllowIfThrowsExceptionWhenCallbackResponseDenied()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('quz');\n        $this->expectExceptionCode('qux');\n\n        $this->getBasicGate()->allowIf(function () {\n            return Response::deny('quz', 'qux');\n        }, 'foo', 'bar');\n    }\n\n    public function testAllowIfThrowsExceptionIfUnauthenticated()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $gate->allowIf(function () {\n            return true;\n        }, 'foo', 'bar');\n    }\n\n    public function testAllowIfThrowsExceptionIfAuthUserExpectedWhenGuest()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $gate->allowIf(function (stdClass $user) {\n            return true;\n        }, 'foo', 'bar');\n    }\n\n    public function testDenyIfAuthorizesFalse()\n    {\n        $response = $this->getBasicGate()->denyIf(false);\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testDenyIfAuthorizesFalsy()\n    {\n        $response = $this->getBasicGate()->denyIf(0);\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testDenyIfAuthorizesIfGuest()\n    {\n        $response = $this->getBasicGate()->forUser(null)->denyIf(false);\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testDenyIfAuthorizesCallbackFalse()\n    {\n        $response = $this->getBasicGate()->denyIf(function ($user) {\n            $this->assertSame(1, $user->id);\n\n            return false;\n        }, 'foo', 'bar');\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('foo', $response->message());\n        $this->assertSame('bar', $response->code());\n    }\n\n    public function testDenyIfAuthorizesResponseAllowed()\n    {\n        $response = $this->getBasicGate()->denyIf(Response::allow('foo', 'bar'));\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('foo', $response->message());\n        $this->assertSame('bar', $response->code());\n    }\n\n    public function testDenyIfAuthorizesCallbackResponseAllowed()\n    {\n        $response = $this->getBasicGate()->denyIf(function () {\n            return Response::allow('quz', 'qux');\n        }, 'foo', 'bar');\n\n        $this->assertTrue($response->allowed());\n        $this->assertSame('quz', $response->message());\n        $this->assertSame('qux', $response->code());\n    }\n\n    public function testDenyIfCallbackAcceptsGuestsWhenAuthenticated()\n    {\n        $response = $this->getBasicGate()->denyIf(function (?stdClass $user = null) {\n            return $user === null;\n        });\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testDenyIfCallbackAcceptsGuestsWhenUnauthenticated()\n    {\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $response = $gate->denyIf(function (?stdClass $user = null) {\n            return $user !== null;\n        });\n\n        $this->assertTrue($response->allowed());\n    }\n\n    public function testDenyIfThrowsExceptionWhenTrue()\n    {\n        $this->expectException(AuthorizationException::class);\n\n        $this->getBasicGate()->denyIf(true);\n    }\n\n    public function testDenyIfThrowsExceptionWhenCallbackTrue()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $this->getBasicGate()->denyIf(function () {\n            return true;\n        }, 'foo', 'bar');\n    }\n\n    public function testDenyIfThrowsExceptionWhenResponseDenied()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $this->getBasicGate()->denyIf(Response::deny('foo', 'bar'));\n    }\n\n    public function testDenyIfThrowsExceptionWhenCallbackResponseDenied()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('quz');\n        $this->expectExceptionCode('qux');\n\n        $this->getBasicGate()->denyIf(function () {\n            return Response::deny('quz', 'qux');\n        }, 'foo', 'bar');\n    }\n\n    public function testDenyIfThrowsExceptionIfUnauthenticated()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $gate->denyIf(function () {\n            return false;\n        }, 'foo', 'bar');\n    }\n\n    public function testDenyIfThrowsExceptionIfAuthUserExpectedWhenGuest()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n        $this->expectExceptionCode('bar');\n\n        $gate = $this->getBasicGate()->forUser(null);\n\n        $gate->denyIf(function (stdClass $user) {\n            return false;\n        }, 'foo', 'bar');\n    }\n\n    protected function getBasicGate($isAdmin = false)\n    {\n        return new Gate(new Container, function () use ($isAdmin) {\n            return (object) ['id' => 1, 'isAdmin' => $isAdmin];\n        });\n    }\n\n    public function testAnyAbilityCheckPassesIfAllPass()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithAllPermissions::class);\n\n        $this->assertTrue($gate->any(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testAnyAbilityCheckPassesIfAtLeastOnePasses()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithMixedPermissions::class);\n\n        $this->assertTrue($gate->any(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testAnyAbilityCheckFailsIfNonePass()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithNoPermissions::class);\n\n        $this->assertFalse($gate->any(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testNoneAbilityCheckPassesIfAllFail()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithNoPermissions::class);\n\n        $this->assertTrue($gate->none(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testEveryAbilityCheckPassesIfAllPass()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithAllPermissions::class);\n\n        $this->assertTrue($gate->check(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testEveryAbilityCheckFailsIfAtLeastOneFails()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithMixedPermissions::class);\n\n        $this->assertFalse($gate->check(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testEveryAbilityCheckFailsIfNonePass()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithNoPermissions::class);\n\n        $this->assertFalse($gate->check(['edit', 'update'], new AccessGateTestDummy));\n    }\n\n    public function testAnyAbilitiesCheckUsingBackedEnum()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithAllPermissions::class);\n\n        $this->assertTrue($gate->any(['edit', AbilitiesEnum::UPDATE], new AccessGateTestDummy));\n    }\n\n    public function testNoneAbilitiesCheckUsingBackedEnum()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithNoPermissions::class);\n\n        $this->assertTrue($gate->none(['edit', AbilitiesEnum::UPDATE], new AccessGateTestDummy));\n    }\n\n    public function testAbilitiesCheckUsingBackedEnum()\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyWithAllPermissions::class);\n\n        $this->assertTrue($gate->check(['edit', AbilitiesEnum::UPDATE], new AccessGateTestDummy));\n    }\n\n    /**\n     * @param  array  $abilitiesToSet\n     * @param  array|string  $abilitiesToCheck\n     * @param  bool  $expectedHasValue\n     */\n    #[DataProvider('hasAbilitiesTestDataProvider')]\n    public function testHasAbilities($abilitiesToSet, $abilitiesToCheck, $expectedHasValue)\n    {\n        $gate = $this->getBasicGate();\n\n        $gate->resource('test', AccessGateTestResource::class, $abilitiesToSet);\n\n        $this->assertEquals($expectedHasValue, $gate->has($abilitiesToCheck));\n    }\n\n    public static function hasAbilitiesTestDataProvider()\n    {\n        $abilities = ['foo' => 'foo', 'bar' => 'bar'];\n        $noAbilities = [];\n\n        return [\n            [$abilities, ['test.foo', 'test.bar'], true],\n            [$abilities, ['test.bar', 'test.foo'], true],\n            [$abilities, ['test.bar', 'test.foo', 'test.baz'], false],\n            [$abilities, ['test.bar'], true],\n            [$abilities, ['baz'], false],\n            [$abilities, [''], false],\n            [$abilities, [], true],\n            [$abilities, 'test.bar', true],\n            [$abilities, 'test.foo', true],\n            [$abilities, '', false],\n            [$noAbilities, '', false],\n            [$noAbilities, [], true],\n        ];\n    }\n\n    public function testClassesCanBeDefinedAsCallbacksUsingAtNotationForGuests()\n    {\n        $gate = new Gate(new Container, function () {\n            //\n        });\n\n        $gate->define('foo', AccessGateTestClassForGuest::class.'@foo');\n        $gate->define('obj_foo', [new AccessGateTestClassForGuest, 'foo']);\n        $gate->define('static_foo', [AccessGateTestClassForGuest::class, 'staticFoo']);\n        $gate->define('static_@foo', AccessGateTestClassForGuest::class.'@staticFoo');\n        $gate->define('bar', AccessGateTestClassForGuest::class.'@bar');\n        $gate->define('invokable', AccessGateTestGuestInvokableClass::class);\n        $gate->define('nullable_invokable', AccessGateTestGuestNullableInvokable::class);\n        $gate->define('absent_invokable', 'someAbsentClass');\n\n        AccessGateTestClassForGuest::$calledMethod = '';\n\n        $this->assertTrue($gate->check('foo'));\n        $this->assertSame('foo was called', AccessGateTestClassForGuest::$calledMethod);\n\n        $this->assertTrue($gate->check('static_foo'));\n        $this->assertSame('static foo was invoked', AccessGateTestClassForGuest::$calledMethod);\n\n        $this->assertTrue($gate->check('bar'));\n        $this->assertSame('bar got invoked', AccessGateTestClassForGuest::$calledMethod);\n\n        $this->assertTrue($gate->check('static_@foo'));\n        $this->assertSame('static foo was invoked', AccessGateTestClassForGuest::$calledMethod);\n\n        $this->assertTrue($gate->check('invokable'));\n        $this->assertSame('__invoke was called', AccessGateTestGuestInvokableClass::$calledMethod);\n\n        $this->assertTrue($gate->check('nullable_invokable'));\n        $this->assertSame('Nullable __invoke was called', AccessGateTestGuestNullableInvokable::$calledMethod);\n\n        $this->assertFalse($gate->check('absent_invokable'));\n    }\n\n    public function testCanSetDenialResponseInConstructor()\n    {\n        $gate = new Gate(container: new Container, userResolver: function () {\n            //\n        });\n\n        $gate->defaultDenialResponse(Response::denyWithStatus(999, 'my_message', 'abc'));\n\n        $gate->define('foo', function () {\n            return false;\n        });\n\n        $response = $gate->inspect('foo', new AccessGateTestDummy);\n\n        $this->assertTrue($response->denied());\n        $this->assertFalse($response->allowed());\n        $this->assertSame('my_message', $response->message());\n        $this->assertSame('abc', $response->code());\n        $this->assertSame(999, $response->status());\n    }\n\n    public function testCanSetDenialResponse()\n    {\n        $gate = new Gate(container: new Container, userResolver: function () {\n            //\n        });\n\n        $gate->define('foo', function () {\n            return false;\n        });\n        $gate->defaultDenialResponse(Response::denyWithStatus(404, 'not_found', 'xyz'));\n\n        $response = $gate->inspect('foo', new AccessGateTestDummy);\n        $this->assertTrue($response->denied());\n        $this->assertFalse($response->allowed());\n        $this->assertSame('not_found', $response->message());\n        $this->assertSame('xyz', $response->code());\n        $this->assertSame(404, $response->status());\n    }\n}\n\nclass AccessGateTestClassForGuest\n{\n    public static $calledMethod = null;\n\n    public function foo($user = null)\n    {\n        static::$calledMethod = 'foo was called';\n\n        return true;\n    }\n\n    public static function staticFoo($user = null)\n    {\n        static::$calledMethod = 'static foo was invoked';\n\n        return true;\n    }\n\n    public function bar(?stdClass $user)\n    {\n        static::$calledMethod = 'bar got invoked';\n\n        return true;\n    }\n}\n\nclass AccessGateTestStaticClass\n{\n    public static function foo($user)\n    {\n        return $user->id === 1;\n    }\n}\n\nclass AccessGateTestClass\n{\n    public function foo($user)\n    {\n        return $user->id === 1;\n    }\n}\n\nclass AccessGateTestInvokableClass\n{\n    public function __invoke($user)\n    {\n        return $user->id === 1;\n    }\n}\n\nclass AccessGateTestGuestInvokableClass\n{\n    public static $calledMethod = null;\n\n    public function __invoke($user = null)\n    {\n        static::$calledMethod = '__invoke was called';\n\n        return true;\n    }\n}\n\nclass AccessGateTestGuestNullableInvokable\n{\n    public static $calledMethod = null;\n\n    public function __invoke(?stdClass $user)\n    {\n        static::$calledMethod = 'Nullable __invoke was called';\n\n        return true;\n    }\n}\n\ninterface AccessGateTestDummyInterface\n{\n    //\n}\n\nclass AccessGateTestDummy implements AccessGateTestDummyInterface\n{\n    //\n}\n\nclass AccessGateTestSubDummy extends AccessGateTestDummy\n{\n    //\n}\n\nclass AccessGateTestPolicy\n{\n    use HandlesAuthorization;\n\n    public function createAny($user, $additional)\n    {\n        return $additional;\n    }\n\n    public function create($user)\n    {\n        return $user->isAdmin ? $this->allow() : $this->deny('You are not an admin.');\n    }\n\n    public function updateAny($user, AccessGateTestDummy $dummy)\n    {\n        return ! $user->isAdmin;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return ! $user->isAdmin;\n    }\n\n    public function updateDash($user, AccessGateTestDummy $dummy)\n    {\n        return $user instanceof stdClass;\n    }\n}\n\nclass AccessGateTestPolicyWithBefore\n{\n    public function before($user, $ability)\n    {\n        return true;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return false;\n    }\n}\n\nclass AccessGateTestResource\n{\n    public function view($user)\n    {\n        return true;\n    }\n\n    public function create($user)\n    {\n        return true;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n\n    public function delete($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestCustomResource\n{\n    public function foo($user)\n    {\n        return true;\n    }\n\n    public function bar($user)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyWithMixedPermissions\n{\n    public function edit($user, AccessGateTestDummy $dummy)\n    {\n        return false;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyWithNoPermissions\n{\n    public function edit($user, AccessGateTestDummy $dummy)\n    {\n        return false;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return false;\n    }\n}\n\nclass AccessGateTestPolicyWithAllPermissions\n{\n    public function edit($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyThatAllowsGuests\n{\n    public function before(?stdClass $user)\n    {\n        $_SERVER['__laravel.testBefore'] = true;\n    }\n\n    public function edit(?stdClass $user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyWithNonGuestBefore\n{\n    public function before(stdClass $user)\n    {\n        $_SERVER['__laravel.testBefore'] = true;\n    }\n\n    public function edit(?stdClass $user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n\n    public function update($user, AccessGateTestDummy $dummy)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestBeforeCallback\n{\n    public function allowEverything($user = null)\n    {\n        return true;\n    }\n\n    public static function allowEverythingStatically($user = null)\n    {\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyWithCode\n{\n    use HandlesAuthorization;\n\n    public function view($user)\n    {\n        if (! $user->isAdmin) {\n            return $this->deny('Not allowed to view as it is not published.', 'unpublished');\n        }\n\n        return true;\n    }\n}\n\nclass AccessGateTestPolicyWithDeniedResponseObject\n{\n    public function create()\n    {\n        return Response::deny('Not allowed.', 'some_code');\n    }\n}\n\nclass AccessGateTestPolicyThrowingAuthorizationException\n{\n    public function create()\n    {\n        throw new AuthorizationException('Not allowed.', 'some_code');\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthAccessResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Response;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthAccessResponseTest extends TestCase\n{\n    public function testAllowMethod()\n    {\n        $response = Response::allow('some message', 'some_code');\n\n        $this->assertTrue($response->allowed());\n        $this->assertFalse($response->denied());\n        $this->assertSame('some message', $response->message());\n        $this->assertSame('some_code', $response->code());\n    }\n\n    public function testDenyMethod()\n    {\n        $response = Response::deny('some message', 'some_code');\n\n        $this->assertTrue($response->denied());\n        $this->assertFalse($response->allowed());\n        $this->assertSame('some message', $response->message());\n        $this->assertSame('some_code', $response->code());\n    }\n\n    public function testDenyMethodWithNoMessageReturnsNull()\n    {\n        $response = Response::deny();\n\n        $this->assertNull($response->message());\n    }\n\n    public function testItSetsEmptyStatusOnExceptionWhenAuthorizing()\n    {\n        try {\n            Response::deny('foo', 3)->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertNull($e->status());\n            $this->assertFalse($e->hasStatus());\n            $this->assertSame('foo', $e->response()->message());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n    }\n\n    public function testItSetsStatusOnExceptionWhenAuthorizing()\n    {\n        try {\n            Response::deny('foo', 3)->withStatus(418)->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(418, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame('foo', $e->response()->message());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n\n        try {\n            Response::deny('foo', 3)->asNotFound()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(404, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame('foo', $e->response()->message());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n\n        try {\n            Response::denyWithStatus(444)->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(444, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertNull($e->response()->message());\n            $this->assertSame('This action is unauthorized.', $e->getMessage());\n            $this->assertSame(0, $e->getCode());\n        }\n\n        try {\n            Response::denyWithStatus(444, 'foo', 3)->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(444, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame('foo', $e->response()->message());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n\n        try {\n            Response::denyAsNotFound()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(404, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertNull($e->response()->message());\n            $this->assertSame('This action is unauthorized.', $e->getMessage());\n            $this->assertSame(0, $e->getCode());\n        }\n\n        try {\n            Response::denyAsNotFound('foo', 3)->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertSame(404, $e->status());\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame('foo', $e->response()->message());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n    }\n\n    public function testAuthorizeMethodThrowsAuthorizationExceptionWhenResponseDenied()\n    {\n        $response = Response::deny('Some message.', 'some_code');\n\n        try {\n            $response->authorize();\n        } catch (AuthorizationException $e) {\n            $this->assertSame('Some message.', $e->getMessage());\n            $this->assertSame('some_code', $e->getCode());\n            $this->assertEquals($response, $e->response());\n        }\n    }\n\n    public function testAuthorizeMethodThrowsAuthorizationExceptionWithDefaultMessage()\n    {\n        $response = Response::deny();\n\n        try {\n            $response->authorize();\n        } catch (AuthorizationException $e) {\n            $this->assertSame('This action is unauthorized.', $e->getMessage());\n        }\n    }\n\n    public function testThrowIfNeededDoesntThrowAuthorizationExceptionWhenResponseAllowed()\n    {\n        $response = Response::allow('Some message.', 'some_code');\n\n        $this->assertEquals($response, $response->authorize());\n    }\n\n    public function testCastingToStringReturnsMessage()\n    {\n        $response = new Response(true, 'some data');\n        $this->assertSame('some data', (string) $response);\n\n        $response = new Response(false, null);\n        $this->assertSame('', (string) $response);\n    }\n\n    public function testResponseToArrayMethod()\n    {\n        $response = new Response(false, 'Not allowed.', 'some_code');\n\n        $this->assertEquals([\n            'allowed' => false,\n            'message' => 'Not allowed.',\n            'code' => 'some_code',\n        ], $response->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthDatabaseTokenRepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Passwords\\DatabaseTokenRepository;\nuse Illuminate\\Contracts\\Auth\\CanResetPassword;\nuse Illuminate\\Contracts\\Hashing\\Hasher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass AuthDatabaseTokenRepositoryTest extends TestCase\n{\n    public function testCreateInsertsNewRecordIntoTable()\n    {\n        $repo = $this->getRepo();\n        $repo->getHasher()->shouldReceive('make')->once()->andReturn('hashed-token');\n        $repo->getConnection()->shouldReceive('table')->times(2)->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $query->shouldReceive('delete')->once();\n        $query->shouldReceive('insert')->once();\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->times(2)->andReturn('email');\n\n        $results = $repo->create($user);\n\n        $this->assertIsString($results);\n        $this->assertGreaterThan(1, strlen($results));\n    }\n\n    public function testExistReturnsFalseIfNoRowFoundForUser()\n    {\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $query->shouldReceive('first')->once()->andReturn(null);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertFalse($repo->exists($user, 'token'));\n    }\n\n    public function testExistReturnsFalseIfRecordIsExpired()\n    {\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $date = Carbon::now()->subSeconds(300000)->toDateTimeString();\n        $query->shouldReceive('first')->once()->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertFalse($repo->exists($user, 'token'));\n    }\n\n    public function testExistReturnsTrueIfValidRecordExists()\n    {\n        $repo = $this->getRepo();\n        $repo->getHasher()->shouldReceive('check')->once()->with('token', 'hashed-token')->andReturn(true);\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $date = Carbon::now()->subMinutes(10)->toDateTimeString();\n        $query->shouldReceive('first')->once()->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertTrue($repo->exists($user, 'token'));\n    }\n\n    public function testExistReturnsFalseIfInvalidToken()\n    {\n        $repo = $this->getRepo();\n        $repo->getHasher()->shouldReceive('check')->once()->with('wrong-token', 'hashed-token')->andReturn(false);\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $date = Carbon::now()->subMinutes(10)->toDateTimeString();\n        $query->shouldReceive('first')->once()->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertFalse($repo->exists($user, 'wrong-token'));\n    }\n\n    public function testRecentlyCreatedReturnsFalseIfNoRowFoundForUser()\n    {\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $query->shouldReceive('first')->once()->andReturn(null);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertFalse($repo->recentlyCreatedToken($user));\n    }\n\n    public function testRecentlyCreatedReturnsTrueIfRecordIsRecentlyCreated()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $date = Carbon::now()->subSeconds(59)->toDateTimeString();\n        $query->shouldReceive('first')->once()->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertTrue($repo->recentlyCreatedToken($user));\n\n        Carbon::setTestNow();\n    }\n\n    public function testRecentlyCreatedReturnsFalseIfValidRecordExists()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $date = Carbon::now()->subSeconds(61)->toDateTimeString();\n        $query->shouldReceive('first')->once()->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']);\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $this->assertFalse($repo->recentlyCreatedToken($user));\n\n        Carbon::setTestNow();\n    }\n\n    public function testDeleteMethodDeletesByToken()\n    {\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query);\n        $query->shouldReceive('delete')->once();\n        $user = m::mock(CanResetPassword::class);\n        $user->shouldReceive('getEmailForPasswordReset')->once()->andReturn('email');\n\n        $repo->delete($user);\n    }\n\n    public function testDeleteExpiredMethodDeletesExpiredTokens()\n    {\n        $repo = $this->getRepo();\n        $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('created_at', '<', m::any())->andReturn($query);\n        $query->shouldReceive('delete')->once();\n\n        $repo->deleteExpired();\n    }\n\n    protected function getRepo()\n    {\n        return new DatabaseTokenRepository(\n            m::mock(Connection::class),\n            m::mock(Hasher::class),\n            'table', 'key');\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthDatabaseUserProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\DatabaseUserProvider;\nuse Illuminate\\Auth\\GenericUser;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Contracts\\Hashing\\Hasher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass AuthDatabaseUserProviderTest extends TestCase\n{\n    public function testRetrieveByIDReturnsUserWhenUserIsFound()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('find')->once()->with(1)->andReturn(['id' => 1, 'name' => 'Dayle']);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveById(1);\n\n        $this->assertInstanceOf(GenericUser::class, $user);\n        $this->assertSame(1, $user->getAuthIdentifier());\n        $this->assertSame('Dayle', $user->name);\n    }\n\n    public function testRetrieveByIDReturnsNullWhenUserIsNotFound()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('find')->once()->with(1)->andReturn(null);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveById(1);\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByTokenReturnsUser()\n    {\n        $mockUser = new stdClass;\n        $mockUser->remember_token = 'a';\n\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('find')->once()->with(1)->andReturn($mockUser);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertEquals(new GenericUser((array) $mockUser), $user);\n    }\n\n    public function testRetrieveTokenWithBadIdentifierReturnsNull()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('find')->once()->with(1)->andReturn(null);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByBadTokenReturnsNull()\n    {\n        $mockUser = new stdClass;\n        $mockUser->remember_token = null;\n\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('find')->once()->with(1)->andReturn($mockUser);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByCredentialsReturnsUserWhenUserIsFound()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('where')->once()->with('username', 'dayle');\n        $conn->shouldReceive('whereIn')->once()->with('group', ['one', 'two']);\n        $conn->shouldReceive('first')->once()->andReturn(['id' => 1, 'name' => 'taylor']);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByCredentials(['username' => 'dayle', 'password' => 'foo', 'group' => ['one', 'two']]);\n\n        $this->assertInstanceOf(GenericUser::class, $user);\n        $this->assertSame(1, $user->getAuthIdentifier());\n        $this->assertSame('taylor', $user->name);\n    }\n\n    public function testRetrieveByCredentialsAcceptsCallback()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('where')->once()->with('username', 'dayle');\n        $conn->shouldReceive('whereIn')->once()->with('group', ['one', 'two']);\n        $conn->shouldReceive('first')->once()->andReturn(['id' => 1, 'name' => 'taylor']);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n\n        $user = $provider->retrieveByCredentials([function ($builder) {\n            $builder->where('username', 'dayle');\n            $builder->whereIn('group', ['one', 'two']);\n        }]);\n\n        $this->assertInstanceOf(GenericUser::class, $user);\n        $this->assertSame(1, $user->getAuthIdentifier());\n        $this->assertSame('taylor', $user->name);\n    }\n\n    public function testRetrieveByCredentialsReturnsNullWhenUserIsFound()\n    {\n        $conn = m::mock(Connection::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);\n        $conn->shouldReceive('where')->once()->with('username', 'dayle');\n        $conn->shouldReceive('first')->once()->andReturn(null);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByCredentials(['username' => 'dayle']);\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByCredentialsWithMultiplyPasswordsReturnsNull()\n    {\n        $conn = m::mock(Connection::class);\n        $hasher = m::mock(Hasher::class);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = $provider->retrieveByCredentials([\n            'password' => 'dayle',\n            'password2' => 'night',\n        ]);\n\n        $this->assertNull($user);\n    }\n\n    public function testCredentialValidation()\n    {\n        $conn = m::mock(Connection::class);\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->once()->with('plain', 'hash')->andReturn(true);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertTrue($result);\n    }\n\n    public function testCredentialValidationFails()\n    {\n        $conn = m::mock(Connection::class);\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->once()->with('plain', 'hash')->andReturn(false);\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertFalse($result);\n    }\n\n    public function testCredentialValidationFailsGracefullyWithNullPassword()\n    {\n        $conn = m::mock(Connection::class);\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->never();\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn(null);\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertFalse($result);\n    }\n\n    public function testRehashPasswordIfRequired()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('needsRehash')->once()->with('hash')->andReturn(true);\n        $hasher->shouldReceive('make')->once()->with('plain')->andReturn('rehashed');\n\n        $conn = m::mock(Connection::class);\n        $table = m::mock(ConnectionInterface::class);\n        $conn->shouldReceive('table')->once()->with('foo')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('id', 1)->andReturnSelf();\n        $table->shouldReceive('update')->once()->with(['password_attribute' => 'rehashed']);\n\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');\n        $user->shouldReceive('getAuthIdentifier')->once()->andReturn(1);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $user->shouldReceive('getAuthPasswordName')->once()->andReturn('password_attribute');\n\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $provider->rehashPasswordIfRequired($user, ['password' => 'plain']);\n    }\n\n    public function testDontRehashPasswordIfNotRequired()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('needsRehash')->once()->with('hash')->andReturn(false);\n        $hasher->shouldNotReceive('make');\n\n        $conn = m::mock(Connection::class);\n        $table = m::mock(ConnectionInterface::class);\n        $conn->shouldNotReceive('table');\n        $table->shouldNotReceive('where');\n        $table->shouldNotReceive('update');\n\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $user->shouldNotReceive('getAuthIdentifierName');\n        $user->shouldNotReceive('getAuthIdentifier');\n        $user->shouldNotReceive('getAuthPasswordName');\n\n        $provider = new DatabaseUserProvider($conn, $hasher, 'foo');\n        $provider->rehashPasswordIfRequired($user, ['password' => 'plain']);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthEloquentUserProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\EloquentUserProvider;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Contracts\\Hashing\\Hasher;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass AuthEloquentUserProviderTest extends TestCase\n{\n    public function testRetrieveByIDReturnsUser()\n    {\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');\n        $mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);\n        $mock->shouldReceive('first')->once()->andReturn('bar');\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveById(1);\n\n        $this->assertSame('bar', $user);\n    }\n\n    public function testRetrieveByTokenReturnsUser()\n    {\n        $mockUser = m::mock(stdClass::class);\n        $mockUser->shouldReceive('getRememberToken')->once()->andReturn('a');\n\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');\n        $mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);\n        $mock->shouldReceive('first')->once()->andReturn($mockUser);\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertEquals($mockUser, $user);\n    }\n\n    public function testRetrieveTokenWithBadIdentifierReturnsNull()\n    {\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');\n        $mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);\n        $mock->shouldReceive('first')->once()->andReturn(null);\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrievingWithOnlyPasswordCredentialReturnsNull()\n    {\n        $provider = $this->getProviderMock();\n        $user = $provider->retrieveByCredentials(['api_password' => 'foo']);\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByBadTokenReturnsNull()\n    {\n        $mockUser = m::mock(stdClass::class);\n        $mockUser->shouldReceive('getRememberToken')->once()->andReturn(null);\n\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');\n        $mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);\n        $mock->shouldReceive('first')->once()->andReturn($mockUser);\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveByToken(1, 'a');\n\n        $this->assertNull($user);\n    }\n\n    public function testRetrieveByCredentialsReturnsUser()\n    {\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('where')->once()->with('username', 'dayle');\n        $mock->shouldReceive('whereIn')->once()->with('group', ['one', 'two']);\n        $mock->shouldReceive('first')->once()->andReturn('bar');\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveByCredentials(['username' => 'dayle', 'password' => 'foo', 'group' => ['one', 'two']]);\n\n        $this->assertSame('bar', $user);\n    }\n\n    public function testRetrieveByCredentialsAcceptsCallback()\n    {\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('where')->once()->with('username', 'dayle');\n        $mock->shouldReceive('whereIn')->once()->with('group', ['one', 'two']);\n        $mock->shouldReceive('first')->once()->andReturn('bar');\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $user = $provider->retrieveByCredentials([function ($builder) {\n            $builder->where('username', 'dayle');\n            $builder->whereIn('group', ['one', 'two']);\n        }]);\n\n        $this->assertSame('bar', $user);\n    }\n\n    public function testRetrieveByCredentialsWithMultiplyPasswordsReturnsNull()\n    {\n        $provider = $this->getProviderMock();\n        $user = $provider->retrieveByCredentials([\n            'password' => 'dayle',\n            'password2' => 'night',\n        ]);\n\n        $this->assertNull($user);\n    }\n\n    public function testCredentialValidation()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->once()->with('plain', 'hash')->andReturn(true);\n        $provider = new EloquentUserProvider($hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertTrue($result);\n    }\n\n    public function testCredentialValidationFailed()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->once()->with('plain', 'hash')->andReturn(false);\n        $provider = new EloquentUserProvider($hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertFalse($result);\n    }\n\n    public function testCredentialValidationFailsGracefullyWithNullPassword()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('check')->never();\n        $provider = new EloquentUserProvider($hasher, 'foo');\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn(null);\n        $result = $provider->validateCredentials($user, ['password' => 'plain']);\n\n        $this->assertFalse($result);\n    }\n\n    public function testRehashPasswordIfRequired()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('needsRehash')->once()->with('hash')->andReturn(true);\n        $hasher->shouldReceive('make')->once()->with('plain')->andReturn('rehashed');\n\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $user->shouldReceive('getAuthPasswordName')->once()->andReturn('password_attribute');\n        $user->shouldReceive('forceFill')->once()->with(['password_attribute' => 'rehashed'])->andReturnSelf();\n        $user->shouldReceive('save')->once();\n\n        $provider = new EloquentUserProvider($hasher, 'foo');\n        $provider->rehashPasswordIfRequired($user, ['password' => 'plain']);\n    }\n\n    public function testDontRehashPasswordIfNotRequired()\n    {\n        $hasher = m::mock(Hasher::class);\n        $hasher->shouldReceive('needsRehash')->once()->with('hash')->andReturn(false);\n        $hasher->shouldNotReceive('make');\n\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthPassword')->once()->andReturn('hash');\n        $user->shouldNotReceive('getAuthPasswordName');\n        $user->shouldNotReceive('forceFill');\n        $user->shouldNotReceive('save');\n\n        $provider = new EloquentUserProvider($hasher, 'foo');\n        $provider->rehashPasswordIfRequired($user, ['password' => 'plain']);\n    }\n\n    public function testModelsCanBeCreated()\n    {\n        $hasher = m::mock(Hasher::class);\n        $provider = new EloquentUserProvider($hasher, EloquentProviderUserStub::class);\n        $model = $provider->createModel();\n\n        $this->assertInstanceOf(EloquentProviderUserStub::class, $model);\n    }\n\n    public function testRegistersQueryHandler()\n    {\n        $callback = function ($builder) {\n            $builder->whereIn('group', ['one', 'two']);\n        };\n\n        $provider = $this->getProviderMock();\n        $mock = m::mock(stdClass::class);\n        $mock->shouldReceive('newQuery')->once()->andReturn($mock);\n        $mock->shouldReceive('where')->once()->with('username', 'dayle');\n        $mock->shouldReceive('whereIn')->once()->with('group', ['one', 'two']);\n        $mock->shouldReceive('first')->once()->andReturn('bar');\n        $provider->expects($this->once())->method('createModel')->willReturn($mock);\n        $provider->withQuery($callback);\n        $user = $provider->retrieveByCredentials([function ($builder) {\n            $builder->where('username', 'dayle');\n        }]);\n\n        $this->assertSame('bar', $user);\n        $this->assertSame($callback, $provider->getQueryCallback());\n    }\n\n    protected function getProviderMock()\n    {\n        $hasher = m::mock(Hasher::class);\n\n        return $this->getMockBuilder(EloquentUserProvider::class)->onlyMethods(['createModel'])->setConstructorArgs([$hasher, 'foo'])->getMock();\n    }\n}\n\nclass EloquentProviderUserStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Auth/AuthGuardTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Auth\\Events\\Attempting;\nuse Illuminate\\Auth\\Events\\Authenticated;\nuse Illuminate\\Auth\\Events\\CurrentDeviceLogout;\nuse Illuminate\\Auth\\Events\\Failed;\nuse Illuminate\\Auth\\Events\\Login;\nuse Illuminate\\Auth\\Events\\Logout;\nuse Illuminate\\Auth\\Events\\Validated;\nuse Illuminate\\Auth\\SessionGuard;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Illuminate\\Cookie\\CookieJar;\nuse Illuminate\\Support\\Timebox;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException;\n\nclass AuthGuardTest extends TestCase\n{\n    public function testBasicReturnsNullOnValidAttempt()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]);\n        $guard->shouldReceive('check')->once()->andReturn(false);\n        $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'])->andReturn(true);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']);\n        $guard->setRequest($request);\n\n        $guard->basic('email');\n    }\n\n    public function testBasicReturnsNullWhenAlreadyLoggedIn()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class.'[check]', ['default', $provider, $session]);\n        $guard->shouldReceive('check')->once()->andReturn(true);\n        $guard->shouldReceive('attempt')->never();\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']);\n        $guard->setRequest($request);\n\n        $guard->basic('email');\n    }\n\n    public function testBasicReturnsResponseOnFailure()\n    {\n        $this->expectException(UnauthorizedHttpException::class);\n\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]);\n        $guard->shouldReceive('check')->once()->andReturn(false);\n        $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret'])->andReturn(false);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']);\n        $guard->setRequest($request);\n        $guard->basic('email');\n    }\n\n    public function testBasicWithExtraConditions()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]);\n        $guard->shouldReceive('check')->once()->andReturn(false);\n        $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1])->andReturn(true);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']);\n        $guard->setRequest($request);\n\n        $guard->basic('email', ['active' => 1]);\n    }\n\n    public function testBasicWithExtraArrayConditions()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class.'[check,attempt]', ['default', $provider, $session]);\n        $guard->shouldReceive('check')->once()->andReturn(false);\n        $guard->shouldReceive('attempt')->once()->with(['email' => 'foo@bar.com', 'password' => 'secret', 'active' => 1, 'type' => [1, 2, 3]])->andReturn(true);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo@bar.com', 'PHP_AUTH_PW' => 'secret']);\n        $guard->setRequest($request);\n\n        $guard->basic('email', ['active' => 1, 'type' => [1, 2, 3]]);\n    }\n\n    public function testAttemptCallsRetrieveByCredentials()\n    {\n        $guard = $this->getGuard();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox = $guard->getTimebox();\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback) use ($timebox) {\n            return $callback($timebox);\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Failed::class));\n        $events->shouldNotReceive('dispatch')->with(m::type(Validated::class));\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->with(['foo']);\n        $guard->getProvider()->shouldNotReceive('rehashPasswordIfRequired');\n        $guard->attempt(['foo']);\n    }\n\n    public function testAttemptReturnsUserInterface()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $guard = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['login'])->setConstructorArgs(['default', $provider, $session, $request, $timebox])->getMock();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback, $microseconds) use ($timebox) {\n            return $callback($timebox->shouldReceive('returnEarly')->once()->getMock());\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Validated::class));\n        $user = $this->createMock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->andReturn($user);\n        $guard->getProvider()->shouldReceive('validateCredentials')->with($user, ['foo'])->andReturn(true);\n        $guard->getProvider()->shouldReceive('rehashPasswordIfRequired')->with($user, ['foo'])->once();\n        $guard->expects($this->once())->method('login')->with($this->equalTo($user));\n        $this->assertTrue($guard->attempt(['foo']));\n    }\n\n    public function testAttemptReturnsFalseIfUserNotGiven()\n    {\n        $mock = $this->getGuard();\n        $mock->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox = $mock->getTimebox();\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback, $microseconds) use ($timebox) {\n            return $callback($timebox);\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Failed::class));\n        $events->shouldNotReceive('dispatch')->with(m::type(Validated::class));\n        $mock->getProvider()->shouldReceive('retrieveByCredentials')->once()->andReturn(null);\n        $mock->getProvider()->shouldNotReceive('rehashPasswordIfRequired');\n        $this->assertFalse($mock->attempt(['foo']));\n    }\n\n    public function testAttemptAndWithCallbacks()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName'])->setConstructorArgs(['default', $provider, $session, $request, $timebox])->getMock();\n        $mock->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox->shouldReceive('call')->andReturnUsing(function ($callback) use ($timebox) {\n            return $callback($timebox->shouldReceive('returnEarly')->getMock());\n        });\n        $user = m::mock(Authenticatable::class);\n        $events->shouldReceive('dispatch')->times(3)->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Login::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Authenticated::class));\n        $events->shouldReceive('dispatch')->twice()->with(m::type(Validated::class));\n        $events->shouldReceive('dispatch')->twice()->with(m::type(Failed::class));\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $user->shouldReceive('getAuthIdentifier')->once()->andReturn('bar');\n        $mock->getSession()->shouldReceive('put')->with('foo', 'bar')->once();\n        $session->shouldReceive('regenerate')->once();\n        $mock->getProvider()->shouldReceive('retrieveByCredentials')->times(3)->with(['foo'])->andReturn($user);\n        $mock->getProvider()->shouldReceive('validateCredentials')->twice()->andReturnTrue();\n        $mock->getProvider()->shouldReceive('validateCredentials')->once()->andReturnFalse();\n        $mock->getProvider()->shouldReceive('rehashPasswordIfRequired')->with($user, ['foo'])->once();\n\n        $this->assertTrue($mock->attemptWhen(['foo'], function ($user, $guard) {\n            static::assertInstanceOf(Authenticatable::class, $user);\n            static::assertInstanceOf(SessionGuard::class, $guard);\n\n            return true;\n        }));\n\n        $this->assertFalse($mock->attemptWhen(['foo'], function ($user, $guard) {\n            static::assertInstanceOf(Authenticatable::class, $user);\n            static::assertInstanceOf(SessionGuard::class, $guard);\n\n            return false;\n        }));\n\n        $executed = false;\n\n        $this->assertFalse($mock->attemptWhen(['foo'], false, function () use (&$executed) {\n            return $executed = true;\n        }));\n\n        $this->assertFalse($executed);\n    }\n\n    public function testAttemptRehashesPasswordWhenRequired()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $guard = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['login'])->setConstructorArgs(['default', $provider, $session, $request, $timebox])->getMock();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback, $microseconds) use ($timebox) {\n            return $callback($timebox->shouldReceive('returnEarly')->once()->getMock());\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Validated::class));\n        $user = $this->createMock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->andReturn($user);\n        $guard->getProvider()->shouldReceive('validateCredentials')->with($user, ['foo'])->andReturn(true);\n        $guard->getProvider()->shouldReceive('rehashPasswordIfRequired')->with($user, ['foo'])->once();\n        $guard->expects($this->once())->method('login')->with($this->equalTo($user));\n        $this->assertTrue($guard->attempt(['foo']));\n    }\n\n    public function testAttemptDoesntRehashPasswordWhenDisabled()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $guard = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['login'])\n            ->setConstructorArgs(['default', $provider, $session, $request, $timebox, $rehashOnLogin = false])\n            ->getMock();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback, $microseconds) use ($timebox) {\n            return $callback($timebox->shouldReceive('returnEarly')->once()->getMock());\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Validated::class));\n        $user = $this->createMock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->andReturn($user);\n        $guard->getProvider()->shouldReceive('validateCredentials')->with($user, ['foo'])->andReturn(true);\n        $guard->getProvider()->shouldNotReceive('rehashPasswordIfRequired');\n        $guard->expects($this->once())->method('login')->with($this->equalTo($user));\n        $this->assertTrue($guard->attempt(['foo']));\n    }\n\n    public function testLoginStoresIdentifierInSession()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $user = m::mock(Authenticatable::class);\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $user->shouldReceive('getAuthIdentifier')->once()->andReturn('bar');\n        $mock->getSession()->shouldReceive('put')->with('foo', 'bar')->once();\n        $session->shouldReceive('regenerate')->once();\n        $mock->login($user);\n    }\n\n    public function testSessionGuardIsMacroable()\n    {\n        $guard = $this->getGuard();\n\n        $guard->macro('foo', function () {\n            return 'bar';\n        });\n\n        $this->assertSame(\n            'bar', $guard->foo()\n        );\n    }\n\n    public function testLoginFiresLoginAndAuthenticatedEvents()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->setDispatcher($events = m::mock(Dispatcher::class));\n        $user = m::mock(Authenticatable::class);\n        $events->shouldReceive('dispatch')->once()->with(m::type(Login::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Authenticated::class));\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $user->shouldReceive('getAuthIdentifier')->once()->andReturn('bar');\n        $mock->getSession()->shouldReceive('put')->with('foo', 'bar')->once();\n        $session->shouldReceive('regenerate')->once();\n        $mock->login($user);\n    }\n\n    public function testFailedAttemptFiresFailedEvent()\n    {\n        $guard = $this->getGuard();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $timebox = $guard->getTimebox();\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback, $microseconds) use ($timebox) {\n            return $callback($timebox);\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(Attempting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Failed::class));\n        $events->shouldNotReceive('dispatch')->with(m::type(Validated::class));\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn(null);\n        $guard->getProvider()->shouldNotReceive('rehashPasswordIfRequired');\n        $guard->attempt(['foo']);\n    }\n\n    public function testAuthenticateReturnsUserWhenUserIsNotNull()\n    {\n        $user = m::mock(Authenticatable::class);\n        $guard = $this->getGuard();\n        $guard->setUser($user);\n\n        $this->assertEquals($user, $guard->authenticate());\n    }\n\n    public function testSetUserFiresAuthenticatedEvent()\n    {\n        $user = m::mock(Authenticatable::class);\n        $guard = $this->getGuard();\n        $guard->setDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(Authenticated::class));\n        $guard->setUser($user);\n    }\n\n    public function testAuthenticateThrowsWhenUserIsNull()\n    {\n        $this->expectException(AuthenticationException::class);\n        $this->expectExceptionMessage('Unauthenticated.');\n\n        $guard = $this->getGuard();\n        $guard->getSession()->shouldReceive('get')->once()->andReturn(null);\n\n        $guard->authenticate();\n    }\n\n    public function testHasUserReturnsTrueWhenUserIsNotNull()\n    {\n        $user = m::mock(Authenticatable::class);\n        $guard = $this->getGuard();\n        $guard->setUser($user);\n\n        $this->assertTrue($guard->hasUser());\n    }\n\n    public function testHasUserReturnsFalseWhenUserIsNull()\n    {\n        $guard = $this->getGuard();\n        $guard->getSession()->shouldNotReceive('get');\n\n        $this->assertFalse($guard->hasUser());\n    }\n\n    public function testIsAuthedReturnsTrueWhenUserIsNotNull()\n    {\n        $user = m::mock(Authenticatable::class);\n        $mock = $this->getGuard();\n        $mock->setUser($user);\n        $this->assertTrue($mock->check());\n        $this->assertFalse($mock->guest());\n    }\n\n    public function testIsAuthedReturnsFalseWhenUserIsNull()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['user'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->expects($this->exactly(2))->method('user')->willReturn(null);\n        $this->assertFalse($mock->check());\n        $this->assertTrue($mock->guest());\n    }\n\n    public function testUserMethodReturnsCachedUser()\n    {\n        $user = m::mock(Authenticatable::class);\n        $mock = $this->getGuard();\n        $mock->setUser($user);\n        $this->assertSame($user, $mock->user());\n    }\n\n    public function testNullIsReturnedForUserIfNoUserFound()\n    {\n        $mock = $this->getGuard();\n        $mock->getSession()->shouldReceive('get')->once()->andReturn(null);\n        $this->assertNull($mock->user());\n    }\n\n    public function testUserIsSetToRetrievedUser()\n    {\n        $mock = $this->getGuard();\n        $mock->getSession()->shouldReceive('get')->once()->andReturn(1);\n        $user = m::mock(Authenticatable::class);\n        $mock->getProvider()->shouldReceive('retrieveById')->once()->with(1)->andReturn($user);\n        $this->assertSame($user, $mock->user());\n        $this->assertSame($user, $mock->getUser());\n    }\n\n    public function testLogoutRemovesSessionTokenAndRememberMeCookie()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName', 'getRecallerName', 'recaller'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->setCookieJar($cookies = m::mock(CookieJar::class));\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getRememberToken')->once()->andReturn('a');\n        $user->shouldReceive('setRememberToken')->once();\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $mock->expects($this->exactly(2))->method('getRecallerName')->willReturn($recallerName = 'bar');\n        $mock->expects($this->once())->method('recaller')->willReturn('non-null-cookie');\n        $provider->shouldReceive('updateRememberToken')->once();\n\n        $cookie = m::mock(Cookie::class);\n        $cookies->shouldReceive('forget')->once()->with('bar')->andReturn($cookie);\n        $cookies->shouldReceive('queue')->once()->with($cookie);\n        $cookies->shouldReceive('unqueue')->once()->with($recallerName);\n        $mock->getSession()->shouldReceive('remove')->once()->with('foo');\n        $mock->setUser($user);\n        $mock->logout();\n        $this->assertNull($mock->getUser());\n    }\n\n    public function testLogoutDoesNotEnqueueRememberMeCookieForDeletionIfCookieDoesntExist()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName', 'getRecallerName', 'recaller'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->setCookieJar($cookies = m::mock(CookieJar::class));\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $mock->expects($this->once())->method('getRecallerName')->willReturn($recallerName = 'bar');\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $mock->expects($this->once())->method('recaller')->willReturn(null);\n\n        $cookies->shouldReceive('unqueue')->with($recallerName);\n\n        $mock->getSession()->shouldReceive('remove')->once()->with('foo');\n        $mock->setUser($user);\n        $mock->logout();\n        $this->assertNull($mock->getUser());\n    }\n\n    public function testLogoutFiresLogoutEvent()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['clearUserDataFromStorage'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->expects($this->once())->method('clearUserDataFromStorage');\n        $mock->setDispatcher($events = m::mock(Dispatcher::class));\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $events->shouldReceive('dispatch')->once()->with(m::type(Authenticated::class));\n        $mock->setUser($user);\n        $events->shouldReceive('dispatch')->once()->with(m::type(Logout::class));\n        $mock->logout();\n    }\n\n    public function testLogoutDoesNotSetRememberTokenIfNotPreviouslySet()\n    {\n        [$session, $provider, $request] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['clearUserDataFromStorage'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $user = m::mock(Authenticatable::class);\n\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $user->shouldNotReceive('setRememberToken');\n        $provider->shouldNotReceive('updateRememberToken');\n\n        $mock->setUser($user);\n        $mock->logout();\n    }\n\n    public function testLogoutCurrentDeviceRemovesRememberMeCookie()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName', 'getRecallerName', 'recaller'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->setCookieJar($cookies = m::mock(CookieJar::class));\n        $user = m::mock(Authenticatable::class);\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $mock->expects($this->exactly(2))->method('getRecallerName')->willReturn($recallerName = 'bar');\n        $mock->expects($this->once())->method('recaller')->willReturn('non-null-cookie');\n\n        $cookie = m::mock(Cookie::class);\n        $cookies->shouldReceive('forget')->once()->with('bar')->andReturn($cookie);\n        $cookies->shouldReceive('queue')->once()->with($cookie);\n        $cookies->shouldReceive('unqueue')->once()->with($recallerName);\n        $mock->getSession()->shouldReceive('remove')->once()->with('foo');\n        $mock->setUser($user);\n        $mock->logoutCurrentDevice();\n        $this->assertNull($mock->getUser());\n    }\n\n    public function testLogoutCurrentDeviceDoesNotEnqueueRememberMeCookieForDeletionIfCookieDoesntExist()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['getName', 'getRecallerName', 'recaller'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->setCookieJar($cookies = m::mock(CookieJar::class));\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $mock->expects($this->once())->method('getName')->willReturn('foo');\n        $mock->expects($this->once())->method('getRecallerName')->willReturn($recallerName = 'bar');\n        $mock->expects($this->once())->method('recaller')->willReturn(null);\n        $cookies->shouldReceive('unqueue')->once()->with($recallerName);\n\n        $mock->getSession()->shouldReceive('remove')->once()->with('foo');\n        $mock->setUser($user);\n        $mock->logoutCurrentDevice();\n        $this->assertNull($mock->getUser());\n    }\n\n    public function testLogoutCurrentDeviceFiresLogoutEvent()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $mock = $this->getMockBuilder(SessionGuard::class)->onlyMethods(['clearUserDataFromStorage'])->setConstructorArgs(['default', $provider, $session, $request])->getMock();\n        $mock->expects($this->once())->method('clearUserDataFromStorage');\n        $mock->setDispatcher($events = m::mock(Dispatcher::class));\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $events->shouldReceive('dispatch')->once()->with(m::type(Authenticated::class));\n        $mock->setUser($user);\n        $events->shouldReceive('dispatch')->once()->with(m::type(CurrentDeviceLogout::class));\n        $mock->logoutCurrentDevice();\n    }\n\n    public function testLoginMethodQueuesCookieWhenRemembering()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = new SessionGuard('default', $provider, $session, $request);\n        $guard->setCookieJar($cookie);\n        $foreverCookie = new Cookie($guard->getRecallerName(), 'foo');\n        $expectedHash = hash_hmac('sha256', 'bar', 'base-key-for-password-hash-mac');\n        $cookie->shouldReceive('make')->once()->with($guard->getRecallerName(), 'foo|recaller|'.$expectedHash, 576000)->andReturn($foreverCookie);\n        $cookie->shouldReceive('queue')->once()->with($foreverCookie);\n        $guard->getSession()->shouldReceive('put')->once()->with($guard->getName(), 'foo');\n        $session->shouldReceive('regenerate')->once();\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthIdentifier')->andReturn('foo');\n        $user->shouldReceive('getAuthPassword')->andReturn('bar');\n        $user->shouldReceive('getRememberToken')->andReturn('recaller');\n        $user->shouldReceive('setRememberToken')->never();\n        $provider->shouldReceive('updateRememberToken')->never();\n        $guard->login($user, true);\n    }\n\n    public function testLoginMethodQueuesCookieWhenRememberingAndAllowsOverride()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = new SessionGuard('default', $provider, $session, $request);\n        $guard->setRememberDuration(5000);\n        $guard->setCookieJar($cookie);\n        $foreverCookie = new Cookie($guard->getRecallerName(), 'foo');\n        $expectedHash = hash_hmac('sha256', 'bar', 'base-key-for-password-hash-mac');\n        $cookie->shouldReceive('make')->once()->with($guard->getRecallerName(), 'foo|recaller|'.$expectedHash, 5000)->andReturn($foreverCookie);\n        $cookie->shouldReceive('queue')->once()->with($foreverCookie);\n        $guard->getSession()->shouldReceive('put')->once()->with($guard->getName(), 'foo');\n        $session->shouldReceive('regenerate')->once();\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthIdentifier')->andReturn('foo');\n        $user->shouldReceive('getAuthPassword')->andReturn('bar');\n        $user->shouldReceive('getRememberToken')->andReturn('recaller');\n        $user->shouldReceive('setRememberToken')->never();\n        $provider->shouldReceive('updateRememberToken')->never();\n        $guard->login($user, true);\n    }\n\n    public function testLoginMethodCreatesRememberTokenIfOneDoesntExist()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = new SessionGuard('default', $provider, $session, $request);\n        $guard->setCookieJar($cookie);\n        $foreverCookie = new Cookie($guard->getRecallerName(), 'foo');\n        $cookie->shouldReceive('make')->once()->andReturn($foreverCookie);\n        $cookie->shouldReceive('queue')->once()->with($foreverCookie);\n        $guard->getSession()->shouldReceive('put')->once()->with($guard->getName(), 'foo');\n        $session->shouldReceive('regenerate')->once();\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthIdentifier')->andReturn('foo');\n        $user->shouldReceive('getAuthPassword')->andReturn('foo');\n        $user->shouldReceive('getRememberToken')->andReturn(null);\n        $user->shouldReceive('setRememberToken')->once();\n        $provider->shouldReceive('updateRememberToken')->once();\n        $guard->login($user, true);\n    }\n\n    public function testLoginUsingIdLogsInWithUser()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session])->makePartial();\n\n        $user = m::mock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveById')->once()->with(10)->andReturn($user);\n        $guard->shouldReceive('login')->once()->with($user, false);\n\n        $this->assertSame($user, $guard->loginUsingId(10));\n    }\n\n    public function testLoginUsingIdFailure()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session])->makePartial();\n\n        $guard->getProvider()->shouldReceive('retrieveById')->once()->with(11)->andReturn(null);\n        $guard->shouldNotReceive('login');\n\n        $this->assertFalse($guard->loginUsingId(11));\n    }\n\n    public function testOnceUsingIdSetsUser()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session])->makePartial();\n\n        $user = m::mock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveById')->once()->with(10)->andReturn($user);\n        $guard->shouldReceive('setUser')->once()->with($user);\n\n        $this->assertSame($user, $guard->onceUsingId(10));\n    }\n\n    public function testOnceUsingIdFailure()\n    {\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session])->makePartial();\n\n        $guard->getProvider()->shouldReceive('retrieveById')->once()->with(11)->andReturn(null);\n        $guard->shouldNotReceive('setUser');\n\n        $this->assertFalse($guard->onceUsingId(11));\n    }\n\n    public function testUserUsesRememberCookieIfItExists()\n    {\n        $guard = $this->getGuard();\n        [$session, $provider, $request, $cookie] = $this->getMocks();\n        $request = Request::create('/', 'GET', [], [$guard->getRecallerName() => 'id|recaller|baz']);\n        $guard = new SessionGuard('default', $provider, $session, $request);\n        $guard->getSession()->shouldReceive('get')->once()->with($guard->getName())->andReturn(null);\n        $user = m::mock(Authenticatable::class);\n        $guard->getProvider()->shouldReceive('retrieveByToken')->once()->with('id', 'recaller')->andReturn($user);\n        $user->shouldReceive('getAuthIdentifier')->once()->andReturn('bar');\n        $guard->getSession()->shouldReceive('put')->with($guard->getName(), 'bar')->once();\n        $session->shouldReceive('regenerate')->once();\n        $this->assertSame($user, $guard->user());\n        $this->assertTrue($guard->viaRemember());\n    }\n\n    public function testLoginOnceSetsUser()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session, $request, $timebox])->makePartial();\n        $user = m::mock(Authenticatable::class);\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback) use ($timebox) {\n            return $callback($timebox->shouldReceive('returnEarly')->once()->getMock());\n        });\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user);\n        $guard->getProvider()->shouldReceive('validateCredentials')->once()->with($user, ['foo'])->andReturn(true);\n        $guard->getProvider()->shouldReceive('rehashPasswordIfRequired')->with($user, ['foo'])->once();\n        $guard->shouldReceive('setUser')->once()->with($user);\n        $this->assertTrue($guard->once(['foo']));\n    }\n\n    public function testLoginOnceFailure()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n        $guard = m::mock(SessionGuard::class, ['default', $provider, $session, $request, $timebox])->makePartial();\n        $user = m::mock(Authenticatable::class);\n        $timebox->shouldReceive('call')->once()->andReturnUsing(function ($callback) use ($timebox) {\n            return $callback($timebox);\n        });\n        $guard->getProvider()->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user);\n        $guard->getProvider()->shouldReceive('validateCredentials')->once()->with($user, ['foo'])->andReturn(false);\n        $guard->getProvider()->shouldNotReceive('rehashPasswordIfRequired');\n        $this->assertFalse($guard->once(['foo']));\n    }\n\n    public function testForgetUserSetsUserToNull()\n    {\n        $user = m::mock(Authenticatable::class);\n        $guard = $this->getGuard();\n        $guard->setUser($user);\n        $guard->forgetUser();\n        $this->assertNull($guard->getUser());\n    }\n\n    protected function getGuard()\n    {\n        [$session, $provider, $request, $cookie, $timebox] = $this->getMocks();\n\n        return new SessionGuard('default', $provider, $session, $request, $timebox);\n    }\n\n    protected function getMocks()\n    {\n        return [\n            m::mock(Session::class),\n            m::mock(UserProvider::class),\n            Request::create('/', 'GET'),\n            m::mock(CookieJar::class),\n            m::mock(Timebox::class),\n        ];\n    }\n\n    protected function getCookieJar()\n    {\n        return new CookieJar(Request::create('/foo', 'GET'), m::mock(Encrypter::class), ['domain' => 'foo.com', 'path' => '/', 'secure' => false, 'httpOnly' => false]);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthHandlesAuthorizationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\HandlesAuthorization;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthHandlesAuthorizationTest extends TestCase\n{\n    use HandlesAuthorization;\n\n    public function testAllowMethod()\n    {\n        $response = $this->allow('some message', 'some_code');\n\n        $this->assertTrue($response->allowed());\n        $this->assertFalse($response->denied());\n        $this->assertSame('some message', $response->message());\n        $this->assertSame('some_code', $response->code());\n    }\n\n    public function testDenyMethod()\n    {\n        $response = $this->deny('some message', 'some_code');\n\n        $this->assertTrue($response->denied());\n        $this->assertFalse($response->allowed());\n        $this->assertSame('some message', $response->message());\n        $this->assertSame('some_code', $response->code());\n    }\n\n    public function testDenyHasNullStatus()\n    {\n        $class = new class()\n        {\n            use HandlesAuthorization;\n\n            public function __invoke()\n            {\n                return $this->deny('xxxx', 321);\n            }\n        };\n\n        try {\n            $class()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertFalse($e->hasStatus());\n            $this->assertNull($e->status());\n        }\n    }\n\n    public function testItCanDenyWithStatus()\n    {\n        $class = new class()\n        {\n            use HandlesAuthorization;\n\n            public function __invoke()\n            {\n                return $this->denyWithStatus(418);\n            }\n        };\n\n        try {\n            $class()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame(418, $e->status());\n            $this->assertSame('This action is unauthorized.', $e->getMessage());\n            $this->assertSame(0, $e->getCode());\n        }\n\n        $class = new class()\n        {\n            use HandlesAuthorization;\n\n            public function __invoke()\n            {\n                return $this->denyWithStatus(418, 'foo', 3);\n            }\n        };\n\n        try {\n            $class()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame(418, $e->status());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n    }\n\n    public function testItCanDenyAsNotFound()\n    {\n        $class = new class()\n        {\n            use HandlesAuthorization;\n\n            public function __invoke()\n            {\n                return $this->denyAsNotFound();\n            }\n        };\n\n        try {\n            $class()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame(404, $e->status());\n            $this->assertSame('This action is unauthorized.', $e->getMessage());\n            $this->assertSame(0, $e->getCode());\n        }\n\n        $class = new class()\n        {\n            use HandlesAuthorization;\n\n            public function __invoke()\n            {\n                return $this->denyAsNotFound('foo', 3);\n            }\n        };\n\n        try {\n            $class()->authorize();\n            $this->fail();\n        } catch (AuthorizationException $e) {\n            $this->assertTrue($e->hasStatus());\n            $this->assertSame(404, $e->status());\n            $this->assertSame('foo', $e->getMessage());\n            $this->assertSame(3, $e->getCode());\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthListenersSendEmailVerificationNotificationHandleFunctionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Events\\Registered;\nuse Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification;\nuse Illuminate\\Contracts\\Auth\\MustVerifyEmail;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthListenersSendEmailVerificationNotificationHandleFunctionTest extends TestCase\n{\n    /**\n     * @return void\n     */\n    public function testWillExecuted()\n    {\n        $user = $this->getMockBuilder(MustVerifyEmail::class)->getMock();\n        $user->method('hasVerifiedEmail')->willReturn(false);\n        $user->expects($this->once())->method('sendEmailVerificationNotification');\n\n        $listener = new SendEmailVerificationNotification;\n\n        $listener->handle(new Registered($user));\n    }\n\n    /**\n     * @return void\n     */\n    public function testUserIsNotInstanceOfMustVerifyEmail()\n    {\n        $user = m::mock(User::class);\n        $user->shouldNotReceive('sendEmailVerificationNotification');\n\n        $listener = new SendEmailVerificationNotification;\n\n        $listener->handle(new Registered($user));\n    }\n\n    /**\n     * @return void\n     */\n    public function testHasVerifiedEmailAsTrue()\n    {\n        $user = $this->getMockBuilder(MustVerifyEmail::class)->getMock();\n        $user->method('hasVerifiedEmail')->willReturn(true);\n        $user->expects($this->never())->method('sendEmailVerificationNotification');\n\n        $listener = new SendEmailVerificationNotification;\n\n        $listener->handle(new Registered($user));\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthPasswordBrokerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Passwords\\PasswordBroker;\nuse Illuminate\\Auth\\Passwords\\TokenRepositoryInterface;\nuse Illuminate\\Contracts\\Auth\\CanResetPassword;\nuse Illuminate\\Contracts\\Auth\\PasswordBroker as PasswordBrokerContract;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Support\\Arr;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse UnexpectedValueException;\n\nclass AuthPasswordBrokerTest extends TestCase\n{\n    public function testIfUserIsNotFoundErrorRedirectIsReturned()\n    {\n        $mocks = $this->getMocks();\n        $broker = m::mock(PasswordBroker::class, array_values($mocks))->makePartial();\n        $broker->shouldReceive('getUser')->once()->andReturnNull();\n\n        $this->assertSame(PasswordBrokerContract::INVALID_USER, $broker->sendResetLink(['credentials']));\n    }\n\n    public function testIfTokenIsRecentlyCreated()\n    {\n        $mocks = $this->getMocks();\n        $broker = m::mock(PasswordBroker::class, array_values($mocks))->makePartial();\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));\n        $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(true);\n        $user->shouldReceive('sendPasswordResetNotification')->with('token');\n\n        $this->assertSame(PasswordBrokerContract::RESET_THROTTLED, $broker->sendResetLink(['foo']));\n    }\n\n    public function testGetUserThrowsExceptionIfUserDoesntImplementCanResetPassword()\n    {\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage('User must implement CanResetPassword interface.');\n\n        $broker = $this->getBroker($mocks = $this->getMocks());\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn('bar');\n\n        $broker->getUser(['foo']);\n    }\n\n    public function testUserIsRetrievedByCredentials()\n    {\n        $broker = $this->getBroker($mocks = $this->getMocks());\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));\n\n        $this->assertEquals($user, $broker->getUser(['foo']));\n    }\n\n    public function testBrokerCreatesTokenAndRedirectsWithoutError()\n    {\n        $mocks = $this->getMocks();\n        $broker = m::mock(PasswordBroker::class, array_values($mocks))->makePartial();\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));\n        $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(false);\n        $mocks['tokens']->shouldReceive('create')->once()->with($user)->andReturn('token');\n        $user->shouldReceive('sendPasswordResetNotification')->with('token');\n\n        $this->assertSame(PasswordBrokerContract::RESET_LINK_SENT, $broker->sendResetLink(['foo']));\n    }\n\n    public function testRedirectIsReturnedByResetWhenUserCredentialsInvalid()\n    {\n        $broker = $this->getBroker($mocks = $this->getMocks());\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['creds'])->andReturn(null);\n\n        $this->assertSame(PasswordBrokerContract::INVALID_USER, $broker->reset(['creds'], function () {\n            //\n        }));\n    }\n\n    public function testRedirectReturnedByRemindWhenRecordDoesntExistInTable()\n    {\n        $creds = ['token' => 'token'];\n        $broker = $this->getBroker($mocks = $this->getMocks());\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(Arr::except($creds, ['token']))->andReturn($user = m::mock(CanResetPassword::class));\n        $mocks['tokens']->shouldReceive('exists')->with($user, 'token')->andReturn(false);\n\n        $this->assertSame(PasswordBrokerContract::INVALID_TOKEN, $broker->reset($creds, function () {\n            //\n        }));\n    }\n\n    public function testResetRemovesRecordOnReminderTableAndCallsCallback()\n    {\n        unset($_SERVER['__password.reset.test']);\n        $mocks = $this->getMocks();\n        $broker = m::mock(PasswordBroker::class, array_values($mocks))->makePartial()->shouldAllowMockingProtectedMethods();\n        $broker->shouldReceive('validateReset')->once()->andReturn($user = m::mock(CanResetPassword::class));\n        $mocks['tokens']->shouldReceive('delete')->once()->with($user);\n        $callback = function ($user, $password) {\n            $_SERVER['__password.reset.test'] = compact('user', 'password');\n\n            return 'foo';\n        };\n\n        $this->assertSame(PasswordBrokerContract::PASSWORD_RESET, $broker->reset(['password' => 'password', 'token' => 'token'], $callback));\n        $this->assertEquals(['user' => $user, 'password' => 'password'], $_SERVER['__password.reset.test']);\n    }\n\n    public function testExecutesCallbackInsteadOfSendingNotification()\n    {\n        $executed = false;\n\n        $closure = function () use (&$executed) {\n            $executed = true;\n        };\n\n        $mocks = $this->getMocks();\n        $broker = m::mock(PasswordBroker::class, array_values($mocks))->makePartial();\n        $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));\n        $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(false);\n        $mocks['tokens']->shouldReceive('create')->once()->with($user)->andReturn('token');\n        $user->shouldReceive('sendPasswordResetNotification')->with('token');\n\n        $this->assertEquals(PasswordBrokerContract::RESET_LINK_SENT, $broker->sendResetLink(['foo'], $closure));\n\n        $this->assertTrue($executed);\n    }\n\n    protected function getBroker($mocks)\n    {\n        return new PasswordBroker($mocks['tokens'], $mocks['users']);\n    }\n\n    protected function getMocks()\n    {\n        return [\n            'tokens' => m::mock(TokenRepositoryInterface::class),\n            'users' => m::mock(UserProvider::class),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthTokenGuardTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\TokenGuard;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthTokenGuardTest extends TestCase\n{\n    public function testUserCanBeRetrievedByQueryStringVariable()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'foo'])->andReturn($user);\n        $request = Request::create('/', 'GET', ['api_token' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n        $this->assertTrue($guard->check());\n        $this->assertFalse($guard->guest());\n        $this->assertSame(1, $guard->id());\n    }\n\n    public function testTokenCanBeHashed()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => hash('sha256', 'foo')])->andReturn($user);\n        $request = Request::create('/', 'GET', ['api_token' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request, 'api_token', 'api_token', $hash = true);\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n        $this->assertTrue($guard->check());\n        $this->assertFalse($guard->guest());\n        $this->assertSame(1, $guard->id());\n    }\n\n    public function testUserCanBeRetrievedByAuthHeaders()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'foo'])->andReturn((object) ['id' => 1]);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo', 'PHP_AUTH_PW' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n    }\n\n    public function testUserCanBeRetrievedByBearerToken()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'foo'])->andReturn((object) ['id' => 1]);\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'Bearer foo']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n    }\n\n    public function testValidateCanDetermineIfCredentialsAreValid()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'foo'])->andReturn($user);\n        $request = Request::create('/', 'GET', ['api_token' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $this->assertTrue($guard->validate(['api_token' => 'foo']));\n    }\n\n    public function testValidateCanDetermineIfCredentialsAreInvalid()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'foo'])->andReturn(null);\n        $request = Request::create('/', 'GET', ['api_token' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $this->assertFalse($guard->validate(['api_token' => 'foo']));\n    }\n\n    public function testValidateIfApiTokenIsEmpty()\n    {\n        $provider = m::mock(UserProvider::class);\n        $request = Request::create('/', 'GET', ['api_token' => '']);\n\n        $guard = new TokenGuard($provider, $request);\n\n        $this->assertFalse($guard->validate(['api_token' => '']));\n    }\n\n    public function testItAllowsToPassCustomRequestInSetterAndUseItForValidation()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['api_token' => 'custom'])->andReturn($user);\n        $request = Request::create('/', 'GET', ['api_token' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request);\n        $guard->setRequest(Request::create('/', 'GET', ['api_token' => 'custom']));\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n    }\n\n    public function testUserCanBeRetrievedByBearerTokenWithCustomKey()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['custom_token_field' => 'foo'])->andReturn((object) ['id' => 1]);\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'Bearer foo']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n    }\n\n    public function testUserCanBeRetrievedByQueryStringVariableWithCustomKey()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['custom_token_field' => 'foo'])->andReturn($user);\n        $request = Request::create('/', 'GET', ['custom_token_field' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n        $this->assertTrue($guard->check());\n        $this->assertFalse($guard->guest());\n        $this->assertSame(1, $guard->id());\n    }\n\n    public function testUserCanBeRetrievedByAuthHeadersWithCustomField()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['custom_token_field' => 'foo'])->andReturn((object) ['id' => 1]);\n        $request = Request::create('/', 'GET', [], [], [], ['PHP_AUTH_USER' => 'foo', 'PHP_AUTH_PW' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $user = $guard->user();\n\n        $this->assertSame(1, $user->id);\n    }\n\n    public function testValidateCanDetermineIfCredentialsAreValidWithCustomKey()\n    {\n        $provider = m::mock(UserProvider::class);\n        $user = new AuthTokenGuardTestUser;\n        $user->id = 1;\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['custom_token_field' => 'foo'])->andReturn($user);\n        $request = Request::create('/', 'GET', ['custom_token_field' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $this->assertTrue($guard->validate(['custom_token_field' => 'foo']));\n    }\n\n    public function testValidateCanDetermineIfCredentialsAreInvalidWithCustomKey()\n    {\n        $provider = m::mock(UserProvider::class);\n        $provider->shouldReceive('retrieveByCredentials')->once()->with(['custom_token_field' => 'foo'])->andReturn(null);\n        $request = Request::create('/', 'GET', ['custom_token_field' => 'foo']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $this->assertFalse($guard->validate(['custom_token_field' => 'foo']));\n    }\n\n    public function testValidateIfApiTokenIsEmptyWithCustomKey()\n    {\n        $provider = m::mock(UserProvider::class);\n        $request = Request::create('/', 'GET', ['custom_token_field' => '']);\n\n        $guard = new TokenGuard($provider, $request, 'custom_token_field', 'custom_token_field');\n\n        $this->assertFalse($guard->validate(['custom_token_field' => '']));\n    }\n}\n\nclass AuthTokenGuardTestUser\n{\n    public $id;\n\n    public function getAuthIdentifier()\n    {\n        return $this->id;\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthenticatableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Foundation\\Auth\\User;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthenticatableTest extends TestCase\n{\n    public function testItReturnsSameRememberTokenForString()\n    {\n        $user = new User;\n        $user->setRememberToken('sample_token');\n        $this->assertSame('sample_token', $user->getRememberToken());\n    }\n\n    public function testItReturnsStringAsRememberTokenWhenItWasSetToTrue()\n    {\n        $user = new User;\n        $user->setRememberToken(true);\n        $this->assertSame('1', $user->getRememberToken());\n    }\n\n    public function testItReturnsNullWhenRememberTokenNameWasSetToEmpty()\n    {\n        $user = new class extends User\n        {\n            public function getRememberTokenName()\n            {\n                return '';\n            }\n        };\n        $user->setRememberToken(true);\n        $this->assertNull($user->getRememberToken());\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthenticateMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Auth\\AuthManager;\nuse Illuminate\\Auth\\EloquentUserProvider;\nuse Illuminate\\Auth\\Middleware\\Authenticate;\nuse Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth;\nuse Illuminate\\Auth\\RequestGuard;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass AuthenticateMiddlewareTest extends TestCase\n{\n    protected $auth;\n\n    protected function setUp(): void\n    {\n        $container = Container::setInstance(new Container);\n\n        $this->auth = new AuthManager($container);\n\n        $container->singleton('config', function () {\n            return $this->createConfig();\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = Authenticate::using('foo');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authenticate:foo', $signature);\n\n        $signature = Authenticate::using('foo', 'bar');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authenticate:foo,bar', $signature);\n\n        $signature = Authenticate::using('foo', 'bar', 'baz');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authenticate:foo,bar,baz', $signature);\n    }\n\n    public function testItCanGenerateDefinitionViaStaticMethodForBasic()\n    {\n        $signature = AuthenticateWithBasicAuth::using('guard');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth:guard', $signature);\n\n        $signature = AuthenticateWithBasicAuth::using('guard', 'field');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth:guard,field', $signature);\n\n        $signature = AuthenticateWithBasicAuth::using(field: 'field');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\AuthenticateWithBasicAuth:,field', $signature);\n    }\n\n    public function testDefaultUnauthenticatedThrows()\n    {\n        $this->expectException(AuthenticationException::class);\n        $this->expectExceptionMessage('Unauthenticated.');\n\n        $this->registerAuthDriver('default', false);\n\n        $this->authenticate();\n    }\n\n    public function testDefaultUnauthenticatedThrowsWithGuards()\n    {\n        try {\n            $this->registerAuthDriver('default', false);\n\n            $this->authenticate('default');\n        } catch (AuthenticationException $e) {\n            $this->assertContains('default', $e->guards());\n\n            return;\n        }\n\n        $this->fail();\n    }\n\n    public function testDefaultAuthenticatedKeepsDefaultDriver()\n    {\n        $driver = $this->registerAuthDriver('default', true);\n\n        $this->authenticate();\n\n        $this->assertSame($driver, $this->auth->guard());\n    }\n\n    public function testSecondaryAuthenticatedUpdatesDefaultDriver()\n    {\n        $this->registerAuthDriver('default', false);\n\n        $secondary = $this->registerAuthDriver('secondary', true);\n\n        $this->authenticate('secondary');\n\n        $this->assertSame($secondary, $this->auth->guard());\n    }\n\n    public function testMultipleDriversUnauthenticatedThrows()\n    {\n        $this->expectException(AuthenticationException::class);\n        $this->expectExceptionMessage('Unauthenticated.');\n\n        $this->registerAuthDriver('default', false);\n\n        $this->registerAuthDriver('secondary', false);\n\n        $this->authenticate('default', 'secondary');\n    }\n\n    public function testMultipleDriversUnauthenticatedThrowsWithGuards()\n    {\n        $expectedGuards = ['default', 'secondary'];\n\n        try {\n            $this->registerAuthDriver('default', false);\n\n            $this->registerAuthDriver('secondary', false);\n\n            $this->authenticate(...$expectedGuards);\n        } catch (AuthenticationException $e) {\n            $this->assertEquals($expectedGuards, $e->guards());\n\n            return;\n        }\n\n        $this->fail();\n    }\n\n    public function testMultipleDriversAuthenticatedUpdatesDefault()\n    {\n        $this->registerAuthDriver('default', false);\n\n        $secondary = $this->registerAuthDriver('secondary', true);\n\n        $this->authenticate('default', 'secondary');\n\n        $this->assertSame($secondary, $this->auth->guard());\n    }\n\n    public function testCustomDriverClosureBoundObjectIsAuthManager()\n    {\n        $this->auth->extend(__CLASS__, fn () => $this);\n        $this->assertSame($this->auth, $this->auth->guard(__CLASS__));\n    }\n\n    /**\n     * Create a new config repository instance.\n     *\n     * @return \\Illuminate\\Config\\Repository\n     */\n    protected function createConfig()\n    {\n        return new Config([\n            'auth' => [\n                'defaults' => ['guard' => 'default'],\n                'guards' => [\n                    'default' => ['driver' => 'default'],\n                    'secondary' => ['driver' => 'secondary'],\n                    __CLASS__ => ['driver' => __CLASS__],\n                ],\n            ],\n        ]);\n    }\n\n    /**\n     * Create and register a new auth driver with the auth manager.\n     *\n     * @param  string  $name\n     * @param  bool  $authenticated\n     * @return \\Illuminate\\Auth\\RequestGuard\n     */\n    protected function registerAuthDriver($name, $authenticated)\n    {\n        $driver = $this->createAuthDriver($authenticated);\n\n        $this->auth->extend($name, function () use ($driver) {\n            return $driver;\n        });\n\n        return $driver;\n    }\n\n    /**\n     * Create a new auth driver.\n     *\n     * @param  bool  $authenticated\n     * @return \\Illuminate\\Auth\\RequestGuard\n     */\n    protected function createAuthDriver($authenticated)\n    {\n        return new RequestGuard(function () use ($authenticated) {\n            return $authenticated ? new stdClass : null;\n        }, m::mock(Request::class), m::mock(EloquentUserProvider::class));\n    }\n\n    /**\n     * Call the authenticate middleware with the given guards.\n     *\n     * @param  string  ...$guards\n     * @return void\n     *\n     * @throws \\Illuminate\\Auth\\AuthenticationException\n     */\n    protected function authenticate(...$guards)\n    {\n        $request = m::mock(Request::class);\n\n        $request->shouldReceive('expectsJson')->andReturn(false);\n\n        $nextParam = null;\n\n        $next = function ($param) use (&$nextParam) {\n            $nextParam = $param;\n        };\n\n        (new Authenticate($this->auth))->handle($request, $next, ...$guards);\n\n        $this->assertSame($request, $nextParam);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthorizeMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Gate;\nuse Illuminate\\Auth\\Middleware\\Authorize;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate as GateContract;\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\CallableDispatcher;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse Illuminate\\Routing\\Middleware\\SubstituteBindings;\nuse Illuminate\\Routing\\Router;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\ninclude_once 'Enums.php';\n\nclass AuthorizeMiddlewareTest extends TestCase\n{\n    protected $container;\n    protected $user;\n    protected $router;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->user = new stdClass;\n\n        Container::setInstance($this->container = new Container);\n\n        $this->container->singleton(GateContract::class, function () {\n            return new Gate($this->container, function () {\n                return $this->user;\n            });\n        });\n\n        $this->router = new Router(new Dispatcher, $this->container);\n\n        $this->container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $this->container->instance(Registrar::class, $this->router);\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = Authorize::using('ability');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authorize:ability', $signature);\n\n        $signature = Authorize::using('ability', 'model');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authorize:ability,model', $signature);\n\n        $signature = Authorize::using('ability', 'model', \\App\\Models\\Comment::class);\n        $this->assertSame('Illuminate\\Auth\\Middleware\\Authorize:ability,model,App\\Models\\Comment', $signature);\n    }\n\n    public function testSimpleAbilityUnauthorized()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('This action is unauthorized.');\n\n        $this->gate()->define('view-dashboard', function ($user, $additional = null) {\n            $this->assertNull($additional);\n\n            return false;\n        });\n\n        $this->router->get('dashboard', [\n            'middleware' => Authorize::class.':view-dashboard',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $this->router->dispatch(Request::create('dashboard', 'GET'));\n    }\n\n    public function testSimpleAbilityAuthorized()\n    {\n        $this->gate()->define('view-dashboard', function ($user) {\n            return true;\n        });\n\n        $this->router->get('dashboard', [\n            'middleware' => Authorize::class.':view-dashboard',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('dashboard', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testSimpleAbilityWithStringParameter()\n    {\n        $this->gate()->define('view-dashboard', function ($user, $param) {\n            return $param === 'some string';\n        });\n\n        $this->router->get('dashboard', [\n            'middleware' => Authorize::class.':view-dashboard,\"some string\"',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('dashboard', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testSimpleAbilityWithBackedEnumParameter()\n    {\n        $this->gate()->define('view-dashboard', function ($user) {\n            return true;\n        });\n\n        $this->router->middleware(Authorize::using(AbilitiesEnum::VIEW_DASHBOARD))->get('dashboard', [\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('dashboard', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testSimpleAbilityWithNullParameter()\n    {\n        $this->gate()->define('view-dashboard', function ($user, $param = null) {\n            $this->assertNull($param);\n\n            return true;\n        });\n\n        $this->router->get('dashboard', [\n            'middleware' => Authorize::class.':view-dashboard,null',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $this->router->dispatch(Request::create('dashboard', 'GET'));\n    }\n\n    public function testSimpleAbilityWithOptionalParameter()\n    {\n        $post = new stdClass;\n\n        $this->router->bind('post', function () use ($post) {\n            return $post;\n        });\n\n        $this->gate()->define('view-comments', function ($user, $model = null) {\n            return true;\n        });\n\n        $middleware = [SubstituteBindings::class, Authorize::class.':view-comments,post'];\n\n        $this->router->get('comments', [\n            'middleware' => $middleware,\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n        $this->router->get('posts/{post}/comments', [\n            'middleware' => $middleware,\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('posts/1/comments', 'GET'));\n        $this->assertSame('success', $response->content());\n\n        $response = $this->router->dispatch(Request::create('comments', 'GET'));\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testSimpleAbilityWithStringParameterFromRouteParameter()\n    {\n        $this->gate()->define('view-dashboard', function ($user, $param) {\n            return $param === 'true';\n        });\n\n        $this->router->get('dashboard/{route_parameter}', [\n            'middleware' => Authorize::class.':view-dashboard,route_parameter',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('dashboard/true', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testSimpleAbilityWithStringParameter0FromRouteParameter()\n    {\n        $this->gate()->define('view-dashboard', function ($user, $param) {\n            return $param === '0';\n        });\n\n        $this->router->get('dashboard/{route_parameter}', [\n            'middleware' => Authorize::class.':view-dashboard,route_parameter',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('dashboard/0', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testModelTypeUnauthorized()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('This action is unauthorized.');\n\n        $this->gate()->define('create', function ($user, $model) {\n            $this->assertSame('App\\User', $model);\n\n            return false;\n        });\n\n        $this->router->get('users/create', [\n            'middleware' => [SubstituteBindings::class, Authorize::class.':create,App\\User'],\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $this->router->dispatch(Request::create('users/create', 'GET'));\n    }\n\n    public function testModelTypeAuthorized()\n    {\n        $this->gate()->define('create', function ($user, $model) {\n            $this->assertSame('App\\User', $model);\n\n            return true;\n        });\n\n        $this->router->get('users/create', [\n            'middleware' => Authorize::class.':create,App\\User',\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('users/create', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testModelUnauthorized()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('This action is unauthorized.');\n\n        $post = new stdClass;\n\n        $this->router->bind('post', function () use ($post) {\n            return $post;\n        });\n\n        $this->gate()->define('edit', function ($user, $model) use ($post) {\n            $this->assertSame($model, $post);\n\n            return false;\n        });\n\n        $this->router->get('posts/{post}/edit', [\n            'middleware' => [SubstituteBindings::class, Authorize::class.':edit,post'],\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $this->router->dispatch(Request::create('posts/1/edit', 'GET'));\n    }\n\n    public function testModelAuthorized()\n    {\n        $post = new stdClass;\n\n        $this->router->bind('post', function () use ($post) {\n            return $post;\n        });\n\n        $this->gate()->define('edit', function ($user, $model) use ($post) {\n            $this->assertSame($model, $post);\n\n            return true;\n        });\n\n        $this->router->get('posts/{post}/edit', [\n            'middleware' => [SubstituteBindings::class, Authorize::class.':edit,post'],\n            'uses' => function () {\n                return 'success';\n            },\n        ]);\n\n        $response = $this->router->dispatch(Request::create('posts/1/edit', 'GET'));\n\n        $this->assertSame('success', $response->content());\n    }\n\n    public function testModelInstanceAsParameter()\n    {\n        $instance = m::mock(Model::class);\n\n        $this->gate()->define('success', function ($user, $model) use ($instance) {\n            $this->assertSame($model, $instance);\n\n            return true;\n        });\n\n        $request = m::mock(Request::class);\n\n        $next = function () {\n            //\n        };\n\n        (new Authorize($this->gate()))\n            ->handle($request, $next, 'success', $instance);\n    }\n\n    /**\n     * Get the Gate instance from the container.\n     *\n     * @return \\Illuminate\\Auth\\Access\\Gate\n     */\n    protected function gate()\n    {\n        return $this->container->make(GateContract::class);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/AuthorizesResourcesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Closure;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Routing\\Router;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthorizesResourcesTest extends TestCase\n{\n    public function testCreateMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'create', 'can:create,App\\User');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'create', 'can:create,App\\User,App\\Post');\n    }\n\n    public function testStoreMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'store', 'can:create,App\\User');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'store', 'can:create,App\\User,App\\Post');\n    }\n\n    public function testShowMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'show', 'can:view,user');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'show', 'can:view,user,post');\n    }\n\n    public function testEditMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'edit', 'can:update,user');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'edit', 'can:update,user,post');\n    }\n\n    public function testUpdateMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'update', 'can:update,user');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'update', 'can:update,user,post');\n    }\n\n    public function testDestroyMethod()\n    {\n        $controller = new AuthorizesResourcesController;\n\n        $this->assertHasMiddleware($controller, 'destroy', 'can:delete,user');\n\n        $controller = new AuthorizesResourcesWithArrayController;\n\n        $this->assertHasMiddleware($controller, 'destroy', 'can:delete,user,post');\n    }\n\n    /**\n     * Assert that the given middleware has been registered on the given controller for the given method.\n     *\n     * @param  \\Illuminate\\Routing\\Controller  $controller\n     * @param  string  $method\n     * @param  string  $middleware\n     * @return void\n     */\n    protected function assertHasMiddleware($controller, $method, $middleware)\n    {\n        $router = new Router(new Dispatcher);\n\n        $router->aliasMiddleware('can', AuthorizesResourcesMiddleware::class);\n        $router->get($method)->uses(get_class($controller).'@'.$method);\n\n        $this->assertSame(\n            'caught '.$middleware,\n            $router->dispatch(Request::create($method, 'GET'))->getContent(),\n            \"The [{$middleware}] middleware was not registered for method [{$method}]\"\n        );\n    }\n}\n\nclass AuthorizesResourcesController extends Controller\n{\n    use AuthorizesRequests;\n\n    public function __construct()\n    {\n        $this->authorizeResource('App\\User', 'user');\n    }\n\n    public function index()\n    {\n        //\n    }\n\n    public function create()\n    {\n        //\n    }\n\n    public function store()\n    {\n        //\n    }\n\n    public function show()\n    {\n        //\n    }\n\n    public function edit()\n    {\n        //\n    }\n\n    public function update()\n    {\n        //\n    }\n\n    public function destroy()\n    {\n        //\n    }\n}\n\nclass AuthorizesResourcesWithArrayController extends Controller\n{\n    use AuthorizesRequests;\n\n    public function __construct()\n    {\n        $this->authorizeResource(['App\\User', 'App\\Post'], ['user', 'post']);\n    }\n\n    public function index()\n    {\n        //\n    }\n\n    public function create()\n    {\n        //\n    }\n\n    public function store()\n    {\n        //\n    }\n\n    public function show()\n    {\n        //\n    }\n\n    public function edit()\n    {\n        //\n    }\n\n    public function update()\n    {\n        //\n    }\n\n    public function destroy()\n    {\n        //\n    }\n}\n\nclass AuthorizesResourcesMiddleware\n{\n    public function handle($request, Closure $next, $method, $parameter, ...$models)\n    {\n        $params = array_merge([$parameter], $models);\n\n        return \"caught can:{$method},\".implode(',', $params);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/EnsureEmailIsVerifiedTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nuse Illuminate\\Auth\\Middleware\\EnsureEmailIsVerified;\nuse PHPUnit\\Framework\\TestCase;\n\nclass EnsureEmailIsVerifiedTest extends TestCase\n{\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = EnsureEmailIsVerified::redirectTo('route.name');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\EnsureEmailIsVerified:route.name', $signature);\n    }\n}\n"
  },
  {
    "path": "tests/Auth/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Auth;\n\nenum AbilitiesEnum: string\n{\n    case VIEW_DASHBOARD = 'view-dashboard';\n    case UPDATE = 'update';\n}\n"
  },
  {
    "path": "tests/Auth/RedirectIfAuthenticatedMiddlewareTest.php",
    "content": "<?php\n\nnamespace Auth;\n\nuse Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RedirectIfAuthenticatedMiddlewareTest extends TestCase\n{\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = RedirectIfAuthenticated::using('foo');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated:foo', $signature);\n\n        $signature = RedirectIfAuthenticated::using('foo', 'bar');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated:foo,bar', $signature);\n\n        $signature = RedirectIfAuthenticated::using('foo', 'bar', 'baz');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated:foo,bar,baz', $signature);\n    }\n}\n"
  },
  {
    "path": "tests/Broadcasting/AblyBroadcasterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Ably\\AblyRest;\nuse Illuminate\\Broadcasting\\Broadcasters\\AblyBroadcaster;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass AblyBroadcasterTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Broadcasting\\Broadcasters\\AblyBroadcaster\n     */\n    public $broadcaster;\n\n    public $ably;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->ably = m::mock(AblyRest::class, ['abcd:efgh']);\n\n        $this->broadcaster = m::mock(AblyBroadcaster::class, [$this->ably])->makePartial();\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPrivateChannelWhenCallbackReturnTrue()\n    {\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenCallbackReturnFalse()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return false;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPresenceChannelWhenCallbackReturnAnArray()\n    {\n        $returnData = [1, 2, 3, 4];\n        $this->broadcaster->channel('test', function () use ($returnData) {\n            return $returnData;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenCallbackReturnNull()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            //\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return [1, 2, 3, 4];\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('presence-test')\n        );\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel, 'socket_id' => 'abcd.1234']);\n\n        $request->shouldReceive('input')\n            ->with('callback', false)\n            ->andReturn(false);\n\n        $user = m::mock('User');\n        $user->shouldReceive('getAuthIdentifierForBroadcasting')\n            ->andReturn(42);\n        $user->shouldReceive('getAuthIdentifier')\n            ->andReturn(42);\n\n        $request->shouldReceive('user')\n            ->andReturn($user);\n\n        return $request;\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithoutUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel]);\n\n        $request->shouldReceive('user')\n            ->andReturn(null);\n\n        return $request;\n    }\n}\n"
  },
  {
    "path": "tests/Broadcasting/BroadcastEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Exception;\nuse Illuminate\\Broadcasting\\BroadcastEvent;\nuse Illuminate\\Broadcasting\\InteractsWithBroadcasting;\nuse Illuminate\\Contracts\\Broadcasting\\Broadcaster;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastingFactory;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nclass BroadcastEventTest extends TestCase\n{\n    public function testBasicEventBroadcastParameterFormatting()\n    {\n        $broadcaster = m::mock(Broadcaster::class);\n\n        $broadcaster->shouldReceive('broadcast')->once()->with(\n            ['test-channel'], TestBroadcastEvent::class, ['firstName' => 'Taylor', 'lastName' => 'Otwell', 'collection' => ['foo' => 'bar']]\n        );\n\n        $manager = m::mock(BroadcastingFactory::class);\n\n        $manager->shouldReceive('connection')->once()->with(null)->andReturn($broadcaster);\n\n        $event = new TestBroadcastEvent;\n\n        (new BroadcastEvent($event))->handle($manager);\n    }\n\n    public function testManualParameterSpecification()\n    {\n        $broadcaster = m::mock(Broadcaster::class);\n\n        $broadcaster->shouldReceive('broadcast')->once()->with(\n            ['test-channel'], TestBroadcastEventWithManualData::class, ['name' => 'Taylor', 'socket' => null]\n        );\n\n        $manager = m::mock(BroadcastingFactory::class);\n\n        $manager->shouldReceive('connection')->once()->with(null)->andReturn($broadcaster);\n\n        $event = new TestBroadcastEventWithManualData;\n\n        (new BroadcastEvent($event))->handle($manager);\n    }\n\n    public function testSpecificBroadcasterGiven()\n    {\n        $broadcaster = m::mock(Broadcaster::class);\n\n        $broadcaster->shouldReceive('broadcast')->once();\n\n        $manager = m::mock(BroadcastingFactory::class);\n\n        $manager->shouldReceive('connection')->once()->with('log')->andReturn($broadcaster);\n\n        $event = new TestBroadcastEventWithSpecificBroadcaster;\n\n        (new BroadcastEvent($event))->handle($manager);\n    }\n\n    public function testSpecificChannelsPerConnection()\n    {\n        $broadcaster = m::mock(Broadcaster::class);\n\n        $broadcaster->shouldReceive('broadcast')->once()->with(\n            ['first-channel'], TestBroadcastEventWithChannelsPerConnection::class, ['firstName' => 'Taylor', 'lastName' => 'Otwell', 'collection' => ['foo' => 'bar']]\n        );\n\n        $broadcaster->shouldReceive('broadcast')->once()->with(\n            ['second-channel'], TestBroadcastEventWithChannelsPerConnection::class, ['firstName' => 'Taylor']\n        );\n\n        $manager = m::mock(BroadcastingFactory::class);\n\n        $manager->shouldReceive('connection')->once()->with('first_connection')->andReturn($broadcaster);\n        $manager->shouldReceive('connection')->once()->with('second_connection')->andReturn($broadcaster);\n\n        $event = new TestBroadcastEventWithChannelsPerConnection;\n\n        (new BroadcastEvent($event))->handle($manager);\n    }\n\n    public function testMiddlewareProxiesMiddlewareFromUnderlyingEvent()\n    {\n        $event = new class\n        {\n            public function middleware(): array\n            {\n                return ['foo', 'bar'];\n            }\n        };\n\n        $job = new BroadcastEvent($event);\n\n        $this->assertSame(['foo', 'bar'], $job->middleware());\n    }\n\n    public function testMiddlewareProxiesFailedHandlerFromUnderlyingEvent()\n    {\n        $event = new class\n        {\n            public function failed(?Throwable $e = null): void\n            {\n                $e->validateCall();\n            }\n        };\n\n        $job = new BroadcastEvent($event);\n\n        $exception = m::mock(Exception::class);\n        $exception->expects('validateCall');\n\n        $job->failed($exception);\n    }\n}\n\nclass TestBroadcastEvent\n{\n    public $firstName = 'Taylor';\n    public $lastName = 'Otwell';\n    public $collection;\n    private $title = 'Developer';\n\n    public function __construct()\n    {\n        $this->collection = collect(['foo' => 'bar']);\n    }\n\n    public function broadcastOn()\n    {\n        return ['test-channel'];\n    }\n}\n\nclass TestBroadcastEventWithManualData extends TestBroadcastEvent\n{\n    public function broadcastWith()\n    {\n        return ['name' => 'Taylor'];\n    }\n}\n\nclass TestBroadcastEventWithSpecificBroadcaster extends TestBroadcastEvent\n{\n    use InteractsWithBroadcasting;\n\n    public function __construct()\n    {\n        $this->broadcastVia('log');\n    }\n}\n\nclass TestBroadcastEventWithChannelsPerConnection extends TestBroadcastEvent\n{\n    public function broadcastConnections()\n    {\n        return [\n            'first_connection',\n            'second_connection',\n        ];\n    }\n\n    public function broadcastWith()\n    {\n        return [\n            'first_connection' => [\n                'firstName' => 'Taylor',\n                'lastName' => 'Otwell',\n                'collection' => ['foo' => 'bar'],\n            ],\n            'second_connection' => [\n                'firstName' => 'Taylor',\n            ],\n        ];\n    }\n\n    public function broadcastOn()\n    {\n        return [\n            'first_connection' => ['first-channel'],\n            'second_connection' => ['second-channel'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Broadcasting/BroadcasterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Exception;\nuse Illuminate\\Broadcasting\\Broadcasters\\Broadcaster;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Routing\\BindingRegistrar;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\RouteBinding;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass BroadcasterTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Tests\\Broadcasting\\FakeBroadcaster\n     */\n    public $broadcaster;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->broadcaster = new FakeBroadcaster;\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testExtractingParametersWhileCheckingForUserAccess()\n    {\n        $callback = function ($user, BroadcasterTestEloquentModelStub $model, $nonModel) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('asd.{model}.{nonModel}', 'asd.1.something', $callback);\n        $this->assertEquals(['model.1.instance', 'something'], $parameters);\n\n        $callback = function ($user, BroadcasterTestEloquentModelStub $model, BroadcasterTestEloquentModelStub $model2, $something) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('asd.{model}.{model2}.{nonModel}', 'asd.1.uid.something', $callback);\n        $this->assertEquals(['model.1.instance', 'model.uid.instance', 'something'], $parameters);\n\n        $callback = function ($user) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('asd', 'asd', $callback);\n        $this->assertEquals([], $parameters);\n\n        $callback = function ($user, $something) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('asd', 'asd', $callback);\n        $this->assertEquals([], $parameters);\n\n        // Test Explicit Binding...\n        $container = new Container;\n        Container::setInstance($container);\n        $binder = m::mock(BindingRegistrar::class);\n        $binder->shouldReceive('getBindingCallback')->times(2)->with('model')->andReturn(function () {\n            return 'bound';\n        });\n        $container->instance(BindingRegistrar::class, $binder);\n        $callback = function ($user, $model) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('something.{model}', 'something.1', $callback);\n        $this->assertEquals(['bound'], $parameters);\n        Container::setInstance(new Container);\n    }\n\n    public function testCanUseChannelClasses()\n    {\n        $parameters = $this->broadcaster->extractAuthParameters('asd.{model}.{nonModel}', 'asd.1.something', DummyBroadcastingChannel::class);\n        $this->assertEquals(['model.1.instance', 'something'], $parameters);\n    }\n\n    public function testModelRouteBinding()\n    {\n        $container = new Container;\n        Container::setInstance($container);\n        $binder = m::mock(BindingRegistrar::class);\n        $callback = RouteBinding::forModel($container, BroadcasterTestEloquentModelStub::class);\n\n        $binder->shouldReceive('getBindingCallback')->times(2)->with('model')->andReturn($callback);\n        $container->instance(BindingRegistrar::class, $binder);\n        $callback = function ($user, $model) {\n            //\n        };\n        $parameters = $this->broadcaster->extractAuthParameters('something.{model}', 'something.1', $callback);\n        $this->assertEquals(['model.1.instance'], $parameters);\n        Container::setInstance(new Container);\n    }\n\n    public function testUnknownChannelAuthHandlerTypeThrowsException()\n    {\n        $this->expectException(Exception::class);\n\n        $this->broadcaster->extractAuthParameters('asd.{model}.{nonModel}', 'asd.1.something', 123);\n    }\n\n    public function testCanRegisterChannelsAsClasses()\n    {\n        $this->broadcaster->channel('something', function () {\n            //\n        });\n\n        $this->broadcaster->channel('somethingelse', DummyBroadcastingChannel::class);\n    }\n\n    public function testNotFoundThrowsHttpException()\n    {\n        $this->expectException(HttpException::class);\n\n        $callback = function ($user, BroadcasterTestEloquentModelNotFoundStub $model) {\n            //\n        };\n        $this->broadcaster->extractAuthParameters('asd.{model}', 'asd.1', $callback);\n    }\n\n    public function testCanRegisterChannelsWithoutOptions()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        });\n    }\n\n    public function testCanRegisterChannelsWithOptions()\n    {\n        $options = ['a' => ['b', 'c']];\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, $options);\n    }\n\n    public function testCanRetrieveChannelsOptions()\n    {\n        $options = ['a' => ['b', 'c']];\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, $options);\n\n        $this->assertEquals(\n            $options,\n            $this->broadcaster->retrieveChannelOptions('somechannel')\n        );\n    }\n\n    public function testCanRetrieveChannelsOptionsUsingAChannelNameContainingArgs()\n    {\n        $options = ['a' => ['b', 'c']];\n        $this->broadcaster->channel('somechannel.{id}.test.{text}', function () {\n            //\n        }, $options);\n\n        $this->assertEquals(\n            $options,\n            $this->broadcaster->retrieveChannelOptions('somechannel.23.test.mytext')\n        );\n    }\n\n    public function testCanRetrieveChannelsOptionsWhenMultipleChannelsAreRegistered()\n    {\n        $options = ['a' => ['b', 'c']];\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        });\n        $this->broadcaster->channel('someotherchannel', function () {\n            //\n        }, $options);\n\n        $this->assertEquals(\n            $options,\n            $this->broadcaster->retrieveChannelOptions('someotherchannel')\n        );\n    }\n\n    public function testDontRetrieveChannelsOptionsWhenChannelDoesntExists()\n    {\n        $options = ['a' => ['b', 'c']];\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, $options);\n\n        $this->assertEquals(\n            [],\n            $this->broadcaster->retrieveChannelOptions('someotherchannel')\n        );\n    }\n\n    public function testRetrieveUserWithoutGuard()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        });\n\n        $request = m::mock(Request::class);\n        $request->shouldReceive('user')\n            ->once()\n            ->withNoArgs()\n            ->andReturn(new DummyUser);\n\n        $this->assertInstanceOf(\n            DummyUser::class,\n            $this->broadcaster->retrieveUser($request, 'somechannel')\n        );\n    }\n\n    public function testRetrieveUserWithOneGuardUsingAStringForSpecifyingGuard()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, ['guards' => 'myguard']);\n\n        $request = m::mock(Request::class);\n        $request->shouldReceive('user')\n            ->once()\n            ->with('myguard')\n            ->andReturn(new DummyUser);\n\n        $this->assertInstanceOf(\n            DummyUser::class,\n            $this->broadcaster->retrieveUser($request, 'somechannel')\n        );\n    }\n\n    public function testRetrieveUserWithMultipleGuardsAndRespectGuardsOrder()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, ['guards' => ['myguard1', 'myguard2']]);\n        $this->broadcaster->channel('someotherchannel', function () {\n            //\n        }, ['guards' => ['myguard2', 'myguard1']]);\n\n        $request = m::mock(Request::class);\n        $request->shouldReceive('user')\n            ->once()\n            ->with('myguard1')\n            ->andReturn(null);\n        $request->shouldReceive('user')\n            ->twice()\n            ->with('myguard2')\n            ->andReturn(new DummyUser)\n            ->ordered('user');\n\n        $this->assertInstanceOf(\n            DummyUser::class,\n            $this->broadcaster->retrieveUser($request, 'somechannel')\n        );\n\n        $this->assertInstanceOf(\n            DummyUser::class,\n            $this->broadcaster->retrieveUser($request, 'someotherchannel')\n        );\n    }\n\n    public function testRetrieveUserDontUseDefaultGuardWhenOneGuardSpecified()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, ['guards' => 'myguard']);\n\n        $request = m::mock(Request::class);\n        $request->shouldReceive('user')\n            ->once()\n            ->with('myguard')\n            ->andReturn(null);\n        $request->shouldNotReceive('user')\n            ->withNoArgs();\n\n        $this->broadcaster->retrieveUser($request, 'somechannel');\n    }\n\n    public function testRetrieveUserDontUseDefaultGuardWhenMultipleGuardsSpecified()\n    {\n        $this->broadcaster->channel('somechannel', function () {\n            //\n        }, ['guards' => ['myguard1', 'myguard2']]);\n\n        $request = m::mock(Request::class);\n        $request->shouldReceive('user')\n            ->once()\n            ->with('myguard1')\n            ->andReturn(null);\n        $request->shouldReceive('user')\n            ->once()\n            ->with('myguard2')\n            ->andReturn(null);\n        $request->shouldNotReceive('user')\n            ->withNoArgs();\n\n        $this->broadcaster->retrieveUser($request, 'somechannel');\n    }\n\n    public function testUserAuthenticationWithValidUser()\n    {\n        $this->broadcaster->resolveAuthenticatedUserUsing(function ($request) {\n            return ['id' => '12345', 'socket' => $request->socket_id];\n        });\n\n        $user = $this->broadcaster->resolveAuthenticatedUser(new Request(['socket_id' => '1234.1234']));\n\n        $this->assertSame([\n            'id' => '12345',\n            'socket' => '1234.1234',\n        ], $user);\n    }\n\n    public function testUserAuthenticationWithInvalidUser()\n    {\n        $this->broadcaster->resolveAuthenticatedUserUsing(function ($request) {\n            return null;\n        });\n\n        $user = $this->broadcaster->resolveAuthenticatedUser(new Request(['socket_id' => '1234.1234']));\n\n        $this->assertNull($user);\n    }\n\n    public function testUserAuthenticationWithoutResolve()\n    {\n        $this->assertNull($this->broadcaster->resolveAuthenticatedUser(new Request(['socket_id' => '1234.1234'])));\n    }\n\n    #[DataProvider('channelNameMatchPatternProvider')]\n    public function testChannelNameMatchPattern($channel, $pattern, $shouldMatch)\n    {\n        $this->assertEquals($shouldMatch, $this->broadcaster->channelNameMatchesPattern($channel, $pattern));\n    }\n\n    public static function channelNameMatchPatternProvider()\n    {\n        return [\n            ['something', 'something', true],\n            ['something.23', 'something.{id}', true],\n            ['something.23.test', 'something.{id}.test', true],\n            ['something.23.test.42', 'something.{id}.test.{id2}', true],\n            ['something-23:test-42', 'something-{id}:test-{id2}', true],\n            ['something..test.42', 'something.{id}.test.{id2}', false],\n            ['23:string:test', '{id}:string:{text}', true],\n            ['something.23', 'something', false],\n            ['something.23.test.42', 'something.test.{id}', false],\n            ['something-23-test-42', 'something-{id}-test', false],\n            ['23:test', '{id}:test:abcd', false],\n            ['customer.order.1', 'order.{id}', false],\n            ['customerorder.1', 'order.{id}', false],\n        ];\n    }\n}\n\nclass FakeBroadcaster extends Broadcaster\n{\n    public function auth($request)\n    {\n        //\n    }\n\n    public function validAuthenticationResponse($request, $result)\n    {\n        //\n    }\n\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        //\n    }\n\n    public function extractAuthParameters($pattern, $channel, $callback)\n    {\n        return parent::extractAuthParameters($pattern, $channel, $callback);\n    }\n\n    public function retrieveChannelOptions($channel)\n    {\n        return parent::retrieveChannelOptions($channel);\n    }\n\n    public function retrieveUser($request, $channel)\n    {\n        return parent::retrieveUser($request, $channel);\n    }\n\n    public function channelNameMatchesPattern($channel, $pattern)\n    {\n        return parent::channelNameMatchesPattern($channel, $pattern);\n    }\n}\n\nclass BroadcasterTestEloquentModelStub extends Model\n{\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        return \"model.{$this->value}.instance\";\n    }\n}\n\nclass BroadcasterTestEloquentModelNotFoundStub extends Model\n{\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        //\n    }\n}\n\nclass DummyBroadcastingChannel\n{\n    public function join($user, BroadcasterTestEloquentModelStub $model, $nonModel)\n    {\n        //\n    }\n}\n\nclass DummyUser\n{\n    //\n}\n"
  },
  {
    "path": "tests/Broadcasting/PusherBroadcasterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Illuminate\\Broadcasting\\Broadcasters\\PusherBroadcaster;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass PusherBroadcasterTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Broadcasting\\Broadcasters\\PusherBroadcaster\n     */\n    public $broadcaster;\n\n    public $pusher;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->pusher = m::mock('Pusher\\Pusher');\n        $this->broadcaster = m::mock(PusherBroadcaster::class, [$this->pusher])->makePartial();\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPrivateChannelWhenCallbackReturnTrue()\n    {\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenCallbackReturnFalse()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return false;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPresenceChannelWhenCallbackReturnAnArray()\n    {\n        $returnData = [1, 2, 3, 4];\n        $this->broadcaster->channel('test', function () use ($returnData) {\n            return $returnData;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenCallbackReturnNull()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            //\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return [1, 2, 3, 4];\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('presence-test')\n        );\n    }\n\n    public function testValidAuthenticationResponseCallPusherSocketAuthMethodWithPrivateChannel()\n    {\n        $request = $this->getMockRequestWithUserForChannel('private-test');\n\n        $data = [\n            'auth' => 'abcd:efgh',\n        ];\n\n        $this->pusher->shouldReceive('socket_auth')\n            ->once()\n            ->andReturn(json_encode($data));\n\n        $this->assertEquals(\n            $data,\n            $this->broadcaster->validAuthenticationResponse($request, true)\n        );\n    }\n\n    public function testValidAuthenticationResponseCallPusherPresenceAuthMethodWithPresenceChannel()\n    {\n        $request = $this->getMockRequestWithUserForChannel('presence-test');\n\n        $data = [\n            'auth' => 'abcd:efgh',\n            'channel_data' => [\n                'user_id' => 42,\n                'user_info' => [1, 2, 3, 4],\n            ],\n        ];\n\n        $this->pusher->shouldReceive('presence_auth')\n            ->once()\n            ->andReturn(json_encode($data));\n\n        $this->assertEquals(\n            $data,\n            $this->broadcaster->validAuthenticationResponse($request, true)\n        );\n    }\n\n    public function testUserAuthenticationForPusher()\n    {\n        $this->pusher\n            ->shouldReceive('getSettings')\n            ->andReturn([\n                'auth_key' => '278d425bdf160c739803',\n                'secret' => '7ad3773142a6692b25b8',\n            ]);\n\n        $this->broadcaster = new PusherBroadcaster($this->pusher);\n\n        $this->broadcaster->resolveAuthenticatedUserUsing(function () {\n            return ['id' => '12345'];\n        });\n\n        $response = $this->broadcaster->resolveAuthenticatedUser(new Request(['socket_id' => '1234.1234']));\n\n        // The result is hard-coded from the Pusher docs\n        // See: https://pusher.com/docs/channels/library_auth_reference/auth-signatures/#user-authentication\n        $this->assertSame([\n            'auth' => '278d425bdf160c739803:4708d583dada6a56435fb8bc611c77c359a31eebde13337c16ab43aa6de336ba',\n            'user_data' => json_encode(['id' => '12345']),\n        ], $response);\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel, 'socket_id' => 'abcd.1234']);\n\n        $request->shouldReceive('input')\n            ->with('callback', false)\n            ->andReturn(false);\n\n        $user = m::mock('User');\n        $user->shouldReceive('getAuthIdentifierForBroadcasting')\n            ->andReturn(42);\n        $user->shouldReceive('getAuthIdentifier')\n            ->andReturn(42);\n\n        $request->shouldReceive('user')\n            ->andReturn($user);\n\n        return $request;\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithoutUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel]);\n\n        $request->shouldReceive('user')\n            ->andReturn(null);\n\n        return $request;\n    }\n}\n"
  },
  {
    "path": "tests/Broadcasting/RedisBroadcasterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Illuminate\\Broadcasting\\Broadcasters\\RedisBroadcaster;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\n\nclass RedisBroadcasterTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Broadcasting\\Broadcasters\\RedisBroadcaster\n     */\n    public $broadcaster;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->broadcaster = m::mock(RedisBroadcaster::class)->makePartial();\n        $container = Container::setInstance(new Container);\n\n        $container->singleton('config', function () {\n            return $this->createConfig();\n        });\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPrivateChannelWhenCallbackReturnTrue()\n    {\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenCallbackReturnFalse()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return false;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPrivateChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return true;\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('private-test')\n        );\n    }\n\n    public function testAuthCallValidAuthenticationResponseWithPresenceChannelWhenCallbackReturnAnArray()\n    {\n        $returnData = [1, 2, 3, 4];\n        $this->broadcaster->channel('test', function () use ($returnData) {\n            return $returnData;\n        });\n\n        $this->broadcaster->shouldReceive('validAuthenticationResponse')\n            ->once();\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenCallbackReturnNull()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            //\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithUserForChannel('presence-test')\n        );\n    }\n\n    public function testAuthThrowAccessDeniedHttpExceptionWithPresenceChannelWhenRequestUserNotFound()\n    {\n        $this->expectException(AccessDeniedHttpException::class);\n\n        $this->broadcaster->channel('test', function () {\n            return [1, 2, 3, 4];\n        });\n\n        $this->broadcaster->auth(\n            $this->getMockRequestWithoutUserForChannel('presence-test')\n        );\n    }\n\n    public function testValidAuthenticationResponseWithPrivateChannel()\n    {\n        $request = $this->getMockRequestWithUserForChannel('private-test');\n\n        $this->assertEquals(\n            json_encode(true),\n            $this->broadcaster->validAuthenticationResponse($request, true)\n        );\n    }\n\n    public function testValidAuthenticationResponseWithPresenceChannel()\n    {\n        $request = $this->getMockRequestWithUserForChannel('presence-test');\n\n        $this->assertEquals(\n            json_encode([\n                'channel_data' => [\n                    'user_id' => 42,\n                    'user_info' => [\n                        'a' => 'b',\n                        'c' => 'd',\n                    ],\n                ],\n            ]),\n            $this->broadcaster->validAuthenticationResponse($request, [\n                'a' => 'b',\n                'c' => 'd',\n            ])\n        );\n    }\n\n    /**\n     * Create a new config repository instance.\n     *\n     * @return \\Illuminate\\Config\\Repository\n     */\n    protected function createConfig()\n    {\n        return new Config([\n            'redis' => [\n                'options' => ['prefix' => 'laravel_database_'],\n            ],\n        ]);\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel]);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel]);\n\n        $user = m::mock('User');\n        $user->shouldReceive('getAuthIdentifierForBroadcasting')\n            ->andReturn(42);\n        $user->shouldReceive('getAuthIdentifier')\n            ->andReturn(42);\n\n        $request->shouldReceive('user')\n            ->andReturn($user);\n\n        return $request;\n    }\n\n    /**\n     * @param  string  $channel\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function getMockRequestWithoutUserForChannel($channel)\n    {\n        $request = m::mock(Request::class);\n        $request->shouldReceive('all')->andReturn(['channel_name' => $channel]);\n\n        $request->shouldReceive('user')\n            ->andReturn(null);\n\n        return $request;\n    }\n}\n"
  },
  {
    "path": "tests/Broadcasting/UsePusherChannelsNamesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Broadcasting;\n\nuse Illuminate\\Broadcasting\\Broadcasters\\Broadcaster;\nuse Illuminate\\Broadcasting\\Broadcasters\\UsePusherChannelConventions;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass UsePusherChannelsNamesTest extends TestCase\n{\n    #[DataProvider('channelsProvider')]\n    public function testChannelNameNormalization($requestChannelName, $normalizedName, $guarded)\n    {\n        $broadcaster = new FakeBroadcasterUsingPusherChannelsNames;\n\n        $this->assertSame(\n            $normalizedName,\n            $broadcaster->normalizeChannelName($requestChannelName)\n        );\n    }\n\n    public function testChannelNameNormalizationSpecialCase()\n    {\n        $broadcaster = new FakeBroadcasterUsingPusherChannelsNames;\n\n        $this->assertSame(\n            'private-123',\n            $broadcaster->normalizeChannelName('private-encrypted-private-123')\n        );\n    }\n\n    public function testChannelNamePatternMatching()\n    {\n        $broadcaster = new FakeBroadcasterUsingPusherChannelsNames;\n\n        $this->assertEquals(\n            0,\n            $broadcaster->testChannelNameMatchesPattern(\n                'TestChannel',\n                'Test.{id}'\n            )\n        );\n    }\n\n    #[DataProvider('channelsProvider')]\n    public function testIsGuardedChannel($requestChannelName, $normalizedName, $guarded)\n    {\n        $broadcaster = new FakeBroadcasterUsingPusherChannelsNames;\n\n        $this->assertSame(\n            $guarded,\n            $broadcaster->isGuardedChannel($requestChannelName)\n        );\n    }\n\n    public static function channelsProvider()\n    {\n        $prefixesInfos = [\n            ['prefix' => 'private-', 'guarded' => true],\n            ['prefix' => 'private-encrypted-', 'guarded' => true],\n            ['prefix' => 'presence-', 'guarded' => true],\n            ['prefix' => '', 'guarded' => false],\n        ];\n\n        $channels = [\n            'test',\n            'test-channel',\n            'test-private-channel',\n            'test-presence-channel',\n            'abcd.efgh',\n            'abcd.efgh.ijkl',\n            'test.{param}',\n            'test-{param}',\n            '{a}.{b}',\n            '{a}-{b}',\n            '{a}-{b}.{c}',\n        ];\n\n        $tests = [];\n        foreach ($prefixesInfos as $prefixInfos) {\n            foreach ($channels as $channel) {\n                $tests[] = [\n                    $prefixInfos['prefix'].$channel,\n                    $channel,\n                    $prefixInfos['guarded'],\n                ];\n            }\n        }\n\n        $tests[] = ['private-private-test', 'private-test', true];\n        $tests[] = ['private-presence-test', 'presence-test', true];\n        $tests[] = ['presence-private-test', 'private-test', true];\n        $tests[] = ['presence-presence-test', 'presence-test', true];\n        $tests[] = ['public-test', 'public-test', false];\n\n        return $tests;\n    }\n}\n\nclass FakeBroadcasterUsingPusherChannelsNames extends Broadcaster\n{\n    use UsePusherChannelConventions;\n\n    public function auth($request)\n    {\n        //\n    }\n\n    public function validAuthenticationResponse($request, $result)\n    {\n        //\n    }\n\n    public function broadcast(array $channels, $event, array $payload = [])\n    {\n        //\n    }\n\n    public function testChannelNameMatchesPattern($channel, $pattern)\n    {\n        return $this->channelNameMatchesPattern($channel, $pattern);\n    }\n}\n"
  },
  {
    "path": "tests/Bus/BusBatchTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchFactory;\nuse Illuminate\\Bus\\DatabaseBatchRepository;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Events\\BatchCanceled;\nuse Illuminate\\Bus\\Events\\BatchFinished;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Contracts\\Events\\Dispatcher as EventDispatcher;\nuse Illuminate\\Contracts\\Queue\\Factory;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Foundation\\Bus\\PendingChain;\nuse Illuminate\\Queue\\CallQueuedClosure;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse stdClass;\n\nclass BusBatchTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        if (! Facade::getFacadeApplication()) {\n            $container = new Container;\n            Facade::setFacadeApplication($container);\n\n            $queue = m::mock(Factory::class);\n            $container->instance(Factory::class, $queue);\n            $container->alias(Factory::class, 'queue');\n\n            $dispatcher = m::mock(Dispatcher::class, [$container]);\n\n            $dispatcher->shouldReceive('batch')->zeroOrMoreTimes()->andReturnUsing(function ($jobs) {\n                $pendingBatch = m::mock(PendingBatch::class);\n                $pendingBatch->shouldReceive('name')->andReturnSelf();\n                $pendingBatch->shouldReceive('dispatch')->zeroOrMoreTimes()->andReturn(m::mock(Batch::class));\n\n                return $pendingBatch;\n            })->byDefault();\n\n            $dispatcher->shouldReceive('chain')->zeroOrMoreTimes()->andReturnUsing(function ($jobs) {\n                $pendingChain = m::mock(PendingChain::class, [$jobs, \\stdClass::class]);\n                $pendingChain->shouldReceive('dispatch')->zeroOrMoreTimes()->andReturn(m::mock(Batch::class));\n\n                return $pendingChain;\n            })->byDefault();\n\n            $container->instance(BusDispatcher::class, $dispatcher);\n            $container->alias(BusDispatcher::class, 'bus');\n        }\n\n        $this->createSchema();\n\n        $_SERVER['__finally.count'] = 0;\n        $_SERVER['__progress.count'] = 0;\n        $_SERVER['__then.count'] = 0;\n        $_SERVER['__catch.count'] = 0;\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('job_batches', function ($table) {\n            $table->string('id')->primary();\n            $table->string('name');\n            $table->integer('total_jobs');\n            $table->integer('pending_jobs');\n            $table->integer('failed_jobs');\n            $table->text('failed_job_ids');\n            $table->text('options')->nullable();\n            $table->integer('cancelled_at')->nullable();\n            $table->integer('created_at');\n            $table->integer('finished_at')->nullable();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     */\n    protected function tearDown(): void\n    {\n        if (Facade::getFacadeApplication()) {\n            Facade::setFacadeApplication(null);\n        }\n\n        Container::setInstance(null);\n\n        unset($_SERVER['__finally.batch'], $_SERVER['__progress.batch'], $_SERVER['__then.batch'], $_SERVER['__catch.batch'], $_SERVER['__catch.exception']);\n\n        $this->schema()->drop('job_batches');\n\n        parent::tearDown();\n    }\n\n    public function test_jobs_can_be_added_to_the_batch()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $secondJob = new class\n        {\n            use Batchable;\n        };\n\n        $thirdJob = function () {\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once()->with(m::on(function ($args) use ($job, $secondJob) {\n            return\n                $args[0] == $job &&\n                $args[1] == $secondJob &&\n                $args[2] instanceof CallQueuedClosure\n                && is_string($args[2]->batchId);\n        }), '', 'test-queue');\n\n        $batch = $batch->add([$job, $secondJob, $thirdJob]);\n\n        $this->assertEquals(3, $batch->totalJobs);\n        $this->assertEquals(3, $batch->pendingJobs);\n        $this->assertIsString($job->batchId);\n        $this->assertInstanceOf(CarbonImmutable::class, $batch->createdAt);\n    }\n\n    public function test_jobs_can_be_added_to_pending_batch()\n    {\n        $batch = new PendingBatch(new Container, collect());\n        $this->assertCount(0, $batch->jobs);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n        $batch->add([$job]);\n        $this->assertCount(1, $batch->jobs);\n\n        $secondJob = new class\n        {\n            use Batchable;\n\n            public $anotherProperty;\n        };\n        $batch->add($secondJob);\n        $this->assertCount(2, $batch->jobs);\n    }\n\n    public function test_jobs_can_be_added_to_the_pending_batch_from_iterable()\n    {\n        $batch = new PendingBatch(new Container, collect());\n        $this->assertCount(0, $batch->jobs);\n\n        $count = 3;\n        $generator = function (int $jobsCount) {\n            for ($i = 0; $i < $jobsCount; $i++) {\n                yield new class\n                {\n                    use Batchable;\n                };\n            }\n        };\n\n        $batch->add($generator($count));\n        $this->assertCount($count, $batch->jobs);\n    }\n\n    public function test_processed_jobs_can_be_calculated()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $batch->totalJobs = 10;\n        $batch->pendingJobs = 4;\n\n        $this->assertEquals(6, $batch->processedJobs());\n        $this->assertEquals(60, $batch->progress());\n    }\n\n    public function test_successful_jobs_can_be_recorded()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $secondJob = new class\n        {\n            use Batchable;\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once();\n\n        $batch = $batch->add([$job, $secondJob]);\n        $this->assertEquals(2, $batch->pendingJobs);\n\n        $batch->recordSuccessfulJob('test-id');\n        $batch->recordSuccessfulJob('test-id');\n\n        $this->assertInstanceOf(Batch::class, $_SERVER['__finally.batch']);\n        $this->assertInstanceOf(Batch::class, $_SERVER['__progress.batch']);\n        $this->assertInstanceOf(Batch::class, $_SERVER['__then.batch']);\n\n        $batch = $batch->fresh();\n        $this->assertEquals(0, $batch->pendingJobs);\n        $this->assertTrue($batch->finished());\n        $this->assertEquals(1, $_SERVER['__finally.count']);\n        $this->assertEquals(2, $_SERVER['__progress.count']);\n        $this->assertEquals(1, $_SERVER['__then.count']);\n    }\n\n    public function test_batch_finished_event_is_dispatched()\n    {\n        Container::getInstance()->instance(EventDispatcher::class, $events = m::mock(EventDispatcher::class));\n\n        $queue = m::mock(Factory::class);\n        $batch = $this->createTestBatch($queue);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once();\n\n        $batch = $batch->add([$job]);\n\n        $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) use ($batch) {\n            return $event instanceof BatchFinished && $event->batch === $batch;\n        }));\n\n        $batch->recordSuccessfulJob('test-id');\n    }\n\n    public function test_failed_jobs_can_be_recorded_while_not_allowing_failures()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue, $allowFailures = false);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $secondJob = new class\n        {\n            use Batchable;\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once();\n\n        $batch = $batch->add([$job, $secondJob]);\n        $this->assertEquals(2, $batch->pendingJobs);\n\n        $batch->recordFailedJob('test-id', new RuntimeException('Something went wrong.'));\n        $batch->recordFailedJob('test-id', new RuntimeException('Something else went wrong.'));\n\n        $this->assertInstanceOf(Batch::class, $_SERVER['__finally.batch']);\n        $this->assertFalse(isset($_SERVER['__then.batch']));\n\n        $batch = $batch->fresh();\n        $this->assertEquals(2, $batch->pendingJobs);\n        $this->assertEquals(2, $batch->failedJobs);\n        $this->assertTrue($batch->finished());\n        $this->assertTrue($batch->cancelled());\n        $this->assertEquals(1, $_SERVER['__finally.count']);\n        $this->assertEquals(0, $_SERVER['__progress.count']);\n        $this->assertEquals(1, $_SERVER['__catch.count']);\n        $this->assertSame('Something went wrong.', $_SERVER['__catch.exception']->getMessage());\n    }\n\n    public function test_failed_jobs_can_be_recorded_while_allowing_failures()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue, $allowFailures = true);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $secondJob = new class\n        {\n            use Batchable;\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once();\n\n        $batch = $batch->add([$job, $secondJob]);\n        $this->assertEquals(2, $batch->pendingJobs);\n\n        $batch->recordFailedJob('test-id', new RuntimeException('Something went wrong.'));\n        $batch->recordFailedJob('test-id', new RuntimeException('Something else went wrong.'));\n\n        // While allowing failures this batch never actually completes...\n        $this->assertFalse(isset($_SERVER['__then.batch']));\n\n        $batch = $batch->fresh();\n        $this->assertEquals(2, $batch->pendingJobs);\n        $this->assertEquals(2, $batch->failedJobs);\n        $this->assertFalse($batch->finished());\n        $this->assertFalse($batch->cancelled());\n        $this->assertEquals(1, $_SERVER['__catch.count']);\n        $this->assertEquals(2, $_SERVER['__progress.count']);\n        $this->assertSame('Something went wrong.', $_SERVER['__catch.exception']->getMessage());\n    }\n\n    public function test_pending_batch_filters_out_falsy_jobs()\n    {\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $secondJob = new class\n        {\n            use Batchable;\n        };\n\n        $jobsWithNulls = collect([$job, null, $secondJob, [], 0, '', false]);\n\n        $batch = new PendingBatch(new Container, $jobsWithNulls);\n\n        $this->assertCount(2, $batch->jobs);\n        $this->assertTrue($batch->jobs->contains($job));\n        $this->assertTrue($batch->jobs->contains($secondJob));\n    }\n\n    public function test_failure_callbacks_execute_correctly(): void\n    {\n        $queue = m::mock(Factory::class);\n\n        $repository = new DatabaseBatchRepository(new BatchFactory($queue), DB::connection(), 'job_batches');\n\n        $pendingBatch = (new PendingBatch(new Container, collect()))\n            ->allowFailures([\n                static fn (Batch $batch, $e): true => $_SERVER['__failure1.invoked'] = true,\n                function (Batch $batch, $e) {\n                    $_SERVER['__failure2.invoked'] = true;\n                },\n                function (Batch $batch, $e) {\n                    $_SERVER['__failure3.batch'] = $batch;\n                    $_SERVER['__failure3.exception'] = $e;\n                    $_SERVER['__failure3.batch_id'] = $batch->id;\n                    $_SERVER['__failure3.batch_class'] = get_class($batch);\n                    $_SERVER['__failure3.exception_class'] = get_class($e);\n                    $_SERVER['__failure3.exception_message'] = $e->getMessage();\n                    $_SERVER['__failure3.param_count'] = func_num_args();\n                },\n            ])\n            ->onConnection('test-connection')\n            ->onQueue('test-queue');\n\n        $batch = $repository->store($pendingBatch);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once();\n\n        $batch = $batch->add([$job]);\n\n        $_SERVER['__failure1.invoked'] = false;\n        $_SERVER['__failure2.invoked'] = false;\n        $_SERVER['__failure3.batch'] = null;\n        $_SERVER['__failure3.exception'] = null;\n\n        $batch->recordFailedJob('test-id', new RuntimeException('Comprehensive callback test.'));\n\n        $this->assertTrue($_SERVER['__failure1.invoked']);\n        $this->assertTrue($_SERVER['__failure2.invoked']);\n        $this->assertInstanceOf(Batch::class, $_SERVER['__failure3.batch']);\n        $this->assertSame('Comprehensive callback test.', $_SERVER['__failure3.exception']->getMessage());\n        $this->assertSame($batch->id, $_SERVER['__failure3.batch_id']);\n        $this->assertSame(Batch::class, $_SERVER['__failure3.batch_class']);\n        $this->assertSame(RuntimeException::class, $_SERVER['__failure3.exception_class']);\n        $this->assertEquals(2, $_SERVER['__failure3.param_count']);\n    }\n\n    public function test_batch_can_be_cancelled()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $batch->cancel();\n\n        $batch = $batch->fresh();\n\n        $this->assertTrue($batch->cancelled());\n    }\n\n    public function test_batch_cancelled_event_is_dispatched()\n    {\n        Container::getInstance()->instance(EventDispatcher::class, $events = m::mock(EventDispatcher::class));\n\n        $queue = m::mock(Factory::class);\n        $batch = $this->createTestBatch($queue);\n\n        $exception = new RuntimeException('Something went wrong.');\n\n        $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) use ($batch, $exception) {\n            return $event instanceof BatchCanceled\n                && $event->batch->id === $batch->id\n                && $event->exception === $exception;\n        }));\n\n        $batch->cancel($exception);\n    }\n\n    public function test_batch_can_be_deleted()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $batch->delete();\n\n        $batch = $batch->fresh();\n\n        $this->assertNull($batch);\n    }\n\n    public function test_batch_state_can_be_inspected()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $this->assertFalse($batch->finished());\n        $batch->finishedAt = Carbon::now();\n        $this->assertTrue($batch->finished());\n\n        $batch->options['progress'] = [];\n        $this->assertFalse($batch->hasProgressCallbacks());\n        $batch->options['progress'] = [1];\n        $this->assertTrue($batch->hasProgressCallbacks());\n\n        $batch->options['then'] = [];\n        $this->assertFalse($batch->hasThenCallbacks());\n        $batch->options['then'] = [1];\n        $this->assertTrue($batch->hasThenCallbacks());\n\n        $this->assertFalse($batch->allowsFailures());\n        $batch->options['allowFailures'] = true;\n        $this->assertTrue($batch->allowsFailures());\n\n        $this->assertFalse($batch->hasFailures());\n        $batch->failedJobs = 1;\n        $this->assertTrue($batch->hasFailures());\n\n        $batch->options['catch'] = [];\n        $this->assertFalse($batch->hasCatchCallbacks());\n        $batch->options['catch'] = [1];\n        $this->assertTrue($batch->hasCatchCallbacks());\n\n        $this->assertFalse($batch->cancelled());\n        $batch->cancelledAt = Carbon::now();\n        $this->assertTrue($batch->cancelled());\n\n        $this->assertIsString(json_encode($batch));\n    }\n\n    public function test_chain_can_be_added_to_batch()\n    {\n        $queue = m::mock(Factory::class);\n\n        $batch = $this->createTestBatch($queue);\n\n        $chainHeadJob = new ChainHeadJob;\n\n        $secondJob = new SecondTestJob;\n\n        $thirdJob = new ThirdTestJob;\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once()->with(m::on(function ($args) use ($chainHeadJob, $secondJob, $thirdJob) {\n            return\n                $args[0] == $chainHeadJob\n                && serialize($secondJob) == $args[0]->chained[0]\n                && serialize($thirdJob) == $args[0]->chained[1];\n        }), '', 'test-queue');\n\n        $batch = $batch->add([\n            [$chainHeadJob, $secondJob, $thirdJob],\n        ]);\n\n        $this->assertEquals(3, $batch->totalJobs);\n        $this->assertEquals(3, $batch->pendingJobs);\n        $this->assertSame('test-queue', $chainHeadJob->chainQueue);\n        $this->assertIsString($chainHeadJob->batchId);\n        $this->assertIsString($secondJob->batchId);\n        $this->assertIsString($thirdJob->batchId);\n        $this->assertInstanceOf(CarbonImmutable::class, $batch->createdAt);\n    }\n\n    public function test_chained_jobs_in_batch_preserve_their_queue_when_batch_has_no_queue()\n    {\n        $queue = m::mock(Factory::class);\n\n        $repository = new DatabaseBatchRepository(new BatchFactory($queue), DB::connection(), 'job_batches');\n\n        // Create a batch WITHOUT onQueue — this is the key difference\n        $pendingBatch = (new PendingBatch(new Container, collect()))\n            ->onConnection('test-connection');\n\n        $batch = $repository->store($pendingBatch);\n\n        $firstJob = (new ChainHeadJob)->onQueue('custom-queue');\n        $secondJob = (new SecondTestJob)->onQueue('custom-queue');\n\n        $queue->shouldReceive('connection')->once()\n            ->with('test-connection')\n            ->andReturn($connection = m::mock(stdClass::class));\n\n        $connection->shouldReceive('bulk')->once()->with(m::on(function ($args) {\n            return true;\n        }), '', null);\n\n        $batch->add([\n            [$firstJob, $secondJob],\n        ]);\n\n        // Both jobs had ->onQueue('custom-queue') set before batching.\n        // The second job retains its queue, but the first job's queue\n        // is wiped to null by Batch::add() calling allOnQueue(null).\n        $this->assertSame('custom-queue', $secondJob->queue);\n        $this->assertSame('custom-queue', $firstJob->queue);\n    }\n\n    public function test_chained_closure_after_multiple_batches_is_properly_dispatched()\n    {\n        Queue::fake();\n\n        $TestBatchJob = new class\n        {\n            use Batchable;\n\n            public function handle()\n            {\n            }\n        };\n\n        Bus::chain([\n            Bus::batch([$TestBatchJob])->name('Batch 1'),\n            Bus::batch([$TestBatchJob])->name('Batch 2'),\n            function () {\n            },\n        ])->dispatch();\n\n        $this->assertTrue(true);\n    }\n\n    public function test_options_serialization_on_postgres()\n    {\n        $pendingBatch = (new PendingBatch(new Container, collect()))\n            ->onQueue('test-queue');\n\n        $connection = m::spy(PostgresConnection::class);\n        $builder = m::spy(Builder::class);\n\n        $connection->shouldReceive('table')->andReturn($builder);\n        $builder->shouldReceive('useWritePdo')->andReturnSelf();\n        $builder->shouldReceive('where')->andReturnSelf();\n\n        $repository = new DatabaseBatchRepository(\n            new BatchFactory(m::mock(Factory::class)), $connection, 'job_batches'\n        );\n\n        $repository->store($pendingBatch);\n\n        $builder->shouldHaveReceived('insert')\n            ->withArgs(function ($argument) use ($pendingBatch) {\n                return unserialize(base64_decode($argument['options'])) === $pendingBatch->options;\n            });\n\n        $builder->shouldHaveReceived('first');\n    }\n\n    #[DataProvider('serializedOptions')]\n    public function test_options_unserialize_on_postgres($serialize, $options)\n    {\n        $factory = m::mock(BatchFactory::class);\n\n        $connection = m::spy(PostgresConnection::class);\n\n        $connection->shouldReceive('table->useWritePdo->where->first')\n            ->andReturn($m = (object) [\n                'id' => '',\n                'name' => '',\n                'total_jobs' => '',\n                'pending_jobs' => '',\n                'failed_jobs' => '',\n                'failed_job_ids' => '[]',\n                'options' => $serialize,\n                'created_at' => Carbon::now()->timestamp,\n                'cancelled_at' => null,\n                'finished_at' => null,\n            ]);\n\n        $batch = (new DatabaseBatchRepository($factory, $connection, 'job_batches'));\n\n        $factory->shouldReceive('make')\n            ->withSomeOfArgs($batch, '', '', '', '', '', '', $options);\n\n        $batch->find(1);\n    }\n\n    /**\n     * @return array\n     */\n    public static function serializedOptions()\n    {\n        $options = [1, 2];\n\n        return [\n            [serialize($options), $options],\n            [base64_encode(serialize($options)), $options],\n        ];\n    }\n\n    protected function createTestBatch($queue, $allowFailures = false)\n    {\n        $repository = new DatabaseBatchRepository(new BatchFactory($queue), DB::connection(), 'job_batches');\n\n        $pendingBatch = (new PendingBatch(new Container, collect()))\n            ->progress(function (Batch $batch) {\n                $_SERVER['__progress.batch'] = $batch;\n                $_SERVER['__progress.count']++;\n            })\n            ->then(function (Batch $batch) {\n                $_SERVER['__then.batch'] = $batch;\n                $_SERVER['__then.count']++;\n            })\n            ->catch(function (Batch $batch, $e) {\n                $_SERVER['__catch.batch'] = $batch;\n                $_SERVER['__catch.exception'] = $e;\n                $_SERVER['__catch.count']++;\n            })\n            ->finally(function (Batch $batch) {\n                $_SERVER['__finally.batch'] = $batch;\n                $_SERVER['__finally.count']++;\n            })\n            ->allowFailures($allowFailures)\n            ->onConnection('test-connection')\n            ->onQueue('test-queue');\n\n        return $repository->store($pendingBatch);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Model::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass ChainHeadJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, Queueable;\n}\n\nclass SecondTestJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, Queueable;\n}\n\nclass ThirdTestJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, Queueable;\n}\n"
  },
  {
    "path": "tests/Bus/BusBatchableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Testing\\Fakes\\BatchFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass BusBatchableTest extends TestCase\n{\n    public function test_batch_may_be_retrieved()\n    {\n        $class = new class\n        {\n            use Batchable;\n        };\n\n        $this->assertSame($class, $class->withBatchId('test-batch-id'));\n        $this->assertSame('test-batch-id', $class->batchId);\n\n        Container::setInstance($container = new Container);\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('find')->once()->with('test-batch-id')->andReturn('test-batch');\n        $container->instance(BatchRepository::class, $repository);\n\n        $this->assertSame('test-batch', $class->batch());\n\n        Container::setInstance(null);\n    }\n\n    public function test_with_fake_batch_sets_and_returns_fake()\n    {\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        [$self, $batch] = $job->withFakeBatch('test-batch-id', 'test-batch-name', 3, 3, 0, [], []);\n\n        $this->assertSame($job, $self);\n        $this->assertInstanceOf(BatchFake::class, $batch);\n        $this->assertSame($batch, $job->batch());\n        $this->assertSame('test-batch-id', $job->batch()->id);\n        $this->assertSame('test-batch-name', $job->batch()->name);\n        $this->assertSame(3, $job->batch()->totalJobs);\n    }\n\n    public function test_batching_reflects_cancelled_state()\n    {\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $job->withFakeBatch('test-batch-id', 'test-batch-name');\n\n        // Initially not cancelled\n        $this->assertTrue($job->batching());\n\n        // Cancel the batch and ensure batching() returns false\n        $job->batch()->cancel();\n        $this->assertFalse($job->batching());\n    }\n}\n"
  },
  {
    "path": "tests/Bus/BusDispatcherTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Queue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass BusDispatcherTest extends TestCase\n{\n    public function testCommandsThatShouldQueueIsQueued()\n    {\n        $container = new Container;\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $dispatcher = new Dispatcher($container, function () {\n            $mock = m::mock(Queue::class);\n            $mock->shouldReceive('push')->once();\n\n            return $mock;\n        });\n\n        $dispatcher->dispatch(m::mock(ShouldQueue::class));\n\n        Container::setInstance(null);\n    }\n\n    public function testCommandsThatShouldQueueIsQueuedUsingCustomHandler()\n    {\n        $container = new Container;\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $dispatcher = new Dispatcher($container, function () {\n            $mock = m::mock(Queue::class);\n            $mock->shouldReceive('push')->once();\n\n            return $mock;\n        });\n\n        $dispatcher->dispatch(new BusDispatcherTestCustomQueueCommand);\n\n        Container::setInstance(null);\n    }\n\n    public function testCommandsThatShouldQueueIsQueuedUsingCustomQueueAndDelay()\n    {\n        $container = new Container;\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $dispatcher = new Dispatcher($container, function () {\n            $mock = m::mock(Queue::class);\n            $mock->shouldReceive('later')->once()->with(10, m::type(BusDispatcherTestSpecificQueueAndDelayCommand::class), '', 'foo');\n\n            return $mock;\n        });\n\n        $dispatcher->dispatch(new BusDispatcherTestSpecificQueueAndDelayCommand);\n\n        Container::setInstance(null);\n    }\n\n    public function testCommandsAreDispatchedWithQueueRoute()\n    {\n        Container::setInstance($container = new Container);\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn('high-priority');\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n\n        $mock = m::mock(Queue::class);\n        $mock->shouldReceive('push')->once()->with(BusDispatcherQueueable::class, '', 'high-priority');\n\n        $dispatcher = new Dispatcher($container, function () use ($mock) {\n            return $mock;\n        });\n\n        $dispatcher->dispatch(new BusDispatcherQueueable);\n\n        Container::setInstance(null);\n    }\n\n    public function testDispatchNowShouldNeverQueue()\n    {\n        $container = new Container;\n        $mock = m::mock(Queue::class);\n        $mock->shouldReceive('push')->never();\n        $dispatcher = new Dispatcher($container, function () use ($mock) {\n            return $mock;\n        });\n\n        $dispatcher->dispatch(new BusDispatcherBasicCommand);\n    }\n\n    public function testDispatcherCanDispatchStandAloneHandler()\n    {\n        $container = new Container;\n        $mock = m::mock(Queue::class);\n        $dispatcher = new Dispatcher($container, function () use ($mock) {\n            return $mock;\n        });\n\n        $dispatcher->map([StandAloneCommand::class => StandAloneHandler::class]);\n\n        $response = $dispatcher->dispatch(new StandAloneCommand);\n\n        $this->assertInstanceOf(StandAloneCommand::class, $response);\n    }\n\n    public function testOnConnectionOnJobWhenDispatching()\n    {\n        Container::setInstance($container = new Container);\n        $container->singleton('config', function () {\n            return new Config([\n                'queue' => [\n                    'default' => 'null',\n                    'connections' => [\n                        'null' => ['driver' => 'null'],\n                    ],\n                ],\n            ]);\n        });\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n\n        $dispatcher = new Dispatcher($container, function () {\n            $mock = m::mock(Queue::class);\n            $mock->shouldReceive('push')->once();\n\n            return $mock;\n        });\n\n        $job = (new ShouldNotBeDispatched)->onConnection('null');\n\n        $dispatcher->dispatch($job);\n\n        Container::setInstance(null);\n    }\n}\n\nclass BusInjectionStub\n{\n    //\n}\n\nclass BusDispatcherBasicCommand\n{\n    public $name;\n\n    public function __construct($name = null)\n    {\n        $this->name = $name;\n    }\n\n    public function handle(BusInjectionStub $stub)\n    {\n        //\n    }\n}\n\nclass BusDispatcherTestCustomQueueCommand implements ShouldQueue\n{\n    public function queue($queue, $command)\n    {\n        $queue->push($command);\n    }\n}\n\nclass BusDispatcherTestSpecificQueueAndDelayCommand implements ShouldQueue\n{\n    public $queue = 'foo';\n    public $delay = 10;\n}\n\nclass BusDispatcherQueueable implements ShouldQueue\n{\n    use Queueable;\n}\n\nclass StandAloneCommand\n{\n    //\n}\n\nclass StandAloneHandler\n{\n    public function handle(StandAloneCommand $command)\n    {\n        return $command;\n    }\n}\n\nclass ShouldNotBeDispatched implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        throw new RuntimeException('This should not be run');\n    }\n}\n"
  },
  {
    "path": "tests/Bus/BusPendingBatchTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Collection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse stdClass;\n\nclass BusPendingBatchTest extends TestCase\n{\n    public function test_pending_batch_may_be_configured_and_dispatched()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldReceive('dispatch')->once();\n\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $pendingBatch = $pendingBatch->before(function () {\n            //\n        })->progress(function () {\n            //\n        })->then(function () {\n            //\n        })->catch(function () {\n            //\n        })->allowFailures()->onConnection('test-connection')->onQueue('test-queue')->withOption('extra-option', 123);\n\n        $this->assertSame('test-connection', $pendingBatch->connection());\n        $this->assertSame('test-queue', $pendingBatch->queue());\n        $this->assertCount(1, $pendingBatch->beforeCallbacks());\n        $this->assertCount(1, $pendingBatch->progressCallbacks());\n        $this->assertCount(1, $pendingBatch->thenCallbacks());\n        $this->assertCount(1, $pendingBatch->catchCallbacks());\n        $this->assertArrayHasKey('extra-option', $pendingBatch->options);\n        $this->assertSame(123, $pendingBatch->options['extra-option']);\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('store')->once()->with($pendingBatch)->andReturn($batch = m::mock(stdClass::class));\n        $batch->shouldReceive('add')->once()->with(m::type(Collection::class))->andReturn($batch = m::mock(Batch::class));\n\n        $container->instance(BatchRepository::class, $repository);\n\n        $pendingBatch->dispatch();\n    }\n\n    public function test_batch_is_deleted_from_storage_if_exception_thrown_during_batching()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $container = new Container;\n\n        $job = new class {\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $repository = m::mock(BatchRepository::class);\n\n        $repository->shouldReceive('store')->once()->with($pendingBatch)->andReturn($batch = m::mock(stdClass::class));\n\n        $batch->id = 'test-id';\n\n        $batch->shouldReceive('add')->once()->andReturnUsing(function () {\n            throw new RuntimeException('Failed to add jobs...');\n        });\n\n        $repository->shouldReceive('delete')->once()->with('test-id');\n\n        $container->instance(BatchRepository::class, $repository);\n\n        $pendingBatch->dispatch();\n    }\n\n    public function test_batch_is_dispatched_when_dispatchif_is_true()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldReceive('dispatch')->once();\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('store')->once()->andReturn($batch = m::mock(stdClass::class));\n        $batch->shouldReceive('add')->once()->andReturn($batch = m::mock(Batch::class));\n\n        $container->instance(BatchRepository::class, $repository);\n\n        $result = $pendingBatch->dispatchIf(true);\n\n        $this->assertInstanceOf(Batch::class, $result);\n    }\n\n    public function test_batch_is_not_dispatched_when_dispatchif_is_false()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldNotReceive('dispatch');\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $repository = m::mock(BatchRepository::class);\n        $container->instance(BatchRepository::class, $repository);\n\n        $result = $pendingBatch->dispatchIf(false);\n\n        $this->assertNull($result);\n    }\n\n    public function test_batch_is_dispatched_when_dispatchunless_is_false()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldReceive('dispatch')->once();\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('store')->once()->andReturn($batch = m::mock(stdClass::class));\n        $batch->shouldReceive('add')->once()->andReturn($batch = m::mock(Batch::class));\n\n        $container->instance(BatchRepository::class, $repository);\n\n        $result = $pendingBatch->dispatchUnless(false);\n\n        $this->assertInstanceOf(Batch::class, $result);\n    }\n\n    public function test_batch_is_not_dispatched_when_dispatchunless_is_true()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldNotReceive('dispatch');\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $repository = m::mock(BatchRepository::class);\n        $container->instance(BatchRepository::class, $repository);\n\n        $result = $pendingBatch->dispatchUnless(true);\n\n        $this->assertNull($result);\n    }\n\n    public function test_batch_before_event_is_called()\n    {\n        $container = new Container;\n\n        $eventDispatcher = m::mock(Dispatcher::class);\n        $eventDispatcher->shouldReceive('dispatch')->once();\n\n        $container->instance(Dispatcher::class, $eventDispatcher);\n\n        $job = new class\n        {\n            use Batchable;\n        };\n\n        $beforeCalled = false;\n\n        $pendingBatch = new PendingBatch($container, new Collection([$job]));\n\n        $pendingBatch = $pendingBatch->before(function () use (&$beforeCalled) {\n            $beforeCalled = true;\n        })->onConnection('test-connection')->onQueue('test-queue');\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('store')->once()->with($pendingBatch)->andReturn($batch = m::mock(stdClass::class));\n        $batch->shouldReceive('add')->once()->with(m::type(Collection::class))->andReturn($batch = m::mock(Batch::class));\n\n        $container->instance(BatchRepository::class, $repository);\n\n        $pendingBatch->dispatch();\n\n        $this->assertTrue($beforeCalled);\n    }\n\n    public function test_it_throws_exception_if_batched_job_is_not_batchable(): void\n    {\n        $nonBatchableJob = new class {\n        };\n\n        $this->expectException(RuntimeException::class);\n\n        new PendingBatch(new Container, new Collection([$nonBatchableJob]));\n    }\n\n    public function test_it_throws_an_exception_if_batched_job_contains_batch_with_nonbatchable_job(): void\n    {\n        $this->expectException(RuntimeException::class);\n\n        $container = new Container;\n        new PendingBatch(\n            $container,\n            new Collection(\n                [new PendingBatch($container, new Collection([new BatchableJob, new class {\n                }]))]\n            )\n        );\n    }\n\n    public function test_it_can_batch_a_closure(): void\n    {\n        new PendingBatch(\n            new Container,\n            new Collection([\n                function () {\n                },\n            ])\n        );\n        $this->expectNotToPerformAssertions();\n    }\n\n    public function test_allow_failures_with_boolean_true_enables_failure_tolerance(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures(true);\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertEmpty($batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_with_boolean_false_disables_failure_tolerance(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures(false);\n\n        $this->assertSame($batch, $result);\n        $this->assertFalse($batch->options['allowFailures']);\n        $this->assertEmpty($batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_with_single_closure_registers_callback(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures(static fn (): true => true);\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertCount(1, $batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_with_single_callable_registers_callback(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures('strlen');\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertCount(1, $batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_with_array_of_callables_registers_multiple_callbacks(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures([\n            static fn (): true => true,\n            'strlen',\n            [$batch, 'failureCallbacks'],\n            strlen(...),\n        ]);\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertCount(4, $batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_registers_only_valid_callbacks(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures([\n            // 3 valid\n            static fn (): true => true,\n            'strlen',\n            [$batch, 'failureCallbacks'],\n            // 5 invalid\n            'invalid_function_name',\n            123,\n            null,\n            [],\n            new stdClass,\n        ]);\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertCount(3, $batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_with_empty_array_enables_tolerance_without_callbacks(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $result = $batch->allowFailures([]);\n\n        $this->assertSame($batch, $result);\n        $this->assertTrue($batch->options['allowFailures']);\n        $this->assertEmpty($batch->failureCallbacks());\n    }\n\n    public function test_allow_failures_is_chainable(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $this->assertSame($batch, $batch->allowFailures(true));\n        $this->assertSame($batch, $batch->allowFailures(false));\n        $this->assertSame($batch, $batch->allowFailures(static fn (): true => true));\n        $this->assertSame($batch, $batch->allowFailures('strlen'));\n        $this->assertSame($batch, $batch->allowFailures([static fn (): true => true, 'strlen']));\n        $this->assertSame($batch, $batch->allowFailures([]));\n    }\n\n    public function test_failure_callbacks_accessor_returns_registered_callbacks(): void\n    {\n        $batch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $this->assertEmpty($batch->failureCallbacks());\n\n        $batch->allowFailures(\n            static fn (): true => true\n        );\n\n        $this->assertCount(1, $batch->failureCallbacks());\n\n        $freshBatch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $freshBatch->allowFailures([\n            'strlen',\n            [$freshBatch, 'failureCallbacks'],\n        ]);\n\n        $this->assertCount(2, $freshBatch->failureCallbacks());\n\n        $anotherBatch = new PendingBatch(new Container, new Collection([new BatchableJob]));\n\n        $anotherBatch->allowFailures([\n            static fn (): false => false,\n            'trim',\n            123,\n            'invalid_function',\n        ]);\n\n        $this->assertCount(2, $anotherBatch->failureCallbacks());\n    }\n}\n\nclass BatchableJob\n{\n    use Batchable;\n}\n"
  },
  {
    "path": "tests/Bus/BusPendingDispatchTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Illuminate\\Foundation\\Bus\\PendingDispatch;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\n\nclass PendingDispatchWithoutDestructor extends PendingDispatch\n{\n    public function __destruct()\n    {\n        // Prevent the job from being dispatched\n    }\n}\n\nclass BusPendingDispatchTest extends TestCase\n{\n    protected $job;\n\n    /**\n     * @var PendingDispatchWithoutDestructor\n     */\n    protected $pendingDispatch;\n\n    protected function setUp(): void\n    {\n        $this->job = m::mock(stdClass::class);\n        $this->pendingDispatch = new PendingDispatchWithoutDestructor($this->job);\n\n        parent::setUp();\n    }\n\n    public function testOnConnection()\n    {\n        $this->job->shouldReceive('onConnection')->once()->with('test-connection');\n        $this->pendingDispatch->onConnection('test-connection');\n    }\n\n    public function testOnQueue()\n    {\n        $this->job->shouldReceive('onQueue')->once()->with('test-queue');\n        $this->pendingDispatch->onQueue('test-queue');\n    }\n\n    public function testAllOnConnection()\n    {\n        $this->job->shouldReceive('allOnConnection')->once()->with('test-connection');\n        $this->pendingDispatch->allOnConnection('test-connection');\n    }\n\n    public function testAllOnQueue()\n    {\n        $this->job->shouldReceive('allOnQueue')->once()->with('test-queue');\n        $this->pendingDispatch->allOnQueue('test-queue');\n    }\n\n    public function testDelay()\n    {\n        $this->job->shouldReceive('delay')->once()->with(60);\n        $this->pendingDispatch->delay(60);\n    }\n\n    public function testWithoutDelay()\n    {\n        $this->job->shouldReceive('withoutDelay')->once();\n        $this->pendingDispatch->withoutDelay();\n    }\n\n    public function testAfterCommit()\n    {\n        $this->job->shouldReceive('afterCommit')->once();\n        $this->pendingDispatch->afterCommit();\n    }\n\n    public function testBeforeCommit()\n    {\n        $this->job->shouldReceive('beforeCommit')->once();\n        $this->pendingDispatch->beforeCommit();\n    }\n\n    public function testChain()\n    {\n        $chain = [new stdClass];\n        $this->job->shouldReceive('chain')->once()->with($chain);\n        $this->pendingDispatch->chain($chain);\n    }\n\n    public function testAfterResponse()\n    {\n        $this->pendingDispatch->afterResponse();\n        $this->assertTrue(\n            (new ReflectionClass($this->pendingDispatch))->getProperty('afterResponse')->getValue($this->pendingDispatch)\n        );\n    }\n\n    public function testGetJob()\n    {\n        $this->assertSame($this->job, $this->pendingDispatch->getJob());\n    }\n\n    public function testDynamicallyProxyMethods()\n    {\n        $newJob = m::mock(stdClass::class);\n        $this->job->shouldReceive('appendToChain')->once()->with($newJob);\n        $this->pendingDispatch->appendToChain($newJob);\n    }\n}\n"
  },
  {
    "path": "tests/Bus/QueueableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Bus;\n\nuse Illuminate\\Bus\\Queueable;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueableTest extends TestCase\n{\n    public static function connectionDataProvider(): array\n    {\n        return [\n            'uses string' => ['redis', 'redis'],\n            'uses BackedEnum #1' => [ConnectionEnum::SQS, 'sqs'],\n            'uses BackedEnum #2' => [ConnectionEnum::REDIS, 'redis'],\n            'uses null' => [null, null],\n        ];\n    }\n\n    #[DataProvider('connectionDataProvider')]\n    public function testOnConnection(mixed $connection, ?string $expected): void\n    {\n        $job = new FakeJob();\n        $job->onConnection($connection);\n\n        $this->assertSame($job->connection, $expected);\n    }\n\n    #[DataProvider('connectionDataProvider')]\n    public function testAllOnConnection(mixed $connection, ?string $expected): void\n    {\n        $job = new FakeJob();\n        $job->allOnConnection($connection);\n\n        $this->assertSame($job->connection, $expected);\n        $this->assertSame($job->chainConnection, $expected);\n    }\n\n    public static function queuesDataProvider(): array\n    {\n        return [\n            'uses string' => ['high', 'high'],\n            'uses BackedEnum #1' => [QueueEnum::DEFAULT, 'default'],\n            'uses BackedEnum #2' => [QueueEnum::HIGH, 'high'],\n            'uses null' => [null, null],\n        ];\n    }\n\n    #[DataProvider('queuesDataProvider')]\n    public function testOnQueue(mixed $queue, ?string $expected): void\n    {\n        $job = new FakeJob();\n        $job->onQueue($queue);\n\n        $this->assertSame($job->queue, $expected);\n    }\n\n    #[DataProvider('queuesDataProvider')]\n    public function testAllOnQueue(mixed $queue, ?string $expected): void\n    {\n        $job = new FakeJob();\n        $job->allOnQueue($queue);\n\n        $this->assertSame($job->queue, $expected);\n        $this->assertSame($job->chainQueue, $expected);\n    }\n}\n\nclass FakeJob\n{\n    use Queueable;\n}\n\nenum ConnectionEnum: string\n{\n    case SQS = 'sqs';\n    case REDIS = 'redis';\n}\n\nenum QueueEnum: string\n{\n    case HIGH = 'high';\n    case DEFAULT = 'default';\n}\n"
  },
  {
    "path": "tests/Cache/CacheApcStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ApcStore;\nuse Illuminate\\Cache\\ApcWrapper;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheApcStoreTest extends TestCase\n{\n    public function testGetReturnsNullWhenNotFound()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock();\n        $apc->expects($this->once())->method('get')->with($this->equalTo('foobar'))->willReturn(null);\n        $store = new ApcStore($apc, 'foo');\n        $this->assertNull($store->get('bar'));\n    }\n\n    public function testAPCValueIsReturned()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock();\n        $apc->expects($this->once())->method('get')->willReturn('bar');\n        $store = new ApcStore($apc);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testAPCFalseValueIsReturned()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock();\n        $apc->expects($this->once())->method('get')->willReturn(false);\n        $store = new ApcStore($apc);\n        $this->assertFalse($store->get('foo'));\n    }\n\n    public function testGetMultipleReturnsNullWhenNotFoundAndValueWhenFound()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get'])->getMock();\n        $apc->expects($this->exactly(3))->method('get')->willReturnMap([\n            ['foo', 'qux'],\n            ['bar', null],\n            ['baz', 'norf'],\n        ]);\n        $store = new ApcStore($apc);\n        $this->assertEquals([\n            'foo' => 'qux',\n            'bar' => null,\n            'baz' => 'norf',\n        ], $store->many(['foo', 'bar', 'baz']));\n    }\n\n    public function testSetMethodProperlyCallsAPC()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock();\n        $apc->expects($this->once())\n            ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(60))\n            ->willReturn(true);\n        $store = new ApcStore($apc);\n        $result = $store->put('foo', 'bar', 60);\n        $this->assertTrue($result);\n    }\n\n    public function testSetMultipleMethodProperlyCallsAPC()\n    {\n        $apc = m::mock(ApcWrapper::class);\n\n        $apc->shouldReceive('put')\n            ->once()\n            ->with('foo', 'bar', 60)\n            ->andReturn(true);\n\n        $apc->shouldReceive('put')\n            ->once()\n            ->with('baz', 'qux', 60)\n            ->andReturn(true);\n\n        $apc->shouldReceive('put')\n            ->once()\n            ->with('bar', 'norf', 60)\n            ->andReturn(true);\n\n        $store = new ApcStore($apc);\n        $result = $store->putMany([\n            'foo' => 'bar',\n            'baz' => 'qux',\n            'bar' => 'norf',\n        ], 60);\n        $this->assertTrue($result);\n    }\n\n    public function testIncrementMethodProperlyCallsAPC()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['increment'])->getMock();\n        $apc->expects($this->once())->method('increment')->with($this->equalTo('foo'), $this->equalTo(5));\n        $store = new ApcStore($apc);\n        $store->increment('foo', 5);\n    }\n\n    public function testDecrementMethodProperlyCallsAPC()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['decrement'])->getMock();\n        $apc->expects($this->once())->method('decrement')->with($this->equalTo('foo'), $this->equalTo(5));\n        $store = new ApcStore($apc);\n        $store->decrement('foo', 5);\n    }\n\n    public function testStoreItemForeverProperlyCallsAPC()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['put'])->getMock();\n        $apc->expects($this->once())\n            ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(0))\n            ->willReturn(true);\n        $store = new ApcStore($apc);\n        $result = $store->forever('foo', 'bar');\n        $this->assertTrue($result);\n    }\n\n    public function testForgetMethodProperlyCallsAPC()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['delete'])->getMock();\n        $apc->expects($this->once())->method('delete')->with($this->equalTo('foo'))->willReturn(true);\n        $store = new ApcStore($apc);\n        $result = $store->forget('foo');\n        $this->assertTrue($result);\n    }\n\n    public function testTouchMethodProperlyCallsAPC(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['get', 'put'])->getMock();\n\n        $apc->expects($this->once())->method('get')->with($this->equalTo($key))->willReturn('bar');\n        $apc->expects($this->once())->method('put')->with($this->equalTo($key), $this->equalTo('bar'), $this->equalTo($ttl))->willReturn(true);\n\n        $this->assertTrue((new ApcStore($apc))->touch($key, $ttl));\n    }\n\n    public function testFlushesCached()\n    {\n        $apc = $this->getMockBuilder(ApcWrapper::class)->onlyMethods(['flush'])->getMock();\n        $apc->expects($this->once())->method('flush')->willReturn(true);\n        $store = new ApcStore($apc);\n        $result = $store->flush();\n        $this->assertTrue($result);\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheArrayStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass CacheArrayStoreTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testItemsCanBeSetAndRetrieved()\n    {\n        $store = new ArrayStore;\n        $result = $store->put('foo', 'bar', 10);\n        $this->assertTrue($result);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testCacheTtl(): void\n    {\n        $store = new ArrayStore();\n\n        Carbon::setTestNow('2000-01-01 00:00:00.500'); // 500 milliseconds past\n        $store->put('hello', 'world', 1);\n\n        Carbon::setTestNow('2000-01-01 00:00:01.499'); // progress 0.999 seconds\n        $this->assertSame('world', $store->get('hello'));\n\n        Carbon::setTestNow('2000-01-01 00:00:01.500'); // progress 0.001 seconds. 1 second since putting into cache.\n        $this->assertNull($store->get('hello'));\n    }\n\n    public function testMultipleItemsCanBeSetAndRetrieved()\n    {\n        $store = new ArrayStore;\n        $result = $store->put('foo', 'bar', 10);\n        $resultMany = $store->putMany([\n            'fizz' => 'buz',\n            'quz' => 'baz',\n        ], 10);\n        $this->assertTrue($result);\n        $this->assertTrue($resultMany);\n        $this->assertEquals([\n            'foo' => 'bar',\n            'fizz' => 'buz',\n            'quz' => 'baz',\n            'norf' => null,\n        ], $store->many(['foo', 'fizz', 'quz', 'norf']));\n    }\n\n    public function testItemsCanExpire()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore;\n\n        $store->put('foo', 'bar', 10);\n        Carbon::setTestNow(Carbon::now()->addSeconds(10)->addSecond());\n        $result = $store->get('foo');\n\n        $this->assertNull($result);\n    }\n\n    public function testTouchExtendsTtl(): void\n    {\n        $key = 'key';\n        $value = 'value';\n\n        $store = new ArrayStore;\n\n        Carbon::setTestNow($now = Carbon::now());\n\n        $store->put($key, $value, 30);\n        $store->touch($key, 60);\n\n        Carbon::setTestNow($now->addSeconds(45));\n\n        $this->assertSame($value, $store->get($key));\n    }\n\n    public function testStoreItemForeverProperlyStoresInArray()\n    {\n        $mock = $this->getMockBuilder(ArrayStore::class)->onlyMethods(['put'])->getMock();\n        $mock->expects($this->once())\n            ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(0))\n            ->willReturn(true);\n        $result = $mock->forever('foo', 'bar');\n        $this->assertTrue($result);\n    }\n\n    public function testValuesCanBeIncremented()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', 1, 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(2, $result);\n        $this->assertEquals(2, $store->get('foo'));\n\n        $result = $store->increment('foo', 2);\n        $this->assertEquals(4, $result);\n        $this->assertEquals(4, $store->get('foo'));\n    }\n\n    public function testValuesGetCastedByIncrementOrDecrement()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', '1', 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(2, $result);\n        $this->assertEquals(2, $store->get('foo'));\n\n        $store->put('bar', '1', 10);\n        $result = $store->decrement('bar');\n        $this->assertEquals(0, $result);\n        $this->assertEquals(0, $store->get('bar'));\n    }\n\n    public function testIncrementNonNumericValues()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', 'I am string', 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(1, $result);\n        $this->assertEquals(1, $store->get('foo'));\n    }\n\n    public function testNonExistingKeysCanBeIncremented()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore;\n        $result = $store->increment('foo');\n        $this->assertEquals(1, $result);\n        $this->assertEquals(1, $store->get('foo'));\n\n        // Will be there forever\n        Carbon::setTestNow(Carbon::now()->addYears(10));\n        $this->assertEquals(1, $store->get('foo'));\n    }\n\n    public function testExpiredKeysAreIncrementedLikeNonExistingKeys()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore;\n\n        $store->put('foo', 999, 10);\n        Carbon::setTestNow(Carbon::now()->addSeconds(10)->addSecond());\n        $result = $store->increment('foo');\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testValuesCanBeDecremented()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', 1, 10);\n        $result = $store->decrement('foo');\n        $this->assertEquals(0, $result);\n        $this->assertEquals(0, $store->get('foo'));\n\n        $result = $store->decrement('foo', 2);\n        $this->assertEquals(-2, $result);\n        $this->assertEquals(-2, $store->get('foo'));\n    }\n\n    public function testItemsCanBeRemoved()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', 'bar', 10);\n        $this->assertTrue($store->forget('foo'));\n        $this->assertNull($store->get('foo'));\n        $this->assertFalse($store->forget('foo'));\n    }\n\n    public function testItemsCanBeFlushed()\n    {\n        $store = new ArrayStore;\n        $store->put('foo', 'bar', 10);\n        $store->put('baz', 'boom', 10);\n        $result = $store->flush();\n        $this->assertTrue($result);\n        $this->assertNull($store->get('foo'));\n        $this->assertNull($store->get('baz'));\n    }\n\n    public function testLocksCanBeFlushed()\n    {\n        $store = new ArrayStore;\n        $store->lock('foo', 10);\n        $store->lock('bar', 10);\n        $result = $store->flushLocks();\n        $this->assertTrue($result);\n        $this->assertNull($store->get('foo'));\n        $this->assertNull($store->get('bar'));\n        $this->assertEmpty($store->locks);\n    }\n\n    public function testCacheKey()\n    {\n        $store = new ArrayStore;\n        $this->assertEmpty($store->getPrefix());\n    }\n\n    public function testCannotAcquireLockTwice()\n    {\n        $store = new ArrayStore;\n        $lock = $store->lock('foo', 10);\n\n        $this->assertTrue($lock->acquire());\n        $this->assertFalse($lock->acquire());\n    }\n\n    public function testCanAcquireLockAgainAfterExpiry()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore;\n        $lock = $store->lock('foo', 10);\n        $lock->acquire();\n        Carbon::setTestNow(Carbon::now()->addSeconds(10));\n\n        $this->assertTrue($lock->acquire());\n    }\n\n    public function testLockExpirationLowerBoundary()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore;\n        $lock = $store->lock('foo', 10);\n        $lock->acquire();\n        Carbon::setTestNow(Carbon::now()->addSeconds(10)->subMicrosecond());\n\n        $this->assertFalse($lock->acquire());\n    }\n\n    public function testLockWithNoExpirationNeverExpires()\n    {\n        $store = new ArrayStore;\n        $lock = $store->lock('foo');\n        $lock->acquire();\n        Carbon::setTestNow(Carbon::now()->addYears(100));\n\n        $this->assertFalse($lock->acquire());\n    }\n\n    public function testCanAcquireLockAfterRelease()\n    {\n        $store = new ArrayStore;\n        $lock = $store->lock('foo', 10);\n        $lock->acquire();\n\n        $this->assertTrue($lock->release());\n        $this->assertTrue($lock->acquire());\n    }\n\n    public function testAnotherOwnerCannotReleaseLock()\n    {\n        $store = new ArrayStore;\n        $owner = $store->lock('foo', 10);\n        $wannabeOwner = $store->lock('foo', 10);\n        $owner->acquire();\n\n        $this->assertFalse($wannabeOwner->release());\n    }\n\n    public function testAnotherOwnerCanForceReleaseALock()\n    {\n        $store = new ArrayStore;\n        $owner = $store->lock('foo', 10);\n        $wannabeOwner = $store->lock('foo', 10);\n        $owner->acquire();\n        $wannabeOwner->forceRelease();\n\n        $this->assertTrue($wannabeOwner->acquire());\n    }\n\n    public function testValuesAreNotStoredByReference()\n    {\n        $store = new ArrayStore($serialize = true);\n        $object = new stdClass;\n        $object->foo = true;\n\n        $store->put('object', $object, 10);\n        $object->bar = true;\n\n        $retrievedObject = $store->get('object');\n\n        $this->assertTrue($retrievedObject->foo);\n        $this->assertFalse(property_exists($retrievedObject, 'bar'));\n    }\n\n    public function testValuesAreStoredByReferenceIfSerializationIsDisabled()\n    {\n        $store = new ArrayStore;\n        $object = new stdClass;\n        $object->foo = true;\n\n        $store->put('object', $object, 10);\n        $object->bar = true;\n\n        $retrievedObject = $store->get('object');\n\n        $this->assertTrue($retrievedObject->foo);\n        $this->assertTrue($retrievedObject->bar);\n    }\n\n    public function testReleasingLockAfterAlreadyForceReleasedByAnotherOwnerFails()\n    {\n        $store = new ArrayStore;\n        $owner = $store->lock('foo', 10);\n        $wannabeOwner = $store->lock('foo', 10);\n        $owner->acquire();\n        $wannabeOwner->forceRelease();\n\n        $this->assertFalse($wannabeOwner->release());\n    }\n\n    public function testOwnerStatusCanBeCheckedAfterRestoringLock()\n    {\n        $store = new ArrayStore;\n        $firstLock = $store->lock('foo', 10);\n\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = $store->restoreLock('foo', $owner);\n        $this->assertTrue($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testOtherOwnerDoesNotOwnLockAfterRestore()\n    {\n        $store = new ArrayStore;\n        $firstLock = $store->lock('foo', 10);\n\n        $this->assertTrue($firstLock->get());\n\n        $secondLock = $store->restoreLock('foo', 'other_owner');\n\n        $this->assertFalse($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testRestoringNonExistingLockDoesNotOwnAnything()\n    {\n        $store = new ArrayStore;\n        $firstLock = $store->restoreLock('foo', 'owner');\n\n        $this->assertFalse($firstLock->isOwnedByCurrentProcess());\n    }\n\n    public function testCanGetAll()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore(false);\n        $store->put('foo', 'bar', 10);\n\n        $this->assertEquals([\n            'foo' => ['value' => 'bar', 'expiresAt' => Carbon::now()->addSeconds(10)->getPreciseTimestamp(3) / 1000],\n        ], $store->all());\n    }\n\n    public function testCanGetAllWhenSerialized()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new ArrayStore(true);\n        $store->put('foo', 'bar', 10);\n        $this->assertEquals([\n            'foo' => ['value' => 'bar', 'expiresAt' => $expiresAt = (Carbon::now()->addSeconds(10)->getPreciseTimestamp(3) / 1000)],\n        ], $store->all());\n\n        // Now let's put a serializable value in there\n        $store->forget('foo');\n        $store->put('foo', Carbon::now(), 10);\n\n        $this->assertEquals([\n            'foo' => [\n                'value' => Carbon::now(),\n                'expiresAt' => $expiresAt,\n            ],\n        ], $store->all());\n\n        $this->assertEquals(\n            serialize(Carbon::now()),\n            $store->all(false)['foo']['value']\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheDatabaseStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Closure;\nuse Illuminate\\Cache\\DatabaseStore;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\PostgresConnection;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass CacheDatabaseStoreTest extends TestCase\n{\n    public function testNullIsReturnedWhenItemNotFound()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('whereIn')->once()->with('key', ['prefixfoo'])->andReturn($table);\n        $table->shouldReceive('get')->once()->andReturn(collect([]));\n\n        $this->assertNull($store->get('foo'));\n    }\n\n    public function testNullIsReturnedAndItemDeletedWhenItemIsExpired()\n    {\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['forgetIfExpired'])->setConstructorArgs($this->getMocks())->getMock();\n\n        $getQuery = m::mock(stdClass::class);\n        $getQuery->shouldReceive('whereIn')->once()->with('key', ['prefixfoo'])->andReturn($getQuery);\n        $getQuery->shouldReceive('get')->once()->andReturn(collect([(object) ['key' => 'prefixfoo', 'expiration' => 1]]));\n\n        $deleteQuery = m::mock(stdClass::class);\n        $deleteQuery->shouldReceive('whereIn')->once()->with('key', ['prefixfoo', 'prefixilluminate:cache:flexible:created:foo'])->andReturn($deleteQuery);\n        $deleteQuery->shouldReceive('where')->once()->with('expiration', '<=', m::any())->andReturn($deleteQuery);\n        $deleteQuery->shouldReceive('delete')->once()->andReturnNull();\n\n        $store->getConnection()->shouldReceive('table')->twice()->with('table')->andReturn($getQuery, $deleteQuery);\n\n        $this->assertNull($store->get('foo'));\n    }\n\n    public function testDecryptedValueIsReturnedWhenItemIsValid()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('whereIn')->once()->with('key', ['prefixfoo'])->andReturn($table);\n        $table->shouldReceive('get')->once()->andReturn(collect([(object) ['key' => 'prefixfoo', 'value' => serialize('bar'), 'expiration' => 999999999999999]]));\n\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testValueIsReturnedOnPostgres()\n    {\n        $store = $this->getPostgresStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('whereIn')->once()->with('key', ['prefixfoo'])->andReturn($table);\n        $table->shouldReceive('get')->once()->andReturn(collect([(object) ['key' => 'prefixfoo', 'value' => base64_encode(serialize('bar')), 'expiration' => 999999999999999]]));\n\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testValueIsReturnedOnSqlite()\n    {\n        $store = $this->getSqliteStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('whereIn')->once()->with('key', ['prefixfoo'])->andReturn($table);\n        $table->shouldReceive('get')->once()->andReturn(collect([(object) ['key' => 'prefixfoo', 'value' => base64_encode(serialize(\"\\0bar\\0\")), 'expiration' => 999999999999999]]));\n\n        $this->assertSame(\"\\0bar\\0\", $store->get('foo'));\n    }\n\n    public function testValueIsUpserted()\n    {\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getMocks())->getMock();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(1);\n        $table->shouldReceive('upsert')->once()->with([['key' => 'prefixfoo', 'value' => serialize('bar'), 'expiration' => 61]], 'key')->andReturnTrue();\n\n        $result = $store->put('foo', 'bar', 60);\n        $this->assertTrue($result);\n    }\n\n    public function testValueIsUpsertedOnPostgres()\n    {\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getPostgresMocks())->getMock();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(1);\n        $table->shouldReceive('upsert')->once()->with([['key' => 'prefixfoo', 'value' => base64_encode(serialize(\"\\0\")), 'expiration' => 61]], 'key')->andReturn(1);\n\n        $result = $store->put('foo', \"\\0\", 60);\n        $this->assertTrue($result);\n    }\n\n    public function testValueIsUpsertedOnSqlite()\n    {\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getSqliteMocks())->getMock();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(1);\n        $table->shouldReceive('upsert')->once()->with([['key' => 'prefixfoo', 'value' => base64_encode(serialize(\"\\0\")), 'expiration' => 61]], 'key')->andReturn(1);\n\n        $result = $store->put('foo', \"\\0\", 60);\n        $this->assertTrue($result);\n    }\n\n    public function testForeverCallsStoreItemWithReallyLongTime()\n    {\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['put'])->setConstructorArgs($this->getMocks())->getMock();\n        $store->expects($this->once())->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(315360000))->willReturn(true);\n        $result = $store->forever('foo', 'bar');\n        $this->assertTrue($result);\n    }\n\n    public function testItemsMayBeRemovedFromCache()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('whereIn')->once()->with('key', ['prefixfoo', 'prefixilluminate:cache:flexible:created:foo'])->andReturn($table);\n        $table->shouldReceive('delete')->once();\n\n        $store->forget('foo');\n    }\n\n    public function testItemsMayBeFlushedFromCache()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('delete')->once()->andReturn(2);\n\n        $result = $store->flush();\n        $this->assertTrue($result);\n    }\n\n    public function testLocksMayBeFlushedFromCache()\n    {\n        $store = $this->getStore();\n        $connection = m::mock(\\Illuminate\\Database\\ConnectionInterface::class);\n        $store->setLockConnection($connection);\n        $table = m::mock(stdClass::class);\n        $store->getLockConnection()->shouldReceive('table')->once()->with('cache_locks')->andReturn($table);\n        $table->shouldReceive('delete')->once()->andReturn(2);\n\n        $result = $store->flushLocks();\n        $this->assertTrue($result);\n    }\n\n    public function testIncrementReturnsCorrectValues()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $cache = m::mock(stdClass::class);\n\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn(null);\n        $this->assertFalse($store->increment('foo'));\n\n        $cache->value = serialize('bar');\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn($cache);\n        $this->assertFalse($store->increment('foo'));\n\n        $cache->value = serialize(2);\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn($cache);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('update')->once()->with(['value' => serialize(3)]);\n        $this->assertEquals(3, $store->increment('foo'));\n    }\n\n    public function testDecrementReturnsCorrectValues()\n    {\n        $store = $this->getStore();\n        $table = m::mock(stdClass::class);\n        $cache = m::mock(stdClass::class);\n\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn(null);\n        $this->assertFalse($store->decrement('foo'));\n\n        $cache->value = serialize('bar');\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixfoo')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn($cache);\n        $this->assertFalse($store->decrement('foo'));\n\n        $cache->value = serialize(3);\n        $store->getConnection()->shouldReceive('transaction')->once()->with(m::type(Closure::class))->andReturnUsing(function ($closure) {\n            return $closure();\n        });\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixbar')->andReturn($table);\n        $table->shouldReceive('lockForUpdate')->once()->andReturn($table);\n        $table->shouldReceive('first')->once()->andReturn($cache);\n        $store->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($table);\n        $table->shouldReceive('where')->once()->with('key', 'prefixbar')->andReturn($table);\n        $table->shouldReceive('update')->once()->with(['value' => serialize(2)]);\n        $this->assertEquals(2, $store->decrement('bar'));\n    }\n\n    public function testTouchExtendsTtl()\n    {\n        $ttl = 60;\n\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getMocks())->getMock();\n        $table = m::mock(stdClass::class);\n\n        $store->getConnection()->shouldReceive('table')->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(0);\n        $table->shouldReceive('where')->twice()->andReturn($table);\n        $table->shouldReceive('update')->once()->with(['expiration' => $ttl])->andReturn(1);\n\n        $this->assertTrue($store->touch('foo', $ttl));\n    }\n\n    public function testTouchExtendsTtlOnPostgres(): void\n    {\n        $ttl = 60;\n\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getPostgresMocks())->getMock();\n        $table = m::mock(stdClass::class);\n\n        $store->getConnection()->shouldReceive('table')->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(0);\n        $table->shouldReceive('where')->twice()->andReturn($table);\n        $table->shouldReceive('update')->once()->with(['expiration' => $ttl])->andReturn(1);\n\n        $this->assertTrue($store->touch('foo', $ttl));\n    }\n\n    public function testTouchExtendsTtlOnSqlite()\n    {\n        $ttl = 60;\n\n        $store = $this->getMockBuilder(DatabaseStore::class)->onlyMethods(['getTime'])->setConstructorArgs($this->getSqliteMocks())->getMock();\n        $table = m::mock(stdClass::class);\n\n        $store->getConnection()->shouldReceive('table')->with('table')->andReturn($table);\n        $store->expects($this->once())->method('getTime')->willReturn(0);\n        $table->shouldReceive('where')->twice()->andReturn($table);\n        $table->shouldReceive('update')->once()->with(['expiration' => $ttl])->andReturn(1);\n\n        $this->assertTrue($store->touch('foo', $ttl));\n    }\n\n    protected function getStore()\n    {\n        return new DatabaseStore(m::mock(Connection::class), 'table', 'prefix');\n    }\n\n    protected function getPostgresStore()\n    {\n        return new DatabaseStore(m::mock(PostgresConnection::class), 'table', 'prefix');\n    }\n\n    protected function getSqliteStore()\n    {\n        return new DatabaseStore(m::mock(SQLiteConnection::class), 'table', 'prefix');\n    }\n\n    protected function getMocks()\n    {\n        return [m::mock(Connection::class), 'table', 'prefix'];\n    }\n\n    protected function getPostgresMocks()\n    {\n        return [m::mock(PostgresConnection::class), 'table', 'prefix'];\n    }\n\n    protected function getSqliteMocks()\n    {\n        return [m::mock(SQLiteConnection::class), 'table', 'prefix'];\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheDynamoDbStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Illuminate\\Cache\\DynamoDbStore;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheDynamoDbStoreTest extends TestCase\n{\n    public function testTouchMethodCorrectlyCallsDynamoDb(): void\n    {\n        $table = 'table';\n        $key = 'key';\n        $ttl = 60;\n\n        $this->assertTrue((new DynamoDbStore($dynamo = new TestDynamo, $table))->touch($key, $ttl));\n\n        $this->assertTrue(\n            isset($dynamo->args['UpdateExpression'], $dynamo->args['TableName'], $dynamo->args['Key']['key']['S'])\n                && $dynamo->args['TableName'] === $table\n                && $dynamo->args['Key']['key']['S'] === $key\n                && str_contains($dynamo->args['UpdateExpression'], 'SET')\n        );\n\n        $this->assertTrue(\n            $ttl === $dynamo->args['ExpressionAttributeValues'][':expiry']['N']\n            - $dynamo->args['ExpressionAttributeValues'][':now']['N']\n        );\n    }\n}\n\nclass TestDynamo extends DynamoDbClient\n{\n    public array $args;\n\n    public function __construct()\n    {\n    }\n\n    public function updateItem(array $args): bool\n    {\n        $this->args = $args;\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\Events\\CacheFlushed;\nuse Illuminate\\Cache\\Events\\CacheFlushFailed;\nuse Illuminate\\Cache\\Events\\CacheFlushing;\nuse Illuminate\\Cache\\Events\\CacheHit;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushed;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushFailed;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushing;\nuse Illuminate\\Cache\\Events\\CacheMissed;\nuse Illuminate\\Cache\\Events\\ForgettingKey;\nuse Illuminate\\Cache\\Events\\KeyForgetFailed;\nuse Illuminate\\Cache\\Events\\KeyForgotten;\nuse Illuminate\\Cache\\Events\\KeyWritten;\nuse Illuminate\\Cache\\Events\\RetrievingKey;\nuse Illuminate\\Cache\\Events\\RetrievingManyKeys;\nuse Illuminate\\Cache\\Events\\WritingKey;\nuse Illuminate\\Cache\\Events\\WritingManyKeys;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Events\\Dispatcher;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheEventsTest extends TestCase\n{\n    public function testHasTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $this->assertFalse($repository->has('foo'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux']));\n        $this->assertTrue($repository->has('baz'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $this->assertFalse($repository->tags('taylor')->has('foo'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux', 'tags' => ['taylor']]));\n        $this->assertTrue($repository->tags('taylor')->has('baz'));\n    }\n\n    public function testGetTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $this->assertNull($repository->get('foo'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingManyKeys::class, ['storeName' => 'array', 'keys' => ['foo', 'bar']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'bar']));\n        $this->assertSame(['foo' => null, 'bar' => null], $repository->get(['foo', 'bar']));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux']));\n        $this->assertSame('qux', $repository->get('baz'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $this->assertNull($repository->tags('taylor')->get('foo'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux', 'tags' => ['taylor']]));\n        $this->assertSame('qux', $repository->tags('taylor')->get('baz'));\n    }\n\n    public function testPullTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(ForgettingKey::class, ['storeName' => 'array', 'key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyForgotten::class, ['storeName' => 'array', 'key' => 'baz']));\n        $this->assertSame('qux', $repository->pull('baz'));\n    }\n\n    public function testPullTriggersEventsUsingTags()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheHit::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(ForgettingKey::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyForgotten::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $this->assertSame('qux', $repository->tags('taylor')->pull('baz'));\n    }\n\n    public function testPutTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $repository->put('foo', 'bar', 99);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingManyKeys::class, ['storeName' => 'array', 'keys' => ['foo', 'baz'], 'values' => ['bar', 'qux'], 'seconds' => 99]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'baz', 'value' => 'qux', 'seconds' => 99]));\n        $repository->putMany(['foo' => 'bar', 'baz' => 'qux'], 99);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $repository->tags('taylor')->put('foo', 'bar', 99);\n    }\n\n    public function testAddTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $this->assertTrue($repository->add('foo', 'bar', 99));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $this->assertTrue($repository->tags('taylor')->add('foo', 'bar', 99));\n    }\n\n    public function testForeverTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null]));\n        $repository->forever('foo', 'bar');\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null, 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null, 'tags' => ['taylor']]));\n        $repository->tags('taylor')->forever('foo', 'bar');\n    }\n\n    public function testRememberTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99]));\n        $this->assertSame('bar', $repository->remember('foo', 99, function () {\n            return 'bar';\n        }));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => 99, 'tags' => ['taylor']]));\n        $this->assertSame('bar', $repository->tags('taylor')->remember('foo', 99, function () {\n            return 'bar';\n        }));\n    }\n\n    public function testRememberForeverTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null]));\n        $this->assertSame('bar', $repository->rememberForever('foo', function () {\n            return 'bar';\n        }));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(RetrievingKey::class, ['storeName' => 'array', 'key' => 'foo']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(CacheMissed::class, ['storeName' => 'array', 'key' => 'foo', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(WritingKey::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null, 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyWritten::class, ['storeName' => 'array', 'key' => 'foo', 'value' => 'bar', 'seconds' => null, 'tags' => ['taylor']]));\n        $this->assertSame('bar', $repository->tags('taylor')->rememberForever('foo', function () {\n            return 'bar';\n        }));\n    }\n\n    public function testForgetTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(ForgettingKey::class, ['storeName' => 'array', 'key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyForgotten::class, ['storeName' => 'array', 'key' => 'baz']));\n        $this->assertTrue($repository->forget('baz'));\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(ForgettingKey::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyForgotten::class, ['storeName' => 'array', 'key' => 'baz', 'tags' => ['taylor']]));\n        $this->assertTrue($repository->tags('taylor')->forget('baz'));\n    }\n\n    public function testForgetDoesTriggerFailedEventOnFailure()\n    {\n        $dispatcher = $this->getDispatcher();\n        $store = m::mock(Store::class);\n        $store->shouldReceive('forget')->andReturn(false);\n        $repository = new Repository($store);\n        $repository->setEventDispatcher($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(ForgettingKey::class, ['key' => 'baz']));\n        $dispatcher->shouldReceive('dispatch')->once()->with($this->assertEventMatches(KeyForgetFailed::class, ['key' => 'baz']));\n        $this->assertFalse($repository->forget('baz'));\n    }\n\n    public function testFlushTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheFlushing::class, [\n                'storeName' => 'array',\n            ])\n        );\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheFlushed::class, [\n                'storeName' => 'array',\n            ])\n        );\n        $this->assertTrue($repository->clear());\n    }\n\n    public function testFlushLocksTriggersEvents()\n    {\n        $dispatcher = $this->getDispatcher();\n        $repository = $this->getRepository($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheLocksFlushing::class, [\n                'storeName' => 'array',\n            ])\n        );\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheLocksFlushed::class, [\n                'storeName' => 'array',\n            ])\n        );\n        $this->assertTrue($repository->flushLocks());\n    }\n\n    public function testFlushFailureDoesDispatchEvent()\n    {\n        $dispatcher = $this->getDispatcher();\n\n        // Create a store that fails to flush\n        $failingStore = m::mock(Store::class);\n        $failingStore->shouldReceive('flush')->andReturn(false);\n\n        $repository = new Repository($failingStore, ['store' => 'array']);\n        $repository->setEventDispatcher($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheFlushing::class, [\n                'storeName' => 'array',\n            ])\n        );\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheFlushFailed::class, [\n                'storeName' => 'array',\n            ])\n        );\n        $this->assertFalse($repository->clear());\n    }\n\n    public function testFlushLocksFailureDoesDispatchEvent()\n    {\n        $dispatcher = $this->getDispatcher();\n\n        // Create a store that fails to flush locks\n        $failingStore = m::mock(ArrayStore::class);\n        $failingStore->shouldReceive('flushLocks')->andReturn(false);\n\n        $repository = new Repository($failingStore, ['store' => 'array']);\n        $repository->setEventDispatcher($dispatcher);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheLocksFlushing::class, [\n                'storeName' => 'array',\n            ])\n        );\n\n        $dispatcher->shouldReceive('dispatch')->once()->with(\n            $this->assertEventMatches(CacheLocksFlushFailed::class, [\n                'storeName' => 'array',\n            ])\n        );\n        $this->assertFalse($repository->flushLocks());\n    }\n\n    protected function assertEventMatches($eventClass, $properties = [])\n    {\n        return m::on(function ($event) use ($eventClass, $properties) {\n            if (! $event instanceof $eventClass) {\n                return false;\n            }\n\n            foreach ($properties as $name => $value) {\n                if ($value != $event->$name) {\n                    return false;\n                }\n            }\n\n            return true;\n        });\n    }\n\n    protected function getDispatcher()\n    {\n        return m::mock(Dispatcher::class);\n    }\n\n    protected function getRepository($dispatcher)\n    {\n        $repository = new Repository(new ArrayStore, ['store' => 'array']);\n        $repository->put('baz', 'qux', 99);\n        $repository->tags('taylor')->put('baz', 'qux', 99);\n        $repository->setEventDispatcher($dispatcher);\n\n        return $repository;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheFileStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Exception;\nuse Illuminate\\Cache\\FileStore;\nuse Illuminate\\Contracts\\Filesystem\\FileNotFoundException;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass CacheFileStoreTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testNullIsReturnedIfFileDoesntExist()\n    {\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('get')->will($this->throwException(new FileNotFoundException));\n        $store = new FileStore($files, __DIR__);\n        $value = $store->get('foo');\n        $this->assertNull($value);\n    }\n\n    public function testPutCreatesMissingDirectories()\n    {\n        $files = $this->mockFilesystem();\n        $hash = sha1('foo');\n        $contents = '0000000000';\n        $full_dir = __DIR__.'/'.substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->expects($this->once())->method('makeDirectory')->with($this->equalTo($full_dir), $this->equalTo(0777), $this->equalTo(true));\n        $files->expects($this->once())->method('put')->with($this->equalTo($full_dir.'/'.$hash))->willReturn(strlen($contents));\n        $store = new FileStore($files, __DIR__);\n        $result = $store->put('foo', $contents, 0);\n        $this->assertTrue($result);\n    }\n\n    public function testPutWillConsiderZeroAsEternalTime()\n    {\n        $files = $this->mockFilesystem();\n\n        $hash = sha1('O--L / key');\n        $filePath = __DIR__.'/'.substr($hash, 0, 2).'/'.substr($hash, 2, 2).'/'.$hash;\n        $ten9s = '9999999999'; // The \"forever\" time value.\n        $fileContents = $ten9s.serialize('gold');\n        $exclusiveLock = true;\n\n        $files->expects($this->once())->method('put')->with(\n            $this->equalTo($filePath),\n            $this->equalTo($fileContents),\n            $this->equalTo($exclusiveLock) // Ensure we do lock the file while putting.\n        )->willReturn(strlen($fileContents));\n\n        (new FileStore($files, __DIR__))->put('O--L / key', 'gold', 0);\n    }\n\n    public function testPutWillConsiderBigValuesAsEternalTime()\n    {\n        $files = $this->mockFilesystem();\n\n        $hash = sha1('O--L / key');\n        $filePath = __DIR__.'/'.substr($hash, 0, 2).'/'.substr($hash, 2, 2).'/'.$hash;\n        $ten9s = '9999999999'; // The \"forever\" time value.\n        $fileContents = $ten9s.serialize('gold');\n\n        $files->expects($this->once())->method('put')->with(\n            $this->equalTo($filePath),\n            $this->equalTo($fileContents),\n        );\n\n        (new FileStore($files, __DIR__))->put('O--L / key', 'gold', (int) $ten9s + 1);\n    }\n\n    public function testExpiredItemsReturnNullAndGetDeleted()\n    {\n        $files = $this->mockFilesystem();\n        $contents = '0000000000';\n        $files->expects($this->once())->method('get')->willReturn($contents);\n        $store = $this->getMockBuilder(FileStore::class)->onlyMethods(['forget'])->setConstructorArgs([$files, __DIR__])->getMock();\n        $store->expects($this->once())->method('forget');\n        $value = $store->get('foo');\n        $this->assertNull($value);\n    }\n\n    public function testValidItemReturnsContents()\n    {\n        $files = $this->mockFilesystem();\n        $contents = '9999999999'.serialize('Hello World');\n        $files->expects($this->once())->method('get')->willReturn($contents);\n        $store = new FileStore($files, __DIR__);\n        $this->assertSame('Hello World', $store->get('foo'));\n    }\n\n    public function testStoreItemProperlyStoresValues()\n    {\n        $files = $this->mockFilesystem();\n        $store = $this->getMockBuilder(FileStore::class)->onlyMethods(['expiration'])->setConstructorArgs([$files, __DIR__])->getMock();\n        $store->expects($this->once())->method('expiration')->with($this->equalTo(10))->willReturn(1111111111);\n        $contents = '1111111111'.serialize('Hello World');\n        $hash = sha1('foo');\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->expects($this->once())->method('put')->with($this->equalTo(__DIR__.'/'.$cache_dir.'/'.$hash), $this->equalTo($contents))->willReturn(strlen($contents));\n        $result = $store->put('foo', 'Hello World', 10);\n        $this->assertTrue($result);\n    }\n\n    public function testTouchExtendsTtl(): void\n    {\n        $files = $this->mockFilesystem();\n        $store = $this->getMockBuilder(FileStore::class)->onlyMethods(['expiration', 'get', 'getPayload'])->setConstructorArgs([$files, __DIR__])->getMock();\n\n        $now = Carbon::now();\n\n        $key = 'foo';\n        $content = 'Hello World';\n        $ttl = 60;\n        $hash = sha1($key);\n        $path = __DIR__.'/'.substr($hash, 0, 2).'/'.substr($hash, 2, 2).'/'.$hash;\n\n        $store->expects($this->once())\n            ->method('expiration')\n            ->with($this->equalTo($ttl))\n            ->willReturn($now->clone()->addSeconds($ttl)->getTimestamp());\n        $store->expects($this->once())\n            ->method('getPayload')\n            ->with($key)\n            ->willReturn(['data' => $content, 'expiration' => $now->clone()->addSeconds($ttl)->getTimestamp()]);\n        $files->expects($this->once())\n            ->method('put')\n            ->with(\n                $this->equalTo($path),\n                $this->equalTo($now->clone()->addSeconds($ttl)->getTimestamp().serialize($content)),\n                $this->equalTo(true)\n            )\n            ->willReturn(1);\n\n        $this->assertTrue($store->touch($key, $ttl));\n    }\n\n    public function testStoreItemProperlySetsPermissions()\n    {\n        $files = m::mock(Filesystem::class);\n        $files->shouldIgnoreMissing();\n        $store = $this->getMockBuilder(FileStore::class)->onlyMethods(['expiration'])->setConstructorArgs([$files, __DIR__, 0644])->getMock();\n        $hash = sha1('foo');\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->shouldReceive('put')->withArgs([__DIR__.'/'.$cache_dir.'/'.$hash, m::any(), m::any()])->andReturnUsing(function ($name, $value) {\n            return strlen($value);\n        });\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_dir.'/'.$hash])->andReturnValues(['0600', '0644'])->times(3);\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_dir.'/'.$hash, 0644])->andReturn([true])->once();\n        $result = $store->put('foo', 'foo', 10);\n        $this->assertTrue($result);\n        $result = $store->put('foo', 'bar', 10);\n        $this->assertTrue($result);\n        $result = $store->put('foo', 'baz', 10);\n        $this->assertTrue($result);\n    }\n\n    public function testStoreItemDirectoryProperlySetsPermissions()\n    {\n        $files = m::mock(Filesystem::class);\n        $files->shouldIgnoreMissing();\n        $store = $this->getMockBuilder(FileStore::class)->onlyMethods(['expiration'])->setConstructorArgs([$files, __DIR__, 0606])->getMock();\n        $hash = sha1('foo');\n        $cache_parent_dir = substr($hash, 0, 2);\n        $cache_dir = $cache_parent_dir.'/'.substr($hash, 2, 2);\n\n        $files->shouldReceive('put')->withArgs([__DIR__.'/'.$cache_dir.'/'.$hash, m::any(), m::any()])->andReturnUsing(function ($name, $value) {\n            return strlen($value);\n        });\n\n        $files->shouldReceive('exists')->withArgs([__DIR__.'/'.$cache_dir])->andReturn(false)->once();\n        $files->shouldReceive('makeDirectory')->withArgs([__DIR__.'/'.$cache_dir, 0777, true, true])->once();\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_parent_dir])->andReturn(['0600'])->once();\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_parent_dir, 0606])->andReturn([true])->once();\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_dir])->andReturn(['0600'])->once();\n        $files->shouldReceive('chmod')->withArgs([__DIR__.'/'.$cache_dir, 0606])->andReturn([true])->once();\n\n        $result = $store->put('foo', 'foo', 10);\n        $this->assertTrue($result);\n    }\n\n    public function testForeversAreStoredWithHighTimestamp()\n    {\n        $files = $this->mockFilesystem();\n        $contents = '9999999999'.serialize('Hello World');\n        $hash = sha1('foo');\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->expects($this->once())->method('put')->with($this->equalTo(__DIR__.'/'.$cache_dir.'/'.$hash), $this->equalTo($contents))->willReturn(strlen($contents));\n        $store = new FileStore($files, __DIR__);\n        $result = $store->forever('foo', 'Hello World', 10);\n        $this->assertTrue($result);\n    }\n\n    public function testForeversAreNotRemovedOnIncrement()\n    {\n        $files = $this->mockFilesystem();\n        $contents = '9999999999'.serialize('Hello World');\n        $store = new FileStore($files, __DIR__);\n        $store->forever('foo', 'Hello World');\n        $store->increment('foo');\n        $files->expects($this->once())->method('get')->willReturn($contents);\n        $this->assertSame('Hello World', $store->get('foo'));\n    }\n\n    public function testIncrementExpiredKeys()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $filePath = $this->getCachePath('foo');\n        $files = $this->mockFilesystem();\n        $now = Carbon::now()->getTimestamp();\n        $initialValue = ($now - 10).serialize(77);\n        $valueAfterIncrement = '9999999999'.serialize(3);\n        $store = new FileStore($files, __DIR__);\n\n        $files->expects($this->once())->method('get')->with($this->equalTo($filePath), $this->equalTo(true))->willReturn($initialValue);\n        $files->expects($this->once())->method('put')->with($this->equalTo($filePath), $this->equalTo($valueAfterIncrement));\n\n        $result = $store->increment('foo', 3);\n    }\n\n    public function testIncrementCanAtomicallyJump()\n    {\n        $filePath = $this->getCachePath('foo');\n        $files = $this->mockFilesystem();\n        $initialValue = '9999999999'.serialize(1);\n        $valueAfterIncrement = '9999999999'.serialize(4);\n        $store = new FileStore($files, __DIR__);\n\n        $files->expects($this->once())->method('get')->with($this->equalTo($filePath), $this->equalTo(true))->willReturn($initialValue);\n        $files->expects($this->once())->method('put')->with($this->equalTo($filePath), $this->equalTo($valueAfterIncrement));\n\n        $result = $store->increment('foo', 3);\n        $this->assertEquals(4, $result);\n    }\n\n    public function testDecrementCanAtomicallyJump()\n    {\n        $filePath = $this->getCachePath('foo');\n\n        $files = $this->mockFilesystem();\n        $initialValue = '9999999999'.serialize(2);\n        $valueAfterIncrement = '9999999999'.serialize(0);\n        $store = new FileStore($files, __DIR__);\n\n        $files->expects($this->once())->method('get')->with($this->equalTo($filePath), $this->equalTo(true))->willReturn($initialValue);\n        $files->expects($this->once())->method('put')->with($this->equalTo($filePath), $this->equalTo($valueAfterIncrement));\n\n        $result = $store->decrement('foo', 2);\n        $this->assertEquals(0, $result);\n    }\n\n    public function testIncrementNonNumericValues()\n    {\n        $filePath = $this->getCachePath('foo');\n\n        $files = $this->mockFilesystem();\n        $initialValue = '1999999909'.serialize('foo');\n        $valueAfterIncrement = '1999999909'.serialize(1);\n        $store = new FileStore($files, __DIR__);\n        $files->expects($this->once())->method('get')->with($this->equalTo($filePath), $this->equalTo(true))->willReturn($initialValue);\n        $files->expects($this->once())->method('put')->with($this->equalTo($filePath), $this->equalTo($valueAfterIncrement));\n        $result = $store->increment('foo');\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testIncrementNonExistentKeys()\n    {\n        $filePath = $this->getCachePath('foo');\n\n        $files = $this->mockFilesystem();\n        $valueAfterIncrement = '9999999999'.serialize(1);\n        $store = new FileStore($files, __DIR__);\n        // simulates a missing item in file store by the exception\n        $files->expects($this->once())->method('get')->with($this->equalTo($filePath), $this->equalTo(true))->willThrowException(new Exception);\n        $files->expects($this->once())->method('put')->with($this->equalTo($filePath), $this->equalTo($valueAfterIncrement));\n        $result = $store->increment('foo');\n        $this->assertIsInt($result);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testIncrementDoesNotExtendCacheLife()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $files = $this->mockFilesystem();\n        $expiration = Carbon::now()->addSeconds(50)->getTimestamp();\n        $initialValue = $expiration.serialize(1);\n        $valueAfterIncrement = $expiration.serialize(2);\n        $store = new FileStore($files, __DIR__);\n        $files->expects($this->once())->method('get')->willReturn($initialValue);\n        $hash = sha1('foo');\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->expects($this->once())->method('put')->with($this->equalTo(__DIR__.'/'.$cache_dir.'/'.$hash), $this->equalTo($valueAfterIncrement));\n        $store->increment('foo');\n    }\n\n    public function testRemoveDeletesFileDoesntExist()\n    {\n        $files = $this->mockFilesystem();\n        $hash = sha1('foobull');\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n        $files->expects($this->once())->method('exists')->with($this->equalTo(__DIR__.'/'.$cache_dir.'/'.$hash))->willReturn(false);\n        $store = new FileStore($files, __DIR__);\n        $store->forget('foobull');\n    }\n\n    public function testRemoveDeletesFile()\n    {\n        $files = new Filesystem;\n        $store = new FileStore($files, __DIR__);\n        $store->put('foobar', 'Hello Baby', 10);\n\n        $this->assertFileExists($store->path('foobar'));\n\n        $store->forget('foobar');\n\n        $this->assertFileDoesNotExist($store->path('foobar'));\n    }\n\n    public function testFlushCleansDirectory()\n    {\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo(__DIR__))->willReturn(true);\n        $files->expects($this->once())->method('directories')->with($this->equalTo(__DIR__))->willReturn(['foo']);\n        $files->expects($this->once())->method('deleteDirectory')->with($this->equalTo('foo'))->willReturn(true);\n\n        $store = new FileStore($files, __DIR__);\n        $result = $store->flush();\n        $this->assertTrue($result, 'Flush failed');\n    }\n\n    public function testFlushFailsDirectoryClean()\n    {\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo(__DIR__))->willReturn(true);\n        $files->expects($this->once())->method('directories')->with($this->equalTo(__DIR__))->willReturn(['foo']);\n        $files->expects($this->once())->method('deleteDirectory')->with($this->equalTo('foo'))->willReturn(false);\n\n        $store = new FileStore($files, __DIR__);\n        $result = $store->flush();\n        $this->assertFalse($result, 'Flush should not have cleared directories');\n    }\n\n    public function testFlushIgnoreNonExistingDirectory()\n    {\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo(__DIR__.'--wrong'))->willReturn(false);\n\n        $store = new FileStore($files, __DIR__.'--wrong');\n        $result = $store->flush();\n        $this->assertFalse($result, 'Flush should not clean directory');\n    }\n\n    public function testFlushingLocksCleansDirectory()\n    {\n        $lockDir = __DIR__.'/locks';\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo($lockDir))->willReturn(true);\n        $files->expects($this->once())->method('directories')->with($this->equalTo($lockDir))->willReturn(['foo']);\n        $files->expects($this->once())->method('deleteDirectory')->with($this->equalTo('foo'))->willReturn(true);\n\n        $store = new FileStore($files, __DIR__);\n        $store->setLockDirectory($lockDir);\n        $result = $store->flushLocks();\n        $this->assertTrue($result, 'Flushing locks failed');\n    }\n\n    public function testFlushingLocksFailsDirectoryClean()\n    {\n        $lockDir = __DIR__.'/locks';\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo($lockDir))->willReturn(true);\n        $files->expects($this->once())->method('directories')->with($this->equalTo($lockDir))->willReturn(['foo']);\n        $files->expects($this->once())->method('deleteDirectory')->with($this->equalTo('foo'))->willReturn(false);\n\n        $store = new FileStore($files, __DIR__);\n        $store->setLockDirectory($lockDir);\n        $result = $store->flushLocks();\n        $this->assertFalse($result, 'Flushing locks should not have cleared directories');\n    }\n\n    public function testFlushingLocksIgnoreNonExistingDirectory()\n    {\n        $lockDir = __DIR__.'/locks';\n        $files = $this->mockFilesystem();\n        $files->expects($this->once())->method('isDirectory')->with($this->equalTo($lockDir))->willReturn(false);\n\n        $store = new FileStore($files, __DIR__);\n        $store->setLockDirectory($lockDir);\n        $result = $store->flushLocks();\n        $this->assertFalse($result, 'Flushing locks should not clean locks directory');\n    }\n\n    public function testHasSeparateLockStoreReturnsTrueWhenLockDirectoryDiffers()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n        $store->setLockDirectory('/locks');\n\n        $this->assertTrue($store->hasSeparateLockStore());\n    }\n\n    public function testHasSeparateLockStoreReturnsFalseWhenLockDirectoryIsSame()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n        $store->setLockDirectory(__DIR__);\n\n        $this->assertFalse($store->hasSeparateLockStore());\n    }\n\n    public function testHasSeparateLockStoreReturnsFalseWhenLockDirectoryIsNull()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n        $store->setLockDirectory(null);\n\n        $this->assertFalse($store->hasSeparateLockStore());\n    }\n\n    public function testFlushLocksThrowsExceptionWhenLockDirectoryIsSame()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n        $store->setLockDirectory(__DIR__);\n\n        $this->expectException(RuntimeException::class);\n\n        $store->flushLocks();\n    }\n\n    public function testItHandlesForgettingNonFlexibleKeys()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n\n        $key = Str::random();\n        $path = $store->path($key);\n        $flexiblePath = \"illuminate:cache:flexible:created:{$key}\";\n\n        $store->put($key, 'value', 5);\n\n        $this->assertFileExists($path);\n        $this->assertFileDoesNotExist($flexiblePath);\n\n        $store->forget($key);\n\n        $this->assertFileDoesNotExist($path);\n        $this->assertFileDoesNotExist($flexiblePath);\n    }\n\n    public function itOnlyForgetsFlexibleKeysIfParentIsForgotten()\n    {\n        $store = new FileStore(new Filesystem, __DIR__);\n\n        $key = Str::random();\n        $path = $store->path($key);\n        $flexiblePath = \"illuminate:cache:flexible:created:{$key}\";\n\n        touch($flexiblePath);\n\n        $this->assertFileDoesNotExist($path);\n        $this->assertFileExists($flexiblePath);\n\n        $store->forget($key);\n\n        $this->assertFileDoesNotExist($path);\n        $this->assertFileExists($flexiblePath);\n\n        $store->put($key, 'value', 5);\n\n        $this->assertFileDoesNotExist($path);\n        $this->assertFileDoesNotExist($flexiblePath);\n    }\n\n    protected function mockFilesystem()\n    {\n        return $this->createMock(Filesystem::class);\n    }\n\n    protected function getCachePath($key)\n    {\n        $hash = sha1($key);\n        $cache_dir = substr($hash, 0, 2).'/'.substr($hash, 2, 2);\n\n        return __DIR__.'/'.$cache_dir.'/'.$hash;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Cache\\NullStore;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Events\\Dispatcher as Event;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheManagerTest extends TestCase\n{\n    public function testCustomDriverClosureBoundObjectIsCacheManager()\n    {\n        $manager = new CacheManager($this->getApp([\n            'cache' => [\n                'stores' => [\n                    __CLASS__ => [\n                        'driver' => __CLASS__,\n                    ],\n                ],\n            ],\n        ]));\n        $manager->extend(__CLASS__, fn () => $this);\n        $this->assertSame($manager, $manager->store(__CLASS__));\n    }\n\n    public function testCustomDriverOverridesInternalDrivers()\n    {\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'my_store' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $cacheManager = new CacheManager($app);\n\n        $myArrayDriver = (object) ['flag' => 'mm(u_u)mm'];\n        $cacheManager->extend('array', fn () => $myArrayDriver);\n\n        $driver = $cacheManager->store('my_store');\n\n        $this->assertSame('mm(u_u)mm', $driver->flag);\n    }\n\n    public function testItCanBuildRepositories()\n    {\n        $app = $this->getApp([]);\n        $cacheManager = new CacheManager($app);\n\n        $arrayCache = $cacheManager->build(['driver' => 'array']);\n        $nullCache = $cacheManager->build(['driver' => 'null']);\n\n        $this->assertInstanceOf(ArrayStore::class, $arrayCache->getStore());\n        $this->assertInstanceOf(NullStore::class, $nullCache->getStore());\n    }\n\n    public function testItMakesRepositoryWhenContainerHasNoDispatcher()\n    {\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'my_store' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $this->assertFalse($app->bound(Dispatcher::class));\n\n        $cacheManager = new CacheManager($app);\n        $repo = $cacheManager->repository($theStore = new NullStore);\n\n        $this->assertNull($repo->getEventDispatcher());\n        $this->assertSame($theStore, $repo->getStore());\n\n        // binding dispatcher after the repo's birth will have no effect.\n        $app->bind(Dispatcher::class, fn () => new Event);\n\n        $this->assertNull($repo->getEventDispatcher());\n        $this->assertSame($theStore, $repo->getStore());\n\n        $cacheManager = new CacheManager($app);\n        $repo = $cacheManager->repository(new NullStore);\n        // now that the $app has a Dispatcher, the newly born repository will also have one.\n        $this->assertNotNull($repo->getEventDispatcher());\n    }\n\n    public function testItRefreshesDispatcherOnAllStores()\n    {\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'store_1' => [\n                        'driver' => 'array',\n                    ],\n                    'store_2' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $cacheManager = new CacheManager($app);\n        $repo1 = $cacheManager->store('store_1');\n        $repo2 = $cacheManager->store('store_2');\n\n        $this->assertNull($repo1->getEventDispatcher());\n        $this->assertNull($repo2->getEventDispatcher());\n\n        $dispatcher = new Event;\n        $app->bind(Dispatcher::class, fn () => $dispatcher);\n\n        $cacheManager->refreshEventDispatcher();\n\n        $this->assertNotSame($repo1, $repo2);\n        $this->assertSame($dispatcher, $repo1->getEventDispatcher());\n        $this->assertSame($dispatcher, $repo2->getEventDispatcher());\n    }\n\n    public function testItSetsDefaultDriverChangesGlobalConfig()\n    {\n        $userConfig = [\n            'cache' => [\n                'default' => 'store_1',\n                'stores' => [\n                    'store_1' => [\n                        'driver' => 'array',\n                    ],\n                    'store_2' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $cacheManager = new CacheManager($app);\n\n        $cacheManager->setDefaultDriver('><((((@>');\n\n        $this->assertEquals('><((((@>', $app->get('config')->get('cache.default'));\n    }\n\n    public function testItPurgesMemoizedStoreObjects()\n    {\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'store_1' => [\n                        'driver' => 'array',\n                    ],\n                    'store_2' => [\n                        'driver' => 'null',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $cacheManager = new CacheManager($app);\n\n        $repo1 = $cacheManager->store('store_1');\n        $repo2 = $cacheManager->store('store_1');\n\n        $repo3 = $cacheManager->store('store_2');\n        $repo4 = $cacheManager->store('store_2');\n        $repo5 = $cacheManager->store('store_2');\n\n        $this->assertSame($repo1, $repo2);\n        $this->assertSame($repo3, $repo4);\n        $this->assertSame($repo3, $repo5);\n        $this->assertNotSame($repo1, $repo5);\n\n        $cacheManager->purge('store_1');\n\n        // Make sure a now object is built this time.\n        $repo6 = $cacheManager->store('store_1');\n        $this->assertNotSame($repo1, $repo6);\n\n        // Make sure Purge does not delete all objects.\n        $repo7 = $cacheManager->store('store_2');\n        $this->assertSame($repo3, $repo7);\n    }\n\n    public function testForgetDriver()\n    {\n        $cacheManager = m::mock(CacheManager::class)\n            ->shouldAllowMockingProtectedMethods()\n            ->makePartial();\n\n        $cacheManager->shouldReceive('resolve')\n            ->withArgs(['array'])\n            ->times(4)\n            ->andReturn(new ArrayStore);\n\n        $cacheManager->shouldReceive('getDefaultDriver')\n            ->once()\n            ->andReturn('array');\n\n        foreach (['array', ['array'], null] as $option) {\n            $cacheManager->store('array');\n            $cacheManager->store('array');\n            $cacheManager->forgetDriver($option);\n            $cacheManager->store('array');\n            $cacheManager->store('array');\n        }\n    }\n\n    public function testForgetDriverForgets()\n    {\n        $cacheManager = new CacheManager([\n            'config' => [\n                'cache.stores.forget' => [\n                    'driver' => 'forget',\n                ],\n            ],\n        ]);\n        $cacheManager->extend('forget', function () {\n            return new ArrayStore;\n        });\n\n        $cacheManager->store('forget')->forever('foo', 'bar');\n        $this->assertSame('bar', $cacheManager->store('forget')->get('foo'));\n        $cacheManager->forgetDriver('forget');\n        $this->assertNull($cacheManager->store('forget')->get('foo'));\n    }\n\n    public function testThrowExceptionWhenUnknownDriverIsUsed()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Driver [unknown_taxi_driver] is not supported.');\n\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'my_store' => [\n                        'driver' => 'unknown_taxi_driver',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n\n        $cacheManager = new CacheManager($app);\n\n        $cacheManager->store('my_store');\n    }\n\n    public function testThrowExceptionWhenUnknownStoreIsUsed()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache store [alien_store] is not defined.');\n\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'my_store' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n\n        $cacheManager = new CacheManager($app);\n\n        $cacheManager->store('alien_store');\n    }\n\n    public function testMakesRepositoryWithoutDispatcherWhenEventsDisabled()\n    {\n        $userConfig = [\n            'cache' => [\n                'stores' => [\n                    'my_store' => [\n                        'driver' => 'array',\n                    ],\n                    'my_store_without_events' => [\n                        'driver' => 'array',\n                        'events' => false,\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $app->bind(Dispatcher::class, fn () => new Event);\n\n        $cacheManager = new CacheManager($app);\n\n        // The repository will have an event dispatcher\n        $repo = $cacheManager->store('my_store');\n        $this->assertNotNull($repo->getEventDispatcher());\n\n        // This repository will not have an event dispatcher as 'with_events' is false\n        $repoWithoutEvents = $cacheManager->store('my_store_without_events');\n        $this->assertNull($repoWithoutEvents->getEventDispatcher());\n    }\n\n    protected function getApp(array $userConfig)\n    {\n        $app = new Container;\n        $app->singleton('config', fn () => new Repository($userConfig));\n\n        return $app;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheMemcachedConnectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\MemcachedConnector;\nuse Memcached;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass CacheMemcachedConnectorTest extends TestCase\n{\n    public function testServersAreAddedCorrectly()\n    {\n        $memcached = $this->memcachedMockWithAddServer();\n\n        $connector = $this->connectorMock();\n        $connector->expects($this->once())\n            ->method('createMemcachedInstance')\n            ->willReturn($memcached);\n\n        $result = $this->connect($connector);\n\n        $this->assertSame($result, $memcached);\n    }\n\n    public function testServersAreAddedCorrectlyWithPersistentConnection()\n    {\n        $persistentConnectionId = 'persistent_connection_id';\n\n        $memcached = $this->memcachedMockWithAddServer();\n\n        $connector = $this->connectorMock();\n        $connector->expects($this->once())\n            ->method('createMemcachedInstance')\n            ->with($persistentConnectionId)\n            ->willReturn($memcached);\n\n        $result = $this->connect($connector, $persistentConnectionId);\n\n        $this->assertSame($result, $memcached);\n    }\n\n    #[RequiresPhpExtension('memcached')]\n    public function testServersAreAddedCorrectlyWithValidOptions()\n    {\n        $validOptions = [\n            Memcached::OPT_NO_BLOCK => true,\n            Memcached::OPT_CONNECT_TIMEOUT => 2000,\n        ];\n\n        $memcached = $this->memcachedMockWithAddServer();\n        $memcached->shouldReceive('setOptions')->once()->andReturn(true);\n\n        $connector = $this->connectorMock();\n        $connector->expects($this->once())\n            ->method('createMemcachedInstance')\n            ->willReturn($memcached);\n\n        $result = $this->connect($connector, false, $validOptions);\n\n        $this->assertSame($result, $memcached);\n    }\n\n    #[RequiresPhpExtension('memcached')]\n    public function testServersAreAddedCorrectlyWithSaslCredentials()\n    {\n        $saslCredentials = ['foo', 'bar'];\n\n        $memcached = $this->memcachedMockWithAddServer();\n        $memcached->shouldReceive('setOption')->once()->with(Memcached::OPT_BINARY_PROTOCOL, true)->andReturn(true);\n        $memcached->shouldReceive('setSaslAuthData')\n            ->once()->with($saslCredentials[0], $saslCredentials[1])\n            ->andReturn(true);\n\n        $connector = $this->connectorMock();\n        $connector->expects($this->once())->method('createMemcachedInstance')->willReturn($memcached);\n\n        $result = $this->connect($connector, false, [], $saslCredentials);\n\n        $this->assertSame($result, $memcached);\n    }\n\n    protected function memcachedMockWithAddServer($returnedVersion = [])\n    {\n        $memcached = m::mock(stdClass::class);\n        $memcached->shouldReceive('addServer')->once()->with($this->getHost(), $this->getPort(), $this->getWeight());\n        $memcached->shouldReceive('getServerList')->once()->andReturn([]);\n\n        return $memcached;\n    }\n\n    protected function connectorMock()\n    {\n        return $this->getMockBuilder(MemcachedConnector::class)->onlyMethods(['createMemcachedInstance'])->getMock();\n    }\n\n    protected function connect(\n        $connector,\n        $persistentConnectionId = false,\n        array $customOptions = [],\n        array $saslCredentials = []\n    ) {\n        return $connector->connect(\n            $this->getServers(),\n            $persistentConnectionId,\n            $customOptions,\n            $saslCredentials\n        );\n    }\n\n    protected function getServers()\n    {\n        return [['host' => $this->getHost(), 'port' => $this->getPort(), 'weight' => $this->getWeight()]];\n    }\n\n    protected function getHost()\n    {\n        return 'localhost';\n    }\n\n    protected function getPort()\n    {\n        return 11211;\n    }\n\n    protected function getWeight()\n    {\n        return 100;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheMemcachedStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\MemcachedStore;\nuse Illuminate\\Support\\Carbon;\nuse Memcached;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\n\n#[RequiresPhpExtension('memcached')]\nclass CacheMemcachedStoreTest extends TestCase\n{\n    public function testGetReturnsNullWhenNotFound()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['get', 'getResultCode'])->getMock();\n        $memcache->expects($this->once())->method('get')->with($this->equalTo('foo:bar'))->willReturn(null);\n        $memcache->expects($this->once())->method('getResultCode')->willReturn(1);\n        $store = new MemcachedStore($memcache, 'foo:');\n        $this->assertNull($store->get('bar'));\n    }\n\n    public function testMemcacheValueIsReturned()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['get', 'getResultCode'])->getMock();\n        $memcache->expects($this->once())->method('get')->willReturn('bar');\n        $memcache->expects($this->once())->method('getResultCode')->willReturn(0);\n        $store = new MemcachedStore($memcache);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testMemcacheGetMultiValuesAreReturnedWithCorrectKeys()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['getMulti', 'getResultCode'])->getMock();\n        $memcache->expects($this->once())->method('getMulti')->with(\n            ['foo:foo', 'foo:bar', 'foo:baz']\n        )->willReturn([\n            'fizz', 'buzz', 'norf',\n        ]);\n        $memcache->expects($this->once())->method('getResultCode')->willReturn(0);\n        $store = new MemcachedStore($memcache, 'foo:');\n        $this->assertEquals([\n            'foo' => 'fizz',\n            'bar' => 'buzz',\n            'baz' => 'norf',\n        ], $store->many([\n            'foo', 'bar', 'baz',\n        ]));\n    }\n\n    public function testSetMethodProperlyCallsMemcache()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['set'])->getMock();\n        $memcache->expects($this->once())->method('set')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo($now->timestamp + 60))->willReturn(true);\n        $store = new MemcachedStore($memcache);\n        $result = $store->put('foo', 'bar', 60);\n        $this->assertTrue($result);\n        Carbon::setTestNow(null);\n    }\n\n    public function testTouchMethodProperlyCallsMemcache(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        $now = Carbon::now();\n\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['touch'])->getMock();\n\n        $memcache->expects($this->once())->method('touch')->with($this->equalTo($key), $this->equalTo($now->addSeconds($ttl)->getTimestamp()))->willReturn(true);\n\n        $this->assertTrue((new MemcachedStore($memcache))->touch($key, $ttl));\n    }\n\n    public function testIncrementMethodProperlyCallsMemcache()\n    {\n        $memcached = m::mock(Memcached::class);\n        $memcached->shouldReceive('increment')->with('foo', 5)->once()->andReturn(5);\n\n        $store = new MemcachedStore($memcached);\n        $store->increment('foo', 5);\n    }\n\n    public function testDecrementMethodProperlyCallsMemcache()\n    {\n        $memcached = m::mock(Memcached::class);\n        $memcached->shouldReceive('decrement')->with('foo', 5)->once()->andReturn(0);\n\n        $store = new MemcachedStore($memcached);\n        $store->decrement('foo', 5);\n    }\n\n    public function testStoreItemForeverProperlyCallsMemcached()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['set'])->getMock();\n        $memcache->expects($this->once())->method('set')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(0))->willReturn(true);\n        $store = new MemcachedStore($memcache);\n        $result = $store->forever('foo', 'bar');\n        $this->assertTrue($result);\n    }\n\n    public function testForgetMethodProperlyCallsMemcache()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['delete'])->getMock();\n        $memcache->expects($this->once())->method('delete')->with($this->equalTo('foo'));\n        $store = new MemcachedStore($memcache);\n        $store->forget('foo');\n    }\n\n    public function testFlushesCached()\n    {\n        $memcache = $this->getMockBuilder(Memcached::class)->onlyMethods(['flush'])->getMock();\n        $memcache->expects($this->once())->method('flush')->willReturn(true);\n        $store = new MemcachedStore($memcache);\n        $result = $store->flush();\n        $this->assertTrue($result);\n    }\n\n    public function testGetAndSetPrefix()\n    {\n        $store = new MemcachedStore(new Memcached, 'bar');\n        $this->assertSame('bar', $store->getPrefix());\n        $store->setPrefix('foo');\n        $this->assertSame('foo', $store->getPrefix());\n        $store->setPrefix(null);\n        $this->assertEmpty($store->getPrefix());\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheMemoizedStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\MemoizedStore;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheMemoizedStoreTest extends TestCase\n{\n    public function testTouchExtendsTtl(): void\n    {\n        $store = new MemoizedStore('test', new Repository(new ArrayStore));\n\n        Carbon::setTestNow($now = Carbon::now());\n\n        $store->put('foo', 'bar', 30);\n        $store->touch('foo', 60);\n\n        Carbon::setTestNow($now->addSeconds(45));\n\n        $this->assertSame('bar', $store->get('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheNullStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\NullStore;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheNullStoreTest extends TestCase\n{\n    public function testItemsCanNotBeCached()\n    {\n        $store = new NullStore;\n        $store->put('foo', 'bar', 10);\n        $this->assertNull($store->get('foo'));\n    }\n\n    public function testGetMultipleReturnsMultipleNulls()\n    {\n        $store = new NullStore;\n\n        $this->assertEquals([\n            'foo' => null,\n            'bar' => null,\n        ], $store->many([\n            'foo',\n            'bar',\n        ]));\n    }\n\n    public function testIncrementAndDecrementReturnFalse()\n    {\n        $store = new NullStore;\n        $this->assertFalse($store->increment('foo'));\n        $this->assertFalse($store->decrement('foo'));\n    }\n\n    public function testTouchReturnsFalse(): void\n    {\n        $this->assertFalse((new NullStore)->touch('foo', 30));\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheRateLimiterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheRateLimiterTest extends TestCase\n{\n    public function testTooManyAttemptsReturnTrueIfAlreadyLockedOut()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->once()->with('key', 0)->andReturn(1);\n        $cache->shouldReceive('has')->once()->with('key:timer')->andReturn(true);\n        $cache->shouldReceive('add')->never();\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertTrue($rateLimiter->tooManyAttempts('key', 1));\n    }\n\n    public function testHitProperlyIncrementsAttemptCount()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);\n        $cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(true);\n        $cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->hit('key', 1);\n    }\n\n    public function testIncrementProperlyIncrementsAttemptCount()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);\n        $cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(true);\n        $cache->shouldReceive('increment')->once()->with('key', 5)->andReturn(5);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->increment('key', 1, 5);\n    }\n\n    public function testDecrementProperlyDecrementsAttemptCount()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);\n        $cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(true);\n        $cache->shouldReceive('increment')->once()->with('key', -5)->andReturn(-5);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->decrement('key', 1, 5);\n    }\n\n    public function testHitHasNoMemoryLeak()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1)->andReturn(true);\n        $cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturn(false);\n        $cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);\n        $cache->shouldReceive('put')->once()->with('key', 1, 1);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->hit('key', 1);\n    }\n\n    public function testRemainingIsNotNegative(): void\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->with('key', 0)->andReturn(5);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertSame(0, $rateLimiter->remaining('key', 3));\n        $this->assertSame(0, $rateLimiter->retriesLeft('key', 3));\n    }\n\n    public function testRetriesLeftReturnsCorrectCount()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->once()->with('key', 0)->andReturn(3);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertEquals(2, $rateLimiter->retriesLeft('key', 5));\n    }\n\n    public function testClearClearsTheCacheKeys()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('forget')->once()->with('key');\n        $cache->shouldReceive('forget')->once()->with('key:timer');\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->clear('key');\n    }\n\n    public function testAvailableInReturnsPositiveValues()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->andReturn(Carbon::now()->subSeconds(60)->getTimestamp(), null);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertTrue($rateLimiter->availableIn('key:timer') >= 0);\n        $this->assertTrue($rateLimiter->availableIn('key:timer') >= 0);\n    }\n\n    public function testAttemptsCallbackReturnsTrue()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->once()->with('key', 0)->andReturn(0);\n        $cache->shouldReceive('add')->once()->with('key:timer', m::type('int'), 1);\n        $cache->shouldReceive('add')->once()->with('key', 0, 1)->andReturns(1);\n        $cache->shouldReceive('increment')->once()->with('key', 1)->andReturn(1);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $executed = false;\n\n        $rateLimiter = new RateLimiter($cache);\n\n        $rateLimiter->attempt('key', 1, function () use (&$executed) {\n            $executed = true;\n        }, 1);\n        $this->assertTrue($executed);\n    }\n\n    public function testAttemptsCallbackReturnsCallbackReturn()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->times(6)->with('key', 0)->andReturn(0);\n        $cache->shouldReceive('add')->times(6)->with('key:timer', m::type('int'), 1);\n        $cache->shouldReceive('add')->times(6)->with('key', 0, 1)->andReturns(1);\n        $cache->shouldReceive('increment')->times(6)->with('key', 1)->andReturn(1);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertSame('foo', $rateLimiter->attempt('key', 1, function () {\n            return 'foo';\n        }, 1));\n\n        $this->assertSame(false, $rateLimiter->attempt('key', 1, function () {\n            return false;\n        }, 1));\n\n        $this->assertSame([], $rateLimiter->attempt('key', 1, function () {\n            return [];\n        }, 1));\n\n        $this->assertSame(0, $rateLimiter->attempt('key', 1, function () {\n            return 0;\n        }, 1));\n\n        $this->assertSame(0.0, $rateLimiter->attempt('key', 1, function () {\n            return 0.0;\n        }, 1));\n\n        $this->assertSame('', $rateLimiter->attempt('key', 1, function () {\n            return '';\n        }, 1));\n    }\n\n    public function testAttemptsCallbackReturnsFalse()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->once()->with('key', 0)->andReturn(2);\n        $cache->shouldReceive('has')->once()->with('key:timer')->andReturn(true);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $executed = false;\n\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertFalse($rateLimiter->attempt('key', 1, function () use (&$executed) {\n            $executed = true;\n        }, 1));\n        $this->assertFalse($executed);\n    }\n\n    public function testKeysAreSanitizedFromUnicodeCharacters()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->once()->with('john', 0)->andReturn(1);\n        $cache->shouldReceive('has')->once()->with('john:timer')->andReturn(true);\n        $cache->shouldReceive('add')->never();\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n        $rateLimiter = new RateLimiter($cache);\n\n        $this->assertTrue($rateLimiter->tooManyAttempts('jôhn', 1));\n    }\n\n    public function testKeyIsSanitizedOnlyOnce()\n    {\n        $cache = m::mock(Cache::class);\n        $rateLimiter = new RateLimiter($cache);\n\n        $key = \"john'doe\";\n        $cleanedKey = $rateLimiter->cleanRateLimiterKey($key);\n\n        $cache->shouldReceive('get')->once()->with($cleanedKey, 0)->andReturn(1);\n        $cache->shouldReceive('has')->once()->with(\"$cleanedKey:timer\")->andReturn(true);\n        $cache->shouldReceive('add')->never();\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->assertTrue($rateLimiter->tooManyAttempts($key, 1));\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheRedisStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\RedisStore;\nuse Illuminate\\Contracts\\Redis\\Factory;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheRedisStoreTest extends TestCase\n{\n    public function testGetReturnsNullWhenNotFound()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('get')->once()->with('prefix:foo')->andReturn(null);\n        $this->assertNull($redis->get('foo'));\n    }\n\n    public function testRedisValueIsReturned()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('get')->once()->with('prefix:foo')->andReturn(serialize('foo'));\n        $this->assertSame('foo', $redis->get('foo'));\n    }\n\n    public function testRedisMultipleValuesAreReturned()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('mget')->once()->with(['prefix:foo', 'prefix:fizz', 'prefix:norf', 'prefix:null'])\n            ->andReturn([\n                serialize('bar'),\n                serialize('buzz'),\n                serialize('quz'),\n                null,\n            ]);\n\n        $results = $redis->many(['foo', 'fizz', 'norf', 'null']);\n\n        $this->assertSame('bar', $results['foo']);\n        $this->assertSame('buzz', $results['fizz']);\n        $this->assertSame('quz', $results['norf']);\n        $this->assertNull($results['null']);\n    }\n\n    public function testRedisValueIsReturnedForNumerics()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('get')->once()->with('prefix:foo')->andReturn(1);\n        $this->assertEquals(1, $redis->get('foo'));\n    }\n\n    public function testSetMethodProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('setex')->once()->with('prefix:foo', 60, serialize('foo'))->andReturn('OK');\n        $result = $redis->put('foo', 'foo', 60);\n        $this->assertTrue($result);\n    }\n\n    public function testSetMultipleMethodProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        /** @var m\\MockInterface $connection */\n        $connection = $redis->getRedis();\n        $connection->shouldReceive('connection')->with('default')->andReturn($redis->getRedis());\n        $connection->shouldReceive('multi')->once();\n        $redis->getRedis()->shouldReceive('setex')->once()->with('prefix:foo', 60, serialize('bar'))->andReturn('OK');\n        $redis->getRedis()->shouldReceive('setex')->once()->with('prefix:baz', 60, serialize('qux'))->andReturn('OK');\n        $redis->getRedis()->shouldReceive('setex')->once()->with('prefix:bar', 60, serialize('norf'))->andReturn('OK');\n        $connection->shouldReceive('exec')->once();\n\n        $result = $redis->putMany([\n            'foo' => 'bar',\n            'baz' => 'qux',\n            'bar' => 'norf',\n        ], 60);\n        $this->assertTrue($result);\n    }\n\n    public function testSetMethodProperlyCallsRedisForNumerics()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('setex')->once()->with('prefix:foo', 60, 1);\n        $result = $redis->put('foo', 1, 60);\n        $this->assertFalse($result);\n    }\n\n    public function testIncrementMethodProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('incrby')->once()->with('prefix:foo', 5);\n        $redis->increment('foo', 5);\n    }\n\n    public function testDecrementMethodProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('decrby')->once()->with('prefix:foo', 5);\n        $redis->decrement('foo', 5);\n    }\n\n    public function testStoreItemForeverProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('set')->once()->with('prefix:foo', serialize('foo'))->andReturn('OK');\n        $result = $redis->forever('foo', 'foo', 60);\n        $this->assertTrue($result);\n    }\n\n    public function testTouchMethodProperlyCallsRedis(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        $redis = $this->getRedis();\n\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('expire')->once()->with(\"prefix:$key\", $ttl)->andReturn(true);\n\n        $this->assertTrue($redis->touch($key, $ttl));\n    }\n\n    public function testForgetMethodProperlyCallsRedis()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('del')->once()->with('prefix:foo');\n        $redis->forget('foo');\n    }\n\n    public function testFlushesCached()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('default')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('flushdb')->once()->andReturn('ok');\n        $result = $redis->flush();\n        $this->assertTrue($result);\n    }\n\n    public function testFlushesCachedLocks()\n    {\n        $redis = $this->getRedis();\n        $redis->getRedis()->shouldReceive('connection')->once()->with('locks')->andReturn($redis->getRedis());\n        $redis->getRedis()->shouldReceive('flushdb')->once()->andReturn('ok');\n        $redis->setLockConnection('locks');\n        $result = $redis->flushLocks();\n        $this->assertTrue($result);\n    }\n\n    public function testGetAndSetPrefix()\n    {\n        $redis = $this->getRedis();\n        $this->assertSame('prefix:', $redis->getPrefix());\n        $redis->setPrefix('foo');\n        $this->assertSame('foo', $redis->getPrefix());\n        $redis->setPrefix(null);\n        $this->assertEmpty($redis->getPrefix());\n    }\n\n    protected function getRedis()\n    {\n        return new RedisStore(m::mock(Factory::class), 'prefix:');\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheRepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse ArrayIterator;\nuse BadMethodCallException;\nuse DateInterval;\nuse DateTime;\nuse DateTimeImmutable;\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\FileStore;\nuse Illuminate\\Cache\\Lock;\nuse Illuminate\\Cache\\MemcachedStore;\nuse Illuminate\\Cache\\RedisStore;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Cache\\TaggableStore;\nuse Illuminate\\Cache\\TaggedCache;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\LockTimeoutException;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Carbon;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheRepositoryTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Carbon::setTestNow(Carbon::parse(self::getTestDate()));\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testGetReturnsValueFromCache()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $this->assertSame('bar', $repo->get('foo'));\n    }\n\n    public function testGetReturnsMultipleValuesFromCacheWhenGivenAnArray()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('many')->once()->with(['foo', 'bar'])->andReturn(['foo' => 'bar', 'bar' => 'baz']);\n        $this->assertEquals(['foo' => 'bar', 'bar' => 'baz'], $repo->get(['foo', 'bar']));\n    }\n\n    public function testGetReturnsMultipleValuesFromCacheWhenGivenAnArrayWithDefaultValues()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('many')->once()->with(['foo', 'bar'])->andReturn(['foo' => null, 'bar' => 'baz']);\n        $this->assertEquals(['foo' => 'default', 'bar' => 'baz'], $repo->get(['foo' => 'default', 'bar']));\n    }\n\n    public function testGetReturnsMultipleValuesFromCacheWhenGivenAnArrayOfOneTwoThree()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('many')->once()->with([1, 2, 3])->andReturn([1 => null, 2 => null, 3 => null]);\n        $this->assertEquals([1 => null, 2 => null, 3 => null], $repo->get([1, 2, 3]));\n    }\n\n    public function testDefaultValueIsReturned()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->times(2)->andReturn(null);\n        $this->assertSame('bar', $repo->get('foo', 'bar'));\n        $this->assertSame('baz', $repo->get('boom', function () {\n            return 'baz';\n        }));\n    }\n\n    public function testSettingDefaultCacheTime()\n    {\n        $repo = $this->getRepository();\n        $repo->setDefaultCacheTime(10);\n        $this->assertEquals(10, $repo->getDefaultCacheTime());\n    }\n\n    public function testHasMethod()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $repo->getStore()->shouldReceive('get')->once()->with('bar')->andReturn('bar');\n        $repo->getStore()->shouldReceive('get')->once()->with('baz')->andReturn(false);\n\n        $this->assertTrue($repo->has('bar'));\n        $this->assertFalse($repo->has('foo'));\n        $this->assertTrue($repo->has('baz'));\n    }\n\n    public function testMissingMethod()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $repo->getStore()->shouldReceive('get')->once()->with('bar')->andReturn('bar');\n\n        $this->assertTrue($repo->missing('foo'));\n        $this->assertFalse($repo->missing('bar'));\n    }\n\n    public function testRememberMethodCallsPutAndReturnsDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->andReturn(null);\n        $repo->getStore()->shouldReceive('put')->once()->with('foo', 'bar', 10);\n        $result = $repo->remember('foo', 10, function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $result);\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->times(2)->andReturn(null);\n        $repo->getStore()->shouldReceive('put')->once()->with('foo', 'bar', 602);\n        $repo->getStore()->shouldReceive('put')->once()->with('baz', 'qux', 598);\n        $result = $repo->remember('foo', Carbon::now()->addMinutes(10)->addSeconds(2), function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $result);\n        $result = $repo->remember('baz', Carbon::now()->addMinutes(10)->subSeconds(2), function () {\n            return 'qux';\n        });\n        $this->assertSame('qux', $result);\n\n        // Use a callable...\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->andReturn(null);\n        $repo->getStore()->shouldReceive('put')->once()->with('foo', 'bar', 10);\n        $result = $repo->remember('foo', function () {\n            return 10;\n        }, function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $result);\n    }\n\n    public function testRememberForeverMethodCallsForeverAndReturnsDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->andReturn(null);\n        $repo->getStore()->shouldReceive('forever')->once()->with('foo', 'bar');\n        $result = $repo->rememberForever('foo', function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $result);\n    }\n\n    public function testPuttingMultipleItemsInCache()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('putMany')->once()->with(['foo' => 'bar', 'bar' => 'baz'], 1);\n        $repo->put(['foo' => 'bar', 'bar' => 'baz'], 1);\n    }\n\n    public function testSettingMultipleItemsInCacheArray()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('putMany')->once()->with(['foo' => 'bar', 'bar' => 'baz'], 1)->andReturn(true);\n        $result = $repo->setMultiple(['foo' => 'bar', 'bar' => 'baz'], 1);\n        $this->assertTrue($result);\n    }\n\n    public function testSettingMultipleItemsInCacheIterator()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('putMany')->once()->with(['foo' => 'bar', 'bar' => 'baz'], 1)->andReturn(true);\n        $result = $repo->setMultiple(new ArrayIterator(['foo' => 'bar', 'bar' => 'baz']), 1);\n        $this->assertTrue($result);\n    }\n\n    public function testPutWithNullTTLRemembersItemForever()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forever')->once()->with('foo', 'bar')->andReturn(true);\n        $this->assertTrue($repo->put('foo', 'bar'));\n    }\n\n    public function testPutWithDatetimeInPastOrZeroSecondsRemovesOldItem()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('put')->never();\n        $repo->getStore()->shouldReceive('forget')->twice()->andReturn(true);\n        $result = $repo->put('foo', 'bar', Carbon::now()->subMinutes(10));\n        $this->assertTrue($result);\n        $result = $repo->put('foo', 'bar', Carbon::now());\n        $this->assertTrue($result);\n    }\n\n    public function testPutManyWithNullTTLRemembersItemsForever()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forever')->with('foo', 'bar')->andReturn(true);\n        $repo->getStore()->shouldReceive('forever')->with('bar', 'baz')->andReturn(true);\n        $this->assertTrue($repo->putMany(['foo' => 'bar', 'bar' => 'baz']));\n    }\n\n    public function testAddWithStoreFailureReturnsFalse()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('add')->never();\n        $repo->getStore()->shouldReceive('get')->andReturn(null);\n        $repo->getStore()->shouldReceive('put')->andReturn(false);\n        $this->assertFalse($repo->add('foo', 'bar', 60));\n    }\n\n    public function testCacheAddCallsRedisStoreAdd()\n    {\n        $store = m::mock(RedisStore::class);\n        $store->shouldReceive('add')->once()->with('k', 'v', 60)->andReturn(true);\n        $repository = new Repository($store);\n        $this->assertTrue($repository->add('k', 'v', 60));\n    }\n\n    public function testAddMethodCanAcceptDateIntervals()\n    {\n        $storeWithAdd = m::mock(RedisStore::class);\n        $storeWithAdd->shouldReceive('add')->once()->with('k', 'v', 61)->andReturn(true);\n        $repository = new Repository($storeWithAdd);\n        $this->assertTrue($repository->add('k', 'v', DateInterval::createFromDateString('61 seconds')));\n\n        $storeWithoutAdd = m::mock(ArrayStore::class);\n        $this->assertFalse(method_exists(ArrayStore::class, 'add'), 'This store should not have add method on it.');\n        $storeWithoutAdd->shouldReceive('get')->once()->with('k')->andReturn(null);\n        $storeWithoutAdd->shouldReceive('put')->once()->with('k', 'v', 60)->andReturn(true);\n        $repository = new Repository($storeWithoutAdd);\n        $this->assertTrue($repository->add('k', 'v', DateInterval::createFromDateString('60 seconds')));\n    }\n\n    public function testAddMethodCanAcceptDateTimeInterface()\n    {\n        $withAddStore = m::mock(RedisStore::class);\n        $withAddStore->shouldReceive('add')->once()->with('k', 'v', 61)->andReturn(true);\n        $repository = new Repository($withAddStore);\n        $this->assertTrue($repository->add('k', 'v', Carbon::now()->addSeconds(61)));\n\n        $noAddStore = m::mock(ArrayStore::class);\n        $this->assertFalse(method_exists(ArrayStore::class, 'add'), 'This store should not have add method on it.');\n        $noAddStore->shouldReceive('get')->once()->with('k')->andReturn(null);\n        $noAddStore->shouldReceive('put')->once()->with('k', 'v', 62)->andReturn(true);\n        $repository = new Repository($noAddStore);\n        $this->assertTrue($repository->add('k', 'v', Carbon::now()->addSeconds(62)));\n    }\n\n    public function testAddWithNullTTLRemembersItemForever()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $repo->getStore()->shouldReceive('forever')->once()->with('foo', 'bar')->andReturn(true);\n        $this->assertTrue($repo->add('foo', 'bar'));\n    }\n\n    public function testAddWithDatetimeInPastOrZeroSecondsReturnsImmediately()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('add', 'get', 'put')->never();\n        $result = $repo->add('foo', 'bar', Carbon::now()->subMinutes(10));\n        $this->assertFalse($result);\n        $result = $repo->add('foo', 'bar', Carbon::now());\n        $this->assertFalse($result);\n        $result = $repo->add('foo', 'bar', -1);\n        $this->assertFalse($result);\n    }\n\n    public static function dataProviderTestGetSeconds()\n    {\n        return [\n            [Carbon::parse(self::getTestDate())->addMinutes(5)],\n            [(new DateTime(self::getTestDate()))->modify('+5 minutes')],\n            [(new DateTimeImmutable(self::getTestDate()))->modify('+5 minutes')],\n            [new DateInterval('PT5M')],\n            [300],\n        ];\n    }\n\n    /**\n     * @param  mixed  $duration\n     */\n    #[DataProvider('dataProviderTestGetSeconds')]\n    public function testGetSeconds($duration)\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('put')->once()->with($key = 'foo', $value = 'bar', 300);\n        $repo->put($key, $value, $duration);\n    }\n\n    public function testRegisterMacroWithNonStaticCall()\n    {\n        $repo = $this->getRepository();\n        $repo::macro(__CLASS__, function () {\n            return 'Taylor';\n        });\n        $this->assertSame('Taylor', $repo->{__CLASS__}());\n    }\n\n    public function testForgettingCacheKey()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-key')->andReturn(true);\n        $repo->forget('a-key');\n    }\n\n    public function testRemovingCacheKey()\n    {\n        // Alias of Forget\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-key')->andReturn(true);\n        $repo->delete('a-key');\n    }\n\n    public function testSettingCache()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('put')->with($key = 'foo', $value = 'bar', 1)->andReturn(true);\n        $result = $repo->set($key, $value, 1);\n        $this->assertTrue($result);\n    }\n\n    public function testClearingWholeCache()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('flush')->andReturn(true);\n        $repo->clear();\n    }\n\n    public function testGettingMultipleValuesFromCache()\n    {\n        $keys = ['key1', 'key2', 'key3'];\n        $default = 5;\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('many')->once()->with(['key1', 'key2', 'key3'])->andReturn(['key1' => 1, 'key2' => null, 'key3' => null]);\n        $this->assertEquals(['key1' => 1, 'key2' => 5, 'key3' => 5], $repo->getMultiple($keys, $default));\n    }\n\n    public function testRemovingMultipleKeys()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-key')->andReturn(true);\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-second-key')->andReturn(true);\n\n        $this->assertTrue($repo->deleteMultiple(['a-key', 'a-second-key']));\n    }\n\n    public function testRemovingMultipleKeysFailsIfOneFails()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-key')->andReturn(true);\n        $repo->getStore()->shouldReceive('forget')->once()->with('a-second-key')->andReturn(false);\n\n        $this->assertFalse($repo->deleteMultiple(['a-key', 'a-second-key']));\n    }\n\n    public function testAllTagsArePassedToTaggableStore()\n    {\n        $store = m::mock(ArrayStore::class);\n        $repo = new Repository($store);\n\n        $taggedCache = m::mock();\n        $taggedCache->shouldReceive('setDefaultCacheTime');\n        $store->shouldReceive('tags')->once()->with(['foo', 'bar', 'baz'])->andReturn($taggedCache);\n        $repo->tags('foo', 'bar', 'baz');\n    }\n\n    public function testItThrowsExceptionWhenStoreDoesNotSupportTags()\n    {\n        $this->expectException(BadMethodCallException::class);\n\n        $store = new FileStore(new Filesystem, '/usr');\n        $this->assertFalse(method_exists($store, 'tags'), 'Store should not support tagging.');\n        (new Repository($store))->tags('foo');\n    }\n\n    public function testTagMethodReturnsTaggedCache()\n    {\n        $store = (new Repository(new ArrayStore()))->tags('foo');\n\n        $this->assertInstanceOf(TaggedCache::class, $store);\n    }\n\n    public function testPossibleInputTypesToTags()\n    {\n        $repo = new Repository(new ArrayStore());\n\n        $store = $repo->tags('foo');\n        $this->assertEquals(['foo'], $store->getTags()->getNames());\n\n        $store = $repo->tags(['foo!', 'Kangaroo']);\n        $this->assertEquals(['foo!', 'Kangaroo'], $store->getTags()->getNames());\n\n        $store = $repo->tags('r1', 'r2', 'r3');\n        $this->assertEquals(['r1', 'r2', 'r3'], $store->getTags()->getNames());\n    }\n\n    public function testEventDispatcherIsPassedToStoreFromRepository()\n    {\n        $repo = new Repository(new ArrayStore());\n        $repo->setEventDispatcher(new Dispatcher());\n\n        $store = $repo->tags('foo');\n\n        $this->assertSame($store->getEventDispatcher(), $repo->getEventDispatcher());\n    }\n\n    public function testDefaultCacheLifeTimeIsSetOnTaggableStore()\n    {\n        $repo = new Repository(new ArrayStore());\n        $repo->setDefaultCacheTime(random_int(1, 100));\n\n        $store = $repo->tags('foo');\n\n        $this->assertSame($store->getDefaultCacheTime(), $repo->getDefaultCacheTime());\n    }\n\n    public function testFlushLocksDelegatesToStore()\n    {\n        $flushable = m::mock(RedisStore::class);\n        $flushable->shouldReceive('flushLocks')->once()->andReturn(true);\n\n        $repo = new Repository($flushable);\n\n        $this->assertTrue($repo->flushLocks());\n    }\n\n    public function testTaggableRepositoriesSupportTags()\n    {\n        $taggable = m::mock(TaggableStore::class);\n        $taggableRepo = new Repository($taggable);\n\n        $this->assertTrue($taggableRepo->supportsTags());\n    }\n\n    public function testNonTaggableRepositoryDoesNotSupportTags()\n    {\n        $nonTaggable = m::mock(FileStore::class);\n        $nonTaggableRepo = new Repository($nonTaggable);\n\n        $this->assertFalse($nonTaggableRepo->supportsTags());\n    }\n\n    public function testFlushableLockRepositorySupportsFlushingLocks()\n    {\n        $flushable = m::mock(RedisStore::class);\n        $flushableRepo = new Repository($flushable);\n\n        $this->assertTrue($flushableRepo->supportsFlushingLocks());\n    }\n\n    public function testNonFlushableLockRepositoryDoesNotSupportFlushingLocks()\n    {\n        $nonFlushable = m::mock(MemcachedStore::class);\n        $nonFlushableRepo = new Repository($nonFlushable);\n\n        $this->assertFalse($nonFlushableRepo->supportsFlushingLocks());\n    }\n\n    public function testItThrowsExceptionWhenStoreDoesNotSupportFlushingLocks()\n    {\n        $this->expectException(BadMethodCallException::class);\n\n        $nonFlushable = m::mock(MemcachedStore::class);\n        $nonFlushableRepo = new Repository($nonFlushable);\n\n        $nonFlushableRepo->flushLocks();\n    }\n\n    public function testTouchWithSecondsTtlCorrectlyProxiesToStore(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('touch')->once()->with($key, $ttl)->andReturn(true);\n        $this->assertTrue($repo->touch($key, $ttl));\n    }\n\n    public function testTouchWithDatetimeTtlCorrectlyProxiesToStore(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        Carbon::setTestNow($now = Carbon::now());\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('touch')->once()->with($key, $ttl)->andReturn(true);\n        $this->assertTrue($repo->touch($key, $now->addSeconds($ttl)));\n    }\n\n    public function testTouchWithDateIntervalTtlCorrectlyProxiesToStore(): void\n    {\n        $key = 'key';\n        $ttl = 60;\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('touch')->once()->with($key, $ttl)->andReturn(true);\n        $this->assertTrue($repo->touch($key, DateInterval::createFromDateString(\"$ttl seconds\")));\n    }\n\n    public function testAtomicExecutesCallbackAndReturnsResult()\n    {\n        $repo = new Repository(new ArrayStore);\n\n        $result = $repo->withoutOverlapping('foo', function () {\n            return 'bar';\n        });\n\n        $this->assertSame('bar', $result);\n    }\n\n    public function testAtomicPassesLockAndWaitSecondsToLock()\n    {\n        $store = m::mock(Store::class, LockProvider::class);\n        $repo = new Repository($store);\n        $lock = m::mock(Lock::class);\n\n        $store->shouldReceive('lock')->once()->with('foo', 30, null)->andReturn($lock);\n        $lock->shouldReceive('block')->once()->with(15, m::type('callable'))->andReturnUsing(function ($seconds, $callback) {\n            return $callback();\n        });\n\n        $result = $repo->withoutOverlapping('foo', function () {\n            return 'bar';\n        }, 30, 15);\n\n        $this->assertSame('bar', $result);\n    }\n\n    public function testAtomicPassesOwnerToLock()\n    {\n        $store = m::mock(Store::class, LockProvider::class);\n        $repo = new Repository($store);\n        $lock = m::mock(Lock::class);\n\n        $store->shouldReceive('lock')->once()->with('foo', 10, 'my-owner')->andReturn($lock);\n        $lock->shouldReceive('block')->once()->with(10, m::type('callable'))->andReturnUsing(function ($seconds, $callback) {\n            return $callback();\n        });\n\n        $result = $repo->withoutOverlapping('foo', function () {\n            return 'bar';\n        }, 10, 10, 'my-owner');\n\n        $this->assertSame('bar', $result);\n    }\n\n    public function testAtomicThrowsOnLockTimeout()\n    {\n        $repo = new Repository(new ArrayStore);\n\n        $repo->getStore()->lock('foo', 10)->acquire();\n\n        $called = false;\n\n        try {\n            $repo->withoutOverlapping('foo', function () use (&$called) {\n                $called = true;\n            }, 10, 0);\n\n            $this->fail('Expected LockTimeoutException was not thrown.');\n        } catch (LockTimeoutException) {\n            $this->assertFalse($called);\n        }\n    }\n\n    public function testTaggedCacheWorksWithEnumKey()\n    {\n        $cache = (new Repository(new ArrayStore()))->tags('test-tag');\n\n        $cache->put(TestCacheKey::FOO, 5);\n        $this->assertSame(6, $cache->increment(TestCacheKey::FOO));\n        $this->assertSame(5, $cache->decrement(TestCacheKey::FOO));\n    }\n\n    protected function getRepository()\n    {\n        $dispatcher = new Dispatcher(m::mock(Container::class));\n        $repository = new Repository(m::mock(Store::class));\n\n        $repository->setEventDispatcher($dispatcher);\n\n        return $repository;\n    }\n\n    protected static function getTestDate()\n    {\n        return '2030-07-25 12:13:14 UTC';\n    }\n\n    public function testItGetsAsString()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $this->assertSame('bar', $repo->string('foo'));\n    }\n\n    public function testItGetsAsStringWithDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $this->assertSame('default', $repo->string('foo', 'default'));\n    }\n\n    public function testItThrowsExceptionWhenGettingNonStringAsString()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be a string, integer given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(123);\n        $repo->string('foo');\n    }\n\n    public function testItGetsAsInteger()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(123);\n        $this->assertSame(123, $repo->integer('foo'));\n    }\n\n    public function testItGetsAsIntegerWithDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $this->assertSame(456, $repo->integer('foo', 456));\n    }\n\n    public function testItGetsAsIntegerFromNumericString()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('123');\n        $this->assertSame(123, $repo->integer('foo'));\n    }\n\n    public function testItThrowsExceptionWhenGettingNonIntegerAsInteger()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be an integer, string given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $repo->integer('foo');\n    }\n\n    public function testItThrowsExceptionWhenGettingFloatStringAsInteger()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be an integer, string given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('1.5');\n        $repo->integer('foo');\n    }\n\n    public function testItGetsAsFloat()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(1.5);\n        $this->assertSame(1.5, $repo->float('foo'));\n    }\n\n    public function testItGetsAsFloatWithDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $this->assertSame(2.5, $repo->float('foo', 2.5));\n    }\n\n    public function testItGetsAsFloatFromNumericString()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('1.5');\n        $this->assertSame(1.5, $repo->float('foo'));\n    }\n\n    public function testItThrowsExceptionWhenGettingNonFloatAsFloat()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be a float, string given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $repo->float('foo');\n    }\n\n    public function testItGetsAsBoolean()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(true);\n        $this->assertTrue($repo->boolean('foo'));\n    }\n\n    public function testItGetsAsBooleanWithDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $this->assertFalse($repo->boolean('foo', false));\n    }\n\n    public function testItThrowsExceptionWhenGettingNonBooleanAsBoolean()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be a boolean, string given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $repo->boolean('foo');\n    }\n\n    public function testItGetsAsArray()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(['bar', 'baz']);\n        $this->assertSame(['bar', 'baz'], $repo->array('foo'));\n    }\n\n    public function testItGetsAsArrayWithDefault()\n    {\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn(null);\n        $this->assertSame(['default'], $repo->array('foo', ['default']));\n    }\n\n    public function testItThrowsExceptionWhenGettingNonArrayAsArray()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Cache value for key [foo] must be an array, string given.');\n\n        $repo = $this->getRepository();\n        $repo->getStore()->shouldReceive('get')->once()->with('foo')->andReturn('bar');\n        $repo->array('foo');\n    }\n}\n\nenum TestCacheKey: string\n{\n    case FOO = 'foo';\n}\n"
  },
  {
    "path": "tests/Cache/CacheSessionStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\SessionStore;\nuse Illuminate\\Session\\ArraySessionHandler;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass CacheSessionStoreTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testItemsCanBeSetAndRetrieved()\n    {\n        $store = new SessionStore(self::getSession());\n        $result = $store->put('foo', 'bar', 10);\n        $this->assertTrue($result);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testCacheTtl(): void\n    {\n        $store = new SessionStore(self::getSession());\n\n        Carbon::setTestNow('2000-01-01 00:00:00.500'); // 500 milliseconds past\n        $store->put('hello', 'world', 1);\n\n        Carbon::setTestNow('2000-01-01 00:00:01.499'); // progress 0.999 seconds\n        $this->assertSame('world', $store->get('hello'));\n\n        Carbon::setTestNow('2000-01-01 00:00:01.500'); // progress 0.001 seconds. 1 second since putting into cache.\n        $this->assertNull($store->get('hello'));\n    }\n\n    public function testMultipleItemsCanBeSetAndRetrieved()\n    {\n        $store = new SessionStore(self::getSession());\n        $result = $store->put('foo', 'bar', 10);\n        $resultMany = $store->putMany([\n            'fizz' => 'buz',\n            'quz' => 'baz',\n        ], 10);\n        $this->assertTrue($result);\n        $this->assertTrue($resultMany);\n        $this->assertEquals([\n            'foo' => 'bar',\n            'fizz' => 'buz',\n            'quz' => 'baz',\n            'norf' => null,\n        ], $store->many(['foo', 'fizz', 'quz', 'norf']));\n    }\n\n    public function testItemsCanExpire()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new SessionStore(self::getSession());\n\n        $store->put('foo', 'bar', 10);\n        Carbon::setTestNow(Carbon::now()->addSeconds(10)->addSecond());\n        $result = $store->get('foo');\n\n        $this->assertNull($result);\n    }\n\n    public function testTouchExtendsTtl()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 'bar', 10);\n\n        // Move time forward and touch to extend TTL\n        Carbon::setTestNow(Carbon::now()->addSeconds(5));\n        $this->assertTrue($store->touch('foo', 60));\n\n        // Value should still exist past the original expiry\n        Carbon::setTestNow(Carbon::now()->addSeconds(10));\n        $this->assertSame('bar', $store->get('foo'));\n\n        // Value should expire after the new TTL\n        Carbon::setTestNow(Carbon::now()->addSeconds(50));\n        $this->assertNull($store->get('foo'));\n    }\n\n    public function testStoreItemForeverProperlyStoresInArray()\n    {\n        $mock = $this->getMockBuilder(SessionStore::class)\n            ->setConstructorArgs([self::getSession()])\n            ->onlyMethods(['put'])\n            ->getMock();\n        $mock->expects($this->once())\n            ->method('put')->with($this->equalTo('foo'), $this->equalTo('bar'), $this->equalTo(0))\n            ->willReturn(true);\n        $result = $mock->forever('foo', 'bar');\n        $this->assertTrue($result);\n    }\n\n    public function testValuesCanBeIncremented()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 1, 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(2, $result);\n        $this->assertEquals(2, $store->get('foo'));\n\n        $result = $store->increment('foo', 2);\n        $this->assertEquals(4, $result);\n        $this->assertEquals(4, $store->get('foo'));\n    }\n\n    public function testValuesGetCastedByIncrementOrDecrement()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', '1', 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(2, $result);\n        $this->assertEquals(2, $store->get('foo'));\n\n        $store->put('bar', '1', 10);\n        $result = $store->decrement('bar');\n        $this->assertEquals(0, $result);\n        $this->assertEquals(0, $store->get('bar'));\n    }\n\n    public function testIncrementNonNumericValues()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 'I am string', 10);\n        $result = $store->increment('foo');\n        $this->assertEquals(1, $result);\n        $this->assertEquals(1, $store->get('foo'));\n    }\n\n    public function testNonExistingKeysCanBeIncremented()\n    {\n        $store = new SessionStore(self::getSession());\n        $result = $store->increment('foo');\n        $this->assertEquals(1, $result);\n        $this->assertEquals(1, $store->get('foo'));\n\n        // Will be there forever\n        Carbon::setTestNow(Carbon::now()->addYears(10));\n        $this->assertEquals(1, $store->get('foo'));\n    }\n\n    public function testExpiredKeysAreIncrementedLikeNonExistingKeys()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new SessionStore(self::getSession());\n\n        $store->put('foo', 999, 10);\n        Carbon::setTestNow(Carbon::now()->addSeconds(10)->addSecond());\n        $result = $store->increment('foo');\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testValuesCanBeDecremented()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 1, 10);\n        $result = $store->decrement('foo');\n        $this->assertEquals(0, $result);\n        $this->assertEquals(0, $store->get('foo'));\n\n        $result = $store->decrement('foo', 2);\n        $this->assertEquals(-2, $result);\n        $this->assertEquals(-2, $store->get('foo'));\n    }\n\n    public function testItemsCanBeRemoved()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 'bar', 10);\n        $this->assertTrue($store->forget('foo'));\n        $this->assertNull($store->get('foo'));\n        $this->assertFalse($store->forget('foo'));\n    }\n\n    public function testItemsCanBeFlushed()\n    {\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 'bar', 10);\n        $store->put('baz', 'boom', 10);\n        $result = $store->flush();\n        $this->assertTrue($result);\n        $this->assertNull($store->get('foo'));\n        $this->assertNull($store->get('baz'));\n    }\n\n    public function testCacheKey()\n    {\n        $store = new SessionStore(self::getSession());\n        $this->assertEmpty($store->getPrefix());\n    }\n\n    public function testItemKey()\n    {\n        $store = new SessionStore(self::getSession(), 'custom_prefix');\n        $this->assertEquals('custom_prefix.foo', $store->itemKey('foo'));\n    }\n\n    public function testValuesAreStoredByReference()\n    {\n        $store = new SessionStore(self::getSession());\n        $object = new stdClass;\n        $object->foo = true;\n\n        $store->put('object', $object, 10);\n        $object->bar = true;\n\n        $retrievedObject = $store->get('object');\n\n        $this->assertTrue($retrievedObject->foo);\n        $this->assertTrue($retrievedObject->bar);\n    }\n\n    public function testCanGetAll()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $store = new SessionStore(self::getSession());\n        $store->put('foo', 'bar', 10);\n\n        $this->assertEquals([\n            'foo' => ['value' => 'bar', 'expiresAt' => Carbon::now()->addSeconds(10)->getPreciseTimestamp(3) / 1000],\n        ], $store->all());\n    }\n\n    protected static function getSession()\n    {\n        return new Store(\n            name: 'name',\n            serialization: 'php',\n            handler: new ArraySessionHandler(10),\n            id: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheSpyMemoTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Closure;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Config\\Repository as ConfigRepository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Mockery as m;\nuse Mockery\\LegacyMockInterface;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheSpyMemoTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $container = new Container;\n\n        $container->instance('config', new ConfigRepository([\n            'cache' => [\n                'default' => 'array',\n                'stores' => [\n                    'array' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ]));\n\n        $container->instance('cache', new CacheManager($container));\n\n        Facade::setFacadeApplication($container);\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::clearResolvedInstances();\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function test_cache_spy_works_with_memoized_cache()\n    {\n        $cache = Cache::spy();\n\n        Cache::memo()->remember('key', 60, fn () => 'bar');\n\n        $cache->shouldHaveReceived('memo')->once();\n    }\n\n    public function test_cache_spy_tracks_remember_on_memoized_cache_as_described_in_issue()\n    {\n        $cache = Cache::spy();\n\n        $memoizedCache = Cache::memo();\n        $value = $memoizedCache->remember('key', 60, fn () => 'bar');\n\n        $this->assertSame('bar', $value);\n\n        $memoizedCache->shouldHaveReceived('remember')->once()->with('key', 60, m::type(Closure::class));\n    }\n\n    public function test_cache_spy_tracks_remember_calls_on_memoized_cache()\n    {\n        $cache = Cache::spy();\n\n        $memoizedCache = Cache::memo();\n        $memoizedCache->remember('key', 60, fn () => 'bar');\n\n        $memoizedCache->shouldHaveReceived('remember')->once()->with('key', 60, m::type(Closure::class));\n    }\n\n    public function test_cache_spy_memo_returns_spied_repository()\n    {\n        $cache = Cache::spy();\n\n        $memoizedCache = Cache::memo();\n\n        $this->assertInstanceOf(LegacyMockInterface::class, $memoizedCache);\n\n        $memoizedCache->remember('key', 60, fn () => 'bar');\n\n        $memoizedCache->shouldHaveReceived('remember')->once();\n    }\n}\n"
  },
  {
    "path": "tests/Cache/CacheTaggedCacheTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse DateInterval;\nuse DateTime;\nuse Illuminate\\Cache\\ArrayStore;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheTaggedCacheTest extends TestCase\n{\n    public function testCacheCanBeSavedWithMultipleTags()\n    {\n        $store = new ArrayStore;\n        $tags = ['bop', 'zap'];\n        $store->tags($tags)->put('foo', 'bar', 10);\n        $this->assertSame('bar', $store->tags($tags)->get('foo'));\n    }\n\n    public function testCacheCanBeSetWithDatetimeArgument()\n    {\n        $store = new ArrayStore;\n        $tags = ['bop', 'zap'];\n        $duration = new DateTime;\n        $duration->add(new DateInterval('PT10M'));\n        $store->tags($tags)->put('foo', 'bar', $duration);\n        $this->assertSame('bar', $store->tags($tags)->get('foo'));\n    }\n\n    public function testCacheSavedWithMultipleTagsCanBeFlushed()\n    {\n        $store = new ArrayStore;\n        $tags1 = ['bop', 'zap'];\n        $store->tags($tags1)->put('foo', 'bar', 10);\n        $tags2 = ['bam', 'pow'];\n        $store->tags($tags2)->put('foo', 'bar', 10);\n        $store->tags('zap')->flush();\n        $this->assertNull($store->tags($tags1)->get('foo'));\n        $this->assertSame('bar', $store->tags($tags2)->get('foo'));\n    }\n\n    public function testTagsWithStringArgument()\n    {\n        $store = new ArrayStore;\n        $store->tags('bop')->put('foo', 'bar', 10);\n        $this->assertSame('bar', $store->tags('bop')->get('foo'));\n    }\n\n    public function testWithIncrement()\n    {\n        $store = new ArrayStore;\n        $taggableStore = $store->tags('bop');\n\n        $taggableStore->put('foo', 5, 10);\n\n        $value = $taggableStore->increment('foo');\n        $this->assertSame(6, $value);\n\n        $value = $taggableStore->increment('foo');\n        $this->assertSame(7, $value);\n\n        $value = $taggableStore->increment('foo', 3);\n        $this->assertSame(10, $value);\n\n        $value = $taggableStore->increment('foo', -2);\n        $this->assertSame(8, $value);\n\n        $value = $taggableStore->increment('x');\n        $this->assertSame(1, $value);\n\n        $value = $taggableStore->increment('y', 10);\n        $this->assertSame(10, $value);\n    }\n\n    public function testWithDecrement()\n    {\n        $store = new ArrayStore;\n        $taggableStore = $store->tags('bop');\n\n        $taggableStore->put('foo', 50, 10);\n\n        $value = $taggableStore->decrement('foo');\n        $this->assertSame(49, $value);\n\n        $value = $taggableStore->decrement('foo');\n        $this->assertSame(48, $value);\n\n        $value = $taggableStore->decrement('foo', 3);\n        $this->assertSame(45, $value);\n\n        $value = $taggableStore->decrement('foo', -2);\n        $this->assertSame(47, $value);\n\n        $value = $taggableStore->decrement('x');\n        $this->assertSame(-1, $value);\n\n        $value = $taggableStore->decrement('y', 10);\n        $this->assertSame(-10, $value);\n    }\n\n    public function testMany()\n    {\n        $store = $this->getTestCacheStoreWithTagValues();\n\n        $values = $store->tags(['fruit'])->many(['a', 'e', 'b', 'd', 'c']);\n        $this->assertSame([\n            'a' => 'apple',\n            'e' => null,\n            'b' => 'banana',\n            'd' => null,\n            'c' => 'orange',\n        ], $values);\n    }\n\n    public function testManyWithDefaultValues()\n    {\n        $store = $this->getTestCacheStoreWithTagValues();\n\n        $values = $store->tags(['fruit'])->many([\n            'a' => 147,\n            'e' => 547,\n            'b' => 'hello world!',\n            'x' => 'hello world!',\n            'd',\n            'c',\n        ]);\n        $this->assertSame([\n            'a' => 'apple',\n            'e' => 547,\n            'b' => 'banana',\n            'x' => 'hello world!',\n            'd' => null,\n            'c' => 'orange',\n        ], $values);\n    }\n\n    public function testGetMultiple()\n    {\n        $store = $this->getTestCacheStoreWithTagValues();\n\n        $values = $store->tags(['fruit'])->getMultiple(['a', 'e', 'b', 'd', 'c']);\n        $this->assertSame([\n            'a' => 'apple',\n            'e' => null,\n            'b' => 'banana',\n            'd' => null,\n            'c' => 'orange',\n        ], $values);\n\n        $values = $store->tags(['fruit', 'color'])->getMultiple(['a', 'e', 'b', 'd', 'c']);\n        $this->assertSame([\n            'a' => 'red',\n            'e' => 'blue',\n            'b' => null,\n            'd' => 'yellow',\n            'c' => null,\n        ], $values);\n    }\n\n    public function testGetMultipleWithDefaultValue()\n    {\n        $store = $this->getTestCacheStoreWithTagValues();\n\n        $values = $store->tags(['fruit', 'color'])->getMultiple(['a', 'e', 'b', 'd', 'c'], 547);\n        $this->assertSame([\n            'a' => 'red',\n            'e' => 'blue',\n            'b' => 547,\n            'd' => 'yellow',\n            'c' => 547,\n        ], $values);\n    }\n\n    public function testTagsWithIncrementCanBeFlushed()\n    {\n        $store = new ArrayStore;\n        $store->tags('bop')->increment('foo', 5);\n        $this->assertEquals(5, $store->tags('bop')->get('foo'));\n        $store->tags('bop')->flush();\n        $this->assertNull($store->tags('bop')->get('foo'));\n    }\n\n    public function testTagsWithDecrementCanBeFlushed()\n    {\n        $store = new ArrayStore;\n        $store->tags('bop')->decrement('foo', 5);\n        $this->assertEquals(-5, $store->tags('bop')->get('foo'));\n        $store->tags('bop')->flush();\n        $this->assertNull($store->tags('bop')->get('foo'));\n    }\n\n    public function testTagsCacheForever()\n    {\n        $store = new ArrayStore;\n        $tags = ['bop', 'zap'];\n        $store->tags($tags)->forever('foo', 'bar');\n        $this->assertSame('bar', $store->tags($tags)->get('foo'));\n    }\n\n    private function getTestCacheStoreWithTagValues(): ArrayStore\n    {\n        $store = new ArrayStore;\n\n        $tags = ['fruit'];\n        $store->tags($tags)->put('a', 'apple', 10);\n        $store->tags($tags)->put('b', 'banana', 10);\n        $store->tags($tags)->put('c', 'orange', 10);\n\n        $tags = ['fruit', 'color'];\n        $store->tags($tags)->putMany([\n            'a' => 'red',\n            'd' => 'yellow',\n            'e' => 'blue',\n        ], 10);\n\n        $tags = ['sizes', 'shirt'];\n        $store->tags($tags)->putMany([\n            'a' => 'small',\n            'b' => 'medium',\n            'c' => 'large',\n        ], 10);\n\n        return $store;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/ClearCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse BadMethodCallException;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Cache\\Console\\ClearCommand;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Application;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass ClearCommandTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Tests\\Cache\\ClearCommandTestStub\n     */\n    private $command;\n\n    /**\n     * @var \\Illuminate\\Cache\\CacheManager|\\Mockery\\MockInterface\n     */\n    private $cacheManager;\n\n    /**\n     * @var \\Illuminate\\Filesystem\\Filesystem|\\Mockery\\MockInterface\n     */\n    private $files;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Repository|\\Mockery\\MockInterface\n     */\n    private $cacheRepository;\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->cacheManager = m::mock(CacheManager::class);\n        $this->files = m::mock(Filesystem::class);\n        $this->cacheRepository = m::mock(Repository::class);\n        $this->command = new ClearCommandTestStub($this->cacheManager, $this->files);\n\n        $app = new Application;\n        $app['path.storage'] = __DIR__;\n        $this->command->setLaravel($app);\n    }\n\n    public function testClearWithNoStoreArgument()\n    {\n        $this->files->shouldReceive('exists')->andReturn(true);\n        $this->files->shouldReceive('files')->andReturn([]);\n\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        $this->runCommand($this->command);\n    }\n\n    public function testClearWithStoreArgument()\n    {\n        $this->files->shouldReceive('exists')->andReturn(true);\n        $this->files->shouldReceive('files')->andReturn([]);\n\n        $this->cacheManager->shouldReceive('store')->once()->with('foo')->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        $this->runCommand($this->command, ['store' => 'foo']);\n    }\n\n    public function testClearWithInvalidStoreArgument()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $this->files->shouldReceive('files')->andReturn([]);\n\n        $this->cacheManager->shouldReceive('store')->once()->with('bar')->andThrow(InvalidArgumentException::class);\n        $this->cacheRepository->shouldReceive('flush')->never();\n\n        $this->runCommand($this->command, ['store' => 'bar']);\n    }\n\n    public function testClearWithTagsOption()\n    {\n        $this->files->shouldReceive('exists')->andReturn(true);\n        $this->files->shouldReceive('files')->andReturn([]);\n\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('tags')->once()->with(['foo', 'bar'])->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        $this->runCommand($this->command, ['--tags' => 'foo,bar']);\n    }\n\n    public function testClearWithStoreArgumentAndTagsOption()\n    {\n        $this->files->shouldReceive('exists')->andReturn(true);\n        $this->files->shouldReceive('files')->andReturn([]);\n\n        $this->cacheManager->shouldReceive('store')->once()->with('redis')->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('tags')->once()->with(['foo'])->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        $this->runCommand($this->command, ['store' => 'redis', '--tags' => 'foo']);\n    }\n\n    public function testClearWillClearRealTimeFacades()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        $this->files->shouldReceive('exists')->andReturn(true);\n        $this->files->shouldReceive('files')->andReturn(['/facade-XXXX.php']);\n        $this->files->shouldReceive('delete')->with('/facade-XXXX.php')->once();\n\n        $this->runCommand($this->command);\n    }\n\n    public function testClearWillNotClearRealTimeFacadesIfCacheDirectoryDoesntExist()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flush')->once();\n\n        // No files should be looped over and nothing should be deleted if the cache directory doesn't exist\n        $this->files->shouldReceive('exists')->andReturn(false);\n        $this->files->shouldNotReceive('files');\n        $this->files->shouldNotReceive('delete');\n\n        $this->runCommand($this->command);\n    }\n\n    public function testClearLocksWithNoStoreArgument()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flushLocks')->once()->andReturn(true);\n        $this->cacheRepository->shouldNotReceive('flush');\n\n        $this->files->shouldNotReceive('exists');\n        $this->files->shouldNotReceive('files');\n        $this->files->shouldNotReceive('delete');\n\n        $this->assertSame(0, $this->runCommand($this->command, ['--locks' => true]));\n    }\n\n    public function testClearLocksWithStoreArgument()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with('redis')->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flushLocks')->once()->andReturn(true);\n        $this->cacheRepository->shouldNotReceive('flush');\n\n        $this->assertSame(0, $this->runCommand($this->command, ['store' => 'redis', '--locks' => true]));\n    }\n\n    public function testClearLocksCannotBeUsedWithTags()\n    {\n        $this->cacheManager->shouldNotReceive('store');\n        $this->cacheRepository->shouldNotReceive('flush');\n        $this->cacheRepository->shouldNotReceive('flushLocks');\n\n        $this->assertSame(1, $this->runCommand($this->command, ['--locks' => true, '--tags' => 'foo']));\n    }\n\n    public function testClearLocksWillFailWhenNotSupportedByStore()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flushLocks')->once()->andThrow(new BadMethodCallException);\n        $this->cacheRepository->shouldNotReceive('flush');\n\n        $this->assertSame(1, $this->runCommand($this->command, ['--locks' => true]));\n    }\n\n    public function testClearLocksWillFailWhenFlushLocksFails()\n    {\n        $this->cacheManager->shouldReceive('store')->once()->with(null)->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('flushLocks')->once()->andReturn(false);\n        $this->cacheRepository->shouldNotReceive('flush');\n\n        $this->assertSame(1, $this->runCommand($this->command, ['--locks' => true]));\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n\nclass ClearCommandTestStub extends ClearCommand\n{\n    public function call($command, array $arguments = [])\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "tests/Cache/ConcurrencyLimiterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse BadMethodCallException;\nuse Error;\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\Limiters\\ConcurrencyLimiter;\nuse Illuminate\\Cache\\Limiters\\LimiterTimeoutException;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nclass ConcurrencyLimiterTest extends TestCase\n{\n    protected Repository $repository;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->repository = new Repository(new ArrayStore);\n    }\n\n    public function testItLocksTasksWhenNoSlotAvailable()\n    {\n        $store = [];\n\n        foreach (range(1, 2) as $i) {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'key', 2, 5))->block(2, function () use (&$store, $i) {\n                $store[] = $i;\n            });\n        }\n\n        try {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'key', 2, 5))->block(0, function () use (&$store) {\n                $store[] = 3;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        (new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'other_key', 2, 5))->block(2, function () use (&$store) {\n            $store[] = 4;\n        });\n\n        $this->assertEquals([1, 2, 4], $store);\n    }\n\n    public function testItReleasesLockAfterTaskFinishes()\n    {\n        $store = [];\n\n        foreach (range(1, 4) as $i) {\n            (new ConcurrencyLimiter($this->repository->getStore(), 'key', 2, 5))->block(2, function () use (&$store, $i) {\n                $store[] = $i;\n            });\n        }\n\n        $this->assertEquals([1, 2, 3, 4], $store);\n    }\n\n    public function testItReleasesLockIfTaskTookTooLong()\n    {\n        $store = [];\n\n        $lock = new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'key', 1, 1);\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(0, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        usleep(1.2 * 1000000);\n\n        $lock->block(0, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 3], $store);\n    }\n\n    public function testItFailsImmediatelyOrRetriesForAWhileBasedOnAGivenTimeout()\n    {\n        $store = [];\n\n        $lock = new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'key', 1, 2);\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(0, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        $lock->block(3, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 3], $store);\n    }\n\n    public function testItFailsAfterRetryTimeout()\n    {\n        $store = [];\n\n        $lock = new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'key', 1, 10);\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(2, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        $this->assertEquals([1], $store);\n    }\n\n    public function testItReleasesIfErrorIsThrown()\n    {\n        $store = [];\n\n        $lock = new ConcurrencyLimiter($this->repository->getStore(), 'key', 1, 5);\n\n        try {\n            $lock->block(1, function () {\n                throw new Error;\n            });\n        } catch (Error) {\n        }\n\n        $lock = new ConcurrencyLimiter($this->repository->getStore(), 'key', 1, 5);\n        $lock->block(1, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        $this->assertEquals([1], $store);\n    }\n\n    public function testFunnelMethodOnRepository()\n    {\n        $store = [];\n\n        $result = $this->repository->funnel('test-funnel')\n            ->limit(2)\n            ->releaseAfter(5)\n            ->block(2)\n            ->then(function () use (&$store) {\n                $store[] = 1;\n\n                return 'ok';\n            });\n\n        $this->assertEquals([1], $store);\n        $this->assertSame('ok', $result);\n    }\n\n    public function testFunnelMethodAcceptsBackedEnum()\n    {\n        $store = [];\n\n        $result = $this->repository->funnel(ConcurrencyLimiterBackedEnum::TestFunnel)\n            ->limit(2)\n            ->releaseAfter(5)\n            ->block(2)\n            ->then(function () use (&$store) {\n                $store[] = 1;\n\n                return 'ok';\n            });\n\n        $this->assertEquals([1], $store);\n        $this->assertSame('ok', $result);\n    }\n\n    public function testFunnelMethodAcceptsUnitEnum()\n    {\n        $store = [];\n\n        $result = $this->repository->funnel(ConcurrencyLimiterUnitEnum::TestFunnel)\n            ->limit(2)\n            ->releaseAfter(5)\n            ->block(2)\n            ->then(function () use (&$store) {\n                $store[] = 1;\n\n                return 'ok';\n            });\n\n        $this->assertEquals([1], $store);\n        $this->assertSame('ok', $result);\n    }\n\n    public function testFunnelBackedEnumSharesKeyWithStringEquivalent()\n    {\n        // Fill all slots using the backed enum's string value\n        foreach (range(1, 2) as $i) {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'test-funnel', 2, 5))->block(2, function () {\n            });\n        }\n\n        // Try to acquire via the BackedEnum — should conflict with the string key\n        $result = $this->repository->funnel(ConcurrencyLimiterBackedEnum::TestFunnel)\n            ->limit(2)\n            ->releaseAfter(5)\n            ->block(0)\n            ->then(\n                function () {\n                    return 'success';\n                },\n                function () {\n                    return 'failed';\n                }\n            );\n\n        $this->assertSame('failed', $result);\n    }\n\n    public function testFunnelThrowsExceptionWhenStoreDoesNotSupportLocks()\n    {\n        $store = $this->createMock(Store::class);\n        $repository = new Repository($store);\n\n        $this->assertNotInstanceOf(LockProvider::class, $store);\n\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('This cache store does not support locks.');\n\n        $repository->funnel('test');\n    }\n\n    public function testFunnelWithFailureCallback()\n    {\n        $store = [];\n\n        // Fill all slots without releasing\n        foreach (range(1, 2) as $i) {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->repository->getStore(), 'funnel-key', 2, 5))->block(2, function () use (&$store, $i) {\n                $store[] = $i;\n            });\n        }\n\n        // Try to acquire when all slots are full\n        $result = $this->repository->funnel('funnel-key')\n            ->limit(2)\n            ->releaseAfter(5)\n            ->block(0)\n            ->then(\n                function () use (&$store) {\n                    $store[] = 'success';\n                },\n                function ($e) use (&$store) {\n                    $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n                    $store[] = 'failed';\n\n                    return 'failure-result';\n                }\n            );\n\n        $this->assertEquals([1, 2, 'failed'], $store);\n        $this->assertSame('failure-result', $result);\n    }\n}\n\nclass ConcurrencyLimiterMockThatDoesntRelease extends ConcurrencyLimiter\n{\n    protected function release($lock)\n    {\n        //\n    }\n}\n\nenum ConcurrencyLimiterBackedEnum: string\n{\n    case TestFunnel = 'test-funnel';\n}\n\nenum ConcurrencyLimiterUnitEnum\n{\n    case TestFunnel;\n}\n"
  },
  {
    "path": "tests/Cache/LimitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\RateLimiting\\GlobalLimit;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse PHPUnit\\Framework\\TestCase;\n\nclass LimitTest extends TestCase\n{\n    public function testConstructors()\n    {\n        $limit = new Limit('', 3, 1);\n        $this->assertSame(1, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perSecond(3);\n        $this->assertSame(1, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perSecond(3, 5);\n        $this->assertSame(5, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perMinute(3);\n        $this->assertSame(60, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perMinute(3, 4);\n        $this->assertSame(240, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perMinutes(2, 3);\n        $this->assertSame(120, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perHour(3);\n        $this->assertSame(3600, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perHour(3, 2);\n        $this->assertSame(7200, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perDay(3);\n        $this->assertSame(86400, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = Limit::perDay(3, 5);\n        $this->assertSame(432000, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n\n        $limit = new GlobalLimit(3);\n        $this->assertSame(60, $limit->decaySeconds);\n        $this->assertSame(3, $limit->maxAttempts);\n    }\n}\n"
  },
  {
    "path": "tests/Cache/RateLimiterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cache;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionProperty;\n\nclass RateLimiterTest extends TestCase\n{\n    public static function registerNamedRateLimiterDataProvider(): array\n    {\n        return [\n            'uses BackedEnum' => [BackedEnumNamedRateLimiter::API, 'api'],\n            'uses UnitEnum' => [UnitEnumNamedRateLimiter::THIRD_PARTY, 'THIRD_PARTY'],\n            'uses normal string' => ['yolo', 'yolo'],\n            'uses int' => [100, '100'],\n        ];\n    }\n\n    #[DataProvider('registerNamedRateLimiterDataProvider')]\n    public function testRegisterNamedRateLimiter(mixed $name, string $expected): void\n    {\n        $reflectedLimitersProperty = new ReflectionProperty(RateLimiter::class, 'limiters');\n\n        $rateLimiter = new RateLimiter($this->createMock(Cache::class));\n        $rateLimiter->for($name, fn () => Limit::perMinute(100));\n\n        $limiters = $reflectedLimitersProperty->getValue($rateLimiter);\n\n        $this->assertArrayHasKey($expected, $limiters);\n\n        $limiterClosure = $rateLimiter->limiter($name);\n\n        $this->assertNotNull($limiterClosure);\n    }\n\n    public function testShouldUseOriginKeyAsPrefixWhenMultipleLimiterWithSameKey()\n    {\n        $rateLimiter = new RateLimiter(new Repository(new ArrayStore));\n\n        $rateLimiter->for('user_limiter', fn (string $userId) => [\n            Limit::perSecond(3)->by($userId),\n            Limit::perMinute(5)->by($userId),\n        ]);\n\n        $userId1 = '123';\n        $userId2 = '456';\n\n        $limiterForUser1 = $rateLimiter->limiter('user_limiter')($userId1);\n        $limiterForUser2 = $rateLimiter->limiter('user_limiter')($userId2);\n\n        for ($i = 0; $i < 3; $i++) {\n            $this->assertFalse($rateLimiter->tooManyAttempts($limiterForUser1[0]->key, $limiterForUser1[0]->maxAttempts));\n            $this->assertFalse($rateLimiter->tooManyAttempts($limiterForUser2[0]->key, $limiterForUser2[0]->maxAttempts));\n\n            $rateLimiter->hit($limiterForUser1[0]->key, $limiterForUser1[0]->decaySeconds);\n            $rateLimiter->hit($limiterForUser2[0]->key, $limiterForUser2[0]->decaySeconds);\n        }\n\n        $this->assertNotSame($limiterForUser1[0]->key, $limiterForUser2[0]->key);\n        $this->assertNotSame($limiterForUser1[1]->key, $limiterForUser2[1]->key);\n    }\n}\n\nenum BackedEnumNamedRateLimiter: string\n{\n    case API = 'api';\n}\n\nenum UnitEnumNamedRateLimiter\n{\n    case THIRD_PARTY;\n}\n"
  },
  {
    "path": "tests/Conditionable/ConditionableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Conditionable;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\HigherOrderWhenProxy;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConditionableTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n    }\n\n    public function testWhen(): void\n    {\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->when(true));\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->when(false));\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->when());\n        $this->assertInstanceOf(Builder::class, TestConditionableModel::query()->when(false, null));\n        $this->assertInstanceOf(Builder::class, TestConditionableModel::query()->when(true, function () {\n        }));\n    }\n\n    public function testUnless(): void\n    {\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->unless(true));\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->unless(false));\n        $this->assertInstanceOf(HigherOrderWhenProxy::class, TestConditionableModel::query()->unless());\n        $this->assertInstanceOf(Builder::class, TestConditionableModel::query()->unless(true, null));\n        $this->assertInstanceOf(Builder::class, TestConditionableModel::query()->unless(false, function () {\n        }));\n    }\n}\n\nclass TestConditionableModel extends Model\n{\n}\n"
  },
  {
    "path": "tests/Config/RepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Config;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Support\\Collection;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RepositoryTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Config\\Repository\n     */\n    protected $repository;\n\n    /**\n     * @var array\n     */\n    protected $config;\n\n    protected function setUp(): void\n    {\n        $this->repository = new Repository($this->config = [\n            'foo' => 'bar',\n            'bar' => 'baz',\n            'baz' => 'bat',\n            'null' => null,\n            'boolean' => true,\n            'integer' => 1,\n            'float' => 1.1,\n            'associate' => [\n                'x' => 'xxx',\n                'y' => 'yyy',\n            ],\n            'array' => [\n                'aaa',\n                'zzz',\n            ],\n            'x' => [\n                'z' => 'zoo',\n            ],\n            'a.b' => 'c',\n            'a' => [\n                'b.c' => 'd',\n            ],\n        ]);\n\n        parent::setUp();\n    }\n\n    public function testGetValueWhenKeyContainDot()\n    {\n        $this->assertSame(\n            $this->repository->get('a.b'), 'c'\n        );\n        $this->assertNull(\n            $this->repository->get('a.b.c')\n        );\n\n        $this->assertNull($this->repository->get('x.y.z'));\n        $this->assertNull($this->repository->get('.'));\n    }\n\n    public function testGetBooleanValue()\n    {\n        $this->assertTrue(\n            $this->repository->get('boolean')\n        );\n    }\n\n    public function testGetNullValue()\n    {\n        $this->assertNull(\n            $this->repository->get('null')\n        );\n    }\n\n    public function testConstruct()\n    {\n        $this->assertInstanceOf(Repository::class, $this->repository);\n    }\n\n    public function testHasIsTrue()\n    {\n        $this->assertTrue($this->repository->has('foo'));\n    }\n\n    public function testHasIsFalse()\n    {\n        $this->assertFalse($this->repository->has('not-exist'));\n    }\n\n    public function testGet()\n    {\n        $this->assertSame('bar', $this->repository->get('foo'));\n    }\n\n    public function testGetWithArrayOfKeys()\n    {\n        $this->assertSame([\n            'foo' => 'bar',\n            'bar' => 'baz',\n            'none' => null,\n        ], $this->repository->get([\n            'foo',\n            'bar',\n            'none',\n        ]));\n\n        $this->assertSame([\n            'x.y' => 'default',\n            'x.z' => 'zoo',\n            'bar' => 'baz',\n            'baz' => 'bat',\n        ], $this->repository->get([\n            'x.y' => 'default',\n            'x.z' => 'default',\n            'bar' => 'default',\n            'baz',\n        ]));\n    }\n\n    public function testGetMany()\n    {\n        $this->assertSame([\n            'foo' => 'bar',\n            'bar' => 'baz',\n            'none' => null,\n        ], $this->repository->getMany([\n            'foo',\n            'bar',\n            'none',\n        ]));\n\n        $this->assertSame([\n            'x.y' => 'default',\n            'x.z' => 'zoo',\n            'bar' => 'baz',\n            'baz' => 'bat',\n        ], $this->repository->getMany([\n            'x.y' => 'default',\n            'x.z' => 'default',\n            'bar' => 'default',\n            'baz',\n        ]));\n    }\n\n    public function testGetWithDefault()\n    {\n        $this->assertSame('default', $this->repository->get('not-exist', 'default'));\n    }\n\n    public function testSet()\n    {\n        $this->repository->set('key', 'value');\n        $this->assertSame('value', $this->repository->get('key'));\n    }\n\n    public function testSetArray()\n    {\n        $this->repository->set([\n            'key1' => 'value1',\n            'key2' => 'value2',\n            'key3',\n            'key4' => [\n                'foo' => 'bar',\n                'bar' => [\n                    'foo' => 'bar',\n                ],\n            ],\n        ]);\n        $this->assertSame('value1', $this->repository->get('key1'));\n        $this->assertSame('value2', $this->repository->get('key2'));\n        $this->assertNull($this->repository->get('key3'));\n        $this->assertSame('bar', $this->repository->get('key4.foo'));\n        $this->assertSame('bar', $this->repository->get('key4.bar.foo'));\n        $this->assertNull($this->repository->get('key5'));\n    }\n\n    public function testPrepend()\n    {\n        $this->assertSame('aaa', $this->repository->get('array.0'));\n        $this->assertSame('zzz', $this->repository->get('array.1'));\n\n        $this->repository->prepend('array', 'xxx');\n        $this->assertSame('xxx', $this->repository->get('array.0'));\n        $this->assertSame('aaa', $this->repository->get('array.1'));\n        $this->assertSame('zzz', $this->repository->get('array.2'));\n        $this->assertNull($this->repository->get('array.3'));\n        $this->assertCount(3, $this->repository->get('array'));\n    }\n\n    public function testPush()\n    {\n        $this->assertSame('aaa', $this->repository->get('array.0'));\n        $this->assertSame('zzz', $this->repository->get('array.1'));\n        $this->repository->push('array', 'xxx');\n        $this->assertSame('aaa', $this->repository->get('array.0'));\n        $this->assertSame('zzz', $this->repository->get('array.1'));\n        $this->assertSame('xxx', $this->repository->get('array.2'));\n\n        $this->assertCount(3, $this->repository->get('array'));\n    }\n\n    public function testPrependWithNewKey()\n    {\n        $this->repository->prepend('new_key', 'xxx');\n        $this->assertSame(['xxx'], $this->repository->get('new_key'));\n    }\n\n    public function testPushWithNewKey()\n    {\n        $this->repository->push('new_key', 'xxx');\n        $this->assertSame(['xxx'], $this->repository->get('new_key'));\n    }\n\n    public function testAll()\n    {\n        $this->assertSame($this->config, $this->repository->all());\n    }\n\n    public function testOffsetExists()\n    {\n        $data = [\n            'foo' => 'bar',\n            'null_value' => null,\n            'empty_string' => '',\n            'numeric_value' => 123,\n        ];\n        $this->repository->set($data);\n\n        $this->assertTrue(isset($this->repository['foo']));\n        $this->assertFalse(isset($this->repository['not-exist']));\n        $this->assertTrue(isset($this->repository['null_value']));\n        $this->assertTrue(isset($this->repository['empty_string']));\n        $this->assertTrue(isset($this->repository['numeric_value']));\n        $this->assertFalse(isset($this->repository[-1]));\n        $this->assertFalse(isset($this->repository['non_numeric']));\n    }\n\n    public function testOffsetGet()\n    {\n        $this->assertNull($this->repository['not-exist']);\n        $this->assertSame('bar', $this->repository['foo']);\n        $this->assertSame([\n            'x' => 'xxx',\n            'y' => 'yyy',\n        ], $this->repository['associate']);\n    }\n\n    public function testOffsetSet()\n    {\n        $this->assertNull($this->repository['key']);\n\n        $this->repository['key'] = 'value';\n\n        $this->assertSame('value', $this->repository['key']);\n\n        $this->repository['key'] = 'new_value';\n        $this->assertSame('new_value', $this->repository['key']);\n\n        $this->repository['new_key'] = null;\n        $this->assertNull($this->repository['new_key']);\n\n        $this->repository[''] = 'value';\n        $this->assertSame('value', $this->repository['']);\n\n        $this->repository[123] = '123';\n        $this->assertSame('123', $this->repository[123]);\n    }\n\n    public function testOffsetUnset()\n    {\n        $this->assertArrayHasKey('associate', $this->repository->all());\n        $this->assertSame($this->config['associate'], $this->repository->get('associate'));\n\n        unset($this->repository['associate']);\n\n        $this->assertArrayHasKey('associate', $this->repository->all());\n        $this->assertNull($this->repository->get('associate'));\n    }\n\n    public function testItIsMacroable()\n    {\n        $this->repository->macro('foo', function () {\n            return 'macroable';\n        });\n\n        $this->assertSame('macroable', $this->repository->foo());\n    }\n\n    public function testItGetsAsString(): void\n    {\n        $this->assertSame(\n            'c', $this->repository->string('a.b')\n        );\n    }\n\n    public function testItThrowsAnExceptionWhenTryingToGetNonStringValueAsString(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Configuration value for key \\[a\\] must be a string, (.*) given.#');\n\n        $this->repository->string('a');\n    }\n\n    public function testItGetsAsArray(): void\n    {\n        $this->assertSame(\n            $this->repository->array('array'), ['aaa', 'zzz']\n        );\n    }\n\n    public function testItThrowsAnExceptionWhenTryingToGetNonArrayValueAsArray(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#Configuration value for key \\[a.b\\] must be an array, (.*) given.#');\n\n        $this->repository->array('a.b');\n    }\n\n    public function testItGetsAsCollection(): void\n    {\n        $collection = $this->repository->collection('array');\n\n        $this->assertInstanceOf(Collection::class, $collection);\n        $this->assertSame(['aaa', 'zzz'], $collection->toArray());\n    }\n\n    public function testItGetsAsBoolean(): void\n    {\n        $this->assertTrue(\n            $this->repository->boolean('boolean')\n        );\n    }\n\n    public function testItThrowsAnExceptionWhenTryingToGetNonBooleanValueAsBoolean(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#Configuration value for key \\[a.b\\] must be a boolean, (.*) given.#');\n\n        $this->repository->boolean('a.b');\n    }\n\n    public function testItGetsAsInteger(): void\n    {\n        $this->assertSame(\n            $this->repository->integer('integer'), 1\n        );\n    }\n\n    public function testItThrowsAnExceptionWhenTryingToGetNonIntegerValueAsInteger(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#Configuration value for key \\[a.b\\] must be an integer, (.*) given.#');\n\n        $this->repository->integer('a.b');\n    }\n\n    public function testItGetsAsFloat(): void\n    {\n        $this->assertSame(\n            $this->repository->float('float'), 1.1\n        );\n    }\n\n    public function testItThrowsAnExceptionWhenTryingToGetNonFloatValueAsFloat(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Configuration value for key \\[a.b\\] must be a float, (.*) given.#');\n\n        $this->repository->float('a.b');\n    }\n}\n"
  },
  {
    "path": "tests/Console/CacheCommandMutexTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\CacheCommandMutex;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Cache\\LockProvider;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Mockery as m;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheCommandMutexTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Console\\CacheCommandMutex\n     */\n    protected $mutex;\n\n    /**\n     * @var \\Illuminate\\Console\\Command\n     */\n    protected $command;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    protected $cacheFactory;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cacheRepository;\n\n    protected function setUp(): void\n    {\n        $this->cacheFactory = m::mock(Factory::class);\n        $this->cacheRepository = m::mock(Repository::class);\n        $this->mutex = new CacheCommandMutex($this->cacheFactory);\n        $this->command = new class extends Command\n        {\n            protected $name = 'command-name';\n        };\n    }\n\n    public function testCanCreateMutex()\n    {\n        $this->mockUsingCacheStore();\n        $this->cacheRepository->shouldReceive('add')\n            ->andReturn(true)\n            ->once();\n        $actual = $this->mutex->create($this->command);\n\n        $this->assertTrue($actual);\n    }\n\n    public function testCannotCreateMutexIfAlreadyExist()\n    {\n        $this->mockUsingCacheStore();\n        $this->cacheRepository->shouldReceive('add')\n            ->andReturn(false)\n            ->once();\n        $actual = $this->mutex->create($this->command);\n\n        $this->assertFalse($actual);\n    }\n\n    public function testCanCreateMutexWithCustomConnection()\n    {\n        $this->mockUsingCacheStore();\n        $this->cacheRepository->shouldReceive('getStore')\n            ->with('test')\n            ->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('add')\n            ->andReturn(false)\n            ->once();\n        $this->mutex->useStore('test');\n\n        $this->mutex->create($this->command);\n    }\n\n    public function testCanCreateMutexWithLockProvider()\n    {\n        $lock = $this->mockUsingLockProvider();\n        $this->acquireLockExpectations($lock, true);\n\n        $actual = $this->mutex->create($this->command);\n\n        $this->assertTrue($actual);\n    }\n\n    public function testCanCreateMutexWithCustomLockProviderConnection()\n    {\n        $this->mockUsingCacheStore();\n        $this->cacheRepository->shouldReceive('getStore')\n            ->with('test')\n            ->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('add')\n            ->andReturn(false)\n            ->once();\n        $this->mutex->useStore('test');\n\n        $this->mutex->create($this->command);\n    }\n\n    public function testCannotCreateMutexIfAlreadyExistWithLockProvider()\n    {\n        $lock = $this->mockUsingLockProvider();\n        $this->acquireLockExpectations($lock, false);\n        $actual = $this->mutex->create($this->command);\n\n        $this->assertFalse($actual);\n    }\n\n    public function testCanCreateMutexWithCustomConnectionWithLockProvider()\n    {\n        $lock = m::mock(LockProvider::class);\n        $this->cacheFactory->expects('store')->once()->with('test')->andReturn($this->cacheRepository);\n        $this->cacheRepository->expects('getStore')->twice()->andReturn($lock);\n\n        $this->acquireLockExpectations($lock, true);\n        $this->mutex->useStore('test');\n\n        $this->mutex->create($this->command);\n    }\n\n    /**\n     * @return void\n     */\n    private function mockUsingCacheStore(): void\n    {\n        $this->cacheFactory->expects('store')->once()->andReturn($this->cacheRepository);\n        $this->cacheRepository->expects('getStore')->andReturn(null);\n    }\n\n    private function mockUsingLockProvider(): m\\MockInterface\n    {\n        $lock = m::mock(LockProvider::class);\n        $this->cacheFactory->expects('store')->once()->andReturn($this->cacheRepository);\n        $this->cacheRepository->expects('getStore')->twice()->andReturn($lock);\n\n        return $lock;\n    }\n\n    private function acquireLockExpectations(MockInterface $lock, bool $acquiresSuccessfully): void\n    {\n        $lock->expects('lock')\n            ->once()\n            ->with(m::type('string'), m::type('int'))\n            ->andReturns($lock);\n\n        $lock->expects('get')\n            ->once()\n            ->andReturns($acquiresSuccessfully);\n    }\n\n    public function testCommandMutexNameWithoutIsolatedMutexNameMethod()\n    {\n        $this->mockUsingCacheStore();\n\n        $this->cacheRepository->shouldReceive('getStore')\n            ->with('test')\n            ->andReturn($this->cacheRepository);\n\n        $this->cacheRepository->shouldReceive('add')\n            ->once()\n            ->withArgs(function ($key) {\n                $this->assertEquals('framework'.DIRECTORY_SEPARATOR.'command-command-name', $key);\n\n                return true;\n            })\n            ->andReturn(true);\n\n        $this->mutex->create($this->command);\n    }\n\n    public function testCommandMutexNameWithIsolatedMutexNameMethod()\n    {\n        $command = new class extends Command\n        {\n            protected $name = 'command-name';\n\n            public function isolatableId()\n            {\n                return 'isolated';\n            }\n        };\n\n        $this->mockUsingCacheStore();\n\n        $this->cacheRepository->shouldReceive('getStore')\n            ->with('test')\n            ->andReturn($this->cacheRepository);\n\n        $this->cacheRepository->shouldReceive('add')\n            ->once()\n            ->withArgs(function ($key) {\n                $this->assertEquals('framework'.DIRECTORY_SEPARATOR.'command-command-name-isolated', $key);\n\n                return true;\n            })\n            ->andReturn(true);\n\n        $this->mutex->create($command);\n    }\n}\n"
  },
  {
    "path": "tests/Console/CommandMutexTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\CommandMutex;\nuse Illuminate\\Contracts\\Console\\Isolatable;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithMockery;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass CommandMutexTest extends TestCase\n{\n    use InteractsWithMockery;\n\n    /**\n     * @var Command\n     */\n    protected $command;\n\n    /**\n     * @var CommandMutex\n     */\n    protected $commandMutex;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $this->command = new class extends Command implements Isolatable\n        {\n            public $ran = 0;\n\n            public function __invoke()\n            {\n                $this->ran++;\n            }\n        };\n\n        $this->commandMutex = m::mock(CommandMutex::class);\n\n        $app = new Application;\n        $app->instance(CommandMutex::class, $this->commandMutex);\n        $this->command->setLaravel($app);\n    }\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        $this->tearDownTheTestEnvironmentUsingMockery();\n    }\n\n    public function testCanRunIsolatedCommandIfNotBlocked()\n    {\n        $this->commandMutex->shouldReceive('create')\n            ->andReturn(true)\n            ->once();\n        $this->commandMutex->shouldReceive('forget')\n            ->andReturn(true)\n            ->once();\n\n        $this->runCommand();\n\n        $this->assertEquals(1, $this->command->ran);\n    }\n\n    public function testCannotRunIsolatedCommandIfBlocked()\n    {\n        $this->commandMutex->shouldReceive('create')\n            ->andReturn(false)\n            ->once();\n\n        $this->runCommand();\n\n        $this->assertEquals(0, $this->command->ran);\n    }\n\n    public function testCanRunCommandAgainAfterOtherCommandFinished()\n    {\n        $this->commandMutex->shouldReceive('create')\n            ->andReturn(true)\n            ->twice();\n        $this->commandMutex->shouldReceive('forget')\n            ->andReturn(true)\n            ->twice();\n\n        $this->runCommand();\n        $this->runCommand();\n\n        $this->assertEquals(2, $this->command->ran);\n    }\n\n    public function testCanRunCommandAgainNonAutomated()\n    {\n        $this->commandMutex->shouldNotHaveBeenCalled();\n\n        $this->runCommand(false);\n\n        $this->assertEquals(1, $this->command->ran);\n    }\n\n    protected function runCommand($withIsolated = true)\n    {\n        $input = new ArrayInput(['--isolated' => $withIsolated]);\n        $output = new NullOutput;\n        $this->command->run($input, $output);\n    }\n}\n"
  },
  {
    "path": "tests/Console/CommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Attributes\\Help;\nuse Illuminate\\Console\\Attributes\\Hidden;\nuse Illuminate\\Console\\Attributes\\Signature;\nuse Illuminate\\Console\\Attributes\\Usage;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\View\\Components\\Factory;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\n\nclass CommandTest extends TestCase\n{\n    public function testCallingClassCommandResolveCommandViaApplicationResolution()\n    {\n        $command = new class extends Command\n        {\n            public function handle()\n            {\n            }\n        };\n\n        $application = m::mock(Application::class);\n        $command->setLaravel($application);\n\n        $input = new ArrayInput([]);\n        $output = new NullOutput;\n        $outputStyle = m::mock(OutputStyle::class);\n        $application->shouldReceive('make')->with(OutputStyle::class, ['input' => $input, 'output' => $output])->andReturn($outputStyle);\n        $application->shouldReceive('make')->with(Factory::class, ['output' => $outputStyle])->andReturn(m::mock(Factory::class));\n\n        $application->shouldReceive('call')->with([$command, 'handle'])->andReturnUsing(function () use ($command, $application) {\n            $commandCalled = m::mock(Command::class);\n\n            $application->shouldReceive('make')->once()->with(Command::class)->andReturn($commandCalled);\n\n            $commandCalled->shouldReceive('setApplication')->once()->with(null);\n            $commandCalled->shouldReceive('setLaravel')->once()->with($application);\n            $commandCalled->shouldReceive('run')->once();\n\n            $command->call(Command::class);\n        });\n        $application->shouldReceive('runningUnitTests')->andReturn(true);\n\n        $command->run($input, $output);\n    }\n\n    public function testGettingCommandArgumentsAndOptionsByClass()\n    {\n        $command = new class extends Command\n        {\n            public function handle()\n            {\n            }\n\n            protected function getArguments()\n            {\n                return [\n                    new InputArgument('argument-one', InputArgument::REQUIRED, 'first test argument'),\n                    ['argument-two', InputArgument::OPTIONAL, 'a second test argument'],\n                    [\n                        'name' => 'argument-three',\n                        'description' => 'a third test argument',\n                        'mode' => InputArgument::OPTIONAL,\n                        'default' => 'third-argument-default',\n                    ],\n                ];\n            }\n\n            protected function getOptions()\n            {\n                return [\n                    new InputOption('option-one', 'o', InputOption::VALUE_OPTIONAL, 'first test option'),\n                    ['option-two', 't', InputOption::VALUE_REQUIRED, 'second test option'],\n                    [\n                        'name' => 'option-three',\n                        'description' => 'a third test option',\n                        'mode' => InputOption::VALUE_OPTIONAL,\n                        'default' => 'third-option-default',\n                    ],\n                ];\n            }\n        };\n\n        $application = app();\n        $command->setLaravel($application);\n\n        $input = new ArrayInput([\n            'argument-one' => 'test-first-argument',\n            'argument-two' => 'test-second-argument',\n            '--option-one' => 'test-first-option',\n            '--option-two' => 'test-second-option',\n        ]);\n        $output = new NullOutput;\n\n        $command->run($input, $output);\n\n        $this->assertSame('test-first-argument', $command->argument('argument-one'));\n        $this->assertSame('test-second-argument', $command->argument('argument-two'));\n        $this->assertSame('third-argument-default', $command->argument('argument-three'));\n        $this->assertSame('test-first-option', $command->option('option-one'));\n        $this->assertSame('test-second-option', $command->option('option-two'));\n        $this->assertSame('third-option-default', $command->option('option-three'));\n    }\n\n    public function testTheInputSetterOverwrite()\n    {\n        $input = m::mock(InputInterface::class);\n        $input->shouldReceive('hasArgument')->once()->with('foo')->andReturn(false);\n\n        $command = new Command;\n        $command->setInput($input);\n\n        $this->assertFalse($command->hasArgument('foo'));\n    }\n\n    public function testTheOutputSetterOverwrite()\n    {\n        $output = m::mock(OutputStyle::class);\n        $output->shouldReceive('writeln')->once()->withArgs(function (...$args) {\n            return $args[0] === '<info>foo</info>';\n        });\n\n        $command = new Command;\n        $command->setOutput($output);\n\n        $command->info('foo');\n    }\n\n    public function testSetHidden()\n    {\n        $command = new class extends Command\n        {\n            public function parentIsHidden()\n            {\n                return parent::isHidden();\n            }\n        };\n\n        $this->assertFalse($command->isHidden());\n        $this->assertFalse($command->parentIsHidden());\n\n        $command->setHidden(true);\n\n        $this->assertTrue($command->isHidden());\n        $this->assertTrue($command->parentIsHidden());\n    }\n\n    public function testHiddenProperty()\n    {\n        $command = new class extends Command\n        {\n            protected $hidden = true;\n\n            public function parentIsHidden()\n            {\n                return parent::isHidden();\n            }\n        };\n\n        $this->assertTrue($command->isHidden());\n        $this->assertTrue($command->parentIsHidden());\n\n        $command->setHidden(false);\n\n        $this->assertFalse($command->isHidden());\n        $this->assertFalse($command->parentIsHidden());\n    }\n\n    public function testAliasesProperty()\n    {\n        $command = new class extends Command\n        {\n            protected $name = 'foo:bar';\n\n            protected $aliases = ['bar:baz', 'baz:qux'];\n        };\n\n        $this->assertSame(['bar:baz', 'baz:qux'], $command->getAliases());\n    }\n\n    public function testChoiceIsSingleSelectByDefault()\n    {\n        $output = m::mock(OutputStyle::class);\n        $output->shouldReceive('askQuestion')->once()->withArgs(function (ChoiceQuestion $question) {\n            return $question->isMultiselect() === false;\n        });\n\n        $command = new Command;\n        $command->setOutput($output);\n\n        $command->choice('Do you need further help?', ['yes', 'no']);\n    }\n\n    public function testChoiceWithMultiselect()\n    {\n        $output = m::mock(OutputStyle::class);\n        $output->shouldReceive('askQuestion')->once()->withArgs(function (ChoiceQuestion $question) {\n            return $question->isMultiselect() === true;\n        });\n\n        $command = new Command;\n        $command->setOutput($output);\n\n        $command->choice('Select all that apply.', ['option-1', 'option-2', 'option-3'], null, null, true);\n    }\n\n    public function testSignatureAttributeCanSetAliases()\n    {\n        $command = new SignatureWithAliasesCommand;\n\n        $this->assertSame('foo:bar', $command->getName());\n        $this->assertSame(['bar:baz', 'baz:qux'], $command->getAliases());\n    }\n\n    public function testHiddenAttributeHidesCommand()\n    {\n        $command = new HiddenCommand;\n\n        $this->assertTrue($command->isHidden());\n    }\n\n    public function testHelpAttributeCanSetHelp()\n    {\n        $command = new HelpCommand;\n\n        $this->assertSame('Extended help text.', $command->getHelp());\n    }\n\n    public function testUsageAttributeCanSetUsages()\n    {\n        $command = new UsageCommand;\n\n        $this->assertSame(['foo:bar 1', 'foo:bar 1 --force'], $command->getUsages());\n    }\n}\n\n#[Signature('foo:bar', aliases: ['bar:baz', 'baz:qux'])]\nclass SignatureWithAliasesCommand extends Command\n{\n    public function handle()\n    {\n    }\n}\n\n#[Signature('foo:bar')]\n#[Hidden]\nclass HiddenCommand extends Command\n{\n    public function handle()\n    {\n    }\n}\n\n#[Signature('foo:bar')]\n#[Help('Extended help text.')]\nclass HelpCommand extends Command\n{\n    public function handle()\n    {\n    }\n}\n\n#[Signature('foo:bar {user}')]\n#[Usage('foo:bar 1')]\n#[Usage('foo:bar 1 --force')]\nclass UsageCommand extends Command\n{\n    public function handle()\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Console/CommandTrapTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Signals;\nuse Illuminate\\Tests\\Console\\Fixtures\\FakeSignalsRegistry;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CommandTrapTest extends TestCase\n{\n    protected $registry;\n\n    protected $signals;\n\n    protected $state;\n\n    protected function setUp(): void\n    {\n        Signals::resolveAvailabilityUsing(fn () => true);\n\n        $this->registry = new FakeSignalsRegistry();\n        $this->state = null;\n    }\n\n    public function testTrapWhenAvailable()\n    {\n        $command = $this->createCommand();\n\n        $command->trap('my-signal', function () {\n            $this->state = 'taylorotwell';\n        });\n\n        $this->registry->handle('my-signal');\n\n        $this->assertSame('taylorotwell', $this->state);\n    }\n\n    public function testTrapWhenNotAvailable()\n    {\n        Signals::resolveAvailabilityUsing(fn () => false);\n\n        $command = $this->createCommand();\n\n        $command->trap('my-signal', function () {\n            $this->state = 'taylorotwell';\n        });\n\n        $this->registry->handle('my-signal');\n\n        $this->assertNull($this->state);\n    }\n\n    public function testUntrap()\n    {\n        $command = $this->createCommand();\n\n        $command->trap('my-signal', function () {\n            $this->state = 'taylorotwell';\n        });\n\n        $command->untrap();\n\n        $this->registry->handle('my-signal');\n\n        $this->assertNull($this->state);\n    }\n\n    public function testNestedTraps()\n    {\n        $a = $this->createCommand();\n        $a->trap('my-signal', fn () => $this->state .= '1');\n\n        $b = $this->createCommand();\n        $b->trap('my-signal', fn () => $this->state .= '2');\n\n        $c = $this->createCommand();\n        $c->trap('my-signal', fn () => $this->state .= '3');\n\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('321', $this->state);\n\n        $c->untrap();\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('21', $this->state);\n\n        $d = $this->createCommand();\n        $d->trap('my-signal', fn () => $this->state .= '3');\n\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('321', $this->state);\n\n        $d->untrap();\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('21', $this->state);\n\n        $b->untrap();\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('1', $this->state);\n\n        $a->untrap();\n        $this->state = '';\n        $this->registry->handle('my-signal');\n        $this->assertSame('', $this->state);\n    }\n\n    protected function createCommand()\n    {\n        $command = new Command;\n        $registry = $this->registry;\n\n        (fn () => $this->signals = new Signals($registry))->call($command);\n\n        return $command;\n    }\n}\n"
  },
  {
    "path": "tests/Console/Concerns/InteractsWithIOTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Concerns;\n\nuse Generator;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Concerns\\InteractsWithIO;\nuse Illuminate\\Console\\OutputStyle;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Helper\\ProgressBar;\nuse Symfony\\Component\\Console\\Input\\ArgvInput;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nclass InteractsWithIOTest extends TestCase\n{\n    #[DataProvider('iterableDataProvider')]\n    public function testWithProgressBarIterable($iterable)\n    {\n        $command = new CommandInteractsWithIO;\n        $bufferedOutput = new BufferedOutput();\n        $output = m::mock(OutputStyle::class, [new ArgvInput(), $bufferedOutput])->makePartial();\n        $command->setOutput($output);\n\n        $output->shouldReceive('createProgressBar')\n            ->once()\n            ->with(count($iterable))\n            ->andReturnUsing(function ($steps) use ($bufferedOutput) {\n                // we can't mock ProgressBar because it's final, so return a real one\n                return new ProgressBar($bufferedOutput, $steps);\n            });\n\n        $calledTimes = 0;\n        $result = $command->withProgressBar($iterable, function ($value, $bar, $key) use (&$calledTimes, $iterable) {\n            $this->assertInstanceOf(ProgressBar::class, $bar);\n            $this->assertSame(array_values($iterable)[$calledTimes], $value);\n            $this->assertSame(array_keys($iterable)[$calledTimes], $key);\n            $calledTimes++;\n        });\n\n        $this->assertSame(count($iterable), $calledTimes);\n        $this->assertSame($iterable, $result);\n    }\n\n    public static function iterableDataProvider(): Generator\n    {\n        yield [['a', 'b', 'c']];\n\n        yield [['foo' => 'a', 'bar' => 'b', 'baz' => 'c']];\n    }\n\n    public function testWithProgressBarInteger()\n    {\n        $command = new CommandInteractsWithIO;\n        $bufferedOutput = new BufferedOutput();\n        $output = m::mock(OutputStyle::class, [new ArgvInput(), $bufferedOutput])->makePartial();\n        $command->setOutput($output);\n\n        $totalSteps = 5;\n\n        $output->shouldReceive('createProgressBar')\n            ->once()\n            ->with($totalSteps)\n            ->andReturnUsing(function ($steps) use ($bufferedOutput) {\n                // we can't mock ProgressBar because it's final, so return a real one\n                return new ProgressBar($bufferedOutput, $steps);\n            });\n\n        $called = false;\n        $command->withProgressBar($totalSteps, function ($bar) use (&$called) {\n            $this->assertInstanceOf(ProgressBar::class, $bar);\n            $called = true;\n        });\n\n        $this->assertTrue($called);\n    }\n}\n\nclass CommandInteractsWithIO extends Command\n{\n    use InteractsWithIO;\n}\n"
  },
  {
    "path": "tests/Console/ConfiguresPromptsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\View\\Components\\Factory;\nuse Laravel\\Prompts\\Prompt;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nuse function Laravel\\Prompts\\multiselect;\nuse function Laravel\\Prompts\\select;\n\nclass ConfiguresPromptsTest extends TestCase\n{\n    #[DataProvider('selectDataProvider')]\n    public function testSelectFallback($prompt, $expectedOptions, $expectedDefault, $return, $expectedReturn)\n    {\n        Prompt::fallbackWhen(true);\n\n        $command = new class($prompt) extends Command\n        {\n            public $answer;\n\n            public function __construct(protected $prompt)\n            {\n                parent::__construct();\n            }\n\n            public function handle()\n            {\n                $this->answer = ($this->prompt)();\n            }\n        };\n\n        $this->runCommand($command, fn ($components) => $components\n            ->expects('choice')\n            ->with('Test', $expectedOptions, $expectedDefault)\n            ->andReturn($return)\n        );\n\n        $this->assertSame($expectedReturn, $command->answer);\n    }\n\n    public static function selectDataProvider()\n    {\n        return [\n            'list with no default' => [fn () => select('Test', ['a', 'b', 'c']), ['a', 'b', 'c'], null, 'b', 'b'],\n            'numeric keys with no default' => [fn () => select('Test', [1 => 'a', 2 => 'b', 3 => 'c']), [1 => 'a', 2 => 'b', 3 => 'c'], null, '2', 2],\n            'assoc with no default' => [fn () => select('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C']), ['a' => 'A', 'b' => 'B', 'c' => 'C'], null, 'b', 'b'],\n            'list with default' => [fn () => select('Test', ['a', 'b', 'c'], 'b'), ['a', 'b', 'c'], 'b', 'b', 'b'],\n            'numeric keys with default' => [fn () => select('Test', [1 => 'a', 2 => 'b', 3 => 'c'], 2), [1 => 'a', 2 => 'b', 3 => 'c'], 2, '2', 2],\n            'assoc with default' => [fn () => select('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C'], 'b'), ['a' => 'A', 'b' => 'B', 'c' => 'C'], 'b', 'b', 'b'],\n        ];\n    }\n\n    #[DataProvider('multiselectDataProvider')]\n    public function testMultiselectFallback($prompt, $expectedOptions, $expectedDefault, $return, $expectedReturn)\n    {\n        Prompt::fallbackWhen(true);\n\n        $command = new class($prompt) extends Command\n        {\n            public $answer;\n\n            public function __construct(protected $prompt)\n            {\n                parent::__construct();\n            }\n\n            public function handle()\n            {\n                $this->answer = ($this->prompt)();\n            }\n        };\n\n        $this->runCommand($command, fn ($components) => $components\n            ->expects('choice')\n            ->with('Test', $expectedOptions, $expectedDefault, null, true)\n            ->andReturn($return)\n        );\n\n        $this->assertSame($expectedReturn, $command->answer);\n    }\n\n    public static function multiselectDataProvider()\n    {\n        return [\n            'list with no default' => [fn () => multiselect('Test', ['a', 'b', 'c']), ['None', 'a', 'b', 'c'], 'None', ['None'], []],\n            'numeric keys with no default' => [fn () => multiselect('Test', [1 => 'a', 2 => 'b', 3 => 'c']), ['' => 'None', 1 => 'a', 2 => 'b', 3 => 'c'], 'None', [''], []],\n            'assoc with no default' => [fn () => multiselect('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C']), ['' => 'None', 'a' => 'A', 'b' => 'B', 'c' => 'C'], 'None', [''], []],\n            'list with default' => [fn () => multiselect('Test', ['a', 'b', 'c'], ['b', 'c']), ['None', 'a', 'b', 'c'], 'b,c', ['b', 'c'], ['b', 'c']],\n            'numeric keys with default' => [fn () => multiselect('Test', [1 => 'a', 2 => 'b', 3 => 'c'], [2, 3]), ['' => 'None', 1 => 'a', 2 => 'b', 3 => 'c'], '2,3', ['2', '3'], [2, 3]],\n            'assoc with default' => [fn () => multiselect('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C'], ['b', 'c']), ['' => 'None', 'a' => 'A', 'b' => 'B', 'c' => 'C'], 'b,c', ['b', 'c'], ['b', 'c']],\n            'required list with no default' => [fn () => multiselect('Test', ['a', 'b', 'c'], required: true), ['a', 'b', 'c'], null, ['b', 'c'], ['b', 'c']],\n            'required numeric keys with no default' => [fn () => multiselect('Test', [1 => 'a', 2 => 'b', 3 => 'c'], required: true), [1 => 'a', 2 => 'b', 3 => 'c'], null, ['2', '3'], [2, 3]],\n            'required assoc with no default' => [fn () => multiselect('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C'], required: true), ['a' => 'A', 'b' => 'B', 'c' => 'C'], null, ['b', 'c'], ['b', 'c']],\n            'required list with default' => [fn () => multiselect('Test', ['a', 'b', 'c'], ['b', 'c'], required: true), ['a', 'b', 'c'], 'b,c', ['b', 'c'], ['b', 'c']],\n            'required numeric keys with default' => [fn () => multiselect('Test', [1 => 'a', 2 => 'b', 3 => 'c'], [2, 3], required: true), [1 => 'a', 2 => 'b', 3 => 'c'], '2,3', ['2', '3'], [2, 3]],\n            'required assoc with default' => [fn () => multiselect('Test', ['a' => 'A', 'b' => 'B', 'c' => 'C'], ['b', 'c'], required: true), ['a' => 'A', 'b' => 'B', 'c' => 'C'], 'b,c', ['b', 'c'], ['b', 'c']],\n        ];\n    }\n\n    protected function runCommand($command, $expectations)\n    {\n        $command->setLaravel($application = m::mock(Application::class));\n\n        $application->shouldReceive('make')->withArgs(fn ($abstract) => $abstract === OutputStyle::class)->andReturn($outputStyle = m::mock(OutputStyle::class));\n        $application->shouldReceive('make')->withArgs(fn ($abstract) => $abstract === Factory::class)->andReturn($factory = m::mock(Factory::class));\n        $application->shouldReceive('runningUnitTests')->andReturn(false);\n        $application->shouldReceive('call')->with([$command, 'handle'])->andReturnUsing(fn ($callback) => call_user_func($callback));\n        $outputStyle->shouldReceive('newLinesWritten')->andReturn(1);\n\n        $expectations($factory);\n\n        $command->run(new ArrayInput([]), new NullOutput);\n    }\n}\n"
  },
  {
    "path": "tests/Console/ConsoleApplicationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Composer\\Autoload\\ClassLoader;\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Foundation\\Application as ApplicationContract;\nuse Illuminate\\Events\\Dispatcher as EventsDispatcher;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Application as FoundationApplication;\nuse Illuminate\\Foundation\\Console\\Kernel;\nuse Illuminate\\Tests\\Console\\Fixtures\\FakeCommandWithArrayInputPrompting;\nuse Illuminate\\Tests\\Console\\Fixtures\\FakeCommandWithInputPrompting;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithMockery;\nuse Orchestra\\Testbench\\Foundation\\Application as Testbench;\nuse PHPUnit\\Framework\\Attributes\\RunInSeparateProcess;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Command\\Command as SymfonyCommand;\nuse Symfony\\Component\\Console\\Exception\\CommandNotFoundException;\nuse Throwable;\n\nuse function Illuminate\\Filesystem\\join_paths;\nuse function Orchestra\\Testbench\\default_skeleton_path;\n\nclass ConsoleApplicationTest extends TestCase\n{\n    use InteractsWithMockery;\n\n    protected function tearDown(): void\n    {\n        $this->tearDownTheTestEnvironmentUsingMockery();\n\n        parent::tearDown();\n    }\n\n    public function testAddSetsLaravelInstance()\n    {\n        $artisan = $this->getMockConsole(['addToParent']);\n        $command = m::mock(Command::class);\n        $command->shouldReceive('setLaravel')->once()->with(m::type(ApplicationContract::class));\n        $artisan->expects($this->once())->method('addToParent')->with($this->equalTo($command))->willReturn($command);\n        $result = $artisan->add($command);\n\n        $this->assertSame($command, $result);\n    }\n\n    public function testLaravelNotSetOnSymfonyCommands()\n    {\n        $artisan = $this->getMockConsole(['addToParent']);\n        $command = m::mock(SymfonyCommand::class);\n        $command->shouldReceive('setLaravel')->never();\n        $artisan->expects($this->once())->method('addToParent')->with($this->equalTo($command))->willReturn($command);\n        $result = $artisan->add($command);\n\n        $this->assertSame($command, $result);\n    }\n\n    public function testResolveAddsCommandViaApplicationResolution()\n    {\n        $artisan = $this->getMockConsole(['addToParent']);\n        $command = m::mock(SymfonyCommand::class);\n        $artisan->getLaravel()->shouldReceive('make')->once()->with('foo')->andReturn(m::mock(SymfonyCommand::class));\n        $artisan->expects($this->once())->method('addToParent')->with($this->equalTo($command))->willReturn($command);\n        $result = $artisan->resolve('foo');\n\n        $this->assertSame($command, $result);\n    }\n\n    public function testResolvingCommandsWithAliasViaAttribute()\n    {\n        $container = new FoundationApplication();\n        $artisan = new Application($container, new EventsDispatcher($container), $container->version());\n        $artisan->resolve(CommandWithAliasViaAttribute::class);\n        $artisan->setContainerCommandLoader();\n\n        $this->assertInstanceOf(CommandWithAliasViaAttribute::class, $artisan->get('command-name'));\n        $this->assertInstanceOf(CommandWithAliasViaAttribute::class, $artisan->get('command-alias'));\n        $this->assertArrayHasKey('command-name', $artisan->all());\n        $this->assertArrayHasKey('command-alias', $artisan->all());\n    }\n\n    public function testResolvingCommandsWithAliasViaProperty()\n    {\n        $container = new FoundationApplication();\n        $artisan = new Application($container, new EventsDispatcher($container), $container->version());\n        $artisan->resolve(CommandWithAliasViaProperty::class);\n        $artisan->setContainerCommandLoader();\n\n        $this->assertInstanceOf(CommandWithAliasViaProperty::class, $artisan->get('command-name'));\n        $this->assertInstanceOf(CommandWithAliasViaProperty::class, $artisan->get('command-alias'));\n        $this->assertArrayHasKey('command-name', $artisan->all());\n        $this->assertArrayHasKey('command-alias', $artisan->all());\n    }\n\n    public function testResolvingCommandsWithNoAliasViaAttribute()\n    {\n        $container = new FoundationApplication();\n        $artisan = new Application($container, new EventsDispatcher($container), $container->version());\n        $artisan->resolve(CommandWithNoAliasViaAttribute::class);\n        $artisan->setContainerCommandLoader();\n\n        $this->assertInstanceOf(CommandWithNoAliasViaAttribute::class, $artisan->get('command-name'));\n        try {\n            $artisan->get('command-alias');\n            $this->fail();\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(CommandNotFoundException::class, $e);\n        }\n        $this->assertArrayHasKey('command-name', $artisan->all());\n        $this->assertArrayNotHasKey('command-alias', $artisan->all());\n    }\n\n    public function testResolvingCommandsWithNoAliasViaProperty()\n    {\n        $container = new FoundationApplication();\n        $artisan = new Application($container, new EventsDispatcher($container), $container->version());\n        $artisan->resolve(CommandWithNoAliasViaProperty::class);\n        $artisan->setContainerCommandLoader();\n\n        $this->assertInstanceOf(CommandWithNoAliasViaProperty::class, $artisan->get('command-name'));\n        try {\n            $artisan->get('command-alias');\n            $this->fail();\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(CommandNotFoundException::class, $e);\n        }\n        $this->assertArrayHasKey('command-name', $artisan->all());\n        $this->assertArrayNotHasKey('command-alias', $artisan->all());\n    }\n\n    public function testCallFullyStringCommandLine()\n    {\n        $artisan = new Application(\n            m::mock(ApplicationContract::class, ['version' => '6.0']),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $codeOfCallingArrayInput = $artisan->call('help', [\n            '--raw' => true,\n            '--format' => 'txt',\n            '--no-interaction' => true,\n            '--env' => 'testing',\n        ]);\n\n        $outputOfCallingArrayInput = $artisan->output();\n\n        $codeOfCallingStringInput = $artisan->call(\n            'help --raw --format=txt --no-interaction --env=testing'\n        );\n\n        $outputOfCallingStringInput = $artisan->output();\n\n        $this->assertSame($codeOfCallingArrayInput, $codeOfCallingStringInput);\n        $this->assertSame($outputOfCallingArrayInput, $outputOfCallingStringInput);\n    }\n\n    public function testCommandInputPromptsWhenRequiredArgumentIsMissing()\n    {\n        $artisan = new Application(\n            $laravel = new FoundationApplication(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $artisan->addCommands([$command = new FakeCommandWithInputPrompting()]);\n\n        $command->setLaravel($laravel);\n\n        $exitCode = $artisan->call('fake-command-for-testing');\n\n        $this->assertTrue($command->prompted);\n        $this->assertSame('foo', $command->argument('name'));\n        $this->assertSame(0, $exitCode);\n    }\n\n    public function testCommandInputDoesntPromptWhenRequiredArgumentIsPassed()\n    {\n        $artisan = new Application(\n            new FoundationApplication(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $artisan->addCommands([$command = new FakeCommandWithInputPrompting()]);\n\n        $exitCode = $artisan->call('fake-command-for-testing', [\n            'name' => 'foo',\n        ]);\n\n        $this->assertFalse($command->prompted);\n        $this->assertSame('foo', $command->argument('name'));\n        $this->assertSame(0, $exitCode);\n    }\n\n    public function testCommandInputPromptsWhenRequiredArgumentsAreMissing()\n    {\n        $artisan = new Application(\n            $laravel = new FoundationApplication(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $artisan->addCommands([$command = new FakeCommandWithArrayInputPrompting()]);\n\n        $command->setLaravel($laravel);\n\n        $exitCode = $artisan->call('fake-command-for-testing-array');\n\n        $this->assertTrue($command->prompted);\n        $this->assertSame(['foo'], $command->argument('names'));\n        $this->assertSame(0, $exitCode);\n    }\n\n    public function testCommandInputDoesntPromptWhenRequiredArgumentsArePassed()\n    {\n        $artisan = new Application(\n            new FoundationApplication(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $artisan->addCommands([$command = new FakeCommandWithArrayInputPrompting()]);\n\n        $exitCode = $artisan->call('fake-command-for-testing-array', [\n            'names' => ['foo', 'bar', 'baz'],\n        ]);\n\n        $this->assertFalse($command->prompted);\n        $this->assertSame(['foo', 'bar', 'baz'], $command->argument('names'));\n        $this->assertSame(0, $exitCode);\n    }\n\n    public function testCallMethodCanCallArtisanCommandUsingCommandClassObject()\n    {\n        $artisan = new Application(\n            $laravel = new FoundationApplication(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null]),\n            'testing'\n        );\n\n        $artisan->addCommands([$command = new FakeCommandWithInputPrompting()]);\n\n        $command->setLaravel($laravel);\n\n        $exitCode = $artisan->call($command);\n\n        $this->assertTrue($command->prompted);\n        $this->assertSame('foo', $command->argument('name'));\n        $this->assertSame(0, $exitCode);\n    }\n\n    #[RunInSeparateProcess]\n    public function testLoadIgnoresTestFiles()\n    {\n        $files = new Filesystem;\n\n        $files->ensureDirectoryExists(join_paths(default_skeleton_path(), 'app', 'Console', 'Commands'), 0755, true);\n\n        try {\n            $files->put(\n                join_paths(default_skeleton_path(), 'app', 'Console', 'Commands', 'ExampleCommand.php'),\n                '<?php namespace App\\Console\\Commands; class ExampleCommand extends \\Illuminate\\Console\\Command { protected $signature = \"example\"; public function handle() {} }'\n            );\n\n            $files->put(\n                join_paths(default_skeleton_path(), 'app', 'Console', 'Commands', 'ExampleCommandTest.php'),\n                '<?php namespace App\\Console\\Commands; class ExampleCommandTest extends \\Illuminate\\Console\\Command { protected $signature = \"example-test\"; public function handle() {} }'\n            );\n\n            $files->put(\n                join_paths(default_skeleton_path(), 'app', 'Console', 'Commands', 'ExampleCommandUnitTest.php'),\n                '<?php namespace App\\Console\\Commands; class ExampleCommandUnitTest extends \\PHPUnit\\Framework\\TestCase { public function test_command() { $this->assertTrue(true); } }'\n            );\n\n            foreach (ClassLoader::getRegisteredLoaders() as $loader) {\n                $loader->addPsr4('App\\\\', [default_skeleton_path('app')]);\n            }\n\n            $app = Testbench::create(default_skeleton_path());\n            $events = new EventsDispatcher($app);\n            $app->instance('events', $events);\n\n            $kernel = new TestKernel($app, $events);\n\n            $commands = $kernel->getRegisteredCommands();\n\n            $this->assertContains('App\\Console\\Commands\\ExampleCommand', $commands);\n            $this->assertContains('App\\Console\\Commands\\ExampleCommandTest', $commands);\n            $this->assertNotContains('App\\Console\\Commands\\ExampleCommandUnitTest', $commands);\n\n            Testbench::flushState($this);\n        } finally {\n            $files->cleanDirectory(default_skeleton_path('app', 'Console', 'Commands'));\n        }\n    }\n\n    protected function getMockConsole(array $methods)\n    {\n        $app = m::mock(ApplicationContract::class, ['version' => '6.0']);\n        $events = m::mock(Dispatcher::class, ['dispatch' => null]);\n\n        return $this->getMockBuilder(Application::class)->onlyMethods($methods)->setConstructorArgs([\n            $app, $events, 'test-version',\n        ])->getMock();\n    }\n}\n\n#[AsCommand('command-name')]\nclass CommandWithNoAliasViaAttribute extends Command\n{\n    //\n}\n#[AsCommand('command-name', aliases: ['command-alias'])]\nclass CommandWithAliasViaAttribute extends Command\n{\n    //\n}\n\nclass CommandWithNoAliasViaProperty extends Command\n{\n    public $name = 'command-name';\n}\n\nclass CommandWithAliasViaProperty extends Command\n{\n    public $name = 'command-name';\n    public $aliases = ['command-alias'];\n}\n\nclass TestKernel extends Kernel\n{\n    public $loadedCommands = [];\n\n    public function loadFrom($paths)\n    {\n        $this->load($paths);\n    }\n\n    #[\\Override]\n    protected function commandClassFromFile(\\SplFileInfo $file, string $namespace): string\n    {\n        return tap(parent::commandClassFromFile($file, $namespace), fn ($command) => $this->loadedCommands[] = $command);\n    }\n\n    public function getRegisteredCommands(): array\n    {\n        return collect($this->getArtisan()->all())->values()->transform(fn ($command) => $command::class)->all();\n    }\n}\n"
  },
  {
    "path": "tests/Console/ConsoleEventSchedulerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Scheduling\\CacheEventMutex;\nuse Illuminate\\Console\\Scheduling\\CacheSchedulingMutex;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Console\\Scheduling\\SchedulingMutex;\nuse Illuminate\\Container\\Container;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConsoleEventSchedulerTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Console\\Scheduling\\Schedule\n     */\n    private $schedule;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $container = Container::getInstance();\n\n        $container->instance(EventMutex::class, m::mock(CacheEventMutex::class));\n\n        $container->instance(SchedulingMutex::class, m::mock(CacheSchedulingMutex::class));\n\n        $container->instance(Schedule::class, $this->schedule = new Schedule(m::mock(EventMutex::class)));\n    }\n\n    public function testMutexCanReceiveCustomStore()\n    {\n        Container::getInstance()->make(EventMutex::class)->shouldReceive('useStore')->once()->with('test');\n        Container::getInstance()->make(SchedulingMutex::class)->shouldReceive('useStore')->once()->with('test');\n\n        $this->schedule->useCache('test');\n    }\n\n    public function testExecCreatesNewCommand()\n    {\n        $escape = '\\\\' === DIRECTORY_SEPARATOR ? '\"' : '\\'';\n        $escapeReal = '\\\\' === DIRECTORY_SEPARATOR ? '\\\\\"' : '\"';\n\n        $schedule = $this->schedule;\n        $schedule->exec('path/to/command');\n        $schedule->exec('path/to/command -f --foo=\"bar\"');\n        $schedule->exec('path/to/command', ['-f']);\n        $schedule->exec('path/to/command', ['--foo' => 'bar']);\n        $schedule->exec('path/to/command', ['-f', '--foo' => 'bar']);\n        $schedule->exec('path/to/command', ['--title' => 'A \"real\" test']);\n        $schedule->exec('path/to/command', [['one', 'two']]);\n        $schedule->exec('path/to/command', ['-1 minute']);\n        $schedule->exec('path/to/command', ['foo' => ['bar', 'baz']]);\n        $schedule->exec('path/to/command', ['--foo' => ['bar', 'baz']]);\n        $schedule->exec('path/to/command', ['-F' => ['bar', 'baz']]);\n\n        $events = $schedule->events();\n        $this->assertSame('path/to/command', $events[0]->command);\n        $this->assertSame('path/to/command -f --foo=\"bar\"', $events[1]->command);\n        $this->assertSame('path/to/command -f', $events[2]->command);\n        $this->assertSame(\"path/to/command --foo={$escape}bar{$escape}\", $events[3]->command);\n        $this->assertSame(\"path/to/command -f --foo={$escape}bar{$escape}\", $events[4]->command);\n        $this->assertSame(\"path/to/command --title={$escape}A {$escapeReal}real{$escapeReal} test{$escape}\", $events[5]->command);\n        $this->assertSame(\"path/to/command {$escape}one{$escape} {$escape}two{$escape}\", $events[6]->command);\n        $this->assertSame(\"path/to/command {$escape}-1 minute{$escape}\", $events[7]->command);\n        $this->assertSame(\"path/to/command {$escape}bar{$escape} {$escape}baz{$escape}\", $events[8]->command);\n        $this->assertSame(\"path/to/command --foo={$escape}bar{$escape} --foo={$escape}baz{$escape}\", $events[9]->command);\n        $this->assertSame(\"path/to/command -F {$escape}bar{$escape} -F {$escape}baz{$escape}\", $events[10]->command);\n    }\n\n    public function testExecCreatesNewCommandWithTimezone()\n    {\n        $schedule = new Schedule('UTC');\n        $schedule->exec('path/to/command');\n        $events = $schedule->events();\n        $this->assertSame('UTC', $events[0]->timezone);\n\n        $schedule = new Schedule('Asia/Tokyo');\n        $schedule->exec('path/to/command');\n        $events = $schedule->events();\n        $this->assertSame('Asia/Tokyo', $events[0]->timezone);\n    }\n\n    public function testCommandCreatesNewArtisanCommand()\n    {\n        $schedule = $this->schedule;\n        $schedule->command('queue:listen');\n        $schedule->command('queue:listen --tries=3');\n        $schedule->command('queue:listen', ['--tries' => 3]);\n\n        $events = $schedule->events();\n        $phpBinary = Application::phpBinary();\n        $artisanBinary = Application::artisanBinary();\n        $this->assertEquals($phpBinary.' '.$artisanBinary.' queue:listen', $events[0]->command);\n        $this->assertEquals($phpBinary.' '.$artisanBinary.' queue:listen --tries=3', $events[1]->command);\n        $this->assertEquals($phpBinary.' '.$artisanBinary.' queue:listen --tries=3', $events[2]->command);\n    }\n\n    public function testCreateNewArtisanCommandUsingCommandClass()\n    {\n        $schedule = $this->schedule;\n        $schedule->command(ConsoleCommandStub::class, ['--force']);\n\n        $events = $schedule->events();\n        $phpBinary = Application::phpBinary();\n        $artisanBinary = Application::artisanBinary();\n        $this->assertEquals($phpBinary.' '.$artisanBinary.' foo:bar --force', $events[0]->command);\n    }\n\n    public function testCreateNewArtisanCommandUsingCommandClassObject()\n    {\n        $command = new class extends Command\n        {\n            protected $signature = 'foo:bar';\n\n            public function handle()\n            {\n            }\n        };\n\n        $schedule = $this->schedule;\n        $schedule->command($command, ['--force']);\n\n        $events = $schedule->events();\n        $phpBinary = Application::phpBinary();\n        $artisanBinary = Application::artisanBinary();\n        $this->assertEquals($phpBinary.' '.$artisanBinary.' foo:bar --force', $events[0]->command);\n    }\n\n    public function testItUsesCommandDescriptionAsEventDescription()\n    {\n        $schedule = $this->schedule;\n        $event = $schedule->command(ConsoleCommandStub::class);\n        $this->assertSame('This is a description about the command', $event->description);\n    }\n\n    public function testItShouldBePossibleToOverwriteTheDescription()\n    {\n        $schedule = $this->schedule;\n        $event = $schedule->command(ConsoleCommandStub::class)\n            ->description('This is an alternative description');\n        $this->assertSame('This is an alternative description', $event->description);\n    }\n\n    public function testCallCreatesNewJobWithTimezone()\n    {\n        $schedule = new Schedule('UTC');\n        $schedule->call('path/to/command');\n        $events = $schedule->events();\n        $this->assertSame('UTC', $events[0]->timezone);\n\n        $schedule = new Schedule('Asia/Tokyo');\n        $schedule->call('path/to/command');\n        $events = $schedule->events();\n        $this->assertSame('Asia/Tokyo', $events[0]->timezone);\n    }\n}\n\nclass FooClassStub\n{\n    protected $schedule;\n\n    public function __construct(Schedule $schedule)\n    {\n        $this->schedule = $schedule;\n    }\n}\n\nclass ConsoleCommandStub extends Command\n{\n    protected $signature = 'foo:bar';\n\n    protected $description = 'This is a description about the command';\n\n    protected $foo;\n\n    public function __construct(FooClassStub $foo)\n    {\n        parent::__construct();\n\n        $this->foo = $foo;\n    }\n}\n"
  },
  {
    "path": "tests/Console/ConsoleParserTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Parser;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConsoleParserTest extends TestCase\n{\n    public function testBasicParameterParsing()\n    {\n        $results = Parser::parse('command:name');\n\n        $this->assertSame('command:name', $results[0]);\n\n        $results = Parser::parse('command:name {argument} {--option}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('argument', $results[1][0]->getName());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertFalse($results[2][0]->acceptValue());\n\n        $results = Parser::parse('command:name {argument*} {--option=}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('argument', $results[1][0]->getName());\n        $this->assertTrue($results[1][0]->isArray());\n        $this->assertTrue($results[1][0]->isRequired());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertTrue($results[2][0]->acceptValue());\n\n        $results = Parser::parse('command:name {argument?*} {--option=*}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('argument', $results[1][0]->getName());\n        $this->assertTrue($results[1][0]->isArray());\n        $this->assertFalse($results[1][0]->isRequired());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n\n        $results = Parser::parse('command:name {argument?* : The argument description.}    {--option=* : The option description.}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('argument', $results[1][0]->getName());\n        $this->assertSame('The argument description.', $results[1][0]->getDescription());\n        $this->assertTrue($results[1][0]->isArray());\n        $this->assertFalse($results[1][0]->isRequired());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertSame('The option description.', $results[2][0]->getDescription());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n\n        $results = Parser::parse('command:name\n            {argument?* : The argument description.}\n            {--option=* : The option description.}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('argument', $results[1][0]->getName());\n        $this->assertSame('The argument description.', $results[1][0]->getDescription());\n        $this->assertTrue($results[1][0]->isArray());\n        $this->assertFalse($results[1][0]->isRequired());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertSame('The option description.', $results[2][0]->getDescription());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n    }\n\n    public function testShortcutNameParsing()\n    {\n        $results = Parser::parse('command:name {--o|option}');\n\n        $this->assertSame('o', $results[2][0]->getShortcut());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertFalse($results[2][0]->acceptValue());\n\n        $results = Parser::parse('command:name {--o|option=}');\n\n        $this->assertSame('o', $results[2][0]->getShortcut());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertTrue($results[2][0]->acceptValue());\n\n        $results = Parser::parse('command:name {--o|option=*}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('o', $results[2][0]->getShortcut());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n\n        $results = Parser::parse('command:name {--o|option=* : The option description.}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('o', $results[2][0]->getShortcut());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertSame('The option description.', $results[2][0]->getDescription());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n\n        $results = Parser::parse('command:name\n            {--o|option=* : The option description.}');\n\n        $this->assertSame('command:name', $results[0]);\n        $this->assertSame('o', $results[2][0]->getShortcut());\n        $this->assertSame('option', $results[2][0]->getName());\n        $this->assertSame('The option description.', $results[2][0]->getDescription());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n    }\n\n    public function testDefaultValueParsing()\n    {\n        $results = Parser::parse('command:name {argument=defaultArgumentValue} {--option=defaultOptionValue}');\n\n        $this->assertFalse($results[1][0]->isRequired());\n        $this->assertSame('defaultArgumentValue', $results[1][0]->getDefault());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertSame('defaultOptionValue', $results[2][0]->getDefault());\n\n        $results = Parser::parse('command:name {argument=*defaultArgumentValue1,defaultArgumentValue2} {--option=*defaultOptionValue1,defaultOptionValue2}');\n\n        $this->assertTrue($results[1][0]->isArray());\n        $this->assertFalse($results[1][0]->isRequired());\n        $this->assertEquals(['defaultArgumentValue1', 'defaultArgumentValue2'], $results[1][0]->getDefault());\n        $this->assertTrue($results[2][0]->acceptValue());\n        $this->assertTrue($results[2][0]->isArray());\n        $this->assertEquals(['defaultOptionValue1', 'defaultOptionValue2'], $results[2][0]->getDefault());\n    }\n\n    public function testArgumentDefaultValue()\n    {\n        $results = Parser::parse('command:name {argument= : The argument description.}');\n        $this->assertNull($results[1][0]->getDefault());\n\n        $results = Parser::parse('command:name {argument=default : The argument description.}');\n        $this->assertSame('default', $results[1][0]->getDefault());\n    }\n\n    public function testOptionDefaultValue()\n    {\n        $results = Parser::parse('command:name {--option= : The option description.}');\n        $this->assertNull($results[2][0]->getDefault());\n\n        $results = Parser::parse('command:name {--option=default : The option description.}');\n        $this->assertSame('default', $results[2][0]->getDefault());\n    }\n\n    public function testNameIsSpacesException()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Unable to determine command name from signature.');\n\n        Parser::parse(\" \\t\\n\\r\\x0B\\f\");\n    }\n\n    public function testNameInEmptyException()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Unable to determine command name from signature.');\n\n        Parser::parse('');\n    }\n}\n"
  },
  {
    "path": "tests/Console/ConsoleScheduledEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConsoleScheduledEventTest extends TestCase\n{\n    /**\n     * The default configuration timezone.\n     *\n     * @var string\n     */\n    protected $defaultTimezone;\n\n    protected function setUp(): void\n    {\n        $this->defaultTimezone = date_default_timezone_get();\n        date_default_timezone_set('UTC');\n    }\n\n    protected function tearDown(): void\n    {\n        date_default_timezone_set($this->defaultTimezone);\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testBasicCronCompilation()\n    {\n        $app = m::mock(Application::class.'[isDownForMaintenance,environment]');\n        $app->shouldReceive('isDownForMaintenance')->andReturn(false);\n        $app->shouldReceive('environment')->andReturn('production');\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('* * * * *', $event->getExpression());\n        $this->assertTrue($event->isDue($app));\n        $this->assertTrue($event->skip(function () {\n            return true;\n        })->isDue($app));\n        $this->assertFalse($event->skip(function () {\n            return true;\n        })->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('* * * * *', $event->getExpression());\n        $this->assertFalse($event->environments('local')->isDue($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('* * * * *', $event->getExpression());\n        $this->assertFalse($event->when(function () {\n            return false;\n        })->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('* * * * *', $event->getExpression());\n        $this->assertFalse($event->when(false)->filtersPass($app));\n\n        // chained rules should be commutative\n        $eventA = new Event(m::mock(EventMutex::class), 'php foo');\n        $eventB = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertEquals(\n            $eventA->daily()->hourly()->getExpression(),\n            $eventB->hourly()->daily()->getExpression());\n\n        $eventA = new Event(m::mock(EventMutex::class), 'php foo');\n        $eventB = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertEquals(\n            $eventA->weekdays()->hourly()->getExpression(),\n            $eventB->hourly()->weekdays()->getExpression());\n    }\n\n    public function testEventIsDueCheck()\n    {\n        $app = m::mock(Application::class.'[isDownForMaintenance,environment]');\n        $app->shouldReceive('isDownForMaintenance')->andReturn(false);\n        $app->shouldReceive('environment')->andReturn('production');\n        Carbon::setTestNow(Carbon::create(2015, 1, 1, 0, 0, 0));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('* * * * 4', $event->thursdays()->getExpression());\n        $this->assertTrue($event->isDue($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo');\n        $this->assertSame('0 19 * * 3', $event->wednesdays()->at('19:00')->timezone('EST')->getExpression());\n        $this->assertTrue($event->isDue($app));\n    }\n\n    public function testTimeBetweenChecks()\n    {\n        $app = m::mock(Application::class.'[isDownForMaintenance,environment]');\n        $app->shouldReceive('isDownForMaintenance')->andReturn(false);\n        $app->shouldReceive('environment')->andReturn('production');\n\n        Carbon::setTestNow(Carbon::now()->startOfDay()->addHours(9));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->between('8:00', '10:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->between('9:00', '9:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->between('23:00', '10:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->between('8:00', '6:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->between('10:00', '11:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->between('10:00', '8:00')->filtersPass($app));\n    }\n\n    public function testTimeUnlessBetweenChecks()\n    {\n        $app = m::mock(Application::class.'[isDownForMaintenance,environment]');\n        $app->shouldReceive('isDownForMaintenance')->andReturn(false);\n        $app->shouldReceive('environment')->andReturn('production');\n\n        Carbon::setTestNow(Carbon::now()->startOfDay()->addHours(9));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->unlessBetween('8:00', '10:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->unlessBetween('9:00', '9:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->unlessBetween('23:00', '10:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertFalse($event->unlessBetween('8:00', '6:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->unlessBetween('10:00', '11:00')->filtersPass($app));\n\n        $event = new Event(m::mock(EventMutex::class), 'php foo', 'UTC');\n        $this->assertTrue($event->unlessBetween('10:00', '8:00')->filtersPass($app));\n    }\n}\n"
  },
  {
    "path": "tests/Console/Fixtures/FakeCommandWithArrayInputPrompting.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Fixtures;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput;\nuse Laravel\\Prompts\\Prompt;\nuse Laravel\\Prompts\\TextPrompt;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\n\nclass FakeCommandWithArrayInputPrompting extends Command implements PromptsForMissingInput\n{\n    protected $signature = 'fake-command-for-testing-array {names* : An array argument}';\n\n    public $prompted = false;\n\n    protected function configurePrompts(InputInterface $input)\n    {\n        Prompt::interactive(true);\n        Prompt::fallbackWhen(true);\n\n        TextPrompt::fallbackUsing(function () {\n            $this->prompted = true;\n\n            return 'foo';\n        });\n    }\n\n    public function handle(): int\n    {\n        return self::SUCCESS;\n    }\n}\n"
  },
  {
    "path": "tests/Console/Fixtures/FakeCommandWithInputPrompting.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Fixtures;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\PromptsForMissingInput;\nuse Laravel\\Prompts\\Prompt;\nuse Laravel\\Prompts\\TextPrompt;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\n\nclass FakeCommandWithInputPrompting extends Command implements PromptsForMissingInput\n{\n    protected $signature = 'fake-command-for-testing {name : An argument}';\n\n    public $prompted = false;\n\n    protected function configurePrompts(InputInterface $input)\n    {\n        Prompt::interactive(true);\n        Prompt::fallbackWhen(true);\n\n        TextPrompt::fallbackUsing(function () {\n            $this->prompted = true;\n\n            return 'foo';\n        });\n    }\n\n    public function handle(): int\n    {\n        return self::SUCCESS;\n    }\n}\n"
  },
  {
    "path": "tests/Console/Fixtures/FakeSignalsRegistry.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Fixtures;\n\nclass FakeSignalsRegistry\n{\n    protected $signalHandlers = [\n        'my-signal' => [],\n    ];\n\n    public function register($signal, $signalHandler)\n    {\n        $this->signalHandlers[$signal][] = $signalHandler;\n    }\n\n    public function handle($signal)\n    {\n        $count = count($this->signalHandlers[$signal]);\n\n        foreach ($this->signalHandlers[$signal] as $i => $signalHandler) {\n            $hasNext = $i !== $count - 1;\n            $signalHandler($signal, $hasNext);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Console/Fixtures/JobToTestWithSchedule.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Console\\Fixtures;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\n\nfinal class JobToTestWithSchedule implements ShouldQueue\n{\n}\n"
  },
  {
    "path": "tests/Console/OutputStyleTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\OutputStyle;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nclass OutputStyleTest extends TestCase\n{\n    public function testDetectsNewLine()\n    {\n        $bufferedOutput = new BufferedOutput();\n\n        $style = new OutputStyle(new ArrayInput([]), $bufferedOutput);\n\n        $this->assertFalse($style->newLineWritten());\n\n        $style->newLine();\n        $this->assertTrue($style->newLineWritten());\n    }\n\n    public function testDetectsNewLineOnUnderlyingOutput()\n    {\n        $bufferedOutput = new BufferedOutput();\n\n        $underlyingStyle = new OutputStyle(new ArrayInput([]), $bufferedOutput);\n        $style = new OutputStyle(new ArrayInput([]), $underlyingStyle);\n\n        $underlyingStyle->newLine();\n        $this->assertTrue($style->newLineWritten());\n    }\n\n    public function testDetectsNewLineOnWrite()\n    {\n        $bufferedOutput = new BufferedOutput();\n\n        $style = new OutputStyle(new ArrayInput([]), $bufferedOutput);\n\n        $style->write('Foo');\n        $this->assertFalse($style->newLineWritten());\n\n        $style->write('Foo', true);\n        $this->assertTrue($style->newLineWritten());\n    }\n\n    public function testDetectsNewLineOnWriteln()\n    {\n        $bufferedOutput = new BufferedOutput();\n\n        $style = new OutputStyle(new ArrayInput([]), $bufferedOutput);\n\n        $style->writeln('Foo');\n        $this->assertTrue($style->newLineWritten());\n    }\n\n    public function testDetectsNewLineOnlyOnOutput()\n    {\n        $bufferedOutput = new BufferedOutput();\n\n        $style = new OutputStyle(new ArrayInput([]), $bufferedOutput);\n\n        $style->setVerbosity(OutputStyle::VERBOSITY_NORMAL);\n\n        $style->writeln('Foo', OutputStyle::VERBOSITY_VERBOSE);\n        $this->assertFalse($style->newLineWritten());\n\n        $style->setVerbosity(OutputStyle::VERBOSITY_VERBOSE);\n\n        $style->writeln('Foo', OutputStyle::VERBOSITY_VERBOSE);\n        $this->assertTrue($style->newLineWritten());\n    }\n}\n"
  },
  {
    "path": "tests/Console/Scheduling/CacheEventMutexTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Scheduling;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Console\\Scheduling\\CacheEventMutex;\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheEventMutexTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Console\\Scheduling\\CacheEventMutex\n     */\n    protected $cacheMutex;\n\n    /**\n     * @var \\Illuminate\\Console\\Scheduling\\Event\n     */\n    protected $event;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    protected $cacheFactory;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cacheRepository;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->cacheFactory = m::mock(Factory::class);\n        $this->cacheRepository = m::mock(Repository::class);\n        $this->cacheFactory->shouldReceive('store')->andReturn($this->cacheRepository);\n        $this->cacheMutex = new CacheEventMutex($this->cacheFactory);\n        $this->event = new Event($this->cacheMutex, 'command');\n    }\n\n    public function testPreventOverlap()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('add')->once();\n\n        $this->cacheMutex->create($this->event);\n    }\n\n    public function testCustomConnection()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheFactory->shouldReceive('store')->with('test')->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('add')->once();\n        $this->cacheMutex->useStore('test');\n\n        $this->cacheMutex->create($this->event);\n    }\n\n    public function testPreventOverlapFails()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('add')->once()->andReturn(false);\n\n        $this->assertFalse($this->cacheMutex->create($this->event));\n    }\n\n    public function testOverlapsForNonRunningTask()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('has')->once()->andReturn(false);\n\n        $this->assertFalse($this->cacheMutex->exists($this->event));\n    }\n\n    public function testOverlapsForRunningTask()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('has')->once()->andReturn(true);\n\n        $this->assertTrue($this->cacheMutex->exists($this->event));\n    }\n\n    public function testResetOverlap()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('forget')->once();\n\n        $this->cacheMutex->forget($this->event);\n    }\n\n    public function testPreventOverlapWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->assertTrue($this->cacheMutex->create($this->event));\n    }\n\n    public function testPreventOverlapFailsWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        // first create the lock, so we can test that the next call fails.\n        $this->cacheMutex->create($this->event);\n\n        $this->assertFalse($this->cacheMutex->create($this->event));\n    }\n\n    public function testOverlapsForNonRunningTaskWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->assertFalse($this->cacheMutex->exists($this->event));\n    }\n\n    public function testOverlapsForRunningTaskWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->cacheMutex->create($this->event);\n\n        $this->assertTrue($this->cacheMutex->exists($this->event));\n    }\n\n    public function testResetOverlapWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->cacheMutex->create($this->event);\n\n        $this->cacheMutex->forget($this->event);\n\n        $this->assertFalse($this->cacheMutex->exists($this->event));\n    }\n}\n"
  },
  {
    "path": "tests/Console/Scheduling/CacheSchedulingMutexTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Scheduling;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Console\\Scheduling\\CacheEventMutex;\nuse Illuminate\\Console\\Scheduling\\CacheSchedulingMutex;\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheSchedulingMutexTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Console\\Scheduling\\CacheSchedulingMutex\n     */\n    protected $cacheMutex;\n\n    /**\n     * @var \\Illuminate\\Console\\Scheduling\\Event\n     */\n    protected $event;\n\n    /**\n     * @var \\Illuminate\\Support\\Carbon\n     */\n    protected $time;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Factory\n     */\n    protected $cacheFactory;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Cache\\Repository\n     */\n    protected $cacheRepository;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->cacheFactory = m::mock(Factory::class);\n        $this->cacheRepository = m::mock(Repository::class);\n        $this->cacheFactory->shouldReceive('store')->andReturn($this->cacheRepository);\n        $this->cacheMutex = new CacheSchedulingMutex($this->cacheFactory);\n        $this->event = new Event(new CacheEventMutex($this->cacheFactory), 'command');\n        $this->time = Carbon::now();\n    }\n\n    public function testMutexReceivesCorrectCreate()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('add')->once()->with($this->event->mutexName().$this->time->format('Hi'), true, 3600)->andReturn(true);\n\n        $this->assertTrue($this->cacheMutex->create($this->event, $this->time));\n    }\n\n    public function testCanUseCustomConnection()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheFactory->shouldReceive('store')->with('test')->andReturn($this->cacheRepository);\n        $this->cacheRepository->shouldReceive('add')->once()->with($this->event->mutexName().$this->time->format('Hi'), true, 3600)->andReturn(true);\n        $this->cacheMutex->useStore('test');\n\n        $this->assertTrue($this->cacheMutex->create($this->event, $this->time));\n    }\n\n    public function testPreventsMultipleRuns()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('add')->once()->with($this->event->mutexName().$this->time->format('Hi'), true, 3600)->andReturn(false);\n\n        $this->assertFalse($this->cacheMutex->create($this->event, $this->time));\n    }\n\n    public function testChecksForNonRunSchedule()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('has')->once()->with($this->event->mutexName().$this->time->format('Hi'))->andReturn(false);\n\n        $this->assertFalse($this->cacheMutex->exists($this->event, $this->time));\n    }\n\n    public function testChecksForAlreadyRunSchedule()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new \\stdClass);\n        $this->cacheRepository->shouldReceive('has')->with($this->event->mutexName().$this->time->format('Hi'))->andReturn(true);\n\n        $this->assertTrue($this->cacheMutex->exists($this->event, $this->time));\n    }\n\n    public function testMutexReceivesCorrectCreateWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->assertTrue($this->cacheMutex->create($this->event, $this->time));\n    }\n\n    public function testPreventsMultipleRunsWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        // first create the lock, so we can test that the next call fails.\n        $this->cacheMutex->create($this->event, $this->time);\n\n        $this->assertFalse($this->cacheMutex->create($this->event, $this->time));\n    }\n\n    public function testChecksForNonRunScheduleWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->assertFalse($this->cacheMutex->exists($this->event, $this->time));\n    }\n\n    public function testChecksForAlreadyRunScheduleWithLockProvider()\n    {\n        $this->cacheRepository->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $this->cacheMutex->create($this->event, $this->time);\n\n        $this->assertTrue($this->cacheMutex->exists($this->event, $this->time));\n    }\n}\n"
  },
  {
    "path": "tests/Console/Scheduling/EventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Illuminate\\Support\\php_binary;\n\nclass EventTest extends TestCase\n{\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    public function testBuildCommandUsingUnix()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $this->assertSame(\"php -i > '/dev/null' 2>&1\", $event->buildCommand());\n    }\n\n    #[RequiresOperatingSystem('Windows')]\n    public function testBuildCommandUsingWindows()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $this->assertSame('php -i > \"NUL\" 2>&1', $event->buildCommand());\n    }\n\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    public function testBuildCommandInBackgroundUsingUnix()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->runInBackground();\n\n        $scheduleId = '\"framework'.DIRECTORY_SEPARATOR.'schedule-eeb46c93d45e928d62aaf684d727e213b7094822\"';\n\n        $this->assertSame(\"(php -i > '/dev/null' 2>&1 ; '\".php_binary().\"' 'artisan' schedule:finish {$scheduleId} \\\"$?\\\") > '/dev/null' 2>&1 &\", $event->buildCommand());\n    }\n\n    #[RequiresOperatingSystem('Windows')]\n    public function testBuildCommandInBackgroundUsingWindows()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->runInBackground();\n\n        $scheduleId = '\"framework'.DIRECTORY_SEPARATOR.'schedule-eeb46c93d45e928d62aaf684d727e213b7094822\"';\n\n        $this->assertSame('start /b cmd /v:on /c \"(php -i & '.php_binary().' artisan schedule:finish '.$scheduleId.' ^!ERRORLEVEL^!) > \"NUL\" 2>&1\"', $event->buildCommand());\n    }\n\n    public function testBuildCommandSendOutputTo()\n    {\n        $quote = (DIRECTORY_SEPARATOR === '\\\\') ? '\"' : \"'\";\n\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $event->sendOutputTo('/dev/null');\n        $this->assertSame(\"php -i > {$quote}/dev/null{$quote} 2>&1\", $event->buildCommand());\n\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $event->sendOutputTo('/my folder/foo.log');\n        $this->assertSame(\"php -i > {$quote}/my folder/foo.log{$quote} 2>&1\", $event->buildCommand());\n    }\n\n    public function testBuildCommandAppendOutput()\n    {\n        $quote = (DIRECTORY_SEPARATOR === '\\\\') ? '\"' : \"'\";\n\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $event->appendOutputTo('/dev/null');\n        $this->assertSame(\"php -i >> {$quote}/dev/null{$quote} 2>&1\", $event->buildCommand());\n    }\n\n    public function testNextRunDate()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->dailyAt('10:15');\n\n        $this->assertSame('10:15:00', $event->nextRunDate()->toTimeString());\n    }\n\n    public function testCustomMutexName()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->description('Fancy command description');\n\n        $this->assertSame('framework'.DIRECTORY_SEPARATOR.'schedule-eeb46c93d45e928d62aaf684d727e213b7094822', $event->mutexName());\n\n        $event->createMutexNameUsing(function (Event $event) {\n            return Str::slug($event->description);\n        });\n\n        $this->assertSame('fancy-command-description', $event->mutexName());\n    }\n\n    public function testDaysOfMonthMethod()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $event->daysOfMonth(1, 15);\n        $this->assertSame('0 0 1,15 * *', $event->getExpression());\n\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->daysOfMonth([1, 10, 20, 30]);\n        $this->assertSame('0 0 1,10,20,30 * *', $event->getExpression());\n    }\n\n    public function testEventDoesNotRunWhenPausedByDefault()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $this->assertFalse($event->runsWhenPaused());\n    }\n\n    public function testEventRunsWhenMarkedAsEvenWhenPaused()\n    {\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n        $event->evenWhenPaused();\n\n        $this->assertTrue($event->runsWhenPaused());\n    }\n}\n"
  },
  {
    "path": "tests/Console/Scheduling/FrequencyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FrequencyTest extends TestCase\n{\n    /** @var \\Illuminate\\Console\\Scheduling\\Event */\n    protected $event;\n\n    protected function setUp(): void\n    {\n        $this->event = new Event(\n            m::mock(EventMutex::class),\n            'php foo'\n        );\n    }\n\n    public function testEveryMinute()\n    {\n        $this->assertSame('* * * * *', $this->event->getExpression());\n        $this->assertSame('* * * * *', $this->event->everyMinute()->getExpression());\n    }\n\n    public function testEveryXMinutes()\n    {\n        $this->assertSame('*/2 * * * *', $this->event->everyTwoMinutes()->getExpression());\n        $this->assertSame('*/3 * * * *', $this->event->everyThreeMinutes()->getExpression());\n        $this->assertSame('*/4 * * * *', $this->event->everyFourMinutes()->getExpression());\n        $this->assertSame('*/5 * * * *', $this->event->everyFiveMinutes()->getExpression());\n        $this->assertSame('*/10 * * * *', $this->event->everyTenMinutes()->getExpression());\n        $this->assertSame('*/15 * * * *', $this->event->everyFifteenMinutes()->getExpression());\n        $this->assertSame('*/30 * * * *', $this->event->everyThirtyMinutes()->getExpression());\n    }\n\n    public function testDaily()\n    {\n        $this->assertSame('0 0 * * *', $this->event->daily()->getExpression());\n    }\n\n    public function testDailyAt()\n    {\n        $this->assertSame('8 13 * * *', $this->event->dailyAt('13:08')->getExpression());\n    }\n\n    public function testDailyAtParsesMinutesAndIgnoresSecondsWhenSecondsAreDefined()\n    {\n        $this->assertSame('8 13 * * *', $this->event->dailyAt('13:08:10')->getExpression());\n    }\n\n    public function testTwiceDaily()\n    {\n        $this->assertSame('0 3,15 * * *', $this->event->twiceDaily(3, 15)->getExpression());\n    }\n\n    public function testTwiceDailyAt()\n    {\n        $this->assertSame('5 3,15 * * *', $this->event->twiceDailyAt(3, 15, 5)->getExpression());\n    }\n\n    public function testWeekly()\n    {\n        $this->assertSame('0 0 * * 0', $this->event->weekly()->getExpression());\n    }\n\n    public function testWeeklyOn()\n    {\n        $this->assertSame('0 8 * * 1', $this->event->weeklyOn(1, '8:00')->getExpression());\n    }\n\n    public function testOverrideWithHourly()\n    {\n        $this->assertSame('0 * * * *', $this->event->everyFiveMinutes()->hourly()->getExpression());\n        $this->assertSame('37 * * * *', $this->event->hourlyAt(37)->getExpression());\n        $this->assertSame('*/10 * * * *', $this->event->hourlyAt('*/10')->getExpression());\n        $this->assertSame('15,30,45 * * * *', $this->event->hourlyAt([15, 30, 45])->getExpression());\n    }\n\n    public function testHourly()\n    {\n        $this->assertSame('0 1-23/2 * * *', $this->event->everyOddHour()->getExpression());\n        $this->assertSame('0 */2 * * *', $this->event->everyTwoHours()->getExpression());\n        $this->assertSame('0 */3 * * *', $this->event->everyThreeHours()->getExpression());\n        $this->assertSame('0 */4 * * *', $this->event->everyFourHours()->getExpression());\n        $this->assertSame('0 */6 * * *', $this->event->everySixHours()->getExpression());\n\n        $this->assertSame('37 1-23/2 * * *', $this->event->everyOddHour(37)->getExpression());\n        $this->assertSame('37 */2 * * *', $this->event->everyTwoHours(37)->getExpression());\n        $this->assertSame('37 */3 * * *', $this->event->everyThreeHours(37)->getExpression());\n        $this->assertSame('37 */4 * * *', $this->event->everyFourHours(37)->getExpression());\n        $this->assertSame('37 */6 * * *', $this->event->everySixHours(37)->getExpression());\n\n        $this->assertSame('*/10 1-23/2 * * *', $this->event->everyOddHour('*/10')->getExpression());\n        $this->assertSame('*/10 */2 * * *', $this->event->everyTwoHours('*/10')->getExpression());\n        $this->assertSame('*/10 */3 * * *', $this->event->everyThreeHours('*/10')->getExpression());\n        $this->assertSame('*/10 */4 * * *', $this->event->everyFourHours('*/10')->getExpression());\n        $this->assertSame('*/10 */6 * * *', $this->event->everySixHours('*/10')->getExpression());\n\n        $this->assertSame('15,30,45 1-23/2 * * *', $this->event->everyOddHour([15, 30, 45])->getExpression());\n        $this->assertSame('15,30,45 */2 * * *', $this->event->everyTwoHours([15, 30, 45])->getExpression());\n        $this->assertSame('15,30,45 */3 * * *', $this->event->everyThreeHours([15, 30, 45])->getExpression());\n        $this->assertSame('15,30,45 */4 * * *', $this->event->everyFourHours([15, 30, 45])->getExpression());\n        $this->assertSame('15,30,45 */6 * * *', $this->event->everySixHours([15, 30, 45])->getExpression());\n    }\n\n    public function testMonthly()\n    {\n        $this->assertSame('0 0 1 * *', $this->event->monthly()->getExpression());\n    }\n\n    public function testMonthlyOn()\n    {\n        $this->assertSame('0 15 4 * *', $this->event->monthlyOn(4, '15:00')->getExpression());\n    }\n\n    public function testLastDayOfMonth()\n    {\n        Carbon::setTestNow('2020-10-10 10:10:10');\n\n        $this->assertSame('0 0 31 * *', $this->event->lastDayOfMonth()->getExpression());\n\n        Carbon::setTestNow(null);\n    }\n\n    public function testTwiceMonthly()\n    {\n        $this->assertSame('0 0 1,16 * *', $this->event->twiceMonthly(1, 16)->getExpression());\n    }\n\n    public function testTwiceMonthlyAtTime()\n    {\n        $this->assertSame('30 1 1,16 * *', $this->event->twiceMonthly(1, 16, '1:30')->getExpression());\n    }\n\n    public function testMonthlyOnWithMinutes()\n    {\n        $this->assertSame('15 15 4 * *', $this->event->monthlyOn(4, '15:15')->getExpression());\n    }\n\n    public function testWeekdaysDaily()\n    {\n        $this->assertSame('0 0 * * 1-5', $this->event->weekdays()->daily()->getExpression());\n    }\n\n    public function testWeekdaysHourly()\n    {\n        $this->assertSame('0 * * * 1-5', $this->event->weekdays()->hourly()->getExpression());\n    }\n\n    public function testWeekdays()\n    {\n        $this->assertSame('* * * * 1-5', $this->event->weekdays()->getExpression());\n    }\n\n    public function testWeekends()\n    {\n        $this->assertSame('* * * * 6,0', $this->event->weekends()->getExpression());\n    }\n\n    public function testSundays()\n    {\n        $this->assertSame('* * * * 0', $this->event->sundays()->getExpression());\n    }\n\n    public function testMondays()\n    {\n        $this->assertSame('* * * * 1', $this->event->mondays()->getExpression());\n    }\n\n    public function testTuesdays()\n    {\n        $this->assertSame('* * * * 2', $this->event->tuesdays()->getExpression());\n    }\n\n    public function testWednesdays()\n    {\n        $this->assertSame('* * * * 3', $this->event->wednesdays()->getExpression());\n    }\n\n    public function testThursdays()\n    {\n        $this->assertSame('* * * * 4', $this->event->thursdays()->getExpression());\n    }\n\n    public function testFridays()\n    {\n        $this->assertSame('* * * * 5', $this->event->fridays()->getExpression());\n    }\n\n    public function testSaturdays()\n    {\n        $this->assertSame('* * * * 6', $this->event->saturdays()->getExpression());\n    }\n\n    public function testQuarterly()\n    {\n        $this->assertSame('0 0 1 1-12/3 *', $this->event->quarterly()->getExpression());\n    }\n\n    public function testYearly()\n    {\n        $this->assertSame('0 0 1 1 *', $this->event->yearly()->getExpression());\n    }\n\n    public function testYearlyOn()\n    {\n        $this->assertSame('8 15 5 4 *', $this->event->yearlyOn(4, 5, '15:08')->getExpression());\n    }\n\n    public function testYearlyOnMondaysOnly()\n    {\n        $this->assertSame('1 9 * 7 1', $this->event->mondays()->yearlyOn(7, '*', '09:01')->getExpression());\n    }\n\n    public function testYearlyOnTuesdaysAndDayOfMonth20()\n    {\n        $this->assertSame('1 9 20 7 2', $this->event->tuesdays()->yearlyOn(7, 20, '09:01')->getExpression());\n    }\n\n    public function testFrequencyMacro()\n    {\n        Event::macro('everyXMinutes', function ($x) {\n            return $this->spliceIntoPosition(1, \"*/{$x}\");\n        });\n\n        $this->assertSame('*/6 * * * *', $this->event->everyXMinutes(6)->getExpression());\n    }\n}\n"
  },
  {
    "path": "tests/Console/Scheduling/ScheduleTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Console\\Scheduling\\SchedulingMutex;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Tests\\Console\\Fixtures\\JobToTestWithSchedule;\nuse Mockery as m;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\Attributes\\CoversClass;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\n#[CoversClass(Schedule::class)]\nfinal class ScheduleTest extends TestCase\n{\n    private Container $container;\n    private EventMutex&MockInterface $eventMutex;\n    private SchedulingMutex&MockInterface $schedulingMutex;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->container = new Container;\n        Container::setInstance($this->container);\n        $this->eventMutex = m::mock(EventMutex::class);\n        $this->container->instance(EventMutex::class, $this->eventMutex);\n        $this->schedulingMutex = m::mock(SchedulingMutex::class);\n        $this->container->instance(SchedulingMutex::class, $this->schedulingMutex);\n    }\n\n    #[DataProvider('jobHonoursDisplayNameIfMethodExistsProvider')]\n    public function testJobHonoursDisplayNameIfMethodExists(object $job, string $jobName): void\n    {\n        $schedule = new Schedule();\n        $scheduledJob = $schedule->job($job);\n        self::assertSame($jobName, $scheduledJob->description);\n        self::assertFalse($this->container->resolved(JobToTestWithSchedule::class));\n    }\n\n    public static function jobHonoursDisplayNameIfMethodExistsProvider(): array\n    {\n        $job = new class implements ShouldQueue\n        {\n            public function displayName(): string\n            {\n                return 'testJob-123';\n            }\n        };\n\n        return [\n            [new JobToTestWithSchedule, JobToTestWithSchedule::class],\n            [$job, 'testJob-123'],\n        ];\n    }\n\n    public function testJobIsNotInstantiatedIfSuppliedAsClassname(): void\n    {\n        $schedule = new Schedule();\n        $scheduledJob = $schedule->job(JobToTestWithSchedule::class);\n        self::assertSame(JobToTestWithSchedule::class, $scheduledJob->description);\n        self::assertFalse($this->container->resolved(JobToTestWithSchedule::class));\n    }\n}\n"
  },
  {
    "path": "tests/Console/SignalsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console;\n\nuse Illuminate\\Console\\Signals;\nuse Illuminate\\Tests\\Console\\Fixtures\\FakeSignalsRegistry;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SignalsTest extends TestCase\n{\n    protected $registry;\n\n    protected $signals;\n\n    protected $state;\n\n    protected function setUp(): void\n    {\n        $this->registry = new FakeSignalsRegistry();\n        $this->signals = new Signals($this->registry);\n    }\n\n    protected function tearDown(): void\n    {\n        $this->state = null;\n\n        parent::tearDown();\n    }\n\n    public function testRegister()\n    {\n        $this->signals->register('my-signal', function () {\n            $this->state .= 'otwell';\n        });\n\n        $this->signals->register('my-signal', function () {\n            $this->state = 'taylor';\n        });\n\n        $this->registry->handle('my-signal');\n\n        $this->assertSame('taylorotwell', $this->state);\n    }\n\n    public function testUnregister()\n    {\n        $this->signals->register('my-signal', function () {\n            $this->state .= 'otwell';\n        });\n\n        $this->signals->register('my-signal', function () {\n            $this->state = 'taylor';\n        });\n\n        $this->signals->unregister();\n\n        $this->registry->handle('my-signal');\n\n        $this->assertNull($this->state);\n    }\n}\n"
  },
  {
    "path": "tests/Console/View/ComponentsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Console\\View;\n\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\View\\Components;\nuse Illuminate\\Database\\Migrations\\MigrationResult;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\nuse Symfony\\Component\\Console\\Question\\ChoiceQuestion;\n\nclass ComponentsTest extends TestCase\n{\n    public function testAlert()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Alert($output))->render('The application is in the [production] environment');\n\n        $this->assertStringContainsString(\n            'THE APPLICATION IS IN THE [PRODUCTION] ENVIRONMENT.',\n            $output->fetch()\n        );\n    }\n\n    public function testBulletList()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\BulletList($output))->render([\n            'ls -la',\n            'php artisan inspire',\n        ]);\n\n        $output = $output->fetch();\n\n        $this->assertStringContainsString('⇂ ls -la', $output);\n        $this->assertStringContainsString('⇂ php artisan inspire', $output);\n    }\n\n    public function testSuccess()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Success($output))->render('The application is in the [production] environment');\n\n        $this->assertStringContainsString('SUCCESS  The application is in the [production] environment.', $output->fetch());\n    }\n\n    public function testError()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Error($output))->render('The application is in the [production] environment');\n\n        $this->assertStringContainsString('ERROR  The application is in the [production] environment.', $output->fetch());\n    }\n\n    public function testInfo()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Info($output))->render('The application is in the [production] environment');\n\n        $this->assertStringContainsString('INFO  The application is in the [production] environment.', $output->fetch());\n    }\n\n    public function testConfirm()\n    {\n        $output = m::mock(OutputStyle::class);\n\n        $output->shouldReceive('confirm')\n            ->with('Question?', false)\n            ->once()\n            ->andReturnTrue();\n\n        $result = (new Components\\Confirm($output))->render('Question?');\n        $this->assertTrue($result);\n\n        $output->shouldReceive('confirm')\n            ->with('Question?', true)\n            ->once()\n            ->andReturnTrue();\n\n        $result = (new Components\\Confirm($output))->render('Question?', true);\n        $this->assertTrue($result);\n    }\n\n    public function testChoice()\n    {\n        $output = m::mock(OutputStyle::class);\n\n        $output->shouldReceive('askQuestion')\n            ->with(m::type(ChoiceQuestion::class))\n            ->once()\n            ->andReturn('a');\n\n        $result = (new Components\\Choice($output))->render('Question?', ['a', 'b']);\n        $this->assertSame('a', $result);\n    }\n\n    public function testTask()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Task($output))->render('My task', fn () => MigrationResult::Success->value);\n        $result = $output->fetch();\n        $this->assertStringContainsString('My task', $result);\n        $this->assertStringContainsString('DONE', $result);\n\n        (new Components\\Task($output))->render('My task', fn () => MigrationResult::Failure->value);\n        $result = $output->fetch();\n        $this->assertStringContainsString('My task', $result);\n        $this->assertStringContainsString('FAIL', $result);\n\n        (new Components\\Task($output))->render('My task', fn () => MigrationResult::Skipped->value);\n        $result = $output->fetch();\n        $this->assertStringContainsString('My task', $result);\n        $this->assertStringContainsString('SKIPPED', $result);\n    }\n\n    public function testTwoColumnDetail()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\TwoColumnDetail($output))->render('First', 'Second');\n        $result = $output->fetch();\n        $this->assertStringContainsString('First', $result);\n        $this->assertStringContainsString('Second', $result);\n    }\n\n    public function testTwoColumnDetailPreservesTrailingPunctuationInValue()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\TwoColumnDetail($output))->render('Key', 'value!');\n        $result = $output->fetch();\n        $this->assertStringContainsString('value!', $result);\n    }\n\n    public function testWarn()\n    {\n        $output = new BufferedOutput();\n\n        (new Components\\Warn($output))->render('The application is in the [production] environment');\n\n        $this->assertStringContainsString('WARN  The application is in the [production] environment.', $output->fetch());\n    }\n}\n"
  },
  {
    "path": "tests/Container/AfterResolvingAttributeCallbackTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Attribute;\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AfterResolvingAttributeCallbackTest extends TestCase\n{\n    public function testCallbackIsCalledAfterDependencyResolutionWithAttribute()\n    {\n        $container = new Container();\n\n        $container->afterResolvingAttribute(ContainerTestOnTenant::class, function (ContainerTestOnTenant $attribute, HasTenantImpl $hasTenantImpl, Container $container) {\n            $hasTenantImpl->onTenant($attribute->tenant);\n        });\n\n        $hasTenantA = $container->make(ContainerTestHasTenantImplPropertyWithTenantA::class);\n        $this->assertInstanceOf(HasTenantImpl::class, $hasTenantA->property);\n        $this->assertEquals(Tenant::TenantA, $hasTenantA->property->tenant);\n\n        $hasTenantB = $container->make(ContainerTestHasTenantImplPropertyWithTenantB::class);\n        $this->assertInstanceOf(HasTenantImpl::class, $hasTenantB->property);\n        $this->assertEquals(Tenant::TenantB, $hasTenantB->property->tenant);\n    }\n\n    public function testCallbackIsCalledAfterClassWithAttributeIsResolved()\n    {\n        $container = new Container();\n\n        $container->afterResolvingAttribute(\n            ContainerTestBootable::class,\n            fn ($_, $instance, Container $container) => method_exists($instance, 'booting') && $container->call([$instance, 'booting'])\n        );\n\n        $instance = $container->make(ContainerTestHasBootable::class);\n\n        $this->assertInstanceOf(ContainerTestHasBootable::class, $instance);\n        $this->assertTrue($instance->hasBooted);\n    }\n\n    public function testCallbackIsCalledAfterClassWithConstructorAndAttributeIsResolved()\n    {\n        $container = new Container();\n\n        $container->afterResolvingAttribute(ContainerTestConfiguresClass::class, function (ContainerTestConfiguresClass $attribute, $class) {\n            $class->value = $attribute->value;\n        });\n\n        $container->when(ContainerTestHasSelfConfiguringAttributeAndConstructor::class)\n            ->needs('$value')\n            ->give('no-the-right-value');\n\n        $instance = $container->make(ContainerTestHasSelfConfiguringAttributeAndConstructor::class);\n\n        $this->assertInstanceOf(ContainerTestHasSelfConfiguringAttributeAndConstructor::class, $instance);\n        $this->assertEquals('the-right-value', $instance->value);\n    }\n\n    public function testCallbackIsCalledOnAppCall()\n    {\n        $container = new Container();\n\n        $container->afterResolvingAttribute(ContainerTestOnTenant::class, function (ContainerTestOnTenant $attribute, HasTenantImpl $hasTenantImpl, Container $container) {\n            $hasTenantImpl->onTenant($attribute->tenant);\n        });\n\n        $tenant = $container->call(function (#[ContainerTestOnTenant(Tenant::TenantA)] HasTenantImpl $property) {\n            return $property->tenant;\n        });\n\n        $this->assertEquals(Tenant::TenantA, $tenant);\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class ContainerTestOnTenant\n{\n    public function __construct(\n        public readonly Tenant $tenant\n    ) {\n    }\n}\n\nenum Tenant\n{\n    case TenantA;\n    case TenantB;\n}\n\nfinal class HasTenantImpl\n{\n    public ?Tenant $tenant = null;\n\n    public function onTenant(Tenant $tenant): void\n    {\n        $this->tenant = $tenant;\n    }\n}\n\nfinal class ContainerTestHasTenantImplPropertyWithTenantA\n{\n    public function __construct(\n        #[ContainerTestOnTenant(Tenant::TenantA)]\n        public readonly HasTenantImpl $property\n    ) {\n    }\n}\n\nfinal class ContainerTestHasTenantImplPropertyWithTenantB\n{\n    public function __construct(\n        #[ContainerTestOnTenant(Tenant::TenantB)]\n        public readonly HasTenantImpl $property\n    ) {\n    }\n}\n\n#[Attribute(Attribute::TARGET_CLASS)]\nfinal class ContainerTestConfiguresClass\n{\n    public function __construct(\n        public readonly string $value\n    ) {\n    }\n}\n\n#[ContainerTestConfiguresClass(value: 'the-right-value')]\nfinal class ContainerTestHasSelfConfiguringAttributeAndConstructor\n{\n    public function __construct(\n        public string $value\n    ) {\n    }\n}\n\n#[Attribute(Attribute::TARGET_CLASS)]\nfinal class ContainerTestBootable\n{\n}\n\n#[ContainerTestBootable]\nfinal class ContainerTestHasBootable\n{\n    public bool $hasBooted = false;\n\n    public function booting(): void\n    {\n        $this->hasBooted = true;\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContainerCallTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Closure;\nuse Error;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass ContainerCallTest extends TestCase\n{\n    public function testCallWithAtSignBasedClassReferencesWithoutMethodThrowsException()\n    {\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Call to undefined function ContainerTestCallStub()');\n\n        $container = new Container;\n        $container->call('ContainerTestCallStub');\n    }\n\n    public function testCallWithAtSignBasedClassReferences()\n    {\n        $container = new Container;\n        $result = $container->call(ContainerTestCallStub::class.'@work', ['foo', 'bar']);\n        $this->assertEquals(['foo', 'bar'], $result);\n\n        $container = new Container;\n        $result = $container->call(ContainerTestCallStub::class.'@inject');\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n\n        $container = new Container;\n        $result = $container->call(ContainerTestCallStub::class.'@inject', ['default' => 'foo']);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('foo', $result[1]);\n\n        $container = new Container;\n        $result = $container->call(ContainerTestCallStub::class, ['foo', 'bar'], 'work');\n        $this->assertEquals(['foo', 'bar'], $result);\n    }\n\n    public function testCallWithCallableArray()\n    {\n        $container = new Container;\n        $stub = new ContainerTestCallStub;\n        $result = $container->call([$stub, 'work'], ['foo', 'bar']);\n        $this->assertEquals(['foo', 'bar'], $result);\n    }\n\n    public function testCallWithStaticMethodNameString()\n    {\n        $container = new Container;\n        $result = $container->call('Illuminate\\Tests\\Container\\ContainerStaticMethodStub::inject');\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n    }\n\n    public function testCallWithGlobalMethodName()\n    {\n        $container = new Container;\n        $result = $container->call('Illuminate\\Tests\\Container\\containerTestInject');\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n    }\n\n    public function testCallWithBoundMethod()\n    {\n        $container = new Container;\n        $container->bindMethod(ContainerTestCallStub::class.'@unresolvable', function ($stub) {\n            return $stub->unresolvable('foo', 'bar');\n        });\n        $result = $container->call(ContainerTestCallStub::class.'@unresolvable');\n        $this->assertEquals(['foo', 'bar'], $result);\n\n        $container = new Container;\n        $container->bindMethod(ContainerTestCallStub::class.'@unresolvable', function ($stub) {\n            return $stub->unresolvable('foo', 'bar');\n        });\n        $result = $container->call([new ContainerTestCallStub, 'unresolvable']);\n        $this->assertEquals(['foo', 'bar'], $result);\n\n        $container = new Container;\n        $result = $container->call([new ContainerTestCallStub, 'inject'], ['_stub' => 'foo', 'default' => 'bar']);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('bar', $result[1]);\n\n        $container = new Container;\n        $result = $container->call([new ContainerTestCallStub, 'inject'], ['_stub' => 'foo']);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n    }\n\n    public function testBindMethodAcceptsAnArray()\n    {\n        $container = new Container;\n        $container->bindMethod([ContainerTestCallStub::class, 'unresolvable'], function ($stub) {\n            return $stub->unresolvable('foo', 'bar');\n        });\n        $result = $container->call(ContainerTestCallStub::class.'@unresolvable');\n        $this->assertEquals(['foo', 'bar'], $result);\n\n        $container = new Container;\n        $container->bindMethod([ContainerTestCallStub::class, 'unresolvable'], function ($stub) {\n            return $stub->unresolvable('foo', 'bar');\n        });\n        $result = $container->call([new ContainerTestCallStub, 'unresolvable']);\n        $this->assertEquals(['foo', 'bar'], $result);\n    }\n\n    public function testClosureCallWithInjectedDependency()\n    {\n        $container = new Container;\n        $container->call(function (ContainerCallConcreteStub $stub) {\n            //\n        }, ['foo' => 'bar']);\n\n        $container->call(function (ContainerCallConcreteStub $stub) {\n            //\n        }, ['foo' => 'bar', 'stub' => new ContainerCallConcreteStub]);\n    }\n\n    public function testCallWithDependencies()\n    {\n        $container = new Container;\n        $result = $container->call(function (stdClass $foo, $bar = []) {\n            return func_get_args();\n        });\n\n        $this->assertInstanceOf(stdClass::class, $result[0]);\n        $this->assertEquals([], $result[1]);\n\n        $result = $container->call(function (stdClass $foo, $bar = []) {\n            return func_get_args();\n        }, ['bar' => 'taylor']);\n\n        $this->assertInstanceOf(stdClass::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n\n        $stub = new ContainerCallConcreteStub;\n        $result = $container->call(function (stdClass $foo, ContainerCallConcreteStub $bar) {\n            return func_get_args();\n        }, [ContainerCallConcreteStub::class => $stub]);\n\n        $this->assertInstanceOf(stdClass::class, $result[0]);\n        $this->assertSame($stub, $result[1]);\n\n        // Wrap a function...\n        $result = $container->wrap(function (stdClass $foo, $bar = []) {\n            return func_get_args();\n        }, ['bar' => 'taylor']);\n\n        $this->assertInstanceOf(Closure::class, $result);\n        $result = $result();\n\n        $this->assertInstanceOf(stdClass::class, $result[0]);\n        $this->assertSame('taylor', $result[1]);\n    }\n\n    public function testCallWithVariadicDependency()\n    {\n        $stub1 = new ContainerCallConcreteStub;\n        $stub2 = new ContainerCallConcreteStub;\n\n        $container = new Container;\n        $container->bind(ContainerCallConcreteStub::class, function () use ($stub1, $stub2) {\n            return [\n                $stub1,\n                $stub2,\n            ];\n        });\n\n        $result = $container->call(function (stdClass $foo, ContainerCallConcreteStub ...$bar) {\n            return func_get_args();\n        });\n\n        $this->assertInstanceOf(stdClass::class, $result[0]);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[1]);\n        $this->assertSame($stub1, $result[1]);\n        $this->assertSame($stub2, $result[2]);\n    }\n\n    public function testCallWithCallableObject()\n    {\n        $container = new Container;\n        $callable = new ContainerCallCallableStub;\n        $result = $container->call($callable);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('jeffrey', $result[1]);\n    }\n\n    public function testCallWithCallableClassString()\n    {\n        $container = new Container;\n        $result = $container->call(ContainerCallCallableClassStringStub::class);\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result[0]);\n        $this->assertSame('jeffrey', $result[1]);\n        $this->assertInstanceOf(ContainerTestCallStub::class, $result[2]);\n    }\n\n    public function testCallWithoutRequiredParamsThrowsException()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Unable to resolve dependency [Parameter #0 [ <required> $foo ]] in class Illuminate\\Tests\\Container\\ContainerTestCallStub');\n\n        $container = new Container;\n        $container->call(ContainerTestCallStub::class.'@unresolvable');\n    }\n\n    public function testCallWithUnnamedParametersThrowsException()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Unable to resolve dependency [Parameter #0 [ <required> $foo ]] in class Illuminate\\Tests\\Container\\ContainerTestCallStub');\n\n        $container = new Container;\n        $container->call([new ContainerTestCallStub, 'unresolvable'], ['foo', 'bar']);\n    }\n\n    public function testCallWithoutRequiredParamsOnClosureThrowsException()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Unable to resolve dependency [Parameter #0 [ <required> $foo ]] in class Illuminate\\Tests\\Container\\ContainerCallTest');\n\n        $container = new Container;\n        $container->call(function ($foo, $bar = 'default') {\n            return $foo;\n        });\n    }\n\n    public function testCallWithNullableClassParameterDefaultValue()\n    {\n        $container = new Container;\n\n        $result = $container->call(function (?ContainerCallConcreteStub $stub = null) {\n            return $stub;\n        });\n\n        $this->assertNull($result);\n    }\n\n    public function testCallWithNullableClassParameterDefaultValueWithBinding()\n    {\n        $container = new Container;\n        $container->bind(ContainerCallConcreteStub::class);\n\n        $result = $container->call(function (?ContainerCallConcreteStub $stub = null) {\n            return $stub;\n        });\n\n        $this->assertInstanceOf(ContainerCallConcreteStub::class, $result);\n    }\n}\n\nclass ContainerTestCallStub\n{\n    public function work()\n    {\n        return func_get_args();\n    }\n\n    public function inject(ContainerCallConcreteStub $stub, $default = 'taylor')\n    {\n        return func_get_args();\n    }\n\n    public function unresolvable($foo, $bar)\n    {\n        return func_get_args();\n    }\n}\n\nclass ContainerCallConcreteStub\n{\n    //\n}\n\nfunction containerTestInject(ContainerCallConcreteStub $stub, $default = 'taylor')\n{\n    return func_get_args();\n}\n\nclass ContainerStaticMethodStub\n{\n    public static function inject(ContainerCallConcreteStub $stub, $default = 'taylor')\n    {\n        return func_get_args();\n    }\n}\n\nclass ContainerCallCallableStub\n{\n    public function __invoke(ContainerCallConcreteStub $stub, $default = 'jeffrey')\n    {\n        return func_get_args();\n    }\n}\n\nclass ContainerCallCallableClassStringStub\n{\n    public $stub;\n\n    public $default;\n\n    public function __construct(ContainerCallConcreteStub $stub, $default = 'jeffrey')\n    {\n        $this->stub = $stub;\n        $this->default = $default;\n    }\n\n    public function __invoke(ContainerTestCallStub $dependency)\n    {\n        return [$this->stub, $this->default, $dependency];\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContainerExtendTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass ContainerExtendTest extends TestCase\n{\n    public function testExtendedBindings()\n    {\n        $container = new Container;\n        $container['foo'] = 'foo';\n        $container->extend('foo', function ($old, $container) {\n            return $old.'bar';\n        });\n\n        $this->assertSame('foobar', $container->make('foo'));\n\n        $container = new Container;\n\n        $container->singleton('foo', function () {\n            return (object) ['name' => 'taylor'];\n        });\n        $container->extend('foo', function ($old, $container) {\n            $old->age = 26;\n\n            return $old;\n        });\n\n        $result = $container->make('foo');\n\n        $this->assertSame('taylor', $result->name);\n        $this->assertEquals(26, $result->age);\n        $this->assertSame($result, $container->make('foo'));\n    }\n\n    public function testExtendInstancesArePreserved()\n    {\n        $container = new Container;\n        $container->bind('foo', function () {\n            $obj = new stdClass;\n            $obj->foo = 'bar';\n\n            return $obj;\n        });\n\n        $obj = new stdClass;\n        $obj->foo = 'foo';\n        $container->instance('foo', $obj);\n        $container->extend('foo', function ($obj, $container) {\n            $obj->bar = 'baz';\n\n            return $obj;\n        });\n        $container->extend('foo', function ($obj, $container) {\n            $obj->baz = 'foo';\n\n            return $obj;\n        });\n\n        $this->assertSame('foo', $container->make('foo')->foo);\n        $this->assertSame('baz', $container->make('foo')->bar);\n        $this->assertSame('foo', $container->make('foo')->baz);\n    }\n\n    public function testExtendIsLazyInitialized()\n    {\n        ContainerLazyExtendStub::$initialized = false;\n\n        $container = new Container;\n        $container->bind(ContainerLazyExtendStub::class);\n        $container->extend(ContainerLazyExtendStub::class, function ($obj, $container) {\n            $obj->init();\n\n            return $obj;\n        });\n        $this->assertFalse(ContainerLazyExtendStub::$initialized);\n        $container->make(ContainerLazyExtendStub::class);\n        $this->assertTrue(ContainerLazyExtendStub::$initialized);\n    }\n\n    public function testExtendCanBeCalledBeforeBind()\n    {\n        $container = new Container;\n        $container->extend('foo', function ($old, $container) {\n            return $old.'bar';\n        });\n        $container['foo'] = 'foo';\n\n        $this->assertSame('foobar', $container->make('foo'));\n    }\n\n    public function testExtendInstanceRebindingCallback()\n    {\n        $_SERVER['_test_rebind'] = false;\n\n        $container = new Container;\n        $container->rebinding('foo', function () {\n            $_SERVER['_test_rebind'] = true;\n        });\n\n        $obj = new stdClass;\n        $container->instance('foo', $obj);\n\n        $container->extend('foo', function ($obj, $container) {\n            return $obj;\n        });\n\n        $this->assertTrue($_SERVER['_test_rebind']);\n    }\n\n    public function testExtendBindRebindingCallback()\n    {\n        $_SERVER['_test_rebind'] = false;\n\n        $container = new Container;\n        $container->rebinding('foo', function () {\n            $_SERVER['_test_rebind'] = true;\n        });\n        $container->bind('foo', function () {\n            return new stdClass;\n        });\n\n        $this->assertFalse($_SERVER['_test_rebind']);\n\n        $container->make('foo');\n\n        $container->extend('foo', function ($obj, $container) {\n            return $obj;\n        });\n\n        $this->assertTrue($_SERVER['_test_rebind']);\n    }\n\n    public function testExtensionWorksOnAliasedBindings()\n    {\n        $container = new Container;\n        $container->singleton('something', function () {\n            return 'some value';\n        });\n        $container->alias('something', 'something-alias');\n        $container->extend('something-alias', function ($value) {\n            return $value.' extended';\n        });\n\n        $this->assertSame('some value extended', $container->make('something'));\n    }\n\n    public function testMultipleExtends()\n    {\n        $container = new Container;\n        $container['foo'] = 'foo';\n        $container->extend('foo', function ($old, $container) {\n            return $old.'bar';\n        });\n        $container->extend('foo', function ($old, $container) {\n            return $old.'baz';\n        });\n\n        $this->assertSame('foobarbaz', $container->make('foo'));\n    }\n\n    public function testUnsetExtend()\n    {\n        $container = new Container;\n        $container->bind('foo', function () {\n            $obj = new stdClass;\n            $obj->foo = 'bar';\n\n            return $obj;\n        });\n\n        $container->extend('foo', function ($obj, $container) {\n            $obj->bar = 'baz';\n\n            return $obj;\n        });\n\n        unset($container['foo']);\n        $container->forgetExtenders('foo');\n\n        $container->bind('foo', function () {\n            return 'foo';\n        });\n\n        $this->assertSame('foo', $container->make('foo'));\n    }\n\n    public function testExtendContextualBinding()\n    {\n        $container = new Container();\n        $container->when(ContainerExtendConsumesInterfaceStub::class)\n            ->needs(ContainerExtendInterfaceStub::class)\n            ->give(fn () => new ContainerExtendInterfaceImplementationStub('foo'));\n\n        $container->extend(ContainerExtendInterfaceStub::class, function ($instance) {\n            self::assertInstanceOf(ContainerExtendInterfaceImplementationStub::class, $instance);\n            self::assertSame('foo', $instance->value);\n\n            return new ContainerExtendInterfaceImplementationStub('bar');\n        });\n\n        self::assertSame('bar', $container->make(ContainerExtendConsumesInterfaceStub::class)->stub->value);\n    }\n\n    // https://github.com/laravel/framework/issues/53501\n    public function testExtendContextualBindingAfterResolution()\n    {\n        $container = new Container();\n        $container->when(ContainerExtendConsumesInterfaceStub::class)\n            ->needs(ContainerExtendInterfaceStub::class)\n            ->give(fn () => new ContainerExtendInterfaceImplementationStub('foo'));\n\n        $container->make(ContainerExtendConsumesInterfaceStub::class);\n\n        $container->extend(ContainerExtendInterfaceStub::class, function ($instance) {\n            self::assertInstanceOf(ContainerExtendInterfaceImplementationStub::class, $instance);\n            self::assertSame('foo', $instance->value);\n\n            return new ContainerExtendInterfaceImplementationStub('bar');\n        });\n\n        self::assertSame('bar', $container->make(ContainerExtendConsumesInterfaceStub::class)->stub->value);\n    }\n}\n\nclass ContainerLazyExtendStub\n{\n    public static $initialized = false;\n\n    public function init()\n    {\n        static::$initialized = true;\n    }\n}\n\ninterface ContainerExtendInterfaceStub\n{\n}\n\nclass ContainerExtendInterfaceImplementationStub implements ContainerExtendInterfaceStub\n{\n    public function __construct(\n        public string $value,\n    ) {\n    }\n}\n\nclass ContainerExtendConsumesInterfaceStub\n{\n    public function __construct(\n        public ContainerExtendInterfaceStub $stub,\n    ) {\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContainerResolveNonInstantiableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ContainerResolveNonInstantiableTest extends TestCase\n{\n    public function testResolvingNonInstantiableWithDefaultRemovesWiths()\n    {\n        $container = new Container;\n        $object = $container->make(ParentClass::class, ['i' => 42]);\n\n        $this->assertSame(42, $object->i);\n    }\n\n    public function testResolvingNonInstantiableWithVariadicRemovesWiths()\n    {\n        $container = new Container;\n        $parent = $container->make(VariadicParentClass::class, ['i' => 42]);\n\n        $this->assertCount(0, $parent->child->objects);\n        $this->assertSame(42, $parent->i);\n    }\n\n    public function testResolveVariadicPrimitive()\n    {\n        $container = new Container;\n        $parent = $container->make(VariadicPrimitive::class);\n\n        $this->assertSame($parent->params, []);\n    }\n}\n\ninterface TestInterface\n{\n}\n\nclass ParentClass\n{\n    /**\n     * @var int\n     */\n    public $i;\n\n    public function __construct(?TestInterface $testObject = null, int $i = 0)\n    {\n        $this->i = $i;\n    }\n}\n\nclass VariadicParentClass\n{\n    /**\n     * @var \\Illuminate\\Tests\\Container\\ChildClass\n     */\n    public $child;\n\n    /**\n     * @var int\n     */\n    public $i;\n\n    public function __construct(ChildClass $child, int $i = 0)\n    {\n        $this->child = $child;\n        $this->i = $i;\n    }\n}\n\nclass ChildClass\n{\n    /**\n     * @var array\n     */\n    public $objects;\n\n    public function __construct(TestInterface ...$objects)\n    {\n        $this->objects = $objects;\n    }\n}\n\nclass VariadicPrimitive\n{\n    /**\n     * @var array\n     */\n    public $params;\n\n    public function __construct(...$params)\n    {\n        $this->params = $params;\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContainerTaggingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ContainerTaggingTest extends TestCase\n{\n    public function testContainerTags()\n    {\n        $container = new Container;\n        $container->tag(ContainerImplementationTaggedStub::class, 'foo', 'bar');\n        $container->tag(ContainerImplementationTaggedStubTwo::class, ['foo']);\n\n        $this->assertCount(1, $container->tagged('bar'));\n        $this->assertCount(2, $container->tagged('foo'));\n\n        $fooResults = [];\n        foreach ($container->tagged('foo') as $foo) {\n            $fooResults[] = $foo;\n        }\n\n        $barResults = [];\n        foreach ($container->tagged('bar') as $bar) {\n            $barResults[] = $bar;\n        }\n\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $fooResults[0]);\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $barResults[0]);\n        $this->assertInstanceOf(ContainerImplementationTaggedStubTwo::class, $fooResults[1]);\n\n        $container = new Container;\n        $container->tag([ContainerImplementationTaggedStub::class, ContainerImplementationTaggedStubTwo::class], ['foo']);\n        $this->assertCount(2, $container->tagged('foo'));\n\n        $fooResults = [];\n        foreach ($container->tagged('foo') as $foo) {\n            $fooResults[] = $foo;\n        }\n\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $fooResults[0]);\n        $this->assertInstanceOf(ContainerImplementationTaggedStubTwo::class, $fooResults[1]);\n\n        $this->assertCount(0, $container->tagged('this_tag_does_not_exist'));\n    }\n\n    public function testTaggedServicesAreLazyLoaded()\n    {\n        $container = $this->createPartialMock(Container::class, ['make']);\n        $container->expects($this->once())->method('make')->willReturn(new ContainerImplementationTaggedStub);\n\n        $container->tag(ContainerImplementationTaggedStub::class, ['foo']);\n        $container->tag(ContainerImplementationTaggedStubTwo::class, ['foo']);\n\n        $fooResults = [];\n        foreach ($container->tagged('foo') as $foo) {\n            $fooResults[] = $foo;\n            break;\n        }\n\n        $this->assertCount(2, $container->tagged('foo'));\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $fooResults[0]);\n    }\n\n    public function testLazyLoadedTaggedServicesCanBeLoopedOverMultipleTimes()\n    {\n        $container = new Container;\n        $container->tag(ContainerImplementationTaggedStub::class, 'foo');\n        $container->tag(ContainerImplementationTaggedStubTwo::class, ['foo']);\n\n        $services = $container->tagged('foo');\n\n        $fooResults = [];\n        foreach ($services as $foo) {\n            $fooResults[] = $foo;\n        }\n\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $fooResults[0]);\n        $this->assertInstanceOf(ContainerImplementationTaggedStubTwo::class, $fooResults[1]);\n\n        $fooResults = [];\n        foreach ($services as $foo) {\n            $fooResults[] = $foo;\n        }\n\n        $this->assertInstanceOf(ContainerImplementationTaggedStub::class, $fooResults[0]);\n        $this->assertInstanceOf(ContainerImplementationTaggedStubTwo::class, $fooResults[1]);\n    }\n}\n\ninterface IContainerTaggedContractStub\n{\n    //\n}\n\nclass ContainerImplementationTaggedStub implements IContainerTaggedContractStub\n{\n    //\n}\n\nclass ContainerImplementationTaggedStubTwo implements IContainerTaggedContractStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Container/ContainerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Attribute;\nuse Illuminate\\Container\\Attributes\\Bind;\nuse Illuminate\\Container\\Attributes\\Scoped;\nuse Illuminate\\Container\\Attributes\\Singleton;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Container\\EntryNotFoundException;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse Illuminate\\Contracts\\Container\\SelfBuilding;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Container\\ContainerExceptionInterface;\nuse stdClass;\nuse TypeError;\n\nclass ContainerTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testContainerSingleton()\n    {\n        $container = Container::setInstance(new Container);\n\n        $this->assertSame($container, Container::getInstance());\n\n        Container::setInstance(null);\n\n        $container2 = Container::getInstance();\n\n        $this->assertInstanceOf(Container::class, $container2);\n        $this->assertNotSame($container, $container2);\n    }\n\n    public function testClosureResolution()\n    {\n        $container = new Container;\n        $container->bind('name', function () {\n            return 'Taylor';\n        });\n        $this->assertSame('Taylor', $container->make('name'));\n    }\n\n    public function testAbstractCanBeBoundFromConcreteReturnType()\n    {\n        $container = new Container;\n        $container->bind(function (): IContainerContractStub|ContainerImplementationStub {\n            return new ContainerImplementationStub;\n        });\n        $container->singleton(function (): ContainerConcreteStub {\n            return new ContainerConcreteStub;\n        });\n\n        $this->assertInstanceOf(\n            IContainerContractStub::class,\n            $container->make(IContainerContractStub::class)\n        );\n\n        $this->assertTrue($container->isShared(ContainerConcreteStub::class));\n    }\n\n    public function testBindIfDoesntRegisterIfServiceAlreadyRegistered()\n    {\n        $container = new Container;\n        $container->bind('name', function () {\n            return 'Taylor';\n        });\n        $container->bindIf('name', function () {\n            return 'Dayle';\n        });\n\n        $this->assertSame('Taylor', $container->make('name'));\n    }\n\n    public function testBindIfDoesRegisterIfServiceNotRegisteredYet()\n    {\n        $container = new Container;\n        $container->bind('surname', function () {\n            return 'Taylor';\n        });\n        $container->bindIf('name', function () {\n            return 'Dayle';\n        });\n\n        $this->assertSame('Dayle', $container->make('name'));\n    }\n\n    public function testSingletonIfDoesntRegisterIfBindingAlreadyRegistered()\n    {\n        $container = new Container;\n        $container->singleton('class', function () {\n            return new stdClass;\n        });\n        $firstInstantiation = $container->make('class');\n        $container->singletonIf('class', function () {\n            return new ContainerConcreteStub;\n        });\n        $secondInstantiation = $container->make('class');\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testSingletonIfDoesRegisterIfBindingNotRegisteredYet()\n    {\n        $container = new Container;\n        $container->singleton('class', function () {\n            return new stdClass;\n        });\n        $container->singletonIf('otherClass', function () {\n            return new ContainerConcreteStub;\n        });\n        $firstInstantiation = $container->make('otherClass');\n        $secondInstantiation = $container->make('otherClass');\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testSharedClosureResolution()\n    {\n        $container = new Container;\n        $container->singleton('class', function () {\n            return new stdClass;\n        });\n        $firstInstantiation = $container->make('class');\n        $secondInstantiation = $container->make('class');\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testScopedClosureResolution()\n    {\n        $container = new Container;\n        $container->scoped('class', function () {\n            return new stdClass;\n        });\n        $firstInstantiation = $container->make('class');\n        $secondInstantiation = $container->make('class');\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testScopedBindingsWithClosureReturnType()\n    {\n        $container = new Container;\n        $container->scoped(fn (): stdClass => new stdClass);\n        $container->forgetScopedInstances();\n    }\n\n    public function testScopedIf()\n    {\n        $container = new Container;\n        $container->scopedIf('class', function () {\n            return 'foo';\n        });\n        $this->assertSame('foo', $container->make('class'));\n        $container->scopedIf('class', function () {\n            return 'bar';\n        });\n        $this->assertSame('foo', $container->make('class'));\n        $this->assertNotSame('bar', $container->make('class'));\n    }\n\n    public function testScopedClosureResets()\n    {\n        $container = new Container;\n        $container->scoped('class', function () {\n            return new stdClass;\n        });\n        $firstInstantiation = $container->make('class');\n\n        $container->forgetScopedInstances();\n\n        $secondInstantiation = $container->make('class');\n        $this->assertNotSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testAutoConcreteResolution()\n    {\n        $container = new Container;\n        $this->assertInstanceOf(ContainerConcreteStub::class, $container->make(ContainerConcreteStub::class));\n    }\n\n    public function testSharedConcreteResolution()\n    {\n        $container = new Container;\n        $container->singleton(ContainerConcreteStub::class);\n\n        $var1 = $container->make(ContainerConcreteStub::class);\n        $var2 = $container->make(ContainerConcreteStub::class);\n        $this->assertSame($var1, $var2);\n    }\n\n    public function testScopedConcreteResolutionResets()\n    {\n        $container = new Container;\n        $container->scoped(ContainerConcreteStub::class);\n\n        $var1 = $container->make(ContainerConcreteStub::class);\n\n        $container->forgetScopedInstances();\n\n        $var2 = $container->make(ContainerConcreteStub::class);\n\n        $this->assertNotSame($var1, $var2);\n    }\n\n    public function testBindFailsLoudlyWithInvalidArgument()\n    {\n        $this->expectException(TypeError::class);\n        $container = new Container;\n\n        $concrete = new ContainerConcreteStub;\n        $container->bind(ContainerConcreteStub::class, $concrete);\n    }\n\n    public function testAbstractToConcreteResolution()\n    {\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerImplementationStub::class);\n        $class = $container->make(ContainerDependentStub::class);\n        $this->assertInstanceOf(ContainerImplementationStub::class, $class->impl);\n    }\n\n    public function testNestedDependencyResolution()\n    {\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerImplementationStub::class);\n        $class = $container->make(ContainerNestedDependentStub::class);\n        $this->assertInstanceOf(ContainerDependentStub::class, $class->inner);\n        $this->assertInstanceOf(ContainerImplementationStub::class, $class->inner->impl);\n    }\n\n    public function testContainerIsPassedToResolvers()\n    {\n        $container = new Container;\n        $container->bind('something', function ($c) {\n            return $c;\n        });\n        $c = $container->make('something');\n        $this->assertSame($c, $container);\n    }\n\n    public function testArrayAccess()\n    {\n        $container = new Container;\n        $this->assertFalse(isset($container['something']));\n        $container['something'] = function () {\n            return 'foo';\n        };\n        $this->assertTrue(isset($container['something']));\n        $this->assertNotEmpty($container['something']);\n        $this->assertSame('foo', $container['something']);\n        unset($container['something']);\n        $this->assertFalse(isset($container['something']));\n\n        //test offsetSet when it's not instanceof Closure\n        $container = new Container;\n        $container['something'] = 'text';\n        $this->assertTrue(isset($container['something']));\n        $this->assertNotEmpty($container['something']);\n        $this->assertSame('text', $container['something']);\n        unset($container['something']);\n        $this->assertFalse(isset($container['something']));\n    }\n\n    public function testAliases()\n    {\n        $container = new Container;\n        $container['foo'] = 'bar';\n        $container->alias('foo', 'baz');\n        $container->alias('baz', 'bat');\n        $this->assertSame('bar', $container->make('foo'));\n        $this->assertSame('bar', $container->make('baz'));\n        $this->assertSame('bar', $container->make('bat'));\n    }\n\n    public function testAliasesWithArrayOfParameters()\n    {\n        $container = new Container;\n        $container->bind('foo', function ($app, $config) {\n            return $config;\n        });\n        $container->alias('foo', 'baz');\n        $this->assertEquals([1, 2, 3], $container->make('baz', [1, 2, 3]));\n    }\n\n    public function testBindingsCanBeOverridden()\n    {\n        $container = new Container;\n        $container['foo'] = 'bar';\n        $container['foo'] = 'baz';\n        $this->assertSame('baz', $container['foo']);\n    }\n\n    public function testBindingAnInstanceReturnsTheInstance()\n    {\n        $container = new Container;\n\n        $bound = new stdClass;\n        $resolved = $container->instance('foo', $bound);\n\n        $this->assertSame($bound, $resolved);\n    }\n\n    public function testBindingAnInstanceAsShared()\n    {\n        $container = new Container;\n        $bound = new stdClass;\n        $container->instance('foo', $bound);\n        $object = $container->make('foo');\n        $this->assertSame($bound, $object);\n    }\n\n    public function testResolutionOfDefaultParameters()\n    {\n        $container = new Container;\n        $instance = $container->make(ContainerDefaultValueStub::class);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->stub);\n        $this->assertSame('taylor', $instance->default);\n    }\n\n    public function testResolutionOfClassWithDefaultParameters()\n    {\n        $container = new Container;\n        $instance = $container->make(ContainerClassWithDefaultValueStub::class);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->noDefault);\n        $this->assertSame(null, $instance->default);\n\n        $container->bind(ContainerConcreteStub::class, fn () => new ContainerConcreteStub);\n        $instance = $container->make(ContainerClassWithDefaultValueStub::class);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->default);\n    }\n\n    public function testResolutionOfClassWithDefaultParametersAndContextualBindings()\n    {\n        $container = new Container;\n\n        $container->when(ContainerClassWithDefaultValueStub::class)\n            ->needs(ContainerConcreteStub::class)\n            ->give(fn () => new ContainerConcreteStub);\n        $instance = $container->make(ContainerClassWithDefaultValueStub::class);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->default);\n    }\n\n    public function testBound()\n    {\n        $container = new Container;\n        $container->bind(ContainerConcreteStub::class, function () {\n            //\n        });\n        $this->assertTrue($container->bound(ContainerConcreteStub::class));\n        $this->assertFalse($container->bound(IContainerContractStub::class));\n\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerConcreteStub::class);\n        $this->assertTrue($container->bound(IContainerContractStub::class));\n        $this->assertFalse($container->bound(ContainerConcreteStub::class));\n    }\n\n    public function testUnsetRemoveBoundInstances()\n    {\n        $container = new Container;\n        $container->instance('object', new stdClass);\n        unset($container['object']);\n\n        $this->assertFalse($container->bound('object'));\n    }\n\n    public function testBoundInstanceAndAliasCheckViaArrayAccess()\n    {\n        $container = new Container;\n        $container->instance('object', new stdClass);\n        $container->alias('object', 'alias');\n\n        $this->assertTrue(isset($container['object']));\n        $this->assertTrue(isset($container['alias']));\n    }\n\n    public function testReboundListeners()\n    {\n        unset($_SERVER['__test.rebind']);\n\n        $container = new Container;\n        $container->bind('foo', function () {\n            //\n        });\n        $container->rebinding('foo', function () {\n            $_SERVER['__test.rebind'] = true;\n        });\n        $container->bind('foo', function () {\n            //\n        });\n\n        $this->assertTrue($_SERVER['__test.rebind']);\n    }\n\n    public function testReboundListenersOnInstances()\n    {\n        unset($_SERVER['__test.rebind']);\n\n        $container = new Container;\n        $container->instance('foo', function () {\n            //\n        });\n        $container->rebinding('foo', function () {\n            $_SERVER['__test.rebind'] = true;\n        });\n        $container->instance('foo', function () {\n            //\n        });\n\n        $this->assertTrue($_SERVER['__test.rebind']);\n    }\n\n    public function testReboundListenersOnInstancesOnlyFiresIfWasAlreadyBound()\n    {\n        $_SERVER['__test.rebind'] = false;\n\n        $container = new Container;\n        $container->rebinding('foo', function () {\n            $_SERVER['__test.rebind'] = true;\n        });\n        $container->instance('foo', function () {\n            //\n        });\n\n        $this->assertFalse($_SERVER['__test.rebind']);\n    }\n\n    public function testInternalClassWithDefaultParameters()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Unresolvable dependency resolving [Parameter #0 [ <required> $first ]] in class Illuminate\\Tests\\Container\\ContainerMixedPrimitiveStub');\n\n        $container = new Container;\n        $container->make(ContainerMixedPrimitiveStub::class, []);\n    }\n\n    public function testBindingResolutionExceptionMessage()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Target [Illuminate\\Tests\\Container\\IContainerContractStub] is not instantiable.');\n\n        $container = new Container;\n        $container->make(IContainerContractStub::class, []);\n    }\n\n    public function testBindingResolutionExceptionMessageIncludesBuildStack()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Target [Illuminate\\Tests\\Container\\IContainerContractStub] is not instantiable while building [Illuminate\\Tests\\Container\\ContainerDependentStub].');\n\n        $container = new Container;\n        $container->make(ContainerDependentStub::class, []);\n    }\n\n    public function testBindingResolutionExceptionMessageWhenClassDoesNotExist()\n    {\n        $this->expectException(BindingResolutionException::class);\n        $this->expectExceptionMessage('Target class [Foo\\Bar\\Baz\\DummyClass] does not exist.');\n\n        $container = new Container;\n        $container->build('Foo\\Bar\\Baz\\DummyClass');\n    }\n\n    public function testForgetInstanceForgetsInstance()\n    {\n        $container = new Container;\n        $containerConcreteStub = new ContainerConcreteStub;\n        $container->instance(ContainerConcreteStub::class, $containerConcreteStub);\n        $this->assertTrue($container->isShared(ContainerConcreteStub::class));\n        $container->forgetInstance(ContainerConcreteStub::class);\n        $this->assertFalse($container->isShared(ContainerConcreteStub::class));\n    }\n\n    public function testForgetInstancesForgetsAllInstances()\n    {\n        $container = new Container;\n        $containerConcreteStub1 = new ContainerConcreteStub;\n        $containerConcreteStub2 = new ContainerConcreteStub;\n        $containerConcreteStub3 = new ContainerConcreteStub;\n        $container->instance('Instance1', $containerConcreteStub1);\n        $container->instance('Instance2', $containerConcreteStub2);\n        $container->instance('Instance3', $containerConcreteStub3);\n        $this->assertTrue($container->isShared('Instance1'));\n        $this->assertTrue($container->isShared('Instance2'));\n        $this->assertTrue($container->isShared('Instance3'));\n        $container->forgetInstances();\n        $this->assertFalse($container->isShared('Instance1'));\n        $this->assertFalse($container->isShared('Instance2'));\n        $this->assertFalse($container->isShared('Instance3'));\n    }\n\n    public function testContainerFlushFlushesAllBindingsAliasesAndResolvedInstances()\n    {\n        $container = new Container;\n        $container->bind('ConcreteStub', function () {\n            return new ContainerConcreteStub;\n        }, true);\n        $container->alias('ConcreteStub', 'ContainerConcreteStub');\n        $container->make('ConcreteStub');\n        $this->assertTrue($container->resolved('ConcreteStub'));\n        $this->assertTrue($container->isAlias('ContainerConcreteStub'));\n        $this->assertArrayHasKey('ConcreteStub', $container->getBindings());\n        $this->assertTrue($container->isShared('ConcreteStub'));\n        $container->flush();\n        $this->assertFalse($container->resolved('ConcreteStub'));\n        $this->assertFalse($container->isAlias('ContainerConcreteStub'));\n        $this->assertEmpty($container->getBindings());\n        $this->assertFalse($container->isShared('ConcreteStub'));\n    }\n\n    public function testResolvedResolvesAliasToBindingNameBeforeChecking()\n    {\n        $container = new Container;\n        $container->bind('ConcreteStub', function () {\n            return new ContainerConcreteStub;\n        }, true);\n        $container->alias('ConcreteStub', 'foo');\n\n        $this->assertFalse($container->resolved('ConcreteStub'));\n        $this->assertFalse($container->resolved('foo'));\n\n        $container->make('ConcreteStub');\n\n        $this->assertTrue($container->resolved('ConcreteStub'));\n        $this->assertTrue($container->resolved('foo'));\n    }\n\n    public function testGetAlias()\n    {\n        $container = new Container;\n        $container->alias('ConcreteStub', 'foo');\n        $this->assertSame('ConcreteStub', $container->getAlias('foo'));\n    }\n\n    public function testCurrentlyResolving()\n    {\n        $container = new Container;\n\n        $container->afterResolvingAttribute(ContainerCurrentResolvingAttribute::class, function ($attr, $instance, $container) {\n            $this->assertEquals(ContainerCurrentResolvingConcrete::class, $container->currentlyResolving());\n        });\n\n        $container->when(ContainerCurrentResolvingConcrete::class)\n            ->needs('$currentlyResolving')\n            ->give(fn ($container) => $container->currentlyResolving());\n\n        $resolved = $container->make(ContainerCurrentResolvingConcrete::class);\n\n        $this->assertEquals(ContainerCurrentResolvingConcrete::class, $resolved->currentlyResolving);\n    }\n\n    public function testGetAliasRecursive()\n    {\n        $container = new Container;\n        $container->alias('ConcreteStub', 'foo');\n        $container->alias('foo', 'bar');\n        $container->alias('bar', 'baz');\n        $this->assertSame('ConcreteStub', $container->getAlias('baz'));\n        $this->assertTrue($container->isAlias('baz'));\n        $this->assertTrue($container->isAlias('bar'));\n        $this->assertTrue($container->isAlias('foo'));\n    }\n\n    public function testItThrowsExceptionWhenAbstractIsSameAsAlias()\n    {\n        $this->expectException('LogicException');\n        $this->expectExceptionMessage('[name] is aliased to itself.');\n\n        $container = new Container;\n        $container->alias('name', 'name');\n    }\n\n    public function testContainerGetFactory()\n    {\n        $container = new Container;\n        $container->bind('name', function () {\n            return 'Taylor';\n        });\n\n        $factory = $container->factory('name');\n        $this->assertEquals($container->make('name'), $factory());\n    }\n\n    public function testMakeWithMethodIsAnAliasForMakeMethod()\n    {\n        $mock = $this->getMockBuilder(Container::class)\n            ->onlyMethods(['make'])\n            ->getMock();\n\n        $mock->expects($this->once())\n            ->method('make')\n            ->with(ContainerDefaultValueStub::class, ['default' => 'laurence'])\n            ->willReturn(new stdClass);\n\n        $result = $mock->makeWith(ContainerDefaultValueStub::class, ['default' => 'laurence']);\n\n        $this->assertInstanceOf(stdClass::class, $result);\n    }\n\n    public function testResolvingWithArrayOfParameters()\n    {\n        $container = new Container;\n        $instance = $container->make(ContainerDefaultValueStub::class, ['default' => 'adam']);\n        $this->assertSame('adam', $instance->default);\n\n        $instance = $container->make(ContainerDefaultValueStub::class);\n        $this->assertSame('taylor', $instance->default);\n\n        $container->bind('foo', function ($app, $config) {\n            return $config;\n        });\n\n        $this->assertEquals([1, 2, 3], $container->make('foo', [1, 2, 3]));\n    }\n\n    public function testResolvingWithArrayOfMixedParameters()\n    {\n        $container = new Container;\n        $instance = $container->make(ContainerMixedPrimitiveStub::class, ['first' => 1, 'last' => 2, 'third' => 3]);\n        $this->assertSame(1, $instance->first);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->stub);\n        $this->assertSame(2, $instance->last);\n        $this->assertFalse(isset($instance->third));\n    }\n\n    public function testResolvingWithUsingAnInterface()\n    {\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerInjectVariableStubWithInterfaceImplementation::class);\n        $instance = $container->make(IContainerContractStub::class, ['something' => 'laurence']);\n        $this->assertSame('laurence', $instance->something);\n    }\n\n    public function testNestedParameterOverride()\n    {\n        $container = new Container;\n        $container->bind('foo', function ($app, $config) {\n            return $app->make('bar', ['name' => 'Taylor']);\n        });\n        $container->bind('bar', function ($app, $config) {\n            return $config;\n        });\n\n        $this->assertEquals(['name' => 'Taylor'], $container->make('foo', ['something']));\n    }\n\n    public function testNestedParametersAreResetForFreshMake()\n    {\n        $container = new Container;\n\n        $container->bind('foo', function ($app, $config) {\n            return $app->make('bar');\n        });\n\n        $container->bind('bar', function ($app, $config) {\n            return $config;\n        });\n\n        $this->assertEquals([], $container->make('foo', ['something']));\n    }\n\n    public function testSingletonBindingsNotRespectedWithMakeParameters()\n    {\n        $container = new Container;\n\n        $container->singleton('foo', function ($app, $config) {\n            return $config;\n        });\n\n        $this->assertEquals(['name' => 'taylor'], $container->make('foo', ['name' => 'taylor']));\n        $this->assertEquals(['name' => 'abigail'], $container->make('foo', ['name' => 'abigail']));\n    }\n\n    public function testCanBuildWithoutParameterStackWithNoConstructors()\n    {\n        $container = new Container;\n        $this->assertInstanceOf(ContainerConcreteStub::class, $container->build(ContainerConcreteStub::class));\n    }\n\n    public function testCanBuildWithoutParameterStackWithConstructors()\n    {\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerImplementationStub::class);\n        $this->assertInstanceOf(ContainerDependentStub::class, $container->build(ContainerDependentStub::class));\n    }\n\n    public function testContainerKnowsEntry()\n    {\n        $container = new Container;\n        $container->bind(IContainerContractStub::class, ContainerImplementationStub::class);\n        $this->assertTrue($container->has(IContainerContractStub::class));\n    }\n\n    public function testContainerCanBindAnyWord()\n    {\n        $container = new Container;\n        $container->bind('Taylor', stdClass::class);\n        $this->assertInstanceOf(stdClass::class, $container->get('Taylor'));\n    }\n\n    public function testContainerCanDynamicallySetService()\n    {\n        $container = new Container;\n        $this->assertFalse(isset($container['name']));\n        $container['name'] = 'Taylor';\n        $this->assertTrue(isset($container['name']));\n        $this->assertSame('Taylor', $container['name']);\n    }\n\n    public function testUnknownEntryThrowsException()\n    {\n        $this->expectException(EntryNotFoundException::class);\n\n        $container = new Container;\n        $container->get('Taylor');\n    }\n\n    public function testBoundEntriesThrowsContainerExceptionWhenNotResolvable()\n    {\n        $this->expectException(ContainerExceptionInterface::class);\n\n        $container = new Container;\n        $container->bind('Taylor', IContainerContractStub::class);\n\n        $container->get('Taylor');\n    }\n\n    public function testContainerCanResolveClasses()\n    {\n        $container = new Container;\n        $class = $container->get(ContainerConcreteStub::class);\n\n        $this->assertInstanceOf(ContainerConcreteStub::class, $class);\n    }\n\n    public function testMethodLevelContextualBinding()\n    {\n        $container = new Container;\n\n        $container->bind(IContainerContractStub::class, ContainerImplementationStubTwo::class);\n\n        $container->when(ContainerContextualBindingCallTarget::class)\n            ->needs(IContainerContractStub::class)\n            ->give(ContainerImplementationStub::class);\n\n        $result = $container->call([new ContainerContextualBindingCallTarget, 'work']);\n\n        $this->assertInstanceOf(ContainerImplementationStub::class, $result);\n    }\n\n    public function testContainerSingletonAttribute()\n    {\n        $container = new Container;\n        $firstInstantiation = $container->get(ContainerSingletonAttribute::class);\n\n        $secondInstantiation = $container->get(ContainerSingletonAttribute::class);\n\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testContainerScopedAttribute()\n    {\n        $container = new Container;\n        $firstInstantiation = $container->get(ContainerScopedAttribute::class);\n        $secondInstantiation = $container->get(ContainerScopedAttribute::class);\n\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n\n        $container->forgetScopedInstances();\n\n        $thirdInstantiation = $container->get(ContainerScopedAttribute::class);\n        $this->assertNotSame($firstInstantiation, $thirdInstantiation);\n    }\n\n    public function testBindInterfaceToSingleton()\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($arr) => true);\n        $firstInstantiation = $container->get(ContainerBindSingletonTestInterface::class);\n        $secondInstantiation = $container->get(ContainerBindSingletonTestInterface::class);\n\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n    }\n\n    public function testBindInterfaceToScoped()\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($arr) => $arr === ['test']);\n        $firstInstantiation = $container->get(ContainerBindScopedTestInterface::class);\n        $secondInstantiation = $container->get(ContainerBindScopedTestInterface::class);\n\n        $this->assertSame($firstInstantiation, $secondInstantiation);\n\n        // With a different environment\n        $container->resolveEnvironmentUsing(fn ($arr) => $arr === ['test2']);\n        $thirdInstantiation = $container->get(ContainerBindScopedTestInterface::class);\n        $this->assertSame($firstInstantiation, $thirdInstantiation);\n\n        $container->forgetScopedInstances();\n\n        $thirdInstantiation = $container->get(ContainerBindScopedTestInterface::class);\n        $this->assertNotSame($firstInstantiation, $thirdInstantiation);\n    }\n\n    public function testWildcardBindingButNoEnvironmentResolveSetThrowsBindingResolutionException(): void\n    {\n        $this->expectException(BindingResolutionException::class);\n        $container = new Container;\n\n        $instance = $container->make(WildcardOnlyInterface::class);\n\n        $this->assertInstanceOf(WildcardConcrete::class, $instance);\n    }\n\n    public function testChecksForMoreSpecificEnvironmentBeforeFallingBackToDefault(): void\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($env) => in_array('prod', $env));\n\n        $instance = $container->make(WildcardAndProdInterface::class);\n\n        $this->assertInstanceOf(ProdConcrete::class, $instance);\n        $container->flush();\n        $container->resolveEnvironmentUsing(fn ($env) => in_array('some_string', $env));\n        $instance = $container->make(WildcardAndProdInterface::class);\n        $this->assertInstanceOf(FallbackConcrete::class, $instance);\n    }\n\n    public function testCanPassAStringForEnvironmentEnvironment(): void\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($env) => in_array('cli', $env));\n\n        $instance = $container->make(CliOnlyInterface::class);\n\n        $this->assertInstanceOf(CliConcrete::class, $instance);\n    }\n\n    public function testAnEmptyEnvironmentListThrowsAnException(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn () => true);\n        $container->make(EmptyEnvInterface::class);\n    }\n\n    public function testContainerBindingsTakePrecedence(): void\n    {\n        $container = new Container;\n        $container->bind(OverrideInterface::class, AltConcrete::class);\n\n        $instance = $container->make(OverrideInterface::class);\n\n        $this->assertInstanceOf(AltConcrete::class, $instance);\n    }\n\n    public function testFlushResetsEnvironmentResolverAndCheckedBindings(): void\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($environments) => in_array('prod', $environments));\n\n        $first = $container->make(MultiEnvInterface::class);\n        $this->assertInstanceOf(ProdConcrete::class, $first);\n\n        $container->flush();\n        $container->resolveEnvironmentUsing(fn (array $environments) => in_array('dev', $environments));\n\n        $second = $container->make(MultiEnvInterface::class);\n        $this->assertInstanceOf(DevConcrete::class, $second);\n    }\n\n    public function testNoMatchingEnvironmentAndNoWildcardThrowsBindingResolutionException(): void\n    {\n        $this->expectException(BindingResolutionException::class);\n\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn () => false);\n\n        $container->make(ProdEnvOnlyInterface::class);\n    }\n\n    public function testScopedSingletonWithBind()\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($environments) => true);\n\n        $original = $container->make(IsScoped::class);\n        $new = $container->make(IsScoped::class);\n\n        $this->assertSame($original, $new);\n        $container->forgetScopedInstances();\n        $this->assertNotSame($original, $container->make(IsScoped::class));\n    }\n\n    public function testSingletonWithBind()\n    {\n        $container = new Container;\n        $container->resolveEnvironmentUsing(fn ($environments) => true);\n\n        $original = $container->make(IsSingleton::class);\n        $new = $container->make(IsSingleton::class);\n\n        $this->assertSame($original, $new);\n    }\n\n    public function testWithFactoryHasDependency()\n    {\n        $container = new Container;\n        $_SERVER['__withFactory.email'] = 'taylor@laravel.com';\n        $_SERVER['__withFactory.userId'] = 999;\n\n        $container->bind(RequestDtoDependencyContract::class, RequestDtoDependency::class);\n        $r = $container->make(RequestDto::class);\n\n        $this->assertInstanceOf(RequestDto::class, $r);\n        $this->assertEquals(999, $r->userId);\n        $this->assertEquals('taylor@laravel.com', $r->email);\n    }\n\n    // public function testContainerCanCatchCircularDependency()\n    // {\n    //     $this->expectException(\\Illuminate\\Contracts\\Container\\CircularDependencyException::class);\n\n    //     $container = new Container;\n    //     $container->get(CircularAStub::class);\n    // }\n}\n\nclass CircularAStub\n{\n    public function __construct(CircularBStub $b)\n    {\n        //\n    }\n}\n\nclass CircularBStub\n{\n    public function __construct(CircularCStub $c)\n    {\n        //\n    }\n}\n\nclass CircularCStub\n{\n    public function __construct(CircularAStub $a)\n    {\n        //\n    }\n}\n\nclass ContainerConcreteStub\n{\n    //\n}\n\ninterface IContainerContractStub\n{\n    //\n}\n\nclass ContainerImplementationStub implements IContainerContractStub\n{\n    //\n}\n\nclass ContainerImplementationStubTwo implements IContainerContractStub\n{\n    //\n}\n\nclass ContainerDependentStub\n{\n    public $impl;\n\n    public function __construct(IContainerContractStub $impl)\n    {\n        $this->impl = $impl;\n    }\n}\n\nclass ContainerNestedDependentStub\n{\n    public $inner;\n\n    public function __construct(ContainerDependentStub $inner)\n    {\n        $this->inner = $inner;\n    }\n}\n\nclass ContainerDefaultValueStub\n{\n    public $stub;\n    public $default;\n\n    public function __construct(ContainerConcreteStub $stub, $default = 'taylor')\n    {\n        $this->stub = $stub;\n        $this->default = $default;\n    }\n}\n\nclass ContainerClassWithDefaultValueStub\n{\n    public function __construct(\n        public ?ContainerConcreteStub $noDefault,\n        public ?ContainerConcreteStub $default = null,\n    ) {\n    }\n}\n\nclass ContainerMixedPrimitiveStub\n{\n    public $first;\n    public $last;\n    public $stub;\n\n    public function __construct($first, ContainerConcreteStub $stub, $last)\n    {\n        $this->stub = $stub;\n        $this->last = $last;\n        $this->first = $first;\n    }\n}\n\nclass ContainerInjectVariableStub\n{\n    public $something;\n\n    public function __construct(ContainerConcreteStub $concrete, $something)\n    {\n        $this->something = $something;\n    }\n}\n\nclass ContainerInjectVariableStubWithInterfaceImplementation implements IContainerContractStub\n{\n    public $something;\n\n    public function __construct(ContainerConcreteStub $concrete, $something)\n    {\n        $this->something = $something;\n    }\n}\n\nclass ContainerContextualBindingCallTarget\n{\n    public function __construct()\n    {\n    }\n\n    public function work(IContainerContractStub $stub)\n    {\n        return $stub;\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass ContainerCurrentResolvingAttribute implements ContextualAttribute\n{\n    public function resolve()\n    {\n    }\n}\n\nclass ContainerCurrentResolvingConcrete\n{\n    public $currentlyResolving;\n\n    public function __construct(\n        #[ContainerCurrentResolvingAttribute]\n        string $currentlyResolving\n    ) {\n        $this->currentlyResolving = $currentlyResolving;\n    }\n}\n\n#[Singleton]\nclass ContainerSingletonAttribute\n{\n}\n\n#[Scoped]\nclass ContainerScopedAttribute\n{\n}\n\n#[Bind(ContainerSingletonAttribute::class, environments: ['foo', ContainerTestEnvironments::Bar])]\ninterface ContainerBindSingletonTestInterface\n{\n}\n\nenum ContainerTestEnvironments: string\n{\n    case Bar = 'bar';\n}\n\n#[Bind(ContainerScopedAttribute::class, environments: ['test'])]\n#[Bind(ContainerScopedAttribute::class, environments: ['test2'])]\ninterface ContainerBindScopedTestInterface\n{\n}\n\n#[Bind(WildcardConcrete::class)]\ninterface WildcardOnlyInterface\n{\n}\n\nclass WildcardConcrete implements WildcardOnlyInterface\n{\n}\n\n/*\n * The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment.\n */\n#[Bind(FallbackConcrete::class)]\n#[Bind(ProdConcrete::class, environments: 'prod')]\ninterface WildcardAndProdInterface\n{\n}\n\nclass FallbackConcrete implements WildcardAndProdInterface\n{\n}\nclass ProdConcrete implements WildcardAndProdInterface\n{\n}\n\n#[Bind(CliConcrete::class, environments: 'cli')]\ninterface CliOnlyInterface\n{\n}\n\nclass CliConcrete implements CliOnlyInterface\n{\n}\n\n#[Bind(BadConcrete::class, environments: [])]\ninterface EmptyEnvInterface\n{\n}\n\nclass BadConcrete implements EmptyEnvInterface\n{\n}\n\n#[Bind(ProdConcrete::class, environments: 'prod')]\ninterface ProdEnvOnlyInterface\n{\n}\n\n#[Bind(ProdConcrete::class, environments: 'prod')]\n#[Bind(DevConcrete::class, environments: 'dev')]\ninterface MultiEnvInterface\n{\n}\n\nclass DevConcrete implements MultiEnvInterface\n{\n}\n\n#[Bind(OriginalConcrete::class)]\ninterface OverrideInterface\n{\n}\n\nclass OriginalConcrete implements OverrideInterface\n{\n}\n\nclass AltConcrete implements OverrideInterface\n{\n}\n\n#[Bind(IsScopedConcrete::class)]\n#[Scoped]\ninterface IsScoped\n{\n}\n\nclass IsScopedConcrete implements IsScoped\n{\n}\n\n#[Bind(IsScopedConcrete::class)]\n#[Singleton]\ninterface IsSingleton\n{\n}\n\nclass RequestDto implements SelfBuilding\n{\n    public function __construct(\n        public readonly int $userId,\n        public readonly string $email,\n    ) {\n    }\n\n    public static function newInstance(RequestDtoDependencyContract $dependency): self\n    {\n        return new self(\n            $dependency->userId,\n            $_SERVER['__withFactory.email'],\n        );\n    }\n}\n\ninterface RequestDtoDependencyContract\n{\n}\n\nclass RequestDtoDependency implements RequestDtoDependencyContract\n{\n    public int $userId;\n\n    public function __construct()\n    {\n        $this->userId = $_SERVER['__withFactory.userId'];\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContextualAttributeBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Attribute;\nuse Illuminate\\Auth\\AuthManager;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Cache\\Repository as CacheRepository;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Attributes\\Auth;\nuse Illuminate\\Container\\Attributes\\Authenticated;\nuse Illuminate\\Container\\Attributes\\Cache;\nuse Illuminate\\Container\\Attributes\\Config;\nuse Illuminate\\Container\\Attributes\\Context;\nuse Illuminate\\Container\\Attributes\\CurrentUser;\nuse Illuminate\\Container\\Attributes\\Database;\nuse Illuminate\\Container\\Attributes\\Give;\nuse Illuminate\\Container\\Attributes\\Log;\nuse Illuminate\\Container\\Attributes\\RouteParameter;\nuse Illuminate\\Container\\Attributes\\Storage;\nuse Illuminate\\Container\\Attributes\\Tag;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Container\\RewindableGenerator;\nuse Illuminate\\Contracts\\Auth\\Authenticatable as AuthenticatableContract;\nuse Illuminate\\Contracts\\Auth\\Guard as GuardContract;\nuse Illuminate\\Contracts\\Container\\ContextualAttribute;\nuse Illuminate\\Contracts\\Filesystem\\Filesystem;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\DatabaseManager;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Filesystem\\FilesystemManager;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Log\\Context\\Repository as ContextRepository;\nuse Illuminate\\Log\\LogManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass ContextualAttributeBindingTest extends TestCase\n{\n    public function testDependencyCanBeResolvedFromAttributeBinding()\n    {\n        $container = new Container;\n\n        $container->bind(ContainerTestContract::class, fn (): ContainerTestImplB => new ContainerTestImplB);\n        $container->whenHasAttribute(ContainerTestAttributeThatResolvesContractImpl::class, function (ContainerTestAttributeThatResolvesContractImpl $attribute) {\n            return match ($attribute->name) {\n                'A' => new ContainerTestImplA,\n                'B' => new ContainerTestImplB\n            };\n        });\n\n        $classA = $container->make(ContainerTestHasAttributeThatResolvesToImplA::class);\n\n        $this->assertInstanceOf(ContainerTestHasAttributeThatResolvesToImplA::class, $classA);\n        $this->assertInstanceOf(ContainerTestImplA::class, $classA->property);\n\n        $classB = $container->make(ContainerTestHasAttributeThatResolvesToImplB::class);\n\n        $this->assertInstanceOf(ContainerTestHasAttributeThatResolvesToImplB::class, $classB);\n        $this->assertInstanceOf(ContainerTestImplB::class, $classB->property);\n    }\n\n    public function testSimpleDependencyCanBeResolvedCorrectlyFromGiveAttributeBinding()\n    {\n        $container = new Container;\n\n        $container->bind(ContainerTestContract::class, concrete: ContainerTestImplA::class);\n\n        $resolution = $container->make(GiveTestSimple::class);\n\n        $this->assertInstanceOf(SimpleDependency::class, $resolution->dependency);\n    }\n\n    public function testComplexDependencyCanBeResolvedCorrectlyFromGiveAttributeBinding()\n    {\n        $container = new Container;\n\n        $container->bind(ContainerTestContract::class, concrete: ContainerTestImplA::class);\n\n        $resolution = $container->make(GiveTestComplex::class);\n\n        $this->assertInstanceOf(ComplexDependency::class, $resolution->dependency);\n        $this->assertTrue($resolution->dependency->param);\n    }\n\n    public function testScalarDependencyCanBeResolvedFromAttributeBinding()\n    {\n        $container = new Container;\n        $container->singleton('config', fn () => new Repository([\n            'app' => [\n                'timezone' => 'Europe/Paris',\n            ],\n        ]));\n\n        $container->whenHasAttribute(ContainerTestConfigValue::class, function (ContainerTestConfigValue $attribute, Container $container) {\n            return $container->make('config')->get($attribute->key);\n        });\n\n        $class = $container->make(ContainerTestHasConfigValueProperty::class);\n\n        $this->assertInstanceOf(ContainerTestHasConfigValueProperty::class, $class);\n        $this->assertEquals('Europe/Paris', $class->timezone);\n    }\n\n    public function testScalarDependencyCanBeResolvedFromAttributeResolveMethod()\n    {\n        $container = new Container;\n        $container->singleton('config', fn () => new Repository([\n            'app' => [\n                'env' => 'production',\n            ],\n        ]));\n\n        $class = $container->make(ContainerTestHasConfigValueWithResolveProperty::class);\n\n        $this->assertInstanceOf(ContainerTestHasConfigValueWithResolveProperty::class, $class);\n        $this->assertEquals('production', $class->env);\n    }\n\n    public function testDependencyWithAfterCallbackAttributeCanBeResolved()\n    {\n        $container = new Container;\n\n        $class = $container->make(ContainerTestHasConfigValueWithResolvePropertyAndAfterCallback::class);\n\n        $this->assertEquals('Developer', $class->person->role);\n    }\n\n    public function testAuthedAttribute()\n    {\n        $container = new Container;\n        $container->singleton('auth', function () {\n            $manager = m::mock(AuthManager::class);\n            $manager->shouldReceive('userResolver')->andReturn(fn ($guard = null) => $manager->guard($guard)->user());\n            $manager->shouldReceive('guard')->with('foo')->andReturnUsing(function () {\n                $guard = m::mock(GuardContract::class);\n                $guard->shouldReceive('user')->andReturn(m:mock(AuthenticatableContract::class));\n\n                return $guard;\n            });\n            $manager->shouldReceive('guard')->with('bar')->andReturnUsing(function () {\n                $guard = m::mock(GuardContract::class);\n                $guard->shouldReceive('user')->andReturn(m:mock(AuthenticatableContract::class));\n\n                return $guard;\n            });\n\n            return $manager;\n        });\n\n        $container->make(AuthedTest::class);\n    }\n\n    public function testCacheAttribute()\n    {\n        $container = new Container;\n        $container->singleton('cache', function () {\n            $manager = m::mock(CacheManager::class);\n            $manager->shouldReceive('store')->with('foo')->andReturn(m::mock(CacheRepository::class));\n            $manager->shouldReceive('store')->with('bar')->andReturn(m::mock(CacheRepository::class));\n\n            return $manager;\n        });\n\n        $container->make(CacheTest::class);\n    }\n\n    public function testConfigAttribute()\n    {\n        $container = new Container;\n        $container->singleton('config', function () {\n            $repository = m::mock(Repository::class);\n            $repository->shouldReceive('get')->with('foo', null)->andReturn('foo');\n            $repository->shouldReceive('get')->with('bar', null)->andReturn('bar');\n\n            return $repository;\n        });\n\n        $container->make(ConfigTest::class);\n    }\n\n    public function testDatabaseAttribute()\n    {\n        $container = new Container;\n        $container->singleton('db', function () {\n            $manager = m::mock(DatabaseManager::class);\n            $manager->shouldReceive('connection')->with('foo')->andReturn(m::mock(Connection::class));\n            $manager->shouldReceive('connection')->with('bar')->andReturn(m::mock(Connection::class));\n\n            return $manager;\n        });\n\n        $container->make(DatabaseTest::class);\n    }\n\n    public function testAuthAttribute()\n    {\n        $container = new Container; //\n        $container->singleton('auth', function () {\n            $manager = m::mock(AuthManager::class);\n            $manager->shouldReceive('guard')->with('foo')->andReturn(m::mock(GuardContract::class));\n            $manager->shouldReceive('guard')->with('bar')->andReturn(m::mock(GuardContract::class));\n\n            return $manager;\n        });\n\n        $container->make(GuardTest::class);\n    }\n\n    public function testLogAttribute()\n    {\n        $container = new Container;\n        $container->singleton('log', function () {\n            $manager = m::mock(LogManager::class);\n            $manager->shouldReceive('channel')->with('foo')->andReturn(m::mock(LoggerInterface::class));\n            $manager->shouldReceive('channel')->with('bar')->andReturn(m::mock(LoggerInterface::class));\n\n            return $manager;\n        });\n\n        $container->make(LogTest::class);\n    }\n\n    public function testRouteParameterAttribute()\n    {\n        $container = new Container;\n        $container->singleton('request', function () {\n            $request = m::mock(Request::class);\n            $request->shouldReceive('route')->with('foo')->andReturn(m::mock(Model::class));\n            $request->shouldReceive('route')->with('bar')->andReturn('bar');\n\n            return $request;\n        });\n\n        $container->make(RouteParameterTest::class);\n    }\n\n    public function testContextAttribute(): void\n    {\n        $container = new Container;\n\n        $container->singleton(ContextRepository::class, function () {\n            $context = m::mock(ContextRepository::class);\n            $context->shouldReceive('get')->once()->with('foo', null)->andReturn('foo');\n\n            return $context;\n        });\n\n        $container->make(ContextTest::class);\n    }\n\n    public function testContextAttributeInteractingWithHidden(): void\n    {\n        $container = new Container;\n\n        $container->singleton(ContextRepository::class, function () {\n            $context = m::mock(ContextRepository::class);\n            $context->shouldReceive('getHidden')->once()->with('bar', null)->andReturn('bar');\n            $context->shouldNotReceive('get');\n\n            return $context;\n        });\n\n        $container->make(ContextHiddenTest::class);\n    }\n\n    public function testStorageAttribute()\n    {\n        $container = new Container;\n        $container->singleton('filesystem', function () {\n            $manager = m::mock(FilesystemManager::class);\n            $manager->shouldReceive('disk')->with('foo')->andReturn(m::mock(Filesystem::class));\n            $manager->shouldReceive('disk')->with('bar')->andReturn(m::mock(Filesystem::class));\n\n            return $manager;\n        });\n\n        $container->make(StorageTest::class);\n    }\n\n    public function testInjectionWithAttributeOnAppCall()\n    {\n        $container = new Container;\n\n        $person = $container->call(function (ContainerTestHasConfigValueWithResolvePropertyAndAfterCallback $hasAttribute) {\n            return $hasAttribute->person;\n        });\n\n        $this->assertEquals('Taylor', $person->name);\n    }\n\n    public function testAttributeOnAppCall()\n    {\n        $container = new Container;\n        $container->singleton('config', fn () => new Repository([\n            'app' => [\n                'timezone' => 'Europe/Paris',\n                'locale' => null,\n            ],\n        ]));\n\n        $value = $container->call(function (#[Config('app.timezone')] string $value) {\n            return $value;\n        });\n\n        $this->assertEquals('Europe/Paris', $value);\n\n        $value = $container->call(function (#[Config('app.locale')] ?string $value) {\n            return $value;\n        });\n\n        $this->assertNull($value);\n    }\n\n    public function testNestedAttributeOnAppCall()\n    {\n        $container = new Container;\n        $container->singleton('config', fn () => new Repository([\n            'app' => [\n                'timezone' => 'Europe/Paris',\n                'locale' => null,\n            ],\n        ]));\n\n        $value = $container->call(function (TimezoneObject $object) {\n            return $object;\n        });\n\n        $this->assertEquals('Europe/Paris', $value->timezone);\n\n        $value = $container->call(function (LocaleObject $object) {\n            return $object;\n        });\n\n        $this->assertNull($value->locale);\n    }\n\n    public function testTagAttribute()\n    {\n        $container = new Container;\n        $container->bind('one', fn (): int => 1);\n        $container->bind('two', fn (): int => 2);\n        $container->tag(['one', 'two'], 'numbers');\n\n        $value = $container->call(function (#[Tag('numbers')] RewindableGenerator $integers) {\n            return $integers;\n        });\n\n        $this->assertEquals([1, 2], iterator_to_array($value));\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nclass ContainerTestAttributeThatResolvesContractImpl implements ContextualAttribute\n{\n    public function __construct(\n        public readonly string $name\n    ) {\n    }\n}\n\ninterface ContainerTestContract\n{\n}\n\nfinal class ContainerTestImplA implements ContainerTestContract\n{\n}\n\nfinal class ContainerTestImplB implements ContainerTestContract\n{\n}\n\nfinal class ContainerTestHasAttributeThatResolvesToImplA\n{\n    public function __construct(\n        #[ContainerTestAttributeThatResolvesContractImpl('A')]\n        public readonly ContainerTestContract $property\n    ) {\n    }\n}\n\nfinal class ContainerTestHasAttributeThatResolvesToImplB\n{\n    public function __construct(\n        #[ContainerTestAttributeThatResolvesContractImpl('B')]\n        public readonly ContainerTestContract $property\n    ) {\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class ContainerTestConfigValue implements ContextualAttribute\n{\n    public function __construct(\n        public readonly string $key\n    ) {\n    }\n}\n\nfinal class ContainerTestHasConfigValueProperty\n{\n    public function __construct(\n        #[ContainerTestConfigValue('app.timezone')]\n        public string $timezone\n    ) {\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class ContainerTestConfigValueWithResolve implements ContextualAttribute\n{\n    public function __construct(\n        public readonly string $key\n    ) {\n    }\n\n    public function resolve(self $attribute, Container $container): string\n    {\n        return $container->make('config')->get($attribute->key);\n    }\n}\n\nfinal class ContainerTestHasConfigValueWithResolveProperty\n{\n    public function __construct(\n        #[ContainerTestConfigValueWithResolve('app.env')]\n        public string $env\n    ) {\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class ContainerTestConfigValueWithResolveAndAfter implements ContextualAttribute\n{\n    public function resolve(self $attribute, Container $container): object\n    {\n        return (object) ['name' => 'Taylor'];\n    }\n\n    public function after(self $attribute, object $value, Container $container): void\n    {\n        $value->role = 'Developer';\n    }\n}\n\nfinal class ContainerTestHasConfigValueWithResolvePropertyAndAfterCallback\n{\n    public function __construct(\n        #[ContainerTestConfigValueWithResolveAndAfter]\n        public object $person\n    ) {\n    }\n}\n\nfinal class SimpleDependency implements ContainerTestContract\n{\n}\n\nfinal class ComplexDependency implements ContainerTestContract\n{\n    public function __construct(public bool $param)\n    {\n    }\n}\n\nfinal class AuthedTest\n{\n    public function __construct(#[Authenticated('foo')] AuthenticatableContract $foo, #[CurrentUser('bar')] AuthenticatableContract $bar)\n    {\n    }\n}\n\nfinal class CacheTest\n{\n    public function __construct(#[Cache('foo')] CacheRepository $foo, #[Cache('bar')] CacheRepository $bar)\n    {\n    }\n}\n\nfinal class ConfigTest\n{\n    public function __construct(#[Config('foo')] string $foo, #[Config('bar')] string $bar)\n    {\n    }\n}\n\nfinal class ContextTest\n{\n    public function __construct(#[Context('foo')] string $foo)\n    {\n    }\n}\n\nfinal class ContextHiddenTest\n{\n    public function __construct(#[Context('bar', hidden: true)] string $foo)\n    {\n    }\n}\n\nfinal class DatabaseTest\n{\n    public function __construct(#[Database('foo')] Connection $foo, #[Database('bar')] Connection $bar)\n    {\n    }\n}\n\nfinal class GuardTest\n{\n    public function __construct(#[Auth('foo')] GuardContract $foo, #[Auth('bar')] GuardContract $bar)\n    {\n    }\n}\n\nfinal class LogTest\n{\n    public function __construct(#[Log('foo')] LoggerInterface $foo, #[Log('bar')] LoggerInterface $bar)\n    {\n    }\n}\n\nfinal class RouteParameterTest\n{\n    public function __construct(#[RouteParameter('foo')] Model $foo, #[RouteParameter('bar')] string $bar)\n    {\n    }\n}\n\nfinal class StorageTest\n{\n    public function __construct(#[Storage('foo')] Filesystem $foo, #[Storage('bar')] Filesystem $bar)\n    {\n    }\n}\n\nfinal class GiveTestSimple\n{\n    public function __construct(\n        #[Give(SimpleDependency::class)]\n        public readonly ContainerTestContract $dependency\n    ) {\n    }\n}\n\nfinal class GiveTestComplex\n{\n    public function __construct(\n        #[Give(ComplexDependency::class, ['param' => true])]\n        public readonly ContainerTestContract $dependency\n    ) {\n    }\n}\n\nfinal class TimezoneObject\n{\n    public function __construct(\n        #[Config('app.timezone')] public readonly ?string $timezone\n    ) {\n        //\n    }\n}\n\nfinal class LocaleObject\n{\n    public function __construct(\n        #[Config('app.locale')] public readonly ?string $locale\n    ) {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Container/ContextualBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ContextualBindingTest extends TestCase\n{\n    public function testContainerCanInjectDifferentImplementationsDependingOnContext()\n    {\n        $container = new Container;\n\n        $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStub::class);\n        $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $one = $container->make(ContainerTestContextInjectOne::class);\n        $two = $container->make(ContainerTestContextInjectTwo::class);\n\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);\n\n        // Test With Closures\n        $container = new Container;\n\n        $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStub::class);\n        $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(function ($container) {\n            return $container->make(ContainerContextImplementationStubTwo::class);\n        });\n\n        $one = $container->make(ContainerTestContextInjectOne::class);\n        $two = $container->make(ContainerTestContextInjectTwo::class);\n\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);\n\n        // Test nesting to make the same 'abstract' in different context\n        $container = new Container;\n\n        $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(function ($container) {\n            return $container->make(IContainerContextContractStub::class);\n        });\n\n        $one = $container->make(ContainerTestContextInjectOne::class);\n\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);\n    }\n\n    public function testContextualBindingWorksForExistingInstancedBindings()\n    {\n        $container = new Container;\n\n        $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $container->make(ContainerTestContextInjectOne::class)->impl);\n    }\n\n    public function testContextualBindingWorksForNewlyInstancedBindings()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextualBindingWorksOnExistingAliasedInstances()\n    {\n        $container = new Container;\n\n        $container->instance('stub', new ContainerImplementationStub);\n        $container->alias('stub', IContainerContextContractStub::class);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextualBindingWorksOnNewAliasedInstances()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $container->instance('stub', new ContainerImplementationStub);\n        $container->alias('stub', IContainerContextContractStub::class);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextualBindingWorksOnNewAliasedBindings()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $container->bind('stub', ContainerContextImplementationStub::class);\n        $container->alias('stub', IContainerContextContractStub::class);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextualBindingDoesNotFollowStaleAliases()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectOne::class)->needs('stale')->give(ContainerContextImplementationStub::class);\n        $container->when(ContainerTestContextInjectOne::class)->needs('live')->give(ContainerContextImplementationStubTwo::class);\n\n        $container->alias(IContainerContextContractStub::class, 'stale');\n        $container->alias('unrelated', 'stale');\n        $container->alias(IContainerContextContractStub::class, 'live');\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextualBindingWorksForMultipleClasses()\n    {\n        $container = new Container;\n\n        $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);\n\n        $container->when([ContainerTestContextInjectTwo::class, ContainerTestContextInjectThree::class])->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStub::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectTwo::class)->impl\n        );\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectThree::class)->impl\n        );\n    }\n\n    public function testContextualBindingDoesntOverrideNonContextualResolution()\n    {\n        $container = new Container;\n\n        $container->instance('stub', new ContainerContextImplementationStub);\n        $container->alias('stub', IContainerContextContractStub::class);\n\n        $container->when(ContainerTestContextInjectTwo::class)->needs(IContainerContextContractStub::class)->give(ContainerContextImplementationStubTwo::class);\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStubTwo::class,\n            $container->make(ContainerTestContextInjectTwo::class)->impl\n        );\n\n        $this->assertInstanceOf(\n            ContainerContextImplementationStub::class,\n            $container->make(ContainerTestContextInjectOne::class)->impl\n        );\n    }\n\n    public function testContextuallyBoundInstancesAreNotUnnecessarilyRecreated()\n    {\n        ContainerTestContextInjectInstantiations::$instantiations = 0;\n\n        $container = new Container;\n\n        $container->instance(IContainerContextContractStub::class, new ContainerImplementationStub);\n        $container->instance(ContainerTestContextInjectInstantiations::class, new ContainerTestContextInjectInstantiations);\n\n        $this->assertEquals(1, ContainerTestContextInjectInstantiations::$instantiations);\n\n        $container->when(ContainerTestContextInjectOne::class)->needs(IContainerContextContractStub::class)->give(ContainerTestContextInjectInstantiations::class);\n\n        $container->make(ContainerTestContextInjectOne::class);\n        $container->make(ContainerTestContextInjectOne::class);\n        $container->make(ContainerTestContextInjectOne::class);\n        $container->make(ContainerTestContextInjectOne::class);\n\n        $this->assertEquals(1, ContainerTestContextInjectInstantiations::$instantiations);\n    }\n\n    public function testContainerCanInjectSimpleVariable()\n    {\n        $container = new Container;\n        $container->when(ContainerInjectVariableStub::class)->needs('$something')->give(100);\n        $instance = $container->make(ContainerInjectVariableStub::class);\n        $this->assertEquals(100, $instance->something);\n\n        $container = new Container;\n        $container->when(ContainerInjectVariableStub::class)->needs('$something')->give(function ($container) {\n            return $container->make(ContainerConcreteStub::class);\n        });\n        $instance = $container->make(ContainerInjectVariableStub::class);\n        $this->assertInstanceOf(ContainerConcreteStub::class, $instance->something);\n    }\n\n    public function testContextualBindingWorksWithAliasedTargets()\n    {\n        $container = new Container;\n\n        $container->bind(IContainerContextContractStub::class, ContainerContextImplementationStub::class);\n        $container->alias(IContainerContextContractStub::class, 'interface-stub');\n\n        $container->alias(ContainerContextImplementationStub::class, 'stub-1');\n\n        $container->when(ContainerTestContextInjectOne::class)->needs('interface-stub')->give('stub-1');\n        $container->when(ContainerTestContextInjectTwo::class)->needs('interface-stub')->give(ContainerContextImplementationStubTwo::class);\n\n        $one = $container->make(ContainerTestContextInjectOne::class);\n        $two = $container->make(ContainerTestContextInjectTwo::class);\n\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $one->impl);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $two->impl);\n    }\n\n    public function testContextualBindingWorksForNestedOptionalDependencies()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectTwoInstances::class)->needs(ContainerTestContextInjectTwo::class)->give(function () {\n            return new ContainerTestContextInjectTwo(new ContainerContextImplementationStubTwo);\n        });\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectTwoInstances::class);\n        $this->assertInstanceOf(\n            ContainerTestContextWithOptionalInnerDependency::class,\n            $resolvedInstance->implOne\n        );\n        $this->assertNull($resolvedInstance->implOne->inner);\n\n        $this->assertInstanceOf(\n            ContainerTestContextInjectTwo::class,\n            $resolvedInstance->implTwo\n        );\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->implTwo->impl);\n    }\n\n    public function testContextualBindingWorksForVariadicDependencies()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->give(function ($c) {\n            return [\n                $c->make(ContainerContextImplementationStub::class),\n                $c->make(ContainerContextImplementationStubTwo::class),\n            ];\n        });\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);\n\n        $this->assertCount(2, $resolvedInstance->stubs);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);\n    }\n\n    public function testContextualBindingWorksForVariadicDependenciesWithNothingBound()\n    {\n        $container = new Container;\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);\n\n        $this->assertCount(0, $resolvedInstance->stubs);\n    }\n\n    public function testContextualBindingWorksForVariadicAfterNonVariadicDependencies()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectVariadicAfterNonVariadic::class)->needs(IContainerContextContractStub::class)->give(function ($c) {\n            return [\n                $c->make(ContainerContextImplementationStub::class),\n                $c->make(ContainerContextImplementationStubTwo::class),\n            ];\n        });\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadicAfterNonVariadic::class);\n\n        $this->assertCount(2, $resolvedInstance->stubs);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);\n    }\n\n    public function testContextualBindingWorksForVariadicAfterNonVariadicDependenciesWithNothingBound()\n    {\n        $container = new Container;\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadicAfterNonVariadic::class);\n\n        $this->assertCount(0, $resolvedInstance->stubs);\n    }\n\n    public function testContextualBindingWorksForVariadicDependenciesWithoutFactory()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->give([\n            ContainerContextImplementationStub::class,\n            ContainerContextImplementationStubTwo::class,\n        ]);\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);\n\n        $this->assertCount(2, $resolvedInstance->stubs);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);\n    }\n\n    public function testContextualBindingGivesTagsForArrayWithNoTagsDefined()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectArray::class)->needs('$stubs')->giveTagged('stub');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectArray::class);\n\n        $this->assertCount(0, $resolvedInstance->stubs);\n    }\n\n    public function testContextualBindingGivesTagsForVariadicWithNoTagsDefined()\n    {\n        $container = new Container;\n\n        $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->giveTagged('stub');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);\n\n        $this->assertCount(0, $resolvedInstance->stubs);\n    }\n\n    public function testContextualBindingGivesTagsForArray()\n    {\n        $container = new Container;\n\n        $container->tag([\n            ContainerContextImplementationStub::class,\n            ContainerContextImplementationStubTwo::class,\n        ], ['stub']);\n\n        $container->when(ContainerTestContextInjectArray::class)->needs('$stubs')->giveTagged('stub');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectArray::class);\n\n        $this->assertCount(2, $resolvedInstance->stubs);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);\n    }\n\n    public function testContextualBindingGivesTagsForVariadic()\n    {\n        $container = new Container;\n\n        $container->tag([\n            ContainerContextImplementationStub::class,\n            ContainerContextImplementationStubTwo::class,\n        ], ['stub']);\n\n        $container->when(ContainerTestContextInjectVariadic::class)->needs(IContainerContextContractStub::class)->giveTagged('stub');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectVariadic::class);\n\n        $this->assertCount(2, $resolvedInstance->stubs);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $resolvedInstance->stubs[0]);\n        $this->assertInstanceOf(ContainerContextImplementationStubTwo::class, $resolvedInstance->stubs[1]);\n    }\n\n    public function testContextualBindingGivesValuesFromConfigOptionalValueNull()\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'test' => [\n                    'username' => 'laravel',\n                    'password' => 'hunter42',\n                ],\n            ]);\n        });\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$username')\n            ->giveConfig('test.username');\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$password')\n            ->giveConfig('test.password');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);\n\n        $this->assertSame('laravel', $resolvedInstance->username);\n        $this->assertSame('hunter42', $resolvedInstance->password);\n        $this->assertNull($resolvedInstance->alias);\n    }\n\n    public function testContextualBindingGivesValuesFromConfigOptionalValueSet()\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'test' => [\n                    'username' => 'laravel',\n                    'password' => 'hunter42',\n                    'alias' => 'lumen',\n                ],\n            ]);\n        });\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$username')\n            ->giveConfig('test.username');\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$password')\n            ->giveConfig('test.password');\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$alias')\n            ->giveConfig('test.alias');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);\n\n        $this->assertSame('laravel', $resolvedInstance->username);\n        $this->assertSame('hunter42', $resolvedInstance->password);\n        $this->assertSame('lumen', $resolvedInstance->alias);\n    }\n\n    public function testContextualBindingGivesValuesFromConfigWithDefault()\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'test' => [\n                    'password' => 'hunter42',\n                ],\n            ]);\n        });\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$username')\n            ->giveConfig('test.username', 'DEFAULT_USERNAME');\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigIndividualValues::class)\n            ->needs('$password')\n            ->giveConfig('test.password');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigIndividualValues::class);\n\n        $this->assertSame('DEFAULT_USERNAME', $resolvedInstance->username);\n        $this->assertSame('hunter42', $resolvedInstance->password);\n        $this->assertNull($resolvedInstance->alias);\n    }\n\n    public function testContextualBindingGivesValuesFromConfigArray()\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'test' => [\n                    'username' => 'laravel',\n                    'password' => 'hunter42',\n                    'alias' => 'lumen',\n                ],\n            ]);\n        });\n\n        $container\n            ->when(ContainerTestContextInjectFromConfigArray::class)\n            ->needs('$settings')\n            ->giveConfig('test');\n\n        $resolvedInstance = $container->make(ContainerTestContextInjectFromConfigArray::class);\n\n        $this->assertSame('laravel', $resolvedInstance->settings['username']);\n        $this->assertSame('hunter42', $resolvedInstance->settings['password']);\n        $this->assertSame('lumen', $resolvedInstance->settings['alias']);\n    }\n\n    public function testContextualBindingWorksForMethodInvocation()\n    {\n        $container = new Container;\n\n        $container\n            ->when(ContainerTestContextInjectMethodArgument::class)\n            ->needs(IContainerContextContractStub::class)\n            ->give(ContainerContextImplementationStub::class);\n\n        $object = new ContainerTestContextInjectMethodArgument;\n\n        // array callable syntax...\n        $valueResolvedUsingArraySyntax = $container->call([$object, 'method']);\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $valueResolvedUsingArraySyntax);\n\n        // first class callable syntax...\n        $valueResolvedUsingFirstClassSyntax = $container->call($object->method(...));\n        $this->assertInstanceOf(ContainerContextImplementationStub::class, $valueResolvedUsingFirstClassSyntax);\n    }\n}\n\ninterface IContainerContextContractStub\n{\n    //\n}\n\nclass ContainerContextNonContractStub\n{\n    //\n}\n\nclass ContainerContextImplementationStub implements IContainerContextContractStub\n{\n    //\n}\n\nclass ContainerContextImplementationStubTwo implements IContainerContextContractStub\n{\n    //\n}\n\nclass ContainerTestContextInjectInstantiations implements IContainerContextContractStub\n{\n    public static $instantiations;\n\n    public function __construct()\n    {\n        static::$instantiations++;\n    }\n}\n\nclass ContainerTestContextInjectOne\n{\n    public $impl;\n\n    public function __construct(IContainerContextContractStub $impl)\n    {\n        $this->impl = $impl;\n    }\n}\n\nclass ContainerTestContextInjectTwo\n{\n    public $impl;\n\n    public function __construct(IContainerContextContractStub $impl)\n    {\n        $this->impl = $impl;\n    }\n}\n\nclass ContainerTestContextInjectThree\n{\n    public $impl;\n\n    public function __construct(IContainerContextContractStub $impl)\n    {\n        $this->impl = $impl;\n    }\n}\n\nclass ContainerTestContextInjectTwoInstances\n{\n    public $implOne;\n    public $implTwo;\n\n    public function __construct(ContainerTestContextWithOptionalInnerDependency $implOne, ContainerTestContextInjectTwo $implTwo)\n    {\n        $this->implOne = $implOne;\n        $this->implTwo = $implTwo;\n    }\n}\n\nclass ContainerTestContextWithOptionalInnerDependency\n{\n    public $inner;\n\n    public function __construct(?ContainerTestContextInjectOne $inner = null)\n    {\n        $this->inner = $inner;\n    }\n}\n\nclass ContainerTestContextInjectArray\n{\n    public $stubs;\n\n    public function __construct(array $stubs)\n    {\n        $this->stubs = $stubs;\n    }\n}\n\nclass ContainerTestContextInjectVariadic\n{\n    public $stubs;\n\n    public function __construct(IContainerContextContractStub ...$stubs)\n    {\n        $this->stubs = $stubs;\n    }\n}\n\nclass ContainerTestContextInjectVariadicAfterNonVariadic\n{\n    public $other;\n    public $stubs;\n\n    public function __construct(ContainerContextNonContractStub $other, IContainerContextContractStub ...$stubs)\n    {\n        $this->other = $other;\n        $this->stubs = $stubs;\n    }\n}\n\nclass ContainerTestContextInjectFromConfigIndividualValues\n{\n    public $username;\n    public $password;\n    public $alias = null;\n\n    public function __construct($username, $password, $alias = null)\n    {\n        $this->username = $username;\n        $this->password = $password;\n        $this->alias = $alias;\n    }\n}\n\nclass ContainerTestContextInjectFromConfigArray\n{\n    public $settings;\n\n    public function __construct($settings)\n    {\n        $this->settings = $settings;\n    }\n}\n\nclass ContainerTestContextInjectMethodArgument\n{\n    public function method(IContainerContextContractStub $dependency)\n    {\n        return $dependency;\n    }\n}\n"
  },
  {
    "path": "tests/Container/ResolvingCallbackTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\Container;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass ResolvingCallbackTest extends TestCase\n{\n    public function testResolvingCallbacksAreCalledForSpecificAbstracts()\n    {\n        $container = new Container;\n        $container->resolving('foo', function ($object) {\n            return $object->name = 'taylor';\n        });\n        $container->bind('foo', function () {\n            return new stdClass;\n        });\n        $instance = $container->make('foo');\n\n        $this->assertSame('taylor', $instance->name);\n    }\n\n    public function testResolvingCallbacksAreCalled()\n    {\n        $container = new Container;\n        $container->resolving(function ($object) {\n            return $object->name = 'taylor';\n        });\n        $container->bind('foo', function () {\n            return new stdClass;\n        });\n        $instance = $container->make('foo');\n\n        $this->assertSame('taylor', $instance->name);\n    }\n\n    public function testResolvingCallbacksAreCalledForType()\n    {\n        $container = new Container;\n        $container->resolving(stdClass::class, function ($object) {\n            return $object->name = 'taylor';\n        });\n        $container->bind('foo', function () {\n            return new stdClass;\n        });\n        $instance = $container->make('foo');\n\n        $this->assertSame('taylor', $instance->name);\n    }\n\n    public function testResolvingCallbacksShouldBeFiredWhenCalledWithAliases()\n    {\n        $container = new Container;\n        $container->alias(stdClass::class, 'std');\n        $container->resolving('std', function ($object) {\n            return $object->name = 'taylor';\n        });\n        $container->bind('foo', function () {\n            return new stdClass;\n        });\n        $instance = $container->make('foo');\n\n        $this->assertSame('taylor', $instance->name);\n    }\n\n    public function testResolvingCallbacksAreCalledOnceForImplementation()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testGlobalResolvingCallbacksAreCalledOnceForImplementation()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledOnceForSingletonConcretes()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n        $container->bind(ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(3, $callCounter);\n    }\n\n    public function testResolvingCallbacksCanStillBeAddedAfterTheFirstResolution()\n    {\n        $container = new Container;\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCanceledWhenInterfaceGetsBoundToSomeOtherConcrete()\n    {\n        $container = new Container;\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $callCounter = 0;\n        $container->resolving(ResolvingImplementationStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStubTwo::class);\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledOnceForStringAbstractions()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving('foo', function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind('foo', ResolvingImplementationStub::class);\n\n        $container->make('foo');\n        $this->assertEquals(1, $callCounter);\n\n        $container->make('foo');\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testResolvingCallbacksForConcretesAreCalledOnceForStringAbstractions()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingImplementationStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind('foo', ResolvingImplementationStub::class);\n        $container->bind('bar', ResolvingImplementationStub::class);\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make('foo');\n        $this->assertEquals(2, $callCounter);\n\n        $container->make('bar');\n        $this->assertEquals(3, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(4, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledOnceForImplementation2()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, function () {\n            return new ResolvingImplementationStub;\n        });\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(3, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(4, $callCounter);\n    }\n\n    public function testRebindingDoesNotAffectResolvingCallbacks()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n        $container->bind(ResolvingContractStub::class, function () {\n            return new ResolvingImplementationStub;\n        });\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(3, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(4, $callCounter);\n    }\n\n    public function testParametersPassedIntoResolvingCallbacks()\n    {\n        $container = new Container;\n\n        $container->resolving(ResolvingContractStub::class, function ($obj, $app) use ($container) {\n            $this->assertInstanceOf(ResolvingContractStub::class, $obj);\n            $this->assertInstanceOf(ResolvingImplementationStubTwo::class, $obj);\n            $this->assertSame($container, $app);\n        });\n\n        $container->afterResolving(ResolvingContractStub::class, function ($obj, $app) use ($container) {\n            $this->assertInstanceOf(ResolvingContractStub::class, $obj);\n            $this->assertInstanceOf(ResolvingImplementationStubTwo::class, $obj);\n            $this->assertSame($container, $app);\n        });\n\n        $container->afterResolving(function ($obj, $app) use ($container) {\n            $this->assertInstanceOf(ResolvingContractStub::class, $obj);\n            $this->assertInstanceOf(ResolvingImplementationStubTwo::class, $obj);\n            $this->assertSame($container, $app);\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStubTwo::class);\n        $container->make(ResolvingContractStub::class);\n    }\n\n    public function testResolvingCallbacksAreCallWhenRebindHappens()\n    {\n        $container = new Container;\n\n        $resolvingCallCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$resolvingCallCounter) {\n            $resolvingCallCounter++;\n        });\n\n        $rebindCallCounter = 0;\n        $container->rebinding(ResolvingContractStub::class, function () use (&$rebindCallCounter) {\n            $rebindCallCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $resolvingCallCounter);\n        $this->assertEquals(0, $rebindCallCounter);\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStubTwo::class);\n        $this->assertEquals(2, $resolvingCallCounter);\n        $this->assertEquals(1, $rebindCallCounter);\n\n        $container->make(ResolvingImplementationStubTwo::class);\n        $this->assertEquals(3, $resolvingCallCounter);\n        $this->assertEquals(1, $rebindCallCounter);\n\n        $container->bind(ResolvingContractStub::class, fn () => new ResolvingImplementationStubTwo);\n        $this->assertEquals(4, $resolvingCallCounter);\n        $this->assertEquals(2, $rebindCallCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(5, $resolvingCallCounter);\n        $this->assertEquals(2, $rebindCallCounter);\n    }\n\n    public function testResolvingCallbacksArentCalledWhenNoRebindingsAreRegistered()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStubTwo::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStubTwo::class);\n        $this->assertEquals(2, $callCounter);\n\n        $container->bind(ResolvingContractStub::class, fn () => new ResolvingImplementationStubTwo);\n        $this->assertEquals(2, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(3, $callCounter);\n    }\n\n    public function testRebindingDoesNotAffectMultipleResolvingCallbacks()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->resolving(ResolvingImplementationStubTwo::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        // it should call the callback for interface\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        // it should call the callback for interface\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n\n        // should call the callback for the interface it implements\n        // plus the callback for ResolvingImplementationStubTwo.\n        $container->make(ResolvingImplementationStubTwo::class);\n        $this->assertEquals(4, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledForInterfaces()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingContractStub::class);\n\n        $this->assertEquals(1, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledForConcretesWhenAttachedOnInterface()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingImplementationStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledForConcretesWhenAttachedOnConcretes()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingImplementationStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledForConcretesWithNoBinding()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingImplementationStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testResolvingCallbacksAreCalledForInterFacesWithNoBinding()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->resolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testAfterResolvingCallbacksAreCalledOnceForImplementation()\n    {\n        $container = new Container;\n\n        $callCounter = 0;\n        $container->afterResolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testBeforeResolvingCallbacksAreCalled()\n    {\n        // Given a call counter initialized to zero.\n        $container = new Container;\n        $callCounter = 0;\n\n        // And a contract/implementation stub binding.\n        $container->bind(ResolvingContractStub::class, ResolvingImplementationStub::class);\n\n        // When we add a before resolving callback that increment the counter by one.\n        $container->beforeResolving(ResolvingContractStub::class, function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        // Then resolving the implementation stub increases the counter by one.\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n\n        // And resolving the contract stub increases the counter by one.\n        $container->make(ResolvingContractStub::class);\n        $this->assertEquals(2, $callCounter);\n    }\n\n    public function testGlobalBeforeResolvingCallbacksAreCalled()\n    {\n        // Given a call counter initialized to zero.\n        $container = new Container;\n        $callCounter = 0;\n\n        // When we add a global before resolving callback that increment that counter by one.\n        $container->beforeResolving(function () use (&$callCounter) {\n            $callCounter++;\n        });\n\n        // Then resolving anything increases the counter by one.\n        $container->make(ResolvingImplementationStub::class);\n        $this->assertEquals(1, $callCounter);\n    }\n}\n\ninterface ResolvingContractStub\n{\n    //\n}\n\nclass ResolvingImplementationStub implements ResolvingContractStub\n{\n    //\n}\n\nclass ResolvingImplementationStubTwo implements ResolvingContractStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Container/RewindableGeneratorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\RewindableGenerator;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RewindableGeneratorTest extends TestCase\n{\n    public function testCountUsesProvidedValue()\n    {\n        $generator = new RewindableGenerator(function () {\n            yield 'foo';\n        }, 999);\n\n        $this->assertCount(999, $generator);\n    }\n\n    public function testCountUsesProvidedValueAsCallback()\n    {\n        $called = 0;\n\n        $generator = new RewindableGenerator(function () {\n            yield 'foo';\n        }, function () use (&$called) {\n            $called++;\n\n            return 500;\n        });\n\n        // the count callback is called lazily\n        $this->assertSame(0, $called);\n\n        $this->assertCount(500, $generator);\n\n        count($generator);\n\n        // the count callback is called only once\n        $this->assertSame(1, $called);\n    }\n}\n"
  },
  {
    "path": "tests/Container/UtilTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Container;\n\nuse Illuminate\\Container\\Util;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionParameter;\nuse stdClass;\n\nclass UtilTest extends TestCase\n{\n    public function testUnwrapIfClosure()\n    {\n        $this->assertSame('foo', Util::unwrapIfClosure('foo'));\n        $this->assertSame('foo', Util::unwrapIfClosure(function () {\n            return 'foo';\n        }));\n    }\n\n    public function testArrayWrap()\n    {\n        $string = 'a';\n        $array = ['a'];\n        $object = new stdClass;\n        $object->value = 'a';\n        $this->assertEquals(['a'], Util::arrayWrap($string));\n        $this->assertEquals($array, Util::arrayWrap($array));\n        $this->assertEquals([$object], Util::arrayWrap($object));\n        $this->assertEquals([], Util::arrayWrap(null));\n        $this->assertEquals([null], Util::arrayWrap([null]));\n        $this->assertEquals([null, null], Util::arrayWrap([null, null]));\n        $this->assertEquals([''], Util::arrayWrap(''));\n        $this->assertEquals([''], Util::arrayWrap(['']));\n        $this->assertEquals([false], Util::arrayWrap(false));\n        $this->assertEquals([false], Util::arrayWrap([false]));\n        $this->assertEquals([0], Util::arrayWrap(0));\n\n        $obj = new stdClass;\n        $obj->value = 'a';\n        $obj = unserialize(serialize($obj));\n        $this->assertEquals([$obj], Util::arrayWrap($obj));\n        $this->assertSame($obj, Util::arrayWrap($obj)[0]);\n    }\n\n    public function testGetParameterClassName()\n    {\n        $parameter = new ReflectionParameter(function (stdClass $foo) {\n        }, 0);\n        $this->assertSame('stdClass', Util::getParameterClassName($parameter));\n\n        $parameter = new ReflectionParameter(function (string $foo) {\n        }, 0);\n        $this->assertNull(Util::getParameterClassName($parameter));\n    }\n}\n"
  },
  {
    "path": "tests/Cookie/CookieTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cookie;\n\nuse ArgumentCountError;\nuse Illuminate\\Cookie\\CookieJar;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionObject;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass CookieTest extends TestCase\n{\n    public function testCookiesAreCreatedWithProperOptions()\n    {\n        $cookie = $this->getCreator();\n        $cookie->setDefaultPathAndDomain('foo', 'bar');\n        $c = $cookie->make('color', 'blue', 10, '/path', '/domain', true, false, false, 'lax');\n        $this->assertSame('blue', $c->getValue());\n        $this->assertFalse($c->isHttpOnly());\n        $this->assertTrue($c->isSecure());\n        $this->assertSame('/domain', $c->getDomain());\n        $this->assertSame('/path', $c->getPath());\n        $this->assertSame('lax', $c->getSameSite());\n\n        $c2 = $cookie->forever('color', 'blue', '/path', '/domain', true, false, false, 'strict');\n        $this->assertSame('blue', $c2->getValue());\n        $this->assertFalse($c2->isHttpOnly());\n        $this->assertTrue($c2->isSecure());\n        $this->assertSame('/domain', $c2->getDomain());\n        $this->assertSame('/path', $c2->getPath());\n        $this->assertSame('strict', $c2->getSameSite());\n\n        $c3 = $cookie->forget('color');\n        $this->assertNull($c3->getValue());\n        $this->assertTrue($c3->getExpiresTime() < time());\n    }\n\n    public function testCookiesAreCreatedWithProperOptionsUsingDefaultPathAndDomain(): void\n    {\n        $cookie = $this->getCreator();\n        $cookie->setDefaultPathAndDomain('/path', '/domain', true, 'lax');\n        $c = $cookie->make('color', 'blue');\n        $this->assertSame('blue', $c->getValue());\n        $this->assertTrue($c->isSecure());\n        $this->assertSame('/domain', $c->getDomain());\n        $this->assertSame('/path', $c->getPath());\n        $this->assertSame('lax', $c->getSameSite());\n        $this->assertTrue($c->isHttpOnly());\n    }\n\n    public function testCookiesCanSetSecureOptionUsingDefaultPathAndDomain()\n    {\n        $cookie = $this->getCreator();\n        $cookie->setDefaultPathAndDomain('/path', '/domain', true, 'lax');\n        $c = $cookie->make('color', 'blue', 10, null, null, false);\n        $this->assertSame('blue', $c->getValue());\n        $this->assertFalse($c->isSecure());\n        $this->assertSame('/domain', $c->getDomain());\n        $this->assertSame('/path', $c->getPath());\n        $this->assertSame('lax', $c->getSameSite());\n    }\n\n    public function testQueuedCookiesWithoutName(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $cookie = $this->getCreator();\n        $cookie->queue($cookie->make('', 'bar'));\n    }\n\n    public function testQueuedCookiesWithInvalidParameter(): void\n    {\n        $this->expectException(ArgumentCountError::class);\n\n        $cookie = $this->getCreator();\n        $cookie->queue('invalidCookie');\n    }\n\n    public function testQueuedCookiesWithHandlingEmptyValues(): void\n    {\n        $cookie = $this->getCreator();\n        $cookie->queue($cookie->make('foo', ''));\n        $this->assertTrue($cookie->hasQueued('foo'));\n        $this->assertEquals('', $cookie->queued('foo')->getValue());\n    }\n\n    public function testQueuedCookiesWithRepeatedValue(): void\n    {\n        $cookie = $this->getCreator();\n        $cookie->queue($cookie->make('foo', 'newBar'));\n        $this->assertTrue($cookie->hasQueued('foo'));\n        $this->assertEquals('newBar', $cookie->queued('foo')->getValue());\n\n        $this->expectException(ArgumentCountError::class);\n        $cookie->queue('invalidCookie');\n    }\n\n    public function testQueuedCookies(): void\n    {\n        $cookie = $this->getCreator();\n        $this->assertEmpty($cookie->getQueuedCookies());\n        $this->assertFalse($cookie->hasQueued('foo'));\n        $cookie->queue($cookie->make('foo', 'bar'));\n        $this->assertTrue($cookie->hasQueued('foo'));\n        $this->assertInstanceOf(Cookie::class, $cookie->queued('foo'));\n        $cookie->queue('qu', 'ux');\n        $this->assertTrue($cookie->hasQueued('qu'));\n        $this->assertInstanceOf(Cookie::class, $cookie->queued('qu'));\n    }\n\n    public function testQueuedWithPath(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $this->assertEquals($cookieOne, $cookieJar->queued('foo', null, '/path'));\n        $this->assertEquals($cookieTwo, $cookieJar->queued('foo', null, '/'));\n    }\n\n    public function testQueuedWithoutPath(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $this->assertEquals($cookieTwo, $cookieJar->queued('foo'));\n    }\n\n    public function testHasQueued(): void\n    {\n        $cookieJar = $this->getCreator();\n        // test empty queue\n        $this->assertFalse($cookieJar->hasQueued('foo'));\n\n        $cookie = $cookieJar->make('foo', 'bar');\n        $cookieJar->queue($cookie);\n        $this->assertTrue($cookieJar->hasQueued('foo'));\n        $this->assertFalse($cookieJar->hasQueued('nonexistent'));\n    }\n\n    public function testHasQueuedWithPath(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $this->assertTrue($cookieJar->hasQueued('foo', '/path'));\n        $this->assertTrue($cookieJar->hasQueued('foo', '/'));\n        $this->assertFalse($cookieJar->hasQueued('foo', '/wrongPath'));\n    }\n\n    public function testExpire()\n    {\n        $cookieJar = $this->getCreator();\n        $this->assertCount(0, $cookieJar->getQueuedCookies());\n\n        $cookieJar->expire('foobar', '/path', '/domain');\n\n        $cookie = $cookieJar->queued('foobar');\n        $this->assertSame('foobar', $cookie->getName());\n        $this->assertEquals(null, $cookie->getValue());\n        $this->assertSame('/path', $cookie->getPath());\n        $this->assertSame('/domain', $cookie->getDomain());\n        $this->assertTrue($cookie->getExpiresTime() < time());\n        $this->assertCount(1, $cookieJar->getQueuedCookies());\n    }\n\n    public function testUnqueue(): void\n    {\n        $cookie = $this->getCreator();\n\n        $cookie->unqueue('nonexistent');\n        $this->assertEmpty($cookie->getQueuedCookies());\n\n        $cookie->queue($cookie->make('foo', 'bar'));\n        $cookie->unqueue('foo');\n        $this->assertEmpty($cookie->getQueuedCookies());\n    }\n\n    public function testUnqueueMultipleCookies(): void\n    {\n        $cookie = $this->getCreator();\n        $cookie->queue($cookie->make('foo', 'bar'));\n        $cookie->queue($cookie->make('baz', 'qux'));\n        $cookie->unqueue('foo');\n        $this->assertTrue($cookie->hasQueued('baz'));\n        $this->assertFalse($cookie->hasQueued('foo'));\n    }\n\n    public function testUnqueueWithPath(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $cookieJar->unqueue('foo', '/path');\n        $this->assertEquals(['foo' => ['/' => $cookieTwo]], $this->getQueuedPropertyValue($cookieJar));\n    }\n\n    public function testUnqueueOnlyCookieForName(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookie = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieJar->queue($cookie);\n        $cookieJar->unqueue('foo', '/path');\n        $this->assertEmpty($this->getQueuedPropertyValue($cookieJar));\n    }\n\n    public function testCookieJarIsMacroable()\n    {\n        $cookie = $this->getCreator();\n        $cookie->macro('foo', function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $cookie->foo());\n    }\n\n    public function testQueueCookie(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookie = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieJar->queue($cookie);\n        $this->assertEquals(['foo' => ['/path' => $cookie]], $this->getQueuedPropertyValue($cookieJar));\n    }\n\n    public function testQueueWithCreatingNewCookie(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieJar->queue('foo', 'bar', 0, '/path');\n        $this->assertEquals(\n            ['foo' => ['/path' => new Cookie('foo', 'bar', 0, '/path')]],\n            $this->getQueuedPropertyValue($cookieJar)\n        );\n    }\n\n    public function testGetQueuedCookies(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieThree = $cookieJar->make('oof', 'bar', 0, '/path');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $cookieJar->queue($cookieThree);\n        $this->assertEquals(\n            [$cookieOne, $cookieTwo, $cookieThree],\n            $cookieJar->getQueuedCookies()\n        );\n    }\n\n    public function testFlushQueuedCookies(): void\n    {\n        $cookieJar = $this->getCreator();\n        $cookieJar->queue($cookieJar->make('foo', 'bar', 0, '/path'));\n        $cookieJar->queue($cookieJar->make('foo', 'rab', 0, '/'));\n        $this->assertCount(2, $cookieJar->getQueuedCookies());\n\n        $cookieJar->flushQueuedCookies();\n        $this->assertEmpty($cookieJar->getQueuedCookies());\n    }\n\n    public function getCreator()\n    {\n        return new CookieJar;\n    }\n\n    private function getQueuedPropertyValue(CookieJar $cookieJar)\n    {\n        $property = (new ReflectionObject($cookieJar))->getProperty('queued');\n\n        return $property->getValue($cookieJar);\n    }\n}\n"
  },
  {
    "path": "tests/Cookie/Middleware/AddQueuedCookiesToResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cookie\\Middleware;\n\nuse Illuminate\\Cookie\\CookieJar;\nuse Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\ResponseHeaderBag;\n\nclass AddQueuedCookiesToResponseTest extends TestCase\n{\n    public function testHandle(): void\n    {\n        $cookieJar = new CookieJar;\n        $cookieOne = $cookieJar->make('foo', 'bar', 0, '/path');\n        $cookieTwo = $cookieJar->make('foo', 'rab', 0, '/');\n        $cookieJar->queue($cookieOne);\n        $cookieJar->queue($cookieTwo);\n        $addQueueCookiesToResponseMiddleware = new AddQueuedCookiesToResponse($cookieJar);\n        $next = function (Request $request) {\n            return new Response;\n        };\n        $this->assertEquals(\n            [\n                '' => [\n                    '/path' => [\n                        'foo' => $cookieOne,\n                    ],\n                    '/' => [\n                        'foo' => $cookieTwo,\n                    ],\n                ],\n            ],\n            $addQueueCookiesToResponseMiddleware->handle(new Request, $next)->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY)\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Cookie/Middleware/EncryptCookiesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Cookie\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Encryption\\Encrypter as EncrypterContract;\nuse Illuminate\\Cookie\\CookieJar;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse;\nuse Illuminate\\Cookie\\Middleware\\EncryptCookies;\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Routing\\Router;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass EncryptCookiesTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    /**\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    protected $setCookiePath = 'cookie/set';\n    protected $queueCookiePath = 'cookie/queue';\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->container = new Container;\n        $this->container->singleton(EncrypterContract::class, function () {\n            return new Encrypter(str_repeat('a', 16));\n        });\n\n        $this->router = new Router(new Dispatcher, $this->container);\n\n        EncryptCookiesTestMiddleware::except(['globally_unencrypted_cookie']);\n    }\n\n    public function testSetCookieEncryption()\n    {\n        $this->router->get($this->setCookiePath, [\n            'middleware' => EncryptCookiesTestMiddleware::class,\n            'uses' => EncryptCookiesTestController::class.'@setCookies',\n        ]);\n\n        $response = $this->router->dispatch(Request::create($this->setCookiePath, 'GET'));\n\n        $cookies = $response->headers->getCookies();\n        $this->assertCount(5, $cookies);\n        $this->assertSame('encrypted_cookie', $cookies[0]->getName());\n        $this->assertNotSame('value', $cookies[0]->getValue());\n        $this->assertSame('encrypted[array_cookie]', $cookies[1]->getName());\n        $this->assertNotSame('value', $cookies[1]->getValue());\n        $this->assertSame('encrypted[nested][array_cookie]', $cookies[2]->getName());\n        $this->assertSame('unencrypted_cookie', $cookies[3]->getName());\n        $this->assertSame('value', $cookies[3]->getValue());\n        $this->assertSame('globally_unencrypted_cookie', $cookies[4]->getName());\n        $this->assertSame('value', $cookies[4]->getValue());\n    }\n\n    public function testQueuedCookieEncryption()\n    {\n        $this->router->get($this->queueCookiePath, [\n            'middleware' => [EncryptCookiesTestMiddleware::class, AddQueuedCookiesToResponseTestMiddleware::class],\n            'uses' => EncryptCookiesTestController::class.'@queueCookies',\n        ]);\n\n        $response = $this->router->dispatch(Request::create($this->queueCookiePath, 'GET'));\n\n        $cookies = $response->headers->getCookies();\n        $this->assertCount(5, $cookies);\n        $this->assertSame('encrypted_cookie', $cookies[0]->getName());\n        $this->assertNotSame('value', $cookies[0]->getValue());\n        $this->assertSame('encrypted[array_cookie]', $cookies[1]->getName());\n        $this->assertNotSame('value', $cookies[1]->getValue());\n        $this->assertSame('encrypted[nested][array_cookie]', $cookies[2]->getName());\n        $this->assertNotSame('value', $cookies[2]->getValue());\n        $this->assertSame('unencrypted_cookie', $cookies[3]->getName());\n        $this->assertSame('value', $cookies[3]->getValue());\n        $this->assertSame('globally_unencrypted_cookie', $cookies[4]->getName());\n        $this->assertSame('value', $cookies[4]->getValue());\n    }\n\n    protected function getEncryptedCookieValue($key, $value)\n    {\n        $encrypter = $this->container->make(EncrypterContract::class);\n\n        return $encrypter->encrypt(\n            CookieValuePrefix::create($key, $encrypter->getKey()).$value,\n            false\n        );\n    }\n\n    public function testCookieDecryption()\n    {\n        $cookies = [\n            'encrypted_cookie' => $this->getEncryptedCookieValue('encrypted_cookie', 'value'),\n            'encrypted' => [\n                'array_cookie' => $this->getEncryptedCookieValue('encrypted[array_cookie]', 'value'),\n                'nested' => [\n                    'array_cookie' => $this->getEncryptedCookieValue('encrypted[nested][array_cookie]', 'value'),\n                ],\n            ],\n            'unencrypted_cookie' => 'value',\n            'globally_unencrypted_cookie' => 'value',\n        ];\n\n        $this->container->make(EncryptCookiesTestMiddleware::class)->handle(\n            Request::create('/cookie/read', 'GET', [], $cookies),\n            function ($request) {\n                $cookies = $request->cookies->all();\n                $this->assertCount(4, $cookies);\n                $this->assertArrayHasKey('encrypted_cookie', $cookies);\n                $this->assertSame('value', $cookies['encrypted_cookie']);\n                $this->assertArrayHasKey('encrypted', $cookies);\n                $this->assertArrayHasKey('array_cookie', $cookies['encrypted']);\n                $this->assertSame('value', $cookies['encrypted']['array_cookie']);\n                $this->assertArrayHasKey('nested', $cookies['encrypted']);\n                $this->assertArrayHasKey('array_cookie', $cookies['encrypted']['nested']);\n                $this->assertSame('value', $cookies['encrypted']['nested']['array_cookie']);\n                $this->assertArrayHasKey('unencrypted_cookie', $cookies);\n                $this->assertSame('value', $cookies['unencrypted_cookie']);\n                $this->assertArrayHasKey('globally_unencrypted_cookie', $cookies);\n                $this->assertSame('value', $cookies['globally_unencrypted_cookie']);\n\n                return new Response;\n            }\n        );\n    }\n}\n\nclass EncryptCookiesTestController extends Controller\n{\n    public function setCookies()\n    {\n        $response = new Response;\n        $response->headers->setCookie(new Cookie('encrypted_cookie', 'value'));\n        $response->headers->setCookie(new Cookie('encrypted[array_cookie]', 'value'));\n        $response->headers->setCookie(new Cookie('encrypted[nested][array_cookie]', 'value'));\n        $response->headers->setCookie(new Cookie('unencrypted_cookie', 'value'));\n        $response->headers->setCookie(new Cookie('globally_unencrypted_cookie', 'value'));\n\n        return $response;\n    }\n\n    public function queueCookies()\n    {\n        return new Response;\n    }\n}\n\nclass EncryptCookiesTestMiddleware extends EncryptCookies\n{\n    protected $except = [\n        'unencrypted_cookie',\n    ];\n}\n\nclass AddQueuedCookiesToResponseTestMiddleware extends AddQueuedCookiesToResponse\n{\n    public function __construct()\n    {\n        $cookie = new CookieJar;\n        $cookie->queue(new Cookie('encrypted_cookie', 'value'));\n        $cookie->queue(new Cookie('encrypted[array_cookie]', 'value'));\n        $cookie->queue(new Cookie('encrypted[nested][array_cookie]', 'value'));\n        $cookie->queue(new Cookie('unencrypted_cookie', 'value'));\n        $cookie->queue(new Cookie('globally_unencrypted_cookie', 'value'));\n\n        $this->cookies = $cookie;\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseAbstractSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseAbstractSchemaGrammarTest extends TestCase\n{\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new class($connection) extends Grammar {\n        };\n\n        $this->assertSame('create database \"foo\"', $grammar->compileCreateDatabase('foo'));\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new class($connection) extends Grammar {\n        };\n\n        $this->assertSame('drop database if exists \"foo\"', $grammar->compileDropDatabaseIfExists('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConcernsBuildsQueriesTraitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Concerns\\BuildsQueries;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseConcernsBuildsQueriesTraitTest extends TestCase\n{\n    public function testTapCallbackInstance()\n    {\n        $mock = new class\n        {\n            use BuildsQueries;\n        };\n\n        $mock->tap(function ($builder) use ($mock) {\n            $this->assertEquals($mock, $builder);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConcernsHasAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasAttributes;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseConcernsHasAttributesTest extends TestCase\n{\n    public function testWithoutConstructor()\n    {\n        $instance = new HasAttributesWithoutConstructor();\n        $attributes = $instance->getMutatedAttributes();\n        $this->assertEquals(['some_attribute'], $attributes);\n    }\n\n    public function testWithConstructorArguments()\n    {\n        $instance = new HasAttributesWithConstructorArguments(null);\n        $attributes = $instance->getMutatedAttributes();\n        $this->assertEquals(['some_attribute'], $attributes);\n    }\n\n    public function testRelationsToArray()\n    {\n        $mock = m::mock(HasAttributesWithoutConstructor::class)\n            ->makePartial()\n            ->shouldAllowMockingProtectedMethods()\n            ->shouldReceive('getArrayableRelations')->andReturn([\n                'arrayable_relation' => Collection::make(['foo' => 'bar']),\n                'invalid_relation' => 'invalid',\n                'null_relation' => null,\n            ])\n            ->getMock();\n\n        $this->assertEquals([\n            'arrayable_relation' => ['foo' => 'bar'],\n            'null_relation' => null,\n        ], $mock->relationsToArray());\n    }\n\n    public function testCastingEmptyStringToArrayDoesNotError()\n    {\n        $instance = new HasAttributesWithArrayCast();\n        $this->assertEquals(['foo' => null], $instance->attributesToArray());\n\n        $this->assertTrue(json_last_error() === JSON_ERROR_NONE);\n    }\n\n    public function testUnsettingCachedAttribute()\n    {\n        $instance = new HasCacheableAttributeWithAccessor();\n        $this->assertEquals('foo', $instance->getAttribute('cacheableProperty'));\n        $this->assertTrue($instance->cachedAttributeIsset('cacheableProperty'));\n\n        unset($instance->cacheableProperty);\n\n        $this->assertFalse($instance->cachedAttributeIsset('cacheableProperty'));\n    }\n}\n\nclass HasAttributesWithoutConstructor\n{\n    use HasAttributes;\n\n    public function someAttribute(): Attribute\n    {\n        return new Attribute(function () {\n        });\n    }\n}\n\nclass HasAttributesWithConstructorArguments extends HasAttributesWithoutConstructor\n{\n    public function __construct($someValue)\n    {\n    }\n}\n\nclass HasAttributesWithArrayCast\n{\n    use HasAttributes;\n\n    public function getArrayableAttributes(): array\n    {\n        return ['foo' => ''];\n    }\n\n    public function getCasts(): array\n    {\n        return ['foo' => 'array'];\n    }\n\n    public function usesTimestamps(): bool\n    {\n        return false;\n    }\n}\n\n/**\n * @property string $cacheableProperty\n */\nclass HasCacheableAttributeWithAccessor extends Model\n{\n    public function cacheableProperty(): Attribute\n    {\n        return Attribute::make(\n            get: fn () => 'foo'\n        )->shouldCache();\n    }\n\n    public function cachedAttributeIsset($attribute): bool\n    {\n        return isset($this->attributeCastCache[$attribute]);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConcernsPreventsCircularRecursionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Concerns\\PreventsCircularRecursion;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseConcernsPreventsCircularRecursionTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        PreventsCircularRecursionWithRecursiveMethod::$globalStack = 0;\n    }\n\n    public function testRecursiveCallsArePreventedWithoutPreventingSubsequentCalls()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n\n        $this->assertEquals(0, $instance->callStack());\n        $this->assertEquals(1, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n\n        $this->assertEquals(1, $instance->callStack());\n        $this->assertEquals(2, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n    }\n\n    public function testRecursiveDefaultCallbackIsCalledOnlyOnRecursion()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n        $this->assertEquals(0, $instance->defaultStack);\n\n        $this->assertEquals(['instance' => 1, 'default' => 0], $instance->callCallableDefaultStack());\n        $this->assertEquals(1, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n        $this->assertEquals(1, $instance->defaultStack);\n\n        $this->assertEquals(['instance' => 2, 'default' => 1], $instance->callCallableDefaultStack());\n        $this->assertEquals(2, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(2, $instance->defaultStack);\n    }\n\n    public function testRecursiveDefaultCallbackIsCalledOnlyOncePerCallStack()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n        $this->assertEquals(0, $instance->defaultStack);\n\n        $this->assertEquals(\n            [\n                ['instance' => 1, 'default' => 0],\n                ['instance' => 1, 'default' => 0],\n                ['instance' => 1, 'default' => 0],\n            ],\n            $instance->callCallableDefaultStackRepeatedly(),\n        );\n        $this->assertEquals(1, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n        $this->assertEquals(1, $instance->defaultStack);\n\n        $this->assertEquals(\n            [\n                ['instance' => 2, 'default' => 1],\n                ['instance' => 2, 'default' => 1],\n                ['instance' => 2, 'default' => 1],\n            ],\n            $instance->callCallableDefaultStackRepeatedly(),\n        );\n        $this->assertEquals(2, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(2, $instance->defaultStack);\n    }\n\n    public function testRecursiveCallsAreLimitedToIndividualInstances()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n        $other = $instance->other;\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n        $this->assertEquals(0, $other->instanceStack);\n\n        $instance->callStack();\n        $this->assertEquals(1, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n        $this->assertEquals(0, $other->instanceStack);\n\n        $instance->callStack();\n        $this->assertEquals(2, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(0, $other->instanceStack);\n\n        $other->callStack();\n        $this->assertEquals(3, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(1, $other->instanceStack);\n\n        $other->callStack();\n        $this->assertEquals(4, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(2, $other->instanceStack);\n    }\n\n    public function testRecursiveCallsToCircularReferenceCallsOtherInstanceOnce()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n        $other = $instance->other;\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n        $this->assertEquals(0, $other->instanceStack);\n\n        $instance->callOtherStack();\n        $this->assertEquals(2, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n        $this->assertEquals(1, $other->instanceStack);\n\n        $instance->callOtherStack();\n        $this->assertEquals(4, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(2, $other->instanceStack);\n\n        $other->callOtherStack();\n        $this->assertEquals(6, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(3, $other->instanceStack);\n        $this->assertEquals(3, $instance->instanceStack);\n\n        $other->callOtherStack();\n        $this->assertEquals(8, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(4, $other->instanceStack);\n        $this->assertEquals(4, $instance->instanceStack);\n    }\n\n    public function testRecursiveCallsToCircularLinkedListCallsEachInstanceOnce()\n    {\n        $instance = new PreventsCircularRecursionWithRecursiveMethod();\n        $second = $instance->other;\n        $third = new PreventsCircularRecursionWithRecursiveMethod($second);\n        $instance->other = $third;\n\n        $this->assertEquals(0, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(0, $instance->instanceStack);\n        $this->assertEquals(0, $second->instanceStack);\n        $this->assertEquals(0, $third->instanceStack);\n\n        $instance->callOtherStack();\n        $this->assertEquals(3, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(1, $instance->instanceStack);\n        $this->assertEquals(1, $second->instanceStack);\n        $this->assertEquals(1, $third->instanceStack);\n\n        $second->callOtherStack();\n        $this->assertEquals(6, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(2, $instance->instanceStack);\n        $this->assertEquals(2, $second->instanceStack);\n        $this->assertEquals(2, $third->instanceStack);\n\n        $third->callOtherStack();\n        $this->assertEquals(9, PreventsCircularRecursionWithRecursiveMethod::$globalStack);\n        $this->assertEquals(3, $instance->instanceStack);\n        $this->assertEquals(3, $second->instanceStack);\n        $this->assertEquals(3, $third->instanceStack);\n    }\n\n    public function testMockedModelCallToWithoutRecursionMethodWorks(): void\n    {\n        $mock = m::mock(TestModel::class)->makePartial();\n\n        // Model toArray method implementation\n        $toArray = $mock->withoutRecursion(\n            fn () => array_merge($mock->attributesToArray(), $mock->relationsToArray()),\n            fn () => $mock->attributesToArray(),\n        );\n        $this->assertEquals([], $toArray);\n    }\n}\n\nclass PreventsCircularRecursionWithRecursiveMethod\n{\n    use PreventsCircularRecursion;\n\n    public function __construct(\n        public ?PreventsCircularRecursionWithRecursiveMethod $other = null,\n    ) {\n        $this->other ??= new PreventsCircularRecursionWithRecursiveMethod($this);\n    }\n\n    public static int $globalStack = 0;\n    public int $instanceStack = 0;\n    public int $defaultStack = 0;\n\n    public function callStack(): int\n    {\n        return $this->withoutRecursion(\n            function () {\n                static::$globalStack++;\n                $this->instanceStack++;\n\n                return $this->callStack();\n            },\n            $this->instanceStack,\n        );\n    }\n\n    public function callCallableDefaultStack(): array\n    {\n        return $this->withoutRecursion(\n            function () {\n                static::$globalStack++;\n                $this->instanceStack++;\n\n                return $this->callCallableDefaultStack();\n            },\n            fn () => [\n                'instance' => $this->instanceStack,\n                'default' => $this->defaultStack++,\n            ],\n        );\n    }\n\n    public function callCallableDefaultStackRepeatedly(): array\n    {\n        return $this->withoutRecursion(\n            function () {\n                static::$globalStack++;\n                $this->instanceStack++;\n\n                return [\n                    $this->callCallableDefaultStackRepeatedly(),\n                    $this->callCallableDefaultStackRepeatedly(),\n                    $this->callCallableDefaultStackRepeatedly(),\n                ];\n            },\n            fn () => [\n                'instance' => $this->instanceStack,\n                'default' => $this->defaultStack++,\n            ],\n        );\n    }\n\n    public function callOtherStack(): int\n    {\n        return $this->withoutRecursion(\n            function () {\n                $this->other->callStack();\n\n                return $this->other->callOtherStack();\n            },\n            $this->instanceStack,\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConnectionFactoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Connectors\\ConnectionFactory;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionProperty;\n\nclass DatabaseConnectionFactoryTest extends TestCase\n{\n    protected $db;\n\n    protected function setUp(): void\n    {\n        $this->db = new DB;\n\n        $this->db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->db->addConnection([\n            'url' => 'sqlite:///:memory:',\n        ], 'url');\n\n        $this->db->addConnection([\n            'driver' => 'sqlite',\n            'read' => [\n                'database' => ':memory:',\n            ],\n            'write' => [\n                'database' => ':memory:',\n            ],\n        ], 'read_write');\n\n        $this->db->setAsGlobal();\n    }\n\n    public function testConnectionCanBeCreated()\n    {\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection()->getPdo());\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection()->getReadPdo());\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection('read_write')->getPdo());\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection('read_write')->getReadPdo());\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection('url')->getPdo());\n        $this->assertInstanceOf(PDO::class, $this->db->getConnection('url')->getReadPdo());\n    }\n\n    public function testConnectionFromUrlHasProperConfig()\n    {\n        $this->db->addConnection([\n            'url' => 'mysql://root:pass@db/local?strict=true',\n            'unix_socket' => '',\n            'charset' => 'utf8mb4',\n            'collation' => 'utf8mb4_unicode_ci',\n            'prefix' => '',\n            'prefix_indexes' => true,\n            'strict' => false,\n            'engine' => null,\n        ], 'url-config');\n\n        $this->assertEquals([\n            'name' => 'url-config',\n            'driver' => 'mysql',\n            'database' => 'local',\n            'host' => 'db',\n            'username' => 'root',\n            'password' => 'pass',\n            'unix_socket' => '',\n            'charset' => 'utf8mb4',\n            'collation' => 'utf8mb4_unicode_ci',\n            'prefix' => '',\n            'prefix_indexes' => true,\n            'strict' => true,\n            'engine' => null,\n        ], $this->db->getConnection('url-config')->getConfig());\n    }\n\n    public function testSingleConnectionNotCreatedUntilNeeded()\n    {\n        $connection = $this->db->getConnection();\n        $pdo = new ReflectionProperty(get_class($connection), 'pdo');\n        $readPdo = new ReflectionProperty(get_class($connection), 'readPdo');\n\n        $this->assertNotInstanceOf(PDO::class, $pdo->getValue($connection));\n        $this->assertNotInstanceOf(PDO::class, $readPdo->getValue($connection));\n    }\n\n    public function testReadWriteConnectionsNotCreatedUntilNeeded()\n    {\n        $connection = $this->db->getConnection('read_write');\n        $pdo = new ReflectionProperty(get_class($connection), 'pdo');\n        $readPdo = new ReflectionProperty(get_class($connection), 'readPdo');\n\n        $this->assertNotInstanceOf(PDO::class, $pdo->getValue($connection));\n        $this->assertNotInstanceOf(PDO::class, $readPdo->getValue($connection));\n    }\n\n    public function testReadWriteConnectionSetsReadPdoConfig()\n    {\n        $connection = $this->db->getConnection('read_write');\n\n        $readPdoConfig = new ReflectionProperty(get_class($connection), 'readPdoConfig');\n\n        $config = $readPdoConfig->getValue($connection);\n\n        $this->assertNotEmpty($config);\n        $this->assertArrayHasKey('database', $config);\n        $this->assertSame(':memory:', $config['database']);\n    }\n\n    public function testIfDriverIsntSetExceptionIsThrown()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('A driver must be specified.');\n\n        $factory = new ConnectionFactory($container = m::mock(Container::class));\n        $factory->createConnector(['foo']);\n    }\n\n    public function testExceptionIsThrownOnUnsupportedDriver()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Unsupported driver [foo]');\n\n        $factory = new ConnectionFactory($container = m::mock(Container::class));\n        $container->shouldReceive('bound')->once()->andReturn(false);\n        $factory->createConnector(['driver' => 'foo']);\n    }\n\n    public function testCustomConnectorsCanBeResolvedViaContainer()\n    {\n        $factory = new ConnectionFactory($container = m::mock(Container::class));\n        $container->shouldReceive('bound')->once()->with('db.connector.foo')->andReturn(true);\n        $container->shouldReceive('make')->once()->with('db.connector.foo')->andReturn('connector');\n\n        $this->assertSame('connector', $factory->createConnector(['driver' => 'foo']));\n    }\n\n    public function testSqliteForeignKeyConstraints()\n    {\n        $this->db->addConnection([\n            'url' => 'sqlite:///:memory:?foreign_key_constraints=true',\n        ], 'constraints_set');\n\n        $this->assertEquals(0, $this->db->getConnection()->select('PRAGMA foreign_keys')[0]->foreign_keys);\n\n        $this->assertEquals(1, $this->db->getConnection('constraints_set')->select('PRAGMA foreign_keys')[0]->foreign_keys);\n    }\n\n    public function testSqliteBusyTimeout()\n    {\n        $this->db->addConnection([\n            'url' => 'sqlite:///:memory:?busy_timeout=1234',\n        ], 'busy_timeout_set');\n\n        // Can't compare to 0, default value may be something else\n        $this->assertNotSame(1234, $this->db->getConnection()->select('PRAGMA busy_timeout')[0]->timeout);\n\n        $this->assertSame(1234, $this->db->getConnection('busy_timeout_set')->select('PRAGMA busy_timeout')[0]->timeout);\n    }\n\n    public function testSqliteSynchronous()\n    {\n        $this->db->addConnection([\n            'url' => 'sqlite:///:memory:?synchronous=NORMAL',\n        ], 'synchronous_set');\n\n        $this->assertSame(2, $this->db->getConnection()->select('PRAGMA synchronous')[0]->synchronous);\n\n        $this->assertSame(1, $this->db->getConnection('synchronous_set')->select('PRAGMA synchronous')[0]->synchronous);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse DateTime;\nuse ErrorException;\nuse Exception;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Database\\Events\\TransactionBeginning;\nuse Illuminate\\Database\\Events\\TransactionCommitted;\nuse Illuminate\\Database\\Events\\TransactionCommitting;\nuse Illuminate\\Database\\Events\\TransactionRolledBack;\nuse Illuminate\\Database\\MultipleColumnsSelectedException;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Mockery as m;\nuse PDO;\nuse PDOException;\nuse PDOStatement;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\n\nclass DatabaseConnectionTest extends TestCase\n{\n    public function testSettingDefaultCallsGetDefaultGrammar()\n    {\n        $connection = $this->getMockConnection();\n        $mock = m::mock(stdClass::class);\n        $connection->expects($this->once())->method('getDefaultQueryGrammar')->willReturn($mock);\n        $connection->useDefaultQueryGrammar();\n        $this->assertEquals($mock, $connection->getQueryGrammar());\n    }\n\n    public function testSettingDefaultCallsGetDefaultPostProcessor()\n    {\n        $connection = $this->getMockConnection();\n        $mock = m::mock(stdClass::class);\n        $connection->expects($this->once())->method('getDefaultPostProcessor')->willReturn($mock);\n        $connection->useDefaultPostProcessor();\n        $this->assertEquals($mock, $connection->getPostProcessor());\n    }\n\n    public function testSelectOneCallsSelectAndReturnsSingleResult()\n    {\n        $connection = $this->getMockConnection(['select']);\n        $connection->expects($this->once())->method('select')->with('foo', ['bar' => 'baz'])->willReturn(['foo']);\n        $this->assertSame('foo', $connection->selectOne('foo', ['bar' => 'baz']));\n    }\n\n    public function testScalarCallsSelectOneAndReturnsSingleResult()\n    {\n        $connection = $this->getMockConnection(['selectOne']);\n        $connection->expects($this->once())->method('selectOne')->with('select count(*) from tbl')->willReturn((object) ['count(*)' => 5]);\n        $this->assertSame(5, $connection->scalar('select count(*) from tbl'));\n    }\n\n    public function testScalarThrowsExceptionIfMultipleColumnsAreSelected()\n    {\n        $connection = $this->getMockConnection(['selectOne']);\n        $connection->expects($this->once())->method('selectOne')->with('select a, b from tbl')->willReturn((object) ['a' => 'a', 'b' => 'b']);\n        $this->expectException(MultipleColumnsSelectedException::class);\n        $connection->scalar('select a, b from tbl');\n    }\n\n    public function testScalarReturnsNullIfUnderlyingSelectReturnsNoRows()\n    {\n        $connection = $this->getMockConnection(['selectOne']);\n        $connection->expects($this->once())->method('selectOne')->with('select foo from tbl where 0=1')->willReturn(null);\n        $this->assertNull($connection->scalar('select foo from tbl where 0=1'));\n    }\n\n    public function testSelectProperlyCallsPDO()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $writePdo->expects($this->never())->method('prepare');\n        $statement = $this->getMockBuilder('PDOStatement')\n            ->onlyMethods(['setFetchMode', 'execute', 'fetchAll', 'bindValue'])\n            ->getMock();\n        $statement->expects($this->once())->method('setFetchMode');\n        $statement->expects($this->once())->method('bindValue')->with('foo', 'bar', 2);\n        $statement->expects($this->once())->method('execute');\n        $statement->expects($this->once())->method('fetchAll')->willReturn(['boom']);\n        $pdo->expects($this->once())->method('prepare')->with('foo')->willReturn($statement);\n        $mock = $this->getMockConnection(['prepareBindings'], $writePdo);\n        $mock->setReadPdo($pdo);\n        $mock->expects($this->once())->method('prepareBindings')->with($this->equalTo(['foo' => 'bar']))->willReturn(['foo' => 'bar']);\n        $results = $mock->select('foo', ['foo' => 'bar']);\n        $this->assertEquals(['boom'], $results);\n        $log = $mock->getQueryLog();\n        $this->assertSame('foo', $log[0]['query']);\n        $this->assertEquals(['foo' => 'bar'], $log[0]['bindings']);\n        $this->assertIsNumeric($log[0]['time']);\n    }\n\n    public function testSelectResultsetsReturnsMultipleRowset()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $writePdo->expects($this->never())->method('prepare');\n        $statement = $this->getMockBuilder('PDOStatement')\n            ->onlyMethods(['setFetchMode', 'execute', 'fetchAll', 'bindValue', 'nextRowset'])\n            ->getMock();\n        $statement->expects($this->once())->method('setFetchMode');\n        $statement->expects($this->once())->method('bindValue')->with(1, 'foo', 2);\n        $statement->expects($this->once())->method('execute');\n        $statement->expects($this->atLeastOnce())->method('fetchAll')->willReturn(['boom']);\n        $statement->expects($this->atLeastOnce())->method('nextRowset')->willReturnCallback(function () {\n            static $i = 1;\n\n            return ++$i <= 2;\n        });\n        $pdo->expects($this->once())->method('prepare')->with('CALL a_procedure(?)')->willReturn($statement);\n        $mock = $this->getMockConnection(['prepareBindings'], $writePdo);\n        $mock->setReadPdo($pdo);\n        $mock->expects($this->once())->method('prepareBindings')->with($this->equalTo(['foo']))->willReturn(['foo']);\n        $results = $mock->selectResultsets('CALL a_procedure(?)', ['foo']);\n        $this->assertEquals([['boom'], ['boom']], $results);\n        $log = $mock->getQueryLog();\n        $this->assertSame('CALL a_procedure(?)', $log[0]['query']);\n        $this->assertEquals(['foo'], $log[0]['bindings']);\n        $this->assertIsNumeric($log[0]['time']);\n    }\n\n    public function testInsertCallsTheStatementMethod()\n    {\n        $connection = $this->getMockConnection(['statement']);\n        $connection->expects($this->once())->method('statement')->with($this->equalTo('foo'), $this->equalTo(['bar']))->willReturn('baz');\n        $results = $connection->insert('foo', ['bar']);\n        $this->assertSame('baz', $results);\n    }\n\n    public function testUpdateCallsTheAffectingStatementMethod()\n    {\n        $connection = $this->getMockConnection(['affectingStatement']);\n        $connection->expects($this->once())->method('affectingStatement')->with($this->equalTo('foo'), $this->equalTo(['bar']))->willReturn('baz');\n        $results = $connection->update('foo', ['bar']);\n        $this->assertSame('baz', $results);\n    }\n\n    public function testDeleteCallsTheAffectingStatementMethod()\n    {\n        $connection = $this->getMockConnection(['affectingStatement']);\n        $connection->expects($this->once())->method('affectingStatement')->with($this->equalTo('foo'), $this->equalTo(['bar']))->willReturn(true);\n        $results = $connection->delete('foo', ['bar']);\n        $this->assertTrue($results);\n    }\n\n    public function testStatementProperlyCallsPDO()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $statement = $this->getMockBuilder('PDOStatement')->onlyMethods(['execute', 'bindValue'])->getMock();\n        $statement->expects($this->once())->method('bindValue')->with(1, 'bar', 2);\n        $statement->expects($this->once())->method('execute')->willReturn(true);\n        $pdo->expects($this->once())->method('prepare')->with($this->equalTo('foo'))->willReturn($statement);\n        $mock = $this->getMockConnection(['prepareBindings'], $pdo);\n        $mock->expects($this->once())->method('prepareBindings')->with($this->equalTo(['bar']))->willReturn(['bar']);\n        $results = $mock->statement('foo', ['bar']);\n        $this->assertTrue($results);\n        $log = $mock->getQueryLog();\n        $this->assertSame('foo', $log[0]['query']);\n        $this->assertEquals(['bar'], $log[0]['bindings']);\n        $this->assertIsNumeric($log[0]['time']);\n    }\n\n    public function testAffectingStatementProperlyCallsPDO()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['prepare'])->getMock();\n        $statement = $this->getMockBuilder('PDOStatement')->onlyMethods(['execute', 'rowCount', 'bindValue'])->getMock();\n        $statement->expects($this->once())->method('bindValue')->with('foo', 'bar', 2);\n        $statement->expects($this->once())->method('execute');\n        $statement->expects($this->once())->method('rowCount')->willReturn(42);\n        $pdo->expects($this->once())->method('prepare')->with('foo')->willReturn($statement);\n        $mock = $this->getMockConnection(['prepareBindings'], $pdo);\n        $mock->expects($this->once())->method('prepareBindings')->with($this->equalTo(['foo' => 'bar']))->willReturn(['foo' => 'bar']);\n        $results = $mock->update('foo', ['foo' => 'bar']);\n        $this->assertSame(42, $results);\n        $log = $mock->getQueryLog();\n        $this->assertSame('foo', $log[0]['query']);\n        $this->assertEquals(['foo' => 'bar'], $log[0]['bindings']);\n        $this->assertIsNumeric($log[0]['time']);\n    }\n\n    public function testTransactionLevelNotIncrementedOnTransactionException()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $pdo->expects($this->once())->method('beginTransaction')->will($this->throwException(new Exception));\n        $connection = $this->getMockConnection([], $pdo);\n        try {\n            $connection->beginTransaction();\n        } catch (Exception) {\n            $this->assertEquals(0, $connection->transactionLevel());\n        }\n    }\n\n    public function testBeginTransactionMethodRetriesOnFailure()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $pdo->method('beginTransaction')\n            ->willReturnOnConsecutiveCalls($this->throwException(new ErrorException('server has gone away')), true);\n        $connection = $this->getMockConnection(['reconnect'], $pdo);\n        $connection->expects($this->once())->method('reconnect');\n        $connection->beginTransaction();\n        $this->assertEquals(1, $connection->transactionLevel());\n    }\n\n    public function testBeginTransactionMethodReconnectsMissingConnection()\n    {\n        $connection = $this->getMockConnection();\n        $connection->setReconnector(function ($connection) {\n            $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n            $connection->setPdo($pdo);\n        });\n        $connection->disconnect();\n        $connection->beginTransaction();\n        $this->assertEquals(1, $connection->transactionLevel());\n    }\n\n    public function testBeginTransactionMethodNeverRetriesIfWithinTransaction()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $pdo->expects($this->once())->method('beginTransaction');\n        $pdo->expects($this->once())->method('exec')->will($this->throwException(new Exception));\n        $connection = $this->getMockConnection(['reconnect'], $pdo);\n        $queryGrammar = $this->createMock(Grammar::class);\n        $queryGrammar->expects($this->once())->method('compileSavepoint')->willReturn('trans1');\n        $queryGrammar->expects($this->once())->method('supportsSavepoints')->willReturn(true);\n        $connection->setQueryGrammar($queryGrammar);\n        $connection->expects($this->never())->method('reconnect');\n        $connection->beginTransaction();\n        $this->assertEquals(1, $connection->transactionLevel());\n        try {\n            $connection->beginTransaction();\n        } catch (Exception) {\n            $this->assertEquals(1, $connection->transactionLevel());\n        }\n    }\n\n    public function testSwapPDOWithOpenTransactionResetsTransactionLevel()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $pdo->expects($this->once())->method('beginTransaction')->willReturn(true);\n        $connection = $this->getMockConnection([], $pdo);\n        $connection->beginTransaction();\n        $connection->disconnect();\n        $this->assertEquals(0, $connection->transactionLevel());\n    }\n\n    public function testBeganTransactionFiresEventsIfSet()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $connection = $this->getMockConnection(['getName'], $pdo);\n        $connection->expects($this->any())->method('getName')->willReturn('name');\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(TransactionBeginning::class));\n        $connection->beginTransaction();\n    }\n\n    public function testCommittedFiresEventsIfSet()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $connection = $this->getMockConnection(['getName'], $pdo);\n        $connection->expects($this->any())->method('getName')->willReturn('name');\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(TransactionCommitted::class));\n        $connection->commit();\n    }\n\n    public function testCommittingFiresEventsIfSet()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $connection = $this->getMockConnection(['getName', 'transactionLevel'], $pdo);\n        $connection->expects($this->any())->method('getName')->willReturn('name');\n        $connection->expects($this->any())->method('transactionLevel')->willReturn(1);\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(TransactionCommitting::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(TransactionCommitted::class));\n        $connection->commit();\n    }\n\n    public function testRollBackedFiresEventsIfSet()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $connection = $this->getMockConnection(['getName'], $pdo);\n        $connection->expects($this->any())->method('getName')->willReturn('name');\n        $connection->beginTransaction();\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(TransactionRolledBack::class));\n        $connection->rollBack();\n    }\n\n    public function testRedundantRollBackFiresNoEvent()\n    {\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $connection = $this->getMockConnection(['getName'], $pdo);\n        $connection->expects($this->any())->method('getName')->willReturn('name');\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldNotReceive('dispatch');\n        $connection->rollBack();\n    }\n\n    public function testTransactionMethodRunsSuccessfully()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['beginTransaction', 'commit'])->getMock();\n        $mock = $this->getMockConnection([], $pdo);\n        $pdo->expects($this->once())->method('beginTransaction');\n        $pdo->expects($this->once())->method('commit');\n        $result = $mock->transaction(function ($db) {\n            return $db;\n        });\n        $this->assertEquals($mock, $result);\n    }\n\n    public function testTransactionRetriesOnCommitDeadlockWhenPDOHasActiveTransaction()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['inTransaction', 'beginTransaction', 'commit', 'rollBack'])->getMock();\n        $mock = $this->getMockConnection([], $pdo);\n\n        $pdo->expects($this->exactly(2))->method('beginTransaction');\n        $pdo->expects($this->exactly(2))->method('commit')->willReturnOnConsecutiveCalls(\n            $this->throwException(new DatabaseConnectionTestMockPDOException('Serialization failure', '40001')),\n            true,\n        );\n        $pdo->method('inTransaction')->willReturn(true);\n        $pdo->expects($this->once())->method('rollBack');\n\n        $result = $mock->transaction(function () {\n            return 'success';\n        }, 2);\n\n        $this->assertSame('success', $result);\n    }\n\n    public function testTransactionRetriesOnSerializationFailure()\n    {\n        $this->expectException(PDOException::class);\n        $this->expectExceptionMessage('Serialization failure');\n\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['inTransaction', 'beginTransaction', 'commit', 'rollBack'])->getMock();\n        $mock = $this->getMockConnection([], $pdo);\n        $pdo->expects($this->exactly(3))->method('commit')->will($this->throwException(new DatabaseConnectionTestMockPDOException('Serialization failure', '40001')));\n        $pdo->expects($this->exactly(3))->method('beginTransaction');\n        $pdo->method('inTransaction')->willReturn(true);\n        $pdo->expects($this->exactly(2))->method('rollBack');\n        $mock->transaction(function () {\n        }, 3);\n    }\n\n    public function testTransactionMethodRetriesOnDeadlock()\n    {\n        $this->expectException(QueryException::class);\n        $this->expectExceptionMessage('Deadlock found when trying to get lock (Connection: conn, SQL: )');\n\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['inTransaction', 'beginTransaction', 'commit', 'rollBack'])->getMock();\n        $mock = $this->getMockConnection([], $pdo);\n        $pdo->method('inTransaction')->willReturn(true);\n        $pdo->expects($this->exactly(3))->method('beginTransaction');\n        $pdo->expects($this->exactly(3))->method('rollBack');\n        $pdo->expects($this->never())->method('commit');\n        $mock->transaction(function () {\n            throw new QueryException('conn', '', [], new Exception('Deadlock found when trying to get lock'));\n        }, 3);\n    }\n\n    public function testTransactionMethodRollsbackAndThrows()\n    {\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['inTransaction', 'beginTransaction', 'commit', 'rollBack'])->getMock();\n        $mock = $this->getMockConnection([], $pdo);\n        // $pdo->expects($this->once())->method('inTransaction');\n        $pdo->method('inTransaction')->willReturn(true);\n        $pdo->expects($this->once())->method('beginTransaction');\n        $pdo->expects($this->once())->method('rollBack');\n        $pdo->expects($this->never())->method('commit');\n        try {\n            $mock->transaction(function () {\n                throw new Exception('foo');\n            });\n        } catch (Exception $e) {\n            $this->assertSame('foo', $e->getMessage());\n        }\n    }\n\n    public function testOnLostConnectionPDOIsNotSwappedWithinATransaction()\n    {\n        $this->expectException(QueryException::class);\n        $this->expectExceptionMessage('server has gone away (Connection: , Host: , Port: , Database: , SQL: foo)');\n\n        $pdo = m::mock(PDO::class);\n        $pdo->shouldReceive('beginTransaction')->once();\n        $statement = m::mock(PDOStatement::class);\n        $pdo->shouldReceive('prepare')->once()->andReturn($statement);\n        $statement->shouldReceive('execute')->once()->andThrow(new PDOException('server has gone away'));\n\n        $connection = new Connection($pdo);\n        $connection->beginTransaction();\n        $connection->statement('foo');\n    }\n\n    public function testOnLostConnectionPDOIsSwappedOutsideTransaction()\n    {\n        $pdo = m::mock(PDO::class);\n\n        $statement = m::mock(PDOStatement::class);\n        $statement->shouldReceive('execute')->once()->andThrow(new PDOException('server has gone away'));\n        $statement->shouldReceive('execute')->once()->andReturn(true);\n\n        $pdo->shouldReceive('prepare')->twice()->andReturn($statement);\n\n        $connection = new Connection($pdo);\n\n        $called = false;\n\n        $connection->setReconnector(function ($connection) use (&$called) {\n            $called = true;\n        });\n\n        $this->assertTrue($connection->statement('foo'));\n\n        $this->assertTrue($called);\n    }\n\n    public function testRunMethodRetriesOnFailure()\n    {\n        $method = (new ReflectionClass(Connection::class))->getMethod('run');\n\n        $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class);\n        $mock = $this->getMockConnection(['tryAgainIfCausedByLostConnection'], $pdo);\n        $mock->expects($this->once())->method('tryAgainIfCausedByLostConnection');\n\n        $method->invokeArgs($mock, ['', [], function () {\n            throw new QueryException('', '', [], new Exception);\n        }]);\n    }\n\n    public function testRunMethodNeverRetriesIfWithinTransaction()\n    {\n        $this->expectException(QueryException::class);\n        $this->expectExceptionMessage('(Connection: conn, SQL: ) (Connection: , Host: , Port: , Database: , SQL: )');\n\n        $method = (new ReflectionClass(Connection::class))->getMethod('run');\n\n        $pdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)->onlyMethods(['beginTransaction'])->getMock();\n        $mock = $this->getMockConnection(['tryAgainIfCausedByLostConnection'], $pdo);\n        $pdo->expects($this->once())->method('beginTransaction');\n        $mock->expects($this->never())->method('tryAgainIfCausedByLostConnection');\n        $mock->beginTransaction();\n\n        $method->invokeArgs($mock, ['', [], function () {\n            throw new QueryException('conn', '', [], new Exception);\n        }]);\n    }\n\n    public function testFromCreatesNewQueryBuilder()\n    {\n        $conn = $this->getMockConnection();\n        $conn->setQueryGrammar(m::mock(Grammar::class));\n        $conn->setPostProcessor(m::mock(Processor::class));\n        $builder = $conn->table('users');\n        $this->assertInstanceOf(BaseBuilder::class, $builder);\n        $this->assertSame('users', $builder->from);\n    }\n\n    public function testPrepareBindings()\n    {\n        $date = m::mock(DateTime::class);\n        $date->shouldReceive('format')->once()->with('foo')->andReturn('bar');\n        $bindings = ['test' => $date];\n        $conn = $this->getMockConnection();\n        $grammar = m::mock(Grammar::class);\n        $grammar->shouldReceive('getDateFormat')->once()->andReturn('foo');\n        $conn->setQueryGrammar($grammar);\n        $result = $conn->prepareBindings($bindings);\n        $this->assertEquals(['test' => 'bar'], $result);\n    }\n\n    public function testLogQueryFiresEventsIfSet()\n    {\n        $connection = $this->getMockConnection();\n        $connection->logQuery('foo', [], time());\n        $connection->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(QueryExecuted::class));\n        $connection->logQuery('foo', [], null);\n    }\n\n    public function testBeforeExecutingHooksCanBeRegistered()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('The callback was fired');\n\n        $connection = $this->getMockConnection();\n        $connection->beforeExecuting(function () {\n            throw new Exception('The callback was fired');\n        });\n        $connection->select('foo bar', ['baz']);\n    }\n\n    public function testBeforeStartingTransactionHooksCanBeRegistered()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('The callback was fired');\n\n        $connection = $this->getMockConnection();\n        $connection->beforeStartingTransaction(function () {\n            throw new Exception('The callback was fired');\n        });\n        $connection->beginTransaction();\n    }\n\n    public function testPretendOnlyLogsQueries()\n    {\n        $connection = $this->getMockConnection();\n        $queries = $connection->pretend(function ($connection) {\n            $connection->select('foo bar', ['baz']);\n        });\n        $this->assertSame('foo bar', $queries[0]['query']);\n        $this->assertEquals(['baz'], $queries[0]['bindings']);\n    }\n\n    public function testSchemaBuilderCanBeCreated()\n    {\n        $connection = $this->getMockConnection();\n        $schema = $connection->getSchemaBuilder();\n        $this->assertInstanceOf(Builder::class, $schema);\n        $this->assertSame($connection, $schema->getConnection());\n    }\n\n    public function testGetRawQueryLog()\n    {\n        $mock = $this->getMockConnection(['getQueryLog']);\n        $mock->expects($this->once())->method('getQueryLog')->willReturn([\n            [\n                'query' => 'select * from tbl where col = ?',\n                'bindings' => [\n                    0 => 'foo',\n                ],\n                'time' => 1.23,\n            ],\n        ]);\n\n        $queryGrammar = $this->createMock(Grammar::class);\n        $queryGrammar->expects($this->once())\n            ->method('substituteBindingsIntoRawSql')\n            ->with('select * from tbl where col = ?', ['foo'])\n            ->willReturn(\"select * from tbl where col = 'foo'\");\n        $mock->setQueryGrammar($queryGrammar);\n\n        $log = $mock->getRawQueryLog();\n\n        $this->assertEquals(\"select * from tbl where col = 'foo'\", $log[0]['raw_query']);\n        $this->assertEquals(1.23, $log[0]['time']);\n    }\n\n    public function testQueryExceptionContainsReadConnectionDetailsWhenUsingReadPdo()\n    {\n        // Create write PDO mock that will NOT be used for this query\n        $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)\n            ->onlyMethods(['prepare'])\n            ->getMock();\n        $writePdo->expects($this->never())->method('prepare');\n\n        // Create read PDO mock that throws an exception\n        $readPdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)\n            ->onlyMethods(['prepare'])\n            ->getMock();\n        $readPdo->expects($this->once())\n            ->method('prepare')\n            ->willThrowException(new PDOException('Connection refused'));\n\n        // Write configuration (passed to constructor)\n        $writeConfig = [\n            'driver' => 'mysql',\n            'name' => 'mysql',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'write_db',\n        ];\n\n        // Create connection with write config\n        $connection = new Connection($writePdo, 'write_db', '', $writeConfig);\n        $connection->useDefaultQueryGrammar();\n        $connection->useDefaultPostProcessor();\n\n        // Read configuration (different from write)\n        $readConfig = [\n            'host' => '192.168.1.20',\n            'port' => '3307',\n            'database' => 'read_db',\n        ];\n\n        // Set read PDO and its config\n        $connection->setReadPdo($readPdo);\n        $connection->setReadPdoConfig($readConfig);\n\n        try {\n            $connection->select('SELECT * FROM users', useReadPdo: true);\n            $this->fail('Expected QueryException was not thrown');\n        } catch (QueryException $e) {\n            // Verify the readWriteType is correctly set to 'read'\n            $this->assertSame('read', $e->readWriteType);\n\n            // Verify connection details show READ config, not write config\n            $connectionDetails = $e->getConnectionDetails();\n            $this->assertSame('192.168.1.20', $connectionDetails['host']);\n            $this->assertSame('3307', $connectionDetails['port']);\n            $this->assertSame('read_db', $connectionDetails['database']);\n        }\n    }\n\n    public function testQueryExceptionContainsReadConnectionDetailsWhenReadPdoConnectionFails()\n    {\n        // Write PDO (won't be used)\n        $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)\n            ->onlyMethods(['prepare'])\n            ->getMock();\n        $writePdo->expects($this->never())->method('prepare');\n\n        // Write configuration\n        $writeConfig = [\n            'driver' => 'mysql',\n            'name' => 'mysql',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'write_db',\n        ];\n\n        $connection = new Connection($writePdo, 'write_db', '', $writeConfig);\n        $connection->useDefaultQueryGrammar();\n        $connection->useDefaultPostProcessor();\n\n        // Read config (different host)\n        $readConfig = [\n            'host' => '192.168.1.20',\n            'port' => '3307',\n            'database' => 'read_db',\n        ];\n\n        // Simulate lazy PDO that fails during connection (e.g., SET NAMES fails)\n        $connection->setReadPdo(function () {\n            throw new PDOException('SQLSTATE[HY000] SET NAMES failed');\n        });\n        $connection->setReadPdoConfig($readConfig);\n\n        try {\n            $connection->select('SELECT * FROM users', useReadPdo: true);\n            $this->fail('Expected QueryException was not thrown');\n        } catch (QueryException $e) {\n            $this->assertSame('read', $e->readWriteType);\n\n            // Verify connection details show READ config even for connection-time failures\n            $connectionDetails = $e->getConnectionDetails();\n            $this->assertSame('192.168.1.20', $connectionDetails['host']);\n            $this->assertSame('3307', $connectionDetails['port']);\n            $this->assertSame('read_db', $connectionDetails['database']);\n        }\n    }\n\n    public function testQueryExceptionContainsWriteConnectionDetailsWhenUsingWritePdo()\n    {\n        // Create write PDO mock that throws an exception\n        $writePdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)\n            ->onlyMethods(['prepare'])\n            ->getMock();\n        $writePdo->expects($this->once())\n            ->method('prepare')\n            ->willThrowException(new PDOException('Connection refused'));\n\n        // Create read PDO mock that will NOT be used\n        $readPdo = $this->getMockBuilder(DatabaseConnectionTestMockPDO::class)\n            ->onlyMethods(['prepare'])\n            ->getMock();\n        $readPdo->expects($this->never())->method('prepare');\n\n        // Write configuration (passed to constructor)\n        $writeConfig = [\n            'driver' => 'mysql',\n            'name' => 'mysql',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'write_db',\n        ];\n\n        $connection = new Connection($writePdo, 'write_db', '', $writeConfig);\n        $connection->useDefaultQueryGrammar();\n        $connection->useDefaultPostProcessor();\n\n        // Read configuration (different from write)\n        $readConfig = [\n            'host' => '192.168.1.20',\n            'port' => '3307',\n            'database' => 'read_db',\n        ];\n\n        $connection->setReadPdo($readPdo);\n        $connection->setReadPdoConfig($readConfig);\n\n        try {\n            $connection->select('SELECT * FROM users', useReadPdo: false);\n            $this->fail('Expected QueryException was not thrown');\n        } catch (QueryException $e) {\n            // Verify the readWriteType is correctly set to 'write'\n            $this->assertSame('write', $e->readWriteType);\n\n            // Verify connection details show WRITE config, not read config\n            $connectionDetails = $e->getConnectionDetails();\n            $this->assertSame('192.168.1.10', $connectionDetails['host']);\n            $this->assertSame('3306', $connectionDetails['port']);\n            $this->assertSame('write_db', $connectionDetails['database']);\n        }\n    }\n\n    public function testQueryExceptionContainsWriteConnectionDetailsWhenWritePdoConnectionFails()\n    {\n        // Write configuration\n        $writeConfig = [\n            'driver' => 'mysql',\n            'name' => 'mysql',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'write_db',\n        ];\n\n        // Simulate lazy write PDO that fails during connection (e.g., SET NAMES fails)\n        $connection = new Connection(function () {\n            throw new PDOException('SQLSTATE[HY000] SET NAMES failed');\n        }, 'write_db', '', $writeConfig);\n        $connection->useDefaultQueryGrammar();\n        $connection->useDefaultPostProcessor();\n\n        // Read config (different host)\n        $readConfig = [\n            'host' => '192.168.1.20',\n            'port' => '3307',\n            'database' => 'read_db',\n        ];\n\n        $connection->setReadPdo(new DatabaseConnectionTestMockPDO);\n        $connection->setReadPdoConfig($readConfig);\n\n        try {\n            $connection->select('SELECT * FROM users', useReadPdo: false);\n            $this->fail('Expected QueryException was not thrown');\n        } catch (QueryException $e) {\n            $this->assertSame('write', $e->readWriteType);\n\n            // Verify connection details show WRITE config even for connection-time failures\n            $connectionDetails = $e->getConnectionDetails();\n            $this->assertSame('192.168.1.10', $connectionDetails['host']);\n            $this->assertSame('3306', $connectionDetails['port']);\n            $this->assertSame('write_db', $connectionDetails['database']);\n        }\n    }\n\n    protected function getMockConnection($methods = [], $pdo = null)\n    {\n        $pdo = $pdo ?: new DatabaseConnectionTestMockPDO;\n        $defaults = ['getDefaultQueryGrammar', 'getDefaultPostProcessor', 'getDefaultSchemaGrammar'];\n        $connection = $this->getMockBuilder(Connection::class)->onlyMethods(array_merge($defaults, $methods))->setConstructorArgs([$pdo])->getMock();\n        $connection->enableQueryLog();\n\n        return $connection;\n    }\n}\n\nclass DatabaseConnectionTestMockPDO extends PDO\n{\n    public function __construct()\n    {\n        //\n    }\n}\n\nclass DatabaseConnectionTestMockPDOException extends PDOException\n{\n    /**\n     * Overrides Exception::__construct, which casts $code to integer, so that we can create\n     * an exception with a string $code consistent with the real PDOException behavior.\n     *\n     * @param  string|null  $message\n     * @param  string|null  $code\n     */\n    public function __construct($message = null, $code = null)\n    {\n        $this->message = $message;\n        $this->code = $code;\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseConnectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connectors\\Connector;\nuse Illuminate\\Database\\Connectors\\MySqlConnector;\nuse Illuminate\\Database\\Connectors\\PostgresConnector;\nuse Illuminate\\Database\\Connectors\\SQLiteConnector;\nuse Illuminate\\Database\\Connectors\\SqlServerConnector;\nuse Mockery as m;\nuse PDO;\nuse PDOStatement;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseConnectorTest extends TestCase\n{\n    public function testOptionResolution()\n    {\n        $connector = new Connector;\n        $connector->setDefaultOptions([0 => 'foo', 1 => 'bar']);\n        $this->assertEquals([0 => 'baz', 1 => 'bar', 2 => 'boom'], $connector->getOptions(['options' => [0 => 'baz', 2 => 'boom']]));\n    }\n\n    #[DataProvider('mySqlConnectProvider')]\n    public function testMySqlConnectCallsCreateConnectionWithProperArguments($dsn, $config)\n    {\n        $connector = $this->getMockBuilder(MySqlConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(PDO::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $connection->shouldReceive('exec')->once()->with('use `bar`;')->andReturn(true);\n        $connection->shouldReceive('exec')->once()->with(\"SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';\")->andReturn(true);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public static function mySqlConnectProvider()\n    {\n        return [\n            ['mysql:host=foo;dbname=bar', ['host' => 'foo', 'database' => 'bar', 'collation' => 'utf8_unicode_ci', 'charset' => 'utf8']],\n            ['mysql:host=foo;port=111;dbname=bar', ['host' => 'foo', 'database' => 'bar', 'port' => 111, 'collation' => 'utf8_unicode_ci', 'charset' => 'utf8']],\n            ['mysql:unix_socket=baz;dbname=bar', ['host' => 'foo', 'database' => 'bar', 'port' => 111, 'unix_socket' => 'baz', 'collation' => 'utf8_unicode_ci', 'charset' => 'utf8']],\n        ];\n    }\n\n    public function testMySqlConnectCallsCreateConnectionWithIsolationLevel()\n    {\n        $dsn = 'mysql:host=foo;dbname=bar';\n        $config = ['host' => 'foo', 'database' => 'bar', 'collation' => 'utf8_unicode_ci', 'charset' => 'utf8', 'isolation_level' => 'REPEATABLE READ'];\n\n        $connector = $this->getMockBuilder(MySqlConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(PDO::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $connection->shouldReceive('exec')->once()->with('use `bar`;')->andReturn(true);\n        $connection->shouldReceive('exec')->once()->with('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;')->andReturn(true);\n        $connection->shouldReceive('exec')->once()->with(\"SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';\")->andReturn(true);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testPostgresConnectCallsCreateConnectionWithProperArguments()\n    {\n        $dsn = 'pgsql:host=foo;dbname=\\'bar\\';port=111;client_encoding=\\'utf8\\'';\n        $config = ['host' => 'foo', 'database' => 'bar', 'port' => 111, 'charset' => 'utf8'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->zeroOrMoreTimes()->andReturn($statement);\n        $statement->shouldReceive('execute')->zeroOrMoreTimes();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    /**\n     * @param  string  $searchPath\n     * @param  string  $expectedSql\n     */\n    #[DataProvider('provideSearchPaths')]\n    public function testPostgresSearchPathIsSet($searchPath, $expectedSql)\n    {\n        $dsn = 'pgsql:host=foo;dbname=\\'bar\\';client_encoding=\\'utf8\\'';\n        $config = ['host' => 'foo', 'database' => 'bar', 'search_path' => $searchPath, 'charset' => 'utf8'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->once()->with($expectedSql)->andReturn($statement);\n        $statement->shouldReceive('execute')->once();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public static function provideSearchPaths()\n    {\n        return [\n            'all-lowercase' => [\n                'public',\n                'set search_path to \"public\"',\n            ],\n            'case-sensitive' => [\n                'Public',\n                'set search_path to \"Public\"',\n            ],\n            'special characters' => [\n                '¡foo_bar-Baz!.Áüõß',\n                'set search_path to \"¡foo_bar-Baz!.Áüõß\"',\n            ],\n            'single-quoted' => [\n                \"'public'\",\n                'set search_path to \"public\"',\n            ],\n            'double-quoted' => [\n                '\"public\"',\n                'set search_path to \"public\"',\n            ],\n            'variable' => [\n                '$user',\n                'set search_path to \"$user\"',\n            ],\n            'delimit space' => [\n                'public user',\n                'set search_path to \"public\", \"user\"',\n            ],\n            'delimit newline' => [\n                \"public\\nuser\\r\\n\\ttest\",\n                'set search_path to \"public\", \"user\", \"test\"',\n            ],\n            'delimit comma' => [\n                'public,user',\n                'set search_path to \"public\", \"user\"',\n            ],\n            'delimit comma and space' => [\n                'public, user',\n                'set search_path to \"public\", \"user\"',\n            ],\n            'single-quoted many' => [\n                \"'public', 'user'\",\n                'set search_path to \"public\", \"user\"',\n            ],\n            'double-quoted many' => [\n                '\"public\", \"user\"',\n                'set search_path to \"public\", \"user\"',\n            ],\n            'quoted space is unsupported in string' => [\n                '\"public user\"',\n                'set search_path to \"public\", \"user\"',\n            ],\n            'array' => [\n                ['public', 'user'],\n                'set search_path to \"public\", \"user\"',\n            ],\n            'array with variable' => [\n                ['public', '$user'],\n                'set search_path to \"public\", \"$user\"',\n            ],\n            'array with delimiter characters' => [\n                ['public', '\"user\"', \"'test'\", 'spaced schema'],\n                'set search_path to \"public\", \"user\", \"test\", \"spaced schema\"',\n            ],\n        ];\n    }\n\n    public function testPostgresSearchPathFallbackToConfigKeySchema()\n    {\n        $dsn = 'pgsql:host=foo;dbname=\\'bar\\';client_encoding=\\'utf8\\'';\n        $config = ['host' => 'foo', 'database' => 'bar', 'schema' => ['public', '\"user\"'], 'charset' => 'utf8'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->once()->with('set search_path to \"public\", \"user\"')->andReturn($statement);\n        $statement->shouldReceive('execute')->once();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testPostgresApplicationNameIsSet()\n    {\n        $dsn = 'pgsql:host=foo;dbname=\\'bar\\';client_encoding=\\'utf8\\';application_name=\\'Laravel App\\'';\n        $config = ['host' => 'foo', 'database' => 'bar', 'charset' => 'utf8', 'application_name' => 'Laravel App'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->zeroOrMoreTimes()->andReturn($statement);\n        $statement->shouldReceive('execute')->zeroOrMoreTimes();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testPostgresApplicationUseAlternativeDatabaseName()\n    {\n        $dsn = 'pgsql:dbname=\\'baz\\'';\n        $config = ['database' => 'bar', 'connect_via_database' => 'baz'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->zeroOrMoreTimes()->andReturn($statement);\n        $statement->shouldReceive('execute')->zeroOrMoreTimes();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testPostgresApplicationUseAlternativeDatabaseNameAndPort()\n    {\n        $dsn = 'pgsql:dbname=\\'baz\\';port=2345';\n        $config = ['database' => 'bar', 'connect_via_database' => 'baz', 'port' => 5432, 'connect_via_port' => 2345];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->zeroOrMoreTimes()->andReturn($statement);\n        $statement->shouldReceive('execute')->zeroOrMoreTimes();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testPostgresConnectorReadsIsolationLevelFromConfig()\n    {\n        $dsn = 'pgsql:host=foo;dbname=\\'bar\\';port=111';\n        $config = ['host' => 'foo', 'database' => 'bar', 'port' => 111, 'isolation_level' => 'SERIALIZABLE'];\n        $connector = $this->getMockBuilder(PostgresConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(PDO::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $statement = m::mock(PDOStatement::class);\n        $connection->shouldReceive('prepare')->once()->with('set session characteristics as transaction isolation level SERIALIZABLE')->andReturn($statement);\n        $statement->shouldReceive('execute')->zeroOrMoreTimes();\n        $connection->shouldReceive('exec')->zeroOrMoreTimes();\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testSQLiteMemoryDatabasesMayBeConnectedTo()\n    {\n        $dsn = 'sqlite::memory:';\n        $config = ['database' => ':memory:'];\n        $connector = $this->getMockBuilder(SQLiteConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testSQLiteNamedMemoryDatabasesMayBeConnectedTo()\n    {\n        $dsn = 'sqlite:file:mydb?mode=memory&cache=shared';\n        $config = ['database' => 'file:mydb?mode=memory&cache=shared'];\n        $connector = $this->getMockBuilder(SQLiteConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testSQLiteFileDatabasesMayBeConnectedTo()\n    {\n        $dsn = 'sqlite:'.__DIR__;\n        $config = ['database' => __DIR__];\n        $connector = $this->getMockBuilder(SQLiteConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testSqlServerConnectCallsCreateConnectionWithProperArguments()\n    {\n        $config = ['host' => 'foo', 'database' => 'bar', 'port' => 111];\n        $dsn = $this->getDsn($config);\n        $connector = $this->getMockBuilder(SqlServerConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    public function testSqlServerConnectCallsCreateConnectionWithOptionalArguments()\n    {\n        $config = ['host' => 'foo', 'database' => 'bar', 'port' => 111, 'readonly' => true, 'charset' => 'utf-8', 'pooling' => false, 'appname' => 'baz'];\n        $dsn = $this->getDsn($config);\n        $connector = $this->getMockBuilder(SqlServerConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    #[RequiresPhpExtension('odbc')]\n    public function testSqlServerConnectCallsCreateConnectionWithPreferredODBC()\n    {\n        $config = ['odbc' => true, 'odbc_datasource_name' => 'server=localhost;database=test;'];\n        $dsn = $this->getDsn($config);\n        $connector = $this->getMockBuilder(SqlServerConnector::class)->onlyMethods(['createConnection', 'getOptions'])->getMock();\n        $connection = m::mock(stdClass::class);\n        $connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);\n        $connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);\n        $result = $connector->connect($config);\n\n        $this->assertSame($result, $connection);\n    }\n\n    protected function getDsn(array $config)\n    {\n        extract($config, EXTR_SKIP);\n\n        $availableDrivers = PDO::getAvailableDrivers();\n\n        if (in_array('odbc', $availableDrivers) &&\n            ($config['odbc'] ?? null) === true) {\n            return isset($config['odbc_datasource_name'])\n                ? 'odbc:'.$config['odbc_datasource_name'] : '';\n        }\n\n        if (in_array('sqlsrv', $availableDrivers)) {\n            $port = isset($config['port']) ? ','.$port : '';\n            $appname = isset($config['appname']) ? ';APP='.$config['appname'] : '';\n            $readonly = isset($config['readonly']) ? ';ApplicationIntent=ReadOnly' : '';\n            $pooling = (isset($config['pooling']) && $config['pooling'] == false) ? ';ConnectionPooling=0' : '';\n\n            return \"sqlsrv:Server={$host}{$port};Database={$database}{$readonly}{$pooling}{$appname}\";\n        } else {\n            $port = isset($config['port']) ? ':'.$port : '';\n            $appname = isset($config['appname']) ? ';appname='.$config['appname'] : '';\n            $charset = isset($config['charset']) ? ';charset='.$config['charset'] : '';\n\n            return \"dblib:host={$host}{$port};dbname={$database}{$charset}{$appname}\";\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentAsBinaryCastTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\AsBinary;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\BinaryCodec;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\nuse Symfony\\Component\\Uid\\Ulid;\n\nclass DatabaseEloquentAsBinaryCastTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        $reflection = new \\ReflectionClass(BinaryCodec::class);\n        $property = $reflection->getProperty('customCodecs');\n        $property->setValue(null, []);\n\n        parent::tearDown();\n    }\n\n    public function testCastThrowsWhenFormatMissing()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The binary codec format is required.');\n\n        $model = new AsBinaryTestModel;\n        $model->setRawAttributes(['no_format' => 'value']);\n        $model->no_format;\n    }\n\n    public function testCastThrowsOnInvalidFormat()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Unsupported binary codec format [invalid]. Allowed formats are: uuid, ulid.');\n\n        $model = new AsBinaryTestModel;\n        $model->setRawAttributes(['invalid_format' => 'value']);\n        $model->invalid_format;\n    }\n\n    public function testGetDecodesUuidFromBinary()\n    {\n        $uuid = '550e8400-e29b-41d4-a716-446655440000';\n        $model = new AsBinaryTestModel;\n        $model->setRawAttributes(['uuid' => Uuid::fromString($uuid)->getBytes()]);\n\n        $this->assertSame($uuid, $model->uuid);\n    }\n\n    public function testSetEncodesUuidToBinary()\n    {\n        $uuid = '550e8400-e29b-41d4-a716-446655440000';\n        $model = new AsBinaryTestModel;\n        $model->uuid = $uuid;\n\n        $this->assertSame(Uuid::fromString($uuid)->getBytes(), $model->getAttributes()['uuid']);\n    }\n\n    public function testGetDecodesUlidFromBinary()\n    {\n        $ulid = '01ARZ3NDEKTSV4RRFFQ69G5FAV';\n        $model = new AsBinaryTestModel;\n        $model->setRawAttributes(['ulid' => Ulid::fromString($ulid)->toBinary()]);\n\n        $this->assertSame($ulid, $model->ulid);\n    }\n\n    public function testSetEncodesUlidToBinary()\n    {\n        $ulid = '01ARZ3NDEKTSV4RRFFQ69G5FAV';\n        $model = new AsBinaryTestModel;\n        $model->ulid = $ulid;\n\n        $this->assertSame(Ulid::fromString($ulid)->toBinary(), $model->getAttributes()['ulid']);\n    }\n\n    public function testGetReturnsNullForNullValue()\n    {\n        $model = new AsBinaryTestModel;\n        $model->setRawAttributes(['uuid' => null]);\n\n        $this->assertNull($model->uuid);\n    }\n\n    public function testSetEncodesNullToNull()\n    {\n        $model = new AsBinaryTestModel;\n        $model->uuid = null;\n\n        $this->assertNull($model->getAttributes()['uuid']);\n    }\n\n    public function testUuidHelperMethod()\n    {\n        $this->assertSame(AsBinary::class.':uuid', AsBinary::uuid());\n    }\n\n    public function testUlidHelperMethod()\n    {\n        $this->assertSame(AsBinary::class.':ulid', AsBinary::ulid());\n    }\n\n    public function testOfHelperMethod()\n    {\n        $this->assertSame(AsBinary::class.':custom', AsBinary::of('custom'));\n    }\n}\n\nclass AsBinaryTestModel extends Model\n{\n    protected $guarded = [];\n\n    protected function casts(): array\n    {\n        return [\n            'uuid' => AsBinary::class.':uuid',\n            'ulid' => AsBinary::class.':ulid',\n            'no_format' => AsBinary::class,\n            'invalid_format' => AsBinary::class.':invalid',\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyAggregateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Query\\Expression;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyAggregateTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    public function testWithSumDifferentTables()\n    {\n        $this->seedData();\n\n        $order = BelongsToManyAggregateTestTestOrder::query()\n            ->withSum('products as total_products', 'order_product.quantity')\n            ->first();\n\n        $this->assertEquals(12, $order->total_products);\n    }\n\n    public function testWithSumSameTable()\n    {\n        $this->seedData();\n\n        $order = BelongsToManyAggregateTestTestTransaction::query()\n            ->withSum('allocatedTo as total_allocated', 'allocations.amount')\n            ->first();\n\n        $this->assertEquals(1200, $order->total_allocated);\n    }\n\n    public function testWithSumExpression()\n    {\n        $this->seedData();\n\n        $order = BelongsToManyAggregateTestTestTransaction::query()\n            ->withSum('allocatedTo as total_allocated', new Expression('allocations.amount * 2'))\n            ->first();\n\n        $this->assertEquals(2400, $order->total_allocated);\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('orders', function ($table) {\n            $table->increments('id');\n        });\n\n        $this->schema()->create('products', function ($table) {\n            $table->increments('id');\n        });\n\n        $this->schema()->create('order_product', function ($table) {\n            $table->integer('order_id')->unsigned();\n            $table->foreign('order_id')->references('id')->on('orders');\n            $table->integer('product_id')->unsigned();\n            $table->foreign('product_id')->references('id')->on('products');\n            $table->integer('quantity')->unsigned();\n        });\n\n        $this->schema()->create('transactions', function ($table) {\n            $table->increments('id');\n            $table->integer('value')->unsigned();\n        });\n\n        $this->schema()->create('allocations', function ($table) {\n            $table->integer('from_id')->unsigned();\n            $table->foreign('from_id')->references('id')->on('transactions');\n            $table->integer('to_id')->unsigned();\n            $table->foreign('to_id')->references('id')->on('transactions');\n            $table->integer('amount')->unsigned();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('orders');\n        $this->schema()->drop('products');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $order = BelongsToManyAggregateTestTestOrder::create(['id' => 1]);\n\n        BelongsToManyAggregateTestTestProduct::query()->insert([\n            ['id' => 1],\n            ['id' => 2],\n            ['id' => 3],\n        ]);\n\n        $order->products()->sync([\n            1 => ['quantity' => 3],\n            2 => ['quantity' => 4],\n            3 => ['quantity' => 5],\n        ]);\n\n        $transaction = BelongsToManyAggregateTestTestTransaction::create(['id' => 1, 'value' => 1200]);\n\n        BelongsToManyAggregateTestTestTransaction::query()->insert([\n            ['id' => 2, 'value' => -300],\n            ['id' => 3, 'value' => -400],\n            ['id' => 4, 'value' => -500],\n        ]);\n\n        $transaction->allocatedTo()->sync([\n            2 => ['amount' => 300],\n            3 => ['amount' => 400],\n            4 => ['amount' => 500],\n        ]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass BelongsToManyAggregateTestTestOrder extends Eloquent\n{\n    protected $table = 'orders';\n    protected $fillable = ['id'];\n    public $timestamps = false;\n\n    public function products()\n    {\n        return $this\n            ->belongsToMany(BelongsToManyAggregateTestTestProduct::class, 'order_product', 'order_id', 'product_id')\n            ->withPivot('quantity');\n    }\n}\n\nclass BelongsToManyAggregateTestTestProduct extends Eloquent\n{\n    protected $table = 'products';\n    protected $fillable = ['id'];\n    public $timestamps = false;\n}\n\nclass BelongsToManyAggregateTestTestTransaction extends Eloquent\n{\n    protected $table = 'transactions';\n    protected $fillable = ['id', 'value'];\n    public $timestamps = false;\n\n    public function allocatedTo()\n    {\n        return $this\n            ->belongsToMany(BelongsToManyAggregateTestTestTransaction::class, 'allocations', 'from_id', 'to_id')\n            ->withPivot('quantity');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyChunkByIdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyChunkByIdTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n        });\n\n        $this->schema()->create('articles', function ($table) {\n            $table->increments('id');\n            $table->string('title');\n        });\n\n        $this->schema()->create('article_user', function ($table) {\n            $table->increments('id');\n            $table->integer('article_id')->unsigned();\n            $table->foreign('article_id')->references('id')->on('articles');\n            $table->integer('user_id')->unsigned();\n            $table->foreign('user_id')->references('id')->on('users');\n        });\n    }\n\n    public function testBelongsToChunkById()\n    {\n        $this->seedData();\n\n        $user = BelongsToManyChunkByIdTestTestUser::query()->first();\n        $i = 0;\n\n        $user->articles()->chunkById(1, function (Collection $collection) use (&$i) {\n            $i++;\n            $this->assertEquals($i, $collection->first()->id);\n        });\n\n        $this->assertSame(3, $i);\n    }\n\n    public function testBelongsToChunkByIdDesc()\n    {\n        $this->seedData();\n\n        $user = BelongsToManyChunkByIdTestTestUser::query()->first();\n        $i = 0;\n\n        $user->articles()->chunkByIdDesc(1, function (Collection $collection) use (&$i) {\n            $this->assertEquals(3 - $i, $collection->first()->id);\n            $i++;\n        });\n\n        $this->assertSame(3, $i);\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('article_user');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $user = BelongsToManyChunkByIdTestTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        BelongsToManyChunkByIdTestTestArticle::query()->insert([\n            ['id' => 1, 'title' => 'Another title'],\n            ['id' => 2, 'title' => 'Another title'],\n            ['id' => 3, 'title' => 'Another title'],\n        ]);\n\n        $user->articles()->sync([3, 1, 2]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass BelongsToManyChunkByIdTestTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $fillable = ['id', 'email'];\n    public $timestamps = false;\n\n    public function articles()\n    {\n        return $this->belongsToMany(BelongsToManyChunkByIdTestTestArticle::class, 'article_user', 'user_id', 'article_id');\n    }\n}\n\nclass BelongsToManyChunkByIdTestTestArticle extends Eloquent\n{\n    protected $table = 'articles';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    public $timestamps = false;\n    protected $fillable = ['id', 'title'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyCreateOrFirstTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyCreateOrFirstTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Carbon::setTestNow('2023-01-01 00:00:00');\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('createOrFirstValues')]\n    public function testCreateOrFirstMethodCreatesNewRelated(Closure|array $values): void\n    {\n        $source = new BelongsToManyCreateOrFirstTestSourceModel();\n        $source->id = 123;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n            [456],\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $source->getConnection()->expects('insert')->with(\n            'insert into \"related_table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $source->getConnection()->expects('insert')->with(\n            'insert into \"pivot_table\" (\"related_id\", \"source_id\") values (?, ?)',\n            [456, 123],\n        )->andReturnTrue();\n\n        $result = $source->related()->createOrFirst(['attr' => 'foo'], $values);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testCreateOrFirstMethodAssociatesExistingRelated(): void\n    {\n        $source = new BelongsToManyCreateOrFirstTestSourceModel();\n        $source->id = 123;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $sql = 'insert into \"related_table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $source->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $source->getConnection()\n            ->expects('select')\n            ->with('select * from \"related_table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 456,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $source->getConnection()->expects('insert')->with(\n            'insert into \"pivot_table\" (\"related_id\", \"source_id\") values (?, ?)',\n            [456, 123],\n        )->andReturnTrue();\n\n        $result = $source->related()->createOrFirst(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            // Pivot is not loaded when related model is newly created.\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesExistingRelatedAlreadyAssociated(): void\n    {\n        $source = new BelongsToManyCreateOrFirstTestSourceModel();\n        $source->id = 123;\n        $source->exists = true;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"related_table\".*, \"pivot_table\".\"source_id\" as \"pivot_source_id\", \"pivot_table\".\"related_id\" as \"pivot_related_id\" from \"related_table\" inner join \"pivot_table\" on \"related_table\".\"id\" = \"pivot_table\".\"related_id\" where \"pivot_table\".\"source_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 456,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n                'pivot_source_id' => 123,\n                'pivot_related_id' => 456,\n            ]]);\n\n        $result = $source->related()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n            'pivot' => [\n                'source_id' => 123,\n                'related_id' => 456,\n            ],\n        ], $result->toArray());\n    }\n\n    public function testCreateOrFirstMethodRetrievesExistingRelatedAssociatedJustNow(): void\n    {\n        $source = new BelongsToManyCreateOrFirstTestSourceModel();\n        $source->id = 123;\n        $source->exists = true;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $sql = 'insert into \"related_table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $source->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $source->getConnection()\n            ->expects('select')\n            ->with('select * from \"related_table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 456,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $sql = 'insert into \"pivot_table\" (\"related_id\", \"source_id\") values (?, ?)';\n        $bindings = [456, 123];\n\n        $source->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"related_table\".*, \"pivot_table\".\"source_id\" as \"pivot_source_id\", \"pivot_table\".\"related_id\" as \"pivot_related_id\" from \"related_table\" inner join \"pivot_table\" on \"related_table\".\"id\" = \"pivot_table\".\"related_id\" where \"pivot_table\".\"source_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                false,\n                [],\n            )\n            ->andReturn([[\n                'id' => 456,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n                'pivot_source_id' => 123,\n                'pivot_related_id' => 456,\n            ]]);\n\n        $result = $source->related()->createOrFirst(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n            'pivot' => [\n                'source_id' => 123,\n                'related_id' => 456,\n            ],\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesExistingRelatedAndAssociatesIt(): void\n    {\n        $source = new BelongsToManyCreateOrFirstTestSourceModel();\n        $source->id = 123;\n        $source->exists = true;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"related_table\".*, \"pivot_table\".\"source_id\" as \"pivot_source_id\", \"pivot_table\".\"related_id\" as \"pivot_related_id\" from \"related_table\" inner join \"pivot_table\" on \"related_table\".\"id\" = \"pivot_table\".\"related_id\" where \"pivot_table\".\"source_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select * from \"related_table\" where (\"attr\" = ?) limit 1',\n                ['foo'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 456,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $source->getConnection()\n            ->expects('insert')\n            ->with(\n                'insert into \"pivot_table\" (\"related_id\", \"source_id\") values (?, ?)',\n                [456, 123],\n            )\n            ->andReturnTrue();\n\n        $result = $source->related()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            // Pivot is not loaded when related model is newly created.\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodFallsBackToCreateOrFirst(): void\n    {\n        $source = new class() extends BelongsToManyCreateOrFirstTestSourceModel\n        {\n            protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName = null): BelongsToMany\n            {\n                $relation = m::mock(BelongsToMany::class)->makePartial();\n                $relation->__construct(...func_get_args());\n                $instance = new BelongsToManyCreateOrFirstTestRelatedModel([\n                    'id' => 456,\n                    'attr' => 'foo',\n                    'val' => 'bar',\n                    'created_at' => '2023-01-01T00:00:00.000000Z',\n                    'updated_at' => '2023-01-01T00:00:00.000000Z',\n                    'pivot' => [\n                        'source_id' => 123,\n                        'related_id' => 456,\n                    ],\n                ]);\n                $instance->exists = true;\n                $instance->wasRecentlyCreated = false;\n                $instance->syncOriginal();\n                $relation\n                    ->expects('createOrFirst')\n                    ->with(['attr' => 'foo'], ['val' => 'bar'], [], true)\n                    ->andReturn($instance);\n\n                return $relation;\n            }\n        };\n        $source->id = 123;\n        $source->exists = true;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"related_table\".*, \"pivot_table\".\"source_id\" as \"pivot_source_id\", \"pivot_table\".\"related_id\" as \"pivot_related_id\" from \"related_table\" inner join \"pivot_table\" on \"related_table\".\"id\" = \"pivot_table\".\"related_id\" where \"pivot_table\".\"source_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $source->getConnection()\n            ->expects('select')\n            ->with(\n                'select * from \"related_table\" where (\"attr\" = ?) limit 1',\n                ['foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $result = $source->related()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n            'pivot' => [\n                'source_id' => 123,\n                'related_id' => 456,\n            ],\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewRelated(): void\n    {\n        $source = new class() extends BelongsToManyCreateOrFirstTestSourceModel\n        {\n            protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName = null): BelongsToMany\n            {\n                $relation = m::mock(BelongsToMany::class)->makePartial();\n                $relation->__construct(...func_get_args());\n                $instance = new BelongsToManyCreateOrFirstTestRelatedModel([\n                    'id' => 456,\n                    'attr' => 'foo',\n                    'val' => 'bar',\n                    'created_at' => '2023-01-01T00:00:00.000000Z',\n                    'updated_at' => '2023-01-01T00:00:00.000000Z',\n                ]);\n                $instance->exists = true;\n                $instance->wasRecentlyCreated = true;\n                $instance->syncOriginal();\n                $relation\n                    ->expects('firstOrCreate')\n                    ->with(['attr' => 'foo'], ['val' => 'baz'], [], true)\n                    ->andReturn($instance);\n\n                return $relation;\n            }\n        };\n        $source->id = 123;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n\n        $result = $source->related()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesExistingRelated(): void\n    {\n        $source = new class() extends BelongsToManyCreateOrFirstTestSourceModel\n        {\n            protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName = null): BelongsToMany\n            {\n                $relation = m::mock(BelongsToMany::class)->makePartial();\n                $relation->__construct(...func_get_args());\n                $instance = new BelongsToManyCreateOrFirstTestRelatedModel([\n                    'id' => 456,\n                    'attr' => 'foo',\n                    'val' => 'bar',\n                    'created_at' => '2023-01-01T00:00:00.000000Z',\n                    'updated_at' => '2023-01-01T00:00:00.000000Z',\n                ]);\n                $instance->exists = true;\n                $instance->wasRecentlyCreated = false;\n                $instance->syncOriginal();\n                $relation\n                    ->expects('firstOrCreate')\n                    ->with(['attr' => 'foo'], ['val' => 'baz'], [], true)\n                    ->andReturn($instance);\n\n                return $relation;\n            }\n        };\n        $source->id = 123;\n        $this->mockConnectionForModels(\n            [$source, new BelongsToManyCreateOrFirstTestRelatedModel()],\n            'SQLite',\n        );\n        $source->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $source->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $source->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"related_table\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['baz', '2023-01-01 00:00:00', 456],\n            )\n            ->andReturn(1);\n\n        $result = $source->related()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertEquals([\n            'id' => 456,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public static function createOrFirstValues(): array\n    {\n        return [\n            'array' => [['val' => 'bar']],\n            'closure' => [fn () => ['val' => 'bar']],\n        ];\n    }\n\n    protected function mockConnectionForModels(array $models, string $database, array $lastInsertIds = []): void\n    {\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$database.'Grammar';\n        $processorClass = 'Illuminate\\Database\\Query\\Processors\\\\'.$database.'Processor';\n        $processor = new $processorClass;\n        $connection = m::mock(Connection::class, ['getPostProcessor' => $processor]);\n        $grammar = new $grammarClass($connection);\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new BaseBuilder($connection, $grammar, $processor);\n        });\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $connection]);\n\n        foreach ($models as $model) {\n            /** @var Model $model */\n            $class = get_class($model);\n            $class::setConnectionResolver($resolver);\n        }\n\n        $connection->shouldReceive('getPdo')->andReturn($pdo = m::mock(PDO::class));\n\n        foreach ($lastInsertIds as $id) {\n            $pdo->expects('lastInsertId')->andReturn($id);\n        }\n    }\n}\n\n/**\n * @property int $id\n */\nclass BelongsToManyCreateOrFirstTestRelatedModel extends Model\n{\n    protected $table = 'related_table';\n    protected $guarded = [];\n}\n\n/**\n * @property int $id\n */\nclass BelongsToManyCreateOrFirstTestSourceModel extends Model\n{\n    protected $table = 'source_table';\n    protected $guarded = [];\n\n    public function related(): BelongsToMany\n    {\n        return $this->belongsToMany(\n            BelongsToManyCreateOrFirstTestRelatedModel::class,\n            'pivot_table',\n            'source_id',\n            'related_id',\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyEachByIdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyEachByIdTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n        });\n\n        $this->schema()->create('articles', function ($table) {\n            $table->increments('id');\n            $table->string('title');\n        });\n\n        $this->schema()->create('article_user', function ($table) {\n            $table->increments('id');\n            $table->integer('article_id')->unsigned();\n            $table->foreign('article_id')->references('id')->on('articles');\n            $table->integer('user_id')->unsigned();\n            $table->foreign('user_id')->references('id')->on('users');\n        });\n    }\n\n    public function testBelongsToEachById()\n    {\n        $this->seedData();\n\n        $user = BelongsToManyEachByIdTestTestUser::query()->first();\n        $i = 0;\n\n        $user->articles()->eachById(function (BelongsToManyEachByIdTestTestArticle $model) use (&$i) {\n            $i++;\n            $this->assertEquals($i, $model->id);\n        });\n\n        $this->assertSame(3, $i);\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('article_user');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $user = BelongsToManyEachByIdTestTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        BelongsToManyEachByIdTestTestArticle::query()->insert([\n            ['id' => 1, 'title' => 'Another title'],\n            ['id' => 2, 'title' => 'Another title'],\n            ['id' => 3, 'title' => 'Another title'],\n        ]);\n\n        $user->articles()->sync([3, 1, 2]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass BelongsToManyEachByIdTestTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $fillable = ['id', 'email'];\n    public $timestamps = false;\n\n    public function articles()\n    {\n        return $this->belongsToMany(BelongsToManyEachByIdTestTestArticle::class, 'article_user', 'user_id', 'article_id');\n    }\n}\n\nclass BelongsToManyEachByIdTestTestArticle extends Eloquent\n{\n    protected $table = 'articles';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    public $timestamps = false;\n    protected $fillable = ['id', 'title'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyExpressionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyExpressionTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    public function testAmbiguousColumnsExpression(): void\n    {\n        $this->seedData();\n\n        $tags = DatabaseEloquentBelongsToManyExpressionTestTestPost::findOrFail(1)\n            ->tags()\n            ->wherePivotNotIn(new Expression(\"tag_id || '_' || type\"), ['1_t1'])\n            ->get();\n\n        $this->assertCount(1, $tags);\n        $this->assertEquals(2, $tags->first()->getKey());\n    }\n\n    public function testQualifiedColumnExpression(): void\n    {\n        $this->seedData();\n\n        $tags = DatabaseEloquentBelongsToManyExpressionTestTestPost::findOrFail(2)\n            ->tags()\n            ->wherePivotNotIn(new Expression(\"taggables.tag_id || '_' || taggables.type\"), ['2_t2'])\n            ->get();\n\n        $this->assertCount(1, $tags);\n        $this->assertEquals(3, $tags->first()->getKey());\n    }\n\n    public function testGlobalScopesAreAppliedToBelongsToManyRelation(): void\n    {\n        $this->seedData();\n        $post = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->firstOrFail();\n        DatabaseEloquentBelongsToManyExpressionTestTestTag::addGlobalScope(\n            'default',\n            static fn () => throw new Exception('Default global scope.')\n        );\n\n        $this->expectExceptionMessage('Default global scope.');\n        $post->tags()->get();\n    }\n\n    public function testGlobalScopesCanBeRemovedFromBelongsToManyRelation(): void\n    {\n        $this->seedData();\n        $post = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->firstOrFail();\n        DatabaseEloquentBelongsToManyExpressionTestTestTag::addGlobalScope(\n            'default',\n            static fn () => throw new Exception('Default global scope.')\n        );\n\n        $this->assertNotEmpty($post->tags()->withoutGlobalScopes()->get());\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('posts', fn (Blueprint $t) => $t->id());\n        $this->schema()->create('tags', fn (Blueprint $t) => $t->id());\n        $this->schema()->create('taggables', function (Blueprint $t) {\n            $t->unsignedBigInteger('tag_id');\n            $t->unsignedBigInteger('taggable_id');\n            $t->string('type', 10);\n            $t->string('taggable_type');\n        }\n        );\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('posts');\n        $this->schema()->drop('tags');\n        $this->schema()->drop('taggables');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData(): void\n    {\n        $p1 = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->create();\n        $p2 = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->create();\n        $t1 = DatabaseEloquentBelongsToManyExpressionTestTestTag::query()->create();\n        $t2 = DatabaseEloquentBelongsToManyExpressionTestTestTag::query()->create();\n        $t3 = DatabaseEloquentBelongsToManyExpressionTestTestTag::query()->create();\n\n        $p1->tags()->sync([\n            $t1->getKey() => ['type' => 't1'],\n            $t2->getKey() => ['type' => 't2'],\n        ]);\n        $p2->tags()->sync([\n            $t2->getKey() => ['type' => 't2'],\n            $t3->getKey() => ['type' => 't3'],\n        ]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass DatabaseEloquentBelongsToManyExpressionTestTestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $fillable = ['id'];\n    public $timestamps = false;\n\n    public function tags(): MorphToMany\n    {\n        return  $this->morphToMany(\n            DatabaseEloquentBelongsToManyExpressionTestTestTag::class,\n            'taggable',\n            'taggables',\n            'taggable_id',\n            'tag_id',\n            'id',\n            'id',\n        );\n    }\n}\n\nclass DatabaseEloquentBelongsToManyExpressionTestTestTag extends Eloquent\n{\n    protected $table = 'tags';\n    protected $fillable = ['id'];\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyLazyByIdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyLazyByIdTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n        });\n\n        $this->schema()->create('articles', function ($table) {\n            $table->increments('aid');\n            $table->string('title');\n        });\n\n        $this->schema()->create('article_user', function ($table) {\n            $table->integer('article_id')->unsigned();\n            $table->foreign('article_id')->references('aid')->on('articles');\n            $table->integer('user_id')->unsigned();\n            $table->foreign('user_id')->references('id')->on('users');\n        });\n    }\n\n    public function testBelongsToLazyById()\n    {\n        $this->seedData();\n\n        $user = BelongsToManyLazyByIdTestTestUser::query()->first();\n        $i = 0;\n\n        $user->articles()->lazyById(1)->each(function ($model) use (&$i) {\n            $i++;\n            $this->assertEquals($i, $model->aid);\n        });\n\n        $this->assertSame(3, $i);\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('article_user');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $user = BelongsToManyLazyByIdTestTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        BelongsToManyLazyByIdTestTestArticle::query()->insert([\n            ['aid' => 1, 'title' => 'Another title'],\n            ['aid' => 2, 'title' => 'Another title'],\n            ['aid' => 3, 'title' => 'Another title'],\n        ]);\n\n        $user->articles()->sync([3, 1, 2]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass BelongsToManyLazyByIdTestTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $fillable = ['id', 'email'];\n    public $timestamps = false;\n\n    public function articles()\n    {\n        return $this->belongsToMany(BelongsToManyLazyByIdTestTestArticle::class, 'article_user', 'user_id', 'article_id');\n    }\n}\n\nclass BelongsToManyLazyByIdTestTestArticle extends Eloquent\n{\n    protected $primaryKey = 'aid';\n    protected $table = 'articles';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    public $timestamps = false;\n    protected $fillable = ['aid', 'title'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyOrFailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyOrFailTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email');\n        });\n\n        $this->schema()->create('roles', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        $this->schema()->create('role_user', function ($table) {\n            $table->integer('user_id')->unsigned();\n            $table->integer('role_id')->unsigned();\n            $table->boolean('active')->default(false);\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('roles');\n        $this->schema()->drop('role_user');\n    }\n\n    protected function seedData()\n    {\n        OrFailUser::create(['id' => 1, 'email' => 'taylor@laravel.com']);\n        OrFailRole::insert([\n            ['id' => 1, 'name' => 'Admin'],\n            ['id' => 2, 'name' => 'Editor'],\n            ['id' => 3, 'name' => 'Viewer'],\n        ]);\n    }\n\n    public function testSyncOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n\n        $result = $user->roles()->syncOrFail([1, 2]);\n\n        $this->assertEquals([1, 2], $result['attached']);\n        $this->assertEmpty($result['detached']);\n        $this->assertEmpty($result['updated']);\n        $this->assertCount(2, $user->roles);\n    }\n\n    public function testSyncWithoutDetachingOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attach([1]);\n\n        $result = $user->roles()->syncWithoutDetachingOrFail([2, 3]);\n\n        $this->assertEquals([2, 3], $result['attached']);\n        $this->assertEmpty($result['detached']);\n        $this->assertCount(3, $user->roles()->get());\n    }\n\n    public function testAttachOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n\n        $user->roles()->attachOrFail(1);\n\n        $this->assertCount(1, $user->roles);\n    }\n\n    public function testAttachOrFailWithAttributes()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attachOrFail(1, ['active' => true]);\n\n        $pivot = DB::table('role_user')->where('user_id', 1)->where('role_id', 1)->first();\n        $this->assertEquals(1, $pivot->active);\n    }\n\n    public function testDetachOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attach([1, 2, 3]);\n\n        $result = $user->roles()->detachOrFail([1, 2]);\n\n        $this->assertEquals(2, $result);\n        $this->assertCount(1, $user->roles()->get());\n    }\n\n    public function testDetachOrFailAll()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attach([1, 2, 3]);\n\n        $result = $user->roles()->detachOrFail();\n\n        $this->assertEquals(3, $result);\n        $this->assertCount(0, $user->roles()->get());\n    }\n\n    public function testToggleOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attach([1]);\n\n        $result = $user->roles()->toggleOrFail([1, 2]);\n\n        $this->assertEquals([1], $result['detached']);\n        $this->assertEquals([2], $result['attached']);\n        $this->assertCount(1, $user->roles()->get());\n    }\n\n    public function testSyncWithPivotValuesOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n\n        $result = $user->roles()->syncWithPivotValuesOrFail([1, 2], ['active' => true]);\n\n        $this->assertEquals([1, 2], $result['attached']);\n        $this->assertEmpty($result['detached']);\n        $this->assertEmpty($result['updated']);\n\n        $pivot = DB::table('role_user')->where('user_id', 1)->where('role_id', 1)->first();\n        $this->assertEquals(1, $pivot->active);\n    }\n\n    public function testUpdateExistingPivotOrFail()\n    {\n        $this->seedData();\n\n        $user = OrFailUser::find(1);\n        $user->roles()->attach(1, ['active' => false]);\n\n        $result = $user->roles()->updateExistingPivotOrFail(1, ['active' => true]);\n\n        $this->assertEquals(1, $result);\n\n        $pivot = DB::table('role_user')->where('user_id', 1)->where('role_id', 1)->first();\n        $this->assertEquals(1, $pivot->active);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass OrFailUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function roles(): BelongsToMany\n    {\n        return $this->belongsToMany(OrFailRole::class, 'role_user', 'user_id', 'role_id');\n    }\n}\n\nclass OrFailRole extends Eloquent\n{\n    protected $table = 'roles';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManySyncReturnValueTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManySyncReturnValueTypeTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n        });\n\n        $this->schema()->create('articles', function ($table) {\n            $table->string('id');\n            $table->string('title');\n\n            $table->primary('id');\n        });\n\n        $this->schema()->create('article_user', function ($table) {\n            $table->string('article_id');\n            $table->foreign('article_id')->references('id')->on('articles');\n            $table->integer('user_id')->unsigned();\n            $table->foreign('user_id')->references('id')->on('users');\n            $table->boolean('visible')->default(false);\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('article_user');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        BelongsToManySyncTestTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        BelongsToManySyncTestTestArticle::insert([\n            ['id' => '7b7306ae-5a02-46fa-a84c-9538f45c7dd4', 'title' => 'uuid title'],\n            ['id' => (string) (PHP_INT_MAX + 1), 'title' => 'Another title'],\n            ['id' => '1', 'title' => 'Another title'],\n        ]);\n    }\n\n    public function testSyncReturnValueType()\n    {\n        $this->seedData();\n\n        $user = BelongsToManySyncTestTestUser::query()->first();\n        $articleIDs = BelongsToManySyncTestTestArticle::all()->pluck('id')->toArray();\n\n        $changes = $user->articles()->sync($articleIDs);\n\n        collect($changes['attached'])->map(function ($id) {\n            $this->assertSame(gettype($id), (new BelongsToManySyncTestTestArticle)->getKeyType());\n        });\n\n        $user->articles->each(function (BelongsToManySyncTestTestArticle $article) {\n            $this->assertSame('0', (string) $article->pivot->visible);\n        });\n    }\n\n    public function testSyncWithPivotDefaultsReturnValueType()\n    {\n        $this->seedData();\n\n        $user = BelongsToManySyncTestTestUser::query()->first();\n        $articleIDs = BelongsToManySyncTestTestArticle::all()->pluck('id')->toArray();\n\n        $changes = $user->articles()->syncWithPivotValues($articleIDs, ['visible' => true]);\n\n        collect($changes['attached'])->each(function ($id) {\n            $this->assertSame(gettype($id), (new BelongsToManySyncTestTestArticle)->getKeyType());\n        });\n\n        $user->articles->each(function (BelongsToManySyncTestTestArticle $article) {\n            $this->assertSame('1', (string) $article->pivot->visible);\n        });\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass BelongsToManySyncTestTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $fillable = ['id', 'email'];\n    public $timestamps = false;\n\n    public function articles()\n    {\n        return $this->belongsToMany(BelongsToManySyncTestTestArticle::class, 'article_user', 'user_id', 'article_id')->withPivot('visible');\n    }\n}\n\nclass BelongsToManySyncTestTestArticle extends Eloquent\n{\n    protected $table = 'articles';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    public $timestamps = false;\n    protected $fillable = ['id', 'title'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManySyncTouchesParentTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot as EloquentPivot;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManySyncTouchesParentTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('articles', function ($table) {\n            $table->string('id');\n            $table->string('title');\n\n            $table->primary('id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('article_user', function ($table) {\n            $table->string('article_id');\n            $table->foreign('article_id')->references('id')->on('articles');\n            $table->integer('user_id')->unsigned();\n            $table->foreign('user_id')->references('id')->on('users');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('article_user');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::create(['id' => 2, 'email' => 'anonymous@gmail.com']);\n        DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::create(['id' => 3, 'email' => 'anoni-mous@gmail.com']);\n    }\n\n    public function testSyncWithDetachedValuesShouldTouch()\n    {\n        $this->seedData();\n\n        Carbon::setTestNow('2021-07-19 10:13:14');\n        $article = DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticle::create(['id' => 1, 'title' => 'uuid title']);\n        $article->users()->sync([1, 2, 3]);\n        $this->assertSame('2021-07-19 10:13:14', $article->updated_at->format('Y-m-d H:i:s'));\n\n        Carbon::setTestNow('2021-07-20 19:13:14');\n        $result = $article->users()->sync([1, 2]);\n        $this->assertCount(1, collect($result['detached']));\n        $this->assertSame('3', (string) collect($result['detached'])->first());\n\n        $article->refresh();\n        $this->assertSame('2021-07-20 19:13:14', $article->updated_at->format('Y-m-d H:i:s'));\n\n        $user1 = DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::find(1);\n        $this->assertNotSame('2021-07-20 19:13:14', $user1->updated_at->format('Y-m-d H:i:s'));\n        $user2 = DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::find(2);\n        $this->assertNotSame('2021-07-20 19:13:14', $user2->updated_at->format('Y-m-d H:i:s'));\n        $user3 = DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::find(3);\n        $this->assertNotSame('2021-07-20 19:13:14', $user3->updated_at->format('Y-m-d H:i:s'));\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticle extends Eloquent\n{\n    protected $table = 'articles';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    protected $fillable = ['id', 'title'];\n\n    public function users()\n    {\n        return $this\n            ->belongsToMany(DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticle::class, 'article_user', 'article_id', 'user_id')\n            ->using(DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticleUser::class)\n            ->withTimestamps();\n    }\n}\n\nclass DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticleUser extends EloquentPivot\n{\n    protected $table = 'article_user';\n    protected $fillable = ['article_id', 'user_id'];\n    protected $touches = ['article'];\n\n    public function article()\n    {\n        return $this->belongsTo(DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticle::class, 'article_id', 'id');\n    }\n\n    public function user()\n    {\n        return $this->belongsTo(DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser::class, 'user_id', 'id');\n    }\n}\n\nclass DatabaseEloquentBelongsToManySyncTouchesParentTestTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $keyType = 'string';\n    public $incrementing = false;\n    protected $fillable = ['id', 'email'];\n\n    public function articles()\n    {\n        return $this\n            ->belongsToMany(DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticle::class, 'article_user', 'user_id', 'article_id')\n            ->using(DatabaseEloquentBelongsToManySyncTouchesParentTestTestArticleUser::class)\n            ->withTimestamps();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyWithAttributesPendingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyWithAttributesPendingTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        $this->createSchema();\n    }\n\n    public function testCreatesPendingAttributesAndPivotValues(): void\n    {\n        $post = ManyToManyPendingAttributesPost::create();\n        $tag = $post->metaTags()->create(['name' => 'long article']);\n\n        $this->assertSame('long article', $tag->name);\n        $this->assertTrue($tag->visible);\n\n        $pivot = DB::table('pending_attributes_pivot')->first();\n        $this->assertSame('meta', $pivot->type);\n        $this->assertSame($post->id, $pivot->post_id);\n        $this->assertSame($tag->id, $pivot->tag_id);\n    }\n\n    public function testQueriesPendingAttributesAndPivotValues(): void\n    {\n        $post = new ManyToManyPendingAttributesPost(['id' => 2]);\n        $wheres = $post->metaTags()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_pivot.tag_id',\n            'operator' => '=',\n            'value' => 2,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_pivot.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure no other wheres exist\n        $this->assertCount(2, $wheres);\n    }\n\n    public function testMorphToManyPendingAttributes(): void\n    {\n        $post = new ManyToManyPendingAttributesPost(['id' => 2]);\n        $wheres = $post->morphedTags()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.taggable_type',\n            'operator' => '=',\n            'value' => ManyToManyPendingAttributesPost::class,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.taggable_id',\n            'operator' => '=',\n            'value' => 2,\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure no other wheres exist\n        $this->assertCount(3, $wheres);\n\n        $tag = $post->morphedTags()->create(['name' => 'new tag']);\n\n        $this->assertTrue($tag->visible);\n        $this->assertSame('new tag', $tag->name);\n        $this->assertSame($tag->id, $post->morphedTags()->first()->id);\n    }\n\n    public function testMorphedByManyPendingAttributes(): void\n    {\n        $tag = new ManyToManyPendingAttributesTag(['id' => 4]);\n        $wheres = $tag->morphedPosts()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.taggable_type',\n            'operator' => '=',\n            'value' => ManyToManyPendingAttributesPost::class,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'pending_attributes_taggables.tag_id',\n            'operator' => '=',\n            'value' => 4,\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure no other wheres exist\n        $this->assertCount(3, $wheres);\n\n        $post = $tag->morphedPosts()->create();\n        $this->assertSame('Title!', $post->title);\n        $this->assertSame($post->id, $tag->morphedPosts()->first()->id);\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('pending_attributes_posts', function ($table) {\n            $table->increments('id');\n            $table->string('title')->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('pending_attributes_tags', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->boolean('visible')->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('pending_attributes_pivot', function ($table) {\n            $table->integer('post_id');\n            $table->integer('tag_id');\n            $table->string('type');\n        });\n\n        $this->schema()->create('pending_attributes_taggables', function ($table) {\n            $table->integer('tag_id');\n            $table->integer('taggable_id');\n            $table->string('taggable_type');\n            $table->string('type');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('pending_attributes_posts');\n        $this->schema()->drop('pending_attributes_tags');\n        $this->schema()->drop('pending_attributes_pivot');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Model::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass ManyToManyPendingAttributesPost extends Model\n{\n    protected $guarded = [];\n    protected $table = 'pending_attributes_posts';\n\n    public function tags(): BelongsToMany\n    {\n        return $this->belongsToMany(\n            ManyToManyPendingAttributesTag::class,\n            'pending_attributes_pivot',\n            'tag_id',\n            'post_id',\n        );\n    }\n\n    public function metaTags(): BelongsToMany\n    {\n        return $this->tags()\n            ->withAttributes('visible', true, asConditions: false)\n            ->withPivotValue('type', 'meta');\n    }\n\n    public function morphedTags(): MorphToMany\n    {\n        return $this\n            ->morphToMany(\n                ManyToManyPendingAttributesTag::class,\n                'taggable',\n                'pending_attributes_taggables',\n                relatedPivotKey: 'tag_id'\n            )\n            ->withAttributes('visible', true, asConditions: false)\n            ->withPivotValue('type', 'meta');\n    }\n}\n\nclass ManyToManyPendingAttributesTag extends Model\n{\n    protected $guarded = [];\n    protected $table = 'pending_attributes_tags';\n\n    public function morphedPosts(): MorphToMany\n    {\n        return $this\n            ->morphedByMany(\n                ManyToManyPendingAttributesPost::class,\n                'taggable',\n                'pending_attributes_taggables',\n                'tag_id',\n            )\n            ->withAttributes('title', 'Title!', asConditions: false)\n            ->withPivotValue('type', 'meta');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyWithAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToManyWithAttributesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        $this->createSchema();\n    }\n\n    public function testCreatesWithAttributesAndPivotValues(): void\n    {\n        $post = ManyToManyWithAttributesPost::create();\n        $tag = $post->metaTags()->create(['name' => 'long article']);\n\n        $this->assertSame('long article', $tag->name);\n        $this->assertTrue($tag->visible);\n\n        $pivot = DB::table('with_attributes_pivot')->first();\n        $this->assertSame('meta', $pivot->type);\n        $this->assertSame($post->id, $pivot->post_id);\n        $this->assertSame($tag->id, $pivot->tag_id);\n    }\n\n    public function testQueriesWithAttributesAndPivotValues(): void\n    {\n        $post = new ManyToManyWithAttributesPost(['id' => 2]);\n        $wheres = $post->metaTags()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_tags.visible',\n            'operator' => '=',\n            'value' => true,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_pivot.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n    }\n\n    public function testMorphToManyWithAttributes(): void\n    {\n        $post = new ManyToManyWithAttributesPost(['id' => 2]);\n        $wheres = $post->morphedTags()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_tags.visible',\n            'operator' => '=',\n            'value' => true,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.taggable_type',\n            'operator' => '=',\n            'value' => ManyToManyWithAttributesPost::class,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.taggable_id',\n            'operator' => '=',\n            'value' => 2,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $tag = $post->morphedTags()->create(['name' => 'new tag']);\n\n        $this->assertTrue($tag->visible);\n        $this->assertSame('new tag', $tag->name);\n        $this->assertSame($tag->id, $post->morphedTags()->first()->id);\n    }\n\n    public function testMorphedByManyWithAttributes(): void\n    {\n        $tag = new ManyToManyWithAttributesTag(['id' => 4]);\n        $wheres = $tag->morphedPosts()->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_posts.title',\n            'operator' => '=',\n            'value' => 'Title!',\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.type',\n            'operator' => '=',\n            'value' => 'meta',\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.taggable_type',\n            'operator' => '=',\n            'value' => ManyToManyWithAttributesPost::class,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_taggables.tag_id',\n            'operator' => '=',\n            'value' => 4,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $post = $tag->morphedPosts()->create();\n        $this->assertSame('Title!', $post->title);\n        $this->assertSame($post->id, $tag->morphedPosts()->first()->id);\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('with_attributes_posts', function ($table) {\n            $table->increments('id');\n            $table->string('title')->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('with_attributes_tags', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->boolean('visible')->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('with_attributes_pivot', function ($table) {\n            $table->integer('post_id');\n            $table->integer('tag_id');\n            $table->string('type');\n        });\n\n        $this->schema()->create('with_attributes_taggables', function ($table) {\n            $table->integer('tag_id');\n            $table->integer('taggable_id');\n            $table->string('taggable_type');\n            $table->string('type');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('with_attributes_posts');\n        $this->schema()->drop('with_attributes_tags');\n        $this->schema()->drop('with_attributes_pivot');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Model::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass ManyToManyWithAttributesPost extends Model\n{\n    protected $guarded = [];\n    protected $table = 'with_attributes_posts';\n\n    public function tags(): BelongsToMany\n    {\n        return $this->belongsToMany(\n            ManyToManyWithAttributesTag::class,\n            'with_attributes_pivot',\n            'tag_id',\n            'post_id',\n        );\n    }\n\n    public function metaTags(): BelongsToMany\n    {\n        return $this->tags()\n            ->withAttributes('visible', true)\n            ->withPivotValue('type', 'meta');\n    }\n\n    public function morphedTags(): MorphToMany\n    {\n        return $this\n            ->morphToMany(\n                ManyToManyWithAttributesTag::class,\n                'taggable',\n                'with_attributes_taggables',\n                relatedPivotKey: 'tag_id'\n            )\n            ->withAttributes('visible', true)\n            ->withPivotValue('type', 'meta');\n    }\n}\n\nclass ManyToManyWithAttributesTag extends Model\n{\n    protected $guarded = [];\n    protected $table = 'with_attributes_tags';\n\n    public function morphedPosts(): MorphToMany\n    {\n        return $this\n            ->morphedByMany(\n                ManyToManyWithAttributesPost::class,\n                'taggable',\n                'with_attributes_taggables',\n                'tag_id',\n            )\n            ->withAttributes('title', 'Title!')\n            ->withPivotValue('type', 'meta');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyWithCastedAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentBelongsToManyWithCastedAttributesTest extends TestCase\n{\n    public function testModelsAreProperlyMatchedToParents()\n    {\n        $relation = $this->getRelation();\n        $model1 = m::mock(Model::class);\n        $model1->shouldReceive('hasAttribute')->passthru();\n        $model1->shouldReceive('getAttribute')->with('parent_key')->andReturn(1);\n        $model1->shouldReceive('getAttribute')->with('foo')->passthru();\n        $model1->shouldReceive('hasGetMutator')->andReturn(false);\n        $model1->shouldReceive('hasAttributeMutator')->andReturn(false);\n        $model1->shouldReceive('hasRelationAutoloadCallback')->andReturn(false);\n        $model1->shouldReceive('getCasts')->andReturn([]);\n        $model1->shouldReceive('getRelationValue', 'relationLoaded', 'relationResolver', 'setRelation', 'isRelation')->passthru();\n\n        $model2 = m::mock(Model::class);\n        $model2->shouldReceive('hasAttribute')->passthru();\n        $model2->shouldReceive('getAttribute')->with('parent_key')->andReturn(2);\n        $model2->shouldReceive('getAttribute')->with('foo')->passthru();\n        $model2->shouldReceive('hasGetMutator')->andReturn(false);\n        $model2->shouldReceive('hasAttributeMutator')->andReturn(false);\n        $model2->shouldReceive('hasRelationAutoloadCallback')->andReturn(false);\n        $model2->shouldReceive('getCasts')->andReturn([]);\n        $model2->shouldReceive('getRelationValue', 'relationLoaded', 'relationResolver', 'setRelation', 'isRelation')->passthru();\n\n        $result1 = (object) [\n            'pivot' => (object) [\n                'foreign_key' => new class\n                {\n                    public function __toString()\n                    {\n                        return '1';\n                    }\n                },\n            ],\n        ];\n\n        $models = $relation->match([$model1, $model2], Collection::wrap($result1), 'foo');\n        $this->assertNull($models[1]->foo);\n        $this->assertSame(1, $models[0]->foo->count());\n        $this->assertContains($result1, $models[0]->foo);\n    }\n\n    protected function getRelation()\n    {\n        $builder = m::mock(Builder::class);\n        $related = m::mock(Model::class);\n        $related->shouldReceive('newCollection')->passthru();\n        $related->shouldReceive('resolveCollectionFromAttribute')->passthru();\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $related->shouldReceive('qualifyColumn');\n        $builder->shouldReceive('join', 'where');\n        $builder->shouldReceive('getQuery')->andReturn(\n            m::mock(stdClass::class, ['getGrammar' => m::mock(Grammar::class, ['isExpression' => false])])\n        );\n\n        return new BelongsToMany(\n            $builder,\n            new EloquentBelongsToManyModelStub,\n            'relation',\n            'foreign_key',\n            'id',\n            'parent_key',\n            'related_key'\n        );\n    }\n}\n\nclass EloquentBelongsToManyModelStub extends Model\n{\n    public $foreign_key = 'foreign.value';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyWithDefaultAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentBelongsToManyWithDefaultAttributesTest extends TestCase\n{\n    public function testWithPivotValueMethodSetsWhereConditionsForFetching()\n    {\n        $relation = $this->getMockBuilder(BelongsToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();\n        $relation->withPivotValue(['is_admin' => 1]);\n    }\n\n    public function testWithPivotValueMethodSetsDefaultArgumentsForInsertion()\n    {\n        $relation = $this->getMockBuilder(BelongsToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();\n        $relation->withPivotValue(['is_admin' => 1]);\n\n        $query = m::mock(stdClass::class);\n        $query->shouldReceive('from')->once()->with('club_user')->andReturn($query);\n        $query->shouldReceive('insert')->once()->with([['club_id' => 1, 'user_id' => 1, 'is_admin' => 1]])->andReturn(true);\n        $relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);\n\n        $relation->attach(1);\n    }\n\n    public function getRelationArguments()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getKey')->andReturn(1);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n\n        $builder = m::mock(Builder::class);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        $related->shouldReceive('getTable')->andReturn('users');\n        $related->shouldReceive('getKeyName')->andReturn('id');\n        $related->shouldReceive('qualifyColumn')->with('id')->andReturn('users.id');\n\n        $builder->shouldReceive('join')->once()->with('club_user', 'users.id', '=', 'club_user.user_id');\n        $builder->shouldReceive('where')->once()->with('club_user.club_id', '=', 1);\n        $builder->shouldReceive('where')->once()->with('club_user.is_admin', '=', 1, 'and');\n\n        $builder->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));\n        $mockQueryBuilder->shouldReceive('getGrammar')->andReturn(m::mock(Grammar::class, ['isExpression' => false]));\n\n        return [$builder, $parent, 'club_user', 'club_id', 'user_id', 'id', 'id', null, false];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToManyWithoutTouchingTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentBelongsToManyWithoutTouchingTest extends TestCase\n{\n    public function testItWillNotTouchRelatedModelsWhenUpdatingChild(): void\n    {\n        /** @var Article $related */\n        $related = m::mock(Article::class)->makePartial();\n        $related->shouldReceive('getUpdatedAtColumn')->never();\n        $related->shouldReceive('freshTimestampString')->never();\n\n        $this->assertFalse($related::isIgnoringTouch());\n\n        Model::withoutTouching(function () use ($related) {\n            $this->assertTrue($related::isIgnoringTouch());\n\n            $builder = m::mock(Builder::class);\n            $builder->shouldReceive('join');\n            $parent = m::mock(User::class);\n\n            $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n            $builder->shouldReceive('getModel')->andReturn($related);\n            $builder->shouldReceive('where');\n            $builder->shouldReceive('getQuery')->andReturn(\n                m::mock(stdClass::class, ['getGrammar' => m::mock(Grammar::class, ['isExpression' => false])])\n            );\n            $relation = new BelongsToMany($builder, $parent, 'article_users', 'user_id', 'article_id', 'id', 'id');\n            $builder->shouldReceive('update')->never();\n\n            $relation->touch();\n        });\n\n        $this->assertFalse($related::isIgnoringTouch());\n    }\n}\n\nclass User extends Model\n{\n    protected $table = 'users';\n    protected $fillable = ['id', 'email'];\n\n    public function articles(): BelongsToMany\n    {\n        return $this->belongsToMany(Article::class, 'article_user', 'user_id', 'article_id');\n    }\n}\n\nclass Article extends Model\n{\n    protected $table = 'articles';\n    protected $fillable = ['id', 'title'];\n    protected $touches = ['user'];\n\n    public function users(): BelongsToMany\n    {\n        return $this->belongsToMany(User::class, 'article_user', 'article_id', 'user_id');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBelongsToTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Bar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBelongsToTest extends TestCase\n{\n    protected $builder;\n\n    protected $related;\n\n    public function testBelongsToWithDefault()\n    {\n        $relation = $this->getRelation()->withDefault();\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentBelongsToModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n    }\n\n    public function testBelongsToWithDynamicDefault()\n    {\n        $relation = $this->getRelation()->withDefault(function ($newModel) {\n            $newModel->username = 'taylor';\n        });\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentBelongsToModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame('taylor', $newModel->username);\n    }\n\n    public function testBelongsToWithArrayDefault()\n    {\n        $relation = $this->getRelation()->withDefault(['username' => 'taylor']);\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentBelongsToModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame('taylor', $newModel->username);\n    }\n\n    public function testEagerConstraintsAreProperlyAdded()\n    {\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', ['foreign.value', 'foreign.value.two']);\n        $models = [new EloquentBelongsToModelStub, new EloquentBelongsToModelStub, new AnotherEloquentBelongsToModelStub];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testIdsInEagerConstraintsCanBeZero()\n    {\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', [0, 'foreign.value']);\n        $models = [new EloquentBelongsToModelStub, new EloquentBelongsToModelStubWithZeroId];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testIdsInEagerConstraintsCanBeBackedEnum()\n    {\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', [5, 'foreign.value']);\n        $models = [new EloquentBelongsToModelStub, new EloquentBelongsToModelStubWithBackedEnumCast];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testRelationIsProperlyInitialized()\n    {\n        $relation = $this->getRelation();\n        $model = m::mock(Model::class);\n        $model->shouldReceive('setRelation')->once()->with('foo', null);\n        $models = $relation->initRelation([$model], 'foo');\n\n        $this->assertEquals([$model], $models);\n    }\n\n    public function testModelsAreProperlyMatchedToParents()\n    {\n        $relation = $this->getRelation();\n\n        $result1 = new class extends Model\n        {\n            protected $attributes = ['id' => 1];\n        };\n\n        $result2 = new class extends Model\n        {\n            protected $attributes = ['id' => 2];\n        };\n\n        $result3 = new class extends Model\n        {\n            protected $attributes = ['id' => 3];\n\n            public function __toString()\n            {\n                return '3';\n            }\n        };\n\n        $result4 = new class extends Model\n        {\n            protected $casts = [\n                'id' => Bar::class,\n            ];\n\n            protected $attributes = ['id' => 5];\n        };\n\n        $model1 = new EloquentBelongsToModelStub;\n        $model1->foreign_key = 1;\n        $model2 = new EloquentBelongsToModelStub;\n        $model2->foreign_key = 2;\n        $model3 = new EloquentBelongsToModelStub;\n        $model3->foreign_key = new class\n        {\n            public function __toString()\n            {\n                return '3';\n            }\n        };\n        $model4 = new EloquentBelongsToModelStub;\n        $model4->foreign_key = 5;\n        $models = $relation->match(\n            [$model1, $model2, $model3, $model4],\n            new Collection([$result1, $result2, $result3, $result4]),\n            'foo'\n        );\n\n        $this->assertEquals(1, $models[0]->foo->getAttribute('id'));\n        $this->assertEquals(2, $models[1]->foo->getAttribute('id'));\n        $this->assertSame('3', (string) $models[2]->foo->getAttribute('id'));\n        $this->assertEquals(5, $models[3]->foo->getAttribute('id')->value);\n    }\n\n    public function testAssociateMethodSetsForeignKeyOnModel()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        $relation = $this->getRelation($parent);\n        $associate = m::mock(Model::class);\n        $associate->shouldReceive('getAttribute')->once()->with('id')->andReturn(1);\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n        $parent->shouldReceive('setRelation')->once()->with('relation', $associate);\n\n        $relation->associate($associate);\n    }\n\n    public function testDissociateMethodUnsetsForeignKeyOnModel()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        $relation = $this->getRelation($parent);\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', null);\n\n        // Always set relation when we received Model\n        $parent->shouldReceive('setRelation')->once()->with('relation', null);\n\n        $relation->dissociate();\n    }\n\n    public function testAssociateMethodSetsForeignKeyOnModelById()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        $relation = $this->getRelation($parent);\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n\n        // Always unset relation when we received id, regardless of dirtiness\n        $parent->shouldReceive('isDirty')->never();\n        $parent->shouldReceive('unsetRelation')->once()->with($relation->getRelationName());\n\n        $relation->associate(1);\n    }\n\n    public function testDefaultEagerConstraintsWhenIncrementing()\n    {\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', m::mustBe([]));\n        $models = [new MissingEloquentBelongsToModelStub, new MissingEloquentBelongsToModelStub];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testDefaultEagerConstraintsWhenIncrementingAndNonIntKeyType()\n    {\n        $relation = $this->getRelation(null, 'string');\n        $relation->getQuery()->shouldReceive('whereIn')->once()->with('relation.id', m::mustBe([]));\n        $models = [new MissingEloquentBelongsToModelStub, new MissingEloquentBelongsToModelStub];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testDefaultEagerConstraintsWhenNotIncrementing()\n    {\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', m::mustBe([]));\n        $models = [new MissingEloquentBelongsToModelStub, new MissingEloquentBelongsToModelStub];\n        $relation->addEagerConstraints($models);\n    }\n\n    public function testIsNotNull()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is(null));\n    }\n\n    public function testIsModel()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerParentKey()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return an integer\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('1');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerRelatedKey()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return a string\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('1');\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerKeys()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return an integer\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullParentKey()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return null\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(null);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullRelatedKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(null);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value.two');\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherTable()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('table.two');\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherConnection()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation.two');\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    protected function getRelation($parent = null, $keyType = 'int')\n    {\n        $this->builder = m::mock(Builder::class);\n        $this->builder->shouldReceive('where')->with('relation.id', '=', 'foreign.value');\n        $this->related = m::mock(Model::class);\n        $this->related->shouldReceive('getKeyType')->andReturn($keyType);\n        $this->related->shouldReceive('getKeyName')->andReturn('id');\n        $this->related->shouldReceive('getTable')->andReturn('relation');\n        $this->related->shouldReceive('qualifyColumn')->andReturnUsing(fn (string $column) => \"relation.{$column}\");\n        $this->builder->shouldReceive('getModel')->andReturn($this->related);\n        $parent = $parent ?: new EloquentBelongsToModelStub;\n\n        return new BelongsTo($this->builder, $parent, 'foreign_key', 'id', 'relation');\n    }\n}\n\nclass EloquentBelongsToModelStub extends Model\n{\n    public $foreign_key = 'foreign.value';\n}\n\nclass AnotherEloquentBelongsToModelStub extends Model\n{\n    public $foreign_key = 'foreign.value.two';\n}\n\nclass EloquentBelongsToModelStubWithZeroId extends Model\n{\n    public $foreign_key = 0;\n}\n\nclass MissingEloquentBelongsToModelStub extends Model\n{\n    public $foreign_key;\n}\n\nclass EloquentBelongsToModelStubWithBackedEnumCast extends Model\n{\n    protected $casts = [\n        'foreign_key' => Bar::class,\n    ];\n\n    public $attributes = [\n        'foreign_key' => 5,\n    ];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBuilderCreateOrFirstTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentBuilderCreateOrFirstTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Carbon::setTestNow('2023-01-01 00:00:00');\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('createOrFirstValues')]\n    public function testCreateOrFirstMethodCreatesNewRecord(Closure|array $values): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite', [123]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->newQuery()->createOrFirst(['attr' => 'foo'], $values);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testCreateOrFirstMethodRetrievesExistingRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $sql = 'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], false, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $model->newQuery()->createOrFirst(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesExistingRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $model->newQuery()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodCreatesNewRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite', [123]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->newQuery()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $sql = 'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], false, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $model->newQuery()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesExistingRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"table\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['baz', '2023-01-01 00:00:00', 123],\n            )\n            ->andReturn(1);\n\n        $result = $model->newQuery()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite', [123]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->newQuery()->updateOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $sql = 'insert into \"table\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'baz', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], false, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"table\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['baz', '2023-01-01 00:00:00', 123],\n            )\n            ->andReturn(1);\n\n        $result = $model->newQuery()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testIncrementOrCreateMethodIncrementsExistingRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'count' => 1,\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()\n            ->expects('raw')\n            ->with('\"count\" + 1')\n            ->andReturn('2');\n\n        $model->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"table\" set \"count\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['2', '2023-01-01 00:00:00', 123],\n            )\n            ->andReturn(1);\n\n        $result = $model->newQuery()->incrementOrCreate(['attr' => 'foo'], 'count');\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'count' => 2,\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testIncrementOrCreateMethodCreatesNewRecord(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite', [123]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"table\" (\"attr\", \"count\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', '1', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->newQuery()->incrementOrCreate(['attr' => 'foo']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'count' => 1,\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testIncrementOrCreateMethodIncrementParametersArePassed(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'count' => 1,\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()\n            ->expects('raw')\n            ->with('\"count\" + 2')\n            ->andReturn('3');\n\n        $model->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"table\" set \"count\" = ?, \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['3', 'baz', '2023-01-01 00:00:00', 123],\n            )\n            ->andReturn(1);\n\n        $result = $model->newQuery()->incrementOrCreate(['attr' => 'foo'], step: 2, extra: ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'count' => 3,\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testIncrementOrCreateMethodRetrievesRecordCreatedJustNow(): void\n    {\n        $model = new EloquentBuilderCreateOrFirstTestModel();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], true, [])\n            ->andReturn([]);\n\n        $sql = 'insert into \"table\" (\"attr\", \"count\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', '1', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"table\" where (\"attr\" = ?) limit 1', ['foo'], false, [])\n            ->andReturn([[\n                'id' => 123,\n                'attr' => 'foo',\n                'count' => 1,\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()\n            ->expects('raw')\n            ->with('\"count\" + 1')\n            ->andReturn('2');\n\n        $model->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"table\" set \"count\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['2', '2023-01-01 00:00:00', 123],\n            )\n            ->andReturn(1);\n\n        $result = $model->newQuery()->incrementOrCreate(['attr' => 'foo']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 123,\n            'attr' => 'foo',\n            'count' => 2,\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public static function createOrFirstValues(): array\n    {\n        return [\n            'array' => [['val' => 'bar']],\n            'closure' => [fn () => ['val' => 'bar']],\n        ];\n    }\n\n    protected function mockConnectionForModel(Model $model, string $database, array $lastInsertIds = []): void\n    {\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$database.'Grammar';\n        $processorClass = 'Illuminate\\Database\\Query\\Processors\\\\'.$database.'Processor';\n        $processor = new $processorClass;\n        $connection = m::mock(Connection::class, ['getPostProcessor' => $processor]);\n        $grammar = new $grammarClass($connection);\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new Builder($connection, $grammar, $processor);\n        });\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $connection]);\n\n        $class = get_class($model);\n        $class::setConnectionResolver($resolver);\n\n        $connection->shouldReceive('getPdo')->andReturn($pdo = m::mock(PDO::class));\n\n        foreach ($lastInsertIds as $id) {\n            $pdo->expects('lastInsertId')->andReturn($id);\n        }\n    }\n}\n\nclass EloquentBuilderCreateOrFirstTestModel extends Model\n{\n    protected $table = 'table';\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse BadMethodCallException;\nuse Closure;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\RelationNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentBuilderTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testFindMethod()\n    {\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $builder->setModel($model);\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('first')->with(['column'])->andReturn('baz');\n\n        $result = $builder->find('bar', ['column']);\n        $this->assertSame('baz', $result);\n    }\n\n    public function testFindSoleMethod()\n    {\n        $builder = m::mock(Builder::class.'[sole]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $builder->setModel($model);\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('sole')->with(['column'])->andReturn('baz');\n\n        $result = $builder->findSole('bar', ['column']);\n        $this->assertSame('baz', $result);\n    }\n\n    public function testFindManyMethod()\n    {\n        // ids are not empty\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', ['one', 'two']);\n        $builder->shouldReceive('get')->with(['column'])->andReturn(['baz']);\n\n        $result = $builder->findMany(['one', 'two'], ['column']);\n        $this->assertEquals(['baz'], $result);\n\n        // ids are empty array\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('newCollection')->once()->withNoArgs()->andReturn('emptycollection');\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldNotReceive('whereIntegerInRaw');\n        $builder->shouldNotReceive('get');\n\n        $result = $builder->findMany([], ['column']);\n        $this->assertSame('emptycollection', $result);\n\n        // ids are empty collection\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('newCollection')->once()->withNoArgs()->andReturn('emptycollection');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldNotReceive('whereIn');\n        $builder->shouldNotReceive('get');\n\n        $result = $builder->findMany(collect(), ['column']);\n        $this->assertSame('emptycollection', $result);\n    }\n\n    public function testFindOrNewMethodModelFound()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $model->shouldReceive('findOrNew')->once()->andReturn('baz');\n\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('first')->with(['column'])->andReturn('baz');\n\n        $expected = $model->findOrNew('bar', ['column']);\n        $result = $builder->find('bar', ['column']);\n        $this->assertEquals($expected, $result);\n    }\n\n    public function testFindOrNewMethodModelNotFound()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $model->shouldReceive('findOrNew')->once()->andReturn(m::mock(Model::class));\n\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('first')->with(['column'])->andReturn(null);\n\n        $result = $model->findOrNew('bar', ['column']);\n        $findResult = $builder->find('bar', ['column']);\n        $this->assertNull($findResult);\n        $this->assertInstanceOf(Model::class, $result);\n    }\n\n    public function testFindOrFailMethodThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('first')->with(['column'])->andReturn(null);\n        $builder->findOrFail('bar', ['column']);\n    }\n\n    public function testFindOrFailMethodWithManyThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKey')->andReturn(1);\n        $model->shouldReceive('getKeyType')->andReturn('int');\n\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);\n        $builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model]));\n        $builder->findOrFail([1, 2], ['column']);\n    }\n\n    public function testFindOrFailMethodWithManyUsingCollectionThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKey')->andReturn(1);\n        $model->shouldReceive('getKeyType')->andReturn('int');\n\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);\n        $builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model]));\n        $builder->findOrFail(new Collection([1, 2]), ['column']);\n    }\n\n    public function testFindOrMethod()\n    {\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('where')->with('foo_table.foo', '=', 1)->twice();\n        $builder->getQuery()->shouldReceive('where')->with('foo_table.foo', '=', 2)->once();\n        $builder->shouldReceive('first')->andReturn($model)->once();\n        $builder->shouldReceive('first')->with(['column'])->andReturn($model)->once();\n        $builder->shouldReceive('first')->andReturn(null)->once();\n\n        $this->assertSame($model, $builder->findOr(1, fn () => 'callback result'));\n        $this->assertSame($model, $builder->findOr(1, ['column'], fn () => 'callback result'));\n        $this->assertSame('callback result', $builder->findOr(2, fn () => 'callback result'));\n    }\n\n    public function testFindOrMethodWithMany()\n    {\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model1 = $this->getMockModel();\n        $model2 = $this->getMockModel();\n        $model1->shouldReceive('getKeyType')->andReturn('int');\n        $model2->shouldReceive('getKeyType')->andReturn('int');\n        $builder->setModel($model1);\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2])->twice();\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2, 3])->once();\n        $builder->shouldReceive('get')->andReturn(new Collection([$model1, $model2]))->once();\n        $builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model1, $model2]))->once();\n        $builder->shouldReceive('get')->andReturn(null)->once();\n\n        $result = $builder->findOr([1, 2], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame($model1, $result[0]);\n        $this->assertSame($model2, $result[1]);\n\n        $result = $builder->findOr([1, 2], ['column'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame($model1, $result[0]);\n        $this->assertSame($model2, $result[1]);\n\n        $result = $builder->findOr([1, 2, 3], fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFindOrMethodWithManyUsingCollection()\n    {\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model1 = $this->getMockModel();\n        $model2 = $this->getMockModel();\n        $model1->shouldReceive('getKeyType')->andReturn('int');\n        $model2->shouldReceive('getKeyType')->andReturn('int');\n        $builder->setModel($model1);\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2])->twice();\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->with('foo_table.foo', [1, 2, 3])->once();\n        $builder->shouldReceive('get')->andReturn(new Collection([$model1, $model2]))->once();\n        $builder->shouldReceive('get')->with(['column'])->andReturn(new Collection([$model1, $model2]))->once();\n        $builder->shouldReceive('get')->andReturn(null)->once();\n\n        $result = $builder->findOr(new Collection([1, 2]), fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame($model1, $result[0]);\n        $this->assertSame($model2, $result[1]);\n\n        $result = $builder->findOr(new Collection([1, 2]), ['column'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame($model1, $result[0]);\n        $this->assertSame($model2, $result[1]);\n\n        $result = $builder->findOr(new Collection([1, 2, 3]), fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFirstOrFailMethodThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $builder->setModel($this->getMockModel());\n        $builder->shouldReceive('first')->with(['column'])->andReturn(null);\n        $builder->firstOrFail(['column']);\n    }\n\n    public function testFindWithMany()\n    {\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);\n        $builder->setModel($model);\n        $builder->shouldReceive('get')->with(['column'])->andReturn('baz');\n\n        $result = $builder->find([1, 2], ['column']);\n        $this->assertSame('baz', $result);\n    }\n\n    public function testFindWithManyUsingCollection()\n    {\n        $ids = collect([1, 2]);\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('foo_table.foo', [1, 2]);\n        $builder->setModel($model);\n        $builder->shouldReceive('get')->with(['column'])->andReturn('baz');\n\n        $result = $builder->find($ids, ['column']);\n        $this->assertSame('baz', $result);\n    }\n\n    public function testFirstMethod()\n    {\n        $builder = m::mock(Builder::class.'[get,take]', [$this->getMockQueryBuilder()]);\n        $builder->shouldReceive('limit')->with(1)->andReturnSelf();\n        $builder->shouldReceive('get')->with(['*'])->andReturn(new Collection(['bar']));\n\n        $result = $builder->first();\n        $this->assertSame('bar', $result);\n    }\n\n    public function testQualifyColumn()\n    {\n        $builder = new Builder(m::mock(BaseBuilder::class));\n        $builder->shouldReceive('from')->with('foo_table');\n\n        $builder->setModel(new EloquentBuilderTestStubStringPrimaryKey);\n\n        $this->assertSame('foo_table.column', $builder->qualifyColumn('column'));\n    }\n\n    public function testQualifyColumns()\n    {\n        $builder = new Builder(m::mock(BaseBuilder::class));\n        $builder->shouldReceive('from')->with('foo_table');\n\n        $builder->setModel(new EloquentBuilderTestStubStringPrimaryKey);\n\n        $this->assertEquals(['foo_table.column', 'foo_table.name'], $builder->qualifyColumns(['column', 'name']));\n    }\n\n    public function testGetMethodLoadsModelsAndHydratesEagerRelations()\n    {\n        $builder = m::mock(Builder::class.'[getModels,eagerLoadRelations]', [$this->getMockQueryBuilder()]);\n        $builder->shouldReceive('applyScopes')->andReturnSelf();\n        $builder->shouldReceive('getModels')->with(['foo'])->andReturn(['bar']);\n        $builder->shouldReceive('eagerLoadRelations')->with(['bar'])->andReturn(['bar', 'baz']);\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('newCollection')->with(['bar', 'baz'])->andReturn(new Collection(['bar', 'baz']));\n\n        $results = $builder->get(['foo']);\n        $this->assertEquals(['bar', 'baz'], $results->all());\n    }\n\n    public function testGetMethodDoesntHydrateEagerRelationsWhenNoResultsAreReturned()\n    {\n        $builder = m::mock(Builder::class.'[getModels,eagerLoadRelations]', [$this->getMockQueryBuilder()]);\n        $builder->shouldReceive('applyScopes')->andReturnSelf();\n        $builder->shouldReceive('getModels')->with(['foo'])->andReturn([]);\n        $builder->shouldReceive('eagerLoadRelations')->never();\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('newCollection')->with([])->andReturn(new Collection([]));\n\n        $results = $builder->get(['foo']);\n        $this->assertEquals([], $results->all());\n    }\n\n    public function testValueMethodWithModelFound()\n    {\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $mockModel = new stdClass;\n        $mockModel->name = 'foo';\n        $builder->shouldReceive('first')->with(['name'])->andReturn($mockModel);\n\n        $this->assertSame('foo', $builder->value('name'));\n    }\n\n    public function testValueMethodWithModelNotFound()\n    {\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $builder->shouldReceive('first')->with(['name'])->andReturn(null);\n\n        $this->assertNull($builder->value('name'));\n    }\n\n    public function testValueOrFailMethodWithModelFound()\n    {\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $mockModel = new stdClass;\n        $mockModel->name = 'foo';\n        $builder->shouldReceive('first')->with(['name'])->andReturn($mockModel);\n\n        $this->assertSame('foo', $builder->valueOrFail('name'));\n    }\n\n    public function testValueOrFailMethodWithModelNotFoundThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $builder = m::mock(Builder::class.'[first]', [$this->getMockQueryBuilder()]);\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo_table.foo', '=', 'bar');\n        $builder->shouldReceive('first')->with(['column'])->andReturn(null);\n        $builder->whereKey('bar')->valueOrFail('column');\n    }\n\n    public function testChunkWithLastChunkComplete()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,offset,limit,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection(['foo1', 'foo2']);\n        $chunk2 = new Collection(['foo3', 'foo4']);\n        $chunk3 = new Collection([]);\n\n        $builder->shouldReceive('getOffset')->once()->andReturn(null);\n        $builder->shouldReceive('getLimit')->once()->andReturn(null);\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(4)->andReturnSelf();\n        $builder->shouldReceive('limit')->times(3)->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        });\n    }\n\n    public function testChunkWithLastChunkPartial()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,offset,limit,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection(['foo1', 'foo2']);\n        $chunk2 = new Collection(['foo3']);\n        $builder->shouldReceive('getOffset')->once()->andReturn(null);\n        $builder->shouldReceive('getLimit')->once()->andReturn(null);\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('limit')->twice()->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        });\n    }\n\n    public function testChunkCanBeStoppedByReturningFalse()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,offset,limit,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection(['foo1', 'foo2']);\n        $chunk2 = new Collection(['foo3']);\n\n        $builder->shouldReceive('getOffset')->once()->andReturn(null);\n        $builder->shouldReceive('getLimit')->once()->andReturn(null);\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('limit')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(1)->andReturn($chunk1);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n\n            return false;\n        });\n    }\n\n    public function testChunkWithCountZero()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,offset,limit,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('getOffset')->once()->andReturn(null);\n        $builder->shouldReceive('getLimit')->once()->andReturn(null);\n        $builder->shouldReceive('offset')->never();\n        $builder->shouldReceive('limit')->never();\n        $builder->shouldReceive('get')->never();\n\n        $builder->chunk(0, function () {\n            $this->fail('Should not be called.');\n        });\n    }\n\n    public function testChunkPaginatesUsingIdWithLastChunkComplete()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = new Collection([(object) ['someIdField' => 10], (object) ['someIdField' => 11]]);\n        $chunk3 = new Collection([]);\n        $builder->shouldReceive('getOffset')->andReturnNull();\n        $builder->shouldReceive('getLimit')->andReturnNull();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 11, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithLastChunkPartial()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = new Collection([(object) ['someIdField' => 10]]);\n        $builder->shouldReceive('getOffset')->andReturnNull();\n        $builder->shouldReceive('getLimit')->andReturnNull();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithCountZero()\n    {\n        $builder = m::mock(Builder::class.'[getOffset,getLimit,forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('getOffset')->andReturnNull();\n        $builder->shouldReceive('getLimit')->andReturnNull();\n        $builder->shouldReceive('forPageAfterId')->never();\n        $builder->shouldReceive('get')->never();\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->never();\n\n        $builder->chunkById(0, function () {\n            $this->fail('Should never be called.');\n        }, 'someIdField');\n    }\n\n    public function testLazyWithLastChunkComplete()\n    {\n        $builder = m::mock(Builder::class.'[forPage,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();\n        $builder->shouldReceive('forPage')->once()->with(2, 2)->andReturnSelf();\n        $builder->shouldReceive('forPage')->once()->with(3, 2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn(\n            new Collection(['foo1', 'foo2']),\n            new Collection(['foo3', 'foo4']),\n            new Collection([])\n        );\n\n        $this->assertEquals(\n            ['foo1', 'foo2', 'foo3', 'foo4'],\n            $builder->lazy(2)->all()\n        );\n    }\n\n    public function testLazyWithLastChunkPartial()\n    {\n        $builder = m::mock(Builder::class.'[forPage,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();\n        $builder->shouldReceive('forPage')->once()->with(2, 2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn(\n            new Collection(['foo1', 'foo2']),\n            new Collection(['foo3'])\n        );\n\n        $this->assertEquals(\n            ['foo1', 'foo2', 'foo3'],\n            $builder->lazy(2)->all()\n        );\n    }\n\n    public function testLazyIsLazy()\n    {\n        $builder = m::mock(Builder::class.'[forPage,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn(new Collection(['foo1', 'foo2']));\n\n        $this->assertEquals(['foo1', 'foo2'], $builder->lazy(2)->take(2)->all());\n    }\n\n    public function testLazyByIdWithLastChunkComplete()\n    {\n        $builder = m::mock(Builder::class.'[forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = new Collection([(object) ['someIdField' => 10], (object) ['someIdField' => 11]]);\n        $chunk3 = new Collection([]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 11, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $this->assertEquals(\n            [\n                (object) ['someIdField' => 1],\n                (object) ['someIdField' => 2],\n                (object) ['someIdField' => 10],\n                (object) ['someIdField' => 11],\n            ],\n            $builder->lazyById(2, 'someIdField')->all()\n        );\n    }\n\n    public function testLazyByIdWithLastChunkPartial()\n    {\n        $builder = m::mock(Builder::class.'[forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = new Collection([(object) ['someIdField' => 10]]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $this->assertEquals(\n            [\n                (object) ['someIdField' => 1],\n                (object) ['someIdField' => 2],\n                (object) ['someIdField' => 10],\n            ],\n            $builder->lazyById(2, 'someIdField')->all()\n        );\n    }\n\n    public function testLazyByIdIsLazy()\n    {\n        $builder = m::mock(Builder::class.'[forPageAfterId,get]', [$this->getMockQueryBuilder()]);\n        $builder->getQuery()->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = new Collection([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn($chunk1);\n\n        $this->assertEquals(\n            [\n                (object) ['someIdField' => 1],\n                (object) ['someIdField' => 2],\n            ],\n            $builder->lazyById(2, 'someIdField')->take(2)->all()\n        );\n    }\n\n    public function testPluckReturnsTheMutatedAttributesOfAModel()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with('name', '')->andReturn(new BaseCollection(['bar', 'baz']));\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('name')->andReturn(true);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'bar'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'bar']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'baz'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'baz']));\n\n        $this->assertEquals(['foo_bar', 'foo_baz'], $builder->pluck('name')->all());\n    }\n\n    public function testPluckReturnsTheCastedAttributesOfAModel()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with('name', '')->andReturn(new BaseCollection(['bar', 'baz']));\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('name')->andReturn(false);\n        $builder->getModel()->shouldReceive('hasCast')->with('name')->andReturn(true);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'bar'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'bar']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'baz'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'baz']));\n\n        $this->assertEquals(['foo_bar', 'foo_baz'], $builder->pluck('name')->all());\n    }\n\n    public function testPluckReturnsTheDateAttributesOfAModel()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with('created_at', '')->andReturn(new BaseCollection(['2010-01-01 00:00:00', '2011-01-01 00:00:00']));\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('created_at')->andReturn(false);\n        $builder->getModel()->shouldReceive('hasCast')->with('created_at')->andReturn(false);\n        $builder->getModel()->shouldReceive('getDates')->andReturn(['created_at']);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['created_at' => '2010-01-01 00:00:00'])->andReturn(new EloquentBuilderTestPluckDatesStub(['created_at' => '2010-01-01 00:00:00']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['created_at' => '2011-01-01 00:00:00'])->andReturn(new EloquentBuilderTestPluckDatesStub(['created_at' => '2011-01-01 00:00:00']));\n\n        $this->assertEquals(['date_2010-01-01 00:00:00', 'date_2011-01-01 00:00:00'], $builder->pluck('created_at')->all());\n    }\n\n    public function testQualifiedPluckReturnsTheMutatedAttributesOfAModel()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('qualifyColumn')->with('name')->andReturn('foo_table.name');\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with($model->qualifyColumn('name'), '')->andReturn(new BaseCollection(['bar', 'baz']));\n        $builder->setModel($model);\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('name')->andReturn(true);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'bar'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'bar']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'baz'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'baz']));\n\n        $this->assertEquals(['foo_bar', 'foo_baz'], $builder->pluck($model->qualifyColumn('name'))->all());\n    }\n\n    public function testQualifiedPluckReturnsTheCastedAttributesOfAModel()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('qualifyColumn')->with('name')->andReturn('foo_table.name');\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with($model->qualifyColumn('name'), '')->andReturn(new BaseCollection(['bar', 'baz']));\n        $builder->setModel($model);\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('name')->andReturn(false);\n        $builder->getModel()->shouldReceive('hasCast')->with('name')->andReturn(true);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'bar'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'bar']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'baz'])->andReturn(new EloquentBuilderTestPluckStub(['name' => 'baz']));\n\n        $this->assertEquals(['foo_bar', 'foo_baz'], $builder->pluck($model->qualifyColumn('name'))->all());\n    }\n\n    public function testQualifiedPluckReturnsTheDateAttributesOfAModel()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('qualifyColumn')->with('created_at')->andReturn('foo_table.created_at');\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with($model->qualifyColumn('created_at'), '')->andReturn(new BaseCollection(['2010-01-01 00:00:00', '2011-01-01 00:00:00']));\n        $builder->setModel($model);\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('created_at')->andReturn(false);\n        $builder->getModel()->shouldReceive('hasCast')->with('created_at')->andReturn(false);\n        $builder->getModel()->shouldReceive('getDates')->andReturn(['created_at']);\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['created_at' => '2010-01-01 00:00:00'])->andReturn(new EloquentBuilderTestPluckDatesStub(['created_at' => '2010-01-01 00:00:00']));\n        $builder->getModel()->shouldReceive('newFromBuilder')->with(['created_at' => '2011-01-01 00:00:00'])->andReturn(new EloquentBuilderTestPluckDatesStub(['created_at' => '2011-01-01 00:00:00']));\n\n        $this->assertEquals(['date_2010-01-01 00:00:00', 'date_2011-01-01 00:00:00'], $builder->pluck($model->qualifyColumn('created_at'))->all());\n    }\n\n    public function testPluckWithoutModelGetterJustReturnsTheAttributesFoundInDatabase()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('pluck')->with('name', '')->andReturn(new BaseCollection(['bar', 'baz']));\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('hasAnyGetMutator')->with('name')->andReturn(false);\n        $builder->getModel()->shouldReceive('hasCast')->with('name')->andReturn(false);\n        $builder->getModel()->shouldReceive('getDates')->andReturn(['created_at']);\n\n        $this->assertEquals(['bar', 'baz'], $builder->pluck('name')->all());\n    }\n\n    public function testLocalMacrosAreCalledOnBuilder()\n    {\n        unset($_SERVER['__test.builder']);\n        $builder = new Builder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n        $builder->macro('fooBar', function ($builder) {\n            $_SERVER['__test.builder'] = $builder;\n\n            return $builder;\n        });\n        $result = $builder->fooBar();\n\n        $this->assertTrue($builder->hasMacro('fooBar'));\n        $this->assertEquals($builder, $result);\n        $this->assertEquals($builder, $_SERVER['__test.builder']);\n        unset($_SERVER['__test.builder']);\n    }\n\n    public function testGlobalMacrosAreCalledOnBuilder()\n    {\n        Builder::macro('foo', function ($bar) {\n            return $bar;\n        });\n\n        Builder::macro('bam', function () {\n            return $this->getQuery();\n        });\n\n        $builder = $this->getBuilder();\n\n        $this->assertTrue(Builder::hasGlobalMacro('foo'));\n        $this->assertSame('bar', $builder->foo('bar'));\n        $this->assertEquals($builder->bam(), $builder->getQuery());\n    }\n\n    public function testMissingStaticMacrosThrowsProperException()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Database\\Eloquent\\Builder::missingMacro()');\n\n        Builder::missingMacro();\n    }\n\n    public function testGetModelsProperlyHydratesModels()\n    {\n        $builder = m::mock(Builder::class.'[get]', [$this->getMockQueryBuilder()]);\n        $records[] = ['name' => 'taylor', 'age' => 26];\n        $records[] = ['name' => 'dayle', 'age' => 28];\n        $builder->getQuery()->shouldReceive('get')->once()->with(['foo'])->andReturn(new BaseCollection($records));\n        $model = m::mock(Model::class.'[getTable,hydrate]');\n        $model->shouldReceive('getTable')->once()->andReturn('foo_table');\n        $builder->setModel($model);\n        $model->shouldReceive('hydrate')->once()->with($records)->andReturn(new Collection(['hydrated']));\n        $models = $builder->getModels(['foo']);\n\n        $this->assertEquals(['hydrated'], $models);\n    }\n\n    public function testEagerLoadRelationsLoadTopLevelRelationships()\n    {\n        $builder = m::mock(Builder::class.'[eagerLoadRelation]', [$this->getMockQueryBuilder()]);\n        $nop1 = function () {\n            //\n        };\n        $nop2 = function () {\n            //\n        };\n        $builder->setEagerLoads(['foo' => $nop1, 'foo.bar' => $nop2]);\n        $builder->shouldAllowMockingProtectedMethods()->shouldReceive('eagerLoadRelation')->with(['models'], 'foo', $nop1)->andReturn(['foo']);\n\n        $results = $builder->eagerLoadRelations(['models']);\n        $this->assertEquals(['foo'], $results);\n    }\n\n    public function testEagerLoadRelationsCanBeFlushed()\n    {\n        $builder = m::mock(Builder::class.'[eagerLoadRelation]', [$this->getMockQueryBuilder()]);\n\n        $builder->setEagerLoads(['foo']);\n\n        $this->assertSame(['foo'], $builder->getEagerLoads());\n\n        $builder->withoutEagerLoads();\n\n        $this->assertEmpty($builder->getEagerLoads());\n    }\n\n    public function testRelationshipEagerLoadProcess()\n    {\n        $builder = m::mock(Builder::class.'[getRelation]', [$this->getMockQueryBuilder()]);\n        $builder->setEagerLoads(['orders' => function ($query) {\n            $_SERVER['__eloquent.constrain'] = $query;\n        }]);\n        $relation = m::mock(stdClass::class);\n        $relation->shouldReceive('addEagerConstraints')->once()->with(['models']);\n        $relation->shouldReceive('initRelation')->once()->with(['models'], 'orders')->andReturn(['models']);\n        $relation->shouldReceive('getEager')->once()->andReturn(['results']);\n        $relation->shouldReceive('match')->once()->with(['models'], ['results'], 'orders')->andReturn(['models.matched']);\n        $builder->shouldReceive('getRelation')->once()->with('orders')->andReturn($relation);\n        $results = $builder->eagerLoadRelations(['models']);\n\n        $this->assertEquals(['models.matched'], $results);\n        $this->assertEquals($relation, $_SERVER['__eloquent.constrain']);\n        unset($_SERVER['__eloquent.constrain']);\n    }\n\n    public function testRelationshipEagerLoadProcessForImplicitlyEmpty()\n    {\n        $queryBuilder = $this->getMockQueryBuilder();\n        $builder = m::mock(Builder::class.'[getRelation]', [$queryBuilder]);\n        $builder->setEagerLoads(['parentFoo' => function ($query) {\n            $_SERVER['__eloquent.constrain'] = $query;\n        }]);\n        $model = new EloquentBuilderTestModelSelfRelatedStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n\n        $models = [\n            new EloquentBuilderTestModelSelfRelatedStub,\n            new EloquentBuilderTestModelSelfRelatedStub,\n        ];\n        $relation = m::mock($model->parentFoo());\n\n        $builder->shouldReceive('getRelation')->once()->with('parentFoo')->andReturn($relation);\n\n        $results = $builder->eagerLoadRelations($models);\n\n        unset($_SERVER['__eloquent.constrain']);\n    }\n\n    public function testGetRelationProperlySetsNestedRelationships()\n    {\n        $builder = $this->getBuilder();\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('newInstance->orders')->once()->andReturn($relation = m::mock(stdClass::class));\n        $relationQuery = m::mock(stdClass::class);\n        $relation->shouldReceive('getQuery')->andReturn($relationQuery);\n        $relationQuery->shouldReceive('with')->once()->with(['lines' => null, 'lines.details' => null]);\n        $builder->setEagerLoads(['orders' => null, 'orders.lines' => null, 'orders.lines.details' => null]);\n\n        $builder->getRelation('orders');\n    }\n\n    public function testGetRelationProperlySetsNestedRelationshipsWithSimilarNames()\n    {\n        $builder = $this->getBuilder();\n        $builder->setModel($this->getMockModel());\n        $builder->getModel()->shouldReceive('newInstance->orders')->once()->andReturn($relation = m::mock(stdClass::class));\n        $builder->getModel()->shouldReceive('newInstance->ordersGroups')->once()->andReturn($groupsRelation = m::mock(stdClass::class));\n\n        $relationQuery = m::mock(stdClass::class);\n        $relation->shouldReceive('getQuery')->andReturn($relationQuery);\n\n        $groupRelationQuery = m::mock(stdClass::class);\n        $groupsRelation->shouldReceive('getQuery')->andReturn($groupRelationQuery);\n        $groupRelationQuery->shouldReceive('with')->once()->with(['lines' => null, 'lines.details' => null]);\n\n        $builder->setEagerLoads(['orders' => null, 'ordersGroups' => null, 'ordersGroups.lines' => null, 'ordersGroups.lines.details' => null]);\n\n        $builder->getRelation('orders');\n        $builder->getRelation('ordersGroups');\n    }\n\n    public function testGetRelationThrowsException()\n    {\n        $this->expectException(RelationNotFoundException::class);\n\n        $builder = $this->getBuilder();\n        $builder->setModel($this->getMockModel());\n\n        $builder->getRelation('invalid');\n    }\n\n    public function testEagerLoadParsingSetsProperRelationships()\n    {\n        $builder = $this->getBuilder();\n        $builder->with(['orders', 'orders.lines']);\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertEquals(['orders', 'orders.lines'], array_keys($eagers));\n        $this->assertInstanceOf(Closure::class, $eagers['orders']);\n        $this->assertInstanceOf(Closure::class, $eagers['orders.lines']);\n\n        $builder = $this->getBuilder();\n        $builder->with('orders', 'orders.lines');\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertEquals(['orders', 'orders.lines'], array_keys($eagers));\n        $this->assertInstanceOf(Closure::class, $eagers['orders']);\n        $this->assertInstanceOf(Closure::class, $eagers['orders.lines']);\n\n        $builder = $this->getBuilder();\n        $builder->with(['orders.lines']);\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertEquals(['orders', 'orders.lines'], array_keys($eagers));\n        $this->assertInstanceOf(Closure::class, $eagers['orders']);\n        $this->assertInstanceOf(Closure::class, $eagers['orders.lines']);\n\n        $builder = $this->getBuilder();\n        $builder->with(['orders' => function () {\n            return 'foo';\n        }]);\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertSame('foo', $eagers['orders']($this->getBuilder()));\n\n        $builder = $this->getBuilder();\n        $builder->with(['orders.lines' => function () {\n            return 'foo';\n        }]);\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertInstanceOf(Closure::class, $eagers['orders']);\n        $this->assertNull($eagers['orders']());\n        $this->assertSame('foo', $eagers['orders.lines']($this->getBuilder()));\n\n        $builder = $this->getBuilder();\n        $builder->with('orders.lines', function () {\n            return 'foo';\n        });\n        $eagers = $builder->getEagerLoads();\n\n        $this->assertInstanceOf(Closure::class, $eagers['orders']);\n        $this->assertNull($eagers['orders']());\n        $this->assertSame('foo', $eagers['orders.lines']($this->getBuilder()));\n    }\n\n    public function testQueryPassThru()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('foobar')->once()->andReturn('foo');\n\n        $this->assertInstanceOf(Builder::class, $builder->foobar());\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('insert')->once()->with(['bar'])->andReturn('foo');\n\n        $this->assertSame('foo', $builder->insert(['bar']));\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('insertOrIgnore')->once()->with(['bar'])->andReturn('foo');\n\n        $this->assertSame('foo', $builder->insertOrIgnore(['bar']));\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('insertOrIgnoreUsing')->once()->with(['bar'], 'baz')->andReturn('foo');\n\n        $this->assertSame('foo', $builder->insertOrIgnoreUsing(['bar'], 'baz'));\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('insertGetId')->once()->with(['bar'])->andReturn('foo');\n\n        $this->assertSame('foo', $builder->insertGetId(['bar']));\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('insertUsing')->once()->with(['bar'], 'baz')->andReturn('foo');\n\n        $this->assertSame('foo', $builder->insertUsing(['bar'], 'baz'));\n\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('raw')->once()->with('bar')->andReturn('foo');\n\n        $this->assertSame('foo', $builder->raw('bar'));\n    }\n\n    public function testQueryScopes()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo', 'bar');\n        $builder->setModel($model = new EloquentBuilderTestScopeStub);\n        $result = $builder->approved();\n\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testQueryDynamicScopes()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->getQuery()->shouldReceive('where')->once()->with('bar', 'foo');\n        $builder->setModel($model = new EloquentBuilderTestDynamicScopeStub);\n        $result = $builder->dynamic('bar', 'foo');\n\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testQueryDynamicScopesNamed()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo', 'foo');\n        $builder->setModel($model = new EloquentBuilderTestDynamicScopeStub);\n        $result = $builder->dynamic(bar: 'foo');\n\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testNestedWhere()\n    {\n        $nestedQuery = m::mock(Builder::class);\n        $nestedRawQuery = $this->getMockQueryBuilder();\n        $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery);\n        $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]);\n        $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]);\n        $model = $this->getMockModel()->makePartial();\n        $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery);\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('addNestedWhereQuery')->once()->with($nestedRawQuery, 'and');\n        $nestedQuery->shouldReceive('foo')->once();\n\n        $result = $builder->where(function ($query) {\n            $query->foo();\n        });\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testRealNestedWhereWithScopes()\n    {\n        $model = new EloquentBuilderTestNestedStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->where('foo', '=', 'bar')->where(function ($query) {\n            $query->where('baz', '>', 9000);\n        });\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and (\"baz\" > ?) and \"table\".\"deleted_at\" is null', $query->toSql());\n        $this->assertEquals(['bar', 9000], $query->getBindings());\n    }\n\n    public function testRealNestedWhereWithScopesMacro()\n    {\n        $model = new EloquentBuilderTestNestedStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->where('foo', '=', 'bar')->where(function ($query) {\n            $query->where('baz', '>', 9000)->onlyTrashed();\n        })->withTrashed();\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and (\"baz\" > ? and \"table\".\"deleted_at\" is not null)', $query->toSql());\n        $this->assertEquals(['bar', 9000], $query->getBindings());\n    }\n\n    public function testRealNestedWhereWithMultipleScopesAndOneDeadScope()\n    {\n        $model = new EloquentBuilderTestNestedStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->empty()->where('foo', '=', 'bar')->empty()->where(function ($query) {\n            $query->empty()->where('baz', '>', 9000);\n        });\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and (\"baz\" > ?) and \"table\".\"deleted_at\" is null', $query->toSql());\n        $this->assertEquals(['bar', 9000], $query->getBindings());\n    }\n\n    public function testSimpleWhereNot()\n    {\n        $model = new EloquentBuilderTestStub();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->whereNot('name', 'foo')->whereNot('name', '<>', 'bar');\n        $this->assertEquals('select * from \"table\" where not \"name\" = ? and not \"name\" <> ?', $query->toSql());\n        $this->assertEquals(['foo', 'bar'], $query->getBindings());\n    }\n\n    public function testWhereNot()\n    {\n        $nestedQuery = m::mock(Builder::class);\n        $nestedRawQuery = $this->getMockQueryBuilder();\n        $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery);\n        $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]);\n        $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]);\n        $model = $this->getMockModel()->makePartial();\n        $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery);\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('addNestedWhereQuery')->once()->with($nestedRawQuery, 'and not');\n        $nestedQuery->shouldReceive('foo')->once();\n\n        $result = $builder->whereNot(function ($query) {\n            $query->foo();\n        });\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testSimpleOrWhereNot()\n    {\n        $model = new EloquentBuilderTestStub();\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->orWhereNot('name', 'foo')->orWhereNot('name', '<>', 'bar');\n        $this->assertEquals('select * from \"table\" where not \"name\" = ? or not \"name\" <> ?', $query->toSql());\n        $this->assertEquals(['foo', 'bar'], $query->getBindings());\n    }\n\n    public function testOrWhereNot()\n    {\n        $nestedQuery = m::mock(Builder::class);\n        $nestedRawQuery = $this->getMockQueryBuilder();\n        $nestedQuery->shouldReceive('getQuery')->once()->andReturn($nestedRawQuery);\n        $nestedQuery->shouldReceive('getEagerLoads')->once()->andReturn([]);\n        $nestedQuery->shouldReceive('removedScopes')->once()->andReturn([]);\n        $model = $this->getMockModel()->makePartial();\n        $model->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($nestedQuery);\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('from');\n        $builder->setModel($model);\n        $builder->getQuery()->shouldReceive('addNestedWhereQuery')->once()->with($nestedRawQuery, 'or not');\n        $nestedQuery->shouldReceive('foo')->once();\n\n        $result = $builder->orWhereNot(function ($query) {\n            $query->foo();\n        });\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testRealQueryHigherOrderOrWhereScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->orWhere->two();\n        $this->assertSame('select * from \"table\" where \"one\" = ? or (\"two\" = ?)', $query->toSql());\n    }\n\n    public function testRealQueryChainedHigherOrderOrWhereScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->orWhere->two()->orWhere->three();\n        $this->assertSame('select * from \"table\" where \"one\" = ? or (\"two\" = ?) or (\"three\" = ?)', $query->toSql());\n    }\n\n    public function testRealQueryHigherOrderWhereNotScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->whereNot->two();\n        $this->assertSame('select * from \"table\" where \"one\" = ? and not (\"two\" = ?)', $query->toSql());\n    }\n\n    public function testRealQueryChainedHigherOrderWhereNotScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->whereNot->two()->whereNot->three();\n        $this->assertSame('select * from \"table\" where \"one\" = ? and not (\"two\" = ?) and not (\"three\" = ?)', $query->toSql());\n    }\n\n    public function testRealQueryHigherOrderOrWhereNotScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->orWhereNot->two();\n        $this->assertSame('select * from \"table\" where \"one\" = ? or not (\"two\" = ?)', $query->toSql());\n    }\n\n    public function testRealQueryChainedHigherOrderOrWhereNotScopes()\n    {\n        $model = new EloquentBuilderTestHigherOrderWhereScopeStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $query = $model->newQuery()->one()->orWhereNot->two()->orWhereNot->three();\n        $this->assertSame('select * from \"table\" where \"one\" = ? or not (\"two\" = ?) or not (\"three\" = ?)', $query->toSql());\n    }\n\n    public function testSimpleWhere()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo', '=', 'bar');\n        $result = $builder->where('foo', '=', 'bar');\n        $this->assertEquals($result, $builder);\n    }\n\n    public function testPostgresOperatorsWhere()\n    {\n        $builder = $this->getBuilder();\n        $builder->getQuery()->shouldReceive('where')->once()->with('foo', '@>', 'bar');\n        $result = $builder->where('foo', '@>', 'bar');\n        $this->assertEquals($result, $builder);\n    }\n\n    public function testWhereBelongsTo()\n    {\n        $related = new EloquentBuilderTestWhereBelongsToStub([\n            'id' => 1,\n            'parent_id' => 2,\n        ]);\n\n        $parent = new EloquentBuilderTestWhereBelongsToStub([\n            'id' => 2,\n            'parent_id' => 1,\n        ]);\n\n        $builder = $this->getBuilder();\n        $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');\n        $builder->setModel($related);\n        $builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2], 'and');\n\n        $result = $builder->whereBelongsTo($parent);\n        $this->assertEquals($result, $builder);\n\n        $builder = $this->getBuilder();\n        $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');\n        $builder->setModel($related);\n        $builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2], 'and');\n\n        $result = $builder->whereBelongsTo($parent, 'parent');\n        $this->assertEquals($result, $builder);\n\n        $parents = new Collection([new EloquentBuilderTestWhereBelongsToStub([\n            'id' => 2,\n            'parent_id' => 1,\n        ]), new EloquentBuilderTestWhereBelongsToStub([\n            'id' => 3,\n            'parent_id' => 1,\n        ])]);\n\n        $builder = $this->getBuilder();\n        $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');\n        $builder->setModel($related);\n        $builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2, 3], 'and');\n\n        $result = $builder->whereBelongsTo($parents);\n        $this->assertEquals($result, $builder);\n\n        $builder = $this->getBuilder();\n        $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');\n        $builder->setModel($related);\n        $builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2, 3], 'and');\n\n        $result = $builder->whereBelongsTo($parents, 'parent');\n        $this->assertEquals($result, $builder);\n    }\n\n    public function testWhereAttachedTo()\n    {\n        $related = new EloquentBuilderTestModelFarRelatedStub;\n        $related->id = 49;\n        $related->name = 'test';\n\n        $builder = EloquentBuilderTestModelParentStub::whereAttachedTo($related, 'roles');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where exists (select * from \"eloquent_builder_test_model_far_related_stubs\" inner join \"user_role\" on \"eloquent_builder_test_model_far_related_stubs\".\"id\" = \"user_role\".\"related_id\" where \"eloquent_builder_test_model_parent_stubs\".\"id\" = \"user_role\".\"self_id\" and \"eloquent_builder_test_model_far_related_stubs\".\"id\" in (49))', $builder->toSql());\n    }\n\n    public function testWhereAttachedToCollection()\n    {\n        $model1 = new EloquentBuilderTestModelParentStub;\n        $model1->id = 3;\n        $model1->name = 'test3';\n\n        $model2 = new EloquentBuilderTestModelParentStub;\n        $model2->id = 4;\n        $model2->name = 'test4';\n\n        $builder = EloquentBuilderTestModelFarRelatedStub::whereAttachedTo(new Collection([$model1, $model2]), 'roles');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_far_related_stubs\" where exists (select * from \"eloquent_builder_test_model_parent_stubs\" inner join \"user_role\" on \"eloquent_builder_test_model_parent_stubs\".\"id\" = \"user_role\".\"self_id\" where \"eloquent_builder_test_model_far_related_stubs\".\"id\" = \"user_role\".\"related_id\" and \"eloquent_builder_test_model_parent_stubs\".\"id\" in (3, 4))', $builder->toSql());\n    }\n\n    public function testDeleteOverride()\n    {\n        $builder = $this->getBuilder();\n        $builder->onDelete(function ($builder) {\n            return ['foo' => $builder];\n        });\n        $this->assertEquals(['foo' => $builder], $builder->delete());\n    }\n\n    public function testWithCount()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withCount('foo');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithCountAndSelect()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->select('id')->withCount('foo');\n\n        $this->assertSame('select \"id\", (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithCountSecondRelationWithClosure()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withCount(['address', 'foo' => function ($query) {\n            $query->where('active', false);\n        }]);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"address_count\", (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"active\" = ?) as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithCountAndMergedWheres()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->select('id')->withCount(['activeFoo' => function ($q) {\n            $q->where('bam', '>', 'qux');\n        }]);\n\n        $this->assertSame('select \"id\", (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"bam\" > ? and \"active\" = ?) as \"active_foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n        $this->assertEquals(['qux', true], $builder->getBindings());\n    }\n\n    public function testWithCountAndGlobalScope()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        EloquentBuilderTestModelCloseRelatedStub::addGlobalScope('withCount', function ($query) {\n            return $query->addSelect('id');\n        });\n\n        $builder = $model->select('id')->withCount(['foo']);\n\n        // Remove the global scope so it doesn't interfere with any other tests\n        EloquentBuilderTestModelCloseRelatedStub::addGlobalScope('withCount', function ($query) {\n            //\n        });\n\n        $this->assertSame('select \"id\", (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithMin()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withMin('foo', 'price');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select min(\"eloquent_builder_test_model_close_related_stubs\".\"price\") from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_min_price\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithMinExpression()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withMin('foo', new Expression('price - discount'));\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select min(price - discount) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_min_price_discount\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithMinOnBelongsToMany()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withMin('roles', 'id');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select min(\"eloquent_builder_test_model_far_related_stubs\".\"id\") from \"eloquent_builder_test_model_far_related_stubs\" inner join \"user_role\" on \"eloquent_builder_test_model_far_related_stubs\".\"id\" = \"user_role\".\"related_id\" where \"eloquent_builder_test_model_parent_stubs\".\"id\" = \"user_role\".\"self_id\") as \"roles_min_id\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithMinOnSelfRelated()\n    {\n        $model = new EloquentBuilderTestModelSelfRelatedStub;\n\n        $sql = $model->withMin('childFoos', 'created_at')->toSql();\n\n        // alias has a dynamic hash, so replace with a static string for comparison\n        $alias = 'self_alias_hash';\n        $aliasRegex = '/\\b(laravel_reserved_\\d)(\\b|$)/i';\n\n        $sql = preg_replace($aliasRegex, $alias, $sql);\n\n        $this->assertSame('select \"self_related_stubs\".*, (select min(\"self_alias_hash\".\"created_at\") from \"self_related_stubs\" as \"self_alias_hash\" where \"self_related_stubs\".\"id\" = \"self_alias_hash\".\"parent_id\") as \"child_foos_min_created_at\" from \"self_related_stubs\"', $sql);\n    }\n\n    public function testWithMax()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withMax('foo', 'price');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select max(\"eloquent_builder_test_model_close_related_stubs\".\"price\") from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_max_price\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithMaxExpression()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withMax('foo', new Expression('price - discount'));\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select max(price - discount) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_max_price_discount\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithAvg()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withAvg('foo', 'price');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select avg(\"eloquent_builder_test_model_close_related_stubs\".\"price\") from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_avg_price\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWitAvgExpression()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withAvg('foo', new Expression('price - discount'));\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select avg(price - discount) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_avg_price_discount\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithCountAndConstraintsAndHaving()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('bar', 'baz');\n        $builder->withCount(['foo' => function ($q) {\n            $q->where('bam', '>', 'qux');\n        }])->having('foo_count', '>=', 1);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"bam\" > ?) as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? having \"foo_count\" >= ?', $builder->toSql());\n        $this->assertEquals(['qux', 'baz', 1], $builder->getBindings());\n    }\n\n    public function testWithCountAndRename()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withCount('foo as foo_bar');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_bar\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithCountMultipleAndPartialRename()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withCount(['foo as foo_bar', 'foo']);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_bar\", (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithAggregateAlias()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withAggregate('foo', new Expression('TIMESTAMPDIFF(SECOND, `created_at`, `updated_at`)'), 'sum');\n\n        $this->assertSame(\n            'select \"eloquent_builder_test_model_parent_stubs\".*, (select sum(TIMESTAMPDIFF(SECOND, `created_at`, `updated_at`)) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_sum_timestampdiffsecond_created_at_updated_at\" from \"eloquent_builder_test_model_parent_stubs\"',\n            $builder->toSql()\n        );\n    }\n\n    public function testWithAggregateAndSelfRelationConstrain()\n    {\n        EloquentBuilderTestStub::resolveRelationUsing('children', function ($model) {\n            return $model->hasMany(EloquentBuilderTestStub::class, 'parent_id', 'id')->where('enum_value', new stdClass);\n        });\n\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $relationHash = $model->children()->getRelationCountHash(false);\n\n        $builder = $model->withCount('children');\n\n        $this->assertSame(vsprintf('select \"table\".*, (select count(*) from \"table\" as \"%s\" where \"table\".\"id\" = \"%s\".\"parent_id\" and \"enum_value\" = ?) as \"children_count\" from \"table\"', [$relationHash, $relationHash]), $builder->toSql());\n    }\n\n    public function testWithExists()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withExists('foo');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithExistsAndSelect()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->select('id')->withExists('foo');\n\n        $this->assertSame('select \"id\", exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithExistsAndMergedWheres()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->select('id')->withExists(['activeFoo' => function ($q) {\n            $q->where('bam', '>', 'qux');\n        }]);\n\n        $this->assertSame('select \"id\", exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"bam\" > ? and \"active\" = ?) as \"active_foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n        $this->assertEquals(['qux', true], $builder->getBindings());\n    }\n\n    public function testWithExistsAndGlobalScope()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        EloquentBuilderTestModelCloseRelatedStub::addGlobalScope('withExists', function ($query) {\n            return $query->addSelect('id');\n        });\n\n        $builder = $model->select('id')->withExists(['foo']);\n\n        // Remove the global scope so it doesn't interfere with any other tests\n        EloquentBuilderTestModelCloseRelatedStub::addGlobalScope('withExists', function ($query) {\n            //\n        });\n\n        $this->assertSame('select \"id\", exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithExistsOnBelongsToMany()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withExists('roles');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, exists(select * from \"eloquent_builder_test_model_far_related_stubs\" inner join \"user_role\" on \"eloquent_builder_test_model_far_related_stubs\".\"id\" = \"user_role\".\"related_id\" where \"eloquent_builder_test_model_parent_stubs\".\"id\" = \"user_role\".\"self_id\") as \"roles_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithExistsOnSelfRelated()\n    {\n        $model = new EloquentBuilderTestModelSelfRelatedStub;\n\n        $sql = $model->withExists('childFoos')->toSql();\n\n        // alias has a dynamic hash, so replace with a static string for comparison\n        $alias = 'self_alias_hash';\n        $aliasRegex = '/\\b(laravel_reserved_\\d)(\\b|$)/i';\n\n        $sql = preg_replace($aliasRegex, $alias, $sql);\n\n        $this->assertSame('select \"self_related_stubs\".*, exists(select * from \"self_related_stubs\" as \"self_alias_hash\" where \"self_related_stubs\".\"id\" = \"self_alias_hash\".\"parent_id\") as \"child_foos_exists\" from \"self_related_stubs\"', $sql);\n    }\n\n    public function testWithExistsAndRename()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withExists('foo as foo_bar');\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_bar\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testWithExistsMultipleAndPartialRename()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->withExists(['foo as foo_bar', 'foo']);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_bar\", exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n    }\n\n    public function testHasWithConstraintsAndHavingInSubquery()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('bar', 'baz');\n        $builder->whereHas('foo', function ($q) {\n            $q->having('bam', '>', 'qux');\n        })->where('quux', 'quuux');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? and exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" having \"bam\" > ?) and \"quux\" = ?', $builder->toSql());\n        $this->assertEquals(['baz', 'qux', 'quuux'], $builder->getBindings());\n    }\n\n    public function testHasWithConstraintsWithOrWhereAndHavingInSubquery()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('name', 'larry');\n        $builder->whereHas('address', function ($q) {\n            $q->where('zipcode', '90210');\n            $q->orWhere('zipcode', '90220');\n            $q->having('street', '=', 'fooside dr');\n        })->where('age', 29);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"name\" = ? and exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and (\"zipcode\" = ? or \"zipcode\" = ?) having \"street\" = ?) and \"age\" = ?', $builder->toSql());\n        $this->assertEquals(['larry', '90210', '90220', 'fooside dr', 29], $builder->getBindings());\n    }\n\n    public function testHasWithConstraintsWithOrWhereAndSubqueryInRelationFromClause()\n    {\n        EloquentBuilderTestModelParentStub::resolveRelationUsing('addressAsExpression', function ($model) {\n            return $model->address()->fromSub(EloquentBuilderTestModelCloseRelatedStub::query(), 'eloquent_builder_test_model_close_related_stubs');\n        });\n\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('name', 'larry');\n        $builder->whereHas('addressAsExpression', function ($q) {\n            $q->where('zipcode', '90210');\n            $q->orWhere('zipcode', '90220');\n            $q->having('street', '=', 'fooside dr');\n        })->where('age', 29);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"name\" = ? and exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and (\"zipcode\" = ? or \"zipcode\" = ?) having \"street\" = ?) and \"age\" = ?', $builder->toSql());\n        $this->assertEquals(['larry', '90210', '90220', 'fooside dr', 29], $builder->getBindings());\n    }\n\n    public function testHasWithConstraintsAndJoinAndHavingInSubquery()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $builder = $model->where('bar', 'baz');\n        $builder->whereHas('foo', function ($q) {\n            $q->join('quuuux', function ($j) {\n                $j->where('quuuuux', '=', 'quuuuuux');\n            });\n            $q->having('bam', '>', 'qux');\n        })->where('quux', 'quuux');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? and exists (select * from \"eloquent_builder_test_model_close_related_stubs\" inner join \"quuuux\" on \"quuuuux\" = ? where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" having \"bam\" > ?) and \"quux\" = ?', $builder->toSql());\n        $this->assertEquals(['baz', 'quuuuuux', 'qux', 'quuux'], $builder->getBindings());\n    }\n\n    public function testHasWithConstraintsAndHavingInSubqueryWithCount()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('bar', 'baz');\n        $builder->whereHas('foo', function ($q) {\n            $q->having('bam', '>', 'qux');\n        }, '>=', 2)->where('quux', 'quuux');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? and (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" having \"bam\" > ?) >= 2 and \"quux\" = ?', $builder->toSql());\n        $this->assertEquals(['baz', 'qux', 'quuux'], $builder->getBindings());\n    }\n\n    public function testWithCountAndConstraintsWithBindingInSelectSub()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->newQuery();\n        $builder->withCount(['foo' => function ($q) use ($model) {\n            $q->selectSub($model->newQuery()->where('bam', '=', 3)->selectRaw('count(0)'), 'bam_3_count');\n        }]);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, (select count(*) from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_count\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n        $this->assertSame([], $builder->getBindings());\n    }\n\n    public function testWithExistsAndConstraintsWithBindingInSelectSub()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->newQuery();\n        $builder->withExists(['foo' => function ($q) use ($model) {\n            $q->selectSub($model->newQuery()->where('bam', '=', 3)->selectRaw('count(0)'), 'bam_3_count');\n        }]);\n\n        $this->assertSame('select \"eloquent_builder_test_model_parent_stubs\".*, exists(select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\") as \"foo_exists\" from \"eloquent_builder_test_model_parent_stubs\"', $builder->toSql());\n        $this->assertSame([], $builder->getBindings());\n    }\n\n    public function testHasNestedWithConstraints()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->whereHas('foo', function ($q) {\n            $q->whereHas('bar', function ($q) {\n                $q->where('baz', 'bam');\n            });\n        })->toSql();\n\n        $result = $model->whereHas('foo.bar', function ($q) {\n            $q->where('baz', 'bam');\n        })->toSql();\n\n        $this->assertEquals($builder, $result);\n    }\n\n    public function testHasNested()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->whereHas('foo', function ($q) {\n            $q->has('bar');\n        });\n\n        $result = $model->has('foo.bar')->toSql();\n\n        $this->assertEquals($builder->toSql(), $result);\n    }\n\n    public function testHasNestedWithMorphTo()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $connection = $this->mockConnectionForModel($model, '');\n\n        $morphToKey = $model->morph()->getMorphType();\n\n        $connection->shouldReceive('select')->once()->andReturn([\n            [$morphToKey => EloquentBuilderTestModelFarRelatedStub::class],\n            [$morphToKey => EloquentBuilderTestModelOtherFarRelatedStub::class],\n        ]);\n\n        $builder = $model->orWhereHasMorph('morph', [EloquentBuilderTestModelFarRelatedStub::class], function ($q) {\n            $q->has('baz');\n        })->orWhereHasMorph('morph', [EloquentBuilderTestModelOtherFarRelatedStub::class], function ($q) {\n            $q->has('baz');\n        });\n\n        $results = $model->has('morph.baz')->toSql();\n\n        // we need to adjust the expected builder because some parathesis are added,\n        // which doesn't impact the behavior of the test.\n\n        $builderSql = $builder->toSql();\n        $builderSql = str_replace(')))) or ((', '))) or (', $builderSql);\n\n        $this->assertSame($builderSql, $results);\n    }\n\n    public function testHasNestedWithMorphToAndMultipleSubRelations()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $connection = $this->mockConnectionForModel($model, '');\n\n        $morphToKey = $model->morph()->getMorphType();\n\n        $connection->shouldReceive('select')->once()->andReturn([\n            [$morphToKey => EloquentBuilderTestModelFarRelatedStub::class],\n            [$morphToKey => EloquentBuilderTestModelOtherFarRelatedStub::class],\n        ]);\n\n        $builder = $model->orWhereHasMorph('morph', [EloquentBuilderTestModelFarRelatedStub::class], function ($q) {\n            $q->has('baz.bam');\n        })->orWhereHasMorph('morph', [EloquentBuilderTestModelOtherFarRelatedStub::class], function ($q) {\n            $q->has('baz.bam');\n        });\n\n        $results = $model->has('morph.baz.bam')->toSql();\n\n        // we need to adjust the expected builder because some parathesis are added,\n        // which doesn't impact the behavior of the test.\n\n        $builderSql = $builder->toSql();\n        $builderSql = str_replace(')))) or ((', '))) or (', $builderSql);\n\n        $this->assertSame($builderSql, $results);\n    }\n\n    public function testOrHasNested()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->whereHas('foo', function ($q) {\n            $q->has('bar');\n        })->orWhereHas('foo', function ($q) {\n            $q->has('baz');\n        });\n\n        $result = $model->has('foo.bar')->orHas('foo.baz')->toSql();\n\n        $this->assertEquals($builder->toSql(), $result);\n    }\n\n    public function testSelfHasNested()\n    {\n        $model = new EloquentBuilderTestModelSelfRelatedStub;\n\n        $nestedSql = $model->whereHas('parentFoo', function ($q) {\n            $q->has('childFoo');\n        })->toSql();\n\n        $dotSql = $model->has('parentFoo.childFoo')->toSql();\n\n        // alias has a dynamic hash, so replace with a static string for comparison\n        $alias = 'self_alias_hash';\n        $aliasRegex = '/\\b(laravel_reserved_\\d)(\\b|$)/i';\n\n        $nestedSql = preg_replace($aliasRegex, $alias, $nestedSql);\n        $dotSql = preg_replace($aliasRegex, $alias, $dotSql);\n\n        $this->assertEquals($nestedSql, $dotSql);\n    }\n\n    public function testSelfHasNestedUsesAlias()\n    {\n        $model = new EloquentBuilderTestModelSelfRelatedStub;\n\n        $sql = $model->has('parentFoo.childFoo')->toSql();\n\n        // alias has a dynamic hash, so replace with a static string for comparison\n        $alias = 'self_alias_hash';\n        $aliasRegex = '/\\b(laravel_reserved_\\d)(\\b|$)/i';\n\n        $sql = preg_replace($aliasRegex, $alias, $sql);\n\n        $this->assertStringContainsString('\"self_alias_hash\".\"id\" = \"self_related_stubs\".\"parent_id\"', $sql);\n    }\n\n    public function testDoesntHave()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->doesntHave('foo');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\")', $builder->toSql());\n    }\n\n    public function testDoesntHaveNested()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->doesntHave('foo.bar');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and exists (select * from \"eloquent_builder_test_model_far_related_stubs\" where \"eloquent_builder_test_model_close_related_stubs\".\"id\" = \"eloquent_builder_test_model_far_related_stubs\".\"eloquent_builder_test_model_close_related_stub_id\"))', $builder->toSql());\n    }\n\n    public function testOrDoesntHave()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('bar', 'baz')->orDoesntHave('foo');\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\")', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testWhereDoesntHave()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->whereDoesntHave('foo', function ($query) {\n            $query->where('bar', 'baz');\n        });\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testOrWhereDoesntHave()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n\n        $builder = $model->where('bar', 'baz')->orWhereDoesntHave('foo', function ($query) {\n            $query->where('qux', 'quux');\n        });\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not exists (select * from \"eloquent_builder_test_model_close_related_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"foo_id\" = \"eloquent_builder_test_model_close_related_stubs\".\"id\" and \"qux\" = ?)', $builder->toSql());\n        $this->assertEquals(['baz', 'quux'], $builder->getBindings());\n    }\n\n    public function testWhereMorphedTo()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereMorphedToCollection()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $builder = $model->whereMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)))', $builder->toSql());\n        $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereMorphedToCollectionWithDifferentModels()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelFarRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $thirdRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $thirdRelatedModel->id = 3;\n\n        $builder = $model->whereMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)) or (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());\n    }\n\n    public function testWhereMorphedToNull()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->whereMorphedTo('morph', null);\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is null', $builder->toSql());\n    }\n\n    public function testWhereNotMorphedTo()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToCollection()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $builder = $model->whereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)))', $builder->toSql());\n        $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToCollectionWithDifferentModels()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelFarRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $thirdRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $thirdRelatedModel->id = 3;\n\n        $builder = $model->whereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)) or (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());\n    }\n\n    public function testOrWhereMorphedTo()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->where('bar', 'baz')->orWhereMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals(['baz', $relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testOrWhereMorphedToCollection()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $builder = $model->where('bar', 'baz')->orWhereMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)))', $builder->toSql());\n        $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testOrWhereMorphedToCollectionWithDifferentModels()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelFarRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $thirdRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $thirdRelatedModel->id = 3;\n\n        $builder = $model->where('bar', 'baz')->orWhereMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)) or (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());\n    }\n\n    public function testOrWhereMorphedToNull()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->where('bar', 'baz')->orWhereMorphedTo('morph', null);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or \"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is null', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testOrWhereNotMorphedTo()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals(['baz', $relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testOrWhereNotMorphedToCollection()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel]));\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)))', $builder->toSql());\n        $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testOrWhereNotMorphedToCollectionWithDifferentModels()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $firstRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $firstRelatedModel->id = 1;\n\n        $secondRelatedModel = new EloquentBuilderTestModelFarRelatedStub;\n        $secondRelatedModel->id = 2;\n\n        $thirdRelatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $thirdRelatedModel->id = 3;\n\n        $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?, ?)) or (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings());\n    }\n\n    public function testWhereMorphedToClass()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->whereMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ?', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToClass()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->whereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ?)', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testOrWhereMorphedToClass()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->where('bar', 'baz')->orWhereMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or \"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ?', $builder->toSql());\n        $this->assertEquals(['baz', EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testOrWhereNotMorphedToClass()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"bar\" = ? or not (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ?)', $builder->toSql());\n        $this->assertEquals(['baz', EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToWithSQLite()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToClassWithSQLite()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'SQLite');\n\n        $builder = $model->whereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is ?)', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToWithMySQL()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'MySql');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from `eloquent_builder_test_model_parent_stubs` where not ((`eloquent_builder_test_model_parent_stubs`.`morph_type` <=> ? and `eloquent_builder_test_model_parent_stubs`.`morph_id` in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToClassWithMySQL()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'MySql');\n\n        $builder = $model->whereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from `eloquent_builder_test_model_parent_stubs` where not (`eloquent_builder_test_model_parent_stubs`.`morph_type` <=> ?)', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToWithPostgres()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'Postgres');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not ((\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ? and \"eloquent_builder_test_model_parent_stubs\".\"morph_id\" in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToClassWithPostgres()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'Postgres');\n\n        $builder = $model->whereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where not (\"eloquent_builder_test_model_parent_stubs\".\"morph_type\" is not distinct from ?)', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToWithSqlServer()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'SqlServer');\n\n        $relatedModel = new EloquentBuilderTestModelCloseRelatedStub;\n        $relatedModel->id = 1;\n\n        $builder = $model->whereNotMorphedTo('morph', $relatedModel);\n\n        $this->assertSame('select * from [eloquent_builder_test_model_parent_stubs] where not ((exists (select [eloquent_builder_test_model_parent_stubs].[morph_type] intersect select ?) and [eloquent_builder_test_model_parent_stubs].[morph_id] in (?)))', $builder->toSql());\n        $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings());\n    }\n\n    public function testWhereNotMorphedToClassWithSqlServer()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, 'SqlServer');\n\n        $builder = $model->whereNotMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from [eloquent_builder_test_model_parent_stubs] where not (exists (select [eloquent_builder_test_model_parent_stubs].[morph_type] intersect select ?))', $builder->toSql());\n        $this->assertEquals([EloquentBuilderTestModelCloseRelatedStub::class], $builder->getBindings());\n    }\n\n    public function testWhereMorphedToAlias()\n    {\n        $model = new EloquentBuilderTestModelParentStub;\n        $this->mockConnectionForModel($model, '');\n\n        Relation::morphMap([\n            'alias' => EloquentBuilderTestModelCloseRelatedStub::class,\n        ]);\n\n        $builder = $model->whereMorphedTo('morph', EloquentBuilderTestModelCloseRelatedStub::class);\n\n        $this->assertSame('select * from \"eloquent_builder_test_model_parent_stubs\" where \"eloquent_builder_test_model_parent_stubs\".\"morph_type\" = ?', $builder->toSql());\n        $this->assertEquals(['alias'], $builder->getBindings());\n\n        Relation::morphMap([], false);\n    }\n\n    public function testWhereKeyMethodWithInt()\n    {\n        $model = $this->getMockModel();\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $int = 1;\n\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', $int);\n\n        $builder->whereKey($int);\n    }\n\n    public function testWhereKeyMethodWithStringZero()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $int = 0;\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', (string) $int);\n\n        $builder->whereKey($int);\n    }\n\n    public function testWhereKeyMethodWithStringNull()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', m::on(function ($argument) {\n            return $argument === null;\n        }));\n\n        $builder->whereKey(null);\n    }\n\n    public function testWhereKeyMethodWithArray()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $array = [1, 2, 3];\n\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with($keyName, $array);\n\n        $builder->whereKey($array);\n    }\n\n    public function testWhereKeyMethodWithCollection()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $collection = new Collection([1, 2, 3]);\n\n        $builder->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with($keyName, $collection);\n\n        $builder->whereKey($collection);\n    }\n\n    public function testWhereKeyMethodWithModel()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '=', m::on(function ($argument) {\n            return $argument === '1';\n        }));\n\n        $builder->whereKey(new class extends Model\n        {\n            protected $attributes = ['id' => 1];\n        });\n    }\n\n    public function testWhereKeyNotMethodWithStringZero()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $int = 0;\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', (string) $int);\n\n        $builder->whereKeyNot($int);\n    }\n\n    public function testWhereKeyNotMethodWithStringNull()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', m::on(function ($argument) {\n            return $argument === null;\n        }));\n\n        $builder->whereKeyNot(null);\n    }\n\n    public function testWhereKeyNotMethodWithInt()\n    {\n        $model = $this->getMockModel();\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $int = 1;\n\n        $model->shouldReceive('getKeyType')->once()->andReturn('int');\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', $int);\n\n        $builder->whereKeyNot($int);\n    }\n\n    public function testWhereKeyNotMethodWithArray()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $array = [1, 2, 3];\n\n        $builder->getQuery()->shouldReceive('whereIntegerNotInRaw')->once()->with($keyName, $array);\n\n        $builder->whereKeyNot($array);\n    }\n\n    public function testWhereKeyNotMethodWithCollection()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getKeyType')->andReturn('int');\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $collection = new Collection([1, 2, 3]);\n\n        $builder->getQuery()->shouldReceive('whereIntegerNotInRaw')->once()->with($keyName, $collection);\n\n        $builder->whereKeyNot($collection);\n    }\n\n    public function testWhereKeyNotMethodWithModel()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', m::on(function ($argument) {\n            return $argument === '1';\n        }));\n\n        $builder->whereKeyNot(new class extends Model\n        {\n            protected $attributes = ['id' => 1];\n        });\n    }\n\n    public function testExceptMethodWithModel()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('where')->once()->with($keyName, '!=', m::on(function ($argument) {\n            return $argument === '1';\n        }));\n\n        $builder->except(new class extends Model\n        {\n            protected $attributes = ['id' => 1];\n        });\n    }\n\n    public function testExceptMethodWithCollectionOfModel()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('whereNotIn')->once()->with($keyName, m::on(function ($argument) {\n            return $argument === [1, 2];\n        }));\n\n        $models = new Collection([\n            new class extends Model\n            {\n                protected $attributes = ['id' => 1];\n            },\n            new class extends Model\n            {\n                protected $attributes = ['id' => 2];\n            },\n        ]);\n\n        $builder->except($models);\n    }\n\n    public function testExceptMethodWithArrayOfModel()\n    {\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder = $this->getBuilder()->setModel($model);\n        $keyName = $model->getQualifiedKeyName();\n\n        $builder->getQuery()->shouldReceive('whereNotIn')->once()->with($keyName, m::on(function ($argument) {\n            return $argument === [1, 2];\n        }));\n\n        $models = [\n            new class extends Model\n            {\n                protected $attributes = ['id' => 1];\n            },\n            new class extends Model\n            {\n                protected $attributes = ['id' => 2];\n            },\n        ];\n\n        $builder->except($models);\n    }\n\n    public function testWhereIn()\n    {\n        $model = new EloquentBuilderTestNestedStub;\n        $this->mockConnectionForModel($model, '');\n        $query = $model->newQuery()->withoutGlobalScopes()->whereIn('foo', $model->newQuery()->select('id'));\n        $expected = 'select * from \"table\" where \"foo\" in (select \"id\" from \"table\" where \"table\".\"deleted_at\" is null)';\n        $this->assertEquals($expected, $query->toSql());\n    }\n\n    public function testLatestWithoutColumnWithCreatedAt()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getCreatedAtColumn')->andReturn('foo');\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('latest')->once()->with('foo');\n\n        $builder->latest();\n    }\n\n    public function testLatestWithoutColumnWithoutCreatedAt()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getCreatedAtColumn')->andReturn(null);\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('latest')->once()->with('created_at');\n\n        $builder->latest();\n    }\n\n    public function testLatestWithColumn()\n    {\n        $model = $this->getMockModel();\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('latest')->once()->with('foo');\n\n        $builder->latest('foo');\n    }\n\n    public function testOldestWithoutColumnWithCreatedAt()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getCreatedAtColumn')->andReturn('foo');\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('oldest')->once()->with('foo');\n\n        $builder->oldest();\n    }\n\n    public function testOldestWithoutColumnWithoutCreatedAt()\n    {\n        $model = $this->getMockModel();\n        $model->shouldReceive('getCreatedAtColumn')->andReturn(null);\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('oldest')->once()->with('created_at');\n\n        $builder->oldest();\n    }\n\n    public function testOldestWithColumn()\n    {\n        $model = $this->getMockModel();\n        $builder = $this->getBuilder()->setModel($model);\n\n        $builder->getQuery()->shouldReceive('oldest')->once()->with('foo');\n\n        $builder->oldest('foo');\n    }\n\n    public function testUpdate()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" set \"foo\" = ?, \"table\".\"updated_at\" = ?', ['bar', $now])->andReturn(1);\n\n        $result = $builder->update(['foo' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateWithTimestampValue()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" set \"foo\" = ?, \"table\".\"updated_at\" = ?', ['bar', null])->andReturn(1);\n\n        $result = $builder->update(['foo' => 'bar', 'updated_at' => null]);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateWithQualifiedTimestampValue()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" set \"table\".\"foo\" = ?, \"table\".\"updated_at\" = ?', ['bar', null])->andReturn(1);\n\n        $result = $builder->update(['table.foo' => 'bar', 'table.updated_at' => null]);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateWithoutTimestamp()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubWithoutTimestamp;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" set \"foo\" = ?', ['bar'])->andReturn(1);\n\n        $result = $builder->update(['foo' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateWithAlias()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" as \"alias\" set \"foo\" = ?, \"alias\".\"updated_at\" = ?', ['bar', $now])->andReturn(1);\n\n        $result = $builder->from('table as alias')->update(['foo' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateWithAliasWithQualifiedTimestampValue()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStub;\n        $this->mockConnectionForModel($model, '');\n        $builder->setModel($model);\n        $builder->getConnection()->shouldReceive('update')->once()\n            ->with('update \"table\" as \"alias\" set \"foo\" = ?, \"alias\".\"updated_at\" = ?', ['bar', null])->andReturn(1);\n\n        $result = $builder->from('table as alias')->update(['foo' => 'bar', 'alias.updated_at' => null]);\n        $this->assertEquals(1, $result);\n\n        Carbon::setTestNow(null);\n    }\n\n    public function testUpsert()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('foo_table')->andReturn('foo_table');\n        $query->from = 'foo_table';\n\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder->setModel($model);\n\n        $query->shouldReceive('upsert')->once()\n            ->with([\n                ['email' => 'foo', 'name' => 'bar', 'updated_at' => $now, 'created_at' => $now],\n                ['name' => 'bar2', 'email' => 'foo2', 'updated_at' => $now, 'created_at' => $now],\n            ], ['email'], ['email', 'name', 'updated_at'])->andReturn(2);\n\n        $result = $builder->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], ['email']);\n\n        $this->assertEquals(2, $result);\n    }\n\n    public function testTouch()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('foo_table')->andReturn('foo_table');\n        $query->from = 'foo_table';\n\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder->setModel($model);\n\n        $query->shouldReceive('update')->once()->with(['updated_at' => $now])->andReturn(2);\n\n        $result = $builder->touch();\n\n        $this->assertEquals(2, $result);\n    }\n\n    public function testTouchWithCustomColumn()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('foo_table')->andReturn('foo_table');\n        $query->from = 'foo_table';\n\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder->setModel($model);\n\n        $query->shouldReceive('update')->once()->with(['published_at' => $now])->andReturn(2);\n\n        $result = $builder->touch('published_at');\n\n        $this->assertEquals(2, $result);\n    }\n\n    public function testTouchWithMultipleColumns()\n    {\n        Carbon::setTestNow($now = '2017-10-10 10:10:10');\n\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('foo_table')->andReturn('foo_table');\n        $query->from = 'foo_table';\n\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubStringPrimaryKey;\n        $builder->setModel($model);\n\n        $query->shouldReceive('update')->once()->with(['published_at' => $now, 'verified_at' => $now])->andReturn(2);\n\n        $result = $builder->touch(['published_at', 'verified_at']);\n\n        $this->assertEquals(2, $result);\n    }\n\n    public function testTouchWithoutUpdatedAtColumn()\n    {\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('table')->andReturn('table');\n        $query->from = 'table';\n\n        $builder = new Builder($query);\n        $model = new EloquentBuilderTestStubWithoutTimestamp;\n        $builder->setModel($model);\n\n        $query->shouldNotReceive('update');\n\n        $result = $builder->touch();\n\n        $this->assertFalse($result);\n    }\n\n    public function testWithCastsMethod()\n    {\n        $builder = new Builder($this->getMockQueryBuilder());\n        $model = $this->getMockModel();\n        $builder->setModel($model);\n\n        $model->shouldReceive('mergeCasts')->with(['foo' => 'bar'])->once();\n        $builder->withCasts(['foo' => 'bar']);\n    }\n\n    public function testClone()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = new Builder($query);\n        $builder->select('*')->from('users');\n        $clone = $builder->clone()->where('email', 'foo');\n\n        $this->assertNotSame($builder, $clone);\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $clone->toSql());\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModel()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $query = new BaseBuilder($connection, new Grammar($connection), m::mock(Processor::class));\n        $builder = (new Builder($query))->setModel(new EloquentBuilderTestStub);\n        $builder->select('*')->from('users');\n\n        $onCloneCallbackCalledCount = 0;\n\n        $onCloneQuery = null;\n\n        $builder->onClone(function (Builder $query) use (&$onCloneCallbackCalledCount, &$onCloneQuery) {\n            $onCloneCallbackCalledCount++;\n\n            $onCloneQuery = $query;\n        });\n\n        $clone = $builder->clone()->where('email', 'foo');\n\n        $this->assertNotSame($builder, $clone);\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $clone->toSql());\n\n        $this->assertSame(1, $onCloneCallbackCalledCount);\n        $this->assertSame($onCloneQuery, $clone);\n    }\n\n    public function testToRawSql()\n    {\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('toRawSql')\n            ->andReturn('select * from \"users\" where \"email\" = \\'foo\\'');\n\n        $builder = new Builder($query);\n\n        $this->assertSame('select * from \"users\" where \"email\" = \\'foo\\'', $builder->toRawSql());\n    }\n\n    public function testPassthruMethodsCallsAreNotCaseSensitive()\n    {\n        $query = m::mock(BaseBuilder::class);\n\n        $mockResponse = 'select 1';\n        $query\n            ->shouldReceive('toRawSql')\n            ->andReturn($mockResponse)\n            ->times(3);\n\n        $builder = new Builder($query);\n\n        $this->assertSame('select 1', $builder->TORAWSQL());\n        $this->assertSame('select 1', $builder->toRawSql());\n        $this->assertSame('select 1', $builder->toRawSQL());\n    }\n\n    public function testPassthruArrayElementsMustAllBeLowercase()\n    {\n        $builder = new class(m::mock(BaseBuilder::class)) extends Builder\n        {\n            // expose protected member for test\n            public function getPassthru(): array\n            {\n                return $this->passthru;\n            }\n        };\n\n        $passthru = $builder->getPassthru();\n\n        foreach ($passthru as $method) {\n            $lowercaseMethod = strtolower($method);\n\n            $this->assertSame(\n                $lowercaseMethod,\n                $method,\n                'Eloquent\\\\Builder relies on lowercase method names in $passthru array to correctly mimic PHP case-insensitivity on method dispatch.'.\n                    'If you are adding a new method to the $passthru array, make sure the name is lowercased.'\n            );\n        }\n    }\n\n    public function testPipeCallback()\n    {\n        $query = new Builder(new BaseBuilder(\n            $connection = new Connection(new PDO('sqlite::memory:')),\n            new Grammar($connection),\n            new Processor,\n        ));\n\n        $result = $query->pipe(fn (Builder $query) => 5);\n        $this->assertSame(5, $result);\n\n        $result = $query->pipe(fn (Builder $query) => null);\n        $this->assertSame($query, $result);\n\n        $result = $query->pipe(function (Builder $query) {\n            //\n        });\n        $this->assertSame($query, $result);\n\n        $this->assertCount(0, $query->getQuery()->wheres);\n        $result = $query->pipe(fn (Builder $query) => $query->where('foo', 'bar'));\n        $this->assertSame($query, $result);\n        $this->assertCount(1, $query->getQuery()->wheres);\n    }\n\n    protected function mockConnectionForModel($model, $database)\n    {\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$database.'Grammar';\n        $processorClass = 'Illuminate\\Database\\Query\\Processors\\\\'.$database.'Processor';\n        $processor = new $processorClass;\n        $connection = m::mock(Connection::class, ['getPostProcessor' => $processor]);\n        $grammar = new $grammarClass($connection);\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new BaseBuilder($connection, $grammar, $processor);\n        });\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $connection]);\n        $class = get_class($model);\n        $class::setConnectionResolver($resolver);\n\n        return $connection;\n    }\n\n    protected function getBuilder()\n    {\n        return new Builder($this->getMockQueryBuilder());\n    }\n\n    protected function getMockModel()\n    {\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getKeyName')->andReturn('foo');\n        $model->shouldReceive('getTable')->andReturn('foo_table');\n        $model->shouldReceive('getQualifiedKeyName')->andReturn('foo_table.foo');\n\n        return $model;\n    }\n\n    protected function getMockQueryBuilder()\n    {\n        $query = m::mock(BaseBuilder::class);\n        $query->shouldReceive('from')->with('foo_table');\n\n        return $query;\n    }\n}\n\nclass EloquentBuilderTestStub extends Model\n{\n    protected $table = 'table';\n}\n\nclass EloquentBuilderTestScopeStub extends Model\n{\n    public function scopeApproved($query)\n    {\n        $query->where('foo', 'bar');\n    }\n}\n\nclass EloquentBuilderTestDynamicScopeStub extends Model\n{\n    public function scopeDynamic($query, $foo = 'foo', $bar = 'bar')\n    {\n        $query->where($foo, $bar);\n    }\n}\n\nclass EloquentBuilderTestHigherOrderWhereScopeStub extends Model\n{\n    protected $table = 'table';\n\n    public function scopeOne($query)\n    {\n        $query->where('one', 'foo');\n    }\n\n    public function scopeTwo($query)\n    {\n        $query->where('two', 'bar');\n    }\n\n    public function scopeThree($query)\n    {\n        $query->where('three', 'baz');\n    }\n}\n\nclass EloquentBuilderTestNestedStub extends Model\n{\n    protected $table = 'table';\n    use SoftDeletes;\n\n    public function scopeEmpty($query)\n    {\n        return $query;\n    }\n}\n\nclass EloquentBuilderTestPluckStub\n{\n    protected $attributes;\n\n    public function __construct($attributes)\n    {\n        $this->attributes = $attributes;\n    }\n\n    public function __get($key)\n    {\n        return 'foo_'.$this->attributes[$key];\n    }\n}\n\nclass EloquentBuilderTestPluckDatesStub extends Model\n{\n    protected $attributes;\n\n    public function __construct($attributes)\n    {\n        $this->attributes = $attributes;\n    }\n\n    protected function asDateTime($value)\n    {\n        return 'date_'.$value;\n    }\n}\n\nclass EloquentBuilderTestModelParentStub extends Model\n{\n    public function foo()\n    {\n        return $this->belongsTo(EloquentBuilderTestModelCloseRelatedStub::class);\n    }\n\n    public function address()\n    {\n        return $this->belongsTo(EloquentBuilderTestModelCloseRelatedStub::class, 'foo_id');\n    }\n\n    public function activeFoo()\n    {\n        return $this->belongsTo(EloquentBuilderTestModelCloseRelatedStub::class, 'foo_id')->where('active', true);\n    }\n\n    public function roles()\n    {\n        return $this->belongsToMany(\n            EloquentBuilderTestModelFarRelatedStub::class,\n            'user_role',\n            'self_id',\n            'related_id'\n        );\n    }\n\n    public function morph()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass EloquentBuilderTestModelCloseRelatedStub extends Model\n{\n    public function bar()\n    {\n        return $this->hasMany(EloquentBuilderTestModelFarRelatedStub::class);\n    }\n\n    public function baz()\n    {\n        return $this->hasMany(EloquentBuilderTestModelFarRelatedStub::class);\n    }\n\n    public function bam()\n    {\n        return $this->hasMany(EloquentBuilderTestModelOtherFarRelatedStub::class);\n    }\n}\n\nclass EloquentBuilderTestModelFarRelatedStub extends Model\n{\n    public function roles()\n    {\n        return $this->belongsToMany(\n            EloquentBuilderTestModelParentStub::class,\n            'user_role',\n            'related_id',\n            'self_id',\n        );\n    }\n\n    public function baz()\n    {\n        return $this->belongsTo(EloquentBuilderTestModelCloseRelatedStub::class);\n    }\n}\n\nclass EloquentBuilderTestModelOtherFarRelatedStub extends Model\n{\n    public function roles()\n    {\n        return $this->belongsToMany(\n            EloquentBuilderTestModelParentStub::class,\n            'user_role',\n            'related_id',\n            'self_id',\n        );\n    }\n\n    public function baz()\n    {\n        return $this->belongsTo(EloquentBuilderTestModelCloseRelatedStub::class);\n    }\n}\n\nclass EloquentBuilderTestModelSelfRelatedStub extends Model\n{\n    protected $table = 'self_related_stubs';\n\n    public function parentFoo()\n    {\n        return $this->belongsTo(self::class, 'parent_id', 'id', 'parent');\n    }\n\n    public function childFoo()\n    {\n        return $this->hasOne(self::class, 'parent_id', 'id');\n    }\n\n    public function childFoos()\n    {\n        return $this->hasMany(self::class, 'parent_id', 'id', 'children');\n    }\n\n    public function parentBars()\n    {\n        return $this->belongsToMany(self::class, 'self_pivot', 'child_id', 'parent_id', 'parent_bars');\n    }\n\n    public function childBars()\n    {\n        return $this->belongsToMany(self::class, 'self_pivot', 'parent_id', 'child_id', 'child_bars');\n    }\n\n    public function bazes()\n    {\n        return $this->hasMany(EloquentBuilderTestModelFarRelatedStub::class, 'foreign_key', 'id', 'bar');\n    }\n}\n\nclass EloquentBuilderTestStubWithoutTimestamp extends Model\n{\n    const UPDATED_AT = null;\n\n    protected $table = 'table';\n}\n\nclass EloquentBuilderTestStubStringPrimaryKey extends Model\n{\n    public $incrementing = false;\n\n    protected $table = 'foo_table';\n\n    protected $keyType = 'string';\n}\n\nclass EloquentBuilderTestWhereBelongsToStub extends Model\n{\n    protected $fillable = [\n        'id',\n        'parent_id',\n    ];\n\n    public function eloquentBuilderTestWhereBelongsToStub()\n    {\n        return $this->belongsTo(self::class, 'parent_id', 'id', 'parent');\n    }\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class, 'parent_id', 'id', 'parent');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentCollectionQueueableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentCollectionQueueableTest extends TestCase\n{\n    public function testSerializesPivotsEntitiesId()\n    {\n        $spy = m::spy(Pivot::class);\n\n        $c = new Collection([$spy]);\n\n        $c->getQueueableIds();\n\n        $spy->shouldHaveReceived()\n            ->getQueueableId()\n            ->once();\n    }\n\n    public function testSerializesModelEntitiesById()\n    {\n        $spy = m::spy(Model::class);\n\n        $c = new Collection([$spy]);\n\n        $c->getQueueableIds();\n\n        $spy->shouldHaveReceived()\n            ->getQueueableId()\n            ->once();\n    }\n\n    /**\n     * @throws \\Exception\n     */\n    public function testJsonSerializationOfCollectionQueueableIdsWorks()\n    {\n        // When the ID of a Model is binary instead of int or string, the Collection\n        // serialization + JSON encoding breaks because of UTF-8 issues. Encoding\n        // of a QueueableCollection must favor QueueableEntity::queueableId().\n        $mock = m::mock(Model::class, [\n            'getKey' => random_bytes(10),\n            'getQueueableId' => 'mocked',\n        ]);\n\n        $c = new Collection([$mock]);\n\n        $payload = [\n            'ids' => $c->getQueueableIds(),\n        ];\n\n        $this->assertNotFalse(\n            json_encode($payload),\n            'EloquentCollection is not using the QueueableEntity::getQueueableId() method.'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse LogicException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nuse function Orchestra\\Testbench\\phpunit_version_compare;\n\nclass DatabaseEloquentCollectionTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n        });\n\n        $this->schema()->create('articles', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->string('title');\n        });\n\n        $this->schema()->create('comments', function ($table) {\n            $table->increments('id');\n            $table->integer('article_id');\n            $table->string('content');\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('articles');\n        $this->schema()->drop('comments');\n\n        parent::tearDown();\n    }\n\n    public function testAddingItemsToCollection()\n    {\n        $c = new Collection(['foo']);\n        $c->add('bar')->add('baz');\n        $this->assertEquals(['foo', 'bar', 'baz'], $c->all());\n    }\n\n    public function testGettingMaxItemsFromCollection()\n    {\n        $c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);\n        $this->assertEquals(20, $c->max('foo'));\n    }\n\n    public function testGettingMinItemsFromCollection()\n    {\n        $c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);\n        $this->assertEquals(10, $c->min('foo'));\n    }\n\n    public function testContainsWithMultipleArguments()\n    {\n        $c = new Collection([['id' => 1], ['id' => 2]]);\n\n        $this->assertTrue($c->contains('id', 1));\n        $this->assertTrue($c->contains('id', '>=', 2));\n        $this->assertFalse($c->contains('id', '>', 2));\n\n        $this->assertFalse($c->doesntContain('id', 1));\n        $this->assertFalse($c->doesntContain('id', '>=', 2));\n        $this->assertTrue($c->doesntContain('id', '>', 2));\n    }\n\n    public function testContainsIndicatesIfModelInArray()\n    {\n        $mockModel = m::mock(Model::class);\n        $mockModel->shouldReceive('is')->with($mockModel)->andReturn(true);\n        $mockModel->shouldReceive('is')->andReturn(false);\n        $mockModel2 = m::mock(Model::class);\n        $mockModel2->shouldReceive('is')->with($mockModel2)->andReturn(true);\n        $mockModel2->shouldReceive('is')->andReturn(false);\n        $mockModel3 = m::mock(Model::class);\n        $mockModel3->shouldReceive('is')->with($mockModel3)->andReturn(true);\n        $mockModel3->shouldReceive('is')->andReturn(false);\n        $c = new Collection([$mockModel, $mockModel2]);\n\n        $this->assertTrue($c->contains($mockModel));\n        $this->assertTrue($c->contains($mockModel2));\n        $this->assertFalse($c->contains($mockModel3));\n\n        $this->assertFalse($c->doesntContain($mockModel));\n        $this->assertFalse($c->doesntContain($mockModel2));\n        $this->assertTrue($c->doesntContain($mockModel3));\n    }\n\n    public function testContainsIndicatesIfDifferentModelInArray()\n    {\n        $mockModelFoo = m::namedMock('Foo', Model::class);\n        $mockModelFoo->shouldReceive('is')->with($mockModelFoo)->andReturn(true);\n        $mockModelFoo->shouldReceive('is')->andReturn(false);\n        $mockModelBar = m::namedMock('Bar', Model::class);\n        $mockModelBar->shouldReceive('is')->with($mockModelBar)->andReturn(true);\n        $mockModelBar->shouldReceive('is')->andReturn(false);\n        $c = new Collection([$mockModelFoo]);\n\n        $this->assertTrue($c->contains($mockModelFoo));\n        $this->assertFalse($c->contains($mockModelBar));\n\n        $this->assertFalse($c->doesntContain($mockModelFoo));\n        $this->assertTrue($c->doesntContain($mockModelBar));\n    }\n\n    public function testContainsIndicatesIfKeyedModelInArray()\n    {\n        $mockModel = m::mock(Model::class);\n        $mockModel->shouldReceive('getKey')->andReturn('1');\n        $c = new Collection([$mockModel]);\n        $mockModel2 = m::mock(Model::class);\n        $mockModel2->shouldReceive('getKey')->andReturn('2');\n        $c->add($mockModel2);\n\n        $this->assertTrue($c->contains(1));\n        $this->assertTrue($c->contains(2));\n        $this->assertFalse($c->contains(3));\n\n        $this->assertFalse($c->doesntContain(1));\n        $this->assertFalse($c->doesntContain(2));\n        $this->assertTrue($c->doesntContain(3));\n    }\n\n    public function testContainsKeyAndValueIndicatesIfModelInArray()\n    {\n        $mockModel1 = m::mock(Model::class);\n        $mockModel1->shouldReceive('offsetExists')->with('name')->andReturn(true);\n        $mockModel1->shouldReceive('offsetGet')->with('name')->andReturn('Taylor');\n        $mockModel2 = m::mock(Model::class);\n        $mockModel2->shouldReceive('offsetExists')->andReturn(true);\n        $mockModel2->shouldReceive('offsetGet')->with('name')->andReturn('Abigail');\n        $c = new Collection([$mockModel1, $mockModel2]);\n\n        $this->assertTrue($c->contains('name', 'Taylor'));\n        $this->assertTrue($c->contains('name', 'Abigail'));\n        $this->assertFalse($c->contains('name', 'Dayle'));\n\n        $this->assertFalse($c->doesntContain('name', 'Taylor'));\n        $this->assertFalse($c->doesntContain('name', 'Abigail'));\n        $this->assertTrue($c->doesntContain('name', 'Dayle'));\n    }\n\n    public function testContainsClosureIndicatesIfModelInArray()\n    {\n        $mockModel1 = m::mock(Model::class);\n        $mockModel1->shouldReceive('getKey')->andReturn(1);\n        $mockModel2 = m::mock(Model::class);\n        $mockModel2->shouldReceive('getKey')->andReturn(2);\n        $c = new Collection([$mockModel1, $mockModel2]);\n\n        $this->assertTrue($c->contains(function ($model) {\n            return $model->getKey() < 2;\n        }));\n        $this->assertFalse($c->contains(function ($model) {\n            return $model->getKey() > 2;\n        }));\n\n        $this->assertFalse($c->doesntContain(function ($model) {\n            return $model->getKey() < 2;\n        }));\n        $this->assertTrue($c->doesntContain(function ($model) {\n            return $model->getKey() > 2;\n        }));\n    }\n\n    public function testFindMethodFindsModelById()\n    {\n        $mockModel = m::mock(Model::class);\n        $mockModel->shouldReceive('getKey')->andReturn(1);\n        $c = new Collection([$mockModel]);\n\n        $this->assertSame($mockModel, $c->find(1));\n        $this->assertSame('taylor', $c->find(2, 'taylor'));\n    }\n\n    public function testFindMethodFindsManyModelsById()\n    {\n        $model1 = (new TestEloquentCollectionModel)->forceFill(['id' => 1]);\n        $model2 = (new TestEloquentCollectionModel)->forceFill(['id' => 2]);\n        $model3 = (new TestEloquentCollectionModel)->forceFill(['id' => 3]);\n\n        $c = new Collection;\n        $this->assertInstanceOf(Collection::class, $c->find([]));\n        $this->assertCount(0, $c->find([1]));\n\n        $c->push($model1);\n        $this->assertCount(1, $c->find([1]));\n        $this->assertEquals(1, $c->find([1])->first()->id);\n        $this->assertCount(0, $c->find([2]));\n\n        $c->push($model2)->push($model3);\n        $this->assertCount(1, $c->find([2]));\n        $this->assertEquals(2, $c->find([2])->first()->id);\n        $this->assertCount(2, $c->find([2, 3, 4]));\n        $this->assertCount(2, $c->find(collect([2, 3, 4])));\n        $this->assertEquals([2, 3], $c->find(collect([2, 3, 4]))->pluck('id')->all());\n        $this->assertEquals([2, 3], $c->find([2, 3, 4])->pluck('id')->all());\n    }\n\n    public function testFindOrFailFindsModelById()\n    {\n        $mockModel = m::mock(Model::class);\n        $mockModel->shouldReceive('getKey')->andReturn(1);\n        $c = new Collection([$mockModel]);\n\n        $this->assertSame($mockModel, $c->findOrFail(1));\n    }\n\n    public function testFindOrFailFindsManyModelsById()\n    {\n        $model1 = (new TestEloquentCollectionModel)->forceFill(['id' => 1]);\n        $model2 = (new TestEloquentCollectionModel)->forceFill(['id' => 2]);\n\n        $c = new Collection;\n        $this->assertInstanceOf(Collection::class, $c->findOrFail([]));\n        $this->assertCount(0, $c->findOrFail([]));\n\n        $c->push($model1);\n        $this->assertCount(1, $c->findOrFail([1]));\n        $this->assertEquals(1, $c->findOrFail([1])->first()->id);\n\n        $c->push($model2);\n        $this->assertCount(2, $c->findOrFail([1, 2]));\n\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\TestEloquentCollectionModel] 3');\n\n        $c->findOrFail([1, 2, 3]);\n    }\n\n    public function testFindOrFailThrowsExceptionWithMessageWhenOtherModelsArePresent()\n    {\n        $model = (new TestEloquentCollectionModel)->forceFill(['id' => 1]);\n\n        $c = new Collection([$model]);\n\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\TestEloquentCollectionModel] 2');\n\n        $c->findOrFail(2);\n    }\n\n    public function testFindOrFailThrowsExceptionWithoutMessageWhenOtherModelsAreNotPresent()\n    {\n        $c = new Collection();\n\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('');\n\n        $c->findOrFail(1);\n    }\n\n    public function testLoadMethodEagerLoadsGivenRelationships()\n    {\n        $c = $this->getMockBuilder(Collection::class)->onlyMethods(['first'])->setConstructorArgs([['foo']])->getMock();\n        $mockItem = m::mock(stdClass::class);\n        $c->expects($this->once())->method('first')->willReturn($mockItem);\n        $mockItem->shouldReceive('newQueryWithoutRelationships')->once()->andReturn($mockItem);\n        $mockItem->shouldReceive('with')->with(['bar', 'baz'])->andReturn($mockItem);\n        $mockItem->shouldReceive('eagerLoadRelations')->once()->with(['foo'])->andReturn(['results']);\n        $c->load('bar', 'baz');\n\n        $this->assertEquals(['results'], $c->all());\n    }\n\n    public function testCollectionDictionaryReturnsModelKeys()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c = new Collection([$one, $two, $three]);\n\n        $this->assertEquals([1, 2, 3], $c->modelKeys());\n    }\n\n    public function testCollectionMergesWithGivenCollection()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c1 = new Collection([$one, $two]);\n        $c2 = new Collection([$two, $three]);\n\n        $this->assertEquals(new Collection([$one, $two, $three]), $c1->merge($c2));\n    }\n\n    public function testMap()\n    {\n        $one = m::mock(Model::class);\n        $two = m::mock(Model::class);\n\n        $c = new Collection([$one, $two]);\n\n        $cAfterMap = $c->map(function ($item) {\n            return $item;\n        });\n\n        $this->assertEquals($c->all(), $cAfterMap->all());\n        $this->assertInstanceOf(Collection::class, $cAfterMap);\n    }\n\n    public function testMappingToNonModelsReturnsABaseCollection()\n    {\n        $one = m::mock(Model::class);\n        $two = m::mock(Model::class);\n\n        $c = (new Collection([$one, $two]))->map(function ($item) {\n            return 'not-a-model';\n        });\n\n        $this->assertEquals(BaseCollection::class, get_class($c));\n    }\n\n    public function testMapWithKeys()\n    {\n        $one = m::mock(Model::class);\n        $two = m::mock(Model::class);\n\n        $c = new Collection([$one, $two]);\n\n        $key = 0;\n        $cAfterMap = $c->mapWithKeys(function ($item) use (&$key) {\n            return [$key++ => $item];\n        });\n\n        $this->assertEquals($c->all(), $cAfterMap->all());\n        $this->assertInstanceOf(Collection::class, $cAfterMap);\n    }\n\n    public function testMapWithKeysToNonModelsReturnsABaseCollection()\n    {\n        $one = m::mock(Model::class);\n        $two = m::mock(Model::class);\n\n        $key = 0;\n        $c = (new Collection([$one, $two]))->mapWithKeys(function ($item) use (&$key) {\n            return [$key++ => 'not-a-model'];\n        });\n\n        $this->assertEquals(BaseCollection::class, get_class($c));\n    }\n\n    public function testCollectionDiffsWithGivenCollection()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c1 = new Collection([$one, $two]);\n        $c2 = new Collection([$two, $three]);\n\n        $this->assertEquals(new Collection([$one]), $c1->diff($c2));\n    }\n\n    public function testCollectionReturnsDuplicateBasedOnlyOnKeys()\n    {\n        $one = new TestEloquentCollectionModel;\n        $two = new TestEloquentCollectionModel;\n        $three = new TestEloquentCollectionModel;\n        $four = new TestEloquentCollectionModel;\n        $one->id = 1;\n        $one->someAttribute = '1';\n        $two->id = 1;\n        $two->someAttribute = '2';\n        $three->id = 1;\n        $three->someAttribute = '3';\n        $four->id = 2;\n        $four->someAttribute = '4';\n\n        $duplicates = Collection::make([$one, $two, $three, $four])->duplicates()->all();\n        $this->assertSame([1 => $two, 2 => $three], $duplicates);\n\n        $duplicates = Collection::make([$one, $two, $three, $four])->duplicatesStrict()->all();\n        $this->assertSame([1 => $two, 2 => $three], $duplicates);\n    }\n\n    public function testCollectionIntersectWithNull()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c1 = new Collection([$one, $two, $three]);\n\n        $this->assertEquals([], $c1->intersect(null)->all());\n    }\n\n    public function testCollectionIntersectsWithGivenCollection()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c1 = new Collection([$one, $two]);\n        $c2 = new Collection([$two, $three]);\n\n        $this->assertEquals(new Collection([$two]), $c1->intersect($c2));\n    }\n\n    public function testCollectionReturnsUniqueItems()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $c = new Collection([$one, $two, $two]);\n\n        $this->assertEquals(new Collection([$one, $two]), $c->unique());\n    }\n\n    public function testCollectionReturnsUniqueStrictBasedOnKeysOnly()\n    {\n        $one = new TestEloquentCollectionModel;\n        $two = new TestEloquentCollectionModel;\n        $three = new TestEloquentCollectionModel;\n        $four = new TestEloquentCollectionModel;\n        $one->id = 1;\n        $one->someAttribute = '1';\n        $two->id = 1;\n        $two->someAttribute = '2';\n        $three->id = 1;\n        $three->someAttribute = '3';\n        $four->id = 2;\n        $four->someAttribute = '4';\n\n        $uniques = Collection::make([$one, $two, $three, $four])->unique()->all();\n        $this->assertSame([$three, $four], $uniques);\n\n        $uniques = Collection::make([$one, $two, $three, $four])->unique(null, true)->all();\n        $this->assertSame([$three, $four], $uniques);\n    }\n\n    public function testOnlyReturnsCollectionWithGivenModelKeys()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c = new Collection([$one, $two, $three]);\n\n        $this->assertEquals($c, $c->only(null));\n        $this->assertEquals(new Collection([$one]), $c->only(1));\n        $this->assertEquals(new Collection([$two, $three]), $c->only([2, 3]));\n    }\n\n    public function testExceptReturnsCollectionWithoutGivenModelKeys()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $three = m::mock(Model::class);\n        $three->shouldReceive('getKey')->andReturn(3);\n\n        $c = new Collection([$one, $two, $three]);\n\n        $this->assertEquals($c, $c->except(null));\n        $this->assertEquals(new Collection([$one, $three]), $c->except(2));\n        $this->assertEquals(new Collection([$one]), $c->except([2, 3]));\n    }\n\n    public function testMakeHiddenAddsHiddenOnEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->makeHidden(['visible']);\n\n        $this->assertEquals(['hidden', 'visible'], $c[0]->getHidden());\n    }\n\n    public function testMakeVisibleRemovesHiddenFromEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->makeVisible(['hidden']);\n\n        $this->assertEquals([], $c[0]->getHidden());\n    }\n\n    public function testMergeHiddenAddsHiddenOnEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->mergeHidden(['merged']);\n\n        $this->assertEquals(['hidden', 'merged'], $c[0]->getHidden());\n    }\n\n    public function testMergeVisibleRemovesHiddenFromEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->mergeVisible(['merged']);\n\n        $this->assertEquals(['visible', 'merged'], $c[0]->getVisible());\n    }\n\n    public function testSetVisibleReplacesVisibleOnEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->setVisible(['hidden']);\n\n        $this->assertEquals(['hidden'], $c[0]->getVisible());\n    }\n\n    public function testSetHiddenReplacesHiddenOnEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->setHidden(['visible']);\n\n        $this->assertEquals(['visible'], $c[0]->getHidden());\n    }\n\n    public function testAppendsAddsTestOnEntireCollection()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->makeVisible('test');\n        $c = $c->append('test');\n\n        $this->assertEquals(['test' => 'test'], $c[0]->toArray());\n    }\n\n    public function testSetAppendsSetsAppendedPropertiesOnEntireCollection()\n    {\n        $c = new Collection([new EloquentAppendingTestUserModel]);\n        $c->setAppends(['other_appended_field']);\n\n        $this->assertEquals(\n            [['other_appended_field' => 'bye']],\n            $c->toArray()\n        );\n    }\n\n    public function testWithoutAppendsRemovesAppendsOnEntireCollection()\n    {\n        $this->seedData();\n        $c = EloquentAppendingTestUserModel::query()->get();\n        $this->assertEquals('hello', $c->toArray()[0]['appended_field']);\n\n        $c = $c->withoutAppends();\n        $this->assertArrayNotHasKey('appended_field', $c->toArray()[0]);\n    }\n\n    public function testNonModelRelatedMethods()\n    {\n        $a = new Collection([['foo' => 'bar'], ['foo' => 'baz']]);\n        $b = new Collection(['a', 'b', 'c']);\n        $this->assertEquals(BaseCollection::class, get_class($a->pluck('foo')));\n        $this->assertEquals(BaseCollection::class, get_class($a->keys()));\n        $this->assertEquals(BaseCollection::class, get_class($a->collapse()));\n        $this->assertEquals(BaseCollection::class, get_class($a->flatten()));\n        $this->assertEquals(BaseCollection::class, get_class($a->zip(['a', 'b'], ['c', 'd'])));\n        $this->assertEquals(BaseCollection::class, get_class($a->countBy('foo')));\n        $this->assertEquals(BaseCollection::class, get_class($b->flip()));\n        $this->assertEquals(BaseCollection::class, get_class($a->partition('foo', '=', 'bar')));\n        $this->assertEquals(BaseCollection::class, get_class($a->partition('foo', 'bar')));\n    }\n\n    public function testMakeVisibleRemovesHiddenAndIncludesVisible()\n    {\n        $c = new Collection([new TestEloquentCollectionModel]);\n        $c = $c->makeVisible('hidden');\n\n        $this->assertEquals([], $c[0]->getHidden());\n        $this->assertEquals(['visible', 'hidden'], $c[0]->getVisible());\n    }\n\n    public function testMultiply()\n    {\n        $a = new TestEloquentCollectionModel();\n        $b = new TestEloquentCollectionModel();\n\n        $c = new Collection([$a, $b]);\n\n        $this->assertEquals([], $c->multiply(-1)->all());\n        $this->assertEquals([], $c->multiply(0)->all());\n\n        $this->assertEquals([$a, $b], $c->multiply(1)->all());\n\n        $this->assertEquals([$a, $b, $a, $b, $a, $b], $c->multiply(3)->all());\n    }\n\n    public function testQueueableCollectionImplementation()\n    {\n        $c = new Collection([new TestEloquentCollectionModel, new TestEloquentCollectionModel]);\n        $this->assertEquals(TestEloquentCollectionModel::class, $c->getQueueableClass());\n    }\n\n    public function testQueueableCollectionImplementationThrowsExceptionOnMultipleModelTypes()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Queueing collections with multiple model types is not supported.');\n\n        $c = new Collection([new TestEloquentCollectionModel, (object) ['id' => 'something']]);\n        $c->getQueueableClass();\n    }\n\n    public function testQueueableRelationshipsReturnsOnlyRelationsCommonToAllModels()\n    {\n        // This is needed to prevent loading non-existing relationships on polymorphic model collections (#26126)\n        $c = new Collection([\n            new class\n            {\n                public function getQueueableRelations()\n                {\n                    return ['user'];\n                }\n            },\n            new class\n            {\n                public function getQueueableRelations()\n                {\n                    return ['user', 'comments'];\n                }\n            },\n        ]);\n\n        $this->assertEquals(['user'], $c->getQueueableRelations());\n    }\n\n    public function testQueueableRelationshipsIgnoreCollectionKeys()\n    {\n        $c = new Collection([\n            'foo' => new class\n            {\n                public function getQueueableRelations()\n                {\n                    return [];\n                }\n            },\n            'bar' => new class\n            {\n                public function getQueueableRelations()\n                {\n                    return [];\n                }\n            },\n        ]);\n\n        $this->assertEquals([], $c->getQueueableRelations());\n    }\n\n    public function testEmptyCollectionStayEmptyOnFresh()\n    {\n        $c = new Collection;\n        $this->assertEquals($c, $c->fresh());\n    }\n\n    public function testCanConvertCollectionOfModelsToEloquentQueryBuilder()\n    {\n        $one = m::mock(Model::class);\n        $one->shouldReceive('getKey')->andReturn(1);\n\n        $two = m::mock(Model::class);\n        $two->shouldReceive('getKey')->andReturn(2);\n\n        $c = new Collection([$one, $two]);\n\n        $mocBuilder = m::mock(Builder::class);\n        $one->shouldReceive('newModelQuery')->once()->andReturn($mocBuilder);\n        $mocBuilder->shouldReceive('whereKey')->once()->with($c->modelKeys())->andReturn($mocBuilder);\n        $this->assertInstanceOf(Builder::class, $c->toQuery());\n    }\n\n    public function testConvertingEmptyCollectionToQueryThrowsException()\n    {\n        $this->expectException(LogicException::class);\n\n        $c = new Collection;\n        $c->toQuery();\n    }\n\n    public function testLoadExistsShouldCastBool()\n    {\n        $this->seedData();\n        $user = EloquentTestUserModel::with('articles')->first();\n        $user->articles->loadExists('comments');\n        $commentsExists = $user->articles->pluck('comments_exists')->toArray();\n\n        if (phpunit_version_compare('11.5.0', '<')) {\n            $this->assertContainsOnly('bool', $commentsExists);\n        } else {\n            $this->assertContainsOnlyBool($commentsExists);\n        }\n    }\n\n    public function testWithNonScalarKey()\n    {\n        $fooKey = new EloquentTestKey('foo');\n        $foo = m::mock(Model::class);\n        $foo->shouldReceive('getKey')->andReturn($fooKey);\n\n        $barKey = new EloquentTestKey('bar');\n        $bar = m::mock(Model::class);\n        $bar->shouldReceive('getKey')->andReturn($barKey);\n\n        $collection = new Collection([$foo, $bar]);\n\n        $this->assertCount(1, $collection->only([$fooKey]));\n        $this->assertSame($foo, $collection->only($fooKey)->first());\n\n        $this->assertCount(1, $collection->except([$fooKey]));\n        $this->assertSame($bar, $collection->except($fooKey)->first());\n    }\n\n    public function testPluck()\n    {\n        $model1 = (new TestEloquentCollectionModel)->forceFill(['id' => 1, 'name' => 'John', 'country' => 'US']);\n        $model2 = (new TestEloquentCollectionModel)->forceFill(['id' => 2, 'name' => 'Jane', 'country' => 'NL']);\n        $model3 = (new TestEloquentCollectionModel)->forceFill(['id' => 3, 'name' => 'Taylor', 'country' => 'US']);\n\n        $c = new Collection;\n\n        $c->push($model1)->push($model2)->push($model3);\n\n        $this->assertInstanceOf(BaseCollection::class, $c->pluck('id'));\n        $this->assertEquals([1, 2, 3], $c->pluck('id')->all());\n\n        $this->assertInstanceOf(BaseCollection::class, $c->pluck('id', 'id'));\n        $this->assertEquals([1 => 1, 2 => 2, 3 => 3], $c->pluck('id', 'id')->all());\n        $this->assertInstanceOf(BaseCollection::class, $c->pluck('test'));\n\n        $this->assertEquals(['John (US)', 'Jane (NL)', 'Taylor (US)'], $c->pluck(fn (TestEloquentCollectionModel $model) => \"{$model->name} ({$model->country})\")->all());\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $user = EloquentTestUserModel::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n\n        EloquentTestArticleModel::query()->insert([\n            ['user_id' => 1, 'title' => 'Another title'],\n            ['user_id' => 1, 'title' => 'Another title'],\n            ['user_id' => 1, 'title' => 'Another title'],\n        ]);\n\n        EloquentTestCommentModel::query()->insert([\n            ['article_id' => 1, 'content' => 'Another comment'],\n            ['article_id' => 2, 'content' => 'Another comment'],\n        ]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass TestEloquentCollectionModel extends Model\n{\n    protected $visible = ['visible'];\n    protected $hidden = ['hidden'];\n\n    public function getTestAttribute()\n    {\n        return 'test';\n    }\n}\n\nclass EloquentTestUserModel extends Model\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function articles()\n    {\n        return $this->hasMany(EloquentTestArticleModel::class, 'user_id');\n    }\n}\n\nclass EloquentTestArticleModel extends Model\n{\n    protected $table = 'articles';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function comments()\n    {\n        return $this->hasMany(EloquentTestCommentModel::class, 'article_id');\n    }\n}\n\nclass EloquentTestCommentModel extends Model\n{\n    protected $table = 'comments';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass EloquentTestKey\n{\n    public function __construct(private readonly string $key)\n    {\n    }\n\n    public function __toString()\n    {\n        return $this->key;\n    }\n}\n\nclass EloquentAppendingTestUserModel extends Model\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected $appends = ['appended_field'];\n\n    public function getAppendedFieldAttribute()\n    {\n        return 'hello';\n    }\n\n    public function getOtherAppendedFieldAttribute()\n    {\n        return 'bye';\n    }\n\n    public function articles()\n    {\n        return $this->hasMany(EloquentTestArticleModel::class, 'user_id');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentDynamicRelationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Query\\Builder as Query;\nuse Illuminate\\Tests\\Database\\DynamicRelationModel2 as Related;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentDynamicRelationsTest extends TestCase\n{\n    public function testBasicDynamicRelations()\n    {\n        DynamicRelationModel::resolveRelationUsing('dynamicRel_2', fn () => new FakeHasManyRel);\n        $model = new DynamicRelationModel;\n        $this->assertEquals(['many' => 'related'], $model->dynamicRel_2);\n        $this->assertEquals(['many' => 'related'], $model->getRelationValue('dynamicRel_2'));\n    }\n\n    public function testBasicDynamicRelationsOverride()\n    {\n        // Dynamic Relations can override each other.\n        DynamicRelationModel::resolveRelationUsing('dynamicRelConflict', fn ($m) => $m->hasOne(Related::class));\n        DynamicRelationModel::resolveRelationUsing('dynamicRelConflict', fn (DynamicRelationModel $m) => new FakeHasManyRel);\n\n        $model = new DynamicRelationModel;\n        $this->assertInstanceOf(HasMany::class, $model->dynamicRelConflict());\n        $this->assertEquals(['many' => 'related'], $model->dynamicRelConflict);\n        $this->assertEquals(['many' => 'related'], $model->getRelationValue('dynamicRelConflict'));\n        $this->assertTrue($model->isRelation('dynamicRelConflict'));\n    }\n\n    public function testInharitedDynamicRelations()\n    {\n        DynamicRelationModel::resolveRelationUsing('inheritedDynamicRel', fn () => new FakeHasManyRel);\n        $model = new DynamicRelationModel;\n        $model2 = new DynamicRelationModel2;\n        $model4 = new DynamicRelationModel4;\n        $this->assertTrue($model->isRelation('inheritedDynamicRel'));\n        $this->assertTrue($model4->isRelation('inheritedDynamicRel'));\n        $this->assertFalse($model2->isRelation('inheritedDynamicRel'));\n        $this->assertEquals($model->inheritedDynamicRel(), $model4->inheritedDynamicRel());\n        $this->assertEquals($model->inheritedDynamicRel, $model4->inheritedDynamicRel);\n    }\n\n    public function testInheritedDynamicRelationsOverride()\n    {\n        // Inherited Dynamic Relations can be overridden\n        DynamicRelationModel::resolveRelationUsing('dynamicRelConflict', fn ($m) => $m->hasOne(Related::class));\n        $model = new DynamicRelationModel;\n        $model4 = new DynamicRelationModel4;\n        $this->assertInstanceOf(HasOne::class, $model->dynamicRelConflict());\n        $this->assertInstanceOf(HasOne::class, $model4->dynamicRelConflict());\n        DynamicRelationModel4::resolveRelationUsing('dynamicRelConflict', fn ($m) => $m->hasMany(Related::class));\n        $this->assertInstanceOf(HasOne::class, $model->dynamicRelConflict());\n        $this->assertInstanceOf(HasMany::class, $model4->dynamicRelConflict());\n    }\n\n    public function testDynamicRelationsCanNotHaveTheSameNameAsNormalRelations()\n    {\n        $model = new DynamicRelationModel;\n\n        // Dynamic relations can not override hard-coded methods.\n        DynamicRelationModel::resolveRelationUsing('hardCodedRelation', fn ($m) => $m->hasOne(Related::class));\n        $this->assertInstanceOf(HasMany::class, $model->hardCodedRelation());\n        $this->assertEquals(['many' => 'related'], $model->hardCodedRelation);\n        $this->assertEquals(['many' => 'related'], $model->getRelationValue('hardCodedRelation'));\n        $this->assertTrue($model->isRelation('hardCodedRelation'));\n    }\n\n    public function testRelationResolvers()\n    {\n        $model1 = new DynamicRelationModel;\n        $model3 = new DynamicRelationModel3;\n\n        // Same dynamic methods with the same name on two models do not conflict or override.\n        DynamicRelationModel::resolveRelationUsing('dynamicRel', fn ($m) => $m->hasOne(Related::class));\n        DynamicRelationModel3::resolveRelationUsing('dynamicRel', fn (DynamicRelationModel3 $m) => $m->hasMany(Related::class));\n        $this->assertInstanceOf(HasOne::class, $model1->dynamicRel());\n        $this->assertInstanceOf(HasMany::class, $model3->dynamicRel());\n        $this->assertTrue($model1->isRelation('dynamicRel'));\n        $this->assertTrue($model3->isRelation('dynamicRel'));\n    }\n}\n\nclass DynamicRelationModel extends Model\n{\n    public function hardCodedRelation()\n    {\n        return new FakeHasManyRel();\n    }\n}\n\nclass DynamicRelationModel2 extends Model\n{\n    public function getResults()\n    {\n        //\n    }\n\n    public function newQuery()\n    {\n        $query = new class extends Query\n        {\n            public function __construct()\n            {\n                //\n            }\n        };\n\n        return new Builder($query);\n    }\n}\n\nclass DynamicRelationModel3 extends Model\n{\n    //\n}\n\nclass DynamicRelationModel4 extends DynamicRelationModel\n{\n    //\n}\n\nclass FakeHasManyRel extends HasMany\n{\n    public function __construct()\n    {\n        //\n    }\n\n    public function getResults()\n    {\n        return ['many' => 'related'];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentFactoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse BadMethodCallException;\nuse Faker\\Generator;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Factories\\CrossJoinSequence;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Factories\\Sequence;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\Money\\Price;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nclass DatabaseEloquentFactoryTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $container = Container::getInstance();\n        $container->singleton(Generator::class, function ($app, $parameters) {\n            return \\Faker\\Factory::create('en_US');\n        });\n        $container->instance(Application::class, $app = m::mock(Application::class));\n        $app->shouldReceive('getNamespace')->andReturn('App\\\\');\n\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n        Factory::expandRelationshipsByDefault();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('options')->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('posts', function ($table) {\n            $table->increments('id');\n            $table->foreignId('user_id');\n            $table->string('title');\n            $table->softDeletes();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('comments', function ($table) {\n            $table->increments('id');\n            $table->foreignId('commentable_id');\n            $table->string('commentable_type');\n            $table->foreignId('user_id');\n            $table->string('body');\n            $table->softDeletes();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('roles', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('role_user', function ($table) {\n            $table->foreignId('role_id');\n            $table->foreignId('user_id');\n            $table->string('admin')->default('N');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function test_basic_model_can_be_created()\n    {\n        $user = FactoryTestUserFactory::new()->create();\n        $this->assertInstanceOf(Eloquent::class, $user);\n\n        $user = FactoryTestUserFactory::new()->createOne();\n        $this->assertInstanceOf(Eloquent::class, $user);\n\n        $user = FactoryTestUserFactory::new()->create(['name' => 'Taylor Otwell']);\n        $this->assertInstanceOf(Eloquent::class, $user);\n        $this->assertSame('Taylor Otwell', $user->name);\n\n        $user = FactoryTestUserFactory::new()->set('name', 'Taylor Otwell')->create();\n        $this->assertInstanceOf(Eloquent::class, $user);\n        $this->assertSame('Taylor Otwell', $user->name);\n\n        $users = FactoryTestUserFactory::new()->createMany([\n            ['name' => 'Taylor Otwell'],\n            ['name' => 'Jeffrey Way'],\n        ]);\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n\n        $users = FactoryTestUserFactory::new()->createMany(2);\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n\n        $users = FactoryTestUserFactory::times(2)->createMany();\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n\n        $users = FactoryTestUserFactory::times(2)->createMany();\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n\n        $users = FactoryTestUserFactory::times(3)->createMany([\n            ['name' => 'Taylor Otwell'],\n            ['name' => 'Jeffrey Way'],\n        ]);\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n\n        $users = FactoryTestUserFactory::new()->createMany();\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(1, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n\n        $users = FactoryTestUserFactory::times(10)->create();\n        $this->assertCount(10, $users);\n    }\n\n    public function test_expanded_closure_attributes_are_resolved_and_passed_to_closures()\n    {\n        $user = FactoryTestUserFactory::new()->create([\n            'name' => function () {\n                return 'taylor';\n            },\n            'options' => function ($attributes) {\n                return $attributes['name'].'-options';\n            },\n        ]);\n\n        $this->assertSame('taylor-options', $user->options);\n    }\n\n    public function test_expanded_closure_attribute_returning_a_factory_is_resolved()\n    {\n        $post = FactoryTestPostFactory::new()->create([\n            'title' => 'post',\n            'user_id' => fn ($attributes) => FactoryTestUserFactory::new([\n                'options' => $attributes['title'].'-options',\n            ]),\n        ]);\n\n        $this->assertEquals('post-options', $post->user->options);\n    }\n\n    public function test_make_creates_unpersisted_model_instance()\n    {\n        $user = FactoryTestUserFactory::new()->makeOne();\n        $this->assertInstanceOf(Eloquent::class, $user);\n\n        $user = FactoryTestUserFactory::new()->make(['name' => 'Taylor Otwell']);\n\n        $this->assertInstanceOf(Eloquent::class, $user);\n        $this->assertSame('Taylor Otwell', $user->name);\n        $this->assertCount(0, FactoryTestUser::all());\n    }\n\n    public function test_make_many_creates_unpersisted_model_instances()\n    {\n        $users = FactoryTestUserFactory::new()->makeMany([\n            ['name' => 'Taylor Otwell'],\n            ['name' => 'Jeffrey Way'],\n        ]);\n\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(2, $users);\n        $this->assertSame('Taylor Otwell', $users[0]->name);\n        $this->assertSame('Jeffrey Way', $users[1]->name);\n        $this->assertCount(0, FactoryTestUser::all());\n\n        $users = FactoryTestUserFactory::new()->makeMany(3);\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(3, $users);\n        $this->assertInstanceOf(FactoryTestUser::class, $users->first());\n        $this->assertCount(0, FactoryTestUser::all());\n\n        $users = FactoryTestUserFactory::new()->makeMany();\n        $this->assertInstanceOf(Collection::class, $users);\n        $this->assertCount(1, $users);\n        $this->assertCount(0, FactoryTestUser::all());\n    }\n\n    public function test_basic_model_attributes_can_be_created()\n    {\n        $user = FactoryTestUserFactory::new()->raw();\n        $this->assertIsArray($user);\n\n        $user = FactoryTestUserFactory::new()->raw(['name' => 'Taylor Otwell']);\n        $this->assertIsArray($user);\n        $this->assertSame('Taylor Otwell', $user['name']);\n    }\n\n    public function test_expanded_model_attributes_can_be_created()\n    {\n        $post = FactoryTestPostFactory::new()->raw();\n        $this->assertIsArray($post);\n\n        $post = FactoryTestPostFactory::new()->raw(['title' => 'Test Title']);\n        $this->assertIsArray($post);\n        $this->assertIsInt($post['user_id']);\n        $this->assertSame('Test Title', $post['title']);\n    }\n\n    public function test_lazy_model_attributes_can_be_created()\n    {\n        $userFunction = FactoryTestUserFactory::new()->lazy();\n        $this->assertIsCallable($userFunction);\n        $this->assertInstanceOf(Eloquent::class, $userFunction());\n\n        $userFunction = FactoryTestUserFactory::new()->lazy(['name' => 'Taylor Otwell']);\n        $this->assertIsCallable($userFunction);\n\n        $user = $userFunction();\n        $this->assertInstanceOf(Eloquent::class, $user);\n        $this->assertSame('Taylor Otwell', $user->name);\n    }\n\n    public function test_multiple_model_attributes_can_be_created()\n    {\n        $posts = FactoryTestPostFactory::times(10)->raw();\n        $this->assertIsArray($posts);\n\n        $this->assertCount(10, $posts);\n    }\n\n    public function test_after_creating_and_making_callbacks_are_called()\n    {\n        $user = FactoryTestUserFactory::new()\n            ->afterMaking(function ($user) {\n                $_SERVER['__test.user.making'] = $user;\n            })\n            ->afterCreating(function ($user) {\n                $_SERVER['__test.user.creating'] = $user;\n            })\n            ->create();\n\n        $this->assertSame($user, $_SERVER['__test.user.making']);\n        $this->assertSame($user, $_SERVER['__test.user.creating']);\n\n        unset($_SERVER['__test.user.making'], $_SERVER['__test.user.creating']);\n    }\n\n    public function test_without_after_making_removes_callbacks()\n    {\n        $user = FactoryTestUserFactory::new()\n            ->afterMaking(function ($user) {\n                $_SERVER['__test.user.making'] = $user;\n            })\n            ->withoutAfterMaking()\n            ->create();\n\n        $this->assertArrayNotHasKey('__test.user.making', $_SERVER);\n    }\n\n    public function test_without_after_creating_removes_callbacks()\n    {\n        $user = FactoryTestUserFactory::new()\n            ->afterCreating(function ($user) {\n                $_SERVER['__test.user.creating'] = $user;\n            })\n            ->withoutAfterCreating()\n            ->create();\n\n        $this->assertArrayNotHasKey('__test.user.creating', $_SERVER);\n    }\n\n    public function test_without_after_making_removes_configure_callbacks()\n    {\n        $user = FactoryTestUserWithCallbacksFactory::new()\n            ->withoutAfterMaking()\n            ->create();\n\n        $this->assertArrayNotHasKey('__test.user.making', $_SERVER);\n        $this->assertSame($user, $_SERVER['__test.user.creating']);\n\n        unset($_SERVER['__test.user.creating']);\n    }\n\n    public function test_without_after_creating_removes_configure_callbacks()\n    {\n        $user = FactoryTestUserWithCallbacksFactory::new()\n            ->withoutAfterCreating()\n            ->create();\n\n        $this->assertSame($user, $_SERVER['__test.user.making']);\n        $this->assertArrayNotHasKey('__test.user.creating', $_SERVER);\n\n        unset($_SERVER['__test.user.making']);\n    }\n\n    public function test_has_many_relationship()\n    {\n        $users = FactoryTestUserFactory::times(10)\n            ->has(\n                FactoryTestPostFactory::times(3)\n                    ->state(function ($attributes, $user) {\n                        // Test parent is passed to child state mutations...\n                        $_SERVER['__test.post.state-user'] = $user;\n\n                        return [];\n                    })\n                    // Test parents passed to callback...\n                    ->afterCreating(function ($post, $user) {\n                        $_SERVER['__test.post.creating-post'] = $post;\n                        $_SERVER['__test.post.creating-user'] = $user;\n                    }),\n                'posts'\n            )\n            ->create();\n\n        $this->assertCount(10, FactoryTestUser::all());\n        $this->assertCount(30, FactoryTestPost::all());\n        $this->assertCount(3, FactoryTestUser::latest()->first()->posts);\n\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.post.creating-post']);\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.post.creating-user']);\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.post.state-user']);\n\n        unset($_SERVER['__test.post.creating-post'], $_SERVER['__test.post.creating-user'], $_SERVER['__test.post.state-user']);\n    }\n\n    public function test_belongs_to_relationship()\n    {\n        $posts = FactoryTestPostFactory::times(3)\n            ->for(FactoryTestUserFactory::new(['name' => 'Taylor Otwell']), 'user')\n            ->create();\n\n        $this->assertCount(3, $posts->filter(function ($post) {\n            return $post->user->name === 'Taylor Otwell';\n        }));\n\n        $this->assertCount(1, FactoryTestUser::all());\n        $this->assertCount(3, FactoryTestPost::all());\n    }\n\n    public function test_belongs_to_relationship_with_existing_model_instance()\n    {\n        $user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->create();\n        $posts = FactoryTestPostFactory::times(3)\n            ->for($user, 'user')\n            ->create();\n\n        $this->assertCount(3, $posts->filter(function ($post) use ($user) {\n            return $post->user->is($user);\n        }));\n\n        $this->assertCount(1, FactoryTestUser::all());\n        $this->assertCount(3, FactoryTestPost::all());\n    }\n\n    public function test_belongs_to_relationship_with_existing_model_instance_with_relationship_name_implied_from_model()\n    {\n        $user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->create();\n        $posts = FactoryTestPostFactory::times(3)\n            ->for($user)\n            ->create();\n\n        $this->assertCount(3, $posts->filter(function ($post) use ($user) {\n            return $post->factoryTestUser->is($user);\n        }));\n\n        $this->assertCount(1, FactoryTestUser::all());\n        $this->assertCount(3, FactoryTestPost::all());\n    }\n\n    public function test_morph_to_relationship()\n    {\n        $posts = FactoryTestCommentFactory::times(3)\n            ->for(FactoryTestPostFactory::new(['title' => 'Test Title']), 'commentable')\n            ->create();\n\n        $this->assertSame('Test Title', FactoryTestPost::first()->title);\n        $this->assertCount(3, FactoryTestPost::first()->comments);\n\n        $this->assertCount(1, FactoryTestPost::all());\n        $this->assertCount(3, FactoryTestComment::all());\n    }\n\n    public function test_morph_to_relationship_with_existing_model_instance()\n    {\n        $post = FactoryTestPostFactory::new(['title' => 'Test Title'])->create();\n        $posts = FactoryTestCommentFactory::times(3)\n            ->for($post, 'commentable')\n            ->create();\n\n        $this->assertSame('Test Title', FactoryTestPost::first()->title);\n        $this->assertCount(3, FactoryTestPost::first()->comments);\n\n        $this->assertCount(1, FactoryTestPost::all());\n        $this->assertCount(3, FactoryTestComment::all());\n    }\n\n    public function test_belongs_to_many_relationship()\n    {\n        $users = FactoryTestUserFactory::times(3)\n            ->hasAttached(\n                FactoryTestRoleFactory::times(3)->afterCreating(function ($role, $user) {\n                    $_SERVER['__test.role.creating-role'] = $role;\n                    $_SERVER['__test.role.creating-user'] = $user;\n                }),\n                ['admin' => 'Y'],\n                'roles'\n            )\n            ->create();\n\n        $this->assertCount(9, FactoryTestRole::all());\n\n        $user = FactoryTestUser::latest()->first();\n\n        $this->assertCount(3, $user->roles);\n        $this->assertSame('Y', $user->roles->first()->pivot->admin);\n\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-role']);\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-user']);\n\n        unset($_SERVER['__test.role.creating-role'], $_SERVER['__test.role.creating-user']);\n    }\n\n    public function test_belongs_to_many_relationship_related_models_set_on_instance_when_touching_owner()\n    {\n        $user = FactoryTestUserFactory::new()->create();\n        $role = FactoryTestRoleFactory::new()->hasAttached($user, [], 'users')->create();\n\n        $this->assertCount(1, $role->users);\n    }\n\n    public function test_relation_can_be_loaded_before_model_is_created()\n    {\n        $user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->createOne();\n\n        $post = FactoryTestPostFactory::new()\n            ->for($user, 'user')\n            ->afterMaking(function (FactoryTestPost $post) {\n                $post->load('user');\n            })\n            ->createOne();\n\n        $this->assertTrue($post->relationLoaded('user'));\n        $this->assertTrue($post->user->is($user));\n\n        $this->assertCount(1, FactoryTestUser::all());\n        $this->assertCount(1, FactoryTestPost::all());\n    }\n\n    public function test_belongs_to_many_relationship_with_existing_model_instances()\n    {\n        $roles = FactoryTestRoleFactory::times(3)\n            ->afterCreating(function ($role) {\n                $_SERVER['__test.role.creating-role'] = $role;\n            })\n            ->create();\n        FactoryTestUserFactory::times(3)\n            ->hasAttached($roles, ['admin' => 'Y'], 'roles')\n            ->create();\n\n        $this->assertCount(3, FactoryTestRole::all());\n\n        $user = FactoryTestUser::latest()->first();\n\n        $this->assertCount(3, $user->roles);\n        $this->assertSame('Y', $user->roles->first()->pivot->admin);\n\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-role']);\n\n        unset($_SERVER['__test.role.creating-role']);\n    }\n\n    public function test_belongs_to_many_relationship_with_existing_model_instances_using_array()\n    {\n        $roles = FactoryTestRoleFactory::times(3)\n            ->afterCreating(function ($role) {\n                $_SERVER['__test.role.creating-role'] = $role;\n            })\n            ->create();\n        FactoryTestUserFactory::times(3)\n            ->hasAttached($roles->toArray(), ['admin' => 'Y'], 'roles')\n            ->create();\n\n        $this->assertCount(3, FactoryTestRole::all());\n\n        $user = FactoryTestUser::latest()->first();\n\n        $this->assertCount(3, $user->roles);\n        $this->assertSame('Y', $user->roles->first()->pivot->admin);\n\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-role']);\n\n        unset($_SERVER['__test.role.creating-role']);\n    }\n\n    public function test_belongs_to_many_relationship_with_existing_model_instances_with_relationship_name_implied_from_model()\n    {\n        $roles = FactoryTestRoleFactory::times(3)\n            ->afterCreating(function ($role) {\n                $_SERVER['__test.role.creating-role'] = $role;\n            })\n            ->create();\n        FactoryTestUserFactory::times(3)\n            ->hasAttached($roles, ['admin' => 'Y'])\n            ->create();\n\n        $this->assertCount(3, FactoryTestRole::all());\n\n        $user = FactoryTestUser::latest()->first();\n\n        $this->assertCount(3, $user->factoryTestRoles);\n        $this->assertSame('Y', $user->factoryTestRoles->first()->pivot->admin);\n\n        $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-role']);\n\n        unset($_SERVER['__test.role.creating-role']);\n    }\n\n    public function test_sequences()\n    {\n        $users = FactoryTestUserFactory::times(2)->sequence(\n            ['name' => 'Taylor Otwell'],\n            ['name' => 'Abigail Otwell'],\n        )->create();\n\n        $this->assertSame('Taylor Otwell', $users[0]->name);\n        $this->assertSame('Abigail Otwell', $users[1]->name);\n\n        $user = FactoryTestUserFactory::new()\n            ->hasAttached(\n                FactoryTestRoleFactory::times(4),\n                new Sequence(['admin' => 'Y'], ['admin' => 'N']),\n                'roles'\n            )\n            ->create();\n\n        $this->assertCount(4, $user->roles);\n\n        $this->assertCount(2, $user->roles->filter(function ($role) {\n            return $role->pivot->admin === 'Y';\n        }));\n\n        $this->assertCount(2, $user->roles->filter(function ($role) {\n            return $role->pivot->admin === 'N';\n        }));\n\n        $users = FactoryTestUserFactory::times(2)->sequence(function ($sequence) {\n            return ['name' => 'index: '.$sequence->index];\n        })->create();\n\n        $this->assertSame('index: 0', $users[0]->name);\n        $this->assertSame('index: 1', $users[1]->name);\n    }\n\n    public function test_counted_sequence()\n    {\n        $factory = FactoryTestUserFactory::new()->forEachSequence(\n            ['name' => 'Taylor Otwell'],\n            ['name' => 'Abigail Otwell'],\n            ['name' => 'Dayle Rees']\n        );\n\n        $class = new ReflectionClass($factory);\n        $prop = $class->getProperty('count');\n        $value = $prop->getValue($factory);\n\n        $this->assertSame(3, $value);\n    }\n\n    public function test_sequence_with_has_many_relationship()\n    {\n        $users = FactoryTestUserFactory::times(2)\n            ->sequence(\n                ['name' => 'Abigail Otwell'],\n                ['name' => 'Taylor Otwell'],\n            )\n            ->has(\n                FactoryTestPostFactory::times(3)\n                    ->state(['title' => 'Post'])\n                    ->sequence(function ($sequence, $attributes, $user) {\n                        return ['title' => $user->name.' '.$attributes['title'].' '.($sequence->index % 3 + 1)];\n                    }),\n                'posts'\n            )\n            ->create();\n\n        $this->assertCount(2, FactoryTestUser::all());\n        $this->assertCount(6, FactoryTestPost::all());\n        $this->assertCount(3, FactoryTestUser::latest()->first()->posts);\n        $this->assertEquals(\n            FactoryTestPost::orderBy('title')->pluck('title')->all(),\n            [\n                'Abigail Otwell Post 1',\n                'Abigail Otwell Post 2',\n                'Abigail Otwell Post 3',\n                'Taylor Otwell Post 1',\n                'Taylor Otwell Post 2',\n                'Taylor Otwell Post 3',\n            ]\n        );\n    }\n\n    public function test_cross_join_sequences()\n    {\n        $assert = function ($users) {\n            $assertions = [\n                ['first_name' => 'Thomas', 'last_name' => 'Anderson'],\n                ['first_name' => 'Thomas', 'last_name' => 'Smith'],\n                ['first_name' => 'Agent', 'last_name' => 'Anderson'],\n                ['first_name' => 'Agent', 'last_name' => 'Smith'],\n            ];\n\n            foreach ($assertions as $key => $assertion) {\n                $this->assertSame(\n                    $assertion,\n                    $users[$key]->only('first_name', 'last_name'),\n                );\n            }\n        };\n\n        $usersByClass = FactoryTestUserFactory::times(4)\n            ->state(\n                new CrossJoinSequence(\n                    [['first_name' => 'Thomas'], ['first_name' => 'Agent']],\n                    [['last_name' => 'Anderson'], ['last_name' => 'Smith']],\n                ),\n            )\n            ->make();\n\n        $assert($usersByClass);\n\n        $usersByMethod = FactoryTestUserFactory::times(4)\n            ->crossJoinSequence(\n                [['first_name' => 'Thomas'], ['first_name' => 'Agent']],\n                [['last_name' => 'Anderson'], ['last_name' => 'Smith']],\n            )\n            ->make();\n\n        $assert($usersByMethod);\n    }\n\n    public function test_resolve_nested_model_factories()\n    {\n        Factory::useNamespace('Factories\\\\');\n\n        $resolves = [\n            'App\\\\Foo' => 'Factories\\\\FooFactory',\n            'App\\\\Models\\\\Foo' => 'Factories\\\\FooFactory',\n            'App\\\\Models\\\\Nested\\\\Foo' => 'Factories\\\\Nested\\\\FooFactory',\n            'App\\\\Models\\\\Really\\\\Nested\\\\Foo' => 'Factories\\\\Really\\\\Nested\\\\FooFactory',\n        ];\n\n        foreach ($resolves as $model => $factory) {\n            $this->assertEquals($factory, Factory::resolveFactoryName($model));\n        }\n    }\n\n    public function test_resolve_nested_model_name_from_factory()\n    {\n        Container::getInstance()->instance(Application::class, $app = m::mock(Application::class));\n        $app->shouldReceive('getNamespace')->andReturn('Illuminate\\\\Tests\\\\Database\\\\Fixtures\\\\');\n\n        Factory::useNamespace('Illuminate\\\\Tests\\\\Database\\\\Fixtures\\\\Factories\\\\');\n\n        $factory = Price::factory();\n\n        $this->assertSame(Price::class, $factory->modelName());\n    }\n\n    public function test_resolve_non_app_nested_model_factories()\n    {\n        Container::getInstance()->instance(Application::class, $app = m::mock(Application::class));\n        $app->shouldReceive('getNamespace')->andReturn('Foo\\\\');\n\n        Factory::useNamespace('Factories\\\\');\n\n        $resolves = [\n            'Foo\\\\Bar' => 'Factories\\\\BarFactory',\n            'Foo\\\\Models\\\\Bar' => 'Factories\\\\BarFactory',\n            'Foo\\\\Models\\\\Nested\\\\Bar' => 'Factories\\\\Nested\\\\BarFactory',\n            'Foo\\\\Models\\\\Really\\\\Nested\\\\Bar' => 'Factories\\\\Really\\\\Nested\\\\BarFactory',\n        ];\n\n        foreach ($resolves as $model => $factory) {\n            $this->assertEquals($factory, Factory::resolveFactoryName($model));\n        }\n    }\n\n    public function test_model_has_factory()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $this->assertInstanceOf(FactoryTestUserFactory::class, FactoryTestUser::factory());\n    }\n\n    public function test_dynamic_has_and_for_methods()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $user = FactoryTestUserFactory::new()->hasPosts(3)->create();\n\n        $this->assertCount(3, $user->posts);\n\n        $post = FactoryTestPostFactory::new()\n            ->forAuthor(['name' => 'Taylor Otwell'])\n            ->hasComments(2)\n            ->create();\n\n        $this->assertInstanceOf(FactoryTestUser::class, $post->author);\n        $this->assertSame('Taylor Otwell', $post->author->name);\n        $this->assertCount(2, $post->comments);\n    }\n\n    public function test_can_be_macroable()\n    {\n        $factory = FactoryTestUserFactory::new();\n        $factory->macro('getFoo', function () {\n            return 'Hello World';\n        });\n\n        $this->assertSame('Hello World', $factory->getFoo());\n    }\n\n    public function test_factory_can_conditionally_execute_code()\n    {\n        FactoryTestUserFactory::new()\n            ->when(true, function () {\n                $this->assertTrue(true);\n            })\n            ->when(false, function () {\n                $this->fail('Unreachable code that has somehow been reached.');\n            })\n            ->unless(false, function () {\n                $this->assertTrue(true);\n            })\n            ->unless(true, function () {\n                $this->fail('Unreachable code that has somehow been reached.');\n            });\n    }\n\n    public function test_dynamic_trashed_state_for_softdeletes_models()\n    {\n        $now = Carbon::create(2020, 6, 7, 8, 9);\n        Carbon::setTestNow($now);\n        $post = FactoryTestPostFactory::new()->trashed()->create();\n\n        $this->assertTrue($post->deleted_at->equalTo($now->subDay()));\n\n        $deleted_at = Carbon::create(2020, 1, 2, 3, 4, 5);\n        $post = FactoryTestPostFactory::new()->trashed($deleted_at)->create();\n\n        $this->assertTrue($deleted_at->equalTo($post->deleted_at));\n\n        Carbon::setTestNow();\n    }\n\n    public function test_dynamic_trashed_state_respects_existing_state()\n    {\n        $now = Carbon::create(2020, 6, 7, 8, 9);\n        Carbon::setTestNow($now);\n        $comment = FactoryTestCommentFactory::new()->trashed()->create();\n\n        $this->assertTrue($comment->deleted_at->equalTo($now->subWeek()));\n\n        Carbon::setTestNow();\n    }\n\n    public function test_dynamic_trashed_state_throws_exception_when_not_a_softdeletes_model()\n    {\n        $this->expectException(BadMethodCallException::class);\n        FactoryTestUserFactory::new()->trashed()->create();\n    }\n\n    public function test_model_instances_can_be_used_in_place_of_nested_factories()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $user = FactoryTestUserFactory::new()->create();\n        $post = FactoryTestPostFactory::new()\n            ->recycle($user)\n            ->hasComments(2)\n            ->create();\n\n        $this->assertSame(1, FactoryTestUser::count());\n        $this->assertEquals($user->id, $post->user_id);\n        $this->assertEquals($user->id, $post->comments[0]->user_id);\n        $this->assertEquals($user->id, $post->comments[1]->user_id);\n    }\n\n    public function test_for_method_recycles_models()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $user = FactoryTestUserFactory::new()->create();\n        $post = FactoryTestPostFactory::new()\n            ->recycle($user)\n            ->for(FactoryTestUserFactory::new())\n            ->create();\n\n        $this->assertSame(1, FactoryTestUser::count());\n    }\n\n    public function test_has_method_does_not_reassign_the_parent()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $post = FactoryTestPostFactory::new()->create();\n        $user = FactoryTestUserFactory::new()\n            ->recycle($post)\n            // The recycled post already belongs to a user, so it shouldn't be recycled here.\n            ->has(FactoryTestPostFactory::new(), 'posts')\n            ->create();\n\n        $this->assertSame(2, FactoryTestPost::count());\n    }\n\n    public function test_multiple_models_can_be_provided_to_recycle()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $users = FactoryTestUserFactory::new()->count(3)->create();\n\n        $posts = FactoryTestPostFactory::new()\n            ->recycle($users)\n            ->for(FactoryTestUserFactory::new())\n            ->has(FactoryTestCommentFactory::new()->count(5), 'comments')\n            ->count(2)\n            ->create();\n\n        $this->assertSame(3, FactoryTestUser::count());\n    }\n\n    public function test_recycled_models_can_be_combined_with_multiple_calls()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $users = FactoryTestUserFactory::new()\n            ->count(2)\n            ->create();\n        $posts = FactoryTestPostFactory::new()\n            ->recycle($users)\n            ->count(2)\n            ->create();\n        $additionalUser = FactoryTestUserFactory::new()\n            ->create();\n        $additionalPost = FactoryTestPostFactory::new()\n            ->recycle($additionalUser)\n            ->create();\n\n        $this->assertSame(3, FactoryTestUser::count());\n        $this->assertSame(3, FactoryTestPost::count());\n\n        $comments = FactoryTestCommentFactory::new()\n            ->recycle($users)\n            ->recycle($posts)\n            ->recycle([$additionalUser, $additionalPost])\n            ->count(5)\n            ->create();\n\n        $this->assertSame(3, FactoryTestUser::count());\n        $this->assertSame(3, FactoryTestPost::count());\n    }\n\n    public function test_no_models_can_be_provided_to_recycle()\n    {\n        Factory::guessFactoryNamesUsing(function ($model) {\n            return $model.'Factory';\n        });\n\n        $posts = FactoryTestPostFactory::new()\n            ->recycle([])\n            ->count(2)\n            ->create();\n\n        $this->assertSame(2, FactoryTestPost::count());\n        $this->assertSame(2, FactoryTestUser::count());\n    }\n\n    public function test_can_disable_relationships()\n    {\n        $post = FactoryTestPostFactory::new()\n            ->withoutParents()\n            ->make();\n\n        $this->assertNull($post->user_id);\n    }\n\n    public function test_can_disable_relationships_explicitly_by_model_name()\n    {\n        $comment = FactoryTestCommentFactory::new()\n            ->withoutParents([FactoryTestUser::class])\n            ->make();\n\n        $this->assertNull($comment->user_id);\n        $this->assertNotNull($comment->commentable->id);\n    }\n\n    public function test_can_disable_relationships_explicitly_by_attribute_name()\n    {\n        $comment = FactoryTestCommentFactory::new()\n            ->withoutParents(['user_id'])\n            ->make();\n\n        $this->assertNull($comment->user_id);\n        $this->assertNotNull($comment->commentable->id);\n    }\n\n    public function test_can_disable_relationships_explicitly_by_both_attribute_name_and_model_name()\n    {\n        $comment = FactoryTestCommentFactory::new()\n            ->withoutParents(['user_id', FactoryTestPost::class])\n            ->make();\n\n        $this->assertNull($comment->user_id);\n        $this->assertNull($comment->commentable->id);\n    }\n\n    public function test_can_default_to_without_parents()\n    {\n        FactoryTestPostFactory::dontExpandRelationshipsByDefault();\n\n        $post = FactoryTestPostFactory::new()->make();\n        $this->assertNull($post->user_id);\n\n        FactoryTestPostFactory::expandRelationshipsByDefault();\n        $postWithParents = FactoryTestPostFactory::new()->create();\n        $this->assertNotNull($postWithParents->user_id);\n    }\n\n    public function test_factory_model_names_correct()\n    {\n        $this->assertEquals(FactoryTestUseFactoryAttribute::factory()->modelName(), FactoryTestUseFactoryAttribute::class);\n        $this->assertEquals(FactoryTestGuessModel::factory()->modelName(), FactoryTestGuessModel::class);\n    }\n\n    public function test_factory_global_model_resolver()\n    {\n        Factory::guessModelNamesUsing(function ($factory) {\n            return __NAMESPACE__.'\\\\'.Str::replaceLast('Factory', '', class_basename($factory::class));\n        });\n\n        $this->assertEquals(FactoryTestGuessModel::factory()->modelName(), FactoryTestGuessModel::class);\n        $this->assertEquals(FactoryTestUseFactoryAttribute::factory()->modelName(), FactoryTestUseFactoryAttribute::class);\n\n        $this->assertEquals(FactoryTestUseFactoryAttributeFactory::new()->modelName(), FactoryTestUseFactoryAttribute::class);\n        $this->assertEquals(FactoryTestGuessModelFactory::new()->modelName(), FactoryTestGuessModel::class);\n    }\n\n    public function test_factory_model_has_many_relationship_has_pending_attributes()\n    {\n        FactoryTestUser::factory()->has(new FactoryTestPostFactory(), 'postsWithFooBarBazAsTitle')->create();\n\n        $this->assertEquals('foo bar baz', FactoryTestPost::first()->title);\n    }\n\n    public function test_factory_model_has_many_relationship_has_pending_attributes_override()\n    {\n        FactoryTestUser::factory()->has((new FactoryTestPostFactory())->state(['title' => 'other title']), 'postsWithFooBarBazAsTitle')->create();\n\n        $this->assertEquals('other title', FactoryTestPost::first()->title);\n    }\n\n    public function test_factory_model_has_one_relationship_has_pending_attributes()\n    {\n        FactoryTestUser::factory()->has(new FactoryTestPostFactory(), 'postWithFooBarBazAsTitle')->create();\n\n        $this->assertEquals('foo bar baz', FactoryTestPost::first()->title);\n    }\n\n    public function test_factory_model_has_one_relationship_has_pending_attributes_override()\n    {\n        FactoryTestUser::factory()->has((new FactoryTestPostFactory())->state(['title' => 'other title']), 'postWithFooBarBazAsTitle')->create();\n\n        $this->assertEquals('other title', FactoryTestPost::first()->title);\n    }\n\n    public function test_factory_model_belongs_to_many_relationship_has_pending_attributes()\n    {\n        FactoryTestUser::factory()->has(new FactoryTestRoleFactory(), 'rolesWithFooBarBazAsName')->create();\n\n        $this->assertEquals('foo bar baz', FactoryTestRole::first()->name);\n    }\n\n    public function test_factory_model_belongs_to_many_relationship_has_pending_attributes_override()\n    {\n        FactoryTestUser::factory()->has((new FactoryTestRoleFactory())->state(['name' => 'other name']), 'rolesWithFooBarBazAsName')->create();\n\n        $this->assertEquals('other name', FactoryTestRole::first()->name);\n    }\n\n    public function test_factory_model_morph_many_relationship_has_pending_attributes()\n    {\n        (new FactoryTestPostFactory())->has(new FactoryTestCommentFactory(), 'commentsWithFooBarBazAsBody')->create();\n\n        $this->assertEquals('foo bar baz', FactoryTestComment::first()->body);\n    }\n\n    public function test_factory_model_morph_many_relationship_has_pending_attributes_override()\n    {\n        (new FactoryTestPostFactory())->has((new FactoryTestCommentFactory())->state(['body' => 'other body']), 'commentsWithFooBarBazAsBody')->create();\n\n        $this->assertEquals('other body', FactoryTestComment::first()->body);\n    }\n\n    public function test_factory_can_insert()\n    {\n        (new FactoryTestPostFactory())\n            ->count(5)\n            ->recycle([\n                (new FactoryTestUserFactory())->create(['name' => Name::Taylor]),\n                (new FactoryTestUserFactory())->create(['name' => Name::Shad, 'created_at' => Carbon::now()]),\n            ])\n            ->state(['title' => 'hello'])\n            ->insert();\n        $this->assertCount(5, $posts = FactoryTestPost::query()->where('title', 'hello')->get());\n        $this->assertEquals(strtoupper($posts[0]->user->name), $posts[0]->upper_case_name);\n        $this->assertEquals(\n            2,\n            ($users = FactoryTestUser::query()->get())->count()\n        );\n        $this->assertCount(1, $users->where('name', 'totwell'));\n        $this->assertCount(1, $users->where('name', 'shaedrich'));\n    }\n\n    public function test_factory_can_insert_with_hidden()\n    {\n        (new FactoryTestUserFactory())->forEachSequence(['name' => Name::Taylor, 'options' => 'abc'])->insert();\n        $user = DB::table('users')->sole();\n        $this->assertEquals('abc', $user->options);\n        $userModel = FactoryTestUser::query()->sole();\n        $this->assertEquals('abc', $userModel->options);\n    }\n\n    public function test_factory_can_insert_with_array_casts()\n    {\n        (new FactoryTestUserWithArrayFactory())->count(2)->insert();\n        $users = DB::table('users')->get();\n        foreach ($users as $user) {\n            $this->assertEquals(['rtj'], json_decode($user->options, true));\n            $createdAt = Carbon::parse($user->created_at);\n            $updatedAt = Carbon::parse($user->updated_at);\n            $this->assertEquals($updatedAt, $createdAt);\n        }\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\ConnectionInterface\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass FactoryTestUserFactory extends Factory\n{\n    protected $model = FactoryTestUser::class;\n\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n            'options' => null,\n        ];\n    }\n}\n\nclass FactoryTestUser extends Eloquent\n{\n    use HasFactory;\n\n    protected $table = 'users';\n    protected $hidden = ['options'];\n    protected $withCount = ['posts'];\n    protected $with = ['posts'];\n\n    public function posts()\n    {\n        return $this->hasMany(FactoryTestPost::class, 'user_id');\n    }\n\n    public function postsWithFooBarBazAsTitle()\n    {\n        return $this->hasMany(FactoryTestPost::class, 'user_id')->withAttributes(['title' => 'foo bar baz']);\n    }\n\n    public function postWithFooBarBazAsTitle()\n    {\n        return $this->hasOne(FactoryTestPost::class, 'user_id')->withAttributes(['title' => 'foo bar baz']);\n    }\n\n    public function roles()\n    {\n        return $this->belongsToMany(FactoryTestRole::class, 'role_user', 'user_id', 'role_id')->withPivot('admin');\n    }\n\n    public function rolesWithFooBarBazAsName()\n    {\n        return $this->belongsToMany(FactoryTestRole::class, 'role_user', 'user_id', 'role_id')->withPivot('admin')->withAttributes(['name' => 'foo bar baz']);\n    }\n\n    public function factoryTestRoles()\n    {\n        return $this->belongsToMany(FactoryTestRole::class, 'role_user', 'user_id', 'role_id')->withPivot('admin');\n    }\n}\n\nclass FactoryTestPostFactory extends Factory\n{\n    protected $model = FactoryTestPost::class;\n\n    public function definition()\n    {\n        return [\n            'user_id' => FactoryTestUserFactory::new(),\n            'title' => $this->faker->name(),\n        ];\n    }\n}\n\nclass FactoryTestPost extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'posts';\n\n    protected $appends = ['upper_case_name'];\n\n    public function upperCaseName(): Attribute\n    {\n        return Attribute::get(fn ($attr) => Str::upper($this->user->name));\n    }\n\n    public function user()\n    {\n        return $this->belongsTo(FactoryTestUser::class, 'user_id');\n    }\n\n    public function factoryTestUser()\n    {\n        return $this->belongsTo(FactoryTestUser::class, 'user_id');\n    }\n\n    public function author()\n    {\n        return $this->belongsTo(FactoryTestUser::class, 'user_id');\n    }\n\n    public function comments()\n    {\n        return $this->morphMany(FactoryTestComment::class, 'commentable');\n    }\n\n    public function commentsWithFooBarBazAsBody()\n    {\n        return $this->morphMany(FactoryTestComment::class, 'commentable')->withAttributes(['body' => 'foo bar baz']);\n    }\n}\n\nclass FactoryTestCommentFactory extends Factory\n{\n    protected $model = FactoryTestComment::class;\n\n    public function definition()\n    {\n        return [\n            'commentable_id' => FactoryTestPostFactory::new(),\n            'commentable_type' => FactoryTestPost::class,\n            'user_id' => fn () => FactoryTestUserFactory::new(),\n            'body' => $this->faker->name(),\n        ];\n    }\n\n    public function trashed()\n    {\n        return $this->state([\n            'deleted_at' => Carbon::now()->subWeek(),\n        ]);\n    }\n}\n\nclass FactoryTestComment extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'comments';\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass FactoryTestRoleFactory extends Factory\n{\n    protected $model = FactoryTestRole::class;\n\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n        ];\n    }\n}\n\nclass FactoryTestRole extends Eloquent\n{\n    protected $table = 'roles';\n\n    protected $touches = ['users'];\n\n    public function users()\n    {\n        return $this->belongsToMany(FactoryTestUser::class, 'role_user', 'role_id', 'user_id')->withPivot('admin');\n    }\n}\n\nclass FactoryTestGuessModelFactory extends Factory\n{\n    protected static function appNamespace()\n    {\n        return __NAMESPACE__.'\\\\';\n    }\n\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n        ];\n    }\n}\n\nclass FactoryTestGuessModel extends Eloquent\n{\n    use HasFactory;\n\n    protected static $factory = FactoryTestGuessModelFactory::class;\n}\n\nclass FactoryTestUseFactoryAttributeFactory extends Factory\n{\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n        ];\n    }\n}\n\n#[UseFactory(FactoryTestUseFactoryAttributeFactory::class)]\nclass FactoryTestUseFactoryAttribute extends Eloquent\n{\n    use HasFactory;\n}\n\nclass FactoryTestUserWithArray extends Eloquent\n{\n    protected $table = 'users';\n\n    protected function casts()\n    {\n        return ['options' => 'array'];\n    }\n}\n\nclass FactoryTestUserWithArrayFactory extends Factory\n{\n    protected $model = FactoryTestUserWithArray::class;\n\n    public function definition()\n    {\n        return [\n            'name' => 'killer mike',\n            'options' => ['rtj'],\n        ];\n    }\n}\n\nclass FactoryTestUserWithCallbacksFactory extends Factory\n{\n    protected $model = FactoryTestUser::class;\n\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n            'options' => null,\n        ];\n    }\n\n    public function configure()\n    {\n        return $this->afterMaking(function ($user) {\n            $_SERVER['__test.user.making'] = $user;\n        })->afterCreating(function ($user) {\n            $_SERVER['__test.user.creating'] = $user;\n        });\n    }\n}\n\nenum Name: string\n{\n    case Taylor = 'totwell';\n    case Shad = 'shaedrich';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentGlobalScopesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Attributes\\ScopedBy;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Scope;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentGlobalScopesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        tap(new DB)->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ])->bootEloquent();\n    }\n\n    protected function tearDown(): void\n    {\n        Model::unsetConnectionResolver();\n\n        parent::tearDown();\n    }\n\n    public function testGlobalScopeIsApplied()\n    {\n        $model = new EloquentGlobalScopesTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testGlobalScopeCanBeRemoved()\n    {\n        $model = new EloquentGlobalScopesTestModel;\n        $query = $model->newQuery()->withoutGlobalScope(ActiveScope::class);\n        $this->assertSame('select * from \"table\"', $query->toSql());\n        $this->assertEquals([], $query->getBindings());\n    }\n\n    public function testClassNameGlobalScopeIsApplied()\n    {\n        $model = new EloquentClassNameGlobalScopesTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testGlobalScopeInAttributeIsApplied()\n    {\n        $model = new EloquentGlobalScopeInAttributeTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testGlobalScopeInInheritedAttributeIsApplied()\n    {\n        $model = new EloquentGlobalScopeInInheritedAttributeTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testClosureGlobalScopeIsApplied()\n    {\n        $model = new EloquentClosureGlobalScopesTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ? order by \"name\" asc', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testGlobalScopesCanBeRegisteredViaArray()\n    {\n        $model = new EloquentGlobalScopesArrayTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ? order by \"name\" asc', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testClosureGlobalScopeCanBeRemoved()\n    {\n        $model = new EloquentClosureGlobalScopesTestModel;\n        $query = $model->newQuery()->withoutGlobalScope('active_scope');\n        $this->assertSame('select * from \"table\" order by \"name\" asc', $query->toSql());\n        $this->assertEquals([], $query->getBindings());\n    }\n\n    public function testGlobalScopeCanBeRemovedAfterTheQueryIsExecuted()\n    {\n        $model = new EloquentClosureGlobalScopesTestModel;\n        $query = $model->newQuery();\n        $this->assertSame('select * from \"table\" where \"active\" = ? order by \"name\" asc', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n\n        $query->withoutGlobalScope('active_scope');\n        $this->assertSame('select * from \"table\" order by \"name\" asc', $query->toSql());\n        $this->assertEquals([], $query->getBindings());\n    }\n\n    public function testAllGlobalScopesCanBeRemoved()\n    {\n        $model = new EloquentClosureGlobalScopesTestModel;\n        $query = $model->newQuery()->withoutGlobalScopes();\n        $this->assertSame('select * from \"table\"', $query->toSql());\n        $this->assertEquals([], $query->getBindings());\n\n        $query = EloquentClosureGlobalScopesTestModel::withoutGlobalScopes();\n        $this->assertSame('select * from \"table\"', $query->toSql());\n        $this->assertEquals([], $query->getBindings());\n    }\n\n    public function testAllGlobalScopesCanBeRemovedExceptSpecified()\n    {\n        $model = new EloquentClosureGlobalScopesTestModel;\n        $query = $model->newQuery()->withoutGlobalScopesExcept(['active_scope']);\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n\n        $query = EloquentClosureGlobalScopesTestModel::withoutGlobalScopesExcept(['active_scope']);\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([1], $query->getBindings());\n    }\n\n    public function testGlobalScopesWithOrWhereConditionsAreNested()\n    {\n        $model = new EloquentClosureGlobalScopesWithOrTestModel;\n\n        $query = $model->newQuery();\n        $this->assertSame('select \"email\", \"password\" from \"table\" where (\"email\" = ? or \"email\" = ?) and \"active\" = ? order by \"name\" asc', $query->toSql());\n        $this->assertEquals(['taylor@gmail.com', 'someone@else.com', 1], $query->getBindings());\n\n        $query = $model->newQuery()->where('col1', 'val1')->orWhere('col2', 'val2');\n        $this->assertSame('select \"email\", \"password\" from \"table\" where (\"col1\" = ? or \"col2\" = ?) and (\"email\" = ? or \"email\" = ?) and \"active\" = ? order by \"name\" asc', $query->toSql());\n        $this->assertEquals(['val1', 'val2', 'taylor@gmail.com', 'someone@else.com', 1], $query->getBindings());\n    }\n\n    public function testRegularScopesWithOrWhereConditionsAreNested()\n    {\n        $query = EloquentClosureGlobalScopesTestModel::withoutGlobalScopes()->where('foo', 'foo')->orWhere('bar', 'bar')->approved();\n\n        $this->assertSame('select * from \"table\" where (\"foo\" = ? or \"bar\" = ?) and (\"approved\" = ? or \"should_approve\" = ?)', $query->toSql());\n        $this->assertEquals(['foo', 'bar', 1, 0], $query->getBindings());\n    }\n\n    public function testScopesStartingWithOrBooleanArePreserved()\n    {\n        $query = EloquentClosureGlobalScopesTestModel::withoutGlobalScopes()->where('foo', 'foo')->orWhere('bar', 'bar')->orApproved();\n\n        $this->assertSame('select * from \"table\" where (\"foo\" = ? or \"bar\" = ?) or (\"approved\" = ? or \"should_approve\" = ?)', $query->toSql());\n        $this->assertEquals(['foo', 'bar', 1, 0], $query->getBindings());\n    }\n\n    public function testHasQueryWhereBothModelsHaveGlobalScopes()\n    {\n        $query = EloquentGlobalScopesWithRelationModel::has('related')->where('bar', 'baz');\n\n        $subQuery = 'select * from \"table\" where \"table2\".\"id\" = \"table\".\"related_id\" and \"foo\" = ? and \"active\" = ?';\n        $mainQuery = 'select * from \"table2\" where exists ('.$subQuery.') and \"bar\" = ? and \"active\" = ? order by \"name\" asc';\n\n        $this->assertEquals($mainQuery, $query->toSql());\n        $this->assertEquals(['bar', 1, 'baz', 1], $query->getBindings());\n    }\n\n    public function testRegularScopesThatRemoveGlobalScopes()\n    {\n        $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->approved()->notApproved();\n\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and (\"approved\" = ? or \"should_approve\" = ?) and (\"approved\" = ? or \"should_approve\" = ?) order by \"name\" asc', $query->toSql());\n        $this->assertEquals(['foo', 1, 0, 0, 1], $query->getBindings());\n    }\n\n    public function testRegularScopesThatRemoveGlobalScopesCalledInNestedWhereCondition()\n    {\n        $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->where(function ($query) {\n            $query->approved();\n            $query->orWhere(function ($query) {\n                $query->notApproved();\n            });\n        });\n\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and ((\"approved\" = ? or \"should_approve\" = ?) or ((\"approved\" = ? or \"should_approve\" = ?))) order by \"name\" asc', $query->toSql());\n        $this->assertEquals(['foo', 1, 0, 0, 1], $query->getBindings());\n    }\n\n    public function testRemovingGlobalScopeInNestedWhereCondition()\n    {\n        $query = EloquentClosureGlobalScopesTestModel::where('foo', 'foo')->where(function ($query) {\n            $query->approved();\n            $query->withoutGlobalScope('active_scope');\n        });\n\n        $this->assertSame('select * from \"table\" where \"foo\" = ? and ((\"approved\" = ? or \"should_approve\" = ?)) order by \"name\" asc', $query->toSql());\n        $this->assertEquals(['foo', 1, 0], $query->getBindings());\n    }\n}\n\nclass EloquentClosureGlobalScopesTestModel extends Model\n{\n    protected $table = 'table';\n\n    public static function boot()\n    {\n        static::addGlobalScope(function ($query) {\n            $query->orderBy('name');\n        });\n\n        static::addGlobalScope('active_scope', function ($query) {\n            $query->where('active', 1);\n        });\n\n        parent::boot();\n    }\n\n    public function scopeApproved($query)\n    {\n        return $query->where('approved', 1)->orWhere('should_approve', 0);\n    }\n\n    public function scopeNotApproved($query)\n    {\n        return $query->where('approved', 0)->orWhere('should_approve', 1)->withoutGlobalScope('active_scope');\n    }\n\n    public function scopeOrApproved($query)\n    {\n        return $query->orWhere('approved', 1)->orWhere('should_approve', 0);\n    }\n}\n\nclass EloquentGlobalScopesWithRelationModel extends EloquentClosureGlobalScopesTestModel\n{\n    protected $table = 'table2';\n\n    public function related()\n    {\n        return $this->hasMany(EloquentGlobalScopesTestModel::class, 'related_id')->where('foo', 'bar');\n    }\n}\n\nclass EloquentClosureGlobalScopesWithOrTestModel extends EloquentClosureGlobalScopesTestModel\n{\n    public static function boot()\n    {\n        static::addGlobalScope('or_scope', function ($query) {\n            $query->where('email', 'taylor@gmail.com')->orWhere('email', 'someone@else.com');\n        });\n\n        static::addGlobalScope(function ($query) {\n            $query->select('email', 'password');\n        });\n\n        parent::boot();\n    }\n}\n\nclass EloquentGlobalScopesTestModel extends Model\n{\n    protected $table = 'table';\n\n    public static function boot()\n    {\n        static::addGlobalScope(new ActiveScope);\n\n        parent::boot();\n    }\n}\n\nclass EloquentClassNameGlobalScopesTestModel extends Model\n{\n    protected $table = 'table';\n\n    public static function boot()\n    {\n        static::addGlobalScope(ActiveScope::class);\n\n        parent::boot();\n    }\n}\n\nclass EloquentGlobalScopesArrayTestModel extends Model\n{\n    protected $table = 'table';\n\n    public static function boot()\n    {\n        static::addGlobalScopes([\n            'active_scope' => new ActiveScope,\n            fn ($query) => $query->orderBy('name'),\n        ]);\n\n        parent::boot();\n    }\n}\n\n#[ScopedBy(ActiveScope::class)]\nclass EloquentGlobalScopeInAttributeTestModel extends Model\n{\n    protected $table = 'table';\n}\n\nclass ActiveScope implements Scope\n{\n    public function apply(Builder $builder, Model $model)\n    {\n        return $builder->where('active', 1);\n    }\n}\n\n#[ScopedBy(ActiveScope::class)]\ntrait EloquentGlobalScopeInInheritedAttributeTestTrait\n{\n    //\n}\n\nclass EloquentGlobalScopeInInheritedAttributeTestModel extends Model\n{\n    use EloquentGlobalScopeInInheritedAttributeTestTrait;\n\n    protected $table = 'table';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasManyCreateOrFirstTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasManyCreateOrFirstTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Carbon::setTestNow('2023-01-01 00:00:00');\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('createOrFirstValues')]\n    public function testCreateOrFirstMethodCreatesNewRecord(Closure|array $values): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite', [456]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)',\n            ['foo', 'bar', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->children()->createOrFirst(['attr' => 'foo'], $values);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testCreateOrFirstMethodRetrievesExistingRecord(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $sql = 'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], false, [])\n            ->andReturn([[\n                'id' => 456,\n                'parent_id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $model->children()->createOrFirst(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodCreatesNewRecord(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite', [456]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([]);\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)',\n            ['foo', 'bar', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesExistingRecord(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([[\n                'id' => 456,\n                'parent_id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01T00:00:00.000000Z',\n                'updated_at' => '2023-01-01T00:00:00.000000Z',\n            ]]);\n\n        $result = $model->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([]);\n\n        $sql = 'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], false, [])\n            ->andReturn([[\n                'id' => 456,\n                'parent_id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $model->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewRecord(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite', [456]);\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([]);\n\n        $model->getConnection()->expects('insert')->with(\n            'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)',\n            ['foo', 'bar', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $model->children()->updateOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesExistingRecord(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([[\n                'id' => 456,\n                'parent_id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01T00:00:00.000000Z',\n                'updated_at' => '2023-01-01T00:00:00.000000Z',\n            ]]);\n\n        $model->getConnection()->expects('update')->with(\n            'update \"child_table\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n            ['baz', '2023-01-01 00:00:00', 456],\n        )->andReturn(1);\n\n        $result = $model->children()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void\n    {\n        $model = new HasManyCreateOrFirstTestParentModel();\n        $model->id = 123;\n        $this->mockConnectionForModel($model, 'SQLite');\n        $model->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $model->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], true, [])\n            ->andReturn([]);\n\n        $sql = 'insert into \"child_table\" (\"attr\", \"val\", \"parent_id\", \"updated_at\", \"created_at\") values (?, ?, ?, ?, ?)';\n        $bindings = ['foo', 'baz', 123, '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $model->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $model->getConnection()\n            ->expects('select')\n            ->with('select * from \"child_table\" where \"child_table\".\"parent_id\" = ? and \"child_table\".\"parent_id\" is not null and (\"attr\" = ?) limit 1', [123, 'foo'], false, [])\n            ->andReturn([[\n                'id' => 456,\n                'parent_id' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $model->getConnection()->expects('update')->with(\n            'update \"child_table\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n            ['baz', '2023-01-01 00:00:00', 456],\n        )->andReturn(1);\n\n        $result = $model->children()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 456,\n            'parent_id' => 123,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public static function createOrFirstValues(): array\n    {\n        return [\n            'array' => [['val' => 'bar']],\n            'closure' => [fn () => ['val' => 'bar']],\n        ];\n    }\n\n    protected function mockConnectionForModel(Model $model, string $database, array $lastInsertIds = []): void\n    {\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$database.'Grammar';\n        $processorClass = 'Illuminate\\Database\\Query\\Processors\\\\'.$database.'Processor';\n        $processor = new $processorClass;\n        $connection = m::mock(Connection::class, ['getPostProcessor' => $processor]);\n        $grammar = new $grammarClass($connection);\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new Builder($connection, $grammar, $processor);\n        });\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $connection]);\n\n        $class = get_class($model);\n        $class::setConnectionResolver($resolver);\n\n        $connection->shouldReceive('getPdo')->andReturn($pdo = m::mock(PDO::class));\n\n        foreach ($lastInsertIds as $id) {\n            $pdo->expects('lastInsertId')->andReturn($id);\n        }\n    }\n}\n\n/**\n * @property int $id\n */\nclass HasManyCreateOrFirstTestParentModel extends Model\n{\n    protected $table = 'parent_table';\n    protected $guarded = [];\n\n    public function children(): HasMany\n    {\n        return $this->hasMany(HasManyCreateOrFirstTestChildModel::class, 'parent_id');\n    }\n}\n\n/**\n * @property int $id\n * @property int $parent_id\n */\nclass HasManyCreateOrFirstTestChildModel extends Model\n{\n    protected $table = 'child_table';\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentHasManyTest extends TestCase\n{\n    public function testMakeMethodDoesNotSaveNewModel()\n    {\n        $relation = $this->getRelation();\n        $instance = $this->expectNewModel($relation, ['name' => 'taylor']);\n        $instance->expects($this->never())->method('save');\n\n        $this->assertEquals($instance, $relation->make(['name' => 'taylor']));\n    }\n\n    public function testMakeManyCreatesARelatedModelForEachRecord()\n    {\n        $records = [\n            'taylor' => ['name' => 'taylor'],\n            'colin' => ['name' => 'colin'],\n        ];\n\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('newCollection')->once()->andReturn(new Collection);\n\n        $taylor = $this->expectNewModel($relation, ['name' => 'taylor']);\n        $taylor->expects($this->never())->method('save');\n        $colin = $this->expectNewModel($relation, ['name' => 'colin']);\n        $colin->expects($this->never())->method('save');\n\n        $instances = $relation->makeMany($records);\n        $this->assertInstanceOf(Collection::class, $instances);\n        $this->assertEquals($taylor, $instances[0]);\n        $this->assertEquals($colin, $instances[1]);\n    }\n\n    public function testCreateMethodProperlyCreatesNewModel()\n    {\n        $relation = $this->getRelation();\n        $created = $this->expectCreatedModel($relation, ['name' => 'taylor']);\n\n        $this->assertEquals($created, $relation->create(['name' => 'taylor']));\n    }\n\n    public function testForceCreateMethodProperlyCreatesNewModel()\n    {\n        $relation = $this->getRelation();\n        $created = $this->expectForceCreatedModel($relation, ['name' => 'taylor']);\n\n        $this->assertEquals($created, $relation->forceCreate(['name' => 'taylor']));\n        $this->assertEquals(1, $created->getAttribute('foreign_key'));\n    }\n\n    public function testFindOrNewMethodFindsModel()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('find')->once()->with('foo', ['*'])->andReturn($model = m::mock(stdClass::class));\n        $model->shouldReceive('setAttribute')->never();\n\n        $this->assertInstanceOf(stdClass::class, $relation->findOrNew('foo'));\n    }\n\n    public function testFindOrNewMethodReturnsNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('find')->once()->with('foo', ['*'])->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with()->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n\n        $this->assertInstanceOf(Model::class, $relation->findOrNew('foo'));\n    }\n\n    public function testFirstOrNewMethodFindsFirstModel()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n        $model->shouldReceive('setAttribute')->never();\n\n        $this->assertInstanceOf(stdClass::class, $relation->firstOrNew(['foo']));\n    }\n\n    public function testFirstOrNewMethodWithValuesFindsFirstModel()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n\n        $this->assertInstanceOf(stdClass::class, $relation->firstOrNew(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrNewMethodReturnsNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $model = $this->expectNewModel($relation, ['foo']);\n\n        $this->assertEquals($model, $relation->firstOrNew(['foo']));\n    }\n\n    public function testFirstOrNewMethodWithValuesCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $model = $this->expectNewModel($relation, ['foo' => 'bar', 'baz' => 'qux']);\n\n        $this->assertEquals($model, $relation->firstOrNew(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrCreateMethodFindsFirstModel()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(stdClass::class, $relation->firstOrCreate(['foo']));\n    }\n\n    public function testFirstOrCreateMethodWithValuesFindsFirstModel()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(stdClass::class, $relation->firstOrCreate(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrCreateMethodCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(fn ($scope) => $scope());\n        $model = $this->expectCreatedModel($relation, ['foo']);\n\n        $this->assertEquals($model, $relation->firstOrCreate(['foo']));\n    }\n\n    public function testFirstOrCreateMethodWithValuesCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(fn ($scope) => $scope());\n        $model = $this->expectCreatedModel($relation, ['foo' => 'bar', 'baz' => 'qux']);\n\n        $this->assertEquals($model, $relation->firstOrCreate(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testCreateOrFirstMethodWithValuesFindsFirstModel()\n    {\n        $relation = $this->getRelation();\n\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo' => 'bar', 'baz' => 'qux'])->andReturn(m::mock(Model::class, function ($model) {\n            $model->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n            $model->shouldReceive('save')->once()->andThrow(\n                new UniqueConstraintViolationException('mysql', 'example mysql', [], new Exception('SQLSTATE[23000]: Integrity constraint violation: 1062')),\n            );\n        }));\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('useWritePdo')->once()->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n\n        $this->assertInstanceOf(stdClass::class, $found = $relation->createOrFirst(['foo' => 'bar'], ['baz' => 'qux']));\n        $this->assertSame($model, $found);\n    }\n\n    public function testCreateOrFirstMethodCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->never();\n        $relation->getQuery()->shouldReceive('first')->never();\n        $model = $this->expectCreatedModel($relation, ['foo']);\n\n        $this->assertEquals($model, $relation->createOrFirst(['foo']));\n    }\n\n    public function testCreateOrFirstMethodWithValuesCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->never();\n        $relation->getQuery()->shouldReceive('first')->never();\n        $model = $this->expectCreatedModel($relation, ['foo' => 'bar', 'baz' => 'qux']);\n\n        $this->assertEquals($model, $relation->createOrFirst(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testUpdateOrCreateMethodFindsFirstModelAndUpdates()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(stdClass::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n\n        $model->wasRecentlyCreated = false;\n        $model->shouldReceive('fill')->once()->with(['bar'])->andReturn($model);\n        $model->shouldReceive('save')->once();\n\n        $this->assertInstanceOf(stdClass::class, $relation->updateOrCreate(['foo'], ['bar']));\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewModelWithForeignKeySet()\n    {\n        $relation = $this->getRelation();\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo', 'bar'])->andReturn($model = m::mock(Model::class));\n\n        $model->wasRecentlyCreated = true;\n        $model->shouldReceive('save')->once()->andReturn(true);\n        $model->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n\n        $this->assertInstanceOf(Model::class, $relation->updateOrCreate(['foo'], ['bar']));\n    }\n\n    public function testRelationUpsertFillsForeignKey()\n    {\n        $relation = $this->getRelation();\n\n        $relation->getQuery()->shouldReceive('upsert')->once()->with(\n            [\n                ['email' => 'foo3', 'name' => 'bar', $relation->getForeignKeyName() => $relation->getParentKey()],\n            ],\n            ['email'],\n            ['name']\n        );\n\n        $relation->upsert(\n            ['email' => 'foo3', 'name' => 'bar'],\n            ['email'],\n            ['name']\n        );\n\n        $relation->getQuery()->shouldReceive('upsert')->once()->with(\n            [\n                ['email' => 'foo3', 'name' => 'bar', $relation->getForeignKeyName() => $relation->getParentKey()],\n                ['name' => 'bar2', 'email' => 'foo2', $relation->getForeignKeyName() => $relation->getParentKey()],\n            ],\n            ['email'],\n            ['name']\n        );\n\n        $relation->upsert(\n            [\n                ['email' => 'foo3', 'name' => 'bar'],\n                ['name' => 'bar2', 'email' => 'foo2'],\n            ],\n            ['email'],\n            ['name']\n        );\n    }\n\n    public function testRelationIsProperlyInitialized()\n    {\n        $relation = $this->getRelation();\n        $model = m::mock(Model::class);\n        $relation->getRelated()->shouldReceive('newCollection')->andReturnUsing(function ($array = []) {\n            return new Collection($array);\n        });\n        $model->shouldReceive('setRelation')->once()->with('foo', m::type(Collection::class));\n        $models = $relation->initRelation([$model], 'foo');\n\n        $this->assertEquals([$model], $models);\n    }\n\n    public function testEagerConstraintsAreProperlyAdded()\n    {\n        $relation = $this->getRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->once()->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('table.foreign_key', [1, 2]);\n        $model1 = new EloquentHasManyModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentHasManyModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    public function testEagerConstraintsAreProperlyAddedWithStringKey()\n    {\n        $relation = $this->getRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->once()->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('string');\n        $relation->getQuery()->shouldReceive('whereIn')->once()->with('table.foreign_key', [1, 2]);\n        $model1 = new EloquentHasManyModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentHasManyModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    public function testModelsAreProperlyMatchedToParents()\n    {\n        $relation = $this->getRelation();\n\n        $result1 = new EloquentHasManyModelStub;\n        $result1->foreign_key = 1;\n        $result2 = new EloquentHasManyModelStub;\n        $result2->foreign_key = 2;\n        $result3 = new EloquentHasManyModelStub;\n        $result3->foreign_key = 2;\n\n        $model1 = new EloquentHasManyModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentHasManyModelStub;\n        $model2->id = 2;\n        $model3 = new EloquentHasManyModelStub;\n        $model3->id = 3;\n\n        $relation->getRelated()->shouldReceive('newCollection')->andReturnUsing(function ($array) {\n            return new Collection($array);\n        });\n        $models = $relation->match([$model1, $model2, $model3], new Collection([$result1, $result2, $result3]), 'foo');\n\n        $this->assertEquals(1, $models[0]->foo[0]->foreign_key);\n        $this->assertCount(1, $models[0]->foo);\n        $this->assertEquals(2, $models[1]->foo[0]->foreign_key);\n        $this->assertEquals(2, $models[1]->foo[1]->foreign_key);\n        $this->assertCount(2, $models[1]->foo);\n        $this->assertNull($models[2]->foo);\n    }\n\n    public function testCreateManyCreatesARelatedModelForEachRecord()\n    {\n        $records = [\n            'taylor' => ['name' => 'taylor'],\n            'colin' => ['name' => 'colin'],\n        ];\n\n        $relation = $this->getRelation();\n        $relation->getRelated()->shouldReceive('newCollection')->once()->andReturn(new Collection);\n\n        $taylor = $this->expectCreatedModel($relation, ['name' => 'taylor']);\n        $colin = $this->expectCreatedModel($relation, ['name' => 'colin']);\n\n        $instances = $relation->createMany($records);\n        $this->assertInstanceOf(Collection::class, $instances);\n        $this->assertEquals($taylor, $instances[0]);\n        $this->assertEquals($colin, $instances[1]);\n    }\n\n    protected function getRelation()\n    {\n        $queryBuilder = m::mock(QueryBuilder::class);\n        $builder = m::mock(Builder::class, [$queryBuilder]);\n        $builder->shouldReceive('whereNotNull')->with('table.foreign_key');\n        $builder->shouldReceive('where')->with('table.foreign_key', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n\n        return new HasMany($builder, $parent, 'table.foreign_key', 'id');\n    }\n\n    protected function expectNewModel($relation, $attributes = null)\n    {\n        $model = $this->getMockBuilder(Model::class)->onlyMethods(['setAttribute', 'save'])->getMock();\n        $relation->getRelated()->shouldReceive('newInstance')->with($attributes)->andReturn($model);\n        $model->expects($this->once())->method('setAttribute')->with('foreign_key', 1);\n\n        return $model;\n    }\n\n    protected function expectCreatedModel($relation, $attributes)\n    {\n        $model = $this->expectNewModel($relation, $attributes);\n        $model->expects($this->once())->method('save');\n\n        return $model;\n    }\n\n    protected function expectForceCreatedModel($relation, $attributes)\n    {\n        $attributes[$relation->getForeignKeyName()] = $relation->getParentKey();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->with($relation->getForeignKeyName())->andReturn($relation->getParentKey());\n\n        $relation->getRelated()->shouldReceive('forceCreate')->once()->with($attributes)->andReturn($model);\n\n        return $model;\n    }\n}\n\nclass EloquentHasManyModelStub extends Model\n{\n    public $foreign_key = 'foreign.value';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasManyThroughCreateOrFirstTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasManyThroughCreateOrFirstTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Carbon::setTestNow('2023-01-01 00:00:00');\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('createOrFirstValues')]\n    public function testCreateOrFirstMethodCreatesNewRecord(Closure|array $values): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $this->mockConnectionForModel($parent, 'SQLite', [789]);\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n        $parent->getConnection()->expects('insert')->with(\n            'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $parent->children()->createOrFirst(['attr' => 'foo'], $values);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testCreateOrFirstMethodRetrievesExistingRecord(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite');\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $sql = 'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $parent->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 789,\n                'pivot_id' => 456,\n                'laravel_through_key' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $parent->children()->createOrFirst(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'pivot_id' => 456,\n            'laravel_through_key' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodCreatesNewRecord(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite', [789]);\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $parent->getConnection()->expects('insert')->with(\n            'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n            ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n        )->andReturnTrue();\n\n        $result = $parent->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesExistingRecord(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite');\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 789,\n                'pivot_id' => 456,\n                'laravel_through_key' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01 00:00:00',\n                'updated_at' => '2023-01-01 00:00:00',\n            ]]);\n\n        $result = $parent->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'pivot_id' => 456,\n            'laravel_through_key' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite');\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $sql = 'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $parent->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ? and \"val\" = ?) limit 1',\n                [123, 'foo', 'bar'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 789,\n                'pivot_id' => 456,\n                'laravel_through_key' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01T00:00:00.000000Z',\n                'updated_at' => '2023-01-01T00:00:00.000000Z',\n            ]]);\n\n        $result = $parent->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'pivot_id' => 456,\n            'laravel_through_key' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewRecord(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite', [789]);\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $parent->getConnection()\n            ->expects('insert')\n            ->with(\n                'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)',\n                ['foo', 'baz', '2023-01-01 00:00:00', '2023-01-01 00:00:00'],\n            )\n            ->andReturnTrue();\n\n        $result = $parent->children()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertTrue($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesExistingRecord(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite');\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 789,\n                'pivot_id' => 456,\n                'laravel_through_key' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01T00:00:00.000000Z',\n                'updated_at' => '2023-01-01T00:00:00.000000Z',\n            ]]);\n\n        $parent->getConnection()\n            ->expects('update')\n            ->with(\n                'update \"child\" set \"val\" = ?, \"updated_at\" = ? where \"id\" = ?',\n                ['baz', '2023-01-01 00:00:00', 789],\n            )\n            ->andReturn(1);\n\n        $result = $parent->children()->updateOrCreate(['attr' => 'foo'], ['val' => 'baz']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'pivot_id' => 456,\n            'laravel_through_key' => 123,\n            'attr' => 'foo',\n            'val' => 'baz',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public function testUpdateOrCreateMethodUpdatesRecordCreatedJustNow(): void\n    {\n        $parent = new HasManyThroughCreateOrFirstTestParentModel();\n        $parent->id = 123;\n        $parent->exists = true;\n        $this->mockConnectionForModel($parent, 'SQLite');\n        $parent->getConnection()->shouldReceive('transactionLevel')->andReturn(0);\n        $parent->getConnection()->shouldReceive('getName')->andReturn('sqlite');\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ?) limit 1',\n                [123, 'foo'],\n                true,\n                [],\n            )\n            ->andReturn([]);\n\n        $sql = 'insert into \"child\" (\"attr\", \"val\", \"updated_at\", \"created_at\") values (?, ?, ?, ?)';\n        $bindings = ['foo', 'bar', '2023-01-01 00:00:00', '2023-01-01 00:00:00'];\n\n        $parent->getConnection()\n            ->expects('insert')\n            ->with($sql, $bindings)\n            ->andThrow(new UniqueConstraintViolationException('sqlite', $sql, $bindings, new Exception()));\n\n        $parent->getConnection()\n            ->expects('select')\n            ->with(\n                'select \"child\".*, \"pivot\".\"parent_id\" as \"laravel_through_key\" from \"child\" inner join \"pivot\" on \"pivot\".\"id\" = \"child\".\"pivot_id\" where \"pivot\".\"parent_id\" = ? and (\"attr\" = ? and \"val\" = ?) limit 1',\n                [123, 'foo', 'bar'],\n                true,\n                [],\n            )\n            ->andReturn([[\n                'id' => 789,\n                'pivot_id' => 456,\n                'laravel_through_key' => 123,\n                'attr' => 'foo',\n                'val' => 'bar',\n                'created_at' => '2023-01-01T00:00:00.000000Z',\n                'updated_at' => '2023-01-01T00:00:00.000000Z',\n            ]]);\n\n        $result = $parent->children()->firstOrCreate(['attr' => 'foo'], ['val' => 'bar']);\n        $this->assertFalse($result->wasRecentlyCreated);\n        $this->assertEquals([\n            'id' => 789,\n            'pivot_id' => 456,\n            'laravel_through_key' => 123,\n            'attr' => 'foo',\n            'val' => 'bar',\n            'created_at' => '2023-01-01T00:00:00.000000Z',\n            'updated_at' => '2023-01-01T00:00:00.000000Z',\n        ], $result->toArray());\n    }\n\n    public static function createOrFirstValues(): array\n    {\n        return [\n            'array' => [['val' => 'bar']],\n            'closure' => [fn () => ['val' => 'bar']],\n        ];\n    }\n\n    protected function mockConnectionForModel(Model $model, string $database, array $lastInsertIds = []): void\n    {\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$database.'Grammar';\n        $processorClass = 'Illuminate\\Database\\Query\\Processors\\\\'.$database.'Processor';\n        $processor = new $processorClass;\n        $connection = m::mock(Connection::class, ['getPostProcessor' => $processor]);\n        $grammar = new $grammarClass($connection);\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new Builder($connection, $grammar, $processor);\n        });\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $connection]);\n\n        $class = get_class($model);\n        $class::setConnectionResolver($resolver);\n\n        $connection->shouldReceive('getPdo')->andReturn($pdo = m::mock(PDO::class));\n\n        foreach ($lastInsertIds as $id) {\n            $pdo->expects('lastInsertId')->andReturn($id);\n        }\n    }\n}\n\n/**\n * @property int $id\n * @property int $pivot_id\n */\nclass HasManyThroughCreateOrFirstTestChildModel extends Model\n{\n    protected $table = 'child';\n    protected $guarded = [];\n}\n\n/**\n * @property int $id\n * @property int $parent_id\n */\nclass HasManyThroughCreateOrFirstTestPivotModel extends Model\n{\n    protected $table = 'pivot';\n    protected $guarded = [];\n}\n\n/**\n * @property int $id\n */\nclass HasManyThroughCreateOrFirstTestParentModel extends Model\n{\n    protected $table = 'parent';\n    protected $guarded = [];\n\n    public function children(): HasManyThrough\n    {\n        return $this->hasManyThrough(\n            HasManyThroughCreateOrFirstTestChildModel::class,\n            HasManyThroughCreateOrFirstTestPivotModel::class,\n            'parent_id',\n            'pivot_id',\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasManyThroughIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasManyThroughIntegrationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->unsignedInteger('country_id');\n            $table->string('country_short');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('posts', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->string('title');\n            $table->text('body');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('countries', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('shortname');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('posts');\n        $this->schema()->drop('countries');\n\n        parent::tearDown();\n    }\n\n    public function testItLoadsAHasManyThroughRelationWithCustomKeys()\n    {\n        $this->seedData();\n        $posts = HasManyThroughTestCountry::first()->posts;\n\n        $this->assertSame('A title', $posts[0]->title);\n        $this->assertCount(2, $posts);\n    }\n\n    public function testItLoadsADefaultHasManyThroughRelation()\n    {\n        $this->migrateDefault();\n        $this->seedDefaultData();\n\n        $posts = HasManyThroughDefaultTestCountry::first()->posts;\n        $this->assertSame('A title', $posts[0]->title);\n        $this->assertCount(2, $posts);\n\n        $this->resetDefault();\n    }\n\n    public function testItLoadsARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $posts = HasManyThroughIntermediateTestCountry::first()->posts;\n\n        $this->assertSame('A title', $posts[0]->title);\n        $this->assertCount(2, $posts);\n    }\n\n    public function testEagerLoadingARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $posts = HasManyThroughIntermediateTestCountry::with('posts')->first()->posts;\n\n        $this->assertSame('A title', $posts[0]->title);\n        $this->assertCount(2, $posts);\n    }\n\n    public function testWhereHasOnARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $country = HasManyThroughIntermediateTestCountry::whereHas('posts', function ($query) {\n            $query->where('title', 'A title');\n        })->get();\n\n        $this->assertCount(1, $country);\n    }\n\n    public function testWithWhereHasOnARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $country = HasManyThroughIntermediateTestCountry::withWhereHas('posts', function ($query) {\n            $query->where('title', 'A title');\n        })->get();\n\n        $this->assertCount(1, $country);\n        $this->assertTrue($country->first()->relationLoaded('posts'));\n        $this->assertEquals($country->first()->posts->pluck('title')->unique()->toArray(), ['A title']);\n    }\n\n    public function testFindMethod()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->createMany([\n                ['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com'],\n                ['id' => 2, 'title' => 'Another title', 'body' => 'Another body', 'email' => 'taylorotwell@gmail.com'],\n            ]);\n\n        $country = HasManyThroughTestCountry::first();\n        $post = $country->posts()->find(1);\n\n        $this->assertNotNull($post);\n        $this->assertSame('A title', $post->title);\n\n        $this->assertCount(2, $country->posts()->find([1, 2]));\n        $this->assertCount(2, $country->posts()->find(new Collection([1, 2])));\n    }\n\n    public function testFindManyMethod()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->createMany([\n                ['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com'],\n                ['id' => 2, 'title' => 'Another title', 'body' => 'Another body', 'email' => 'taylorotwell@gmail.com'],\n            ]);\n\n        $country = HasManyThroughTestCountry::first();\n\n        $this->assertCount(2, $country->posts()->findMany([1, 2]));\n        $this->assertCount(2, $country->posts()->findMany(new Collection([1, 2])));\n    }\n\n    public function testFirstOrFailThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\HasManyThroughTestPost].');\n\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us']);\n\n        HasManyThroughTestCountry::first()->posts()->firstOrFail();\n    }\n\n    public function testFindOrFailThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\HasManyThroughTestPost] 1');\n\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us']);\n\n        HasManyThroughTestCountry::first()->posts()->findOrFail(1);\n    }\n\n    public function testFindOrFailWithManyThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\HasManyThroughTestPost] 1, 2');\n\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->create(['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com']);\n\n        HasManyThroughTestCountry::first()->posts()->findOrFail([1, 2]);\n    }\n\n    public function testFindOrFailWithManyUsingCollectionThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\HasManyThroughTestPost] 1, 2');\n\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->create(['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com']);\n\n        HasManyThroughTestCountry::first()->posts()->findOrFail(new Collection([1, 2]));\n    }\n\n    public function testFindOrMethod()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->create(['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com']);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(1, fn () => 'callback result');\n        $this->assertInstanceOf(HasManyThroughTestPost::class, $result);\n        $this->assertSame(1, $result->id);\n        $this->assertSame('A title', $result->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(1, ['posts.id'], fn () => 'callback result');\n        $this->assertInstanceOf(HasManyThroughTestPost::class, $result);\n        $this->assertSame(1, $result->id);\n        $this->assertNull($result->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(2, fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFindOrMethodWithMany()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->createMany([\n                ['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com'],\n                ['id' => 2, 'title' => 'Another title', 'body' => 'Another body', 'email' => 'taylorotwell@gmail.com'],\n            ]);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr([1, 2], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertSame('A title', $result[0]->title);\n        $this->assertSame('Another title', $result[1]->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr([1, 2], ['posts.id'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNull($result[0]->title);\n        $this->assertNull($result[1]->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr([1, 2, 3], fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFindOrMethodWithManyUsingCollection()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->createMany([\n                ['id' => 1, 'title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com'],\n                ['id' => 2, 'title' => 'Another title', 'body' => 'Another body', 'email' => 'taylorotwell@gmail.com'],\n            ]);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(new Collection([1, 2]), fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertSame('A title', $result[0]->title);\n        $this->assertSame('Another title', $result[1]->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(new Collection([1, 2]), ['posts.id'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNull($result[0]->title);\n        $this->assertNull($result[1]->title);\n\n        $result = HasManyThroughTestCountry::first()->posts()->findOr(new Collection([1, 2, 3]), fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFirstRetrievesFirstRecord()\n    {\n        $this->seedData();\n        $post = HasManyThroughTestCountry::first()->posts()->first();\n\n        $this->assertNotNull($post);\n        $this->assertSame('A title', $post->title);\n    }\n\n    public function testAllColumnsAreRetrievedByDefault()\n    {\n        $this->seedData();\n        $post = HasManyThroughTestCountry::first()->posts()->first();\n        $this->assertEquals([\n            'id',\n            'user_id',\n            'title',\n            'body',\n            'email',\n            'created_at',\n            'updated_at',\n            'laravel_through_key',\n        ], array_keys($post->getAttributes()));\n    }\n\n    public function testOnlyProperColumnsAreSelectedIfProvided()\n    {\n        $this->seedData();\n        $post = HasManyThroughTestCountry::first()->posts()->first(['title', 'body']);\n\n        $this->assertEquals([\n            'title',\n            'body',\n            'laravel_through_key',\n        ], array_keys($post->getAttributes()));\n    }\n\n    public function testChunkReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $country->posts()->chunk(10, function ($postsChunk) {\n            $post = $postsChunk->first();\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        });\n    }\n\n    public function testChunkById()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $i = 0;\n        $count = 0;\n\n        $country->posts()->chunkById(2, function ($collection) use (&$i, &$count) {\n            $i++;\n            $count += $collection->count();\n        });\n\n        $this->assertEquals(3, $i);\n        $this->assertEquals(6, $count);\n    }\n\n    public function testCursorReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $posts = $country->posts()->cursor();\n\n        $this->assertInstanceOf(LazyCollection::class, $posts);\n\n        foreach ($posts as $post) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        }\n    }\n\n    public function testEachReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $country->posts()->each(function ($post) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        });\n    }\n\n    public function testEachByIdReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $country->posts()->eachById(function ($post) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        });\n    }\n\n    public function testLazyReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $country->posts()->lazy(10)->each(function ($post) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        });\n    }\n\n    public function testLazyById()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $country = HasManyThroughTestCountry::find(2);\n\n        $i = 0;\n\n        $country->posts()->lazyById(2)->each(function ($post) use (&$i, &$count) {\n            $i++;\n\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key',\n            ], array_keys($post->getAttributes()));\n        });\n\n        $this->assertEquals(6, $i);\n    }\n\n    public function testIntermediateSoftDeletesAreIgnored()\n    {\n        $this->seedData();\n        HasManyThroughSoftDeletesTestUser::first()->delete();\n\n        $posts = HasManyThroughSoftDeletesTestCountry::first()->posts;\n\n        $this->assertSame('A title', $posts[0]->title);\n        $this->assertCount(2, $posts);\n    }\n\n    public function testEagerLoadingLoadsRelatedModelsCorrectly()\n    {\n        $this->seedData();\n        $country = HasManyThroughSoftDeletesTestCountry::with('posts')->first();\n\n        $this->assertSame('us', $country->shortname);\n        $this->assertSame('A title', $country->posts[0]->title);\n        $this->assertCount(2, $country->posts);\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        HasManyThroughTestCountry::create(['id' => 1, 'name' => 'United States of America', 'shortname' => 'us'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'country_short' => 'us'])\n            ->posts()->createMany([\n                ['title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com'],\n                ['title' => 'Another title', 'body' => 'Another body', 'email' => 'taylorotwell@gmail.com'],\n            ]);\n    }\n\n    protected function seedDataExtended()\n    {\n        $country = HasManyThroughTestCountry::create(['id' => 2, 'name' => 'United Kingdom', 'shortname' => 'uk']);\n        $country->users()->create(['id' => 2, 'email' => 'example1@gmail.com', 'country_short' => 'uk'])\n            ->posts()->createMany([\n                ['title' => 'Example1 title1', 'body' => 'Example1 body1', 'email' => 'example1post1@gmail.com'],\n                ['title' => 'Example1 title2', 'body' => 'Example1 body2', 'email' => 'example1post2@gmail.com'],\n            ]);\n        $country->users()->create(['id' => 3, 'email' => 'example2@gmail.com', 'country_short' => 'uk'])\n            ->posts()->createMany([\n                ['title' => 'Example2 title1', 'body' => 'Example2 body1', 'email' => 'example2post1@gmail.com'],\n                ['title' => 'Example2 title2', 'body' => 'Example2 body2', 'email' => 'example2post2@gmail.com'],\n            ]);\n        $country->users()->create(['id' => 4, 'email' => 'example3@gmail.com', 'country_short' => 'uk'])\n            ->posts()->createMany([\n                ['title' => 'Example3 title1', 'body' => 'Example3 body1', 'email' => 'example3post1@gmail.com'],\n                ['title' => 'Example3 title2', 'body' => 'Example3 body2', 'email' => 'example3post2@gmail.com'],\n            ]);\n    }\n\n    /**\n     * Seed data for a default HasManyThrough setup.\n     */\n    protected function seedDefaultData()\n    {\n        HasManyThroughDefaultTestCountry::create(['id' => 1, 'name' => 'United States of America'])\n            ->users()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com'])\n            ->posts()->createMany([\n                ['title' => 'A title', 'body' => 'A body'],\n                ['title' => 'Another title', 'body' => 'Another body'],\n            ]);\n    }\n\n    /**\n     * Drop the default tables.\n     */\n    protected function resetDefault()\n    {\n        $this->schema()->drop('users_default');\n        $this->schema()->drop('posts_default');\n        $this->schema()->drop('countries_default');\n    }\n\n    /**\n     * Migrate tables for classes with a Laravel \"default\" HasManyThrough setup.\n     */\n    protected function migrateDefault()\n    {\n        $this->schema()->create('users_default', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->unsignedInteger('has_many_through_default_test_country_id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('posts_default', function ($table) {\n            $table->increments('id');\n            $table->integer('has_many_through_default_test_user_id');\n            $table->string('title');\n            $table->text('body');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('countries_default', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasManyThroughTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(HasManyThroughTestPost::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasManyThroughTestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasManyThroughTestUser::class, 'user_id');\n    }\n}\n\nclass HasManyThroughTestCountry extends Eloquent\n{\n    protected $table = 'countries';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasManyThrough(HasManyThroughTestPost::class, HasManyThroughTestUser::class, 'country_id', 'user_id');\n    }\n\n    public function users()\n    {\n        return $this->hasMany(HasManyThroughTestUser::class, 'country_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasManyThroughDefaultTestUser extends Eloquent\n{\n    protected $table = 'users_default';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(HasManyThroughDefaultTestPost::class);\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasManyThroughDefaultTestPost extends Eloquent\n{\n    protected $table = 'posts_default';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasManyThroughDefaultTestUser::class);\n    }\n}\n\nclass HasManyThroughDefaultTestCountry extends Eloquent\n{\n    protected $table = 'countries_default';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasManyThrough(HasManyThroughDefaultTestPost::class, HasManyThroughDefaultTestUser::class);\n    }\n\n    public function users()\n    {\n        return $this->hasMany(HasManyThroughDefaultTestUser::class);\n    }\n}\n\nclass HasManyThroughIntermediateTestCountry extends Eloquent\n{\n    protected $table = 'countries';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasManyThrough(HasManyThroughTestPost::class, HasManyThroughTestUser::class, 'country_short', 'email', 'shortname', 'email');\n    }\n\n    public function users()\n    {\n        return $this->hasMany(HasManyThroughTestUser::class, 'country_id');\n    }\n}\n\nclass HasManyThroughSoftDeletesTestUser extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(HasManyThroughSoftDeletesTestPost::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasManyThroughSoftDeletesTestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasManyThroughSoftDeletesTestUser::class, 'user_id');\n    }\n}\n\nclass HasManyThroughSoftDeletesTestCountry extends Eloquent\n{\n    protected $table = 'countries';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasManyThrough(HasManyThroughSoftDeletesTestPost::class, HasManyThroughTestUser::class, 'country_id', 'user_id');\n    }\n\n    public function users()\n    {\n        return $this->hasMany(HasManyThroughSoftDeletesTestUser::class, 'country_id');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneOfManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneOfManyTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n        });\n\n        $this->schema()->create('logins', function ($table) {\n            $table->increments('id');\n            $table->foreignId('user_id');\n            $table->dateTime('deleted_at')->nullable();\n        });\n\n        $this->schema()->create('states', function ($table) {\n            $table->increments('id');\n            $table->string('state');\n            $table->string('type');\n            $table->foreignId('user_id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('prices', function ($table) {\n            $table->increments('id');\n            $table->dateTime('published_at');\n            $table->foreignId('user_id');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('logins');\n        $this->schema()->drop('states');\n        $this->schema()->drop('prices');\n\n        parent::tearDown();\n    }\n\n    public function testItGuessesRelationName()\n    {\n        $user = HasOneOfManyTestUser::make();\n        $this->assertSame('latest_login', $user->latest_login()->getRelationName());\n    }\n\n    public function testItGuessesRelationNameAndAddsOfManyWhenTableNameIsRelationName()\n    {\n        $model = HasOneOfManyTestModel::make();\n        $this->assertSame('logins_of_many', $model->logins()->getRelationName());\n    }\n\n    public function testRelationNameCanBeSet()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        // Using \"ofMany\"\n        $relation = $user->latest_login()->ofMany('id', 'max', 'foo');\n        $this->assertSame('foo', $relation->getRelationName());\n\n        // Using \"latestOfMAny\"\n        $relation = $user->latest_login()->latestOfMAny('id', 'bar');\n        $this->assertSame('bar', $relation->getRelationName());\n\n        // Using \"oldestOfMAny\"\n        $relation = $user->latest_login()->oldestOfMAny('id', 'baz');\n        $this->assertSame('baz', $relation->getRelationName());\n    }\n\n    public function testCorrectLatestOfManyQuery(): void\n    {\n        $user = HasOneOfManyTestUser::create();\n        $relation = $user->latest_login();\n        $this->assertSame('select \"logins\".* from \"logins\" inner join (select MAX(\"logins\".\"id\") as \"id_aggregate\", \"logins\".\"user_id\" from \"logins\" where \"logins\".\"user_id\" = ? and \"logins\".\"user_id\" is not null group by \"logins\".\"user_id\") as \"latest_login\" on \"latest_login\".\"id_aggregate\" = \"logins\".\"id\" and \"latest_login\".\"user_id\" = \"logins\".\"user_id\" where \"logins\".\"user_id\" = ? and \"logins\".\"user_id\" is not null', $relation->getQuery()->toSql());\n    }\n\n    public function testEagerLoadingAppliesConstraintsToInnerJoinSubQuery()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $relation = $user->latest_login();\n        $relation->addEagerConstraints([$user]);\n        $this->assertSame('select MAX(\"logins\".\"id\") as \"id_aggregate\", \"logins\".\"user_id\" from \"logins\" where \"logins\".\"user_id\" = ? and \"logins\".\"user_id\" is not null and \"logins\".\"user_id\" in (1) group by \"logins\".\"user_id\"', $relation->getOneOfManySubQuery()->toSql());\n    }\n\n    public function testGlobalScopeIsNotAppliedWhenRelationIsDefinedWithoutGlobalScope()\n    {\n        HasOneOfManyTestLogin::addGlobalScope('test', function ($query) {\n            $query->orderBy('id');\n        });\n\n        $user = HasOneOfManyTestUser::create();\n        $relation = $user->latest_login_without_global_scope();\n        $relation->addEagerConstraints([$user]);\n        $this->assertSame('select \"logins\".* from \"logins\" inner join (select MAX(\"logins\".\"id\") as \"id_aggregate\", \"logins\".\"user_id\" from \"logins\" where \"logins\".\"user_id\" = ? and \"logins\".\"user_id\" is not null and \"logins\".\"user_id\" in (1) group by \"logins\".\"user_id\") as \"latestOfMany\" on \"latestOfMany\".\"id_aggregate\" = \"logins\".\"id\" and \"latestOfMany\".\"user_id\" = \"logins\".\"user_id\" where \"logins\".\"user_id\" = ? and \"logins\".\"user_id\" is not null', $relation->getQuery()->toSql());\n\n        HasOneOfManyTestLogin::addGlobalScope('test', function ($query) {\n        });\n    }\n\n    public function testGlobalScopeIsNotAppliedWhenRelationIsDefinedWithoutGlobalScopeWithComplexQuery()\n    {\n        HasOneOfManyTestPrice::addGlobalScope('test', function ($query) {\n            $query->orderBy('id');\n        });\n\n        $user = HasOneOfManyTestUser::create();\n        $relation = $user->price_without_global_scope();\n        $this->assertSame('select \"prices\".* from \"prices\" inner join (select max(\"prices\".\"id\") as \"id_aggregate\", min(\"prices\".\"published_at\") as \"published_at_aggregate\", \"prices\".\"user_id\" from \"prices\" inner join (select max(\"prices\".\"published_at\") as \"published_at_aggregate\", \"prices\".\"user_id\" from \"prices\" where \"published_at\" < ? and \"prices\".\"user_id\" = ? and \"prices\".\"user_id\" is not null group by \"prices\".\"user_id\") as \"price_without_global_scope\" on \"price_without_global_scope\".\"published_at_aggregate\" = \"prices\".\"published_at\" and \"price_without_global_scope\".\"user_id\" = \"prices\".\"user_id\" where \"published_at\" < ? group by \"prices\".\"user_id\") as \"price_without_global_scope\" on \"price_without_global_scope\".\"id_aggregate\" = \"prices\".\"id\" and \"price_without_global_scope\".\"published_at_aggregate\" = \"prices\".\"published_at\" and \"price_without_global_scope\".\"user_id\" = \"prices\".\"user_id\" where \"prices\".\"user_id\" = ? and \"prices\".\"user_id\" is not null', $relation->getQuery()->toSql());\n\n        HasOneOfManyTestPrice::addGlobalScope('test', function ($query) {\n        });\n    }\n\n    public function testQualifyingSubSelectColumn()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $this->assertSame('latest_login.id', $user->latest_login()->qualifySubSelectColumn('id'));\n    }\n\n    public function testItFailsWhenUsingInvalidAggregate()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid aggregate [count] used within ofMany relation. Available aggregates: MIN, MAX');\n        $user = HasOneOfManyTestUser::make();\n        $user->latest_login_with_invalid_aggregate();\n    }\n\n    public function testItGetsCorrectResults()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $result = $user->latest_login()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($latestLogin->id, $result->id);\n    }\n\n    public function testResultDoesNotHaveAggregateColumn()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n\n        $result = $user->latest_login()->getResults();\n        $this->assertNotNull($result);\n        $this->assertFalse(isset($result->id_aggregate));\n    }\n\n    public function testItGetsCorrectResultsUsingShortcutMethod()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $result = $user->latest_login_with_shortcut()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($latestLogin->id, $result->id);\n    }\n\n    public function testItGetsCorrectResultsUsingShortcutReceivingMultipleColumnsMethod()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $result = $user->price_with_shortcut()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($price->id, $result->id);\n    }\n\n    public function testKeyIsAddedToAggregatesWhenMissing()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $result = $user->price_without_key_in_aggregates()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($price->id, $result->id);\n    }\n\n    public function testItGetsWithConstraintsCorrectResults()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $user->logins()->create();\n\n        $result = $user->latest_login()->whereKey($previousLogin->getKey())->getResults();\n        $this->assertNull($result);\n    }\n\n    public function testItEagerLoadsCorrectModels()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $user = HasOneOfManyTestUser::with('latest_login')->first();\n\n        $this->assertTrue($user->relationLoaded('latest_login'));\n        $this->assertSame($latestLogin->id, $user->latest_login->id);\n    }\n\n    public function testItJoinsOtherTableInSubQuery()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n\n        $this->assertNull($user->latest_login_with_foo_state);\n\n        $user->unsetRelation('latest_login_with_foo_state');\n        $user->states()->create([\n            'type' => 'foo',\n            'state' => 'draft',\n        ]);\n\n        $this->assertNotNull($user->latest_login_with_foo_state);\n    }\n\n    public function testHasNested()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $found = HasOneOfManyTestUser::whereHas('latest_login', function ($query) use ($latestLogin) {\n            $query->where('logins.id', $latestLogin->id);\n        })->exists();\n        $this->assertTrue($found);\n\n        $found = HasOneOfManyTestUser::whereHas('latest_login', function ($query) use ($previousLogin) {\n            $query->where('logins.id', $previousLogin->id);\n        })->exists();\n        $this->assertFalse($found);\n    }\n\n    public function testWithHasNested()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $found = HasOneOfManyTestUser::withWhereHas('latest_login', function ($query) use ($latestLogin) {\n            $query->where('logins.id', $latestLogin->id);\n        })->first();\n\n        $this->assertTrue((bool) $found);\n        $this->assertTrue($found->relationLoaded('latest_login'));\n        $this->assertEquals($found->latest_login->id, $latestLogin->id);\n\n        $found = HasOneOfManyTestUser::withWhereHas('latest_login', function ($query) use ($previousLogin) {\n            $query->where('logins.id', $previousLogin->id);\n        })->exists();\n\n        $this->assertFalse($found);\n    }\n\n    public function testHasCount()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n        $user->logins()->create();\n\n        $user = HasOneOfManyTestUser::withCount('latest_login')->first();\n        $this->assertEquals(1, $user->latest_login_count);\n    }\n\n    public function testExists()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $this->assertFalse($user->latest_login()->whereKey($previousLogin->getKey())->exists());\n        $this->assertTrue($user->latest_login()->whereKey($latestLogin->getKey())->exists());\n    }\n\n    public function testIsMethod()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $login1 = $user->latest_login()->create();\n        $login2 = $user->latest_login()->create();\n\n        $this->assertFalse($user->latest_login()->is($login1));\n        $this->assertTrue($user->latest_login()->is($login2));\n    }\n\n    public function testIsNotMethod()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $login1 = $user->latest_login()->create();\n        $login2 = $user->latest_login()->create();\n\n        $this->assertTrue($user->latest_login()->isNot($login1));\n        $this->assertFalse($user->latest_login()->isNot($login2));\n    }\n\n    public function testGet()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $previousLogin = $user->logins()->create();\n        $latestLogin = $user->logins()->create();\n\n        $latestLogins = $user->latest_login()->get();\n        $this->assertCount(1, $latestLogins);\n        $this->assertSame($latestLogin->id, $latestLogins->first()->id);\n\n        $latestLogins = $user->latest_login()->whereKey($previousLogin->getKey())->get();\n        $this->assertCount(0, $latestLogins);\n    }\n\n    public function testCount()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n        $user->logins()->create();\n\n        $this->assertSame(1, $user->latest_login()->count());\n    }\n\n    public function testAggregate()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $firstLogin = $user->logins()->create();\n        $user->logins()->create();\n\n        $user = HasOneOfManyTestUser::first();\n        $this->assertSame($firstLogin->id, $user->first_login->id);\n    }\n\n    public function testJoinConstraints()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->states()->create([\n            'type' => 'foo',\n            'state' => 'draft',\n        ]);\n        $currentForState = $user->states()->create([\n            'type' => 'foo',\n            'state' => 'active',\n        ]);\n        $user->states()->create([\n            'type' => 'bar',\n            'state' => 'baz',\n        ]);\n\n        $user = HasOneOfManyTestUser::first();\n        $this->assertSame($currentForState->id, $user->foo_state->id);\n    }\n\n    public function testMultipleAggregates()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $user = HasOneOfManyTestUser::first();\n        $this->assertSame($price->id, $user->price->id);\n    }\n\n    public function testEagerLoadingWithMultipleAggregates()\n    {\n        $user1 = HasOneOfManyTestUser::create();\n        $user2 = HasOneOfManyTestUser::create();\n\n        $user1->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user1Price = $user1->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user1->prices()->create([\n            'published_at' => '2021-04-01 00:00:00',\n        ]);\n\n        $user2Price = $user2->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user2->prices()->create([\n            'published_at' => '2021-04-01 00:00:00',\n        ]);\n\n        $users = HasOneOfManyTestUser::with('price')->get();\n\n        $this->assertNotNull($users[0]->price);\n        $this->assertSame($user1Price->id, $users[0]->price->id);\n\n        $this->assertNotNull($users[1]->price);\n        $this->assertSame($user2Price->id, $users[1]->price->id);\n    }\n\n    public function testWithExists()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        $user = HasOneOfManyTestUser::withExists('latest_login')->first();\n        $this->assertFalse($user->latest_login_exists);\n\n        $user->logins()->create();\n        $user = HasOneOfManyTestUser::withExists('latest_login')->first();\n        $this->assertTrue($user->latest_login_exists);\n    }\n\n    public function testWithExistsWithConstraintsInJoinSubSelect()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        $user = HasOneOfManyTestUser::withExists('foo_state')->first();\n\n        $this->assertFalse($user->foo_state_exists);\n\n        $user->states()->create([\n            'type' => 'foo',\n            'state' => 'bar',\n        ]);\n        $user = HasOneOfManyTestUser::withExists('foo_state')->first();\n        $this->assertTrue($user->foo_state_exists);\n    }\n\n    public function testWithSoftDeletes()\n    {\n        $user = HasOneOfManyTestUser::create();\n        $user->logins()->create();\n        $user->latest_login_with_soft_deletes;\n        $this->assertNotNull($user->latest_login_with_soft_deletes);\n    }\n\n    public function testWithConstraintNotInAggregate()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        $previousFoo = $user->states()->create([\n            'type' => 'foo',\n            'state' => 'bar',\n            'updated_at' => '2020-01-01 00:00:00',\n        ]);\n        $newFoo = $user->states()->create([\n            'type' => 'foo',\n            'state' => 'active',\n            'updated_at' => '2021-01-01 12:00:00',\n        ]);\n        $newBar = $user->states()->create([\n            'type' => 'bar',\n            'state' => 'active',\n            'updated_at' => '2021-01-01 12:00:00',\n        ]);\n\n        $this->assertSame($newFoo->id, $user->last_updated_foo_state->id);\n    }\n\n    public function testItGetsCorrectResultUsingAtLeastTwoAggregatesDistinctFromId()\n    {\n        $user = HasOneOfManyTestUser::create();\n\n        $expectedState = $user->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-03',\n        ]);\n\n        $user->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-02',\n        ]);\n\n        $this->assertSame($user->latest_updated_latest_created_state->id, $expectedState->id);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneOfManyTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function logins()\n    {\n        return $this->hasMany(HasOneOfManyTestLogin::class, 'user_id');\n    }\n\n    public function latest_login()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->ofMany();\n    }\n\n    public function latest_login_with_soft_deletes()\n    {\n        return $this->hasOne(HasOneOfManyTestLoginWithSoftDeletes::class, 'user_id')->ofMany();\n    }\n\n    public function latest_login_with_shortcut()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->latestOfMany();\n    }\n\n    public function latest_login_with_invalid_aggregate()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->ofMany('id', 'count');\n    }\n\n    public function latest_login_without_global_scope()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->withoutGlobalScopes()->latestOfMany();\n    }\n\n    public function first_login()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->ofMany('id', 'min');\n    }\n\n    public function latest_login_with_foo_state()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class, 'user_id')->ofMany(\n            ['id' => 'max'],\n            function ($query) {\n                $query->join('states', 'states.user_id', 'logins.user_id')\n                    ->where('states.type', 'foo');\n            }\n        );\n    }\n\n    public function states()\n    {\n        return $this->hasMany(HasOneOfManyTestState::class, 'user_id');\n    }\n\n    public function foo_state()\n    {\n        return $this->hasOne(HasOneOfManyTestState::class, 'user_id')->ofMany(\n            [], // should automatically add 'id' => 'max'\n            function ($q) {\n                $q->where('type', 'foo');\n            }\n        );\n    }\n\n    public function last_updated_foo_state()\n    {\n        return $this->hasOne(HasOneOfManyTestState::class, 'user_id')->ofMany([\n            'updated_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('type', 'foo');\n        });\n    }\n\n    public function prices()\n    {\n        return $this->hasMany(HasOneOfManyTestPrice::class, 'user_id');\n    }\n\n    public function price()\n    {\n        return $this->hasOne(HasOneOfManyTestPrice::class, 'user_id')->ofMany([\n            'published_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('published_at', '<', Carbon::now());\n        });\n    }\n\n    public function price_without_key_in_aggregates()\n    {\n        return $this->hasOne(HasOneOfManyTestPrice::class, 'user_id')->ofMany(['published_at' => 'MAX']);\n    }\n\n    public function price_with_shortcut()\n    {\n        return $this->hasOne(HasOneOfManyTestPrice::class, 'user_id')->latestOfMany(['published_at', 'id']);\n    }\n\n    public function price_without_global_scope()\n    {\n        return $this->hasOne(HasOneOfManyTestPrice::class, 'user_id')->withoutGlobalScopes()->ofMany([\n            'published_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('published_at', '<', Carbon::now());\n        });\n    }\n\n    public function latest_updated_latest_created_state()\n    {\n        return $this->hasOne(HasOneOfManyTestState::class, 'user_id')->ofMany([\n            'updated_at' => 'max',\n            'created_at' => 'max',\n        ]);\n    }\n}\n\nclass HasOneOfManyTestModel extends Eloquent\n{\n    public function logins()\n    {\n        return $this->hasOne(HasOneOfManyTestLogin::class)->ofMany();\n    }\n}\n\nclass HasOneOfManyTestLogin extends Eloquent\n{\n    protected $table = 'logins';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass HasOneOfManyTestLoginWithSoftDeletes extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'logins';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass HasOneOfManyTestState extends Eloquent\n{\n    protected $table = 'states';\n    protected $guarded = [];\n    public $timestamps = true;\n    protected $fillable = ['type', 'state', 'updated_at'];\n}\n\nclass HasOneOfManyTestPrice extends Eloquent\n{\n    protected $table = 'prices';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected $fillable = ['published_at'];\n    protected $casts = ['published_at' => 'datetime'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneOrManyWithAttributesPendingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneOrManyWithAttributesPendingTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n    }\n\n    public function testHasManyAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testHasOneAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasOne(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testMorphManyAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphMany(RelatedPendingAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testMorphOneAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphOne(RelatedPendingAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testPendingAttributesCanBeOverridden(): void\n    {\n        $key = 'a key';\n        $defaultValue = 'a value';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $defaultValue], asConditions: false);\n\n        $relatedModel = $relationship->make([$key => $value]);\n\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testQueryingDoesNotBreakWither(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->where($key, $value)\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testAttributesCanBeAppended(): void\n    {\n        $parent = new RelatedPendingAttributesModel;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes(['a' => 'A'], asConditions: false)\n            ->withAttributes(['b' => 'B'], asConditions: false)\n            ->withAttributes(['a' => 'AA'], asConditions: false);\n\n        $relatedModel = $relationship->make([\n            'b' => 'BB',\n            'c' => 'C',\n        ]);\n\n        $this->assertSame('AA', $relatedModel->a);\n        $this->assertSame('BB', $relatedModel->b);\n        $this->assertSame('C', $relatedModel->c);\n    }\n\n    public function testSingleAttributeApi(): void\n    {\n        $parent = new RelatedPendingAttributesModel;\n        $key = 'attr';\n        $value = 'Value';\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes($key, $value, asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testWheresAreNotSet(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $wheres = $relationship->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => $parent->qualifyColumn('parent_id'),\n            'operator' => '=',\n            'value' => $parentId,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'NotNull',\n            'column' => $parent->qualifyColumn('parent_id'),\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure no other wheres exist\n        $this->assertCount(2, $wheres);\n    }\n\n    public function testNullValueIsAccepted(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => null], asConditions: false);\n\n        $wheres = $relationship->toBase()->wheres;\n        $relatedModel = $relationship->make();\n\n        $this->assertNull($relatedModel->$key);\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => $parent->qualifyColumn('parent_id'),\n            'operator' => '=',\n            'value' => $parentId,\n            'boolean' => 'and',\n        ], $wheres);\n\n        $this->assertContains([\n            'type' => 'NotNull',\n            'column' => $parent->qualifyColumn('parent_id'),\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure no other wheres exist\n        $this->assertCount(2, $wheres);\n    }\n\n    public function testOneKeepsAttributesFromHasMany(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value], asConditions: false)\n            ->one();\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testOneKeepsAttributesFromMorphMany(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphMany(RelatedPendingAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value], asConditions: false)\n            ->one();\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testHasManyAddsCastedAttributes(): void\n    {\n        $parentId = 123;\n\n        $parent = new RelatedPendingAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedPendingAttributesModel::class, 'parent_id')\n            ->withAttributes(['is_admin' => 1], asConditions: false);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame(true, $relatedModel->is_admin);\n    }\n}\n\nclass RelatedPendingAttributesModel extends Model\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'is_admin' => 'boolean',\n    ];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneOrManyWithAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneOrManyWithAttributesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n    }\n\n    public function testHasManyAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testHasOneAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasOne(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testMorphManyAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphMany(RelatedWithAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testMorphOneAddsAttributes(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphOne(RelatedWithAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testWithAttributesCanBeOverridden(): void\n    {\n        $key = 'a key';\n        $defaultValue = 'a value';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $defaultValue]);\n\n        $relatedModel = $relationship->make([$key => $value]);\n\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testQueryingDoesNotBreakWither(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->where($key, $value)\n            ->withAttributes([$key => $value]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testAttributesCanBeAppended(): void\n    {\n        $parent = new RelatedWithAttributesModel;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes(['a' => 'A'])\n            ->withAttributes(['b' => 'B'])\n            ->withAttributes(['a' => 'AA']);\n\n        $relatedModel = $relationship->make([\n            'b' => 'BB',\n            'c' => 'C',\n        ]);\n\n        $this->assertSame('AA', $relatedModel->a);\n        $this->assertSame('BB', $relatedModel->b);\n        $this->assertSame('C', $relatedModel->c);\n    }\n\n    public function testSingleAttributeApi(): void\n    {\n        $parent = new RelatedWithAttributesModel;\n        $key = 'attr';\n        $value = 'Value';\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes($key, $value);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testWheresAreSet(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value]);\n\n        $wheres = $relationship->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'related_with_attributes_models.'.$key,\n            'operator' => '=',\n            'value' => $value,\n            'boolean' => 'and',\n        ], $wheres);\n\n        // Ensure this doesn't break the default where either.\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => $parent->qualifyColumn('parent_id'),\n            'operator' => '=',\n            'value' => $parentId,\n            'boolean' => 'and',\n        ], $wheres);\n    }\n\n    public function testNullValueIsAccepted(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => null]);\n\n        $wheres = $relationship->toBase()->wheres;\n        $relatedModel = $relationship->make();\n\n        $this->assertNull($relatedModel->$key);\n\n        $this->assertContains([\n            'type' => 'Null',\n            'column' => 'related_with_attributes_models.'.$key,\n            'boolean' => 'and',\n        ], $wheres);\n    }\n\n    public function testOneKeepsAttributesFromHasMany(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes([$key => $value])\n            ->one();\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testOneKeepsAttributesFromMorphMany(): void\n    {\n        $parentId = 123;\n        $key = 'a key';\n        $value = 'the value';\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->morphMany(RelatedWithAttributesModel::class, 'relatable')\n            ->withAttributes([$key => $value])\n            ->one();\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->relatable_id);\n        $this->assertSame($parent::class, $relatedModel->relatable_type);\n        $this->assertSame($value, $relatedModel->$key);\n    }\n\n    public function testHasManyAddsCastedAttributes(): void\n    {\n        $parentId = 123;\n\n        $parent = new RelatedWithAttributesModel;\n        $parent->id = $parentId;\n\n        $relationship = $parent\n            ->hasMany(RelatedWithAttributesModel::class, 'parent_id')\n            ->withAttributes(['is_admin' => 1]);\n\n        $relatedModel = $relationship->make();\n\n        $this->assertSame($parentId, $relatedModel->parent_id);\n        $this->assertSame(true, $relatedModel->is_admin);\n    }\n}\n\nclass RelatedWithAttributesModel extends Model\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'is_admin' => 'boolean',\n    ];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Contracts\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneTest extends TestCase\n{\n    protected $builder;\n\n    protected $related;\n\n    protected $parent;\n\n    public function testHasOneWithDefault()\n    {\n        $relation = $this->getRelation()->withDefault();\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentHasOneModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame(1, $newModel->getAttribute('foreign_key'));\n    }\n\n    public function testHasOneWithDynamicDefault()\n    {\n        $relation = $this->getRelation()->withDefault(function ($newModel) {\n            $newModel->username = 'taylor';\n        });\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentHasOneModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame('taylor', $newModel->username);\n\n        $this->assertSame(1, $newModel->getAttribute('foreign_key'));\n    }\n\n    public function testHasOneWithDynamicDefaultUseParentModel()\n    {\n        $relation = $this->getRelation()->withDefault(function ($newModel, $parentModel) {\n            $newModel->username = $parentModel->username;\n        });\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentHasOneModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame('taylor', $newModel->username);\n\n        $this->assertSame(1, $newModel->getAttribute('foreign_key'));\n    }\n\n    public function testHasOneWithArrayDefault()\n    {\n        $attributes = ['username' => 'taylor'];\n\n        $relation = $this->getRelation()->withDefault($attributes);\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentHasOneModelStub;\n\n        $this->related->shouldReceive('newInstance')->once()->andReturn($newModel);\n\n        $this->assertSame($newModel, $relation->getResults());\n\n        $this->assertSame('taylor', $newModel->username);\n\n        $this->assertSame(1, $newModel->getAttribute('foreign_key'));\n    }\n\n    public function testMakeMethodDoesNotSaveNewModel()\n    {\n        $relation = $this->getRelation();\n        $instance = $this->getMockBuilder(Model::class)->onlyMethods(['save', 'newInstance', 'setAttribute'])->getMock();\n        $relation->getRelated()->shouldReceive('newInstance')->with(['name' => 'taylor'])->andReturn($instance);\n        $instance->expects($this->once())->method('setAttribute')->with('foreign_key', 1);\n        $instance->expects($this->never())->method('save');\n\n        $this->assertEquals($instance, $relation->make(['name' => 'taylor']));\n    }\n\n    public function testSaveMethodSetsForeignKeyOnModel()\n    {\n        $relation = $this->getRelation();\n        $mockModel = $this->getMockBuilder(Model::class)->onlyMethods(['save'])->getMock();\n        $mockModel->expects($this->once())->method('save')->willReturn(true);\n        $result = $relation->save($mockModel);\n\n        $attributes = $result->getAttributes();\n        $this->assertEquals(1, $attributes['foreign_key']);\n    }\n\n    public function testCreateMethodProperlyCreatesNewModel()\n    {\n        $relation = $this->getRelation();\n        $created = $this->getMockBuilder(Model::class)->onlyMethods(['save', 'getKey', 'setAttribute'])->getMock();\n        $created->expects($this->once())->method('save')->willReturn(true);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['name' => 'taylor'])->andReturn($created);\n        $created->expects($this->once())->method('setAttribute')->with('foreign_key', 1);\n\n        $this->assertEquals($created, $relation->create(['name' => 'taylor']));\n    }\n\n    public function testForceCreateMethodProperlyCreatesNewModel()\n    {\n        $relation = $this->getRelation();\n        $attributes = ['name' => 'taylor', $relation->getForeignKeyName() => $relation->getParentKey()];\n\n        $created = m::mock(Model::class);\n        $created->shouldReceive('getAttribute')->with($relation->getForeignKeyName())->andReturn($relation->getParentKey());\n\n        $relation->getRelated()->shouldReceive('forceCreate')->once()->with($attributes)->andReturn($created);\n\n        $this->assertEquals($created, $relation->forceCreate(['name' => 'taylor']));\n        $this->assertEquals(1, $created->getAttribute('foreign_key'));\n    }\n\n    public function testRelationIsProperlyInitialized()\n    {\n        $relation = $this->getRelation();\n        $model = m::mock(Model::class);\n        $model->shouldReceive('setRelation')->once()->with('foo', null);\n        $models = $relation->initRelation([$model], 'foo');\n\n        $this->assertEquals([$model], $models);\n    }\n\n    public function testEagerConstraintsAreProperlyAdded()\n    {\n        $relation = $this->getRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->once()->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('table.foreign_key', [1, 2]);\n        $model1 = new EloquentHasOneModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentHasOneModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    public function testModelsAreProperlyMatchedToParents()\n    {\n        $relation = $this->getRelation();\n\n        $result1 = new EloquentHasOneModelStub;\n        $result1->foreign_key = 1;\n        $result2 = new EloquentHasOneModelStub;\n        $result2->foreign_key = 2;\n        $result3 = new EloquentHasOneModelStub;\n        $result3->foreign_key = new class\n        {\n            public function __toString()\n            {\n                return '4';\n            }\n        };\n\n        $model1 = new EloquentHasOneModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentHasOneModelStub;\n        $model2->id = 2;\n        $model3 = new EloquentHasOneModelStub;\n        $model3->id = 3;\n        $model4 = new EloquentHasOneModelStub;\n        $model4->id = 4;\n\n        $models = $relation->match([$model1, $model2, $model3, $model4], new Collection([$result1, $result2, $result3]), 'foo');\n\n        $this->assertEquals(1, $models[0]->foo->foreign_key);\n        $this->assertEquals(2, $models[1]->foo->foreign_key);\n        $this->assertNull($models[2]->foo);\n        $this->assertSame('4', (string) $models[3]->foo->foreign_key);\n    }\n\n    public function testRelationCountQueryCanBeBuilt()\n    {\n        $relation = $this->getRelation();\n        $builder = m::mock(Builder::class);\n\n        $baseQuery = m::mock(BaseBuilder::class);\n        $baseQuery->from = 'one';\n        $parentQuery = m::mock(BaseBuilder::class);\n        $parentQuery->from = 'two';\n\n        $builder->shouldReceive('getQuery')->once()->andReturn($baseQuery);\n        $builder->shouldReceive('getQuery')->once()->andReturn($parentQuery);\n\n        $builder->shouldReceive('select')->once()->with(m::type(Expression::class))->andReturnSelf();\n        $relation->getParent()->shouldReceive('qualifyColumn')->andReturn('table.id');\n        $builder->shouldReceive('whereColumn')->once()->with('table.id', '=', 'table.foreign_key')->andReturn($baseQuery);\n        $baseQuery->shouldReceive('setBindings')->once()->with([], 'select');\n\n        $relation->getRelationExistenceCountQuery($builder, $builder);\n    }\n\n    public function testIsNotNull()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->never();\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is(null));\n    }\n\n    public function testIsModel()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->once()->andReturn('table');\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithStringRelatedKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->once()->andReturn('table');\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('1');\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullRelatedKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->never();\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(null);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherRelatedKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->never();\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(2);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherTable()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->once()->andReturn('table');\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table.two');\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherConnection()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getTable')->once()->andReturn('table');\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection.two');\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    protected function getRelation()\n    {\n        $this->builder = m::mock(Builder::class);\n        $this->builder->shouldReceive('whereNotNull')->with('table.foreign_key');\n        $this->builder->shouldReceive('where')->with('table.foreign_key', '=', 1);\n        $this->related = m::mock(Model::class);\n        $this->builder->shouldReceive('getModel')->andReturn($this->related);\n        $this->parent = m::mock(Model::class);\n        $this->parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $this->parent->shouldReceive('getAttribute')->with('username')->andReturn('taylor');\n        $this->parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $this->parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n        $this->parent->shouldReceive('newQueryWithoutScopes')->andReturn($this->builder);\n\n        return new HasOne($this->builder, $this->parent, 'table.foreign_key', 'id');\n    }\n}\n\nclass EloquentHasOneModelStub extends Model\n{\n    public $foreign_key = 'foreign.value';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneThroughIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneThroughIntegrationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->unsignedInteger('position_id')->unique()->nullable();\n            $table->string('position_short');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('contracts', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id')->unique();\n            $table->string('title');\n            $table->text('body');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('positions', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('shortname');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('contracts');\n        $this->schema()->drop('positions');\n\n        parent::tearDown();\n    }\n\n    public function testItLoadsAHasOneThroughRelationWithCustomKeys()\n    {\n        $this->seedData();\n        $contract = HasOneThroughTestPosition::first()->contract;\n\n        $this->assertSame('A title', $contract->title);\n    }\n\n    public function testItLoadsADefaultHasOneThroughRelation()\n    {\n        $this->migrateDefault();\n        $this->seedDefaultData();\n\n        $contract = HasOneThroughDefaultTestPosition::first()->contract;\n        $this->assertSame('A title', $contract->title);\n        $this->assertArrayNotHasKey('email', $contract->getAttributes());\n\n        $this->resetDefault();\n    }\n\n    public function testItLoadsARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $contract = HasOneThroughIntermediateTestPosition::first()->contract;\n\n        $this->assertSame('A title', $contract->title);\n    }\n\n    public function testEagerLoadingARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $contract = HasOneThroughIntermediateTestPosition::with('contract')->first()->contract;\n\n        $this->assertSame('A title', $contract->title);\n    }\n\n    public function testWhereHasOnARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $position = HasOneThroughIntermediateTestPosition::whereHas('contract', function ($query) {\n            $query->where('title', 'A title');\n        })->get();\n\n        $this->assertCount(1, $position);\n    }\n\n    public function testWithWhereHasOnARelationWithCustomIntermediateAndLocalKey()\n    {\n        $this->seedData();\n        $position = HasOneThroughIntermediateTestPosition::withWhereHas('contract', function ($query) {\n            $query->where('title', 'A title');\n        })->get();\n\n        $this->assertCount(1, $position);\n        $this->assertTrue($position->first()->relationLoaded('contract'));\n        $this->assertEquals($position->first()->contract->pluck('title')->unique()->toArray(), ['A title']);\n    }\n\n    public function testFirstOrFailThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\HasOneThroughTestContract].');\n\n        HasOneThroughTestPosition::create(['id' => 1, 'name' => 'President', 'shortname' => 'ps'])\n            ->user()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'position_short' => 'ps']);\n\n        HasOneThroughTestPosition::first()->contract()->firstOrFail();\n    }\n\n    public function testFindOrFailThrowsAnException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        HasOneThroughTestPosition::create(['id' => 1, 'name' => 'President', 'shortname' => 'ps'])\n            ->user()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'position_short' => 'ps']);\n\n        HasOneThroughTestPosition::first()->contract()->findOrFail(1);\n    }\n\n    public function testFirstRetrievesFirstRecord()\n    {\n        $this->seedData();\n        $contract = HasOneThroughTestPosition::first()->contract()->first();\n\n        $this->assertNotNull($contract);\n        $this->assertSame('A title', $contract->title);\n    }\n\n    public function testAllColumnsAreRetrievedByDefault()\n    {\n        $this->seedData();\n        $contract = HasOneThroughTestPosition::first()->contract()->first();\n        $this->assertEquals([\n            'id',\n            'user_id',\n            'title',\n            'body',\n            'email',\n            'created_at',\n            'updated_at',\n            'laravel_through_key',\n        ], array_keys($contract->getAttributes()));\n    }\n\n    public function testOnlyProperColumnsAreSelectedIfProvided()\n    {\n        $this->seedData();\n        $contract = HasOneThroughTestPosition::first()->contract()->first(['title', 'body']);\n\n        $this->assertEquals([\n            'title',\n            'body',\n            'laravel_through_key',\n        ], array_keys($contract->getAttributes()));\n    }\n\n    public function testChunkReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $position = HasOneThroughTestPosition::find(1);\n\n        $position->contract()->chunk(10, function ($contractsChunk) {\n            $contract = $contractsChunk->first();\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key', ], array_keys($contract->getAttributes()));\n        });\n    }\n\n    public function testCursorReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $position = HasOneThroughTestPosition::find(1);\n\n        $contracts = $position->contract()->cursor();\n\n        foreach ($contracts as $contract) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key', ], array_keys($contract->getAttributes()));\n        }\n    }\n\n    public function testEachReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $position = HasOneThroughTestPosition::find(1);\n\n        $position->contract()->each(function ($contract) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key', ], array_keys($contract->getAttributes()));\n        });\n    }\n\n    public function testLazyReturnsCorrectModels()\n    {\n        $this->seedData();\n        $this->seedDataExtended();\n        $position = HasOneThroughTestPosition::find(1);\n\n        $position->contract()->lazy()->each(function ($contract) {\n            $this->assertEquals([\n                'id',\n                'user_id',\n                'title',\n                'body',\n                'email',\n                'created_at',\n                'updated_at',\n                'laravel_through_key', ], array_keys($contract->getAttributes()));\n        });\n    }\n\n    public function testIntermediateSoftDeletesAreIgnored()\n    {\n        $this->seedData();\n        HasOneThroughSoftDeletesTestUser::first()->delete();\n\n        $contract = HasOneThroughSoftDeletesTestPosition::first()->contract;\n\n        $this->assertSame('A title', $contract->title);\n    }\n\n    public function testEagerLoadingLoadsRelatedModelsCorrectly()\n    {\n        $this->seedData();\n        $position = HasOneThroughSoftDeletesTestPosition::with('contract')->first();\n\n        $this->assertSame('ps', $position->shortname);\n        $this->assertSame('A title', $position->contract->title);\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        HasOneThroughTestPosition::create(['id' => 1, 'name' => 'President', 'shortname' => 'ps'])\n            ->user()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'position_short' => 'ps'])\n            ->contract()->create(['title' => 'A title', 'body' => 'A body', 'email' => 'taylorotwell@gmail.com']);\n    }\n\n    protected function seedDataExtended()\n    {\n        $position = HasOneThroughTestPosition::create(['id' => 2, 'name' => 'Vice President', 'shortname' => 'vp']);\n        $position->user()->create(['id' => 2, 'email' => 'example1@gmail.com', 'position_short' => 'vp'])\n            ->contract()->create(\n                ['title' => 'Example1 title1', 'body' => 'Example1 body1', 'email' => 'example1contract1@gmail.com']\n            );\n    }\n\n    /**\n     * Seed data for a default HasOneThrough setup.\n     */\n    protected function seedDefaultData()\n    {\n        HasOneThroughDefaultTestPosition::create(['id' => 1, 'name' => 'President'])\n            ->user()->create(['id' => 1, 'email' => 'taylorotwell@gmail.com'])\n            ->contract()->create(['title' => 'A title', 'body' => 'A body']);\n    }\n\n    /**\n     * Drop the default tables.\n     */\n    protected function resetDefault()\n    {\n        $this->schema()->drop('users_default');\n        $this->schema()->drop('contracts_default');\n        $this->schema()->drop('positions_default');\n    }\n\n    /**\n     * Migrate tables for classes with a Laravel \"default\" HasOneThrough setup.\n     */\n    protected function migrateDefault()\n    {\n        $this->schema()->create('users_default', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->unsignedInteger('has_one_through_default_test_position_id')->unique()->nullable();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('contracts_default', function ($table) {\n            $table->increments('id');\n            $table->integer('has_one_through_default_test_user_id')->unique();\n            $table->string('title');\n            $table->text('body');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('positions_default', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneThroughTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOne(HasOneThroughTestContract::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneThroughTestContract extends Eloquent\n{\n    protected $table = 'contracts';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasOneThroughTestUser::class, 'user_id');\n    }\n}\n\nclass HasOneThroughTestPosition extends Eloquent\n{\n    protected $table = 'positions';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOneThrough(HasOneThroughTestContract::class, HasOneThroughTestUser::class, 'position_id', 'user_id');\n    }\n\n    public function user()\n    {\n        return $this->hasOne(HasOneThroughTestUser::class, 'position_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneThroughDefaultTestUser extends Eloquent\n{\n    protected $table = 'users_default';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOne(HasOneThroughDefaultTestContract::class);\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneThroughDefaultTestContract extends Eloquent\n{\n    protected $table = 'contracts_default';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasOneThroughDefaultTestUser::class);\n    }\n}\n\nclass HasOneThroughDefaultTestPosition extends Eloquent\n{\n    protected $table = 'positions_default';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOneThrough(HasOneThroughDefaultTestContract::class, HasOneThroughDefaultTestUser::class);\n    }\n\n    public function user()\n    {\n        return $this->hasOne(HasOneThroughDefaultTestUser::class);\n    }\n}\n\nclass HasOneThroughIntermediateTestPosition extends Eloquent\n{\n    protected $table = 'positions';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOneThrough(HasOneThroughTestContract::class, HasOneThroughTestUser::class, 'position_short', 'email', 'shortname', 'email');\n    }\n\n    public function user()\n    {\n        return $this->hasOne(HasOneThroughTestUser::class, 'position_id');\n    }\n}\n\nclass HasOneThroughSoftDeletesTestUser extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOne(HasOneThroughSoftDeletesTestContract::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass HasOneThroughSoftDeletesTestContract extends Eloquent\n{\n    protected $table = 'contracts';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->belongsTo(HasOneThroughSoftDeletesTestUser::class, 'user_id');\n    }\n}\n\nclass HasOneThroughSoftDeletesTestPosition extends Eloquent\n{\n    protected $table = 'positions';\n    protected $guarded = [];\n\n    public function contract()\n    {\n        return $this->hasOneThrough(HasOneThroughSoftDeletesTestContract::class, HasOneThroughTestUser::class, 'position_id', 'user_id');\n    }\n\n    public function user()\n    {\n        return $this->hasOne(HasOneThroughSoftDeletesTestUser::class, 'position_id');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentHasOneThroughOfManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Support\\Carbon;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentHasOneThroughOfManyTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n        $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:']);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    public function createSchema(): void\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n        });\n\n        $this->schema()->create('intermediates', function ($table) {\n            $table->increments('id');\n            $table->foreignId('user_id');\n        });\n\n        $this->schema()->create('logins', function ($table) {\n            $table->increments('id');\n            $table->foreignId('intermediate_id');\n            $table->dateTime('deleted_at')->nullable();\n        });\n\n        $this->schema()->create('states', function ($table) {\n            $table->increments('id');\n            $table->string('state');\n            $table->string('type');\n            $table->foreignId('intermediate_id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('prices', function ($table) {\n            $table->increments('id');\n            $table->dateTime('published_at');\n            $table->foreignId('intermediate_id');\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('intermediates');\n        $this->schema()->drop('logins');\n        $this->schema()->drop('states');\n        $this->schema()->drop('prices');\n\n        parent::tearDown();\n    }\n\n    public function testItGuessesRelationName(): void\n    {\n        $user = HasOneThroughOfManyTestUser::make();\n        $this->assertSame('latest_login', $user->latest_login()->getRelationName());\n    }\n\n    public function testItGuessesRelationNameAndAddsOfManyWhenTableNameIsRelationName(): void\n    {\n        $model = HasOneThroughOfManyTestModel::make();\n        $this->assertSame('logins_of_many', $model->logins()->getRelationName());\n    }\n\n    public function testRelationNameCanBeSet(): void\n    {\n        $user = HasOneThroughOfManyTestUser::create();\n\n        $relation = $user->latest_login()->ofMany('id', 'max', 'foo');\n        $this->assertSame('foo', $relation->getRelationName());\n\n        $relation = $user->latest_login()->latestOfMany('id', 'bar');\n        $this->assertSame('bar', $relation->getRelationName());\n\n        $relation = $user->latest_login()->oldestOfMany('id', 'baz');\n        $this->assertSame('baz', $relation->getRelationName());\n    }\n\n    public function testCorrectLatestOfManyQuery(): void\n    {\n        $user = HasOneThroughOfManyTestUser::create();\n        $relation = $user->latest_login();\n        $this->assertSame('select \"logins\".* from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" inner join (select MAX(\"logins\".\"id\") as \"id_aggregate\", \"intermediates\".\"user_id\" from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" where \"intermediates\".\"user_id\" = ? group by \"intermediates\".\"user_id\") as \"latest_login\" on \"latest_login\".\"id_aggregate\" = \"logins\".\"id\" and \"latest_login\".\"user_id\" = \"intermediates\".\"user_id\" where \"intermediates\".\"user_id\" = ?', $relation->getQuery()->toSql());\n    }\n\n    public function testEagerLoadingAppliesConstraintsToInnerJoinSubQuery(): void\n    {\n        $user = HasOneThroughOfManyTestUser::create();\n        $relation = $user->latest_login();\n        $relation->addEagerConstraints([$user]);\n        $this->assertSame('select MAX(\"logins\".\"id\") as \"id_aggregate\", \"intermediates\".\"user_id\" from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" where \"intermediates\".\"user_id\" = ? and \"intermediates\".\"user_id\" in (1) group by \"intermediates\".\"user_id\"', $relation->getOneOfManySubQuery()->toSql());\n    }\n\n    public function testEagerLoadingAppliesConstraintsToQuery(): void\n    {\n        $user = HasOneThroughOfManyTestUser::create();\n        $relation = $user->latest_login();\n        $relation->addEagerConstraints([$user]);\n        $this->assertSame('select \"logins\".* from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" inner join (select MAX(\"logins\".\"id\") as \"id_aggregate\", \"intermediates\".\"user_id\" from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" where \"intermediates\".\"user_id\" = ? and \"intermediates\".\"user_id\" in (1) group by \"intermediates\".\"user_id\") as \"latest_login\" on \"latest_login\".\"id_aggregate\" = \"logins\".\"id\" and \"latest_login\".\"user_id\" = \"intermediates\".\"user_id\" where \"intermediates\".\"user_id\" = ?', $relation->getQuery()->toSql());\n    }\n\n    public function testGlobalScopeIsNotAppliedWhenRelationIsDefinedWithoutGlobalScope(): void\n    {\n        HasOneThroughOfManyTestLogin::addGlobalScope('test', function ($query) {\n            $query->orderBy($query->qualifyColumn('id'));\n        });\n\n        $user = HasOneThroughOfManyTestUser::create();\n        $relation = $user->latest_login_without_global_scope();\n        $relation->addEagerConstraints([$user]);\n        $this->assertSame('select \"logins\".* from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" inner join (select MAX(\"logins\".\"id\") as \"id_aggregate\", \"intermediates\".\"user_id\" from \"logins\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"logins\".\"intermediate_id\" where \"intermediates\".\"user_id\" = ? and \"intermediates\".\"user_id\" in (1) group by \"intermediates\".\"user_id\") as \"latestOfMany\" on \"latestOfMany\".\"id_aggregate\" = \"logins\".\"id\" and \"latestOfMany\".\"user_id\" = \"intermediates\".\"user_id\" where \"intermediates\".\"user_id\" = ?', $relation->getQuery()->toSql());\n\n        HasOneThroughOfManyTestLogin::addGlobalScope('test', function ($query) {\n        });\n    }\n\n    public function testGlobalScopeIsNotAppliedWhenRelationIsDefinedWithoutGlobalScopeWithComplexQuery(): void\n    {\n        HasOneThroughOfManyTestPrice::addGlobalScope('test', function ($query) {\n            $query->orderBy($query->qualifyColumn('id'));\n        });\n\n        $user = HasOneThroughOfManyTestUser::create();\n        $relation = $user->price_without_global_scope();\n        $this->assertSame('select \"prices\".* from \"prices\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"prices\".\"intermediate_id\" inner join (select max(\"prices\".\"id\") as \"id_aggregate\", min(\"prices\".\"published_at\") as \"published_at_aggregate\", \"intermediates\".\"user_id\" from \"prices\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"prices\".\"intermediate_id\" inner join (select max(\"prices\".\"published_at\") as \"published_at_aggregate\", \"intermediates\".\"user_id\" from \"prices\" inner join \"intermediates\" on \"intermediates\".\"id\" = \"prices\".\"intermediate_id\" where \"published_at\" < ? and \"intermediates\".\"user_id\" = ? group by \"intermediates\".\"user_id\") as \"price_without_global_scope\" on \"price_without_global_scope\".\"published_at_aggregate\" = \"prices\".\"published_at\" and \"price_without_global_scope\".\"user_id\" = \"intermediates\".\"user_id\" where \"published_at\" < ? group by \"intermediates\".\"user_id\") as \"price_without_global_scope\" on \"price_without_global_scope\".\"id_aggregate\" = \"prices\".\"id\" and \"price_without_global_scope\".\"published_at_aggregate\" = \"prices\".\"published_at\" and \"price_without_global_scope\".\"user_id\" = \"intermediates\".\"user_id\" where \"intermediates\".\"user_id\" = ?', $relation->getQuery()->toSql());\n\n        HasOneThroughOfManyTestPrice::addGlobalScope('test', function ($query) {\n        });\n    }\n\n    public function testQualifyingSubSelectColumn(): void\n    {\n        $user = HasOneThroughOfManyTestUser::make();\n        $this->assertSame('latest_login.id', $user->latest_login()->qualifySubSelectColumn('id'));\n    }\n\n    public function testItFailsWhenUsingInvalidAggregate(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid aggregate [count] used within ofMany relation. Available aggregates: MIN, MAX');\n        $user = HasOneThroughOfManyTestUser::make();\n        $user->latest_login_with_invalid_aggregate();\n    }\n\n    public function testItGetsCorrectResults(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->last()->logins()->create();\n        $latestLogin = $user->intermediates->first()->logins()->create();\n\n        $result = $user->latest_login()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($latestLogin->id, $result->id);\n    }\n\n    public function testResultDoesNotHaveAggregateColumn(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(1)->create();\n        $user->intermediates->first()->logins()->create();\n\n        $result = $user->latest_login()->getResults();\n        $this->assertNotNull($result);\n        $this->assertFalse(isset($result->id_aggregate));\n    }\n\n    public function testItGetsCorrectResultsUsingShortcutMethod(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->last()->logins()->create();\n        $latestLogin = $user->intermediates->first()->logins()->create();\n\n        $result = $user->latest_login_with_shortcut()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($latestLogin->id, $result->id);\n    }\n\n    public function testItGetsCorrectResultsUsingShortcutReceivingMultipleColumnsMethod(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->intermediates->first()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $result = $user->price_with_shortcut()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($price->id, $result->id);\n    }\n\n    public function testKeyIsAddedToAggregatesWhenMissing(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->intermediates->first()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $result = $user->price_without_key_in_aggregates()->getResults();\n        $this->assertNotNull($result);\n        $this->assertSame($price->id, $result->id);\n    }\n\n    public function testItGetsWithConstraintsCorrectResults(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->last()->logins()->create();\n        $user->intermediates->first()->logins()->create();\n\n        $result = $user->latest_login()->whereKey($previousLogin->getKey())->getResults();\n        $this->assertNull($result);\n    }\n\n    public function testItEagerLoadsCorrectModels(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->logins()->create();\n        $latestLogin = $user->intermediates->first()->logins()->create();\n\n        $user = HasOneThroughOfManyTestUser::with('latest_login')->first();\n\n        $this->assertTrue($user->relationLoaded('latest_login'));\n        $this->assertSame($latestLogin->id, $user->latest_login->id);\n    }\n\n    public function testItJoinsOtherTableInSubQuery(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->first()->logins()->create();\n\n        $this->assertNull($user->latest_login_with_foo_state);\n\n        $user->unsetRelation('latest_login_with_foo_state');\n        $user->intermediates->first()->states()->create([\n            'type' => 'foo',\n            'state' => 'draft',\n        ]);\n\n        $this->assertNotNull($user->latest_login_with_foo_state);\n    }\n\n    public function testHasNested(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->first()->logins()->create();\n        $latestLogin = $user->intermediates->last()->logins()->create();\n\n        $found = HasOneThroughOfManyTestUser::whereHas('latest_login', function ($query) use ($latestLogin) {\n            $query->where('logins.id', $latestLogin->id);\n        })->exists();\n        $this->assertTrue($found);\n\n        $found = HasOneThroughOfManyTestUser::whereHas('latest_login', function ($query) use ($previousLogin) {\n            $query->where('logins.id', $previousLogin->id);\n        })->exists();\n        $this->assertFalse($found);\n    }\n\n    public function testWithHasNested(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->first()->logins()->create();\n        $latestLogin = $user->intermediates->last()->logins()->create();\n\n        $found = HasOneThroughOfManyTestUser::withWhereHas('latest_login', function ($query) use ($latestLogin) {\n            $query->where('logins.id', $latestLogin->id);\n        })->first();\n\n        $this->assertTrue((bool) $found);\n        $this->assertTrue($found->relationLoaded('latest_login'));\n        $this->assertEquals($found->latest_login->id, $latestLogin->id);\n\n        $found = HasOneThroughOfManyTestUser::withWhereHas('latest_login', function ($query) use ($previousLogin) {\n            $query->where('logins.id', $previousLogin->id);\n        })->exists();\n\n        $this->assertFalse($found);\n    }\n\n    public function testHasCount(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->logins()->create();\n        $user->intermediates->first()->logins()->create();\n\n        $user = HasOneThroughOfManyTestUser::withCount('latest_login')->first();\n        $this->assertEquals(1, $user->latest_login_count);\n    }\n\n    public function testExists(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->last()->logins()->create();\n        $latestLogin = $user->intermediates->first()->logins()->create();\n\n        $this->assertFalse($user->latest_login()->whereKey($previousLogin->getKey())->exists());\n        $this->assertTrue($user->latest_login()->whereKey($latestLogin->getKey())->exists());\n    }\n\n    public function testIsMethod(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $login1 = $user->intermediates->last()->logins()->create();\n        $login2 = $user->intermediates->first()->logins()->create();\n\n        $this->assertFalse($user->latest_login()->is($login1));\n        $this->assertTrue($user->latest_login()->is($login2));\n    }\n\n    public function testIsNotMethod(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $login1 = $user->intermediates->last()->logins()->create();\n        $login2 = $user->intermediates->first()->logins()->create();\n\n        $this->assertTrue($user->latest_login()->isNot($login1));\n        $this->assertFalse($user->latest_login()->isNot($login2));\n    }\n\n    public function testGet(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $previousLogin = $user->intermediates->last()->logins()->create();\n        $latestLogin = $user->intermediates->first()->logins()->create();\n\n        $latestLogins = $user->latest_login()->get();\n        $this->assertCount(1, $latestLogins);\n        $this->assertSame($latestLogin->id, $latestLogins->first()->id);\n\n        $latestLogins = $user->latest_login()->whereKey($previousLogin->getKey())->get();\n        $this->assertCount(0, $latestLogins);\n    }\n\n    public function testCount(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->logins()->create();\n        $user->intermediates->first()->logins()->create();\n\n        $this->assertSame(1, $user->latest_login()->count());\n    }\n\n    public function testAggregate(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $firstLogin = $user->intermediates->first()->logins()->create();\n        $user->intermediates->last()->logins()->create();\n\n        $user = HasOneThroughOfManyTestUser::first();\n        $this->assertSame($firstLogin->id, $user->first_login->id);\n    }\n\n    public function testJoinConstraints(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->states()->create([\n            'type' => 'foo',\n            'state' => 'draft',\n        ]);\n        $currentForState = $user->intermediates->first()->states()->create([\n            'type' => 'foo',\n            'state' => 'active',\n        ]);\n        $user->intermediates->first()->states()->create([\n            'type' => 'bar',\n            'state' => 'baz',\n        ]);\n\n        $user = HasOneThroughOfManyTestUser::first();\n        $this->assertSame($currentForState->id, $user->foo_state->id);\n    }\n\n    public function testMultipleAggregates(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user->intermediates->last()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $price = $user->intermediates->first()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n\n        $user = HasOneThroughOfManyTestUser::first();\n        $this->assertSame($price->id, $user->price->id);\n    }\n\n    public function testEagerLoadingWithMultipleAggregates(): void\n    {\n        $user1 = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n        $user2 = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n\n        $user1->intermediates->last()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user1Price = $user1->intermediates->first()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user1->intermediates->first()->prices()->create([\n            'published_at' => '2021-04-01 00:00:00',\n        ]);\n\n        $user2Price = $user2->intermediates->last()->prices()->create([\n            'published_at' => '2021-05-01 00:00:00',\n        ]);\n        $user2->intermediates->first()->prices()->create([\n            'published_at' => '2021-04-01 00:00:00',\n        ]);\n\n        $users = HasOneThroughOfManyTestUser::with('price')->get();\n\n        $this->assertNotNull($users[0]->price);\n        $this->assertSame($user1Price->id, $users[0]->price->id);\n\n        $this->assertNotNull($users[1]->price);\n        $this->assertSame($user2Price->id, $users[1]->price->id);\n    }\n\n    public function testWithExists(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(1)->create();\n\n        $user = HasOneThroughOfManyTestUser::withExists('latest_login')->first();\n        $this->assertFalse($user->latest_login_exists);\n\n        $user->intermediates->first()->logins()->create();\n        $user = HasOneThroughOfManyTestUser::withExists('latest_login')->first();\n        $this->assertTrue($user->latest_login_exists);\n    }\n\n    public function testWithExistsWithConstraintsInJoinSubSelect(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(1)->create();\n        $user = HasOneThroughOfManyTestUser::withExists('foo_state')->first();\n\n        $this->assertFalse($user->foo_state_exists);\n\n        $user->intermediates->first()->states()->create([\n            'type' => 'foo',\n            'state' => 'bar',\n        ]);\n        $user = HasOneThroughOfManyTestUser::withExists('foo_state')->first();\n        $this->assertTrue($user->foo_state_exists);\n    }\n\n    public function testWithSoftDeletes(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(1)->create();\n        $user->intermediates->first()->logins()->create();\n        $user->latest_login_with_soft_deletes;\n        $this->assertNotNull($user->latest_login_with_soft_deletes);\n    }\n\n    public function testWithConstraintNotInAggregate(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n\n        $previousFoo = $user->intermediates->last()->states()->create([\n            'type' => 'foo',\n            'state' => 'bar',\n            'updated_at' => '2020-01-01 00:00:00',\n        ]);\n        $newFoo = $user->intermediates->first()->states()->create([\n            'type' => 'foo',\n            'state' => 'active',\n            'updated_at' => '2021-01-01 12:00:00',\n        ]);\n        $newBar = $user->intermediates->first()->states()->create([\n            'type' => 'bar',\n            'state' => 'active',\n            'updated_at' => '2021-01-01 12:00:00',\n        ]);\n\n        $this->assertSame($newFoo->id, $user->last_updated_foo_state->id);\n    }\n\n    public function testItGetsCorrectResultUsingAtLeastTwoAggregatesDistinctFromId(): void\n    {\n        $user = HasOneThroughOfManyTestUser::factory()->hasIntermediates(2)->create();\n\n        $expectedState = $user->intermediates->last()->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-03',\n        ]);\n\n        $user->intermediates->first()->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-02',\n        ]);\n\n        $this->assertSame($user->latest_updated_latest_created_state->id, $expectedState->id);\n    }\n\n    protected function connection(): Connection\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    protected function schema(): Builder\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass HasOneThroughOfManyTestUser extends Eloquent\n{\n    use HasFactory;\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected static string $factory = HasOneThroughOfManyTestUserFactory::class;\n\n    public function intermediates(): HasMany\n    {\n        return $this->hasMany(HasOneThroughOfManyTestIntermediate::class, 'user_id');\n    }\n\n    public function logins(): HasManyThrough\n    {\n        return $this->through('intermediates')->has('logins');\n    }\n\n    public function latest_login(): HasOneThrough\n    {\n        return $this->hasOneThrough(\n            HasOneThroughOfManyTestLogin::class,\n            HasOneThroughOfManyTestIntermediate::class,\n            'user_id',\n            'intermediate_id'\n        )->ofMany();\n    }\n\n    public function latest_login_with_soft_deletes(): HasOneThrough\n    {\n        return $this->hasOneThrough(\n            HasOneThroughOfManyTestLoginWithSoftDeletes::class,\n            HasOneThroughOfManyTestIntermediate::class,\n            'user_id',\n            'intermediate_id',\n        )->ofMany();\n    }\n\n    public function latest_login_with_shortcut(): HasOneThrough\n    {\n        return $this->logins()->one()->latestOfMany();\n    }\n\n    public function latest_login_with_invalid_aggregate(): HasOneThrough\n    {\n        return $this->logins()->one()->ofMany('id', 'count');\n    }\n\n    public function latest_login_without_global_scope(): HasOneThrough\n    {\n        return $this->logins()->one()->withoutGlobalScopes()->latestOfMany();\n    }\n\n    public function first_login(): HasOneThrough\n    {\n        return $this->logins()->one()->ofMany('id', 'min');\n    }\n\n    public function latest_login_with_foo_state(): HasOneThrough\n    {\n        return $this->logins()->one()->ofMany(\n            ['id' => 'max'],\n            function ($query) {\n                $query->join('states', 'states.intermediate_id', 'logins.intermediate_id')\n                    ->where('states.type', 'foo');\n            }\n        );\n    }\n\n    public function states(): HasManyThrough\n    {\n        return $this->through($this->intermediates())\n            ->has(fn ($intermediate) => $intermediate->states());\n    }\n\n    public function foo_state(): HasOneThrough\n    {\n        return $this->states()->one()->ofMany(\n            ['id' => 'max'],\n            function ($q) {\n                $q->where('type', 'foo');\n            }\n        );\n    }\n\n    public function last_updated_foo_state(): HasOneThrough\n    {\n        return $this->states()->one()->ofMany([\n            'updated_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('type', 'foo');\n        });\n    }\n\n    public function prices(): HasManyThrough\n    {\n        return $this->throughIntermediates()->hasPrices();\n    }\n\n    public function price(): HasOneThrough\n    {\n        return $this->prices()->one()->ofMany([\n            'published_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('published_at', '<', Carbon::now());\n        });\n    }\n\n    public function price_without_key_in_aggregates(): HasOneThrough\n    {\n        return $this->prices()->one()->ofMany(['published_at' => 'MAX']);\n    }\n\n    public function price_with_shortcut(): HasOneThrough\n    {\n        return $this->prices()->one()->latestOfMany(['published_at', 'id']);\n    }\n\n    public function price_without_global_scope(): HasOneThrough\n    {\n        return $this->prices()->one()->withoutGlobalScopes()->ofMany([\n            'published_at' => 'max',\n            'id' => 'max',\n        ], function ($q) {\n            $q->where('published_at', '<', Carbon::now());\n        });\n    }\n\n    public function latest_updated_latest_created_state(): HasOneThrough\n    {\n        return $this->states()->one()->ofMany([\n            'updated_at' => 'max',\n            'created_at' => 'max',\n        ]);\n    }\n}\n\nclass HasOneThroughOfManyTestIntermediate extends Eloquent\n{\n    use HasFactory;\n    protected $table = 'intermediates';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected static string $factory = HasOneThroughOfManyTestIntermediateFactory::class;\n\n    public function logins(): HasMany\n    {\n        return $this->hasMany(HasOneThroughOfManyTestLogin::class, 'intermediate_id');\n    }\n\n    public function states(): HasMany\n    {\n        return $this->hasMany(HasOneThroughOfManyTestState::class, 'intermediate_id');\n    }\n\n    public function prices(): HasMany\n    {\n        return $this->hasMany(HasOneThroughOfManyTestPrice::class, 'intermediate_id');\n    }\n}\n\nclass HasOneThroughOfManyTestModel extends Eloquent\n{\n    public function logins(): HasOneThrough\n    {\n        return $this->hasOneThrough(\n            HasOneThroughOfManyTestLogin::class,\n            HasOneThroughOfManyTestIntermediate::class,\n            'user_id',\n            'intermediate_id',\n        )->ofMany();\n    }\n}\n\nclass HasOneThroughOfManyTestLogin extends Eloquent\n{\n    protected $table = 'logins';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass HasOneThroughOfManyTestLoginWithSoftDeletes extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'logins';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass HasOneThroughOfManyTestState extends Eloquent\n{\n    protected $table = 'states';\n    protected $guarded = [];\n    public $timestamps = true;\n    protected $fillable = ['type', 'state', 'updated_at'];\n}\n\nclass HasOneThroughOfManyTestPrice extends Eloquent\n{\n    protected $table = 'prices';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected $fillable = ['published_at'];\n    protected $casts = ['published_at' => 'datetime'];\n}\n\nclass HasOneThroughOfManyTestUserFactory extends Factory\n{\n    protected $model = HasOneThroughOfManyTestUser::class;\n\n    public function definition(): array\n    {\n        return [];\n    }\n}\n\nclass HasOneThroughOfManyTestIntermediateFactory extends Factory\n{\n    protected $model = HasOneThroughOfManyTestIntermediate::class;\n\n    public function definition(): array\n    {\n        return ['user_id' => HasOneThroughOfManyTestUser::factory()];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Eloquent\\SoftDeletingScope;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Pagination\\AbstractPaginator as Paginator;\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Database\\Fixtures\\User;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentIntegrationTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], 'second_connection');\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema('default')->create('test_orders', function ($table) {\n            $table->increments('id');\n            $table->string('item_type');\n            $table->integer('item_id');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('with_json', function ($table) {\n            $table->increments('id');\n            $table->text('json')->default(json_encode([]));\n        });\n\n        $this->schema('second_connection')->create('test_items', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('users_with_space_in_column_name', function ($table) {\n            $table->increments('id');\n            $table->string('name')->nullable();\n            $table->string('email address');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('users_having_uuids', function (Blueprint $table) {\n            $table->id();\n            $table->uuid();\n            $table->string('name');\n            $table->tinyInteger('role');\n            $table->string('role_string');\n        });\n\n        foreach (['default', 'second_connection'] as $connection) {\n            $this->schema($connection)->create('users', function ($table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                $table->string('email');\n                $table->timestamp('birthday', 6)->nullable();\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('unique_users', function ($table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                // Unique constraint will be applied only for non-null values\n                $table->string('screen_name')->nullable()->unique();\n                $table->string('email')->unique();\n                $table->timestamp('birthday', 6)->nullable();\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('friends', function ($table) {\n                $table->integer('user_id');\n                $table->integer('friend_id');\n                $table->integer('friend_level_id')->nullable();\n            });\n\n            $this->schema($connection)->create('posts', function ($table) {\n                $table->increments('id');\n                $table->integer('user_id');\n                $table->integer('parent_id')->nullable();\n                $table->string('name');\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('comments', function ($table) {\n                $table->increments('id');\n                $table->integer('post_id');\n                $table->string('content');\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('friend_levels', function ($table) {\n                $table->increments('id');\n                $table->string('level');\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('photos', function ($table) {\n                $table->increments('id');\n                $table->morphs('imageable');\n                $table->string('name');\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('soft_deleted_users', function ($table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                $table->string('email');\n                $table->timestamps();\n                $table->softDeletes();\n            });\n\n            $this->schema($connection)->create('tags', function ($table) {\n                $table->increments('id');\n                $table->string('name');\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('taggables', function ($table) {\n                $table->integer('tag_id');\n                $table->morphs('taggable');\n                $table->string('taxonomy')->nullable();\n            });\n\n            $this->schema($connection)->create('categories', function ($table) {\n                $table->increments('id');\n                $table->string('name');\n                $table->integer('parent_id')->nullable();\n                $table->timestamps();\n            });\n\n            $this->schema($connection)->create('achievements', function ($table) {\n                $table->increments('id');\n                $table->integer('status')->nullable();\n            });\n\n            $this->schema($connection)->create('eloquent_test_achievement_eloquent_test_user', function ($table) {\n                $table->integer('eloquent_test_achievement_id');\n                $table->integer('eloquent_test_user_id');\n            });\n        }\n\n        $this->schema($connection)->create('non_incrementing_users', function ($table) {\n            $table->string('name')->nullable();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        foreach (['default', 'second_connection'] as $connection) {\n            $this->schema($connection)->drop('users');\n            $this->schema($connection)->drop('friends');\n            $this->schema($connection)->drop('posts');\n            $this->schema($connection)->drop('friend_levels');\n            $this->schema($connection)->drop('photos');\n        }\n\n        Relation::morphMap([], false);\n        Eloquent::unsetConnectionResolver();\n\n        Carbon::setTestNow(null);\n        Str::createUuidsNormally();\n        DB::flushQueryLog();\n\n        parent::tearDown();\n    }\n\n    /**\n     * Tests...\n     */\n    public function testBasicModelRetrieval()\n    {\n        EloquentTestUser::insert([['id' => 1, 'email' => 'taylorotwell@gmail.com'], ['id' => 2, 'email' => 'abigailotwell@gmail.com']]);\n\n        $this->assertEquals(2, EloquentTestUser::count());\n\n        $this->assertFalse(EloquentTestUser::where('email', 'taylorotwell@gmail.com')->doesntExist());\n        $this->assertTrue(EloquentTestUser::where('email', 'mohamed@laravel.com')->doesntExist());\n\n        $model = EloquentTestUser::where('email', 'taylorotwell@gmail.com')->first();\n        $this->assertSame('taylorotwell@gmail.com', $model->email);\n        $this->assertTrue(isset($model->email));\n        $this->assertTrue(isset($model->friends));\n\n        $model = EloquentTestUser::find(1);\n        $this->assertInstanceOf(EloquentTestUser::class, $model);\n        $this->assertEquals(1, $model->id);\n\n        $model = EloquentTestUser::find(2);\n        $this->assertInstanceOf(EloquentTestUser::class, $model);\n        $this->assertEquals(2, $model->id);\n\n        $missing = EloquentTestUser::find(3);\n        $this->assertNull($missing);\n\n        $collection = EloquentTestUser::find([]);\n        $this->assertInstanceOf(Collection::class, $collection);\n        $this->assertCount(0, $collection);\n\n        $collection = EloquentTestUser::find([1, 2, 3]);\n        $this->assertInstanceOf(Collection::class, $collection);\n        $this->assertCount(2, $collection);\n\n        $models = EloquentTestUser::where('id', 1)->cursor();\n        foreach ($models as $model) {\n            $this->assertEquals(1, $model->id);\n            $this->assertSame('default', $model->getConnectionName());\n        }\n\n        $records = DB::table('users')->where('id', 1)->cursor();\n        foreach ($records as $record) {\n            $this->assertEquals(1, $record->id);\n        }\n\n        $records = DB::cursor('select * from users where id = ?', [1]);\n        foreach ($records as $record) {\n            $this->assertEquals(1, $record->id);\n        }\n    }\n\n    public function testBasicModelCollectionRetrieval()\n    {\n        EloquentTestUser::insert([['id' => 1, 'email' => 'taylorotwell@gmail.com'], ['id' => 2, 'email' => 'abigailotwell@gmail.com']]);\n\n        $models = EloquentTestUser::oldest('id')->get();\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(Collection::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n    }\n\n    public function testPaginatedModelCollectionRetrieval()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            ['id' => 3, 'email' => 'foo@gmail.com'],\n        ]);\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(2);\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n\n        Paginator::currentPageResolver(function () {\n            return 2;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(2);\n\n        $this->assertCount(1, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertSame('foo@gmail.com', $models[0]->email);\n    }\n\n    public function testPaginatedModelCollectionRetrievalUsingCallablePerPage()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            ['id' => 3, 'email' => 'foo@gmail.com'],\n        ]);\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(function ($total) {\n            return $total <= 3 ? 3 : 2;\n        });\n\n        $this->assertCount(3, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[2]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n        $this->assertSame('foo@gmail.com', $models[2]->email);\n\n        Paginator::currentPageResolver(function () {\n            return 2;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(function ($total) {\n            return $total <= 3 ? 3 : 2;\n        });\n\n        $this->assertCount(0, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n\n        EloquentTestUser::create(['id' => 4, 'email' => 'bar@gmail.com']);\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(function ($total) {\n            return $total <= 3 ? 3 : 2;\n        });\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n\n        Paginator::currentPageResolver(function () {\n            return 2;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(function ($total) {\n            return $total <= 3 ? 3 : 2;\n        });\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('foo@gmail.com', $models[0]->email);\n        $this->assertSame('bar@gmail.com', $models[1]->email);\n    }\n\n    public function testPaginatedModelCollectionRetrievalWhenNoElements()\n    {\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(2);\n\n        $this->assertCount(0, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n\n        Paginator::currentPageResolver(function () {\n            return 2;\n        });\n        $models = EloquentTestUser::oldest('id')->paginate(2);\n\n        $this->assertCount(0, $models);\n    }\n\n    public function testPaginatedModelCollectionRetrievalWhenNoElementsAndDefaultPerPage()\n    {\n        $models = EloquentTestUser::oldest('id')->paginate();\n\n        $this->assertCount(0, $models);\n        $this->assertInstanceOf(LengthAwarePaginator::class, $models);\n    }\n\n    public function testCountForPaginationWithGrouping()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            ['id' => 3, 'email' => 'foo@gmail.com'],\n            ['id' => 4, 'email' => 'foo@gmail.com'],\n        ]);\n\n        $query = EloquentTestUser::groupBy('email')->getQuery();\n\n        $this->assertEquals(3, $query->getCountForPagination());\n    }\n\n    public function testCountForPaginationWithGroupingAndSubSelects()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            ['id' => 3, 'email' => 'foo@gmail.com'],\n            ['id' => 4, 'email' => 'foo@gmail.com'],\n        ]);\n        $user1 = EloquentTestUser::find(1);\n\n        $user1->friends()->create(['id' => 5, 'email' => 'friend@gmail.com']);\n\n        $query = EloquentTestUser::select([\n            'id',\n            'friends_count' => EloquentTestUser::whereColumn('friend_id', 'user_id')->count(),\n        ])->groupBy('email')->getQuery();\n\n        $this->assertEquals(4, $query->getCountForPagination());\n    }\n\n    public function testCursorPaginatedModelCollectionRetrieval()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            $secondParams = ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            ['id' => 3, 'email' => 'foo@gmail.com'],\n        ]);\n\n        CursorPaginator::currentCursorResolver(function () {\n            return null;\n        });\n        $models = EloquentTestUser::oldest('id')->cursorPaginate(2);\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(CursorPaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n        $this->assertTrue($models->hasMorePages());\n        $this->assertTrue($models->hasPages());\n\n        CursorPaginator::currentCursorResolver(function () use ($secondParams) {\n            return new Cursor($secondParams);\n        });\n        $models = EloquentTestUser::oldest('id')->cursorPaginate(2);\n\n        $this->assertCount(1, $models);\n        $this->assertInstanceOf(CursorPaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertSame('foo@gmail.com', $models[0]->email);\n        $this->assertFalse($models->hasMorePages());\n        $this->assertTrue($models->hasPages());\n    }\n\n    public function testPreviousCursorPaginatedModelCollectionRetrieval()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n            $thirdParams = ['id' => 3, 'email' => 'foo@gmail.com'],\n        ]);\n\n        CursorPaginator::currentCursorResolver(function () use ($thirdParams) {\n            return new Cursor($thirdParams, false);\n        });\n        $models = EloquentTestUser::oldest('id')->cursorPaginate(2);\n\n        $this->assertCount(2, $models);\n        $this->assertInstanceOf(CursorPaginator::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[1]);\n        $this->assertSame('taylorotwell@gmail.com', $models[0]->email);\n        $this->assertSame('abigailotwell@gmail.com', $models[1]->email);\n        $this->assertTrue($models->hasMorePages());\n        $this->assertTrue($models->hasPages());\n    }\n\n    public function testCursorPaginatedModelCollectionRetrievalWhenNoElements()\n    {\n        CursorPaginator::currentCursorResolver(function () {\n            return null;\n        });\n        $models = EloquentTestUser::oldest('id')->cursorPaginate(2);\n\n        $this->assertCount(0, $models);\n        $this->assertInstanceOf(CursorPaginator::class, $models);\n\n        Paginator::currentPageResolver(function () {\n            return new Cursor(['id' => 1]);\n        });\n        $models = EloquentTestUser::oldest('id')->cursorPaginate(2);\n\n        $this->assertCount(0, $models);\n    }\n\n    public function testCursorPaginatedModelCollectionRetrievalWhenNoElementsAndDefaultPerPage()\n    {\n        $models = EloquentTestUser::oldest('id')->cursorPaginate();\n\n        $this->assertCount(0, $models);\n        $this->assertInstanceOf(CursorPaginator::class, $models);\n    }\n\n    public function testFirstOrNew()\n    {\n        $user1 = EloquentTestUser::firstOrNew(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro']\n        );\n\n        $this->assertSame('Nuno Maduro', $user1->name);\n    }\n\n    public function testFirstOrCreate()\n    {\n        $user1 = EloquentTestUser::firstOrCreate(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = EloquentTestUser::firstOrCreate(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = EloquentTestUser::firstOrCreate(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = EloquentTestUser::firstOrCreate(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user1 = EloquentTestUniqueUser::createOrFirst(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = EloquentTestUniqueUser::createOrFirst(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = EloquentTestUniqueUser::createOrFirst(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = EloquentTestUniqueUser::createOrFirst(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirstNonAttributeFieldViolation()\n    {\n        // 'email' and 'screen_name' are unique and independent of each other.\n        EloquentTestUniqueUser::create([\n            'email' => 'taylorotwell+foo@gmail.com',\n            'screen_name' => '@taylorotwell',\n        ]);\n\n        $this->expectException(UniqueConstraintViolationException::class);\n\n        // Although 'email' is expected to be unique and is passed as $attributes,\n        // if the 'screen_name' attribute listed in non-unique $values causes a violation,\n        // a UniqueConstraintViolationException should be thrown.\n        EloquentTestUniqueUser::createOrFirst(\n            ['email' => 'taylorotwell+bar@gmail.com'],\n            [\n                'screen_name' => '@taylorotwell',\n            ]\n        );\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user1 = EloquentTestUniqueUser::create(['email' => 'taylorotwell@gmail.com']);\n\n        DB::transaction(function () use ($user1) {\n            $user2 = EloquentTestUniqueUser::createOrFirst(\n                ['email' => 'taylorotwell@gmail.com'],\n                ['name' => 'Taylor Otwell']\n            );\n\n            $this->assertEquals($user1->id, $user2->id);\n            $this->assertSame('taylorotwell@gmail.com', $user2->email);\n            $this->assertNull($user2->name);\n        });\n    }\n\n    public function testUpdateOrCreate()\n    {\n        $user1 = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n\n        $user2 = EloquentTestUser::updateOrCreate(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertSame('Taylor Otwell', $user2->name);\n\n        $user3 = EloquentTestUser::updateOrCreate(\n            ['email' => 'themsaid@gmail.com'],\n            ['name' => 'Mohamed Said']\n        );\n\n        $this->assertSame('Mohamed Said', $user3->name);\n        $this->assertEquals(2, EloquentTestUser::count());\n    }\n\n    public function testUpdateOrCreateOnDifferentConnection()\n    {\n        EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n\n        EloquentTestUser::on('second_connection')->updateOrCreate(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        EloquentTestUser::on('second_connection')->updateOrCreate(\n            ['email' => 'themsaid@gmail.com'],\n            ['name' => 'Mohamed Said']\n        );\n\n        $this->assertEquals(1, EloquentTestUser::count());\n        $this->assertEquals(2, EloquentTestUser::on('second_connection')->count());\n    }\n\n    public function testCheckAndCreateMethodsOnMultiConnections()\n    {\n        EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        EloquentTestUser::on('second_connection')->find(\n            EloquentTestUser::on('second_connection')->insert(['id' => 2, 'email' => 'themsaid@gmail.com'])\n        );\n\n        $user1 = EloquentTestUser::on('second_connection')->findOrNew(1);\n        $user2 = EloquentTestUser::on('second_connection')->findOrNew(2);\n        $this->assertFalse($user1->exists);\n        $this->assertTrue($user2->exists);\n        $this->assertSame('second_connection', $user1->getConnectionName());\n        $this->assertSame('second_connection', $user2->getConnectionName());\n\n        $user1 = EloquentTestUser::on('second_connection')->firstOrNew(['email' => 'taylorotwell@gmail.com']);\n        $user2 = EloquentTestUser::on('second_connection')->firstOrNew(['email' => 'themsaid@gmail.com']);\n        $this->assertFalse($user1->exists);\n        $this->assertTrue($user2->exists);\n        $this->assertSame('second_connection', $user1->getConnectionName());\n        $this->assertSame('second_connection', $user2->getConnectionName());\n\n        $this->assertEquals(1, EloquentTestUser::on('second_connection')->count());\n        $user1 = EloquentTestUser::on('second_connection')->firstOrCreate(['email' => 'taylorotwell@gmail.com']);\n        $user2 = EloquentTestUser::on('second_connection')->firstOrCreate(['email' => 'themsaid@gmail.com']);\n        $this->assertSame('second_connection', $user1->getConnectionName());\n        $this->assertSame('second_connection', $user2->getConnectionName());\n        $this->assertEquals(2, EloquentTestUser::on('second_connection')->count());\n    }\n\n    public function testCreatingModelWithEmptyAttributes()\n    {\n        $model = EloquentTestNonIncrementing::create([]);\n\n        $this->assertFalse($model->exists);\n        $this->assertFalse($model->wasRecentlyCreated);\n    }\n\n    public function testChunk()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->chunk(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('First', $users[0]->name);\n                $this->assertSame('Second', $users[1]->name);\n            } else {\n                $this->assertCount(1, $users);\n                $this->assertSame('Third', $users[0]->name);\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(2, $chunks);\n    }\n\n    public function testChunksWithLimitsWhereLimitIsLessThanTotal()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->limit(2)->chunk(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('First', $users[0]->name);\n                $this->assertSame('Second', $users[1]->name);\n            } else {\n                $this->fail('Should only have had one page.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(1, $chunks);\n    }\n\n    public function testChunksWithLimitsWhereLimitIsMoreThanTotal()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->limit(10)->chunk(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('First', $users[0]->name);\n                $this->assertSame('Second', $users[1]->name);\n            } elseif ($page === 2) {\n                $this->assertCount(1, $users);\n                $this->assertSame('Third', $users[0]->name);\n            } else {\n                $this->fail('Should have had two pages.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(2, $chunks);\n    }\n\n    public function testChunksWithOffset()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->offset(1)->chunk(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('Second', $users[0]->name);\n                $this->assertSame('Third', $users[1]->name);\n            } else {\n                $this->fail('Should only have had one page.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(1, $chunks);\n    }\n\n    public function testChunksWithOffsetWhereMoreThanTotal()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->offset(3)->chunk(2, function () use (&$chunks) {\n            $chunks++;\n        });\n\n        $this->assertEquals(0, $chunks);\n    }\n\n    public function testChunksWithLimitsAndOffsets()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n            ['name' => 'Fourth', 'email' => 'fourth@example.com'],\n            ['name' => 'Fifth', 'email' => 'fifth@example.com'],\n            ['name' => 'Sixth', 'email' => 'sixth@example.com'],\n            ['name' => 'Seventh', 'email' => 'seventh@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->orderBy('id', 'asc')->offset(2)->limit(3)->chunk(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('Third', $users[0]->name);\n                $this->assertSame('Fourth', $users[1]->name);\n            } elseif ($page == 2) {\n                $this->assertCount(1, $users);\n                $this->assertSame('Fifth', $users[0]->name);\n            } else {\n                $this->fail('Should only have had two pages.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(2, $chunks);\n    }\n\n    public function testChunkByIdWithLimits()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->limit(2)->chunkById(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('First', $users[0]->name);\n                $this->assertSame('Second', $users[1]->name);\n            } else {\n                $this->fail('Should only have had one page.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(1, $chunks);\n    }\n\n    public function testChunkByIdWithOffsets()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->offset(1)->chunkById(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('Second', $users[0]->name);\n                $this->assertSame('Third', $users[1]->name);\n            } else {\n                $this->fail('Should only have had one page.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(1, $chunks);\n    }\n\n    public function testChunkByIdWithLimitsAndOffsets()\n    {\n        EloquentTestUser::insert([\n            ['name' => 'First', 'email' => 'first@example.com'],\n            ['name' => 'Second', 'email' => 'second@example.com'],\n            ['name' => 'Third', 'email' => 'third@example.com'],\n            ['name' => 'Fourth', 'email' => 'fourth@example.com'],\n            ['name' => 'Fifth', 'email' => 'fifth@example.com'],\n            ['name' => 'Sixth', 'email' => 'sixth@example.com'],\n            ['name' => 'Seventh', 'email' => 'seventh@example.com'],\n        ]);\n\n        $chunks = 0;\n\n        EloquentTestUser::query()->offset(2)->limit(3)->chunkById(2, function (Collection $users, $page) use (&$chunks) {\n            if ($page == 1) {\n                $this->assertCount(2, $users);\n                $this->assertSame('Third', $users[0]->name);\n                $this->assertSame('Fourth', $users[1]->name);\n            } elseif ($page == 2) {\n                $this->assertCount(1, $users);\n                $this->assertSame('Fifth', $users[0]->name);\n            } else {\n                $this->fail('Should only have had two pages.');\n            }\n\n            $chunks++;\n        });\n\n        $this->assertEquals(2, $chunks);\n    }\n\n    public function testChunkByIdWithNonIncrementingKey()\n    {\n        EloquentTestNonIncrementingSecond::insert([\n            ['name' => ' First'],\n            ['name' => ' Second'],\n            ['name' => ' Third'],\n        ]);\n\n        $i = 0;\n        EloquentTestNonIncrementingSecond::query()->chunkById(2, function (Collection $users) use (&$i) {\n            if (! $i) {\n                $this->assertSame(' First', $users[0]->name);\n                $this->assertSame(' Second', $users[1]->name);\n            } else {\n                $this->assertSame(' Third', $users[0]->name);\n            }\n            $i++;\n        }, 'name');\n        $this->assertEquals(2, $i);\n    }\n\n    public function testEachByIdWithNonIncrementingKey()\n    {\n        EloquentTestNonIncrementingSecond::insert([\n            ['name' => ' First'],\n            ['name' => ' Second'],\n            ['name' => ' Third'],\n        ]);\n\n        $users = [];\n        EloquentTestNonIncrementingSecond::query()->eachById(\n            function (EloquentTestNonIncrementingSecond $user, $i) use (&$users) {\n                $users[] = [$user->name, $i];\n            }, 2, 'name');\n        $this->assertSame([[' First', 0], [' Second', 1], [' Third', 2]], $users);\n    }\n\n    public function testPluck()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n        ]);\n\n        $simple = EloquentTestUser::oldest('id')->pluck('users.email')->all();\n        $keyed = EloquentTestUser::oldest('id')->pluck('users.email', 'users.id')->all();\n\n        $this->assertEquals(['taylorotwell@gmail.com', 'abigailotwell@gmail.com'], $simple);\n        $this->assertEquals([1 => 'taylorotwell@gmail.com', 2 => 'abigailotwell@gmail.com'], $keyed);\n    }\n\n    public function testPluckWithJoin()\n    {\n        $user1 = EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $user2 = EloquentTestUser::create(['id' => 2, 'email' => 'abigailotwell@gmail.com']);\n\n        $user2->posts()->create(['id' => 1, 'name' => 'First post']);\n        $user1->posts()->create(['id' => 2, 'name' => 'Second post']);\n\n        $query = EloquentTestUser::join('posts', 'users.id', '=', 'posts.user_id');\n\n        $this->assertEquals([1 => 'First post', 2 => 'Second post'], $query->pluck('posts.name', 'posts.id')->all());\n        $this->assertEquals([2 => 'First post', 1 => 'Second post'], $query->pluck('posts.name', 'users.id')->all());\n        $this->assertEquals(['abigailotwell@gmail.com' => 'First post', 'taylorotwell@gmail.com' => 'Second post'], $query->pluck('posts.name', 'users.email AS user_email')->all());\n    }\n\n    public function testPluckWithColumnNameContainingASpace()\n    {\n        EloquentTestUserWithSpaceInColumnName::insert([\n            ['id' => 1, 'email address' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email address' => 'abigailotwell@gmail.com'],\n        ]);\n\n        $simple = EloquentTestUserWithSpaceInColumnName::oldest('id')->pluck('users_with_space_in_column_name.email address')->all();\n        $keyed = EloquentTestUserWithSpaceInColumnName::oldest('id')->pluck('email address', 'id')->all();\n\n        $this->assertEquals(['taylorotwell@gmail.com', 'abigailotwell@gmail.com'], $simple);\n        $this->assertEquals([1 => 'taylorotwell@gmail.com', 2 => 'abigailotwell@gmail.com'], $keyed);\n    }\n\n    public function testFindOrFail()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n        ]);\n\n        $single = EloquentTestUser::findOrFail(1);\n        $multiple = EloquentTestUser::findOrFail([1, 2]);\n\n        $this->assertInstanceOf(EloquentTestUser::class, $single);\n        $this->assertSame('taylorotwell@gmail.com', $single->email);\n        $this->assertInstanceOf(Collection::class, $multiple);\n        $this->assertInstanceOf(EloquentTestUser::class, $multiple[0]);\n        $this->assertInstanceOf(EloquentTestUser::class, $multiple[1]);\n    }\n\n    public function testFindOrFailWithSingleIdThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\EloquentTestUser] 1');\n        $this->expectExceptionObject(\n            (new ModelNotFoundException())->setModel(EloquentTestUser::class, [1]),\n        );\n\n        EloquentTestUser::findOrFail(1);\n    }\n\n    public function testFindOrFailWithMultipleIdsThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\EloquentTestUser] 2, 3');\n        $this->expectExceptionObject(\n            (new ModelNotFoundException())->setModel(EloquentTestUser::class, [2, 3]),\n        );\n\n        EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        EloquentTestUser::findOrFail([1, 2, 3]);\n    }\n\n    public function testFindOrFailWithMultipleIdsUsingCollectionThrowsModelNotFoundException()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Database\\EloquentTestUser] 2, 3');\n        $this->expectExceptionObject(\n            (new ModelNotFoundException())->setModel(EloquentTestUser::class, [2, 3]),\n        );\n\n        EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        EloquentTestUser::findOrFail(new Collection([1, 1, 2, 3]));\n    }\n\n    public function testOneToOneRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->post()->create(['name' => 'First Post']);\n\n        $post = $user->post;\n        $user = $post->user;\n\n        $this->assertTrue(isset($user->post->name));\n        $this->assertInstanceOf(EloquentTestUser::class, $user);\n        $this->assertInstanceOf(EloquentTestPost::class, $post);\n        $this->assertSame('taylorotwell@gmail.com', $user->email);\n        $this->assertSame('First Post', $post->name);\n    }\n\n    public function testIssetLoadsInRelationshipIfItIsntLoadedAlready()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->post()->create(['name' => 'First Post']);\n\n        $this->assertTrue(isset($user->post->name));\n    }\n\n    public function testOneToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->posts()->create(['name' => 'First Post']);\n        $user->posts()->create(['name' => 'Second Post']);\n\n        $posts = $user->posts;\n        $post2 = $user->posts()->where('name', 'Second Post')->first();\n\n        $this->assertInstanceOf(Collection::class, $posts);\n        $this->assertCount(2, $posts);\n        $this->assertInstanceOf(EloquentTestPost::class, $posts[0]);\n        $this->assertInstanceOf(EloquentTestPost::class, $posts[1]);\n        $this->assertInstanceOf(EloquentTestPost::class, $post2);\n        $this->assertSame('Second Post', $post2->name);\n        $this->assertInstanceOf(EloquentTestUser::class, $post2->user);\n        $this->assertSame('taylorotwell@gmail.com', $post2->user->email);\n    }\n\n    public function testBasicModelHydration()\n    {\n        $user = new EloquentTestUser(['email' => 'taylorotwell@gmail.com']);\n        $user->setConnection('second_connection');\n        $user->save();\n\n        $user = new EloquentTestUser(['email' => 'abigailotwell@gmail.com']);\n        $user->setConnection('second_connection');\n        $user->save();\n\n        $models = EloquentTestUser::on('second_connection')->fromQuery('SELECT * FROM users WHERE email = ?', ['abigailotwell@gmail.com']);\n\n        $this->assertInstanceOf(Collection::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertSame('abigailotwell@gmail.com', $models[0]->email);\n        $this->assertSame('second_connection', $models[0]->getConnectionName());\n        $this->assertCount(1, $models);\n    }\n\n    public function testFirstOrNewOnHasOneRelationShip()\n    {\n        $user1 = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $post1 = $user1->post()->firstOrNew(['name' => 'First Post'], ['name' => 'New Post']);\n\n        $this->assertSame('New Post', $post1->name);\n\n        $user2 = EloquentTestUser::create(['email' => 'abigailotwell@gmail.com']);\n        $post = $user2->post()->create(['name' => 'First Post']);\n        $post2 = $user2->post()->firstOrNew(['name' => 'First Post'], ['name' => 'New Post']);\n\n        $this->assertSame('First Post', $post2->name);\n        $this->assertSame($post->id, $post2->id);\n    }\n\n    public function testFirstOrCreateOnHasOneRelationShip()\n    {\n        $user1 = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $post1 = $user1->post()->firstOrCreate(['name' => 'First Post'], ['name' => 'New Post']);\n\n        $this->assertSame('New Post', $post1->name);\n\n        $user2 = EloquentTestUser::create(['email' => 'abigailotwell@gmail.com']);\n        $post = $user2->post()->create(['name' => 'First Post']);\n        $post2 = $user2->post()->firstOrCreate(['name' => 'First Post'], ['name' => 'New Post']);\n\n        $this->assertSame('First Post', $post2->name);\n        $this->assertSame($post->id, $post2->id);\n    }\n\n    public function testHasOnSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        $this->assertTrue(isset($user->friends[0]->id));\n\n        $results = EloquentTestUser::has('friends')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testWhereHasOnSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        $results = EloquentTestUser::whereHas('friends', function ($query) {\n            $query->where('email', 'abigailotwell@gmail.com');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testWithWhereHasOnSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        $results = EloquentTestUser::withWhereHas('friends', function ($query) {\n            $query->where('email', 'abigailotwell@gmail.com');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n        $this->assertTrue($results->first()->relationLoaded('friends'));\n        $this->assertSame($results->first()->friends->pluck('email')->unique()->toArray(), ['abigailotwell@gmail.com']);\n    }\n\n    public function testHasOnNestedSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n        $friend->friends()->create(['email' => 'foo@gmail.com']);\n\n        $results = EloquentTestUser::has('friends.friends')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testWhereHasOnNestedSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n        $friend->friends()->create(['email' => 'foo@gmail.com']);\n\n        $results = EloquentTestUser::whereHas('friends.friends', function ($query) {\n            $query->where('email', 'foo@gmail.com');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testWithWhereHasOnNestedSelfReferencingBelongsToManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n        $friend->friends()->create(['email' => 'foo@gmail.com']);\n\n        $results = EloquentTestUser::withWhereHas('friends.friends', function ($query) {\n            $query->where('email', 'foo@gmail.com');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n        $this->assertTrue($results->first()->relationLoaded('friends'));\n        $this->assertSame($results->first()->friends->pluck('email')->unique()->toArray(), ['abigailotwell@gmail.com']);\n        $this->assertSame($results->first()->friends->pluck('friends')->flatten()->pluck('email')->unique()->toArray(), ['foo@gmail.com']);\n    }\n\n    public function testHasOnSelfReferencingBelongsToManyRelationshipWithWherePivot()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        $results = EloquentTestUser::has('friendsOne')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testHasOnNestedSelfReferencingBelongsToManyRelationshipWithWherePivot()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n        $friend->friends()->create(['email' => 'foo@gmail.com']);\n\n        $results = EloquentTestUser::has('friendsOne.friendsTwo')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('taylorotwell@gmail.com', $results->first()->email);\n    }\n\n    public function testHasOnSelfReferencingBelongsToRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::has('parentPost')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n    }\n\n    public function testAggregatedValuesOfDatetimeField()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'test1@test.test', 'created_at' => '2016-08-10 09:21:00', 'updated_at' => Carbon::now()],\n            ['id' => 2, 'email' => 'test2@test.test', 'created_at' => '2016-08-01 12:00:00', 'updated_at' => Carbon::now()],\n        ]);\n\n        $this->assertSame('2016-08-10 09:21:00', EloquentTestUser::max('created_at'));\n        $this->assertSame('2016-08-01 12:00:00', EloquentTestUser::min('created_at'));\n    }\n\n    public function testWhereHasOnSelfReferencingBelongsToRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::whereHas('parentPost', function ($query) {\n            $query->where('name', 'Parent Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n    }\n\n    public function testWithWhereHasOnSelfReferencingBelongsToRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::withWhereHas('parentPost', function ($query) {\n            $query->where('name', 'Parent Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n        $this->assertTrue($results->first()->relationLoaded('parentPost'));\n        $this->assertSame($results->first()->parentPost->name, 'Parent Post');\n    }\n\n    public function testHasOnNestedSelfReferencingBelongsToRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::has('parentPost.parentPost')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n    }\n\n    public function testWhereHasOnNestedSelfReferencingBelongsToRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::whereHas('parentPost.parentPost', function ($query) {\n            $query->where('name', 'Grandparent Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n    }\n\n    public function testWithWhereHasOnNestedSelfReferencingBelongsToRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::withWhereHas('parentPost.parentPost', function ($query) {\n            $query->where('name', 'Grandparent Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Child Post', $results->first()->name);\n        $this->assertTrue($results->first()->relationLoaded('parentPost'));\n        $this->assertSame($results->first()->parentPost->name, 'Parent Post');\n        $this->assertTrue($results->first()->parentPost->relationLoaded('parentPost'));\n        $this->assertSame($results->first()->parentPost->parentPost->name, 'Grandparent Post');\n    }\n\n    public function testHasOnSelfReferencingHasManyRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::has('childPosts')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Parent Post', $results->first()->name);\n    }\n\n    public function testWhereHasOnSelfReferencingHasManyRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::whereHas('childPosts', function ($query) {\n            $query->where('name', 'Child Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Parent Post', $results->first()->name);\n    }\n\n    public function testWithWhereHasOnSelfReferencingHasManyRelationship()\n    {\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 2]);\n\n        $results = EloquentTestPost::withWhereHas('childPosts', function ($query) {\n            $query->where('name', 'Child Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Parent Post', $results->first()->name);\n        $this->assertTrue($results->first()->relationLoaded('childPosts'));\n        $this->assertSame($results->first()->childPosts->pluck('name')->unique()->toArray(), ['Child Post']);\n    }\n\n    public function testHasOnNestedSelfReferencingHasManyRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::has('childPosts.childPosts')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Grandparent Post', $results->first()->name);\n    }\n\n    public function testWhereHasOnNestedSelfReferencingHasManyRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::whereHas('childPosts.childPosts', function ($query) {\n            $query->where('name', 'Child Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Grandparent Post', $results->first()->name);\n    }\n\n    public function testWithWhereHasOnNestedSelfReferencingHasManyRelationship()\n    {\n        $grandParentPost = EloquentTestPost::create(['name' => 'Grandparent Post', 'user_id' => 1]);\n        $parentPost = EloquentTestPost::create(['name' => 'Parent Post', 'parent_id' => $grandParentPost->id, 'user_id' => 2]);\n        EloquentTestPost::create(['name' => 'Child Post', 'parent_id' => $parentPost->id, 'user_id' => 3]);\n\n        $results = EloquentTestPost::withWhereHas('childPosts.childPosts', function ($query) {\n            $query->where('name', 'Child Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Grandparent Post', $results->first()->name);\n        $this->assertTrue($results->first()->relationLoaded('childPosts'));\n        $this->assertSame($results->first()->childPosts->pluck('name')->unique()->toArray(), ['Parent Post']);\n        $this->assertSame($results->first()->childPosts->pluck('childPosts')->flatten()->pluck('name')->unique()->toArray(), ['Child Post']);\n    }\n\n    public function testHasWithNonWhereBindings()\n    {\n        $user = EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n\n        $user->posts()->create(['name' => 'Post 2'])\n            ->photos()->create(['name' => 'photo.jpg']);\n\n        $query = EloquentTestUser::has('postWithPhotos');\n\n        $bindingsCount = count($query->getBindings());\n        $questionMarksCount = substr_count($query->toSql(), '?');\n\n        $this->assertEquals($questionMarksCount, $bindingsCount);\n    }\n\n    public function testHasOnMorphToRelationship()\n    {\n        $post = EloquentTestPost::create(['name' => 'Morph Post', 'user_id' => 1]);\n        (new EloquentTestPhoto)->imageable()->associate($post)->fill(['name' => 'Morph Photo'])->save();\n\n        $photos = EloquentTestPhoto::has('imageable')->get();\n\n        $this->assertEquals(1, $photos->count());\n    }\n\n    public function testBelongsToManyRelationshipModelsAreProperlyHydratedWithSoleQuery()\n    {\n        $user = EloquentTestUserWithCustomFriendPivot::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        $user->friends()->get()->each(function ($friend) {\n            $this->assertInstanceOf(EloquentTestFriendPivot::class, $friend->pivot);\n        });\n\n        $soleFriend = $user->friends()->where('email', 'abigailotwell@gmail.com')->sole();\n\n        $this->assertInstanceOf(EloquentTestFriendPivot::class, $soleFriend->pivot);\n    }\n\n    public function testBelongsToManyRelationshipMissingModelExceptionWithSoleQueryWorks()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $user = EloquentTestUserWithCustomFriendPivot::create(['email' => 'taylorotwell@gmail.com']);\n        $user->friends()->where('email', 'abigailotwell@gmail.com')->sole();\n    }\n\n    public function testBelongsToManyRelationshipModelsAreProperlyHydratedOverChunkedRequest()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        EloquentTestUser::first()->friends()->chunk(2, function ($friends) use ($user, $friend) {\n            $this->assertCount(1, $friends);\n            $this->assertSame('abigailotwell@gmail.com', $friends->first()->email);\n            $this->assertEquals($user->id, $friends->first()->pivot->user_id);\n            $this->assertEquals($friend->id, $friends->first()->pivot->friend_id);\n        });\n    }\n\n    public function testBelongsToManyRelationshipModelsAreProperlyHydratedOverEachRequest()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        EloquentTestUser::first()->friends()->each(function ($result) use ($user, $friend) {\n            $this->assertSame('abigailotwell@gmail.com', $result->email);\n            $this->assertEquals($user->id, $result->pivot->user_id);\n            $this->assertEquals($friend->id, $result->pivot->friend_id);\n        });\n    }\n\n    public function testBelongsToManyRelationshipModelsAreProperlyHydratedOverCursorRequest()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $friend = $user->friends()->create(['email' => 'abigailotwell@gmail.com']);\n\n        foreach (EloquentTestUser::first()->friends()->cursor() as $result) {\n            $this->assertSame('abigailotwell@gmail.com', $result->email);\n            $this->assertEquals($user->id, $result->pivot->user_id);\n            $this->assertEquals($friend->id, $result->pivot->friend_id);\n        }\n    }\n\n    public function testWhereAttachedTo()\n    {\n        EloquentTestUser::insert([\n            ['email' => 'user1@gmail.com'],\n            ['email' => 'user2@gmail.com'],\n            ['email' => 'user3@gmail.com'],\n        ]);\n\n        [$user1, $user2, $user3] = EloquentTestUser::get();\n\n        EloquentTestAchievement::fillAndInsert([['status' => 3], [], []]);\n        [$achievement1, $achievement2, $achievement3] = EloquentTestAchievement::get();\n\n        $user1->eloquentTestAchievements()->attach([$achievement1]);\n        $user2->eloquentTestAchievements()->attach([$achievement1, $achievement3]);\n        $user3->eloquentTestAchievements()->attach([$achievement2, $achievement3]);\n\n        $achievedAchievement1 = EloquentTestUser::whereAttachedTo($achievement1)->get();\n\n        $this->assertSame(2, $achievedAchievement1->count());\n        $this->assertTrue($achievedAchievement1->contains($user1));\n        $this->assertTrue($achievedAchievement1->contains($user2));\n\n        $achievedByUser1or2 = EloquentTestAchievement::whereAttachedTo(\n            new Collection([$user1, $user2])\n        )->get();\n\n        $this->assertSame(2, $achievedByUser1or2->count());\n        $this->assertTrue($achievedByUser1or2->contains($achievement1));\n        $this->assertTrue($achievedByUser1or2->contains($achievement3));\n    }\n\n    public function testBasicHasManyEagerLoading()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->posts()->create(['name' => 'First Post']);\n        $user = EloquentTestUser::with('posts')->where('email', 'taylorotwell@gmail.com')->first();\n\n        $this->assertSame('First Post', $user->posts->first()->name);\n\n        $post = EloquentTestPost::with('user')->where('name', 'First Post')->get();\n        $this->assertSame('taylorotwell@gmail.com', $post->first()->user->email);\n    }\n\n    public function testBasicNestedSelfReferencingHasManyEagerLoading()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $post = $user->posts()->create(['name' => 'First Post']);\n        $post->childPosts()->create(['name' => 'Child Post', 'user_id' => $user->id]);\n\n        $user = EloquentTestUser::with('posts.childPosts')->where('email', 'taylorotwell@gmail.com')->first();\n\n        $this->assertNotNull($user->posts->first());\n        $this->assertSame('First Post', $user->posts->first()->name);\n\n        $this->assertNotNull($user->posts->first()->childPosts->first());\n        $this->assertSame('Child Post', $user->posts->first()->childPosts->first()->name);\n\n        $post = EloquentTestPost::with('parentPost.user')->where('name', 'Child Post')->get();\n        $this->assertNotNull($post->first()->parentPost);\n        $this->assertNotNull($post->first()->parentPost->user);\n        $this->assertSame('taylorotwell@gmail.com', $post->first()->parentPost->user->email);\n    }\n\n    public function testBasicMorphManyRelationship()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->photos()->create(['name' => 'Avatar 1']);\n        $user->photos()->create(['name' => 'Avatar 2']);\n        $post = $user->posts()->create(['name' => 'First Post']);\n        $post->photos()->create(['name' => 'Hero 1']);\n        $post->photos()->create(['name' => 'Hero 2']);\n\n        $this->assertInstanceOf(Collection::class, $user->photos);\n        $this->assertInstanceOf(EloquentTestPhoto::class, $user->photos[0]);\n        $this->assertInstanceOf(Collection::class, $post->photos);\n        $this->assertInstanceOf(EloquentTestPhoto::class, $post->photos[0]);\n        $this->assertCount(2, $user->photos);\n        $this->assertCount(2, $post->photos);\n        $this->assertSame('Avatar 1', $user->photos[0]->name);\n        $this->assertSame('Avatar 2', $user->photos[1]->name);\n        $this->assertSame('Hero 1', $post->photos[0]->name);\n        $this->assertSame('Hero 2', $post->photos[1]->name);\n\n        $photos = EloquentTestPhoto::orderBy('name')->get();\n\n        $this->assertInstanceOf(Collection::class, $photos);\n        $this->assertCount(4, $photos);\n        $this->assertInstanceOf(EloquentTestUser::class, $photos[0]->imageable);\n        $this->assertInstanceOf(EloquentTestPost::class, $photos[2]->imageable);\n        $this->assertSame('taylorotwell@gmail.com', $photos[1]->imageable->email);\n        $this->assertSame('First Post', $photos[3]->imageable->name);\n    }\n\n    public function testMorphMapIsUsedForCreatingAndFetchingThroughRelation()\n    {\n        Relation::morphMap([\n            'user' => EloquentTestUser::class,\n            'post' => EloquentTestPost::class,\n        ]);\n\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->photos()->create(['name' => 'Avatar 1']);\n        $user->photos()->create(['name' => 'Avatar 2']);\n        $post = $user->posts()->create(['name' => 'First Post']);\n        $post->photos()->create(['name' => 'Hero 1']);\n        $post->photos()->create(['name' => 'Hero 2']);\n\n        $this->assertInstanceOf(Collection::class, $user->photos);\n        $this->assertInstanceOf(EloquentTestPhoto::class, $user->photos[0]);\n        $this->assertInstanceOf(Collection::class, $post->photos);\n        $this->assertInstanceOf(EloquentTestPhoto::class, $post->photos[0]);\n        $this->assertCount(2, $user->photos);\n        $this->assertCount(2, $post->photos);\n        $this->assertSame('Avatar 1', $user->photos[0]->name);\n        $this->assertSame('Avatar 2', $user->photos[1]->name);\n        $this->assertSame('Hero 1', $post->photos[0]->name);\n        $this->assertSame('Hero 2', $post->photos[1]->name);\n\n        $this->assertSame('user', $user->photos[0]->imageable_type);\n        $this->assertSame('user', $user->photos[1]->imageable_type);\n        $this->assertSame('post', $post->photos[0]->imageable_type);\n        $this->assertSame('post', $post->photos[1]->imageable_type);\n    }\n\n    public function testMorphMapIsUsedWhenFetchingParent()\n    {\n        Relation::morphMap([\n            'user' => EloquentTestUser::class,\n            'post' => EloquentTestPost::class,\n        ]);\n\n        $user = EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        $user->photos()->create(['name' => 'Avatar 1']);\n\n        $photo = EloquentTestPhoto::first();\n        $this->assertSame('user', $photo->imageable_type);\n        $this->assertInstanceOf(EloquentTestUser::class, $photo->imageable);\n    }\n\n    public function testMorphMapIsMergedByDefault()\n    {\n        $map1 = [\n            'user' => EloquentTestUser::class,\n        ];\n        $map2 = [\n            'post' => EloquentTestPost::class,\n        ];\n\n        Relation::morphMap($map1);\n        Relation::morphMap($map2);\n\n        $this->assertEquals(array_merge($map1, $map2), Relation::morphMap());\n    }\n\n    public function testMorphMapOverwritesCurrentMap()\n    {\n        $map1 = [\n            'user' => EloquentTestUser::class,\n        ];\n        $map2 = [\n            'post' => EloquentTestPost::class,\n        ];\n\n        Relation::morphMap($map1, false);\n        $this->assertEquals($map1, Relation::morphMap());\n        Relation::morphMap($map2, false);\n        $this->assertEquals($map2, Relation::morphMap());\n    }\n\n    public function testEmptyMorphToRelationship()\n    {\n        $photo = new EloquentTestPhoto;\n\n        $this->assertNull($photo->imageable);\n    }\n\n    public function testSaveOrFail()\n    {\n        $date = '1970-01-01';\n        $post = new EloquentTestPost([\n            'user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date,\n        ]);\n\n        $this->assertTrue($post->saveOrFail());\n        $this->assertEquals(1, EloquentTestPost::count());\n    }\n\n    public function testSavingJSONFields()\n    {\n        $model = EloquentTestWithJSON::create(['json' => ['x' => 0]]);\n        $this->assertEquals(['x' => 0], $model->json);\n\n        $model->fillable(['json->y', 'json->a->b']);\n\n        $model->update(['json->y' => '1']);\n        $this->assertArrayNotHasKey('json->y', $model->toArray());\n        $this->assertEquals(['x' => 0, 'y' => 1], $model->json);\n\n        $model->update(['json->a->b' => '3']);\n        $this->assertArrayNotHasKey('json->a->b', $model->toArray());\n        $this->assertEquals(['x' => 0, 'y' => 1, 'a' => ['b' => 3]], $model->json);\n    }\n\n    public function testSaveOrFailWithDuplicatedEntry()\n    {\n        $this->expectException(QueryException::class);\n        $this->expectExceptionMessage('SQLSTATE[23000]:');\n\n        $date = '1970-01-01';\n        EloquentTestPost::create([\n            'id' => 1, 'user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date,\n        ]);\n\n        $post = new EloquentTestPost([\n            'id' => 1, 'user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date,\n        ]);\n\n        $post->saveOrFail();\n    }\n\n    public function testMultiInsertsWithDifferentValues()\n    {\n        $date = '1970-01-01';\n        $result = EloquentTestPost::insert([\n            ['user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date],\n            ['user_id' => 2, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date],\n        ]);\n\n        $this->assertTrue($result);\n        $this->assertEquals(2, EloquentTestPost::count());\n    }\n\n    public function testMultiInsertsWithSameValues()\n    {\n        $date = '1970-01-01';\n        $result = EloquentTestPost::insert([\n            ['user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date],\n            ['user_id' => 1, 'name' => 'Post', 'created_at' => $date, 'updated_at' => $date],\n        ]);\n\n        $this->assertTrue($result);\n        $this->assertEquals(2, EloquentTestPost::count());\n    }\n\n    public function testNestedTransactions()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylor@laravel.com']);\n        $this->connection()->transaction(function () use ($user) {\n            try {\n                $this->connection()->transaction(function () use ($user) {\n                    $user->email = 'otwell@laravel.com';\n                    $user->save();\n                    throw new Exception;\n                });\n            } catch (Exception) {\n                // ignore the exception\n            }\n            $user = EloquentTestUser::first();\n            $this->assertSame('taylor@laravel.com', $user->email);\n        });\n    }\n\n    public function testNestedTransactionsUsingSaveOrFailWillSucceed()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylor@laravel.com']);\n        $this->connection()->transaction(function () use ($user) {\n            try {\n                $user->email = 'otwell@laravel.com';\n                $user->saveOrFail();\n            } catch (Exception) {\n                // ignore the exception\n            }\n\n            $user = EloquentTestUser::first();\n            $this->assertSame('otwell@laravel.com', $user->email);\n            $this->assertEquals(1, $user->id);\n        });\n    }\n\n    public function testNestedTransactionsUsingSaveOrFailWillFails()\n    {\n        $user = EloquentTestUser::create(['email' => 'taylor@laravel.com']);\n        $this->connection()->transaction(function () use ($user) {\n            try {\n                $user->id = 'invalid';\n                $user->email = 'otwell@laravel.com';\n                $user->saveOrFail();\n            } catch (Exception) {\n                // ignore the exception\n            }\n\n            $user = EloquentTestUser::first();\n            $this->assertSame('taylor@laravel.com', $user->email);\n            $this->assertEquals(1, $user->id);\n        });\n    }\n\n    public function testToArrayIncludesDefaultFormattedTimestamps()\n    {\n        $model = new EloquentTestUser;\n\n        $model->setRawAttributes([\n            'created_at' => '2012-12-04',\n            'updated_at' => '2012-12-05',\n        ]);\n\n        $array = $model->toArray();\n\n        $this->assertSame('2012-12-04T00:00:00.000000Z', $array['created_at']);\n        $this->assertSame('2012-12-05T00:00:00.000000Z', $array['updated_at']);\n    }\n\n    public function testToArrayIncludesCustomFormattedTimestamps()\n    {\n        $model = new EloquentTestUserWithCustomDateSerialization;\n\n        $model->setRawAttributes([\n            'created_at' => '2012-12-04',\n            'updated_at' => '2012-12-05',\n        ]);\n\n        $array = $model->toArray();\n\n        $this->assertSame('04-12-12', $array['created_at']);\n        $this->assertSame('05-12-12', $array['updated_at']);\n    }\n\n    public function testIncrementingPrimaryKeysAreCastToIntegersByDefault()\n    {\n        EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n\n        $user = EloquentTestUser::first();\n        $this->assertIsInt($user->id);\n    }\n\n    public function testDefaultIncrementingPrimaryKeyIntegerCastCanBeOverwritten()\n    {\n        EloquentTestUserWithStringCastId::create(['email' => 'taylorotwell@gmail.com']);\n\n        $user = EloquentTestUserWithStringCastId::first();\n        $this->assertIsString($user->id);\n    }\n\n    public function testRelationsArePreloadedInGlobalScope()\n    {\n        $user = EloquentTestUserWithGlobalScope::create(['email' => 'taylorotwell@gmail.com']);\n        $user->posts()->create(['name' => 'My Post']);\n\n        $result = EloquentTestUserWithGlobalScope::first();\n\n        $this->assertCount(1, $result->getRelations());\n    }\n\n    public function testModelIgnoredByGlobalScopeCanBeRefreshed()\n    {\n        $user = EloquentTestUserWithOmittingGlobalScope::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n\n        $this->assertNotNull($user->fresh());\n    }\n\n    public function testGlobalScopeCanBeRemovedByOtherGlobalScope()\n    {\n        $user = EloquentTestUserWithGlobalScopeRemovingOtherScope::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $user->delete();\n\n        $this->assertNotNull(EloquentTestUserWithGlobalScopeRemovingOtherScope::find($user->id));\n    }\n\n    public function testForPageBeforeIdCorrectlyPaginates()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n        ]);\n\n        $results = EloquentTestUser::forPageBeforeId(15, 2);\n        $this->assertInstanceOf(Builder::class, $results);\n        $this->assertEquals(1, $results->first()->id);\n\n        $results = EloquentTestUser::orderBy('id', 'desc')->forPageBeforeId(15, 2);\n        $this->assertInstanceOf(Builder::class, $results);\n        $this->assertEquals(1, $results->first()->id);\n    }\n\n    public function testForPageAfterIdCorrectlyPaginates()\n    {\n        EloquentTestUser::insert([\n            ['id' => 1, 'email' => 'taylorotwell@gmail.com'],\n            ['id' => 2, 'email' => 'abigailotwell@gmail.com'],\n        ]);\n\n        $results = EloquentTestUser::forPageAfterId(15, 1);\n        $this->assertInstanceOf(Builder::class, $results);\n        $this->assertEquals(2, $results->first()->id);\n\n        $results = EloquentTestUser::orderBy('id', 'desc')->forPageAfterId(15, 1);\n        $this->assertInstanceOf(Builder::class, $results);\n        $this->assertEquals(2, $results->first()->id);\n    }\n\n    public function testMorphToRelationsAcrossDatabaseConnections()\n    {\n        $item = null;\n\n        EloquentTestItem::create(['id' => 1]);\n        EloquentTestOrder::create(['id' => 1, 'item_type' => EloquentTestItem::class, 'item_id' => 1]);\n        try {\n            $item = EloquentTestOrder::first()->item;\n        } catch (Exception) {\n            // ignore the exception\n        }\n\n        $this->assertInstanceOf(EloquentTestItem::class, $item);\n    }\n\n    public function testEagerLoadedMorphToRelationsOnAnotherDatabaseConnection()\n    {\n        EloquentTestPost::create(['id' => 1, 'name' => 'Default Connection Post', 'user_id' => 1]);\n        EloquentTestPhoto::create(['id' => 1, 'imageable_type' => EloquentTestPost::class, 'imageable_id' => 1, 'name' => 'Photo']);\n\n        EloquentTestPost::on('second_connection')\n            ->create(['id' => 1, 'name' => 'Second Connection Post', 'user_id' => 1]);\n        EloquentTestPhoto::on('second_connection')\n            ->create(['id' => 1, 'imageable_type' => EloquentTestPost::class, 'imageable_id' => 1, 'name' => 'Photo']);\n\n        $defaultConnectionPost = EloquentTestPhoto::with('imageable')->first()->imageable;\n        $secondConnectionPost = EloquentTestPhoto::on('second_connection')->with('imageable')->first()->imageable;\n\n        $this->assertSame('Default Connection Post', $defaultConnectionPost->name);\n        $this->assertSame('Second Connection Post', $secondConnectionPost->name);\n    }\n\n    public function testBelongsToManyCustomPivot()\n    {\n        $john = EloquentTestUserWithCustomFriendPivot::create(['id' => 1, 'name' => 'John Doe', 'email' => 'johndoe@example.com']);\n        $jane = EloquentTestUserWithCustomFriendPivot::create(['id' => 2, 'name' => 'Jane Doe', 'email' => 'janedoe@example.com']);\n        $jack = EloquentTestUserWithCustomFriendPivot::create(['id' => 3, 'name' => 'Jack Doe', 'email' => 'jackdoe@example.com']);\n        $jule = EloquentTestUserWithCustomFriendPivot::create(['id' => 4, 'name' => 'Jule Doe', 'email' => 'juledoe@example.com']);\n\n        EloquentTestFriendLevel::insert([\n            ['id' => 1, 'level' => 'acquaintance'],\n            ['id' => 2, 'level' => 'friend'],\n            ['id' => 3, 'level' => 'bff'],\n        ]);\n\n        $john->friends()->attach($jane, ['friend_level_id' => 1]);\n        $john->friends()->attach($jack, ['friend_level_id' => 2]);\n        $john->friends()->attach($jule, ['friend_level_id' => 3]);\n\n        $johnWithFriends = EloquentTestUserWithCustomFriendPivot::with('friends')->find(1);\n\n        $this->assertCount(3, $johnWithFriends->friends);\n        $this->assertSame('friend', $johnWithFriends->friends->find(3)->pivot->level->level);\n        $this->assertSame('Jule Doe', $johnWithFriends->friends->find(4)->pivot->friend->name);\n    }\n\n    public function testIsAfterRetrievingTheSameModel()\n    {\n        $saved = EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $retrieved = EloquentTestUser::find(1);\n\n        $this->assertTrue($saved->is($retrieved));\n    }\n\n    public function testFreshMethodOnModel()\n    {\n        $now = Carbon::now()->startOfSecond();\n        $nowSerialized = $now->toJSON();\n        $nowWithFractionsSerialized = $now->toJSON();\n        Carbon::setTestNow($now);\n\n        $storedUser1 = EloquentTestUser::create([\n            'id' => 1,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $now,\n        ]);\n        $storedUser1->newQuery()->update([\n            'email' => 'dev@mathieutu.ovh',\n            'name' => 'Mathieu TUDISCO',\n        ]);\n        $freshStoredUser1 = $storedUser1->fresh();\n\n        $storedUser2 = EloquentTestUser::create([\n            'id' => 2,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $now,\n        ]);\n        $storedUser2->newQuery()->update(['email' => 'dev@mathieutu.ovh']);\n        $freshStoredUser2 = $storedUser2->fresh();\n\n        $notStoredUser = new EloquentTestUser([\n            'id' => 3,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $now,\n        ]);\n        $freshNotStoredUser = $notStoredUser->fresh();\n\n        $this->assertEquals([\n            'id' => 1,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $nowWithFractionsSerialized,\n            'created_at' => $nowSerialized,\n            'updated_at' => $nowSerialized,\n        ], $storedUser1->toArray());\n        $this->assertEquals([\n            'id' => 1,\n            'name' => 'Mathieu TUDISCO',\n            'email' => 'dev@mathieutu.ovh',\n            'birthday' => $nowWithFractionsSerialized,\n            'created_at' => $nowSerialized,\n            'updated_at' => $nowSerialized,\n        ], $freshStoredUser1->toArray());\n        $this->assertInstanceOf(EloquentTestUser::class, $storedUser1);\n\n        $this->assertEquals([\n            'id' => 2,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $nowWithFractionsSerialized,\n            'created_at' => $nowSerialized,\n            'updated_at' => $nowSerialized,\n        ], $storedUser2->toArray());\n        $this->assertEquals([\n            'id' => 2,\n            'name' => null,\n            'email' => 'dev@mathieutu.ovh',\n            'birthday' => $nowWithFractionsSerialized,\n            'created_at' => $nowSerialized,\n            'updated_at' => $nowSerialized,\n        ], $freshStoredUser2->toArray());\n        $this->assertInstanceOf(EloquentTestUser::class, $storedUser2);\n\n        $this->assertEquals([\n            'id' => 3,\n            'email' => 'taylorotwell@gmail.com',\n            'birthday' => $nowWithFractionsSerialized,\n        ], $notStoredUser->toArray());\n        $this->assertNull($freshNotStoredUser);\n    }\n\n    public function testFreshMethodOnCollection()\n    {\n        EloquentTestUser::insert([['id' => 1, 'email' => 'taylorotwell@gmail.com'], ['id' => 2, 'email' => 'taylorotwell@gmail.com']]);\n\n        $users = EloquentTestUser::all()\n            ->add(new EloquentTestUser(['id' => 3, 'email' => 'taylorotwell@gmail.com']));\n\n        EloquentTestUser::find(1)->update(['name' => 'Mathieu TUDISCO']);\n        EloquentTestUser::find(2)->update(['email' => 'dev@mathieutu.ovh']);\n\n        $this->assertCount(3, $users);\n        $this->assertNotSame('Mathieu TUDISCO', $users[0]->name);\n        $this->assertNotSame('dev@mathieutu.ovh', $users[1]->email);\n\n        $refreshedUsers = $users->fresh();\n\n        $this->assertCount(2, $refreshedUsers);\n        $this->assertSame('Mathieu TUDISCO', $refreshedUsers[0]->name);\n        $this->assertSame('dev@mathieutu.ovh', $refreshedUsers[1]->email);\n    }\n\n    public function testTimestampsUsingDefaultDateFormat()\n    {\n        $model = new EloquentTestUser;\n        $model->setDateFormat('Y-m-d H:i:s'); // Default MySQL/PostgreSQL/SQLite date format\n        $model->setRawAttributes([\n            'created_at' => '2017-11-14 08:23:19',\n        ]);\n\n        $this->assertSame('2017-11-14 08:23:19', $model->fromDateTime($model->getAttribute('created_at')));\n    }\n\n    public function testTimestampsUsingDefaultSqlServerDateFormat()\n    {\n        $model = new EloquentTestUser;\n        $model->setDateFormat('Y-m-d H:i:s.v'); // Default SQL Server date format\n        $model->setRawAttributes([\n            'created_at' => '2017-11-14 08:23:19.000',\n            'updated_at' => '2017-11-14 08:23:19.734',\n        ]);\n\n        $this->assertSame('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at')));\n        $this->assertSame('2017-11-14 08:23:19.734', $model->fromDateTime($model->getAttribute('updated_at')));\n    }\n\n    public function testTimestampsUsingCustomDateFormat()\n    {\n        // Simulating using custom precisions with timestamps(4)\n        $model = new EloquentTestUser;\n        $model->setDateFormat('Y-m-d H:i:s.u'); // Custom date format\n        $model->setRawAttributes([\n            'created_at' => '2017-11-14 08:23:19.0000',\n            'updated_at' => '2017-11-14 08:23:19.7348',\n        ]);\n\n        // Note: when storing databases would truncate the value to the given precision\n        $this->assertSame('2017-11-14 08:23:19.000000', $model->fromDateTime($model->getAttribute('created_at')));\n        $this->assertSame('2017-11-14 08:23:19.734800', $model->fromDateTime($model->getAttribute('updated_at')));\n    }\n\n    public function testTimestampsUsingOldSqlServerDateFormat()\n    {\n        $model = new EloquentTestUser;\n        $model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format\n        $model->setRawAttributes([\n            'created_at' => '2017-11-14 08:23:19.000',\n        ]);\n\n        $this->assertSame('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at')));\n    }\n\n    public function testTimestampsUsingOldSqlServerDateFormatFallbackToDefaultParsing()\n    {\n        $model = new EloquentTestUser;\n        $model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format\n        $model->setRawAttributes([\n            'updated_at' => '2017-11-14 08:23:19.734',\n        ]);\n\n        $date = $model->getAttribute('updated_at');\n        $this->assertSame('2017-11-14 08:23:19.734', $date->format('Y-m-d H:i:s.v'), 'the date should contains the precision');\n        $this->assertSame('2017-11-14 08:23:19.000', $model->fromDateTime($date), 'the format should trims it');\n        // No longer throwing exception since Laravel 7,\n        // but Date::hasFormat() can be used instead to check date formatting:\n        $this->assertTrue(Date::hasFormat('2017-11-14 08:23:19.000', $model->getDateFormat()));\n        $this->assertFalse(Date::hasFormat('2017-11-14 08:23:19.734', $model->getDateFormat()));\n    }\n\n    public function testSpecialFormats()\n    {\n        $model = new EloquentTestUser;\n        $model->setDateFormat('!Y-d-m \\\\Y');\n        $model->setRawAttributes([\n            'updated_at' => '2017-05-11 Y',\n        ]);\n\n        $date = $model->getAttribute('updated_at');\n        $this->assertSame('2017-11-05 00:00:00.000000', $date->format('Y-m-d H:i:s.u'), 'the date should respect the whole format');\n\n        $model->setDateFormat('Y d m|');\n        $model->setRawAttributes([\n            'updated_at' => '2020 11 09',\n        ]);\n\n        $date = $model->getAttribute('updated_at');\n        $this->assertSame('2020-09-11 00:00:00.000000', $date->format('Y-m-d H:i:s.u'), 'the date should respect the whole format');\n\n        $model->setDateFormat('Y d m|*');\n        $model->setRawAttributes([\n            'updated_at' => '2020 11 09 foo',\n        ]);\n\n        $date = $model->getAttribute('updated_at');\n        $this->assertSame('2020-09-11 00:00:00.000000', $date->format('Y-m-d H:i:s.u'), 'the date should respect the whole format');\n    }\n\n    public function testUpdatingChildModelTouchesParent()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        $post->update(['name' => 'Updated']);\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is not touching model own timestamps.');\n        $this->assertTrue($future->isSameDay($user->fresh()->updated_at), 'It is not touching models related timestamps.');\n    }\n\n    public function testMultiLevelTouchingWorks()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingComment::create(['content' => 'Comment content', 'post_id' => 1]);\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is not touching models related timestamps.');\n        $this->assertTrue($future->isSameDay($user->fresh()->updated_at), 'It is not touching models related timestamps.');\n    }\n\n    public function testDeletingChildModelTouchesParentTimestamps()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        $post->delete();\n\n        $this->assertTrue($future->isSameDay($user->fresh()->updated_at), 'It is not touching models related timestamps.');\n    }\n\n    public function testTouchingChildModelUpdatesParentsTimestamps()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        $post->touch();\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is not touching model own timestamps.');\n        $this->assertTrue($future->isSameDay($user->fresh()->updated_at), 'It is not touching models related timestamps.');\n    }\n\n    public function testTouchingChildModelRespectsParentNoTouching()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingUser::withoutTouching(function () use ($post) {\n            $post->touch();\n        });\n\n        $this->assertTrue(\n            $future->isSameDay($post->fresh()->updated_at),\n            'It is not touching model own timestamps in withoutTouching scope.'\n        );\n\n        $this->assertTrue(\n            $before->isSameDay($user->fresh()->updated_at),\n            'It is touching model own timestamps in withoutTouching scope, when it should not.'\n        );\n    }\n\n    public function testUpdatingChildPostRespectsNoTouchingDefinition()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingUser::withoutTouching(function () use ($post) {\n            $post->update(['name' => 'Updated']);\n        });\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is not touching model own timestamps when it should.');\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models relationships when it should be disabled.');\n    }\n\n    public function testUpdatingModelInTheDisabledScopeTouchesItsOwnTimestamps()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        Model::withoutTouching(function () use ($post) {\n            $post->update(['name' => 'Updated']);\n        });\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is touching models when it should be disabled.');\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testDeletingChildModelRespectsTheNoTouchingRule()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingUser::withoutTouching(function () use ($post) {\n            $post->delete();\n        });\n\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testRespectedMultiLevelTouchingChain()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingUser::withoutTouching(function () {\n            EloquentTouchingComment::create(['content' => 'Comment content', 'post_id' => 1]);\n        });\n\n        $this->assertTrue($future->isSameDay($post->fresh()->updated_at), 'It is touching models when it should be disabled.');\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testTouchesGreatParentEvenWhenParentIsInNoTouchScope()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingPost::withoutTouching(function () {\n            EloquentTouchingComment::create(['content' => 'Comment content', 'post_id' => 1]);\n        });\n\n        $this->assertTrue($before->isSameDay($post->fresh()->updated_at), 'It is touching models when it should be disabled.');\n        $this->assertTrue($future->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testCanNestCallsOfNoTouching()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        EloquentTouchingUser::withoutTouching(function () {\n            EloquentTouchingPost::withoutTouching(function () {\n                EloquentTouchingComment::create(['content' => 'Comment content', 'post_id' => 1]);\n            });\n        });\n\n        $this->assertTrue($before->isSameDay($post->fresh()->updated_at), 'It is touching models when it should be disabled.');\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testCanPassArrayOfModelsToIgnore()\n    {\n        $before = Carbon::now();\n\n        $user = EloquentTouchingUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post = EloquentTouchingPost::create(['id' => 1, 'name' => 'Parent Post', 'user_id' => 1]);\n\n        $this->assertTrue($before->isSameDay($user->updated_at));\n        $this->assertTrue($before->isSameDay($post->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        Model::withoutTouchingOn([EloquentTouchingUser::class, EloquentTouchingPost::class], function () {\n            EloquentTouchingComment::create(['content' => 'Comment content', 'post_id' => 1]);\n        });\n\n        $this->assertTrue($before->isSameDay($post->fresh()->updated_at), 'It is touching models when it should be disabled.');\n        $this->assertTrue($before->isSameDay($user->fresh()->updated_at), 'It is touching models when it should be disabled.');\n    }\n\n    public function testWhenBaseModelIsIgnoredAllChildModelsAreIgnored()\n    {\n        $this->assertFalse(Model::isIgnoringTouch());\n        $this->assertFalse(User::isIgnoringTouch());\n\n        Model::withoutTouching(function () {\n            $this->assertTrue(Model::isIgnoringTouch());\n            $this->assertTrue(User::isIgnoringTouch());\n        });\n\n        $this->assertFalse(User::isIgnoringTouch());\n        $this->assertFalse(Model::isIgnoringTouch());\n    }\n\n    public function testChildModelsAreIgnored()\n    {\n        $this->assertFalse(Model::isIgnoringTouch());\n        $this->assertFalse(User::isIgnoringTouch());\n        $this->assertFalse(Post::isIgnoringTouch());\n\n        User::withoutTouching(function () {\n            $this->assertFalse(Model::isIgnoringTouch());\n            $this->assertFalse(Post::isIgnoringTouch());\n            $this->assertTrue(User::isIgnoringTouch());\n        });\n\n        $this->assertFalse(Post::isIgnoringTouch());\n        $this->assertFalse(User::isIgnoringTouch());\n        $this->assertFalse(Model::isIgnoringTouch());\n    }\n\n    public function testPivotsCanBeRefreshed()\n    {\n        EloquentTestFriendLevel::create(['id' => 1, 'level' => 'acquaintance']);\n        EloquentTestFriendLevel::create(['id' => 2, 'level' => 'friend']);\n\n        $user = EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $user->friends()->create(['id' => 2, 'email' => 'abigailotwell@gmail.com'], ['friend_level_id' => 1]);\n\n        $pivot = $user->friends[0]->pivot;\n\n        // Simulate a change that happened externally\n        DB::table('friends')->where('user_id', 1)->where('friend_id', 2)->update([\n            'friend_level_id' => 2,\n        ]);\n\n        $this->assertInstanceOf(Pivot::class, $freshPivot = $pivot->fresh());\n        $this->assertEquals(2, $freshPivot->friend_level_id);\n\n        $this->assertSame($pivot, $pivot->refresh());\n        $this->assertEquals(2, $pivot->friend_level_id);\n    }\n\n    public function testMorphPivotsCanBeRefreshed()\n    {\n        $post = EloquentTestPost::create(['name' => 'MorphToMany Post', 'user_id' => 1]);\n        $post->tags()->create(['id' => 1, 'name' => 'News']);\n\n        $pivot = $post->tags[0]->pivot;\n\n        // Simulate a change that happened externally\n        DB::table('taggables')\n            ->where([\n                'taggable_type' => EloquentTestPost::class,\n                'taggable_id' => 1,\n                'tag_id' => 1,\n            ])\n            ->update([\n                'taxonomy' => 'primary',\n            ]);\n\n        $this->assertInstanceOf(MorphPivot::class, $freshPivot = $pivot->fresh());\n        $this->assertSame('primary', $freshPivot->taxonomy);\n\n        $this->assertSame($pivot, $pivot->refresh());\n        $this->assertSame('primary', $pivot->taxonomy);\n    }\n\n    public function testTouchingChaperonedChildModelUpdatesParentTimestamps()\n    {\n        $before = Carbon::now();\n\n        $one = EloquentTouchingCategory::create(['id' => 1, 'name' => 'One']);\n        $two = $one->children()->create(['id' => 2, 'name' => 'Two']);\n\n        $this->assertTrue($before->isSameDay($one->updated_at));\n        $this->assertTrue($before->isSameDay($two->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        $two->touch();\n\n        $this->assertTrue($future->isSameDay($two->fresh()->updated_at), 'It is not touching model own timestamps.');\n        $this->assertTrue($future->isSameDay($one->fresh()->updated_at), 'It is not touching chaperoned models related timestamps.');\n    }\n\n    public function testTouchingBiDirectionalChaperonedModelUpdatesAllRelatedTimestamps()\n    {\n        $before = Carbon::now();\n\n        EloquentTouchingCategory::insert([\n            ['id' => 1, 'name' => 'One', 'parent_id' => null, 'created_at' => $before, 'updated_at' => $before],\n            ['id' => 2, 'name' => 'Two', 'parent_id' => 1, 'created_at' => $before, 'updated_at' => $before],\n            ['id' => 3, 'name' => 'Three', 'parent_id' => 1, 'created_at' => $before, 'updated_at' => $before],\n            ['id' => 4, 'name' => 'Four', 'parent_id' => 2, 'created_at' => $before, 'updated_at' => $before],\n        ]);\n\n        $one = EloquentTouchingCategory::find(1);\n        [$two, $three] = $one->children;\n        [$four] = $two->children;\n\n        $this->assertTrue($before->isSameDay($one->updated_at));\n        $this->assertTrue($before->isSameDay($two->updated_at));\n        $this->assertTrue($before->isSameDay($three->updated_at));\n        $this->assertTrue($before->isSameDay($four->updated_at));\n\n        Carbon::setTestNow($future = $before->copy()->addDays(3));\n\n        // Touch a random model and check that all of the others have been updated\n        $models = tap([$one, $two, $three, $four], shuffle(...));\n        $target = array_shift($models);\n        $target->touch();\n\n        $this->assertTrue($future->isSameDay($target->fresh()->updated_at), 'It is not touching model own timestamps.');\n\n        while ($next = array_shift($models)) {\n            $this->assertTrue(\n                $future->isSameDay($next->fresh()->updated_at),\n                'It is not touching related models timestamps.'\n            );\n        }\n    }\n\n    public function testCanFillAndInsert()\n    {\n        DB::enableQueryLog();\n        Carbon::setTestNow('2025-03-15T07:32:00Z');\n\n        $this->assertTrue(EloquentTestUser::fillAndInsert([\n            ['email' => 'taylor@laravel.com', 'birthday' => null],\n            ['email' => 'nuno@laravel.com', 'birthday' => new Carbon('1980-01-01')],\n            ['email' => 'tim@laravel.com', 'birthday' => '1987-11-01', 'created_at' => '2025-01-02T02:00:55', 'updated_at' => Carbon::parse('2025-02-19T11:41:13')],\n        ]));\n\n        $this->assertCount(1, DB::getQueryLog());\n\n        $this->assertCount(3, $users = EloquentTestUser::get());\n\n        $users->take(2)->each(function (EloquentTestUser $user) {\n            $this->assertEquals(Carbon::parse('2025-03-15T07:32:00Z'), $user->created_at);\n            $this->assertEquals(Carbon::parse('2025-03-15T07:32:00Z'), $user->updated_at);\n        });\n\n        $tim = $users->firstWhere('email', 'tim@laravel.com');\n        $this->assertEquals(Carbon::parse('2025-01-02T02:00:55'), $tim->created_at);\n        $this->assertEquals(Carbon::parse('2025-02-19T11:41:13'), $tim->updated_at);\n\n        $this->assertNull($users[0]->birthday);\n        $this->assertInstanceOf(\\DateTime::class, $users[1]->birthday);\n        $this->assertInstanceOf(\\DateTime::class, $users[2]->birthday);\n        $this->assertEquals('1987-11-01', $users[2]->birthday->format('Y-m-d'));\n\n        DB::flushQueryLog();\n\n        $this->assertTrue(EloquentTestWithJSON::fillAndInsert([\n            ['id' => 1, 'json' => ['album' => 'Keep It Like a Secret', 'release_date' => '1999-02-02']],\n            ['id' => 2, 'json' => (object) ['album' => 'You In Reverse', 'release_date' => '2006-04-11']],\n        ]));\n\n        $this->assertCount(1, DB::getQueryLog());\n\n        $this->assertCount(2, $testsWithJson = EloquentTestWithJSON::get());\n\n        $testsWithJson->each(function (EloquentTestWithJSON $testWithJson) {\n            $this->assertIsArray($testWithJson->json);\n            $this->assertArrayHasKey('album', $testWithJson->json);\n        });\n    }\n\n    public function testCanFillAndInsertWithUniqueStringIds()\n    {\n        Str::createUuidsUsingSequence([\n            '00000000-0000-7000-0000-000000000000',\n            '11111111-0000-7000-0000-000000000000',\n            '22222222-0000-7000-0000-000000000000',\n        ]);\n\n        $this->assertTrue(ModelWithUniqueStringIds::fillAndInsert([\n            [\n                'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin,\n            ],\n            [\n                'name' => 'Nuno', 'role' => 3, 'role_string' => 'admin',\n            ],\n            [\n                'name' => 'Dries', 'uuid' => 'bbbb0000-0000-7000-0000-000000000000',\n            ],\n            [\n                'name' => 'Chris',\n            ],\n        ]));\n\n        $models = ModelWithUniqueStringIds::get();\n\n        $taylor = $models->firstWhere('name', 'Taylor');\n        $nuno = $models->firstWhere('name', 'Nuno');\n        $dries = $models->firstWhere('name', 'Dries');\n        $chris = $models->firstWhere('name', 'Chris');\n\n        $this->assertEquals(IntBackedRole::Admin, $taylor->role);\n        $this->assertEquals(StringBackedRole::Admin, $taylor->role_string);\n        $this->assertSame('00000000-0000-7000-0000-000000000000', $taylor->uuid);\n\n        $this->assertEquals(IntBackedRole::Admin, $nuno->role);\n        $this->assertEquals(StringBackedRole::Admin, $nuno->role_string);\n        $this->assertSame('11111111-0000-7000-0000-000000000000', $nuno->uuid);\n\n        $this->assertEquals(IntBackedRole::User, $dries->role);\n        $this->assertEquals(StringBackedRole::User, $dries->role_string);\n        $this->assertSame('bbbb0000-0000-7000-0000-000000000000', $dries->uuid);\n\n        $this->assertEquals(IntBackedRole::User, $chris->role);\n        $this->assertEquals(StringBackedRole::User, $chris->role_string);\n        $this->assertSame('22222222-0000-7000-0000-000000000000', $chris->uuid);\n    }\n\n    public function testFillAndInsertOrIgnore()\n    {\n        Str::createUuidsUsingSequence([\n            '00000000-0000-7000-0000-000000000000',\n            '11111111-0000-7000-0000-000000000000',\n            '22222222-0000-7000-0000-000000000000',\n        ]);\n\n        $this->assertEquals(1, ModelWithUniqueStringIds::fillAndInsertOrIgnore([\n            [\n                'id' => 1, 'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin,\n            ],\n        ]));\n\n        $this->assertSame(1, ModelWithUniqueStringIds::fillAndInsertOrIgnore([\n            [\n                'id' => 1, 'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin,\n            ],\n            [\n                'id' => 2, 'name' => 'Nuno',\n            ],\n        ]));\n\n        $models = ModelWithUniqueStringIds::get();\n        $this->assertSame('00000000-0000-7000-0000-000000000000', $models->firstWhere('name', 'Taylor')->uuid);\n        $this->assertSame(\n            ['uuid' => '22222222-0000-7000-0000-000000000000', 'role' => IntBackedRole::User],\n            $models->firstWhere('name', 'Nuno')->only('uuid', 'role')\n        );\n    }\n\n    public function testFillAndInsertGetId()\n    {\n        Str::createUuidsUsingSequence([\n            '00000000-0000-7000-0000-000000000000',\n        ]);\n\n        DB::enableQueryLog();\n\n        $this->assertIsInt($newId = ModelWithUniqueStringIds::fillAndInsertGetId([\n            'name' => 'Taylor',\n            'role' => IntBackedRole::Admin,\n            'role_string' => StringBackedRole::Admin,\n        ]));\n        $this->assertCount(1, DB::getRawQueryLog());\n        $this->assertSame($newId, ModelWithUniqueStringIds::sole()->id);\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass EloquentTestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $casts = ['birthday' => 'datetime'];\n    protected $guarded = [];\n\n    public function friends()\n    {\n        return $this->belongsToMany(self::class, 'friends', 'user_id', 'friend_id');\n    }\n\n    public function friendsOne()\n    {\n        return $this->belongsToMany(self::class, 'friends', 'user_id', 'friend_id')->wherePivot('user_id', 1);\n    }\n\n    public function friendsTwo()\n    {\n        return $this->belongsToMany(self::class, 'friends', 'user_id', 'friend_id')->wherePivot('user_id', 2);\n    }\n\n    public function posts()\n    {\n        return $this->hasMany(EloquentTestPost::class, 'user_id');\n    }\n\n    public function post()\n    {\n        return $this->hasOne(EloquentTestPost::class, 'user_id');\n    }\n\n    public function photos()\n    {\n        return $this->morphMany(EloquentTestPhoto::class, 'imageable');\n    }\n\n    public function postWithPhotos()\n    {\n        return $this->post()->join('photo', function ($join) {\n            $join->on('photo.imageable_id', 'post.id');\n            $join->where('photo.imageable_type', 'EloquentTestPost');\n        });\n    }\n\n    public function eloquentTestAchievements()\n    {\n        return $this->belongsToMany(EloquentTestAchievement::class);\n    }\n}\n\nclass EloquentTestUserWithCustomFriendPivot extends EloquentTestUser\n{\n    public function friends()\n    {\n        return $this->belongsToMany(EloquentTestUser::class, 'friends', 'user_id', 'friend_id')\n            ->using(EloquentTestFriendPivot::class)->withPivot('user_id', 'friend_id', 'friend_level_id');\n    }\n}\n\nclass EloquentTestUserWithSpaceInColumnName extends EloquentTestUser\n{\n    protected $table = 'users_with_space_in_column_name';\n}\n\nclass EloquentTestNonIncrementing extends Eloquent\n{\n    protected $table = 'non_incrementing_users';\n    protected $guarded = [];\n    public $incrementing = false;\n    public $timestamps = false;\n}\n\nclass EloquentTestNonIncrementingSecond extends EloquentTestNonIncrementing\n{\n    protected $connection = 'second_connection';\n}\n\nclass EloquentTestUserWithGlobalScope extends EloquentTestUser\n{\n    public static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope(function ($builder) {\n            $builder->with('posts');\n        });\n    }\n}\n\nclass EloquentTestUserWithOmittingGlobalScope extends EloquentTestUser\n{\n    public static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope(function ($builder) {\n            $builder->where('email', '!=', 'taylorotwell@gmail.com');\n        });\n    }\n}\n\nclass EloquentTestUserWithGlobalScopeRemovingOtherScope extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'soft_deleted_users';\n\n    protected $guarded = [];\n\n    public static function boot()\n    {\n        static::addGlobalScope(function ($builder) {\n            $builder->withoutGlobalScope(SoftDeletingScope::class);\n        });\n\n        parent::boot();\n    }\n}\n\nclass EloquentTestUniqueUser extends Eloquent\n{\n    protected $table = 'unique_users';\n    protected $casts = ['birthday' => 'datetime'];\n    protected $guarded = [];\n}\n\nclass EloquentTestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function user()\n    {\n        return $this->belongsTo(EloquentTestUser::class, 'user_id');\n    }\n\n    public function photos()\n    {\n        return $this->morphMany(EloquentTestPhoto::class, 'imageable');\n    }\n\n    public function childPosts()\n    {\n        return $this->hasMany(self::class, 'parent_id');\n    }\n\n    public function parentPost()\n    {\n        return $this->belongsTo(self::class, 'parent_id');\n    }\n\n    public function tags()\n    {\n        return $this->morphToMany(EloquentTestTag::class, 'taggable', Taggable::class, null, 'tag_id')->withPivot('taxonomy');\n    }\n}\n\nclass Taggable extends MorphPivot\n{\n}\n\nclass EloquentTestTag extends Eloquent\n{\n    protected $table = 'tags';\n    protected $guarded = [];\n}\n\nclass EloquentTestFriendLevel extends Eloquent\n{\n    protected $table = 'friend_levels';\n    protected $guarded = [];\n}\n\nclass EloquentTestPhoto extends Eloquent\n{\n    protected $table = 'photos';\n    protected $guarded = [];\n\n    public function imageable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass EloquentTestUserWithStringCastId extends EloquentTestUser\n{\n    protected $casts = [\n        'id' => 'string',\n    ];\n}\n\nclass EloquentTestUserWithCustomDateSerialization extends EloquentTestUser\n{\n    protected function serializeDate(DateTimeInterface $date)\n    {\n        return $date->format('d-m-y');\n    }\n}\n\nclass EloquentTestOrder extends Eloquent\n{\n    protected $guarded = [];\n    protected $table = 'test_orders';\n    protected $with = ['item'];\n\n    public function item()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass EloquentTestItem extends Eloquent\n{\n    protected $guarded = [];\n    protected $table = 'test_items';\n    protected $connection = 'second_connection';\n}\n\nclass EloquentTestWithJSON extends Eloquent\n{\n    protected $guarded = [];\n    protected $table = 'with_json';\n    public $timestamps = false;\n    protected $casts = [\n        'json' => 'array',\n    ];\n}\n\nclass EloquentTestFriendPivot extends Pivot\n{\n    protected $table = 'friends';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function user()\n    {\n        return $this->belongsTo(EloquentTestUser::class);\n    }\n\n    public function friend()\n    {\n        return $this->belongsTo(EloquentTestUser::class);\n    }\n\n    public function level()\n    {\n        return $this->belongsTo(EloquentTestFriendLevel::class, 'friend_level_id');\n    }\n}\n\nclass EloquentTouchingUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n}\n\nclass EloquentTouchingPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    protected $touches = [\n        'user',\n    ];\n\n    public function user()\n    {\n        return $this->belongsTo(EloquentTouchingUser::class, 'user_id');\n    }\n}\n\nclass EloquentTouchingComment extends Eloquent\n{\n    protected $table = 'comments';\n    protected $guarded = [];\n\n    protected $touches = [\n        'post',\n    ];\n\n    public function post()\n    {\n        return $this->belongsTo(EloquentTouchingPost::class, 'post_id');\n    }\n}\n\nclass EloquentTouchingCategory extends Eloquent\n{\n    protected $table = 'categories';\n    protected $guarded = [];\n\n    protected $touches = [\n        'parent',\n        'children',\n    ];\n\n    public function parent()\n    {\n        return $this->belongsTo(EloquentTouchingCategory::class, 'parent_id');\n    }\n\n    public function children()\n    {\n        return $this->hasMany(EloquentTouchingCategory::class, 'parent_id')->chaperone();\n    }\n}\n\nclass EloquentTestAchievement extends Eloquent\n{\n    public $timestamps = false;\n\n    protected $table = 'achievements';\n    protected $guarded = [];\n    protected $attributes = ['status' => null];\n\n    public function eloquentTestUsers()\n    {\n        return $this->belongsToMany(EloquentTestUser::class);\n    }\n}\n\nclass ModelWithUniqueStringIds extends Eloquent\n{\n    use HasUuids;\n\n    public $timestamps = false;\n\n    protected $table = 'users_having_uuids';\n\n    protected function casts()\n    {\n        return [\n            'role' => IntBackedRole::class,\n            'role_string' => StringBackedRole::class,\n        ];\n    }\n\n    protected $attributes = [\n        'role' => IntBackedRole::User,\n        'role_string' => StringBackedRole::User,\n    ];\n\n    public function uniqueIds()\n    {\n        return ['uuid'];\n    }\n}\n\nenum IntBackedRole: int\n{\n    case User = 1;\n    case Admin = 3;\n}\n\nenum StringBackedRole: string\n{\n    case User = 'user';\n    case Admin = 'admin';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentIntegrationWithTablePrefixTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentIntegrationWithTablePrefixTest extends TestCase\n{\n    /**\n     * Bootstrap Eloquent.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        Eloquent::getConnectionResolver()->connection()->setTablePrefix('prefix_');\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema('default')->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('friends', function ($table) {\n            $table->integer('user_id');\n            $table->integer('friend_id');\n        });\n\n        $this->schema('default')->create('posts', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->integer('parent_id')->nullable();\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('photos', function ($table) {\n            $table->increments('id');\n            $table->morphs('imageable');\n            $table->string('name');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        foreach (['default'] as $connection) {\n            $this->schema($connection)->drop('users');\n            $this->schema($connection)->drop('friends');\n            $this->schema($connection)->drop('posts');\n            $this->schema($connection)->drop('photos');\n        }\n\n        Relation::morphMap([], false);\n\n        parent::tearDown();\n    }\n\n    public function testBasicModelHydration()\n    {\n        EloquentTestUser::create(['email' => 'taylorotwell@gmail.com']);\n        EloquentTestUser::create(['email' => 'abigailotwell@gmail.com']);\n\n        $models = EloquentTestUser::fromQuery('SELECT * FROM prefix_users WHERE email = ?', ['abigailotwell@gmail.com']);\n\n        $this->assertInstanceOf(Collection::class, $models);\n        $this->assertInstanceOf(EloquentTestUser::class, $models[0]);\n        $this->assertSame('abigailotwell@gmail.com', $models[0]->email);\n        $this->assertCount(1, $models);\n    }\n\n    public function testTablePrefixWithClonedConnection()\n    {\n        $originalConnection = $this->connection();\n        $originalPrefix = $originalConnection->getTablePrefix();\n\n        $clonedConnection = clone $originalConnection;\n        $clonedConnection->setTablePrefix('cloned_');\n\n        $this->assertSame($originalPrefix, $originalConnection->getTablePrefix());\n        $this->assertSame('cloned_', $clonedConnection->getTablePrefix());\n\n        $clonedConnection->getSchemaBuilder()->create('test_table', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        $this->assertTrue($clonedConnection->getSchemaBuilder()->hasTable('test_table'));\n        $query = $clonedConnection->table('test_table')->toSql();\n        $this->assertStringContainsString('cloned_test_table', $query);\n\n        $clonedConnection->getSchemaBuilder()->drop('test_table');\n    }\n\n    public function testQueryGrammarUsesCorrectPrefixAfterCloning()\n    {\n        $originalConnection = $this->connection();\n\n        $clonedConnection = clone $originalConnection;\n        $clonedConnection->setTablePrefix('new_prefix_');\n\n        $selectSql = $clonedConnection->table('users')->toSql();\n        $this->assertStringContainsString('new_prefix_users', $selectSql);\n\n        $insertSql = $clonedConnection->table('users')->toSql();\n        $this->assertStringContainsString('new_prefix_users', $insertSql);\n\n        $updateSql = $clonedConnection->table('users')->where('id', 1)->toSql();\n        $this->assertStringContainsString('new_prefix_users', $updateSql);\n\n        $deleteSql = $clonedConnection->table('users')->where('id', 1)->toSql();\n        $this->assertStringContainsString('new_prefix_users', $deleteSql);\n\n        $originalSql = $originalConnection->table('users')->toSql();\n        $this->assertStringContainsString('prefix_users', $originalSql);\n        $this->assertStringNotContainsString('new_prefix_users', $originalSql);\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentInverseRelationHasManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentInverseRelationHasManyTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('test_users', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('test_posts', function ($table) {\n            $table->increments('id');\n            $table->foreignId('user_id');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('test_users');\n        $this->schema()->drop('test_posts');\n\n        parent::tearDown();\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::all();\n\n        foreach ($users as $user) {\n            $this->assertFalse($user->relationLoaded('posts'));\n            foreach ($user->posts as $post) {\n                $this->assertTrue($post->relationLoaded('user'));\n                $this->assertSame($user, $post->user);\n            }\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::with('posts')->get();\n\n        foreach ($users as $user) {\n            $posts = $user->getRelation('posts');\n\n            foreach ($posts as $post) {\n                $this->assertTrue($post->relationLoaded('user'));\n                $this->assertSame($user, $post->user);\n            }\n        }\n    }\n\n    public function testHasLatestOfManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::all();\n\n        foreach ($users as $user) {\n            $this->assertFalse($user->relationLoaded('lastPost'));\n            $post = $user->lastPost;\n\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasLatestOfManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::with('lastPost')->get();\n\n        foreach ($users as $user) {\n            $post = $user->getRelation('lastPost');\n\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testOneOfManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::all();\n\n        foreach ($users as $user) {\n            $this->assertFalse($user->relationLoaded('firstPost'));\n            $post = $user->firstPost;\n\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testOneOfManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        HasManyInverseUserModel::factory()->count(3)->withPosts()->create();\n        $users = HasManyInverseUserModel::with('firstPost')->get();\n\n        foreach ($users as $user) {\n            $post = $user->getRelation('firstPost');\n\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenMakingMany()\n    {\n        $user = HasManyInverseUserModel::create();\n\n        $posts = $user->posts()->makeMany(array_fill(0, 3, []));\n\n        foreach ($posts as $post) {\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenCreatingMany()\n    {\n        $user = HasManyInverseUserModel::create();\n\n        $posts = $user->posts()->createMany(array_fill(0, 3, []));\n\n        foreach ($posts as $post) {\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenCreatingManyQuietly()\n    {\n        $user = HasManyInverseUserModel::create();\n\n        $posts = $user->posts()->createManyQuietly(array_fill(0, 3, []));\n\n        foreach ($posts as $post) {\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenSavingMany()\n    {\n        $user = HasManyInverseUserModel::create();\n\n        $posts = array_fill(0, 3, new HasManyInversePostModel);\n\n        $user->posts()->saveMany($posts);\n\n        foreach ($posts as $post) {\n            $this->assertTrue($post->relationLoaded('user'));\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    public function testHasManyInverseRelationIsProperlySetToParentWhenUpdatingMany()\n    {\n        $user = HasManyInverseUserModel::create();\n\n        $posts = HasManyInversePostModel::factory()->count(3)->create();\n\n        foreach ($posts as $post) {\n            $this->assertTrue($user->isNot($post->user));\n        }\n\n        $user->posts()->saveMany($posts);\n\n        foreach ($posts as $post) {\n            $this->assertSame($user, $post->user);\n        }\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass HasManyInverseUserModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_users';\n    protected $fillable = ['id'];\n\n    protected static function newFactory()\n    {\n        return new HasManyInverseUserModelFactory();\n    }\n\n    public function posts(): HasMany\n    {\n        return $this->hasMany(HasManyInversePostModel::class, 'user_id')->inverse('user');\n    }\n\n    public function lastPost(): HasOne\n    {\n        return $this->hasOne(HasManyInversePostModel::class, 'user_id')->latestOfMany()->inverse('user');\n    }\n\n    public function firstPost(): HasOne\n    {\n        return $this->posts()->one();\n    }\n}\n\nclass HasManyInverseUserModelFactory extends Factory\n{\n    protected $model = HasManyInverseUserModel::class;\n\n    public function definition()\n    {\n        return [];\n    }\n\n    public function withPosts(int $count = 3)\n    {\n        return $this->afterCreating(function (HasManyInverseUserModel $model) use ($count) {\n            HasManyInversePostModel::factory()->recycle($model)->count($count)->create();\n        });\n    }\n}\n\nclass HasManyInversePostModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_posts';\n    protected $fillable = ['id', 'user_id'];\n\n    protected static function newFactory()\n    {\n        return new HasManyInversePostModelFactory();\n    }\n\n    public function user(): BelongsTo\n    {\n        return $this->belongsTo(HasManyInverseUserModel::class, 'user_id');\n    }\n}\n\nclass HasManyInversePostModelFactory extends Factory\n{\n    protected $model = HasManyInversePostModel::class;\n\n    public function definition()\n    {\n        return [\n            'user_id' => HasManyInverseUserModel::factory(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentInverseRelationHasOneTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentInverseRelationHasOneTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('test_parent', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('test_child', function ($table) {\n            $table->increments('id');\n            $table->foreignId('parent_id')->unique();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('test_parent');\n        $this->schema()->drop('test_child');\n\n        parent::tearDown();\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        HasOneInverseChildModel::factory(5)->create();\n        $models = HasOneInverseParentModel::all();\n\n        foreach ($models as $parent) {\n            $this->assertFalse($parent->relationLoaded('child'));\n            $child = $parent->child;\n            $this->assertTrue($child->relationLoaded('parent'));\n            $this->assertSame($parent, $child->parent);\n        }\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        HasOneInverseChildModel::factory(5)->create();\n\n        $models = HasOneInverseParentModel::with('child')->get();\n\n        foreach ($models as $parent) {\n            $child = $parent->child;\n\n            $this->assertTrue($child->relationLoaded('parent'));\n            $this->assertSame($parent, $child->parent);\n        }\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenMaking()\n    {\n        $parent = HasOneInverseParentModel::create();\n\n        $child = $parent->child()->make();\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenCreating()\n    {\n        $parent = HasOneInverseParentModel::create();\n\n        $child = $parent->child()->create();\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenCreatingQuietly()\n    {\n        $parent = HasOneInverseParentModel::create();\n\n        $child = $parent->child()->createQuietly();\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenForceCreating()\n    {\n        $parent = HasOneInverseParentModel::create();\n\n        $child = $parent->child()->forceCreate();\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenSaving()\n    {\n        $parent = HasOneInverseParentModel::create();\n        $child = HasOneInverseChildModel::make();\n\n        $this->assertFalse($child->relationLoaded('parent'));\n        $parent->child()->save($child);\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenSavingQuietly()\n    {\n        $parent = HasOneInverseParentModel::create();\n        $child = HasOneInverseChildModel::make();\n\n        $this->assertFalse($child->relationLoaded('parent'));\n        $parent->child()->saveQuietly($child);\n\n        $this->assertTrue($child->relationLoaded('parent'));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    public function testHasOneInverseRelationIsProperlySetToParentWhenUpdating()\n    {\n        $parent = HasOneInverseParentModel::create();\n        $child = HasOneInverseChildModel::factory()->create();\n\n        $this->assertTrue($parent->isNot($child->parent));\n\n        $parent->child()->save($child);\n\n        $this->assertTrue($parent->is($child->parent));\n        $this->assertSame($parent, $child->parent);\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass HasOneInverseParentModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_parent';\n\n    protected $fillable = ['id'];\n\n    protected static function newFactory()\n    {\n        return new HasOneInverseParentModelFactory();\n    }\n\n    public function child(): HasOne\n    {\n        return $this->hasOne(HasOneInverseChildModel::class, 'parent_id')->inverse('parent');\n    }\n}\n\nclass HasOneInverseParentModelFactory extends Factory\n{\n    protected $model = HasOneInverseParentModel::class;\n\n    public function definition()\n    {\n        return [];\n    }\n}\n\nclass HasOneInverseChildModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_child';\n    protected $fillable = ['id', 'parent_id'];\n\n    protected static function newFactory()\n    {\n        return new HasOneInverseChildModelFactory();\n    }\n\n    public function parent(): BelongsTo\n    {\n        return $this->belongsTo(HasOneInverseParentModel::class, 'parent_id');\n    }\n}\n\nclass HasOneInverseChildModelFactory extends Factory\n{\n    protected $model = HasOneInverseChildModel::class;\n\n    public function definition()\n    {\n        return [\n            'parent_id' => HasOneInverseParentModel::factory(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentInverseRelationMorphManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentInverseRelationMorphManyTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('test_posts', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('test_comments', function ($table) {\n            $table->increments('id');\n            $table->morphs('commentable');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('test_posts');\n        $this->schema()->drop('test_comments');\n\n        parent::tearDown();\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphManyInversePostModel::factory()->withComments()->count(3)->create();\n        $posts = MorphManyInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('comments'));\n            $comments = $post->comments;\n            foreach ($comments as $comment) {\n                $this->assertTrue($comment->relationLoaded('commentable'));\n                $this->assertSame($post, $comment->commentable);\n            }\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphManyInversePostModel::factory()->withComments()->count(3)->create();\n        $posts = MorphManyInversePostModel::with('comments')->get();\n\n        foreach ($posts as $post) {\n            $comments = $post->getRelation('comments');\n\n            foreach ($comments as $comment) {\n                $this->assertTrue($comment->relationLoaded('commentable'));\n                $this->assertSame($post, $comment->commentable);\n            }\n        }\n    }\n\n    public function testMorphManyGuessedInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphManyInversePostModel::factory()->withComments()->count(3)->create();\n        $posts = MorphManyInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('guessedComments'));\n            $comments = $post->guessedComments;\n            foreach ($comments as $comment) {\n                $this->assertTrue($comment->relationLoaded('commentable'));\n                $this->assertSame($post, $comment->commentable);\n            }\n        }\n    }\n\n    public function testMorphManyGuessedInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphManyInversePostModel::factory()->withComments()->count(3)->create();\n        $posts = MorphManyInversePostModel::with('guessedComments')->get();\n\n        foreach ($posts as $post) {\n            $comments = $post->getRelation('guessedComments');\n\n            foreach ($comments as $comment) {\n                $this->assertTrue($comment->relationLoaded('commentable'));\n                $this->assertSame($post, $comment->commentable);\n            }\n        }\n    }\n\n    public function testMorphLatestOfManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('lastComment'));\n            $comment = $post->lastComment;\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphLatestOfManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::with('lastComment')->get();\n\n        foreach ($posts as $post) {\n            $comment = $post->getRelation('lastComment');\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphLatestOfManyGuessedInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('guessedLastComment'));\n            $comment = $post->guessedLastComment;\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphLatestOfManyGuessedInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::with('guessedLastComment')->get();\n\n        foreach ($posts as $post) {\n            $comment = $post->getRelation('guessedLastComment');\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphOneOfManyInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('firstComment'));\n            $comment = $post->firstComment;\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphOneOfManyInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphManyInversePostModel::factory()->count(3)->withComments()->create();\n        $posts = MorphManyInversePostModel::with('firstComment')->get();\n\n        foreach ($posts as $post) {\n            $comment = $post->getRelation('firstComment');\n\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenMakingMany()\n    {\n        $post = MorphManyInversePostModel::create();\n\n        $comments = $post->comments()->makeMany(array_fill(0, 3, []));\n\n        foreach ($comments as $comment) {\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenCreatingMany()\n    {\n        $post = MorphManyInversePostModel::create();\n\n        $comments = $post->comments()->createMany(array_fill(0, 3, []));\n\n        foreach ($comments as $comment) {\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenCreatingManyQuietly()\n    {\n        $post = MorphManyInversePostModel::create();\n\n        $comments = $post->comments()->createManyQuietly(array_fill(0, 3, []));\n\n        foreach ($comments as $comment) {\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenSavingMany()\n    {\n        $post = MorphManyInversePostModel::create();\n        $comments = array_fill(0, 3, new MorphManyInverseCommentModel);\n\n        $post->comments()->saveMany($comments);\n\n        foreach ($comments as $comment) {\n            $this->assertTrue($comment->relationLoaded('commentable'));\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    public function testMorphManyInverseRelationIsProperlySetToParentWhenUpdatingMany()\n    {\n        $post = MorphManyInversePostModel::create();\n        $comments = MorphManyInverseCommentModel::factory()->count(3)->create();\n\n        foreach ($comments as $comment) {\n            $this->assertTrue($post->isNot($comment->commentable));\n        }\n\n        $post->comments()->saveMany($comments);\n\n        foreach ($comments as $comment) {\n            $this->assertSame($post, $comment->commentable);\n        }\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass MorphManyInversePostModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_posts';\n    protected $fillable = ['id'];\n\n    protected static function newFactory()\n    {\n        return new MorphManyInversePostModelFactory();\n    }\n\n    public function comments(): MorphMany\n    {\n        return $this->morphMany(MorphManyInverseCommentModel::class, 'commentable')->inverse('commentable');\n    }\n\n    public function guessedComments(): MorphMany\n    {\n        return $this->morphMany(MorphManyInverseCommentModel::class, 'commentable')->inverse();\n    }\n\n    public function lastComment(): MorphOne\n    {\n        return $this->morphOne(MorphManyInverseCommentModel::class, 'commentable')->latestOfMany()->inverse('commentable');\n    }\n\n    public function guessedLastComment(): MorphOne\n    {\n        return $this->morphOne(MorphManyInverseCommentModel::class, 'commentable')->latestOfMany()->inverse();\n    }\n\n    public function firstComment(): MorphOne\n    {\n        return $this->comments()->one();\n    }\n}\n\nclass MorphManyInversePostModelFactory extends Factory\n{\n    protected $model = MorphManyInversePostModel::class;\n\n    public function definition()\n    {\n        return [];\n    }\n\n    public function withComments(int $count = 3)\n    {\n        return $this->afterCreating(function (MorphManyInversePostModel $model) use ($count) {\n            MorphManyInverseCommentModel::factory()->recycle($model)->count($count)->create();\n        });\n    }\n}\n\nclass MorphManyInverseCommentModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_comments';\n    protected $fillable = ['id', 'commentable_type', 'commentable_id'];\n\n    protected static function newFactory()\n    {\n        return new MorphManyInverseCommentModelFactory();\n    }\n\n    public function commentable(): MorphTo\n    {\n        return $this->morphTo('commentable');\n    }\n}\n\nclass MorphManyInverseCommentModelFactory extends Factory\n{\n    protected $model = MorphManyInverseCommentModel::class;\n\n    public function definition()\n    {\n        return [\n            'commentable_type' => MorphManyInversePostModel::class,\n            'commentable_id' => MorphManyInversePostModel::factory(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentInverseRelationMorphOneTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentInverseRelationMorphOneTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('test_posts', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('test_images', function ($table) {\n            $table->increments('id');\n            $table->morphs('imageable');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('test_posts');\n        $this->schema()->drop('test_images');\n\n        parent::tearDown();\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphOneInverseImageModel::factory(6)->create();\n        $posts = MorphOneInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('image'));\n            $image = $post->image;\n            $this->assertTrue($image->relationLoaded('imageable'));\n            $this->assertSame($post, $image->imageable);\n        }\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphOneInverseImageModel::factory(6)->create();\n        $posts = MorphOneInversePostModel::with('image')->get();\n\n        foreach ($posts as $post) {\n            $image = $post->getRelation('image');\n\n            $this->assertTrue($image->relationLoaded('imageable'));\n            $this->assertSame($post, $image->imageable);\n        }\n    }\n\n    public function testMorphOneGuessedInverseRelationIsProperlySetToParentWhenLazyLoaded()\n    {\n        MorphOneInverseImageModel::factory(6)->create();\n        $posts = MorphOneInversePostModel::all();\n\n        foreach ($posts as $post) {\n            $this->assertFalse($post->relationLoaded('guessedImage'));\n            $image = $post->guessedImage;\n            $this->assertTrue($image->relationLoaded('imageable'));\n            $this->assertSame($post, $image->imageable);\n        }\n    }\n\n    public function testMorphOneGuessedInverseRelationIsProperlySetToParentWhenEagerLoaded()\n    {\n        MorphOneInverseImageModel::factory(6)->create();\n        $posts = MorphOneInversePostModel::with('guessedImage')->get();\n\n        foreach ($posts as $post) {\n            $image = $post->getRelation('guessedImage');\n\n            $this->assertTrue($image->relationLoaded('imageable'));\n            $this->assertSame($post, $image->imageable);\n        }\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenMaking()\n    {\n        $post = MorphOneInversePostModel::create();\n\n        $image = $post->image()->make();\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenCreating()\n    {\n        $post = MorphOneInversePostModel::create();\n\n        $image = $post->image()->create();\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenCreatingQuietly()\n    {\n        $post = MorphOneInversePostModel::create();\n\n        $image = $post->image()->createQuietly();\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenForceCreating()\n    {\n        $post = MorphOneInversePostModel::create();\n\n        $image = $post->image()->forceCreate();\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenSaving()\n    {\n        $post = MorphOneInversePostModel::create();\n        $image = MorphOneInverseImageModel::make();\n\n        $this->assertFalse($image->relationLoaded('imageable'));\n        $post->image()->save($image);\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenSavingQuietly()\n    {\n        $post = MorphOneInversePostModel::create();\n        $image = MorphOneInverseImageModel::make();\n\n        $this->assertFalse($image->relationLoaded('imageable'));\n        $post->image()->saveQuietly($image);\n\n        $this->assertTrue($image->relationLoaded('imageable'));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    public function testMorphOneInverseRelationIsProperlySetToParentWhenUpdating()\n    {\n        $post = MorphOneInversePostModel::create();\n        $image = MorphOneInverseImageModel::factory()->create();\n\n        $this->assertTrue($post->isNot($image->imageable));\n\n        $post->image()->save($image);\n\n        $this->assertTrue($post->is($image->imageable));\n        $this->assertSame($post, $image->imageable);\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\nclass MorphOneInversePostModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_posts';\n    protected $fillable = ['id'];\n\n    protected static function newFactory()\n    {\n        return new MorphOneInversePostModelFactory();\n    }\n\n    public function image(): MorphOne\n    {\n        return $this->morphOne(MorphOneInverseImageModel::class, 'imageable')->inverse('imageable');\n    }\n\n    public function guessedImage(): MorphOne\n    {\n        return $this->morphOne(MorphOneInverseImageModel::class, 'imageable')->inverse();\n    }\n}\n\nclass MorphOneInversePostModelFactory extends Factory\n{\n    protected $model = MorphOneInversePostModel::class;\n\n    public function definition()\n    {\n        return [];\n    }\n}\n\nclass MorphOneInverseImageModel extends Model\n{\n    use HasFactory;\n\n    protected $table = 'test_images';\n    protected $fillable = ['id', 'imageable_type', 'imageable_id'];\n\n    protected static function newFactory()\n    {\n        return new MorphOneInverseImageModelFactory();\n    }\n\n    public function imageable(): MorphTo\n    {\n        return $this->morphTo('imageable');\n    }\n}\n\nclass MorphOneInverseImageModelFactory extends Factory\n{\n    protected $model = MorphOneInverseImageModel::class;\n\n    public function definition()\n    {\n        return [\n            'imageable_type' => MorphOneInversePostModel::class,\n            'imageable_id' => MorphOneInversePostModel::factory(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentInverseRelationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\RelationNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\SupportsInverseRelations;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Support\\Stringable;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentInverseRelationTest extends TestCase\n{\n    public function testBuilderCallbackIsNotAppliedWhenInverseRelationIsNotSet()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n        $builder->shouldReceive('afterQuery')->never();\n\n        new HasInverseRelationStub($builder, new HasInverseRelationParentStub());\n    }\n\n    public function testBuilderCallbackIsNotSetIfInverseRelationIsEmptyString()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n        $builder->shouldReceive('afterQuery')->never();\n\n        $this->expectException(RelationNotFoundException::class);\n\n        (new HasInverseRelationStub($builder, new HasInverseRelationParentStub()))->inverse('');\n    }\n\n    public function testBuilderCallbackIsNotSetIfInverseRelationshipDoesNotExist()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n        $builder->shouldReceive('afterQuery')->never();\n\n        $this->expectException(RelationNotFoundException::class);\n\n        (new HasInverseRelationStub($builder, new HasInverseRelationParentStub()))->inverse('foo');\n    }\n\n    public function testWithoutInverseMethodRemovesInverseRelation()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n        $builder->shouldReceive('afterQuery')->once()->andReturnSelf();\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub()));\n        $this->assertNull($relation->getInverseRelationship());\n\n        $relation->inverse('test');\n        $this->assertSame('test', $relation->getInverseRelationship());\n\n        $relation->withoutInverse();\n        $this->assertNull($relation->getInverseRelationship());\n    }\n\n    public function testBuilderCallbackIsAppliedWhenInverseRelationIsSet()\n    {\n        $parent = new HasInverseRelationParentStub();\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n        $builder->shouldReceive('afterQuery')->withArgs(function (\\Closure $callback) use ($parent) {\n            $relation = (new \\ReflectionFunction($callback))->getClosureThis();\n\n            return $relation instanceof HasInverseRelationStub && $relation->getParent() === $parent;\n        })->once()->andReturnSelf();\n\n        (new HasInverseRelationStub($builder, $parent))->inverse('test');\n    }\n\n    public function testBuilderCallbackAppliesInverseRelationToAllModelsInResult()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n\n        // Capture the callback so that we can manually call it.\n        $afterQuery = null;\n        $builder->shouldReceive('afterQuery')->withArgs(function (\\Closure $callback) use (&$afterQuery) {\n            return (bool) $afterQuery = $callback;\n        })->once()->andReturnSelf();\n\n        $parent = new HasInverseRelationParentStub();\n        (new HasInverseRelationStub($builder, $parent))->inverse('test');\n\n        $results = new Collection(array_fill(0, 5, new HasInverseRelationRelatedStub()));\n\n        foreach ($results as $model) {\n            $this->assertEmpty($model->getRelations());\n            $this->assertFalse($model->relationLoaded('test'));\n        }\n\n        $results = $afterQuery($results);\n\n        foreach ($results as $model) {\n            $this->assertNotEmpty($model->getRelations());\n            $this->assertTrue($model->relationLoaded('test'));\n            $this->assertSame($parent, $model->test);\n        }\n    }\n\n    public function testInverseRelationIsNotSetIfInverseRelationIsUnset()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationRelatedStub());\n\n        // Capture the callback so that we can manually call it.\n        $afterQuery = null;\n        $builder->shouldReceive('afterQuery')->withArgs(function (\\Closure $callback) use (&$afterQuery) {\n            return (bool) $afterQuery = $callback;\n        })->once()->andReturnSelf();\n\n        $parent = new HasInverseRelationParentStub();\n        $relation = (new HasInverseRelationStub($builder, $parent));\n        $relation->inverse('test');\n\n        $results = new Collection(array_fill(0, 5, new HasInverseRelationRelatedStub()));\n        foreach ($results as $model) {\n            $this->assertEmpty($model->getRelations());\n        }\n        $results = $afterQuery($results);\n        foreach ($results as $model) {\n            $this->assertNotEmpty($model->getRelations());\n            $this->assertSame($parent, $model->getRelation('test'));\n        }\n\n        // Reset the inverse relation\n        $relation->withoutInverse();\n\n        $results = new Collection(array_fill(0, 5, new HasInverseRelationRelatedStub()));\n        foreach ($results as $model) {\n            $this->assertEmpty($model->getRelations());\n        }\n        foreach ($results as $model) {\n            $this->assertEmpty($model->getRelations());\n        }\n    }\n\n    public function testProvidesPossibleInverseRelationBasedOnParent()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasOneInverseChildModel);\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub));\n\n        $possibleRelations = ['hasInverseRelationParentStub', 'parentStub', 'owner'];\n        $this->assertSame($possibleRelations, array_values($relation->exposeGetPossibleInverseRelations()));\n    }\n\n    public function testProvidesPossibleInverseRelationBasedOnForeignKey()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationParentStub);\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub, 'test_id'));\n\n        $this->assertTrue(in_array('test', $relation->exposeGetPossibleInverseRelations()));\n    }\n\n    public function testProvidesPossibleRecursiveRelationsIfRelatedIsTheSameClassAsParent()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn(new HasInverseRelationParentStub);\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub));\n\n        $this->assertTrue(in_array('parent', $relation->exposeGetPossibleInverseRelations()));\n    }\n\n    #[DataProvider('guessedParentRelationsDataProvider')]\n    public function testGuessesInverseRelationBasedOnParent($guessedRelation)\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === $guessedRelation);\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub));\n\n        $this->assertSame($guessedRelation, $relation->exposeGuessInverseRelation());\n    }\n\n    public function testGuessesPossibleInverseRelationBasedOnForeignKey()\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === 'test');\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub, 'test_id'));\n\n        $this->assertSame('test', $relation->exposeGuessInverseRelation());\n    }\n\n    public function testGuessesRecursiveInverseRelationsIfRelatedIsSameClassAsParent()\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === 'parent');\n\n        $parent = clone $related;\n        $parent->shouldReceive('getForeignKey')->andReturn('recursive_parent_id');\n        $parent->shouldReceive('getKeyName')->andReturn('id');\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        $relation = (new HasInverseRelationStub($builder, $parent));\n\n        $this->assertSame('parent', $relation->exposeGuessInverseRelation());\n    }\n\n    #[DataProvider('guessedParentRelationsDataProvider')]\n    public function testSetsGuessedInverseRelationBasedOnParent($guessedRelation)\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === $guessedRelation);\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $builder->shouldReceive('afterQuery')->once()->andReturnSelf();\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub))->inverse();\n\n        $this->assertSame($guessedRelation, $relation->getInverseRelationship());\n    }\n\n    public function testSetsRecursiveInverseRelationsIfRelatedIsSameClassAsParent()\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === 'parent');\n\n        $parent = clone $related;\n        $parent->shouldReceive('getForeignKey')->andReturn('recursive_parent_id');\n        $parent->shouldReceive('getKeyName')->andReturn('id');\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $builder->shouldReceive('afterQuery')->once()->andReturnSelf();\n\n        $relation = (new HasInverseRelationStub($builder, $parent))->inverse();\n\n        $this->assertSame('parent', $relation->getInverseRelationship());\n    }\n\n    public function testSetsGuessedInverseRelationBasedOnForeignKey()\n    {\n        $related = m::mock(Model::class);\n        $related->shouldReceive('isRelation')->andReturnUsing(fn ($relation) => $relation === 'test');\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $builder->shouldReceive('afterQuery')->once()->andReturnSelf();\n\n        $relation = (new HasInverseRelationStub($builder, new HasInverseRelationParentStub, 'test_id'))->inverse();\n\n        $this->assertSame('test', $relation->getInverseRelationship());\n    }\n\n    public function testOnlyHydratesInverseRelationOnModels()\n    {\n        $relation = m::mock(HasInverseRelationStub::class)->shouldAllowMockingProtectedMethods()->makePartial();\n        $relation->shouldReceive('getParent')->andReturn(new HasInverseRelationParentStub);\n        $relation->shouldReceive('applyInverseRelationToModel')->times(6);\n        $relation->exposeApplyInverseRelationToCollection([\n            new HasInverseRelationRelatedStub(),\n            12345,\n            new HasInverseRelationRelatedStub(),\n            new HasInverseRelationRelatedStub(),\n            Model::class,\n            new HasInverseRelationRelatedStub(),\n            true,\n            [],\n            new HasInverseRelationRelatedStub(),\n            'foo',\n            new class() {\n            },\n            new HasInverseRelationRelatedStub(),\n        ]);\n    }\n\n    public static function guessedParentRelationsDataProvider()\n    {\n        yield ['hasInverseRelationParentStub'];\n        yield ['parentStub'];\n        yield ['owner'];\n    }\n}\n\nclass HasInverseRelationParentStub extends Model\n{\n    protected static $unguarded = true;\n    protected $primaryKey = 'id';\n\n    public function getForeignKey()\n    {\n        return 'parent_stub_id';\n    }\n}\n\nclass HasInverseRelationRelatedStub extends Model\n{\n    protected static $unguarded = true;\n    protected $primaryKey = 'id';\n\n    public function getForeignKey()\n    {\n        return 'child_stub_id';\n    }\n\n    public function test(): BelongsTo\n    {\n        return $this->belongsTo(HasInverseRelationParentStub::class);\n    }\n}\n\nclass HasInverseRelationStub extends Relation\n{\n    use SupportsInverseRelations;\n\n    public function __construct(\n        Builder $query,\n        Model $parent,\n        protected ?string $foreignKey = null,\n    ) {\n        parent::__construct($query, $parent);\n        $this->foreignKey ??= (new Stringable(class_basename($parent)))->snake()->finish('_id')->toString();\n    }\n\n    public function getForeignKeyName()\n    {\n        return $this->foreignKey;\n    }\n\n    // None of these methods will actually be called - they're just needed to fill out `Relation`\n    public function match(array $models, Collection $results, $relation)\n    {\n        return $models;\n    }\n\n    public function initRelation(array $models, $relation)\n    {\n        return $models;\n    }\n\n    public function getResults()\n    {\n        return $this->query->get();\n    }\n\n    public function addConstraints()\n    {\n        //\n    }\n\n    public function addEagerConstraints(array $models)\n    {\n        //\n    }\n\n    // Expose access to protected methods for testing\n    public function exposeGetPossibleInverseRelations(): array\n    {\n        return $this->getPossibleInverseRelations();\n    }\n\n    public function exposeGuessInverseRelation(): ?string\n    {\n        return $this->guessInverseRelation();\n    }\n\n    public function exposeApplyInverseRelationToCollection($models, ?Model $parent = null)\n    {\n        return $this->applyInverseRelationToCollection($models, $parent);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentIrregularPluralTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentIrregularPluralTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        $this->createSchema();\n    }\n\n    public function createSchema()\n    {\n        $this->schema()->create('irregular_plural_humans', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('irregular_plural_tokens', function ($table) {\n            $table->increments('id');\n            $table->string('title');\n        });\n\n        $this->schema()->create('irregular_plural_human_irregular_plural_token', function ($table) {\n            $table->integer('irregular_plural_human_id')->unsigned();\n            $table->integer('irregular_plural_token_id')->unsigned();\n        });\n\n        $this->schema()->create('irregular_plural_mottoes', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        $this->schema()->create('cool_mottoes', function ($table) {\n            $table->integer('irregular_plural_motto_id');\n            $table->integer('cool_motto_id');\n            $table->string('cool_motto_type');\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('irregular_plural_tokens');\n        $this->schema()->drop('irregular_plural_humans');\n        $this->schema()->drop('irregular_plural_human_irregular_plural_token');\n\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    protected function schema()\n    {\n        $connection = Model::getConnectionResolver()->connection();\n\n        return $connection->getSchemaBuilder();\n    }\n\n    public function testItPluralizesTheTableName()\n    {\n        $model = new IrregularPluralHuman;\n\n        $this->assertSame('irregular_plural_humans', $model->getTable());\n    }\n\n    public function testItTouchesTheParentWithAnIrregularPlural()\n    {\n        Carbon::setTestNow('2018-05-01 12:13:14');\n\n        IrregularPluralHuman::create(['email' => 'taylorotwell@gmail.com']);\n\n        IrregularPluralToken::insert([\n            ['title' => 'The title'],\n        ]);\n\n        $human = IrregularPluralHuman::query()->first();\n\n        $tokenIds = IrregularPluralToken::pluck('id');\n\n        Carbon::setTestNow('2018-05-01 15:16:17');\n\n        $human->irregularPluralTokens()->sync($tokenIds);\n\n        $human->refresh();\n\n        $this->assertSame('2018-05-01 12:13:14', (string) $human->created_at);\n        $this->assertSame('2018-05-01 15:16:17', (string) $human->updated_at);\n    }\n\n    public function testItPluralizesMorphToManyRelationships()\n    {\n        $human = IrregularPluralHuman::create(['email' => 'bobby@example.com']);\n\n        $human->mottoes()->create(['name' => 'Real eyes realize real lies']);\n\n        $motto = IrregularPluralMotto::query()->first();\n\n        $this->assertSame('Real eyes realize real lies', $motto->name);\n    }\n}\n\nclass IrregularPluralHuman extends Model\n{\n    protected $guarded = [];\n\n    public function irregularPluralTokens()\n    {\n        return $this->belongsToMany(\n            IrregularPluralToken::class,\n            'irregular_plural_human_irregular_plural_token',\n            'irregular_plural_token_id',\n            'irregular_plural_human_id'\n        );\n    }\n\n    public function mottoes()\n    {\n        return $this->morphToMany(IrregularPluralMotto::class, 'cool_motto');\n    }\n}\n\nclass IrregularPluralToken extends Model\n{\n    protected $guarded = [];\n\n    public $timestamps = false;\n\n    protected $touches = [\n        'irregularPluralHumans',\n    ];\n}\n\nclass IrregularPluralMotto extends Model\n{\n    protected $guarded = [];\n\n    public $timestamps = false;\n\n    public function irregularPluralHumans()\n    {\n        return $this->morphedByMany(IrregularPluralHuman::class, 'cool_motto');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentLocalScopesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentLocalScopesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        tap(new DB)->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ])->bootEloquent();\n    }\n\n    protected function tearDown(): void\n    {\n        Model::unsetConnectionResolver();\n\n        parent::tearDown();\n    }\n\n    public function testCanCheckExistenceOfLocalScope()\n    {\n        $model = new EloquentLocalScopesTestModel;\n\n        $this->assertTrue($model->hasNamedScope('active'));\n        $this->assertTrue($model->hasNamedScope('type'));\n\n        $this->assertFalse($model->hasNamedScope('nonExistentLocalScope'));\n    }\n\n    public function testLocalScopeIsApplied()\n    {\n        $model = new EloquentLocalScopesTestModel;\n        $query = $model->newQuery()->active();\n\n        $this->assertSame('select * from \"table\" where \"active\" = ?', $query->toSql());\n        $this->assertEquals([true], $query->getBindings());\n    }\n\n    public function testDynamicLocalScopeIsApplied()\n    {\n        $model = new EloquentLocalScopesTestModel;\n        $query = $model->newQuery()->type('foo');\n\n        $this->assertSame('select * from \"table\" where \"type\" = ?', $query->toSql());\n        $this->assertEquals(['foo'], $query->getBindings());\n    }\n\n    public function testLocalScopesCanChained()\n    {\n        $model = new EloquentLocalScopesTestModel;\n        $query = $model->newQuery()->active()->type('foo');\n\n        $this->assertSame('select * from \"table\" where \"active\" = ? and \"type\" = ?', $query->toSql());\n        $this->assertEquals([true, 'foo'], $query->getBindings());\n    }\n\n    public function testLocalScopeNestingDoesntDoubleFirstWhereClauseNegation()\n    {\n        $model = new EloquentLocalScopesTestModel;\n        $query = $model\n            ->newQuery()\n            ->whereNot('firstWhere', true)\n            ->orWhere('secondWhere', true)\n            ->active();\n\n        $this->assertSame('select * from \"table\" where (not \"firstWhere\" = ? or \"secondWhere\" = ?) and \"active\" = ?', $query->toSql());\n        $this->assertEquals([true, true, true], $query->getBindings());\n    }\n\n    public function testLocalScopeNestingGroupsOrNotWhereClause()\n    {\n        $model = new EloquentLocalScopesTestModel;\n        $query = $model\n            ->newQuery()\n            ->where('firstWhere', true)\n            ->orWhereNot('secondWhere', true)\n            ->active();\n\n        $this->assertSame('select * from \"table\" where (\"firstWhere\" = ? or not \"secondWhere\" = ?) and \"active\" = ?', $query->toSql());\n        $this->assertEquals([true, true, true], $query->getBindings());\n    }\n}\n\nclass EloquentLocalScopesTestModel extends Model\n{\n    protected $table = 'table';\n\n    public function scopeActive($query)\n    {\n        $query->where('active', true);\n    }\n\n    public function scopeType($query, $type)\n    {\n        $query->where('type', $type);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentModelAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Appends;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Connection;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Fillable;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Guarded;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Hidden;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Table;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Touches;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Unguarded;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Visible;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentModelAttributesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], 'secondary');\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        Model::clearBootedModels();\n    }\n\n    public function test_table_attribute(): void\n    {\n        $model = new ModelWithTableAttribute;\n\n        $this->assertSame('custom_table_name', $model->getTable());\n    }\n\n    public function test_table_property_takes_precedence(): void\n    {\n        $model = new ModelWithTableAttributeAndProperty;\n\n        $this->assertSame('property_table', $model->getTable());\n    }\n\n    public function test_primary_key_attribute(): void\n    {\n        $model = new ModelWithPrimaryKeyAttribute;\n\n        $this->assertSame('custom_id', $model->getKeyName());\n    }\n\n    public function test_primary_key_property_takes_precedence(): void\n    {\n        $model = new ModelWithPrimaryKeyAttributeAndProperty;\n\n        $this->assertSame('property_id', $model->getKeyName());\n    }\n\n    public function test_primary_key_attribute_with_type(): void\n    {\n        $model = new ModelWithPrimaryKeyTypeAttribute;\n\n        $this->assertSame('uuid', $model->getKeyName());\n        $this->assertSame('string', $model->getKeyType());\n    }\n\n    public function test_primary_key_attribute_with_incrementing(): void\n    {\n        $model = new ModelWithPrimaryKeyIncrementingAttribute;\n\n        $this->assertSame('uuid', $model->getKeyName());\n        $this->assertFalse($model->getIncrementing());\n    }\n\n    public function test_primary_key_attribute_with_all_options(): void\n    {\n        $model = new ModelWithFullPrimaryKeyAttribute;\n\n        $this->assertSame('uuid', $model->getKeyName());\n        $this->assertSame('string', $model->getKeyType());\n        $this->assertFalse($model->getIncrementing());\n    }\n\n    public function test_connection_attribute(): void\n    {\n        $model = new ModelWithConnectionAttribute;\n\n        $this->assertSame('secondary', $model->getConnectionName());\n    }\n\n    public function test_timestamps_attribute(): void\n    {\n        $model = new ModelWithTimestampsFalseAttribute;\n\n        $this->assertFalse($model->usesTimestamps());\n    }\n\n    public function test_without_timestamps_attribute(): void\n    {\n        $model = new ModelWithoutTimestampsAttribute;\n\n        $this->assertFalse($model->usesTimestamps());\n    }\n\n    public function test_timestamps_property_takes_precedence(): void\n    {\n        $model = new ModelWithTimestampsAttributeAndProperty;\n\n        $this->assertFalse($model->usesTimestamps());\n    }\n\n    public function test_date_format_attribute(): void\n    {\n        $model = new ModelWithDateFormatAttribute;\n\n        $this->assertSame('U', $model->getDateFormat());\n    }\n\n    public function test_fillable_attribute(): void\n    {\n        $model = new ModelWithFillableAttribute;\n\n        $this->assertSame(['name', 'email'], $model->getFillable());\n    }\n\n    public function test_fillable_property_takes_precedence(): void\n    {\n        $model = new ModelWithFillableAttributeAndProperty;\n\n        $this->assertSame(['title'], $model->getFillable());\n    }\n\n    public function test_guarded_attribute(): void\n    {\n        $model = new ModelWithGuardedAttribute;\n\n        $this->assertSame(['id', 'secret'], $model->getGuarded());\n    }\n\n    public function test_guarded_property_takes_precedence(): void\n    {\n        $model = new ModelWithGuardedAttributeAndProperty;\n\n        $this->assertSame(['token'], $model->getGuarded());\n    }\n\n    public function test_unguarded_attribute(): void\n    {\n        $model = new ModelWithUnguardedAttribute;\n\n        $this->assertSame([], $model->getGuarded());\n        $this->assertFalse($model->isGuarded('anything'));\n    }\n\n    public function test_guarded_attribute_is_inherited(): void\n    {\n        $model = new ModelExtendingGuardedParent;\n\n        $this->assertSame(['id', 'secret'], $model->getGuarded());\n    }\n\n    public function test_hidden_attribute(): void\n    {\n        $model = new ModelWithHiddenAttribute;\n\n        $this->assertSame(['password', 'secret'], $model->getHidden());\n    }\n\n    public function test_visible_attribute(): void\n    {\n        $model = new ModelWithVisibleAttribute;\n\n        $this->assertSame(['id', 'name'], $model->getVisible());\n    }\n\n    public function test_appends_attribute(): void\n    {\n        $model = new ModelWithAppendsAttribute;\n\n        $this->assertSame(['full_name', 'is_admin'], $model->getAppends());\n    }\n\n    public function test_touches_attribute(): void\n    {\n        $model = new ModelWithTouchesAttribute;\n\n        $this->assertSame(['post', 'author'], $model->getTouchedRelations());\n    }\n\n    public function test_merge_fillable_works_with_attribute(): void\n    {\n        $model = new ModelWithFillableAttribute;\n\n        $this->assertSame(['name', 'email'], $model->getFillable());\n\n        $model->mergeFillable(['phone']);\n\n        $this->assertSame(['name', 'email', 'phone'], $model->getFillable());\n    }\n\n    public function test_merge_hidden_works_with_attribute(): void\n    {\n        $model = new ModelWithHiddenAttribute;\n\n        $this->assertSame(['password', 'secret'], $model->getHidden());\n\n        $model->mergeHidden(['api_key']);\n\n        $this->assertSame(['password', 'secret', 'api_key'], $model->getHidden());\n    }\n\n    public function test_set_fillable_overrides_attribute(): void\n    {\n        $model = new ModelWithFillableAttribute;\n\n        $this->assertSame(['name', 'email'], $model->getFillable());\n\n        $model->fillable(['only_this']);\n\n        $this->assertSame(['only_this'], $model->getFillable());\n    }\n\n    public function test_set_hidden_overrides_attribute(): void\n    {\n        $model = new ModelWithHiddenAttribute;\n\n        $this->assertSame(['password', 'secret'], $model->getHidden());\n\n        $model->setHidden(['only_this']);\n\n        $this->assertSame(['only_this'], $model->getHidden());\n    }\n\n    public function test_is_ignoring_touch_with_timestamps_attribute(): void\n    {\n        $this->assertTrue(ModelWithoutTimestampsAttribute::isIgnoringTouch());\n        $this->assertTrue(ModelWithTimestampsFalseAttribute::isIgnoringTouch());\n        $this->assertFalse(ModelWithFillableAttribute::isIgnoringTouch());\n    }\n}\n\n#[Table('custom_table_name')]\nclass ModelWithTableAttribute extends Model\n{\n    //\n}\n\n#[Table('attribute_table')]\nclass ModelWithTableAttributeAndProperty extends Model\n{\n    protected $table = 'property_table';\n}\n\n#[Table(key: 'custom_id')]\nclass ModelWithPrimaryKeyAttribute extends Model\n{\n    //\n}\n\n#[Table(key: 'attribute_id')]\nclass ModelWithPrimaryKeyAttributeAndProperty extends Model\n{\n    protected $primaryKey = 'property_id';\n}\n\n#[Table(key: 'uuid', keyType: 'string')]\nclass ModelWithPrimaryKeyTypeAttribute extends Model\n{\n    //\n}\n\n#[Table(key: 'uuid', incrementing: false)]\nclass ModelWithPrimaryKeyIncrementingAttribute extends Model\n{\n    //\n}\n\n#[Table(key: 'uuid', keyType: 'string', incrementing: false)]\nclass ModelWithFullPrimaryKeyAttribute extends Model\n{\n    //\n}\n\n#[Connection('secondary')]\nclass ModelWithConnectionAttribute extends Model\n{\n    //\n}\n\n#[Table(timestamps: false)]\nclass ModelWithTimestampsFalseAttribute extends Model\n{\n    //\n}\n\n#[Table(timestamps: false)]\nclass ModelWithoutTimestampsAttribute extends Model\n{\n    //\n}\n\n#[Table(timestamps: false)]\nclass ModelWithTimestampsAttributeAndProperty extends Model\n{\n    public $timestamps = false;\n}\n\n#[Table(dateFormat: 'U')]\nclass ModelWithDateFormatAttribute extends Model\n{\n    //\n}\n\n#[Fillable(['name', 'email'])]\nclass ModelWithFillableAttribute extends Model\n{\n    //\n}\n\n#[Fillable(['name', 'email'])]\nclass ModelWithFillableAttributeAndProperty extends Model\n{\n    protected $fillable = ['title'];\n}\n\n#[Guarded(['id', 'secret'])]\nclass ModelWithGuardedAttribute extends Model\n{\n    //\n}\n\n#[Guarded(['id', 'secret'])]\nclass ModelWithGuardedAttributeAndProperty extends Model\n{\n    protected $guarded = ['token'];\n}\n\n#[Guarded(['id', 'secret'])]\nclass GuardedBaseModel extends Model\n{\n    //\n}\n\nclass ModelExtendingGuardedParent extends GuardedBaseModel\n{\n    //\n}\n\n#[Unguarded]\nclass ModelWithUnguardedAttribute extends Model\n{\n    //\n}\n\n#[Hidden(['password', 'secret'])]\nclass ModelWithHiddenAttribute extends Model\n{\n    //\n}\n\n#[Visible(['id', 'name'])]\nclass ModelWithVisibleAttribute extends Model\n{\n    //\n}\n\n#[Appends(['full_name', 'is_admin'])]\nclass ModelWithAppendsAttribute extends Model\n{\n    //\n}\n\n#[Touches(['post', 'author'])]\nclass ModelWithTouchesAttribute extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentModelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse DateTime;\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Exception;\nuse Foo\\Bar\\EloquentModelNamespacedStub;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\ConnectionResolverInterface as Resolver;\nuse Illuminate\\Database\\Eloquent\\Attributes\\CollectedBy;\nuse Illuminate\\Database\\Eloquent\\Attributes\\ObservedBy;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Casts\\ArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsFluent;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsHtmlString;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsStringable;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsUri;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\JsonEncodingException;\nuse Illuminate\\Database\\Eloquent\\MassAssignmentException;\nuse Illuminate\\Database\\Eloquent\\MissingAttributeException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection as BaseCollection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Tests\\Database\\stubs\\TestCast;\nuse Illuminate\\Tests\\Database\\stubs\\TestValueObject;\nuse InvalidArgumentException;\nuse LogicException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\nuse Stringable as NativeStringable;\n\ninclude_once 'Enums.php';\n\nclass DatabaseEloquentModelTest extends TestCase\n{\n    use InteractsWithTime;\n\n    protected $encrypter;\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        Model::unsetEventDispatcher();\n        Carbon::resetToStringFormat();\n\n        parent::tearDown();\n    }\n\n    public function testAttributeManipulation()\n    {\n        $model = new EloquentModelStub;\n        $model->name = 'foo';\n        $this->assertSame('foo', $model->name);\n        $this->assertTrue(isset($model->name));\n        unset($model->name);\n        $this->assertFalse(isset($model->name));\n\n        // test mutation\n        $model->list_items = ['name' => 'taylor'];\n        $this->assertEquals(['name' => 'taylor'], $model->list_items);\n        $attributes = $model->getAttributes();\n        $this->assertSame(json_encode(['name' => 'taylor']), $attributes['list_items']);\n    }\n\n    public function testSetAttributeWithNumericKey()\n    {\n        $model = new EloquentDateModelStub;\n        $model->setAttribute(0, 'value');\n\n        $this->assertEquals([0 => 'value'], $model->getAttributes());\n    }\n\n    public function testDirtyAttributes()\n    {\n        $model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]);\n        $model->syncOriginal();\n        $model->foo = 1;\n        $model->bar = 20;\n        $model->baz = 30;\n\n        $this->assertTrue($model->isDirty());\n        $this->assertFalse($model->isDirty('foo'));\n        $this->assertTrue($model->isDirty('bar'));\n        $this->assertTrue($model->isDirty('foo', 'bar'));\n        $this->assertTrue($model->isDirty(['foo', 'bar']));\n    }\n\n    public function testIntAndNullComparisonWhenDirty()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->intAttribute = null;\n        $model->syncOriginal();\n        $this->assertFalse($model->isDirty('intAttribute'));\n        $model->forceFill(['intAttribute' => 0]);\n        $this->assertTrue($model->isDirty('intAttribute'));\n    }\n\n    public function testFloatAndNullComparisonWhenDirty()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->floatAttribute = null;\n        $model->syncOriginal();\n        $this->assertFalse($model->isDirty('floatAttribute'));\n        $model->forceFill(['floatAttribute' => 0.0]);\n        $this->assertTrue($model->isDirty('floatAttribute'));\n    }\n\n    public function testDirtyOnCastOrDateAttributes()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setDateFormat('Y-m-d H:i:s');\n        $model->boolAttribute = 1;\n        $model->foo = 1;\n        $model->bar = '2017-03-18';\n        $model->dateAttribute = '2017-03-18';\n        $model->datetimeAttribute = '2017-03-23 22:17:00';\n        $model->syncOriginal();\n\n        $model->boolAttribute = true;\n        $model->foo = true;\n        $model->bar = '2017-03-18 00:00:00';\n        $model->dateAttribute = '2017-03-18 00:00:00';\n        $model->datetimeAttribute = null;\n\n        $this->assertTrue($model->isDirty());\n        $this->assertTrue($model->isDirty('foo'));\n        $this->assertTrue($model->isDirty('bar'));\n        $this->assertFalse($model->isDirty('boolAttribute'));\n        $this->assertFalse($model->isDirty('dateAttribute'));\n        $this->assertTrue($model->isDirty('datetimeAttribute'));\n    }\n\n    public function testDirtyOnCastedObjects()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'objectAttribute' => '[\"one\", \"two\", \"three\"]',\n            'collectionAttribute' => '[\"one\", \"two\", \"three\"]',\n        ]);\n        $model->syncOriginal();\n\n        $model->objectAttribute = ['one', 'two', 'three'];\n        $model->collectionAttribute = ['one', 'two', 'three'];\n\n        $this->assertFalse($model->isDirty());\n        $this->assertFalse($model->isDirty('objectAttribute'));\n        $this->assertFalse($model->isDirty('collectionAttribute'));\n    }\n\n    public function testDirtyOnCastedArrayObject()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asarrayobjectAttribute' => '{\"foo\": \"bar\"}',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(ArrayObject::class, $model->asarrayobjectAttribute);\n        $this->assertFalse($model->isDirty('asarrayobjectAttribute'));\n\n        $model->asarrayobjectAttribute = ['foo' => 'bar'];\n        $this->assertFalse($model->isDirty('asarrayobjectAttribute'));\n\n        $model->asarrayobjectAttribute = ['foo' => 'baz'];\n        $this->assertTrue($model->isDirty('asarrayobjectAttribute'));\n    }\n\n    public function testDirtyOnCastedCollection()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'ascollectionAttribute' => '{\"foo\": \"bar\"}',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(BaseCollection::class, $model->ascollectionAttribute);\n        $this->assertFalse($model->isDirty('ascollectionAttribute'));\n\n        $model->ascollectionAttribute = ['foo' => 'bar'];\n        $this->assertFalse($model->isDirty('ascollectionAttribute'));\n\n        $model->ascollectionAttribute = ['foo' => 'baz'];\n        $this->assertTrue($model->isDirty('ascollectionAttribute'));\n    }\n\n    public function testDirtyOnCastedCustomCollection()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asCustomCollectionAttribute' => '{\"bar\": \"foo\"}',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(CustomCollection::class, $model->asCustomCollectionAttribute);\n        $this->assertFalse($model->isDirty('asCustomCollectionAttribute'));\n\n        $model->asCustomCollectionAttribute = ['bar' => 'foo'];\n        $this->assertFalse($model->isDirty('asCustomCollectionAttribute'));\n\n        $model->asCustomCollectionAttribute = ['baz' => 'foo'];\n        $this->assertTrue($model->isDirty('asCustomCollectionAttribute'));\n    }\n\n    public function testDirtyOnCastedCustomCollectionAsArray()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asCustomCollectionAsArrayAttribute' => '{\"bar\": \"foo\"}',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(CustomCollection::class, $model->asCustomCollectionAsArrayAttribute);\n        $this->assertFalse($model->isDirty('asCustomCollectionAsArrayAttribute'));\n\n        $model->asCustomCollectionAsArrayAttribute = ['bar' => 'foo'];\n        $this->assertFalse($model->isDirty('asCustomCollectionAsArrayAttribute'));\n\n        $model->asCustomCollectionAsArrayAttribute = ['baz' => 'foo'];\n        $this->assertTrue($model->isDirty('asCustomCollectionAsArrayAttribute'));\n    }\n\n    public function testDirtyOnCastedStringable()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asStringableAttribute' => 'foo bar',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(Stringable::class, $model->asStringableAttribute);\n        $this->assertFalse($model->isDirty('asStringableAttribute'));\n\n        $model->asStringableAttribute = new Stringable('foo bar');\n        $this->assertFalse($model->isDirty('asStringableAttribute'));\n\n        $model->asStringableAttribute = new Stringable('foo baz');\n        $this->assertTrue($model->isDirty('asStringableAttribute'));\n    }\n\n    public function testDirtyOnCastedHtmlString()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asHtmlStringAttribute' => '<div>foo bar</div>',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(HtmlString::class, $model->asHtmlStringAttribute);\n        $this->assertFalse($model->isDirty('asHtmlStringAttribute'));\n\n        $model->asHtmlStringAttribute = new HtmlString('<div>foo bar</div>');\n        $this->assertFalse($model->isDirty('asHtmlStringAttribute'));\n\n        $model->asHtmlStringAttribute = new Stringable('<div>foo baz</div>');\n        $this->assertTrue($model->isDirty('asHtmlStringAttribute'));\n    }\n\n    public function testDirtyOnCastedUri()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asUriAttribute' => 'https://www.example.com:1234?query=param&another=value',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(Uri::class, $model->asUriAttribute);\n        $this->assertFalse($model->isDirty('asUriAttribute'));\n\n        $model->asUriAttribute = new Uri('https://www.example.com:1234?query=param&another=value');\n        $this->assertFalse($model->isDirty('asUriAttribute'));\n\n        $model->asUriAttribute = new Uri('https://www.updated.com:1234?query=param&another=value');\n        $this->assertTrue($model->isDirty('asUriAttribute'));\n    }\n\n    public function testDirtyOnCastedFluent()\n    {\n        $value = [\n            'address' => [\n                'street' => 'test_street',\n                'city' => 'test_city',\n            ],\n        ];\n\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes(['asFluentAttribute' => json_encode($value)]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(Fluent::class, $model->asFluentAttribute);\n        $this->assertFalse($model->isDirty('asFluentAttribute'));\n\n        $model->asFluentAttribute = new Fluent($value);\n        $this->assertFalse($model->isDirty('asFluentAttribute'));\n\n        $value['address']['street'] = 'updated_street';\n        $model->asFluentAttribute = new Fluent($value);\n        $this->assertTrue($model->isDirty('asFluentAttribute'));\n    }\n\n    // public function testDirtyOnCastedEncryptedCollection()\n    // {\n    //     $this->encrypter = m::mock(Encrypter::class);\n    //     Crypt::swap($this->encrypter);\n    //     Model::$encrypter = null;\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->with('{\"foo\":\"bar\"}')\n    //         ->andReturn('encrypted-value');\n\n    //     $this->encrypter->expects('decryptString')\n    //         ->with('encrypted-value')\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->with('{\"foo\":\"baz\"}')\n    //         ->andReturn('new-encrypted-value');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('encrypted-value', false)\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('new-encrypted-value', false)\n    //         ->andReturn('{\"foo\":\"baz\"}');\n\n    //     $model = new EloquentModelCastingStub;\n    //     $model->setRawAttributes([\n    //         'asEncryptedCollectionAttribute' => 'encrypted-value',\n    //     ]);\n    //     $model->syncOriginal();\n\n    //     $this->assertInstanceOf(BaseCollection::class, $model->asEncryptedCollectionAttribute);\n    //     $this->assertFalse($model->isDirty('asEncryptedCollectionAttribute'));\n\n    //     $model->asEncryptedCollectionAttribute = ['foo' => 'bar'];\n    //     $this->assertFalse($model->isDirty('asEncryptedCollectionAttribute'));\n\n    //     $model->asEncryptedCollectionAttribute = ['foo' => 'baz'];\n    //     $this->assertTrue($model->isDirty('asEncryptedCollectionAttribute'));\n    // }\n\n    // public function testDirtyOnCastedEncryptedCustomCollection()\n    // {\n    //     $this->encrypter = m::mock(Encrypter::class);\n    //     Crypt::swap($this->encrypter);\n    //     Model::$encrypter = null;\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->twice()\n    //         ->with('{\"foo\":\"bar\"}')\n    //         ->andReturn('encrypted-custom-value');\n\n    //     $this->encrypter->expects('decryptString')\n    //         ->with('encrypted-custom-value')\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->with('{\"foo\":\"baz\"}')\n    //         ->andReturn('new-encrypted-custom-value');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('encrypted-custom-value', false)\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('new-encrypted-custom-value', false)\n    //         ->andReturn('{\"foo\":\"baz\"}');\n\n    //     $model = new EloquentModelCastingStub;\n    //     $model->setRawAttributes([\n    //         'asEncryptedCustomCollectionAttribute' => 'encrypted-custom-value',\n    //     ]);\n    //     $model->syncOriginal();\n\n    //     $this->assertInstanceOf(CustomCollection::class, $model->asEncryptedCustomCollectionAttribute);\n    //     $this->assertFalse($model->isDirty('asEncryptedCustomCollectionAttribute'));\n\n    //     $model->asEncryptedCustomCollectionAttribute = ['foo' => 'bar'];\n    //     $this->assertFalse($model->isDirty('asEncryptedCustomCollectionAttribute'));\n\n    //     $model->asEncryptedCustomCollectionAttribute = ['foo' => 'baz'];\n    //     $this->assertTrue($model->isDirty('asEncryptedCustomCollectionAttribute'));\n    // }\n\n    // public function testDirtyOnCastedEncryptedCustomCollectionAsArray()\n    // {\n    //     $this->encrypter = m::mock(Encrypter::class);\n    //     Crypt::swap($this->encrypter);\n    //     Model::$encrypter = null;\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->twice()\n    //         ->with('{\"foo\":\"bar\"}')\n    //         ->andReturn('encrypted-custom-value');\n\n    //     $this->encrypter->expects('decryptString')\n    //         ->with('encrypted-custom-value')\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->with('{\"foo\":\"baz\"}')\n    //         ->andReturn('new-encrypted-custom-value');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('encrypted-custom-value', false)\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('new-encrypted-custom-value', false)\n    //         ->andReturn('{\"foo\":\"baz\"}');\n\n    //     $model = new EloquentModelCastingStub;\n    //     $model->setRawAttributes([\n    //         'asEncryptedCustomCollectionAsArrayAttribute' => 'encrypted-custom-value',\n    //     ]);\n    //     $model->syncOriginal();\n\n    //     $this->assertInstanceOf(CustomCollection::class, $model->asEncryptedCustomCollectionAsArrayAttribute);\n    //     $this->assertFalse($model->isDirty('asEncryptedCustomCollectionAsArrayAttribute'));\n\n    //     $model->asEncryptedCustomCollectionAsArrayAttribute = ['foo' => 'bar'];\n    //     $this->assertFalse($model->isDirty('asEncryptedCustomCollectionAsArrayAttribute'));\n\n    //     $model->asEncryptedCustomCollectionAsArrayAttribute = ['foo' => 'baz'];\n    //     $this->assertTrue($model->isDirty('asEncryptedCustomCollectionAsArrayAttribute'));\n    // }\n\n    // public function testDirtyOnCastedEncryptedArrayObject()\n    // {\n    //     $this->encrypter = m::mock(Encrypter::class);\n    //     Crypt::swap($this->encrypter);\n    //     Model::$encrypter = null;\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->twice()\n    //         ->with('{\"foo\":\"bar\"}')\n    //         ->andReturn('encrypted-value');\n\n    //     $this->encrypter->expects('decryptString')\n    //         ->with('encrypted-value')\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('encryptString')\n    //         ->with('{\"foo\":\"baz\"}')\n    //         ->andReturn('new-encrypted-value');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('encrypted-value', false)\n    //         ->andReturn('{\"foo\": \"bar\"}');\n\n    //     $this->encrypter->expects('decrypt')\n    //         ->with('new-encrypted-value', false)\n    //         ->andReturn('{\"foo\":\"baz\"}');\n\n    //     $model = new EloquentModelCastingStub;\n    //     $model->setRawAttributes([\n    //         'asEncryptedArrayObjectAttribute' => 'encrypted-value',\n    //     ]);\n    //     $model->syncOriginal();\n\n    //     $this->assertInstanceOf(ArrayObject::class, $model->asEncryptedArrayObjectAttribute);\n    //     $this->assertFalse($model->isDirty('asEncryptedArrayObjectAttribute'));\n\n    //     $model->asEncryptedArrayObjectAttribute = ['foo' => 'bar'];\n    //     $this->assertFalse($model->isDirty('asEncryptedArrayObjectAttribute'));\n\n    //     $model->asEncryptedArrayObjectAttribute = ['foo' => 'baz'];\n    //     $this->assertTrue($model->isDirty('asEncryptedArrayObjectAttribute'));\n    // }\n\n    public function testDirtyOnEnumCollectionObject()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asEnumCollectionAttribute' => '[\"draft\", \"pending\"]',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(BaseCollection::class, $model->asEnumCollectionAttribute);\n        $this->assertFalse($model->isDirty('asEnumCollectionAttribute'));\n\n        $model->asEnumCollectionAttribute = ['draft', 'pending'];\n        $this->assertFalse($model->isDirty('asEnumCollectionAttribute'));\n\n        $model->asEnumCollectionAttribute = ['draft', 'done'];\n        $this->assertTrue($model->isDirty('asEnumCollectionAttribute'));\n    }\n\n    public function testDirtyOnCustomEnumCollectionObject()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asCustomEnumCollectionAttribute' => '[\"draft\", \"pending\"]',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(BaseCollection::class, $model->asCustomEnumCollectionAttribute);\n        $this->assertFalse($model->isDirty('asCustomEnumCollectionAttribute'));\n\n        $model->asCustomEnumCollectionAttribute = ['draft', 'pending'];\n        $this->assertFalse($model->isDirty('asCustomEnumCollectionAttribute'));\n\n        $model->asCustomEnumCollectionAttribute = ['draft', 'done'];\n        $this->assertTrue($model->isDirty('asCustomEnumCollectionAttribute'));\n    }\n\n    public function testDirtyOnEnumArrayObject()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asEnumArrayObjectAttribute' => '[\"draft\", \"pending\"]',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(ArrayObject::class, $model->asEnumArrayObjectAttribute);\n        $this->assertFalse($model->isDirty('asEnumArrayObjectAttribute'));\n\n        $model->asEnumArrayObjectAttribute = ['draft', 'pending'];\n        $this->assertFalse($model->isDirty('asEnumArrayObjectAttribute'));\n\n        $model->asEnumArrayObjectAttribute = ['draft', 'done'];\n        $this->assertTrue($model->isDirty('asEnumArrayObjectAttribute'));\n    }\n\n    public function testDirtyOnCustomEnumArrayObjectUsing()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'asCustomEnumArrayObjectAttribute' => '[\"draft\", \"pending\"]',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(ArrayObject::class, $model->asCustomEnumArrayObjectAttribute);\n        $this->assertFalse($model->isDirty('asCustomEnumArrayObjectAttribute'));\n\n        $model->asCustomEnumArrayObjectAttribute = ['draft', 'pending'];\n        $this->assertFalse($model->isDirty('asCustomEnumArrayObjectAttribute'));\n\n        $model->asCustomEnumArrayObjectAttribute = ['draft', 'done'];\n        $this->assertTrue($model->isDirty('asCustomEnumArrayObjectAttribute'));\n    }\n\n    public function testHasCastsOnEnumAttribute()\n    {\n        $model = new EloquentModelEnumCastingStub();\n        $this->assertTrue($model->hasCast('enumAttribute', StringStatus::class));\n    }\n\n    public function testCleanAttributes()\n    {\n        $model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]);\n        $model->syncOriginal();\n        $model->foo = 1;\n        $model->bar = 20;\n        $model->baz = 30;\n\n        $this->assertFalse($model->isClean());\n        $this->assertTrue($model->isClean('foo'));\n        $this->assertFalse($model->isClean('bar'));\n        $this->assertFalse($model->isClean('foo', 'bar'));\n        $this->assertFalse($model->isClean(['foo', 'bar']));\n    }\n\n    public function testCleanWhenFloatUpdateAttribute()\n    {\n        // test is equivalent\n        $model = new EloquentModelStub(['castedFloat' => 8 - 6.4]);\n        $model->syncOriginal();\n        $model->castedFloat = 1.6;\n        $this->assertTrue($model->originalIsEquivalent('castedFloat'));\n\n        // test is not equivalent\n        $model = new EloquentModelStub(['castedFloat' => 5.6]);\n        $model->syncOriginal();\n        $model->castedFloat = 5.5;\n        $this->assertFalse($model->originalIsEquivalent('castedFloat'));\n    }\n\n    public function testCalculatedAttributes()\n    {\n        $model = new EloquentModelStub;\n        $model->password = 'secret';\n        $attributes = $model->getAttributes();\n\n        // ensure password attribute was not set to null\n        $this->assertArrayNotHasKey('password', $attributes);\n        $this->assertSame('******', $model->password);\n\n        $hash = 'e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4';\n\n        $this->assertEquals($hash, $attributes['password_hash']);\n        $this->assertEquals($hash, $model->password_hash);\n    }\n\n    public function testArrayAccessToAttributes()\n    {\n        $model = new EloquentModelStub(['attributes' => 1, 'connection' => 2, 'table' => 3]);\n        unset($model['table']);\n\n        $this->assertTrue(isset($model['attributes']));\n        $this->assertEquals(1, $model['attributes']);\n        $this->assertTrue(isset($model['connection']));\n        $this->assertEquals(2, $model['connection']);\n        $this->assertFalse(isset($model['table']));\n        $this->assertEquals(null, $model['table']);\n        $this->assertFalse(isset($model['with']));\n    }\n\n    public function testOnly()\n    {\n        $model = new EloquentModelStub;\n        $model->first_name = 'taylor';\n        $model->last_name = 'otwell';\n        $model->project = 'laravel';\n\n        $this->assertEquals(['project' => 'laravel'], $model->only('project'));\n        $this->assertEquals(['first_name' => 'taylor', 'last_name' => 'otwell'], $model->only('first_name', 'last_name'));\n        $this->assertEquals(['first_name' => 'taylor', 'last_name' => 'otwell'], $model->only(['first_name', 'last_name']));\n    }\n\n    public function testExcept()\n    {\n        $model = new EloquentModelStub;\n        $model->first_name = 'taylor';\n        $model->last_name = 'otwell';\n        $model->project = 'laravel';\n\n        $this->assertEquals(['first_name' => 'taylor', 'last_name' => 'otwell'], $model->except('project'));\n        $this->assertEquals(['project' => 'laravel'], $model->except('first_name', 'last_name'));\n        $this->assertEquals(['project' => 'laravel'], $model->except(['first_name', 'last_name']));\n    }\n\n    public function testNewInstanceReturnsNewInstanceWithAttributesSet()\n    {\n        $model = new EloquentModelStub;\n        $instance = $model->newInstance(['name' => 'taylor']);\n        $this->assertInstanceOf(EloquentModelStub::class, $instance);\n        $this->assertSame('taylor', $instance->name);\n    }\n\n    public function testNewInstanceReturnsNewInstanceWithTableSet()\n    {\n        $model = new EloquentModelStub;\n        $model->setTable('test');\n        $newInstance = $model->newInstance();\n\n        $this->assertSame('test', $newInstance->getTable());\n    }\n\n    public function testNewInstanceReturnsNewInstanceWithMergedCasts()\n    {\n        $model = new EloquentModelStub;\n        $model->mergeCasts(['foo' => 'date']);\n        $newInstance = $model->newInstance();\n\n        $this->assertArrayHasKey('foo', $newInstance->getCasts());\n        $this->assertSame('date', $newInstance->getCasts()['foo']);\n    }\n\n    public function testCreateMethodSavesNewModel()\n    {\n        $_SERVER['__eloquent.saved'] = false;\n        $model = EloquentModelSaveStub::create(['name' => 'taylor']);\n        $this->assertTrue($_SERVER['__eloquent.saved']);\n        $this->assertSame('taylor', $model->name);\n    }\n\n    public function testMakeMethodDoesNotSaveNewModel()\n    {\n        $_SERVER['__eloquent.saved'] = false;\n        $model = EloquentModelSaveStub::make(['name' => 'taylor']);\n        $this->assertFalse($_SERVER['__eloquent.saved']);\n        $this->assertSame('taylor', $model->name);\n    }\n\n    public function testForceCreateMethodSavesNewModelWithGuardedAttributes()\n    {\n        $_SERVER['__eloquent.saved'] = false;\n        $model = EloquentModelSaveStub::forceCreate(['id' => 21]);\n        $this->assertTrue($_SERVER['__eloquent.saved']);\n        $this->assertEquals(21, $model->id);\n    }\n\n    public function testFindMethodUseWritePdo()\n    {\n        EloquentModelFindWithWritePdoStub::onWriteConnection()->find(1);\n    }\n\n    public function testDestroyMethodCallsQueryBuilderCorrectly()\n    {\n        EloquentModelDestroyStub::destroy(1, 2, 3);\n    }\n\n    public function testDestroyMethodCallsQueryBuilderCorrectlyWithCollection()\n    {\n        EloquentModelDestroyStub::destroy(new BaseCollection([1, 2, 3]));\n    }\n\n    public function testDestroyMethodCallsQueryBuilderCorrectlyWithEloquentCollection()\n    {\n        EloquentModelDestroyStub::destroy(new Collection([\n            new EloquentModelDestroyStub(['id' => 1]),\n            new EloquentModelDestroyStub(['id' => 2]),\n            new EloquentModelDestroyStub(['id' => 3]),\n        ]));\n    }\n\n    public function testDestroyMethodCallsQueryBuilderCorrectlyWithMultipleArgs()\n    {\n        EloquentModelDestroyStub::destroy(1, 2, 3);\n    }\n\n    public function testDestroyMethodCallsQueryBuilderCorrectlyWithEmptyIds()\n    {\n        $count = EloquentModelEmptyDestroyStub::destroy([]);\n        $this->assertSame(0, $count);\n    }\n\n    public function testWithMethodCallsQueryBuilderCorrectly()\n    {\n        $result = EloquentModelWithStub::with('foo', 'bar');\n        $this->assertSame('foo', $result);\n    }\n\n    public function testWithoutMethodRemovesEagerLoadedRelationshipCorrectly()\n    {\n        $model = new EloquentModelWithoutRelationStub;\n        $this->addMockConnection($model);\n        $instance = $model->newInstance()->newQuery()->without('foo');\n        $this->assertEmpty($instance->getEagerLoads());\n    }\n\n    public function testWithOnlyMethodLoadsRelationshipCorrectly()\n    {\n        $model = new EloquentModelWithoutRelationStub();\n        $this->addMockConnection($model);\n        $instance = $model->newInstance()->newQuery()->withOnly('taylor');\n        $this->assertNotNull($instance->getEagerLoads()['taylor']);\n        $this->assertArrayNotHasKey('foo', $instance->getEagerLoads());\n    }\n\n    public function testEagerLoadingWithColumns()\n    {\n        $model = new EloquentModelWithoutRelationStub;\n        $instance = $model->newInstance()->newQuery()->with('foo:bar,baz', 'hadi');\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('select')->once()->with(['bar', 'baz']);\n        $this->assertNotNull($instance->getEagerLoads()['hadi']);\n        $this->assertNotNull($instance->getEagerLoads()['foo']);\n        $closure = $instance->getEagerLoads()['foo'];\n        $closure($builder);\n    }\n\n    public function testWithWhereHasWithSpecificColumns()\n    {\n        $model = new EloquentModelWithWhereHasStub;\n        $instance = $model->newInstance()->newQuery()->withWhereHas('foo:diaa,fares');\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('select')->once()->with(['diaa', 'fares']);\n        $this->assertNotNull($instance->getEagerLoads()['foo']);\n        $closure = $instance->getEagerLoads()['foo'];\n        $closure($builder);\n    }\n\n    public function testWithWhereHasWorksInNestedQuery()\n    {\n        $model = new EloquentModelWithWhereHasStub;\n        $instance = $model->newInstance()->newQuery()->where(fn (Builder $q) => $q->withWhereHas('foo:diaa,fares'));\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('select')->once()->with(['diaa', 'fares']);\n        $this->assertNotNull($instance->getEagerLoads()['foo']);\n        $closure = $instance->getEagerLoads()['foo'];\n        $closure($builder);\n    }\n\n    public function testWithMethodCallsQueryBuilderCorrectlyWithArray()\n    {\n        $result = EloquentModelWithStub::with(['foo', 'bar']);\n        $this->assertSame('foo', $result);\n    }\n\n    public function testUpdateProcess()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('where')->once()->with('id', '=', 1);\n        $query->shouldReceive('update')->once()->with(['name' => 'taylor'])->andReturn(1);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true);\n\n        $model->id = 1;\n        $model->foo = 'bar';\n        // make sure foo isn't synced so we can test that dirty attributes only are updated\n        $model->syncOriginal();\n        $model->name = 'taylor';\n        $model->exists = true;\n        $this->assertTrue($model->save());\n    }\n\n    public function testUpdateProcessDoesntOverrideTimestamps()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('where')->once()->with('id', '=', 1);\n        $query->shouldReceive('update')->once()->with(['created_at' => 'foo', 'updated_at' => 'bar'])->andReturn(1);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until');\n        $events->shouldReceive('dispatch');\n\n        $model->id = 1;\n        $model->syncOriginal();\n        $model->created_at = 'foo';\n        $model->updated_at = 'bar';\n        $model->exists = true;\n        $this->assertTrue($model->save());\n    }\n\n    public function testSaveIsCanceledIfSavingEventReturnsFalse()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock();\n        $query = m::mock(Builder::class);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(false);\n        $model->exists = true;\n\n        $this->assertFalse($model->save());\n    }\n\n    public function testUpdateIsCanceledIfUpdatingEventReturnsFalse()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock();\n        $query = m::mock(Builder::class);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(false);\n        $model->exists = true;\n        $model->foo = 'bar';\n\n        $this->assertFalse($model->save());\n    }\n\n    public function testEventsCanBeFiredWithCustomEventObjects()\n    {\n        $model = $this->getMockBuilder(EloquentModelEventObjectStub::class)->onlyMethods(['newModelQuery'])->getMock();\n        $query = m::mock(Builder::class);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with(m::type(EloquentModelSavingEventStub::class))->andReturn(false);\n        $model->exists = true;\n\n        $this->assertFalse($model->save());\n    }\n\n    public function testUpdateProcessWithoutTimestamps()\n    {\n        $model = $this->getMockBuilder(EloquentModelEventObjectStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'fireModelEvent'])->getMock();\n        $model->timestamps = false;\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('where')->once()->with('id', '=', 1);\n        $query->shouldReceive('update')->once()->with(['name' => 'taylor'])->andReturn(1);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->never())->method('updateTimestamps');\n        $model->expects($this->any())->method('fireModelEvent')->willReturn(true);\n\n        $model->id = 1;\n        $model->syncOriginal();\n        $model->name = 'taylor';\n        $model->exists = true;\n        $this->assertTrue($model->save());\n    }\n\n    public function testUpdateUsesOldPrimaryKey()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('where')->once()->with('id', '=', 1);\n        $query->shouldReceive('update')->once()->with(['id' => 2, 'foo' => 'bar'])->andReturn(1);\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true);\n\n        $model->id = 1;\n        $model->syncOriginal();\n        $model->id = 2;\n        $model->foo = 'bar';\n        $model->exists = true;\n\n        $this->assertTrue($model->save());\n    }\n\n    public function testTimestampsAreReturnedAsObjects()\n    {\n        $model = $this->getMockBuilder(EloquentDateModelStub::class)->onlyMethods(['getDateFormat'])->getMock();\n        $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d');\n        $model->setRawAttributes([\n            'created_at' => '2012-12-04',\n            'updated_at' => '2012-12-05',\n        ]);\n\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n        $this->assertInstanceOf(Carbon::class, $model->updated_at);\n    }\n\n    public function testTimestampsAreReturnedAsObjectsFromPlainDatesAndTimestamps()\n    {\n        $model = $this->getMockBuilder(EloquentDateModelStub::class)->onlyMethods(['getDateFormat'])->getMock();\n        $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d H:i:s');\n        $model->setRawAttributes([\n            'created_at' => '2012-12-04',\n            'updated_at' => $this->currentTime(),\n        ]);\n\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n        $this->assertInstanceOf(Carbon::class, $model->updated_at);\n    }\n\n    public function testTimestampsAreReturnedAsObjectsOnCreate()\n    {\n        $timestamps = [\n            'created_at' => Carbon::now(),\n            'updated_at' => Carbon::now(),\n        ];\n        $model = new EloquentDateModelStub;\n        Model::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $resolver->shouldReceive('connection')->andReturn($mockConnection = m::mock(stdClass::class));\n        $mockConnection->shouldReceive('getQueryGrammar')->andReturn($mockConnection);\n        $mockConnection->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s');\n        $instance = $model->newInstance($timestamps);\n        $this->assertInstanceOf(Carbon::class, $instance->updated_at);\n        $this->assertInstanceOf(Carbon::class, $instance->created_at);\n    }\n\n    public function testDateTimeAttributesReturnNullIfSetToNull()\n    {\n        $timestamps = [\n            'created_at' => Carbon::now(),\n            'updated_at' => Carbon::now(),\n        ];\n        $model = new EloquentDateModelStub;\n        Model::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $resolver->shouldReceive('connection')->andReturn($mockConnection = m::mock(stdClass::class));\n        $mockConnection->shouldReceive('getQueryGrammar')->andReturn($mockConnection);\n        $mockConnection->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s');\n        $instance = $model->newInstance($timestamps);\n\n        $instance->created_at = null;\n        $this->assertNull($instance->created_at);\n    }\n\n    public function testTimestampsAreCreatedFromStringsAndIntegers()\n    {\n        $model = new EloquentDateModelStub;\n        $model->created_at = '2013-05-22 00:00:00';\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n\n        $model = new EloquentDateModelStub;\n        $model->created_at = $this->currentTime();\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n\n        $model = new EloquentDateModelStub;\n        $model->created_at = 0;\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n\n        $model = new EloquentDateModelStub;\n        $model->created_at = '2012-01-01';\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n    }\n\n    public function testFromDateTime()\n    {\n        $model = new EloquentModelStub;\n\n        $value = Carbon::parse('2015-04-17 22:59:01');\n        $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value));\n\n        $value = new DateTime('2015-04-17 22:59:01');\n        $this->assertInstanceOf(DateTime::class, $value);\n        $this->assertInstanceOf(DateTimeInterface::class, $value);\n        $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value));\n\n        $value = new DateTimeImmutable('2015-04-17 22:59:01');\n        $this->assertInstanceOf(DateTimeImmutable::class, $value);\n        $this->assertInstanceOf(DateTimeInterface::class, $value);\n        $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value));\n\n        $value = '2015-04-17 22:59:01';\n        $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value));\n\n        $value = '2015-04-17';\n        $this->assertSame('2015-04-17 00:00:00', $model->fromDateTime($value));\n\n        $value = '2015-4-17';\n        $this->assertSame('2015-04-17 00:00:00', $model->fromDateTime($value));\n\n        $value = '1429311541';\n        $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value));\n\n        $this->assertNull($model->fromDateTime(null));\n    }\n\n    public function testFromDateTimeMilliseconds()\n    {\n        $model = $this->getMockBuilder('Illuminate\\Tests\\Database\\EloquentDateModelStub')->onlyMethods(['getDateFormat'])->getMock();\n        $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d H:s.vi');\n        $model->setRawAttributes([\n            'created_at' => '2012-12-04 22:59.32130',\n        ]);\n\n        $this->assertInstanceOf(Carbon::class, $model->created_at);\n        $this->assertSame('22:30:59.321000', $model->created_at->format('H:i:s.u'));\n    }\n\n    public function testInsertProcess()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertTrue($model->save());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insert')->once()->with(['name' => 'taylor']);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n        $model->setIncrementing(false);\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertTrue($model->save());\n        $this->assertNull($model->id);\n        $this->assertTrue($model->exists);\n    }\n\n    public function testInsertIsCanceledIfCreatingEventReturnsFalse()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(false);\n\n        $this->assertFalse($model->save());\n        $this->assertFalse($model->exists);\n    }\n\n    public function testInsertOrIgnoreProcessWithIncrementing()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $baseQuery = m::mock(BaseBuilder::class);\n        $query->shouldReceive('toBase')->once()->andReturn($baseQuery);\n        $baseQuery->shouldReceive('insertOrIgnoreReturning')->once()->with(['name' => 'taylor'], ['*'], null)->andReturn(new BaseCollection([(object) ['id' => 1, 'name' => 'taylor']]));\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertTrue($model->saveOrIgnore());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n        $this->assertTrue($model->wasRecentlyCreated);\n    }\n\n    public function testInsertOrIgnoreProcessWithConflict()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $baseQuery = m::mock(BaseBuilder::class);\n        $query->shouldReceive('toBase')->once()->andReturn($baseQuery);\n        $baseQuery->shouldReceive('insertOrIgnoreReturning')->once()->with(['name' => 'taylor'], ['*'], null)->andReturn(new BaseCollection);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertFalse($model->saveOrIgnore());\n        $this->assertFalse($model->exists);\n        $this->assertFalse($model->wasRecentlyCreated);\n    }\n\n    public function testInsertOrIgnoreProcessWithNonIncrementing()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $baseQuery = m::mock(BaseBuilder::class);\n        $query->shouldReceive('toBase')->once()->andReturn($baseQuery);\n        $baseQuery->shouldReceive('insertOrIgnoreReturning')->once()->with(['name' => 'taylor'], ['*'], null)->andReturn(new BaseCollection([(object) ['name' => 'taylor']]));\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n        $model->setIncrementing(false);\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertTrue($model->saveOrIgnore());\n        $this->assertNull($model->id);\n        $this->assertTrue($model->exists);\n        $this->assertTrue($model->wasRecentlyCreated);\n    }\n\n    public function testInsertOrIgnoreProcessWithNamedUnique()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $baseQuery = m::mock(BaseBuilder::class);\n        $query->shouldReceive('toBase')->once()->andReturn($baseQuery);\n        $baseQuery->shouldReceive('insertOrIgnoreReturning')->once()->with(['name' => 'taylor'], ['*'], ['name'])->andReturn(new BaseCollection);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true);\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $this->assertFalse($model->saveOrIgnore([], ['name']));\n        $this->assertFalse($model->exists);\n        $this->assertFalse($model->wasRecentlyCreated);\n    }\n\n    public function testInsertOrIgnoreThrowsOnExistingModel()\n    {\n        $this->expectException(\\LogicException::class);\n\n        $model = new EloquentModelStub;\n        $model->exists = true;\n        $model->saveOrIgnore();\n    }\n\n    public function testDeleteProperlyDeletesModel()\n    {\n        $model = $this->getMockBuilder(Model::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'touchOwners'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('where')->once()->with('id', '=', 1)->andReturn($query);\n        $query->shouldReceive('delete')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('touchOwners');\n        $model->exists = true;\n        $model->id = 1;\n        $model->delete();\n    }\n\n    public function testPushNoRelations()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->name = 'taylor';\n        $model->exists = false;\n\n        $this->assertTrue($model->push());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n    }\n\n    public function testPushEmptyOneRelation()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $model->setRelation('relationOne', null);\n\n        $this->assertTrue($model->push());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n        $this->assertNull($model->relationOne);\n    }\n\n    public function testPushOneRelation()\n    {\n        $related1 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'related1'], 'id')->andReturn(2);\n        $query->shouldReceive('getConnection')->once();\n        $related1->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $related1->expects($this->once())->method('updateTimestamps');\n        $related1->name = 'related1';\n        $related1->exists = false;\n\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $model->setRelation('relationOne', $related1);\n\n        $this->assertTrue($model->push());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n        $this->assertEquals(2, $model->relationOne->id);\n        $this->assertTrue($model->relationOne->exists);\n        $this->assertEquals(2, $related1->id);\n        $this->assertTrue($related1->exists);\n    }\n\n    public function testPushEmptyManyRelation()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $model->setRelation('relationMany', new Collection([]));\n\n        $this->assertTrue($model->push());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n        $this->assertCount(0, $model->relationMany);\n    }\n\n    public function testPushManyRelation()\n    {\n        $related1 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'related1'], 'id')->andReturn(2);\n        $query->shouldReceive('getConnection')->once();\n        $related1->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $related1->expects($this->once())->method('updateTimestamps');\n        $related1->name = 'related1';\n        $related1->exists = false;\n\n        $related2 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'related2'], 'id')->andReturn(3);\n        $query->shouldReceive('getConnection')->once();\n        $related2->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $related2->expects($this->once())->method('updateTimestamps');\n        $related2->name = 'related2';\n        $related2->exists = false;\n\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n        $model->expects($this->once())->method('updateTimestamps');\n\n        $model->name = 'taylor';\n        $model->exists = false;\n        $model->setRelation('relationMany', new Collection([$related1, $related2]));\n\n        $this->assertTrue($model->push());\n        $this->assertEquals(1, $model->id);\n        $this->assertTrue($model->exists);\n        $this->assertCount(2, $model->relationMany);\n        $this->assertEquals([2, 3], $model->relationMany->pluck('id')->all());\n    }\n\n    public function testPushCircularRelations()\n    {\n        $parent = new EloquentModelWithRecursiveRelationshipsStub(['id' => 1, 'parent_id' => null]);\n        $lastId = $parent->id;\n        $parent->setRelation('self', $parent);\n\n        $children = new Collection();\n        for ($count = 0; $count < 2; $count++) {\n            $child = new EloquentModelWithRecursiveRelationshipsStub(['id' => ++$lastId, 'parent_id' => $parent->id]);\n            $child->setRelation('parent', $parent);\n            $child->setRelation('self', $child);\n            $children->push($child);\n        }\n        $parent->setRelation('children', $children);\n\n        try {\n            $this->assertTrue($parent->push());\n        } catch (\\RuntimeException $e) {\n            $this->fail($e->getMessage());\n        }\n    }\n\n    public function testNewQueryReturnsEloquentQueryBuilder()\n    {\n        $conn = m::mock(Connection::class);\n        $grammar = m::mock(Grammar::class);\n        $processor = m::mock(Processor::class);\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $conn->shouldReceive('query')->andReturnUsing(function () use ($conn, $grammar, $processor) {\n            return new BaseBuilder($conn, $grammar, $processor);\n        });\n        $resolver->shouldReceive('connection')->andReturn($conn);\n        $model = new EloquentModelStub;\n        $builder = $model->newQuery();\n        $this->assertInstanceOf(Builder::class, $builder);\n    }\n\n    public function testGetAndSetTableOperations()\n    {\n        $model = new EloquentModelStub;\n        $this->assertSame('stub', $model->getTable());\n        $model->setTable('foo');\n        $this->assertSame('foo', $model->getTable());\n    }\n\n    public function testGetKeyReturnsValueOfPrimaryKey()\n    {\n        $model = new EloquentModelStub;\n        $model->id = 1;\n        $this->assertEquals(1, $model->getKey());\n        $this->assertSame('id', $model->getKeyName());\n    }\n\n    public function testConnectionManagement()\n    {\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $model = m::mock(EloquentModelStub::class.'[getConnectionName,connection]');\n\n        $retval = $model->setConnection('foo');\n        $this->assertEquals($retval, $model);\n        $this->assertSame('foo', $model->connection);\n\n        $model->shouldReceive('getConnectionName')->once()->andReturn('somethingElse');\n        $resolver->shouldReceive('connection')->once()->with('somethingElse')->andReturn('bar');\n\n        $this->assertSame('bar', $model->getConnection());\n    }\n\n    #[TestWith(['Foo'])]\n    #[TestWith([ConnectionName::Foo])]\n    #[TestWith([ConnectionNameBacked::Foo])]\n    public function testConnectionEnums(string|\\UnitEnum $connectionName)\n    {\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $model = new EloquentModelStub;\n\n        $retval = $model->setConnection($connectionName);\n        $this->assertEquals($retval, $model);\n        $this->assertSame('Foo', $model->getConnectionName());\n\n        $resolver->shouldReceive('connection')->once()->with('Foo')->andReturn('bar');\n\n        $this->assertSame('bar', $model->getConnection());\n    }\n\n    public function testToArray()\n    {\n        $model = new EloquentModelStub;\n        $model->name = 'foo';\n        $model->age = null;\n        $model->password = 'password1';\n        $model->setHidden(['password']);\n        $model->setRelation('names', new BaseCollection([\n            new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']),\n        ]));\n        $model->setRelation('partner', new EloquentModelStub(['name' => 'abby']));\n        $model->setRelation('group', null);\n        $model->setRelation('multi', new BaseCollection);\n        $array = $model->toArray();\n\n        $this->assertIsArray($array);\n        $this->assertSame('foo', $array['name']);\n        $this->assertSame('baz', $array['names'][0]['bar']);\n        $this->assertSame('boom', $array['names'][1]['bam']);\n        $this->assertSame('abby', $array['partner']['name']);\n        $this->assertNull($array['group']);\n        $this->assertEquals([], $array['multi']);\n        $this->assertFalse(isset($array['password']));\n\n        $model->setAppends(['appendable']);\n        $array = $model->toArray();\n        $this->assertSame('appended', $array['appendable']);\n    }\n\n    public function testToArrayWithCircularRelations()\n    {\n        $parent = new EloquentModelWithRecursiveRelationshipsStub(['id' => 1, 'parent_id' => null]);\n        $lastId = $parent->id;\n        $parent->setRelation('self', $parent);\n\n        $children = new Collection();\n        for ($count = 0; $count < 2; $count++) {\n            $child = new EloquentModelWithRecursiveRelationshipsStub(['id' => ++$lastId, 'parent_id' => $parent->id]);\n            $child->setRelation('parent', $parent);\n            $child->setRelation('self', $child);\n            $children->push($child);\n        }\n        $parent->setRelation('children', $children);\n\n        try {\n            $this->assertSame(\n                [\n                    'id' => 1,\n                    'parent_id' => null,\n                    'self' => ['id' => 1, 'parent_id' => null],\n                    'children' => [\n                        [\n                            'id' => 2,\n                            'parent_id' => 1,\n                            'parent' => ['id' => 1, 'parent_id' => null],\n                            'self' => ['id' => 2, 'parent_id' => 1],\n                        ],\n                        [\n                            'id' => 3,\n                            'parent_id' => 1,\n                            'parent' => ['id' => 1, 'parent_id' => null],\n                            'self' => ['id' => 3, 'parent_id' => 1],\n                        ],\n                    ],\n                ],\n                $parent->toArray()\n            );\n        } catch (\\RuntimeException $e) {\n            $this->fail($e->getMessage());\n        }\n    }\n\n    public function testGetQueueableRelationsWithCircularRelations()\n    {\n        $parent = new EloquentModelWithRecursiveRelationshipsStub(['id' => 1, 'parent_id' => null]);\n        $lastId = $parent->id;\n        $parent->setRelation('self', $parent);\n\n        $children = new Collection();\n        for ($count = 0; $count < 2; $count++) {\n            $child = new EloquentModelWithRecursiveRelationshipsStub(['id' => ++$lastId, 'parent_id' => $parent->id]);\n            $child->setRelation('parent', $parent);\n            $child->setRelation('self', $child);\n            $children->push($child);\n        }\n        $parent->setRelation('children', $children);\n\n        try {\n            $this->assertSame(\n                [\n                    'self',\n                    'children',\n                    'children.parent',\n                    'children.self',\n                ],\n                $parent->getQueueableRelations()\n            );\n        } catch (\\RuntimeException $e) {\n            $this->fail($e->getMessage());\n        }\n    }\n\n    public function testVisibleCreatesArrayWhitelist()\n    {\n        $model = new EloquentModelStub;\n        $model->setVisible(['name']);\n        $model->name = 'Taylor';\n        $model->age = 26;\n        $array = $model->toArray();\n\n        $this->assertEquals(['name' => 'Taylor'], $array);\n    }\n\n    public function testHiddenCanAlsoExcludeRelationships()\n    {\n        $model = new EloquentModelStub;\n        $model->name = 'Taylor';\n        $model->setRelation('foo', ['bar']);\n        $model->setHidden(['foo', 'list_items', 'password']);\n        $array = $model->toArray();\n\n        $this->assertEquals(['name' => 'Taylor'], $array);\n    }\n\n    public function testGetArrayableRelationsFunctionExcludeHiddenRelationships()\n    {\n        $model = new EloquentModelStub;\n\n        $class = new ReflectionClass($model);\n        $method = $class->getMethod('getArrayableRelations');\n\n        $model->setRelation('foo', ['bar']);\n        $model->setRelation('bam', ['boom']);\n        $model->setHidden(['foo']);\n\n        $array = $method->invokeArgs($model, []);\n\n        $this->assertSame(['bam' => ['boom']], $array);\n    }\n\n    public function testToArraySnakeAttributes()\n    {\n        $model = new EloquentModelStub;\n        $model->setRelation('namesList', new BaseCollection([\n            new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']),\n        ]));\n        $array = $model->toArray();\n\n        $this->assertSame('baz', $array['names_list'][0]['bar']);\n        $this->assertSame('boom', $array['names_list'][1]['bam']);\n\n        $model = new EloquentModelCamelStub;\n        $model->setRelation('namesList', new BaseCollection([\n            new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']),\n        ]));\n        $array = $model->toArray();\n\n        $this->assertSame('baz', $array['namesList'][0]['bar']);\n        $this->assertSame('boom', $array['namesList'][1]['bam']);\n    }\n\n    public function testToArrayUsesMutators()\n    {\n        $model = new EloquentModelStub;\n        $model->list_items = [1, 2, 3];\n        $array = $model->toArray();\n\n        $this->assertEquals([1, 2, 3], $array['list_items']);\n    }\n\n    public function testHidden()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $model->setHidden(['age', 'id']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n    }\n\n    public function testMergeHiddenMergesHidden()\n    {\n        $model = new EloquentModelHiddenStub;\n\n        $hiddenCount = count($model->getHidden());\n        $this->assertContains('foo', $model->getHidden());\n\n        $model->mergeHidden(['bar']);\n        $this->assertCount($hiddenCount + 1, $model->getHidden());\n        $this->assertContains('bar', $model->getHidden());\n    }\n\n    public function testVisible()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $model->setVisible(['name', 'id']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n    }\n\n    public function testMergeVisibleMergesVisible()\n    {\n        $model = new EloquentModelVisibleStub;\n\n        $visibleCount = count($model->getVisible());\n        $this->assertContains('foo', $model->getVisible());\n\n        $model->mergeVisible(['bar']);\n        $this->assertCount($visibleCount + 1, $model->getVisible());\n        $this->assertContains('bar', $model->getVisible());\n    }\n\n    public function testDynamicHidden()\n    {\n        $model = new EloquentModelDynamicHiddenStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n    }\n\n    public function testWithHidden()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $model->setHidden(['age', 'id']);\n        $model->makeVisible('age');\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayNotHasKey('id', $array);\n    }\n\n    public function testMakeHidden()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'address' => 'foobar', 'id' => 'baz']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayHasKey('address', $array);\n        $this->assertArrayHasKey('id', $array);\n\n        $array = $model->makeHidden('address')->toArray();\n        $this->assertArrayNotHasKey('address', $array);\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayHasKey('id', $array);\n\n        $array = $model->makeHidden(['name', 'age'])->toArray();\n        $this->assertArrayNotHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n        $this->assertArrayNotHasKey('address', $array);\n        $this->assertArrayHasKey('id', $array);\n    }\n\n    public function testDynamicVisible()\n    {\n        $model = new EloquentModelDynamicVisibleStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n    }\n\n    public function testMakeVisibleIf()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']);\n        $model->setHidden(['age', 'id']);\n        $model->makeVisibleIf(true, 'age');\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayNotHasKey('id', $array);\n\n        $model->setHidden(['age', 'id']);\n        $model->makeVisibleIf(false, 'age');\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n        $this->assertArrayNotHasKey('id', $array);\n\n        $model->setHidden(['age', 'id']);\n        $model->makeVisibleIf(function ($model) {\n            return ! is_null($model->name);\n        }, 'age');\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayNotHasKey('id', $array);\n    }\n\n    public function testMakeHiddenIf()\n    {\n        $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'address' => 'foobar', 'id' => 'baz']);\n        $array = $model->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayHasKey('address', $array);\n        $this->assertArrayHasKey('id', $array);\n\n        $array = $model->makeHiddenIf(true, 'address')->toArray();\n        $this->assertArrayNotHasKey('address', $array);\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayHasKey('id', $array);\n\n        $model->makeVisible('address');\n\n        $array = $model->makeHiddenIf(false, ['name', 'age'])->toArray();\n        $this->assertArrayHasKey('name', $array);\n        $this->assertArrayHasKey('age', $array);\n        $this->assertArrayHasKey('address', $array);\n        $this->assertArrayHasKey('id', $array);\n\n        $array = $model->makeHiddenIf(function ($model) {\n            return ! is_null($model->id);\n        }, ['name', 'age'])->toArray();\n        $this->assertArrayHasKey('address', $array);\n        $this->assertArrayNotHasKey('name', $array);\n        $this->assertArrayNotHasKey('age', $array);\n        $this->assertArrayHasKey('id', $array);\n    }\n\n    public function testFillable()\n    {\n        $model = new EloquentModelStub;\n        $model->fillable(['name', 'age']);\n        $model->fill(['name' => 'foo', 'age' => 'bar']);\n        $this->assertSame('foo', $model->name);\n        $this->assertSame('bar', $model->age);\n    }\n\n    public function testQualifyColumn()\n    {\n        $model = new EloquentModelStub;\n\n        $this->assertSame('stub.column', $model->qualifyColumn('column'));\n    }\n\n    public function testForceFillMethodFillsGuardedAttributes()\n    {\n        $model = (new EloquentModelSaveStub)->forceFill(['id' => 21]);\n        $this->assertEquals(21, $model->id);\n    }\n\n    public function testFillingJSONAttributes()\n    {\n        $model = new EloquentModelStub;\n        $model->fillable(['meta->name', 'meta->price', 'meta->size->width']);\n        $model->fill(['meta->name' => 'foo', 'meta->price' => 'bar', 'meta->size->width' => 'baz']);\n        $this->assertEquals(\n            ['meta' => json_encode(['name' => 'foo', 'price' => 'bar', 'size' => ['width' => 'baz']])],\n            $model->toArray()\n        );\n\n        $model = new EloquentModelStub(['meta' => json_encode(['name' => 'Taylor'])]);\n        $model->fillable(['meta->name', 'meta->price', 'meta->size->width']);\n        $model->fill(['meta->name' => 'foo', 'meta->price' => 'bar', 'meta->size->width' => 'baz']);\n        $this->assertEquals(\n            ['meta' => json_encode(['name' => 'foo', 'price' => 'bar', 'size' => ['width' => 'baz']])],\n            $model->toArray()\n        );\n    }\n\n    public function testUnguardAllowsAnythingToBeSet()\n    {\n        $model = new EloquentModelStub;\n        EloquentModelStub::unguard();\n        $model->guard(['*']);\n        $model->fill(['name' => 'foo', 'age' => 'bar']);\n        $this->assertSame('foo', $model->name);\n        $this->assertSame('bar', $model->age);\n        EloquentModelStub::unguard(false);\n    }\n\n    public function testUnderscorePropertiesAreNotFilled()\n    {\n        $model = new EloquentModelStub;\n        $model->fill(['_method' => 'PUT']);\n        $this->assertEquals([], $model->getAttributes());\n    }\n\n    public function testGuarded()\n    {\n        $model = new EloquentModelStub;\n\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class));\n        $resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class));\n        $connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']);\n\n        $model->guard(['name', 'age']);\n        $model->fill(['name' => 'foo', 'age' => 'bar', 'foo' => 'bar']);\n        $this->assertFalse(isset($model->name));\n        $this->assertFalse(isset($model->age));\n        $this->assertSame('bar', $model->foo);\n\n        $model = new EloquentModelStub;\n        $model->guard(['name', 'age']);\n        $model->fill(['Foo' => 'bar']);\n        $this->assertFalse(isset($model->Foo));\n\n        $handledMassAssignmentExceptions = 0;\n\n        Model::preventSilentlyDiscardingAttributes();\n\n        $this->expectException(MassAssignmentException::class);\n        $model = new EloquentModelStub;\n        $model->guard(['name', 'age']);\n        $model->fill(['Foo' => 'bar']);\n\n        Model::preventSilentlyDiscardingAttributes(false);\n    }\n\n    public function testGuardedWithFillableConfig(): void\n    {\n        $model = new EloquentModelStub;\n        $model::unguard();\n\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class));\n        $resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class));\n        $connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']);\n\n        $model->guard([]);\n        $model->fillable(['name']);\n        $model->fill(['name' => 'Leto Atreides', 'age' => 51]);\n\n        self::assertSame(\n            ['name' => 'Leto Atreides', 'age' => 51],\n            $model->getAttributes(),\n        );\n\n        $model::reguard();\n    }\n\n    public function testUsesOverriddenHandlerWhenDiscardingAttributes()\n    {\n        EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class));\n        $resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class));\n        $connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']);\n\n        Model::preventSilentlyDiscardingAttributes();\n\n        $callbackModel = null;\n        $callbackKeys = null;\n        Model::handleDiscardedAttributeViolationUsing(function ($model, $keys) use (&$callbackModel, &$callbackKeys) {\n            $callbackModel = $model;\n            $callbackKeys = $keys;\n        });\n\n        $model = new EloquentModelStub;\n        $model->guard(['name', 'age']);\n        $model->fill(['Foo' => 'bar']);\n\n        $this->assertInstanceOf(EloquentModelStub::class, $callbackModel);\n        $this->assertEquals(['Foo'], $callbackKeys);\n\n        Model::preventSilentlyDiscardingAttributes(false);\n        Model::handleDiscardedAttributeViolationUsing(null);\n    }\n\n    public function testFillableOverridesGuarded()\n    {\n        Model::preventSilentlyDiscardingAttributes(false);\n\n        $model = new EloquentModelStub;\n        $model->guard([]);\n        $model->fillable(['age', 'foo']);\n        $model->fill(['name' => 'foo', 'age' => 'bar', 'foo' => 'bar']);\n        $this->assertFalse(isset($model->name));\n        $this->assertSame('bar', $model->age);\n        $this->assertSame('bar', $model->foo);\n    }\n\n    public function testGlobalGuarded()\n    {\n        $this->expectException(MassAssignmentException::class);\n        $this->expectExceptionMessage('name');\n\n        $model = new EloquentModelStub;\n        $model->guard(['*']);\n        $model->fill(['name' => 'foo', 'age' => 'bar', 'votes' => 'baz']);\n    }\n\n    public function testUnguardedRunsCallbackWhileBeingUnguarded()\n    {\n        $model = Model::unguarded(function () {\n            return (new EloquentModelStub)->guard(['*'])->fill(['name' => 'Taylor']);\n        });\n        $this->assertSame('Taylor', $model->name);\n        $this->assertFalse(Model::isUnguarded());\n    }\n\n    public function testUnguardedCallDoesNotChangeUnguardedState()\n    {\n        Model::unguard();\n        $model = Model::unguarded(function () {\n            return (new EloquentModelStub)->guard(['*'])->fill(['name' => 'Taylor']);\n        });\n        $this->assertSame('Taylor', $model->name);\n        $this->assertTrue(Model::isUnguarded());\n        Model::reguard();\n    }\n\n    public function testUnguardedCallDoesNotChangeUnguardedStateOnException()\n    {\n        try {\n            Model::unguarded(function () {\n                throw new Exception;\n            });\n        } catch (Exception) {\n            // ignore the exception\n        }\n        $this->assertFalse(Model::isUnguarded());\n    }\n\n    public function testHasOneCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->hasOne(EloquentModelSaveStub::class);\n        $this->assertSame('save_stub.eloquent_model_stub_id', $relation->getQualifiedForeignKeyName());\n\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->hasOne(EloquentModelSaveStub::class, 'foo');\n        $this->assertSame('save_stub.foo', $relation->getQualifiedForeignKeyName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n    }\n\n    public function testMorphOneCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->morphOne(EloquentModelSaveStub::class, 'morph');\n        $this->assertSame('save_stub.morph_id', $relation->getQualifiedForeignKeyName());\n        $this->assertSame('save_stub.morph_type', $relation->getQualifiedMorphType());\n        $this->assertEquals(EloquentModelStub::class, $relation->getMorphClass());\n    }\n\n    public function testCorrectMorphClassIsReturned()\n    {\n        Relation::morphMap(['alias' => 'AnotherModel']);\n        $model = new EloquentModelStub;\n\n        try {\n            $this->assertEquals(EloquentModelStub::class, $model->getMorphClass());\n        } finally {\n            Relation::morphMap([], false);\n        }\n    }\n\n    public function testHasManyCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->hasMany(EloquentModelSaveStub::class);\n        $this->assertSame('save_stub.eloquent_model_stub_id', $relation->getQualifiedForeignKeyName());\n\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->hasMany(EloquentModelSaveStub::class, 'foo');\n\n        $this->assertSame('save_stub.foo', $relation->getQualifiedForeignKeyName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n    }\n\n    public function testMorphManyCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->morphMany(EloquentModelSaveStub::class, 'morph');\n        $this->assertSame('save_stub.morph_id', $relation->getQualifiedForeignKeyName());\n        $this->assertSame('save_stub.morph_type', $relation->getQualifiedMorphType());\n        $this->assertEquals(EloquentModelStub::class, $relation->getMorphClass());\n    }\n\n    public function testBelongsToCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->belongsToStub();\n        $this->assertSame('belongs_to_stub_id', $relation->getForeignKeyName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->belongsToExplicitKeyStub();\n        $this->assertSame('foo', $relation->getForeignKeyName());\n    }\n\n    public function testMorphToCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n\n        // $this->morphTo();\n        $model->setAttribute('morph_to_stub_type', EloquentModelSaveStub::class);\n        $relation = $model->morphToStub();\n        $this->assertSame('morph_to_stub_id', $relation->getForeignKeyName());\n        $this->assertSame('morph_to_stub_type', $relation->getMorphType());\n        $this->assertSame('morphToStub', $relation->getRelationName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n\n        // $this->morphTo(null, 'type', 'id');\n        $relation2 = $model->morphToStubWithKeys();\n        $this->assertSame('id', $relation2->getForeignKeyName());\n        $this->assertSame('type', $relation2->getMorphType());\n        $this->assertSame('morphToStubWithKeys', $relation2->getRelationName());\n\n        // $this->morphTo('someName');\n        $relation3 = $model->morphToStubWithName();\n        $this->assertSame('some_name_id', $relation3->getForeignKeyName());\n        $this->assertSame('some_name_type', $relation3->getMorphType());\n        $this->assertSame('someName', $relation3->getRelationName());\n\n        // $this->morphTo('someName', 'type', 'id');\n        $relation4 = $model->morphToStubWithNameAndKeys();\n        $this->assertSame('id', $relation4->getForeignKeyName());\n        $this->assertSame('type', $relation4->getMorphType());\n        $this->assertSame('someName', $relation4->getRelationName());\n    }\n\n    public function testBelongsToManyCreatesProperRelation()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n\n        $relation = $model->belongsToMany(EloquentModelSaveStub::class);\n        $this->assertSame('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_stub_id', $relation->getQualifiedForeignPivotKeyName());\n        $this->assertSame('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_save_stub_id', $relation->getQualifiedRelatedPivotKeyName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n        $this->assertEquals(__FUNCTION__, $relation->getRelationName());\n\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n        $relation = $model->belongsToMany(EloquentModelSaveStub::class, 'table', 'foreign', 'other');\n        $this->assertSame('table.foreign', $relation->getQualifiedForeignPivotKeyName());\n        $this->assertSame('table.other', $relation->getQualifiedRelatedPivotKeyName());\n        $this->assertSame($model, $relation->getParent());\n        $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel());\n    }\n\n    public function testRelationsWithVariedConnections()\n    {\n        // Has one\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasOne(EloquentNoConnectionModelStub::class);\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasOne(EloquentDifferentConnectionModelStub::class);\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n\n        // Morph One\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->morphOne(EloquentNoConnectionModelStub::class, 'type');\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->morphOne(EloquentDifferentConnectionModelStub::class, 'type');\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n\n        // Belongs to\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->belongsTo(EloquentNoConnectionModelStub::class);\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->belongsTo(EloquentDifferentConnectionModelStub::class);\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n\n        // has many\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasMany(EloquentNoConnectionModelStub::class);\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasMany(EloquentDifferentConnectionModelStub::class);\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n\n        // has many through\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasManyThrough(EloquentNoConnectionModelStub::class, EloquentModelSaveStub::class);\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->hasManyThrough(EloquentDifferentConnectionModelStub::class, EloquentModelSaveStub::class);\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n\n        // belongs to many\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->belongsToMany(EloquentNoConnectionModelStub::class);\n        $this->assertSame('non_default', $relation->getRelated()->getConnectionName());\n\n        $model = new EloquentModelStub;\n        $model->setConnection('non_default');\n        $this->addMockConnection($model);\n        $relation = $model->belongsToMany(EloquentDifferentConnectionModelStub::class);\n        $this->assertSame('different_connection', $relation->getRelated()->getConnectionName());\n    }\n\n    public function testModelsAssumeTheirName()\n    {\n        require_once __DIR__.'/stubs/EloquentModelNamespacedStub.php';\n\n        $model = new EloquentModelWithoutTableStub;\n        $this->assertSame('eloquent_model_without_table_stubs', $model->getTable());\n\n        $namespacedModel = new EloquentModelNamespacedStub;\n        $this->assertSame('eloquent_model_namespaced_stubs', $namespacedModel->getTable());\n    }\n\n    public function testTheMutatorCacheIsPopulated()\n    {\n        $class = new EloquentModelStub;\n\n        $expectedAttributes = [\n            'list_items',\n            'password',\n            'appendable',\n        ];\n\n        $this->assertEquals($expectedAttributes, $class->getMutatedAttributes());\n    }\n\n    public function testRouteKeyIsPrimaryKey()\n    {\n        $model = new EloquentModelNonIncrementingStub;\n        $model->id = 'foo';\n        $this->assertSame('foo', $model->getRouteKey());\n    }\n\n    public function testRouteNameIsPrimaryKeyName()\n    {\n        $model = new EloquentModelStub;\n        $this->assertSame('id', $model->getRouteKeyName());\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModel()\n    {\n        $class = new EloquentModelStub;\n        $class->id = 1;\n        $class->exists = true;\n        $class->first = 'taylor';\n        $class->last = 'otwell';\n        $class->created_at = $class->freshTimestamp();\n        $class->updated_at = $class->freshTimestamp();\n        $class->setRelation('foo', ['bar']);\n\n        $clone = $class->replicate();\n\n        $this->assertNull($clone->id);\n        $this->assertFalse($clone->exists);\n        $this->assertSame('taylor', $clone->first);\n        $this->assertSame('otwell', $clone->last);\n        $this->assertArrayNotHasKey('created_at', $clone->getAttributes());\n        $this->assertArrayNotHasKey('updated_at', $clone->getAttributes());\n        $this->assertEquals(['bar'], $clone->foo);\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModelWhenModelHasUuidPrimaryKey()\n    {\n        $class = new EloquentPrimaryUuidModelStub();\n        $class->uuid = 'ccf55569-bc4a-4450-875f-b5cffb1b34ec';\n        $class->exists = true;\n        $class->first = 'taylor';\n        $class->last = 'otwell';\n        $class->created_at = $class->freshTimestamp();\n        $class->updated_at = $class->freshTimestamp();\n        $class->setRelation('foo', ['bar']);\n\n        $clone = $class->replicate();\n\n        $this->assertNull($clone->uuid);\n        $this->assertFalse($clone->exists);\n        $this->assertSame('taylor', $clone->first);\n        $this->assertSame('otwell', $clone->last);\n        $this->assertArrayNotHasKey('created_at', $clone->getAttributes());\n        $this->assertArrayNotHasKey('updated_at', $clone->getAttributes());\n        $this->assertEquals(['bar'], $clone->foo);\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModelWhenModelHasUuid()\n    {\n        $class = new EloquentNonPrimaryUuidModelStub();\n        $class->id = 1;\n        $class->uuid = 'ccf55569-bc4a-4450-875f-b5cffb1b34ec';\n        $class->exists = true;\n        $class->first = 'taylor';\n        $class->last = 'otwell';\n        $class->created_at = $class->freshTimestamp();\n        $class->updated_at = $class->freshTimestamp();\n        $class->setRelation('foo', ['bar']);\n\n        $clone = $class->replicate();\n\n        $this->assertNull($clone->id);\n        $this->assertNull($clone->uuid);\n        $this->assertFalse($clone->exists);\n        $this->assertSame('taylor', $clone->first);\n        $this->assertSame('otwell', $clone->last);\n        $this->assertArrayNotHasKey('created_at', $clone->getAttributes());\n        $this->assertArrayNotHasKey('updated_at', $clone->getAttributes());\n        $this->assertEquals(['bar'], $clone->foo);\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModelWhenModelHasUlidPrimaryKey()\n    {\n        $class = new EloquentPrimaryUlidModelStub();\n        $class->ulid = '01HBZ975D8606P6CV672KW1AP2';\n        $class->exists = true;\n        $class->first = 'taylor';\n        $class->last = 'otwell';\n        $class->created_at = $class->freshTimestamp();\n        $class->updated_at = $class->freshTimestamp();\n        $class->setRelation('foo', ['bar']);\n\n        $clone = $class->replicate();\n\n        $this->assertNull($clone->ulid);\n        $this->assertFalse($clone->exists);\n        $this->assertSame('taylor', $clone->first);\n        $this->assertSame('otwell', $clone->last);\n        $this->assertArrayNotHasKey('created_at', $clone->getAttributes());\n        $this->assertArrayNotHasKey('updated_at', $clone->getAttributes());\n        $this->assertEquals(['bar'], $clone->foo);\n    }\n\n    public function testCloneModelMakesAFreshCopyOfTheModelWhenModelHasUlid()\n    {\n        $class = new EloquentNonPrimaryUlidModelStub();\n        $class->id = 1;\n        $class->ulid = '01HBZ975D8606P6CV672KW1AP2';\n        $class->exists = true;\n        $class->first = 'taylor';\n        $class->last = 'otwell';\n        $class->created_at = $class->freshTimestamp();\n        $class->updated_at = $class->freshTimestamp();\n        $class->setRelation('foo', ['bar']);\n\n        $clone = $class->replicate();\n\n        $this->assertNull($clone->id);\n        $this->assertNull($clone->ulid);\n        $this->assertFalse($clone->exists);\n        $this->assertSame('taylor', $clone->first);\n        $this->assertSame('otwell', $clone->last);\n        $this->assertArrayNotHasKey('created_at', $clone->getAttributes());\n        $this->assertArrayNotHasKey('updated_at', $clone->getAttributes());\n        $this->assertEquals(['bar'], $clone->foo);\n    }\n\n    public function testModelObserversCanBeAttachedToModels()\n    {\n        EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelStub::observe(new EloquentTestObserverStub);\n        EloquentModelStub::flushEventListeners();\n    }\n\n    public function testModelObserversCanBeAttachedToModelsWithString()\n    {\n        EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelStub::observe(EloquentTestObserverStub::class);\n        EloquentModelStub::flushEventListeners();\n    }\n\n    public function testModelObserversCanBeAttachedToModelsThroughAnArray()\n    {\n        EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelStub::observe([EloquentTestObserverStub::class]);\n        EloquentModelStub::flushEventListeners();\n    }\n\n    public function testModelObserversCanBeAttachedToModelsWithStringUsingAttribute()\n    {\n        EloquentModelWithObserveAttributeStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch');\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelWithObserveAttributeStub::flushEventListeners();\n    }\n\n    public function testModelObserversCanBeAttachedToModelsThroughAnArrayUsingAttribute()\n    {\n        EloquentModelWithObserveAttributeUsingArrayStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch');\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeUsingArrayStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeUsingArrayStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelWithObserveAttributeUsingArrayStub::flushEventListeners();\n    }\n\n    public function testModelObserversCanBeAttachedToModelsThroughAttributesOnParentClasses()\n    {\n        EloquentModelWithObserveAttributeGrandchildStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch');\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestAnotherObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestAnotherObserverStub::class.'@saved');\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestThirdObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelWithObserveAttributeGrandchildStub', EloquentTestThirdObserverStub::class.'@saved');\n        $events->shouldReceive('forget');\n        EloquentModelWithObserveAttributeGrandchildStub::flushEventListeners();\n    }\n\n    public function testThrowExceptionOnAttachingNotExistsModelObserverWithString()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        EloquentModelStub::observe(NotExistClass::class);\n    }\n\n    public function testThrowExceptionOnAttachingNotExistsModelObserversThroughAnArray()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        EloquentModelStub::observe([NotExistClass::class]);\n    }\n\n    public function testModelObserversCanBeAttachedToModelsThroughCallingObserveMethodOnlyOnce()\n    {\n        EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestObserverStub::class.'@saved');\n\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestAnotherObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelStub', EloquentTestAnotherObserverStub::class.'@saved');\n\n        $events->shouldReceive('forget');\n\n        EloquentModelStub::observe([\n            EloquentTestObserverStub::class,\n            EloquentTestAnotherObserverStub::class,\n        ]);\n\n        EloquentModelStub::flushEventListeners();\n    }\n\n    public function testWithoutEventDispatcher()\n    {\n        EloquentModelSaveStub::setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\\Tests\\Database\\EloquentModelSaveStub', EloquentTestObserverStub::class.'@creating');\n        $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelSaveStub', EloquentTestObserverStub::class.'@saved');\n        $events->shouldNotReceive('until');\n        $events->shouldNotReceive('dispatch');\n        $events->shouldReceive('forget');\n        EloquentModelSaveStub::observe(EloquentTestObserverStub::class);\n\n        $model = EloquentModelSaveStub::withoutEvents(function () {\n            $model = new EloquentModelSaveStub;\n            $model->save();\n\n            return $model;\n        });\n\n        $model->withoutEvents(function () use ($model) {\n            $model->first_name = 'Taylor';\n            $model->save();\n        });\n\n        $events->shouldReceive('until')->once()->with('eloquent.saving: Illuminate\\Tests\\Database\\EloquentModelSaveStub', $model);\n        $events->shouldReceive('dispatch')->once()->with('eloquent.saved: Illuminate\\Tests\\Database\\EloquentModelSaveStub', $model);\n\n        $model->last_name = 'Otwell';\n        $model->save();\n\n        EloquentModelSaveStub::flushEventListeners();\n    }\n\n    public function testSetObservableEvents()\n    {\n        $class = new EloquentModelStub;\n        $class->setObservableEvents(['foo']);\n\n        $this->assertContains('foo', $class->getObservableEvents());\n    }\n\n    public function testAddObservableEvent()\n    {\n        $class = new EloquentModelStub;\n        $class->addObservableEvents('foo');\n\n        $this->assertContains('foo', $class->getObservableEvents());\n    }\n\n    public function testAddMultipleObserveableEvents()\n    {\n        $class = new EloquentModelStub;\n        $class->addObservableEvents('foo', 'bar');\n\n        $this->assertContains('foo', $class->getObservableEvents());\n        $this->assertContains('bar', $class->getObservableEvents());\n    }\n\n    public function testRemoveObservableEvent()\n    {\n        $class = new EloquentModelStub;\n        $class->setObservableEvents(['foo', 'bar']);\n        $class->removeObservableEvents('bar');\n\n        $this->assertNotContains('bar', $class->getObservableEvents());\n    }\n\n    public function testRemoveMultipleObservableEvents()\n    {\n        $class = new EloquentModelStub;\n        $class->setObservableEvents(['foo', 'bar']);\n        $class->removeObservableEvents('foo', 'bar');\n\n        $this->assertNotContains('foo', $class->getObservableEvents());\n        $this->assertNotContains('bar', $class->getObservableEvents());\n    }\n\n    public function testGetModelAttributeMethodThrowsExceptionIfNotRelation()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Illuminate\\Tests\\Database\\EloquentModelStub::incorrectRelationStub must return a relationship instance.');\n\n        $model = new EloquentModelStub;\n        $model->incorrectRelationStub;\n    }\n\n    public function testModelIsBootedOnUnserialize()\n    {\n        $model = new EloquentModelBootingTestStub;\n        $this->assertTrue(EloquentModelBootingTestStub::isBooted());\n        $model->foo = 'bar';\n        $string = serialize($model);\n        $model = null;\n        EloquentModelBootingTestStub::unboot();\n        $this->assertFalse(EloquentModelBootingTestStub::isBooted());\n        unserialize($string);\n        $this->assertTrue(EloquentModelBootingTestStub::isBooted());\n    }\n\n    public function testCallbacksCanBeRunAfterBootingHasFinished()\n    {\n        $this->assertFalse(EloquentModelBootingCallbackTestStub::$bootHasFinished);\n\n        $model = new EloquentModelBootingCallbackTestStub();\n\n        $this->assertTrue($model::$bootHasFinished);\n\n        EloquentModelBootingCallbackTestStub::unboot();\n    }\n\n    public function testBootedCallbacksAreSeparatedByClass()\n    {\n        $this->assertFalse(EloquentModelBootingCallbackTestStub::$bootHasFinished);\n\n        $model = new EloquentModelBootingCallbackTestStub();\n\n        $this->assertTrue($model::$bootHasFinished);\n\n        $this->assertFalse(EloquentChildModelBootingCallbackTestStub::$bootHasFinished);\n\n        $model = new EloquentChildModelBootingCallbackTestStub();\n\n        $this->assertTrue($model::$bootHasFinished);\n\n        EloquentModelBootingCallbackTestStub::unboot();\n        EloquentChildModelBootingCallbackTestStub::unboot();\n    }\n\n    public function testModelsTraitIsInitialized()\n    {\n        $model = new EloquentModelStubWithTrait;\n        $this->assertTrue($model->fooBarIsInitialized);\n    }\n\n    public function testAppendingOfAttributes()\n    {\n        $model = new EloquentModelAppendsStub;\n\n        $this->assertTrue(isset($model->is_admin));\n        $this->assertTrue(isset($model->camelCased));\n        $this->assertTrue(isset($model->StudlyCased));\n\n        $this->assertSame('admin', $model->is_admin);\n        $this->assertSame('camelCased', $model->camelCased);\n        $this->assertSame('StudlyCased', $model->StudlyCased);\n\n        $this->assertEquals(['is_admin', 'camelCased', 'StudlyCased'], $model->getAppends());\n\n        $this->assertTrue($model->hasAppended('is_admin'));\n        $this->assertTrue($model->hasAppended('camelCased'));\n        $this->assertTrue($model->hasAppended('StudlyCased'));\n        $this->assertFalse($model->hasAppended('not_appended'));\n\n        $model->setHidden(['is_admin', 'camelCased', 'StudlyCased']);\n        $this->assertEquals([], $model->toArray());\n\n        $model->setVisible([]);\n        $this->assertEquals([], $model->toArray());\n    }\n\n    public function testMergeAppendsMergesAppends()\n    {\n        $model = new EloquentModelAppendsStub;\n\n        $appendsCount = count($model->getAppends());\n        $this->assertEquals(['is_admin', 'camelCased', 'StudlyCased'], $model->getAppends());\n\n        $model->mergeAppends(['bar']);\n        $this->assertCount($appendsCount + 1, $model->getAppends());\n        $this->assertContains('bar', $model->getAppends());\n    }\n\n    public function testHasAppendedReturnsTrueWhenAttributeIsAppended()\n    {\n        $model = new EloquentModelAppendsStub;\n\n        $this->assertTrue($model->hasAppended('is_admin'));\n        $this->assertTrue($model->hasAppended('camelCased'));\n        $this->assertTrue($model->hasAppended('StudlyCased'));\n    }\n\n    public function testHasAppendedReturnsFalseWhenAttributeIsNotAppended()\n    {\n        $model = new EloquentModelAppendsStub;\n\n        $this->assertFalse($model->hasAppended('foo'));\n        $this->assertFalse($model->hasAppended('bar'));\n    }\n\n    public function testWithoutAppendsRemovesAppends()\n    {\n        $model = new EloquentModelAppendsStub;\n\n        $this->assertEquals(['is_admin', 'camelCased', 'StudlyCased'], $model->getAppends());\n\n        $model->withoutAppends();\n\n        $this->assertEmpty($model->getAppends());\n    }\n\n    public function testGetMutatedAttributes()\n    {\n        $model = new EloquentModelGetMutatorsStub;\n\n        $this->assertEquals(['first_name', 'middle_name', 'last_name'], $model->getMutatedAttributes());\n\n        EloquentModelGetMutatorsStub::resetMutatorCache();\n\n        EloquentModelGetMutatorsStub::$snakeAttributes = false;\n        $this->assertEquals(['firstName', 'middleName', 'lastName'], $model->getMutatedAttributes());\n    }\n\n    public function testReplicateCreatesANewModelInstanceWithSameAttributeValues()\n    {\n        $model = new EloquentModelStub;\n        $model->id = 'id';\n        $model->foo = 'bar';\n        $model->created_at = new DateTime;\n        $model->updated_at = new DateTime;\n        $replicated = $model->replicate();\n\n        $this->assertNull($replicated->id);\n        $this->assertSame('bar', $replicated->foo);\n        $this->assertNull($replicated->created_at);\n        $this->assertNull($replicated->updated_at);\n    }\n\n    public function testReplicatingEventIsFiredWhenReplicatingModel()\n    {\n        $model = new EloquentModelStub;\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with('eloquent.replicating: '.get_class($model), m::on(function ($m) use ($model) {\n            return $model->is($m);\n        }));\n\n        $model->replicate();\n    }\n\n    public function testReplicateQuietlyCreatesANewModelInstanceWithSameAttributeValuesAndIsQuiet()\n    {\n        $model = new EloquentModelStub;\n        $model->id = 'id';\n        $model->foo = 'bar';\n        $model->created_at = new DateTime;\n        $model->updated_at = new DateTime;\n        $replicated = $model->replicateQuietly();\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->never()->with('eloquent.replicating: '.get_class($model), $model)->andReturn(true);\n\n        $this->assertNull($replicated->id);\n        $this->assertSame('bar', $replicated->foo);\n        $this->assertNull($replicated->created_at);\n        $this->assertNull($replicated->updated_at);\n    }\n\n    public function testIncrementOnExistingModelCallsQueryAndSetsAttribute()\n    {\n        $model = m::mock(EloquentModelStub::class.'[newQueryWithoutScopes]');\n        $model->exists = true;\n        $model->id = 1;\n        $model->syncOriginalAttribute('id');\n        $model->foo = 2;\n\n        $model->shouldReceive('newQueryWithoutScopes')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->andReturn($query);\n        $query->shouldReceive('increment');\n\n        // hmm\n        $model->publicIncrement('foo', 1);\n        $this->assertFalse($model->isDirty());\n\n        $model->publicIncrement('foo', 1, ['category' => 1]);\n        $this->assertEquals(4, $model->foo);\n        $this->assertEquals(1, $model->category);\n        $this->assertTrue($model->isDirty('category'));\n    }\n\n    public function testIncrementQuietlyOnExistingModelCallsQueryAndSetsAttributeAndIsQuiet()\n    {\n        $model = m::mock(EloquentModelStub::class.'[newQueryWithoutScopes]');\n        $model->exists = true;\n        $model->id = 1;\n        $model->syncOriginalAttribute('id');\n        $model->foo = 2;\n\n        $model->shouldReceive('newQueryWithoutScopes')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->andReturn($query);\n        $query->shouldReceive('increment');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->never()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->never()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->never()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->never()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true);\n\n        $model->publicIncrementQuietly('foo', 1);\n        $this->assertFalse($model->isDirty());\n\n        $model->publicIncrementQuietly('foo', 1, ['category' => 1]);\n        $this->assertEquals(4, $model->foo);\n        $this->assertEquals(1, $model->category);\n        $this->assertTrue($model->isDirty('category'));\n    }\n\n    public function testDecrementQuietlyOnExistingModelCallsQueryAndSetsAttributeAndIsQuiet()\n    {\n        $model = m::mock(EloquentModelStub::class.'[newQueryWithoutScopes]');\n        $model->exists = true;\n        $model->id = 1;\n        $model->syncOriginalAttribute('id');\n        $model->foo = 4;\n\n        $model->shouldReceive('newQueryWithoutScopes')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->andReturn($query);\n        $query->shouldReceive('decrement');\n\n        $model->setEventDispatcher($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('until')->never()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('until')->never()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->never()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true);\n        $events->shouldReceive('dispatch')->never()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true);\n\n        $model->publicDecrementQuietly('foo', 1);\n        $this->assertFalse($model->isDirty());\n\n        $model->publicDecrementQuietly('foo', 1, ['category' => 1]);\n        $this->assertEquals(2, $model->foo);\n        $this->assertEquals(1, $model->category);\n        $this->assertTrue($model->isDirty('category'));\n    }\n\n    public function testRelationshipTouchOwnersIsPropagated()\n    {\n        $relation = $this->getMockBuilder(BelongsTo::class)->onlyMethods(['touch'])->disableOriginalConstructor()->getMock();\n        $relation->expects($this->once())->method('touch');\n\n        $model = m::mock(EloquentModelStub::class.'[partner]');\n        $this->addMockConnection($model);\n        $model->shouldReceive('partner')->once()->andReturn($relation);\n        $model->setTouchedRelations(['partner']);\n\n        $mockPartnerModel = m::mock(EloquentModelStub::class.'[touchOwners]');\n        $mockPartnerModel->shouldReceive('touchOwners')->once();\n        $model->setRelation('partner', $mockPartnerModel);\n\n        $model->touchOwners();\n    }\n\n    public function testRelationshipTouchOwnersIsNotPropagatedIfNoRelationshipResult()\n    {\n        $relation = $this->getMockBuilder(BelongsTo::class)->onlyMethods(['touch'])->disableOriginalConstructor()->getMock();\n        $relation->expects($this->once())->method('touch');\n\n        $model = m::mock(EloquentModelStub::class.'[partner]');\n        $this->addMockConnection($model);\n        $model->shouldReceive('partner')->once()->andReturn($relation);\n        $model->setTouchedRelations(['partner']);\n\n        $model->setRelation('partner', null);\n\n        $model->touchOwners();\n    }\n\n    public function testModelAttributesAreCastedWhenPresentInCastsPropertyOrCastsMethod()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setDateFormat('Y-m-d H:i:s');\n        $model->intAttribute = '3';\n        $model->floatAttribute = '4.0';\n        $model->stringAttribute = 2.5;\n        $model->boolAttribute = 1;\n        $model->booleanAttribute = 0;\n        $model->objectAttribute = ['foo' => 'bar'];\n        $obj = new stdClass;\n        $obj->foo = 'bar';\n        $model->arrayAttribute = $obj;\n        $model->jsonAttribute = ['foo' => 'bar'];\n        $model->jsonAttributeWithUnicode = ['こんにちは' => '世界'];\n        $model->dateAttribute = '1969-07-20';\n        $model->datetimeAttribute = '1969-07-20 22:56:00';\n        $model->timestampAttribute = '1969-07-20 22:56:00';\n        $model->collectionAttribute = new BaseCollection;\n        $model->asCustomCollectionAttribute = new CustomCollection;\n\n        $this->assertIsInt($model->intAttribute);\n        $this->assertIsFloat($model->floatAttribute);\n        $this->assertIsString($model->stringAttribute);\n        $this->assertIsBool($model->boolAttribute);\n        $this->assertIsBool($model->booleanAttribute);\n        $this->assertIsObject($model->objectAttribute);\n        $this->assertIsArray($model->arrayAttribute);\n        $this->assertIsArray($model->jsonAttribute);\n        $this->assertIsArray($model->jsonAttributeWithUnicode);\n        $this->assertTrue($model->boolAttribute);\n        $this->assertFalse($model->booleanAttribute);\n        $this->assertEquals($obj, $model->objectAttribute);\n        $this->assertEquals(['foo' => 'bar'], $model->arrayAttribute);\n        $this->assertEquals(['foo' => 'bar'], $model->jsonAttribute);\n        $this->assertSame('{\"foo\":\"bar\"}', $model->jsonAttributeValue());\n        $this->assertEquals(['こんにちは' => '世界'], $model->jsonAttributeWithUnicode);\n        $this->assertSame('{\"こんにちは\":\"世界\"}', $model->jsonAttributeWithUnicodeValue());\n        $this->assertInstanceOf(Carbon::class, $model->dateAttribute);\n        $this->assertInstanceOf(Carbon::class, $model->datetimeAttribute);\n        $this->assertInstanceOf(BaseCollection::class, $model->collectionAttribute);\n        $this->assertInstanceOf(CustomCollection::class, $model->asCustomCollectionAttribute);\n        $this->assertSame('1969-07-20', $model->dateAttribute->toDateString());\n        $this->assertSame('1969-07-20 22:56:00', $model->datetimeAttribute->toDateTimeString());\n        $this->assertEquals(-14173440, $model->timestampAttribute);\n\n        $arr = $model->toArray();\n\n        $this->assertIsInt($arr['intAttribute']);\n        $this->assertIsFloat($arr['floatAttribute']);\n        $this->assertIsString($arr['stringAttribute']);\n        $this->assertIsBool($arr['boolAttribute']);\n        $this->assertIsBool($arr['booleanAttribute']);\n        $this->assertIsObject($arr['objectAttribute']);\n        $this->assertIsArray($arr['arrayAttribute']);\n        $this->assertIsArray($arr['jsonAttribute']);\n        $this->assertIsArray($arr['jsonAttributeWithUnicode']);\n        $this->assertIsArray($arr['collectionAttribute']);\n        $this->assertTrue($arr['boolAttribute']);\n        $this->assertFalse($arr['booleanAttribute']);\n        $this->assertEquals($obj, $arr['objectAttribute']);\n        $this->assertEquals(['foo' => 'bar'], $arr['arrayAttribute']);\n        $this->assertEquals(['foo' => 'bar'], $arr['jsonAttribute']);\n        $this->assertEquals(['こんにちは' => '世界'], $arr['jsonAttributeWithUnicode']);\n        $this->assertSame('1969-07-20 00:00:00', $arr['dateAttribute']);\n        $this->assertSame('1969-07-20 22:56:00', $arr['datetimeAttribute']);\n        $this->assertEquals(-14173440, $arr['timestampAttribute']);\n    }\n\n    public function testModelDateAttributeCastingResetsTime()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setDateFormat('Y-m-d H:i:s');\n        $model->dateAttribute = '1969-07-20 22:56:00';\n\n        $this->assertSame('1969-07-20 00:00:00', $model->dateAttribute->toDateTimeString());\n\n        $arr = $model->toArray();\n        $this->assertSame('1969-07-20 00:00:00', $arr['dateAttribute']);\n    }\n\n    public function testModelAttributeCastingPreservesNull()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->intAttribute = null;\n        $model->floatAttribute = null;\n        $model->stringAttribute = null;\n        $model->boolAttribute = null;\n        $model->booleanAttribute = null;\n        $model->objectAttribute = null;\n        $model->arrayAttribute = null;\n        $model->jsonAttribute = null;\n        $model->jsonAttributeWithUnicode = null;\n        $model->dateAttribute = null;\n        $model->datetimeAttribute = null;\n        $model->timestampAttribute = null;\n        $model->collectionAttribute = null;\n\n        $attributes = $model->getAttributes();\n\n        $this->assertNull($attributes['intAttribute']);\n        $this->assertNull($attributes['floatAttribute']);\n        $this->assertNull($attributes['stringAttribute']);\n        $this->assertNull($attributes['boolAttribute']);\n        $this->assertNull($attributes['booleanAttribute']);\n        $this->assertNull($attributes['objectAttribute']);\n        $this->assertNull($attributes['arrayAttribute']);\n        $this->assertNull($attributes['jsonAttribute']);\n        $this->assertNull($attributes['jsonAttributeWithUnicode']);\n        $this->assertNull($attributes['dateAttribute']);\n        $this->assertNull($attributes['datetimeAttribute']);\n        $this->assertNull($attributes['timestampAttribute']);\n        $this->assertNull($attributes['collectionAttribute']);\n\n        $this->assertNull($model->intAttribute);\n        $this->assertNull($model->floatAttribute);\n        $this->assertNull($model->stringAttribute);\n        $this->assertNull($model->boolAttribute);\n        $this->assertNull($model->booleanAttribute);\n        $this->assertNull($model->objectAttribute);\n        $this->assertNull($model->arrayAttribute);\n        $this->assertNull($model->jsonAttribute);\n        $this->assertNull($model->jsonAttributeWithUnicode);\n        $this->assertNull($model->dateAttribute);\n        $this->assertNull($model->datetimeAttribute);\n        $this->assertNull($model->timestampAttribute);\n        $this->assertNull($model->collectionAttribute);\n\n        $array = $model->toArray();\n\n        $this->assertNull($array['intAttribute']);\n        $this->assertNull($array['floatAttribute']);\n        $this->assertNull($array['stringAttribute']);\n        $this->assertNull($array['boolAttribute']);\n        $this->assertNull($array['booleanAttribute']);\n        $this->assertNull($array['objectAttribute']);\n        $this->assertNull($array['arrayAttribute']);\n        $this->assertNull($array['jsonAttribute']);\n        $this->assertNull($array['jsonAttributeWithUnicode']);\n        $this->assertNull($array['dateAttribute']);\n        $this->assertNull($array['datetimeAttribute']);\n        $this->assertNull($array['timestampAttribute']);\n        $this->assertNull($attributes['collectionAttribute']);\n    }\n\n    public function testModelAttributeCastingFailsOnUnencodableData()\n    {\n        $this->expectException(JsonEncodingException::class);\n        $this->expectExceptionMessage('Unable to encode attribute [objectAttribute] for model [Illuminate\\Tests\\Database\\EloquentModelCastingStub] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded.');\n\n        $model = new EloquentModelCastingStub;\n        $model->objectAttribute = ['foo' => \"b\\xF8r\"];\n        $obj = new stdClass;\n        $obj->foo = \"b\\xF8r\";\n        $model->arrayAttribute = $obj;\n\n        $model->getAttributes();\n    }\n\n    public function testModelJsonCastingFailsOnUnencodableData()\n    {\n        $this->expectException(JsonEncodingException::class);\n        $this->expectExceptionMessage('Unable to encode attribute [jsonAttribute] for model [Illuminate\\Tests\\Database\\EloquentModelCastingStub] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded.');\n\n        $model = new EloquentModelCastingStub;\n        $model->jsonAttribute = ['foo' => \"b\\xF8r\"];\n\n        $model->getAttributes();\n    }\n\n    public function testModelAttributeCastingFailsOnUnencodableDataWithUnicode()\n    {\n        $this->expectException(JsonEncodingException::class);\n        $this->expectExceptionMessage('Unable to encode attribute [jsonAttributeWithUnicode] for model [Illuminate\\Tests\\Database\\EloquentModelCastingStub] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded.');\n\n        $model = new EloquentModelCastingStub;\n        $model->jsonAttributeWithUnicode = ['foo' => \"b\\xF8r\"];\n\n        $model->getAttributes();\n    }\n\n    public function testJsonCastingRespectsUnicodeOption()\n    {\n        $data = ['こんにちは' => '世界'];\n        $model = new EloquentModelCastingStub;\n        $model->jsonAttribute = $data;\n        $model->jsonAttributeWithUnicode = $data;\n\n        $this->assertSame('{\"\\u3053\\u3093\\u306b\\u3061\\u306f\":\"\\u4e16\\u754c\"}', $model->jsonAttributeValue());\n        $this->assertSame('{\"こんにちは\":\"世界\"}', $model->jsonAttributeWithUnicodeValue());\n        $this->assertSame(['こんにちは' => '世界'], $model->jsonAttribute);\n        $this->assertSame(['こんにちは' => '世界'], $model->jsonAttributeWithUnicode);\n    }\n\n    public function testModelAttributeCastingWithFloats()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $model->floatAttribute = 0;\n        $this->assertSame(0.0, $model->floatAttribute);\n\n        $model->floatAttribute = 'Infinity';\n        $this->assertSame(INF, $model->floatAttribute);\n\n        $model->floatAttribute = INF;\n        $this->assertSame(INF, $model->floatAttribute);\n\n        $model->floatAttribute = '-Infinity';\n        $this->assertSame(-INF, $model->floatAttribute);\n\n        $model->floatAttribute = -INF;\n        $this->assertSame(-INF, $model->floatAttribute);\n\n        $model->floatAttribute = 'NaN';\n        $this->assertNan($model->floatAttribute);\n\n        $model->floatAttribute = NAN;\n        $this->assertNan($model->floatAttribute);\n    }\n\n    public function testModelAttributeCastingWithArrays()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $model->asEnumArrayObjectAttribute = ['draft', 'pending'];\n        $this->assertInstanceOf(ArrayObject::class, $model->asEnumArrayObjectAttribute);\n    }\n\n    public function testMergeCastsMergesCasts()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $castCount = count($model->getCasts());\n        $this->assertArrayNotHasKey('foo', $model->getCasts());\n\n        $model->mergeCasts(['foo' => 'date']);\n        $this->assertCount($castCount + 1, $model->getCasts());\n        $this->assertArrayHasKey('foo', $model->getCasts());\n    }\n\n    public function testMergeCastsMergesCastsUsingArrays()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $castCount = count($model->getCasts());\n        $this->assertArrayNotHasKey('foo', $model->getCasts());\n\n        $model->mergeCasts([\n            'foo' => ['MyClass', 'myArgumentA'],\n            'bar' => ['MyClass', 'myArgumentA', 'myArgumentB'],\n        ]);\n\n        $this->assertCount($castCount + 2, $model->getCasts());\n        $this->assertArrayHasKey('foo', $model->getCasts());\n        $this->assertEquals($model->getCasts()['foo'], 'MyClass:myArgumentA');\n        $this->assertEquals($model->getCasts()['bar'], 'MyClass:myArgumentA,myArgumentB');\n    }\n\n    public function testUnsetCastAttributes()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->asToObjectCast = TestValueObject::make([\n            'myPropertyA' => 'A',\n            'myPropertyB' => 'B',\n        ]);\n        unset($model->asToObjectCast);\n        $this->assertArrayNotHasKey('asToObjectCast', $model->getAttributes());\n    }\n\n    public function testUpdatingNonExistentModelFails()\n    {\n        $model = new EloquentModelStub;\n        $this->assertFalse($model->update());\n    }\n\n    public function testIssetBehavesCorrectlyWithAttributesAndRelationships()\n    {\n        $model = new EloquentModelStub;\n        $this->assertFalse(isset($model->nonexistent));\n\n        $model->some_attribute = 'some_value';\n        $this->assertTrue(isset($model->some_attribute));\n\n        $model->setRelation('some_relation', 'some_value');\n        $this->assertTrue(isset($model->some_relation));\n    }\n\n    public function testNonExistingAttributeWithInternalMethodNameDoesntCallMethod()\n    {\n        $model = m::mock(EloquentModelStub::class.'[delete,getRelationValue]');\n        $model->name = 'Spark';\n        $model->shouldNotReceive('delete');\n        $model->shouldReceive('getRelationValue')->once()->with('belongsToStub')->andReturn('relation');\n\n        // Can return a normal relation\n        $this->assertSame('relation', $model->belongsToStub);\n\n        // Can return a normal attribute\n        $this->assertSame('Spark', $model->name);\n\n        // Returns null for a Model.php method name\n        $this->assertNull($model->delete);\n\n        $model = m::mock(EloquentModelStub::class.'[delete]');\n        $model->delete = 123;\n        $this->assertEquals(123, $model->delete);\n    }\n\n    public function testIntKeyTypePreserved()\n    {\n        $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with([], 'id')->andReturn(1);\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n\n        $this->assertTrue($model->save());\n        $this->assertEquals(1, $model->id);\n    }\n\n    public function testStringKeyTypePreserved()\n    {\n        $model = $this->getMockBuilder(EloquentKeyTypeModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();\n\n        $query = m::mock(Builder::class);\n        $query->shouldReceive('insertGetId')->once()->with([], 'id')->andReturn('string id');\n        $query->shouldReceive('getConnection')->once();\n        $model->expects($this->once())->method('newModelQuery')->willReturn($query);\n\n        $this->assertTrue($model->save());\n        $this->assertSame('string id', $model->id);\n    }\n\n    public function testScopesMethod()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n\n        $scopes = [\n            'published',\n            'category' => 'Laravel',\n            'framework' => ['Laravel', '5.3'],\n            'date' => Carbon::now(),\n        ];\n\n        $this->assertInstanceOf(Builder::class, $model->scopes($scopes));\n        $this->assertSame($scopes, $model->scopesCalled);\n    }\n\n    public function testScopesMethodWithString()\n    {\n        $model = new EloquentModelStub;\n        $this->addMockConnection($model);\n\n        $this->assertInstanceOf(Builder::class, $model->scopes('published'));\n        $this->assertSame(['published'], $model->scopesCalled);\n    }\n\n    public function testIsWithNull()\n    {\n        $firstInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance = null;\n\n        $this->assertFalse($firstInstance->is($secondInstance));\n    }\n\n    public function testIsWithTheSameModelInstance()\n    {\n        $firstInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance = new EloquentModelStub(['id' => 1]);\n        $result = $firstInstance->is($secondInstance);\n        $this->assertTrue($result);\n    }\n\n    public function testIsWithAnotherModelInstance()\n    {\n        $firstInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance = new EloquentModelStub(['id' => 2]);\n        $result = $firstInstance->is($secondInstance);\n        $this->assertFalse($result);\n    }\n\n    public function testIsWithAnotherTable()\n    {\n        $firstInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance->setTable('foo');\n        $result = $firstInstance->is($secondInstance);\n        $this->assertFalse($result);\n    }\n\n    public function testIsWithAnotherConnection()\n    {\n        $firstInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance = new EloquentModelStub(['id' => 1]);\n        $secondInstance->setConnection('foo');\n        $result = $firstInstance->is($secondInstance);\n        $this->assertFalse($result);\n    }\n\n    public function testWithoutTouchingCallback()\n    {\n        new EloquentModelStub(['id' => 1]);\n\n        $called = false;\n\n        EloquentModelStub::withoutTouching(function () use (&$called) {\n            $called = true;\n        });\n\n        $this->assertTrue($called);\n    }\n\n    public function testWithoutTouchingOnCallback()\n    {\n        new EloquentModelStub(['id' => 1]);\n\n        $called = false;\n\n        Model::withoutTouchingOn([EloquentModelStub::class], function () use (&$called) {\n            $called = true;\n        });\n\n        $this->assertTrue($called);\n    }\n\n    public function testThrowsWhenAccessingMissingAttributes()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        try {\n            $model = new EloquentModelStub(['id' => 1]);\n            $model->exists = true;\n\n            $this->assertEquals(1, $model->id);\n            $this->expectException(MissingAttributeException::class);\n\n            $model->this_attribute_does_not_exist;\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testThrowsWhenAccessingMissingAttributesWhichArePrimitiveCasts()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        $model = new EloquentModelWithPrimitiveCasts(['id' => 1]);\n        $model->exists = true;\n\n        $exceptionCount = 0;\n        $primitiveCasts = EloquentModelWithPrimitiveCasts::makePrimitiveCastsArray();\n        try {\n            try {\n                $this->assertEquals(null, $model->backed_enum);\n            } catch (MissingAttributeException) {\n                $exceptionCount++;\n            }\n\n            foreach ($primitiveCasts as $key => $type) {\n                try {\n                    $v = $model->{$key};\n                } catch (MissingAttributeException) {\n                    $exceptionCount++;\n                }\n            }\n\n            $this->assertInstanceOf(Address::class, $model->address);\n\n            $this->assertEquals(1, $model->id);\n            $this->assertEquals('ok', $model->this_is_fine);\n            $this->assertEquals('ok', $model->this_is_also_fine);\n\n            // Primitive castables, enum castable\n            $expectedExceptionCount = count($primitiveCasts) + 1;\n            $this->assertEquals($expectedExceptionCount, $exceptionCount);\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testUsesOverriddenHandlerWhenAccessingMissingAttributes()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        $callbackModel = null;\n        $callbackKey = null;\n\n        Model::handleMissingAttributeViolationUsing(function ($model, $key) use (&$callbackModel, &$callbackKey) {\n            $callbackModel = $model;\n            $callbackKey = $key;\n        });\n\n        $model = new EloquentModelStub(['id' => 1]);\n        $model->exists = true;\n\n        $this->assertEquals(1, $model->id);\n\n        $model->this_attribute_does_not_exist;\n\n        $this->assertInstanceOf(EloquentModelStub::class, $callbackModel);\n        $this->assertEquals('this_attribute_does_not_exist', $callbackKey);\n\n        Model::preventAccessingMissingAttributes($originalMode);\n        Model::handleMissingAttributeViolationUsing(null);\n    }\n\n    public function testDoesntThrowWhenAccessingMissingAttributesOnModelThatIsNotSaved()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        try {\n            $model = new EloquentModelStub(['id' => 1]);\n            $model->exists = false;\n\n            $this->assertEquals(1, $model->id);\n            $this->assertNull($model->this_attribute_does_not_exist);\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testDoesntThrowWhenAccessingMissingAttributesOnModelThatWasRecentlyCreated()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        try {\n            $model = new EloquentModelStub(['id' => 1]);\n            $model->exists = true;\n            $model->wasRecentlyCreated = true;\n\n            $this->assertEquals(1, $model->id);\n            $this->assertNull($model->this_attribute_does_not_exist);\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testDoesntThrowWhenAssigningMissingAttributes()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        try {\n            $model = new EloquentModelStub(['id' => 1]);\n            $model->exists = true;\n\n            $model->this_attribute_does_not_exist = 'now it does';\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testDoesntThrowWhenTestingMissingAttributes()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        try {\n            $model = new EloquentModelStub(['id' => 1]);\n            $model->exists = true;\n\n            $this->assertTrue(isset($model->id));\n            $this->assertFalse(isset($model->this_attribute_does_not_exist));\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    protected function addMockConnection($model)\n    {\n        $model->setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $resolver->shouldReceive('connection')->andReturn($connection = m::mock(Connection::class));\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class));\n        $grammar->shouldReceive('getBitwiseOperators')->andReturn([]);\n        $grammar->shouldReceive('isExpression')->andReturnFalse();\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class));\n        $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) {\n            return new BaseBuilder($connection, $grammar, $processor);\n        });\n    }\n\n    public function testTouchMethodWithMultipleAttributes()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n\n        $model = m::mock(EloquentModelStub::class.'[save]');\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $result = $model->touch(['published_at', 'verified_at']);\n\n        $this->assertTrue($result);\n        $this->assertEquals($now->toDateTimeString(), $model->published_at->toDateTimeString());\n        $this->assertEquals($now->toDateTimeString(), $model->verified_at->toDateTimeString());\n    }\n\n    public function testTouchingModelWithTimestamps()\n    {\n        $this->assertFalse(\n            Model::isIgnoringTouch(Model::class)\n        );\n    }\n\n    public function testNotTouchingModelWithUpdatedAtNull()\n    {\n        $this->assertTrue(\n            Model::isIgnoringTouch(EloquentModelWithUpdatedAtNull::class)\n        );\n    }\n\n    public function testNotTouchingModelWithoutTimestamps()\n    {\n        $this->assertTrue(\n            Model::isIgnoringTouch(EloquentModelWithoutTimestamps::class)\n        );\n    }\n\n    public function testGetOriginalCastsAttributes()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->intAttribute = '1';\n        $model->floatAttribute = '0.1234';\n        $model->stringAttribute = 432;\n        $model->boolAttribute = '1';\n        $model->booleanAttribute = '0';\n        $stdClass = new stdClass;\n        $stdClass->json_key = 'json_value';\n        $model->objectAttribute = $stdClass;\n        $array = [\n            'foo' => 'bar',\n        ];\n        $collection = collect($array);\n        $model->arrayAttribute = $array;\n        $model->jsonAttribute = $array;\n        $model->jsonAttributeWithUnicode = $array;\n        $model->collectionAttribute = $collection;\n\n        $model->syncOriginal();\n\n        $model->intAttribute = 2;\n        $model->floatAttribute = 0.443;\n        $model->stringAttribute = '12';\n        $model->boolAttribute = true;\n        $model->booleanAttribute = false;\n        $model->objectAttribute = $stdClass;\n        $model->arrayAttribute = [\n            'foo' => 'bar2',\n        ];\n        $model->jsonAttribute = [\n            'foo' => 'bar2',\n        ];\n        $model->jsonAttributeWithUnicode = [\n            'foo' => 'bar2',\n        ];\n        $model->collectionAttribute = collect([\n            'foo' => 'bar2',\n        ]);\n\n        $this->assertIsInt($model->getOriginal('intAttribute'));\n        $this->assertEquals(1, $model->getOriginal('intAttribute'));\n        $this->assertEquals(2, $model->intAttribute);\n        $this->assertEquals(2, $model->getAttribute('intAttribute'));\n\n        $this->assertIsFloat($model->getOriginal('floatAttribute'));\n        $this->assertEquals(0.1234, $model->getOriginal('floatAttribute'));\n        $this->assertEquals(0.443, $model->floatAttribute);\n\n        $this->assertIsString($model->getOriginal('stringAttribute'));\n        $this->assertSame('432', $model->getOriginal('stringAttribute'));\n        $this->assertSame('12', $model->stringAttribute);\n\n        $this->assertIsBool($model->getOriginal('boolAttribute'));\n        $this->assertTrue($model->getOriginal('boolAttribute'));\n        $this->assertTrue($model->boolAttribute);\n\n        $this->assertIsBool($model->getOriginal('booleanAttribute'));\n        $this->assertFalse($model->getOriginal('booleanAttribute'));\n        $this->assertFalse($model->booleanAttribute);\n\n        $this->assertEquals($stdClass, $model->getOriginal('objectAttribute'));\n        $this->assertEquals($model->getAttribute('objectAttribute'), $model->getOriginal('objectAttribute'));\n\n        $this->assertEquals($array, $model->getOriginal('arrayAttribute'));\n        $this->assertEquals(['foo' => 'bar'], $model->getOriginal('arrayAttribute'));\n        $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('arrayAttribute'));\n\n        $this->assertEquals($array, $model->getOriginal('jsonAttribute'));\n        $this->assertEquals(['foo' => 'bar'], $model->getOriginal('jsonAttribute'));\n        $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('jsonAttribute'));\n\n        $this->assertEquals($array, $model->getOriginal('jsonAttributeWithUnicode'));\n        $this->assertEquals(['foo' => 'bar'], $model->getOriginal('jsonAttributeWithUnicode'));\n        $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('jsonAttributeWithUnicode'));\n\n        $this->assertEquals(['foo' => 'bar'], $model->getOriginal('collectionAttribute')->toArray());\n        $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('collectionAttribute')->toArray());\n    }\n\n    public function testCastsMethodHasPriorityOverCastsProperty()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'duplicatedAttribute' => '1',\n        ], true);\n\n        $this->assertIsInt($model->duplicatedAttribute);\n        $this->assertEquals(1, $model->duplicatedAttribute);\n        $this->assertEquals(1, $model->getAttribute('duplicatedAttribute'));\n    }\n\n    public function testCastsMethodIsTakenInConsiderationOnSerialization()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'duplicatedAttribute' => '1',\n        ], true);\n\n        $model = unserialize(serialize($model));\n\n        $this->assertIsInt($model->duplicatedAttribute);\n        $this->assertEquals(1, $model->duplicatedAttribute);\n        $this->assertEquals(1, $model->getAttribute('duplicatedAttribute'));\n    }\n\n    public function testCastOnArrayFormatWithOneElement()\n    {\n        $model = new EloquentModelCastingStub;\n        $model->setRawAttributes([\n            'singleElementInArrayAttribute' => '{\"bar\": \"foo\"}',\n        ]);\n        $model->syncOriginal();\n\n        $this->assertInstanceOf(BaseCollection::class, $model->singleElementInArrayAttribute);\n        $this->assertEquals(['bar' => 'foo'], $model->singleElementInArrayAttribute->toArray());\n        $this->assertEquals(['bar' => 'foo'], $model->getAttribute('singleElementInArrayAttribute')->toArray());\n    }\n\n    public function testUsingStringableObjectCastUsesStringRepresentation()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $this->assertEquals('int', $model->getCasts()['castStringableObject']);\n    }\n\n    public function testMergeingStringableObjectCastUSesStringRepresentation()\n    {\n        $stringable = new StringableCastBuilder();\n        $stringable->cast = 'test';\n\n        $model = (new EloquentModelCastingStub)->mergeCasts([\n            'something' => $stringable,\n        ]);\n\n        $this->assertEquals('test', $model->getCasts()['something']);\n    }\n\n    public function testUsingPlainObjectAsCastThrowsException()\n    {\n        $model = new EloquentModelCastingStub;\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The cast object for the something attribute must implement Stringable.');\n\n        $model->mergeCasts([\n            'something' => (object) [],\n        ]);\n    }\n\n    public function testUnsavedModel()\n    {\n        $user = new UnsavedModel;\n        $user->name = null;\n\n        $this->assertNull($user->name);\n    }\n\n    public function testDiscardChanges()\n    {\n        $user = new EloquentModelStub([\n            'name' => 'Taylor Otwell',\n        ]);\n\n        $this->assertNotEmpty($user->isDirty());\n        $this->assertNull($user->getOriginal('name'));\n        $this->assertSame('Taylor Otwell', $user->getAttribute('name'));\n\n        $user->discardChanges();\n\n        $this->assertEmpty($user->isDirty());\n        $this->assertNull($user->getOriginal('name'));\n        $this->assertNull($user->getAttribute('name'));\n    }\n\n    public function testDiscardChangesWithCasts()\n    {\n        $model = new EloquentModelWithPrimitiveCasts();\n\n        $model->address_line_one = '123 Main Street';\n\n        $this->assertEquals('123 Main Street', $model->address->lineOne);\n        $this->assertEquals('123 MAIN STREET', $model->address_in_caps);\n\n        $model->discardChanges();\n\n        $this->assertNull($model->address->lineOne);\n        $this->assertNull($model->address_in_caps);\n    }\n\n    public function testHasAttribute()\n    {\n        $user = new EloquentModelStub([\n            'name' => 'Mateus',\n        ]);\n\n        $this->assertTrue($user->hasAttribute('name'));\n        $this->assertTrue($user->hasAttribute('password'));\n        $this->assertTrue($user->hasAttribute('castedFloat'));\n        $this->assertFalse($user->hasAttribute('nonexistent'));\n        $this->assertFalse($user->hasAttribute('belongsToStub'));\n    }\n\n    public function testModelToJsonSucceedsWithPriorErrors(): void\n    {\n        $user = new EloquentModelStub(['name' => 'Mateus']);\n\n        // Simulate a JSON error\n        json_decode('{');\n        $this->assertTrue(json_last_error() !== JSON_ERROR_NONE);\n\n        $this->assertSame('{\"name\":\"Mateus\"}', $user->toJson(JSON_THROW_ON_ERROR));\n    }\n\n    public function testModelToPrettyJson(): void\n    {\n        $user = new EloquentModelStub(['name' => 'Mateus', 'active' => true, 'number' => '123']);\n        $results = $user->toPrettyJson();\n        $expected = $user->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n\n        $results = $user->toPrettyJson(JSON_NUMERIC_CHECK);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('\"number\": 123', $results);\n    }\n\n    public function testFillableWithMutators()\n    {\n        $model = new EloquentModelWithMutators;\n        $model->fillable(['full_name', 'full_address']);\n        $model->fill(['id' => 1, 'full_name' => 'John Doe', 'full_address' => '123 Main Street, Anytown']);\n\n        $this->assertNull($model->id);\n        $this->assertSame('John', $model->first_name);\n        $this->assertSame('Doe', $model->last_name);\n        $this->assertSame('123 Main Street', $model->address_line_one);\n        $this->assertSame('Anytown', $model->address_line_two);\n    }\n\n    public function testGuardedWithMutators()\n    {\n        $model = new EloquentModelWithMutators;\n        $model->guard(['id']);\n        $model->fill(['id' => 1, 'full_name' => 'John Doe', 'full_address' => '123 Main Street, Anytown']);\n\n        $this->assertNull($model->id);\n        $this->assertSame('John', $model->first_name);\n        $this->assertSame('Doe', $model->last_name);\n        $this->assertSame('123 Main Street', $model->address_line_one);\n        $this->assertSame('Anytown', $model->address_line_two);\n    }\n\n    public function testCollectedByAttribute()\n    {\n        $model = new EloquentModelWithCollectedByAttribute;\n        $collection = $model->newCollection([$model]);\n\n        $this->assertInstanceOf(CustomEloquentCollection::class, $collection);\n    }\n\n    public function testUseFactoryAttribute()\n    {\n        $model = new EloquentModelWithUseFactoryAttribute;\n        $instance = EloquentModelWithUseFactoryAttribute::factory()->make(['name' => 'test name']);\n        $factory = EloquentModelWithUseFactoryAttribute::factory();\n        $this->assertInstanceOf(EloquentModelWithUseFactoryAttribute::class, $instance);\n        $this->assertInstanceOf(EloquentModelWithUseFactoryAttributeFactory::class, $model::factory());\n        $this->assertInstanceOf(EloquentModelWithUseFactoryAttributeFactory::class, $model::newFactory());\n        $this->assertEquals(EloquentModelWithUseFactoryAttribute::class, $factory->modelName());\n        $this->assertEquals('test name', $instance->name); // Small smoke test to ensure the factory is working\n    }\n\n    public function testNestedModelBootingIsDisallowed()\n    {\n        $this->expectExceptionMessageMatches('/The \\[(.+)] method may not be called on model \\[(.+)\\] while it is being booted\\./');\n\n        $model = new class extends Model\n        {\n            protected static function boot()\n            {\n                parent::boot();\n\n                $tableName = (new static())->getTable();\n            }\n        };\n    }\n\n    public function testUseCustomBuilderWithUseEloquentBuilderAttribute()\n    {\n        $model = new EloquentModelWithUseEloquentBuilderAttributeStub();\n\n        $query = $this->createMock(\\Illuminate\\Database\\Query\\Builder::class);\n        $eloquentBuilder = $model->newEloquentBuilder($query);\n\n        $this->assertInstanceOf(CustomBuilder::class, $eloquentBuilder);\n    }\n\n    public function testDefaultBuilderIsUsedWhenUseEloquentBuilderAttributeIsNotPresent()\n    {\n        $model = new EloquentModelWithoutUseEloquentBuilderAttributeStub();\n\n        $query = $this->createMock(\\Illuminate\\Database\\Query\\Builder::class);\n        $eloquentBuilder = $model->newEloquentBuilder($query);\n\n        $this->assertNotInstanceOf(CustomBuilder::class, $eloquentBuilder);\n    }\n}\n\nclass CustomBuilder extends Builder\n{\n}\n\n#[\\Illuminate\\Database\\Eloquent\\Attributes\\UseEloquentBuilder(CustomBuilder::class)]\nclass EloquentModelWithUseEloquentBuilderAttributeStub extends Model\n{\n}\n\nclass EloquentModelWithoutUseEloquentBuilderAttributeStub extends Model\n{\n}\n\nclass EloquentTestObserverStub\n{\n    public function creating()\n    {\n        //\n    }\n\n    public function saved()\n    {\n        //\n    }\n}\n\nclass EloquentTestAnotherObserverStub\n{\n    public function creating()\n    {\n        //\n    }\n\n    public function saved()\n    {\n        //\n    }\n}\n\nclass EloquentTestThirdObserverStub\n{\n    public function creating()\n    {\n        //\n    }\n\n    public function saved()\n    {\n        //\n    }\n}\n\nclass EloquentModelStub extends Model\n{\n    public $connection;\n    public $scopesCalled = [];\n    protected $table = 'stub';\n    protected $guarded = [];\n    protected $casts = ['castedFloat' => 'float'];\n\n    public function getListItemsAttribute($value)\n    {\n        return json_decode($value, true);\n    }\n\n    public function setListItemsAttribute($value)\n    {\n        $this->attributes['list_items'] = json_encode($value);\n    }\n\n    public function getPasswordAttribute()\n    {\n        return '******';\n    }\n\n    public function setPasswordAttribute($value)\n    {\n        $this->attributes['password_hash'] = sha1($value);\n    }\n\n    public function publicIncrement($column, $amount = 1, $extra = [])\n    {\n        return $this->increment($column, $amount, $extra);\n    }\n\n    public function publicIncrementQuietly($column, $amount = 1, $extra = [])\n    {\n        return $this->incrementQuietly($column, $amount, $extra);\n    }\n\n    public function publicDecrementQuietly($column, $amount = 1, $extra = [])\n    {\n        return $this->decrementQuietly($column, $amount, $extra);\n    }\n\n    public function belongsToStub()\n    {\n        return $this->belongsTo(EloquentModelSaveStub::class);\n    }\n\n    public function morphToStub()\n    {\n        return $this->morphTo();\n    }\n\n    public function morphToStubWithKeys()\n    {\n        return $this->morphTo(null, 'type', 'id');\n    }\n\n    public function morphToStubWithName()\n    {\n        return $this->morphTo('someName');\n    }\n\n    public function morphToStubWithNameAndKeys()\n    {\n        return $this->morphTo('someName', 'type', 'id');\n    }\n\n    public function belongsToExplicitKeyStub()\n    {\n        return $this->belongsTo(EloquentModelSaveStub::class, 'foo');\n    }\n\n    public function incorrectRelationStub()\n    {\n        return 'foo';\n    }\n\n    public function getDates()\n    {\n        return [];\n    }\n\n    public function getAppendableAttribute()\n    {\n        return 'appended';\n    }\n\n    public function scopePublished(Builder $builder)\n    {\n        $this->scopesCalled[] = 'published';\n    }\n\n    public function scopeCategory(Builder $builder, $category)\n    {\n        $this->scopesCalled['category'] = $category;\n    }\n\n    public function scopeFramework(Builder $builder, $framework, $version)\n    {\n        $this->scopesCalled['framework'] = [$framework, $version];\n    }\n\n    public function scopeDate(Builder $builder, Carbon $date)\n    {\n        $this->scopesCalled['date'] = $date;\n    }\n}\n\ntrait FooBarTrait\n{\n    public $fooBarIsInitialized = false;\n\n    public function initializeFooBarTrait()\n    {\n        $this->fooBarIsInitialized = true;\n    }\n}\n\nclass EloquentModelStubWithTrait extends EloquentModelStub\n{\n    use FooBarTrait;\n}\n\nclass EloquentModelCamelStub extends EloquentModelStub\n{\n    public static $snakeAttributes = false;\n}\n\nclass EloquentDateModelStub extends EloquentModelStub\n{\n    public function getDates()\n    {\n        return ['created_at', 'updated_at'];\n    }\n}\n\nclass EloquentModelSaveStub extends Model\n{\n    protected $table = 'save_stub';\n    protected $guarded = [];\n\n    public function save(array $options = [])\n    {\n        if ($this->fireModelEvent('saving') === false) {\n            return false;\n        }\n\n        $_SERVER['__eloquent.saved'] = true;\n\n        $this->fireModelEvent('saved', false);\n    }\n\n    public function setIncrementing($value)\n    {\n        $this->incrementing = $value;\n    }\n\n    public function getConnection()\n    {\n        $mock = m::mock(Connection::class);\n        $mock->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class));\n        $grammar->shouldReceive('getBitwiseOperators')->andReturn([]);\n        $grammar->shouldReceive('isExpression')->andReturnFalse();\n        $mock->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class));\n        $mock->shouldReceive('getName')->andReturn('name');\n        $mock->shouldReceive('query')->andReturnUsing(function () use ($mock, $grammar, $processor) {\n            return new BaseBuilder($mock, $grammar, $processor);\n        });\n\n        return $mock;\n    }\n}\n\nclass EloquentKeyTypeModelStub extends EloquentModelStub\n{\n    protected $keyType = 'string';\n}\n\nclass EloquentModelFindWithWritePdoStub extends Model\n{\n    public function newQuery()\n    {\n        $mock = m::mock(Builder::class);\n        $mock->shouldReceive('useWritePdo')->once()->andReturnSelf();\n        $mock->shouldReceive('find')->once()->with(1)->andReturn('foo');\n\n        return $mock;\n    }\n}\n\nclass EloquentModelDestroyStub extends Model\n{\n    protected $fillable = [\n        'id',\n    ];\n\n    public function newQuery()\n    {\n        $mock = m::mock(Builder::class);\n        $mock->shouldReceive('whereIn')->once()->with('id', [1, 2, 3])->andReturn($mock);\n        $mock->shouldReceive('get')->once()->andReturn([$model = m::mock(stdClass::class)]);\n        $model->shouldReceive('delete')->once();\n\n        return $mock;\n    }\n}\n\nclass EloquentModelEmptyDestroyStub extends Model\n{\n    public function newQuery()\n    {\n        $mock = m::mock(Builder::class);\n        $mock->shouldReceive('whereIn')->never();\n\n        return $mock;\n    }\n}\n\nclass EloquentModelWithStub extends Model\n{\n    public function newQuery()\n    {\n        $mock = m::mock(Builder::class);\n        $mock->shouldReceive('with')->once()->with(['foo', 'bar'])->andReturn('foo');\n\n        return $mock;\n    }\n}\n\nclass EloquentModelWithWhereHasStub extends Model\n{\n    public function foo()\n    {\n        return $this->hasMany(EloquentModelStub::class);\n    }\n}\n\nclass EloquentModelWithoutRelationStub extends Model\n{\n    public $with = ['foo'];\n\n    protected $guarded = [];\n\n    public function getEagerLoads()\n    {\n        return $this->eagerLoads;\n    }\n}\n\nclass EloquentModelWithoutTableStub extends Model\n{\n    //\n}\n\nclass EloquentModelBootingTestStub extends Model\n{\n    public static function unboot()\n    {\n        unset(static::$booted[static::class]);\n        unset(static::$bootedCallbacks[static::class]);\n    }\n\n    public static function isBooted()\n    {\n        return array_key_exists(static::class, static::$booted);\n    }\n}\n\nclass EloquentModelAppendsStub extends Model\n{\n    protected $appends = ['is_admin', 'camelCased', 'StudlyCased'];\n\n    public function getIsAdminAttribute()\n    {\n        return 'admin';\n    }\n\n    public function getCamelCasedAttribute()\n    {\n        return 'camelCased';\n    }\n\n    public function getStudlyCasedAttribute()\n    {\n        return 'StudlyCased';\n    }\n}\n\nclass EloquentModelGetMutatorsStub extends Model\n{\n    public static function resetMutatorCache()\n    {\n        static::$mutatorCache = [];\n    }\n\n    public function getFirstNameAttribute()\n    {\n        //\n    }\n\n    public function getMiddleNameAttribute()\n    {\n        //\n    }\n\n    public function getLastNameAttribute()\n    {\n        //\n    }\n\n    public function doNotgetFirstInvalidAttribute()\n    {\n        //\n    }\n\n    public function doNotGetSecondInvalidAttribute()\n    {\n        //\n    }\n\n    public function doNotgetThirdInvalidAttributeEither()\n    {\n        //\n    }\n\n    public function doNotGetFourthInvalidAttributeEither()\n    {\n        //\n    }\n}\n\nclass EloquentModelCastingStub extends Model\n{\n    protected $casts = [\n        'floatAttribute' => 'float',\n        'boolAttribute' => 'bool',\n        'objectAttribute' => 'object',\n        'jsonAttribute' => 'json',\n        'jsonAttributeWithUnicode' => 'json:unicode',\n        'dateAttribute' => 'date',\n        'timestampAttribute' => 'timestamp',\n        'ascollectionAttribute' => AsCollection::class,\n        'asCustomCollectionAsArrayAttribute' => [AsCollection::class, CustomCollection::class],\n        'asEncryptedCollectionAttribute' => AsEncryptedCollection::class,\n        'asEnumCollectionAttribute' => AsEnumCollection::class.':'.StringStatus::class,\n        'asEnumArrayObjectAttribute' => AsEnumArrayObject::class.':'.StringStatus::class,\n        'duplicatedAttribute' => 'string',\n    ];\n\n    protected function casts(): array\n    {\n        return [\n            'intAttribute' => 'int',\n            'stringAttribute' => 'string',\n            'booleanAttribute' => 'boolean',\n            'arrayAttribute' => 'array',\n            'collectionAttribute' => 'collection',\n            'datetimeAttribute' => 'datetime',\n            'asarrayobjectAttribute' => AsArrayObject::class,\n            'asStringableAttribute' => AsStringable::class,\n            'asHtmlStringAttribute' => AsHtmlString::class,\n            'asUriAttribute' => AsUri::class,\n            'asFluentAttribute' => AsFluent::class,\n            'asCustomCollectionAttribute' => AsCollection::using(CustomCollection::class),\n            'asEncryptedArrayObjectAttribute' => AsEncryptedArrayObject::class,\n            'asEncryptedCustomCollectionAttribute' => AsEncryptedCollection::using(CustomCollection::class),\n            'asEncryptedCustomCollectionAsArrayAttribute' => [AsEncryptedCollection::class, CustomCollection::class],\n            'asCustomEnumCollectionAttribute' => AsEnumCollection::of(StringStatus::class),\n            'asCustomEnumArrayObjectAttribute' => AsEnumArrayObject::of(StringStatus::class),\n            'singleElementInArrayAttribute' => [AsCollection::class],\n            'duplicatedAttribute' => 'int',\n            'asToObjectCast' => TestCast::class,\n            'castStringableObject' => new StringableCastBuilder(),\n        ];\n    }\n\n    public function jsonAttributeValue()\n    {\n        return $this->attributes['jsonAttribute'];\n    }\n\n    public function jsonAttributeWithUnicodeValue()\n    {\n        return $this->attributes['jsonAttributeWithUnicode'];\n    }\n\n    protected function serializeDate(DateTimeInterface $date)\n    {\n        return $date->format('Y-m-d H:i:s');\n    }\n}\n\nclass EloquentModelEnumCastingStub extends Model\n{\n    protected $casts = ['enumAttribute' => StringStatus::class];\n}\n\nclass EloquentModelDynamicHiddenStub extends Model\n{\n    protected $table = 'stub';\n    protected $guarded = [];\n\n    public function getHidden()\n    {\n        return ['age', 'id'];\n    }\n}\n\nclass EloquentModelVisibleStub extends Model\n{\n    protected $table = 'stub';\n    protected $visible = ['foo'];\n}\n\nclass EloquentModelHiddenStub extends Model\n{\n    protected $table = 'stub';\n    protected $hidden = ['foo'];\n}\n\nclass EloquentModelDynamicVisibleStub extends Model\n{\n    protected $table = 'stub';\n    protected $guarded = [];\n\n    public function getVisible()\n    {\n        return ['name', 'id'];\n    }\n}\n\nclass EloquentModelNonIncrementingStub extends Model\n{\n    protected $table = 'stub';\n    protected $guarded = [];\n    public $incrementing = false;\n}\n\nclass EloquentNoConnectionModelStub extends EloquentModelStub\n{\n    //\n}\n\nclass EloquentDifferentConnectionModelStub extends EloquentModelStub\n{\n    public $connection = 'different_connection';\n}\n\nclass EloquentPrimaryUuidModelStub extends EloquentModelStub\n{\n    use HasUuids;\n\n    public $incrementing = false;\n    protected $keyType = 'string';\n\n    public function getKeyName()\n    {\n        return 'uuid';\n    }\n}\n\nclass EloquentNonPrimaryUuidModelStub extends EloquentModelStub\n{\n    use HasUuids;\n\n    public function getKeyName()\n    {\n        return 'id';\n    }\n\n    public function uniqueIds()\n    {\n        return ['uuid'];\n    }\n}\n\nclass EloquentPrimaryUlidModelStub extends EloquentModelStub\n{\n    use HasUlids;\n\n    public $incrementing = false;\n    protected $keyType = 'string';\n\n    public function getKeyName()\n    {\n        return 'ulid';\n    }\n}\n\nclass EloquentNonPrimaryUlidModelStub extends EloquentModelStub\n{\n    use HasUlids;\n\n    public function getKeyName()\n    {\n        return 'id';\n    }\n\n    public function uniqueIds()\n    {\n        return ['ulid'];\n    }\n}\n\n#[ObservedBy(EloquentTestObserverStub::class)]\nclass EloquentModelWithObserveAttributeStub extends EloquentModelStub\n{\n    //\n}\n\n#[ObservedBy([EloquentTestObserverStub::class])]\nclass EloquentModelWithObserveAttributeUsingArrayStub extends EloquentModelStub\n{\n    //\n}\n\n#[ObservedBy([EloquentTestObserverStub::class])]\nclass EloquentModelWithObserveAttributeGrandparentStub extends EloquentModelStub\n{\n    //\n}\n\n#[ObservedBy([EloquentTestAnotherObserverStub::class])]\nclass EloquentModelWithObserveAttributeParentStub extends EloquentModelWithObserveAttributeGrandparentStub\n{\n    //\n}\n\n#[ObservedBy([EloquentTestThirdObserverStub::class])]\nclass EloquentModelWithObserveAttributeGrandchildStub extends EloquentModelWithObserveAttributeParentStub\n{\n    //\n}\n\nclass EloquentModelSavingEventStub\n{\n    //\n}\n\nclass EloquentModelEventObjectStub extends Model\n{\n    protected $dispatchesEvents = [\n        'saving' => EloquentModelSavingEventStub::class,\n    ];\n}\n\nclass EloquentModelWithoutTimestamps extends Model\n{\n    protected $table = 'stub';\n    public $timestamps = false;\n}\n\nclass EloquentModelWithUpdatedAtNull extends Model\n{\n    protected $table = 'stub';\n    const UPDATED_AT = null;\n}\n\nclass UnsavedModel extends Model\n{\n    protected $casts = ['name' => Uppercase::class];\n}\n\nclass Uppercase implements CastsInboundAttributes\n{\n    public function set($model, string $key, $value, array $attributes)\n    {\n        return is_string($value) ? strtoupper($value) : $value;\n    }\n}\n\nclass CustomCollection extends BaseCollection\n{\n    //\n}\n\nclass EloquentModelWithPrimitiveCasts extends Model\n{\n    public $fillable = ['id'];\n\n    public $casts = [\n        'backed_enum' => CastableBackedEnum::class,\n        'address' => Address::class,\n    ];\n\n    public $attributes = [\n        'address_line_one' => null,\n        'address_line_two' => null,\n    ];\n\n    public static function makePrimitiveCastsArray(): array\n    {\n        $toReturn = [];\n\n        foreach (static::$primitiveCastTypes as $index => $primitiveCastType) {\n            $toReturn['primitive_cast_'.$index] = $primitiveCastType;\n        }\n\n        return $toReturn;\n    }\n\n    public function __construct(array $attributes = [])\n    {\n        parent::__construct($attributes);\n\n        $this->mergeCasts(self::makePrimitiveCastsArray());\n    }\n\n    public function getThisIsFineAttribute($value)\n    {\n        return 'ok';\n    }\n\n    public function thisIsAlsoFine(): Attribute\n    {\n        return Attribute::get(fn () => 'ok');\n    }\n\n    public function addressInCaps(): Attribute\n    {\n        return Attribute::get(\n            function () {\n                $value = $this->getAttributes()['address_line_one'] ?? null;\n\n                return is_string($value) ? strtoupper($value) : $value;\n            }\n        )->shouldCache();\n    }\n}\n\nenum CastableBackedEnum: string\n{\n    case Value1 = 'value1';\n}\n\nclass Address implements Castable\n{\n    public function __construct(\n        public ?string $lineOne = null,\n        public ?string $lineTwo = null\n    ) {\n    }\n\n    public static function castUsing(array $arguments): CastsAttributes\n    {\n        return new class implements CastsAttributes\n        {\n            public function get(Model $model, string $key, mixed $value, array $attributes): Address\n            {\n                return new Address(\n                    $attributes['address_line_one'],\n                    $attributes['address_line_two']\n                );\n            }\n\n            public function set(Model $model, string $key, mixed $value, array $attributes): array\n            {\n                return [\n                    'address_line_one' => $value->lineOne ?? null,\n                    'address_line_two' => $value->lineTwo ?? null,\n                ];\n            }\n        };\n    }\n}\n\nclass EloquentModelWithRecursiveRelationshipsStub extends Model\n{\n    public $fillable = ['id', 'parent_id'];\n\n    protected static \\WeakMap $recursionDetectionCache;\n\n    public function getQueueableRelations()\n    {\n        try {\n            $this->stepIn();\n\n            return parent::getQueueableRelations();\n        } finally {\n            $this->stepOut();\n        }\n    }\n\n    public function push()\n    {\n        try {\n            $this->stepIn();\n\n            return parent::push();\n        } finally {\n            $this->stepOut();\n        }\n    }\n\n    public function save(array $options = [])\n    {\n        return true;\n    }\n\n    public function relationsToArray()\n    {\n        try {\n            $this->stepIn();\n\n            return parent::relationsToArray();\n        } finally {\n            $this->stepOut();\n        }\n    }\n\n    public function parent(): BelongsTo\n    {\n        return $this->belongsTo(static::class, 'parent_id');\n    }\n\n    public function children(): HasMany\n    {\n        return $this->hasMany(static::class, 'parent_id');\n    }\n\n    public function self(): BelongsTo\n    {\n        return $this->belongsTo(static::class, 'id');\n    }\n\n    protected static function getRecursionDetectionCache()\n    {\n        return static::$recursionDetectionCache ??= new \\WeakMap;\n    }\n\n    protected function getRecursionDepth(): int\n    {\n        $cache = static::getRecursionDetectionCache();\n\n        return $cache->offsetExists($this) ? $cache->offsetGet($this) : 0;\n    }\n\n    protected function stepIn(): void\n    {\n        $depth = $this->getRecursionDepth();\n\n        if ($depth > 1) {\n            throw new \\RuntimeException('Recursion detected');\n        }\n        static::getRecursionDetectionCache()->offsetSet($this, $depth + 1);\n    }\n\n    protected function stepOut(): void\n    {\n        $cache = static::getRecursionDetectionCache();\n        if ($depth = $this->getRecursionDepth()) {\n            $cache->offsetSet($this, $depth - 1);\n        } else {\n            $cache->offsetUnset($this);\n        }\n    }\n}\n\nclass EloquentModelWithMutators extends Model\n{\n    public $attributes = [\n        'first_name' => null,\n        'last_name' => null,\n        'address_line_one' => null,\n        'address_line_two' => null,\n    ];\n\n    protected function fullName(): Attribute\n    {\n        return Attribute::make(\n            set: function (string $fullName) {\n                [$firstName, $lastName] = explode(' ', $fullName);\n\n                return [\n                    'first_name' => $firstName,\n                    'last_name' => $lastName,\n                ];\n            }\n        );\n    }\n\n    public function setFullAddressAttribute($fullAddress)\n    {\n        [$addressLineOne, $addressLineTwo] = explode(', ', $fullAddress);\n\n        $this->attributes['address_line_one'] = $addressLineOne;\n        $this->attributes['address_line_two'] = $addressLineTwo;\n    }\n}\n\n#[CollectedBy(CustomEloquentCollection::class)]\nclass EloquentModelWithCollectedByAttribute extends Model\n{\n}\n\nclass CustomEloquentCollection extends Collection\n{\n}\n\nclass EloquentModelWithUseFactoryAttributeFactory extends Factory\n{\n    public function definition()\n    {\n        return [];\n    }\n}\n\n#[UseFactory(EloquentModelWithUseFactoryAttributeFactory::class)]\nclass EloquentModelWithUseFactoryAttribute extends Model\n{\n    use HasFactory;\n}\n\ntrait EloquentTraitBootingCallbackTestStub\n{\n    public static function bootEloquentTraitBootingCallbackTestStub()\n    {\n        static::whenBooted(fn () => static::$bootHasFinished = true);\n    }\n}\n\nclass EloquentModelBootingCallbackTestStub extends Model\n{\n    use EloquentTraitBootingCallbackTestStub;\n\n    public static bool $bootHasFinished = false;\n\n    public static function unboot()\n    {\n        unset(static::$booted[static::class]);\n        unset(static::$bootedCallbacks[static::class]);\n        static::$bootHasFinished = false;\n    }\n}\n\nclass EloquentChildModelBootingCallbackTestStub extends EloquentModelBootingCallbackTestStub\n{\n    public static bool $bootHasFinished = false;\n}\n\nclass StringableCastBuilder implements NativeStringable\n{\n    public $cast = 'int';\n\n    public function __toString()\n    {\n        return $this->cast;\n    }\n}\n\nenum ConnectionName\n{\n    case Foo;\n    case Bar;\n}\n\nenum ConnectionNameBacked: string\n{\n    case Foo = 'Foo';\n    case Bar = 'Bar';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentMorphOneOfManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentMorphOneOfManyTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('products', function ($table) {\n            $table->increments('id');\n        });\n\n        $this->schema()->create('states', function ($table) {\n            $table->increments('id');\n            $table->morphs('stateful');\n            $table->string('state');\n            $table->string('type')->nullable();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('products');\n        $this->schema()->drop('states');\n\n        parent::tearDown();\n    }\n\n    public function testEagerLoadingAppliesConstraintsToInnerJoinSubQuery()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $relation = $product->current_state();\n        $relation->addEagerConstraints([$product]);\n        $this->assertSame('select MAX(\"states\".\"id\") as \"id_aggregate\", \"states\".\"stateful_id\", \"states\".\"stateful_type\" from \"states\" where \"states\".\"stateful_type\" = ? and \"states\".\"stateful_id\" = ? and \"states\".\"stateful_id\" is not null and \"states\".\"stateful_id\" in (1) and \"states\".\"stateful_type\" = ? group by \"states\".\"stateful_id\", \"states\".\"stateful_type\"', $relation->getOneOfManySubQuery()->toSql());\n    }\n\n    public function testReceivingModel()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $product->states()->create([\n            'state' => 'draft',\n        ]);\n        $product->states()->create([\n            'state' => 'active',\n        ]);\n\n        $this->assertNotNull($product->current_state);\n        $this->assertSame('active', $product->current_state->state);\n    }\n\n    public function testMorphType()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $product->states()->create([\n            'state' => 'draft',\n        ]);\n        $product->states()->create([\n            'state' => 'active',\n        ]);\n        $state = $product->states()->make([\n            'state' => 'foo',\n        ]);\n        $state->stateful_type = 'bar';\n        $state->save();\n\n        $this->assertNotNull($product->current_state);\n        $this->assertSame('active', $product->current_state->state);\n    }\n\n    public function testForceCreateMorphType()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $state = $product->states()->forceCreate([\n            'state' => 'active',\n        ]);\n\n        $this->assertNotNull($state);\n        $this->assertSame(MorphOneOfManyTestProduct::class, $product->current_state->stateful_type);\n    }\n\n    public function testExists()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $previousState = $product->states()->create([\n            'state' => 'draft',\n        ]);\n        $currentState = $product->states()->create([\n            'state' => 'active',\n        ]);\n\n        $exists = MorphOneOfManyTestProduct::whereHas('current_state', function ($q) use ($previousState) {\n            $q->whereKey($previousState->getKey());\n        })->exists();\n        $this->assertFalse($exists);\n\n        $exists = MorphOneOfManyTestProduct::whereHas('current_state', function ($q) use ($currentState) {\n            $q->whereKey($currentState->getKey());\n        })->exists();\n        $this->assertTrue($exists);\n    }\n\n    public function testWithWhereHas()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $previousState = $product->states()->create([\n            'state' => 'draft',\n        ]);\n        $currentState = $product->states()->create([\n            'state' => 'active',\n        ]);\n\n        $exists = MorphOneOfManyTestProduct::withWhereHas('current_state', function ($q) use ($previousState) {\n            $q->whereKey($previousState->getKey());\n        })->exists();\n        $this->assertFalse($exists);\n\n        $exists = MorphOneOfManyTestProduct::withWhereHas('current_state', function ($q) use ($currentState) {\n            $q->whereKey($currentState->getKey());\n        })->get();\n\n        $this->assertCount(1, $exists);\n        $this->assertTrue($exists->first()->relationLoaded('current_state'));\n        $this->assertSame($exists->first()->current_state->state, $currentState->state);\n    }\n\n    public function testWithWhereRelation()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n        $currentState = $product->states()->create([\n            'state' => 'active',\n        ]);\n\n        $exists = MorphOneOfManyTestProduct::withWhereRelation('current_state', 'state', 'active')->exists();\n        $this->assertTrue($exists);\n\n        $exists = MorphOneOfManyTestProduct::withWhereRelation('current_state', 'state', 'active')->get();\n\n        $this->assertCount(1, $exists);\n        $this->assertTrue($exists->first()->relationLoaded('current_state'));\n        $this->assertSame($exists->first()->current_state->state, $currentState->state);\n    }\n\n    public function testWithExists()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n\n        $product = MorphOneOfManyTestProduct::withExists('current_state')->first();\n        $this->assertFalse($product->current_state_exists);\n\n        $product->states()->create([\n            'state' => 'draft',\n        ]);\n        $product = MorphOneOfManyTestProduct::withExists('current_state')->first();\n        $this->assertTrue($product->current_state_exists);\n    }\n\n    public function testWithExistsWithConstraintsInJoinSubSelect()\n    {\n        $product = MorphOneOfManyTestProduct::create();\n\n        $product = MorphOneOfManyTestProduct::withExists('current_foo_state')->first();\n        $this->assertFalse($product->current_foo_state_exists);\n\n        $product->states()->create([\n            'state' => 'draft',\n            'type' => 'foo',\n        ]);\n        $product = MorphOneOfManyTestProduct::withExists('current_foo_state')->first();\n        $this->assertTrue($product->current_foo_state_exists);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass MorphOneOfManyTestProduct extends Eloquent\n{\n    protected $table = 'products';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function states()\n    {\n        return $this->morphMany(MorphOneOfManyTestState::class, 'stateful');\n    }\n\n    public function current_state()\n    {\n        return $this->morphOne(MorphOneOfManyTestState::class, 'stateful')->ofMany();\n    }\n\n    public function current_foo_state()\n    {\n        return $this->morphOne(MorphOneOfManyTestState::class, 'stateful')->ofMany(\n            ['id' => 'max'],\n            function ($q) {\n                $q->where('type', 'foo');\n            }\n        );\n    }\n}\n\nclass MorphOneOfManyTestState extends Eloquent\n{\n    protected $table = 'states';\n    protected $guarded = [];\n    public $timestamps = false;\n    protected $fillable = ['state', 'type'];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentMorphTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Foo\\Bar\\EloquentModelNamespacedStub;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentMorphTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Relation::morphMap([], false);\n\n        parent::tearDown();\n    }\n\n    public function testMorphOneSetsProperConstraints()\n    {\n        $this->getOneRelation();\n    }\n\n    public function testMorphOneEagerConstraintsAreProperlyAdded()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->once()->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('string');\n        $relation->getQuery()->shouldReceive('whereIn')->once()->with('table.morph_id', [1, 2]);\n        $relation->getQuery()->shouldReceive('where')->once()->with('table.morph_type', get_class($relation->getParent()));\n\n        $model1 = new EloquentMorphResetModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentMorphResetModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    /**\n     * Note that the tests are the exact same for morph many because the classes share this code...\n     * Will still test to be safe.\n     */\n    public function testMorphManySetsProperConstraints()\n    {\n        $this->getManyRelation();\n    }\n\n    public function testMorphManyEagerConstraintsAreProperlyAdded()\n    {\n        $relation = $this->getManyRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->once()->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('table.morph_id', [1, 2]);\n        $relation->getQuery()->shouldReceive('where')->once()->with('table.morph_type', get_class($relation->getParent()));\n\n        $model1 = new EloquentMorphResetModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentMorphResetModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    public function testMorphRelationUpsertFillsForeignKey()\n    {\n        $relation = $this->getManyRelation();\n\n        $relation->getQuery()->shouldReceive('upsert')->once()->with(\n            [\n                ['email' => 'foo3', 'name' => 'bar', $relation->getForeignKeyName() => $relation->getParentKey(), $relation->getMorphType() => $relation->getMorphClass()],\n            ],\n            ['email'],\n            ['name']\n        );\n\n        $relation->upsert(\n            ['email' => 'foo3', 'name' => 'bar'],\n            ['email'],\n            ['name']\n        );\n\n        $relation->getQuery()->shouldReceive('upsert')->once()->with(\n            [\n                ['email' => 'foo3', 'name' => 'bar', $relation->getForeignKeyName() => $relation->getParentKey(), $relation->getMorphType() => $relation->getMorphClass()],\n                ['name' => 'bar2', 'email' => 'foo2', $relation->getForeignKeyName() => $relation->getParentKey(), $relation->getMorphType() => $relation->getMorphClass()],\n            ],\n            ['email'],\n            ['name']\n        );\n\n        $relation->upsert(\n            [\n                ['email' => 'foo3', 'name' => 'bar'],\n                ['name' => 'bar2', 'email' => 'foo2'],\n            ],\n            ['email'],\n            ['name']\n        );\n    }\n\n    public function testMakeFunctionOnMorph()\n    {\n        $_SERVER['__eloquent.saved'] = false;\n        // Doesn't matter which relation type we use since they share the code...\n        $relation = $this->getOneRelation();\n        $instance = m::mock(Model::class);\n        $instance->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $instance->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $instance->shouldReceive('save')->never();\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['name' => 'taylor'])->andReturn($instance);\n\n        $this->assertEquals($instance, $relation->make(['name' => 'taylor']));\n    }\n\n    public function testCreateFunctionOnMorph()\n    {\n        // Doesn't matter which relation type we use since they share the code...\n        $relation = $this->getOneRelation();\n        $created = m::mock(Model::class);\n        $created->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $created->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['name' => 'taylor'])->andReturn($created);\n        $created->shouldReceive('save')->once()->andReturn(true);\n\n        $this->assertEquals($created, $relation->create(['name' => 'taylor']));\n    }\n\n    public function testFindOrNewMethodFindsModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('find')->once()->with('foo', ['*'])->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->findOrNew('foo'));\n    }\n\n    public function testFindOrNewMethodReturnsNewModelWithMorphKeysSet()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('find')->once()->with('foo', ['*'])->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with()->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->findOrNew('foo'));\n    }\n\n    public function testFirstOrNewMethodFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrNew(['foo']));\n    }\n\n    public function testFirstOrNewMethodWithValueFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrNew(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrNewMethodReturnsNewModelWithMorphKeysSet()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrNew(['foo']));\n    }\n\n    public function testFirstOrNewMethodWithValuesReturnsNewModelWithMorphKeysSet()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo' => 'bar', 'baz' => 'qux'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrNew(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrCreateMethodFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrCreate(['foo']));\n    }\n\n    public function testFirstOrCreateMethodWithValuesFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('save')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrCreate(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testFirstOrCreateMethodCreatesNewMorphModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(fn ($scope) => $scope());\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrCreate(['foo']));\n    }\n\n    public function testFirstOrCreateMethodWithValuesCreatesNewMorphModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(fn ($scope) => $scope());\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo' => 'bar', 'baz' => 'qux'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $this->assertInstanceOf(Model::class, $relation->firstOrCreate(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testCreateOrFirstMethodFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andThrow(\n            new UniqueConstraintViolationException('mysql', 'example mysql', [], new Exception('SQLSTATE[23000]: Integrity constraint violation: 1062')),\n        );\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('useWritePdo')->once()->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n\n        $this->assertInstanceOf(Model::class, $relation->createOrFirst(['foo']));\n    }\n\n    public function testCreateOrFirstMethodWithValuesFindsFirstModel()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo' => 'bar', 'baz' => 'qux'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andThrow(\n            new UniqueConstraintViolationException('mysql', 'example mysql', [], new Exception('SQLSTATE[23000]: Integrity constraint violation: 1062')),\n        );\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('useWritePdo')->once()->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo' => 'bar'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n\n        $this->assertInstanceOf(Model::class, $relation->createOrFirst(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testCreateOrFirstMethodCreatesNewMorphModel()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->never();\n        $relation->getQuery()->shouldReceive('first')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->createOrFirst(['foo']));\n    }\n\n    public function testCreateOrFirstMethodWithValuesCreatesNewMorphModel()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo' => 'bar', 'baz' => 'qux'])->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->never();\n        $relation->getQuery()->shouldReceive('first')->never();\n\n        $this->assertInstanceOf(Model::class, $relation->createOrFirst(['foo' => 'bar'], ['baz' => 'qux']));\n    }\n\n    public function testUpdateOrCreateMethodFindsFirstModelAndUpdates()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn($model = m::mock(Model::class));\n        $relation->getRelated()->shouldReceive('newInstance')->never();\n\n        $model->wasRecentlyCreated = false;\n        $model->shouldReceive('setAttribute')->never();\n        $model->shouldReceive('fill')->once()->with(['bar'])->andReturn($model);\n        $model->shouldReceive('save')->once();\n\n        $this->assertInstanceOf(Model::class, $relation->updateOrCreate(['foo'], ['bar']));\n    }\n\n    public function testUpdateOrCreateMethodCreatesNewMorphModel()\n    {\n        $relation = $this->getOneRelation();\n        $relation->getQuery()->shouldReceive('withSavepointIfNeeded')->once()->andReturnUsing(function ($scope) {\n            return $scope();\n        });\n        $relation->getQuery()->shouldReceive('where')->once()->with(['foo'])->andReturn($relation->getQuery());\n        $relation->getQuery()->shouldReceive('first')->once()->with()->andReturn(null);\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['foo', 'bar'])->andReturn($model = m::mock(Model::class));\n\n        $model->wasRecentlyCreated = true;\n        $model->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $model->shouldReceive('setAttribute')->once()->with('morph_type', get_class($relation->getParent()));\n        $model->shouldReceive('save')->once()->andReturn(true);\n\n        $this->assertInstanceOf(Model::class, $relation->updateOrCreate(['foo'], ['bar']));\n    }\n\n    public function testCreateFunctionOnNamespacedMorph()\n    {\n        $relation = $this->getNamespacedRelation('namespace');\n        $created = m::mock(Model::class);\n        $created->shouldReceive('setAttribute')->once()->with('morph_id', 1);\n        $created->shouldReceive('setAttribute')->once()->with('morph_type', 'namespace');\n        $relation->getRelated()->shouldReceive('newInstance')->once()->with(['name' => 'taylor'])->andReturn($created);\n        $created->shouldReceive('save')->once()->andReturn(true);\n\n        $this->assertEquals($created, $relation->create(['name' => 'taylor']));\n    }\n\n    public function testIsNotNull()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->never();\n        $relation->getRelated()->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is(null));\n    }\n\n    public function testIsModel()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->once()->andReturn('table');\n        $relation->getRelated()->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithStringRelatedKey()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->once()->andReturn('table');\n        $relation->getRelated()->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn('1');\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullRelatedKey()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->never();\n        $relation->getRelated()->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn(null);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherRelatedKey()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->never();\n        $relation->getRelated()->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn(2);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherTable()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->once()->andReturn('table');\n        $relation->getRelated()->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table.two');\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherConnection()\n    {\n        $relation = $this->getOneRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->once()->andReturn('table');\n        $relation->getRelated()->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('morph_id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('table');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('connection.two');\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    protected function getOneRelation()\n    {\n        $queryBuilder = m::mock(QueryBuilder::class);\n        $builder = m::mock(Builder::class, [$queryBuilder]);\n        $builder->shouldReceive('whereNotNull')->once()->with('table.morph_id');\n        $builder->shouldReceive('where')->once()->with('table.morph_id', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));\n        $builder->shouldReceive('where')->once()->with('table.morph_type', get_class($parent));\n\n        return new MorphOne($builder, $parent, 'table.morph_type', 'table.morph_id', 'id');\n    }\n\n    protected function getManyRelation()\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('whereNotNull')->once()->with('table.morph_id');\n        $builder->shouldReceive('where')->once()->with('table.morph_id', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));\n        $builder->shouldReceive('where')->once()->with('table.morph_type', get_class($parent));\n\n        return new MorphMany($builder, $parent, 'table.morph_type', 'table.morph_id', 'id');\n    }\n\n    protected function getNamespacedRelation($alias)\n    {\n        require_once __DIR__.'/stubs/EloquentModelNamespacedStub.php';\n\n        Relation::morphMap([\n            $alias => EloquentModelNamespacedStub::class,\n        ]);\n\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('whereNotNull')->once()->with('table.morph_id');\n        $builder->shouldReceive('where')->once()->with('table.morph_id', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(EloquentModelNamespacedStub::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getMorphClass')->andReturn($alias);\n        $builder->shouldReceive('where')->once()->with('table.morph_type', $alias);\n\n        return new MorphOne($builder, $parent, 'table.morph_type', 'table.morph_id', 'id');\n    }\n}\n\nclass EloquentMorphResetModelStub extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentMorphToManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Mockery\\Adapter\\Phpunit\\MockeryTestCase as TestCase;\nuse Mockery as m;\nuse stdClass;\n\nclass DatabaseEloquentMorphToManyTest extends TestCase\n{\n    public function testEagerConstraintsAreProperlyAdded(): void\n    {\n        $relation = $this->getRelation();\n        $relation->getParent()->shouldReceive('getKeyName')->andReturn('id');\n        $relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('int');\n        $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('taggables.taggable_id', [1, 2]);\n        $relation->getQuery()->shouldReceive('where')->once()->with('taggables.taggable_type', get_class($relation->getParent()));\n        $model1 = new EloquentMorphToManyModelStub;\n        $model1->id = 1;\n        $model2 = new EloquentMorphToManyModelStub;\n        $model2->id = 2;\n        $relation->addEagerConstraints([$model1, $model2]);\n    }\n\n    public function testAttachInsertsPivotTableRecord(): void\n    {\n        $relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();\n        $query = m::mock(stdClass::class);\n        $query->shouldReceive('from')->once()->with('taggables')->andReturn($query);\n        $query->shouldReceive('insert')->once()->with([['taggable_id' => 1, 'taggable_type' => get_class($relation->getParent()), 'tag_id' => 2, 'foo' => 'bar']])->andReturn(true);\n        $relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);\n        $relation->expects($this->once())->method('touchIfTouching');\n\n        $relation->attach(2, ['foo' => 'bar']);\n    }\n\n    public function testDetachRemovesPivotTableRecord(): void\n    {\n        $relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();\n        $query = m::mock(stdClass::class);\n        $query->shouldReceive('from')->once()->with('taggables')->andReturn($query);\n        $query->shouldReceive('where')->once()->with('taggables.taggable_id', 1)->andReturn($query);\n        $query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);\n        $query->shouldReceive('whereIn')->once()->with('taggables.tag_id', [1, 2, 3]);\n        $query->shouldReceive('delete')->once()->andReturn(true);\n        $relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);\n        $relation->expects($this->once())->method('touchIfTouching');\n\n        $this->assertTrue($relation->detach([1, 2, 3]));\n    }\n\n    public function testDetachMethodClearsAllPivotRecordsWhenNoIDsAreGiven(): void\n    {\n        $relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();\n        $query = m::mock(stdClass::class);\n        $query->shouldReceive('from')->once()->with('taggables')->andReturn($query);\n        $query->shouldReceive('where')->once()->with('taggables.taggable_id', 1)->andReturn($query);\n        $query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);\n        $query->shouldReceive('whereIn')->never();\n        $query->shouldReceive('delete')->once()->andReturn(true);\n        $relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);\n        $relation->expects($this->once())->method('touchIfTouching');\n\n        $this->assertTrue($relation->detach());\n    }\n\n    public function testQueryExpressionCanBePassedToDifferentPivotQueryBuilderClauses(): void\n    {\n        $value = 'pivot_value';\n        $column = new Expression(\"CONCAT(foo, '_', bar)\");\n        $relation = $this->getRelation();\n        /** @var Builder|m\\MockInterface $builder */\n        $builder = $relation->getQuery();\n\n        $builder->shouldReceive('where')->with($column, '=', $value, 'and')->times(2)->andReturnSelf();\n        $relation->wherePivot($column, '=', $value);\n        $relation->withPivotValue($column, $value);\n\n        $builder->shouldReceive('whereBetween')->with($column, [$value, $value], 'and', false)->once()->andReturnSelf();\n        $relation->wherePivotBetween($column, [$value, $value]);\n\n        $builder->shouldReceive('whereIn')->with($column, [$value], 'and', false)->once()->andReturnSelf();\n        $relation->wherePivotIn($column, [$value]);\n\n        $builder->shouldReceive('whereNull')->with($column, 'and', false)->once()->andReturnSelf();\n        $relation->wherePivotNull($column);\n\n        $builder->shouldReceive('orderBy')->with($column, 'asc')->once()->andReturnSelf();\n        $relation->orderByPivot($column);\n    }\n\n    public function getRelation(): MorphToMany\n    {\n        [$builder, $parent] = $this->getRelationArguments();\n\n        return new MorphToMany($builder, $parent, 'taggable', 'taggables', 'taggable_id', 'tag_id', 'id', 'id');\n    }\n\n    public function getRelationArguments(): array\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));\n        $parent->shouldReceive('getKey')->andReturn(1);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n        $parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n\n        $builder = m::mock(Builder::class);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        $related->shouldReceive('getTable')->andReturn('tags');\n        $related->shouldReceive('getKeyName')->andReturn('id');\n        $related->shouldReceive('qualifyColumn')->with('id')->andReturn('tags.id');\n        $related->shouldReceive('getMorphClass')->andReturn(get_class($related));\n\n        $builder->shouldReceive('join')->once()->with('taggables', 'tags.id', '=', 'taggables.tag_id');\n        $builder->shouldReceive('where')->once()->with('taggables.taggable_id', '=', 1);\n        $builder->shouldReceive('where')->once()->with('taggables.taggable_type', get_class($parent));\n\n        $grammar = m::mock(Grammar::class);\n        $grammar->shouldReceive('isExpression')->with(m::type(Expression::class))->andReturnTrue();\n        $grammar->shouldReceive('isExpression')->with(m::type('string'))->andReturnFalse();\n        $builder->shouldReceive('getQuery')->andReturn(\n            m::mock(stdClass::class, ['getGrammar' => $grammar])\n        );\n\n        return [$builder, $parent, 'taggable', 'taggables', 'taggable_id', 'tag_id', 'id', 'id', 'relation_name', false];\n    }\n}\n\nclass EloquentMorphToManyModelStub extends Model\n{\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentMorphToTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Tests\\Database\\stubs\\TestEnum;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentMorphToTest extends TestCase\n{\n    protected $builder;\n\n    protected $related;\n\n    public function testLookupDictionaryIsProperlyConstructedForEnums()\n    {\n        $relation = $this->getRelation();\n        $relation->addEagerConstraints([\n            $one = (object) ['morph_type' => 'morph_type_2', 'foreign_key' => TestEnum::test],\n        ]);\n        $dictionary = $relation->getDictionary();\n        $relation->getDictionary();\n        $enumKey = TestEnum::test;\n        if (isset($enumKey->value)) {\n            $value = $dictionary['morph_type_2'][$enumKey->value][0]->foreign_key;\n            $this->assertEquals(TestEnum::test, $value);\n        } else {\n            $this->fail('An enum should contain value property');\n        }\n    }\n\n    public function testLookupDictionaryIsProperlyConstructed()\n    {\n        $stringish = new class\n        {\n            public function __toString()\n            {\n                return 'foreign_key_2';\n            }\n        };\n\n        $relation = $this->getRelation();\n        $relation->addEagerConstraints([\n            $one = (object) ['morph_type' => 'morph_type_1', 'foreign_key' => 'foreign_key_1'],\n            $two = (object) ['morph_type' => 'morph_type_1', 'foreign_key' => 'foreign_key_1'],\n            $three = (object) ['morph_type' => 'morph_type_2', 'foreign_key' => 'foreign_key_2'],\n            $four = (object) ['morph_type' => 'morph_type_2', 'foreign_key' => $stringish],\n        ]);\n\n        $dictionary = $relation->getDictionary();\n\n        $this->assertEquals([\n            'morph_type_1' => [\n                'foreign_key_1' => [\n                    $one,\n                    $two,\n                ],\n            ],\n            'morph_type_2' => [\n                'foreign_key_2' => [\n                    $three,\n                    $four,\n                ],\n            ],\n        ], $dictionary);\n    }\n\n    public function testMorphToWithDefault()\n    {\n        $relation = $this->getRelation()->withDefault();\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentMorphToModelStub;\n\n        $this->assertEquals($newModel, $relation->getResults());\n    }\n\n    public function testMorphToWithDynamicDefault()\n    {\n        $relation = $this->getRelation()->withDefault(function ($newModel) {\n            $newModel->username = 'taylor';\n        });\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentMorphToModelStub;\n        $newModel->username = 'taylor';\n\n        $result = $relation->getResults();\n\n        $this->assertEquals($newModel, $result);\n\n        $this->assertSame('taylor', $result->username);\n    }\n\n    public function testMorphToWithArrayDefault()\n    {\n        $relation = $this->getRelation()->withDefault(['username' => 'taylor']);\n\n        $this->builder->shouldReceive('first')->once()->andReturnNull();\n\n        $newModel = new EloquentMorphToModelStub;\n        $newModel->username = 'taylor';\n\n        $result = $relation->getResults();\n\n        $this->assertEquals($newModel, $result);\n\n        $this->assertSame('taylor', $result->username);\n    }\n\n    public function testMorphToWithZeroMorphType()\n    {\n        $parent = $this->getMockBuilder(EloquentMorphToModelStub::class)->onlyMethods(['getAttributeFromArray', 'morphEagerTo', 'morphInstanceTo'])->getMock();\n        $parent->method('getAttributeFromArray')->with('relation_type')->willReturn(0);\n        $parent->expects($this->once())->method('morphInstanceTo');\n        $parent->expects($this->never())->method('morphEagerTo');\n\n        $parent->relation();\n    }\n\n    public function testMorphToWithEmptyStringMorphType()\n    {\n        $parent = $this->getMockBuilder(EloquentMorphToModelStub::class)->onlyMethods(['getAttributeFromArray', 'morphEagerTo', 'morphInstanceTo'])->getMock();\n        $parent->method('getAttributeFromArray')->with('relation_type')->willReturn('');\n        $parent->expects($this->once())->method('morphEagerTo');\n        $parent->expects($this->never())->method('morphInstanceTo');\n\n        $parent->relation();\n    }\n\n    public function testMorphToWithSpecifiedClassDefault()\n    {\n        $parent = new EloquentMorphToModelStub;\n        $parent->relation_type = EloquentMorphToRelatedStub::class;\n\n        $relation = $parent->relation()->withDefault();\n\n        $newModel = new EloquentMorphToRelatedStub;\n\n        $result = $relation->getResults();\n\n        $this->assertEquals($newModel, $result);\n    }\n\n    public function testAssociateMethodSetsForeignKeyAndTypeOnModel()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('foreign_key')->andReturn('foreign.value');\n\n        $relation = $this->getRelationAssociate($parent);\n\n        $associate = m::mock(Model::class);\n        $associate->shouldReceive('getAttribute')->andReturn(1);\n        $associate->shouldReceive('getMorphClass')->andReturn('Model');\n\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', 1);\n        $parent->shouldReceive('setAttribute')->once()->with('morph_type', 'Model');\n        $parent->shouldReceive('setRelation')->once()->with('relation', $associate);\n\n        $relation->associate($associate);\n    }\n\n    public function testAssociateMethodIgnoresNullValue()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n\n        $relation = $this->getRelationAssociate($parent);\n\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', null);\n        $parent->shouldReceive('setAttribute')->once()->with('morph_type', null);\n        $parent->shouldReceive('setRelation')->once()->with('relation', null);\n\n        $relation->associate(null);\n    }\n\n    public function testDissociateMethodDeletesUnsetsKeyAndTypeOnModel()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n\n        $relation = $this->getRelation($parent);\n\n        $parent->shouldReceive('setAttribute')->once()->with('foreign_key', null);\n        $parent->shouldReceive('setAttribute')->once()->with('morph_type', null);\n        $parent->shouldReceive('setRelation')->once()->with('relation', null);\n\n        $relation->dissociate();\n    }\n\n    public function testIsNotNull()\n    {\n        $relation = $this->getRelation();\n\n        $relation->getRelated()->shouldReceive('getTable')->never();\n        $relation->getRelated()->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is(null));\n    }\n\n    public function testIsModel()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerParentKey()\n    {\n        $parent = m::mock(Model::class);\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return an integer\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('1');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerRelatedKey()\n    {\n        $parent = m::mock(Model::class);\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return a string\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('1');\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsModelWithIntegerKeys()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return an integer\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(1);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(1);\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $this->assertTrue($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullParentKey()\n    {\n        $parent = m::mock(Model::class);\n\n        // when addConstraints is called we need to return the foreign value\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn('foreign.value');\n        // when getParentKey is called we want to return null\n\n        $parent->shouldReceive('getAttribute')->once()->with('foreign_key')->andReturn(null);\n\n        $relation = $this->getRelation($parent);\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithNullRelatedKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn(null);\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherKey()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value.two');\n        $model->shouldReceive('getTable')->never();\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherTable()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->never();\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('table.two');\n        $model->shouldReceive('getConnectionName')->never();\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    public function testIsNotModelWithAnotherConnection()\n    {\n        $relation = $this->getRelation();\n\n        $this->related->shouldReceive('getConnectionName')->once()->andReturn('relation');\n\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getAttribute')->once()->with('id')->andReturn('foreign.value');\n        $model->shouldReceive('getTable')->once()->andReturn('relation');\n        $model->shouldReceive('getConnectionName')->once()->andReturn('relation.two');\n\n        $this->assertFalse($relation->is($model));\n    }\n\n    protected function getRelationAssociate($parent)\n    {\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('where')->with('relation.id', '=', 'foreign.value');\n        $related = m::mock(Model::class);\n        $related->shouldReceive('getKey')->andReturn(1);\n        $related->shouldReceive('getTable')->andReturn('relation');\n        $related->shouldReceive('qualifyColumn')->andReturnUsing(fn (string $column) => \"relation.{$column}\");\n        $builder->shouldReceive('getModel')->andReturn($related);\n\n        return new MorphTo($builder, $parent, 'foreign_key', 'id', 'morph_type', 'relation');\n    }\n\n    public function getRelation($parent = null, $builder = null)\n    {\n        $this->builder = $builder ?: m::mock(Builder::class);\n        $this->builder->shouldReceive('where')->with('relation.id', '=', 'foreign.value');\n        $this->related = m::mock(Model::class);\n        $this->related->shouldReceive('getKeyName')->andReturn('id');\n        $this->related->shouldReceive('getTable')->andReturn('relation');\n        $this->related->shouldReceive('qualifyColumn')->andReturnUsing(fn (string $column) => \"relation.{$column}\");\n        $this->builder->shouldReceive('getModel')->andReturn($this->related);\n        $parent = $parent ?: new EloquentMorphToModelStub;\n\n        return m::mock(MorphTo::class.'[createModelByType]', [$this->builder, $parent, 'foreign_key', 'id', 'morph_type', 'relation']);\n    }\n}\n\nclass EloquentMorphToModelStub extends Model\n{\n    public $foreign_key = 'foreign.value';\n\n    public $table = 'eloquent_morph_to_model_stubs';\n\n    public function relation()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass EloquentMorphToRelatedStub extends Model\n{\n    public $table = 'eloquent_morph_to_related_stubs';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentPivotTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseEloquentPivotTest extends TestCase\n{\n    public function testPropertiesAreSetCorrectly()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->twice()->andReturn('connection');\n        $parent->setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class));\n        $resolver->shouldReceive('connection')->andReturn($connection = m::mock(Connection::class));\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class));\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class));\n        $parent->getConnection()->getQueryGrammar()->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s');\n        $parent->setDateFormat('Y-m-d H:i:s');\n        $pivot = Pivot::fromAttributes($parent, ['foo' => 'bar', 'created_at' => '2015-09-12'], 'table', true);\n\n        $this->assertEquals(['foo' => 'bar', 'created_at' => '2015-09-12 00:00:00'], $pivot->getAttributes());\n        $this->assertSame('connection', $pivot->getConnectionName());\n        $this->assertSame('table', $pivot->getTable());\n        $this->assertTrue($pivot->exists);\n        $this->assertSame($parent, $pivot->pivotParent);\n    }\n\n    public function testMutatorsAreCalledFromConstructor()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $pivot = DatabaseEloquentPivotTestMutatorStub::fromAttributes($parent, ['foo' => 'bar'], 'table', true);\n\n        $this->assertTrue($pivot->getMutatorCalled());\n    }\n\n    public function testFromRawAttributesDoesNotDoubleMutate()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $pivot = DatabaseEloquentPivotTestJsonCastStub::fromRawAttributes($parent, ['foo' => json_encode(['name' => 'Taylor'])], 'table', true);\n\n        $this->assertEquals(['name' => 'Taylor'], $pivot->foo);\n    }\n\n    public function testFromRawAttributesDoesNotMutate()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n\n        $pivot = DatabaseEloquentPivotTestMutatorStub::fromRawAttributes($parent, ['foo' => 'bar'], 'table', true);\n\n        $this->assertFalse($pivot->getMutatorCalled());\n    }\n\n    public function testPropertiesUnchangedAreNotDirty()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n        $pivot = Pivot::fromAttributes($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true);\n\n        $this->assertEquals([], $pivot->getDirty());\n    }\n\n    public function testPropertiesChangedAreDirty()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n        $pivot = Pivot::fromAttributes($parent, ['foo' => 'bar', 'shimy' => 'shake'], 'table', true);\n        $pivot->shimy = 'changed';\n\n        $this->assertEquals(['shimy' => 'changed'], $pivot->getDirty());\n    }\n\n    public function testTimestampPropertyIsSetIfCreatedAtInAttributes()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName,getDates]');\n        $parent->shouldReceive('getConnectionName')->andReturn('connection');\n        $parent->shouldReceive('getDates')->andReturn([]);\n        $pivot = DatabaseEloquentPivotTestDateStub::fromAttributes($parent, ['foo' => 'bar', 'created_at' => 'foo'], 'table');\n        $this->assertTrue($pivot->timestamps);\n\n        $pivot = DatabaseEloquentPivotTestDateStub::fromAttributes($parent, ['foo' => 'bar'], 'table');\n        $this->assertFalse($pivot->timestamps);\n    }\n\n    public function testTimestampPropertyIsTrueWhenCreatingFromRawAttributes()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName,getDates]');\n        $parent->shouldReceive('getConnectionName')->andReturn('connection');\n        $pivot = Pivot::fromRawAttributes($parent, ['foo' => 'bar', 'created_at' => 'foo'], 'table');\n        $this->assertTrue($pivot->timestamps);\n    }\n\n    public function testKeysCanBeSetProperly()\n    {\n        $parent = m::mock(Model::class.'[getConnectionName]');\n        $parent->shouldReceive('getConnectionName')->once()->andReturn('connection');\n        $pivot = Pivot::fromAttributes($parent, ['foo' => 'bar'], 'table');\n        $pivot->setPivotKeys('foreign', 'other');\n\n        $this->assertSame('foreign', $pivot->getForeignKey());\n        $this->assertSame('other', $pivot->getOtherKey());\n    }\n\n    public function testDeleteMethodDeletesModelByKeys()\n    {\n        $pivot = $this->getMockBuilder(Pivot::class)->onlyMethods(['newQueryWithoutRelationships'])->getMock();\n        $pivot->setPivotKeys('foreign', 'other');\n        $pivot->foreign = 'foreign.value';\n        $pivot->other = 'other.value';\n        $query = m::mock(stdClass::class);\n        $query->shouldReceive('where')->once()->with(['foreign' => 'foreign.value', 'other' => 'other.value'])->andReturn($query);\n        $query->shouldReceive('delete')->once()->andReturn(true);\n        $pivot->expects($this->once())->method('newQueryWithoutRelationships')->willReturn($query);\n\n        $rowsAffected = $pivot->delete();\n        $this->assertEquals(1, $rowsAffected);\n    }\n\n    public function testPivotModelTableNameIsSingular()\n    {\n        $pivot = new Pivot;\n\n        $this->assertSame('pivot', $pivot->getTable());\n    }\n\n    public function testPivotModelWithParentReturnsParentsTimestampColumns()\n    {\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('parent_created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('parent_updated_at');\n\n        $pivotWithParent = new Pivot;\n        $pivotWithParent->pivotParent = $parent;\n\n        $this->assertSame('parent_created_at', $pivotWithParent->getCreatedAtColumn());\n        $this->assertSame('parent_updated_at', $pivotWithParent->getUpdatedAtColumn());\n    }\n\n    public function testPivotModelWithoutParentReturnsModelTimestampColumns()\n    {\n        $model = new DummyModel;\n\n        $pivotWithoutParent = new Pivot;\n\n        $this->assertEquals($model->getCreatedAtColumn(), $pivotWithoutParent->getCreatedAtColumn());\n        $this->assertEquals($model->getUpdatedAtColumn(), $pivotWithoutParent->getUpdatedAtColumn());\n    }\n\n    public function testWithoutRelations()\n    {\n        $original = new Pivot;\n\n        $original->pivotParent = 'foo';\n        $original->setRelation('bar', 'baz');\n\n        $this->assertSame('baz', $original->getRelation('bar'));\n\n        $pivot = $original->withoutRelations();\n\n        $this->assertInstanceOf(Pivot::class, $pivot);\n        $this->assertNotSame($pivot, $original);\n        $this->assertSame('foo', $original->pivotParent);\n        $this->assertNull($pivot->pivotParent);\n        $this->assertTrue($original->relationLoaded('bar'));\n        $this->assertFalse($pivot->relationLoaded('bar'));\n\n        $pivot = $original->unsetRelations();\n\n        $this->assertSame($pivot, $original);\n        $this->assertNull($pivot->pivotParent);\n        $this->assertFalse($pivot->relationLoaded('bar'));\n    }\n}\n\nclass DatabaseEloquentPivotTestDateStub extends Pivot\n{\n    public function getDates()\n    {\n        return [];\n    }\n}\n\nclass DatabaseEloquentPivotTestMutatorStub extends Pivot\n{\n    private $mutatorCalled = false;\n\n    public function setFooAttribute($value)\n    {\n        $this->mutatorCalled = true;\n\n        return $value;\n    }\n\n    public function getMutatorCalled()\n    {\n        return $this->mutatorCalled;\n    }\n}\n\nclass DatabaseEloquentPivotTestJsonCastStub extends Pivot\n{\n    protected $casts = [\n        'foo' => 'json',\n    ];\n}\n\nclass DummyModel extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentPolymorphicIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentPolymorphicIntegrationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('posts', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->string('title');\n            $table->text('body');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('comments', function ($table) {\n            $table->increments('id');\n            $table->integer('commentable_id');\n            $table->string('commentable_type');\n            $table->integer('user_id');\n            $table->text('body');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('likes', function ($table) {\n            $table->increments('id');\n            $table->integer('likeable_id');\n            $table->string('likeable_type');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('posts');\n        $this->schema()->drop('comments');\n\n        parent::tearDown();\n    }\n\n    public function testItLoadsRelationshipsAutomatically()\n    {\n        $this->seedData();\n\n        $like = TestLikeWithSingleWith::first();\n\n        $this->assertTrue($like->relationLoaded('likeable'));\n        $this->assertEquals(TestComment::first(), $like->likeable);\n    }\n\n    public function testItLoadsChainedRelationshipsAutomatically()\n    {\n        $this->seedData();\n\n        $like = TestLikeWithSingleWith::first();\n\n        $this->assertTrue($like->likeable->relationLoaded('commentable'));\n        $this->assertEquals(TestPost::first(), $like->likeable->commentable);\n    }\n\n    public function testItLoadsNestedRelationshipsAutomatically()\n    {\n        $this->seedData();\n\n        $like = TestLikeWithNestedWith::first();\n\n        $this->assertTrue($like->relationLoaded('likeable'));\n        $this->assertTrue($like->likeable->relationLoaded('owner'));\n\n        $this->assertEquals(TestUser::first(), $like->likeable->owner);\n    }\n\n    public function testItLoadsNestedRelationshipsOnDemand()\n    {\n        $this->seedData();\n\n        $like = TestLike::with('likeable.owner')->first();\n\n        $this->assertTrue($like->relationLoaded('likeable'));\n        $this->assertTrue($like->likeable->relationLoaded('owner'));\n\n        $this->assertEquals(TestUser::first(), $like->likeable->owner);\n    }\n\n    public function testItLoadsNestedMorphRelationshipsOnDemand()\n    {\n        $this->seedData();\n\n        TestPost::first()->likes()->create([]);\n\n        $likes = TestLike::with('likeable.owner')->get()->loadMorph('likeable', [\n            TestComment::class => ['commentable'],\n            TestPost::class => 'comments',\n        ]);\n\n        $this->assertTrue($likes[0]->relationLoaded('likeable'));\n        $this->assertTrue($likes[0]->likeable->relationLoaded('owner'));\n        $this->assertTrue($likes[0]->likeable->relationLoaded('commentable'));\n\n        $this->assertTrue($likes[1]->relationLoaded('likeable'));\n        $this->assertTrue($likes[1]->likeable->relationLoaded('owner'));\n        $this->assertTrue($likes[1]->likeable->relationLoaded('comments'));\n    }\n\n    public function testItLoadsNestedMorphRelationshipCountsOnDemand()\n    {\n        $this->seedData();\n\n        TestPost::first()->likes()->create([]);\n        TestComment::first()->likes()->create([]);\n\n        $likes = TestLike::with('likeable.owner')->get()->loadMorphCount('likeable', [\n            TestComment::class => ['likes'],\n            TestPost::class => 'comments',\n        ]);\n\n        $this->assertTrue($likes[0]->relationLoaded('likeable'));\n        $this->assertTrue($likes[0]->likeable->relationLoaded('owner'));\n        $this->assertEquals(2, $likes[0]->likeable->likes_count);\n\n        $this->assertTrue($likes[1]->relationLoaded('likeable'));\n        $this->assertTrue($likes[1]->likeable->relationLoaded('owner'));\n        $this->assertEquals(1, $likes[1]->likeable->comments_count);\n\n        $this->assertTrue($likes[2]->relationLoaded('likeable'));\n        $this->assertTrue($likes[2]->likeable->relationLoaded('owner'));\n        $this->assertEquals(2, $likes[2]->likeable->likes_count);\n    }\n\n    /**\n     * Helpers...\n     */\n    protected function seedData()\n    {\n        $taylor = TestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n\n        $taylor->posts()->create(['title' => 'A title', 'body' => 'A body'])\n            ->comments()->create(['body' => 'A comment body', 'user_id' => 1])\n            ->likes()->create([]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass TestUser extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(TestPost::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass TestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->morphMany(TestComment::class, 'commentable');\n    }\n\n    public function owner()\n    {\n        return $this->belongsTo(TestUser::class, 'user_id');\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(TestLike::class, 'likeable');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass TestComment extends Eloquent\n{\n    protected $table = 'comments';\n    protected $guarded = [];\n    protected $with = ['commentable'];\n\n    public function owner()\n    {\n        return $this->belongsTo(TestUser::class, 'user_id');\n    }\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(TestLike::class, 'likeable');\n    }\n}\n\nclass TestLike extends Eloquent\n{\n    protected $table = 'likes';\n    protected $guarded = [];\n\n    public function likeable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass TestLikeWithSingleWith extends Eloquent\n{\n    protected $table = 'likes';\n    protected $guarded = [];\n    protected $with = ['likeable'];\n\n    public function likeable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass TestLikeWithNestedWith extends Eloquent\n{\n    protected $table = 'likes';\n    protected $guarded = [];\n    protected $with = ['likeable.owner'];\n\n    public function likeable()\n    {\n        return $this->morphTo();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentPolymorphicRelationsIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentPolymorphicRelationsIntegrationTest extends TestCase\n{\n    /**\n     * Bootstrap Eloquent.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema('default')->create('posts', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('images', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('tags', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        $this->schema('default')->create('taggables', function ($table) {\n            $table->integer('eloquent_many_to_many_polymorphic_test_tag_id');\n            $table->integer('taggable_id');\n            $table->string('taggable_type');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        foreach (['default'] as $connection) {\n            $this->schema($connection)->drop('posts');\n            $this->schema($connection)->drop('images');\n            $this->schema($connection)->drop('tags');\n            $this->schema($connection)->drop('taggables');\n        }\n\n        Relation::morphMap([], false);\n\n        parent::tearDown();\n    }\n\n    public function testCreation()\n    {\n        $post = EloquentManyToManyPolymorphicTestPost::create();\n        $image = EloquentManyToManyPolymorphicTestImage::create();\n        $tag = EloquentManyToManyPolymorphicTestTag::create();\n        $tag2 = EloquentManyToManyPolymorphicTestTag::create();\n\n        $post->tags()->attach($tag->id);\n        $post->tags()->attach($tag2->id);\n        $image->tags()->attach($tag->id);\n\n        $this->assertCount(2, $post->tags);\n        $this->assertCount(1, $image->tags);\n        $this->assertCount(1, $tag->posts);\n        $this->assertCount(1, $tag->images);\n        $this->assertCount(1, $tag2->posts);\n        $this->assertCount(0, $tag2->images);\n    }\n\n    public function testEagerLoading()\n    {\n        $post = EloquentManyToManyPolymorphicTestPost::create();\n        $tag = EloquentManyToManyPolymorphicTestTag::create();\n        $post->tags()->attach($tag->id);\n\n        $post = EloquentManyToManyPolymorphicTestPost::with('tags')->whereId(1)->first();\n        $tag = EloquentManyToManyPolymorphicTestTag::with('posts')->whereId(1)->first();\n\n        $this->assertTrue($post->relationLoaded('tags'));\n        $this->assertTrue($tag->relationLoaded('posts'));\n        $this->assertEquals($tag->id, $post->tags->first()->id);\n        $this->assertEquals($post->id, $tag->posts->first()->id);\n    }\n\n    public function testChunkById()\n    {\n        $post = EloquentManyToManyPolymorphicTestPost::create();\n        $tag1 = EloquentManyToManyPolymorphicTestTag::create();\n        $tag2 = EloquentManyToManyPolymorphicTestTag::create();\n        $tag3 = EloquentManyToManyPolymorphicTestTag::create();\n        $post->tags()->attach([$tag1->id, $tag2->id, $tag3->id]);\n\n        $count = 0;\n        $iterations = 0;\n        $post->tags()->chunkById(2, function ($tags) use (&$iterations, &$count) {\n            $this->assertInstanceOf(EloquentManyToManyPolymorphicTestTag::class, $tags->first());\n            $count += $tags->count();\n            $iterations++;\n        });\n\n        $this->assertEquals(2, $iterations);\n        $this->assertEquals(3, $count);\n    }\n\n    /**\n     * Helpers...\n     */\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection($connection = 'default')\n    {\n        return Eloquent::getConnectionResolver()->connection($connection);\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass EloquentManyToManyPolymorphicTestPost extends Eloquent\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function tags()\n    {\n        return $this->morphToMany(EloquentManyToManyPolymorphicTestTag::class, 'taggable');\n    }\n}\n\nclass EloquentManyToManyPolymorphicTestImage extends Eloquent\n{\n    protected $table = 'images';\n    protected $guarded = [];\n\n    public function tags()\n    {\n        return $this->morphToMany(EloquentManyToManyPolymorphicTestTag::class, 'taggable');\n    }\n}\n\nclass EloquentManyToManyPolymorphicTestTag extends Eloquent\n{\n    protected $table = 'tags';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->morphedByMany(EloquentManyToManyPolymorphicTestPost::class, 'taggable');\n    }\n\n    public function images()\n    {\n        return $this->morphedByMany(EloquentManyToManyPolymorphicTestImage::class, 'taggable');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentRelationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentRelationTest extends TestCase\n{\n    public function testSetRelationFail()\n    {\n        $parent = new EloquentRelationResetModelStub;\n        $relation = new EloquentRelationResetModelStub;\n        $parent->setRelation('test', $relation);\n        $parent->setRelation('foo', 'bar');\n        $this->assertArrayNotHasKey('foo', $parent->toArray());\n    }\n\n    public function testUnsetExistingRelation()\n    {\n        $parent = new EloquentRelationResetModelStub;\n        $relation = new EloquentRelationResetModelStub;\n        $parent->setRelation('foo', $relation);\n        $parent->unsetRelation('foo');\n        $this->assertFalse($parent->relationLoaded('foo'));\n    }\n\n    public function testTouchMethodUpdatesRelatedTimestamps()\n    {\n        $builder = m::mock(Builder::class);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $related = m::mock(EloquentNoTouchingModelStub::class)->makePartial();\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $builder->shouldReceive('whereNotNull');\n        $builder->shouldReceive('where');\n        $builder->shouldReceive('withoutGlobalScopes')->andReturn($builder);\n        $relation = new HasOne($builder, $parent, 'foreign_key', 'id');\n        $related->shouldReceive('getTable')->andReturn('table');\n        $related->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n        $now = Carbon::now();\n        $related->shouldReceive('freshTimestampString')->andReturn($now);\n        $builder->shouldReceive('update')->once()->with(['updated_at' => $now]);\n\n        $relation->touch();\n    }\n\n    public function testCanDisableParentTouchingForAllModels()\n    {\n        /** @var \\Illuminate\\Tests\\Database\\EloquentNoTouchingModelStub $related */\n        $related = m::mock(EloquentNoTouchingModelStub::class)->makePartial();\n        $related->shouldReceive('getUpdatedAtColumn')->never();\n        $related->shouldReceive('freshTimestampString')->never();\n\n        $this->assertFalse($related::isIgnoringTouch());\n\n        Model::withoutTouching(function () use ($related) {\n            $this->assertTrue($related::isIgnoringTouch());\n\n            $builder = m::mock(Builder::class);\n            $parent = m::mock(Model::class);\n\n            $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n            $builder->shouldReceive('getModel')->andReturn($related);\n            $builder->shouldReceive('whereNotNull');\n            $builder->shouldReceive('where');\n            $builder->shouldReceive('withoutGlobalScopes')->andReturn($builder);\n            $relation = new HasOne($builder, $parent, 'foreign_key', 'id');\n            $builder->shouldReceive('update')->never();\n\n            $relation->touch();\n        });\n\n        $this->assertFalse($related::isIgnoringTouch());\n    }\n\n    public function testCanDisableTouchingForSpecificModel()\n    {\n        $related = m::mock(EloquentNoTouchingModelStub::class)->makePartial();\n        $related->shouldReceive('getUpdatedAtColumn')->never();\n        $related->shouldReceive('freshTimestampString')->never();\n\n        $anotherRelated = m::mock(EloquentNoTouchingAnotherModelStub::class)->makePartial();\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($anotherRelated::isIgnoringTouch());\n\n        EloquentNoTouchingModelStub::withoutTouching(function () use ($related, $anotherRelated) {\n            $this->assertTrue($related::isIgnoringTouch());\n            $this->assertFalse($anotherRelated::isIgnoringTouch());\n\n            $builder = m::mock(Builder::class);\n            $parent = m::mock(Model::class);\n\n            $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n            $builder->shouldReceive('getModel')->andReturn($related);\n            $builder->shouldReceive('whereNotNull');\n            $builder->shouldReceive('where');\n            $builder->shouldReceive('withoutGlobalScopes')->andReturnSelf();\n            $relation = new HasOne($builder, $parent, 'foreign_key', 'id');\n            $builder->shouldReceive('update')->never();\n\n            $relation->touch();\n\n            $anotherBuilder = m::mock(Builder::class);\n            $anotherParent = m::mock(Model::class);\n\n            $anotherParent->shouldReceive('getAttribute')->with('id')->andReturn(2);\n            $anotherBuilder->shouldReceive('getModel')->andReturn($anotherRelated);\n            $anotherBuilder->shouldReceive('whereNotNull');\n            $anotherBuilder->shouldReceive('where');\n            $anotherBuilder->shouldReceive('withoutGlobalScopes')->andReturnSelf();\n            $anotherRelation = new HasOne($anotherBuilder, $anotherParent, 'foreign_key', 'id');\n            $now = Carbon::now();\n            $anotherRelated->shouldReceive('freshTimestampString')->andReturn($now);\n            $anotherBuilder->shouldReceive('update')->once()->with(['updated_at' => $now]);\n\n            $anotherRelation->touch();\n        });\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($anotherRelated::isIgnoringTouch());\n    }\n\n    public function testParentModelIsNotTouchedWhenChildModelIsIgnored()\n    {\n        $related = m::mock(EloquentNoTouchingModelStub::class)->makePartial();\n        $related->shouldReceive('getUpdatedAtColumn')->never();\n        $related->shouldReceive('freshTimestampString')->never();\n\n        $relatedChild = m::mock(EloquentNoTouchingChildModelStub::class)->makePartial();\n        $relatedChild->shouldReceive('getUpdatedAtColumn')->never();\n        $relatedChild->shouldReceive('freshTimestampString')->never();\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($relatedChild::isIgnoringTouch());\n\n        EloquentNoTouchingModelStub::withoutTouching(function () use ($related, $relatedChild) {\n            $this->assertTrue($related::isIgnoringTouch());\n            $this->assertTrue($relatedChild::isIgnoringTouch());\n\n            $builder = m::mock(Builder::class);\n            $parent = m::mock(Model::class);\n\n            $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n            $builder->shouldReceive('getModel')->andReturn($related);\n            $builder->shouldReceive('whereNotNull');\n            $builder->shouldReceive('where');\n            $builder->shouldReceive('withoutGlobalScopes')->andReturnSelf();\n            $relation = new HasOne($builder, $parent, 'foreign_key', 'id');\n            $builder->shouldReceive('update')->never();\n\n            $relation->touch();\n\n            $anotherBuilder = m::mock(Builder::class);\n            $anotherParent = m::mock(Model::class);\n\n            $anotherParent->shouldReceive('getAttribute')->with('id')->andReturn(2);\n            $anotherBuilder->shouldReceive('getModel')->andReturn($relatedChild);\n            $anotherBuilder->shouldReceive('whereNotNull');\n            $anotherBuilder->shouldReceive('where');\n            $anotherBuilder->shouldReceive('withoutGlobalScopes')->andReturnSelf();\n            $anotherRelation = new HasOne($anotherBuilder, $anotherParent, 'foreign_key', 'id');\n            $anotherBuilder->shouldReceive('update')->never();\n\n            $anotherRelation->touch();\n        });\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($relatedChild::isIgnoringTouch());\n    }\n\n    public function testIgnoredModelsStateIsResetWhenThereAreExceptions()\n    {\n        $related = m::mock(EloquentNoTouchingModelStub::class)->makePartial();\n        $related->shouldReceive('getUpdatedAtColumn')->never();\n        $related->shouldReceive('freshTimestampString')->never();\n\n        $relatedChild = m::mock(EloquentNoTouchingChildModelStub::class)->makePartial();\n        $relatedChild->shouldReceive('getUpdatedAtColumn')->never();\n        $relatedChild->shouldReceive('freshTimestampString')->never();\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($relatedChild::isIgnoringTouch());\n\n        try {\n            EloquentNoTouchingModelStub::withoutTouching(function () use ($related, $relatedChild) {\n                $this->assertTrue($related::isIgnoringTouch());\n                $this->assertTrue($relatedChild::isIgnoringTouch());\n\n                throw new Exception;\n            });\n\n            $this->fail('Exception was not thrown');\n        } catch (Exception) {\n            // Does nothing.\n        }\n\n        $this->assertFalse($related::isIgnoringTouch());\n        $this->assertFalse($relatedChild::isIgnoringTouch());\n    }\n\n    public function testSettingMorphMapWithNumericArrayUsesTheTableNames()\n    {\n        Relation::morphMap([EloquentRelationResetModelStub::class]);\n\n        $this->assertEquals([\n            'reset' => EloquentRelationResetModelStub::class,\n        ], Relation::morphMap());\n\n        Relation::morphMap([], false);\n    }\n\n    public function testSettingMorphMapWithNumericKeys()\n    {\n        Relation::morphMap([1 => 'App\\User']);\n\n        $this->assertEquals([\n            1 => 'App\\User',\n        ], Relation::morphMap());\n\n        Relation::morphMap([], false);\n    }\n\n    public function testGetMorphAlias()\n    {\n        Relation::morphMap(['user' => 'App\\User']);\n\n        $this->assertSame('user', Relation::getMorphAlias('App\\User'));\n        $this->assertSame('Does\\Not\\Exist', Relation::getMorphAlias('Does\\Not\\Exist'));\n    }\n\n    public function testWithoutRelations()\n    {\n        $original = new EloquentNoTouchingModelStub;\n\n        $original->setRelation('foo', 'baz');\n\n        $this->assertSame('baz', $original->getRelation('foo'));\n\n        $model = $original->withoutRelations();\n\n        $this->assertInstanceOf(EloquentNoTouchingModelStub::class, $model);\n        $this->assertTrue($original->relationLoaded('foo'));\n        $this->assertFalse($model->relationLoaded('foo'));\n\n        $model = $original->unsetRelations();\n\n        $this->assertInstanceOf(EloquentNoTouchingModelStub::class, $model);\n        $this->assertFalse($original->relationLoaded('foo'));\n        $this->assertFalse($model->relationLoaded('foo'));\n    }\n\n    public function testWithoutRelation()\n    {\n        $original = new EloquentNoTouchingModelStub;\n\n        $original->setRelation('foo', 'baz');\n        $original->setRelation('bar', 'qux');\n\n        $model = $original->withoutRelation('foo');\n\n        $this->assertInstanceOf(EloquentNoTouchingModelStub::class, $model);\n        $this->assertNotSame($model, $original);\n        $this->assertTrue($original->relationLoaded('foo'));\n        $this->assertTrue($original->relationLoaded('bar'));\n        $this->assertFalse($model->relationLoaded('foo'));\n        $this->assertTrue($model->relationLoaded('bar'));\n    }\n\n    public function testWithoutRelationWithArray()\n    {\n        $original = new EloquentNoTouchingModelStub;\n\n        $original->setRelation('foo', 'baz');\n        $original->setRelation('bar', 'qux');\n        $original->setRelation('bam', 'zap');\n\n        $model = $original->withoutRelation(['foo', 'bar']);\n\n        $this->assertTrue($original->relationLoaded('foo'));\n        $this->assertTrue($original->relationLoaded('bar'));\n        $this->assertTrue($original->relationLoaded('bam'));\n        $this->assertFalse($model->relationLoaded('foo'));\n        $this->assertFalse($model->relationLoaded('bar'));\n        $this->assertTrue($model->relationLoaded('bam'));\n    }\n\n    public function testMacroable()\n    {\n        Relation::macro('foo', function () {\n            return 'foo';\n        });\n\n        $model = new EloquentRelationResetModelStub;\n        $relation = new EloquentRelationStub($model->newQuery(), $model);\n\n        $result = $relation->foo();\n        $this->assertSame('foo', $result);\n    }\n\n    public function testIsRelationIgnoresAttribute()\n    {\n        $model = new EloquentRelationAndAttributeModelStub;\n\n        $this->assertTrue($model->isRelation('parent'));\n        $this->assertFalse($model->isRelation('field'));\n    }\n}\n\nclass EloquentRelationResetModelStub extends Model\n{\n    protected $table = 'reset';\n\n    // Override method call which would normally go through __call()\n\n    public function getQuery()\n    {\n        return $this->newQuery()->getQuery();\n    }\n}\n\nclass EloquentRelationStub extends Relation\n{\n    public function addConstraints()\n    {\n        //\n    }\n\n    public function addEagerConstraints(array $models)\n    {\n        //\n    }\n\n    public function initRelation(array $models, $relation)\n    {\n        //\n    }\n\n    public function match(array $models, Collection $results, $relation)\n    {\n        //\n    }\n\n    public function getResults()\n    {\n        //\n    }\n}\n\nclass EloquentNoTouchingModelStub extends Model\n{\n    protected $table = 'table';\n    protected $attributes = [\n        'id' => 1,\n    ];\n}\n\nclass EloquentNoTouchingChildModelStub extends EloquentNoTouchingModelStub\n{\n    //\n}\n\nclass EloquentNoTouchingAnotherModelStub extends Model\n{\n    protected $table = 'another_table';\n    protected $attributes = [\n        'id' => 2,\n    ];\n}\n\nclass EloquentRelationAndAttributeModelStub extends Model\n{\n    protected $table = 'one_more_table';\n\n    public function field(): Attribute\n    {\n        return new Attribute(\n            function ($value) {\n                return $value;\n            },\n            function ($value) {\n                return $value;\n            },\n        );\n    }\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentRelationshipsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\EloquentRelationshipsTest;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentRelationshipsTest extends TestCase\n{\n    public function testStandardRelationships()\n    {\n        $post = new Post;\n\n        $this->assertInstanceOf(HasOne::class, $post->attachment());\n        $this->assertInstanceOf(BelongsTo::class, $post->author());\n        $this->assertInstanceOf(HasMany::class, $post->comments());\n        $this->assertInstanceOf(MorphOne::class, $post->owner());\n        $this->assertInstanceOf(MorphMany::class, $post->likes());\n        $this->assertInstanceOf(BelongsToMany::class, $post->viewers());\n        $this->assertInstanceOf(HasManyThrough::class, $post->lovers());\n        $this->assertInstanceOf(HasOneThrough::class, $post->contract());\n        $this->assertInstanceOf(MorphToMany::class, $post->tags());\n        $this->assertInstanceOf(MorphTo::class, $post->postable());\n    }\n\n    public function testOverriddenRelationships()\n    {\n        $post = new CustomPost;\n\n        $this->assertInstanceOf(CustomHasOne::class, $post->attachment());\n        $this->assertInstanceOf(CustomBelongsTo::class, $post->author());\n        $this->assertInstanceOf(CustomHasMany::class, $post->comments());\n        $this->assertInstanceOf(CustomMorphOne::class, $post->owner());\n        $this->assertInstanceOf(CustomMorphMany::class, $post->likes());\n        $this->assertInstanceOf(CustomBelongsToMany::class, $post->viewers());\n        $this->assertInstanceOf(CustomHasManyThrough::class, $post->lovers());\n        $this->assertInstanceOf(CustomHasOneThrough::class, $post->contract());\n        $this->assertInstanceOf(CustomMorphToMany::class, $post->tags());\n        $this->assertInstanceOf(CustomMorphTo::class, $post->postable());\n    }\n\n    public function testAlwaysUnsetBelongsToRelationWhenReceivedModelId()\n    {\n        // create users\n        $user1 = (new FakeRelationship)->forceFill(['id' => 1]);\n        $user2 = (new FakeRelationship)->forceFill(['id' => 2]);\n\n        // sync user 1 using Model\n        $post = new Post;\n        $post->author()->associate($user1);\n        $post->syncOriginal();\n\n        // associate user 2 using Model\n        $post->author()->associate($user2);\n        $this->assertTrue($post->isDirty());\n        $this->assertTrue($post->relationLoaded('author'));\n        $this->assertSame($user2, $post->author);\n\n        // associate user 1 using model ID\n        $post->author()->associate($user1->id);\n        $this->assertTrue($post->isClean());\n\n        // we must unset relation even if attributes are clean\n        $this->assertFalse($post->relationLoaded('author'));\n    }\n\n    public function testPendingHasThroughRelationship()\n    {\n        $fluent = (new FluentMechanic())->owner();\n        $classic = (new ClassicMechanic())->owner();\n\n        $this->assertInstanceOf(HasOneThrough::class, $classic);\n        $this->assertInstanceOf(HasOneThrough::class, $fluent);\n        $this->assertSame('m_id', $classic->getLocalKeyName());\n        $this->assertSame('m_id', $fluent->getLocalKeyName());\n        $this->assertSame('c_id', $classic->getSecondLocalKeyName());\n        $this->assertSame('c_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('mechanic_id', $classic->getFirstKeyName());\n        $this->assertSame('mechanic_id', $fluent->getFirstKeyName());\n        $this->assertSame('car_id', $classic->getForeignKeyName());\n        $this->assertSame('car_id', $fluent->getForeignKeyName());\n        $this->assertSame('classic_mechanics.m_id', $classic->getQualifiedLocalKeyName());\n        $this->assertSame('fluent_mechanics.m_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('cars.mechanic_id', $fluent->getQualifiedFirstKeyName());\n        $this->assertSame('cars.mechanic_id', $classic->getQualifiedFirstKeyName());\n\n        $fluent = (new FluentProject())->deployments();\n        $classic = (new ClassicProject())->deployments();\n\n        $this->assertInstanceOf(HasManyThrough::class, $classic);\n        $this->assertInstanceOf(HasManyThrough::class, $fluent);\n        $this->assertSame('p_id', $classic->getLocalKeyName());\n        $this->assertSame('p_id', $fluent->getLocalKeyName());\n        $this->assertSame('e_id', $classic->getSecondLocalKeyName());\n        $this->assertSame('e_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('pro_id', $classic->getFirstKeyName());\n        $this->assertSame('pro_id', $fluent->getFirstKeyName());\n        $this->assertSame('env_id', $classic->getForeignKeyName());\n        $this->assertSame('env_id', $fluent->getForeignKeyName());\n        $this->assertSame('classic_projects.p_id', $classic->getQualifiedLocalKeyName());\n        $this->assertSame('fluent_projects.p_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('environments.pro_id', $fluent->getQualifiedFirstKeyName());\n        $this->assertSame('environments.pro_id', $classic->getQualifiedFirstKeyName());\n\n        $fluent = (new FluentProject())->environmentData();\n        $classic = (new ClassicProject())->environmentData();\n\n        $this->assertInstanceOf(HasManyThrough::class, $classic);\n        $this->assertInstanceOf(HasManyThrough::class, $fluent);\n        $this->assertSame('p_id', $classic->getLocalKeyName());\n        $this->assertSame('p_id', $fluent->getLocalKeyName());\n        $this->assertSame('e_id', $classic->getSecondLocalKeyName());\n        $this->assertSame('e_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('pro_id', $classic->getFirstKeyName());\n        $this->assertSame('pro_id', $fluent->getFirstKeyName());\n        $this->assertSame('env_id', $classic->getForeignKeyName());\n        $this->assertSame('env_id', $fluent->getForeignKeyName());\n        $this->assertSame('classic_projects.p_id', $classic->getQualifiedLocalKeyName());\n        $this->assertSame('fluent_projects.p_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('environments.pro_id', $fluent->getQualifiedFirstKeyName());\n        $this->assertSame('environments.pro_id', $classic->getQualifiedFirstKeyName());\n    }\n\n    public function testStringyHasThroughApi()\n    {\n        $fluent = (new FluentMechanic())->owner();\n        $stringy = (new class extends FluentMechanic\n        {\n            public function owner()\n            {\n                return $this->through('car')->has('owner');\n            }\n\n            public function getTable()\n            {\n                return 'stringy_mechanics';\n            }\n        })->owner();\n\n        $this->assertInstanceOf(HasOneThrough::class, $fluent);\n        $this->assertInstanceOf(HasOneThrough::class, $stringy);\n        $this->assertSame('m_id', $fluent->getLocalKeyName());\n        $this->assertSame('m_id', $stringy->getLocalKeyName());\n        $this->assertSame('c_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('c_id', $stringy->getSecondLocalKeyName());\n        $this->assertSame('mechanic_id', $fluent->getFirstKeyName());\n        $this->assertSame('mechanic_id', $stringy->getFirstKeyName());\n        $this->assertSame('car_id', $fluent->getForeignKeyName());\n        $this->assertSame('car_id', $stringy->getForeignKeyName());\n        $this->assertSame('fluent_mechanics.m_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('stringy_mechanics.m_id', $stringy->getQualifiedLocalKeyName());\n        $this->assertSame('cars.mechanic_id', $stringy->getQualifiedFirstKeyName());\n        $this->assertSame('cars.mechanic_id', $fluent->getQualifiedFirstKeyName());\n\n        $fluent = (new FluentProject())->deployments();\n        $stringy = (new class extends FluentProject\n        {\n            public function deployments()\n            {\n                return $this->through('environments')->has('deployments');\n            }\n\n            public function getTable()\n            {\n                return 'stringy_projects';\n            }\n        })->deployments();\n\n        $this->assertInstanceOf(HasManyThrough::class, $fluent);\n        $this->assertInstanceOf(HasManyThrough::class, $stringy);\n        $this->assertSame('p_id', $fluent->getLocalKeyName());\n        $this->assertSame('p_id', $stringy->getLocalKeyName());\n        $this->assertSame('e_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('e_id', $stringy->getSecondLocalKeyName());\n        $this->assertSame('pro_id', $fluent->getFirstKeyName());\n        $this->assertSame('pro_id', $stringy->getFirstKeyName());\n        $this->assertSame('env_id', $fluent->getForeignKeyName());\n        $this->assertSame('env_id', $stringy->getForeignKeyName());\n        $this->assertSame('fluent_projects.p_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('stringy_projects.p_id', $stringy->getQualifiedLocalKeyName());\n        $this->assertSame('environments.pro_id', $stringy->getQualifiedFirstKeyName());\n        $this->assertSame('environments.pro_id', $fluent->getQualifiedFirstKeyName());\n    }\n\n    public function testHigherOrderHasThroughApi()\n    {\n        $fluent = (new FluentMechanic())->owner();\n        $higher = (new class extends FluentMechanic\n        {\n            public function owner()\n            {\n                return $this->throughCar()->hasOwner();\n            }\n\n            public function getTable()\n            {\n                return 'higher_mechanics';\n            }\n        })->owner();\n\n        $this->assertInstanceOf(HasOneThrough::class, $fluent);\n        $this->assertInstanceOf(HasOneThrough::class, $higher);\n        $this->assertSame('m_id', $fluent->getLocalKeyName());\n        $this->assertSame('m_id', $higher->getLocalKeyName());\n        $this->assertSame('c_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('c_id', $higher->getSecondLocalKeyName());\n        $this->assertSame('mechanic_id', $fluent->getFirstKeyName());\n        $this->assertSame('mechanic_id', $higher->getFirstKeyName());\n        $this->assertSame('car_id', $fluent->getForeignKeyName());\n        $this->assertSame('car_id', $higher->getForeignKeyName());\n        $this->assertSame('fluent_mechanics.m_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('higher_mechanics.m_id', $higher->getQualifiedLocalKeyName());\n        $this->assertSame('cars.mechanic_id', $higher->getQualifiedFirstKeyName());\n        $this->assertSame('cars.mechanic_id', $fluent->getQualifiedFirstKeyName());\n\n        $fluent = (new FluentProject())->deployments();\n        $higher = (new class extends FluentProject\n        {\n            public function deployments()\n            {\n                return $this->throughEnvironments()->hasDeployments();\n            }\n\n            public function getTable()\n            {\n                return 'higher_projects';\n            }\n        })->deployments();\n\n        $this->assertInstanceOf(HasManyThrough::class, $fluent);\n        $this->assertInstanceOf(HasManyThrough::class, $higher);\n        $this->assertSame('p_id', $fluent->getLocalKeyName());\n        $this->assertSame('p_id', $higher->getLocalKeyName());\n        $this->assertSame('e_id', $fluent->getSecondLocalKeyName());\n        $this->assertSame('e_id', $higher->getSecondLocalKeyName());\n        $this->assertSame('pro_id', $fluent->getFirstKeyName());\n        $this->assertSame('pro_id', $higher->getFirstKeyName());\n        $this->assertSame('env_id', $fluent->getForeignKeyName());\n        $this->assertSame('env_id', $higher->getForeignKeyName());\n        $this->assertSame('fluent_projects.p_id', $fluent->getQualifiedLocalKeyName());\n        $this->assertSame('higher_projects.p_id', $higher->getQualifiedLocalKeyName());\n        $this->assertSame('environments.pro_id', $higher->getQualifiedFirstKeyName());\n        $this->assertSame('environments.pro_id', $fluent->getQualifiedFirstKeyName());\n    }\n}\n\nclass FakeRelationship extends Model\n{\n    //\n}\n\nclass Post extends Model\n{\n    public function attachment()\n    {\n        return $this->hasOne(FakeRelationship::class);\n    }\n\n    public function author()\n    {\n        return $this->belongsTo(FakeRelationship::class);\n    }\n\n    public function comments()\n    {\n        return $this->hasMany(FakeRelationship::class);\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(FakeRelationship::class, 'actionable');\n    }\n\n    public function owner()\n    {\n        return $this->morphOne(FakeRelationship::class, 'property');\n    }\n\n    public function viewers()\n    {\n        return $this->belongsToMany(FakeRelationship::class);\n    }\n\n    public function lovers()\n    {\n        return $this->hasManyThrough(FakeRelationship::class, FakeRelationship::class);\n    }\n\n    public function contract()\n    {\n        return $this->hasOneThrough(FakeRelationship::class, FakeRelationship::class);\n    }\n\n    public function tags()\n    {\n        return $this->morphToMany(FakeRelationship::class, 'taggable');\n    }\n\n    public function postable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass CustomPost extends Post\n{\n    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)\n    {\n        return new CustomBelongsTo($query, $child, $foreignKey, $ownerKey, $relation);\n    }\n\n    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)\n    {\n        return new CustomHasMany($query, $parent, $foreignKey, $localKey);\n    }\n\n    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)\n    {\n        return new CustomHasOne($query, $parent, $foreignKey, $localKey);\n    }\n\n    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)\n    {\n        return new CustomMorphOne($query, $parent, $type, $id, $localKey);\n    }\n\n    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)\n    {\n        return new CustomMorphMany($query, $parent, $type, $id, $localKey);\n    }\n\n    protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey,\n        $parentKey, $relatedKey, $relationName = null\n    ) {\n        return new CustomBelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);\n    }\n\n    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey,\n        $secondKey, $localKey, $secondLocalKey\n    ) {\n        return new CustomHasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);\n    }\n\n    protected function newHasOneThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey,\n        $secondKey, $localKey, $secondLocalKey\n    ) {\n        return new CustomHasOneThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);\n    }\n\n    protected function newMorphToMany(Builder $query, Model $parent, $name, $table, $foreignPivotKey,\n        $relatedPivotKey, $parentKey, $relatedKey, $relationName = null, $inverse = false)\n    {\n        return new CustomMorphToMany($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey,\n            $relationName, $inverse);\n    }\n\n    protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)\n    {\n        return new CustomMorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);\n    }\n}\n\nclass CustomHasOne extends HasOne\n{\n    //\n}\n\nclass CustomBelongsTo extends BelongsTo\n{\n    //\n}\n\nclass CustomHasMany extends HasMany\n{\n    //\n}\n\nclass CustomMorphOne extends MorphOne\n{\n    //\n}\n\nclass CustomMorphMany extends MorphMany\n{\n    //\n}\n\nclass CustomBelongsToMany extends BelongsToMany\n{\n    //\n}\n\nclass CustomHasManyThrough extends HasManyThrough\n{\n    //\n}\n\nclass CustomHasOneThrough extends HasOneThrough\n{\n    //\n}\n\nclass CustomMorphToMany extends MorphToMany\n{\n    //\n}\n\nclass CustomMorphTo extends MorphTo\n{\n    //\n}\n\nclass MockedConnectionModel extends Model\n{\n    public function getConnection()\n    {\n        $mock = m::mock(Connection::class);\n        $mock->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class));\n        $grammar->shouldReceive('getBitwiseOperators')->andReturn([]);\n        $mock->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class));\n        $mock->shouldReceive('getName')->andReturn('name');\n        $mock->shouldReceive('query')->andReturnUsing(function () use ($mock, $grammar, $processor) {\n            return new BaseBuilder($mock, $grammar, $processor);\n        });\n\n        return $mock;\n    }\n}\n\nclass Car extends MockedConnectionModel\n{\n    public function owner()\n    {\n        return $this->hasOne(Owner::class, 'car_id', 'c_id');\n    }\n}\n\nclass Owner extends MockedConnectionModel\n{\n    //\n}\n\nclass FluentMechanic extends MockedConnectionModel\n{\n    public function owner()\n    {\n        return $this->through($this->car())\n            ->has(fn (Car $car) => $car->owner());\n    }\n\n    public function car()\n    {\n        return $this->hasOne(Car::class, 'mechanic_id', 'm_id');\n    }\n}\n\nclass ClassicMechanic extends MockedConnectionModel\n{\n    public function owner()\n    {\n        return $this->hasOneThrough(Owner::class, Car::class, 'mechanic_id', 'car_id', 'm_id', 'c_id');\n    }\n}\n\nclass ClassicProject extends MockedConnectionModel\n{\n    public function deployments()\n    {\n        return $this->hasManyThrough(\n            Deployment::class,\n            Environment::class,\n            'pro_id',\n            'env_id',\n            'p_id',\n            'e_id',\n        );\n    }\n\n    public function environmentData()\n    {\n        return $this->hasManyThrough(\n            Metadata::class,\n            Environment::class,\n            'pro_id',\n            'env_id',\n            'p_id',\n            'e_id',\n        );\n    }\n}\n\nclass FluentProject extends MockedConnectionModel\n{\n    public function deployments()\n    {\n        return $this->through($this->environments())->has(fn (Environment $env) => $env->deployments());\n    }\n\n    public function environmentData()\n    {\n        return $this->through($this->environments())->has(fn (Environment $env) => $env->metadata());\n    }\n\n    public function environments()\n    {\n        return $this->hasMany(Environment::class, 'pro_id', 'p_id');\n    }\n}\n\nclass Environment extends MockedConnectionModel\n{\n    public function deployments()\n    {\n        return $this->hasMany(Deployment::class, 'env_id', 'e_id');\n    }\n\n    public function metadata()\n    {\n        return $this->hasOne(MetaData::class, 'env_id', 'e_id');\n    }\n}\n\nclass MetaData extends MockedConnectionModel\n{\n    //\n}\n\nclass Deployment extends MockedConnectionModel\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentResourceCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceCollectionTestModel;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModelWithUseResourceAttribute;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModelWithUseResourceCollectionAttribute;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceCollectionTestResource;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceTestJsonResource;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceTestJsonResourceCollection;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentResourceCollectionTest extends TestCase\n{\n    public function testItCanTransformToExplicitResource()\n    {\n        $collection = new Collection([\n            new EloquentResourceCollectionTestModel(),\n        ]);\n\n        $resource = $collection->toResourceCollection(EloquentResourceCollectionTestResource::class);\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n\n    public function testItThrowsExceptionWhenResourceCannotBeFound()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Failed to find resource class for model [Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceCollectionTestModel].');\n\n        $collection = new Collection([\n            new EloquentResourceCollectionTestModel(),\n        ]);\n        $collection->toResourceCollection();\n    }\n\n    public function testItCanGuessResourceWhenNotProvided()\n    {\n        $collection = new Collection([\n            new EloquentResourceCollectionTestModel(),\n        ]);\n\n        class_alias(EloquentResourceCollectionTestResource::class, 'Illuminate\\Tests\\Database\\Fixtures\\Http\\Resources\\EloquentResourceCollectionTestModelResource');\n\n        $resource = $collection->toResourceCollection();\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n\n    public function testItCanTransformToResourceViaUseResourceAttribute()\n    {\n        $collection = new Collection([\n            new EloquentResourceTestResourceModelWithUseResourceCollectionAttribute(),\n        ]);\n\n        $resource = $collection->toResourceCollection();\n\n        $this->assertInstanceOf(EloquentResourceTestJsonResourceCollection::class, $resource);\n    }\n\n    public function testItCanTransformToResourceViaUseResourceCollectionAttribute()\n    {\n        $collection = new Collection([\n            new EloquentResourceTestResourceModelWithUseResourceAttribute(),\n        ]);\n\n        $resource = $collection->toResourceCollection();\n\n        $this->assertInstanceOf(AnonymousResourceCollection::class, $resource);\n        $this->assertInstanceOf(EloquentResourceTestJsonResource::class, $resource[0]);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentResourceModelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModel;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModelWithGuessableResource;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModelWithUseResourceAttribute;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceTestJsonResource;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentResourceModelTest extends TestCase\n{\n    public function testItCanTransformToExplicitResource()\n    {\n        $model = new EloquentResourceTestResourceModel();\n        $resource = $model->toResource(EloquentResourceTestJsonResource::class);\n\n        $this->assertInstanceOf(EloquentResourceTestJsonResource::class, $resource);\n        $this->assertSame($model, $resource->resource);\n    }\n\n    public function testItThrowsExceptionWhenResourceCannotBeFound()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Failed to find resource class for model [Illuminate\\Tests\\Database\\Fixtures\\Models\\EloquentResourceTestResourceModel].');\n\n        $model = new EloquentResourceTestResourceModel();\n        $model->toResource();\n    }\n\n    public function testItCanGuessResourceWhenNotProvided()\n    {\n        $model = new EloquentResourceTestResourceModelWithGuessableResource();\n\n        class_alias(EloquentResourceTestJsonResource::class, 'Illuminate\\Tests\\Database\\Fixtures\\Http\\Resources\\EloquentResourceTestResourceModelWithGuessableResourceResource');\n\n        $resource = $model->toResource();\n\n        $this->assertInstanceOf(EloquentResourceTestJsonResource::class, $resource);\n        $this->assertSame($model, $resource->resource);\n    }\n\n    public function testItCanGuessResourceWhenNotProvidedWithNonResourceSuffix()\n    {\n        $model = new EloquentResourceTestResourceModelWithGuessableResource();\n\n        class_alias(EloquentResourceTestJsonResource::class, 'Illuminate\\Tests\\Database\\Fixtures\\Http\\Resources\\EloquentResourceTestResourceModelWithGuessableResource');\n\n        $resource = $model->toResource();\n\n        $this->assertInstanceOf(EloquentResourceTestJsonResource::class, $resource);\n        $this->assertSame($model, $resource->resource);\n    }\n\n    public function testItCanGuessResourceName()\n    {\n        $model = new EloquentResourceTestResourceModel();\n        $this->assertEquals([\n            'Illuminate\\Tests\\Database\\Fixtures\\Http\\Resources\\EloquentResourceTestResourceModelResource',\n            'Illuminate\\Tests\\Database\\Fixtures\\Http\\Resources\\EloquentResourceTestResourceModel',\n        ], $model::guessResourceName());\n    }\n\n    public function testItCanTransformToResourceViaUseResourceAttribute()\n    {\n        $model = new EloquentResourceTestResourceModelWithUseResourceAttribute();\n\n        $resource = $model->toResource();\n\n        $this->assertInstanceOf(EloquentResourceTestJsonResource::class, $resource);\n        $this->assertSame($model, $resource->resource);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentSoftDeletesIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse BadMethodCallException;\nuse Exception;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Eloquent\\SoftDeletingScope;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Pagination\\Paginator;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentSoftDeletesIntegrationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id')->nullable(); // circular reference to parent User\n            $table->integer('group_id')->nullable();\n            $table->string('email')->unique();\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('posts', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->string('title');\n            $table->integer('priority')->default(0);\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('comments', function ($table) {\n            $table->increments('id');\n            $table->integer('owner_id')->nullable();\n            $table->string('owner_type')->nullable();\n            $table->integer('post_id');\n            $table->string('body');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('addresses', function ($table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->string('address');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        $this->schema()->create('groups', function ($table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        $this->schema()->drop('users');\n        $this->schema()->drop('posts');\n        $this->schema()->drop('comments');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Tests...\n     */\n    public function testSoftDeletesAreNotRetrieved()\n    {\n        $this->createUsers();\n\n        $users = SoftDeletesTestUser::all();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(2, $users->first()->id);\n        $this->assertNull(SoftDeletesTestUser::find(1));\n    }\n\n    public function testSoftDeletesAreNotRetrievedFromBaseQuery()\n    {\n        $this->createUsers();\n\n        $query = SoftDeletesTestUser::query()->toBase();\n\n        $this->assertInstanceOf(Builder::class, $query);\n        $this->assertCount(1, $query->get());\n    }\n\n    public function testSoftDeletesAreNotRetrievedFromRelationshipBaseQuery()\n    {\n        [, $abigail] = $this->createUsers();\n\n        $abigail->posts()->create(['title' => 'Foo']);\n        $abigail->posts()->create(['title' => 'Bar'])->delete();\n\n        $query = $abigail->posts()->toBase();\n\n        $this->assertInstanceOf(Builder::class, $query);\n        $this->assertCount(1, $query->get());\n    }\n\n    public function testSoftDeletesAreNotRetrievedFromBuilderHelpers()\n    {\n        $this->createUsers();\n\n        $count = 0;\n        $query = SoftDeletesTestUser::query();\n        $query->chunk(2, function ($user) use (&$count) {\n            $count += count($user);\n        });\n        $this->assertEquals(1, $count);\n\n        $query = SoftDeletesTestUser::query();\n        $this->assertCount(1, $query->pluck('email')->all());\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n\n        CursorPaginator::currentCursorResolver(function () {\n            return null;\n        });\n\n        $query = SoftDeletesTestUser::query();\n        $this->assertCount(1, $query->paginate(2)->all());\n\n        $query = SoftDeletesTestUser::query();\n        $this->assertCount(1, $query->simplePaginate(2)->all());\n\n        $query = SoftDeletesTestUser::query();\n        $this->assertCount(1, $query->cursorPaginate(2)->all());\n\n        $this->assertEquals(0, SoftDeletesTestUser::where('email', 'taylorotwell@gmail.com')->increment('id'));\n        $this->assertEquals(0, SoftDeletesTestUser::where('email', 'taylorotwell@gmail.com')->decrement('id'));\n    }\n\n    public function testWithTrashedReturnsAllRecords()\n    {\n        $this->createUsers();\n\n        $this->assertCount(2, SoftDeletesTestUser::withTrashed()->get());\n        $this->assertInstanceOf(Eloquent::class, SoftDeletesTestUser::withTrashed()->find(1));\n    }\n\n    public function testWithTrashedAcceptsAnArgument()\n    {\n        $this->createUsers();\n\n        $this->assertCount(1, SoftDeletesTestUser::withTrashed(false)->get());\n        $this->assertCount(2, SoftDeletesTestUser::withTrashed(true)->get());\n    }\n\n    public function testDeleteSetsDeletedColumn()\n    {\n        $this->createUsers();\n\n        $this->assertInstanceOf(Carbon::class, SoftDeletesTestUser::withTrashed()->find(1)->deleted_at);\n        $this->assertNull(SoftDeletesTestUser::find(2)->deleted_at);\n    }\n\n    public function testForceDeleteActuallyDeletesRecords()\n    {\n        $this->createUsers();\n        SoftDeletesTestUser::find(2)->forceDelete();\n\n        $users = SoftDeletesTestUser::withTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(1, $users->first()->id);\n    }\n\n    public function testForceDeleteUpdateExistsProperty()\n    {\n        $this->createUsers();\n        $user = SoftDeletesTestUser::find(2);\n\n        $this->assertTrue($user->exists);\n\n        $user->forceDelete();\n\n        $this->assertFalse($user->exists);\n    }\n\n    public function testForceDeleteDoesntUpdateExistsPropertyIfFailed()\n    {\n        $user = new class() extends SoftDeletesTestUser\n        {\n            public $exists = true;\n\n            public function newModelQuery()\n            {\n                return m::spy(parent::newModelQuery(), function (MockInterface $mock) {\n                    $mock->shouldReceive('forceDelete')->andThrow(new Exception());\n                });\n            }\n        };\n\n        $this->assertTrue($user->exists);\n\n        try {\n            $user->forceDelete();\n        } catch (Exception) {\n        }\n\n        $this->assertTrue($user->exists);\n    }\n\n    public function testForceDestroyFullyDeletesRecord()\n    {\n        $this->createUsers();\n        $deleted = SoftDeletesTestUser::forceDestroy(2);\n\n        $this->assertSame(1, $deleted);\n\n        $users = SoftDeletesTestUser::withTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(1, $users->first()->id);\n        $this->assertNull(SoftDeletesTestUser::find(2));\n    }\n\n    public function testForceDestroyDeletesAlreadyDeletedRecord()\n    {\n        $this->createUsers();\n        $deleted = SoftDeletesTestUser::forceDestroy(1);\n\n        $this->assertSame(1, $deleted);\n\n        $users = SoftDeletesTestUser::withTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(2, $users->first()->id);\n        $this->assertNull(SoftDeletesTestUser::find(1));\n    }\n\n    public function testForceDestroyDeletesMultipleRecords()\n    {\n        $this->createUsers();\n        $deleted = SoftDeletesTestUser::forceDestroy([1, 2]);\n\n        $this->assertSame(2, $deleted);\n\n        $this->assertTrue(SoftDeletesTestUser::withTrashed()->get()->isEmpty());\n    }\n\n    public function testForceDestroyDeletesRecordsFromCollection()\n    {\n        $this->createUsers();\n        $deleted = SoftDeletesTestUser::forceDestroy(collect([1, 2]));\n\n        $this->assertSame(2, $deleted);\n\n        $this->assertTrue(SoftDeletesTestUser::withTrashed()->get()->isEmpty());\n    }\n\n    public function testForceDestroyDeletesRecordsFromEloquentCollection()\n    {\n        $this->createUsers();\n        $deleted = SoftDeletesTestUser::forceDestroy(SoftDeletesTestUser::all());\n\n        $this->assertSame(1, $deleted);\n\n        $users = SoftDeletesTestUser::withTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(1, $users->first()->id);\n        $this->assertNull(SoftDeletesTestUser::find(2));\n    }\n\n    public function testRestoreRestoresRecords()\n    {\n        $this->createUsers();\n        $taylor = SoftDeletesTestUser::withTrashed()->find(1);\n\n        $this->assertTrue($taylor->trashed());\n\n        $taylor->restore();\n\n        $users = SoftDeletesTestUser::all();\n\n        $this->assertCount(2, $users);\n        $this->assertNull($users->find(1)->deleted_at);\n        $this->assertNull($users->find(2)->deleted_at);\n    }\n\n    public function testOnlyTrashedOnlyReturnsTrashedRecords()\n    {\n        $this->createUsers();\n\n        $users = SoftDeletesTestUser::onlyTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(1, $users->first()->id);\n    }\n\n    public function testOnlyWithoutTrashedOnlyReturnsTrashedRecords()\n    {\n        $this->createUsers();\n\n        $users = SoftDeletesTestUser::withoutTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(2, $users->first()->id);\n\n        $users = SoftDeletesTestUser::withTrashed()->withoutTrashed()->get();\n\n        $this->assertCount(1, $users);\n        $this->assertEquals(2, $users->first()->id);\n    }\n\n    public function testFirstOrNew()\n    {\n        $this->createUsers();\n\n        $result = SoftDeletesTestUser::firstOrNew(['email' => 'taylorotwell@gmail.com']);\n        $this->assertNull($result->id);\n\n        $result = SoftDeletesTestUser::withTrashed()->firstOrNew(['email' => 'taylorotwell@gmail.com']);\n        $this->assertEquals(1, $result->id);\n    }\n\n    public function testFindOrNew()\n    {\n        $this->createUsers();\n\n        $result = SoftDeletesTestUser::findOrNew(1);\n        $this->assertNull($result->id);\n\n        $result = SoftDeletesTestUser::withTrashed()->findOrNew(1);\n        $this->assertEquals(1, $result->id);\n    }\n\n    public function testFirstOrCreate()\n    {\n        $this->createUsers();\n\n        $result = SoftDeletesTestUser::withTrashed()->firstOrCreate(['email' => 'taylorotwell@gmail.com']);\n        $this->assertSame('taylorotwell@gmail.com', $result->email);\n        $this->assertCount(1, SoftDeletesTestUser::all());\n\n        $result = SoftDeletesTestUser::firstOrCreate(['email' => 'foo@bar.com']);\n        $this->assertSame('foo@bar.com', $result->email);\n        $this->assertCount(2, SoftDeletesTestUser::all());\n        $this->assertCount(3, SoftDeletesTestUser::withTrashed()->get());\n    }\n\n    public function testCreateOrFirst()\n    {\n        $this->createUsers();\n\n        $result = SoftDeletesTestUser::withTrashed()->createOrFirst(['email' => 'taylorotwell@gmail.com']);\n        $this->assertSame('taylorotwell@gmail.com', $result->email);\n        $this->assertCount(1, SoftDeletesTestUser::all());\n\n        $result = SoftDeletesTestUser::createOrFirst(['email' => 'foo@bar.com']);\n        $this->assertSame('foo@bar.com', $result->email);\n        $this->assertCount(2, SoftDeletesTestUser::all());\n        $this->assertCount(3, SoftDeletesTestUser::withTrashed()->get());\n    }\n\n    /**\n     * @throws \\Exception\n     */\n    public function testUpdateModelAfterSoftDeleting()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n        $this->createUsers();\n\n        /** @var \\Illuminate\\Tests\\Database\\SoftDeletesTestUser $userModel */\n        $userModel = SoftDeletesTestUser::find(2);\n        $userModel->delete();\n        $this->assertEquals($now->toDateTimeString(), $userModel->getOriginal('deleted_at'));\n        $this->assertNull(SoftDeletesTestUser::find(2));\n        $this->assertEquals($userModel, SoftDeletesTestUser::withTrashed()->find(2));\n    }\n\n    /**\n     * @throws \\Exception\n     */\n    public function testRestoreAfterSoftDelete()\n    {\n        $this->createUsers();\n\n        /** @var \\Illuminate\\Tests\\Database\\SoftDeletesTestUser $userModel */\n        $userModel = SoftDeletesTestUser::find(2);\n        $userModel->delete();\n        $userModel->restore();\n\n        $this->assertEquals($userModel->id, SoftDeletesTestUser::find(2)->id);\n    }\n\n    /**\n     * @throws \\Exception\n     */\n    public function testSoftDeleteAfterRestoring()\n    {\n        $this->createUsers();\n\n        /** @var \\Illuminate\\Tests\\Database\\SoftDeletesTestUser $userModel */\n        $userModel = SoftDeletesTestUser::withTrashed()->find(1);\n        $userModel->restore();\n        $this->assertEquals($userModel->deleted_at, SoftDeletesTestUser::find(1)->deleted_at);\n        $this->assertEquals($userModel->getOriginal('deleted_at'), SoftDeletesTestUser::find(1)->deleted_at);\n        $userModel->delete();\n        $this->assertNull(SoftDeletesTestUser::find(1));\n        $this->assertEquals($userModel->deleted_at, SoftDeletesTestUser::withTrashed()->find(1)->deleted_at);\n        $this->assertEquals($userModel->getOriginal('deleted_at'), SoftDeletesTestUser::withTrashed()->find(1)->deleted_at);\n    }\n\n    public function testModifyingBeforeSoftDeletingAndRestoring()\n    {\n        $this->createUsers();\n\n        /** @var \\Illuminate\\Tests\\Database\\SoftDeletesTestUser $userModel */\n        $userModel = SoftDeletesTestUser::find(2);\n        $userModel->email = 'foo@bar.com';\n        $userModel->delete();\n        $userModel->restore();\n\n        $this->assertEquals($userModel->id, SoftDeletesTestUser::find(2)->id);\n        $this->assertSame('foo@bar.com', SoftDeletesTestUser::find(2)->email);\n    }\n\n    public function testUpdateOrCreate()\n    {\n        $this->createUsers();\n\n        $result = SoftDeletesTestUser::updateOrCreate(['email' => 'foo@bar.com'], ['email' => 'bar@baz.com']);\n        $this->assertSame('bar@baz.com', $result->email);\n        $this->assertCount(2, SoftDeletesTestUser::all());\n\n        $result = SoftDeletesTestUser::withTrashed()->updateOrCreate(['email' => 'taylorotwell@gmail.com'], ['email' => 'foo@bar.com']);\n        $this->assertSame('foo@bar.com', $result->email);\n        $this->assertCount(2, SoftDeletesTestUser::all());\n        $this->assertCount(3, SoftDeletesTestUser::withTrashed()->get());\n    }\n\n    public function testHasOneRelationshipCanBeSoftDeleted()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $abigail->address()->create(['address' => 'Laravel avenue 43']);\n\n        // delete on builder\n        $abigail->address()->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->address);\n        $this->assertSame('Laravel avenue 43', $abigail->address()->withTrashed()->first()->address);\n\n        // restore\n        $abigail->address()->withTrashed()->restore();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertSame('Laravel avenue 43', $abigail->address->address);\n\n        // delete on model\n        $abigail->address->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->address);\n        $this->assertSame('Laravel avenue 43', $abigail->address()->withTrashed()->first()->address);\n\n        // force delete\n        $abigail->address()->withTrashed()->forceDelete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->address);\n    }\n\n    public function testBelongsToRelationshipCanBeSoftDeleted()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $group = SoftDeletesTestGroup::create(['name' => 'admin']);\n        $abigail->group()->associate($group);\n        $abigail->save();\n\n        // delete on builder\n        $abigail->group()->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->group);\n        $this->assertSame('admin', $abigail->group()->withTrashed()->first()->name);\n\n        // restore\n        $abigail->group()->withTrashed()->restore();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertSame('admin', $abigail->group->name);\n\n        // delete on model\n        $abigail->group->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->group);\n        $this->assertSame('admin', $abigail->group()->withTrashed()->first()->name);\n\n        // force delete\n        $abigail->group()->withTrashed()->forceDelete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertNull($abigail->group()->withTrashed()->first());\n    }\n\n    public function testHasManyRelationshipCanBeSoftDeleted()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $abigail->posts()->create(['title' => 'First Title']);\n        $abigail->posts()->create(['title' => 'Second Title']);\n\n        // delete on builder\n        $abigail->posts()->where('title', 'Second Title')->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertCount(1, $abigail->posts);\n        $this->assertSame('First Title', $abigail->posts->first()->title);\n        $this->assertCount(2, $abigail->posts()->withTrashed()->get());\n\n        // restore\n        $abigail->posts()->withTrashed()->restore();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertCount(2, $abigail->posts);\n\n        // force delete\n        $abigail->posts()->where('title', 'Second Title')->forceDelete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertCount(1, $abigail->posts);\n        $this->assertCount(1, $abigail->posts()->withTrashed()->get());\n    }\n\n    public function testRelationToSqlAppliesSoftDelete()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n\n        $this->assertSame(\n            'select * from \"posts\" where \"posts\".\"user_id\" = ? and \"posts\".\"user_id\" is not null and \"posts\".\"deleted_at\" is null',\n            $abigail->posts()->toSql()\n        );\n    }\n\n    public function testRelationExistsAndDoesntExistHonorsSoftDelete()\n    {\n        $this->createUsers();\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n\n        // 'exists' should return true before soft delete\n        $abigail->posts()->create(['title' => 'First Title']);\n        $this->assertTrue($abigail->posts()->exists());\n        $this->assertFalse($abigail->posts()->doesntExist());\n\n        // 'exists' should return false after soft delete\n        $abigail->posts()->first()->delete();\n        $this->assertFalse($abigail->posts()->exists());\n        $this->assertTrue($abigail->posts()->doesntExist());\n\n        // 'exists' should return true after restore\n        $abigail->posts()->withTrashed()->restore();\n        $this->assertTrue($abigail->posts()->exists());\n        $this->assertFalse($abigail->posts()->doesntExist());\n\n        // 'exists' should return false after a force delete\n        $abigail->posts()->first()->forceDelete();\n        $this->assertFalse($abigail->posts()->exists());\n        $this->assertTrue($abigail->posts()->doesntExist());\n    }\n\n    public function testRelationCountHonorsSoftDelete()\n    {\n        $this->createUsers();\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n\n        // check count before soft delete\n        $abigail->posts()->create(['title' => 'First Title']);\n        $abigail->posts()->create(['title' => 'Second Title']);\n        $this->assertEquals(2, $abigail->posts()->count());\n\n        // check count after soft delete\n        $abigail->posts()->where('title', 'Second Title')->delete();\n        $this->assertEquals(1, $abigail->posts()->count());\n\n        // check count after restore\n        $abigail->posts()->withTrashed()->restore();\n        $this->assertEquals(2, $abigail->posts()->count());\n\n        // check count after a force delete\n        $abigail->posts()->where('title', 'Second Title')->forceDelete();\n        $this->assertEquals(1, $abigail->posts()->count());\n    }\n\n    public function testRelationAggregatesHonorsSoftDelete()\n    {\n        $this->createUsers();\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n\n        // check aggregates before soft delete\n        $abigail->posts()->create(['title' => 'First Title', 'priority' => 2]);\n        $abigail->posts()->create(['title' => 'Second Title', 'priority' => 4]);\n        $abigail->posts()->create(['title' => 'Third Title', 'priority' => 6]);\n        $this->assertEquals(2, $abigail->posts()->min('priority'));\n        $this->assertEquals(6, $abigail->posts()->max('priority'));\n        $this->assertEquals(12, $abigail->posts()->sum('priority'));\n        $this->assertEquals(4, $abigail->posts()->avg('priority'));\n\n        // check aggregates after soft delete\n        $abigail->posts()->where('title', 'First Title')->delete();\n        $this->assertEquals(4, $abigail->posts()->min('priority'));\n        $this->assertEquals(6, $abigail->posts()->max('priority'));\n        $this->assertEquals(10, $abigail->posts()->sum('priority'));\n        $this->assertEquals(5, $abigail->posts()->avg('priority'));\n\n        // check aggregates after restore\n        $abigail->posts()->withTrashed()->restore();\n        $this->assertEquals(2, $abigail->posts()->min('priority'));\n        $this->assertEquals(6, $abigail->posts()->max('priority'));\n        $this->assertEquals(12, $abigail->posts()->sum('priority'));\n        $this->assertEquals(4, $abigail->posts()->avg('priority'));\n\n        // check aggregates after a force delete\n        $abigail->posts()->where('title', 'Third Title')->forceDelete();\n        $this->assertEquals(2, $abigail->posts()->min('priority'));\n        $this->assertEquals(4, $abigail->posts()->max('priority'));\n        $this->assertEquals(6, $abigail->posts()->sum('priority'));\n        $this->assertEquals(3, $abigail->posts()->avg('priority'));\n    }\n\n    public function testSoftDeleteIsAppliedToNewQuery()\n    {\n        $query = (new SoftDeletesTestUser)->newQuery();\n        $this->assertSame('select * from \"users\" where \"users\".\"deleted_at\" is null', $query->toSql());\n    }\n\n    public function testSecondLevelRelationshipCanBeSoftDeleted()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post = $abigail->posts()->create(['title' => 'First Title']);\n        $post->comments()->create(['body' => 'Comment Body']);\n\n        $abigail->posts()->first()->comments()->delete();\n\n        $abigail = $abigail->fresh();\n\n        $this->assertCount(0, $abigail->posts()->first()->comments);\n        $this->assertCount(1, $abigail->posts()->first()->comments()->withTrashed()->get());\n    }\n\n    public function testWhereHasWithDeletedRelationship()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post = $abigail->posts()->create(['title' => 'First Title']);\n\n        $users = SoftDeletesTestUser::where('email', 'taylorotwell@gmail.com')->has('posts')->get();\n        $this->assertCount(0, $users);\n\n        $users = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->has('posts')->get();\n        $this->assertCount(1, $users);\n\n        $users = SoftDeletesTestUser::where('email', 'doesnt@exist.com')->orHas('posts')->get();\n        $this->assertCount(1, $users);\n\n        $users = SoftDeletesTestUser::whereHas('posts', function ($query) {\n            $query->where('title', 'First Title');\n        })->get();\n        $this->assertCount(1, $users);\n\n        $users = SoftDeletesTestUser::whereHas('posts', function ($query) {\n            $query->where('title', 'Another Title');\n        })->get();\n        $this->assertCount(0, $users);\n\n        $users = SoftDeletesTestUser::where('email', 'doesnt@exist.com')->orWhereHas('posts', function ($query) {\n            $query->where('title', 'First Title');\n        })->get();\n        $this->assertCount(1, $users);\n\n        // With Post Deleted...\n\n        $post->delete();\n        $users = SoftDeletesTestUser::has('posts')->get();\n        $this->assertCount(0, $users);\n    }\n\n    public function testWhereHasWithNestedDeletedRelationshipAndOnlyTrashedCondition()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post = $abigail->posts()->create(['title' => 'First Title']);\n        $post->delete();\n\n        $users = SoftDeletesTestUser::has('posts')->get();\n        $this->assertCount(0, $users);\n\n        $users = SoftDeletesTestUser::whereHas('posts', function ($q) {\n            $q->onlyTrashed();\n        })->get();\n        $this->assertCount(1, $users);\n\n        $users = SoftDeletesTestUser::whereHas('posts', function ($q) {\n            $q->withTrashed();\n        })->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testWhereHasWithNestedDeletedRelationship()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post = $abigail->posts()->create(['title' => 'First Title']);\n        $comment = $post->comments()->create(['body' => 'Comment Body']);\n        $comment->delete();\n\n        $users = SoftDeletesTestUser::has('posts.comments')->get();\n        $this->assertCount(0, $users);\n\n        $users = SoftDeletesTestUser::doesntHave('posts.comments')->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testWhereDoesntHaveWithNestedDeletedRelationship()\n    {\n        $this->createUsers();\n\n        $users = SoftDeletesTestUser::doesntHave('posts.comments')->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testWhereHasWithNestedDeletedRelationshipAndWithTrashedCondition()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUserWithTrashedPosts::where('email', 'abigailotwell@gmail.com')->first();\n        $post = $abigail->posts()->create(['title' => 'First Title']);\n        $post->delete();\n\n        $users = SoftDeletesTestUserWithTrashedPosts::has('posts')->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testWithCountWithNestedDeletedRelationshipAndOnlyTrashedCondition()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post1 = $abigail->posts()->create(['title' => 'First Title']);\n        $post1->delete();\n        $abigail->posts()->create(['title' => 'Second Title']);\n        $abigail->posts()->create(['title' => 'Third Title']);\n\n        $user = SoftDeletesTestUser::withCount('posts')->orderBy('postsCount', 'desc')->first();\n        $this->assertEquals(2, $user->posts_count);\n\n        $user = SoftDeletesTestUser::withCount(['posts' => function ($q) {\n            $q->onlyTrashed();\n        }])->orderBy('postsCount', 'desc')->first();\n        $this->assertEquals(1, $user->posts_count);\n\n        $user = SoftDeletesTestUser::withCount(['posts' => function ($q) {\n            $q->withTrashed();\n        }])->orderBy('postsCount', 'desc')->first();\n        $this->assertEquals(3, $user->posts_count);\n\n        $user = SoftDeletesTestUser::withCount(['posts' => function ($q) {\n            $q->withTrashed()->where('title', 'First Title');\n        }])->orderBy('postsCount', 'desc')->first();\n        $this->assertEquals(1, $user->posts_count);\n\n        $user = SoftDeletesTestUser::withCount(['posts' => function ($q) {\n            $q->where('title', 'First Title');\n        }])->orderBy('postsCount', 'desc')->first();\n        $this->assertEquals(0, $user->posts_count);\n    }\n\n    public function testOrWhereWithSoftDeleteConstraint()\n    {\n        $this->createUsers();\n\n        $users = SoftDeletesTestUser::where('email', 'taylorotwell@gmail.com')->orWhere('email', 'abigailotwell@gmail.com');\n        $this->assertEquals(['abigailotwell@gmail.com'], $users->pluck('email')->all());\n    }\n\n    public function testMorphToWithTrashed()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post1 = $abigail->posts()->create(['title' => 'First Title']);\n        $post1->comments()->create([\n            'body' => 'Comment Body',\n            'owner_type' => SoftDeletesTestUser::class,\n            'owner_id' => $abigail->id,\n        ]);\n\n        $abigail->delete();\n\n        $comment = SoftDeletesTestCommentWithTrashed::with(['owner' => function ($q) {\n            $q->withoutGlobalScope(SoftDeletingScope::class);\n        }])->first();\n\n        $this->assertEquals($abigail->email, $comment->owner->email);\n\n        $comment = SoftDeletesTestCommentWithTrashed::with(['owner' => function ($q) {\n            $q->withTrashed();\n        }])->first();\n\n        $this->assertEquals($abigail->email, $comment->owner->email);\n\n        $comment = TestCommentWithoutSoftDelete::with(['owner' => function ($q) {\n            $q->withTrashed();\n        }])->first();\n\n        $this->assertEquals($abigail->email, $comment->owner->email);\n    }\n\n    public function testMorphToWithBadMethodCall()\n    {\n        $this->expectException(BadMethodCallException::class);\n\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post1 = $abigail->posts()->create(['title' => 'First Title']);\n\n        $post1->comments()->create([\n            'body' => 'Comment Body',\n            'owner_type' => SoftDeletesTestUser::class,\n            'owner_id' => $abigail->id,\n        ]);\n\n        TestCommentWithoutSoftDelete::with(['owner' => function ($q) {\n            $q->thisMethodDoesNotExist();\n        }])->first();\n    }\n\n    public function testMorphToWithConstraints()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post1 = $abigail->posts()->create(['title' => 'First Title']);\n        $post1->comments()->create([\n            'body' => 'Comment Body',\n            'owner_type' => SoftDeletesTestUser::class,\n            'owner_id' => $abigail->id,\n        ]);\n\n        $comment = SoftDeletesTestCommentWithTrashed::with(['owner' => function ($q) {\n            $q->where('email', 'taylorotwell@gmail.com');\n        }])->first();\n\n        $this->assertNull($comment->owner);\n    }\n\n    public function testMorphToWithoutConstraints()\n    {\n        $this->createUsers();\n\n        $abigail = SoftDeletesTestUser::where('email', 'abigailotwell@gmail.com')->first();\n        $post1 = $abigail->posts()->create(['title' => 'First Title']);\n        $post1->comments()->create([\n            'body' => 'Comment Body',\n            'owner_type' => SoftDeletesTestUser::class,\n            'owner_id' => $abigail->id,\n        ]);\n\n        $comment = SoftDeletesTestCommentWithTrashed::with('owner')->first();\n\n        $this->assertEquals($abigail->email, $comment->owner->email);\n\n        $abigail->delete();\n        $comment = SoftDeletesTestCommentWithTrashed::with('owner')->first();\n\n        $this->assertNull($comment->owner);\n    }\n\n    public function testMorphToNonSoftDeletingModel()\n    {\n        $taylor = TestUserWithoutSoftDelete::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);\n        $post1 = $taylor->posts()->create(['title' => 'First Title']);\n        $post1->comments()->create([\n            'body' => 'Comment Body',\n            'owner_type' => TestUserWithoutSoftDelete::class,\n            'owner_id' => $taylor->id,\n        ]);\n\n        $comment = SoftDeletesTestCommentWithTrashed::with('owner')->first();\n\n        $this->assertEquals($taylor->email, $comment->owner->email);\n\n        $taylor->delete();\n        $comment = SoftDeletesTestCommentWithTrashed::with('owner')->first();\n\n        $this->assertNull($comment->owner);\n    }\n\n    public function testSelfReferencingRelationshipWithSoftDeletes()\n    {\n        // https://github.com/laravel/framework/issues/42075\n        [$taylor, $abigail] = $this->createUsers();\n\n        $this->assertCount(1, $abigail->self_referencing);\n        $this->assertTrue($abigail->self_referencing->first()->is($taylor));\n\n        $this->assertCount(0, $taylor->self_referencing);\n        $this->assertEquals(1, SoftDeletesTestUser::whereHas('self_referencing')->count());\n    }\n\n    /**\n     * Helpers...\n     *\n     * @return \\Illuminate\\Tests\\Database\\SoftDeletesTestUser[]\n     */\n    protected function createUsers()\n    {\n        $taylor = SoftDeletesTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com', 'user_id' => 2]);\n        $abigail = SoftDeletesTestUser::create(['id' => 2, 'email' => 'abigailotwell@gmail.com']);\n\n        $taylor->delete();\n\n        return [$taylor, $abigail];\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass TestUserWithoutSoftDelete extends Eloquent\n{\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(SoftDeletesTestPost::class, 'user_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass SoftDeletesTestUser extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function self_referencing()\n    {\n        return $this->hasMany(SoftDeletesTestUser::class, 'user_id')->onlyTrashed();\n    }\n\n    public function posts()\n    {\n        return $this->hasMany(SoftDeletesTestPost::class, 'user_id');\n    }\n\n    public function address()\n    {\n        return $this->hasOne(SoftDeletesTestAddress::class, 'user_id');\n    }\n\n    public function group()\n    {\n        return $this->belongsTo(SoftDeletesTestGroup::class, 'group_id');\n    }\n}\n\nclass SoftDeletesTestUserWithTrashedPosts extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'users';\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(SoftDeletesTestPost::class, 'user_id')->withTrashed();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass SoftDeletesTestPost extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'posts';\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->hasMany(SoftDeletesTestComment::class, 'post_id');\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass TestCommentWithoutSoftDelete extends Eloquent\n{\n    protected $table = 'comments';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->morphTo();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass SoftDeletesTestComment extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'comments';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass SoftDeletesTestCommentWithTrashed extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'comments';\n    protected $guarded = [];\n\n    public function owner()\n    {\n        return $this->morphTo();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass SoftDeletesTestAddress extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'addresses';\n    protected $guarded = [];\n}\n\n/**\n * Eloquent Models...\n */\nclass SoftDeletesTestGroup extends Eloquent\n{\n    use SoftDeletes;\n\n    protected $table = 'groups';\n    protected $guarded = [];\n\n    public function users()\n    {\n        $this->hasMany(SoftDeletesTestUser::class);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentStrictMorphsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\ClassMorphViolationException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentStrictMorphsTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Relation::requireMorphMap();\n    }\n\n    public function testStrictModeThrowsAnExceptionOnClassMap()\n    {\n        $this->expectException(ClassMorphViolationException::class);\n\n        $model = new TestModel;\n\n        $model->getMorphClass();\n    }\n\n    public function testStrictModeDoesNotThrowExceptionWhenMorphMap()\n    {\n        $model = new TestModel;\n\n        Relation::morphMap([\n            'test' => TestModel::class,\n        ]);\n\n        $morphName = $model->getMorphClass();\n        $this->assertSame('test', $morphName);\n    }\n\n    public function testMapsCanBeEnforcedInOneMethod()\n    {\n        $model = new TestModel;\n\n        Relation::requireMorphMap(false);\n\n        Relation::enforceMorphMap([\n            'test' => TestModel::class,\n        ]);\n\n        $morphName = $model->getMorphClass();\n        $this->assertSame('test', $morphName);\n    }\n\n    public function testMapIgnoreGenericPivotClass()\n    {\n        $pivotModel = new Pivot();\n\n        $pivotModel->getMorphClass();\n    }\n\n    public function testMapCanBeEnforcedToCustomPivotClass()\n    {\n        $this->expectException(ClassMorphViolationException::class);\n\n        $pivotModel = new TestPivotModel();\n\n        $pivotModel->getMorphClass();\n    }\n\n    protected function tearDown(): void\n    {\n        Relation::morphMap([], false);\n        Relation::requireMorphMap(false);\n\n        parent::tearDown();\n    }\n}\n\nclass TestModel extends Model\n{\n}\n\nclass TestPivotModel extends Pivot\n{\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentTimestampsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass DatabaseEloquentTimestampsTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamps();\n        });\n\n        $this->schema()->create('users_created_at', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->string('created_at');\n        });\n\n        $this->schema()->create('users_updated_at', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->string('updated_at');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('users');\n        $this->schema()->drop('users_created_at');\n        $this->schema()->drop('users_updated_at');\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    /**\n     * Tests...\n     */\n    public function testUserWithCreatedAtAndUpdatedAt()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n\n        $user = UserWithCreatedAndUpdated::create([\n            'email' => 'test@test.com',\n        ]);\n\n        $this->assertEquals($now->toDateTimeString(), $user->created_at->toDateTimeString());\n        $this->assertEquals($now->toDateTimeString(), $user->updated_at->toDateTimeString());\n    }\n\n    public function testUserWithCreatedAt()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n\n        $user = UserWithCreated::create([\n            'email' => 'test@test.com',\n        ]);\n\n        $this->assertEquals($now->toDateTimeString(), $user->created_at->toDateTimeString());\n    }\n\n    public function testUserWithUpdatedAt()\n    {\n        Carbon::setTestNow($now = Carbon::now());\n\n        $user = UserWithUpdated::create([\n            'email' => 'test@test.com',\n        ]);\n\n        $this->assertEquals($now->toDateTimeString(), $user->updated_at->toDateTimeString());\n    }\n\n    public function testWithoutTimestamp()\n    {\n        Carbon::setTestNow($now = Carbon::now()->setYear(1995)->startOfYear());\n        $user = UserWithCreatedAndUpdated::create(['email' => 'foo@example.com']);\n        Carbon::setTestNow(Carbon::now()->addHour());\n\n        $this->assertTrue($user->usesTimestamps());\n\n        $user->withoutTimestamps(function () use ($user) {\n            $this->assertFalse($user->usesTimestamps());\n\n            $user->withoutTimestamps(function () use ($user) {\n                $this->assertFalse($user->usesTimestamps());\n            });\n\n            $this->assertFalse($user->usesTimestamps());\n            $user->update([\n                'email' => 'bar@example.com',\n            ]);\n        });\n\n        $this->assertTrue($user->usesTimestamps());\n        $this->assertTrue($now->equalTo($user->updated_at));\n        $this->assertSame('bar@example.com', $user->email);\n    }\n\n    public function testWithoutTimestampWhenAlreadyIgnoringTimestamps()\n    {\n        Carbon::setTestNow($now = Carbon::now()->setYear(1995)->startOfYear());\n        $user = UserWithCreatedAndUpdated::create(['email' => 'foo@example.com']);\n        Carbon::setTestNow(Carbon::now()->addHour());\n\n        $user->timestamps = false;\n\n        $this->assertFalse($user->usesTimestamps());\n\n        $user->withoutTimestamps(function () use ($user) {\n            $this->assertFalse($user->usesTimestamps());\n            $user->update([\n                'email' => 'bar@example.com',\n            ]);\n        });\n\n        $this->assertFalse($user->usesTimestamps());\n        $this->assertTrue($now->equalTo($user->updated_at));\n        $this->assertSame('bar@example.com', $user->email);\n    }\n\n    public function testWithoutTimestampRestoresWhenClosureThrowsException()\n    {\n        $user = UserWithCreatedAndUpdated::create(['email' => 'foo@example.com']);\n\n        $user->timestamps = true;\n\n        try {\n            $user->withoutTimestamps(function () use ($user) {\n                $this->assertFalse($user->usesTimestamps());\n                throw new RuntimeException();\n            });\n            $this->fail();\n        } catch (RuntimeException) {\n            //\n        }\n\n        $this->assertTrue($user->timestamps);\n    }\n\n    public function testWithoutTimestampsRespectsClasses()\n    {\n        $a = new UserWithCreatedAndUpdated();\n        $b = new UserWithCreatedAndUpdated();\n        $z = new UserWithUpdated();\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        Eloquent::withoutTimestamps(function () use ($a, $b, $z) {\n            $this->assertFalse($a->usesTimestamps());\n            $this->assertFalse($b->usesTimestamps());\n            $this->assertFalse($z->usesTimestamps());\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        UserWithCreatedAndUpdated::withoutTimestamps(function () use ($a, $b, $z) {\n            $this->assertFalse($a->usesTimestamps());\n            $this->assertFalse($b->usesTimestamps());\n            $this->assertTrue($z->usesTimestamps());\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        UserWithUpdated::withoutTimestamps(function () use ($a, $b, $z) {\n            $this->assertTrue($a->usesTimestamps());\n            $this->assertTrue($b->usesTimestamps());\n            $this->assertFalse($z->usesTimestamps());\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        Eloquent::withoutTimestampsOn([], function () use ($a, $b, $z) {\n            $this->assertTrue($a->usesTimestamps());\n            $this->assertTrue($b->usesTimestamps());\n            $this->assertTrue($z->usesTimestamps());\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        Eloquent::withoutTimestampsOn([UserWithCreatedAndUpdated::class], function () use ($a, $b, $z) {\n            $this->assertFalse($a->usesTimestamps());\n            $this->assertFalse($b->usesTimestamps());\n            $this->assertTrue($z->usesTimestamps());\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        Eloquent::withoutTimestampsOn([UserWithUpdated::class], function () use ($a, $b, $z) {\n            $this->assertTrue($a->usesTimestamps());\n            $this->assertTrue($b->usesTimestamps());\n            $this->assertFalse($z->usesTimestamps());\n            $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n\n        Eloquent::withoutTimestampsOn([UserWithCreatedAndUpdated::class, UserWithUpdated::class], function () use ($a, $b, $z) {\n            $this->assertFalse($a->usesTimestamps());\n            $this->assertFalse($b->usesTimestamps());\n            $this->assertFalse($z->usesTimestamps());\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n            $this->assertTrue(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n        });\n\n        $this->assertTrue($a->usesTimestamps());\n        $this->assertTrue($b->usesTimestamps());\n        $this->assertTrue($z->usesTimestamps());\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithCreatedAndUpdated::class));\n        $this->assertFalse(Eloquent::isIgnoringTimestamps(UserWithUpdated::class));\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass UserWithCreatedAndUpdated extends Eloquent\n{\n    protected $table = 'users';\n\n    protected $guarded = [];\n}\n\nclass UserWithCreated extends Eloquent\n{\n    public const UPDATED_AT = null;\n\n    protected $table = 'users_created_at';\n\n    protected $guarded = [];\n\n    protected $dateFormat = 'U';\n}\n\nclass UserWithUpdated extends Eloquent\n{\n    public const CREATED_AT = null;\n\n    protected $table = 'users_updated_at';\n\n    protected $guarded = [];\n\n    protected $dateFormat = 'U';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentWithAttributesPendingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Builder;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentWithAttributesPendingTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->dropIfExists((new PendingAttributesModel)->getTable());\n\n        parent::tearDown();\n    }\n\n    public function testAddsAttributes(): void\n    {\n        $key = 'a key';\n        $value = 'the value';\n\n        $query = PendingAttributesModel::query()\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $model = $query->make();\n\n        $this->assertSame($value, $model->$key);\n    }\n\n    public function testDoesNotAddWheres(): void\n    {\n        $key = 'a key';\n        $value = 'the value';\n\n        $query = PendingAttributesModel::query()\n            ->withAttributes([$key => $value], asConditions: false);\n\n        $wheres = $query->toBase()->wheres;\n\n        // Ensure no wheres exist\n        $this->assertEmpty($wheres);\n    }\n\n    public function testAddsWithCasts(): void\n    {\n        $query = PendingAttributesModel::query()\n            ->withAttributes([\n                'is_admin' => 1,\n                'first_name' => 'FIRST',\n                'last_name' => 'LAST',\n                'type' => PendingAttributesEnum::internal,\n            ], asConditions: false);\n\n        $model = $query->make();\n\n        $this->assertSame(true, $model->is_admin);\n        $this->assertSame('First', $model->first_name);\n        $this->assertSame('Last', $model->last_name);\n        $this->assertSame(PendingAttributesEnum::internal, $model->type);\n\n        $this->assertEqualsCanonicalizing([\n            'is_admin' => 1,\n            'first_name' => 'first',\n            'last_name' => 'last',\n            'type' => 'int',\n        ], $model->getAttributes());\n    }\n\n    public function testAddsWithCastsViaDb(): void\n    {\n        $this->bootTable();\n\n        $query = PendingAttributesModel::query()\n            ->withAttributes([\n                'is_admin' => 1,\n                'first_name' => 'FIRST',\n                'last_name' => 'LAST',\n                'type' => PendingAttributesEnum::internal,\n            ], asConditions: false);\n\n        $query->create();\n\n        $model = PendingAttributesModel::first();\n\n        $this->assertSame(true, $model->is_admin);\n        $this->assertSame('First', $model->first_name);\n        $this->assertSame('Last', $model->last_name);\n        $this->assertSame(PendingAttributesEnum::internal, $model->type);\n    }\n\n    protected function bootTable(): void\n    {\n        $this->schema()->create((new PendingAttributesModel)->getTable(), function ($table) {\n            $table->id();\n            $table->boolean('is_admin');\n            $table->string('first_name');\n            $table->string('last_name');\n            $table->string('type');\n            $table->timestamps();\n        });\n    }\n\n    protected function schema(): Builder\n    {\n        return PendingAttributesModel::getConnectionResolver()->connection()->getSchemaBuilder();\n    }\n}\n\nclass PendingAttributesModel extends Model\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'is_admin' => 'boolean',\n        'type' => PendingAttributesEnum::class,\n    ];\n\n    public function setFirstNameAttribute(string $value): void\n    {\n        $this->attributes['first_name'] = strtolower($value);\n    }\n\n    public function getFirstNameAttribute(?string $value): string\n    {\n        return ucfirst($value);\n    }\n\n    protected function lastName(): Attribute\n    {\n        return Attribute::make(\n            get: fn (string $value) => ucfirst($value),\n            set: fn (string $value) => strtolower($value),\n        );\n    }\n}\n\nenum PendingAttributesEnum: string\n{\n    case internal = 'int';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentWithAttributesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Builder;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentWithAttributesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->schema()->dropIfExists((new WithAttributesModel)->getTable());\n\n        parent::tearDown();\n    }\n\n    public function testAddsAttributes(): void\n    {\n        $key = 'a key';\n        $value = 'the value';\n\n        $query = WithAttributesModel::query()\n            ->withAttributes([$key => $value]);\n\n        $model = $query->make();\n\n        $this->assertSame($value, $model->$key);\n    }\n\n    public function testAddsWheres(): void\n    {\n        $key = 'a key';\n        $value = 'the value';\n\n        $query = WithAttributesModel::query()\n            ->withAttributes([$key => $value]);\n\n        $wheres = $query->toBase()->wheres;\n\n        $this->assertContains([\n            'type' => 'Basic',\n            'column' => 'with_attributes_models.'.$key,\n            'operator' => '=',\n            'value' => $value,\n            'boolean' => 'and',\n        ], $wheres);\n    }\n\n    public function testAddsWithCasts(): void\n    {\n        $query = WithAttributesModel::query()\n            ->withAttributes([\n                'is_admin' => 1,\n                'first_name' => 'FIRST',\n                'last_name' => 'LAST',\n                'type' => WithAttributesEnum::internal,\n            ]);\n\n        $model = $query->make();\n\n        $this->assertSame(true, $model->is_admin);\n        $this->assertSame('First', $model->first_name);\n        $this->assertSame('Last', $model->last_name);\n        $this->assertSame(WithAttributesEnum::internal, $model->type);\n\n        $this->assertEqualsCanonicalizing([\n            'is_admin' => 1,\n            'first_name' => 'first',\n            'last_name' => 'last',\n            'type' => 'int',\n        ], $model->getAttributes());\n    }\n\n    public function testAddsWithCastsViaDb(): void\n    {\n        $this->bootTable();\n\n        $query = WithAttributesModel::query()\n            ->withAttributes([\n                'is_admin' => 1,\n                'first_name' => 'FIRST',\n                'last_name' => 'LAST',\n                'type' => WithAttributesEnum::internal,\n            ]);\n\n        $query->create();\n\n        $model = WithAttributesModel::first();\n\n        $this->assertSame(true, $model->is_admin);\n        $this->assertSame('First', $model->first_name);\n        $this->assertSame('Last', $model->last_name);\n        $this->assertSame(WithAttributesEnum::internal, $model->type);\n    }\n\n    protected function bootTable(): void\n    {\n        $this->schema()->create((new WithAttributesModel)->getTable(), function ($table) {\n            $table->id();\n            $table->boolean('is_admin');\n            $table->string('first_name');\n            $table->string('last_name');\n            $table->string('type');\n            $table->timestamps();\n        });\n    }\n\n    protected function schema(): Builder\n    {\n        return WithAttributesModel::getConnectionResolver()->connection()->getSchemaBuilder();\n    }\n}\n\nclass WithAttributesModel extends Model\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'is_admin' => 'boolean',\n        'type' => WithAttributesEnum::class,\n    ];\n\n    public function setFirstNameAttribute(string $value): void\n    {\n        $this->attributes['first_name'] = strtolower($value);\n    }\n\n    public function getFirstNameAttribute(?string $value): string\n    {\n        return ucfirst($value);\n    }\n\n    protected function lastName(): Attribute\n    {\n        return Attribute::make(\n            get: fn (string $value) => ucfirst($value),\n            set: fn (string $value) => strtolower($value),\n        );\n    }\n}\n\nenum WithAttributesEnum: string\n{\n    case internal = 'int';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseEloquentWithCastsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\MissingAttributeException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseEloquentWithCastsTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        $this->schema()->create('times', function ($table) {\n            $table->increments('id');\n            $table->time('time');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('unique_times', function ($table) {\n            $table->increments('id');\n            $table->time('time')->unique();\n            $table->timestamps();\n        });\n    }\n\n    public function testWithFirstOrNew()\n    {\n        $time1 = Time::query()->withCasts(['time' => 'string'])\n            ->firstOrNew(['time' => '07:30']);\n\n        Time::query()->insert(['time' => '07:30']);\n\n        $time2 = Time::query()->withCasts(['time' => 'string'])\n            ->firstOrNew(['time' => '07:30']);\n\n        $this->assertSame('07:30', $time1->time);\n        $this->assertSame($time1->time, $time2->time);\n    }\n\n    public function testWithFirstOrCreate()\n    {\n        $time1 = Time::query()->withCasts(['time' => 'string'])\n            ->firstOrCreate(['time' => '07:30']);\n\n        $time2 = Time::query()->withCasts(['time' => 'string'])\n            ->firstOrCreate(['time' => '07:30']);\n\n        $this->assertSame($time1->id, $time2->id);\n    }\n\n    public function testWithCreateOrFirst()\n    {\n        $time1 = UniqueTime::query()->withCasts(['time' => 'string'])\n            ->createOrFirst(['time' => '07:30']);\n\n        $time2 = UniqueTime::query()->withCasts(['time' => 'string'])\n            ->createOrFirst(['time' => '07:30']);\n\n        $this->assertSame($time1->id, $time2->id);\n    }\n\n    public function testThrowsExceptionIfCastableAttributeWasNotRetrievedAndPreventMissingAttributesIsEnabled()\n    {\n        Time::create(['time' => Carbon::now()]);\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n\n        $this->expectException(MissingAttributeException::class);\n        try {\n            $time = Time::query()->select('id')->first();\n            $this->assertNull($time->time);\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\nclass Time extends Eloquent\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'time' => 'datetime',\n    ];\n}\n\nclass UniqueTime extends Eloquent\n{\n    protected $guarded = [];\n\n    protected $casts = [\n        'time' => 'datetime',\n    ];\n}\n"
  },
  {
    "path": "tests/Database/DatabaseIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Events\\Dispatcher;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseIntegrationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->setAsGlobal();\n        $db->setEventDispatcher(new Dispatcher);\n    }\n\n    public function testQueryExecutedToRawSql(): void\n    {\n        $connection = DB::connection();\n\n        $connection->listen(function (QueryExecuted $query) use (&$queryExecuted): void {\n            $queryExecuted = $query;\n        });\n\n        $connection->select('select ?', [true]);\n\n        $this->assertInstanceOf(QueryExecuted::class, $queryExecuted);\n        $this->assertSame('select ?', $queryExecuted->sql);\n        $this->assertSame([true], $queryExecuted->bindings);\n        $this->assertSame('select 1', $queryExecuted->toRawSql());\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\Grammars\\MariaDbGrammar;\nuse Illuminate\\Database\\Schema\\MariaDbBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMariaDbBuilderTest extends TestCase\n{\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new MariaDbGrammar($connection);\n\n        $connection->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8mb4');\n        $connection->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8mb4_unicode_ci');\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'create database `my_temporary_database` default character set `utf8mb4` default collate `utf8mb4_unicode_ci`'\n        )->andReturn(true);\n\n        $builder = new MariaDbBuilder($connection);\n        $builder->createDatabase('my_temporary_database');\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new MariaDbGrammar($connection);\n\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'drop database if exists `my_database_a`'\n        )->andReturn(true);\n\n        $builder = new MariaDbBuilder($connection);\n\n        $builder->dropDatabaseIfExists('my_database_a');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbProcessorTest.php",
    "content": "<?php\n\nnamespace Database;\n\nuse Illuminate\\Database\\Query\\Processors\\MariaDbProcessor;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMariaDbProcessorTest extends TestCase\n{\n    public function testProcessColumns()\n    {\n        $processor = new MariaDbProcessor;\n        $listing = [\n            ['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => 'YES', 'default' => '', 'extra' => 'auto_increment', 'comment' => 'bar', 'expression' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'NO', 'default' => 'foo', 'extra' => '', 'comment' => '', 'expression' => null],\n            ['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'YES', 'default' => 'NULL', 'extra' => 'on update CURRENT_TIMESTAMP', 'comment' => 'NULL', 'expression' => null],\n        ];\n        $expected = [\n            ['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar', 'generation' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => '', 'generation' => null],\n            ['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],\n        ];\n        $this->assertEquals($expected, $processor->processColumns($listing));\n\n        // convert listing to objects to simulate PDO::FETCH_CLASS\n        foreach ($listing as &$row) {\n            $row = (object) $row;\n        }\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Grammars\\MariaDbGrammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMariaDbQueryGrammarTest extends TestCase\n{\n    public function testToRawSql()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('escape')->with('foo', false)->andReturn(\"'foo'\");\n        $grammar = new MariaDbGrammar($connection);\n\n        $query = $grammar->substituteBindingsIntoRawSql(\n            'select * from \"users\" where \\'Hello\\\\\\'World?\\' IS NOT NULL AND \"email\" = ?',\n            ['foo'],\n        );\n\n        $this->assertSame('select * from \"users\" where \\'Hello\\\\\\'World?\\' IS NOT NULL AND \"email\" = \\'foo\\'', $query);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Processors\\MariaDbProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\MariaDbGrammar;\nuse Illuminate\\Database\\Schema\\MariaDbBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMariaDbSchemaBuilderTest extends TestCase\n{\n    public function testHasTable()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(MariaDbGrammar::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('db');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $builder = new MariaDbBuilder($connection);\n        $grammar->shouldReceive('compileTableExists')->once()->andReturn('sql');\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('scalar')->once()->with('sql')->andReturn(1);\n\n        $this->assertTrue($builder->hasTable('table'));\n    }\n\n    public function testGetColumnListing()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(MariaDbGrammar::class);\n        $processor = m::mock(MariaDbProcessor::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('db');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $grammar->shouldReceive('compileColumns')->with(null, 'prefix_table')->once()->andReturn('sql');\n        $processor->shouldReceive('processColumns')->once()->andReturn([['name' => 'column']]);\n        $builder = new MariaDbBuilder($connection);\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql')->andReturn([['name' => 'column']]);\n\n        $this->assertEquals(['column'], $builder->getColumnListing('table'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\ForeignIdColumnDefinition;\nuse Illuminate\\Database\\Schema\\Grammars\\MariaDbGrammar;\nuse Illuminate\\Database\\Schema\\MariaDbBuilder;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Foo;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMariaDbSchemaGrammarTest extends TestCase\n{\n    public function testBasicCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `id` int unsigned not null auto_increment primary key',\n            'alter table `users` add `email` varchar(255) not null',\n        ], $statements);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n        $conn->shouldReceive('getServerVersion')->andReturn('10.7.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->uuid('id')->primary();\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table `users` (`id` uuid not null, primary key (`id`))', $statements[0]);\n    }\n\n    public function testAutoIncrementStartingValue()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id')->startingValue(1000);\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n        $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]);\n    }\n\n    public function testAddColumnsWithMultipleAutoIncrementStartingValue()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id()->from(100);\n        $blueprint->string('name')->from(200);\n        $statements = $blueprint->toSql();\n\n        $this->assertEquals([\n            'alter table `users` add `id` bigint unsigned not null auto_increment primary key',\n            'alter table `users` add `name` varchar(255) not null',\n            'alter table `users` auto_increment = 100',\n        ], $statements);\n    }\n\n    public function testEngineCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $blueprint->engine('InnoDB');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn('InnoDB');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB\", $statements[0]);\n    }\n\n    public function testCharsetCollationCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $blueprint->charset('utf8mb4');\n        $blueprint->collation('utf8mb4_unicode_ci');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email')->charset('utf8mb4')->collation('utf8mb4_unicode_ci');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) character set utf8mb4 collate 'utf8mb4_unicode_ci' not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n    }\n\n    public function testBasicCreateTableWithPrefix()\n    {\n        $conn = $this->getConnection(prefix: 'prefix_');\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table `prefix_users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]);\n    }\n\n    public function testCreateTemporaryTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create temporary table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]);\n    }\n\n    public function testDropTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table `users`', $statements[0]);\n    }\n\n    public function testDropTableIfExists()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table if exists `users`', $statements[0]);\n    }\n\n    public function testDropColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn(['foo', 'bar']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]);\n    }\n\n    public function testDropPrimary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropPrimary();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop primary key', $statements[0]);\n    }\n\n    public function testDropUnique()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropUnique('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop index `foo`', $statements[0]);\n    }\n\n    public function testDropIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop index `foo`', $statements[0]);\n    }\n\n    public function testDropSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` drop index `geo_coordinates_spatialindex`', $statements[0]);\n    }\n\n    public function testDropForeign()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropForeign('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop foreign key `foo`', $statements[0]);\n    }\n\n    public function testDropTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestamps();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]);\n    }\n\n    public function testDropTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestampsTz();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]);\n    }\n\n    public function testDropMorphs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'photos');\n        $blueprint->dropMorphs('imageable');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `photos` drop index `photos_imageable_type_imageable_id_index`', $statements[0]);\n        $this->assertSame('alter table `photos` drop `imageable_type`, drop `imageable_id`', $statements[1]);\n    }\n\n    public function testRenameTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rename('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('rename table `users` to `foo`', $statements[0]);\n    }\n\n    public function testRenameIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->renameIndex('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` rename index `foo` to `bar`', $statements[0]);\n    }\n\n    public function testAddingPrimaryKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add primary key (`foo`)', $statements[0]);\n    }\n\n    public function testAddingPrimaryKeyWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo', 'bar', 'hash');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add primary key using hash(`foo`)', $statements[0]);\n    }\n\n    public function testAddingUniqueKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add unique `bar`(`foo`)', $statements[0]);\n    }\n\n    public function testAddingIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `baz`(`foo`, `bar`)', $statements[0]);\n    }\n\n    public function testAddingIndexWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz', 'hash');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `baz` using hash(`foo`, `bar`)', $statements[0]);\n    }\n\n    public function testAddingFulltextIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext('body');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add fulltext `users_body_fulltext`(`body`)', $statements[0]);\n    }\n\n    public function testAddingSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[0]);\n    }\n\n    public function testAddingFluentSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point')->spatialIndex();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[1]);\n    }\n\n    public function testAddingRawIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `raw_index`((function(column)))', $statements[0]);\n    }\n\n    public function testAddingForeignKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnDelete();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on delete cascade', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnUpdate();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on update cascade', $statements[0]);\n    }\n\n    public function testAddingIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingSmallIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` smallint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingForeignID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignId = $blueprint->foreignId('foo');\n        $blueprint->foreignId('company_id')->constrained();\n        $blueprint->foreignId('laravel_idea_id')->constrained();\n        $blueprint->foreignId('team_id')->references('id')->on('teams');\n        $blueprint->foreignId('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table `users` add `foo` bigint unsigned not null',\n            'alter table `users` add `company_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)',\n            'alter table `users` add `laravel_idea_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)',\n            'alter table `users` add `team_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)',\n            'alter table `users` add `team_column_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingForeignIdSpecifyingIndexNameInConstraint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreignId('company_id')->constrained(indexName: 'my_index');\n        $statements = $blueprint->toSql();\n        $this->assertSame([\n            'alter table `users` add `company_id` bigint unsigned not null',\n            'alter table `users` add constraint `my_index` foreign key (`company_id`) references `companies` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingBigIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingColumnInTableFirst()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->first();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null first', $statements[0]);\n    }\n\n    public function testAddingColumnAfterAnotherColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->after('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null after `foo`', $statements[0]);\n    }\n\n    public function testAddingMultipleColumnsAfterAnotherColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->after('foo', function ($blueprint) {\n            $blueprint->string('one');\n            $blueprint->string('two');\n        });\n        $blueprint->string('three');\n        $statements = $blueprint->toSql();\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `users` add `one` varchar(255) not null after `foo`',\n            'alter table `users` add `two` varchar(255) not null after `one`',\n            'alter table `users` add `three` varchar(255) not null',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('price - 5');\n        $blueprint->integer('discounted_stored')->storedAs('price - 5');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5)',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored',\n        ], $statements);\n\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('price - 5')->nullable(false);\n        $blueprint->integer('discounted_stored')->storedAs('price - 5')->nullable(false);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5) not null',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored not null',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumnWithCharset()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'links');\n        $blueprint->string('url', 2083)->charset('ascii');\n        $blueprint->string('url_hash_virtual', 64)->virtualAs('sha2(url, 256)')->charset('ascii');\n        $blueprint->string('url_hash_stored', 64)->storedAs('sha2(url, 256)')->charset('ascii');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `links` add `url` varchar(2083) character set ascii not null',\n            'alter table `links` add `url_hash_virtual` varchar(64) character set ascii as (sha2(url, 256))',\n            'alter table `links` add `url_hash_stored` varchar(64) character set ascii as (sha2(url, 256)) stored',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumnByExpression()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs(new Expression('price - 5'));\n        $blueprint->integer('discounted_stored')->storedAs(new Expression('price - 5'));\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5)',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored',\n        ], $statements);\n    }\n\n    public function testAddingInvisibleColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('secret', 64)->nullable(false)->invisible();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `secret` varchar(64) not null invisible', $statements[0]);\n    }\n\n    public function testAddingString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(255) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default \\'bar\\'', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default(new Expression('CURRENT TIMESTAMP'));\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default CURRENT TIMESTAMP', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default(Foo::BAR);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default \\'bar\\'', $statements[0]);\n    }\n\n    public function testAddingText()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->text('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` text not null', $statements[0]);\n    }\n\n    public function testAddingBigInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` int not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` int not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingIncrementsWithStartingValues()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id()->startingValue(1000);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n        $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]);\n    }\n\n    public function testAddingMediumInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` mediumint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` mediumint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingSmallInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` smallint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` smallint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingTinyInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingFloat()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->float('foo', 5);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` float(5) not null', $statements[0]);\n    }\n\n    public function testAddingDouble()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->double('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` double not null', $statements[0]);\n    }\n\n    public function testAddingDecimal()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->decimal('foo', 5, 2);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` decimal(5, 2) not null', $statements[0]);\n    }\n\n    public function testAddingBoolean()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->boolean('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint(1) not null', $statements[0]);\n    }\n\n    public function testAddingEnum()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->enum('role', ['member', 'admin']);\n        $blueprint->enum('status', Foo::cases());\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `users` add `role` enum(\\'member\\', \\'admin\\') not null', $statements[0]);\n        $this->assertSame('alter table `users` add `status` enum(\\'bar\\') not null', $statements[1]);\n    }\n\n    public function testAddingSet()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->set('role', ['member', 'admin']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `role` set(\\'member\\', \\'admin\\') not null', $statements[0]);\n    }\n\n    public function testAddingJson()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` json not null', $statements[0]);\n    }\n\n    public function testAddingJsonb()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` json not null', $statements[0]);\n    }\n\n    public function testAddingDate()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(true);\n        $conn->shouldReceive('getServerVersion')->andReturn('10.3.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->date('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` date not null', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrent()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(true);\n        $conn->shouldReceive('getServerVersion')->andReturn('10.3.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` date not null default (CURDATE())', $statements[0]);\n    }\n\n    public function testAddingYear()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(true);\n        $conn->shouldReceive('getServerVersion')->andReturn('10.3.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->year('birth_year');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `birth_year` year not null', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrent()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(true);\n        $conn->shouldReceive('getServerVersion')->andReturn('10.3.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `birth_year` year not null default (YEAR(CURDATE()))', $statements[0]);\n    }\n\n    public function testAddingDateTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithOnUpdateCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null on update CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrentAndOnUpdateCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrentOnUpdateCurrentAndPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo', 3)->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(3) not null default CURRENT_TIMESTAMP(3) on update CURRENT_TIMESTAMP(3)', $statements[0]);\n    }\n\n    public function testAddingDateTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]);\n    }\n\n    public function testAddingTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]);\n    }\n\n    public function testAddingTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]);\n    }\n\n    public function testAddingTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestamp()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefault()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at')->default('2015-07-22 11:43:17');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'\", $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefaultCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampWithOnUpdateCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null on update CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefaultCurrentAndOnUpdateCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1) on update CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimeStampTzWithDefault()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at')->default('2015-07-22 11:43:17');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'\", $statements[0]);\n    }\n\n    public function testAddingTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamps();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `created_at` timestamp null',\n            'alter table `users` add `updated_at` timestamp null',\n        ], $statements);\n    }\n\n    public function testAddingTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampsTz();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `created_at` timestamp null',\n            'alter table `users` add `updated_at` timestamp null',\n        ], $statements);\n    }\n\n    public function testAddingRememberToken()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rememberToken();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `remember_token` varchar(100) null', $statements[0]);\n    }\n\n    public function testAddingBinary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->binary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` blob not null', $statements[0]);\n    }\n\n    public function testAddingUuid()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getServerVersion')->andReturn('10.7.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` uuid not null', $statements[0]);\n    }\n\n    public function testAddingUuidOn106()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getServerVersion')->andReturn('10.6.21');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` char(36) not null', $statements[0]);\n    }\n\n    public function testAddingUuidDefaultsColumnName()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getServerVersion')->andReturn('10.7.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->uuid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `uuid` uuid not null', $statements[0]);\n    }\n\n    public function testAddingForeignUuid()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getServerVersion')->andReturn('10.7.0');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $foreignUuid = $blueprint->foreignUuid('foo');\n        $blueprint->foreignUuid('company_id')->constrained();\n        $blueprint->foreignUuid('laravel_idea_id')->constrained();\n        $blueprint->foreignUuid('team_id')->references('id')->on('teams');\n        $blueprint->foreignUuid('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid);\n        $this->assertSame([\n            'alter table `users` add `foo` uuid not null',\n            'alter table `users` add `company_id` uuid not null',\n            'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)',\n            'alter table `users` add `laravel_idea_id` uuid not null',\n            'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)',\n            'alter table `users` add `team_id` uuid not null',\n            'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)',\n            'alter table `users` add `team_column_id` uuid not null',\n            'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingIpAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingIpAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `ip_address` varchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `mac_address` varchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingGeometry()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometry not null', $statements[0]);\n    }\n\n    public function testAddingGeography()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geography('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometry ref_system_id=4326 not null', $statements[0]);\n    }\n\n    public function testAddingPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point not null', $statements[0]);\n    }\n\n    public function testAddingPointWithSrid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point', 4326);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point ref_system_id=4326 not null', $statements[0]);\n    }\n\n    public function testAddingPointWithSridColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point', 4326)->after('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point ref_system_id=4326 not null after `id`', $statements[0]);\n    }\n\n    public function testAddingLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'linestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` linestring not null', $statements[0]);\n    }\n\n    public function testAddingPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'polygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` polygon not null', $statements[0]);\n    }\n\n    public function testAddingGeometryCollection()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'geometrycollection');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometrycollection not null', $statements[0]);\n    }\n\n    public function testAddingMultiPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipoint');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multipoint not null', $statements[0]);\n    }\n\n    public function testAddingMultiLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multilinestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multilinestring not null', $statements[0]);\n    }\n\n    public function testAddingMultiPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipolygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multipolygon not null', $statements[0]);\n    }\n\n    public function testAddingComment()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo')->comment(\"Escape ' when using words like it's\");\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `foo` varchar(255) not null comment 'Escape \\\\' when using words like it\\\\'s'\", $statements[0]);\n    }\n\n    public function testCreateDatabase()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_foo');\n        $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_foo');\n\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_a');\n\n        $this->assertSame(\n            'create database `my_database_a` default character set `utf8mb4_foo` default collate `utf8mb4_unicode_ci_foo`',\n            $statement\n        );\n\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_bar');\n        $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_bar');\n\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_b');\n\n        $this->assertSame(\n            'create database `my_database_b` default character set `utf8mb4_bar` default collate `utf8mb4_unicode_ci_bar`',\n            $statement\n        );\n    }\n\n    public function testCreateTableWithVirtualAsColumn()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->virtualAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column)) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_value(`my_json_column`, '$.\\\"some_attribute\\\"')))\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_value(`my_json_column`, '$.\\\"some_attribute\\\".\\\"nested\\\"')))\", $statements[0]);\n    }\n\n    public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) as (json_value(`my_json_column`, '$.\\\"foo\\\"[0][1]')))\", $statements[0]);\n    }\n\n    public function testCreateTableWithStoredAsColumn()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->storedAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column) stored) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_value(`my_json_column`, '$.\\\"some_attribute\\\"')) stored)\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_value(`my_json_column`, '$.\\\"some_attribute\\\".\\\"nested\\\"')) stored)\", $statements[0]);\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a');\n\n        $this->assertSame(\n            'drop database if exists `my_database_a`',\n            $statement\n        );\n\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b');\n\n        $this->assertSame(\n            'drop database if exists `my_database_b`',\n            $statement\n        );\n    }\n\n    public function testDropAllTables()\n    {\n        $connection = $this->getConnection();\n        $statement = $this->getGrammar($connection)->compileDropAllTables(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop table `alpha`, `beta`, `gamma`', $statement);\n    }\n\n    public function testDropAllViews()\n    {\n        $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop view `alpha`, `beta`, `gamma`', $statement);\n    }\n\n    public function testGrammarsAreMacroable()\n    {\n        // compileReplace macro.\n        $this->getGrammar()::macro('compileReplace', function () {\n            return true;\n        });\n\n        $c = $this->getGrammar()::compileReplace();\n\n        $this->assertTrue($c);\n    }\n\n    protected function getConnection(\n        ?MariaDbGrammar $grammar = null,\n        ?MariaDbBuilder $builder = null,\n        string $prefix = ''\n    ) {\n        $connection = m::mock(Connection::class)\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->with('prefix_indexes')->andReturn(null)\n            ->getMock();\n\n        $grammar ??= $this->getGrammar($connection);\n        $builder ??= $this->getBuilder();\n\n        return $connection\n            ->shouldReceive('getSchemaGrammar')->andReturn($grammar)\n            ->shouldReceive('getSchemaBuilder')->andReturn($builder)\n            ->getMock();\n    }\n\n    public function getGrammar(?Connection $connection = null)\n    {\n        return new MariaDbGrammar($connection ?? $this->getConnection());\n    }\n\n    public function getBuilder()\n    {\n        return mock(MariaDbBuilder::class);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMariaDbSchemaStateTest.php",
    "content": "<?php\n\nnamespace Database;\n\nuse Generator;\nuse Illuminate\\Database\\MariaDbConnection;\nuse Illuminate\\Database\\Schema\\MariaDbSchemaState;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\n\nclass DatabaseMariaDbSchemaStateTest extends TestCase\n{\n    #[DataProvider('provider')]\n    public function testConnectionString(string $expectedConnectionString, array $expectedVariables, array $dbConfig): void\n    {\n        $connection = $this->createMock(MariaDbConnection::class);\n        $connection->method('getConfig')->willReturn($dbConfig);\n\n        $schemaState = new MariaDbSchemaState($connection);\n\n        $versionInfo = ['version' => '11.8.3', 'isMariaDb' => true];\n\n        // test connectionString\n        $method = new ReflectionMethod(get_class($schemaState), 'connectionString');\n        $connString = $method->invoke($schemaState, $versionInfo);\n\n        self::assertEquals($expectedConnectionString, $connString);\n\n        // test baseVariables\n        $method = new ReflectionMethod(get_class($schemaState), 'baseVariables');\n        $variables = $method->invoke($schemaState, $dbConfig);\n\n        self::assertEquals($expectedVariables, $variables);\n    }\n\n    public static function provider(): Generator\n    {\n        yield 'default' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '127.0.0.1',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'host' => '127.0.0.1',\n                'database' => 'forge',\n            ],\n        ];\n\n        yield 'ssl_ca' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl-ca=\"${:LARAVEL_LOAD_SSL_CA}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => 'ssl.ca',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA => 'ssl.ca',\n                ],\n            ],\n        ];\n\n        yield 'ssl_cert_and_key' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl-ca=\"${:LARAVEL_LOAD_SSL_CA}\" --ssl-cert=\"${:LARAVEL_LOAD_SSL_CERT}\" --ssl-key=\"${:LARAVEL_LOAD_SSL_KEY}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => 'ssl.ca',\n                'LARAVEL_LOAD_SSL_CERT' => '/path/to/client-cert.pem',\n                'LARAVEL_LOAD_SSL_KEY' => '/path/to/client-key.pem',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA => 'ssl.ca',\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CERT : \\PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_KEY : \\PDO::MYSQL_ATTR_SSL_KEY => '/path/to/client-key.pem',\n                ],\n            ],\n        ];\n\n        yield 'no_ssl' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl=off', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_VERIFY_SERVER_CERT : \\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,\n                ],\n            ],\n        ];\n\n        yield 'unix socket' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --socket=\"${:LARAVEL_LOAD_SOCKET}\"', [\n                'LARAVEL_LOAD_SOCKET' => '/tmp/mysql.sock',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'unix_socket' => '/tmp/mysql.sock',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationCreatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Migrations\\MigrationCreator;\nuse Illuminate\\Filesystem\\Filesystem;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMigrationCreatorTest extends TestCase\n{\n    public function testBasicCreateMethodStoresMigrationFile()\n    {\n        $creator = $this->getCreator();\n\n        $creator->expects($this->any())->method('getDatePrefix')->willReturn('foo');\n        $creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.stub')->andReturn(false);\n        $creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.stub')->andReturn('return new class');\n        $creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo');\n        $creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class');\n        $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);\n        $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');\n\n        $creator->create('create_bar', 'foo');\n    }\n\n    public function testBasicCreateMethodCallsPostCreateHooks()\n    {\n        $table = 'baz';\n\n        $creator = $this->getCreator();\n        unset($_SERVER['__migration.creator.table'], $_SERVER['__migration.creator.path']);\n        $creator->afterCreate(function ($table, $path) {\n            $_SERVER['__migration.creator.table'] = $table;\n            $_SERVER['__migration.creator.path'] = $path;\n        });\n\n        $creator->expects($this->any())->method('getDatePrefix')->willReturn('foo');\n        $creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.update.stub')->andReturn(false);\n        $creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.update.stub')->andReturn('return new class DummyTable');\n        $creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo');\n        $creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class baz');\n        $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);\n        $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');\n\n        $creator->create('create_bar', 'foo', $table);\n\n        $this->assertEquals($_SERVER['__migration.creator.table'], $table);\n        $this->assertEquals($_SERVER['__migration.creator.path'], 'foo/foo_create_bar.php');\n\n        unset($_SERVER['__migration.creator.table'], $_SERVER['__migration.creator.path']);\n    }\n\n    public function testTableUpdateMigrationStoresMigrationFile()\n    {\n        $creator = $this->getCreator();\n        $creator->expects($this->any())->method('getDatePrefix')->willReturn('foo');\n        $creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.update.stub')->andReturn(false);\n        $creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.update.stub')->andReturn('return new class DummyTable');\n        $creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo');\n        $creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class baz');\n        $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);\n        $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');\n\n        $creator->create('create_bar', 'foo', 'baz');\n    }\n\n    public function testTableCreationMigrationStoresMigrationFile()\n    {\n        $creator = $this->getCreator();\n        $creator->expects($this->any())->method('getDatePrefix')->willReturn('foo');\n        $creator->getFilesystem()->shouldReceive('exists')->once()->with('stubs/migration.create.stub')->andReturn(false);\n        $creator->getFilesystem()->shouldReceive('get')->once()->with($creator->stubPath().'/migration.create.stub')->andReturn('return new class DummyTable');\n        $creator->getFilesystem()->shouldReceive('ensureDirectoryExists')->once()->with('foo');\n        $creator->getFilesystem()->shouldReceive('put')->once()->with('foo/foo_create_bar.php', 'return new class baz');\n        $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);\n        $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');\n\n        $creator->create('create_bar', 'foo', 'baz', true);\n    }\n\n    public function testTableUpdateMigrationWontCreateDuplicateClass()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('A MigrationCreatorFakeMigration class already exists.');\n\n        $creator = $this->getCreator();\n\n        $creator->getFilesystem()->shouldReceive('glob')->once()->with('foo/*.php')->andReturn(['foo/foo_create_bar.php']);\n        $creator->getFilesystem()->shouldReceive('requireOnce')->once()->with('foo/foo_create_bar.php');\n\n        $creator->create('migration_creator_fake_migration', 'foo');\n    }\n\n    protected function getCreator()\n    {\n        $files = m::mock(Filesystem::class);\n        $customStubs = 'stubs';\n\n        return $this->getMockBuilder(MigrationCreator::class)\n            ->onlyMethods(['getDatePrefix'])\n            ->setConstructorArgs([$files, $customStubs])\n            ->getMock();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationInstallCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Console\\Migrations\\InstallCommand;\nuse Illuminate\\Database\\Migrations\\MigrationRepositoryInterface;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationInstallCommandTest extends TestCase\n{\n    public function testFireCallsRepositoryToInstall()\n    {\n        $command = new InstallCommand($repo = m::mock(MigrationRepositoryInterface::class));\n        $command->setLaravel(new Application);\n        $repo->shouldReceive('setSource')->once()->with('foo');\n        $repo->shouldReceive('createRepository')->once();\n        $repo->shouldReceive('repositoryExists')->once()->andReturn(false);\n\n        $this->runCommand($command, ['--database' => 'foo']);\n    }\n\n    public function testFireCallsRepositoryToInstallExists()\n    {\n        $command = new InstallCommand($repo = m::mock(MigrationRepositoryInterface::class));\n        $command->setLaravel(new Application);\n        $repo->shouldReceive('setSource')->once()->with('foo');\n        $repo->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command, ['--database' => 'foo']);\n    }\n\n    protected function runCommand($command, $options = [])\n    {\n        return $command->run(new ArrayInput($options), new NullOutput);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand;\nuse Illuminate\\Database\\Migrations\\MigrationCreator;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Composer;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationMakeCommandTest extends TestCase\n{\n    public function testBasicCreateDumpsAutoload()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            $composer = m::mock(Composer::class)\n        );\n        $app = new Application;\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $creator->shouldReceive('create')->once()\n            ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)\n            ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');\n\n        $this->runCommand($command, ['name' => 'create_foo']);\n    }\n\n    public function testBasicCreateGivesCreatorProperArguments()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            m::mock(Composer::class)->shouldIgnoreMissing()\n        );\n        $app = new Application;\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $creator->shouldReceive('create')->once()\n            ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)\n            ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');\n\n        $this->runCommand($command, ['name' => 'create_foo']);\n    }\n\n    public function testBasicCreateGivesCreatorProperArgumentsWhenNameIsStudlyCase()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            m::mock(Composer::class)->shouldIgnoreMissing()\n        );\n        $app = new Application;\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $creator->shouldReceive('create')->once()\n            ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'foo', true)\n            ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');\n\n        $this->runCommand($command, ['name' => 'CreateFoo']);\n    }\n\n    public function testBasicCreateGivesCreatorProperArgumentsWhenTableIsSet()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            m::mock(Composer::class)->shouldIgnoreMissing()\n        );\n        $app = new Application;\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $creator->shouldReceive('create')->once()\n            ->with('create_foo', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true)\n            ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_foo.php');\n\n        $this->runCommand($command, ['name' => 'create_foo', '--create' => 'users']);\n    }\n\n    public function testBasicCreateGivesCreatorProperArgumentsWhenCreateTablePatternIsFound()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            m::mock(Composer::class)->shouldIgnoreMissing()\n        );\n        $app = new Application;\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $creator->shouldReceive('create')->once()\n            ->with('create_users_table', __DIR__.DIRECTORY_SEPARATOR.'migrations', 'users', true)\n            ->andReturn(__DIR__.'/migrations/2021_04_23_110457_create_users_table.php');\n\n        $this->runCommand($command, ['name' => 'create_users_table']);\n    }\n\n    public function testCanSpecifyPathToCreateMigrationsIn()\n    {\n        $command = new MigrateMakeCommand(\n            $creator = m::mock(MigrationCreator::class),\n            m::mock(Composer::class)->shouldIgnoreMissing()\n        );\n        $app = new Application;\n        $command->setLaravel($app);\n        $app->setBasePath('/home/laravel');\n        $creator->shouldReceive('create')->once()\n            ->with('create_foo', '/home/laravel/vendor/laravel-package/migrations', 'users', true)\n            ->andReturn('/home/laravel/vendor/laravel-package/migrations/2021_04_23_110457_create_foo.php');\n        $this->runCommand($command, ['name' => 'create_foo', '--path' => 'vendor/laravel-package/migrations', '--create' => 'users']);\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationMigrateCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Console\\CommandMutex;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Console\\Migrations\\MigrateCommand;\nuse Illuminate\\Database\\Events\\SchemaLoaded;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationMigrateCommandTest extends TestCase\n{\n    public function testBasicMigrationsCallMigratorWithProperArguments()\n    {\n        $command = new MigrateCommand($migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class));\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(true);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => false]);\n        $migrator->shouldReceive('getNotes')->andReturn([]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command);\n    }\n\n    public function testMigrationsCanBeRunWithStoredSchema()\n    {\n        $command = new MigrateCommand($migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class));\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(false);\n        $migrator->shouldReceive('resolveConnection')->andReturn($connection = m::mock(stdClass::class));\n        $connection->shouldReceive('getName')->andReturn('mysql');\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('deleteRepository')->once();\n        $connection->shouldReceive('getSchemaState')->andReturn($schemaState = m::mock(stdClass::class));\n        $schemaState->shouldReceive('handleOutputUsing')->andReturnSelf();\n        $schemaState->shouldReceive('load')->once()->with(__DIR__.'/stubs/schema.sql');\n        $dispatcher->shouldReceive('dispatch')->once()->with(m::type(SchemaLoaded::class));\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => false]);\n        $migrator->shouldReceive('getNotes')->andReturn([]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command, ['--schema-path' => __DIR__.'/stubs/schema.sql']);\n    }\n\n    public function testMigrationRepositoryCreatedWhenNecessary()\n    {\n        $params = [$migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class)];\n        $command = $this->getMockBuilder(MigrateCommand::class)->onlyMethods(['callSilent'])->setConstructorArgs($params)->getMock();\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(true);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => false]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(false);\n        $command->expects($this->once())->method('callSilent')->with($this->equalTo('migrate:install'), $this->equalTo([]));\n\n        $this->runCommand($command);\n    }\n\n    public function testTheCommandMayBePretended()\n    {\n        $command = new MigrateCommand($migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class));\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(true);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => true, 'step' => false]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command, ['--pretend' => true]);\n    }\n\n    public function testTheDatabaseMayBeSet()\n    {\n        $command = new MigrateCommand($migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class));\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(true);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => false]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command, ['--database' => 'foo']);\n    }\n\n    public function testStepMayBeSet()\n    {\n        $command = new MigrateCommand($migrator = m::mock(Migrator::class), $dispatcher = m::mock(Dispatcher::class));\n        $app = new ApplicationDatabaseMigrationStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('hasRunAnyMigrations')->andReturn(true);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('run')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => true]);\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n\n        $this->runCommand($command, ['--step' => true]);\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n\nclass ApplicationDatabaseMigrationStub extends Application\n{\n    public function __construct(array $data = [])\n    {\n        $mutex = m::mock(CommandMutex::class);\n        $mutex->shouldReceive('create')->andReturn(true);\n        $mutex->shouldReceive('release')->andReturn(true);\n        $this->instance(CommandMutex::class, $mutex);\n\n        foreach ($data as $abstract => $instance) {\n            $this->instance($abstract, $instance);\n        }\n    }\n\n    public function environment(...$environments)\n    {\n        return 'development';\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationRefreshCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Console\\Migrations\\MigrateCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RefreshCommand;\nuse Illuminate\\Database\\Console\\Migrations\\ResetCommand;\nuse Illuminate\\Database\\Console\\Migrations\\RollbackCommand;\nuse Illuminate\\Database\\Events\\DatabaseRefreshed;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Application as ConsoleApplication;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationRefreshCommandTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        RefreshCommand::prohibit(false);\n\n        parent::tearDown();\n    }\n\n    public function testRefreshCommandCallsCommandsWithProperArguments()\n    {\n        $command = new RefreshCommand;\n\n        $app = new ApplicationDatabaseRefreshStub(['path.database' => __DIR__]);\n        $dispatcher = $app->instance(Dispatcher::class, $events = m::mock());\n        $console = m::mock(ConsoleApplication::class)->makePartial();\n        $console->__construct();\n        $command->setLaravel($app);\n        $command->setApplication($console);\n\n        $resetCommand = m::mock(ResetCommand::class);\n        $migrateCommand = m::mock(MigrateCommand::class);\n\n        $console->shouldReceive('find')->with('migrate:reset')->andReturn($resetCommand);\n        $console->shouldReceive('find')->with('migrate')->andReturn($migrateCommand);\n        $dispatcher->shouldReceive('dispatch')->once()->with(m::type(DatabaseRefreshed::class));\n\n        $quote = DIRECTORY_SEPARATOR === '\\\\' ? '\"' : \"'\";\n        $resetCommand->shouldReceive('run')->with(new InputMatcher(\"--force=1 {$quote}migrate:reset{$quote}\"), m::any());\n        $migrateCommand->shouldReceive('run')->with(new InputMatcher('--force=1 migrate'), m::any());\n\n        $this->runCommand($command);\n    }\n\n    public function testRefreshCommandCallsCommandsWithStep()\n    {\n        $command = new RefreshCommand;\n\n        $app = new ApplicationDatabaseRefreshStub(['path.database' => __DIR__]);\n        $dispatcher = $app->instance(Dispatcher::class, $events = m::mock());\n        $console = m::mock(ConsoleApplication::class)->makePartial();\n        $console->__construct();\n        $command->setLaravel($app);\n        $command->setApplication($console);\n\n        $rollbackCommand = m::mock(RollbackCommand::class);\n        $migrateCommand = m::mock(MigrateCommand::class);\n\n        $console->shouldReceive('find')->with('migrate:rollback')->andReturn($rollbackCommand);\n        $console->shouldReceive('find')->with('migrate')->andReturn($migrateCommand);\n        $dispatcher->shouldReceive('dispatch')->once()->with(m::type(DatabaseRefreshed::class));\n\n        $quote = DIRECTORY_SEPARATOR === '\\\\' ? '\"' : \"'\";\n        $rollbackCommand->shouldReceive('run')->with(new InputMatcher(\"--step=2 --force=1 {$quote}migrate:rollback{$quote}\"), m::any());\n        $migrateCommand->shouldReceive('run')->with(new InputMatcher('--force=1 migrate'), m::any());\n\n        $this->runCommand($command, ['--step' => 2]);\n    }\n\n    public function testRefreshCommandExitsWhenProhibited()\n    {\n        $command = new RefreshCommand;\n\n        $app = new ApplicationDatabaseRefreshStub(['path.database' => __DIR__]);\n        $dispatcher = $app->instance(Dispatcher::class, $events = m::mock());\n        $console = m::mock(ConsoleApplication::class)->makePartial();\n        $console->__construct();\n        $command->setLaravel($app);\n        $command->setApplication($console);\n\n        RefreshCommand::prohibit();\n\n        $code = $this->runCommand($command);\n\n        $this->assertSame(1, $code);\n\n        $console->shouldNotHaveBeenCalled();\n        $dispatcher->shouldNotReceive('dispatch');\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n\nclass InputMatcher extends m\\Matcher\\MatcherAbstract\n{\n    /**\n     * @param  \\Symfony\\Component\\Console\\Input\\ArrayInput  $actual\n     * @return bool\n     */\n    public function match(&$actual)\n    {\n        return (string) $actual == $this->_expected;\n    }\n\n    public function __toString()\n    {\n        return '';\n    }\n}\n\nclass ApplicationDatabaseRefreshStub extends Application\n{\n    public function __construct(array $data = [])\n    {\n        foreach ($data as $abstract => $instance) {\n            $this->instance($abstract, $instance);\n        }\n    }\n\n    public function environment(...$environments)\n    {\n        return 'development';\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationRepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Migrations\\DatabaseMigrationRepository;\nuse Illuminate\\Support\\Collection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseMigrationRepositoryTest extends TestCase\n{\n    public function testGetRanMigrationsListMigrationsByPackage()\n    {\n        $repo = $this->getRepository();\n        $query = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);\n        $query->shouldReceive('orderBy')->once()->with('batch', 'asc')->andReturn($query);\n        $query->shouldReceive('orderBy')->once()->with('migration', 'asc')->andReturn($query);\n        $query->shouldReceive('pluck')->once()->with('migration')->andReturn(new Collection(['bar']));\n        $query->shouldReceive('useWritePdo')->once()->andReturn($query);\n\n        $this->assertEquals(['bar'], $repo->getRan());\n    }\n\n    public function testGetLastMigrationsGetsAllMigrationsWithTheLatestBatchNumber()\n    {\n        $repo = $this->getMockBuilder(DatabaseMigrationRepository::class)->onlyMethods(['getLastBatchNumber'])->setConstructorArgs([\n            $resolver = m::mock(ConnectionResolverInterface::class), 'migrations',\n        ])->getMock();\n        $repo->expects($this->once())->method('getLastBatchNumber')->willReturn(1);\n        $query = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);\n        $query->shouldReceive('where')->once()->with('batch', 1)->andReturn($query);\n        $query->shouldReceive('orderBy')->once()->with('migration', 'desc')->andReturn($query);\n        $query->shouldReceive('get')->once()->andReturn(new Collection(['foo']));\n        $query->shouldReceive('useWritePdo')->once()->andReturn($query);\n\n        $this->assertEquals(['foo'], $repo->getLast());\n    }\n\n    public function testLogMethodInsertsRecordIntoMigrationTable()\n    {\n        $repo = $this->getRepository();\n        $query = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);\n        $query->shouldReceive('insert')->once()->with(['migration' => 'bar', 'batch' => 1]);\n        $query->shouldReceive('useWritePdo')->once()->andReturn($query);\n\n        $repo->log('bar', 1);\n    }\n\n    public function testDeleteMethodRemovesAMigrationFromTheTable()\n    {\n        $repo = $this->getRepository();\n        $query = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);\n        $query->shouldReceive('where')->once()->with('migration', 'foo')->andReturn($query);\n        $query->shouldReceive('delete')->once();\n        $query->shouldReceive('useWritePdo')->once()->andReturn($query);\n        $migration = (object) ['migration' => 'foo'];\n\n        $repo->delete($migration);\n    }\n\n    public function testGetNextBatchNumberReturnsLastBatchNumberPlusOne()\n    {\n        $repo = $this->getMockBuilder(DatabaseMigrationRepository::class)->onlyMethods(['getLastBatchNumber'])->setConstructorArgs([\n            m::mock(ConnectionResolverInterface::class), 'migrations',\n        ])->getMock();\n        $repo->expects($this->once())->method('getLastBatchNumber')->willReturn(1);\n\n        $this->assertEquals(2, $repo->getNextBatchNumber());\n    }\n\n    public function testGetLastBatchNumberReturnsMaxBatch()\n    {\n        $repo = $this->getRepository();\n        $query = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);\n        $query->shouldReceive('max')->once()->andReturn(1);\n        $query->shouldReceive('useWritePdo')->once()->andReturn($query);\n\n        $this->assertEquals(1, $repo->getLastBatchNumber());\n    }\n\n    public function testCreateRepositoryCreatesProperDatabaseTable()\n    {\n        $repo = $this->getRepository();\n        $schema = m::mock(stdClass::class);\n        $connectionMock = m::mock(Connection::class);\n        $repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);\n        $repo->getConnection()->shouldReceive('getSchemaBuilder')->once()->andReturn($schema);\n        $schema->shouldReceive('create')->once()->with('migrations', m::type(Closure::class));\n\n        $repo->createRepository();\n    }\n\n    protected function getRepository()\n    {\n        return new DatabaseMigrationRepository(m::mock(ConnectionResolverInterface::class), 'migrations');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationResetCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Illuminate\\Database\\Console\\Migrations\\ResetCommand;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationResetCommandTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        ResetCommand::prohibit(false);\n\n        parent::tearDown();\n    }\n\n    public function testResetCommandCallsMigratorWithProperArguments()\n    {\n        $command = new ResetCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseResetStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->with(null, m::type(Closure::class))->andReturnUsing(function ($connection, $callback) {\n            $callback();\n        });\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('reset')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], false);\n\n        $this->runCommand($command);\n    }\n\n    public function testResetCommandCanBePretended()\n    {\n        $command = new ResetCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseResetStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->with('foo', m::type(Closure::class))->andReturnUsing(function ($connection, $callback) {\n            $callback();\n        });\n        $migrator->shouldReceive('repositoryExists')->once()->andReturn(true);\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('reset')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], true);\n\n        $this->runCommand($command, ['--pretend' => true, '--database' => 'foo']);\n    }\n\n    public function testRefreshCommandExitsWhenProhibited()\n    {\n        $command = new ResetCommand($migrator = m::mock(Migrator::class));\n\n        $app = new ApplicationDatabaseResetStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n\n        ResetCommand::prohibit();\n\n        $code = $this->runCommand($command);\n\n        $this->assertSame(1, $code);\n\n        $migrator->shouldNotHaveBeenCalled();\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n\nclass ApplicationDatabaseResetStub extends Application\n{\n    public function __construct(array $data = [])\n    {\n        foreach ($data as $abstract => $instance) {\n            $this->instance($abstract, $instance);\n        }\n    }\n\n    public function environment(...$environments)\n    {\n        return 'development';\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigrationRollbackCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Console\\Migrations\\RollbackCommand;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass DatabaseMigrationRollbackCommandTest extends TestCase\n{\n    public function testRollbackCommandCallsMigratorWithProperArguments()\n    {\n        $command = new RollbackCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseRollbackStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 0, 'batch' => 0]);\n\n        $this->runCommand($command);\n    }\n\n    public function testRollbackCommandCallsMigratorWithStepOption()\n    {\n        $command = new RollbackCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseRollbackStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => false, 'step' => 2, 'batch' => 0]);\n\n        $this->runCommand($command, ['--step' => 2]);\n    }\n\n    public function testRollbackCommandCanBePretended()\n    {\n        $command = new RollbackCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseRollbackStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], true);\n\n        $this->runCommand($command, ['--pretend' => true, '--database' => 'foo']);\n    }\n\n    public function testRollbackCommandCanBePretendedWithStepOption()\n    {\n        $command = new RollbackCommand($migrator = m::mock(Migrator::class));\n        $app = new ApplicationDatabaseRollbackStub(['path.database' => __DIR__]);\n        $app->useDatabasePath(__DIR__);\n        $command->setLaravel($app);\n        $migrator->shouldReceive('paths')->once()->andReturn([]);\n        $migrator->shouldReceive('usingConnection')->once()->andReturnUsing(function ($name, $callback) {\n            return $callback();\n        });\n        $migrator->shouldReceive('setOutput')->once()->andReturn($migrator);\n        $migrator->shouldReceive('rollback')->once()->with([__DIR__.DIRECTORY_SEPARATOR.'migrations'], ['pretend' => true, 'step' => 2, 'batch' => 0]);\n\n        $this->runCommand($command, ['--pretend' => true, '--database' => 'foo', '--step' => 2]);\n    }\n\n    protected function runCommand($command, $input = [])\n    {\n        return $command->run(new ArrayInput($input), new NullOutput);\n    }\n}\n\nclass ApplicationDatabaseRollbackStub extends Application\n{\n    public function __construct(array $data = [])\n    {\n        foreach ($data as $abstract => $instance) {\n            $this->instance($abstract, $instance);\n        }\n    }\n\n    public function environment(...$environments)\n    {\n        return 'development';\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMigratorIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Migrations\\DatabaseMigrationRepository;\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMigratorIntegrationTest extends TestCase\n{\n    protected $db;\n    protected $migrator;\n\n    /**\n     * Bootstrap Eloquent.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $this->db = $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], 'sqlite2');\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], 'sqlite3');\n\n        $db->setAsGlobal();\n\n        $container = new Container;\n        $container->instance('db', $db->getDatabaseManager());\n        $container->bind('db.schema', function ($app) {\n            return $app['db']->connection()->getSchemaBuilder();\n        });\n\n        Facade::setFacadeApplication($container);\n\n        $this->migrator = new Migrator(\n            $repository = new DatabaseMigrationRepository($db->getDatabaseManager(), 'migrations'),\n            $db->getDatabaseManager(),\n            new Filesystem\n        );\n\n        $output = m::mock(OutputStyle::class);\n        $output->shouldReceive('write');\n        $output->shouldReceive('writeln');\n        $output->shouldReceive('newLinesWritten');\n\n        $this->migrator->setOutput($output);\n\n        if (! $repository->repositoryExists()) {\n            $repository->createRepository();\n        }\n\n        $repository2 = new DatabaseMigrationRepository($db->getDatabaseManager(), 'migrations');\n        $repository2->setSource('sqlite2');\n\n        if (! $repository2->repositoryExists()) {\n            $repository2->createRepository();\n        }\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::clearResolvedInstances();\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function testBasicMigrationOfSingleFolder()\n    {\n        $ran = $this->migrator->run([__DIR__.'/migrations/one']);\n\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n\n        $this->assertTrue(str_contains($ran[0], 'users'));\n        $this->assertTrue(str_contains($ran[1], 'password_resets'));\n    }\n\n    public function testMigrationsDefaultConnectionCanBeChanged()\n    {\n        $ran = $this->migrator->usingConnection('sqlite2', function () {\n            return $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqllite3']);\n        });\n\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n        $this->assertTrue($this->db->schema('sqlite2')->hasTable('users'));\n        $this->assertTrue($this->db->schema('sqlite2')->hasTable('password_resets'));\n        $this->assertFalse($this->db->schema('sqlite3')->hasTable('users'));\n        $this->assertFalse($this->db->schema('sqlite3')->hasTable('password_resets'));\n\n        $this->assertTrue(Str::contains($ran[0], 'users'));\n        $this->assertTrue(Str::contains($ran[1], 'password_resets'));\n    }\n\n    public function testMigrationsCanEachDefineConnection()\n    {\n        $ran = $this->migrator->run([__DIR__.'/migrations/connection_configured']);\n\n        $this->assertFalse($this->db->schema()->hasTable('failed_jobs'));\n        $this->assertFalse($this->db->schema()->hasTable('jobs'));\n        $this->assertFalse($this->db->schema('sqlite2')->hasTable('failed_jobs'));\n        $this->assertFalse($this->db->schema('sqlite2')->hasTable('jobs'));\n        $this->assertTrue($this->db->schema('sqlite3')->hasTable('failed_jobs'));\n        $this->assertTrue($this->db->schema('sqlite3')->hasTable('jobs'));\n\n        $this->assertTrue(Str::contains($ran[0], 'failed_jobs'));\n        $this->assertTrue(Str::contains($ran[1], 'jobs'));\n    }\n\n    public function testMigratorCannotChangeDefinedMigrationConnection()\n    {\n        $ran = $this->migrator->usingConnection('sqlite2', function () {\n            return $this->migrator->run([__DIR__.'/migrations/connection_configured']);\n        });\n\n        $this->assertFalse($this->db->schema()->hasTable('failed_jobs'));\n        $this->assertFalse($this->db->schema()->hasTable('jobs'));\n        $this->assertFalse($this->db->schema('sqlite2')->hasTable('failed_jobs'));\n        $this->assertFalse($this->db->schema('sqlite2')->hasTable('jobs'));\n        $this->assertTrue($this->db->schema('sqlite3')->hasTable('failed_jobs'));\n        $this->assertTrue($this->db->schema('sqlite3')->hasTable('jobs'));\n\n        $this->assertTrue(Str::contains($ran[0], 'failed_jobs'));\n        $this->assertTrue(Str::contains($ran[1], 'jobs'));\n    }\n\n    public function testMigrationsCanBeRolledBack()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $rolledBack = $this->migrator->rollback([__DIR__.'/migrations/one']);\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n\n        $this->assertTrue(str_contains($rolledBack[0], 'password_resets'));\n        $this->assertTrue(str_contains($rolledBack[1], 'users'));\n    }\n\n    public function testMigrationsCanBeResetUsingAnString()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $rolledBack = $this->migrator->reset(__DIR__.'/migrations/one');\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n\n        $this->assertTrue(str_contains($rolledBack[0], 'password_resets'));\n        $this->assertTrue(str_contains($rolledBack[1], 'users'));\n    }\n\n    public function testMigrationsCanBeResetUsingAnArray()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $rolledBack = $this->migrator->reset([__DIR__.'/migrations/one']);\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n\n        $this->assertTrue(str_contains($rolledBack[0], 'password_resets'));\n        $this->assertTrue(str_contains($rolledBack[1], 'users'));\n    }\n\n    public function testNoErrorIsThrownWhenNoOutstandingMigrationsExist()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $this->migrator->run([__DIR__.'/migrations/one']);\n    }\n\n    public function testNoErrorIsThrownWhenNothingToRollback()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $this->migrator->rollback([__DIR__.'/migrations/one']);\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n        $this->migrator->rollback([__DIR__.'/migrations/one']);\n    }\n\n    public function testMigrationsCanRunAcrossMultiplePaths()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one', __DIR__.'/migrations/two']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $this->assertTrue($this->db->schema()->hasTable('flights'));\n    }\n\n    public function testMigrationsCanBeRolledBackAcrossMultiplePaths()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one', __DIR__.'/migrations/two']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $this->assertTrue($this->db->schema()->hasTable('flights'));\n        $this->migrator->rollback([__DIR__.'/migrations/one', __DIR__.'/migrations/two']);\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n        $this->assertFalse($this->db->schema()->hasTable('flights'));\n    }\n\n    public function testMigrationsCanBeResetAcrossMultiplePaths()\n    {\n        $this->migrator->run([__DIR__.'/migrations/one', __DIR__.'/migrations/two']);\n        $this->assertTrue($this->db->schema()->hasTable('users'));\n        $this->assertTrue($this->db->schema()->hasTable('password_resets'));\n        $this->assertTrue($this->db->schema()->hasTable('flights'));\n        $this->migrator->reset([__DIR__.'/migrations/one', __DIR__.'/migrations/two']);\n        $this->assertFalse($this->db->schema()->hasTable('users'));\n        $this->assertFalse($this->db->schema()->hasTable('password_resets'));\n        $this->assertFalse($this->db->schema()->hasTable('flights'));\n    }\n\n    public function testMigrationsCanBeProperlySortedAcrossMultiplePaths()\n    {\n        $paths = [__DIR__.'/migrations/multi_path/vendor', __DIR__.'/migrations/multi_path/app'];\n\n        $migrationsFilesFullPaths = array_values($this->migrator->getMigrationFiles($paths));\n\n        $expected = [\n            __DIR__.'/migrations/multi_path/app/2016_01_01_000000_create_users_table.php', // This file was not created on the \"vendor\" directory on purpose\n            __DIR__.'/migrations/multi_path/vendor/2016_01_01_200000_create_flights_table.php', // This file was not created on the \"app\" directory on purpose\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000001_rename_table_one.php',\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000002_rename_table_two.php',\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000003_rename_table_three.php',\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000004_rename_table_four.php',\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000005_create_table_one.php',\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000006_create_table_two.php',\n            __DIR__.'/migrations/multi_path/vendor/2019_08_08_000007_create_table_three.php', // This file was not created on the \"app\" directory on purpose\n            __DIR__.'/migrations/multi_path/app/2019_08_08_000008_create_table_four.php',\n        ];\n\n        $this->assertEquals($expected, $migrationsFilesFullPaths);\n    }\n\n    public function testConnectionPriorToMigrationIsNotChangedAfterMigration()\n    {\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->assertSame('default', $this->migrator->getConnection());\n    }\n\n    public function testConnectionPriorToMigrationIsNotChangedAfterRollback()\n    {\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->migrator->rollback([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->assertSame('default', $this->migrator->getConnection());\n    }\n\n    public function testConnectionPriorToMigrationIsNotChangedWhenNoOutstandingMigrationsExist()\n    {\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->assertSame('default', $this->migrator->getConnection());\n    }\n\n    public function testConnectionPriorToMigrationIsNotChangedWhenNothingToRollback()\n    {\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->migrator->rollback([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->migrator->rollback([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->assertSame('default', $this->migrator->getConnection());\n    }\n\n    public function testConnectionPriorToMigrationIsNotChangedAfterMigrateReset()\n    {\n        $this->migrator->setConnection('default');\n        $this->migrator->run([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->migrator->reset([__DIR__.'/migrations/one'], ['database' => 'sqlite2']);\n        $this->assertSame('default', $this->migrator->getConnection());\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySQLSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Processors\\MySqlProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Schema\\MySqlBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMySQLSchemaBuilderTest extends TestCase\n{\n    public function testHasTable()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(MySqlGrammar::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('db');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $builder = new MySqlBuilder($connection);\n        $grammar->shouldReceive('compileTableExists')->once()->andReturn('sql');\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('scalar')->once()->with('sql')->andReturn(1);\n\n        $this->assertTrue($builder->hasTable('table'));\n    }\n\n    public function testGetColumnListing()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(MySqlGrammar::class);\n        $processor = m::mock(MySqlProcessor::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('db');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $grammar->shouldReceive('compileColumns')->with(null, 'prefix_table')->once()->andReturn('sql');\n        $processor->shouldReceive('processColumns')->once()->andReturn([['name' => 'column']]);\n        $builder = new MySqlBuilder($connection);\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql')->andReturn([['name' => 'column']]);\n\n        $this->assertEquals(['column'], $builder->getColumnListing('table'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySqlBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar as MySqlGrammarSchema;\nuse Illuminate\\Database\\Schema\\MySqlBuilder;\nuse Mockery;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMySqlBuilderTest extends TestCase\n{\n    public function testCreateDatabase(): void\n    {\n        $connection = Mockery::mock(Connection::class);\n        $grammar = new MySqlGrammarSchema($connection);\n\n        $connection->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8mb4');\n        $connection->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8mb4_unicode_ci');\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'create database `my_temporary_database` default character set `utf8mb4` default collate `utf8mb4_unicode_ci`'\n        )->andReturn(true);\n\n        $builder = new MySqlBuilder($connection);\n        $builder->createDatabase('my_temporary_database');\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = Mockery::mock(Connection::class);\n        $grammar = new MySqlGrammarSchema($connection);\n\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'drop database if exists `my_database_a`'\n        )->andReturn(true);\n\n        $builder = new MySqlBuilder($connection);\n\n        $builder->dropDatabaseIfExists('my_database_a');\n    }\n\n    public function testDeleteWithJoinCompilesOrderByAndLimit(): void\n    {\n        $connection = Mockery::mock(Connection::class);\n        $processor = Mockery::mock(Processor::class);\n        $grammar = new MySqlGrammar($connection);\n\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n\n        $builder = new Builder($connection, $grammar, $processor);\n\n        $builder\n            ->from('users')\n            ->join('contacts', 'users.id', '=', 'contacts.id')\n            ->where('email', '=', 'foo')\n            ->orderBy('users.id')\n            ->limit(5);\n\n        $sql = $grammar->compileDelete($builder);\n\n        $this->assertStringContainsString('order by `users`.`id` asc', $sql);\n        $this->assertStringContainsString('limit 5', $sql);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySqlProcessorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Query\\Processors\\MySqlProcessor;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMySqlProcessorTest extends TestCase\n{\n    public function testProcessColumns()\n    {\n        $processor = new MySqlProcessor;\n        $listing = [\n            ['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => 'YES', 'default' => '', 'extra' => 'auto_increment', 'comment' => 'bar', 'expression' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'NO', 'default' => 'foo', 'extra' => '', 'comment' => '', 'expression' => null],\n            ['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'YES', 'default' => 'NULL', 'extra' => 'on update CURRENT_TIMESTAMP', 'comment' => 'NULL', 'expression' => null],\n        ];\n        $expected = [\n            ['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar', 'generation' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => null, 'generation' => null],\n            ['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],\n        ];\n        $this->assertEquals($expected, $processor->processColumns($listing));\n\n        // convert listing to objects to simulate PDO::FETCH_CLASS\n        foreach ($listing as &$row) {\n            $row = (object) $row;\n        }\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySqlQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMySqlQueryGrammarTest extends TestCase\n{\n    public function testToRawSql()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('escape')->with('foo', false)->andReturn(\"'foo'\");\n        $grammar = new MySqlGrammar($connection);\n\n        $query = $grammar->substituteBindingsIntoRawSql(\n            'select * from \"users\" where \\'Hello\\\\\\'World?\\' IS NOT NULL AND \"email\" = ?',\n            ['foo'],\n        );\n\n        $this->assertSame('select * from \"users\" where \\'Hello\\\\\\'World?\\' IS NOT NULL AND \"email\" = \\'foo\\'', $query);\n    }\n\n    public function testTimeout()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('email', 'like', '%test%')->timeout(60);\n        $this->assertSame(\n            'select /*+ MAX_EXECUTION_TIME(60000) */ * from `users` where `email` like ?',\n            $builder->toSql()\n        );\n    }\n\n    public function testTimeoutWithDistinct()\n    {\n        $builder = $this->getBuilder();\n        $builder->distinct()->select('*')->from('users')->timeout(30);\n        $this->assertSame(\n            'select /*+ MAX_EXECUTION_TIME(30000) */ distinct * from `users`',\n            $builder->toSql()\n        );\n    }\n\n    public function testTimeoutWithAggregate()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('users')->timeout(10);\n        $builder->aggregate = ['function' => 'count', 'columns' => ['*']];\n        $this->assertSame(\n            'select /*+ MAX_EXECUTION_TIME(10000) */ count(*) as aggregate from `users`',\n            $builder->toSql()\n        );\n    }\n\n    public function testTimeoutNullRemovesTimeout()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->timeout(60)->timeout(null);\n        $this->assertSame('select * from `users`', $builder->toSql());\n    }\n\n    public function testTimeoutThrowsExceptionForNegativeValue()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->timeout(-1);\n    }\n\n    protected function getBuilder()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySqlSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\ForeignIdColumnDefinition;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Schema\\MySqlBuilder;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Foo;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseMySqlSchemaGrammarTest extends TestCase\n{\n    public function testBasicCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `id` int unsigned not null auto_increment primary key',\n            'alter table `users` add `email` varchar(255) not null',\n        ], $statements);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->uuid('id')->primary();\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table `users` (`id` char(36) not null, primary key (`id`))', $statements[0]);\n    }\n\n    public function testAutoIncrementStartingValue()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id')->startingValue(1000);\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n        $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]);\n    }\n\n    public function testAddColumnsWithMultipleAutoIncrementStartingValue()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id()->from(100);\n        $blueprint->string('name')->from(200);\n        $statements = $blueprint->toSql();\n\n        $this->assertEquals([\n            'alter table `users` add `id` bigint unsigned not null auto_increment primary key',\n            'alter table `users` add `name` varchar(255) not null',\n            'alter table `users` auto_increment = 100',\n        ], $statements);\n    }\n\n    public function testEngineCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $blueprint->engine('InnoDB');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn('InnoDB');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8 collate 'utf8_unicode_ci' engine = InnoDB\", $statements[0]);\n    }\n\n    public function testCharsetCollationCreateTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $blueprint->charset('utf8mb4');\n        $blueprint->collation('utf8mb4_unicode_ci');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email')->charset('utf8mb4')->collation('utf8mb4_unicode_ci');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) character set utf8mb4 collate 'utf8mb4_unicode_ci' not null) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n    }\n\n    public function testBasicCreateTableWithPrefix()\n    {\n        $conn = $this->getConnection(prefix: 'prefix_');\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table `prefix_users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]);\n    }\n\n    public function testCreateTemporaryTable()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create temporary table `users` (`id` int unsigned not null auto_increment primary key, `email` varchar(255) not null)', $statements[0]);\n    }\n\n    public function testDropTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table `users`', $statements[0]);\n    }\n\n    public function testDropTableIfExists()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table if exists `users`', $statements[0]);\n    }\n\n    public function testDropColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn(['foo', 'bar']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `foo`, drop `bar`', $statements[0]);\n    }\n\n    public function testDropPrimary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropPrimary();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop primary key', $statements[0]);\n    }\n\n    public function testDropUnique()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropUnique('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop index `foo`', $statements[0]);\n    }\n\n    public function testDropIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop index `foo`', $statements[0]);\n    }\n\n    public function testDropSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` drop index `geo_coordinates_spatialindex`', $statements[0]);\n    }\n\n    public function testDropForeign()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropForeign('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop foreign key `foo`', $statements[0]);\n    }\n\n    public function testDropTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestamps();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]);\n    }\n\n    public function testDropTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestampsTz();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `created_at`, drop `updated_at`', $statements[0]);\n    }\n\n    public function testDropMorphs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'photos');\n        $blueprint->dropMorphs('imageable');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `photos` drop index `photos_imageable_type_imageable_id_index`', $statements[0]);\n        $this->assertSame('alter table `photos` drop `imageable_type`, drop `imageable_id`', $statements[1]);\n    }\n\n    public function testRenameTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rename('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('rename table `users` to `foo`', $statements[0]);\n    }\n\n    public function testRenameIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->renameIndex('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` rename index `foo` to `bar`', $statements[0]);\n    }\n\n    public function testAddingPrimaryKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add primary key (`foo`)', $statements[0]);\n    }\n\n    public function testAddingPrimaryKeyWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo', 'bar', 'hash');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add primary key using hash(`foo`)', $statements[0]);\n    }\n\n    public function testAddingUniqueKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add unique `bar`(`foo`)', $statements[0]);\n    }\n\n    public function testAddingIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `baz`(`foo`, `bar`)', $statements[0]);\n    }\n\n    public function testAddingIndexWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz', 'hash');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `baz` using hash(`foo`, `bar`)', $statements[0]);\n    }\n\n    public function testAddingFulltextIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext('body');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add fulltext `users_body_fulltext`(`body`)', $statements[0]);\n    }\n\n    public function testAddingSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[0]);\n    }\n\n    public function testAddingFluentSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point')->spatialIndex();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `geo` add spatial index `geo_coordinates_spatialindex`(`coordinates`)', $statements[1]);\n    }\n\n    public function testAddingRawIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `raw_index`((function(column)))', $statements[0]);\n    }\n\n    public function testAddingForeignKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnDelete();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on delete cascade', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnUpdate();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_foo_id_foreign` foreign key (`foo_id`) references `orders` (`id`) on update cascade', $statements[0]);\n    }\n\n    public function testAddingIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` int unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingSmallIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` smallint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingForeignID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignId = $blueprint->foreignId('foo');\n        $blueprint->foreignId('company_id')->constrained();\n        $blueprint->foreignId('laravel_idea_id')->constrained();\n        $blueprint->foreignId('team_id')->references('id')->on('teams');\n        $blueprint->foreignId('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table `users` add `foo` bigint unsigned not null',\n            'alter table `users` add `company_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)',\n            'alter table `users` add `laravel_idea_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)',\n            'alter table `users` add `team_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)',\n            'alter table `users` add `team_column_id` bigint unsigned not null',\n            'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingForeignIdSpecifyingIndexNameInConstraint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreignId('company_id')->constrained(indexName: 'my_index');\n        $statements = $blueprint->toSql();\n        $this->assertSame([\n            'alter table `users` add `company_id` bigint unsigned not null',\n            'alter table `users` add constraint `my_index` foreign key (`company_id`) references `companies` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingBigIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingColumnInTableFirst()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->first();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null first', $statements[0]);\n    }\n\n    public function testAddingColumnAfterAnotherColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->after('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null after `foo`', $statements[0]);\n    }\n\n    public function testAddingMultipleColumnsAfterAnotherColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->after('foo', function ($blueprint) {\n            $blueprint->string('one');\n            $blueprint->string('two');\n        });\n        $blueprint->string('three');\n        $statements = $blueprint->toSql();\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `users` add `one` varchar(255) not null after `foo`',\n            'alter table `users` add `two` varchar(255) not null after `one`',\n            'alter table `users` add `three` varchar(255) not null',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('price - 5');\n        $blueprint->integer('discounted_stored')->storedAs('price - 5');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5)',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored',\n        ], $statements);\n\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('price - 5')->nullable(false);\n        $blueprint->integer('discounted_stored')->storedAs('price - 5')->nullable(false);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5) not null',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored not null',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumnWithCharset()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'links');\n        $blueprint->string('url', 2083)->charset('ascii');\n        $blueprint->string('url_hash_virtual', 64)->virtualAs('sha2(url, 256)')->charset('ascii');\n        $blueprint->string('url_hash_stored', 64)->storedAs('sha2(url, 256)')->charset('ascii');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `links` add `url` varchar(2083) character set ascii not null',\n            'alter table `links` add `url_hash_virtual` varchar(64) character set ascii as (sha2(url, 256))',\n            'alter table `links` add `url_hash_stored` varchar(64) character set ascii as (sha2(url, 256)) stored',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedColumnByExpression()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs(new Expression('price - 5'));\n        $blueprint->integer('discounted_stored')->storedAs(new Expression('price - 5'));\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table `products` add `price` int not null',\n            'alter table `products` add `discounted_virtual` int as (price - 5)',\n            'alter table `products` add `discounted_stored` int as (price - 5) stored',\n        ], $statements);\n    }\n\n    public function testAddingInvisibleColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('secret', 64)->nullable(false)->invisible();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `secret` varchar(64) not null invisible', $statements[0]);\n    }\n\n    public function testAddingString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(255) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default \\'bar\\'', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default(new Expression('CURRENT TIMESTAMP'));\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default CURRENT TIMESTAMP', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default(Foo::BAR);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(100) null default \\'bar\\'', $statements[0]);\n    }\n\n    public function testAddingText()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->text('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` text not null', $statements[0]);\n    }\n\n    public function testAddingBigInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` bigint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` int not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` int not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingIncrementsWithStartingValues()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id()->startingValue(1000);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `users` add `id` bigint unsigned not null auto_increment primary key', $statements[0]);\n        $this->assertSame('alter table `users` auto_increment = 1000', $statements[1]);\n    }\n\n    public function testAddingMediumInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` mediumint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` mediumint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingSmallInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` smallint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` smallint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingTinyInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint not null auto_increment primary key', $statements[0]);\n    }\n\n    public function testAddingFloat()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->float('foo', 5);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` float(5) not null', $statements[0]);\n    }\n\n    public function testAddingDouble()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->double('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` double not null', $statements[0]);\n    }\n\n    public function testAddingDecimal()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->decimal('foo', 5, 2);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` decimal(5, 2) not null', $statements[0]);\n    }\n\n    public function testAddingBoolean()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->boolean('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` tinyint(1) not null', $statements[0]);\n    }\n\n    public function testAddingEnum()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->enum('role', ['member', 'admin']);\n        $blueprint->enum('status', Foo::cases());\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table `users` add `role` enum(\\'member\\', \\'admin\\') not null', $statements[0]);\n        $this->assertSame('alter table `users` add `status` enum(\\'bar\\') not null', $statements[1]);\n    }\n\n    public function testAddingSet()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->set('role', ['member', 'admin']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `role` set(\\'member\\', \\'admin\\') not null', $statements[0]);\n    }\n\n    public function testAddingJson()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` json not null', $statements[0]);\n    }\n\n    public function testAddingJsonb()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` json not null', $statements[0]);\n    }\n\n    public function testAddingDate()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('8.0.13');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->date('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` date not null', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrent()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('8.0.13');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` date not null default (CURDATE())', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrentOn57()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('5.7');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` date not null', $statements[0]);\n    }\n\n    public function testAddingYear()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('8.0.13');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->year('birth_year');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `birth_year` year not null', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrent()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('8.0.13');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `birth_year` year not null default (YEAR(CURDATE()))', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrentOn57()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('isMaria')->andReturn(false);\n        $conn->shouldReceive('getServerVersion')->andReturn('5.7');\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `birth_year` year not null', $statements[0]);\n    }\n\n    public function testAddingDateTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithOnUpdateCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null on update CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrentAndOnUpdateCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo')->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithDefaultCurrentOnUpdateCurrentAndPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('foo', 3)->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(3) not null default CURRENT_TIMESTAMP(3) on update CURRENT_TIMESTAMP(3)', $statements[0]);\n    }\n\n    public function testAddingDateTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime(1) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` datetime not null', $statements[0]);\n    }\n\n    public function testAddingTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]);\n    }\n\n    public function testAddingTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time not null', $statements[0]);\n    }\n\n    public function testAddingTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestamp()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefault()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at')->default('2015-07-22 11:43:17');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'\", $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefaultCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampWithOnUpdateCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null on update CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampWithDefaultCurrentAndOnUpdateCurrentSpecifyingPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1)->useCurrent()->useCurrentOnUpdate();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null default CURRENT_TIMESTAMP(1) on update CURRENT_TIMESTAMP(1)', $statements[0]);\n    }\n\n    public function testAddingTimestampTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `created_at` timestamp(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimeStampTzWithDefault()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at')->default('2015-07-22 11:43:17');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `created_at` timestamp not null default '2015-07-22 11:43:17'\", $statements[0]);\n    }\n\n    public function testAddingTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamps();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `created_at` timestamp null',\n            'alter table `users` add `updated_at` timestamp null',\n        ], $statements);\n    }\n\n    public function testAddingTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampsTz();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table `users` add `created_at` timestamp null',\n            'alter table `users` add `updated_at` timestamp null',\n        ], $statements);\n    }\n\n    public function testAddingRememberToken()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rememberToken();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `remember_token` varchar(100) null', $statements[0]);\n    }\n\n    public function testAddingBinary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->binary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` blob not null', $statements[0]);\n    }\n\n    public function testAddingUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` char(36) not null', $statements[0]);\n    }\n\n    public function testAddingUuidDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `uuid` char(36) not null', $statements[0]);\n    }\n\n    public function testAddingForeignUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignUuid = $blueprint->foreignUuid('foo');\n        $blueprint->foreignUuid('company_id')->constrained();\n        $blueprint->foreignUuid('laravel_idea_id')->constrained();\n        $blueprint->foreignUuid('team_id')->references('id')->on('teams');\n        $blueprint->foreignUuid('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid);\n        $this->assertSame([\n            'alter table `users` add `foo` char(36) not null',\n            'alter table `users` add `company_id` char(36) not null',\n            'alter table `users` add constraint `users_company_id_foreign` foreign key (`company_id`) references `companies` (`id`)',\n            'alter table `users` add `laravel_idea_id` char(36) not null',\n            'alter table `users` add constraint `users_laravel_idea_id_foreign` foreign key (`laravel_idea_id`) references `laravel_ideas` (`id`)',\n            'alter table `users` add `team_id` char(36) not null',\n            'alter table `users` add constraint `users_team_id_foreign` foreign key (`team_id`) references `teams` (`id`)',\n            'alter table `users` add `team_column_id` char(36) not null',\n            'alter table `users` add constraint `users_team_column_id_foreign` foreign key (`team_column_id`) references `teams` (`id`)',\n        ], $statements);\n    }\n\n    public function testAddingIpAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingIpAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `ip_address` varchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `foo` varchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `mac_address` varchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingGeometry()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometry not null', $statements[0]);\n    }\n\n    public function testAddingGeography()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geography('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometry srid 4326 not null', $statements[0]);\n    }\n\n    public function testAddingPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point not null', $statements[0]);\n    }\n\n    public function testAddingPointWithSrid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point', 4326);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null', $statements[0]);\n    }\n\n    public function testAddingPointWithSridColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point', 4326)->after('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` point srid 4326 not null after `id`', $statements[0]);\n    }\n\n    public function testAddingLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'linestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` linestring not null', $statements[0]);\n    }\n\n    public function testAddingPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'polygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` polygon not null', $statements[0]);\n    }\n\n    public function testAddingGeometryCollection()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'geometrycollection');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` geometrycollection not null', $statements[0]);\n    }\n\n    public function testAddingMultiPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipoint');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multipoint not null', $statements[0]);\n    }\n\n    public function testAddingMultiLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multilinestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multilinestring not null', $statements[0]);\n    }\n\n    public function testAddingMultiPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipolygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `geo` add `coordinates` multipolygon not null', $statements[0]);\n    }\n\n    public function testAddingComment()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo')->comment(\"Escape ' when using words like it's\");\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table `users` add `foo` varchar(255) not null comment 'Escape \\\\' when using words like it\\\\'s'\", $statements[0]);\n    }\n\n    public function testAddingVector()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'embeddings');\n        $blueprint->vector('embedding', 384);\n        $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `embeddings` add `embedding` vector(384) not null', $statements[0]);\n    }\n\n    public function testCreateDatabase()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_foo');\n        $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_foo');\n\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_a');\n\n        $this->assertSame(\n            'create database `my_database_a` default character set `utf8mb4_foo` default collate `utf8mb4_unicode_ci_foo`',\n            $statement\n        );\n\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8mb4_bar');\n        $connection->shouldReceive('getConfig')->once()->once()->with('collation')->andReturn('utf8mb4_unicode_ci_bar');\n\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_b');\n\n        $this->assertSame(\n            'create database `my_database_b` default character set `utf8mb4_bar` default collate `utf8mb4_unicode_ci_bar`',\n            $statement\n        );\n    }\n\n    public function testCreateTableWithVirtualAsColumn()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->virtualAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column)) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\\\"some_attribute\\\"'))))\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\\\"some_attribute\\\".\\\"nested\\\"'))))\", $statements[0]);\n    }\n\n    public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\\\"foo\\\"[0][1]'))))\", $statements[0]);\n    }\n\n    public function testCreateTableWithStoredAsColumn()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $conn->shouldReceive('getConfig')->once()->with('collation')->andReturn('utf8_unicode_ci');\n        $conn->shouldReceive('getConfig')->once()->with('engine')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->storedAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_column` varchar(255) not null, `my_other_column` varchar(255) as (my_column) stored) default character set utf8 collate 'utf8_unicode_ci'\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\\\"some_attribute\\\"'))) stored)\", $statements[0]);\n\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table `users` (`my_json_column` varchar(255) not null, `my_other_column` varchar(255) as (json_unquote(json_extract(`my_json_column`, '$.\\\"some_attribute\\\".\\\"nested\\\"'))) stored)\", $statements[0]);\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a');\n\n        $this->assertSame(\n            'drop database if exists `my_database_a`',\n            $statement\n        );\n\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b');\n\n        $this->assertSame(\n            'drop database if exists `my_database_b`',\n            $statement\n        );\n    }\n\n    public function testDropAllTables()\n    {\n        $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop table `alpha`, `beta`, `gamma`', $statement);\n    }\n\n    public function testDropAllViews()\n    {\n        $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop view `alpha`, `beta`, `gamma`', $statement);\n    }\n\n    public function testDropAllTablesWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllTables(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop table `schema`.`alpha`, `schema`.`beta`, `schema`.`gamma`', $statement);\n    }\n\n    public function testDropAllViewsWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllViews(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop view `schema`.`alpha`, `schema`.`beta`, `schema`.`gamma`', $statement);\n    }\n\n    public function testGrammarsAreMacroable()\n    {\n        // compileReplace macro.\n        $this->getGrammar()::macro('compileReplace', function () {\n            return true;\n        });\n\n        $c = $this->getGrammar()::compileReplace();\n\n        $this->assertTrue($c);\n    }\n\n    protected function getConnection(\n        ?MySqlGrammar $grammar = null,\n        ?MySqlBuilder $builder = null,\n        string $prefix = ''\n    ) {\n        $connection = m::mock(Connection::class)\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->with('prefix_indexes')->andReturn(null)\n            ->shouldReceive('isMaria')->andReturn(false)\n            ->getMock();\n\n        $grammar ??= $this->getGrammar($connection);\n        $builder ??= $this->getBuilder();\n\n        return $connection\n            ->shouldReceive('getSchemaGrammar')->andReturn($grammar)\n            ->shouldReceive('getSchemaBuilder')->andReturn($builder)\n            ->getMock();\n    }\n\n    public function testAddingColumnWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->instant();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null, algorithm=instant', $statements[0]);\n    }\n\n    public function testChangingColumnWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name', 100)->change()->instant();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` modify `name` varchar(100) not null, algorithm=instant', $statements[0]);\n    }\n\n    public function testDroppingColumnWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('name')->instant();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `name`, algorithm=instant', $statements[0]);\n    }\n\n    public function testAddingColumnWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null, lock=none', $statements[0]);\n    }\n\n    public function testChangingColumnWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name', 100)->change()->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` modify `name` varchar(100) not null, lock=none', $statements[0]);\n    }\n\n    public function testDroppingColumnWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('name')->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` drop `name`, lock=none', $statements[0]);\n    }\n\n    public function testColumnWithBothAlgorithmAndLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('name')->instant()->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add `name` varchar(255) not null, algorithm=instant, lock=none', $statements[0]);\n    }\n\n    public function testAddingIndexWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index('name')->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `users_name_index`(`name`), lock=none', $statements[0]);\n    }\n\n    public function testAddingUniqueIndexWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('email')->lock('shared');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add unique `users_email_unique`(`email`), lock=shared', $statements[0]);\n    }\n\n    public function testAddingPrimaryKeyWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('id')->lock('exclusive');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add primary key (`id`), lock=exclusive', $statements[0]);\n    }\n\n    public function testAddingForeignKeyWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('user_id')->references('id')->on('accounts')->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add constraint `users_user_id_foreign` foreign key (`user_id`) references `accounts` (`id`), lock=none', $statements[0]);\n    }\n\n    public function testAddingFullTextIndexWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fullText('content')->lock('shared');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add fulltext `users_content_fulltext`(`content`), lock=shared', $statements[0]);\n    }\n\n    public function testAddingSpatialIndexWithLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->spatialIndex('location')->lock('default');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add spatial index `users_location_spatialindex`(`location`), lock=default', $statements[0]);\n    }\n\n    public function testIndexWithAlgorithmAndLock()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index('name', 'custom_idx')->algorithm('btree')->lock('none');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table `users` add index `custom_idx` using btree(`name`), lock=none', $statements[0]);\n    }\n\n    public function getGrammar(?Connection $connection = null)\n    {\n        return new MySqlGrammar($connection ?? $this->getConnection());\n    }\n\n    public function getBuilder()\n    {\n        return mock(MySqlBuilder::class);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseMySqlSchemaStateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Generator;\nuse Illuminate\\Database\\MySqlConnection;\nuse Illuminate\\Database\\Schema\\MySqlSchemaState;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\nuse Symfony\\Component\\Process\\Process;\n\nclass DatabaseMySqlSchemaStateTest extends TestCase\n{\n    #[DataProvider('provider')]\n    public function testConnectionString(string $expectedConnectionString, array $expectedVariables, array $dbConfig): void\n    {\n        $connection = $this->createMock(MySqlConnection::class);\n        $connection->method('getConfig')->willReturn($dbConfig);\n\n        $schemaState = new MySqlSchemaState($connection);\n\n        $versionInfo = ['version' => '8.0.0', 'isMariaDb' => false];\n\n        // test connectionString\n        $method = new ReflectionMethod(get_class($schemaState), 'connectionString');\n        $connString = $method->invoke($schemaState, $versionInfo);\n\n        self::assertEquals($expectedConnectionString, $connString);\n\n        // test baseVariables\n        $method = new ReflectionMethod(get_class($schemaState), 'baseVariables');\n        $variables = $method->invoke($schemaState, $dbConfig);\n\n        self::assertEquals($expectedVariables, $variables);\n    }\n\n    public static function provider(): Generator\n    {\n        yield 'default' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '127.0.0.1',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'host' => '127.0.0.1',\n                'database' => 'forge',\n            ],\n        ];\n\n        yield 'ssl_ca' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl-ca=\"${:LARAVEL_LOAD_SSL_CA}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => 'ssl.ca',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA => 'ssl.ca',\n                ],\n            ],\n        ];\n\n        yield 'ssl_cert_and_key' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl-ca=\"${:LARAVEL_LOAD_SSL_CA}\" --ssl-cert=\"${:LARAVEL_LOAD_SSL_CERT}\" --ssl-key=\"${:LARAVEL_LOAD_SSL_KEY}\"', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => 'ssl.ca',\n                'LARAVEL_LOAD_SSL_CERT' => '/path/to/client-cert.pem',\n                'LARAVEL_LOAD_SSL_KEY' => '/path/to/client-key.pem',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CA : \\PDO::MYSQL_ATTR_SSL_CA => 'ssl.ca',\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_CERT : \\PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_KEY : \\PDO::MYSQL_ATTR_SSL_KEY => '/path/to/client-key.pem',\n                ],\n            ],\n        ];\n\n        yield 'no_ssl' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --host=\"${:LARAVEL_LOAD_HOST}\" --port=\"${:LARAVEL_LOAD_PORT}\" --ssl-mode=DISABLED', [\n                'LARAVEL_LOAD_SOCKET' => '',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'options' => [\n                    PHP_VERSION_ID >= 80500 ? \\Pdo\\Mysql::ATTR_SSL_VERIFY_SERVER_CERT : \\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,\n                ],\n            ],\n        ];\n\n        yield 'unix socket' => [\n            ' --user=\"${:LARAVEL_LOAD_USER}\" --password=\"${:LARAVEL_LOAD_PASSWORD}\" --socket=\"${:LARAVEL_LOAD_SOCKET}\"', [\n                'LARAVEL_LOAD_SOCKET' => '/tmp/mysql.sock',\n                'LARAVEL_LOAD_HOST' => '',\n                'LARAVEL_LOAD_PORT' => '',\n                'LARAVEL_LOAD_USER' => 'root',\n                'LARAVEL_LOAD_PASSWORD' => '',\n                'LARAVEL_LOAD_DATABASE' => 'forge',\n                'LARAVEL_LOAD_SSL_CA' => '',\n                'LARAVEL_LOAD_SSL_CERT' => '',\n                'LARAVEL_LOAD_SSL_KEY' => '',\n            ], [\n                'username' => 'root',\n                'database' => 'forge',\n                'unix_socket' => '/tmp/mysql.sock',\n            ],\n        ];\n    }\n\n    public function testExecuteDumpProcessForDepth()\n    {\n        $mockProcess = $this->createMock(Process::class);\n        $mockProcess->method('setTimeout')->willReturnSelf();\n        $mockProcess->method('mustRun')->will(\n            $this->throwException(new Exception('column-statistics'))\n        );\n\n        $mockOutput = $this->createMock(\\stdClass::class);\n        $mockVariables = [];\n\n        $schemaState = $this->getMockBuilder(MySqlSchemaState::class)\n            ->disableOriginalConstructor()\n            ->onlyMethods(['makeProcess'])\n            ->getMock();\n\n        $schemaState->method('makeProcess')->willReturn($mockProcess);\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Dump execution exceeded maximum depth of 30.');\n\n        // test executeDumpProcess\n        $method = new ReflectionMethod(get_class($schemaState), 'executeDumpProcess');\n        $method->invoke($schemaState, $mockProcess, $mockOutput, $mockVariables, 31);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabasePostgresBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Processors\\PostgresProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar;\nuse Illuminate\\Database\\Schema\\PostgresBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabasePostgresBuilderTest extends TestCase\n{\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new PostgresGrammar($connection);\n\n        $connection->shouldReceive('getConfig')->once()->with('charset')->andReturn('utf8');\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'create database \"my_temporary_database\" encoding \"utf8\"'\n        )->andReturn(true);\n\n        $builder = $this->getBuilder($connection);\n        $builder->createDatabase('my_temporary_database');\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new PostgresGrammar($connection);\n\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'drop database if exists \"my_database_a\"'\n        )->andReturn(true);\n\n        $builder = $this->getBuilder($connection);\n\n        $builder->dropDatabaseIfExists('my_database_a');\n    }\n\n    public function testHasTableWhenSchemaUnqualifiedAndSearchPathMissing()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn(null);\n        $connection->shouldReceive('getConfig')->with('schema')->andReturn(null);\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileTableExists')->andReturn('sql');\n        $connection->shouldReceive('scalar')->with('sql')->andReturn(1);\n        $connection->shouldReceive('getTablePrefix');\n        $builder = $this->getBuilder($connection);\n\n        $this->assertTrue($builder->hasTable('foo'));\n        $this->assertTrue($builder->hasTable('public.foo'));\n    }\n\n    public function testHasTableWhenSchemaUnqualifiedAndSearchPathFilled()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('myapp,public');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileTableExists')->andReturn('sql');\n        $connection->shouldReceive('scalar')->with('sql')->andReturn(1);\n        $connection->shouldReceive('getTablePrefix');\n        $builder = $this->getBuilder($connection);\n\n        $this->assertTrue($builder->hasTable('foo'));\n        $this->assertTrue($builder->hasTable('myapp.foo'));\n    }\n\n    public function testHasTableWhenSchemaUnqualifiedAndSearchPathFallbackFilled()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn(null);\n        $connection->shouldReceive('getConfig')->with('schema')->andReturn(['myapp', 'public']);\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileTableExists')->andReturn('sql');\n        $connection->shouldReceive('scalar')->with('sql')->andReturn(1);\n        $connection->shouldReceive('getTablePrefix');\n        $builder = $this->getBuilder($connection);\n\n        $this->assertTrue($builder->hasTable('foo'));\n        $this->assertTrue($builder->hasTable('myapp.foo'));\n    }\n\n    public function testHasTableWhenSchemaUnqualifiedAndSearchPathIsUserVariable()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser');\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('$user');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileTableExists')->andReturn('sql');\n        $connection->shouldReceive('scalar')->with('sql')->andReturn(1);\n        $connection->shouldReceive('getTablePrefix');\n        $builder = $this->getBuilder($connection);\n\n        $this->assertTrue($builder->hasTable('foo'));\n        $this->assertTrue($builder->hasTable('foouser.foo'));\n    }\n\n    public function testHasTableWhenSchemaQualifiedAndSearchPathMismatches()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileTableExists')->andReturn('sql');\n        $connection->shouldReceive('scalar')->with('sql')->andReturn(1);\n        $connection->shouldReceive('getTablePrefix');\n        $builder = $this->getBuilder($connection);\n\n        $this->assertTrue($builder->hasTable('myapp.foo'));\n    }\n\n    public function testHasTableWhenDatabaseAndSchemaQualifiedAndSearchPathMismatches()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $connection = $this->getConnection();\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $builder = $this->getBuilder($connection);\n\n        $builder->hasTable('mydatabase.myapp.foo');\n    }\n\n    public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathMissing()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn(null);\n        $connection->shouldReceive('getConfig')->with('schema')->andReturn(null);\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileColumns')->with(null, 'foo')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]);\n        $connection->shouldReceive('getTablePrefix');\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]);\n        $builder = $this->getBuilder($connection);\n\n        $builder->getColumnListing('foo');\n    }\n\n    public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathFilled()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('myapp,public');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileColumns')->with(null, 'foo')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]);\n        $connection->shouldReceive('getTablePrefix');\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]);\n        $builder = $this->getBuilder($connection);\n\n        $builder->getColumnListing('foo');\n    }\n\n    public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathIsUserVariable()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser');\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('$user');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileColumns')->with(null, 'foo')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]);\n        $connection->shouldReceive('getTablePrefix');\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]);\n        $builder = $this->getBuilder($connection);\n\n        $builder->getColumnListing('foo');\n    }\n\n    public function testGetColumnListingWhenSchemaQualifiedAndSearchPathMismatches()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $grammar->shouldReceive('compileColumns')->with('myapp', 'foo')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]);\n        $connection->shouldReceive('getTablePrefix');\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]);\n        $builder = $this->getBuilder($connection);\n\n        $builder->getColumnListing('myapp.foo');\n    }\n\n    public function testGetColumnWhenDatabaseAndSchemaQualifiedAndSearchPathMismatches()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public');\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $builder = $this->getBuilder($connection);\n\n        $builder->getColumnListing('mydatabase.myapp.foo');\n    }\n\n    public function testDropAllTablesWhenSearchPathIsString()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public');\n        $connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);\n        $grammar = m::mock(PostgresGrammar::class);\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $grammar->shouldReceive('compileTables')->andReturn('sql');\n        $processor->shouldReceive('processTables')->once()->andReturn([['name' => 'users', 'schema' => 'public', 'schema_qualified_name' => 'public.users']]);\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'users', 'schema' => 'public', 'schema_qualified_name' => 'public.users']]);\n        $grammar->shouldReceive('compileDropAllTables')->with(['public.users'])->andReturn('drop table \"public\".\"users\" cascade');\n        $connection->shouldReceive('statement')->with('drop table \"public\".\"users\" cascade');\n        $builder = $this->getBuilder($connection);\n\n        $builder->dropAllTables();\n    }\n\n    public function testDropAllTablesWhenSearchPathIsStringOfMany()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser');\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn('\"$user\", public, foo_bar-Baz.Áüõß');\n        $connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);\n        $grammar = m::mock(PostgresGrammar::class);\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processTables')->once()->andReturn([['name' => 'users', 'schema' => 'foouser', 'schema_qualified_name' => 'foouser.users']]);\n        $grammar->shouldReceive('compileTables')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'users', 'schema' => 'foouser', 'schema_qualified_name' => 'foouser.users']]);\n        $grammar->shouldReceive('compileDropAllTables')->with(['foouser.users'])->andReturn('drop table \"foouser\".\"users\" cascade');\n        $connection->shouldReceive('statement')->with('drop table \"foouser\".\"users\" cascade');\n        $builder = $this->getBuilder($connection);\n\n        $builder->dropAllTables();\n    }\n\n    public function testDropAllTablesWhenSearchPathIsArrayOfMany()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser');\n        $connection->shouldReceive('getConfig')->with('search_path')->andReturn([\n            '$user',\n            '\"dev\"',\n            \"'test'\",\n            'spaced schema',\n        ]);\n        $connection->shouldReceive('getConfig')->with('dont_drop')->andReturn(['foo']);\n        $grammar = m::mock(PostgresGrammar::class);\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processTables')->once()->andReturn([['name' => 'users', 'schema' => 'foouser', 'schema_qualified_name' => 'foouser.users']]);\n        $grammar->shouldReceive('compileTables')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'users', 'schema' => 'foouser', 'schema_qualified_name' => 'foouser.users']]);\n        $grammar->shouldReceive('compileDropAllTables')->with(['foouser.users'])->andReturn('drop table \"foouser\".\"users\" cascade');\n        $connection->shouldReceive('statement')->with('drop table \"foouser\".\"users\" cascade');\n        $builder = $this->getBuilder($connection);\n\n        $builder->dropAllTables();\n    }\n\n    protected function getConnection()\n    {\n        return m::mock(Connection::class);\n    }\n\n    protected function getBuilder($connection)\n    {\n        return new PostgresBuilder($connection);\n    }\n\n    protected function getGrammar()\n    {\n        return new PostgresGrammar;\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabasePostgresProcessorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Query\\Processors\\PostgresProcessor;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabasePostgresProcessorTest extends TestCase\n{\n    public function testProcessColumns()\n    {\n        $processor = new PostgresProcessor;\n\n        $listing = [\n            ['name' => 'id', 'type_name' => 'int4', 'type' => 'integer', 'collation' => '', 'nullable' => true, 'default' => \"nextval('employee_id_seq'::regclass)\", 'comment' => '', 'generated' => false],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'character varying(100)', 'collation' => 'collate', 'nullable' => false, 'default' => '', 'comment' => 'foo', 'generated' => false],\n            ['name' => 'balance', 'type_name' => 'numeric', 'type' => 'numeric(8,2)', 'collation' => '', 'nullable' => true, 'default' => '4', 'comment' => 'NULL', 'generated' => false],\n            ['name' => 'birth_date', 'type_name' => 'timestamp', 'type' => 'timestamp(6) without time zone', 'collation' => '', 'nullable' => false, 'default' => '', 'comment' => '', 'generated' => false],\n        ];\n        $expected = [\n            ['name' => 'id', 'type_name' => 'int4', 'type' => 'integer', 'collation' => '', 'nullable' => true, 'default' => \"nextval('employee_id_seq'::regclass)\", 'auto_increment' => true, 'comment' => '', 'generation' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'character varying(100)', 'collation' => 'collate', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => 'foo', 'generation' => null],\n            ['name' => 'balance', 'type_name' => 'numeric', 'type' => 'numeric(8,2)', 'collation' => '', 'nullable' => true, 'default' => '4', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],\n            ['name' => 'birth_date', 'type_name' => 'timestamp', 'type' => 'timestamp(6) without time zone', 'collation' => '', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => '', 'generation' => null],\n        ];\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n\n        // convert listing to objects to simulate PDO::FETCH_CLASS\n        foreach ($listing as &$row) {\n            $row = (object) $row;\n        }\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabasePostgresQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Grammars\\PostgresGrammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabasePostgresQueryGrammarTest extends TestCase\n{\n    public function testToRawSql()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('escape')->with('foo', false)->andReturn(\"'foo'\");\n        $grammar = new PostgresGrammar($connection);\n\n        $query = $grammar->substituteBindingsIntoRawSql(\n            'select * from \"users\" where \\'{}\\' ?? \\'Hello\\\\\\'\\\\\\'World?\\' AND \"email\" = ?',\n            ['foo'],\n        );\n\n        $this->assertSame('select * from \"users\" where \\'{}\\' ? \\'Hello\\\\\\'\\\\\\'World?\\' AND \"email\" = \\'foo\\'', $query);\n    }\n\n    public function testCustomOperators()\n    {\n        PostgresGrammar::customOperators(['@@@', '@>', '']);\n        PostgresGrammar::customOperators(['@@>', 1]);\n\n        $connection = m::mock(Connection::class);\n        $grammar = new PostgresGrammar($connection);\n\n        $operators = $grammar->getOperators();\n\n        $this->assertIsList($operators);\n        $this->assertContains('@@@', $operators);\n        $this->assertContains('@@>', $operators);\n        $this->assertNotContains('', $operators);\n        $this->assertNotContains(1, $operators);\n        $this->assertSame(array_unique($operators), $operators);\n    }\n\n    public function testCompileTruncate()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n\n        $postgres = new PostgresGrammar($connection);\n        $builder = m::mock(Builder::class);\n        $builder->from = 'users';\n\n        $this->assertEquals([\n            'truncate \"users\" restart identity cascade' => [],\n        ], $postgres->compileTruncate($builder));\n\n        PostgresGrammar::cascadeOnTruncate(false);\n\n        $this->assertEquals([\n            'truncate \"users\" restart identity' => [],\n        ], $postgres->compileTruncate($builder));\n\n        PostgresGrammar::cascadeOnTruncate();\n\n        $this->assertEquals([\n            'truncate \"users\" restart identity cascade' => [],\n        ], $postgres->compileTruncate($builder));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabasePostgresSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Processors\\PostgresProcessor;\nuse Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar;\nuse Illuminate\\Database\\Schema\\PostgresBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabasePostgresSchemaBuilderTest extends TestCase\n{\n    public function testHasTable()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(PostgresGrammar::class);\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $builder = new PostgresBuilder($connection);\n        $grammar->shouldReceive('compileTableExists')->twice()->andReturn('sql');\n        $connection->shouldReceive('getTablePrefix')->twice()->andReturn('prefix_');\n        $connection->shouldReceive('scalar')->twice()->with('sql')->andReturn(1);\n\n        $this->assertTrue($builder->hasTable('table'));\n        $this->assertTrue($builder->hasTable('public.table'));\n    }\n\n    public function testGetColumnListing()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(PostgresGrammar::class);\n        $processor = m::mock(PostgresProcessor::class);\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $grammar->shouldReceive('compileColumns')->with(null, 'prefix_table')->once()->andReturn('sql');\n        $processor->shouldReceive('processColumns')->once()->andReturn([['name' => 'column']]);\n        $builder = new PostgresBuilder($connection);\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql')->andReturn([['name' => 'column']]);\n\n        $this->assertEquals(['column'], $builder->getColumnListing('table'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabasePostgresSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Database\\Schema\\ForeignIdColumnDefinition;\nuse Illuminate\\Database\\Schema\\Grammars\\PostgresGrammar;\nuse Illuminate\\Database\\Schema\\PostgresBuilder;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Foo;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabasePostgresSchemaGrammarTest extends TestCase\n{\n    public function testBasicCreateTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $blueprint->string('name')->collation('nb_NO.utf8');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"id\" serial not null primary key, \"email\" varchar(255) not null, \"name\" varchar(255) collate \"nb_NO.utf8\" not null)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add column \"id\" serial not null primary key',\n            'alter table \"users\" add column \"email\" varchar(255) not null',\n        ], $statements);\n    }\n\n    public function testAddingVector()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'embeddings');\n        $blueprint->vector('embedding', 384);\n        $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"embeddings\" add column \"embedding\" vector(384) not null', $statements[0]);\n    }\n\n    public function testAddingTsvectorColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'test');\n        $blueprint->tsvector('search_vector');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"test\" add column \"search_vector\" tsvector not null', $statements[0]);\n    }\n\n    public function testAddingNullableTsvectorColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'test');\n        $blueprint->tsvector('search_vector')->nullable();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"test\" add column \"search_vector\" tsvector null', $statements[0]);\n    }\n\n    public function testAddingTsvectorColumnWithStoredAs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'test');\n        $blueprint->tsvector('search_vector')->nullable()->storedAs(\"to_tsvector('english', coalesce(name, ''))\");\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"test\" add column \"search_vector\" tsvector null generated always as (to_tsvector(\\'english\\', coalesce(name, \\'\\'))) stored', $statements[0]);\n    }\n\n    public function testCreateTableWithAutoIncrementStartingValue()\n    {\n        $connection = $this->getConnection();\n        $connection->getSchemaBuilder()->shouldReceive('parseSchemaAndTable')->andReturn([null, 'users']);\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->create();\n        $blueprint->increments('id')->startingValue(1000);\n        $blueprint->string('email');\n        $blueprint->string('name')->collation('nb_NO.utf8');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create table \"users\" (\"id\" serial not null primary key, \"email\" varchar(255) not null, \"name\" varchar(255) collate \"nb_NO.utf8\" not null)', $statements[0]);\n        $this->assertSame(\"select setval(pg_get_serial_sequence('\\\"users\\\"', 'id'), 1000, false)\", $statements[1]);\n    }\n\n    public function testAddColumnsWithMultipleAutoIncrementStartingValue()\n    {\n        $builder = $this->getBuilder();\n        $builder->shouldReceive('parseSchemaAndTable')->andReturn([null, 'users']);\n\n        $blueprint = new Blueprint($this->getConnection(builder: $builder), 'users');\n        $blueprint->id()->from(100);\n        $blueprint->increments('code')->from(200);\n        $blueprint->string('name')->from(300);\n        $statements = $blueprint->toSql();\n\n        $this->assertEquals([\n            'alter table \"users\" add column \"id\" bigserial not null primary key',\n            'alter table \"users\" add column \"code\" serial not null primary key',\n            'alter table \"users\" add column \"name\" varchar(255) not null',\n            \"select setval(pg_get_serial_sequence('\\\"users\\\"', 'id'), 100, false)\",\n            \"select setval(pg_get_serial_sequence('\\\"users\\\"', 'code'), 200, false)\",\n        ], $statements);\n    }\n\n    public function testCreateTableAndCommentColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email')->comment('my first comment');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create table \"users\" (\"id\" serial not null primary key, \"email\" varchar(255) not null)', $statements[0]);\n        $this->assertSame('comment on column \"users\".\"email\" is \\'my first comment\\'', $statements[1]);\n    }\n\n    public function testCreateTemporaryTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create temporary table \"users\" (\"id\" serial not null primary key, \"email\" varchar(255) not null)', $statements[0]);\n    }\n\n    public function testDropTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table \"users\"', $statements[0]);\n    }\n\n    public function testDropTableIfExists()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table if exists \"users\"', $statements[0]);\n    }\n\n    public function testDropColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop column \"foo\"', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn(['foo', 'bar']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop column \"foo\", drop column \"bar\"', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop column \"foo\", drop column \"bar\"', $statements[0]);\n    }\n\n    public function testDropPrimary()\n    {\n        $connection = $this->getConnection();\n        $connection->getSchemaBuilder()->shouldReceive('parseSchemaAndTable')->andReturn([null, 'users']);\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->dropPrimary();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"users_pkey\"', $statements[0]);\n    }\n\n    public function testDropUnique()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropUnique('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"foo\"', $statements[0]);\n    }\n\n    public function testDropIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"foo\"', $statements[0]);\n    }\n\n    public function testDropSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"geo_coordinates_spatialindex\"', $statements[0]);\n    }\n\n    public function testDropForeign()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropForeign('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"foo\"', $statements[0]);\n    }\n\n    public function testDropTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestamps();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop column \"created_at\", drop column \"updated_at\"', $statements[0]);\n    }\n\n    public function testDropTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestampsTz();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop column \"created_at\", drop column \"updated_at\"', $statements[0]);\n    }\n\n    public function testDropMorphs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'photos');\n        $blueprint->dropMorphs('imageable');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('drop index \"photos_imageable_type_imageable_id_index\"', $statements[0]);\n        $this->assertSame('alter table \"photos\" drop column \"imageable_type\", drop column \"imageable_id\"', $statements[1]);\n    }\n\n    public function testRenameTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rename('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" rename to \"foo\"', $statements[0]);\n    }\n\n    public function testRenameIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->renameIndex('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter index \"foo\" rename to \"bar\"', $statements[0]);\n    }\n\n    public function testAddingPrimaryKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add primary key (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"bar\" unique (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKeyWithNullsNotDistinct()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar')->nullsNotDistinct();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"bar\" unique nulls not distinct (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKeyWithNullsDistinct()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar')->nullsNotDistinct(false);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"bar\" unique nulls distinct (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKeyOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create unique index concurrently \"users_foo_unique\" on \"users\" (\"foo\")', $statements[0]);\n        $this->assertSame('alter table \"users\" add constraint \"users_foo_unique\" unique using index \"users_foo_unique\"', $statements[1]);\n    }\n\n    public function testAddingIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"baz\" on \"users\" (\"foo\", \"bar\")', $statements[0]);\n    }\n\n    public function testAddingIndexWithAlgorithm()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz', 'hash');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"baz\" on \"users\" using hash (\"foo\", \"bar\")', $statements[0]);\n    }\n\n    public function testAddingIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index('foo', 'baz')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"baz\" on \"users\" (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingFulltextIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext('body');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"users_body_fulltext\" on \"users\" using gin ((to_tsvector(\\'english\\', \"body\")))', $statements[0]);\n    }\n\n    public function testAddingFulltextIndexMultipleColumns()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext(['body', 'title']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"users_body_title_fulltext\" on \"users\" using gin ((to_tsvector(\\'english\\', \"body\") || to_tsvector(\\'english\\', \"title\")))', $statements[0]);\n    }\n\n    public function testAddingFulltextIndexWithLanguage()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext('body')->language('spanish');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"users_body_fulltext\" on \"users\" using gin ((to_tsvector(\\'spanish\\', \"body\")))', $statements[0]);\n    }\n\n    public function testAddingFulltextIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->fulltext('body')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"users_body_fulltext\" on \"users\" using gin ((to_tsvector(\\'english\\', \"body\")))', $statements[0]);\n    }\n\n    public function testAddingFulltextIndexWithFluency()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('body')->fulltext();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create index \"users_body_fulltext\" on \"users\" using gin ((to_tsvector(\\'english\\', \"body\")))', $statements[1]);\n    }\n\n    public function testAddingSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"geo_coordinates_spatialindex\" on \"geo\" using gist (\"coordinates\")', $statements[0]);\n    }\n\n    public function testAddingSpatialIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"geo_coordinates_spatialindex\" on \"geo\" using gist (\"coordinates\")', $statements[0]);\n    }\n\n    public function testAddingFluentSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point')->spatialIndex();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create index \"geo_coordinates_spatialindex\" on \"geo\" using gist (\"coordinates\")', $statements[1]);\n    }\n\n    public function testAddingSpatialIndexWithOperatorClass()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates', 'my_index', 'point_ops');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"my_index\" on \"geo\" using gist (\"coordinates\" point_ops)', $statements[0]);\n    }\n\n    public function testAddingSpatialIndexWithOperatorClassMultipleColumns()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex(['coordinates', 'location'], 'my_index', 'point_ops');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"my_index\" on \"geo\" using gist (\"coordinates\" point_ops, \"location\" point_ops)', $statements[0]);\n    }\n\n    public function testAddingSpatialIndexWithOperatorClassOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates', 'my_index', 'point_ops')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"my_index\" on \"geo\" using gist (\"coordinates\" point_ops)', $statements[0]);\n    }\n\n    public function testAddingVectorIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'posts');\n        $blueprint->vectorIndex('embeddings');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"posts_embeddings_vectorindex\" on \"posts\" using hnsw (\"embeddings\" vector_cosine_ops)', $statements[0]);\n    }\n\n    public function testAddingVectorIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'posts');\n        $blueprint->vectorIndex('embeddings')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"posts_embeddings_vectorindex\" on \"posts\" using hnsw (\"embeddings\" vector_cosine_ops)', $statements[0]);\n    }\n\n    public function testAddingVectorIndexWithName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'posts');\n        $blueprint->vectorIndex('embeddings', 'my_vector_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"my_vector_index\" on \"posts\" using hnsw (\"embeddings\" vector_cosine_ops)', $statements[0]);\n    }\n\n    public function testAddingFluentVectorIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'posts');\n        $blueprint->vector('embeddings', 1536)->vectorIndex();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create index \"posts_embeddings_vectorindex\" on \"posts\" using hnsw (\"embeddings\" vector_cosine_ops)', $statements[1]);\n    }\n\n    public function testAddingFluentIndexOnVectorColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'posts');\n        $blueprint->vector('embeddings', 1536)->index();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create index \"posts_embeddings_vectorindex\" on \"posts\" using hnsw (\"embeddings\" vector_cosine_ops)', $statements[1]);\n    }\n\n    public function testAddingRawIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"raw_index\" on \"users\" ((function(column)))', $statements[0]);\n    }\n\n    public function testAddingRawIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index concurrently \"raw_index\" on \"users\" ((function(column)))', $statements[0]);\n    }\n\n    public function testAddingIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" serial not null primary key', $statements[0]);\n    }\n\n    public function testAddingSmallIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" smallserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingMediumIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" serial not null primary key', $statements[0]);\n    }\n\n    public function testAddingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" bigserial not null primary key', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" bigserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingForeignID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignId = $blueprint->foreignId('foo');\n        $blueprint->foreignId('company_id')->constrained();\n        $blueprint->foreignId('laravel_idea_id')->constrained();\n        $blueprint->foreignId('team_id')->references('id')->on('teams');\n        $blueprint->foreignId('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" bigint not null',\n            'alter table \"users\" add column \"company_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_company_id_foreign\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n            'alter table \"users\" add column \"laravel_idea_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_laravel_idea_id_foreign\" foreign key (\"laravel_idea_id\") references \"laravel_ideas\" (\"id\")',\n            'alter table \"users\" add column \"team_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_team_id_foreign\" foreign key (\"team_id\") references \"teams\" (\"id\")',\n            'alter table \"users\" add column \"team_column_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_team_column_id_foreign\" foreign key (\"team_column_id\") references \"teams\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingForeignIdSpecifyingIndexNameInConstraint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreignId('company_id')->constrained(indexName: 'my_index');\n        $statements = $blueprint->toSql();\n        $this->assertSame([\n            'alter table \"users\" add column \"company_id\" bigint not null',\n            'alter table \"users\" add constraint \"my_index\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingBigIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" bigserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar(255) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar(100) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar(100) null default \\'bar\\'', $statements[0]);\n    }\n\n    public function testAddingStringWithoutLengthLimit()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar(255) not null', $statements[0]);\n\n        Builder::$defaultStringLength = null;\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        try {\n            $this->assertCount(1, $statements);\n            $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n        } finally {\n            Builder::$defaultStringLength = 255;\n        }\n    }\n\n    public function testAddingCharWithoutLengthLimit()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->char('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" char(255) not null', $statements[0]);\n\n        Builder::$defaultStringLength = null;\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->char('foo');\n        $statements = $blueprint->toSql();\n\n        try {\n            $this->assertCount(1, $statements);\n            $this->assertSame('alter table \"users\" add column \"foo\" char not null', $statements[0]);\n        } finally {\n            Builder::$defaultStringLength = 255;\n        }\n    }\n\n    public function testAddingText()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->text('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" text not null', $statements[0]);\n    }\n\n    public function testAddingBigInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" bigint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" bigserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" serial not null primary key', $statements[0]);\n    }\n\n    public function testAddingMediumInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" serial not null primary key', $statements[0]);\n    }\n\n    public function testAddingTinyInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" smallint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" smallserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingSmallInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" smallint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" smallserial not null primary key', $statements[0]);\n    }\n\n    public function testAddingFloat()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->float('foo', 5);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" float(5) not null', $statements[0]);\n    }\n\n    public function testAddingDouble()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->double('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" double precision not null', $statements[0]);\n    }\n\n    public function testAddingDecimal()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->decimal('foo', 5, 2);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" decimal(5, 2) not null', $statements[0]);\n    }\n\n    public function testAddingBoolean()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->boolean('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" boolean not null', $statements[0]);\n    }\n\n    public function testAddingEnum()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->enum('role', ['member', 'admin']);\n        $blueprint->enum('status', Foo::cases());\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table \"users\" add column \"role\" varchar(255) check (\"role\" in (\\'member\\', \\'admin\\')) not null', $statements[0]);\n        $this->assertSame('alter table \"users\" add column \"status\" varchar(255) check (\"status\" in (\\'bar\\')) not null', $statements[1]);\n    }\n\n    public function testAddingDate()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" date not null', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" date not null default CURRENT_DATE', $statements[0]);\n    }\n\n    public function testAddingYear()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"birth_year\" integer not null', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"birth_year\" integer not null default EXTRACT(YEAR FROM CURRENT_DATE)', $statements[0]);\n    }\n\n    public function testAddingJson()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" json not null', $statements[0]);\n    }\n\n    public function testAddingJsonb()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" jsonb not null', $statements[0]);\n    }\n\n    #[DataProvider('datetimeAndPrecisionProvider')]\n    public function testAddingDatetimeMethods(string $method, string $type, ?int $userPrecision, false|int|null $grammarPrecision, ?int $expected)\n    {\n        PostgresBuilder::defaultTimePrecision($grammarPrecision);\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->{$method}('created_at', $userPrecision);\n        $statements = $blueprint->toSql();\n        $type = is_null($expected) ? $type : \"{$type}({$expected})\";\n        $with = str_contains($method, 'Tz') ? 'with' : 'without';\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"alter table \\\"users\\\" add column \\\"created_at\\\" {$type} {$with} time zone not null\", $statements[0]);\n    }\n\n    #[TestWith(['timestamps'])]\n    #[TestWith(['timestampsTz'])]\n    public function testAddingTimestamps(string $method)\n    {\n        PostgresBuilder::defaultTimePrecision(0);\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->{$method}();\n        $statements = $blueprint->toSql();\n        $with = str_contains($method, 'Tz') ? 'with' : 'without';\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            \"alter table \\\"users\\\" add column \\\"created_at\\\" timestamp(0) {$with} time zone null\",\n            \"alter table \\\"users\\\" add column \\\"updated_at\\\" timestamp(0) {$with} time zone null\",\n        ], $statements);\n    }\n\n    public function testAddingBinary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->binary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" bytea not null', $statements[0]);\n    }\n\n    public function testAddingUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" uuid not null', $statements[0]);\n    }\n\n    public function testAddingUuidDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"uuid\" uuid not null', $statements[0]);\n    }\n\n    public function testAddingForeignUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignUuid = $blueprint->foreignUuid('foo');\n        $blueprint->foreignUuid('company_id')->constrained();\n        $blueprint->foreignUuid('laravel_idea_id')->constrained();\n        $blueprint->foreignUuid('team_id')->references('id')->on('teams');\n        $blueprint->foreignUuid('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" uuid not null',\n            'alter table \"users\" add column \"company_id\" uuid not null',\n            'alter table \"users\" add constraint \"users_company_id_foreign\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n            'alter table \"users\" add column \"laravel_idea_id\" uuid not null',\n            'alter table \"users\" add constraint \"users_laravel_idea_id_foreign\" foreign key (\"laravel_idea_id\") references \"laravel_ideas\" (\"id\")',\n            'alter table \"users\" add column \"team_id\" uuid not null',\n            'alter table \"users\" add constraint \"users_team_id_foreign\" foreign key (\"team_id\") references \"teams\" (\"id\")',\n            'alter table \"users\" add column \"team_column_id\" uuid not null',\n            'alter table \"users\" add constraint \"users_team_column_id_foreign\" foreign key (\"team_column_id\") references \"teams\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingGeneratedAs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('foo')->generatedAs();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null generated by default as identity primary key', $statements[0]);\n        // With always modifier\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('foo')->generatedAs()->always();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null generated always as identity primary key', $statements[0]);\n        // With sequence options\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('foo')->generatedAs('increment by 10 start with 100');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null generated by default as identity (increment by 10 start with 100) primary key', $statements[0]);\n        // Not a primary key\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo')->generatedAs();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null generated by default as identity', $statements[0]);\n    }\n\n    public function testAddingVirtualAs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo')->nullable();\n        $blueprint->boolean('bar')->virtualAs('foo is not null');\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" integer null',\n            'alter table \"users\" add column \"bar\" boolean not null generated always as (foo is not null) virtual',\n        ], $statements);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo')->nullable();\n        $blueprint->boolean('bar')->virtualAs(new Expression('foo is not null'));\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" integer null',\n            'alter table \"users\" add column \"bar\" boolean not null generated always as (foo is not null) virtual',\n        ], $statements);\n    }\n\n    public function testAddingStoredAs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo')->nullable();\n        $blueprint->boolean('bar')->storedAs('foo is not null');\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" integer null',\n            'alter table \"users\" add column \"bar\" boolean not null generated always as (foo is not null) stored',\n        ], $statements);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo')->nullable();\n        $blueprint->boolean('bar')->storedAs(new Expression('foo is not null'));\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" integer null',\n            'alter table \"users\" add column \"bar\" boolean not null generated always as (foo is not null) stored',\n        ], $statements);\n    }\n\n    public function testAddingIpAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" inet not null', $statements[0]);\n    }\n\n    public function testAddingIpAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"ip_address\" inet not null', $statements[0]);\n    }\n\n    public function testAddingMacAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" macaddr not null', $statements[0]);\n    }\n\n    public function testAddingMacAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"mac_address\" macaddr not null', $statements[0]);\n    }\n\n    public function testCompileForeign()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"users_parent_id_foreign\" foreign key (\"parent_id\") references \"parents\" (\"id\") on delete cascade deferrable', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable(false)->initiallyImmediate();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"users_parent_id_foreign\" foreign key (\"parent_id\") references \"parents\" (\"id\") on delete cascade not deferrable', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->initiallyImmediate(false);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"users_parent_id_foreign\" foreign key (\"parent_id\") references \"parents\" (\"id\") on delete cascade deferrable initially deferred', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreign('parent_id')->references('id')->on('parents')->onDelete('cascade')->deferrable()->notValid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"users_parent_id_foreign\" foreign key (\"parent_id\") references \"parents\" (\"id\") on delete cascade deferrable not valid', $statements[0]);\n    }\n\n    public function testAddingGeometry()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry not null', $statements[0]);\n    }\n\n    public function testAddingGeography()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geography('coordinates', 'pointzm', 4269);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geography(pointzm,4269) not null', $statements[0]);\n    }\n\n    public function testAddingPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(point) not null', $statements[0]);\n    }\n\n    public function testAddingPointWithSrid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point', 4269);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(point,4269) not null', $statements[0]);\n    }\n\n    public function testAddingLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'linestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(linestring) not null', $statements[0]);\n    }\n\n    public function testAddingPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'polygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(polygon) not null', $statements[0]);\n    }\n\n    public function testAddingGeometryCollection()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'geometrycollection');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(geometrycollection) not null', $statements[0]);\n    }\n\n    public function testAddingMultiPoint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipoint');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(multipoint) not null', $statements[0]);\n    }\n\n    public function testAddingMultiLineString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multilinestring');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(multilinestring) not null', $statements[0]);\n    }\n\n    public function testAddingMultiPolygon()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'multipolygon');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry(multipolygon) not null', $statements[0]);\n    }\n\n    public function testCreateDatabase()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_foo');\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_a');\n\n        $this->assertSame(\n            'create database \"my_database_a\" encoding \"utf8_foo\"',\n            $statement\n        );\n\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getConfig')->once()->once()->with('charset')->andReturn('utf8_bar');\n        $statement = $this->getGrammar($connection)->compileCreateDatabase('my_database_b');\n\n        $this->assertSame(\n            'create database \"my_database_b\" encoding \"utf8_bar\"',\n            $statement\n        );\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a');\n\n        $this->assertSame(\n            'drop database if exists \"my_database_a\"',\n            $statement\n        );\n\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b');\n\n        $this->assertSame(\n            'drop database if exists \"my_database_b\"',\n            $statement\n        );\n    }\n\n    public function testDropAllTablesEscapesTableNames()\n    {\n        $statement = $this->getGrammar()->compileDropAllTables(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop table \"alpha\", \"beta\", \"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllViewsEscapesTableNames()\n    {\n        $statement = $this->getGrammar()->compileDropAllViews(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop view \"alpha\", \"beta\", \"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllTypesEscapesTableNames()\n    {\n        $statement = $this->getGrammar()->compileDropAllTypes(['alpha', 'beta', 'gamma']);\n\n        $this->assertSame('drop type \"alpha\", \"beta\", \"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllTablesWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllTables(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop table \"schema\".\"alpha\", \"schema\".\"beta\", \"schema\".\"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllViewsWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllViews(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop view \"schema\".\"alpha\", \"schema\".\"beta\", \"schema\".\"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllTypesWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllTypes(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop type \"schema\".\"alpha\", \"schema\".\"beta\", \"schema\".\"gamma\" cascade', $statement);\n    }\n\n    public function testDropAllDomainsWithPrefixAndSchema()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $statement = $this->getGrammar($connection)->compileDropAllDomains(['schema.alpha', 'schema.beta', 'schema.gamma']);\n\n        $this->assertSame('drop domain \"schema\".\"alpha\", \"schema\".\"beta\", \"schema\".\"gamma\" cascade', $statement);\n    }\n\n    public function testCompileColumns()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getServerVersion')->once()->andReturn('12.0.0');\n\n        $statement = $connection->getSchemaGrammar()->compileColumns('public', 'table');\n\n        $this->assertStringContainsString(\"where c.relname = 'table' and n.nspname = 'public'\", $statement);\n    }\n\n    protected function getConnection(\n        ?PostgresGrammar $grammar = null,\n        ?PostgresBuilder $builder = null,\n        string $prefix = ''\n    ) {\n        $connection = m::mock(Connection::class)\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->with('prefix_indexes')->andReturn(null)\n            ->getMock();\n\n        $grammar ??= $this->getGrammar($connection);\n        $builder ??= $this->getBuilder();\n\n        return $connection\n            ->shouldReceive('getSchemaGrammar')->andReturn($grammar)\n            ->shouldReceive('getSchemaBuilder')->andReturn($builder)\n            ->getMock();\n    }\n\n    public function getGrammar(?Connection $connection = null)\n    {\n        return new PostgresGrammar($connection ?? $this->getConnection());\n    }\n\n    public function getBuilder()\n    {\n        return mock(PostgresBuilder::class);\n    }\n\n    /** @return list<array{method: string, type: string, user: int|null, grammar: false|int|null, expected: int|null}> */\n    public static function datetimeAndPrecisionProvider(): array\n    {\n        $methods = [\n            ['method' => 'datetime', 'type' => 'timestamp'],\n            ['method' => 'datetimeTz', 'type' => 'timestamp'],\n            ['method' => 'timestamp', 'type' => 'timestamp'],\n            ['method' => 'timestampTz', 'type' => 'timestamp'],\n            ['method' => 'time', 'type' => 'time'],\n            ['method' => 'timeTz', 'type' => 'time'],\n        ];\n        $precisions = [\n            'user can override grammar default' => ['userPrecision' => 1, 'grammarPrecision' => null, 'expected' => 1],\n            'fallback to grammar default' => ['userPrecision' => null, 'grammarPrecision' => 5, 'expected' => 5],\n            'fallback to database default' => ['userPrecision' => null, 'grammarPrecision' => null, 'expected' => null],\n        ];\n\n        $result = [];\n\n        foreach ($methods as $datetime) {\n            foreach ($precisions as $precision) {\n                $result[] = array_merge($datetime, $precision);\n            }\n        }\n\n        return $result;\n    }\n\n    public function testGrammarsAreMacroable()\n    {\n        // compileReplace macro.\n        $this->getGrammar()::macro('compileReplace', function () {\n            return true;\n        });\n\n        $c = $this->getGrammar()::compileReplace();\n\n        $this->assertTrue($c);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseProcessorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseProcessorTest extends TestCase\n{\n    public function testInsertGetIdProcessing()\n    {\n        $pdo = $this->createMock(ProcessorTestPDOStub::class);\n        $pdo->expects($this->once())->method('lastInsertId')->with($this->equalTo('id'))->willReturn('1');\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('insert')->once()->with('sql', ['foo']);\n        $connection->shouldReceive('getPdo')->once()->andReturn($pdo);\n        $builder = m::mock(Builder::class);\n        $builder->shouldReceive('getConnection')->andReturn($connection);\n        $processor = new Processor;\n        $result = $processor->processInsertGetId($builder, 'sql', ['foo'], 'id');\n        $this->assertSame(1, $result);\n    }\n}\n\nclass ProcessorTestPDOStub extends PDO\n{\n    public function __construct()\n    {\n        //\n    }\n\n    public function lastInsertId($sequence = null): string|false\n    {\n        return '';\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseQueryBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse BadMethodCallException;\nuse Closure;\nuse DateInterval;\nuse DatePeriod;\nuse DateTime;\nuse Illuminate\\Contracts\\Database\\Query\\ConditionExpression;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Eloquent\\Builder as EloquentBuilder;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Expression as Raw;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Grammars\\MariaDbGrammar;\nuse Illuminate\\Database\\Query\\Grammars\\MySqlGrammar;\nuse Illuminate\\Database\\Query\\Grammars\\PostgresGrammar;\nuse Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar;\nuse Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar;\nuse Illuminate\\Database\\Query\\JoinClause;\nuse Illuminate\\Database\\Query\\Processors\\MySqlProcessor;\nuse Illuminate\\Database\\Query\\Processors\\PostgresProcessor;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Database\\RecordNotFoundException;\nuse Illuminate\\Pagination\\AbstractPaginator as Paginator;\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Bar;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse stdClass;\n\ninclude_once 'Enums.php';\n\nclass DatabaseQueryBuilderTest extends TestCase\n{\n    protected $called;\n\n    public function testBasicSelect()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users');\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n    }\n\n    public function testBasicSelectWithGetColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->getProcessor()->shouldReceive('processSelect');\n        $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {\n            $this->assertSame('select * from \"users\"', $sql);\n        });\n        $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {\n            $this->assertSame('select \"foo\", \"bar\" from \"users\"', $sql);\n        });\n        $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {\n            $this->assertSame('select \"baz\" from \"users\"', $sql);\n        });\n\n        $builder->from('users')->get();\n        $this->assertNull($builder->columns);\n\n        $builder->from('users')->get(['foo', 'bar']);\n        $this->assertNull($builder->columns);\n\n        $builder->from('users')->get('baz');\n        $this->assertNull($builder->columns);\n\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n        $this->assertNull($builder->columns);\n    }\n\n    public function testBasicSelectUseWritePdo()\n    {\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->getConnection()->shouldReceive('select')->once()\n            ->with('select * from `users`', [], false, []);\n        $builder->useWritePdo()->select('*')->from('users')->get();\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->getConnection()->shouldReceive('select')->once()\n            ->with('select * from `users`', [], true, []);\n        $builder->select('*')->from('users')->get();\n    }\n\n    public function testBasicTableWrappingProtectsQuotationMarks()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('some\"table');\n        $this->assertSame('select * from \"some\"\"table\"', $builder->toSql());\n    }\n\n    public function testAliasWrappingAsWholeConstant()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('x.y as foo.bar')->from('baz');\n        $this->assertSame('select \"x\".\"y\" as \"foo.bar\" from \"baz\"', $builder->toSql());\n    }\n\n    public function testAliasWrappingWithSpacesInDatabaseName()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('w x.y.z as foo.bar')->from('baz');\n        $this->assertSame('select \"w x\".\"y\".\"z\" as \"foo.bar\" from \"baz\"', $builder->toSql());\n    }\n\n    public function testAddingSelects()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('foo')->addSelect('bar')->addSelect(['baz', 'boom'])->addSelect('bar')->from('users');\n        $this->assertSame('select \"foo\", \"bar\", \"baz\", \"boom\" from \"users\"', $builder->toSql());\n    }\n\n    public function testBasicSelectWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $builder->select('*')->from('users');\n        $this->assertSame('select * from \"prefix_users\"', $builder->toSql());\n    }\n\n    public function testBasicSelectDistinct()\n    {\n        $builder = $this->getBuilder();\n        $builder->distinct()->select('foo', 'bar')->from('users');\n        $this->assertSame('select distinct \"foo\", \"bar\" from \"users\"', $builder->toSql());\n    }\n\n    public function testBasicSelectDistinctOnColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->distinct('foo')->select('foo', 'bar')->from('users');\n        $this->assertSame('select distinct \"foo\", \"bar\" from \"users\"', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->distinct('foo')->select('foo', 'bar')->from('users');\n        $this->assertSame('select distinct on (\"foo\") \"foo\", \"bar\" from \"users\"', $builder->toSql());\n    }\n\n    public function testBasicAlias()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('foo as bar')->from('users');\n        $this->assertSame('select \"foo\" as \"bar\" from \"users\"', $builder->toSql());\n    }\n\n    public function testAliasWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $builder->select('*')->from('users as people');\n        $this->assertSame('select * from \"prefix_users\" as \"prefix_people\"', $builder->toSql());\n    }\n\n    public function testJoinAliasesWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $builder->select('*')->from('services')->join('translations AS t', 't.item_id', '=', 'services.id');\n        $this->assertSame('select * from \"prefix_services\" inner join \"prefix_translations\" as \"prefix_t\" on \"prefix_t\".\"item_id\" = \"prefix_services\".\"id\"', $builder->toSql());\n    }\n\n    public function testBasicTableWrapping()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('public.users');\n        $this->assertSame('select * from \"public\".\"users\"', $builder->toSql());\n    }\n\n    public function testWhenCallback()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertTrue($condition);\n\n            $query->where('id', '=', 1);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when(true, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when(false, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $builder->toSql());\n    }\n\n    public function testWhenCallbackWithReturn()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertTrue($condition);\n\n            return $query->where('id', '=', 1);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when(true, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when(false, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $builder->toSql());\n    }\n\n    public function testWhenCallbackWithDefault()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertSame('truthy', $condition);\n\n            $query->where('id', '=', 1);\n        };\n\n        $default = function ($query, $condition) {\n            $this->assertEquals(0, $condition);\n\n            $query->where('id', '=', 2);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when('truthy', $callback, $default)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->when(0, $callback, $default)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testUnlessCallback()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertFalse($condition);\n\n            $query->where('id', '=', 1);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless(false, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless(true, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $builder->toSql());\n    }\n\n    public function testUnlessCallbackWithReturn()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertFalse($condition);\n\n            return $query->where('id', '=', 1);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless(false, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless(true, $callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $builder->toSql());\n    }\n\n    public function testUnlessCallbackWithDefault()\n    {\n        $callback = function ($query, $condition) {\n            $this->assertEquals(0, $condition);\n\n            $query->where('id', '=', 1);\n        };\n\n        $default = function ($query, $condition) {\n            $this->assertSame('truthy', $condition);\n\n            $query->where('id', '=', 2);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless(0, $callback, $default)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->unless('truthy', $callback, $default)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testTapCallback()\n    {\n        $callback = function ($query) {\n            return $query->where('id', '=', 1);\n        };\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->tap($callback)->where('email', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? and \"email\" = ?', $builder->toSql());\n    }\n\n    public function testPipeCallback()\n    {\n        $query = $this->getBuilder();\n\n        $result = $query->pipe(fn (Builder $query) => 5);\n        $this->assertSame(5, $result);\n\n        $result = $query->pipe(fn (Builder $query) => null);\n        $this->assertSame($query, $result);\n\n        $result = $query->pipe(function (Builder $query) {\n            //\n        });\n        $this->assertSame($query, $result);\n\n        $this->assertCount(0, $query->wheres);\n        $result = $query->pipe(fn (Builder $query) => $query->where('foo', 'bar'));\n        $this->assertSame($query, $result);\n        $this->assertCount(1, $query->wheres);\n    }\n\n    public function testBasicWheres()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $this->assertSame('select * from \"users\" where \"id\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testBasicWhereNot()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot('name', 'foo')->whereNot('name', '<>', 'bar');\n        $this->assertSame('select * from \"users\" where not \"name\" = ? and not \"name\" <> ?', $builder->toSql());\n        $this->assertEquals(['foo', 'bar'], $builder->getBindings());\n    }\n\n    public function testWheresWithArrayValue()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', [12]);\n        $this->assertSame('select * from \"users\" where \"id\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 12], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', [12, 30]);\n        $this->assertSame('select * from \"users\" where \"id\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 12], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '!=', [12, 30]);\n        $this->assertSame('select * from \"users\" where \"id\" != ?', $builder->toSql());\n        $this->assertEquals([0 => 12], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '<>', [12, 30]);\n        $this->assertSame('select * from \"users\" where \"id\" <> ?', $builder->toSql());\n        $this->assertEquals([0 => 12], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', [[12, 30]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 12], $builder->getBindings());\n    }\n\n    public function testMySqlWrappingProtectsQuotationMarks()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->From('some`table');\n        $this->assertSame('select * from `some``table`', $builder->toSql());\n    }\n\n    public function testDateBasedWheresAcceptsTwoArguments()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', 1);\n        $this->assertSame('select * from `users` where date(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', 1);\n        $this->assertSame('select * from `users` where day(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', 1);\n        $this->assertSame('select * from `users` where month(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', 1);\n        $this->assertSame('select * from `users` where year(`created_at`) = ?', $builder->toSql());\n    }\n\n    public function testDateBasedOrWheresAcceptsTwoArguments()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', 1)->orWhereDate('created_at', 1);\n        $this->assertSame('select * from `users` where `id` = ? or date(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', 1)->orWhereDay('created_at', 1);\n        $this->assertSame('select * from `users` where `id` = ? or day(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', 1)->orWhereMonth('created_at', 1);\n        $this->assertSame('select * from `users` where `id` = ? or month(`created_at`) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', 1)->orWhereYear('created_at', 1);\n        $this->assertSame('select * from `users` where `id` = ? or year(`created_at`) = ?', $builder->toSql());\n    }\n\n    public function testDateBasedWheresExpressionIsNotBound()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'))->where('admin', true);\n        $this->assertEquals([true], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', new Raw('NOW()'));\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', new Raw('NOW()'));\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', new Raw('NOW()'));\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testWhereDateMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');\n        $this->assertSame('select * from `users` where date(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', new Raw('NOW()'));\n        $this->assertSame('select * from `users` where date(`created_at`) = NOW()', $builder->toSql());\n    }\n\n    public function testWhereDayMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1);\n        $this->assertSame('select * from `users` where day(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testOrWhereDayMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1)->orWhereDay('created_at', '=', 2);\n        $this->assertSame('select * from `users` where day(`created_at`) = ? or day(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testOrWhereDayPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1)->orWhereDay('created_at', '=', 2);\n        $this->assertSame('select * from \"users\" where extract(day from \"created_at\") = ? or extract(day from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testOrWhereDaySqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1)->orWhereDay('created_at', '=', 2);\n        $this->assertSame('select * from [users] where day([created_at]) = ? or day([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testWhereMonthMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);\n        $this->assertSame('select * from `users` where month(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 5], $builder->getBindings());\n    }\n\n    public function testOrWhereMonthMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5)->orWhereMonth('created_at', '=', 6);\n        $this->assertSame('select * from `users` where month(`created_at`) = ? or month(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 5, 1 => 6], $builder->getBindings());\n    }\n\n    public function testOrWhereMonthPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5)->orWhereMonth('created_at', '=', 6);\n        $this->assertSame('select * from \"users\" where extract(month from \"created_at\") = ? or extract(month from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 5, 1 => 6], $builder->getBindings());\n    }\n\n    public function testOrWhereMonthSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5)->orWhereMonth('created_at', '=', 6);\n        $this->assertSame('select * from [users] where month([created_at]) = ? or month([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 5, 1 => 6], $builder->getBindings());\n    }\n\n    public function testWhereYearMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);\n        $this->assertSame('select * from `users` where year(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014], $builder->getBindings());\n    }\n\n    public function testOrWhereYearMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014)->orWhereYear('created_at', '=', 2015);\n        $this->assertSame('select * from `users` where year(`created_at`) = ? or year(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014, 1 => 2015], $builder->getBindings());\n    }\n\n    public function testOrWhereYearPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014)->orWhereYear('created_at', '=', 2015);\n        $this->assertSame('select * from \"users\" where extract(year from \"created_at\") = ? or extract(year from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014, 1 => 2015], $builder->getBindings());\n    }\n\n    public function testOrWhereYearSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014)->orWhereYear('created_at', '=', 2015);\n        $this->assertSame('select * from [users] where year([created_at]) = ? or year([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014, 1 => 2015], $builder->getBindings());\n    }\n\n    public function testWhereTimeMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from `users` where time(`created_at`) >= ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWhereTimeOperatorOptionalMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '22:00');\n        $this->assertSame('select * from `users` where time(`created_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWhereTimeOperatorOptionalPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '22:00');\n        $this->assertSame('select * from \"users\" where \"created_at\"::time = ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWhereTimeSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '22:00');\n        $this->assertSame('select * from [users] where cast([created_at] as time) = ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', new Raw('NOW()'));\n        $this->assertSame('select * from [users] where cast([created_at] as time) = NOW()', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testOrWhereTimeMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '<=', '10:00')->orWhereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from `users` where time(`created_at`) <= ? or time(`created_at`) >= ?', $builder->toSql());\n        $this->assertEquals([0 => '10:00', 1 => '22:00'], $builder->getBindings());\n    }\n\n    public function testOrWhereTimePostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '<=', '10:00')->orWhereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from \"users\" where \"created_at\"::time <= ? or \"created_at\"::time >= ?', $builder->toSql());\n        $this->assertEquals([0 => '10:00', 1 => '22:00'], $builder->getBindings());\n    }\n\n    public function testOrWhereTimeSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '<=', '10:00')->orWhereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from [users] where cast([created_at] as time) <= ? or cast([created_at] as time) >= ?', $builder->toSql());\n        $this->assertEquals([0 => '10:00', 1 => '22:00'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '<=', '10:00')->orWhereTime('created_at', new Raw('NOW()'));\n        $this->assertSame('select * from [users] where cast([created_at] as time) <= ? or cast([created_at] as time) = NOW()', $builder->toSql());\n        $this->assertEquals([0 => '10:00'], $builder->getBindings());\n    }\n\n    public function testWhereDatePostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');\n        $this->assertSame('select * from \"users\" where \"created_at\"::date = ?', $builder->toSql());\n        $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));\n        $this->assertSame('select * from \"users\" where \"created_at\"::date = NOW()', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereDate('result->created_at', new Raw('NOW()'));\n        $this->assertSame('select * from \"users\" where (\"result\"->>\\'created_at\\')::date = NOW()', $builder->toSql());\n    }\n\n    public function testWhereDayPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1);\n        $this->assertSame('select * from \"users\" where extract(day from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereMonthPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);\n        $this->assertSame('select * from \"users\" where extract(month from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 5], $builder->getBindings());\n    }\n\n    public function testWhereYearPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);\n        $this->assertSame('select * from \"users\" where extract(year from \"created_at\") = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014], $builder->getBindings());\n    }\n\n    public function testWhereTimePostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from \"users\" where \"created_at\"::time >= ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereTime('result->created_at', '>=', '22:00');\n        $this->assertSame('select * from \"users\" where (\"result\"->>\\'created_at\\')::time >= ?', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWherePast()\n    {\n        Carbon::setTestNow('2022-04-20 23:45:06.123456');\n\n        $testDate = Carbon::create('2022-04-20 23:45:06.123456');\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->wherePast('published_at');\n        $this->assertSame('select * from \"posts\" where \"published_at\" < ?', $builder->toSql());\n        $this->assertEquals([0 => $testDate], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWherePast('published_at');\n        $this->assertSame('select * from \"posts\" where \"id\" = ? or \"published_at\" < ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => $testDate], $builder->getBindings());\n    }\n\n    public function testWherePastUsesArray()\n    {\n        Carbon::setTestNow('2022-04-20 12:34:56.123456');\n\n        $testDate = Carbon::create('2022-04-20 12:34:56.123456');\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->wherePast(['published_at', 'held_at']);\n        $this->assertSame('select * from \"posts\" where \"published_at\" < ? and \"held_at\" < ?', $builder->toSql());\n        $this->assertEquals([0 => $testDate, 1 => $testDate], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWherePast(['published_at', 'held_at']);\n        $this->assertSame('select * from \"posts\" where \"id\" = ? or \"published_at\" < ? or \"held_at\" < ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => $testDate, 2 => $testDate], $builder->getBindings());\n    }\n\n    public function testWhereTodayMySQL()\n    {\n        Carbon::setTestNow('2022-04-20 12:34:56.123456');\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('posts')->whereToday('published_at');\n        $this->assertSame('select * from `posts` where date(`published_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2022-04-20'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereToday('published_at');\n        $this->assertSame('select * from `posts` where `id` = ? or date(`published_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => '2022-04-20'], $builder->getBindings());\n    }\n\n    public function testPassingArrayToWhereTodayMySQL()\n    {\n        Carbon::setTestNow('2022-04-20 12:34:56.123456');\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('posts')->whereToday(['published_at', 'held_at']);\n        $this->assertSame('select * from `posts` where date(`published_at`) = ? and date(`held_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2022-04-20', 1 => '2022-04-20'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereToday(['published_at', 'held_at']);\n        $this->assertSame('select * from `posts` where `id` = ? or date(`published_at`) = ? or date(`held_at`) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => '2022-04-20', 2 => '2022-04-20'], $builder->getBindings());\n    }\n\n    public function testWhereTodaySqlServer()\n    {\n        Carbon::setTestNow('2022-04-20 12:34:56.123456');\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('posts')->whereToday('published_at');\n        $this->assertSame('select * from [posts] where cast([published_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2022-04-20'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereToday('published_at');\n        $this->assertSame('select * from [posts] where [id] = ? or cast([published_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => '2022-04-20'], $builder->getBindings());\n    }\n\n    public function testPassingArrayToWhereTodaySqlServer()\n    {\n        Carbon::setTestNow('2022-04-20 12:34:56.123456');\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('posts')->whereToday(['published_at', 'held_at']);\n        $this->assertSame('select * from [posts] where cast([published_at] as date) = ? and cast([held_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2022-04-20', 1 => '2022-04-20'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereToday(['published_at', 'held_at']);\n        $this->assertSame('select * from [posts] where [id] = ? or cast([published_at] as date) = ? or cast([held_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => '2022-04-20', 2 => '2022-04-20'], $builder->getBindings());\n    }\n\n    public function testWhereFuture()\n    {\n        Carbon::setTestNow('2022-04-22 21:01:23.123456');\n\n        $testDate = Carbon::create('2022-04-22 21:01:23.123456');\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->whereFuture('published_at');\n        $this->assertSame('select * from \"posts\" where \"published_at\" > ?', $builder->toSql());\n        $this->assertEquals([0 => $testDate], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereFuture('published_at');\n        $this->assertSame('select * from \"posts\" where \"id\" = ? or \"published_at\" > ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => $testDate], $builder->getBindings());\n    }\n\n    public function testPassingArrayToWhereFuture()\n    {\n        Carbon::setTestNow('2022-04-22 01:23:45.123456');\n\n        $testDate = Carbon::create('2022-04-22 01:23:45.123456');\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->whereFuture(['published_at', 'held_at']);\n        $this->assertSame('select * from \"posts\" where \"published_at\" > ? and \"held_at\" > ?', $builder->toSql());\n        $this->assertEquals([0 => $testDate, 1 => $testDate], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('id', '=', 1)->orWhereFuture(['published_at', 'held_at']);\n        $this->assertSame('select * from \"posts\" where \"id\" = ? or \"published_at\" > ? or \"held_at\" > ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => $testDate, 2 => $testDate], $builder->getBindings());\n    }\n\n    public function testWhereLikePostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', 'like', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', 'LIKE', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text LIKE ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', 'ilike', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', 'not like', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', 'not ilike', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text not ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n    }\n\n    public function testWhereLikeClausePostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1', false);\n        $this->assertSame('select * from \"users\" where \"id\"::text ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1', true);\n        $this->assertSame('select * from \"users\" where \"id\"::text like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1');\n        $this->assertSame('select * from \"users\" where \"id\"::text not ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1', false);\n        $this->assertSame('select * from \"users\" where \"id\"::text not ilike ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1', true);\n        $this->assertSame('select * from \"users\" where \"id\"::text not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n    }\n\n    public function testWhereLikeClauseMysql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1');\n        $this->assertSame('select * from `users` where `id` like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1', false);\n        $this->assertSame('select * from `users` where `id` like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1', true);\n        $this->assertSame('select * from `users` where `id` like binary ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1');\n        $this->assertSame('select * from `users` where `id` not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1', false);\n        $this->assertSame('select * from `users` where `id` not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1', true);\n        $this->assertSame('select * from `users` where `id` not like binary ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n    }\n\n    public function testWhereLikeClauseSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1');\n        $this->assertSame('select * from \"users\" where \"id\" like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1', true);\n        $this->assertSame('select * from \"users\" where \"id\" glob ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereLike('description', 'Hell* _orld?%', true);\n        $this->assertSame('select * from \"users\" where \"description\" glob ?', $builder->toSql());\n        $this->assertEquals([0 => 'Hell[*] ?orld[?]*'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1');\n        $this->assertSame('select * from \"users\" where \"id\" not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereNotLike('description', 'Hell* _orld?%', true);\n        $this->assertSame('select * from \"users\" where \"description\" not glob ?', $builder->toSql());\n        $this->assertEquals([0 => 'Hell[*] ?orld[?]*'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereLike('name', 'John%', true)->whereNotLike('name', '%Doe%', true);\n        $this->assertSame('select * from \"users\" where \"name\" glob ? and \"name\" not glob ?', $builder->toSql());\n        $this->assertEquals([0 => 'John*', 1 => '*Doe*'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereLike('name', 'John%')->orWhereLike('name', 'Jane%', true);\n        $this->assertSame('select * from \"users\" where \"name\" like ? or \"name\" glob ?', $builder->toSql());\n        $this->assertEquals([0 => 'John%', 1 => 'Jane*'], $builder->getBindings());\n    }\n\n    public function testWhereLikeClauseSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1');\n        $this->assertSame('select * from [users] where [id] like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereLike('id', '1')->orWhereLike('id', '2');\n        $this->assertSame('select * from [users] where [id] like ? or [id] like ?', $builder->toSql());\n        $this->assertEquals([0 => '1', 1 => '2'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereNotLike('id', '1');\n        $this->assertSame('select * from [users] where [id] not like ?', $builder->toSql());\n        $this->assertEquals([0 => '1'], $builder->getBindings());\n    }\n\n    public function testWhereDateSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');\n        $this->assertSame('select * from \"users\" where strftime(\\'%Y-%m-%d\\', \"created_at\") = cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));\n        $this->assertSame('select * from \"users\" where strftime(\\'%Y-%m-%d\\', \"created_at\") = cast(NOW() as text)', $builder->toSql());\n    }\n\n    public function testWhereDaySqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1);\n        $this->assertSame('select * from \"users\" where strftime(\\'%d\\', \"created_at\") = cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereMonthSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);\n        $this->assertSame('select * from \"users\" where strftime(\\'%m\\', \"created_at\") = cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => 5], $builder->getBindings());\n    }\n\n    public function testWhereYearSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);\n        $this->assertSame('select * from \"users\" where strftime(\\'%Y\\', \"created_at\") = cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => 2014], $builder->getBindings());\n    }\n\n    public function testWhereTimeSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');\n        $this->assertSame('select * from \"users\" where strftime(\\'%H:%M:%S\\', \"created_at\") >= cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWhereTimeOperatorOptionalSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereTime('created_at', '22:00');\n        $this->assertSame('select * from \"users\" where strftime(\\'%H:%M:%S\\', \"created_at\") = cast(? as text)', $builder->toSql());\n        $this->assertEquals([0 => '22:00'], $builder->getBindings());\n    }\n\n    public function testWhereDateSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');\n        $this->assertSame('select * from [users] where cast([created_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));\n        $this->assertSame('select * from [users] where cast([created_at] as date) = NOW()', $builder->toSql());\n    }\n\n    public function testWhereDaySqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereDay('created_at', '=', 1);\n        $this->assertSame('select * from [users] where day([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereMonthSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);\n        $this->assertSame('select * from [users] where month([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 5], $builder->getBindings());\n    }\n\n    public function testWhereYearSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);\n        $this->assertSame('select * from [users] where year([created_at]) = ?', $builder->toSql());\n        $this->assertEquals([0 => 2014], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEquals()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar')->whereNullSafeEquals('baz', 'qux');\n        $this->assertSame('select * from \"users\" where \"foo\" is not distinct from ? and \"baz\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar', 'qux'], $builder->getBindings());\n    }\n\n    public function testOrWhereNullSafeEquals()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', 'bar')->orWhereNullSafeEquals('baz', 'qux');\n        $this->assertSame('select * from \"users\" where \"foo\" = ? or \"baz\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar', 'qux'], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEqualsViaNullSafeOperator()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEqualsWithNullViaOperator()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is null', $builder->toSql());\n    }\n\n    public function testWhereNullSafeEqualsMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar');\n        $this->assertSame('select * from `users` where `foo` <=> ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', 'bar');\n        $this->assertSame('select * from `users` where `foo` <=> ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEqualsSQLite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEqualsPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', 'bar');\n        $this->assertSame('select * from \"users\" where \"foo\" is not distinct from ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testWhereNullSafeEqualsSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereNullSafeEquals('foo', 'bar');\n        $this->assertSame('select * from [users] where exists (select [foo] intersect select ?)', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', 'bar');\n        $this->assertSame('select * from [users] where exists (select [foo] intersect select ?)', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testWhereBetweens()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween('id', [1, 2]);\n        $this->assertSame('select * from \"users\" where \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween('id', [[1, 2, 3]]);\n        $this->assertSame('select * from \"users\" where \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween('id', [[1], [2, 3]]);\n        $this->assertSame('select * from \"users\" where \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotBetween('id', [1, 2]);\n        $this->assertSame('select * from \"users\" where \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween('id', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" between 1 and 2', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $period = Carbon::now()->startOfDay()->toPeriod(Carbon::now()->addDay()->startOfDay());\n        $builder->select('*')->from('users')->whereBetween('created_at', $period);\n        $this->assertSame('select * from \"users\" where \"created_at\" between ? and ?', $builder->toSql());\n        $this->assertEquals([Carbon::now()->startOfDay(), Carbon::now()->addDay()->startOfDay()], $builder->getBindings());\n\n        // custom long carbon period date\n        $builder = $this->getBuilder();\n        $period = Carbon::now()->startOfDay()->toPeriod(Carbon::now()->addMonth()->startOfDay());\n        $builder->select('*')->from('users')->whereBetween('created_at', $period);\n        $this->assertSame('select * from \"users\" where \"created_at\" between ? and ?', $builder->toSql());\n        $this->assertEquals([Carbon::now()->startOfDay(), Carbon::now()->addMonth()->startOfDay()], $builder->getBindings());\n\n        // DatePeriod with end date\n        $builder = $this->getBuilder();\n        $period = new DatePeriod(Carbon::now()->startOfDay(), new DateInterval('P1D'), Carbon::now()->addDays(5)->startOfDay());\n        $builder->select('*')->from('users')->whereBetween('created_at', $period);\n        $this->assertSame('select * from \"users\" where \"created_at\" between ? and ?', $builder->toSql());\n        $this->assertEquals([Carbon::now()->startOfDay(), Carbon::now()->addDays(5)->startOfDay()], $builder->getBindings());\n\n        // DatePeriod with recurrence count (no end date)\n        $builder = $this->getBuilder();\n        $period = new DatePeriod(Carbon::now()->startOfDay(), new DateInterval('P1D'), 5);\n        $builder->select('*')->from('users')->whereBetween('created_at', $period);\n        $this->assertSame('select * from \"users\" where \"created_at\" between ? and ?', $builder->toSql());\n        $this->assertEquals([Carbon::now()->startOfDay(), Carbon::now()->addDays(5)->startOfDay()], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween('id', collect([1, 2]));\n        $this->assertSame('select * from \"users\" where \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $subqueryBuilder = $this->getBuilder();\n        $subqueryBuilder->select('id')->from('posts')->where('status', 'published')->orderByDesc('created_at')->limit(1);\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetween($subqueryBuilder, collect([1, 2]));\n        $this->assertSame('select * from \"users\" where (select \"id\" from \"posts\" where \"status\" = ? order by \"created_at\" desc limit 1) between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 'published', 1 => 1, 2 => 2], $builder->getBindings());\n    }\n\n    public function testOrWhereBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', [3, 5]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 5], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', [[3, 4, 5]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 4], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', [[3, 5]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 5], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', [[4], [6, 8]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 4, 2 => 6], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', collect([3, 4]));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 4], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereBetween('id', [new Raw(3), new Raw(4)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between 3 and 4', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testOrWhereNotBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', [3, 5]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 5], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', [[3, 4, 5]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 4], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', [[3, 5]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 5], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', [[4], [6, 8]]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 4, 2 => 6], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', collect([3, 4]));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 3, 2 => 4], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotBetween('id', [new Raw(3), new Raw(4)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between 3 and 4', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereBetweenColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetweenColumns('id', ['users.created_at', 'users.updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" between \"users\".\"created_at\" and \"users\".\"updated_at\"', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotBetweenColumns('id', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetweenColumns('id', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" between 1 and 2', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $subqueryBuilder = $this->getBuilder();\n        $subqueryBuilder->select('created_at')->from('posts')->where('status', 'published')->orderByDesc('created_at')->limit(1);\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereBetweenColumns($subqueryBuilder, ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where (select \"created_at\" from \"posts\" where \"status\" = ? order by \"created_at\" desc limit 1) between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 'published'], $builder->getBindings());\n    }\n\n    public function testOrWhereBetweenColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereBetweenColumns('id', ['users.created_at', 'users.updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between \"users\".\"created_at\" and \"users\".\"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereBetweenColumns('id', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereBetweenColumns('id', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n    }\n\n    public function testOrWhereNotBetweenColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereNotBetweenColumns('id', ['users.created_at', 'users.updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between \"users\".\"created_at\" and \"users\".\"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereNotBetweenColumns('id', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereNotBetweenColumns('id', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => 2], $builder->getBindings());\n    }\n\n    public function testWhereValueBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where ? between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where ? between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueBetween('2020-01-01 19:30:00', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where ? between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueBetween(new Raw(1), ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where 1 between \"created_at\" and \"updated_at\"', $builder->toSql());\n    }\n\n    public function testOrWhereValueBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueBetween('2020-01-01 19:30:00', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueBetween(new Raw(1), ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or 1 between \"created_at\" and \"updated_at\"', $builder->toSql());\n    }\n\n    public function testWhereValueNotBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueNotBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where ? not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueNotBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where ? not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueNotBetween('2020-01-01 19:30:00', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where ? not between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereValueNotBetween(new Raw(1), ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where 1 not between \"created_at\" and \"updated_at\"', $builder->toSql());\n    }\n\n    public function testOrWhereValueNotBetween()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueNotBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueNotBetween('2020-01-01 19:30:00', ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? not between \"created_at\" and \"updated_at\"', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueNotBetween('2020-01-01 19:30:00', [new Raw(1), new Raw(2)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or ? not between 1 and 2', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => '2020-01-01 19:30:00'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 2)->orWhereValueNotBetween(new Raw(1), ['created_at', 'updated_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or 1 not between \"created_at\" and \"updated_at\"', $builder->toSql());\n    }\n\n    public function testBasicOrWheres()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhere('email', '=', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"email\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testBasicOrWhereNot()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orWhereNot('name', 'foo')->orWhereNot('name', '<>', 'bar');\n        $this->assertSame('select * from \"users\" where not \"name\" = ? or not \"name\" <> ?', $builder->toSql());\n        $this->assertEquals(['foo', 'bar'], $builder->getBindings());\n    }\n\n    public function testRawWheres()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereRaw('id = ? or email = ?', [1, 'foo']);\n        $this->assertSame('select * from \"users\" where id = ? or email = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testRawOrWheres()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereRaw('email = ?', ['foo']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or email = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testBasicWhereIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', [1, 2, 3]);\n        $this->assertSame('select * from \"users\" where \"id\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());\n\n        // associative arrays as values:\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', [\n            'issue' => 45582,\n            'id' => 2,\n            3,\n        ]);\n        $this->assertSame('select * from \"users\" where \"id\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 45582, 1 => 2, 2 => 3], $builder->getBindings());\n\n        // can accept some nested arrays as values.\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', [\n            ['issue' => 45582],\n            ['id' => 2],\n            [3],\n        ]);\n        $this->assertSame('select * from \"users\" where \"id\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 45582, 1 => 2, 2 => 3], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', [1, 2, 3]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 1, 2 => 2, 3 => 3], $builder->getBindings());\n    }\n\n    public function testBasicWhereInsException()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', [\n            [\n                'a' => 1,\n                'b' => 1,\n            ],\n            ['c' => 2],\n            [3],\n        ]);\n    }\n\n    public function testBasicWhereNotIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotIn('id', [1, 2, 3]);\n        $this->assertSame('select * from \"users\" where \"id\" not in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotIn('id', [1, 2, 3]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 1, 2 => 2, 3 => 3], $builder->getBindings());\n    }\n\n    public function testRawWhereIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', [new Raw(1)]);\n        $this->assertSame('select * from \"users\" where \"id\" in (1)', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', [new Raw(1)]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" in (1)', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testEmptyWhereIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', []);\n        $this->assertSame('select * from \"users\" where 0 = 1', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', []);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or 0 = 1', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testEmptyWhereNotIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotIn('id', []);\n        $this->assertSame('select * from \"users\" where 1 = 1', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotIn('id', []);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or 1 = 1', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereIntegerInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIntegerInRaw('id', [\n            '1a', 2, Bar::FOO,\n        ]);\n        $this->assertSame('select * from \"users\" where \"id\" in (1, 2, 5)', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIntegerInRaw('id', [\n            ['id' => '1a'],\n            ['id' => 2],\n            ['any' => '3'],\n            ['id' => Bar::FOO],\n        ]);\n        $this->assertSame('select * from \"users\" where \"id\" in (1, 2, 3, 5)', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testOrWhereIntegerInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerInRaw('id', ['1a', 2]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" in (1, 2)', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testWhereIntegerNotInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIntegerNotInRaw('id', ['1a', 2]);\n        $this->assertSame('select * from \"users\" where \"id\" not in (1, 2)', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testOrWhereIntegerNotInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerNotInRaw('id', ['1a', 2]);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" not in (1, 2)', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testEmptyWhereIntegerInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIntegerInRaw('id', []);\n        $this->assertSame('select * from \"users\" where 0 = 1', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testEmptyWhereIntegerNotInRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIntegerNotInRaw('id', []);\n        $this->assertSame('select * from \"users\" where 1 = 1', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testBasicWhereColumn()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn('first_name', 'last_name')->orWhereColumn('first_name', 'middle_name');\n        $this->assertSame('select * from \"users\" where \"first_name\" = \"last_name\" or \"first_name\" = \"middle_name\"', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn('updated_at', '>', 'created_at');\n        $this->assertSame('select * from \"users\" where \"updated_at\" > \"created_at\"', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testArrayWhereColumn()\n    {\n        $conditions = [\n            ['first_name', 'last_name'],\n            ['updated_at', '>', 'created_at'],\n        ];\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn($conditions);\n        $this->assertSame('select * from \"users\" where (\"first_name\" = \"last_name\" and \"updated_at\" > \"created_at\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testWhereFulltextMySql()\n    {\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World');\n        $this->assertSame('select * from `users` where match (`body`) against (? in natural language mode)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World', ['expanded' => true]);\n        $this->assertSame('select * from `users` where match (`body`) against (? in natural language mode with query expansion)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', '+Hello -World', ['mode' => 'boolean']);\n        $this->assertSame('select * from `users` where match (`body`) against (? in boolean mode)', $builder->toSql());\n        $this->assertEquals(['+Hello -World'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', '+Hello -World', ['mode' => 'boolean', 'expanded' => true]);\n        $this->assertSame('select * from `users` where match (`body`) against (? in boolean mode)', $builder->toSql());\n        $this->assertEquals(['+Hello -World'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText(['body', 'title'], 'Car,Plane');\n        $this->assertSame('select * from `users` where match (`body`, `title`) against (? in natural language mode)', $builder->toSql());\n        $this->assertEquals(['Car,Plane'], $builder->getBindings());\n    }\n\n    public function testWhereFulltextPostgres()\n    {\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World');\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\")) @@ plainto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World', ['language' => 'simple']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'simple\\', \"body\")) @@ plainto_tsquery(\\'simple\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World', ['mode' => 'plain']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\")) @@ plainto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World', ['mode' => 'phrase']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\")) @@ phraseto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', '+Hello -World', ['mode' => 'websearch']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\")) @@ websearch_to_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['+Hello -World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('body', 'Hello World', ['language' => 'simple', 'mode' => 'plain']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'simple\\', \"body\")) @@ plainto_tsquery(\\'simple\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText(['body', 'title'], 'Car Plane');\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\") || to_tsvector(\\'english\\', \"title\")) @@ plainto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Car Plane'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText(['body', 'title'], 'Air | Plan:* -Car', ['mode' => 'raw']);\n        $this->assertSame('select * from \"users\" where (to_tsvector(\\'english\\', \"body\") || to_tsvector(\\'english\\', \"title\")) @@ to_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Air | Plan:* -Car'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('search_vector', 'Hello World', ['vector' => true]);\n        $this->assertSame('select * from \"users\" where (\"search_vector\") @@ plainto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('search_vector_nl', 'Hello World', ['vector' => true, 'language' => 'dutch']);\n        $this->assertSame('select * from \"users\" where (\"search_vector_nl\") @@ plainto_tsquery(\\'dutch\\', ?)', $builder->toSql());\n        $this->assertEquals(['Hello World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText('search_vector', '+Hello -World', ['vector' => true, 'mode' => 'websearch']);\n        $this->assertSame('select * from \"users\" where (\"search_vector\") @@ websearch_to_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['+Hello -World'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilderWithProcessor();\n        $builder->select('*')->from('users')->whereFullText(['tsv_title', 'tsv_body'], 'Car Plane', ['vector' => true]);\n        $this->assertSame('select * from \"users\" where (\"tsv_title\" || \"tsv_body\") @@ plainto_tsquery(\\'english\\', ?)', $builder->toSql());\n        $this->assertEquals(['Car Plane'], $builder->getBindings());\n    }\n\n    public function testWhereAll()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAll(['last_name', 'email'], '%Otwell%');\n        $this->assertSame('select * from \"users\" where (\"last_name\" = ? and \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAll(['last_name', 'email'], 'not like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where (\"last_name\" not like ? and \"email\" not like ?)', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAll([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where ((\"last_name\" like ?) and (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testOrWhereAll()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAll(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" like ? and \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereAll(['last_name', 'email'], 'like', '%Otwell%', 'or');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" like ? and \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAll(['last_name', 'email'], '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" = ? and \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAll([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or ((\"last_name\" like ?) and (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testWhereAny()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAny(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAny(['last_name', 'email'], '%Otwell%');\n        $this->assertSame('select * from \"users\" where (\"last_name\" = ? or \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAny([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where ((\"last_name\" like ?) or (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testOrWhereAny()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereAny(['last_name', 'email'], 'like', '%Otwell%', 'or');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['last_name', 'email'], '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or (\"last_name\" = ? or \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or ((\"last_name\" like ?) or (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testWhereNone()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNone(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where not (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNone(['last_name', 'email'], 'Otwell');\n        $this->assertSame('select * from \"users\" where not (\"last_name\" = ? or \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['Otwell', 'Otwell'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNone(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? and not (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNone([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where not ((\"last_name\" like ?) or (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testOrWhereNone()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNone(['last_name', 'email'], 'like', '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or not (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNone(['last_name', 'email'], 'like', '%Otwell%', 'or');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or not (\"last_name\" like ? or \"email\" like ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNone(['last_name', 'email'], '%Otwell%');\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or not (\"last_name\" = ? or \"email\" = ?)', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNone([\n            fn (Builder $query) => $query->where('last_name', 'like', '%Otwell%'),\n            fn (Builder $query) => $query->where('email', 'like', '%Otwell%'),\n        ]);\n        $this->assertSame('select * from \"users\" where \"first_name\" like ? or not ((\"last_name\" like ?) or (\"email\" like ?))', $builder->toSql());\n        $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());\n    }\n\n    public function testUnions()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->union($this->getMySqlBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $this->assertSame('(select * from `users` where `id` = ?) union (select * from `users` where `id` = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getMysqlBuilder();\n        $expectedSql = '(select `a` from `t1` where `a` = ? and `b` = ?) union (select `a` from `t2` where `a` = ? and `b` = ?) order by `a` asc limit 10';\n        $union = $this->getMysqlBuilder()->select('a')->from('t2')->where('a', 11)->where('b', 2);\n        $builder->select('a')->from('t1')->where('a', 10)->where('b', 1)->union($union)->orderBy('a')->limit(10);\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals([0 => 10, 1 => 1, 2 => 11, 3 => 2], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $expectedSql = '(select \"name\" from \"users\" where \"id\" = ?) union (select \"name\" from \"users\" where \"id\" = ?)';\n        $builder->select('name')->from('users')->where('id', '=', 1);\n        $builder->union($this->getPostgresBuilder()->select('name')->from('users')->where('id', '=', 2));\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $expectedSql = 'select * from (select \"name\" from \"users\" where \"id\" = ?) union select * from (select \"name\" from \"users\" where \"id\" = ?)';\n        $builder->select('name')->from('users')->where('id', '=', 1);\n        $builder->union($this->getSQLiteBuilder()->select('name')->from('users')->where('id', '=', 2));\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $expectedSql = 'select * from (select [name] from [users] where [id] = ?) as [temp_table] union select * from (select [name] from [users] where [id] = ?) as [temp_table]';\n        $builder->select('name')->from('users')->where('id', '=', 1);\n        $builder->union($this->getSqlServerBuilder()->select('name')->from('users')->where('id', '=', 2));\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $eloquentBuilder = new EloquentBuilder($this->getBuilder());\n        $builder->select('*')->from('users')->where('id', '=', 1)->union($eloquentBuilder->select('*')->from('users')->where('id', '=', 2));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testUnionAlls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union all (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $expectedSql = '(select * from \"users\" where \"id\" = ?) union all (select * from \"users\" where \"id\" = ?)';\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $eloquentBuilder = new EloquentBuilder($this->getBuilder());\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->unionAll($eloquentBuilder->select('*')->from('users')->where('id', '=', 2));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union all (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testMultipleUnions()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 3));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union (select * from \"users\" where \"id\" = ?) union (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());\n    }\n\n    public function testMultipleUnionAlls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 3));\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union all (select * from \"users\" where \"id\" = ?) union all (select * from \"users\" where \"id\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());\n    }\n\n    public function testUnionOrderBys()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $builder->orderBy('id', 'desc');\n        $this->assertSame('(select * from \"users\" where \"id\" = ?) union (select * from \"users\" where \"id\" = ?) order by \"id\" desc', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testUnionLimitsAndOffsets()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users');\n        $builder->union($this->getBuilder()->select('*')->from('dogs'));\n        $builder->offset(5)->limit(10);\n        $this->assertSame('(select * from \"users\") union (select * from \"dogs\") limit 10 offset 5', $builder->toSql());\n\n        $expectedSql = '(select * from \"users\") union (select * from \"dogs\") limit 10 offset 5';\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users');\n        $builder->union($this->getBuilder()->select('*')->from('dogs'));\n        $builder->offset(5)->limit(10);\n        $this->assertEquals($expectedSql, $builder->toSql());\n\n        $expectedSql = '(select * from \"users\" limit 11) union (select * from \"dogs\" limit 22) limit 10 offset 5';\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->limit(11);\n        $builder->union($this->getBuilder()->select('*')->from('dogs')->limit(22));\n        $builder->offset(5)->limit(10);\n        $this->assertEquals($expectedSql, $builder->toSql());\n    }\n\n    public function testUnionWithJoin()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users');\n        $builder->union($this->getBuilder()->select('*')->from('dogs')->join('breeds', function ($join) {\n            $join->on('dogs.breed_id', '=', 'breeds.id')\n                ->where('breeds.is_native', '=', 1);\n        }));\n        $this->assertSame('(select * from \"users\") union (select * from \"dogs\" inner join \"breeds\" on \"dogs\".\"breed_id\" = \"breeds\".\"id\" and \"breeds\".\"is_native\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testMySqlUnionOrderBys()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1);\n        $builder->union($this->getMySqlBuilder()->select('*')->from('users')->where('id', '=', 2));\n        $builder->orderBy('id', 'desc');\n        $this->assertSame('(select * from `users` where `id` = ?) union (select * from `users` where `id` = ?) order by `id` desc', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testMySqlUnionLimitsAndOffsets()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users');\n        $builder->union($this->getMySqlBuilder()->select('*')->from('dogs'));\n        $builder->offset(5)->limit(10);\n        $this->assertSame('(select * from `users`) union (select * from `dogs`) limit 10 offset 5', $builder->toSql());\n    }\n\n    public function testUnionAggregate()\n    {\n        $expected = 'select count(*) as aggregate from ((select * from `posts`) union (select * from `videos`)) as `temp_table`';\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []);\n        $builder->getProcessor()->shouldReceive('processSelect')->once();\n        $builder->from('posts')->union($this->getMySqlBuilder()->from('videos'))->count();\n\n        $expected = 'select count(*) as aggregate from ((select `id` from `posts`) union (select `id` from `videos`)) as `temp_table`';\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []);\n        $builder->getProcessor()->shouldReceive('processSelect')->once();\n        $builder->from('posts')->select('id')->union($this->getMySqlBuilder()->from('videos')->select('id'))->count();\n\n        $expected = 'select count(*) as aggregate from ((select * from \"posts\") union (select * from \"videos\")) as \"temp_table\"';\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []);\n        $builder->getProcessor()->shouldReceive('processSelect')->once();\n        $builder->from('posts')->union($this->getPostgresBuilder()->from('videos'))->count();\n\n        $expected = 'select count(*) as aggregate from (select * from (select * from \"posts\") union select * from (select * from \"videos\")) as \"temp_table\"';\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []);\n        $builder->getProcessor()->shouldReceive('processSelect')->once();\n        $builder->from('posts')->union($this->getSQLiteBuilder()->from('videos'))->count();\n\n        $expected = 'select count(*) as aggregate from (select * from (select * from [posts]) as [temp_table] union select * from (select * from [videos]) as [temp_table]) as [temp_table]';\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true, []);\n        $builder->getProcessor()->shouldReceive('processSelect')->once();\n        $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count();\n    }\n\n    public function testHavingAggregate()\n    {\n        $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`';\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $builder->from('posts')->selectSub(function ($query) {\n            $query->from('videos')->select('count(*)')->whereColumn('posts.id', '=', 'videos.post_id');\n        }, 'videos_count')->having('videos_count', '>', 1);\n        $builder->count();\n    }\n\n    public function testSubSelectWhereIns()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereIn('id', function ($q) {\n            $q->select('id')->from('users')->where('age', '>', 25)->limit(3);\n        });\n        $this->assertSame('select * from \"users\" where \"id\" in (select \"id\" from \"users\" where \"age\" > ? limit 3)', $builder->toSql());\n        $this->assertEquals([25], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotIn('id', function ($q) {\n            $q->select('id')->from('users')->where('age', '>', 25)->limit(3);\n        });\n        $this->assertSame('select * from \"users\" where \"id\" not in (select \"id\" from \"users\" where \"age\" > ? limit 3)', $builder->toSql());\n        $this->assertEquals([25], $builder->getBindings());\n    }\n\n    public function testBasicWhereNulls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNull('id');\n        $this->assertSame('select * from \"users\" where \"id\" is null', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNull('id');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" is null', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testBasicWhereNullExpressionsMysql()\n    {\n        $builder = $this->getMysqlBuilder();\n        $builder->select('*')->from('users')->whereNull(new Raw('id'));\n        $this->assertSame('select * from `users` where id is null', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getMysqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNull(new Raw('id'));\n        $this->assertSame('select * from `users` where `id` = ? or id is null', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testJsonWhereNullMysql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNull('items->id');\n        $this->assertSame('select * from `users` where (json_extract(`items`, \\'$.\"id\"\\') is null OR json_type(json_extract(`items`, \\'$.\"id\"\\')) = \\'NULL\\')', $builder->toSql());\n    }\n\n    public function testJsonWhereNotNullMysql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNotNull('items->id');\n        $this->assertSame('select * from `users` where (json_extract(`items`, \\'$.\"id\"\\') is not null AND json_type(json_extract(`items`, \\'$.\"id\"\\')) != \\'NULL\\')', $builder->toSql());\n    }\n\n    public function testJsonWhereNullExpressionMysql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNull(new Raw('items->id'));\n        $this->assertSame('select * from `users` where (json_extract(`items`, \\'$.\"id\"\\') is null OR json_type(json_extract(`items`, \\'$.\"id\"\\')) = \\'NULL\\')', $builder->toSql());\n    }\n\n    public function testJsonWhereNotNullExpressionMysql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereNotNull(new Raw('items->id'));\n        $this->assertSame('select * from `users` where (json_extract(`items`, \\'$.\"id\"\\') is not null AND json_type(json_extract(`items`, \\'$.\"id\"\\')) != \\'NULL\\')', $builder->toSql());\n    }\n\n    public function testArrayWhereNulls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNull(['id', 'expires_at']);\n        $this->assertSame('select * from \"users\" where \"id\" is null and \"expires_at\" is null', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNull(['id', 'expires_at']);\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"id\" is null or \"expires_at\" is null', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testBasicWhereNotNulls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotNull('id');\n        $this->assertSame('select * from \"users\" where \"id\" is not null', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '>', 1)->orWhereNotNull('id');\n        $this->assertSame('select * from \"users\" where \"id\" > ? or \"id\" is not null', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testArrayWhereNotNulls()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNotNull(['id', 'expires_at']);\n        $this->assertSame('select * from \"users\" where \"id\" is not null and \"expires_at\" is not null', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', '>', 1)->orWhereNotNull(['id', 'expires_at']);\n        $this->assertSame('select * from \"users\" where \"id\" > ? or \"id\" is not null or \"expires_at\" is not null', $builder->toSql());\n        $this->assertEquals([0 => 1], $builder->getBindings());\n    }\n\n    public function testGroupBys()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy('email');\n        $this->assertSame('select * from \"users\" group by \"email\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy('id', 'email');\n        $this->assertSame('select * from \"users\" group by \"id\", \"email\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy(['id', 'email']);\n        $this->assertSame('select * from \"users\" group by \"id\", \"email\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy(new Raw('DATE(created_at)'));\n        $this->assertSame('select * from \"users\" group by DATE(created_at)', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupByRaw('DATE(created_at), ? DESC', ['foo']);\n        $this->assertSame('select * from \"users\" group by DATE(created_at), ? DESC', $builder->toSql());\n        $this->assertEquals(['foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->havingRaw('?', ['havingRawBinding'])->groupByRaw('?', ['groupByRawBinding'])->whereRaw('?', ['whereRawBinding']);\n        $this->assertEquals(['whereRawBinding', 'groupByRawBinding', 'havingRawBinding'], $builder->getBindings());\n    }\n\n    public function testOrderBys()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderBy('email')->orderBy('age', 'desc');\n        $this->assertSame('select * from \"users\" order by \"email\" asc, \"age\" desc', $builder->toSql());\n\n        $builder->orders = null;\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n\n        $builder->orders = [];\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderBy('email')->orderByRaw('\"age\" ? desc', ['foo']);\n        $this->assertSame('select * from \"users\" order by \"email\" asc, \"age\" ? desc', $builder->toSql());\n        $this->assertEquals(['foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderByDesc('name');\n        $this->assertSame('select * from \"users\" order by \"name\" desc', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('public', 1)\n            ->unionAll($this->getBuilder()->select('*')->from('videos')->where('public', 1))\n            ->orderByRaw('field(category, ?, ?) asc', ['news', 'opinion']);\n        $this->assertSame('(select * from \"posts\" where \"public\" = ?) union all (select * from \"videos\" where \"public\" = ?) order by field(category, ?, ?) asc', $builder->toSql());\n        $this->assertEquals([1, 1, 'news', 'opinion'], $builder->getBindings());\n    }\n\n    public function testLatest()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->latest();\n        $this->assertSame('select * from \"users\" order by \"created_at\" desc', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->latest()->limit(1);\n        $this->assertSame('select * from \"users\" order by \"created_at\" desc limit 1', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->latest('updated_at');\n        $this->assertSame('select * from \"users\" order by \"updated_at\" desc', $builder->toSql());\n    }\n\n    public function testOldest()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->oldest();\n        $this->assertSame('select * from \"users\" order by \"created_at\" asc', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->oldest()->limit(1);\n        $this->assertSame('select * from \"users\" order by \"created_at\" asc limit 1', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->oldest('updated_at');\n        $this->assertSame('select * from \"users\" order by \"updated_at\" asc', $builder->toSql());\n    }\n\n    public function testInRandomOrderMySql()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inRandomOrder();\n        $this->assertSame('select * from \"users\" order by RANDOM()', $builder->toSql());\n    }\n\n    public function testInRandomOrderMySqlGrammarWithoutSeed()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->inRandomOrder();\n        $this->assertSame('select * from `users` order by RAND()', $builder->toSql());\n    }\n\n    public function testInRandomOrderMySqlGrammarWithSeed()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->inRandomOrder(123);\n        $this->assertSame('select * from `users` order by RAND(123)', $builder->toSql());\n    }\n\n    public function testInRandomOrderPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->inRandomOrder();\n        $this->assertSame('select * from \"users\" order by RANDOM()', $builder->toSql());\n    }\n\n    public function testInRandomOrderSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->inRandomOrder();\n        $this->assertSame('select * from [users] order by NEWID()', $builder->toSql());\n    }\n\n    public function testInOrderOf()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active', 'pending', 'inactive']);\n        $this->assertSame('select * from \"users\" order by case when \"status\" = ? then 0 when \"status\" = ? then 1 when \"status\" = ? then 2 else 3 end', $builder->toSql());\n        $this->assertEquals(['active', 'pending', 'inactive'], $builder->getBindings());\n    }\n\n    public function testInOrderOfWithExistingOrders()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active', 'pending'])->orderBy('name');\n        $this->assertSame('select * from \"users\" order by case when \"status\" = ? then 0 when \"status\" = ? then 1 else 2 end, \"name\" asc', $builder->toSql());\n        $this->assertEquals(['active', 'pending'], $builder->getBindings());\n    }\n\n    public function testInOrderOfWithEmptyValues()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', []);\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n    }\n\n    public function testInOrderOfWithSingleValue()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active']);\n        $this->assertSame('select * from \"users\" order by case when \"status\" = ? then 0 else 1 end', $builder->toSql());\n        $this->assertEquals(['active'], $builder->getBindings());\n    }\n\n    public function testInOrderOfMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active', 'pending']);\n        $this->assertSame('select * from `users` order by case when `status` = ? then 0 when `status` = ? then 1 else 2 end', $builder->toSql());\n        $this->assertEquals(['active', 'pending'], $builder->getBindings());\n    }\n\n    public function testInOrderOfPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active', 'pending']);\n        $this->assertSame('select * from \"users\" order by case when \"status\" = ? then 0 when \"status\" = ? then 1 else 2 end', $builder->toSql());\n        $this->assertEquals(['active', 'pending'], $builder->getBindings());\n    }\n\n    public function testInOrderOfSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->inOrderOf('status', ['active', 'pending']);\n        $this->assertSame('select * from [users] order by case when [status] = ? then 0 when [status] = ? then 1 else 2 end', $builder->toSql());\n        $this->assertEquals(['active', 'pending'], $builder->getBindings());\n    }\n\n    public function testInOrderOfWithIntegerValues()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->inOrderOf('id', [5, 2, 8]);\n        $this->assertSame('select * from \"users\" order by case when \"id\" = ? then 0 when \"id\" = ? then 1 when \"id\" = ? then 2 else 3 end', $builder->toSql());\n        $this->assertEquals([5, 2, 8], $builder->getBindings());\n    }\n\n    public function testInOrderOfWithWhereClause()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('active', true)->inOrderOf('status', ['pending', 'approved']);\n        $this->assertSame('select * from \"users\" where \"active\" = ? order by case when \"status\" = ? then 0 when \"status\" = ? then 1 else 2 end', $builder->toSql());\n        $this->assertEquals([true, 'pending', 'approved'], $builder->getBindings());\n    }\n\n    public function testOrderBysSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->orderBy('email')->orderBy('age', 'desc');\n        $this->assertSame('select * from [users] order by [email] asc, [age] desc', $builder->toSql());\n\n        $builder->orders = null;\n        $this->assertSame('select * from [users]', $builder->toSql());\n\n        $builder->orders = [];\n        $this->assertSame('select * from [users]', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->orderBy('email');\n        $this->assertSame('select * from [users] order by [email] asc', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->orderByDesc('name');\n        $this->assertSame('select * from [users] order by [name] desc', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->orderByRaw('[age] asc');\n        $this->assertSame('select * from [users] order by [age] asc', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->orderBy('email')->orderByRaw('[age] ? desc', ['foo']);\n        $this->assertSame('select * from [users] order by [email] asc, [age] ? desc', $builder->toSql());\n        $this->assertEquals(['foo'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->offset(25)->limit(10)->orderByRaw('[email] desc');\n        $this->assertSame('select * from [users] order by [email] desc offset 25 rows fetch next 10 rows only', $builder->toSql());\n    }\n\n    public function testReorder()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderBy('name');\n        $this->assertSame('select * from \"users\" order by \"name\" asc', $builder->toSql());\n        $builder->reorder();\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderBy('name');\n        $this->assertSame('select * from \"users\" order by \"name\" asc', $builder->toSql());\n        $builder->reorder('email', 'desc');\n        $this->assertSame('select * from \"users\" order by \"email\" desc', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('first');\n        $builder->union($this->getBuilder()->select('*')->from('second'));\n        $builder->orderBy('name');\n        $this->assertSame('(select * from \"first\") union (select * from \"second\") order by \"name\" asc', $builder->toSql());\n        $builder->reorder();\n        $this->assertSame('(select * from \"first\") union (select * from \"second\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderByRaw('?', [true]);\n        $this->assertEquals([true], $builder->getBindings());\n        $builder->reorder();\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testOrderBySubQueries()\n    {\n        $expected = 'select * from \"users\" order by (select \"created_at\" from \"logins\" where \"user_id\" = \"users\".\"id\" limit 1)';\n        $subQuery = function ($query) {\n            return $query->select('created_at')->from('logins')->whereColumn('user_id', 'users.id')->limit(1);\n        };\n\n        $builder = $this->getBuilder()->select('*')->from('users')->orderBy($subQuery);\n        $this->assertSame(\"$expected asc\", $builder->toSql());\n\n        $builder = $this->getBuilder()->select('*')->from('users')->orderBy($subQuery, 'desc');\n        $this->assertSame(\"$expected desc\", $builder->toSql());\n\n        $builder = $this->getBuilder()->select('*')->from('users')->orderByDesc($subQuery);\n        $this->assertSame(\"$expected desc\", $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('posts')->where('public', 1)\n            ->unionAll($this->getBuilder()->select('*')->from('videos')->where('public', 1))\n            ->orderBy($this->getBuilder()->selectRaw('field(category, ?, ?)', ['news', 'opinion']));\n        $this->assertSame('(select * from \"posts\" where \"public\" = ?) union all (select * from \"videos\" where \"public\" = ?) order by (select field(category, ?, ?)) asc', $builder->toSql());\n        $this->assertEquals([1, 1, 'news', 'opinion'], $builder->getBindings());\n    }\n\n    public function testOrderByInvalidDirectionParam()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderBy('age', 'asec');\n    }\n\n    public function testHavings()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having('email', '>', 1);\n        $this->assertSame('select * from \"users\" having \"email\" > ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')\n            ->orHaving('email', '=', 'test@example.com')\n            ->orHaving('email', '=', 'test2@example.com');\n        $this->assertSame('select * from \"users\" having \"email\" = ? or \"email\" = ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy('email')->having('email', '>', 1);\n        $this->assertSame('select * from \"users\" group by \"email\" having \"email\" > ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('email as foo_email')->from('users')->having('foo_email', '>', 1);\n        $this->assertSame('select \"email\" as \"foo_email\" from \"users\" having \"foo_email\" > ?', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->having('total', '>', new Raw('3'));\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" > 3', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->having('total', '>', 3);\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" > ?', $builder->toSql());\n    }\n\n    public function testNestedHavings()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having('email', '=', 'foo')->orHaving(function ($q) {\n            $q->having('name', '=', 'bar')->having('age', '=', 25);\n        });\n        $this->assertSame('select * from \"users\" having \"email\" = ? or (\"name\" = ? and \"age\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'foo', 1 => 'bar', 2 => 25], $builder->getBindings());\n    }\n\n    public function testNestedHavingBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->having('email', '=', 'foo')->having(function ($q) {\n            $q->selectRaw('?', ['ignore'])->having('name', '=', 'bar');\n        });\n        $this->assertEquals([0 => 'foo', 1 => 'bar'], $builder->getBindings());\n    }\n\n    public function testHavingBetweens()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingBetween('id', [1, 2, 3]);\n        $this->assertSame('select * from \"users\" having \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingBetween('id', [[1, 2], [3, 4]]);\n        $this->assertSame('select * from \"users\" having \"id\" between ? and ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testHavingNull()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingNull('email');\n        $this->assertSame('select * from \"users\" having \"email\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')\n            ->havingNull('email')\n            ->havingNull('phone');\n        $this->assertSame('select * from \"users\" having \"email\" is null and \"phone\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')\n            ->orHavingNull('email')\n            ->orHavingNull('phone');\n        $this->assertSame('select * from \"users\" having \"email\" is null or \"phone\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy('email')->havingNull('email');\n        $this->assertSame('select * from \"users\" group by \"email\" having \"email\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('email as foo_email')->from('users')->havingNull('foo_email');\n        $this->assertSame('select \"email\" as \"foo_email\" from \"users\" having \"foo_email\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->havingNull('total');\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->havingNull('total');\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" is null', $builder->toSql());\n    }\n\n    public function testHavingNotNull()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingNotNull('email');\n        $this->assertSame('select * from \"users\" having \"email\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')\n            ->havingNotNull('email')\n            ->havingNotNull('phone');\n        $this->assertSame('select * from \"users\" having \"email\" is not null and \"phone\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')\n            ->orHavingNotNull('email')\n            ->orHavingNotNull('phone');\n        $this->assertSame('select * from \"users\" having \"email\" is not null or \"phone\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->groupBy('email')->havingNotNull('email');\n        $this->assertSame('select * from \"users\" group by \"email\" having \"email\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('email as foo_email')->from('users')->havingNotNull('foo_email');\n        $this->assertSame('select \"email\" as \"foo_email\" from \"users\" having \"foo_email\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->havingNotNull('total');\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select(['category', new Raw('count(*) as \"total\"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->havingNotNull('total');\n        $this->assertSame('select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" is not null', $builder->toSql());\n    }\n\n    public function testHavingExpression()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having(\n            new class() implements ConditionExpression\n            {\n                public function getValue(\\Illuminate\\Database\\Grammar $grammar)\n                {\n                    return '1 = 1';\n                }\n            }\n        );\n        $this->assertSame('select * from \"users\" having 1 = 1', $builder->toSql());\n        $this->assertSame([], $builder->getBindings());\n    }\n\n    public function testHavingShortcut()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having('email', 1)->orHaving('email', 2);\n        $this->assertSame('select * from \"users\" having \"email\" = ? or \"email\" = ?', $builder->toSql());\n    }\n\n    public function testHavingFollowedBySelectGet()\n    {\n        $builder = $this->getBuilder();\n        $query = 'select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" > ?';\n        $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true, [])->andReturn([['category' => 'rock', 'total' => 5]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('item');\n        $result = $builder->select(['category', new Raw('count(*) as \"total\"')])->where('department', '=', 'popular')->groupBy('category')->having('total', '>', 3)->get();\n        $this->assertEquals([['category' => 'rock', 'total' => 5]], $result->all());\n\n        // Using \\Raw value\n        $builder = $this->getBuilder();\n        $query = 'select \"category\", count(*) as \"total\" from \"item\" where \"department\" = ? group by \"category\" having \"total\" > 3';\n        $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true, [])->andReturn([['category' => 'rock', 'total' => 5]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('item');\n        $result = $builder->select(['category', new Raw('count(*) as \"total\"')])->where('department', '=', 'popular')->groupBy('category')->having('total', '>', new Raw('3'))->get();\n        $this->assertEquals([['category' => 'rock', 'total' => 5]], $result->all());\n    }\n\n    public function testRawHavings()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingRaw('user_foo < user_bar');\n        $this->assertSame('select * from \"users\" having user_foo < user_bar', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having('baz', '=', 1)->orHavingRaw('user_foo < user_bar');\n        $this->assertSame('select * from \"users\" having \"baz\" = ? or user_foo < user_bar', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->havingBetween('last_login_date', ['2018-11-16', '2018-12-16'])->orHavingRaw('user_foo < user_bar');\n        $this->assertSame('select * from \"users\" having \"last_login_date\" between ? and ? or user_foo < user_bar', $builder->toSql());\n    }\n\n    public function testLimitsAndOffsets()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(5)->limit(10);\n        $this->assertSame('select * from \"users\" limit 10 offset 5', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->limit(null);\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->limit(0);\n        $this->assertSame('select * from \"users\" limit 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(5)->limit(10);\n        $this->assertSame('select * from \"users\" limit 10 offset 5', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(0)->limit(0);\n        $this->assertSame('select * from \"users\" limit 0 offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(-5)->limit(-10);\n        $this->assertSame('select * from \"users\" offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(null)->limit(null);\n        $this->assertSame('select * from \"users\" offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->offset(5)->limit(null);\n        $this->assertSame('select * from \"users\" offset 5', $builder->toSql());\n    }\n\n    public function testForPage()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(2, 15);\n        $this->assertSame('select * from \"users\" limit 15 offset 15', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(0, 15);\n        $this->assertSame('select * from \"users\" limit 15 offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(-2, 15);\n        $this->assertSame('select * from \"users\" limit 15 offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(2, 0);\n        $this->assertSame('select * from \"users\" limit 0 offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(0, 0);\n        $this->assertSame('select * from \"users\" limit 0 offset 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPage(-2, 0);\n        $this->assertSame('select * from \"users\" limit 0 offset 0', $builder->toSql());\n    }\n\n    public function testForPageBeforeId()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPageBeforeId(15, null);\n        $this->assertSame('select * from \"users\" where \"id\" is not null order by \"id\" desc limit 15', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPageBeforeId(15, 0);\n        $this->assertSame('select * from \"users\" where \"id\" < ? order by \"id\" desc limit 15', $builder->toSql());\n    }\n\n    public function testForPageAfterId()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPageAfterId(15, null);\n        $this->assertSame('select * from \"users\" where \"id\" is not null order by \"id\" asc limit 15', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->forPageAfterId(15, 0);\n        $this->assertSame('select * from \"users\" where \"id\" > ? order by \"id\" asc limit 15', $builder->toSql());\n    }\n\n    public function testGetCountForPaginationWithBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('users')->selectSub(function ($q) {\n            $q->select('body')->from('posts')->where('id', 4);\n        }, 'post');\n\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $count = $builder->getCountForPagination();\n        $this->assertEquals(1, $count);\n        $this->assertEquals([4], $builder->getBindings());\n    }\n\n    public function testGetCountForPaginationWithColumnAliases()\n    {\n        $builder = $this->getBuilder();\n        $columns = ['body as post_body', 'teaser', 'posts.created as published'];\n        $builder->from('posts')->select($columns);\n\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(\"body\", \"teaser\", \"posts\".\"created\") as aggregate from \"posts\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $count = $builder->getCountForPagination($columns);\n        $this->assertEquals(1, $count);\n    }\n\n    public function testGetCountForPaginationWithUnion()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'));\n\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select \"id\" from \"posts\") union (select \"id\" from \"videos\")) as \"temp_table\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $count = $builder->getCountForPagination();\n        $this->assertEquals(1, $count);\n    }\n\n    public function testGetCountForPaginationWithUnionOrders()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->latest();\n\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select \"id\" from \"posts\") union (select \"id\" from \"videos\")) as \"temp_table\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $count = $builder->getCountForPagination();\n        $this->assertEquals(1, $count);\n    }\n\n    public function testGetCountForPaginationWithUnionLimitAndOffset()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'))->limit(15)->offset(1);\n\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select \"id\" from \"posts\") union (select \"id\" from \"videos\")) as \"temp_table\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n\n        $count = $builder->getCountForPagination();\n        $this->assertEquals(1, $count);\n    }\n\n    public function testWhereShortcut()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('id', 1)->orWhere('name', 'foo');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or \"name\" = ?', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testOrWheresHaveConsistentResults()\n    {\n        $queries = [];\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere(['foo' => 1, 'bar' => 2]);\n        $queries[] = $builder->toSql();\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', 2]]);\n        $queries[] = $builder->toSql();\n\n        $this->assertSame([\n            'select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)',\n            'select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)',\n        ], $queries);\n\n        $queries = [];\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn(['foo' => '_foo', 'bar' => '_bar']);\n        $queries[] = $builder->toSql();\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn([['foo', '_foo'], ['bar', '_bar']]);\n        $queries[] = $builder->toSql();\n\n        $this->assertSame([\n            'select * from \"users\" where \"xxxx\" = ? or (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")',\n            'select * from \"users\" where \"xxxx\" = ? or (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")',\n        ], $queries);\n    }\n\n    public function testWhereWithArrayConditions()\n    {\n        // where(key, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]]);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2]);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        // where(key, <, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" < ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? or \"bar\" < ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" < ?)', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        // whereNot(key, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]], boolean: 'or');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? or \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]], boolean: 'and');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2], boolean: 'or');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? or \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2], boolean: 'and');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        // whereNot(key, <, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" < ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]], boolean: 'or');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? or \"bar\" < ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]], boolean: 'and');\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" < ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        // whereColumn(col1, col2)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']]);\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '_bar']], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar']);\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar'], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn(['foo' => '_foo', 'bar' => '_bar'], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        // whereColumn(col1, <, col2)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']]);\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" < \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']], boolean: 'or');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" or \"bar\" < \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereColumn([['foo', '_foo'], ['bar', '<', '_bar']], boolean: 'and');\n        $this->assertSame('select * from \"users\" where (\"foo\" = \"_foo\" and \"bar\" < \"_bar\")', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n\n        // whereAll([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAll(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAll(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        // whereAny([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAny(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereAny(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        // whereNone([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNone(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where not (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNone(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where not (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 2, 1 => 2], $builder->getBindings());\n\n        // where()->orWhere(key, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', 2]]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere(['foo' => 1, 'bar' => 2]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        // where()->orWhere(key, <, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" < ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereColumn(col1, col2)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn([['foo', '_foo'], ['bar', '_bar']]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereColumn(['foo' => '_foo', 'bar' => '_bar']);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = \"_foo\" or \"bar\" = \"_bar\")', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx'], $builder->getBindings());\n\n        // where()->orWhere(key, <, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhere([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" < ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereNot(key, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot([['foo', 1], ['bar', 2]]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or not ((\"foo\" = ? or \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot(['foo' => 1, 'bar' => 2]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or not ((\"foo\" = ? or \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereNot(key, <, value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNot([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or not ((\"foo\" = ? or \"bar\" < ?))', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 1, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereAll([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAll(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAll(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? and \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereAny([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAny(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereAny(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n\n        // where()->orWhereNone([...keys], value)\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNone(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or not (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('xxxx', 'xxxx')->orWhereNone(['foo', 'bar'], 2);\n        $this->assertSame('select * from \"users\" where \"xxxx\" = ? or not (\"foo\" = ? or \"bar\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'xxxx', 1 => 2, 2 => 2], $builder->getBindings());\n    }\n\n    public function testNestedWheres()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('email', '=', 'foo')->orWhere(function ($q) {\n            $q->where('name', '=', 'bar')->where('age', '=', 25);\n        });\n        $this->assertSame('select * from \"users\" where \"email\" = ? or (\"name\" = ? and \"age\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'foo', 1 => 'bar', 2 => 25], $builder->getBindings());\n    }\n\n    public function testNestedWhereBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->where('email', '=', 'foo')->where(function ($q) {\n            $q->selectRaw('?', ['ignore'])->where('name', '=', 'bar');\n        });\n        $this->assertEquals([0 => 'foo', 1 => 'bar'], $builder->getBindings());\n    }\n\n    public function testWhereNot()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot(function ($q) {\n            $q->where('email', '=', 'foo');\n        });\n        $this->assertSame('select * from \"users\" where not (\"email\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('name', '=', 'bar')->whereNot(function ($q) {\n            $q->where('email', '=', 'foo');\n        });\n        $this->assertSame('select * from \"users\" where \"name\" = ? and not (\"email\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'bar', 1 => 'foo'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('name', '=', 'bar')->orWhereNot(function ($q) {\n            $q->where('email', '=', 'foo');\n        });\n        $this->assertSame('select * from \"users\" where \"name\" = ? or not (\"email\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'bar', 1 => 'foo'], $builder->getBindings());\n    }\n\n    public function testIncrementManyArgumentValidation1()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Non-numeric value passed as increment amount for column: \\'col\\'.');\n        $builder = $this->getBuilder();\n        $builder->from('users')->incrementEach(['col' => 'a']);\n    }\n\n    public function testIncrementManyArgumentValidation2()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Non-associative array passed to incrementEach method.');\n        $builder = $this->getBuilder();\n        $builder->from('users')->incrementEach([11 => 11]);\n    }\n\n    public function testWhereNotWithArrayConditions()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', 2]]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot(['foo' => 1, 'bar' => 2]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" = ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->whereNot([['foo', 1], ['bar', '<', 2]]);\n        $this->assertSame('select * from \"users\" where not ((\"foo\" = ? and \"bar\" < ?))', $builder->toSql());\n        $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());\n    }\n\n    public function testFullSubSelects()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('email', '=', 'foo')->orWhere('id', '=', function ($q) {\n            $q->select(new Raw('max(id)'))->from('users')->where('email', '=', 'bar');\n        });\n\n        $this->assertSame('select * from \"users\" where \"email\" = ? or \"id\" = (select max(id) from \"users\" where \"email\" = ?)', $builder->toSql());\n        $this->assertEquals([0 => 'foo', 1 => 'bar'], $builder->getBindings());\n    }\n\n    public function testWhereExists()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereExists(function ($q) {\n            $q->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'));\n        });\n        $this->assertSame('select * from \"orders\" where exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereNotExists(function ($q) {\n            $q->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'));\n        });\n        $this->assertSame('select * from \"orders\" where not exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereExists(function ($q) {\n            $q->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'));\n        });\n        $this->assertSame('select * from \"orders\" where \"id\" = ? or exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereNotExists(function ($q) {\n            $q->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'));\n        });\n        $this->assertSame('select * from \"orders\" where \"id\" = ? or not exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereExists(\n            $this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'))\n        );\n        $this->assertSame('select * from \"orders\" where exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereNotExists(\n            $this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'))\n        );\n        $this->assertSame('select * from \"orders\" where not exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereExists(\n            $this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'))\n        );\n        $this->assertSame('select * from \"orders\" where \"id\" = ? or exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereNotExists(\n            $this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'))\n        );\n        $this->assertSame('select * from \"orders\" where \"id\" = ? or not exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereExists(\n            (new EloquentBuilder($this->getBuilder()))->select('*')->from('products')->where('products.id', '=', new Raw('\"orders\".\"id\"'))\n        );\n        $this->assertSame('select * from \"orders\" where exists (select * from \"products\" where \"products\".\"id\" = \"orders\".\"id\")', $builder->toSql());\n    }\n\n    public function testBasicJoins()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', 'users.id', 'contacts.id');\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->leftJoin('photos', 'users.id', '=', 'photos.id');\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" left join \"photos\" on \"users\".\"id\" = \"photos\".\"id\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoinWhere('photos', 'users.id', '=', 'bar')->joinWhere('photos', 'users.id', '=', 'foo');\n        $this->assertSame('select * from \"users\" left join \"photos\" on \"users\".\"id\" = ? inner join \"photos\" on \"users\".\"id\" = ?', $builder->toSql());\n        $this->assertEquals(['bar', 'foo'], $builder->getBindings());\n    }\n\n    public function testCrossJoins()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('sizes')->crossJoin('colors');\n        $this->assertSame('select * from \"sizes\" cross join \"colors\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('tableB')->join('tableA', 'tableA.column1', '=', 'tableB.column2', 'cross');\n        $this->assertSame('select * from \"tableB\" cross join \"tableA\" on \"tableA\".\"column1\" = \"tableB\".\"column2\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('tableB')->crossJoin('tableA', 'tableA.column1', '=', 'tableB.column2');\n        $this->assertSame('select * from \"tableB\" cross join \"tableA\" on \"tableA\".\"column1\" = \"tableB\".\"column2\"', $builder->toSql());\n    }\n\n    public function testCrossJoinSubs()\n    {\n        $builder = $this->getBuilder();\n        $builder->selectRaw('(sale / overall.sales) * 100 AS percent_of_total')->from('sales')->crossJoinSub($this->getBuilder()->selectRaw('SUM(sale) AS sales')->from('sales'), 'overall');\n        $this->assertSame('select (sale / overall.sales) * 100 AS percent_of_total from \"sales\" cross join (select SUM(sale) AS sales from \"sales\") as \"overall\"', $builder->toSql());\n    }\n\n    public function testComplexJoin()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->orOn('users.name', '=', 'contacts.name');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"users\".\"name\" = \"contacts\".\"name\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->where('users.id', '=', 'foo')->orWhere('users.name', '=', 'bar');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = ? or \"users\".\"name\" = ?', $builder->toSql());\n        $this->assertEquals(['foo', 'bar'], $builder->getBindings());\n\n        // Run the assertions again\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = ? or \"users\".\"name\" = ?', $builder->toSql());\n        $this->assertEquals(['foo', 'bar'], $builder->getBindings());\n    }\n\n    public function testJoinWhereNull()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->whereNull('contacts.deleted_at');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"deleted_at\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->orWhereNull('contacts.deleted_at');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"contacts\".\"deleted_at\" is null', $builder->toSql());\n    }\n\n    public function testJoinWhereNotNull()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->whereNotNull('contacts.deleted_at');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"deleted_at\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->orWhereNotNull('contacts.deleted_at');\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"contacts\".\"deleted_at\" is not null', $builder->toSql());\n    }\n\n    public function testJoinWhereIn()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->whereIn('contacts.name', [48, 'baz', null]);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"name\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([48, 'baz', null], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->orWhereIn('contacts.name', [48, 'baz', null]);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"contacts\".\"name\" in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([48, 'baz', null], $builder->getBindings());\n    }\n\n    public function testJoinWhereInSubquery()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $q = $this->getBuilder();\n            $q->select('name')->from('contacts')->where('name', 'baz');\n            $j->on('users.id', '=', 'contacts.id')->whereIn('contacts.name', $q);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"name\" in (select \"name\" from \"contacts\" where \"name\" = ?)', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $q = $this->getBuilder();\n            $q->select('name')->from('contacts')->where('name', 'baz');\n            $j->on('users.id', '=', 'contacts.id')->orWhereIn('contacts.name', $q);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"contacts\".\"name\" in (select \"name\" from \"contacts\" where \"name\" = ?)', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testJoinWhereNotIn()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->whereNotIn('contacts.name', [48, 'baz', null]);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"name\" not in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([48, 'baz', null], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->orWhereNotIn('contacts.name', [48, 'baz', null]);\n        });\n        $this->assertSame('select * from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" or \"contacts\".\"name\" not in (?, ?, ?)', $builder->toSql());\n        $this->assertEquals([48, 'baz', null], $builder->getBindings());\n    }\n\n    public function testJoinsWithNestedConditions()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->where(function ($j) {\n                $j->where('contacts.country', '=', 'US')->orWhere('contacts.is_partner', '=', 1);\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and (\"contacts\".\"country\" = ? or \"contacts\".\"is_partner\" = ?)', $builder->toSql());\n        $this->assertEquals(['US', 1], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', '=', 'contacts.id')->where('contacts.is_active', '=', 1)->orOn(function ($j) {\n                $j->orWhere(function ($j) {\n                    $j->where('contacts.country', '=', 'UK')->orOn('contacts.type', '=', 'users.type');\n                })->where(function ($j) {\n                    $j->where('contacts.country', '=', 'US')->orWhereNull('contacts.is_partner');\n                });\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contacts\".\"is_active\" = ? or ((\"contacts\".\"country\" = ? or \"contacts\".\"type\" = \"users\".\"type\") and (\"contacts\".\"country\" = ? or \"contacts\".\"is_partner\" is null))', $builder->toSql());\n        $this->assertEquals([1, 'UK', 'US'], $builder->getBindings());\n    }\n\n    public function testJoinsWithAdvancedConditions()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')->where(function ($j) {\n                $j->whereRole('admin')\n                    ->orWhereNull('contacts.disabled')\n                    ->orWhereRaw('year(contacts.created_at) = 2016');\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and (\"role\" = ? or \"contacts\".\"disabled\" is null or year(contacts.created_at) = 2016)', $builder->toSql());\n        $this->assertEquals(['admin'], $builder->getBindings());\n    }\n\n    public function testJoinsWithSubqueryCondition()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')->whereIn('contact_type_id', function ($q) {\n                $q->select('id')->from('contact_types')\n                    ->where('category_id', '1')\n                    ->whereNull('deleted_at');\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and \"contact_type_id\" in (select \"id\" from \"contact_types\" where \"category_id\" = ? and \"deleted_at\" is null)', $builder->toSql());\n        $this->assertEquals(['1'], $builder->getBindings());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')->whereExists(function ($q) {\n                $q->selectRaw('1')->from('contact_types')\n                    ->whereRaw('contact_types.id = contacts.contact_type_id')\n                    ->where('category_id', '1')\n                    ->whereNull('deleted_at');\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and exists (select 1 from \"contact_types\" where contact_types.id = contacts.contact_type_id and \"category_id\" = ? and \"deleted_at\" is null)', $builder->toSql());\n        $this->assertEquals(['1'], $builder->getBindings());\n    }\n\n    public function testJoinsWithAdvancedSubqueryCondition()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')->whereExists(function ($q) {\n                $q->selectRaw('1')->from('contact_types')\n                    ->whereRaw('contact_types.id = contacts.contact_type_id')\n                    ->where('category_id', '1')\n                    ->whereNull('deleted_at')\n                    ->whereIn('level_id', function ($q) {\n                        $q->select('id')->from('levels')\n                            ->where('is_active', true);\n                    });\n            });\n        });\n        $this->assertSame('select * from \"users\" left join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and exists (select 1 from \"contact_types\" where contact_types.id = contacts.contact_type_id and \"category_id\" = ? and \"deleted_at\" is null and \"level_id\" in (select \"id\" from \"levels\" where \"is_active\" = ?))', $builder->toSql());\n        $this->assertEquals(['1', true], $builder->getBindings());\n    }\n\n    public function testJoinsWithNestedJoins()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id');\n        });\n        $this->assertSame('select \"users\".\"id\", \"contacts\".\"id\", \"contact_types\".\"id\" from \"users\" left join (\"contacts\" inner join \"contact_types\" on \"contacts\".\"contact_type_id\" = \"contact_types\".\"id\") on \"users\".\"id\" = \"contacts\".\"id\"', $builder->toSql());\n    }\n\n    public function testJoinsWithMultipleNestedJoins()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('users.id', 'contacts.id', 'contact_types.id', 'countries.id', 'planets.id')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')\n                ->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')\n                ->leftJoin('countries', function ($q) {\n                    $q->on('contacts.country', '=', 'countries.country')\n                        ->join('planets', function ($q) {\n                            $q->on('countries.planet_id', '=', 'planet.id')\n                                ->where('planet.is_settled', '=', 1)\n                                ->where('planet.population', '>=', 10000);\n                        });\n                });\n        });\n        $this->assertSame('select \"users\".\"id\", \"contacts\".\"id\", \"contact_types\".\"id\", \"countries\".\"id\", \"planets\".\"id\" from \"users\" left join (\"contacts\" inner join \"contact_types\" on \"contacts\".\"contact_type_id\" = \"contact_types\".\"id\" left join (\"countries\" inner join \"planets\" on \"countries\".\"planet_id\" = \"planet\".\"id\" and \"planet\".\"is_settled\" = ? and \"planet\".\"population\" >= ?) on \"contacts\".\"country\" = \"countries\".\"country\") on \"users\".\"id\" = \"contacts\".\"id\"', $builder->toSql());\n        $this->assertEquals(['1', 10000], $builder->getBindings());\n    }\n\n    public function testJoinsWithNestedJoinWithAdvancedSubqueryCondition()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {\n            $j->on('users.id', 'contacts.id')\n                ->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')\n                ->whereExists(function ($q) {\n                    $q->select('*')->from('countries')\n                        ->whereColumn('contacts.country', '=', 'countries.country')\n                        ->join('planets', function ($q) {\n                            $q->on('countries.planet_id', '=', 'planet.id')\n                                ->where('planet.is_settled', '=', 1);\n                        })\n                        ->where('planet.population', '>=', 10000);\n                });\n        });\n        $this->assertSame('select \"users\".\"id\", \"contacts\".\"id\", \"contact_types\".\"id\" from \"users\" left join (\"contacts\" inner join \"contact_types\" on \"contacts\".\"contact_type_id\" = \"contact_types\".\"id\") on \"users\".\"id\" = \"contacts\".\"id\" and exists (select * from \"countries\" inner join \"planets\" on \"countries\".\"planet_id\" = \"planet\".\"id\" and \"planet\".\"is_settled\" = ? where \"contacts\".\"country\" = \"countries\".\"country\" and \"planet\".\"population\" >= ?)', $builder->toSql());\n        $this->assertEquals(['1', 10000], $builder->getBindings());\n    }\n\n    public function testJoinWithNestedOnCondition()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('users.id')->from('users')->join('contacts', function (JoinClause $j) {\n            return $j\n                ->on('users.id', 'contacts.id')\n                ->addNestedWhereQuery($this->getBuilder()->where('contacts.id', 1));\n        });\n        $this->assertSame('select \"users\".\"id\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" and (\"contacts\".\"id\" = ?)', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testJoinSub()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('users')->joinSub('select * from \"contacts\"', 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"users\" inner join (select * from \"contacts\") as \"sub\" on \"users\".\"id\" = \"sub\".\"id\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->from('users')->joinSub(function ($q) {\n            $q->from('contacts');\n        }, 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"users\" inner join (select * from \"contacts\") as \"sub\" on \"users\".\"id\" = \"sub\".\"id\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $eloquentBuilder = new EloquentBuilder($this->getBuilder()->from('contacts'));\n        $builder->from('users')->joinSub($eloquentBuilder, 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"users\" inner join (select * from \"contacts\") as \"sub\" on \"users\".\"id\" = \"sub\".\"id\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $sub1 = $this->getBuilder()->from('contacts')->where('name', 'foo');\n        $sub2 = $this->getBuilder()->from('contacts')->where('name', 'bar');\n        $builder->from('users')\n            ->joinSub($sub1, 'sub1', 'users.id', '=', 1, 'inner', true)\n            ->joinSub($sub2, 'sub2', 'users.id', '=', 'sub2.user_id');\n        $expected = 'select * from \"users\" ';\n        $expected .= 'inner join (select * from \"contacts\" where \"name\" = ?) as \"sub1\" on \"users\".\"id\" = ? ';\n        $expected .= 'inner join (select * from \"contacts\" where \"name\" = ?) as \"sub2\" on \"users\".\"id\" = \"sub2\".\"user_id\"';\n        $this->assertEquals($expected, $builder->toSql());\n        $this->assertEquals(['foo', 1, 'bar'], $builder->getRawBindings()['join']);\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->joinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');\n    }\n\n    public function testJoinSubWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $builder->from('users')->joinSub('select * from \"contacts\"', 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"prefix_users\" inner join (select * from \"contacts\") as \"prefix_sub\" on \"prefix_users\".\"id\" = \"prefix_sub\".\"id\"', $builder->toSql());\n    }\n\n    public function testLeftJoinSub()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('users')->leftJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"users\" left join (select * from \"contacts\") as \"sub\" on \"users\".\"id\" = \"sub\".\"id\"', $builder->toSql());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->leftJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');\n    }\n\n    public function testRightJoinSub()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('users')->rightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from \"users\" right join (select * from \"contacts\") as \"sub\" on \"users\".\"id\" = \"sub\".\"id\"', $builder->toSql());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->rightJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');\n    }\n\n    public function testStraightJoin()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->select('*')->from('users')->straightJoin('contacts', 'users.id', 'contacts.id');\n        $this->assertSame('select * from `users` straight_join `contacts` on `users`.`id` = `contacts`.`id`', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->select('*')->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->straightJoin('photos', 'users.id', '=', 'photos.id');\n        $this->assertSame('select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` straight_join `photos` on `users`.`id` = `photos`.`id`', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->select('*')->from('users')->straightJoinWhere('photos', 'users.id', '=', 'bar')->joinWhere('photos', 'users.id', '=', 'foo');\n        $this->assertSame('select * from `users` straight_join `photos` on `users`.`id` = ? inner join `photos` on `users`.`id` = ?', $builder->toSql());\n        $this->assertEquals(['bar', 'foo'], $builder->getBindings());\n    }\n\n    public function testStraightJoinNoSupport()\n    {\n        $this->expectException(RuntimeException::class);\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->straightJoin('contacts', 'users.id', 'contacts.id');\n        $builder->toSql();\n    }\n\n    public function testStraightJoinSub()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->straightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');\n        $this->assertSame('select * from `users` straight_join (select * from \"contacts\") as `sub` on `users`.`id` = `sub`.`id`', $builder->toSql());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->straightJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');\n    }\n\n    public function testStraightJoinSubNoSupport()\n    {\n        $this->expectException(RuntimeException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->straightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');\n        $builder->toSql();\n    }\n\n    public function testJoinLateral()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral('select * from `contacts` where `contracts`.`user_id` = `users`.`id`', 'sub');\n        $this->assertSame('select * from `users` inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id`) as `sub` on true', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub');\n        $this->assertSame('select * from `users` inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id`) as `sub` on true', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $sub = $this->getMySqlBuilder();\n        $sub->getConnection()->shouldReceive('getDatabaseName');\n        $eloquentBuilder = new EloquentBuilder($sub->from('contacts')->whereColumn('contracts.user_id', 'users.id'));\n        $builder->from('users')->joinLateral($eloquentBuilder, 'sub');\n        $this->assertSame('select * from `users` inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id`) as `sub` on true', $builder->toSql());\n\n        $sub1 = $this->getMySqlBuilder();\n        $sub1->getConnection()->shouldReceive('getDatabaseName');\n        $sub1 = $sub1->from('contacts')->whereColumn('contracts.user_id', 'users.id')->where('name', 'foo');\n\n        $sub2 = $this->getMySqlBuilder();\n        $sub2->getConnection()->shouldReceive('getDatabaseName');\n        $sub2 = $sub2->from('contacts')->whereColumn('contracts.user_id', 'users.id')->where('name', 'bar');\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral($sub1, 'sub1')->joinLateral($sub2, 'sub2');\n\n        $expected = 'select * from `users` ';\n        $expected .= 'inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id` and `name` = ?) as `sub1` on true ';\n        $expected .= 'inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id` and `name` = ?) as `sub2` on true';\n\n        $this->assertEquals($expected, $builder->toSql());\n        $this->assertEquals(['foo', 'bar'], $builder->getRawBindings()['join']);\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getMySqlBuilder();\n        $builder->from('users')->joinLateral(['foo'], 'sub');\n    }\n\n    public function testJoinLateralMariaDb()\n    {\n        $this->expectException(RuntimeException::class);\n        $builder = $this->getMariaDbBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub')->toSql();\n    }\n\n    public function testJoinLateralSQLite()\n    {\n        $this->expectException(RuntimeException::class);\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub')->toSql();\n    }\n\n    public function testJoinLateralPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub');\n        $this->assertSame('select * from \"users\" inner join lateral (select * from \"contacts\" where \"contracts\".\"user_id\" = \"users\".\"id\") as \"sub\" on true', $builder->toSql());\n    }\n\n    public function testJoinLateralSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->joinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub');\n        $this->assertSame('select * from [users] cross apply (select * from [contacts] where [contracts].[user_id] = [users].[id]) as [sub]', $builder->toSql());\n    }\n\n    public function testJoinLateralWithPrefix()\n    {\n        $builder = $this->getMySqlBuilder(prefix: 'prefix_');\n        $builder->from('users')->joinLateral('select * from `contacts` where `contracts`.`user_id` = `users`.`id`', 'sub');\n        $this->assertSame('select * from `prefix_users` inner join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id`) as `prefix_sub` on true', $builder->toSql());\n    }\n\n    public function testLeftJoinLateral()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n\n        $sub = $this->getMySqlBuilder();\n        $sub->getConnection()->shouldReceive('getDatabaseName');\n\n        $builder->from('users')->leftJoinLateral($sub->from('contacts')->whereColumn('contracts.user_id', 'users.id'), 'sub');\n        $this->assertSame('select * from `users` left join lateral (select * from `contacts` where `contracts`.`user_id` = `users`.`id`) as `sub` on true', $builder->toSql());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('users')->leftJoinLateral(['foo'], 'sub');\n    }\n\n    public function testLeftJoinLateralSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->from('users')->leftJoinLateral(function ($q) {\n            $q->from('contacts')->whereColumn('contracts.user_id', 'users.id');\n        }, 'sub');\n        $this->assertSame('select * from [users] outer apply (select * from [contacts] where [contracts].[user_id] = [users].[id]) as [sub]', $builder->toSql());\n    }\n\n    public function testRawExpressionsInSelect()\n    {\n        $builder = $this->getBuilder();\n        $builder->select(new Raw('substr(foo, 6)'))->from('users');\n        $this->assertSame('select substr(foo, 6) from \"users\"', $builder->toSql());\n    }\n\n    public function testFindReturnsFirstResultByID()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select * from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->find(1);\n        $this->assertEquals(['foo' => 'bar'], $results);\n    }\n\n    public function testFindOrReturnsFirstResultByID()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $data = m::mock(stdClass::class);\n        $builder->shouldReceive('first')->andReturn($data)->once();\n        $builder->shouldReceive('first')->with(['column'])->andReturn($data)->once();\n        $builder->shouldReceive('first')->andReturn(null)->once();\n\n        $this->assertSame($data, $builder->findOr(1, fn () => 'callback result'));\n        $this->assertSame($data, $builder->findOr(1, ['column'], fn () => 'callback result'));\n        $this->assertSame('callback result', $builder->findOr(1, fn () => 'callback result'));\n    }\n\n    public function testFirstMethodReturnsFirstResult()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select * from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->first();\n        $this->assertEquals(['foo' => 'bar'], $results);\n    }\n\n    public function testFirstOrFailMethodReturnsFirstResult()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select * from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->firstOrFail();\n        $this->assertEquals(['foo' => 'bar'], $results);\n    }\n\n    public function testFirstOrFailMethodThrowsRecordNotFoundException()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select * from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([]);\n\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [])->andReturn([]);\n\n        $this->expectException(RecordNotFoundException::class);\n        $this->expectExceptionMessage('No record found for the given query.');\n\n        $builder->from('users')->where('id', '=', 1)->firstOrFail();\n    }\n\n    public function testPluckMethodGetsCollectionOfColumnValues()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->pluck('foo');\n        $this->assertEquals(['bar', 'baz'], $results->all());\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->andReturn([['id' => 1, 'foo' => 'bar'], ['id' => 10, 'foo' => 'baz']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['id' => 1, 'foo' => 'bar'], ['id' => 10, 'foo' => 'baz']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->pluck('foo', 'id');\n        $this->assertEquals([1 => 'bar', 10 => 'baz'], $results->all());\n    }\n\n    public function testPluckAvoidsDuplicateColumnSelection()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select \"foo\" from \"users\" where \"id\" = ?', [1], true, [])->andReturn([['foo' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->pluck('foo', 'foo');\n        $this->assertEquals(['bar' => 'bar'], $results->all());\n    }\n\n    public function testImplode()\n    {\n        // Test without glue.\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->implode('foo');\n        $this->assertSame('barbaz', $results);\n\n        // Test with glue.\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->where('id', '=', 1)->implode('foo', ',');\n        $this->assertSame('bar,baz', $results);\n    }\n\n    public function testValueMethodReturnsSingleColumn()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select \"foo\" from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([['foo' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn([['foo' => 'bar']]);\n        $results = $builder->from('users')->where('id', '=', 1)->value('foo');\n        $this->assertSame('bar', $results);\n    }\n\n    public function testRawValueMethodReturnsSingleColumn()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select UPPER(\"foo\") from \"users\" where \"id\" = ? limit 1', [1], true, [])->andReturn([['UPPER(\"foo\")' => 'BAR']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['UPPER(\"foo\")' => 'BAR']])->andReturn([['UPPER(\"foo\")' => 'BAR']]);\n        $results = $builder->from('users')->where('id', '=', 1)->rawValue('UPPER(\"foo\")');\n        $this->assertSame('BAR', $results);\n    }\n\n    public function testAggregateFunctions()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->count();\n        $this->assertEquals(1, $results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from \"users\") as \"exists\"', [], true)->andReturn([['exists' => 1]]);\n        $results = $builder->from('users')->exists();\n        $this->assertTrue($results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from \"users\") as \"exists\"', [], true)->andReturn([['exists' => 0]]);\n        $results = $builder->from('users')->doesntExist();\n        $this->assertTrue($results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select max(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->max('id');\n        $this->assertEquals(1, $results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select min(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->min('id');\n        $this->assertEquals(1, $results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select sum(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->sum('id');\n        $this->assertEquals(1, $results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select avg(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->avg('id');\n        $this->assertEquals(1, $results);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select avg(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $results = $builder->from('users')->average('id');\n        $this->assertEquals(1, $results);\n    }\n\n    public function testSqlServerExists()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select top 1 1 [exists] from [users]', [], true)->andReturn([['exists' => 1]]);\n        $results = $builder->from('users')->exists();\n        $this->assertTrue($results);\n    }\n\n    public function testExistsOr()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 1]]);\n        $results = $builder->from('users')->doesntExistOr(function () {\n            return 123;\n        });\n        $this->assertSame(123, $results);\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 0]]);\n        $results = $builder->from('users')->doesntExistOr(function () {\n            throw new RuntimeException;\n        });\n        $this->assertTrue($results);\n    }\n\n    public function testDoesntExistsOr()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 0]]);\n        $results = $builder->from('users')->existsOr(function () {\n            return 123;\n        });\n        $this->assertSame(123, $results);\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 1]]);\n        $results = $builder->from('users')->existsOr(function () {\n            throw new RuntimeException;\n        });\n        $this->assertTrue($results);\n    }\n\n    public function testAggregateResetFollowedByGet()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getConnection()->shouldReceive('select')->once()->with('select sum(\"id\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 2]]);\n        $builder->getConnection()->shouldReceive('select')->once()->with('select \"column1\", \"column2\" from \"users\"', [], true, [])->andReturn([['column1' => 'foo', 'column2' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('users')->select('column1', 'column2');\n        $count = $builder->count();\n        $this->assertEquals(1, $count);\n        $sum = $builder->sum('id');\n        $this->assertEquals(2, $sum);\n        $result = $builder->get();\n        $this->assertEquals([['column1' => 'foo', 'column2' => 'bar']], $result->all());\n    }\n\n    public function testAggregateResetFollowedBySelectGet()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(\"column1\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getConnection()->shouldReceive('select')->once()->with('select \"column2\", \"column3\" from \"users\"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('users');\n        $count = $builder->count('column1');\n        $this->assertEquals(1, $count);\n        $result = $builder->select('column2', 'column3')->get();\n        $this->assertEquals([['column2' => 'foo', 'column3' => 'bar']], $result->all());\n    }\n\n    public function testAggregateResetFollowedByGetWithColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(\"column1\") as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getConnection()->shouldReceive('select')->once()->with('select \"column2\", \"column3\" from \"users\"', [], true, [])->andReturn([['column2' => 'foo', 'column3' => 'bar']]);\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('users');\n        $count = $builder->count('column1');\n        $this->assertEquals(1, $count);\n        $result = $builder->get(['column2', 'column3']);\n        $this->assertEquals([['column2' => 'foo', 'column3' => 'bar']], $result->all());\n    }\n\n    public function testAggregateWithSubSelect()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from \"users\"', [], true, [])->andReturn([['aggregate' => 1]]);\n        $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {\n            return $results;\n        });\n        $builder->from('users')->selectSub(function ($query) {\n            $query->from('posts')->select('foo', 'bar')->where('title', 'foo');\n        }, 'post');\n        $count = $builder->count();\n        $this->assertEquals(1, $count);\n        $this->assertSame('(select \"foo\", \"bar\" from \"posts\" where \"title\" = ?) as \"post\"', $builder->getGrammar()->getValue($builder->columns[0]));\n        $this->assertEquals(['foo'], $builder->getBindings());\n    }\n\n    public function testSubqueriesBindings()\n    {\n        $builder = $this->getBuilder();\n        $second = $this->getBuilder()->select('*')->from('users')->orderByRaw('id = ?', 2);\n        $third = $this->getBuilder()->select('*')->from('users')->where('id', 3)->groupBy('id')->having('id', '!=', 4);\n        $builder->groupBy('a')->having('a', '=', 1)->union($second)->union($third);\n        $this->assertEquals([0 => 1, 1 => 2, 2 => 3, 3 => 4], $builder->getBindings());\n\n        $builder = $this->getBuilder()->select('*')->from('users')->where('email', '=', function ($q) {\n            $q->select(new Raw('max(id)'))\n                ->from('users')->where('email', '=', 'bar')\n                ->orderByRaw('email like ?', '%.com')\n                ->groupBy('id')->having('id', '=', 4);\n        })->orWhere('id', '=', 'foo')->groupBy('id')->having('id', '=', 5);\n        $this->assertEquals([0 => 'bar', 1 => 4, 2 => '%.com', 3 => 'foo', 4 => 5], $builder->getBindings());\n    }\n\n    public function testInsertMethod()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('insert')->once()->with('insert into \"users\" (\"email\") values (?)', ['foo'])->andReturn(true);\n        $result = $builder->from('users')->insert(['email' => 'foo']);\n        $this->assertTrue($result);\n    }\n\n    public function testInsertUsingMethod()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"table1\" (\"foo\") select \"bar\" from \"table2\" where \"foreign_id\" = ?', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertUsing(\n            ['foo'],\n            function (Builder $query) {\n                $query->select(['bar'])->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testInsertUsingWithEmptyColumns()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"table1\" select * from \"table2\" where \"foreign_id\" = ?', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertUsing(\n            [],\n            function (Builder $query) {\n                $query->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testInsertUsingInvalidSubquery()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->from('table1')->insertUsing(['foo'], ['bar']);\n    }\n\n    public function testInsertOrIgnoreMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getBuilder();\n        $builder->from('users')->insertOrIgnore(['email' => 'foo']);\n    }\n\n    public function testMySqlInsertOrIgnoreMethod()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert ignore into `users` (`email`) values (?)', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testPostgresInsertOrIgnoreMethod()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\") values (?) on conflict do nothing', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testSQLiteInsertOrIgnoreMethod()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert or ignore into \"users\" (\"email\") values (?)', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testSqlServerInsertOrIgnoreMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getSqlServerBuilder();\n        $builder->from('users')->insertOrIgnore(['email' => 'foo']);\n    }\n\n    public function testInsertOrIgnoreReturningMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo']);\n    }\n\n    public function testInsertOrIgnoreReturningMethodWithEmptyValues()\n    {\n        $builder = $this->getPostgresBuilder();\n        $result = $builder->from('users')->insertOrIgnoreReturning([]);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertTrue($result->isEmpty());\n    }\n\n    public function testMySqlInsertOrIgnoreReturningMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getMySqlBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo']);\n    }\n\n    public function testPostgresInsertOrIgnoreReturningMethod()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\") values (?) on conflict do nothing returning \"id\"',\n            ['foo']\n        )->andReturn([['id' => 1]]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo'], ['id']);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1]], $result->all());\n    }\n\n    public function testPostgresInsertOrIgnoreReturningMethodWithUniqueByColumn()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\", \"name\") values (?, ?) on conflict (\"email\") do nothing returning *',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo', 'name' => 'bar']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo', 'name' => 'bar'], ['*'], 'email');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo', 'name' => 'bar']], $result->all());\n    }\n\n    public function testPostgresInsertOrIgnoreReturningMethodWithUniqueByColumns()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\", \"name\") values (?, ?) on conflict (\"email\", \"name\") do nothing returning *',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo', 'name' => 'bar']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo', 'name' => 'bar'], ['*'], ['email', 'name']);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo', 'name' => 'bar']], $result->all());\n    }\n\n    public function testPostgresInsertOrIgnoreReturningMethodWithMultipleRecords()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\") values (?), (?) on conflict do nothing returning \"id\", \"email\"',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(\n            [['email' => 'foo'], ['email' => 'bar']],\n            ['id', 'email']\n        );\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo']], $result->all());\n    }\n\n    public function testSqliteInsertOrIgnoreReturningMethod()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\") values (?) on conflict do nothing returning \"id\"',\n            ['foo']\n        )->andReturn([['id' => 1]]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo'], ['id']);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1]], $result->all());\n    }\n\n    public function testSqliteInsertOrIgnoreReturningMethodWithUniqueByColumn()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\", \"name\") values (?, ?) on conflict (\"email\") do nothing returning *',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo', 'name' => 'bar']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo', 'name' => 'bar'], ['*'], 'email');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo', 'name' => 'bar']], $result->all());\n    }\n\n    public function testSqliteInsertOrIgnoreReturningMethodWithUniqueByColumns()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\", \"name\") values (?, ?) on conflict (\"email\", \"name\") do nothing returning *',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo', 'name' => 'bar']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo', 'name' => 'bar'], ['*'], ['email', 'name']);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo', 'name' => 'bar']], $result->all());\n    }\n\n    public function testSqliteInsertOrIgnoreReturningMethodWithMultipleRecords()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\") values (?), (?) on conflict do nothing returning \"id\", \"email\"',\n            ['foo', 'bar']\n        )->andReturn([['id' => 1, 'email' => 'foo']]);\n        $result = $builder->from('users')->insertOrIgnoreReturning(\n            [['email' => 'foo'], ['email' => 'bar']],\n            ['id', 'email']\n        );\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertEquals([['id' => 1, 'email' => 'foo']], $result->all());\n    }\n\n    public function testSqlServerInsertOrIgnoreReturningMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getSqlServerBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo']);\n    }\n\n    public function testInsertOrIgnoreReturningWithEmptyUniqueByArray()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The unique columns must not be empty.');\n        $builder = $this->getPostgresBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo'], ['*'], []);\n    }\n\n    public function testInsertOrIgnoreReturningWithEmptyUniqueByString()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The unique columns must not be empty.');\n        $builder = $this->getPostgresBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo'], ['*'], '');\n    }\n\n    public function testInsertOrIgnoreReturningWithEmptyReturning()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The returning columns must not be empty.');\n        $builder = $this->getPostgresBuilder();\n        $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo'], []);\n    }\n\n    public function testInsertOrIgnoreReturningDoesNotMarkRecordsModifiedWhenNoRowsWereInserted()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('selectFromWriteConnection')->once()->with(\n            'insert into \"users\" (\"email\") values (?) on conflict do nothing returning *',\n            ['foo']\n        )->andReturn([]);\n        $builder->getConnection()->shouldReceive('recordsHaveBeenModified')->once()->with(false);\n        $result = $builder->from('users')->insertOrIgnoreReturning(['email' => 'foo']);\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertTrue($result->isEmpty());\n    }\n\n    public function testInsertOrIgnoreUsingMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getBuilder();\n        $builder->from('users')->insertOrIgnoreUsing(['email' => 'foo'], 'bar');\n    }\n\n    public function testSqlServerInsertOrIgnoreUsingMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('does not support');\n        $builder = $this->getSqlServerBuilder();\n        $builder->from('users')->insertOrIgnoreUsing(['email' => 'foo'], 'bar');\n    }\n\n    public function testMySqlInsertOrIgnoreUsingMethod()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert ignore into `table1` (`foo`) select `bar` from `table2` where `foreign_id` = ?', [0 => 5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            ['foo'],\n            function (Builder $query) {\n                $query->select(['bar'])->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testMySqlInsertOrIgnoreUsingWithEmptyColumns()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert ignore into `table1` select * from `table2` where `foreign_id` = ?', [0 => 5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            [],\n            function (Builder $query) {\n                $query->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testMySqlInsertOrIgnoreUsingInvalidSubquery()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getMySqlBuilder();\n        $builder->from('table1')->insertOrIgnoreUsing(['foo'], ['bar']);\n    }\n\n    public function testPostgresInsertOrIgnoreUsingMethod()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"table1\" (\"foo\") select \"bar\" from \"table2\" where \"foreign_id\" = ? on conflict do nothing', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            ['foo'],\n            function (Builder $query) {\n                $query->select(['bar'])->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testPostgresInsertOrIgnoreUsingWithEmptyColumns()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"table1\" select * from \"table2\" where \"foreign_id\" = ? on conflict do nothing', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            [],\n            function (Builder $query) {\n                $query->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testPostgresInsertOrIgnoreUsingInvalidSubquery()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getPostgresBuilder();\n        $builder->from('table1')->insertOrIgnoreUsing(['foo'], ['bar']);\n    }\n\n    public function testSQLiteInsertOrIgnoreUsingMethod()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert or ignore into \"table1\" (\"foo\") select \"bar\" from \"table2\" where \"foreign_id\" = ?', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            ['foo'],\n            function (Builder $query) {\n                $query->select(['bar'])->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testSQLiteInsertOrIgnoreUsingWithEmptyColumns()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('getDatabaseName');\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert or ignore into \"table1\" select * from \"table2\" where \"foreign_id\" = ?', [5])->andReturn(1);\n\n        $result = $builder->from('table1')->insertOrIgnoreUsing(\n            [],\n            function (Builder $query) {\n                $query->from('table2')->where('foreign_id', '=', 5);\n            }\n        );\n\n        $this->assertEquals(1, $result);\n    }\n\n    public function testSQLiteInsertOrIgnoreUsingInvalidSubquery()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getSQLiteBuilder();\n        $builder->from('table1')->insertOrIgnoreUsing(['foo'], ['bar']);\n    }\n\n    public function testInsertGetIdMethod()\n    {\n        $builder = $this->getBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" (\"email\") values (?)', ['foo'], 'id')->andReturn(1);\n        $result = $builder->from('users')->insertGetId(['email' => 'foo'], 'id');\n        $this->assertEquals(1, $result);\n    }\n\n    public function testInsertGetIdMethodRemovesExpressions()\n    {\n        $builder = $this->getBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" (\"email\", \"bar\") values (?, bar)', ['foo'], 'id')->andReturn(1);\n        $result = $builder->from('users')->insertGetId(['email' => 'foo', 'bar' => new Raw('bar')], 'id');\n        $this->assertEquals(1, $result);\n    }\n\n    public function testInsertGetIdWithEmptyValues()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into `users` () values ()', [], null);\n        $builder->from('users')->insertGetId([]);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" default values returning \"id\"', [], null);\n        $builder->from('users')->insertGetId([]);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" default values', [], null);\n        $builder->from('users')->insertGetId([]);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into [users] default values', [], null);\n        $builder->from('users')->insertGetId([]);\n    }\n\n    public function testInsertMethodRespectsRawBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('insert')->once()->with('insert into \"users\" (\"email\") values (CURRENT TIMESTAMP)', [])->andReturn(true);\n        $result = $builder->from('users')->insert(['email' => new Raw('CURRENT TIMESTAMP')]);\n        $this->assertTrue($result);\n    }\n\n    public function testMultipleInsertsWithExpressionValues()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('insert')->once()->with('insert into \"users\" (\"email\") values (UPPER(\\'Foo\\')), (LOWER(\\'Foo\\'))', [])->andReturn(true);\n        $result = $builder->from('users')->insert([['email' => new Raw(\"UPPER('Foo')\")], ['email' => new Raw(\"LOWER('Foo')\")]]);\n        $this->assertTrue($result);\n    }\n\n    public function testUpdateMethod()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `email` = ?, `name` = ? where `id` = ? order by `foo` desc limit 5', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->orderBy('foo', 'desc')->limit(5)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpsertMethod()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(false)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) on duplicate key update `email` = values(`email`), `name` = values(`name`)', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(true)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) as laravel_upsert_alias on duplicate key update `email` = `laravel_upsert_alias`.`email`, `name` = `laravel_upsert_alias`.`name`', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?) on conflict (\"email\") do update set \"email\" = \"excluded\".\"email\", \"name\" = \"excluded\".\"name\"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?) on conflict (\"email\") do update set \"email\" = \"excluded\".\"email\", \"name\" = \"excluded\".\"name\"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [email] = [laravel_source].[email], [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');\n        $this->assertEquals(2, $result);\n    }\n\n    public function testUpsertMethodWithUpdateColumns()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(false)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) on duplicate key update `name` = values(`name`)', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(true)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) as laravel_upsert_alias on duplicate key update `name` = `laravel_upsert_alias`.`name`', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?) on conflict (\"email\") do update set \"name\" = \"excluded\".\"name\"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?) on conflict (\"email\") do update set \"name\" = \"excluded\".\"name\"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);\n        $this->assertEquals(2, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);\n        $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);\n        $this->assertEquals(2, $result);\n    }\n\n    public function testUpsertMethodWithEmptyUniqueByArray()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The unique columns must not be empty.');\n        $builder = $this->getPostgresBuilder();\n        $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar']], []);\n    }\n\n    public function testUpsertMethodWithEmptyUniqueByString()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The unique columns must not be empty.');\n        $builder = $this->getPostgresBuilder();\n        $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar']], '');\n    }\n\n    public function testUpdateMethodWithJoins()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" set \"email\" = ?, \"name\" = ? where \"users\".\"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ? set \"email\" = ?, \"name\" = ?', [1, 'foo', 'bar'])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithJoinsOnSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update [users] set [email] = ?, [name] = ? from [users] inner join [orders] on [users].[id] = [orders].[user_id] where [users].[id] = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update [users] set [email] = ?, [name] = ? from [users] inner join [orders] on [users].[id] = [orders].[user_id] and [users].[id] = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithJoinsOnMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update `users` inner join `orders` on `users`.`id` = `orders`.`user_id` set `email` = ?, `name` = ? where `users`.`id` = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update `users` inner join `orders` on `users`.`id` = `orders`.`user_id` and `users`.`id` = ? set `email` = ?, `name` = ?', [1, 'foo', 'bar'])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithJoinsOnSQLite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"rowid\" in (select \"users\".\"rowid\" from \"users\" where \"users\".\"id\" > ? order by \"id\" asc limit 3)', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('users.id', '>', 1)->limit(3)->oldest('id')->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"rowid\" in (select \"users\".\"rowid\" from \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" where \"users\".\"id\" = ?)', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"rowid\" in (select \"users\".\"rowid\" from \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ?)', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" as \"u\" set \"email\" = ?, \"name\" = ? where \"rowid\" in (select \"u\".\"rowid\" from \"users\" as \"u\" inner join \"orders\" as \"o\" on \"u\".\"id\" = \"o\".\"user_id\")', ['foo', 'bar'])->andReturn(1);\n        $result = $builder->from('users as u')->join('orders as o', 'u.id', '=', 'o.user_id')->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithJoinsAndAliasesOnSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update [u] set [email] = ?, [name] = ? from [users] as [u] inner join [orders] on [u].[id] = [orders].[user_id] where [u].[id] = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users as u')->join('orders', 'u.id', '=', 'orders.user_id')->where('u.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithoutJoinsOnPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->update(['users.email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->selectRaw('?', ['ignore'])->update(['users.email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\".\"users\" set \"email\" = ?, \"name\" = ? where \"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users.users')->where('id', '=', 1)->selectRaw('?', ['ignore'])->update(['users.users.email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWithJoinsOnPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" where \"users\".\"id\" = ?)', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ?)', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"orders\" on \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ? where \"name\" = ?)', ['foo', 'bar', 1, 'baz'])->andReturn(1);\n        $result = $builder->from('users')\n            ->join('orders', function ($join) {\n                $join->on('users.id', '=', 'orders.user_id')\n                    ->where('users.id', '=', 1);\n            })->where('name', 'baz')\n            ->update(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateFromMethodWithJoinsOnPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? from \"orders\" where \"users\".\"id\" = ? and \"users\".\"id\" = \"orders\".\"user_id\"', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->updateFrom(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? from \"orders\" where \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ?', ['foo', 'bar', 1])->andReturn(1);\n        $result = $builder->from('users')->join('orders', function ($join) {\n            $join->on('users.id', '=', 'orders.user_id')\n                ->where('users.id', '=', 1);\n        })->updateFrom(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ?, \"name\" = ? from \"orders\" where \"name\" = ? and \"users\".\"id\" = \"orders\".\"user_id\" and \"users\".\"id\" = ?', ['foo', 'bar', 'baz', 1])->andReturn(1);\n        $result = $builder->from('users')\n            ->join('orders', function ($join) {\n                $join->on('users.id', '=', 'orders.user_id')\n                    ->where('users.id', '=', 1);\n            })->where('name', 'baz')\n            ->updateFrom(['email' => 'foo', 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodRespectsRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = foo, \"name\" = ? where \"id\" = ?', ['bar', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->update(['email' => new Raw('foo'), 'name' => 'bar']);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateMethodWorksWithQueryAsValue()\n    {\n        $builder = $this->getBuilder();\n        $subQueryBuilder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"credits\" = (select sum(credits) from \"transactions\" where \"transactions\".\"user_id\" = \"users\".\"id\" and \"type\" = ?) where \"id\" = ?', ['foo', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->update(['credits' => $subQueryBuilder->from('transactions')->selectRaw('sum(credits)')->whereColumn('transactions.user_id', 'users.id')->where('type', 'foo')]);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getBuilder();\n        $subQueryBuilder = new EloquentBuilder($this->getBuilder());\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"credits\" = (select sum(credits) from \"transactions\" where \"transactions\".\"user_id\" = \"users\".\"id\" and \"type\" = ?) where \"id\" = ?', ['foo', 1])->andReturn(1);\n        $result = $builder->from('users')->where('id', '=', 1)->update(['credits' => $subQueryBuilder->from('transactions')->selectRaw('sum(credits)')->whereColumn('transactions.user_id', 'users.id')->where('type', 'foo')]);\n        $this->assertEquals(1, $result);\n    }\n\n    public function testUpdateOrInsertMethod()\n    {\n        $builder = m::mock(Builder::class.'[where,exists,insert]', [\n            $connection = m::mock(Connection::class),\n            new Grammar($connection),\n            m::mock(Processor::class),\n        ]);\n\n        $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());\n        $builder->shouldReceive('exists')->once()->andReturn(false);\n        $builder->shouldReceive('insert')->once()->with(['email' => 'foo', 'name' => 'bar'])->andReturn(true);\n\n        $this->assertTrue($builder->updateOrInsert(['email' => 'foo'], ['name' => 'bar']));\n\n        $builder = m::mock(Builder::class.'[where,exists,update]', [\n            $connection = m::mock(Connection::class),\n            new Grammar($connection),\n            m::mock(Processor::class),\n        ]);\n\n        $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());\n        $builder->shouldReceive('exists')->once()->andReturn(true);\n        $builder->shouldReceive('take')->andReturnSelf();\n        $builder->shouldReceive('update')->once()->with(['name' => 'bar'])->andReturn(1);\n\n        $this->assertTrue($builder->updateOrInsert(['email' => 'foo'], ['name' => 'bar']));\n    }\n\n    public function testUpdateOrInsertMethodWorksWithEmptyUpdateValues()\n    {\n        $builder = m::spy(Builder::class.'[where,exists,update]', [\n            $connection = m::mock(Connection::class),\n            new Grammar($connection),\n            m::mock(Processor::class),\n        ]);\n\n        $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());\n        $builder->shouldReceive('exists')->once()->andReturn(true);\n\n        $this->assertTrue($builder->updateOrInsert(['email' => 'foo']));\n        $builder->shouldNotHaveReceived('update');\n    }\n\n    public function testDeleteMethod()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"email\" = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->where('email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"users\".\"id\" = ?', [1])->andReturn(1);\n        $result = $builder->from('users')->delete(1);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"users\".\"id\" = ?', [1])->andReturn(1);\n        $result = $builder->from('users')->selectRaw('?', ['ignore'])->delete(1);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqliteBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"rowid\" in (select \"users\".\"rowid\" from \"users\" where \"email\" = ? order by \"id\" asc limit 1)', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from `users` where `email` = ? order by `id` asc limit 1', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from [users] where [email] = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->where('email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete top (1) from [users] where [email] = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n    }\n\n    public function testDeleteWithJoinMethod()\n    {\n        $builder = $this->getSqliteBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"rowid\" in (select \"users\".\"rowid\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" where \"users\".\"email\" = ? order by \"users\".\"id\" asc limit 1)', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('users.email', '=', 'foo')->orderBy('users.id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqliteBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" as \"u\" where \"rowid\" in (select \"u\".\"rowid\" from \"users\" as \"u\" inner join \"contacts\" as \"c\" on \"u\".\"id\" = \"c\".\"id\")', [])->andReturn(1);\n        $result = $builder->from('users as u')->join('contacts as c', 'u.id', '=', 'c.id')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete `users` from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` where `email` = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete `a` from `users` as `a` inner join `users` as `b` on `a`.`id` = `b`.`user_id` where `email` = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete `users` from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` where `users`.`id` = ?', [1])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->delete(1);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete [users] from [users] inner join [contacts] on [users].[id] = [contacts].[id] where [email] = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete [a] from [users] as [a] inner join [users] as [b] on [a].[id] = [b].[user_id] where [email] = ?', ['foo'])->andReturn(1);\n        $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete [users] from [users] inner join [contacts] on [users].[id] = [contacts].[id] where [users].[id] = ?', [1])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->delete(1);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" where \"users\".\"email\" = ?)', ['foo'])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('users.email', '=', 'foo')->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" as \"a\" where \"ctid\" in (select \"a\".\"ctid\" from \"users\" as \"a\" inner join \"users\" as \"b\" on \"a\".\"id\" = \"b\".\"user_id\" where \"email\" = ? order by \"id\" asc limit 1)', ['foo'])->andReturn(1);\n        $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\" where \"users\".\"id\" = ? order by \"id\" asc limit 1)', [1])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->orderBy('id')->limit(1)->delete(1);\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"user_id\" and \"users\".\"id\" = ? where \"name\" = ?)', [1, 'baz'])->andReturn(1);\n        $result = $builder->from('users')\n            ->join('contacts', function ($join) {\n                $join->on('users.id', '=', 'contacts.user_id')\n                    ->where('users.id', '=', 1);\n            })->where('name', 'baz')\n            ->delete();\n        $this->assertEquals(1, $result);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\" where \"ctid\" in (select \"users\".\"ctid\" from \"users\" inner join \"contacts\" on \"users\".\"id\" = \"contacts\".\"id\")', [])->andReturn(1);\n        $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->delete();\n        $this->assertEquals(1, $result);\n    }\n\n    public function testTruncateMethod()\n    {\n        $builder = $this->getBuilder();\n        $connection = $builder->getConnection();\n        $connection->shouldReceive('statement')->once()->with('truncate table \"users\"', []);\n        $builder->from('users')->truncate();\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('getSchemaBuilder->parseSchemaAndTable')->andReturn([null, 'users']);\n        $builder->from('users');\n        $this->assertEquals([\n            'delete from sqlite_sequence where name = ?' => ['users'],\n            'delete from \"users\"' => [],\n        ], $builder->getGrammar()->compileTruncate($builder));\n    }\n\n    public function testTruncateMethodWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $connection = $builder->getConnection();\n        $connection->shouldReceive('statement')->once()->with('truncate table \"prefix_users\"', []);\n        $builder->from('users')->truncate();\n\n        $builder = $this->getSQLiteBuilder(prefix: 'prefix_');\n        $builder->getConnection()->shouldReceive('getSchemaBuilder->parseSchemaAndTable')->andReturn([null, 'users']);\n        $builder->from('users');\n        $this->assertEquals([\n            'delete from sqlite_sequence where name = ?' => ['prefix_users'],\n            'delete from \"prefix_users\"' => [],\n        ], $builder->getGrammar()->compileTruncate($builder));\n    }\n\n    public function testTruncateMethodWithPrefixAndSchema()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $connection = $builder->getConnection();\n        $connection->shouldReceive('statement')->once()->with('truncate table \"my_schema\".\"prefix_users\"', []);\n        $builder->from('my_schema.users')->truncate();\n\n        $builder = $this->getSQLiteBuilder(prefix: 'prefix_');\n        $builder->getConnection()->shouldReceive('getSchemaBuilder->parseSchemaAndTable')->andReturn(['my_schema', 'users']);\n        $builder->from('my_schema.users');\n        $this->assertEquals([\n            'delete from \"my_schema\".sqlite_sequence where name = ?' => ['prefix_users'],\n            'delete from \"my_schema\".\"prefix_users\"' => [],\n        ], $builder->getGrammar()->compileTruncate($builder));\n    }\n\n    public function testPreserveAddsClosureToArray()\n    {\n        $builder = $this->getBuilder();\n        $builder->beforeQuery(function () {\n        });\n        $this->assertCount(1, $builder->beforeQueryCallbacks);\n        $this->assertInstanceOf(Closure::class, $builder->beforeQueryCallbacks[0]);\n    }\n\n    public function testApplyPreserveCleansArray()\n    {\n        $builder = $this->getBuilder();\n        $builder->beforeQuery(function () {\n        });\n        $this->assertCount(1, $builder->beforeQueryCallbacks);\n        $builder->applyBeforeQueryCallbacks();\n        $this->assertCount(0, $builder->beforeQueryCallbacks);\n    }\n\n    public function testPreservedAreAppliedByToSql()\n    {\n        $builder = $this->getBuilder();\n        $builder->beforeQuery(function ($builder) {\n            $builder->where('foo', 'bar');\n        });\n        $this->assertSame('select * where \"foo\" = ?', $builder->toSql());\n        $this->assertEquals(['bar'], $builder->getBindings());\n    }\n\n    public function testPreservedAreAppliedByInsert()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('insert')->once()->with('insert into \"users\" (\"email\") values (?)', ['foo']);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->insert(['email' => 'foo']);\n    }\n\n    public function testPreservedAreAppliedByInsertGetId()\n    {\n        $this->called = false;\n        $builder = $this->getBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" (\"email\") values (?)', ['foo'], 'id');\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->insertGetId(['email' => 'foo'], 'id');\n    }\n\n    public function testPreservedAreAppliedByInsertUsing()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into \"users\" (\"email\") select *', []);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->insertUsing(['email'], $this->getBuilder());\n    }\n\n    public function testPreservedAreAppliedByUpsert()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(false)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`) values (?) on duplicate key update `email` = values(`email`)', ['foo']);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->upsert(['email' => 'foo'], 'id');\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()\n            ->shouldReceive('getConfig')->with('use_upsert_alias')->andReturn(true)\n            ->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`) values (?) as laravel_upsert_alias on duplicate key update `email` = `laravel_upsert_alias`.`email`', ['foo']);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->upsert(['email' => 'foo'], 'id');\n    }\n\n    public function testPreservedAreAppliedByUpdate()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update \"users\" set \"email\" = ? where \"id\" = ?', ['foo', 1]);\n        $builder->from('users')->beforeQuery(function ($builder) {\n            $builder->where('id', 1);\n        });\n        $builder->update(['email' => 'foo']);\n    }\n\n    public function testPreservedAreAppliedByDelete()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('delete')->once()->with('delete from \"users\"', []);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->delete();\n    }\n\n    public function testPreservedAreAppliedByTruncate()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('statement')->once()->with('truncate table \"users\"', []);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->truncate();\n    }\n\n    public function testPreservedAreAppliedByExists()\n    {\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from \"users\") as \"exists\"', [], true);\n        $builder->beforeQuery(function ($builder) {\n            $builder->from('users');\n        });\n        $builder->exists();\n    }\n\n    public function testPostgresInsertGetId()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into \"users\" (\"email\") values (?) returning \"id\"', ['foo'], 'id')->andReturn(1);\n        $result = $builder->from('users')->insertGetId(['email' => 'foo'], 'id');\n        $this->assertEquals(1, $result);\n    }\n\n    public function testMySqlWrapping()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users');\n        $this->assertSame('select * from `users`', $builder->toSql());\n    }\n\n    public function testMySqlUpdateWrappingJson()\n    {\n        $connection = $this->createMock(Connection::class);\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        $connection->expects($this->once())\n            ->method('update')\n            ->with(\n                'update `users` set `name` = json_set(`name`, \\'$.\"first_name\"\\', ?), `name` = json_set(`name`, \\'$.\"last_name\"\\', ?) where `active` = ?',\n                ['John', 'Doe', 1]\n            );\n\n        $builder = new Builder($connection, $grammar, $processor);\n\n        $builder->from('users')->where('active', '=', 1)->update(['name->first_name' => 'John', 'name->last_name' => 'Doe']);\n    }\n\n    public function testMySqlUpdateWrappingNestedJson()\n    {\n        $connection = $this->createMock(Connection::class);\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        $connection->expects($this->once())\n            ->method('update')\n            ->with(\n                'update `users` set `meta` = json_set(`meta`, \\'$.\"name\".\"first_name\"\\', ?), `meta` = json_set(`meta`, \\'$.\"name\".\"last_name\"\\', ?) where `active` = ?',\n                ['John', 'Doe', 1]\n            );\n\n        $builder = new Builder($connection, $grammar, $processor);\n\n        $builder->from('users')->where('active', '=', 1)->update(['meta->name->first_name' => 'John', 'meta->name->last_name' => 'Doe']);\n    }\n\n    public function testMySqlUpdateWrappingJsonArray()\n    {\n        $connection = $this->createMock(Connection::class);\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        $connection->expects($this->once())\n            ->method('update')\n            ->with(\n                'update `users` set `options` = ?, `meta` = json_set(`meta`, \\'$.\"tags\"\\', cast(? as json)), `group_id` = 45, `created_at` = ? where `active` = ?',\n                [\n                    json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),\n                    json_encode(['white', 'large']),\n                    new DateTime('2019-08-06'),\n                    1,\n                ]\n            );\n\n        $builder = new Builder($connection, $grammar, $processor);\n        $builder->from('users')->where('active', 1)->update([\n            'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],\n            'meta->tags' => ['white', 'large'],\n            'group_id' => new Raw('45'),\n            'created_at' => new DateTime('2019-08-06'),\n        ]);\n    }\n\n    public function testMySqlUpdateWrappingJsonPathArrayIndex()\n    {\n        $connection = $this->createMock(Connection::class);\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        $connection->expects($this->once())\n            ->method('update')\n            ->with(\n                'update `users` set `options` = json_set(`options`, \\'$[1].\"2fa\"\\', false), `meta` = json_set(`meta`, \\'$.\"tags\"[0][2]\\', ?) where `active` = ?',\n                [\n                    'large',\n                    1,\n                ]\n            );\n\n        $builder = new Builder($connection, $grammar, $processor);\n        $builder->from('users')->where('active', 1)->update([\n            'options->[1]->2fa' => false,\n            'meta->tags[0][2]' => 'large',\n        ]);\n    }\n\n    public function testMySqlUpdateWithJsonPreparesBindingsCorrectly()\n    {\n        $connection = $this->getConnection();\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        $connection->shouldReceive('update')\n            ->once()\n            ->with(\n                'update `users` set `options` = json_set(`options`, \\'$.\"enable\"\\', false), `updated_at` = ? where `id` = ?',\n                ['2015-05-26 22:02:06', 0]\n            );\n        $builder = new Builder($connection, $grammar, $processor);\n        $builder->from('users')->where('id', '=', 0)->update(['options->enable' => false, 'updated_at' => '2015-05-26 22:02:06']);\n\n        $connection->shouldReceive('update')\n            ->once()\n            ->with(\n                'update `users` set `options` = json_set(`options`, \\'$.\"size\"\\', ?), `updated_at` = ? where `id` = ?',\n                [45, '2015-05-26 22:02:06', 0]\n            );\n        $builder = new Builder($connection, $grammar, $processor);\n        $builder->from('users')->where('id', '=', 0)->update(['options->size' => 45, 'updated_at' => '2015-05-26 22:02:06']);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `options` = json_set(`options`, \\'$.\"size\"\\', ?)', [null]);\n        $builder->from('users')->update(['options->size' => null]);\n\n        $builder = $this->getMySqlBuilder();\n        $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `options` = json_set(`options`, \\'$.\"size\"\\', 45)', []);\n        $builder->from('users')->update(['options->size' => new Raw('45')]);\n    }\n\n    public function testPostgresUpdateWrappingJson()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = jsonb_set(\"options\"::jsonb, \\'{\"name\",\"first_name\"}\\', ?)', ['\"John\"']);\n        $builder->from('users')->update(['users.options->name->first_name' => 'John']);\n\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = jsonb_set(\"options\"::jsonb, \\'{\"language\"}\\', \\'null\\')', []);\n        $builder->from('users')->update(['options->language' => new Raw(\"'null'\")]);\n    }\n\n    public function testPostgresUpdateWrappingJsonArray()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = ?, \"meta\" = jsonb_set(\"meta\"::jsonb, \\'{\"tags\"}\\', ?), \"group_id\" = 45, \"created_at\" = ?', [\n                json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),\n                json_encode(['white', 'large']),\n                new DateTime('2019-08-06'),\n            ]);\n\n        $builder->from('users')->update([\n            'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],\n            'meta->tags' => ['white', 'large'],\n            'group_id' => new Raw('45'),\n            'created_at' => new DateTime('2019-08-06'),\n        ]);\n    }\n\n    public function testPostgresUpdateWrappingJsonPathArrayIndex()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = jsonb_set(\"options\"::jsonb, \\'{1,\"2fa\"}\\', ?), \"meta\" = jsonb_set(\"meta\"::jsonb, \\'{\"tags\",0,2}\\', ?) where (\"options\"->1->\\'2fa\\')::jsonb = \\'true\\'::jsonb', [\n                'false',\n                '\"large\"',\n            ]);\n\n        $builder->from('users')->where('options->[1]->2fa', true)->update([\n            'options->[1]->2fa' => false,\n            'meta->tags[0][2]' => 'large',\n        ]);\n    }\n\n    public function testSQLiteUpdateWrappingJsonArray()\n    {\n        $builder = $this->getSQLiteBuilder();\n\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = ?, \"group_id\" = 45, \"created_at\" = ?', [\n                json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),\n                new DateTime('2019-08-06'),\n            ]);\n\n        $builder->from('users')->update([\n            'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],\n            'group_id' => new Raw('45'),\n            'created_at' => new DateTime('2019-08-06'),\n        ]);\n    }\n\n    public function testSQLiteUpdateWrappingNestedJsonArray()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"group_id\" = 45, \"created_at\" = ?, \"options\" = json_patch(ifnull(\"options\", json(\\'{}\\')), json(?))', [\n                new DateTime('2019-08-06'),\n                json_encode(['name' => 'Taylor', 'security' => ['2fa' => false, 'presets' => ['laravel', 'vue']], 'sharing' => ['twitter' => 'username']]),\n            ]);\n\n        $builder->from('users')->update([\n            'options->name' => 'Taylor',\n            'group_id' => new Raw('45'),\n            'options->security' => ['2fa' => false, 'presets' => ['laravel', 'vue']],\n            'options->sharing->twitter' => 'username',\n            'created_at' => new DateTime('2019-08-06'),\n        ]);\n    }\n\n    public function testSQLiteUpdateWrappingJsonPathArrayIndex()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->getConnection()->shouldReceive('update')\n            ->with('update \"users\" set \"options\" = json_patch(ifnull(\"options\", json(\\'{}\\')), json(?)), \"meta\" = json_patch(ifnull(\"meta\", json(\\'{}\\')), json(?)) where json_extract(\"options\", \\'$[1].\"2fa\"\\') = true', [\n                '{\"[1]\":{\"2fa\":false}}',\n                '{\"tags[0][2]\":\"large\"}',\n            ]);\n\n        $builder->from('users')->where('options->[1]->2fa', true)->update([\n            'options->[1]->2fa' => false,\n            'meta->tags[0][2]' => 'large',\n        ]);\n    }\n\n    public function testMySqlWrappingJsonWithString()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->sku', '=', 'foo-bar');\n        $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \\'$.\"sku\"\\')) = ?', $builder->toSql());\n        $this->assertCount(1, $builder->getRawBindings()['where']);\n        $this->assertSame('foo-bar', $builder->getRawBindings()['where'][0]);\n    }\n\n    public function testMySqlWrappingJsonWithInteger()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->price', '=', 1);\n        $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \\'$.\"price\"\\')) = ?', $builder->toSql());\n    }\n\n    public function testMySqlWrappingJsonWithDouble()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->price', '=', 1.5);\n        $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \\'$.\"price\"\\')) = ?', $builder->toSql());\n    }\n\n    public function testMySqlWrappingJsonWithBoolean()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->available', '=', true);\n        $this->assertSame('select * from `users` where json_extract(`items`, \\'$.\"available\"\\') = true', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where(new Raw(\"items->'$.available'\"), '=', true);\n        $this->assertSame(\"select * from `users` where items->'$.available' = true\", $builder->toSql());\n    }\n\n    public function testMySqlWrappingJsonWithBooleanAndIntegerThatLooksLikeOne()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->available', '=', true)->where('items->active', '=', false)->where('items->number_available', '=', 0);\n        $this->assertSame('select * from `users` where json_extract(`items`, \\'$.\"available\"\\') = true and json_extract(`items`, \\'$.\"active\"\\') = false and json_unquote(json_extract(`items`, \\'$.\"number_available\"\\')) = ?', $builder->toSql());\n    }\n\n    public function testJsonPathEscaping()\n    {\n        $expectedWithJsonEscaped = <<<'SQL'\nselect json_unquote(json_extract(`json`, '$.\"''))#\"'))\nSQL;\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select(\"json->'))#\");\n        $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select(\"json->\\'))#\");\n        $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select(\"json->\\\\'))#\");\n        $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select(\"json->\\\\\\'))#\");\n        $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());\n    }\n\n    public function testMySqlWrappingJson()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereRaw('items->\\'$.\"price\"\\' = 1');\n        $this->assertSame('select * from `users` where items->\\'$.\"price\"\\' = 1', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');\n        $this->assertSame('select json_unquote(json_extract(`items`, \\'$.\"price\"\\')) from `users` where json_unquote(json_extract(`users`.`items`, \\'$.\"price\"\\')) = ? order by json_unquote(json_extract(`items`, \\'$.\"price\"\\')) asc', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);\n        $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \\'$.\"price\".\"in_usd\"\\')) = ?', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);\n        $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \\'$.\"price\".\"in_usd\"\\')) = ? and json_unquote(json_extract(`items`, \\'$.\"age\"\\')) = ?', $builder->toSql());\n    }\n\n    public function testPostgresWrappingJson()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');\n        $this->assertSame('select \"items\"->>\\'price\\' from \"users\" where \"users\".\"items\"->>\\'price\\' = ? order by \"items\"->>\\'price\\' asc', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);\n        $this->assertSame('select * from \"users\" where \"items\"->\\'price\\'->>\\'in_usd\\' = ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);\n        $this->assertSame('select * from \"users\" where \"items\"->\\'price\\'->>\\'in_usd\\' = ? and \"items\"->>\\'age\\' = ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('items->prices->0', '=', 1)->where('items->age', '=', 2);\n        $this->assertSame('select * from \"users\" where \"items\"->\\'prices\\'->>0 = ? and \"items\"->>\\'age\\' = ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('items->available', '=', true);\n        $this->assertSame('select * from \"users\" where (\"items\"->\\'available\\')::jsonb = \\'true\\'::jsonb', $builder->toSql());\n    }\n\n    public function testSqlServerWrappingJson()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');\n        $this->assertSame('select json_value([items], \\'$.\"price\"\\') from [users] where json_value([users].[items], \\'$.\"price\"\\') = ? order by json_value([items], \\'$.\"price\"\\') asc', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);\n        $this->assertSame('select * from [users] where json_value([items], \\'$.\"price\".\"in_usd\"\\') = ?', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);\n        $this->assertSame('select * from [users] where json_value([items], \\'$.\"price\".\"in_usd\"\\') = ? and json_value([items], \\'$.\"age\"\\') = ?', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('items->available', '=', true);\n        $this->assertSame('select * from [users] where json_value([items], \\'$.\"available\"\\') = \\'true\\'', $builder->toSql());\n    }\n\n    public function testSqliteWrappingJson()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');\n        $this->assertSame('select json_extract(\"items\", \\'$.\"price\"\\') from \"users\" where json_extract(\"users\".\"items\", \\'$.\"price\"\\') = ? order by json_extract(\"items\", \\'$.\"price\"\\') asc', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);\n        $this->assertSame('select * from \"users\" where json_extract(\"items\", \\'$.\"price\".\"in_usd\"\\') = ?', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);\n        $this->assertSame('select * from \"users\" where json_extract(\"items\", \\'$.\"price\".\"in_usd\"\\') = ? and json_extract(\"items\", \\'$.\"age\"\\') = ?', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('items->available', '=', true);\n        $this->assertSame('select * from \"users\" where json_extract(\"items\", \\'$.\"available\"\\') = true', $builder->toSql());\n    }\n\n    public function testSQLiteOrderBy()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->orderBy('email', 'desc');\n        $this->assertSame('select * from \"users\" order by \"email\" desc', $builder->toSql());\n    }\n\n    public function testSqlServerLimitsAndOffsets()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->limit(10);\n        $this->assertSame('select top 10 * from [users]', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->offset(10)->orderBy('email', 'desc');\n        $this->assertSame('select * from [users] order by [email] desc offset 10 rows', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->offset(10)->limit(10);\n        $this->assertSame('select * from [users] order by (SELECT 0) offset 10 rows fetch next 10 rows only', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->offset(11)->limit(10)->orderBy('email', 'desc');\n        $this->assertSame('select * from [users] order by [email] desc offset 11 rows fetch next 10 rows only', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $subQuery = function ($query) {\n            return $query->select('created_at')->from('logins')->where('users.name', 'nameBinding')->whereColumn('user_id', 'users.id')->limit(1);\n        };\n        $builder->select('*')->from('users')->where('email', 'emailBinding')->orderBy($subQuery)->offset(10)->limit(10);\n        $this->assertSame('select * from [users] where [email] = ? order by (select top 1 [created_at] from [logins] where [users].[name] = ? and [user_id] = [users].[id]) asc offset 10 rows fetch next 10 rows only', $builder->toSql());\n        $this->assertEquals(['emailBinding', 'nameBinding'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->limit('foo');\n        $this->assertSame('select * from [users]', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->limit('foo')->offset('bar');\n        $this->assertSame('select * from [users]', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->offset('bar');\n        $this->assertSame('select * from [users]', $builder->toSql());\n    }\n\n    public function testMySqlSoundsLikeOperator()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('name', 'sounds like', 'John Doe');\n        $this->assertSame('select * from `users` where `name` sounds like ?', $builder->toSql());\n        $this->assertEquals(['John Doe'], $builder->getBindings());\n    }\n\n    public function testBitwiseOperators()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('bar', '&', 1);\n        $this->assertSame('select * from \"users\" where \"bar\" & ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('bar', '#', 1);\n        $this->assertSame('select * from \"users\" where (\"bar\" # ?)::bool', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('range', '>>', '[2022-01-08 00:00:00,2022-01-09 00:00:00)');\n        $this->assertSame('select * from \"users\" where (\"range\" >> ?)::bool', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('bar', '&', 1);\n        $this->assertSame('select * from [users] where ([bar] & ?) != 0', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->having('bar', '&', 1);\n        $this->assertSame('select * from \"users\" having \"bar\" & ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->having('bar', '#', 1);\n        $this->assertSame('select * from \"users\" having (\"bar\" # ?)::bool', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->having('range', '>>', '[2022-01-08 00:00:00,2022-01-09 00:00:00)');\n        $this->assertSame('select * from \"users\" having (\"range\" >> ?)::bool', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->having('bar', '&', 1);\n        $this->assertSame('select * from [users] having ([bar] & ?) != 0', $builder->toSql());\n    }\n\n    public function testMergeWheresCanMergeWheresAndBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->wheres = ['foo'];\n        $builder->mergeWheres(['wheres'], [12 => 'foo', 13 => 'bar']);\n        $this->assertEquals(['foo', 'wheres'], $builder->wheres);\n        $this->assertEquals(['foo', 'bar'], $builder->getBindings());\n    }\n\n    public function testPrepareValueAndOperator()\n    {\n        $builder = $this->getBuilder();\n        [$value, $operator] = $builder->prepareValueAndOperator('>', '20');\n        $this->assertSame('>', $value);\n        $this->assertSame('20', $operator);\n\n        $builder = $this->getBuilder();\n        [$value, $operator] = $builder->prepareValueAndOperator('>', '20', true);\n        $this->assertSame('20', $value);\n        $this->assertSame('=', $operator);\n    }\n\n    public function testPrepareValueAndOperatorExpectException()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Illegal operator and value combination.');\n\n        $builder = $this->getBuilder();\n        $builder->prepareValueAndOperator(null, 'like');\n    }\n\n    public function testProvidingNullWithOperatorsBuildsCorrectly()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '=', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '!=', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '<>', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is not null', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('foo', '<=>', null);\n        $this->assertSame('select * from \"users\" where \"foo\" is null', $builder->toSql());\n    }\n\n    public function testDynamicWhere()\n    {\n        $method = 'whereFooBarAndBazOrQux';\n        $parameters = ['corge', 'waldo', 'fred'];\n        $builder = m::mock(Builder::class)->makePartial();\n\n        $builder->shouldReceive('where')->with('foo_bar', '=', $parameters[0], 'and')->once()->andReturnSelf();\n        $builder->shouldReceive('where')->with('baz', '=', $parameters[1], 'and')->once()->andReturnSelf();\n        $builder->shouldReceive('where')->with('qux', '=', $parameters[2], 'or')->once()->andReturnSelf();\n\n        $this->assertEquals($builder, $builder->dynamicWhere($method, $parameters));\n    }\n\n    public function testDynamicWhereIsNotGreedy()\n    {\n        $method = 'whereIosVersionAndAndroidVersionOrOrientation';\n        $parameters = ['6.1', '4.2', 'Vertical'];\n        $builder = m::mock(Builder::class)->makePartial();\n\n        $builder->shouldReceive('where')->with('ios_version', '=', '6.1', 'and')->once()->andReturnSelf();\n        $builder->shouldReceive('where')->with('android_version', '=', '4.2', 'and')->once()->andReturnSelf();\n        $builder->shouldReceive('where')->with('orientation', '=', 'Vertical', 'or')->once()->andReturnSelf();\n\n        $builder->dynamicWhere($method, $parameters);\n    }\n\n    public function testCallTriggersDynamicWhere()\n    {\n        $builder = $this->getBuilder();\n\n        $this->assertEquals($builder, $builder->whereFooAndBar('baz', 'qux'));\n        $this->assertCount(2, $builder->wheres);\n    }\n\n    public function testBuilderThrowsExpectedExceptionWithUndefinedMethod()\n    {\n        $this->expectException(BadMethodCallException::class);\n\n        $builder = $this->getBuilder();\n        $builder->getConnection()->shouldReceive('select');\n        $builder->getProcessor()->shouldReceive('processSelect')->andReturn([]);\n\n        $builder->noValidMethodHere();\n    }\n\n    public function testMySqlLock()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();\n        $this->assertSame('select * from `foo` where `bar` = ? for update', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);\n        $this->assertSame('select * from `foo` where `bar` = ? lock in share mode', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('lock in share mode');\n        $this->assertSame('select * from `foo` where `bar` = ? lock in share mode', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testPostgresLock()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();\n        $this->assertSame('select * from \"foo\" where \"bar\" = ? for update', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);\n        $this->assertSame('select * from \"foo\" where \"bar\" = ? for share', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('for key share');\n        $this->assertSame('select * from \"foo\" where \"bar\" = ? for key share', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testSqlServerLock()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();\n        $this->assertSame('select * from [foo] with(rowlock,updlock,holdlock) where [bar] = ?', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);\n        $this->assertSame('select * from [foo] with(rowlock,holdlock) where [bar] = ?', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('with(holdlock)');\n        $this->assertSame('select * from [foo] with(holdlock) where [bar] = ?', $builder->toSql());\n        $this->assertEquals(['baz'], $builder->getBindings());\n    }\n\n    public function testSelectWithLockUsesWritePdo()\n    {\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->getConnection()->shouldReceive('select')->once()\n            ->with(m::any(), m::any(), false, []);\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock()->get();\n\n        $builder = $this->getMySqlBuilderWithProcessor();\n        $builder->getConnection()->shouldReceive('select')->once()\n            ->with(m::any(), m::any(), false, []);\n        $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false)->get();\n    }\n\n    public function testBindingOrder()\n    {\n        $expectedSql = 'select * from \"users\" inner join \"othertable\" on \"bar\" = ? where \"registered\" = ? group by \"city\" having \"population\" > ? order by match (\"foo\") against(?)';\n        $expectedBindings = ['foo', 1, 3, 'bar'];\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->join('othertable', function ($join) {\n            $join->where('bar', '=', 'foo');\n        })->where('registered', 1)->groupBy('city')->having('population', '>', 3)->orderByRaw('match (\"foo\") against(?)', ['bar']);\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals($expectedBindings, $builder->getBindings());\n\n        // order of statements reversed\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->orderByRaw('match (\"foo\") against(?)', ['bar'])->having('population', '>', 3)->groupBy('city')->where('registered', 1)->join('othertable', function ($join) {\n            $join->where('bar', '=', 'foo');\n        });\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals($expectedBindings, $builder->getBindings());\n    }\n\n    public function testAddBindingWithArrayMergesBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->addBinding(['foo', 'bar']);\n        $builder->addBinding(['baz']);\n        $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());\n    }\n\n    public function testAddBindingWithArrayMergesBindingsInCorrectOrder()\n    {\n        $builder = $this->getBuilder();\n        $builder->addBinding(['bar', 'baz'], 'having');\n        $builder->addBinding(['foo'], 'where');\n        $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());\n    }\n\n    public function testAddBindingWithEnum()\n    {\n        $builder = $this->getBuilder();\n        $builder->addBinding(IntegerStatus::done);\n        $builder->addBinding([NonBackedStatus::done]);\n        $this->assertEquals([2, 'done'], $builder->getBindings());\n    }\n\n    public function testMergeBuilders()\n    {\n        $builder = $this->getBuilder();\n        $builder->addBinding(['foo', 'bar']);\n        $otherBuilder = $this->getBuilder();\n        $otherBuilder->addBinding(['baz']);\n        $builder->mergeBindings($otherBuilder);\n        $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());\n    }\n\n    public function testMergeBuildersBindingOrder()\n    {\n        $builder = $this->getBuilder();\n        $builder->addBinding('foo', 'where');\n        $builder->addBinding('baz', 'having');\n        $otherBuilder = $this->getBuilder();\n        $otherBuilder->addBinding('bar', 'where');\n        $builder->mergeBindings($otherBuilder);\n        $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());\n    }\n\n    public function testSubSelect()\n    {\n        $expectedSql = 'select \"foo\", \"bar\", (select \"baz\" from \"two\" where \"subkey\" = ?) as \"sub\" from \"one\" where \"key\" = ?';\n        $expectedBindings = ['subval', 'val'];\n\n        $builder = $this->getPostgresBuilder();\n        $builder->from('one')->select(['foo', 'bar'])->where('key', '=', 'val');\n        $builder->selectSub(function ($query) {\n            $query->from('two')->select('baz')->where('subkey', '=', 'subval');\n        }, 'sub');\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals($expectedBindings, $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->from('one')->select(['foo', 'bar'])->where('key', '=', 'val');\n        $subBuilder = $this->getPostgresBuilder();\n        $subBuilder->from('two')->select('baz')->where('subkey', '=', 'subval');\n        $builder->selectSub($subBuilder, 'sub');\n        $this->assertEquals($expectedSql, $builder->toSql());\n        $this->assertEquals($expectedBindings, $builder->getBindings());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getPostgresBuilder();\n        $builder->selectSub(['foo'], 'sub');\n    }\n\n    public function testSubSelectResetBindings()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->from('one')->selectSub(function ($query) {\n            $query->from('two')->select('baz')->where('subkey', '=', 'subval');\n        }, 'sub');\n\n        $this->assertSame('select (select \"baz\" from \"two\" where \"subkey\" = ?) as \"sub\" from \"one\"', $builder->toSql());\n        $this->assertEquals(['subval'], $builder->getBindings());\n\n        $builder->select('*');\n\n        $this->assertSame('select * from \"one\"', $builder->toSql());\n        $this->assertEquals([], $builder->getBindings());\n    }\n\n    public function testSelectExpression()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('one')\n            ->selectExpression(new Raw('1 + 1'), 'expr')\n            ->selectExpression('2 + 2', 'expr2');\n\n        $this->assertSame('select (1 + 1) as \"expr\", (2 + 2) as \"expr2\" from \"one\"', $builder->toSql());\n    }\n\n    public function testSelect()\n    {\n        $builder = $this->getBuilder();\n        $builder->from('one')->select([\n            'two',\n            'three' => 'threee as threeee',\n            'four' => $this->getBuilder()->from('tbl')->select('col'),\n            'five' => new Raw('1 + 1'),\n        ]);\n\n        $this->assertSame('select \"two\", \"threee\" as \"threeee\", (select \"col\" from \"tbl\") as \"four\", 1 + 1 from \"one\"', $builder->toSql());\n    }\n\n    public function testSqlServerWhereDate()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-09-23');\n        $this->assertSame('select * from [users] where cast([created_at] as date) = ?', $builder->toSql());\n        $this->assertEquals([0 => '2015-09-23'], $builder->getBindings());\n    }\n\n    public function testUppercaseLeadingBooleansAreRemoved()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'AND');\n        $this->assertSame('select * from \"users\" where \"name\" = ?', $builder->toSql());\n    }\n\n    public function testLowercaseLeadingBooleansAreRemoved()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'and');\n        $this->assertSame('select * from \"users\" where \"name\" = ?', $builder->toSql());\n    }\n\n    public function testCaseInsensitiveLeadingBooleansAreRemoved()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'And');\n        $this->assertSame('select * from \"users\" where \"name\" = ?', $builder->toSql());\n    }\n\n    public function testTableValuedFunctionAsTableInSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users()');\n        $this->assertSame('select * from [users]()', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users(1,2)');\n        $this->assertSame('select * from [users](1,2)', $builder->toSql());\n    }\n\n    public function testChunkWithLastChunkComplete()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect(['foo1', 'foo2']);\n        $chunk2 = collect(['foo3', 'foo4']);\n        $chunk3 = collect([]);\n\n        $builder->shouldReceive('getOffset')->once()->andReturnNull();\n        $builder->shouldReceive('getLimit')->once()->andReturnNull();\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(4)->andReturnSelf();\n        $builder->shouldReceive('limit')->times(3)->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        });\n    }\n\n    public function testChunkWithLastChunkPartial()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect(['foo1', 'foo2']);\n        $chunk2 = collect(['foo3']);\n\n        $builder->shouldReceive('getOffset')->once()->andReturnNull();\n        $builder->shouldReceive('getLimit')->once()->andReturnNull();\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('offset')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('limit')->twice()->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        });\n    }\n\n    public function testChunkCanBeStoppedByReturningFalse()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect(['foo1', 'foo2']);\n        $chunk2 = collect(['foo3']);\n        $builder->shouldReceive('getOffset')->once()->andReturnNull();\n        $builder->shouldReceive('getLimit')->once()->andReturnNull();\n        $builder->shouldReceive('offset')->once()->with(0)->andReturnSelf();\n        $builder->shouldReceive('limit')->once()->with(2)->andReturnSelf();\n        $builder->shouldReceive('get')->times(1)->andReturn($chunk1);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);\n\n        $builder->chunk(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n\n            return false;\n        });\n    }\n\n    public function testChunkWithCountZero()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('getOffset')->once()->andReturnNull();\n        $builder->shouldReceive('getLimit')->once()->andReturnNull();\n        $builder->shouldReceive('offset')->never();\n        $builder->shouldReceive('limit')->never();\n        $builder->shouldReceive('get')->never();\n\n        $builder->chunk(0, function () {\n            $this->fail('Should never be called.');\n        });\n    }\n\n    public function testChunkByIdOnArrays()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect([['someIdField' => 1], ['someIdField' => 2]]);\n        $chunk2 = collect([['someIdField' => 10], ['someIdField' => 11]]);\n        $chunk3 = collect([]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 11, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithLastChunkComplete()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = collect([(object) ['someIdField' => 10], (object) ['someIdField' => 11]]);\n        $chunk3 = collect([]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 11, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithLastChunkPartial()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);\n        $chunk2 = collect([(object) ['someIdField' => 10]]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithCountZero()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $builder->shouldReceive('forPageAfterId')->never();\n        $builder->shouldReceive('get')->never();\n\n        $builder->chunkById(0, function () {\n            $this->fail('Should never be called.');\n        }, 'someIdField');\n    }\n\n    public function testChunkPaginatesUsingIdWithAlias()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];\n\n        $chunk1 = collect([(object) ['table_id' => 1], (object) ['table_id' => 10]]);\n        $chunk2 = collect([]);\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'table.id')->andReturnSelf();\n        $builder->shouldReceive('forPageAfterId')->once()->with(2, 10, 'table.id')->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);\n\n        $builder->chunkById(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'table.id', 'table_id');\n    }\n\n    public function testChunkPaginatesUsingIdDesc()\n    {\n        $builder = $this->getMockQueryBuilder();\n        $builder->orders[] = ['column' => 'foobar', 'direction' => 'desc'];\n\n        $chunk1 = collect([(object) ['someIdField' => 10], (object) ['someIdField' => 1]]);\n        $chunk2 = collect([]);\n        $builder->shouldReceive('forPageBeforeId')->once()->with(2, 0, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('forPageBeforeId')->once()->with(2, 1, 'someIdField')->andReturnSelf();\n        $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);\n\n        $callbackAssertor = m::mock(stdClass::class);\n        $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);\n        $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);\n\n        $builder->chunkByIdDesc(2, function ($results) use ($callbackAssertor) {\n            $callbackAssertor->doSomething($results);\n        }, 'someIdField');\n    }\n\n    public function testPaginate()\n    {\n        $perPage = 16;\n        $columns = ['test'];\n        $pageName = 'page-name';\n        $page = 1;\n        $builder = $this->getMockQueryBuilder();\n        $path = 'http://foo.bar?page=3';\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);\n        $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn($results);\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->paginate($perPage, $columns, $pageName, $page);\n\n        $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [\n            'path' => $path,\n            'pageName' => $pageName,\n        ]), $result);\n    }\n\n    public function testPaginateWithDefaultArguments()\n    {\n        $perPage = 15;\n        $pageName = 'page';\n        $page = 1;\n        $builder = $this->getMockQueryBuilder();\n        $path = 'http://foo.bar?page=3';\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);\n        $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn($results);\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->paginate();\n\n        $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [\n            'path' => $path,\n            'pageName' => $pageName,\n        ]), $result);\n    }\n\n    public function testPaginateWhenNoResults()\n    {\n        $perPage = 15;\n        $pageName = 'page';\n        $page = 1;\n        $builder = $this->getMockQueryBuilder();\n        $path = 'http://foo.bar?page=3';\n\n        $results = [];\n\n        $builder->shouldReceive('getCountForPagination')->once()->andReturn(0);\n        $builder->shouldNotReceive('forPage');\n        $builder->shouldNotReceive('get');\n\n        Paginator::currentPageResolver(function () {\n            return 1;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->paginate();\n\n        $this->assertEquals(new LengthAwarePaginator($results, 0, $perPage, $page, [\n            'path' => $path,\n            'pageName' => $pageName,\n        ]), $result);\n    }\n\n    public function testPaginateWithSpecificColumns()\n    {\n        $perPage = 16;\n        $columns = ['id', 'name'];\n        $pageName = 'page-name';\n        $page = 1;\n        $builder = $this->getMockQueryBuilder();\n        $path = 'http://foo.bar?page=3';\n\n        $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]);\n\n        $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);\n        $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn($results);\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->paginate($perPage, $columns, $pageName, $page);\n\n        $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [\n            'path' => $path,\n            'pageName' => $pageName,\n        ]), $result);\n    }\n\n    public function testPaginateWithTotalOverride()\n    {\n        $perPage = 16;\n        $columns = ['id', 'name'];\n        $pageName = 'page-name';\n        $page = 1;\n        $builder = $this->getMockQueryBuilder();\n        $path = 'http://foo.bar?page=3';\n\n        $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]);\n\n        $builder->shouldReceive('getCountForPagination')->never();\n        $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();\n        $builder->shouldReceive('get')->once()->andReturn($results);\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->paginate($perPage, $columns, $pageName, $page, 10);\n\n        $this->assertEquals(10, $result->total());\n    }\n\n    public function testCursorPaginate()\n    {\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['test' => 'bar']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->orderBy('test');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select * from \"foobar\" where (\"test\" > ?) order by \"test\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals(['bar'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateMultipleOrderColumns()\n    {\n        $perPage = 16;\n        $columns = ['test', 'another'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['test' => 'bar', 'another' => 'foo']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->orderBy('test')->orderBy('another');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo', 'another' => 1], ['test' => 'bar', 'another' => 2]]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select * from \"foobar\" where (\"test\" > ? or (\"test\" = ? and (\"another\" > ?))) order by \"test\" asc, \"another\" asc limit 17',\n                $builder->toSql()\n            );\n            $this->assertEquals(['bar', 'bar', 'foo'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test', 'another'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithDefaultArguments()\n    {\n        $perPage = 15;\n        $cursorName = 'cursor';\n        $cursor = new Cursor(['test' => 'bar']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->orderBy('test');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select * from \"foobar\" where (\"test\" > ?) order by \"test\" asc limit 16',\n                $builder->toSql());\n            $this->assertEquals(['bar'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        CursorPaginator::currentCursorResolver(function () use ($cursor) {\n            return $cursor;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate();\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWhenNoResults()\n    {\n        $perPage = 15;\n        $cursorName = 'cursor';\n        $builder = $this->getMockQueryBuilder()->orderBy('test');\n        $path = 'http://foo.bar?cursor=3';\n\n        $results = [];\n\n        $builder->shouldReceive('get')->once()->andReturn($results);\n\n        CursorPaginator::currentCursorResolver(function () {\n            return null;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate();\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, null, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithSpecificColumns()\n    {\n        $perPage = 16;\n        $columns = ['id', 'name'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['id' => 2]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->orderBy('id');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor=3';\n\n        $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select * from \"foobar\" where (\"id\" > ?) order by \"id\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([2], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['id'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithMixedOrders()\n    {\n        $perPage = 16;\n        $columns = ['foo', 'bar', 'baz'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['foo' => 1, 'bar' => 2, 'baz' => 3]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->orderBy('foo')->orderByDesc('bar')->orderBy('baz');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['foo' => 1, 'bar' => 2, 'baz' => 4], ['foo' => 1, 'bar' => 1, 'baz' => 1]]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select * from \"foobar\" where (\"foo\" > ? or (\"foo\" = ? and (\"bar\" < ? or (\"bar\" = ? and (\"baz\" > ?))))) order by \"foo\" asc, \"bar\" desc, \"baz\" asc limit 17',\n                $builder->toSql()\n            );\n            $this->assertEquals([1, 1, 2, 2, 3], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['foo', 'bar', 'baz'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithDynamicColumnInSelectRaw()\n    {\n        $perPage = 15;\n        $cursorName = 'cursor';\n        $cursor = new Cursor(['test' => 'bar']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->select('*')->selectRaw('(CONCAT(firstname, \\' \\', lastname)) as test')->orderBy('test');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select *, (CONCAT(firstname, \\' \\', lastname)) as test from \"foobar\" where ((CONCAT(firstname, \\' \\', lastname)) > ?) order by \"test\" asc limit 16',\n                $builder->toSql());\n            $this->assertEquals(['bar'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        CursorPaginator::currentCursorResolver(function () use ($cursor) {\n            return $cursor;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate();\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithDynamicColumnWithCastInSelectRaw()\n    {\n        $perPage = 15;\n        $cursorName = 'cursor';\n        $cursor = new Cursor(['test' => 'bar']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->select('*')->selectRaw('(CAST(CONCAT(firstname, \\' \\', lastname) as VARCHAR)) as test')->orderBy('test');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select *, (CAST(CONCAT(firstname, \\' \\', lastname) as VARCHAR)) as test from \"foobar\" where ((CAST(CONCAT(firstname, \\' \\', lastname) as VARCHAR)) > ?) order by \"test\" asc limit 16',\n                $builder->toSql());\n            $this->assertEquals(['bar'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        CursorPaginator::currentCursorResolver(function () use ($cursor) {\n            return $cursor;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate();\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithDynamicColumnInSelectSub()\n    {\n        $perPage = 15;\n        $cursorName = 'cursor';\n        $cursor = new Cursor(['test' => 'bar']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->from('foobar')->select('*')->selectSub('CONCAT(firstname, \\' \\', lastname)', 'test')->orderBy('test');\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([['test' => 'foo'], ['test' => 'bar']]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {\n            $this->assertEquals(\n                'select *, (CONCAT(firstname, \\' \\', lastname)) as \"test\" from \"foobar\" where ((CONCAT(firstname, \\' \\', lastname)) > ?) order by \"test\" asc limit 16',\n                $builder->toSql());\n            $this->assertEquals(['bar'], $builder->bindings['where']);\n\n            return $results;\n        });\n\n        CursorPaginator::currentCursorResolver(function () use ($cursor) {\n            return $cursor;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate();\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['test'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionWheres()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at')->selectRaw(\"'video' as type\")->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'news' as type\")->from('news'));\n        $builder->orderBy('created_at');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where (\"start_time\" > ?)) union (select \"id\", \"created_at\", \\'news\\' as type from \"news\" where (\"created_at\" > ?)) order by \"created_at\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([$ts], $builder->bindings['where']);\n            $this->assertEquals([$ts], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithMultipleUnionsAndMultipleWheres()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at')->selectRaw(\"'video' as type\")->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'news' as type\")->from('news')->where('extra', 'first'));\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'podcast' as type\")->from('podcasts')->where('extra', 'second'));\n        $builder->orderBy('created_at');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news'],\n            ['id' => 3, 'created_at' => Carbon::now(), 'type' => 'podcasts'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where (\"start_time\" > ?)) union (select \"id\", \"created_at\", \\'news\\' as type from \"news\" where \"extra\" = ? and (\"created_at\" > ?)) union (select \"id\", \"created_at\", \\'podcast\\' as type from \"podcasts\" where \"extra\" = ? and (\"created_at\" > ?)) order by \"created_at\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([$ts], $builder->bindings['where']);\n            $this->assertEquals(['first', $ts, 'second', $ts], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionMultipleWheresMultipleOrders()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['id', 'created_at', 'type'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['id' => 1, 'created_at' => $ts, 'type' => 'news']);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at', 'type')->from('videos')->where('extra', 'first');\n        $builder->union($this->getBuilder()->select('id', 'created_at', 'type')->from('news')->where('extra', 'second'));\n        $builder->union($this->getBuilder()->select('id', 'created_at', 'type')->from('podcasts')->where('extra', 'third'));\n        $builder->orderBy('id')->orderByDesc('created_at')->orderBy('type');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now()->addDay(), 'type' => 'video'],\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'news'],\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'podcast'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'podcast'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \"type\" from \"videos\" where \"extra\" = ? and (\"id\" > ? or (\"id\" = ? and (\"start_time\" < ? or (\"start_time\" = ? and (\"type\" > ?)))))) union (select \"id\", \"created_at\", \"type\" from \"news\" where \"extra\" = ? and (\"id\" > ? or (\"id\" = ? and (\"start_time\" < ? or (\"start_time\" = ? and (\"type\" > ?)))))) union (select \"id\", \"created_at\", \"type\" from \"podcasts\" where \"extra\" = ? and (\"id\" > ? or (\"id\" = ? and (\"start_time\" < ? or (\"start_time\" = ? and (\"type\" > ?)))))) order by \"id\" asc, \"created_at\" desc, \"type\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals(['first', 1, 1, $ts, $ts, 'news'], $builder->bindings['where']);\n            $this->assertEquals(['second', 1, 1, $ts, $ts, 'news', 'third', 1, 1, $ts, $ts, 'news'], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['id', 'created_at', 'type'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionWheresWithRawOrderExpression()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'is_published', 'start_time as created_at')->selectRaw(\"'video' as type\")->where('is_published', true)->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'is_published', 'created_at')->selectRaw(\"'news' as type\")->where('is_published', true)->from('news'));\n        $builder->orderByRaw('case when (id = 3 and type=\"news\" then 0 else 1 end)')->orderBy('created_at');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video', 'is_published' => true],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news', 'is_published' => true],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"is_published\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where \"is_published\" = ? and (\"start_time\" > ?)) union (select \"id\", \"is_published\", \"created_at\", \\'news\\' as type from \"news\" where \"is_published\" = ? and (\"created_at\" > ?)) order by case when (id = 3 and type=\"news\" then 0 else 1 end), \"created_at\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([true, $ts], $builder->bindings['where']);\n            $this->assertEquals([true, $ts], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionWheresReverseOrder()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts], false);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at')->selectRaw(\"'video' as type\")->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'news' as type\")->from('news'));\n        $builder->orderBy('created_at');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where (\"start_time\" < ?)) union (select \"id\", \"created_at\", \\'news\\' as type from \"news\" where (\"created_at\" < ?)) order by \"created_at\" desc limit 17',\n                $builder->toSql());\n            $this->assertEquals([$ts], $builder->bindings['where']);\n            $this->assertEquals([$ts], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionWheresMultipleOrders()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts, 'id' => 1]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at')->selectRaw(\"'video' as type\")->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'news' as type\")->from('news'));\n        $builder->orderByDesc('created_at')->orderBy('id');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where (\"start_time\" < ? or (\"start_time\" = ? and (\"id\" > ?)))) union (select \"id\", \"created_at\", \\'news\\' as type from \"news\" where (\"created_at\" < ? or (\"created_at\" = ? and (\"id\" > ?)))) order by \"created_at\" desc, \"id\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([$ts, $ts, 1], $builder->bindings['where']);\n            $this->assertEquals([$ts, $ts, 1], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at', 'id'],\n        ]), $result);\n    }\n\n    public function testCursorPaginateWithUnionWheresAndAliassedOrderColumns()\n    {\n        $ts = Carbon::now()->toDateTimeString();\n\n        $perPage = 16;\n        $columns = ['test'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['created_at' => $ts]);\n        $builder = $this->getMockQueryBuilder();\n        $builder->select('id', 'start_time as created_at')->selectRaw(\"'video' as type\")->from('videos');\n        $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw(\"'news' as type\")->from('news'));\n        $builder->union($this->getBuilder()->select('id', 'init_at as created_at')->selectRaw(\"'podcast' as type\")->from('podcasts'));\n        $builder->orderBy('created_at');\n\n        $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {\n            return new Builder($builder->connection, $builder->grammar, $builder->processor);\n        });\n\n        $path = 'http://foo.bar?cursor='.$cursor->encode();\n\n        $results = collect([\n            ['id' => 1, 'created_at' => Carbon::now(), 'type' => 'video'],\n            ['id' => 2, 'created_at' => Carbon::now(), 'type' => 'news'],\n            ['id' => 3, 'created_at' => Carbon::now(), 'type' => 'podcast'],\n        ]);\n\n        $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {\n            $this->assertEquals(\n                '(select \"id\", \"start_time\" as \"created_at\", \\'video\\' as type from \"videos\" where (\"start_time\" > ?)) union (select \"id\", \"created_at\", \\'news\\' as type from \"news\" where (\"created_at\" > ?)) union (select \"id\", \"init_at\" as \"created_at\", \\'podcast\\' as type from \"podcasts\" where (\"init_at\" > ?)) order by \"created_at\" asc limit 17',\n                $builder->toSql());\n            $this->assertEquals([$ts], $builder->bindings['where']);\n            $this->assertEquals([$ts, $ts], $builder->bindings['union']);\n\n            return $results;\n        });\n\n        Paginator::currentPathResolver(function () use ($path) {\n            return $path;\n        });\n\n        $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);\n\n        $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [\n            'path' => $path,\n            'cursorName' => $cursorName,\n            'parameters' => ['created_at'],\n        ]), $result);\n    }\n\n    public function testWhereExpression()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where(\n            new class() implements ConditionExpression\n            {\n                public function getValue(\\Illuminate\\Database\\Grammar $grammar)\n                {\n                    return '1 = 1';\n                }\n            }\n        );\n        $this->assertSame('select * from \"orders\" where 1 = 1', $builder->toSql());\n        $this->assertSame([], $builder->getBindings());\n    }\n\n    public function testWhereRowValues()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereRowValues(['last_update', 'order_number'], '<', [1, 2]);\n        $this->assertSame('select * from \"orders\" where (\"last_update\", \"order_number\") < (?, ?)', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->where('company_id', 1)->orWhereRowValues(['last_update', 'order_number'], '<', [1, 2]);\n        $this->assertSame('select * from \"orders\" where \"company_id\" = ? or (\"last_update\", \"order_number\") < (?, ?)', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereRowValues(['last_update', 'order_number'], '<', [1, new Raw('2')]);\n        $this->assertSame('select * from \"orders\" where (\"last_update\", \"order_number\") < (?, 2)', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereRowValuesArityMismatch()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The number of columns must match the number of values');\n\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('orders')->whereRowValues(['last_update'], '<', [1, 2]);\n    }\n\n    public function testWhereJsonContainsMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('options', ['en']);\n        $this->assertSame('select * from `users` where json_contains(`options`, ?)', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('users.options->languages', ['en']);\n        $this->assertSame('select * from `users` where json_contains(`users`.`options`, ?, \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw(\"'[\\\"en\\\"]'\"));\n        $this->assertSame('select * from `users` where `id` = ? or json_contains(`options`, \\'[\"en\"]\\', \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonOverlapsMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonOverlaps('options', ['en', 'fr']);\n        $this->assertSame('select * from `users` where json_overlaps(`options`, ?)', $builder->toSql());\n        $this->assertEquals(['[\"en\",\"fr\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonOverlaps('users.options->languages', ['en', 'fr']);\n        $this->assertSame('select * from `users` where json_overlaps(`users`.`options`, ?, \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals(['[\"en\",\"fr\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonOverlaps('options->languages', new Raw(\"'[\\\"en\\\", \\\"fr\\\"]'\"));\n        $this->assertSame('select * from `users` where `id` = ? or json_overlaps(`options`, \\'[\"en\", \"fr\"]\\', \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonContainsPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('options', ['en']);\n        $this->assertSame('select * from \"users\" where (\"options\")::jsonb @> ?', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('users.options->languages', ['en']);\n        $this->assertSame('select * from \"users\" where (\"users\".\"options\"->\\'languages\\')::jsonb @> ?', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw(\"'[\\\"en\\\"]'\"));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or (\"options\"->\\'languages\\')::jsonb @> \\'[\"en\"]\\'', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonContainsSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('options', 'en')->toSql();\n        $this->assertSame('select * from \"users\" where exists (select 1 from json_each(\"options\") where \"json_each\".\"value\" is ?)', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('users.options->language', 'en')->toSql();\n        $this->assertSame('select * from \"users\" where exists (select 1 from json_each(\"users\".\"options\", \\'$.\"language\"\\') where \"json_each\".\"value\" is ?)', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n    }\n\n    public function testWhereJsonContainsSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('options', true);\n        $this->assertSame('select * from [users] where ? in (select [value] from openjson([options]))', $builder->toSql());\n        $this->assertEquals(['true'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonContains('users.options->languages', 'en');\n        $this->assertSame('select * from [users] where ? in (select [value] from openjson([users].[options], \\'$.\"languages\"\\'))', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw(\"'en'\"));\n        $this->assertSame('select * from [users] where [id] = ? or \\'en\\' in (select [value] from openjson([options], \\'$.\"languages\"\\'))', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonDoesntContainMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en']);\n        $this->assertSame('select * from `users` where not json_contains(`options`, ?, \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw(\"'[\\\"en\\\"]'\"));\n        $this->assertSame('select * from `users` where `id` = ? or not json_contains(`options`, \\'[\"en\"]\\', \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonDoesntOverlapMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntOverlap('options->languages', ['en', 'fr']);\n        $this->assertSame('select * from `users` where not json_overlaps(`options`, ?, \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals(['[\"en\",\"fr\"]'], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntOverlap('options->languages', new Raw(\"'[\\\"en\\\", \\\"fr\\\"]'\"));\n        $this->assertSame('select * from `users` where `id` = ? or not json_overlaps(`options`, \\'[\"en\", \"fr\"]\\', \\'$.\"languages\"\\')', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonDoesntContainPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en']);\n        $this->assertSame('select * from \"users\" where not (\"options\"->\\'languages\\')::jsonb @> ?', $builder->toSql());\n        $this->assertEquals(['[\"en\"]'], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw(\"'[\\\"en\\\"]'\"));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or not (\"options\"->\\'languages\\')::jsonb @> \\'[\"en\"]\\'', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonDoesntContainSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContain('options', 'en')->toSql();\n        $this->assertSame('select * from \"users\" where not exists (select 1 from json_each(\"options\") where \"json_each\".\"value\" is ?)', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContain('users.options->language', 'en')->toSql();\n        $this->assertSame('select * from \"users\" where not exists (select 1 from json_each(\"users\".\"options\", \\'$.\"language\"\\') where \"json_each\".\"value\" is ?)', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n    }\n\n    public function testWhereJsonDoesntContainSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', 'en');\n        $this->assertSame('select * from [users] where not ? in (select [value] from openjson([options], \\'$.\"languages\"\\'))', $builder->toSql());\n        $this->assertEquals(['en'], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw(\"'en'\"));\n        $this->assertSame('select * from [users] where [id] = ? or not \\'en\\' in (select [value] from openjson([options], \\'$.\"languages\"\\'))', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonContainsKeyMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('users.options->languages');\n        $this->assertSame('select * from `users` where ifnull(json_contains_path(`users`.`options`, \\'one\\', \\'$.\"languages\"\\'), 0)', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->language->primary');\n        $this->assertSame('select * from `users` where ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"language\".\"primary\"\\'), 0)', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContainsKey('options->languages');\n        $this->assertSame('select * from `users` where `id` = ? or ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"languages\"\\'), 0)', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->languages[0][1]');\n        $this->assertSame('select * from `users` where ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"languages\"[0][1]\\'), 0)', $builder->toSql());\n    }\n\n    public function testWhereJsonContainsKeyPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('users.options->languages');\n        $this->assertSame('select * from \"users\" where coalesce((\"users\".\"options\")::jsonb ?? \\'languages\\', false)', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->language->primary');\n        $this->assertSame('select * from \"users\" where coalesce((\"options\"->\\'language\\')::jsonb ?? \\'primary\\', false)', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContainsKey('options->languages');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or coalesce((\"options\")::jsonb ?? \\'languages\\', false)', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->languages[0][1]');\n        $this->assertSame('select * from \"users\" where case when jsonb_typeof((\"options\"->\\'languages\\'->0)::jsonb) = \\'array\\' then jsonb_array_length((\"options\"->\\'languages\\'->0)::jsonb) >= 2 else false end', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->languages[-1]');\n        $this->assertSame('select * from \"users\" where case when jsonb_typeof((\"options\"->\\'languages\\')::jsonb) = \\'array\\' then jsonb_array_length((\"options\"->\\'languages\\')::jsonb) >= 1 else false end', $builder->toSql());\n    }\n\n    public function testWhereJsonContainsKeySqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('users.options->languages');\n        $this->assertSame('select * from \"users\" where json_type(\"users\".\"options\", \\'$.\"languages\"\\') is not null', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->language->primary');\n        $this->assertSame('select * from \"users\" where json_type(\"options\", \\'$.\"language\".\"primary\"\\') is not null', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContainsKey('options->languages');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or json_type(\"options\", \\'$.\"languages\"\\') is not null', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->languages[0][1]');\n        $this->assertSame('select * from \"users\" where json_type(\"options\", \\'$.\"languages\"[0][1]\\') is not null', $builder->toSql());\n    }\n\n    public function testWhereJsonContainsKeySqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('users.options->languages');\n        $this->assertSame('select * from [users] where \\'languages\\' in (select [key] from openjson([users].[options]))', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->language->primary');\n        $this->assertSame('select * from [users] where \\'primary\\' in (select [key] from openjson([options], \\'$.\"language\"\\'))', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContainsKey('options->languages');\n        $this->assertSame('select * from [users] where [id] = ? or \\'languages\\' in (select [key] from openjson([options]))', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonContainsKey('options->languages[0][1]');\n        $this->assertSame('select * from [users] where 1 in (select [key] from openjson([options], \\'$.\"languages\"[0]\\'))', $builder->toSql());\n    }\n\n    public function testWhereJsonDoesntContainKeyMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from `users` where not ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"languages\"\\'), 0)', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from `users` where `id` = ? or not ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"languages\"\\'), 0)', $builder->toSql());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages[0][1]');\n        $this->assertSame('select * from `users` where not ifnull(json_contains_path(`options`, \\'one\\', \\'$.\"languages\"[0][1]\\'), 0)', $builder->toSql());\n    }\n\n    public function testWhereJsonDoesntContainKeyPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from \"users\" where not coalesce((\"options\")::jsonb ?? \\'languages\\', false)', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or not coalesce((\"options\")::jsonb ?? \\'languages\\', false)', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages[0][1]');\n        $this->assertSame('select * from \"users\" where not case when jsonb_typeof((\"options\"->\\'languages\\'->0)::jsonb) = \\'array\\' then jsonb_array_length((\"options\"->\\'languages\\'->0)::jsonb) >= 2 else false end', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages[-1]');\n        $this->assertSame('select * from \"users\" where not case when jsonb_typeof((\"options\"->\\'languages\\')::jsonb) = \\'array\\' then jsonb_array_length((\"options\"->\\'languages\\')::jsonb) >= 1 else false end', $builder->toSql());\n    }\n\n    public function testWhereJsonDoesntContainKeySqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from \"users\" where not json_type(\"options\", \\'$.\"languages\"\\') is not null', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or not json_type(\"options\", \\'$.\"languages\"\\') is not null', $builder->toSql());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages[0][1]');\n        $this->assertSame('select * from \"users\" where \"id\" = ? or not json_type(\"options\", \\'$.\"languages\"[0][1]\\') is not null', $builder->toSql());\n    }\n\n    public function testWhereJsonDoesntContainKeySqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from [users] where not \\'languages\\' in (select [key] from openjson([options]))', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages');\n        $this->assertSame('select * from [users] where [id] = ? or not \\'languages\\' in (select [key] from openjson([options]))', $builder->toSql());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContainKey('options->languages[0][1]');\n        $this->assertSame('select * from [users] where [id] = ? or not 1 in (select [key] from openjson([options], \\'$.\"languages\"[0]\\'))', $builder->toSql());\n    }\n\n    public function testWhereJsonLengthMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('options', 0);\n        $this->assertSame('select * from `users` where json_length(`options`) = ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);\n        $this->assertSame('select * from `users` where json_length(`users`.`options`, \\'$.\"languages\"\\') > ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));\n        $this->assertSame('select * from `users` where `id` = ? or json_length(`options`, \\'$.\"languages\"\\') = 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n\n        $builder = $this->getMySqlBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));\n        $this->assertSame('select * from `users` where `id` = ? or json_length(`options`, \\'$.\"languages\"\\') > 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonLengthPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('options', 0);\n        $this->assertSame('select * from \"users\" where jsonb_array_length((\"options\")::jsonb) = ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);\n        $this->assertSame('select * from \"users\" where jsonb_array_length((\"users\".\"options\"->\\'languages\\')::jsonb) > ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or jsonb_array_length((\"options\"->\\'languages\\')::jsonb) = 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or jsonb_array_length((\"options\"->\\'languages\\')::jsonb) > 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonLengthSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('options', 0);\n        $this->assertSame('select * from \"users\" where json_array_length(\"options\") = ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);\n        $this->assertSame('select * from \"users\" where json_array_length(\"users\".\"options\", \\'$.\"languages\"\\') > ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or json_array_length(\"options\", \\'$.\"languages\"\\') = 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));\n        $this->assertSame('select * from \"users\" where \"id\" = ? or json_array_length(\"options\", \\'$.\"languages\"\\') > 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testWhereJsonLengthSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('options', 0);\n        $this->assertSame('select * from [users] where (select count(*) from openjson([options])) = ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);\n        $this->assertSame('select * from [users] where (select count(*) from openjson([users].[options], \\'$.\"languages\"\\')) > ?', $builder->toSql());\n        $this->assertEquals([0], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));\n        $this->assertSame('select * from [users] where [id] = ? or (select count(*) from openjson([options], \\'$.\"languages\"\\')) = 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));\n        $this->assertSame('select * from [users] where [id] = ? or (select count(*) from openjson([options], \\'$.\"languages\"\\')) > 0', $builder->toSql());\n        $this->assertEquals([1], $builder->getBindings());\n    }\n\n    public function testFrom()\n    {\n        $builder = $this->getBuilder();\n        $builder->from($this->getBuilder()->from('users'), 'u');\n        $this->assertSame('select * from (select * from \"users\") as \"u\"', $builder->toSql());\n\n        $builder = $this->getBuilder();\n        $eloquentBuilder = new EloquentBuilder($this->getBuilder());\n        $builder->from($eloquentBuilder->from('users'), 'u');\n        $this->assertSame('select * from (select * from \"users\") as \"u\"', $builder->toSql());\n    }\n\n    public function testFromSub()\n    {\n        $builder = $this->getBuilder();\n        $builder->fromSub(function ($query) {\n            $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions')->where('foo', '=', '1');\n        }, 'sessions')->where('bar', '<', '10');\n        $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from \"user_sessions\" where \"foo\" = ?) as \"sessions\" where \"bar\" < ?', $builder->toSql());\n        $this->assertEquals(['1', '10'], $builder->getBindings());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->fromSub(['invalid'], 'sessions')->where('bar', '<', '10');\n    }\n\n    public function testFromSubWithPrefix()\n    {\n        $builder = $this->getBuilder(prefix: 'prefix_');\n        $builder->fromSub(function ($query) {\n            $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions')->where('foo', '=', '1');\n        }, 'sessions')->where('bar', '<', '10');\n        $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from \"prefix_user_sessions\" where \"foo\" = ?) as \"prefix_sessions\" where \"bar\" < ?', $builder->toSql());\n        $this->assertEquals(['1', '10'], $builder->getBindings());\n    }\n\n    public function testFromSubWithoutBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->fromSub(function ($query) {\n            $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions');\n        }, 'sessions');\n        $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from \"user_sessions\") as \"sessions\"', $builder->toSql());\n\n        $this->expectException(InvalidArgumentException::class);\n        $builder = $this->getBuilder();\n        $builder->fromSub(['invalid'], 'sessions');\n    }\n\n    public function testFromRaw()\n    {\n        $builder = $this->getBuilder();\n        $builder->fromRaw(new Raw('(select max(last_seen_at) as last_seen_at from \"user_sessions\") as \"sessions\"'));\n        $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from \"user_sessions\") as \"sessions\"', $builder->toSql());\n    }\n\n    public function testFromRawOnSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->fromRaw('dbo.[SomeNameWithRoundBrackets (test)]');\n        $this->assertSame('select * from dbo.[SomeNameWithRoundBrackets (test)]', $builder->toSql());\n    }\n\n    public function testFromRawWithWhereOnTheMainQuery()\n    {\n        $builder = $this->getBuilder();\n        $builder->fromRaw(new Raw('(select max(last_seen_at) as last_seen_at from \"sessions\") as \"last_seen_at\"'))->where('last_seen_at', '>', '1520652582');\n        $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from \"sessions\") as \"last_seen_at\" where \"last_seen_at\" > ?', $builder->toSql());\n        $this->assertEquals(['1520652582'], $builder->getBindings());\n    }\n\n    public function testFromQuestionMarkOperatorOnPostgres()\n    {\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('roles', '?', 'superuser');\n        $this->assertSame('select * from \"users\" where \"roles\" ?? ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('roles', '?|', 'superuser');\n        $this->assertSame('select * from \"users\" where \"roles\" ??| ?', $builder->toSql());\n\n        $builder = $this->getPostgresBuilder();\n        $builder->select('*')->from('users')->where('roles', '?&', 'superuser');\n        $this->assertSame('select * from \"users\" where \"roles\" ??& ?', $builder->toSql());\n    }\n\n    public function testUseIndexMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('foo')->from('users')->useIndex('test_index');\n        $this->assertSame('select `foo` from `users` use index (test_index)', $builder->toSql());\n    }\n\n    public function testForceIndexMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('foo')->from('users')->forceIndex('test_index');\n        $this->assertSame('select `foo` from `users` force index (test_index)', $builder->toSql());\n    }\n\n    public function testIgnoreIndexMySql()\n    {\n        $builder = $this->getMySqlBuilder();\n        $builder->select('foo')->from('users')->ignoreIndex('test_index');\n        $this->assertSame('select `foo` from `users` ignore index (test_index)', $builder->toSql());\n    }\n\n    public function testUseIndexSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('foo')->from('users')->useIndex('test_index');\n        $this->assertSame('select \"foo\" from \"users\"', $builder->toSql());\n    }\n\n    public function testForceIndexSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('foo')->from('users')->forceIndex('test_index');\n        $this->assertSame('select \"foo\" from \"users\" indexed by test_index', $builder->toSql());\n    }\n\n    public function testIgnoreIndexSqlite()\n    {\n        $builder = $this->getSQLiteBuilder();\n        $builder->select('foo')->from('users')->ignoreIndex('test_index');\n        $this->assertSame('select \"foo\" from \"users\"', $builder->toSql());\n    }\n\n    public function testUseIndexSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('foo')->from('users')->useIndex('test_index');\n        $this->assertSame('select [foo] from [users]', $builder->toSql());\n    }\n\n    public function testForceIndexSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('foo')->from('users')->forceIndex('test_index');\n        $this->assertSame('select [foo] from [users] with (index([test_index]))', $builder->toSql());\n    }\n\n    public function testIgnoreIndexSqlServer()\n    {\n        $builder = $this->getSqlServerBuilder();\n        $builder->select('foo')->from('users')->ignoreIndex('test_index');\n        $this->assertSame('select [foo] from [users]', $builder->toSql());\n    }\n\n    public function testClone()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users');\n        $clone = $builder->clone()->where('email', 'foo');\n\n        $this->assertNotSame($builder, $clone);\n        $this->assertSame('select * from \"users\"', $builder->toSql());\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $clone->toSql());\n    }\n\n    public function testCloneWithout()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('email', 'foo')->orderBy('email');\n        $clone = $builder->cloneWithout(['orders']);\n\n        $this->assertSame('select * from \"users\" where \"email\" = ? order by \"email\" asc', $builder->toSql());\n        $this->assertSame('select * from \"users\" where \"email\" = ?', $clone->toSql());\n    }\n\n    public function testCloneWithoutBindings()\n    {\n        $builder = $this->getBuilder();\n        $builder->select('*')->from('users')->where('email', 'foo')->orderBy('email');\n        $clone = $builder->cloneWithout(['wheres'])->cloneWithoutBindings(['where']);\n\n        $this->assertSame('select * from \"users\" where \"email\" = ? order by \"email\" asc', $builder->toSql());\n        $this->assertEquals([0 => 'foo'], $builder->getBindings());\n\n        $this->assertSame('select * from \"users\" order by \"email\" asc', $clone->toSql());\n        $this->assertEquals([], $clone->getBindings());\n    }\n\n    public function testToRawSql()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('prepareBindings')\n            ->with(['foo'])\n            ->andReturn(['foo']);\n        $grammar = m::mock(Grammar::class, [$connection])->makePartial();\n        $grammar->shouldReceive('substituteBindingsIntoRawSql')\n            ->with('select * from \"users\" where \"email\" = ?', ['foo'])\n            ->andReturn('select * from \"users\" where \"email\" = \\'foo\\'');\n        $builder = new Builder($connection, $grammar, m::mock(Processor::class));\n        $builder->select('*')->from('users')->where('email', 'foo');\n\n        $this->assertSame('select * from \"users\" where \"email\" = \\'foo\\'', $builder->toRawSql());\n    }\n\n    protected function getConnection(string $prefix = '')\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getDatabaseName')->andReturn('database');\n        $connection->shouldReceive('getTablePrefix')->andReturn($prefix);\n\n        return $connection;\n    }\n\n    protected function getBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new Grammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getPostgresBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new PostgresGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getMySqlBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new MySqlGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getMariaDbBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new MariaDbGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getSQLiteBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new SQLiteGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getSqlServerBuilder(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new SqlServerGrammar($connection);\n        $processor = m::mock(Processor::class);\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getMySqlBuilderWithProcessor(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new MySqlGrammar($connection);\n        $processor = new MySqlProcessor;\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    protected function getPostgresBuilderWithProcessor(string $prefix = '')\n    {\n        $connection = $this->getConnection(prefix: $prefix);\n        $grammar = new PostgresGrammar($connection);\n        $processor = new PostgresProcessor;\n\n        return new Builder($connection, $grammar, $processor);\n    }\n\n    /**\n     * @return MockInterface|\\Illuminate\\Database\\Query\\Builder\n     */\n    protected function getMockQueryBuilder()\n    {\n        return m::mock(Builder::class, [\n            $connection = $this->getConnection(),\n            new Grammar($connection),\n            m::mock(Processor::class),\n        ])->makePartial();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseQueryExceptionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Support\\Facades\\DB;\nuse Mockery as m;\nuse PDOException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseQueryExceptionTest extends TestCase\n{\n    public function testIfItEmbedsBindingsIntoSql()\n    {\n        $connection = $this->getConnection();\n\n        $sql = 'SELECT * FROM huehue WHERE a = ? and hue = ?';\n        $bindings = [1, 'br'];\n\n        $expectedSql = \"SELECT * FROM huehue WHERE a = 1 and hue = 'br'\";\n\n        $pdoException = new PDOException('Mock SQL error');\n        $exception = new QueryException($connection->getName(), $sql, $bindings, $pdoException);\n\n        DB::shouldReceive('connection')->andReturn($connection);\n        $result = $exception->getRawSql();\n\n        $this->assertSame($expectedSql, $result);\n    }\n\n    public function testIfItReturnsSameSqlWhenThereAreNoBindings()\n    {\n        $connection = $this->getConnection();\n\n        $sql = \"SELECT * FROM huehue WHERE a = 1 and hue = 'br'\";\n        $bindings = [];\n\n        $expectedSql = $sql;\n\n        $pdoException = new PDOException('Mock SQL error');\n        $exception = new QueryException($connection->getName(), $sql, $bindings, $pdoException);\n\n        DB::shouldReceive('connection')->andReturn($connection);\n        $result = $exception->getRawSql();\n\n        $this->assertSame($expectedSql, $result);\n    }\n\n    public function testMessageIncludesConnectionInfo()\n    {\n        $pdoException = new PDOException('SQLSTATE[HY000] [2002] No such file or directory');\n        $exception = new QueryException('mysql::read', 'SELECT * FROM users', [], $pdoException, [\n            'driver' => 'mysql',\n            'name' => 'mysql::read',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'laravel_db',\n            'unix_socket' => null,\n        ]);\n\n        $this->assertStringContainsString('Host: 192.168.1.10', $exception->getMessage());\n        $this->assertStringContainsString('Port: 3306', $exception->getMessage());\n        $this->assertStringContainsString('Database: laravel_db', $exception->getMessage());\n        $this->assertStringContainsString('Connection: mysql::read', $exception->getMessage());\n    }\n\n    public function testMessageIncludesUnixSocket()\n    {\n        $pdoException = new PDOException('SQLSTATE[HY000] [2002] No such file or directory');\n        $exception = new QueryException('mysql', 'SELECT * FROM users', [], $pdoException, [\n            'driver' => 'mysql',\n            'unix_socket' => '/tmp/mysql.sock',\n            'database' => 'laravel_db',\n        ]);\n\n        $this->assertStringContainsString('Socket: /tmp/mysql.sock', $exception->getMessage());\n        $this->assertStringContainsString('Database: laravel_db', $exception->getMessage());\n        $this->assertStringNotContainsString('Host:', $exception->getMessage());\n    }\n\n    public function testMessageHandlesArrayHosts()\n    {\n        $pdoException = new PDOException('SQLSTATE[HY000] [2002] No such file or directory');\n        $exception = new QueryException('mysql::read', 'SELECT * FROM users', [], $pdoException, [\n            'driver' => 'mysql',\n            'host' => ['192.168.1.10', '192.168.1.11'],\n            'port' => '3306',\n            'database' => 'laravel_db',\n        ]);\n\n        $this->assertStringContainsString('Host: 192.168.1.10, 192.168.1.11', $exception->getMessage());\n    }\n\n    public function testMessageHandlesEmptyConnectionInfo()\n    {\n        $pdoException = new PDOException('SQLSTATE[HY000] [2002] No such file or directory');\n        $exception = new QueryException('mysql', 'SELECT * FROM users', [], $pdoException, [\n            'driver' => 'mysql',\n            'host' => '',\n            'port' => '',\n            'database' => '',\n        ]);\n\n        $this->assertStringContainsString('Host: ,', $exception->getMessage());\n        $this->assertStringContainsString('Database: ', $exception->getMessage());\n    }\n\n    public function testMessageForSqliteOnlyShowsDatabase()\n    {\n        $pdoException = new PDOException('SQLSTATE[HY000]: General error: 1 no such table');\n        $exception = new QueryException('sqlite', 'SELECT * FROM users', [], $pdoException, [\n            'driver' => 'sqlite',\n            'name' => 'sqlite',\n            'host' => null,\n            'port' => null,\n            'database' => '/path/to/database.sqlite',\n            'unix_socket' => null,\n        ]);\n\n        $this->assertStringContainsString('Database: /path/to/database.sqlite', $exception->getMessage());\n        $this->assertStringNotContainsString('Host:', $exception->getMessage());\n        $this->assertStringNotContainsString('Port:', $exception->getMessage());\n    }\n\n    public function testGetConnectionInfoReturnsConnectionInfo()\n    {\n        $pdoException = new PDOException('Mock error');\n        $connectionInfo = [\n            'driver' => 'mysql',\n            'name' => 'mysql::read',\n            'host' => '192.168.1.10',\n            'port' => '3306',\n            'database' => 'laravel_db',\n            'unix_socket' => null,\n        ];\n        $exception = new QueryException('mysql::read', 'SELECT * FROM users', [], $pdoException, $connectionInfo);\n\n        $this->assertSame($connectionInfo, $exception->getConnectionDetails());\n    }\n\n    public function testBackwardCompatibilityWithoutConnectionInfo()\n    {\n        $pdoException = new PDOException('Mock SQL error');\n        $exception = new QueryException('mysql', 'SELECT * FROM users WHERE id = ?', [1], $pdoException);\n\n        $this->assertSame('Mock SQL error (Connection: mysql, SQL: SELECT * FROM users WHERE id = 1)', $exception->getMessage());\n        $this->assertSame([], $exception->getConnectionDetails());\n    }\n\n    protected function getConnection()\n    {\n        $connection = m::mock(Connection::class);\n\n        $grammar = new Grammar($connection);\n\n        $connection->shouldReceive('getName')->andReturn('default');\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n        $connection->shouldReceive('escape')->with(1, false)->andReturn(1);\n        $connection->shouldReceive('escape')->with('br', false)->andReturn(\"'br'\");\n\n        return $connection;\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nclass DatabaseQueryGrammarTest extends TestCase\n{\n    public function testWhereRawReturnsStringWhenExpressionPassed()\n    {\n        $builder = m::mock(Builder::class);\n        $grammar = new Grammar(m::mock(Connection::class));\n        $reflection = new ReflectionClass($grammar);\n        $method = $reflection->getMethod('whereRaw');\n        $expressionArray = ['sql' => new Expression('select * from \"users\"')];\n\n        $rawQuery = $method->invoke($grammar, $builder, $expressionArray);\n\n        $this->assertSame('select * from \"users\"', $rawQuery);\n    }\n\n    public function testWhereRawReturnsStringWhenStringPassed()\n    {\n        $builder = m::mock(Builder::class);\n        $grammar = new Grammar(m::mock(Connection::class));\n        $reflection = new ReflectionClass($grammar);\n        $method = $reflection->getMethod('whereRaw');\n        $stringArray = ['sql' => 'select * from \"users\"'];\n\n        $rawQuery = $method->invoke($grammar, $builder, $stringArray);\n\n        $this->assertSame('select * from \"users\"', $rawQuery);\n    }\n\n    public function testCompileOrdersAcceptsExpression()\n    {\n        $builder = m::mock(Builder::class);\n        $grammar = new Grammar(m::mock(Connection::class));\n\n        // compileOrders() calls $query->getGrammar() → return our $grammar\n        $builder->shouldReceive('getGrammar')->andReturn($grammar);\n\n        $orders = [\n            ['sql' => new Expression('length(\"name\") desc')], // mimics orderByRaw(DB::raw(...))\n        ];\n\n        $ref = new \\ReflectionClass($grammar);\n        $method = $ref->getMethod('compileOrders'); // protected\n        $sql = $method->invoke($grammar, $builder, $orders);\n\n        $this->assertSame('order by length(\"name\") desc', strtolower($sql));\n    }\n\n    public function testCompileOrdersAcceptsExpressionWithPlaceholders()\n    {\n        $builder = m::mock(Builder::class);\n        $grammar = new Grammar(m::mock(Connection::class));\n        $builder->shouldReceive('getGrammar')->andReturn($grammar);\n\n        $orders = [\n            ['sql' => new Expression('field(status, ?, ?) asc')],\n        ];\n\n        $ref = new \\ReflectionClass($grammar);\n        $method = $ref->getMethod('compileOrders');\n        $sql = $method->invoke($grammar, $builder, $orders);\n\n        $this->assertSame('order by field(status, ?, ?) asc', strtolower($sql));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSQLiteBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\SQLiteBuilder;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\File;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSQLiteBuilderTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $app = new Container;\n\n        Container::setInstance($app)\n            ->singleton('files', Filesystem::class);\n\n        Facade::setFacadeApplication($app);\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getSchemaGrammar')->once();\n\n        $builder = new SQLiteBuilder($connection);\n\n        File::shouldReceive('put')\n            ->once()\n            ->with('my_temporary_database_a', '')\n            ->andReturn(20); // bytes\n\n        $this->assertTrue($builder->createDatabase('my_temporary_database_a'));\n\n        File::shouldReceive('put')\n            ->once()\n            ->with('my_temporary_database_b', '')\n            ->andReturn(false);\n\n        $this->assertFalse($builder->createDatabase('my_temporary_database_b'));\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getSchemaGrammar')->once();\n\n        $builder = new SQLiteBuilder($connection);\n\n        File::shouldReceive('exists')\n            ->once()\n            ->andReturn(true);\n\n        File::shouldReceive('delete')\n            ->once()\n            ->with('my_temporary_database_b')\n            ->andReturn(true);\n\n        $this->assertTrue($builder->dropDatabaseIfExists('my_temporary_database_b'));\n\n        File::shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->assertTrue($builder->dropDatabaseIfExists('my_temporary_database_c'));\n\n        File::shouldReceive('exists')\n            ->once()\n            ->andReturn(true);\n\n        File::shouldReceive('delete')\n            ->once()\n            ->with('my_temporary_database_c')\n            ->andReturn(false);\n\n        $this->assertFalse($builder->dropDatabaseIfExists('my_temporary_database_c'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSQLiteProcessorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Query\\Processors\\SQLiteProcessor;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSQLiteProcessorTest extends TestCase\n{\n    public function testProcessColumns()\n    {\n        $processor = new SQLiteProcessor;\n\n        $listing = [\n            ['name' => 'id', 'type' => 'INTEGER', 'nullable' => '0', 'default' => '', 'primary' => '1', 'extra' => 1],\n            ['name' => 'name', 'type' => 'varchar', 'nullable' => '1', 'default' => 'foo', 'primary' => '0', 'extra' => 1],\n            ['name' => 'is_active', 'type' => 'tinyint(1)', 'nullable' => '0', 'default' => '1', 'primary' => '0', 'extra' => 1],\n            ['name' => 'with/slash', 'type' => 'tinyint(1)', 'nullable' => '0', 'default' => '1', 'primary' => '0', 'extra' => 1],\n        ];\n        $expected = [\n            ['name' => 'id', 'type_name' => 'integer', 'type' => 'integer', 'collation' => null, 'nullable' => false, 'default' => '', 'auto_increment' => true, 'comment' => null, 'generation' => null],\n            ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => true, 'default' => 'foo', 'auto_increment' => false, 'comment' => null, 'generation' => null],\n            ['name' => 'is_active', 'type_name' => 'tinyint', 'type' => 'tinyint(1)', 'collation' => null, 'nullable' => false, 'default' => '1', 'auto_increment' => false, 'comment' => null, 'generation' => null],\n            ['name' => 'with/slash', 'type_name' => 'tinyint', 'type' => 'tinyint(1)', 'collation' => null, 'nullable' => false, 'default' => '1', 'auto_increment' => false, 'comment' => null, 'generation' => null],\n        ];\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n\n        // convert listing to objects to simulate PDO::FETCH_CLASS\n        foreach ($listing as &$row) {\n            $row = (object) $row;\n        }\n\n        $this->assertEquals($expected, $processor->processColumns($listing));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSQLiteQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Grammars\\SQLiteGrammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSQLiteQueryGrammarTest extends TestCase\n{\n    public function testToRawSql()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('escape')->with('foo', false)->andReturn(\"'foo'\");\n        $grammar = new SQLiteGrammar($connection);\n\n        $query = $grammar->substituteBindingsIntoRawSql(\n            'select * from \"users\" where \\'Hello\\'\\'World?\\' IS NOT NULL AND \"email\" = ?',\n            ['foo'],\n        );\n\n        $this->assertSame('select * from \"users\" where \\'Hello\\'\\'World?\\' IS NOT NULL AND \"email\" = \\'foo\\'', $query);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSQLiteSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Capsule\\Manager;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Query\\Processors\\SQLiteProcessor;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\ForeignIdColumnDefinition;\nuse Illuminate\\Database\\Schema\\Grammars\\SQLiteGrammar;\nuse Illuminate\\Database\\Schema\\SQLiteBuilder;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Foo;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass DatabaseSQLiteSchemaGrammarTest extends TestCase\n{\n    public function testBasicCreateTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"id\" integer primary key autoincrement not null, \"email\" varchar not null)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $expected = [\n            'alter table \"users\" add column \"id\" integer primary key autoincrement not null',\n            'alter table \"users\" add column \"email\" varchar not null',\n        ];\n        $this->assertEquals($expected, $statements);\n    }\n\n    public function testCreateTemporaryTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create temporary table \"users\" (\"id\" integer primary key autoincrement not null, \"email\" varchar not null)', $statements[0]);\n    }\n\n    public function testDropTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table \"users\"', $statements[0]);\n    }\n\n    public function testDropTableIfExists()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table if exists \"users\"', $statements[0]);\n    }\n\n    public function testDropUnique()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropUnique('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"foo\"', $statements[0]);\n    }\n\n    public function testDropIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"foo\"', $statements[0]);\n    }\n\n    public function testDropIndexWithSchema()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'my_schema.users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"my_schema\".\"foo\"', $statements[0]);\n    }\n\n    public function testDropColumn()\n    {\n        $db = new Manager;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => 'prefix_',\n        ]);\n\n        $schema = $db->getConnection()->getSchemaBuilder();\n\n        $schema->create('users', function (Blueprint $table) {\n            $table->string('email');\n            $table->string('name');\n        });\n\n        $this->assertTrue($schema->hasTable('users'));\n        $this->assertTrue($schema->hasColumn('users', 'name'));\n\n        $schema->table('users', function (Blueprint $table) {\n            $table->dropColumn('name');\n        });\n\n        $this->assertFalse($schema->hasColumn('users', 'name'));\n    }\n\n    public function testDropSpatialIndex()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('The database driver in use does not support spatial indexes.');\n\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $blueprint->toSql();\n    }\n\n    public function testRenameTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rename('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" rename to \"foo\"', $statements[0]);\n    }\n\n    public function testRenameIndex()\n    {\n        $db = new Manager;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => 'prefix_',\n        ]);\n\n        $schema = $db->getConnection()->getSchemaBuilder();\n\n        $schema->create('users', function (Blueprint $table) {\n            $table->string('name');\n            $table->string('email');\n        });\n\n        $schema->table('users', function (Blueprint $table) {\n            $table->index(['name', 'email'], 'index1');\n        });\n\n        $indexes = $schema->getIndexListing('users');\n\n        $this->assertContains('index1', $indexes);\n        $this->assertNotContains('index2', $indexes);\n\n        $schema->table('users', function (Blueprint $table) {\n            $table->renameIndex('index1', 'index2');\n        });\n\n        $this->assertFalse($schema->hasIndex('users', 'index1'));\n        $this->assertTrue(collect($schema->getIndexes('users'))->contains(\n            fn ($index) => $index['name'] === 'index2' && $index['columns'] === ['name', 'email']\n        ));\n    }\n\n    public function testAddingPrimaryKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('foo')->primary();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"foo\" varchar not null, primary key (\"foo\"))', $statements[0]);\n    }\n\n    public function testAddingForeignKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('foo')->primary();\n        $blueprint->string('order_id');\n        $blueprint->foreign('order_id')->references('id')->on('orders');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"foo\" varchar not null, \"order_id\" varchar not null, foreign key(\"order_id\") references \"orders\"(\"id\"), primary key (\"foo\"))', $statements[0]);\n    }\n\n    public function testAddingUniqueKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create unique index \"bar\" on \"users\" (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"baz\" on \"users\" (\"foo\", \"bar\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKeyWithSchema()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'foo.users');\n        $blueprint->unique('foo', 'bar');\n\n        $this->assertSame(['create unique index \"foo\".\"bar\" on \"users\" (\"foo\")'], $blueprint->toSql());\n    }\n\n    public function testAddingIndexWithSchema()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'foo.users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n\n        $this->assertSame(['create index \"foo\".\"baz\" on \"users\" (\"foo\", \"bar\")'], $blueprint->toSql());\n    }\n\n    public function testAddingSpatialIndex()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('The database driver in use does not support spatial indexes.');\n\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $blueprint->toSql();\n    }\n\n    public function testAddingFluentSpatialIndex()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('The database driver in use does not support spatial indexes.');\n\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates')->spatialIndex();\n        $blueprint->toSql();\n    }\n\n    public function testAddingRawIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"raw_index\" on \"users\" ((function(column)))', $statements[0]);\n    }\n\n    public function testAddingIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingSmallIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingMediumIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" integer primary key autoincrement not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingForeignID()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('getPostProcessor')->andReturn(new SQliteProcessor);\n        $connection->shouldReceive('selectFromWriteConnection')->andReturn([]);\n        $connection->shouldReceive('scalar')->andReturn('');\n\n        $blueprint = new Blueprint($connection, 'users');\n        $foreignId = $blueprint->foreignId('foo');\n        $blueprint->foreignId('company_id')->constrained();\n        $blueprint->foreignId('laravel_idea_id')->constrained();\n        $blueprint->foreignId('team_id')->references('id')->on('teams');\n        $blueprint->foreignId('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" integer not null',\n            'alter table \"users\" add column \"company_id\" integer not null',\n            'create table \"__temp__users\" (\"foo\" integer not null, \"company_id\" integer not null, foreign key(\"company_id\") references \"companies\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\") select \"foo\", \"company_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"laravel_idea_id\" integer not null',\n            'create table \"__temp__users\" (\"foo\" integer not null, \"company_id\" integer not null, \"laravel_idea_id\" integer not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\") select \"foo\", \"company_id\", \"laravel_idea_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"team_id\" integer not null',\n            'create table \"__temp__users\" (\"foo\" integer not null, \"company_id\" integer not null, \"laravel_idea_id\" integer not null, \"team_id\" integer not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"), foreign key(\"team_id\") references \"teams\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\") select \"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"team_column_id\" integer not null',\n            'create table \"__temp__users\" (\"foo\" integer not null, \"company_id\" integer not null, \"laravel_idea_id\" integer not null, \"team_id\" integer not null, \"team_column_id\" integer not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"), foreign key(\"team_id\") references \"teams\"(\"id\"), foreign key(\"team_column_id\") references \"teams\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\", \"team_column_id\") select \"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\", \"team_column_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ], $statements);\n    }\n\n    public function testAddingForeignIdSpecifyingIndexNameInConstraint()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('getPostProcessor')->andReturn(new SQliteProcessor);\n        $connection->shouldReceive('selectFromWriteConnection')->andReturn([]);\n        $connection->shouldReceive('scalar')->andReturn('');\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->foreignId('company_id')->constrained(indexName: 'my_index');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertSame([\n            'alter table \"users\" add column \"company_id\" integer not null',\n            'create table \"__temp__users\" (\"company_id\" integer not null, foreign key(\"company_id\") references \"companies\"(\"id\"))',\n            'insert into \"__temp__users\" (\"company_id\") select \"company_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ], $statements);\n    }\n\n    public function testAddingBigIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"id\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar default \\'bar\\'', $statements[0]);\n    }\n\n    public function testAddingText()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->text('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" text not null', $statements[0]);\n    }\n\n    public function testAddingBigInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingMediumInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingTinyInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingSmallInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" integer primary key autoincrement not null', $statements[0]);\n    }\n\n    public function testAddingFloat()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->float('foo', 5);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" float not null', $statements[0]);\n    }\n\n    public function testAddingDouble()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->double('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" double not null', $statements[0]);\n    }\n\n    public function testAddingDecimal()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->decimal('foo', 5, 2);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" numeric not null', $statements[0]);\n    }\n\n    public function testAddingBoolean()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->boolean('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" tinyint(1) not null', $statements[0]);\n    }\n\n    public function testAddingEnum()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->enum('role', ['member', 'admin']);\n        $blueprint->enum('status', Foo::cases());\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table \"users\" add column \"role\" varchar check (\"role\" in (\\'member\\', \\'admin\\')) not null', $statements[0]);\n        $this->assertSame('alter table \"users\" add column \"status\" varchar check (\"status\" in (\\'bar\\')) not null', $statements[1]);\n    }\n\n    public function testAddingJson()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" text not null', $statements[0]);\n    }\n\n    public function testAddingNativeJson()\n    {\n        $connection = m::mock(Connection::class);\n        $connection\n            ->shouldReceive('getTablePrefix')->andReturn('')\n            ->shouldReceive('getConfig')->once()->with('use_native_json')->andReturn(true)\n            ->shouldReceive('getSchemaGrammar')->andReturn($this->getGrammar($connection))\n            ->shouldReceive('getSchemaBuilder')->andReturn($this->getBuilder())\n            ->shouldReceive('getServerVersion')->andReturn('3.35')\n            ->getMock();\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" json not null', $statements[0]);\n    }\n\n    public function testAddingJsonb()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" text not null', $statements[0]);\n    }\n\n    public function testAddingNativeJsonb()\n    {\n        $connection = m::mock(Connection::class);\n        $connection\n            ->shouldReceive('getTablePrefix')->andReturn('')\n            ->shouldReceive('getConfig')->once()->with('use_native_jsonb')->andReturn(true)\n            ->shouldReceive('getSchemaGrammar')->andReturn($this->getGrammar($connection))\n            ->shouldReceive('getSchemaBuilder')->andReturn($this->getBuilder())\n            ->shouldReceive('getServerVersion')->andReturn('3.35')\n            ->getMock();\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" jsonb not null', $statements[0]);\n    }\n\n    public function testAddingDate()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" date not null', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" date not null default CURRENT_DATE', $statements[0]);\n    }\n\n    public function testAddingYear()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"birth_year\" integer not null', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"birth_year\" integer not null default (CAST(strftime(\\'%Y\\', \\'now\\') AS INTEGER))', $statements[0]);\n    }\n\n    public function testAddingDateTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimestamp()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamps();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertEquals([\n            'alter table \"users\" add column \"created_at\" datetime',\n            'alter table \"users\" add column \"updated_at\" datetime',\n        ], $statements);\n    }\n\n    public function testAddingTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampsTz();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertEquals([\n            'alter table \"users\" add column \"created_at\" datetime',\n            'alter table \"users\" add column \"updated_at\" datetime',\n        ], $statements);\n    }\n\n    public function testAddingRememberToken()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rememberToken();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"remember_token\" varchar', $statements[0]);\n    }\n\n    public function testAddingBinary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->binary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" blob not null', $statements[0]);\n    }\n\n    public function testAddingUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingUuidDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"uuid\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingForeignUuid()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $connection->shouldReceive('getPostProcessor')->andReturn(new SQliteProcessor);\n        $connection->shouldReceive('selectFromWriteConnection')->andReturn([]);\n        $connection->shouldReceive('scalar')->andReturn('');\n\n        $blueprint = new Blueprint($connection, 'users');\n        $foreignUuid = $blueprint->foreignUuid('foo');\n        $blueprint->foreignUuid('company_id')->constrained();\n        $blueprint->foreignUuid('laravel_idea_id')->constrained();\n        $blueprint->foreignUuid('team_id')->references('id')->on('teams');\n        $blueprint->foreignUuid('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignUuid);\n        $this->assertSame([\n            'alter table \"users\" add column \"foo\" varchar not null',\n            'alter table \"users\" add column \"company_id\" varchar not null',\n            'create table \"__temp__users\" (\"foo\" varchar not null, \"company_id\" varchar not null, foreign key(\"company_id\") references \"companies\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\") select \"foo\", \"company_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"laravel_idea_id\" varchar not null',\n            'create table \"__temp__users\" (\"foo\" varchar not null, \"company_id\" varchar not null, \"laravel_idea_id\" varchar not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\") select \"foo\", \"company_id\", \"laravel_idea_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"team_id\" varchar not null',\n            'create table \"__temp__users\" (\"foo\" varchar not null, \"company_id\" varchar not null, \"laravel_idea_id\" varchar not null, \"team_id\" varchar not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"), foreign key(\"team_id\") references \"teams\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\") select \"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'alter table \"users\" add column \"team_column_id\" varchar not null',\n            'create table \"__temp__users\" (\"foo\" varchar not null, \"company_id\" varchar not null, \"laravel_idea_id\" varchar not null, \"team_id\" varchar not null, \"team_column_id\" varchar not null, foreign key(\"company_id\") references \"companies\"(\"id\"), foreign key(\"laravel_idea_id\") references \"laravel_ideas\"(\"id\"), foreign key(\"team_id\") references \"teams\"(\"id\"), foreign key(\"team_column_id\") references \"teams\"(\"id\"))',\n            'insert into \"__temp__users\" (\"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\", \"team_column_id\") select \"foo\", \"company_id\", \"laravel_idea_id\", \"team_id\", \"team_column_id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ], $statements);\n    }\n\n    public function testAddingIpAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingIpAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"ip_address\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingMacAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"foo\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingMacAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add column \"mac_address\" varchar not null', $statements[0]);\n    }\n\n    public function testAddingGeometry()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add column \"coordinates\" geometry not null', $statements[0]);\n    }\n\n    public function testAddingGeneratedColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->create();\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('\"price\" - 5');\n        $blueprint->integer('discounted_stored')->storedAs('\"price\" - 5');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"products\" (\"price\" integer not null, \"discounted_virtual\" integer as (\"price\" - 5), \"discounted_stored\" integer as (\"price\" - 5) stored)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs('\"price\" - 5')->nullable(false);\n        $blueprint->integer('discounted_stored')->storedAs('\"price\" - 5')->nullable(false);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(3, $statements);\n        $expected = [\n            'alter table \"products\" add column \"price\" integer not null',\n            'alter table \"products\" add column \"discounted_virtual\" integer not null as (\"price\" - 5)',\n            'alter table \"products\" add column \"discounted_stored\" integer not null as (\"price\" - 5) stored',\n        ];\n        $this->assertSame($expected, $statements);\n    }\n\n    public function testAddingGeneratedColumnByExpression()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->create();\n        $blueprint->integer('price');\n        $blueprint->integer('discounted_virtual')->virtualAs(new Expression('\"price\" - 5'));\n        $blueprint->integer('discounted_stored')->storedAs(new Expression('\"price\" - 5'));\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"products\" (\"price\" integer not null, \"discounted_virtual\" integer as (\"price\" - 5), \"discounted_stored\" integer as (\"price\" - 5) stored)', $statements[0]);\n    }\n\n    public function testGrammarsAreMacroable()\n    {\n        // compileReplace macro.\n        $this->getGrammar()::macro('compileReplace', function () {\n            return true;\n        });\n\n        $c = $this->getGrammar()::compileReplace();\n\n        $this->assertTrue($c);\n    }\n\n    public function testCreateTableWithVirtualAsColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->virtualAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_column\" varchar not null, \"my_other_column\" varchar as (my_column))', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_json_column\" varchar not null, \"my_other_column\" varchar as (json_extract(\"my_json_column\", \\'$.\"some_attribute\"\\')))', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->virtualAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_json_column\" varchar not null, \"my_other_column\" varchar as (json_extract(\"my_json_column\", \\'$.\"some_attribute\".\"nested\"\\')))', $statements[0]);\n    }\n\n    public function testCreateTableWithVirtualAsColumnWhenJsonColumnHasArrayKey()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('getConfig')->andReturn(null);\n\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column')->virtualAsJson('my_json_column->foo[0][1]');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"create table \\\"users\\\" (\\\"my_json_column\\\" varchar as (json_extract(\\\"my_json_column\\\", '$.\\\"foo\\\"[0][1]')))\", $statements[0]);\n    }\n\n    public function testCreateTableWithStoredAsColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_column');\n        $blueprint->string('my_other_column')->storedAs('my_column');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_column\" varchar not null, \"my_other_column\" varchar as (my_column) stored)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_json_column\" varchar not null, \"my_other_column\" varchar as (json_extract(\"my_json_column\", \\'$.\"some_attribute\"\\')) stored)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->string('my_json_column');\n        $blueprint->string('my_other_column')->storedAsJson('my_json_column->some_attribute->nested');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"my_json_column\" varchar not null, \"my_other_column\" varchar as (json_extract(\"my_json_column\", \\'$.\"some_attribute\".\"nested\"\\')) stored)', $statements[0]);\n    }\n\n    public function testDroppingColumnsWorks()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users', function ($table) {\n            $table->dropColumn('name');\n        });\n\n        $this->assertEquals(['alter table \"users\" drop column \"name\"'], $blueprint->toSql());\n    }\n\n    public function testRenamingAndChangingColumnsWork()\n    {\n        $builder = mock(SQLiteBuilder::class)\n            ->makePartial()\n            ->shouldReceive('getColumns')->andReturn([\n                ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => false, 'default' => null, 'auto_increment' => false, 'comment' => null, 'generation' => null],\n                ['name' => 'age', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => false, 'default' => null, 'auto_increment' => false, 'comment' => null, 'generation' => null],\n            ])\n            ->shouldReceive('getIndexes')->andReturn([])\n            ->shouldReceive('getForeignKeys')->andReturn([])\n            ->getMock();\n\n        $connection = $this->getConnection(builder: $builder);\n        $connection->shouldReceive('scalar')->with('pragma foreign_keys')->andReturn(false);\n\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->renameColumn('name', 'first_name');\n        $blueprint->integer('age')->change();\n\n        $this->assertEquals([\n            'alter table \"users\" rename column \"name\" to \"first_name\"',\n            'create table \"__temp__users\" (\"first_name\" varchar not null, \"age\" integer not null)',\n            'insert into \"__temp__users\" (\"first_name\", \"age\") select \"first_name\", \"age\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ], $blueprint->toSql());\n    }\n\n    public function testRenamingAndChangingColumnsWorkWithSchema()\n    {\n        $builder = mock(SQLiteBuilder::class)\n            ->makePartial()\n            ->shouldReceive('getColumns')->andReturn([\n                ['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => false, 'default' => null, 'auto_increment' => false, 'comment' => null, 'generation' => null],\n                ['name' => 'age', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => false, 'default' => null, 'auto_increment' => false, 'comment' => null, 'generation' => null],\n            ])\n            ->shouldReceive('getIndexes')->andReturn([])\n            ->shouldReceive('getForeignKeys')->andReturn([])\n            ->getMock();\n\n        $connection = $this->getConnection(builder: $builder);\n        $connection->shouldReceive('scalar')->with('pragma foreign_keys')->andReturn(false);\n\n        $blueprint = new Blueprint($connection, 'my_schema.users');\n        $blueprint->renameColumn('name', 'first_name');\n        $blueprint->integer('age')->change();\n\n        $this->assertEquals([\n            'alter table \"my_schema\".\"users\" rename column \"name\" to \"first_name\"',\n            'create table \"my_schema\".\"__temp__users\" (\"first_name\" varchar not null, \"age\" integer not null)',\n            'insert into \"my_schema\".\"__temp__users\" (\"first_name\", \"age\") select \"first_name\", \"age\" from \"my_schema\".\"users\"',\n            'drop table \"my_schema\".\"users\"',\n            'alter table \"my_schema\".\"__temp__users\" rename to \"users\"',\n        ], $blueprint->toSql());\n    }\n\n    protected function getConnection(\n        ?SQLiteGrammar $grammar = null,\n        ?SQLiteBuilder $builder = null,\n        $prefix = ''\n    ) {\n        $connection = m::mock(Connection::class);\n        $grammar ??= $this->getGrammar($connection);\n        $builder ??= $this->getBuilder();\n\n        return $connection\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->andReturn(null)\n            ->shouldReceive('getSchemaGrammar')->andReturn($grammar)\n            ->shouldReceive('getSchemaBuilder')->andReturn($builder)\n            ->shouldReceive('getServerVersion')->andReturn('3.35')\n            ->getMock();\n    }\n\n    public function getGrammar(?Connection $connection = null)\n    {\n        return new SQLiteGrammar($connection ?? $this->getConnection());\n    }\n\n    public function getBuilder()\n    {\n        return mock(SQLiteBuilder::class)\n            ->makePartial()\n            ->shouldReceive('getColumns')->andReturn([])\n            ->shouldReceive('getIndexes')->andReturn([])\n            ->shouldReceive('getForeignKeys')->andReturn([])\n            ->getMock();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSchemaBlueprintTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Database\\Schema\\Grammars\\MySqlGrammar;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\User;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSchemaBlueprintTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Builder::$defaultMorphKeyType = 'int';\n\n        parent::tearDown();\n    }\n\n    public function testToSqlRunsCommandsFromBlueprint()\n    {\n        $conn = $this->getConnection();\n        $conn->shouldReceive('statement')->once()->with('foo');\n        $conn->shouldReceive('statement')->once()->with('bar');\n        $blueprint = $this->getMockBuilder(Blueprint::class)->onlyMethods(['toSql'])->setConstructorArgs([$conn, 'users'])->getMock();\n        $blueprint->expects($this->once())->method('toSql')->willReturn(['foo', 'bar']);\n\n        $blueprint->build();\n    }\n\n    public function testIndexDefaultNames()\n    {\n        $blueprint = $this->getBlueprint(table: 'users');\n        $blueprint->unique(['foo', 'bar']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('users_foo_bar_unique', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'users');\n        $blueprint->index('foo');\n        $commands = $blueprint->getCommands();\n        $this->assertSame('users_foo_index', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $commands = $blueprint->getCommands();\n        $this->assertSame('geo_coordinates_spatialindex', $commands[0]->index);\n    }\n\n    public function testIndexDefaultNamesWhenPrefixSupplied()\n    {\n        $blueprint = $this->getBlueprint(table: 'users', prefix: 'prefix_');\n        $blueprint->unique(['foo', 'bar']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_users_foo_bar_unique', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'users', prefix: 'prefix_');\n        $blueprint->index('foo');\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_users_foo_index', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'geo', prefix: 'prefix_');\n        $blueprint->spatialIndex('coordinates');\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_geo_coordinates_spatialindex', $commands[0]->index);\n    }\n\n    public function testDropIndexDefaultNames()\n    {\n        $blueprint = $this->getBlueprint(table: 'users');\n        $blueprint->dropUnique(['foo', 'bar']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('users_foo_bar_unique', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'users');\n        $blueprint->dropIndex(['foo']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('users_foo_index', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('geo_coordinates_spatialindex', $commands[0]->index);\n    }\n\n    public function testDropIndexDefaultNamesWhenPrefixSupplied()\n    {\n        $blueprint = $this->getBlueprint(table: 'users', prefix: 'prefix_');\n        $blueprint->dropUnique(['foo', 'bar']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_users_foo_bar_unique', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'users', prefix: 'prefix_');\n        $blueprint->dropIndex(['foo']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_users_foo_index', $commands[0]->index);\n\n        $blueprint = $this->getBlueprint(table: 'geo', prefix: 'prefix_');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $commands = $blueprint->getCommands();\n        $this->assertSame('prefix_geo_coordinates_spatialindex', $commands[0]->index);\n    }\n\n    public function testDefaultCurrentDate()\n    {\n        $getSql = function ($grammar, $mysql57 = false) {\n            if ($grammar == 'MySql') {\n                $connection = $this->getConnection($grammar);\n                $mysql57 ? $connection->shouldReceive('getServerVersion')->andReturn('5.7') : $connection->shouldReceive('getServerVersion')->andReturn('8.0.13');\n                $connection->shouldReceive('isMaria')->andReturn(false);\n\n                return (new Blueprint($connection, 'users', function ($table) {\n                    $table->date('created')->useCurrent();\n                }))->toSql();\n            } else {\n                return $this->getBlueprint($grammar, 'users', function ($table) {\n                    $table->date('created')->useCurrent();\n                })->toSql();\n            }\n        };\n\n        $this->assertEquals(['alter table `users` add `created` date not null default (CURDATE())'], $getSql('MySql'));\n        $this->assertEquals(['alter table `users` add `created` date not null'], $getSql('MySql', mysql57: true));\n        $this->assertEquals(['alter table \"users\" add column \"created\" date not null default CURRENT_DATE'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" add column \"created\" date not null default CURRENT_DATE'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"users\" add \"created\" date not null default CAST(GETDATE() AS DATE)'], $getSql('SqlServer'));\n    }\n\n    public function testDefaultCurrentDateTime()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->dateTime('created')->useCurrent();\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `users` add `created` datetime not null default CURRENT_TIMESTAMP'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"users\" add column \"created\" timestamp(0) without time zone not null default CURRENT_TIMESTAMP'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" add column \"created\" datetime not null default CURRENT_TIMESTAMP'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"users\" add \"created\" datetime not null default CURRENT_TIMESTAMP'], $getSql('SqlServer'));\n    }\n\n    public function testDefaultCurrentTimestamp()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->timestamp('created')->useCurrent();\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `users` add `created` timestamp not null default CURRENT_TIMESTAMP'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"users\" add column \"created\" timestamp(0) without time zone not null default CURRENT_TIMESTAMP'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" add column \"created\" datetime not null default CURRENT_TIMESTAMP'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"users\" add \"created\" datetime not null default CURRENT_TIMESTAMP'], $getSql('SqlServer'));\n    }\n\n    public function testDefaultCurrentYear()\n    {\n        $getSql = function ($grammar, $mysql57 = false) {\n            if ($grammar == 'MySql') {\n                $connection = $this->getConnection($grammar);\n                $mysql57 ? $connection->shouldReceive('getServerVersion')->andReturn('5.7') : $connection->shouldReceive('getServerVersion')->andReturn('8.0.13');\n                $connection->shouldReceive('isMaria')->andReturn(false);\n\n                return (new Blueprint($connection, 'users', function ($table) {\n                    $table->year('birth_year')->useCurrent();\n                }))->toSql();\n            } else {\n                return $this->getBlueprint($grammar, 'users', function ($table) {\n                    $table->year('birth_year')->useCurrent();\n                })->toSql();\n            }\n        };\n\n        $this->assertEquals(['alter table `users` add `birth_year` year not null default (YEAR(CURDATE()))'], $getSql('MySql'));\n        $this->assertEquals(['alter table `users` add `birth_year` year not null'], $getSql('MySql', mysql57: true));\n        $this->assertEquals(['alter table \"users\" add column \"birth_year\" integer not null default EXTRACT(YEAR FROM CURRENT_DATE)'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" add column \"birth_year\" integer not null default (CAST(strftime(\\'%Y\\', \\'now\\') AS INTEGER))'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"users\" add \"birth_year\" int not null default CAST(YEAR(GETDATE()) AS INTEGER)'], $getSql('SqlServer'));\n    }\n\n    public function testRemoveColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->string('foo');\n                $table->string('remove_this');\n                $table->removeColumn('remove_this');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `users` add `foo` varchar(255) not null'], $getSql('MySql'));\n    }\n\n    public function testRenameColumn()\n    {\n        $getSql = function ($grammar) {\n            $connection = $this->getConnection($grammar);\n            $connection->shouldReceive('getServerVersion')->andReturn('8.0.4');\n            $connection->shouldReceive('isMaria')->andReturn(false);\n\n            return (new Blueprint($connection, 'users', function ($table) {\n                $table->renameColumn('foo', 'bar');\n            }))->toSql();\n        };\n\n        $this->assertEquals(['alter table `users` rename column `foo` to `bar`'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"users\" rename column \"foo\" to \"bar\"'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" rename column \"foo\" to \"bar\"'], $getSql('SQLite'));\n        $this->assertEquals(['sp_rename N\\'\"users\".\"foo\"\\', \"bar\", N\\'COLUMN\\''], $getSql('SqlServer'));\n    }\n\n    public function testNativeRenameColumnOnMysql57()\n    {\n        $connection = $this->getConnection('MySql');\n        $connection->shouldReceive('isMaria')->andReturn(false);\n        $connection->shouldReceive('getServerVersion')->andReturn('5.7');\n        $connection->getSchemaBuilder()->shouldReceive('getColumns')->andReturn([\n            ['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false, 'generation' => null],\n            ['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true, 'generation' => null],\n            ['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],\n        ]);\n\n        $blueprint = new Blueprint($connection, 'users', function ($table) {\n            $table->renameColumn('name', 'title');\n            $table->renameColumn('id', 'key');\n            $table->renameColumn('generated', 'new_generated');\n        });\n\n        $this->assertEquals([\n            \"alter table `users` change `name` `title` varchar(255) collate 'utf8mb4_unicode_ci' null default 'foo'\",\n            \"alter table `users` change `id` `key` bigint unsigned not null auto_increment comment 'lorem ipsum'\",\n            'alter table `users` change `generated` `new_generated` int as (expression) stored not null',\n        ], $blueprint->toSql());\n    }\n\n    public function testNativeRenameColumnOnLegacyMariaDB()\n    {\n        $connection = $this->getConnection('MariaDb');\n        $connection->shouldReceive('isMaria')->andReturn(true);\n        $connection->shouldReceive('getServerVersion')->andReturn('10.1.35');\n        $connection->getSchemaBuilder()->shouldReceive('getColumns')->andReturn([\n            ['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false, 'generation' => null],\n            ['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true, 'generation' => null],\n            ['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],\n            ['name' => 'foo', 'type' => 'int', 'type_name' => 'int', 'nullable' => true, 'collation' => null, 'default' => 'NULL', 'comment' => null, 'auto_increment' => false, 'generation' => null],\n        ]);\n\n        $blueprint = new Blueprint($connection, 'users', function ($table) {\n            $table->renameColumn('name', 'title');\n            $table->renameColumn('id', 'key');\n            $table->renameColumn('generated', 'new_generated');\n            $table->renameColumn('foo', 'bar');\n        });\n\n        $this->assertEquals([\n            \"alter table `users` change `name` `title` varchar(255) collate 'utf8mb4_unicode_ci' null default 'foo'\",\n            \"alter table `users` change `id` `key` bigint unsigned not null auto_increment comment 'lorem ipsum'\",\n            'alter table `users` change `generated` `new_generated` int as (expression) stored not null',\n            'alter table `users` change `foo` `bar` int null default NULL',\n        ], $blueprint->toSql());\n    }\n\n    public function testDropColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->dropColumn('foo');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `users` drop `foo`'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"users\" drop column \"foo\"'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"users\" drop column \"foo\"'], $getSql('SQLite'));\n        $this->assertStringContainsString('alter table \"users\" drop column \"foo\"', $getSql('SqlServer')[0]);\n    }\n\n    public function testNativeColumnModifyingOnMySql()\n    {\n        $blueprint = $this->getBlueprint('MySql', 'users', function ($table) {\n            $table->double('amount')->nullable()->invisible()->after('name')->change();\n            $table->timestamp('added_at', 4)->nullable(false)->useCurrent()->useCurrentOnUpdate()->change();\n            $table->enum('difficulty', ['easy', 'hard'])->default('easy')->charset('utf8mb4')->collation('unicode')->change();\n            $table->geometry('positions', 'multipolygon', 1234)->storedAs('expression')->change();\n            $table->string('old_name', 50)->renameTo('new_name')->change();\n            $table->bigIncrements('id')->first()->from(10)->comment('my comment')->change();\n        });\n\n        $this->assertEquals([\n            'alter table `users` modify `amount` double null invisible after `name`',\n            'alter table `users` modify `added_at` timestamp(4) not null default CURRENT_TIMESTAMP(4) on update CURRENT_TIMESTAMP(4)',\n            \"alter table `users` modify `difficulty` enum('easy', 'hard') character set utf8mb4 collate 'unicode' not null default 'easy'\",\n            'alter table `users` modify `positions` multipolygon srid 1234 as (expression) stored',\n            'alter table `users` change `old_name` `new_name` varchar(50) not null',\n            \"alter table `users` modify `id` bigint unsigned not null auto_increment comment 'my comment' first\",\n            'alter table `users` auto_increment = 10',\n        ], $blueprint->toSql());\n    }\n\n    public function testMacroable()\n    {\n        Blueprint::macro('foo', function () {\n            return $this->addCommand('foo');\n        });\n\n        MySqlGrammar::macro('compileFoo', function () {\n            return 'bar';\n        });\n\n        $blueprint = $this->getBlueprint('MySql', 'users', function ($table) {\n            $table->foo();\n        });\n\n        $this->assertEquals(['bar'], $blueprint->toSql());\n    }\n\n    public function testDefaultUsingIdMorph()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->morphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) not null',\n            'alter table `comments` add `commentable_id` bigint unsigned not null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDefaultUsingNullableIdMorph()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->nullableMorphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) null',\n            'alter table `comments` add `commentable_id` bigint unsigned null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDefaultUsingUuidMorph()\n    {\n        Builder::defaultMorphKeyType('uuid');\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->morphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) not null',\n            'alter table `comments` add `commentable_id` char(36) not null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDefaultUsingNullableUuidMorph()\n    {\n        Builder::defaultMorphKeyType('uuid');\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->nullableMorphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) null',\n            'alter table `comments` add `commentable_id` char(36) null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDefaultUsingUlidMorph()\n    {\n        Builder::defaultMorphKeyType('ulid');\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->morphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) not null',\n            'alter table `comments` add `commentable_id` char(26) not null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDefaultUsingNullableUlidMorph()\n    {\n        Builder::defaultMorphKeyType('ulid');\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'comments', function ($table) {\n                $table->nullableMorphs('commentable');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `comments` add `commentable_type` varchar(255) null',\n            'alter table `comments` add `commentable_id` char(26) null',\n            'alter table `comments` add index `comments_commentable_type_commentable_id_index`(`commentable_type`, `commentable_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipColumnWithIncrementalModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor('Illuminate\\Foundation\\Auth\\User');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `user_id` bigint unsigned not null',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipColumnWithNonIncrementalModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor(Fixtures\\Models\\EloquentModelUsingNonIncrementedInt::class);\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `model_using_non_incremented_int_id` bigint unsigned not null',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipColumnWithUuidModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor(Fixtures\\Models\\EloquentModelUsingUuid::class);\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `model_using_uuid_id` char(36) not null',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipColumnWithUlidModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor(Fixtures\\Models\\EloquentModelUsingUlid::class);\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table \"posts\" add column \"model_using_ulid_id\" char(26) not null',\n        ], $getSql('Postgres'));\n\n        $this->assertEquals([\n            'alter table `posts` add `model_using_ulid_id` char(26) not null',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipConstrainedColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor('Illuminate\\Foundation\\Auth\\User')->constrained();\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `user_id` bigint unsigned not null',\n            'alter table `posts` add constraint `posts_user_id_foreign` foreign key (`user_id`) references `users` (`id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testGenerateRelationshipForModelWithNonStandardPrimaryKeyName()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->foreignIdFor(User::class)->constrained();\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `user_internal_id` bigint unsigned not null',\n            'alter table `posts` add constraint `posts_user_internal_id_foreign` foreign key (`user_internal_id`) references `users` (`internal_id`)',\n        ], $getSql('MySql'));\n    }\n\n    public function testDropRelationshipColumnWithIncrementalModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->dropForeignIdFor('Illuminate\\Foundation\\Auth\\User');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` drop `user_id`',\n        ], $getSql('MySql'));\n    }\n\n    public function testDropRelationshipColumnWithUuidModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->dropForeignIdFor(Fixtures\\Models\\EloquentModelUsingUuid::class);\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` drop `model_using_uuid_id`',\n        ], $getSql('MySql'));\n    }\n\n    public function testDropConstrainedRelationshipColumnWithIncrementalModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->dropConstrainedForeignIdFor('Illuminate\\Foundation\\Auth\\User');\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` drop foreign key `posts_user_id_foreign`',\n            'alter table `posts` drop `user_id`',\n        ], $getSql('MySql'));\n    }\n\n    public function testDropConstrainedRelationshipColumnWithUuidModel()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->dropConstrainedForeignIdFor(Fixtures\\Models\\EloquentModelUsingUuid::class);\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` drop foreign key `posts_model_using_uuid_id_foreign`',\n            'alter table `posts` drop `model_using_uuid_id`',\n        ], $getSql('MySql'));\n    }\n\n    public function testTinyTextColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->tinyText('note');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `posts` add `note` tinytext not null'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"posts\" add column \"note\" text not null'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"posts\" add column \"note\" varchar(255) not null'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"posts\" add \"note\" nvarchar(255) not null'], $getSql('SqlServer'));\n    }\n\n    public function testTinyTextNullableColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->tinyText('note')->nullable();\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `posts` add `note` tinytext null'], $getSql('MySql'));\n        $this->assertEquals(['alter table \"posts\" add column \"note\" text'], $getSql('SQLite'));\n        $this->assertEquals(['alter table \"posts\" add column \"note\" varchar(255) null'], $getSql('Postgres'));\n        $this->assertEquals(['alter table \"posts\" add \"note\" nvarchar(255) null'], $getSql('SqlServer'));\n    }\n\n    public function testRawColumn()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->rawColumn('legacy_boolean', 'INT(1)')->nullable();\n            })->toSql();\n        };\n\n        $this->assertEquals([\n            'alter table `posts` add `legacy_boolean` INT(1) null',\n        ], $getSql('MySql'));\n\n        $this->assertEquals([\n            'alter table \"posts\" add column \"legacy_boolean\" INT(1)',\n        ], $getSql('SQLite'));\n\n        $this->assertEquals([\n            'alter table \"posts\" add column \"legacy_boolean\" INT(1) null',\n        ], $getSql('Postgres'));\n\n        $this->assertEquals([\n            'alter table \"posts\" add \"legacy_boolean\" INT(1) null',\n        ], $getSql('SqlServer'));\n    }\n\n    public function testTableComment()\n    {\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->comment('Look at my comment, it is amazing');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `posts` comment = \\'Look at my comment, it is amazing\\''], $getSql('MySql'));\n        $this->assertEquals(['comment on table \"posts\" is \\'Look at my comment, it is amazing\\''], $getSql('Postgres'));\n    }\n\n    public function testColumnDefault()\n    {\n        // Test a normal string literal column default.\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->tinyText('note')->default('this will work');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `posts` add `note` tinytext not null default \\'this will work\\''], $getSql('MySql'));\n\n        // Test a string literal column default containing an apostrophe (#56124)\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $table->tinyText('note')->default('this\\'ll work too');\n            })->toSql();\n        };\n\n        $this->assertEquals(['alter table `posts` add `note` tinytext not null default \\'this\\'\\'ll work too\\''], $getSql('MySql'));\n\n        // Test a backed enumeration column default\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $enum = ApostropheBackedEnum::ValueWithoutApostrophe;\n                $table->tinyText('note')->default($enum);\n            })->toSql();\n        };\n        $this->assertEquals(['alter table `posts` add `note` tinytext not null default \\'this will work\\''], $getSql('MySql'));\n\n        // Test a backed enumeration column default containing an apostrophe (#56124)\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'posts', function ($table) {\n                $enum = ApostropheBackedEnum::ValueWithApostrophe;\n                $table->tinyText('note')->default($enum);\n            })->toSql();\n        };\n        $this->assertEquals(['alter table `posts` add `note` tinytext not null default \\'this\\'\\'ll work too\\''], $getSql('MySql'));\n    }\n\n    protected function getConnection(?string $grammar = null, string $prefix = '')\n    {\n        $connection = m::mock(Connection::class)\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->with('prefix_indexes')->andReturn(true)\n            ->getMock();\n\n        $grammar ??= 'MySql';\n        $grammarClass = 'Illuminate\\Database\\Schema\\Grammars\\\\'.$grammar.'Grammar';\n        $builderClass = 'Illuminate\\Database\\Schema\\\\'.$grammar.'Builder';\n\n        $connection->shouldReceive('getSchemaGrammar')->andReturn(new $grammarClass($connection));\n        $connection->shouldReceive('getSchemaBuilder')->andReturn(m::mock($builderClass));\n\n        if ($grammar === 'SQLite') {\n            $connection->shouldReceive('getServerVersion')->andReturn('3.35');\n        }\n\n        if ($grammar === 'MySql') {\n            $connection->shouldReceive('isMaria')->andReturn(false);\n        }\n\n        return $connection;\n    }\n\n    protected function getBlueprint(\n        ?string $grammar = null,\n        string $table = '',\n        ?Closure $callback = null,\n        string $prefix = ''\n    ): Blueprint {\n        $connection = $this->getConnection($grammar, $prefix);\n\n        return new Blueprint($connection, $table, $callback);\n    }\n}\n\nenum ApostropheBackedEnum: string\n{\n    case ValueWithoutApostrophe = 'this will work';\n    case ValueWithApostrophe = 'this\\'ll work too';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSchemaBuilderIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Facade;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSchemaBuilderIntegrationTest extends TestCase\n{\n    protected $db;\n\n    /**\n     * Bootstrap database.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $this->db = $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->setAsGlobal();\n\n        $container = new Container;\n        $container->instance('db', $db->getDatabaseManager());\n        Facade::setFacadeApplication($container);\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::clearResolvedInstances();\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function testHasColumnWithTablePrefix()\n    {\n        $this->db->connection()->setTablePrefix('test_');\n\n        $this->db->connection()->getSchemaBuilder()->create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n        });\n\n        $this->assertTrue($this->db->connection()->getSchemaBuilder()->hasColumn('table1', 'name'));\n    }\n\n    public function testHasColumnAndIndexWithPrefixIndexDisabled()\n    {\n        $this->db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => 'example_',\n            'prefix_indexes' => false,\n        ]);\n\n        $this->schemaBuilder()->create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name')->index();\n        });\n\n        $this->assertTrue($this->schemaBuilder()->hasIndex('table1', 'table1_name_index'));\n    }\n\n    public function testHasColumnAndIndexWithPrefixIndexEnabled()\n    {\n        $this->db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => 'example_',\n            'prefix_indexes' => true,\n        ]);\n\n        $this->schemaBuilder()->create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name')->index();\n        });\n\n        $this->assertTrue($this->schemaBuilder()->hasIndex('table1', 'example_table1_name_index'));\n    }\n\n    public function testDropColumnWithTablePrefix()\n    {\n        $this->db->connection()->setTablePrefix('test_');\n\n        $this->schemaBuilder()->create('pandemic_table', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('stay_home');\n            $table->string('covid19');\n            $table->string('wear_mask');\n        });\n\n        // drop single columns\n        $this->assertTrue($this->schemaBuilder()->hasColumn('pandemic_table', 'stay_home'));\n        $this->schemaBuilder()->dropColumns('pandemic_table', 'stay_home');\n        $this->assertFalse($this->schemaBuilder()->hasColumn('pandemic_table', 'stay_home'));\n\n        // drop multiple columns\n        $this->assertTrue($this->schemaBuilder()->hasColumn('pandemic_table', 'covid19'));\n        $this->schemaBuilder()->dropColumns('pandemic_table', ['covid19', 'wear_mask']);\n        $this->assertFalse($this->schemaBuilder()->hasColumn('pandemic_table', 'wear_mask'));\n        $this->assertFalse($this->schemaBuilder()->hasColumn('pandemic_table', 'covid19'));\n    }\n\n    private function schemaBuilder()\n    {\n        return $this->db->connection()->getSchemaBuilder();\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Database\\Schema\\Grammars\\Grammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseSchemaBuilderTest extends TestCase\n{\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(stdClass::class);\n        $grammar->shouldReceive('compileCreateDatabase')->andReturn('sql');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('statement')->with('sql')->andReturnTrue();\n        $builder = new Builder($connection);\n\n        $this->assertTrue($builder->createDatabase('foo'));\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(stdClass::class);\n        $grammar->shouldReceive('compileDropDatabaseIfExists')->andReturn('sql');\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('statement')->with('sql')->andReturnTrue();\n        $builder = new Builder($connection);\n\n        $this->assertTrue($builder->dropDatabaseIfExists('foo'));\n    }\n\n    public function testHasTableCorrectlyCallsGrammar()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(Grammar::class);\n        $processor = m::mock(Processor::class);\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $builder = new Builder($connection);\n        $grammar->shouldReceive('compileTableExists');\n        $grammar->shouldReceive('compileTables')->once()->andReturn('sql');\n        $processor->shouldReceive('processTables')->once()->andReturn([['name' => 'prefix_table']]);\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql')->andReturn([['name' => 'prefix_table']]);\n\n        $this->assertTrue($builder->hasTable('table'));\n    }\n\n    public function testTableHasColumns()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(stdClass::class);\n        $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar);\n        $builder = m::mock(Builder::class.'[getColumnListing]', [$connection]);\n        $builder->shouldReceive('getColumnListing')->with('users')->twice()->andReturn(['id', 'firstname']);\n\n        $this->assertTrue($builder->hasColumns('users', ['id', 'firstname']));\n        $this->assertFalse($builder->hasColumns('users', ['id', 'address']));\n    }\n\n    public function testGetColumnTypeAddsPrefix()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = m::mock(Grammar::class);\n        $processor = m::mock(Processor::class);\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('getPostProcessor')->andReturn($processor);\n        $processor->shouldReceive('processColumns')->once()->andReturn([['name' => 'id', 'type_name' => 'integer']]);\n        $builder = new Builder($connection);\n        $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_');\n        $grammar->shouldReceive('compileColumns')->once()->with(null, 'prefix_users')->andReturn('sql');\n        $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql')->andReturn([['name' => 'id', 'type_name' => 'integer']]);\n\n        $this->assertSame('integer', $builder->getColumnType('users', 'id'));\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSeederTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Seeder;\nuse Mockery as m;\nuse Mockery\\Mock;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass TestSeeder extends Seeder\n{\n    public function run()\n    {\n        //\n    }\n}\n\nclass TestDepsSeeder extends Seeder\n{\n    public function run(Mock $someDependency, $someParam = '')\n    {\n        //\n    }\n}\n\nclass DatabaseSeederTest extends TestCase\n{\n    public function testCallResolveTheClassAndCallsRun()\n    {\n        $seeder = new TestSeeder;\n        $seeder->setContainer($container = m::mock(Container::class));\n        $output = m::mock(OutputInterface::class);\n        $output->shouldReceive('writeln')->times(3);\n        $command = m::mock(Command::class);\n        $command->shouldReceive('getOutput')->times(3)->andReturn($output);\n        $seeder->setCommand($command);\n        $container->shouldReceive('make')->once()->with('ClassName')->andReturn($child = m::mock(Seeder::class));\n        $child->shouldReceive('setContainer')->once()->with($container)->andReturn($child);\n        $child->shouldReceive('setCommand')->once()->with($command)->andReturn($child);\n        $child->shouldReceive('__invoke')->once();\n\n        $seeder->call('ClassName');\n    }\n\n    public function testSetContainer()\n    {\n        $seeder = new TestSeeder;\n        $container = m::mock(Container::class);\n        $this->assertEquals($seeder->setContainer($container), $seeder);\n    }\n\n    public function testSetCommand()\n    {\n        $seeder = new TestSeeder;\n        $command = m::mock(Command::class);\n        $this->assertEquals($seeder->setCommand($command), $seeder);\n    }\n\n    public function testInjectDependenciesOnRunMethod()\n    {\n        $container = m::mock(Container::class);\n        $container->shouldReceive('call');\n\n        $seeder = new TestDepsSeeder;\n        $seeder->setContainer($container);\n\n        $seeder->__invoke();\n\n        $container->shouldHaveReceived('call')->once()->with([$seeder, 'run'], []);\n    }\n\n    public function testSendParamsOnCallMethodWithDeps()\n    {\n        $container = m::mock(Container::class);\n        $container->shouldReceive('call');\n\n        $seeder = new TestDepsSeeder;\n        $seeder->setContainer($container);\n\n        $seeder->__invoke(['test1', 'test2']);\n\n        $container->shouldHaveReceived('call')->once()->with([$seeder, 'run'], ['test1', 'test2']);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSoftDeletingScopeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\ConnectionInterface;\nuse Illuminate\\Database\\Eloquent\\Builder as EloquentBuilder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletingScope;\nuse Illuminate\\Database\\Query\\Builder as BaseBuilder;\nuse Illuminate\\Database\\Query\\Grammars\\Grammar;\nuse Illuminate\\Database\\Query\\Processors\\Processor;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseSoftDeletingScopeTest extends TestCase\n{\n    public function testApplyingScopeToABuilder()\n    {\n        $scope = m::mock(SoftDeletingScope::class.'[extend]');\n        $builder = m::mock(EloquentBuilder::class);\n        $model = m::mock(Model::class);\n        $model->shouldReceive('getQualifiedDeletedAtColumn')->once()->andReturn('table.deleted_at');\n        $builder->shouldReceive('whereNull')->once()->with('table.deleted_at');\n\n        $scope->apply($builder, $model);\n    }\n\n    public function testRestoreExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n        $scope = new SoftDeletingScope;\n        $scope->extend($builder);\n        $callback = $builder->getMacro('restore');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('withTrashed')->once();\n        $givenBuilder->shouldReceive('getModel')->once()->andReturn($model = m::mock(stdClass::class));\n        $model->shouldReceive('getDeletedAtColumn')->once()->andReturn('deleted_at');\n        $givenBuilder->shouldReceive('update')->once()->with(['deleted_at' => null]);\n\n        $callback($givenBuilder);\n    }\n\n    public function testRestoreOrCreateExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n\n        $scope = new SoftDeletingScope;\n        $scope->extend($builder);\n        $callback = $builder->getMacro('restoreOrCreate');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('withTrashed')->once();\n        $attributes = ['name' => 'foo'];\n        $values = ['email' => 'bar'];\n        $givenBuilder->shouldReceive('firstOrCreate')->once()->with($attributes, $values)->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('restore')->once()->andReturn(true);\n        $result = $callback($givenBuilder, $attributes, $values);\n\n        $this->assertEquals($model, $result);\n    }\n\n    public function testCreateOrRestoreExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n\n        $scope = new SoftDeletingScope;\n        $scope->extend($builder);\n        $callback = $builder->getMacro('createOrRestore');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('withTrashed')->once();\n        $attributes = ['name' => 'foo'];\n        $values = ['email' => 'bar'];\n        $givenBuilder->shouldReceive('createOrFirst')->once()->with($attributes, $values)->andReturn($model = m::mock(Model::class));\n        $model->shouldReceive('restore')->once()->andReturn(true);\n        $result = $callback($givenBuilder, $attributes, $values);\n\n        $this->assertEquals($model, $result);\n    }\n\n    public function testWithTrashedExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n        $scope = m::mock(SoftDeletingScope::class.'[remove]');\n        $scope->extend($builder);\n        $callback = $builder->getMacro('withTrashed');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('getModel')->andReturn($model = m::mock(Model::class));\n        $givenBuilder->shouldReceive('withoutGlobalScope')->with($scope)->andReturn($givenBuilder);\n        $result = $callback($givenBuilder);\n\n        $this->assertEquals($givenBuilder, $result);\n    }\n\n    public function testOnlyTrashedExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n        $model = m::mock(Model::class);\n        $model->makePartial();\n        $scope = m::mock(SoftDeletingScope::class.'[remove]');\n        $scope->extend($builder);\n        $callback = $builder->getMacro('onlyTrashed');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('getQuery')->andReturn($query = m::mock(stdClass::class));\n        $givenBuilder->shouldReceive('getModel')->andReturn($model);\n        $givenBuilder->shouldReceive('withoutGlobalScope')->with($scope)->andReturn($givenBuilder);\n        $model->shouldReceive('getQualifiedDeletedAtColumn')->andReturn('table.deleted_at');\n        $givenBuilder->shouldReceive('whereNotNull')->once()->with('table.deleted_at');\n        $result = $callback($givenBuilder);\n\n        $this->assertEquals($givenBuilder, $result);\n    }\n\n    public function testWithoutTrashedExtension()\n    {\n        $builder = new EloquentBuilder(new BaseBuilder(\n            m::mock(ConnectionInterface::class),\n            m::mock(Grammar::class),\n            m::mock(Processor::class)\n        ));\n        $model = m::mock(Model::class);\n        $model->makePartial();\n        $scope = m::mock(SoftDeletingScope::class.'[remove]');\n        $scope->extend($builder);\n        $callback = $builder->getMacro('withoutTrashed');\n        $givenBuilder = m::mock(EloquentBuilder::class);\n        $givenBuilder->shouldReceive('getQuery')->andReturn($query = m::mock(stdClass::class));\n        $givenBuilder->shouldReceive('getModel')->andReturn($model);\n        $givenBuilder->shouldReceive('withoutGlobalScope')->with($scope)->andReturn($givenBuilder);\n        $model->shouldReceive('getQualifiedDeletedAtColumn')->andReturn('table.deleted_at');\n        $givenBuilder->shouldReceive('whereNull')->once()->with('table.deleted_at');\n        $result = $callback($givenBuilder);\n\n        $this->assertEquals($givenBuilder, $result);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSoftDeletingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSoftDeletingTest extends TestCase\n{\n    public function testDeletedAtIsAddedToCastsAsDefaultType()\n    {\n        $model = new SoftDeletingModel;\n\n        $this->assertArrayHasKey('deleted_at', $model->getCasts());\n        $this->assertSame('datetime', $model->getCasts()['deleted_at']);\n    }\n\n    public function testDeletedAtIsCastToCarbonInstance()\n    {\n        $expected = Carbon::createFromFormat('Y-m-d H:i:s', '2018-12-29 13:59:39');\n        $model = new SoftDeletingModel(['deleted_at' => $expected->format('Y-m-d H:i:s')]);\n\n        $this->assertInstanceOf(Carbon::class, $model->deleted_at);\n        $this->assertTrue($expected->eq($model->deleted_at));\n    }\n\n    public function testExistingCastOverridesAddedDateCast()\n    {\n        $model = new class(['deleted_at' => '2018-12-29 13:59:39']) extends SoftDeletingModel\n        {\n            protected $casts = ['deleted_at' => 'bool'];\n        };\n\n        $this->assertTrue($model->deleted_at);\n    }\n\n    public function testExistingMutatorOverridesAddedDateCast()\n    {\n        $model = new class(['deleted_at' => '2018-12-29 13:59:39']) extends SoftDeletingModel\n        {\n            protected function getDeletedAtAttribute()\n            {\n                return 'expected';\n            }\n        };\n\n        $this->assertSame('expected', $model->deleted_at);\n    }\n\n    public function testCastingToStringOverridesAutomaticDateCastingToRetainPreviousBehaviour()\n    {\n        $model = new class(['deleted_at' => '2018-12-29 13:59:39']) extends SoftDeletingModel\n        {\n            protected $casts = ['deleted_at' => 'string'];\n        };\n\n        $this->assertSame('2018-12-29 13:59:39', $model->deleted_at);\n    }\n}\n\nclass SoftDeletingModel extends Model\n{\n    use SoftDeletes;\n\n    protected $guarded = [];\n\n    protected $dateFormat = 'Y-m-d H:i:s';\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSoftDeletingTraitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass DatabaseSoftDeletingTraitTest extends TestCase\n{\n    public function testDeleteSetsSoftDeletedColumn()\n    {\n        $model = m::mock(DatabaseSoftDeletingTraitStub::class);\n        $model->makePartial();\n        $model->shouldReceive('newModelQuery')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('where')->once()->with('id', '=', 1)->andReturn($query);\n        $query->shouldReceive('update')->once()->with([\n            'deleted_at' => 'date-time',\n            'updated_at' => 'date-time',\n        ]);\n        $model->shouldReceive('syncOriginalAttributes')->once()->with([\n            'deleted_at',\n            'updated_at',\n        ]);\n        $model->shouldReceive('usesTimestamps')->once()->andReturn(true);\n        $model->delete();\n\n        $this->assertInstanceOf(Carbon::class, $model->deleted_at);\n    }\n\n    public function testRestore()\n    {\n        $model = m::mock(DatabaseSoftDeletingTraitStub::class);\n        $model->makePartial();\n        $model->shouldReceive('fireModelEvent')->with('restoring')->andReturn(true);\n        $model->shouldReceive('save')->once();\n        $model->shouldReceive('fireModelEvent')->with('restored', false)->andReturn(true);\n\n        $model->restore();\n\n        $this->assertNull($model->deleted_at);\n    }\n\n    public function testRestoreCancel()\n    {\n        $model = m::mock(DatabaseSoftDeletingTraitStub::class);\n        $model->makePartial();\n        $model->shouldReceive('fireModelEvent')->with('restoring')->andReturn(false);\n        $model->shouldReceive('save')->never();\n\n        $this->assertFalse($model->restore());\n    }\n}\n\nclass DatabaseSoftDeletingTraitStub\n{\n    use SoftDeletes;\n\n    public $deleted_at;\n    public $updated_at;\n    public $timestamps = true;\n    public $exists = false;\n\n    public function newQuery()\n    {\n        //\n    }\n\n    public function getKey()\n    {\n        return 1;\n    }\n\n    public function getKeyName()\n    {\n        return 'id';\n    }\n\n    public function save()\n    {\n        //\n    }\n\n    public function delete()\n    {\n        return $this->performDeleteOnModel();\n    }\n\n    public function fireModelEvent()\n    {\n        //\n    }\n\n    public function freshTimestamp()\n    {\n        return Carbon::now();\n    }\n\n    public function fromDateTime()\n    {\n        return 'date-time';\n    }\n\n    public function getUpdatedAtColumn()\n    {\n        return defined('static::UPDATED_AT') ? static::UPDATED_AT : 'updated_at';\n    }\n\n    public function setKeysForSaveQuery($query)\n    {\n        $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());\n\n        return $query;\n    }\n\n    protected function getKeyForSaveQuery()\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSqlServerQueryGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Grammars\\SqlServerGrammar;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSqlServerQueryGrammarTest extends TestCase\n{\n    public function testToRawSql()\n    {\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('escape')->with('foo', false)->andReturn(\"'foo'\");\n        $grammar = new SqlServerGrammar($connection);\n\n        $query = $grammar->substituteBindingsIntoRawSql(\n            \"select * from [users] where 'Hello''World?' IS NOT NULL AND [email] = ?\",\n            ['foo'],\n        );\n\n        $this->assertSame(\"select * from [users] where 'Hello''World?' IS NOT NULL AND [email] = 'foo'\", $query);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSqlServerSchemaGrammarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Schema\\ForeignIdColumnDefinition;\nuse Illuminate\\Database\\Schema\\Grammars\\SqlServerGrammar;\nuse Illuminate\\Database\\Schema\\SqlServerBuilder;\nuse Illuminate\\Tests\\Database\\Fixtures\\Enums\\Foo;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseSqlServerSchemaGrammarTest extends TestCase\n{\n    public function testBasicCreateTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"users\" (\"id\" int not null identity primary key, \"email\" nvarchar(255) not null)', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add \"id\" int not null identity primary key',\n            'alter table \"users\" add \"email\" nvarchar(255) not null',\n        ], $statements);\n\n        $conn = $this->getConnection(prefix: 'prefix_');\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->create();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"prefix_users\" (\"id\" int not null identity primary key, \"email\" nvarchar(255) not null)', $statements[0]);\n    }\n\n    public function testCreateTemporaryTable()\n    {\n        $connection = $this->getConnection();\n        $connection->shouldReceive('getTablePrefix')->andReturn('');\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"#users\" (\"id\" int not null identity primary key, \"email\" nvarchar(255) not null)', $statements[0]);\n    }\n\n    public function testCreateTemporaryTableWithPrefix()\n    {\n        $connection = $this->getConnection(prefix: 'prefix_');\n        $blueprint = new Blueprint($connection, 'users');\n        $blueprint->create();\n        $blueprint->temporary();\n        $blueprint->increments('id');\n        $blueprint->string('email');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create table \"#prefix_users\" (\"id\" int not null identity primary key, \"email\" nvarchar(255) not null)', $statements[0]);\n    }\n\n    public function testDropTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table \"users\"', $statements[0]);\n\n        $conn = $this->getConnection(prefix: 'prefix_');\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->drop();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop table \"prefix_users\"', $statements[0]);\n    }\n\n    public function testDropTableIfExists()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('if object_id(N\\'\"users\"\\', \\'U\\') is not null drop table \"users\"', $statements[0]);\n\n        $conn = $this->getConnection(prefix: 'prefix_');\n        $blueprint = new Blueprint($conn, 'users');\n        $blueprint->dropIfExists();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('if object_id(N\\'\"prefix_users\"\\', \\'U\\') is not null drop table \"prefix_users\"', $statements[0]);\n    }\n\n    public function testDropColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertStringContainsString('alter table \"users\" drop column \"foo\"', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn(['foo', 'bar']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertStringContainsString('alter table \"users\" drop column \"foo\", \"bar\"', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropColumn('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertStringContainsString('alter table \"users\" drop column \"foo\", \"bar\"', $statements[0]);\n    }\n\n    public function testDropColumnDropsCreatesSqlToDropDefaultConstraints()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'foo');\n        $blueprint->dropColumn('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame(\"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"foo\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"foo\\\"') AND [name] in ('bar') AND [default_object_id] <> 0;EXEC(@sql);alter table \\\"foo\\\" drop column \\\"bar\\\"\", $statements[0]);\n    }\n\n    public function testDropPrimary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropPrimary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"foo\"', $statements[0]);\n    }\n\n    public function testDropUnique()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropUnique('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"foo\" on \"users\"', $statements[0]);\n    }\n\n    public function testDropIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropIndex('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"foo\" on \"users\"', $statements[0]);\n    }\n\n    public function testDropSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->dropSpatialIndex(['coordinates']);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('drop index \"geo_coordinates_spatialindex\" on \"geo\"', $statements[0]);\n    }\n\n    public function testDropForeign()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropForeign('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"foo\"', $statements[0]);\n    }\n\n    public function testDropConstrainedForeignId()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropConstrainedForeignId('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table \"users\" drop constraint \"users_foo_foreign\"', $statements[0]);\n        $this->assertSame('DECLARE @sql NVARCHAR(MAX) = \\'\\';SELECT @sql += \\'ALTER TABLE \"users\" DROP CONSTRAINT \\' + OBJECT_NAME([default_object_id]) + \\';\\' FROM sys.columns WHERE [object_id] = OBJECT_ID(N\\'\"users\"\\') AND [name] in (\\'foo\\') AND [default_object_id] <> 0;EXEC(@sql);alter table \"users\" drop column \"foo\"', $statements[1]);\n    }\n\n    public function testDropTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestamps();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertStringContainsString('alter table \"users\" drop column \"created_at\", \"updated_at\"', $statements[0]);\n    }\n\n    public function testDropTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dropTimestampsTz();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertStringContainsString('alter table \"users\" drop column \"created_at\", \"updated_at\"', $statements[0]);\n    }\n\n    public function testDropMorphs()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'photos');\n        $blueprint->dropMorphs('imageable');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('drop index \"photos_imageable_type_imageable_id_index\" on \"photos\"', $statements[0]);\n        $this->assertStringContainsString('alter table \"photos\" drop column \"imageable_type\", \"imageable_id\"', $statements[1]);\n    }\n\n    public function testRenameTable()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rename('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('sp_rename N\\'\"users\"\\', \"foo\"', $statements[0]);\n    }\n\n    public function testRenameIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->renameIndex('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('sp_rename N\\'\"users\".\"foo\"\\', \"bar\", N\\'INDEX\\'', $statements[0]);\n    }\n\n    public function testAddingPrimaryKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->primary('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add constraint \"bar\" primary key (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKey()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create unique index \"bar\" on \"users\" (\"foo\")', $statements[0]);\n    }\n\n    public function testAddingUniqueKeyOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->unique('foo', 'bar')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create unique index \"bar\" on \"users\" (\"foo\") with (online = on)', $statements[0]);\n    }\n\n    public function testAddingIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"baz\" on \"users\" (\"foo\", \"bar\")', $statements[0]);\n    }\n\n    public function testAddingIndexOnline()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->index(['foo', 'bar'], 'baz')->online();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"baz\" on \"users\" (\"foo\", \"bar\") with (online = on)', $statements[0]);\n    }\n\n    public function testAddingSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->spatialIndex('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create spatial index \"geo_coordinates_spatialindex\" on \"geo\" (\"coordinates\")', $statements[0]);\n    }\n\n    public function testAddingFluentSpatialIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates', 'point')->spatialIndex();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('create spatial index \"geo_coordinates_spatialindex\" on \"geo\" (\"coordinates\")', $statements[1]);\n    }\n\n    public function testAddingRawIndex()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rawIndex('(function(column))', 'raw_index');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('create index \"raw_index\" on \"users\" ((function(column)))', $statements[0]);\n    }\n\n    public function testAddingIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->increments('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"id\" int not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingSmallIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"id\" smallint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingMediumIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"id\" int not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"id\" bigint not null identity primary key', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->id('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" bigint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingForeignID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignId = $blueprint->foreignId('foo');\n        $blueprint->foreignId('company_id')->constrained();\n        $blueprint->foreignId('laravel_idea_id')->constrained();\n        $blueprint->foreignId('team_id')->references('id')->on('teams');\n        $blueprint->foreignId('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table \"users\" add \"foo\" bigint not null',\n            'alter table \"users\" add \"company_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_company_id_foreign\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n            'alter table \"users\" add \"laravel_idea_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_laravel_idea_id_foreign\" foreign key (\"laravel_idea_id\") references \"laravel_ideas\" (\"id\")',\n            'alter table \"users\" add \"team_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_team_id_foreign\" foreign key (\"team_id\") references \"teams\" (\"id\")',\n            'alter table \"users\" add \"team_column_id\" bigint not null',\n            'alter table \"users\" add constraint \"users_team_column_id_foreign\" foreign key (\"team_column_id\") references \"teams\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingForeignIdSpecifyingIndexNameInConstraint()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->foreignId('company_id')->constrained(indexName: 'my_index');\n        $statements = $blueprint->toSql();\n        $this->assertSame([\n            'alter table \"users\" add \"company_id\" bigint not null',\n            'alter table \"users\" add constraint \"my_index\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingBigIncrementingID()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigIncrements('id');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"id\" bigint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingString()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(255) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(100) not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->string('foo', 100)->nullable()->default('bar');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(100) null default \\'bar\\'', $statements[0]);\n    }\n\n    public function testAddingText()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->text('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(max) not null', $statements[0]);\n    }\n\n    public function testAddingBigInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" bigint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->bigInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" bigint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" int not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->integer('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" int not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingMediumInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" int not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->mediumInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" int not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingTinyInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" tinyint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->tinyInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" tinyint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingSmallInteger()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" smallint not null', $statements[0]);\n\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->smallInteger('foo', true);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" smallint not null identity primary key', $statements[0]);\n    }\n\n    public function testAddingFloat()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->float('foo', 5);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" float(5) not null', $statements[0]);\n    }\n\n    public function testAddingDouble()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->double('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" double precision not null', $statements[0]);\n    }\n\n    public function testAddingDecimal()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->decimal('foo', 5, 2);\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" decimal(5, 2) not null', $statements[0]);\n    }\n\n    public function testAddingBoolean()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->boolean('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" bit not null', $statements[0]);\n    }\n\n    public function testAddingEnum()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->enum('role', ['member', 'admin']);\n        $blueprint->enum('status', Foo::cases());\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(2, $statements);\n        $this->assertSame('alter table \"users\" add \"role\" nvarchar(255) check (\"role\" in (N\\'member\\', N\\'admin\\')) not null', $statements[0]);\n        $this->assertSame('alter table \"users\" add \"status\" nvarchar(255) check (\"status\" in (N\\'bar\\')) not null', $statements[1]);\n    }\n\n    public function testAddingJson()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->json('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(max) not null', $statements[0]);\n    }\n\n    public function testAddingJsonb()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->jsonb('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(max) not null', $statements[0]);\n    }\n\n    public function testAddingDate()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" date not null', $statements[0]);\n    }\n\n    public function testAddingDateWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->date('foo')->useCurrent();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" date not null default CAST(GETDATE() AS DATE)', $statements[0]);\n    }\n\n    public function testAddingYear()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"birth_year\" int not null', $statements[0]);\n    }\n\n    public function testAddingYearWithDefaultCurrent()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->year('birth_year')->useCurrent();\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"birth_year\" int not null default CAST(YEAR(GETDATE()) AS INTEGER)', $statements[0]);\n    }\n\n    public function testAddingDateTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTime('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetime2(1) not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" datetimeoffset not null', $statements[0]);\n    }\n\n    public function testAddingDateTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->dateTimeTz('foo', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" datetimeoffset(1) not null', $statements[0]);\n    }\n\n    public function testAddingTime()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimeWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->time('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimeTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" time not null', $statements[0]);\n    }\n\n    public function testAddingTimeTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timeTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" time(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestamp()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetime not null', $statements[0]);\n    }\n\n    public function testAddingTimestampWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamp('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetime2(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at');\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetimeoffset not null', $statements[0]);\n    }\n\n    public function testAddingTimestampTzWithPrecision()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampTz('created_at', 1);\n        $statements = $blueprint->toSql();\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"created_at\" datetimeoffset(1) not null', $statements[0]);\n    }\n\n    public function testAddingTimestamps()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestamps();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add \"created_at\" datetime null',\n            'alter table \"users\" add \"updated_at\" datetime null',\n        ], $statements);\n    }\n\n    public function testAddingTimestampsTz()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->timestampsTz();\n        $statements = $blueprint->toSql();\n        $this->assertCount(2, $statements);\n        $this->assertSame([\n            'alter table \"users\" add \"created_at\" datetimeoffset null',\n            'alter table \"users\" add \"updated_at\" datetimeoffset null',\n        ], $statements);\n    }\n\n    public function testAddingRememberToken()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->rememberToken();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"remember_token\" nvarchar(100) null', $statements[0]);\n    }\n\n    public function testAddingBinary()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->binary('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" varbinary(max) not null', $statements[0]);\n    }\n\n    public function testAddingUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" uniqueidentifier not null', $statements[0]);\n    }\n\n    public function testAddingUuidDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->uuid();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"uuid\" uniqueidentifier not null', $statements[0]);\n    }\n\n    public function testAddingForeignUuid()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $foreignId = $blueprint->foreignUuid('foo');\n        $blueprint->foreignUuid('company_id')->constrained();\n        $blueprint->foreignUuid('laravel_idea_id')->constrained();\n        $blueprint->foreignUuid('team_id')->references('id')->on('teams');\n        $blueprint->foreignUuid('team_column_id')->constrained('teams');\n\n        $statements = $blueprint->toSql();\n\n        $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId);\n        $this->assertSame([\n            'alter table \"users\" add \"foo\" uniqueidentifier not null',\n            'alter table \"users\" add \"company_id\" uniqueidentifier not null',\n            'alter table \"users\" add constraint \"users_company_id_foreign\" foreign key (\"company_id\") references \"companies\" (\"id\")',\n            'alter table \"users\" add \"laravel_idea_id\" uniqueidentifier not null',\n            'alter table \"users\" add constraint \"users_laravel_idea_id_foreign\" foreign key (\"laravel_idea_id\") references \"laravel_ideas\" (\"id\")',\n            'alter table \"users\" add \"team_id\" uniqueidentifier not null',\n            'alter table \"users\" add constraint \"users_team_id_foreign\" foreign key (\"team_id\") references \"teams\" (\"id\")',\n            'alter table \"users\" add \"team_column_id\" uniqueidentifier not null',\n            'alter table \"users\" add constraint \"users_team_column_id_foreign\" foreign key (\"team_column_id\") references \"teams\" (\"id\")',\n        ], $statements);\n    }\n\n    public function testAddingIpAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingIpAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->ipAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"ip_address\" nvarchar(45) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddress()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress('foo');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"foo\" nvarchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingMacAddressDefaultsColumnName()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'users');\n        $blueprint->macAddress();\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"users\" add \"mac_address\" nvarchar(17) not null', $statements[0]);\n    }\n\n    public function testAddingGeometry()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geometry('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add \"coordinates\" geometry not null', $statements[0]);\n    }\n\n    public function testAddingGeography()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'geo');\n        $blueprint->geography('coordinates');\n        $statements = $blueprint->toSql();\n\n        $this->assertCount(1, $statements);\n        $this->assertSame('alter table \"geo\" add \"coordinates\" geography not null', $statements[0]);\n    }\n\n    public function testAddingGeneratedColumn()\n    {\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->computed('discounted_virtual', 'price - 5');\n        $blueprint->computed('discounted_stored', 'price - 5')->persisted();\n        $statements = $blueprint->toSql();\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table \"products\" add \"price\" int not null',\n            'alter table \"products\" add \"discounted_virtual\" as (price - 5)',\n            'alter table \"products\" add \"discounted_stored\" as (price - 5) persisted',\n        ], $statements);\n\n        $blueprint = new Blueprint($this->getConnection(), 'products');\n        $blueprint->integer('price');\n        $blueprint->computed('discounted_virtual', new Expression('price - 5'));\n        $blueprint->computed('discounted_stored', new Expression('price - 5'))->persisted();\n        $statements = $blueprint->toSql();\n        $this->assertCount(3, $statements);\n        $this->assertSame([\n            'alter table \"products\" add \"price\" int not null',\n            'alter table \"products\" add \"discounted_virtual\" as (price - 5)',\n            'alter table \"products\" add \"discounted_stored\" as (price - 5) persisted',\n        ], $statements);\n    }\n\n    public function testGrammarsAreMacroable()\n    {\n        // compileReplace macro.\n        $this->getGrammar()::macro('compileReplace', function () {\n            return true;\n        });\n\n        $c = $this->getGrammar()::compileReplace();\n\n        $this->assertTrue($c);\n    }\n\n    public function testQuoteString()\n    {\n        $this->assertSame(\"N'中文測試'\", $this->getGrammar()->quoteString('中文測試'));\n    }\n\n    public function testQuoteStringOnArray()\n    {\n        $this->assertSame(\"N'中文', N'測試'\", $this->getGrammar()->quoteString(['中文', '測試']));\n    }\n\n    public function testCreateDatabase()\n    {\n        $statement = $this->getGrammar()->compileCreateDatabase('my_database_a');\n\n        $this->assertSame(\n            'create database \"my_database_a\"',\n            $statement\n        );\n\n        $statement = $this->getGrammar()->compileCreateDatabase('my_database_b');\n\n        $this->assertSame(\n            'create database \"my_database_b\"',\n            $statement\n        );\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_a');\n\n        $this->assertSame(\n            'drop database if exists \"my_database_a\"',\n            $statement\n        );\n\n        $statement = $this->getGrammar()->compileDropDatabaseIfExists('my_database_b');\n\n        $this->assertSame(\n            'drop database if exists \"my_database_b\"',\n            $statement\n        );\n    }\n\n    protected function getConnection(\n        ?SqlServerGrammar $grammar = null,\n        ?SqlServerBuilder $builder = null,\n        string $prefix = ''\n    ) {\n        $connection = m::mock(Connection::class)\n            ->shouldReceive('getTablePrefix')->andReturn($prefix)\n            ->shouldReceive('getConfig')->with('prefix_indexes')->andReturn(null)\n            ->getMock();\n\n        $grammar ??= $this->getGrammar($connection);\n        $builder ??= $this->getBuilder();\n\n        return $connection\n            ->shouldReceive('getSchemaGrammar')->andReturn($grammar)\n            ->shouldReceive('getSchemaBuilder')->andReturn($builder)\n            ->getMock();\n    }\n\n    public function getGrammar(?Connection $connection = null)\n    {\n        return new SqlServerGrammar($connection ?? $this->getConnection());\n    }\n\n    public function getBuilder()\n    {\n        return mock(SqlServerBuilder::class);\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseSqliteSchemaStateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Schema\\SqliteSchemaState;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Mockery as m;\nuse PDO;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Process\\Process;\n\nclass DatabaseSqliteSchemaStateTest extends TestCase\n{\n    public function testLoadSchemaToDatabase(): void\n    {\n        $config = ['driver' => 'sqlite', 'database' => 'database/database.sqlite', 'prefix' => '', 'foreign_key_constraints' => true, 'name' => 'sqlite'];\n        $connection = m::mock(SQLiteConnection::class);\n        $connection->shouldReceive('getConfig')->andReturn($config);\n        $connection->shouldReceive('getDatabaseName')->andReturn($config['database']);\n\n        $process = m::spy(Process::class);\n        $processFactory = m::spy(function () use ($process) {\n            return $process;\n        });\n\n        $schemaState = new SqliteSchemaState($connection, null, $processFactory);\n        $schemaState->load('database/schema/sqlite-schema.dump');\n\n        $processFactory->shouldHaveBeenCalled()->with('sqlite3 \"${:LARAVEL_LOAD_DATABASE}\" < \"${:LARAVEL_LOAD_PATH}\"');\n\n        $process->shouldHaveReceived('mustRun')->with(null, [\n            'LARAVEL_LOAD_DATABASE' => 'database/database.sqlite',\n            'LARAVEL_LOAD_PATH' => 'database/schema/sqlite-schema.dump',\n        ]);\n    }\n\n    public function testLoadSchemaToInMemory(): void\n    {\n        $config = ['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', 'foreign_key_constraints' => true, 'name' => 'sqlite'];\n        $connection = m::mock(SQLiteConnection::class);\n        $connection->shouldReceive('getConfig')->andReturn($config);\n        $connection->shouldReceive('getDatabaseName')->andReturn($config['database']);\n        $connection->shouldReceive('getPdo')->andReturn($pdo = m::spy(PDO::class));\n\n        $files = m::mock(Filesystem::class);\n        $files->shouldReceive('get')->andReturn('CREATE TABLE IF NOT EXISTS \"migrations\" (\"id\" integer not null primary key autoincrement, \"migration\" varchar not null, \"batch\" integer not null);');\n\n        $schemaState = new SqliteSchemaState($connection, $files);\n        $schemaState->load('database/schema/sqlite-schema.dump');\n\n        $pdo->shouldHaveReceived('exec')->with('CREATE TABLE IF NOT EXISTS \"migrations\" (\"id\" integer not null primary key autoincrement, \"migration\" varchar not null, \"batch\" integer not null);');\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseTransactionsManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\DatabaseTransactionsManager;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseTransactionsManagerTest extends TestCase\n{\n    public function testBeginningTransactions()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n\n        $this->assertCount(3, $manager->getPendingTransactions());\n        $this->assertSame('default', $manager->getPendingTransactions()[0]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[0]->level);\n        $this->assertSame('default', $manager->getPendingTransactions()[1]->connection);\n        $this->assertEquals(2, $manager->getPendingTransactions()[1]->level);\n        $this->assertSame('admin', $manager->getPendingTransactions()[2]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[2]->level);\n    }\n\n    public function testRollingBackTransactions()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n\n        $manager->rollback('default', 1);\n\n        $this->assertCount(2, $manager->getPendingTransactions());\n\n        $this->assertSame('default', $manager->getPendingTransactions()[0]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[0]->level);\n\n        $this->assertSame('admin', $manager->getPendingTransactions()[1]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[1]->level);\n    }\n\n    public function testRollingBackTransactionsAllTheWay()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n\n        $manager->rollback('default', 0);\n\n        $this->assertCount(1, $manager->getPendingTransactions());\n\n        $this->assertSame('admin', $manager->getPendingTransactions()[0]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[0]->level);\n    }\n\n    public function testCommittingTransactions()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n        $manager->begin('admin', 2);\n\n        $manager->commit('default', 2, 1);\n        $executedTransactions = $manager->commit('default', 1, 0);\n\n        $executedAdminTransactions = $manager->commit('admin', 2, 1);\n\n        $this->assertCount(1, $manager->getPendingTransactions()); // One pending \"admin\" transaction left...\n        $this->assertCount(2, $executedTransactions); // Two committed transactions on \"default\"\n        $this->assertCount(0, $executedAdminTransactions); // Zero executed committed transactions on \"default\"\n\n        // Level 2 \"admin\" callback has been staged...\n        $this->assertSame('admin', $manager->getCommittedTransactions()[0]->connection);\n        $this->assertEquals(2, $manager->getCommittedTransactions()[0]->level);\n\n        // Level 1 \"admin\" callback still pending...\n        $this->assertSame('admin', $manager->getPendingTransactions()[0]->connection);\n        $this->assertEquals(1, $manager->getPendingTransactions()[0]->level);\n    }\n\n    public function testCallbacksAreAddedToTheCurrentTransaction()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallback(function () use (&$callbacks) {\n        });\n\n        $manager->begin('default', 2);\n\n        $manager->begin('admin', 1);\n\n        $manager->addCallback(function () use (&$callbacks) {\n        });\n\n        $this->assertCount(1, $manager->getPendingTransactions()[0]->getCallbacks());\n        $this->assertCount(0, $manager->getPendingTransactions()[1]->getCallbacks());\n        $this->assertCount(1, $manager->getPendingTransactions()[2]->getCallbacks());\n    }\n\n    public function testCallbacksRunInFifoOrder()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $order = [];\n\n        $manager->begin('default', 1);\n\n        $manager->addCallback(function () use (&$order) {\n            $order[] = 1;\n        });\n\n        $manager->addCallback(function () use (&$order) {\n            $order[] = 2;\n        });\n\n        $manager->addCallback(function () use (&$order) {\n            $order[] = 3;\n        });\n\n        $manager->commit('default', 1, 0);\n\n        $this->assertSame([1, 2, 3], $order);\n    }\n\n    public function testCommittingTransactionsExecutesCallbacks()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $manager->begin('default', 2);\n\n        $manager->addCallback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 2];\n        });\n\n        $manager->begin('admin', 1);\n\n        $manager->commit('default', 2, 1);\n        $manager->commit('default', 1, 0);\n\n        $this->assertCount(2, $callbacks);\n        $this->assertEquals(['default', 2], $callbacks[0]);\n        $this->assertEquals(['default', 1], $callbacks[1]);\n    }\n\n    public function testCommittingExecutesOnlyCallbacksOfTheConnection()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n\n        $manager->addCallback(function () use (&$callbacks) {\n            $callbacks[] = ['admin', 1];\n        });\n\n        $manager->commit('default', 2, 1);\n        $manager->commit('default', 1, 0);\n\n        $this->assertCount(1, $callbacks);\n        $this->assertEquals(['default', 1], $callbacks[0]);\n    }\n\n    public function testCallbackIsExecutedIfNoTransactions()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->addCallback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $this->assertCount(1, $callbacks);\n        $this->assertEquals(['default', 1], $callbacks[0]);\n    }\n\n    public function testCallbacksForRollbackAreAddedToTheCurrentTransaction()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n        });\n\n        $manager->begin('default', 2);\n\n        $manager->begin('admin', 1);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n        });\n\n        $this->assertCount(1, $manager->getPendingTransactions()[0]->getCallbacksForRollback());\n        $this->assertCount(0, $manager->getPendingTransactions()[1]->getCallbacksForRollback());\n        $this->assertCount(1, $manager->getPendingTransactions()[2]->getCallbacksForRollback());\n    }\n\n    public function testRollbackTransactionsExecutesCallbacks()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $manager->begin('default', 2);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 2];\n        });\n\n        $manager->begin('admin', 1);\n\n        $manager->rollback('default', 1);\n        $manager->rollback('default', 0);\n\n        $this->assertCount(2, $callbacks);\n        $this->assertEquals(['default', 2], $callbacks[0]);\n        $this->assertEquals(['default', 1], $callbacks[1]);\n    }\n\n    public function testRollbackExecutesOnlyCallbacksOfTheConnection()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $manager->begin('default', 2);\n        $manager->begin('admin', 1);\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n            $callbacks[] = ['admin', 1];\n        });\n\n        $manager->rollback('default', 1);\n        $manager->rollback('default', 0);\n\n        $this->assertCount(1, $callbacks);\n        $this->assertEquals(['default', 1], $callbacks[0]);\n    }\n\n    public function testCallbackForRollbackIsNotExecutedIfNoTransactions()\n    {\n        $callbacks = [];\n\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->addCallbackForRollback(function () use (&$callbacks) {\n            $callbacks[] = ['default', 1];\n        });\n\n        $this->assertCount(0, $callbacks);\n    }\n\n    public function testStageTransactions()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('admin', 1);\n\n        $this->assertCount(2, $manager->getPendingTransactions());\n\n        $pendingTransactions = $manager->getPendingTransactions();\n\n        $this->assertEquals(1, $pendingTransactions[0]->level);\n        $this->assertEquals('default', $pendingTransactions[0]->connection);\n        $this->assertEquals(1, $pendingTransactions[1]->level);\n        $this->assertEquals('admin', $pendingTransactions[1]->connection);\n\n        $manager->stageTransactions('default', 1);\n\n        $this->assertCount(1, $manager->getPendingTransactions());\n        $this->assertCount(1, $manager->getCommittedTransactions());\n        $this->assertEquals('default', $manager->getCommittedTransactions()[0]->connection);\n\n        $manager->stageTransactions('admin', 1);\n\n        $this->assertCount(0, $manager->getPendingTransactions());\n        $this->assertCount(2, $manager->getCommittedTransactions());\n        $this->assertEquals('admin', $manager->getCommittedTransactions()[1]->connection);\n    }\n\n    public function testStageTransactionsOnlyStagesTheTransactionsAtOrAboveTheGivenLevel()\n    {\n        $manager = new DatabaseTransactionsManager;\n\n        $manager->begin('default', 1);\n        $manager->begin('default', 2);\n        $manager->begin('default', 3);\n        $manager->stageTransactions('default', 2);\n\n        $this->assertCount(1, $manager->getPendingTransactions());\n        $this->assertCount(2, $manager->getCommittedTransactions());\n    }\n}\n"
  },
  {
    "path": "tests/Database/DatabaseTransactionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\DatabaseTransactionsManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nclass DatabaseTransactionsTest extends TestCase\n{\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], 'second_connection');\n\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    protected function createSchema()\n    {\n        foreach (['default', 'second_connection'] as $connection) {\n            $this->schema($connection)->create('users', function ($table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                $table->string('value')->nullable();\n            });\n        }\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        foreach (['default', 'second_connection'] as $connection) {\n            $this->schema($connection)->drop('users');\n        }\n\n        parent::tearDown();\n    }\n\n    public function testTransactionIsRecordedAndCommitted()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('commit')->once()->with('default', 1, 0);\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        $this->connection()->transaction(function () {\n            $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                'value' => 2,\n            ]);\n        });\n    }\n\n    public function testTransactionIsRecordedAndCommittedUsingTheSeparateMethods()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('commit')->once()->with('default', 1, 0);\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        $this->connection()->beginTransaction();\n        $this->connection()->table('users')->where(['name' => 'zain'])->update([\n            'value' => 2,\n        ]);\n        $this->connection()->commit();\n    }\n\n    public function testNestedTransactionIsRecordedAndCommitted()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 2);\n        $transactionManager->shouldReceive('commit')->once()->with('default', 2, 1);\n        $transactionManager->shouldReceive('commit')->once()->with('default', 1, 0);\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        $this->connection()->transaction(function () {\n            $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                'value' => 2,\n            ]);\n\n            $this->connection()->transaction(function () {\n                $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                    'value' => 2,\n                ]);\n            });\n        });\n    }\n\n    public function testNestedTransactionIsRecordeForDifferentConnectionsdAndCommitted()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('begin')->once()->with('second_connection', 1);\n        $transactionManager->shouldReceive('begin')->once()->with('second_connection', 2);\n        $transactionManager->shouldReceive('commit')->once()->with('default', 1, 0);\n        $transactionManager->shouldReceive('commit')->once()->with('second_connection', 2, 1);\n        $transactionManager->shouldReceive('commit')->once()->with('second_connection', 1, 0);\n\n        $this->connection()->setTransactionManager($transactionManager);\n        $this->connection('second_connection')->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        $this->connection()->transaction(function () {\n            $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                'value' => 2,\n            ]);\n\n            $this->connection('second_connection')->transaction(function () {\n                $this->connection('second_connection')->table('users')->where(['name' => 'zain'])->update([\n                    'value' => 2,\n                ]);\n\n                $this->connection('second_connection')->transaction(function () {\n                    $this->connection('second_connection')->table('users')->where(['name' => 'zain'])->update([\n                        'value' => 2,\n                    ]);\n                });\n            });\n        });\n    }\n\n    public function testTransactionIsRolledBack()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('rollback')->once()->with('default', 0);\n        $transactionManager->shouldNotReceive('commit');\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        try {\n            $this->connection()->transaction(function () {\n                $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                    'value' => 2,\n                ]);\n\n                throw new Exception;\n            });\n        } catch (Throwable) {\n        }\n    }\n\n    public function testTransactionIsRolledBackUsingSeparateMethods()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('rollback')->once()->with('default', 0);\n        $transactionManager->shouldNotReceive('commit', 1, 0);\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        $this->connection()->beginTransaction();\n\n        $this->connection()->table('users')->where(['name' => 'zain'])->update([\n            'value' => 2,\n        ]);\n\n        $this->connection()->rollBack();\n    }\n\n    public function testNestedTransactionsAreRolledBack()\n    {\n        $transactionManager = m::mock(new DatabaseTransactionsManager);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 1);\n        $transactionManager->shouldReceive('begin')->once()->with('default', 2);\n        $transactionManager->shouldReceive('rollback')->once()->with('default', 1);\n        $transactionManager->shouldReceive('rollback')->once()->with('default', 0);\n        $transactionManager->shouldNotReceive('commit');\n\n        $this->connection()->setTransactionManager($transactionManager);\n\n        $this->connection()->table('users')->insert([\n            'name' => 'zain', 'value' => 1,\n        ]);\n\n        try {\n            $this->connection()->transaction(function () {\n                $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                    'value' => 2,\n                ]);\n\n                $this->connection()->transaction(function () {\n                    $this->connection()->table('users')->where(['name' => 'zain'])->update([\n                        'value' => 2,\n                    ]);\n\n                    throw new Exception;\n                });\n            });\n        } catch (Throwable) {\n        }\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema($connection = 'default')\n    {\n        return $this->connection($connection)->getSchemaBuilder();\n    }\n\n    public function connection($name = 'default')\n    {\n        return DB::connection($name);\n    }\n}\n"
  },
  {
    "path": "tests/Database/EloquentHasOneOrManyDeprecationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass EloquentHasOneOrManyDeprecationTest extends TestCase\n{\n    public function testHasManyMatchWithNullLocalKey(): void\n    {\n        $relation = $this->getHasManyRelation();\n\n        $result1 = new HasOneOrManyDeprecationModelStub;\n        $result1->foreign_key = 1;\n\n        $result2 = new HasOneOrManyDeprecationModelStub;\n        $result2->foreign_key = '';\n\n        $model1 = new HasOneOrManyDeprecationModelStub;\n        $model1->id = 1;\n        $model2 = new HasOneOrManyDeprecationModelStub;\n        $model2->id = null;\n\n        $relation->getRelated()->shouldReceive('newCollection')->andReturnUsing(function ($array) {\n            return new Collection($array);\n        });\n\n        $models = $relation->match([$model1, $model2], new Collection([$result1, $result2]), 'foo');\n\n        $this->assertCount(1, $models[0]->foo);\n        $this->assertNull($models[1]->foo);\n    }\n\n    public function testHasOneMatchWithNullLocalKey(): void\n    {\n        $relation = $this->getHasOneRelation();\n\n        $result1 = new HasOneOrManyDeprecationModelStub;\n        $result1->foreign_key = 1;\n\n        $model1 = new HasOneOrManyDeprecationModelStub;\n        $model1->id = 1;\n        $model2 = new HasOneOrManyDeprecationModelStub;\n        $model2->id = null;\n\n        $models = $relation->match([$model1, $model2], new Collection([$result1]), 'foo');\n\n        $this->assertInstanceOf(HasOneOrManyDeprecationModelStub::class, $models[0]->foo);\n        $this->assertNull($models[1]->foo);\n    }\n\n    protected function getHasManyRelation(): HasMany\n    {\n        $queryBuilder = m::mock(QueryBuilder::class);\n        $builder = m::mock(Builder::class, [$queryBuilder]);\n        $builder->shouldReceive('whereNotNull')->with('table.foreign_key');\n        $builder->shouldReceive('where')->with('table.foreign_key', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n\n        return new HasMany($builder, $parent, 'table.foreign_key', 'id');\n    }\n\n    protected function getHasOneRelation(): HasOne\n    {\n        $queryBuilder = m::mock(QueryBuilder::class);\n        $builder = m::mock(Builder::class, [$queryBuilder]);\n        $builder->shouldReceive('whereNotNull')->with('table.foreign_key');\n        $builder->shouldReceive('where')->with('table.foreign_key', '=', 1);\n        $related = m::mock(Model::class);\n        $builder->shouldReceive('getModel')->andReturn($related);\n        $parent = m::mock(Model::class);\n        $parent->shouldReceive('getAttribute')->with('id')->andReturn(1);\n        $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');\n        $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');\n\n        return new HasOne($builder, $parent, 'table.foreign_key', 'id');\n    }\n}\n\nclass HasOneOrManyDeprecationModelStub extends Model\n{\n    public $foreign_key;\n}\n"
  },
  {
    "path": "tests/Database/EloquentModelCustomCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Brick\\Math\\BigNumber;\nuse GMP;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\ComparesCastableAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\SerializesCastableAttributes;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\MassAssignmentException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\Group;\nuse PHPUnit\\Framework\\TestCase;\n\n#[Group('integration')]\nclass EloquentModelCustomCastingTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n        $db->setAsGlobal();\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create('casting_table', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('address_line_one');\n            $table->string('address_line_two');\n            $table->integer('amount');\n            $table->string('string_field');\n            $table->timestamps();\n        });\n\n        $this->schema()->create('members', function (Blueprint $table) {\n            $table->increments('id');\n            $table->decimal('amount', 4, 2);\n        });\n\n        $this->schema()->create('documents', function (Blueprint $table) {\n            $table->increments('id');\n            $table->json('document');\n        });\n\n        $this->schema()->create('people', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('address_line_one');\n            $table->string('address_line_two');\n        });\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('casting_table');\n        $this->schema()->drop('members');\n        $this->schema()->drop('documents');\n\n        parent::tearDown();\n    }\n\n    #[RequiresPhpExtension('gmp')]\n    public function testSavingCastedAttributesToDatabase()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\CustomCasts $model */\n        $model = CustomCasts::create([\n            'address' => new AddressModel('address_line_one_value', 'address_line_two_value'),\n            'amount' => gmp_init('1000', 10),\n            'string_field' => null,\n        ]);\n\n        $this->assertSame('address_line_one_value', $model->getOriginal('address_line_one'));\n        $this->assertSame('address_line_one_value', $model->getAttribute('address_line_one'));\n\n        $this->assertSame('address_line_two_value', $model->getOriginal('address_line_two'));\n        $this->assertSame('address_line_two_value', $model->getAttribute('address_line_two'));\n\n        $this->assertSame('1000', $model->getRawOriginal('amount'));\n\n        $this->assertNull($model->getOriginal('string_field'));\n        $this->assertNull($model->getAttribute('string_field'));\n        $this->assertSame('', $model->getRawOriginal('string_field'));\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\CustomCasts $another_model */\n        $another_model = CustomCasts::create([\n            'address_line_one' => 'address_line_one_value',\n            'address_line_two' => 'address_line_two_value',\n            'amount' => gmp_init('500', 10),\n            'string_field' => 'string_value',\n        ]);\n\n        $this->assertInstanceOf(AddressModel::class, $another_model->address);\n\n        $this->assertSame('address_line_one_value', $model->address->lineOne);\n        $this->assertSame('address_line_two_value', $model->address->lineTwo);\n        $this->assertInstanceOf(GMP::class, $model->amount);\n    }\n\n    #[RequiresPhpExtension('gmp')]\n    public function testInvalidArgumentExceptionOnInvalidValue()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\CustomCasts $model */\n        $model = CustomCasts::create([\n            'address' => new AddressModel('address_line_one_value', 'address_line_two_value'),\n            'amount' => gmp_init('1000', 10),\n            'string_field' => 'string_value',\n        ]);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The given value is not an Address instance.');\n        $model->address = 'single_string';\n\n        // Ensure model values remain unchanged\n        $this->assertSame('address_line_one_value', $model->address->lineOne);\n        $this->assertSame('address_line_two_value', $model->address->lineTwo);\n    }\n\n    #[RequiresPhpExtension('gmp')]\n    public function testInvalidArgumentExceptionOnNull()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\CustomCasts $model */\n        $model = CustomCasts::create([\n            'address' => new AddressModel('address_line_one_value', 'address_line_two_value'),\n            'amount' => gmp_init('1000', 10),\n            'string_field' => 'string_value',\n        ]);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The given value is not an Address instance.');\n        $model->address = null;\n\n        // Ensure model values remain unchanged\n        $this->assertSame('address_line_one_value', $model->address->lineOne);\n        $this->assertSame('address_line_two_value', $model->address->lineTwo);\n    }\n\n    #[RequiresPhpExtension('gmp')]\n    public function testModelsWithCustomCastsCanBeConvertedToArrays()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\CustomCasts $model */\n        $model = CustomCasts::create([\n            'address' => new AddressModel('address_line_one_value', 'address_line_two_value'),\n            'amount' => gmp_init('1000', 10),\n            'string_field' => 'string_value',\n        ]);\n\n        // Ensure model values remain unchanged\n        $this->assertSame([\n            'address_line_one' => 'address_line_one_value',\n            'address_line_two' => 'address_line_two_value',\n            'amount' => '1000',\n            'string_field' => 'string_value',\n            'updated_at' => $model->updated_at->toJSON(),\n            'created_at' => $model->created_at->toJSON(),\n            'id' => 1,\n        ], $model->toArray());\n    }\n\n    public function testModelWithCustomCastsWorkWithCustomIncrementDecrement()\n    {\n        $model = new Member();\n        $model->amount = new Euro('2');\n        $model->save();\n\n        $this->assertInstanceOf(Euro::class, $model->amount);\n        $this->assertEquals('2', $model->amount->value);\n\n        $model->increment('amount', new Euro('1'));\n        $this->assertEquals('3.00', $model->amount->value);\n    }\n\n    public function testModelWithCustomCastsCompareFunction()\n    {\n        // Set raw attribute, this is an example of how we would receive JSON string from the database.\n        // Note the spaces after the colon.\n        $model = new Document();\n        $model->setRawAttributes(['document' => '{\"content\": \"content\", \"title\": \"hello world\"}']);\n        $model->save();\n\n        // Inverse title and content this would result in a different JSON string when json_encode is used\n        $document = new \\stdClass();\n        $document->title = 'hello world';\n        $document->content = 'content';\n        $model->document = $document;\n\n        $this->assertFalse($model->isDirty('document'));\n        $document->title = 'hello world 2';\n        $this->assertTrue($model->isDirty('document'));\n    }\n\n    public function testModelWithCustomCastsUnguardedCanBeMassAssigned()\n    {\n        Person::preventSilentlyDiscardingAttributes();\n\n        $model = Person::create(['address' => new AddressDto('123 Main St.', 'Anytown, USA')]);\n        $this->assertSame('123 Main St.', $model->address->lineOne);\n        $this->assertSame('Anytown, USA', $model->address->lineTwo);\n    }\n\n    public function testModelWithCustomCastsCanBeGuardedAgainstMassAssigned()\n    {\n        Person::preventSilentlyDiscardingAttributes();\n        $this->expectException(MassAssignmentException::class);\n\n        $model = new Person();\n        $model->guard(['address']);\n        $model->create(['id' => 1, 'address' => new AddressDto('123 Main St.', 'Anytown, USA')]);\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n}\n\n/**\n * Eloquent Casts...\n */\nclass AddressCast implements CastsAttributes\n{\n    /**\n     * Cast the given value.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return \\Illuminate\\Tests\\Integration\\Database\\AddressModel\n     */\n    public function get($model, $key, $value, $attributes)\n    {\n        return new AddressModel(\n            $attributes['address_line_one'],\n            $attributes['address_line_two'],\n        );\n    }\n\n    /**\n     * Prepare the given value for storage.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  AddressModel  $value\n     * @param  array  $attributes\n     * @return array\n     */\n    public function set($model, $key, $value, $attributes)\n    {\n        if (! $value instanceof AddressModel) {\n            throw new InvalidArgumentException('The given value is not an Address instance.');\n        }\n\n        return [\n            'address_line_one' => $value->lineOne,\n            'address_line_two' => $value->lineTwo,\n        ];\n    }\n}\n\nclass GMPCast implements CastsAttributes, SerializesCastableAttributes\n{\n    /**\n     * Cast the given value.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  string  $value\n     * @param  array  $attributes\n     * @return string|null\n     */\n    public function get($model, $key, $value, $attributes)\n    {\n        return gmp_init($value, 10);\n    }\n\n    /**\n     * Prepare the given value for storage.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  string|null  $value\n     * @param  array  $attributes\n     * @return string\n     */\n    public function set($model, $key, $value, $attributes)\n    {\n        return gmp_strval($value, 10);\n    }\n\n    /**\n     * Serialize the attribute when converting the model to an array.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return mixed\n     */\n    public function serialize($model, string $key, $value, array $attributes)\n    {\n        return gmp_strval($value, 10);\n    }\n}\n\nclass NonNullableString implements CastsAttributes\n{\n    /**\n     * Cast the given value.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  string  $value\n     * @param  array  $attributes\n     * @return string|null\n     */\n    public function get($model, $key, $value, $attributes)\n    {\n        return ($value != '') ? $value : null;\n    }\n\n    /**\n     * Prepare the given value for storage.\n     *\n     * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n     * @param  string  $key\n     * @param  string|null  $value\n     * @param  array  $attributes\n     * @return string\n     */\n    public function set($model, $key, $value, $attributes)\n    {\n        return $value ?? '';\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass CustomCasts extends Eloquent\n{\n    /**\n     * @var string\n     */\n    protected $table = 'casting_table';\n\n    /**\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * @var array\n     */\n    protected $casts = [\n        'address' => AddressCast::class,\n        'amount' => GMPCast::class,\n        'string_field' => NonNullableString::class,\n    ];\n}\n\nclass AddressModel\n{\n    /**\n     * @var string\n     */\n    public $lineOne;\n\n    /**\n     * @var string\n     */\n    public $lineTwo;\n\n    public function __construct($address_line_one, $address_line_two)\n    {\n        $this->lineOne = $address_line_one;\n        $this->lineTwo = $address_line_two;\n    }\n}\n\nclass Euro implements Castable\n{\n    public string $value;\n\n    public function __construct(string $value)\n    {\n        $this->value = $value;\n    }\n\n    public static function castUsing(array $arguments)\n    {\n        return EuroCaster::class;\n    }\n}\n\nclass EuroCaster implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return new Euro($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return $value instanceof Euro ? $value->value : $value;\n    }\n\n    public function increment($model, $key, $value, $attributes)\n    {\n        $model->$key = new Euro((string) BigNumber::of((string) $model->$key->value)->plus($value->value)->toScale(2));\n\n        return $model->$key;\n    }\n\n    public function decrement($model, $key, $value, $attributes)\n    {\n        $model->$key = new Euro((string) BigNumber::of((string) $model->$key->value)->subtract($value->value)->toScale(2));\n\n        return $model->$key;\n    }\n}\n\nclass Member extends Model\n{\n    public $timestamps = false;\n    protected $casts = [\n        'amount' => Euro::class,\n    ];\n}\n\nclass Document extends Model\n{\n    public $timestamps = false;\n\n    protected $casts = [\n        'document' => StructuredDocumentCaster::class,\n    ];\n}\n\nclass Person extends Model\n{\n    protected $guarded = ['id'];\n    public $timestamps = false;\n    protected $casts = [\n        'address' => AsAddress::class,\n    ];\n}\n\nclass StructuredDocumentCaster implements CastsAttributes, ComparesCastableAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return json_decode($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return json_encode($value);\n    }\n\n    public function compare($model, $key, $value1, $value2)\n    {\n        return json_decode($value1) == json_decode($value2);\n    }\n}\n\nclass AddressDto\n{\n    public function __construct(public string $lineOne, public string $lineTwo)\n    {\n        //\n    }\n}\n\nclass AsAddress implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return new AddressDto($attributes['address_line_one'], $attributes['address_line_two']);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return ['address_line_one' => $value->lineOne, 'address_line_two' => $value->lineTwo];\n    }\n}\n"
  },
  {
    "path": "tests/Database/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\n\nenum StringStatus: string\n{\n    case draft = 'draft';\n    case pending = 'pending';\n    case done = 'done';\n}\n\nenum IntegerStatus: int\n{\n    case draft = 0;\n    case pending = 1;\n    case done = 2;\n}\n\nenum NonBackedStatus\n{\n    case draft;\n    case pending;\n    case done;\n}\n\nenum ArrayableStatus: string implements Arrayable\n{\n    case pending = 'pending';\n    case done = 'done';\n\n    public function description(): string\n    {\n        return match ($this) {\n            self::pending => 'pending status description',\n            self::done => 'done status description'\n        };\n    }\n\n    public function toArray()\n    {\n        return [\n            'name' => $this->name,\n            'value' => $this->value,\n            'description' => $this->description(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Enums/Bar.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Enums;\n\nenum Bar: int\n{\n    case FOO = 5;\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Enums/Foo.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Enums;\n\nenum Foo: string\n{\n    case BAR = 'bar';\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Factories/Money/PriceFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Factories\\Money;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\n\nclass PriceFactory extends Factory\n{\n    public function definition()\n    {\n        return [\n            'name' => $this->faker->name(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentModelUsingNonIncrementedInt.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentModelUsingNonIncrementedInt extends Model\n{\n    protected $keyType = 'int';\n    public $incrementing = false;\n\n    /**\n     * The table associated with the model.\n     *\n     * @var string\n     */\n    protected $table = 'model';\n\n    /**\n     * Get the default foreign key name for the model.\n     *\n     * @return string\n     */\n    public function getForeignKey()\n    {\n        return 'model_using_non_incremented_int_id';\n    }\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentModelUsingUlid.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentModelUsingUlid extends Model\n{\n    use HasUlids;\n\n    /**\n     * The table associated with the model.\n     *\n     * @var string\n     */\n    protected $table = 'model';\n\n    /**\n     * Get the default foreign key name for the model.\n     *\n     * @return string\n     */\n    public function getForeignKey()\n    {\n        return 'model_using_ulid_id';\n    }\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentModelUsingUuid.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentModelUsingUuid extends Model\n{\n    /**\n     * The table associated with the model.\n     *\n     * @var string\n     */\n    protected $table = 'model';\n\n    /**\n     * The \"type\" of the primary key ID.\n     *\n     * @var string\n     */\n    protected $keyType = 'string';\n\n    /**\n     * Indicates if the IDs are auto-incrementing.\n     *\n     * @var bool\n     */\n    public $incrementing = false;\n\n    /**\n     * Get the default foreign key name for the model.\n     *\n     * @return string\n     */\n    public function getForeignKey()\n    {\n        return 'model_using_uuid_id';\n    }\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentResourceCollectionTestModel.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentResourceCollectionTestModel extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentResourceTestResourceModel.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentResourceTestResourceModel extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentResourceTestResourceModelWithGuessableResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentResourceTestResourceModelWithGuessableResource extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentResourceTestResourceModelWithUseResourceAttribute.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceTestJsonResource;\n\n#[UseResource(EloquentResourceTestJsonResource::class)]\nclass EloquentResourceTestResourceModelWithUseResourceAttribute extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/EloquentResourceTestResourceModelWithUseResourceCollectionAttribute.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResourceCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Tests\\Database\\Fixtures\\Resources\\EloquentResourceTestJsonResourceCollection;\n\n#[UseResourceCollection(EloquentResourceTestJsonResourceCollection::class)]\nclass EloquentResourceTestResourceModelWithUseResourceCollectionAttribute extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/Money/Price.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models\\Money;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Tests\\Database\\Fixtures\\Factories\\Money\\PriceFactory;\n\nclass Price extends Model\n{\n    /** @use HasFactory<PriceFactory> */\n    use HasFactory;\n\n    protected $table = 'prices';\n\n    protected static string $factory = PriceFactory::class;\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Models/User.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Models;\n\nuse Illuminate\\Foundation\\Auth\\User as FoundationUser;\n\nclass User extends FoundationUser\n{\n    protected $primaryKey = 'internal_id';\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Resources/EloquentResourceCollectionTestResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Resources;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass EloquentResourceCollectionTestResource extends JsonResource\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Resources/EloquentResourceTestJsonResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Resources;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass EloquentResourceTestJsonResource extends JsonResource\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/Fixtures/Resources/EloquentResourceTestJsonResourceCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Fixtures\\Resources;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass EloquentResourceTestJsonResourceCollection extends ResourceCollection\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/PruneCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Closure;\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Console\\PruneCommand;\nuse Illuminate\\Database\\Events\\ModelPruningFinished;\nuse Illuminate\\Database\\Events\\ModelPruningStarting;\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Application;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nclass PruneCommandTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Application::setInstance($container = new Application(__DIR__.'/Pruning'));\n\n        Closure::bind(\n            fn () => $this->namespace = 'Illuminate\\\\Tests\\\\Database\\\\Pruning\\\\',\n            $container,\n            Application::class,\n        )();\n\n        $container->useAppPath(__DIR__.'/Pruning');\n\n        $container->singleton(DispatcherContract::class, function () {\n            return new Dispatcher();\n        });\n\n        $container->alias(DispatcherContract::class, 'events');\n    }\n\n    public function testPrunableModelAndExceptWithEachOther(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The --models and --except options cannot be combined.');\n\n        $this->artisan([\n            '--model' => Pruning\\Models\\PrunableTestModelWithPrunableRecords::class,\n            '--except' => Pruning\\Models\\PrunableTestModelWithPrunableRecords::class,\n        ]);\n    }\n\n    public function testPrunableModelWithPrunableRecords()\n    {\n        $output = $this->artisan(['--model' => Pruning\\Models\\PrunableTestModelWithPrunableRecords::class]);\n\n        $output = $output->fetch();\n\n        $this->assertStringContainsString(\n            'Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestModelWithPrunableRecords',\n            $output,\n        );\n\n        $this->assertStringContainsString(\n            '10 records',\n            $output,\n        );\n\n        $this->assertStringContainsString(\n            'Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestModelWithPrunableRecords',\n            $output,\n        );\n\n        $this->assertStringContainsString(\n            '20 records',\n            $output,\n        );\n    }\n\n    public function testPrunableTestModelWithoutPrunableRecords()\n    {\n        $output = $this->artisan(['--model' => Pruning\\Models\\PrunableTestModelWithoutPrunableRecords::class]);\n\n        $this->assertStringContainsString(\n            'No prunable [Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestModelWithoutPrunableRecords] records found.',\n            $output->fetch()\n        );\n    }\n\n    public function testPrunableSoftDeletedModelWithPrunableRecords()\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        DB::connection('default')->getSchemaBuilder()->create('prunables', function ($table) {\n            $table->string('value')->nullable();\n            $table->datetime('deleted_at')->nullable();\n        });\n        DB::connection('default')->table('prunables')->insert([\n            ['value' => 1, 'deleted_at' => null],\n            ['value' => 2, 'deleted_at' => '2021-12-01 00:00:00'],\n            ['value' => 3, 'deleted_at' => null],\n            ['value' => 4, 'deleted_at' => '2021-12-02 00:00:00'],\n        ]);\n\n        $output = $this->artisan(['--model' => Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords::class]);\n\n        $output = $output->fetch();\n\n        $this->assertStringContainsString(\n            'Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords',\n            $output,\n        );\n\n        $this->assertStringContainsString(\n            '2 records',\n            $output,\n        );\n\n        $this->assertEquals(2, Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords::withTrashed()->count());\n    }\n\n    public function testNonPrunableTest()\n    {\n        $output = $this->artisan(['--model' => Pruning\\Models\\NonPrunableTestModel::class]);\n\n        $this->assertStringContainsString(\n            'No prunable [Illuminate\\Tests\\Database\\Pruning\\Models\\NonPrunableTestModel] records found.',\n            $output->fetch(),\n        );\n    }\n\n    public function testNonPrunableTestWithATrait()\n    {\n        $output = $this->artisan(['--model' => Pruning\\Models\\NonPrunableTrait::class]);\n\n        $this->assertStringContainsString(\n            'No prunable models found.',\n            $output->fetch(),\n        );\n    }\n\n    public function testNonModelFilesAreIgnoredTest()\n    {\n        $output = $this->artisan(['--path' => 'Models']);\n\n        $output = $output->fetch();\n\n        $this->assertStringNotContainsString(\n            'No prunable [Illuminate\\Tests\\Database\\Pruning\\Models\\AbstractPrunableModel] records found.',\n            $output,\n        );\n\n        $this->assertStringNotContainsString(\n            'No prunable [Illuminate\\Tests\\Database\\Pruning\\Models\\SomeClass] records found.',\n            $output,\n        );\n\n        $this->assertStringNotContainsString(\n            'No prunable [Illuminate\\Tests\\Database\\Pruning\\Models\\SomeEnum] records found.',\n            $output,\n        );\n    }\n\n    public function testTheCommandMayBePretended()\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        DB::connection('default')->getSchemaBuilder()->create('prunables', function ($table) {\n            $table->string('name')->nullable();\n            $table->string('value')->nullable();\n        });\n        DB::connection('default')->table('prunables')->insert([\n            ['name' => 'zain', 'value' => 1],\n            ['name' => 'patrice', 'value' => 2],\n            ['name' => 'amelia', 'value' => 3],\n            ['name' => 'stuart', 'value' => 4],\n            ['name' => 'bello', 'value' => 5],\n        ]);\n\n        $output = $this->artisan([\n            '--model' => Pruning\\Models\\PrunableTestModelWithPrunableRecords::class,\n            '--pretend' => true,\n        ]);\n\n        $this->assertStringContainsString(\n            '3 [Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestModelWithPrunableRecords] records will be pruned.',\n            $output->fetch(),\n        );\n\n        $this->assertEquals(5, Pruning\\Models\\PrunableTestModelWithPrunableRecords::count());\n    }\n\n    public function testTheCommandMayBePretendedOnSoftDeletedModel()\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->bootEloquent();\n        $db->setAsGlobal();\n        DB::connection('default')->getSchemaBuilder()->create('prunables', function ($table) {\n            $table->string('value')->nullable();\n            $table->datetime('deleted_at')->nullable();\n        });\n        DB::connection('default')->table('prunables')->insert([\n            ['value' => 1, 'deleted_at' => null],\n            ['value' => 2, 'deleted_at' => '2021-12-01 00:00:00'],\n            ['value' => 3, 'deleted_at' => null],\n            ['value' => 4, 'deleted_at' => '2021-12-02 00:00:00'],\n        ]);\n\n        $output = $this->artisan([\n            '--model' => Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords::class,\n            '--pretend' => true,\n        ]);\n\n        $this->assertStringContainsString(\n            '2 [Illuminate\\Tests\\Database\\Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords] records will be pruned.',\n            $output->fetch(),\n        );\n\n        $this->assertEquals(4, Pruning\\Models\\PrunableTestSoftDeletedModelWithPrunableRecords::withTrashed()->count());\n    }\n\n    public function testTheCommandDispatchesEvents()\n    {\n        $dispatcher = m::mock(DispatcherContract::class);\n\n        $dispatcher->shouldReceive('dispatch')->once()->withArgs(function ($event) {\n            return get_class($event) === ModelPruningStarting::class &&\n                $event->models === [Pruning\\Models\\PrunableTestModelWithPrunableRecords::class];\n        });\n        $dispatcher->shouldReceive('listen')->once()->with(ModelsPruned::class, m::type(Closure::class));\n        $dispatcher->shouldReceive('dispatch')->twice()->with(m::type(ModelsPruned::class));\n        $dispatcher->shouldReceive('dispatch')->once()->withArgs(function ($event) {\n            return get_class($event) === ModelPruningFinished::class &&\n                $event->models === [Pruning\\Models\\PrunableTestModelWithPrunableRecords::class];\n        });\n        $dispatcher->shouldReceive('forget')->once()->with(ModelsPruned::class);\n\n        Application::getInstance()->instance(DispatcherContract::class, $dispatcher);\n\n        $this->artisan(['--model' => Pruning\\Models\\PrunableTestModelWithPrunableRecords::class]);\n    }\n\n    protected function artisan($arguments)\n    {\n        $input = new ArrayInput($arguments);\n        $output = new BufferedOutput;\n\n        tap(new PruneCommand())\n            ->setLaravel(Application::getInstance())\n            ->run($input, $output);\n\n        return $output;\n    }\n\n    protected function tearDown(): void\n    {\n        Application::setInstance(null);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/AbstractPrunableModel.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Prunable;\n\nabstract class AbstractPrunableModel extends Model\n{\n    use Prunable;\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/NonPrunableTestModel.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass NonPrunableTestModel extends Model\n{\n    // ..\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/NonPrunableTrait.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Prunable;\n\ntrait NonPrunableTrait\n{\n    use Prunable;\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/PrunableTestModelWithPrunableRecords.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\MassPrunable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Events\\ModelsPruned;\n\nclass PrunableTestModelWithPrunableRecords extends Model\n{\n    use MassPrunable;\n\n    protected $table = 'prunables';\n    protected $connection = 'default';\n\n    public function pruneAll()\n    {\n        event(new ModelsPruned(static::class, 10));\n        event(new ModelsPruned(static::class, 20));\n\n        return 20;\n    }\n\n    public function prunable()\n    {\n        return static::where('value', '>=', 3);\n    }\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/PrunableTestModelWithoutPrunableRecords.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Prunable;\n\nclass PrunableTestModelWithoutPrunableRecords extends Model\n{\n    use Prunable;\n\n    public function pruneAll()\n    {\n        return 0;\n    }\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/PrunableTestSoftDeletedModelWithPrunableRecords.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nuse Illuminate\\Database\\Eloquent\\MassPrunable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\n\nclass PrunableTestSoftDeletedModelWithPrunableRecords extends Model\n{\n    use MassPrunable, SoftDeletes;\n\n    protected $table = 'prunables';\n    protected $connection = 'default';\n\n    public function prunable()\n    {\n        return static::where('value', '>=', 3);\n    }\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/SomeClass.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nclass SomeClass\n{\n}\n"
  },
  {
    "path": "tests/Database/Pruning/Models/SomeEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\Pruning\\Models;\n\nenum SomeEnum\n{\n    case Foo;\n}\n"
  },
  {
    "path": "tests/Database/QueryDurationThresholdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse PDO;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueryDurationThresholdTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Support\\Carbon\n     */\n    protected $now;\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function testItCanHandleReachingADurationThresholdInTheDb()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = 0;\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1.1), function () use (&$called) {\n            $called++;\n        });\n\n        $connection->logQuery('xxxx', [], 1.0);\n        $connection->logQuery('xxxx', [], 0.1);\n        $this->assertSame(0, $called);\n\n        $connection->logQuery('xxxx', [], 0.1);\n        $this->assertSame(1, $called);\n    }\n\n    public function testItIsOnlyCalledOnce()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = 0;\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function () use (&$called) {\n            $called++;\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n\n        $this->assertSame(1, $called);\n    }\n\n    public function testItIsOnlyCalledOnceWhenGivenDateTime()\n    {\n        Carbon::setTestNow($this->now = Carbon::create(2017, 6, 27, 13, 14, 15, 'UTC'));\n\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = 0;\n        $connection->whenQueryingForLongerThan($this->now->addMilliseconds(1), function () use (&$called) {\n            $called++;\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n\n        $this->assertSame(1, $called);\n    }\n\n    public function testItCanSpecifyMultipleHandlersWithTheSameIntervals()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = [];\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function () use (&$called) {\n            $called['a'] = true;\n        });\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function () use (&$called) {\n            $called['b'] = true;\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n\n        $this->assertSame([\n            'a' => true,\n            'b' => true,\n        ], $called);\n    }\n\n    public function testItCanSpecifyMultipleHandlersWithDifferentIntervals()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = [];\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function () use (&$called) {\n            $called['a'] = true;\n        });\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(2), function () use (&$called) {\n            $called['b'] = true;\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $this->assertSame([\n            'a' => true,\n        ], $called);\n\n        $connection->logQuery('xxxx', [], 1);\n        $this->assertSame([\n            'a' => true,\n            'b' => true,\n        ], $called);\n    }\n\n    public function testItHasAccessToConnectionInHandler()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'), '', '', ['name' => 'expected-name']);\n        $connection->setEventDispatcher(new Dispatcher());\n        $name = null;\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function ($connection) use (&$name) {\n            $name = $connection->getName();\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n\n        $this->assertSame('expected-name', $name);\n    }\n\n    public function testItHasSpecifyThresholdWithFloat()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = false;\n        $connection->whenQueryingForLongerThan(1.1, function () use (&$called) {\n            $called = true;\n        });\n\n        $connection->logQuery('xxxx', [], 1.1);\n        $this->assertFalse($called);\n\n        $connection->logQuery('xxxx', [], 0.1);\n        $this->assertTrue($called);\n    }\n\n    public function testItHasSpecifyThresholdWithInt()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = false;\n        $connection->whenQueryingForLongerThan(2, function () use (&$called) {\n            $called = true;\n        });\n\n        $connection->logQuery('xxxx', [], 1.1);\n        $this->assertFalse($called);\n\n        $connection->logQuery('xxxx', [], 1.0);\n        $this->assertTrue($called);\n    }\n\n    public function testItCanResetTotalQueryDuration()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n\n        $connection->logQuery('xxxx', [], 1.1);\n        $this->assertSame(1.1, $connection->totalQueryDuration());\n        $connection->logQuery('xxxx', [], 1.1);\n        $this->assertSame(2.2, $connection->totalQueryDuration());\n\n        $connection->resetTotalQueryDuration();\n        $this->assertSame(0.0, $connection->totalQueryDuration());\n    }\n\n    public function testItCanRestoreAlreadyRunHandlers()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $called = 0;\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(1), function () use (&$called) {\n            $called++;\n        });\n\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $this->assertSame(1, $called);\n\n        $connection->allowQueryDurationHandlersToRunAgain();\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $this->assertSame(2, $called);\n\n        $connection->allowQueryDurationHandlersToRunAgain();\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $connection->logQuery('xxxx', [], 1);\n        $this->assertSame(3, $called);\n    }\n\n    public function testItCanAccessAllQueriesWhenQueryLoggingIsActive()\n    {\n        $connection = new Connection(new PDO('sqlite::memory:'));\n        $connection->setEventDispatcher(new Dispatcher());\n        $connection->enableQueryLog();\n        $queries = [];\n        $connection->whenQueryingForLongerThan(CarbonInterval::milliseconds(2), function ($connection, $event) use (&$queries) {\n            $queries = Arr::pluck($connection->getQueryLog(), 'query');\n            $queries[] = $event->sql;\n        });\n\n        $connection->logQuery('foo', [], 1);\n        $connection->logQuery('bar', [], 1);\n        $connection->logQuery('baz', [], 1);\n\n        $this->assertSame([\n            'foo',\n            'bar',\n            'baz',\n        ], $queries);\n    }\n}\n"
  },
  {
    "path": "tests/Database/SeedCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\OutputStyle;\nuse Illuminate\\Console\\View\\Components\\Factory;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\Console\\Seeds\\SeedCommand;\nuse Illuminate\\Database\\Console\\Seeds\\WithoutModelEvents;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Seeder;\nuse Illuminate\\Events\\NullDispatcher;\nuse Illuminate\\Testing\\Assert;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass SeedCommandTest extends TestCase\n{\n    public function testHandle()\n    {\n        $input = new ArrayInput(['--force' => true, '--database' => 'sqlite']);\n        $output = new NullOutput;\n        $outputStyle = new OutputStyle($input, $output);\n\n        $seeder = m::mock(Seeder::class);\n        $seeder->shouldReceive('setContainer')->once()->andReturnSelf();\n        $seeder->shouldReceive('setCommand')->once()->andReturnSelf();\n        $seeder->shouldReceive('__invoke')->once();\n\n        $resolver = m::mock(ConnectionResolverInterface::class);\n        $resolver->shouldReceive('getDefaultConnection')->once();\n        $resolver->shouldReceive('setDefaultConnection')->once()->with('sqlite');\n\n        $container = m::mock(Container::class);\n        $container->shouldReceive('call');\n        $container->shouldReceive('environment')->once()->andReturn('testing');\n        $container->shouldReceive('runningUnitTests')->andReturn('true');\n        $container->shouldReceive('make')->with('DatabaseSeeder')->andReturn($seeder);\n        $container->shouldReceive('make')->with(OutputStyle::class, m::any())->andReturn(\n            $outputStyle\n        );\n        $container->shouldReceive('make')->with(Factory::class, m::any())->andReturn(\n            new Factory($outputStyle)\n        );\n\n        $command = new SeedCommand($resolver);\n        $command->setLaravel($container);\n\n        // call run to set up IO, then fire manually.\n        $command->run($input, $output);\n        $command->handle();\n\n        $container->shouldHaveReceived('call')->with([$command, 'handle']);\n    }\n\n    public function testWithoutModelEvents()\n    {\n        $input = new ArrayInput([\n            '--force' => true,\n            '--database' => 'sqlite',\n            '--class' => UserWithoutModelEventsSeeder::class,\n        ]);\n        $output = new NullOutput;\n        $outputStyle = new OutputStyle($input, $output);\n\n        $instance = new UserWithoutModelEventsSeeder();\n\n        $seeder = m::mock($instance);\n        $seeder->shouldReceive('setContainer')->once()->andReturnSelf();\n        $seeder->shouldReceive('setCommand')->once()->andReturnSelf();\n\n        $resolver = m::mock(ConnectionResolverInterface::class);\n        $resolver->shouldReceive('getDefaultConnection')->once();\n        $resolver->shouldReceive('setDefaultConnection')->once()->with('sqlite');\n\n        $container = m::mock(Container::class);\n        $container->shouldReceive('call');\n        $container->shouldReceive('environment')->once()->andReturn('testing');\n        $container->shouldReceive('runningUnitTests')->andReturn('true');\n        $container->shouldReceive('make')->with(UserWithoutModelEventsSeeder::class)->andReturn($seeder);\n        $container->shouldReceive('make')->with(OutputStyle::class, m::any())->andReturn(\n            $outputStyle\n        );\n        $container->shouldReceive('make')->with(Factory::class, m::any())->andReturn(\n            new Factory($outputStyle)\n        );\n\n        $command = new SeedCommand($resolver);\n        $command->setLaravel($container);\n\n        Model::setEventDispatcher($dispatcher = m::mock(Dispatcher::class));\n\n        // call run to set up IO, then fire manually.\n        $command->run($input, $output);\n        $command->handle();\n\n        Assert::assertSame($dispatcher, Model::getEventDispatcher());\n\n        $container->shouldHaveReceived('call')->with([$command, 'handle']);\n    }\n\n    public function testProhibitable()\n    {\n        $input = new ArrayInput([]);\n        $output = new NullOutput;\n        $outputStyle = new OutputStyle($input, $output);\n\n        $resolver = m::mock(ConnectionResolverInterface::class);\n\n        $container = m::mock(Container::class);\n        $container->shouldReceive('call');\n        $container->shouldReceive('runningUnitTests')->andReturn('true');\n        $container->shouldReceive('make')->with(OutputStyle::class, m::any())->andReturn(\n            $outputStyle\n        );\n        $container->shouldReceive('make')->with(Factory::class, m::any())->andReturn(\n            new Factory($outputStyle)\n        );\n\n        $command = new SeedCommand($resolver);\n        $command->setLaravel($container);\n\n        // call run to set up IO, then fire manually.\n        $command->run($input, $output);\n\n        SeedCommand::prohibit();\n\n        Assert::assertSame(Command::FAILURE, $command->handle());\n    }\n\n    protected function tearDown(): void\n    {\n        SeedCommand::prohibit(false);\n\n        Model::unsetEventDispatcher();\n\n        parent::tearDown();\n    }\n}\n\nclass UserWithoutModelEventsSeeder extends Seeder\n{\n    use WithoutModelEvents;\n\n    public function run()\n    {\n        Assert::assertInstanceOf(NullDispatcher::class, Model::getEventDispatcher());\n    }\n}\n"
  },
  {
    "path": "tests/Database/SqlServerBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\Grammars\\SqlServerGrammar;\nuse Illuminate\\Database\\Schema\\SqlServerBuilder;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SqlServerBuilderTest extends TestCase\n{\n    public function testCreateDatabase()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new SqlServerGrammar($connection);\n\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'create database \"my_temporary_database_a\"'\n        )->andReturn(true);\n\n        $builder = new SqlServerBuilder($connection);\n        $builder->createDatabase('my_temporary_database_a');\n    }\n\n    public function testDropDatabaseIfExists()\n    {\n        $connection = m::mock(Connection::class);\n        $grammar = new SqlServerGrammar($connection);\n\n        $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar);\n        $connection->shouldReceive('statement')->once()->with(\n            'drop database if exists \"my_temporary_database_b\"'\n        )->andReturn(true);\n\n        $builder = new SqlServerBuilder($connection);\n\n        $builder->dropDatabaseIfExists('my_temporary_database_b');\n    }\n}\n"
  },
  {
    "path": "tests/Database/TableGuesserTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database;\n\nuse Illuminate\\Database\\Console\\Migrations\\TableGuesser;\nuse PHPUnit\\Framework\\TestCase;\n\nclass TableGuesserTest extends TestCase\n{\n    public function testMigrationIsProperlyParsed()\n    {\n        [$table, $create] = TableGuesser::guess('create_users_table');\n        $this->assertSame('users', $table);\n        $this->assertTrue($create);\n\n        [$table, $create] = TableGuesser::guess('add_status_column_to_users_table');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_to_users_table');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('change_status_column_in_users_table');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('drop_status_column_from_users_table');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n    }\n\n    public function testMigrationIsProperlyParsedWithoutTableSuffix()\n    {\n        [$table, $create] = TableGuesser::guess('create_users');\n        $this->assertSame('users', $table);\n        $this->assertTrue($create);\n\n        [$table, $create] = TableGuesser::guess('add_status_column_to_users');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('add_is_sent_to_crm_column_column_to_users');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('change_status_column_in_users');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n\n        [$table, $create] = TableGuesser::guess('drop_status_column_from_users');\n        $this->assertSame('users', $table);\n        $this->assertFalse($create);\n    }\n}\n"
  },
  {
    "path": "tests/Database/migrations/connection_configured/2022_02_21_000000_create_failed_jobs_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * The database connection that should be used by the migration.\n     *\n     * @var string\n     */\n    protected $connection = 'sqlite3';\n\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('failed_jobs', function (Blueprint $table) {\n            $table->id();\n            $table->text('connection');\n            $table->text('queue');\n            $table->longText('payload');\n            $table->longText('exception');\n            $table->timestamp('failed_at')->useCurrent();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('failed_jobs');\n    }\n};\n"
  },
  {
    "path": "tests/Database/migrations/connection_configured/2022_02_21_120000_create_jobs_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::connection('sqlite3')->create('jobs', function (Blueprint $table) {\n            $table->bigIncrements('id');\n            $table->string('queue')->index();\n            $table->longText('payload');\n            $table->unsignedTinyInteger('attempts');\n            $table->unsignedInteger('reserved_at')->nullable();\n            $table->unsignedInteger('available_at');\n            $table->unsignedInteger('created_at');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::connection('sqlite3')->dropIfExists('jobs');\n    }\n};\n"
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2016_01_01_000000_create_users_table.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000001_rename_table_one.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000002_rename_table_two.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000003_rename_table_three.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000004_rename_table_four.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000005_create_table_one.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000006_create_table_two.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/app/2019_08_08_000008_create_table_four.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2016_01_01_200000_create_flights_table.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000001_rename_table_one.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000002_rename_table_two.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000003_rename_table_three.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000004_rename_table_four.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000005_create_table_one.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000006_create_table_two.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000007_create_table_three.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/multi_path/vendor/2019_08_08_000008_create_table_four.php",
    "content": ""
  },
  {
    "path": "tests/Database/migrations/one/2016_01_01_000000_create_users_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreateUsersTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('email')->unique();\n            $table->string('password');\n            $table->rememberToken();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('users');\n    }\n}\n"
  },
  {
    "path": "tests/Database/migrations/one/2016_01_01_100000_create_password_resets_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreatePasswordResetsTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('password_resets', function (Blueprint $table) {\n            $table->string('email')->index();\n            $table->string('token')->index();\n            $table->timestamp('created_at');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('password_resets');\n    }\n}\n"
  },
  {
    "path": "tests/Database/migrations/should_run/2016_01_01_200000_create_flights_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreateFlightsTable extends Migration\n{\n    public function shouldRun(): bool\n    {\n        return false;\n    }\n\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('flights', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('flights');\n    }\n}\n"
  },
  {
    "path": "tests/Database/migrations/two/2016_01_01_200000_create_flights_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreateFlightsTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('flights', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::dropIfExists('flights');\n    }\n}\n"
  },
  {
    "path": "tests/Database/stubs/EloquentModelNamespacedStub.php",
    "content": "<?php\n\nnamespace Foo\\Bar;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentModelNamespacedStub extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/stubs/MigrationCreatorFakeMigration.php",
    "content": "<?php\n\nclass MigrationCreatorFakeMigration\n{\n    //\n}\n"
  },
  {
    "path": "tests/Database/stubs/TestCast.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\stubs;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass TestCast implements CastsAttributes\n{\n    /**\n     * @param  Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return TestValueObject|null\n     */\n    public function get(Model $model, string $key, mixed $value, array $attributes)\n    {\n        if (! json_validate($value)) {\n            return null;\n        }\n        $value = json_decode($value, true);\n        if (! is_array($value)) {\n            return null;\n        }\n\n        return TestValueObject::make($value);\n    }\n\n    /**\n     * @param  Model  $model\n     * @param  string  $key\n     * @param  mixed  $value\n     * @param  array  $attributes\n     * @return array\n     */\n    public function set(Model $model, string $key, mixed $value, array $attributes)\n    {\n        if (! $value instanceof TestValueObject) {\n            return [\n                $key => null,\n            ];\n        }\n\n        return [\n            $key => json_encode($value->toArray()),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Database/stubs/TestEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\stubs;\n\nenum TestEnum: string\n{\n    case test = 'test';\n}\n"
  },
  {
    "path": "tests/Database/stubs/TestValueObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Database\\stubs;\n\nclass TestValueObject\n{\n    private string $myPropertyA;\n    private string $myPropertyB;\n\n    public static function make(?array $test): self\n    {\n        $self = new self;\n        if (! empty($test['myPropertyA'])) {\n            $self->myPropertyA = $test['myPropertyA'];\n        }\n        if (! empty($test['myPropertyB'])) {\n            $self->myPropertyB = $test['myPropertyB'];\n        }\n\n        return $self;\n    }\n\n    public function toArray(): array\n    {\n        if (isset($this->myPropertyA)) {\n            $result['myPropertyA'] = $this->myPropertyA;\n        }\n        if (isset($this->myPropertyB)) {\n            $result['myPropertyB'] = $this->myPropertyB;\n        }\n\n        return $result ?? [];\n    }\n}\n"
  },
  {
    "path": "tests/Database/stubs/schema.sql",
    "content": ""
  },
  {
    "path": "tests/Encryption/EncrypterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Encryption;\n\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Encryption\\Encrypter;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass EncrypterTest extends TestCase\n{\n    public function testEncryption(): void\n    {\n        $e = new Encrypter(str_repeat('a', 16));\n        $encrypted = $e->encrypt('foo');\n        $this->assertNotSame('foo', $encrypted);\n        $this->assertSame('foo', $e->decrypt($encrypted));\n\n        $encrypted = $e->encrypt('');\n        $this->assertSame('', $e->decrypt($encrypted));\n\n        $longString = str_repeat('a', 1000);\n        $encrypted = $e->encrypt($longString);\n        $this->assertSame($longString, $e->decrypt($encrypted));\n\n        $data = ['foo' => 'bar', 'baz' => 'qux'];\n        $encryptedArray = $e->encrypt($data);\n        $this->assertNotSame($data, $encryptedArray);\n        $this->assertSame($data, $e->decrypt($encryptedArray));\n    }\n\n    public function testRawStringEncryption()\n    {\n        $e = new Encrypter(str_repeat('a', 16));\n        $encrypted = $e->encryptString('foo');\n        $this->assertNotSame('foo', $encrypted);\n        $this->assertSame('foo', $e->decryptString($encrypted));\n    }\n\n    public function testRawStringEncryptionWithPreviousKeys()\n    {\n        $previous = new Encrypter(str_repeat('b', 16));\n        $previousValue = $previous->encryptString('foo');\n\n        $new = new Encrypter(str_repeat('a', 16));\n        $new->previousKeys([str_repeat('b', 16)]);\n\n        $decrypted = $new->decryptString($previousValue);\n        $this->assertSame('foo', $decrypted);\n    }\n\n    public function testItValidatesMacOnPerKeyBasis()\n    {\n        // Payload created with (key: str_repeat('b', 16)) but will\n        // \"successfully\" decrypt with (key: str_repeat('a', 16)), however it\n        // outputs a random binary string as it is not the correct key.\n        $encrypted = 'eyJpdiI6Ilg0dFM5TVRibEFqZW54c3lQdWJoVVE9PSIsInZhbHVlIjoiRGJpa2p2ZHI3eUs0dUtRakJneUhUUT09IiwibWFjIjoiMjBjZWYxODdhNThhOTk4MTk1NTc0YTE1MDgzODU1OWE0ZmQ4MDc5ZjMxYThkOGM1ZmM1MzlmYzBkYTBjMWI1ZiIsInRhZyI6IiJ9';\n\n        $new = new Encrypter(str_repeat('a', 16));\n        $new->previousKeys([str_repeat('b', 16)]);\n        $this->assertSame('foo', $new->decryptString($encrypted));\n    }\n\n    public function testEncryptionUsingBase64EncodedKey()\n    {\n        $e = new Encrypter(random_bytes(16));\n        $encrypted = $e->encrypt('foo');\n        $this->assertNotSame('foo', $encrypted);\n        $this->assertSame('foo', $e->decrypt($encrypted));\n    }\n\n    public function testEncryptedLengthIsFixed()\n    {\n        $e = new Encrypter(str_repeat('a', 16));\n        $lengths = [];\n        for ($i = 0; $i < 100; $i++) {\n            $lengths[] = strlen($e->encrypt('foo'));\n        }\n        $this->assertSame(min($lengths), max($lengths));\n    }\n\n    public function testWithCustomCipher()\n    {\n        $e = new Encrypter(str_repeat('b', 32), 'AES-256-GCM');\n        $encrypted = $e->encrypt('bar');\n        $this->assertNotSame('bar', $encrypted);\n        $this->assertSame('bar', $e->decrypt($encrypted));\n\n        $e = new Encrypter(random_bytes(32), 'AES-256-GCM');\n        $encrypted = $e->encrypt('foo');\n        $this->assertNotSame('foo', $encrypted);\n        $this->assertSame('foo', $e->decrypt($encrypted));\n    }\n\n    public function testCipherNamesCanBeMixedCase()\n    {\n        $upper = new Encrypter(str_repeat('b', 16), 'AES-128-GCM');\n        $encrypted = $upper->encrypt('bar');\n        $this->assertNotSame('bar', $encrypted);\n\n        $lower = new Encrypter(str_repeat('b', 16), 'aes-128-gcm');\n        $this->assertSame('bar', $lower->decrypt($encrypted));\n\n        $mixed = new Encrypter(str_repeat('b', 16), 'aEs-128-GcM');\n        $this->assertSame('bar', $mixed->decrypt($encrypted));\n    }\n\n    public function testThatAnAeadCipherIncludesTag()\n    {\n        $e = new Encrypter(str_repeat('b', 32), 'AES-256-GCM');\n        $encrypted = $e->encrypt('foo');\n        $data = json_decode(base64_decode($encrypted));\n\n        $this->assertEmpty($data->mac);\n        $this->assertNotEmpty($data->tag);\n    }\n\n    public function testThatAnAeadTagMustBeProvidedInFullLength()\n    {\n        $e = new Encrypter(str_repeat('b', 32), 'AES-256-GCM');\n        $encrypted = $e->encrypt('foo');\n        $data = json_decode(base64_decode($encrypted));\n\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('Could not decrypt the data.');\n\n        $data->tag = substr($data->tag, 0, 4);\n        $encrypted = base64_encode(json_encode($data));\n        $e->decrypt($encrypted);\n    }\n\n    public function testThatAnAeadTagCantBeModified()\n    {\n        $e = new Encrypter(str_repeat('b', 32), 'AES-256-GCM');\n        $encrypted = $e->encrypt('foo');\n        $data = json_decode(base64_decode($encrypted));\n\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('Could not decrypt the data.');\n\n        $data->tag[0] = $data->tag[0] === 'A' ? 'B' : 'A';\n        $encrypted = base64_encode(json_encode($data));\n        $e->decrypt($encrypted);\n    }\n\n    public function testThatANonAeadCipherIncludesMac()\n    {\n        $e = new Encrypter(str_repeat('b', 32), 'AES-256-CBC');\n        $encrypted = $e->encrypt('foo');\n        $data = json_decode(base64_decode($encrypted));\n\n        $this->assertEmpty($data->tag);\n        $this->assertNotEmpty($data->mac);\n    }\n\n    public function testDoNoAllowLongerKey()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unsupported cipher or incorrect key length. Supported ciphers are: aes-128-cbc, aes-256-cbc, aes-128-gcm, aes-256-gcm.');\n\n        new Encrypter(str_repeat('z', 32));\n    }\n\n    public function testWithBadKeyLength()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unsupported cipher or incorrect key length. Supported ciphers are: aes-128-cbc, aes-256-cbc, aes-128-gcm, aes-256-gcm.');\n\n        new Encrypter(str_repeat('a', 5));\n    }\n\n    public function testWithBadKeyLengthAlternativeCipher()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unsupported cipher or incorrect key length. Supported ciphers are: aes-128-cbc, aes-256-cbc, aes-128-gcm, aes-256-gcm.');\n\n        new Encrypter(str_repeat('a', 16), 'AES-256-GCM');\n    }\n\n    public function testWithUnsupportedCipher()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unsupported cipher or incorrect key length. Supported ciphers are: aes-128-cbc, aes-256-cbc, aes-128-gcm, aes-256-gcm.');\n\n        new Encrypter(str_repeat('c', 16), 'AES-256-CFB8');\n    }\n\n    public function testExceptionThrownWhenPayloadIsInvalid()\n    {\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('The payload is invalid.');\n\n        $e = new Encrypter(str_repeat('a', 16));\n        $payload = $e->encrypt('foo');\n        $payload = str_shuffle($payload);\n        $e->decrypt($payload);\n    }\n\n    public function testDecryptionExceptionIsThrownWhenUnexpectedTagIsAdded()\n    {\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('Unable to use tag because the cipher algorithm does not support AEAD.');\n\n        $e = new Encrypter(str_repeat('a', 16));\n        $payload = $e->encrypt('foo');\n        $decodedPayload = json_decode(base64_decode($payload));\n        $decodedPayload->tag = 'set-manually';\n        $e->decrypt(base64_encode(json_encode($decodedPayload)));\n    }\n\n    public function testExceptionThrownWithDifferentKey()\n    {\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('The MAC is invalid.');\n\n        $a = new Encrypter(str_repeat('a', 16));\n        $b = new Encrypter(str_repeat('b', 16));\n        $b->decrypt($a->encrypt('baz'));\n    }\n\n    public function testExceptionThrownWhenIvIsTooLong()\n    {\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('The payload is invalid.');\n\n        $e = new Encrypter(str_repeat('a', 16));\n        $payload = $e->encrypt('foo');\n        $data = json_decode(base64_decode($payload), true);\n        $data['iv'] .= $data['value'][0];\n        $data['value'] = substr($data['value'], 1);\n        $modified_payload = base64_encode(json_encode($data));\n        $e->decrypt($modified_payload);\n    }\n\n    public function testSupportedMethodAcceptsAnyCasing()\n    {\n        $key = str_repeat('a', 16);\n\n        $this->assertTrue(Encrypter::supported($key, 'AES-128-GCM'));\n        $this->assertTrue(Encrypter::supported($key, 'aes-128-CBC'));\n        $this->assertTrue(Encrypter::supported($key, 'aes-128-cbc'));\n    }\n\n    public static function provideTamperedData()\n    {\n        $validIv = base64_encode(str_repeat('.', 16));\n\n        return [\n            [['iv' => ['value_in_array'], 'value' => '', 'mac' => '']],\n            [['iv' => new class() {\n            }, 'value' => '', 'mac' => '']],\n            [['iv' => $validIv, 'value' => ['value_in_array'], 'mac' => '']],\n            [['iv' => $validIv, 'value' => new class() {\n            }, 'mac' => '']],\n            [['iv' => $validIv, 'value' => '', 'mac' => ['value_in_array']]],\n            [['iv' => $validIv, 'value' => '', 'mac' => null]],\n            [['iv' => $validIv, 'value' => '', 'mac' => '', 'tag' => ['value_in_array']]],\n            [['iv' => $validIv, 'value' => '', 'mac' => '', 'tag' => -1]],\n        ];\n    }\n\n    #[DataProvider('provideTamperedData')]\n    public function testTamperedPayloadWillGetRejected($payload)\n    {\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('The payload is invalid.');\n\n        $enc = new Encrypter(str_repeat('x', 16));\n        $enc->decrypt(base64_encode(json_encode($payload)));\n    }\n\n    public function testEncryptedReturnsTrueForEncryptedValue()\n    {\n        $e = new Encrypter(str_repeat('a', 16));\n        $encrypted = $e->encrypt('foo');\n\n        $this->assertTrue(Encrypter::appearsEncrypted($encrypted));\n    }\n\n    public function testEncryptedReturnsTrueForEncryptedArray()\n    {\n        $e = new Encrypter(str_repeat('a', 16));\n        $encrypted = $e->encrypt(['foo' => 'bar']);\n\n        $this->assertTrue(Encrypter::appearsEncrypted($encrypted));\n    }\n\n    public function testEncryptedReturnsFalseForPlainText()\n    {\n        $this->assertFalse(Encrypter::appearsEncrypted('foo'));\n        $this->assertFalse(Encrypter::appearsEncrypted('APP_NAME=Laravel'));\n        $this->assertFalse(Encrypter::appearsEncrypted(\"APP_NAME=Laravel\\nAPP_ENV=local\"));\n    }\n\n    public function testEncryptedReturnsFalseForNonString()\n    {\n        $this->assertFalse(Encrypter::appearsEncrypted(123));\n        $this->assertFalse(Encrypter::appearsEncrypted(['foo' => 'bar']));\n        $this->assertFalse(Encrypter::appearsEncrypted(null));\n    }\n}\n"
  },
  {
    "path": "tests/Events/BroadcastedEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Events;\n\nuse Illuminate\\Broadcasting\\PendingBroadcast;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastFactory;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Events\\Dispatcher;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass BroadcastedEventsTest extends TestCase\n{\n    public function testShouldBroadcastSuccess()\n    {\n        $d = m::mock(Dispatcher::class);\n\n        $d->makePartial()->shouldAllowMockingProtectedMethods();\n\n        $event = new BroadcastEvent;\n\n        $this->assertTrue($d->shouldBroadcast([$event]));\n\n        $event = new AlwaysBroadcastEvent;\n\n        $this->assertTrue($d->shouldBroadcast([$event]));\n    }\n\n    public function testShouldBroadcastAsQueuedAndCallNormalListeners()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $broadcast = m::mock(BroadcastFactory::class);\n        $broadcast->shouldReceive('queue')->once();\n        $container->shouldReceive('make')->once()->with(BroadcastFactory::class)->andReturn($broadcast);\n\n        $d->listen(AlwaysBroadcastEvent::class, function ($payload) {\n            $_SERVER['__event.test'] = $payload;\n        });\n\n        $d->dispatch($e = new AlwaysBroadcastEvent);\n\n        $this->assertSame($e, $_SERVER['__event.test']);\n    }\n\n    public function testShouldBroadcastFail()\n    {\n        $d = m::mock(Dispatcher::class);\n\n        $d->makePartial()->shouldAllowMockingProtectedMethods();\n\n        $event = new BroadcastFalseCondition;\n\n        $this->assertFalse($d->shouldBroadcast([$event]));\n\n        $event = new ExampleEvent;\n\n        $this->assertFalse($d->shouldBroadcast([$event]));\n    }\n\n    public function testBroadcastWithMultipleChannels()\n    {\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $broadcast = m::mock(BroadcastFactory::class);\n        $broadcast->shouldReceive('queue')->once();\n        $container->shouldReceive('make')->once()->with(BroadcastFactory::class)->andReturn($broadcast);\n\n        $event = new class implements ShouldBroadcast\n        {\n            public function broadcastOn()\n            {\n                return ['channel-1', 'channel-2'];\n            }\n        };\n\n        $d->dispatch($event);\n    }\n\n    public function testBroadcastWithCustomConnectionName()\n    {\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $broadcast = m::mock(BroadcastFactory::class);\n        $broadcast->shouldReceive('queue')->once();\n        $container->shouldReceive('make')->once()->with(BroadcastFactory::class)->andReturn($broadcast);\n\n        $event = new class implements ShouldBroadcast\n        {\n            public $connection = 'custom-connection';\n\n            public function broadcastOn()\n            {\n                return ['test-channel'];\n            }\n        };\n\n        $d->dispatch($event);\n    }\n\n    public function testBroadcastWithCustomEventName()\n    {\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $broadcast = m::mock(BroadcastFactory::class);\n        $broadcast->shouldReceive('queue')->once();\n        $container->shouldReceive('make')->once()->with(BroadcastFactory::class)->andReturn($broadcast);\n\n        $event = new class implements ShouldBroadcast\n        {\n            public function broadcastOn()\n            {\n                return ['test-channel'];\n            }\n\n            public function broadcastAs()\n            {\n                return 'custom-event-name';\n            }\n        };\n\n        $d->dispatch($event);\n    }\n\n    public function testBroadcastWithCustomPayload()\n    {\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $broadcast = m::mock(BroadcastFactory::class);\n        $broadcast->shouldReceive('queue')->once();\n        $container->shouldReceive('make')->once()->with(BroadcastFactory::class)->andReturn($broadcast);\n\n        $event = new class implements ShouldBroadcast\n        {\n            public $customData = 'test-data';\n\n            public function broadcastOn()\n            {\n                return ['test-channel'];\n            }\n\n            public function broadcastWith()\n            {\n                return ['custom' => $this->customData];\n            }\n        };\n\n        $d->dispatch($event);\n    }\n\n    public function testEventBroadcastsUsingNamedArguments()\n    {\n        $container = new Container;\n        $broadcast = m::mock(BroadcastFactory::class);\n        $container->instance(BroadcastFactory::class, $broadcast);\n\n        $originalContainer = Container::getInstance();\n        Container::setInstance($container);\n\n        try {\n            $pendingBroadcast = m::mock(PendingBroadcast::class);\n\n            $broadcast->shouldReceive('event')\n                ->once()\n                ->with(m::on(function ($event) {\n                    $this->assertInstanceOf(BroadcastableNamedArgumentsEvent::class, $event);\n                    $this->assertSame('first-value', $event->first);\n                    $this->assertSame('second-value', $event->second);\n\n                    return true;\n                }))\n                ->andReturn($pendingBroadcast);\n\n            $this->assertSame(\n                $pendingBroadcast,\n                BroadcastableNamedArgumentsEvent::broadcast(second: 'second-value', first: 'first-value')\n            );\n        } finally {\n            Container::setInstance($originalContainer);\n        }\n    }\n}\n\nclass BroadcastEvent implements ShouldBroadcast\n{\n    public function broadcastOn()\n    {\n        return ['test-channel'];\n    }\n\n    public function broadcastWhen()\n    {\n        return true;\n    }\n}\n\nclass AlwaysBroadcastEvent implements ShouldBroadcast\n{\n    public function broadcastOn()\n    {\n        return ['test-channel'];\n    }\n}\n\nclass BroadcastFalseCondition extends BroadcastEvent\n{\n    public function broadcastWhen()\n    {\n        return false;\n    }\n}\n\nclass BroadcastableNamedArgumentsEvent\n{\n    use \\Illuminate\\Foundation\\Events\\Dispatchable;\n\n    public function __construct(\n        public string $first,\n        public string $second,\n    ) {\n    }\n}\n"
  },
  {
    "path": "tests/Events/EventsDispatcherTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Events;\n\nuse Error;\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Events\\Dispatcher;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass EventsDispatcherTest extends TestCase\n{\n    public function testBasicEventExecution()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'] = $foo;\n        });\n        $response = $d->dispatch('foo', ['bar']);\n\n        $this->assertEquals([null], $response);\n        $this->assertSame('bar', $_SERVER['__event.test']);\n\n        // we can still add listeners after the event has fired\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'] .= $foo;\n        });\n\n        $d->dispatch('foo', ['bar']);\n        $this->assertSame('barbar', $_SERVER['__event.test']);\n    }\n\n    public function testDeferEventExecution()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'] = $foo;\n        });\n\n        $result = $d->defer(function () use ($d) {\n            $d->dispatch('foo', ['bar']);\n            $this->assertArrayNotHasKey('__event.test', $_SERVER);\n\n            return 'callback_result';\n        });\n\n        $this->assertEquals('callback_result', $result);\n        $this->assertSame('bar', $_SERVER['__event.test']);\n    }\n\n    public function testDeferMultipleEvents()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen('foo', function ($value) {\n            $_SERVER['__event.test'][] = $value;\n        });\n        $d->listen('bar', function ($value) {\n            $_SERVER['__event.test'][] = $value;\n        });\n        $d->defer(function () use ($d) {\n            $d->dispatch('foo', ['foo']);\n            $d->dispatch('bar', ['bar']);\n            $this->assertSame([], $_SERVER['__event.test']);\n        });\n\n        $this->assertSame(['foo', 'bar'], $_SERVER['__event.test']);\n    }\n\n    public function testDeferNestedEvents()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'][] = $foo;\n        });\n\n        $d->defer(function () use ($d) {\n            $d->dispatch('foo', ['outer1']);\n\n            $d->defer(function () use ($d) {\n                $d->dispatch('foo', ['inner']);\n                $this->assertSame([], $_SERVER['__event.test']);\n            });\n\n            $this->assertSame(['inner'], $_SERVER['__event.test']);\n            $d->dispatch('foo', ['outer2']);\n        });\n\n        $this->assertSame(['inner', 'outer1', 'outer2'], $_SERVER['__event.test']);\n    }\n\n    public function testDeferSpecificEvents()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'][] = $foo;\n        });\n\n        $d->listen('bar', function ($bar) {\n            $_SERVER['__event.test'][] = $bar;\n        });\n\n        $d->defer(function () use ($d) {\n            $d->dispatch('foo', ['deferred']);\n            $d->dispatch('bar', ['immediate']);\n\n            $this->assertSame(['immediate'], $_SERVER['__event.test']);\n        }, ['foo']);\n\n        $this->assertSame(['immediate', 'deferred'], $_SERVER['__event.test']);\n    }\n\n    public function testDeferSpecificNestedEvents()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'][] = $foo;\n        });\n\n        $d->listen('bar', function ($bar) {\n            $_SERVER['__event.test'][] = $bar;\n        });\n\n        $d->defer(function () use ($d) {\n            $d->dispatch('foo', ['outer-deferred']);\n            $d->dispatch('bar', ['outer-immediate']);\n\n            $this->assertSame(['outer-immediate'], $_SERVER['__event.test']);\n\n            $d->defer(function () use ($d) {\n                $d->dispatch('foo', ['inner-deferred']);\n                $d->dispatch('bar', ['inner-immediate']);\n\n                $this->assertSame(['outer-immediate', 'inner-immediate'], $_SERVER['__event.test']);\n            }, ['foo']);\n\n            $this->assertSame(['outer-immediate', 'inner-immediate', 'inner-deferred'], $_SERVER['__event.test']);\n        }, ['foo']);\n\n        $this->assertSame(['outer-immediate', 'inner-immediate', 'inner-deferred', 'outer-deferred'], $_SERVER['__event.test']);\n    }\n\n    public function testDeferSpecificObjectEvents()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n\n        $d->listen(DeferTestEvent::class, function () {\n            $_SERVER['__event.test'][] = 'DeferTestEvent';\n        });\n\n        $d->listen(ImmediateTestEvent::class, function () {\n            $_SERVER['__event.test'][] = 'ImmediateTestEvent';\n        });\n\n        $d->defer(function () use ($d) {\n            $d->dispatch(new DeferTestEvent());\n            $d->dispatch(new ImmediateTestEvent());\n\n            $this->assertSame(['ImmediateTestEvent'], $_SERVER['__event.test']);\n        }, [DeferTestEvent::class]);\n\n        $this->assertSame(['ImmediateTestEvent', 'DeferTestEvent'], $_SERVER['__event.test']);\n    }\n\n    public function testHaltingEventExecution()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function ($foo) {\n            $this->assertTrue(true);\n\n            return 'here';\n        });\n        $d->listen('foo', function ($foo) {\n            throw new Exception('should not be called');\n        });\n\n        $response = $d->dispatch('foo', ['bar'], true);\n        $this->assertSame('here', $response);\n\n        $response = $d->until('foo', ['bar']);\n        $this->assertSame('here', $response);\n    }\n\n    public function testResponseWhenNoListenersAreSet()\n    {\n        $d = new Dispatcher;\n        $response = $d->dispatch('foo');\n\n        $this->assertEquals([], $response);\n\n        $response = $d->dispatch('foo', [], true);\n        $this->assertNull($response);\n    }\n\n    public function testReturningFalseStopsPropagation()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function ($foo) {\n            return $foo;\n        });\n\n        $d->listen('foo', function ($foo) {\n            $_SERVER['__event.test'] = $foo;\n\n            return false;\n        });\n\n        $d->listen('foo', function ($foo) {\n            throw new Exception('should not be called');\n        });\n\n        $response = $d->dispatch('foo', ['bar']);\n\n        $this->assertSame('bar', $_SERVER['__event.test']);\n        $this->assertEquals(['bar'], $response);\n    }\n\n    public function testReturningFalsyValuesContinuesPropagation()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function () {\n            return 0;\n        });\n        $d->listen('foo', function () {\n            return [];\n        });\n        $d->listen('foo', function () {\n            return '';\n        });\n        $d->listen('foo', function () {\n        });\n\n        $response = $d->dispatch('foo', ['bar']);\n\n        $this->assertEquals([0, [], '', null], $response);\n    }\n\n    public function testContainerResolutionOfEventHandlers()\n    {\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $container->shouldReceive('make')->once()->with(TestEventListener::class)->andReturn(new TestEventListener);\n        $d->listen('foo', TestEventListener::class.'@onFooEvent');\n        $response = $d->dispatch('foo', ['foo', 'bar']);\n\n        $this->assertEquals(['baz'], $response);\n    }\n\n    public function testContainerResolutionOfEventHandlersWithDefaultMethods()\n    {\n        $d = new Dispatcher(new Container);\n        $d->listen('foo', TestEventListener::class);\n        $response = $d->dispatch('foo', ['foo', 'bar']);\n        $this->assertEquals(['baz'], $response);\n    }\n\n    public function testQueuedEventsAreFired()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('update', function ($name) {\n            $_SERVER['__event.test'] = $name;\n        });\n        $d->push('update', ['name' => 'taylor']);\n        $d->listen('update', function ($name) {\n            $_SERVER['__event.test'] .= '_'.$name;\n        });\n\n        $this->assertFalse(isset($_SERVER['__event.test']));\n        $d->flush('update');\n        $d->listen('update', function ($name) {\n            $_SERVER['__event.test'] .= $name;\n        });\n        $this->assertSame('taylor_taylor', $_SERVER['__event.test']);\n    }\n\n    public function testQueuedEventsCanBeForgotten()\n    {\n        $_SERVER['__event.test'] = 'unset';\n        $d = new Dispatcher;\n        $d->push('update', ['name' => 'taylor']);\n        $d->listen('update', function ($name) {\n            $_SERVER['__event.test'] = $name;\n        });\n\n        $d->forgetPushed();\n        $d->flush('update');\n        $this->assertSame('unset', $_SERVER['__event.test']);\n    }\n\n    public function testMultiplePushedEventsWillGetFlushed()\n    {\n        $_SERVER['__event.test'] = '';\n        $d = new Dispatcher;\n        $d->push('update', ['name' => 'taylor ']);\n        $d->push('update', ['name' => 'otwell']);\n        $d->listen('update', function ($name) {\n            $_SERVER['__event.test'] .= $name;\n        });\n\n        $d->flush('update');\n        $this->assertSame('taylor otwell', $_SERVER['__event.test']);\n    }\n\n    public function testPushMethodCanAcceptObjectAsPayload()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->push(ExampleEvent::class, $e = new ExampleEvent);\n        $d->listen(ExampleEvent::class, function ($payload) {\n            $_SERVER['__event.test'] = $payload;\n        });\n\n        $d->flush(ExampleEvent::class);\n\n        $this->assertSame($e, $_SERVER['__event.test']);\n    }\n\n    public function testWildcardListeners()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo.bar', function () {\n            $_SERVER['__event.test'] = 'regular';\n        });\n        $d->listen('foo.*', function () {\n            $_SERVER['__event.test'] = 'wildcard';\n        });\n        $d->listen('bar.*', function () {\n            $_SERVER['__event.test'] = 'nope';\n        });\n\n        $response = $d->dispatch('foo.bar');\n\n        $this->assertEquals([null, null], $response);\n        $this->assertSame('wildcard', $_SERVER['__event.test']);\n    }\n\n    public function testWildcardListenersWithResponses()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo.bar', function () {\n            return 'regular';\n        });\n        $d->listen('foo.*', function () {\n            return 'wildcard';\n        });\n        $d->listen('bar.*', function () {\n            return 'nope';\n        });\n\n        $response = $d->dispatch('foo.bar');\n\n        $this->assertEquals(['regular', 'wildcard'], $response);\n    }\n\n    public function testWildcardListenersCacheFlushing()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo.*', function () {\n            $_SERVER['__event.test'] = 'cached_wildcard';\n        });\n        $d->dispatch('foo.bar');\n        $this->assertSame('cached_wildcard', $_SERVER['__event.test']);\n\n        $d->listen('foo.*', function () {\n            $_SERVER['__event.test'] = 'new_wildcard';\n        });\n        $d->dispatch('foo.bar');\n        $this->assertSame('new_wildcard', $_SERVER['__event.test']);\n    }\n\n    public function testListenersCanBeRemoved()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo', function () {\n            $_SERVER['__event.test'] = 'foo';\n        });\n        $d->forget('foo');\n        $d->dispatch('foo');\n\n        $this->assertFalse(isset($_SERVER['__event.test']));\n    }\n\n    public function testWildcardListenersCanBeRemoved()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen('foo.*', function () {\n            $_SERVER['__event.test'] = 'foo';\n        });\n        $d->forget('foo.*');\n        $d->dispatch('foo.bar');\n\n        $this->assertFalse(isset($_SERVER['__event.test']));\n    }\n\n    public function testWildcardCacheIsClearedWhenListenersAreRemoved()\n    {\n        unset($_SERVER['__event.test']);\n\n        $d = new Dispatcher;\n        $d->listen('foo*', function () {\n            $_SERVER['__event.test'] = 'foo';\n        });\n        $d->dispatch('foo');\n\n        $this->assertSame('foo', $_SERVER['__event.test']);\n\n        unset($_SERVER['__event.test']);\n\n        $d->forget('foo*');\n        $d->dispatch('foo');\n\n        $this->assertFalse(isset($_SERVER['__event.test']));\n    }\n\n    public function testHasWildcardListeners()\n    {\n        $d = new Dispatcher;\n        $d->listen('foo', 'listener1');\n        $this->assertFalse($d->hasWildcardListeners('foo'));\n\n        $d->listen('foo*', 'listener1');\n        $this->assertTrue($d->hasWildcardListeners('foo'));\n    }\n\n    public function testListenersCanBeFound()\n    {\n        $d = new Dispatcher;\n        $this->assertFalse($d->hasListeners('foo'));\n\n        $d->listen('foo', function () {\n            //\n        });\n        $this->assertTrue($d->hasListeners('foo'));\n    }\n\n    public function testWildcardListenersCanBeFound()\n    {\n        $d = new Dispatcher;\n        $this->assertFalse($d->hasListeners('foo.*'));\n\n        $d->listen('foo.*', function () {\n            //\n        });\n        $this->assertTrue($d->hasListeners('foo.*'));\n        $this->assertTrue($d->hasListeners('foo.bar'));\n    }\n\n    public function testEventPassedFirstToWildcards()\n    {\n        $d = new Dispatcher;\n        $d->listen('foo.*', function ($event, $data) {\n            $this->assertSame('foo.bar', $event);\n            $this->assertEquals(['first', 'second'], $data);\n        });\n        $d->dispatch('foo.bar', ['first', 'second']);\n\n        $d = new Dispatcher;\n        $d->listen('foo.bar', function ($first, $second) {\n            $this->assertSame('first', $first);\n            $this->assertSame('second', $second);\n        });\n        $d->dispatch('foo.bar', ['first', 'second']);\n    }\n\n    public function testClassesWork()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen(ExampleEvent::class, function () {\n            $_SERVER['__event.test'] = 'baz';\n        });\n        $d->dispatch(new ExampleEvent);\n\n        $this->assertSame('baz', $_SERVER['__event.test']);\n    }\n\n    public function testClassesWorkWithAnonymousListeners()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen(function (ExampleEvent $event) {\n            $_SERVER['__event.test'] = 'qux';\n        });\n        $d->dispatch(new ExampleEvent);\n\n        $this->assertSame('qux', $_SERVER['__event.test']);\n    }\n\n    public function testEventClassesArePayload()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen(ExampleEvent::class, function ($payload) {\n            $_SERVER['__event.test'] = $payload;\n        });\n        $d->dispatch($e = new ExampleEvent, ['foo']);\n\n        $this->assertSame($e, $_SERVER['__event.test']);\n    }\n\n    public function testInterfacesWork()\n    {\n        unset($_SERVER['__event.test']);\n        $d = new Dispatcher;\n        $d->listen(SomeEventInterface::class, function () {\n            $_SERVER['__event.test'] = 'bar';\n        });\n        $d->dispatch(new AnotherEvent);\n\n        $this->assertSame('bar', $_SERVER['__event.test']);\n    }\n\n    public function testBothClassesAndInterfacesWork()\n    {\n        unset($_SERVER['__event.test']);\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen(AnotherEvent::class, function ($p) {\n            $_SERVER['__event.test'][] = $p;\n            $_SERVER['__event.test1'] = 'fooo';\n        });\n        $d->listen(SomeEventInterface::class, function ($p) {\n            $_SERVER['__event.test'][] = $p;\n            $_SERVER['__event.test2'] = 'baar';\n        });\n        $d->dispatch($e = new AnotherEvent, ['foo']);\n\n        $this->assertSame($e, $_SERVER['__event.test'][0]);\n        $this->assertSame($e, $_SERVER['__event.test'][1]);\n        $this->assertSame('fooo', $_SERVER['__event.test1']);\n        $this->assertSame('baar', $_SERVER['__event.test2']);\n\n        unset($_SERVER['__event.test1'], $_SERVER['__event.test2']);\n    }\n\n    public function testNestedEvent()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n\n        $d->listen('event', function () use ($d) {\n            $d->listen('event', function () {\n                $_SERVER['__event.test'][] = 'fired 1';\n            });\n            $d->listen('event', function () {\n                $_SERVER['__event.test'][] = 'fired 2';\n            });\n        });\n\n        $d->dispatch('event');\n        $this->assertSame([], $_SERVER['__event.test']);\n        $d->dispatch('event');\n        $this->assertEquals(['fired 1', 'fired 2'], $_SERVER['__event.test']);\n    }\n\n    public function testDuplicateListenersWillFire()\n    {\n        $d = new Dispatcher;\n        $d->listen('event', TestListener::class);\n        $d->listen('event', TestListener::class);\n        $d->listen('event', TestListener::class.'@handle');\n        $d->listen('event', TestListener::class.'@handle');\n        $d->dispatch('event');\n\n        $this->assertEquals(4, TestListener::$counter);\n        TestListener::$counter = 0;\n    }\n\n    public function testGetListeners()\n    {\n        $d = new Dispatcher;\n        $d->listen(ExampleEvent::class, 'Listener1');\n        $d->listen(ExampleEvent::class, 'Listener2');\n        $listeners = $d->getListeners(ExampleEvent::class);\n        $this->assertCount(2, $listeners);\n\n        $d->listen(ExampleEvent::class, 'Listener3');\n        $listeners = $d->getListeners(ExampleEvent::class);\n        $this->assertCount(3, $listeners);\n    }\n\n    public function testListenersObjectsCreationOrder()\n    {\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen(TestEvent::class, TestListener1::class);\n        $d->listen(TestEvent::class, TestListener2::class);\n        $d->listen(TestEvent::class, TestListener3::class);\n\n        // Attaching events does not make any objects.\n        $this->assertEquals([], $_SERVER['__event.test']);\n\n        $d->dispatch(TestEvent::class);\n\n        // Dispatching event does not make an object of the event class.\n        $this->assertEquals([\n            'cons-1',\n            'handle-1',\n            'cons-2',\n            'handle-2',\n            'cons-3',\n            'handle-3',\n        ], $_SERVER['__event.test']);\n\n        $d->dispatch(TestEvent::class);\n\n        // Event Objects are re-resolved on each dispatch. (No memoization)\n        $this->assertEquals([\n            'cons-1',\n            'handle-1',\n            'cons-2',\n            'handle-2',\n            'cons-3',\n            'handle-3',\n            'cons-1',\n            'handle-1',\n            'cons-2',\n            'handle-2',\n            'cons-3',\n            'handle-3',\n        ], $_SERVER['__event.test']);\n\n        unset($_SERVER['__event.test']);\n    }\n\n    public function test_Listener_object_creation_is_lazy()\n    {\n        $d = new Dispatcher;\n        $d->listen(TestEvent::class, TestListener1::class);\n        $d->listen(TestEvent::class, TestListener2Falser::class);\n        $d->listen(TestEvent::class, TestListener3::class);\n        $d->listen(ExampleEvent::class, TestListener2::class);\n\n        $_SERVER['__event.test'] = [];\n        $d->dispatch(ExampleEvent::class);\n\n        // It only resolves relevant listeners not all.\n        $this->assertEquals(['cons-2', 'handle-2'], $_SERVER['__event.test']);\n\n        $_SERVER['__event.test'] = [];\n        $d->dispatch(TestEvent::class);\n\n        $this->assertEquals([\n            'cons-1',\n            'handle-1',\n            'cons-2-falser',\n            'handle-2-falser',\n        ], $_SERVER['__event.test']);\n\n        unset($_SERVER['__event.test']);\n\n        $d = new Dispatcher;\n        $d->listen(TestEvent::class, TestListener1::class);\n        $d->listen(TestEvent::class, TestListener2Falser::class);\n        $d->listen(TestEvent::class, TestListener3::class);\n\n        $_SERVER['__event.test'] = [];\n        $d->dispatch(TestEvent::class, halt: true);\n\n        $this->assertEquals([\n            'cons-1',\n            'handle-1',\n        ], $_SERVER['__event.test']);\n\n        unset($_SERVER['__event.test']);\n    }\n\n    public function testInvokeIsCalled()\n    {\n        // Only \"handle\" is called when both \"handle\" and \"__invoke\" exist on listener.\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen('myEvent', TestListenerInvokeyHandler::class);\n        $d->dispatch('myEvent');\n        $this->assertEquals(['__construct', 'handle'], $_SERVER['__event.test']);\n\n        // \"__invoke\" is called when there is no handle.\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen('myEvent', TestListenerInvokey::class);\n        $d->listen('myEvent', TestListenerInvokeyHandler::class);\n        $d->dispatch('myEvent', 'somePayload');\n        $this->assertEquals(['__construct', '__invoke_somePayload'], $_SERVER['__event.test']);\n\n        // It falls back to __invoke if the referenced method is not found.\n        $_SERVER['__event.test'] = [];\n        $d = new Dispatcher;\n        $d->listen('myEvent', [TestListenerInvokey::class, 'someAbsentMethod']);\n        $d->dispatch('myEvent', 'somePayload');\n        $this->assertEquals(['__construct', '__invoke_somePayload'], $_SERVER['__event.test']);\n\n        // It throws an \"Error\" when there is no method to be called.\n        $d = new Dispatcher;\n        $d->listen('myEvent', TestListenerLean::class);\n\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Call to undefined method '.TestListenerLean::class.'::__invoke()');\n\n        $d->dispatch('myEvent', 'somePayload');\n\n        unset($_SERVER['__event.test']);\n    }\n\n    public function testEventDispatchesUsingNamedArguments()\n    {\n        $container = new Container;\n        $events = m::mock(Dispatcher::class);\n        $container->instance('events', $events);\n\n        $originalContainer = Container::getInstance();\n        Container::setInstance($container);\n\n        try {\n            $events->shouldReceive('dispatch')\n                ->once()\n                ->with(m::on(function ($event) {\n                    $this->assertInstanceOf(DispatchableNamedArgumentsEvent::class, $event);\n                    $this->assertSame('first-value', $event->first);\n                    $this->assertSame('second-value', $event->second);\n\n                    return true;\n                }))\n                ->andReturn(['dispatched']);\n\n            $this->assertSame(\n                ['dispatched'],\n                DispatchableNamedArgumentsEvent::dispatch(second: 'second-value', first: 'first-value')\n            );\n        } finally {\n            Container::setInstance($originalContainer);\n        }\n    }\n}\n\nclass TestListenerLean\n{\n    //\n}\n\nclass TestListenerInvokeyHandler\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = '__construct';\n    }\n\n    public function __invoke()\n    {\n        $_SERVER['__event.test'][] = '__invoke';\n    }\n\n    public function handle()\n    {\n        $_SERVER['__event.test'][] = 'handle';\n    }\n}\n\nclass TestListenerInvokey\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = '__construct';\n    }\n\n    public function __invoke($payload)\n    {\n        $_SERVER['__event.test'][] = '__invoke_'.$payload;\n\n        return false;\n    }\n}\n\nclass ExampleEvent\n{\n    //\n}\n\ninterface SomeEventInterface\n{\n    //\n}\n\nclass AnotherEvent implements SomeEventInterface\n{\n    //\n}\n\nclass TestEventListener\n{\n    public function handle($foo, $bar)\n    {\n        return 'baz';\n    }\n\n    public function onFooEvent($foo, $bar)\n    {\n        return 'baz';\n    }\n}\n\nclass TestListener\n{\n    public static $counter = 0;\n\n    public function handle()\n    {\n        self::$counter++;\n    }\n}\n\nclass TestEvent\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = 'cons-event-1';\n    }\n}\n\nclass TestListener1\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = 'cons-1';\n    }\n\n    public function handle()\n    {\n        $_SERVER['__event.test'][] = 'handle-1';\n\n        return 'resp-1';\n    }\n}\n\nclass TestListener2\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = 'cons-2';\n    }\n\n    public function handle()\n    {\n        $_SERVER['__event.test'][] = 'handle-2';\n\n        return 'resp-2';\n    }\n}\n\nclass TestListener2Falser\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = 'cons-2-falser';\n    }\n\n    public function handle()\n    {\n        $_SERVER['__event.test'][] = 'handle-2-falser';\n\n        return false;\n    }\n}\n\nclass TestListener3\n{\n    public function __construct()\n    {\n        $_SERVER['__event.test'][] = 'cons-3';\n    }\n\n    public function handle()\n    {\n        $_SERVER['__event.test'][] = 'handle-3';\n    }\n}\n\nclass DeferTestEvent\n{\n}\n\nclass ImmediateTestEvent\n{\n}\n\nclass DispatchableNamedArgumentsEvent\n{\n    use \\Illuminate\\Foundation\\Events\\Dispatchable;\n\n    public function __construct(\n        public string $first,\n        public string $second,\n    ) {\n    }\n}\n"
  },
  {
    "path": "tests/Events/EventsSubscriberTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Events;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Events\\Dispatcher;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass EventsSubscriberTest extends TestCase\n{\n    public function testEventSubscribers()\n    {\n        $this->expectNotToPerformAssertions();\n\n        $d = new Dispatcher($container = m::mock(Container::class));\n        $subs = m::mock(ExampleSubscriber::class);\n        $subs->shouldReceive('subscribe')->once()->with($d);\n        $container->shouldReceive('make')->once()->with(ExampleSubscriber::class)->andReturn($subs);\n\n        $d->subscribe(ExampleSubscriber::class);\n    }\n\n    public function testEventSubscribeCanAcceptObject()\n    {\n        $this->expectNotToPerformAssertions();\n\n        $d = new Dispatcher;\n        $subs = m::mock(ExampleSubscriber::class);\n        $subs->shouldReceive('subscribe')->once()->with($d);\n\n        $d->subscribe($subs);\n    }\n\n    public function testEventSubscribeCanReturnMappings()\n    {\n        $d = new Dispatcher;\n        $d->subscribe(DeclarativeSubscriber::class);\n\n        $d->dispatch('myEvent1');\n        $this->assertSame('L1_L2_', DeclarativeSubscriber::$string);\n\n        $d->dispatch('myEvent2');\n        $this->assertSame('L1_L2_L3', DeclarativeSubscriber::$string);\n    }\n}\n\nclass ExampleSubscriber\n{\n    public function subscribe($e)\n    {\n        // There would be no error if a non-array is returned.\n        return '(O_o)';\n    }\n}\n\nclass DeclarativeSubscriber\n{\n    public static $string = '';\n\n    public function subscribe()\n    {\n        return [\n            'myEvent1' => [\n                self::class.'@listener1',\n                self::class.'@listener2',\n            ],\n            'myEvent2' => [\n                self::class.'@listener3',\n            ],\n        ];\n    }\n\n    public function listener1()\n    {\n        self::$string .= 'L1_';\n    }\n\n    public function listener2()\n    {\n        self::$string .= 'L2_';\n    }\n\n    public function listener3()\n    {\n        self::$string .= 'L3';\n    }\n}\n"
  },
  {
    "path": "tests/Events/QueuedEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Events;\n\nuse Illuminate\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Lock;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Contracts\\Queue\\Queue;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Events\\CallQueuedListener;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\QueueManager;\nuse Illuminate\\Queue\\QueueRoutes;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Testing\\Fakes\\QueueFake;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueuedEventsTest extends TestCase\n{\n    public function testQueuedEventHandlersAreQueued()\n    {\n        $d = new Dispatcher;\n        $queue = m::mock(Queue::class);\n\n        $queue->shouldReceive('connection')->once()->with(null)->andReturnSelf();\n\n        $queue->shouldReceive('pushOn')->once()->with(null, m::type(CallQueuedListener::class));\n\n        $d->setQueueResolver(function () use ($queue) {\n            return $queue;\n        });\n\n        $d->listen('some.event', TestDispatcherQueuedHandler::class.'@someMethod');\n        $d->dispatch('some.event', ['foo', 'bar']);\n    }\n\n    public function testCustomizedQueuedEventHandlersAreQueued()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherConnectionQueuedHandler::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushedOn('my_queue', CallQueuedListener::class);\n    }\n\n    public function testQueueIsSetByGetQueue()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherGetQueue::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushedOn('some_other_queue', CallQueuedListener::class);\n    }\n\n    public function testQueueIsSetByGetConnection()\n    {\n        $d = new Dispatcher;\n        $queue = m::mock(Queue::class);\n\n        $queue->shouldReceive('connection')->once()->with('some_other_connection')->andReturnSelf();\n\n        $queue->shouldReceive('pushOn')->once()->with(null, m::type(CallQueuedListener::class));\n\n        $d->setQueueResolver(function () use ($queue) {\n            return $queue;\n        });\n\n        $d->listen('some.event', TestDispatcherGetConnection::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n    }\n\n    public function testDelayIsSetByWithDelay()\n    {\n        $d = new Dispatcher;\n        $queue = m::mock(Queue::class);\n\n        $queue->shouldReceive('connection')->once()->with(null)->andReturnSelf();\n\n        $queue->shouldReceive('laterOn')->once()->with(null, 20, m::type(CallQueuedListener::class));\n\n        $d->setQueueResolver(function () use ($queue) {\n            return $queue;\n        });\n\n        $d->listen('some.event', TestDispatcherGetDelay::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n    }\n\n    public function testQueueIsSetByGetQueueDynamically()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherGetQueueDynamically::class.'@handle');\n        $d->dispatch('some.event', [['useHighPriorityQueue' => true], 'bar']);\n\n        $fakeQueue->assertPushedOn('p0', CallQueuedListener::class);\n    }\n\n    public function testQueueIsSetByGetConnectionDynamically()\n    {\n        $d = new Dispatcher;\n        $queueManager = $this->createMock(QueueManager::class);\n        $queue = $this->createMock(Queue::class);\n\n        $queueManager->expects($this->once())\n            ->method('connection')\n            ->with('redis')\n            ->willReturn($queue);\n\n        $queue->expects($this->once())\n            ->method('pushOn')\n            ->with(null, $this->isInstanceOf(CallQueuedListener::class));\n\n        $d->setQueueResolver(function () use ($queueManager) {\n            return $queueManager;\n        });\n\n        $d->listen('some.event', TestDispatcherGetConnectionDynamically::class.'@handle');\n        $d->dispatch('some.event', [\n            ['shouldUseRedisConnection' => true],\n            'bar',\n        ]);\n    }\n\n    public function testQueueIsSetUsingQueueRoutes()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $queueRoutes = new QueueRoutes;\n        $queueRoutes->set(TestDispatcherQueueRoutes::class, 'event-queue', 'event-connection');\n        $container->instance('queue.routes', $queueRoutes);\n\n        $fakeQueue = new QueueFake($container);\n\n        Container::setInstance($container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherQueueRoutes::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->connection('event-connection')->assertPushedOn('event-queue', CallQueuedListener::class);\n\n        Container::setInstance(null);\n    }\n\n    public function testDelayIsSetByWithDelayDynamically()\n    {\n        $d = new Dispatcher;\n        $queue = m::mock(Queue::class);\n\n        $queue->shouldReceive('connection')->once()->with(null)->andReturnSelf();\n\n        $queue->shouldReceive('laterOn')->once()->with(null, 60, m::type(CallQueuedListener::class));\n\n        $d->setQueueResolver(function () use ($queue) {\n            return $queue;\n        });\n\n        $d->listen('some.event', TestDispatcherGetDelayDynamically::class.'@handle');\n        $d->dispatch('some.event', [['useHighDelay' => true], 'bar']);\n    }\n\n    public function testQueuePropagateRetryUntilAndMaxExceptions()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherOptions::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->maxExceptions === 1 && $job->retryUntil !== null;\n        });\n    }\n\n    public function testQueuePropagateTries()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherOptions::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->tries === 5;\n        });\n    }\n\n    public function testQueuePropagateMessageGroupProperty()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherWithMessageGroupProperty::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->messageGroup === 'group-property';\n        });\n    }\n\n    public function testQueuePropagateMessageGroupMethodOverProperty()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherWithMessageGroupMethod::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->messageGroup === 'group-method';\n        });\n    }\n\n    public function testQueuePropagateDeduplicationIdMethod()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherWithDeduplicationIdMethod::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n\n            return is_callable($job->deduplicator) && call_user_func($job->deduplicator, '', null) === 'deduplication-id-method';\n        });\n    }\n\n    public function testQueuePropagateDeduplicatorMethodOverDeduplicationIdMethod()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherWithDeduplicatorMethod::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n\n            return is_callable($job->deduplicator) && call_user_func($job->deduplicator, '', null) === 'deduplicator-method';\n        });\n    }\n\n    public function testQueuePropagateMiddleware()\n    {\n        $d = new Dispatcher;\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherMiddleware::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return count($job->middleware) === 1\n                && $job->middleware[0] instanceof TestMiddleware\n                && $job->middleware[0]->a === 'foo'\n                && $job->middleware[0]->b === 'bar';\n        });\n    }\n\n    public function testDispatchesOnQueueDefinedWithEnum()\n    {\n        $d = new Dispatcher;\n        $queue = m::mock(Queue::class);\n\n        $fakeQueue = new QueueFake(new Container);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherViaQueueSupportsEnum::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushedOn('enumerated-queue', CallQueuedListener::class);\n    }\n\n    public function testQueuePropagatesShouldBeUnique()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n\n        $cache->shouldReceive('lock')->once()->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(true);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherShouldBeUnique::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->shouldBeUnique === true\n                && $job->shouldBeUniqueUntilProcessing === false\n                && $job->uniqueId === 'unique-listener-id'\n                && $job->uniqueFor === 60;\n        });\n    }\n\n    public function testUniqueListenerNotQueuedWhenLockNotAcquired()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n\n        $cache->shouldReceive('lock')->once()->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(false);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherShouldBeUnique::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertNothingPushed();\n    }\n\n    public function testQueuePropagatesShouldBeUniqueUntilProcessing()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n\n        $cache->shouldReceive('lock')->once()->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(true);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherShouldBeUniqueUntilProcessing::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->shouldBeUnique === true\n                && $job->shouldBeUniqueUntilProcessing === true;\n        });\n    }\n\n    public function testQueuePropagatesUniqueIdFromMethod()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n\n        $cache->shouldReceive('lock')->once()->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(true);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherUniqueIdFromMethod::class.'@handle');\n        $d->dispatch('some.event', [['id' => 'event-123'], 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->uniqueId === 'unique-id-event-123';\n        });\n    }\n\n    public function testUniqueLockKeyUsesListenerClassName()\n    {\n        $listener = new CallQueuedListener(TestDispatcherShouldBeUnique::class, 'handle', []);\n        $listener->shouldBeUnique = true;\n        $listener->uniqueId = 'test-id';\n\n        $this->assertSame(TestDispatcherShouldBeUnique::class, $listener->displayName());\n        $this->assertSame(\n            'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUnique::class).':test-id',\n            \\Illuminate\\Bus\\UniqueLock::getKey($listener)\n        );\n    }\n\n    public function testUniqueLockIsAcquiredWithListenerClassName()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n\n        $expectedKey = 'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUnique::class).':unique-listener-id';\n\n        $cache->shouldReceive('lock')\n            ->once()\n            ->with($expectedKey, 60)\n            ->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(true);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherShouldBeUnique::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class);\n    }\n\n    public function testUniqueViaUsesListenerCacheRepository()\n    {\n        $container = new Container;\n        $d = new Dispatcher($container);\n\n        $fakeQueue = new QueueFake($container);\n        $defaultCache = m::mock(Cache::class);\n        $uniqueCache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $defaultCache);\n\n        $defaultCache->shouldNotReceive('lock');\n\n        TestDispatcherShouldBeUniqueWithCustomCache::$cache = $uniqueCache;\n\n        $expectedKey = 'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUniqueWithCustomCache::class).':unique-listener-id';\n\n        $uniqueCache->shouldReceive('lock')\n            ->once()\n            ->with($expectedKey, 60)\n            ->andReturn($lock);\n        $lock->shouldReceive('get')->once()->andReturn(true);\n\n        $d->setQueueResolver(function () use ($fakeQueue) {\n            return $fakeQueue;\n        });\n\n        $d->listen('some.event', TestDispatcherShouldBeUniqueWithCustomCache::class.'@handle');\n        $d->dispatch('some.event', ['foo', 'bar']);\n\n        $fakeQueue->assertPushed(CallQueuedListener::class);\n    }\n\n    public function testUniqueLockIsReleasedOnProcessingWithListenerClassName()\n    {\n        $container = new Container;\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n        $container->instance(BusDispatcher::class, new BusDispatcher($container));\n\n        $listener = new CallQueuedListener(TestDispatcherShouldBeUnique::class, 'handle', ['foo', 'bar']);\n        $listener->shouldBeUnique = true;\n        $listener->uniqueId = 'unique-listener-id';\n        $listener->uniqueFor = 60;\n\n        $expectedKey = 'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUnique::class).':unique-listener-id';\n\n        $cache->shouldReceive('lock')\n            ->once()\n            ->with($expectedKey)\n            ->andReturn($lock);\n        $lock->shouldReceive('forceRelease')->once();\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $handler = new CallQueuedHandler(new BusDispatcher($container), $container);\n        $handler->call($job, ['command' => serialize($listener)]);\n    }\n\n    public function testUniqueUntilProcessingLockIsReleasedBeforeHandling()\n    {\n        $container = new Container;\n        $cache = m::mock(Cache::class);\n        $lock = m::mock(Lock::class);\n\n        $container->instance(Cache::class, $cache);\n        $container->instance(BusDispatcher::class, new BusDispatcher($container));\n\n        TestDispatcherShouldBeUniqueUntilProcessing::$lockReleasedBeforeHandling = null;\n        TestDispatcherShouldBeUniqueUntilProcessing::$cache = $cache;\n        TestDispatcherShouldBeUniqueUntilProcessing::$expectedLockKey = 'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUniqueUntilProcessing::class).':until-processing-id';\n\n        $listener = new CallQueuedListener(TestDispatcherShouldBeUniqueUntilProcessing::class, 'handle', ['foo', 'bar']);\n        $listener->shouldBeUnique = true;\n        $listener->shouldBeUniqueUntilProcessing = true;\n        $listener->uniqueId = 'until-processing-id';\n\n        $expectedKey = 'laravel_unique_job:'.hash('xxh128', TestDispatcherShouldBeUniqueUntilProcessing::class).':until-processing-id';\n\n        $cache->shouldReceive('lock')\n            ->with($expectedKey)\n            ->andReturn($lock);\n        $lock->shouldReceive('forceRelease')->once();\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $handler = new CallQueuedHandler(new BusDispatcher($container), $container);\n        $handler->call($job, ['command' => serialize($listener)]);\n\n        $this->assertTrue(TestDispatcherShouldBeUniqueUntilProcessing::$lockReleasedBeforeHandling);\n    }\n}\n\nclass TestDispatcherQueuedHandler implements ShouldQueue\n{\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherConnectionQueuedHandler implements ShouldQueue\n{\n    public $connection = 'redis';\n\n    public $delay = 10;\n\n    public $queue = 'my_queue';\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherGetQueue implements ShouldQueue\n{\n    public $queue = 'my_queue';\n\n    public function handle()\n    {\n        //\n    }\n\n    public function viaQueue()\n    {\n        return 'some_other_queue';\n    }\n}\n\nclass TestDispatcherGetConnection implements ShouldQueue\n{\n    public $connection = 'my_connection';\n\n    public function handle()\n    {\n        //\n    }\n\n    public function viaConnection()\n    {\n        return 'some_other_connection';\n    }\n}\n\nclass TestDispatcherGetDelay implements ShouldQueue\n{\n    public $delay = 10;\n\n    public function handle()\n    {\n        //\n    }\n\n    public function withDelay()\n    {\n        return 20;\n    }\n}\n\nclass TestDispatcherOptions implements ShouldQueue\n{\n    public $maxExceptions = 1;\n\n    public function retryUntil()\n    {\n        return Carbon::now()->addHour(1);\n    }\n\n    public function tries()\n    {\n        return 5;\n    }\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherWithMessageGroupProperty implements ShouldQueue\n{\n    public $messageGroup = 'group-property';\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherWithMessageGroupMethod implements ShouldQueue\n{\n    public $messageGroup = 'group-property';\n\n    public function handle()\n    {\n        //\n    }\n\n    public function messageGroup($event)\n    {\n        return 'group-method';\n    }\n}\n\nclass TestDispatcherWithDeduplicationIdMethod implements ShouldQueue\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function deduplicationId($payload, $queue)\n    {\n        return 'deduplication-id-method';\n    }\n}\n\nclass TestDispatcherWithDeduplicatorMethod implements ShouldQueue\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function deduplicationId($payload, $queue)\n    {\n        return 'deduplication-id-method';\n    }\n\n    public function deduplicator($event)\n    {\n        return fn ($payload, $queue) => 'deduplicator-method';\n    }\n}\n\nclass TestDispatcherMiddleware implements ShouldQueue\n{\n    public function middleware($a, $b)\n    {\n        return [new TestMiddleware($a, $b)];\n    }\n\n    public function handle($a, $b)\n    {\n        //\n    }\n}\n\nclass TestMiddleware\n{\n    public $a;\n    public $b;\n\n    public function __construct($a, $b)\n    {\n        $this->a = $a;\n        $this->b = $b;\n    }\n\n    public function handle($job, $next)\n    {\n        $next($job);\n    }\n}\n\nclass TestDispatcherGetConnectionDynamically implements ShouldQueue\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function viaConnection($event)\n    {\n        if ($event['shouldUseRedisConnection']) {\n            return 'redis';\n        }\n\n        return 'sqs';\n    }\n}\n\nclass TestDispatcherGetQueueDynamically implements ShouldQueue\n{\n    public $queue = 'my_queue';\n\n    public function handle()\n    {\n        //\n    }\n\n    public function viaQueue($event)\n    {\n        if ($event['useHighPriorityQueue']) {\n            return 'p0';\n        }\n\n        return 'p99';\n    }\n}\n\nclass TestDispatcherGetDelayDynamically implements ShouldQueue\n{\n    public $delay = 10;\n\n    public function handle()\n    {\n        //\n    }\n\n    public function withDelay($event)\n    {\n        if ($event['useHighDelay']) {\n            return 60;\n        }\n\n        return 20;\n    }\n}\n\nenum TestQueueType: string\n{\n    case EnumeratedQueue = 'enumerated-queue';\n}\n\nclass TestDispatcherViaQueueSupportsEnum implements ShouldQueue\n{\n    public function viaQueue()\n    {\n        return TestQueueType::EnumeratedQueue;\n    }\n}\n\nclass TestDispatcherQueueRoutes implements ShouldQueue\n{\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherShouldBeUnique implements ShouldQueue, ShouldBeUnique\n{\n    public $uniqueId = 'unique-listener-id';\n\n    public $uniqueFor = 60;\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass TestDispatcherShouldBeUniqueUntilProcessing implements ShouldQueue, ShouldBeUniqueUntilProcessing\n{\n    use InteractsWithQueue;\n\n    public static $lockReleasedBeforeHandling = null;\n    public static $cache = null;\n    public static $expectedLockKey = '';\n\n    public function handle()\n    {\n        $lock = m::mock(Lock::class);\n        $lock->shouldReceive('get')->andReturn(true);\n        static::$cache->shouldReceive('lock')\n            ->with(static::$expectedLockKey, 10)\n            ->andReturn($lock);\n\n        static::$lockReleasedBeforeHandling = static::$cache->lock(static::$expectedLockKey, 10)->get();\n    }\n}\n\nclass TestDispatcherUniqueIdFromMethod implements ShouldQueue, ShouldBeUnique\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function uniqueId($event)\n    {\n        return 'unique-id-'.$event['id'];\n    }\n}\n\nclass TestDispatcherShouldBeUniqueWithCustomCache implements ShouldQueue, ShouldBeUnique\n{\n    public static $cache = null;\n\n    public function handle()\n    {\n        //\n    }\n\n    public function uniqueId()\n    {\n        return 'unique-listener-id';\n    }\n\n    public function uniqueFor()\n    {\n        return 60;\n    }\n\n    public function uniqueVia(): Cache\n    {\n        return static::$cache;\n    }\n}\n"
  },
  {
    "path": "tests/Filesystem/FilesystemAdapterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Filesystem;\n\nuse GuzzleHttp\\Psr7\\Stream;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Filesystem\\FilesystemAdapter;\nuse Illuminate\\Filesystem\\FilesystemManager;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Testing\\Assert;\nuse InvalidArgumentException;\nuse League\\Flysystem\\Filesystem;\nuse League\\Flysystem\\Ftp\\FtpAdapter;\nuse League\\Flysystem\\Local\\LocalFilesystemAdapter;\nuse League\\Flysystem\\UnableToReadFile;\nuse League\\Flysystem\\UnableToRetrieveMetadata;\nuse League\\Flysystem\\UnableToWriteFile;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass FilesystemAdapterTest extends TestCase\n{\n    private $tempDir;\n    private $filesystem;\n    private $adapter;\n\n    protected function setUp(): void\n    {\n        $this->tempDir = __DIR__.'/tmp';\n        $this->filesystem = new Filesystem(\n            $this->adapter = new LocalFilesystemAdapter($this->tempDir)\n        );\n    }\n\n    protected function tearDown(): void\n    {\n        $filesystem = new Filesystem(\n            $this->adapter = new LocalFilesystemAdapter(dirname($this->tempDir))\n        );\n        $filesystem->deleteDirectory(basename($this->tempDir));\n\n        unset($this->tempDir, $this->filesystem, $this->adapter);\n\n        parent::tearDown();\n    }\n\n    public function testResponse()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $files = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $response = $files->response('file.txt');\n\n        ob_start();\n        $response->sendContent();\n        $content = ob_get_clean();\n\n        $this->assertInstanceOf(StreamedResponse::class, $response);\n        $this->assertSame('Hello World', $content);\n        $this->assertSame('inline; filename=file.txt', $response->headers->get('content-disposition'));\n    }\n\n    public function testMimeTypeIsNotCalledAlreadyProvidedToResponse()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n\n        $files = m::mock(FilesystemAdapter::class, [$this->filesystem, $this->adapter])->makePartial();\n        $files->shouldReceive('mimeType')->never();\n\n        $files->response('file.txt', null, [\n            'Content-Type' => 'text/x-custom',\n        ]);\n    }\n\n    public function testSizeIsNotCalledAlreadyProvidedToResponse()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n\n        $files = m::mock(FilesystemAdapter::class, [$this->filesystem, $this->adapter])->makePartial();\n        $files->shouldReceive('size')->never();\n\n        $files->response('file.txt', null, [\n            'Content-Length' => 11,\n        ]);\n    }\n\n    public function testFallbackNameCalledAlreadyProvidedToResponse()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n\n        $files = m::mock(FilesystemAdapter::class, [$this->filesystem, $this->adapter])\n            ->shouldAllowMockingProtectedMethods()\n            ->makePartial();\n        $files->shouldReceive('fallbackName')->never();\n\n        $files->response('file.txt', null, [\n            'Content-Disposition' => 'attachment',\n        ]);\n    }\n\n    public function testDownload()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $files = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $response = $files->download('file.txt', 'hello.txt');\n        $this->assertInstanceOf(StreamedResponse::class, $response);\n        $this->assertSame('attachment; filename=hello.txt', $response->headers->get('content-disposition'));\n    }\n\n    public function testDownloadNonAsciiFilename()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $files = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $response = $files->download('file.txt', 'привет.txt');\n        $this->assertInstanceOf(StreamedResponse::class, $response);\n        $this->assertSame(\"attachment; filename=privet.txt; filename*=utf-8''%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82.txt\", $response->headers->get('content-disposition'));\n    }\n\n    public function testDownloadNonAsciiEmptyFilename()\n    {\n        $this->filesystem->write('привет.txt', 'Hello World');\n        $files = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $response = $files->download('привет.txt');\n        $this->assertInstanceOf(StreamedResponse::class, $response);\n        $this->assertSame('attachment; filename=privet.txt; filename*=utf-8\\'\\'%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82.txt', $response->headers->get('content-disposition'));\n    }\n\n    public function testDownloadPercentInFilename()\n    {\n        $this->filesystem->write('Hello%World.txt', 'Hello World');\n        $files = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $response = $files->download('Hello%World.txt', 'Hello%World.txt');\n        $this->assertInstanceOf(StreamedResponse::class, $response);\n        $this->assertSame('attachment; filename=HelloWorld.txt; filename*=utf-8\\'\\'Hello%25World.txt', $response->headers->get('content-disposition'));\n    }\n\n    public function testExists()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->exists('file.txt'));\n        $this->assertTrue($filesystemAdapter->fileExists('file.txt'));\n    }\n\n    public function testMissing()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->missing('file.txt'));\n        $this->assertTrue($filesystemAdapter->fileMissing('file.txt'));\n    }\n\n    public function testDirectoryExists()\n    {\n        $this->filesystem->write('/foo/bar/file.txt', 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->directoryExists('/foo/bar'));\n    }\n\n    public function testDirectoryMissing()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->directoryMissing('/foo/bar'));\n    }\n\n    public function testPath()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter, [\n            'root' => $this->tempDir.DIRECTORY_SEPARATOR,\n        ]);\n        $this->assertEquals($this->tempDir.DIRECTORY_SEPARATOR.'file.txt', $filesystemAdapter->path('file.txt'));\n    }\n\n    public function testGet()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertSame('Hello World', $filesystemAdapter->get('file.txt'));\n    }\n\n    public function testGetFileNotFound()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertNull($filesystemAdapter->get('file.txt'));\n    }\n\n    public function testJsonReturnsDecodedJsonData()\n    {\n        $this->filesystem->write('file.json', '{\"foo\": \"bar\"}');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertSame(['foo' => 'bar'], $filesystemAdapter->json('file.json'));\n    }\n\n    public function testJsonReturnsNullIfJsonDataIsInvalid()\n    {\n        $this->filesystem->write('file.json', '{\"foo\":');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertNull($filesystemAdapter->json('file.json'));\n    }\n\n    public function testMimeTypeNotDetected()\n    {\n        $this->filesystem->write('unknown.mime-type', '');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertFalse($filesystemAdapter->mimeType('unknown.mime-type'));\n    }\n\n    public function testPut()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->put('file.txt', 'Something inside');\n        $this->assertStringEqualsFile($this->tempDir.'/file.txt', 'Something inside');\n    }\n\n    public function testPrepend()\n    {\n        file_put_contents($this->tempDir.'/file.txt', 'World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->prepend('file.txt', 'Hello ');\n        $this->assertStringEqualsFile($this->tempDir.'/file.txt', 'Hello '.PHP_EOL.'World');\n    }\n\n    public function testAppend()\n    {\n        file_put_contents($this->tempDir.'/file.txt', 'Hello ');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->append('file.txt', 'Moon');\n        $this->assertStringEqualsFile($this->tempDir.'/file.txt', 'Hello '.PHP_EOL.'Moon');\n    }\n\n    public function testDelete()\n    {\n        file_put_contents($this->tempDir.'/file.txt', 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->delete('file.txt'));\n        Assert::assertFileDoesNotExist($this->tempDir.'/file.txt');\n    }\n\n    public function testDeleteReturnsTrueWhenFileNotFound()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertTrue($filesystemAdapter->delete('file.txt'));\n    }\n\n    public function testCopy()\n    {\n        $data = '33232';\n        mkdir($this->tempDir.'/foo');\n        file_put_contents($this->tempDir.'/foo/foo.txt', $data);\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->copy('/foo/foo.txt', '/foo/foo2.txt');\n\n        $this->assertFileExists($this->tempDir.'/foo/foo.txt');\n        $this->assertEquals($data, file_get_contents($this->tempDir.'/foo/foo.txt'));\n\n        $this->assertFileExists($this->tempDir.'/foo/foo2.txt');\n        $this->assertEquals($data, file_get_contents($this->tempDir.'/foo/foo2.txt'));\n    }\n\n    public function testMove()\n    {\n        $data = '33232';\n        mkdir($this->tempDir.'/foo');\n        file_put_contents($this->tempDir.'/foo/foo.txt', $data);\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->move('/foo/foo.txt', '/foo/foo2.txt');\n\n        Assert::assertFileDoesNotExist($this->tempDir.'/foo/foo.txt');\n\n        $this->assertFileExists($this->tempDir.'/foo/foo2.txt');\n        $this->assertEquals($data, file_get_contents($this->tempDir.'/foo/foo2.txt'));\n    }\n\n    public function testStream()\n    {\n        $this->filesystem->write('file.txt', $original_content = 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $readStream = $filesystemAdapter->readStream('file.txt');\n        $filesystemAdapter->writeStream('copy.txt', $readStream);\n        $this->assertEquals($original_content, $filesystemAdapter->get('copy.txt'));\n    }\n\n    public function testStreamBetweenFilesystems()\n    {\n        $secondFilesystem = new Filesystem(new LocalFilesystemAdapter($this->tempDir.'/second'));\n        $this->filesystem->write('file.txt', $original_content = 'Hello World');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $secondFilesystemAdapter = new FilesystemAdapter($secondFilesystem, $this->adapter);\n        $readStream = $filesystemAdapter->readStream('file.txt');\n        $secondFilesystemAdapter->writeStream('copy.txt', $readStream);\n        $this->assertEquals($original_content, $secondFilesystemAdapter->get('copy.txt'));\n    }\n\n    public function testStreamToExistingFileOverwrites()\n    {\n        $this->filesystem->write('file.txt', 'Hello World');\n        $this->filesystem->write('existing.txt', 'Dear Kate');\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $readStream = $filesystemAdapter->readStream('file.txt');\n        $filesystemAdapter->writeStream('existing.txt', $readStream);\n        $this->assertSame('Hello World', $filesystemAdapter->read('existing.txt'));\n    }\n\n    public function testReadStreamNonExistentFileReturnsNull()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $this->assertNull($filesystemAdapter->readStream('nonexistent.txt'));\n    }\n\n    public function testStreamInvalidResourceThrows()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->writeStream('file.txt', 'foo bar');\n    }\n\n    public function testPutWithStreamInterface()\n    {\n        file_put_contents($this->tempDir.'/foo.txt', 'some-data');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $stream = fopen($this->tempDir.'/foo.txt', 'r');\n        $guzzleStream = new Stream($stream);\n        $filesystemAdapter->put('bar.txt', $guzzleStream);\n        fclose($stream);\n\n        $this->assertSame('some-data', $filesystemAdapter->get('bar.txt'));\n    }\n\n    public function testPutFileAs()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'uploaded file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $uploadedFile = new UploadedFile($filePath, 'org.txt', null, null, true);\n\n        $storagePath = $filesystemAdapter->putFileAs('/', $uploadedFile, 'new.txt');\n\n        $this->assertSame('new.txt', $storagePath);\n\n        $this->assertFileExists($filePath);\n\n        $filesystemAdapter->assertExists($storagePath);\n\n        $this->assertSame('uploaded file content', $filesystemAdapter->read($storagePath));\n\n        $filesystemAdapter->assertExists(\n            $storagePath,\n            'uploaded file content'\n        );\n    }\n\n    public function testPutFileAsWithAbsoluteFilePath()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'normal file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $storagePath = $filesystemAdapter->putFileAs('/', $filePath, 'new.txt');\n\n        $this->assertSame('normal file content', $filesystemAdapter->read($storagePath));\n    }\n\n    public function testPutFileAsWithoutPath()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'normal file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $storagePath = $filesystemAdapter->putFileAs($filePath, 'new.txt');\n\n        $this->assertSame('normal file content', $filesystemAdapter->read($storagePath));\n    }\n\n    public function testPutFile()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'uploaded file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $uploadedFile = new UploadedFile($filePath, 'org.txt', null, null, true);\n\n        $storagePath = $filesystemAdapter->putFile('/', $uploadedFile);\n\n        $this->assertSame(44, strlen($storagePath)); // random 40 characters + \".txt\"\n\n        $this->assertFileExists($filePath);\n\n        $filesystemAdapter->assertExists($storagePath);\n\n        $filesystemAdapter->assertExists(\n            $storagePath,\n            'uploaded file content'\n        );\n    }\n\n    public function testPutFileWithAbsoluteFilePath()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'uploaded file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $storagePath = $filesystemAdapter->putFile('/', $filePath);\n\n        $this->assertSame(44, strlen($storagePath)); // random 40 characters + \".txt\"\n\n        $filesystemAdapter->assertExists($storagePath);\n\n        $filesystemAdapter->assertExists(\n            $storagePath,\n            'uploaded file content'\n        );\n    }\n\n    public function testPutFileWithoutPath()\n    {\n        file_put_contents($filePath = $this->tempDir.'/foo.txt', 'normal file content');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $storagePath = $filesystemAdapter->putFile($filePath);\n\n        $this->assertSame('normal file content', $filesystemAdapter->read($storagePath));\n    }\n\n    #[RequiresPhpExtension('ftp')]\n    public function testCreateFtpDriver()\n    {\n        $filesystem = new FilesystemManager(new Application);\n\n        $driver = $filesystem->createFtpDriver([\n            'host' => 'ftp.example.com',\n            'username' => 'admin',\n            'permPublic' => 0700,\n            'unsupportedParam' => true,\n        ]);\n\n        $this->assertInstanceOf(FtpAdapter::class, $driver->getAdapter());\n\n        $config = $driver->getConfig();\n        $this->assertEquals(0700, $config['permPublic']);\n        $this->assertSame('ftp.example.com', $config['host']);\n        $this->assertSame('admin', $config['username']);\n    }\n\n    public function testMacroable()\n    {\n        $this->filesystem->write('foo.txt', 'Hello World');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->macro('getFoo', function () {\n            return $this->get('foo.txt');\n        });\n\n        $this->assertSame('Hello World', $filesystemAdapter->getFoo());\n    }\n\n    public function testTemporaryUrlWithCustomCallback()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $filesystemAdapter->buildTemporaryUrlsUsing(function ($path, Carbon $expiration, $options) {\n            return $path.$expiration->toString().implode('', $options);\n        });\n\n        $path = 'foo';\n        $expiration = Carbon::create(2021, 18, 12, 13);\n        $options = ['bar' => 'baz'];\n\n        $this->assertSame(\n            $path.$expiration->toString().implode('', $options),\n            $filesystemAdapter->temporaryUrl($path, $expiration, $options)\n        );\n    }\n\n    public function testThrowExceptionsForGet()\n    {\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['throw' => true]);\n\n        try {\n            $adapter->get('/foo.txt');\n        } catch (UnableToReadFile) {\n            $this->assertTrue(true);\n\n            return;\n        }\n\n        $this->fail('Exception was not thrown.');\n    }\n\n    public function testThrowExceptionsForReadStream()\n    {\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['throw' => true]);\n\n        try {\n            $adapter->readStream('/foo.txt');\n        } catch (UnableToReadFile) {\n            $this->assertTrue(true);\n\n            return;\n        }\n\n        $this->fail('Exception was not thrown.');\n    }\n\n    public function testThrowExceptionsForPut()\n    {\n        $this->filesystem->write('foo.txt', 'Hello World');\n\n        chmod(__DIR__.'/tmp/foo.txt', 0400);\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['throw' => true]);\n\n        try {\n            $adapter->put('/foo.txt', 'Hello World!');\n        } catch (UnableToWriteFile) {\n            $this->assertTrue(true);\n\n            return;\n        } finally {\n            chmod(__DIR__.'/tmp/foo.txt', 0600);\n        }\n\n        $this->fail('Exception was not thrown.');\n    }\n\n    public function testThrowExceptionsForMimeType()\n    {\n        $this->filesystem->write('unknown.mime-type', '');\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['throw' => true]);\n\n        try {\n            $adapter->mimeType('unknown.mime-type');\n        } catch (UnableToRetrieveMetadata) {\n            $this->assertTrue(true);\n\n            return;\n        }\n\n        $this->fail('Exception was not thrown.');\n    }\n\n    public function testReportExceptionsForGet()\n    {\n        $container = Container::getInstance();\n\n        $exceptionHandler = m::mock(ExceptionHandler::class);\n\n        $exceptionHandler->shouldReceive('report')\n            ->once()\n            ->andReturnUsing(function (UnableToReadFile $e) {\n                self::assertStringContainsString(\n                    'Unable to read file from location: foo.txt.',\n                    $e->getMessage(),\n                );\n            });\n\n        $container->bind(ExceptionHandler::class, function () use ($exceptionHandler) {\n            return $exceptionHandler;\n        });\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['report' => true]);\n\n        try {\n            $adapter->get('/foo.txt');\n        } catch (UnableToReadFile) {\n            $this->fail('Exception was thrown.');\n        }\n    }\n\n    public function testReportExceptionsForReadStream()\n    {\n        $container = Container::getInstance();\n\n        $exceptionHandler = m::mock(ExceptionHandler::class);\n\n        $exceptionHandler->shouldReceive('report')\n            ->once()\n            ->andReturnUsing(function (UnableToReadFile $e) {\n                self::assertStringContainsString(\n                    'Unable to read file from location: foo.txt.',\n                    $e->getMessage(),\n                );\n            });\n\n        $container->bind(ExceptionHandler::class, function () use ($exceptionHandler) {\n            return $exceptionHandler;\n        });\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['report' => true], $exceptionHandler);\n\n        try {\n            $adapter->readStream('/foo.txt');\n        } catch (UnableToReadFile) {\n            $this->fail('Exception was thrown.');\n        }\n    }\n\n    public function testReportExceptionsForPut()\n    {\n        $container = Container::getInstance();\n\n        $exceptionHandler = m::mock(ExceptionHandler::class);\n\n        $exceptionHandler->shouldReceive('report')\n            ->once()\n            ->andReturnUsing(function (UnableToWriteFile $e) {\n                self::assertStringContainsString(\n                    'Unable to write file at location: foo.txt.',\n                    $e->getMessage(),\n                );\n            });\n\n        $container->bind(ExceptionHandler::class, function () use ($exceptionHandler) {\n            return $exceptionHandler;\n        });\n\n        $this->filesystem->write('foo.txt', 'Hello World');\n\n        chmod(__DIR__.'/tmp/foo.txt', 0400);\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['report' => true], $exceptionHandler);\n\n        try {\n            $adapter->put('/foo.txt', 'Hello World!');\n        } catch (UnableToWriteFile) {\n            $this->fail('Exception was thrown.');\n        } finally {\n            chmod(__DIR__.'/tmp/foo.txt', 0600);\n        }\n    }\n\n    public function testReportExceptionsForMimeType()\n    {\n        $container = Container::getInstance();\n\n        $exceptionHandler = m::mock(ExceptionHandler::class);\n\n        $exceptionHandler->shouldReceive('report')\n            ->once()\n            ->andReturnUsing(function (UnableToRetrieveMetadata $e) {\n                self::assertStringContainsString(\n                    'Unable to retrieve the mime_type for file at location: unknown.mime-type.',\n                    $e->getMessage(),\n                );\n            });\n\n        $container->bind(ExceptionHandler::class, function () use ($exceptionHandler) {\n            return $exceptionHandler;\n        });\n\n        $this->filesystem->write('unknown.mime-type', '');\n\n        $adapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['report' => true], $exceptionHandler);\n\n        try {\n            $adapter->mimeType('unknown.mime-type');\n        } catch (UnableToRetrieveMetadata) {\n            $this->fail('Exception was thrown.');\n        }\n    }\n\n    public function testGetAllFiles()\n    {\n        $this->filesystem->write('body.txt', 'Hello World');\n        $this->filesystem->write('file1.txt', 'Hello World');\n        $this->filesystem->write('file.txt', 'Hello World');\n        $this->filesystem->write('existing.txt', 'Dear Kate');\n\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $this->assertSame($filesystemAdapter->files(), ['body.txt', 'existing.txt', 'file.txt', 'file1.txt']);\n    }\n\n    public function testProvidesTemporaryUrls()\n    {\n        $localAdapter = new class($this->tempDir) extends LocalFilesystemAdapter\n        {\n            public function getTemporaryUrl($path, Carbon $expiration, $options): string\n            {\n                return $path.$expiration->toString().implode('', $options);\n            }\n        };\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $localAdapter);\n\n        $this->assertTrue($filesystemAdapter->providesTemporaryUrls());\n    }\n\n    public function testProvidesTemporaryUrlsWithCustomCallback()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $filesystemAdapter->buildTemporaryUrlsUsing(function ($path, Carbon $expiration, $options) {\n            return $path.$expiration->toString().implode('', $options);\n        });\n\n        $this->assertTrue($filesystemAdapter->providesTemporaryUrls());\n    }\n\n    public function testProvidesTemporaryUrlsForS3Adapter()\n    {\n        $filesystem = new FilesystemManager(new Application);\n        $filesystemAdapter = $filesystem->createS3Driver([\n            'region' => 'us-west-1',\n            'bucket' => 'laravel',\n        ]);\n\n        $this->assertTrue($filesystemAdapter->providesTemporaryUrls());\n    }\n\n    public function testUsesRightSeperatorForS3Adapter()\n    {\n        $filesystem = new FilesystemManager(new Application);\n        $filesystemAdapter = $filesystem->createS3Driver([\n            'region' => 'us-west-1',\n            'bucket' => 'laravel',\n            'root' => 'something',\n            'directory_separator' => '\\\\',\n        ]);\n\n        $path = $filesystemAdapter->path('different');\n        $this->assertStringContainsString('/', $path);\n        $this->assertStringNotContainsString('\\\\', $path);\n    }\n\n    public function testProvidesTemporaryUrlsForAdapterWithoutTemporaryUrlSupport()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $this->assertFalse($filesystemAdapter->providesTemporaryUrls());\n    }\n\n    public function testPrefixesUrls()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter, ['url' => 'https://example.org/', 'prefix' => 'images']);\n\n        $this->assertEquals('https://example.org/images/picture.jpeg', $filesystemAdapter->url('picture.jpeg'));\n    }\n\n    public function testGetChecksum()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n        $filesystemAdapter->write('path.txt', 'contents of file');\n\n        $this->assertEquals('730bed78bccf58c2cfe44c29b71e5e6b', $filesystemAdapter->checksum('path.txt'));\n        $this->assertEquals('a5c3556d', $filesystemAdapter->checksum('path.txt', ['checksum_algo' => 'crc32']));\n    }\n\n    public function testUsesRightSeperatorForS3AdapterWithoutDoublePrefixing()\n    {\n        $filesystem = new FilesystemManager(new Application);\n        $filesystemAdapter = $filesystem->createS3Driver([\n            'region' => 'us-west-1',\n            'bucket' => 'laravel',\n            'root' => 'my-root',\n            'prefix' => 'someprefix',\n            'directory_separator' => '\\\\',\n        ]);\n\n        $path = $filesystemAdapter->path('different');\n        $this->assertEquals('my-root/someprefix/different', $path);\n    }\n\n    public function testTemporaryUploadUrlWithCustomCallback()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $filesystemAdapter->buildTemporaryUploadUrlsUsing(function ($path, Carbon $expiration, $options) {\n            return [\n                'url' => $path.$expiration->toString().implode('', $options),\n                'headers' => ['X-Custom' => 'header'],\n            ];\n        });\n\n        $path = 'foo';\n        $expiration = Carbon::create(2021, 18, 12, 13);\n        $options = ['bar' => 'baz'];\n\n        $result = $filesystemAdapter->temporaryUploadUrl($path, $expiration, $options);\n\n        $this->assertSame($path.$expiration->toString().implode('', $options), $result['url']);\n        $this->assertSame(['X-Custom' => 'header'], $result['headers']);\n    }\n\n    public function testProvidesTemporaryUploadUrls()\n    {\n        $localAdapter = new class($this->tempDir) extends LocalFilesystemAdapter\n        {\n            public function temporaryUploadUrl($path, $expiration, $options): array\n            {\n                return [\n                    'url' => $path,\n                    'headers' => [],\n                ];\n            }\n        };\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $localAdapter);\n\n        $this->assertTrue($filesystemAdapter->providesTemporaryUploadUrls());\n    }\n\n    public function testProvidesTemporaryUploadUrlsWithCustomCallback()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $filesystemAdapter->buildTemporaryUploadUrlsUsing(function ($path, Carbon $expiration, $options) {\n            return [\n                'url' => $path.$expiration->toString().implode('', $options),\n                'headers' => [],\n            ];\n        });\n\n        $this->assertTrue($filesystemAdapter->providesTemporaryUploadUrls());\n    }\n\n    public function testProvidesTemporaryUploadUrlsForAdapterWithoutTemporaryUploadUrlSupport()\n    {\n        $filesystemAdapter = new FilesystemAdapter($this->filesystem, $this->adapter);\n\n        $this->assertFalse($filesystemAdapter->providesTemporaryUploadUrls());\n    }\n}\n"
  },
  {
    "path": "tests/Filesystem/FilesystemManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Filesystem;\n\nuse Illuminate\\Contracts\\Filesystem\\Filesystem;\nuse Illuminate\\Filesystem\\FilesystemManager;\nuse Illuminate\\Foundation\\Application;\nuse InvalidArgumentException;\nuse League\\Flysystem\\PathPrefixing\\PathPrefixedAdapter;\nuse League\\Flysystem\\UnableToReadFile;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FilesystemManagerTest extends TestCase\n{\n    public function testExceptionThrownOnUnsupportedDriver()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Disk [local] does not have a configured driver.');\n\n        $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n            $app['config'] = ['filesystems.disks.local' => null];\n        }));\n\n        $filesystem->disk('local');\n    }\n\n    public function testCanBuildOnDemandDisk()\n    {\n        $filesystem = new FilesystemManager(new Application);\n\n        $this->assertInstanceOf(Filesystem::class, $filesystem->build('my-custom-path'));\n\n        $this->assertInstanceOf(Filesystem::class, $filesystem->build([\n            'driver' => 'local',\n            'root' => 'my-custom-path',\n            'url' => 'my-custom-url',\n            'visibility' => 'public',\n        ]));\n\n        rmdir(__DIR__.'/../../my-custom-path');\n    }\n\n    public function testCanBuildReadOnlyDisks()\n    {\n        $filesystem = new FilesystemManager(new Application);\n\n        $disk = $filesystem->build([\n            'driver' => 'local',\n            'read-only' => true,\n            'root' => 'my-custom-path',\n            'url' => 'my-custom-url',\n            'visibility' => 'public',\n        ]);\n\n        file_put_contents(__DIR__.'/../../my-custom-path/path.txt', 'contents');\n\n        // read operations work\n        $this->assertEquals('contents', $disk->get('path.txt'));\n        $this->assertEquals(['path.txt'], $disk->files());\n\n        // write operations fail\n        $this->assertFalse($disk->put('path.txt', 'contents'));\n        $this->assertFalse($disk->delete('path.txt'));\n        $this->assertFalse($disk->deleteDirectory('directory'));\n        $this->assertFalse($disk->prepend('path.txt', 'data'));\n        $this->assertFalse($disk->append('path.txt', 'data'));\n        $handle = fopen('php://memory', 'rw');\n        fwrite($handle, 'content');\n        $this->assertFalse($disk->writeStream('path.txt', $handle));\n        fclose($handle);\n\n        unlink(__DIR__.'/../../my-custom-path/path.txt');\n        rmdir(__DIR__.'/../../my-custom-path');\n    }\n\n    public function testCanBuildScopedDisks()\n    {\n        try {\n            $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n                $app['config'] = [\n                    'filesystems.disks.local' => [\n                        'driver' => 'local',\n                        'root' => 'to-be-scoped',\n                    ],\n                ];\n            }));\n\n            $local = $filesystem->disk('local');\n            $scoped = $filesystem->build([\n                'driver' => 'scoped',\n                'disk' => 'local',\n                'prefix' => 'path-prefix',\n            ]);\n\n            $scoped->put('dirname/filename.txt', 'file content');\n            $this->assertEquals('file content', $local->get('path-prefix/dirname/filename.txt'));\n            $local->deleteDirectory('path-prefix');\n        } finally {\n            rmdir(__DIR__.'/../../to-be-scoped');\n        }\n    }\n\n    public function testCanBuildScopedDiskFromScopedDisk()\n    {\n        try {\n            $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n                $app['config'] = [\n                    'filesystems.disks.local' => [\n                        'driver' => 'local',\n                        'root' => 'root-to-be-scoped',\n                    ],\n                    'filesystems.disks.scoped-from-root' => [\n                        'driver' => 'scoped',\n                        'disk' => 'local',\n                        'prefix' => 'scoped-from-root-prefix',\n                    ],\n                ];\n            }));\n\n            $root = $filesystem->disk('local');\n            $nestedScoped = $filesystem->build([\n                'driver' => 'scoped',\n                'disk' => 'scoped-from-root',\n                'prefix' => 'nested-scoped-prefix',\n            ]);\n\n            $nestedScoped->put('dirname/filename.txt', 'file content');\n            $this->assertEquals('file content', $root->get('scoped-from-root-prefix/nested-scoped-prefix/dirname/filename.txt'));\n            $root->deleteDirectory('scoped-from-root-prefix');\n        } finally {\n            rmdir(__DIR__.'/../../root-to-be-scoped');\n        }\n    }\n\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    public function testCanBuildScopedDisksWithVisibility()\n    {\n        try {\n            $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n                $app['config'] = [\n                    'filesystems.disks.local' => [\n                        'driver' => 'local',\n                        'root' => 'to-be-scoped',\n                        'visibility' => 'public',\n                    ],\n                ];\n            }));\n\n            $scoped = $filesystem->build([\n                'driver' => 'scoped',\n                'disk' => 'local',\n                'prefix' => 'path-prefix',\n                'visibility' => 'private',\n            ]);\n\n            $scoped->put('dirname/filename.txt', 'file content');\n\n            $this->assertEquals('private', $scoped->getVisibility('dirname/filename.txt'));\n        } finally {\n            unlink(__DIR__.'/../../to-be-scoped/path-prefix/dirname/filename.txt');\n            rmdir(__DIR__.'/../../to-be-scoped/path-prefix/dirname');\n            rmdir(__DIR__.'/../../to-be-scoped/path-prefix');\n            rmdir(__DIR__.'/../../to-be-scoped');\n        }\n    }\n\n    public function testCanBuildScopedDisksWithThrow()\n    {\n        try {\n            $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n                $app['config'] = [\n                    'filesystems.disks.local' => [\n                        'driver' => 'local',\n                        'root' => 'to-be-scoped',\n                        'throw' => false,\n                    ],\n                ];\n            }));\n\n            $scoped = $filesystem->build([\n                'driver' => 'scoped',\n                'disk' => 'local',\n                'prefix' => 'path-prefix',\n                'throw' => true,\n            ]);\n\n            $this->expectException(UnableToReadFile::class);\n            $scoped->get('dirname/filename.txt');\n        } finally {\n            rmdir(__DIR__.'/../../to-be-scoped');\n        }\n    }\n\n    public function testCanBuildInlineScopedDisks()\n    {\n        try {\n            $filesystem = new FilesystemManager(new Application);\n\n            $scoped = $filesystem->build([\n                'driver' => 'scoped',\n                'disk' => [\n                    'driver' => 'local',\n                    'root' => 'to-be-scoped',\n                ],\n                'prefix' => 'path-prefix',\n            ]);\n\n            $scoped->put('dirname/filename.txt', 'file content');\n            $this->assertTrue(is_dir(__DIR__.'/../../to-be-scoped/path-prefix'));\n            $this->assertEquals(file_get_contents(__DIR__.'/../../to-be-scoped/path-prefix/dirname/filename.txt'), 'file content');\n        } finally {\n            unlink(__DIR__.'/../../to-be-scoped/path-prefix/dirname/filename.txt');\n            rmdir(__DIR__.'/../../to-be-scoped/path-prefix/dirname');\n            rmdir(__DIR__.'/../../to-be-scoped/path-prefix');\n            rmdir(__DIR__.'/../../to-be-scoped');\n        }\n    }\n\n    public function testCustomDriverClosureBoundObjectIsFilesystemManager()\n    {\n        $manager = new FilesystemManager(tap(new Application, function ($app) {\n            $app['config'] = [\n                'filesystems.disks.'.__CLASS__ => [\n                    'driver' => __CLASS__,\n                ],\n            ];\n        }));\n        $manager->extend(__CLASS__, fn () => $this);\n        $this->assertSame($manager, $manager->disk(__CLASS__));\n    }\n\n    // public function testKeepTrackOfAdapterDecoration()\n    // {\n    //     try {\n    //         $filesystem = new FilesystemManager(tap(new Application, function ($app) {\n    //             $app['config'] = [\n    //                 'filesystems.disks.local' => [\n    //                     'driver' => 'local',\n    //                     'root' => 'to-be-scoped',\n    //                 ],\n    //             ];\n    //         }));\n\n    //         $scoped = $filesystem->build([\n    //             'driver' => 'scoped',\n    //             'disk' => 'local',\n    //             'prefix' => 'path-prefix',\n    //         ]);\n\n    //         $this->assertInstanceOf(PathPrefixedAdapter::class, $scoped->getAdapter());\n    //     } finally {\n    //         rmdir(__DIR__.'/../../to-be-scoped');\n    //     }\n    // }\n}\n"
  },
  {
    "path": "tests/Filesystem/FilesystemTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Filesystem;\n\nuse Illuminate\\Contracts\\Filesystem\\FileNotFoundException;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Testing\\Assert;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\AfterClass;\nuse PHPUnit\\Framework\\Attributes\\BeforeClass;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\nuse SplFileInfo;\n\nuse function Orchestra\\Testbench\\terminate;\n\nclass FilesystemTest extends TestCase\n{\n    private static $tempDir;\n\n    #[BeforeClass]\n    public static function setUpTempDir()\n    {\n        self::$tempDir = sys_get_temp_dir().'/tmp';\n        mkdir(self::$tempDir);\n    }\n\n    #[AfterClass]\n    public static function tearDownTempDir()\n    {\n        $files = new Filesystem;\n        $files->deleteDirectory(self::$tempDir);\n        self::$tempDir = null;\n    }\n\n    protected function tearDown(): void\n    {\n        $files = new Filesystem;\n        $files->deleteDirectory(self::$tempDir, $preserve = true);\n\n        parent::tearDown();\n    }\n\n    public function testGetRetrievesFiles()\n    {\n        file_put_contents(self::$tempDir.'/file.txt', 'Hello World');\n        $files = new Filesystem;\n        $this->assertSame('Hello World', $files->get(self::$tempDir.'/file.txt'));\n    }\n\n    public function testPutStoresFiles()\n    {\n        $files = new Filesystem;\n        $files->put(self::$tempDir.'/file.txt', 'Hello World');\n        $this->assertStringEqualsFile(self::$tempDir.'/file.txt', 'Hello World');\n    }\n\n    public function testLines()\n    {\n        $path = self::$tempDir.'/file.txt';\n\n        $contents = ' '.PHP_EOL.' spaces around '.PHP_EOL.PHP_EOL.'Line 2'.PHP_EOL.'1 trailing empty line ->'.PHP_EOL.PHP_EOL;\n        file_put_contents($path, $contents);\n\n        $files = new Filesystem;\n        $this->assertInstanceOf(LazyCollection::class, $files->lines($path));\n\n        $this->assertSame(\n            [' ', ' spaces around ', '', 'Line 2', '1 trailing empty line ->', '', ''],\n            $files->lines($path)->all()\n        );\n\n        // an empty file:\n        ftruncate(fopen($path, 'w'), 0);\n        $this->assertSame([''], $files->lines($path)->all());\n    }\n\n    public function testLinesThrowsExceptionNonexisitingFile()\n    {\n        $this->expectException(FileNotFoundException::class);\n        $this->expectExceptionMessage('File does not exist at path '.__DIR__.'/unknown-file.txt.');\n\n        (new Filesystem)->lines(__DIR__.'/unknown-file.txt');\n    }\n\n    public function testReplaceCreatesFile()\n    {\n        $tempFile = self::$tempDir.'/file.txt';\n\n        $filesystem = new Filesystem;\n\n        $filesystem->replace($tempFile, 'Hello World');\n        $this->assertStringEqualsFile($tempFile, 'Hello World');\n    }\n\n    public function testReplaceInFileCorrectlyReplaces()\n    {\n        $tempFile = self::$tempDir.'/file.txt';\n\n        $filesystem = new Filesystem;\n\n        $filesystem->put($tempFile, 'Hello World');\n        $filesystem->replaceInFile('Hello World', 'Hello Taylor', $tempFile);\n        $this->assertStringEqualsFile($tempFile, 'Hello Taylor');\n    }\n\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    public function testReplaceWhenUnixSymlinkExists()\n    {\n        $tempFile = self::$tempDir.'/file.txt';\n        $symlinkDir = self::$tempDir.'/symlink_dir';\n        $symlink = \"{$symlinkDir}/symlink.txt\";\n\n        mkdir($symlinkDir);\n        symlink($tempFile, $symlink);\n\n        // Prevent changes to symlink_dir\n        chmod($symlinkDir, 0555);\n\n        // Test with a weird non-standard umask.\n        $umask = 0131;\n        $originalUmask = umask($umask);\n\n        $filesystem = new Filesystem;\n\n        // Test replacing non-existent file.\n        $filesystem->replace($tempFile, 'Hello World');\n        $this->assertStringEqualsFile($tempFile, 'Hello World');\n        $this->assertEquals($umask, 0777 - $this->getFilePermissions($tempFile));\n\n        // Test replacing existing file.\n        $filesystem->replace($tempFile, 'Something Else');\n        $this->assertStringEqualsFile($tempFile, 'Something Else');\n        $this->assertEquals($umask, 0777 - $this->getFilePermissions($tempFile));\n\n        // Test replacing symlinked file.\n        $filesystem->replace($symlink, 'Yet Something Else Again');\n        $this->assertStringEqualsFile($tempFile, 'Yet Something Else Again');\n        $this->assertEquals($umask, 0777 - $this->getFilePermissions($tempFile));\n\n        umask($originalUmask);\n\n        // Reset changes to symlink_dir\n        chmod($symlinkDir, 0777 - $originalUmask);\n    }\n\n    public function testSetChmod()\n    {\n        file_put_contents(self::$tempDir.'/file.txt', 'Hello World');\n        $files = new Filesystem;\n        $files->chmod(self::$tempDir.'/file.txt', 0755);\n        $filePermission = substr(sprintf('%o', fileperms(self::$tempDir.'/file.txt')), -4);\n        $expectedPermissions = DIRECTORY_SEPARATOR === '\\\\' ? '0666' : '0755';\n        $this->assertEquals($expectedPermissions, $filePermission);\n    }\n\n    public function testGetChmod()\n    {\n        file_put_contents(self::$tempDir.'/file.txt', 'Hello World');\n        chmod(self::$tempDir.'/file.txt', 0755);\n\n        $files = new Filesystem;\n        $filePermission = $files->chmod(self::$tempDir.'/file.txt');\n        $expectedPermissions = DIRECTORY_SEPARATOR === '\\\\' ? '0666' : '0755';\n        $this->assertEquals($expectedPermissions, $filePermission);\n    }\n\n    public function testDeleteRemovesFiles()\n    {\n        file_put_contents(self::$tempDir.'/file1.txt', 'Hello World');\n        file_put_contents(self::$tempDir.'/file2.txt', 'Hello World');\n        file_put_contents(self::$tempDir.'/file3.txt', 'Hello World');\n\n        $files = new Filesystem;\n        $files->delete(self::$tempDir.'/file1.txt');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/file1.txt');\n\n        $files->delete([self::$tempDir.'/file2.txt', self::$tempDir.'/file3.txt']);\n        Assert::assertFileDoesNotExist(self::$tempDir.'/file2.txt');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/file3.txt');\n    }\n\n    public function testPrependExistingFiles()\n    {\n        $files = new Filesystem;\n        $files->put(self::$tempDir.'/file.txt', 'World');\n        $files->prepend(self::$tempDir.'/file.txt', 'Hello ');\n        $this->assertStringEqualsFile(self::$tempDir.'/file.txt', 'Hello World');\n    }\n\n    public function testPrependNewFiles()\n    {\n        $files = new Filesystem;\n        $files->prepend(self::$tempDir.'/file.txt', 'Hello World');\n        $this->assertStringEqualsFile(self::$tempDir.'/file.txt', 'Hello World');\n    }\n\n    public function testMissingFile()\n    {\n        $files = new Filesystem;\n        $this->assertTrue($files->missing(self::$tempDir.'/file.txt'));\n    }\n\n    public function testDeleteDirectory()\n    {\n        mkdir(self::$tempDir.'/foo');\n        file_put_contents(self::$tempDir.'/foo/file.txt', 'Hello World');\n        $files = new Filesystem;\n        $files->deleteDirectory(self::$tempDir.'/foo');\n        Assert::assertDirectoryDoesNotExist(self::$tempDir.'/foo');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/foo/file.txt');\n    }\n\n    public function testDeleteDirectoryReturnFalseWhenNotADirectory()\n    {\n        mkdir(self::$tempDir.'/bar');\n        file_put_contents(self::$tempDir.'/bar/file.txt', 'Hello World');\n        $files = new Filesystem;\n        $this->assertFalse($files->deleteDirectory(self::$tempDir.'/bar/file.txt'));\n    }\n\n    public function testCleanDirectory()\n    {\n        mkdir(self::$tempDir.'/baz');\n        file_put_contents(self::$tempDir.'/baz/file.txt', 'Hello World');\n        $files = new Filesystem;\n        $files->cleanDirectory(self::$tempDir.'/baz');\n        $this->assertDirectoryExists(self::$tempDir.'/baz');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/baz/file.txt');\n    }\n\n    public function testMacro()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'Hello World');\n        $files = new Filesystem;\n        $tempDir = self::$tempDir;\n        $files->macro('getFoo', function () use ($files, $tempDir) {\n            return $files->get($tempDir.'/foo.txt');\n        });\n        $this->assertSame('Hello World', $files->getFoo());\n    }\n\n    public function testFilesMethod()\n    {\n        mkdir(self::$tempDir.'/views');\n        file_put_contents(self::$tempDir.'/views/1.txt', '1');\n        file_put_contents(self::$tempDir.'/views/2.txt', '2');\n        mkdir(self::$tempDir.'/views/_layouts');\n        $files = new Filesystem;\n        $results = $files->files(self::$tempDir.'/views');\n        $this->assertInstanceOf(SplFileInfo::class, $results[0]);\n        $this->assertInstanceOf(SplFileInfo::class, $results[1]);\n        unset($files);\n    }\n\n    public function testCopyDirectoryReturnsFalseIfSourceIsntDirectory()\n    {\n        $files = new Filesystem;\n        $this->assertFalse($files->copyDirectory(self::$tempDir.'/breeze/boom/foo/bar/baz', self::$tempDir));\n    }\n\n    public function testCopyDirectoryMovesEntireDirectory()\n    {\n        mkdir(self::$tempDir.'/tmp', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp/foo.txt', '');\n        file_put_contents(self::$tempDir.'/tmp/bar.txt', '');\n        mkdir(self::$tempDir.'/tmp/nested', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp/nested/baz.txt', '');\n\n        $files = new Filesystem;\n        $files->copyDirectory(self::$tempDir.'/tmp', self::$tempDir.'/tmp2');\n        $this->assertDirectoryExists(self::$tempDir.'/tmp2');\n        $this->assertFileExists(self::$tempDir.'/tmp2/foo.txt');\n        $this->assertFileExists(self::$tempDir.'/tmp2/bar.txt');\n        $this->assertDirectoryExists(self::$tempDir.'/tmp2/nested');\n        $this->assertFileExists(self::$tempDir.'/tmp2/nested/baz.txt');\n    }\n\n    public function testMoveDirectoryMovesEntireDirectory()\n    {\n        mkdir(self::$tempDir.'/tmp2', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp2/foo.txt', '');\n        file_put_contents(self::$tempDir.'/tmp2/bar.txt', '');\n        mkdir(self::$tempDir.'/tmp2/nested', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp2/nested/baz.txt', '');\n\n        $files = new Filesystem;\n        $files->moveDirectory(self::$tempDir.'/tmp2', self::$tempDir.'/tmp3');\n        $this->assertDirectoryExists(self::$tempDir.'/tmp3');\n        $this->assertFileExists(self::$tempDir.'/tmp3/foo.txt');\n        $this->assertFileExists(self::$tempDir.'/tmp3/bar.txt');\n        $this->assertDirectoryExists(self::$tempDir.'/tmp3/nested');\n        $this->assertFileExists(self::$tempDir.'/tmp3/nested/baz.txt');\n        Assert::assertDirectoryDoesNotExist(self::$tempDir.'/tmp2');\n    }\n\n    public function testMoveDirectoryMovesEntireDirectoryAndOverwrites()\n    {\n        mkdir(self::$tempDir.'/tmp4', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp4/foo.txt', '');\n        file_put_contents(self::$tempDir.'/tmp4/bar.txt', '');\n        mkdir(self::$tempDir.'/tmp4/nested', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp4/nested/baz.txt', '');\n        mkdir(self::$tempDir.'/tmp5', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp5/foo2.txt', '');\n        file_put_contents(self::$tempDir.'/tmp5/bar2.txt', '');\n\n        $files = new Filesystem;\n        $files->moveDirectory(self::$tempDir.'/tmp4', self::$tempDir.'/tmp5', true);\n        $this->assertDirectoryExists(self::$tempDir.'/tmp5');\n        $this->assertFileExists(self::$tempDir.'/tmp5/foo.txt');\n        $this->assertFileExists(self::$tempDir.'/tmp5/bar.txt');\n        $this->assertDirectoryExists(self::$tempDir.'/tmp5/nested');\n        $this->assertFileExists(self::$tempDir.'/tmp5/nested/baz.txt');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/tmp5/foo2.txt');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/tmp5/bar2.txt');\n        Assert::assertDirectoryDoesNotExist(self::$tempDir.'/tmp4');\n    }\n\n    public function testMoveDirectoryReturnsFalseWhileOverwritingAndUnableToDeleteDestinationDirectory()\n    {\n        mkdir(self::$tempDir.'/tmp6', 0777, true);\n        file_put_contents(self::$tempDir.'/tmp6/foo.txt', '');\n        mkdir(self::$tempDir.'/tmp7', 0777, true);\n\n        $files = m::mock(Filesystem::class)->makePartial();\n        $files->shouldReceive('deleteDirectory')->once()->andReturn(false);\n        $this->assertFalse($files->moveDirectory(self::$tempDir.'/tmp6', self::$tempDir.'/tmp7', true));\n    }\n\n    public function testGetThrowsExceptionNonexisitingFile()\n    {\n        $this->expectException(FileNotFoundException::class);\n        $this->expectExceptionMessage('File does not exist at path '.self::$tempDir.'/unknown-file.txt.');\n\n        (new Filesystem)->get(self::$tempDir.'/unknown-file.txt');\n    }\n\n    public function testGetRequireReturnsProperly()\n    {\n        file_put_contents(self::$tempDir.'/file.php', '<?php return \"Howdy?\"; ?>');\n        $files = new Filesystem;\n        $this->assertSame('Howdy?', $files->getRequire(self::$tempDir.'/file.php'));\n    }\n\n    public function testGetRequireThrowsExceptionNonExistingFile()\n    {\n        $this->expectException(FileNotFoundException::class);\n        $this->expectExceptionMessage('File does not exist at path '.self::$tempDir.'/unknown-file.txt.');\n\n        (new Filesystem)->getRequire(self::$tempDir.'/unknown-file.txt');\n    }\n\n    public function testJsonReturnsDecodedJsonData()\n    {\n        file_put_contents(self::$tempDir.'/file.json', '{\"foo\": \"bar\"}');\n        $files = new Filesystem;\n        $this->assertSame(['foo' => 'bar'], $files->json(self::$tempDir.'/file.json'));\n    }\n\n    public function testJsonReturnsNullIfJsonDataIsInvalid()\n    {\n        file_put_contents(self::$tempDir.'/file.json', '{\"foo\":');\n        $files = new Filesystem;\n        $this->assertNull($files->json(self::$tempDir.'/file.json'));\n    }\n\n    public function testAppendAddsDataToFile()\n    {\n        file_put_contents(self::$tempDir.'/file.txt', 'foo');\n        $files = new Filesystem;\n        $bytesWritten = $files->append(self::$tempDir.'/file.txt', 'bar');\n        $this->assertEquals(mb_strlen('bar', '8bit'), $bytesWritten);\n        $this->assertFileExists(self::$tempDir.'/file.txt');\n        $this->assertStringEqualsFile(self::$tempDir.'/file.txt', 'foobar');\n    }\n\n    public function testMoveMovesFiles()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $files->move(self::$tempDir.'/foo.txt', self::$tempDir.'/bar.txt');\n        $this->assertFileExists(self::$tempDir.'/bar.txt');\n        Assert::assertFileDoesNotExist(self::$tempDir.'/foo.txt');\n    }\n\n    public function testNameReturnsName()\n    {\n        file_put_contents(self::$tempDir.'/foobar.txt', 'foo');\n        $filesystem = new Filesystem;\n        $this->assertSame('foobar', $filesystem->name(self::$tempDir.'/foobar.txt'));\n    }\n\n    public function testExtensionReturnsExtension()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertSame('txt', $files->extension(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testBasenameReturnsBasename()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertSame('foo.txt', $files->basename(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testDirnameReturnsDirectory()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertEquals(self::$tempDir, $files->dirname(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testTypeIdentifiesFile()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertSame('file', $files->type(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testTypeIdentifiesDirectory()\n    {\n        mkdir(self::$tempDir.'/foo-dir');\n        $files = new Filesystem;\n        $this->assertSame('dir', $files->type(self::$tempDir.'/foo-dir'));\n    }\n\n    public function testSizeOutputsSize()\n    {\n        $size = file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertEquals($size, $files->size(self::$tempDir.'/foo.txt'));\n    }\n\n    #[RequiresPhpExtension('fileinfo')]\n    public function testMimeTypeOutputsMimeType()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        $this->assertSame('text/plain', $files->mimeType(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testIsWritable()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        @chmod(self::$tempDir.'/foo.txt', 0444);\n        $this->assertFalse($files->isWritable(self::$tempDir.'/foo.txt'));\n        @chmod(self::$tempDir.'/foo.txt', 0777);\n        $this->assertTrue($files->isWritable(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testIsReadable()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $files = new Filesystem;\n        // chmod is noneffective on Windows\n        if (DIRECTORY_SEPARATOR === '\\\\') {\n            $this->assertTrue($files->isReadable(self::$tempDir.'/foo.txt'));\n        } else {\n            @chmod(self::$tempDir.'/foo.txt', 0000);\n            $this->assertFalse($files->isReadable(self::$tempDir.'/foo.txt'));\n            @chmod(self::$tempDir.'/foo.txt', 0777);\n            $this->assertTrue($files->isReadable(self::$tempDir.'/foo.txt'));\n        }\n        $this->assertFalse($files->isReadable(self::$tempDir.'/doesnotexist.txt'));\n    }\n\n    public function testIsDirEmpty()\n    {\n        mkdir(self::$tempDir.'/foo-dir');\n        file_put_contents(self::$tempDir.'/foo-dir/.hidden', 'foo');\n        mkdir(self::$tempDir.'/bar-dir');\n        file_put_contents(self::$tempDir.'/bar-dir/foo.txt', 'foo');\n        mkdir(self::$tempDir.'/baz-dir');\n        mkdir(self::$tempDir.'/baz-dir/.hidden');\n        mkdir(self::$tempDir.'/quz-dir');\n        mkdir(self::$tempDir.'/quz-dir/not-hidden');\n\n        $files = new Filesystem;\n\n        $this->assertTrue($files->isEmptyDirectory(self::$tempDir.'/foo-dir', true));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/foo-dir'));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/bar-dir', true));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/bar-dir'));\n        $this->assertTrue($files->isEmptyDirectory(self::$tempDir.'/baz-dir', true));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/baz-dir'));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/quz-dir', true));\n        $this->assertFalse($files->isEmptyDirectory(self::$tempDir.'/quz-dir'));\n    }\n\n    public function testGlobFindsFiles()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        file_put_contents(self::$tempDir.'/bar.txt', 'bar');\n        $files = new Filesystem;\n        $glob = $files->glob(self::$tempDir.'/*.txt');\n        $this->assertContains(self::$tempDir.'/foo.txt', $glob);\n        $this->assertContains(self::$tempDir.'/bar.txt', $glob);\n    }\n\n    public function testAllFilesFindsFiles()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        file_put_contents(self::$tempDir.'/bar.txt', 'bar');\n        $files = new Filesystem;\n        $allFiles = [];\n        foreach ($files->allFiles(self::$tempDir) as $file) {\n            $allFiles[] = $file->getFilename();\n        }\n        $this->assertContains('foo.txt', $allFiles);\n        $this->assertContains('bar.txt', $allFiles);\n    }\n\n    public function testDirectoriesFindsDirectories()\n    {\n        mkdir(self::$tempDir.'/film');\n        mkdir(self::$tempDir.'/music');\n        $files = new Filesystem;\n        $directories = $files->directories(self::$tempDir);\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'film', $directories);\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'music', $directories);\n    }\n\n    public function testAllDirectoriesFindsDirectories()\n    {\n        mkdir(self::$tempDir.'/film');\n        mkdir(self::$tempDir.'/music');\n        mkdir(self::$tempDir.'/music/rock');\n        mkdir(self::$tempDir.'/music/blues');\n\n        $directories = (new Filesystem)->allDirectories(self::$tempDir);\n\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'film', $directories);\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'music', $directories);\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'music'.DIRECTORY_SEPARATOR.'rock', $directories);\n        $this->assertContains(self::$tempDir.DIRECTORY_SEPARATOR.'music'.DIRECTORY_SEPARATOR.'blues', $directories);\n    }\n\n    public function testMakeDirectory()\n    {\n        $files = new Filesystem;\n        $this->assertTrue($files->makeDirectory(self::$tempDir.'/created'));\n        $this->assertFileExists(self::$tempDir.'/created');\n    }\n\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    #[RequiresPhpExtension('pcntl')]\n    public function testSharedGet()\n    {\n        $content = str_repeat('123456', 1000000);\n        $result = 1;\n\n        posix_setpgid(0, 0);\n\n        for ($i = 1; $i <= 20; $i++) {\n            $pid = pcntl_fork();\n\n            if (! $pid) {\n                $files = new Filesystem;\n                $files->put(self::$tempDir.'/file.txt', $content, true);\n                $read = $files->get(self::$tempDir.'/file.txt', true);\n\n                terminate($this, strlen($read) === strlen($content) ? 1 : 0);\n            }\n        }\n\n        while (pcntl_waitpid(0, $status) != -1) {\n            $status = pcntl_wexitstatus($status);\n            $result *= $status;\n        }\n\n        $this->assertSame(1, $result);\n    }\n\n    public function testRequireOnceRequiresFileProperly()\n    {\n        $filesystem = new Filesystem;\n        mkdir(self::$tempDir.'/scripts');\n        file_put_contents(self::$tempDir.'/scripts/foo.php', '<?php function random_function_xyz(){};');\n        $filesystem->requireOnce(self::$tempDir.'/scripts/foo.php');\n        file_put_contents(self::$tempDir.'/scripts/foo.php', '<?php function random_function_xyz_changed(){};');\n        $filesystem->requireOnce(self::$tempDir.'/scripts/foo.php');\n        $this->assertTrue(function_exists('random_function_xyz'));\n        $this->assertFalse(function_exists('random_function_xyz_changed'));\n    }\n\n    public function testRequireOnceThrowsExceptionNonexisitingFile()\n    {\n        $this->expectException(FileNotFoundException::class);\n        $this->expectExceptionMessage('File does not exist at path '.__DIR__.'/unknown-file.txt.');\n\n        (new Filesystem)->requireOnce(__DIR__.'/unknown-file.txt');\n    }\n\n    public function testCopyCopiesFileProperly()\n    {\n        $filesystem = new Filesystem;\n        $data = 'contents';\n        mkdir(self::$tempDir.'/text');\n        file_put_contents(self::$tempDir.'/text/foo.txt', $data);\n        $filesystem->copy(self::$tempDir.'/text/foo.txt', self::$tempDir.'/text/foo2.txt');\n        $this->assertFileExists(self::$tempDir.'/text/foo2.txt');\n        $this->assertEquals($data, file_get_contents(self::$tempDir.'/text/foo2.txt'));\n    }\n\n    public function testHasSameHashChecksFileHashes()\n    {\n        $filesystem = new Filesystem;\n\n        mkdir(self::$tempDir.'/text');\n        file_put_contents(self::$tempDir.'/text/foo.txt', 'contents');\n        file_put_contents(self::$tempDir.'/text/foo2.txt', 'contents');\n        file_put_contents(self::$tempDir.'/text/foo3.txt', 'invalid');\n\n        $this->assertTrue($filesystem->hasSameHash(self::$tempDir.'/text/foo.txt', self::$tempDir.'/text/foo2.txt'));\n        $this->assertFalse($filesystem->hasSameHash(self::$tempDir.'/text/foo.txt', self::$tempDir.'/text/foo3.txt'));\n        $this->assertFalse($filesystem->hasSameHash(self::$tempDir.'/text/foo4.txt', self::$tempDir.'/text/foo.txt'));\n        $this->assertFalse($filesystem->hasSameHash(self::$tempDir.'/text/foo.txt', self::$tempDir.'/text/foo4.txt'));\n    }\n\n    public function testIsFileChecksFilesProperly()\n    {\n        $filesystem = new Filesystem;\n        mkdir(self::$tempDir.'/help');\n        file_put_contents(self::$tempDir.'/help/foo.txt', 'contents');\n        $this->assertTrue($filesystem->isFile(self::$tempDir.'/help/foo.txt'));\n        $this->assertFalse($filesystem->isFile(self::$tempDir.'./help'));\n    }\n\n    public function testFilesMethodReturnsFileInfoObjects()\n    {\n        mkdir(self::$tempDir.'/objects');\n        file_put_contents(self::$tempDir.'/objects/1.txt', '1');\n        file_put_contents(self::$tempDir.'/objects/2.txt', '2');\n        mkdir(self::$tempDir.'/objects/bar');\n        $files = new Filesystem;\n        $this->assertContainsOnlyInstancesOf(SplFileInfo::class, $files->files(self::$tempDir.'/objects'));\n        unset($files);\n    }\n\n    public function testAllFilesReturnsFileInfoObjects()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        file_put_contents(self::$tempDir.'/bar.txt', 'bar');\n        $files = new Filesystem;\n        $this->assertContainsOnlyInstancesOf(SplFileInfo::class, $files->allFiles(self::$tempDir));\n    }\n\n    public function testHashWithDefaultValue()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $filesystem = new Filesystem;\n        $this->assertSame('acbd18db4cc2f85cedef654fccc4a4d8', $filesystem->hash(self::$tempDir.'/foo.txt'));\n    }\n\n    public function testHash()\n    {\n        file_put_contents(self::$tempDir.'/foo.txt', 'foo');\n        $filesystem = new Filesystem;\n        $this->assertSame('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', $filesystem->hash(self::$tempDir.'/foo.txt', 'sha1'));\n        $this->assertSame('76d3bc41c9f588f7fcd0d5bf4718f8f84b1c41b20882703100b9eb9413807c01', $filesystem->hash(self::$tempDir.'/foo.txt', 'sha3-256'));\n    }\n\n    public function testLastModifiedReturnsTimestamp()\n    {\n        $path = self::$tempDir.'/timestamp.txt';\n        file_put_contents($path, 'test content');\n\n        $filesystem = new Filesystem;\n        $timestamp = $filesystem->lastModified($path);\n\n        $this->assertIsInt($timestamp);\n        $this->assertGreaterThan(0, $timestamp);\n        $this->assertEquals(filemtime($path), $timestamp);\n    }\n\n    /**\n     * @param  string  $file\n     * @return int\n     */\n    private function getFilePermissions($file)\n    {\n        $filePerms = fileperms($file);\n        $filePerms = substr(sprintf('%o', $filePerms), -3);\n\n        return (int) base_convert($filePerms, 8, 10);\n    }\n\n    public function testFileCreationAndContentVerification()\n    {\n        $files = new Filesystem;\n\n        $testContent = 'This is a test file content';\n        $filePath = self::$tempDir.'/test.txt';\n\n        $files->put($filePath, $testContent);\n\n        $this->assertTrue($files->exists($filePath));\n        $this->assertSame($testContent, $files->get($filePath));\n        $this->assertEquals(strlen($testContent), $files->size($filePath));\n    }\n\n    public function testDirectoryOperationsWithSubdirectories()\n    {\n        $files = new Filesystem;\n\n        $dirPath = self::$tempDir.'/test_dir';\n        $subDirPath = $dirPath.'/sub_dir';\n\n        $this->assertTrue($files->makeDirectory($dirPath));\n        $this->assertTrue($files->isDirectory($dirPath));\n\n        $this->assertTrue($files->makeDirectory($subDirPath));\n        $this->assertTrue($files->isDirectory($subDirPath));\n\n        $filePath = $subDirPath.'/test.txt';\n        $files->put($filePath, 'test content');\n\n        $this->assertTrue($files->exists($filePath));\n\n        $allFiles = $files->allFiles($dirPath);\n\n        $this->assertCount(1, $allFiles);\n        $this->assertEquals('test.txt', $allFiles[0]->getFilename());\n    }\n}\n"
  },
  {
    "path": "tests/Filesystem/JoinPathsHelperTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Filesystem;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\nclass JoinPathsHelperTest extends TestCase\n{\n    #[RequiresOperatingSystem('Linux|DAR')]\n    #[DataProvider('unixDataProvider')]\n    public function testItCanMergePathsForUnix(string $expected, string $given)\n    {\n        $this->assertSame($expected, $given);\n    }\n\n    public static function unixDataProvider()\n    {\n        yield ['very/Basic/Functionality.php', join_paths('very', 'Basic', 'Functionality.php')];\n        yield ['segments/get/ltrimed/by_directory/separator.php', join_paths('segments', '/get/ltrimed', '/by_directory/separator.php')];\n        yield ['only/\\\\os_separator\\\\/\\\\get_ltrimmed.php', join_paths('only', '\\\\os_separator\\\\', '\\\\get_ltrimmed.php')];\n        yield ['/base_path//does_not/get_trimmed.php', join_paths('/base_path/', '/does_not', '/get_trimmed.php')];\n        yield ['Empty/0/1/Segments/00/Get_removed.php', join_paths('Empty', '', '0', null, 0, false, [], '1', 'Segments', '00', 'Get_removed.php')];\n        yield ['', join_paths(null, null, '')];\n        yield ['1/2/3', join_paths(1, 0, 2, 3)];\n        yield ['app/objecty', join_paths('app', new class()\n        {\n            public function __toString()\n            {\n                return 'objecty';\n            }\n        })];\n        yield ['app/0', join_paths('app', new class()\n        {\n            public function __toString()\n            {\n                return '0';\n            }\n        })];\n    }\n\n    #[RequiresOperatingSystem('Windows')]\n    #[DataProvider('windowsDataProvider')]\n    public function testItCanMergePathsForWindows(string $expected, string $given)\n    {\n        $this->assertSame($expected, $given);\n    }\n\n    public static function windowsDataProvider()\n    {\n        yield ['app\\Basic\\Functionality.php', join_paths('app', 'Basic', 'Functionality.php')];\n        yield ['segments\\get\\ltrimed\\by_directory\\separator.php', join_paths('segments', '\\get\\ltrimed', '\\by_directory\\separator.php')];\n        yield ['only\\\\/os_separator/\\\\/get_ltrimmed.php', join_paths('only', '/os_separator/', '/get_ltrimmed.php')];\n        yield ['\\base_path\\\\\\\\does_not\\get_trimmed.php', join_paths('\\\\base_path\\\\', '\\does_not', '\\get_trimmed.php')];\n        yield ['Empty\\0\\1\\Segments\\00\\Get_removed.php', join_paths('Empty', '', '0', null, 0, false, [], '1', 'Segments', '00', 'Get_removed.php')];\n        yield ['', join_paths(null, null, '')];\n        yield ['1\\2\\3', join_paths(1, 2, 3)];\n        yield ['app\\\\objecty', join_paths('app', new class()\n        {\n            public function __toString()\n            {\n                return 'objecty';\n            }\n        })];\n        yield ['app\\\\0', join_paths('app', new class()\n        {\n            public function __toString()\n            {\n                return '0';\n            }\n        })];\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Bootstrap/HandleExceptionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Bootstrap;\n\nuse ErrorException;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\HandleExceptions;\nuse Illuminate\\Log\\LogManager;\nuse Illuminate\\Support\\Env;\nuse Mockery as m;\nuse Monolog\\Handler\\NullHandler;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse RuntimeException;\n\nclass HandleExceptionsTest extends TestCase\n{\n    protected $app;\n    protected $config;\n\n    protected function setUp(): void\n    {\n        $this->app = m::mock(Application::setInstance(new Application));\n\n        $this->app->instance('config', $this->config = new Config());\n    }\n\n    protected function handleExceptions()\n    {\n        return tap(new HandleExceptions(), function ($instance) {\n            (new ReflectionClass($instance))->getProperty('app')->setValue($instance, $this->app);\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        Application::setInstance(null);\n        HandleExceptions::flushState($this);\n\n        parent::tearDown();\n    }\n\n    public function testPhpDeprecations()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->with('deprecations')->andReturnSelf();\n        $logger->expects('warning')->with(sprintf('%s in %s on line %s',\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        ));\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testPhpDeprecationsWithStackTraces()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $this->config->set('logging.deprecations', [\n            'channel' => 'null',\n            'trace' => true,\n        ]);\n\n        $logger->expects('channel')->with('deprecations')->andReturnSelf();\n        $logger->expects('warning')->with(\n            m::on(fn (string $message) => (bool) preg_match(\n                <<<REGEXP\n                #ErrorException: str_contains\\(\\): Passing null to parameter \\#2 \\(\\\\\\$needle\\) of type string is deprecated in /home/user/laravel/routes/web\\.php:17\n                Stack trace:\n                \\#0 .*helpers.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions.*\n                \\#1 .*HandleExceptions\\.php\\(.*\\): with.*\n                \\#2 .*HandleExceptions\\.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions->handleDeprecation.*\n                \\#3 .*HandleExceptionsTest\\.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions->handleError.*\n                [\\s\\S]*#i\n                REGEXP,\n                $message\n            ))\n        );\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testNullValueAsChannelUsesNullDriver()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $this->config->set('logging.deprecations', [\n            'channel' => null,\n            'trace' => false,\n        ]);\n\n        $logger->expects('channel')->with('deprecations')->andReturnSelf();\n        $logger->expects('warning')->with(sprintf('%s in %s on line %s',\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        ));\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertEquals([\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n        ], $this->config->get('logging.channels.deprecations'));\n    }\n\n    public function testUserDeprecations()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->with('deprecations')->andReturnSelf();\n        $logger->expects('warning')->with(sprintf('%s in %s on line %s',\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        ));\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testUserDeprecationsWithStackTraces()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $this->config->set('logging.deprecations', [\n            'channel' => 'null',\n            'trace' => true,\n        ]);\n\n        $logger->expects('channel')->with('deprecations')->andReturnSelf();\n        $logger->expects('warning')->with(\n            m::on(fn (string $message) => (bool) preg_match(\n                <<<REGEXP\n                #ErrorException: str_contains\\(\\): Passing null to parameter \\#2 \\(\\\\\\$needle\\) of type string is deprecated in /home/user/laravel/routes/web\\.php:17\n                Stack trace:\n                \\#0 .*helpers.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions.*\n                \\#1 .*HandleExceptions\\.php\\(.*\\): with.*\n                \\#2 .*HandleExceptions\\.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions->handleDeprecation.*\n                \\#3 .*HandleExceptionsTest\\.php\\(.*\\): Illuminate\\\\\\\\Foundation\\\\\\\\Bootstrap\\\\\\\\HandleExceptions->handleError.*\n                [\\s\\S]*#i\n                REGEXP,\n                $message\n            ))\n        );\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testErrors()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n\n        $logger->shouldNotReceive('channel');\n        $logger->shouldNotReceive('warning');\n\n        $this->expectException(ErrorException::class);\n        $this->expectExceptionMessage('Something went wrong');\n\n        $this->handleExceptions()->handleError(\n            E_ERROR,\n            'Something went wrong',\n            '/home/user/laravel/src/Providers/AppServiceProvider.php',\n            17\n        );\n    }\n\n    public function testEnsuresDeprecationsDriver()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->andReturnSelf();\n        $logger->expects('warning');\n\n        $this->config->set('logging.channels.stack', [\n            'driver' => 'stack',\n            'channels' => ['single'],\n            'ignore_exceptions' => false,\n        ]);\n        $this->config->set('logging.deprecations', 'stack');\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertEquals(\n            [\n                'driver' => 'stack',\n                'channels' => ['single'],\n                'ignore_exceptions' => false,\n            ],\n            $this->config->get('logging.channels.deprecations')\n        );\n    }\n\n    public function testEnsuresNullDeprecationsDriver()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->andReturnSelf();\n        $logger->expects('warning');\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertEquals(\n            NullHandler::class,\n            $this->config->get('logging.channels.deprecations.handler')\n        );\n    }\n\n    public function testEnsuresNullLogDriver()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->andReturnSelf();\n        $logger->expects('warning');\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertEquals(\n            NullHandler::class,\n            $this->config->get('logging.channels.deprecations.handler')\n        );\n    }\n\n    public function testDoNotOverrideExistingNullLogDriver()\n    {\n        $logger = m::mock(LogManager::class);\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $logger->expects('channel')->andReturnSelf();\n        $logger->expects('warning');\n\n        $this->config->set('logging.channels.null', [\n            'driver' => 'monolog',\n            'handler' => CustomNullHandler::class,\n        ]);\n\n        $this->handleExceptions()->handleError(\n            E_USER_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertEquals(\n            CustomNullHandler::class,\n            $this->config->get('logging.channels.deprecations.handler')\n        );\n    }\n\n    public function testNoDeprecationsDriverIfNoDeprecationsHereSend()\n    {\n        $this->assertEquals(null, $this->config->get('logging.deprecations'));\n        $this->assertEquals(null, $this->config->get('logging.channels.deprecations'));\n    }\n\n    public function testIgnoreDeprecationIfLoggerUnresolvable()\n    {\n        $this->app->expects('runningUnitTests')->andReturn(false);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testItIgnoreDeprecationLoggingWhenRunningUnitTests()\n    {\n        $resolved = false;\n        $this->app->bind(LogManager::class, function () use (&$resolved) {\n            $resolved = true;\n\n            throw new RuntimeException();\n        });\n        $this->app->expects('runningUnitTests')->andReturn(true);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n\n        $this->assertFalse($resolved);\n    }\n\n    public function testItCanForceViaConfigDeprecationLoggingWhenRunningUnitTests()\n    {\n        $logger = m::mock(LogManager::class);\n        $logger->expects('channel')->andReturnSelf();\n        $logger->expects('warning');\n        $this->app->instance(LogManager::class, $logger);\n        $this->app->expects('runningUnitTests')->andReturn(true);\n        $this->app->expects('hasBeenBootstrapped')->andReturn(true);\n\n        Env::getRepository()->set('LOG_DEPRECATIONS_WHILE_TESTING', true);\n\n        $this->handleExceptions()->handleError(\n            E_DEPRECATED,\n            'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',\n            '/home/user/laravel/routes/web.php',\n            17\n        );\n    }\n\n    public function testForgetApp()\n    {\n        $instance = $this->handleExceptions();\n\n        $appResolver = fn () => (new ReflectionClass($instance))->getProperty('app')->getValue($instance);\n\n        $this->assertNotNull($appResolver());\n\n        HandleExceptions::forgetApp();\n\n        $this->assertNull($appResolver());\n    }\n\n    public function testHandlerForgetsPreviousApp()\n    {\n        $instance = $this->handleExceptions();\n\n        $appResolver = fn () => (new ReflectionClass($instance))->getProperty('app')->getValue($instance);\n\n        $this->assertSame($this->app, $appResolver());\n\n        $instance->bootstrap($newApp = tap(m::mock(Application::class), function ($app) {\n            $app->expects('environment')->andReturn(true);\n        }));\n\n        $this->assertNotSame($this->app, $appResolver());\n        $this->assertSame($newApp, $appResolver());\n    }\n}\n\nclass CustomNullHandler extends NullHandler\n{\n}\n"
  },
  {
    "path": "tests/Foundation/Bootstrap/LoadConfigurationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Bootstrap;\n\nuse Closure;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\LoadConfiguration;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nclass LoadConfigurationTest extends TestCase\n{\n    public function testLoadsBaseConfiguration()\n    {\n        $app = new Application();\n\n        (new LoadConfiguration)->bootstrap($app);\n\n        $this->assertSame('Laravel', $app['config']['app.name']);\n    }\n\n    public function testSetsEnvironmentResolver()\n    {\n        $app = new Application();\n        $this->assertNull((new ReflectionClass($app))->getProperty('environmentResolver')->getValue($app));\n\n        (new LoadConfiguration)->bootstrap($app);\n\n        $this->assertInstanceOf(\n            Closure::class,\n            (new ReflectionClass($app))->getProperty('environmentResolver')->getValue($app)\n        );\n    }\n\n    public function testDontLoadBaseConfiguration()\n    {\n        $app = new Application();\n        $app->dontMergeFrameworkConfiguration();\n\n        (new LoadConfiguration)->bootstrap($app);\n\n        $this->assertNull($app['config']['app.name']);\n    }\n\n    public function testLoadsConfigurationInIsolation()\n    {\n        $app = new Application(__DIR__.'/../fixtures');\n        $app->useConfigPath(__DIR__.'/../fixtures/config');\n\n        (new LoadConfiguration)->bootstrap($app);\n\n        $this->assertNull($app['config']['bar.foo']);\n        $this->assertSame('bar', $app['config']['custom.foo']);\n    }\n\n    public function testConfigurationArrayKeysMatchLoadedFilenames()\n    {\n        $baseConfigPath = __DIR__.'/../../../config';\n        $customConfigPath = __DIR__.'/../fixtures/config';\n\n        $app = new Application();\n        $app->useConfigPath($customConfigPath);\n\n        (new LoadConfiguration)->bootstrap($app);\n\n        $this->assertEqualsCanonicalizing(\n            array_keys($app['config']->all()),\n            collect((new Filesystem)->files([\n                $baseConfigPath,\n                $customConfigPath,\n            ]))->map(fn ($file) => $file->getBaseName('.php'))->unique()->values()->toArray()\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Bootstrap/LoadEnvironmentVariablesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Bootstrap;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass LoadEnvironmentVariablesTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        unset($_ENV['FOO'], $_SERVER['FOO']);\n        putenv('FOO');\n\n        parent::tearDown();\n    }\n\n    protected function getAppMock($file)\n    {\n        $app = m::mock(Application::class);\n\n        $app->shouldReceive('configurationIsCached')\n            ->once()->with()->andReturn(false);\n        $app->shouldReceive('runningInConsole')\n            ->once()->with()->andReturn(false);\n        $app->shouldReceive('environmentPath')\n            ->once()->with()->andReturn(__DIR__.'/../fixtures');\n        $app->shouldReceive('environmentFile')\n            ->once()->with()->andReturn($file);\n\n        return $app;\n    }\n\n    public function testCanLoad()\n    {\n        $this->expectOutputString('');\n\n        (new LoadEnvironmentVariables)->bootstrap($this->getAppMock('.env'));\n\n        $this->assertSame('BAR', env('FOO'));\n        $this->assertSame('BAR', getenv('FOO'));\n        $this->assertSame('BAR', $_ENV['FOO']);\n        $this->assertSame('BAR', $_SERVER['FOO']);\n    }\n\n    public function testCanFailSilent()\n    {\n        $this->expectOutputString('');\n\n        (new LoadEnvironmentVariables)->bootstrap($this->getAppMock('BAD_FILE'));\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Configuration/ExceptionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Configuration;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Foundation\\Configuration\\Exceptions;\nuse Illuminate\\Foundation\\Exceptions\\Handler;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass ExceptionsTest extends TestCase\n{\n    public function testStopIgnoring()\n    {\n        $container = new Container;\n        $exceptions = new Exceptions($handler = new class($container) extends Handler\n        {\n            public function getDontReport(): array\n            {\n                return array_merge($this->dontReport, $this->internalDontReport);\n            }\n        });\n\n        $this->assertContains(HttpException::class, $handler->getDontReport());\n        $exceptions = $exceptions->stopIgnoring(HttpException::class);\n        $this->assertInstanceOf(Exceptions::class, $exceptions);\n        $this->assertNotContains(HttpException::class, $handler->getDontReport());\n\n        $this->assertContains(ModelNotFoundException::class, $handler->getDontReport());\n        $exceptions->stopIgnoring([ModelNotFoundException::class]);\n        $this->assertNotContains(ModelNotFoundException::class, $handler->getDontReport());\n    }\n\n    public function testShouldRenderJsonWhen()\n    {\n        $exceptions = new Exceptions(new Handler(new Container));\n\n        $shouldReturnJson = (fn () => $this->shouldReturnJson(new Request, new Exception()))->call($exceptions->handler);\n        $this->assertFalse($shouldReturnJson);\n\n        $exceptions->shouldRenderJsonWhen(fn () => true);\n        $shouldReturnJson = (fn () => $this->shouldReturnJson(new Request, new Exception()))->call($exceptions->handler);\n        $this->assertTrue($shouldReturnJson);\n\n        $exceptions->shouldRenderJsonWhen(fn () => false);\n        $shouldReturnJson = (fn () => $this->shouldReturnJson(new Request, new Exception()))->call($exceptions->handler);\n        $this->assertFalse($shouldReturnJson);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Configuration/MiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Configuration;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode;\nuse Illuminate\\Cookie\\Middleware\\EncryptCookies;\nuse Illuminate\\Foundation\\Configuration\\Middleware;\nuse Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Foundation\\Http\\Middleware\\TrimStrings;\nuse Illuminate\\Http\\Middleware\\TrustHosts;\nuse Illuminate\\Http\\Middleware\\TrustProxies;\nuse Illuminate\\Http\\Request;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\nclass MiddlewareTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n        ConvertEmptyStringsToNull::flushState();\n        EncryptCookies::flushState();\n        PreventRequestForgery::flushState();\n        PreventRequestsDuringMaintenance::flushState();\n        TrimStrings::flushState();\n        TrustProxies::flushState();\n\n        parent::tearDown();\n    }\n\n    public function testConvertEmptyStringsToNull()\n    {\n        $configuration = new Middleware();\n        $middleware = new ConvertEmptyStringsToNull();\n\n        $configuration->convertEmptyStringsToNull(except: [\n            fn (Request $request) => $request->has('skip-all-1'),\n            fn (Request $request) => $request->has('skip-all-2'),\n        ]);\n\n        $symfonyRequest = new SymfonyRequest([\n            'aaa' => '  123  ',\n            'bbb' => '',\n        ]);\n\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $request = $middleware->handle($request, fn (Request $request) => $request);\n\n        $this->assertSame('  123  ', $request->get('aaa'));\n        $this->assertNull($request->get('bbb'));\n\n        $symfonyRequest = new SymfonyRequest([\n            'aaa' => '  123  ',\n            'bbb' => '',\n            'skip-all-1' => 'true',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $request = $middleware->handle($request, fn (Request $request) => $request);\n\n        $this->assertSame('  123  ', $request->get('aaa'));\n        $this->assertSame('', $request->get('bbb'));\n\n        $symfonyRequest = new SymfonyRequest([\n            'aaa' => '  123  ',\n            'bbb' => '',\n            'skip-all-2' => 'true',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $request = $middleware->handle($request, fn (Request $request) => $request);\n\n        $this->assertSame('  123  ', $request->get('aaa'));\n        $this->assertSame('', $request->get('bbb'));\n    }\n\n    public function testTrimStrings()\n    {\n        $configuration = new Middleware();\n        $middleware = new TrimStrings();\n\n        $configuration->trimStrings(except: [\n            'aaa',\n            fn (Request $request) => $request->has('skip-all'),\n        ]);\n\n        $symfonyRequest = new SymfonyRequest([\n            'aaa' => '  123  ',\n            'bbb' => '  456  ',\n            'ccc' => '  789  ',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $request = $middleware->handle($request, fn (Request $request) => $request);\n\n        $this->assertSame('  123  ', $request->get('aaa'));\n        $this->assertSame('456', $request->get('bbb'));\n        $this->assertSame('789', $request->get('ccc'));\n\n        $symfonyRequest = new SymfonyRequest([\n            'aaa' => '  123  ',\n            'bbb' => '  456  ',\n            'ccc' => '  789  ',\n            'skip-all' => true,\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $request = $middleware->handle($request, fn (Request $request) => $request);\n\n        $this->assertSame('  123  ', $request->get('aaa'));\n        $this->assertSame('  456  ', $request->get('bbb'));\n        $this->assertSame('  789  ', $request->get('ccc'));\n    }\n\n    public function testTrustProxies()\n    {\n        $configuration = new Middleware();\n        $middleware = new TrustProxies;\n\n        $reflection = new ReflectionClass($middleware);\n        $method = $reflection->getMethod('proxies');\n        $property = $reflection->getProperty('proxies');\n\n        $this->assertNull($method->invoke($middleware));\n\n        $property->setValue($middleware, [\n            '192.168.1.1',\n            '192.168.1.2',\n        ]);\n\n        $this->assertEquals([\n            '192.168.1.1',\n            '192.168.1.2',\n        ], $method->invoke($middleware));\n\n        $configuration->trustProxies(at: '*');\n        $this->assertEquals('*', $method->invoke($middleware));\n\n        $configuration->trustProxies(at: [\n            '192.168.1.3',\n            '192.168.1.4',\n        ]);\n        $this->assertEquals([\n            '192.168.1.3',\n            '192.168.1.4',\n        ], $method->invoke($middleware));\n    }\n\n    public function testTrustHeaders()\n    {\n        $configuration = new Middleware();\n        $middleware = new TrustProxies;\n\n        $reflection = new ReflectionClass($middleware);\n        $method = $reflection->getMethod('headers');\n        $property = $reflection->getProperty('headers');\n\n        $this->assertEquals(Request::HEADER_X_FORWARDED_FOR |\n            Request::HEADER_X_FORWARDED_HOST |\n            Request::HEADER_X_FORWARDED_PORT |\n            Request::HEADER_X_FORWARDED_PROTO |\n            Request::HEADER_X_FORWARDED_PREFIX |\n            Request::HEADER_X_FORWARDED_AWS_ELB, $method->invoke($middleware));\n\n        $property->setValue($middleware, Request::HEADER_X_FORWARDED_AWS_ELB);\n\n        $this->assertEquals(Request::HEADER_X_FORWARDED_AWS_ELB, $method->invoke($middleware));\n\n        $configuration->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR);\n\n        $this->assertEquals(Request::HEADER_X_FORWARDED_FOR, $method->invoke($middleware));\n\n        $configuration->trustProxies([\n            '192.168.1.3',\n            '192.168.1.4',\n        ], Request::HEADER_X_FORWARDED_FOR |\n            Request::HEADER_X_FORWARDED_HOST |\n            Request::HEADER_X_FORWARDED_PORT\n        );\n\n        $this->assertEquals(Request::HEADER_X_FORWARDED_FOR |\n            Request::HEADER_X_FORWARDED_HOST |\n            Request::HEADER_X_FORWARDED_PORT, $method->invoke($middleware));\n    }\n\n    public function testTrustHosts()\n    {\n        $app = m::mock(Application::class);\n        $configuration = new Middleware();\n        $middleware = new class($app) extends TrustHosts\n        {\n            protected function allSubdomainsOfApplicationUrl()\n            {\n                return '^(.+\\.)?laravel\\.test$';\n            }\n        };\n\n        $this->assertEquals(['^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts();\n        $this->assertEquals(['^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts(at: ['my.test']);\n        $this->assertEquals(['my.test', '^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts(at: static fn () => ['my.test']);\n        $this->assertEquals(['my.test', '^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts(at: ['my.test'], subdomains: false);\n        $this->assertEquals(['my.test'], $middleware->hosts());\n\n        $configuration->trustHosts(at: static fn () => ['my.test'], subdomains: false);\n        $this->assertEquals(['my.test'], $middleware->hosts());\n\n        $configuration->trustHosts(at: []);\n        $this->assertEquals(['^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts(at: static fn () => []);\n        $this->assertEquals(['^(.+\\.)?laravel\\.test$'], $middleware->hosts());\n\n        $configuration->trustHosts(at: [], subdomains: false);\n        $this->assertEquals([], $middleware->hosts());\n\n        $configuration->trustHosts(at: static fn () => [], subdomains: false);\n        $this->assertEquals([], $middleware->hosts());\n    }\n\n    public function testEncryptCookies()\n    {\n        $configuration = new Middleware();\n        $encrypter = m::mock(Encrypter::class);\n        $middleware = new EncryptCookies($encrypter);\n\n        $this->assertFalse($middleware->isDisabled('aaa'));\n        $this->assertFalse($middleware->isDisabled('bbb'));\n\n        $configuration->encryptCookies(except: [\n            'aaa',\n            'bbb',\n        ]);\n\n        $this->assertTrue($middleware->isDisabled('aaa'));\n        $this->assertTrue($middleware->isDisabled('bbb'));\n    }\n\n    public function testPreventRequestsDuringMaintenance()\n    {\n        $configuration = new Middleware();\n\n        $mode = m::mock(MaintenanceMode::class);\n        $mode->shouldReceive('active')->andReturn(true);\n        $mode->shouldReceive('date')->andReturn([]);\n        $app = m::mock(Application::class);\n        $app->shouldReceive('maintenanceMode')->andReturn($mode);\n        $middleware = new PreventRequestsDuringMaintenance($app);\n\n        $reflection = new ReflectionClass($middleware);\n        $method = $reflection->getMethod('inExceptArray');\n\n        $symfonyRequest = new SymfonyRequest();\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $symfonyRequest->server->set('REQUEST_URI', 'metrics/requests');\n\n        $request = Request::createFromBase($symfonyRequest);\n        $this->assertFalse($method->invoke($middleware, $request));\n\n        $configuration->preventRequestsDuringMaintenance(['metrics/*']);\n        $this->assertTrue($method->invoke($middleware, $request));\n    }\n\n    public function testPreventRequestForgery()\n    {\n        $configuration = new Middleware();\n        $middleware = new PreventRequestForgery(\n            m::mock(Application::class),\n            m::mock(Encrypter::class)\n        );\n\n        $this->assertSame([], $middleware->getExcludedPaths());\n\n        $configuration->preventRequestForgery(\n            except: ['/webhook', '/api/*'],\n            originOnly: true,\n            allowSameSite: true\n        );\n\n        $this->assertSame(['/webhook', '/api/*'], $middleware->getExcludedPaths());\n\n        $reflection = new ReflectionClass(PreventRequestForgery::class);\n        $this->assertTrue($reflection->getStaticPropertyValue('originOnly'));\n        $this->assertTrue($reflection->getStaticPropertyValue('allowSameSite'));\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Console/AboutCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Console\\AboutCommand;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AboutCommandTest extends TestCase\n{\n    /**\n     * @param  \\Closure(bool):mixed  $format\n     * @param  mixed  $expected\n     */\n    #[DataProvider('cliDataProvider')]\n    public function testItCanFormatForCliInterface($format, $expected)\n    {\n        $this->assertSame($expected, value($format, false));\n    }\n\n    public static function cliDataProvider()\n    {\n        yield [AboutCommand::format(true, console: fn ($value) => $value === true ? 'YES' : 'NO'), 'YES'];\n        yield [AboutCommand::format(false, console: fn ($value) => $value === true ? 'YES' : 'NO'), 'NO'];\n    }\n\n    /**\n     * @param  \\Closure(bool):mixed  $format\n     * @param  mixed  $expected\n     */\n    #[DataProvider('jsonDataProvider')]\n    public function testItCanFormatForJsonInterface($format, $expected)\n    {\n        $this->assertSame($expected, value($format, true));\n    }\n\n    public static function jsonDataProvider()\n    {\n        yield [AboutCommand::format(true, json: fn ($value) => $value === true ? 'YES' : 'NO'), 'YES'];\n        yield [AboutCommand::format(false, json: fn ($value) => $value === true ? 'YES' : 'NO'), 'NO'];\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Console/CliDumperTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Console\\CliDumper;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\nuse Symfony\\Component\\VarDumper\\Caster\\ReflectionCaster;\nuse Symfony\\Component\\VarDumper\\Cloner\\VarCloner;\n\nclass CliDumperTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        CliDumper::resolveDumpSourceUsing(function () {\n            return [\n                '/my-work-director/app/routes/console.php',\n                'app/routes/console.php',\n                18,\n            ];\n        });\n    }\n\n    public function testString()\n    {\n        $output = $this->dump('string');\n\n        $expected = \"\\\"string\\\" // app/routes/console.php:18\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testInteger()\n    {\n        $output = $this->dump(1);\n\n        $expected = \"1 // app/routes/console.php:18\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testFloat()\n    {\n        $output = $this->dump(1.1);\n\n        $expected = \"1.1 // app/routes/console.php:18\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testArray()\n    {\n        $output = $this->dump(['string', 1, 1.1, ['string', 1, 1.1]]);\n\n        $expected = <<<'EOF'\n        array:4 [\n          0 => \"string\"\n          1 => 1\n          2 => 1.1\n          3 => array:3 [\n            0 => \"string\"\n            1 => 1\n            2 => 1.1\n          ]\n        ] // app/routes/console.php:18\n\n        EOF;\n\n        $this->assertSame(\n            str_replace(\"\\r\\n\", \"\\n\", $expected),\n            str_replace(\"\\r\\n\", \"\\n\", $output)\n        );\n    }\n\n    public function testBoolean()\n    {\n        $output = $this->dump(true);\n\n        $expected = \"true // app/routes/console.php:18\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testObject()\n    {\n        $user = new stdClass();\n        $user->name = 'Guus';\n\n        $output = $this->dump($user);\n\n        $objectId = spl_object_id($user);\n\n        $expected = <<<EOF\n        {#$objectId\n          +\"name\": \"Guus\"\n        } // app/routes/console.php:18\n\n        EOF;\n\n        $this->assertSame(\n            str_replace(\"\\r\\n\", \"\\n\", $expected),\n            str_replace(\"\\r\\n\", \"\\n\", $output)\n        );\n    }\n\n    public function testNull()\n    {\n        $output = $this->dump(null);\n\n        $expected = \"null // app/routes/console.php:18\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testWhenIsFileViewIsNotViewCompiled()\n    {\n        $file = '/my-work-directory/routes/console.php';\n\n        $output = new BufferedOutput();\n        $dumper = new CliDumper(\n            $output,\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('isCompiledViewFile');\n        $isCompiledViewFile = $method->invoke($dumper, $file);\n\n        $this->assertFalse($isCompiledViewFile);\n    }\n\n    public function testWhenIsFileViewIsViewCompiled()\n    {\n        $file = '/my-work-directory/storage/framework/views/6687c33c38b71a8560.php';\n\n        $output = new BufferedOutput();\n        $dumper = new CliDumper(\n            $output,\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('isCompiledViewFile');\n        $isCompiledViewFile = $method->invoke($dumper, $file);\n\n        $this->assertTrue($isCompiledViewFile);\n    }\n\n    public function testGetOriginalViewCompiledFile()\n    {\n        $compiled = __DIR__.'/../fixtures/fake-compiled-view.php';\n        $original = '/my-work-directory/resources/views/welcome.blade.php';\n\n        $output = new BufferedOutput();\n        $dumper = new CliDumper(\n            $output,\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('getOriginalFileForCompiledView');\n\n        $this->assertSame($original, $method->invoke($dumper, $compiled));\n    }\n\n    public function testWhenGetOriginalViewCompiledFileFails()\n    {\n        $compiled = __DIR__.'/../fixtures/fake-compiled-view-without-source-map.php';\n        $original = $compiled;\n\n        $output = new BufferedOutput();\n        $dumper = new CliDumper(\n            $output,\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('getOriginalFileForCompiledView');\n\n        $this->assertSame($original, $method->invoke($dumper, $compiled));\n    }\n\n    public function testUnresolvableSource()\n    {\n        CliDumper::resolveDumpSourceUsing(fn () => null);\n\n        $output = $this->dump('string');\n\n        $expected = \"\\\"string\\\"\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    public function testUnresolvableLine()\n    {\n        CliDumper::resolveDumpSourceUsing(function () {\n            return [\n                '/my-work-directory/resources/views/welcome.blade.php',\n                'resources/views/welcome.blade.php',\n                null,\n            ];\n        });\n\n        $output = $this->dump('hey from view');\n\n        $expected = \"\\\"hey from view\\\" // resources/views/welcome.blade.php\\n\";\n\n        $this->assertSame($expected, $output);\n    }\n\n    protected function dump($value)\n    {\n        $output = new BufferedOutput();\n        $dumper = new CliDumper(\n            $output,\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views',\n        );\n\n        $cloner = tap(new VarCloner())->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);\n\n        $dumper->dumpWithSource($cloner->cloneVar($value));\n\n        return $output->fetch();\n    }\n\n    protected function tearDown(): void\n    {\n        CliDumper::resolveDumpSourceUsing(null);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Console/KernelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Console;\n\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Console\\Kernel;\nuse Illuminate\\Foundation\\Events\\Terminating;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\StringInput;\n\nclass KernelTest extends TestCase\n{\n    public function testItDispatchesTerminatingEvent()\n    {\n        $called = [];\n        $app = new Application;\n        $events = new Dispatcher($app);\n        $app->instance('events', $events);\n        $kernel = new Kernel($app, $events);\n        $events->listen(function (Terminating $terminating) use (&$called) {\n            $called[] = 'terminating event';\n        });\n        $app->terminating(function () use (&$called) {\n            $called[] = 'terminating callback';\n        });\n\n        $kernel->terminate(new StringInput('tinker'), 0);\n\n        $this->assertSame([\n            'terminating event',\n            'terminating callback',\n        ], $called);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Console/RouteListCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Console;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Console\\RouteListCommand;\nuse Illuminate\\Foundation\\Http\\Kernel;\nuse Illuminate\\Routing\\Router;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RouteListCommandTest extends TestCase\n{\n    protected Application $app;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->app = new Application(\n            $laravel = new \\Illuminate\\Foundation\\Application(__DIR__),\n            m::mock(Dispatcher::class, ['dispatch' => null, 'fire' => null]),\n            'testing',\n        );\n\n        $router = new Router(m::mock('Illuminate\\Events\\Dispatcher'));\n\n        $kernel = new class($laravel, $router) extends Kernel\n        {\n            protected $middlewareGroups = [\n                'web' => ['Middleware 1', 'Middleware 2', 'Middleware 5'],\n                'auth' => ['Middleware 3', 'Middleware 4'],\n            ];\n\n            protected $middlewarePriority = [\n                'Middleware 1',\n                'Middleware 4',\n                'Middleware 2',\n                'Middleware 3',\n            ];\n        };\n\n        $kernel->prependToMiddlewarePriority('Middleware 5');\n\n        $laravel->instance(Kernel::class, $kernel);\n\n        $router->get('/example', function () {\n            return 'Hello World';\n        })->middleware('exampleMiddleware');\n\n        $router->get('/sub-example', function () {\n            return 'Hello World';\n        })->domain('sub')\n            ->middleware('exampleMiddleware');\n\n        $router->get('/example-group', function () {\n            return 'Hello Group';\n        })->middleware(['web', 'auth']);\n\n        $command = new RouteListCommand($router);\n        $command->setLaravel($laravel);\n\n        $this->app->addCommands([$command]);\n    }\n\n    public function testNoMiddlewareIfNotVerbose()\n    {\n        $this->app->call('route:list');\n        $output = $this->app->output();\n\n        $this->assertStringNotContainsString('exampleMiddleware', $output);\n    }\n\n    public function testSortRouteListAsc()\n    {\n        $this->app->call('route:list', ['--json' => true, '--sort' => 'domain,uri']);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('example', $routes[0]['uri']);\n        $this->assertEquals('example-group', $routes[1]['uri']);\n        $this->assertEquals('sub-example', $routes[2]['uri']);\n\n        foreach ($routes as $route) {\n            $this->assertArrayHasKey('path', $route);\n            $this->assertStringContainsString('RouteListCommandTest.php:', $route['path']);\n        }\n    }\n\n    public function testSortRouteListDesc()\n    {\n        $this->app->call('route:list', ['--json' => true, '--sort' => 'domain,uri', '--reverse' => true]);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('sub-example', $routes[0]['uri']);\n        $this->assertEquals('example-group', $routes[1]['uri']);\n        $this->assertEquals('example', $routes[2]['uri']);\n\n        foreach ($routes as $route) {\n            $this->assertArrayHasKey('path', $route);\n            $this->assertStringContainsString('RouteListCommandTest.php:', $route['path']);\n        }\n    }\n\n    public function testSortRouteListDefault()\n    {\n        $this->app->call('route:list', ['--json' => true]);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('example', $routes[0]['uri']);\n        $this->assertEquals('example-group', $routes[1]['uri']);\n        $this->assertEquals('sub-example', $routes[2]['uri']);\n\n        foreach ($routes as $route) {\n            $this->assertArrayHasKey('path', $route);\n            $this->assertStringContainsString('RouteListCommandTest.php:', $route['path']);\n        }\n    }\n\n    public function testSortRouteListPrecedence()\n    {\n        $this->app->call('route:list', ['--json' => true, '--sort' => 'definition']);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('example', $routes[0]['uri']);\n        $this->assertEquals('sub-example', $routes[1]['uri']);\n        $this->assertEquals('example-group', $routes[2]['uri']);\n\n        foreach ($routes as $route) {\n            $this->assertArrayHasKey('path', $route);\n            $this->assertStringContainsString('RouteListCommandTest.php:', $route['path']);\n        }\n    }\n\n    public function testMiddlewareGroupsAssignmentInCli()\n    {\n        $this->app->call('route:list', ['-v' => true]);\n        $output = $this->app->output();\n\n        $this->assertStringContainsString('exampleMiddleware', $output);\n        $this->assertStringContainsString('web', $output);\n        $this->assertStringContainsString('auth', $output);\n\n        $this->assertStringNotContainsString('Middleware 1', $output);\n        $this->assertStringNotContainsString('Middleware 2', $output);\n        $this->assertStringNotContainsString('Middleware 3', $output);\n        $this->assertStringNotContainsString('Middleware 4', $output);\n        $this->assertStringNotContainsString('Middleware 5', $output);\n    }\n\n    public function testMiddlewareGroupsExpandInCliIfVeryVerbose()\n    {\n        $this->app->call('route:list', ['-vv' => true]);\n        $output = $this->app->output();\n\n        $this->assertStringContainsString('exampleMiddleware', $output);\n        $this->assertStringContainsString('Middleware 1', $output);\n        $this->assertStringContainsString('Middleware 2', $output);\n        $this->assertStringContainsString('Middleware 3', $output);\n        $this->assertStringContainsString('Middleware 4', $output);\n        $this->assertStringContainsString('Middleware 5', $output);\n\n        $this->assertStringNotContainsString('web', $output);\n        $this->assertStringNotContainsString('auth', $output);\n    }\n\n    public function testMiddlewareGroupsAssignmentInJson()\n    {\n        $this->app->call('route:list', ['--json' => true, '-v' => true]);\n        $output = $this->app->output();\n\n        $this->assertStringContainsString('exampleMiddleware', $output);\n        $this->assertStringContainsString('web', $output);\n        $this->assertStringContainsString('auth', $output);\n\n        $this->assertStringNotContainsString('Middleware 1', $output);\n        $this->assertStringNotContainsString('Middleware 2', $output);\n        $this->assertStringNotContainsString('Middleware 3', $output);\n        $this->assertStringNotContainsString('Middleware 4', $output);\n        $this->assertStringNotContainsString('Middleware 5', $output);\n    }\n\n    public function testMiddlewareGroupsExpandInJsonIfVeryVerbose()\n    {\n        $this->app->call('route:list', ['--json' => true, '-vv' => true]);\n        $output = $this->app->output();\n\n        $this->assertStringContainsString('exampleMiddleware', $output);\n        $this->assertStringContainsString('Middleware 1', $output);\n        $this->assertStringContainsString('Middleware 2', $output);\n        $this->assertStringContainsString('Middleware 3', $output);\n        $this->assertStringContainsString('Middleware 4', $output);\n        $this->assertStringContainsString('Middleware 5', $output);\n\n        $this->assertStringNotContainsString('web', $output);\n        $this->assertStringNotContainsString('auth', $output);\n    }\n\n    public function testMiddlewareGroupsExpandCorrectlySortedIfVeryVerbose()\n    {\n        $this->app->call('route:list', ['--json' => true, '-vv' => true]);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('example', $routes[0]['uri']);\n        $this->assertEquals(['exampleMiddleware'], $routes[0]['middleware']);\n        $this->assertEquals('example-group', $routes[1]['uri']);\n        $this->assertEquals(['Middleware 5', 'Middleware 1', 'Middleware 4', 'Middleware 2', 'Middleware 3'], $routes[1]['middleware']);\n        $this->assertEquals('sub-example', $routes[2]['uri']);\n        $this->assertEquals(['exampleMiddleware'], $routes[2]['middleware']);\n    }\n\n    public function testFilterByMiddleware()\n    {\n        $this->app->call('route:list', ['--json' => true, '-v' => true, '--middleware' => 'auth']);\n        $output = $this->app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(1, $routes);\n        $this->assertEquals('example-group', $routes[0]['uri']);\n        $this->assertEquals(['web', 'auth'], $routes[0]['middleware']);\n        $this->assertStringContainsString('RouteListCommandTest.php:', $routes[0]['path']);\n    }\n\n    public function testClosureRouteShowsPathInCli()\n    {\n        RouteListCommand::resolveTerminalWidthUsing(fn () => 200);\n\n        $this->app->call('route:list');\n        $output = $this->app->output();\n\n        $this->assertStringContainsString('RouteListCommandTest.php:', $output);\n\n        RouteListCommand::resolveTerminalWidthUsing(null);\n    }\n\n    public function testControllerRoutePathIsNull()\n    {\n        $laravel = new \\Illuminate\\Foundation\\Application(__DIR__);\n        $router = new Router(m::mock('Illuminate\\Events\\Dispatcher'));\n\n        $kernel = new class($laravel, $router) extends Kernel\n        {\n            protected $middlewareGroups = [];\n        };\n\n        $laravel->instance(Kernel::class, $kernel);\n\n        $router->get('/controller-route', [RouteListCommandTestController::class, 'index']);\n\n        $command = new RouteListCommand($router);\n        $command->setLaravel($laravel);\n\n        $app = new Application(\n            $laravel,\n            m::mock(Dispatcher::class, ['dispatch' => null, 'fire' => null]),\n            'testing',\n        );\n        $app->addCommands([$command]);\n        $app->call('route:list', ['--json' => true]);\n        $output = $app->output();\n\n        $routes = json_decode($output, true);\n\n        $this->assertCount(1, $routes);\n        $this->assertNull($routes[0]['path']);\n    }\n}\n\nclass RouteListCommandTestController\n{\n    public function index()\n    {\n        return 'Hello World';\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Console/ServeCommandLogParserTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Console\\ServeCommand;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ServeCommandLogParserTest extends TestCase\n{\n    public function testExtractRequestPortWithValidLogLine()\n    {\n        $line = '[Mon Nov 19 10:30:45 2024] :8080 Info';\n\n        $this->assertEquals(8080, ServeCommand::getRequestPortFromLine($line));\n    }\n\n    public function testExtractRequestPortWithValidLogLineAndExtraData()\n    {\n        $line = '[Mon Nov 19 10:30:45 2024] :3000 [Client Connected]';\n\n        $this->assertEquals(3000, ServeCommand::getRequestPortFromLine($line));\n    }\n\n    public function testExtractRequestPortWithValidLogLineWithoutDate()\n    {\n        $line = ':5000 [Server Started]';\n\n        $this->assertEquals(5000, ServeCommand::getRequestPortFromLine($line));\n    }\n\n    public function testExtractRequestPortWithMissingPort()\n    {\n        $line = '[Mon Nov 19 10:30:45 2024] Info';\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: [Mon Nov 19 10:30:45 2024] Info');\n\n        ServeCommand::getRequestPortFromLine($line);\n    }\n\n    public function testExtractRequestPortWithInvalidPortFormat()\n    {\n        $line = '[Mon Nov 19 10:30:45 2024] :abcd Info';\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: [Mon Nov 19 10:30:45 2024] :abcd Info');\n\n        ServeCommand::getRequestPortFromLine($line);\n    }\n\n    public function testExtractRequestPortWithEmptyLogLine()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: ');\n\n        ServeCommand::getRequestPortFromLine('');\n    }\n\n    public function testExtractRequestPortWithWhitespaceOnlyLine()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: ');\n\n        ServeCommand::getRequestPortFromLine('   ');\n    }\n\n    public function testExtractRequestPortWithRandomString()\n    {\n        $line = 'Random log entry without port';\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: Random log entry without port');\n\n        ServeCommand::getRequestPortFromLine($line);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Exceptions/Renderer/FrameTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Exceptions\\Renderer;\n\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Frame;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\ErrorHandler\\Exception\\FlattenException;\n\nclass FrameTest extends TestCase\n{\n    #[RequiresOperatingSystem('Linux|DAR')]\n    #[DataProvider('unixFileDataProvider')]\n    public function test_it_normalizes_file_path_on_unix($frameData, $basePath, $expected)\n    {\n        $exception = m::mock(FlattenException::class);\n        $classMap = [];\n        $frame = new Frame($exception, $classMap, $frameData, $basePath);\n\n        $this->assertEquals($expected, $frame->file());\n    }\n\n    public static function unixFileDataProvider()\n    {\n        yield 'internal function' => [\n            ['line' => 10],\n            '/path/to/your-app',\n            '[internal function]',\n        ];\n        yield 'unknown file' => [\n            ['file' => 123, 'line' => 10],\n            '/path/to/your-app',\n            '[unknown file]',\n        ];\n        yield 'file with base path' => [\n            ['file' => '/path/to/your-app/app/Http/Controllers/UserController.php', 'line' => 10],\n            '/path/to/your-app',\n            'app/Http/Controllers/UserController.php',\n        ];\n        yield 'file without base path' => [\n            ['file' => '/other/path/app/Http/Controllers/UserController.php', 'line' => 10],\n            '/path/to/your-app',\n            '/other/path/app/Http/Controllers/UserController.php',\n        ];\n    }\n\n    #[RequiresOperatingSystem('Windows')]\n    #[DataProvider('windowsFileDataProvider')]\n    public function test_it_normalizes_file_path_on_windows($frameData, $basePath, $expected)\n    {\n        $exception = m::mock(FlattenException::class);\n        $classMap = [];\n        $frame = new Frame($exception, $classMap, $frameData, $basePath);\n\n        $this->assertEquals($expected, $frame->file());\n    }\n\n    public static function windowsFileDataProvider()\n    {\n        yield 'internal function' => [\n            ['line' => 10],\n            'C:\\path\\to\\your-app',\n            '[internal function]',\n        ];\n        yield 'unknown file' => [\n            ['file' => 123, 'line' => 10],\n            'C:\\path\\to\\your-app',\n            '[unknown file]',\n        ];\n        yield 'file with base path' => [\n            ['file' => 'C:\\path\\to\\your-app\\app\\Http\\Controllers\\UserController.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            'app\\Http\\Controllers\\UserController.php',\n        ];\n        yield 'file without base path' => [\n            ['file' => 'D:\\other\\path\\app\\Http\\Controllers\\UserController.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            'D:\\other\\path\\app\\Http\\Controllers\\UserController.php',\n        ];\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    #[DataProvider('unixIsFromVendorDataProvider')]\n    public function test_it_determines_if_frame_is_from_vendor_on_unix($frameData, $basePath, $expected)\n    {\n        $exception = m::mock(FlattenException::class);\n        $classMap = [];\n        $frame = new Frame($exception, $classMap, $frameData, $basePath);\n\n        $this->assertEquals($expected, $frame->isFromVendor());\n    }\n\n    public static function unixIsFromVendorDataProvider()\n    {\n        yield 'vendor file' => [\n            ['file' => '/path/to/your-app/vendor/laravel/framework/src/File.php', 'line' => 10],\n            '/path/to/your-app',\n            true,\n        ];\n        yield 'app file' => [\n            ['file' => '/path/to/your-app/app/Models/User.php', 'line' => 10],\n            '/path/to/your-app',\n            false,\n        ];\n        yield 'outside base path' => [\n            ['file' => '/other/path/file.php', 'line' => 10],\n            '/path/to/your-app',\n            true,\n        ];\n        yield 'vendor in filename' => [\n            ['file' => '/path/to/your-app/app/vendorfile.php', 'line' => 10],\n            '/path/to/your-app',\n            false,\n        ];\n    }\n\n    #[RequiresOperatingSystem('Windows')]\n    #[DataProvider('windowsIsFromVendorDataProvider')]\n    public function test_it_determines_if_frame_is_from_vendor_on_windows($frameData, $basePath, $expected)\n    {\n        $exception = m::mock(FlattenException::class);\n        $classMap = [];\n        $frame = new Frame($exception, $classMap, $frameData, $basePath);\n\n        $this->assertEquals($expected, $frame->isFromVendor());\n    }\n\n    public static function windowsIsFromVendorDataProvider()\n    {\n        yield 'vendor file' => [\n            ['file' => 'C:\\path\\to\\your-app\\vendor\\laravel\\framework\\src\\File.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            true,\n        ];\n        yield 'app file' => [\n            ['file' => 'C:\\path\\to\\your-app\\app\\Models\\User.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            false,\n        ];\n        yield 'outside base path' => [\n            ['file' => 'D:\\other\\path\\file.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            true,\n        ];\n        yield 'vendor in filename' => [\n            ['file' => 'C:\\path\\to\\your-app\\app\\vendorfile.php', 'line' => 10],\n            'C:\\path\\to\\your-app',\n            false,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Exceptions/Renderer/ListenerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Exceptions\\Renderer;\n\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Listener;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ListenerTest extends TestCase\n{\n    public function test_queries_returns_expected_shape_after_query_executed()\n    {\n        $connection = m::mock();\n\n        $connection->shouldReceive('getName')->andReturn('testing');\n        $connection->shouldReceive('prepareBindings')->with(['foo'])->andReturn(['foo']);\n\n        $event = new QueryExecuted('select * from users where id = ?', ['foo'], 5.2, $connection);\n\n        $listener = new Listener();\n\n        $listener->onQueryExecuted($event);\n\n        $queries = $listener->queries();\n\n        $this->assertIsArray($queries);\n        $this->assertCount(1, $queries);\n\n        $query = $queries[0];\n\n        $this->assertArrayHasKey('connectionName', $query);\n        $this->assertArrayHasKey('time', $query);\n        $this->assertArrayHasKey('sql', $query);\n        $this->assertArrayHasKey('bindings', $query);\n\n        $this->assertEquals('testing', $query['connectionName']);\n        $this->assertEquals(5.2, $query['time']);\n        $this->assertEquals('select * from users where id = ?', $query['sql']);\n        $this->assertEquals(['foo'], $query['bindings']);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationAliasLoaderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Foundation\\AliasLoader;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationAliasLoaderTest extends TestCase\n{\n    public function testLoaderCanBeCreatedAndRegisteredOnce()\n    {\n        $loader = AliasLoader::getInstance(['foo' => 'bar']);\n\n        $this->assertEquals(['foo' => 'bar'], $loader->getAliases());\n        $this->assertFalse($loader->isRegistered());\n        $loader->register();\n\n        $this->assertTrue($loader->isRegistered());\n    }\n\n    public function testGetInstanceCreatesOneInstance()\n    {\n        $loader = AliasLoader::getInstance(['foo' => 'bar']);\n        $this->assertSame($loader, AliasLoader::getInstance());\n    }\n\n    public function testLoaderCanBeCreatedAndRegisteredMergingAliases()\n    {\n        $loader = AliasLoader::getInstance(['foo' => 'bar']);\n        $this->assertEquals(['foo' => 'bar'], $loader->getAliases());\n\n        $loader = AliasLoader::getInstance(['foo2' => 'bar2']);\n        $this->assertEquals(['foo2' => 'bar2', 'foo' => 'bar'], $loader->getAliases());\n\n        // override keys\n        $loader = AliasLoader::getInstance(['foo' => 'baz']);\n        $this->assertEquals(['foo2' => 'bar2', 'foo' => 'baz'], $loader->getAliases());\n    }\n\n    public function testLoaderCanAliasAndLoadClasses()\n    {\n        $loader = AliasLoader::getInstance(['some_alias_foo_bar' => FoundationAliasLoaderStub::class]);\n\n        $result = $loader->load('some_alias_foo_bar');\n\n        $this->assertInstanceOf(FoundationAliasLoaderStub::class, new \\some_alias_foo_bar);\n        $this->assertTrue($result);\n\n        $result2 = $loader->load('bar');\n        $this->assertNull($result2);\n    }\n\n    public function testSetAlias()\n    {\n        $loader = AliasLoader::getInstance();\n        $loader->setAliases(['some_alias_foo' => FoundationAliasLoaderStub::class]);\n\n        $result = $loader->load('some_alias_foo');\n\n        $fooObj = new \\some_alias_foo;\n        $this->assertInstanceOf(FoundationAliasLoaderStub::class, $fooObj);\n        $this->assertTrue($result);\n    }\n}\n\nclass FoundationAliasLoaderStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationApplicationBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Foundation\\Application;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationApplicationBuilderTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        unset($_ENV['APP_BASE_PATH']);\n\n        unset($_ENV['LARAVEL_STORAGE_PATH'], $_SERVER['LARAVEL_STORAGE_PATH']);\n\n        parent::tearDown();\n    }\n\n    public function testBaseDirectoryWithArg()\n    {\n        $_ENV['APP_BASE_PATH'] = __DIR__.'/as-env';\n\n        $app = Application::configure(__DIR__.'/as-arg')->create();\n\n        $this->assertSame(__DIR__.'/as-arg', $app->basePath());\n    }\n\n    public function testBaseDirectoryWithEnv()\n    {\n        $_ENV['APP_BASE_PATH'] = __DIR__.'/as-env';\n\n        $app = Application::configure()->create();\n\n        $this->assertSame(__DIR__.'/as-env', $app->basePath());\n    }\n\n    public function testBaseDirectoryWithComposer()\n    {\n        $app = Application::configure()->create();\n\n        $this->assertSame(dirname(__DIR__, 2), $app->basePath());\n    }\n\n    public function testStoragePathWithGlobalEnvVariable()\n    {\n        $_ENV['LARAVEL_STORAGE_PATH'] = __DIR__.'/env-storage';\n\n        $app = Application::configure()->create();\n\n        $this->assertSame(__DIR__.'/env-storage', $app->storagePath());\n    }\n\n    public function testStoragePathWithGlobalServerVariable()\n    {\n        $_SERVER['LARAVEL_STORAGE_PATH'] = __DIR__.'/server-storage';\n\n        $app = Application::configure()->create();\n\n        $this->assertSame(__DIR__.'/server-storage', $app->storagePath());\n    }\n\n    public function testStoragePathPrefersEnvVariable()\n    {\n        $_ENV['LARAVEL_STORAGE_PATH'] = __DIR__.'/env-storage';\n        $_SERVER['LARAVEL_STORAGE_PATH'] = __DIR__.'/server-storage';\n\n        $app = Application::configure()->create();\n\n        $this->assertSame(__DIR__.'/env-storage', $app->storagePath());\n    }\n\n    public function testStoragePathBasedOnBasePath()\n    {\n        $app = Application::configure()->create();\n        $this->assertSame($app->basePath().DIRECTORY_SEPARATOR.'storage', $app->storagePath());\n    }\n\n    public function testStoragePathCanBeCustomized()\n    {\n        $_ENV['LARAVEL_STORAGE_PATH'] = __DIR__.'/env-storage';\n\n        $app = Application::configure()->create();\n        $app->useStoragePath(__DIR__.'/custom-storage');\n\n        $this->assertSame(__DIR__.'/custom-storage', $app->storagePath());\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationApplicationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Contracts\\Support\\DeferrableProvider;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Bootstrap\\RegisterFacades;\nuse Illuminate\\Foundation\\Events\\LocaleUpdated;\nuse Illuminate\\Support\\ServiceProvider;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\nclass FoundationApplicationTest extends TestCase\n{\n    public function testSetLocaleSetsLocaleAndFiresLocaleChangedEvent()\n    {\n        $app = new Application;\n\n        $app['config'] = $config = m::mock(stdClass::class);\n        $config->shouldReceive('get')->once()->with('app.locale')->andReturn('bar');\n        $config->shouldReceive('set')->once()->with('app.locale', 'foo');\n        $app['translator'] = $trans = m::mock(stdClass::class);\n        $trans->shouldReceive('setLocale')->once()->with('foo');\n        $app['events'] = $events = m::mock(stdClass::class);\n        $events->shouldReceive('dispatch')->once()->with(m::on(function (LocaleUpdated $event) {\n            return $event->locale === 'foo' && $event->previousLocale === 'bar';\n        }));\n\n        $app->setLocale('foo');\n    }\n\n    public function testServiceProvidersAreCorrectlyRegistered()\n    {\n        $provider = m::mock(ApplicationBasicServiceProviderStub::class);\n        $class = get_class($provider);\n        $provider->shouldReceive('register')->once();\n        $app = new Application;\n        $app->register($provider);\n\n        $this->assertArrayHasKey($class, $app->getLoadedProviders());\n    }\n\n    public function testClassesAreBoundWhenServiceProviderIsRegistered()\n    {\n        $app = new Application;\n        $app->register($provider = new class($app) extends ServiceProvider\n        {\n            public $bindings = [\n                AbstractClass::class => ConcreteClass::class,\n            ];\n        });\n\n        $this->assertArrayHasKey(get_class($provider), $app->getLoadedProviders());\n\n        $instance = $app->make(AbstractClass::class);\n\n        $this->assertInstanceOf(ConcreteClass::class, $instance);\n        $this->assertNotSame($instance, $app->make(AbstractClass::class));\n    }\n\n    public function testSingletonsAreCreatedWhenServiceProviderIsRegistered()\n    {\n        $app = new Application;\n        $app->register($provider = new class($app) extends ServiceProvider\n        {\n            public $singletons = [\n                NonContractBackedClass::class,\n                AbstractClass::class => ConcreteClass::class,\n            ];\n        });\n\n        $this->assertArrayHasKey(get_class($provider), $app->getLoadedProviders());\n\n        $instance = $app->make(AbstractClass::class);\n\n        $this->assertInstanceOf(ConcreteClass::class, $instance);\n        $this->assertSame($instance, $app->make(AbstractClass::class));\n\n        $instance = $app->make(NonContractBackedClass::class);\n\n        $this->assertInstanceOf(NonContractBackedClass::class, $instance);\n        $this->assertSame($instance, $app->make(NonContractBackedClass::class));\n    }\n\n    public function testServiceProvidersAreCorrectlyRegisteredWhenRegisterMethodIsNotFilled()\n    {\n        $provider = m::mock(ServiceProvider::class);\n        $class = get_class($provider);\n        $provider->shouldReceive('register')->once();\n        $app = new Application;\n        $app->register($provider);\n\n        $this->assertArrayHasKey($class, $app->getLoadedProviders());\n    }\n\n    public function testServiceProvidersCouldBeLoaded()\n    {\n        $provider = m::mock(ServiceProvider::class);\n        $class = get_class($provider);\n        $provider->shouldReceive('register')->once();\n        $app = new Application;\n        $app->register($provider);\n\n        $this->assertTrue($app->providerIsLoaded($class));\n        $this->assertFalse($app->providerIsLoaded(ApplicationBasicServiceProviderStub::class));\n    }\n\n    public function testDeferredServicesMarkedAsBound()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredServiceProviderStub::class]);\n        $this->assertTrue($app->bound('foo'));\n        $this->assertSame('foo', $app->make('foo'));\n    }\n\n    public function testDeferredServicesAreSharedProperly()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredSharedServiceProviderStub::class]);\n        $this->assertTrue($app->bound('foo'));\n        $one = $app->make('foo');\n        $two = $app->make('foo');\n        $this->assertInstanceOf(stdClass::class, $one);\n        $this->assertInstanceOf(stdClass::class, $two);\n        $this->assertSame($one, $two);\n    }\n\n    public function testDeferredServicesCanBeExtended()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredServiceProviderStub::class]);\n        $app->extend('foo', function ($instance, $container) {\n            return $instance.'bar';\n        });\n        $this->assertSame('foobar', $app->make('foo'));\n    }\n\n    public function testDeferredServiceProviderIsRegisteredOnlyOnce()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredServiceProviderCountStub::class]);\n        $obj = $app->make('foo');\n        $this->assertInstanceOf(stdClass::class, $obj);\n        $this->assertSame($obj, $app->make('foo'));\n        $this->assertEquals(1, ApplicationDeferredServiceProviderCountStub::$count);\n    }\n\n    public function testDeferredServiceDontRunWhenInstanceSet()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredServiceProviderStub::class]);\n        $app->instance('foo', 'bar');\n        $instance = $app->make('foo');\n        $this->assertSame('bar', $instance);\n    }\n\n    public function testDeferredServicesAreLazilyInitialized()\n    {\n        ApplicationDeferredServiceProviderStub::$initialized = false;\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationDeferredServiceProviderStub::class]);\n        $this->assertTrue($app->bound('foo'));\n        $this->assertFalse(ApplicationDeferredServiceProviderStub::$initialized);\n        $app->extend('foo', function ($instance, $container) {\n            return $instance.'bar';\n        });\n        $this->assertFalse(ApplicationDeferredServiceProviderStub::$initialized);\n        $this->assertSame('foobar', $app->make('foo'));\n        $this->assertTrue(ApplicationDeferredServiceProviderStub::$initialized);\n    }\n\n    public function testDeferredServicesCanRegisterFactories()\n    {\n        $app = new Application;\n        $app->setDeferredServices(['foo' => ApplicationFactoryProviderStub::class]);\n        $this->assertTrue($app->bound('foo'));\n        $this->assertEquals(1, $app->make('foo'));\n        $this->assertEquals(2, $app->make('foo'));\n        $this->assertEquals(3, $app->make('foo'));\n    }\n\n    public function testSingleProviderCanProvideMultipleDeferredServices()\n    {\n        $app = new Application;\n        $app->setDeferredServices([\n            'foo' => ApplicationMultiProviderStub::class,\n            'bar' => ApplicationMultiProviderStub::class,\n        ]);\n        $this->assertSame('foo', $app->make('foo'));\n        $this->assertSame('foobar', $app->make('bar'));\n    }\n\n    public function testDeferredServiceIsLoadedWhenAccessingImplementationThroughInterface()\n    {\n        $app = new Application;\n        $app->setDeferredServices([\n            SampleInterface::class => InterfaceToImplementationDeferredServiceProvider::class,\n            SampleImplementation::class => SampleImplementationDeferredServiceProvider::class,\n        ]);\n        $instance = $app->make(SampleInterface::class);\n        $this->assertSame('foo', $instance->getPrimitive());\n    }\n\n    public function testEnvironment()\n    {\n        $app = new Application;\n        $app['env'] = 'foo';\n\n        $this->assertSame('foo', $app->environment());\n\n        $this->assertTrue($app->environment('foo'));\n        $this->assertTrue($app->environment('f*'));\n        $this->assertTrue($app->environment('foo', 'bar'));\n        $this->assertTrue($app->environment(['foo', 'bar']));\n\n        $this->assertFalse($app->environment('qux'));\n        $this->assertFalse($app->environment('q*'));\n        $this->assertFalse($app->environment('qux', 'bar'));\n        $this->assertFalse($app->environment(['qux', 'bar']));\n    }\n\n    public function testEnvironmentHelpers()\n    {\n        $local = new Application;\n        $local['env'] = 'local';\n\n        $this->assertTrue($local->isLocal());\n        $this->assertFalse($local->isProduction());\n        $this->assertFalse($local->runningUnitTests());\n\n        $production = new Application;\n        $production['env'] = 'production';\n\n        $this->assertTrue($production->isProduction());\n        $this->assertFalse($production->isLocal());\n        $this->assertFalse($production->runningUnitTests());\n\n        $testing = new Application;\n        $testing['env'] = 'testing';\n\n        $this->assertTrue($testing->runningUnitTests());\n        $this->assertFalse($testing->isLocal());\n        $this->assertFalse($testing->isProduction());\n    }\n\n    public function testDebugHelper()\n    {\n        $debugOff = new Application;\n        $debugOff['config'] = new Repository(['app' => ['debug' => false]]);\n\n        $this->assertFalse($debugOff->hasDebugModeEnabled());\n\n        $debugOn = new Application;\n        $debugOn['config'] = new Repository(['app' => ['debug' => true]]);\n\n        $this->assertTrue($debugOn->hasDebugModeEnabled());\n    }\n\n    public function testMethodAfterLoadingEnvironmentAddsClosure()\n    {\n        $app = new Application;\n        $closure = function () {\n            //\n        };\n        $app->afterLoadingEnvironment($closure);\n        $this->assertArrayHasKey(0, $app['events']->getListeners('bootstrapped: Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables'));\n    }\n\n    public function testBeforeBootstrappingAddsClosure()\n    {\n        $app = new Application;\n        $closure = function () {\n            //\n        };\n        $app->beforeBootstrapping(RegisterFacades::class, $closure);\n        $this->assertArrayHasKey(0, $app['events']->getListeners('bootstrapping: Illuminate\\Foundation\\Bootstrap\\RegisterFacades'));\n    }\n\n    public function testTerminationTests()\n    {\n        $app = new Application;\n\n        $result = [];\n        $callback1 = function () use (&$result) {\n            $result[] = 1;\n        };\n\n        $callback2 = function () use (&$result) {\n            $result[] = 2;\n        };\n\n        $callback3 = function () use (&$result) {\n            $result[] = 3;\n        };\n\n        $app->terminating($callback1);\n        $app->terminating($callback2);\n        $app->terminating($callback3);\n\n        $app->terminate();\n\n        $this->assertEquals([1, 2, 3], $result);\n    }\n\n    public function testAfterBootstrappingAddsClosure()\n    {\n        $app = new Application;\n        $closure = function () {\n            //\n        };\n        $app->afterBootstrapping(RegisterFacades::class, $closure);\n        $this->assertArrayHasKey(0, $app['events']->getListeners('bootstrapped: Illuminate\\Foundation\\Bootstrap\\RegisterFacades'));\n    }\n\n    public function testTerminationCallbacksCanAcceptAtNotation()\n    {\n        $app = new Application;\n        $app->terminating(ConcreteTerminator::class.'@terminate');\n\n        $app->terminate();\n\n        $this->assertEquals(1, ConcreteTerminator::$counter);\n    }\n\n    public function testBootingCallbacks()\n    {\n        $application = new Application;\n\n        $counter = 0;\n        $closure = function ($app) use (&$counter, $application) {\n            $counter++;\n            $this->assertSame($application, $app);\n        };\n\n        $closure2 = function ($app) use (&$counter, $application) {\n            $counter++;\n            $this->assertSame($application, $app);\n        };\n\n        $application->booting($closure);\n        $application->booting($closure2);\n\n        $application->boot();\n\n        $this->assertEquals(2, $counter);\n    }\n\n    public function testBootedCallbacks()\n    {\n        $application = new Application;\n\n        $counter = 0;\n        $closure = function ($app) use (&$counter, $application) {\n            $counter++;\n            $this->assertSame($application, $app);\n        };\n\n        $closure2 = function ($app) use (&$counter, $application) {\n            $counter++;\n            $this->assertSame($application, $app);\n        };\n\n        $closure3 = function ($app) use (&$counter, $application) {\n            $counter++;\n            $this->assertSame($application, $app);\n        };\n\n        $application->booting($closure);\n        $application->booted($closure);\n        $application->booted($closure2);\n        $application->boot();\n\n        $this->assertEquals(3, $counter);\n\n        $application->booted($closure3);\n\n        $this->assertEquals(4, $counter);\n    }\n\n    public function testGetNamespace()\n    {\n        $app1 = new Application(realpath(__DIR__.'/fixtures/laravel1'));\n        $app2 = new Application(realpath(__DIR__.'/fixtures/laravel2'));\n\n        $this->assertSame('Laravel\\\\One\\\\', $app1->getNamespace());\n        $this->assertSame('Laravel\\\\Two\\\\', $app2->getNamespace());\n    }\n\n    public function testCachePathsResolveToBootstrapCacheDirectory()\n    {\n        $app = new Application('/base/path');\n\n        $ds = DIRECTORY_SEPARATOR;\n        $this->assertSame('/base/path'.$ds.'bootstrap'.$ds.'cache/services.php', $app->getCachedServicesPath());\n        $this->assertSame('/base/path'.$ds.'bootstrap'.$ds.'cache/packages.php', $app->getCachedPackagesPath());\n        $this->assertSame('/base/path'.$ds.'bootstrap'.$ds.'cache/config.php', $app->getCachedConfigPath());\n        $this->assertSame('/base/path'.$ds.'bootstrap'.$ds.'cache/routes-v7.php', $app->getCachedRoutesPath());\n        $this->assertSame('/base/path'.$ds.'bootstrap'.$ds.'cache/events.php', $app->getCachedEventsPath());\n    }\n\n    public function testEnvPathsAreUsedForCachePathsWhenSpecified()\n    {\n        $app = new Application('/base/path');\n        $_SERVER['APP_SERVICES_CACHE'] = '/absolute/path/services.php';\n        $_SERVER['APP_PACKAGES_CACHE'] = '/absolute/path/packages.php';\n        $_SERVER['APP_CONFIG_CACHE'] = '/absolute/path/config.php';\n        $_SERVER['APP_ROUTES_CACHE'] = '/absolute/path/routes.php';\n        $_SERVER['APP_EVENTS_CACHE'] = '/absolute/path/events.php';\n\n        $this->assertSame('/absolute/path/services.php', $app->getCachedServicesPath());\n        $this->assertSame('/absolute/path/packages.php', $app->getCachedPackagesPath());\n        $this->assertSame('/absolute/path/config.php', $app->getCachedConfigPath());\n        $this->assertSame('/absolute/path/routes.php', $app->getCachedRoutesPath());\n        $this->assertSame('/absolute/path/events.php', $app->getCachedEventsPath());\n\n        unset(\n            $_SERVER['APP_SERVICES_CACHE'],\n            $_SERVER['APP_PACKAGES_CACHE'],\n            $_SERVER['APP_CONFIG_CACHE'],\n            $_SERVER['APP_ROUTES_CACHE'],\n            $_SERVER['APP_EVENTS_CACHE']\n        );\n    }\n\n    public function testEnvPathsAreUsedAndMadeAbsoluteForCachePathsWhenSpecifiedAsRelative()\n    {\n        $app = new Application('/base/path');\n        $_SERVER['APP_SERVICES_CACHE'] = 'relative/path/services.php';\n        $_SERVER['APP_PACKAGES_CACHE'] = 'relative/path/packages.php';\n        $_SERVER['APP_CONFIG_CACHE'] = 'relative/path/config.php';\n        $_SERVER['APP_ROUTES_CACHE'] = 'relative/path/routes.php';\n        $_SERVER['APP_EVENTS_CACHE'] = 'relative/path/events.php';\n\n        $ds = DIRECTORY_SEPARATOR;\n        $this->assertSame('/base/path'.$ds.'relative/path/services.php', $app->getCachedServicesPath());\n        $this->assertSame('/base/path'.$ds.'relative/path/packages.php', $app->getCachedPackagesPath());\n        $this->assertSame('/base/path'.$ds.'relative/path/config.php', $app->getCachedConfigPath());\n        $this->assertSame('/base/path'.$ds.'relative/path/routes.php', $app->getCachedRoutesPath());\n        $this->assertSame('/base/path'.$ds.'relative/path/events.php', $app->getCachedEventsPath());\n\n        unset(\n            $_SERVER['APP_SERVICES_CACHE'],\n            $_SERVER['APP_PACKAGES_CACHE'],\n            $_SERVER['APP_CONFIG_CACHE'],\n            $_SERVER['APP_ROUTES_CACHE'],\n            $_SERVER['APP_EVENTS_CACHE']\n        );\n    }\n\n    public function testEnvPathsAreUsedAndMadeAbsoluteForCachePathsWhenSpecifiedAsRelativeWithNullBasePath()\n    {\n        $app = new Application;\n        $_SERVER['APP_SERVICES_CACHE'] = 'relative/path/services.php';\n        $_SERVER['APP_PACKAGES_CACHE'] = 'relative/path/packages.php';\n        $_SERVER['APP_CONFIG_CACHE'] = 'relative/path/config.php';\n        $_SERVER['APP_ROUTES_CACHE'] = 'relative/path/routes.php';\n        $_SERVER['APP_EVENTS_CACHE'] = 'relative/path/events.php';\n\n        $ds = DIRECTORY_SEPARATOR;\n        $this->assertSame($ds.'relative/path/services.php', $app->getCachedServicesPath());\n        $this->assertSame($ds.'relative/path/packages.php', $app->getCachedPackagesPath());\n        $this->assertSame($ds.'relative/path/config.php', $app->getCachedConfigPath());\n        $this->assertSame($ds.'relative/path/routes.php', $app->getCachedRoutesPath());\n        $this->assertSame($ds.'relative/path/events.php', $app->getCachedEventsPath());\n\n        unset(\n            $_SERVER['APP_SERVICES_CACHE'],\n            $_SERVER['APP_PACKAGES_CACHE'],\n            $_SERVER['APP_CONFIG_CACHE'],\n            $_SERVER['APP_ROUTES_CACHE'],\n            $_SERVER['APP_EVENTS_CACHE']\n        );\n    }\n\n    public function testEnvPathsAreAbsoluteInWindows()\n    {\n        $app = new Application(__DIR__);\n        $app->addAbsoluteCachePathPrefix('C:');\n        $_SERVER['APP_SERVICES_CACHE'] = 'C:\\framework\\services.php';\n        $_SERVER['APP_PACKAGES_CACHE'] = 'C:\\framework\\packages.php';\n        $_SERVER['APP_CONFIG_CACHE'] = 'C:\\framework\\config.php';\n        $_SERVER['APP_ROUTES_CACHE'] = 'C:\\framework\\routes.php';\n        $_SERVER['APP_EVENTS_CACHE'] = 'C:\\framework\\events.php';\n\n        $this->assertSame('C:\\framework\\services.php', $app->getCachedServicesPath());\n        $this->assertSame('C:\\framework\\packages.php', $app->getCachedPackagesPath());\n        $this->assertSame('C:\\framework\\config.php', $app->getCachedConfigPath());\n        $this->assertSame('C:\\framework\\routes.php', $app->getCachedRoutesPath());\n        $this->assertSame('C:\\framework\\events.php', $app->getCachedEventsPath());\n\n        unset(\n            $_SERVER['APP_SERVICES_CACHE'],\n            $_SERVER['APP_PACKAGES_CACHE'],\n            $_SERVER['APP_CONFIG_CACHE'],\n            $_SERVER['APP_ROUTES_CACHE'],\n            $_SERVER['APP_EVENTS_CACHE']\n        );\n    }\n\n    public function testMacroable(): void\n    {\n        $app = new Application;\n        $app['env'] = 'foo';\n\n        $app->macro('foo', function () {\n            return $this->environment('foo');\n        });\n\n        $this->assertTrue($app->foo());\n\n        $app['env'] = 'bar';\n\n        $this->assertFalse($app->foo());\n    }\n\n    public function testUseConfigPath(): void\n    {\n        $app = new Application;\n        $app->useConfigPath(__DIR__.'/fixtures/config');\n        $app->bootstrapWith([\\Illuminate\\Foundation\\Bootstrap\\LoadConfiguration::class]);\n\n        $this->assertSame('bar', $app->make('config')->get('app.foo'));\n    }\n\n    public function testMergingConfig(): void\n    {\n        $app = new Application;\n        $app->useConfigPath(__DIR__.'/fixtures/config');\n        $app->bootstrapWith([\\Illuminate\\Foundation\\Bootstrap\\LoadConfiguration::class]);\n\n        $config = $app->make('config');\n\n        $this->assertSame('UTC', $config->get('app.timezone'));\n        $this->assertSame('bar', $config->get('app.foo'));\n\n        $this->assertSame('overwrite', $config->get('broadcasting.default'));\n        $this->assertSame('broadcasting', $config->get('broadcasting.custom_option'));\n        $this->assertIsArray($config->get('broadcasting.connections.pusher'));\n        $this->assertSame(['overwrite' => true], $config->get('broadcasting.connections.reverb'));\n        $this->assertSame(['merge' => true], $config->get('broadcasting.connections.new'));\n\n        $this->assertSame('overwrite', $config->get('cache.default'));\n        $this->assertSame('cache', $config->get('cache.custom_option'));\n        $this->assertIsArray($config->get('cache.stores.database'));\n        $this->assertSame(['overwrite' => true], $config->get('cache.stores.array'));\n        $this->assertSame(['merge' => true], $config->get('cache.stores.new'));\n\n        $this->assertSame('overwrite', $config->get('database.default'));\n        $this->assertSame('database', $config->get('database.custom_option'));\n        $this->assertIsArray($config->get('database.connections.pgsql'));\n        $this->assertSame(['overwrite' => true], $config->get('database.connections.mysql'));\n        $this->assertSame(['merge' => true], $config->get('database.connections.new'));\n\n        $this->assertSame('overwrite', $config->get('filesystems.default'));\n        $this->assertSame('filesystems', $config->get('filesystems.custom_option'));\n        $this->assertIsArray($config->get('filesystems.disks.s3'));\n        $this->assertSame(['overwrite' => true], $config->get('filesystems.disks.local'));\n        $this->assertSame(['merge' => true], $config->get('filesystems.disks.new'));\n\n        $this->assertSame('overwrite', $config->get('logging.default'));\n        $this->assertSame('logging', $config->get('logging.custom_option'));\n        $this->assertIsArray($config->get('logging.channels.single'));\n        $this->assertSame(['overwrite' => true], $config->get('logging.channels.stack'));\n        $this->assertSame(['merge' => true], $config->get('logging.channels.new'));\n\n        $this->assertSame('overwrite', $config->get('mail.default'));\n        $this->assertSame('mail', $config->get('mail.custom_option'));\n        $this->assertIsArray($config->get('mail.mailers.ses'));\n        $this->assertSame(['overwrite' => true], $config->get('mail.mailers.smtp'));\n        $this->assertSame(['merge' => true], $config->get('mail.mailers.new'));\n\n        $this->assertSame('overwrite', $config->get('queue.default'));\n        $this->assertSame('queue', $config->get('queue.custom_option'));\n        $this->assertIsArray($config->get('queue.connections.redis'));\n        $this->assertSame(['overwrite' => true], $config->get('queue.connections.database'));\n        $this->assertSame(['merge' => true], $config->get('queue.connections.new'));\n    }\n\n    public function testAbortThrowsNotFoundHttpException()\n    {\n        $this->expectException(NotFoundHttpException::class);\n        $this->expectExceptionMessage('Page was not found');\n\n        $app = new Application();\n        $app->abort(404, 'Page was not found');\n    }\n\n    public function testAbortThrowsHttpException()\n    {\n        $this->expectException(HttpException::class);\n        $this->expectExceptionMessage('Request is bad');\n\n        $app = new Application();\n        $app->abort(400, 'Request is bad');\n    }\n\n    public function testAbortAcceptsHeaders()\n    {\n        try {\n            $app = new Application();\n            $app->abort(400, 'Bad request', ['X-FOO' => 'BAR']);\n            $this->fail(sprintf('abort must throw an %s.', HttpException::class));\n        } catch (HttpException $exception) {\n            $this->assertSame(['X-FOO' => 'BAR'], $exception->getHeaders());\n        }\n    }\n\n    public function test_routes_are_cached()\n    {\n        $app = new Application();\n        $app->instance('routes.cached', true);\n        $this->assertTrue($app->routesAreCached());\n    }\n\n    public function test_routes_are_not_cached_by_instance_falls_back_to_file()\n    {\n        $app = new Application();\n        $files = new FileExistsFake;\n        $app->instance('files', $files);\n\n        $this->assertFalse($app->routesAreCached());\n        $this->assertStringContainsString('routes-v7.php', $files->pathRequested);\n    }\n\n    public function test_events_are_cached_uses_container_instance()\n    {\n        $app = new Application();\n        $app->instance('events.cached', true);\n        $files = new FileExistsFake;\n        $app->instance('files', $files);\n\n        $this->assertTrue($app->eventsAreCached());\n        $this->assertFalse(isset($files->pathRequested));\n    }\n\n    public function test_events_are_cached_checks_filesystem_if_not_set()\n    {\n        $app = new Application();\n        $files = new FileExistsFake;\n        $app->instance('files', $files);\n\n        $this->assertFalse($app->eventsAreCached());\n        $this->assertStringContainsString('events.php', $files->pathRequested);\n        $this->assertTrue($app->bound('events.cached'));\n        $this->assertFalse($app->make('events.cached'));\n    }\n\n    public function testCoreContainerAliasesAreRegisteredByDefault(): void\n    {\n        $app = new Application();\n\n        $this->assertTrue($app->isAlias(\\Illuminate\\Contracts\\Translation\\Translator::class));\n        $this->assertSame('translator', $app->getAlias(\\Illuminate\\Contracts\\Translation\\Translator::class));\n        $this->assertTrue($app->isAlias(\\Illuminate\\Contracts\\Auth\\PasswordBrokerFactory::class));\n        $this->assertSame('auth.password', $app->getAlias(\\Illuminate\\Contracts\\Auth\\PasswordBrokerFactory::class));\n        $this->assertTrue($app->isAlias(\\Illuminate\\Contracts\\Auth\\PasswordBroker::class));\n        $this->assertSame('auth.password.broker', $app->getAlias(\\Illuminate\\Contracts\\Auth\\PasswordBroker::class));\n    }\n}\n\nclass ApplicationBasicServiceProviderStub extends ServiceProvider\n{\n    public function boot()\n    {\n        //\n    }\n\n    public function register()\n    {\n        //\n    }\n}\n\nclass ApplicationDeferredSharedServiceProviderStub extends ServiceProvider implements DeferrableProvider\n{\n    public function register()\n    {\n        $this->app->singleton('foo', function () {\n            return new stdClass;\n        });\n    }\n}\n\nclass ApplicationDeferredServiceProviderCountStub extends ServiceProvider implements DeferrableProvider\n{\n    public static $count = 0;\n\n    public function register()\n    {\n        static::$count++;\n        $this->app['foo'] = new stdClass;\n    }\n}\n\nclass ApplicationDeferredServiceProviderStub extends ServiceProvider implements DeferrableProvider\n{\n    public static $initialized = false;\n\n    public function register()\n    {\n        static::$initialized = true;\n        $this->app['foo'] = 'foo';\n    }\n}\n\ninterface SampleInterface\n{\n    public function getPrimitive();\n}\n\nclass SampleImplementation implements SampleInterface\n{\n    private $primitive;\n\n    public function __construct($primitive)\n    {\n        $this->primitive = $primitive;\n    }\n\n    public function getPrimitive()\n    {\n        return $this->primitive;\n    }\n}\n\nclass InterfaceToImplementationDeferredServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    public function register()\n    {\n        $this->app->bind(SampleInterface::class, SampleImplementation::class);\n    }\n}\n\nclass SampleImplementationDeferredServiceProvider extends ServiceProvider implements DeferrableProvider\n{\n    public function register()\n    {\n        $this->app->when(SampleImplementation::class)->needs('$primitive')->give(function () {\n            return 'foo';\n        });\n    }\n}\n\nclass ApplicationFactoryProviderStub extends ServiceProvider implements DeferrableProvider\n{\n    public function register()\n    {\n        $this->app->bind('foo', function () {\n            static $count = 0;\n\n            return ++$count;\n        });\n    }\n}\n\nclass ApplicationMultiProviderStub extends ServiceProvider implements DeferrableProvider\n{\n    public function register()\n    {\n        $this->app->singleton('foo', function () {\n            return 'foo';\n        });\n        $this->app->singleton('bar', function ($app) {\n            return $app['foo'].'bar';\n        });\n    }\n}\n\nabstract class AbstractClass\n{\n    //\n}\n\nclass ConcreteClass extends AbstractClass\n{\n    //\n}\n\nclass NonContractBackedClass\n{\n    //\n}\n\nclass ConcreteTerminator\n{\n    public static $counter = 0;\n\n    public function terminate()\n    {\n        return self::$counter++;\n    }\n}\n\nclass FileExistsFake\n{\n    public string $pathRequested;\n\n    public function exists(string $path): bool\n    {\n        $this->pathRequested = $path;\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationAuthenticationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Auth\\AuthManager;\nuse Illuminate\\Contracts\\Auth\\Authenticatable;\nuse Illuminate\\Contracts\\Auth\\Guard;\nuse Illuminate\\Contracts\\Auth\\UserProvider;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithAuthentication;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationAuthenticationTest extends TestCase\n{\n    use InteractsWithAuthentication;\n\n    /**\n     * @var \\Mockery\n     */\n    protected $app;\n\n    /**\n     * @return array\n     */\n    protected $credentials = [\n        'email' => 'someone@laravel.com',\n        'password' => 'secret_password',\n    ];\n\n    /**\n     * @return \\Illuminate\\Contracts\\Auth\\Guard|\\Mockery\\LegacyMockInterface|\\Mockery\\MockInterface\n     */\n    protected function mockGuard()\n    {\n        $guard = m::mock(Guard::class);\n\n        $auth = m::mock(AuthManager::class);\n        $auth->shouldReceive('guard')\n            ->once()\n            ->andReturn($guard);\n\n        $this->app = m::mock(Application::class);\n        $this->app->shouldReceive('make')\n            ->once()\n            ->withArgs(['auth'])\n            ->andReturn($auth);\n\n        return $guard;\n    }\n\n    public function testAssertAuthenticated()\n    {\n        $this->mockGuard()\n            ->shouldReceive('check')\n            ->once()\n            ->andReturn(true);\n\n        $this->assertAuthenticated();\n    }\n\n    public function testAssertGuest()\n    {\n        $this->mockGuard()\n            ->shouldReceive('check')\n            ->once()\n            ->andReturn(false);\n\n        $this->assertGuest();\n    }\n\n    public function testAssertAuthenticatedAs()\n    {\n        $expected = m::mock(Authenticatable::class);\n        $expected->shouldReceive('getAuthIdentifier')\n            ->andReturn('1');\n\n        $this->mockGuard()\n            ->shouldReceive('user')\n            ->once()\n            ->andReturn($expected);\n\n        $user = m::mock(Authenticatable::class);\n        $user->shouldReceive('getAuthIdentifier')\n            ->andReturn('1');\n\n        $this->assertAuthenticatedAs($user);\n    }\n\n    protected function setupProvider(array $credentials)\n    {\n        $user = m::mock(Authenticatable::class);\n\n        $provider = m::mock(UserProvider::class);\n\n        $provider->shouldReceive('retrieveByCredentials')\n            ->with($credentials)\n            ->andReturn($user);\n\n        $provider->shouldReceive('validateCredentials')\n            ->with($user, $credentials)\n            ->andReturn($this->credentials === $credentials);\n\n        $this->mockGuard()\n            ->shouldReceive('getProvider')\n            ->once()\n            ->andReturn($provider);\n    }\n\n    public function testAssertCredentials()\n    {\n        $this->setupProvider($this->credentials);\n\n        $this->assertCredentials($this->credentials);\n    }\n\n    public function testAssertCredentialsMissing()\n    {\n        $credentials = [\n            'email' => 'invalid',\n            'password' => 'credentials',\n        ];\n\n        $this->setupProvider($credentials);\n\n        $this->assertInvalidCredentials($credentials);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationAuthorizesRequestsTraitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Gate;\nuse Illuminate\\Auth\\Access\\Response;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Auth\\Access\\Gate as GateContract;\nuse Illuminate\\Foundation\\Auth\\Access\\AuthorizesRequests;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationAuthorizesRequestsTraitTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testBasicGateCheck()\n    {\n        unset($_SERVER['_test.authorizes.trait']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->define('baz', function () {\n            $_SERVER['_test.authorizes.trait'] = true;\n\n            return true;\n        });\n\n        $response = (new FoundationTestAuthorizeTraitClass)->authorize('baz');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($_SERVER['_test.authorizes.trait']);\n    }\n\n    public function testAcceptsBackedEnumAsAbility()\n    {\n        unset($_SERVER['_test.authorizes.trait.enum']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->define('baz', function () {\n            $_SERVER['_test.authorizes.trait.enum'] = true;\n\n            return true;\n        });\n\n        $response = (new FoundationTestAuthorizeTraitClass)->authorize(TestAbility::BAZ);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($_SERVER['_test.authorizes.trait.enum']);\n    }\n\n    public function testExceptionIsThrownIfGateCheckFails()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('This action is unauthorized.');\n\n        $gate = $this->getBasicGate();\n\n        $gate->define('baz', function () {\n            return false;\n        });\n\n        (new FoundationTestAuthorizeTraitClass)->authorize('baz');\n    }\n\n    public function testPoliciesMayBeCalled()\n    {\n        unset($_SERVER['_test.authorizes.trait.policy']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(FoundationAuthorizesRequestTestClass::class, FoundationAuthorizesRequestTestPolicy::class);\n\n        $response = (new FoundationTestAuthorizeTraitClass)->authorize('update', new FoundationAuthorizesRequestTestClass);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($_SERVER['_test.authorizes.trait.policy']);\n    }\n\n    public function testPolicyMethodMayBeGuessedPassingModelInstance()\n    {\n        unset($_SERVER['_test.authorizes.trait.policy']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(FoundationAuthorizesRequestTestClass::class, FoundationAuthorizesRequestTestPolicy::class);\n\n        $response = (new FoundationTestAuthorizeTraitClass)->authorize(new FoundationAuthorizesRequestTestClass);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($_SERVER['_test.authorizes.trait.policy']);\n    }\n\n    public function testPolicyMethodMayBeGuessedPassingClassName()\n    {\n        unset($_SERVER['_test.authorizes.trait.policy']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy('\\\\'.FoundationAuthorizesRequestTestClass::class, FoundationAuthorizesRequestTestPolicy::class);\n\n        $response = (new FoundationTestAuthorizeTraitClass)->authorize('\\\\'.FoundationAuthorizesRequestTestClass::class);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($_SERVER['_test.authorizes.trait.policy']);\n    }\n\n    public function testPolicyMethodMayBeGuessedAndNormalized()\n    {\n        unset($_SERVER['_test.authorizes.trait.policy']);\n\n        $gate = $this->getBasicGate();\n\n        $gate->policy(FoundationAuthorizesRequestTestClass::class, FoundationAuthorizesRequestTestPolicy::class);\n\n        (new FoundationTestAuthorizeTraitClass)->store(new FoundationAuthorizesRequestTestClass);\n\n        $this->assertTrue($_SERVER['_test.authorizes.trait.policy']);\n    }\n\n    public function getBasicGate()\n    {\n        $container = Container::setInstance(new Container);\n\n        $gate = new Gate($container, function () {\n            return (object) ['id' => 1];\n        });\n\n        $container->instance(GateContract::class, $gate);\n\n        return $gate;\n    }\n}\n\nclass FoundationAuthorizesRequestTestClass\n{\n    //\n}\n\nclass FoundationAuthorizesRequestTestPolicy\n{\n    public function create()\n    {\n        $_SERVER['_test.authorizes.trait.policy'] = true;\n\n        return true;\n    }\n\n    public function update()\n    {\n        $_SERVER['_test.authorizes.trait.policy'] = true;\n\n        return true;\n    }\n\n    public function testPolicyMethodMayBeGuessedPassingModelInstance()\n    {\n        $_SERVER['_test.authorizes.trait.policy'] = true;\n\n        return true;\n    }\n\n    public function testPolicyMethodMayBeGuessedPassingClassName()\n    {\n        $_SERVER['_test.authorizes.trait.policy'] = true;\n\n        return true;\n    }\n}\n\nclass FoundationTestAuthorizeTraitClass\n{\n    use AuthorizesRequests;\n\n    public function store($object)\n    {\n        $this->authorize($object);\n    }\n}\n\nenum TestAbility: string\n{\n    case BAZ = 'baz';\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationCacheBasedMaintenanceModeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Foundation\\CacheBasedMaintenanceMode;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationCacheBasedMaintenanceModeTest extends TestCase\n{\n    public function test_it_determines_whether_maintenance_mode_is_active()\n    {\n        $cache = m::mock(Factory::class, Repository::class);\n        $cache->shouldReceive('store')->with('store-key')->andReturnSelf();\n\n        $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key');\n\n        $cache->shouldReceive('has')->once()->with('key')->andReturnFalse();\n        $this->assertFalse($manager->active());\n\n        $cache->shouldReceive('has')->once()->with('key')->andReturnTrue();\n        $this->assertTrue($manager->active());\n    }\n\n    public function test_it_retrieves_payload_from_cache()\n    {\n        $cache = m::mock(Factory::class, Repository::class);\n        $cache->shouldReceive('store')->with('store-key')->andReturnSelf();\n\n        $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key');\n\n        $cache->shouldReceive('get')->once()->with('key')->andReturn(['payload']);\n        $this->assertSame(['payload'], $manager->data());\n    }\n\n    public function test_it_stores_payload_in_cache()\n    {\n        $cache = m::spy(Factory::class, Repository::class);\n        $cache->shouldReceive('store')->with('store-key')->andReturnSelf();\n\n        $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key');\n        $manager->activate(['payload']);\n\n        $cache->shouldHaveReceived('put')->once()->with('key', ['payload']);\n    }\n\n    public function test_it_removes_payload_from_cache()\n    {\n        $cache = m::spy(Factory::class, Repository::class);\n        $cache->shouldReceive('store')->with('store-key')->andReturnSelf();\n\n        $manager = new CacheBasedMaintenanceMode($cache, 'store-key', 'key');\n        $manager->deactivate();\n\n        $cache->shouldHaveReceived('forget')->once()->with('key');\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationDocsCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Console\\DocsCommand;\nuse Illuminate\\Support\\Facades\\Http;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\n\nclass FoundationDocsCommandTest extends TestCase\n{\n    /**\n     * The URL opened by the command.\n     *\n     * @var string|null\n     */\n    protected $openedUrl;\n\n    /**\n     * The command registered to the container.\n     *\n     * @var \\Illuminate\\Foundation\\Console\\DocsCommand\n     */\n    protected $command;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Http::preventStrayRequests()->fake([\n            'https://laravel.com/docs/8.x/index.json' => Http::response(file_get_contents(__DIR__.'/fixtures/docs.json')),\n        ]);\n\n        $this->app[Kernel::class]->registerCommand($this->command());\n    }\n\n    protected function tearDown(): void\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY');\n        putenv('ARTISAN_DOCS_OPEN_STRATEGY');\n\n        parent::tearDown();\n    }\n\n    public function testItCanOpenTheLaravelDocumentation(): void\n    {\n        $this->artisan('docs')\n            ->expectsQuestion('Which page would you like to open?', '')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/installation')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/installation');\n    }\n\n    public function testItCanSpecifyAutocompleteInOriginalCasing(): void\n    {\n        $this->artisan('docs')\n            ->expectsQuestion('Which page would you like to open?', 'Laravel Dusk')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/dusk')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/dusk');\n    }\n\n    public function testItCanSpecifyAutocompleteInLowerCasing(): void\n    {\n        $this->artisan('docs')\n            ->expectsQuestion('Which page would you like to open?', 'laravel dusk')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/dusk')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/dusk');\n    }\n\n    public function testItMatchesSectionsThatStartWithInput()\n    {\n        $this->artisan('docs el-col uni')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent-collections#method-unique')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent-collections#method-unique');\n    }\n\n    public function testItMatchesSectionsWithFuzzyMatching()\n    {\n        $this->artisan('docs el-col qery')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent-collections#method-toquery')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent-collections#method-toquery');\n    }\n\n    public function testItCanProvidePageToVisit(): void\n    {\n        $this->artisan('docs eloquent\\ collections')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent-collections')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent-collections');\n    }\n\n    public function testItCanUseHyphensInsteadOfEscapingSpaces(): void\n    {\n        $this->artisan('docs eloquent-collections')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent-collections')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent-collections');\n    }\n\n    public function testItHasMinimumScoreToMatch(): void\n    {\n        $this->artisan('docs zag')\n            ->expectsOutputToContain('Unable to determine the page you are trying to visit.')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x');\n    }\n\n    public function testItMinimumScoreAccountsForInputLength(): void\n    {\n        $this->artisan('docs z')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/localization')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/localization');\n    }\n\n    public function testItCanUseCustomAskStrategy()\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/always-dusk-ask-strategy.php');\n\n        $this->artisan('docs')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/dusk')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/dusk');\n    }\n\n    public function testItFallsbackToAutocompleteWhenAskStrategyContainsBadSyntax(): void\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/bad-syntax-strategy.php');\n\n        $this->artisan('docs')\n            ->expectsQuestion('Which page would you like to open?', 'laravel dusk')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/dusk')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/dusk');\n    }\n\n    public function testItFallsbackToAutocompleteWithBadAskStrategyReturnValue(): void\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/bad-return-strategy.php');\n\n        $this->artisan('docs')\n            ->expectsQuestion('Which page would you like to open?', 'laravel dusk')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/dusk')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/dusk');\n    }\n\n    public function testItCatchesAndHandlesProcessInterruptExceptionsInAskStrategies()\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/process-interrupt-strategy.php');\n\n        $this->artisan('docs')->assertExitCode(130);\n    }\n\n    public function testItBubblesUpAskStrategyExceptions()\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/exception-throwing-strategy.php');\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('strategy failed');\n\n        $this->artisan('docs');\n    }\n\n    public function testItBubblesUpNonProcessInterruptExceptionsInAskStrategies()\n    {\n        putenv('ARTISAN_DOCS_ASK_STRATEGY='.__DIR__.'/fixtures/process-failure-strategy.php');\n\n        $this->expectException(ProcessFailedException::class);\n\n        if (PHP_OS_FAMILY === 'Windows') {\n            $this->expectExceptionMessage('The command \"expected-command\" failed.\n\nExit Code: 1(General error)\n\nWorking directory: expected-working-directory');\n        } else {\n            $this->expectExceptionMessage('The command \"\\'expected-command\\'\" failed.\n\nExit Code: 1(General error)\n\nWorking directory: expected-working-directory');\n        }\n\n        $this->artisan('docs');\n    }\n\n    public function testItCanGuessTheRequestedPageWhenItIsTheStartOfAPageTitle()\n    {\n        $this->artisan('docs elo')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent');\n    }\n\n    public function testItCanGuessTheRequestedPageWhenItIsContainedSomewhereInThePageTitle()\n    {\n        $this->artisan('docs quent')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent');\n    }\n\n    public function testItCanGuessTheWithTopAndTailMatching()\n    {\n        $this->artisan('docs elo-col')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/eloquent-collections')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/eloquent-collections');\n    }\n\n    public function testItCanSpecifyCustomOpenCommandsViaEnvVariables()\n    {\n        $GLOBALS['open-strategy-output-path'] = __DIR__.'/output.txt';\n        putenv('ARTISAN_DOCS_OPEN_STRATEGY='.__DIR__.'/fixtures/open-strategy.php');\n        $this->app[Kernel::class]->registerCommand($this->command()->setUrlOpener(null));\n\n        @unlink($GLOBALS['open-strategy-output-path']);\n\n        $this->artisan('docs installation')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/installation')\n            ->assertSuccessful();\n\n        if (PHP_OS_FAMILY === 'Windows') {\n            $this->assertSame('\"https://laravel.com/docs/8.x/installation?expected-query=1\"', trim(file_get_contents($GLOBALS['open-strategy-output-path'])));\n        } else {\n            $this->assertSame('https://laravel.com/docs/8.x/installation?expected-query=1', trim(file_get_contents($GLOBALS['open-strategy-output-path'])));\n        }\n\n        @unlink($GLOBALS['open-strategy-output-path']);\n        unset($GLOBALS['open-strategy-output-path']);\n    }\n\n    public function testItHandlesBadSyntaxInOpeners()\n    {\n        putenv('ARTISAN_DOCS_OPEN_STRATEGY='.__DIR__.'/fixtures/bad-syntax-strategy.php');\n        $this->app[Kernel::class]->registerCommand($this->command()->setUrlOpener(null));\n\n        $this->artisan('docs installation')\n            ->expectsOutputToContain('Unable to open the URL with your custom strategy. You will need to open it yourself.')\n            ->assertSuccessful();\n    }\n\n    public function testItHandlesBadReturnTypesInOpeners()\n    {\n        putenv('ARTISAN_DOCS_OPEN_STRATEGY='.__DIR__.'/fixtures/bad-return-strategy.php');\n        $this->app[Kernel::class]->registerCommand($this->command()->setUrlOpener(null));\n\n        $this->artisan('docs installation')\n            ->expectsOutputToContain('Unable to open the URL with your custom strategy. You will need to open it yourself.')\n            ->assertSuccessful();\n    }\n\n    public function testItCanPerformSearchAgainstLaravelDotCom()\n    {\n        $argCache = $_SERVER['argv'];\n        $_SERVER['argv'] = explode(' ', 'artisan docs -- here is my search term for the laravel website');\n        $this->app[Kernel::class]->registerCommand($this->command());\n\n        $this->artisan('docs -- here is my search term for the laravel website')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x?q=here%20is%20my%20search%20term%20for%20the%20laravel%20website')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x?q=here%20is%20my%20search%20term%20for%20the%20laravel%20website');\n\n        $_SERVER['argv'] = $argCache;\n    }\n\n    public function testUnknownSystemNotifiedToOpenManually()\n    {\n        $this->app[Kernel::class]->registerCommand($this->command()->setUrlOpener(null)->setSystemOsFamily('Laravel OS'));\n\n        $this->artisan('docs validation')\n            ->expectsOutputToContain('Unable to open the URL on your system. You will need to open it yourself or create a custom opener for your system.')\n            ->assertSuccessful();\n    }\n\n    public function testGuessedMatchesThatDirectlyContainTheGivenStringRankHigherThanArbitraryMatches()\n    {\n        $this->artisan('docs ora')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/filesystem')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/filesystem');\n    }\n\n    public function testItHandlesPoorSpelling()\n    {\n        $this->artisan('docs vewis')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x/views')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x/views');\n    }\n\n    public function testItHandlesNoInteractionOption()\n    {\n        $this->artisan('docs -n')\n            ->expectsOutputToContain('Opening the docs to: https://laravel.com/docs/8.x')\n            ->assertSuccessful();\n\n        $this->assertSame($this->openedUrl, 'https://laravel.com/docs/8.x');\n    }\n\n    public function testCanGetHelpWithoutInstantiatingDependencies()\n    {\n        $help = (new DocsCommand())->getHelp();\n        $this->stringContains('php artisan docs', $help);\n    }\n\n    protected function command()\n    {\n        $this->app->forgetInstance(DocsCommand::class);\n\n        return $this->app->make(DocsCommand::class)\n            ->setVersion('8.30.12')\n            ->setUrlOpener(function ($url) {\n                $this->openedUrl = $url;\n            });\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationEnvironmentDetectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Foundation\\EnvironmentDetector;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationEnvironmentDetectorTest extends TestCase\n{\n    public function testClosureCanBeUsedForCustomEnvironmentDetection()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        });\n        $this->assertSame('foobar', $result);\n    }\n\n    public function testConsoleEnvironmentDetection()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--env=local']);\n        $this->assertSame('local', $result);\n    }\n\n    public function testConsoleEnvironmentDetectionSeparatedWithSpace()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--env', 'local']);\n        $this->assertSame('local', $result);\n    }\n\n    public function testConsoleEnvironmentDetectionWithNoValue()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--env']);\n        $this->assertSame('foobar', $result);\n    }\n\n    public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnv()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--envelope=mail']);\n        $this->assertSame('foobar', $result);\n    }\n\n    public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnvSeparatedWithSpace()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--envelope', 'mail']);\n        $this->assertSame('foobar', $result);\n    }\n\n    public function testConsoleEnvironmentDetectionDoesNotUseArgumentThatStartsWithEnvWithNoValue()\n    {\n        $env = new EnvironmentDetector;\n\n        $result = $env->detect(function () {\n            return 'foobar';\n        }, ['--envelope']);\n        $this->assertSame('foobar', $result);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationExceptionsHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\NullStore;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory as ResponseFactoryContract;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Foundation\\Exceptions\\Handler;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithExceptionHandling;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Routing\\ResponseFactory;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Lottery;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Testing\\Assert;\nuse Illuminate\\Validation\\ValidationException;\nuse Illuminate\\Validation\\Validator;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse OutOfRangeException;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LogLevel;\nuse RuntimeException;\nuse stdClass;\nuse Symfony\\Component\\HttpFoundation\\Exception\\SuspiciousOperationException;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpException;\n\nclass FoundationExceptionsHandlerTest extends TestCase\n{\n    use InteractsWithExceptionHandling;\n\n    protected $config;\n\n    protected $viewFactory;\n\n    protected $container;\n\n    protected $handler;\n\n    protected $request;\n\n    protected function setUp(): void\n    {\n        $this->config = m::mock(Config::class);\n\n        $this->viewFactory = m::mock(ViewFactory::class);\n\n        $this->request = m::mock(stdClass::class);\n\n        $this->container = Container::setInstance(new Container);\n\n        $this->container->instance('config', $this->config);\n\n        $this->container->instance(ViewFactory::class, $this->viewFactory);\n\n        $this->container->instance(ResponseFactoryContract::class, new ResponseFactory(\n            $this->viewFactory,\n            m::mock(Redirector::class)\n        ));\n\n        $this->handler = new Handler($this->container);\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testHandlerReportsExceptionAsContext()\n    {\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldReceive('error')->withArgs(['Exception message', m::hasKey('exception')])->once();\n\n        $this->handler->report(new RuntimeException('Exception message'));\n    }\n\n    public function testHandlerCallsContextMethodIfPresent()\n    {\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldReceive('error')->withArgs(['Exception message', m::subset(['foo' => 'bar'])])->once();\n\n        $this->handler->report(new ContextProvidingException('Exception message'));\n    }\n\n    public function testHandlerReportsExceptionWhenUnReportable()\n    {\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldReceive('error')->withArgs(['Exception message', m::hasKey('exception')])->once();\n\n        $this->handler->report(new UnReportableException('Exception message'));\n    }\n\n    public function testHandlerReportsExceptionWithCustomLogLevel()\n    {\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n\n        $logger->shouldReceive('critical')->withArgs(['Critical message', m::hasKey('exception')])->once();\n        $logger->shouldReceive('error')->withArgs(['Error message', m::hasKey('exception')])->once();\n        $logger->shouldReceive('log')->withArgs(['custom', 'Custom message', m::hasKey('exception')])->once();\n\n        $this->handler->level(InvalidArgumentException::class, LogLevel::CRITICAL);\n        $this->handler->level(OutOfRangeException::class, 'custom');\n\n        $this->handler->report(new InvalidArgumentException('Critical message'));\n        $this->handler->report(new RuntimeException('Error message'));\n        $this->handler->report(new OutOfRangeException('Custom message'));\n    }\n\n    public function testHandlerIgnoresNotReportableExceptions()\n    {\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldNotReceive('log');\n\n        $this->handler->ignore(RuntimeException::class);\n\n        $this->handler->report(new RuntimeException('Exception message'));\n    }\n\n    public function testHandlerCallsReportMethodWithDependencies()\n    {\n        $reporter = m::mock(ReportingService::class);\n        $this->container->instance(ReportingService::class, $reporter);\n        $reporter->shouldReceive('send')->withArgs(['Exception message'])->once();\n\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldNotReceive('log');\n\n        $this->handler->report(new ReportableException('Exception message'));\n    }\n\n    public function testHandlerReportsExceptionUsingCallableClass()\n    {\n        $reporter = m::mock(ReportingService::class);\n        $reporter->shouldReceive('send')->withArgs(['Exception message'])->once();\n\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldNotReceive('log');\n\n        $this->handler->reportable(new CustomReporter($reporter));\n\n        $this->handler->report(new CustomException('Exception message'));\n    }\n\n    public function testShouldReturnJson()\n    {\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n        $e = new Exception('My custom error message');\n\n        $request = $this->request;\n\n        $shouldReturnJson = (fn () => $this->shouldReturnJson($request, $e))->call($this->handler);\n        $this->assertTrue($shouldReturnJson);\n\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(false);\n\n        $shouldReturnJson = (fn () => $this->shouldReturnJson($request, $e))->call($this->handler);\n        $this->assertFalse($shouldReturnJson);\n    }\n\n    public function testShouldReturnJsonWhen()\n    {\n        $this->request->shouldReceive('expectsJson')->never();\n        $exception = new Exception('My custom error message');\n\n        $request = $this->request;\n\n        $this->handler->shouldRenderJsonWhen(function ($r, $e) use ($request, $exception) {\n            $this->assertSame($request, $r);\n            $this->assertSame($exception, $e);\n\n            return true;\n        });\n\n        $shouldReturnJson = (fn () => $this->shouldReturnJson($request, $exception))->call($this->handler);\n        $this->assertTrue($shouldReturnJson);\n\n        $this->handler->shouldRenderJsonWhen(function ($r, $e) use ($request, $exception) {\n            $this->assertSame($request, $r);\n            $this->assertSame($exception, $e);\n\n            return false;\n        });\n\n        $shouldReturnJson = (fn () => $this->shouldReturnJson($request, $exception))->call($this->handler);\n        $this->assertFalse($shouldReturnJson);\n\n        $this->assertSame(6, Assert::getCount());\n    }\n\n    public function testReturnsJsonWithStackTraceWhenAjaxRequestAndDebugTrue()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(true);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new Exception('My custom error message'))->getContent();\n\n        $this->assertStringNotContainsString('<!DOCTYPE html>', $response);\n        $this->assertStringContainsString('\"message\": \"My custom error message\"', $response);\n        $this->assertStringContainsString('\"file\":', $response);\n        $this->assertStringContainsString('\"line\":', $response);\n        $this->assertStringContainsString('\"trace\":', $response);\n    }\n\n    public function testReturnsCustomResponseFromRenderableCallback()\n    {\n        $this->handler->renderable(function (CustomException $e, $request) {\n            $this->assertSame($this->request, $request);\n\n            return response()->json(['response' => 'My custom exception response']);\n        });\n\n        $response = $this->handler->render($this->request, new CustomException)->getContent();\n\n        $this->assertSame('{\"response\":\"My custom exception response\"}', $response);\n    }\n\n    public function testReturnsCustomResponseFromCallableClass()\n    {\n        $this->handler->renderable(new CustomRenderer);\n\n        $response = $this->handler->render($this->request, new CustomException)->getContent();\n\n        $this->assertSame('{\"response\":\"The CustomRenderer response\"}', $response);\n    }\n\n    public function testReturnsResponseFromRenderableException()\n    {\n        $response = $this->handler->render(Request::create('/'), new RenderableException)->getContent();\n\n        $this->assertSame('{\"response\":\"My renderable exception response\"}', $response);\n    }\n\n    public function testReturnsResponseFromMappedRenderableException()\n    {\n        $this->handler->map(RuntimeException::class, RenderableException::class);\n\n        $response = $this->handler->render(Request::create('/'), new RuntimeException)->getContent();\n\n        $this->assertSame('{\"response\":\"My renderable exception response\"}', $response);\n    }\n\n    public function testReturnsCustomResponseWhenExceptionImplementsResponsable()\n    {\n        $response = $this->handler->render($this->request, new ResponsableException)->getContent();\n\n        $this->assertSame('{\"response\":\"My responsable exception response\"}', $response);\n    }\n\n    public function testReturnsJsonWithoutStackTraceWhenAjaxRequestAndDebugFalseAndExceptionMessageIsMasked()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(false);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new Exception('This error message should not be visible'))->getContent();\n\n        $this->assertStringContainsString('\"message\": \"Server Error\"', $response);\n        $this->assertStringNotContainsString('<!DOCTYPE html>', $response);\n        $this->assertStringNotContainsString('This error message should not be visible', $response);\n        $this->assertStringNotContainsString('\"file\":', $response);\n        $this->assertStringNotContainsString('\"line\":', $response);\n        $this->assertStringNotContainsString('\"trace\":', $response);\n    }\n\n    public function testReturnsJsonWithoutStackTraceWhenAjaxRequestAndDebugFalseAndHttpExceptionErrorIsShown()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(false);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new HttpException(403, 'My custom error message'))->getContent();\n\n        $this->assertStringContainsString('\"message\": \"My custom error message\"', $response);\n        $this->assertStringNotContainsString('<!DOCTYPE html>', $response);\n        $this->assertStringNotContainsString('\"message\": \"Server Error\"', $response);\n        $this->assertStringNotContainsString('\"file\":', $response);\n        $this->assertStringNotContainsString('\"line\":', $response);\n        $this->assertStringNotContainsString('\"trace\":', $response);\n    }\n\n    public function testReturnsJsonWithoutStackTraceWhenAjaxRequestAndDebugFalseAndAccessDeniedHttpExceptionErrorIsShown()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(false);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new AccessDeniedHttpException('My custom error message'))->getContent();\n\n        $this->assertStringContainsString('\"message\": \"My custom error message\"', $response);\n        $this->assertStringNotContainsString('<!DOCTYPE html>', $response);\n        $this->assertStringNotContainsString('\"message\": \"Server Error\"', $response);\n        $this->assertStringNotContainsString('\"file\":', $response);\n        $this->assertStringNotContainsString('\"line\":', $response);\n        $this->assertStringNotContainsString('\"trace\":', $response);\n    }\n\n    public function testValidateFileMethod()\n    {\n        $argumentExpected = ['input' => 'My input value'];\n        $argumentActual = null;\n\n        $this->container->singleton('redirect', function () use (&$argumentActual) {\n            $redirector = m::mock(Redirector::class);\n\n            $redirector->shouldReceive('to')->once()\n                ->andReturn($responder = m::mock(RedirectResponse::class));\n\n            $responder->shouldReceive('withInput')->once()->with(m::on(\n                function ($argument) use (&$argumentActual) {\n                    $argumentActual = $argument;\n\n                    return true;\n                }))->andReturn($responder);\n\n            $responder->shouldReceive('withErrors')->once()\n                ->andReturn($responder);\n\n            return $redirector;\n        });\n\n        $file = m::mock(UploadedFile::class);\n        $file->shouldReceive('getPathname')->andReturn('photo.jpg');\n        $file->shouldReceive('getClientOriginalName')->andReturn('photo.jpg');\n        $file->shouldReceive('getClientMimeType')->andReturn('application/octet-stream');\n        $file->shouldReceive('getError')->andReturn(\\UPLOAD_ERR_NO_FILE);\n\n        $request = Request::create('/', 'POST', $argumentExpected, [], ['photo' => $file]);\n\n        $validator = m::mock(Validator::class);\n        $validator->shouldReceive('errors')->andReturn(new MessageBag(['error' => 'My custom validation exception']));\n\n        $validationException = new ValidationException($validator);\n        $validationException->redirectTo = '/';\n\n        $this->handler->render($request, $validationException);\n\n        $this->assertEquals($argumentExpected, $argumentActual);\n    }\n\n    public function testSuspiciousOperationReturns400WithoutReporting()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(true);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new SuspiciousOperationException('Invalid method override \"__CONSTRUCT\"'));\n\n        $this->assertEquals(400, $response->getStatusCode());\n        $this->assertStringContainsString('\"message\": \"Bad request.\"', $response->getContent());\n\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldNotReceive('log');\n\n        $this->handler->report(new SuspiciousOperationException('Invalid method override \"__CONSTRUCT\"'));\n    }\n\n    public function testRecordsNotFoundReturns404WithoutReporting()\n    {\n        $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(true);\n        $this->request->shouldReceive('expectsJson')->once()->andReturn(true);\n\n        $response = $this->handler->render($this->request, new RecordsNotFoundException);\n\n        $this->assertEquals(404, $response->getStatusCode());\n        $this->assertStringContainsString('\"message\": \"Not found.\"', $response->getContent());\n\n        $logger = m::mock(LoggerInterface::class);\n        $this->container->instance(LoggerInterface::class, $logger);\n        $logger->shouldNotReceive('log');\n\n        $this->handler->report(new RecordsNotFoundException);\n    }\n\n    public function testItReturnsSpecificErrorViewIfExists()\n    {\n        $viewFactory = m::mock(ViewFactory::class);\n        $viewFactory->shouldReceive('exists')->with('errors::502')->andReturn(true);\n\n        $this->container->instance(ViewFactory::class, $viewFactory);\n\n        $handler = new class($this->container) extends Handler\n        {\n            public function getErrorView($e)\n            {\n                return $this->getHttpExceptionView($e);\n            }\n        };\n\n        $this->assertSame('errors::502', $handler->getErrorView(new HttpException(502)));\n    }\n\n    public function testItReturnsFallbackErrorViewIfExists()\n    {\n        $viewFactory = m::mock(ViewFactory::class);\n        $viewFactory->shouldReceive('exists')->once()->with('errors::502')->andReturn(false);\n        $viewFactory->shouldReceive('exists')->once()->with('errors::5xx')->andReturn(true);\n\n        $this->container->instance(ViewFactory::class, $viewFactory);\n\n        $handler = new class($this->container) extends Handler\n        {\n            public function getErrorView($e)\n            {\n                return $this->getHttpExceptionView($e);\n            }\n        };\n\n        $this->assertSame('errors::5xx', $handler->getErrorView(new HttpException(502)));\n    }\n\n    public function testItReturnsNullIfNoErrorViewExists()\n    {\n        $viewFactory = m::mock(ViewFactory::class);\n        $viewFactory->shouldReceive('exists')->once()->with('errors::404')->andReturn(false);\n        $viewFactory->shouldReceive('exists')->once()->with('errors::4xx')->andReturn(false);\n\n        $this->container->instance(ViewFactory::class, $viewFactory);\n\n        $handler = new class($this->container) extends Handler\n        {\n            public function getErrorView($e)\n            {\n                return $this->getHttpExceptionView($e);\n            }\n        };\n\n        $this->assertNull($handler->getErrorView(new HttpException(404)));\n    }\n\n    private function executeScenarioWhereErrorViewThrowsWhileRenderingAndDebugIs($debug)\n    {\n        $this->viewFactory->shouldReceive('exists')->once()->with('errors::404')->andReturn(true);\n        $this->viewFactory->shouldReceive('make')->once()->withAnyArgs()->andThrow(new Exception('Rendering this view throws an exception'));\n\n        $this->config->shouldReceive('get')->with('app.debug', null)->andReturn($debug);\n\n        $handler = new class($this->container) extends Handler\n        {\n            protected function registerErrorViewPaths()\n            {\n            }\n\n            public function getErrorView($e)\n            {\n                return $this->renderHttpException($e);\n            }\n        };\n\n        $this->assertInstanceOf(SymfonyResponse::class, $handler->getErrorView(new HttpException(404)));\n    }\n\n    public function testItDoesNotCrashIfErrorViewThrowsWhileRenderingAndDebugFalse()\n    {\n        // When debug is false, the exception thrown while rendering the error view\n        // should not bubble as this may trigger an infinite loop.\n    }\n\n    public function testItDoesNotCrashIfErrorViewThrowsWhileRenderingAndDebugTrue()\n    {\n        // When debug is true, it is OK to bubble the exception thrown while rendering\n        // the error view as the debug handler should handle this gracefully.\n\n        $this->expectException(\\Exception::class);\n        $this->expectExceptionMessage('Rendering this view throws an exception');\n        $this->executeScenarioWhereErrorViewThrowsWhileRenderingAndDebugIs(true);\n    }\n\n    public function testAssertExceptionIsThrown()\n    {\n        $this->assertThrows(function () {\n            throw new Exception;\n        });\n        $this->assertThrows(function () {\n            throw new CustomException;\n        });\n        $this->assertThrows(function () {\n            throw new CustomException;\n        }, CustomException::class);\n        $this->assertThrows(function () {\n            throw new Exception('Some message.');\n        }, expectedMessage: 'Some message.');\n        $this->assertThrows(function () {\n            throw new CustomException('Some message.');\n        }, expectedMessage: 'Some message.');\n        $this->assertThrows(function () {\n            throw new CustomException('Some message.');\n        }, expectedClass: CustomException::class, expectedMessage: 'Some message.');\n\n        try {\n            $this->assertThrows(function () {\n                throw new Exception;\n            }, CustomException::class);\n            $testFailed = true;\n        } catch (AssertionFailedError) {\n            $testFailed = false;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertThrows failed: non matching exceptions are thrown.');\n        }\n\n        try {\n            $this->assertThrows(function () {\n                throw new Exception('Some message.');\n            }, expectedClass: Exception::class, expectedMessage: 'Other message.');\n            $testFailed = true;\n        } catch (AssertionFailedError) {\n            $testFailed = false;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertThrows failed: non matching message are thrown.');\n        }\n\n        $this->assertThrows(function () {\n            throw new CustomException('Some message.');\n        }, function (CustomException $exception) {\n            return $exception->getMessage() === 'Some message.';\n        });\n\n        try {\n            $this->assertThrows(function () {\n                throw new CustomException('Some message.');\n            }, function (CustomException $exception) {\n                return false;\n            });\n            $testFailed = true;\n        } catch (AssertionFailedError) {\n            $testFailed = false;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertThrows failed: exception callback succeeded.');\n        }\n\n        try {\n            $this->assertThrows(function () {\n                throw new Exception('Some message.');\n            }, function (CustomException $exception) {\n                return true;\n            });\n            $testFailed = true;\n        } catch (AssertionFailedError) {\n            $testFailed = false;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertThrows failed: non matching exceptions are thrown.');\n        }\n    }\n\n    public function testAssertNoExceptionIsThrown()\n    {\n        try {\n            $this->assertDoesntThrow(function () {\n                throw new Exception;\n            });\n\n            $testFailed = true;\n        } catch (AssertionFailedError) {\n            $testFailed = false;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertDoesntThrow failed: thrown exception was not detected.');\n        }\n\n        try {\n            $this->assertDoesntThrow(function () {\n            });\n\n            $testFailed = false;\n        } catch (AssertionFailedError) {\n            $testFailed = true;\n        }\n\n        if ($testFailed) {\n            Assert::fail('assertDoesntThrow failed: exception was detected while no exception was thrown.');\n        }\n    }\n\n    public function testItReportsDuplicateExceptions()\n    {\n        $reported = [];\n        $this->handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        $this->handler->report($one = new RuntimeException('foo'));\n        $this->handler->report($one);\n        $this->handler->report($two = new RuntimeException('foo'));\n\n        $this->assertSame($reported, [$one, $one, $two]);\n    }\n\n    public function testItCanDedupeExceptions()\n    {\n        $reported = [];\n        $e = new RuntimeException('foo');\n        $this->handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        $this->handler->dontReportDuplicates();\n        $this->handler->report($one = new RuntimeException('foo'));\n        $this->handler->report($one);\n        $this->handler->report($two = new RuntimeException('foo'));\n\n        $this->assertSame($reported, [$one, $two]);\n    }\n\n    public function testItCanSkipExceptionReportingUsingCallback()\n    {\n        $reported = [];\n        $e1 = new RuntimeException('foo');\n        $e2 = new RuntimeException('bar');\n\n        $this->handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        $this->handler->dontReportWhen(function (\\Throwable $e) {\n            return $e->getMessage() === 'foo';\n        });\n\n        $this->handler->report($e1);\n        $this->handler->report($e2);\n        $this->handler->report($e1);\n\n        $this->assertSame($reported, [$e2]);\n    }\n\n    public function testItDoesNotThrottleExceptionsByDefault()\n    {\n        $reported = [];\n        $this->handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        for ($i = 0; $i < 100; $i++) {\n            $this->handler->report(new RuntimeException(\"Exception {$i}\"));\n        }\n\n        $this->assertCount(100, $reported);\n    }\n\n    public function testItDoesNotThrottleExceptionsWhenNullReturned()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                //\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        for ($i = 0; $i < 100; $i++) {\n            $handler->report(new RuntimeException(\"Exception {$i}\"));\n        }\n\n        $this->assertCount(100, $reported);\n    }\n\n    public function testItDoesNotThrottleExceptionsWhenUnlimitedLimit()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return Limit::none();\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        for ($i = 0; $i < 100; $i++) {\n            $handler->report(new RuntimeException(\"Exception {$i}\"));\n        }\n\n        $this->assertCount(100, $reported);\n    }\n\n    public function testItCanSampleExceptionsByClass()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return match (true) {\n                    $e instanceof RuntimeException => Lottery::odds(2, 10),\n                    default => parent::throttle($e),\n                };\n            }\n        };\n        Lottery::forceResultWithSequence([\n            true, false, false, false, false,\n            true, false, false, false, false,\n        ]);\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        for ($i = 0; $i < 10; $i++) {\n            $handler->report(new Exception(\"Exception {$i}\"));\n            $handler->report(new RuntimeException(\"RuntimeException {$i}\"));\n        }\n\n        [$runtimeExceptions, $baseExceptions] = collect($reported)->partition(fn ($e) => $e instanceof RuntimeException);\n        $this->assertCount(10, $baseExceptions);\n        $this->assertCount(2, $runtimeExceptions);\n    }\n\n    public function testItRescuesExceptionsWhileThrottlingAndReports()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                throw new RuntimeException('Something went wrong in the throttle method.');\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n\n        $handler->report(new Exception('Something in the app went wrong.'));\n\n        $this->assertCount(1, $reported);\n        $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage());\n    }\n\n    public function testItRescuesExceptionsIfThereIsAnIssueResolvingTheRateLimiter()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return Limit::perDay(1);\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n        $resolved = false;\n        $this->container->bind(RateLimiter::class, function () use (&$resolved) {\n            $resolved = true;\n\n            throw new Exception('Error resolving rate limiter.');\n        });\n\n        $handler->report(new Exception('Something in the app went wrong.'));\n\n        $this->assertTrue($resolved);\n        $this->assertCount(1, $reported);\n        $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage());\n    }\n\n    public function testItRescuesExceptionsIfThereIsAnIssueWithTheRateLimiter()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return Limit::perDay(1);\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n        $this->container->instance(RateLimiter::class, $limiter = new class(new Repository(new NullStore)) extends RateLimiter\n        {\n            public $attempted = false;\n\n            public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60)\n            {\n                $this->attempted = true;\n\n                throw new Exception('Unable to connect to Redis.');\n            }\n        });\n\n        $handler->report(new Exception('Something in the app went wrong.'));\n\n        $this->assertTrue($limiter->attempted);\n        $this->assertCount(1, $reported);\n        $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage());\n    }\n\n    public function testItCanRateLimitExceptions()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return Limit::perMinute(7);\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n        $this->container->instance(RateLimiter::class, $limiter = new class(new Repository(new ArrayStore)) extends RateLimiter\n        {\n            public $attempted = 0;\n\n            public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60)\n            {\n                $this->attempted++;\n\n                return parent::attempt(...func_get_args());\n            }\n        });\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n\n        for ($i = 0; $i < 100; $i++) {\n            $handler->report(new Exception('Something in the app went wrong.'));\n        }\n\n        $this->assertSame(100, $limiter->attempted);\n        $this->assertCount(7, $reported);\n        $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage());\n\n        Carbon::setTestNow(Carbon::now()->addMinute());\n\n        for ($i = 0; $i < 100; $i++) {\n            $handler->report(new Exception('Something in the app went wrong.'));\n        }\n\n        $this->assertSame(200, $limiter->attempted);\n        $this->assertCount(14, $reported);\n        $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage());\n    }\n\n    public function testRateLimitExpiresOnBoundary()\n    {\n        $handler = new class($this->container) extends Handler\n        {\n            protected function throttle($e)\n            {\n                return Limit::perMinute(1);\n            }\n        };\n        $reported = [];\n        $handler->reportable(function (\\Throwable $e) use (&$reported) {\n            $reported[] = $e;\n\n            return false;\n        });\n        $this->container->instance(RateLimiter::class, $limiter = new class(new Repository(new ArrayStore)) extends RateLimiter\n        {\n            public $attempted = 0;\n\n            public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60)\n            {\n                $this->attempted++;\n\n                return parent::attempt(...func_get_args());\n            }\n        });\n\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n        $handler->report(new Exception('Something in the app went wrong 1.'));\n        Carbon::setTestNow('2000-01-01 00:00:59.999');\n        $handler->report(new Exception('Something in the app went wrong 1.'));\n\n        $this->assertSame(2, $limiter->attempted);\n        $this->assertCount(1, $reported);\n        $this->assertSame('Something in the app went wrong 1.', $reported[0]->getMessage());\n\n        Carbon::setTestNow('2000-01-01 00:01:00.000');\n        $handler->report(new Exception('Something in the app went wrong 2.'));\n        Carbon::setTestNow('2000-01-01 00:01:59.999');\n        $handler->report(new Exception('Something in the app went wrong 2.'));\n\n        $this->assertSame(4, $limiter->attempted);\n        $this->assertCount(2, $reported);\n        $this->assertSame('Something in the app went wrong 2.', $reported[1]->getMessage());\n    }\n}\n\nclass CustomException extends Exception\n{\n}\n\nclass ResponsableException extends Exception implements Responsable\n{\n    public function toResponse($request)\n    {\n        return response()->json(['response' => 'My responsable exception response']);\n    }\n}\n\nclass ReportableException extends Exception\n{\n    public function report(ReportingService $reportingService)\n    {\n        $reportingService->send($this->getMessage());\n    }\n}\n\nclass UnReportableException extends Exception\n{\n    public function report()\n    {\n        return false;\n    }\n}\n\nclass RenderableException extends Exception\n{\n    public function render($request)\n    {\n        return response()->json(['response' => 'My renderable exception response']);\n    }\n}\n\nclass ContextProvidingException extends Exception\n{\n    public function context()\n    {\n        return [\n            'foo' => 'bar',\n        ];\n    }\n}\n\nclass CustomReporter\n{\n    private $service;\n\n    public function __construct(ReportingService $service)\n    {\n        $this->service = $service;\n    }\n\n    public function __invoke(CustomException $e)\n    {\n        $this->service->send($e->getMessage());\n\n        return false;\n    }\n}\n\nclass CustomRenderer\n{\n    public function __invoke(CustomException $e, $request)\n    {\n        return response()->json(['response' => 'The CustomRenderer response']);\n    }\n}\n\ninterface ReportingService\n{\n    public function send($message);\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationFormRequestTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Response;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Translation\\Translator;\nuse Illuminate\\Contracts\\Validation\\Factory as ValidationFactoryContract;\nuse Illuminate\\Contracts\\Validation\\Validator;\nuse Illuminate\\Foundation\\Http\\Attributes\\ErrorBag;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Validation\\Factory as ValidationFactory;\nuse Illuminate\\Validation\\ValidationException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationFormRequestTest extends TestCase\n{\n    protected $mocks = [];\n\n    protected function tearDown(): void\n    {\n        $this->mocks = [];\n\n        parent::tearDown();\n    }\n\n    public function testValidatedMethodReturnsTheValidatedData()\n    {\n        $request = $this->createRequest(['name' => 'specified', 'with' => 'extras']);\n\n        $request->validateResolved();\n\n        $this->assertEquals(['name' => 'specified'], $request->validated());\n    }\n\n    public function testValidatedMethodReturnsTheValidatedDataNestedRules()\n    {\n        $payload = ['nested' => ['foo' => 'bar', 'baz' => ''], 'array' => [1, 2]];\n\n        $request = $this->createRequest($payload, FoundationTestFormRequestNestedStub::class);\n\n        $request->validateResolved();\n\n        $this->assertEquals(['nested' => ['foo' => 'bar'], 'array' => [1, 2]], $request->validated());\n    }\n\n    public function testValidatedMethodReturnsTheValidatedDataNestedChildRules()\n    {\n        $payload = ['nested' => ['foo' => 'bar', 'with' => 'extras']];\n\n        $request = $this->createRequest($payload, FoundationTestFormRequestNestedChildStub::class);\n\n        $request->validateResolved();\n\n        $this->assertEquals(['nested' => ['foo' => 'bar']], $request->validated());\n    }\n\n    public function testValidatedMethodReturnsTheValidatedDataNestedArrayRules()\n    {\n        $payload = ['nested' => [['bar' => 'baz', 'with' => 'extras'], ['bar' => 'baz2', 'with' => 'extras']]];\n\n        $request = $this->createRequest($payload, FoundationTestFormRequestNestedArrayStub::class);\n\n        $request->validateResolved();\n\n        $this->assertEquals(['nested' => [['bar' => 'baz'], ['bar' => 'baz2']]], $request->validated());\n    }\n\n    public function testValidatedMethodNotValidateTwice()\n    {\n        $payload = ['name' => 'specified', 'with' => 'extras'];\n\n        $request = $this->createRequest($payload, FoundationTestFormRequestTwiceStub::class);\n\n        $request->validateResolved();\n        $request->validated();\n\n        $this->assertEquals(1, FoundationTestFormRequestTwiceStub::$count);\n    }\n\n    public function testValidateThrowsWhenValidationFails()\n    {\n        $this->expectException(ValidationException::class);\n\n        $request = $this->createRequest(['no' => 'name']);\n\n        $this->mocks['redirect']->shouldReceive('withInput->withErrors');\n\n        $request->validateResolved();\n    }\n\n    public function testValidateThrowsWhenValidationFailsWithConfiguredErrorBagAttribute()\n    {\n        $request = $this->createRequest(['no' => 'name'], FoundationTestFormRequestWithErrorBagAttribute::class);\n\n        $exception = $this->catchException(ValidationException::class, function () use ($request) {\n            $request->validateResolved();\n        });\n\n        $this->assertSame('login', $exception->errorBag);\n    }\n\n    public function testValidateMethodThrowsWhenAuthorizationFails()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('This action is unauthorized.');\n\n        $this->createRequest([], FoundationTestFormRequestForbiddenStub::class)->validateResolved();\n    }\n\n    public function testValidateThrowsExceptionFromAuthorizationResponse()\n    {\n        $this->expectException(AuthorizationException::class);\n        $this->expectExceptionMessage('foo');\n\n        $this->createRequest([], FoundationTestFormRequestForbiddenWithResponseStub::class)->validateResolved();\n    }\n\n    public function testValidateDoesntThrowExceptionFromResponseAllowed()\n    {\n        $this->createRequest([], FoundationTestFormRequestPassesWithResponseStub::class)->validateResolved();\n    }\n\n    public function testPrepareForValidationRunsBeforeValidation()\n    {\n        $this->createRequest([], FoundationTestFormRequestHooks::class)->validateResolved();\n    }\n\n    public function testAfterValidationRunsAfterValidation()\n    {\n        $request = $this->createRequest([], FoundationTestFormRequestHooks::class);\n\n        $request->validateResolved();\n\n        $this->assertEquals(['name' => 'Adam'], $request->all());\n    }\n\n    public function testValidatedMethodReturnsOnlyRequestedValidatedData()\n    {\n        $request = $this->createRequest(['name' => 'specified', 'with' => 'extras']);\n\n        $request->validateResolved();\n\n        $this->assertSame('specified', $request->validated('name'));\n    }\n\n    public function testValidatedMethodReturnsOnlyRequestedNestedValidatedData()\n    {\n        $payload = ['nested' => ['foo' => 'bar', 'baz' => ''], 'array' => [1, 2]];\n\n        $request = $this->createRequest($payload, FoundationTestFormRequestNestedStub::class);\n\n        $request->validateResolved();\n\n        $this->assertSame('bar', $request->validated('nested.foo'));\n    }\n\n    public function testAfterMethod()\n    {\n        $request = new class extends FormRequest\n        {\n            public $value = 'value-from-request';\n\n            public function rules()\n            {\n                return [];\n            }\n\n            protected function failedValidation(Validator $validator)\n            {\n                throw new class($validator) extends Exception\n                {\n                    public function __construct(public $validator)\n                    {\n                        //\n                    }\n                };\n            }\n\n            public function after(InjectedDependency $dep)\n            {\n                return [\n                    new AfterValidationRule($dep->value),\n                    new InvokableAfterValidationRule($this->value),\n                    fn ($validator) => $validator->errors()->add('closure', 'true'),\n                ];\n            }\n        };\n        $request->setContainer($container = new Container);\n        $container->instance(\\Illuminate\\Contracts\\Validation\\Factory::class, (new \\Illuminate\\Validation\\Factory(\n            new \\Illuminate\\Translation\\Translator(new \\Illuminate\\Translation\\ArrayLoader(), 'en')\n        ))->setContainer($container));\n        $container->instance(InjectedDependency::class, new InjectedDependency('value-from-dependency'));\n\n        $messages = [];\n\n        try {\n            $request->validateResolved();\n            $this->fail();\n        } catch (Exception $e) {\n            if (property_exists($e, 'validator')) {\n                $messages = $e->validator->messages()->messages();\n            }\n        }\n\n        $this->assertSame([\n            'after' => ['value-from-dependency'],\n            'invokable' => ['value-from-request'],\n            'closure' => ['true'],\n        ], $messages);\n    }\n\n    public function testRequestCanPassWithoutRulesMethod()\n    {\n        $request = $this->createRequest([], FoundationTestFormRequestWithoutRulesMethod::class);\n\n        $request->validateResolved();\n\n        $this->assertEquals([], $request->all());\n    }\n\n    public function testRequestWithGetRules()\n    {\n        FoundationTestFormRequestWithGetRules::$useRuleSet = 'a';\n        $request = $this->createRequest(['a' => 1], FoundationTestFormRequestWithGetRules::class);\n\n        $request->validateResolved();\n        $this->assertEquals(['a' => 1], $request->all());\n\n        $this->expectException(ValidationException::class);\n        FoundationTestFormRequestWithGetRules::$useRuleSet = 'b';\n\n        $request = $this->createRequest(['a' => 1], FoundationTestFormRequestWithGetRules::class);\n\n        $request->validateResolved();\n    }\n\n    /**\n     * Catch the given exception thrown from the executor, and return it.\n     *\n     * @param  string  $class\n     * @param  \\Closure  $executor\n     * @return \\Exception\n     *\n     * @throws \\Exception\n     */\n    protected function catchException($class, $executor)\n    {\n        try {\n            $executor();\n        } catch (Exception $e) {\n            if (is_a($e, $class)) {\n                return $e;\n            }\n\n            throw $e;\n        }\n\n        throw new Exception(\"No exception thrown. Expected exception {$class}.\");\n    }\n\n    /**\n     * Create a new request of the given type.\n     *\n     * @param  array  $payload\n     * @param  string  $class\n     * @return \\Illuminate\\Foundation\\Http\\FormRequest\n     */\n    protected function createRequest($payload = [], $class = FoundationTestFormRequestStub::class)\n    {\n        $container = tap(new Container, function ($container) {\n            $container->instance(\n                ValidationFactoryContract::class,\n                $this->createValidationFactory($container)\n            );\n        });\n\n        $request = $class::create('/', 'GET', $payload);\n\n        return $request->setRedirector($this->createMockRedirector($request))\n            ->setContainer($container);\n    }\n\n    /**\n     * Create a new validation factory.\n     *\n     * @param  \\Illuminate\\Container\\Container  $container\n     * @return \\Illuminate\\Validation\\Factory\n     */\n    protected function createValidationFactory($container)\n    {\n        $translator = m::mock(Translator::class)->shouldReceive('get')\n            ->zeroOrMoreTimes()->andReturn('error')->getMock();\n\n        return new ValidationFactory($translator, $container);\n    }\n\n    /**\n     * Create a mock redirector.\n     *\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return \\Illuminate\\Routing\\Redirector\n     */\n    protected function createMockRedirector($request)\n    {\n        $redirector = $this->mocks['redirector'] = m::mock(Redirector::class);\n\n        $redirector->shouldReceive('getUrlGenerator')->zeroOrMoreTimes()\n            ->andReturn($generator = $this->createMockUrlGenerator());\n\n        $redirector->shouldReceive('to')->zeroOrMoreTimes()\n            ->andReturn($this->createMockRedirectResponse());\n\n        $generator->shouldReceive('previous')->zeroOrMoreTimes()\n            ->andReturn('previous');\n\n        return $redirector;\n    }\n\n    /**\n     * Create a mock URL generator.\n     *\n     * @return \\Illuminate\\Routing\\UrlGenerator\n     */\n    protected function createMockUrlGenerator()\n    {\n        return $this->mocks['generator'] = m::mock(UrlGenerator::class);\n    }\n\n    /**\n     * Create a mock redirect response.\n     *\n     * @return \\Illuminate\\Http\\RedirectResponse\n     */\n    protected function createMockRedirectResponse()\n    {\n        return $this->mocks['redirect'] = m::mock(RedirectResponse::class);\n    }\n}\n\nclass FoundationTestFormRequestStub extends FormRequest\n{\n    public function rules()\n    {\n        return ['name' => 'required'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestNestedStub extends FormRequest\n{\n    public function rules()\n    {\n        return ['nested.foo' => 'required', 'array.*' => 'integer'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestNestedChildStub extends FormRequest\n{\n    public function rules()\n    {\n        return ['nested.foo' => 'required'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestNestedArrayStub extends FormRequest\n{\n    public function rules()\n    {\n        return ['nested.*.bar' => 'required'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestTwiceStub extends FormRequest\n{\n    public static $count = 0;\n\n    public function rules()\n    {\n        return ['name' => 'required'];\n    }\n\n    public function withValidator(Validator $validator)\n    {\n        $validator->after(function ($validator) {\n            self::$count++;\n        });\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestForbiddenStub extends FormRequest\n{\n    public function authorize()\n    {\n        return false;\n    }\n}\n\nclass FoundationTestFormRequestHooks extends FormRequest\n{\n    public function rules()\n    {\n        return ['name' => 'required'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n\n    public function prepareForValidation()\n    {\n        $this->replace(['name' => 'Taylor']);\n    }\n\n    public function passedValidation()\n    {\n        $this->replace(['name' => 'Adam']);\n    }\n}\n\nclass FoundationTestFormRequestForbiddenWithResponseStub extends FormRequest\n{\n    public function authorize()\n    {\n        return Response::deny('foo');\n    }\n}\n\nclass FoundationTestFormRequestPassesWithResponseStub extends FormRequest\n{\n    public function rules()\n    {\n        return [];\n    }\n\n    public function authorize()\n    {\n        return Response::allow('baz');\n    }\n}\n\n#[ErrorBag('login')]\nclass FoundationTestFormRequestWithErrorBagAttribute extends FormRequest\n{\n    public function rules()\n    {\n        return ['name' => 'required'];\n    }\n\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass InvokableAfterValidationRule\n{\n    public function __construct(private $value)\n    {\n    }\n\n    public function __invoke($validator)\n    {\n        $validator->errors()->add('invokable', $this->value);\n    }\n}\n\nclass AfterValidationRule\n{\n    public function __construct(private $value)\n    {\n        //\n    }\n\n    public function after($validator)\n    {\n        $validator->errors()->add('after', $this->value);\n    }\n}\n\nclass InjectedDependency\n{\n    public function __construct(public $value)\n    {\n        //\n    }\n}\n\nclass FoundationTestFormRequestWithoutRulesMethod extends FormRequest\n{\n    public function authorize()\n    {\n        return true;\n    }\n}\n\nclass FoundationTestFormRequestWithGetRules extends FormRequest\n{\n    public static $useRuleSet = 'a';\n\n    protected function validationRules(): array\n    {\n        if (self::$useRuleSet === 'a') {\n            return [\n                'a' => ['required', 'int', 'min:1'],\n            ];\n        } else {\n            return [\n                'a' => ['required', 'int', 'min:2'],\n            ];\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationHelpersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Exception;\nuse Illuminate\\Broadcasting\\FakePendingBroadcast;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as CacheRepository;\nuse Illuminate\\Contracts\\Config\\Repository;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Mix;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\n\nclass FoundationHelpersTest extends TestCase\n{\n    public function testCache()\n    {\n        $app = new Application;\n        $app['cache'] = $cache = m::mock(CacheRepository::class);\n\n        // 1. cache()\n        $this->assertInstanceOf(CacheRepository::class, cache());\n\n        // 2. cache(['foo' => 'bar'], 1);\n        $cache->shouldReceive('put')->once()->with('foo', 'bar', 1);\n        cache(['foo' => 'bar'], 1);\n\n        // 3. cache('foo');\n        $cache->shouldReceive('get')->once()->with('foo', null)->andReturn('bar');\n        $this->assertSame('bar', cache('foo'));\n\n        // 4. cache('foo', null);\n        $cache->shouldReceive('get')->once()->with('foo', null)->andReturn('bar');\n        $this->assertSame('bar', cache('foo', null));\n\n        // 5. cache('baz', 'default');\n        $cache->shouldReceive('get')->once()->with('baz', 'default')->andReturn('default');\n        $this->assertSame('default', cache('baz', 'default'));\n    }\n\n    public function testEvents()\n    {\n        $app = new Application;\n        $app['events'] = $dispatcher = m::mock(Dispatcher::class);\n\n        $dispatcher->shouldReceive('dispatch')->once()->with('a', 'b', 'c')->andReturn('foo');\n        $this->assertSame('foo', event('a', 'b', 'c'));\n    }\n\n    public function testMixDoesNotIncludeHost()\n    {\n        $app = new Application;\n        $app['config'] = m::mock(Repository::class);\n        $app['config']->shouldReceive('get')->with('app.mix_url');\n        $app['config']->shouldReceive('get')->with('app.mix_hot_proxy_url');\n\n        $manifest = $this->makeManifest();\n\n        $result = mix('/unversioned.css');\n\n        $this->assertSame('/versioned.css', $result->toHtml());\n\n        unlink($manifest);\n    }\n\n    public function testMixCachesManifestForSubsequentCalls()\n    {\n        $app = new Application;\n        $app['config'] = m::mock(Repository::class);\n        $app['config']->shouldReceive('get')->with('app.mix_url');\n        $app['config']->shouldReceive('get')->with('app.mix_hot_proxy_url');\n\n        $manifest = $this->makeManifest();\n        mix('unversioned.css');\n        unlink($manifest);\n\n        $result = mix('/unversioned.css');\n\n        $this->assertSame('/versioned.css', $result->toHtml());\n    }\n\n    public function testMixAssetMissingStartingSlashHaveItAdded()\n    {\n        $app = new Application;\n        $app['config'] = m::mock(Repository::class);\n        $app['config']->shouldReceive('get')->with('app.mix_url');\n        $app['config']->shouldReceive('get')->with('app.mix_hot_proxy_url');\n\n        $manifest = $this->makeManifest();\n\n        $result = mix('unversioned.css');\n\n        $this->assertSame('/versioned.css', $result->toHtml());\n\n        unlink($manifest);\n    }\n\n    public function testMixMissingManifestThrowsException()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Mix manifest not found');\n\n        mix('unversioned.css', 'missing');\n    }\n\n    public function testMixWithManifestDirectory()\n    {\n        $app = new Application;\n        $app['config'] = m::mock(Repository::class);\n        $app['config']->shouldReceive('get')->with('app.mix_url');\n        $app['config']->shouldReceive('get')->with('app.mix_hot_proxy_url');\n\n        mkdir($directory = __DIR__.'/mix');\n        $manifest = $this->makeManifest('mix');\n\n        $result = mix('unversioned.css', 'mix');\n\n        $this->assertSame('/mix/versioned.css', $result->toHtml());\n\n        unlink($manifest);\n        rmdir($directory);\n    }\n\n    public function testMixManifestDirectoryMissingStartingSlashHasItAdded()\n    {\n        mkdir($directory = __DIR__.'/mix');\n        $manifest = $this->makeManifest('/mix');\n\n        $result = mix('unversioned.css', 'mix');\n\n        $this->assertSame('/mix/versioned.css', $result->toHtml());\n\n        unlink($manifest);\n        rmdir($directory);\n    }\n\n    public function testMixHotModuleReloadingGetsUrlFromFileWithHttps()\n    {\n        $path = $this->makeHotModuleReloadFile('https://laravel.com/docs');\n\n        $result = mix('unversioned.css');\n\n        $this->assertSame('//laravel.com/docs/unversioned.css', $result->toHtml());\n\n        unlink($path);\n    }\n\n    public function testMixHotModuleReloadingGetsUrlFromFileWithHttp()\n    {\n        $path = $this->makeHotModuleReloadFile('http://laravel.com/docs');\n\n        $result = mix('unversioned.css');\n\n        $this->assertSame('//laravel.com/docs/unversioned.css', $result->toHtml());\n\n        unlink($path);\n    }\n\n    public function testMixHotModuleReloadingGetsUrlFromFileWithManifestDirectoryAndHttps()\n    {\n        mkdir($directory = __DIR__.'/mix');\n        $path = $this->makeHotModuleReloadFile('https://laravel.com/docs', 'mix');\n\n        $result = mix('unversioned.css', 'mix');\n\n        $this->assertSame('//laravel.com/docs/unversioned.css', $result->toHtml());\n\n        unlink($path);\n        rmdir($directory);\n    }\n\n    public function testMixHotModuleReloadingGetsUrlFromFileWithManifestDirectoryAndHttp()\n    {\n        mkdir($directory = __DIR__.'/mix');\n        $path = $this->makeHotModuleReloadFile('http://laravel.com/docs', 'mix');\n\n        $result = mix('unversioned.css', 'mix');\n\n        $this->assertSame('//laravel.com/docs/unversioned.css', $result->toHtml());\n\n        unlink($path);\n        rmdir($directory);\n    }\n\n    public function testMixHotModuleReloadingUsesLocalhostIfNoHttpScheme()\n    {\n        $path = $this->makeHotModuleReloadFile('');\n\n        $result = mix('unversioned.css');\n\n        $this->assertSame('//localhost:8080/unversioned.css', $result->toHtml());\n\n        unlink($path);\n    }\n\n    public function testMixHotModuleReloadingWithManifestDirectoryUsesLocalhostIfNoHttpScheme()\n    {\n        mkdir($directory = __DIR__.'/mix');\n        $path = $this->makeHotModuleReloadFile('', 'mix');\n\n        $result = mix('unversioned.css', 'mix');\n\n        $this->assertSame('//localhost:8080/unversioned.css', $result->toHtml());\n\n        unlink($path);\n        rmdir($directory);\n    }\n\n    protected function makeHotModuleReloadFile($url, $directory = '')\n    {\n        app()->usePublicPath(__DIR__);\n\n        $path = public_path(Str::finish($directory, '/').'hot');\n\n        // Laravel mix when run 'hot' has a new line after the\n        // url, so for consistency this \"\\n\" is added.\n        file_put_contents($path, \"{$url}\\n\");\n\n        return $path;\n    }\n\n    protected function makeManifest($directory = '')\n    {\n        app()->usePublicPath(__DIR__);\n\n        $path = public_path(Str::finish($directory, '/').'mix-manifest.json');\n\n        touch($path);\n\n        // Laravel mix prints JSON pretty and with escaped\n        // slashes, so we are doing that here for consistency.\n        $content = json_encode(['/unversioned.css' => '/versioned.css'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);\n\n        file_put_contents($path, $content);\n\n        return $path;\n    }\n\n    public function testMixIsSwappableForTests()\n    {\n        (new Application)->instance(Mix::class, function () {\n            return 'expected';\n        });\n\n        $this->assertSame('expected', mix('asset.png'));\n    }\n\n    public function testAbortReceivesCodeAsSymfonyResponseInstance()\n    {\n        try {\n            abort($code = new SymfonyResponse());\n\n            $this->fail(\n                sprintf('abort function must throw %s when receiving code as Symfony Response instance.', HttpResponseException::class)\n            );\n        } catch (HttpResponseException $ex) {\n            $this->assertSame($code, $ex->getResponse());\n        }\n    }\n\n    public function testAbortReceivesCodeAsResponableImplementation()\n    {\n        app()->instance('request', $request = Request::create('/'));\n\n        try {\n            abort($code = new class implements Responsable\n            {\n                public $request;\n\n                public function toResponse($request)\n                {\n                    $this->request = $request;\n\n                    return new SymfonyResponse();\n                }\n            });\n\n            $this->fail(\n                sprintf('abort function must throw %s when receiving code as Responable implementation.', HttpResponseException::class)\n            );\n        } catch (HttpResponseException) {\n            $this->assertSame($request, $code->request);\n        }\n    }\n\n    public function testAbortReceivesCodeAsInteger()\n    {\n        $app = m::mock(Application::class);\n        $app->shouldReceive('abort')\n            ->with($code = 400, $message = 'Bad request', $headers = ['X-FOO' => 'BAR'])\n            ->once();\n\n        Container::setInstance($app);\n\n        abort($code, $message, $headers);\n    }\n\n    public function testBroadcastIfReturnsFakeOnFalse()\n    {\n        $this->assertInstanceOf(FakePendingBroadcast::class, broadcast_if(false, 'foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationInteractsWithDatabaseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithDatabase;\nuse Illuminate\\Foundation\\Testing\\TestCase as TestingTestCase;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\DB;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Concerns\\CreatesApplication;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationInteractsWithDatabaseTest extends TestCase\n{\n    use InteractsWithDatabase;\n\n    protected $table = 'products';\n\n    protected $data = [\n        'title' => 'Spark',\n        'name' => 'Laravel',\n    ];\n\n    protected $connection;\n\n    protected function setUp(): void\n    {\n        $this->connection = m::mock(Connection::class);\n    }\n\n    public function testSeeInDatabaseFindsResults()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseHas($this->table, $this->data);\n    }\n\n    public function testAssertDatabaseHasSupportsModelClass()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseHas(ProductStub::class, $this->data);\n    }\n\n    public function testAssertDatabaseHasConstrainsToModel()\n    {\n        $data = $this->data;\n\n        $this->data = [\n            'id' => 1,\n            ...$this->data,\n        ];\n\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseHas(new ProductStub(['id' => 1]), $data);\n    }\n\n    public function testSeeInDatabaseDoesNotFindResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertDatabaseHas($this->table, $this->data);\n    }\n\n    public function testSeeInDatabaseFindsNotMatchingResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->expectExceptionMessage('Found similar results: '.json_encode([['title' => 'Forge']], JSON_PRETTY_PRINT));\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('limit')->andReturnSelf();\n        $builder->shouldReceive('get')->andReturn(collect([['title' => 'Forge']]));\n\n        $this->assertDatabaseHas($this->table, $this->data);\n    }\n\n    public function testSeeInDatabaseFindsManyNotMatchingResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->expectExceptionMessage('Found similar results: '.json_encode(['data', 'data', 'data'], JSON_PRETTY_PRINT).' and 2 others.');\n\n        $builder = $this->mockCountBuilder(false, countResult: [5, 5]);\n\n        $builder->shouldReceive('limit')->andReturnSelf();\n        $builder->shouldReceive('get')->andReturn(\n            collect(array_fill(0, 3, 'data'))\n        );\n\n        $this->assertDatabaseHas($this->table, $this->data);\n    }\n\n    public function testDontSeeInDatabaseDoesNotFindResults()\n    {\n        $this->mockCountBuilder(false);\n\n        $this->assertDatabaseMissing($this->table, $this->data);\n    }\n\n    public function testAssertDatabaseMissingSupportsModelClass()\n    {\n        $this->mockCountBuilder(false);\n\n        $this->assertDatabaseMissing(ProductStub::class, $this->data);\n    }\n\n    public function testAssertDatabaseMissingConstrainsToModel()\n    {\n        $data = $this->data;\n\n        $this->data = [\n            'id' => 1,\n            ...$this->data,\n        ];\n\n        $this->mockCountBuilder(false);\n\n        $this->assertDatabaseMissing(new ProductStub(['id' => 1]), $data);\n    }\n\n    public function testDontSeeInDatabaseFindsResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $builder = $this->mockCountBuilder(true);\n\n        $builder->shouldReceive('limit')->andReturnSelf();\n        $builder->shouldReceive('get')->andReturn(collect([$this->data]));\n\n        $this->assertDatabaseMissing($this->table, $this->data);\n    }\n\n    public function testAssertTableEntriesCount()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseCount($this->table, 1);\n    }\n\n    public function testAssertDatabaseCountSupportModels()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseCount(ProductStub::class, 1);\n        $this->assertDatabaseCount(new ProductStub, 1);\n    }\n\n    public function testAssertDatabaseEmpty()\n    {\n        $this->mockCountBuilder(false);\n\n        $this->assertDatabaseEmpty(ProductStub::class);\n        $this->assertDatabaseEmpty(new ProductStub);\n    }\n\n    public function testAssertTableEntriesCountWrong()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('Failed asserting that table [products] matches expected entries count of 3. Entries found: 1.');\n        $this->mockCountBuilder(true);\n\n        $this->assertDatabaseCount($this->table, 3);\n    }\n\n    public function testAssertDatabaseMissingPassesWhenDoesNotFindResults()\n    {\n        $this->mockCountBuilder(false);\n\n        $this->assertDatabaseMissing($this->table, $this->data);\n    }\n\n    public function testAssertDatabaseMissingFailsWhenFindsResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $builder = $this->mockCountBuilder(true);\n\n        $builder->shouldReceive('get')->andReturn(collect([$this->data]));\n\n        $this->assertDatabaseMissing($this->table, $this->data);\n    }\n\n    public function testAssertModelMissingPassesWhenDoesNotFindModelResults()\n    {\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertModelMissing(new ProductStub($this->data));\n    }\n\n    public function testAssertSoftDeletedInDatabaseFindsResults()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertSoftDeleted($this->table, $this->data);\n    }\n\n    public function testAssertSoftDeletedSupportModelStrings()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertSoftDeleted(ProductStub::class, $this->data);\n    }\n\n    public function testAssertSoftDeletedInDatabaseDoesNotFindResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertSoftDeleted($this->table, $this->data);\n    }\n\n    public function testAssertSoftDeletedInDatabaseDoesNotFindModelResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertSoftDeleted(new ProductStub($this->data));\n    }\n\n    public function testAssertSoftDeletedInDatabaseDoesNotFindModelWithCustomColumnResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $model = new CustomProductStub(['id' => 1, 'name' => 'Laravel']);\n        $this->data = ['id' => 1, 'name' => 'Tailwind'];\n\n        $builder = $this->mockCountBuilder(false, 'trashed_at');\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertSoftDeleted($model, ['name' => 'Tailwind']);\n    }\n\n    public function testAssertSoftDeletedInDatabaseDoesNotFindModePassedViaFcnWithCustomColumnResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $model = new CustomProductStub(['id' => 1, 'name' => 'Laravel']);\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(false, 'trashed_at');\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertSoftDeleted(CustomProductStub::class, ['id' => $model->id]);\n    }\n\n    public function testAssertNotSoftDeletedInDatabaseFindsResults()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertNotSoftDeleted($this->table, $this->data);\n    }\n\n    public function testAssertNotSoftDeletedSupportModelStrings()\n    {\n        $this->mockCountBuilder(true);\n\n        $this->assertNotSoftDeleted(ProductStub::class, $this->data);\n    }\n\n    public function testAssertNotSoftDeletedOnlyFindsMatchingModels()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('Failed asserting that any existing row');\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect(), collect(1));\n\n        $this->assertNotSoftDeleted(ProductStub::class, $this->data);\n    }\n\n    public function testAssertNotSoftDeletedInDatabaseDoesNotFindResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertNotSoftDeleted($this->table, $this->data);\n    }\n\n    public function testAssertNotSoftDeletedInDatabaseDoesNotFindModelResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(false);\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertNotSoftDeleted(new ProductStub($this->data));\n    }\n\n    public function testAssertNotSoftDeletedInDatabaseDoesNotFindModelWithCustomColumnResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $model = new CustomProductStub(['id' => 1, 'name' => 'Laravel']);\n        $this->data = ['id' => 1, 'name' => 'Tailwind'];\n\n        $builder = $this->mockCountBuilder(false, 'trashed_at');\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertNotSoftDeleted($model, ['name' => 'Tailwind']);\n    }\n\n    public function testAssertNotSoftDeletedInDatabaseDoesNotFindModelPassedViaFcnWithCustomColumnResults()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The table is empty.');\n\n        $model = new CustomProductStub(['id' => 1, 'name' => 'Laravel']);\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(false, 'trashed_at');\n\n        $builder->shouldReceive('get')->andReturn(collect());\n\n        $this->assertNotSoftDeleted(CustomProductStub::class, ['id' => $model->id]);\n    }\n\n    public function testAssertExistsPassesWhenFindsResults()\n    {\n        $this->data = ['id' => 1];\n\n        $builder = $this->mockCountBuilder(true);\n\n        $builder->shouldReceive('get')->andReturn(collect($this->data));\n\n        $this->assertModelExists(new ProductStub($this->data));\n    }\n\n    public function testGetTableNameFromModel()\n    {\n        $this->assertEquals($this->table, $this->getTable(ProductStub::class));\n        $this->assertEquals($this->table, $this->getTable(new ProductStub));\n        $this->assertEquals($this->table, $this->getTable($this->table));\n        $this->assertEquals('all_products', $this->getTable((new ProductStub)->setTable('all_products')));\n    }\n\n    public function testGetTableConnectionNameFromModel()\n    {\n        $this->assertSame(null, $this->getTableConnection(ProductStub::class));\n        $this->assertSame(null, $this->getTableConnection(new ProductStub));\n        $this->assertSame('mysql', $this->getTableConnection((new ProductStub)->setConnection('mysql')));\n    }\n\n    public function testGetTableCustomizedDeletedAtColumnName()\n    {\n        $this->assertEquals('trashed_at', $this->getDeletedAtColumn(CustomProductStub::class));\n        $this->assertEquals('trashed_at', $this->getDeletedAtColumn(new CustomProductStub()));\n    }\n\n    public function testExpectsDatabaseQueryCount()\n    {\n        $case = new class('foo') extends TestingTestCase\n        {\n            use CreatesApplication;\n\n            public function testExpectsDatabaseQueryCount()\n            {\n                $this->expectsDatabaseQueryCount(0);\n            }\n        };\n\n        $case->setUp();\n        $case->testExpectsDatabaseQueryCount();\n        $case->tearDown();\n\n        $case = new class('foo') extends TestingTestCase\n        {\n            use CreatesApplication;\n\n            public function testExpectsDatabaseQueryCount()\n            {\n                $this->expectsDatabaseQueryCount(3);\n            }\n        };\n\n        $case->setUp();\n        $case->testExpectsDatabaseQueryCount();\n\n        try {\n            $case->tearDown();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertSame(\"Expected 3 database queries on the [testing] connection. 0 occurred.\\nFailed asserting that 0 is identical to 3.\", $e->getMessage());\n        }\n\n        $case = new class('foo') extends TestingTestCase\n        {\n            use CreatesApplication;\n\n            public function testExpectsDatabaseQueryCount()\n            {\n                $this->expectsDatabaseQueryCount(3);\n\n                DB::pretend(function ($db) {\n                    $db->table('foo')->count();\n                    $db->table('foo')->count();\n                    $db->table('foo')->count();\n                    $db->table('foo')->count();\n                });\n            }\n        };\n\n        $case->setUp();\n        $case->testExpectsDatabaseQueryCount();\n\n        try {\n            $case->tearDown();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertSame(\"Expected 3 database queries on the [testing] connection. 4 occurred.\\nFailed asserting that 4 is identical to 3.\", $e->getMessage());\n        }\n\n        $case = new class('foo') extends TestingTestCase\n        {\n            use CreatesApplication;\n\n            public function testExpectsDatabaseQueryCount()\n            {\n                $this->expectsDatabaseQueryCount(4);\n                $this->expectsDatabaseQueryCount(1, 'mysql');\n\n                DB::pretend(function ($db) {\n                    $db->table('foo')->count();\n                    $db->table('foo')->count();\n                    $db->table('foo')->count();\n                });\n\n                DB::connection('mysql')->pretend(function ($db) {\n                    $db->table('foo')->count();\n                });\n            }\n        };\n\n        $case->setUp();\n        $case->testExpectsDatabaseQueryCount();\n        $case->tearDown();\n    }\n\n    protected function mockCountBuilder($existsResult, $deletedAtColumn = 'deleted_at', $countResult = null)\n    {\n        $builder = m::mock(Builder::class);\n\n        $countResult = Arr::wrap($countResult);\n        $countResult = ! empty($countResult) ? $countResult : [$existsResult ? 1 : 0];\n\n        $key = array_key_first($this->data);\n        $value = $this->data[$key];\n\n        $builder->shouldReceive('where')->with($key, $value)->andReturnSelf();\n\n        $builder->shouldReceive('select')->with(array_keys($this->data))->andReturnSelf();\n\n        $builder->shouldReceive('limit')->andReturnSelf();\n\n        $builder->shouldReceive('where')->with($this->data)->andReturnSelf();\n\n        $builder->shouldReceive('whereNotNull')->with($deletedAtColumn)->andReturnSelf();\n\n        $builder->shouldReceive('whereNull')->with($deletedAtColumn)->andReturnSelf();\n\n        $builder->shouldReceive('exists')->andReturn($existsResult)->byDefault();\n\n        $builder->shouldReceive('count')->andReturn(...$countResult)->byDefault();\n\n        $this->connection->shouldReceive('table')\n            ->with($this->table)\n            ->andReturn($builder);\n\n        return $builder;\n    }\n\n    protected function getConnection()\n    {\n        return $this->connection;\n    }\n}\n\nclass ProductStub extends Model\n{\n    use SoftDeletes;\n\n    protected $table = 'products';\n\n    protected $guarded = [];\n}\n\nclass CustomProductStub extends ProductStub\n{\n    const DELETED_AT = 'trashed_at';\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationInteractsWithTimeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithTime;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationInteractsWithTimeTest extends TestCase\n{\n    use InteractsWithTime;\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    public function testFreezeTimeReturnsFrozenTime()\n    {\n        $actual = $this->freezeTime();\n\n        $this->assertTrue(Carbon::hasTestNow());\n        $this->assertInstanceOf(\\DateTimeInterface::class, $actual);\n        $this->assertTrue(Carbon::getTestNow()->eq($actual));\n    }\n\n    public function testFreezeTimeReturnsCallbackResult()\n    {\n        $actual = $this->freezeTime(function () {\n            return 12345;\n        });\n\n        $this->assertSame(12345, $actual);\n        $this->assertFalse(Carbon::hasTestNow());\n    }\n\n    public function testFreezeTimeReturnsCallbackResultEvenWhenNull()\n    {\n        $actual = $this->freezeTime(function () {\n            return null;\n        });\n\n        $this->assertNull($actual);\n        $this->assertFalse(Carbon::hasTestNow());\n    }\n\n    public function testFreezeSecondReturnsFrozenTime()\n    {\n        $actual = $this->freezeSecond();\n\n        $this->assertTrue(Carbon::hasTestNow());\n        $this->assertInstanceOf(\\DateTimeInterface::class, $actual);\n        $this->assertTrue(Carbon::getTestNow()->eq($actual));\n        $this->assertSame(0, $actual->milliseconds);\n    }\n\n    public function testFreezeSecondReturnsCallbackResult()\n    {\n        $actual = $this->freezeSecond(function () {\n            return 12345;\n        });\n\n        $this->assertSame(12345, $actual);\n        $this->assertFalse(Carbon::hasTestNow());\n    }\n\n    public function testFreezeSecondReturnsCallbackResultEvenWhenNull()\n    {\n        $actual = $this->freezeSecond(function () {\n            return null;\n        });\n\n        $this->assertNull($actual);\n        $this->assertFalse(Carbon::hasTestNow());\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationPackageManifestTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\PackageManifest;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FoundationPackageManifestTest extends TestCase\n{\n    public function testAssetLoading()\n    {\n        @unlink(__DIR__.'/fixtures/packages.php');\n        $manifest = new PackageManifest(new Filesystem, __DIR__.'/fixtures', __DIR__.'/fixtures/packages.php');\n        $this->assertEquals(['foo', 'bar', 'baz'], $manifest->providers());\n        $this->assertEquals(['Foo' => 'Foo\\\\Facade'], $manifest->aliases());\n        unlink(__DIR__.'/fixtures/packages.php');\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationProviderRepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Exception;\nuse Illuminate\\Contracts\\Foundation\\Application as ApplicationContract;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\ProviderRepository;\nuse Illuminate\\Support\\ServiceProvider;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass FoundationProviderRepositoryTest extends TestCase\n{\n    public function testServicesAreRegisteredWhenManifestIsNotRecompiled()\n    {\n        $app = m::mock(Application::class);\n\n        $repo = m::mock(ProviderRepository::class.'[createProvider,loadManifest,shouldRecompile]', [$app, m::mock(Filesystem::class), [__DIR__.'/services.php']]);\n        $repo->shouldReceive('loadManifest')->once()->andReturn(['eager' => ['foo'], 'deferred' => ['deferred'], 'providers' => ['providers'], 'when' => []]);\n        $repo->shouldReceive('shouldRecompile')->once()->andReturn(false);\n\n        $app->shouldReceive('register')->once()->with('foo');\n        $app->shouldReceive('runningInConsole')->andReturn(false);\n        $app->shouldReceive('addDeferredServices')->once()->with(['deferred']);\n\n        $repo->load([]);\n    }\n\n    public function testManifestIsProperlyRecompiled()\n    {\n        $app = m::mock(Application::class);\n\n        $repo = m::mock(ProviderRepository::class.'[createProvider,loadManifest,writeManifest,shouldRecompile]', [$app, m::mock(Filesystem::class), [__DIR__.'/services.php']]);\n\n        $repo->shouldReceive('loadManifest')->once()->andReturn(['eager' => [], 'deferred' => ['deferred']]);\n        $repo->shouldReceive('shouldRecompile')->once()->andReturn(true);\n\n        // foo mock is just a deferred provider\n        $repo->shouldReceive('createProvider')->once()->with('foo')->andReturn($fooMock = m::mock(stdClass::class));\n        $fooMock->shouldReceive('isDeferred')->once()->andReturn(true);\n        $fooMock->shouldReceive('provides')->once()->andReturn(['foo.provides1', 'foo.provides2']);\n        $fooMock->shouldReceive('when')->once()->andReturn([]);\n\n        // bar mock is added to eagers since it's not reserved\n        $repo->shouldReceive('createProvider')->once()->with('bar')->andReturn($barMock = m::mock(ServiceProvider::class));\n        $barMock->shouldReceive('isDeferred')->once()->andReturn(false);\n        $repo->shouldReceive('writeManifest')->once()->andReturnUsing(function ($manifest) {\n            return $manifest;\n        });\n\n        $app->shouldReceive('register')->once()->with('bar');\n        $app->shouldReceive('runningInConsole')->andReturn(false);\n        $app->shouldReceive('addDeferredServices')->once()->with(['foo.provides1' => 'foo', 'foo.provides2' => 'foo']);\n\n        $repo->load(['foo', 'bar']);\n    }\n\n    public function testShouldRecompileReturnsCorrectValue()\n    {\n        $repo = new ProviderRepository(m::mock(ApplicationContract::class), new Filesystem, __DIR__.'/services.php');\n        $this->assertTrue($repo->shouldRecompile(null, []));\n        $this->assertTrue($repo->shouldRecompile(['providers' => ['foo']], ['foo', 'bar']));\n        $this->assertFalse($repo->shouldRecompile(['providers' => ['foo']], ['foo']));\n    }\n\n    public function testLoadManifestReturnsParsedJSON()\n    {\n        $repo = new ProviderRepository(m::mock(ApplicationContract::class), $files = m::mock(Filesystem::class), __DIR__.'/services.php');\n        $files->shouldReceive('exists')->once()->with(__DIR__.'/services.php')->andReturn(true);\n        $files->shouldReceive('getRequire')->once()->with(__DIR__.'/services.php')->andReturn($array = ['users' => ['dayle' => true], 'when' => []]);\n\n        $this->assertEquals($array, $repo->loadManifest());\n    }\n\n    public function testWriteManifestStoresToProperLocation()\n    {\n        $repo = new ProviderRepository(m::mock(ApplicationContract::class), $files = m::mock(Filesystem::class), __DIR__.'/services.php');\n        $files->shouldReceive('replace')->once()->with(__DIR__.'/services.php', '<?php return '.var_export(['foo'], true).';');\n\n        $result = $repo->writeManifest(['foo']);\n\n        $this->assertEquals(['foo', 'when' => []], $result);\n    }\n\n    public function testWriteManifestThrowsExceptionIfManifestDirDoesntExist()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessageMatches('/^The (.*) directory must be present and writable.$/');\n\n        $repo = new ProviderRepository(m::mock(ApplicationContract::class), $files = m::mock(Filesystem::class), __DIR__.'/cache/services.php');\n        $files->shouldReceive('replace')->never();\n\n        $repo->writeManifest(['foo']);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/FoundationViteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation;\n\nuse Illuminate\\Foundation\\Vite;\nuse Illuminate\\Foundation\\ViteException;\nuse Illuminate\\Foundation\\ViteManifestNotFoundException;\nuse Illuminate\\Support\\Facades\\Vite as ViteFacade;\nuse Illuminate\\Support\\Js;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FoundationViteTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        app('config')->set('app.asset_url', 'https://example.com');\n    }\n\n    protected function tearDown(): void\n    {\n        $this->cleanViteManifest();\n        $this->cleanViteHotFile();\n\n        parent::tearDown();\n    }\n\n    public function testViteWithJsOnly()\n    {\n        $this->makeViteManifest();\n\n        $result = app(Vite::class)('resources/js/app.js');\n\n        $this->assertStringEndsWith('<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\"></script>', $result->toHtml());\n    }\n\n    public function testViteWithCssAndJs()\n    {\n        $this->makeViteManifest();\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/app.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testViteWithCssImport()\n    {\n        $this->makeViteManifest();\n\n        $result = app(Vite::class)('resources/js/app-with-css-import.js');\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/imported-css.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app-with-css-import.versioned.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testViteWithSharedCssImport()\n    {\n        $this->makeViteManifest();\n\n        $result = app(Vite::class)(['resources/js/app-with-shared-css.js']);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/shared-css.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app-with-shared-css.versioned.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testViteHotModuleReplacementWithJsOnly()\n    {\n        $this->makeViteHotFile();\n\n        $result = app(Vite::class)('resources/js/app.js');\n\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\"></script>'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testViteHotModuleReplacementWithJsAndCss()\n    {\n        $this->makeViteHotFile();\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\"></script>'\n            .'<link rel=\"stylesheet\" href=\"http://localhost:3000/resources/css/app.css\" />'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanGenerateCspNonceWithHotFile()\n    {\n        Str::createRandomStringsUsing(fn ($length) => \"random-string-with-length:{$length}\");\n        $this->makeViteHotFile();\n\n        $nonce = ViteFacade::useCspNonce();\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame('random-string-with-length:40', $nonce);\n        $this->assertSame('random-string-with-length:40', ViteFacade::cspNonce());\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\" nonce=\"random-string-with-length:40\"></script>'\n            .'<link rel=\"stylesheet\" href=\"http://localhost:3000/resources/css/app.css\" nonce=\"random-string-with-length:40\" />'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\" nonce=\"random-string-with-length:40\"></script>',\n            $result->toHtml()\n        );\n\n        Str::createRandomStringsNormally();\n    }\n\n    public function testItCanGenerateCspNonceWithManifest()\n    {\n        Str::createRandomStringsUsing(fn ($length) => \"random-string-with-length:{$length}\");\n        $this->makeViteManifest();\n\n        $nonce = ViteFacade::useCspNonce();\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame('random-string-with-length:40', $nonce);\n        $this->assertSame('random-string-with-length:40', ViteFacade::cspNonce());\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/app.versioned.css\" nonce=\"random-string-with-length:40\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\" nonce=\"random-string-with-length:40\"></script>',\n            $result->toHtml()\n        );\n\n        Str::createRandomStringsNormally();\n    }\n\n    public function testItCanSpecifyCspNonceWithHotFile()\n    {\n        $this->makeViteHotFile();\n\n        $nonce = ViteFacade::useCspNonce('expected-nonce');\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame('expected-nonce', $nonce);\n        $this->assertSame('expected-nonce', ViteFacade::cspNonce());\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\" nonce=\"expected-nonce\"></script>'\n            .'<link rel=\"stylesheet\" href=\"http://localhost:3000/resources/css/app.css\" nonce=\"expected-nonce\" />'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\" nonce=\"expected-nonce\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanSpecifyCspNonceWithManifest()\n    {\n        $this->makeViteManifest();\n\n        $nonce = ViteFacade::useCspNonce('expected-nonce');\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame('expected-nonce', $nonce);\n        $this->assertSame('expected-nonce', ViteFacade::cspNonce());\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/app.versioned.css\" nonce=\"expected-nonce\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\" nonce=\"expected-nonce\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testReactRefreshWithNoNonce()\n    {\n        $this->makeViteHotFile();\n\n        $result = app(Vite::class)->reactRefresh();\n\n        $this->assertStringNotContainsString('nonce', $result);\n    }\n\n    public function testReactRefreshNonce()\n    {\n        $this->makeViteHotFile();\n\n        $nonce = ViteFacade::useCspNonce('expected-nonce');\n        $result = app(Vite::class)->reactRefresh();\n\n        $this->assertStringContainsString(sprintf('nonce=\"%s\"', $nonce), $result);\n    }\n\n    public function testItCanInjectIntegrityWhenPresentInManifest()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'integrity' => 'expected-app.js-integrity',\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n                'integrity' => 'expected-app.css-integrity',\n            ],\n        ], $buildDir);\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js'], $buildDir);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" integrity=\"expected-app.css-integrity\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" integrity=\"expected-app.js-integrity\"></script>',\n            $result->toHtml()\n        );\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanInjectIntegrityWhenPresentInManifestForCss()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'css' => [\n                    'assets/direct-css-dependency.aabbcc.css',\n                ],\n                'integrity' => 'expected-app.js-integrity',\n            ],\n            '_import.versioned.js' => [\n                'file' => 'assets/import.versioned.js',\n                'css' => [\n                    'assets/imported-css.versioned.css',\n                ],\n                'integrity' => 'expected-import.js-integrity',\n            ],\n            'imported-css.css' => [\n                'file' => 'assets/direct-css-dependency.aabbcc.css',\n                'integrity' => 'expected-imported-css.css-integrity',\n            ],\n        ], $buildDir);\n\n        $result = app(Vite::class)('resources/js/app.js', $buildDir);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/direct-css-dependency.aabbcc.css\" integrity=\"expected-imported-css.css-integrity\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" integrity=\"expected-app.js-integrity\"></script>',\n            $result->toHtml()\n        );\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanInjectIntegrityWhenPresentInManifestForImportedCss()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'imports' => [\n                    '_import.versioned.js',\n                ],\n                'integrity' => 'expected-app.js-integrity',\n            ],\n            '_import.versioned.js' => [\n                'file' => 'assets/import.versioned.js',\n                'css' => [\n                    'assets/imported-css.versioned.css',\n                ],\n                'integrity' => 'expected-import.js-integrity',\n            ],\n            'imported-css.css' => [\n                'file' => 'assets/imported-css.versioned.css',\n                'integrity' => 'expected-imported-css.css-integrity',\n            ],\n        ], $buildDir);\n\n        $result = app(Vite::class)('resources/js/app.js', $buildDir);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/imported-css.versioned.css\" integrity=\"expected-imported-css.css-integrity\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" integrity=\"expected-app.js-integrity\"></script>',\n            $result->toHtml()\n        );\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanSpecifyIntegrityKey()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'different-integrity-key' => 'expected-app.js-integrity',\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n                'different-integrity-key' => 'expected-app.css-integrity',\n            ],\n        ], $buildDir);\n        ViteFacade::useIntegrityKey('different-integrity-key');\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js'], $buildDir);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" integrity=\"expected-app.css-integrity\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" integrity=\"expected-app.js-integrity\"></script>',\n            $result->toHtml()\n        );\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanSpecifyArbitraryAttributesForScriptTagsWhenBuilt()\n    {\n        $this->makeViteManifest();\n        ViteFacade::useScriptTagAttributes([\n            'general' => 'attribute',\n        ]);\n        ViteFacade::useScriptTagAttributes(function ($src, $url, $chunk, $manifest) {\n            $this->assertSame('resources/js/app.js', $src);\n            $this->assertSame('https://example.com/build/assets/app.versioned.js', $url);\n            $this->assertSame([\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n            ], $chunk);\n            $this->assertSame([\n                'resources/js/app.js' => [\n                    'src' => 'resources/js/app.js',\n                    'file' => 'assets/app.versioned.js',\n                ],\n                'resources/js/app-with-css-import.js' => [\n                    'src' => 'resources/js/app-with-css-import.js',\n                    'file' => 'assets/app-with-css-import.versioned.js',\n                    'css' => [\n                        'assets/imported-css.versioned.css',\n                    ],\n                ],\n                'resources/css/imported-css.css' => [\n                    'file' => 'assets/imported-css.versioned.css',\n                ],\n                'resources/js/app-with-shared-css.js' => [\n                    'src' => 'resources/js/app-with-shared-css.js',\n                    'file' => 'assets/app-with-shared-css.versioned.js',\n                    'imports' => [\n                        '_someFile.js',\n                    ],\n                ],\n                'resources/css/app.css' => [\n                    'src' => 'resources/css/app.css',\n                    'file' => 'assets/app.versioned.css',\n                ],\n                '_someFile.js' => [\n                    'file' => 'assets/someFile.versioned.js',\n                    'css' => [\n                        'assets/shared-css.versioned.css',\n                    ],\n                ],\n                'resources/css/shared-css' => [\n                    'src' => 'resources/css/shared-css',\n                    'file' => 'assets/shared-css.versioned.css',\n                ],\n            ], $manifest);\n\n            return [\n                'crossorigin',\n                'data-persistent-across-pages' => 'YES',\n                'remove-me' => false,\n                'keep-me' => true,\n                'null' => null,\n                'empty-string' => '',\n                'zero' => 0,\n            ];\n        });\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/app.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me empty-string=\"\" zero=\"0\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanSpecifyArbitraryAttributesForStylesheetTagsWhenBuild()\n    {\n        $this->makeViteManifest();\n        ViteFacade::useStyleTagAttributes([\n            'general' => 'attribute',\n        ]);\n        ViteFacade::useStyleTagAttributes(function ($src, $url, $chunk, $manifest) {\n            $this->assertSame('resources/css/app.css', $src);\n            $this->assertSame('https://example.com/build/assets/app.versioned.css', $url);\n            $this->assertSame([\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ], $chunk);\n            $this->assertSame([\n                'resources/js/app.js' => [\n                    'src' => 'resources/js/app.js',\n                    'file' => 'assets/app.versioned.js',\n                ],\n                'resources/js/app-with-css-import.js' => [\n                    'src' => 'resources/js/app-with-css-import.js',\n                    'file' => 'assets/app-with-css-import.versioned.js',\n                    'css' => [\n                        'assets/imported-css.versioned.css',\n                    ],\n                ],\n                'resources/css/imported-css.css' => [\n                    'file' => 'assets/imported-css.versioned.css',\n                ],\n                'resources/js/app-with-shared-css.js' => [\n                    'src' => 'resources/js/app-with-shared-css.js',\n                    'file' => 'assets/app-with-shared-css.versioned.js',\n                    'imports' => [\n                        '_someFile.js',\n                    ],\n                ],\n                'resources/css/app.css' => [\n                    'src' => 'resources/css/app.css',\n                    'file' => 'assets/app.versioned.css',\n                ],\n                '_someFile.js' => [\n                    'file' => 'assets/someFile.versioned.js',\n                    'css' => [\n                        'assets/shared-css.versioned.css',\n                    ],\n                ],\n                'resources/css/shared-css' => [\n                    'src' => 'resources/css/shared-css',\n                    'file' => 'assets/shared-css.versioned.css',\n                ],\n            ], $manifest);\n\n            return [\n                'crossorigin',\n                'data-persistent-across-pages' => 'YES',\n                'remove-me' => false,\n                'keep-me' => true,\n            ];\n        });\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"stylesheet\" href=\"https://example.com/build/assets/app.versioned.css\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me />'\n            .'<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanSpecifyArbitraryAttributesForScriptTagsWhenHotModuleReloading()\n    {\n        $this->makeViteHotFile();\n        ViteFacade::useScriptTagAttributes([\n            'general' => 'attribute',\n        ]);\n        $expectedArguments = [\n            ['src' => '@vite/client', 'url' => 'http://localhost:3000/@vite/client'],\n            ['src' => 'resources/js/app.js', 'url' => 'http://localhost:3000/resources/js/app.js'],\n        ];\n        ViteFacade::useScriptTagAttributes(function ($src, $url, $chunk, $manifest) use (&$expectedArguments) {\n            $args = array_shift($expectedArguments);\n\n            $this->assertSame($args['src'], $src);\n            $this->assertSame($args['url'], $url);\n            $this->assertNull($chunk);\n            $this->assertNull($manifest);\n\n            return [\n                'crossorigin',\n                'data-persistent-across-pages' => 'YES',\n                'remove-me' => false,\n                'keep-me' => true,\n            ];\n        });\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me></script>'\n            .'<link rel=\"stylesheet\" href=\"http://localhost:3000/resources/css/app.css\" />'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanSpecifyArbitraryAttributesForStylesheetTagsWhenHotModuleReloading()\n    {\n        $this->makeViteHotFile();\n        ViteFacade::useStyleTagAttributes([\n            'general' => 'attribute',\n        ]);\n        ViteFacade::useStyleTagAttributes(function ($src, $url, $chunk, $manifest) {\n            $this->assertSame('resources/css/app.css', $src);\n            $this->assertSame('http://localhost:3000/resources/css/app.css', $url);\n            $this->assertNull($chunk);\n            $this->assertNull($manifest);\n\n            return [\n                'crossorigin',\n                'data-persistent-across-pages' => 'YES',\n                'remove-me' => false,\n                'keep-me' => true,\n            ];\n        });\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\"></script>'\n            .'<link rel=\"stylesheet\" href=\"http://localhost:3000/resources/css/app.css\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me />'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanOverrideAllAttributes()\n    {\n        $this->makeViteManifest();\n        ViteFacade::useStyleTagAttributes([\n            'rel' => 'expected-rel',\n            'href' => 'expected-href',\n        ]);\n        ViteFacade::useScriptTagAttributes([\n            'type' => 'expected-type',\n            'src' => 'expected-src',\n        ]);\n\n        $result = app(Vite::class)(['resources/css/app.css', 'resources/js/app.js']);\n\n        $this->assertStringEndsWith(\n            '<link rel=\"expected-rel\" href=\"expected-href\" />'\n            .'<script type=\"expected-type\" src=\"expected-src\"></script>',\n            $result->toHtml()\n        );\n    }\n\n    public function testItCanGenerateIndividualAssetUrlInBuildMode()\n    {\n        $this->makeViteManifest();\n\n        $url = ViteFacade::asset('resources/js/app.js');\n\n        $this->assertSame('https://example.com/build/assets/app.versioned.js', $url);\n    }\n\n    public function testItCanGenerateIndividualAssetUrlInHotMode()\n    {\n        $this->makeViteHotFile();\n\n        $url = ViteFacade::asset('resources/js/app.js');\n\n        $this->assertSame('http://localhost:3000/resources/js/app.js', $url);\n    }\n\n    public function testItThrowsWhenUnableToFindAssetManifestInBuildMode()\n    {\n        $this->expectException(ViteException::class);\n        $this->expectExceptionMessage('Vite manifest not found at: '.public_path('build/manifest.json'));\n\n        ViteFacade::asset('resources/js/app.js');\n    }\n\n    public function testItThrowsDeprecatedExecptionWhenUnableToFindAssetManifestInBuildMode()\n    {\n        $this->expectException(ViteManifestNotFoundException::class);\n        $this->expectExceptionMessage('Vite manifest not found at: '.public_path('build/manifest.json'));\n\n        ViteFacade::asset('resources/js/app.js');\n    }\n\n    public function testItThrowsWhenUnableToFindAssetChunkInBuildMode()\n    {\n        $this->makeViteManifest();\n\n        $this->expectException(ViteException::class);\n        $this->expectExceptionMessage('Unable to locate file in Vite manifest: resources/js/missing.js');\n\n        ViteFacade::asset('resources/js/missing.js');\n    }\n\n    public function testItDoesNotReturnHashInDevMode()\n    {\n        $this->makeViteHotFile();\n\n        $this->assertNull(ViteFacade::manifestHash());\n\n        $this->cleanViteHotFile();\n    }\n\n    public function testItGetsHashInBuildMode()\n    {\n        $this->makeViteManifest(['a.js' => ['src' => 'a.js']]);\n\n        $this->assertSame('98ca5a789544599b562c9978f3147a0f', ViteFacade::manifestHash());\n\n        $this->cleanViteManifest();\n    }\n\n    public function testItGetsDifferentHashesForDifferentManifestsInBuildMode()\n    {\n        $this->makeViteManifest(['a.js' => ['src' => 'a.js']]);\n        $this->makeViteManifest(['b.js' => ['src' => 'b.js']], 'admin');\n\n        $this->assertSame('98ca5a789544599b562c9978f3147a0f', ViteFacade::manifestHash());\n        $this->assertSame('928a60835978bae84e5381fbb08a38b2', ViteFacade::manifestHash('admin'));\n\n        $this->cleanViteManifest();\n        $this->cleanViteManifest('admin');\n    }\n\n    public function testViteCanSetEntryPointsWithFluentBuilder()\n    {\n        $this->makeViteManifest();\n\n        $vite = app(Vite::class);\n\n        $this->assertSame('', $vite->toHtml());\n\n        $vite->withEntryPoints(['resources/js/app.js']);\n\n        $this->assertStringEndsWith(\n            '<script type=\"module\" src=\"https://example.com/build/assets/app.versioned.js\"></script>',\n            $vite->toHtml()\n        );\n    }\n\n    public function testViteCanOverrideBuildDirectory()\n    {\n        $this->makeViteManifest(null, 'custom-build');\n\n        $vite = app(Vite::class);\n\n        $vite->withEntryPoints(['resources/js/app.js'])->useBuildDirectory('custom-build');\n\n        $this->assertStringEndsWith(\n            '<script type=\"module\" src=\"https://example.com/custom-build/assets/app.versioned.js\"></script>',\n            $vite->toHtml()\n        );\n\n        $this->cleanViteManifest('custom-build');\n    }\n\n    public function testViteCanOverrideHotFilePath()\n    {\n        $this->makeViteHotFile('cold');\n\n        $vite = app(Vite::class);\n\n        $vite->withEntryPoints(['resources/js/app.js'])->useHotFile('cold');\n\n        $this->assertSame(\n            '<script type=\"module\" src=\"http://localhost:3000/@vite/client\"></script>'\n            .'<script type=\"module\" src=\"http://localhost:3000/resources/js/app.js\"></script>',\n            $vite->toHtml()\n        );\n\n        $this->cleanViteHotFile('cold');\n    }\n\n    public function testViteCanAssetPath()\n    {\n        $this->makeViteManifest([\n            'resources/images/profile.png' => [\n                'src' => 'resources/images/profile.png',\n                'file' => 'assets/profile.versioned.png',\n            ],\n        ], $buildDir = Str::random());\n        $vite = app(Vite::class)->useBuildDirectory($buildDir);\n        $this->app['config']->set('app.asset_url', 'https://cdn.app.com');\n\n        // default behaviour...\n        $this->assertSame(\"https://cdn.app.com/{$buildDir}/assets/profile.versioned.png\", $vite->asset('resources/images/profile.png'));\n\n        // custom behaviour\n        $vite->createAssetPathsUsing(function ($path) {\n            return 'https://tenant-cdn.app.com/'.$path;\n        });\n        $this->assertSame(\"https://tenant-cdn.app.com/{$buildDir}/assets/profile.versioned.png\", $vite->asset('resources/images/profile.png'));\n\n        // restore default behaviour...\n        $vite->createAssetPathsUsing(null);\n        $this->assertSame(\"https://cdn.app.com/{$buildDir}/assets/profile.versioned.png\", $vite->asset('resources/images/profile.png'));\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testViteIsMacroable()\n    {\n        $this->makeViteManifest([\n            'resources/images/profile.png' => [\n                'src' => 'resources/images/profile.png',\n                'file' => 'assets/profile.versioned.png',\n            ],\n        ], $buildDir = Str::random());\n        Vite::macro('image', function ($asset, $buildDir = null) {\n            return $this->asset(\"resources/images/{$asset}\", $buildDir);\n        });\n\n        $path = ViteFacade::image('profile.png', $buildDir);\n\n        $this->assertSame(\"https://example.com/{$buildDir}/assets/profile.versioned.png\", $path);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItGeneratesPreloadDirectivesForJsAndCssImports()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/jetstream-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n\n        $result = app(Vite::class)(['resources/js/Pages/Auth/Login.vue'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app.9842b564.css\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/Login.8c52c4a3.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app.a26d8e4d.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/AuthenticationCard.47ef70cc.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/AuthenticationCardLogo.9999a373.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/Checkbox.33ba23f3.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/TextInput.e2f0248c.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/InputLabel.d245ec4e.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/PrimaryButton.931d2859.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/_plugin-vue_export-helper.cdc0426e.js\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.9842b564.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/Login.8c52c4a3.js\"></script>', $result->toHtml()\n        );\n        $this->assertSame([\n            'https://example.com/'.$buildDir.'/assets/app.9842b564.css' => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/Login.8c52c4a3.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/app.a26d8e4d.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/AuthenticationCard.47ef70cc.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/AuthenticationCardLogo.9999a373.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/Checkbox.33ba23f3.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/TextInput.e2f0248c.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/InputLabel.d245ec4e.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/PrimaryButton.931d2859.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            'https://example.com/'.$buildDir.'/assets/_plugin-vue_export-helper.cdc0426e.js' => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanSpecifyAttributesForPreloadedAssets()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'imports' => [\n                    'import.js',\n                ],\n                'css' => [\n                    'assets/app.versioned.css',\n                ],\n            ],\n            'import.js' => [\n                'file' => 'assets/import.versioned.js',\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ],\n        ], $buildDir);\n        ViteFacade::usePreloadTagAttributes([\n            'general' => 'attribute',\n        ]);\n        ViteFacade::usePreloadTagAttributes(function ($src, $url, $chunk, $manifest) use ($buildDir) {\n            $this->assertSame([\n                'resources/js/app.js' => [\n                    'src' => 'resources/js/app.js',\n                    'file' => 'assets/app.versioned.js',\n                    'imports' => [\n                        'import.js',\n                    ],\n                    'css' => [\n                        'assets/app.versioned.css',\n                    ],\n                ],\n                'import.js' => [\n                    'file' => 'assets/import.versioned.js',\n                ],\n                'resources/css/app.css' => [\n                    'src' => 'resources/css/app.css',\n                    'file' => 'assets/app.versioned.css',\n                ],\n            ], $manifest);\n\n            (match ($src) {\n                'resources/js/app.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app.versioned.js\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/js/app.js',\n                        'file' => 'assets/app.versioned.js',\n                        'imports' => [\n                            'import.js',\n                        ],\n                        'css' => [\n                            'assets/app.versioned.css',\n                        ],\n                    ], $chunk);\n                },\n                'import.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/import.versioned.js\", $url);\n                    $this->assertSame([\n                        'file' => 'assets/import.versioned.js',\n                    ], $chunk);\n                },\n                'resources/css/app.css' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app.versioned.css\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/css/app.css',\n                        'file' => 'assets/app.versioned.css',\n                    ], $chunk);\n                },\n            })();\n\n            return [\n                'crossorigin',\n                'data-persistent-across-pages' => 'YES',\n                'remove-me' => false,\n                'keep-me' => true,\n                'null' => null,\n                'empty-string' => '',\n                'zero' => 0,\n            ];\n        });\n\n        $result = app(Vite::class)(['resources/js/app.js'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me empty-string=\"\" zero=\"0\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me empty-string=\"\" zero=\"0\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/import.versioned.js\" general=\"attribute\" crossorigin data-persistent-across-pages=\"YES\" keep-me empty-string=\"\" zero=\"0\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\"></script>',\n            $result->toHtml());\n\n        $this->assertSame([\n            \"https://example.com/$buildDir/assets/app.versioned.css\" => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n                'general=\"attribute\"',\n                'crossorigin',\n                'data-persistent-across-pages=\"YES\"',\n                'keep-me',\n                'empty-string=\"\"',\n                'zero=\"0\"',\n            ],\n            \"https://example.com/$buildDir/assets/app.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n                'general=\"attribute\"',\n                'crossorigin',\n                'data-persistent-across-pages=\"YES\"',\n                'keep-me',\n                'empty-string=\"\"',\n                'zero=\"0\"',\n            ],\n            \"https://example.com/$buildDir/assets/import.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n                'general=\"attribute\"',\n                'crossorigin',\n                'data-persistent-across-pages=\"YES\"',\n                'keep-me',\n                'empty-string=\"\"',\n                'zero=\"0\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanSuppressPreloadTagGeneration()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'imports' => [\n                    'import.js',\n                    'import-nopreload.js',\n                ],\n                'css' => [\n                    'assets/app.versioned.css',\n                    'assets/app-nopreload.versioned.css',\n                ],\n            ],\n            'resources/js/app-nopreload.js' => [\n                'src' => 'resources/js/app-nopreload.js',\n                'file' => 'assets/app-nopreload.versioned.js',\n            ],\n            'import.js' => [\n                'file' => 'assets/import.versioned.js',\n            ],\n            'import-nopreload.js' => [\n                'file' => 'assets/import-nopreload.versioned.js',\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ],\n            'resources/css/app-nopreload.css' => [\n                'src' => 'resources/css/app-nopreload.css',\n                'file' => 'assets/app-nopreload.versioned.css',\n            ],\n        ], $buildDir);\n        ViteFacade::usePreloadTagAttributes(function ($src, $url, $chunk, $manifest) use ($buildDir) {\n            $this->assertSame([\n                'resources/js/app.js' => [\n                    'src' => 'resources/js/app.js',\n                    'file' => 'assets/app.versioned.js',\n                    'imports' => [\n                        'import.js',\n                        'import-nopreload.js',\n                    ],\n                    'css' => [\n                        'assets/app.versioned.css',\n                        'assets/app-nopreload.versioned.css',\n                    ],\n                ],\n                'resources/js/app-nopreload.js' => [\n                    'src' => 'resources/js/app-nopreload.js',\n                    'file' => 'assets/app-nopreload.versioned.js',\n                ],\n                'import.js' => [\n                    'file' => 'assets/import.versioned.js',\n                ],\n                'import-nopreload.js' => [\n                    'file' => 'assets/import-nopreload.versioned.js',\n                ],\n                'resources/css/app.css' => [\n                    'src' => 'resources/css/app.css',\n                    'file' => 'assets/app.versioned.css',\n                ],\n                'resources/css/app-nopreload.css' => [\n                    'src' => 'resources/css/app-nopreload.css',\n                    'file' => 'assets/app-nopreload.versioned.css',\n                ],\n            ], $manifest);\n\n            (match ($src) {\n                'resources/js/app.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app.versioned.js\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/js/app.js',\n                        'file' => 'assets/app.versioned.js',\n                        'imports' => [\n                            'import.js',\n                            'import-nopreload.js',\n                        ],\n                        'css' => [\n                            'assets/app.versioned.css',\n                            'assets/app-nopreload.versioned.css',\n                        ],\n                    ], $chunk);\n                },\n                'resources/js/app-nopreload.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app-nopreload.versioned.js\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/js/app-nopreload.js',\n                        'file' => 'assets/app-nopreload.versioned.js',\n                    ], $chunk);\n                },\n                'import.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/import.versioned.js\", $url);\n                    $this->assertSame([\n                        'file' => 'assets/import.versioned.js',\n                    ], $chunk);\n                },\n                'import-nopreload.js' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/import-nopreload.versioned.js\", $url);\n                    $this->assertSame([\n                        'file' => 'assets/import-nopreload.versioned.js',\n                    ], $chunk);\n                },\n                'resources/css/app.css' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app.versioned.css\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/css/app.css',\n                        'file' => 'assets/app.versioned.css',\n                    ], $chunk);\n                },\n                'resources/css/app-nopreload.css' => function () use ($url, $chunk, $buildDir) {\n                    $this->assertSame(\"https://example.com/{$buildDir}/assets/app-nopreload.versioned.css\", $url);\n                    $this->assertSame([\n                        'src' => 'resources/css/app-nopreload.css',\n                        'file' => 'assets/app-nopreload.versioned.css',\n                    ], $chunk);\n                },\n            })();\n\n            return Str::contains($src, '-nopreload') ? false : [];\n        });\n\n        $result = app(Vite::class)(['resources/js/app.js', 'resources/js/app-nopreload.js'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/import.versioned.js\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app-nopreload.versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\"></script>'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app-nopreload.versioned.js\"></script>',\n            $result->toHtml());\n\n        $this->assertSame([\n            \"https://example.com/$buildDir/assets/app.versioned.css\" => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n            ],\n            \"https://example.com/$buildDir/assets/app.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            \"https://example.com/$buildDir/assets/import.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testPreloadAssetsGetAssetNonce()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'css' => [\n                    'assets/app.versioned.css',\n                ],\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ],\n        ], $buildDir);\n        ViteFacade::useCspNonce('expected-nonce');\n\n        $result = app(Vite::class)(['resources/js/app.js'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" nonce=\"expected-nonce\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" nonce=\"expected-nonce\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" nonce=\"expected-nonce\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" nonce=\"expected-nonce\"></script>',\n            $result->toHtml());\n\n        $this->assertSame([\n            \"https://example.com/$buildDir/assets/app.versioned.css\" => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n                'nonce=\"expected-nonce\"',\n            ],\n            \"https://example.com/$buildDir/assets/app.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n                'nonce=\"expected-nonce\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testCrossoriginAttributeIsInheritedByPreloadTags()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n                'css' => [\n                    'assets/app.versioned.css',\n                ],\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ],\n        ], $buildDir);\n        ViteFacade::useScriptTagAttributes([\n            'crossorigin' => 'script-crossorigin',\n        ]);\n        ViteFacade::useStyleTagAttributes([\n            'crossorigin' => 'style-crossorigin',\n        ]);\n\n        $result = app(Vite::class)(['resources/js/app.js'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" crossorigin=\"style-crossorigin\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" crossorigin=\"script-crossorigin\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app.versioned.css\" crossorigin=\"style-crossorigin\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app.versioned.js\" crossorigin=\"script-crossorigin\"></script>',\n            $result->toHtml());\n\n        $this->assertSame([\n            \"https://example.com/$buildDir/assets/app.versioned.css\" => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n                'crossorigin=\"style-crossorigin\"',\n            ],\n            \"https://example.com/$buildDir/assets/app.versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n                'crossorigin=\"script-crossorigin\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanConfigureTheManifestFilename()\n    {\n        $buildDir = Str::random();\n        app()->usePublicPath(__DIR__);\n        if (! file_exists(public_path($buildDir))) {\n            mkdir(public_path($buildDir));\n        }\n        $contents = json_encode([\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app-from-custom-manifest.js',\n                'file' => 'assets/app-from-custom-manifest.versioned.js',\n            ],\n        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);\n        file_put_contents(public_path(\"{$buildDir}/custom-manifest.json\"), $contents);\n\n        ViteFacade::useManifestFilename('custom-manifest.json');\n\n        $result = app(Vite::class)(['resources/js/app.js'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app-from-custom-manifest.versioned.js\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app-from-custom-manifest.versioned.js\"></script>',\n            $result->toHtml());\n\n        unlink(public_path(\"{$buildDir}/custom-manifest.json\"));\n        rmdir(public_path($buildDir));\n    }\n\n    public function testItOnlyOutputsUniquePreloadTags()\n    {\n        $buildDir = Str::random();\n        $this->makeViteManifest([\n            'resources/js/app.css' => [\n                'file' => 'assets/app-versioned.css',\n                'src' => 'resources/js/app.css',\n            ],\n            'resources/js/Pages/Welcome.vue' => [\n                'file' => 'assets/Welcome-versioned.js',\n                'src' => 'resources/js/Pages/Welcome.vue',\n                'imports' => [\n                    'resources/js/app.js',\n                ],\n            ],\n            'resources/js/app.js' => [\n                'file' => 'assets/app-versioned.js',\n                'src' => 'resources/js/app.js',\n                'css' => [\n                    'assets/app-versioned.css',\n                ],\n            ],\n        ], $buildDir);\n\n        $result = app(Vite::class)(['resources/js/app.js', 'resources/js/Pages/Welcome.vue'], $buildDir);\n\n        $this->assertSame(\n            '<link rel=\"preload\" as=\"style\" href=\"https://example.com/'.$buildDir.'/assets/app-versioned.css\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/app-versioned.js\" />'\n            .'<link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/'.$buildDir.'/assets/Welcome-versioned.js\" />'\n            .'<link rel=\"stylesheet\" href=\"https://example.com/'.$buildDir.'/assets/app-versioned.css\" />'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/app-versioned.js\"></script>'\n            .'<script type=\"module\" src=\"https://example.com/'.$buildDir.'/assets/Welcome-versioned.js\"></script>',\n            $result->toHtml());\n\n        $this->assertSame([\n            \"https://example.com/$buildDir/assets/app-versioned.css\" => [\n                'rel=\"preload\"',\n                'as=\"style\"',\n            ],\n            \"https://example.com/$buildDir/assets/app-versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n            \"https://example.com/$buildDir/assets/Welcome-versioned.js\" => [\n                'rel=\"modulepreload\"',\n                'as=\"script\"',\n            ],\n        ], ViteFacade::preloadedAssets());\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItRetrievesAssetContent()\n    {\n        $this->makeViteManifest();\n\n        $this->makeAsset('/app.versioned.js', 'some content');\n\n        $content = ViteFacade::content('resources/js/app.js');\n\n        $this->assertSame('some content', $content);\n\n        $this->cleanAsset('/app.versioned.js');\n\n        $this->cleanViteManifest();\n    }\n\n    public function testItThrowsWhenUnableToFindFileToRetrieveContent()\n    {\n        $this->makeViteManifest();\n\n        $this->expectException(ViteException::class);\n        $this->expectExceptionMessage('Unable to locate file from Vite manifest: '.public_path('build/assets/app.versioned.js'));\n\n        ViteFacade::content('resources/js/app.js');\n    }\n\n    protected function makeViteManifest($contents = null, $path = 'build')\n    {\n        app()->usePublicPath(__DIR__);\n\n        if (! file_exists(public_path($path))) {\n            mkdir(public_path($path));\n        }\n\n        $manifest = json_encode($contents ?? [\n            'resources/js/app.js' => [\n                'src' => 'resources/js/app.js',\n                'file' => 'assets/app.versioned.js',\n            ],\n            'resources/js/app-with-css-import.js' => [\n                'src' => 'resources/js/app-with-css-import.js',\n                'file' => 'assets/app-with-css-import.versioned.js',\n                'css' => [\n                    'assets/imported-css.versioned.css',\n                ],\n            ],\n            'resources/css/imported-css.css' => [\n                // 'src' => 'resources/css/imported-css.css',\n                'file' => 'assets/imported-css.versioned.css',\n            ],\n            'resources/js/app-with-shared-css.js' => [\n                'src' => 'resources/js/app-with-shared-css.js',\n                'file' => 'assets/app-with-shared-css.versioned.js',\n                'imports' => [\n                    '_someFile.js',\n                ],\n            ],\n            'resources/css/app.css' => [\n                'src' => 'resources/css/app.css',\n                'file' => 'assets/app.versioned.css',\n            ],\n            '_someFile.js' => [\n                'file' => 'assets/someFile.versioned.js',\n                'css' => [\n                    'assets/shared-css.versioned.css',\n                ],\n            ],\n            'resources/css/shared-css' => [\n                'src' => 'resources/css/shared-css',\n                'file' => 'assets/shared-css.versioned.css',\n            ],\n        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);\n\n        file_put_contents(public_path(\"{$path}/manifest.json\"), $manifest);\n    }\n\n    public function testItCanPrefetchEntrypoint()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->prefetch(concurrency: 3)->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'fetchpriority' => 'low'],\n        ]);\n        $this->assertSame(<<<HTML\n        <link rel=\"preload\" as=\"style\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/app-lliD09ip.js\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/index-BSdK3M0e.js\" /><link rel=\"stylesheet\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><script type=\"module\" src=\"https://example.com/{$buildDir}/assets/app-lliD09ip.js\"></script>\n        <script>\n             window.addEventListener('load', () => window.setTimeout(() => {\n                const makeLink = (asset) => {\n                    const link = document.createElement('link')\n\n                    Object.keys(asset).forEach((attribute) => {\n                        link.setAttribute(attribute, asset[attribute])\n                    })\n\n                    return link\n                }\n\n                const loadNext = (assets, count) => window.setTimeout(() => {\n                    if (count > assets.length) {\n                        count = assets.length\n\n                        if (count === 0) {\n                            return\n                        }\n                    }\n\n                    const fragment = new DocumentFragment\n\n                    while (count > 0) {\n                        const link = makeLink(assets.shift())\n                        fragment.append(link)\n                        count--\n\n                        if (assets.length) {\n                            link.onload = () => loadNext(assets, 1)\n                            link.onerror = () => loadNext(assets, 1)\n                        }\n                    }\n\n                    document.head.append(fragment)\n                })\n\n                loadNext({$expectedAssets}, 3)\n            }))\n        </script>\n        HTML, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItHandlesSpecifyingPageWithAppJs()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js', 'resources/js/Pages/Auth/Login.vue'])->useBuildDirectory($buildDir)->prefetch(concurrency: 3)->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'fetchpriority' => 'low'],\n        ]);\n        $this->assertStringContainsString(<<<JAVASCRIPT\n                loadNext({$expectedAssets}, 3)\n            JAVASCRIPT, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanSpecifyWaterfallChunks()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->prefetch(concurrency: 10)->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'fetchpriority' => 'low'],\n        ]);\n        $this->assertStringContainsString(<<<JAVASCRIPT\n                loadNext({$expectedAssets}, 10)\n            JAVASCRIPT, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanPrefetchAggressively()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->prefetch()->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'fetchpriority' => 'low'],\n        ]);\n\n        $this->assertSame(<<<HTML\n        <link rel=\"preload\" as=\"style\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/app-lliD09ip.js\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/index-BSdK3M0e.js\" /><link rel=\"stylesheet\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><script type=\"module\" src=\"https://example.com/{$buildDir}/assets/app-lliD09ip.js\"></script>\n        <script>\n             window.addEventListener('load', () => window.setTimeout(() => {\n                const makeLink = (asset) => {\n                    const link = document.createElement('link')\n\n                    Object.keys(asset).forEach((attribute) => {\n                        link.setAttribute(attribute, asset[attribute])\n                    })\n\n                    return link\n                }\n\n                const fragment = new DocumentFragment;\n                {$expectedAssets}.forEach((asset) => fragment.append(makeLink(asset)))\n                document.head.append(fragment)\n             }))\n        </script>\n        HTML, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testAddsAttributesToPrefetchTags()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->prefetch(concurrency: 3))->useCspNonce('abc123')->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'nonce' => 'abc123', 'fetchpriority' => 'low'],\n        ]);\n        $this->assertStringContainsString(<<<JAVASCRIPT\n                loadNext({$expectedAssets}, 3)\n        JAVASCRIPT, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItNormalisesAttributes()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js']))->useBuildDirectory($buildDir)->prefetch(concurrency: 3)->usePreloadTagAttributes([\n            'key' => 'value',\n            'key-only',\n            'true-value' => true,\n            'false-value' => false,\n            'null-value' => null,\n        ])->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value', 'fetchpriority' => 'low'],\n        ]);\n\n        $this->assertStringContainsString(<<<JAVASCRIPT\n                loadNext({$expectedAssets}, 3)\n        JAVASCRIPT, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItPrefetchesCss()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) ViteFacade::withEntryPoints(['resources/js/admin.js'])->useBuildDirectory($buildDir)->prefetch(concurrency: 3)->toHtml();\n\n        $expectedAssets = Js::from([\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/admin-runtime-import-CRvLQy6v.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'script', 'href' => \"https://example.com/{$buildDir}/assets/admin-runtime-import-import-DKMIaPXC.js\", 'fetchpriority' => 'low'],\n            ['rel' => 'prefetch', 'as' => 'style', 'href' => \"https://example.com/{$buildDir}/assets/admin-runtime-import-BlmN0T4U.css\", 'fetchpriority' => 'low'],\n        ]);\n        $this->assertSame(<<<HTML\n        <link rel=\"preload\" as=\"style\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><link rel=\"preload\" as=\"style\" href=\"https://example.com/{$buildDir}/assets/admin-BctAalm_.css\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/admin-Sefg0Q45.js\" /><link rel=\"modulepreload\" as=\"script\" href=\"https://example.com/{$buildDir}/assets/index-BSdK3M0e.js\" /><link rel=\"stylesheet\" href=\"https://example.com/{$buildDir}/assets/index-B3s1tYeC.css\" /><link rel=\"stylesheet\" href=\"https://example.com/{$buildDir}/assets/admin-BctAalm_.css\" /><script type=\"module\" src=\"https://example.com/{$buildDir}/assets/admin-Sefg0Q45.js\"></script>\n        <script>\n             window.addEventListener('load', () => window.setTimeout(() => {\n                const makeLink = (asset) => {\n                    const link = document.createElement('link')\n\n                    Object.keys(asset).forEach((attribute) => {\n                        link.setAttribute(attribute, asset[attribute])\n                    })\n\n                    return link\n                }\n\n                const loadNext = (assets, count) => window.setTimeout(() => {\n                    if (count > assets.length) {\n                        count = assets.length\n\n                        if (count === 0) {\n                            return\n                        }\n                    }\n\n                    const fragment = new DocumentFragment\n\n                    while (count > 0) {\n                        const link = makeLink(assets.shift())\n                        fragment.append(link)\n                        count--\n\n                        if (assets.length) {\n                            link.onload = () => loadNext(assets, 1)\n                            link.onerror = () => loadNext(assets, 1)\n                        }\n                    }\n\n                    document.head.append(fragment)\n                })\n\n                loadNext({$expectedAssets}, 3)\n            }))\n        </script>\n        HTML, $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testSupportCspNonceInPrefetchScript()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js']))\n            ->useCspNonce('abc123')\n            ->useBuildDirectory($buildDir)\n            ->prefetch()\n            ->toHtml();\n        $this->assertStringContainsString('<script nonce=\"abc123\">', $html);\n\n        $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js']))\n            ->useCspNonce('abc123')\n            ->useBuildDirectory($buildDir)\n            ->prefetch(concurrency: 3)\n            ->toHtml();\n        $this->assertStringContainsString('<script nonce=\"abc123\">', $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanConfigureThePrefetchTriggerEvent()\n    {\n        $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));\n        $buildDir = Str::random();\n        $this->makeViteManifest($manifest, $buildDir);\n        app()->usePublicPath(__DIR__);\n\n        $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js']))\n            ->useBuildDirectory($buildDir)\n            ->prefetch(event: 'vite:prefetch')\n            ->toHtml();\n        $this->assertStringNotContainsString(\"window.addEventListener('load', \", $html);\n        $this->assertStringContainsString(\"window.addEventListener('vite:prefetch', \", $html);\n\n        $this->cleanViteManifest($buildDir);\n    }\n\n    public function testItCanFlushState()\n    {\n        $this->makeViteManifest();\n\n        app(Vite::class)('resources/js/app.js');\n        app()->forgetScopedInstances();\n        $this->assertCount(1, app(Vite::class)->preloadedAssets());\n\n        app(Vite::class)->flush();\n        $this->assertCount(0, app(Vite::class)->preloadedAssets());\n    }\n\n    protected function cleanViteManifest($path = 'build')\n    {\n        if (file_exists(public_path(\"{$path}/manifest.json\"))) {\n            unlink(public_path(\"{$path}/manifest.json\"));\n        }\n\n        if (file_exists(public_path($path))) {\n            rmdir(public_path($path));\n        }\n    }\n\n    protected function makeAsset($asset, $content)\n    {\n        $path = public_path('build/assets');\n\n        if (! file_exists($path)) {\n            mkdir($path, recursive: true);\n        }\n\n        file_put_contents($path.'/'.$asset, $content);\n    }\n\n    protected function cleanAsset($asset)\n    {\n        $path = public_path('build/assets');\n\n        unlink($path.$asset);\n\n        rmdir($path);\n    }\n\n    protected function makeViteHotFile($path = null)\n    {\n        app()->usePublicPath(__DIR__);\n\n        $path ??= public_path('hot');\n\n        file_put_contents($path, 'http://localhost:3000');\n    }\n\n    protected function cleanViteHotFile($path = null)\n    {\n        $path ??= public_path('hot');\n\n        if (file_exists($path)) {\n            unlink($path);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Http/HtmlDumperTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Foundation\\Http\\HtmlDumper;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\nuse Symfony\\Component\\VarDumper\\Caster\\ReflectionCaster;\nuse Symfony\\Component\\VarDumper\\Cloner\\VarCloner;\n\nclass HtmlDumperTest extends TestCase\n{\n    protected $app;\n\n    protected function setUp(): void\n    {\n        HtmlDumper::resolveDumpSourceUsing(function () {\n            return [\n                '/my-work-director/app/routes/console.php',\n                'app/routes/console.php',\n                18,\n            ];\n        });\n\n        $this->app = Container::getInstance();\n    }\n\n    public function testString()\n    {\n        $output = $this->dump('string');\n\n        $expected = \"string</span>\\\"<span style=\\\"color: #A0A0A0;\\\"> // app/routes/console.php:18</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testInteger()\n    {\n        $output = $this->dump(1);\n\n        $expected = \"1</span><span style=\\\"color: #A0A0A0;\\\"> // app/routes/console.php:18</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testFloat()\n    {\n        $output = $this->dump(1.1);\n\n        $expected = \"1.1</span><span style=\\\"color: #A0A0A0;\\\"> // app/routes/console.php:18</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testArray()\n    {\n        $output = $this->dump(['string', 1, 1.1, ['string', 1, 1.1]]);\n\n        $expected = '<samp data-depth=1 class=sf-dump-expanded><span style=\"color: #A0A0A0;\"> // app/routes/console.php:18</span>';\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testBoolean()\n    {\n        $output = $this->dump(true);\n\n        $expected = \"true</span><span style=\\\"color: #A0A0A0;\\\"> // app/routes/console.php:18</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testObject()\n    {\n        $user = new stdClass();\n        $user->name = 'Guus';\n\n        $output = $this->dump($user);\n\n        $expected = '<samp data-depth=1 class=sf-dump-expanded><span style=\"color: #A0A0A0;\"> // app/routes/console.php:18</span>';\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testNull()\n    {\n        $output = $this->dump(null);\n\n        $expected = \"null</span><span style=\\\"color: #A0A0A0;\\\"> // app/routes/console.php:18</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testUnresolvableSource()\n    {\n        HtmlDumper::resolveDumpSourceUsing(fn () => null);\n\n        $output = $this->dump('string');\n\n        $expected = \"string</span>\\\"\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testWhenIsFileViewIsNotViewCompiled()\n    {\n        $file = '/my-work-directory/routes/web.php';\n\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('isCompiledViewFile');\n        $isCompiledViewFile = $method->invoke($dumper, $file);\n\n        $this->assertFalse($isCompiledViewFile);\n    }\n\n    public function testWhenIsFileViewIsViewCompiled()\n    {\n        $file = '/my-work-directory/storage/framework/views/6687c33c38b71a8560.php';\n\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('isCompiledViewFile');\n        $isCompiledViewFile = $method->invoke($dumper, $file);\n\n        $this->assertTrue($isCompiledViewFile);\n    }\n\n    public function testGetOriginalViewCompiledFile()\n    {\n        $compiled = __DIR__.'/../fixtures/fake-compiled-view.php';\n        $original = '/my-work-directory/resources/views/welcome.blade.php';\n\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('getOriginalFileForCompiledView');\n\n        $this->assertSame($original, $method->invoke($dumper, $compiled));\n    }\n\n    public function testWhenGetOriginalViewCompiledFileFails()\n    {\n        $compiled = __DIR__.'/../fixtures/fake-compiled-view-without-source-map.php';\n        $original = $compiled;\n\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $reflection = new ReflectionClass($dumper);\n        $method = $reflection->getMethod('getOriginalFileForCompiledView');\n\n        $this->assertSame($original, $method->invoke($dumper, $compiled));\n    }\n\n    public function testUnresolvableLine()\n    {\n        HtmlDumper::resolveDumpSourceUsing(function () {\n            return [\n                '/my-work-directory/resources/views/welcome.blade.php',\n                'resources/views/welcome.blade.php',\n                null,\n            ];\n        });\n\n        $output = $this->dump('hey from view');\n\n        $expected = \"hey from view</span>\\\"<span style=\\\"color: #A0A0A0;\\\"> // resources/views/welcome.blade.php</span>\\n</pre>\";\n\n        $this->assertStringContainsString($expected, $output);\n    }\n\n    public function testHref()\n    {\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        // Failure...\n        $href = (fn () => $this->resolveSourceHref(\n            '/my-work-directory/app/my-file',\n            10,\n        ))->call($dumper);\n        $this->assertNull($href);\n\n        $config = new Repository();\n        $this->app->instance('config', $config);\n        $resolveSourceHref = fn () => (fn () => $this->resolveSourceHref(\n            '/my-work-directory/app/my-file',\n            10,\n        ))->call($dumper);\n\n        // Empty...\n        $this->assertNull($resolveSourceHref());\n\n        // When editor name is provided...\n        $config->set('app.editor', 'phpstorm');\n        $this->assertSame(\n            'phpstorm://open?file=/my-work-directory/app/my-file&line=10', $resolveSourceHref()\n        );\n\n        // When editor name is provided on array format...\n        $config->set('app.editor', ['name' => 'phpstorm']);\n        $this->assertSame(\n            'phpstorm://open?file=/my-work-directory/app/my-file&line=10', $resolveSourceHref()\n        );\n\n        // When editor name and base path is provided on array format...\n        $config->set('app.editor', ['name' => 'phpstorm', 'base_path' => '/my-docker-work-directory']);\n        $this->assertSame(\n            'phpstorm://open?file=/my-docker-work-directory/app/my-file&line=10', $resolveSourceHref());\n\n        // When href is provided on array format...\n        $config->set('app.editor', ['href' => 'vscode://open?file={file}&line={line}']);\n        $this->assertSame(\n            'vscode://open?file=/my-work-directory/app/my-file&line=10', $resolveSourceHref()\n        );\n\n        // When href and base path is provided on array format...\n        $config->set('app.editor', ['href' => 'vscode://open?file={file}&line={line}', 'base_path' => '/my-docker-work-directory']);\n        $this->assertSame(\n            'vscode://open?file=/my-docker-work-directory/app/my-file&line=10', $resolveSourceHref()\n        );\n\n        // When editor name is provided...\n        $config->set('app.editor', 'sublime');\n        $this->assertSame('subl://open?url=file:///my-work-directory/app/my-file&line=10', $resolveSourceHref());\n\n        // Missing line\n        $config->set('app.editor', ['name' => 'vscode', 'base_path' => '/my-docker-work-directory']);\n\n        $href = (fn () => $this->resolveSourceHref(\n            '/my-work-directory/app/my-file',\n            null,\n        ))->call($dumper);\n        $this->assertSame(\n            'vscode://file//my-docker-work-directory/app/my-file:1',\n            $href,\n        );\n\n        // When base path appears elsewhere in the file path\n        $config->set('app.editor', ['name' => 'vscode', 'base_path' => '/my-docker-work-directory']);\n        $href = (fn () => $this->resolveSourceHref(\n            '/my-work-directory/storage/my-work-directory/my-file',\n            10,\n        ))->call($dumper);\n        $this->assertSame(\n            'vscode://file//my-docker-work-directory/storage/my-work-directory/my-file:10',\n            $href,\n        );\n    }\n\n    protected function dump($value)\n    {\n        $outputFile = stream_get_meta_data(tmpfile())['uri'];\n\n        $dumper = new HtmlDumper(\n            '/my-work-directory',\n            '/my-work-directory/storage/framework/views'\n        );\n\n        $dumper->setOutput($outputFile);\n\n        $cloner = tap(new VarCloner())->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);\n\n        $dumper->dumpWithSource($cloner->cloneVar($value));\n\n        return tap(file_get_contents($outputFile), fn () => @unlink($outputFile));\n    }\n\n    protected function tearDown(): void\n    {\n        HtmlDumper::resolveDumpSourceUsing(null);\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Http/KernelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http;\n\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Events\\Terminating;\nuse Illuminate\\Foundation\\Http\\Kernel;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\Router;\nuse PHPUnit\\Framework\\TestCase;\n\nclass KernelTest extends TestCase\n{\n    public function testGetMiddlewareGroups()\n    {\n        $kernel = new Kernel($this->getApplication(), $this->getRouter());\n\n        $this->assertEquals([], $kernel->getMiddlewareGroups());\n    }\n\n    public function testGetRouteMiddleware()\n    {\n        $kernel = new Kernel($this->getApplication(), $this->getRouter());\n\n        $this->assertEquals([], $kernel->getRouteMiddleware());\n    }\n\n    public function testGetMiddlewarePriority()\n    {\n        $kernel = new Kernel($this->getApplication(), $this->getRouter());\n\n        $this->assertEquals([\n            \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,\n            \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n            \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n            \\Illuminate\\Session\\Middleware\\StartSession::class,\n            \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n            \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis::class,\n            \\Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions::class,\n            \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n            \\Illuminate\\Auth\\Middleware\\Authorize::class,\n        ], $kernel->getMiddlewarePriority());\n    }\n\n    public function testAddToMiddlewarePriorityAfter()\n    {\n        $kernel = new Kernel($this->getApplication(), $this->getRouter());\n\n        $kernel->addToMiddlewarePriorityAfter(\n            [\n                \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n                \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n            ],\n            \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,\n        );\n\n        $this->assertEquals([\n            \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,\n            \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n            \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n            \\Illuminate\\Session\\Middleware\\StartSession::class,\n            \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n            \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis::class,\n            \\Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions::class,\n            \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n            \\Illuminate\\Auth\\Middleware\\Authorize::class,\n        ], $kernel->getMiddlewarePriority());\n    }\n\n    public function testAddToMiddlewarePriorityBefore()\n    {\n        $kernel = new Kernel($this->getApplication(), $this->getRouter());\n\n        $kernel->addToMiddlewarePriorityBefore(\n            [\n                \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n                \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n            ],\n            \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,\n        );\n\n        $this->assertEquals([\n            \\Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ValidateSignature::class,\n            \\Illuminate\\Cookie\\Middleware\\EncryptCookies::class,\n            \\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse::class,\n            \\Illuminate\\Session\\Middleware\\StartSession::class,\n            \\Illuminate\\View\\Middleware\\ShareErrorsFromSession::class,\n            \\Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequests::class,\n            \\Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis::class,\n            \\Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions::class,\n            \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,\n            \\Illuminate\\Auth\\Middleware\\Authorize::class,\n        ], $kernel->getMiddlewarePriority());\n    }\n\n    public function testItTriggersTerminatingEvent()\n    {\n        $called = [];\n        $app = $this->getApplication();\n        $events = new Dispatcher($app);\n        $app->instance('events', $events);\n        $kernel = new Kernel($app, $this->getRouter());\n        $app->instance('terminating-middleware', new class($called)\n        {\n            public function __construct(private &$called)\n            {\n                //\n            }\n\n            public function handle($request, $next)\n            {\n                return $next($request);\n            }\n\n            public function terminate($request, $response)\n            {\n                $this->called[] = 'terminating middleware';\n            }\n        });\n        $kernel->setGlobalMiddleware([\n            'terminating-middleware',\n        ]);\n        $events->listen(function (Terminating $terminating) use (&$called) {\n            $called[] = 'terminating event';\n        });\n        $app->terminating(function () use (&$called) {\n            $called[] = 'terminating callback';\n        });\n\n        $kernel->terminate(new Request(), new Response());\n\n        $this->assertSame([\n            'terminating event',\n            'terminating middleware',\n            'terminating callback',\n        ], $called);\n    }\n\n    /**\n     * @return \\Illuminate\\Contracts\\Foundation\\Application\n     */\n    protected function getApplication()\n    {\n        return new Application;\n    }\n\n    /**\n     * @return \\Illuminate\\Routing\\Router\n     */\n    protected function getRouter()\n    {\n        return new Router(new Dispatcher);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Http/Middleware/ConvertEmptyStringsToNullTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\nclass ConvertEmptyStringsToNullTest extends TestCase\n{\n    public function testConvertsEmptyStringsToNull()\n    {\n        $middleware = new ConvertEmptyStringsToNull;\n        $symfonyRequest = new SymfonyRequest([\n            'foo' => 'bar',\n            'baz' => '',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('bar', $request->get('foo'));\n            $this->assertNull($request->get('baz'));\n        });\n    }\n\n    public function testSkipConvertsEmptyStringsToNull()\n    {\n        $middleware = new ConvertEmptyStringsToNull;\n        ConvertEmptyStringsToNull::skipWhen(fn ($request) => '' === $request->baz);\n        $symfonyRequest = new SymfonyRequest([\n            'foo' => 'bar',\n            'baz' => '',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('bar', $request->get('foo'));\n            $this->assertSame('', $request->get('baz'));\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Http/Middleware/TransformsRequestTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\nclass TransformsRequestTest extends TestCase\n{\n    public function testTransformOncePerKeyWhenMethodIsGet()\n    {\n        $middleware = new TruncateInput;\n        $symfonyRequest = new SymfonyRequest([\n            'bar' => '123',\n            'baz' => 'abc',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('12', $request->get('bar'));\n            $this->assertSame('ab', $request->get('baz'));\n        });\n    }\n\n    public function testTransformOncePerKeyWhenMethodIsPost()\n    {\n        $middleware = new ManipulateInput;\n        $symfonyRequest = new SymfonyRequest(\n            [\n                'name' => 'Damian',\n                'beers' => 4,\n            ],\n            ['age' => 28]\n        );\n        $symfonyRequest->server->set('REQUEST_METHOD', 'POST');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('Damian', $request->get('name'));\n            $this->assertEquals(27, $request->get('age'));\n            $this->assertEquals(5, $request->get('beers'));\n        });\n    }\n\n    public function testTransformOncePerArrayKeysWhenMethodIsPost()\n    {\n        $middleware = new ManipulateArrayInput;\n        $symfonyRequest = new SymfonyRequest(\n            [\n                'name' => 'Damian',\n                'beers' => [4, 8, 12],\n            ],\n            [\n                'age' => [28, 56, 84],\n            ]\n        );\n        $symfonyRequest->server->set('REQUEST_METHOD', 'POST');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('Damian', $request->get('name'));\n            $this->assertEquals([27, 55, 83], $request->get('age'));\n            $this->assertEquals([5, 9, 13], $request->get('beers'));\n        });\n    }\n\n    public function testTransformOncePerKeyWhenContentTypeIsJson()\n    {\n        $middleware = new ManipulateInput;\n        $symfonyRequest = new SymfonyRequest(\n            [\n                'name' => 'Damian',\n                'beers' => 4,\n            ],\n            [],\n            [],\n            [],\n            [],\n            ['CONTENT_TYPE' => '/json'],\n            json_encode(['age' => 28])\n        );\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('Damian', $request->input('name'));\n            $this->assertEquals(27, $request->input('age'));\n            $this->assertEquals(5, $request->input('beers'));\n        });\n    }\n}\n\nclass ManipulateInput extends TransformsRequest\n{\n    protected function transform($key, $value)\n    {\n        if ($key === 'beers') {\n            $value++;\n        }\n\n        if ($key === 'age') {\n            $value--;\n        }\n\n        return $value;\n    }\n}\n\nclass ManipulateArrayInput extends TransformsRequest\n{\n    protected function transform($key, $value)\n    {\n        if (str_contains($key, 'beers')) {\n            $value++;\n        }\n\n        if (str_contains($key, 'age')) {\n            $value--;\n        }\n\n        return $value;\n    }\n}\n\nclass TruncateInput extends TransformsRequest\n{\n    protected function transform($key, $value)\n    {\n        return substr($value, 0, -1);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Http/Middleware/TrimStringsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\TrimStrings;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\nclass TrimStringsTest extends TestCase\n{\n    public function testTrimStringsIgnoringExceptAttribute()\n    {\n        $middleware = new TrimStringsWithExceptAttribute;\n        $symfonyRequest = new SymfonyRequest([\n            'abc' => '  123  ',\n            'xyz' => '  456  ',\n            'foo' => '  789  ',\n            'bar' => '  010  ',\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('123', $request->get('abc'));\n            $this->assertSame('456', $request->get('xyz'));\n            $this->assertSame('  789  ', $request->get('foo'));\n            $this->assertSame('  010  ', $request->get('bar'));\n        });\n    }\n\n    public function testTrimStringsNBSP()\n    {\n        $middleware = new TrimStrings;\n        $symfonyRequest = new SymfonyRequest([\n            // Here has some NBSP, but it still display to space.\n            // Please note, do not edit in browser\n            'abc' => '   123    ',\n            'zwnbsp' => '﻿  ha  ﻿﻿',\n            'xyz' => 'だ',\n            'foo' => 'ム',\n            'bar' => '   だ    ',\n            'baz' => '   ム    ',\n            'binary' => \" \\xE9  \",\n        ]);\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $request = Request::createFromBase($symfonyRequest);\n\n        $middleware->handle($request, function (Request $request) {\n            $this->assertSame('123', $request->get('abc'));\n            $this->assertSame('ha', $request->get('zwnbsp'));\n            $this->assertSame('だ', $request->get('xyz'));\n            $this->assertSame('ム', $request->get('foo'));\n            $this->assertSame('だ', $request->get('bar'));\n            $this->assertSame('ム', $request->get('baz'));\n            $this->assertSame(\"\\xE9\", $request->get('binary'));\n        });\n    }\n}\n\nclass TrimStringsWithExceptAttribute extends TrimStrings\n{\n    protected $except = [\n        'foo',\n        'bar',\n    ];\n}\n"
  },
  {
    "path": "tests/Foundation/Http/Middleware/ValidatePathEncodingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Http\\Middleware;\n\nuse Illuminate\\Http\\Exceptions\\MalformedUrlException;\nuse Illuminate\\Http\\Middleware\\ValidatePathEncoding;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\n\nclass ValidatePathEncodingTest extends TestCase\n{\n    #[TestWith(['/'])]\n    #[TestWith(['valid-path'])]\n    #[TestWith(['ä'])]\n    #[TestWith(['with%20space'])]\n    #[TestWith(['%E6%B1%89%E5%AD%97%E5%AD%97%E7%AC%A6%E9%9B%86'])]\n    public function testValidPathsArePassing(string $path): void\n    {\n        $middleware = new ValidatePathEncoding;\n        $symfonyRequest = new SymfonyRequest;\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $symfonyRequest->server->set('REQUEST_URI', $path);\n        $request = Request::createFromBase($symfonyRequest);\n\n        $response = $middleware->handle($request, fn () => new Response('OK'));\n\n        $this->assertSame(200, $response->status());\n        $this->assertSame('OK', $response->content());\n    }\n\n    #[TestWith(['%C0'])]\n    #[TestWith(['%c0'])]\n    public function testInvalidPathsAreFailing(string $path): void\n    {\n        $middleware = new ValidatePathEncoding;\n        $symfonyRequest = new SymfonyRequest;\n        $symfonyRequest->server->set('REQUEST_METHOD', 'GET');\n        $symfonyRequest->server->set('REQUEST_URI', $path);\n        $request = Request::createFromBase($symfonyRequest);\n\n        try {\n            $middleware->handle($request, fn () => new Response('OK'));\n\n            $this->fail('MalformedUrlExceptions should have been thrown.');\n        } catch(MalformedUrlException $e) {\n            $this->assertSame(400, $e->getStatusCode());\n            $this->assertSame('Malformed URL.', $e->getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/BootTraitsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Illuminate\\Foundation\\Testing\\Attributes\\SetUp;\nuse Illuminate\\Foundation\\Testing\\Attributes\\TearDown;\nuse Illuminate\\Foundation\\Testing\\TestCase as FoundationTestCase;\nuse Orchestra\\Testbench\\Concerns\\CreatesApplication;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\n\ntrait TestTrait\n{\n    public $setUp = false;\n    public $tearDown = false;\n\n    public function setUpTestTrait()\n    {\n        $this->setUp = true;\n    }\n\n    public function tearDownTestTrait()\n    {\n        $this->tearDown = true;\n    }\n}\n\ntrait TestTraitWithAttributes\n{\n    public $attributeSetUp = false;\n    public $attributeTearDown = false;\n\n    #[SetUp]\n    public function initializeSearch()\n    {\n        $this->attributeSetUp = true;\n    }\n\n    #[TearDown]\n    public function cleanUpSearch()\n    {\n        $this->attributeTearDown = true;\n    }\n}\n\nclass TestCaseWithTrait extends FoundationTestCase\n{\n    use CreatesApplication;\n    use TestTrait;\n}\n\nclass TestCaseWithAttributeTrait extends FoundationTestCase\n{\n    use CreatesApplication;\n    use TestTraitWithAttributes;\n}\n\nclass TestCaseWithBothTraits extends FoundationTestCase\n{\n    use CreatesApplication;\n    use TestTrait;\n    use TestTraitWithAttributes;\n}\n\nclass BootTraitsTest extends TestCase\n{\n    public function testSetUpAndTearDownTraits()\n    {\n        $testCase = new TestCaseWithTrait('foo');\n\n        $method = new ReflectionMethod($testCase, 'setUpTraits');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->setUp);\n\n        $method = new ReflectionMethod($testCase, 'callBeforeApplicationDestroyedCallbacks');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->tearDown);\n    }\n\n    public function testSetUpAndTearDownWithAttributes()\n    {\n        $testCase = new TestCaseWithAttributeTrait('foo');\n\n        $method = new ReflectionMethod($testCase, 'setUpTraits');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->attributeSetUp);\n\n        $method = new ReflectionMethod($testCase, 'callBeforeApplicationDestroyedCallbacks');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->attributeTearDown);\n    }\n\n    public function testConventionalAndAttributeTraitsWorkTogether()\n    {\n        $testCase = new TestCaseWithBothTraits('foo');\n\n        $method = new ReflectionMethod($testCase, 'setUpTraits');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->setUp);\n        $this->assertTrue($testCase->attributeSetUp);\n\n        $method = new ReflectionMethod($testCase, 'callBeforeApplicationDestroyedCallbacks');\n        $method->invoke($testCase);\n\n        $this->assertTrue($testCase->tearDown);\n        $this->assertTrue($testCase->attributeTearDown);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/Concerns/InteractsWithContainerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Foundation\\Mix;\nuse Illuminate\\Foundation\\Vite;\nuse Illuminate\\Support\\Defer\\DeferredCallbackCollection;\nuse Orchestra\\Testbench\\TestCase;\nuse stdClass;\n\nclass InteractsWithContainerTest extends TestCase\n{\n    public function testWithoutViteBindsEmptyHandlerAndReturnsInstance()\n    {\n        $instance = $this->withoutVite();\n\n        $this->assertSame('', app(Vite::class)(['resources/js/app.js'])->toHtml());\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithoutViteHandlesReactRefresh()\n    {\n        $instance = $this->withoutVite();\n\n        $this->assertSame('', app(Vite::class)->reactRefresh());\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithoutViteHandlesAsset()\n    {\n        $instance = $this->withoutVite();\n\n        $this->assertSame('', app(Vite::class)->asset('path/to/asset.png'));\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithViteRestoresOriginalHandlerAndReturnsInstance()\n    {\n        $handler = new stdClass;\n        $this->app->instance(Vite::class, $handler);\n\n        $this->withoutVite();\n        $instance = $this->withVite();\n\n        $this->assertSame($handler, resolve(Vite::class));\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithoutViteReturnsEmptyArrayForPreloadedAssets(): void\n    {\n        $instance = $this->withoutVite();\n\n        $this->assertSame([], app(Vite::class)->preloadedAssets());\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithoutMixBindsEmptyHandlerAndReturnsInstance()\n    {\n        $instance = $this->withoutMix();\n\n        $this->assertSame('', (string) mix('path/to/asset.png'));\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithMixRestoresOriginalHandlerAndReturnsInstance()\n    {\n        $handler = new stdClass;\n        $this->app->instance(Mix::class, $handler);\n\n        $this->withoutMix();\n        $instance = $this->withMix();\n\n        $this->assertSame($handler, resolve(Mix::class));\n        $this->assertSame($this, $instance);\n    }\n\n    public function testWithoutDefer()\n    {\n        $called = [];\n        defer(function () use (&$called) {\n            $called[] = 1;\n        });\n        $this->assertSame([], $called);\n\n        $instance = $this->withoutDefer();\n        defer(function () use (&$called) {\n            $called[] = 2;\n        });\n        $this->assertSame([2], $called);\n        $this->assertSame($this, $instance);\n\n        $this->withDefer();\n        $this->assertSame([2], $called);\n        $this->app[DeferredCallbackCollection::class]->invoke();\n        $this->assertSame([2, 1], $called);\n    }\n\n    public function testForgetMock()\n    {\n        $this->mock(InstanceStub::class)\n            ->shouldReceive('execute')\n            ->once()\n            ->andReturn('bar');\n\n        $this->assertSame('bar', $this->app->make(InstanceStub::class)->execute());\n\n        $this->forgetMock(InstanceStub::class);\n        $this->assertSame('foo', $this->app->make(InstanceStub::class)->execute());\n    }\n}\n\nclass InstanceStub\n{\n    public function execute()\n    {\n        return 'foo';\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/Concerns/InteractsWithViewsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithViews;\nuse Illuminate\\Testing\\TestComponent;\nuse Illuminate\\View\\Component;\nuse Orchestra\\Testbench\\TestCase;\n\nclass InteractsWithViewsTest extends TestCase\n{\n    use InteractsWithViews;\n\n    public function testBladeCorrectlyRendersString()\n    {\n        $string = (string) $this->blade('@if(true)test @endif');\n\n        $this->assertSame('test ', $string);\n    }\n\n    public function testComponentCanAccessPublicProperties()\n    {\n        $exampleComponent = new class extends Component\n        {\n            public $foo = 'bar';\n\n            public function speak()\n            {\n                return 'hello';\n            }\n\n            public function render()\n            {\n                return 'rendered content';\n            }\n        };\n\n        $component = $this->component(get_class($exampleComponent));\n\n        $this->assertSame('bar', $component->foo);\n        $this->assertSame('hello', $component->speak());\n        $component->assertSee('content');\n    }\n\n    public function testComponentMacroable()\n    {\n        TestComponent::macro('foo', fn (): string => 'bar');\n\n        $exampleComponent = new class extends Component\n        {\n            public function render()\n            {\n                return 'rendered content';\n            }\n        };\n\n        $component = $this->component(get_class($exampleComponent));\n\n        $this->assertSame('bar', $component->foo());\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/Concerns/MakesHttpRequestsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests;\nuse Illuminate\\Http\\RedirectResponse;\nuse Orchestra\\Testbench\\TestCase;\n\nclass MakesHttpRequestsTest extends TestCase\n{\n    public function testFromSetsHeaderAndSession()\n    {\n        $this->from('previous/url');\n\n        $this->assertSame('previous/url', $this->defaultHeaders['referer']);\n        $this->assertSame('previous/url', $this->app['session']->previousUrl());\n    }\n\n    public function testFromRouteSetsHeaderAndSession()\n    {\n        $router = $this->app->make(Registrar::class);\n\n        $router->get('previous/url', fn () => 'ok')->name('previous-url');\n\n        $this->fromRoute('previous-url');\n\n        $this->assertSame('http://localhost/previous/url', $this->defaultHeaders['referer']);\n        $this->assertSame('http://localhost/previous/url', $this->app['session']->previousUrl());\n    }\n\n    public function testFromRemoveHeader()\n    {\n        $this->withHeader('name', 'Milwad')->from('previous/url');\n\n        $this->assertEquals('Milwad', $this->defaultHeaders['name']);\n\n        $this->withoutHeader('name')->from('previous/url');\n\n        $this->assertArrayNotHasKey('name', $this->defaultHeaders);\n    }\n\n    public function testFromRemoveHeaders()\n    {\n        $this->withHeaders([\n            'name' => 'Milwad',\n            'foo' => 'bar',\n        ])->from('previous/url');\n\n        $this->assertEquals('Milwad', $this->defaultHeaders['name']);\n        $this->assertEquals('bar', $this->defaultHeaders['foo']);\n\n        $this->withoutHeaders(['name', 'foo'])->from('previous/url');\n\n        $this->assertArrayNotHasKey('name', $this->defaultHeaders);\n        $this->assertArrayNotHasKey('foo', $this->defaultHeaders);\n    }\n\n    public function testWithTokenSetsAuthorizationHeader()\n    {\n        $this->withToken('foobar');\n        $this->assertSame('Bearer foobar', $this->defaultHeaders['Authorization']);\n\n        $this->withToken('foobar', 'Basic');\n        $this->assertSame('Basic foobar', $this->defaultHeaders['Authorization']);\n    }\n\n    public function testWithBasicAuthSetsAuthorizationHeader()\n    {\n        $callback = function ($username, $password) {\n            return base64_encode(\"$username:$password\");\n        };\n\n        $username = 'foo';\n        $password = 'bar';\n\n        $this->withBasicAuth($username, $password);\n        $this->assertSame('Basic '.$callback($username, $password), $this->defaultHeaders['Authorization']);\n\n        $password = 'buzz';\n\n        $this->withBasicAuth($username, $password);\n        $this->assertSame('Basic '.$callback($username, $password), $this->defaultHeaders['Authorization']);\n    }\n\n    public function testWithoutTokenRemovesAuthorizationHeader()\n    {\n        $this->withToken('foobar');\n        $this->assertSame('Bearer foobar', $this->defaultHeaders['Authorization']);\n\n        $this->withoutToken();\n        $this->assertArrayNotHasKey('Authorization', $this->defaultHeaders);\n    }\n\n    public function testWithoutAndWithMiddleware()\n    {\n        $this->assertFalse($this->app->has('middleware.disable'));\n\n        $this->withoutMiddleware();\n        $this->assertTrue($this->app->has('middleware.disable'));\n        $this->assertTrue($this->app->make('middleware.disable'));\n\n        $this->withMiddleware();\n        $this->assertFalse($this->app->has('middleware.disable'));\n    }\n\n    public function testWithoutAndWithMiddlewareWithParameter()\n    {\n        $next = function ($request) {\n            return $request;\n        };\n\n        $this->assertFalse($this->app->has(MyMiddleware::class));\n        $this->assertSame(\n            'fooWithMiddleware',\n            $this->app->make(MyMiddleware::class)->handle('foo', $next)\n        );\n\n        $this->withoutMiddleware(MyMiddleware::class);\n        $this->assertTrue($this->app->has(MyMiddleware::class));\n        $this->assertSame(\n            'foo',\n            $this->app->make(MyMiddleware::class)->handle('foo', $next)\n        );\n\n        $this->withMiddleware(MyMiddleware::class);\n        $this->assertFalse($this->app->has(MyMiddleware::class));\n        $this->assertSame(\n            'fooWithMiddleware',\n            $this->app->make(MyMiddleware::class)->handle('foo', $next)\n        );\n    }\n\n    public function testWithCookieSetCookie()\n    {\n        $this->withCookie('foo', 'bar');\n\n        $this->assertCount(1, $this->defaultCookies);\n        $this->assertSame('bar', $this->defaultCookies['foo']);\n    }\n\n    public function testWithCookiesSetsCookiesAndOverwritesPreviousValues()\n    {\n        $this->withCookie('foo', 'bar');\n        $this->withCookies([\n            'foo' => 'baz',\n            'new-cookie' => 'new-value',\n        ]);\n\n        $this->assertCount(2, $this->defaultCookies);\n        $this->assertSame('baz', $this->defaultCookies['foo']);\n        $this->assertSame('new-value', $this->defaultCookies['new-cookie']);\n    }\n\n    public function testWithUnencryptedCookieSetCookie()\n    {\n        $this->withUnencryptedCookie('foo', 'bar');\n\n        $this->assertCount(1, $this->unencryptedCookies);\n        $this->assertSame('bar', $this->unencryptedCookies['foo']);\n    }\n\n    public function testWithUnencryptedCookiesSetsCookiesAndOverwritesPreviousValues()\n    {\n        $this->withUnencryptedCookie('foo', 'bar');\n        $this->withUnencryptedCookies([\n            'foo' => 'baz',\n            'new-cookie' => 'new-value',\n        ]);\n\n        $this->assertCount(2, $this->unencryptedCookies);\n        $this->assertSame('baz', $this->unencryptedCookies['foo']);\n        $this->assertSame('new-value', $this->unencryptedCookies['new-cookie']);\n    }\n\n    public function testWithoutAndWithCredentials()\n    {\n        $this->encryptCookies = false;\n\n        $this->assertSame([], $this->prepareCookiesForJsonRequest());\n\n        $this->withCredentials();\n        $this->defaultCookies = ['foo' => 'bar'];\n        $this->assertSame(['foo' => 'bar'], $this->prepareCookiesForJsonRequest());\n    }\n\n    public function testFollowingRedirects()\n    {\n        $router = $this->app->make(Registrar::class);\n        $url = $this->app->make(UrlGenerator::class);\n\n        $router->get('from', function () use ($url) {\n            return new RedirectResponse($url->to('to'));\n        });\n\n        $router->get('to', function () {\n            return 'OK';\n        });\n\n        $this->followingRedirects()\n            ->get('from')\n            ->assertOk()\n            ->assertSee('OK');\n    }\n\n    public function testFollowingRedirectsTerminatesInExpectedOrder()\n    {\n        $router = $this->app->make(Registrar::class);\n        $url = $this->app->make(UrlGenerator::class);\n\n        $callOrder = [];\n        TerminatingMiddleware::$callback = function ($request) use (&$callOrder) {\n            $callOrder[] = $request->path();\n        };\n\n        $router->get('from', function () use ($url) {\n            return new RedirectResponse($url->to('to'));\n        })->middleware(TerminatingMiddleware::class);\n\n        $router->get('to', function () {\n            return 'OK';\n        })->middleware(TerminatingMiddleware::class);\n\n        $this->followingRedirects()->get('from');\n\n        $this->assertEquals(['from', 'to'], $callOrder);\n    }\n\n    public function testWithPrecognition()\n    {\n        $this->withPrecognition();\n        $this->assertSame('true', $this->defaultHeaders['Precognition']);\n\n        $this->app->make(Registrar::class)\n            ->get('test-route', fn () => 'ok')->middleware(HandlePrecognitiveRequests::class);\n        $this->get('test-route')\n            ->assertStatus(204)\n            ->assertHeader('Precognition', 'true')\n            ->assertHeader('Precognition-Success', 'true');\n    }\n}\n\nclass MyMiddleware\n{\n    public function handle($request, $next)\n    {\n        return $next($request.'WithMiddleware');\n    }\n}\n\nclass TerminatingMiddleware\n{\n    public static $callback;\n\n    public function handle($request, $next)\n    {\n        return $next($request);\n    }\n\n    public function terminate($request, $response)\n    {\n        call_user_func(static::$callback, $request, $response);\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/DatabaseMigrationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\nuse Illuminate\\Foundation\\Console\\Kernel as ConsoleKernel;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithConsole;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabaseState;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Concerns\\ApplicationTestingHooks;\nuse Orchestra\\Testbench\\Foundation\\Application as Testbench;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Orchestra\\Testbench\\package_path;\n\nclass DatabaseMigrationsTest extends TestCase\n{\n    use ApplicationTestingHooks;\n    use DatabaseMigrations;\n    use InteractsWithConsole;\n\n    public $dropViews = false;\n\n    public $dropTypes = false;\n\n    protected function setUp(): void\n    {\n        RefreshDatabaseState::$migrated = false;\n\n        $this->afterApplicationCreated(function () {\n            $this->app['config']->set([\n                'database.default' => 'testing',\n                'database.connections.testing' => [\n                    'driver' => 'sqlite',\n                    'database' => ':memory:',\n                ],\n            ]);\n        });\n\n        $this->setUpTheApplicationTestingHooks();\n        $this->withoutMockingConsoleOutput();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownTheApplicationTestingHooks();\n\n        RefreshDatabaseState::$migrated = false;\n\n        parent::tearDown();\n    }\n\n    protected function refreshApplication()\n    {\n        $this->app = Testbench::create(\n            basePath: package_path('vendor/orchestra/testbench-core/laravel'),\n        );\n    }\n\n    public function testRefreshTestDatabaseDefault()\n    {\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => false,\n                '--drop-types' => false,\n                '--seed' => false,\n            ]);\n\n        $this->runDatabaseMigrations();\n    }\n\n    public function testRefreshTestDatabaseWithDropViewsOption()\n    {\n        $this->dropViews = true;\n\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => true,\n                '--drop-types' => false,\n                '--seed' => false,\n            ]);\n\n        $this->runDatabaseMigrations();\n    }\n\n    public function testRefreshTestDatabaseWithDropTypesOption()\n    {\n        $this->dropTypes = true;\n\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => false,\n                '--drop-types' => true,\n                '--seed' => false,\n            ]);\n\n        $this->runDatabaseMigrations();\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/DatabaseTransactionsManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseTransactionsManager;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseTransactionsManagerTest extends TestCase\n{\n    public function testItExecutesCallbacksImmediatelyIfThereIsOnlyOneTransaction()\n    {\n        $testObject = new TestingDatabaseTransactionsManagerTestObject;\n        $manager = new DatabaseTransactionsManager([null]);\n\n        $manager->begin('foo', 1);\n\n        $manager->addCallback(fn () => $testObject->handle());\n\n        $this->assertTrue($testObject->ran);\n        $this->assertEquals(1, $testObject->runs);\n    }\n\n    public function testItIgnoresTheBaseTransactionForCallbackApplicableTransactions()\n    {\n        $manager = new DatabaseTransactionsManager([null]);\n\n        $manager->begin('foo', 1);\n        $manager->begin('foo', 2);\n\n        $this->assertCount(1, $manager->callbackApplicableTransactions());\n        $this->assertEquals(2, $manager->callbackApplicableTransactions()[0]->level);\n    }\n\n    public function testCommittingDoesNotRemoveTheBasePendingTransaction()\n    {\n        $manager = new DatabaseTransactionsManager([null]);\n\n        $manager->begin('foo', 1);\n\n        $manager->begin('foo', 2);\n        $manager->commit('foo', 2, 1);\n\n        $this->assertCount(0, $manager->callbackApplicableTransactions());\n\n        $manager->begin('foo', 2);\n\n        $this->assertCount(1, $manager->callbackApplicableTransactions());\n        $this->assertEquals(2, $manager->callbackApplicableTransactions()[0]->level);\n    }\n\n    public function testItExecutesCallbacksForTheSecondTransaction()\n    {\n        $testObject = new TestingDatabaseTransactionsManagerTestObject;\n        $manager = new DatabaseTransactionsManager([null]);\n        $manager->begin('foo', 1);\n        $manager->begin('foo', 2);\n\n        $manager->addCallback(fn () => $testObject->handle());\n\n        $this->assertFalse($testObject->ran);\n\n        $manager->commit('foo', 2, 1);\n        $manager->commit('foo', 1, 0);\n        $this->assertTrue($testObject->ran);\n        $this->assertEquals(1, $testObject->runs);\n    }\n\n    public function testItExecutesTransactionCallbacksAtLevelOne()\n    {\n        $manager = new DatabaseTransactionsManager([null]);\n\n        $this->assertFalse($manager->afterCommitCallbacksShouldBeExecuted(0));\n        $this->assertTrue($manager->afterCommitCallbacksShouldBeExecuted(1));\n        $this->assertFalse($manager->afterCommitCallbacksShouldBeExecuted(2));\n    }\n\n    public function testSkipsTheNumberOfConnectionsTransacting()\n    {\n        $manager = new DatabaseTransactionsManager([null]);\n\n        $manager->begin('foo', 1);\n        $manager->begin('foo', 2);\n\n        $this->assertCount(1, $manager->callbackApplicableTransactions());\n    }\n}\n\nclass TestingDatabaseTransactionsManagerTestObject\n{\n    public $ran = false;\n\n    public $runs = 0;\n\n    public function handle()\n    {\n        $this->ran = true;\n        $this->runs++;\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/DatabaseTruncationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Schema\\Builder;\nuse Illuminate\\Database\\Schema\\PostgresBuilder;\nuse Illuminate\\Foundation\\Testing\\DatabaseTruncation;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DatabaseTruncationTest extends TestCase\n{\n    use DatabaseTruncation;\n\n    private ?array $app;\n\n    private ?array $tablesToTruncate = null;\n\n    private ?array $exceptTables = null;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->app['config'] = new Repository([\n            'database' => [\n                'migrations' => [\n                    'table' => 'migrations',\n                ],\n            ],\n        ]);\n    }\n\n    protected function tearDown(): void\n    {\n        $this->app = null;\n        static::$allTables = [];\n        $this->tablesToTruncate = null;\n        $this->exceptTables = null;\n\n        parent::tearDown();\n    }\n\n    public function testTruncateTables()\n    {\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => null, 'name' => 'foo', 'schema_qualified_name' => 'foo'],\n            ['schema' => null, 'name' => 'bar', 'schema_qualified_name' => 'bar'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['foo', 'bar'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithTablesToTruncateProperty()\n    {\n        $this->tablesToTruncate = ['foo', 'bar', 'qux'];\n\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => null, 'name' => 'migrations', 'schema_qualified_name' => 'migrations'],\n            ['schema' => null, 'name' => 'foo', 'schema_qualified_name' => 'foo'],\n            ['schema' => null, 'name' => 'bar', 'schema_qualified_name' => 'bar'],\n            ['schema' => null, 'name' => 'baz', 'schema_qualified_name' => 'baz'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['foo', 'bar'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithExceptTablesProperty()\n    {\n        $this->exceptTables = ['baz', 'qux'];\n\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => null, 'name' => 'migrations', 'schema_qualified_name' => 'migrations'],\n            ['schema' => null, 'name' => 'foo', 'schema_qualified_name' => 'foo'],\n            ['schema' => null, 'name' => 'bar', 'schema_qualified_name' => 'bar'],\n            ['schema' => null, 'name' => 'baz', 'schema_qualified_name' => 'baz'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['foo', 'bar'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithSchema()\n    {\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => 'public', 'name' => 'migrations', 'schema_qualified_name' => 'public.migrations'],\n            ['schema' => 'public', 'name' => 'foo', 'schema_qualified_name' => 'public.foo'],\n            ['schema' => 'public', 'name' => 'bar', 'schema_qualified_name' => 'public.bar'],\n            ['schema' => 'private', 'name' => 'migrations', 'schema_qualified_name' => 'private.migrations'],\n            ['schema' => 'private', 'name' => 'foo', 'schema_qualified_name' => 'private.foo'],\n            ['schema' => 'private', 'name' => 'baz', 'schema_qualified_name' => 'private.baz'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['public.foo', 'public.bar', 'private.foo', 'private.baz'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithSchemaTablesToTruncateProperty()\n    {\n        $this->tablesToTruncate = ['foo', 'public.bar'];\n\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => 'public', 'name' => 'migrations', 'schema_qualified_name' => 'public.migrations'],\n            ['schema' => 'public', 'name' => 'foo', 'schema_qualified_name' => 'public.foo'],\n            ['schema' => 'public', 'name' => 'bar', 'schema_qualified_name' => 'public.bar'],\n            ['schema' => 'public', 'name' => 'baz', 'schema_qualified_name' => 'public.baz'],\n            ['schema' => 'private', 'name' => 'migrations', 'schema_qualified_name' => 'private.migrations'],\n            ['schema' => 'private', 'name' => 'foo', 'schema_qualified_name' => 'private.foo'],\n            ['schema' => 'private', 'name' => 'bar', 'schema_qualified_name' => 'private.bar'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['public.foo', 'public.bar', 'private.foo'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithSchemaAndExceptTablesProperty()\n    {\n        $this->exceptTables = ['foo', 'public.bar'];\n\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => 'public', 'name' => 'migrations', 'schema_qualified_name' => 'public.migrations'],\n            ['schema' => 'public', 'name' => 'foo', 'schema_qualified_name' => 'public.foo'],\n            ['schema' => 'public', 'name' => 'bar', 'schema_qualified_name' => 'public.bar'],\n            ['schema' => 'public', 'name' => 'baz', 'schema_qualified_name' => 'public.baz'],\n            ['schema' => 'private', 'name' => 'migrations', 'schema_qualified_name' => 'private.migrations'],\n            ['schema' => 'private', 'name' => 'foo', 'schema_qualified_name' => 'private.foo'],\n            ['schema' => 'private', 'name' => 'bar', 'schema_qualified_name' => 'private.bar'],\n        ]);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['public.baz', 'private.bar'], $truncatedTables);\n    }\n\n    public function testTruncateTablesWithConnectionPrefix()\n    {\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => 'public', 'name' => 'my_migrations', 'schema_qualified_name' => 'public.my_migrations'],\n            ['schema' => 'public', 'name' => 'my_foo', 'schema_qualified_name' => 'public.my_foo'],\n            ['schema' => 'public', 'name' => 'my_baz', 'schema_qualified_name' => 'public.my_baz'],\n            ['schema' => 'private', 'name' => 'my_migrations', 'schema_qualified_name' => 'private.my_migrations'],\n            ['schema' => 'private', 'name' => 'my_foo', 'schema_qualified_name' => 'private.my_foo'],\n        ], 'my_');\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['public.my_foo', 'public.my_baz', 'private.my_foo'], $truncatedTables);\n    }\n\n    public function testTruncateTablesOnPgsqlWithSearchPath()\n    {\n        $connection = $this->arrangeConnection($truncatedTables, [\n            ['schema' => 'public', 'name' => 'migrations', 'schema_qualified_name' => 'public.migrations'],\n            ['schema' => 'public', 'name' => 'foo', 'schema_qualified_name' => 'public.foo'],\n            ['schema' => 'public', 'name' => 'bar', 'schema_qualified_name' => 'public.bar'],\n            ['schema' => 'my_schema', 'name' => 'foo', 'schema_qualified_name' => 'my_schema.foo'],\n            ['schema' => 'my_schema', 'name' => 'baz', 'schema_qualified_name' => 'my_schema.baz'],\n            ['schema' => 'private', 'name' => 'migrations', 'schema_qualified_name' => 'private.migrations'],\n            ['schema' => 'private', 'name' => 'foo', 'schema_qualified_name' => 'private.foo'],\n            ['schema' => 'private', 'name' => 'baz', 'schema_qualified_name' => 'private.baz'],\n        ], '', PostgresBuilder::class, ['my_schema', 'public']);\n\n        $this->truncateTablesForConnection($connection, 'test');\n\n        $this->assertEquals(['public.foo', 'public.bar', 'my_schema.foo', 'my_schema.baz'], $truncatedTables);\n    }\n\n    private function arrangeConnection(\n        ?array &$actual, array $allTables, string $prefix = '', ?string $builder = null, ?array $schemas = []\n    ): Connection {\n        $actual = [];\n\n        $schema = m::mock($builder ?? Builder::class);\n        $schema->shouldReceive('getTables')->with($schemas)->once()->andReturn(\n            empty($schemas)\n                ? $allTables\n                : array_filter($allTables, fn ($table) => in_array($table['schema'], $schemas))\n        );\n        $schema->shouldReceive('getCurrentSchemaListing')->once()->andReturn($schemas);\n\n        $connection = m::mock(Connection::class);\n        $connection->shouldReceive('getTablePrefix')->andReturn($prefix);\n        $connection->shouldReceive('getEventDispatcher')->once()->andReturn($dispatcher = m::mock(Dispatcher::class));\n        $connection->shouldReceive('unsetEventDispatcher')->once();\n        $connection->shouldReceive('setEventDispatcher')->once()->with($dispatcher);\n        $connection->shouldReceive('getSchemaBuilder')->once()->andReturn($schema);\n        $connection->shouldReceive('withoutTablePrefix')->andReturnUsing(function ($callback) use ($connection) {\n            $callback($connection);\n        });\n        $connection->shouldReceive('table')\n            ->andReturnUsing(function (string $tableName) use (&$actual) {\n                $actual[] = $tableName;\n\n                $table = m::mock();\n                $table->shouldReceive('exists')->andReturnTrue();\n                $table->shouldReceive('truncate');\n\n                return $table;\n            });\n\n        return $connection;\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/RefreshDatabaseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernelContract;\nuse Illuminate\\Foundation\\Console\\Kernel as ConsoleKernel;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithConsole;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabaseState;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Concerns\\ApplicationTestingHooks;\nuse Orchestra\\Testbench\\Foundation\\Application as Testbench;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Orchestra\\Testbench\\package_path;\n\nclass RefreshDatabaseTest extends TestCase\n{\n    use ApplicationTestingHooks;\n    use InteractsWithConsole;\n    use RefreshDatabase;\n\n    public $dropViews = false;\n\n    public $dropTypes = false;\n\n    protected function setUp(): void\n    {\n        RefreshDatabaseState::$migrated = false;\n\n        $this->setUpTheApplicationTestingHooks();\n        $this->withoutMockingConsoleOutput();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownTheApplicationTestingHooks();\n\n        RefreshDatabaseState::$migrated = false;\n\n        parent::tearDown();\n    }\n\n    protected function refreshApplication()\n    {\n        $this->app = Testbench::create(\n            basePath: package_path('vendor/orchestra/testbench-core/laravel'),\n        );\n    }\n\n    public function testRefreshTestDatabaseDefault()\n    {\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => false,\n                '--drop-types' => false,\n                '--seed' => false,\n            ]);\n\n        $this->refreshTestDatabase();\n    }\n\n    public function testRefreshTestDatabaseWithDropViewsOption()\n    {\n        $this->dropViews = true;\n\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => true,\n                '--drop-types' => false,\n                '--seed' => false,\n            ]);\n\n        $this->refreshTestDatabase();\n    }\n\n    public function testRefreshTestDatabaseWithDropTypesOption()\n    {\n        $this->dropTypes = true;\n\n        $this->app->instance(ConsoleKernelContract::class, $kernel = m::spy(ConsoleKernel::class));\n\n        $kernel->shouldReceive('call')\n            ->once()\n            ->with('migrate:fresh', [\n                '--drop-views' => false,\n                '--drop-types' => true,\n                '--seed' => false,\n            ]);\n\n        $this->refreshTestDatabase();\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/Traits/CanConfigureMigrationCommandsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing\\Traits;\n\nuse Illuminate\\Foundation\\Testing\\Traits\\CanConfigureMigrationCommands;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\n\nclass CanConfigureMigrationCommandsTest extends TestCase\n{\n    protected $traitObject;\n\n    protected function setUp(): void\n    {\n        $this->traitObject = new CanConfigureMigrationCommandsTestMockClass();\n    }\n\n    private function __reflectAndSetupAccessibleForProtectedTraitMethod($methodName)\n    {\n        return new ReflectionMethod(\n            get_class($this->traitObject),\n            $methodName\n        );\n    }\n\n    public function testMigrateFreshUsingDefault(): void\n    {\n        $migrateFreshUsingReflection = $this->__reflectAndSetupAccessibleForProtectedTraitMethod('migrateFreshUsing');\n\n        $expected = [\n            '--drop-views' => false,\n            '--drop-types' => false,\n            '--seed' => false,\n        ];\n\n        $this->assertEquals($expected, $migrateFreshUsingReflection->invoke($this->traitObject));\n    }\n\n    public function testMigrateFreshUsingWithPropertySets(): void\n    {\n        $migrateFreshUsingReflection = $this->__reflectAndSetupAccessibleForProtectedTraitMethod('migrateFreshUsing');\n\n        $expected = [\n            '--drop-views' => true,\n            '--drop-types' => false,\n            '--seed' => false,\n        ];\n\n        $this->traitObject->dropViews = true;\n\n        $this->assertEquals($expected, $migrateFreshUsingReflection->invoke($this->traitObject));\n\n        $expected = [\n            '--drop-views' => false,\n            '--drop-types' => true,\n            '--seed' => false,\n        ];\n\n        $this->traitObject->dropViews = false;\n        $this->traitObject->dropTypes = true;\n\n        $this->assertEquals($expected, $migrateFreshUsingReflection->invoke($this->traitObject));\n\n        $expected = [\n            '--drop-views' => true,\n            '--drop-types' => true,\n            '--seed' => false,\n        ];\n\n        $this->traitObject->dropViews = true;\n        $this->traitObject->dropTypes = true;\n\n        $this->assertEquals($expected, $migrateFreshUsingReflection->invoke($this->traitObject));\n    }\n}\n\nclass CanConfigureMigrationCommandsTestMockClass\n{\n    use CanConfigureMigrationCommands;\n\n    public $dropViews = false;\n\n    public $dropTypes = false;\n}\n"
  },
  {
    "path": "tests/Foundation/Testing/WormholeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Foundation\\Testing;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Foundation\\Testing\\Wormhole;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse PHPUnit\\Framework\\TestCase;\n\nclass WormholeTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Date::useDefault();\n\n        parent::tearDown();\n    }\n\n    public function testCanTravelBackToPresent()\n    {\n        // Preserve the timelines we want to compare the reality with...\n        $present = Date::now();\n        $future = Date::now()->addDays(10);\n\n        // Travel in time...\n        (new Wormhole(10))->days();\n\n        // Assert we are now in the future...\n        $this->assertEquals($future->format('Y-m-d'), Date::now()->format('Y-m-d'));\n\n        // Assert we can go back to the present...\n        $this->assertEquals($present->format('Y-m-d'), Wormhole::back()->format('Y-m-d'));\n    }\n\n    public function testCarbonImmutableCompatibility()\n    {\n        // Tell the Date Factory to use CarbonImmutable...\n        Date::use(CarbonImmutable::class);\n\n        // Record what time it is in 10 days...\n        $present = Date::now();\n        $future = $present->addDays(10);\n\n        // Travel in time...\n        (new Wormhole(10))->days();\n\n        // Assert that the present time didn't get mutated...\n        $this->assertNotEquals($future->format('Y-m-d'), $present->format('Y-m-d'));\n\n        // Assert the time travel was successful...\n        $this->assertEquals($future->format('Y-m-d'), Date::now()->format('Y-m-d'));\n    }\n\n    public function testItCanTravelByMicroseconds()\n    {\n        Carbon::setTestNow(Carbon::parse('2000-01-01 00:00:00')->startOfSecond());\n\n        (new Wormhole(1))->microsecond();\n        $this->assertSame('2000-01-01 00:00:00.000001', Date::now()->format('Y-m-d H:i:s.u'));\n\n        (new Wormhole(5))->microseconds();\n        $this->assertSame('2000-01-01 00:00:00.000006', Date::now()->format('Y-m-d H:i:s.u'));\n\n        Carbon::setTestnow();\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/fixtures/always-dusk-ask-strategy.php",
    "content": "<?php\n\nreturn fn ($command) => 'dusk';\n"
  },
  {
    "path": "tests/Foundation/fixtures/bad-return-strategy.php",
    "content": "<?php\n\nreturn 9; // should return a callable\n"
  },
  {
    "path": "tests/Foundation/fixtures/bad-syntax-strategy.php",
    "content": "<?php\n\n); // bad syntax\n\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/app.php",
    "content": "<?php\n\nreturn [\n    'foo' => 'bar',\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/broadcasting.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'broadcasting',\n\n    'default' => 'overwrite',\n\n    'connections' => [\n        'reverb' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/cache.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'cache',\n\n    'default' => 'overwrite',\n\n    'stores' => [\n        'array' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/custom.php",
    "content": "<?php\n\n$name = 'bar';\n\nreturn [\n    'foo' => $name,\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/database.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'database',\n\n    'default' => 'overwrite',\n\n    'connections' => [\n        'mysql' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/filesystems.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'filesystems',\n\n    'default' => 'overwrite',\n\n    'disks' => [\n        'local' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/logging.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'logging',\n\n    'default' => 'overwrite',\n\n    'channels' => [\n        'stack' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/mail.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'mail',\n\n    'default' => 'overwrite',\n\n    'mailers' => [\n        'smtp' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/config/queue.php",
    "content": "<?php\n\nreturn [\n    'custom_option' => 'queue',\n\n    'default' => 'overwrite',\n\n    'connections' => [\n        'database' => [\n            'overwrite' => true,\n        ],\n\n        'new' => [\n            'merge' => true,\n        ],\n    ],\n];\n"
  },
  {
    "path": "tests/Foundation/fixtures/docs.json",
    "content": "{\n    \"pages\": {\n        \"installation\": {\n            \"title\": \"Installation\",\n            \"sections\": {}\n        },\n        \"views\": {\n            \"title\": \"Views\",\n            \"sections\": {}\n        },\n        \"validation\": {\n            \"title\": \"Validation\",\n            \"sections\": {}\n        },\n        \"filesystem\": {\n            \"title\": \"File Storage\",\n            \"sections\": {}\n        },\n        \"localization\": {\n            \"title\": \"Localization\",\n            \"sections\": {}\n        },\n        \"eloquent\": {\n            \"title\": \"Eloquent: Getting Started\",\n            \"sections\": {\n            }\n        },\n        \"eloquent-collections\": {\n            \"title\": \"Eloquent: Collections\",\n            \"sections\": {\n                \"introduction\": {\n                    \"title\": \"Introduction\"\n                },\n                \"eloquent-collection-conversion\": {\n                    \"title\": \"Eloquent Collection Conversion\"\n                },\n                \"available-methods\": {\n                    \"title\": \"Available Methods\"\n                },\n                \"method-append\": {\n                    \"title\": \"`append($attributes)` {.collection-method .first-collection-method}\"\n                },\n                \"method-contains\": {\n                    \"title\": \"`contains($key, $operator = null, $value = null)` {.collection-method}\"\n                },\n                \"method-diff\": {\n                    \"title\": \"`diff($items)` {.collection-method}\"\n                },\n                \"method-except\": {\n                    \"title\": \"`except($keys)` {.collection-method}\"\n                },\n                \"method-find\": {\n                    \"title\": \"`find($key)` {.collection-method}\"\n                },\n                \"method-fresh\": {\n                    \"title\": \"`fresh($with = [])` {.collection-method}\"\n                },\n                \"method-intersect\": {\n                    \"title\": \"`intersect($items)` {.collection-method}\"\n                },\n                \"method-load\": {\n                    \"title\": \"`load($relations)` {.collection-method}\"\n                },\n                \"method-loadMissing\": {\n                    \"title\": \"`loadMissing($relations)` {.collection-method}\"\n                },\n                \"method-modelKeys\": {\n                    \"title\": \"`modelKeys()` {.collection-method}\"\n                },\n                \"method-makeVisible\": {\n                    \"title\": \"`makeVisible($attributes)` {.collection-method}\"\n                },\n                \"method-makeHidden\": {\n                    \"title\": \"`makeHidden($attributes)` {.collection-method}\"\n                },\n                \"method-only\": {\n                    \"title\": \"`only($keys)` {.collection-method}\"\n                },\n                \"method-toquery\": {\n                    \"title\": \"`toQuery()` {.collection-method}\"\n                },\n                \"method-unique\": {\n                    \"title\": \"`unique($key = null, $strict = false)` {.collection-method}\"\n                },\n                \"custom-collections\": {\n                    \"title\": \"Custom Collections\"\n                }\n            }\n        },\n        \"dusk\": {\n            \"title\": \"Laravel Dusk\",\n            \"sections\": {}\n        }\n    }\n}\n\n"
  },
  {
    "path": "tests/Foundation/fixtures/exception-throwing-strategy.php",
    "content": "<?php\n\nreturn fn () => throw new RuntimeException('strategy failed');\n"
  },
  {
    "path": "tests/Foundation/fixtures/fake-compiled-view-without-source-map.php",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <title></title>\n</head>\n<body>\n"
  },
  {
    "path": "tests/Foundation/fixtures/fake-compiled-view.php",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <title></title>\n</head>\n<body>\n<?php /**PATH /my-work-directory/resources/views/welcome.blade.php ENDPATH**/ ?>\n"
  },
  {
    "path": "tests/Foundation/fixtures/jetstream-manifest.json",
    "content": "{\n  \"resources/js/app.js\": {\n    \"file\": \"assets/app.a26d8e4d.js\",\n    \"src\": \"resources/js/app.js\",\n    \"isEntry\": true,\n    \"dynamicImports\": [\n      \"resources/js/Pages/API/Index.vue\",\n      \"resources/js/Pages/API/Partials/ApiTokenManager.vue\",\n      \"resources/js/Pages/Auth/ConfirmPassword.vue\",\n      \"resources/js/Pages/Auth/ForgotPassword.vue\",\n      \"resources/js/Pages/Auth/Login.vue\",\n      \"resources/js/Pages/Auth/Register.vue\",\n      \"resources/js/Pages/Auth/ResetPassword.vue\",\n      \"resources/js/Pages/Auth/TwoFactorChallenge.vue\",\n      \"resources/js/Pages/Auth/VerifyEmail.vue\",\n      \"resources/js/Pages/Dashboard.vue\",\n      \"resources/js/Pages/PrivacyPolicy.vue\",\n      \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n      \"resources/js/Pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue\",\n      \"resources/js/Pages/Profile/Partials/TwoFactorAuthenticationForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n      \"resources/js/Pages/Profile/Show.vue\",\n      \"resources/js/Pages/TermsOfService.vue\",\n      \"resources/js/Pages/Welcome.vue\"\n    ],\n    \"css\": [\n      \"assets/app.9842b564.css\"\n    ]\n  },\n  \"resources/js/Pages/API/Index.vue\": {\n    \"file\": \"assets/Index.58f39f21.js\",\n    \"src\": \"resources/js/Pages/API/Index.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/Pages/API/Partials/ApiTokenManager.vue\",\n      \"_AppLayout.e6a6a429.js\",\n      \"resources/js/app.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"_Checkbox.33ba23f3.js\",\n      \"_DangerButton.12acbcf1.js\",\n      \"_FormSection.64ccd4c1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_SectionBorder.b8ebe4c3.js\"\n    ]\n  },\n  \"resources/js/Pages/API/Partials/ApiTokenManager.vue\": {\n    \"file\": \"assets/ApiTokenManager.b6097283.js\",\n    \"src\": \"resources/js/Pages/API/Partials/ApiTokenManager.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_Checkbox.33ba23f3.js\",\n      \"_DangerButton.12acbcf1.js\",\n      \"_FormSection.64ccd4c1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_SectionBorder.b8ebe4c3.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"_AppLayout.e6a6a429.js\": {\n    \"file\": \"assets/AppLayout.e6a6a429.js\",\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"_ActionMessage.f06648ac.js\": {\n    \"file\": \"assets/ActionMessage.f06648ac.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_DialogModal.957bf006.js\": {\n    \"file\": \"assets/DialogModal.957bf006.js\",\n    \"imports\": [\n      \"_SectionTitle.060e9618.js\",\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_Checkbox.33ba23f3.js\": {\n    \"file\": \"assets/Checkbox.33ba23f3.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_DangerButton.12acbcf1.js\": {\n    \"file\": \"assets/DangerButton.12acbcf1.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_FormSection.64ccd4c1.js\": {\n    \"file\": \"assets/FormSection.64ccd4c1.js\",\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_SectionTitle.060e9618.js\"\n    ]\n  },\n  \"_TextInput.e2f0248c.js\": {\n    \"file\": \"assets/TextInput.e2f0248c.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_InputLabel.d245ec4e.js\": {\n    \"file\": \"assets/InputLabel.d245ec4e.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_PrimaryButton.931d2859.js\": {\n    \"file\": \"assets/PrimaryButton.931d2859.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_SecondaryButton.0f3618fc.js\": {\n    \"file\": \"assets/SecondaryButton.0f3618fc.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_SectionBorder.b8ebe4c3.js\": {\n    \"file\": \"assets/SectionBorder.b8ebe4c3.js\",\n    \"imports\": [\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_SectionTitle.060e9618.js\": {\n    \"file\": \"assets/SectionTitle.060e9618.js\",\n    \"imports\": [\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"resources/js/app.js\"\n    ]\n  },\n  \"__plugin-vue_export-helper.cdc0426e.js\": {\n    \"file\": \"assets/_plugin-vue_export-helper.cdc0426e.js\"\n  },\n  \"resources/js/Pages/Auth/ConfirmPassword.vue\": {\n    \"file\": \"assets/ConfirmPassword.0f0db8fa.js\",\n    \"src\": \"resources/js/Pages/Auth/ConfirmPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"_AuthenticationCard.47ef70cc.js\": {\n    \"file\": \"assets/AuthenticationCard.47ef70cc.js\",\n    \"imports\": [\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"resources/js/app.js\"\n    ]\n  },\n  \"_AuthenticationCardLogo.9999a373.js\": {\n    \"file\": \"assets/AuthenticationCardLogo.9999a373.js\",\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/ForgotPassword.vue\": {\n    \"file\": \"assets/ForgotPassword.5e46b816.js\",\n    \"src\": \"resources/js/Pages/Auth/ForgotPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/Login.vue\": {\n    \"file\": \"assets/Login.8c52c4a3.js\",\n    \"src\": \"resources/js/Pages/Auth/Login.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_Checkbox.33ba23f3.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/Register.vue\": {\n    \"file\": \"assets/Register.f69e0819.js\",\n    \"src\": \"resources/js/Pages/Auth/Register.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_Checkbox.33ba23f3.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/ResetPassword.vue\": {\n    \"file\": \"assets/ResetPassword.507eb03d.js\",\n    \"src\": \"resources/js/Pages/Auth/ResetPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/TwoFactorChallenge.vue\": {\n    \"file\": \"assets/TwoFactorChallenge.60db078c.js\",\n    \"src\": \"resources/js/Pages/Auth/TwoFactorChallenge.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/VerifyEmail.vue\": {\n    \"file\": \"assets/VerifyEmail.fc56de65.js\",\n    \"src\": \"resources/js/Pages/Auth/VerifyEmail.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCard.47ef70cc.js\",\n      \"_AuthenticationCardLogo.9999a373.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Dashboard.vue\": {\n    \"file\": \"assets/Dashboard.50e1603d.js\",\n    \"src\": \"resources/js/Pages/Dashboard.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_AppLayout.e6a6a429.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"resources/js/app.js\"\n    ]\n  },\n  \"resources/js/Pages/PrivacyPolicy.vue\": {\n    \"file\": \"assets/PrivacyPolicy.c2abeb25.js\",\n    \"src\": \"resources/js/Pages/PrivacyPolicy.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCardLogo.9999a373.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\": {\n    \"file\": \"assets/DeleteUserForm.9a6b1c68.js\",\n    \"src\": \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_DangerButton.12acbcf1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue\": {\n    \"file\": \"assets/LogoutOtherBrowserSessionsForm.6fa01927.js\",\n    \"src\": \"resources/js/Pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/TwoFactorAuthenticationForm.vue\": {\n    \"file\": \"assets/TwoFactorAuthenticationForm.494ff4de.js\",\n    \"src\": \"resources/js/Pages/Profile/Partials/TwoFactorAuthenticationForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_DangerButton.12acbcf1.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\": {\n    \"file\": \"assets/UpdatePasswordForm.a8718b3a.js\",\n    \"src\": \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_FormSection.64ccd4c1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\": {\n    \"file\": \"assets/UpdateProfileInformationForm.dc291001.js\",\n    \"src\": \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_FormSection.64ccd4c1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Show.vue\": {\n    \"file\": \"assets/Show.836f42f9.js\",\n    \"src\": \"resources/js/Pages/Profile/Show.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_AppLayout.e6a6a429.js\",\n      \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n      \"resources/js/Pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue\",\n      \"_SectionBorder.b8ebe4c3.js\",\n      \"resources/js/Pages/Profile/Partials/TwoFactorAuthenticationForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n      \"resources/js/app.js\",\n      \"__plugin-vue_export-helper.cdc0426e.js\",\n      \"_DialogModal.957bf006.js\",\n      \"_SectionTitle.060e9618.js\",\n      \"_DangerButton.12acbcf1.js\",\n      \"_TextInput.e2f0248c.js\",\n      \"_SecondaryButton.0f3618fc.js\",\n      \"_ActionMessage.f06648ac.js\",\n      \"_PrimaryButton.931d2859.js\",\n      \"_InputLabel.d245ec4e.js\",\n      \"_FormSection.64ccd4c1.js\"\n    ]\n  },\n  \"resources/js/Pages/TermsOfService.vue\": {\n    \"file\": \"assets/TermsOfService.a0750aab.js\",\n    \"src\": \"resources/js/Pages/TermsOfService.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\",\n      \"_AuthenticationCardLogo.9999a373.js\"\n    ]\n  },\n  \"resources/js/Pages/Welcome.vue\": {\n    \"file\": \"assets/Welcome.78edc4a1.js\",\n    \"src\": \"resources/js/Pages/Welcome.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"resources/js/app.js\"\n    ]\n  },\n  \"resources/js/app.css\": {\n    \"file\": \"assets/app.9842b564.css\",\n    \"src\": \"resources/js/app.css\"\n  }\n}\n\n"
  },
  {
    "path": "tests/Foundation/fixtures/laravel1/composer.json",
    "content": "{\n    \"autoload\": {\n        \"psr-4\": {\n            \"Laravel\\\\One\\\\\": \"app/\"\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/fixtures/laravel2/composer.json",
    "content": "{\n    \"autoload\": {\n        \"psr-4\": {\n            \"Laravel\\\\Two\\\\\": \"app/\"\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Foundation/fixtures/open-strategy.php",
    "content": "<?php\n\nuse Symfony\\Component\\Process\\Process;\n\nreturn function ($url) {\n    Process::fromShellCommandline(sprintf('echo %s > %s', escapeshellarg($url.'?expected-query=1'), escapeshellarg($GLOBALS['open-strategy-output-path'])))->run();\n};\n"
  },
  {
    "path": "tests/Foundation/fixtures/prefetching-manifest.json",
    "content": "{\n  \"_ApplicationLogo-BhIZH06z.js\": {\n    \"file\": \"assets/ApplicationLogo-BhIZH06z.js\",\n    \"name\": \"ApplicationLogo\",\n    \"imports\": [\n      \"__plugin-vue_export-helper-DlAUqK2U.js\",\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"_AuthenticatedLayout-DfWF52N1.js\": {\n    \"file\": \"assets/AuthenticatedLayout-DfWF52N1.js\",\n    \"name\": \"AuthenticatedLayout\",\n    \"imports\": [\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"_GuestLayout-BY3LC-73.js\": {\n    \"file\": \"assets/GuestLayout-BY3LC-73.js\",\n    \"name\": \"GuestLayout\",\n    \"imports\": [\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"_PrimaryButton-DuXwr-9M.js\": {\n    \"file\": \"assets/PrimaryButton-DuXwr-9M.js\",\n    \"name\": \"PrimaryButton\",\n    \"imports\": [\n      \"__plugin-vue_export-helper-DlAUqK2U.js\",\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"_TextInput-C8CCB_U_.js\": {\n    \"file\": \"assets/TextInput-C8CCB_U_.js\",\n    \"name\": \"TextInput\",\n    \"imports\": [\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"__plugin-vue_export-helper-DlAUqK2U.js\": {\n    \"file\": \"assets/_plugin-vue_export-helper-DlAUqK2U.js\",\n    \"name\": \"_plugin-vue_export-helper\"\n  },\n  \"_index-!~{00f}~.js\": {\n    \"file\": \"assets/index-B3s1tYeC.css\",\n    \"src\": \"_index-!~{00f}~.js\"\n  },\n  \"_index-BSdK3M0e.js\": {\n    \"file\": \"assets/index-BSdK3M0e.js\",\n    \"name\": \"index\",\n    \"css\": [\n      \"assets/index-B3s1tYeC.css\"\n    ]\n  },\n  \"resources/js/Pages/Auth/ConfirmPassword.vue\": {\n    \"file\": \"assets/ConfirmPassword-CDwcgU8E.js\",\n    \"name\": \"ConfirmPassword\",\n    \"src\": \"resources/js/Pages/Auth/ConfirmPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/ForgotPassword.vue\": {\n    \"file\": \"assets/ForgotPassword-B0WWE0BO.js\",\n    \"name\": \"ForgotPassword\",\n    \"src\": \"resources/js/Pages/Auth/ForgotPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/Login.vue\": {\n    \"file\": \"assets/Login-DAFSdGSW.js\",\n    \"name\": \"Login\",\n    \"src\": \"resources/js/Pages/Auth/Login.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/Register.vue\": {\n    \"file\": \"assets/Register-CfYQbTlA.js\",\n    \"name\": \"Register\",\n    \"src\": \"resources/js/Pages/Auth/Register.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/ResetPassword.vue\": {\n    \"file\": \"assets/ResetPassword-BNl7a4X1.js\",\n    \"name\": \"ResetPassword\",\n    \"src\": \"resources/js/Pages/Auth/ResetPassword.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Auth/VerifyEmail.vue\": {\n    \"file\": \"assets/VerifyEmail-CyukB_SZ.js\",\n    \"name\": \"VerifyEmail\",\n    \"src\": \"resources/js/Pages/Auth/VerifyEmail.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_GuestLayout-BY3LC-73.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Dashboard.vue\": {\n    \"file\": \"assets/Dashboard-DM_LxQy2.js\",\n    \"name\": \"Dashboard\",\n    \"src\": \"resources/js/Pages/Dashboard.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_AuthenticatedLayout-DfWF52N1.js\",\n      \"_index-BSdK3M0e.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Edit.vue\": {\n    \"file\": \"assets/Edit-CYV2sXpe.js\",\n    \"name\": \"Edit\",\n    \"src\": \"resources/js/Pages/Profile/Edit.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_AuthenticatedLayout-DfWF52N1.js\",\n      \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n      \"_index-BSdK3M0e.js\",\n      \"_ApplicationLogo-BhIZH06z.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\": {\n    \"file\": \"assets/DeleteUserForm-B1oHFaVP.js\",\n    \"name\": \"DeleteUserForm\",\n    \"src\": \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\",\n      \"_TextInput-C8CCB_U_.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\": {\n    \"file\": \"assets/UpdatePasswordForm-CaeWqGla.js\",\n    \"name\": \"UpdatePasswordForm\",\n    \"src\": \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\": {\n    \"file\": \"assets/UpdateProfileInformationForm-CJwkYwQQ.js\",\n    \"name\": \"UpdateProfileInformationForm\",\n    \"src\": \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\",\n      \"_TextInput-C8CCB_U_.js\",\n      \"_PrimaryButton-DuXwr-9M.js\",\n      \"__plugin-vue_export-helper-DlAUqK2U.js\"\n    ]\n  },\n  \"resources/js/Pages/Welcome.vue\": {\n    \"file\": \"assets/Welcome-D_7l79PQ.js\",\n    \"name\": \"Welcome\",\n    \"src\": \"resources/js/Pages/Welcome.vue\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\"\n    ]\n  },\n  \"resources/js/admin-runtime-import-import.js\": {\n    \"file\": \"assets/admin-runtime-import-import-DKMIaPXC.js\",\n    \"name\": \"admin-runtime-import-import\",\n    \"src\": \"resources/js/admin-runtime-import-import.js\",\n    \"isDynamicEntry\": true\n  },\n  \"resources/js/admin-runtime-import.js\": {\n    \"file\": \"assets/admin-runtime-import-CRvLQy6v.js\",\n    \"name\": \"admin-runtime-import\",\n    \"src\": \"resources/js/admin-runtime-import.js\",\n    \"isDynamicEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\"\n    ],\n    \"dynamicImports\": [\n      \"resources/js/admin-runtime-import-import.js\"\n    ],\n    \"css\": [\n      \"assets/admin-runtime-import-BlmN0T4U.css\"\n    ]\n  },\n  \"resources/js/admin.js\": {\n    \"file\": \"assets/admin-Sefg0Q45.js\",\n    \"name\": \"admin\",\n    \"src\": \"resources/js/admin.js\",\n    \"isEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\"\n    ],\n    \"dynamicImports\": [\n      \"resources/js/Pages/Auth/ConfirmPassword.vue\",\n      \"resources/js/Pages/Auth/ForgotPassword.vue\",\n      \"resources/js/Pages/Auth/Login.vue\",\n      \"resources/js/Pages/Auth/Register.vue\",\n      \"resources/js/Pages/Auth/ResetPassword.vue\",\n      \"resources/js/Pages/Auth/VerifyEmail.vue\",\n      \"resources/js/Pages/Dashboard.vue\",\n      \"resources/js/Pages/Profile/Edit.vue\",\n      \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n      \"resources/js/Pages/Welcome.vue\",\n      \"resources/js/admin-runtime-import.js\"\n    ],\n    \"css\": [\n      \"assets/admin-BctAalm_.css\"\n    ]\n  },\n  \"resources/js/app.js\": {\n    \"file\": \"assets/app-lliD09ip.js\",\n    \"name\": \"app\",\n    \"src\": \"resources/js/app.js\",\n    \"isEntry\": true,\n    \"imports\": [\n      \"_index-BSdK3M0e.js\"\n    ],\n    \"dynamicImports\": [\n      \"resources/js/Pages/Auth/ConfirmPassword.vue\",\n      \"resources/js/Pages/Auth/ForgotPassword.vue\",\n      \"resources/js/Pages/Auth/Login.vue\",\n      \"resources/js/Pages/Auth/Register.vue\",\n      \"resources/js/Pages/Auth/ResetPassword.vue\",\n      \"resources/js/Pages/Auth/VerifyEmail.vue\",\n      \"resources/js/Pages/Dashboard.vue\",\n      \"resources/js/Pages/Profile/Edit.vue\",\n      \"resources/js/Pages/Profile/Partials/DeleteUserForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue\",\n      \"resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue\",\n      \"resources/js/Pages/Welcome.vue\"\n    ]\n  }\n}\n\n"
  },
  {
    "path": "tests/Foundation/fixtures/process-failure-strategy.php",
    "content": "<?php\n\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\nuse Symfony\\Component\\Process\\Process;\n\nreturn fn () => throw new ProcessFailedException(new class(['expected-command']) extends Process\n{\n    public function isSuccessful(): bool\n    {\n        return false;\n    }\n\n    public function getExitCode(): ?int\n    {\n        return 1;\n    }\n\n    public function isOutputDisabled(): bool\n    {\n        return true;\n    }\n\n    public function getWorkingDirectory(): ?string\n    {\n        return 'expected-working-directory';\n    }\n});\n"
  },
  {
    "path": "tests/Foundation/fixtures/process-interrupt-strategy.php",
    "content": "<?php\n\nuse Symfony\\Component\\Process\\Exception\\ProcessFailedException;\nuse Symfony\\Component\\Process\\Process;\n\nreturn fn () => throw new ProcessFailedException(new class([]) extends Process\n{\n    public function isSuccessful(): bool\n    {\n        return false;\n    }\n\n    public function getExitCode(): ?int\n    {\n        return 130;\n    }\n\n    public function isOutputDisabled(): bool\n    {\n        return true;\n    }\n});\n"
  },
  {
    "path": "tests/Foundation/fixtures/vendor/composer/installed.json",
    "content": "[\n  {\n    \"name\": \"vendor_a/package_a\",\n    \"version\": \"v1.0.1\",\n    \"type\": \"library\",\n    \"extra\": {\n      \"branch-alias\": {\n        \"dev-master\": \"1.0-dev\"\n      },\n      \"laravel\": {\n        \"providers\": \"foo\",\n        \"aliases\": {\n          \"Foo\": \"Foo\\\\Facade\"\n        },\n        \"dont-discover\": [\n            \"vendor_a/package_d\"\n        ]\n      }\n    }\n  },\n  {\n    \"name\": \"vendor_a/package_b\",\n    \"extra\": {\n      \"laravel\": {\n        \"providers\": [\n          \"bar\",\n          \"baz\"\n        ],\n        \"dont-discover\": [\n            \"vendor_a/package_e\"\n        ]\n      }\n    }\n  },\n  {\n    \"name\": \"vendor_a/package_c\",\n    \"type\": \"library\"\n  },\n  {\n    \"name\": \"vendor_a/package_d\",\n    \"extra\": {\n      \"laravel\": {\n        \"providers\": [\n          \"bazinga\"\n        ]\n      }\n    }\n  },\n  {\n    \"name\": \"vendor_a/package_e\",\n    \"extra\": {\n      \"laravel\": {\n        \"providers\": [\n          \"pennypennypenny\"\n        ]\n      }\n    }\n  }\n]\n"
  },
  {
    "path": "tests/Hashing/HasherTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Hashing;\n\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Hashing\\Argon2IdHasher;\nuse Illuminate\\Hashing\\ArgonHasher;\nuse Illuminate\\Hashing\\BcryptHasher;\nuse Illuminate\\Hashing\\HashManager;\nuse PHPUnit\\Framework\\Attributes\\Depends;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass HasherTest extends TestCase\n{\n    public $hashManager;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $container = Container::setInstance(new Container);\n        $container->singleton('config', fn () => new Config());\n\n        $this->hashManager = new HashManager($container);\n    }\n\n    public function testEmptyHashedValueReturnsFalse()\n    {\n        $hasher = new BcryptHasher();\n        $this->assertFalse($hasher->check('password', ''));\n        $hasher = new ArgonHasher();\n        $this->assertFalse($hasher->check('password', ''));\n        $hasher = new Argon2IdHasher();\n        $this->assertFalse($hasher->check('password', ''));\n    }\n\n    public function testNullHashedValueReturnsFalse()\n    {\n        $hasher = new BcryptHasher();\n        $this->assertFalse($hasher->check('password', null));\n        $hasher = new ArgonHasher();\n        $this->assertFalse($hasher->check('password', null));\n        $hasher = new Argon2IdHasher();\n        $this->assertFalse($hasher->check('password', null));\n    }\n\n    public function testBasicBcryptHashing()\n    {\n        $hasher = new BcryptHasher;\n        $value = $hasher->make('password');\n        $this->assertNotSame('password', $value);\n        $this->assertTrue($hasher->check('password', $value));\n        $this->assertFalse($hasher->needsRehash($value));\n        $this->assertTrue($hasher->needsRehash($value, ['rounds' => 1]));\n        $this->assertSame('bcrypt', password_get_info($value)['algoName']);\n        $this->assertGreaterThanOrEqual(12, password_get_info($value)['options']['cost']);\n        $this->assertTrue($this->hashManager->isHashed($value));\n    }\n\n    public function testBcryptValueTooLong()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $hasher = new BcryptHasher(['limit' => 72]);\n        $hasher->make(str_repeat('a', 73));\n    }\n\n    public function testBasicArgon2iHashing()\n    {\n        $hasher = new ArgonHasher;\n        $value = $hasher->make('password');\n        $this->assertNotSame('password', $value);\n        $this->assertTrue($hasher->check('password', $value));\n        $this->assertFalse($hasher->needsRehash($value));\n        $this->assertTrue($hasher->needsRehash($value, ['threads' => 1]));\n        $this->assertSame('argon2i', password_get_info($value)['algoName']);\n        $this->assertTrue($this->hashManager->isHashed($value));\n    }\n\n    public function testBasicArgon2idHashing()\n    {\n        $hasher = new Argon2IdHasher;\n        $value = $hasher->make('password');\n        $this->assertNotSame('password', $value);\n        $this->assertTrue($hasher->check('password', $value));\n        $this->assertFalse($hasher->needsRehash($value));\n        $this->assertTrue($hasher->needsRehash($value, ['threads' => 1]));\n        $this->assertSame('argon2id', password_get_info($value)['algoName']);\n        $this->assertTrue($this->hashManager->isHashed($value));\n    }\n\n    #[Depends('testBasicBcryptHashing')]\n    public function testBasicBcryptVerification()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $argonHasher = new ArgonHasher(['verify' => true]);\n        $argonHashed = $argonHasher->make('password');\n        (new BcryptHasher(['verify' => true]))->check('password', $argonHashed);\n    }\n\n    #[Depends('testBasicArgon2iHashing')]\n    public function testBasicArgon2iVerification()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $bcryptHasher = new BcryptHasher(['verify' => true]);\n        $bcryptHashed = $bcryptHasher->make('password');\n        (new ArgonHasher(['verify' => true]))->check('password', $bcryptHashed);\n    }\n\n    #[Depends('testBasicArgon2idHashing')]\n    public function testBasicArgon2idVerification()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $bcryptHasher = new BcryptHasher(['verify' => true]);\n        $bcryptHashed = $bcryptHasher->make('password');\n        (new Argon2IdHasher(['verify' => true]))->check('password', $bcryptHashed);\n    }\n\n    public function testIsHashedWithNonHashedValue()\n    {\n        $this->assertFalse($this->hashManager->isHashed('foo'));\n    }\n\n    public function testBasicBcryptNotSupported()\n    {\n        $this->expectException(RuntimeException::class);\n\n        (new BcryptHasher(['rounds' => 0]))->make('password');\n    }\n\n    public function testBasicArgon2iNotSupported()\n    {\n        $this->expectException(RuntimeException::class);\n\n        (new ArgonHasher(['time' => 0]))->make('password');\n    }\n\n    public function testBasicArgon2idNotSupported()\n    {\n        $this->expectException(RuntimeException::class);\n\n        (new Argon2IdHasher(['time' => 0]))->make('password');\n    }\n}\n"
  },
  {
    "path": "tests/Http/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nenum TestEnumBacked: string\n{\n    case test = 'test';\n    case test_empty = '';\n}\n\nenum TestIntegerEnumBacked: int\n{\n    case minus_1 = -1;\n    case zero = 0;\n    case plus_1 = 1;\n}\n\nenum TestEnum\n{\n    case test;\n}\n"
  },
  {
    "path": "tests/Http/HttpClientTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Exception;\nuse GuzzleHttp\\Exception\\ConnectException;\nuse GuzzleHttp\\Exception\\RequestException as GuzzleRequestException;\nuse GuzzleHttp\\Exception\\TooManyRedirectsException;\nuse GuzzleHttp\\Middleware;\nuse GuzzleHttp\\Promise\\Create;\nuse GuzzleHttp\\Promise\\PromiseInterface;\nuse GuzzleHttp\\Promise\\RejectedPromise;\nuse GuzzleHttp\\Psr7\\NoSeekStream;\nuse GuzzleHttp\\Psr7\\Request as GuzzleRequest;\nuse GuzzleHttp\\Psr7\\Response as Psr7Response;\nuse GuzzleHttp\\Psr7\\Utils;\nuse GuzzleHttp\\TransferStats;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Http\\Client\\Batch;\nuse Illuminate\\Http\\Client\\BatchInProgressException;\nuse Illuminate\\Http\\Client\\ConnectionException;\nuse Illuminate\\Http\\Client\\Events\\RequestSending;\nuse Illuminate\\Http\\Client\\Events\\ResponseReceived;\nuse Illuminate\\Http\\Client\\Factory;\nuse Illuminate\\Http\\Client\\PendingRequest;\nuse Illuminate\\Http\\Client\\Pool;\nuse Illuminate\\Http\\Client\\Request;\nuse Illuminate\\Http\\Client\\RequestException;\nuse Illuminate\\Http\\Client\\Response;\nuse Illuminate\\Http\\Client\\ResponseSequence;\nuse Illuminate\\Http\\Client\\StrayRequestException;\nuse Illuminate\\Http\\Response as HttpResponse;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Defer\\DeferredCallback;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse JsonSerializable;\nuse Mockery as m;\nuse OutOfBoundsException;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Http\\Message\\RequestInterface;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse RuntimeException;\nuse Symfony\\Component\\VarDumper\\VarDumper;\nuse Throwable;\n\nclass HttpClientTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Http\\Client\\Factory\n     */\n    protected $factory;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->factory = new Factory;\n\n        RequestException::truncate();\n    }\n\n    protected function tearDown(): void\n    {\n        Response::flushState();\n    }\n\n    public function testStubbedResponsesAreReturnedAfterFaking()\n    {\n        $this->factory->fake();\n\n        $response = $this->factory->post('http://laravel.com/test-missing-page');\n\n        $this->assertTrue($response->ok());\n    }\n\n    public function testCreatedRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_CREATED),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->created());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->created());\n    }\n\n    public function testStatusCodeShorthand()\n    {\n        $this->factory->fake([\n            'forge.laravel.com' => 204,\n            'vapor.laravel.com' => HttpResponse::HTTP_CREATED,\n        ]);\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertTrue($response->noContent());\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->created());\n    }\n\n    public function testStatusCodeShorthandAssumeBodyWhenInvalidHttpStatusCode()\n    {\n        $this->factory->fake([\n            'forge.laravel.com' => 999,\n            'vapor.laravel.com' => 1,\n        ]);\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertTrue($response->ok());\n        $this->assertSame('999', $response->body());\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->ok());\n        $this->assertSame('1', $response->body());\n    }\n\n    public function testBodyShorthands()\n    {\n        $this->factory->fake([\n            'google.com' => 'Hello World',\n            'github.com' => ['foo' => 'bar'],\n        ]);\n\n        $response = $this->factory->get('http://google.com');\n        $this->assertTrue($response->ok());\n        $this->assertSame('Hello World', $response->body());\n\n        $response = $this->factory->post('http://github.com');\n        $this->assertTrue($response->ok());\n        $this->assertSame('{\"foo\":\"bar\"}', $response->body());\n        $this->assertSame(['foo' => 'bar'], $response->json());\n    }\n\n    public function testAcceptedRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_ACCEPTED),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->accepted());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->accepted());\n    }\n\n    public function testMovedPermanentlyRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_MOVED_PERMANENTLY),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->movedPermanently());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->movedPermanently());\n    }\n\n    public function testNoContentRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_NO_CONTENT),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->noContent());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->noContent());\n    }\n\n    public function testFoundRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_FOUND),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->found());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->found());\n    }\n\n    public function testNotModifiedRequest(): void\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_NOT_MODIFIED),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('https://vapor.laravel.com');\n        $this->assertTrue($response->notModified());\n\n        $response = $this->factory->post('https://forge.laravel.com');\n        $this->assertFalse($response->notModified());\n    }\n\n    public function testBadRequestRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_BAD_REQUEST),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->badRequest());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->badRequest());\n    }\n\n    public function testPaymentRequiredRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_PAYMENT_REQUIRED),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->paymentRequired());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->paymentRequired());\n    }\n\n    public function testRequestTimeoutRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_REQUEST_TIMEOUT),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->requestTimeout());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->requestTimeout());\n    }\n\n    public function testConflictResponseRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_CONFLICT),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->conflict());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->conflict());\n    }\n\n    public function testUnprocessableContentRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_UNPROCESSABLE_ENTITY),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->unprocessableContent());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->unprocessableContent());\n    }\n\n    public function testUnprocessableEntityRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_UNPROCESSABLE_ENTITY),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->unprocessableEntity());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->unprocessableEntity());\n    }\n\n    public function testTooManyRequestsRequest()\n    {\n        $this->factory->fake([\n            'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_TOO_MANY_REQUESTS),\n            'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK),\n        ]);\n\n        $response = $this->factory->post('http://vapor.laravel.com');\n        $this->assertTrue($response->tooManyRequests());\n\n        $response = $this->factory->post('http://forge.laravel.com');\n        $this->assertFalse($response->tooManyRequests());\n    }\n\n    public function testUnauthorizedRequest()\n    {\n        $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 401),\n        ]);\n\n        $response = $this->factory->post('http://laravel.com');\n\n        $this->assertTrue($response->unauthorized());\n    }\n\n    public function testForbiddenRequest()\n    {\n        $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 403),\n        ]);\n\n        $response = $this->factory->post('http://laravel.com');\n\n        $this->assertTrue($response->forbidden());\n    }\n\n    public function testNotFoundResponse()\n    {\n        $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 404),\n        ]);\n\n        $response = $this->factory->post('http://laravel.com');\n\n        $this->assertTrue($response->notFound());\n    }\n\n    public function testResponseBodyCasting()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', $response->body());\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', (string) $response);\n        $this->assertIsArray($response->json());\n        $this->assertSame(['foo' => 'bar'], $response->json()['result']);\n        $this->assertSame(['foo' => 'bar'], $response->json('result'));\n        $this->assertSame('bar', $response->json('result.foo'));\n        $this->assertSame('default', $response->json('missing_key', 'default'));\n        $this->assertSame(['foo' => 'bar'], $response['result']);\n    }\n\n    public function testResponseObjectAsArray()\n    {\n        $this->factory->fake([\n            '*' => [['foo' => 'bar'], ['bar' => 'foo']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertSame('[{\"foo\":\"bar\"},{\"bar\":\"foo\"}]', $response->body());\n        $this->assertSame('[{\"foo\":\"bar\"},{\"bar\":\"foo\"}]', (string) $response);\n        $this->assertIsArray($response->object());\n        $this->assertSame('bar', $response->object()[0]->foo);\n    }\n\n    public function testResponseObjectAsObject()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertIsObject($response->object());\n        $this->assertSame('bar', $response->object()->result->foo);\n    }\n\n    public function testResponseObjectIsTappable()\n    {\n        $bar = null;\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $this->factory->get('http://foo.com/api')\n            ->tap(function (Response $response) use (&$bar) {\n                $bar = $response['result']['foo'];\n            });\n\n        $this->assertSame('bar', $bar);\n    }\n\n    public function testResponseObjectIsMacroable()\n    {\n        Response::macro('movieFields', function () {\n            return $this->collect()\n                ->mapWithKeys(fn ($field, $key) => [strtolower($key) => $field])\n                ->toArray();\n        });\n\n        $response = $this->factory->fake([\n            '*' => [\n                'Title' => 'The Godfather',\n                'Year' => 1972,\n                'Rated' => 'R',\n                'Runtime' => '175 min',\n                'Director' => 'Francis Ford Coppola',\n            ],\n        ]);\n\n        $response = $this->factory->get('http://www.omdbapi.com/?apikey=test_api_key&i=test_imdb_id');\n\n        $this->assertIsArray($response->movieFields());\n        $this->assertSame([\n            'title' => 'The Godfather',\n            'year' => 1972,\n            'rated' => 'R',\n            'runtime' => '175 min',\n            'director' => 'Francis Ford Coppola',\n        ], $response->movieFields());\n    }\n\n    public function testResponseCanBeReturnedAsResource()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertIsResource($response->resource());\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', stream_get_contents($response->resource()));\n    }\n\n    public function testResponseCanBeReturnedAsCollection()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertInstanceOf(Collection::class, $response->collect());\n        $this->assertEquals(collect(['result' => ['foo' => 'bar']]), $response->collect());\n        $this->assertEquals(collect(['foo' => 'bar']), $response->collect('result'));\n        $this->assertEquals(collect(['bar']), $response->collect('result.foo'));\n        $this->assertEquals(collect(), $response->collect('missing_key'));\n    }\n\n    public function testResponseCanBeReturnedAsFluent()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api');\n\n        $this->assertInstanceOf(Fluent::class, $response->fluent());\n        $this->assertEquals(new Fluent(['result' => ['foo' => 'bar']]), $response->fluent());\n        $this->assertEquals(new Fluent(['foo' => 'bar']), $response->fluent('result'));\n        $this->assertEquals(new Fluent(['bar']), $response->fluent('result.foo'));\n        $this->assertEquals(new Fluent([]), $response->fluent('missing_key'));\n    }\n\n    public function testSendRequestBodyAsJsonByDefault()\n    {\n        $body = '{\"test\":\"phpunit\"}';\n\n        $fakeRequest = function (Request $request) use ($body) {\n            self::assertSame($body, $request->body());\n            self::assertContains('application/json', $request->header('Content-Type'));\n\n            return ['my' => 'response'];\n        };\n\n        $this->factory->fake($fakeRequest);\n\n        $this->factory->withBody($body)->send('get', 'http://foo.com/api');\n    }\n\n    public function testSendRequestBodyWithManyAmpersands()\n    {\n        $body = str_repeat('A thousand &. ', 1000);\n\n        $fakeRequest = function (Request $request) use ($body) {\n            self::assertSame($body, $request->body());\n            self::assertContains('text/plain', $request->header('Content-Type'));\n\n            return ['my' => 'response'];\n        };\n\n        $this->factory->fake($fakeRequest);\n\n        $this->factory->withBody($body, 'text/plain')->send('post', 'http://foo.com/api');\n    }\n\n    public function testSendStreamRequestBody()\n    {\n        $string = 'Look at me, i am a stream!!';\n        $resource = fopen('php://temp', 'w');\n        fwrite($resource, $string);\n        rewind($resource);\n        $body = Utils::streamFor($resource);\n\n        $fakeRequest = function (Request $request) use ($string) {\n            self::assertSame($string, $request->body());\n            self::assertContains('text/plain', $request->header('Content-Type'));\n\n            return ['my' => 'response'];\n        };\n\n        $this->factory->fake($fakeRequest);\n\n        $this->factory->withBody($body, 'text/plain')->send('post', 'http://foo.com/api');\n    }\n\n    public function testUrlsCanBeStubbedByPath()\n    {\n        $this->factory->fake([\n            'foo.com/*' => ['page' => 'foo'],\n            'bar.com/*' => ['page' => 'bar'],\n            '*' => ['page' => 'fallback'],\n        ]);\n\n        $fooResponse = $this->factory->post('http://foo.com/test');\n        $barResponse = $this->factory->post('http://bar.com/test');\n        $fallbackResponse = $this->factory->post('http://fallback.com/test');\n\n        $this->assertSame('foo', $fooResponse['page']);\n        $this->assertSame('bar', $barResponse['page']);\n        $this->assertSame('fallback', $fallbackResponse['page']);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/test' &&\n                   $request->hasHeader('Content-Type', 'application/json');\n        });\n    }\n\n    public function testCanSendJsonData()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeader('Content-Type', 'application/json') &&\n                   $request->hasHeader('X-Test-Header', 'foo') &&\n                   $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                   $request['name'] === 'Taylor';\n        });\n    }\n\n    public function testCanSendFormData()\n    {\n        $this->factory->fake();\n\n        $this->factory->asForm()->post('http://foo.com/form', [\n            'name' => 'Taylor',\n            'title' => 'Laravel Developer',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                   $request->hasHeader('Content-Type', 'application/x-www-form-urlencoded') &&\n                   $request['name'] === 'Taylor';\n        });\n    }\n\n    #[DataProvider('methodsReceivingArrayableDataProvider')]\n    public function testCanSendArrayableFormData(string $method)\n    {\n        $this->factory->fake();\n\n        $this->factory->asForm()->{$method}('http://foo.com/form', new Fluent([\n            'name' => 'Taylor',\n            'title' => 'Laravel Developer',\n        ]));\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                   $request->hasHeader('Content-Type', 'application/x-www-form-urlencoded') &&\n                   $request['name'] === 'Taylor';\n        });\n    }\n\n    #[DataProvider('methodsReceivingArrayableDataProvider')]\n    public function testCanSendJsonSerializableData(string $method)\n    {\n        $this->factory->fake();\n\n        $this->factory->asJson()->{$method}('http://foo.com/form', new class implements JsonSerializable\n        {\n            public function jsonSerialize(): mixed\n            {\n                return [\n                    'name' => 'Taylor',\n                    'title' => 'Laravel Developer',\n                ];\n            }\n        });\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                $request->hasHeader('Content-Type', 'application/json') &&\n                $request['name'] === 'Taylor';\n        });\n    }\n\n    #[DataProvider('methodsReceivingArrayableDataProvider')]\n    public function testPrefersJsonSerializableOverArrayableData(string $method)\n    {\n        $this->factory->fake();\n\n        $this->factory->asJson()->{$method}('http://foo.com/form', new class implements JsonSerializable, Arrayable\n        {\n            public function jsonSerialize(): mixed\n            {\n                return [\n                    'attributes' => (object) [],\n                ];\n            }\n\n            public function toArray(): array\n            {\n                return [\n                    'attributes' => [],\n                ];\n            }\n        });\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                $request->hasHeader('Content-Type', 'application/json') &&\n                $request->body() === '{\"attributes\":{}}';\n        });\n    }\n\n    public function testCanSendJsonDataWithStringable()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json', [\n            'name' => new Stringable('Taylor'),\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeader('Content-Type', 'application/json') &&\n                   $request->hasHeader('X-Test-Header', 'foo') &&\n                   $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                   $request['name'] === 'Taylor';\n        });\n    }\n\n    public function testCanSendFormDataWithStringable()\n    {\n        $this->factory->fake();\n\n        $this->factory->asForm()->post('http://foo.com/form', [\n            'name' => new Stringable('Taylor'),\n            'title' => 'Laravel Developer',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                   $request->hasHeader('Content-Type', 'application/x-www-form-urlencoded') &&\n                   $request['name'] === 'Taylor';\n        });\n    }\n\n    public function testCanSendFormDataWithStringableInArrays()\n    {\n        $this->factory->fake();\n\n        $this->factory->asForm()->post('http://foo.com/form', [\n            'posts' => [['title' => new Stringable('Taylor')]],\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                   $request->hasHeader('Content-Type', 'application/x-www-form-urlencoded') &&\n                   $request['posts'][0]['title'] === 'Taylor';\n        });\n    }\n\n    public function testRecordedCallsAreEmptiedWhenFakeIsCalled()\n    {\n        $this->factory->fake([\n            'http://foo.com/*' => ['page' => 'foo'],\n        ]);\n\n        $this->factory->get('http://foo.com/test');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/test';\n        });\n\n        $this->factory->fake();\n\n        $this->factory->assertNothingSent();\n    }\n\n    public function testSpecificRequestIsNotBeingSent()\n    {\n        $this->factory->fake();\n\n        $this->factory->post('http://foo.com/form', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->assertNotSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/form' &&\n                $request['name'] === 'Peter';\n        });\n    }\n\n    public function testNoRequestIsNotBeingSent()\n    {\n        $this->factory->fake();\n\n        $this->factory->assertNothingSent();\n    }\n\n    public function testRequestCount()\n    {\n        $this->factory->fake();\n        $this->factory->assertSentCount(0);\n\n        $this->factory->post('http://foo.com/form', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->assertSentCount(1);\n\n        $this->factory->post('http://foo.com/form', [\n            'name' => 'Jim',\n        ]);\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testCanSendMultipartData()\n    {\n        $this->factory->fake();\n\n        $this->factory->asMultipart()->post('http://foo.com/multipart', [\n            [\n                'name' => 'foo',\n                'contents' => 'data',\n                'headers' => ['X-Test-Header' => 'foo'],\n            ],\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/multipart' &&\n                   Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                   $request[0]['name'] === 'foo';\n        });\n    }\n\n    public function testFilesCanBeAttached()\n    {\n        $this->factory->fake();\n\n        $this->factory->attach('foo', 'data', 'file.txt', ['X-Test-Header' => 'foo'])\n            ->post('http://foo.com/file');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/file' &&\n                   Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                   $request[0]['name'] === 'foo' &&\n                   $request->hasFile('foo', 'data', 'file.txt');\n        });\n    }\n\n    public function testCanSendMultipartDataWithSimplifiedParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->asMultipart()->post('http://foo.com/multipart', [\n            'foo' => 'bar',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/multipart' &&\n                Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                $request[0]['name'] === 'foo' &&\n                $request[0]['contents'] === 'bar';\n        });\n    }\n\n    public function testCanSendMultipartDataWithBothSimplifiedAndExtendedParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->asMultipart()->post('http://foo.com/multipart', [\n            'foo' => 'bar',\n            [\n                'name' => 'foobar',\n                'contents' => 'data',\n                'headers' => ['X-Test-Header' => 'foo'],\n            ],\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/multipart' &&\n                Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                $request[0]['name'] === 'foo' &&\n                $request[0]['contents'] === 'bar' &&\n                $request[1]['name'] === 'foobar' &&\n                $request[1]['contents'] === 'data' &&\n                $request[1]['headers']['X-Test-Header'] === 'foo';\n        });\n    }\n\n    public function testCanSendMultipartDataWithArrayValues()\n    {\n        $this->factory->fake();\n\n        $this->factory->asMultipart()->post('http://foo.com/multipart', [\n            'name' => 'Steve',\n            'roles' => ['Network Administrator', 'Janitor'],\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/multipart' &&\n                Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                $request[0]['name'] === 'name' &&\n                $request[0]['contents'] === 'Steve' &&\n                $request[1]['name'] === 'roles[]' &&\n                $request[1]['contents'] === 'Network Administrator' &&\n                $request[2]['name'] === 'roles[]' &&\n                $request[2]['contents'] === 'Janitor';\n        });\n    }\n\n    public function testCanSendMultipartDataWithFileAndArrayValues()\n    {\n        $this->factory->fake();\n\n        $this->factory\n            ->attach('attachment', 'photo_content', 'photo.jpg', ['Content-Type' => 'image/jpeg'])\n            ->post('http://foo.com/multipart', [\n                'name' => 'Steve',\n                'roles' => ['Network Administrator', 'Janitor'],\n            ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/multipart' &&\n                Str::startsWith($request->header('Content-Type')[0], 'multipart') &&\n                $request[0]['name'] === 'name' &&\n                $request[0]['contents'] === 'Steve' &&\n                $request[1]['name'] === 'roles[]' &&\n                $request[1]['contents'] === 'Network Administrator' &&\n                $request[2]['name'] === 'roles[]' &&\n                $request[2]['contents'] === 'Janitor' &&\n                $request[3]['name'] === 'attachment' &&\n                $request[3]['contents'] === 'photo_content' &&\n                $request[3]['filename'] === 'photo.jpg';\n        });\n    }\n\n    public function testItCanSendToken()\n    {\n        $this->factory->fake();\n\n        $this->factory->withToken('token')->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                $request->hasHeader('Authorization', 'Bearer token');\n        });\n    }\n\n    public function testItCanSendUserAgent()\n    {\n        $this->factory->fake();\n\n        $this->factory->withUserAgent('Laravel')->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                $request->hasHeader('User-Agent', 'Laravel');\n        });\n    }\n\n    public function testItOnlySendsOneUserAgentHeader()\n    {\n        $this->factory->fake();\n\n        $this->factory->withUserAgent('Laravel')\n            ->withUserAgent('FooBar')\n            ->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            $userAgent = $request->header('User-Agent');\n\n            return $request->url() === 'http://foo.com/json' &&\n                count($userAgent) === 1 &&\n                $userAgent[0] === 'FooBar';\n        });\n    }\n\n    public function testSequenceBuilder()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push('Ok', 201)\n                ->push(['fact' => 'Cats are great!'])\n                ->pushFile(__DIR__.'/fixtures/test.txt')\n                ->pushStatus(403),\n        ]);\n\n        $response = $this->factory->get('https://example.com');\n        $this->assertSame('Ok', $response->body());\n        $this->assertSame(201, $response->status());\n\n        $response = $this->factory->get('https://example.com');\n        $this->assertSame(['fact' => 'Cats are great!'], $response->json());\n        $this->assertSame('application/json', $response->header('Content-Type'));\n        $this->assertSame(200, $response->status());\n\n        $response = $this->factory->get('https://example.com');\n        $this->assertSame(\n            \"This is a story about something that happened long ago when your grandfather was a child.\\n\",\n            str_replace(\"\\r\\n\", \"\\n\", $response->body())\n        );\n        $this->assertSame(200, $response->status());\n\n        $response = $this->factory->get('https://example.com');\n        $this->assertSame('', $response->body());\n        $this->assertSame(403, $response->status());\n\n        $this->expectException(OutOfBoundsException::class);\n\n        // The sequence is empty, it should throw an exception.\n        $this->factory->get('https://example.com');\n    }\n\n    public function testSequenceBuilderCanKeepGoingWhenEmpty()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->dontFailWhenEmpty()\n                ->push('Ok'),\n        ]);\n\n        $response = $this->factory->get('https://laravel.com');\n        $this->assertSame('Ok', $response->body());\n\n        // The sequence is empty, but it should not fail.\n        $this->factory->get('https://laravel.com');\n    }\n\n    public function testAssertSequencesAreEmpty()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push('1')\n                ->push('2'),\n        ]);\n\n        $this->factory->get('https://example.com');\n        $this->factory->get('https://example.com');\n\n        $this->factory->assertSequencesAreEmpty();\n    }\n\n    public function testFakeSequence()\n    {\n        $this->factory->fakeSequence()\n            ->pushStatus(201)\n            ->pushStatus(301);\n\n        $this->assertSame(201, $this->factory->get('https://example.com')->status());\n        $this->assertSame(301, $this->factory->get('https://example.com')->status());\n    }\n\n    public function testWithCookies()\n    {\n        $this->factory->fakeSequence()->pushStatus(200);\n\n        $response = $this->factory->withCookies(\n            ['foo' => 'bar'], 'https://laravel.com'\n        )->get('https://laravel.com');\n\n        $this->assertCount(1, $response->cookies()->toArray());\n\n        /** @var \\GuzzleHttp\\Cookie\\CookieJarInterface $responseCookies */\n        $responseCookie = $response->cookies()->toArray()[0];\n\n        $this->assertSame('foo', $responseCookie['Name']);\n        $this->assertSame('bar', $responseCookie['Value']);\n        $this->assertSame('https://laravel.com', $responseCookie['Domain']);\n    }\n\n    public function testWithQueryParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters(\n            ['foo' => 'bar']\n        )->get('https://laravel.com');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo=bar';\n        });\n    }\n\n    public function testWithArrayQueryParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters(\n            ['foo' => ['bar', 'baz']],\n        )->get('https://laravel.com');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo%5B0%5D=bar&foo%5B1%5D=baz';\n        });\n    }\n\n    public function testWithQueryParametersAllowsAddingMoreOnRequest()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters(\n            ['foo' => 'bar']\n        )->get('https://laravel.com', [\n            'baz' => 'qux',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo=bar&baz=qux';\n        });\n    }\n\n    public function testWithQueryParametersAllowsOverridingParameterOnRequest()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters([\n            'foo' => 'bar',\n            'baz' => 'baz',\n        ])->get('https://laravel.com', [\n            // Override the previously set value\n            'baz' => 'qux',\n        ]);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo=bar&baz=qux';\n        });\n    }\n\n    public function testWithStringableQueryParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters(\n            ['foo' => new Stringable('bar')]\n        )->get('https://laravel.com');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo=bar';\n        });\n    }\n\n    public function testWithArrayStringableQueryParameters()\n    {\n        $this->factory->fake();\n\n        $this->factory->withQueryParameters(\n            ['foo' => ['bar', new Stringable('baz')]],\n        )->get('https://laravel.com');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com?foo%5B0%5D=bar&foo%5B1%5D=baz';\n        });\n    }\n\n    public function testGetWithArrayQueryParam()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get', ['foo' => 'bar']);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo=bar'\n                && $request['foo'] === 'bar';\n        });\n    }\n\n    public function testGetWithArrayableQueryParam()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get', new Fluent(['foo' => 'bar']));\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo=bar'\n                && $request['foo'] === 'bar';\n        });\n    }\n\n    public function testGetWithStringQueryParam()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get', 'foo=bar');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo=bar'\n                && $request['foo'] === 'bar';\n        });\n    }\n\n    public function testGetWithQuery()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get?foo=bar&page=1');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo=bar&page=1'\n                && $request['foo'] === 'bar'\n                && $request['page'] === '1';\n        });\n    }\n\n    public function testGetWithQueryWontEncode()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get?foo;bar;1;5;10&page=1');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo;bar;1;5;10&page=1'\n                && ! isset($request['foo'])\n                && ! isset($request['bar'])\n                && $request['page'] === '1';\n        });\n    }\n\n    public function testGetWithArrayQueryParamOverwrites()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get?foo=bar&page=1', ['hello' => 'world']);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?hello=world'\n                && $request['hello'] === 'world';\n        });\n    }\n\n    public function testGetWithArrayQueryParamEncodes()\n    {\n        $this->factory->fake();\n\n        $this->factory->get('http://foo.com/get', ['foo;bar; space test' => 'laravel']);\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get?foo%3Bbar%3B%20space%20test=laravel'\n                && $request['foo;bar; space test'] === 'laravel';\n        });\n    }\n\n    public function testWithBaseUrl()\n    {\n        $this->factory->fake();\n\n        $this->factory->baseUrl('http://foo.com/')->get('get');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/get';\n        });\n\n        $this->factory->fake();\n\n        $this->factory->baseUrl('http://foo.com/')->get('http://bar.com/get');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://bar.com/get';\n        });\n    }\n\n    public function testCanConfirmManyHeaders()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeaders([\n                       'X-Test-Header' => 'foo',\n                       'X-Test-ArrayHeader' => ['bar', 'baz'],\n                   ]);\n        });\n    }\n\n    public function testCanConfirmManyHeadersUsingAString()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeaders('X-Test-Header');\n        });\n    }\n\n    public function testItMergesMultipleHeaders()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n        ])->withHeaders([\n            'X-Test-Header' => 'bar',\n        ])->withHeaders([\n            'X-Test-Header' => ['baz', 'qux'],\n        ])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeaders(['X-Test-Header' => ['foo', 'bar', 'baz', 'qux']]);\n        });\n    }\n\n    public function testItCanReplaceHeaders()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n        ])->replaceHeaders([\n            'X-Test-Header' => 'baz',\n        ])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeaders(['X-Test-Header' => ['baz']]);\n        });\n    }\n\n    public function testItCanReplaceHeadersWhenNoHeadersYetSet()\n    {\n        $this->factory->fake();\n\n        $this->factory->replaceHeaders([\n            'X-Test-Header' => 'baz',\n        ])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                   $request->hasHeaders(['X-Test-Header' => ['baz']]);\n        });\n    }\n\n    public function testCanConfirmSingleStringHeader()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeader('X-Test-Header', 'foo')->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                $request->hasHeaders([\n                    'X-Test-Header' => 'foo',\n                ]);\n        });\n    }\n\n    public function testCanConfirmSingleArrayHeader()\n    {\n        $this->factory->fake();\n\n        $this->factory->withHeader('X-Test-ArrayHeader', ['bar', 'baz'])->post('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'http://foo.com/json' &&\n                $request->hasHeaders([\n                    'X-Test-ArrayHeader' => ['bar', 'baz'],\n                ]);\n        });\n    }\n\n    public function testExceptionAccessorOnSuccess()\n    {\n        $resp = new Response(new Psr7Response());\n\n        $this->assertNull($resp->toException());\n    }\n\n    public function testExceptionAccessorOnFailure()\n    {\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed',\n            ],\n        ];\n        $response = new Psr7Response(403, [], json_encode($error));\n        $resp = new Response($response);\n\n        $this->assertInstanceOf(RequestException::class, $resp->toException());\n    }\n\n    public function testRequestExceptionSummary()\n    {\n        $this->expectException(RequestException::class);\n        $this->expectExceptionMessage('{\"error\":{\"code\":403,\"message\":\"The Request can not be completed\"}}');\n\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed',\n            ],\n        ];\n\n        $response = new Psr7Response(403, [], json_encode($error));\n\n        throw tap(new RequestException(new Response($response)), fn ($exception) => $exception->report());\n    }\n\n    public function testRequestExceptionTruncatedSummary()\n    {\n        $this->expectException(RequestException::class);\n        $this->expectExceptionMessage('{\"error\":{\"code\":403,\"message\":\"The Request can not be completed because quota limit was exceeded. Please, check our sup (truncated...)');\n\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed because quota limit was exceeded. Please, check our support team to increase your limit',\n            ],\n        ];\n        $response = new Psr7Response(403, [], json_encode($error));\n\n        throw tap(new RequestException(new Response($response)), fn ($exception) => $exception->report());\n    }\n\n    public function testRequestExceptionWithoutTruncatedSummary()\n    {\n        RequestException::dontTruncate();\n\n        $this->expectException(RequestException::class);\n        $this->expectExceptionMessage('{\"error\":{\"code\":403,\"message\":\"The Request can not be completed because quota limit was exceeded. Please, check our support team to increase your limit');\n\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed because quota limit was exceeded. Please, check our support team to increase your limit',\n            ],\n        ];\n        $response = new Psr7Response(403, [], json_encode($error));\n\n        throw tap(new RequestException(new Response($response)), fn ($exception) => $exception->report());\n    }\n\n    public function testRequestExceptionWithCustomTruncatedSummary()\n    {\n        RequestException::truncateAt(60);\n\n        $this->expectException(RequestException::class);\n        $this->expectExceptionMessage('{\"error\":{\"code\":403,\"message\":\"The Request can not be compl (truncated...)');\n\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed because quota limit was exceeded. Please, check our support team to increase your limit',\n            ],\n        ];\n        $response = new Psr7Response(403, [], json_encode($error));\n\n        throw tap(new RequestException(new Response($response)), fn ($exception) => $exception->report());\n    }\n\n    public function testRequestLevelTruncationLevelOnRequestException()\n    {\n        RequestException::truncateAt(60);\n\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n        try {\n            $this->factory->throw()->truncateExceptionsAt(3)->get('http://foo.com/json');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        // Ensure the exception message is truncated according to the request level truncation setting.\n        $this->assertEquals(\"HTTP request returned status code 403:\\n[\\\"e (truncated...)\\n\", $exception->getMessage());\n\n        $exception->report();\n\n        // Ensure that the truncation level is not changed when reporting the exception.\n        $this->assertEquals(\"HTTP request returned status code 403:\\n[\\\"e (truncated...)\\n\", $exception->getMessage());\n\n        $this->assertEquals(60, RequestException::$truncateAt);\n    }\n\n    public function testNoTruncationOnRequestLevel()\n    {\n        RequestException::truncateAt(60);\n\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->throw()->dontTruncateExceptions()->get('http://foo.com/json');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $exception->report();\n\n        $this->assertEquals(\"HTTP request returned status code 403:\\nHTTP/1.1 403 Forbidden\\r\\nContent-Type: application/json\\r\\n\\r\\n[\\\"error\\\"]\\n\", $exception->getMessage());\n\n        $this->assertEquals(60, RequestException::$truncateAt);\n    }\n\n    public function testRequestExceptionDoesNotTruncateButRequestDoes()\n    {\n        RequestException::dontTruncate();\n\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n        try {\n            $this->factory->throw()->truncateExceptionsAt(3)->get('http://foo.com/json');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $exception->report();\n\n        $this->assertEquals(\"HTTP request returned status code 403:\\n[\\\"e (truncated...)\\n\", $exception->getMessage());\n\n        $this->assertFalse(RequestException::$truncateAt);\n    }\n\n    public function testAsyncRequestExceptionsRespectRequestTruncation()\n    {\n        RequestException::dontTruncate();\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = $this->factory->async()->throw()->truncateExceptionsAt(4)->get('http://foo.com/json')->wait();\n\n        $exception->report();\n\n        $this->assertInstanceOf(RequestException::class, $exception);\n        $this->assertEquals(\"HTTP request returned status code 403:\\n[\\\"er (truncated...)\\n\", $exception->getMessage());\n        $this->assertFalse(RequestException::$truncateAt);\n    }\n\n    public function testRequestExceptionEmptyBody()\n    {\n        $this->expectException(RequestException::class);\n        $this->expectExceptionMessageMatches('/HTTP request returned status code 403$/');\n\n        $response = new Psr7Response(403);\n\n        throw new RequestException(new Response($response));\n    }\n\n    public function testReportingExceptionTwiceDoesNotIncludeSummaryTwice()\n    {\n        RequestException::dontTruncate();\n\n        $error = [\n            'error' => [\n                'code' => 403,\n                'message' => 'The Request can not be completed',\n            ],\n        ];\n\n        $response = new Psr7Response(403, [], json_encode($error));\n\n        $exception = new RequestException(new Response($response));\n        $exception->report();\n        $exception->report();\n\n        $this->assertEquals(1, substr_count($exception->getMessage(), '{\"error\":{\"code\":403,\"message\":\"The Request can not be completed\"}}'));\n    }\n\n    #[TestWith([false])]\n    #[TestWith([120])]\n    public function testStreamingResponseExceptionMessageIsNotSummarizedWhenBodyIsNotSeekable(int|false $truncateAt)\n    {\n        RequestException::$truncateAt = $truncateAt;\n\n        $this->factory->fake([\n            '*' => Create::promiseFor(\n                new Psr7Response(\n                    400,\n                    ['Content-Type' => 'application/json'],\n                    new NoSeekStream(Utils::streamFor(json_encode(['hello' => 'world'])))\n                )\n            ),\n        ]);\n\n        $throwCallbackCalled = false;\n\n        try {\n            $this->factory\n                ->withOptions(['stream' => true])\n                ->throw(function (Response $response, RequestException $exception) use (&$throwCallbackCalled) {\n                    $throwCallbackCalled = true;\n\n                    $this->assertNotNull($response->json());\n                    $this->assertSame('HTTP request returned status code 400', $exception->getMessage());\n                })\n                ->get('http://example.com');\n\n            $this->fail('RequestException was not thrown.');\n        } catch (RequestException $exception) {\n            $this->assertSame('HTTP request returned status code 400', $exception->getMessage());\n        }\n\n        $this->assertTrue($throwCallbackCalled);\n    }\n\n    public function testOnErrorDoesntCallClosureOnInformational()\n    {\n        $status = 0;\n        $client = $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 101),\n        ]);\n\n        $response = $client->get('laravel.com')\n            ->onError(function ($response) use (&$status) {\n                $status = $response->status();\n            });\n\n        $this->assertSame(0, $status);\n        $this->assertSame(101, $response->status());\n    }\n\n    public function testOnErrorDoesntCallClosureOnSuccess()\n    {\n        $status = 0;\n        $client = $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 201),\n        ]);\n\n        $response = $client->get('laravel.com')\n            ->onError(function ($response) use (&$status) {\n                $status = $response->status();\n            });\n\n        $this->assertSame(0, $status);\n        $this->assertSame(201, $response->status());\n    }\n\n    public function testOnErrorDoesntCallClosureOnRedirection()\n    {\n        $status = 0;\n        $client = $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 301),\n        ]);\n\n        $response = $client->get('laravel.com')\n            ->onError(function ($response) use (&$status) {\n                $status = $response->status();\n            });\n\n        $this->assertSame(0, $status);\n        $this->assertSame(301, $response->status());\n    }\n\n    public function testOnErrorCallsClosureOnClientError()\n    {\n        $status = 0;\n        $client = $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 401),\n        ]);\n\n        $response = $client->get('laravel.com')\n            ->onError(function ($response) use (&$status) {\n                $status = $response->status();\n            });\n\n        $this->assertSame(401, $status);\n        $this->assertSame(401, $response->status());\n    }\n\n    public function testOnErrorCallsClosureOnServerError()\n    {\n        $status = 0;\n        $client = $this->factory->fake([\n            'laravel.com' => $this->factory::response('', 501),\n        ]);\n\n        $response = $client->get('laravel.com')\n            ->onError(function ($response) use (&$status) {\n                $status = $response->status();\n            });\n\n        $this->assertSame(501, $status);\n        $this->assertSame(501, $response->status());\n    }\n\n    public function testSinkToFile()\n    {\n        $this->factory->fakeSequence()->push('abc123');\n\n        $destination = __DIR__.'/fixtures/sunk.txt';\n\n        if (file_exists($destination)) {\n            unlink($destination);\n        }\n\n        $this->factory->withOptions(['sink' => $destination])->get('https://example.com');\n\n        $this->assertFileExists($destination);\n        $this->assertSame('abc123', file_get_contents($destination));\n\n        unlink($destination);\n    }\n\n    public function testSinkToResource()\n    {\n        $this->factory->fakeSequence()->push('abc123');\n\n        $resource = fopen('php://temp', 'w');\n\n        $this->factory->sink($resource)->get('https://example.com');\n\n        $this->assertSame(0, ftell($resource));\n        $this->assertSame('abc123', stream_get_contents($resource));\n    }\n\n    public function testSinkWhenStubbedByPath()\n    {\n        $this->factory->fake([\n            'foo.com/*' => ['page' => 'foo'],\n        ]);\n\n        $resource = fopen('php://temp', 'w');\n\n        $this->factory->sink($resource)->get('http://foo.com/test');\n\n        $this->assertSame(json_encode(['page' => 'foo']), stream_get_contents($resource));\n    }\n\n    public function testCanAssertAgainstOrderOfHttpRequestsWithUrlStrings()\n    {\n        $this->factory->fake();\n\n        $exampleUrls = [\n            'http://example.com/1',\n            'http://example.com/2',\n            'http://example.com/3',\n        ];\n\n        foreach ($exampleUrls as $url) {\n            $this->factory->get($url);\n        }\n\n        $this->factory->assertSentInOrder($exampleUrls);\n    }\n\n    public function testAssertionsSentOutOfOrderThrowAssertionFailed()\n    {\n        $this->factory->fake();\n\n        $exampleUrls = [\n            'http://example.com/1',\n            'http://example.com/2',\n            'http://example.com/3',\n        ];\n\n        $this->factory->get($exampleUrls[0]);\n        $this->factory->get($exampleUrls[2]);\n        $this->factory->get($exampleUrls[1]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->factory->assertSentInOrder($exampleUrls);\n    }\n\n    public function testWrongNumberOfRequestsThrowAssertionFailed()\n    {\n        $this->factory->fake();\n\n        $exampleUrls = [\n            'http://example.com/1',\n            'http://example.com/2',\n            'http://example.com/3',\n        ];\n\n        $this->factory->get($exampleUrls[0]);\n        $this->factory->get($exampleUrls[1]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->factory->assertSentInOrder($exampleUrls);\n    }\n\n    public function testCanAssertAgainstOrderOfHttpRequestsWithCallables()\n    {\n        $this->factory->fake();\n\n        $exampleUrls = [\n            function ($request) {\n                return $request->url() === 'http://example.com/1';\n            },\n            function ($request) {\n                return $request->url() === 'http://example.com/2';\n            },\n            function ($request) {\n                return $request->url() === 'http://example.com/3';\n            },\n        ];\n\n        $this->factory->get('http://example.com/1');\n        $this->factory->get('http://example.com/2');\n        $this->factory->get('http://example.com/3');\n\n        $this->factory->assertSentInOrder($exampleUrls);\n    }\n\n    public function testCanAssertAgainstOrderOfHttpRequestsWithCallablesAndHeaders()\n    {\n        $this->factory->fake();\n\n        $executionOrder = [\n            function (Request $request) {\n                return $request->url() === 'http://foo.com/json' &&\n                       $request->hasHeader('Content-Type', 'application/json') &&\n                       $request->hasHeader('X-Test-Header', 'foo') &&\n                       $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                       $request['name'] === 'Taylor';\n            },\n            function (Request $request) {\n                return $request->url() === 'http://bar.com/json' &&\n                       $request->hasHeader('Content-Type', 'application/json') &&\n                       $request->hasHeader('X-Test-Header', 'bar') &&\n                       $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                       $request['name'] === 'Taylor';\n            },\n        ];\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'bar',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://bar.com/json', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->assertSentInOrder($executionOrder);\n    }\n\n    public function testCanAssertAgainstOrderOfHttpRequestsWithCallablesAndHeadersFailsCorrectly()\n    {\n        $this->factory->fake();\n\n        $executionOrder = [\n            function (Request $request) {\n                return $request->url() === 'http://bar.com/json' &&\n                       $request->hasHeader('Content-Type', 'application/json') &&\n                       $request->hasHeader('X-Test-Header', 'bar') &&\n                       $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                       $request['name'] === 'Taylor';\n            },\n            function (Request $request) {\n                return $request->url() === 'http://foo.com/json' &&\n                       $request->hasHeader('Content-Type', 'application/json') &&\n                       $request->hasHeader('X-Test-Header', 'foo') &&\n                       $request->hasHeader('X-Test-ArrayHeader', ['bar', 'baz']) &&\n                       $request['name'] === 'Taylor';\n            },\n        ];\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'foo',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://foo.com/json', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->factory->withHeaders([\n            'X-Test-Header' => 'bar',\n            'X-Test-ArrayHeader' => ['bar', 'baz'],\n        ])->post('http://bar.com/json', [\n            'name' => 'Taylor',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->factory->assertSentInOrder($executionOrder);\n    }\n\n    public function testCanDump()\n    {\n        $dumped = [];\n\n        VarDumper::setHandler(function ($value) use (&$dumped) {\n            $dumped[] = $value;\n        });\n\n        $this->factory->fake()->dump(1, 2, 3)->withOptions(['delay' => 1000])->get('http://foo.com');\n\n        $this->assertSame(1, $dumped[0]);\n        $this->assertSame(2, $dumped[1]);\n        $this->assertSame(3, $dumped[2]);\n        $this->assertInstanceOf(Request::class, $dumped[3]);\n        $this->assertSame(1000, $dumped[4]['delay']);\n\n        VarDumper::setHandler(null);\n    }\n\n    public function testResponseCanDump()\n    {\n        $dumped = [];\n\n        VarDumper::setHandler(function ($value) use (&$dumped) {\n            $dumped[] = $value;\n        });\n\n        $this->factory->fake([\n            '200.com' => $this->factory::response('hello', 200),\n        ]);\n\n        $this->factory->get('http://200.com')->dump();\n\n        $this->assertSame('\"GET http://200.com\" 200', $dumped[0]);\n        $this->assertSame('hello', $dumped[1]);\n\n        VarDumper::setHandler(null);\n    }\n\n    public function testResponseCanDumpWithKey()\n    {\n        $dumped = [];\n\n        VarDumper::setHandler(function ($value) use (&$dumped) {\n            $dumped[] = $value;\n        });\n\n        $this->factory->fake([\n            '200.com' => $this->factory::response(['hello' => 'world'], 200),\n        ]);\n\n        $this->factory->get('http://200.com')->dump('hello');\n\n        $this->assertSame('\"GET http://200.com\" 200', $dumped[0]);\n        $this->assertSame('world', $dumped[1]);\n\n        VarDumper::setHandler(null);\n    }\n\n    public function testResponseCanDumpHeaders()\n    {\n        $dumped = [];\n\n        VarDumper::setHandler(function ($value) use (&$dumped) {\n            $dumped[] = $value;\n        });\n\n        $this->factory->fake([\n            '200.com' => $this->factory::response('hello', 200, ['hello' => 'world']),\n        ]);\n\n        $this->factory->get('http://200.com')->dumpHeaders();\n\n        $this->assertSame(['hello' => ['world']], $dumped[0]);\n\n        VarDumper::setHandler(null);\n    }\n\n    public function testResponseSequenceIsMacroable()\n    {\n        ResponseSequence::macro('customMethod', function () {\n            return 'yes!';\n        });\n\n        $this->assertSame('yes!', $this->factory->fakeSequence()->customMethod());\n    }\n\n    public function testRequestsCanBeAsync()\n    {\n        $request = new PendingRequest($this->factory);\n\n        $promise = $request->async()->get('http://foo.com');\n\n        $this->assertInstanceOf(PromiseInterface::class, $promise);\n\n        $this->assertSame($promise, $request->getPromise());\n    }\n\n    public function testClientCanBeSet()\n    {\n        $client = $this->factory->buildClient();\n\n        $request = new PendingRequest($this->factory);\n\n        $this->assertNotSame($client, $request->buildClient());\n\n        $request->setClient($client);\n\n        $this->assertSame($client, $request->buildClient());\n    }\n\n    public function testRequestsCanReplaceOptions()\n    {\n        $request = new PendingRequest($this->factory);\n\n        $request = $request->withOptions(['http_errors' => true, 'connect_timeout' => 10]);\n\n        $this->assertSame(['connect_timeout' => 10, 'crypto_method' => 33, 'http_errors' => true, 'timeout' => 30], $request->getOptions());\n\n        $request = $request->withOptions(['connect_timeout' => 20]);\n\n        $this->assertSame(['connect_timeout' => 20, 'crypto_method' => 33, 'http_errors' => true, 'timeout' => 30], $request->getOptions());\n    }\n\n    public function testMultipleRequestsAreSentInThePool()\n    {\n        $this->factory->fake([\n            '200.com' => $this->factory::response('', 200),\n            '400.com' => $this->factory::response('', 400),\n            '500.com' => $this->factory::response('', 500),\n        ]);\n\n        $responses = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('200.com'),\n                $pool->get('400.com'),\n                $pool->get('500.com'),\n            ];\n        });\n\n        $this->assertSame(200, $responses[0]->status());\n        $this->assertSame(400, $responses[1]->status());\n        $this->assertSame(500, $responses[2]->status());\n    }\n\n    public function testMultipleRequestsAreSentInThePoolWithKeys()\n    {\n        $this->factory->fake([\n            '200.com' => $this->factory::response('', 200),\n            '400.com' => $this->factory::response('', 400),\n            '500.com' => $this->factory::response('', 500),\n        ]);\n\n        $responses = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->as('test200')->get('200.com'),\n                $pool->as('test400')->get('400.com'),\n                $pool->as('test500')->get('500.com'),\n                $pool->newRequest()->get('200.com'),\n            ];\n        });\n\n        $this->assertSame(200, $responses['test200']->status());\n        $this->assertSame(200, $responses[0]->status());\n        $this->assertSame(400, $responses['test400']->status());\n        $this->assertSame(500, $responses['test500']->status());\n    }\n\n    public function testMiddlewareRunsInPool()\n    {\n        $this->factory->fake(function (Request $request) {\n            return $this->factory->response('Fake');\n        });\n\n        $history = [];\n\n        $middleware = Middleware::history($history);\n\n        $responses = $this->factory->pool(fn (Pool $pool) => [\n            $pool->withMiddleware($middleware)->post('https://example.com', ['hyped-for' => 'laravel-movie']),\n        ]);\n\n        $response = $responses[0];\n\n        $this->assertSame('Fake', $response->body());\n\n        $this->assertCount(1, $history);\n\n        $this->assertSame('Fake', tap($history[0]['response']->getBody())->rewind()->getContents());\n\n        $this->assertSame(['hyped-for' => 'laravel-movie'], json_decode(tap($history[0]['request']->getBody())->rewind()->getContents(), true));\n    }\n\n    public function testPoolConcurrency()\n    {\n        $this->factory->fake([\n            '200.com' => $this->factory::response('', 200),\n            '400.com' => $this->factory::response('', 400),\n            '500.com' => $this->factory::response('', 500),\n        ]);\n\n        $responses = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('200.com'),\n                $pool->get('400.com'),\n                $pool->get('500.com'),\n            ];\n        }, 2);\n\n        $this->assertSame(200, $responses[0]->status());\n        $this->assertSame(400, $responses[1]->status());\n        $this->assertSame(500, $responses[2]->status());\n    }\n\n    public function testTheRequestSendingAndResponseReceivedEventsAreFiredWhenARequestIsSent()\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->times(5)->with(m::type(RequestSending::class));\n        $events->shouldReceive('dispatch')->times(5)->with(m::type(ResponseReceived::class));\n\n        $factory = new Factory($events);\n        $factory->fake();\n\n        $factory->get('https://example.com');\n        $factory->head('https://example.com');\n        $factory->post('https://example.com');\n        $factory->patch('https://example.com');\n        $factory->delete('https://example.com');\n    }\n\n    public function testTheRequestSendingAndResponseReceivedEventsAreFiredWhenARequestIsSentAsync()\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->times(5)->with(m::type(RequestSending::class));\n        $events->shouldReceive('dispatch')->times(5)->with(m::type(ResponseReceived::class));\n\n        $factory = new Factory($events);\n        $factory->fake();\n        $factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('https://example.com'),\n                $pool->head('https://example.com'),\n                $pool->post('https://example.com'),\n                $pool->patch('https://example.com'),\n                $pool->delete('https://example.com'),\n            ];\n        });\n    }\n\n    public function testTheRequestSendingAndResponseReceivedEventsAreFiredForEveryRetry()\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->times(2)->with(m::type(RequestSending::class));\n        $events->shouldReceive('dispatch')->times(2)->with(m::type(ResponseReceived::class));\n\n        $factory = new Factory($events);\n        $factory->fake([\n            '*' => $factory->response(['error'], 403),\n        ]);\n\n        $response = $factory->retry(2, 1000, null, false)->get('http://foo.com/get');\n\n        $this->assertTrue($response->failed());\n\n        $factory->assertSentCount(2);\n    }\n\n    public function testTheTransferStatsAreCalledSafelyWhenFakingTheRequest()\n    {\n        $this->factory->fake(['https://example.com' => ['world' => 'Hello world']]);\n        $stats = $this->factory->get('https://example.com')->handlerStats();\n        $effectiveUri = $this->factory->get('https://example.com')->effectiveUri();\n\n        $this->assertIsArray($stats);\n        $this->assertEmpty($stats);\n\n        $this->assertNull($effectiveUri);\n    }\n\n    public function testTransferStatsArePresentWhenFakingTheRequestUsingAPromiseResponse()\n    {\n        $this->factory->fake(['https://example.com' => $this->factory->response()]);\n        $effectiveUri = $this->factory->get('https://example.com')->effectiveUri();\n\n        $this->assertSame('https://example.com', (string) $effectiveUri);\n    }\n\n    public function testClonedClientsWorkSuccessfullyWithTheRequestObject()\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::type(RequestSending::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(ResponseReceived::class));\n\n        $factory = new Factory($events);\n        $factory->fake(['example.com' => $factory->response('foo', 200)]);\n\n        $client = $factory->timeout(10);\n        $clonedClient = clone $client;\n\n        $clonedClient->get('https://example.com');\n    }\n\n    public function testRequestIsMacroable()\n    {\n        Request::macro('customMethod', function () {\n            return 'yes!';\n        });\n\n        $this->factory->fake(function (Request $request) {\n            $this->assertSame('yes!', $request->customMethod());\n\n            return $this->factory->response();\n        });\n\n        $this->factory->get('https://example.com');\n    }\n\n    public function testRequestExceptionIsThrownWhenRetriesExhausted()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->retry(2, 1000, null, true)\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testRequestExceptionIsThrownWhenRetriesExhaustedWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->retry([1], 0, null, true)\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testRequestExceptionIsThrownWithoutRetriesIfRetryNotNecessary()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $exception = null;\n        $whenAttempts = 0;\n\n        try {\n            $this->factory\n                ->retry(2, 1000, function ($exception) use (&$whenAttempts) {\n                    $whenAttempts++;\n\n                    return $exception->response->status() === 403;\n                }, true)\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->assertSame(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestExceptionIsThrownWithoutRetriesIfRetryNotNecessaryWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $exception = null;\n        $whenAttempts = 0;\n\n        try {\n            $this->factory\n                ->retry([1000, 1000], 1000, function ($exception) use (&$whenAttempts) {\n                    $whenAttempts++;\n\n                    return $exception->response->status() === 403;\n                }, true)\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->assertSame(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestExceptionIsNotThrownWhenDisabledAndRetriesExhausted()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $response = $this->factory\n            ->retry(2, 1000, null, false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->failed());\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testRequestExceptionIsNotThrownWhenDisabledAndRetriesExhaustedWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $response = $this->factory\n            ->retry([1, 2], throw: false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->failed());\n\n        $this->factory->assertSentCount(3);\n    }\n\n    public function testRequestExceptionIsNotThrownWithoutRetriesIfRetryNotNecessary()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $whenAttempts = 0;\n\n        $response = $this->factory\n            ->retry(2, 1000, function ($exception) use (&$whenAttempts) {\n                $whenAttempts++;\n\n                return $exception->response->status() === 403;\n            }, false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->failed());\n\n        $this->assertSame(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestExceptionIsNotThrownWithoutRetriesIfRetryNotNecessaryWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $whenAttempts = 0;\n\n        $response = $this->factory\n            ->retry([1, 2], 0, function ($exception) use (&$whenAttempts) {\n                $whenAttempts++;\n\n                return $exception->response->status() === 403;\n            }, false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->failed());\n\n        $this->assertSame(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestCanBeModifiedInRetryCallback()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push(['error'], 500)\n                ->push(['ok'], 200),\n        ]);\n\n        $response = $this->factory\n            ->retry(2, 1000, function ($exception, $request) {\n                $this->assertInstanceOf(PendingRequest::class, $request);\n\n                $request->withHeaders(['Foo' => 'Bar']);\n\n                return true;\n            }, false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->successful());\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->hasHeader('Foo') && $request->header('Foo') === ['Bar'];\n        });\n    }\n\n    public function testRequestCanBeModifiedInRetryCallbackWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push(['error'], 500)\n                ->push(['ok'], 200),\n        ]);\n\n        $response = $this->factory\n            ->retry([2], when: function ($exception, $request) {\n                $this->assertInstanceOf(PendingRequest::class, $request);\n\n                $request->withHeaders(['Foo' => 'Bar']);\n\n                return true;\n            }, throw: false)\n            ->get('http://foo.com/get');\n\n        $this->assertTrue($response->successful());\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->hasHeader('Foo') && $request->header('Foo') === ['Bar'];\n        });\n    }\n\n    public function testExceptionThrownInRetryCallbackWithoutRetrying()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->retry(2, 1000, function ($exception) use (&$whenAttempts) {\n                    throw new Exception('Foo bar');\n                }, false)\n                ->get('http://foo.com/get');\n        } catch (Exception $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(Exception::class, $exception);\n        $this->assertEquals('Foo bar', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testExceptionThrownInRetryCallbackWithoutRetryingWithBackoffArray()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->retry([1, 2, 3], when: function ($exception) use (&$whenAttempts) {\n                    throw new Exception('Foo bar');\n                }, throw: false)\n                ->get('http://foo.com/get');\n        } catch (Exception $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(Exception::class, $exception);\n        $this->assertEquals('Foo bar', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestsWillBeWaitingSleepMillisecondsReceivedBeforeRetry()\n    {\n        Sleep::fake();\n\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push(['error'], 500)\n                ->push(['error'], 500)\n                ->push(['ok'], 200),\n        ]);\n\n        $this->factory\n            ->retry(3, function ($attempt, $exception) {\n                $this->assertInstanceOf(RequestException::class, $exception);\n\n                return $attempt * 100;\n            }, null, true)\n            ->get('http://foo.com/get');\n\n        $this->factory->assertSentCount(3);\n\n        // Make sure we waited 300ms for the first two attempts\n        Sleep::assertSleptTimes(2);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n            Sleep::usleep(200_000),\n        ]);\n    }\n\n    public function testRequestExceptionReturnedWhenRetriesExhaustedInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, null, true)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testRequestExceptionIsReturnedWithoutRetriesIfRetryNotNecessaryInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $whenAttempts = collect();\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, function ($exception) use ($whenAttempts) {\n                $whenAttempts->push($exception);\n\n                return $exception->response->status() === 403;\n            }, true)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->assertCount(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestExceptionIsNotReturnedWhenDisabledAndRetriesExhaustedInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, null, false)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($response);\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($response->failed());\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testRequestExceptionIsNotReturnedWithoutRetriesIfRetryNotNecessaryInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        $whenAttempts = collect();\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, function ($exception) use ($whenAttempts) {\n                $whenAttempts->push($exception);\n\n                return $exception->response->status() === 403;\n            }, false)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($response);\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertTrue($response->failed());\n\n        $this->assertCount(1, $whenAttempts);\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testRequestCanBeModifiedInRetryCallbackInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push(['error'], 500)\n                ->push(['ok'], 200),\n        ]);\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, function ($exception, $request) {\n                $this->assertInstanceOf(PendingRequest::class, $request);\n\n                $request->withHeaders(['Foo' => 'Bar']);\n\n                return true;\n            }, false)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertTrue($response->successful());\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->hasHeader('Foo') && $request->header('Foo') === ['Bar'];\n        });\n    }\n\n    public function testHandleRequestExeptionWithNoResponseInPoolConsideredConnectionException()\n    {\n        $requestException = new GuzzleRequestException('Error', new \\GuzzleHttp\\Psr7\\Request('GET', '/'));\n        $this->factory->fake([\n            'noresponse.com' => new RejectedPromise($requestException),\n        ]);\n\n        $responses = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('noresponse.com'),\n            ];\n        });\n\n        self::assertInstanceOf(ConnectionException::class, $responses[0]);\n        self::assertSame($requestException, $responses[0]->getPrevious());\n    }\n\n    public function testExceptionThrownInRetryCallbackIsReturnedWithoutRetryingInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 500),\n        ]);\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(2, 1000, function ($exception) {\n                throw new Exception('Foo bar');\n            }, false)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(Exception::class, $exception);\n        $this->assertEquals('Foo bar', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testExceptionThrowInMiddlewareAllowsRetry()\n    {\n        $middleware = Middleware::mapRequest(function (RequestInterface $request) {\n            throw new RuntimeException;\n        });\n\n        $this->expectException(RuntimeException::class);\n\n        $this->factory->fake(function (Request $request) {\n            return $this->factory->response('Fake');\n        })->withMiddleware($middleware)\n            ->retry(3, 1, function (Exception $exception, PendingRequest $request) {\n                return true;\n            })->post('https://example.com');\n    }\n\n    public function testRequestsWillBeWaitingSleepMillisecondsReceivedInBackoffArray()\n    {\n        Sleep::fake();\n\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->push(['error'], 500)\n                ->push(['error'], 500)\n                ->push(['error'], 500)\n                ->push(['ok'], 200),\n        ]);\n\n        $this->factory\n            ->retry([50, 100, 200], 0, null, true)\n            ->get('http://foo.com/get');\n\n        $this->factory->assertSentCount(4);\n\n        // Make sure we waited 300ms for the first two attempts\n        Sleep::assertSleptTimes(3);\n\n        Sleep::assertSequence([\n            Sleep::usleep(50_000),\n            Sleep::usleep(100_000),\n            Sleep::usleep(200_000),\n        ]);\n    }\n\n    public function testFailedRequest()\n    {\n        $requestException = $this->factory->failedRequest(['code' => 'not_found'], 404, ['X-RateLimit-Remaining' => 199]);\n\n        $this->assertInstanceOf(RequestException::class, $requestException);\n        $this->assertEqualsCanonicalizing(['code' => 'not_found'], $requestException->response->json());\n        $this->assertEquals(404, $requestException->response->status());\n        $this->assertEquals(199, $requestException->response->header('X-RateLimit-Remaining'));\n    }\n\n    public function testFakeConnectionException()\n    {\n        $this->factory->fake($this->factory->failedConnection('Fake'));\n\n        $exception = null;\n\n        try {\n            $this->factory->post('https://example.com');\n        } catch (Throwable $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(ConnectionException::class, $exception);\n        $this->assertSame('Fake', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n        $this->factory->assertSent(function (Request $request, ?Response $response) {\n            return $request->url() === 'https://example.com' && $response === null;\n        });\n    }\n\n    public function testFakeConnectionExceptionWithinFakeClosure()\n    {\n        $this->factory->fake(fn () => $this->factory->failedConnection('Fake'));\n\n        $exception = null;\n\n        try {\n            $this->factory->post('https://example.com');\n        } catch (Throwable $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(ConnectionException::class, $exception);\n        $this->assertSame('Fake', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testFakeConnectionExceptionWithinArray()\n    {\n        $this->factory->fake(['*' => $this->factory->failedConnection('Fake')]);\n\n        $exception = null;\n\n        try {\n            $this->factory->post('https://example.com');\n        } catch (Throwable $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(ConnectionException::class, $exception);\n        $this->assertSame('Fake', $exception->getMessage());\n\n        $this->factory->assertSentCount(1);\n    }\n\n    public function testFakeConnectionExceptionWithinSequence()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->sequence()\n                ->pushFailedConnection('Fake')\n                ->push('Success'),\n        ]);\n\n        $exception = null;\n\n        $response = $this->factory->retry(3, function ($attempt, $e) use (&$exception) {\n            $exception = $e;\n\n            return true;\n        })->post('https://example.com');\n\n        $this->assertSame('Success', $response->body());\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(ConnectionException::class, $exception);\n        $this->assertSame('Fake', $exception->getMessage());\n\n        $this->factory->assertSentCount(2);\n    }\n\n    public function testMiddlewareRunsWhenFaked()\n    {\n        $this->factory->fake(function (Request $request) {\n            return $this->factory->response('Fake');\n        });\n\n        $history = [];\n\n        $pendingRequest = $this->factory->withMiddleware(\n            Middleware::history($history)\n        );\n\n        $response = $pendingRequest->post('https://example.com', ['hyped-for' => 'laravel-movie']);\n\n        $this->assertSame('Fake', $response->body());\n\n        $this->assertCount(1, $history);\n\n        $this->assertSame('Fake', tap($history[0]['response']->getBody())->rewind()->getContents());\n\n        $this->assertSame(['hyped-for' => 'laravel-movie'], json_decode(tap($history[0]['request']->getBody())->rewind()->getContents(), true));\n    }\n\n    public function testMiddlewareRunsAndCanChangeRequestOnAssertSent()\n    {\n        $this->factory->fake(function (Request $request) {\n            return $this->factory->response('Fake');\n        });\n\n        $pendingRequest = $this->factory->withMiddleware(\n            Middleware::mapRequest(fn (RequestInterface $request) => $request->withHeader('X-Test-Header', 'Test'))\n        );\n\n        $pendingRequest->post('https://laravel.example', ['laravel' => 'framework']);\n\n        $this->factory->assertSent(function (Request $request) {\n            return\n                $request->url() === 'https://laravel.example' &&\n                $request->hasHeader('X-Test-Header', 'Test');\n        });\n    }\n\n    public function testSslCertificateErrorsConvertedToConnectionException()\n    {\n        $this->factory->fake(function () {\n            $request = new GuzzleRequest('HEAD', 'https://ssl-error.laravel.example');\n            throw new GuzzleRequestException(\n                'cURL error 60: SSL certificate problem: unable to get local issuer certificate',\n                $request\n            );\n        });\n\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('cURL error 60: SSL certificate problem: unable to get local issuer certificate');\n\n        $this->factory->head('https://ssl-error.laravel.example');\n    }\n\n    public function testConnectExceptionIsConvertedToConnectionExceptionEvenWhenWithoutFactory()\n    {\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('cURL error 60: SSL certificate problem');\n\n        $pendingRequest = new PendingRequest();\n\n        $pendingRequest->setHandler(function () {\n            throw new ConnectException(\n                'cURL error 60: SSL certificate problem: unable to get local issuer certificate',\n                new GuzzleRequest('HEAD', 'https://ssl-error.laravel.example')\n            );\n        });\n\n        $pendingRequest->head('https://ssl-error.laravel.example');\n    }\n\n    public function testRequestExceptionWithoutResponseIsConvertedToConnectionExceptionEvenWhenWithoutFactory()\n    {\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('cURL error 28: Operation timed out');\n\n        $pendingRequest = new PendingRequest();\n\n        $pendingRequest->setHandler(function () {\n            throw new GuzzleRequestException(\n                'cURL error 28: Operation timed out',\n                new GuzzleRequest('GET', 'https://timeout-laravel.example')\n            );\n        });\n\n        $pendingRequest->get('https://timeout-laravel.example');\n    }\n\n    public function testRequestExceptionWithResponseIsConvertedToConnectionExceptionEvenWhenWithoutFactory()\n    {\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('cURL error 28: Operation timed out');\n\n        $pendingRequest = new PendingRequest();\n\n        $pendingRequest->setHandler(function () {\n            throw new GuzzleRequestException(\n                'cURL error 28: Operation timed out',\n                new GuzzleRequest('GET', 'https://timeout-laravel.example'),\n                new Psr7Response(301)\n            );\n        });\n\n        $pendingRequest->get('https://timeout-laravel.example');\n    }\n\n    public function testTooManyRedirectsExceptionIsConvertedToConnectionExceptionEvenWhenWithoutFactory()\n    {\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('Maximum number of redirects (5) exceeded');\n\n        $pendingRequest = new PendingRequest();\n\n        $pendingRequest->setHandler(function () {\n            throw new TooManyRedirectsException(\n                'Maximum number of redirects (5) exceeded',\n                new GuzzleRequest('GET', 'https://redirect.laravel.example'),\n                new Psr7Response(301)\n            );\n        });\n\n        $pendingRequest->maxRedirects(5)->get('https://redirect.laravel.example');\n    }\n\n    public function testTooManyRedirectsExceptionConvertedToConnectionException()\n    {\n        $this->factory->fake(function () {\n            $request = new GuzzleRequest('GET', 'https://redirect.laravel.example');\n            $response = new Psr7Response(301, ['Location' => 'https://redirect2.laravel.example']);\n\n            throw new TooManyRedirectsException(\n                'Maximum number of redirects (5) exceeded',\n                $request,\n                $response\n            );\n        });\n\n        $this->expectException(ConnectionException::class);\n        $this->expectExceptionMessage('Maximum number of redirects (5) exceeded');\n\n        $this->factory->maxRedirects(5)->get('https://redirect.laravel.example');\n    }\n\n    public function testTooManyRedirectsWithFakedRedirectChain()\n    {\n        $this->factory->fake([\n            '1.example.com' => $this->factory->response(null, 301, ['Location' => 'https://2.example.com']),\n            '2.example.com' => $this->factory->response(null, 301, ['Location' => 'https://3.example.com']),\n            '3.example.com' => $this->factory->response('', 200),\n        ]);\n\n        $this->expectException(ConnectionException::class);\n\n        $this->factory->maxRedirects(1)->get('https://1.example.com');\n    }\n\n    public function testRequestExceptionIsNotThrownIfThePendingRequestIsSetToThrowOnFailureButTheResponseIsSuccessful()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['success'], 200),\n        ]);\n\n        $response = $this->factory\n            ->throw()\n            ->get('http://foo.com/get');\n\n        $this->assertSame(200, $response->status());\n    }\n\n    public function testRequestExceptionIsThrownIfThePendingRequestIsSetToThrowOnFailure()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->throw()\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsThrownIfTheThrowIfOnThePendingRequestIsSetToTrueOnFailure()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory\n                ->throwIf(true)\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotThrownIfTheThrowIfOnThePendingRequestIsSetToFalseOnFailure()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $response = $this->factory\n            ->throwIf(false)\n            ->get('http://foo.com/get');\n\n        $this->assertSame(403, $response->status());\n    }\n\n    public function testRequestExceptionIsThrownIfTheThrowIfClosureOnThePendingRequestReturnsTrue()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        $hitThrowCallback = false;\n\n        try {\n            $this->factory\n                ->throwIf(function ($response) {\n                    $this->assertInstanceOf(Response::class, $response);\n                    $this->assertSame(403, $response->status());\n\n                    return true;\n                }, function ($response, $e) use (&$hitThrowCallback) {\n                    $this->assertInstanceOf(Response::class, $response);\n                    $this->assertSame(403, $response->status());\n\n                    $this->assertInstanceOf(RequestException::class, $e);\n                    $hitThrowCallback = true;\n                })\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n        $this->assertTrue($hitThrowCallback);\n    }\n\n    public function testRequestExceptionIsNotThrownIfTheThrowIfClosureOnThePendingRequestReturnsFalse()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $hitThrowCallback = false;\n\n        $response = $this->factory\n            ->throwIf(function ($response) {\n                $this->assertInstanceOf(Response::class, $response);\n                $this->assertSame(403, $response->status());\n\n                return false;\n            }, function ($response, $e) use (&$hitThrowCallback) {\n                $hitThrowCallback = true;\n            })\n            ->get('http://foo.com/get');\n\n        $this->assertSame(403, $response->status());\n        $this->assertFalse($hitThrowCallback);\n    }\n\n    public function testRequestExceptionIsThrownWithCallbackIfThePendingRequestIsSetToThrowOnFailure()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $exception = null;\n\n        $flag = false;\n\n        try {\n            $this->factory\n                ->throw(function ($exception) use (&$flag) {\n                    $flag = true;\n                })\n                ->get('http://foo.com/get');\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertTrue($flag);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsThrownIfTheRequestFails()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throw();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsThrownWithCallbackIfTheRequestFails()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        $flag = false;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throw(function () use (&$flag) {\n                $flag = true;\n            });\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertTrue($flag);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotThrownIfTheRequestDoesNotFail()\n    {\n        $this->factory->fake([\n            '*' => ['result' => ['foo' => 'bar']],\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api')->throw();\n\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', $response->body());\n    }\n\n    public function testRequestExceptionIsNotReturnedIfThePendingRequestIsSetToThrowOnFailureButTheResponseIsSuccessfulInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['success'], 200),\n        ]);\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->throw()->get('http://foo.com/get'),\n        ]);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertSame(200, $response->status());\n    }\n\n    public function testRequestExceptionIsReturnedIfThePendingRequestIsSetToThrowOnFailureInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->throw()->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsReturnedIfTheThrowIfOnThePendingRequestIsSetToTrueOnFailureInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->throwIf(true)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotReturnedIfTheThrowIfOnThePendingRequestIsSetToFalseOnFailureInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->throwIf(false)->get('http://foo.com/get'),\n        ]);\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertSame(403, $response->status());\n    }\n\n    public function testRequestExceptionIsReturnedIfTheThrowIfClosureOnThePendingRequestReturnsTrueInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $hitThrowCallback = collect();\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->throwIf(function ($response) {\n                $this->assertInstanceOf(Response::class, $response);\n                $this->assertSame(403, $response->status());\n\n                return true;\n            }, function ($response, $e) use (&$hitThrowCallback) {\n                $this->assertInstanceOf(Response::class, $response);\n                $this->assertSame(403, $response->status());\n\n                $this->assertInstanceOf(RequestException::class, $e);\n\n                $hitThrowCallback->push(true);\n            })->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n        $this->assertCount(1, $hitThrowCallback);\n    }\n\n    public function testRequestExceptionIsNotReturnedIfTheThrowIfClosureOnThePendingRequestReturnsFalseInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $hitThrowCallback = collect();\n\n        [$response] = $this->factory->pool(fn ($pool) => [\n            $pool->throwIf(function ($response) {\n                $this->assertInstanceOf(Response::class, $response);\n                $this->assertSame(403, $response->status());\n\n                return false;\n            }, function ($response, $e) use (&$hitThrowCallback) {\n                $hitThrowCallback->push(true);\n            })->get('http://foo.com/get'),\n        ]);\n\n        $this->assertCount(0, $hitThrowCallback);\n        $this->assertSame(403, $response->status());\n    }\n\n    public function testRequestExceptionIsReturnedWithCallbackIfThePendingRequestIsSetToThrowOnFailureInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        $flag = collect();\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->throw(function ($exception) use (&$flag) {\n                $flag->push(true);\n            })->get('http://foo.com/get'),\n        ]);\n\n        $this->assertCount(1, $flag);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsReturnedAfterLastRetryInPool()\n    {\n        $this->factory->fake([\n            '*' => $this->factory->response(['error'], 403),\n        ]);\n\n        [$exception] = $this->factory->pool(fn ($pool) => [\n            $pool->retry(3)->throw()->get('http://foo.com/get'),\n        ]);\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $this->factory->assertSentCount(3);\n    }\n\n    public function testRequestExceptionIsThrowIfConditionIsSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIf(true);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotThrownIfConditionIsNotSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response(['result' => ['foo' => 'bar']], 400),\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api')->throwIf(false);\n\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', $response->body());\n    }\n\n    public function testRequestExceptionIsThrownWhenUnlessConditionIsNotSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwUnless(false);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotThrownWhenUnlessConditionIsSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response(['result' => ['foo' => 'bar']], 400),\n        ]);\n\n        $response = $this->factory->get('http://foo.com/api')->throwUnless(true);\n\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', $response->body());\n    }\n\n    public function testRequestExceptionIsThrowIfConditionClosureIsSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        $hitThrowCallback = false;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIf(function ($response) {\n                $this->assertSame(400, $response->status());\n\n                return true;\n            }, function ($response, $e) use (&$hitThrowCallback) {\n                $this->assertSame(400, $response->status());\n                $this->assertInstanceOf(RequestException::class, $e);\n\n                $hitThrowCallback = true;\n            });\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n        $this->assertTrue($hitThrowCallback);\n    }\n\n    public function testRequestExceptionIsNotThrownIfConditionClosureIsNotSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response(['result' => ['foo' => 'bar']], 400),\n        ]);\n\n        $hitThrowCallback = false;\n\n        $response = $this->factory->get('http://foo.com/api')->throwIf(function ($response) {\n            $this->assertSame(400, $response->status());\n\n            return false;\n        }, function ($response, $e) use (&$hitThrowCallback) {\n            $hitThrowCallback = true;\n        });\n\n        $this->assertSame('{\"result\":{\"foo\":\"bar\"}}', $response->body());\n        $this->assertFalse($hitThrowCallback);\n    }\n\n    public function testRequestExceptionIsThrownIfStatusCodeIsSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIfStatus(400);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsThrownIfStatusCodeIsSatisfiedWithClosure()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIfStatus(fn ($status) => $status === 400);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsNotThrownIfStatusCodeIsNotSatisfied()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 400),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIfStatus(500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n    }\n\n    public function testRequestExceptionIsThrownUnlessStatusCodeIsSatisfied()\n    {\n        $this->factory->fake([\n            'http://foo.com/api/400' => $this->factory::response('', 400),\n            'http://foo.com/api/408' => $this->factory::response('', 408),\n            'http://foo.com/api/500' => $this->factory::response('', 500),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/400')->throwUnlessStatus(500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        $this->factory->fake([\n            'http://foo.com/api/400' => $this->factory::response('', 400),\n            'http://foo.com/api/408' => $this->factory::response('', 408),\n            'http://foo.com/api/500' => $this->factory::response('', 500),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/400')->throwUnlessStatus(fn ($status) => $status === 500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/408')->throwUnlessStatus(500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/500')->throwUnlessStatus(500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/500')->throwUnlessStatus(fn ($status) => $status === 500);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n    }\n\n    public function testRequestExceptionIsThrownIfIsClientError()\n    {\n        $this->factory->fake([\n            'http://foo.com/api/400' => $this->factory::response('', 400),\n            'http://foo.com/api/408' => $this->factory::response('', 408),\n            'http://foo.com/api/500' => $this->factory::response('', 500),\n            'http://foo.com/api/504' => $this->factory::response('', 504),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/400')->throwIfClientError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/408')->throwIfClientError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/500')->throwIfClientError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/504')->throwIfClientError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n    }\n\n    public function testThrowIfStatusWorksWithNonErrorStatusCodes()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 201),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIfStatus(201);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwIfStatus(fn ($status) => $status === 201);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testThrowUnlessStatusWorksWithNonErrorStatusCodes()\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('', 201),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwUnlessStatus(200);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwUnlessStatus(201);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api')->throwUnlessStatus(fn ($status) => $status === 200);\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testRequestExceptionIsThrownIfIsServerError()\n    {\n        $this->factory->fake([\n            'http://foo.com/api/400' => $this->factory::response('', 400),\n            'http://foo.com/api/408' => $this->factory::response('', 408),\n            'http://foo.com/api/500' => $this->factory::response('', 500),\n            'http://foo.com/api/504' => $this->factory::response('', 504),\n        ]);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/400')->throwIfServerError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/408')->throwIfServerError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNull($exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/500')->throwIfServerError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n\n        $exception = null;\n\n        try {\n            $this->factory->get('http://foo.com/api/504')->throwIfServerError();\n        } catch (RequestException $e) {\n            $exception = $e;\n        }\n\n        $this->assertNotNull($exception);\n        $this->assertInstanceOf(RequestException::class, $exception);\n    }\n\n    public function testItCanEnforceFaking()\n    {\n        $this->factory->preventStrayRequests();\n        $this->factory->fake(['https://vapor.laravel.com' => Factory::response('ok', 200)]);\n        $this->factory->fake(['https://forge.laravel.com' => Factory::response('ok', 200)]);\n\n        $responses = [];\n        $responses[] = $this->factory->get('https://vapor.laravel.com')->body();\n        $responses[] = $this->factory->get('https://forge.laravel.com')->body();\n        $this->assertSame(['ok', 'ok'], $responses);\n\n        $this->expectException(StrayRequestException::class);\n        $this->expectExceptionMessage('Attempted request to [https://laravel.com] without a matching fake.');\n\n        $this->factory->get('https://laravel.com');\n    }\n\n    public function testItCanEnforceFakingInThePool()\n    {\n        $this->factory->preventStrayRequests();\n        $this->factory->fake(['https://vapor.laravel.com' => Factory::response('ok', 200)]);\n        $this->factory->fake(['https://forge.laravel.com' => Factory::response('ok', 200)]);\n\n        $responses = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('https://vapor.laravel.com'),\n                $pool->get('https://forge.laravel.com'),\n            ];\n        });\n\n        $this->assertSame(200, $responses[0]->status());\n        $this->assertSame(200, $responses[1]->status());\n\n        [$exception] = $this->factory->pool(function (Pool $pool) {\n            return [\n                $pool->get('https://laravel.com'),\n            ];\n        });\n\n        $this->assertInstanceOf(StrayRequestException::class, $exception);\n        $this->assertEquals('Attempted request to [https://laravel.com] without a matching fake.', $exception->getMessage());\n    }\n\n    public function testPreventingStrayRequests()\n    {\n        $this->assertFalse($this->factory->preventingStrayRequests());\n\n        $this->factory->preventStrayRequests();\n\n        $this->assertTrue($this->factory->preventingStrayRequests());\n    }\n\n    public function testAllowingStrayRequestUrls()\n    {\n        $this->assertFalse($this->factory->preventingStrayRequests());\n        $this->assertTrue($this->factory->isAllowedRequestUrl('127.0.0.1'));\n\n        $this->factory->preventStrayRequests();\n        $this->assertFalse($this->factory->isAllowedRequestUrl('127.0.0.1'));\n        $this->factory->allowStrayRequests([\n            '127.0.0.1',\n        ]);\n\n        $this->assertTrue($this->factory->preventingStrayRequests());\n        $this->assertTrue($this->factory->isAllowedRequestUrl('127.0.0.1'));\n    }\n\n    public function testItCanAddAuthorizationHeaderIntoRequestUsingBeforeSendingCallback()\n    {\n        $this->factory->fake();\n\n        $this->factory->beforeSending(function (Request $request) {\n            $requestLine = sprintf(\n                '%s %s HTTP/%s',\n                $request->toPsrRequest()->getMethod(),\n                $request->toPsrRequest()->getUri()->withScheme('')->withHost(''),\n                $request->toPsrRequest()->getProtocolVersion()\n            );\n\n            return $request->toPsrRequest()->withHeader('Authorization', 'Bearer '.$requestLine);\n        })->get('http://foo.com/json');\n\n        $this->factory->assertSent(function (Request $request) {\n            return\n                $request->url() === 'http://foo.com/json' &&\n                $request->hasHeader('Authorization', 'Bearer GET /json HTTP/1.1');\n        });\n    }\n\n    public function testItCanSetAllowMaxRedirects(): void\n    {\n        $request = new PendingRequest($this->factory);\n\n        $request = $request->withOptions(['allow_redirects' => ['max' => 5]]);\n\n        $this->assertSame(['connect_timeout' => 10, 'crypto_method' => 33, 'http_errors' => false, 'timeout' => 30, 'allow_redirects' => ['max' => 5]], $request->getOptions());\n\n        $request = $request->maxRedirects(10);\n\n        $this->assertSame(['connect_timeout' => 10, 'crypto_method' => 33, 'http_errors' => false, 'timeout' => 30, 'allow_redirects' => ['max' => 10]], $request->getOptions());\n    }\n\n    public function testPreventDuplicatedContentType(): void\n    {\n        $client = $this->factory->asJson();\n\n        $this->assertSame('application/json', Arr::get($client->getOptions(), 'headers.Content-Type'));\n\n        $client->asJson();\n        $client->asJson();\n\n        $this->assertSame('application/json', Arr::get($client->getOptions(), 'headers.Content-Type'));\n\n        $client->contentType('foo');\n\n        $this->assertSame('foo', Arr::get($client->getOptions(), 'headers.Content-Type'));\n    }\n\n    public function testItCanSubstituteUrlParams(): void\n    {\n        $this->factory->fake();\n\n        $this->factory->withUrlParameters([\n            'endpoint' => 'https://laravel.com',\n            'page' => 'docs',\n            'version' => '9.x',\n            'thing' => 'validation',\n        ])->get('{+endpoint}/{page}/{version}/{thing}');\n\n        $this->factory->assertSent(function (Request $request) {\n            return $request->url() === 'https://laravel.com/docs/9.x/validation';\n        });\n    }\n\n    public function testTheTransferStatsAreCustomizable(): void\n    {\n        $onStatsFunctionCalled = false;\n\n        $stats = $this->factory\n            ->withOptions([\n                'on_stats' => function (TransferStats $stats) use (&$onStatsFunctionCalled) {\n                    $onStatsFunctionCalled = true;\n                },\n            ])\n            ->get('http://example.com')\n            ->handlerStats();\n\n        $this->assertIsArray($stats);\n        $this->assertNotEmpty($stats);\n        $this->assertTrue($onStatsFunctionCalled);\n    }\n\n    public function testTheTransferStatsAreCustomizableOnFake(): void\n    {\n        $onStatsFunctionCalled = false;\n\n        $this->factory\n            ->fake()\n            ->withOptions([\n                'on_stats' => function (TransferStats $stats) use (&$onStatsFunctionCalled) {\n                    $onStatsFunctionCalled = true;\n                },\n            ])\n            ->get('https://foo.bar')\n            ->handlerStats();\n\n        $this->assertTrue($onStatsFunctionCalled);\n    }\n\n    public function testItCanAddGlobalMiddleware()\n    {\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n        $requests = [];\n        $responses = [];\n        $this->factory->fake(function ($r) use (&$requests) {\n            $requests[] = $r;\n\n            Carbon::setTestNow(Carbon::now()->addSeconds(6 * count($requests)));\n\n            return $this->factory::response('expected content');\n        });\n\n        $this->factory->globalMiddleware(Middleware::mapRequest(function ($request) {\n            // Test manipulating headers on outgoing request...\n            return $request->withHeader('User-Agent', 'Laravel Framework/1.0')\n                ->withAddedHeader('shared', 'global')\n                ->withHeader('list', ['item-1', 'item-2'])\n                ->withAddedHeader('list', ['item-3']);\n        }))->globalMiddleware(Middleware::mapResponse(function ($response) use (&$requests) {\n            // Test adding headers in incoming response..\n            return $response->withHeader('X-Count', (string) count($requests));\n        }))->globalMiddleware(function ($handler) {\n            // Test wrapping request in timing function...\n            return function ($request, $options) use ($handler) {\n                $startedAt = Carbon::now();\n\n                return $handler($request, $options)->then(function (ResponseInterface $response) use ($startedAt) {\n                    return $response->withHeader('X-Duration', \"{$startedAt->diffInSeconds(Carbon::now())} seconds\");\n                });\n            };\n        });\n        $responses[] = $this->factory->post('http://forge.laravel.com');\n        $responses[] = $this->factory->withHeader('shared', 'local')->post('http://vapor.laravel.com');\n\n        $this->assertCount(2, $requests);\n        $this->assertCount(2, $responses);\n\n        $this->assertSame(['Laravel Framework/1.0'], $requests[0]->header('User-Agent'));\n        $this->assertSame(['item-1', 'item-2', 'item-3'], $requests[0]->header('list'));\n        $this->assertSame(['global'], $requests[0]->header('shared'));\n        $this->assertSame('1', $responses[0]->header('X-Count'));\n        $this->assertSame('6 seconds', $responses[0]->header('X-Duration'));\n\n        $this->assertSame(['Laravel Framework/1.0'], $requests[1]->header('User-Agent'));\n        $this->assertSame(['item-1', 'item-2', 'item-3'], $requests[1]->header('list'));\n        $this->assertSame(['local', 'global'], $requests[1]->header('shared'));\n        $this->assertSame('2', $responses[1]->header('X-Count'));\n        $this->assertSame('12 seconds', $responses[1]->header('X-Duration'));\n    }\n\n    public function testItCanAddGlobalRequestMiddleware()\n    {\n        $requests = [];\n        $this->factory->fake(function ($r) use (&$requests) {\n            $requests[] = $r;\n\n            return Factory::response('expected content');\n        });\n\n        $this->factory->globalRequestMiddleware(function ($request) {\n            return $request->withHeader('User-Agent', 'Laravel Framework/1.0');\n        });\n        $this->factory->post('http://forge.laravel.com');\n        $this->factory->post('http://laravel.com');\n\n        $this->assertSame(['Laravel Framework/1.0'], $requests[0]->header('User-Agent'));\n        $this->assertSame(['Laravel Framework/1.0'], $requests[1]->header('User-Agent'));\n    }\n\n    public function testItCanAddGlobalResponseMiddleware()\n    {\n        $responses = [];\n        $this->factory->fake(function ($r) use (&$request) {\n            return Factory::response('expected content');\n        });\n\n        $this->factory->globalResponseMiddleware(function ($response) {\n            return $response->withHeader('X-Foo', 'Bar');\n        });\n        $responses[] = $this->factory->post('http://forge.laravel.com');\n        $responses[] = $this->factory->post('http://laravel.com');\n\n        $this->assertSame('Bar', $responses[0]->header('X-Foo'));\n        $this->assertSame('Bar', $responses[1]->header('X-Foo'));\n    }\n\n    public function testItCanGetTheGlobalMiddleware()\n    {\n        $this->factory->globalMiddleware($middleware = fn () => null);\n\n        $this->assertEquals([$middleware], $this->factory->getGlobalMiddleware());\n    }\n\n    public function testItCanAddRequestMiddleware()\n    {\n        $requests = [];\n        $this->factory->fake(function ($r) use (&$requests) {\n            $requests[] = $r;\n\n            return Factory::response('expected content');\n        });\n\n        $this->factory->withRequestMiddleware(function ($request) {\n            return $request->withHeader('User-Agent', 'Laravel Framework/1.0');\n        })->post('http://forge.laravel.com');\n        $this->factory->post('http://laravel.com');\n\n        $this->assertSame(['Laravel Framework/1.0'], $requests[0]->header('User-Agent'));\n        $this->assertSame(['GuzzleHttp/7'], $requests[1]->header('User-Agent'));\n    }\n\n    public function testItCanAddResponseMiddleware()\n    {\n        $responses = [];\n        $this->factory->fake(function ($r) use (&$request) {\n            return Factory::response('expected content');\n        });\n\n        $responses[] = $this->factory->withResponseMiddleware(function ($response) {\n            return $response->withHeader('X-Foo', 'Bar');\n        })->post('http://forge.laravel.com');\n        $responses[] = $this->factory->post('http://laravel.com');\n\n        $this->assertSame('Bar', $responses[0]->header('X-Foo'));\n        $this->assertSame('', $responses[1]->header('X-Foo'));\n    }\n\n    public function testItReturnsResponse(): void\n    {\n        $this->factory->fake([\n            '*' => $this->factory::response('expected content'),\n        ]);\n\n        $response = $this->factory->get('http://laravel.com');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertSame('expected content', $response->body());\n    }\n\n    public function testItCanReturnCustomResponseClass(): void\n    {\n        $factory = new CustomFactory;\n\n        $factory->fake([\n            '*' => $factory::response('expected content'),\n        ]);\n\n        $response = $factory->get('http://laravel.fake');\n\n        $this->assertInstanceOf(TestResponse::class, $response);\n        $this->assertSame('expected content', $response->body());\n    }\n\n    public function testItCanHaveGlobalDefaultValues()\n    {\n        $factory = new Factory;\n        $timeout = null;\n        $allowRedirects = null;\n        $headers = null;\n        $factory->fake(function ($request, $options) use (&$timeout, &$allowRedirects, &$headers, $factory) {\n            $timeout = $options['timeout'];\n            $allowRedirects = $options['allow_redirects'];\n            $headers = $request->headers();\n\n            return $factory->response('');\n        });\n\n        $factory->get('https://laravel.com');\n        $this->assertSame(30, $timeout);\n        $this->assertSame(['max' => 5, 'protocols' => ['http', 'https'], 'strict' => false, 'referer' => false, 'track_redirects' => false], $allowRedirects);\n        $this->assertNull($headers['X-Foo'] ?? null);\n\n        $factory->globalOptions([\n            'timeout' => 5,\n            'allow_redirects' => false,\n            'headers' => [\n                'X-Foo' => 'true',\n            ],\n        ]);\n\n        $factory->get('https://laravel.com');\n        $this->assertSame(5, $timeout);\n        $this->assertFalse($allowRedirects);\n        $this->assertSame(['true'], $headers['X-Foo']);\n\n        $factory->globalOptions(fn () => [\n            'timeout' => 10,\n            'headers' => [\n                'X-Foo' => 'false',\n                'X-Bar' => 'true',\n            ],\n        ]);\n\n        $factory->get('https://laravel.com');\n        $this->assertSame(10, $timeout);\n        $this->assertSame(['max' => 5, 'protocols' => ['http', 'https'], 'strict' => false, 'referer' => false, 'track_redirects' => false], $allowRedirects);\n        $this->assertSame(['false'], $headers['X-Foo']);\n        $this->assertSame(['true'], $headers['X-Bar']);\n    }\n\n    public function testItCanCreatePendingRequest()\n    {\n        $factory = new Factory();\n\n        $this->assertInstanceOf(PendingRequest::class, $factory->createPendingRequest());\n    }\n\n    public function testBatchNoCallbacks(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $batch = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n                $batch->as('third')->get('https://500.com'),\n            ];\n        });\n\n        $this->assertSame(3, $batch->totalRequests);\n        $this->assertFalse($batch->finished());\n\n        $responses = $batch->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n        $this->assertSame(500, $responses['third']->status());\n\n        $this->assertSame(3, $batch->totalRequests);\n        $this->assertSame(0, $batch->pendingRequests);\n        $this->assertSame(1, $batch->failedRequests);\n        $this->assertTrue($batch->hasFailures());\n        $this->assertTrue($batch->finished());\n    }\n\n    public function testBatchDefer(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $batch = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n                $batch->as('third')->get('https://500.com'),\n            ];\n        });\n\n        $this->assertSame(3, $batch->totalRequests);\n        $this->assertFalse($batch->finished());\n\n        $deferredCallback = $batch->defer();\n\n        $this->assertInstanceOf(DeferredCallback::class, $deferredCallback);\n        $this->assertFalse($batch->finished());\n    }\n\n    public function testCannotAddRequestsToInProgressBatch(): void\n    {\n        $this->expectException(BatchInProgressException::class);\n\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n            ];\n        })->progress(function (Batch $batch, int|string $key, Response $response) use (&$progressCallbacks) {\n            $batch->as('third')->get('https://500.com');\n        })->send();\n    }\n\n    public function testBatchBeforeHook(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n        ]);\n\n        $beforeCallback = false;\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n            ];\n        })->before(function (Batch $batch) use (&$beforeCallback) {\n            $beforeCallback = true;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n        $this->assertTrue($beforeCallback);\n    }\n\n    public function testBatchProgressHook(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $progressCallbacks = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n                $batch->as('third')->get('https://500.com'),\n            ];\n        })->progress(function (Batch $batch, int|string $key, Response $response) use (&$progressCallbacks) {\n            $progressCallbacks[$key] = $response;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n        $this->assertSame(500, $responses['third']->status());\n\n        $this->assertCount(2, $progressCallbacks);\n        $this->assertArrayHasKey('first', $progressCallbacks);\n        $this->assertArrayHasKey('second', $progressCallbacks);\n        $this->assertArrayNotHasKey('third', $progressCallbacks);\n\n        $this->assertSame($responses['first'], $progressCallbacks['first']);\n        $this->assertSame($responses['second'], $progressCallbacks['second']);\n    }\n\n    public function testBatchCatchHook(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $catchCallbacks = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n                $batch->as('third')->get('https://500.com'),\n            ];\n        })->catch(function (Batch $batch, int|string $key, Response|RequestException $response) use (&$catchCallbacks) {\n            $catchCallbacks[$key] = $response;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n        $this->assertSame(500, $responses['third']->status());\n\n        $this->assertCount(1, $catchCallbacks);\n        $this->assertArrayNotHasKey('first', $catchCallbacks);\n        $this->assertArrayNotHasKey('second', $catchCallbacks);\n        $this->assertArrayHasKey('third', $catchCallbacks);\n\n        $this->assertSame($responses['third'], $catchCallbacks['third']);\n    }\n\n    public function testBatchThenHookIsCalled(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n        ]);\n\n        $thenCallback = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n            ];\n        })->then(function (Batch $batch, array $results) use (&$thenCallback) {\n            $thenCallback = $results;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n\n        $this->assertCount(2, $thenCallback);\n        $this->assertArrayHasKey('first', $thenCallback);\n        $this->assertArrayHasKey('second', $thenCallback);\n\n        $this->assertSame($responses['first'], $thenCallback['first']);\n        $this->assertSame($responses['second'], $thenCallback['second']);\n    }\n\n    public function testBatchThenHookIsNotCalled(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $thenCallback = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://500.com'),\n            ];\n        })->then(function (Batch $batch, array $results) use (&$thenCallback) {\n            $thenCallback = $results;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(500, $responses['second']->status());\n\n        $this->assertCount(0, $thenCallback);\n    }\n\n    public function testBatchFinallyHookIsCalledWithoutErrors(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n        ]);\n\n        $finallyCallback = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n            ];\n        })->finally(function (Batch $batch, array $results) use (&$finallyCallback) {\n            $finallyCallback = $results;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n\n        $this->assertCount(2, $finallyCallback);\n        $this->assertArrayHasKey('first', $finallyCallback);\n        $this->assertArrayHasKey('second', $finallyCallback);\n\n        $this->assertSame($responses['first'], $finallyCallback['first']);\n        $this->assertSame($responses['second'], $finallyCallback['second']);\n    }\n\n    public function testBatchFinallyHookIsCalledWithErrors(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://500.com' => $this->factory::response('Error', 500),\n        ]);\n\n        $finallyCallback = [];\n\n        $responses = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://500.com'),\n            ];\n        })->finally(function (Batch $batch, array $results) use (&$finallyCallback) {\n            $finallyCallback = $results;\n        })->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(500, $responses['second']->status());\n\n        $this->assertCount(2, $finallyCallback);\n        $this->assertArrayHasKey('first', $finallyCallback);\n        $this->assertArrayHasKey('second', $finallyCallback);\n\n        $this->assertSame($responses['first'], $finallyCallback['first']);\n        $this->assertSame($responses['second'], $finallyCallback['second']);\n    }\n\n    public function testBatchConcurrency(): void\n    {\n        $this->factory->fake([\n            'https://200.com' => $this->factory::response('OK', 200),\n            'https://201.com' => $this->factory::response('Created', 201),\n            'https://202.com' => $this->factory::response('Accepted', 202),\n            'https://203.com' => $this->factory::response('Non-Authoritative Information', 203),\n        ]);\n\n        $executionOrder = [];\n\n        $batch = $this->factory->batch(function (Batch $batch) {\n            return [\n                $batch->as('first')->get('https://200.com'),\n                $batch->as('second')->get('https://201.com'),\n                $batch->as('third')->get('https://202.com'),\n                $batch->as('fourth')->get('https://203.com'),\n            ];\n        })->progress(function (Batch $batch, int|string $key, Response $response) use (&$executionOrder) {\n            $executionOrder[] = $key;\n        })->concurrency(2);\n\n        $this->assertSame(4, $batch->totalRequests);\n\n        $responses = $batch->send();\n\n        $this->assertSame(200, $responses['first']->status());\n        $this->assertSame(201, $responses['second']->status());\n        $this->assertSame(202, $responses['third']->status());\n        $this->assertSame(203, $responses['fourth']->status());\n\n        $this->assertSame(4, $batch->totalRequests);\n        $this->assertSame(0, $batch->pendingRequests);\n        $this->assertSame(0, $batch->failedRequests);\n    }\n\n    public static function methodsReceivingArrayableDataProvider()\n    {\n        return [\n            'patch' => ['patch'],\n            'put' => ['put'],\n            'post' => ['post'],\n            'delete' => ['delete'],\n        ];\n    }\n\n    public function testAfterResponse()\n    {\n        $this->factory->fake([\n            'http://200.com*' => $this->factory::response('OK'),\n        ]);\n\n        $response = $this->factory\n            ->afterResponse(fn (Response $response): TestResponse => new TestResponse($response->toPsrResponse()))\n            ->afterResponse(fn () => 'abc')\n            ->afterResponse(function ($r) {\n                $this->assertInstanceOf(TestResponse::class, $r);\n            })\n            ->afterResponse(fn (Response $r) => new Response($r->toPsrResponse()->withBody(Utils::streamFor(strtolower($r->body())))))\n            ->get('http://200.com');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertSame('ok', $response->body());\n    }\n\n    public function testAfterResponseWithThrows()\n    {\n        $this->factory->fake([\n            'http://500.com*' => $this->factory::response('oh no', 500),\n        ]);\n\n        try {\n            $this->factory->throw()\n                ->afterResponse(fn ($response) => new TestResponse($response->toPsrResponse()))\n                ->post('http://500.com');\n        } catch (RequestException $e) {\n            $this->assertInstanceOf(TestResponse::class, $e->response);\n        }\n    }\n\n    public function testAfterResponseWithAsync()\n    {\n        $this->factory->fake([\n            'http://200.com*' => $this->factory::response('OK', 200),\n            'http://401.com*' => $this->factory::response('Unauthorized.', 401),\n        ]);\n\n        $o = $this->factory->pool(function (Pool $pool): void {\n            $pool->as('200')->afterResponse(fn (Response $response) => new TestResponse($response->toPsrResponse()))->get('http://200.com');\n            $pool->as('401-throwing')->throw()->afterResponse(fn (Response $response) => new TestResponse($response->toPsrResponse()))->get('http://401.com');\n            $pool->as('401-response')->afterResponse(fn (Response $response) => new TestResponse($response->toPsrResponse()->withBody(Utils::streamFor('different'))))->get('http://401.com');\n        }, 0);\n\n        $this->assertInstanceOf(TestResponse::class, $o['200']);\n        $this->assertInstanceOf(TestResponse::class, $o['401-response']);\n        $this->assertEquals('different', $o['401-response']->body());\n        $this->assertInstanceOf(RequestException::class, $o['401-throwing']);\n        $this->assertInstanceOf(TestResponse::class, $o['401-throwing']->response);\n    }\n\n    public function testRespectsDefaultFlags()\n    {\n        Response::$defaultJsonDecodingFlags = JSON_BIGINT_AS_STRING;\n\n        // Create a response with a big integer that exceeds PHP_INT_MAX\n        $bigInt = '9223372036854775808';\n        $body = '{\"value\":'.$bigInt.'}';\n\n        $response = new Response(Factory::psr7Response($body));\n\n        // With JSON_BIGINT_AS_STRING, it should be the exact string\n        $this->assertSame($bigInt, $response->json('value'));\n        $this->assertSame($bigInt, $response->object()->value);\n        $this->assertSame($bigInt, $response->collect('value')->first());\n        $this->assertSame($bigInt, $response->fluent()->get('value'));\n\n        // Default json_decode behavior (flags=0), big integers become floats (losing precision)\n        $this->assertIsFloat($response->json('value', null, 0));\n        $this->assertIsFloat($response->object(0)->value);\n        $this->assertIsFloat($response->collect('value', 0)->first());\n        $this->assertIsFloat($response->fluent(flags: 0)->get('value'));\n    }\n\n    public function testJsonDecodingIsCachedWhenFlagsMatch()\n    {\n        Response::$defaultJsonDecodingFlags = JSON_BIGINT_AS_STRING;\n\n        $response = new BodyTrackingResponse(Factory::psr7Response('{\"foo\":\"bar\"}'));\n\n        // First call decodes with default (JSON_BIGINT_AS_STRING)\n        $response->json();\n        $this->assertSame(1, $response->bodyCallCount);\n\n        // Second call with same (null) flags uses cache\n        $response->json();\n        $this->assertSame(1, $response->bodyCallCount);\n\n        // Explicit flags matching default still uses cache\n        $response->json(flags: JSON_BIGINT_AS_STRING);\n        $this->assertSame(1, $response->bodyCallCount);\n\n        // Different flags triggers re-decode\n        $response->json(flags: 0);\n        $this->assertSame(2, $response->bodyCallCount);\n\n        // Same explicit flags uses cache\n        $response->json(flags: 0);\n        $this->assertSame(2, $response->bodyCallCount);\n\n        // Null flags means \"use default\", cached flags differ, so re-decode\n        $response->json();\n        $this->assertSame(3, $response->bodyCallCount);\n    }\n}\n\nclass CustomFactory extends Factory\n{\n    protected function newPendingRequest()\n    {\n        return new class extends PendingRequest\n        {\n            protected function newResponse($response)\n            {\n                return new TestResponse($response);\n            }\n        };\n    }\n}\n\nclass TestResponse extends Response\n{\n}\n\nclass BodyTrackingResponse extends Response\n{\n    public int $bodyCallCount = 0;\n\n    public function body()\n    {\n        $this->bodyCallCount++;\n\n        return parent::body();\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpJsonResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Http\\JsonResponse;\nuse InvalidArgumentException;\nuse JsonSerializable;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass HttpJsonResponseTest extends TestCase\n{\n    #[DataProvider('setAndRetrieveDataProvider')]\n    public function testSetAndRetrieveData($data)\n    {\n        $response = new JsonResponse($data);\n\n        $this->assertInstanceOf(stdClass::class, $response->getData());\n        $this->assertSame('bar', $response->getData()->foo);\n    }\n\n    public static function setAndRetrieveDataProvider()\n    {\n        return [\n            'Jsonable data' => [new JsonResponseTestJsonableObject],\n            'JsonSerializable data' => [new JsonResponseTestJsonSerializeObject],\n            'Arrayable data' => [new JsonResponseTestArrayableObject],\n            'Array data' => [['foo' => 'bar']],\n            'stdClass data' => [(object) ['foo' => 'bar']],\n        ];\n    }\n\n    public function testGetOriginalContent()\n    {\n        $response = new JsonResponse(new JsonResponseTestArrayableObject);\n        $this->assertInstanceOf(JsonResponseTestArrayableObject::class, $response->getOriginalContent());\n\n        $response = new JsonResponse;\n        $response->setData(new JsonResponseTestArrayableObject);\n        $this->assertInstanceOf(JsonResponseTestArrayableObject::class, $response->getOriginalContent());\n    }\n\n    public function testSetAndRetrieveOptions()\n    {\n        $response = new JsonResponse(['foo' => 'bar']);\n        $response->setEncodingOptions(JSON_PRETTY_PRINT);\n        $this->assertSame(JSON_PRETTY_PRINT, $response->getEncodingOptions());\n    }\n\n    public function testSetAndRetrieveDefaultOptions()\n    {\n        $response = new JsonResponse(['foo' => 'bar']);\n        $this->assertSame(0, $response->getEncodingOptions());\n    }\n\n    public function testSetAndRetrieveStatusCode()\n    {\n        $response = new JsonResponse(['foo' => 'bar'], 404);\n        $this->assertSame(404, $response->getStatusCode());\n\n        $response = new JsonResponse(['foo' => 'bar']);\n        $response->setStatusCode(404);\n        $this->assertSame(404, $response->getStatusCode());\n    }\n\n    #[DataProvider('jsonErrorDataProvider')]\n    public function testInvalidArgumentExceptionOnJsonError($data)\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        new JsonResponse(['data' => $data]);\n    }\n\n    #[DataProvider('jsonErrorDataProvider')]\n    public function testGracefullyHandledSomeJsonErrorsWithPartialOutputOnError($data)\n    {\n        new JsonResponse(['data' => $data], 200, [], JSON_PARTIAL_OUTPUT_ON_ERROR);\n    }\n\n    public static function jsonErrorDataProvider()\n    {\n        // Resources can't be encoded\n        $resource = tmpfile();\n\n        // Recursion can't be encoded\n        $recursiveObject = new stdClass;\n        $objectB = new stdClass;\n        $recursiveObject->b = $objectB;\n        $objectB->a = $recursiveObject;\n\n        // NAN or INF can't be encoded\n        $nan = NAN;\n\n        return [\n            [$resource],\n            [$recursiveObject],\n            [$nan],\n        ];\n    }\n\n    public function testFromJsonString()\n    {\n        $json_string = '{\"foo\":\"bar\"}';\n        $response = JsonResponse::fromJsonString($json_string);\n\n        $this->assertSame('bar', $response->getData()->foo);\n    }\n}\n\nclass JsonResponseTestJsonableObject implements Jsonable\n{\n    public function toJson($options = 0)\n    {\n        return '{\"foo\":\"bar\"}';\n    }\n}\n\nclass JsonResponseTestJsonSerializeObject implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return ['foo' => 'bar'];\n    }\n}\n\nclass JsonResponseTestArrayableObject implements Arrayable\n{\n    public function toArray()\n    {\n        return ['foo' => 'bar'];\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpMimeTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Illuminate\\Http\\Testing\\MimeType;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mime\\MimeTypesInterface;\n\nclass HttpMimeTypeTest extends TestCase\n{\n    public function testMimeTypeFromFileNameExistsTrue()\n    {\n        $this->assertSame('image/jpeg', MimeType::from('foo.jpg'));\n    }\n\n    public function testMimeTypeFromFileNameExistsFalse()\n    {\n        $this->assertSame('application/octet-stream', MimeType::from('foo.bar'));\n    }\n\n    public function testMimeTypeFromExtensionExistsTrue()\n    {\n        $this->assertSame('image/jpeg', MimeType::get('jpg'));\n    }\n\n    public function testMimeTypeFromExtensionExistsFalse()\n    {\n        $this->assertSame('application/octet-stream', MimeType::get('bar'));\n    }\n\n    public function testMimeTypeSymfonyInstance()\n    {\n        $this->assertInstanceOf(MimeTypesInterface::class, MimeType::getMimeTypes());\n    }\n\n    public function testSearchExtensionFromMimeType()\n    {\n        $this->assertContains(MimeType::search('video/quicktime'), ['qt', 'mov']);\n        $this->assertNull(MimeType::search('foo/bar'));\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpRedirectResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Support\\MessageProvider;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass HttpRedirectResponseTest extends TestCase\n{\n    public function testHeaderOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $this->assertNull($response->headers->get('foo'));\n        $response->header('foo', 'bar');\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $response->header('foo', 'baz', false);\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $response->header('foo', 'baz');\n        $this->assertSame('baz', $response->headers->get('foo'));\n    }\n\n    public function testWithOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flash')->twice();\n        $response->with(['name', 'age']);\n    }\n\n    public function testWithCookieOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $this->assertCount(0, $response->headers->getCookies());\n        $this->assertEquals($response, $response->withCookie(new Cookie('foo', 'bar')));\n        $cookies = $response->headers->getCookies();\n        $this->assertCount(1, $cookies);\n        $this->assertSame('foo', $cookies[0]->getName());\n        $this->assertSame('bar', $cookies[0]->getValue());\n    }\n\n    public function testFragmentIdentifierOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n\n        $response->withFragment('foo');\n        $this->assertSame('foo', parse_url($response->getTargetUrl(), PHP_URL_FRAGMENT));\n\n        $response->withFragment('#bar');\n        $this->assertSame('bar', parse_url($response->getTargetUrl(), PHP_URL_FRAGMENT));\n\n        $response->withoutFragment();\n        $this->assertNull(parse_url($response->getTargetUrl(), PHP_URL_FRAGMENT));\n    }\n\n    public function testInputOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor', 'age' => 26]);\n        $response->withInput();\n    }\n\n    public function testWithCookies()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->withCookies([\n            new Cookie('name', 'milwad'),\n        ]);\n\n        $this->assertEquals('name', $response->headers->getCookies()[0]->getName());\n        $this->assertEquals('milwad', $response->headers->getCookies()[0]->getValue());\n    }\n\n    public function testOnlyInputOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $response->onlyInput('name');\n    }\n\n    public function testExceptInputOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $response->exceptInput('age');\n    }\n\n    public function testFlashingErrorsOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);\n        $session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));\n        $provider = m::mock(MessageProvider::class);\n        $provider->shouldReceive('getMessageBag')->once()->andReturn(new MessageBag);\n        $response->withErrors($provider);\n    }\n\n    public function testCanEnforceSameOriginWhenSameOrigin()\n    {\n        $response = new RedirectResponse('https://example.com/foo/bar');\n        $response->setRequest(Request::create('https://example.com/baz/buzz'));\n        $response->enforceSameOrigin('fallback');\n\n        $this->assertSame('https://example.com/foo/bar', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenSameOriginAndCustomPort()\n    {\n        $response = new RedirectResponse('https://example.com:1/foo/bar');\n        $response->setRequest(Request::create('https://example.com:1/baz/buzz'));\n        $response->enforceSameOrigin('fallback');\n\n        $this->assertSame('https://example.com:1/foo/bar', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenNotSameScheme()\n    {\n        $response = new RedirectResponse('https://example.com/foo/bar');\n        $response->setRequest(Request::create('http://example.com/baz/buzz'));\n        $response->enforceSameOrigin('fallback');\n\n        $this->assertSame('fallback', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenNotSameHostname()\n    {\n        $response = new RedirectResponse('https://example.com/foo/bar');\n        $response->setRequest(Request::create('https://example2.com/baz/buzz'));\n        $response->enforceSameOrigin('fallback');\n\n        $this->assertSame('fallback', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenNotSamePort()\n    {\n        $response = new RedirectResponse('https://example.com:1/foo/bar');\n        $response->setRequest(Request::create('https://example.com:2/baz/buzz'));\n        $response->enforceSameOrigin('fallback');\n\n        $this->assertSame('fallback', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenNotSameSchemeAndSchemeValidationIsDisabled()\n    {\n        $response = new RedirectResponse('https://example.com/foo/bar');\n        $response->setRequest(Request::create('http://example.com/baz/buzz'));\n        $response->enforceSameOrigin('fallback', validateScheme: false);\n\n        $this->assertSame('https://example.com/foo/bar', $response->getTargetUrl());\n    }\n\n    public function testCanEnforceSameOriginWhenNotSamePortAndPortValidationIsDisabled()\n    {\n        $response = new RedirectResponse('https://example.com:1/foo/bar');\n        $response->setRequest(Request::create('https://example.com:2/baz/buzz'));\n        $response->enforceSameOrigin('fallback', validatePort: false);\n\n        $this->assertSame('https://example.com:1/foo/bar', $response->getTargetUrl());\n    }\n\n    public function testSettersGettersOnRequest()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $this->assertNull($response->getRequest());\n        $this->assertNull($response->getSession());\n\n        $request = Request::create('/', 'GET');\n        $session = m::mock(Store::class);\n        $response->setRequest($request);\n        $response->setSession($session);\n        $this->assertSame($request, $response->getRequest());\n        $this->assertSame($session, $response->getSession());\n    }\n\n    public function testRedirectWithErrorsArrayConvertsToMessageBag()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);\n        $session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));\n        $provider = ['foo' => 'bar'];\n        $response->withErrors($provider);\n    }\n\n    public function testMagicCall()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flash')->once()->with('foo', 'bar');\n        $response->withFoo('bar');\n    }\n\n    public function testMagicCallException()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Http\\RedirectResponse::doesNotExist()');\n\n        $response = new RedirectResponse('foo.bar');\n        $response->doesNotExist('bar');\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpRequestTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Carbon\\CarbonInterval;\nuse Carbon\\Unit;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Tests\\Database\\Fixtures\\Models\\Money\\Price;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse Symfony\\Component\\HttpFoundation\\Exception\\SessionNotFoundException;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile as SymfonyUploadedFile;\nuse Symfony\\Component\\HttpFoundation\\InputBag;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\nuse Symfony\\Component\\HttpFoundation\\Session\\SessionInterface;\n\ninclude_once 'Enums.php';\n\nclass HttpRequestTest extends TestCase\n{\n    public function testInstanceMethod()\n    {\n        $request = Request::create('');\n        $this->assertSame($request, $request->instance());\n    }\n\n    public function testMethodMethod()\n    {\n        $request = Request::create('', 'GET');\n        $this->assertSame('GET', $request->method());\n\n        $request = Request::create('', 'HEAD');\n        $this->assertSame('HEAD', $request->method());\n\n        $request = Request::create('', 'POST');\n        $this->assertSame('POST', $request->method());\n\n        $request = Request::create('', 'PUT');\n        $this->assertSame('PUT', $request->method());\n\n        $request = Request::create('', 'PATCH');\n        $this->assertSame('PATCH', $request->method());\n\n        $request = Request::create('', 'DELETE');\n        $this->assertSame('DELETE', $request->method());\n\n        $request = Request::create('', 'OPTIONS');\n        $this->assertSame('OPTIONS', $request->method());\n    }\n\n    public function testRootMethod()\n    {\n        $request = Request::create('http://example.com/foo/bar/script.php?test');\n        $this->assertSame('http://example.com', $request->root());\n    }\n\n    public function testPathMethod()\n    {\n        $request = Request::create('');\n        $this->assertSame('/', $request->path());\n\n        $request = Request::create('/foo/bar');\n        $this->assertSame('foo/bar', $request->path());\n    }\n\n    public function testDecodedPathMethod()\n    {\n        $request = Request::create('/foo%20bar');\n        $this->assertSame('foo bar', $request->decodedPath());\n    }\n\n    #[DataProvider('segmentProvider')]\n    public function testSegmentMethod($path, $segment, $expected)\n    {\n        $request = Request::create($path);\n        $this->assertEquals($expected, $request->segment($segment, 'default'));\n    }\n\n    public static function segmentProvider()\n    {\n        return [\n            ['', 1, 'default'],\n            ['foo/bar//baz', 1, 'foo'],\n            ['foo/bar//baz', 2, 'bar'],\n            ['foo/bar//baz', 3, 'baz'],\n        ];\n    }\n\n    #[DataProvider('segmentsProvider')]\n    public function testSegmentsMethod($path, $expected)\n    {\n        $request = Request::create($path);\n        $this->assertEquals($expected, $request->segments());\n\n        $request = Request::create('foo/bar');\n        $this->assertEquals(['foo', 'bar'], $request->segments());\n    }\n\n    public static function segmentsProvider()\n    {\n        return [\n            ['', []],\n            ['foo/bar', ['foo', 'bar']],\n            ['foo/bar//baz', ['foo', 'bar', 'baz']],\n            ['foo/0/bar', ['foo', '0', 'bar']],\n        ];\n    }\n\n    public function testUrlMethod()\n    {\n        $request = Request::create('http://foo.com/foo/bar?name=taylor');\n        $this->assertSame('http://foo.com/foo/bar', $request->url());\n\n        $request = Request::create('http://foo.com/foo/bar/?');\n        $this->assertSame('http://foo.com/foo/bar', $request->url());\n    }\n\n    public function testFullUrlMethod()\n    {\n        $request = Request::create('http://foo.com/foo/bar?name=taylor');\n        $this->assertSame('http://foo.com/foo/bar?name=taylor', $request->fullUrl());\n\n        $request = Request::create('https://foo.com');\n        $this->assertSame('https://foo.com', $request->fullUrl());\n\n        $request = Request::create('https://foo.com');\n        $this->assertSame('https://foo.com/?coupon=foo', $request->fullUrlWithQuery(['coupon' => 'foo']));\n\n        $request = Request::create('https://foo.com?a=b');\n        $this->assertSame('https://foo.com/?a=b', $request->fullUrl());\n\n        $request = Request::create('https://foo.com?a=b');\n        $this->assertSame('https://foo.com/?a=b&coupon=foo', $request->fullUrlWithQuery(['coupon' => 'foo']));\n\n        $request = Request::create('https://foo.com?a=b');\n        $this->assertSame('https://foo.com/?a=c', $request->fullUrlWithQuery(['a' => 'c']));\n\n        $request = Request::create('http://foo.com/foo/bar?name=taylor');\n        $this->assertSame('http://foo.com/foo/bar?name=taylor', $request->fullUrlWithQuery(['name' => 'taylor']));\n\n        $request = Request::create('http://foo.com/foo/bar/?name=taylor');\n        $this->assertSame('http://foo.com/foo/bar?name=graham', $request->fullUrlWithQuery(['name' => 'graham']));\n\n        $request = Request::create('https://foo.com');\n        $this->assertSame('https://foo.com/?key=value%20with%20spaces', $request->fullUrlWithQuery(['key' => 'value with spaces']));\n    }\n\n    public function testFullUrlWithoutQueryMethod()\n    {\n        $request = Request::create('http://foo.com/foo/bar?name=taylor&age=30');\n        $this->assertSame('http://foo.com/foo/bar?age=30', $request->fullUrlWithoutQuery('name'));\n\n        $request = Request::create('http://foo.com/foo/bar?name=taylor&age=30');\n        $this->assertSame('http://foo.com/foo/bar?age=30', $request->fullUrlWithoutQuery(['name']));\n\n        $request = Request::create('http://foo.com/foo/bar?name=taylor&age=30&city=nyc');\n        $this->assertSame('http://foo.com/foo/bar?city=nyc', $request->fullUrlWithoutQuery(['name', 'age']));\n\n        $request = Request::create('http://foo.com/foo/bar?name=taylor');\n        $this->assertSame('http://foo.com/foo/bar', $request->fullUrlWithoutQuery('name'));\n\n        $request = Request::create('http://foo.com/foo/bar');\n        $this->assertSame('http://foo.com/foo/bar', $request->fullUrlWithoutQuery('name'));\n\n        $request = Request::create('https://foo.com?a=b&c=d');\n        $this->assertSame('https://foo.com/?c=d', $request->fullUrlWithoutQuery('a'));\n\n        $request = Request::create('https://foo.com/?name=taylor&age=30');\n        $this->assertSame('https://foo.com/?age=30', $request->fullUrlWithoutQuery('name'));\n    }\n\n    public function testIsMethod()\n    {\n        $request = Request::create('/foo/bar');\n\n        $this->assertTrue($request->is('foo*'));\n        $this->assertFalse($request->is('bar*'));\n        $this->assertTrue($request->is('*bar*'));\n        $this->assertTrue($request->is('bar*', 'foo*', 'baz'));\n\n        $request = Request::create('/');\n\n        $this->assertTrue($request->is('/'));\n    }\n\n    public function testFullUrlIsMethod()\n    {\n        $request = Request::create('http://example.com/foo/bar');\n\n        $this->assertTrue($request->fullUrlIs('http://example.com/foo/bar'));\n        $this->assertFalse($request->fullUrlIs('example.com*'));\n        $this->assertTrue($request->fullUrlIs('http://*'));\n        $this->assertTrue($request->fullUrlIs('*foo*'));\n        $this->assertTrue($request->fullUrlIs('*bar'));\n        $this->assertTrue($request->fullUrlIs('*'));\n    }\n\n    public function testRouteIsMethod()\n    {\n        $request = Request::create('/foo/bar');\n\n        $this->assertFalse($request->routeIs('foo.bar'));\n\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/foo/bar', ['as' => 'foo.bar']);\n            $route->bind($request);\n\n            return $route;\n        });\n\n        $this->assertTrue($request->routeIs('foo.bar'));\n        $this->assertTrue($request->routeIs('foo*', '*bar'));\n        $this->assertFalse($request->routeIs('foo.foo'));\n    }\n\n    public function testRouteMethod()\n    {\n        $request = Request::create('/foo/bar');\n\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/foo/{required}/{optional?}', []);\n            $route->bind($request);\n\n            return $route;\n        });\n\n        $this->assertSame('bar', $request->route('required'));\n        $this->assertSame('bar', $request->route('required', 'default'));\n        $this->assertNull($request->route('optional'));\n        $this->assertSame('default', $request->route('optional', 'default'));\n    }\n\n    public function testAjaxMethod()\n    {\n        $request = Request::create('/');\n        $this->assertFalse($request->ajax());\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'], '{}');\n        $this->assertTrue($request->ajax());\n        $request = Request::create('/', 'POST');\n        $request->headers->set('X-Requested-With', 'XMLHttpRequest');\n        $this->assertTrue($request->ajax());\n        $request->headers->set('X-Requested-With', '');\n        $this->assertFalse($request->ajax());\n    }\n\n    public function testPrefetchMethod()\n    {\n        $request = Request::create('/');\n        $this->assertFalse($request->prefetch());\n\n        $request->server->set('HTTP_X_MOZ', '');\n        $this->assertFalse($request->prefetch());\n        $request->server->set('HTTP_X_MOZ', 'prefetch');\n        $this->assertTrue($request->prefetch());\n        $request->server->set('HTTP_X_MOZ', 'Prefetch');\n        $this->assertTrue($request->prefetch());\n\n        $request->server->remove('HTTP_X_MOZ');\n\n        $request->headers->set('Purpose', '');\n        $this->assertFalse($request->prefetch());\n        $request->headers->set('Purpose', 'prefetch');\n        $this->assertTrue($request->prefetch());\n        $request->headers->set('Purpose', 'Prefetch');\n        $this->assertTrue($request->prefetch());\n\n        $request->headers->remove('Purpose');\n\n        $request->headers->set('Sec-Purpose', '');\n        $this->assertFalse($request->prefetch());\n        $request->headers->set('Sec-Purpose', 'prefetch');\n        $this->assertTrue($request->prefetch());\n        $request->headers->set('Sec-Purpose', 'Prefetch');\n        $this->assertTrue($request->prefetch());\n    }\n\n    public function testPjaxMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_X_PJAX' => 'true'], '{}');\n        $this->assertTrue($request->pjax());\n        $request->headers->set('X-PJAX', 'false');\n        $this->assertTrue($request->pjax());\n        $request->headers->set('X-PJAX', null);\n        $this->assertFalse($request->pjax());\n        $request->headers->set('X-PJAX', '');\n        $this->assertFalse($request->pjax());\n    }\n\n    public function testSecureMethod()\n    {\n        $request = Request::create('http://example.com');\n        $this->assertFalse($request->secure());\n        $request = Request::create('https://example.com');\n        $this->assertTrue($request->secure());\n    }\n\n    public function testUserAgentMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], [\n            'HTTP_USER_AGENT' => 'Laravel',\n        ]);\n\n        $this->assertSame('Laravel', $request->userAgent());\n    }\n\n    public function testHostMethod()\n    {\n        $request = Request::create('http://example.com');\n        $this->assertSame('example.com', $request->host());\n\n        $request = Request::create('https://example.com');\n        $this->assertSame('example.com', $request->host());\n\n        $request = Request::create('https://example.com:8080');\n        $this->assertSame('example.com', $request->host());\n\n        $request = Request::create('http://example.com:8080');\n        $this->assertSame('example.com', $request->host());\n    }\n\n    public function testHttpHostMethod()\n    {\n        $request = Request::create('http://example.com');\n        $this->assertSame('example.com', $request->httpHost());\n\n        $request = Request::create('https://example.com');\n        $this->assertSame('example.com', $request->httpHost());\n\n        $request = Request::create('http://example.com:8080');\n        $this->assertSame('example.com:8080', $request->httpHost());\n\n        $request = Request::create('https://example.com:8080');\n        $this->assertSame('example.com:8080', $request->httpHost());\n    }\n\n    public function testSchemeAndHttpHostMethod()\n    {\n        $request = Request::create('http://example.com');\n        $this->assertSame('http://example.com', $request->schemeAndHttpHost());\n\n        $request = Request::create('https://example.com');\n        $this->assertSame('https://example.com', $request->schemeAndHttpHost());\n\n        $request = Request::create('http://example.com:8080');\n        $this->assertSame('http://example.com:8080', $request->schemeAndHttpHost());\n\n        $request = Request::create('https://example.com:8080');\n        $this->assertSame('https://example.com:8080', $request->schemeAndHttpHost());\n    }\n\n    public function testHasMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n        $this->assertTrue($request->has('name'));\n        $this->assertTrue($request->has('age'));\n        $this->assertTrue($request->has('city'));\n        $this->assertFalse($request->has('foo'));\n        $this->assertFalse($request->has('name', 'email'));\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $this->assertTrue($request->has('name'));\n        $this->assertTrue($request->has('name', 'email'));\n        $this->assertTrue($request->has(['name', 'email']));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar', 'bar']]);\n        $this->assertTrue($request->has('foo'));\n\n        $request = Request::create('/', 'GET', ['foo' => '', 'bar' => null]);\n        $this->assertTrue($request->has('foo'));\n        $this->assertTrue($request->has('bar'));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar' => null, 'baz' => '']]);\n        $this->assertTrue($request->has('foo.bar'));\n        $this->assertTrue($request->has('foo.baz'));\n    }\n\n    public function testWhenHasMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n\n        $name = $age = $city = $foo = $bar = false;\n\n        $request->whenHas('name', function ($value) use (&$name) {\n            $name = $value;\n        });\n\n        $request->whenHas('age', function ($value) use (&$age) {\n            $age = $value;\n        });\n\n        $request->whenHas('city', function ($value) use (&$city) {\n            $city = $value;\n        });\n\n        $request->whenHas('foo', function () use (&$foo) {\n            $foo = 'test';\n        });\n\n        $request->whenHas('bar', function () use (&$bar) {\n            $bar = 'test';\n        }, function () use (&$bar) {\n            $bar = true;\n        });\n\n        $this->assertSame('Taylor', $name);\n        $this->assertSame('', $age);\n        $this->assertNull($city);\n        $this->assertFalse($foo);\n        $this->assertTrue($bar);\n    }\n\n    public function testWhenFilledMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n\n        $name = $age = $city = $foo = $bar = false;\n\n        $request->whenFilled('name', function ($value) use (&$name) {\n            $name = $value;\n        });\n\n        $request->whenFilled('age', function ($value) use (&$age) {\n            $age = 'test';\n        });\n\n        $request->whenFilled('city', function ($value) use (&$city) {\n            $city = 'test';\n        });\n\n        $request->whenFilled('foo', function () use (&$foo) {\n            $foo = 'test';\n        });\n\n        $request->whenFilled('bar', function () use (&$bar) {\n            $bar = 'test';\n        }, function () use (&$bar) {\n            $bar = true;\n        });\n\n        $this->assertSame('Taylor', $name);\n        $this->assertFalse($age);\n        $this->assertFalse($city);\n        $this->assertFalse($foo);\n        $this->assertTrue($bar);\n    }\n\n    public function testMissingMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n        $this->assertFalse($request->missing('name'));\n        $this->assertFalse($request->missing('age'));\n        $this->assertFalse($request->missing('city'));\n        $this->assertTrue($request->missing('foo'));\n        $this->assertTrue($request->missing('name', 'email'));\n        $this->assertTrue($request->missing(['name', 'email']));\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $this->assertFalse($request->missing('name'));\n        $this->assertFalse($request->missing('name', 'email'));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar', 'bar']]);\n        $this->assertFalse($request->missing('foo'));\n\n        $request = Request::create('/', 'GET', ['foo' => '', 'bar' => null]);\n        $this->assertFalse($request->missing('foo'));\n        $this->assertFalse($request->missing('bar'));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar' => null, 'baz' => '']]);\n        $this->assertFalse($request->missing('foo.bar'));\n        $this->assertFalse($request->missing('foo.baz'));\n    }\n\n    public function testWhenMissingMethod()\n    {\n        $request = Request::create('/', 'GET', ['bar' => null]);\n\n        $name = $age = $city = $foo = $bar = true;\n\n        $request->whenMissing('name', function ($value) use (&$name) {\n            $name = 'Taylor';\n        });\n\n        $request->whenMissing('age', function ($value) use (&$age) {\n            $age = '';\n        });\n\n        $request->whenMissing('city', function ($value) use (&$city) {\n            $city = null;\n        });\n\n        $request->whenMissing('foo', function () use (&$foo) {\n            $foo = false;\n        });\n\n        $request->whenMissing('bar', function () use (&$bar) {\n            $bar = 'test';\n        }, function () use (&$bar) {\n            $bar = true;\n        });\n\n        $this->assertSame('Taylor', $name);\n        $this->assertSame('', $age);\n        $this->assertNull($city);\n        $this->assertFalse($foo);\n        $this->assertTrue($bar);\n    }\n\n    public function testHasAnyMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n        $this->assertTrue($request->hasAny('name'));\n        $this->assertTrue($request->hasAny('age'));\n        $this->assertTrue($request->hasAny('city'));\n        $this->assertFalse($request->hasAny('foo'));\n        $this->assertTrue($request->hasAny('name', 'email'));\n        $this->assertTrue($request->hasAny(['name', 'email']));\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $this->assertTrue($request->hasAny('name', 'email'));\n        $this->assertFalse($request->hasAny('surname', 'password'));\n        $this->assertFalse($request->hasAny(['surname', 'password']));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar' => null, 'baz' => '']]);\n        $this->assertTrue($request->hasAny('foo.bar'));\n        $this->assertTrue($request->hasAny('foo.baz'));\n        $this->assertFalse($request->hasAny('foo.bax'));\n        $this->assertTrue($request->hasAny(['foo.bax', 'foo.baz']));\n    }\n\n    public function testFilledMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n        $this->assertTrue($request->filled('name'));\n        $this->assertFalse($request->filled('age'));\n        $this->assertFalse($request->filled('city'));\n        $this->assertFalse($request->filled('foo'));\n        $this->assertFalse($request->filled('name', 'email'));\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $this->assertTrue($request->filled('name'));\n        $this->assertTrue($request->filled('name', 'email'));\n        $this->assertTrue($request->filled(['name', 'email']));\n\n        // test arrays within query string\n        $request = Request::create('/', 'GET', ['foo' => ['bar', 'baz']]);\n        $this->assertTrue($request->filled('foo'));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar' => 'baz']]);\n        $this->assertTrue($request->filled('foo.bar'));\n    }\n\n    public function testIsNotFilledMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n        $this->assertFalse($request->isNotFilled('name'));\n        $this->assertTrue($request->isNotFilled('age'));\n        $this->assertTrue($request->isNotFilled('city'));\n        $this->assertTrue($request->isNotFilled('foo'));\n        $this->assertFalse($request->isNotFilled(['name', 'email']));\n        $this->assertTrue($request->isNotFilled(['foo', 'age']));\n        $this->assertTrue($request->isNotFilled(['age', 'city']));\n\n        $request = Request::create('/', 'GET', ['foo' => ['bar', 'baz' => '0']]);\n        $this->assertFalse($request->isNotFilled('foo'));\n        $this->assertTrue($request->isNotFilled('foo.bar'));\n        $this->assertFalse($request->isNotFilled('foo.baz'));\n    }\n\n    public function testFilledAnyMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => '', 'city' => null]);\n\n        $this->assertTrue($request->anyFilled(['name']));\n        $this->assertTrue($request->anyFilled('name'));\n\n        $this->assertFalse($request->anyFilled(['age']));\n        $this->assertFalse($request->anyFilled('age'));\n\n        $this->assertFalse($request->anyFilled(['foo']));\n        $this->assertFalse($request->anyFilled('foo'));\n\n        $this->assertTrue($request->anyFilled(['age', 'name']));\n        $this->assertTrue($request->anyFilled('age', 'name'));\n\n        $this->assertTrue($request->anyFilled(['foo', 'name']));\n        $this->assertTrue($request->anyFilled('foo', 'name'));\n\n        $this->assertFalse($request->anyFilled(['age', 'city']));\n        $this->assertFalse($request->anyFilled('age', 'city'));\n\n        $this->assertFalse($request->anyFilled(['foo', 'bar']));\n        $this->assertFalse($request->anyFilled('foo', 'bar'));\n    }\n\n    public function testInputMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n        $this->assertSame('Taylor', $request->input('name'));\n        $this->assertSame('Taylor', $request['name']);\n        $this->assertSame('Bob', $request->input('foo', 'Bob'));\n\n        $request = Request::create('/', 'GET', [], [], ['file' => new SymfonyUploadedFile(__FILE__, 'foo.php')]);\n        $this->assertInstanceOf(SymfonyUploadedFile::class, $request['file']);\n    }\n\n    public function testFluentMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'user' => [\n                'name' => 'Michael',\n                'role' => 'admin',\n            ],\n            'users' => null,\n        ]);\n        $this->assertSame(['name' => 'Michael', 'role' => 'admin'], $request->fluent('user')->toArray());\n        $this->assertSame([], $request->fluent('users')->toArray());\n        $this->assertSame([], $request->fluent('not_found')->toArray());\n    }\n\n    public function testStringMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'int' => 123,\n            'int_str' => '456',\n            'float' => 123.456,\n            'float_str' => '123.456',\n            'float_zero' => 0.000,\n            'float_str_zero' => '0.000',\n            'str' => 'abc',\n            'empty_str' => '',\n            'null' => null,\n        ]);\n        $this->assertTrue($request->string('int') instanceof Stringable);\n        $this->assertTrue($request->string('unknown_key') instanceof Stringable);\n        $this->assertSame('123', $request->string('int')->value());\n        $this->assertSame('456', $request->string('int_str')->value());\n        $this->assertSame('123.456', $request->string('float')->value());\n        $this->assertSame('123.456', $request->string('float_str')->value());\n        $this->assertSame('0', $request->string('float_zero')->value());\n        $this->assertSame('0.000', $request->string('float_str_zero')->value());\n        $this->assertSame('', $request->string('empty_str')->value());\n        $this->assertSame('', $request->string('null')->value());\n        $this->assertSame('', $request->string('unknown_key')->value());\n    }\n\n    public function testBooleanMethod()\n    {\n        $request = Request::create('/', 'GET', ['with_trashed' => 'false', 'download' => true, 'checked' => 1, 'unchecked' => '0', 'with_on' => 'on', 'with_yes' => 'yes']);\n        $this->assertTrue($request->boolean('checked'));\n        $this->assertTrue($request->boolean('download'));\n        $this->assertFalse($request->boolean('unchecked'));\n        $this->assertFalse($request->boolean('with_trashed'));\n        $this->assertFalse($request->boolean('some_undefined_key'));\n        $this->assertTrue($request->boolean('with_on'));\n        $this->assertTrue($request->boolean('with_yes'));\n    }\n\n    public function testIntegerMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'int' => '123',\n            'raw_int' => 456,\n            'zero_padded' => '078',\n            'space_padded' => ' 901',\n            'nan' => 'nan',\n            'mixed' => '1ab',\n            'underscore_notation' => '2_000',\n            'null' => null,\n        ]);\n        $this->assertSame(123, $request->integer('int'));\n        $this->assertSame(456, $request->integer('raw_int'));\n        $this->assertSame(78, $request->integer('zero_padded'));\n        $this->assertSame(901, $request->integer('space_padded'));\n        $this->assertSame(0, $request->integer('nan'));\n        $this->assertSame(1, $request->integer('mixed'));\n        $this->assertSame(2, $request->integer('underscore_notation'));\n        $this->assertSame(123456, $request->integer('unknown_key', 123456));\n        $this->assertSame(0, $request->integer('null'));\n        $this->assertSame(0, $request->integer('null', 123456));\n    }\n\n    public function testFloatMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'float' => '1.23',\n            'raw_float' => 45.6,\n            'decimal_only' => '.6',\n            'zero_padded' => '0.78',\n            'space_padded' => ' 90.1',\n            'nan' => 'nan',\n            'mixed' => '1.ab',\n            'scientific_notation' => '1e3',\n            'null' => null,\n        ]);\n        $this->assertSame(1.23, $request->float('float'));\n        $this->assertSame(45.6, $request->float('raw_float'));\n        $this->assertSame(.6, $request->float('decimal_only'));\n        $this->assertSame(0.78, $request->float('zero_padded'));\n        $this->assertSame(90.1, $request->float('space_padded'));\n        $this->assertSame(0.0, $request->float('nan'));\n        $this->assertSame(1.0, $request->float('mixed'));\n        $this->assertSame(1e3, $request->float('scientific_notation'));\n        $this->assertSame(123.456, $request->float('unknown_key', 123.456));\n        $this->assertSame(0.0, $request->float('null'));\n        $this->assertSame(0.0, $request->float('null', 123.456));\n    }\n\n    public function testArrayMethod()\n    {\n        $request = Request::create('/', 'GET', []);\n        $this->assertIsArray($request->array());\n        $this->assertEmpty($request->array());\n\n        $request = Request::create('/', 'GET', [\n            'users' => [1, 2, 3],\n            'roles' => [4, 5, 6],\n            'email' => 'test@example.com',\n        ]);\n\n        $this->assertEmpty($request->array('missing'));\n        $this->assertEmpty($request->array(['missing']));\n        $this->assertEquals([1, 2, 3], $request->array('users'));\n        $this->assertEquals(['users' => [1, 2, 3]], $request->array(['users']));\n        $this->assertEquals(['users' => [1, 2, 3], 'email' => 'test@example.com'], $request->array(['users', 'email']));\n\n        $this->assertEquals([\n            'users' => [1, 2, 3],\n            'roles' => [4, 5, 6],\n            'email' => 'test@example.com',\n        ], $request->array());\n    }\n\n    public function testCollectMethod()\n    {\n        $request = Request::create('/', 'GET', ['users' => [1, 2, 3]]);\n\n        $this->assertInstanceOf(Collection::class, $request->collect('users'));\n        $this->assertTrue($request->collect('developers')->isEmpty());\n        $this->assertEquals([1, 2, 3], $request->collect('users')->all());\n        $this->assertEquals(['users' => [1, 2, 3]], $request->collect()->all());\n\n        $request = Request::create('/', 'GET', ['text-payload']);\n        $this->assertEquals(['text-payload'], $request->collect()->all());\n\n        $request = Request::create('/', 'GET', ['email' => 'test@example.com']);\n        $this->assertEquals(['test@example.com'], $request->collect('email')->all());\n\n        $request = Request::create('/', 'GET', []);\n        $this->assertInstanceOf(Collection::class, $request->collect());\n        $this->assertTrue($request->collect()->isEmpty());\n\n        $request = Request::create('/', 'GET', ['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com']);\n        $this->assertInstanceOf(Collection::class, $request->collect(['users']));\n        $this->assertTrue($request->collect(['developers'])->isEmpty());\n        $this->assertTrue($request->collect(['roles'])->isNotEmpty());\n        $this->assertEquals(['roles' => [4, 5, 6]], $request->collect(['roles'])->all());\n        $this->assertEquals(['users' => [1, 2, 3], 'email' => 'test@example.com'], $request->collect(['users', 'email'])->all());\n        $this->assertEquals(collect(['roles' => [4, 5, 6], 'foo' => ['bar', 'baz']]), $request->collect(['roles', 'foo']));\n        $this->assertEquals(['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com'], $request->collect()->all());\n    }\n\n    public function testDateMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'as_null' => null,\n            'as_invalid' => 'invalid',\n\n            'as_datetime' => '20-01-01 16:30:25',\n            'as_format' => '1577896225',\n            'as_timezone' => '20-01-01 13:30:25',\n\n            'as_date' => '2020-01-01',\n            'as_time' => '16:30:25',\n        ]);\n\n        $current = Carbon::create(2020, 1, 1, 16, 30, 25);\n\n        $this->assertNull($request->date('as_null'));\n        $this->assertNull($request->date('doesnt_exists'));\n\n        $this->assertEquals($current, $request->date('as_datetime'));\n        $this->assertEquals($current->format('Y-m-d H:i:s P'), $request->date('as_format', 'U')->format('Y-m-d H:i:s P'));\n        $this->assertEquals($current, $request->date('as_timezone', null, 'America/Santiago'));\n\n        $this->assertTrue($request->date('as_date')->isSameDay($current));\n        $this->assertTrue($request->date('as_time')->isSameSecond('16:30:25'));\n    }\n\n    public function testDateMethodExceptionWhenValueInvalid()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $request = Request::create('/', 'GET', [\n            'date' => 'invalid',\n        ]);\n\n        $request->date('date');\n    }\n\n    public function testDateMethodExceptionWhenFormatInvalid()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $request = Request::create('/', 'GET', [\n            'date' => '20-01-01 16:30:25',\n        ]);\n\n        $request->date('date', 'invalid_format');\n    }\n\n    public function testIntervalMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'as_null' => null,\n            'as_empty' => '',\n            'as_iso' => 'P1Y2M3DT4H5M6S',\n            'as_human' => '2 hours 30 minutes',\n            'as_seconds' => '90',\n            'as_minutes' => '45',\n        ]);\n\n        $this->assertNull($request->interval('as_null'));\n        $this->assertNull($request->interval('as_empty'));\n        $this->assertNull($request->interval('doesnt_exist'));\n\n        $interval = $request->interval('as_iso');\n        $this->assertInstanceOf(CarbonInterval::class, $interval);\n        $this->assertSame(1, $interval->years);\n        $this->assertSame(2, $interval->months);\n        $this->assertSame(3, $interval->dayz);\n        $this->assertSame(4, $interval->hours);\n        $this->assertSame(5, $interval->minutes);\n        $this->assertSame(6, $interval->seconds);\n\n        $interval = $request->interval('as_human');\n        $this->assertInstanceOf(CarbonInterval::class, $interval);\n        $this->assertSame(2, $interval->hours);\n        $this->assertSame(30, $interval->minutes);\n\n        $interval = $request->interval('as_seconds', 'second');\n        $this->assertInstanceOf(CarbonInterval::class, $interval);\n        $this->assertSame(90, $interval->seconds);\n\n        $this->assertSame(90, $request->interval('as_seconds', 'minute')->minutes);\n        $this->assertSame(90, $request->interval('as_seconds', 'hour')->hours);\n        $this->assertSame(90, $request->interval('as_seconds', 'day')->dayz);\n\n        $this->assertSame(45, $request->interval('as_minutes', Unit::Minute)->minutes);\n        $this->assertSame(45, $request->interval('as_minutes', Unit::Second)->seconds);\n    }\n\n    public function testEnumMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'valid_enum_value' => 'test',\n            'invalid_enum_value' => 'invalid',\n            'empty_value_request' => '',\n            'string' => [\n                'minus_1' => '-1',\n                '0' => '0',\n                'plus_1' => '1',\n                'doesnt_exist' => '-1024',\n            ],\n            'int' => [\n                'minus_1' => -1,\n                '0' => 0,\n                'plus_1' => 1,\n                'doesnt_exist' => 1024,\n            ],\n        ]);\n\n        $this->assertNull($request->enum('doesnt_exist', TestEnumBacked::class));\n\n        $this->assertEquals(TestEnumBacked::test, $request->enum('invalid_enum_value', TestEnumBacked::class, TestEnumBacked::test));\n        $this->assertEquals(TestEnumBacked::test, $request->enum('missing_key', TestEnumBacked::class, TestEnumBacked::test));\n\n        $this->assertEquals(TestEnumBacked::test, $request->enum('valid_enum_value', TestEnumBacked::class));\n\n        $this->assertNull($request->enum('invalid_enum_value', TestEnumBacked::class));\n        $this->assertNull($request->enum('empty_value_request', TestEnumBacked::class));\n        $this->assertNull($request->enum('valid_enum_value', TestEnum::class));\n\n        $this->assertEquals(TestIntegerEnumBacked::minus_1, $request->enum('string.minus_1', TestIntegerEnumBacked::class));\n        $this->assertEquals(TestIntegerEnumBacked::zero, $request->enum('string.0', TestIntegerEnumBacked::class));\n        $this->assertEquals(TestIntegerEnumBacked::plus_1, $request->enum('string.plus_1', TestIntegerEnumBacked::class));\n        $this->assertNull($request->enum('string.doesnt_exist', TestIntegerEnumBacked::class));\n        $this->assertEquals(TestIntegerEnumBacked::minus_1, $request->enum('int.minus_1', TestIntegerEnumBacked::class));\n        $this->assertEquals(TestIntegerEnumBacked::zero, $request->enum('int.0', TestIntegerEnumBacked::class));\n        $this->assertEquals(TestIntegerEnumBacked::plus_1, $request->enum('int.plus_1', TestIntegerEnumBacked::class));\n        $this->assertNull($request->enum('int.doesnt_exist', TestIntegerEnumBacked::class));\n    }\n\n    public function testEnumsMethod()\n    {\n        $request = Request::create('/', 'GET', [\n            'valid_enum_values' => ['test', 'test'],\n            'invalid_enum_values' => ['invalid', 'invalid'],\n            'empty_value_request' => [],\n            'string' => [\n                'minus_1' => ['-1', '0'],\n                '0' => '0',\n                'plus_1' => '1',\n                'doesnt_exist' => '-1024',\n            ],\n            'int' => [\n                'minus_1' => -1,\n                '0' => 0,\n                'plus_1' => 1,\n                'doesnt_exist' => 1024,\n            ],\n        ]);\n\n        $this->assertEmpty($request->enums('doesnt_exist', TestEnumBacked::class));\n\n        $this->assertEquals([TestEnumBacked::test, TestEnumBacked::test], $request->enums('valid_enum_values', TestEnumBacked::class));\n\n        $this->assertEmpty($request->enums('invalid_enum_value', TestEnumBacked::class));\n        $this->assertEmpty($request->enums('empty_value_request', TestEnumBacked::class));\n        $this->assertEmpty($request->enums('valid_enum_value', TestEnum::class));\n\n        $this->assertEquals([TestIntegerEnumBacked::minus_1, TestIntegerEnumBacked::zero], $request->enums('string.minus_1', TestIntegerEnumBacked::class));\n        $this->assertEquals([TestIntegerEnumBacked::zero], $request->enums('string.0', TestIntegerEnumBacked::class));\n        $this->assertEquals([TestIntegerEnumBacked::plus_1], $request->enums('string.plus_1', TestIntegerEnumBacked::class));\n        $this->assertEmpty($request->enums('string.doesnt_exist', TestIntegerEnumBacked::class));\n        $this->assertEquals([TestIntegerEnumBacked::minus_1], $request->enums('int.minus_1', TestIntegerEnumBacked::class));\n        $this->assertEquals([TestIntegerEnumBacked::zero], $request->enums('int.0', TestIntegerEnumBacked::class));\n        $this->assertEquals([TestIntegerEnumBacked::plus_1], $request->enums('int.plus_1', TestIntegerEnumBacked::class));\n        $this->assertEmpty($request->enums('int.doesnt_exist', TestIntegerEnumBacked::class));\n    }\n\n    public function testArrayAccess()\n    {\n        $request = Request::create('/', 'GET', ['name' => null, 'foo' => ['bar' => null, 'baz' => '']]);\n\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/foo/bar/{id}/{name}', []);\n            $route->bind($request);\n            $route->setParameter('id', 'foo');\n            $route->setParameter('name', 'Taylor');\n\n            return $route;\n        });\n\n        $this->assertFalse(isset($request['non-existent']));\n        $this->assertNull($request['non-existent']);\n\n        $this->assertTrue(isset($request['name']));\n        $this->assertNull($request['name']);\n\n        $this->assertNotSame('Taylor', $request['name']);\n\n        $this->assertTrue(isset($request['foo.bar']));\n        $this->assertNull($request['foo.bar']);\n        $this->assertTrue(isset($request['foo.baz']));\n        $this->assertSame('', $request['foo.baz']);\n\n        $this->assertTrue(isset($request['id']));\n        $this->assertSame('foo', $request['id']);\n    }\n\n    public function testArrayAccessWithoutRouteResolver()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n\n        $this->assertFalse(isset($request['non-existent']));\n        $this->assertNull($request['non-existent']);\n\n        $this->assertTrue(isset($request['name']));\n        $this->assertSame('Taylor', $request['name']);\n    }\n\n    public function testAllMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => null]);\n        $this->assertEquals(['name' => 'Taylor', 'age' => null, 'email' => null], $request->all('name', 'age', 'email'));\n        $this->assertEquals(['name' => 'Taylor'], $request->all('name'));\n        $this->assertEquals(['name' => 'Taylor', 'age' => null], $request->all());\n\n        $request = Request::create('/', 'GET', ['developer' => ['name' => 'Taylor', 'age' => null]]);\n        $this->assertEquals(['developer' => ['name' => 'Taylor', 'skills' => null]], $request->all('developer.name', 'developer.skills'));\n        $this->assertEquals(['developer' => ['name' => 'Taylor', 'skills' => null]], $request->all(['developer.name', 'developer.skills']));\n        $this->assertEquals(['developer' => ['age' => null]], $request->all('developer.age'));\n        $this->assertEquals(['developer' => ['skills' => null]], $request->all('developer.skills'));\n        $this->assertEquals(['developer' => ['name' => 'Taylor', 'age' => null]], $request->all());\n    }\n\n    public function testKeysMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => null]);\n        $this->assertEquals(['name', 'age'], $request->keys());\n\n        $files = [\n            'foo' => [\n                'size' => 500,\n                'name' => 'foo.jpg',\n                'tmp_name' => __FILE__,\n                'type' => 'blah',\n                'error' => null,\n            ],\n        ];\n        $request = Request::create('/', 'GET', [], [], $files);\n        $this->assertEquals(['foo'], $request->keys());\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor'], [], $files);\n        $this->assertEquals(['name', 'foo'], $request->keys());\n    }\n\n    public function testOnlyMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => null]);\n        $this->assertEquals(['name' => 'Taylor', 'age' => null], $request->only('name', 'age', 'email'));\n\n        $request = Request::create('/', 'GET', ['developer' => ['name' => 'Taylor', 'age' => null]]);\n        $this->assertEquals(['developer' => ['name' => 'Taylor']], $request->only('developer.name', 'developer.skills'));\n        $this->assertEquals(['developer' => ['age' => null]], $request->only('developer.age'));\n        $this->assertEquals([], $request->only('developer.skills'));\n    }\n\n    public function testExceptMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 25]);\n        $this->assertEquals(['name' => 'Taylor'], $request->except('age'));\n        $this->assertEquals([], $request->except('age', 'name'));\n        $this->assertEquals([], $request->except(['age', 'name']));\n    }\n\n    public function testQueryMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n        $this->assertSame(['name' => 'Taylor'], $request->query());\n        $this->assertSame('Taylor', $request->query('name'));\n        $this->assertSame('Taylor', $request->query('name', 'Amir'));\n        $this->assertSame('Bob', $request->query('foo', 'Bob'));\n        $all = $request->query(null);\n        $this->assertSame('Taylor', $all['name']);\n\n        $request = Request::create('/', 'GET', ['hello' => 'world', 'user' => ['Taylor', 'Mohamed Said']]);\n        $this->assertSame(['Taylor', 'Mohamed Said'], $request->query('user'));\n        $this->assertSame(['hello' => 'world', 'user' => ['Taylor', 'Mohamed Said']], $request->query->all());\n\n        $request = Request::create('/?hello=world&user[]=Taylor&user[]=Mohamed%20Said', 'GET', []);\n        $this->assertSame(['Taylor', 'Mohamed Said'], $request->query('user'));\n        $this->assertSame(['hello' => 'world', 'user' => ['Taylor', 'Mohamed Said']], $request->query->all());\n    }\n\n    public function testPostMethod()\n    {\n        $request = Request::create('/', 'POST', ['name' => 'Taylor']);\n        $this->assertSame(['name' => 'Taylor'], $request->post());\n        $this->assertSame('Taylor', $request->post('name'));\n        $this->assertSame('Taylor', $request->post('name', 'Amir'));\n        $this->assertSame('Bob', $request->post('foo', 'Bob'));\n        $all = $request->post(null);\n        $this->assertSame('Taylor', $all['name']);\n    }\n\n    public function testCookieMethod()\n    {\n        $request = Request::create('/', 'GET', [], ['name' => 'Taylor']);\n        $this->assertSame(['name' => 'Taylor'], $request->cookie());\n        $this->assertSame('Taylor', $request->cookie('name'));\n        $this->assertSame('Taylor', $request->cookie('name', 'Amir'));\n        $this->assertSame('Bob', $request->cookie('foo', 'Bob'));\n        $all = $request->cookie(null);\n        $this->assertSame('Taylor', $all['name']);\n    }\n\n    public function testHasCookieMethod()\n    {\n        $request = Request::create('/', 'GET', [], ['foo' => 'bar']);\n        $this->assertTrue($request->hasCookie('foo'));\n        $this->assertFalse($request->hasCookie('qu'));\n    }\n\n    public function testFileMethod()\n    {\n        $files = [\n            'foo' => [\n                'size' => 500,\n                'name' => 'foo.jpg',\n                'tmp_name' => __FILE__,\n                'type' => 'blah',\n                'error' => null,\n            ],\n        ];\n        $request = Request::create('/', 'GET', [], [], $files);\n        $this->assertInstanceOf(SymfonyUploadedFile::class, $request->file('foo'));\n    }\n\n    public function testHasFileMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], []);\n        $this->assertFalse($request->hasFile('foo'));\n\n        $files = [\n            'foo' => [\n                'size' => 500,\n                'name' => 'foo.jpg',\n                'tmp_name' => __FILE__,\n                'type' => 'blah',\n                'error' => null,\n            ],\n        ];\n        $request = Request::create('/', 'GET', [], [], $files);\n        $this->assertTrue($request->hasFile('foo'));\n        $this->assertFalse($request->hasFile('bar'));\n    }\n\n    public function testServerMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['foo' => 'bar']);\n        $this->assertSame('bar', $request->server('foo'));\n        $this->assertSame('bar', $request->server('foo.doesnt.exist', 'bar'));\n        $all = $request->server(null);\n        $this->assertSame('bar', $all['foo']);\n    }\n\n    public function testMergeMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n        $merge = ['buddy' => 'Dayle'];\n        $request->merge($merge);\n        $this->assertSame('Taylor', $request->input('name'));\n        $this->assertSame('Dayle', $request->input('buddy'));\n    }\n\n    public function testMergeIfMissingMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n        $merge = ['boolean_setting' => 0];\n        $request->mergeIfMissing($merge);\n        $this->assertSame('Taylor', $request->input('name'));\n        $this->assertSame(0, $request->input('boolean_setting'));\n\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'boolean_setting' => 1]);\n        $merge = ['boolean_setting' => 0];\n        $request->mergeIfMissing($merge);\n        $this->assertSame('Taylor', $request->input('name'));\n        $this->assertSame(1, $request->input('boolean_setting'));\n\n        $request = Request::create('/', 'GET', ['user' => ['first_name' => 'Taylor', 'email' => 'taylor@laravel.com']]);\n        $merge = ['user.last_name' => 'Otwell'];\n        $request->mergeIfMissing($merge);\n        $this->assertSame('Otwell', $request->input('user.last_name'));\n\n        $request = Request::create('/', 'GET', ['user' => ['first_name' => 'Taylor', 'email' => 'taylor@laravel.com']]);\n        $merge = ['user.first_name' => 'John'];\n        $request->mergeIfMissing($merge);\n        $this->assertSame('Taylor', $request->input('user.first_name'));\n    }\n\n    public function testReplaceMethod()\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n        $replace = ['buddy' => 'Dayle'];\n        $request->replace($replace);\n        $this->assertNull($request->input('name'));\n        $this->assertSame('Dayle', $request->input('buddy'));\n    }\n\n    public function testOffsetUnsetMethod()\n    {\n        $request = Request::create('/', 'HEAD', ['name' => 'Taylor']);\n        $request->offsetUnset('name');\n        $this->assertNull($request->input('name'));\n    }\n\n    public function testHeaderMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_DO_THIS' => 'foo']);\n        $this->assertSame('foo', $request->header('do-this'));\n        $this->assertSame('default', $request->header('do-that', 'default'));\n        $all = $request->header(null);\n        $this->assertSame('foo', $all['do-this'][0]);\n    }\n\n    public function testBearerTokenMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'Bearer fooBearerbar']);\n        $this->assertSame('fooBearerbar', $request->bearerToken());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'bearer fooBearerbar']);\n        $this->assertSame('fooBearerbar', $request->bearerToken());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'Basic foo, Bearer bar']);\n        $this->assertSame('bar', $request->bearerToken());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'Bearer foo,bar']);\n        $this->assertSame('foo', $request->bearerToken());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'bearer foo,bar']);\n        $this->assertSame('foo', $request->bearerToken());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => 'foo,bar']);\n        $this->assertNull($request->bearerToken());\n    }\n\n    public function testJSONMethod()\n    {\n        $payload = ['name' => 'taylor'];\n        $request = Request::create('/', 'GET', [], [], [], ['CONTENT_TYPE' => 'application/json'], json_encode($payload));\n        $this->assertSame('taylor', $request->json('name'));\n        $this->assertSame('taylor', $request->json('name', 'Otwell'));\n        $this->assertSame('Moharami', $request->json('family', 'Moharami'));\n        $this->assertSame('taylor', $request->input('name'));\n        $data = $request->json()->all();\n        $this->assertEquals($payload, $data);\n    }\n\n    public function testJSONEmulatingPHPBuiltInServer()\n    {\n        $payload = ['name' => 'taylor'];\n        $content = json_encode($payload);\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json', 'HTTP_CONTENT_LENGTH' => strlen($content)], $content);\n        $this->assertTrue($request->isJson());\n        $data = $request->json()->all();\n        $this->assertEquals($payload, $data);\n\n        $data = $request->all();\n        $this->assertEquals($payload, $data);\n    }\n\n    public static function getPrefersCases()\n    {\n        return [\n            ['application/json', ['json'], 'json'],\n            ['application/json', ['html', 'json'], 'json'],\n            ['application/foo+json', 'application/foo+json', 'application/foo+json'],\n            ['application/foo+json', 'json', 'json'],\n            ['application/json;q=0.5, text/html;q=1.0', ['json', 'html'], 'html'],\n            ['application/json;q=0.5, text/plain;q=1.0, text/html;q=1.0', ['json', 'txt', 'html'], 'txt'],\n            ['application/*', 'json', 'json'],\n            ['application/json; charset=utf-8', 'json', 'json'],\n            ['application/xml; charset=utf-8', ['html', 'json'], null],\n            ['application/json, text/html', ['html', 'json'], 'json'],\n            ['application/json;q=0.4, text/html;q=0.6', ['html', 'json'], 'html'],\n\n            ['application/json; charset=utf-8', 'application/json', 'application/json'],\n            ['application/json, text/html', ['text/html', 'application/json'], 'application/json'],\n            ['application/json;q=0.4, text/html;q=0.6', ['text/html', 'application/json'], 'text/html'],\n            ['application/json;q=0.4, text/html;q=0.6', ['application/json', 'text/html'], 'text/html'],\n\n            ['*/*; charset=utf-8', 'json', 'json'],\n            ['application/*', 'application/json', 'application/json'],\n            ['application/*', 'application/xml', 'application/xml'],\n            ['application/*', 'text/html', null],\n        ];\n    }\n\n    #[DataProvider('getPrefersCases')]\n    public function testPrefersMethod($accept, $prefers, $expected)\n    {\n        $this->assertSame(\n            $expected, Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => $accept])->prefers($prefers)\n        );\n    }\n\n    public function testAllInputReturnsInputAndFiles()\n    {\n        $file = $this->getMockBuilder(UploadedFile::class)->setConstructorArgs([__FILE__, 'photo.jpg'])->getMock();\n        $request = Request::create('/?boom=breeze', 'GET', ['foo' => 'bar'], [], ['baz' => $file]);\n        $this->assertEquals(['foo' => 'bar', 'baz' => $file, 'boom' => 'breeze'], $request->all());\n    }\n\n    public function testAllInputReturnsNestedInputAndFiles()\n    {\n        $file = $this->getMockBuilder(UploadedFile::class)->setConstructorArgs([__FILE__, 'photo.jpg'])->getMock();\n        $request = Request::create('/?boom=breeze', 'GET', ['foo' => ['bar' => 'baz']], [], ['foo' => ['photo' => $file]]);\n        $this->assertEquals(['foo' => ['bar' => 'baz', 'photo' => $file], 'boom' => 'breeze'], $request->all());\n    }\n\n    public function testAllInputReturnsInputAfterReplace()\n    {\n        $request = Request::create('/?boom=breeze', 'GET', ['foo' => ['bar' => 'baz']]);\n        $request->replace(['foo' => ['bar' => 'baz'], 'boom' => 'breeze']);\n        $this->assertEquals(['foo' => ['bar' => 'baz'], 'boom' => 'breeze'], $request->all());\n    }\n\n    public function testAllInputWithNumericKeysReturnsInputAfterReplace()\n    {\n        $request1 = Request::create('/', 'POST', [0 => 'A', 1 => 'B', 2 => 'C']);\n        $request1->replace([0 => 'A', 1 => 'B', 2 => 'C']);\n        $this->assertEquals([0 => 'A', 1 => 'B', 2 => 'C'], $request1->all());\n\n        $request2 = Request::create('/', 'POST', [1 => 'A', 2 => 'B', 3 => 'C']);\n        $request2->replace([1 => 'A', 2 => 'B', 3 => 'C']);\n        $this->assertEquals([1 => 'A', 2 => 'B', 3 => 'C'], $request2->all());\n    }\n\n    public function testInputWithEmptyFilename()\n    {\n        $invalidFiles = [\n            'file' => [\n                'name' => null,\n                'type' => null,\n                'tmp_name' => null,\n                'error' => 4,\n                'size' => 0,\n            ],\n        ];\n\n        $baseRequest = SymfonyRequest::create('/?boom=breeze', 'GET', ['foo' => ['bar' => 'baz']], [], $invalidFiles);\n\n        Request::createFromBase($baseRequest);\n    }\n\n    public function testMultipleFileUploadWithEmptyValue()\n    {\n        $invalidFiles = [\n            'file' => [\n                'name' => [''],\n                'type' => [''],\n                'tmp_name' => [''],\n                'error' => [4],\n                'size' => [0],\n            ],\n        ];\n\n        $baseRequest = SymfonyRequest::create('/?boom=breeze', 'GET', ['foo' => ['bar' => 'baz']], [], $invalidFiles);\n\n        $request = Request::createFromBase($baseRequest);\n\n        $this->assertEmpty($request->files->all());\n    }\n\n    public function testOldMethodCallsSession()\n    {\n        $request = Request::create('/');\n        $session = m::mock(Store::class);\n        $session->shouldReceive('getOldInput')->once()->with('foo', 'bar')->andReturn('boom');\n        $request->setLaravelSession($session);\n        $this->assertSame('boom', $request->old('foo', 'bar'));\n    }\n\n    public function testOldMethodCallsSessionWhenDefaultIsArray()\n    {\n        $request = Request::create('/');\n        $session = m::mock(Store::class);\n        $session->shouldReceive('getOldInput')->once()->with('foo', ['bar'])->andReturn(['bar']);\n        $request->setLaravelSession($session);\n        $this->assertSame(['bar'], $request->old('foo', ['bar']));\n    }\n\n    public function testOldMethodCanGetDefaultValueFromModelByKey()\n    {\n        $request = Request::create('/');\n        $model = m::mock(Price::class);\n        $model->shouldReceive('getAttribute')->once()->with('name')->andReturn('foobar');\n        $session = m::mock(Store::class);\n        $session->shouldReceive('getOldInput')->once()->with('name', 'foobar')->andReturn('foobar');\n        $request->setLaravelSession($session);\n        $this->assertSame('foobar', $request->old('name', $model));\n    }\n\n    public function testFlushMethodCallsSession()\n    {\n        $request = Request::create('/');\n        $session = m::mock(Store::class);\n        $session->shouldReceive('flashInput')->once();\n        $request->setLaravelSession($session);\n        $request->flush();\n    }\n\n    public function testExpectsJson()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $this->assertTrue($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*']);\n        $this->assertFalse($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);\n        $this->assertTrue($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => null, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);\n        $this->assertTrue($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest', 'HTTP_X_PJAX' => 'true']);\n        $this->assertFalse($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html']);\n        $this->assertFalse($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);\n        $this->assertFalse($request->expectsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest', 'HTTP_X_PJAX' => 'true']);\n        $this->assertFalse($request->expectsJson());\n    }\n\n    public function testFormatReturnsAcceptableFormat()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $this->assertSame('json', $request->format());\n        $this->assertTrue($request->wantsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json; charset=utf-8']);\n        $this->assertSame('json', $request->format());\n        $this->assertTrue($request->wantsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/atom+xml']);\n        $this->assertSame('atom', $request->format());\n        $this->assertFalse($request->wantsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'is/not/known']);\n        $this->assertSame('html', $request->format());\n        $this->assertSame('foo', $request->format('foo'));\n    }\n\n    public function testWantsMarkdown()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/markdown']);\n        $this->assertTrue($request->wantsMarkdown());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/markdown; charset=utf-8']);\n        $this->assertTrue($request->wantsMarkdown());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $this->assertFalse($request->wantsMarkdown());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html']);\n        $this->assertFalse($request->wantsMarkdown());\n    }\n\n    public function testAcceptsMarkdown()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/markdown']);\n        $this->assertTrue($request->acceptsMarkdown());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html, text/markdown']);\n        $this->assertFalse($request->wantsMarkdown());\n        $this->assertTrue($request->acceptsMarkdown());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $this->assertFalse($request->acceptsMarkdown());\n    }\n\n    public function testFormatReturnsAcceptsJson()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $this->assertSame('json', $request->format());\n        $this->assertTrue($request->accepts('application/json'));\n        $this->assertTrue($request->accepts('application/baz+json'));\n        $this->assertTrue($request->acceptsJson());\n        $this->assertFalse($request->acceptsHtml());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/foo+json']);\n        $this->assertTrue($request->accepts('application/foo+json'));\n        $this->assertFalse($request->accepts('application/bar+json'));\n        $this->assertFalse($request->accepts('application/json'));\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/*']);\n        $this->assertTrue($request->accepts('application/xml'));\n        $this->assertTrue($request->accepts('application/json'));\n    }\n\n    public function testFormatReturnsAcceptsHtml()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html']);\n        $this->assertSame('html', $request->format());\n        $this->assertTrue($request->accepts('text/html'));\n        $this->assertTrue($request->acceptsHtml());\n        $this->assertFalse($request->acceptsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/*']);\n        $this->assertTrue($request->accepts('text/html'));\n        $this->assertTrue($request->accepts('text/plain'));\n    }\n\n    public function testFormatReturnsAcceptsAll()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*']);\n        $this->assertSame('html', $request->format());\n        $this->assertTrue($request->accepts('text/html'));\n        $this->assertTrue($request->accepts('foo/bar'));\n        $this->assertTrue($request->accepts('application/baz+xml'));\n        $this->assertTrue($request->acceptsHtml());\n        $this->assertTrue($request->acceptsJson());\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*']);\n        $this->assertSame('html', $request->format());\n        $this->assertTrue($request->accepts('text/html'));\n        $this->assertTrue($request->accepts('foo/bar'));\n        $this->assertTrue($request->accepts('application/baz+xml'));\n        $this->assertTrue($request->acceptsHtml());\n        $this->assertTrue($request->acceptsJson());\n    }\n\n    public function testFormatReturnsAcceptsMultiple()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json,text/*']);\n        $this->assertTrue($request->accepts(['text/html', 'application/json']));\n        $this->assertTrue($request->accepts('text/html'));\n        $this->assertTrue($request->accepts('text/foo'));\n        $this->assertTrue($request->accepts('application/json'));\n        $this->assertTrue($request->accepts('application/baz+json'));\n    }\n\n    public function testFormatReturnsAcceptsCharset()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json; charset=utf-8']);\n        $this->assertTrue($request->accepts(['text/html', 'application/json']));\n        $this->assertFalse($request->accepts('text/html'));\n        $this->assertFalse($request->accepts('text/foo'));\n        $this->assertTrue($request->accepts('application/json'));\n        $this->assertTrue($request->accepts('application/baz+json'));\n    }\n\n    public function testWantsJsonRespectsHeaderChanges()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*']);\n\n        $this->assertFalse($request->wantsJson());\n\n        $this->assertTrue($request->acceptsAnyContentType());\n\n        $request->headers->set('Accept', 'application/json');\n\n        $this->assertTrue($request->wantsJson(), 'wantsJson() should return true after Accept header is changed to application/json');\n    }\n\n    public function testAcceptsJsonRespectsHeaderChanges()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*']);\n\n        $this->assertTrue($request->acceptsAnyContentType());\n\n        $request->headers->set('Accept', 'application/json');\n\n        $this->assertTrue($request->acceptsJson(), 'acceptsJson() should return true after Accept header is changed to application/json');\n    }\n\n    public function testPrefersRespectsHeaderChanges()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '*/*']);\n\n        $this->assertTrue($request->acceptsAnyContentType());\n\n        $request->headers->set('Accept', 'application/json');\n\n        $this->assertSame('json', $request->prefers(['html', 'json']), 'prefers() should return json after Accept header is changed to application/json');\n    }\n\n    public function testWantsJsonWorksWhenHeaderSetBeforeFirstCall()\n    {\n        $request = Request::create('/', 'GET', [], [], [], []);\n\n        $request->headers->set('Accept', 'application/json');\n\n        $this->assertTrue($request->wantsJson(), 'wantsJson() should return true when Accept header is set to application/json');\n    }\n\n    public function testCacheClearedWhenTransitioningFromUnsetToSetHeader()\n    {\n        $request = Request::create('/', 'GET', [], [], [], []);\n\n        $request->getAcceptableContentTypes();\n\n        $request->headers->set('Accept', 'application/json');\n\n        $this->assertTrue($request->wantsJson(), 'wantsJson() should return true after Accept header is set from null to application/json');\n\n        $this->assertTrue($request->acceptsJson(), 'acceptsJson() should return true after Accept header is set from null to application/json');\n    }\n\n    public function testAcceptsJsonWorksWhenHeaderChangedMultipleTimes()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'text/html']);\n\n        $this->assertFalse($request->acceptsJson());\n\n        $request->headers->set('Accept', 'application/json');\n        $this->assertTrue($request->acceptsJson());\n\n        $request->headers->set('Accept', 'text/html');\n        $this->assertFalse($request->acceptsJson());\n\n        $request->headers->set('Accept', 'application/json');\n        $this->assertTrue($request->acceptsJson());\n    }\n\n    public function testBadAcceptHeader()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)']);\n        $this->assertFalse($request->accepts(['text/html', 'application/json']));\n        $this->assertFalse($request->accepts('text/html'));\n        $this->assertFalse($request->accepts('text/foo'));\n        $this->assertFalse($request->accepts('application/json'));\n        $this->assertFalse($request->accepts('application/baz+json'));\n        $this->assertFalse($request->acceptsHtml());\n        $this->assertFalse($request->acceptsJson());\n\n        // Should not be handled as regex.\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '.+/.+']);\n        $this->assertFalse($request->accepts('application/json'));\n        $this->assertFalse($request->accepts('application/baz+json'));\n\n        // Should not produce compilation error on invalid regex.\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => '(/(']);\n        $this->assertFalse($request->accepts('text/html'));\n    }\n\n    public function testCaseInsensitiveAcceptHeader()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'APPLICATION/JSON']);\n        $this->assertTrue($request->accepts(['text/html', 'application/json']));\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'AppLiCaTion/JsOn']);\n        $this->assertTrue($request->accepts(['text/html', 'application/json']));\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'APPLICATION/*']);\n        $this->assertTrue($request->accepts(['text/html', 'application/json']));\n\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'APPLICATION/JSON']);\n        $this->assertTrue($request->expectsJson());\n    }\n\n    public function testSessionMethod()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Session store not set on request.');\n\n        $request = Request::create('/');\n        $request->session();\n    }\n\n    public function testHasSessionMethod()\n    {\n        $request = Request::create('/');\n\n        $this->assertFalse($request->hasSession());\n\n        $session = m::mock(Store::class);\n        $request->setLaravelSession($session);\n\n        $this->assertTrue($request->hasSession());\n    }\n\n    public function testGetSessionMethodWithLaravelSession()\n    {\n        $request = Request::create('/');\n\n        $laravelSession = m::mock(Store::class);\n        $request->setLaravelSession($laravelSession);\n\n        $session = $request->getSession();\n        $this->assertInstanceOf(SessionInterface::class, $session);\n\n        $laravelSession->shouldReceive('start')->once()->andReturn(true);\n        $session->start();\n    }\n\n    public function testGetSessionMethodWithoutLaravelSession()\n    {\n        $this->expectException(SessionNotFoundException::class);\n        $this->expectExceptionMessage('There is currently no session available.');\n\n        $request = Request::create('/');\n\n        $request->getSession();\n    }\n\n    public function testUserResolverMakesUserAvailableAsMagicProperty()\n    {\n        $request = Request::create('/', 'GET', [], [], [], ['HTTP_ACCEPT' => 'application/json']);\n        $request->setUserResolver(function () {\n            return 'user';\n        });\n        $this->assertSame('user', $request->user());\n    }\n\n    public function testFingerprintMethod()\n    {\n        $request = Request::create('/', 'GET', [], [], [], []);\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/foo/bar/{id}', []);\n            $route->bind($request);\n\n            return $route;\n        });\n\n        $this->assertEquals(40, mb_strlen($request->fingerprint()));\n    }\n\n    public function testFingerprintWithoutRoute()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to generate fingerprint. Route unavailable.');\n\n        $request = Request::create('/', 'GET', [], [], [], []);\n        $request->fingerprint();\n    }\n\n    /**\n     * Ensure JSON GET requests populate $request->request with the JSON content.\n     *\n     * @link https://github.com/laravel/framework/pull/7052 Correctly fill the $request->request parameter bag on creation.\n     */\n    public function testJsonRequestFillsRequestBodyParams()\n    {\n        $body = [\n            'foo' => 'bar',\n            'baz' => ['qux'],\n        ];\n\n        $server = [\n            'CONTENT_TYPE' => 'application/json',\n        ];\n\n        $base = SymfonyRequest::create('/', 'GET', [], [], [], $server, json_encode($body));\n\n        $request = Request::createFromBase($base);\n\n        $this->assertEquals($request->request->all(), $body);\n    }\n\n    /**\n     * Ensure non-JSON GET requests don't pollute $request->request with the GET parameters.\n     *\n     * @link https://github.com/laravel/framework/pull/37921 Manually populate POST request body with JSON data only when required.\n     */\n    public function testNonJsonRequestDoesntFillRequestBodyParams()\n    {\n        $params = ['foo' => 'bar'];\n\n        $getRequest = Request::create('/', 'GET', $params, [], [], []);\n        $this->assertEquals($getRequest->request->all(), []);\n        $this->assertEquals($getRequest->query->all(), $params);\n\n        $postRequest = Request::create('/', 'POST', $params, [], [], []);\n        $this->assertEquals($postRequest->request->all(), $params);\n        $this->assertEquals($postRequest->query->all(), []);\n    }\n\n    /**\n     * Tests for Http\\Request magic methods `__get()` and `__isset()`.\n     *\n     * @link https://github.com/laravel/framework/issues/10403 Form request object attribute returns empty when have some string.\n     */\n    public function testMagicMethods()\n    {\n        // Simulates QueryStrings.\n        $request = Request::create('/', 'GET', ['foo' => 'bar', 'empty' => '']);\n\n        // Parameter 'foo' is 'bar', then it ISSET and is NOT EMPTY.\n        $this->assertSame('bar', $request->foo);\n        $this->assertTrue(isset($request->foo));\n        $this->assertNotEmpty($request->foo);\n\n        // Parameter 'empty' is '', then it ISSET and is EMPTY.\n        $this->assertSame('', $request->empty);\n        $this->assertTrue(isset($request->empty));\n        $this->assertEmpty($request->empty);\n\n        // Parameter 'undefined' is undefined/null, then it NOT ISSET and is EMPTY.\n        $this->assertNull($request->undefined);\n        $this->assertFalse(isset($request->undefined));\n        $this->assertEmpty($request->undefined);\n\n        // Simulates Route parameters.\n        $request = Request::create('/example/bar', 'GET', ['xyz' => 'overwritten']);\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/example/{foo}/{xyz?}/{undefined?}', []);\n            $route->bind($request);\n\n            return $route;\n        });\n\n        // Router parameter 'foo' is 'bar', then it ISSET and is NOT EMPTY.\n        $this->assertSame('bar', $request->foo);\n        $this->assertSame('bar', $request['foo']);\n        $this->assertTrue(isset($request->foo));\n        $this->assertNotEmpty($request->foo);\n\n        // Router parameter 'undefined' is undefined/null, then it NOT ISSET and is EMPTY.\n        $this->assertNull($request->undefined);\n        $this->assertFalse(isset($request->undefined));\n        $this->assertEmpty($request->undefined);\n\n        // Special case: router parameter 'xyz' is 'overwritten' by QueryString, then it ISSET and is NOT EMPTY.\n        // Basically, QueryStrings have priority over router parameters.\n        $this->assertSame('overwritten', $request->xyz);\n        $this->assertTrue(isset($request->foo));\n        $this->assertNotEmpty($request->foo);\n\n        // Simulates empty QueryString and Routes.\n        $request = Request::create('/');\n        $request->setRouteResolver(function () use ($request) {\n            $route = new Route('GET', '/', []);\n            $route->bind($request);\n\n            return $route;\n        });\n\n        // Parameter 'undefined' is undefined/null, then it NOT ISSET and is EMPTY.\n        $this->assertNull($request->undefined);\n        $this->assertFalse(isset($request->undefined));\n        $this->assertEmpty($request->undefined);\n\n        // Special case: simulates empty QueryString and Routes, without the Route Resolver.\n        // It'll happen when you try to get a parameter outside a route.\n        $request = Request::create('/');\n\n        // Parameter 'undefined' is undefined/null, then it NOT ISSET and is EMPTY.\n        $this->assertNull($request->undefined);\n        $this->assertFalse(isset($request->undefined));\n        $this->assertEmpty($request->undefined);\n    }\n\n    public function testHttpRequestFlashCallsSessionFlashInputWithInputData()\n    {\n        $session = m::mock(Store::class);\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor', 'email' => 'foo']);\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $request->setLaravelSession($session);\n        $request->flash();\n    }\n\n    public function testHttpRequestFlashOnlyCallsFlashWithProperParameters()\n    {\n        $session = m::mock(Store::class);\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $request->setLaravelSession($session);\n        $request->flashOnly(['name']);\n    }\n\n    public function testHttpRequestFlashExceptCallsFlashWithProperParameters()\n    {\n        $session = m::mock(Store::class);\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $request = Request::create('/', 'GET', ['name' => 'Taylor', 'email' => 'foo']);\n        $request->setLaravelSession($session);\n        $request->flashExcept(['email']);\n    }\n\n    public function testGeneratingJsonRequestFromParentRequestUsesCorrectType()\n    {\n        if (! method_exists(SymfonyRequest::class, 'getPayload')) {\n            return;\n        }\n\n        $base = SymfonyRequest::create('/', 'POST', server: ['CONTENT_TYPE' => 'application/json'], content: '{\"hello\":\"world\"}');\n\n        $request = Request::createFromBase($base);\n\n        $this->assertInstanceOf(InputBag::class, $request->getPayload());\n        $this->assertSame('world', $request->getPayload()->get('hello'));\n    }\n\n    public function testJsonRequestsCanMergeDataIntoJsonRequest()\n    {\n        if (! method_exists(SymfonyRequest::class, 'getPayload')) {\n            return;\n        }\n\n        $base = SymfonyRequest::create('/', 'POST', server: ['CONTENT_TYPE' => 'application/json'], content: '{\"first\":\"Taylor\",\"last\":\"Otwell\"}');\n        $request = Request::createFromBase($base);\n\n        $request->merge([\n            'name' => $request->get('first').' '.$request->get('last'),\n        ]);\n\n        $this->assertSame('Taylor Otwell', $request->get('name'));\n    }\n\n    public function testItCanHaveObjectsInJsonPayload()\n    {\n        if (! method_exists(SymfonyRequest::class, 'getPayload')) {\n            return;\n        }\n\n        $base = SymfonyRequest::create('/', 'POST', server: ['CONTENT_TYPE' => 'application/json'], content: '{\"framework\":{\"name\":\"Laravel\"}}');\n        $request = Request::createFromBase($base);\n\n        $value = $request->get('framework');\n\n        $this->assertSame(['name' => 'Laravel'], $request->get('framework'));\n    }\n\n    public function testItDoesNotGenerateJsonErrorsForEmptyContent()\n    {\n        // clear any existing errors\n        json_encode(null);\n\n        Request::create('', 'GET')->json();\n\n        $this->assertTrue(json_last_error() === JSON_ERROR_NONE);\n    }\n\n    public function testItClampsValues()\n    {\n        $request = Request::create('/', 'GET', ['per_page' => 100, 'float' => 9.24]);\n        $this->assertSame(100, $request->clamp('per_page', 100, 101));\n        $this->assertSame(10, $request->clamp('per_page', -10, 10));\n        $this->assertSame(25, $request->clamp('per_page_2', 25, 100, 1));\n        $this->assertSame(100, $request->clamp('per_page', 1, 250, 99));\n        $this->assertSame(22.4, $request->clamp('per_page', 1.11, 22.4, 2));\n        $this->assertSame(9.24, $request->clamp('float', 1, 10));\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse BadMethodCallException;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Contracts\\Support\\MessageProvider;\nuse Illuminate\\Contracts\\Support\\Renderable;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\ViewErrorBag;\nuse JsonSerializable;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\HeaderBag;\nuse Symfony\\Component\\HttpFoundation\\ResponseHeaderBag;\n\nclass HttpResponseTest extends TestCase\n{\n    public function testJsonResponsesAreConvertedAndHeadersAreSet()\n    {\n        $response = new Response(new ArrayableStub);\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response = new Response(new JsonableStub);\n        $this->assertSame('foo', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response = new Response(new ArrayableAndJsonableStub);\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response = new Response;\n        $response->setContent(['foo' => 'bar']);\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response = new Response(new JsonSerializableStub);\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response = new Response(new ArrayableStub);\n        $this->assertSame('{\"foo\":\"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n\n        $response->setContent('{\"foo\": \"bar\"}');\n        $this->assertSame('{\"foo\": \"bar\"}', $response->getContent());\n        $this->assertSame('application/json', $response->headers->get('Content-Type'));\n    }\n\n    public function testRenderablesAreRendered()\n    {\n        $mock = m::mock(Renderable::class);\n        $mock->shouldReceive('render')->once()->andReturn('foo');\n        $response = new Response($mock);\n        $this->assertSame('foo', $response->getContent());\n    }\n\n    public function testHeader()\n    {\n        $response = new Response;\n        $this->assertNull($response->headers->get('foo'));\n        $response->header('foo', 'bar');\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $response->header('foo', 'baz', false);\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $response->header('foo', 'baz');\n        $this->assertSame('baz', $response->headers->get('foo'));\n    }\n\n    public function testWithCookie()\n    {\n        $response = new Response;\n        $this->assertCount(0, $response->headers->getCookies());\n        $this->assertEquals($response, $response->withCookie(new Cookie('foo', 'bar')));\n        $cookies = $response->headers->getCookies();\n        $this->assertCount(1, $cookies);\n        $this->assertSame('foo', $cookies[0]->getName());\n        $this->assertSame('bar', $cookies[0]->getValue());\n    }\n\n    public function testResponseCookiesInheritRequestSecureState()\n    {\n        $cookie = Cookie::create('foo', 'bar');\n\n        $response = new Response('foo');\n        $response->headers->setCookie($cookie);\n\n        $request = Request::create('/', 'GET');\n        $response->prepare($request);\n\n        $this->assertFalse($cookie->isSecure());\n\n        $request = Request::create('https://localhost/', 'GET');\n        $response->prepare($request);\n\n        $this->assertTrue($cookie->isSecure());\n    }\n\n    public function testGetOriginalContent()\n    {\n        $arr = ['foo' => 'bar'];\n        $response = new Response;\n        $response->setContent($arr);\n        $this->assertSame($arr, $response->getOriginalContent());\n    }\n\n    public function testGetOriginalContentRetrievesTheFirstOriginalContent()\n    {\n        $previousResponse = new Response(['foo' => 'bar']);\n        $response = new Response($previousResponse);\n\n        $this->assertSame(['foo' => 'bar'], $response->getOriginalContent());\n    }\n\n    public function testSetAndRetrieveStatusCode()\n    {\n        $response = new Response('foo');\n        $response->setStatusCode(404);\n        $this->assertSame(404, $response->getStatusCode());\n    }\n\n    public function testSetStatusCodeAndRetrieveStatusText()\n    {\n        $response = new Response('foo');\n        $response->setStatusCode(404);\n        $this->assertSame('Not Found', $response->statusText());\n    }\n\n    public function testOnlyInputOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $response->onlyInput('name');\n    }\n\n    public function testExceptInputOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flashInput')->once()->with(['name' => 'Taylor']);\n        $response->exceptInput('age');\n    }\n\n    public function testFlashingErrorsOnRedirect()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);\n        $session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));\n        $provider = m::mock(MessageProvider::class);\n        $provider->shouldReceive('getMessageBag')->once()->andReturn(new MessageBag);\n        $response->withErrors($provider);\n    }\n\n    public function testSettersGettersOnRequest()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $this->assertNull($response->getRequest());\n        $this->assertNull($response->getSession());\n\n        $request = Request::create('/', 'GET');\n        $session = m::mock(Store::class);\n        $response->setRequest($request);\n        $response->setSession($session);\n        $this->assertSame($request, $response->getRequest());\n        $this->assertSame($session, $response->getSession());\n    }\n\n    public function testRedirectWithErrorsArrayConvertsToMessageBag()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('get')->with('errors', m::type(ViewErrorBag::class))->andReturn(new ViewErrorBag);\n        $session->shouldReceive('flash')->once()->with('errors', m::type(ViewErrorBag::class));\n        $provider = ['foo' => 'bar'];\n        $response->withErrors($provider);\n    }\n\n    public function testWithHeaders()\n    {\n        $response = new Response(null, 200, ['foo' => 'bar']);\n        $this->assertSame('bar', $response->headers->get('foo'));\n\n        $response->withHeaders(['foo' => 'BAR', 'bar' => 'baz']);\n        $this->assertSame('BAR', $response->headers->get('foo'));\n        $this->assertSame('baz', $response->headers->get('bar'));\n\n        $responseMessageBag = new ResponseHeaderBag(['bar' => 'BAZ', 'titi' => 'toto']);\n        $response->withHeaders($responseMessageBag);\n        $this->assertSame('BAZ', $response->headers->get('bar'));\n        $this->assertSame('toto', $response->headers->get('titi'));\n\n        $headerBag = new HeaderBag(['bar' => 'BAAA', 'titi' => 'TATA']);\n        $response->withHeaders($headerBag);\n        $this->assertSame('BAAA', $response->headers->get('bar'));\n        $this->assertSame('TATA', $response->headers->get('titi'));\n    }\n\n    public function testWithoutHeader()\n    {\n        $response = new Response(null, 200, ['foo' => 'bar', 'baz' => 'qux', 'zal' => 'ter']);\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $this->assertSame('qux', $response->headers->get('baz'));\n        $this->assertSame('ter', $response->headers->get('zal'));\n\n        // Test removing single header\n        $result = $response->withoutHeader('foo');\n        $this->assertSame($response, $result);\n        $this->assertNull($response->headers->get('foo'));\n        $this->assertSame('qux', $response->headers->get('baz'));\n        $this->assertSame('ter', $response->headers->get('zal'));\n\n        // Test removing multiple headers at once\n        $response->withoutHeader(['baz', 'zal']);\n        $this->assertNull($response->headers->get('baz'));\n        $this->assertNull($response->headers->get('zal'));\n    }\n\n    public function testMagicCall()\n    {\n        $response = new RedirectResponse('foo.bar');\n        $response->setRequest(Request::create('/', 'GET', ['name' => 'Taylor', 'age' => 26]));\n        $response->setSession($session = m::mock(Store::class));\n        $session->shouldReceive('flash')->once()->with('foo', 'bar');\n        $response->withFoo('bar');\n    }\n\n    public function testMagicCallException()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Http\\RedirectResponse::doesNotExist()');\n\n        $response = new RedirectResponse('foo.bar');\n        $response->doesNotExist('bar');\n    }\n}\n\nclass ArrayableStub implements Arrayable\n{\n    public function toArray()\n    {\n        return ['foo' => 'bar'];\n    }\n}\n\nclass ArrayableAndJsonableStub implements Arrayable, Jsonable\n{\n    public function toJson($options = 0)\n    {\n        return '{\"foo\":\"bar\"}';\n    }\n\n    public function toArray()\n    {\n        return [];\n    }\n}\n\nclass JsonableStub implements Jsonable\n{\n    public function toJson($options = 0)\n    {\n        return 'foo';\n    }\n}\n\nclass JsonSerializableStub implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return ['foo' => 'bar'];\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpTestingFileFactoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Illuminate\\Http\\Testing\\FileFactory;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @link https://www.php.net/manual/en/function.gd-info.php\n */\n#[RequiresPhpExtension('gd')]\nclass HttpTestingFileFactoryTest extends TestCase\n{\n    public function testImagePng()\n    {\n        if (! $this->isGDSupported('PNG Support')) {\n            $this->markTestSkipped('Requires PNG support.');\n        }\n\n        $image = (new FileFactory)->image('test.png', 15, 20);\n\n        $info = getimagesize($image->getRealPath());\n\n        $this->assertSame('image/png', $info['mime']);\n        $this->assertSame(15, $info[0]);\n        $this->assertSame(20, $info[1]);\n    }\n\n    public function testImageJpeg()\n    {\n        if (! $this->isGDSupported('JPEG Support')) {\n            $this->markTestSkipped('Requires JPEG support.');\n        }\n\n        $jpeg = (new FileFactory)->image('test.jpeg', 15, 20);\n        $jpg = (new FileFactory)->image('test.jpg');\n\n        $info = getimagesize($jpeg->getRealPath());\n\n        $this->assertSame('image/jpeg', $info['mime']);\n        $this->assertSame(15, $info[0]);\n        $this->assertSame(20, $info[1]);\n        $this->assertSame(\n            'image/jpeg',\n            mime_content_type($jpg->getRealPath())\n        );\n    }\n\n    public function testImageGif()\n    {\n        if (! $this->isGDSupported('GIF Create Support')) {\n            $this->markTestSkipped('Requires GIF Create support.');\n        }\n\n        $image = (new FileFactory)->image('test.gif');\n\n        $this->assertSame(\n            'image/gif',\n            mime_content_type($image->getRealPath())\n        );\n    }\n\n    public function testImageWebp()\n    {\n        if (! $this->isGDSupported('WebP Support')) {\n            $this->markTestSkipped('Requires Webp support.');\n        }\n\n        $image = (new FileFactory)->image('test.webp');\n\n        $this->assertSame(\n            'image/webp',\n            mime_content_type($image->getRealPath())\n        );\n    }\n\n    public function testImageWbmp()\n    {\n        if (! $this->isGDSupported('WBMP Support')) {\n            $this->markTestSkipped('Requires WBMP support.');\n        }\n\n        $image = (new FileFactory)->image('test.wbmp');\n\n        $this->assertSame(\n            'image/vnd.wap.wbmp',\n            getimagesize($image->getRealPath())['mime']\n        );\n    }\n\n    public function testImageBmp()\n    {\n        $image = (new FileFactory)->image('test.bmp');\n\n        $imagePath = $image->getRealPath();\n\n        if (version_compare(PHP_VERSION, '8.3.0-dev', '>=')) {\n            $this->assertSame('image/bmp', mime_content_type($imagePath));\n        } else {\n            $this->assertSame('image/x-ms-bmp', mime_content_type($imagePath));\n        }\n    }\n\n    public function testCreateWithMimeType()\n    {\n        $this->assertSame(\n            'audio/webm',\n            (new FileFactory)->create('someaudio.webm', 0, 'audio/webm')->getMimeType()\n        );\n    }\n\n    public function testCreateWithoutMimeType()\n    {\n        $this->assertSame(\n            'video/webm',\n            (new FileFactory)->create('someaudio.webm')->getMimeType()\n        );\n    }\n\n    #[DataProvider('generateImageDataProvider')]\n    public function testCallingCreateWithoutGDLoadedThrowsAnException(string $fileExtension, string $driver)\n    {\n        if ($this->isGDSupported($driver)) {\n            $this->markTestSkipped(\"Requires no {$driver}\");\n        }\n\n        $this->expectException(\\LogicException::class);\n        (new FileFactory)->image(\"test.{$fileExtension}\");\n    }\n\n    public static function generateImageDataProvider(): array\n    {\n        return [\n            'jpeg' => ['jpeg', 'JPEG Support'],\n            'png' => ['png', 'PNG Support'],\n            'gif' => ['gif', 'GIF Create Support'],\n            'webp' => ['webp', 'WebP Support'],\n            'wbmp' => ['wbmp', 'WBMP Support'],\n            'bmp' => ['bmp', 'BMP Support'],\n        ];\n    }\n\n    /**\n     * @param  string  $driver\n     * @return bool\n     */\n    private function isGDSupported(string $driver = 'GD Version'): bool\n    {\n        $gdInfo = gd_info();\n\n        if (isset($gdInfo[$driver])) {\n            return $gdInfo[$driver];\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/Http/HttpUploadedFileTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Illuminate\\Http\\UploadedFile;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\File\\UploadedFile as SymfonyUploadedFile;\n\nclass HttpUploadedFileTest extends TestCase\n{\n    public function testUploadedFileCanRetrieveContentsFromTextFile()\n    {\n        $file = new UploadedFile(\n            __DIR__.'/fixtures/test.txt',\n            'test.txt',\n            null,\n            null,\n            true\n        );\n\n        $this->assertSame('This is a story about something that happened long ago when your grandfather was a child.', trim($file->get()));\n    }\n\n    public function testUploadedFileInRequestContainsOriginalPathAndName()\n    {\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, '');\n        $this->assertSame('', $symfonyFile->getClientOriginalName());\n        $this->assertSame('', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('', $file->getClientOriginalName());\n        $this->assertSame('', $file->getClientOriginalPath());\n\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, 'test.txt');\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalName());\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('test.txt', $file->getClientOriginalName());\n        $this->assertSame('test.txt', $file->getClientOriginalPath());\n\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, '/test.txt');\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalName());\n        $this->assertSame('/test.txt', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('test.txt', $file->getClientOriginalName());\n        $this->assertSame('/test.txt', $file->getClientOriginalPath());\n\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, '/foo/bar/test.txt');\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalName());\n        $this->assertSame('/foo/bar/test.txt', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('test.txt', $file->getClientOriginalName());\n        $this->assertSame('/foo/bar/test.txt', $file->getClientOriginalPath());\n\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, '/foo/bar/test.txt');\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalName());\n        $this->assertSame('/foo/bar/test.txt', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('test.txt', $file->getClientOriginalName());\n        $this->assertSame('/foo/bar/test.txt', $file->getClientOriginalPath());\n\n        $symfonyFile = new SymfonyUploadedFile(__FILE__, 'file:\\\\foo\\\\test.txt');\n        $this->assertSame('test.txt', $symfonyFile->getClientOriginalName());\n        $this->assertSame('file:/foo/test.txt', $symfonyFile->getClientOriginalPath());\n        $file = UploadedFile::createFromBase($symfonyFile);\n        $this->assertSame('test.txt', $file->getClientOriginalName());\n        $this->assertSame('file:/foo/test.txt', $file->getClientOriginalPath());\n    }\n}\n"
  },
  {
    "path": "tests/Http/JsonResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Http\\Resources\\MissingValue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass JsonResourceTest extends TestCase\n{\n    public function testJsonResourceNullAttributes()\n    {\n        $model = new class extends Model {\n        };\n\n        $model->setAttribute('relation_sum_column', null);\n        $model->setAttribute('relation_count', null);\n        $model->setAttribute('relation_exists', null);\n\n        $resource = new JsonResource($model);\n\n        $this->assertNotInstanceOf(MissingValue::class, $resource->whenAggregated('relation', 'column', 'sum'));\n        $this->assertNotInstanceOf(MissingValue::class, $resource->whenCounted('relation'));\n        $this->assertNotInstanceOf(MissingValue::class, $resource->whenExistsLoaded('relation'));\n\n        $this->assertNull($resource->whenAggregated('relation', 'column', 'sum'));\n        $this->assertNull($resource->whenCounted('relation'));\n        $this->assertNull($resource->whenExistsLoaded('relation'));\n    }\n\n    public function testJsonResourceToJsonSucceedsWithPriorErrors(): void\n    {\n        $model = new class extends Model {\n        };\n\n        $resource = m::mock(JsonResource::class, ['resource' => $model])\n            ->makePartial()\n            ->shouldReceive('jsonSerialize')->andReturn(['foo' => 'bar'])\n            ->getMock();\n\n        // Simulate a JSON error\n        json_decode('{');\n        $this->assertTrue(json_last_error() !== JSON_ERROR_NONE);\n\n        $this->assertSame('{\"foo\":\"bar\"}', $resource->toJson(JSON_THROW_ON_ERROR));\n    }\n\n    public function testJsonResourceToPrettyPrint(): void\n    {\n        $model = new class extends Model {\n        };\n\n        $resource = m::mock(JsonResource::class, ['resource' => $model])\n            ->makePartial()\n            ->shouldReceive('jsonSerialize')->andReturn(['foo' => 'bar', 'bar' => 'foo', 'number' => 123])\n            ->getMock();\n\n        $results = $resource->toPrettyJson();\n        $expected = $resource->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n\n        $results = $resource->toPrettyJson(JSON_NUMERIC_CHECK);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('\"number\": 123', $results);\n    }\n}\n"
  },
  {
    "path": "tests/Http/Middleware/CacheTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Middleware;\n\nuse Illuminate\\Http\\Middleware\\SetCacheHeaders as Cache;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Carbon;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass CacheTest extends TestCase\n{\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = (string) Cache::using('max_age=120;no-transform;s_maxage=60;');\n        $this->assertSame('Illuminate\\Http\\Middleware\\SetCacheHeaders:max_age=120;no-transform;s_maxage=60;', $signature);\n\n        $signature = (string) Cache::using('max_age=120;no-transform;s_maxage=60');\n        $this->assertSame('Illuminate\\Http\\Middleware\\SetCacheHeaders:max_age=120;no-transform;s_maxage=60', $signature);\n\n        $signature = (string) Cache::using([\n            'max_age=120',\n            'no-transform',\n            's_maxage=60',\n            'etag' => true,\n        ]);\n        $this->assertSame('Illuminate\\Http\\Middleware\\SetCacheHeaders:max_age=120;no-transform;s_maxage=60;etag', $signature);\n\n        $signature = (string) Cache::using([\n            'max_age' => 120,\n            'no-transform',\n            's_maxage' => '60',\n        ]);\n        $this->assertSame('Illuminate\\Http\\Middleware\\SetCacheHeaders:max_age=120;no-transform;s_maxage=60', $signature);\n    }\n\n    public function testDoNotSetHeaderWhenMethodNotCacheable()\n    {\n        $request = new Request;\n        $request->setMethod('PUT');\n\n        $response = (new Cache)->handle($request, function () {\n            return new Response('Hello Laravel');\n        }, 'max_age=120;s_maxage=60');\n\n        $this->assertNull($response->getMaxAge());\n    }\n\n    public function testDoNotSetHeaderWhenNoContent()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response;\n        }, 'max_age=120;s_maxage=60');\n\n        $this->assertNull($response->getMaxAge());\n        $this->assertNull($response->getEtag());\n    }\n\n    public function testSetHeaderToFileResponseEvenWithNoContent()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            $filePath = __DIR__.'/../fixtures/test.txt';\n\n            return new BinaryFileResponse($filePath);\n        }, 'max_age=120;s_maxage=60');\n\n        $this->assertNotNull($response->getMaxAge());\n    }\n\n    public function testSetHeaderToDownloadResponseEvenWithNoContent()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new StreamedResponse(function () {\n                $filePath = __DIR__.'/../fixtures/test.txt';\n                readfile($filePath);\n            });\n        }, 'max_age=120;s_maxage=60');\n\n        $this->assertNotNull($response->getMaxAge());\n    }\n\n    public function testAddHeaders()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, 'max_age=100;s_maxage=200;etag=ABC');\n\n        $this->assertSame('\"ABC\"', $response->getEtag());\n        $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control'));\n    }\n\n    public function testAddHeadersUsingArray()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, ['max_age' => 100, 's_maxage' => 200, 'etag' => 'ABC']);\n\n        $this->assertSame('\"ABC\"', $response->getEtag());\n        $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control'));\n    }\n\n    public function testGenerateEtag()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, 'etag;max_age=100;s_maxage=200');\n\n        $this->assertSame('\"4f1b32bff4356281946800d355007128\"', $response->getEtag());\n        $this->assertSame('max-age=100, public, s-maxage=200', $response->headers->get('Cache-Control'));\n    }\n\n    public function testDoesNotOverrideEtag()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return (new Response('some content'))->setEtag('XYZ');\n        }, 'etag');\n\n        $this->assertSame('\"XYZ\"', $response->getEtag());\n    }\n\n    public function testIsNotModified()\n    {\n        $request = new Request;\n        $request->headers->set('If-None-Match', '\"4f1b32bff4356281946800d355007128\"');\n\n        $response = (new Cache)->handle($request, function () {\n            return new Response('some content');\n        }, 'etag;max_age=100;s_maxage=200');\n\n        $this->assertSame(304, $response->getStatusCode());\n    }\n\n    public function testInvalidOption()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, 'invalid');\n    }\n\n    public function testLastModifiedUnixTime()\n    {\n        $time = time();\n\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, \"last_modified=$time\");\n\n        $this->assertSame($time, $response->getLastModified()->getTimestamp());\n    }\n\n    public function testLastModifiedStringDate()\n    {\n        $birthdate = '1973-04-09 10:10:10';\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, \"last_modified=$birthdate\");\n\n        $this->assertSame(Carbon::parse($birthdate)->timestamp, $response->getLastModified()->getTimestamp());\n    }\n\n    public function testTrailingDelimiterIgnored()\n    {\n        $time = time();\n\n        $response = (new Cache)->handle(new Request, function () {\n            return new Response('some content');\n        }, \"last_modified=$time;\");\n\n        $this->assertSame($time, $response->getLastModified()->getTimestamp());\n    }\n\n    public function testItDoesNotSetEtagHeadersForBinaryContent()\n    {\n        $response = (new Cache)->handle(new Request, function () {\n            return new BinaryFileResponse(__DIR__.'/../fixtures/test.txt');\n        }, 'etag');\n\n        $this->assertNull($response->getEtag());\n    }\n}\n"
  },
  {
    "path": "tests/Http/Middleware/PreventRequestForgeryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Middleware;\n\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Contracts\\Foundation\\Application;\nuse Illuminate\\Contracts\\Session\\Session;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery;\nuse Illuminate\\Http\\Exceptions\\OriginMismatchException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Session\\TokenMismatchException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PreventRequestForgeryTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        PreventRequestForgery::flushState();\n\n        parent::tearDown();\n    }\n\n    public function test_same_origin_header_passes()\n    {\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'same-origin']);\n\n        $response = $middleware->handle($request, fn () => new Response('OK'));\n\n        $this->assertEquals('OK', $response->getContent());\n    }\n\n    public function test_same_site_header_rejected_by_default()\n    {\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'same-site']);\n\n        $this->expectException(TokenMismatchException::class);\n\n        $middleware->handle($request, fn () => new Response('OK'));\n    }\n\n    public function test_same_site_header_passes_when_allowed()\n    {\n        PreventRequestForgery::allowSameSite();\n\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'same-site']);\n\n        $response = $middleware->handle($request, fn () => new Response('OK'));\n\n        $this->assertEquals('OK', $response->getContent());\n    }\n\n    public function test_cross_site_with_valid_token_passes()\n    {\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'cross-site'], 'test-token');\n\n        $response = $middleware->handle($request, fn () => new Response('OK'));\n\n        $this->assertEquals('OK', $response->getContent());\n    }\n\n    public function test_cross_site_without_token_fails()\n    {\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'cross-site']);\n\n        $this->expectException(TokenMismatchException::class);\n\n        $middleware->handle($request, fn () => new Response('OK'));\n    }\n\n    public function test_missing_header_without_token_fails()\n    {\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest();\n\n        $this->expectException(TokenMismatchException::class);\n\n        $middleware->handle($request, fn () => new Response('OK'));\n    }\n\n    public function test_origin_only_mode_rejects_cross_site()\n    {\n        PreventRequestForgery::useOriginOnly();\n\n        $middleware = $this->createMiddleware();\n        // Even with a valid token, origin-only mode rejects cross-site\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'cross-site'], 'test-token');\n\n        $this->expectException(OriginMismatchException::class);\n\n        $middleware->handle($request, fn () => new Response('OK'));\n    }\n\n    public function test_origin_only_mode_rejects_missing_header()\n    {\n        PreventRequestForgery::useOriginOnly();\n\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest([], 'test-token');\n\n        $this->expectException(OriginMismatchException::class);\n\n        $middleware->handle($request, fn () => new Response('OK'));\n    }\n\n    public function test_origin_only_mode_passes_same_origin()\n    {\n        PreventRequestForgery::useOriginOnly();\n\n        $middleware = $this->createMiddleware();\n        $request = $this->createRequest(['HTTP_SEC_FETCH_SITE' => 'same-origin']);\n\n        $response = $middleware->handle($request, fn () => new Response('OK'));\n\n        $this->assertEquals('OK', $response->getContent());\n    }\n\n    protected function createRequest(array $server = [], ?string $token = null)\n    {\n        $request = Request::create(\n            'http://example.com/test',\n            'POST',\n            $token ? ['_token' => $token] : [],\n            [],\n            [],\n            $server\n        );\n\n        $session = m::mock(Session::class);\n        $session->shouldReceive('token')->andReturn('test-token');\n        $request->setLaravelSession($session);\n\n        return $request;\n    }\n\n    protected function createMiddleware()\n    {\n        return new PreventRequestForgeryTestStub(\n            m::mock(Application::class),\n            m::mock(Encrypter::class)\n        );\n    }\n}\n\nclass PreventRequestForgeryTestStub extends PreventRequestForgery\n{\n    protected $addHttpCookie = false;\n\n    protected function runningUnitTests()\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/Http/Middleware/TrimStringsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\TrimStrings;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\n\nclass TrimStringsTest extends TestCase\n{\n    /**\n     * Test no zero-width space character returns the same string.\n     */\n    public function test_no_zero_width_space_character_returns_the_same_string()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => 'This title does not contain any zero-width space',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title does not contain any zero-width space', $req->title);\n        });\n    }\n\n    /**\n     * Test leading zero-width space character is trimmed [ZWSP].\n     */\n    public function test_leading_zero_width_space_character_is_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '​This title contains a zero-width space at the beginning',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a zero-width space at the beginning', $req->title);\n        });\n    }\n\n    public function test_trim_strings_can_globally_ignore_certain_inputs()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'globally_ignored_title' => ' test title ',\n        ]);\n\n        TrimStrings::except(['globally_ignored_title']);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals(' test title ', $req->globally_ignored_title);\n        });\n    }\n\n    /**\n     * Test trailing zero-width space character is trimmed [ZWSP].\n     */\n    public function test_trailing_zero_width_space_character_is_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => 'This title contains a zero-width space at the end​',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a zero-width space at the end', $req->title);\n        });\n    }\n\n    /**\n     * Test leading zero-width non-breakable space character is trimmed [ZWNBSP].\n     */\n    public function test_leading_zero_width_non_breakable_space_character_is_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '﻿This title contains a zero-width non-breakable space at the beginning',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a zero-width non-breakable space at the beginning', $req->title);\n        });\n    }\n\n    /**\n     * Test leading multiple zero-width non-breakable space characters are trimmed [ZWNBSP].\n     */\n    public function test_leading_multiple_zero_width_non_breakable_space_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '﻿﻿This title contains a zero-width non-breakable space at the beginning',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a zero-width non-breakable space at the beginning', $req->title);\n        });\n    }\n\n    /**\n     * Test a combination of leading and trailing zero-width non-breakable space and zero-width space characters are trimmed [ZWNBSP], [ZWSP].\n     */\n    public function test_combination_of_leading_and_trailing_zero_width_non_breakable_space_and_zero_width_space_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '﻿​﻿This title contains a combination of zero-width non-breakable space and zero-width spaces characters at the beginning and the end​',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a combination of zero-width non-breakable space and zero-width spaces characters at the beginning and the end', $req->title);\n        });\n    }\n\n    /**\n     * Test leading invisible character are trimmed [U+200E].\n     */\n    public function test_leading_invisible_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '‎This title contains a invisible character at the beginning',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a invisible character at the beginning', $req->title);\n        });\n    }\n\n    /**\n     * Test trailing invisible character are trimmed [U+200E].\n     */\n    public function test_trailing_invisible_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => 'This title contains a invisible character at the end‎',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a invisible character at the end', $req->title);\n        });\n    }\n\n    /**\n     * Test leading multiple invisible character are trimmed [U+200E].\n     */\n    public function test_leading_multiple_invisible_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '‎‎This title contains a invisible character at the beginning',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a invisible character at the beginning', $req->title);\n        });\n    }\n\n    /**\n     * Test trailing multiple invisible character are trimmed [U+200E].\n     */\n    public function test_trailing_multiple_invisible_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => 'This title contains a invisible character at the end‎‎',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a invisible character at the end', $req->title);\n        });\n    }\n\n    /**\n     * Test combination of leading and trailing multiple invisible characters are trimmed [U+200E].\n     */\n    public function test_combination_of_leading_and_trailing_multiple_invisible_characters_are_trimmed()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'title' => '‎‎This title contains a combination of a invisible character at beginning and the end‎‎',\n        ]);\n\n        $middleware = new TrimStrings;\n\n        $middleware->handle($request, function ($req) {\n            $this->assertEquals('This title contains a combination of a invisible character at beginning and the end', $req->title);\n        });\n    }\n\n    public function test_trim_strings_can_ignore_nested_attributes_using_wildcards()\n    {\n        $request = new Request;\n\n        $request->merge([\n            'users' => [\n                ['name' => '  foo  ', 'role' => '  admin  '],\n                ['name' => '  bar  ', 'role' => '  editor  '],\n            ],\n            'teams' => [\n                ['name' => '  team  '],\n            ],\n            'orders' => [\n                [\n                    'items' => [\n                        ['meta' => ['title' => '  foo  ', 'sku' => '  SKU-1  ', 'tags' => ['  alpha  ']]],\n                    ],\n                ],\n                [\n                    'items' => [\n                        ['meta' => ['title' => '  bar  ', 'sku' => '  SKU-2  ', 'tags' => ['  beta  ']]],\n                    ],\n                ],\n            ],\n        ]);\n\n        $middleware = new class extends TrimStrings\n        {\n            protected $except = [\n                'users.*.name',\n                'orders.*.items.*.meta.title',\n                'orders.*.items.*.meta.tags.*',\n            ];\n        };\n\n        $middleware->handle($request, function ($req) {\n            $this->assertSame('  foo  ', $req->input('users.0.name'));\n            $this->assertSame('  bar  ', $req->input('users.1.name'));\n            $this->assertSame('admin', $req->input('users.0.role'));\n            $this->assertSame('editor', $req->input('users.1.role'));\n            $this->assertSame('team', $req->input('teams.0.name'));\n            $this->assertSame('  foo  ', $req->input('orders.0.items.0.meta.title'));\n            $this->assertSame('SKU-1', $req->input('orders.0.items.0.meta.sku'));\n            $this->assertSame('  alpha  ', $req->input('orders.0.items.0.meta.tags.0'));\n\n            $this->assertSame('  bar  ', $req->input('orders.1.items.0.meta.title'));\n            $this->assertSame('SKU-2', $req->input('orders.1.items.0.meta.sku'));\n            $this->assertSame('  beta  ', $req->input('orders.1.items.0.meta.tags.0'));\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Http/Middleware/TrustProxiesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Middleware;\n\nuse Illuminate\\Http\\Middleware\\TrustProxies;\nuse Illuminate\\Http\\Request;\nuse PHPUnit\\Framework\\TestCase;\n\nclass TrustProxiesTest extends TestCase\n{\n    /**\n     * A list of all proxy headers.\n     *\n     * @var int\n     */\n    protected $headerAll = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_PREFIX | Request::HEADER_X_FORWARDED_AWS_ELB;\n\n    /**\n     * Test that Symfony does indeed NOT trust X-Forwarded-*\n     * headers when not given trusted proxies.\n     *\n     * This re-tests Symfony's Request class, but hopefully provides\n     * some clarify to developers looking at the tests.\n     */\n    public function test_request_does_not_trust()\n    {\n        $req = $this->createProxiedRequest();\n\n        $this->assertSame('192.168.10.10', $req->getClientIp(), 'Assert untrusted proxy x-forwarded-for header not used');\n        $this->assertSame('http', $req->getScheme(), 'Assert untrusted proxy x-forwarded-proto header not used');\n        $this->assertSame('localhost', $req->getHost(), 'Assert untrusted proxy x-forwarded-host header not used');\n        $this->assertEquals(8888, $req->getPort(), 'Assert untrusted proxy x-forwarded-port header not used');\n        $this->assertSame('', $req->getBaseUrl(), 'Assert untrusted proxy x-forwarded-prefix header not used');\n    }\n\n    /**\n     * Test that Symfony DOES indeed trust X-Forwarded-*\n     * headers when given trusted proxies.\n     *\n     * Again, this re-tests Symfony's Request class.\n     */\n    public function test_does_trust_trusted_proxy()\n    {\n        $req = $this->createProxiedRequest();\n        $req->setTrustedProxies(['192.168.10.10'], $this->headerAll);\n\n        $this->assertSame('173.174.200.38', $req->getClientIp(), 'Assert trusted proxy x-forwarded-for header used');\n        $this->assertSame('https', $req->getScheme(), 'Assert trusted proxy x-forwarded-proto header used');\n        $this->assertSame('serversforhackers.com', $req->getHost(), 'Assert trusted proxy x-forwarded-host header used');\n        $this->assertEquals(443, $req->getPort(), 'Assert trusted proxy x-forwarded-port header used');\n        $this->assertSame('/prefix', $req->getBaseUrl(), 'Assert trusted proxy x-forwarded-prefix header used');\n    }\n\n    /**\n     * Test the next most typical usage of TrustedProxies:\n     * Trusted X-Forwarded-For header, wildcard for TrustedProxies.\n     */\n    public function test_trusted_proxy_sets_trusted_proxies_with_wildcard()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, '*');\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(), 'Assert trusted proxy x-forwarded-for header used with wildcard proxy setting');\n        });\n    }\n\n    /**\n     * Test the next most typical usage of TrustedProxies:\n     * Trusted X-Forwarded-For header, wildcard for TrustedProxies.\n     */\n    public function test_trusted_proxy_sets_trusted_proxies_with_double_wildcard_for_backwards_compat()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, '**');\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(), 'Assert trusted proxy x-forwarded-for header used with wildcard proxy setting');\n        });\n    }\n\n    /**\n     * Test the next most typical usage of TrustedProxies:\n     * Trusted X-Forwarded-For header, REMOTE_ADDR for TrustedProxies.\n     */\n    public function test_trusted_proxy_sets_trusted_proxies_with_REMOTE_ADDR()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, 'REMOTE_ADDR');\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(), 'Assert trusted proxy x-forwarded-for header used with REMOTE_ADDR proxy setting');\n        });\n    }\n\n    /**\n     * Test the most typical usage of TrustProxies:\n     * Trusted X-Forwarded-For header.\n     */\n    public function test_trusted_proxy_sets_trusted_proxies()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, ['192.168.10.10']);\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(), 'Assert trusted proxy x-forwarded-for header used');\n        });\n    }\n\n    /**\n     * Test X-Forwarded-For header with multiple IP addresses.\n     */\n    public function test_get_client_ips()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, ['192.168.10.10']);\n\n        $forwardedFor = [\n            '192.0.2.2',\n            '192.0.2.2, 192.0.2.199',\n            '192.0.2.2, 192.0.2.199, 99.99.99.99',\n            '192.0.2.2,192.0.2.199',\n        ];\n\n        foreach ($forwardedFor as $forwardedForHeader) {\n            $request = $this->createProxiedRequest(['HTTP_X_FORWARDED_FOR' => $forwardedForHeader]);\n\n            $trustedProxy->handle($request, function ($request) use ($forwardedForHeader) {\n                $ips = $request->getClientIps();\n                $this->assertSame('192.0.2.2', end($ips), 'Assert sets the '.$forwardedForHeader);\n            });\n        }\n    }\n\n    /**\n     * Test X-Forwarded-For header with multiple IP addresses, with some of those being trusted.\n     */\n    public function test_get_client_ip_with_multiple_ip_addresses_some_of_which_are_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, ['192.168.10.10', '192.0.2.199']);\n\n        $forwardedFor = [\n            '192.0.2.2',\n            '192.0.2.2, 192.0.2.199',\n            '99.99.99.99, 192.0.2.2, 192.0.2.199',\n            '192.0.2.2,192.0.2.199',\n        ];\n\n        foreach ($forwardedFor as $forwardedForHeader) {\n            $request = $this->createProxiedRequest(['HTTP_X_FORWARDED_FOR' => $forwardedForHeader]);\n\n            $trustedProxy->handle($request, function ($request) use ($forwardedForHeader) {\n                $this->assertSame('192.0.2.2', $request->getClientIp(), 'Assert sets the '.$forwardedForHeader);\n            });\n        }\n    }\n\n    /**\n     * Test X-Forwarded-For header with multiple IP addresses, with * wildcard trusting of all proxies.\n     */\n    public function test_get_client_ip_with_multiple_ip_addresses_all_proxies_are_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy($this->headerAll, '*');\n\n        $forwardedFor = [\n            '192.0.2.2',\n            '192.0.2.199, 192.0.2.2',\n            '192.0.2.199,192.0.2.2',\n            '99.99.99.99,192.0.2.199,192.0.2.2',\n        ];\n\n        foreach ($forwardedFor as $forwardedForHeader) {\n            $request = $this->createProxiedRequest(['HTTP_X_FORWARDED_FOR' => $forwardedForHeader]);\n\n            $trustedProxy->handle($request, function ($request) use ($forwardedForHeader) {\n                $this->assertSame('192.0.2.2', $request->getClientIp(), 'Assert sets the '.$forwardedForHeader);\n            });\n        }\n    }\n\n    /**\n     * Test distrusting a header.\n     */\n    public function test_can_distrust_headers()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_FORWARDED, ['192.168.10.10']);\n\n        $request = $this->createProxiedRequest([\n            'HTTP_FORWARDED' => 'for=173.174.200.40:443; proto=https; host=serversforhackers.com',\n            'HTTP_X_FORWARDED_FOR' => '173.174.200.38',\n            'HTTP_X_FORWARDED_HOST' => 'svrs4hkrs.com',\n            'HTTP_X_FORWARDED_PORT' => '80',\n            'HTTP_X_FORWARDED_PROTO' => 'http',\n        ]);\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.40', $request->getClientIp(),\n                'Assert trusted proxy used forwarded header for IP');\n            $this->assertSame('https', $request->getScheme(),\n                'Assert trusted proxy used forwarded header for scheme');\n            $this->assertSame('serversforhackers.com', $request->getHost(),\n                'Assert trusted proxy used forwarded header for host');\n            $this->assertEquals(443, $request->getPort(), 'Assert trusted proxy used forwarded header for port');\n        });\n    }\n\n    /**\n     * Test that only the X-Forwarded-For header is trusted.\n     */\n    public function test_x_forwarded_for_header_only_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_X_FORWARDED_FOR, '*');\n\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(),\n                'Assert trusted proxy used forwarded header for IP');\n            $this->assertSame('http', $request->getScheme(),\n                'Assert trusted proxy did not use forwarded header for scheme');\n            $this->assertSame('localhost', $request->getHost(),\n                'Assert trusted proxy did not use forwarded header for host');\n            $this->assertEquals(8888, $request->getPort(), 'Assert trusted proxy did not use forwarded header for port');\n            $this->assertSame('', $request->getBaseUrl(), 'Assert trusted proxy did not use forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test that only the X-Forwarded-Host header is trusted.\n     */\n    public function test_x_forwarded_host_header_only_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_X_FORWARDED_HOST, '*');\n\n        $request = $this->createProxiedRequest(['HTTP_X_FORWARDED_HOST' => 'serversforhackers.com:8888']);\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('192.168.10.10', $request->getClientIp(),\n                'Assert trusted proxy did not use forwarded header for IP');\n            $this->assertSame('http', $request->getScheme(),\n                'Assert trusted proxy did not use forwarded header for scheme');\n            $this->assertSame('serversforhackers.com', $request->getHost(),\n                'Assert trusted proxy used forwarded header for host');\n            $this->assertEquals(8888, $request->getPort(), 'Assert trusted proxy did not use forwarded header for port');\n            $this->assertSame('', $request->getBaseUrl(), 'Assert trusted proxy did not use forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test that only the X-Forwarded-Port header is trusted.\n     */\n    public function test_x_forwarded_port_header_only_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_X_FORWARDED_PORT, '*');\n\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('192.168.10.10', $request->getClientIp(),\n                'Assert trusted proxy did not use forwarded header for IP');\n            $this->assertSame('http', $request->getScheme(),\n                'Assert trusted proxy did not use forwarded header for scheme');\n            $this->assertSame('localhost', $request->getHost(),\n                'Assert trusted proxy did not use forwarded header for host');\n            $this->assertEquals(443, $request->getPort(), 'Assert trusted proxy used forwarded header for port');\n            $this->assertSame('', $request->getBaseUrl(), 'Assert trusted proxy did not use forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test that only the X-Forwarded-Prefix header is trusted.\n     */\n    public function test_x_forwarded_prefix_header_only_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_X_FORWARDED_PREFIX, '*');\n\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('192.168.10.10', $request->getClientIp(),\n                'Assert trusted proxy did not use forwarded header for IP');\n            $this->assertSame('http', $request->getScheme(),\n                'Assert trusted proxy did not use forwarded header for scheme');\n            $this->assertSame('localhost', $request->getHost(),\n                'Assert trusted proxy did not use forwarded header for host');\n            $this->assertEquals(8888, $request->getPort(), 'Assert trusted proxy did not use forwarded header for port');\n            $this->assertSame('/prefix', $request->getBaseUrl(), 'Assert trusted proxy used forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test that only the X-Forwarded-Proto header is trusted.\n     */\n    public function test_x_forwarded_proto_header_only_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(Request::HEADER_X_FORWARDED_PROTO, '*');\n\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('192.168.10.10', $request->getClientIp(),\n                'Assert trusted proxy did not use forwarded header for IP');\n            $this->assertSame('https', $request->getScheme(),\n                'Assert trusted proxy used forwarded header for scheme');\n            $this->assertSame('localhost', $request->getHost(),\n                'Assert trusted proxy did not use forwarded header for host');\n            $this->assertEquals(8888, $request->getPort(), 'Assert trusted proxy did not use forwarded header for port');\n            $this->assertSame('', $request->getBaseUrl(), 'Assert trusted proxy did not use forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test a combination of individual X-Forwarded-* headers are trusted.\n     */\n    public function test_x_forwarded_multiple_individual_headers_trusted()\n    {\n        $trustedProxy = $this->createTrustedProxy(\n            Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST |\n            Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO,\n            '*'\n        );\n\n        $request = $this->createProxiedRequest();\n\n        $trustedProxy->handle($request, function ($request) {\n            $this->assertSame('173.174.200.38', $request->getClientIp(),\n                'Assert trusted proxy used forwarded header for IP');\n            $this->assertSame('https', $request->getScheme(),\n                'Assert trusted proxy used forwarded header for scheme');\n            $this->assertSame('serversforhackers.com', $request->getHost(),\n                'Assert trusted proxy used forwarded header for host');\n            $this->assertEquals(443, $request->getPort(), 'Assert trusted proxy used forwarded header for port');\n            $this->assertSame('', $request->getBaseUrl(), 'Assert trusted proxy did not use forwarded header for prefix');\n        });\n    }\n\n    /**\n     * Test to ensure it's reading text-based configurations and converting it correctly.\n     */\n    public function test_is_reading_text_based_configurations()\n    {\n        $request = $this->createProxiedRequest();\n\n        // trust *all* \"X-Forwarded-*\" headers\n        $trustedProxy = $this->createTrustedProxy('HEADER_X_FORWARDED_ALL', '192.168.1.1, 192.168.1.2');\n        $trustedProxy->handle($request, function (Request $request) {\n            $this->assertEquals($request->getTrustedHeaderSet(), $this->headerAll,\n                'Assert trusted proxy used all \"X-Forwarded-*\" header');\n\n            $this->assertEquals($request->getTrustedProxies(), ['192.168.1.1', '192.168.1.2'],\n                'Assert trusted proxy using proxies as string separated by comma.');\n        });\n\n        // or, if your proxy instead uses the \"Forwarded\" header\n        $trustedProxy = $this->createTrustedProxy('HEADER_FORWARDED', '192.168.1.1, 192.168.1.2');\n        $trustedProxy->handle($request, function (Request $request) {\n            $this->assertEquals($request->getTrustedHeaderSet(), Request::HEADER_FORWARDED,\n                'Assert trusted proxy used forwarded header');\n\n            $this->assertEquals($request->getTrustedProxies(), ['192.168.1.1', '192.168.1.2'],\n                'Assert trusted proxy using proxies as string separated by comma.');\n        });\n\n        // or, if you're using AWS ELB\n        $trustedProxy = $this->createTrustedProxy('HEADER_X_FORWARDED_AWS_ELB', '192.168.1.1, 192.168.1.2');\n        $trustedProxy->handle($request, function (Request $request) {\n            $this->assertEquals($request->getTrustedHeaderSet(), Request::HEADER_X_FORWARDED_AWS_ELB,\n                'Assert trusted proxy used AWS ELB header');\n\n            $this->assertEquals($request->getTrustedProxies(), ['192.168.1.1', '192.168.1.2'],\n                'Assert trusted proxy using proxies as string separated by comma.');\n        });\n    }\n\n    /**\n     * Fake an HTTP request by generating a Symfony Request object.\n     *\n     * @param  array  $serverOverrides\n     * @return \\Illuminate\\Http\\Request\n     */\n    protected function createProxiedRequest($serverOverrides = [])\n    {\n        // Add some X-Forwarded headers and over-ride\n        // defaults, simulating a request made over a proxy\n        $serverOverrides = array_replace([\n            'HTTP_X_FORWARDED_FOR' => '173.174.200.38',         // X-Forwarded-For    -- getClientIp()\n            'HTTP_X_FORWARDED_HOST' => 'serversforhackers.com', // X-Forwarded-Host   -- getHosts()\n            'HTTP_X_FORWARDED_PORT' => '443',                   // X-Forwarded-Port   -- getPort()\n            'HTTP_X_FORWARDED_PREFIX' => '/prefix',             // X-Forwarded-Prefix -- getBaseUrl()\n            'HTTP_X_FORWARDED_PROTO' => 'https',                // X-Forwarded-Proto  -- getScheme() / isSecure()\n            'SERVER_PORT' => 8888,\n            'HTTP_HOST' => 'localhost',\n            'REMOTE_ADDR' => '192.168.10.10',\n        ], $serverOverrides);\n\n        // Create a fake request made over \"http\", one that we'd get over a proxy\n        // which is likely something like this:\n        $request = Request::create('http://localhost:8888/tag/proxy', 'GET', [], [], [], $serverOverrides, null);\n        // Need to make sure these haven't already been set\n        $request->setTrustedProxies([], $this->headerAll);\n\n        return $request;\n    }\n\n    /**\n     * Create an anonymous middleware class.\n     *\n     * @param  null|string|int  $trustedHeaders\n     * @param  null|array|string  $trustedProxies\n     * @return \\Illuminate\\Http\\Middleware\\TrustProxies\n     */\n    protected function createTrustedProxy($trustedHeaders, $trustedProxies)\n    {\n        return new class($trustedHeaders, $trustedProxies) extends TrustProxies\n        {\n            public function __construct($trustedHeaders, $trustedProxies)\n            {\n                $this->headers = $trustedHeaders;\n                $this->proxies = $trustedProxies;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "tests/Http/Middleware/VitePreloadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Middleware;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Foundation\\Vite;\nuse Illuminate\\Http\\Middleware\\AddLinkHeadersForPreloadedAssets;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Facade;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\n\nclass VitePreloadingTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Facade::setFacadeApplication(null);\n        Facade::clearResolvedInstances();\n\n        parent::tearDown();\n    }\n\n    public function testItDoesNotSetLinkTagWhenNoTagsHaveBeenPreloaded()\n    {\n        $app = new Container;\n        $app->instance(Vite::class, new class extends Vite\n        {\n            protected $preloadedAssets = [];\n        });\n        Facade::setFacadeApplication($app);\n\n        $response = (new AddLinkHeadersForPreloadedAssets)->handle(new Request, function () {\n            return new Response('Hello Laravel');\n        });\n\n        $this->assertNull($response->headers->get('Link'));\n    }\n\n    public function testItAddsPreloadLinkHeader()\n    {\n        $app = new Container;\n        $app->instance(Vite::class, new class extends Vite\n        {\n            protected $preloadedAssets = [\n                'https://laravel.com/app.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n            ];\n        });\n        Facade::setFacadeApplication($app);\n\n        $response = (new AddLinkHeadersForPreloadedAssets)->handle(new Request, function () {\n            return new Response('Hello Laravel');\n        });\n\n        $this->assertSame(\n            '<https://laravel.com/app.js>; rel=\"modulepreload\"; foo=\"bar\"',\n            $response->headers->get('Link'),\n        );\n    }\n\n    public function testItDoesNotAttachHeadersToNonIlluminateResponses()\n    {\n        $app = new Container;\n        $app->instance(Vite::class, new class extends Vite\n        {\n            protected $preloadedAssets = [\n                'https://laravel.com/app.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n            ];\n        });\n        Facade::setFacadeApplication($app);\n\n        $response = (new AddLinkHeadersForPreloadedAssets)->handle(new Request, function () {\n            return new SymfonyResponse('Hello Laravel');\n        });\n\n        $this->assertNull($response->headers->get('Link'));\n    }\n\n    public function testItDoesNotOverwriteOtherLinkHeaders()\n    {\n        $app = new Container;\n        $app->instance(Vite::class, new class extends Vite\n        {\n            protected $preloadedAssets = [\n                'https://laravel.com/app.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n            ];\n        });\n        Facade::setFacadeApplication($app);\n\n        $response = (new AddLinkHeadersForPreloadedAssets)->handle(new Request, function () {\n            return new Response('Hello Laravel', headers: ['Link' => '<https://laravel.com/logo.png>; rel=\"preload\"; as=\"image\"']);\n        });\n\n        $this->assertSame(\n            [\n                '<https://laravel.com/logo.png>; rel=\"preload\"; as=\"image\"',\n                '<https://laravel.com/app.js>; rel=\"modulepreload\"; foo=\"bar\"',\n            ],\n            $response->headers->all('Link'),\n        );\n    }\n\n    public function testItCanLimitNumberOfAssetsPreloaded()\n    {\n        $app = new Container;\n        $app->instance(Vite::class, new class extends Vite\n        {\n            protected $preloadedAssets = [\n                'https://laravel.com/first.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n                'https://laravel.com/second.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n                'https://laravel.com/third.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n                'https://laravel.com/fourth.js' => [\n                    'rel=\"modulepreload\"',\n                    'foo=\"bar\"',\n                ],\n            ];\n        });\n        Facade::setFacadeApplication($app);\n\n        $response = (new AddLinkHeadersForPreloadedAssets)->handle(new Request, fn () => new Response('ok'), 2);\n\n        $this->assertSame(\n            [\n                '<https://laravel.com/first.js>; rel=\"modulepreload\"; foo=\"bar\", <https://laravel.com/second.js>; rel=\"modulepreload\"; foo=\"bar\"',\n            ],\n            $response->headers->all('Link'),\n        );\n    }\n\n    public function test_it_can_configure_the_middleware()\n    {\n        $definition = AddLinkHeadersForPreloadedAssets::using(limit: 5);\n\n        $this->assertSame('Illuminate\\Http\\Middleware\\AddLinkHeadersForPreloadedAssets:5', $definition);\n    }\n}\n"
  },
  {
    "path": "tests/Http/Resources/JsonApi/JsonApiResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Http\\Resources\\JsonApi;\n\nuse BadMethodCallException;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\nuse PHPUnit\\Framework\\TestCase;\n\nclass JsonApiResourceTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        JsonResource::flushState();\n        JsonApiResource::flushState();\n\n        parent::tearDown();\n    }\n\n    public function testResponseWrapperIsHardCodedToData()\n    {\n        JsonResource::wrap('laravel');\n\n        $this->assertSame('data', JsonApiResource::$wrap);\n    }\n\n    public function testUnableToSetWrapper()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Using Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource::wrap() method is not allowed.');\n\n        JsonApiResource::wrap('laravel');\n    }\n\n    public function testUnableToUnsetWrapper()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Using Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource::withoutWrapping() method is not allowed.');\n\n        JsonApiResource::withoutWrapping();\n    }\n\n    public function testFlushStateResetsMaxRelationshipDepthToDefault()\n    {\n        $this->assertSame(5, JsonApiResource::$maxRelationshipDepth);\n\n        JsonApiResource::maxRelationshipDepth(10);\n        $this->assertSame(10, JsonApiResource::$maxRelationshipDepth);\n\n        JsonApiResource::flushState();\n\n        $this->assertSame(5, JsonApiResource::$maxRelationshipDepth);\n    }\n}\n"
  },
  {
    "path": "tests/Http/fixtures/test.txt",
    "content": "This is a story about something that happened long ago when your grandfather was a child.\n"
  },
  {
    "path": "tests/IgnoreSkippedPrinter.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests;\n\nuse PHPUnit\\Framework\\TestResult;\nuse PHPUnit\\TextUI\\DefaultResultPrinter;\n\nclass IgnoreSkippedPrinter extends DefaultResultPrinter\n{\n    protected function printSkipped(TestResult $result): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/ApiAuthenticationWithEloquentTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('pdo_mysql')]\nclass ApiAuthenticationWithEloquentTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        // Auth configuration\n        $app['config']->set('auth.defaults.guard', 'api');\n\n        $app['config']->set('auth.guards.api', [\n            'driver' => 'token',\n            'provider' => 'users',\n            'hash' => false,\n        ]);\n\n        // Database configuration\n        $app['config']->set('database.default', 'testbench');\n\n        $app['config']->set('database.connections.testbench', [\n            'driver' => 'mysql',\n            'host' => env('DB_HOST', '127.0.0.1'),\n            'username' => 'root',\n            'password' => 'invalid-credentials',\n            'database' => 'forge',\n            'prefix' => '',\n        ]);\n    }\n\n    public function testAuthenticationViaApiWithEloquentUsingWrongDatabaseCredentialsShouldNotCauseInfiniteLoop()\n    {\n        Route::get('/auth', function () {\n            return 'success';\n        })->middleware('auth:api');\n\n        $this->expectException(QueryException::class);\n\n        $this->expectExceptionMessage(\"Access denied for user 'root'@\");\n\n        try {\n            $this->withoutExceptionHandling()->get('/auth', ['Authorization' => 'Bearer whatever']);\n        } catch (QueryException $e) {\n            if (Str::startsWith($e->getMessage(), 'SQLSTATE[HY000] [2002]')) {\n                $this->markTestSkipped('MySQL instance required.');\n            }\n\n            throw $e;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/AuthenticationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Auth\\EloquentUserProvider;\nuse Illuminate\\Auth\\Events\\Attempting;\nuse Illuminate\\Auth\\Events\\Authenticated;\nuse Illuminate\\Auth\\Events\\Failed;\nuse Illuminate\\Auth\\Events\\Login;\nuse Illuminate\\Auth\\Events\\Logout;\nuse Illuminate\\Auth\\Events\\OtherDeviceLogout;\nuse Illuminate\\Auth\\Events\\Validated;\nuse Illuminate\\Auth\\SessionGuard;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Testing\\Fakes\\EventFake;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\AuthenticationTestUser;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass AuthenticationTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set([\n            'auth.providers.users.model' => AuthenticationTestUser::class,\n            'hashing.driver' => 'bcrypt',\n        ]);\n    }\n\n    protected function defineRoutes($router)\n    {\n        $router->get('basic', function () {\n            return $this->app['auth']->guard()->basic()\n                ?: $this->app['auth']->user()->toJson();\n        });\n\n        $router->get('basicWithCondition', function () {\n            return $this->app['auth']->guard()->basic('email', ['is_active' => true])\n                ?: $this->app['auth']->user()->toJson();\n        });\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->renameColumn('name', 'username');\n        });\n\n        Schema::table('users', function (Blueprint $table) {\n            $table->tinyInteger('is_active')->default(0);\n        });\n\n        AuthenticationTestUser::create([\n            'username' => 'username',\n            'email' => 'email',\n            'password' => bcrypt('password'),\n            'is_active' => true,\n        ]);\n    }\n\n    public function testBasicAuthProtectsRoute()\n    {\n        $this->get('basic')->assertStatus(401);\n    }\n\n    public function testBasicAuthPassesOnCorrectCredentials()\n    {\n        $response = $this->get('basic', [\n            'Authorization' => 'Basic '.base64_encode('email:password'),\n        ]);\n\n        $response->assertStatus(200);\n        $this->assertSame('email', $response->json()['email']);\n    }\n\n    public function testBasicAuthRespectsAdditionalConditions()\n    {\n        AuthenticationTestUser::create([\n            'username' => 'username2',\n            'email' => 'email2',\n            'password' => bcrypt('password'),\n            'is_active' => false,\n        ]);\n\n        $this->get('basicWithCondition', [\n            'Authorization' => 'Basic '.base64_encode('email2:password2'),\n        ])->assertStatus(401);\n\n        $this->get('basicWithCondition', [\n            'Authorization' => 'Basic '.base64_encode('email:password'),\n        ])->assertStatus(200);\n    }\n\n    public function testBasicAuthFailsOnWrongCredentials()\n    {\n        $this->get('basic', [\n            'Authorization' => 'Basic '.base64_encode('email:wrong_password'),\n        ])->assertStatus(401);\n    }\n\n    public function testLoggingInFailsViaAttempt()\n    {\n        Event::fake();\n\n        $this->assertFalse(\n            $this->app['auth']->attempt(['email' => 'wrong', 'password' => 'password'])\n        );\n\n        $this->assertFalse($this->app['auth']->check());\n        $this->assertNull($this->app['auth']->user());\n\n        Event::assertDispatched(Attempting::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(['email' => 'wrong', 'password' => 'password'], $event->credentials);\n\n            return true;\n        });\n        Event::assertNotDispatched(Validated::class);\n\n        Event::assertDispatched(Failed::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(['email' => 'wrong', 'password' => 'password'], $event->credentials);\n            $this->assertNull($event->user);\n\n            return true;\n        });\n    }\n\n    public function testLoggingInSucceedsViaAttempt()\n    {\n        Event::fake();\n\n        $this->assertTrue(\n            $this->app['auth']->attempt(['email' => 'email', 'password' => 'password'])\n        );\n        $this->assertInstanceOf(AuthenticationTestUser::class, $this->app['auth']->user());\n        $this->assertTrue($this->app['auth']->check());\n\n        Event::assertDispatched(Attempting::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(['email' => 'email', 'password' => 'password'], $event->credentials);\n\n            return true;\n        });\n        Event::assertDispatched(Validated::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n        Event::assertDispatched(Login::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n        Event::assertDispatched(Authenticated::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n    }\n\n    public function testLoggingInUsingId()\n    {\n        $this->app['auth']->loginUsingId(1);\n        $this->assertEquals(1, $this->app['auth']->user()->id);\n\n        $this->assertFalse($this->app['auth']->loginUsingId(1000));\n    }\n\n    public function testLoggingOut()\n    {\n        Event::fake();\n\n        $this->app['auth']->loginUsingId(1);\n        $this->assertEquals(1, $this->app['auth']->user()->id);\n\n        $this->app['auth']->logout();\n        $this->assertNull($this->app['auth']->user());\n        Event::assertDispatched(Logout::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n    }\n\n    public function testLoggingOutOtherDevices()\n    {\n        Event::fake();\n\n        $this->app['auth']->loginUsingId(1);\n\n        $user = $this->app['auth']->user();\n\n        $this->assertEquals(1, $user->id);\n\n        $this->app['auth']->logoutOtherDevices('password');\n        $this->assertEquals(1, $user->id);\n\n        Event::assertDispatched(OtherDeviceLogout::class, function ($event) {\n            $this->assertSame('web', $event->guard);\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n    }\n\n    public function testPasswordMustBeValidToLogOutOtherDevices()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('current password');\n\n        $this->app['auth']->loginUsingId(1);\n\n        $user = $this->app['auth']->user();\n\n        $this->assertEquals(1, $user->id);\n\n        $this->app['auth']->logoutOtherDevices('adifferentpassword');\n    }\n\n    public function testLoggingInOutViaAttemptRemembering()\n    {\n        $this->assertTrue(\n            $this->app['auth']->attempt(['email' => 'email', 'password' => 'password'], true)\n        );\n        $this->assertInstanceOf(AuthenticationTestUser::class, $this->app['auth']->user());\n        $this->assertTrue($this->app['auth']->check());\n        $this->assertNotNull($this->app['auth']->user()->getRememberToken());\n\n        $oldToken = $this->app['auth']->user()->getRememberToken();\n        $user = $this->app['auth']->user();\n\n        $this->app['auth']->logout();\n\n        $this->assertNotNull($user->getRememberToken());\n        $this->assertNotEquals($oldToken, $user->getRememberToken());\n    }\n\n    public function testLoggingInOutCurrentDeviceViaRemembering()\n    {\n        $this->assertTrue(\n            $this->app['auth']->attempt(['email' => 'email', 'password' => 'password'], true)\n        );\n        $this->assertInstanceOf(AuthenticationTestUser::class, $this->app['auth']->user());\n        $this->assertTrue($this->app['auth']->check());\n        $this->assertNotNull($this->app['auth']->user()->getRememberToken());\n\n        $oldToken = $this->app['auth']->user()->getRememberToken();\n        $user = $this->app['auth']->user();\n\n        $this->app['auth']->logoutCurrentDevice();\n\n        $this->assertNotNull($user->getRememberToken());\n        $this->assertEquals($oldToken, $user->getRememberToken());\n    }\n\n    public function testAuthViaAttemptRemembering()\n    {\n        $provider = new EloquentUserProvider(app('hash'), AuthenticationTestUser::class);\n\n        $user = AuthenticationTestUser::create([\n            'username' => 'username2',\n            'email' => 'email2',\n            'password' => bcrypt('password'),\n            'remember_token' => $token = Str::random(),\n            'is_active' => false,\n        ]);\n\n        $this->assertEquals($user->id, $provider->retrieveByToken($user->id, $token)->id);\n\n        $user->update([\n            'remember_token' => null,\n        ]);\n\n        $this->assertNull($provider->retrieveByToken($user->id, $token));\n    }\n\n    public function testDispatcherChangesIfThereIsOneOnTheAuthGuard()\n    {\n        $this->assertInstanceOf(SessionGuard::class, $this->app['auth']->guard());\n        $this->assertInstanceOf(Dispatcher::class, $this->app['auth']->guard()->getDispatcher());\n\n        Event::fake();\n\n        $this->assertInstanceOf(SessionGuard::class, $this->app['auth']->guard());\n        $this->assertInstanceOf(EventFake::class, $this->app['auth']->guard()->getDispatcher());\n    }\n\n    public function testDispatcherChangesIfThereIsOneOnTheCustomAuthGuard()\n    {\n        $this->app['config']['auth.guards.myGuard'] = [\n            'driver' => 'myCustomDriver',\n            'provider' => 'user',\n        ];\n\n        Auth::extend('myCustomDriver', function () {\n            return new MyCustomGuardStub;\n        });\n\n        $this->assertInstanceOf(MyCustomGuardStub::class, $this->app['auth']->guard('myGuard'));\n        $this->assertInstanceOf(Dispatcher::class, $this->app['auth']->guard()->getDispatcher());\n\n        Event::fake();\n\n        $this->assertInstanceOf(MyCustomGuardStub::class, $this->app['auth']->guard('myGuard'));\n        $this->assertInstanceOf(EventFake::class, $this->app['auth']->guard()->getDispatcher());\n    }\n\n    public function testHasNoProblemIfThereIsNoDispatchingTheAuthCustomGuard()\n    {\n        $this->app['config']['auth.guards.myGuard'] = [\n            'driver' => 'myCustomDriver',\n            'provider' => 'user',\n        ];\n\n        Auth::extend('myCustomDriver', function () {\n            return new MyDispatcherLessCustomGuardStub;\n        });\n\n        $this->assertInstanceOf(MyDispatcherLessCustomGuardStub::class, $this->app['auth']->guard('myGuard'));\n\n        Event::fake();\n\n        $this->assertInstanceOf(MyDispatcherLessCustomGuardStub::class, $this->app['auth']->guard('myGuard'));\n    }\n}\n\nclass MyCustomGuardStub\n{\n    protected $events;\n\n    public function __construct()\n    {\n        $this->setDispatcher(new Dispatcher);\n    }\n\n    public function setDispatcher(Dispatcher $events)\n    {\n        $this->events = $events;\n    }\n\n    public function getDispatcher()\n    {\n        return $this->events;\n    }\n}\n\nclass MyDispatcherLessCustomGuardStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/AuthenticationTestUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Notifications\\Notifiable;\n\nclass AuthenticationTestUser extends Authenticatable\n{\n    use Notifiable;\n\n    public $table = 'users';\n    public $timestamps = false;\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be hidden for arrays.\n     *\n     * @var string[]\n     */\n    protected $hidden = [\n        'password', 'remember_token',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Models/AuthenticationTestUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Models;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\n\nclass AuthenticationTestUser extends Authenticatable\n{\n    public $table = 'users';\n    public $timestamps = false;\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be hidden for arrays.\n     *\n     * @var string[]\n     */\n    protected $hidden = [\n        'password', 'remember_token',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Models/Nested/SubTestUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Models\\Nested;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\n\nclass SubTestUser extends Authenticatable\n{\n    public $table = 'users';\n    public $timestamps = false;\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be hidden for arrays.\n     *\n     * @var string[]\n     */\n    protected $hidden = [\n        'password', 'remember_token',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Models/Nested/TopTestUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Models\\Nested;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\n\nclass TopTestUser extends Authenticatable\n{\n    public $table = 'users';\n    public $timestamps = false;\n\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be hidden for arrays.\n     *\n     * @var string[]\n     */\n    protected $hidden = [\n        'password', 'remember_token',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Models/Policies/Nested/SubTestUserPolicy.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Models\\Policies\\Nested;\n\nclass SubTestUserPolicy\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Policies/AuthenticationTestUserPolicy.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Policies;\n\nclass AuthenticationTestUserPolicy\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Fixtures/Policies/Nested/TopTestUserPolicy.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Policies\\Nested;\n\nclass TopTestUserPolicy\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Auth/ForgotPasswordTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Auth\\Events\\PasswordResetLinkSent;\nuse Illuminate\\Auth\\Notifications\\ResetPassword;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Notification;\nuse Illuminate\\Support\\Facades\\Password;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\AuthenticationTestUser;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass ForgotPasswordTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function tearDown(): void\n    {\n        ResetPassword::$createUrlCallback = null;\n        ResetPassword::$toMailCallback = null;\n\n        parent::tearDown();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('auth.providers.users.model', AuthenticationTestUser::class);\n    }\n\n    protected function defineRoutes($router)\n    {\n        $router->get('password/reset/{token}', function ($token) {\n            return 'Reset password!';\n        })->name('password.reset');\n\n        $router->get('custom/password/reset/{token}', function ($token) {\n            return 'Custom reset password!';\n        })->name('custom.password.reset');\n    }\n\n    public function testItCanSendForgotPasswordEmail()\n    {\n        Notification::fake();\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('password.reset', ['token' => $notification->token, 'email' => $user->email]);\n            }\n        );\n    }\n\n    public function testItCanTriggerPasswordResetSentEvent()\n    {\n        Event::fake([PasswordResetLinkSent::class]);\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Event::assertDispatched(PasswordResetLinkSent::class, function ($event) {\n            $this->assertEquals(1, $event->user->id);\n\n            return true;\n        });\n    }\n\n    public function testItCanSendForgotPasswordEmailViaCreateUrlUsing()\n    {\n        Notification::fake();\n\n        ResetPassword::createUrlUsing(function ($user, string $token) {\n            return route('custom.password.reset', $token);\n        });\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('custom.password.reset', ['token' => $notification->token]);\n            }\n        );\n    }\n\n    public function testItCanSendForgotPasswordEmailViaToMailUsing()\n    {\n        Notification::fake();\n\n        ResetPassword::toMailUsing(function ($notifiable, $token) {\n            return (new MailMessage)\n                ->subject(__('Reset your password'))\n                ->line(__('You are receiving this email because we received a password reset request for your account.'))\n                ->action(__('Reset Password'), route('custom.password.reset', $token))\n                ->line(__('If you did not request a password reset, no further action is required.'));\n        });\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('custom.password.reset', ['token' => $notification->token]);\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/ForgotPasswordWithoutDefaultRoutesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Auth\\Notifications\\ResetPassword;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Support\\Facades\\Notification;\nuse Illuminate\\Support\\Facades\\Password;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\AuthenticationTestUser;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass ForgotPasswordWithoutDefaultRoutesTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function tearDown(): void\n    {\n        ResetPassword::$createUrlCallback = null;\n        ResetPassword::$toMailCallback = null;\n\n        parent::tearDown();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('auth.providers.users.model', AuthenticationTestUser::class);\n    }\n\n    protected function defineRoutes($router)\n    {\n        $router->get('custom/password/reset/{token}', function ($token) {\n            return 'Custom reset password!';\n        })->name('custom.password.reset');\n    }\n\n    public function testItCannotSendForgotPasswordEmail()\n    {\n        $this->expectException('Symfony\\Component\\Routing\\Exception\\RouteNotFoundException');\n        $this->expectExceptionMessage('Route [password.reset] not defined.');\n\n        Notification::fake();\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('custom.password.reset', ['token' => $notification->token, 'email' => $user->email]);\n            }\n        );\n    }\n\n    public function testItCanSendForgotPasswordEmailViaCreateUrlUsing()\n    {\n        Notification::fake();\n\n        ResetPassword::createUrlUsing(function ($user, string $token) {\n            return route('custom.password.reset', $token);\n        });\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('custom.password.reset', ['token' => $notification->token]);\n            }\n        );\n    }\n\n    public function testItCanSendForgotPasswordEmailViaToMailUsing()\n    {\n        Notification::fake();\n\n        ResetPassword::toMailUsing(function ($notifiable, $token) {\n            return (new MailMessage)\n                ->subject(__('Reset your password'))\n                ->line(__('You are receiving this email because we received a password reset request for your account.'))\n                ->action(__('Reset Password'), route('custom.password.reset', $token))\n                ->line(__('If you did not request a password reset, no further action is required.'));\n        });\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n\n        Password::broker()->sendResetLink([\n            'email' => $user->email,\n        ]);\n\n        Notification::assertSentTo(\n            $user,\n            function (ResetPassword $notification, $channels) use ($user) {\n                $message = $notification->toMail($user);\n\n                return ! is_null($notification->token)\n                    && $message->actionUrl === route('custom.password.reset', ['token' => $notification->token]);\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/GatePolicyResolutionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Auth\\Access\\Events\\GateEvaluated;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UsePolicy;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Gate;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\AuthenticationTestUser;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Models\\Policies\\Nested\\SubTestUserPolicy;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Policies\\AuthenticationTestUserPolicy;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\Policies\\Nested\\TopTestUserPolicy;\nuse Orchestra\\Testbench\\TestCase;\n\nclass GatePolicyResolutionTest extends TestCase\n{\n    public function testGateEvaluationEventIsFired()\n    {\n        Event::fake();\n\n        Gate::check('foo');\n\n        Event::assertDispatched(GateEvaluated::class);\n    }\n\n    public function testPolicyCanBeGuessedUsingClassConventions()\n    {\n        $this->assertInstanceOf(\n            AuthenticationTestUserPolicy::class,\n            Gate::getPolicyFor(AuthenticationTestUser::class)\n        );\n\n        $this->assertInstanceOf(\n            AuthenticationTestUserPolicy::class,\n            Gate::getPolicyFor(Fixtures\\Models\\AuthenticationTestUser::class)\n        );\n\n        $this->assertNull(\n            Gate::getPolicyFor(static::class)\n        );\n    }\n\n    public function testPolicyCanBeGuessedForParallelClassHierarchies()\n    {\n        $this->assertInstanceOf(\n            TopTestUserPolicy::class,\n            Gate::getPolicyFor(Fixtures\\Models\\Nested\\TopTestUser::class)\n        );\n\n        $this->assertInstanceOf(\n            SubTestUserPolicy::class,\n            Gate::getPolicyFor(Fixtures\\Models\\Nested\\SubTestUser::class)\n        );\n    }\n\n    public function testPolicyCanBeGuessedUsingCallback()\n    {\n        Gate::guessPolicyNamesUsing(function () {\n            return AuthenticationTestUserPolicy::class;\n        });\n\n        $this->assertInstanceOf(\n            AuthenticationTestUserPolicy::class,\n            Gate::getPolicyFor(AuthenticationTestUser::class)\n        );\n    }\n\n    public function testPolicyCanBeGuessedMultipleTimes()\n    {\n        Gate::guessPolicyNamesUsing(function () {\n            return [\n                'App\\\\Policies\\\\TestUserPolicy',\n                AuthenticationTestUserPolicy::class,\n            ];\n        });\n\n        $this->assertInstanceOf(\n            AuthenticationTestUserPolicy::class,\n            Gate::getPolicyFor(AuthenticationTestUser::class)\n        );\n    }\n\n    public function testPolicyCanBeGivenByAttribute(): void\n    {\n        Gate::guessPolicyNamesUsing(fn () => [AuthenticationTestUserPolicy::class]);\n\n        $this->assertInstanceOf(PostPolicy::class, Gate::getPolicyFor(Post::class));\n    }\n}\n\n#[UsePolicy(PostPolicy::class)]\nclass Post extends Model\n{\n}\n\nclass PostPolicy\n{\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Middleware/RedirectIfAuthenticatedTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Middleware;\n\nuse Illuminate\\Auth\\Middleware\\RedirectIfAuthenticated;\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Auth\\Fixtures\\AuthenticationTestUser;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RedirectIfAuthenticatedTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->withoutExceptionHandling();\n\n        /** @var \\Illuminate\\Contracts\\Routing\\Registrar $router */\n        $this->router = $this->app->make(Registrar::class);\n\n        $this->router->get('/login', function () {\n            return response('Login Form');\n        })->middleware(RedirectIfAuthenticated::class);\n\n        UserFactory::new()->create();\n\n        $user = AuthenticationTestUser::first();\n        $this->router->get('/login', function () {\n            return response('Login Form');\n        })->middleware(RedirectIfAuthenticated::class);\n\n        UserFactory::new()->create();\n\n        $this->user = AuthenticationTestUser::first();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('auth.providers.users.model', AuthenticationTestUser::class);\n    }\n\n    protected function defineDatabaseMigrations()\n    {\n        $this->loadLaravelMigrations();\n    }\n\n    public function testWhenDashboardNamedRouteIsAvailable()\n    {\n        $this->router->get('/named-dashboard', function () {\n            return response('Named Dashboard');\n        })->name('dashboard');\n\n        $response = $this->actingAs($this->user)->get('/login');\n\n        $response->assertRedirect('/named-dashboard');\n    }\n\n    public function testWhenHomeNamedRouteIsAvailable()\n    {\n        $this->router->get('/named-home', function () {\n            return response('Named Home');\n        })->name('home');\n\n        $response = $this->actingAs($this->user)->get('/login');\n\n        $response->assertRedirect('/named-home');\n    }\n\n    public function testWhenDashboardSlugIsAvailable()\n    {\n        $this->router->get('/dashboard', function () {\n            return response('My Dashboard');\n        });\n\n        $response = $this->actingAs($this->user)->get('/login');\n\n        $response->assertRedirect('/dashboard');\n    }\n\n    public function testWhenHomeSlugIsAvailable()\n    {\n        $this->router->get('/home', function () {\n            return response('My Home');\n        })->name('home');\n\n        $response = $this->actingAs($this->user)->get('/login');\n\n        $response->assertRedirect('/home');\n    }\n\n    public function testWhenHomeOrDashboardAreNotAvailable()\n    {\n        $response = $this->actingAs($this->user)->get('/login');\n\n        $response->assertRedirect('/');\n    }\n\n    public function testWhenGuest()\n    {\n        $response = $this->get('/login');\n\n        $response->assertOk();\n        $response->assertSee('Login Form');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/Middleware/RequirePasswordTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth\\Middleware;\n\nuse Illuminate\\Auth\\Middleware\\RequirePassword;\nuse Illuminate\\Contracts\\Config\\Repository;\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Session\\Middleware\\StartSession;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RequirePasswordTest extends TestCase\n{\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = (string) RequirePassword::using('route.name');\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RequirePassword:route.name', $signature);\n\n        $signature = (string) RequirePassword::using('route.name', 100);\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RequirePassword:route.name,100', $signature);\n\n        $signature = (string) RequirePassword::using(passwordTimeoutSeconds: 100);\n        $this->assertSame('Illuminate\\Auth\\Middleware\\RequirePassword:,100', $signature);\n    }\n\n    public function testUserSeesTheWantedPageIfThePasswordWasRecentlyConfirmed()\n    {\n        $this->withoutExceptionHandling();\n\n        /** @var \\Illuminate\\Contracts\\Routing\\Registrar $router */\n        $router = $this->app->make(Registrar::class);\n\n        $router->get('test-route', function (): Response {\n            return new Response('foobar');\n        })->middleware([StartSession::class, RequirePassword::class]);\n\n        $response = $this->withSession(['auth.password_confirmed_at' => time()])->get('test-route');\n\n        $response->assertOk();\n        $response->assertSeeText('foobar');\n    }\n\n    public function testUserIsRedirectedToThePasswordConfirmRouteIfThePasswordWasNotRecentlyConfirmed()\n    {\n        $this->withoutExceptionHandling();\n\n        /** @var \\Illuminate\\Contracts\\Routing\\Registrar $router */\n        $router = $this->app->make(Registrar::class);\n\n        $router->get('password-confirm', function (): Response {\n            return new Response('foo');\n        })->name('password.confirm');\n\n        $router->get('test-route', function (): Response {\n            return new Response('foobar');\n        })->middleware([StartSession::class, RequirePassword::class]);\n\n        $response = $this->withSession(['auth.password_confirmed_at' => time() - 10801])->get('test-route');\n\n        $response->assertStatus(302);\n        $response->assertRedirect($this->app->make(UrlGenerator::class)->route('password.confirm'));\n    }\n\n    public function testUserIsRedirectedToACustomRouteIfThePasswordWasNotRecentlyConfirmedAndTheCustomRouteIsSpecified()\n    {\n        $this->withoutExceptionHandling();\n\n        /** @var \\Illuminate\\Contracts\\Routing\\Registrar $router */\n        $router = $this->app->make(Registrar::class);\n\n        $router->get('confirm', function (): Response {\n            return new Response('foo');\n        })->name('my-password.confirm');\n\n        $router->get('test-route', function (): Response {\n            return new Response('foobar');\n        })->middleware([StartSession::class, RequirePassword::class.':my-password.confirm']);\n\n        $response = $this->withSession(['auth.password_confirmed_at' => time() - 10801])->get('test-route');\n\n        $response->assertStatus(302);\n        $response->assertRedirect($this->app->make(UrlGenerator::class)->route('my-password.confirm'));\n    }\n\n    public function testAuthPasswordTimeoutIsConfigurable()\n    {\n        $this->withoutExceptionHandling();\n\n        /** @var \\Illuminate\\Contracts\\Routing\\Registrar $router */\n        $router = $this->app->make(Registrar::class);\n\n        $router->get('password-confirm', function (): Response {\n            return new Response('foo');\n        })->name('password.confirm');\n\n        $router->get('test-route', function (): Response {\n            return new Response('foobar');\n        })->middleware([StartSession::class, RequirePassword::class]);\n\n        $this->app->make(Repository::class)->set('auth.password_timeout', 500);\n\n        $response = $this->withSession(['auth.password_confirmed_at' => time() - 495])->get('test-route');\n\n        $response->assertOk();\n        $response->assertSeeText('foobar');\n\n        $response = $this->withSession(['auth.password_confirmed_at' => time() - 501])->get('test-route');\n\n        $response->assertStatus(302);\n        $response->assertRedirect($this->app->make(UrlGenerator::class)->route('password.confirm'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Auth/RehashOnLogoutOtherDevicesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Auth;\n\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Http\\Request;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\n#[WithEnv('BCRYPT_ROUNDS', 12)]\n#[WithConfig('app.key', 'base64:IUHRqAQ99pZ0A1MPjbuv1D6ff3jxv0GIvS2qIW4JNU4=')]\nclass RehashOnLogoutOtherDevicesTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function defineRoutes($router)\n    {\n        $router->post('logout', function (Request $request) {\n            auth()->logoutOtherDevices($request->input('password'));\n\n            return response()->noContent();\n        })->middleware(['web', 'auth']);\n    }\n\n    public function testItRehashThePasswordUsingLogoutOtherDevices()\n    {\n        $this->withoutExceptionHandling();\n\n        $user = UserFactory::new()->create();\n\n        $password = $user->password;\n\n        $this->actingAs($user);\n\n        $this->post('logout', [\n            'password' => 'password',\n        ])->assertStatus(204);\n\n        $user->refresh();\n\n        $this->assertNotSame($password, $user->password);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Broadcasting/BroadcastManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Broadcasting;\n\nuse Illuminate\\Broadcasting\\BroadcastEvent;\nuse Illuminate\\Broadcasting\\BroadcastManager;\nuse Illuminate\\Broadcasting\\UniqueBroadcastEvent;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow;\nuse Illuminate\\Contracts\\Broadcasting\\ShouldRescue;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Support\\Facades\\Broadcast;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Queue;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass BroadcastManagerTest extends TestCase\n{\n    public function testEventCanBeBroadcastNow()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventNow);\n\n        Bus::assertDispatched(BroadcastEvent::class);\n        Queue::assertNotPushed(BroadcastEvent::class);\n    }\n\n    public function testEventsCanBeBroadcast()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEvent);\n\n        Bus::assertNotDispatched(BroadcastEvent::class);\n        Queue::assertPushed(BroadcastEvent::class);\n    }\n\n    public function testEventsCanBeBroadcastUsingQueueRoutes()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Queue::route(TestEvent::class, 'broadcast-queue', 'broadcast-connection');\n\n        Broadcast::queue(new TestEvent);\n        Bus::assertNotDispatched(BroadcastEvent::class);\n        Queue::connection('broadcast-connection')->assertPushedOn('broadcast-queue', BroadcastEvent::class);\n    }\n\n    public function testEventsCanBeRescued()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventRescue);\n\n        Bus::assertNotDispatched(BroadcastEvent::class);\n        Queue::assertPushed(BroadcastEvent::class);\n    }\n\n    public function testNowEventsCanBeRescued()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventNowRescue);\n\n        Bus::assertDispatched(BroadcastEvent::class);\n        Queue::assertNotPushed(BroadcastEvent::class);\n    }\n\n    public function testUniqueEventsCanBeBroadcast()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventUnique);\n\n        Bus::assertNotDispatched(UniqueBroadcastEvent::class);\n        Queue::assertPushed(UniqueBroadcastEvent::class);\n\n        $lockKey = 'laravel_unique_job:'.hash('xxh128', TestEventUnique::class).':';\n        $this->assertFalse($this->app->get(Cache::class)->lock($lockKey, 10)->get());\n    }\n\n    public function testUniqueEventsCanBeBroadcastWithUniqueIdFromProperty()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventUniqueWithIdProperty);\n\n        Bus::assertNotDispatched(UniqueBroadcastEvent::class);\n        Queue::assertPushed(UniqueBroadcastEvent::class);\n\n        $lockKey = 'laravel_unique_job:'.hash('xxh128', TestEventUniqueWithIdProperty::class).':unique-id-property';\n        $this->assertFalse($this->app->get(Cache::class)->lock($lockKey, 10)->get());\n    }\n\n    public function testUniqueEventsCanBeBroadcastWithUniqueIdFromMethod()\n    {\n        Bus::fake();\n        Queue::fake();\n\n        Broadcast::queue(new TestEventUniqueWithIdMethod);\n\n        Bus::assertNotDispatched(UniqueBroadcastEvent::class);\n        Queue::assertPushed(UniqueBroadcastEvent::class);\n\n        $lockKey = 'laravel_unique_job:'.hash('xxh128', TestEventUniqueWithIdMethod::class).':unique-id-method';\n        $this->assertFalse($this->app->get(Cache::class)->lock($lockKey, 10)->get());\n    }\n\n    public function testThrowExceptionWhenUnknownStoreIsUsed()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Broadcast connection [alien_connection] is not defined.');\n\n        $userConfig = [\n            'broadcasting' => [\n                'connections' => [\n                    'my_connection' => [\n                        'driver' => 'pusher',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n\n        $broadcastManager = new BroadcastManager($app);\n\n        $broadcastManager->connection('alien_connection');\n    }\n\n    public function testCustomDriverClosureBoundObjectIsBroadcastManager()\n    {\n        $manager = new BroadcastManager($this->getApp([\n            'broadcasting' => [\n                'connections' => [\n                    __CLASS__ => [\n                        'driver' => __CLASS__,\n                    ],\n                ],\n            ],\n        ]));\n        $manager->extend(__CLASS__, fn () => $this);\n        $this->assertSame($manager, $manager->connection(__CLASS__));\n    }\n\n    public function testThrowExceptionWhenDriverCreationFails()\n    {\n        $userConfig = [\n            'broadcasting' => [\n                'connections' => [\n                    'log_connection_1' => [\n                        'driver' => 'log',\n                    ],\n                ],\n            ],\n        ];\n\n        $app = $this->getApp($userConfig);\n        $app->singleton(\\Psr\\Log\\LoggerInterface::class, function () {\n            throw new \\RuntimeException('Logger service not available');\n        });\n\n        $broadcastManager = new BroadcastManager($app);\n\n        try {\n            $broadcastManager->connection('log_connection_1');\n            $this->fail('Expected BroadcastException was not thrown');\n        } catch (RuntimeException $e) {\n            $this->assertStringContainsString('Failed to create broadcaster for connection \"log_connection_1\"', $e->getMessage());\n            $this->assertStringContainsString('Logger service not available', $e->getMessage());\n            $this->assertInstanceOf(\\RuntimeException::class, $e->getPrevious());\n        }\n    }\n\n    protected function getApp(array $userConfig)\n    {\n        $app = new Container;\n        $app->singleton('config', fn () => new Repository($userConfig));\n\n        return $app;\n    }\n}\n\nclass TestEvent implements ShouldBroadcast\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]\n     */\n    public function broadcastOn()\n    {\n        //\n    }\n}\n\nclass TestEventNow implements ShouldBroadcastNow\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]\n     */\n    public function broadcastOn()\n    {\n        //\n    }\n}\n\nclass TestEventUnique implements ShouldBroadcast, ShouldBeUnique\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]\n     */\n    public function broadcastOn()\n    {\n        //\n    }\n}\n\nclass TestEventUniqueWithIdProperty extends TestEventUnique\n{\n    public string $uniqueId = 'unique-id-property';\n}\n\nclass TestEventUniqueWithIdMethod extends TestEventUnique\n{\n    public string $uniqueId = 'unique-id-method';\n}\n\nclass TestEventRescue implements ShouldBroadcast, ShouldRescue\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]\n     */\n    public function broadcastOn()\n    {\n        //\n    }\n}\n\nclass TestEventNowRescue implements ShouldBroadcastNow, ShouldRescue\n{\n    /**\n     * Get the channels the event should broadcast on.\n     *\n     * @return \\Illuminate\\Broadcasting\\Channel|\\Illuminate\\Broadcasting\\Channel[]\n     */\n    public function broadcastOn()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Broadcasting/SendingBroadcastsViaAnonymousEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Broadcasting;\n\nuse Illuminate\\Broadcasting\\AnonymousEvent;\nuse Illuminate\\Broadcasting\\PresenceChannel;\nuse Illuminate\\Broadcasting\\PrivateChannel;\nuse Illuminate\\Support\\Facades\\Broadcast as BroadcastFacade;\nuse Illuminate\\Support\\Facades\\Event as EventFacade;\nuse Orchestra\\Testbench\\TestCase;\nuse ReflectionClass;\n\nclass SendingBroadcastsViaAnonymousEventTest extends TestCase\n{\n    public function testBroadcastIsSent()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on('test-channel')\n            ->with(['some' => 'data'])\n            ->as('test-event')\n            ->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return (new ReflectionClass($event))->getProperty('connection')->getValue($event) === null &&\n                $event->broadcastOn() === ['test-channel'] &&\n                $event->broadcastAs() === 'test-event' &&\n                $event->broadcastWith() === ['some' => 'data'];\n        });\n    }\n\n    public function testBroadcastIsSentNow()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on('test-channel')\n            ->with(['some' => 'data'])\n            ->as('test-event')\n            ->sendNow();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return (new ReflectionClass($event))->getProperty('connection')->getValue($event) === null &&\n                $event->shouldBroadcastNow();\n        });\n    }\n\n    public function testDefaultNameIsSet()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on('test-channel')\n            ->with(['some' => 'data'])\n            ->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return $event->broadcastAs() === 'AnonymousEvent';\n        });\n    }\n\n    public function testDefaultPayloadIsSet()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on('test-channel')->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return $event->broadcastWith() === [];\n        });\n    }\n\n    public function testSendToMultipleChannels()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on([\n            'test-channel',\n            new PrivateChannel('test-channel'),\n            'presence-test-channel',\n        ])->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            [$one, $two, $three] = $event->broadcastOn();\n\n            return $one === 'test-channel' &&\n                $two instanceof PrivateChannel &&\n                $two->name === 'private-test-channel' &&\n                $three === 'presence-test-channel';\n        });\n    }\n\n    public function testSendViaANonDefaultConnection()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::on('test-channel')\n            ->via('pusher')\n            ->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return (new ReflectionClass($event))->getProperty('connection')->getValue($event) === 'pusher';\n        });\n    }\n\n    public function testSendToOthersOnly()\n    {\n        EventFacade::fake();\n\n        $this->app['request']->headers->add(['X-Socket-ID' => '12345']);\n\n        BroadcastFacade::on('test-channel')->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return $event->socket === null;\n        });\n\n        BroadcastFacade::on('test-channel')\n            ->toOthers()\n            ->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            return $event->socket === '12345';\n        });\n    }\n\n    public function testSendToPrivateChannel()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::private('test-channel')->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            $channel = $event->broadcastOn()[0];\n\n            return $channel instanceof PrivateChannel && $channel->name === 'private-test-channel';\n        });\n    }\n\n    public function testSendToPresenceChannel()\n    {\n        EventFacade::fake();\n\n        BroadcastFacade::presence('test-channel')->send();\n\n        EventFacade::assertDispatched(AnonymousEvent::class, function ($event) {\n            $channel = $event->broadcastOn()[0];\n\n            return $channel instanceof PresenceChannel && $channel->name === 'presence-test-channel';\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/ArrayCacheFunnelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\n\n#[WithConfig('cache.default', 'array')]\nclass ArrayCacheFunnelTest extends CacheFunnelTestCase\n{\n    protected function cache(): Repository\n    {\n        return Cache::store('array');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/CacheFunnelTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Cache\\Limiters\\LimiterTimeoutException;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Orchestra\\Testbench\\TestCase;\nuse Throwable;\n\nabstract class CacheFunnelTestCase extends TestCase\n{\n    abstract protected function cache(): Repository;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        try {\n            $this->releaseFunnelLocks();\n        } catch (Throwable) {\n        }\n    }\n\n    public function testFunnelBasicHappyPath()\n    {\n        $result = $this->cache()->funnel('test')\n            ->limit(2)\n            ->releaseAfter(60)\n            ->block(0)\n            ->then(fn () => 'hello');\n\n        $this->assertSame('hello', $result);\n    }\n\n    public function testFunnelReleasesLockAfterCallback()\n    {\n        for ($i = 0; $i < 5; $i++) {\n            $result = $this->cache()->funnel('test')\n                ->limit(1)\n                ->releaseAfter(60)\n                ->block(0)\n                ->then(fn () => 'ok');\n\n            $this->assertSame('ok', $result);\n        }\n    }\n\n    public function testFunnelLockReleasedOnException()\n    {\n        try {\n            $this->cache()->funnel('test')\n                ->limit(1)\n                ->releaseAfter(60)\n                ->block(0)\n                ->then(function () {\n                    throw new \\Exception('fail');\n                });\n        } catch (\\Exception) {\n        }\n\n        $result = $this->cache()->funnel('test')\n            ->limit(1)\n            ->releaseAfter(60)\n            ->block(0)\n            ->then(fn () => 'recovered');\n\n        $this->assertSame('recovered', $result);\n    }\n\n    public function testFunnelTimeoutExceptionWithoutFailureCallback()\n    {\n        $this->cache()->lock('test1', 60)->get();\n        $this->cache()->lock('test2', 60)->get();\n\n        $this->expectException(LimiterTimeoutException::class);\n\n        $this->cache()->funnel('test')\n            ->limit(2)\n            ->releaseAfter(60)\n            ->block(0)\n            ->then(fn () => 'should not run');\n    }\n\n    public function testFunnelFailureCallbackReceivesException()\n    {\n        $this->cache()->lock('test1', 60)->get();\n        $this->cache()->lock('test2', 60)->get();\n\n        $result = $this->cache()->funnel('test')\n            ->limit(2)\n            ->releaseAfter(60)\n            ->block(0)\n            ->then(\n                fn () => 'should not run',\n                function ($e) {\n                    $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n\n                    return 'failed';\n                }\n            );\n\n        $this->assertSame('failed', $result);\n    }\n\n    public function testFunnelIndependentKeys()\n    {\n        $this->cache()->lock('key-a1', 60)->get();\n\n        $result = $this->cache()->funnel('key-b')\n            ->limit(1)\n            ->releaseAfter(60)\n            ->block(0)\n            ->then(fn () => 'key-b-ok');\n\n        $this->assertSame('key-b-ok', $result);\n    }\n\n    protected function releaseFunnelLocks(): void\n    {\n        $this->cache()->lock('test1')->forceRelease();\n        $this->cache()->lock('test2')->forceRelease();\n        $this->cache()->lock('key-a1')->forceRelease();\n        $this->cache()->lock('key-b1')->forceRelease();\n    }\n\n    protected function tearDown(): void\n    {\n        try {\n            $this->releaseFunnelLocks();\n        } catch (Throwable) {\n        }\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/DatabaseCacheFunnelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration('cache')]\nclass DatabaseCacheFunnelTest extends CacheFunnelTestCase\n{\n    use LazilyRefreshDatabase;\n\n    protected function cache(): Repository\n    {\n        return Cache::store('database');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/DynamoDbStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Aws\\Exception\\AwsException;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Attributes\\RequiresEnv;\nuse Orchestra\\Testbench\\TestCase;\n\n#[RequiresEnv('DYNAMODB_CACHE_TABLE')]\nclass DynamoDbStoreTest extends TestCase\n{\n    public function testItemsCanBeStoredAndRetrieved()\n    {\n        Cache::driver('dynamodb')->put('name', 'Taylor', 10);\n        $this->assertSame('Taylor', Cache::driver('dynamodb')->get('name'));\n\n        Cache::driver('dynamodb')->put(['name' => 'Abigail', 'age' => 28], 10);\n        $this->assertSame('Abigail', Cache::driver('dynamodb')->get('name'));\n        $this->assertEquals(28, Cache::driver('dynamodb')->get('age'));\n\n        $this->assertEquals([\n            'name' => 'Abigail',\n            'age' => 28,\n            'height' => null,\n        ], Cache::driver('dynamodb')->many(['name', 'age', 'height']));\n\n        Cache::driver('dynamodb')->forget('name');\n        $this->assertNull(Cache::driver('dynamodb')->get('name'));\n    }\n\n    public function testItemsCanBeAtomicallyAdded()\n    {\n        $key = Str::random(6);\n\n        $this->assertTrue(Cache::driver('dynamodb')->add($key, 'Taylor', 10));\n        $this->assertFalse(Cache::driver('dynamodb')->add($key, 'Taylor', 10));\n    }\n\n    public function testItemsCanBeIncrementedAndDecremented()\n    {\n        Cache::driver('dynamodb')->put('counter', 0, 10);\n        Cache::driver('dynamodb')->increment('counter');\n        Cache::driver('dynamodb')->increment('counter', 4);\n\n        $this->assertEquals(5, Cache::driver('dynamodb')->get('counter'));\n\n        Cache::driver('dynamodb')->decrement('counter', 5);\n        $this->assertEquals(0, Cache::driver('dynamodb')->get('counter'));\n    }\n\n    public function testLocksCanBeAcquired()\n    {\n        Cache::driver('dynamodb')->lock('lock', 10)->get(function () {\n            $this->assertFalse(Cache::driver('dynamodb')->lock('lock', 10)->get());\n        });\n    }\n\n    /**\n     * Define environment setup.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function defineEnvironment($app)\n    {\n        if (! env('DYNAMODB_CACHE_TABLE')) {\n            $this->markTestSkipped('DynamoDB not configured.');\n        }\n\n        $app['config']->set('cache.default', 'dynamodb');\n\n        $config = $app['config']->get('cache.stores.dynamodb');\n\n        /** @var \\Aws\\DynamoDb\\DynamoDbClient $client */\n        $client = $app->make(Repository::class)->getStore()->getClient();\n\n        if ($this->dynamoTableExists($client, $config['table'])) {\n            return;\n        }\n\n        $client->createTable([\n            'TableName' => $config['table'],\n            'KeySchema' => [\n                [\n                    'AttributeName' => $config['attributes']['key'] ?? 'key',\n                    'KeyType' => 'HASH',\n                ],\n            ],\n            'AttributeDefinitions' => [\n                [\n                    'AttributeName' => $config['attributes']['key'] ?? 'key',\n                    'AttributeType' => 'S',\n                ],\n            ],\n            'ProvisionedThroughput' => [\n                'ReadCapacityUnits' => 1,\n                'WriteCapacityUnits' => 1,\n            ],\n        ]);\n    }\n\n    /**\n     * Determine if the given DynamoDB table exists.\n     *\n     * @param  \\Aws\\DynamoDb\\DynamoDbClient  $client\n     * @param  string  $table\n     * @return bool\n     */\n    public function dynamoTableExists(DynamoDbClient $client, $table)\n    {\n        try {\n            $client->describeTable([\n                'TableName' => $table,\n            ]);\n\n            return true;\n        } catch (AwsException $e) {\n            if (Str::contains($e->getAwsErrorMessage(), ['resource not found', 'Cannot do operations on a non-existent table'])) {\n                return false;\n            }\n\n            throw $e;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/FailoverStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Cache\\Events\\CacheFailedOver;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('cache.default', 'failover')]\n#[WithConfig('cache.stores.array.serialize', false)]\nclass FailoverStoreTest extends TestCase\n{\n    #[\\Override]\n    protected function setUp(): void\n    {\n        parent::setUp();\n        CantSerialize::$throwException = true;\n    }\n\n    public function testFailoverCacheDispatchesEventOnlyOnce()\n    {\n        config([\n            'cache.stores.failing_array' => array_merge(config('cache.stores.array'), ['serialize' => true]),\n        ]);\n\n        config([\n            'cache.stores.failover.stores' => ['failing_array', 'array'],\n        ]);\n\n        Event::fake();\n\n        Cache::put('irrelevant', new CantSerialize());\n\n        Event::assertDispatched(CacheFailedOver::class, function (CacheFailedOver $event) {\n            return $event->storeName === 'failing_array';\n        });\n        $this->assertInstanceOf(CantSerialize::class, Cache::store('array')->get('irrelevant'));\n\n        Cache::put('irrelevant2', new CantSerialize());\n        Event::assertDispatchedTimes(CacheFailedOver::class, 1);\n        CantSerialize::$throwException = false;\n        Cache::put('irrelevant3', new CantSerialize());\n        Event::assertDispatchedTimes(CacheFailedOver::class, 1);\n        CantSerialize::$throwException = true;\n        Cache::put('irrelevant4', new CantSerialize());\n        Event::assertDispatchedTimes(CacheFailedOver::class, 2);\n    }\n}\n\nclass CantSerialize\n{\n    public static bool $throwException = true;\n\n    public function __serialize()\n    {\n        if (self::$throwException) {\n            throw new \\Exception('You cannot serialize this.');\n        }\n\n        return [];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/FileCacheFunnelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\n\n#[WithConfig('cache.default', 'file')]\nclass FileCacheFunnelTest extends CacheFunnelTestCase\n{\n    protected function cache(): Repository\n    {\n        return Cache::store('file');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/FileCacheLockTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Exception;\nuse Illuminate\\Contracts\\Cache\\LockTimeoutException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Sleep;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Throwable;\n\n#[WithConfig('cache.default', 'file')]\nclass FileCacheLockTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        // flush lock from previous tests\n        Cache::lock('foo')->forceRelease();\n    }\n\n    public function testLocksCanBeAcquiredAndReleased()\n    {\n        $lock = Cache::lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse(Cache::lock('foo', 10)->get());\n        $lock->release();\n\n        $lock = Cache::lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse(Cache::lock('foo', 10)->get());\n        Cache::lock('foo')->release();\n    }\n\n    public function testLocksCanBlockForSeconds()\n    {\n        $this->assertSame('taylor', Cache::lock('foo', 10)->block(1, function () {\n            return 'taylor';\n        }));\n\n        Cache::lock('foo')->forceRelease();\n        $this->assertTrue(Cache::lock('foo', 10)->block(1));\n    }\n\n    public function testConcurrentLocksAreReleasedSafely()\n    {\n        Sleep::fake(syncWithCarbon: true);\n\n        $firstLock = Cache::lock('foo', 1);\n        $this->assertTrue($firstLock->get());\n        Sleep::for(2)->seconds();\n\n        $secondLock = Cache::lock('foo', 10);\n        $this->assertTrue($secondLock->get());\n\n        $firstLock->release();\n\n        $this->assertFalse(Cache::lock('foo')->get());\n    }\n\n    public function testLocksWithFailedBlockCallbackAreReleased()\n    {\n        $firstLock = Cache::lock('foo', 10);\n\n        try {\n            $firstLock->block(1, function () {\n                throw new Exception('failed');\n            });\n        } catch (Exception) {\n            // Not testing the exception, just testing the lock\n            // is released regardless of the how the exception\n            // thrown by the callback was handled.\n        }\n\n        $secondLock = Cache::lock('foo', 1);\n\n        $this->assertTrue($secondLock->get());\n    }\n\n    public function testLocksCanBeReleasedUsingOwnerToken()\n    {\n        $firstLock = Cache::lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('file')->restoreLock('foo', $owner);\n        $secondLock->release();\n\n        $this->assertTrue(Cache::lock('foo')->get());\n    }\n\n    public function testOwnerStatusCanBeCheckedAfterRestoringLock()\n    {\n        $firstLock = Cache::lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('file')->restoreLock('foo', $owner);\n        $this->assertTrue($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testCacheRememberReturnsValueWhenLockWithSameKeyExists()\n    {\n        $lock = Cache::lock('my-key', 5);\n        $this->assertTrue($lock->get());\n\n        $value = Cache::remember('my-key', 60, fn () => 'expected-value');\n\n        $this->assertSame('expected-value', $value);\n\n        $lock->release();\n    }\n\n    public function testOtherOwnerDoesNotOwnLockAfterRestore()\n    {\n        $firstLock = Cache::lock('foo', 10);\n        $this->assertTrue($firstLock->isOwnedBy(null));\n        $this->assertTrue($firstLock->get());\n        $this->assertTrue($firstLock->isOwnedBy($firstLock->owner()));\n\n        $secondLock = Cache::store('file')->restoreLock('foo', 'other_owner');\n        $this->assertTrue($secondLock->isOwnedBy($firstLock->owner()));\n        $this->assertFalse($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testExceptionIfBlockCanNotAcquireLock()\n    {\n        Sleep::fake(syncWithCarbon: true);\n\n        // acquire and not release lock\n        Cache::lock('foo', 10)->get();\n\n        // try to get lock and hit block timeout\n        $this->expectException(LockTimeoutException::class);\n        Cache::lock('foo', 10)->block(5);\n    }\n\n    protected function tearDown(): void\n    {\n        try {\n            Cache::lock('foo')->forceRelease();\n        } catch (Throwable) {\n        }\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/Fixtures/Unserializable.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache\\Fixtures;\n\nuse Exception;\n\nclass Unserializable\n{\n    public function __sleep()\n    {\n        throw new Exception('Not serializable');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/MemcachedCacheLockTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\LockTimeoutException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('memcached')]\nclass MemcachedCacheLockTestCase extends MemcachedIntegrationTestCase\n{\n    public function testMemcachedLocksCanBeAcquiredAndReleased()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n        $this->assertTrue(Cache::store('memcached')->lock('foo', 10)->get());\n        $this->assertFalse(Cache::store('memcached')->lock('foo', 10)->get());\n        Cache::store('memcached')->lock('foo')->forceRelease();\n        $this->assertTrue(Cache::store('memcached')->lock('foo', 10)->get());\n        $this->assertFalse(Cache::store('memcached')->lock('foo', 10)->get());\n        Cache::store('memcached')->lock('foo')->forceRelease();\n    }\n\n    public function testMemcachedLocksCanBlockForSeconds()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n        $this->assertSame('taylor', Cache::store('memcached')->lock('foo', 10)->block(1, function () {\n            return 'taylor';\n        }));\n\n        Cache::store('memcached')->lock('foo')->release();\n        $this->assertTrue(Cache::store('memcached')->lock('foo', 10)->block(1));\n    }\n\n    public function testLocksCanRunCallbacks()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n        $this->assertSame('taylor', Cache::store('memcached')->lock('foo', 10)->get(function () {\n            return 'taylor';\n        }));\n    }\n\n    public function testLocksThrowTimeoutIfBlockExpires()\n    {\n        $this->expectException(LockTimeoutException::class);\n\n        Cache::store('memcached')->lock('foo')->release();\n        Cache::store('memcached')->lock('foo', 5)->get();\n        $this->assertSame('taylor', Cache::store('memcached')->lock('foo', 10)->block(1, function () {\n            return 'taylor';\n        }));\n    }\n\n    public function testConcurrentMemcachedLocksAreReleasedSafely()\n    {\n        Cache::store('memcached')->lock('bar')->forceRelease();\n\n        $firstLock = Cache::store('memcached')->lock('bar', 1);\n        $this->assertTrue($firstLock->acquire());\n        sleep(2);\n\n        $secondLock = Cache::store('memcached')->lock('bar', 10);\n        $this->assertTrue($secondLock->acquire());\n\n        $firstLock->release();\n\n        $this->assertTrue(Cache::store('memcached')->has('bar'));\n    }\n\n    public function testMemcachedLocksCanBeReleasedUsingOwnerToken()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('memcached')->lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('memcached')->restoreLock('foo', $owner);\n        $secondLock->release();\n\n        $this->assertTrue(Cache::store('memcached')->lock('foo')->get());\n    }\n\n    public function testOwnerStatusCanBeCheckedAfterRestoringLock()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('memcached')->lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('memcached')->restoreLock('foo', $owner);\n        $this->assertTrue($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testOtherOwnerDoesNotOwnLockAfterRestore()\n    {\n        Cache::store('memcached')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('memcached')->lock('foo', 10);\n        $this->assertTrue($firstLock->isOwnedBy(null));\n        $this->assertTrue($firstLock->get());\n        $this->assertTrue($firstLock->isOwnedBy($firstLock->owner()));\n\n        $secondLock = Cache::store('memcached')->restoreLock('foo', 'other_owner');\n        $this->assertTrue($secondLock->isOwnedBy($firstLock->owner()));\n        $this->assertFalse($secondLock->isOwnedByCurrentProcess());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/MemcachedIntegrationTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Memcached;\nuse Orchestra\\Testbench\\TestCase;\n\nabstract class MemcachedIntegrationTestCase extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        // Determine whether there is a running Memcached instance\n        $testConnection = new Memcached;\n\n        $testConnection->addServer(\n            env('MEMCACHED_HOST', '127.0.0.1'),\n            env('MEMCACHED_PORT', 11211)\n        );\n\n        $testConnection->getVersion();\n\n        if ($testConnection->getResultCode() > Memcached::RES_SUCCESS) {\n            $this->markTestSkipped('Memcached could not establish a connection.');\n        }\n\n        $testConnection->quit();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/MemcachedTaggedCacheTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Support\\Facades\\Cache;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('memcached')]\nclass MemcachedTaggedCacheTestCase extends MemcachedIntegrationTestCase\n{\n    public function testMemcachedCanStoreAndRetrieveTaggedCacheItems()\n    {\n        $store = Cache::store('memcached');\n\n        $store->tags(['people', 'artists'])->put('John', 'foo', 2);\n        $store->tags(['people', 'authors'])->put('Anne', 'bar', 2);\n\n        $this->assertSame('foo', $store->tags(['people', 'artists'])->get('John'));\n        $this->assertSame('bar', $store->tags(['people', 'authors'])->get('Anne'));\n\n        $store->tags(['people', 'artists'])->put('John', 'baz');\n        $store->tags(['people', 'authors'])->put('Anne', 'qux');\n\n        $this->assertSame('baz', $store->tags(['people', 'artists'])->get('John'));\n        $this->assertSame('qux', $store->tags(['people', 'authors'])->get('Anne'));\n\n        $store->tags('authors')->flush();\n        $this->assertNull($store->tags(['people', 'authors'])->get('Anne'));\n\n        $store->tags(['people', 'authors'])->flush();\n        $this->assertNull($store->tags(['people', 'artists'])->get('John'));\n    }\n\n    public function testMemcachedCanStoreManyTaggedCacheItems()\n    {\n        $store = Cache::store('memcached');\n\n        $store->tags(['people', 'artists'])->putMany(['John' => 'foo', 'Jane' => 'bar'], 2);\n\n        $this->assertSame('foo', $store->tags(['people', 'artists'])->get('John'));\n        $this->assertSame('bar', $store->tags(['people', 'artists'])->get('Jane'));\n\n        $store->tags(['people', 'artists'])->putMany(['John' => 'baz', 'Jane' => 'qux']);\n\n        $this->assertSame('baz', $store->tags(['people', 'artists'])->get('John'));\n        $this->assertSame('qux', $store->tags(['people', 'artists'])->get('Jane'));\n\n        $store->tags(['people', 'artists'])->putMany(['John' => 'baz', 'Jane' => 'qux'], -1);\n\n        $this->assertNull($store->tags(['people', 'artists'])->get('John'));\n        $this->assertNull($store->tags(['people', 'artists'])->get('Jane'));\n    }\n\n    public function testMemcachedCanStoreAndFlushTaggedCacheItems()\n    {\n        $store = Cache::store('memcached');\n\n        $this->assertTrue($store->supportsTags());\n\n        $this->assertNull($store->get('foo'));\n\n        $store->put('foo', 'bar');\n\n        $this->assertSame('bar', $store->get('foo'));\n\n        $this->assertNull($store->tags(['bar'])->get('x'));\n\n        $store->tags(['bar'])->put('x', 'y');\n\n        $this->assertSame('y', $store->tags(['bar'])->get('x'));\n\n        $store->tags(['bar'])->flush();\n\n        $this->assertNull($store->tags(['bar'])->get('x'));\n        $this->assertSame('bar', $store->get('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/MemoizedStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse BadMethodCallException;\nuse Illuminate\\Cache\\Events\\CacheEvent;\nuse Illuminate\\Cache\\Events\\CacheMissed;\nuse Illuminate\\Cache\\Events\\ForgettingKey;\nuse Illuminate\\Cache\\Events\\KeyForgotten;\nuse Illuminate\\Cache\\Events\\KeyWritten;\nuse Illuminate\\Cache\\Events\\RetrievingKey;\nuse Illuminate\\Cache\\Events\\RetrievingManyKeys;\nuse Illuminate\\Cache\\Events\\WritingKey;\nuse Illuminate\\Contracts\\Cache\\Store;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Exceptions;\nuse Illuminate\\Support\\Facades\\Redis;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Throwable;\n\n#[WithConfig('cache.default', 'redis')]\n#[WithConfig('cache.prefix', 'laravel-cache-')]\nclass MemoizedStoreTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            $this->setUpRedis();\n\n            Redis::connection(Config::get('cache.stores.redis.connection'))->flushDb();\n            Redis::connection(Config::get('cache.stores.redis.lock_connection'))->flushDb();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->tearDownRedis();\n        });\n\n        parent::setUp();\n    }\n\n    public function test_it_can_memoize_when_retrieving_single_value()\n    {\n        Cache::put('name', 'Tim', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Tim', $live);\n        $this->assertSame('Tim', $memoized);\n\n        Cache::put('name', 'Taylor', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Taylor', $live);\n        $this->assertSame('Tim', $memoized);\n    }\n\n    public function test_null_values_are_memoized_when_retrieving_single_value()\n    {\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertNull($live);\n        $this->assertNull($memoized);\n\n        Cache::put('name', 'Taylor', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Taylor', $live);\n        $this->assertNull($memoized);\n    }\n\n    public function test_it_can_memoize_when_retrieving_multiple_values()\n    {\n        Cache::put('name.0', 'Tim', 60);\n        Cache::put('name.1', 'Taylor', 60);\n\n        $live = Cache::getMultiple(['name.0', 'name.1']);\n        $memoized = Cache::memo()->getMultiple(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $memoized);\n\n        Cache::put('name.0', 'MacDonald', 60);\n        Cache::put('name.1', 'Otwell', 60);\n\n        $live = Cache::getMultiple(['name.0', 'name.1']);\n        $memoized = Cache::memo()->getMultiple(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Otwell'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $memoized);\n    }\n\n    public function test_it_uses_correct_keys_for_getMultiple()\n    {\n        $data = [\n            'a' => 'string-value',\n            '1.1' => 'float-value',\n            '1' => 'integer-value-as-string',\n            2 => 'integer-value',\n        ];\n        Cache::putMany($data);\n\n        $memoValue = Cache::memo()->many(['a', '1.1', '1', 2]);\n        $cacheValue = Cache::many(['a', '1.1', '1', 2]);\n\n        $this->assertSame([\n            'a' => 'string-value',\n            '1.1' => 'float-value',\n            '1' => 'integer-value-as-string',\n            2 => 'integer-value',\n        ], $cacheValue);\n        $this->assertSame($cacheValue, $memoValue);\n\n        // ensure correct on the second memoized retrieval\n        $memoValue = Cache::memo()->many(['a', '1.1', '1', 2]);\n\n        $this->assertSame($cacheValue, $memoValue);\n    }\n\n    public function test_it_uses_correct_keys_for_getMultiple_with_empty_prefix()\n    {\n        Cache::setPrefix(null);\n\n        $data = [\n            '1' => 'one',\n            0 => 'zero',\n        ];\n        Cache::putMany($data);\n\n        $this->assertSame($data, Cache::memo()->many(array_keys($data)));\n        // ensure correct on the second memoized retrieval\n        $this->assertSame($data, Cache::memo()->many(array_keys($data)));\n    }\n\n    public function test_null_values_are_memoized_when_retrieving_multiple_values()\n    {\n        $live = Cache::getMultiple(['name.0', 'name.1']);\n        $memoized = Cache::memo()->getMultiple(['name.0', 'name.1']);\n        $this->assertSame($live, ['name.0' => null, 'name.1' => null]);\n        $this->assertSame($memoized, ['name.0' => null, 'name.1' => null]);\n\n        Cache::put('name.0', 'MacDonald', 60);\n        Cache::put('name.1', 'Otwell', 60);\n\n        $live = Cache::getMultiple(['name.0', 'name.1']);\n        $memoized = Cache::memo()->getMultiple(['name.0', 'name.1']);\n        $this->assertSame($live, ['name.0' => 'MacDonald', 'name.1' => 'Otwell']);\n        $this->assertSame($memoized, ['name.0' => null, 'name.1' => null]);\n    }\n\n    public function test_it_can_retrieve_already_memoized_and_not_yet_memoized_values_when_retrieving_multiple_values()\n    {\n        Cache::put('name.0', 'Tim', 60);\n        Cache::put('name.1', 'Taylor', 60);\n\n        $live = Cache::get('name.0');\n        $memoized = Cache::memo()->get('name.0');\n        $this->assertSame('Tim', $live);\n        $this->assertSame('Tim', $memoized);\n\n        Cache::put('name.0', 'MacDonald', 60);\n        Cache::put('name.1', 'Otwell', 60);\n\n        $live = Cache::getMultiple(['name.0', 'name.1']);\n        $memoized = Cache::memo()->getMultiple(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Otwell'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Otwell'], $memoized);\n    }\n\n    public function test_put_forgets_memoized_value()\n    {\n        Cache::put(['name.0' => 'Tim', 'name.1' => 'Taylor'], 60);\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $memoized);\n\n        Cache::memo()->put('name.0', 'MacDonald');\n        Cache::memo()->put('name.1', 'Otwell');\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Otwell'], $live);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Otwell'], $memoized);\n    }\n\n    public function test_put_many_forgets_memoized_value()\n    {\n        Cache::memo()->put(['name.0' => 'Tim', 'name.1' => 'Taylor'], 60);\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $memoized);\n\n        Cache::memo()->put(['name.0' => 'MacDonald'], 60);\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Taylor'], $live);\n        $this->assertSame(['name.0' => 'MacDonald', 'name.1' => 'Taylor'], $memoized);\n    }\n\n    public function test_increment_forgets_memoized_value()\n    {\n        Cache::put('count', 1, 60);\n\n        $live = Cache::get('count');\n        $memoized = Cache::memo()->get('count');\n        $this->assertSame('1', $live);\n        $this->assertSame('1', $memoized);\n\n        Cache::memo()->increment('count');\n\n        $live = Cache::get('count');\n        $memoized = Cache::memo()->get('count');\n        $this->assertSame('2', $live);\n        $this->assertSame('2', $memoized);\n    }\n\n    public function test_decrement_forgets_memoized_value()\n    {\n        Cache::put('count', 1, 60);\n\n        $live = Cache::get('count');\n        $memoized = Cache::memo()->get('count');\n        $this->assertSame('1', $live);\n        $this->assertSame('1', $memoized);\n\n        Cache::memo()->decrement('count');\n\n        $live = Cache::get('count');\n        $memoized = Cache::memo()->get('count');\n        $this->assertSame('0', $live);\n        $this->assertSame('0', $memoized);\n    }\n\n    public function test_forever_forgets_memoized_value()\n    {\n        Cache::put('name', 'Tim', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Tim', $live);\n        $this->assertSame('Tim', $memoized);\n\n        Cache::memo()->forever('name', 'Taylor');\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Taylor', $live);\n        $this->assertSame('Taylor', $memoized);\n    }\n\n    public function test_forget_forgets_memoized_value()\n    {\n        Cache::put('name', 'Tim', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Tim', $live);\n        $this->assertSame('Tim', $memoized);\n\n        Cache::memo()->forget('name');\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertNull($live);\n        $this->assertNull($memoized);\n    }\n\n    public function test_flush_forgets_memoized_value()\n    {\n        Cache::put(['name.0' => 'Tim', 'name.1' => 'Taylor'], 60);\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $live);\n        $this->assertSame(['name.0' => 'Tim', 'name.1' => 'Taylor'], $memoized);\n\n        Cache::memo()->flush();\n\n        $live = Cache::get(['name.0', 'name.1']);\n        $memoized = Cache::memo()->get(['name.0', 'name.1']);\n        $this->assertSame(['name.0' => null, 'name.1' => null], $live);\n        $this->assertSame(['name.0' => null, 'name.1' => null], $memoized);\n    }\n\n    public function test_memoized_driver_uses_underlying_drivers_prefix()\n    {\n        $this->assertSame('laravel-cache-', Cache::memo()->getPrefix());\n\n        Cache::driver('redis')->setPrefix('foo');\n\n        $this->assertSame('foo', Cache::memo()->getPrefix());\n    }\n\n    public function test_memoized_keys_are_prefixed()\n    {\n        $redis = Cache::store('redis');\n\n        $redis->setPrefix('aaaa');\n        $redis->put('name', 'Tim', 60);\n        $redis->setPrefix('zzzz');\n        $redis->put('name', 'Taylor', 60);\n\n        $redis->setPrefix('aaaa');\n        $value = Cache::memo('redis')->get('name');\n        $this->assertSame('Tim', $value);\n\n        $redis->setPrefix('zzzz');\n        $value = Cache::memo('redis')->get('name');\n        $this->assertSame('Taylor', $value);\n    }\n\n    public function test_it_dispatches_decorated_driver_events_only()\n    {\n        $redis = Cache::driver('redis');\n        $events = [];\n        Event::listen('*', function ($type, $event) use (&$events) {\n            if ($event[0] instanceof CacheEvent) {\n                $events[] = $event[0];\n            }\n        });\n\n        Cache::memo('redis')->get('name');\n        $this->assertCount(2, $events);\n        $this->assertInstanceOf(RetrievingKey::class, $events[0]);\n        $this->assertSame('redis', $events[0]->storeName);\n        $this->assertSame('name', $events[0]->key);\n        $this->assertInstanceOf(CacheMissed::class, $events[1]);\n        $this->assertSame('redis', $events[1]->storeName);\n        $this->assertSame('name', $events[1]->key);\n        Cache::memo('redis')->get('name');\n        $this->assertCount(2, $events);\n\n        Cache::memo('redis')->many(['name']);\n        $this->assertCount(2, $events);\n\n        Cache::memo('redis')->many(['name.0', 'name.1']);\n        $this->assertCount(5, $events);\n        $this->assertInstanceOf(RetrievingManyKeys::class, $events[2]);\n        $this->assertSame('redis', $events[2]->storeName);\n        $this->assertSame(['name.0', 'name.1'], $events[2]->keys);\n        $this->assertInstanceOf(CacheMissed::class, $events[3]);\n        $this->assertSame('redis', $events[3]->storeName);\n        $this->assertSame('name.0', $events[3]->key);\n        $this->assertInstanceOf(CacheMissed::class, $events[4]);\n        $this->assertSame('redis', $events[4]->storeName);\n        $this->assertSame('name.1', $events[4]->key);\n\n        Cache::memo('redis')->many(['name.0', 'name.1']);\n        $this->assertCount(5, $events);\n\n        Cache::memo('redis')->put('name', 'Tim', 1);\n        $this->assertCount(7, $events);\n        $this->assertInstanceOf(WritingKey::class, $events[5]);\n        $this->assertSame('redis', $events[5]->storeName);\n        $this->assertSame('name', $events[5]->key);\n        $this->assertInstanceOf(KeyWritten::class, $events[6]);\n        $this->assertSame('redis', $events[6]->storeName);\n        $this->assertSame('name', $events[6]->key);\n\n        Cache::memo('redis')->putMany(['name.0' => 'Tim', 'name.1' => 'Taylor']);\n        $this->assertCount(11, $events);\n        $this->assertInstanceOf(WritingKey::class, $events[7]);\n        $this->assertSame('redis', $events[7]->storeName);\n        $this->assertSame('name.0', $events[7]->key);\n        $this->assertInstanceOf(KeyWritten::class, $events[8]);\n        $this->assertSame('redis', $events[8]->storeName);\n        $this->assertSame('name.0', $events[8]->key);\n        $this->assertInstanceOf(WritingKey::class, $events[9]);\n        $this->assertSame('redis', $events[9]->storeName);\n        $this->assertSame('name.1', $events[9]->key);\n        $this->assertInstanceOf(KeyWritten::class, $events[10]);\n        $this->assertSame('redis', $events[10]->storeName);\n        $this->assertSame('name.1', $events[10]->key);\n\n        Cache::memo('redis')->increment('count');\n        $this->assertCount(11, $events);\n\n        Cache::memo('redis')->decrement('count');\n        $this->assertCount(11, $events);\n\n        Cache::memo('redis')->forever('name', 'Taylor');\n        $this->assertCount(13, $events);\n        $this->assertInstanceOf(WritingKey::class, $events[11]);\n        $this->assertSame('redis', $events[11]->storeName);\n        $this->assertSame('name', $events[11]->key);\n        $this->assertInstanceOf(KeyWritten::class, $events[12]);\n        $this->assertSame('redis', $events[12]->storeName);\n        $this->assertSame('name', $events[12]->key);\n\n        Cache::memo('redis')->forget('name');\n        $this->assertCount(15, $events);\n        $this->assertInstanceOf(ForgettingKey::class, $events[13]);\n        $this->assertSame('redis', $events[13]->storeName);\n        $this->assertSame('name', $events[13]->key);\n        $this->assertInstanceOf(KeyForgotten::class, $events[14]);\n        $this->assertSame('redis', $events[14]->storeName);\n        $this->assertSame('name', $events[14]->key);\n\n        Cache::memo('redis')->flush();\n        $this->assertCount(15, $events);\n    }\n\n    public function test_it_resets_cache_store_with_scoped_instances()\n    {\n        Cache::put('name', 'Tim', 60);\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Tim', $live);\n        $this->assertSame('Tim', $memoized);\n\n        Cache::put('name', 'Taylor', 60);\n        $this->app->forgetScopedInstances();\n\n        $live = Cache::get('name');\n        $memoized = Cache::memo()->get('name');\n        $this->assertSame('Taylor', $live);\n        $this->assertSame('Taylor', $memoized);\n    }\n\n    public function test_it_throws_when_underlying_store_does_not_support_locks()\n    {\n        $this->freezeTime();\n        $exceptions = [];\n        Exceptions::reportable(function (Throwable $e) use (&$exceptions) {\n            $exceptions[] = $e;\n        });\n        Config::set('cache.stores.no-lock', ['driver' => 'no-lock']);\n        Cache::extend('no-lock', fn () => Cache::repository(new class implements Store\n        {\n            public function get($key)\n            {\n                return Cache::get(...func_get_args());\n            }\n\n            public function many(array $keys)\n            {\n                return Cache::many(...func_get_args());\n            }\n\n            public function put($key, $value, $seconds)\n            {\n                return Cache::put(...func_get_args());\n            }\n\n            public function putMany(array $values, $seconds)\n            {\n                return Cache::putMany(...func_get_args());\n            }\n\n            public function increment($key, $value = 1)\n            {\n                return Cache::increment(...func_get_args());\n            }\n\n            public function decrement($key, $value = 1)\n            {\n                return Cache::decrement(...func_get_args());\n            }\n\n            public function forever($key, $value)\n            {\n                return Cache::forever(...func_get_args());\n            }\n\n            public function forget($key)\n            {\n                return Cache::forget(...func_get_args());\n            }\n\n            public function touch($key, $seconds)\n            {\n                return Cache::touch(...func_get_args());\n            }\n\n            public function flush()\n            {\n                return Cache::flush(...func_get_args());\n            }\n\n            public function getPrefix()\n            {\n                return Cache::getPrefix(...func_get_args());\n            }\n        }));\n        Cache::flexible('key', [10, 20], 'value-1');\n\n        $this->travel(11)->seconds();\n        Cache::memo('no-lock')->flexible('key', [10, 20], 'value-2');\n        defer()->invoke();\n        $value = Cache::get('key');\n\n        $this->assertCount(1, $exceptions);\n        $this->assertInstanceOf(BadMethodCallException::class, $exceptions[0]);\n        $this->assertSame('This cache store does not support locks.', $exceptions[0]->getMessage());\n    }\n\n    public function test_it_supports_with_flexible()\n    {\n        $this->freezeTime();\n        Cache::flexible('key', [10, 20], 'value-1');\n\n        $this->travel(11)->seconds();\n        Cache::memo()->flexible('key', [10, 20], 'value-2');\n        defer()->invoke();\n        $value = Cache::get('key');\n\n        $this->assertSame('value-2', $value);\n    }\n\n    public function test_it_supports_restore_lock()\n    {\n        $owner = Cache::lock('foo', 10)->owner();\n\n        $restoredLock = Cache::memo()->restoreLock('foo', $owner);\n\n        $this->assertSame($owner, $restoredLock->owner());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/NoLockTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('cache.default', 'null')]\n#[WithConfig('cache.stores.null', ['driver' => 'null'])]\nclass NoLockTest extends TestCase\n{\n    public function testLocksCanAlwaysBeAcquiredAndReleased()\n    {\n        Cache::lock('foo')->forceRelease();\n\n        $lock = Cache::lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertTrue(Cache::lock('foo', 10)->get());\n        $this->assertTrue($lock->release());\n        $this->assertTrue($lock->release());\n    }\n\n    public function testLocksCanBlockForSeconds()\n    {\n        Cache::lock('foo')->forceRelease();\n        $this->assertSame('taylor', Cache::lock('foo', 10)->block(1, function () {\n            return 'taylor';\n        }));\n\n        Cache::lock('foo')->forceRelease();\n        $this->assertTrue(Cache::lock('foo', 10)->block(1));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/PhpRedisBackoffTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\RedisManager;\nuse Illuminate\\Support\\Env;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\nuse Redis;\n\n#[RequiresPhpExtension('redis')]\nclass PhpRedisBackoffTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->setUpRedis();\n\n        $client = $this->redis['phpredis']->connection()->client();\n        if (! $client instanceof Redis) {\n            $this->markTestSkipped('Backoff option is only supported with phpredis in non-cluster mode');\n        }\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('phpRedisBackoffAlgorithmsProvider')]\n    public function testPhpRedisBackoffAlgorithmParsing($friendlyAlgorithmName, $expectedAlgorithm)\n    {\n        $host = Env::get('REDIS_HOST', '127.0.0.1');\n        $port = Env::get('REDIS_PORT', 6379);\n\n        $manager = new RedisManager(new Application(), 'phpredis', [\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'backoff_algorithm' => $friendlyAlgorithmName,\n            ],\n        ]);\n\n        $this->assertEquals(\n            $expectedAlgorithm,\n            $manager->connection()->client()->getOption(Redis::OPT_BACKOFF_ALGORITHM)\n        );\n    }\n\n    #[DataProvider('phpRedisBackoffAlgorithmsProvider')]\n    public function testPhpRedisBackoffAlgorithm($friendlyAlgorithm, $expectedAlgorithm)\n    {\n        $host = Env::get('REDIS_HOST', '127.0.0.1');\n        $port = Env::get('REDIS_PORT', 6379);\n\n        $manager = new RedisManager(new Application(), 'phpredis', [\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'backoff_algorithm' => $expectedAlgorithm,\n            ],\n        ]);\n\n        $this->assertEquals(\n            $expectedAlgorithm,\n            $manager->connection()->client()->getOption(Redis::OPT_BACKOFF_ALGORITHM)\n        );\n    }\n\n    public function testAnInvalidPhpRedisBackoffAlgorithmIsConvertedToDefault()\n    {\n        $host = Env::get('REDIS_HOST', '127.0.0.1');\n        $port = Env::get('REDIS_PORT', 6379);\n\n        $manager = new RedisManager(new Application(), 'phpredis', [\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'backoff_algorithm' => 7,\n            ],\n        ]);\n\n        $this->assertEquals(\n            Redis::BACKOFF_ALGORITHM_DEFAULT,\n            $manager->connection()->client()->getOption(Redis::OPT_BACKOFF_ALGORITHM)\n        );\n    }\n\n    public function testItFailsWithAnInvalidPhpRedisAlgorithm()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Algorithm [foo] is not a valid PhpRedis backoff algorithm');\n\n        $host = Env::get('REDIS_HOST', '127.0.0.1');\n        $port = Env::get('REDIS_PORT', 6379);\n\n        (new RedisManager(new Application(), 'phpredis', [\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'backoff_algorithm' => 'foo',\n            ],\n        ]))->connection();\n    }\n\n    public static function phpRedisBackoffAlgorithmsProvider()\n    {\n        if (! class_exists(Redis::class)) {\n            return [];\n        }\n\n        return [\n            ['default', Redis::BACKOFF_ALGORITHM_DEFAULT],\n            ['decorrelated_jitter', Redis::BACKOFF_ALGORITHM_DECORRELATED_JITTER],\n            ['equal_jitter', Redis::BACKOFF_ALGORITHM_EQUAL_JITTER],\n            ['exponential', Redis::BACKOFF_ALGORITHM_EXPONENTIAL],\n            ['uniform', Redis::BACKOFF_ALGORITHM_UNIFORM],\n            ['constant', Redis::BACKOFF_ALGORITHM_CONSTANT],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/PhpRedisCacheLockTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse Redis;\n\nclass PhpRedisCacheLockTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n\n        $connection = $this->app['redis']->connection();\n        $this->markTestSkippedUnless(\n            $connection instanceof PhpRedisConnection || $connection instanceof PhpRedisClusterConnection,\n            'This test is for phpredis only',\n        );\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testRedisLockCanBeAcquiredAndReleasedWithoutSerializationAndCompression()\n    {\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    public function testRedisLockCanBeAcquiredAndReleasedWithPhpSerialization()\n    {\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    public function testRedisLockCanBeAcquiredAndReleasedWithJsonSerialization()\n    {\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    public function testRedisLockCanBeAcquiredAndReleasedWithIgbinarySerialization()\n    {\n        if (! defined('Redis::SERIALIZER_IGBINARY')) {\n            $this->markTestSkipped('Redis extension is not configured to support the igbinary serializer.');\n        }\n\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    public function testRedisLockCanBeAcquiredAndReleasedWithMsgpackSerialization()\n    {\n        if (! defined('Redis::SERIALIZER_MSGPACK')) {\n            $this->markTestSkipped('Redis extension is not configured to support the msgpack serializer.');\n        }\n\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_MSGPACK);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    #[RequiresPhpExtension('lzf')]\n    public function testRedisLockCanBeAcquiredAndReleasedWithLzfCompression()\n    {\n        if (! defined('Redis::COMPRESSION_LZF')) {\n            $this->markTestSkipped('Redis extension is not configured to support the lzf compression.');\n        }\n\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);\n        $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZF);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    #[RequiresPhpExtension('zstd')]\n    public function testRedisLockCanBeAcquiredAndReleasedWithZstdCompression()\n    {\n        if (! defined('Redis::COMPRESSION_ZSTD')) {\n            $this->markTestSkipped('Redis extension is not configured to support the zstd compression.');\n        }\n\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);\n        $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_ZSTD);\n        $client->setOption(Redis::OPT_COMPRESSION_LEVEL, Redis::COMPRESSION_ZSTD_DEFAULT);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n\n        $client->setOption(Redis::OPT_COMPRESSION_LEVEL, Redis::COMPRESSION_ZSTD_MAX);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    #[RequiresPhpExtension('lz4')]\n    public function testRedisLockCanBeAcquiredAndReleasedWithLz4Compression()\n    {\n        if (! defined('Redis::COMPRESSION_LZ4')) {\n            $this->markTestSkipped('Redis extension is not configured to support the lz4 compression.');\n        }\n\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);\n        $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZ4);\n        $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 1);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n\n        $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 3);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n\n        $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 12);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n\n    #[RequiresPhpExtension('lzf')]\n    public function testRedisLockCanBeAcquiredAndReleasedWithSerializationAndCompression()\n    {\n        if (! defined('Redis::COMPRESSION_LZF')) {\n            $this->markTestSkipped('Redis extension is not configured to support the lzf compression.');\n        }\n\n        $this->app['config']->set('database.redis.client', 'phpredis');\n        $this->app['config']->set('cache.stores.redis.connection', 'default');\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->lockConnection()->client();\n\n        $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);\n        $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZF);\n        $store->lock('foo')->forceRelease();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n        $lock = $store->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse($store->lock('foo', 10)->get());\n        $lock->release();\n        $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/Psr6RedisTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Tests\\Integration\\Cache\\Fixtures\\Unserializable;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass Psr6RedisTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            $this->setUpRedis();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->tearDownRedis();\n        });\n\n        parent::setUp();\n    }\n\n    #[DataProvider('redisClientDataProvider')]\n    public function testTransactionIsNotOpenedWhenSerializationFails($redisClient): void\n    {\n        $this->app['config']['cache.default'] = 'redis';\n        $this->app['config']['database.redis.client'] = $redisClient;\n\n        $cache = $this->app->make('cache.psr6');\n\n        $item = $cache->getItem('foo');\n\n        $item->set(new Unserializable());\n        $item->expiresAfter(60);\n\n        $cache->save($item);\n\n        Cache::store('redis')->get('foo');\n    }\n\n    /**\n     * @return array\n     */\n    public static function redisClientDataProvider(): array\n    {\n        return [\n            ['predis'],\n            ['phpredis'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/RedisCacheFunnelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Support\\Facades\\Cache;\n\nclass RedisCacheFunnelTest extends CacheFunnelTestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n\n        Cache::purge('redis');\n\n        $this->releaseFunnelLocks();\n    }\n\n    protected function cache(): Repository\n    {\n        return Cache::store('redis');\n    }\n\n    protected function tearDown(): void\n    {\n        parent::tearDown();\n\n        $this->tearDownRedis();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/RedisCacheIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RedisStore;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\n\n#[RequiresPhpExtension('redis')]\nclass RedisCacheIntegrationTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testRedisCacheAddTwice($driver)\n    {\n        $store = new RedisStore($this->redis[$driver]);\n        $repository = new Repository($store);\n        $this->assertTrue($repository->add('k', 'v', 3600));\n        $this->assertFalse($repository->add('k', 'v', 3600));\n        $this->assertGreaterThan(3500, $this->redis[$driver]->connection()->ttl('k'));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testRedisCacheRateLimiter($driver)\n    {\n        $store = new RedisStore($this->redis[$driver]);\n        $repository = new Repository($store);\n        $rateLimiter = new RateLimiter($repository);\n\n        $this->assertFalse($rateLimiter->tooManyAttempts('key', 1));\n        $this->assertEquals(1, $rateLimiter->hit('key', 60));\n        $this->assertTrue($rateLimiter->tooManyAttempts('key', 1));\n        $this->assertFalse($rateLimiter->tooManyAttempts('key', 2));\n    }\n\n    /**\n     * Breaking change.\n     *\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testRedisCacheAddFalse($driver)\n    {\n        $store = new RedisStore($this->redis[$driver]);\n        $repository = new Repository($store);\n        $repository->forever('k', false);\n        $this->assertFalse($repository->add('k', 'v', 60));\n        $this->assertEquals(-1, $this->redis[$driver]->connection()->ttl('k'));\n    }\n\n    /**\n     * Breaking change.\n     *\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testRedisCacheAddNull($driver)\n    {\n        $store = new RedisStore($this->redis[$driver]);\n        $repository = new Repository($store);\n        $repository->forever('k', null);\n        $this->assertFalse($repository->add('k', 'v', 60));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/RedisCacheLockTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Exception;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RedisCacheLockTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testRedisLocksCanBeAcquiredAndReleased()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $lock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse(Cache::store('redis')->lock('foo', 10)->get());\n        $lock->release();\n\n        $lock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($lock->get());\n        $this->assertFalse(Cache::store('redis')->lock('foo', 10)->get());\n        Cache::store('redis')->lock('foo')->release();\n    }\n\n    public function testRedisLockCanHaveASeparateConnection()\n    {\n        $this->app['config']->set('cache.stores.redis.lock_connection', 'default');\n\n        $this->assertSame('default', Cache::store('redis')->lock('foo')->getConnectionName());\n    }\n\n    public function testRedisLocksCanBlockForSeconds()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n        $this->assertSame('taylor', Cache::store('redis')->lock('foo', 10)->block(1, function () {\n            return 'taylor';\n        }));\n\n        Cache::store('redis')->lock('foo')->forceRelease();\n        $this->assertTrue(Cache::store('redis')->lock('foo', 10)->block(1));\n    }\n\n    public function testConcurrentRedisLocksAreReleasedSafely()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('redis')->lock('foo', 1);\n        $this->assertTrue($firstLock->get());\n        sleep(2);\n\n        $secondLock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($secondLock->get());\n\n        $firstLock->release();\n\n        $this->assertFalse(Cache::store('redis')->lock('foo')->get());\n    }\n\n    public function testRedisLocksWithFailedBlockCallbackAreReleased()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('redis')->lock('foo', 10);\n\n        try {\n            $firstLock->block(1, function () {\n                throw new Exception('failed');\n            });\n        } catch (Exception) {\n            // Not testing the exception, just testing the lock\n            // is released regardless of the how the exception\n            // thrown by the callback was handled.\n        }\n\n        $secondLock = Cache::store('redis')->lock('foo', 1);\n\n        $this->assertTrue($secondLock->get());\n    }\n\n    public function testRedisLocksCanBeReleasedUsingOwnerToken()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('redis')->restoreLock('foo', $owner);\n        $secondLock->release();\n\n        $this->assertTrue(Cache::store('redis')->lock('foo')->get());\n    }\n\n    public function testOwnerStatusCanBeCheckedAfterRestoringLock()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($firstLock->get());\n        $owner = $firstLock->owner();\n\n        $secondLock = Cache::store('redis')->restoreLock('foo', $owner);\n        $this->assertTrue($secondLock->isOwnedByCurrentProcess());\n    }\n\n    public function testOtherOwnerDoesNotOwnLockAfterRestore()\n    {\n        Cache::store('redis')->lock('foo')->forceRelease();\n\n        $firstLock = Cache::store('redis')->lock('foo', 10);\n        $this->assertTrue($firstLock->isOwnedBy(null));\n        $this->assertTrue($firstLock->get());\n        $this->assertTrue($firstLock->isOwnedBy($firstLock->owner()));\n\n        $secondLock = Cache::store('redis')->restoreLock('foo', 'other_owner');\n        $this->assertTrue($secondLock->isOwnedBy($firstLock->owner()));\n        $this->assertFalse($secondLock->isOwnedByCurrentProcess());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/RedisStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse DateTime;\nuse Illuminate\\Cache\\RedisStore;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Sleep;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse RuntimeException;\n\n#[RequiresPhpExtension('redis')]\nclass RedisStoreTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            $this->setUpRedis();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->tearDownRedis();\n        });\n\n        parent::setUp();\n    }\n\n    public function testCacheTtl(): void\n    {\n        $store = Cache::store('redis');\n        $store->clear();\n\n        while ((microtime(true) - time()) > 0.5 && (microtime(true) - time()) < 0.6) {\n            //\n        }\n\n        $store->put('hello', 'world', 1);\n        $putAt = microtime(true);\n\n        Sleep::for(600)->milliseconds();\n        $this->assertTrue((microtime(true) - $putAt) < 1);\n        $this->assertSame('world', $store->get('hello'));\n\n        // Although this key expires after exactly 1 second, Redis has a\n        // 0-1 millisecond error rate on expiring keys (as of Redis 2.6) so\n        // for a non-flakey test we need to account for the millisecond.\n        // see: https://redis.io/commands/expire/\n        while ((microtime(true) - $putAt) < 1.001) {\n            //\n        }\n\n        $this->assertNull($store->get('hello'));\n    }\n\n    public function testItCanStoreInfinite()\n    {\n        Cache::store('redis')->clear();\n\n        $result = Cache::store('redis')->put('foo', INF);\n        $this->assertTrue($result);\n        $this->assertSame(INF, Cache::store('redis')->get('foo'));\n\n        $result = Cache::store('redis')->put('bar', -INF);\n        $this->assertTrue($result);\n        $this->assertSame(-INF, Cache::store('redis')->get('bar'));\n    }\n\n    public function testItCanStoreNan()\n    {\n        Cache::store('redis')->clear();\n\n        $result = Cache::store('redis')->put('foo', NAN);\n        $this->assertTrue($result);\n        $this->assertNan(Cache::store('redis')->get('foo'));\n    }\n\n    public function testItCanExpireWithZeroTTL()\n    {\n        Cache::store('redis')->clear();\n\n        $result = Cache::store('redis')->put('foo', 10, 10);\n        $this->assertTrue($result);\n\n        $result = Cache::store('redis')->put('foo', 10, 0);\n        $this->assertTrue($result);\n\n        $value = Cache::store('redis')->get('foo');\n        $this->assertNull($value);\n    }\n\n    #[TestWith(['laravel_cache_'])]\n    #[TestWith(['laravel-cache-'])]\n    public function testTagsCanBeAccessed(string $cachePrefix)\n    {\n        config(['cache.prefix' => $cachePrefix]);\n\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['people', 'author'])->put('name', 'Sally', 5);\n        Cache::store('redis')->tags(['people', 'author'])->put('age', 30, 5);\n\n        $this->assertEquals('Sally', Cache::store('redis')->tags(['people', 'author'])->get('name'));\n        $this->assertEquals(30, Cache::store('redis')->tags(['people', 'author'])->get('age'));\n\n        Cache::store('redis')->tags(['people', 'author'])->flush();\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(0, count($keyCount));\n    }\n\n    public function testTagEntriesCanBeStoredForever()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['people', 'author'])->forever('name', 'Sally');\n        Cache::store('redis')->tags(['people', 'author'])->forever('age', 30);\n\n        $this->assertEquals('Sally', Cache::store('redis')->tags(['people', 'author'])->get('name'));\n        $this->assertEquals(30, Cache::store('redis')->tags(['people', 'author'])->get('age'));\n\n        Cache::store('redis')->tags(['people', 'author'])->flush();\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(0, count($keyCount));\n    }\n\n    public function testTagEntriesCanBeIncremented()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['votes'])->put('person-1', 0, 5);\n        Cache::store('redis')->tags(['votes'])->increment('person-1');\n        Cache::store('redis')->tags(['votes'])->increment('person-1');\n\n        $this->assertEquals(2, Cache::store('redis')->tags(['votes'])->get('person-1'));\n\n        Cache::store('redis')->tags(['votes'])->decrement('person-1');\n        Cache::store('redis')->tags(['votes'])->decrement('person-1');\n\n        $this->assertEquals(0, Cache::store('redis')->tags(['votes'])->get('person-1'));\n    }\n\n    public function testIncrementedTagEntriesProperlyTurnStale()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['votes'])->add('person-1', 0, $seconds = 1);\n        Cache::store('redis')->tags(['votes'])->increment('person-1');\n        Cache::store('redis')->tags(['votes'])->increment('person-1');\n\n        sleep(2);\n\n        Cache::store('redis')->tags(['votes'])->flushStale();\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(0, count($keyCount));\n    }\n\n    public function testPastTtlTagEntriesAreNotAdded()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['votes'])->add('person-1', 0, new DateTime('yesterday'));\n\n        $value = Cache::store('redis')->tags(['votes'])->get('person-1');\n        $this->assertNull($value);\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(0, count($keyCount));\n    }\n\n    public function testPutPastTtlTagEntriesProperlyTurnStale()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['votes'])->put('person-1', 0, new DateTime('yesterday'));\n        Cache::store('redis')->tags(['votes'])->flushStale();\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(0, count($keyCount));\n    }\n\n    public function testTagsCanBeFlushedBySingleKey()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['people', 'author'])->put('person-1', 'Sally', 5);\n        Cache::store('redis')->tags(['people', 'artist'])->put('person-2', 'John', 5);\n\n        Cache::store('redis')->tags(['artist'])->flush();\n\n        $this->assertEquals('Sally', Cache::store('redis')->tags(['people', 'author'])->get('person-1'));\n        $this->assertNull(Cache::store('redis')->tags(['people', 'artist'])->get('person-2'));\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(3, count($keyCount)); // Sets for people, authors, and actual entry for Sally\n    }\n\n    public function testStaleEntriesCanBeFlushed()\n    {\n        Cache::store('redis')->clear();\n\n        Cache::store('redis')->tags(['people', 'author'])->put('person-1', 'Sally', 1);\n        Cache::store('redis')->tags(['people', 'artist'])->put('person-2', 'John', 1);\n\n        sleep(2);\n\n        // Add a non-stale entry to people...\n        Cache::store('redis')->tags(['people', 'author'])->put('person-3', 'Jennifer', 5);\n\n        Cache::store('redis')->tags(['people'])->flushStale();\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertEquals(4, count($keyCount)); // Sets for people, authors, and artists + individual entry for Jennifer\n    }\n\n    public function testMultipleItemsCanBeSetAndRetrieved()\n    {\n        $store = Cache::store('redis');\n        $result = $store->put('foo', 'bar', 10);\n        $resultMany = $store->putMany([\n            'fizz' => 'buz',\n            'quz' => 'baz',\n        ], 10);\n        $this->assertTrue($result);\n        $this->assertTrue($resultMany);\n        $this->assertEquals([\n            'foo' => 'bar',\n            'fizz' => 'buz',\n            'quz' => 'baz',\n            'norf' => null,\n        ], $store->many(['foo', 'fizz', 'quz', 'norf']));\n\n        $this->assertEquals([], $store->many([]));\n    }\n\n    public function testPutManyCallsPutWhenClustered()\n    {\n        $store = m::mock(RedisStore::class)->makePartial();\n        $store->expects('connection')->andReturn(m::mock(PhpRedisClusterConnection::class));\n        $store->expects('put')\n            ->twice()\n            ->andReturn(true);\n\n        $store->putMany([\n            'foo' => 'bar',\n            'fizz' => 'buz',\n        ], 10);\n    }\n\n    public function testIncrementWithSerializationEnabled()\n    {\n        $this->markTestSkipped('Test makes no sense anymore. Application must explicitly wrap such code in runClean() when used with serialization/compression enabled.');\n\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        /** @var \\Redis $client */\n        $client = $store->connection()->client();\n        $client->setOption(\\Redis::OPT_SERIALIZER, \\Redis::SERIALIZER_PHP);\n\n        $store->flush();\n        $store->add('foo', 1, 10);\n        $this->assertEquals(1, $store->get('foo'));\n\n        $store->increment('foo');\n        $this->assertEquals(2, $store->get('foo'));\n    }\n\n    public function testTagsCanBeFlushedWithLargeNumberOfKeys()\n    {\n        Cache::store('redis')->clear();\n\n        $tags = ['large-test-'.time()];\n\n        for ($i = 1; $i <= 5000; $i++) {\n            Cache::store('redis')->tags($tags)->put(\"key:{$i}\", \"value:{$i}\", 300);\n        }\n\n        $this->assertEquals('value:1', Cache::store('redis')->tags($tags)->get('key:1'));\n        $this->assertEquals('value:2500', Cache::store('redis')->tags($tags)->get('key:2500'));\n        $this->assertEquals('value:5000', Cache::store('redis')->tags($tags)->get('key:5000'));\n\n        Cache::store('redis')->tags($tags)->flush();\n\n        $this->assertNull(Cache::store('redis')->tags($tags)->get('key:1'));\n        $this->assertNull(Cache::store('redis')->tags($tags)->get('key:2500'));\n        $this->assertNull(Cache::store('redis')->tags($tags)->get('key:5000'));\n\n        $keyCount = Cache::store('redis')->connection()->keys('*');\n        $this->assertCount(0, $keyCount);\n    }\n\n    public function testLocksCanBeFlushed()\n    {\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        if (! $store->hasSeparateLockStore()) {\n            $this->markTestSkipped('A separate Redis lock connection is required to test flushing locks.');\n        }\n        $store->flush();\n\n        $store->lock('lock-1', 60)->acquire();\n        $store->lock('lock-2', 60)->acquire();\n        $store->lock('lock-3', 60)->acquire();\n\n        $this->assertTrue($store->flushLocks());\n\n        $this->assertTrue($store->lock('lock-1', 60)->acquire());\n        $this->assertTrue($store->lock('lock-2', 60)->acquire());\n        $this->assertTrue($store->lock('lock-3', 60)->acquire());\n    }\n\n    public function testFlushLocksDoesNotAffectNonLockKeys()\n    {\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        if (! $store->hasSeparateLockStore()) {\n            $this->markTestSkipped('A separate Redis lock connection is required to test flushing locks.');\n        }\n        $store->flush();\n\n        $store->put('foo', 'bar', 60);\n        $store->lock('lock-1', 60)->acquire();\n\n        $store->flushLocks();\n\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testHasSeparateLockStoreReturnsTrueWhenLockConnectionDiffers()\n    {\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        if (! $store->hasSeparateLockStore()) {\n            $this->markTestSkipped('A separate Redis lock connection is required to test flushing locks.');\n        }\n\n        $this->assertTrue($store->hasSeparateLockStore());\n    }\n\n    public function testHasSeparateLockStoreReturnsFalseWhenLockConnectionIsSame()\n    {\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        $store->setConnection('default');\n        $store->setLockConnection('default');\n\n        $this->assertFalse($store->hasSeparateLockStore());\n    }\n\n    public function testFlushLocksThrowsExceptionWhenLockConnectionIsSame()\n    {\n        /** @var \\Illuminate\\Cache\\RedisStore $store */\n        $store = Cache::store('redis');\n        $store->setConnection('default');\n        $store->setLockConnection('default');\n\n        $this->expectException(RuntimeException::class);\n\n        $store->flushLocks();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cache/RepositoryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cache;\n\nuse Illuminate\\Cache\\Events\\KeyWritten;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration('cache')]\nclass RepositoryTest extends TestCase\n{\n    use LazilyRefreshDatabase;\n\n    public function testStaleWhileRevalidate(): void\n    {\n        Carbon::setTestNow('2000-01-01 00:00:00');\n        $cache = Cache::driver('array');\n        $count = 0;\n\n        // Cache is empty. The value should be populated...\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n\n        $this->assertSame(1, $value);\n        $this->assertCount(0, defer());\n        $this->assertSame(1, $cache->get('foo'));\n        $this->assertSame(946684800, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // Cache is fresh. The value should be retrieved from the cache and used...\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(1, $value);\n        $this->assertCount(0, defer());\n        $this->assertSame(1, $cache->get('foo'));\n        $this->assertSame(946684800, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(11));\n\n        // Cache is now \"stale\". The stored value should be used and a deferred\n        // callback should be registered to refresh the cache.\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(1, $value);\n        $this->assertCount(1, defer());\n        $this->assertSame(1, $cache->get('foo'));\n        $this->assertSame(946684800, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // We will hit it again within the same request. This should not queue\n        // up an additional deferred callback as only one can be registered at\n        // a time for each key.\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(1, $value);\n        $this->assertCount(1, defer());\n        $this->assertSame(1, $cache->get('foo'));\n        $this->assertSame(946684800, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // We will now simulate the end of the request lifecycle by executing the\n        // deferred callback. This should refresh the cache.\n        defer()->invoke();\n        $this->assertCount(0, defer());\n        $this->assertSame(2, $cache->get('foo')); // this has been updated!\n        $this->assertSame(946684811, $cache->get('illuminate:cache:flexible:created:foo')); // this has been updated!\n\n        // Now the cache is fresh again...\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(2, $value);\n        $this->assertCount(0, defer());\n        $this->assertSame(2, $cache->get('foo'));\n        $this->assertSame(946684811, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // Let's now progress time beyond the stale TTL...\n        Carbon::setTestNow(Carbon::now()->addSeconds(21));\n\n        // Now the values should have left the cache. We should refresh.\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(3, $value);\n        $this->assertCount(0, defer());\n        $this->assertSame(3, $cache->get('foo'));\n        $this->assertSame(946684832, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // Now lets see what happens when another request, job, or command is\n        // also trying to refresh the same key at the same time. Will push past\n        // the \"fresh\" TTL and register a deferred callback.\n        Carbon::setTestNow(Carbon::now()->addSeconds(11));\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(3, $value);\n        $this->assertCount(1, defer());\n        $this->assertSame(3, $cache->get('foo'));\n        $this->assertSame(946684832, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // Now we will execute the deferred callback but we will first acquire\n        // our own lock. This means that the value should not be refreshed by\n        // deferred callback.\n        /** @var Lock */\n        $lock = $cache->lock('illuminate:cache:flexible:lock:foo');\n\n        $this->assertTrue($lock->acquire());\n        defer()->first()();\n        $this->assertSame(3, $value);\n        $this->assertCount(1, defer());\n        $this->assertSame(3, $cache->get('foo'));\n        $this->assertSame(946684832, $cache->get('illuminate:cache:flexible:created:foo'));\n        $this->assertTrue($lock->release());\n\n        // Now we have cleared the lock we will, one last time, confirm that\n        // the deferred callback does refresh the value when the lock is not active.\n        defer()->invoke();\n        $this->assertCount(0, defer());\n        $this->assertSame(4, $cache->get('foo'));\n        $this->assertSame(946684843, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // The last thing is to check that we don't refresh the cache in the\n        // deferred callback if another thread has already done the work for us.\n        // We will make the cache stale...\n        Carbon::setTestNow(Carbon::now()->addSeconds(11));\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(4, $value);\n        $this->assertCount(1, defer());\n        $this->assertSame(4, $cache->get('foo'));\n        $this->assertSame(946684843, $cache->get('illuminate:cache:flexible:created:foo'));\n\n        // There is now a deferred callback ready to refresh the cache. We will\n        // simulate another thread updating the value.\n        $cache->putMany([\n            'foo' => 99,\n            'illuminate:cache:flexible:created:foo' => 946684863,\n        ]);\n\n        // then we will run the refresh callback\n        defer()->invoke();\n        $value = $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        });\n        $this->assertSame(99, $value);\n        $this->assertCount(0, defer());\n        $this->assertSame(99, $cache->get('foo'));\n        $this->assertSame(946684863, $cache->get('illuminate:cache:flexible:created:foo'));\n    }\n\n    public function testItHandlesStrayTtlKeyAfterMainKeyIsForgotten()\n    {\n        $cache = Cache::driver('array');\n        $count = 0;\n\n        $value = $cache->flexible('count', [5, 10], function () use (&$count) {\n            $count = 1;\n\n            return $count;\n        });\n\n        $this->assertSame(1, $value);\n        $this->assertSame(1, $count);\n\n        $cache->forget('count');\n\n        $value = $cache->flexible('count', [5, 10], function () use (&$count) {\n            $count = 2;\n\n            return $count;\n        });\n        $this->assertSame(2, $value);\n        $this->assertSame(2, $count);\n    }\n\n    public function testItImplicitlyClearsTtlKeysFromDatabaseCache()\n    {\n        $this->freezeTime();\n        $cache = Cache::driver('database');\n\n        $cache->flexible('count', [5, 10], fn () => 1);\n\n        $this->assertTrue($cache->has('count'));\n        $this->assertTrue($cache->has('illuminate:cache:flexible:created:count'));\n\n        $cache->forget('count');\n\n        $this->assertEmpty($cache->getConnection()->table('cache')->get());\n        $this->assertTrue($cache->missing('count'));\n        $this->assertTrue($cache->missing('illuminate:cache:flexible:created:count'));\n\n        $cache->flexible('count', [5, 10], fn () => 1);\n\n        $this->assertTrue($cache->has('count'));\n        $this->assertTrue($cache->has('illuminate:cache:flexible:created:count'));\n\n        $this->travel(20)->seconds();\n        $cache->forgetIfExpired('count');\n\n        $this->assertEmpty($cache->getConnection()->table('cache')->get());\n        $this->assertTrue($cache->missing('count'));\n        $this->assertTrue($cache->missing('illuminate:cache:flexible:created:count'));\n    }\n\n    public function testItImplicitlyClearsTtlKeysFromFileDriver()\n    {\n        $this->freezeTime();\n        $cache = Cache::driver('file');\n\n        $cache->flexible('count', [5, 10], fn () => 1);\n\n        $this->assertTrue($cache->has('count'));\n        $this->assertTrue($cache->has('illuminate:cache:flexible:created:count'));\n\n        $cache->forget('count');\n\n        $this->assertFalse($cache->getFilesystem()->exists($cache->path('count')));\n        $this->assertFalse($cache->getFilesystem()->exists($cache->path('illuminate:cache:flexible:created:count')));\n        $this->assertTrue($cache->missing('count'));\n        $this->assertTrue($cache->missing('illuminate:cache:flexible:created:count'));\n\n        $cache->flexible('count', [5, 10], fn () => 1);\n\n        $this->assertTrue($cache->has('count'));\n        $this->assertTrue($cache->has('illuminate:cache:flexible:created:count'));\n\n        $this->travel(20)->seconds();\n\n        $this->assertTrue($cache->missing('count'));\n        $this->assertFalse($cache->getFilesystem()->exists($cache->path('count')));\n        $this->assertFalse($cache->getFilesystem()->exists($cache->path('illuminate:cache:flexible:created:count')));\n        $this->assertTrue($cache->missing('illuminate:cache:flexible:created:count'));\n    }\n\n    public function testItCanAlwaysDefer()\n    {\n        $this->freezeTime();\n        $cache = Cache::driver('array');\n        $count = 0;\n\n        // Cache is empty. The value should be populated...\n        $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        }, alwaysDefer: true);\n\n        // First call to flexible() should not defer\n        $this->assertCount(0, defer());\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(11));\n\n        // Second callback should defer with always now true\n        $cache->flexible('foo', [10, 20], function () use (&$count) {\n            return ++$count;\n        }, alwaysDefer: true);\n\n        $this->assertCount(1, defer());\n        $this->assertTrue(defer()->first()->always);\n    }\n\n    public function testItRoundsDateTimeValuesToAccountForTimePassedDuringScriptExecution()\n    {\n        // do not freeze time as this test depends on time progressing duration execution.\n        $cache = Cache::driver('array');\n        $events = [];\n        Event::listen(function (KeyWritten $event) use (&$events) {\n            $events[] = $event;\n        });\n\n        $result = $cache->put('foo', 'bar', Carbon::now()->addSecond());\n\n        $this->assertTrue($result);\n        $this->assertCount(1, $events);\n        $this->assertSame('foo', $events[0]->key);\n        $this->assertSame(1, $events[0]->seconds);\n    }\n\n    public function testWorksWithEnumKey()\n    {\n        $cache = Cache::driver('array');\n\n        // put / get / has / missing\n        $cache->put(TestCacheKey::FOO, 'value');\n        $this->assertSame('value', $cache->get(TestCacheKey::FOO));\n        $this->assertSame(['foo' => 'value', 'bar' => null], $cache->get([TestCacheKey::FOO, TestCacheKey::BAR]));\n        $this->assertTrue($cache->has(TestCacheKey::FOO));\n        $this->assertFalse($cache->missing(TestCacheKey::FOO));\n\n        // pull\n        $this->assertSame('value', $cache->pull(TestCacheKey::FOO));\n        $this->assertNull($cache->get(TestCacheKey::FOO));\n\n        // add\n        $this->assertTrue($cache->add(TestCacheKey::FOO, 'added', 3600));\n        $this->assertFalse($cache->add(TestCacheKey::FOO, 'duplicate', 3600));\n        $this->assertSame('added', $cache->get(TestCacheKey::FOO));\n\n        // forever\n        $cache->forever(TestCacheKey::BAR, 'forever');\n        $this->assertSame('forever', $cache->get(TestCacheKey::BAR));\n\n        // remember / rememberForever / sear\n        $this->assertSame('remember', $cache->remember(TestCacheKey::BAZ, 3600, fn () => 'remember'));\n        $this->assertSame('forever', $cache->rememberForever(TestCacheKey::QUX, fn () => 'forever'));\n        $this->assertSame('forever', $cache->sear(TestCacheKey::QUX, fn () => 'ignored'));\n\n        // increment / decrement\n        $cache->put(TestCacheKey::FOO, 5);\n        $this->assertSame(6, $cache->increment(TestCacheKey::FOO));\n        $this->assertSame(5, $cache->decrement(TestCacheKey::FOO));\n\n        // forget\n        $cache->put(TestCacheKey::FOO, 'x');\n        $this->assertTrue($cache->forget(TestCacheKey::FOO));\n        $this->assertNull($cache->get(TestCacheKey::FOO));\n\n        // flexible / withoutOverlapping\n        $this->assertSame('flexible', $cache->flexible(TestCacheKey::FOO, [5, 10], fn () => 'flexible'));\n        $this->assertSame('overlapping', $cache->withoutOverlapping(TestCacheKey::FOO, fn () => 'overlapping'));\n\n        // many / getMultiple\n        $cache->clear();\n        $this->assertSame(['foo' => null, 'bar' => null, 'baz' => null], $cache->many([TestCacheKey::FOO, TestCacheKey::BAR, TestCacheKey::BAZ]));\n        $this->assertSame(['foo' => 'default', 'qux' => 'default'], $cache->getMultiple([TestCacheKey::FOO, TestCacheKey::QUX], 'default'));\n    }\n}\n\nenum TestCacheKey: string\n{\n    case FOO = 'foo';\n    case BAR = 'bar';\n    case BAZ = 'baz';\n    case QUX = 'qux';\n}\n"
  },
  {
    "path": "tests/Integration/Concurrency/ConcurrencyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Concurrency;\n\nuse Exception;\nuse Illuminate\\Concurrency\\ProcessDriver;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Process\\Factory as ProcessFactory;\nuse Illuminate\\Support\\Facades\\Concurrency;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\n\n#[RequiresOperatingSystem('Linux|DAR')]\nclass ConcurrencyTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->defineCacheRoutes(<<<PHP\n<?php\nuse Illuminate\\Support\\Facades\\Concurrency;\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::any('/concurrency', function () {\n    return Concurrency::run([\n        fn () => 1 + 1,\n        fn () => 2 + 2,\n    ]);\n});\nPHP);\n\n        parent::setUp();\n    }\n\n    public function testWorkCanBeDistributed()\n    {\n        $response = $this->get('concurrency')\n            ->assertOk();\n\n        [$first, $second] = $response->original;\n\n        $this->assertEquals(2, $first);\n        $this->assertEquals(4, $second);\n    }\n\n    public function testRunHandlerProcessErrorCode()\n    {\n        $this->expectException(Exception::class);\n        $app = new Application(__DIR__);\n        $processDriver = new ProcessDriver($app->make(ProcessFactory::class));\n        $processDriver->run([\n            fn () => exit(1),\n        ]);\n    }\n\n    public function testOutputIsMappedToArrayInput()\n    {\n        $input = [\n            'first' => fn () => 1 + 1,\n            'second' => fn () => 2 + 2,\n        ];\n\n        $processOutput = Concurrency::driver('process')->run($input);\n\n        $this->assertIsArray($processOutput);\n        $this->assertArrayHasKey('first', $processOutput);\n        $this->assertArrayHasKey('second', $processOutput);\n\n        $syncOutput = Concurrency::driver('sync')->run($input);\n\n        $this->assertIsArray($syncOutput);\n        $this->assertArrayHasKey('first', $syncOutput);\n        $this->assertArrayHasKey('second', $syncOutput);\n\n        /** As of now, the spatie/fork package is not included by default.\n         * $forkOutput = Concurrency::driver('fork')->run([\n         * 'first' => fn() => 1 + 1,\n         * 'second' => fn() => 2 + 2,\n         * ]);.\n         *\n         * $this->assertIsArray($forkOutput);\n         * $this->assertArrayHasKey('first', $forkOutput);\n         * $this->assertArrayHasKey('second', $forkOutput);\n         * $this->assertEquals(2, $forkOutput['first']);\n         * $this->assertEquals(4, $forkOutput['second']);\n         */\n    }\n\n    public function testRunHandlerProcessErrorWithDefaultExceptionWithoutParam()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('This is a different exception');\n\n        Concurrency::run([\n            fn () => throw new Exception(\n                'This is a different exception',\n            ),\n        ]);\n    }\n\n    public function testRunHandlerProcessErrorWithCustomExceptionWithoutParam()\n    {\n        $this->expectException(ExceptionWithoutParam::class);\n        $this->expectExceptionMessage('Test');\n        Concurrency::run([\n            fn () => throw new ExceptionWithoutParam('Test'),\n        ]);\n    }\n\n    public function testRunHandlerProcessErrorWithCustomExceptionWithParam()\n    {\n        $this->expectException(ExceptionWithParam::class);\n        $this->expectExceptionMessage('API request to https://api.example.com failed with status 400 Bad Request');\n        Concurrency::run([\n            fn () => throw new ExceptionWithParam(\n                'https://api.example.com',\n                400,\n                'Bad Request',\n                'Invalid payload'\n            ),\n        ]);\n    }\n\n    public static function getConcurrencyDrivers(): array\n    {\n        return [\n            ['sync'],\n            ['process'],\n            // spatie/fork package is not included by default\n            // ['fork'],\n        ];\n    }\n\n    #[DataProvider('getConcurrencyDrivers')]\n    public function testRunPreservesCallbackOrder(string $driver)\n    {\n        [$first, $second, $third] = Concurrency::driver($driver)->run([\n            function () {\n                usleep(1000000);\n\n                return 'first';\n            },\n            function () {\n                usleep(500000);\n\n                return 'second';\n            },\n            function () {\n                usleep(200000);\n\n                return 'third';\n            },\n        ]);\n\n        $this->assertEquals('first', $first);\n        $this->assertEquals('second', $second);\n        $this->assertEquals('third', $third);\n    }\n}\n\nclass ExceptionWithoutParam extends Exception\n{\n}\n\nclass ExceptionWithParam extends Exception\n{\n    public function __construct(\n        public string $uri,\n        public int $statusCode,\n        public string $reason,\n        public string|array $responseBody = '',\n    ) {\n        parent::__construct(\"API request to {$uri} failed with status $statusCode $reason\");\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Concurrency/Console/InvokeSerializedClosureCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Concurrency\\Console;\n\nuse Illuminate\\Concurrency\\Console\\InvokeSerializedClosureCommand;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nclass CustomParameterException extends RuntimeException\n{\n    public function __construct(\n        public string $customParam,\n        string $message = '',\n    ) {\n        parent::__construct($message ?: \"Exception with param: {$customParam}\");\n    }\n}\n\nclass InvokeSerializedClosureCommandTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->app[Kernel::class]->registerCommand(new InvokeSerializedClosureCommand);\n    }\n\n    public function testItCanInvokeSerializedClosureFromArgument()\n    {\n        // Create a simple closure and serialize it\n        $closure = fn () => 'Hello, World!';\n        $serialized = serialize(new SerializableClosure($closure));\n\n        // Create a new output buffer\n        $output = new BufferedOutput;\n\n        // Call the command with the serialized closure\n        Artisan::call('invoke-serialized-closure', [\n            'code' => $serialized,\n        ], $output);\n\n        // Get the output and decode it\n        $result = json_decode($output->fetch(), true);\n\n        // Verify the result\n        $this->assertTrue($result['successful']);\n        $this->assertEquals('Hello, World!', unserialize($result['result']));\n    }\n\n    public function testItCanInvokeSerializedClosureFromEnvironment()\n    {\n        // Create a simple closure and serialize it\n        $closure = fn () => 'From Environment';\n        $serialized = serialize(new SerializableClosure($closure));\n\n        // Set the environment variable\n        $_SERVER['LARAVEL_INVOKABLE_CLOSURE'] = base64_encode($serialized);\n\n        // Create a new output buffer\n        $output = new BufferedOutput;\n\n        // Call the command without arguments\n        Artisan::call('invoke-serialized-closure', [], $output);\n\n        // Get the output and decode it\n        $result = json_decode($output->fetch(), true);\n\n        // Verify the result\n        $this->assertTrue($result['successful']);\n        $this->assertEquals('From Environment', unserialize($result['result']));\n\n        // Clean up\n        unset($_SERVER['LARAVEL_INVOKABLE_CLOSURE']);\n    }\n\n    public function testItReturnsNullWhenNoClosureIsProvided()\n    {\n        // Create a new output buffer\n        $output = new BufferedOutput;\n\n        // Call the command without arguments\n        Artisan::call('invoke-serialized-closure', [], $output);\n\n        // Get the output and decode it\n        $result = json_decode($output->fetch(), true);\n\n        // Verify the result\n        $this->assertTrue($result['successful']);\n        $this->assertNull(unserialize($result['result']));\n    }\n\n    public function testItHandlesExceptionsGracefully()\n    {\n        // Create a closure that throws an exception\n        $closure = fn () => throw new RuntimeException('Test exception');\n        $serialized = serialize(new SerializableClosure($closure));\n\n        // Create a new output buffer\n        $output = new BufferedOutput;\n\n        // Call the command with the serialized closure\n        Artisan::call('invoke-serialized-closure', [\n            'code' => $serialized,\n        ], $output);\n\n        // Get the output and decode it\n        $result = json_decode($output->fetch(), true);\n\n        // Verify the exception was caught\n        $this->assertFalse($result['successful']);\n        $this->assertEquals('RuntimeException', $result['exception']);\n        $this->assertEquals('Test exception', $result['message']);\n    }\n\n    public function testItHandlesCustomExceptionWithParameters()\n    {\n        // Create a closure that throws an exception with parameters\n        $closure = fn () => throw new CustomParameterException('Test param');\n        $serialized = serialize(new SerializableClosure($closure));\n\n        // Create a new output buffer\n        $output = new BufferedOutput;\n\n        // Call the command with the serialized closure\n        Artisan::call('invoke-serialized-closure', [\n            'code' => $serialized,\n        ], $output);\n\n        // Get the output and decode it\n        $result = json_decode($output->fetch(), true);\n\n        // Verify the exception was caught and parameters were captured\n        $this->assertFalse($result['successful']);\n        $this->assertArrayHasKey('parameters', $result);\n        $this->assertEquals('Test param', $result['parameters']['customParam'] ?? null);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CallCommandsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Foundation\\Console\\ViewClearCommand;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\nclass CallCommandsTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            Artisan::command('test:a', function () {\n                $this->call('view:clear');\n            });\n\n            Artisan::command('test:b', function () {\n                $this->call(ViewClearCommand::class);\n            });\n\n            Artisan::command('test:c', function () {\n                $this->call($this->laravel->make(ViewClearCommand::class));\n            });\n        });\n\n        parent::setUp();\n    }\n\n    #[TestWith(['test:a'])]\n    #[TestWith(['test:b'])]\n    #[TestWith(['test:c'])]\n    public function testItCanCallCommands(string $command): void\n    {\n        $this->artisan($command)->assertSuccessful();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CallbackSchedulingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Console\\Events\\ScheduledTaskFailed;\nuse Illuminate\\Console\\Scheduling\\CacheEventMutex;\nuse Illuminate\\Console\\Scheduling\\CacheSchedulingMutex;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Console\\Scheduling\\SchedulingMutex;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Factory;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass CallbackSchedulingTest extends TestCase\n{\n    protected $log = [];\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $cache = new class implements Factory\n        {\n            public $store;\n\n            public function __construct()\n            {\n                $this->store = new Repository(new ArrayStore(true));\n            }\n\n            public function store($name = null)\n            {\n                return $this->store;\n            }\n        };\n\n        $container = Container::getInstance();\n\n        $container->instance(EventMutex::class, new CacheEventMutex($cache));\n        $container->instance(SchedulingMutex::class, new CacheSchedulingMutex($cache));\n    }\n\n    public function testExecutionOrder(): void\n    {\n        $event = $this->app->make(Schedule::class)\n            ->call($this->logger('call'))\n            ->after($this->logger('after 1'))\n            ->before($this->logger('before 1'))\n            ->after($this->logger('after 2'))\n            ->before($this->logger('before 2'));\n\n        $this->artisan('schedule:run');\n\n        $this->assertLogged('before 1', 'before 2', 'call', 'after 1', 'after 2');\n    }\n\n    public function testCallbacksCannotRunInBackground(): void\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app->make(Schedule::class)\n            ->call($this->logger('call'))\n            ->runInBackground();\n    }\n\n    public function testExceptionHandlingInCallback(): void\n    {\n        $event = $this->app->make(Schedule::class)\n            ->call($this->logger('call'))\n            ->name('test-event')\n            ->withoutOverlapping();\n\n        // Set up \"before\" and \"after\" hooks to ensure they're called\n        $event->before($this->logger('before'))->after($this->logger('after'));\n\n        // Register a hook to validate that the mutex was initially created\n        $mutexWasCreated = false;\n        $event->before(function () use (&$mutexWasCreated, $event) {\n            $mutexWasCreated = $event->mutex->exists($event);\n        });\n\n        // We'll trigger an exception in an \"after\" hook to test exception handling\n        $event->after(function () {\n            throw new RuntimeException;\n        });\n\n        // Because exceptions are caught by the ScheduleRunCommand, we need to listen for\n        // the \"failed\" event to check whether our exception was actually thrown\n        $failed = false;\n        $this->app->make(Dispatcher::class)\n            ->listen(ScheduledTaskFailed::class, function (ScheduledTaskFailed $failure) use (&$failed, $event) {\n                if ($failure->task === $event) {\n                    $failed = true;\n                }\n            });\n\n        $this->artisan('schedule:run');\n\n        // Hooks and execution should happen in correct order\n        $this->assertLogged('before', 'call', 'after');\n\n        // Our exception should have resulted in a failure event\n        $this->assertTrue($failed);\n\n        // Validate that the mutex was originally created, but that it's since\n        // been removed (even though an exception was thrown)\n        $this->assertTrue($mutexWasCreated);\n        $this->assertFalse($event->mutex->exists($event));\n    }\n\n    protected function logger($message)\n    {\n        return function () use ($message) {\n            $this->log[] = $message;\n        };\n    }\n\n    protected function assertLogged(...$message)\n    {\n        $this->assertEquals($message, $this->log);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CommandDurationThresholdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Config;\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\Console\\Input\\StringInput;\nuse Symfony\\Component\\Console\\Output\\ConsoleOutput;\n\nclass CommandDurationThresholdTest extends TestCase\n{\n    public function testItCanHandleExceedingCommandDuration(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $called = false;\n        $kernel->whenCommandLifecycleIsLongerThan(CarbonInterval::seconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($input, new ConsoleOutput);\n\n        $this->assertFalse($called);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMilliseconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertTrue($called);\n    }\n\n    public function testItDoesntCallWhenExactlyThresholdDuration(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $called = false;\n        $kernel->whenCommandLifecycleIsLongerThan(CarbonInterval::seconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($input, new ConsoleOutput);\n\n        $this->assertFalse($called);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItProvidesArgsToHandler(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $args = null;\n        $kernel->whenCommandLifecycleIsLongerThan(CarbonInterval::seconds(0), function () use (&$args) {\n            $args = func_get_args();\n        });\n\n        Carbon::setTestNow($startedAt = Carbon::now());\n        $kernel->handle($input, new ConsoleOutput);\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertCount(3, $args);\n        $this->assertTrue($startedAt->eq($args[0]));\n        $this->assertSame($input, $args[1]);\n        $this->assertSame(21, $args[2]);\n    }\n\n    public function testItCanExceedThresholdWhenSpecifyingDurationAsMilliseconds(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $called = false;\n        $kernel->whenCommandLifecycleIsLongerThan(1000, function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($input, new ConsoleOutput);\n\n        $this->assertFalse($called);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMilliseconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertTrue($called);\n    }\n\n    public function testItCanStayUnderThresholdWhenSpecifyingDurationAsMilliseconds(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $called = false;\n        $kernel->whenCommandLifecycleIsLongerThan(1000, function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($input, new ConsoleOutput);\n\n        $this->assertFalse($called);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItCanExceedThresholdWhenSpecifyingDurationAsDateTime(): void\n    {\n        retry(2, function () {\n            Carbon::setTestNow(Carbon::now());\n\n            $input = new StringInput('foo');\n            $called = false;\n\n            $kernel = $this->app[Kernel::class];\n            $kernel->command('foo', fn () => null);\n            $kernel->whenCommandLifecycleIsLongerThan(Carbon::now()->addSecond()->addMillisecond(), function () use (&$called) {\n                $called = true;\n            });\n\n            $kernel->handle($input, new ConsoleOutput);\n\n            $this->assertFalse($called);\n\n            Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMillisecond());\n\n            $kernel->terminate($input, 21);\n\n            $this->assertTrue($called);\n        }, 500);\n    }\n\n    public function testItCanStayUnderThresholdWhenSpecifyingDurationAsDateTime(): void\n    {\n        Carbon::setTestNow(Carbon::now());\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n        $called = false;\n        $kernel->whenCommandLifecycleIsLongerThan(Carbon::now()->addSecond()->addMillisecond(), function () use (&$called) {\n            $called = true;\n        });\n\n        $kernel->handle($input, new ConsoleOutput);\n\n        $this->assertFalse($called);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($input, 21);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItClearsStartTimeAfterHandlingCommand(): void\n    {\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $input = new StringInput('foo');\n\n        $this->assertNull($kernel->commandStartedAt());\n\n        $kernel->handle($input, new ConsoleOutput);\n        $this->assertNotNull($kernel->commandStartedAt());\n\n        $kernel->terminate($input, 21);\n        $this->assertNull($kernel->commandStartedAt());\n    }\n\n    public function testUsesTheConfiguredDateTimezone(): void\n    {\n        Config::set('app.timezone', 'UTC');\n        $startedAt = null;\n        $kernel = $this->app[Kernel::class];\n        $kernel->command('foo', fn () => null);\n        $kernel->whenCommandLifecycleIsLongerThan(0, function ($started) use (&$startedAt) {\n            $startedAt = $started;\n        });\n\n        Config::set('app.timezone', 'Australia/Melbourne');\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($input = new StringInput('foo'), new ConsoleOutput);\n\n        Carbon::setTestNow(Carbon::now()->addMinute());\n        $kernel->terminate($input, 21);\n\n        $this->assertSame('Australia/Melbourne', $startedAt->timezone->getName());\n    }\n\n    public function testItHandlesCallingTerminateWithoutHandle(): void\n    {\n        $this->app[Kernel::class]->terminate(new StringInput('foo'), 21);\n\n        // this is a placeholder just to show that the above did not throw an exception.\n        $this->assertTrue(true);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CommandEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Events\\CommandFinished;\nuse Illuminate\\Console\\Events\\CommandStarting;\nuse Illuminate\\Contracts\\Console\\Kernel as ConsoleKernel;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Testing\\WithConsoleEvents;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Foundation\\Application as Testbench;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass CommandEventsTest extends TestCase\n{\n    use WithConsoleEvents;\n\n    /**\n     * The path to the file that execution logs will be written to.\n     *\n     * @var string\n     */\n    protected $logfile;\n\n    /**\n     * The Filesystem instance for writing stubs and logs.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $files;\n\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            $this->files = new Filesystem;\n            $this->logfile = storage_path(sprintf('logs/command_events_test_%s.log', (string) Str::random()));\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->files->delete($this->logfile);\n\n            unset($this->files);\n            unset($this->logfile);\n        });\n\n        parent::setUp();\n    }\n\n    #[DataProvider('foregroundCommandEventsProvider')]\n    public function testCommandEventsReceiveParsedInput($callback): void\n    {\n        $this->app[ConsoleKernel::class]->registerCommand(new CommandEventsTestCommand);\n        $this->app[Dispatcher::class]->listen(function (CommandStarting $event) {\n            array_map(fn ($e) => $this->files->append($this->logfile, $e.PHP_EOL), [\n                'CommandStarting',\n                $event->input->getArgument('firstname'),\n                $event->input->getArgument('lastname'),\n                $event->input->getOption('occupation'),\n            ]);\n        });\n\n        Event::listen(function (CommandFinished $event) {\n            array_map(fn ($e) => $this->files->append($this->logfile, $e.PHP_EOL), [\n                'CommandFinished',\n                $event->input->getArgument('firstname'),\n                $event->input->getArgument('lastname'),\n                $event->input->getOption('occupation'),\n            ]);\n        });\n\n        value($callback, $this);\n\n        $this->assertLogged(\n            'CommandStarting', 'taylor', 'otwell', 'coding',\n            'CommandFinished', 'taylor', 'otwell', 'coding',\n        );\n    }\n\n    public static function foregroundCommandEventsProvider()\n    {\n        yield 'Foreground with array' => [function ($testCase) {\n            $testCase->artisan(CommandEventsTestCommand::class, [\n                'firstname' => 'taylor',\n                'lastname' => 'otwell',\n                '--occupation' => 'coding',\n            ]);\n        }];\n\n        yield 'Foreground with string' => [function ($testCase) {\n            $testCase->artisan('command-events-test-command taylor otwell --occupation=coding');\n        }];\n    }\n\n    public function testCommandEventsReceiveParsedInputFromBackground(): void\n    {\n        $laravel = Testbench::create(\n            basePath: static::applicationBasePath(),\n            resolvingCallback: function ($app) {\n                $files = new Filesystem;\n                $log = fn ($msg) => $files->append($this->logfile, $msg.PHP_EOL);\n\n                $app['events']->listen(function (CommandStarting $event) use ($log) {\n                    array_map(fn ($msg) => $log($msg), [\n                        'CommandStarting',\n                        $event->input->getArgument('firstname'),\n                        $event->input->getArgument('lastname'),\n                        $event->input->getOption('occupation'),\n                    ]);\n                });\n\n                $app['events']->listen(function (CommandFinished $event) use ($log) {\n                    array_map(fn ($msg) => $log($msg), [\n                        'CommandFinished',\n                        $event->input->getArgument('firstname'),\n                        $event->input->getArgument('lastname'),\n                        $event->input->getOption('occupation'),\n                    ]);\n                });\n            },\n        );\n\n        tap($laravel[ConsoleKernel::class], function ($kernel) {\n            $kernel->rerouteSymfonyCommandEvents();\n            $kernel->registerCommand(new CommandEventsTestCommand);\n\n            $kernel->call(CommandEventsTestCommand::class, [\n                'firstname' => 'taylor',\n                'lastname' => 'otwell',\n                '--occupation' => 'coding',\n            ]);\n        });\n\n        $this->assertLogged(\n            'CommandStarting', 'taylor', 'otwell', 'coding',\n            'CommandFinished', 'taylor', 'otwell', 'coding',\n        );\n\n        $laravel->terminate();\n    }\n\n    protected function assertLogged(...$messages)\n    {\n        $log = trim($this->files->get($this->logfile));\n\n        $this->assertEquals(implode(PHP_EOL, $messages), $log);\n    }\n}\n\nclass CommandEventsTestCommand extends \\Illuminate\\Console\\Command\n{\n    protected $signature = 'command-events-test-command {firstname} {lastname} {--occupation=cook}';\n\n    public function handle()\n    {\n        // ...\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CommandManualFailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\ManuallyFailedException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CommandManualFailTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Artisan::starting(function ($artisan) {\n            $artisan->resolveCommands([\n                FailingCommandStub::class,\n            ]);\n        });\n\n        parent::setUp();\n    }\n\n    public function testFailArtisanCommandManually(): void\n    {\n        $this->artisan('app:fail')->assertFailed();\n    }\n\n    public function testCreatesAnExceptionFromString(): void\n    {\n        $this->expectException(ManuallyFailedException::class);\n        $this->expectExceptionMessage('Whoops!');\n        $command = new Command;\n        $command->fail('Whoops!');\n    }\n\n    public function testCreatesAnExceptionFromNull(): void\n    {\n        $this->expectException(ManuallyFailedException::class);\n        $this->expectExceptionMessage('Command failed manually.');\n        $command = new Command;\n        $command->fail();\n    }\n\n    public function testThrowsTheOriginalThrowableInstance(): void\n    {\n        try {\n            $command = new Command;\n            $command->fail($original = new \\RuntimeException('Something went wrong.'));\n\n            $this->fail('Command::fail() method must throw the original throwable instance.');\n        } catch (\\Throwable $e) {\n            $this->assertSame($original, $e);\n        }\n    }\n}\n\nclass FailingCommandStub extends Command\n{\n    protected $signature = 'app:fail';\n\n    public function handle()\n    {\n        $this->trigger_failure();\n\n        // This should never be reached.\n        return static::SUCCESS;\n    }\n\n    protected function trigger_failure()\n    {\n        $this->fail('Whoops!');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/CommandSchedulingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass CommandSchedulingTest extends TestCase\n{\n    /**\n     * Each run of this test is assigned a random ID to ensure that separate runs\n     * do not interfere with each other.\n     *\n     * @var string\n     */\n    protected $id;\n\n    /**\n     * The path to the file that execution logs will be written to.\n     *\n     * @var string\n     */\n    protected $logfile;\n\n    /**\n     * Just in case Testbench starts to ship an `artisan` script, we'll check and save a backup.\n     *\n     * @var string|null\n     */\n    protected $originalArtisan;\n\n    /**\n     * The Filesystem instance for writing stubs and logs.\n     *\n     * @var \\Illuminate\\Filesystem\\Filesystem\n     */\n    protected $fs;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->fs = new Filesystem;\n\n        $this->id = Str::random();\n        $this->logfile = storage_path(\"logs/command_scheduling_test_{$this->id}.log\");\n\n        $this->writeArtisanScript();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->fs->delete($this->logfile);\n        $this->fs->delete(base_path('artisan'));\n\n        if (! is_null($this->originalArtisan)) {\n            $this->fs->put(base_path('artisan'), $this->originalArtisan);\n        }\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('executionProvider')]\n    public function testExecutionOrder($background, $expected): void\n    {\n        $schedule = $this->app->make(Schedule::class);\n        $event = $schedule\n            ->command(\"test:{$this->id}\")\n            ->onOneServer()\n            ->after(function () {\n                $this->fs->append($this->logfile, \"foreground:after\\n\");\n            })\n            ->before(function () {\n                $this->fs->append($this->logfile, \"foreground:before\\n\");\n            });\n\n        if ($background) {\n            $event->runInBackground();\n        }\n\n        // We'll trigger the scheduler three times to simulate multiple servers\n        $this->app->instance(Schedule::class, clone $schedule);\n        $this->artisan('schedule:run');\n        $this->app->instance(Schedule::class, clone $schedule);\n        $this->artisan('schedule:run');\n        $this->app->instance(Schedule::class, clone $schedule);\n        $this->artisan('schedule:run');\n\n        if ($background) {\n            // Since our command is running in a separate process, we need to wait\n            // until it has finished executing before running our assertions.\n            $this->waitForLogMessages(...$expected);\n        }\n\n        $this->assertLogged(...$expected);\n    }\n\n    public static function executionProvider()\n    {\n        return [\n            'Foreground' => [false, ['foreground:before', 'handled', 'foreground:after']],\n            'Background' => [true, ['foreground:before', 'handled', 'background:after']],\n        ];\n    }\n\n    protected function waitForLogMessages(...$messages)\n    {\n        $tries = 0;\n        $sleep = 100000; // 100K microseconds = 0.1 second\n        $limit = 50; // 0.1s * 50 = 5 second wait limit\n\n        do {\n            $log = $this->fs->get($this->logfile);\n\n            if (Str::containsAll($log, $messages)) {\n                return;\n            }\n\n            $tries++;\n            usleep($sleep);\n        } while ($tries < $limit);\n    }\n\n    protected function assertLogged(...$messages)\n    {\n        $log = trim($this->fs->get($this->logfile));\n\n        $this->assertEquals(implode(\"\\n\", $messages), $log);\n    }\n\n    protected function writeArtisanScript()\n    {\n        $path = base_path('artisan');\n\n        // Save existing artisan script if there is one\n        if ($this->fs->exists($path)) {\n            $this->originalArtisan = $this->fs->get($path);\n        }\n\n        $thisFile = __FILE__;\n        $logfile = var_export($this->logfile, true);\n\n        $script = <<<PHP\n#!/usr/bin/env php\n<?php\n\n// This is a custom artisan script made specifically for:\n//\n// {$thisFile}\n//\n// It should be automatically cleaned up when the tests have finished executing.\n// If you are seeing this file, an unexpected error must have occurred. Please\n// manually remove it.\n\ndefine('LARAVEL_START', microtime(true));\n\nrequire __DIR__.'/../../../autoload.php';\n\n\\$app = require_once __DIR__.'/bootstrap/app.php';\n\\$kernel = \\$app->make(Illuminate\\Contracts\\Console\\Kernel::class);\n\n// Here is our custom command for the test\nclass CommandSchedulingTestCommand_{$this->id} extends Illuminate\\Console\\Command\n{\n    protected \\$signature = 'test:{$this->id}';\n\n    public function handle()\n    {\n        \\$logfile = {$logfile};\n        (new Illuminate\\Filesystem\\Filesystem)->append(\\$logfile, \"handled\\\\n\");\n    }\n}\n\n// Register command with Kernel\nIlluminate\\Console\\Application::starting(function (\\$artisan) {\n    \\$artisan->add(new CommandSchedulingTestCommand_{$this->id});\n});\n\n// Add command to scheduler so that the after() callback is trigger in our spawned process\nIlluminate\\Foundation\\Application::getInstance()\n    ->booted(function (\\$app) {\n        \\$app->resolving(Illuminate\\Console\\Scheduling\\Schedule::class, function(\\$schedule) {\n            \\$fs = new Illuminate\\Filesystem\\Filesystem;\n            \\$schedule->command(\"test:{$this->id}\")\n                ->after(function() use (\\$fs) {\n                    \\$logfile = {$logfile};\n                    \\$fs->append(\\$logfile, \"background:after\\\\n\");\n                })\n                ->before(function() use (\\$fs) {\n                    \\$logfile = {$logfile};\n                    \\$fs->append(\\$logfile, \"background:before\\\\n\");\n                });\n        });\n    });\n\n\\$status = \\$kernel->handle(\n    \\$input = new Symfony\\Component\\Console\\Input\\ArgvInput,\n    new Symfony\\Component\\Console\\Output\\ConsoleOutput\n);\n\n\\$kernel->terminate(\\$input, \\$status);\n\nexit(\\$status);\n\nPHP;\n\n        $this->fs->put($path, $script);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/ConsoleApplicationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Application as Artisan;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Illuminate\\Foundation\\Console\\QueuedCommand;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\n\nclass ConsoleApplicationTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Artisan::starting(function ($artisan) {\n            $artisan->resolveCommands([\n                FooCommandStub::class,\n                ZondaCommandStub::class,\n            ]);\n        });\n\n        parent::setUp();\n    }\n\n    public function testArtisanCallUsingCommandName(): void\n    {\n        $this->artisan('foo:bar', [\n            'id' => 1,\n        ])->assertExitCode(0);\n    }\n\n    public function testArtisanCallUsingCommandNameAliases(): void\n    {\n        $this->artisan('app:foobar', [\n            'id' => 1,\n        ])->assertExitCode(0);\n    }\n\n    public function testArtisanCallUsingCommandClass(): void\n    {\n        $this->artisan(FooCommandStub::class, [\n            'id' => 1,\n        ])->assertExitCode(0);\n    }\n\n    public function testArtisanCallUsingCommandNameUsingAsCommandAttribute(): void\n    {\n        $this->artisan('zonda', [\n            'id' => 1,\n        ])->assertExitCode(0);\n    }\n\n    public function testArtisanCallUsingCommandNameAliasesUsingAsCommandAttribute(): void\n    {\n        $this->artisan('app:zonda', [\n            'id' => 1,\n        ])->assertExitCode(0);\n    }\n\n    public function testArtisanCallNow(): void\n    {\n        $exitCode = $this->artisan('foo:bar', [\n            'id' => 1,\n        ])->run();\n\n        $this->assertSame(0, $exitCode);\n    }\n\n    public function testArtisanWithMockCallAfterCallNow(): void\n    {\n        $exitCode = $this->artisan('foo:bar', [\n            'id' => 1,\n        ])->run();\n\n        $mock = $this->artisan('foo:bar', [\n            'id' => 1,\n        ]);\n\n        $this->assertSame(0, $exitCode);\n        $mock->assertExitCode(0);\n    }\n\n    public function testArtisanInstantiateScheduleWhenNeed(): void\n    {\n        $this->assertFalse($this->app->resolved(Schedule::class));\n\n        $this->app[Kernel::class]->registerCommand(new ScheduleCommandStub);\n\n        $this->assertFalse($this->app->resolved(Schedule::class));\n\n        $this->artisan('foo:schedule');\n\n        $this->assertTrue($this->app->resolved(Schedule::class));\n    }\n\n    public function testArtisanQueue(): void\n    {\n        Queue::fake();\n\n        $this->app[Kernel::class]->queue('foo:bar', [\n            'id' => 1,\n        ]);\n\n        Queue::assertPushed(QueuedCommand::class, function ($job) {\n            return $job->displayName() === 'foo:bar';\n        });\n    }\n}\n\nclass FooCommandStub extends Command\n{\n    protected $signature = 'foo:bar {id}';\n\n    protected $aliases = ['app:foobar'];\n\n    public function handle()\n    {\n        //\n    }\n}\n\n#[AsCommand(name: 'zonda', aliases: ['app:zonda'])]\nclass ZondaCommandStub extends Command\n{\n    protected $signature = 'zonda {id}';\n\n    protected $aliases = ['app:zonda'];\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass ScheduleCommandStub extends Command\n{\n    protected $signature = 'foo:schedule';\n\n    public function handle(Schedule $schedule)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/EnvironmentDecryptCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\File;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EnvironmentDecryptCommandTest extends TestCase\n{\n    protected $filesystem;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->filesystem = m::spy(Filesystem::class);\n        $this->filesystem->shouldReceive('put')\n            ->andReturn(true);\n        File::swap($this->filesystem);\n    }\n\n    public function testItFailsWithInvalidCipherFails(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:decrypt', ['--cipher' => 'invalid', '--key' => 'abcdefghijklmnop'])\n            ->expectsOutputToContain('Unsupported cipher')\n            ->assertExitCode(1);\n    }\n\n    public function testItFailsUsingCipherWithInvalidKey(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:decrypt', ['--cipher' => 'aes-128-cbc', '--key' => 'invalid'])\n            ->expectsOutputToContain('incorrect key length')\n            ->assertExitCode(1);\n    }\n\n    public function testItFailsWhenEncryptionFileCannotBeFound(): void\n    {\n        $this->filesystem->shouldReceive('exists')->andReturn(true);\n\n        $this->artisan('env:decrypt', ['--key' => 'secret-key'])\n            ->expectsOutputToContain('Environment file already exists.')\n            ->assertExitCode(1);\n    }\n\n    public function testItFailsWhenEnvironmentFileExists(): void\n    {\n        $this->filesystem->shouldReceive('exists')->andReturn(false);\n\n        $this->artisan('env:decrypt', ['--key' => 'secret-key'])\n            ->expectsOutputToContain('Encrypted environment file not found.')\n            ->assertExitCode(1);\n    }\n\n    public function testItGeneratesTheEnvironmentFileWithGeneratedKey(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter($key = Encrypter::generateKey('AES-256-CBC'), 'AES-256-CBC'))\n                    ->encrypt('APP_NAME=Laravel')\n            );\n\n        $this->artisan('env:decrypt', ['--force' => true, '--key' => 'base64:'.base64_encode($key)])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=Laravel');\n    }\n\n    public function testItGeneratesTheEnvironmentFileWithUserProvidedKey(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnop', 'aes-128-gcm'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--cipher' => 'aes-128-gcm', '--key' => 'abcdefghijklmnop'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItGeneratesTheEnvironmentFileWithKeyFromEnvironment(): void\n    {\n        $_SERVER['LARAVEL_ENV_ENCRYPTION_KEY'] = 'ponmlkjihgfedcbaponmlkjihgfedcba';\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('ponmlkjihgfedcbaponmlkjihgfedcba', 'AES-256-CBC'))\n                    ->encrypt('APP_NAME=\"Laravel Three\"')\n            );\n\n        $this->artisan('env:decrypt')\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=\"Laravel Three\"');\n\n        unset($_SERVER['LARAVEL_ENV_ENCRYPTION_KEY']);\n    }\n\n    public function testItGeneratesTheEnvironmentFileWhenForcing(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnop', 'aes-128-gcm'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--force' => true, '--key' => 'abcdefghijklmnop', '--cipher' => 'aes-128-gcm'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItDecryptsMultiLineEnvironmentCorrectly(): void\n    {\n        $contents = <<<'Text'\n        APP_NAME=Laravel\n        APP_ENV=local\n        APP_DEBUG=true\n        APP_URL=http://localhost\n\n        LOG_CHANNEL=stack\n        LOG_DEPRECATIONS_CHANNEL=null\n        LOG_LEVEL=debug\n\n        DB_CONNECTION=mysql\n        DB_HOST=127.0.0.1\n        DB_PORT=3306\n        DB_DATABASE=laravel\n        DB_USERNAME=root\n        DB_PASSWORD=\n        Text;\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnop', 'aes-128-gcm'))\n                    ->encrypt($contents)\n            );\n\n        $this->artisan('env:decrypt', ['--force' => true, '--key' => 'abcdefghijklmnop', '--cipher' => 'aes-128-gcm'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), $contents);\n    }\n\n    public function testItWritesTheEnvironmentFileCustomFilename(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnopabcdefghijklmnop', 'AES-256-CBC'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--env' => 'production', '--key' => 'abcdefghijklmnopabcdefghijklmnop', '--filename' => '.env'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItWritesTheEnvironmentFileCustomPath(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnopabcdefghijklmnop', 'AES-256-CBC'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--env' => 'production', '--key' => 'abcdefghijklmnopabcdefghijklmnop', '--path' => '/tmp'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with('/tmp'.DIRECTORY_SEPARATOR.'.env.production', 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItWritesTheEnvironmentFileCustomPathAndFilename(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter('abcdefghijklmnopabcdefghijklmnop', 'AES-256-CBC'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--env' => 'production', '--key' => 'abcdefghijklmnopabcdefghijklmnop', '--filename' => '.env', '--path' => '/tmp'])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with('/tmp'.DIRECTORY_SEPARATOR.'.env', 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItCannotOverwriteEncryptedFiles(): void\n    {\n        $this->artisan('env:decrypt', ['--env' => 'production', '--key' => 'abcdefghijklmnop', '--filename' => '.env.production.encrypted'])\n            ->expectsOutputToContain('Invalid filename.')\n            ->assertExitCode(1);\n\n        $this->artisan('env:decrypt', ['--env' => 'production', '--key' => 'abcdefghijklmnop', '--filename' => '.env.staging.encrypted'])\n            ->expectsOutputToContain('Invalid filename.')\n            ->assertExitCode(1);\n    }\n\n    public function testItGeneratesTheEnvironmentFileWithInteractivelyUserProvidedKey(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn(\n                (new Encrypter($key = 'abcdefghijklmnop', 'aes-128-gcm'))\n                    ->encrypt('APP_NAME=\"Laravel Two\"')\n            );\n\n        $this->artisan('env:decrypt', ['--cipher' => 'aes-128-gcm'])\n            ->expectsQuestion('What is the decryption key?', $key)\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), 'APP_NAME=\"Laravel Two\"');\n    }\n\n    public function testItAutoDetectsAndDecryptsReadableFormat(): void\n    {\n        $key = 'abcdefghijklmnopabcdefghijklmnop';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        // Create readable format encrypted content\n        $encryptedContent = 'APP_NAME='.$encrypter->encryptString('Laravel').\"\\n\".\n                           'APP_ENV='.$encrypter->encryptString('local');\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn($encryptedContent);\n\n        $this->artisan('env:decrypt', ['--key' => $key])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), \"APP_NAME=Laravel\\nAPP_ENV=local\\n\");\n    }\n\n    public function testItStillDecryptsBlobFormat(): void\n    {\n        $key = 'abcdefghijklmnopabcdefghijklmnop';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        // Create blob format (entire file encrypted as one)\n        $originalContent = \"APP_NAME=Laravel\\nAPP_ENV=local\";\n        $encryptedContent = $encrypter->encrypt($originalContent);\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn($encryptedContent);\n\n        $this->artisan('env:decrypt', ['--key' => $key])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), $originalContent);\n    }\n\n    public function testItDecryptsBlobFormatWithNewlineInContent(): void\n    {\n        $key = 'abcdefghijklmnopabcdefghijklmnop';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        // Create blob format and inject a newline (simulating wrapped base64)\n        $originalContent = \"APP_NAME=Laravel\\nAPP_ENV=local\";\n        $encryptedContent = $encrypter->encrypt($originalContent);\n\n        // Insert a newline in the middle of the base64 string\n        $midpoint = (int) (strlen($encryptedContent) / 2);\n        $encryptedContentWithNewline = substr($encryptedContent, 0, $midpoint).\"\\n\".substr($encryptedContent, $midpoint);\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn($encryptedContentWithNewline);\n\n        $this->artisan('env:decrypt', ['--key' => $key])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), $originalContent);\n    }\n\n    public function testItDecryptsReadableFormatWithBase64Values(): void\n    {\n        $key = 'abcdefghijklmnopabcdefghijklmnop';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        // Create readable format with base64 value containing = signs\n        $encryptedContent = 'APP_KEY='.$encrypter->encryptString('base64:Ge+W23u+VZI2tbrp5QCGWrsUuxgcD65i7jtTRR2ZqfY=').\"\\n\".\n                           'APP_ENV='.$encrypter->encryptString('local');\n\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get')\n            ->once()\n            ->andReturn($encryptedContent);\n\n        $this->artisan('env:decrypt', ['--key' => $key])\n            ->expectsOutputToContain('Environment successfully decrypted.')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env'), \"APP_KEY=base64:Ge+W23u+VZI2tbrp5QCGWrsUuxgcD65i7jtTRR2ZqfY=\\nAPP_ENV=local\\n\");\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/EnvironmentEncryptCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\File;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EnvironmentEncryptCommandTest extends TestCase\n{\n    protected $filesystem;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->filesystem = m::spy(Filesystem::class);\n        $this->filesystem->shouldReceive('get')\n            ->andReturn(true)\n            ->shouldReceive('put')\n            ->andReturn('APP_NAME=Laravel');\n        File::swap($this->filesystem);\n    }\n\n    public function testItFailsWithInvalidCipherFails(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt', ['--cipher' => 'invalid'])\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('Unsupported cipher')\n            ->assertExitCode(1);\n    }\n\n    public function testItFailsUsingCipherWithInvalidKey(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt', ['--cipher' => 'aes-128-cbc', '--key' => 'invalid'])\n            ->expectsOutputToContain('incorrect key length')\n            ->assertExitCode(1);\n    }\n\n    public function testItGeneratesTheCorrectFileWhenUsingEnvironment(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt', ['--env' => 'production'])\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('.env.production.encrypted')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env.production.encrypted'), m::any());\n    }\n\n    public function testItGeneratesTheCorrectFileWhenNotUsingEnvironment(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false)\n            ->shouldReceive('get');\n\n        $this->artisan('env:encrypt')\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env.encrypted'), m::any());\n    }\n\n    public function testItFailsWhenEnvironmentFileCannotBeFound(): void\n    {\n        $this->filesystem->shouldReceive('exists')->andReturn(false);\n\n        $this->artisan('env:encrypt')\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('Environment file not found.')\n            ->assertExitCode(1);\n    }\n\n    public function testItFailsWhenEncryptionFileExists(): void\n    {\n        $this->filesystem->shouldReceive('exists')->andReturn(true);\n\n        $this->artisan('env:encrypt')\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('Encrypted environment file already exists.')\n            ->assertExitCode(1);\n    }\n\n    public function testItGeneratesTheEncryptionFileWhenForcing(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(true);\n\n        $this->artisan('env:encrypt', ['--force' => true])\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env.encrypted'), m::any());\n    }\n\n    public function testItEncryptsWithGivenKeyAndDisplaysIt(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt', ['--key' => $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP'])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->expectsOutputToContain($key)\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n    }\n\n    public function testItEncryptsWithGivenGeneratedBase64KeyAndDisplaysIt(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $key = Encrypter::generateKey('AES-256-CBC');\n\n        $this->artisan('env:encrypt', ['--key' => 'base64:'.base64_encode($key)])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->expectsOutputToContain('base64:'.base64_encode($key))\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n    }\n\n    public function testItEncryptsInReadableFormat(): void\n    {\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(\"APP_NAME=Laravel\\nAPP_ENV=local\");\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) {\n                $lines = explode(\"\\n\", rtrim($content));\n\n                return count($lines) === 2\n                    && str_starts_with($lines[0], 'APP_NAME=')\n                    && str_starts_with($lines[1], 'APP_ENV=');\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP'])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n    }\n\n    public function testItSkipsCommentsAndBlankLinesInReadableFormat(): void\n    {\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(\"# Comment\\nAPP_NAME=Laravel\\n\\nAPP_ENV=local\");\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) {\n                $lines = explode(\"\\n\", rtrim($content));\n\n                // Comments and blank lines are skipped\n                return count($lines) === 2\n                    && str_starts_with($lines[0], 'APP_NAME=')\n                    && str_starts_with($lines[1], 'APP_ENV=');\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP'])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n    }\n\n    public function testItEncryptsMultiLineValuesInReadableFormat(): void\n    {\n        $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        $originalContent = <<<'ENV'\nAPP_TEST_1=\"line1\nline2\nline3\"\nAPP_TEST_2=\"línea1\nlìnea2\nlïne3\"\nENV;\n\n        $encryptedOutput = null;\n\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn($originalContent);\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) use (&$encryptedOutput) {\n                $encryptedOutput = $content;\n\n                return true;\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => $key])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n\n        // Verify structure\n        $lines = explode(\"\\n\", rtrim($encryptedOutput));\n        $this->assertCount(2, $lines);\n        $this->assertTrue(str_starts_with($lines[0], 'APP_TEST_1='));\n        $this->assertTrue(str_starts_with($lines[1], 'APP_TEST_2='));\n\n        // Round-trip: decrypt and verify original values\n        $encryptedValue1 = substr($lines[0], strlen('APP_TEST_1='));\n        $encryptedValue2 = substr($lines[1], strlen('APP_TEST_2='));\n\n        // Quotes are preserved, accented characters are preserved\n        $this->assertSame(\"\\\"line1\\nline2\\nline3\\\"\", $encrypter->decryptString($encryptedValue1));\n        $this->assertSame(\"\\\"línea1\\nlìnea2\\nlïne3\\\"\", $encrypter->decryptString($encryptedValue2));\n    }\n\n    public function testItEncryptsVariableReferencesInReadableFormat(): void\n    {\n        $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        $originalContent = <<<'ENV'\nAPP_TEST_1=${APP_TEST}\nAPP_TEST_2=\"${APP_TEST}\"\nENV;\n\n        $encryptedOutput = null;\n\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn($originalContent);\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) use (&$encryptedOutput) {\n                $encryptedOutput = $content;\n\n                return true;\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => $key])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n\n        // Verify structure\n        $lines = explode(\"\\n\", rtrim($encryptedOutput));\n        $this->assertCount(2, $lines);\n        $this->assertTrue(str_starts_with($lines[0], 'APP_TEST_1='));\n        $this->assertTrue(str_starts_with($lines[1], 'APP_TEST_2='));\n\n        // Round-trip: decrypt and verify values preserve variable reference syntax\n        $encryptedValue1 = substr($lines[0], strlen('APP_TEST_1='));\n        $encryptedValue2 = substr($lines[1], strlen('APP_TEST_2='));\n\n        // Unquoted value preserved as-is, quoted value includes quotes\n        $this->assertSame('${APP_TEST}', $encrypter->decryptString($encryptedValue1));\n        $this->assertSame('\"${APP_TEST}\"', $encrypter->decryptString($encryptedValue2));\n    }\n\n    public function testItSkipsInvalidEnvLinesInReadableFormat(): void\n    {\n        $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        $originalContent = <<<'ENV'\nAPP_TEST_1=valid\nAPP_TEST_2\nAPP_TEST_3=also_valid\nENV;\n\n        $encryptedOutput = null;\n\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn($originalContent);\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) use (&$encryptedOutput) {\n                $encryptedOutput = $content;\n\n                return true;\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => $key])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n\n        // Verify structure - invalid line (APP_TEST_2 without =) is skipped\n        $lines = explode(\"\\n\", rtrim($encryptedOutput));\n        $this->assertCount(2, $lines);\n        $this->assertTrue(str_starts_with($lines[0], 'APP_TEST_1='));\n        $this->assertTrue(str_starts_with($lines[1], 'APP_TEST_3='));\n\n        // Round-trip: decrypt and verify values\n        $encryptedValue1 = substr($lines[0], strlen('APP_TEST_1='));\n        $encryptedValue3 = substr($lines[1], strlen('APP_TEST_3='));\n\n        $this->assertSame('valid', $encrypter->decryptString($encryptedValue1));\n        $this->assertSame('also_valid', $encrypter->decryptString($encryptedValue3));\n    }\n\n    public function testItEncryptsSpecialCharactersInReadableFormat(): void\n    {\n        $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP';\n        $encrypter = new Encrypter($key, 'AES-256-CBC');\n\n        $originalContent = <<<'ENV'\nNAME_1=\"Máximus\"\nNAME_2=M'aximus\nNAME_3=\"M'aximus Decimus Meridius\"\nENV;\n\n        $encryptedOutput = null;\n\n        $filesystem = m::mock(Filesystem::class);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn(true);\n        $filesystem->shouldReceive('exists')\n            ->with(base_path('.env.encrypted'))\n            ->once()\n            ->andReturn(false);\n        $filesystem->shouldReceive('get')\n            ->with(base_path('.env'))\n            ->once()\n            ->andReturn($originalContent);\n        $filesystem->shouldReceive('put')\n            ->once()\n            ->with(base_path('.env.encrypted'), m::on(function ($content) use (&$encryptedOutput) {\n                $encryptedOutput = $content;\n\n                return true;\n            }))\n            ->andReturn(true);\n        File::swap($filesystem);\n\n        $this->artisan('env:encrypt', ['--readable' => true, '--key' => $key])\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->assertExitCode(0);\n\n        // Verify structure\n        $lines = explode(\"\\n\", rtrim($encryptedOutput));\n        $this->assertCount(3, $lines);\n        $this->assertTrue(str_starts_with($lines[0], 'NAME_1='));\n        $this->assertTrue(str_starts_with($lines[1], 'NAME_2='));\n        $this->assertTrue(str_starts_with($lines[2], 'NAME_3='));\n\n        // Round-trip: decrypt and verify special characters are preserved\n        $encryptedValue1 = substr($lines[0], strlen('NAME_1='));\n        $encryptedValue2 = substr($lines[1], strlen('NAME_2='));\n        $encryptedValue3 = substr($lines[2], strlen('NAME_3='));\n\n        // Quoted values include the quotes, unquoted values are as-is\n        $this->assertSame('\"Máximus\"', $encrypter->decryptString($encryptedValue1));\n        $this->assertSame(\"M'aximus\", $encrypter->decryptString($encryptedValue2));\n        $this->assertSame(\"\\\"M'aximus Decimus Meridius\\\"\", $encrypter->decryptString($encryptedValue3));\n    }\n\n    public function testItCanRemoveTheOriginalFile(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt', ['--prune' => true])\n            ->expectsQuestion('What encryption key would you like to use?', 'generate')\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n\n        $this->filesystem->shouldHaveReceived('put')\n            ->with(base_path('.env.encrypted'), m::any());\n\n        $this->filesystem->shouldHaveReceived('delete')\n            ->with(base_path('.env'));\n    }\n\n    public function testItEncryptsWithInteractivelyGivenKeyAndDisplaysIt(): void\n    {\n        $this->filesystem->shouldReceive('exists')\n            ->once()\n            ->andReturn(true)\n            ->shouldReceive('exists')\n            ->once()\n            ->andReturn(false);\n\n        $this->artisan('env:encrypt')\n            ->expectsQuestion('What encryption key would you like to use?', 'ask')\n            ->expectsQuestion('What is the encryption key?', $key = 'ANvVbPbE0tWMHpUySh6liY4WaCmAYKXP')\n            ->expectsOutputToContain('Environment successfully encrypted')\n            ->expectsOutputToContain($key)\n            ->expectsOutputToContain('.env.encrypted')\n            ->assertExitCode(0);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Events/EventListCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Events;\n\nuse Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Console\\EventListCommand;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EventListCommandTest extends TestCase\n{\n    public $dispatcher;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->dispatcher = new Dispatcher();\n        EventListCommand::resolveEventsUsing(fn () => $this->dispatcher);\n    }\n\n    public function testDisplayEmptyList()\n    {\n        $this->artisan(EventListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain(\"Your application doesn't have any events matching the given criteria.\");\n    }\n\n    public function testDisplayEvents()\n    {\n        $this->dispatcher->subscribe(ExampleSubscriber::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleListener::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleQueueListener::class);\n        $this->dispatcher->listen(ExampleBroadcastEvent::class, ExampleBroadcastListener::class);\n        $this->dispatcher->listen(ExampleEvent::class, fn () => '');\n        $closureLineNumber = __LINE__ - 1;\n        $unixFilePath = str_replace('\\\\', '/', __FILE__);\n\n        $this->artisan(EventListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain('ExampleSubscriberEventName')\n            ->expectsOutputToContain('⇂ Illuminate\\Tests\\Integration\\Console\\Events\\ExampleSubscriber@a')\n            ->expectsOutputToContain('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleBroadcastEvent (ShouldBroadcast)')\n            ->expectsOutputToContain('⇂ Illuminate\\Tests\\Integration\\Console\\Events\\ExampleBroadcastListener')\n            ->expectsOutputToContain('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleEvent')\n            ->expectsOutputToContain('⇂ Closure at: '.$unixFilePath.':'.$closureLineNumber);\n    }\n\n    public function testDisplayFilteredEvent()\n    {\n        $this->dispatcher->subscribe(ExampleSubscriber::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleListener::class);\n\n        $this->artisan(EventListCommand::class, ['--event' => 'ExampleEvent'])\n            ->assertSuccessful()\n            ->doesntExpectOutput('  ExampleSubscriberEventName')\n            ->expectsOutputToContain('ExampleEvent');\n    }\n\n    public function testDisplayEmptyListAsJson()\n    {\n        $this->withoutMockingConsoleOutput()->artisan(EventListCommand::class, ['--json' => true]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $this->assertJsonStringEqualsJsonString('[]', $output);\n    }\n\n    public function testDisplayEventsAsJson()\n    {\n        $this->dispatcher->subscribe(ExampleSubscriber::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleListener::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleQueueListener::class);\n        $this->dispatcher->listen(ExampleBroadcastEvent::class, ExampleBroadcastListener::class);\n        $this->dispatcher->listen(ExampleEvent::class, fn () => '');\n        $closureLineNumber = __LINE__ - 1;\n        $unixFilePath = str_replace('\\\\', '/', __FILE__);\n\n        $this->withoutMockingConsoleOutput()->artisan(EventListCommand::class, ['--json' => true]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $this->assertStringContainsString('ExampleSubscriberEventName', $output);\n        $this->assertStringContainsString(json_encode('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleSubscriber@a'), $output);\n        $this->assertStringContainsString(json_encode('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleBroadcastEvent (ShouldBroadcast)'), $output);\n        $this->assertStringContainsString(json_encode('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleBroadcastListener'), $output);\n        $this->assertStringContainsString(json_encode('Illuminate\\Tests\\Integration\\Console\\Events\\ExampleEvent'), $output);\n        $this->assertStringContainsString(json_encode('Closure at: '.$unixFilePath.':'.$closureLineNumber), $output);\n    }\n\n    public function testDisplayFilteredEventAsJson()\n    {\n        $this->dispatcher->subscribe(ExampleSubscriber::class);\n        $this->dispatcher->listen(ExampleEvent::class, ExampleListener::class);\n\n        $this->withoutMockingConsoleOutput()->artisan(EventListCommand::class, [\n            '--event' => 'ExampleEvent',\n            '--json' => true,\n        ]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $this->assertStringContainsString('ExampleEvent', $output);\n        $this->assertStringContainsString('ExampleListener', $output);\n        $this->assertStringNotContainsString('ExampleSubscriberEventName', $output);\n    }\n\n    protected function tearDown(): void\n    {\n        EventListCommand::resolveEventsUsing(null);\n\n        parent::tearDown();\n    }\n}\n\nclass ExampleSubscriber\n{\n    public function subscribe()\n    {\n        return [\n            'ExampleSubscriberEventName' => [\n                self::class.'@a',\n                self::class.'@b',\n            ],\n        ];\n    }\n\n    public function a()\n    {\n    }\n\n    public function b()\n    {\n    }\n}\n\nclass ExampleEvent\n{\n}\n\nclass ExampleBroadcastEvent implements ShouldBroadcast\n{\n    public function broadcastOn()\n    {\n        //\n    }\n}\n\nclass ExampleListener\n{\n    public function handle()\n    {\n    }\n}\n\nclass ExampleQueueListener implements ShouldQueue\n{\n    public function handle()\n    {\n    }\n}\n\nclass ExampleBroadcastListener\n{\n    public function handle()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/GeneratorCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass GeneratorCommandTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected $files = [\n        'app/Console/Commands/FooCommand.php',\n        'resources/views/foo/php.blade.php',\n        'tests/Feature/fixtures.php/SomeTest.php',\n    ];\n\n    public function testItChopsPhpExtension(): void\n    {\n        $this->artisan('make:command', ['name' => 'FooCommand.php'])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Console/Commands/FooCommand.php');\n\n        $this->assertFileContains([\n            'class FooCommand extends Command',\n        ], 'app/Console/Commands/FooCommand.php');\n    }\n\n    public function testItChopsPhpExtensionFromMakeViewCommands(): void\n    {\n        $this->artisan('make:view', ['name' => 'foo.php'])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('resources/views/foo/php.blade.php');\n    }\n\n    public function testItOnlyChopsPhpExtensionFromFilename(): void\n    {\n        $this->artisan('make:test', ['name' => 'fixtures.php/SomeTest'])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('tests/Feature/fixtures.php/SomeTest.php');\n\n        $this->assertFileContains([\n            'class SomeTest extends TestCase',\n        ], 'tests/Feature/fixtures.php/SomeTest.php');\n    }\n\n    #[DataProvider('reservedNamesDataProvider')]\n    public function testItCannotGenerateClassUsingReservedName($given): void\n    {\n        $this->artisan('make:command', ['name' => $given])\n            ->expectsOutputToContain('The name \"'.$given.'\" is reserved by PHP.')\n            ->assertExitCode(0);\n    }\n\n    public static function reservedNamesDataProvider()\n    {\n        yield ['__halt_compiler'];\n        yield ['__HALT_COMPILER'];\n        yield ['array'];\n        yield ['ARRAY'];\n        yield ['__class__'];\n        yield ['__CLASS__'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/JobSchedulingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\n\nclass JobSchedulingTest extends TestCase\n{\n    public function testJobQueuingRespectsJobQueue(): void\n    {\n        Queue::fake();\n\n        /** @var \\Illuminate\\Console\\Scheduling\\Schedule $scheduler */\n        $scheduler = $this->app->make(Schedule::class);\n\n        // all job names were set to an empty string so that the registered shutdown function in CallbackEvent does nothing\n        // that function would in this test environment fire after everything was run, including the tearDown method\n        // (which flushes the entire container) which would then result in a ReflectionException when the container would try\n        // to resolve the config service (which is needed in order to resolve the cache store for the mutex that is being cleared)\n        $scheduler->job(JobWithDefaultQueue::class)->name('')->everyMinute();\n        $scheduler->job(JobWithDefaultQueueTwo::class, 'another-queue')->name('')->everyMinute();\n        $scheduler->job(JobWithoutDefaultQueue::class)->name('')->everyMinute();\n\n        $events = $scheduler->events();\n        foreach ($events as $event) {\n            $event->run($this->app);\n        }\n\n        Queue::assertPushedOn('test-queue', JobWithDefaultQueue::class);\n        Queue::assertPushedOn('another-queue', JobWithDefaultQueueTwo::class);\n        Queue::assertPushedOn(null, JobWithoutDefaultQueue::class);\n        $this->assertTrue(Queue::pushed(JobWithDefaultQueueTwo::class, function ($job, $pushedQueue) {\n            return $pushedQueue === 'test-queue-two';\n        })->isEmpty());\n    }\n\n    public function testJobQueuingRespectsJobConnection(): void\n    {\n        Queue::fake();\n\n        /** @var \\Illuminate\\Console\\Scheduling\\Schedule $scheduler */\n        $scheduler = $this->app->make(Schedule::class);\n\n        // all job names were set to an empty string so that the registered shutdown function in CallbackEvent does nothing\n        // that function would in this test environment fire after everything was run, including the tearDown method\n        // (which flushes the entire container) which would then result in a ReflectionException when the container would try\n        // to resolve the config service (which is needed in order to resolve the cache store for the mutex that is being cleared)\n        $scheduler->job(JobWithDefaultConnection::class)->name('')->everyMinute();\n        $scheduler->job(JobWithDefaultConnection::class, null, 'foo')->name('')->everyMinute();\n        $scheduler->job(JobWithoutDefaultConnection::class)->name('')->everyMinute();\n        $scheduler->job(JobWithoutDefaultConnection::class, null, 'bar')->name('')->everyMinute();\n\n        $events = $scheduler->events();\n        foreach ($events as $event) {\n            $event->run($this->app);\n        }\n\n        $this->assertSame(1, Queue::pushed(JobWithDefaultConnection::class, function (JobWithDefaultConnection $job, $pushedQueue) {\n            return $job->connection === 'test-connection';\n        })->count());\n\n        $this->assertSame(1, Queue::pushed(JobWithDefaultConnection::class, function (JobWithDefaultConnection $job, $pushedQueue) {\n            return $job->connection === 'foo';\n        })->count());\n\n        $this->assertSame(0, Queue::pushed(JobWithDefaultConnection::class, function (JobWithDefaultConnection $job, $pushedQueue) {\n            return $job->connection === null;\n        })->count());\n\n        $this->assertSame(1, Queue::pushed(JobWithoutDefaultConnection::class, function (JobWithoutDefaultConnection $job, $pushedQueue) {\n            return $job->connection === null;\n        })->count());\n\n        $this->assertSame(1, Queue::pushed(JobWithoutDefaultConnection::class, function (JobWithoutDefaultConnection $job, $pushedQueue) {\n            return $job->connection === 'bar';\n        })->count());\n    }\n\n    public function testJobQueuingRespectsQueueRoutes(): void\n    {\n        Queue::fake();\n\n        Queue::route(JobWithDefaultQueue::class, 'default-queue');\n        Queue::route(JobWithoutDefaultQueue::class, 'fallback-queue');\n        Queue::route(JobWithoutDefaultConnection::class, 'some-queue', 'some-connection');\n\n        /** @var \\Illuminate\\Console\\Scheduling\\Schedule $scheduler */\n        $scheduler = $this->app->make(Schedule::class);\n\n        $scheduler->job(JobWithDefaultQueue::class)->name('')->everyMinute();\n        $scheduler->job(JobWithoutDefaultQueue::class)->name('')->everyMinute();\n        $scheduler->job(JobWithoutDefaultConnection::class)->name('')->everyMinute();\n\n        $events = $scheduler->events();\n        foreach ($events as $event) {\n            $event->run($this->app);\n        }\n\n        // Own queue takes precedence over default\n        Queue::assertPushedOn('test-queue', JobWithDefaultQueue::class);\n        Queue::assertPushedOn('fallback-queue', JobWithoutDefaultQueue::class);\n        Queue::connection('some-queue')->assertPushedOn('some-queue', JobWithoutDefaultConnection::class);\n    }\n}\n\nclass JobWithDefaultQueue implements ShouldQueue\n{\n    use Queueable, InteractsWithQueue;\n\n    public function __construct()\n    {\n        $this->onQueue('test-queue');\n    }\n}\n\nclass JobWithDefaultQueueTwo implements ShouldQueue\n{\n    use Queueable, InteractsWithQueue;\n\n    public function __construct()\n    {\n        $this->onQueue('test-queue-two');\n    }\n}\n\nclass JobWithoutDefaultQueue implements ShouldQueue\n{\n    use Queueable, InteractsWithQueue;\n}\n\nclass JobWithDefaultConnection implements ShouldQueue\n{\n    use Queueable, InteractsWithQueue;\n\n    public function __construct()\n    {\n        $this->onConnection('test-connection');\n    }\n}\n\nclass JobWithoutDefaultConnection implements ShouldQueue\n{\n    use Queueable, InteractsWithQueue;\n}\n"
  },
  {
    "path": "tests/Integration/Console/PromptsAssertionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Laravel\\Prompts\\confirm;\nuse function Laravel\\Prompts\\multisearch;\nuse function Laravel\\Prompts\\multiselect;\nuse function Laravel\\Prompts\\password;\nuse function Laravel\\Prompts\\pause;\nuse function Laravel\\Prompts\\search;\nuse function Laravel\\Prompts\\select;\nuse function Laravel\\Prompts\\suggest;\nuse function Laravel\\Prompts\\text;\nuse function Laravel\\Prompts\\textarea;\n\nclass PromptsAssertionTest extends TestCase\n{\n    public function testAssertionForTextPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:text';\n\n                public function handle()\n                {\n                    $name = text('What is your name?', 'John');\n\n                    $this->line($name);\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:text')\n            ->expectsQuestion('What is your name?', 'Jane')\n            ->expectsOutput('Jane');\n    }\n\n    public function testAssertionForPausePrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class($this) extends Command\n            {\n                protected $signature = 'test:pause';\n\n                public function __construct(public PromptsAssertionTest $test)\n                {\n                    parent::__construct();\n                }\n\n                public function handle()\n                {\n                    $value = pause('Press any key to continue...');\n                    $this->test->assertEquals(true, $value);\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:pause')\n            ->expectsQuestion('Press any key to continue...', '');\n    }\n\n    public function testAssertionForTextareaPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:textarea';\n\n                public function handle()\n                {\n                    $name = textarea('What is your name?', 'John');\n\n                    $this->line($name);\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:textarea')\n            ->expectsQuestion('What is your name?', 'Jane')\n            ->expectsOutput('Jane');\n    }\n\n    public function testAssertionForSuggestPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:suggest';\n\n                public function handle()\n                {\n                    $name = suggest('What is your name?', ['John', 'Jane']);\n\n                    $this->line($name);\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:suggest')\n            ->expectsChoice('What is your name?', 'Joe', ['John', 'Jane'])\n            ->expectsOutput('Joe');\n    }\n\n    public function testAssertionForPasswordPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:password';\n\n                public function handle()\n                {\n                    $name = password('What is your password?');\n\n                    $this->line($name);\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:password')\n            ->expectsQuestion('What is your password?', 'secret')\n            ->expectsOutput('secret');\n    }\n\n    public function testAssertionForConfirmPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:confirm';\n\n                public function handle()\n                {\n                    $confirmed = confirm('Is your name John?');\n\n                    if ($confirmed) {\n                        $this->line('Your name is John.');\n                    } else {\n                        $this->line('Your name is not John.');\n                    }\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:confirm')\n            ->expectsConfirmation('Is your name John?', 'no')\n            ->expectsOutput('Your name is not John.');\n\n        $this\n            ->artisan('test:confirm')\n            ->expectsConfirmation('Is your name John?', 'yes')\n            ->expectsOutput('Your name is John.');\n    }\n\n    public function testAssertionForSelectPromptWithAList(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:select';\n\n                public function handle()\n                {\n                    $name = select(\n                        label: 'What is your name?',\n                        options: ['John', 'Jane']\n                    );\n\n                    $this->line(\"Your name is $name.\");\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:select')\n            ->expectsChoice('What is your name?', 'Jane', ['John', 'Jane'])\n            ->expectsOutput('Your name is Jane.');\n    }\n\n    public function testAssertionForSelectPromptWithAnAssociativeArray(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:select';\n\n                public function handle()\n                {\n                    $name = select(\n                        label: 'What is your name?',\n                        options: ['john' => 'John', 'jane' => 'Jane']\n                    );\n\n                    $this->line(\"Your name is $name.\");\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:select')\n            ->expectsChoice('What is your name?', 'jane', ['john' => 'John', 'jane' => 'Jane'])\n            ->expectsOutput('Your name is jane.');\n    }\n\n    public function testAlternativeAssertionForSelectPromptWithAnAssociativeArray(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:select';\n\n                public function handle()\n                {\n                    $name = select(\n                        label: 'What is your name?',\n                        options: ['john' => 'John', 'jane' => 'Jane']\n                    );\n\n                    $this->line(\"Your name is $name.\");\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:select')\n            ->expectsChoice('What is your name?', 'jane', ['john', 'jane', 'John', 'Jane'])\n            ->expectsOutput('Your name is jane.');\n    }\n\n    public function testAssertionForRequiredMultiselectPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:multiselect';\n\n                public function handle()\n                {\n                    $names = multiselect(\n                        label: 'Which names do you like?',\n                        options: ['John', 'Jane', 'Sally', 'Jack'],\n                        required: true\n                    );\n\n                    $this->line(sprintf('You like %s.', implode(', ', $names)));\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:multiselect')\n            ->expectsChoice('Which names do you like?', ['John', 'Jane'], ['John', 'Jane', 'Sally', 'Jack'])\n            ->expectsOutput('You like John, Jane.');\n    }\n\n    public function testAssertionForOptionalMultiselectPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:multiselect';\n\n                public function handle()\n                {\n                    $names = multiselect(\n                        label: 'Which names do you like?',\n                        options: ['John', 'Jane', 'Sally', 'Jack'],\n                    );\n\n                    if (empty($names)) {\n                        $this->line('You like nobody.');\n                    } else {\n                        $this->line(sprintf('You like %s.', implode(', ', $names)));\n                    }\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:multiselect')\n            ->expectsChoice('Which names do you like?', ['John', 'Jane'], ['John', 'Jane', 'Sally', 'Jack'])\n            ->expectsOutput('You like John, Jane.');\n\n        $this\n            ->artisan('test:multiselect')\n            ->expectsChoice('Which names do you like?', ['None'], ['John', 'Jane', 'Sally', 'Jack'])\n            ->expectsOutput('You like nobody.');\n    }\n\n    public function testAssertionForSearchPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:search';\n\n                public function handle()\n                {\n                    $options = collect(['John', 'Jane', 'Sally', 'Jack']);\n\n                    $name = search(\n                        label: 'What is your name?',\n                        options: fn (string $value) => strlen($value) > 0\n                            ? $options->filter(fn ($title) => str_contains($title, $value))->values()->toArray()\n                            : []\n                    );\n\n                    $this->line(\"Your name is $name.\");\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:search')\n            ->expectsSearch('What is your name?', 'Jane', 'J', ['John', 'Jane', 'Jack'])\n            ->expectsOutput('Your name is Jane.');\n    }\n\n    public function testAssertionForMultisearchPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:multisearch';\n\n                public function handle()\n                {\n                    $options = collect(['John', 'Jane', 'Sally', 'Jack']);\n\n                    $names = multisearch(\n                        label: 'Which names do you like?',\n                        options: fn (string $value) => strlen($value) > 0\n                            ? $options->filter(fn ($title) => str_contains($title, $value))->values()->toArray()\n                            : []\n                    );\n\n                    if (empty($names)) {\n                        $this->line('You like nobody.');\n                    } else {\n                        $this->line(sprintf('You like %s.', implode(', ', $names)));\n                    }\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:multisearch')\n            ->expectsSearch('Which names do you like?', ['John', 'Jane'], 'J', ['John', 'Jane', 'Jack'])\n            ->expectsOutput('You like John, Jane.');\n\n        $this\n            ->artisan('test:multisearch')\n            ->expectsSearch('Which names do you like?', [], 'J', ['John', 'Jane', 'Jack'])\n            ->expectsOutput('You like nobody.');\n    }\n\n    public function testAssertionForSelectPromptFollowedByMultisearchPrompt(): void\n    {\n        $this->app[Kernel::class]->registerCommand(\n            new class extends Command\n            {\n                protected $signature = 'test:select';\n\n                public function handle()\n                {\n                    $name = select(\n                        label: 'What is your name?',\n                        options: ['John', 'Jane']\n                    );\n\n                    $titles = collect(['Mr', 'Mrs', 'Ms', 'Dr']);\n                    $title = multisearch(\n                        label: 'What is your title?',\n                        options: fn (string $value) => strlen($value) > 0\n                            ? $titles->filter(fn ($title) => str_contains($title, $value))->values()->toArray()\n                            : []\n                    );\n\n                    $this->line('I will refer to you '.$title[0].' '.$name.'.');\n                }\n            }\n        );\n\n        $this\n            ->artisan('test:select')\n            ->expectsChoice('What is your name?', 'Jane', ['John', 'Jane'])\n            ->expectsSearch('What is your title?', ['Dr'], 'D', ['Dr'])\n            ->expectsOutput('I will refer to you Dr Jane.');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/PromptsValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Contracts\\Console\\Kernel;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Laravel\\Prompts\\text;\n\nclass PromptsValidationTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app[Kernel::class]->registerCommand(new DummyPromptsValidationCommand());\n        $app[Kernel::class]->registerCommand(new DummyPromptsWithLaravelRulesCommand());\n        $app[Kernel::class]->registerCommand(new DummyPromptsWithLaravelRulesMessagesAndAttributesCommand());\n        $app[Kernel::class]->registerCommand(new DummyPromptsWithLaravelRulesCommandWithInlineMessagesAndAttributesCommand());\n    }\n\n    public function testValidationForPrompts(): void\n    {\n        $this\n            ->artisan(DummyPromptsValidationCommand::class)\n            ->expectsQuestion('What is your name?', '')\n            ->expectsOutputToContain('Required!');\n    }\n\n    public function testValidationWithLaravelRulesAndNoCustomization(): void\n    {\n        $this\n            ->artisan(DummyPromptsWithLaravelRulesCommand::class)\n            ->expectsQuestion('What is your name?', '')\n            ->expectsOutputToContain('The answer field is required.');\n    }\n\n    public function testValidationWithLaravelRulesInlineMessagesAndAttributes(): void\n    {\n        $this\n            ->artisan(DummyPromptsWithLaravelRulesCommandWithInlineMessagesAndAttributesCommand::class)\n            ->expectsQuestion('What is your name?', '')\n            ->expectsOutputToContain('Your full name is mandatory.');\n    }\n\n    public function testValidationWithLaravelRulesMessagesAndAttributes(): void\n    {\n        $this\n            ->artisan(DummyPromptsWithLaravelRulesMessagesAndAttributesCommand::class)\n            ->expectsQuestion('What is your name?', '')\n            ->expectsOutputToContain('Your full name is mandatory.');\n    }\n}\n\nclass DummyPromptsValidationCommand extends Command\n{\n    protected $signature = 'prompts-validation-test';\n\n    public function handle()\n    {\n        text('What is your name?', validate: fn ($value) => $value == '' ? 'Required!' : null);\n    }\n}\n\nclass DummyPromptsWithLaravelRulesCommand extends Command\n{\n    protected $signature = 'prompts-laravel-rules-test';\n\n    public function handle()\n    {\n        text('What is your name?', validate: 'required');\n    }\n}\n\nclass DummyPromptsWithLaravelRulesCommandWithInlineMessagesAndAttributesCommand extends Command\n{\n    protected $signature = 'prompts-laravel-rules-inline-test';\n\n    public function handle()\n    {\n        text('What is your name?', validate: literal(\n            rules: ['name' => 'required'],\n            messages: ['name.required' => 'Your :attribute is mandatory.'],\n            attributes: ['name' => 'full name'],\n        ));\n    }\n}\n\nclass DummyPromptsWithLaravelRulesMessagesAndAttributesCommand extends Command\n{\n    protected $signature = 'prompts-laravel-rules-messages-attributes-test';\n\n    public function handle()\n    {\n        text('What is your name?', validate: ['name' => 'required']);\n    }\n\n    protected function validationMessages()\n    {\n        return ['name.required' => 'Your :attribute is mandatory.'];\n    }\n\n    protected function validationAttributes()\n    {\n        return ['name' => 'full name'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/CallbackEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Exception;\nuse Illuminate\\Console\\Scheduling\\CallbackEvent;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CallbackEventTest extends TestCase\n{\n    public function testDefaultResultIsSuccess()\n    {\n        $success = null;\n\n        $event = (new CallbackEvent(m::mock(EventMutex::class), function () {\n        }))->onSuccess(function () use (&$success) {\n            $success = true;\n        })->onFailure(function () use (&$success) {\n            $success = false;\n        });\n\n        $event->run($this->app);\n\n        $this->assertTrue($success);\n    }\n\n    public function testFalseResponseIsFailure()\n    {\n        $success = null;\n\n        $event = (new CallbackEvent(m::mock(EventMutex::class), function () {\n            return false;\n        }))->onSuccess(function () use (&$success) {\n            $success = true;\n        })->onFailure(function () use (&$success) {\n            $success = false;\n        });\n\n        $event->run($this->app);\n\n        $this->assertFalse($success);\n    }\n\n    public function testExceptionIsFailure()\n    {\n        $success = null;\n\n        $event = (new CallbackEvent(m::mock(EventMutex::class), function () {\n            throw new Exception;\n        }))->onSuccess(function () use (&$success) {\n            $success = true;\n        })->onFailure(function () use (&$success) {\n            $success = false;\n        });\n\n        try {\n            $event->run($this->app);\n        } catch (Exception) {\n        }\n\n        $this->assertFalse($success);\n    }\n\n    public function testExceptionBubbles()\n    {\n        $event = new CallbackEvent(m::mock(EventMutex::class), function () {\n            throw new Exception;\n        });\n\n        $this->expectException(Exception::class);\n\n        $event->run($this->app);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/EventPingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse GuzzleHttp\\Client as HttpClient;\nuse GuzzleHttp\\Exception\\ServerException;\nuse GuzzleHttp\\Handler\\MockHandler;\nuse GuzzleHttp\\HandlerStack;\nuse GuzzleHttp\\Psr7\\Response as Psr7Response;\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Console\\Scheduling\\EventMutex;\nuse Illuminate\\Contracts\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EventPingTest extends TestCase\n{\n    public function testPingRescuesTransferExceptions()\n    {\n        $this->spy(ExceptionHandler::class)\n            ->shouldReceive('report')\n            ->once()\n            ->with(m::type(ServerException::class));\n\n        $httpMock = new HttpClient([\n            'handler' => HandlerStack::create(\n                new MockHandler([new Psr7Response(500)])\n            ),\n        ]);\n\n        $this->swap(HttpClient::class, $httpMock);\n\n        $event = new Event(m::mock(EventMutex::class), 'php -i');\n\n        $thenCalled = false;\n\n        $event->pingBefore('https://httpstat.us/500')\n            ->then(function () use (&$thenCalled) {\n                $thenCalled = true;\n            });\n\n        $event->callBeforeCallbacks($this->app->make(Container::class));\n        $event->callAfterCallbacks($this->app->make(Container::class));\n\n        $this->assertTrue($thenCalled);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/ScheduleGroupTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Scheduling\\Event;\nuse Illuminate\\Console\\Scheduling\\Schedule as ScheduleClass;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schedule;\nuse Illuminate\\Tests\\Console\\Fixtures\\JobToTestWithSchedule;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass ScheduleGroupTest extends TestCase\n{\n    public function testGroupCanSetScheduleCronExpression()\n    {\n        $schedule = new ScheduleClass;\n\n        $schedule\n            ->daily()\n            ->group(function (ScheduleClass $schedule) {\n                $schedule->command('inspire');\n            });\n\n        $events = $schedule->events();\n        $this->assertSame('0 0 * * *', $events[0]->expression);\n    }\n\n    public function testGroupedScheduleCanOverrideGroupCronExpression()\n    {\n        Schedule::daily()->group(function () {\n            Schedule::command('inspire');\n            Schedule::command('inspire')\n                ->twiceDaily();\n        });\n\n        $events = Schedule::events();\n        $this->assertSame('0 0 * * *', $events[0]->expression);\n        $this->assertSame('0 1,13 * * *', $events[1]->expression);\n    }\n\n    public function testGroupCanSetScheduleRepeatSeconds()\n    {\n        Schedule::everyMinute()\n            ->everyThirtySeconds()\n            ->group(function () {\n                Schedule::command('inspire');\n            });\n\n        $events = Schedule::events();\n        $this->assertSame(30, $events[0]->repeatSeconds);\n        $this->assertSame('* * * * *', $events[0]->expression);\n    }\n\n    public function testGroupedScheduleCanOverrideGroupRepeatSeconds()\n    {\n        Schedule::everyMinute()\n            ->everyThirtySeconds()\n            ->group(function () {\n                Schedule::command('inspire');\n                Schedule::command('inspire')\n                    ->everyTwentySeconds();\n            });\n\n        $events = Schedule::events();\n        $this->assertSame(30, $events[0]->repeatSeconds);\n        $this->assertSame('* * * * *', $events[0]->expression);\n\n        $this->assertSame(20, $events[1]->repeatSeconds);\n        $this->assertSame('* * * * *', $events[1]->expression);\n    }\n\n    public function testGroupedScheduleCanBeNested()\n    {\n        Schedule::daily()\n            ->timezone('UTC')\n            ->group(function () {\n                Schedule::command('inspire');\n                Schedule::timezone('Asia/Dhaka')->group(function () {\n                    Schedule::command('inspire');\n                });\n            });\n\n        $events = Schedule::events();\n        $this->assertSame('UTC', $events[0]->timezone);\n        $this->assertSame('Asia/Dhaka', $events[1]->timezone);\n    }\n\n    #[DataProvider('groupAttributes')]\n    public function testGroupCanApplyAttributeToSchedules(string $property, mixed $value)\n    {\n        Schedule::$property($value)->group(function () {\n            Schedule::command('inspire');\n        });\n\n        $events = Schedule::events();\n\n        if ($property !== 'withoutOverlapping') {\n            $this->assertSame($value, $events[0]->$property);\n        } else {\n            $this->assertSame($value, $events[0]->expiresAt);\n            $this->assertTrue($events[0]->withoutOverlapping);\n        }\n    }\n\n    public static function groupAttributes(): array\n    {\n        return [\n            'user' => ['user', fake()->userName()],\n            'timezone' => ['timezone', fake()->timezone()],\n            'onOneServer' => ['onOneServer', true],\n            'environments' => [\n                'environments',\n                fake()->randomElements(['local', 'production', 'testing', 'staging'], 2),\n            ],\n            'runInBackground' => ['runInBackground', true],\n            'evenInMaintenanceMode' => ['evenInMaintenanceMode', true],\n            'evenWhenPaused' => ['evenWhenPaused', true],\n            'withoutOverlapping' => ['withoutOverlapping', rand(1000, 1400)],\n        ];\n    }\n\n    #[DataProvider('scheduleTestCases')]\n    public function testGroupedScheduleExecution($time, $expected, $description)\n    {\n        Carbon::setTestNow($time);\n        $app = app();\n\n        Schedule::days([1, 2, 3, 4, 5, 6])->group(function () {\n            Schedule::between('07:00', '08:00')->group(function () {\n                Schedule::call(fn () => 'Task 1')->everyMinute();\n                Schedule::call(fn () => 'Task 2')->everyFiveMinutes();\n            });\n\n            Schedule::call(fn () => 'Task 3')->at('08:05');\n        });\n\n        $events = Schedule::events();\n\n        foreach (array_keys($expected) as $index => $task) {\n            $this->assertTaskExecution(\n                $events[$index],\n                $app,\n                $expected[$task],\n                \"[$description] $task should \".($expected[$task] ? 'run' : 'not run')\n            );\n        }\n\n        Carbon::setTestNow();\n    }\n\n    private function assertTaskExecution($event, $app, $expected, $message): void\n    {\n        $this->assertSame(\n            $expected,\n            $event->filtersPass($app) && $event->isDue($app),\n            $message\n        );\n    }\n\n    public static function scheduleTestCases()\n    {\n        return [\n            [\n                Carbon::create(2024, 1, 1, 7, 30),\n                [\n                    'Task 1' => true,\n                    'Task 2' => true,\n                    'Task 3' => false,\n                ],\n                'Tasks at 07:30',\n            ],\n            [\n                Carbon::create(2024, 1, 1, 8, 5),\n                [\n                    'Task 1' => false,\n                    'Task 2' => false,\n                    'Task 3' => true,\n                ],\n                'Tasks at 08:05',\n            ],\n        ];\n    }\n\n    public function testGroupedPendingEventAttribute()\n    {\n        $schedule = new ScheduleClass;\n        $schedule->weekdays()->group(function ($schedule) {\n            $schedule->command('inspire')->at('00:00'); // this is event, not pending attribute\n            $schedule->at('01:00')->command('inspire'); // this is pending attribute\n            $schedule->command('inspire');  // this goes back to group pending attribute\n        });\n\n        $events = $schedule->events();\n        $this->assertSame('0 0 * * 1-5', $events[0]->expression);\n        $this->assertSame('0 1 * * 1-5', $events[1]->expression);\n        $this->assertSame('* * * * 1-5', $events[2]->expression);\n    }\n\n    public function testGroupedPendingEventAttributesWithoutOverlapping()\n    {\n        $schedule = new ScheduleClass;\n        $schedule->weekdays()->withoutOverlapping()->group(function ($schedule) {\n            $schedule->command('inspire')->at('14:00'); // this is event, not pending attribute\n            $schedule->at('03:00')->command('inspire'); // this is pending attribute\n            $schedule->command('inspire');  // this goes back to group pending attribute\n            $schedule->job(JobToTestWithSchedule::class)->at('04:00');  // this is pending attribute\n        });\n\n        $events = $schedule->events();\n        $this->assertSame('0 14 * * 1-5', $events[0]->expression);\n        $this->assertSame('0 3 * * 1-5', $events[1]->expression);\n        $this->assertSame('* * * * 1-5', $events[2]->expression);\n        $this->assertSame('0 4 * * 1-5', $events[3]->expression);\n    }\n\n    public function testGroupAppliesEventMacrosToAllEvents()\n    {\n        Event::macro('sentryMonitor', function () {\n            $this->sentryMonitored = true;\n\n            return $this;\n        });\n\n        $schedule = new ScheduleClass;\n        $schedule->daily()->sentryMonitor()->group(function ($schedule) {\n            $schedule->command('inspire');\n            $schedule->command('inspire');\n        });\n\n        $events = $schedule->events();\n        $this->assertTrue($events[0]->sentryMonitored);\n        $this->assertTrue($events[1]->sentryMonitored);\n        $this->assertSame('0 0 * * *', $events[0]->expression);\n        $this->assertSame('0 0 * * *', $events[1]->expression);\n\n        Event::flushMacros();\n    }\n\n    public function testGroupAppliesEventMacroCalledBeforeBuiltInAttributes()\n    {\n        Event::macro('sentryMonitor', function () {\n            $this->sentryMonitored = true;\n\n            return $this;\n        });\n\n        $schedule = new ScheduleClass;\n        $schedule->sentryMonitor()->daily()->onOneServer()->group(function ($schedule) {\n            $schedule->command('inspire');\n        });\n\n        $events = $schedule->events();\n        $this->assertTrue($events[0]->sentryMonitored);\n        $this->assertTrue($events[0]->onOneServer);\n        $this->assertSame('0 0 * * *', $events[0]->expression);\n\n        Event::flushMacros();\n    }\n\n    public function testGroupAppliesMultipleEventMacros()\n    {\n        Event::macro('sentryMonitor', function () {\n            $this->sentryMonitored = true;\n\n            return $this;\n        });\n\n        Event::macro('customTag', function ($tag) {\n            $this->customTag = $tag;\n\n            return $this;\n        });\n\n        $schedule = new ScheduleClass;\n        $schedule->daily()->sentryMonitor()->customTag('billing')->group(function ($schedule) {\n            $schedule->command('inspire');\n            $schedule->command('inspire');\n        });\n\n        $events = $schedule->events();\n        $this->assertTrue($events[0]->sentryMonitored);\n        $this->assertSame('billing', $events[0]->customTag);\n        $this->assertTrue($events[1]->sentryMonitored);\n        $this->assertSame('billing', $events[1]->customTag);\n\n        Event::flushMacros();\n    }\n\n    public function testNestedGroupInheritsEventMacros()\n    {\n        Event::macro('sentryMonitor', function () {\n            $this->sentryMonitored = true;\n\n            return $this;\n        });\n\n        $schedule = new ScheduleClass;\n        $schedule->daily()->sentryMonitor()->group(function ($schedule) {\n            $schedule->command('inspire');\n            $schedule->weekly()->group(function ($schedule) {\n                $schedule->command('inspire');\n            });\n        });\n\n        $events = $schedule->events();\n        $this->assertTrue($events[0]->sentryMonitored);\n        $this->assertSame('0 0 * * *', $events[0]->expression);\n        $this->assertTrue($events[1]->sentryMonitored);\n        $this->assertSame('0 0 * * 0', $events[1]->expression);\n\n        Event::flushMacros();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/ScheduleListCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Console\\Scheduling\\ScheduleListCommand;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Illuminate\\Support\\ProcessUtils;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ScheduleListCommandTest extends TestCase\n{\n    public $schedule;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Carbon::setTestNow('2023-01-01');\n        ScheduleListCommand::resolveTerminalWidthUsing(fn () => 80);\n\n        $this->schedule = $this->app->make(Schedule::class);\n    }\n\n    public function testDisplayEmptySchedule()\n    {\n        $this->artisan(ScheduleListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain('No scheduled tasks have been defined.');\n    }\n\n    public function testDisplayEmptyScheduleAsJson()\n    {\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, ['--json' => true]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $this->assertJsonStringEqualsJsonString('[]', $output);\n    }\n\n    public function testDisplaySchedule()\n    {\n        $this->schedule->command(FooCommand::class)->quarterly();\n        $this->schedule->command('inspire')->twiceDaily(14, 18);\n        $this->schedule->command('foobar', ['a' => 'b'])->everyMinute();\n        $this->schedule->job(FooJob::class)->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->everyMinute();\n        $this->schedule->job(FooJob::class)->name('foo-named-job')->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->name('foo-named-param-job')->everyMinute();\n        $this->schedule->command('inspire')->cron('0 9,17 * * *');\n        $this->schedule->command('inspire')->cron(\"0 10\\t* * *\");\n        $this->schedule->call(FooCall::class)->everyMinute();\n        $this->schedule->call([FooCall::class, 'fooFunction'])->everyMinute();\n\n        $this->schedule->call(fn () => '')->everyMinute();\n        $closureLineNumber = __LINE__ - 1;\n        $closureFilePath = __FILE__;\n\n        $this->artisan(ScheduleListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutput('  0 0     1 1-12/3 *  php artisan foo:command .... Next Due: 3 months from now')\n            ->expectsOutput('  0 14,18 * *      *  php artisan inspire ........ Next Due: 14 hours from now')\n            ->expectsOutput('  * *     * *      *  php artisan foobar a='.ProcessUtils::escapeArgument('b').' ... Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooJob  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooParamJob  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  foo-named-job .............. Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  foo-named-param-job ........ Next Due: 1 minute from now')\n            ->expectsOutput('  0 9,17  * *      *  php artisan inspire ......... Next Due: 9 hours from now')\n            ->expectsOutput('  0 10    * *      *  php artisan inspire ........ Next Due: 10 hours from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooCall  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Closure at: Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooCall::fooFunction  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Closure at: '.$closureFilePath.':'.$closureLineNumber.'  Next Due: 1 minute from now');\n    }\n\n    public function testDisplayScheduleAsJson()\n    {\n        $this->schedule->command(FooCommand::class)->quarterly();\n        $this->schedule->command('inspire')->twiceDaily(14, 18);\n        $this->schedule->command('foobar', ['a' => 'b'])->everyMinute();\n        $this->schedule->job(FooJob::class)->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->everyMinute();\n        $this->schedule->job(FooJob::class)->name('foo-named-job')->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->name('foo-named-param-job')->everyMinute();\n        $this->schedule->command('inspire')->cron('0 9,17 * * *');\n        $this->schedule->call(fn () => '')->everyMinute();\n\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, ['--json' => true]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $data = json_decode($output, true);\n\n        $this->assertIsArray($data);\n        $this->assertCount(9, $data);\n\n        $this->assertSame('0 0 1 1-12/3 *', $data[0]['expression']);\n        $this->assertNull($data[0]['repeat_seconds']);\n        $this->assertSame('php artisan foo:command', $data[0]['command']);\n        $this->assertSame('This is the description of the command.', $data[0]['description']);\n        $this->assertStringContainsString('2023-04-01 00:00:00', $data[0]['next_due_date']);\n        $this->assertSame('3 months from now', $data[0]['next_due_date_human']);\n        $this->assertFalse($data[0]['has_mutex']);\n        $this->assertIsArray($data[0]['environments']);\n        $this->assertEmpty($data[0]['environments']);\n\n        $this->assertSame('* * * * *', $data[2]['expression']);\n        $this->assertSame('php artisan foobar a='.ProcessUtils::escapeArgument('b'), $data[2]['command']);\n        $this->assertNull($data[2]['description']);\n        $this->assertSame('1 minute from now', $data[2]['next_due_date_human']);\n\n        $this->assertSame('Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooJob', $data[3]['command']);\n\n        $this->assertSame('foo-named-job', $data[5]['command']);\n\n        $this->assertStringContainsString('Closure at:', $data[8]['command']);\n        $this->assertStringContainsString('ScheduleListCommandTest.php', $data[8]['command']);\n    }\n\n    public function testDisplayScheduleAsJsonWithSpecificEnvironment()\n    {\n        $environment = 'production';\n        $this->schedule->command(FooCommand::class)->quarterly()->environments($environment);\n\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, ['--json' => true]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $data = json_decode($output, true);\n        $this->assertIsArray($data);\n        $this->assertCount(1, $data);\n\n        $this->assertIsArray($data[0]['environments']);\n        $this->assertNotEmpty($data[0]['environments']);\n        $this->assertContains($environment, $data[0]['environments']);\n    }\n\n    public function testDisplayScheduleWithSortAsJson()\n    {\n        $this->schedule->command(FooCommand::class)->quarterly();\n        $this->schedule->command('inspire')->twiceDaily(14, 18);\n        $this->schedule->command('foobar', ['a' => 'b'])->everyMinute();\n\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, [\n            '--next' => true,\n            '--json' => true,\n        ]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $data = json_decode($output, true);\n\n        $this->assertIsArray($data);\n        $this->assertCount(3, $data);\n\n        $this->assertSame('* * * * *', $data[0]['expression']);\n        $this->assertSame('1 minute from now', $data[0]['next_due_date_human']);\n        $this->assertSame('php artisan foobar a='.ProcessUtils::escapeArgument('b'), $data[0]['command']);\n\n        $this->assertSame('0 14,18 * * *', $data[1]['expression']);\n        $this->assertSame('14 hours from now', $data[1]['next_due_date_human']);\n        $this->assertSame('php artisan inspire', $data[1]['command']);\n\n        $this->assertSame('0 0 1 1-12/3 *', $data[2]['expression']);\n        $this->assertSame('3 months from now', $data[2]['next_due_date_human']);\n        $this->assertSame('php artisan foo:command', $data[2]['command']);\n    }\n\n    public function testDisplayScheduleAsJsonWithTimezone()\n    {\n        $this->schedule->command('inspire')->daily();\n\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, [\n            '--timezone' => 'America/Chicago',\n            '--json' => true,\n        ]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $data = json_decode($output, true);\n\n        $this->assertIsArray($data);\n        $this->assertCount(1, $data);\n        $this->assertSame('America/Chicago', $data[0]['timezone']);\n        $this->assertStringContainsString('-06:00', $data[0]['next_due_date']);\n        $this->assertSame('php artisan inspire', $data[0]['command']);\n    }\n\n    public function testDisplayScheduleAsJsonInVerboseMode()\n    {\n        $this->schedule->command(FooCommand::class)->quarterly();\n        $this->schedule->command('inspire')->everyMinute();\n        $this->schedule->call(fn () => '')->everyMinute();\n\n        $this->withoutMockingConsoleOutput()->artisan(ScheduleListCommand::class, [\n            '--json' => true,\n            '-v' => true,\n        ]);\n        $output = Artisan::output();\n\n        $this->assertJson($output);\n        $data = json_decode($output, true);\n\n        $this->assertIsArray($data);\n        $this->assertCount(3, $data);\n\n        $this->assertSame('0 0 1 1-12/3 *', $data[0]['expression']);\n        $this->assertSame(Application::phpBinary().' '.Application::artisanBinary().' foo:command', $data[0]['command']);\n        $this->assertSame('This is the description of the command.', $data[0]['description']);\n\n        $this->assertSame('* * * * *', $data[1]['expression']);\n        $this->assertSame(Application::phpBinary().' '.Application::artisanBinary().' inspire', $data[1]['command']);\n\n        $this->assertStringContainsString('Closure at:', $data[2]['command']);\n        $this->assertStringContainsString('ScheduleListCommandTest.php', $data[2]['command']);\n    }\n\n    public function testDisplayScheduleWithSort()\n    {\n        $this->schedule->command(FooCommand::class)->quarterly();\n        $this->schedule->command('inspire')->twiceDaily(14, 18);\n        $this->schedule->command('foobar', ['a' => 'b'])->everyMinute();\n        $this->schedule->job(FooJob::class)->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->everyMinute();\n        $this->schedule->job(FooJob::class)->name('foo-named-job')->everyMinute();\n        $this->schedule->job(new FooParamJob('test'))->name('foo-named-param-job')->everyMinute();\n        $this->schedule->command('inspire')->cron('0 9,17 * * *');\n        $this->schedule->command('inspire')->cron(\"0 10\\t* * *\");\n        $this->schedule->call(FooCall::class)->everyMinute();\n        $this->schedule->call([FooCall::class, 'fooFunction'])->everyMinute();\n\n        $this->schedule->call(fn () => '')->everyMinute();\n        $closureLineNumber = __LINE__ - 1;\n        $closureFilePath = __FILE__;\n\n        $this->artisan(ScheduleListCommand::class, ['--next' => true])\n            ->assertSuccessful()\n            ->expectsOutput('  * *     * *      *  php artisan foobar a='.ProcessUtils::escapeArgument('b').' ... Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooJob  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooParamJob  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  foo-named-job .............. Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  foo-named-param-job ........ Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooCall  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Closure at: Illuminate\\Tests\\Integration\\Console\\Scheduling\\FooCall::fooFunction  Next Due: 1 minute from now')\n            ->expectsOutput('  * *     * *      *  Closure at: '.$closureFilePath.':'.$closureLineNumber.'  Next Due: 1 minute from now')\n            ->expectsOutput('  0 9,17  * *      *  php artisan inspire ......... Next Due: 9 hours from now')\n            ->expectsOutput('  0 10    * *      *  php artisan inspire ........ Next Due: 10 hours from now')\n            ->expectsOutput('  0 14,18 * *      *  php artisan inspire ........ Next Due: 14 hours from now')\n            ->expectsOutput('  0 0     1 1-12/3 *  php artisan foo:command .... Next Due: 3 months from now');\n    }\n\n    public function testDisplayScheduleInVerboseMode()\n    {\n        $this->schedule->command(FooCommand::class)->everyMinute();\n\n        $this->artisan(ScheduleListCommand::class, ['-v' => true])\n            ->assertSuccessful()\n            ->expectsOutputToContain('Next Due: '.Carbon::now()->setMinutes(1)->format('Y-m-d H:i:s P'))\n            ->expectsOutput('             ⇁ This is the description of the command.');\n    }\n\n    public function testDisplayScheduleSubMinute()\n    {\n        $this->schedule->command('inspire')->weekly()->everySecond();\n        $this->schedule->command('inspire')->everyTwoSeconds();\n        $this->schedule->command('inspire')->everyFiveSeconds();\n        $this->schedule->command('inspire')->everyTenSeconds();\n        $this->schedule->command('inspire')->everyFifteenSeconds();\n        $this->schedule->command('inspire')->everyTwentySeconds();\n        $this->schedule->command('inspire')->everyThirtySeconds();\n\n        $this->artisan(ScheduleListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutput('  * 0 * * 0 1s   php artisan inspire ............. Next Due: 1 second from now')\n            ->expectsOutput('  * * * * * 2s   php artisan inspire ............ Next Due: 2 seconds from now')\n            ->expectsOutput('  * * * * * 5s   php artisan inspire ............ Next Due: 5 seconds from now')\n            ->expectsOutput('  * * * * * 10s  php artisan inspire ........... Next Due: 10 seconds from now')\n            ->expectsOutput('  * * * * * 15s  php artisan inspire ........... Next Due: 15 seconds from now')\n            ->expectsOutput('  * * * * * 20s  php artisan inspire ........... Next Due: 20 seconds from now')\n            ->expectsOutput('  * * * * * 30s  php artisan inspire ........... Next Due: 30 seconds from now');\n    }\n\n    public function testClosureCommandsMayBeScheduled()\n    {\n        $closure = function () {\n        };\n\n        Artisan::command('one', $closure)->weekly()->everySecond();\n        Artisan::command('two', $closure)->everyTwoSeconds();\n        Artisan::command('three', $closure)->everyFiveSeconds();\n        Artisan::command('four', $closure)->everyTenSeconds();\n        Artisan::command('five', $closure)->everyFifteenSeconds();\n        Artisan::command('six', $closure)->everyTwentySeconds()->hourly();\n        Artisan::command('six', $closure)->everyThreeHours()->everySecond();\n\n        $this->artisan(ScheduleListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutput('  * 0   * * 0 1s   php artisan one ............... Next Due: 1 second from now')\n            ->expectsOutput('  * *   * * * 2s   php artisan two .............. Next Due: 2 seconds from now')\n            ->expectsOutput('  * *   * * * 5s   php artisan three ............ Next Due: 5 seconds from now')\n            ->expectsOutput('  * *   * * * 10s  php artisan four ............ Next Due: 10 seconds from now')\n            ->expectsOutput('  * *   * * * 15s  php artisan five ............ Next Due: 15 seconds from now')\n            ->expectsOutput('  0 *   * * * 20s  php artisan six ............. Next Due: 20 seconds from now')\n            ->expectsOutput('  * */3 * * * 1s   php artisan six ............... Next Due: 1 second from now');\n    }\n\n    protected function tearDown(): void\n    {\n        putenv('SHELL_VERBOSITY');\n\n        parent::tearDown();\n    }\n}\n\nclass FooCommand extends Command\n{\n    protected $signature = 'foo:command';\n\n    protected $description = 'This is the description of the command.';\n}\n\nclass FooJob\n{\n}\n\nclass FooParamJob\n{\n    public function __construct($param)\n    {\n    }\n}\n\nclass FooCall\n{\n    public function __invoke(): void\n    {\n    }\n\n    public function fooFunction(): void\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/SchedulePauseCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Events\\SchedulePaused;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SchedulePauseCommandTest extends TestCase\n{\n    public function testDispatchesEvent()\n    {\n        Event::fake();\n\n        $this->artisan('schedule:pause');\n\n        Event::assertDispatched(SchedulePaused::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/ScheduleResumeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Events\\ScheduleResumed;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ScheduleResumeCommandTest extends TestCase\n{\n    public function testDispatchesEvent()\n    {\n        Event::fake();\n\n        $this->artisan('schedule:resume');\n\n        Event::assertDispatched(ScheduleResumed::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/ScheduleRunCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Events\\ScheduledTaskFailed;\nuse Illuminate\\Console\\Events\\ScheduledTaskFinished;\nuse Illuminate\\Console\\Events\\ScheduledTaskStarting;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Container\\BindingResolutionException;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ScheduleRunCommandTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n        Carbon::setTestNow(Carbon::now());\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_failing_command_in_foreground_triggers_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command\n        $schedule = $this->app->make(Schedule::class);\n        $task = $schedule->exec('exit 1')\n            ->everyMinute();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertDispatched(ScheduledTaskFailed::class, function ($event) use ($task) {\n            return $event->task === $task &&\n                   $event->exception->getMessage() === 'Scheduled command [exit 1] failed with exit code [1].';\n        });\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_failing_command_in_background_does_not_trigger_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command\n        $schedule = $this->app->make(Schedule::class);\n        $task = $schedule->exec('exit 1')\n            ->everyMinute()\n            ->runInBackground();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertNotDispatched(ScheduledTaskFailed::class);\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_successful_command_does_not_trigger_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command\n        $schedule = $this->app->make(Schedule::class);\n        $task = $schedule->exec('exit 0')\n            ->everyMinute();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertNotDispatched(ScheduledTaskFailed::class);\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_command_with_no_explicit_return_does_not_trigger_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command that just performs an action without explicit exit\n        $schedule = $this->app->make(Schedule::class);\n        $command = PHP_OS_FAMILY === 'Windows' ? 'cmd /c exit 0' : 'true';\n        $task = $schedule->exec($command)\n            ->everyMinute();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertNotDispatched(ScheduledTaskFailed::class);\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_successful_command_in_background_does_not_trigger_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command\n        $schedule = $this->app->make(Schedule::class);\n        $task = $schedule->exec('exit 0')\n            ->everyMinute()\n            ->runInBackground();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertNotDispatched(ScheduledTaskFailed::class);\n    }\n\n    /**\n     * @throws BindingResolutionException\n     */\n    public function test_command_with_no_explicit_return_in_background_does_not_trigger_event()\n    {\n        Event::fake([\n            ScheduledTaskStarting::class,\n            ScheduledTaskFinished::class,\n            ScheduledTaskFailed::class,\n        ]);\n\n        // Create a schedule and add the command that just performs an action without explicit exit\n        $schedule = $this->app->make(Schedule::class);\n        $task = $schedule->exec('true')\n            ->everyMinute()\n            ->runInBackground();\n\n        // Make sure it will run regardless of schedule\n        $task->when(function () {\n            return true;\n        });\n\n        // Execute the scheduler\n        $this->artisan('schedule:run');\n\n        // Verify the event sequence\n        Event::assertDispatched(ScheduledTaskStarting::class);\n        Event::assertDispatched(ScheduledTaskFinished::class);\n        Event::assertNotDispatched(ScheduledTaskFailed::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/ScheduleTestCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Console\\Scheduling\\ScheduleTestCommand;\nuse Illuminate\\Support\\Carbon;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ScheduleTestCommandTest extends TestCase\n{\n    public $schedule;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Carbon::setTestNow(Carbon::now()->startOfYear());\n\n        $this->schedule = $this->app->make(Schedule::class);\n    }\n\n    public function testRunNoDefinedCommands()\n    {\n        $this->artisan(ScheduleTestCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain('No scheduled commands have been defined.');\n    }\n\n    public function testRunNoMatchingCommand()\n    {\n        $this->schedule->command(BarCommandStub::class);\n\n        $this->artisan(ScheduleTestCommand::class, ['--name' => 'missing:command'])\n            ->assertSuccessful()\n            ->expectsOutputToContain('No matching scheduled command found.');\n    }\n\n    public function testRunUsingNameOption()\n    {\n        $this->schedule->command(BarCommandStub::class)->name('bar-command');\n        $this->schedule->job(BarJobStub::class);\n        $this->schedule->call(fn () => true)->name('callback');\n\n        $expectedOutput = windows_os()\n            ? 'Running [\"artisan\" bar:command]'\n            : \"Running ['artisan' bar:command]\";\n\n        $this->artisan(ScheduleTestCommand::class, ['--name' => 'bar:command'])\n            ->assertSuccessful()\n            ->expectsOutputToContain($expectedOutput);\n\n        $this->artisan(ScheduleTestCommand::class, ['--name' => BarJobStub::class])\n            ->assertSuccessful()\n            ->expectsOutputToContain(sprintf('Running [%s]', BarJobStub::class));\n\n        $this->artisan(ScheduleTestCommand::class, ['--name' => 'callback'])\n            ->assertSuccessful()\n            ->expectsOutputToContain('Running [callback]');\n    }\n\n    public function testRunUsingChoices()\n    {\n        $this->schedule->command(BarCommandStub::class)->name('bar-command');\n        $this->schedule->job(BarJobStub::class);\n        $this->schedule->call(fn () => true)->name('callback');\n\n        $this->artisan(ScheduleTestCommand::class)\n            ->assertSuccessful()\n            ->expectsChoice(\n                'Which command would you like to run?',\n                'callback',\n                [Application::formatCommandString('bar:command'), BarJobStub::class, 'callback'],\n                true\n            )\n            ->expectsOutputToContain('Running [callback]');\n    }\n}\n\nclass BarCommandStub extends Command\n{\n    protected $signature = 'bar:command';\n\n    protected $description = 'This is the description of the command.';\n}\n\nclass BarJobStub\n{\n    public function __invoke()\n    {\n        // ..\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/Scheduling/SubMinuteSchedulingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console\\Scheduling;\n\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Sleep;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass SubMinuteSchedulingTest extends TestCase\n{\n    protected Schedule $schedule;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->schedule = $this->app->make(Schedule::class);\n    }\n\n    public function test_it_doesnt_wait_for_sub_minute_events_when_nothing_is_scheduled()\n    {\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        Sleep::fake();\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('No scheduled commands are ready to run.');\n\n        Sleep::assertNeverSlept();\n    }\n\n    public function test_it_doesnt_wait_for_sub_minute_events_when_none_are_scheduled()\n    {\n        $this->schedule\n            ->call(fn () => true)\n            ->everyMinute();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        Sleep::fake();\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertNeverSlept();\n    }\n\n    #[DataProvider('frequencyProvider')]\n    public function test_it_runs_sub_minute_callbacks($frequency, $expectedRuns)\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->{$frequency}();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        Sleep::fake();\n        Sleep::whenFakingSleep(fn ($duration) => Carbon::setTestNow(Carbon::now()->add($duration)));\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals($expectedRuns, $runs);\n    }\n\n    public function test_it_runs_multiple_sub_minute_callbacks()\n    {\n        $everySecondRuns = 0;\n        $this->schedule->call(function () use (&$everySecondRuns) {\n            $everySecondRuns++;\n        })->everySecond();\n\n        $everyThirtySecondsRuns = 0;\n        $this->schedule->call(function () use (&$everyThirtySecondsRuns) {\n            $everyThirtySecondsRuns++;\n        })->everyThirtySeconds();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        Sleep::fake();\n        Sleep::whenFakingSleep(fn ($duration) => Carbon::setTestNow(Carbon::now()->add($duration)));\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(60, $everySecondRuns);\n        $this->assertEquals(2, $everyThirtySecondsRuns);\n    }\n\n    public function test_sub_minute_scheduling_can_be_interrupted()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        $startedAt = Carbon::now();\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use ($startedAt) {\n            Carbon::setTestNow(Carbon::now()->add($duration));\n\n            if ($startedAt->diffInSeconds() >= 30) {\n                $this->artisan('schedule:interrupt')\n                    ->expectsOutputToContain('Broadcasting schedule interrupt signal.');\n            }\n        });\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(300);\n        $this->assertEquals(30, $runs);\n        $this->assertEquals(30, $startedAt->diffInSeconds(Carbon::now()));\n    }\n\n    public function test_sub_minute_events_stop_for_the_rest_of_the_minute_once_maintenance_mode_is_enabled()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond();\n\n        Config::set('app.maintenance.driver', 'cache');\n        Config::set('app.maintenance.store', 'array');\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        $startedAt = Carbon::now();\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use ($startedAt) {\n            Carbon::setTestNow(Carbon::now()->add($duration));\n\n            if ($startedAt->diffInSeconds() >= 30 && ! $this->app->isDownForMaintenance()) {\n                $this->artisan('down');\n            }\n\n            if ($startedAt->diffInSeconds() >= 40 && $this->app->isDownForMaintenance()) {\n                $this->artisan('up');\n            }\n        });\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(30, $runs);\n    }\n\n    public function test_sub_minute_events_can_be_run_in_maintenance_mode()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond()->evenInMaintenanceMode();\n\n        Config::set('app.maintenance.driver', 'cache');\n        Config::set('app.maintenance.store', 'array');\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        $startedAt = Carbon::now();\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use ($startedAt) {\n            Carbon::setTestNow(Carbon::now()->add($duration));\n\n            if (Carbon::now()->diffInSeconds($startedAt) >= 30 && ! $this->app->isDownForMaintenance()) {\n                $this->artisan('down');\n            }\n        });\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(60, $runs);\n    }\n\n    public function test_sub_minute_events_can_be_run_when_schedule_is_paused()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond()->evenWhenPaused();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        $startedAt = Carbon::now();\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use ($startedAt) {\n            Carbon::setTestNow(Carbon::now()->add($duration));\n\n            if ($startedAt->diffInSeconds() >= 30 && ! Cache::has('illuminate:schedule:paused')) {\n                $this->artisan('schedule:pause');\n            }\n        });\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(60, $runs);\n    }\n\n    public function test_sub_minute_events_stop_for_the_rest_of_the_minute_once_schedule_is_paused()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond();\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        $startedAt = Carbon::now();\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use ($startedAt) {\n            Carbon::setTestNow(Carbon::now()->add($duration));\n\n            if ($startedAt->diffInSeconds() >= 30 && ! Cache::has('illuminate:schedule:paused')) {\n                $this->artisan('schedule:pause');\n            }\n        });\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(30, $runs);\n    }\n\n    public function test_sub_minute_scheduling_respects_filters()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond()->when(fn () => Carbon::now()->second % 2 === 0);\n\n        Carbon::setTestNow(Carbon::now()->startOfMinute());\n        Sleep::fake();\n        Sleep::whenFakingSleep(fn ($duration) => Carbon::setTestNow(Carbon::now()->add($duration)));\n\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [Callback]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(30, $runs);\n    }\n\n    public function test_sub_minute_scheduling_can_run_on_one_server()\n    {\n        $runs = 0;\n        $this->schedule->call(function () use (&$runs) {\n            $runs++;\n        })->everySecond()->name('test')->onOneServer();\n\n        $startedAt = Carbon::now()->startOfMinute();\n        Carbon::setTestNow($startedAt);\n        Sleep::fake();\n        Sleep::whenFakingSleep(fn ($duration) => Carbon::setTestNow(Carbon::now()->add($duration)));\n\n        $this->app->instance(Schedule::class, clone $this->schedule);\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Running [test]');\n\n        Sleep::assertSleptTimes(600);\n        $this->assertEquals(60, $runs);\n\n        // Fake a second server running at the same minute.\n        Carbon::setTestNow($startedAt);\n\n        $this->app->instance(Schedule::class, clone $this->schedule);\n        $this->artisan('schedule:run')\n            ->expectsOutputToContain('Skipping [test]');\n\n        Sleep::assertSleptTimes(1200);\n        $this->assertEquals(60, $runs);\n    }\n\n    public static function frequencyProvider()\n    {\n        return [\n            'everySecond' => ['everySecond', 60],\n            'everyTwoSeconds' => ['everyTwoSeconds', 30],\n            'everyFiveSeconds' => ['everyFiveSeconds', 12],\n            'everyTenSeconds' => ['everyTenSeconds', 6],\n            'everyFifteenSeconds' => ['everyFifteenSeconds', 4],\n            'everyTwentySeconds' => ['everyTwentySeconds', 3],\n            'everyThirtySeconds' => ['everyThirtySeconds', 2],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Console/UniqueJobSchedulingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Console;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Console\\Scheduling\\Schedule;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\n\nclass UniqueJobSchedulingTest extends TestCase\n{\n    public function testJobsPushedToQueue(): void\n    {\n        Queue::fake();\n        $this->dispatch(\n            TestJob::class,\n            TestJob::class,\n            TestJob::class,\n            TestJob::class\n        );\n\n        Queue::assertPushed(TestJob::class, 4);\n    }\n\n    public function testUniqueJobsPushedToQueue(): void\n    {\n        Queue::fake();\n        $this->dispatch(\n            UniqueTestJob::class,\n            UniqueTestJob::class,\n            UniqueTestJob::class,\n            UniqueTestJob::class\n        );\n\n        Queue::assertPushed(UniqueTestJob::class, 1);\n    }\n\n    private function dispatch(...$jobs)\n    {\n        /** @var \\Illuminate\\Console\\Scheduling\\Schedule $scheduler */\n        $scheduler = $this->app->make(Schedule::class);\n        foreach ($jobs as $job) {\n            $scheduler->job($job)->name('')->everyMinute();\n        }\n        $events = $scheduler->events();\n        foreach ($events as $event) {\n            $event->run($this->app);\n        }\n    }\n}\n\nclass TestJob implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable, Dispatchable;\n}\n\nclass UniqueTestJob extends TestJob implements ShouldBeUnique\n{\n}\n"
  },
  {
    "path": "tests/Integration/Container/BuildableIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Container;\n\nuse Illuminate\\Container\\Attributes\\Config;\nuse Illuminate\\Contracts\\Container\\SelfBuilding;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Validation\\ValidationException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass BuildableIntegrationTest extends TestCase\n{\n    public function test_build_method_can_resolve_itself_via_container(): void\n    {\n        config([\n            'aim' => [\n                'api_key' => 'api-key',\n                'user_name' => 'cosmastech',\n                'away_message' => [\n                    'duration' => 500,\n                    'body' => 'sad emo lyrics',\n                ],\n            ],\n        ]);\n\n        $config = $this->app->make(AolInstantMessengerConfig::class);\n\n        $this->assertEquals(500, $config->awayMessageDuration);\n        $this->assertEquals('sad emo lyrics', $config->awayMessage);\n        $this->assertEquals('api-key', $config->apiKey);\n        $this->assertEquals('cosmastech', $config->userName);\n\n        config(['aim.away_message.duration' => 5]);\n\n        try {\n            $this->app->make(AolInstantMessengerConfig::class);\n        } catch (ValidationException $exception) {\n            $this->assertArrayHasKey('away_message.duration', $exception->errors());\n            $this->assertStringContainsString('60', $exception->errors()['away_message.duration'][0]);\n        }\n    }\n}\n\nclass AolInstantMessengerConfig implements SelfBuilding\n{\n    public function __construct(\n        #[Config('aim.api_key')]\n        public string $apiKey,\n        #[Config('aim.user_name')]\n        public string $userName,\n        #[Config('aim.away_message.duration')]\n        public int $awayMessageDuration,\n        #[Config('aim.away_message.body')]\n        public string $awayMessage\n    ) {\n    }\n\n    public static function newInstance()\n    {\n        Validator::make(config('aim'), [\n            'api-key' => 'string',\n            'user_name' => 'string',\n            'away_message' => 'array',\n            'away_message.duration' => ['integer', 'min:60', 'max:3600'],\n            'away_message.body' => ['string', 'min:1'],\n        ])->validate();\n\n        return app()->build(static::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Container/ContextualAttributesBindingIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Container;\n\nuse Illuminate\\Container\\Attributes\\Log;\nuse Illuminate\\Support\\Collection;\nuse Monolog\\Handler\\TestHandler;\nuse Monolog\\LogRecord;\nuse Orchestra\\Testbench\\TestCase;\nuse Psr\\Log\\LoggerInterface;\n\nclass ContextualAttributesBindingIntegrationTest extends TestCase\n{\n    public function testLogAttributeCanSetName()\n    {\n        config(['logging.default' => 'testing']);\n        config(['logging.channels' => [\n            'testing' => [\n                'driver' => 'monolog',\n                'handler' => TestHandler::class,\n            ],\n        ]]);\n\n        /** @var TestHandler $testHandler */\n        $testHandler = resolve('log')->driver()->getLogger()->getHandlers()[0];\n\n        $tester = resolve(LogAttributeTester::class);\n        $tester->log('hello');\n        $tester->logWithName('bye');\n\n        $records = new Collection($testHandler->getRecords());\n\n        $this->assertCount(2, $records);\n        $this->assertEquals('hello', $records->firstWhere(function (LogRecord $record) {\n            return $record->channel === 'testing';\n        })->message);\n        $this->assertEquals('bye', $records->firstWhere(function (LogRecord $record) {\n            return $record->channel === 'look-ma-a-channel-name';\n        })->message);\n    }\n}\n\nclass LogAttributeTester\n{\n    public function __construct(\n        #[Log('testing')]\n        public LoggerInterface $logger,\n        #[Log('testing', 'look-ma-a-channel-name')]\n        public LoggerInterface $loggerWithName\n    ) {\n    }\n\n    public function log(string $line)\n    {\n        $this->logger->info($line);\n    }\n\n    public function logWithName(string $line)\n    {\n        $this->loggerWithName->info($line);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Cookie/CookieTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Cookie;\n\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Session\\NullSessionHandler;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Session;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CookieTest extends TestCase\n{\n    public function test_cookie_is_sent_back_with_proper_expire_time_when_should_expire_on_close()\n    {\n        $this->app['config']->set('session.expire_on_close', true);\n\n        Route::get('/', function () {\n            return 'hello world';\n        })->middleware('web');\n\n        $response = $this->get('/');\n        $this->assertCount(2, $response->headers->getCookies());\n        $this->assertEquals(0, $response->headers->getCookies()[1]->getExpiresTime());\n    }\n\n    public function test_cookie_is_sent_back_with_proper_expire_time_with_respect_to_lifetime()\n    {\n        $this->app['config']->set('session.expire_on_close', false);\n        $this->app['config']->set('session.lifetime', 1);\n\n        Route::get('/', function () {\n            return 'hello world';\n        })->middleware('web');\n\n        Carbon::setTestNow(Carbon::now());\n        $response = $this->get('/');\n        $this->assertCount(2, $response->headers->getCookies());\n        $this->assertEquals(Carbon::now()->getTimestamp() + 60, $response->headers->getCookies()[1]->getExpiresTime());\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app->instance(\n            ExceptionHandler::class,\n            $handler = m::mock(ExceptionHandler::class)->shouldIgnoreMissing()\n        );\n\n        $handler->shouldReceive('render')->andReturn(new Response);\n\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('session.driver', 'fake-null');\n\n        Session::extend('fake-null', function () {\n            return new NullSessionHandler;\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/AfterQueryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass AfterQueryTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('team_id')->nullable();\n        });\n\n        Schema::create('teams', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('owner_id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('users_posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->integer('post_id');\n            $table->timestamps();\n        });\n    }\n\n    public function testAfterQueryOnEloquentBuilder()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function (Collection $users) use ($afterQueryIds) {\n                $afterQueryIds->push(...$users->pluck('id')->all());\n\n                foreach ($users as $user) {\n                    $this->assertInstanceOf(AfterQueryUser::class, $user);\n                }\n            })\n            ->get();\n\n        $this->assertCount(2, $users);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $users->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryOnBaseBuilder()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function (Collection $users) use ($afterQueryIds) {\n                $afterQueryIds->push(...$users->pluck('id')->all());\n\n                foreach ($users as $user) {\n                    $this->assertNotInstanceOf(AfterQueryUser::class, $user);\n                }\n            })\n            ->get();\n\n        $this->assertCount(2, $users);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $users->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryOnEloquentCursor()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function (Collection $users) use ($afterQueryIds) {\n                $afterQueryIds->push(...$users->pluck('id')->all());\n\n                foreach ($users as $user) {\n                    $this->assertInstanceOf(AfterQueryUser::class, $user);\n                }\n            })\n            ->cursor();\n\n        $this->assertCount(2, $users);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $users->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryOnBaseBuilderCursor()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function (Collection $users) use ($afterQueryIds) {\n                $afterQueryIds->push(...$users->pluck('id')->all());\n\n                foreach ($users as $user) {\n                    $this->assertNotInstanceOf(AfterQueryUser::class, $user);\n                }\n            })\n            ->cursor();\n\n        $this->assertCount(2, $users);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $users->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryOnEloquentPluck()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $userIds = AfterQueryUser::query()\n            ->afterQuery(function (Collection $userIds) use ($afterQueryIds) {\n                $afterQueryIds->push(...$userIds->all());\n\n                foreach ($userIds as $userId) {\n                    $this->assertIsInt($userId);\n                }\n            })\n            ->pluck('id');\n\n        $this->assertCount(2, $userIds);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $userIds->toArray());\n    }\n\n    public function testAfterQueryOnBaseBuilderPluck()\n    {\n        AfterQueryUser::create();\n        AfterQueryUser::create();\n\n        $afterQueryIds = collect();\n\n        $userIds = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function (Collection $userIds) use ($afterQueryIds) {\n                $afterQueryIds->push(...$userIds->all());\n\n                foreach ($userIds as $userId) {\n                    $this->assertIsInt((int) $userId);\n                }\n            })\n            ->pluck('id');\n\n        $this->assertCount(2, $userIds);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $userIds->toArray());\n    }\n\n    public function testAfterQueryHookOnBelongsToManyRelationship()\n    {\n        $user = AfterQueryUser::create();\n        $firstPost = AfterQueryPost::create();\n        $secondPost = AfterQueryPost::create();\n\n        $user->posts()->attach($firstPost);\n        $user->posts()->attach($secondPost);\n\n        $afterQueryIds = collect();\n\n        $posts = $user->posts()\n            ->afterQuery(function (Collection $posts) use ($afterQueryIds) {\n                $afterQueryIds->push(...$posts->pluck('id')->all());\n\n                foreach ($posts as $post) {\n                    $this->assertInstanceOf(AfterQueryPost::class, $post);\n                }\n            })\n            ->get();\n\n        $this->assertCount(2, $posts);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $posts->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryKeyByOnEagerBelongsToManyRelationship()\n    {\n        $user = AfterQueryUser::create();\n        $firstPost = AfterQueryPost::create();\n        $secondPost = AfterQueryPost::create();\n\n        $user->posts()->attach($firstPost);\n        $user->posts()->attach($secondPost);\n\n        $posts = AfterQueryUser::with('posts')->first()->posts;\n\n        $this->assertEqualsCanonicalizing($posts->pluck('id')->toArray(), $posts->keys()->toArray());\n    }\n\n    public function testAfterQueryHookOnHasManyThroughRelationship()\n    {\n        $user = AfterQueryUser::create();\n        $team = AfterQueryTeam::create(['owner_id' => $user->id]);\n\n        AfterQueryUser::create(['team_id' => $team->id]);\n        AfterQueryUser::create(['team_id' => $team->id]);\n\n        $afterQueryIds = collect();\n\n        $teamMates = $user->teamMates()\n            ->afterQuery(function (Collection $teamMates) use ($afterQueryIds) {\n                $afterQueryIds->push(...$teamMates->pluck('id')->all());\n\n                foreach ($teamMates as $teamMate) {\n                    $this->assertInstanceOf(AfterQueryUser::class, $teamMate);\n                }\n            })\n            ->get();\n\n        $this->assertCount(2, $teamMates);\n        $this->assertEqualsCanonicalizing($afterQueryIds->toArray(), $teamMates->pluck('id')->toArray());\n    }\n\n    public function testAfterQueryOnEloquentBuilderCanAlterReturnedResult()\n    {\n        $firstUser = AfterQueryUser::create();\n        $secondUser = AfterQueryUser::create();\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $users);\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->pluck('id');\n\n        $this->assertEquals(collect(['foo', 'bar']), $users);\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function ($users) use ($firstUser) {\n                return $users->first()->is($firstUser) ? collect(['foo', 'bar']) : collect(['bar', 'foo']);\n            })\n            ->cursor();\n\n        $this->assertEquals(collect(['foo', 'bar']), $users->collect());\n\n        $users = AfterQueryUser::query()\n            ->afterQuery(function ($users) use ($firstUser) {\n                return $users->where('id', '!=', $firstUser->id);\n            })\n            ->cursor();\n\n        $this->assertEquals([$secondUser->id], $users->collect()->pluck('id')->all());\n\n        $firstPost = AfterQueryPost::create();\n        $secondPost = AfterQueryPost::create();\n\n        $firstUser->posts()->attach($firstPost);\n        $firstUser->posts()->attach($secondPost);\n\n        $posts = $firstUser->posts()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $posts);\n\n        $user = AfterQueryUser::create();\n        $team = AfterQueryTeam::create(['owner_id' => $user->id]);\n\n        AfterQueryUser::create(['team_id' => $team->id]);\n        AfterQueryUser::create(['team_id' => $team->id]);\n\n        $teamMates = $user->teamMates()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $teamMates);\n    }\n\n    public function testAfterQueryOnBaseBuilderCanAlterReturnedResult()\n    {\n        $firstUser = AfterQueryUser::create();\n        $secondUser = AfterQueryUser::create();\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $users);\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->pluck('id');\n\n        $this->assertEquals(collect(['foo', 'bar']), $users);\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function ($users) use ($firstUser) {\n                return ((int) $users->first()->id) === $firstUser->id ? collect(['foo', 'bar']) : collect(['bar', 'foo']);\n            })\n            ->cursor();\n\n        $this->assertEquals(collect(['foo', 'bar']), $users->collect());\n\n        $users = AfterQueryUser::query()\n            ->toBase()\n            ->afterQuery(function ($users) use ($firstUser) {\n                return $users->where('id', '!=', $firstUser->id);\n            })\n            ->cursor();\n\n        $this->assertEquals([$secondUser->id], $users->collect()->pluck('id')->all());\n\n        $firstPost = AfterQueryPost::create();\n        $secondPost = AfterQueryPost::create();\n\n        $firstUser->posts()->attach($firstPost);\n        $firstUser->posts()->attach($secondPost);\n\n        $posts = $firstUser->posts()\n            ->toBase()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $posts);\n\n        $user = AfterQueryUser::create();\n        $team = AfterQueryTeam::create(['owner_id' => $user->id]);\n\n        AfterQueryUser::create(['team_id' => $team->id]);\n        AfterQueryUser::create(['team_id' => $team->id]);\n\n        $teamMates = $user->teamMates()\n            ->toBase()\n            ->afterQuery(function () {\n                return collect(['foo', 'bar']);\n            })\n            ->get();\n\n        $this->assertEquals(collect(['foo', 'bar']), $teamMates);\n    }\n}\n\nclass AfterQueryUser extends Model\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function teamMates()\n    {\n        return $this->hasManyThrough(self::class, AfterQueryTeam::class, 'owner_id', 'team_id');\n    }\n\n    public function posts()\n    {\n        return $this->belongsToMany(AfterQueryPost::class, 'users_posts', 'user_id', 'post_id')\n            ->afterQuery(fn (Collection $posts) => $posts->keyBy(fn (AfterQueryPost $post) => $post->id))\n            ->withTimestamps();\n    }\n}\n\nclass AfterQueryTeam extends Model\n{\n    protected $table = 'teams';\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function members()\n    {\n        return $this->hasMany(AfterQueryUser::class, 'team_id');\n    }\n}\n\nclass AfterQueryPost extends Model\n{\n    protected $table = 'posts';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/ConnectionThreadsCountTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Support\\Facades\\DB;\n\nclass ConnectionThreadsCountTest extends DatabaseTestCase\n{\n    public function testGetThreadsCount()\n    {\n        $count = DB::connection()->threadCount();\n\n        if ($this->driver === 'sqlite') {\n            $this->assertNull($count, 'SQLite does not support connection count');\n        } else {\n            $this->assertGreaterThanOrEqual(1, $count);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseCacheStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Cache\\DatabaseStore;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse RuntimeException;\n\n#[WithMigration('cache')]\nclass DatabaseCacheStoreTest extends DatabaseTestCase\n{\n    public function testValueCanStoreNewCache()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 60);\n\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testPutOperationShouldNotStoreExpired()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 0);\n\n        $this->assertDatabaseMissing($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testValueCanUpdateExistCache()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 60);\n        $store->put('foo', 'new-bar', 60);\n\n        $this->assertSame('new-bar', $store->get('foo'));\n    }\n\n    public function testValueCanUpdateExistCacheInTransaction()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 60);\n\n        DB::beginTransaction();\n        $store->put('foo', 'new-bar', 60);\n        DB::commit();\n\n        $this->assertSame('new-bar', $store->get('foo'));\n    }\n\n    public function testAddOperationShouldNotStoreExpired()\n    {\n        $store = $this->getStore();\n\n        $result = $store->add('foo', 'bar', 0);\n\n        $this->assertFalse($result);\n        $this->assertDatabaseMissing($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testAddOperationCanStoreNewCache()\n    {\n        $store = $this->getStore();\n\n        $result = $store->add('foo', 'bar', 60);\n\n        $this->assertTrue($result);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testAddOperationShouldNotUpdateExistCache()\n    {\n        $store = $this->getStore();\n\n        $store->add('foo', 'bar', 60);\n        $result = $store->add('foo', 'new-bar', 60);\n\n        $this->assertFalse($result);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testAddOperationShouldNotUpdateExistCacheInTransaction()\n    {\n        $store = $this->getStore();\n\n        $store->add('foo', 'bar', 60);\n\n        DB::beginTransaction();\n        $result = $store->add('foo', 'new-bar', 60);\n        DB::commit();\n\n        $this->assertFalse($result);\n        $this->assertSame('bar', $store->get('foo'));\n    }\n\n    public function testAddOperationCanUpdateIfCacheExpired()\n    {\n        $store = $this->getStore();\n\n        $this->insertToCacheTable('foo', 'bar', 0);\n        $result = $store->add('foo', 'new-bar', 60);\n\n        $this->assertTrue($result);\n        $this->assertSame('new-bar', $store->get('foo'));\n    }\n\n    public function testAddOperationCanUpdateIfCacheExpiredInTransaction()\n    {\n        $store = $this->getStore();\n\n        $this->insertToCacheTable('foo', 'bar', 0);\n\n        DB::beginTransaction();\n        $result = $store->add('foo', 'new-bar', 60);\n        DB::commit();\n\n        $this->assertTrue($result);\n        $this->assertSame('new-bar', $store->get('foo'));\n    }\n\n    public function testGetOperationReturnNullIfExpired()\n    {\n        $store = $this->getStore();\n\n        $this->insertToCacheTable('foo', 'bar', 0);\n\n        $result = $store->get('foo');\n\n        $this->assertNull($result);\n    }\n\n    public function testGetOperationCanDeleteExpired()\n    {\n        $store = $this->getStore();\n\n        $this->insertToCacheTable('foo', 'bar', 0);\n\n        $store->get('foo');\n\n        $this->assertDatabaseMissing($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testForgetIfExpiredOperationCanDeleteExpired()\n    {\n        $store = $this->getStore();\n\n        $this->insertToCacheTable('foo', 'bar', 0);\n\n        $store->forgetIfExpired('foo');\n\n        $this->assertDatabaseMissing($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testForgetIfExpiredOperationShouldNotDeleteUnExpired()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 60);\n\n        $store->forgetIfExpired('foo');\n\n        $this->assertDatabaseHas($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testMany()\n    {\n        $this->insertToCacheTable('first', 'a', 60);\n        $this->insertToCacheTable('second', 'b', 60);\n\n        $store = $this->getStore();\n\n        $this->assertEquals([\n            'first' => 'a',\n            'second' => 'b',\n            'third' => null,\n        ], $store->get(['first', 'second', 'third']));\n\n        $this->assertEquals([\n            'first' => 'a',\n            'second' => 'b',\n            'third' => null,\n        ], $store->many(['first', 'second', 'third']));\n    }\n\n    public function testManyWithExpiredKeys()\n    {\n        $this->insertToCacheTable('first', 'a', 0);\n        $this->insertToCacheTable('second', 'b', 60);\n\n        $this->assertEquals([\n            'first' => null,\n            'second' => 'b',\n            'third' => null,\n        ], $this->getStore()->many(['first', 'second', 'third']));\n\n        $this->assertDatabaseMissing($this->getCacheTableName(), ['key' => $this->withCachePrefix('first')]);\n    }\n\n    public function testManyAsAssociativeArray()\n    {\n        $this->insertToCacheTable('first', 'cached', 60);\n\n        $result = $this->getStore()->many([\n            'first' => 'aa',\n            'second' => 'bb',\n            'third',\n        ]);\n\n        $this->assertEquals([\n            'first' => 'cached',\n            'second' => 'bb',\n            'third' => null,\n        ], $result);\n    }\n\n    public function testPutMany()\n    {\n        $store = $this->getStore();\n\n        $store->putMany($data = [\n            'first' => 'a',\n            'second' => 'b',\n        ], 60);\n\n        $this->assertEquals($data, $store->many(['first', 'second']));\n        $this->assertDatabaseHas($this->getCacheTableName(), [\n            'key' => $this->withCachePrefix('first'),\n            'value' => serialize('a'),\n        ]);\n        $this->assertDatabaseHas($this->getCacheTableName(), [\n            'key' => $this->withCachePrefix('second'),\n            'value' => serialize('b'),\n        ]);\n    }\n\n    public function testResolvingSQLiteConnectionDoesNotThrowExceptions()\n    {\n        $originalConfiguration = config('database');\n\n        app('config')->set('database.default', 'sqlite');\n        app('config')->set('database.connections.sqlite.database', __DIR__.'/non-existing-file');\n\n        $store = $this->getStore();\n        $this->assertInstanceOf(SQLiteConnection::class, $store->getConnection());\n\n        app('config')->set('database', $originalConfiguration);\n    }\n\n    public function testLocksCanBeFlushed()\n    {\n        $store = $this->getStore();\n\n        $store->lock('lock-1', 60)->acquire();\n        $store->lock('lock-2', 60)->acquire();\n        $store->lock('lock-3', 60)->acquire();\n\n        $this->assertTrue($store->flushLocks());\n\n        $this->assertTrue($store->lock('lock-1', 60)->acquire());\n        $this->assertTrue($store->lock('lock-2', 60)->acquire());\n        $this->assertTrue($store->lock('lock-3', 60)->acquire());\n    }\n\n    public function testFlushLocksDoesNotAffectCacheEntries()\n    {\n        $store = $this->getStore();\n\n        $store->put('foo', 'bar', 60);\n        $store->lock('lock-1', 60)->acquire();\n\n        $store->flushLocks();\n\n        $this->assertSame('bar', $store->get('foo'));\n        $this->assertDatabaseHas($this->getCacheTableName(), ['key' => $this->withCachePrefix('foo')]);\n    }\n\n    public function testFlushLocksRemovesExpiredLocksToo()\n    {\n        $store = $this->getStore();\n\n        $this->insertToLocksTable('stale-lock', 'owner', 0);\n        $store->lock('active-lock', 60)->acquire();\n\n        $store->flushLocks();\n\n        $this->assertTrue($store->lock('active-lock', 60)->acquire());\n        $this->assertDatabaseMissing($this->getLocksTableName(), ['key' => $this->withCachePrefix('stale-lock')]);\n    }\n\n    public function testHasSeparateLockStoreReturnsTrueWhenTablesAreDifferent()\n    {\n        $store = new DatabaseStore(\n            connection: DB::connection(),\n            table: $this->getCacheTableName(),\n            lockTable: $this->getLocksTableName(),\n        );\n\n        $this->assertTrue($store->hasSeparateLockStore());\n    }\n\n    public function testHasSeparateLockStoreReturnsFalseWhenTablesAreTheSame()\n    {\n        $store = new DatabaseStore(\n            connection: DB::connection(),\n            table: $this->getCacheTableName(),\n            lockTable: $this->getCacheTableName(),\n        );\n\n        $this->assertFalse($store->hasSeparateLockStore());\n    }\n\n    public function testFlushLocksThrowsExceptionWhenTablesAreTheSame()\n    {\n        $store = new DatabaseStore(\n            connection: DB::connection(),\n            table: $this->getCacheTableName(),\n            lockTable: $this->getCacheTableName(),\n        );\n\n        $this->expectException(RuntimeException::class);\n\n        $store->flushLocks();\n    }\n\n    /**\n     * @return \\Illuminate\\Cache\\DatabaseStore\n     */\n    protected function getStore()\n    {\n        return Cache::store('database');\n    }\n\n    protected function getCacheTableName()\n    {\n        return config('cache.stores.database.table');\n    }\n\n    protected function getLocksTableName()\n    {\n        return config('cache.stores.database.lock_table') ?: 'cache_locks';\n    }\n\n    protected function withCachePrefix(string $key)\n    {\n        return config('cache.prefix').$key;\n    }\n\n    protected function insertToCacheTable(string $key, $value, $ttl = 60)\n    {\n        DB::table($this->getCacheTableName())\n            ->insert(\n                [\n                    'key' => $this->withCachePrefix($key),\n                    'value' => serialize($value),\n                    'expiration' => Carbon::now()->addSeconds($ttl)->getTimestamp(),\n                ]\n            );\n    }\n\n    protected function insertToLocksTable(string $key, string $owner, $ttl = 60)\n    {\n        DB::table($this->getLocksTableName())\n            ->insert(\n                [\n                    'key' => $this->withCachePrefix($key),\n                    'owner' => $owner,\n                    'expiration' => Carbon::now()->addSeconds($ttl)->getTimestamp(),\n                ]\n            );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseConnectionsTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\DatabaseManager;\nuse Illuminate\\Database\\Events\\ConnectionEstablished;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Database\\SQLiteConnection;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\DB;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse RuntimeException;\n\nclass DatabaseConnectionsTest extends DatabaseTestCase\n{\n    public function testBuildDatabaseConnection()\n    {\n        /** @var \\Illuminate\\Database\\DatabaseManager $manager */\n        $manager = $this->app->make(DatabaseManager::class);\n\n        $connection = $manager->build([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->assertInstanceOf(SQLiteConnection::class, $connection);\n    }\n\n    public function testEstablishDatabaseConnection()\n    {\n        /** @var \\Illuminate\\Database\\DatabaseManager $manager */\n        $manager = $this->app->make(DatabaseManager::class);\n\n        $connection = $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)');\n\n        $connection->statement('INSERT INTO test_1 (id) VALUES (1)');\n\n        $result = $connection->selectOne('SELECT COUNT(*) as total FROM test_1');\n\n        self::assertSame(1, $result->total);\n    }\n\n    public function testThrowExceptionIfConnectionAlreadyExists()\n    {\n        /** @var \\Illuminate\\Database\\DatabaseManager $manager */\n        $manager = $this->app->make(DatabaseManager::class);\n\n        $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->expectException(RuntimeException::class);\n\n        $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n    }\n\n    public function testOverrideExistingConnection()\n    {\n        /** @var \\Illuminate\\Database\\DatabaseManager $manager */\n        $manager = $this->app->make(DatabaseManager::class);\n\n        $connection = $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $connection->statement('CREATE TABLE test_1 (id INTEGER PRIMARY KEY)');\n\n        $resultBeforeOverride = $connection->select(\"SELECT name FROM sqlite_master WHERE type='table';\");\n\n        $connection = $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ], force: true);\n\n        // After purging a connection of a :memory: SQLite database\n        // anything that was created before the override will no\n        // longer be available. It's a new and fresh database\n        $resultAfterOverride = $connection->select(\"SELECT name FROM sqlite_master WHERE type='table';\");\n\n        self::assertSame('test_1', $resultBeforeOverride[0]->name);\n\n        self::assertEmpty($resultAfterOverride);\n    }\n\n    public function testEstablishingAConnectionWillDispatchAnEvent()\n    {\n        /** @var \\Illuminate\\Events\\Dispatcher $dispatcher */\n        $dispatcher = $this->app->make(Dispatcher::class);\n\n        $event = null;\n\n        $dispatcher->listen(ConnectionEstablished::class, function (ConnectionEstablished $e) use (&$event) {\n            $event = $e;\n        });\n\n        /** @var \\Illuminate\\Database\\DatabaseManager $manager */\n        $manager = $this->app->make(DatabaseManager::class);\n\n        $manager->connectUsing('my-phpunit-connection', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        self::assertInstanceOf(\n            ConnectionEstablished::class,\n            $event,\n            'Expected the ConnectionEstablished event to be dispatched when establishing a connection.'\n        );\n\n        self::assertSame('my-phpunit-connection', $event->connectionName);\n    }\n\n    public function testTablePrefix()\n    {\n        DB::setTablePrefix('prefix_');\n        $this->assertSame('prefix_', DB::getTablePrefix());\n\n        DB::withoutTablePrefix(function ($connection) {\n            $this->assertSame('', $connection->getTablePrefix());\n        });\n\n        $this->assertSame('prefix_', DB::getTablePrefix());\n\n        DB::setTablePrefix('');\n        $this->assertSame('', DB::getTablePrefix());\n    }\n\n    public function testDynamicConnectionDoesntFailOnReconnect()\n    {\n        $connection = DB::build([\n            'name' => 'projects',\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->expectNotToPerformAssertions();\n\n        try {\n            $connection->reconnect();\n        } catch (InvalidArgumentException $e) {\n            if ($e->getMessage() === 'Database connection [projects] not configured.') {\n                $this->fail('Dynamic connection should not throw an exception on reconnect.');\n            }\n        }\n    }\n\n    public function testDynamicConnectionWithNoNameDoesntFailOnReconnect()\n    {\n        $connection = DB::build([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->expectNotToPerformAssertions();\n\n        try {\n            $connection->reconnect();\n        } catch (InvalidArgumentException $e) {\n            if ($e->getMessage() === 'Database connection [projects] not configured.') {\n                $this->fail('Dynamic connection should not throw an exception on reconnect.');\n            }\n        }\n    }\n\n    #[DataProvider('readWriteExpectations')]\n    public function testReadWriteTypeIsProvidedInQueryExecutedEventAndQueryLog(string $connectionName, array $expectedTypes, ?string $loggedType)\n    {\n        $readPath = __DIR__.'/read.sqlite';\n        $writePath = __DIR__.'/write.sqlite';\n        Config::set('database.connections.sqlite', [\n            'driver' => 'sqlite',\n            'read' => [\n                'database' => $readPath,\n            ],\n            'write' => [\n                'database' => $writePath,\n            ],\n        ]);\n        $events = collect();\n        DB::listen($events->push(...));\n\n        try {\n            touch($readPath);\n            touch($writePath);\n\n            $connection = DB::connection($connectionName);\n            $connection->enableQueryLog();\n\n            $connection->statement('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n\n            $connection->statement('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n\n            $this->assertEmpty($events);\n            $this->assertSame([\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],\n            ], Arr::select($connection->getQueryLog(), [\n                'query', 'readWriteType',\n            ]));\n        } finally {\n            @unlink($readPath);\n            @unlink($writePath);\n        }\n    }\n\n    public static function readWriteExpectations(): iterable\n    {\n        yield 'sqlite' => ['sqlite', ['write', 'read', 'write', 'read'], null];\n        yield 'sqlite::read' => ['sqlite::read', ['read', 'read', 'read', 'read'], 'read'];\n        yield 'sqlite::write' => ['sqlite::write', ['write', 'write', 'write', 'write'], 'write'];\n    }\n\n    public function testConnectionsWithoutReadWriteConfigurationAlwaysShowAsWrite()\n    {\n        $writePath = __DIR__.'/write.sqlite';\n        Config::set('database.connections.sqlite', [\n            'driver' => 'sqlite',\n            'database' => $writePath,\n        ]);\n        $events = collect();\n        DB::listen($events->push(...));\n\n        try {\n            touch($writePath);\n\n            $connection = DB::connection('sqlite');\n\n            $connection->statement('select 1');\n            $this->assertSame('write', $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame('write', $events->shift()->readWriteType);\n\n            $connection->statement('select 1');\n            $this->assertSame('write', $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame('write', $events->shift()->readWriteType);\n        } finally {\n            @unlink($writePath);\n        }\n    }\n\n    public function testQueryExceptionsProviderReadWriteType()\n    {\n        $readPath = __DIR__.'/read.sqlite';\n        $writePath = __DIR__.'/write.sqlite';\n        Config::set('database.connections.sqlite', [\n            'driver' => 'sqlite',\n            'read' => [\n                'database' => $readPath,\n            ],\n            'write' => [\n                'database' => $writePath,\n            ],\n        ]);\n\n        try {\n            touch($readPath);\n            touch($writePath);\n\n            try {\n                DB::connection('sqlite::write')->statement('xxxx');\n                $this->fail();\n            } catch (QueryException $exception) {\n                $this->assertSame('write', $exception->readWriteType);\n            }\n\n            try {\n                DB::connection('sqlite::read')->statement('xxxx');\n                $this->fail();\n            } catch (QueryException $exception) {\n                $this->assertSame('read', $exception->readWriteType);\n            }\n\n            try {\n                DB::connection('sqlite')->select('xxxx', useReadPdo: true);\n                $this->fail();\n            } catch (QueryException $exception) {\n                $this->assertSame('read', $exception->readWriteType);\n            }\n\n            try {\n                DB::connection('sqlite')->select('xxxx', useReadPdo: false);\n                $this->fail();\n            } catch (QueryException $exception) {\n                $this->assertSame('write', $exception->readWriteType);\n            }\n        } finally {\n            @unlink($writePath);\n            @unlink($readPath);\n        }\n    }\n\n    #[DataProvider('readWriteExpectations')]\n    public function testQueryInEventListenerCannotInterfereWithReadWriteType(string $connectionName, array $expectedTypes, ?string $loggedType)\n    {\n        $readPath = __DIR__.'/read.sqlite';\n        $writePath = __DIR__.'/write.sqlite';\n        Config::set('database.connections.sqlite', [\n            'driver' => 'sqlite',\n            'read' => [\n                'database' => $readPath,\n            ],\n            'write' => [\n                'database' => $writePath,\n            ],\n        ]);\n        $events = collect();\n        DB::listen($events->push(...));\n\n        try {\n            touch($readPath);\n            touch($writePath);\n\n            $connection = DB::connection($connectionName);\n            $connection->enableQueryLog();\n\n            $connection->listen(function ($query) use ($connection) {\n                if ($query->sql === 'select 1') {\n                    $connection->select('select 2');\n                }\n            });\n\n            $connection->statement('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n            $this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n            $this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);\n\n            $connection->statement('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n            $this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);\n\n            $connection->select('select 1');\n            $this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);\n            $this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);\n\n            $this->assertSame([\n                ['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],\n                ['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],\n                ['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],\n                ['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],\n            ], Arr::select($connection->getQueryLog(), [\n                'query', 'readWriteType',\n            ]));\n        } finally {\n            @unlink($readPath);\n            @unlink($writePath);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseCustomCastsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\AsArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsCollection;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsStringable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Stringable;\n\nclass DatabaseCustomCastsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_eloquent_model_with_custom_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->text('array_object');\n            $table->json('array_object_json');\n            $table->text('collection');\n            $table->string('stringable');\n            $table->string('password');\n            $table->timestamps();\n        });\n\n        Schema::create('test_eloquent_model_with_custom_casts_nullables', function (Blueprint $table) {\n            $table->increments('id');\n            $table->text('array_object')->nullable();\n            $table->json('array_object_json')->nullable();\n            $table->text('collection')->nullable();\n            $table->string('stringable')->nullable();\n            $table->timestamps();\n        });\n    }\n\n    public function test_custom_casting()\n    {\n        $model = new TestEloquentModelWithCustomCasts;\n\n        $model->array_object = ['name' => 'Taylor'];\n        $model->array_object_json = ['name' => 'Taylor'];\n        $model->collection = collect(['name' => 'Taylor']);\n        $model->stringable = new Stringable('Taylor');\n        $model->password = Hash::make('secret');\n\n        $model->save();\n\n        $model = $model->fresh();\n\n        $this->assertEquals(['name' => 'Taylor'], $model->array_object->toArray());\n        $this->assertEquals(['name' => 'Taylor'], $model->array_object_json->toArray());\n        $this->assertEquals(['name' => 'Taylor'], $model->collection->toArray());\n        $this->assertSame('Taylor', (string) $model->stringable);\n        $this->assertTrue(Hash::check('secret', $model->password));\n\n        $model->array_object['age'] = 34;\n        $model->array_object['meta']['title'] = 'Developer';\n\n        $model->array_object_json['age'] = 34;\n        $model->array_object_json['meta']['title'] = 'Developer';\n\n        $model->save();\n\n        $model = $model->fresh();\n\n        $this->assertEquals(\n            [\n                'name' => 'Taylor',\n                'age' => 34,\n                'meta' => ['title' => 'Developer'],\n            ],\n            $model->array_object->toArray()\n        );\n\n        $this->assertEquals(\n            [\n                'name' => 'Taylor',\n                'age' => 34,\n                'meta' => ['title' => 'Developer'],\n            ],\n            $model->array_object_json->toArray()\n        );\n    }\n\n    public function test_custom_casting_using_create()\n    {\n        $model = TestEloquentModelWithCustomCasts::create([\n            'array_object' => ['name' => 'Taylor'],\n            'array_object_json' => ['name' => 'Taylor'],\n            'collection' => collect(['name' => 'Taylor']),\n            'stringable' => new Stringable('Taylor'),\n            'password' => Hash::make('secret'),\n        ]);\n\n        $model->save();\n\n        $model = $model->fresh();\n\n        $this->assertEquals(['name' => 'Taylor'], $model->array_object->toArray());\n        $this->assertEquals(['name' => 'Taylor'], $model->array_object_json->toArray());\n        $this->assertEquals(['name' => 'Taylor'], $model->collection->toArray());\n        $this->assertSame('Taylor', (string) $model->stringable);\n        $this->assertTrue(Hash::check('secret', $model->password));\n    }\n\n    public function test_custom_casting_nullable_values()\n    {\n        $model = new TestEloquentModelWithCustomCastsNullable();\n\n        $model->array_object = null;\n        $model->array_object_json = null;\n        $model->collection = collect();\n        $model->stringable = null;\n\n        $model->save();\n\n        $model = $model->fresh();\n\n        $this->assertEmpty($model->array_object);\n        $this->assertEmpty($model->array_object_json);\n        $this->assertEmpty($model->collection);\n        $this->assertSame('', (string) $model->stringable);\n\n        $model->array_object = ['name' => 'John'];\n        $model->array_object['name'] = 'Taylor';\n        $model->array_object['meta']['title'] = 'Developer';\n\n        $model->array_object_json = ['name' => 'John'];\n        $model->array_object_json['name'] = 'Taylor';\n        $model->array_object_json['meta']['title'] = 'Developer';\n\n        $model->save();\n\n        $model = $model->fresh();\n\n        $this->assertEquals(\n            [\n                'name' => 'Taylor',\n                'meta' => ['title' => 'Developer'],\n            ],\n            $model->array_object->toArray()\n        );\n\n        $this->assertEquals(\n            [\n                'name' => 'Taylor',\n                'meta' => ['title' => 'Developer'],\n            ],\n            $model->array_object_json->toArray()\n        );\n    }\n\n    public function test_as_collection_with_map_into()\n    {\n        $model = new TestEloquentModelWithCustomCasts();\n        $model->mergeCasts([\n            'collection' => AsCollection::of(Fluent::class),\n        ]);\n\n        $model->setRawAttributes([\n            'collection' => json_encode([['foo' => 'bar']]),\n        ]);\n\n        $this->assertInstanceOf(Fluent::class, $model->collection->first());\n        $this->assertSame('bar', $model->collection->first()->foo);\n    }\n\n    public function test_as_custom_collection_with_map_into()\n    {\n        $model = new TestEloquentModelWithCustomCasts();\n        $model->mergeCasts([\n            'collection' => AsCollection::using(CustomCollection::class, Fluent::class),\n        ]);\n\n        $model->setRawAttributes([\n            'collection' => json_encode([['foo' => 'bar']]),\n        ]);\n\n        $this->assertInstanceOf(CustomCollection::class, $model->collection);\n        $this->assertInstanceOf(Fluent::class, $model->collection->first());\n        $this->assertSame('bar', $model->collection->first()->foo);\n    }\n\n    public function test_as_collection_with_map_callback(): void\n    {\n        $model = new TestEloquentModelWithCustomCasts();\n        $model->mergeCasts([\n            'collection' => AsCollection::of([FluentWithCallback::class, 'make']),\n        ]);\n\n        $model->setRawAttributes([\n            'collection' => json_encode([['foo' => 'bar']]),\n        ]);\n\n        $this->assertInstanceOf(FluentWithCallback::class, $model->collection->first());\n        $this->assertSame('bar', $model->collection->first()->foo);\n    }\n\n    public function test_as_custom_collection_with_map_callback(): void\n    {\n        $model = new TestEloquentModelWithCustomCasts();\n        $model->mergeCasts([\n            'collection' => AsCollection::using(CustomCollection::class, [FluentWithCallback::class, 'make']),\n        ]);\n\n        $model->setRawAttributes([\n            'collection' => json_encode([['foo' => 'bar']]),\n        ]);\n\n        $this->assertInstanceOf(CustomCollection::class, $model->collection);\n        $this->assertInstanceOf(FluentWithCallback::class, $model->collection->first());\n        $this->assertSame('bar', $model->collection->first()->foo);\n    }\n}\n\nclass TestEloquentModelWithCustomCasts extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be cast to native types.\n     *\n     * @var array\n     */\n    protected $casts = [\n        'array_object' => AsArrayObject::class,\n        'array_object_json' => AsArrayObject::class,\n        'collection' => AsCollection::class,\n        'stringable' => AsStringable::class,\n        'password' => 'hashed',\n    ];\n}\n\nclass TestEloquentModelWithCustomCastsNullable extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be cast to native types.\n     *\n     * @var array\n     */\n    protected $casts = [\n        'array_object' => AsArrayObject::class,\n        'array_object_json' => AsArrayObject::class,\n        'collection' => AsCollection::class,\n        'stringable' => AsStringable::class,\n    ];\n}\n\nclass FluentWithCallback extends Fluent\n{\n    public static function make($attributes = [])\n    {\n        return new static($attributes);\n    }\n}\n\nclass CustomCollection extends Collection\n{\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseEloquentBroadcastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Closure;\nuse Illuminate\\Broadcasting\\BroadcastEvent;\nuse Illuminate\\Contracts\\Broadcasting\\Broadcaster;\nuse Illuminate\\Contracts\\Broadcasting\\Factory as BroadcastingFactory;\nuse Illuminate\\Database\\Eloquent\\BroadcastableModelEventOccurred;\nuse Illuminate\\Database\\Eloquent\\BroadcastsEvents;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Mockery as m;\n\nclass DatabaseEloquentBroadcastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_eloquent_broadcasting_users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->softDeletes();\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicBroadcasting()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUser;\n        $model->name = 'Taylor';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUser\n                    && count($event->broadcastOn()) === 1\n                    && $event->model->name === 'Taylor'\n                    && $event->broadcastOn()[0]->name == \"private-Illuminate.Tests.Integration.Database.TestEloquentBroadcastUser.{$event->model->id}\";\n        });\n    }\n\n    public function testChannelRouteFormatting()\n    {\n        $model = new TestEloquentBroadcastUser;\n\n        $this->assertSame('Illuminate.Tests.Integration.Database.TestEloquentBroadcastUser.{testEloquentBroadcastUser}', $model->broadcastChannelRoute());\n    }\n\n    public function testBroadcastingOnModelTrashing()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new SoftDeletableTestEloquentBroadcastUser;\n        $model->name = 'Bean';\n        $model->saveQuietly();\n\n        $model->delete();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof SoftDeletableTestEloquentBroadcastUser\n                && $event->event() == 'trashed'\n                && count($event->broadcastOn()) === 1\n                && $event->model->name === 'Bean'\n                && $event->broadcastOn()[0]->name == \"private-Illuminate.Tests.Integration.Database.SoftDeletableTestEloquentBroadcastUser.{$event->model->id}\";\n        });\n    }\n\n    public function testBroadcastingForSpecificEventsOnly()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUserOnSpecificEventsOnly;\n        $model->name = 'James';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserOnSpecificEventsOnly\n                && $event->event() == 'created'\n                && count($event->broadcastOn()) === 1\n                && $event->model->name === 'James'\n                && $event->broadcastOn()[0]->name == \"private-Illuminate.Tests.Integration.Database.TestEloquentBroadcastUserOnSpecificEventsOnly.{$event->model->id}\";\n        });\n\n        $model->name = 'Graham';\n        $model->save();\n\n        Event::assertNotDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserOnSpecificEventsOnly\n                && $event->model->name === 'Graham'\n                && $event->event() == 'updated';\n        });\n    }\n\n    public function testBroadcastNameDefault()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUser;\n        $model->name = 'Mohamed';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUser\n                && $event->model->name === 'Mohamed'\n                && $event->broadcastAs() === 'TestEloquentBroadcastUserCreated'\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return $eventName === 'TestEloquentBroadcastUserCreated';\n                });\n        });\n    }\n\n    public function testBroadcastNameCanBeDefined()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUserWithSpecificBroadcastName;\n        $model->name = 'Nuno';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastName\n                && $event->model->name === 'Nuno'\n                && $event->broadcastAs() === 'foo'\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return $eventName === 'foo';\n                });\n        });\n\n        $model->name = 'Dries';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastName\n                && $event->model->name === 'Dries'\n                && $event->broadcastAs() === 'TestEloquentBroadcastUserWithSpecificBroadcastNameUpdated'\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return $eventName === 'TestEloquentBroadcastUserWithSpecificBroadcastNameUpdated';\n                });\n        });\n    }\n\n    public function testBroadcastPayloadDefault()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUser;\n        $model->name = 'Nuno';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUser\n                && $event->model->name === 'Nuno'\n                && is_null($event->broadcastWith())\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return Arr::has($payload, ['model', 'connection', 'queue', 'socket']);\n                });\n        });\n    }\n\n    public function testBroadcastPayloadCanBeDefined()\n    {\n        Event::fake([BroadcastableModelEventOccurred::class]);\n\n        $model = new TestEloquentBroadcastUserWithSpecificBroadcastPayload;\n        $model->name = 'Dries';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastPayload\n                && $event->model->name === 'Dries'\n                && $event->broadcastWith() === ['foo' => 'bar']\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return Arr::has($payload, ['foo', 'socket']);\n                });\n        });\n\n        $model->name = 'Graham';\n        $model->save();\n\n        Event::assertDispatched(function (BroadcastableModelEventOccurred $event) {\n            return $event->model instanceof TestEloquentBroadcastUserWithSpecificBroadcastPayload\n                && $event->model->name === 'Graham'\n                && is_null($event->broadcastWith())\n                && $this->assertHandldedBroadcastableEvent($event, function (array $channels, string $eventName, array $payload) {\n                    return Arr::has($payload, ['model', 'connection', 'queue', 'socket']);\n                });\n        });\n    }\n\n    private function assertHandldedBroadcastableEvent(BroadcastableModelEventOccurred $event, Closure $closure)\n    {\n        $broadcaster = m::mock(Broadcaster::class);\n        $broadcaster->shouldReceive('broadcast')->once()\n            ->withArgs(function (array $channels, string $eventName, array $payload) use ($closure) {\n                return $closure($channels, $eventName, $payload);\n            });\n\n        $manager = m::mock(BroadcastingFactory::class);\n        $manager->shouldReceive('connection')->once()->with(null)->andReturn($broadcaster);\n\n        (new BroadcastEvent($event))->handle($manager);\n\n        return true;\n    }\n}\n\nclass TestEloquentBroadcastUser extends Model\n{\n    use BroadcastsEvents;\n\n    protected $table = 'test_eloquent_broadcasting_users';\n}\n\nclass SoftDeletableTestEloquentBroadcastUser extends Model\n{\n    use BroadcastsEvents, SoftDeletes;\n\n    protected $table = 'test_eloquent_broadcasting_users';\n}\n\nclass TestEloquentBroadcastUserOnSpecificEventsOnly extends Model\n{\n    use BroadcastsEvents;\n\n    protected $table = 'test_eloquent_broadcasting_users';\n\n    public function broadcastOn($event)\n    {\n        switch ($event) {\n            case 'created':\n                return [$this];\n        }\n    }\n}\n\nclass TestEloquentBroadcastUserWithSpecificBroadcastName extends Model\n{\n    use BroadcastsEvents;\n\n    protected $table = 'test_eloquent_broadcasting_users';\n\n    public function broadcastAs($event)\n    {\n        switch ($event) {\n            case 'created':\n                return 'foo';\n        }\n    }\n}\n\nclass TestEloquentBroadcastUserWithSpecificBroadcastPayload extends Model\n{\n    use BroadcastsEvents;\n\n    protected $table = 'test_eloquent_broadcasting_users';\n\n    public function broadcastWith($event)\n    {\n        switch ($event) {\n            case 'created':\n                return ['foo' => 'bar'];\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseEloquentModelAttributeCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass DatabaseEloquentModelAttributeCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_eloquent_model_with_custom_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicCustomCasting()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n        $model->uppercase = 'taylor';\n\n        $this->assertSame('TAYLOR', $model->uppercase);\n        $this->assertSame('TAYLOR', $model->getAttributes()['uppercase']);\n        $this->assertSame('TAYLOR', $model->toArray()['uppercase']);\n\n        $unserializedModel = unserialize(serialize($model));\n\n        $this->assertSame('TAYLOR', $unserializedModel->uppercase);\n        $this->assertSame('TAYLOR', $unserializedModel->getAttributes()['uppercase']);\n        $this->assertSame('TAYLOR', $unserializedModel->toArray()['uppercase']);\n\n        $model->syncOriginal();\n        $model->uppercase = 'dries';\n        $this->assertSame('TAYLOR', $model->getOriginal('uppercase'));\n\n        $model = new TestEloquentModelWithAttributeCast;\n        $model->uppercase = 'taylor';\n        $model->syncOriginal();\n        $model->uppercase = 'dries';\n        $model->getOriginal();\n\n        $this->assertSame('DRIES', $model->uppercase);\n\n        $model = $model->setAttribute('uppercase', 'james');\n\n        $this->assertInstanceOf(TestEloquentModelWithAttributeCast::class, $model);\n\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $model->address = $address = new AttributeCastAddress('110 Kingsbrook St.', 'My Childhood House');\n        $address->lineOne = '117 Spencer St.';\n        $this->assertSame('117 Spencer St.', $model->getAttributes()['address_line_one']);\n\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $model->setRawAttributes([\n            'address_line_one' => '110 Kingsbrook St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('110 Kingsbrook St.', $model->address->lineOne);\n        $this->assertSame('My Childhood House', $model->address->lineTwo);\n\n        $this->assertSame('110 Kingsbrook St.', $model->toArray()['address_line_one']);\n        $this->assertSame('My Childhood House', $model->toArray()['address_line_two']);\n\n        $model->address->lineOne = '117 Spencer St.';\n\n        $this->assertFalse(isset($model->toArray()['address']));\n        $this->assertSame('117 Spencer St.', $model->toArray()['address_line_one']);\n        $this->assertSame('My Childhood House', $model->toArray()['address_line_two']);\n\n        $this->assertSame('117 Spencer St.', json_decode($model->toJson(), true)['address_line_one']);\n        $this->assertSame('My Childhood House', json_decode($model->toJson(), true)['address_line_two']);\n\n        $model->address = null;\n\n        $this->assertNull($model->toArray()['address_line_one']);\n        $this->assertNull($model->toArray()['address_line_two']);\n\n        $model->options = ['foo' => 'bar'];\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $model->options = ['foo' => 'bar'];\n        $model->options = ['foo' => 'bar'];\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n\n        $this->assertSame(json_encode(['foo' => 'bar']), $model->getAttributes()['options']);\n\n        $model = new TestEloquentModelWithAttributeCast(['options' => []]);\n        $model->syncOriginal();\n        $model->options = ['foo' => 'bar'];\n        $this->assertTrue($model->isDirty('options'));\n\n        $model = new TestEloquentModelWithAttributeCast;\n        $model->birthday_at = Carbon::now();\n        $this->assertIsString($model->toArray()['birthday_at']);\n    }\n\n    public function testGetOriginalWithCastValueObjects()\n    {\n        $model = new TestEloquentModelWithAttributeCast([\n            'address' => new AttributeCastAddress('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = new AttributeCastAddress('117 Spencer St.', 'Another house.');\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal('address')->lineOne);\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n\n        $model = new TestEloquentModelWithAttributeCast([\n            'address' => new AttributeCastAddress('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = new AttributeCastAddress('117 Spencer St.', 'Another house.');\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal()['address_line_one']);\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal()['address_line_one']);\n\n        $model = new TestEloquentModelWithAttributeCast([\n            'address' => new AttributeCastAddress('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = null;\n\n        $this->assertNull($model->address);\n        $this->assertInstanceOf(AttributeCastAddress::class, $model->getOriginal('address'));\n        $this->assertNull($model->address);\n    }\n\n    public function testOneWayCasting()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $this->assertNull($model->password);\n\n        $model->password = 'secret';\n\n        $this->assertEquals(hash('sha256', 'secret'), $model->password);\n        $this->assertEquals(hash('sha256', 'secret'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret'), $model->password);\n\n        $model->password = 'secret2';\n\n        $this->assertEquals(hash('sha256', 'secret2'), $model->password);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->password);\n    }\n\n    public function testSettingRawAttributesClearsTheCastCache()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $model->setRawAttributes([\n            'address_line_one' => '110 Kingsbrook St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('110 Kingsbrook St.', $model->address->lineOne);\n\n        $model->setRawAttributes([\n            'address_line_one' => '117 Spencer St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n    }\n\n    public function testCastsThatOnlyHaveGetterDoNotPersistAnythingToModelOnSave()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $model->virtual;\n\n        $model->getAttributes();\n\n        $this->assertEmpty($model->getDirty());\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsPrimitivesAreNotCached()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = null;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertNotSame($previous, $previous = $model->virtualString);\n        }\n    }\n\n    public function testAttributesCanCacheStrings()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtual_string_cached;\n\n        $this->assertIsString($previous);\n\n        $this->assertSame($previous, $model->virtual_string_cached);\n    }\n\n    public function testAttributesCanCacheBooleans()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $first = $model->virtual_boolean_cached;\n\n        $this->assertIsBool($first);\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertSame($first, $model->virtual_boolean_cached);\n        }\n    }\n\n    public function testAttributesCanCacheNull()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $this->assertSame(0, $model->virtualNullCalls);\n\n        $first = $model->virtual_null_cached;\n\n        $this->assertNull($first);\n\n        $this->assertSame(1, $model->virtualNullCalls);\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertSame($first, $model->virtual_null_cached);\n        }\n\n        $this->assertSame(1, $model->virtualNullCalls);\n    }\n\n    public function testAttributesByDefaultDontCacheBooleans()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $first = $model->virtual_boolean;\n\n        $this->assertIsBool($first);\n\n        foreach (range(0, 50) as $ignored) {\n            $current = $model->virtual_boolean;\n\n            $this->assertIsBool($current);\n\n            if ($first !== $current) {\n                return;\n            }\n        }\n\n        $this->fail('\"virtual_boolean\" seems to be cached.');\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsObjectAreCached()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualObject;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertSame($previous, $previous = $model->virtualObject);\n        }\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsDateTimeAreCached()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualDateTime;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertSame($previous, $previous = $model->virtualDateTime);\n        }\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsObjectAreNotCached()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualObjectWithoutCaching;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertNotSame($previous, $previous = $model->virtualObjectWithoutCaching);\n        }\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsDateTimeAreNotCached()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualDateTimeWithoutCaching;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertNotSame($previous, $previous = $model->virtualDateTimeWithoutCaching);\n        }\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsObjectAreNotCachedFluent()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualObjectWithoutCachingFluent;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertNotSame($previous, $previous = $model->virtualObjectWithoutCachingFluent);\n        }\n    }\n\n    public function testCastsThatOnlyHaveGetterThatReturnsDateTimeAreNotCachedFluent()\n    {\n        $model = new TestEloquentModelWithAttributeCast;\n\n        $previous = $model->virtualDateTimeWithoutCachingFluent;\n\n        foreach (range(0, 10) as $ignored) {\n            $this->assertNotSame($previous, $previous = $model->virtualDateTimeWithoutCachingFluent);\n        }\n    }\n}\n\nclass TestEloquentModelWithAttributeCast extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    public function uppercase(): Attribute\n    {\n        return Attribute::make(\n            function ($value) {\n                return strtoupper($value);\n            },\n            function ($value) {\n                return strtoupper($value);\n            }\n        );\n    }\n\n    public function address(): Attribute\n    {\n        return new Attribute(\n            function ($value, $attributes) {\n                if (is_null($attributes['address_line_one'])) {\n                    return;\n                }\n\n                return new AttributeCastAddress($attributes['address_line_one'], $attributes['address_line_two']);\n            },\n            function ($value) {\n                if (is_null($value)) {\n                    return [\n                        'address_line_one' => null,\n                        'address_line_two' => null,\n                    ];\n                }\n\n                return ['address_line_one' => $value->lineOne, 'address_line_two' => $value->lineTwo];\n            }\n        );\n    }\n\n    public function options(): Attribute\n    {\n        return new Attribute(\n            function ($value) {\n                return json_decode($value, true);\n            },\n            function ($value) {\n                return json_encode($value);\n            }\n        );\n    }\n\n    public function birthdayAt(): Attribute\n    {\n        return new Attribute(\n            function ($value) {\n                return Carbon::parse($value);\n            },\n            function ($value) {\n                return $value->format('Y-m-d');\n            }\n        );\n    }\n\n    public function password(): Attribute\n    {\n        return new Attribute(null, function ($value) {\n            return hash('sha256', $value);\n        });\n    }\n\n    public function virtual(): Attribute\n    {\n        return new Attribute(\n            function () {\n                return collect();\n            }\n        );\n    }\n\n    public function virtualString(): Attribute\n    {\n        return new Attribute(\n            function () {\n                return Str::random(10);\n            }\n        );\n    }\n\n    public function virtualStringCached(): Attribute\n    {\n        return Attribute::get(function () {\n            return Str::random(10);\n        })->shouldCache();\n    }\n\n    public function virtualBooleanCached(): Attribute\n    {\n        return Attribute::get(function () {\n            return (bool) mt_rand(0, 1);\n        })->shouldCache();\n    }\n\n    public function virtualBoolean(): Attribute\n    {\n        return Attribute::get(function () {\n            return (bool) mt_rand(0, 1);\n        });\n    }\n\n    public $virtualNullCalls = 0;\n\n    public function virtualNullCached(): Attribute\n    {\n        return Attribute::get(function () {\n            $this->virtualNullCalls++;\n\n            return null;\n        })->shouldCache();\n    }\n\n    public function virtualObject(): Attribute\n    {\n        return new Attribute(\n            function () {\n                return new AttributeCastAddress(Str::random(10), Str::random(10));\n            }\n        );\n    }\n\n    public function virtualDateTime(): Attribute\n    {\n        return new Attribute(\n            function () {\n                return Date::now()->addSeconds(mt_rand(0, 10000));\n            }\n        );\n    }\n\n    public function virtualObjectWithoutCachingFluent(): Attribute\n    {\n        return (new Attribute(\n            function () {\n                return new AttributeCastAddress(Str::random(10), Str::random(10));\n            }\n        ))->withoutObjectCaching();\n    }\n\n    public function virtualDateTimeWithoutCachingFluent(): Attribute\n    {\n        return (new Attribute(\n            function () {\n                return Date::now()->addSeconds(mt_rand(0, 10000));\n            }\n        ))->withoutObjectCaching();\n    }\n\n    public function virtualObjectWithoutCaching(): Attribute\n    {\n        return Attribute::get(function () {\n            return new AttributeCastAddress(Str::random(10), Str::random(10));\n        })->withoutObjectCaching();\n    }\n\n    public function virtualDateTimeWithoutCaching(): Attribute\n    {\n        return Attribute::get(function () {\n            return Date::now()->addSeconds(mt_rand(0, 10000));\n        })->withoutObjectCaching();\n    }\n}\n\nclass AttributeCastAddress\n{\n    public $lineOne;\n    public $lineTwo;\n\n    public function __construct($lineOne, $lineTwo)\n    {\n        $this->lineOne = $lineOne;\n        $this->lineTwo = $lineTwo;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseEloquentModelCustomCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Exception;\nuse Illuminate\\Contracts\\Database\\Eloquent\\Castable;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\DeviatesCastableAttributes;\nuse Illuminate\\Contracts\\Database\\Eloquent\\SerializesCastableAttributes;\nuse Illuminate\\Database\\Eloquent\\InvalidCastException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseEloquentModelCustomCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_eloquent_model_with_custom_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n            $table->decimal('price');\n        });\n    }\n\n    public function testBasicCustomCasting()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n        $model->uppercase = 'taylor';\n\n        $this->assertSame('TAYLOR', $model->uppercase);\n        $this->assertSame('TAYLOR', $model->getAttributes()['uppercase']);\n        $this->assertSame('TAYLOR', $model->toArray()['uppercase']);\n\n        $unserializedModel = unserialize(serialize($model));\n\n        $this->assertSame('TAYLOR', $unserializedModel->uppercase);\n        $this->assertSame('TAYLOR', $unserializedModel->getAttributes()['uppercase']);\n        $this->assertSame('TAYLOR', $unserializedModel->toArray()['uppercase']);\n\n        $model->syncOriginal();\n        $model->uppercase = 'dries';\n        $this->assertSame('TAYLOR', $model->getOriginal('uppercase'));\n\n        $model = new TestEloquentModelWithCustomCast;\n        $model->uppercase = 'taylor';\n        $model->syncOriginal();\n        $model->uppercase = 'dries';\n        $model->getOriginal();\n\n        $this->assertSame('DRIES', $model->uppercase);\n\n        $model = new TestEloquentModelWithCustomCast;\n\n        $model->address = $address = new Address('110 Kingsbrook St.', 'My Childhood House');\n        $address->lineOne = '117 Spencer St.';\n        $this->assertSame('117 Spencer St.', $model->getAttributes()['address_line_one']);\n\n        $model = new TestEloquentModelWithCustomCast;\n\n        $model->setRawAttributes([\n            'address_line_one' => '110 Kingsbrook St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('110 Kingsbrook St.', $model->address->lineOne);\n        $this->assertSame('My Childhood House', $model->address->lineTwo);\n\n        $this->assertSame('110 Kingsbrook St.', $model->toArray()['address_line_one']);\n        $this->assertSame('My Childhood House', $model->toArray()['address_line_two']);\n\n        $model->address->lineOne = '117 Spencer St.';\n\n        $this->assertFalse(isset($model->toArray()['address']));\n        $this->assertSame('117 Spencer St.', $model->toArray()['address_line_one']);\n        $this->assertSame('My Childhood House', $model->toArray()['address_line_two']);\n\n        $this->assertSame('117 Spencer St.', json_decode($model->toJson(), true)['address_line_one']);\n        $this->assertSame('My Childhood House', json_decode($model->toJson(), true)['address_line_two']);\n\n        $model->address = null;\n\n        $this->assertNull($model->toArray()['address_line_one']);\n        $this->assertNull($model->toArray()['address_line_two']);\n\n        $model->options = ['foo' => 'bar'];\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $model->options = ['foo' => 'bar'];\n        $model->options = ['foo' => 'bar'];\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n        $this->assertEquals(['foo' => 'bar'], $model->options);\n\n        $this->assertSame(json_encode(['foo' => 'bar']), $model->getAttributes()['options']);\n\n        $model = new TestEloquentModelWithCustomCast(['options' => []]);\n        $model->syncOriginal();\n        $model->options = ['foo' => 'bar'];\n        $this->assertTrue($model->isDirty('options'));\n\n        $model = new TestEloquentModelWithCustomCast;\n        $model->birthday_at = Carbon::now();\n        $this->assertIsString($model->toArray()['birthday_at']);\n\n        $model = new TestEloquentModelWithCustomCast;\n        $now = Carbon::now()->toImmutable();\n        $model->anniversary_on_with_object_caching = $now;\n        $model->anniversary_on_without_object_caching = $now;\n        $this->assertSame($now, $model->anniversary_on_with_object_caching);\n        $this->assertSame('UTC', $model->anniversary_on_with_object_caching->format('e'));\n        $this->assertNotSame($now, $model->anniversary_on_without_object_caching);\n        $this->assertNotSame('UTC', $model->anniversary_on_without_object_caching->format('e'));\n    }\n\n    public function testGetOriginalWithCastValueObjects()\n    {\n        $model = new TestEloquentModelWithCustomCast([\n            'address' => new Address('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = new Address('117 Spencer St.', 'Another house.');\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal('address')->lineOne);\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n\n        $model = new TestEloquentModelWithCustomCast([\n            'address' => new Address('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = new Address('117 Spencer St.', 'Another house.');\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal()['address_line_one']);\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n        $this->assertSame('110 Kingsbrook St.', $model->getOriginal()['address_line_one']);\n\n        $model = new TestEloquentModelWithCustomCast([\n            'address' => new Address('110 Kingsbrook St.', 'My Childhood House'),\n        ]);\n\n        $model->syncOriginal();\n\n        $model->address = null;\n\n        $this->assertNull($model->address);\n        $this->assertInstanceOf(Address::class, $model->getOriginal('address'));\n        $this->assertNull($model->address);\n    }\n\n    public function testDeviableCasts()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n        $model->price = '123.456';\n        $model->save();\n\n        $model->increment('price', '530.865');\n\n        $this->assertSame((new Decimal('654.321'))->getValue(), $model->price->getValue());\n\n        $model->decrement('price', '333.333');\n\n        $this->assertSame((new Decimal('320.988'))->getValue(), $model->price->getValue());\n\n        $model->increment('price', new Decimal('100.001'));\n\n        $this->assertSame((new Decimal('420.989'))->getValue(), $model->price->getValue());\n\n        $model->decrement('price', new Decimal('200.002'));\n\n        $this->assertSame((new Decimal('220.987'))->getValue(), $model->price->getValue());\n    }\n\n    public function testSerializableCasts()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n        $model->price = '123.456';\n\n        $expectedValue = (new Decimal('123.456'))->getValue();\n\n        $this->assertSame($expectedValue, $model->price->getValue());\n        $this->assertSame('123.456', $model->getAttributes()['price']);\n        $this->assertSame('123.456', $model->toArray()['price']);\n\n        $unserializedModel = unserialize(serialize($model));\n\n        $this->assertSame($expectedValue, $unserializedModel->price->getValue());\n        $this->assertSame('123.456', $unserializedModel->getAttributes()['price']);\n        $this->assertSame('123.456', $unserializedModel->toArray()['price']);\n    }\n\n    public function testOneWayCasting()\n    {\n        // CastsInboundAttributes is used for casting that is unidirectional... only use case I can think of is one-way hashing...\n        $model = new TestEloquentModelWithCustomCast;\n\n        $model->password = 'secret';\n\n        $this->assertEquals(hash('sha256', 'secret'), $model->password);\n        $this->assertEquals(hash('sha256', 'secret'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret'), $model->password);\n\n        $model->password = 'secret2';\n\n        $this->assertEquals(hash('sha256', 'secret2'), $model->password);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->getAttributes()['password']);\n        $this->assertEquals(hash('sha256', 'secret2'), $model->password);\n    }\n\n    public function testSettingRawAttributesClearsTheCastCache()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n\n        $model->setRawAttributes([\n            'address_line_one' => '110 Kingsbrook St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('110 Kingsbrook St.', $model->address->lineOne);\n\n        $model->setRawAttributes([\n            'address_line_one' => '117 Spencer St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n\n        $this->assertSame('117 Spencer St.', $model->address->lineOne);\n    }\n\n    public function testSettingAttributesUsingArrowClearsTheCastCache()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n        $model->typed_settings = ['foo' => true];\n\n        $this->assertTrue($model->typed_settings->foo);\n\n        $model->setAttribute('typed_settings->foo', false);\n\n        $this->assertFalse($model->typed_settings->foo);\n    }\n\n    public function testWithCastableInterface()\n    {\n        $model = new TestEloquentModelWithCustomCast;\n\n        $model->setRawAttributes([\n            'value_object_with_caster' => serialize(new ValueObject('hello')),\n        ]);\n\n        $this->assertInstanceOf(ValueObject::class, $model->value_object_with_caster);\n        $this->assertSame(serialize(new ValueObject('hello')), $model->toArray()['value_object_with_caster']);\n\n        $model->setRawAttributes([\n            'value_object_caster_with_argument' => null,\n        ]);\n\n        $this->assertSame('argument', $model->value_object_caster_with_argument);\n\n        $model->setRawAttributes([\n            'value_object_caster_with_caster_instance' => serialize(new ValueObject('hello')),\n        ]);\n\n        $this->assertInstanceOf(ValueObject::class, $model->value_object_caster_with_caster_instance);\n    }\n\n    public function testGetFromUndefinedCast()\n    {\n        $this->expectException(InvalidCastException::class);\n\n        $model = new TestEloquentModelWithCustomCast;\n        $model->undefined_cast_column;\n    }\n\n    public function testSetToUndefinedCast()\n    {\n        $this->expectException(InvalidCastException::class);\n\n        $model = new TestEloquentModelWithCustomCast;\n        $this->assertTrue($model->hasCast('undefined_cast_column'));\n\n        $model->undefined_cast_column = 'Glāžšķūņu rūķīši';\n    }\n\n    public function testMutatorCanDependOnAnotherCastedAttribute()\n    {\n        $model = new TestEloquentModelWithCustomCast([\n            'address_line_one' => '110 Kingsbrook St.',\n            'address_line_two' => 'My Childhood House',\n        ]);\n        $model->address->lineOne = 'Changed St.';\n        $this->assertSame('Changed St. (My Childhood House)', $model->address_string);\n    }\n\n    public function testMutatorCanDependOnAnotherCastedCarbonAttribute()\n    {\n        $model = new TestEloquentModelWithCustomCast([\n            'dob' => '2000-11-11',\n            'tob' => '2000-11-11 11:11:00',\n        ]);\n\n        $model->dob->addDay();\n        $this->assertSame('2000-11-12 11:11:00', $model->tob);\n    }\n}\n\nclass TestEloquentModelWithCustomCast extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * The attributes that should be cast to native types.\n     *\n     * @var array\n     */\n    protected $casts = [\n        'dob' => DOBCaster::class,\n        'address' => AddressCaster::class,\n        'price' => DecimalCaster::class,\n        'password' => HashCaster::class,\n        'other_password' => HashCaster::class.':md5',\n        'uppercase' => UppercaseCaster::class,\n        'options' => JsonCaster::class,\n        'typed_settings' => JsonSettingsCaster::class,\n        'value_object_with_caster' => ValueObject::class,\n        'value_object_caster_with_argument' => ValueObject::class.':argument',\n        'value_object_caster_with_caster_instance' => ValueObjectWithCasterInstance::class,\n        'undefined_cast_column' => UndefinedCast::class,\n        'birthday_at' => DateObjectCaster::class,\n        'anniversary_on_with_object_caching' => DateTimezoneCasterWithObjectCaching::class.':America/New_York',\n        'anniversary_on_without_object_caching' => DateTimezoneCasterWithoutObjectCaching::class.':America/New_York',\n    ];\n\n    protected function getTobAttribute(?string $value): ?string\n    {\n        if ($value === null) {\n            return null;\n        }\n\n        if (isset($this->attributes['dob'])) {\n            return Carbon::parse($this->attributes['dob'])->toDateString().' '.\n                Carbon::parse($value)->toTimeString();\n        }\n\n        return Carbon::parse($value)->toDateTimeString();\n    }\n\n    /**\n     * A computed attribute that depends on another casted attribute.\n     *\n     * This simulates a mutator that uses the value of a casted property.\n     */\n    protected function addressString(): \\Illuminate\\Database\\Eloquent\\Casts\\Attribute\n    {\n        return \\Illuminate\\Database\\Eloquent\\Casts\\Attribute::get(function () {\n            $address = $this->address;\n\n            // If mergeAttributesFromClassCasts() hasn't prepared casts properly,\n            // this could be an array instead of an Address instance.\n            if (! $address instanceof Address) {\n                throw new \\RuntimeException('Address was not cast before mutator access.');\n            }\n\n            return \"{$address->lineOne} ({$address->lineTwo})\";\n        });\n    }\n}\n\nclass DOBCaster implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        if ($value === null) {\n            return null;\n        }\n\n        return Carbon::parse($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        if ($value instanceof Carbon) {\n            return [$key => $value->toDateString()];\n        }\n\n        if ($value === null) {\n            return [$key => null];\n        }\n\n        return [$key => (string) $value];\n    }\n}\n\nclass HashCaster implements CastsInboundAttributes\n{\n    protected $algorithm;\n\n    public function __construct($algorithm = 'sha256')\n    {\n        $this->algorithm = $algorithm;\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return [$key => hash($this->algorithm, $value)];\n    }\n}\n\nclass UppercaseCaster implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return strtoupper($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return [$key => strtoupper($value)];\n    }\n}\n\nclass AddressCaster implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        if (is_null($attributes['address_line_one'])) {\n            return;\n        }\n\n        return new Address($attributes['address_line_one'], $attributes['address_line_two']);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        if (is_null($value)) {\n            return [\n                'address_line_one' => null,\n                'address_line_two' => null,\n            ];\n        }\n\n        return ['address_line_one' => $value->lineOne, 'address_line_two' => $value->lineTwo];\n    }\n}\n\nclass JsonCaster implements CastsAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return json_decode($value, true);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return json_encode($value);\n    }\n}\n\nclass JsonSettingsCaster implements CastsAttributes\n{\n    public function get($model, string $key, $value, array $attributes): ?Settings\n    {\n        if ($value === null) {\n            return null;\n        }\n\n        if ($value instanceof Settings) {\n            return $value;\n        }\n\n        $payload = json_decode($value, true, JSON_THROW_ON_ERROR);\n\n        return Settings::from($payload);\n    }\n\n    public function set($model, string $key, $value, array $attributes): ?string\n    {\n        if ($value === null) {\n            return null;\n        }\n\n        if (is_array($value)) {\n            $value = Settings::from($value);\n        }\n\n        if (! $value instanceof Settings) {\n            throw new Exception(\"Attribute `{$key}` with JsonSettingsCaster should be a Settings object\");\n        }\n\n        return $value->toJson();\n    }\n}\n\nclass DecimalCaster implements CastsAttributes, DeviatesCastableAttributes, SerializesCastableAttributes\n{\n    public function get($model, $key, $value, $attributes)\n    {\n        return new Decimal($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return (string) $value;\n    }\n\n    public function increment($model, $key, $value, $attributes)\n    {\n        return new Decimal($attributes[$key] + ($value instanceof Decimal ? (string) $value : $value));\n    }\n\n    public function decrement($model, $key, $value, $attributes)\n    {\n        return new Decimal($attributes[$key] - ($value instanceof Decimal ? (string) $value : $value));\n    }\n\n    public function serialize($model, $key, $value, $attributes)\n    {\n        return (string) $value;\n    }\n}\n\nclass ValueObjectCaster implements CastsAttributes\n{\n    private $argument;\n\n    public function __construct($argument = null)\n    {\n        $this->argument = $argument;\n    }\n\n    public function get($model, $key, $value, $attributes)\n    {\n        if ($this->argument) {\n            return $this->argument;\n        }\n\n        return unserialize($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return serialize($value);\n    }\n}\n\nclass ValueObject implements Castable\n{\n    public $name;\n\n    public function __construct(string $name)\n    {\n        $this->name = $name;\n    }\n\n    public static function castUsing(array $arguments)\n    {\n        return new class(...$arguments) implements CastsAttributes, SerializesCastableAttributes\n        {\n            private $argument;\n\n            public function __construct($argument = null)\n            {\n                $this->argument = $argument;\n            }\n\n            public function get($model, $key, $value, $attributes)\n            {\n                if ($this->argument) {\n                    return $this->argument;\n                }\n\n                return unserialize($value);\n            }\n\n            public function set($model, $key, $value, $attributes)\n            {\n                return serialize($value);\n            }\n\n            public function serialize($model, $key, $value, $attributes)\n            {\n                return serialize($value);\n            }\n        };\n    }\n}\n\nclass ValueObjectWithCasterInstance extends ValueObject\n{\n    public static function castUsing(array $arguments)\n    {\n        return new ValueObjectCaster;\n    }\n}\n\nclass Address\n{\n    public $lineOne;\n    public $lineTwo;\n\n    public function __construct($lineOne, $lineTwo)\n    {\n        $this->lineOne = $lineOne;\n        $this->lineTwo = $lineTwo;\n    }\n}\n\nclass Settings\n{\n    public ?bool $foo;\n    public ?bool $bar;\n\n    public function __construct(?bool $foo, ?bool $bar)\n    {\n        $this->foo = $foo;\n        $this->bar = $bar;\n    }\n\n    public static function from(array $data): Settings\n    {\n        return new self(\n            $data['foo'] ?? null,\n            $data['bar'] ?? null,\n        );\n    }\n\n    public function toJson($options = 0): string\n    {\n        return json_encode(['foo' => $this->foo, 'bar' => $this->bar], $options);\n    }\n}\n\nfinal class Decimal\n{\n    private $value;\n    private $scale;\n\n    public function __construct($value)\n    {\n        $parts = explode('.', (string) $value);\n\n        $this->scale = strlen($parts[1]);\n        $this->value = (int) str_replace('.', '', $value);\n    }\n\n    public function getValue()\n    {\n        return $this->value;\n    }\n\n    public function __toString()\n    {\n        return substr_replace($this->value, '.', -$this->scale, 0);\n    }\n}\n\nclass DateObjectCaster implements CastsAttributes\n{\n    private $argument;\n\n    public function __construct($argument = null)\n    {\n        $this->argument = $argument;\n    }\n\n    public function get($model, $key, $value, $attributes)\n    {\n        return Carbon::parse($value);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return $value->format('Y-m-d');\n    }\n}\n\nclass DateTimezoneCasterWithObjectCaching implements CastsAttributes\n{\n    public function __construct(private string $timezone = 'UTC')\n    {\n    }\n\n    public function get($model, $key, $value, $attributes)\n    {\n        return Carbon::parse($value, $this->timezone);\n    }\n\n    public function set($model, $key, $value, $attributes)\n    {\n        return $value->timezone($this->timezone)->format('Y-m-d');\n    }\n}\n\nclass DateTimezoneCasterWithoutObjectCaching extends DateTimezoneCasterWithObjectCaching\n{\n    public bool $withoutObjectCaching = true;\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseLockTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Cache\\DatabaseLock;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\DB;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse PDOException;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\n#[WithMigration('cache')]\nclass DatabaseLockTest extends DatabaseTestCase\n{\n    public function testLockCanHaveASeparateConnection()\n    {\n        $this->app['config']->set('cache.stores.database.lock_connection', 'test');\n        $this->app['config']->set('database.connections.test', $this->app['config']->get('database.connections.mysql'));\n\n        $this->assertSame('test', Cache::driver('database')->lock('foo')->getConnectionName());\n    }\n\n    public function testLockCanBeAcquired()\n    {\n        $lock = Cache::driver('database')->lock('foo');\n        $this->assertTrue($lock->get());\n\n        $otherLock = Cache::driver('database')->lock('foo');\n        $this->assertFalse($otherLock->get());\n\n        $lock->release();\n\n        $otherLock = Cache::driver('database')->lock('foo');\n        $this->assertTrue($otherLock->get());\n\n        $otherLock->release();\n    }\n\n    public function testLockCanBeForceReleased()\n    {\n        $lock = Cache::driver('database')->lock('foo');\n        $this->assertTrue($lock->get());\n\n        $otherLock = Cache::driver('database')->lock('foo');\n        $otherLock->forceRelease();\n        $this->assertTrue($otherLock->get());\n\n        $otherLock->release();\n    }\n\n    public function testExpiredLockCanBeRetrieved()\n    {\n        $lock = Cache::driver('database')->lock('foo');\n        $this->assertTrue($lock->get());\n        DB::table('cache_locks')->update(['expiration' => Carbon::now()->subDays(1)->getTimestamp()]);\n\n        $otherLock = Cache::driver('database')->lock('foo');\n        $this->assertTrue($otherLock->get());\n\n        $otherLock->release();\n    }\n\n    public function testOtherOwnerDoesNotOwnLockAfterRestore()\n    {\n        $firstLock = Cache::store('database')->lock('foo');\n        $this->assertTrue($firstLock->isOwnedBy(null));\n        $this->assertTrue($firstLock->get());\n        $this->assertTrue($firstLock->isOwnedBy($firstLock->owner()));\n\n        $secondLock = Cache::store('database')->restoreLock('foo', 'other_owner');\n        $this->assertTrue($secondLock->isOwnedBy($firstLock->owner()));\n        $this->assertFalse($secondLock->isOwnedByCurrentProcess());\n    }\n\n    #[TestWith(['Deadlock found when trying to get lock', 1213, true])]\n    #[TestWith(['Table does not exist', 1146, false])]\n    public function testIgnoresConcurrencyException(string $message, int $code, bool $hasConcurrenyError)\n    {\n        $connection = m::mock(Connection::class);\n        $insertBuilder = m::mock(Builder::class);\n        $deleteBuilder = m::mock(Builder::class);\n\n        $insertBuilder->shouldReceive('insert')->once()->andReturn(true);\n\n        $deleteBuilder->shouldReceive('where')->with('expiration', '<=', m::any())->once()->andReturnSelf();\n        $deleteBuilder->shouldReceive('delete')->once()->andThrow(\n            new QueryException(\n                'mysql',\n                'delete from cache_locks where expiration <= ?',\n                [],\n                new PDOException($message, $code)\n            )\n        );\n\n        $connection->shouldReceive('table')->with('cache_locks')->andReturn($insertBuilder, $deleteBuilder);\n\n        $lock = new DatabaseLock($connection, 'cache_locks', 'foo', 0, lottery: [1, 1]);\n\n        if ($hasConcurrenyError) {\n            $this->assertTrue($lock->acquire());\n        } else {\n            $this->expectException(QueryException::class);\n            $this->assertFalse($lock->acquire());\n        }\n    }\n\n    #[TestWith(['Serialization failure: 1213 Deadlock', 40001, true])]\n    #[TestWith(['Table does not exist', 1146, false])]\n    public function testReleaseIgnoresConcurrencyException(string $message, int $code, bool $hasConcurrencyError)\n    {\n        $connection = m::mock(Connection::class);\n        $selectBuilder = m::mock(Builder::class);\n        $deleteBuilder = m::mock(Builder::class);\n\n        $owner = 'owner-123';\n\n        $selectBuilder->shouldReceive('where')->with('key', 'foo')->once()->andReturnSelf();\n        $selectBuilder->shouldReceive('first')->once()->andReturn((object) ['owner' => $owner]);\n\n        $deleteBuilder->shouldReceive('where')->with('key', 'foo')->once()->andReturnSelf();\n        $deleteBuilder->shouldReceive('where')->with('owner', $owner)->once()->andReturnSelf();\n        $deleteBuilder->shouldReceive('delete')->once()->andThrow(\n            new QueryException(\n                'mysql',\n                'delete from cache_locks where key = ? and owner = ?',\n                ['foo', $owner],\n                new PDOException($message, $code)\n            )\n        );\n\n        $connection->shouldReceive('table')->with('cache_locks')->andReturn($selectBuilder, $deleteBuilder);\n\n        $lock = new DatabaseLock($connection, 'cache_locks', 'foo', 10, $owner); // same owner...\n\n        if ($hasConcurrencyError) {\n            $this->assertTrue($lock->release());\n        } else {\n            $this->expectException(QueryException::class);\n            $this->expectExceptionMessage($message);\n            $lock->release();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Orchestra\\Testbench\\TestCase;\n\nabstract class DatabaseTestCase extends TestCase\n{\n    use DatabaseMigrations;\n\n    /**\n     * The current database driver.\n     *\n     * @return string\n     */\n    protected $driver;\n\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            foreach (array_keys($this->app['db']->getConnections()) as $name) {\n                $this->app['db']->purge($name);\n            }\n        });\n\n        parent::setUp();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $connection = $app['config']->get('database.default');\n\n        $this->driver = $app['config']->get(\"database.connections.$connection.driver\");\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/DatabaseTransactionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Support\\Facades\\DB;\n\nclass DatabaseTransactionsTest extends DatabaseTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set([\n            'database.connections.second_connection' => [\n                'driver' => 'sqlite',\n                'database' => ':memory:',\n            ],\n        ]);\n    }\n\n    public function testTransactionCallbacks()\n    {\n        [$firstObject, $secondObject, $thirdObject] = [\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n        ];\n\n        DB::transaction(function () use ($secondObject, $firstObject) {\n            DB::afterCommit(fn () => $firstObject->handle());\n\n            DB::transaction(function () use ($secondObject) {\n                DB::afterCommit(fn () => $secondObject->handle());\n            });\n        });\n\n        $this->assertTrue($firstObject->ran);\n        $this->assertTrue($secondObject->ran);\n        $this->assertEquals(1, $firstObject->runs);\n        $this->assertEquals(1, $secondObject->runs);\n        $this->assertFalse($thirdObject->ran);\n    }\n\n    public function testTransactionCallbacksDoNotInterfereWithOneAnother()\n    {\n        [$firstObject, $secondObject, $thirdObject] = [\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n        ];\n\n        // The problem here is that we're initiating a base transaction, and then two nested transactions.\n        // Although these two nested transactions are not the same, they share the same level (2).\n        // Since they are not the same, the latter one failing should not affect the first one.\n        DB::transaction(function () use ($thirdObject, $secondObject, $firstObject) { // Adds a transaction @ level 1\n            DB::transaction(function () use ($firstObject) { // Adds a transaction @ level 2\n                DB::afterCommit(fn () => $firstObject->handle()); // Adds a callback to be executed after transaction level 2 is committed\n            });\n\n            DB::afterCommit(fn () => $secondObject->handle()); // Adds a callback to be executed after transaction 1 @ lvl 1\n\n            try {\n                DB::transaction(function () use ($thirdObject) { // Adds a transaction 3 @ level 2\n                    DB::afterCommit(fn () => $thirdObject->handle());\n                    throw new \\Exception(); // This should only affect callback 3, not 1, even though both share the same transaction level.\n                });\n            } catch (\\Exception) {\n            }\n        });\n\n        $this->assertTrue($firstObject->ran);\n        $this->assertTrue($secondObject->ran);\n        $this->assertEquals(1, $firstObject->runs);\n        $this->assertEquals(1, $secondObject->runs);\n        $this->assertFalse($thirdObject->ran);\n    }\n\n    public function testTransactionsDoNotAffectDifferentConnections()\n    {\n        [$firstObject, $secondObject, $thirdObject] = [\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n            new TestObjectForTransactions(),\n        ];\n\n        DB::transaction(function () use ($secondObject, $firstObject, $thirdObject) {\n            DB::transaction(function () use ($secondObject) {\n                DB::afterCommit(fn () => $secondObject->handle());\n            });\n\n            DB::afterCommit(fn () => $firstObject->handle());\n\n            try {\n                DB::connection('second_connection')->transaction(function () use ($thirdObject) {\n                    DB::afterCommit(fn () => $thirdObject->handle());\n\n                    throw new \\Exception;\n                });\n            } catch (\\Exception) {\n                //\n            }\n        });\n\n        $this->assertTrue($firstObject->ran);\n        $this->assertTrue($secondObject->ran);\n        $this->assertFalse($thirdObject->ran);\n    }\n\n    public function testAfterRollbackCallbacksAreExecuted()\n    {\n        $afterCommitRan = false;\n        $afterRollbackRan = false;\n\n        try {\n            DB::transaction(function () use (&$afterCommitRan, &$afterRollbackRan) {\n                DB::afterCommit(function () use (&$afterCommitRan) {\n                    $afterCommitRan = true;\n                });\n\n                DB::afterRollBack(function () use (&$afterRollbackRan) {\n                    $afterRollbackRan = true;\n                });\n\n                throw new \\RuntimeException('rollback');\n            });\n        } catch (\\RuntimeException) {\n            // Ignore the expected rollback exception.\n        }\n\n        $this->assertFalse($afterCommitRan);\n        $this->assertTrue($afterRollbackRan);\n    }\n}\n\nclass TestObjectForTransactions\n{\n    public $ran = false;\n\n    public $runs = 0;\n\n    public function handle()\n    {\n        $this->ran = true;\n        $this->runs++;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentAggregateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentAggregateTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('c');\n            $table->string('name');\n            $table->integer('balance')->nullable();\n        });\n    }\n\n    public function testMinMax()\n    {\n        UserAggregateTest::create(['c' => 1, 'name' => 'test-name1', 'balance' => -1]);\n        UserAggregateTest::create(['c' => 2, 'name' => 'test-name2', 'balance' => -1]);\n        UserAggregateTest::create(['c' => 3, 'name' => 'test-name3', 'balance' => 0]);\n        UserAggregateTest::create(['c' => 4, 'name' => 'test-name4', 'balance' => +1]);\n        UserAggregateTest::create(['c' => 5, 'name' => 'test-name5', 'balance' => +2]);\n        UserAggregateTest::create(['c' => 6, 'name' => 'test-name5', 'balance' => null]);\n\n        $this->assertEquals(-1, UserAggregateTest::query()->min('balance'));\n        $this->assertNull(UserAggregateTest::query()->where('name', 'no-name')->min('balance'));\n        $this->assertEquals(1, UserAggregateTest::query()->where('c', '>', 3)->min('balance'));\n\n        $this->assertEquals(2, UserAggregateTest::query()->max('balance'));\n        $this->assertNull(UserAggregateTest::query()->where('name', 'no-name')->max('balance'));\n        $this->assertEquals(0, UserAggregateTest::query()->where('c', '<', 4)->max('balance'));\n    }\n\n    public function testAvg()\n    {\n        UserAggregateTest::create(['c' => 1, 'name' => 'test-name1', 'balance' => -10]);\n        UserAggregateTest::create(['c' => 2, 'name' => 'test-name2', 'balance' => -10]);\n        UserAggregateTest::create(['c' => 3, 'name' => 'test-name3', 'balance' => 0]);\n        UserAggregateTest::create(['c' => 4, 'name' => 'test-name4', 'balance' => +10]);\n        UserAggregateTest::create(['c' => 5, 'name' => 'test-name5', 'balance' => +20]);\n        UserAggregateTest::create(['c' => 6, 'name' => 'test-name5', 'balance' => null]);\n\n        $this->assertEquals(2, UserAggregateTest::query()->avg('balance'));\n        $this->assertNull(UserAggregateTest::query()->where('name', 'no-name')->avg('balance'));\n        $this->assertEquals(15, UserAggregateTest::query()->where('c', '>', 3)->avg('balance'));\n\n        $this->assertEquals(2, UserAggregateTest::query()->average('balance'));\n        $this->assertNull(UserAggregateTest::query()->where('name', 'no-name')->average('balance'));\n        $this->assertEquals(-10, UserAggregateTest::query()->where('c', '<', 3)->average('balance'));\n    }\n\n    public function testSum()\n    {\n        UserAggregateTest::create(['c' => 1, 'name' => 'name-1', 'balance' => -11]);\n        UserAggregateTest::create(['c' => 2, 'name' => 'name-2', 'balance' => -10]);\n        UserAggregateTest::create(['c' => 3, 'name' => 'name-3', 'balance' => 0]);\n        UserAggregateTest::create(['c' => 4, 'name' => 'name-4', 'balance' => +12]);\n        UserAggregateTest::create(['c' => 5, 'name' => 'name-5', 'balance' => null]);\n\n        $this->assertEquals(-9, UserAggregateTest::query()->sum('balance'));\n        $result = UserAggregateTest::query()->where('name', 'no-name')->sum('balance');\n        $this->assertNotNull($result);\n        $this->assertEquals(0, $result);\n        $this->assertEquals(2, UserAggregateTest::query()->where('c', '>', 1)->sum('balance'));\n    }\n\n    public function testNumericAggregate()\n    {\n        UserAggregateTest::create(['c' => 1, 'name' => 'name-1', 'balance' => 40]);\n        UserAggregateTest::create(['c' => 2, 'name' => 'name-2', 'balance' => -40]);\n        UserAggregateTest::create(['c' => 3, 'name' => 'name-3', 'balance' => 0]);\n        UserAggregateTest::create(['c' => 4, 'name' => 'name-4', 'balance' => 20]);\n        UserAggregateTest::create(['c' => 5, 'name' => 'name-5', 'balance' => null]);\n\n        $this->assertEquals(20, UserAggregateTest::query()->numericAggregate('sum', ['balance']));\n        // When calculating the average, rows with NULL values are excluded\n        $this->assertEquals(5, UserAggregateTest::query()->numericAggregate('avg', ['balance']));\n        $this->assertEquals(40, UserAggregateTest::query()->numericAggregate('max', ['balance']));\n        $this->assertEquals(-40, UserAggregateTest::query()->numericAggregate('min', ['balance']));\n    }\n}\n\nclass UserAggregateTest extends Model\n{\n    protected $table = 'users';\n    protected $fillable = ['name', 'c', 'balance'];\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentBelongsToManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentBelongsToManyTest;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentBelongsToManyTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('uuid');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('uuid');\n            $table->string('title');\n            $table->timestamps();\n        });\n\n        Schema::create('tags', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('type')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('unique_tags', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name')->unique();\n            $table->string('type')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('users_posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('user_uuid');\n            $table->string('post_uuid');\n            $table->tinyInteger('is_draft')->default(1);\n            $table->timestamps();\n        });\n\n        Schema::create('posts_tags', function (Blueprint $table) {\n            $table->integer('post_id');\n            $table->integer('tag_id')->default(0);\n            $table->string('tag_name')->default('')->nullable();\n            $table->string('flag')->default('')->nullable();\n            $table->string('isActive')->default('')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('posts_unique_tags', function (Blueprint $table) {\n            $table->integer('post_id');\n            $table->integer('tag_id')->default(0);\n            $table->string('tag_name')->default('')->nullable();\n            $table->string('flag')->default('')->nullable();\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicCreateAndRetrieve()\n    {\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->sync([\n            $tag->id => ['flag' => 'taylor'],\n            $tag2->id => ['flag' => ''],\n            $tag3->id => ['flag' => 'exclude'],\n        ]);\n\n        // Tags with flag = exclude should be excluded\n        $this->assertCount(2, $post->tags);\n        $this->assertInstanceOf(Collection::class, $post->tags);\n        $this->assertEquals($tag->name, $post->tags[0]->name);\n        $this->assertEquals($tag2->name, $post->tags[1]->name);\n\n        // Testing on the pivot model\n        $this->assertInstanceOf(Pivot::class, $post->tags[0]->pivot);\n        $this->assertEquals($post->id, $post->tags[0]->pivot->post_id);\n        $this->assertSame('post_id', $post->tags[0]->pivot->getForeignKey());\n        $this->assertSame('tag_id', $post->tags[0]->pivot->getOtherKey());\n        $this->assertSame('posts_tags', $post->tags[0]->pivot->getTable());\n        $this->assertEquals(\n            [\n                'post_id' => '1', 'tag_id' => '1', 'flag' => 'taylor',\n                'created_at' => '2017-10-10T10:10:10.000000Z', 'updated_at' => '2017-10-10T10:10:10.000000Z',\n            ],\n            $post->tags[0]->pivot->toArray()\n        );\n    }\n\n    public function testRefreshOnOtherModelWorks()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $tag = Tag::create(['name' => $tagName = Str::random()]);\n\n        $post->tags()->sync([\n            $tag->id,\n        ]);\n\n        $post->load('tags');\n\n        $loadedTag = $post->tags()->first();\n\n        $tag->update(['name' => 'newName']);\n\n        $this->assertEquals($tagName, $loadedTag->name);\n\n        $this->assertEquals($tagName, $post->tags[0]->name);\n\n        $loadedTag->refresh();\n\n        $this->assertSame('newName', $loadedTag->name);\n\n        $post->refresh();\n\n        $this->assertSame('newName', $post->tags[0]->name);\n    }\n\n    public function testCustomPivotClass()\n    {\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = TagWithCustomPivot::create(['name' => Str::random()]);\n\n        $post->tagsWithCustomPivot()->attach($tag->id);\n\n        $this->assertInstanceOf(PostTagPivot::class, $post->tagsWithCustomPivot[0]->pivot);\n        $this->assertSame('1507630210', $post->tagsWithCustomPivot[0]->pivot->created_at);\n\n        $this->assertInstanceOf(PostTagPivot::class, $post->tagsWithCustomPivotClass[0]->pivot);\n        $this->assertSame('posts_tags', $post->tagsWithCustomPivotClass()->getTable());\n\n        $this->assertEquals([\n            'post_id' => '1',\n            'tag_id' => '1',\n        ], $post->tagsWithCustomAccessor[0]->tag->toArray());\n\n        $pivot = $post->tagsWithCustomPivot[0]->pivot;\n        $pivot->tag_id = 2;\n        $pivot->save();\n\n        $this->assertEquals(1, PostTagPivot::count());\n        $this->assertEquals(1, PostTagPivot::first()->post_id);\n        $this->assertEquals(2, PostTagPivot::first()->tag_id);\n    }\n\n    public function testCustomPivotClassUsingSync()\n    {\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = TagWithCustomPivot::create(['name' => Str::random()]);\n\n        $results = $post->tagsWithCustomPivot()->sync([\n            $tag->id => ['flag' => 1],\n        ]);\n\n        $this->assertNotEmpty($results['attached']);\n\n        $results = $post->tagsWithCustomPivot()->sync([\n            $tag->id => ['flag' => 1],\n        ]);\n\n        $this->assertEmpty($results['updated']);\n\n        $results = $post->tagsWithCustomPivot()->sync([]);\n\n        $this->assertNotEmpty($results['detached']);\n    }\n\n    public function testCustomPivotClassUsingUpdateExistingPivot()\n    {\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post = Post::create(['title' => Str::random()]);\n        $tag = TagWithCustomPivot::create(['name' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'empty'],\n        ]);\n\n        // Test on actually existing pivot\n        $this->assertEquals(\n            1,\n            $post->tagsWithCustomExtraPivot()->updateExistingPivot($tag->id, ['flag' => 'exclude'])\n        );\n        foreach ($post->tagsWithCustomExtraPivot as $tag) {\n            $this->assertSame('exclude', $tag->pivot->flag);\n        }\n\n        // Test on non-existent pivot\n        $this->assertEquals(\n            0,\n            $post->tagsWithCustomExtraPivot()->updateExistingPivot(0, ['flag' => 'exclude'])\n        );\n    }\n\n    public function testCustomPivotClassUpdatesTimestamps()\n    {\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post = Post::create(['title' => Str::random()]);\n        $tag = TagWithCustomPivot::create(['name' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            [\n                'post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'empty',\n                'created_at' => '2017-10-10 10:10:10',\n                'updated_at' => '2017-10-10 10:10:10',\n            ],\n        ]);\n\n        Carbon::setTestNow('2017-10-10 10:10:20'); // +10 seconds\n\n        $this->assertEquals(\n            1,\n            $post->tagsWithCustomExtraPivot()->updateExistingPivot($tag->id, ['flag' => 'exclude'])\n        );\n        foreach ($post->tagsWithCustomExtraPivot as $tag) {\n            $this->assertSame('exclude', $tag->pivot->flag);\n\n            if ($this->driver === 'sqlsrv') {\n                $this->assertSame('2017-10-10 10:10:10.000', $tag->pivot->getAttributes()['created_at']);\n                $this->assertSame('2017-10-10 10:10:20.000', $tag->pivot->getAttributes()['updated_at']); // +10 seconds\n            } else {\n                $this->assertSame('2017-10-10 10:10:10', $tag->pivot->getAttributes()['created_at']);\n                $this->assertSame('2017-10-10 10:10:20', $tag->pivot->getAttributes()['updated_at']); // +10 seconds\n            }\n        }\n    }\n\n    public function testAttachMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $tag4 = Tag::create(['name' => Str::random()]);\n        $tag5 = Tag::create(['name' => Str::random()]);\n        $tag6 = Tag::create(['name' => Str::random()]);\n        $tag7 = Tag::create(['name' => Str::random()]);\n        $tag8 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach($tag->id);\n        $this->assertEquals($tag->name, $post->tags[0]->name);\n        $this->assertNotNull($post->tags[0]->pivot->created_at);\n\n        $post->tags()->attach($tag2->id, ['flag' => 'taylor']);\n        $post->load('tags');\n        $this->assertEquals($tag2->name, $post->tags[1]->name);\n        $this->assertSame('taylor', $post->tags[1]->pivot->flag);\n\n        $post->tags()->attach([$tag3->id, $tag4->id]);\n        $post->load('tags');\n        $this->assertEquals($tag3->name, $post->tags[2]->name);\n        $this->assertEquals($tag4->name, $post->tags[3]->name);\n\n        $post->tags()->attach([$tag5->id => ['flag' => 'mohamed'], $tag6->id => ['flag' => 'adam']]);\n        $post->load('tags');\n        $this->assertEquals($tag5->name, $post->tags[4]->name);\n        $this->assertSame('mohamed', $post->tags[4]->pivot->flag);\n        $this->assertEquals($tag6->name, $post->tags[5]->name);\n        $this->assertSame('adam', $post->tags[5]->pivot->flag);\n\n        $post->tags()->attach(new Collection([$tag7, $tag8]));\n        $post->load('tags');\n        $this->assertEquals($tag7->name, $post->tags[6]->name);\n        $this->assertEquals($tag8->name, $post->tags[7]->name);\n    }\n\n    public function testDetachMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $tag4 = Tag::create(['name' => Str::random()]);\n        $tag5 = Tag::create(['name' => Str::random()]);\n        Tag::create(['name' => Str::random()]);\n        Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals(Tag::pluck('name'), $post->tags->pluck('name'));\n\n        $post->tags()->detach($tag->id);\n        $post->load('tags');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id])->pluck('name'),\n            $post->tags->pluck('name')\n        );\n\n        $post->tags()->detach([$tag2->id, $tag3->id]);\n        $post->load('tags');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id, $tag2->id, $tag3->id])->pluck('name'),\n            $post->tags->pluck('name')\n        );\n\n        $post->tags()->detach(new Collection([$tag4, $tag5]));\n        $post->load('tags');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id, $tag2->id, $tag3->id, $tag4->id, $tag5->id])->pluck('name'),\n            $post->tags->pluck('name')\n        );\n\n        $this->assertCount(2, $post->tags);\n        $post->tags()->detach();\n        $post->load('tags');\n        $this->assertCount(0, $post->tags);\n    }\n\n    public function testDetachMethodWithCustomPivot()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $tag4 = Tag::create(['name' => Str::random()]);\n        $tag5 = Tag::create(['name' => Str::random()]);\n        Tag::create(['name' => Str::random()]);\n        Tag::create(['name' => Str::random()]);\n\n        $post->tagsWithCustomPivot()->attach(Tag::all());\n\n        $this->assertEquals(Tag::pluck('name'), $post->tags->pluck('name'));\n\n        $post->tagsWithCustomPivot()->detach($tag->id);\n        $post->load('tagsWithCustomPivot');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id])->pluck('name'),\n            $post->tagsWithCustomPivot->pluck('name')\n        );\n\n        $post->tagsWithCustomPivot()->detach([$tag2->id, $tag3->id]);\n        $post->load('tagsWithCustomPivot');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id, $tag2->id, $tag3->id])->pluck('name'),\n            $post->tagsWithCustomPivot->pluck('name')\n        );\n\n        $post->tagsWithCustomPivot()->detach(new Collection([$tag4, $tag5]));\n        $post->load('tagsWithCustomPivot');\n        $this->assertEquals(\n            Tag::whereNotIn('id', [$tag->id, $tag2->id, $tag3->id, $tag4->id, $tag5->id])->pluck('name'),\n            $post->tagsWithCustomPivot->pluck('name')\n        );\n\n        $this->assertCount(2, $post->tagsWithCustomPivot);\n        $post->tagsWithCustomPivot()->detach();\n        $post->load('tagsWithCustomPivot');\n        $this->assertCount(0, $post->tagsWithCustomPivot);\n    }\n\n    public function testFirstMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals($tag->name, $post->tags()->first()->name);\n    }\n\n    public function testFirstOrFailMethod()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $post->tags()->firstOrFail(['id']);\n    }\n\n    public function testFindMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals($tag2->name, $post->tags()->find($tag2->id)->name);\n        $this->assertCount(0, $post->tags()->findMany([]));\n        $this->assertCount(2, $post->tags()->findMany([$tag->id, $tag2->id]));\n        $this->assertCount(0, $post->tags()->findMany(new Collection));\n        $this->assertCount(2, $post->tags()->findMany(new Collection([$tag->id, $tag2->id])));\n    }\n\n    public function testFindMethodStringyKey()\n    {\n        Schema::create('post_string_key', function (Blueprint $table) {\n            $table->string('id', 1)->primary();\n            $table->string('title', 10);\n        });\n\n        Schema::create('tag_string_key', function (Blueprint $table) {\n            $table->string('id', 1)->primary();\n            $table->string('title', 10);\n        });\n\n        Schema::create('post_tag_string_key', function (Blueprint $table) {\n            $table->id();\n            $table->string('post_id', 1);\n            $table->string('tag_id', 1);\n        });\n\n        $post = PostStringPrimaryKey::query()->create([\n            'id' => 'a',\n            'title' => Str::random(10),\n        ]);\n\n        $tag = TagStringPrimaryKey::query()->create([\n            'id' => 'b',\n            'title' => Str::random(10),\n        ]);\n\n        $tag2 = TagStringPrimaryKey::query()->create([\n            'id' => 'c',\n            'title' => Str::random(10),\n        ]);\n\n        $post->tags()->attach(TagStringPrimaryKey::all());\n\n        $this->assertEquals($tag2->name, $post->tags()->find($tag2->id)->name);\n        $this->assertCount(0, $post->tags()->findMany([]));\n        $this->assertCount(2, $post->tags()->findMany([$tag->id, $tag2->id]));\n        $this->assertCount(0, $post->tags()->findMany(new Collection));\n        $this->assertCount(2, $post->tags()->findMany(new Collection([$tag->id, $tag2->id])));\n    }\n\n    public function testFindSoleMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach($tag);\n\n        $this->assertEquals($tag->id, $post->tags()->findSole($tag->id)->id);\n\n        $this->assertEquals($tag->id, $post->tags()->findSole($tag)->id);\n\n        // Test with no records\n        $post->tags()->detach($tag);\n\n        try {\n            $post->tags()->findSole($tag);\n            $this->fail('Expected RecordsNotFoundException was not thrown.');\n        } catch (RecordsNotFoundException $e) {\n            $this->assertTrue(true);\n        }\n    }\n\n    public function testFindOrFailMethod()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Integration\\Database\\EloquentBelongsToManyTest\\Tag] 10');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $post->tags()->findOrFail(10);\n    }\n\n    public function testFindOrFailMethodWithMany()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Integration\\Database\\EloquentBelongsToManyTest\\Tag] 10, 11');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $post->tags()->findOrFail([10, 11]);\n    }\n\n    public function testFindOrFailMethodWithManyUsingCollection()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Integration\\Database\\EloquentBelongsToManyTest\\Tag] 10, 11');\n\n        $post = Post::create(['title' => Str::random()]);\n\n        Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $post->tags()->findOrFail(new Collection([10, 11]));\n    }\n\n    public function testFindOrNewMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals($tag->id, $post->tags()->findOrNew($tag->id)->id);\n\n        $this->assertNull($post->tags()->findOrNew(666)->id);\n        $this->assertInstanceOf(Tag::class, $post->tags()->findOrNew(666));\n    }\n\n    public function testFindOrMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $post->tags()->create(['name' => Str::random()]);\n\n        $result = $post->tags()->findOr(1, fn () => 'callback result');\n        $this->assertInstanceOf(Tag::class, $result);\n        $this->assertSame(1, $result->id);\n        $this->assertNotNull($result->name);\n\n        $result = $post->tags()->findOr(1, ['id'], fn () => 'callback result');\n        $this->assertInstanceOf(Tag::class, $result);\n        $this->assertSame(1, $result->id);\n        $this->assertNull($result->name);\n\n        $result = $post->tags()->findOr(2, fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFindOrMethodWithMany()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $post->tags()->createMany([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        $result = $post->tags()->findOr([1, 2], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNotNull($result[0]->name);\n        $this->assertNotNull($result[1]->name);\n\n        $result = $post->tags()->findOr([1, 2], ['id'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNull($result[0]->name);\n        $this->assertNull($result[1]->name);\n\n        $result = $post->tags()->findOr([1, 2, 3], fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFindOrMethodWithManyUsingCollection()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $post->tags()->createMany([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        $result = $post->tags()->findOr(new Collection([1, 2]), fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNotNull($result[0]->name);\n        $this->assertNotNull($result[1]->name);\n\n        $result = $post->tags()->findOr(new Collection([1, 2]), ['id'], fn () => 'callback result');\n        $this->assertInstanceOf(Collection::class, $result);\n        $this->assertSame(1, $result[0]->id);\n        $this->assertSame(2, $result[1]->id);\n        $this->assertNull($result[0]->name);\n        $this->assertNull($result[1]->name);\n\n        $result = $post->tags()->findOr(new Collection([1, 2, 3]), fn () => 'callback result');\n        $this->assertSame('callback result', $result);\n    }\n\n    public function testFirstOrNewMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals($tag->id, $post->tags()->firstOrNew(['id' => $tag->id])->id);\n\n        $this->assertNull($post->tags()->firstOrNew(['id' => 666])->id);\n        $this->assertInstanceOf(Tag::class, $post->tags()->firstOrNew(['id' => 666]));\n    }\n\n    // public function testFirstOrNewUnrelatedExisting()\n    // {\n    //     $post = Post::create(['title' => Str::random()]);\n\n    //     $name = Str::random();\n    //     $tag = Tag::create(['name' => $name]);\n\n    //     $postTag = $post->tags()->firstOrNew(['name' => $name]);\n    //     $this->assertTrue($postTag->exists);\n    //     $this->assertTrue($postTag->is($tag));\n    //     $this->assertTrue($tag->is($post->tags()->first()));\n    // }\n\n    public function testFirstOrCreateMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $this->assertEquals($tag->id, $post->tags()->firstOrCreate(['name' => $tag->name])->id);\n\n        $new = $post->tags()->firstOrCreate(['name' => 'wavez']);\n        $this->assertSame('wavez', $new->name);\n        $this->assertNotNull($new->id);\n    }\n\n    public function testFirstOrCreateUnrelatedExisting()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $name = Str::random();\n        $tag = Tag::create(['name' => $name]);\n\n        $postTag = $post->tags()->firstOrCreate(['name' => $name]);\n        $this->assertTrue($postTag->exists);\n        $this->assertTrue($postTag->is($tag));\n        $this->assertTrue($tag->is($post->tags()->first()));\n    }\n\n    public function testCreateOrFirst()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = UniqueTag::create(['name' => Str::random()]);\n\n        $post->tagsUnique()->attach(UniqueTag::all());\n\n        $this->assertEquals($tag->id, $post->tagsUnique()->createOrFirst(['name' => $tag->name])->id);\n\n        $new = $post->tagsUnique()->createOrFirst(['name' => 'wavez']);\n        $this->assertSame('wavez', $new->name);\n        $this->assertNotNull($new->id);\n    }\n\n    public function testCreateOrFirstUnrelatedExisting()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $name = Str::random();\n        $tag = UniqueTag::create(['name' => $name]);\n\n        $postTag = $post->tagsUnique()->createOrFirst(['name' => $name]);\n        $this->assertTrue($postTag->exists);\n        $this->assertTrue($postTag->is($tag));\n        $this->assertTrue($tag->is($post->tagsUnique()->first()));\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = UniqueTag::create(['name' => Str::random()]);\n\n        $post->tagsUnique()->attach(UniqueTag::all());\n\n        DB::transaction(function () use ($tag, $post) {\n            $this->assertEquals($tag->id, $post->tagsUnique()->createOrFirst(['name' => $tag->name])->id);\n        });\n    }\n\n    public function testFirstOrNewMethodWithValues()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $tag = Tag::create(['name' => Str::random()]);\n        $post->tags()->attach(Tag::all());\n\n        $existing = $post->tags()->firstOrNew(\n            ['name' => $tag->name],\n            ['type' => 'featured']\n        );\n\n        $this->assertEquals($tag->id, $existing->id);\n        $this->assertNotEquals('foo', $existing->name);\n\n        $new = $post->tags()->firstOrNew(\n            ['name' => 'foo'],\n            ['type' => 'featured']\n        );\n\n        $this->assertSame('foo', $new->name);\n        $this->assertSame('featured', $new->type);\n\n        $new = $post->tags()->firstOrNew(\n            ['name' => 'foo'],\n            ['name' => 'bar']\n        );\n\n        $this->assertSame('bar', $new->name);\n    }\n\n    public function testFirstOrCreateMethodWithValues()\n    {\n        $post = Post::create(['title' => Str::random()]);\n        $tag = Tag::create(['name' => Str::random()]);\n        $post->tags()->attach(Tag::all());\n\n        $existing = $post->tags()->firstOrCreate(\n            ['name' => $tag->name],\n            ['type' => 'featured']\n        );\n\n        $this->assertEquals($tag->id, $existing->id);\n        $this->assertNotEquals('foo', $existing->name);\n\n        $new = $post->tags()->firstOrCreate(\n            ['name' => 'foo'],\n            ['type' => 'featured']\n        );\n\n        $this->assertSame('foo', $new->name);\n        $this->assertSame('featured', $new->type);\n        $this->assertNotNull($new->id);\n\n        $new = $post->tags()->firstOrCreate(\n            ['name' => 'qux'],\n            ['name' => 'bar']\n        );\n\n        $this->assertSame('bar', $new->name);\n        $this->assertNotNull($new->id);\n    }\n\n    public function testUpdateOrCreateMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->attach(Tag::all());\n\n        $post->tags()->updateOrCreate(['id' => $tag->id], ['name' => 'wavez']);\n        $this->assertSame('wavez', $tag->fresh()->name);\n\n        $post->tags()->updateOrCreate(['id' => 666], ['name' => 'dives']);\n        $this->assertNotNull($post->tags()->whereName('dives')->first());\n    }\n\n    public function testUpdateOrCreateUnrelatedExisting()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => 'foo']);\n\n        $postTag = $post->tags()->updateOrCreate(['name' => 'foo'], ['name' => 'wavez']);\n        $this->assertTrue($postTag->exists);\n        $this->assertTrue($postTag->is($tag));\n        $this->assertSame('wavez', $tag->fresh()->name);\n        $this->assertSame('wavez', $postTag->name);\n        $this->assertTrue($tag->is($post->tags()->first()));\n    }\n\n    public function testUpdateOrCreateMethodCreate()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $post->tags()->updateOrCreate(['name' => 'wavez'], ['type' => 'featured']);\n\n        $tag = $post->tags()->whereType('featured')->first();\n\n        $this->assertNotNull($tag);\n        $this->assertSame('wavez', $tag->name);\n    }\n\n    public function testSyncMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $tag4 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->sync([$tag->id, $tag2->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id, $tag2->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        $output = $post->tags()->sync([$tag->id, $tag3->id, $tag4->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id, $tag3->id, $tag4->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        $this->assertEquals([\n            'attached' => [$tag3->id, $tag4->id],\n            'detached' => [1 => $tag2->id],\n            'updated' => [],\n        ], $output);\n\n        $post->tags()->sync([]);\n        $this->assertEmpty($post->load('tags')->tags);\n\n        $post->tags()->sync([\n            $tag->id => ['flag' => 'taylor'],\n            $tag2->id => ['flag' => 'mohamed'],\n        ]);\n        $post->load('tags');\n        $this->assertEquals($tag->name, $post->tags[0]->name);\n        $this->assertSame('taylor', $post->tags[0]->pivot->flag);\n        $this->assertEquals($tag2->name, $post->tags[1]->name);\n        $this->assertSame('mohamed', $post->tags[1]->pivot->flag);\n    }\n\n    public function testSyncMethodWithModels()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $tag4 = Tag::create(['name' => Str::random()]);\n\n        // Test syncing with an array of models\n        $post->tags()->sync([$tag, $tag2]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id, $tag2->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        // Test syncing with a BaseCollection of models\n        $tagCollection = collect([$tag3, $tag4]);\n\n        $post->tags()->sync($tagCollection);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag3->id, $tag4->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        // Test syncing with EloquentCollection of models\n        $tagCollection = Tag::limit(2)->get();\n\n        $post->tags()->sync($tagCollection);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id, $tag2->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n    }\n\n    public function testSyncWithoutDetachingMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->sync([$tag->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        $post->tags()->syncWithoutDetaching([$tag2->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id, $tag2->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n    }\n\n    public function testSyncMethodWithEmptyValueDoesNotQueryWhenDetachingDisabled()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::enableQueryLog();\n\n        foreach ([collect(), [], null] as $value) {\n            $result = $post->tags()->sync($value, false);\n\n            $this->assertEquals([\n                'attached' => [],\n                'detached' => [],\n                'updated' => [],\n            ], $result);\n        }\n\n        $this->assertEmpty(DB::getQueryLog());\n\n        DB::disableQueryLog();\n    }\n\n    public function testToggleMethod()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n\n        $post->tags()->toggle([$tag->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        $post->tags()->toggle([$tag2->id, $tag->id]);\n\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag2->id])->pluck('name'),\n            $post->load('tags')->tags->pluck('name')\n        );\n\n        $post->tags()->toggle([$tag2->id, $tag->id => ['flag' => 'taylor']]);\n        $post->load('tags');\n        $this->assertEquals(\n            Tag::whereIn('id', [$tag->id])->pluck('name'),\n            $post->tags->pluck('name')\n        );\n        $this->assertSame('taylor', $post->tags[0]->pivot->flag);\n    }\n\n    public function testTouchingParent()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = TouchingTag::create(['name' => Str::random()]);\n\n        $post->touchingTags()->attach([$tag->id]);\n\n        $this->assertNotSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $tag->update(['name' => $tag->name]);\n        $this->assertNotSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n\n        $tag->update(['name' => Str::random()]);\n        $this->assertSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n    }\n\n    public function testTouchingRelatedModelsOnSync()\n    {\n        $tag = TouchingTag::create(['name' => Str::random()]);\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $this->assertNotSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n        $this->assertNotSame('2017-10-10 10:10:10', $tag->fresh()->updated_at->toDateTimeString());\n\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $tag->posts()->sync([$post->id]);\n\n        $this->assertSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n        $this->assertSame('2017-10-10 10:10:10', $tag->fresh()->updated_at->toDateTimeString());\n    }\n\n    public function testNoTouchingHappensIfNotConfigured()\n    {\n        $tag = Tag::create(['name' => Str::random()]);\n\n        $post = Post::create(['title' => Str::random()]);\n\n        $this->assertNotSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n        $this->assertNotSame('2017-10-10 10:10:10', $tag->fresh()->updated_at->toDateTimeString());\n\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $tag->posts()->sync([$post->id]);\n\n        $this->assertNotSame('2017-10-10 10:10:10', $post->fresh()->updated_at->toDateTimeString());\n        $this->assertNotSame('2017-10-10 10:10:10', $tag->fresh()->updated_at->toDateTimeString());\n    }\n\n    public function testCanRetrieveRelatedIds()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('tags')->insert([\n            ['name' => 'excluded'],\n            ['name' => Str::random()],\n        ]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => 1, 'flag' => ''],\n            ['post_id' => $post->id, 'tag_id' => 2, 'flag' => 'exclude'],\n            ['post_id' => $post->id, 'tag_id' => 3, 'flag' => ''],\n        ]);\n\n        $this->assertEquals([1, 3], $post->tags()->allRelatedIds()->toArray());\n    }\n\n    public function testCanTouchRelatedModels()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('tags')->insert([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => 1, 'flag' => ''],\n            ['post_id' => $post->id, 'tag_id' => 2, 'flag' => 'exclude'],\n            ['post_id' => $post->id, 'tag_id' => 3, 'flag' => ''],\n        ]);\n\n        Carbon::setTestNow('2017-10-10 10:10:10');\n\n        $post->tags()->touch();\n\n        foreach ($post->tags()->pluck('tags.updated_at') as $date) {\n            $this->assertSame('2017-10-10 10:10:10', $date->toDateTimeString());\n        }\n\n        $this->assertNotSame('2017-10-10 10:10:10', Tag::find(2)->updated_at?->toDateTimeString());\n    }\n\n    public function testWherePivotOnString()\n    {\n        $tag = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'foo'],\n        ]);\n\n        $relationTag = $post->tags()->wherePivot('flag', 'foo')->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n\n        $relationTag = $post->tags()->wherePivot('flag', '=', 'foo')->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testFirstWhere()\n    {\n        $tag = Tag::create(['name' => 'foo'])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'foo'],\n        ]);\n\n        $relationTag = $post->tags()->firstWhere('name', 'foo');\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n\n        $relationTag = $post->tags()->firstWhere('name', '=', 'foo');\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testWherePivotOnBoolean()\n    {\n        $tag = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => true],\n        ]);\n\n        $relationTag = $post->tags()->wherePivot('flag', true)->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n\n        $relationTag = $post->tags()->wherePivot('flag', '=', true)->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testOrWherePivotOnBoolean()\n    {\n        $tag = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => true, 'isActive' => false],\n        ]);\n\n        $relationTag = $post->tags()->wherePivot('isActive', false)->orWherePivot('flag', true)->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testWherePivotNotBetween()\n    {\n        $tag = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => true, 'isActive' => false],\n        ]);\n\n        $relationTag = $post->tags()\n            ->wherePivotNotBetween('isActive', ['true', 'false'])\n            ->orWherePivotNotBetween('flag', ['true', 'false'])\n            ->first();\n\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testWherePivotInMethod()\n    {\n        $tag = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'foo'],\n        ]);\n\n        $relationTag = $post->tags()->wherePivotIn('flag', ['foo'])->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag->getAttributes());\n    }\n\n    public function testOrWherePivotInMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => 'bar'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag3->id, 'flag' => 'baz'],\n        ]);\n\n        $relationTags = $post->tags()->wherePivotIn('flag', ['foo'])->orWherePivotIn('flag', ['baz'])->get();\n        $this->assertEquals($relationTags->pluck('id')->toArray(), [$tag1->id, $tag3->id]);\n    }\n\n    public function testWherePivotNotInMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => 'bar'],\n        ]);\n\n        $relationTag = $post->tags()->wherePivotNotIn('flag', ['foo'])->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag2->getAttributes());\n    }\n\n    public function testOrWherePivotNotInMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $tag3 = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => 'bar'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag3->id, 'flag' => 'baz'],\n        ]);\n\n        $relationTags = $post->tags()->wherePivotIn('flag', ['foo'])->orWherePivotNotIn('flag', ['baz'])->get();\n        $this->assertEquals($relationTags->pluck('id')->toArray(), [$tag1->id, $tag2->id]);\n    }\n\n    public function testWherePivotNullMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()])->fresh();\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => null],\n        ]);\n\n        $relationTag = $post->tagsWithExtraPivot()->wherePivotNull('flag')->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag2->getAttributes());\n    }\n\n    public function testWherePivotNotNullMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()])->fresh();\n        $tag2 = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo', 'isActive' => true],\n        ]);\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => null, 'isActive' => false],\n        ]);\n\n        $relationTag = $post->tagsWithExtraPivot()->wherePivotNotNull('flag')->orWherePivotNotNull('isActive')->first();\n        $this->assertEquals($relationTag->getAttributes(), $tag1->getAttributes());\n    }\n\n    public function testCanUpdateExistingPivot()\n    {\n        $tag = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'empty'],\n        ]);\n\n        $post->tagsWithExtraPivot()->updateExistingPivot($tag->id, ['flag' => 'exclude']);\n\n        foreach ($post->tagsWithExtraPivot as $tag) {\n            $this->assertSame('exclude', $tag->pivot->flag);\n        }\n    }\n\n    public function testCanUpdateExistingPivotUsingArrayableOfIds()\n    {\n        $tags = new Collection([\n            $tag1 = Tag::create(['name' => Str::random()]),\n            $tag2 = Tag::create(['name' => Str::random()]),\n        ]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'empty'],\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => 'empty'],\n        ]);\n\n        $post->tagsWithExtraPivot()->updateExistingPivot($tags, ['flag' => 'exclude']);\n\n        foreach ($post->tagsWithExtraPivot as $tag) {\n            $this->assertSame('exclude', $tag->pivot->flag);\n        }\n    }\n\n    public function testCanUpdateExistingPivotUsingModel()\n    {\n        $tag = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'empty'],\n        ]);\n\n        $post->tagsWithExtraPivot()->updateExistingPivot($tag, ['flag' => 'exclude']);\n\n        foreach ($post->tagsWithExtraPivot as $tag) {\n            $this->assertSame('exclude', $tag->pivot->flag);\n        }\n    }\n\n    public function testCustomRelatedKey()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $tag = $post->tagsWithCustomRelatedKey()->create(['name' => Str::random()]);\n        $this->assertEquals($tag->name, $post->tagsWithCustomRelatedKey()->first()->pivot->tag_name);\n\n        $post->tagsWithCustomRelatedKey()->detach($tag);\n\n        $post->tagsWithCustomRelatedKey()->attach($tag);\n        $this->assertEquals($tag->name, $post->tagsWithCustomRelatedKey()->first()->pivot->tag_name);\n\n        $post->tagsWithCustomRelatedKey()->detach(new Collection([$tag]));\n\n        $post->tagsWithCustomRelatedKey()->attach(new Collection([$tag]));\n        $this->assertEquals($tag->name, $post->tagsWithCustomRelatedKey()->first()->pivot->tag_name);\n\n        $post->tagsWithCustomRelatedKey()->updateExistingPivot($tag, ['flag' => 'exclude']);\n        $this->assertSame('exclude', $post->tagsWithCustomRelatedKey()->first()->pivot->flag);\n    }\n\n    public function testGlobalScopeColumns()\n    {\n        $tag = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag->id, 'flag' => 'empty'],\n        ]);\n\n        $tags = $post->tagsWithGlobalScope;\n\n        $this->assertEquals(['id' => 1], $tags[0]->getAttributes());\n    }\n\n    public function testPivotDoesntHavePrimaryKey()\n    {\n        $user = User::create(['name' => Str::random()]);\n        $post1 = Post::create(['title' => Str::random()]);\n        $post2 = Post::create(['title' => Str::random()]);\n\n        $user->postsWithCustomPivot()->sync([$post1->uuid]);\n        $this->assertEquals($user->uuid, $user->postsWithCustomPivot()->first()->pivot->user_uuid);\n        $this->assertEquals($post1->uuid, $user->postsWithCustomPivot()->first()->pivot->post_uuid);\n        $this->assertEquals(1, $user->postsWithCustomPivot()->first()->pivot->is_draft);\n\n        $user->postsWithCustomPivot()->sync([$post2->uuid]);\n        $this->assertEquals($user->uuid, $user->postsWithCustomPivot()->first()->pivot->user_uuid);\n        $this->assertEquals($post2->uuid, $user->postsWithCustomPivot()->first()->pivot->post_uuid);\n        $this->assertEquals(1, $user->postsWithCustomPivot()->first()->pivot->is_draft);\n\n        $user->postsWithCustomPivot()->updateExistingPivot($post2->uuid, ['is_draft' => 0]);\n        $this->assertEquals(0, $user->postsWithCustomPivot()->first()->pivot->is_draft);\n    }\n\n    public function testOrderByPivotMethod()\n    {\n        $tag1 = Tag::create(['name' => Str::random()]);\n        $tag2 = Tag::create(['name' => Str::random()])->fresh();\n        $tag3 = Tag::create(['name' => Str::random()])->fresh();\n        $tag4 = Tag::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        DB::table('posts_tags')->insert([\n            ['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo3'],\n            ['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => 'foo1'],\n            ['post_id' => $post->id, 'tag_id' => $tag3->id, 'flag' => 'foo4'],\n            ['post_id' => $post->id, 'tag_id' => $tag4->id, 'flag' => 'foo2'],\n        ]);\n\n        $relationTag1 = $post->tagsWithCustomExtraPivot()->orderByPivot('flag', 'asc')->first();\n        $this->assertEquals($relationTag1->getAttributes(), $tag2->getAttributes());\n\n        $relationTag2 = $post->tagsWithCustomExtraPivot()->orderByPivot('flag', 'desc')->first();\n        $this->assertEquals($relationTag2->getAttributes(), $tag3->getAttributes());\n    }\n\n    public function testFirstOrMethod()\n    {\n        $user1 = User::create(['name' => Str::random()]);\n        $user2 = User::create(['name' => Str::random()]);\n        $user3 = User::create(['name' => Str::random()]);\n        $post1 = Post::create(['title' => Str::random()]);\n        $post2 = Post::create(['title' => Str::random()]);\n        $post3 = Post::create(['title' => Str::random()]);\n\n        $user1->posts()->sync([$post1->uuid, $post2->uuid]);\n        $user2->posts()->sync([$post1->uuid, $post2->uuid]);\n\n        $this->assertEquals(\n            $post1->id,\n            $user2->posts()->firstOr(function () {\n                return Post::create(['title' => Str::random()]);\n            })->id\n        );\n\n        $this->assertEquals(\n            $post3->id,\n            $user3->posts()->firstOr(function () use ($post3) {\n                return $post3;\n            })->id\n        );\n    }\n\n    public function testUpdateOrCreateQueryBuilderIsolation()\n    {\n        $user = User::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        $user->postsWithCustomPivot()->attach($post);\n\n        $instance = $user->postsWithCustomPivot()->updateOrCreate(\n            ['uuid' => $post->uuid],\n            ['title' => Str::random()],\n        );\n\n        $this->assertArrayNotHasKey(\n            'user_uuid',\n            $instance->toArray(),\n        );\n    }\n\n    public function testFirstOrCreateQueryBuilderIsolation()\n    {\n        $user = User::create(['name' => Str::random()]);\n        $post = Post::create(['title' => Str::random()]);\n\n        $user->postsWithCustomPivot()->attach($post);\n\n        $instance = $user->postsWithCustomPivot()->firstOrCreate(\n            ['uuid' => $post->uuid],\n            ['title' => Str::random()],\n        );\n\n        $this->assertArrayNotHasKey(\n            'user_uuid',\n            $instance->toArray(),\n        );\n    }\n}\n\nclass User extends Model\n{\n    public $table = 'users';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::creating(function ($model) {\n            $model->setAttribute('uuid', Str::random());\n        });\n    }\n\n    public function posts()\n    {\n        return $this->belongsToMany(Post::class, 'users_posts', 'user_uuid', 'post_uuid', 'uuid', 'uuid')\n            ->withPivot('is_draft')\n            ->withTimestamps();\n    }\n\n    public function postsWithCustomPivot()\n    {\n        return $this->belongsToMany(Post::class, 'users_posts', 'user_uuid', 'post_uuid', 'uuid', 'uuid')\n            ->using(UserPostPivot::class)\n            ->withPivot('is_draft')\n            ->withTimestamps();\n    }\n}\n\nclass PostStringPrimaryKey extends Model\n{\n    public $incrementing = false;\n\n    public $timestamps = false;\n\n    protected $table = 'post_string_key';\n\n    protected $keyType = 'string';\n\n    protected $fillable = ['title', 'id'];\n\n    public function tags()\n    {\n        return $this->belongsToMany(TagStringPrimaryKey::class, 'post_tag_string_key', 'post_id', 'tag_id');\n    }\n}\n\nclass TagStringPrimaryKey extends Model\n{\n    public $incrementing = false;\n\n    public $timestamps = false;\n\n    protected $table = 'tag_string_key';\n\n    protected $keyType = 'string';\n\n    protected $fillable = ['title', 'id'];\n\n    public function posts()\n    {\n        return $this->belongsToMany(PostStringPrimaryKey::class, 'post_tag_string_key', 'tag_id', 'post_id');\n    }\n}\n\nclass Post extends Model\n{\n    public $table = 'posts';\n    public $timestamps = true;\n    protected $guarded = [];\n    protected $touches = ['touchingTags'];\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::creating(function ($model) {\n            $model->setAttribute('uuid', Str::random());\n        });\n    }\n\n    public function users()\n    {\n        return $this->belongsToMany(User::class, 'users_posts', 'post_uuid', 'user_uuid', 'uuid', 'uuid')\n            ->withPivot('is_draft')\n            ->withTimestamps();\n    }\n\n    public function tags()\n    {\n        return $this->belongsToMany(Tag::class, 'posts_tags', 'post_id', 'tag_id')\n            ->withPivot('flag')\n            ->withTimestamps()\n            ->wherePivot('flag', '<>', 'exclude');\n    }\n\n    public function tagsUnique()\n    {\n        return $this->belongsToMany(UniqueTag::class, 'posts_unique_tags', 'post_id', 'tag_id')\n            ->withPivot('flag')\n            ->withTimestamps()\n            ->wherePivot('flag', '<>', 'exclude');\n    }\n\n    public function tagsWithExtraPivot()\n    {\n        return $this->belongsToMany(Tag::class, 'posts_tags', 'post_id', 'tag_id')\n            ->withPivot('flag');\n    }\n\n    public function touchingTags()\n    {\n        return $this->belongsToMany(TouchingTag::class, 'posts_tags', 'post_id', 'tag_id')\n            ->withTimestamps();\n    }\n\n    public function tagsWithCustomPivot()\n    {\n        return $this->belongsToMany(TagWithCustomPivot::class, 'posts_tags', 'post_id', 'tag_id')\n            ->using(PostTagPivot::class)\n            ->withTimestamps();\n    }\n\n    public function tagsWithCustomExtraPivot()\n    {\n        return $this->belongsToMany(TagWithCustomPivot::class, 'posts_tags', 'post_id', 'tag_id')\n            ->using(PostTagPivot::class)\n            ->withTimestamps()\n            ->withPivot('flag');\n    }\n\n    public function tagsWithCustomPivotClass()\n    {\n        return $this->belongsToMany(TagWithCustomPivot::class, PostTagPivot::class, 'post_id', 'tag_id');\n    }\n\n    public function tagsWithCustomAccessor()\n    {\n        return $this->belongsToMany(TagWithCustomPivot::class, 'posts_tags', 'post_id', 'tag_id')\n            ->using(PostTagPivot::class)\n            ->as('tag');\n    }\n\n    public function tagsWithCustomRelatedKey()\n    {\n        return $this->belongsToMany(Tag::class, 'posts_tags', 'post_id', 'tag_name', 'id', 'name')\n            ->withPivot('flag');\n    }\n\n    public function tagsWithGlobalScope()\n    {\n        return $this->belongsToMany(TagWithGlobalScope::class, 'posts_tags', 'post_id', 'tag_id');\n    }\n}\n\nclass Tag extends Model\n{\n    public $table = 'tags';\n    public $timestamps = true;\n    protected $fillable = ['name', 'type'];\n\n    public function posts()\n    {\n        return $this->belongsToMany(Post::class, 'posts_tags', 'tag_id', 'post_id');\n    }\n}\n\nclass UniqueTag extends Model\n{\n    public $table = 'unique_tags';\n    public $timestamps = true;\n    protected $fillable = ['name', 'type'];\n\n    public function posts()\n    {\n        return $this->belongsToMany(Post::class, 'posts_unique_tags', 'tag_id', 'post_id');\n    }\n}\n\nclass TouchingTag extends Model\n{\n    public $table = 'tags';\n    public $timestamps = true;\n    protected $guarded = [];\n    protected $touches = ['posts'];\n\n    public function posts()\n    {\n        return $this->belongsToMany(Post::class, 'posts_tags', 'tag_id', 'post_id');\n    }\n}\n\nclass TagWithCustomPivot extends Model\n{\n    public $table = 'tags';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->belongsToMany(Post::class, 'posts_tags', 'tag_id', 'post_id');\n    }\n}\n\nclass UserPostPivot extends Pivot\n{\n    protected $table = 'users_posts';\n}\n\nclass PostTagPivot extends Pivot\n{\n    protected $table = 'posts_tags';\n\n    public function getCreatedAtAttribute($value)\n    {\n        return Carbon::parse($value)->format('U');\n    }\n}\n\nclass TagWithGlobalScope extends Model\n{\n    public $table = 'tags';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope(function ($query) {\n            $query->select('tags.id');\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentBelongsToTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentBelongsToTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentBelongsToTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('slug')->nullable();\n            $table->unsignedInteger('parent_id')->nullable();\n            $table->string('parent_slug')->nullable();\n        });\n\n        $user = User::create(['slug' => Str::random()]);\n        User::create(['parent_id' => $user->id, 'parent_slug' => $user->slug]);\n    }\n\n    public function testHasSelf()\n    {\n        $users = User::has('parent')->get();\n\n        $this->assertCount(1, $users);\n    }\n\n    public function testHasSelfCustomOwnerKey()\n    {\n        $users = User::has('parentBySlug')->get();\n\n        $this->assertCount(1, $users);\n    }\n\n    public function testAssociateWithModel()\n    {\n        $parent = User::doesntHave('parent')->first();\n        $child = User::has('parent')->first();\n\n        $parent->parent()->associate($child);\n\n        $this->assertEquals($child->id, $parent->parent_id);\n        $this->assertEquals($child->id, $parent->parent->id);\n    }\n\n    public function testAssociateWithId()\n    {\n        $parent = User::doesntHave('parent')->first();\n        $child = User::has('parent')->first();\n\n        $parent->parent()->associate($child->id);\n\n        $this->assertEquals($child->id, $parent->parent_id);\n        $this->assertEquals($child->id, $parent->parent->id);\n    }\n\n    public function testAssociateWithIdUnsetsLoadedRelation()\n    {\n        $child = User::has('parent')->with('parent')->first();\n\n        // Overwrite the (loaded) parent relation\n        $child->parent()->associate($child->id);\n\n        $this->assertEquals($child->id, $child->parent_id);\n        $this->assertFalse($child->relationLoaded('parent'));\n    }\n\n    public function testParentIsNotNull()\n    {\n        $child = User::has('parent')->first();\n        $parent = null;\n\n        $this->assertFalse($child->parent()->is($parent));\n        $this->assertTrue($child->parent()->isNot($parent));\n    }\n\n    public function testParentIsModel()\n    {\n        $child = User::has('parent')->first();\n        $parent = User::doesntHave('parent')->first();\n\n        $this->assertTrue($child->parent()->is($parent));\n        $this->assertFalse($child->parent()->isNot($parent));\n    }\n\n    public function testParentIsNotAnotherModel()\n    {\n        $child = User::has('parent')->first();\n        $parent = new User;\n        $parent->id = 3;\n\n        $this->assertFalse($child->parent()->is($parent));\n        $this->assertTrue($child->parent()->isNot($parent));\n    }\n\n    public function testNullParentIsNotModel()\n    {\n        $child = User::has('parent')->first();\n        $child->parent()->dissociate();\n        $parent = User::doesntHave('parent')->first();\n\n        $this->assertFalse($child->parent()->is($parent));\n        $this->assertTrue($child->parent()->isNot($parent));\n    }\n\n    public function testParentIsNotModelWithAnotherTable()\n    {\n        $child = User::has('parent')->first();\n        $parent = User::doesntHave('parent')->first();\n        $parent->setTable('foo');\n\n        $this->assertFalse($child->parent()->is($parent));\n        $this->assertTrue($child->parent()->isNot($parent));\n    }\n\n    public function testParentIsNotModelWithAnotherConnection()\n    {\n        $child = User::has('parent')->first();\n        $parent = User::doesntHave('parent')->first();\n        $parent->setConnection('foo');\n\n        $this->assertFalse($child->parent()->is($parent));\n        $this->assertTrue($child->parent()->isNot($parent));\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class, 'parent_id');\n    }\n\n    public function parentBySlug()\n    {\n        return $this->belongsTo(self::class, 'parent_slug', 'slug');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentCollectionFreshTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\Fixtures\\User;\n\nclass EloquentCollectionFreshTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->timestamps();\n        });\n    }\n\n    public function testEloquentCollectionFresh()\n    {\n        User::insert([\n            ['email' => 'laravel@framework.com'],\n            ['email' => 'laravel@laravel.com'],\n        ]);\n\n        $collection = User::all();\n\n        $collection->first()->delete();\n\n        $freshCollection = $collection->fresh();\n\n        $this->assertCount(1, $freshCollection);\n        $this->assertInstanceOf(EloquentCollection::class, $freshCollection);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentCollectionLoadCountTest.php",
    "content": "<?php\n\nnamespace App\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentCollectionLoadCountTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('some_default_value');\n            $table->softDeletes();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('likes', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        $post = Post::create();\n        $post->comments()->saveMany([new Comment, new Comment]);\n\n        $post->likes()->save(new Like);\n\n        Post::create();\n    }\n\n    public function testLoadCount()\n    {\n        $posts = Post::all();\n\n        DB::enableQueryLog();\n\n        $posts->loadCount('comments');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertSame('2', (string) $posts[0]->comments_count);\n        $this->assertSame('0', (string) $posts[1]->comments_count);\n        $this->assertSame('2', (string) $posts[0]->getOriginal('comments_count'));\n    }\n\n    public function testLoadCountWithSameModels()\n    {\n        $posts = Post::all()->push(Post::first());\n\n        DB::enableQueryLog();\n\n        $posts->loadCount('comments');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertSame('2', (string) $posts[0]->comments_count);\n        $this->assertSame('0', (string) $posts[1]->comments_count);\n        $this->assertSame('2', (string) $posts[2]->comments_count);\n    }\n\n    public function testLoadCountOnDeletedModels()\n    {\n        $posts = Post::all()->each->delete();\n\n        DB::enableQueryLog();\n\n        $posts->loadCount('comments');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertSame('2', (string) $posts[0]->comments_count);\n        $this->assertSame('0', (string) $posts[1]->comments_count);\n    }\n\n    public function testLoadCountWithArrayOfRelations()\n    {\n        $posts = Post::all();\n\n        DB::enableQueryLog();\n\n        $posts->loadCount(['comments', 'likes']);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertSame('2', (string) $posts[0]->comments_count);\n        $this->assertSame('1', (string) $posts[0]->likes_count);\n        $this->assertSame('0', (string) $posts[1]->comments_count);\n        $this->assertSame('0', (string) $posts[1]->likes_count);\n    }\n\n    public function testLoadCountDoesNotOverrideAttributesWithDefaultValue()\n    {\n        $post = Post::first();\n        $post->some_default_value = 200;\n\n        Collection::make([$post])->loadCount('comments');\n\n        $this->assertSame(200, $post->some_default_value);\n        $this->assertSame('2', (string) $post->comments_count);\n    }\n}\n\nclass Post extends Model\n{\n    use SoftDeletes;\n\n    protected $attributes = [\n        'some_default_value' => 100,\n    ];\n\n    public $timestamps = false;\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function likes()\n    {\n        return $this->hasMany(Like::class);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n}\n\nclass Like extends Model\n{\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentCollectionLoadMissingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentCollectionLoadMissingTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentCollectionLoadMissingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('parent_id')->nullable();\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('revisions', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('comment_id');\n        });\n\n        Schema::create('post_relations', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('post_sub_relations', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_relation_id');\n        });\n\n        Schema::create('post_sub_sub_relations', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_sub_relation_id');\n        });\n\n        User::create();\n\n        Post::insert([\n            ['user_id' => 1],\n            ['user_id' => 1],\n        ]);\n\n        Comment::insert([\n            ['parent_id' => null, 'post_id' => 1],\n            ['parent_id' => 1, 'post_id' => 1],\n            ['parent_id' => 2, 'post_id' => 1],\n        ]);\n\n        Revision::create(['comment_id' => 1]);\n\n        PostRelation::create(['post_id' => 2]);\n        PostSubRelation::create(['post_relation_id' => 1]);\n        PostSubSubRelation::create(['post_sub_relation_id' => 1]);\n    }\n\n    public function testLoadMissing()\n    {\n        $posts = Post::with('comments', 'user')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing('comments.parent.revisions:revisions.comment_id', 'user:id');\n\n        $this->assertCount(2, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertTrue($posts[0]->comments[1]->parent->relationLoaded('revisions'));\n        $this->assertArrayNotHasKey('id', $posts[0]->comments[1]->parent->revisions[0]->getAttributes());\n    }\n\n    public function testLoadMissingWithClosure()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing(['comments.parent' => function ($query) {\n            $query->select('id');\n        }]);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertArrayNotHasKey('post_id', $posts[0]->comments[1]->parent->getAttributes());\n    }\n\n    public function testLoadMissingWithDuplicateRelationName()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing('comments.parent.parent');\n\n        $this->assertCount(2, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertTrue($posts[0]->comments[1]->parent->relationLoaded('parent'));\n    }\n\n    public function testLoadMissingWithoutInitialLoad()\n    {\n        $user = User::first();\n        $user->loadMissing('posts.postRelation.postSubRelations.postSubSubRelations');\n\n        $this->assertEquals(2, $user->posts->count());\n        $this->assertNull($user->posts[0]->postRelation);\n        $this->assertInstanceOf(PostRelation::class, $user->posts[1]->postRelation);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations->count());\n        $this->assertInstanceOf(PostSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations->count());\n        $this->assertInstanceOf(PostSubSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations[0]);\n    }\n\n    public function testLoadMissingWithNestedArraySyntax()\n    {\n        $posts = Post::with('user')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing([\n            'comments' => ['parent'],\n            'user',\n        ]);\n\n        $this->assertCount(2, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertTrue($posts[0]->relationLoaded('user'));\n    }\n\n    public function testLoadMissingWithMultipleDotNotationRelations()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing([\n            'comments.parent',\n            'user.posts',\n        ]);\n\n        $this->assertCount(3, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertTrue($posts[0]->relationLoaded('user'));\n        $this->assertTrue($posts[0]->user->relationLoaded('posts'));\n    }\n\n    public function testLoadMissingWithNestedArrayWithColon()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing(['comments' => ['parent:id']]);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertArrayNotHasKey('post_id', $posts[0]->comments[1]->parent->getAttributes());\n    }\n\n    public function testLoadMissingWithNestedArray()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing(['comments' => ['parent']]);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n    }\n\n    public function testLoadMissingWithNestedArrayWithClosure()\n    {\n        $posts = Post::with('comments')->get();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing(['comments' => ['parent' => function ($query) {\n            $query->select('id');\n        }]]);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));\n        $this->assertArrayNotHasKey('post_id', $posts[0]->comments[1]->parent->getAttributes());\n    }\n\n    public function testLoadMissingWithMultipleNestedArrays()\n    {\n        $users = User::get();\n        $users->loadMissing([\n            'posts' => [\n                'postRelation' => [\n                    'postSubRelations' => [\n                        'postSubSubRelations',\n                    ],\n                ],\n            ],\n        ]);\n\n        $user = $users->first();\n        $this->assertEquals(2, $user->posts->count());\n        $this->assertNull($user->posts[0]->postRelation);\n        $this->assertInstanceOf(PostRelation::class, $user->posts[1]->postRelation);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations->count());\n        $this->assertInstanceOf(PostSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations->count());\n        $this->assertInstanceOf(PostSubSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations[0]);\n    }\n\n    public function testLoadMissingWithMultipleNestedArraysCombinedWithDotNotation()\n    {\n        $users = User::get();\n        $users->loadMissing([\n            'posts' => [\n                'postRelation' => [\n                    'postSubRelations.postSubSubRelations',\n                ],\n            ],\n        ]);\n\n        $user = $users->first();\n        $this->assertEquals(2, $user->posts->count());\n        $this->assertNull($user->posts[0]->postRelation);\n        $this->assertInstanceOf(PostRelation::class, $user->posts[1]->postRelation);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations->count());\n        $this->assertInstanceOf(PostSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]);\n        $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations->count());\n        $this->assertInstanceOf(PostSubSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations[0]);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class);\n    }\n\n    public function revisions()\n    {\n        return $this->hasMany(Revision::class);\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n\n    public function postRelation()\n    {\n        return $this->hasOne(PostRelation::class);\n    }\n}\n\nclass PostRelation extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function postSubRelations()\n    {\n        return $this->hasMany(PostSubRelation::class);\n    }\n}\n\nclass PostSubRelation extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function postSubSubRelations()\n    {\n        return $this->hasMany(PostSubSubRelation::class);\n    }\n}\n\nclass PostSubSubRelation extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n\nclass Revision extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(Post::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentCursorPaginateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentCursorPaginateTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title')->nullable();\n            $table->unsignedInteger('user_id')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('test_users', function ($table) {\n            $table->increments('id');\n            $table->string('name')->nullable();\n            $table->timestamps();\n        });\n    }\n\n    public function testCursorPaginationOnTopOfColumns()\n    {\n        for ($i = 1; $i <= 16; $i++) {\n            $posts[] = [\n                'title' => 'Title '.$i,\n            ];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $this->assertCount(15, TestPost::cursorPaginate(15, ['id', 'title']));\n    }\n\n    public function testPaginationWithUnion()\n    {\n        TestPost::fillAndInsert([\n            ['title' => 'Hello world', 'user_id' => 1],\n            ['title' => 'Goodbye world', 'user_id' => 2],\n            ['title' => 'Howdy', 'user_id' => 3],\n            ['title' => '4th', 'user_id' => 4],\n        ]);\n\n        $table1 = TestPost::query()->whereIn('user_id', [1, 2]);\n        $table2 = TestPost::query()->whereIn('user_id', [3, 4]);\n\n        $result = $table1->unionAll($table2)\n            ->orderBy('user_id', 'desc')\n            ->cursorPaginate(1);\n\n        $this->assertSame(['user_id'], $result->getOptions()['parameters']);\n    }\n\n    public function testPaginationWithDistinct()\n    {\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world'];\n            $posts[] = ['title' => 'Goodbye world'];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestPost::query()->distinct();\n\n        $this->assertEquals(6, $query->get()->count());\n        $this->assertEquals(6, $query->count());\n        $this->assertCount(6, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithWhereClause()\n    {\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world', 'user_id' => null];\n            $posts[] = ['title' => 'Goodbye world', 'user_id' => 2];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestPost::query()->whereNull('user_id');\n\n        $this->assertEquals(3, $query->get()->count());\n        $this->assertEquals(3, $query->count());\n        $this->assertCount(3, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithHasClause()\n    {\n        TestUser::fillAndInsert([[], [], []]);\n\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world', 'user_id' => null];\n            $posts[] = ['title' => 'Goodbye world', 'user_id' => 2];\n            $posts[] = ['title' => 'Howdy', 'user_id' => 3];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestUser::query()->has('posts');\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(2, $query->count());\n        $this->assertCount(2, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithWhereHasClause()\n    {\n        TestUser::fillAndInsert([[], [], []]);\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world', 'user_id' => null];\n            $posts[] = ['title' => 'Goodbye world', 'user_id' => 2];\n            $posts[] = ['title' => 'Howdy', 'user_id' => 3];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestUser::query()->whereHas('posts', function ($query) {\n            $query->where('title', 'Howdy');\n        });\n\n        $this->assertEquals(1, $query->get()->count());\n        $this->assertEquals(1, $query->count());\n        $this->assertCount(1, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithWhereExistsClause()\n    {\n        TestUser::fillAndInsert([[], [], []]);\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world', 'user_id' => null];\n            $posts[] = ['title' => 'Goodbye world', 'user_id' => 2];\n            $posts[] = ['title' => 'Howdy', 'user_id' => 3];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestUser::query()->whereExists(function ($query) {\n            $query->select(DB::raw(1))\n                ->from('test_posts')\n                ->whereColumn('test_posts.user_id', 'test_users.id');\n        });\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(2, $query->count());\n        $this->assertCount(2, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithMultipleWhereClauses()\n    {\n        TestUser::fillAndInsert([[], [], [], []]);\n        for ($i = 1; $i <= 4; $i++) {\n            $posts[] = ['title' => 'Hello world', 'user_id' => null];\n            $posts[] = ['title' => 'Goodbye world', 'user_id' => 2];\n            $posts[] = ['title' => 'Howdy', 'user_id' => 3];\n            $posts[] = ['title' => 'Howdy', 'user_id' => 4];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestUser::query()->whereExists(function ($query) {\n            $query->select(DB::raw(1))\n                ->from('test_posts')\n                ->whereColumn('test_posts.user_id', 'test_users.id');\n        })->whereHas('posts', function ($query) {\n            $query->where('title', 'Howdy');\n        })->where('id', '<', 5)->orderBy('id');\n\n        $clonedQuery = $query->clone();\n        $anotherQuery = $query->clone();\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(2, $query->count());\n        $this->assertCount(2, $query->cursorPaginate()->items());\n        $this->assertCount(1, $clonedQuery->cursorPaginate(1)->items());\n        $this->assertCount(\n            1,\n            $anotherQuery->cursorPaginate(5, ['*'], 'cursor', new Cursor(['id' => 3]))\n                ->items()\n        );\n    }\n\n    public function testPaginationWithMultipleUnionAndMultipleWhereClauses()\n    {\n        TestPost::fillAndInsert([\n            ['title' => 'Post A', 'user_id' => 100],\n            ['title' => 'Post B', 'user_id' => 101],\n        ]);\n\n        $table1 = TestPost::select(['id', 'title', 'user_id'])->where('user_id', 100);\n        $table2 = TestPost::select(['id', 'title', 'user_id'])->where('user_id', 101);\n        $table3 = TestPost::select(['id', 'title', 'user_id'])->where('user_id', 101);\n\n        $columns = ['id'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['id' => 1]);\n\n        $result = $table1->toBase()\n            ->union($table2->toBase())\n            ->union($table3->toBase())\n            ->orderBy('id', 'asc')\n            ->cursorPaginate(1, $columns, $cursorName, $cursor);\n\n        $this->assertSame(['id'], $result->getOptions()['parameters']);\n\n        $postB = $table2->where('id', '>', 1)->first();\n        $this->assertEquals('Post B', $postB->title, 'Expect `Post B` is the result of the second query');\n\n        $this->assertCount(1, $result->items(), 'Expect cursor paginated query should have 1 result');\n        $this->assertEquals('Post B', current($result->items())->title, 'Expect the paginated query would return `Post B`');\n    }\n\n    public function testPaginationWithMultipleAliases()\n    {\n        TestUser::fillAndInsert([\n            ['name' => 'A (user)'],\n            ['name' => 'C (user)'],\n        ]);\n\n        TestPost::fillAndInsert([['title' => 'B (post)'], ['title' => 'D (post)']]);\n\n        $table1 = TestPost::select(['title as alias']);\n        $table2 = TestUser::select(['name as alias']);\n\n        $columns = ['alias'];\n        $cursorName = 'cursor-name';\n        $cursor = new Cursor(['alias' => 'A (user)']);\n\n        $result = $table1->toBase()\n            ->union($table2->toBase())\n            ->orderBy('alias', 'asc')\n            ->cursorPaginate(1, $columns, $cursorName, $cursor);\n\n        $this->assertSame(['alias'], $result->getOptions()['parameters']);\n\n        $this->assertCount(1, $result->items(), 'Expect cursor paginated query should have 1 result');\n        $this->assertEquals('B (post)', current($result->items())->alias, 'Expect the paginated query would return `B (post)`');\n    }\n\n    public function testPaginationWithAliasedOrderBy()\n    {\n        TestUser::fillAndInsert([[], [], [], [], [], []]);\n\n        $query = TestUser::query()->select('id as user_id')->orderBy('user_id');\n        $clonedQuery = $query->clone();\n        $anotherQuery = $query->clone();\n\n        $this->assertEquals(6, $query->get()->count());\n        $this->assertEquals(6, $query->count());\n        $this->assertCount(6, $query->cursorPaginate()->items());\n        $this->assertCount(3, $clonedQuery->cursorPaginate(3)->items());\n        $this->assertCount(\n            4,\n            $anotherQuery->cursorPaginate(10, ['*'], 'cursor', new Cursor(['user_id' => 2]))\n                ->items()\n        );\n    }\n\n    public function testPaginationWithDistinctColumnsAndSelect()\n    {\n        for ($i = 1; $i <= 3; $i++) {\n            $posts[] = ['title' => 'Hello world'];\n            $posts[] = ['title' => 'Goodbye world'];\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestPost::query()->orderBy('title')->distinct('title')->select('title');\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(2, $query->count());\n        $this->assertCount(2, $query->cursorPaginate()->items());\n    }\n\n    public function testPaginationWithDistinctColumnsAndSelectAndJoin()\n    {\n        TestUser::fillAndInsert([[], [], [], [], []]);\n        $users = TestUser::query()->get();\n        for ($i = 1; $i <= 5; $i++) {\n            $user = $users[$i - 1];\n\n            for ($j = 1; $j <= 10; $j++) {\n                $posts[] = [\n                    'title' => 'Title '.$i,\n                    'user_id' => $user->id,\n                ];\n            }\n        }\n        TestPost::fillAndInsert($posts);\n\n        $query = TestUser::query()->join('test_posts', 'test_posts.user_id', '=', 'test_users.id')\n            ->distinct('test_users.id')->select('test_users.*');\n\n        $this->assertEquals(5, $query->get()->count());\n        $this->assertEquals(5, $query->count());\n        $this->assertCount(5, $query->cursorPaginate()->items());\n    }\n}\n\nclass TestPost extends Model\n{\n    protected $guarded = [];\n}\n\nclass TestUser extends Model\n{\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(TestPost::class, 'user_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentCustomPivotCastTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentCustomPivotCastTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n        });\n\n        Schema::create('projects', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        Schema::create('project_users', function (Blueprint $table) {\n            $table->integer('user_id');\n            $table->integer('project_id');\n            $table->text('permissions');\n        });\n    }\n\n    public function testCastsAreRespectedOnAttach()\n    {\n        $user = CustomPivotCastTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->attach($user, ['permissions' => ['foo' => 'bar']]);\n        $project = $project->fresh();\n\n        $this->assertEquals(['foo' => 'bar'], $project->collaborators[0]->pivot->permissions);\n    }\n\n    public function testCastsAreRespectedOnAttachArray()\n    {\n        $user = CustomPivotCastTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $user2 = CustomPivotCastTestUser::forceCreate([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->attach([\n            $user->id => ['permissions' => ['foo' => 'bar']],\n            $user2->id => ['permissions' => ['baz' => 'bar']],\n        ]);\n        $project = $project->fresh();\n\n        $this->assertEquals(['foo' => 'bar'], $project->collaborators[0]->pivot->permissions);\n        $this->assertEquals(['baz' => 'bar'], $project->collaborators[1]->pivot->permissions);\n    }\n\n    public function testCastsAreRespectedOnSync()\n    {\n        $user = CustomPivotCastTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->sync([$user->id => ['permissions' => ['foo' => 'bar']]]);\n        $project = $project->fresh();\n\n        $this->assertEquals(['foo' => 'bar'], $project->collaborators[0]->pivot->permissions);\n    }\n\n    public function testCastsAreRespectedOnSyncArray()\n    {\n        $user = CustomPivotCastTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $user2 = CustomPivotCastTestUser::forceCreate([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->sync([\n            $user->id => ['permissions' => ['foo' => 'bar']],\n            $user2->id => ['permissions' => ['baz' => 'bar']],\n        ]);\n        $project = $project->fresh();\n\n        $this->assertEquals(['foo' => 'bar'], $project->collaborators[0]->pivot->permissions);\n        $this->assertEquals(['baz' => 'bar'], $project->collaborators[1]->pivot->permissions);\n    }\n\n    public function testCastsAreRespectedOnSyncArrayWhileUpdatingExisting()\n    {\n        $user = CustomPivotCastTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $user2 = CustomPivotCastTestUser::forceCreate([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->attach([\n            $user->id => ['permissions' => ['foo' => 'bar']],\n            $user2->id => ['permissions' => ['baz' => 'bar']],\n        ]);\n\n        $project->collaborators()->sync([\n            $user->id => ['permissions' => ['foo1' => 'bar1']],\n            $user2->id => ['permissions' => ['baz2' => 'bar2']],\n        ]);\n\n        $project = $project->fresh();\n\n        $this->assertEquals(['foo1' => 'bar1'], $project->collaborators[0]->pivot->permissions);\n        $this->assertEquals(['baz2' => 'bar2'], $project->collaborators[1]->pivot->permissions);\n    }\n\n    public function testDefaultAttributesAreRespectedAndCastsAreRespected()\n    {\n        $project = CustomPivotCastTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $pivot = $project->collaborators()->newPivot();\n\n        $this->assertEquals(['permissions' => ['create', 'update']], $pivot->toArray());\n    }\n}\n\nclass CustomPivotCastTestUser extends Model\n{\n    public $table = 'users';\n    public $timestamps = false;\n}\n\nclass CustomPivotCastTestProject extends Model\n{\n    public $table = 'projects';\n    public $timestamps = false;\n\n    public function collaborators()\n    {\n        return $this->belongsToMany(\n            CustomPivotCastTestUser::class, 'project_users', 'project_id', 'user_id'\n        )->using(CustomPivotCastTestCollaborator::class)->withPivot('permissions');\n    }\n}\n\nclass CustomPivotCastTestCollaborator extends Pivot\n{\n    public $timestamps = false;\n\n    protected $attributes = [\n        'permissions' => '[\"create\", \"update\"]',\n    ];\n\n    protected $casts = [\n        'permissions' => 'json',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentDeleteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\QueryException;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Database\\Fixtures\\PostStringyKey;\n\nclass EloquentDeleteTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('body')->nullable();\n            $table->integer('post_id');\n            $table->timestamps();\n        });\n\n        Schema::create('roles', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n    }\n\n    public function testDeleteUseLimitWithoutJoins(): void\n    {\n        $totalPosts = 10;\n        $deleteLimit = 1;\n\n        for ($i = 0; $i < $totalPosts; $i++) {\n            Post::query()->create();\n        }\n\n        // Test simple delete with limit (no join)\n        Post::query()->latest('id')->limit($deleteLimit)->delete();\n\n        $this->assertEquals($totalPosts - $deleteLimit, Post::query()->count());\n    }\n\n    public function testDeleteUseLimitWithJoins(): void\n    {\n        $ignoredDrivers = ['sqlsrv', 'mysql', 'mariadb'];\n\n        if (in_array($this->driver, $ignoredDrivers)) {\n            $this->markTestSkipped(\"{$this->driver} does not support LIMIT on DELETE statements with JOIN clauses.\");\n        }\n\n        $totalPosts = 10;\n        $deleteLimit = 1;\n        $whereThreshold = 8;\n\n        for ($i = 0; $i < $totalPosts; $i++) {\n            Comment::query()->create([\n                'post_id' => Post::query()->create()->id,\n            ]);\n        }\n\n        // Test delete with join and limit\n        Post::query()\n            ->join('comments', 'comments.post_id', '=', 'posts.id')\n            ->where('posts.id', '>', $whereThreshold)\n            ->orderBy('posts.id')\n            ->limit($deleteLimit)\n            ->delete();\n\n        $this->assertEquals($totalPosts - $deleteLimit, Post::query()->count());\n    }\n\n    public function testDeleteWithLimitAndJoinThrowsExceptionOnMySql(): void\n    {\n        if (! in_array($this->driver, ['mysql', 'mariadb'])) {\n            $this->markTestSkipped('This test only applies to MySQL/MariaDB.');\n        }\n\n        $this->expectException(QueryException::class);\n\n        for ($i = 0; $i < 10; $i++) {\n            Comment::query()->create([\n                'post_id' => Post::query()->create()->id,\n            ]);\n        }\n\n        Post::query()\n            ->join('comments', 'comments.post_id', '=', 'posts.id')\n            ->where('posts.id', '>', 5)\n            ->orderBy('posts.id')\n            ->limit(1)\n            ->delete();\n    }\n\n    public function testForceDeletedEventIsFired()\n    {\n        $role = Role::create([]);\n        $this->assertInstanceOf(Role::class, $role);\n        Role::observe(new RoleObserver);\n\n        $role->delete();\n        $this->assertNull(RoleObserver::$model);\n\n        $role->forceDelete();\n\n        $this->assertEquals($role->id, RoleObserver::$model->id);\n    }\n\n    public function testForceDeletingEventIsFired()\n    {\n        $role = Role::create([]);\n        $this->assertInstanceOf(Role::class, $role);\n        Role::observe(new RoleObserver());\n\n        $role->forceDelete();\n\n        $this->assertEquals($role->id, RoleObserver::$model->id);\n    }\n\n    public function testDeleteQuietly()\n    {\n        $_SERVER['(-_-)'] = '\\(^_^)/';\n        Post::deleting(fn () => $_SERVER['(-_-)'] = null);\n        Post::deleted(fn () => $_SERVER['(-_-)'] = null);\n        $post = Post::query()->create([]);\n        $result = $post->deleteQuietly();\n\n        $this->assertEquals('\\(^_^)/', $_SERVER['(-_-)']);\n        $this->assertTrue($result);\n        $this->assertFalse($post->exists);\n\n        // For a soft-deleted model:\n        Role::deleting(fn () => $_SERVER['(-_-)'] = null);\n        Role::deleted(fn () => $_SERVER['(-_-)'] = null);\n        Role::softDeleted(fn () => $_SERVER['(-_-)'] = null);\n        $role = Role::create([]);\n        $result = $role->deleteQuietly();\n        $this->assertTrue($result);\n        $this->assertEquals('\\(^_^)/', $_SERVER['(-_-)']);\n\n        unset($_SERVER['(-_-)']);\n    }\n\n    public function testDestroy()\n    {\n        Schema::create('my_posts', function (Blueprint $table) {\n            $table->increments('my_id');\n            $table->timestamps();\n        });\n\n        PostStringyKey::unguard();\n        PostStringyKey::query()->create([]);\n        PostStringyKey::query()->create([]);\n\n        PostStringyKey::query()->getConnection()->enableQueryLog();\n        PostStringyKey::retrieved(fn ($model) => $_SERVER['destroy']['retrieved'][] = $model->my_id);\n        PostStringyKey::deleting(fn ($model) => $_SERVER['destroy']['deleting'][] = $model->my_id);\n        PostStringyKey::deleted(fn ($model) => $_SERVER['destroy']['deleted'][] = $model->my_id);\n\n        $_SERVER['destroy'] = [];\n        PostStringyKey::destroy(1, 2, 3, 4);\n\n        $this->assertEquals([1, 2], $_SERVER['destroy']['retrieved']);\n        $this->assertEquals([1, 2], $_SERVER['destroy']['deleting']);\n        $this->assertEquals([1, 2], $_SERVER['destroy']['deleted']);\n\n        $logs = PostStringyKey::query()->getConnection()->getQueryLog();\n\n        $this->assertEquals(0, PostStringyKey::query()->count());\n\n        $this->assertStringStartsWith('select * from \"my_posts\" where \"my_id\" in (', str_replace(['`', '[', ']'], '\"', $logs[0]['query']));\n\n        $this->assertStringStartsWith('delete from \"my_posts\" where \"my_id\" = ', str_replace(['`', '[', ']'], '\"', $logs[1]['query']));\n        $this->assertEquals([1], $logs[1]['bindings']);\n\n        $this->assertStringStartsWith('delete from \"my_posts\" where \"my_id\" = ', str_replace(['`', '[', ']'], '\"', $logs[2]['query']));\n        $this->assertEquals([2], $logs[2]['bindings']);\n\n        // Total of 3 queries.\n        $this->assertCount(3, $logs);\n\n        PostStringyKey::reguard();\n        unset($_SERVER['destroy']);\n        Schema::drop('my_posts');\n    }\n}\n\nclass Comment extends Model\n{\n    public $table = 'comments';\n    protected $fillable = ['post_id'];\n}\n\nclass Role extends Model\n{\n    use SoftDeletes;\n    public $table = 'roles';\n    protected $guarded = [];\n}\n\nclass RoleObserver\n{\n    public static $model;\n\n    public function forceDeleted($model)\n    {\n        static::$model = $model;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentEagerLoadingLimitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentEagerLoadingLimitTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentEagerLoadingLimitTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->id();\n            $table->unsignedBigInteger('user_id');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->id();\n            $table->unsignedBigInteger('post_id');\n            $table->timestamps();\n        });\n\n        Schema::create('roles', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n        });\n\n        Schema::create('role_user', function (Blueprint $table) {\n            $table->unsignedBigInteger('role_id');\n            $table->unsignedBigInteger('user_id');\n        });\n\n        User::create();\n        User::create();\n\n        Post::create(['user_id' => 1, 'created_at' => new Carbon('2024-01-01 00:00:01')]);\n        Post::create(['user_id' => 1, 'created_at' => new Carbon('2024-01-01 00:00:02')]);\n        Post::create(['user_id' => 1, 'created_at' => new Carbon('2024-01-01 00:00:03')]);\n        Post::create(['user_id' => 2, 'created_at' => new Carbon('2024-01-01 00:00:04')]);\n        Post::create(['user_id' => 2, 'created_at' => new Carbon('2024-01-01 00:00:05')]);\n        Post::create(['user_id' => 2, 'created_at' => new Carbon('2024-01-01 00:00:06')]);\n\n        Comment::create(['post_id' => 1, 'created_at' => new Carbon('2024-01-01 00:00:01')]);\n        Comment::create(['post_id' => 2, 'created_at' => new Carbon('2024-01-01 00:00:02')]);\n        Comment::create(['post_id' => 3, 'created_at' => new Carbon('2024-01-01 00:00:03')]);\n        Comment::create(['post_id' => 4, 'created_at' => new Carbon('2024-01-01 00:00:04')]);\n        Comment::create(['post_id' => 5, 'created_at' => new Carbon('2024-01-01 00:00:05')]);\n        Comment::create(['post_id' => 6, 'created_at' => new Carbon('2024-01-01 00:00:06')]);\n\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:01')]);\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:02')]);\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:03')]);\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:04')]);\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:05')]);\n        Role::create(['created_at' => new Carbon('2024-01-01 00:00:06')]);\n\n        DB::table('role_user')->insert([\n            ['role_id' => 1, 'user_id' => 1],\n            ['role_id' => 2, 'user_id' => 1],\n            ['role_id' => 3, 'user_id' => 1],\n            ['role_id' => 4, 'user_id' => 2],\n            ['role_id' => 5, 'user_id' => 2],\n            ['role_id' => 6, 'user_id' => 2],\n        ]);\n    }\n\n    public function testBelongsToMany(): void\n    {\n        $users = User::with(['roles' => fn ($query) => $query->latest()->limit(2)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([3, 2], $users[0]->roles->pluck('id')->all());\n        $this->assertEquals([6, 5], $users[1]->roles->pluck('id')->all());\n        $this->assertArrayNotHasKey('laravel_row', $users[0]->roles[0]);\n        $this->assertArrayNotHasKey('@laravel_group := `user_id`', $users[0]->roles[0]);\n    }\n\n    public function testBelongsToManyWithOffset(): void\n    {\n        $users = User::with(['roles' => fn ($query) => $query->latest()->limit(2)->offset(1)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([2, 1], $users[0]->roles->pluck('id')->all());\n        $this->assertEquals([5, 4], $users[1]->roles->pluck('id')->all());\n    }\n\n    public function testHasMany(): void\n    {\n        $users = User::with(['posts' => fn ($query) => $query->latest()->limit(2)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([3, 2], $users[0]->posts->pluck('id')->all());\n        $this->assertEquals([6, 5], $users[1]->posts->pluck('id')->all());\n        $this->assertArrayNotHasKey('laravel_row', $users[0]->posts[0]);\n        $this->assertArrayNotHasKey('@laravel_group := `user_id`', $users[0]->posts[0]);\n    }\n\n    public function testHasManyWithOffset(): void\n    {\n        $users = User::with(['posts' => fn ($query) => $query->latest()->limit(2)->offset(1)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([2, 1], $users[0]->posts->pluck('id')->all());\n        $this->assertEquals([5, 4], $users[1]->posts->pluck('id')->all());\n    }\n\n    public function testHasManyThrough(): void\n    {\n        $users = User::with(['comments' => fn ($query) => $query->latest('comments.created_at')->limit(2)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([3, 2], $users[0]->comments->pluck('id')->all());\n        $this->assertEquals([6, 5], $users[1]->comments->pluck('id')->all());\n        $this->assertArrayNotHasKey('laravel_row', $users[0]->comments[0]);\n        $this->assertArrayNotHasKey('@laravel_group := `user_id`', $users[0]->comments[0]);\n    }\n\n    public function testHasManyThroughWithOffset(): void\n    {\n        $users = User::with(['comments' => fn ($query) => $query->latest('comments.created_at')->limit(2)->offset(1)])\n            ->orderBy('id')\n            ->get();\n\n        $this->assertEquals([2, 1], $users[0]->comments->pluck('id')->all());\n        $this->assertEquals([5, 4], $users[1]->comments->pluck('id')->all());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n\nclass Post extends Model\n{\n    protected $guarded = [];\n}\n\nclass Role extends Model\n{\n    protected $guarded = [];\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function comments(): HasManyThrough\n    {\n        return $this->hasManyThrough(Comment::class, Post::class);\n    }\n\n    public function posts(): HasMany\n    {\n        return $this->hasMany(Post::class);\n    }\n\n    public function roles(): BelongsToMany\n    {\n        return $this->belongsToMany(Role::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentHasManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOne;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass EloquentHasManyTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('eloquent_has_many_test_users', function ($table) {\n            $table->id();\n        });\n\n        Schema::create('eloquent_has_many_test_posts', function ($table) {\n            $table->id();\n            $table->foreignId('eloquent_has_many_test_user_id');\n            $table->string('title')->unique();\n            $table->timestamps();\n        });\n\n        Schema::create('eloquent_has_many_test_logins', function ($table) {\n            $table->id();\n            $table->foreignId('eloquent_has_many_test_user_id');\n            $table->timestamp('login_time');\n        });\n    }\n\n    public function testCanGetHasOneFromHasManyRelationship()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        $user->logins()->create(['login_time' => Carbon::now()]);\n\n        $this->assertInstanceOf(HasOne::class, $user->logins()->one());\n    }\n\n    public function testHasOneRelationshipFromHasMany()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        EloquentHasManyTestLogin::create([\n            'eloquent_has_many_test_user_id' => $user->id,\n            'login_time' => '2020-09-29',\n        ]);\n        $latestLogin = EloquentHasManyTestLogin::create([\n            'eloquent_has_many_test_user_id' => $user->id,\n            'login_time' => '2023-03-14',\n        ]);\n        $oldestLogin = EloquentHasManyTestLogin::create([\n            'eloquent_has_many_test_user_id' => $user->id,\n            'login_time' => '2010-01-01',\n        ]);\n\n        $this->assertEquals($oldestLogin->id, $user->oldestLogin->id);\n        $this->assertEquals($latestLogin->id, $user->latestLogin->id);\n    }\n\n    public function testFirstOrCreate()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        $post1 = $user->posts()->create(['title' => Str::random()]);\n        $post2 = $user->posts()->firstOrCreate(['title' => $post1->title]);\n\n        $this->assertTrue($post1->is($post2));\n        $this->assertCount(1, $user->posts()->get());\n    }\n\n    public function testFirstOrCreateWithinTransaction()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        $post1 = $user->posts()->create(['title' => Str::random()]);\n\n        DB::transaction(function () use ($user, $post1) {\n            $post2 = $user->posts()->firstOrCreate(['title' => $post1->title]);\n\n            $this->assertTrue($post1->is($post2));\n        });\n\n        $this->assertCount(1, $user->posts()->get());\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        $post1 = $user->posts()->createOrFirst(['title' => Str::random()]);\n        $post2 = $user->posts()->createOrFirst(['title' => $post1->title]);\n\n        $this->assertTrue($post1->is($post2));\n        $this->assertCount(1, $user->posts()->get());\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user = EloquentHasManyTestUser::create();\n\n        $post1 = $user->posts()->create(['title' => Str::random()]);\n\n        DB::transaction(function () use ($user, $post1) {\n            $post2 = $user->posts()->createOrFirst(['title' => $post1->title]);\n\n            $this->assertTrue($post1->is($post2));\n        });\n\n        $this->assertCount(1, $user->posts()->get());\n    }\n}\n\nclass EloquentHasManyTestUser extends Model\n{\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function logins(): HasMany\n    {\n        return $this->hasMany(EloquentHasManyTestLogin::class);\n    }\n\n    public function latestLogin(): HasOne\n    {\n        return $this->logins()->one()->latestOfMany('login_time');\n    }\n\n    public function oldestLogin(): HasOne\n    {\n        return $this->logins()->one()->oldestOfMany('login_time');\n    }\n\n    public function posts(): HasMany\n    {\n        return $this->hasMany(EloquentHasManyTestPost::class);\n    }\n}\n\nclass EloquentHasManyTestLogin extends Model\n{\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass EloquentHasManyTestPost extends Model\n{\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentHasManyThroughTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentHasManyThroughTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\HasOneThrough;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentHasManyThroughTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('slug')->nullable();\n            $table->integer('team_id')->nullable();\n            $table->string('name');\n        });\n\n        Schema::create('teams', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('owner_id')->nullable();\n            $table->string('owner_slug')->nullable();\n        });\n\n        Schema::create('categories', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('parent_id')->nullable();\n            $table->softDeletes();\n        });\n\n        Schema::create('products', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('category_id');\n        });\n\n        Schema::create('articles', function (Blueprint $table) {\n            $table->id();\n            $table->foreignId('user_id');\n            $table->string('title')->unique();\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicCreateAndRetrieve()\n    {\n        $user = User::create(['name' => Str::random()]);\n\n        $team1 = Team::create(['owner_id' => $user->id]);\n        $team2 = Team::create(['owner_id' => $user->id]);\n\n        $mate1 = User::create(['name' => 'John', 'team_id' => $team1->id]);\n        $mate2 = User::create(['name' => 'Jack', 'team_id' => $team2->id, 'slug' => null]);\n\n        User::create(['name' => Str::random()]);\n\n        $this->assertEquals([$mate1->id, $mate2->id], $user->teamMates->pluck('id')->toArray());\n        $this->assertEquals([$mate1->id, $mate2->id], $user->teamMatesWithPendingRelation->pluck('id')->toArray());\n        $this->assertEquals([$user->id], User::has('teamMates')->pluck('id')->toArray());\n        $this->assertEquals([$user->id], User::has('teamMatesWithPendingRelation')->pluck('id')->toArray());\n\n        $result = $user->teamMates()->first();\n        $this->assertEquals(\n            $mate1->refresh()->getAttributes() + ['laravel_through_key' => '1'],\n            $result->getAttributes()\n        );\n\n        $result = $user->teamMatesWithPendingRelation()->first();\n        $this->assertEquals(\n            $mate1->refresh()->getAttributes() + ['laravel_through_key' => '1'],\n            $result->getAttributes()\n        );\n\n        $result = $user->teamMates()->firstWhere('name', 'Jack');\n        $this->assertEquals(\n            $mate2->refresh()->getAttributes() + ['laravel_through_key' => '1'],\n            $result->getAttributes()\n        );\n\n        $result = $user->teamMatesWithPendingRelation()->firstWhere('name', 'Jack');\n        $this->assertEquals(\n            $mate2->refresh()->getAttributes() + ['laravel_through_key' => '1'],\n            $result->getAttributes()\n        );\n    }\n\n    public function testGlobalScopeColumns()\n    {\n        $user = User::create(['name' => Str::random()]);\n\n        $team1 = Team::create(['owner_id' => $user->id]);\n\n        User::create(['name' => Str::random(), 'team_id' => $team1->id]);\n\n        $teamMates = $user->teamMatesWithGlobalScope;\n        $this->assertEquals(['id' => 2, 'laravel_through_key' => 1], $teamMates[0]->getAttributes());\n\n        $teamMates = $user->teamMatesWithGlobalScopeWithPendingRelation;\n        $this->assertEquals(['id' => 2, 'laravel_through_key' => 1], $teamMates[0]->getAttributes());\n    }\n\n    public function testHasSelf()\n    {\n        $user = User::create(['name' => Str::random()]);\n\n        $team = Team::create(['owner_id' => $user->id]);\n\n        User::create(['name' => Str::random(), 'team_id' => $team->id]);\n\n        $users = User::has('teamMates')->get();\n        $this->assertCount(1, $users);\n\n        $users = User::has('teamMatesWithPendingRelation')->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testHasSelfCustomOwnerKey()\n    {\n        $user = User::create(['slug' => Str::random(), 'name' => Str::random()]);\n\n        $team = Team::create(['owner_slug' => $user->slug]);\n\n        User::create(['name' => Str::random(), 'team_id' => $team->id]);\n\n        $users = User::has('teamMatesBySlug')->get();\n        $this->assertCount(1, $users);\n\n        $users = User::has('teamMatesBySlugWithPendingRelationship')->get();\n        $this->assertCount(1, $users);\n    }\n\n    public function testHasSameParentAndThroughParentTable()\n    {\n        Category::create();\n        Category::create();\n        Category::create(['parent_id' => 1]);\n        Category::create(['parent_id' => 2])->delete();\n\n        Product::create(['category_id' => 3]);\n        Product::create(['category_id' => 4]);\n\n        $categories = Category::has('subProducts')->get();\n\n        $this->assertEquals([1], $categories->pluck('id')->all());\n    }\n\n    public function testFirstOrNewOnMissingRecord()\n    {\n        $taylor = User::create(['name' => 'Taylor', 'slug' => 'taylor']);\n        $team = Team::create(['owner_id' => $taylor->id]);\n\n        $user1 = $taylor->teamMates()->firstOrNew(\n            ['slug' => 'tony'],\n            ['name' => 'Tony', 'team_id' => $team->id],\n        );\n\n        $this->assertFalse($user1->exists);\n        $this->assertEquals($team->id, $user1->team_id);\n        $this->assertSame('tony', $user1->slug);\n        $this->assertSame('Tony', $user1->name);\n    }\n\n    public function testFirstOrNewWhenRecordExists()\n    {\n        $taylor = User::create(['name' => 'Taylor', 'slug' => 'taylor']);\n        $team = Team::create(['owner_id' => $taylor->id]);\n        $existingTony = $team->members()->create(['name' => 'Tony Messias', 'slug' => 'tony']);\n\n        $newTony = $taylor->teamMates()->firstOrNew(\n            ['slug' => 'tony'],\n            ['name' => 'Tony', 'team_id' => $team->id],\n        );\n\n        $this->assertTrue($newTony->exists);\n        $this->assertEquals($team->id, $newTony->team_id);\n        $this->assertSame('tony', $newTony->slug);\n        $this->assertSame('Tony Messias', $newTony->name);\n\n        $this->assertTrue($existingTony->is($newTony));\n        $this->assertSame('tony', $existingTony->refresh()->slug);\n        $this->assertSame('Tony Messias', $existingTony->name);\n    }\n\n    public function testFirstOrCreateWhenModelDoesntExist()\n    {\n        $owner = User::create(['name' => 'Taylor']);\n        Team::create(['owner_id' => $owner->id]);\n\n        $mate = $owner->teamMates()->firstOrCreate(['slug' => 'adam'], ['name' => 'Adam']);\n\n        $this->assertTrue($mate->wasRecentlyCreated);\n        $this->assertNull($mate->team_id);\n        $this->assertEquals('Adam', $mate->name);\n        $this->assertEquals('adam', $mate->slug);\n    }\n\n    public function testFirstOrCreateWhenModelExists()\n    {\n        $owner = User::create(['name' => 'Taylor']);\n        $team = Team::create(['owner_id' => $owner->id]);\n\n        $team->members()->create(['slug' => 'adam', 'name' => 'Adam Wathan']);\n\n        $mate = $owner->teamMates()->firstOrCreate(['slug' => 'adam'], ['name' => 'Adam']);\n\n        $this->assertFalse($mate->wasRecentlyCreated);\n        $this->assertNotNull($mate->team_id);\n        $this->assertTrue($team->is($mate->team));\n        $this->assertEquals('Adam Wathan', $mate->name);\n        $this->assertEquals('adam', $mate->slug);\n    }\n\n    public function testFirstOrCreateRegressionIssue()\n    {\n        $team1 = Team::create();\n        $team2 = Team::create();\n\n        $jane = $team2->members()->create(['name' => 'Jane', 'slug' => 'jane']);\n        $john = $team1->members()->create(['name' => 'John', 'slug' => 'john']);\n\n        $taylor = User::create(['name' => 'Taylor']);\n        $team1->update(['owner_id' => $taylor->id]);\n\n        $newJohn = $taylor->teamMates()->firstOrCreate(\n            ['slug' => 'john'],\n            ['name' => 'John Doe'],\n        );\n\n        $this->assertFalse($newJohn->wasRecentlyCreated);\n        $this->assertTrue($john->is($newJohn));\n        $this->assertEquals('john', $newJohn->refresh()->slug);\n        $this->assertEquals('John', $newJohn->name);\n\n        $this->assertSame('john', $john->refresh()->slug);\n        $this->assertSame('John', $john->name);\n        $this->assertSame('jane', $jane->refresh()->slug);\n        $this->assertSame('Jane', $jane->name);\n    }\n\n    public function testCreateOrFirstWhenRecordDoesntExist()\n    {\n        $team = Team::create();\n        $tony = $team->members()->create(['name' => 'Tony']);\n\n        $article = $team->articles()->createOrFirst(\n            ['title' => 'Laravel Forever'],\n            ['user_id' => $tony->id],\n        );\n\n        $this->assertTrue($article->wasRecentlyCreated);\n        $this->assertEquals('Laravel Forever', $article->title);\n        $this->assertTrue($tony->is($article->user));\n    }\n\n    public function testCreateOrFirstWhenRecordExists()\n    {\n        $team = Team::create();\n        $taylor = $team->members()->create(['name' => 'Taylor']);\n        $tony = $team->members()->create(['name' => 'Tony']);\n\n        $existingArticle = $taylor->articles()->create([\n            'title' => 'Laravel Forever',\n        ]);\n\n        $newArticle = $team->articles()->createOrFirst(\n            ['title' => 'Laravel Forever'],\n            ['user_id' => $tony->id],\n        );\n\n        $this->assertFalse($newArticle->wasRecentlyCreated);\n        $this->assertEquals('Laravel Forever', $newArticle->title);\n        $this->assertTrue($taylor->is($newArticle->user));\n        $this->assertTrue($existingArticle->is($newArticle));\n    }\n\n    public function testCreateOrFirstWhenRecordExistsInTransaction()\n    {\n        $team = Team::create();\n        $taylor = $team->members()->create(['name' => 'Taylor']);\n        $tony = $team->members()->create(['name' => 'Tony']);\n\n        $existingArticle = $taylor->articles()->create([\n            'title' => 'Laravel Forever',\n        ]);\n\n        $newArticle = DB::transaction(fn () => $team->articles()->createOrFirst(\n            ['title' => 'Laravel Forever'],\n            ['user_id' => $tony->id],\n        ));\n\n        $this->assertFalse($newArticle->wasRecentlyCreated);\n        $this->assertEquals('Laravel Forever', $newArticle->title);\n        $this->assertTrue($taylor->is($newArticle->user));\n        $this->assertTrue($existingArticle->is($newArticle));\n    }\n\n    public function testCreateOrFirstRegressionIssue()\n    {\n        $team1 = Team::create();\n\n        $taylor = $team1->members()->create(['name' => 'Taylor']);\n        $tony = $team1->members()->create(['name' => 'Tony']);\n\n        $existingTonyArticle = $tony->articles()->create(['title' => 'The New createOrFirst Method']);\n        $existingTaylorArticle = $taylor->articles()->create(['title' => 'Laravel Forever']);\n\n        $newArticle = $team1->articles()->createOrFirst(\n            ['title' => 'Laravel Forever'],\n            ['user_id' => $tony->id],\n        );\n\n        $this->assertFalse($newArticle->wasRecentlyCreated);\n        $this->assertTrue($existingTaylorArticle->is($newArticle));\n        $this->assertEquals('Laravel Forever', $newArticle->refresh()->title);\n        $this->assertTrue($taylor->is($newArticle->user));\n\n        $this->assertSame('Laravel Forever', $existingTaylorArticle->refresh()->title);\n        $this->assertSame('The New createOrFirst Method', $existingTonyArticle->refresh()->title);\n        $this->assertTrue($tony->is($existingTonyArticle->user));\n    }\n\n    public function testUpdateOrCreateAffectingWrongModelsRegression()\n    {\n        // On Laravel 10.21.0, a bug was introduced that would update the wrong model when using `updateOrCreate()`,\n        // because the UPDATE statement would target a model based on the ID from the parent instead of the actual\n        // conditions that the `updateOrCreate()` targeted. This test replicates the case that causes this bug.\n\n        $team1 = Team::create();\n        $team2 = Team::create();\n\n        // Jane's ID should be the same as the $team1's ID for the bug to occur.\n        $jane = User::create(['name' => 'Jane', 'slug' => 'jane-slug', 'team_id' => $team2->id]);\n        $john = User::create(['name' => 'John', 'slug' => 'john-slug', 'team_id' => $team1->id]);\n\n        $taylor = User::create(['name' => 'Taylor']);\n        $team1->update(['owner_id' => $taylor->id]);\n\n        $this->assertSame(2, $john->id);\n        $this->assertSame(1, $jane->id);\n\n        $this->assertSame(2, $john->refresh()->id);\n        $this->assertSame(1, $jane->refresh()->id);\n\n        $this->assertSame('john-slug', $john->slug);\n        $this->assertSame('jane-slug', $jane->slug);\n\n        $this->assertSame('john-slug', $john->refresh()->slug);\n        $this->assertSame('jane-slug', $jane->refresh()->slug);\n\n        // The `updateOrCreate` method would first try to find a matching attached record with a query like:\n        // `->where($attributes)->first()`, which should return `John` of ID 1 in our case. However, it'd\n        // return the incorrect ID of 2, which caused it to update Jane's record instead of John's.\n\n        $taylor->teamMates()->updateOrCreate([\n            'name' => 'John',\n        ], [\n            'slug' => 'john-doe',\n        ]);\n\n        // Expect $john's slug to be updated to john-doe instead of john-slug.\n        $this->assertSame('john-doe', $john->fresh()->slug);\n        // $jane should not be updated, because it belongs to a different user altogether.\n        $this->assertSame('jane-slug', $jane->fresh()->slug);\n    }\n\n    public function testCanReplicateModelLoadedThroughHasManyThrough()\n    {\n        $team = Team::create();\n        $user = User::create(['team_id' => $team->id, 'name' => 'John']);\n        Article::create(['user_id' => $user->id, 'title' => 'John\\'s new has-many-through-article']);\n\n        $article = $team->articles()->first();\n\n        $this->assertInstanceOf(Article::class, $article);\n\n        $newArticle = $article->replicate();\n        $newArticle->title .= ' v2';\n        $newArticle->save();\n    }\n\n    public function testOne(): void\n    {\n        $team = Team::create();\n\n        $user = User::create(['team_id' => $team->id, 'name' => Str::random()]);\n\n        Article::create(['user_id' => $user->id, 'title' => Str::random(), 'created_at' => Carbon::now()->subDay()]);\n        $latestArticle = Article::create(['user_id' => $user->id, 'title' => Str::random(), 'created_at' => Carbon::now()]);\n\n        $this->assertEquals($latestArticle->id, $team->latestArticle->id);\n    }\n}\n\nclass User extends Model\n{\n    public $table = 'users';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function teamMates()\n    {\n        return $this->hasManyThrough(self::class, Team::class, 'owner_id', 'team_id');\n    }\n\n    public function teamMatesWithPendingRelation()\n    {\n        return $this->through($this->ownedTeams())\n            ->has(fn (Team $team) => $team->members());\n    }\n\n    public function teamMatesBySlug()\n    {\n        return $this->hasManyThrough(self::class, Team::class, 'owner_slug', 'team_id', 'slug');\n    }\n\n    public function teamMatesBySlugWithPendingRelationship()\n    {\n        return $this->through($this->hasMany(Team::class, 'owner_slug', 'slug'))\n            ->has(fn ($team) => $team->hasMany(User::class, 'team_id'));\n    }\n\n    public function teamMatesWithGlobalScope()\n    {\n        return $this->hasManyThrough(UserWithGlobalScope::class, Team::class, 'owner_id', 'team_id');\n    }\n\n    public function teamMatesWithGlobalScopeWithPendingRelation()\n    {\n        return $this->through($this->ownedTeams())\n            ->has(fn (Team $team) => $team->membersWithGlobalScope());\n    }\n\n    public function ownedTeams()\n    {\n        return $this->hasMany(Team::class, 'owner_id');\n    }\n\n    public function team()\n    {\n        return $this->belongsTo(Team::class);\n    }\n\n    public function articles()\n    {\n        return $this->hasMany(Article::class);\n    }\n}\n\nclass UserWithGlobalScope extends Model\n{\n    public $table = 'users';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope(function ($query) {\n            $query->select('users.id');\n        });\n    }\n}\n\nclass Team extends Model\n{\n    public $table = 'teams';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function members()\n    {\n        return $this->hasMany(User::class, 'team_id');\n    }\n\n    public function membersWithGlobalScope()\n    {\n        return $this->hasMany(UserWithGlobalScope::class, 'team_id');\n    }\n\n    public function articles()\n    {\n        return $this->hasManyThrough(Article::class, User::class);\n    }\n\n    public function latestArticle(): HasOneThrough\n    {\n        return $this->articles()->one()->latest();\n    }\n}\n\nclass Category extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function subProducts()\n    {\n        return $this->hasManyThrough(Product::class, self::class, 'parent_id');\n    }\n}\n\nclass Product extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n}\n\nclass Article extends Model\n{\n    protected $guarded = [];\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentHasOneIsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentHasOneIsTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentHasOneIsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        Schema::create('attachments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id')->nullable();\n        });\n\n        $post = Post::create();\n        $post->attachment()->create();\n    }\n\n    public function testChildIsNotNull()\n    {\n        $parent = Post::first();\n        $child = null;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsModel()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n\n        $this->assertTrue($parent->attachment()->is($child));\n        $this->assertFalse($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotAnotherModel()\n    {\n        $parent = Post::first();\n        $child = new Attachment;\n        $child->id = 2;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testNullChildIsNotModel()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->post_id = null;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotModelWithAnotherTable()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->setTable('foo');\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotModelWithAnotherConnection()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->setConnection('foo');\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n}\n\nclass Attachment extends Model\n{\n    public $timestamps = false;\n}\n\nclass Post extends Model\n{\n    public function attachment()\n    {\n        return $this->hasOne(Attachment::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentHasOneOfManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentHasOneOfManyTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentHasOneOfManyTest extends DatabaseTestCase\n{\n    public $retrievedLogins;\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function ($table) {\n            $table->id();\n        });\n\n        Schema::create('logins', function ($table) {\n            $table->id();\n            $table->foreignId('user_id');\n        });\n\n        Schema::create('states', function ($table) {\n            $table->increments('id');\n            $table->string('state');\n            $table->string('type');\n            $table->foreignId('user_id');\n            $table->timestamps();\n        });\n    }\n\n    public function testItOnlyEagerLoadsRequiredModels()\n    {\n        $this->retrievedLogins = 0;\n        User::getEventDispatcher()->listen('eloquent.retrieved:*', function ($event, $models) {\n            foreach ($models as $model) {\n                if (get_class($model) == Login::class) {\n                    $this->retrievedLogins++;\n                }\n            }\n        });\n\n        $user = User::create();\n        $user->latest_login()->create();\n        $user->latest_login()->create();\n        $user = User::create();\n        $user->latest_login()->create();\n        $user->latest_login()->create();\n\n        User::with('latest_login')->get();\n\n        $this->assertSame(2, $this->retrievedLogins);\n    }\n\n    public function testItGetsCorrectResultUsingAtLeastTwoAggregatesDistinctFromId()\n    {\n        $user = User::create();\n\n        $latestState = $user->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-03',\n        ]);\n\n        $oldestState = $user->states()->create([\n            'state' => 'state',\n            'type' => 'type',\n            'created_at' => '2023-01-01',\n            'updated_at' => '2023-01-02',\n        ]);\n\n        $this->assertSame($user->oldest_updated_state->id, $oldestState->id);\n        $this->assertSame($user->oldest_updated_oldest_created_state->id, $oldestState->id);\n\n        $users = User::with('latest_updated_state', 'latest_updated_latest_created_state')->get();\n\n        $this->assertSame($users[0]->latest_updated_state->id, $latestState->id);\n        $this->assertSame($users[0]->latest_updated_latest_created_state->id, $latestState->id);\n    }\n}\n\nclass User extends Model\n{\n    protected $guarded = [];\n    public $timestamps = false;\n\n    public function latest_login()\n    {\n        return $this->hasOne(Login::class)->ofMany();\n    }\n\n    public function states()\n    {\n        return $this->hasMany(State::class);\n    }\n\n    public function latest_updated_state()\n    {\n        return $this->hasOne(State::class, 'user_id')->ofMany('updated_at', 'max');\n    }\n\n    public function oldest_updated_state()\n    {\n        return $this->hasOne(State::class, 'user_id')->ofMany('updated_at', 'min');\n    }\n\n    public function latest_updated_latest_created_state()\n    {\n        return $this->hasOne(State::class, 'user_id')->ofMany([\n            'updated_at' => 'max',\n            'created_at' => 'max',\n        ]);\n    }\n\n    public function oldest_updated_oldest_created_state()\n    {\n        return $this->hasOne(State::class, 'user_id')->ofMany([\n            'updated_at' => 'min',\n            'created_at' => 'min',\n        ]);\n    }\n}\n\nclass Login extends Model\n{\n    protected $guarded = [];\n    public $timestamps = false;\n}\n\nclass State extends Model\n{\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentLazyEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentLazyEagerLoadingTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentLazyEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('one', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('two', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('one_id');\n        });\n\n        Schema::create('three', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('one_id');\n        });\n    }\n\n    public function testItBasic()\n    {\n        $one = Model1::create();\n        $one->twos()->create();\n        $one->threes()->create();\n\n        $model = Model1::find($one->id);\n\n        $this->assertTrue($model->relationLoaded('twos'));\n        $this->assertFalse($model->relationLoaded('threes'));\n\n        DB::enableQueryLog();\n\n        $model->load('threes');\n\n        $this->assertCount(1, DB::getQueryLog());\n\n        $this->assertTrue($model->relationLoaded('threes'));\n    }\n}\n\nclass Model1 extends Model\n{\n    public $table = 'one';\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $with = ['twos'];\n\n    public function twos()\n    {\n        return $this->hasMany(Model2::class, 'one_id');\n    }\n\n    public function threes()\n    {\n        return $this->hasMany(Model3::class, 'one_id');\n    }\n}\n\nclass Model2 extends Model\n{\n    public $table = 'two';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function one()\n    {\n        return $this->belongsTo(Model1::class, 'one_id');\n    }\n}\n\nclass Model3 extends Model\n{\n    public $table = 'three';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function one()\n    {\n        return $this->belongsTo(Model1::class, 'one_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMassPrunableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Database\\Eloquent\\MassPrunable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\nuse LogicException;\nuse Mockery as m;\n\nclass EloquentMassPrunableTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->app->singleton(Dispatcher::class, function () {\n            return m::mock(Dispatcher::class);\n        });\n\n        $this->app->alias(Dispatcher::class, 'events');\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        collect([\n            'mass_prunable_test_models',\n            'mass_prunable_soft_delete_test_models',\n            'mass_prunable_test_model_missing_prunable_methods',\n        ])->each(function ($table) {\n            Schema::create($table, function (Blueprint $table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                $table->softDeletes();\n                $table->boolean('pruned')->default(false);\n                $table->timestamps();\n            });\n        });\n    }\n\n    public function testPrunableMethodMustBeImplemented()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage(\n            'Please implement',\n        );\n\n        MassPrunableTestModelMissingPrunableMethod::create()->pruneAll();\n    }\n\n    public function testPrunesRecords()\n    {\n        app('events')\n            ->shouldReceive('dispatch')\n            ->times(2)\n            ->with(m::type(ModelsPruned::class));\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['name' => 'foo'];\n        })->chunk(200)->each(function ($chunk) {\n            MassPrunableTestModel::insert($chunk->all());\n        });\n\n        $count = (new MassPrunableTestModel)->pruneAll();\n\n        $this->assertEquals(1500, $count);\n        $this->assertEquals(3500, MassPrunableTestModel::count());\n    }\n\n    public function testPrunesSoftDeletedRecords()\n    {\n        app('events')\n            ->shouldReceive('dispatch')\n            ->times(3)\n            ->with(m::type(ModelsPruned::class));\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['deleted_at' => Carbon::now()];\n        })->chunk(200)->each(function ($chunk) {\n            MassPrunableSoftDeleteTestModel::insert($chunk->all());\n        });\n\n        $count = (new MassPrunableSoftDeleteTestModel)->pruneAll();\n\n        $this->assertEquals(3000, $count);\n        $this->assertEquals(0, MassPrunableSoftDeleteTestModel::count());\n        $this->assertEquals(2000, MassPrunableSoftDeleteTestModel::withTrashed()->count());\n    }\n}\n\nclass MassPrunableTestModel extends Model\n{\n    use MassPrunable;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 1500);\n    }\n}\n\nclass MassPrunableSoftDeleteTestModel extends Model\n{\n    use MassPrunable, SoftDeletes;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 3000);\n    }\n}\n\nclass MassPrunableTestModelMissingPrunableMethod extends Model\n{\n    use MassPrunable;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelCustomEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelCustomEventsTest;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\ObservedBy;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelCustomEventsTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Event::listen(CustomEvent::class, function () {\n            $_SERVER['fired_event'] = true;\n        });\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('eloquent_model_stub_with_custom_event_from_traits', function (Blueprint $table) {\n            $table->boolean('custom_attribute');\n            $table->boolean('observer_attribute');\n        });\n    }\n\n    public function testFlushListenersClearsCustomEvents()\n    {\n        $_SERVER['fired_event'] = false;\n\n        TestModel1::flushEventListeners();\n\n        TestModel1::create();\n\n        $this->assertFalse($_SERVER['fired_event']);\n    }\n\n    public function testCustomEventListenersAreFired()\n    {\n        $_SERVER['fired_event'] = false;\n\n        TestModel1::create();\n\n        $this->assertTrue($_SERVER['fired_event']);\n    }\n\n    public function testAddObservableEventFromTrait()\n    {\n        $model = new EloquentModelStubWithCustomEventFromTrait();\n\n        $this->assertNull($model->custom_attribute);\n        $this->assertNull($model->observer_attribute);\n\n        $model->completeCustomAction();\n\n        $this->assertTrue($model->custom_attribute);\n        $this->assertTrue($model->observer_attribute);\n    }\n}\n\nclass TestModel1 extends Model\n{\n    public $dispatchesEvents = ['created' => CustomEvent::class];\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n}\n\nclass CustomEvent\n{\n    //\n}\n\ntrait CustomEventTrait\n{\n    public function completeCustomAction()\n    {\n        $this->custom_attribute = true;\n\n        $this->fireModelEvent('customEvent');\n    }\n\n    public function initializeCustomEventTrait()\n    {\n        $this->addObservableEvents([\n            'customEvent',\n        ]);\n    }\n}\n\nclass CustomObserver\n{\n    public function customEvent(EloquentModelStubWithCustomEventFromTrait $model)\n    {\n        $model->observer_attribute = true;\n    }\n}\n\n#[ObservedBy(CustomObserver::class)]\nclass EloquentModelStubWithCustomEventFromTrait extends Model\n{\n    use CustomEventTrait;\n\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelDateCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelDateCastingTest;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelDateCastingTest extends DatabaseTestCase\n{\n    /** {@inheritdoc} */\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->date('date_field')->nullable();\n            $table->datetime('datetime_field')->nullable();\n            $table->date('immutable_date_field')->nullable();\n            $table->datetime('immutable_datetime_field')->nullable();\n        });\n\n        Schema::create('test_model2', function (Blueprint $table) {\n            $table->increments('id');\n            $table->date('date_field')->nullable();\n            $table->datetime('datetime_field')->nullable();\n            $table->date('immutable_date_field')->nullable();\n            $table->datetime('immutable_datetime_field')->nullable();\n            $table->timestamp('created_at')->nullable();\n        });\n    }\n\n    public function testDatesAreCustomCastable()\n    {\n        $user = TestModel1::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n        ]);\n\n        $this->assertSame('2019-10', $user->toArray()['date_field']);\n        $this->assertSame('2019-10 10:15', $user->toArray()['datetime_field']);\n        $this->assertInstanceOf(Carbon::class, $user->date_field);\n        $this->assertInstanceOf(Carbon::class, $user->datetime_field);\n    }\n\n    public function testDatesFormattedAttributeBindings()\n    {\n        $bindings = [];\n\n        $this->app->make('db')->listen(static function ($query) use (&$bindings) {\n            $bindings = $query->bindings;\n        });\n\n        TestModel1::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n            'immutable_date_field' => '2019-10-01',\n            'immutable_datetime_field' => '2019-10-01 10:15',\n        ]);\n\n        $this->assertSame(['2019-10-01', '2019-10-01 10:15:20', '2019-10-01', '2019-10-01 10:15'], $bindings);\n    }\n\n    public function testDatesFormattedArrayAndJson()\n    {\n        $user = TestModel1::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n            'immutable_date_field' => '2019-10-01',\n            'immutable_datetime_field' => '2019-10-01 10:15',\n        ]);\n\n        $expected = [\n            'date_field' => '2019-10',\n            'datetime_field' => '2019-10 10:15',\n            'immutable_date_field' => '2019-10',\n            'immutable_datetime_field' => '2019-10 10:15',\n            'id' => 1,\n        ];\n\n        $this->assertSame($expected, $user->toArray());\n        $this->assertSame(json_encode($expected), $user->toJson());\n    }\n\n    public function testCustomDateCastsAreComparedAsDatesForCarbonInstances()\n    {\n        $user = TestModel1::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n            'immutable_date_field' => '2019-10-01',\n            'immutable_datetime_field' => '2019-10-01 10:15:20',\n        ]);\n\n        $user->date_field = new Carbon('2019-10-01');\n        $user->datetime_field = new Carbon('2019-10-01 10:15:20');\n        $user->immutable_date_field = new CarbonImmutable('2019-10-01');\n        $user->immutable_datetime_field = new CarbonImmutable('2019-10-01 10:15:20');\n\n        $this->assertArrayNotHasKey('date_field', $user->getDirty());\n        $this->assertArrayNotHasKey('datetime_field', $user->getDirty());\n        $this->assertArrayNotHasKey('immutable_date_field', $user->getDirty());\n        $this->assertArrayNotHasKey('immutable_datetime_field', $user->getDirty());\n    }\n\n    public function testCustomDateCastsAreComparedAsDatesForStringValues()\n    {\n        $user = TestModel1::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n            'immutable_date_field' => '2019-10-01',\n            'immutable_datetime_field' => '2019-10-01 10:15:20',\n        ]);\n\n        $user->date_field = '2019-10-01';\n        $user->datetime_field = '2019-10-01 10:15:20';\n        $user->immutable_date_field = '2019-10-01';\n        $user->immutable_datetime_field = '2019-10-01 10:15:20';\n\n        $this->assertArrayNotHasKey('date_field', $user->getDirty());\n        $this->assertArrayNotHasKey('datetime_field', $user->getDirty());\n        $this->assertArrayNotHasKey('immutable_date_field', $user->getDirty());\n        $this->assertArrayNotHasKey('immutable_datetime_field', $user->getDirty());\n    }\n\n    public function testDatesCanBeSerializedToArray()\n    {\n        $this->freezeSecond(function ($now) {\n            $user = TestModel2::create([\n                'date_field' => '2019-10-01',\n                'datetime_field' => '2019-10-01 10:15:20',\n                'immutable_date_field' => '2019-10-01',\n                'immutable_datetime_field' => '2019-10-01 10:15:20',\n            ]);\n\n            $this->assertSame(['created_at', null], $user->getDates());\n\n            $user->refresh();\n\n            $this->assertSame([\n                'id' => $user->getKey(),\n                'date_field' => '2019-10',\n                'datetime_field' => '2019-10 10:15',\n                'immutable_date_field' => '2019-10',\n                'immutable_datetime_field' => '2019-10 10:15',\n                'created_at' => $now->toISOString(),\n            ], $user->attributesToArray());\n        });\n    }\n}\n\nclass TestModel1 extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'date_field' => 'date:Y-m',\n        'datetime_field' => 'datetime:Y-m H:i',\n        'immutable_date_field' => 'date:Y-m',\n        'immutable_datetime_field' => 'datetime:Y-m H:i',\n    ];\n}\n\nclass TestModel2 extends Model\n{\n    public $table = 'test_model2';\n    const UPDATED_AT = null;\n    protected $guarded = [];\n\n    public $casts = [\n        'date_field' => 'date:Y-m',\n        'datetime_field' => 'datetime:Y-m H:i',\n        'immutable_date_field' => 'date:Y-m',\n        'immutable_datetime_field' => 'datetime:Y-m H:i',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelDecimalCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelDecimalCastingTest;\n\nuse Brick\\Math\\Exception\\NumberFormatException;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Exceptions\\MathException;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelDecimalCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->decimal('decimal_field_2', 8, 2)->nullable();\n            $table->decimal('decimal_field_4', 8, 4)->nullable();\n        });\n    }\n\n    public function testItHandlesExponent()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:20',\n            ];\n        };\n\n        $model->amount = 0.123456789e3;\n        $this->assertSame('123.45678900000000000000', $model->amount);\n\n        $model->amount = '0.123456789e3';\n        $this->assertSame('123.45678900000000000000', $model->amount);\n    }\n\n    public function testItHandlesIntegersWithUnderscores()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:2',\n            ];\n        };\n\n        $model->amount = 1_234.5;\n        $this->assertSame('1234.50', $model->amount);\n    }\n\n    public function testItWrapsThrownExceptions()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:20',\n            ];\n        };\n        $model->amount = 'foo';\n\n        try {\n            $model->amount;\n            $this->fail();\n        } catch (MathException $e) {\n            $this->assertSame('Unable to cast value to a decimal.', $e->getMessage());\n            $this->assertInstanceOf(NumberFormatException::class, $e->getPrevious());\n            $this->assertSame('The given value \"foo\" does not represent a valid number.', $e->getPrevious()->getMessage());\n        }\n    }\n\n    public function testItHandlesMissingIntegers()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:2',\n            ];\n        };\n\n        $model->amount = .8;\n        $this->assertSame('0.80', $model->amount);\n\n        $model->amount = '.8';\n        $this->assertSame('0.80', $model->amount);\n    }\n\n    public function testItHandlesLargeNumbers()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:20',\n            ];\n        };\n\n        $model->amount = '0.89898989898989898989';\n        $this->assertSame('0.89898989898989898989', $model->amount);\n\n        $model->amount = '89898989898989898989';\n        $this->assertSame('89898989898989898989.00000000000000000000', $model->amount);\n    }\n\n    public function testItRounds()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:2',\n            ];\n        };\n\n        $model->amount = '0.8989898989';\n        $this->assertSame('0.90', $model->amount);\n    }\n\n    public function testItTrimsLongValues()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:20',\n            ];\n        };\n\n        $model->amount = '0.89898989898989898989898989898989898989898989';\n        $this->assertSame('0.89898989898989898990', $model->amount);\n    }\n\n    public function testItDoesntRoundNumbers()\n    {\n        $model = new class extends Model\n        {\n            public $timestamps = false;\n\n            protected $casts = [\n                'amount' => 'decimal:1',\n            ];\n        };\n\n        $model->amount = '0.99';\n        $this->assertSame('1.0', $model->amount);\n    }\n\n    public function testDecimalsAreCastable()\n    {\n        $user = TestModel1::create([\n            'decimal_field_2' => '12',\n            'decimal_field_4' => '1234',\n        ]);\n\n        $this->assertSame('12.00', $user->toArray()['decimal_field_2']);\n        $this->assertSame('1234.0000', $user->toArray()['decimal_field_4']);\n\n        $user->decimal_field_2 = 12;\n        $user->decimal_field_4 = '1234';\n\n        $this->assertSame('12.00', $user->toArray()['decimal_field_2']);\n        $this->assertSame('1234.0000', $user->toArray()['decimal_field_4']);\n\n        $this->assertFalse($user->isDirty());\n\n        $user->decimal_field_4 = '1234.1234';\n        $this->assertTrue($user->isDirty());\n    }\n\n    public function testRoundingDirection()\n    {\n        $model = new class extends Model\n        {\n            protected $casts = [\n                'amount' => 'decimal:2',\n            ];\n        };\n\n        $model->amount = '0.999';\n        $this->assertSame('1.00', $model->amount);\n\n        $model->amount = '-0.999';\n        $this->assertSame('-1.00', $model->amount);\n\n        $model->amount = '0.554';\n        $this->assertSame('0.55', $model->amount);\n\n        $model->amount = '-0.554';\n        $this->assertSame('-0.55', $model->amount);\n\n        $model->amount = '0.555';\n        $this->assertSame('0.56', $model->amount);\n\n        $model->amount = '-0.555';\n        $this->assertSame('-0.56', $model->amount);\n\n        $model->amount = '0.005';\n        $this->assertSame('0.01', $model->amount);\n\n        $model->amount = '-0.005';\n        $this->assertSame('-0.01', $model->amount);\n\n        $model->amount = '0.8989898989';\n        $this->assertSame('0.90', $model->amount);\n\n        $model->amount = '-0.8989898989';\n        $this->assertSame('-0.90', $model->amount);\n    }\n}\n\nclass TestModel1 extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'decimal_field_2' => 'decimal:2',\n        'decimal_field_4' => 'decimal:4',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelEncryptedCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Database\\Eloquent\\Casts\\ArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Crypt;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Fluent;\nuse stdClass;\n\nclass EloquentModelEncryptedCastingTest extends DatabaseTestCase\n{\n    protected $encrypter;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->encrypter = $this->mock(Encrypter::class);\n        Crypt::swap($this->encrypter);\n\n        Model::$encrypter = null;\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('encrypted_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('secret', 1000)->nullable();\n            $table->text('secret_array')->nullable();\n            $table->text('secret_json')->nullable();\n            $table->text('secret_object')->nullable();\n            $table->text('secret_collection')->nullable();\n        });\n    }\n\n    public function testStringsAreCastable()\n    {\n        $this->encrypter->expects('encrypt')\n            ->with('this is a secret string', false)\n            ->andReturn('encrypted-secret-string');\n        $this->encrypter->expects('decrypt')\n            ->with('encrypted-secret-string', false)\n            ->andReturn('this is a secret string');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $subject */\n        $subject = EncryptedCast::create([\n            'secret' => 'this is a secret string',\n        ]);\n\n        $this->assertSame('this is a secret string', $subject->secret);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret' => 'encrypted-secret-string',\n        ]);\n    }\n\n    public function testArraysAreCastable()\n    {\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\"}', false)\n            ->andReturn('encrypted-secret-array-string');\n        $this->encrypter->expects('decrypt')\n            ->with('encrypted-secret-array-string', false)\n            ->andReturn('{\"key1\":\"value1\"}');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $subject */\n        $subject = EncryptedCast::create([\n            'secret_array' => ['key1' => 'value1'],\n        ]);\n\n        $this->assertSame(['key1' => 'value1'], $subject->secret_array);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_array' => 'encrypted-secret-array-string',\n        ]);\n    }\n\n    public function testJsonIsCastable()\n    {\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\"}', false)\n            ->andReturn('encrypted-secret-json-string');\n        $this->encrypter->expects('decrypt')\n            ->with('encrypted-secret-json-string', false)\n            ->andReturn('{\"key1\":\"value1\"}');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $subject */\n        $subject = EncryptedCast::create([\n            'secret_json' => ['key1' => 'value1'],\n        ]);\n\n        $this->assertSame(['key1' => 'value1'], $subject->secret_json);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_json' => 'encrypted-secret-json-string',\n        ]);\n    }\n\n    public function testJsonAttributeIsCastable()\n    {\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\"}', false)\n            ->andReturn('encrypted-secret-json-string');\n        $this->encrypter->expects('decrypt')\n            ->with('encrypted-secret-json-string', false)\n            ->andReturn('{\"key1\":\"value1\"}');\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\",\"key2\":\"value2\"}', false)\n            ->andReturn('encrypted-secret-json-string2');\n        $this->encrypter->expects('decrypt')\n            ->with('encrypted-secret-json-string2', false)\n            ->andReturn('{\"key1\":\"value1\",\"key2\":\"value2\"}');\n\n        $subject = new EncryptedCast([\n            'secret_json' => ['key1' => 'value1'],\n        ]);\n        $subject->fill([\n            'secret_json->key2' => 'value2',\n        ]);\n        $subject->save();\n\n        $this->assertSame(['key1' => 'value1', 'key2' => 'value2'], $subject->secret_json);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_json' => 'encrypted-secret-json-string2',\n        ]);\n    }\n\n    public function testObjectIsCastable()\n    {\n        $object = new stdClass;\n        $object->key1 = 'value1';\n\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\"}', false)\n            ->andReturn('encrypted-secret-object-string');\n        $this->encrypter->expects('decrypt')\n            ->twice()\n            ->with('encrypted-secret-object-string', false)\n            ->andReturn('{\"key1\":\"value1\"}');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $object */\n        $object = EncryptedCast::create([\n            'secret_object' => $object,\n        ]);\n\n        $this->assertInstanceOf(stdClass::class, $object->secret_object);\n        $this->assertSame('value1', $object->secret_object->key1);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $object->id,\n            'secret_object' => 'encrypted-secret-object-string',\n        ]);\n    }\n\n    public function testCollectionIsCastable()\n    {\n        $this->encrypter->expects('encrypt')\n            ->with('{\"key1\":\"value1\"}', false)\n            ->andReturn('encrypted-secret-collection-string');\n        $this->encrypter->expects('decrypt')\n            ->twice()\n            ->with('encrypted-secret-collection-string', false)\n            ->andReturn('{\"key1\":\"value1\"}');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $subject */\n        $subject = EncryptedCast::create([\n            'secret_collection' => new Collection(['key1' => 'value1']),\n        ]);\n\n        $this->assertInstanceOf(Collection::class, $subject->secret_collection);\n        $this->assertSame('value1', $subject->secret_collection->get('key1'));\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_collection' => 'encrypted-secret-collection-string',\n        ]);\n    }\n\n    public function testAsEncryptedCollection()\n    {\n        $this->encrypter->expects('encryptString')\n            ->twice()\n            ->with('{\"key1\":\"value1\"}')\n            ->andReturn('encrypted-secret-collection-string-1');\n        $this->encrypter->expects('encryptString')\n            ->times(9)\n            ->with('{\"key1\":\"value1\",\"key2\":\"value2\"}')\n            ->andReturn('encrypted-secret-collection-string-2');\n        $this->encrypter->expects('decryptString')\n            ->once()\n            ->with('encrypted-secret-collection-string-2')\n            ->andReturn('{\"key1\":\"value1\",\"key2\":\"value2\"}');\n\n        $subject = new EncryptedCast;\n\n        $subject->mergeCasts(['secret_collection' => AsEncryptedCollection::class]);\n\n        $subject->secret_collection = new Collection(['key1' => 'value1']);\n        $subject->secret_collection->put('key2', 'value2');\n\n        $subject->save();\n\n        $this->assertInstanceOf(Collection::class, $subject->secret_collection);\n        $this->assertSame('value1', $subject->secret_collection->get('key1'));\n        $this->assertSame('value2', $subject->secret_collection->get('key2'));\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_collection' => 'encrypted-secret-collection-string-2',\n        ]);\n\n        $subject = $subject->fresh();\n\n        $this->assertInstanceOf(Collection::class, $subject->secret_collection);\n        $this->assertSame('value1', $subject->secret_collection->get('key1'));\n        $this->assertSame('value2', $subject->secret_collection->get('key2'));\n\n        $subject->secret_collection = null;\n        $subject->save();\n\n        $this->assertNull($subject->secret_collection);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_collection' => null,\n        ]);\n\n        $this->assertNull($subject->fresh()->secret_collection);\n    }\n\n    public function testAsEncryptedCollectionMap()\n    {\n        $this->encrypter->expects('encryptString')\n            ->twice()\n            ->with('[{\"key1\":\"value1\"}]')\n            ->andReturn('encrypted-secret-collection-string-1');\n        $this->encrypter->expects('encryptString')\n            ->times(11)\n            ->with('[{\"key1\":\"value1\"},{\"key2\":\"value2\"}]')\n            ->andReturn('encrypted-secret-collection-string-2');\n        $this->encrypter->expects('decryptString')\n            ->once()\n            ->with('encrypted-secret-collection-string-2')\n            ->andReturn('[{\"key1\":\"value1\"},{\"key2\":\"value2\"}]');\n\n        $subject = new EncryptedCast;\n\n        $subject->mergeCasts(['secret_collection' => AsEncryptedCollection::of(Fluent::class)]);\n\n        $subject->secret_collection = new Collection([new Fluent(['key1' => 'value1'])]);\n        $subject->secret_collection->push(new Fluent(['key2' => 'value2']));\n\n        $subject->save();\n\n        $this->assertInstanceOf(Collection::class, $subject->secret_collection);\n        $this->assertInstanceOf(Fluent::class, $subject->secret_collection->first());\n        $this->assertSame('value1', $subject->secret_collection->get(0)->key1);\n        $this->assertSame('value2', $subject->secret_collection->get(1)->key2);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_collection' => 'encrypted-secret-collection-string-2',\n        ]);\n\n        $subject = $subject->fresh();\n\n        $this->assertInstanceOf(Collection::class, $subject->secret_collection);\n        $this->assertInstanceOf(Fluent::class, $subject->secret_collection->first());\n        $this->assertSame('value1', $subject->secret_collection->get(0)->key1);\n        $this->assertSame('value2', $subject->secret_collection->get(1)->key2);\n\n        $subject->secret_collection = null;\n        $subject->save();\n\n        $this->assertNull($subject->secret_collection);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_collection' => null,\n        ]);\n\n        $this->assertNull($subject->fresh()->secret_collection);\n    }\n\n    public function testAsEncryptedArrayObject()\n    {\n        $this->encrypter->expects('encryptString')\n            ->once()\n            ->with('{\"key1\":\"value1\"}')\n            ->andReturn('encrypted-secret-array-string-1');\n        $this->encrypter->expects('decryptString')\n            ->once()\n            ->with('encrypted-secret-array-string-1')\n            ->andReturn('{\"key1\":\"value1\"}');\n        $this->encrypter->expects('encryptString')\n            ->times(9)\n            ->with('{\"key1\":\"value1\",\"key2\":\"value2\"}')\n            ->andReturn('encrypted-secret-array-string-2');\n        $this->encrypter->expects('decryptString')\n            ->once()\n            ->with('encrypted-secret-array-string-2')\n            ->andReturn('{\"key1\":\"value1\",\"key2\":\"value2\"}');\n\n        $subject = new EncryptedCast;\n\n        $subject->mergeCasts(['secret_array' => AsEncryptedArrayObject::class]);\n\n        $subject->secret_array = ['key1' => 'value1'];\n        $subject->secret_array['key2'] = 'value2';\n\n        $subject->save();\n\n        $this->assertInstanceOf(ArrayObject::class, $subject->secret_array);\n        $this->assertSame('value1', $subject->secret_array['key1']);\n        $this->assertSame('value2', $subject->secret_array['key2']);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_array' => 'encrypted-secret-array-string-2',\n        ]);\n\n        $subject = $subject->fresh();\n\n        $this->assertInstanceOf(ArrayObject::class, $subject->secret_array);\n        $this->assertSame('value1', $subject->secret_array['key1']);\n        $this->assertSame('value2', $subject->secret_array['key2']);\n\n        $subject->secret_array = null;\n        $subject->save();\n\n        $this->assertNull($subject->secret_array);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret_array' => null,\n        ]);\n\n        $this->assertNull($subject->fresh()->secret_array);\n    }\n\n    public function testCustomEncrypterCanBeSpecified()\n    {\n        $customEncrypter = $this->mock(Encrypter::class);\n\n        $this->assertNull(Model::$encrypter);\n\n        Model::encryptUsing($customEncrypter);\n\n        $this->assertSame($customEncrypter, Model::$encrypter);\n\n        $this->encrypter->expects('encrypt')\n            ->never();\n        $this->encrypter->expects('decrypt')\n            ->never();\n        $customEncrypter->expects('encrypt')\n            ->with('this is a secret string', false)\n            ->andReturn('encrypted-secret-string');\n        $customEncrypter->expects('decrypt')\n            ->with('encrypted-secret-string', false)\n            ->andReturn('this is a secret string');\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EncryptedCast $subject */\n        $subject = EncryptedCast::create([\n            'secret' => 'this is a secret string',\n        ]);\n\n        $this->assertSame('this is a secret string', $subject->secret);\n        $this->assertDatabaseHas('encrypted_casts', [\n            'id' => $subject->id,\n            'secret' => 'encrypted-secret-string',\n        ]);\n    }\n}\n\n/**\n * @property $secret\n * @property $secret_array\n * @property $secret_json\n * @property $secret_object\n * @property $secret_collection\n */\nclass EncryptedCast extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'secret' => 'encrypted',\n        'secret_array' => 'encrypted:array',\n        'secret_json' => 'encrypted:json',\n        'secret_object' => 'encrypted:object',\n        'secret_collection' => 'encrypted:collection',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelEncryptedDirtyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEncryptedArrayObject;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EloquentModelEncryptedDirtyTest extends TestCase\n{\n    public function testDirtyAttributeBehaviorWithNoPreviousKeys()\n    {\n        config(['app.key' => str_repeat('a', 32)]);\n        Model::$encrypter = null;\n\n        $model = new EncryptedDirtyAttributeCast([\n            'secret' => 'some-secret',\n            'secret_array_object' => [1, 2, 3],\n        ]);\n\n        $model->syncOriginal();\n\n        $this->assertFalse($model->isDirty('secret'));\n        $this->assertFalse($model->isDirty('secret_array_object'));\n\n        $model->secret = 'some-secret';\n        $model->secret_array_object = [1, 2, 3];\n\n        // Encrypted attributes should always be considered dirty if updated in any way because of rotatable encryption keys...\n        $this->assertFalse($model->isDirty('secret'));\n        $this->assertFalse($model->isDirty('secret_array_object'));\n\n        $model->secret = 'some-other-secret';\n        $model->secret_array_object = [4, 5, 6];\n\n        // Encrypted attributes should always be considered dirty if updated in any way because of rotatable encryption keys...\n        $this->assertTrue($model->isDirty('secret'));\n        $this->assertTrue($model->isDirty('secret_array_object'));\n    }\n\n    public function testDirtyAttributeBehaviorWithPreviousKeys()\n    {\n        config(['app.key' => str_repeat('a', 32)]);\n        config(['app.previous_keys' => [str_repeat('b', 32)]]);\n        Model::$encrypter = null;\n\n        $model = new EncryptedDirtyAttributeCast([\n            'secret' => 'some-secret',\n            'secret_array_object' => [1, 2, 3],\n        ]);\n\n        $model->syncOriginal();\n\n        $this->assertFalse($model->isDirty('secret'));\n        $this->assertFalse($model->isDirty('secret_array_object'));\n\n        $model->secret = 'some-secret';\n        $model->secret_array_object = [1, 2, 3];\n\n        // Encrypted attributes should always be considered dirty if updated in any way because of rotatable encryption keys...\n        $this->assertTrue($model->isDirty('secret'));\n        $this->assertTrue($model->isDirty('secret_array_object'));\n\n        $model->secret = 'some-other-secret';\n        $model->secret_array_object = [4, 5, 6];\n\n        // Encrypted attributes should always be considered dirty if updated in any way because of rotatable encryption keys...\n        $this->assertTrue($model->isDirty('secret'));\n        $this->assertTrue($model->isDirty('secret_array_object'));\n    }\n}\n\n/**\n * @property $secret\n * @property $secret_array\n * @property $secret_json\n * @property $secret_object\n * @property $secret_collection\n */\nclass EncryptedDirtyAttributeCast extends Model\n{\n    protected $guarded = [];\n\n    public $casts = [\n        'secret' => 'encrypted',\n        'secret_array' => 'encrypted:array',\n        'secret_json' => 'encrypted:json',\n        'secret_object' => 'encrypted:object',\n        'secret_collection' => 'encrypted:collection',\n        'secret_array_object' => AsEncryptedArrayObject::class,\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelEnumCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumArrayObject;\nuse Illuminate\\Database\\Eloquent\\Casts\\AsEnumCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse ValueError;\n\ninclude_once 'Enums.php';\n\nclass EloquentModelEnumCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('enum_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('string_status', 100)->nullable();\n            $table->json('string_status_collection')->nullable();\n            $table->json('string_status_array')->nullable();\n            $table->integer('integer_status')->nullable();\n            $table->json('integer_status_collection')->nullable();\n            $table->json('integer_status_array')->nullable();\n            $table->string('arrayable_status')->nullable();\n        });\n\n        Schema::create('unique_enum_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('string_status', 100)->unique();\n        });\n    }\n\n    public function testEnumsAreCastable()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => 'pending',\n            'string_status_collection' => json_encode(['pending', 'done']),\n            'string_status_array' => json_encode(['pending', 'done']),\n            'integer_status' => 1,\n            'integer_status_collection' => json_encode([1, 2]),\n            'integer_status_array' => json_encode([1, 2]),\n            'arrayable_status' => 'pending',\n        ]);\n\n        $model = EloquentModelEnumCastingTestModel::first();\n\n        $this->assertEquals(StringStatus::pending, $model->string_status);\n        $this->assertEquals([StringStatus::pending, StringStatus::done], $model->string_status_collection->all());\n        $this->assertEquals([StringStatus::pending, StringStatus::done], $model->string_status_array->toArray());\n        $this->assertEquals(IntegerStatus::pending, $model->integer_status);\n        $this->assertEquals([IntegerStatus::pending, IntegerStatus::done], $model->integer_status_collection->all());\n        $this->assertEquals([IntegerStatus::pending, IntegerStatus::done], $model->integer_status_array->toArray());\n        $this->assertEquals(ArrayableStatus::pending, $model->arrayable_status);\n    }\n\n    public function testEnumsReturnNullWhenNull()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => null,\n            'string_status_collection' => null,\n            'string_status_array' => null,\n            'integer_status' => null,\n            'integer_status_collection' => null,\n            'integer_status_array' => null,\n            'arrayable_status' => null,\n        ]);\n\n        $model = EloquentModelEnumCastingTestModel::first();\n\n        $this->assertEquals(null, $model->string_status);\n        $this->assertEquals(null, $model->string_status_collection);\n        $this->assertEquals(null, $model->string_status_array);\n        $this->assertEquals(null, $model->integer_status);\n        $this->assertEquals(null, $model->integer_status_collection);\n        $this->assertEquals(null, $model->integer_status_array);\n        $this->assertEquals(null, $model->arrayable_status);\n    }\n\n    public function testEnumsAreCastableToArray()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => StringStatus::pending,\n            'string_status_collection' => [StringStatus::pending, StringStatus::done],\n            'string_status_array' => [StringStatus::pending, StringStatus::done],\n            'integer_status' => IntegerStatus::pending,\n            'integer_status_collection' => [IntegerStatus::pending, IntegerStatus::done],\n            'integer_status_array' => [IntegerStatus::pending, IntegerStatus::done],\n            'arrayable_status' => ArrayableStatus::pending,\n        ]);\n\n        $this->assertEquals([\n            'string_status' => 'pending',\n            'string_status_collection' => ['pending', 'done'],\n            'string_status_array' => ['pending', 'done'],\n            'integer_status' => 1,\n            'integer_status_collection' => [1, 2],\n            'integer_status_array' => [1, 2],\n            'arrayable_status' => [\n                'name' => 'pending',\n                'value' => 'pending',\n                'description' => 'pending status description',\n            ],\n        ], $model->toArray());\n    }\n\n    public function testEnumsAreCastableToArrayWhenNull()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => null,\n            'string_status_collection' => null,\n            'string_status_array' => null,\n            'integer_status' => null,\n            'integer_status_collection' => null,\n            'integer_status_array' => null,\n            'arrayable_status' => null,\n        ]);\n\n        $this->assertEquals([\n            'string_status' => null,\n            'string_status_collection' => null,\n            'string_status_array' => null,\n            'integer_status' => null,\n            'integer_status_collection' => null,\n            'integer_status_array' => null,\n            'arrayable_status' => null,\n        ], $model->toArray());\n    }\n\n    public function testEnumsAreConvertedOnSave()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => StringStatus::pending,\n            'string_status_collection' => [StringStatus::pending, StringStatus::done],\n            'string_status_array' => [StringStatus::pending, StringStatus::done],\n            'integer_status' => IntegerStatus::pending,\n            'integer_status_collection' => [IntegerStatus::pending, IntegerStatus::done],\n            'integer_status_array' => [IntegerStatus::pending, IntegerStatus::done],\n            'arrayable_status' => ArrayableStatus::pending,\n        ]);\n\n        $model->save();\n\n        $this->assertEquals([\n            'id' => $model->id,\n            'string_status' => 'pending',\n            'string_status_collection' => json_encode(['pending', 'done']),\n            'string_status_array' => json_encode(['pending', 'done']),\n            'integer_status' => 1,\n            'integer_status_collection' => json_encode([1, 2]),\n            'integer_status_array' => json_encode([1, 2]),\n            'arrayable_status' => 'pending',\n        ], collect(DB::table('enum_casts')->where('id', $model->id)->first())->map(function ($value) {\n            return str_replace(', ', ',', $value);\n        })->all());\n    }\n\n    public function testEnumsAreNotConvertedOnSaveWhenAlreadyCorrect()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => 'pending',\n            'string_status_collection' => ['pending', 'done'],\n            'string_status_array' => ['pending', 'done'],\n            'integer_status' => 1,\n            'integer_status_collection' => [1, 2],\n            'integer_status_array' => [1, 2],\n            'arrayable_status' => 'pending',\n        ]);\n\n        $model->save();\n\n        $this->assertEquals([\n            'id' => $model->id,\n            'string_status' => 'pending',\n            'string_status_collection' => json_encode(['pending', 'done']),\n            'string_status_array' => json_encode(['pending', 'done']),\n            'integer_status' => 1,\n            'integer_status_collection' => json_encode([1, 2]),\n            'integer_status_array' => json_encode([1, 2]),\n            'arrayable_status' => 'pending',\n        ], collect(DB::table('enum_casts')->where('id', $model->id)->first())->map(function ($value) {\n            return str_replace(', ', ',', $value);\n        })->all());\n    }\n\n    public function testEnumsAcceptNullOnSave()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => null,\n            'string_status_collection' => null,\n            'string_status_array' => null,\n            'integer_status' => null,\n            'integer_status_collection' => null,\n            'integer_status_array' => null,\n            'arrayable_status' => null,\n        ]);\n\n        $model->save();\n\n        $this->assertEquals((object) [\n            'id' => $model->id,\n            'string_status' => null,\n            'string_status_collection' => null,\n            'string_status_array' => null,\n            'integer_status' => null,\n            'integer_status_collection' => null,\n            'integer_status_array' => null,\n            'arrayable_status' => null,\n        ], DB::table('enum_casts')->where('id', $model->id)->first());\n    }\n\n    public function testEnumsAcceptBackedValueOnSave()\n    {\n        $model = new EloquentModelEnumCastingTestModel([\n            'string_status' => 'pending',\n            'integer_status' => 1,\n            'arrayable_status' => 'pending',\n        ]);\n\n        $model->save();\n\n        $model = EloquentModelEnumCastingTestModel::first();\n\n        $this->assertEquals(StringStatus::pending, $model->string_status);\n        $this->assertEquals(IntegerStatus::pending, $model->integer_status);\n        $this->assertEquals(ArrayableStatus::pending, $model->arrayable_status);\n    }\n\n    public function testFirstOrNew()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => 'pending',\n            'integer_status' => 1,\n            'arrayable_status' => 'pending',\n        ]);\n\n        $model = EloquentModelEnumCastingTestModel::firstOrNew([\n            'string_status' => StringStatus::pending,\n        ]);\n\n        $model2 = EloquentModelEnumCastingTestModel::firstOrNew([\n            'string_status' => StringStatus::done,\n        ]);\n\n        $this->assertTrue($model->exists);\n        $this->assertFalse($model2->exists);\n\n        $model2->save();\n\n        $this->assertEquals(StringStatus::done, $model2->string_status);\n    }\n\n    public function testFirstOrCreate()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => 'pending',\n            'integer_status' => 1,\n        ]);\n\n        $model = EloquentModelEnumCastingTestModel::firstOrCreate([\n            'string_status' => StringStatus::pending,\n        ]);\n\n        $model2 = EloquentModelEnumCastingTestModel::firstOrCreate([\n            'string_status' => StringStatus::done,\n        ]);\n\n        $this->assertEquals(StringStatus::pending, $model->string_status);\n        $this->assertEquals(StringStatus::done, $model2->string_status);\n    }\n\n    public function testAttributeCastToAnEnumCanNotBeSetToAnotherEnum(): void\n    {\n        $model = new EloquentModelEnumCastingTestModel;\n\n        $this->expectException(ValueError::class);\n        $this->expectExceptionMessage(\n            sprintf('Value [%s] is not of the expected enum type [%s].', var_export(ArrayableStatus::pending, true), StringStatus::class)\n        );\n\n        $model->string_status = ArrayableStatus::pending;\n    }\n\n    public function testAttributeCastToAnEnumCanNotBeSetToAValueNotDefinedOnTheEnum(): void\n    {\n        $model = new EloquentModelEnumCastingTestModel;\n\n        $this->expectException(ValueError::class);\n        $this->expectExceptionMessage(\n            sprintf('\"unexpected_value\" is not a valid backing value for enum %s', StringStatus::class)\n        );\n\n        $model->string_status = 'unexpected_value';\n    }\n\n    public function testAnAttributeWithoutACastCanBeSetToAnEnum(): void\n    {\n        $model = new EloquentModelEnumCastingTestModel;\n\n        $model->non_enum_status = StringStatus::pending;\n\n        $this->assertEquals(StringStatus::pending, $model->non_enum_status);\n    }\n\n    public function testCreateOrFirst()\n    {\n        $model1 = EloquentModelEnumCastingUniqueTestModel::createOrFirst([\n            'string_status' => StringStatus::pending,\n        ]);\n\n        $model2 = EloquentModelEnumCastingUniqueTestModel::createOrFirst([\n            'string_status' => StringStatus::pending,\n        ]);\n\n        $model3 = EloquentModelEnumCastingUniqueTestModel::createOrFirst([\n            'string_status' => StringStatus::done,\n        ]);\n\n        $this->assertEquals(StringStatus::pending, $model1->string_status);\n        $this->assertEquals(StringStatus::pending, $model2->string_status);\n        $this->assertTrue($model1->is($model2));\n        $this->assertEquals(StringStatus::done, $model3->string_status);\n    }\n}\n\nclass EloquentModelEnumCastingTestModel extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $table = 'enum_casts';\n\n    public $casts = [\n        'string_status' => StringStatus::class,\n        'string_status_collection' => AsEnumCollection::class.':'.StringStatus::class,\n        'string_status_array' => AsEnumArrayObject::class.':'.StringStatus::class,\n        'integer_status' => IntegerStatus::class,\n        'integer_status_collection' => AsEnumCollection::class.':'.IntegerStatus::class,\n        'integer_status_array' => AsEnumArrayObject::class.':'.IntegerStatus::class,\n        'arrayable_status' => ArrayableStatus::class,\n    ];\n}\n\nclass EloquentModelEnumCastingUniqueTestModel extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $table = 'unique_enum_casts';\n\n    public $casts = [\n        'string_status' => StringStatus::class,\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelHashedCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Schema;\nuse RuntimeException;\n\nclass EloquentModelHashedCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('hashed_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('password')->nullable();\n        });\n    }\n\n    public function testHashedWithBcrypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $subject = HashedCast::create([\n            'password' => 'password',\n        ]);\n\n        $this->assertTrue(password_verify('password', $subject->password));\n        $this->assertSame('2y', password_get_info($subject->password)['algo']);\n        $this->assertSame(13, password_get_info($subject->password)['options']['cost']);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => $subject->password,\n        ]);\n    }\n\n    public function testNotHashedIfAlreadyHashedWithBcrypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $subject = HashedCast::create([\n            // \"password\"; 13 rounds; bcrypt;\n            'password' => '$2y$13$Hdxlvi7OZqK3/fKVNypJs.vJqQcmOo3HnnT6w7fec9FRTRYxAhuCO',\n        ]);\n\n        $this->assertSame('$2y$13$Hdxlvi7OZqK3/fKVNypJs.vJqQcmOo3HnnT6w7fec9FRTRYxAhuCO', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$2y$13$Hdxlvi7OZqK3/fKVNypJs.vJqQcmOo3HnnT6w7fec9FRTRYxAhuCO',\n        ]);\n    }\n\n    public function testNotHashedIfNullWithBrcypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $subject = HashedCast::create([\n            'password' => null,\n        ]);\n\n        $this->assertNull($subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => null,\n        ]);\n    }\n\n    public function testPassingHashWithHigherCostThrowsExceptionWithBcrypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 10);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; 13 rounds; bcrypt;\n            'password' => '$2y$13$Hdxlvi7OZqK3/fKVNypJs.vJqQcmOo3HnnT6w7fec9FRTRYxAhuCO',\n        ]);\n    }\n\n    public function testPassingHashWithLowerCostDoesNotThrowExceptionWithBcrypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $subject = HashedCast::create([\n            // \"password\"; 7 rounds; bcrypt;\n            'password' => '$2y$07$Ivc2VnUOUFtfdbXFc/Ysu.PgiwAHkDmbZQNR1OpIjKCxTxEfWLP5y',\n        ]);\n\n        $this->assertSame('$2y$07$Ivc2VnUOUFtfdbXFc/Ysu.PgiwAHkDmbZQNR1OpIjKCxTxEfWLP5y', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$2y$07$Ivc2VnUOUFtfdbXFc/Ysu.PgiwAHkDmbZQNR1OpIjKCxTxEfWLP5y',\n        ]);\n    }\n\n    public function testPassingDifferentHashAlgorithmThrowsExceptionWithBcrypt()\n    {\n        Config::set('hashing.driver', 'bcrypt');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; argon2id;\n            'password' => '$argon2i$v=19$m=1024,t=2,p=2$OENON0I5bXo2WDQyQnM2bg$3ma8cKHITsmAjyIYKDLdSvtkMCiEz/s6qWnLAf+Ehek',\n        ]);\n    }\n\n    public function testHashedWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $subject = HashedCast::create([\n            'password' => 'password',\n        ]);\n\n        $this->assertTrue(password_verify('password', $subject->password));\n        $this->assertSame('argon2i', password_get_info($subject->password)['algo']);\n        $this->assertSame(1234, password_get_info($subject->password)['options']['memory_cost']);\n        $this->assertSame(2, password_get_info($subject->password)['options']['threads']);\n        $this->assertSame(7, password_get_info($subject->password)['options']['time_cost']);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => $subject->password,\n        ]);\n    }\n\n    public function testNotHashedIfAlreadyHashedWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $subject = HashedCast::create([\n            // \"password\"; 1234 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=1234,t=7,p=2$Lm9vSkJuU3M1SllaaTNwZA$5izrDfbWtpkSBH9EczQ8U1yjSOvAkhE4AuYrbBHwi5k',\n        ]);\n\n        $this->assertSame('$argon2i$v=19$m=1234,t=7,p=2$Lm9vSkJuU3M1SllaaTNwZA$5izrDfbWtpkSBH9EczQ8U1yjSOvAkhE4AuYrbBHwi5k', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$argon2i$v=19$m=1234,t=7,p=2$Lm9vSkJuU3M1SllaaTNwZA$5izrDfbWtpkSBH9EczQ8U1yjSOvAkhE4AuYrbBHwi5k',\n        ]);\n    }\n\n    public function testNotHashedIfNullWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $subject = HashedCast::create([\n            'password' => null,\n        ]);\n\n        $this->assertNull($subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => null,\n        ]);\n    }\n\n    public function testPassingHashWithHigherMemoryThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; 2345 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n    }\n\n    public function testPassingHashWithHigherTimeThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; 1234 memory; 2 threads; 8 time; argon2i;\n            'password' => '$argon2i$v=19$m=1234,t=8,p=2$LmszcGVHd0t6b3JweUxqTQ$sdY25X0Qe86fezr1cEjYQxAHI2SdN67yVs5x0ovffag',\n        ]);\n    }\n\n    public function testPassingHashWithHigherThreadsThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 1234);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; 1234 memory; 3 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=1234,t=7,p=3$OFludXF6bzFpRmdpSHdwSA$J1P4dCGJde6mYe2RZEOFWaztBbDWfxQAM09ZQRMjsw8',\n        ]);\n    }\n\n    public function testPassingHashWithLowerMemoryThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 3456);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $subject = HashedCast::create([\n            // \"password\"; 2345 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n\n        $this->assertSame('$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n    }\n\n    public function testPassingHashWithLowerTimeThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 2345);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 8);\n\n        $subject = HashedCast::create([\n            // \"password\"; 2345 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n\n        $this->assertSame('$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n    }\n\n    public function testPassingHashWithLowerThreadsThrowsExceptionWithArgon()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.argon.memory', 2345);\n        Config::set('hashing.argon.threads', 3);\n        Config::set('hashing.argon.time', 7);\n\n        $subject = HashedCast::create([\n            // \"password\"; 2345 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n\n        $this->assertSame('$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k', $subject->password);\n        $this->assertDatabaseHas('hashed_casts', [\n            'id' => $subject->id,\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n    }\n\n    public function testPassingDifferentHashAlgorithmThrowsExceptionWithArgonAndBcrypt()\n    {\n        Config::set('hashing.driver', 'argon');\n        Config::set('hashing.bcrypt.rounds', 13);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; bcrypt;\n            'password' => '$2y$13$Hdxlvi7OZqK3/fKVNypJs.vJqQcmOo3HnnT6w7fec9FRTRYxAhuCO',\n        ]);\n    }\n\n    public function testPassingDifferentHashAlgorithmThrowsExceptionWithArgon2idAndBcrypt()\n    {\n        Config::set('hashing.driver', 'argon2id');\n        Config::set('hashing.argon.memory', 2345);\n        Config::set('hashing.argon.threads', 2);\n        Config::set('hashing.argon.time', 7);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage(\"Could not verify the hashed value's configuration.\");\n\n        $subject = HashedCast::create([\n            // \"password\"; 2345 memory; 2 threads; 7 time; argon2i;\n            'password' => '$argon2i$v=19$m=2345,t=7,p=2$MWVVZnpiZHl5RkcveHovcA$QECQzuQ2aAKvUpD25cTUJaAyPFxlOIsCRu+5nbDsU3k',\n        ]);\n    }\n}\n\nclass HashedCast extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'password' => 'hashed',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelImmutableDateCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelDateCastingTest;\n\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelImmutableDateCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model_immutable', function (Blueprint $table) {\n            $table->increments('id');\n            $table->date('date_field')->nullable();\n            $table->datetime('datetime_field')->nullable();\n        });\n    }\n\n    public function testDatesAreImmutableCastable()\n    {\n        $model = TestModelImmutable::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n        ]);\n\n        $this->assertSame('2019-10-01T00:00:00.000000Z', $model->toArray()['date_field']);\n        $this->assertSame('2019-10-01T10:15:20.000000Z', $model->toArray()['datetime_field']);\n        $this->assertInstanceOf(CarbonImmutable::class, $model->date_field);\n        $this->assertInstanceOf(CarbonImmutable::class, $model->datetime_field);\n    }\n\n    public function testDatesAreImmutableAndCustomCastable()\n    {\n        $model = TestModelCustomImmutable::create([\n            'date_field' => '2019-10-01',\n            'datetime_field' => '2019-10-01 10:15:20',\n        ]);\n\n        $this->assertSame('2019-10', $model->toArray()['date_field']);\n        $this->assertSame('2019-10 10:15', $model->toArray()['datetime_field']);\n        $this->assertInstanceOf(CarbonImmutable::class, $model->date_field);\n        $this->assertInstanceOf(CarbonImmutable::class, $model->datetime_field);\n    }\n}\n\nclass TestModelImmutable extends Model\n{\n    public $table = 'test_model_immutable';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'date_field' => 'immutable_date',\n        'datetime_field' => 'immutable_datetime',\n    ];\n}\n\nclass TestModelCustomImmutable extends Model\n{\n    public $table = 'test_model_immutable';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'date_field' => 'immutable_date:Y-m',\n        'datetime_field' => 'immutable_datetime:Y-m H:i',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelJsonCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelJsonCastingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse stdClass;\n\nclass EloquentModelJsonCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('json_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->json('basic_string_as_json_field')->nullable();\n            $table->json('json_string_as_json_field')->nullable();\n            $table->json('array_as_json_field')->nullable();\n            $table->json('object_as_json_field')->nullable();\n            $table->json('collection_as_json_field')->nullable();\n        });\n    }\n\n    public function testStringsAreCastable()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EloquentModelJsonCastingTest\\JsonCast $object */\n        $object = JsonCast::create([\n            'basic_string_as_json_field' => 'this is a string',\n            'json_string_as_json_field' => '{\"key1\":\"value1\"}',\n        ]);\n\n        $this->assertSame('this is a string', $object->basic_string_as_json_field);\n        $this->assertSame('{\"key1\":\"value1\"}', $object->json_string_as_json_field);\n    }\n\n    public function testArraysAreCastable()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EloquentModelJsonCastingTest\\JsonCast $object */\n        $object = JsonCast::create([\n            'array_as_json_field' => ['key1' => 'value1'],\n        ]);\n\n        $this->assertEquals(['key1' => 'value1'], $object->array_as_json_field);\n    }\n\n    public function testObjectsAreCastable()\n    {\n        $object = new stdClass;\n        $object->key1 = 'value1';\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EloquentModelJsonCastingTest\\JsonCast $user */\n        $user = JsonCast::create([\n            'object_as_json_field' => $object,\n        ]);\n\n        $this->assertInstanceOf(stdClass::class, $user->object_as_json_field);\n        $this->assertSame('value1', $user->object_as_json_field->key1);\n    }\n\n    public function testCollectionsAreCastable()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\EloquentModelJsonCastingTest\\JsonCast $user */\n        $user = JsonCast::create([\n            'collection_as_json_field' => new Collection(['key1' => 'value1']),\n        ]);\n\n        $this->assertInstanceOf(Collection::class, $user->collection_as_json_field);\n        $this->assertSame('value1', $user->collection_as_json_field->get('key1'));\n    }\n}\n\n/**\n * @property $basic_string_as_json_field\n * @property $json_string_as_json_field\n * @property $array_as_json_field\n * @property $object_as_json_field\n * @property $collection_as_json_field\n */\nclass JsonCast extends Model\n{\n    public $table = 'json_casts';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public $casts = [\n        'basic_string_as_json_field' => 'json',\n        'json_string_as_json_field' => 'json',\n        'array_as_json_field' => 'array',\n        'object_as_json_field' => 'object',\n        'collection_as_json_field' => 'collection',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelLoadCountTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelLoadCountTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelLoadCountTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('base_models', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('related1s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n        });\n\n        Schema::create('related2s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n        });\n\n        Schema::create('deleted_related', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->softDeletes();\n        });\n\n        BaseModel::create();\n\n        Related1::create(['base_model_id' => 1]);\n        Related1::create(['base_model_id' => 1]);\n        Related2::create(['base_model_id' => 1]);\n        DeletedRelated::create(['base_model_id' => 1]);\n    }\n\n    public function testLoadCountSingleRelation()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadCount('related1');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(2, $model->related1_count);\n    }\n\n    public function testLoadCountMultipleRelations()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadCount(['related1', 'related2']);\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(2, $model->related1_count);\n        $this->assertEquals(1, $model->related2_count);\n    }\n\n    public function testLoadCountDeletedRelations()\n    {\n        $model = BaseModel::first();\n\n        $this->assertNull($model->deletedrelated_count);\n\n        $model->loadCount('deletedrelated');\n\n        $this->assertEquals(1, $model->deletedrelated_count);\n\n        DeletedRelated::first()->delete();\n\n        $model = BaseModel::first();\n\n        $this->assertNull($model->deletedrelated_count);\n\n        $model->loadCount('deletedrelated');\n\n        $this->assertEquals(0, $model->deletedrelated_count);\n    }\n}\n\nclass BaseModel extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function related1()\n    {\n        return $this->hasMany(Related1::class);\n    }\n\n    public function related2()\n    {\n        return $this->hasMany(Related2::class);\n    }\n\n    public function deletedrelated()\n    {\n        return $this->hasMany(DeletedRelated::class);\n    }\n}\n\nclass Related1 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n\nclass Related2 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n\nclass DeletedRelated extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelLoadMaxTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelLoadMaxTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelLoadMaxTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('base_models', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('related1s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        Schema::create('related2s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        BaseModel::create();\n\n        Related1::create(['base_model_id' => 1, 'number' => 10]);\n        Related1::create(['base_model_id' => 1, 'number' => 11]);\n        Related2::create(['base_model_id' => 1, 'number' => 12]);\n        Related2::create(['base_model_id' => 1, 'number' => 13]);\n    }\n\n    public function testLoadMaxSingleRelation()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadMax('related1', 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(11, $model->related1_max_number);\n    }\n\n    public function testLoadMaxMultipleRelations()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadMax(['related1', 'related2'], 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(11, $model->related1_max_number);\n        $this->assertEquals(13, $model->related2_max_number);\n    }\n}\n\nclass BaseModel extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function related1()\n    {\n        return $this->hasMany(Related1::class);\n    }\n\n    public function related2()\n    {\n        return $this->hasMany(Related2::class);\n    }\n}\n\nclass Related1 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n\nclass Related2 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelLoadMinTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelLoadMinTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelLoadMinTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('base_models', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('related1s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        Schema::create('related2s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        BaseModel::create();\n\n        Related1::create(['base_model_id' => 1, 'number' => 10]);\n        Related1::create(['base_model_id' => 1, 'number' => 11]);\n        Related2::create(['base_model_id' => 1, 'number' => 12]);\n        Related2::create(['base_model_id' => 1, 'number' => 13]);\n    }\n\n    public function testLoadMinSingleRelation()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadMin('related1', 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(10, $model->related1_min_number);\n    }\n\n    public function testLoadMinMultipleRelations()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadMin(['related1', 'related2'], 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(10, $model->related1_min_number);\n        $this->assertEquals(12, $model->related2_min_number);\n    }\n}\n\nclass BaseModel extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function related1()\n    {\n        return $this->hasMany(Related1::class);\n    }\n\n    public function related2()\n    {\n        return $this->hasMany(Related2::class);\n    }\n}\n\nclass Related1 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n\nclass Related2 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelLoadMissingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelLoadMissingTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelLoadMissingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        Schema::create('comment_mentions_users', function (Blueprint $table) {\n            $table->unsignedInteger('comment_id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('first_comment_id')->nullable();\n            $table->string('content')->nullable();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('parent_id')->nullable();\n            $table->unsignedInteger('post_id');\n            $table->string('content')->nullable();\n        });\n\n        Post::create();\n\n        Comment::create(['parent_id' => null, 'post_id' => 1, 'content' => 'Hello <u:1> <u:2>']);\n        Comment::create(['parent_id' => 1, 'post_id' => 1]);\n\n        User::create(['name' => 'Taylor']);\n        User::create(['name' => 'Otwell']);\n\n        Comment::first()->mentionsUsers()->attach([1, 2]);\n\n        Post::first()->update(['first_comment_id' => 1]);\n    }\n\n    public function testLoadMissing()\n    {\n        $post = Post::with('comments')->first();\n\n        DB::enableQueryLog();\n\n        $post->loadMissing('comments.parent');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertTrue($post->comments[0]->relationLoaded('parent'));\n    }\n\n    public function testLoadMissingNoUnnecessaryAttributeMutatorAccess()\n    {\n        $posts = Post::all();\n\n        DB::enableQueryLog();\n\n        $posts->loadMissing('firstComment.parent');\n\n        $this->assertCount(1, DB::getQueryLog());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class);\n    }\n\n    public function mentionsUsers()\n    {\n        return $this->belongsToMany(User::class, 'comment_mentions_users');\n    }\n\n    public function content(): Attribute\n    {\n        return new Attribute(function (?string $value) {\n            return preg_replace_callback('/<u:(\\d+)>/', function ($matches) {\n                return '@'.$this->mentionsUsers->find($matches[1])?->name;\n            }, $value);\n        });\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function firstComment()\n    {\n        return $this->belongsTo(Comment::class, 'first_comment_id');\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelLoadSumTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelLoadSumTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelLoadSumTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('base_models', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('related1s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        Schema::create('related2s', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('base_model_id');\n            $table->integer('number');\n        });\n\n        BaseModel::create();\n\n        Related1::create(['base_model_id' => 1, 'number' => 10]);\n        Related1::create(['base_model_id' => 1, 'number' => 11]);\n        Related2::create(['base_model_id' => 1, 'number' => 12]);\n    }\n\n    public function testLoadSumSingleRelation()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadSum('related1', 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(21, $model->related1_sum_number);\n    }\n\n    public function testLoadSumMultipleRelations()\n    {\n        $model = BaseModel::first();\n\n        DB::enableQueryLog();\n\n        $model->loadSum(['related1', 'related2'], 'number');\n\n        $this->assertCount(1, DB::getQueryLog());\n        $this->assertEquals(21, $model->related1_sum_number);\n        $this->assertEquals(12, $model->related2_sum_number);\n    }\n}\n\nclass BaseModel extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function related1()\n    {\n        return $this->hasMany(Related1::class);\n    }\n\n    public function related2()\n    {\n        return $this->hasMany(Related2::class);\n    }\n}\n\nclass Related1 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n\nclass Related2 extends Model\n{\n    public $timestamps = false;\n\n    protected $fillable = ['base_model_id', 'number'];\n\n    public function parent()\n    {\n        return $this->belongsTo(BaseModel::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelRefreshTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelRefreshTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Concerns\\AsPivot;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelRefreshTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n    }\n\n    public function testItRefreshesModelExcludedByGlobalScope()\n    {\n        $post = Post::create(['title' => 'mohamed']);\n\n        $post->refresh();\n    }\n\n    public function testItRefreshesASoftDeletedModel()\n    {\n        $post = Post::create(['title' => 'said']);\n\n        Post::find($post->id)->delete();\n\n        $this->assertFalse($post->trashed());\n\n        $post->refresh();\n\n        $this->assertTrue($post->trashed());\n    }\n\n    public function testItSyncsOriginalOnRefresh()\n    {\n        $post = Post::create(['title' => 'pat']);\n\n        Post::find($post->id)->update(['title' => 'patrick']);\n\n        $post->refresh();\n\n        $this->assertEmpty($post->getDirty());\n\n        $this->assertSame('patrick', $post->getOriginal('title'));\n    }\n\n    public function testItDoesNotSyncPreviousOnRefresh()\n    {\n        $post = Post::create(['title' => 'pat']);\n\n        Post::find($post->id)->update(['title' => 'patrick']);\n\n        $post->refresh();\n\n        $this->assertEmpty($post->getDirty());\n        $this->assertEmpty($post->getPrevious());\n    }\n\n    public function testAsPivot()\n    {\n        Schema::create('post_posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->bigInteger('foreign_id');\n            $table->bigInteger('related_id');\n        });\n\n        $post = AsPivotPost::create(['title' => 'parent']);\n        $child = AsPivotPost::create(['title' => 'child']);\n\n        $post->children()->attach($child->getKey());\n\n        $this->assertEquals(1, $post->children->count());\n\n        $post->children->first()->refresh();\n    }\n}\n\nclass Post extends Model\n{\n    public $table = 'posts';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    use SoftDeletes;\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('age', function ($query) {\n            $query->where('title', '!=', 'mohamed');\n        });\n    }\n}\n\nclass AsPivotPost extends Post\n{\n    public function children()\n    {\n        return $this\n            ->belongsToMany(static::class, (new AsPivotPostPivot)->getTable(), 'foreign_id', 'related_id')\n            ->using(AsPivotPostPivot::class);\n    }\n}\n\nclass AsPivotPostPivot extends Model\n{\n    use AsPivot;\n\n    protected $table = 'post_posts';\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelRelationAutoloadTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentModelRelationAutoloadTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentModelRelationAutoloadTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('tags', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name')->nullable();\n            $table->string('status')->nullable();\n            $table->unsignedInteger('post_id')->nullable();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('parent_id')->nullable();\n            $table->morphs('commentable');\n        });\n\n        Schema::create('likes', function (Blueprint $table) {\n            $table->increments('id');\n            $table->morphs('likeable');\n        });\n    }\n\n    public function testRelationAutoloadForCollection()\n    {\n        $post1 = Post::create();\n        $comment1 = $post1->comments()->create(['parent_id' => null]);\n        $comment2 = $post1->comments()->create(['parent_id' => $comment1->id]);\n        $comment2->likes()->create();\n        $comment2->likes()->create();\n\n        $post2 = Post::create();\n        $comment3 = $post2->comments()->create(['parent_id' => null]);\n        $comment3->likes()->create();\n\n        $posts = Post::get();\n\n        DB::enableQueryLog();\n\n        $likes = [];\n\n        $posts->withRelationshipAutoloading();\n\n        foreach ($posts as $post) {\n            foreach ($post->comments as $comment) {\n                $likes = array_merge($likes, $comment->likes->all());\n            }\n        }\n\n        $this->assertCount(2, DB::getQueryLog());\n        $this->assertCount(3, $likes);\n        $this->assertTrue($posts[0]->comments[0]->relationLoaded('likes'));\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadForSingleModel()\n    {\n        $post = Post::create();\n        $comment1 = $post->comments()->create(['parent_id' => null]);\n        $comment2 = $post->comments()->create(['parent_id' => $comment1->id]);\n        $comment2->likes()->create();\n        $comment2->likes()->create();\n\n        DB::enableQueryLog();\n\n        $likes = [];\n\n        $post->withRelationshipAutoloading();\n\n        foreach ($post->comments as $comment) {\n            $likes = array_merge($likes, $comment->likes->all());\n        }\n\n        $this->assertCount(2, DB::getQueryLog());\n        $this->assertCount(2, $likes);\n        $this->assertTrue($post->comments[0]->relationLoaded('likes'));\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadWithSerialization()\n    {\n        Model::automaticallyEagerLoadRelationships();\n\n        $post = Post::create();\n        $comment1 = $post->comments()->create(['parent_id' => null]);\n        $comment2 = $post->comments()->create(['parent_id' => $comment1->id]);\n        $comment2->likes()->create();\n\n        DB::enableQueryLog();\n\n        $likes = [];\n\n        $post = serialize($post);\n        $post = unserialize($post);\n\n        foreach ($post->comments as $comment) {\n            $likes = array_merge($likes, $comment->likes->all());\n        }\n\n        $this->assertCount(2, DB::getQueryLog());\n\n        Model::automaticallyEagerLoadRelationships(false);\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadWithCircularRelations()\n    {\n        $post = Post::create();\n        $comment1 = $post->comments()->create(['parent_id' => null]);\n        $comment2 = $post->comments()->create(['parent_id' => $comment1->id]);\n        $post->likes()->create();\n\n        DB::enableQueryLog();\n\n        $post->withRelationshipAutoloading();\n        $comment = $post->comments->first();\n        $comment->setRelation('post', $post);\n\n        $this->assertCount(1, $post->likes);\n\n        $this->assertCount(2, DB::getQueryLog());\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadWithChaperoneRelations()\n    {\n        Model::automaticallyEagerLoadRelationships();\n\n        $post = Post::create();\n        $comment1 = $post->comments()->create(['parent_id' => null]);\n        $comment2 = $post->comments()->create(['parent_id' => $comment1->id]);\n        $post->likes()->create();\n\n        DB::enableQueryLog();\n\n        $post->load('commentsWithChaperone');\n\n        $this->assertCount(1, $post->likes);\n\n        $this->assertCount(2, DB::getQueryLog());\n\n        Model::automaticallyEagerLoadRelationships(false);\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadVariousNestedMorphRelations()\n    {\n        tap(Post::create(), function ($post) {\n            $post->likes()->create();\n            $post->comments()->create();\n            tap($post->comments()->create(), function ($comment) {\n                $comment->likes()->create();\n                $comment->likes()->create();\n            });\n        });\n\n        tap(Post::create(), function ($post) {\n            $post->likes()->create();\n            tap($post->comments()->create(), function ($comment) {\n                $comment->likes()->create();\n            });\n        });\n\n        tap(Video::create(), function ($video) {\n            tap($video->comments()->create(), function ($comment) {\n                $comment->likes()->create();\n            });\n        });\n\n        tap(Video::create(), function ($video) {\n            tap($video->comments()->create(), function ($comment) {\n                $comment->likes()->create();\n            });\n        });\n\n        $likes = Like::get();\n\n        DB::enableQueryLog();\n\n        $videos = [];\n        $videoLike = null;\n\n        $likes->withRelationshipAutoloading();\n\n        foreach ($likes as $like) {\n            $likeable = $like->likeable;\n\n            if (($likeable instanceof Comment) && ($likeable->commentable instanceof Video)) {\n                $videos[] = $likeable->commentable;\n                $videoLike = $like;\n            }\n        }\n\n        $this->assertCount(4, DB::getQueryLog());\n        $this->assertCount(2, $videos);\n        $this->assertTrue($videoLike->relationLoaded('likeable'));\n        $this->assertTrue($videoLike->likeable->relationLoaded('commentable'));\n\n        DB::disableQueryLog();\n    }\n\n    public function testRelationAutoloadWorksOnFactoryMake()\n    {\n        Model::automaticallyEagerLoadRelationships();\n\n        DB::enableQueryLog();\n\n        $tags = Tag::factory()->times(3)->make();\n\n        $post = Post::create();\n\n        $post->tags()->saveMany($tags);\n\n        $this->assertCount(7, DB::getQueryLog());\n\n        Model::automaticallyEagerLoadRelationships(false);\n\n        DB::disableQueryLog();\n    }\n}\n\nclass TagFactory extends Factory\n{\n    protected $model = Tag::class;\n\n    public function definition()\n    {\n        return [];\n    }\n}\n\nclass Tag extends Model\n{\n    use HasFactory;\n\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    protected static function booted()\n    {\n        static::creating(function ($model) {\n            if ($model->post->shouldApplyStatus()) {\n                $model->status = 'Todo';\n            }\n        });\n    }\n\n    protected static function newFactory()\n    {\n        return TagFactory::new();\n    }\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(self::class);\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(Like::class, 'likeable');\n    }\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    public function shouldApplyStatus()\n    {\n        return false;\n    }\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n\n    public function commentsWithChaperone()\n    {\n        return $this->morphMany(Comment::class, 'commentable')->chaperone();\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(Like::class, 'likeable');\n    }\n\n    public function tags()\n    {\n        return $this->hasMany(Tag::class);\n    }\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n\n    public function likes()\n    {\n        return $this->morphMany(Like::class, 'likeable');\n    }\n}\n\nclass Like extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function likeable()\n    {\n        return $this->morphTo();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelScopeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass EloquentModelScopeTest extends DatabaseTestCase\n{\n    public function testModelHasScope()\n    {\n        $model = new TestScopeModel1;\n\n        $this->assertTrue($model->hasNamedScope('exists'));\n    }\n\n    public function testModelDoesNotHaveScope()\n    {\n        $model = new TestScopeModel1;\n\n        $this->assertFalse($model->hasNamedScope('doesNotExist'));\n    }\n\n    public function testModelHasAttributedScope()\n    {\n        $model = new TestScopeModel1;\n\n        $this->assertTrue($model->hasNamedScope('existsAsWell'));\n    }\n}\n\nclass TestScopeModel1 extends Model\n{\n    public function scopeExists(Builder $builder)\n    {\n        return $builder;\n    }\n\n    #[Scope]\n    protected function existsAsWell(Builder $builder)\n    {\n        return $builder;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelStringCastingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse stdClass;\n\nclass EloquentModelStringCastingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('casting_table', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('array_attributes');\n            $table->string('json_attributes');\n            $table->string('object_attributes');\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Tests...\n     */\n    public function testSavingCastedAttributesToDatabase()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\StringCasts $model */\n        $model = StringCasts::create([\n            'array_attributes' => ['key1' => 'value1'],\n            'json_attributes' => ['json_key' => 'json_value'],\n            'object_attributes' => ['json_key' => 'json_value'],\n        ]);\n        $this->assertSame(['key1' => 'value1'], $model->getOriginal('array_attributes'));\n        $this->assertSame(['key1' => 'value1'], $model->getAttribute('array_attributes'));\n\n        $this->assertSame(['json_key' => 'json_value'], $model->getOriginal('json_attributes'));\n        $this->assertSame(['json_key' => 'json_value'], $model->getAttribute('json_attributes'));\n\n        $stdClass = new stdClass;\n        $stdClass->json_key = 'json_value';\n        $this->assertEquals($stdClass, $model->getOriginal('object_attributes'));\n        $this->assertEquals($stdClass, $model->getAttribute('object_attributes'));\n    }\n\n    public function testSavingCastedEmptyAttributesToDatabase()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\StringCasts $model */\n        $model = StringCasts::create([\n            'array_attributes' => [],\n            'json_attributes' => [],\n            'object_attributes' => [],\n        ]);\n        $this->assertSame([], $model->getOriginal('array_attributes'));\n        $this->assertSame([], $model->getAttribute('array_attributes'));\n\n        $this->assertSame([], $model->getOriginal('json_attributes'));\n        $this->assertSame([], $model->getAttribute('json_attributes'));\n\n        $this->assertSame([], $model->getOriginal('object_attributes'));\n        $this->assertSame([], $model->getAttribute('object_attributes'));\n    }\n}\n\n/**\n * Eloquent Models...\n */\nclass StringCasts extends Eloquent\n{\n    /**\n     * @var string\n     */\n    protected $table = 'casting_table';\n\n    /**\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * @var array\n     */\n    protected $casts = [\n        'array_attributes' => 'array',\n        'json_attributes' => 'json',\n        'object_attributes' => 'object',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass EloquentModelTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamp('nullable_date')->nullable();\n        });\n\n        Schema::create('test_model2', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('title');\n        });\n    }\n\n    public function testUserCanUpdateNullableDate()\n    {\n        $user = TestModel1::create([\n            'nullable_date' => null,\n        ]);\n\n        $user->fill([\n            'nullable_date' => $now = Carbon::now(),\n        ]);\n        $this->assertTrue($user->isDirty('nullable_date'));\n\n        $user->save();\n        $this->assertEquals($now->toDateString(), $user->nullable_date->toDateString());\n    }\n\n    public function testAttributeChanges()\n    {\n        $user = TestModel2::create([\n            'name' => $originalName = Str::random(), 'title' => Str::random(),\n        ]);\n\n        $this->assertEmpty($user->getDirty());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n        $this->assertFalse($user->isDirty());\n        $this->assertFalse($user->wasChanged());\n\n        $user->name = $overrideName = Str::random();\n\n        $this->assertEquals(['name' => $overrideName], $user->getDirty());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n        $this->assertTrue($user->isDirty());\n        $this->assertFalse($user->wasChanged());\n\n        $user->save();\n\n        $this->assertEmpty($user->getDirty());\n        $this->assertEquals(['name' => $overrideName], $user->getChanges());\n        $this->assertEquals(['name' => $originalName], $user->getPrevious());\n        $this->assertTrue($user->wasChanged());\n        $this->assertTrue($user->wasChanged('name'));\n    }\n\n    public function testDiscardChanges()\n    {\n        $user = TestModel2::create([\n            'name' => $originalName = Str::random(), 'title' => Str::random(),\n        ]);\n\n        $this->assertEmpty($user->getDirty());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n        $this->assertFalse($user->isDirty());\n        $this->assertFalse($user->wasChanged());\n\n        $user->name = $overrideName = Str::random();\n\n        $this->assertEquals(['name' => $overrideName], $user->getDirty());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n        $this->assertTrue($user->isDirty());\n        $this->assertFalse($user->wasChanged());\n        $this->assertSame($originalName, $user->getOriginal('name'));\n        $this->assertSame($overrideName, $user->getAttribute('name'));\n\n        $user->discardChanges();\n\n        $this->assertEmpty($user->getDirty());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n        $this->assertSame($originalName, $user->getOriginal('name'));\n        $this->assertSame($originalName, $user->getAttribute('name'));\n\n        $user->save();\n        $this->assertFalse($user->wasChanged());\n        $this->assertEmpty($user->getChanges());\n        $this->assertEmpty($user->getPrevious());\n    }\n\n    public function testInsertRecordWithReservedWordFieldName()\n    {\n        Schema::create('actions', function (Blueprint $table) {\n            $table->id();\n            $table->string('label');\n            $table->timestamp('start');\n            $table->timestamp('end')->nullable();\n            $table->boolean('analyze');\n        });\n\n        $model = new class extends Model\n        {\n            protected $table = 'actions';\n            protected $guarded = ['id'];\n            public $timestamps = false;\n        };\n\n        $model->newInstance()->create([\n            'label' => 'test',\n            'start' => '2023-01-01 00:00:00',\n            'end' => '2024-01-01 00:00:00',\n            'analyze' => true,\n        ]);\n\n        $this->assertDatabaseHas('actions', [\n            'label' => 'test',\n            'start' => '2023-01-01 00:00:00',\n            'end' => '2024-01-01 00:00:00',\n            'analyze' => true,\n        ]);\n    }\n}\n\nclass TestModel1 extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $casts = ['nullable_date' => 'datetime'];\n}\n\nclass TestModel2 extends Model\n{\n    public $table = 'test_model2';\n    public $timestamps = false;\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentModelWithoutEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentModelWithoutEventsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('auto_filled_models', function (Blueprint $table) {\n            $table->increments('id');\n            $table->text('project')->nullable();\n        });\n    }\n\n    public function testWithoutEventsRegistersBootedListenersForLater()\n    {\n        $model = AutoFilledModel::withoutEvents(function () {\n            return AutoFilledModel::create();\n        });\n\n        $this->assertNull($model->project);\n\n        $model->save();\n\n        $this->assertSame('Laravel', $model->project);\n    }\n}\n\nclass AutoFilledModel extends Model\n{\n    public $table = 'auto_filled_models';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::saving(function ($model) {\n            $model->project = 'Laravel';\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphConstrainTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphConstrainTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphConstrainTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->boolean('post_visible');\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('id');\n            $table->boolean('video_visible');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post1 = Post::create(['post_visible' => true]);\n        (new Comment)->commentable()->associate($post1)->save();\n\n        $post2 = Post::create(['post_visible' => false]);\n        (new Comment)->commentable()->associate($post2)->save();\n\n        $video1 = Video::create(['video_visible' => true]);\n        (new Comment)->commentable()->associate($video1)->save();\n\n        $video2 = Video::create(['video_visible' => false]);\n        (new Comment)->commentable()->associate($video2)->save();\n    }\n\n    public function testMorphConstraints()\n    {\n        $comments = Comment::query()\n            ->with(['commentable' => function (MorphTo $morphTo) {\n                $morphTo->constrain([\n                    Post::class => function ($query) {\n                        $query->where('post_visible', true);\n                    },\n                    Video::class => function ($query) {\n                        $query->where('video_visible', true);\n                    },\n                ]);\n            }])\n            ->get();\n\n        $this->assertTrue($comments[0]->commentable->post_visible);\n        $this->assertNull($comments[1]->commentable);\n        $this->assertTrue($comments[2]->commentable->video_visible);\n        $this->assertNull($comments[3]->commentable);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n    protected $fillable = ['post_visible'];\n    protected $casts = ['post_visible' => 'boolean'];\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n    protected $fillable = ['video_visible'];\n    protected $casts = ['video_visible' => 'boolean'];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphCountEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphCountEagerLoadingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphCountEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('likes', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('views', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('video_id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post = Post::create();\n        $video = Video::create();\n\n        tap((new Like)->post()->associate($post))->save();\n        tap((new Like)->post()->associate($post))->save();\n\n        tap((new View)->video()->associate($video))->save();\n\n        (new Comment)->commentable()->associate($post)->save();\n        (new Comment)->commentable()->associate($video)->save();\n    }\n\n    public function testWithMorphCountLoading()\n    {\n        $comments = Comment::query()\n            ->with(['commentable' => function (MorphTo $morphTo) {\n                $morphTo->morphWithCount([Post::class => ['likes']]);\n            }])\n            ->get();\n\n        $this->assertTrue($comments[0]->relationLoaded('commentable'));\n        $this->assertEquals(2, $comments[0]->commentable->likes_count);\n        $this->assertTrue($comments[1]->relationLoaded('commentable'));\n        $this->assertNull($comments[1]->commentable->views_count);\n    }\n\n    public function testWithMorphCountLoadingWithSingleRelation()\n    {\n        $comments = Comment::query()\n            ->with(['commentable' => function (MorphTo $morphTo) {\n                $morphTo->morphWithCount([Post::class => 'likes']);\n            }])\n            ->get();\n\n        $this->assertTrue($comments[0]->relationLoaded('commentable'));\n        $this->assertEquals(2, $comments[0]->commentable->likes_count);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    public function likes()\n    {\n        return $this->hasMany(Like::class);\n    }\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n\n    public function views()\n    {\n        return $this->hasMany(View::class);\n    }\n}\n\nclass Like extends Model\n{\n    public $timestamps = false;\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n}\n\nclass View extends Model\n{\n    public $timestamps = false;\n\n    public function video()\n    {\n        return $this->belongsTo(Video::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphCountLazyEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphCountLazyEagerLoadingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphCountLazyEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('likes', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post = Post::create();\n\n        tap((new Like)->post()->associate($post))->save();\n        tap((new Like)->post()->associate($post))->save();\n\n        (new Comment)->commentable()->associate($post)->save();\n    }\n\n    public function testLazyEagerLoading()\n    {\n        $comment = Comment::first();\n\n        $comment->loadMorphCount('commentable', [\n            Post::class => ['likes'],\n        ]);\n\n        $this->assertTrue($comment->relationLoaded('commentable'));\n        $this->assertEquals(2, $comment->commentable->likes_count);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    public function likes()\n    {\n        return $this->hasMany(Like::class);\n    }\n}\n\nclass Like extends Model\n{\n    public $timestamps = false;\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphEagerLoadingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphTo;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->softDeletes();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('post_id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('video_id');\n        });\n\n        Schema::create('actions', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('target_type');\n            $table->integer('target_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $user = User::create();\n        $user2 = User::forceCreate(['deleted_at' => Carbon::now()]);\n\n        $post = tap((new Post)->user()->associate($user))->save();\n\n        $video = Video::create();\n\n        (new Comment)->commentable()->associate($post)->save();\n        (new Comment)->commentable()->associate($video)->save();\n\n        (new Action)->target()->associate($video)->save();\n        (new Action)->target()->associate($user2)->save();\n    }\n\n    public function testWithMorphLoading()\n    {\n        $comments = Comment::query()\n            ->with(['commentable' => function (MorphTo $morphTo) {\n                $morphTo->morphWith([Post::class => ['user']]);\n            }])\n            ->get();\n\n        $this->assertCount(2, $comments);\n\n        $this->assertTrue($comments[0]->relationLoaded('commentable'));\n        $this->assertInstanceOf(Post::class, $comments[0]->getRelation('commentable'));\n        $this->assertTrue($comments[0]->commentable->relationLoaded('user'));\n        $this->assertTrue($comments[1]->relationLoaded('commentable'));\n        $this->assertInstanceOf(Video::class, $comments[1]->getRelation('commentable'));\n    }\n\n    public function testWithMorphLoadingWithSingleRelation()\n    {\n        $comments = Comment::query()\n            ->with(['commentable' => function (MorphTo $morphTo) {\n                $morphTo->morphWith([Post::class => 'user']);\n            }])\n            ->get();\n\n        $this->assertTrue($comments[0]->relationLoaded('commentable'));\n        $this->assertTrue($comments[0]->commentable->relationLoaded('user'));\n    }\n\n    public function testMorphLoadingMixedWithTrashedRelations()\n    {\n        $action = Action::query()\n            ->with('target')\n            ->get();\n\n        $this->assertCount(2, $action);\n\n        $this->assertTrue($action[0]->relationLoaded('target'));\n        $this->assertInstanceOf(Video::class, $action[0]->getRelation('target'));\n        $this->assertTrue($action[1]->relationLoaded('target'));\n        $this->assertInstanceOf(User::class, $action[1]->getRelation('target'));\n    }\n\n    public function testMorphWithTrashedRelationLazyLoading()\n    {\n        $deletedUser = User::forceCreate(['deleted_at' => Carbon::now()]);\n\n        $action = new Action;\n        $action->target()->associate($deletedUser)->save();\n\n        // model is already set via associate and not retrieved from the database\n        $this->assertInstanceOf(User::class, $action->target);\n\n        $action->unsetRelation('target');\n\n        $this->assertInstanceOf(User::class, $action->target);\n    }\n}\n\nclass Action extends Model\n{\n    public $timestamps = false;\n\n    public function target()\n    {\n        return $this->morphTo()->withTrashed();\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n    protected $primaryKey = 'post_id';\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n\nclass User extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n    protected $primaryKey = 'video_id';\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphLazyEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphLazyEagerLoadingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphLazyEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('post_id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $user = User::create();\n\n        $post = tap((new Post)->user()->associate($user))->save();\n\n        (new Comment)->commentable()->associate($post)->save();\n    }\n\n    public function testLazyEagerLoading()\n    {\n        $comment = Comment::first();\n\n        $comment->loadMorph('commentable', [\n            Post::class => ['user'],\n        ]);\n\n        $this->assertTrue($comment->relationLoaded('commentable'));\n        $this->assertTrue($comment->commentable->relationLoaded('user'));\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n    protected $primaryKey = 'post_id';\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphManyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphManyTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphOne;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphManyTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->integer('commentable_id');\n            $table->string('commentable_type');\n            $table->timestamps();\n        });\n    }\n\n    public function testUpdateModelWithDefaultWithCount()\n    {\n        $post = Post::create(['title' => Str::random()]);\n\n        $post->update(['title' => 'new name']);\n\n        $this->assertSame('new name', $post->title);\n    }\n\n    public function test_self_referencing_existence_query()\n    {\n        $post = Post::create(['title' => 'foo']);\n\n        $comment = tap((new Comment(['name' => 'foo']))->commentable()->associate($post))->save();\n\n        (new Comment(['name' => 'bar']))->commentable()->associate($comment)->save();\n\n        $comments = Comment::has('replies')->get();\n\n        $this->assertEquals([1], $comments->pluck('id')->all());\n    }\n\n    public function testCanMorphOne()\n    {\n        $post = Post::create(['title' => 'Your favorite book by C.S. Lewis']);\n\n        Carbon::setTestNow('1990-02-02 12:00:00');\n        $oldestComment = tap((new Comment(['name' => 'The Allegory Of Love']))->commentable()->associate($post))->save();\n\n        Carbon::setTestNow('2000-07-02 09:00:00');\n        tap((new Comment(['name' => 'The Screwtape Letters']))->commentable()->associate($post))->save();\n\n        Carbon::setTestNow('2022-01-01 00:00:00');\n        $latestComment = tap((new Comment(['name' => 'The Silver Chair']))->commentable()->associate($post))->save();\n\n        $this->assertInstanceOf(MorphOne::class, $post->comments()->one());\n\n        $this->assertEquals($latestComment->id, $post->latestComment->id);\n        $this->assertEquals($oldestComment->id, $post->oldestComment->id);\n    }\n}\n\nclass Post extends Model\n{\n    public $table = 'posts';\n    public $timestamps = true;\n    protected $guarded = [];\n    protected $withCount = ['comments'];\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n\n    public function latestComment(): MorphOne\n    {\n        return $this->comments()->one()->latestOfMany();\n    }\n\n    public function oldestComment(): MorphOne\n    {\n        return $this->comments()->one()->oldestOfMany();\n    }\n}\n\nclass Comment extends Model\n{\n    public $table = 'comments';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n\n    public function replies()\n    {\n        return $this->morphMany(self::class, 'commentable');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphOneIsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphOneIsTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphOneIsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        Schema::create('attachments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('attachable_type')->nullable();\n            $table->integer('attachable_id')->nullable();\n        });\n\n        $post = Post::create();\n        $post->attachment()->create();\n    }\n\n    public function testChildIsNotNull()\n    {\n        $parent = Post::first();\n        $child = null;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsModel()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n\n        $this->assertTrue($parent->attachment()->is($child));\n        $this->assertFalse($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotAnotherModel()\n    {\n        $parent = Post::first();\n        $child = new Attachment;\n        $child->id = 2;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testNullChildIsNotModel()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->attachable_type = null;\n        $child->attachable_id = null;\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotModelWithAnotherTable()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->setTable('foo');\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n\n    public function testChildIsNotModelWithAnotherConnection()\n    {\n        $parent = Post::first();\n        $child = Attachment::first();\n        $child->setConnection('foo');\n\n        $this->assertFalse($parent->attachment()->is($child));\n        $this->assertTrue($parent->attachment()->isNot($child));\n    }\n}\n\nclass Attachment extends Model\n{\n    public $timestamps = false;\n}\n\nclass Post extends Model\n{\n    public function attachment()\n    {\n        return $this->morphOne(Attachment::class, 'attachable');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphToGlobalScopesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphToGlobalScopesTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Eloquent\\SoftDeletingScope;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphToGlobalScopesTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->softDeletes();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post = Post::create();\n        (new Comment)->commentable()->associate($post)->save();\n\n        $post = tap(Post::create())->delete();\n        (new Comment)->commentable()->associate($post)->save();\n    }\n\n    public function testWithGlobalScopes()\n    {\n        $comments = Comment::with('commentable')->get();\n\n        $this->assertNotNull($comments[0]->commentable);\n        $this->assertNull($comments[1]->commentable);\n    }\n\n    public function testWithoutGlobalScope()\n    {\n        $comments = Comment::with(['commentable' => function ($query) {\n            $query->withoutGlobalScopes([SoftDeletingScope::class]);\n        }])->get();\n\n        $this->assertNotNull($comments[0]->commentable);\n        $this->assertNotNull($comments[1]->commentable);\n    }\n\n    public function testWithoutGlobalScopes()\n    {\n        $comments = Comment::with(['commentable' => function ($query) {\n            $query->withoutGlobalScopes();\n        }])->get();\n\n        $this->assertNotNull($comments[0]->commentable);\n        $this->assertNotNull($comments[1]->commentable);\n    }\n\n    public function testLazyLoading()\n    {\n        $comment = Comment::latest('id')->first();\n        $post = $comment->commentable()->withoutGlobalScopes()->first();\n\n        $this->assertNotNull($post);\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphToIsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphToIsTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphToIsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post = Post::create();\n        (new Comment)->commentable()->associate($post)->save();\n    }\n\n    public function testParentIsNotNull()\n    {\n        $child = Comment::first();\n        $parent = null;\n\n        $this->assertFalse($child->commentable()->is($parent));\n        $this->assertTrue($child->commentable()->isNot($parent));\n    }\n\n    public function testParentIsModel()\n    {\n        $child = Comment::first();\n        $parent = Post::first();\n\n        $this->assertTrue($child->commentable()->is($parent));\n        $this->assertFalse($child->commentable()->isNot($parent));\n    }\n\n    public function testParentIsNotAnotherModel()\n    {\n        $child = Comment::first();\n        $parent = new Post;\n        $parent->id = 2;\n\n        $this->assertFalse($child->commentable()->is($parent));\n        $this->assertTrue($child->commentable()->isNot($parent));\n    }\n\n    public function testNullParentIsNotModel()\n    {\n        $child = Comment::first();\n        $child->commentable()->dissociate();\n        $parent = Post::first();\n\n        $this->assertFalse($child->commentable()->is($parent));\n        $this->assertTrue($child->commentable()->isNot($parent));\n    }\n\n    public function testParentIsNotModelWithAnotherTable()\n    {\n        $child = Comment::first();\n        $parent = Post::first();\n        $parent->setTable('foo');\n\n        $this->assertFalse($child->commentable()->is($parent));\n        $this->assertTrue($child->commentable()->isNot($parent));\n    }\n\n    public function testParentIsNotModelWithAnotherConnection()\n    {\n        $child = Comment::first();\n        $parent = Post::first();\n        $parent->setConnection('foo');\n\n        $this->assertFalse($child->commentable()->is($parent));\n        $this->assertTrue($child->commentable()->isNot($parent));\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphToLazyEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphToLazyEagerLoadingTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphToLazyEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('post_id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('video_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $user = User::create();\n\n        $post = tap((new Post)->user()->associate($user))->save();\n\n        $video = Video::create();\n\n        (new Comment)->commentable()->associate($post)->save();\n        (new Comment)->commentable()->associate($video)->save();\n    }\n\n    public function testLazyEagerLoading()\n    {\n        $comments = Comment::all();\n\n        DB::enableQueryLog();\n\n        $comments->load('commentable');\n\n        $this->assertCount(3, DB::getQueryLog());\n        $this->assertTrue($comments[0]->relationLoaded('commentable'));\n        $this->assertTrue($comments[0]->commentable->relationLoaded('user'));\n        $this->assertTrue($comments[1]->relationLoaded('commentable'));\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n    protected $primaryKey = 'post_id';\n    protected $with = ['user'];\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n    protected $primaryKey = 'video_id';\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphToSelectTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphToSelectTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphToSelectTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $post = Post::create();\n        (new Comment)->commentable()->associate($post)->save();\n    }\n\n    public function testSelect()\n    {\n        $comments = Comment::with('commentable:id')->get();\n\n        $this->assertEquals(['id' => 1], $comments[0]->commentable->getAttributes());\n    }\n\n    public function testSelectRaw()\n    {\n        $comments = Comment::with(['commentable' => function ($query) {\n            $query->selectRaw('id');\n        }])->get();\n\n        $this->assertEquals(['id' => 1], $comments[0]->commentable->getAttributes());\n    }\n\n    public function testSelectSub()\n    {\n        $comments = Comment::with(['commentable' => function ($query) {\n            $query->selectSub(function ($query) {\n                $query->select('id');\n            }, 'id');\n        }])->get();\n\n        $this->assertEquals(['id' => 1], $comments[0]->commentable->getAttributes());\n    }\n\n    public function testAddSelect()\n    {\n        $comments = Comment::with(['commentable' => function ($query) {\n            $query->addSelect('id');\n        }])->get();\n\n        $this->assertEquals(['id' => 1], $comments[0]->commentable->getAttributes());\n    }\n\n    public function testLazyLoading()\n    {\n        $comment = Comment::first();\n        $post = $comment->commentable()->select('id')->first();\n\n        $this->assertEquals(['id' => 1], $post->getAttributes());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMorphToTouchesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMorphToTouchesTest;\n\nuse DB;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMorphToTouchesTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->nullableMorphs('commentable');\n        });\n\n        Post::create();\n    }\n\n    public function testNotNull()\n    {\n        $comment = (new Comment)->commentable()->associate(Post::first());\n\n        DB::enableQueryLog();\n\n        $comment->save();\n\n        $this->assertCount(2, DB::getQueryLog());\n    }\n\n    public function testNull()\n    {\n        DB::enableQueryLog();\n\n        Comment::create();\n\n        $this->assertCount(1, DB::getQueryLog());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $touches = ['commentable'];\n\n    public function commentable()\n    {\n        return $this->morphTo(null, null, null, 'id');\n    }\n}\n\nclass Post extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentMultiDimensionalArrayEagerLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentMultiDimensionalArrayEagerLoadingTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentMultiDimensionalArrayEagerLoadingTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('avatars', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->string('content');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('images', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->string('content');\n            $table->unsignedInteger('post_id');\n        });\n\n        Schema::create('tags', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('comment_id');\n        });\n\n        $user = User::create();\n        $user->avatar()->create();\n        $posts = $user->posts()->createMany([\n            [\n                'title' => '1. post title',\n                'content' => '1. post content',\n            ],\n            [\n                'title' => '2. post title',\n                'content' => '2. post content',\n            ],\n        ]);\n        $posts->map->image()->each->create();\n        $comments = $posts->map->comments()->map->create([\n            'title' => 'comment title',\n            'content' => 'comment content',\n        ]);\n        $comments->map->tags()->each->create();\n        $comments->map->tags()->each->create();\n        $comments->map->tags()->each->create();\n    }\n\n    public function testItCanEagerLoad()\n    {\n        DB::enableQueryLog();\n\n        $users = User::query()\n            ->with([\n                'avatar',\n                'posts' => [\n                    'comments' => [\n                        'tags',\n                    ],\n                    'image',\n                ],\n            ])->get();\n\n        $this->assertCount(6, DB::getQueryLog());\n        $this->assertCount(1, $users);\n        $this->assertTrue($users[0]->relationLoaded('avatar'));\n        $this->assertNotNull($users[0]->avatar);\n        $this->assertTrue($users[0]->relationLoaded('posts'));\n        $this->assertCount(2, $users[0]->posts);\n        $this->assertTrue($users[0]->posts[0]->isNot($users[0]->posts[1]));\n        $this->assertTrue($users[0]->posts->every->relationLoaded('image'));\n        $this->assertCount(2, $users[0]->posts->map->image);\n        $this->assertTrue($users[0]->posts[0]->image->isNot($users[0]->posts[1]->image));\n        $this->assertTrue($users[0]->posts->every->relationLoaded('comments'));\n        $this->assertCount(2, $users[0]->posts->flatMap->comments);\n        $this->assertTrue($users[0]->posts[0]->comments[0]->isNot($users[0]->posts[1]->comments[0]));\n        $this->assertTrue($users[0]->posts->flatMap->comments->every->relationLoaded('tags'));\n        $this->assertCount(6, $users[0]->posts->flatMap->comments->flatMap->tags);\n    }\n\n    public function testItAppliesConstraintsViaClosuresAndCanContinueEagerLoading()\n    {\n        DB::enableQueryLog();\n\n        $users = User::query()\n            ->with([\n                'posts' => fn ($query) => $query->withCount('comments')->with([\n                    'comments' => [\n                        'tags',\n                    ],\n                ]),\n            ])\n            ->get();\n\n        $this->assertCount(4, DB::getQueryLog());\n        $this->assertCount(1, $users);\n        $this->assertTrue($users[0]->relationLoaded('posts'));\n        $this->assertCount(2, $users[0]->posts);\n        $users[0]->posts->every(fn ($post) => $this->assertEquals(1, $post->comments_count));\n        $this->assertTrue($users[0]->posts->every->relationLoaded('comments'));\n        $this->assertCount(2, $users[0]->posts->flatMap->comments);\n        $this->assertTrue($users[0]->posts->flatMap->comments->every->relationLoaded('tags'));\n    }\n\n    public function testItCanSpecifyAttributesToSelectInKeys()\n    {\n        DB::enableQueryLog();\n\n        $users = User::query()\n            ->with([\n                'posts:id,title,user_id' => [\n                    'comments:id,content,post_id' => [\n                        'tags',\n                    ],\n                ],\n            ])\n            ->get();\n\n        $this->assertCount(4, DB::getQueryLog());\n        $this->assertCount(1, $users);\n        $this->assertTrue($users[0]->relationLoaded('posts'));\n        $this->assertCount(2, $users[0]->posts);\n        $users[0]->posts->every(fn ($post) => $this->assertSame(['id', 'title', 'user_id'], array_keys($post->getAttributes())));\n        $this->assertTrue($users[0]->posts->every->relationLoaded('comments'));\n        $this->assertCount(2, $users[0]->posts->flatMap->comments);\n        $users[0]->posts->flatMap->comments->every(fn ($post) => $this->assertSame(['id', 'content', 'post_id'], array_keys($post->getAttributes())));\n        $this->assertTrue($users[0]->posts->flatMap->comments->every->relationLoaded('tags'));\n        $this->assertCount(6, $users[0]->posts->flatMap->comments->flatMap->tags);\n    }\n\n    public function testItMixesWithDotNotation()\n    {\n        DB::enableQueryLog();\n\n        $users = User::query()\n            ->with([\n                'posts' => [\n                    'comments',\n                ],\n                'posts.image',\n            ])\n            ->get();\n\n        $this->assertCount(4, DB::getQueryLog());\n        $this->assertCount(1, $users);\n        $this->assertTrue($users[0]->relationLoaded('posts'));\n        $this->assertCount(2, $users[0]->posts);\n        $this->assertTrue($users[0]->posts->every->relationLoaded('comments'));\n        $this->assertCount(2, $users[0]->posts->flatMap->comments);\n        $this->assertTrue($users[0]->posts->every->relationLoaded('image'));\n        $this->assertCount(2, $users[0]->posts->map->image);\n    }\n\n    public function testItMixesConstraintsFromDotNotation()\n    {\n        DB::enableQueryLog();\n\n        $users = User::query()\n            ->with([\n                'posts.comments' => fn ($query) => $query->with('tags'),\n                'posts:id,title,user_id' => [\n                    'comments' => fn ($query) => $query->withCount('tags'),\n                ],\n            ])\n            ->get();\n\n        $this->assertCount(4, DB::getQueryLog());\n        $this->assertCount(1, $users);\n        $this->assertTrue($users[0]->relationLoaded('posts'));\n        $this->assertCount(2, $users[0]->posts);\n        $users[0]->posts->every(fn ($post) => $this->assertNull($post->content));\n        $this->assertTrue($users[0]->posts->every->relationLoaded('comments'));\n        $this->assertCount(2, $users[0]->posts->flatMap->comments);\n        $users[0]->posts->flatMap->comments->every(fn ($comment) => $this->assertEquals(3, $comment->tags_count));\n        $this->assertTrue($users[0]->posts->flatMap->comments->every->relationLoaded('tags'));\n        $this->assertCount(6, $users[0]->posts->flatMap->comments->flatMap->tags);\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function posts()\n    {\n        return $this->hasMany(Post::class);\n    }\n\n    public function avatar()\n    {\n        return $this->hasOne(Avatar::class);\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function image()\n    {\n        return $this->hasOne(Image::class);\n    }\n}\n\nclass Image extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function tags()\n    {\n        return $this->hasMany(Tag::class);\n    }\n}\n\nclass Tag extends Model\n{\n    protected $guarded = [];\n\n    public $timestamps = false;\n}\n\nclass Avatar extends Model\n{\n    protected $guarded = [];\n\n    public $timestamps = false;\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentNamedScopeAttributeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\n#[WithMigration]\nclass EloquentNamedScopeAttributeTest extends TestCase\n{\n    protected $query = 'select * from \"named_scope_users\" where \"email_verified_at\" is not null';\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->markTestSkippedUnless(\n            $this->usesSqliteInMemoryDatabaseConnection(),\n            'Requires in-memory database connection',\n        );\n    }\n\n    #[DataProvider('scopeDataProvider')]\n    public function test_it_can_query_named_scoped_from_the_query_builder(string $methodName)\n    {\n        $query = Fixtures\\NamedScopeUser::query()->{$methodName}(true);\n\n        $this->assertSame($this->query, $query->toRawSql());\n    }\n\n    #[DataProvider('scopeDataProvider')]\n    public function test_it_can_query_named_scoped_from_static_query(string $methodName)\n    {\n        $query = Fixtures\\NamedScopeUser::{$methodName}(true);\n\n        $this->assertSame($this->query, $query->toRawSql());\n    }\n\n    public static function scopeDataProvider(): array\n    {\n        return [\n            'scope with return' => ['verified'],\n            'scope without return' => ['verifiedWithoutReturn'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPaginateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentPaginateTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title')->nullable();\n            $table->unsignedInteger('user_id')->nullable();\n            $table->timestamps();\n        });\n\n        Schema::create('users', function ($table) {\n            $table->increments('id');\n            $table->timestamps();\n        });\n    }\n\n    public function testPaginationOnTopOfColumns()\n    {\n        for ($i = 1; $i <= 50; $i++) {\n            Post::create([\n                'title' => 'Title '.$i,\n            ]);\n        }\n\n        $this->assertCount(15, Post::paginate(15, ['id', 'title']));\n    }\n\n    public function testPaginationWithDistinct()\n    {\n        for ($i = 1; $i <= 3; $i++) {\n            Post::create(['title' => 'Hello world']);\n            Post::create(['title' => 'Goodbye world']);\n        }\n\n        $query = Post::query()->distinct();\n\n        $this->assertEquals(6, $query->get()->count());\n        $this->assertEquals(6, $query->count());\n        $this->assertEquals(6, $query->paginate()->total());\n    }\n\n    public function testPaginationWithDistinctAndSelect()\n    {\n        // This is the 'broken' behaviour, but this test is added to show backwards compatibility.\n        for ($i = 1; $i <= 3; $i++) {\n            Post::create(['title' => 'Hello world']);\n            Post::create(['title' => 'Goodbye world']);\n        }\n\n        $query = Post::query()->distinct()->select('title');\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(6, $query->count());\n        $this->assertEquals(6, $query->paginate()->total());\n    }\n\n    public function testPaginationWithDistinctColumnsAndSelect()\n    {\n        for ($i = 1; $i <= 3; $i++) {\n            Post::create(['title' => 'Hello world']);\n            Post::create(['title' => 'Goodbye world']);\n        }\n\n        $query = Post::query()->distinct('title')->select('title');\n\n        $this->assertEquals(2, $query->get()->count());\n        $this->assertEquals(2, $query->count());\n        $this->assertEquals(2, $query->paginate()->total());\n    }\n\n    public function testPaginationWithDistinctColumnsAndSelectAndJoin()\n    {\n        for ($i = 1; $i <= 5; $i++) {\n            $user = User::create();\n            for ($j = 1; $j <= 10; $j++) {\n                Post::create([\n                    'title' => 'Title '.$i,\n                    'user_id' => $user->id,\n                ]);\n            }\n        }\n\n        $query = User::query()->join('posts', 'posts.user_id', '=', 'users.id')\n            ->distinct('users.id')->select('users.*');\n\n        $this->assertEquals(5, $query->get()->count());\n        $this->assertEquals(5, $query->count());\n        $this->assertEquals(5, $query->paginate()->total());\n    }\n}\n\nclass Post extends Model\n{\n    protected $guarded = [];\n}\n\nclass User extends Model\n{\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPivotEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentPivotEventsTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        // clear event log between requests\n        PivotEventsTestCollaborator::$eventsCalled = [];\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        Schema::create('projects', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('equipments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('equipmentables', function (Blueprint $table) {\n            $table->increments('id');\n            $table->morphs('equipmentable');\n            $table->foreignId('equipment_id');\n        });\n\n        Schema::create('project_users', function (Blueprint $table) {\n            $table->integer('user_id');\n            $table->integer('project_id');\n            $table->text('permissions')->nullable();\n            $table->string('role')->nullable();\n        });\n    }\n\n    public function testPivotWillTriggerEventsToBeFired()\n    {\n        $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);\n        $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->collaborators()->attach($user);\n        $this->assertEquals(['saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->collaborators()->sync([$user2->id]);\n        $this->assertEquals(['deleting', 'deleted', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->collaborators()->sync([$user->id => ['role' => 'owner'], $user2->id => ['role' => 'contributor']]);\n        $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->collaborators()->detach($user);\n        $this->assertEquals(['deleting', 'deleted'], PivotEventsTestCollaborator::$eventsCalled);\n    }\n\n    public function testPivotWithPivotValueWillTriggerEventsToBeFired()\n    {\n        $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);\n        $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->managers()->attach($user);\n        $this->assertEquals(['saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n        $project->managers()->attach($user2);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->managers()->updateExistingPivot($user->id, ['permissions' => ['foo', 'bar']]);\n        $this->assertEquals(['saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n        $project->managers()->detach($user2);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->managers()->sync([$user2->id]);\n        $this->assertEquals(['deleting', 'deleted', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->managers()->sync([$user->id => ['permissions' => ['foo']], $user2->id => ['permissions' => ['bar']]]);\n        $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'updating', 'updated', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->managers()->detach($user);\n        $this->assertEquals(['deleting', 'deleted'], PivotEventsTestCollaborator::$eventsCalled);\n    }\n\n    public function testPivotWithPivotCriteriaTriggerEventsToBeFiredOnCreateUpdateNoneOnDetach()\n    {\n        $user = PivotEventsTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $user2 = PivotEventsTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);\n        $project = PivotEventsTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->contributors()->sync([$user->id, $user2->id]);\n        $this->assertEquals(['saving', 'creating', 'created', 'saved', 'saving', 'creating', 'created', 'saved'], PivotEventsTestCollaborator::$eventsCalled);\n\n        PivotEventsTestCollaborator::$eventsCalled = [];\n        $project->contributors()->detach($user->id);\n        $this->assertEquals([], PivotEventsTestCollaborator::$eventsCalled);\n    }\n\n    public function testCustomPivotUpdateEventHasExistingAttributes()\n    {\n        $_SERVER['pivot_attributes'] = false;\n\n        $user = PivotEventsTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $project = PivotEventsTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->attach($user, ['permissions' => ['foo', 'bar']]);\n\n        $project->collaborators()->updateExistingPivot($user->id, ['role' => 'Lead Developer']);\n\n        $this->assertEquals(\n            [\n                'user_id' => '1',\n                'project_id' => '1',\n                'permissions' => '[\"foo\",\"bar\"]',\n                'role' => 'Lead Developer',\n            ],\n            $_SERVER['pivot_attributes']\n        );\n    }\n\n    public function testCustomPivotUpdateEventHasDirtyCorrect()\n    {\n        $_SERVER['pivot_dirty_attributes'] = false;\n\n        $user = PivotEventsTestUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $project = PivotEventsTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        $project->collaborators()->attach($user, ['permissions' => ['foo', 'bar'], 'role' => 'Developer']);\n\n        $project->collaborators()->updateExistingPivot($user->id, ['role' => 'Lead Developer']);\n\n        $this->assertSame(['role' => 'Lead Developer'], $_SERVER['pivot_dirty_attributes']);\n    }\n\n    public function testCustomMorphPivotClassDetachAttributes()\n    {\n        $project = PivotEventsTestProject::forceCreate([\n            'name' => 'Test Project',\n        ]);\n\n        PivotEventsTestModelEquipment::deleting(function ($model) use ($project) {\n            $this->assertInstanceOf(PivotEventsTestProject::class, $model->equipmentable);\n            $this->assertEquals($project->id, $model->equipmentable->id);\n        });\n\n        $equipment = PivotEventsTestEquipment::forceCreate([\n            'name' => 'important-equipment',\n        ]);\n\n        $project->equipments()->save($equipment);\n        $equipment->projects()->sync([]);\n\n        $this->assertEquals(\n            [PivotEventsTestProject::class, PivotEventsTestProject::class, PivotEventsTestProject::class, PivotEventsTestProject::class, PivotEventsTestProject::class, PivotEventsTestProject::class],\n            PivotEventsTestModelEquipment::$eventsMorphClasses\n        );\n\n        $this->assertEquals(\n            ['equipmentable_type', 'equipmentable_type', 'equipmentable_type', 'equipmentable_type', 'equipmentable_type', 'equipmentable_type'],\n            PivotEventsTestModelEquipment::$eventsMorphTypes\n        );\n    }\n}\n\nclass PivotEventsTestUser extends Model\n{\n    public $table = 'users';\n}\n\nclass PivotEventsTestEquipment extends Model\n{\n    public $table = 'equipments';\n\n    public function getForeignKey()\n    {\n        return 'equipment_id';\n    }\n\n    public function projects()\n    {\n        return $this->morphedByMany(PivotEventsTestProject::class, 'equipmentable')->using(PivotEventsTestModelEquipment::class);\n    }\n}\n\nclass PivotEventsTestProject extends Model\n{\n    public $table = 'projects';\n\n    public function collaborators()\n    {\n        return $this->belongsToMany(\n            PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id'\n        )->using(PivotEventsTestCollaborator::class);\n    }\n\n    public function contributors()\n    {\n        return $this->belongsToMany(PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id')\n            ->using(PivotEventsTestCollaborator::class)\n            ->wherePivot('role', 'contributor');\n    }\n\n    public function managers()\n    {\n        return $this->belongsToMany(PivotEventsTestUser::class, 'project_users', 'project_id', 'user_id')\n            ->using(PivotEventsTestCollaborator::class)\n            ->withPivotValue('role', 'manager');\n    }\n\n    public function equipments()\n    {\n        return $this->morphToMany(PivotEventsTestEquipment::class, 'equipmentable')->using(PivotEventsTestModelEquipment::class);\n    }\n}\n\nclass PivotEventsTestModelEquipment extends MorphPivot\n{\n    public $table = 'equipmentables';\n\n    public static $eventsMorphClasses = [];\n\n    public static $eventsMorphTypes = [];\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::creating(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::created(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::updating(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::updated(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::saving(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::saved(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::deleting(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n\n        static::deleted(function ($model) {\n            static::$eventsMorphClasses[] = $model->morphClass;\n            static::$eventsMorphTypes[] = $model->morphType;\n        });\n    }\n\n    public function equipment()\n    {\n        return $this->belongsTo(PivotEventsTestEquipment::class);\n    }\n\n    public function equipmentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass PivotEventsTestCollaborator extends Pivot\n{\n    public $table = 'project_users';\n\n    public $timestamps = false;\n\n    protected $casts = [\n        'permissions' => 'json',\n    ];\n\n    public static $eventsCalled = [];\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::creating(function ($model) {\n            static::$eventsCalled[] = 'creating';\n        });\n\n        static::created(function ($model) {\n            static::$eventsCalled[] = 'created';\n        });\n\n        static::updating(function ($model) {\n            static::$eventsCalled[] = 'updating';\n        });\n\n        static::updated(function ($model) {\n            $_SERVER['pivot_attributes'] = $model->getAttributes();\n            $_SERVER['pivot_dirty_attributes'] = $model->getDirty();\n            static::$eventsCalled[] = 'updated';\n        });\n\n        static::saving(function ($model) {\n            static::$eventsCalled[] = 'saving';\n        });\n\n        static::saved(function ($model) {\n            static::$eventsCalled[] = 'saved';\n        });\n\n        static::deleting(function ($model) {\n            static::$eventsCalled[] = 'deleting';\n        });\n\n        static::deleted(function ($model) {\n            static::$eventsCalled[] = 'deleted';\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPivotSerializationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection as DatabaseCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentPivotSerializationTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        Schema::create('projects', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('project_users', function (Blueprint $table) {\n            $table->integer('user_id');\n            $table->integer('project_id');\n        });\n\n        Schema::create('tags', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('taggables', function (Blueprint $table) {\n            $table->integer('tag_id');\n            $table->integer('taggable_id');\n            $table->string('taggable_type');\n        });\n    }\n\n    public function testPivotCanBeSerializedAndRestored()\n    {\n        $user = PivotSerializationTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $project = PivotSerializationTestProject::forceCreate(['name' => 'Test Project']);\n        $project->collaborators()->attach($user);\n\n        $project = $project->fresh();\n\n        $class = new PivotSerializationTestClass($project->collaborators->first()->pivot);\n        $class = unserialize(serialize($class));\n\n        $this->assertEquals($project->collaborators->first()->pivot->user_id, $class->pivot->user_id);\n        $this->assertEquals($project->collaborators->first()->pivot->project_id, $class->pivot->project_id);\n\n        $class->pivot->save();\n    }\n\n    public function testMorphPivotCanBeSerializedAndRestored()\n    {\n        $project = PivotSerializationTestProject::forceCreate(['name' => 'Test Project']);\n        $tag = PivotSerializationTestTag::forceCreate(['name' => 'Test Tag']);\n        $project->tags()->attach($tag);\n\n        $project = $project->fresh();\n\n        $class = new PivotSerializationTestClass($project->tags->first()->pivot);\n        $class = unserialize(serialize($class));\n\n        $this->assertEquals($project->tags->first()->pivot->tag_id, $class->pivot->tag_id);\n        $this->assertEquals($project->tags->first()->pivot->taggable_id, $class->pivot->taggable_id);\n        $this->assertEquals($project->tags->first()->pivot->taggable_type, $class->pivot->taggable_type);\n\n        $class->pivot->save();\n    }\n\n    public function testCollectionOfPivotsCanBeSerializedAndRestored()\n    {\n        $user = PivotSerializationTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $user2 = PivotSerializationTestUser::forceCreate(['email' => 'mohamed@laravel.com']);\n        $project = PivotSerializationTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->collaborators()->attach($user);\n        $project->collaborators()->attach($user2);\n\n        $project = $project->fresh();\n\n        $class = new PivotSerializationTestCollectionClass(DatabaseCollection::make($project->collaborators->map->pivot));\n        $class = unserialize(serialize($class));\n\n        $this->assertEquals($project->collaborators[0]->pivot->user_id, $class->pivots[0]->user_id);\n        $this->assertEquals($project->collaborators[1]->pivot->project_id, $class->pivots[1]->project_id);\n    }\n\n    public function testCollectionOfMorphPivotsCanBeSerializedAndRestored()\n    {\n        $tag = PivotSerializationTestTag::forceCreate(['name' => 'Test Tag 1']);\n        $tag2 = PivotSerializationTestTag::forceCreate(['name' => 'Test Tag 2']);\n        $project = PivotSerializationTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->tags()->attach($tag);\n        $project->tags()->attach($tag2);\n\n        $project = $project->fresh();\n\n        $class = new PivotSerializationTestCollectionClass(DatabaseCollection::make($project->tags->map->pivot));\n        $class = unserialize(serialize($class));\n\n        $this->assertEquals($project->tags[0]->pivot->tag_id, $class->pivots[0]->tag_id);\n        $this->assertEquals($project->tags[0]->pivot->taggable_id, $class->pivots[0]->taggable_id);\n        $this->assertEquals($project->tags[0]->pivot->taggable_type, $class->pivots[0]->taggable_type);\n\n        $this->assertEquals($project->tags[1]->pivot->tag_id, $class->pivots[1]->tag_id);\n        $this->assertEquals($project->tags[1]->pivot->taggable_id, $class->pivots[1]->taggable_id);\n        $this->assertEquals($project->tags[1]->pivot->taggable_type, $class->pivots[1]->taggable_type);\n    }\n}\n\nclass PivotSerializationTestClass\n{\n    use SerializesModels;\n\n    public $pivot;\n\n    public function __construct($pivot)\n    {\n        $this->pivot = $pivot;\n    }\n}\n\nclass PivotSerializationTestCollectionClass\n{\n    use SerializesModels;\n\n    public $pivots;\n\n    public function __construct($pivots)\n    {\n        $this->pivots = $pivots;\n    }\n}\n\nclass PivotSerializationTestUser extends Model\n{\n    public $table = 'users';\n}\n\nclass PivotSerializationTestProject extends Model\n{\n    public $table = 'projects';\n\n    public function collaborators()\n    {\n        return $this->belongsToMany(\n            PivotSerializationTestUser::class, 'project_users', 'project_id', 'user_id'\n        )->using(PivotSerializationTestCollaborator::class);\n    }\n\n    public function tags()\n    {\n        return $this->morphToMany(PivotSerializationTestTag::class, 'taggable', 'taggables', 'taggable_id', 'tag_id')\n            ->using(PivotSerializationTestTagAttachment::class);\n    }\n}\n\nclass PivotSerializationTestTag extends Model\n{\n    public $table = 'tags';\n\n    public function projects()\n    {\n        return $this->morphedByMany(PivotSerializationTestProject::class, 'taggable', 'taggables', 'tag_id', 'taggable_id')\n            ->using(PivotSerializationTestTagAttachment::class);\n    }\n}\n\nclass PivotSerializationTestCollaborator extends Pivot\n{\n    public $table = 'project_users';\n\n    public $timestamps = false;\n}\n\nclass PivotSerializationTestTagAttachment extends MorphPivot\n{\n    public $table = 'taggables';\n\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPivotTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentPivotTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->timestamps();\n        });\n\n        Schema::create('projects', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('collaborators', function (Blueprint $table) {\n            $table->integer('user_id');\n            $table->integer('project_id');\n            $table->text('permissions')->nullable();\n        });\n\n        Schema::create('contributors', function (Blueprint $table) {\n            $table->id();\n            $table->integer('user_id');\n            $table->integer('project_id');\n            $table->text('permissions')->nullable();\n        });\n\n        Schema::create('subscriptions', function (Blueprint $table) {\n            $table->integer('user_id');\n            $table->integer('project_id');\n            $table->string('status');\n        });\n    }\n\n    public function testPivotConvenientHelperReturnExpectedResult()\n    {\n        $user = PivotTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $user2 = PivotTestUser::forceCreate(['email' => 'ralph@ralphschindler.com']);\n        $project = PivotTestProject::forceCreate(['name' => 'Test Project']);\n\n        $project->contributors()->attach($user);\n        $project->collaborators()->attach($user2);\n\n        tap($project->contributors->first()->pivot, function ($pivot) {\n            $this->assertEquals(1, $pivot->getKey());\n            $this->assertEquals(1, $pivot->getQueueableId());\n            $this->assertSame('user_id', $pivot->getRelatedKey());\n            $this->assertSame('project_id', $pivot->getForeignKey());\n        });\n\n        tap($project->collaborators->first()->pivot, function ($pivot) {\n            $this->assertNull($pivot->getKey());\n            $this->assertSame('project_id:1:user_id:2', $pivot->getQueueableId());\n            $this->assertSame('user_id', $pivot->getRelatedKey());\n            $this->assertSame('project_id', $pivot->getForeignKey());\n        });\n    }\n\n    public function testPivotValuesCanBeSetFromRelationDefinition()\n    {\n        $user = PivotTestUser::forceCreate(['email' => 'taylor@laravel.com']);\n        $active = PivotTestProject::forceCreate(['name' => 'Active Project']);\n        $inactive = PivotTestProject::forceCreate(['name' => 'Inactive Project']);\n\n        $this->assertSame('active', $user->activeSubscriptions()->newPivot()->status);\n        $this->assertSame('inactive', $user->inactiveSubscriptions()->newPivot()->status);\n\n        $user->activeSubscriptions()->attach($active);\n        $user->inactiveSubscriptions()->attach($inactive);\n\n        $this->assertSame('active', $user->activeSubscriptions->first()->pivot->status);\n        $this->assertSame('inactive', $user->inactiveSubscriptions->first()->pivot->status);\n    }\n}\n\nclass PivotTestUser extends Model\n{\n    public $table = 'users';\n\n    public function activeSubscriptions()\n    {\n        return $this->belongsToMany(PivotTestProject::class, 'subscriptions', 'user_id', 'project_id')\n            ->withPivotValue('status', 'active')\n            ->withPivot('status')\n            ->using(PivotTestSubscription::class);\n    }\n\n    public function inactiveSubscriptions()\n    {\n        return $this->belongsToMany(PivotTestProject::class, 'subscriptions', 'user_id', 'project_id')\n            ->withPivotValue('status', 'inactive')\n            ->withPivot('status')\n            ->using(PivotTestSubscription::class);\n    }\n}\n\nclass PivotTestProject extends Model\n{\n    public $table = 'projects';\n\n    public function collaborators()\n    {\n        return $this->belongsToMany(\n            PivotTestUser::class, 'collaborators', 'project_id', 'user_id'\n        )->withPivot('permissions')\n            ->using(PivotTestCollaborator::class);\n    }\n\n    public function contributors()\n    {\n        return $this->belongsToMany(PivotTestUser::class, 'contributors', 'project_id', 'user_id')\n            ->withPivot('id', 'permissions')\n            ->using(PivotTestContributor::class);\n    }\n}\n\nclass PivotTestCollaborator extends Pivot\n{\n    public $table = 'collaborators';\n\n    public $timestamps = false;\n\n    protected $casts = [\n        'permissions' => 'json',\n    ];\n}\n\nclass PivotTestContributor extends Pivot\n{\n    public $table = 'contributors';\n\n    public $timestamps = false;\n\n    public $incrementing = true;\n\n    protected $casts = [\n        'permissions' => 'json',\n    ];\n}\n\nclass PivotTestSubscription extends Pivot\n{\n    public $table = 'subscriptions';\n\n    public $timestamps = false;\n\n    protected $attributes = [\n        'status' => 'active',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPivotWithoutTimestampTest.fixtures.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentPivotWithoutTimestampTest;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\n#[UseFactory(UserFactory::class)]\nclass User extends Authenticatable\n{\n    use HasFactory;\n\n    public function roles(): BelongsToMany\n    {\n        return $this->belongsToMany(Role::class)\n            ->withPivot('notes')\n            ->using(UserRole::class)\n            ->withTimestamps(updatedAt: false);\n    }\n}\n\n#[UseFactory(RoleFactory::class)]\nclass Role extends Model\n{\n    use HasFactory;\n\n    public function users(): BelongsToMany\n    {\n        return $this->belongsToMany(User::class)\n            ->withPivot('notes')\n            ->using(UserRole::class);\n    }\n}\n\nclass RoleFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'name' => fake()->name(),\n        ];\n    }\n}\n\nclass UserRole extends Pivot\n{\n    public $table = 'role_user';\n\n    public function getUpdatedAtColumn()\n    {\n        return null;\n    }\n}\n\nfunction migrate()\n{\n    Schema::create('roles', function (Blueprint $table) {\n        $table->id();\n        $table->string('name');\n        $table->timestamps();\n    });\n\n    Schema::create('role_user', function (Blueprint $table) {\n        $table->foreignId('user_id');\n        $table->foreignId('role_id');\n        $table->text('notes');\n        $table->timestamp('created_at')->nullable();\n    });\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPivotWithoutTimestampTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Tests\\Integration\\Database\\EloquentPivotWithoutTimestampTest as App;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Concerns\\WithFixtures;\n\n#[WithConfig('auth.providers.users.model', App\\User::class)]\n#[WithMigration]\nclass EloquentPivotWithoutTimestampTest extends DatabaseTestCase\n{\n    use WithFixtures;\n\n    protected function afterRefreshingDatabase()\n    {\n        App\\migrate();\n    }\n\n    public function testAttachingModelWithoutTimestamps()\n    {\n        $now = $this->freezeSecond();\n\n        $user = App\\User::factory()->create();\n        $role = App\\Role::factory()->create();\n\n        $user->roles()->attach($role->getKey(), ['notes' => 'Laravel']);\n\n        $this->assertDatabaseHas('role_user', [\n            'user_id' => $user->getKey(),\n            'role_id' => $role->getKey(),\n            'notes' => 'Laravel',\n            'created_at' => $now,\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPrunableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Exception;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Prunable;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Events\\ModelsPruned;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Exceptions;\nuse Illuminate\\Support\\Facades\\Schema;\nuse LogicException;\n\nclass EloquentPrunableTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        collect([\n            'prunable_test_models',\n            'prunable_soft_delete_test_models',\n            'prunable_test_model_missing_prunable_methods',\n            'prunable_with_custom_prune_method_test_models',\n            'prunable_with_exceptions',\n        ])->each(function ($table) {\n            Schema::create($table, function (Blueprint $table) {\n                $table->increments('id');\n                $table->string('name')->nullable();\n                $table->softDeletes();\n                $table->boolean('pruned')->default(false);\n                $table->timestamps();\n            });\n        });\n    }\n\n    public function testPrunableMethodMustBeImplemented()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage(\n            'Please implement',\n        );\n\n        PrunableTestModelMissingPrunableMethod::create()->pruneAll();\n    }\n\n    public function testPrunesRecords()\n    {\n        Event::fake();\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['name' => 'foo'];\n        })->chunk(200)->each(function ($chunk) {\n            PrunableTestModel::insert($chunk->all());\n        });\n\n        $count = (new PrunableTestModel)->pruneAll();\n\n        $this->assertEquals(1500, $count);\n        $this->assertEquals(3500, PrunableTestModel::count());\n\n        Event::assertDispatched(ModelsPruned::class, 2);\n    }\n\n    public function testPrunesSoftDeletedRecords()\n    {\n        Event::fake();\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['deleted_at' => Carbon::now()];\n        })->chunk(200)->each(function ($chunk) {\n            PrunableSoftDeleteTestModel::insert($chunk->all());\n        });\n\n        $count = (new PrunableSoftDeleteTestModel)->pruneAll();\n\n        $this->assertEquals(3000, $count);\n        $this->assertEquals(0, PrunableSoftDeleteTestModel::count());\n        $this->assertEquals(2000, PrunableSoftDeleteTestModel::withTrashed()->count());\n\n        Event::assertDispatched(ModelsPruned::class, 3);\n    }\n\n    public function testPruneWithCustomPruneMethod()\n    {\n        Event::fake();\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['name' => 'foo'];\n        })->chunk(200)->each(function ($chunk) {\n            PrunableWithCustomPruneMethodTestModel::insert($chunk->all());\n        });\n\n        $count = (new PrunableWithCustomPruneMethodTestModel)->pruneAll();\n\n        $this->assertEquals(1000, $count);\n        $this->assertTrue((bool) PrunableWithCustomPruneMethodTestModel::first()->pruned);\n        $this->assertFalse((bool) PrunableWithCustomPruneMethodTestModel::orderBy('id', 'desc')->first()->pruned);\n        $this->assertEquals(5000, PrunableWithCustomPruneMethodTestModel::count());\n\n        Event::assertDispatched(ModelsPruned::class, 1);\n    }\n\n    public function testPruneWithExceptionAtOneOfModels()\n    {\n        Event::fake();\n        Exceptions::fake();\n\n        collect(range(1, 5000))->map(function ($id) {\n            return ['name' => 'foo'];\n        })->chunk(200)->each(function ($chunk) {\n            PrunableWithException::insert($chunk->all());\n        });\n\n        $count = (new PrunableWithException)->pruneAll();\n\n        $this->assertEquals(999, $count);\n\n        Event::assertDispatched(ModelsPruned::class, 1);\n        Event::assertDispatched(fn (ModelsPruned $event) => $event->count === 999);\n        Exceptions::assertReportedCount(1);\n        Exceptions::assertReported(fn (Exception $exception) => $exception->getMessage() === 'foo bar');\n    }\n}\n\nclass PrunableTestModel extends Model\n{\n    use Prunable;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 1500);\n    }\n}\n\nclass PrunableSoftDeleteTestModel extends Model\n{\n    use Prunable, SoftDeletes;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 3000);\n    }\n}\n\nclass PrunableWithCustomPruneMethodTestModel extends Model\n{\n    use Prunable;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 1000);\n    }\n\n    public function prune()\n    {\n        $this->forceFill([\n            'pruned' => true,\n        ])->save();\n    }\n}\n\nclass PrunableWithException extends Model\n{\n    use Prunable;\n\n    public function prunable()\n    {\n        return $this->where('id', '<=', 1000);\n    }\n\n    public function prune()\n    {\n        if ($this->id === 500) {\n            throw new Exception('foo bar');\n        }\n    }\n}\n\nclass PrunableTestModelMissingPrunableMethod extends Model\n{\n    use Prunable;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentPushTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentPushTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->unsignedInteger('user_id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('comment');\n            $table->unsignedInteger('post_id');\n        });\n    }\n\n    public function testPushMethodSavesTheRelationshipsRecursively()\n    {\n        $user = new UserX;\n        $user->name = 'Test';\n        $user->save();\n        $user->posts()->create(['title' => 'Test title']);\n\n        $post = PostX::firstOrFail();\n        $post->comments()->create(['comment' => 'Test comment']);\n\n        $user = $user->fresh();\n        $user->name = 'Test 1';\n        $user->posts[0]->title = 'Test title 1';\n        $user->posts[0]->comments[0]->comment = 'Test comment 1';\n        $user->push();\n\n        $this->assertSame(1, UserX::count());\n        $this->assertSame('Test 1', UserX::firstOrFail()->name);\n        $this->assertSame(1, PostX::count());\n        $this->assertSame('Test title 1', PostX::firstOrFail()->title);\n        $this->assertSame(1, CommentX::count());\n        $this->assertSame('Test comment 1', CommentX::firstOrFail()->comment);\n    }\n}\n\nclass UserX extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $table = 'users';\n\n    public function posts()\n    {\n        return $this->hasMany(PostX::class, 'user_id');\n    }\n}\n\nclass PostX extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $table = 'posts';\n\n    public function comments()\n    {\n        return $this->hasMany(CommentX::class, 'post_id');\n    }\n}\n\nclass CommentX extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $table = 'comments';\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentStrictLoadingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\LazyLoadingViolationException;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse RuntimeException;\n\nclass EloquentStrictLoadingTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Model::preventLazyLoading();\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('number')->default(1);\n        });\n\n        Schema::create('test_model2', function (Blueprint $table) {\n            $table->increments('id');\n            $table->foreignId('model_1_id');\n        });\n\n        Schema::create('test_model3', function (Blueprint $table) {\n            $table->increments('id');\n            $table->foreignId('model_2_id');\n        });\n    }\n\n    public function testStrictModeThrowsAnExceptionOnLazyLoading()\n    {\n        $this->expectException(LazyLoadingViolationException::class);\n        $this->expectExceptionMessage('Attempted to lazy load');\n\n        EloquentStrictLoadingTestModel1::create();\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::get();\n\n        $models[0]->modelTwos;\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnLazyLoadingWithSingleModel()\n    {\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::get();\n\n        $this->assertInstanceOf(Collection::class, $models);\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnAttributes()\n    {\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::get(['id']);\n\n        $this->assertNull($models[0]->number);\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnEagerLoading()\n    {\n        $this->app['config']->set('database.connections.testing.zxc', false);\n\n        EloquentStrictLoadingTestModel1::create();\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::with('modelTwos')->get();\n\n        $this->assertInstanceOf(Collection::class, $models[0]->modelTwos);\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnLazyEagerLoading()\n    {\n        EloquentStrictLoadingTestModel1::create();\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::get();\n\n        $models->load('modelTwos');\n\n        $this->assertInstanceOf(Collection::class, $models[0]->modelTwos);\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnSingleModelLoading()\n    {\n        $model = EloquentStrictLoadingTestModel1::create();\n\n        $model = EloquentStrictLoadingTestModel1::find($model->id);\n\n        $this->assertInstanceOf(Collection::class, $model->modelTwos);\n    }\n\n    public function testStrictModeThrowsAnExceptionOnLazyLoadingInRelations()\n    {\n        $this->expectException(LazyLoadingViolationException::class);\n        $this->expectExceptionMessage('Attempted to lazy load');\n\n        $model1 = EloquentStrictLoadingTestModel1::create();\n        EloquentStrictLoadingTestModel2::create(['model_1_id' => $model1->id]);\n        EloquentStrictLoadingTestModel2::create(['model_1_id' => $model1->id]);\n\n        $models = EloquentStrictLoadingTestModel1::with('modelTwos')->get();\n\n        $models[0]->modelTwos[0]->modelThrees;\n    }\n\n    public function testStrictModeWithCustomCallbackOnLazyLoading()\n    {\n        Event::fake();\n\n        Model::handleLazyLoadingViolationUsing(function ($model, $key) {\n            event(new ViolatedLazyLoadingEvent($model, $key));\n        });\n\n        EloquentStrictLoadingTestModel1::create();\n        EloquentStrictLoadingTestModel1::create();\n\n        $models = EloquentStrictLoadingTestModel1::get();\n\n        $models[0]->modelTwos;\n\n        Event::assertDispatched(ViolatedLazyLoadingEvent::class);\n    }\n\n    public function testStrictModeWithOverriddenHandlerOnLazyLoading()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Violated');\n\n        EloquentStrictLoadingTestModel1WithCustomHandler::create();\n        EloquentStrictLoadingTestModel1WithCustomHandler::create();\n\n        $models = EloquentStrictLoadingTestModel1WithCustomHandler::get();\n\n        $models[0]->modelTwos;\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnManuallyMadeModel()\n    {\n        $model1 = EloquentStrictLoadingTestModel1WithLocalPreventsLazyLoading::make();\n        $model2 = EloquentStrictLoadingTestModel2::make();\n        $model1->modelTwos->push($model2);\n\n        $this->assertInstanceOf(Collection::class, $model1->modelTwos);\n    }\n\n    public function testStrictModeDoesntThrowAnExceptionOnRecentlyCreatedModel()\n    {\n        $model1 = EloquentStrictLoadingTestModel1WithLocalPreventsLazyLoading::create();\n        $this->assertInstanceOf(Collection::class, $model1->modelTwos);\n    }\n}\n\nclass EloquentStrictLoadingTestModel1 extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function modelTwos()\n    {\n        return $this->hasMany(EloquentStrictLoadingTestModel2::class, 'model_1_id');\n    }\n}\n\nclass EloquentStrictLoadingTestModel1WithCustomHandler extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function modelTwos()\n    {\n        return $this->hasMany(EloquentStrictLoadingTestModel2::class, 'model_1_id');\n    }\n\n    protected function handleLazyLoadingViolation($key)\n    {\n        throw new RuntimeException(\"Violated {$key}\");\n    }\n}\n\nclass EloquentStrictLoadingTestModel1WithLocalPreventsLazyLoading extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    public $preventsLazyLoading = true;\n    protected $guarded = [];\n\n    public function modelTwos()\n    {\n        return $this->hasMany(EloquentStrictLoadingTestModel2::class, 'model_1_id');\n    }\n}\n\nclass EloquentStrictLoadingTestModel2 extends Model\n{\n    public $table = 'test_model2';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function modelThrees()\n    {\n        return $this->hasMany(EloquentStrictLoadingTestModel3::class, 'model_2_id');\n    }\n}\n\nclass EloquentStrictLoadingTestModel3 extends Model\n{\n    public $table = 'test_model3';\n    public $timestamps = false;\n    protected $guarded = [];\n}\n\nclass ViolatedLazyLoadingEvent\n{\n    public $model;\n    public $key;\n\n    public function __construct($model, $key)\n    {\n        $this->model = $model;\n        $this->key = $key;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentThroughTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentThroughTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentThroughTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->boolean('public');\n        });\n\n        Schema::create('other_commentables', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        Schema::create('likes', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('comment_id');\n        });\n\n        $post = tap(new Post(['public' => true]))->save();\n        $comment = tap((new Comment)->commentable()->associate($post))->save();\n        (new Like())->comment()->associate($comment)->save();\n        (new Like())->comment()->associate($comment)->save();\n\n        $otherCommentable = tap(new OtherCommentable())->save();\n        $comment2 = tap((new Comment)->commentable()->associate($otherCommentable))->save();\n        (new Like())->comment()->associate($comment2)->save();\n    }\n\n    public function test()\n    {\n        /** @var Post $post */\n        $post = Post::first();\n        $this->assertEquals(2, $post->commentLikes()->count());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n\n    public function likes()\n    {\n        return $this->hasMany(Like::class);\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    protected $withCount = ['comments'];\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n\n    public function commentLikes()\n    {\n        return $this->through($this->comments())->has('likes');\n    }\n\n    public function texts()\n    {\n        return $this->hasMany(Text::class);\n    }\n}\n\nclass OtherCommentable extends Model\n{\n    public $timestamps = false;\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n}\n\nclass Text extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n}\n\nclass Like extends Model\n{\n    public $timestamps = false;\n\n    public function comment()\n    {\n        return $this->belongsTo(Comment::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTouchParentWithGlobalScopeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentTouchParentWithGlobalScopeTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentTouchParentWithGlobalScopeTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('post_id');\n            $table->string('title');\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicCreateAndRetrieve()\n    {\n        $post = Post::create(['title' => Str::random(), 'updated_at' => '2016-10-10 10:10:10']);\n\n        $this->assertSame('2016-10-10', $post->fresh()->updated_at->toDateString());\n\n        $post->comments()->create(['title' => Str::random()]);\n\n        $this->assertNotSame('2016-10-10', $post->fresh()->updated_at->toDateString());\n    }\n}\n\nclass Post extends Model\n{\n    public $table = 'posts';\n    public $timestamps = true;\n    protected $guarded = [];\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class, 'post_id');\n    }\n\n    public static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('age', function ($builder) {\n            $builder->join('comments', 'comments.post_id', '=', 'posts.id');\n        });\n    }\n}\n\nclass Comment extends Model\n{\n    public $table = 'comments';\n    public $timestamps = true;\n    protected $guarded = [];\n    protected $touches = ['post'];\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class, 'post_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nclass EloquentTransactionWithAfterCommitTest extends DatabaseTestCase\n{\n    use EloquentTransactionWithAfterCommitTests;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitTests.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Concerns\\WithLaravelMigrations;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\ntrait EloquentTransactionWithAfterCommitTests\n{\n    use WithLaravelMigrations;\n\n    protected function setUpEloquentTransactionWithAfterCommitTests(): void\n    {\n        User::unguard();\n    }\n\n    protected function tearDownEloquentTransactionWithAfterCommitTests(): void\n    {\n        User::reguard();\n    }\n\n    public function testObserverIsCalledOnTestsWithAfterCommit()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserver::resetting());\n\n        $user1 = User::create(UserFactory::new()->raw());\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n    }\n\n    public function testObserverCalledWithAfterCommitWhenInsideTransaction()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserver::resetting());\n\n        $user1 = DB::transaction(fn () => User::create(UserFactory::new()->raw()));\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n    }\n\n    public function testObserverCalledWithAfterCommitWhenInsideTransactionWithDispatchSync()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserverUsingDispatchSync::resetting());\n\n        $user1 = DB::transaction(fn () => User::create(UserFactory::new()->raw()));\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n\n        $this->assertDatabaseHas('password_reset_tokens', [\n            'email' => $user1->email,\n            'token' => sha1($user1->email),\n        ]);\n    }\n\n    public function testObserverIsCalledOnTestsWithAfterCommitWhenUsingSavepoint()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserver::resetting());\n\n        $user1 = User::createOrFirst(UserFactory::new()->raw());\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n    }\n\n    public function testObserverIsCalledOnTestsWithAfterCommitWhenUsingSavepointAndInsideTransaction()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserver::resetting());\n\n        $user1 = DB::transaction(fn () => User::createOrFirst(UserFactory::new()->raw()));\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n    }\n\n    public function testObserverIsCalledEvenWhenDeeplyNestingTransactions()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUserObserver::resetting());\n\n        $user1 = DB::transaction(function () use ($observer) {\n            return tap(DB::transaction(function () use ($observer) {\n                return tap(DB::transaction(function () use ($observer) {\n                    return tap(User::createOrFirst(UserFactory::new()->raw()), function () use ($observer) {\n                        $this->assertEquals(0, $observer::$calledTimes, 'Should not have been called');\n                    });\n                }), function () use ($observer) {\n                    $this->assertEquals(0, $observer::$calledTimes, 'Should not have been called');\n                });\n            }), function () use ($observer) {\n                $this->assertEquals(0, $observer::$calledTimes, 'Should not have been called');\n            });\n        });\n\n        $this->assertTrue($user1->exists);\n        $this->assertEquals(1, $observer::$calledTimes, 'Failed to assert the observer was called once.');\n    }\n\n    public function testAfterCommitObserverCreatingEventFiresImmediately()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsCreatingObserver::resetting());\n\n        DB::transaction(function () use ($observer) {\n            User::create(UserFactory::new()->raw());\n\n            $this->assertTrue($observer::$creatingCalled, 'creating should fire immediately inside the transaction');\n            $this->assertFalse($observer::$createdCalled, 'created should not fire until after commit');\n        });\n\n        $this->assertTrue($observer::$createdCalled, 'created should fire after commit');\n    }\n\n    public function testAfterCommitObserverUpdatingEventFiresImmediately()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsUpdatingObserver::resetting());\n\n        $user = User::create(UserFactory::new()->raw());\n\n        DB::transaction(function () use ($user, $observer) {\n            $user->update(['name' => 'Updated Name']);\n\n            $this->assertTrue($observer::$updatingCalled, 'updating should fire immediately inside the transaction');\n            $this->assertFalse($observer::$updatedCalled, 'updated should not fire until after commit');\n        });\n\n        $this->assertTrue($observer::$updatedCalled, 'updated should fire after commit');\n    }\n\n    public function testAfterCommitObserverCreatingCanCancelOperation()\n    {\n        User::observe($observer = EloquentTransactionWithAfterCommitTestsCancellingObserver::resetting());\n\n        $user = DB::transaction(fn () => User::create(UserFactory::new()->raw()));\n\n        $this->assertFalse($user->exists, 'Model should not be persisted when creating returns false');\n        $this->assertTrue($observer::$creatingCalled, 'creating should have been called');\n        $this->assertFalse($observer::$createdCalled, 'created should not fire when creating was cancelled');\n    }\n\n    public function testTransactionCallbackExceptions()\n    {\n        [$firstObject, $secondObject] = [\n            new EloquentTransactionWithAfterCommitTestsTestObjectForTransactions(),\n            new EloquentTransactionWithAfterCommitTestsTestObjectForTransactions(),\n        ];\n\n        $rootTransactionLevel = DB::transactionLevel();\n\n        // After commit callbacks may fail with an exception. When they do, the rest of the callbacks are not\n        // executed. It's important that the transaction would already be committed by that point, so the\n        // transaction level should be modified before executing any callbacks. Also, exceptions in the\n        // callbacks should not affect the connection's transaction level.\n        $this->assertThrows(function () use ($rootTransactionLevel, $secondObject, $firstObject) {\n            DB::transaction(function () use ($rootTransactionLevel, $firstObject, $secondObject) {\n                DB::transaction(function () use ($rootTransactionLevel, $firstObject) {\n                    $this->assertSame($rootTransactionLevel + 2, DB::transactionLevel());\n\n                    DB::afterCommit(function () use ($rootTransactionLevel, $firstObject) {\n                        $this->assertSame($rootTransactionLevel, DB::transactionLevel());\n\n                        $firstObject->handle();\n                    });\n                });\n\n                $this->assertSame($rootTransactionLevel + 1, DB::transactionLevel());\n\n                DB::afterCommit(fn () => throw new \\RuntimeException());\n                DB::afterCommit(fn () => $secondObject->handle());\n            });\n        }, \\RuntimeException::class);\n\n        $this->assertSame($rootTransactionLevel, DB::transactionLevel());\n\n        $this->assertTrue($firstObject->ran);\n        $this->assertFalse($secondObject->ran);\n        $this->assertEquals(1, $firstObject->runs);\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsUserObserver\n{\n    public static $calledTimes = 0;\n\n    public $afterCommit = true;\n\n    public static function resetting()\n    {\n        static::$calledTimes = 0;\n\n        return new static();\n    }\n\n    public function created($user)\n    {\n        static::$calledTimes++;\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsUserObserverUsingDispatchSync extends EloquentTransactionWithAfterCommitTestsUserObserver\n{\n    public function created($user)\n    {\n        dispatch_sync(new EloquentTransactionWithAfterCommitTestsJob($user->email));\n\n        parent::created($user);\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function __construct(public string $email)\n    {\n        // ...\n    }\n\n    public function handle(): void\n    {\n        DB::transaction(function () {\n            DB::table('password_reset_tokens')->insert([\n                ['email' => $this->email, 'token' => sha1($this->email), 'created_at' => Carbon::now()],\n            ]);\n        });\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsTestObjectForTransactions\n{\n    public $ran = false;\n\n    public $runs = 0;\n\n    public function handle()\n    {\n        $this->ran = true;\n        $this->runs++;\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsCreatingObserver\n{\n    public static $creatingCalled = false;\n\n    public static $createdCalled = false;\n\n    public $afterCommit = true;\n\n    public static function resetting()\n    {\n        static::$creatingCalled = false;\n        static::$createdCalled = false;\n\n        return new static();\n    }\n\n    public function creating($user)\n    {\n        static::$creatingCalled = true;\n    }\n\n    public function created($user)\n    {\n        static::$createdCalled = true;\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsUpdatingObserver\n{\n    public static $updatingCalled = false;\n\n    public static $updatedCalled = false;\n\n    public $afterCommit = true;\n\n    public static function resetting()\n    {\n        static::$updatingCalled = false;\n        static::$updatedCalled = false;\n\n        return new static();\n    }\n\n    public function updating($user)\n    {\n        static::$updatingCalled = true;\n    }\n\n    public function updated($user)\n    {\n        static::$updatedCalled = true;\n    }\n}\n\nclass EloquentTransactionWithAfterCommitTestsCancellingObserver\n{\n    public static $creatingCalled = false;\n\n    public static $createdCalled = false;\n\n    public $afterCommit = true;\n\n    public static function resetting()\n    {\n        static::$creatingCalled = false;\n        static::$createdCalled = false;\n\n        return new static();\n    }\n\n    public function creating($user)\n    {\n        static::$creatingCalled = true;\n\n        return false;\n    }\n\n    public function created($user)\n    {\n        static::$createdCalled = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseMigrationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\n\nclass EloquentTransactionWithAfterCommitUsingDatabaseMigrationsTest extends DatabaseTestCase\n{\n    use EloquentTransactionWithAfterCommitTests;\n    use DatabaseMigrations;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseTransactions;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest extends TestCase\n{\n    use EloquentTransactionWithAfterCommitTests;\n    use DatabaseTransactions;\n\n    /**\n     * The current database driver.\n     *\n     * @return string\n     */\n    protected $driver;\n\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            foreach (array_keys($this->app['db']->getConnections()) as $name) {\n                $this->app['db']->purge($name);\n            }\n        });\n\n        parent::setUp();\n\n        if ($this->usesSqliteInMemoryDatabaseConnection()) {\n            $this->markTestSkipped('Test cannot be used with in-memory SQLite connection.');\n        }\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $connection = $app->make('config')->get('database.default');\n\n        $this->driver = $app['config']->get(\"database.connections.$connection.driver\");\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitUsingRefreshDatabaseOnMultipleConnectionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\n\nuse function Orchestra\\Testbench\\artisan;\n\n#[WithConfig('database.connections.second', ['driver' => 'sqlite', 'database' => ':memory:', 'foreign_key_constraints' => false])]\nclass EloquentTransactionWithAfterCommitUsingRefreshDatabaseOnMultipleConnectionsTest extends EloquentTransactionWithAfterCommitUsingRefreshDatabaseTest\n{\n    /** {@inheritDoc} */\n    protected function connectionsToTransact()\n    {\n        return [null, 'second'];\n    }\n\n    /** {@inheritDoc} */\n    protected function afterRefreshingDatabase()\n    {\n        artisan($this, 'migrate', ['--database' => 'second']);\n    }\n\n    public function testAfterCommitCallbacksAreCalledCorrectlyWhenNoAppTransaction()\n    {\n        $called = false;\n\n        DB::afterCommit(function () use (&$called) {\n            $called = true;\n        });\n\n        $this->assertTrue($called);\n    }\n\n    public function testAfterCommitCallbacksAreCalledWithWrappingTransactionsCorrectly()\n    {\n        $calls = [];\n\n        DB::transaction(function () use (&$calls) {\n            DB::afterCommit(function () use (&$calls) {\n                $calls[] = 'first transaction callback';\n            });\n\n            DB::connection('second')->transaction(function () use (&$calls) {\n                DB::connection('second')->afterCommit(function () use (&$calls) {\n                    $calls[] = 'second transaction callback';\n                });\n            });\n        });\n\n        $this->assertEquals([\n            'second transaction callback',\n            'first transaction callback',\n        ], $calls);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentTransactionWithAfterCommitUsingRefreshDatabaseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Orchestra\\Testbench\\TestCase;\n\nclass EloquentTransactionWithAfterCommitUsingRefreshDatabaseTest extends TestCase\n{\n    use EloquentTransactionWithAfterCommitTests;\n    use RefreshDatabase;\n\n    /**\n     * The current database driver.\n     *\n     * @return string\n     */\n    protected $driver;\n\n    /** {@inheritDoc} */\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            foreach (array_keys($this->app['db']->getConnections()) as $name) {\n                $this->app['db']->purge($name);\n            }\n        });\n\n        parent::setUp();\n    }\n\n    /** {@inheritDoc} */\n    protected function defineEnvironment($app)\n    {\n        $connection = $app['config']->get('database.default');\n\n        $this->driver = $app['config']->get(\"database.connections.$connection.driver\");\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentUniqueStringPrimaryKeysTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass EloquentUniqueStringPrimaryKeysTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->uuid('id')->primary();\n            $table->uuid('foo');\n            $table->uuid('bar');\n            $table->timestamps();\n        });\n\n        Schema::create('foo', function (Blueprint $table) {\n            $table->uuid('id')->primary();\n            $table->string('email')->unique();\n            $table->string('name');\n            $table->timestamps();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->ulid('id')->primary();\n            $table->ulid('foo');\n            $table->ulid('bar');\n            $table->timestamps();\n        });\n\n        Schema::create('songs', function (Blueprint $table) {\n            $table->id();\n            $table->uuid('foo');\n            $table->uuid('bar');\n            $table->timestamps();\n        });\n\n        Schema::create('pictures', function (Blueprint $table) {\n            $table->uuid('uuid')->primary();\n            $table->timestamps();\n        });\n    }\n\n    public function testModelWithUuidPrimaryKeyCanBeCreated()\n    {\n        $user = ModelWithUuidPrimaryKey::create();\n\n        $this->assertTrue(Str::isUuid($user->id));\n        $this->assertTrue(Str::isUuid($user->foo));\n        $this->assertTrue(Str::isUuid($user->bar));\n    }\n\n    public function testModelWithUlidPrimaryKeyCanBeCreated()\n    {\n        $user = ModelWithUlidPrimaryKey::create();\n\n        $this->assertTrue(Str::isUlid($user->id));\n        $this->assertTrue(Str::isUlid($user->foo));\n        $this->assertTrue(Str::isUlid($user->bar));\n    }\n\n    public function testModelWithoutUuidPrimaryKeyCanBeCreated()\n    {\n        $user = ModelWithoutUuidPrimaryKey::create();\n\n        $this->assertTrue(is_int($user->id));\n        $this->assertTrue(Str::isUuid($user->foo));\n        $this->assertTrue(Str::isUuid($user->bar));\n    }\n\n    public function testModelWithCustomUuidPrimaryKeyNameCanBeCreated()\n    {\n        $user = ModelWithCustomUuidPrimaryKeyName::create();\n\n        $this->assertTrue(Str::isUuid($user->uuid));\n    }\n\n    public function testModelWithUuidPrimaryKeyCanBeCreatedQuietly()\n    {\n        $user = new ModelWithUuidPrimaryKey();\n\n        $user->saveQuietly();\n\n        $this->assertTrue(Str::isUuid($user->id));\n        $this->assertTrue(Str::isUuid($user->foo));\n        $this->assertTrue(Str::isUuid($user->bar));\n    }\n\n    public function testModelWithUlidPrimaryKeyCanBeCreatedQuietly()\n    {\n        $user = new ModelWithUlidPrimaryKey();\n\n        $user->saveQuietly();\n\n        $this->assertTrue(Str::isUlid($user->id));\n        $this->assertTrue(Str::isUlid($user->foo));\n        $this->assertTrue(Str::isUlid($user->bar));\n    }\n\n    public function testModelWithoutUuidPrimaryKeyCanBeCreatedQuietly()\n    {\n        $user = new ModelWithoutUuidPrimaryKey();\n\n        $user->saveQuietly();\n\n        $this->assertTrue(is_int($user->id));\n        $this->assertTrue(Str::isUuid($user->foo));\n        $this->assertTrue(Str::isUuid($user->bar));\n    }\n\n    public function testModelWithCustomUuidPrimaryKeyNameCanBeCreatedQuietly()\n    {\n        $user = new ModelWithCustomUuidPrimaryKeyName();\n\n        $user->saveQuietly();\n\n        $this->assertTrue(Str::isUuid($user->uuid));\n    }\n\n    public function testUpsertWithUuidPrimaryKey()\n    {\n        ModelUpsertWithUuidPrimaryKey::create(['email' => 'foo', 'name' => 'bar']);\n        ModelUpsertWithUuidPrimaryKey::create(['name' => 'bar1', 'email' => 'foo2']);\n\n        ModelUpsertWithUuidPrimaryKey::upsert([['email' => 'foo3', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], ['email']);\n\n        $this->assertEquals(3, ModelUpsertWithUuidPrimaryKey::count());\n    }\n}\n\nclass ModelWithUuidPrimaryKey extends Eloquent\n{\n    use HasUuids;\n\n    protected $table = 'users';\n\n    protected $guarded = [];\n\n    public function uniqueIds()\n    {\n        return [$this->getKeyName(), 'foo', 'bar'];\n    }\n}\n\nclass ModelUpsertWithUuidPrimaryKey extends Eloquent\n{\n    use HasUuids;\n\n    protected $table = 'foo';\n\n    protected $guarded = [];\n\n    public function uniqueIds()\n    {\n        return [$this->getKeyName()];\n    }\n}\n\nclass ModelWithUlidPrimaryKey extends Eloquent\n{\n    use HasUlids;\n\n    protected $table = 'posts';\n\n    protected $guarded = [];\n\n    public function uniqueIds()\n    {\n        return [$this->getKeyName(), 'foo', 'bar'];\n    }\n}\n\nclass ModelWithoutUuidPrimaryKey extends Eloquent\n{\n    use HasUuids;\n\n    protected $table = 'songs';\n\n    protected $guarded = [];\n\n    public function uniqueIds()\n    {\n        return ['foo', 'bar'];\n    }\n}\n\nclass ModelWithCustomUuidPrimaryKeyName extends Eloquent\n{\n    use HasUuids;\n\n    protected $table = 'pictures';\n\n    protected $guarded = [];\n\n    protected $primaryKey = 'uuid';\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentUpdateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass EloquentUpdateTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('test_model1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name')->nullable();\n            $table->string('title')->nullable();\n        });\n\n        Schema::create('test_model2', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('job')->nullable();\n            $table->softDeletes();\n            $table->timestamps();\n        });\n\n        Schema::create('test_model3', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('counter');\n            $table->softDeletes();\n            $table->timestamps();\n        });\n    }\n\n    public function testBasicUpdate()\n    {\n        TestUpdateModel1::create([\n            'name' => Str::random(),\n            'title' => 'Ms.',\n        ]);\n\n        TestUpdateModel1::where('title', 'Ms.')->delete();\n\n        $this->assertCount(0, TestUpdateModel1::all());\n    }\n\n    public function testUpdateWithLimitsAndOrders()\n    {\n        if ($this->driver === 'sqlsrv') {\n            $this->markTestSkipped('The limit keyword is not supported on MSSQL.');\n        }\n\n        for ($i = 1; $i <= 10; $i++) {\n            TestUpdateModel1::create();\n        }\n\n        TestUpdateModel1::latest('id')->limit(3)->update(['title' => 'Dr.']);\n\n        $this->assertSame('Dr.', TestUpdateModel1::find(8)->title);\n        $this->assertNotSame('Dr.', TestUpdateModel1::find(7)->title);\n    }\n\n    public function testUpdatedAtWithJoins()\n    {\n        TestUpdateModel1::create([\n            'name' => 'Abdul',\n            'title' => 'Mr.',\n        ]);\n\n        TestUpdateModel2::create([\n            'name' => Str::random(),\n        ]);\n\n        TestUpdateModel2::join('test_model1', function ($join) {\n            $join->on('test_model1.id', '=', 'test_model2.id')\n                ->where('test_model1.title', '=', 'Mr.');\n        })->update(['test_model2.name' => 'Abdul', 'job' => 'Engineer']);\n\n        $record = TestUpdateModel2::find(1);\n\n        $this->assertSame('Engineer: Abdul', $record->job.': '.$record->name);\n    }\n\n    public function testSoftDeleteWithJoins()\n    {\n        TestUpdateModel1::create([\n            'name' => Str::random(),\n            'title' => 'Mr.',\n        ]);\n\n        TestUpdateModel2::create([\n            'name' => Str::random(),\n        ]);\n\n        TestUpdateModel2::join('test_model1', function ($join) {\n            $join->on('test_model1.id', '=', 'test_model2.id')\n                ->where('test_model1.title', '=', 'Mr.');\n        })->delete();\n\n        $this->assertCount(0, TestUpdateModel2::all());\n    }\n\n    public function testIncrement()\n    {\n        TestUpdateModel3::create([\n            'counter' => 0,\n        ]);\n\n        TestUpdateModel3::create([\n            'counter' => 0,\n        ])->delete();\n\n        TestUpdateModel3::increment('counter');\n\n        $models = TestUpdateModel3::withoutGlobalScopes()->orderBy('id')->get();\n        $this->assertEquals(1, $models[0]->counter);\n        $this->assertEquals(0, $models[1]->counter);\n    }\n\n    public function testIncrementOrDecrementIgnoresGlobalScopes()\n    {\n        /** @var TestUpdateModel3 $deletedModel */\n        $deletedModel = tap(TestUpdateModel3::create([\n            'counter' => 0,\n        ]), fn ($model) => $model->delete());\n\n        $deletedModel->increment('counter');\n\n        $this->assertEquals(1, $deletedModel->counter);\n\n        $deletedModel->fresh();\n        $this->assertEquals(1, $deletedModel->counter);\n\n        $deletedModel->decrement('counter');\n        $this->assertEquals(0, $deletedModel->fresh()->counter);\n    }\n\n    public function testUpdateSyncsPrevious()\n    {\n        $model = TestUpdateModel1::create([\n            'name' => Str::random(),\n            'title' => 'Ms.',\n        ]);\n\n        $model->update(['title' => 'Dr.']);\n\n        $this->assertSame('Dr.', $model->title);\n        $this->assertSame('Dr.', $model->getOriginal('title'));\n        $this->assertSame(['title' => 'Dr.'], $model->getChanges());\n        $this->assertSame(['title' => 'Ms.'], $model->getPrevious());\n    }\n\n    public function testSaveSyncsPrevious()\n    {\n        $model = TestUpdateModel1::create([\n            'name' => Str::random(),\n            'title' => 'Ms.',\n        ]);\n\n        $model->title = 'Dr.';\n        $model->save();\n\n        $this->assertSame('Dr.', $model->title);\n        $this->assertSame('Dr.', $model->getOriginal('title'));\n        $this->assertSame(['title' => 'Dr.'], $model->getChanges());\n        $this->assertSame(['title' => 'Ms.'], $model->getPrevious());\n    }\n\n    public function testIncrementSyncsPrevious()\n    {\n        $model = TestUpdateModel3::create([\n            'counter' => 0,\n        ]);\n\n        $model->increment('counter');\n\n        $this->assertEquals(1, $model->counter);\n        $this->assertSame(['counter' => 1], $model->getChanges());\n        $this->assertSame(['counter' => 0], $model->getPrevious());\n    }\n}\n\nclass TestUpdateModel1 extends Model\n{\n    public $table = 'test_model1';\n    public $timestamps = false;\n    protected $guarded = [];\n}\n\nclass TestUpdateModel2 extends Model\n{\n    use SoftDeletes;\n\n    public $table = 'test_model2';\n    protected $fillable = ['name'];\n}\n\nclass TestUpdateModel3 extends Model\n{\n    use SoftDeletes;\n\n    public $table = 'test_model3';\n    protected $fillable = ['counter'];\n    protected $casts = ['deleted_at' => 'datetime'];\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentWhereHasMorphTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentWhereHasMorphTest;\n\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentWhereHasMorphTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->softDeletes();\n        });\n\n        Schema::create('videos', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->nullableMorphs('commentable');\n            $table->softDeletes();\n        });\n\n        $models = [];\n\n        $models[] = Post::create(['title' => 'foo']);\n        $models[] = Post::create(['title' => 'bar']);\n        $models[] = Post::create(['title' => 'baz']);\n        end($models)->delete();\n\n        $models[] = Video::create(['title' => 'foo']);\n        $models[] = Video::create(['title' => 'bar']);\n        $models[] = Video::create(['title' => 'baz']);\n        $models[] = null; // deleted\n        $models[] = null; // deleted\n\n        foreach ($models as $model) {\n            $comment = new Comment();\n            $comment->commentable()->associate($model);\n            $comment->title = 'foo';\n            $comment->save();\n        }\n    }\n\n    public function testWhereHasMorph()\n    {\n        $comments = Comment::whereHasMorph('commentable', [Post::class, Video::class], function (Builder $query) {\n            $query->where('title', 'foo');\n        })->orderBy('id')->get();\n\n        $this->assertEquals([1, 4], $comments->pluck('id')->all());\n    }\n\n    public function testWhereHasMorphWithMorphMap()\n    {\n        Relation::morphMap(['posts' => Post::class]);\n\n        Comment::where('commentable_type', Post::class)->update(['commentable_type' => 'posts']);\n\n        try {\n            $comments = Comment::whereHasMorph('commentable', [Post::class, Video::class], function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n            $this->assertEquals([1, 4], $comments->pluck('id')->all());\n        } finally {\n            Relation::morphMap([], false);\n        }\n    }\n\n    public function testWhereHasMorphWithWildcard()\n    {\n        // Test newModelQuery() without global scopes.\n        Comment::where('commentable_type', Video::class)->delete();\n\n        $comments = Comment::withTrashed()\n            ->whereHasMorph('commentable', '*', function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n        $this->assertEquals([1, 4], $comments->pluck('id')->all());\n    }\n\n    public function testWhereHasMorphWithWildcardAndMorphMap()\n    {\n        Relation::morphMap(['posts' => Post::class]);\n\n        Comment::where('commentable_type', Post::class)->update(['commentable_type' => 'posts']);\n\n        try {\n            $comments = Comment::whereHasMorph('commentable', '*', function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n            $this->assertEquals([1, 4], $comments->pluck('id')->all());\n        } finally {\n            Relation::morphMap([], false);\n        }\n    }\n\n    public function testWhereHasMorphWithWildcardAndOnlyNullMorphTypes()\n    {\n        Comment::whereNotNull('commentable_type')->forceDelete();\n\n        $comments = Comment::query()\n            ->whereHasMorph('commentable', '*', function (Builder $query) {\n                $query->where('title', 'foo');\n            })\n            ->orderBy('id')->get();\n\n        $this->assertEmpty($comments->pluck('id')->all());\n    }\n\n    public function testWhereHasMorphWithRelationConstraint()\n    {\n        $comments = Comment::whereHasMorph('commentableWithConstraint', Video::class, function (Builder $query) {\n            $query->where('title', 'like', 'ba%');\n        })->orderBy('id')->get();\n\n        $this->assertEquals([5], $comments->pluck('id')->all());\n    }\n\n    public function testWhereHasMorphWitDifferentConstraints()\n    {\n        $comments = Comment::whereHasMorph('commentable', [Post::class, Video::class], function (Builder $query, $type) {\n            if ($type === Post::class) {\n                $query->where('title', 'foo');\n            }\n\n            if ($type === Video::class) {\n                $query->where('title', 'bar');\n            }\n        })->orderBy('id')->get();\n\n        $this->assertEquals([1, 5], $comments->pluck('id')->all());\n    }\n\n    public function testWhereHasMorphWithOwnerKey()\n    {\n        Schema::table('posts', function (Blueprint $table) {\n            $table->string('slug')->nullable();\n        });\n\n        Schema::table('comments', function (Blueprint $table) {\n            $table->dropIndex('comments_commentable_type_commentable_id_index');\n        });\n\n        Schema::table('comments', function (Blueprint $table) {\n            $table->string('commentable_id')->nullable()->change();\n        });\n\n        Post::where('id', 1)->update(['slug' => 'foo']);\n\n        Comment::where('id', 1)->update(['commentable_id' => 'foo']);\n\n        $comments = Comment::whereHasMorph('commentableWithOwnerKey', Post::class, function (Builder $query) {\n            $query->where('title', 'foo');\n        })->orderBy('id')->get();\n\n        $this->assertEquals([1], $comments->pluck('id')->all());\n    }\n\n    public function testHasMorph()\n    {\n        $comments = Comment::hasMorph('commentable', Post::class)->orderBy('id')->get();\n\n        $this->assertEquals([1, 2], $comments->pluck('id')->all());\n    }\n\n    public function testOrHasMorph()\n    {\n        $comments = Comment::where('id', 1)->orHasMorph('commentable', Video::class)->orderBy('id')->get();\n\n        $this->assertEquals([1, 4, 5, 6], $comments->pluck('id')->all());\n    }\n\n    public function testDoesntHaveMorph()\n    {\n        $comments = Comment::doesntHaveMorph('commentable', Post::class)->orderBy('id')->get();\n\n        $this->assertEquals([3], $comments->pluck('id')->all());\n    }\n\n    public function testOrDoesntHaveMorph()\n    {\n        $comments = Comment::where('id', 1)->orDoesntHaveMorph('commentable', Post::class)->orderBy('id')->get();\n\n        $this->assertEquals([1, 3], $comments->pluck('id')->all());\n    }\n\n    public function testOrWhereHasMorph()\n    {\n        $comments = Comment::where('id', 1)\n            ->orWhereHasMorph('commentable', Video::class, function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n        $this->assertEquals([1, 4], $comments->pluck('id')->all());\n    }\n\n    public function testOrWhereHasMorphWithWildcardAndOnlyNullMorphTypes()\n    {\n        Comment::whereNotNull('commentable_type')->forceDelete();\n\n        $comments = Comment::where('id', 7)\n            ->orWhereHasMorph('commentable', '*', function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n        $this->assertEquals([7], $comments->pluck('id')->all());\n    }\n\n    public function testWhereDoesntHaveMorph()\n    {\n        $comments = Comment::whereDoesntHaveMorph('commentable', Post::class, function (Builder $query) {\n            $query->where('title', 'foo');\n        })->orderBy('id')->get();\n\n        $this->assertEquals([2, 3], $comments->pluck('id')->all());\n    }\n\n    public function testWhereDoesntHaveMorphWithWildcardAndOnlyNullMorphTypes()\n    {\n        Comment::whereNotNull('commentable_type')->forceDelete();\n\n        $comments = Comment::whereDoesntHaveMorph('commentable', [], function (Builder $query) {\n            $query->where('title', 'foo');\n        })->orderBy('id')->get();\n\n        $this->assertEquals([7, 8], $comments->pluck('id')->all());\n    }\n\n    public function testOrWhereDoesntHaveMorph()\n    {\n        $comments = Comment::where('id', 1)\n            ->orWhereDoesntHaveMorph('commentable', Post::class, function (Builder $query) {\n                $query->where('title', 'foo');\n            })->orderBy('id')->get();\n\n        $this->assertEquals([1, 2, 3], $comments->pluck('id')->all());\n    }\n\n    public function testModelScopesAreAccessible()\n    {\n        $comments = Comment::whereHasMorph('commentable', [Post::class, Video::class], function (Builder $query) {\n            $query->someSharedModelScope();\n        })->orderBy('id')->get();\n\n        $this->assertEquals([1, 4], $comments->pluck('id')->all());\n    }\n\n    public function testWhereDoesntHaveMorphWithNullableMorph()\n    {\n        $comments = Comment::whereDoesntHaveMorph('commentable', '*')->orderBy('id')->get();\n\n        $this->assertEquals([3, 7, 8], $comments->pluck('id')->all());\n    }\n\n    public function testWhereDoesntHaveMorphWithNullableMorphAndAdditionalWhereIsLogicallyGrouped()\n    {\n        $commentsWhereFirst = Comment::whereNot('title', 'foo')\n            ->whereDoesntHaveMorph('commentable', '*')\n            ->orderBy('id')\n            ->get();\n\n        $commentsWhereLast = Comment::whereDoesntHaveMorph('commentable', '*')\n            ->whereNot('title', 'foo')\n            ->orderBy('id')\n            ->get();\n\n        $this->assertCount(0, $commentsWhereFirst);\n        $this->assertCount(0, $commentsWhereLast);\n    }\n}\n\nclass Comment extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n\n    public function commentableWithConstraint()\n    {\n        return $this->morphTo('commentable')->where('title', 'bar');\n    }\n\n    public function commentableWithOwnerKey()\n    {\n        return $this->morphTo('commentable', null, null, 'slug');\n    }\n}\n\nclass Post extends Model\n{\n    use SoftDeletes;\n\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function scopeSomeSharedModelScope($query)\n    {\n        $query->where('title', '=', 'foo');\n    }\n}\n\nclass Video extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function scopeSomeSharedModelScope($query)\n    {\n        $query->where('title', '=', 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentWhereHasTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentWhereHasTest;\n\nuse Illuminate\\Database\\Eloquent\\Builder as EloquentBuilder;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Query\\Builder as QueryBuilder;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass EloquentWhereHasTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('user_id');\n            $table->boolean('public');\n        });\n\n        Schema::create('texts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('post_id');\n            $table->text('content');\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('commentable_type');\n            $table->integer('commentable_id');\n        });\n\n        $user = User::create();\n        $post = tap((new Post(['public' => true]))->user()->associate($user))->save();\n        (new Comment)->commentable()->associate($post)->save();\n        (new Text(['content' => 'test']))->post()->associate($post)->save();\n\n        $user = User::create();\n        $post = tap((new Post(['public' => false]))->user()->associate($user))->save();\n        (new Comment)->commentable()->associate($post)->save();\n        (new Text(['content' => 'test2']))->post()->associate($post)->save();\n    }\n\n    /**\n     * Check that the 'whereRelation' callback function works.\n     */\n    #[DataProvider('dataProviderWhereRelationCallback')]\n    public function testWhereRelationCallback($callbackEloquent, $callbackQuery)\n    {\n        $userWhereRelation = User::whereRelation('posts', $callbackEloquent);\n        $userWhereHas = User::whereHas('posts', $callbackEloquent);\n        $query = DB::table('users')->whereExists($callbackQuery);\n\n        $this->assertEquals($userWhereRelation->getQuery()->toSql(), $query->toSql());\n        $this->assertEquals($userWhereRelation->getQuery()->toSql(), $userWhereHas->toSql());\n        $this->assertEquals($userWhereHas->getQuery()->toSql(), $query->toSql());\n\n        $this->assertEquals($userWhereRelation->first()->id, $query->first()->id);\n        $this->assertEquals($userWhereRelation->first()->id, $userWhereHas->first()->id);\n        $this->assertEquals($userWhereHas->first()->id, $query->first()->id);\n    }\n\n    /**\n     * Check that the 'orWhereRelation' callback function works.\n     */\n    #[DataProvider('dataProviderWhereRelationCallback')]\n    public function testOrWhereRelationCallback($callbackEloquent, $callbackQuery)\n    {\n        $userOrWhereRelation = User::orWhereRelation('posts', $callbackEloquent);\n        $userOrWhereHas = User::orWhereHas('posts', $callbackEloquent);\n        $query = DB::table('users')->orWhereExists($callbackQuery);\n\n        $this->assertEquals($userOrWhereRelation->getQuery()->toSql(), $query->toSql());\n        $this->assertEquals($userOrWhereRelation->getQuery()->toSql(), $userOrWhereHas->toSql());\n        $this->assertEquals($userOrWhereHas->getQuery()->toSql(), $query->toSql());\n\n        $this->assertEquals($userOrWhereRelation->first()->id, $query->first()->id);\n        $this->assertEquals($userOrWhereRelation->first()->id, $userOrWhereHas->first()->id);\n        $this->assertEquals($userOrWhereHas->first()->id, $query->first()->id);\n    }\n\n    /**\n     * Check that the 'whereDoesntHaveRelation' callback function works.\n     */\n    #[DataProvider('dataProviderWhereRelationCallback')]\n    public function testWhereDoesntRelationCallback($callbackEloquent, $callbackQuery)\n    {\n        $userWhereDoesntRelation = User::whereDoesntHaveRelation('posts', $callbackEloquent);\n        $userWhereHas = User::whereDoesntHave('posts', $callbackEloquent);\n        $query = DB::table('users')->whereNotExists($callbackQuery);\n\n        $this->assertEquals($userWhereDoesntRelation->getQuery()->toSql(), $query->toSql());\n        $this->assertEquals($userWhereDoesntRelation->getQuery()->toSql(), $userWhereHas->toSql());\n        $this->assertEquals($userWhereHas->getQuery()->toSql(), $query->toSql());\n\n        $this->assertEquals($userWhereDoesntRelation->first()->id, $query->first()->id);\n        $this->assertEquals($userWhereDoesntRelation->first()->id, $userWhereHas->first()->id);\n        $this->assertEquals($userWhereHas->first()->id, $query->first()->id);\n    }\n\n    /**\n     * Check that the 'orWhereDoesntRelation' callback function works.\n     */\n    #[DataProvider('dataProviderWhereRelationCallback')]\n    public function testOrWhereDoesntRelationCallback($callbackEloquent, $callbackQuery)\n    {\n        $userOrWhereDoesntRelation = User::orWhereDoesntHaveRelation('posts', $callbackEloquent);\n        $userOrWhereHas = User::orWhereDoesntHave('posts', $callbackEloquent);\n        $query = DB::table('users')->orWhereNotExists($callbackQuery);\n\n        $this->assertEquals($userOrWhereDoesntRelation->getQuery()->toSql(), $query->toSql());\n        $this->assertEquals($userOrWhereDoesntRelation->getQuery()->toSql(), $userOrWhereHas->toSql());\n        $this->assertEquals($userOrWhereHas->getQuery()->toSql(), $query->toSql());\n\n        $this->assertEquals($userOrWhereDoesntRelation->first()->id, $query->first()->id);\n        $this->assertEquals($userOrWhereDoesntRelation->first()->id, $userOrWhereHas->first()->id);\n        $this->assertEquals($userOrWhereHas->first()->id, $query->first()->id);\n    }\n\n    public static function dataProviderWhereRelationCallback()\n    {\n        $callbackArray = function ($value) {\n            $callbackEloquent = function (EloquentBuilder $builder) use ($value) {\n                $builder->selectRaw('id')->where('public', $value);\n            };\n\n            $callbackQuery = function (QueryBuilder $builder) use ($value) {\n                $hasMany = app()->make(User::class)->posts();\n\n                $builder->from('posts')->addSelect(['*'])->whereColumn(\n                    $hasMany->getQualifiedParentKeyName(),\n                    '=',\n                    $hasMany->getQualifiedForeignKeyName()\n                );\n\n                $builder->selectRaw('id')->where('public', $value);\n            };\n\n            return [$callbackEloquent, $callbackQuery];\n        };\n\n        return [\n            'Find user with post.public = true' => $callbackArray(true),\n            'Find user with post.public = false' => $callbackArray(false),\n        ];\n    }\n\n    public function testWhereRelation()\n    {\n        $users = User::whereRelation('posts', 'public', true)->get();\n\n        $this->assertEquals([1], $users->pluck('id')->all());\n    }\n\n    public function testOrWhereRelation()\n    {\n        $users = User::whereRelation('posts', 'public', true)->orWhereRelation('posts', 'public', false)->get();\n\n        $this->assertEquals([1, 2], $users->pluck('id')->all());\n    }\n\n    public function testNestedWhereRelation()\n    {\n        $texts = User::whereRelation('posts.texts', 'content', 'test')->get();\n\n        $this->assertEquals([1], $texts->pluck('id')->all());\n    }\n\n    public function testNestedOrWhereRelation()\n    {\n        $texts = User::whereRelation('posts.texts', 'content', 'test')->orWhereRelation('posts.texts', 'content', 'test2')->get();\n\n        $this->assertEquals([1, 2], $texts->pluck('id')->all());\n    }\n\n    public function testWhereMorphRelation()\n    {\n        $comments = Comment::whereMorphRelation('commentable', '*', 'public', true)->get();\n\n        $this->assertEquals([1], $comments->pluck('id')->all());\n    }\n\n    public function testOrWhereMorphRelation()\n    {\n        $comments = Comment::whereMorphRelation('commentable', '*', 'public', true)\n            ->orWhereMorphRelation('commentable', '*', 'public', false)\n            ->get();\n\n        $this->assertEquals([1, 2], $comments->pluck('id')->all());\n    }\n\n    public function testWhereDoesntHaveRelation()\n    {\n        $users = User::whereDoesntHaveRelation('posts', 'public', true)->get();\n\n        $this->assertEquals([2], $users->pluck('id')->all());\n    }\n\n    public function testOrWhereDoesntHaveRelation()\n    {\n        $users = User::whereDoesntHaveRelation('posts', 'public', true)->orWhereDoesntHaveRelation('posts', 'public', false)->get();\n\n        $this->assertEquals([1, 2], $users->pluck('id')->all());\n    }\n\n    public function testNestedWhereDoesntHaveRelation()\n    {\n        $texts = User::whereDoesntHaveRelation('posts.texts', 'content', 'test')->get();\n\n        $this->assertEquals([2], $texts->pluck('id')->all());\n    }\n\n    public function testNestedOrWhereDoesntHaveRelation()\n    {\n        $texts = User::whereDoesntHaveRelation('posts.texts', 'content', 'test')->orWhereDoesntHaveRelation('posts.texts', 'content', 'test2')->get();\n\n        $this->assertEquals([1, 2], $texts->pluck('id')->all());\n    }\n\n    public function testWhereMorphDoesntHaveRelation()\n    {\n        $comments = Comment::whereMorphDoesntHaveRelation('commentable', '*', 'public', true)->get();\n\n        $this->assertEquals([2], $comments->pluck('id')->all());\n    }\n\n    public function testOrWhereMorphDoesntHaveRelation()\n    {\n        $comments = Comment::whereMorphDoesntHaveRelation('commentable', '*', 'public', true)\n            ->orWhereMorphDoesntHaveRelation('commentable', '*', 'public', false)\n            ->get();\n\n        $this->assertEquals([1, 2], $comments->pluck('id')->all());\n    }\n\n    public function testWithCount()\n    {\n        $users = User::whereHas('posts', function ($query) {\n            $query->where('public', true);\n        })->get();\n\n        $this->assertEquals([1], $users->pluck('id')->all());\n    }\n}\n\nclass Comment extends Model\n{\n    public $timestamps = false;\n\n    public function commentable()\n    {\n        return $this->morphTo();\n    }\n}\n\nclass Post extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    protected $withCount = ['comments'];\n\n    public function comments()\n    {\n        return $this->morphMany(Comment::class, 'commentable');\n    }\n\n    public function texts()\n    {\n        return $this->hasMany(Text::class);\n    }\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n\nclass Text extends Model\n{\n    public $timestamps = false;\n\n    protected $guarded = [];\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n\n    public function posts()\n    {\n        return $this->hasMany(Post::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentWhereTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\MultipleRecordsFoundException;\nuse Illuminate\\Database\\Query\\Builder;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentWhereTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('email');\n            $table->string('address');\n        });\n    }\n\n    public function testWhereAndWhereOrBehavior()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $firstUser */\n        $firstUser = UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $secondUser */\n        $secondUser = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        $this->assertTrue($firstUser->is(UserWhereTest::where('name', '=', $firstUser->name)->first()));\n        $this->assertTrue($firstUser->is(UserWhereTest::where('name', $firstUser->name)->first()));\n        $this->assertTrue($firstUser->is(UserWhereTest::where('name', $firstUser->name)->where('email', $firstUser->email)->first()));\n        $this->assertNull(UserWhereTest::where('name', $firstUser->name)->where('email', $secondUser->email)->first());\n        $this->assertTrue($secondUser->is(UserWhereTest::where('name', 'wrong-name')->orWhere('email', $secondUser->email)->first()));\n        $this->assertTrue($firstUser->is(UserWhereTest::where(['name' => 'test-name', 'email' => 'test-email'])->first()));\n        $this->assertNull(UserWhereTest::where(['name' => 'test-name', 'email' => 'test-email1'])->first());\n        $this->assertTrue($secondUser->is(\n            UserWhereTest::where(['name' => 'wrong-name', 'email' => 'test-email1'], null, null, 'or')->first())\n        );\n\n        $this->assertSame(\n            1,\n            UserWhereTest::where(['name' => 'test-name', 'email' => 'test-email1'])\n                ->orWhere(['name' => 'test-name1', 'address' => 'wrong-address'])->count()\n        );\n\n        $this->assertTrue(\n            $secondUser->is(\n                UserWhereTest::where(['name' => 'test-name', 'email' => 'test-email1'])\n                    ->orWhere(['name' => 'test-name1', 'address' => 'wrong-address'])\n                    ->first()\n            )\n        );\n    }\n\n    public function testWhereNot()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $firstUser */\n        $firstUser = UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $secondUser */\n        $secondUser = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        $this->assertTrue($secondUser->is(UserWhereTest::whereNot(function ($query) use ($firstUser) {\n            $query->where('name', '=', $firstUser->name);\n        })->first()));\n        $this->assertTrue($firstUser->is(UserWhereTest::where('name', $firstUser->name)->whereNot(function ($query) use ($secondUser) {\n            $query->where('email', $secondUser->email);\n        })->first()));\n        $this->assertTrue($secondUser->is(UserWhereTest::where('name', 'wrong-name')->orWhereNot(function ($query) use ($firstUser) {\n            $query->where('email', $firstUser->email);\n        })->first()));\n    }\n\n    public function testWhereIn()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user1 */\n        $user1 = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user2 */\n        $user2 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email2',\n            'address' => 'test-address2',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user3 */\n        $user3 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email3',\n            'address' => 'test-address3',\n        ]);\n\n        $this->assertTrue($user2->is(UserWhereTest::whereIn('id', [2])->first()));\n\n        $users = UserWhereTest::query()->whereIn('id', [1, 2, 22])->get();\n\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user2->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $users = UserWhereTest::query()->whereIn('email', ['test-email1', 'test-email2'])->get();\n\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user2->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $users = UserWhereTest::query()\n            ->whereIn('id', [1])\n            ->orWhereIn('email', ['test-email1', 'test-email2'])\n            ->get();\n\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user2->is($users[1]));\n        $this->assertCount(2, $users);\n    }\n\n    public function testWhereInCanAcceptQueryable()\n    {\n        $user1 = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        $user2 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email2',\n            'address' => 'test-address2',\n        ]);\n\n        $user3 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email3',\n            'address' => 'test-address3',\n        ]);\n\n        $query = UserWhereTest::query()->select('name')->where('id', '>', 1);\n\n        $users = UserWhereTest::query()->whereIn('name', $query)->get();\n\n        $this->assertTrue($user2->is($users[0]));\n        $this->assertTrue($user3->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $users = UserWhereTest::query()->whereIn('name', function (Builder $query) {\n            $query->select('name')->where('id', '>', 1);\n        })->get();\n\n        $this->assertTrue($user2->is($users[0]));\n        $this->assertTrue($user3->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $query = DB::table('users')->select('name')->where('id', '=', 1);\n\n        $users = UserWhereTest::query()->whereNotIn('name', $query)->get();\n\n        $this->assertTrue($user2->is($users[0]));\n        $this->assertTrue($user3->is($users[1]));\n        $this->assertCount(2, $users);\n    }\n\n    public function testWhereIntegerInRaw()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user1 */\n        $user1 = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user2 */\n        $user2 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email2',\n            'address' => 'test-address2',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $user3 */\n        $user3 = UserWhereTest::create([\n            'name' => 'test-name2',\n            'email' => 'test-email3',\n            'address' => 'test-address3',\n        ]);\n\n        $users = UserWhereTest::query()->whereIntegerInRaw('id', [1, 2, 5])->get();\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user2->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $users = UserWhereTest::query()->whereIntegerNotInRaw('id', [2])->get();\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user3->is($users[1]));\n        $this->assertCount(2, $users);\n\n        $users = UserWhereTest::query()->whereIntegerInRaw('id', ['1', '2'])->get();\n        $this->assertTrue($user1->is($users[0]));\n        $this->assertTrue($user2->is($users[1]));\n        $this->assertCount(2, $users);\n    }\n\n    public function testFirstWhere()\n    {\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $firstUser */\n        $firstUser = UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        /** @var \\Illuminate\\Tests\\Integration\\Database\\UserWhereTest $secondUser */\n        $secondUser = UserWhereTest::create([\n            'name' => 'test-name1',\n            'email' => 'test-email1',\n            'address' => 'test-address1',\n        ]);\n\n        $this->assertTrue($firstUser->is(UserWhereTest::firstWhere('name', '=', $firstUser->name)));\n        $this->assertTrue($firstUser->is(UserWhereTest::firstWhere('name', $firstUser->name)));\n        $this->assertTrue($firstUser->is(UserWhereTest::where('name', $firstUser->name)->firstWhere('email', $firstUser->email)));\n        $this->assertNull(UserWhereTest::where('name', $firstUser->name)->firstWhere('email', $secondUser->email));\n        $this->assertTrue($firstUser->is(UserWhereTest::firstWhere(['name' => 'test-name', 'email' => 'test-email'])));\n        $this->assertNull(UserWhereTest::firstWhere(['name' => 'test-name', 'email' => 'test-email1']));\n        $this->assertTrue($secondUser->is(\n            UserWhereTest::firstWhere(['name' => 'wrong-name', 'email' => 'test-email1'], null, null, 'or'))\n        );\n    }\n\n    public function testSole()\n    {\n        $expected = UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        $this->assertTrue($expected->is(UserWhereTest::where('name', 'test-name')->sole()));\n    }\n\n    public function testSoleFailsForMultipleRecords()\n    {\n        UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'other-email',\n            'address' => 'other-address',\n        ]);\n\n        $this->expectExceptionObject(new MultipleRecordsFoundException(2));\n\n        UserWhereTest::where('name', 'test-name')->sole();\n    }\n\n    public function testSoleFailsIfNoRecords()\n    {\n        try {\n            UserWhereTest::where('name', 'test-name')->sole();\n        } catch (ModelNotFoundException $exception) {\n            //\n        }\n\n        $this->assertSame(UserWhereTest::class, $exception->getModel());\n    }\n\n    public function testSoleValue()\n    {\n        $expected = UserWhereTest::create([\n            'name' => 'test-name',\n            'email' => 'test-email',\n            'address' => 'test-address',\n        ]);\n\n        $this->assertEquals('test-name', UserWhereTest::where('name', 'test-name')->soleValue('name'));\n    }\n\n    public function testChunkMap()\n    {\n        UserWhereTest::create([\n            'name' => 'first-name',\n            'email' => 'first-email',\n            'address' => 'first-address',\n        ]);\n\n        UserWhereTest::create([\n            'name' => 'second-name',\n            'email' => 'second-email',\n            'address' => 'second-address',\n        ]);\n\n        DB::enableQueryLog();\n\n        $results = UserWhereTest::orderBy('id')->chunkMap(function ($user) {\n            return $user->name;\n        }, 1);\n\n        $this->assertCount(2, $results);\n        $this->assertSame('first-name', $results[0]);\n        $this->assertSame('second-name', $results[1]);\n        $this->assertCount(3, DB::getQueryLog());\n    }\n}\n\nclass UserWhereTest extends Model\n{\n    protected $table = 'users';\n    protected $guarded = [];\n    public $timestamps = false;\n}\n"
  },
  {
    "path": "tests/Integration/Database/EloquentWithCountTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\EloquentWithCountTest;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\n\nclass EloquentWithCountTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('one', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('two', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('one_id');\n        });\n\n        Schema::create('three', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('two_id');\n        });\n\n        Schema::create('four', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('one_id');\n        });\n    }\n\n    public function testItBasic()\n    {\n        $one = Model1::create();\n        $two = $one->twos()->Create();\n        $two->threes()->Create();\n\n        $results = Model1::withCount([\n            'twos' => function ($query) {\n                $query->where('id', '>=', 1);\n            },\n        ]);\n\n        $this->assertEquals([\n            ['id' => 1, 'twos_count' => 1],\n        ], $results->get()->toArray());\n    }\n\n    public function testGlobalScopes()\n    {\n        $one = Model1::create();\n        $one->fours()->create();\n\n        $result = Model1::withCount('fours')->first();\n        $this->assertEquals(0, $result->fours_count);\n\n        $result = Model1::withCount('allFours')->first();\n        $this->assertEquals(1, $result->all_fours_count);\n    }\n\n    public function testSortingScopes()\n    {\n        $one = Model1::create();\n        $one->twos()->create();\n\n        $query = Model1::withCount('twos')->getQuery();\n\n        $this->assertNull($query->orders);\n        $this->assertSame([], $query->getRawBindings()['order']);\n    }\n}\n\nclass Model1 extends Model\n{\n    public $table = 'one';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function twos()\n    {\n        return $this->hasMany(Model2::class, 'one_id');\n    }\n\n    public function fours()\n    {\n        return $this->hasMany(Model4::class, 'one_id');\n    }\n\n    public function allFours()\n    {\n        return $this->fours()->withoutGlobalScopes();\n    }\n}\n\nclass Model2 extends Model\n{\n    public $table = 'two';\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $withCount = ['threes'];\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('app', function ($builder) {\n            $builder->latest();\n        });\n    }\n\n    public function threes()\n    {\n        return $this->hasMany(Model3::class, 'two_id');\n    }\n}\n\nclass Model3 extends Model\n{\n    public $table = 'three';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('app', function ($builder) {\n            $builder->where('id', '>', 0);\n        });\n    }\n}\n\nclass Model4 extends Model\n{\n    public $table = 'four';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('app', function ($builder) {\n            $builder->where('id', '>', 1);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\n\nenum StringStatus: string\n{\n    case draft = 'draft';\n    case pending = 'pending';\n    case done = 'done';\n}\n\nenum IntegerStatus: int\n{\n    case draft = 0;\n    case pending = 1;\n    case done = 2;\n}\n\nenum NonBackedStatus\n{\n    case draft;\n    case pending;\n    case done;\n}\n\nenum ArrayableStatus: string implements Arrayable\n{\n    case pending = 'pending';\n    case done = 'done';\n\n    public function description(): string\n    {\n        return match ($this) {\n            self::pending => 'pending status description',\n            self::done => 'done status description'\n        };\n    }\n\n    public function toArray()\n    {\n        return [\n            'name' => $this->name,\n            'value' => $this->value,\n            'description' => $this->description(),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/EventConnectionEstablishedTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Events\\ConnectionEstablished;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Orchestra\\Testbench\\artisan;\n\nclass EventConnectionEstablishedTest extends TestCase\n{\n    use DatabaseMigrations;\n\n    #[WithMigration]\n    public function testItListenToEstablishedConnectionOnReconnect()\n    {\n        Event::fake([ConnectionEstablished::class]);\n\n        Event::assertNotDispatched(ConnectionEstablished::class);\n\n        artisan($this, 'migrate:fresh');\n\n        Event::assertDispatched(ConnectionEstablished::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Fixtures/NamedScopeUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\Scope;\nuse Illuminate\\Database\\Eloquent\\Builder;\n\nclass NamedScopeUser extends User\n{\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function casts(): array\n    {\n        return [\n            'email_verified_at' => 'datetime',\n            'password' => 'hashed',\n        ];\n    }\n\n    #[Scope]\n    protected function verified(Builder $builder, bool $email = true)\n    {\n        return $builder->when(\n            $email === true,\n            fn ($query) => $query->whereNotNull('email_verified_at'),\n            fn ($query) => $query->whereNull('email_verified_at'),\n        );\n    }\n\n    #[Scope]\n    protected function verifiedWithoutReturn(Builder $builder, bool $email = true)\n    {\n        $this->verified($builder, $email);\n    }\n\n    public function scopeVerifiedUser(Builder $builder, bool $email = true)\n    {\n        return $builder->when(\n            $email === true,\n            fn ($query) => $query->whereNotNull('email_verified_at'),\n            fn ($query) => $query->whereNull('email_verified_at'),\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Fixtures/Post.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Post extends Model\n{\n    public $table = 'posts';\n}\n"
  },
  {
    "path": "tests/Integration/Database/Fixtures/PostStringyKey.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass PostStringyKey extends Model\n{\n    public $table = 'my_posts';\n\n    public $primaryKey = 'my_id';\n}\n"
  },
  {
    "path": "tests/Integration/Database/Fixtures/User.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass User extends Model\n{\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/DatabaseEloquentMariaDbIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseEloquentMariaDbIntegrationTest extends MariaDbTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('database_eloquent_mariadb_integration_users')) {\n            Schema::create('database_eloquent_mariadb_integration_users', function (Blueprint $table) {\n                $table->id();\n                $table->string('name')->nullable();\n                $table->string('email')->unique();\n                $table->timestamps();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('database_eloquent_mariadb_integration_users');\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user1 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user1 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(['email' => 'taylor@laravel.com']);\n\n        DB::transaction(function () use ($user1) {\n            $user2 = DatabaseEloquentMariaDbIntegrationUser::createOrFirst(\n                ['email' => 'taylor@laravel.com'],\n                ['name' => 'Taylor Otwell']\n            );\n\n            $this->assertEquals($user1->id, $user2->id);\n            $this->assertSame('taylor@laravel.com', $user2->email);\n            $this->assertNull($user2->name);\n        });\n    }\n}\n\nclass DatabaseEloquentMariaDbIntegrationUser extends Model\n{\n    protected $table = 'database_eloquent_mariadb_integration_users';\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseEmulatePreparesMariaDbConnectionTest extends DatabaseMariaDbConnectionTest\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.connections.mariadb.options', [\n            PDO::ATTR_EMULATE_PREPARES => true,\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/DatabaseMariaDbConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMariaDbConnectionTest extends MariaDbTestCase\n{\n    const TABLE = 'player';\n    const FLOAT_COL = 'float_col';\n    const JSON_COL = 'json_col';\n    const FLOAT_VAL = 0.2;\n\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable(self::TABLE)) {\n            Schema::create(self::TABLE, function (Blueprint $table) {\n                $table->json(self::JSON_COL)->nullable();\n                $table->float(self::FLOAT_COL)->nullable();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop(self::TABLE);\n    }\n\n    #[DataProvider('floatComparisonsDataProvider')]\n    public function testJsonFloatComparison($value, $operator, $shouldMatch)\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => '{\"rank\":'.self::FLOAT_VAL.'}']);\n\n        $this->assertSame(\n            $shouldMatch,\n            DB::table(self::TABLE)->where(self::JSON_COL.'->rank', $operator, $value)->exists(),\n            self::JSON_COL.'->rank should '.($shouldMatch ? '' : 'not ').\"be $operator $value\"\n        );\n    }\n\n    public static function floatComparisonsDataProvider()\n    {\n        return [\n            [0.2, '=', true],\n            [0.2, '>', false],\n            [0.2, '<', false],\n            [0.1, '=', false],\n            [0.1, '<', false],\n            [0.1, '>', true],\n            [0.3, '=', false],\n            [0.3, '<', true],\n            [0.3, '>', false],\n        ];\n    }\n\n    public function testFloatValueStoredCorrectly()\n    {\n        DB::table(self::TABLE)->insert([self::FLOAT_COL => self::FLOAT_VAL]);\n\n        $this->assertEquals(self::FLOAT_VAL, DB::table(self::TABLE)->value(self::FLOAT_COL));\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => json_encode($value)]);\n\n        $this->assertSame($expected, DB::table(self::TABLE)->whereNull(self::JSON_COL.'->'.$key)->exists());\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNotNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => json_encode($value)]);\n\n        $this->assertSame(! $expected, DB::table(self::TABLE)->whereNotNull(self::JSON_COL.'->'.$key)->exists());\n    }\n\n    public static function jsonWhereNullDataProvider()\n    {\n        return [\n            'key not exists' => [true, 'invalid'],\n            'key exists and null' => [true, 'value', ['value' => null]],\n            'key exists and \"null\"' => [false, 'value', ['value' => 'null']],\n            'key exists and not null' => [false, 'value', ['value' => false]],\n            'nested key not exists' => [true, 'nested->invalid'],\n            'nested key exists and null' => [true, 'nested->value', ['nested' => ['value' => null]]],\n            'nested key exists and \"null\"' => [false, 'nested->value', ['nested' => ['value' => 'null']]],\n            'nested key exists and not null' => [false, 'nested->value', ['nested' => ['value' => false]]],\n            'array index not exists' => [false, '[0]', [1 => 'invalid']],\n            'array index exists and null' => [true, '[0]', [null]],\n            'array index exists and \"null\"' => [false, '[0]', ['null']],\n            'array index exists and not null' => [false, '[0]', [false]],\n            'nested array index not exists' => [false, 'nested[0]', ['nested' => [1 => 'nested->invalid']]],\n            'nested array index exists and null' => [true, 'nested->value[1]', ['nested' => ['value' => [0, null]]]],\n            'nested array index exists and \"null\"' => [false, 'nested->value[1]', ['nested' => ['value' => [0, 'null']]]],\n            'nested array index exists and not null' => [false, 'nested->value[1]', ['nested' => ['value' => [0, false]]]],\n        ];\n    }\n\n    public function testJsonPathUpdate()\n    {\n        DB::table(self::TABLE)->insert([\n            [self::JSON_COL => '{\"foo\":[\"bar\"]}'],\n            [self::JSON_COL => '{\"foo\":[\"baz\"]}'],\n        ]);\n        $updatedCount = DB::table(self::TABLE)->where(self::JSON_COL.'->foo[0]', 'baz')->update([\n            self::JSON_COL.'->foo[0]' => 'updated',\n        ]);\n        $this->assertSame(1, $updatedCount);\n    }\n\n    #[DataProvider('jsonContainsKeyDataProvider')]\n    public function testWhereJsonContainsKey($count, $column)\n    {\n        DB::table(self::TABLE)->insert([\n            ['json_col' => '{\"foo\":{\"bar\":[\"baz\"]}}'],\n            ['json_col' => '{\"foo\":{\"bar\":false}}'],\n            ['json_col' => '{\"foo\":{}}'],\n            ['json_col' => '{\"foo\":[{\"bar\":\"bar\"},{\"baz\":\"baz\"}]}'],\n            ['json_col' => '{\"bar\":null}'],\n        ]);\n\n        $this->assertSame($count, DB::table(self::TABLE)->whereJsonContainsKey($column)->count());\n    }\n\n    public static function jsonContainsKeyDataProvider()\n    {\n        return [\n            'string key' => [4, 'json_col->foo'],\n            'nested key exists' => [2, 'json_col->foo->bar'],\n            'string key missing' => [0, 'json_col->none'],\n            'integer key with arrow ' => [0, 'json_col->foo->bar->0'],\n            'integer key with braces' => [2, 'json_col->foo->bar[0]'],\n            'integer key missing' => [0, 'json_col->foo->bar[1]'],\n            'mixed keys' => [1, 'json_col->foo[1]->baz'],\n            'null value' => [1, 'json_col->bar'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderAlterTableWithEnumTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMariaDbSchemaBuilderAlterTableWithEnumTest extends MariaDbTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n            $table->string('age');\n            $table->enum('color', ['red', 'blue']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    public function testRenameColumnOnTableWithEnum()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->renameColumn('name', 'username');\n        });\n\n        $this->assertTrue(Schema::hasColumn('users', 'username'));\n    }\n\n    public function testChangeColumnOnTableWithEnum()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->unsignedInteger('age')->change();\n        });\n\n        $this->assertSame('int', Schema::getColumnType('users', 'age'));\n    }\n\n    public function testGetTablesAndColumnListing()\n    {\n        $tables = Schema::getTables();\n\n        $this->assertCount(2, $tables);\n        $this->assertEquals(['migrations', 'users'], array_column($tables, 'name'));\n\n        $columns = Schema::getColumnListing('users');\n\n        foreach (['id', 'name', 'age', 'color'] as $column) {\n            $this->assertContains($column, $columns);\n        }\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('title');\n        });\n        $tables = Schema::getTables();\n        $this->assertCount(3, $tables);\n        Schema::drop('posts');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/DatabaseMariaDbSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMariaDbSchemaBuilderTest extends MariaDbTestCase\n{\n    public function testAddCommentToTable()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n            $table->comment('This is a comment');\n        });\n\n        $tableInfo = DB::table('information_schema.tables')\n            ->where('table_schema', $this->app['config']->get('database.connections.mariadb.database'))\n            ->where('table_name', 'users')\n            ->select('table_comment as table_comment')\n            ->first();\n\n        $this->assertEquals('This is a comment', $tableInfo->table_comment);\n\n        Schema::drop('users');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/EloquentCastTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentCastTest extends MariaDbTestCase\n{\n    protected $driver = 'mariadb';\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->integer('created_at');\n            $table->integer('updated_at');\n        });\n\n        Schema::create('users_nullable_timestamps', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamp('created_at')->nullable();\n            $table->timestamp('updated_at')->nullable();\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    public function testItCastTimestampsCreatedByTheBuilderWhenTimeHasNotPassed()\n    {\n        Carbon::setTestNow(Carbon::now());\n        $createdAt = Carbon::now()->timestamp;\n\n        $castUser = UserWithIntTimestampsViaCasts::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser = UserWithIntTimestampsViaAttribute::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser = UserWithIntTimestampsViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n\n        $castUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $castUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n\n    public function testItCastTimestampsCreatedByTheBuilderWhenTimeHasPassed()\n    {\n        Carbon::setTestNow(Carbon::now());\n        $createdAt = Carbon::now()->timestamp;\n\n        $castUser = UserWithIntTimestampsViaCasts::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser = UserWithIntTimestampsViaAttribute::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser = UserWithIntTimestampsViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n\n        Carbon::setTestNow(Carbon::now()->addSecond());\n        $updatedAt = Carbon::now()->timestamp;\n\n        $castUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $castUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $castUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $attributeUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n\n    public function testItCastTimestampsUpdatedByAMutator()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $mutatorUser = UserWithUpdatedAtViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertNull($mutatorUser->updated_at);\n\n        Carbon::setTestNow(Carbon::now()->addSecond());\n        $updatedAt = Carbon::now()->timestamp;\n\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($updatedAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n}\n\nclass UserWithIntTimestampsViaCasts extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected $casts = [\n        'created_at' => UnixTimeStampToCarbon::class,\n        'updated_at' => UnixTimeStampToCarbon::class,\n    ];\n}\n\nclass UnixTimeStampToCarbon implements CastsAttributes\n{\n    public function get($model, string $key, $value, array $attributes)\n    {\n        return Carbon::parse($value);\n    }\n\n    public function set($model, string $key, $value, array $attributes)\n    {\n        return Carbon::parse($value)->timestamp;\n    }\n}\n\nclass UserWithIntTimestampsViaAttribute extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected function updatedAt(): Attribute\n    {\n        return Attribute::make(\n            get: fn ($value) => Carbon::parse($value),\n            set: fn ($value) => Carbon::parse($value)->timestamp,\n        );\n    }\n\n    protected function createdAt(): Attribute\n    {\n        return Attribute::make(\n            get: fn ($value) => Carbon::parse($value),\n            set: fn ($value) => Carbon::parse($value)->timestamp,\n        );\n    }\n}\n\nclass UserWithIntTimestampsViaMutator extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected function getUpdatedAtAttribute($value)\n    {\n        return Carbon::parse($value);\n    }\n\n    protected function setUpdatedAtAttribute($value)\n    {\n        $this->attributes['updated_at'] = Carbon::parse($value)->timestamp;\n    }\n\n    protected function getCreatedAtAttribute($value)\n    {\n        return Carbon::parse($value);\n    }\n\n    protected function setCreatedAtAttribute($value)\n    {\n        $this->attributes['created_at'] = Carbon::parse($value)->timestamp;\n    }\n}\n\nclass UserWithUpdatedAtViaMutator extends Model\n{\n    protected $table = 'users_nullable_timestamps';\n\n    protected $fillable = ['email', 'updated_at'];\n\n    public function setUpdatedAtAttribute($value)\n    {\n        if (! $this->id) {\n            return;\n        }\n\n        $this->updated_at = $value;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/EscapeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse RuntimeException;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass EscapeTest extends MariaDbTestCase\n{\n    public function testEscapeInt()\n    {\n        $this->assertSame('42', $this->app['db']->escape(42));\n        $this->assertSame('-6', $this->app['db']->escape(-6));\n    }\n\n    public function testEscapeFloat()\n    {\n        $this->assertSame('3.14159', $this->app['db']->escape(3.14159));\n        $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159));\n    }\n\n    public function testEscapeBool()\n    {\n        $this->assertSame('1', $this->app['db']->escape(true));\n        $this->assertSame('0', $this->app['db']->escape(false));\n    }\n\n    public function testEscapeNull()\n    {\n        $this->assertSame('null', $this->app['db']->escape(null));\n        $this->assertSame('null', $this->app['db']->escape(null, true));\n    }\n\n    public function testEscapeBinary()\n    {\n        $this->assertSame(\"x'dead00beef'\", $this->app['db']->escape(hex2bin('dead00beef'), true));\n    }\n\n    public function testEscapeString()\n    {\n        $this->assertSame(\"'2147483647'\", $this->app['db']->escape('2147483647'));\n        $this->assertSame(\"'true'\", $this->app['db']->escape('true'));\n        $this->assertSame(\"'false'\", $this->app['db']->escape('false'));\n        $this->assertSame(\"'null'\", $this->app['db']->escape('null'));\n        $this->assertSame(\"'Hello\\'World'\", $this->app['db']->escape(\"Hello'World\"));\n    }\n\n    public function testEscapeStringInvalidUtf8()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding an invalid \\x80 utf-8 continuation byte\");\n    }\n\n    public function testEscapeStringNullByte()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding a \\00 byte\");\n    }\n\n    public function testEscapeArray()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(['a', 'b']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/FulltextTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass FulltextTest extends MariaDbTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('articles', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title', 200);\n            $table->text('body');\n            $table->fulltext(['title', 'body']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('articles');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('articles')->insert([\n            ['title' => 'MariaDB Tutorial', 'body' => 'DBMS stands for DataBase ...'],\n            ['title' => 'How To Use MariaDB Well', 'body' => 'After you went through a ...'],\n            ['title' => 'Optimizing MariaDB', 'body' => 'In this tutorial, we show ...'],\n            ['title' => '1001 MariaDB Tricks', 'body' => '1. Never run mariadbd as root. 2. ...'],\n            ['title' => 'MariaDB vs. YourSQL', 'body' => 'In the following database comparison ...'],\n            ['title' => 'MariaDB Security', 'body' => 'When configured properly, MariaDB ...'],\n        ]);\n    }\n\n    /** @link https://mariadb.com/kb/en/full-text-index-overview/#in-natural-language-mode */\n    public function testWhereFulltext()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'database')->get();\n\n        $this->assertCount(2, $articles);\n        $this->assertSame('MariaDB Tutorial', $articles[0]->title);\n        $this->assertSame('MariaDB vs. YourSQL', $articles[1]->title);\n    }\n\n    /** @link https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode */\n    public function testWhereFulltextWithBooleanMode()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], '+MariaDB -YourSQL', ['mode' => 'boolean'])->get();\n\n        $this->assertCount(5, $articles);\n    }\n\n    /** @link https://mariadb.com/kb/en/full-text-index-overview/#with-query-expansion */\n    public function testWhereFulltextWithExpandedQuery()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'database', ['expanded' => true])->get();\n\n        $this->assertCount(6, $articles);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/JsonLikeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass JsonLikeTest extends MariaDbTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('tasks', function (Blueprint $table) {\n            $table->id();\n            $table->json('data');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::dropIfExists('tasks');\n    }\n\n    public function testJsonLikeWithEmoji()\n    {\n        // Test that LIKE queries work correctly with emojis in JSON fields\n        // This verifies that json_value() handles emojis correctly (unlike json_unquote)\n        DB::table('tasks')->insert([\n            ['data' => '{\"status\":\"Building started 🔨\"}'],\n            ['data' => '{\"status\":\"Tests passed ✅\"}'],\n            ['data' => '{\"status\":\"Deployment complete 🌎\"}'],\n        ]);\n\n        // Search for records containing the hammer emoji\n        $buildCount = DB::table('tasks')\n            ->where('data->status', 'like', '%🔨%')\n            ->count();\n        $this->assertSame(1, $buildCount, 'Should find 1 record with hammer emoji');\n\n        // Search for records containing \"Tests\" with emoji\n        $testsCount = DB::table('tasks')\n            ->where('data->status', 'like', '%Tests%')\n            ->count();\n        $this->assertSame(1, $testsCount, 'Should find 1 record with \"Tests\"');\n\n        // Search for records containing rocket emoji\n        $deployCount = DB::table('tasks')\n            ->where('data->status', 'like', '%🌎%')\n            ->count();\n        $this->assertSame(1, $deployCount, 'Should find 1 record with globe emoji');\n\n        // Verify we can find text before emoji\n        $completeCount = DB::table('tasks')\n            ->where('data->status', 'like', '%complete%')\n            ->count();\n        $this->assertSame(1, $completeCount, 'Should find 1 record with \"complete\" before emoji');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MariaDb/MariaDbTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MariaDb;\n\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('mariadb')]\nabstract class MariaDbTestCase extends DatabaseTestCase\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/MigrateWithRealpathTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\TestCase;\n\nclass MigrateWithRealpathTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        if ($this->app['config']->get('database.default') !== 'testing') {\n            $this->artisan('db:wipe', ['--drop-views' => true]);\n        }\n\n        $options = [\n            '--path' => realpath(__DIR__.'/stubs/'),\n            '--realpath' => true,\n        ];\n\n        $this->artisan('migrate', $options);\n\n        $this->beforeApplicationDestroyed(function () use ($options) {\n            $this->artisan('migrate:rollback', $options);\n        });\n    }\n\n    public function testRealpathMigrationHasProperlyExecuted()\n    {\n        $this->assertTrue(Schema::hasTable('members'));\n    }\n\n    public function testMigrationsHasTheMigratedTable()\n    {\n        $this->assertDatabaseHas('migrations', [\n            'id' => 1,\n            'migration' => '2014_10_12_000000_create_members_table',\n            'batch' => 1,\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MigrationServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Migrations\\Migrator;\n\nclass MigrationServiceProviderTest extends DatabaseTestCase\n{\n    public function testContainerCanBuildMigrator()\n    {\n        $fromString = $this->app->make('migrator');\n        $fromClass = $this->app->make(Migrator::class);\n\n        $this->assertSame($fromString, $fromClass);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MigratorEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Events\\MigrationEnded;\nuse Illuminate\\Database\\Events\\MigrationsEnded;\nuse Illuminate\\Database\\Events\\MigrationSkipped;\nuse Illuminate\\Database\\Events\\MigrationsStarted;\nuse Illuminate\\Database\\Events\\MigrationStarted;\nuse Illuminate\\Database\\Events\\NoPendingMigrations;\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass MigratorEventsTest extends TestCase\n{\n    protected function migrateOptions()\n    {\n        return [\n            '--path' => realpath(__DIR__.'/stubs/'),\n            '--realpath' => true,\n        ];\n    }\n\n    public function testMigrationEventsAreFired()\n    {\n        Event::fake();\n\n        $this->artisan('migrate', $this->migrateOptions());\n        $this->artisan('migrate:rollback', $this->migrateOptions());\n\n        Event::assertDispatched(MigrationsStarted::class, 2);\n        Event::assertDispatched(MigrationsEnded::class, 2);\n        Event::assertDispatched(MigrationStarted::class, 2);\n        Event::assertDispatched(MigrationEnded::class, 2);\n        Event::assertDispatched(MigrationSkipped::class, 1);\n    }\n\n    public function testMigrationEventsContainTheOptionsAndPretendFalse()\n    {\n        Event::fake();\n\n        $this->artisan('migrate', $this->migrateOptions());\n        $this->artisan('migrate:rollback', $this->migrateOptions());\n\n        Event::assertDispatched(MigrationsStarted::class, function ($event) {\n            return $event->method === 'up'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === false;\n        });\n        Event::assertDispatched(MigrationsStarted::class, function ($event) {\n            return $event->method === 'down'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === false;\n        });\n        Event::assertDispatched(MigrationsEnded::class, function ($event) {\n            return $event->method === 'up'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === false;\n        });\n        Event::assertDispatched(MigrationsEnded::class, function ($event) {\n            return $event->method === 'down'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === false;\n        });\n    }\n\n    public function testMigrationEventsContainTheOptionsAndPretendTrue()\n    {\n        Event::fake();\n\n        $this->artisan('migrate', $this->migrateOptions() + ['--pretend' => true]);\n        $this->artisan('migrate:rollback', $this->migrateOptions()); // doesn't support pretend\n\n        Event::assertDispatched(MigrationsStarted::class, function ($event) {\n            return $event->method === 'up'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === true;\n        });\n\n        Event::assertDispatched(MigrationsEnded::class, function ($event) {\n            return $event->method === 'up'\n                && is_array($event->options)\n                && isset($event->options['pretend'])\n                && $event->options['pretend'] === true;\n        });\n    }\n\n    public function testMigrationEventsContainTheMigrationAndMethod()\n    {\n        Event::fake();\n\n        $this->artisan('migrate', $this->migrateOptions());\n        $this->artisan('migrate:rollback', $this->migrateOptions());\n\n        Event::assertDispatched(MigrationsStarted::class, function ($event) {\n            return $event->method === 'up';\n        });\n        Event::assertDispatched(MigrationsStarted::class, function ($event) {\n            return $event->method === 'down';\n        });\n        Event::assertDispatched(MigrationsEnded::class, function ($event) {\n            return $event->method === 'up';\n        });\n        Event::assertDispatched(MigrationsEnded::class, function ($event) {\n            return $event->method === 'down';\n        });\n\n        Event::assertDispatched(MigrationStarted::class, function ($event) {\n            return $event->method === 'up' && $event->migration instanceof Migration;\n        });\n        Event::assertDispatched(MigrationStarted::class, function ($event) {\n            return $event->method === 'down' && $event->migration instanceof Migration;\n        });\n        Event::assertDispatched(MigrationEnded::class, function ($event) {\n            return $event->method === 'up' && $event->migration instanceof Migration;\n        });\n        Event::assertDispatched(MigrationEnded::class, function ($event) {\n            return $event->method === 'down' && $event->migration instanceof Migration;\n        });\n    }\n\n    public function testTheNoMigrationEventIsFiredWhenNothingToMigrate()\n    {\n        Event::fake();\n\n        $this->artisan('migrate');\n        $this->artisan('migrate:rollback');\n\n        Event::assertDispatched(NoPendingMigrations::class, function ($event) {\n            return $event->method === 'up';\n        });\n        Event::assertDispatched(NoPendingMigrations::class, function ($event) {\n            return $event->method === 'down';\n        });\n    }\n\n    public function testMigrationSkippedEventIsFired()\n    {\n        Event::fake();\n\n        $this->artisan('migrate', [\n            '--path' => realpath(__DIR__.'/stubs/2014_10_13_000000_skipped_migration.php'),\n            '--realpath' => true,\n        ]);\n\n        Event::assertDispatched(MigrationSkipped::class, function ($event) {\n            return $event->migrationName === '2014_10_13_000000_skipped_migration';\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/ModelInspectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\CollectedBy;\nuse Illuminate\\Database\\Eloquent\\Attributes\\ObservedBy;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelInfo;\nuse Illuminate\\Database\\Eloquent\\ModelInspector;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass ModelInspectorTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('parent_test_models', function (Blueprint $table) {\n            $table->id();\n        });\n        Schema::create('model_info_extractor_test_model', function (Blueprint $table) {\n            $table->increments('id');\n            $table->uuid();\n            $table->string('name');\n            $table->boolean('a_bool');\n            $table->foreignId('parent_test_model_id')->constrained();\n            $table->timestamp('nullable_date')->nullable();\n            $table->timestamps();\n        });\n    }\n\n    public function test_extracts_model_data()\n    {\n        $extractor = new ModelInspector($this->app);\n        $modelInfo = $extractor->inspect(ModelInspectorTestModel::class);\n        $this->assertModelInfo($modelInfo);\n        $this->assertSame(ModelInspectorTestModelEloquentCollection::class, $modelInfo['collection']);\n        $this->assertSame(ModelInspectorTestModelBuilder::class, $modelInfo['builder']);\n        $this->assertSame(ModelInspectorTestModelResource::class, $modelInfo['resource']);\n    }\n\n    public function test_command_returns_json()\n    {\n        $this->withoutMockingConsoleOutput()->artisan('model:show', ['model' => ModelInspectorTestModel::class, '--json' => true]);\n        $o = Artisan::output();\n        $this->assertJson($o);\n        $modelInfo = json_decode($o, true);\n        $this->assertModelInfo($modelInfo);\n    }\n\n    private function assertModelInfo(ModelInfo|array $modelInfo)\n    {\n        $this->assertEquals(ModelInspectorTestModel::class, $modelInfo['class']);\n        $this->assertEquals(Schema::getConnection()->getConfig()['name'], $modelInfo['database']);\n        $this->assertEquals('model_info_extractor_test_model', $modelInfo['table']);\n        $this->assertNull($modelInfo['policy']);\n        $this->assertCount(8, $modelInfo['attributes']);\n\n        $this->assertAttributes([\n            'name' => 'id',\n            'increments' => true,\n            'nullable' => false,\n            'default' => null,\n            'unique' => true,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => null,\n        ], $modelInfo['attributes'][0]);\n\n        $this->assertAttributes([\n            'name' => 'uuid',\n            'increments' => false,\n            'nullable' => false,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => null,\n        ], $modelInfo['attributes'][1]);\n\n        $this->assertAttributes([\n            'name' => 'name',\n            'increments' => false,\n            'nullable' => false,\n            'default' => null,\n            'unique' => false,\n            'fillable' => false,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => null,\n        ], $modelInfo['attributes'][2]);\n\n        $this->assertAttributes([\n            'name' => 'a_bool',\n            'increments' => false,\n            'nullable' => false,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => 'bool',\n        ], $modelInfo['attributes'][3]);\n\n        $this->assertAttributes([\n            'name' => 'parent_test_model_id',\n            'increments' => false,\n            'nullable' => false,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => null,\n        ], $modelInfo['attributes'][4]);\n\n        $this->assertAttributes([\n            'name' => 'nullable_date',\n            'increments' => false,\n            'nullable' => true,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => 'datetime',\n        ], $modelInfo['attributes'][5]);\n\n        $this->assertAttributes([\n            'name' => 'created_at',\n            'increments' => false,\n            'nullable' => true,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => 'datetime',\n        ], $modelInfo['attributes'][6]);\n\n        $this->assertAttributes([\n            'name' => 'updated_at',\n            'increments' => false,\n            'nullable' => true,\n            'default' => null,\n            'unique' => false,\n            'fillable' => true,\n            'hidden' => false,\n            'appended' => null,\n            'cast' => 'datetime',\n        ], $modelInfo['attributes'][7]);\n\n        $this->assertCount(1, $modelInfo['relations']);\n        $this->assertEqualsCanonicalizing([\n            'name' => 'parentModel',\n            'type' => 'BelongsTo',\n            'related' => \"Illuminate\\Tests\\Integration\\Database\\ParentTestModel\",\n        ], $modelInfo['relations'][0]);\n\n        $this->assertEmpty($modelInfo['events']);\n        $this->assertCount(1, $modelInfo['observers']);\n        $this->assertEquals('created', $modelInfo['observers'][0]['event']);\n        $this->assertCount(1, $modelInfo['observers'][0]['observer']);\n        $this->assertEquals(\"Illuminate\\Tests\\Integration\\Database\\ModelInspectorTestModelObserver@created\", $modelInfo['observers'][0]['observer'][0]);\n        $this->assertEquals(ModelInspectorTestModelEloquentCollection::class, $modelInfo['collection']);\n        $this->assertEquals(ModelInspectorTestModelBuilder::class, $modelInfo['builder']);\n    }\n\n    private function assertAttributes($expectedAttributes, $actualAttributes)\n    {\n        foreach (['name', 'increments', 'nullable', 'unique', 'fillable', 'hidden', 'appended', 'cast'] as $key) {\n            $this->assertEquals($expectedAttributes[$key], $actualAttributes[$key]);\n        }\n        // We ignore type because it varies from DB to DB\n        $this->assertArrayHasKey('type', $actualAttributes);\n        $this->assertArrayHasKey('default', $actualAttributes);\n    }\n}\n\n#[ObservedBy(ModelInspectorTestModelObserver::class)]\n#[CollectedBy(ModelInspectorTestModelEloquentCollection::class)]\n#[UseResource(ModelInspectorTestModelResource::class)]\nclass ModelInspectorTestModel extends Model\n{\n    use HasUuids;\n\n    protected static string $builder = ModelInspectorTestModelBuilder::class;\n    public $table = 'model_info_extractor_test_model';\n    protected $guarded = ['name'];\n    protected $casts = ['nullable_date' => 'datetime', 'a_bool' => 'bool'];\n\n    public function parentModel(): BelongsTo\n    {\n        return $this->belongsTo(ParentTestModel::class);\n    }\n}\n\nclass ParentTestModel extends Model\n{\n    public $table = 'parent_test_models';\n    public $timestamps = false;\n}\n\nclass ModelInspectorTestModelObserver\n{\n    public function created()\n    {\n    }\n}\n\nclass ModelInspectorTestModelEloquentCollection extends Collection\n{\n}\n\nclass ModelInspectorTestModelBuilder extends Builder\n{\n}\n\nclass ModelInspectorTestModelResource extends JsonResource\n{\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/DatabaseEloquentMySqlIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseEloquentMySqlIntegrationTest extends MySqlTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('database_eloquent_mysql_integration_users')) {\n            Schema::create('database_eloquent_mysql_integration_users', function (Blueprint $table) {\n                $table->id();\n                $table->string('name')->nullable();\n                $table->string('email')->unique();\n                $table->timestamps();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('database_eloquent_mysql_integration_users');\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user1 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user1 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(['email' => 'taylor@laravel.com']);\n\n        DB::transaction(function () use ($user1) {\n            $user2 = DatabaseEloquentMySqlIntegrationUser::createOrFirst(\n                ['email' => 'taylor@laravel.com'],\n                ['name' => 'Taylor Otwell']\n            );\n\n            $this->assertEquals($user1->id, $user2->id);\n            $this->assertSame('taylor@laravel.com', $user2->email);\n            $this->assertNull($user2->name);\n        });\n    }\n}\n\nclass DatabaseEloquentMySqlIntegrationUser extends Model\n{\n    protected $table = 'database_eloquent_mysql_integration_users';\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse PDO;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseEmulatePreparesMySqlConnectionTest extends DatabaseMySqlConnectionTest\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.connections.mysql.options', [\n            PDO::ATTR_EMULATE_PREPARES => true,\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/DatabaseMySqlConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Events\\QueryExecuted;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMySqlConnectionTest extends MySqlTestCase\n{\n    const TABLE = 'player';\n    const FLOAT_COL = 'float_col';\n    const JSON_COL = 'json_col';\n    const FLOAT_VAL = 0.2;\n\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable(self::TABLE)) {\n            Schema::create(self::TABLE, function (Blueprint $table) {\n                $table->json(self::JSON_COL)->nullable();\n                $table->float(self::FLOAT_COL)->nullable();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop(self::TABLE);\n    }\n\n    #[DataProvider('floatComparisonsDataProvider')]\n    public function testJsonFloatComparison($value, $operator, $shouldMatch)\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => '{\"rank\":'.self::FLOAT_VAL.'}']);\n\n        $this->assertSame(\n            $shouldMatch,\n            DB::table(self::TABLE)->where(self::JSON_COL.'->rank', $operator, $value)->exists(),\n            self::JSON_COL.'->rank should '.($shouldMatch ? '' : 'not ').\"be $operator $value\"\n        );\n    }\n\n    public static function floatComparisonsDataProvider()\n    {\n        return [\n            [0.2, '=', true],\n            [0.2, '>', false],\n            [0.2, '<', false],\n            [0.1, '=', false],\n            [0.1, '<', false],\n            [0.1, '>', true],\n            [0.3, '=', false],\n            [0.3, '<', true],\n            [0.3, '>', false],\n        ];\n    }\n\n    public function testFloatValueStoredCorrectly()\n    {\n        DB::table(self::TABLE)->insert([self::FLOAT_COL => self::FLOAT_VAL]);\n\n        $this->assertEquals(self::FLOAT_VAL, DB::table(self::TABLE)->value(self::FLOAT_COL));\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => json_encode($value)]);\n\n        $this->assertSame($expected, DB::table(self::TABLE)->whereNull(self::JSON_COL.'->'.$key)->exists());\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNotNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table(self::TABLE)->insert([self::JSON_COL => json_encode($value)]);\n\n        $this->assertSame(! $expected, DB::table(self::TABLE)->whereNotNull(self::JSON_COL.'->'.$key)->exists());\n    }\n\n    public static function jsonWhereNullDataProvider()\n    {\n        return [\n            'key not exists' => [true, 'invalid'],\n            'key exists and null' => [true, 'value', ['value' => null]],\n            'key exists and \"null\"' => [false, 'value', ['value' => 'null']],\n            'key exists and not null' => [false, 'value', ['value' => false]],\n            'nested key not exists' => [true, 'nested->invalid'],\n            'nested key exists and null' => [true, 'nested->value', ['nested' => ['value' => null]]],\n            'nested key exists and \"null\"' => [false, 'nested->value', ['nested' => ['value' => 'null']]],\n            'nested key exists and not null' => [false, 'nested->value', ['nested' => ['value' => false]]],\n            'array index not exists' => [false, '[0]', [1 => 'invalid']],\n            'array index exists and null' => [true, '[0]', [null]],\n            'array index exists and \"null\"' => [false, '[0]', ['null']],\n            'array index exists and not null' => [false, '[0]', [false]],\n            'nested array index not exists' => [false, 'nested[0]', ['nested' => [1 => 'nested->invalid']]],\n            'nested array index exists and null' => [true, 'nested->value[1]', ['nested' => ['value' => [0, null]]]],\n            'nested array index exists and \"null\"' => [false, 'nested->value[1]', ['nested' => ['value' => [0, 'null']]]],\n            'nested array index exists and not null' => [false, 'nested->value[1]', ['nested' => ['value' => [0, false]]]],\n        ];\n    }\n\n    public function testJsonPathUpdate()\n    {\n        DB::table(self::TABLE)->insert([\n            [self::JSON_COL => '{\"foo\":[\"bar\"]}'],\n            [self::JSON_COL => '{\"foo\":[\"baz\"]}'],\n        ]);\n        $updatedCount = DB::table(self::TABLE)->where(self::JSON_COL.'->foo[0]', 'baz')->update([\n            self::JSON_COL.'->foo[0]' => 'updated',\n        ]);\n        $this->assertSame(1, $updatedCount);\n    }\n\n    #[DataProvider('jsonContainsKeyDataProvider')]\n    public function testWhereJsonContainsKey($count, $column)\n    {\n        DB::table(self::TABLE)->insert([\n            ['json_col' => '{\"foo\":{\"bar\":[\"baz\"]}}'],\n            ['json_col' => '{\"foo\":{\"bar\":false}}'],\n            ['json_col' => '{\"foo\":{}}'],\n            ['json_col' => '{\"foo\":[{\"bar\":\"bar\"},{\"baz\":\"baz\"}]}'],\n            ['json_col' => '{\"bar\":null}'],\n        ]);\n\n        $this->assertSame($count, DB::table(self::TABLE)->whereJsonContainsKey($column)->count());\n    }\n\n    public static function jsonContainsKeyDataProvider()\n    {\n        return [\n            'string key' => [4, 'json_col->foo'],\n            'nested key exists' => [2, 'json_col->foo->bar'],\n            'string key missing' => [0, 'json_col->none'],\n            'integer key with arrow ' => [0, 'json_col->foo->bar->0'],\n            'integer key with braces' => [2, 'json_col->foo->bar[0]'],\n            'integer key missing' => [0, 'json_col->foo->bar[1]'],\n            'mixed keys' => [1, 'json_col->foo[1]->baz'],\n            'null value' => [1, 'json_col->bar'],\n        ];\n    }\n\n    public function testLastInsertIdIsPreserved()\n    {\n        if (! Schema::hasTable('auto_id_table')) {\n            Schema::create('auto_id_table', function (Blueprint $table) {\n                $table->id();\n            });\n        }\n\n        try {\n            static $callbackExecuted = false;\n            DB::listen(function (QueryExecuted $event) use (&$callbackExecuted) {\n                DB::getPdo()->query('SELECT 1');\n                $callbackExecuted = true;\n            });\n\n            $id = DB::table('auto_id_table')->insertGetId([]);\n            $this->assertTrue($callbackExecuted, 'The query listener was not executed.');\n            $this->assertEquals(1, $id);\n        } finally {\n            Schema::drop('auto_id_table');\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderAlterTableWithEnumTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMySqlSchemaBuilderAlterTableWithEnumTest extends MySqlTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n            $table->string('age');\n            $table->enum('color', ['red', 'blue']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    public function testRenameColumnOnTableWithEnum()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->renameColumn('name', 'username');\n        });\n\n        $this->assertTrue(Schema::hasColumn('users', 'username'));\n    }\n\n    public function testChangeColumnOnTableWithEnum()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->unsignedInteger('age')->change();\n        });\n\n        $this->assertSame('int', Schema::getColumnType('users', 'age'));\n    }\n\n    public function testGetTablesAndColumnListing()\n    {\n        $tables = Schema::getTables();\n\n        $this->assertCount(2, $tables);\n        $this->assertEquals(['migrations', 'users'], array_column($tables, 'name'));\n\n        $columns = Schema::getColumnListing('users');\n\n        foreach (['id', 'name', 'age', 'color'] as $column) {\n            $this->assertContains($column, $columns);\n        }\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('title');\n        });\n        $tables = Schema::getTables();\n        $this->assertCount(3, $tables);\n        Schema::drop('posts');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/DatabaseMySqlSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass DatabaseMySqlSchemaBuilderTest extends MySqlTestCase\n{\n    public function testAddCommentToTable()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n            $table->comment('This is a comment');\n        });\n\n        $tableInfo = DB::table('information_schema.tables')\n            ->where('table_schema', $this->app['config']->get('database.connections.mysql.database'))\n            ->where('table_name', 'users')\n            ->select('table_comment as table_comment')\n            ->first();\n\n        $this->assertEquals('This is a comment', $tableInfo->table_comment);\n\n        Schema::drop('users');\n    }\n\n    #[RequiresDatabase('mysql', '>=8.0.13')]\n    public function testGetRawIndex()\n    {\n        Schema::create('table', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n            $table->rawIndex('(year(created_at))', 'table_raw_index');\n        });\n\n        $indexes = Schema::getIndexes('table');\n\n        $this->assertSame([], collect($indexes)->firstWhere('name', 'table_raw_index')['columns']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/EloquentCastTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;\nuse Illuminate\\Database\\Eloquent\\Casts\\Attribute;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass EloquentCastTest extends MySqlTestCase\n{\n    protected $driver = 'mysql';\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->integer('created_at');\n            $table->integer('updated_at');\n        });\n\n        Schema::create('users_nullable_timestamps', function ($table) {\n            $table->increments('id');\n            $table->string('email')->unique();\n            $table->timestamp('created_at')->nullable();\n            $table->timestamp('updated_at')->nullable();\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    public function testItCastTimestampsCreatedByTheBuilderWhenTimeHasNotPassed()\n    {\n        Carbon::setTestNow(Carbon::now());\n        $createdAt = Carbon::now()->timestamp;\n\n        $castUser = UserWithIntTimestampsViaCasts::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser = UserWithIntTimestampsViaAttribute::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser = UserWithIntTimestampsViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n\n        $castUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $castUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n\n    public function testItCastTimestampsCreatedByTheBuilderWhenTimeHasPassed()\n    {\n        Carbon::setTestNow(Carbon::now());\n        $createdAt = Carbon::now()->timestamp;\n\n        $castUser = UserWithIntTimestampsViaCasts::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser = UserWithIntTimestampsViaAttribute::create([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser = UserWithIntTimestampsViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($createdAt, $castUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->updated_at->timestamp);\n\n        Carbon::setTestNow(Carbon::now()->addSecond());\n        $updatedAt = Carbon::now()->timestamp;\n\n        $castUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $attributeUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($createdAt, $castUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $castUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $castUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $attributeUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $attributeUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $attributeUser->fresh()->updated_at->timestamp);\n        $this->assertSame($createdAt, $mutatorUser->created_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n\n    public function testItCastTimestampsUpdatedByAMutator()\n    {\n        Carbon::setTestNow(Carbon::now());\n\n        $mutatorUser = UserWithUpdatedAtViaMutator::create([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertNull($mutatorUser->updated_at);\n\n        Carbon::setTestNow(Carbon::now()->addSecond());\n        $updatedAt = Carbon::now()->timestamp;\n\n        $mutatorUser->update([\n            'email' => fake()->unique()->email,\n        ]);\n\n        $this->assertSame($updatedAt, $mutatorUser->updated_at->timestamp);\n        $this->assertSame($updatedAt, $mutatorUser->fresh()->updated_at->timestamp);\n    }\n}\n\nclass UserWithIntTimestampsViaCasts extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected $casts = [\n        'created_at' => UnixTimeStampToCarbon::class,\n        'updated_at' => UnixTimeStampToCarbon::class,\n    ];\n}\n\nclass UnixTimeStampToCarbon implements CastsAttributes\n{\n    public function get($model, string $key, $value, array $attributes)\n    {\n        return Carbon::parse($value);\n    }\n\n    public function set($model, string $key, $value, array $attributes)\n    {\n        return Carbon::parse($value)->timestamp;\n    }\n}\n\nclass UserWithIntTimestampsViaAttribute extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected function updatedAt(): Attribute\n    {\n        return Attribute::make(\n            get: fn ($value) => Carbon::parse($value),\n            set: fn ($value) => Carbon::parse($value)->timestamp,\n        );\n    }\n\n    protected function createdAt(): Attribute\n    {\n        return Attribute::make(\n            get: fn ($value) => Carbon::parse($value),\n            set: fn ($value) => Carbon::parse($value)->timestamp,\n        );\n    }\n}\n\nclass UserWithIntTimestampsViaMutator extends Model\n{\n    protected $table = 'users';\n\n    protected $fillable = ['email'];\n\n    protected function getUpdatedAtAttribute($value)\n    {\n        return Carbon::parse($value);\n    }\n\n    protected function setUpdatedAtAttribute($value)\n    {\n        $this->attributes['updated_at'] = Carbon::parse($value)->timestamp;\n    }\n\n    protected function getCreatedAtAttribute($value)\n    {\n        return Carbon::parse($value);\n    }\n\n    protected function setCreatedAtAttribute($value)\n    {\n        $this->attributes['created_at'] = Carbon::parse($value)->timestamp;\n    }\n}\n\nclass UserWithUpdatedAtViaMutator extends Model\n{\n    protected $table = 'users_nullable_timestamps';\n\n    protected $fillable = ['email', 'updated_at'];\n\n    public function setUpdatedAtAttribute($value)\n    {\n        if (! $this->id) {\n            return;\n        }\n\n        $this->updated_at = $value;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/EscapeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse RuntimeException;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass EscapeTest extends MySqlTestCase\n{\n    public function testEscapeInt()\n    {\n        $this->assertSame('42', $this->app['db']->escape(42));\n        $this->assertSame('-6', $this->app['db']->escape(-6));\n    }\n\n    public function testEscapeFloat()\n    {\n        $this->assertSame('3.14159', $this->app['db']->escape(3.14159));\n        $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159));\n    }\n\n    public function testEscapeBool()\n    {\n        $this->assertSame('1', $this->app['db']->escape(true));\n        $this->assertSame('0', $this->app['db']->escape(false));\n    }\n\n    public function testEscapeNull()\n    {\n        $this->assertSame('null', $this->app['db']->escape(null));\n        $this->assertSame('null', $this->app['db']->escape(null, true));\n    }\n\n    public function testEscapeBinary()\n    {\n        $this->assertSame(\"x'dead00beef'\", $this->app['db']->escape(hex2bin('dead00beef'), true));\n    }\n\n    public function testEscapeString()\n    {\n        $this->assertSame(\"'2147483647'\", $this->app['db']->escape('2147483647'));\n        $this->assertSame(\"'true'\", $this->app['db']->escape('true'));\n        $this->assertSame(\"'false'\", $this->app['db']->escape('false'));\n        $this->assertSame(\"'null'\", $this->app['db']->escape('null'));\n        $this->assertSame(\"'Hello\\'World'\", $this->app['db']->escape(\"Hello'World\"));\n    }\n\n    public function testEscapeStringInvalidUtf8()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding an invalid \\x80 utf-8 continuation byte\");\n    }\n\n    public function testEscapeStringNullByte()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding a \\00 byte\");\n    }\n\n    public function testEscapeArray()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(['a', 'b']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/FulltextTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_mysql')]\nclass FulltextTest extends MySqlTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('articles', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title', 200);\n            $table->text('body');\n            $table->fulltext(['title', 'body']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('articles');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('articles')->insert([\n            ['title' => 'MySQL Tutorial', 'body' => 'DBMS stands for DataBase ...'],\n            ['title' => 'How To Use MySQL Well', 'body' => 'After you went through a ...'],\n            ['title' => 'Optimizing MySQL', 'body' => 'In this tutorial, we show ...'],\n            ['title' => '1001 MySQL Tricks', 'body' => '1. Never run mysqld as root. 2. ...'],\n            ['title' => 'MySQL vs. YourSQL', 'body' => 'In the following database comparison ...'],\n            ['title' => 'MySQL Security', 'body' => 'When configured properly, MySQL ...'],\n        ]);\n    }\n\n    /** @link https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-language.html */\n    public function testWhereFulltext()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'database')->get();\n\n        $this->assertCount(2, $articles);\n        $this->assertSame('MySQL Tutorial', $articles[0]->title);\n        $this->assertSame('MySQL vs. YourSQL', $articles[1]->title);\n    }\n\n    /** @link https://dev.mysql.com/doc/refman/8.0/en/fulltext-boolean.html */\n    public function testWhereFulltextWithBooleanMode()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], '+MySQL -YourSQL', ['mode' => 'boolean'])->get();\n\n        $this->assertCount(5, $articles);\n    }\n\n    /** @link https://dev.mysql.com/doc/refman/8.0/en/fulltext-query-expansion.html */\n    public function testWhereFulltextWithExpandedQuery()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'database', ['expanded' => true])->get();\n\n        $this->assertCount(6, $articles);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/JoinLateralTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('pdo_mysql')]\n#[RequiresOperatingSystemFamily('Linux|Darwin')]\nclass JoinLateralTest extends MySqlTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title');\n            $table->integer('rating');\n            $table->unsignedBigInteger('user_id');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('posts');\n        Schema::drop('users');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->checkMySqlVersion();\n\n        DB::table('users')->insert([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        DB::table('posts')->insert([\n            ['title' => Str::random(), 'rating' => 1, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 3, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 7, 'user_id' => 1],\n        ]);\n    }\n\n    protected function checkMySqlVersion()\n    {\n        $mySqlVersion = DB::select('select version()')[0]->{'version()'} ?? '';\n\n        if (str_contains($mySqlVersion, 'Maria')) {\n            $this->markTestSkipped('Lateral joins are not supported on MariaDB'.__CLASS__);\n        } elseif ((float) $mySqlVersion < '8.0.14') {\n            $this->markTestSkipped('Lateral joins are not supported on MySQL < 8.0.14'.__CLASS__);\n        }\n    }\n\n    public function testJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(0, $userWithoutPosts);\n    }\n\n    public function testLeftJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(1, $userWithoutPosts);\n        $this->assertNull($userWithoutPosts[0]->best_post_title);\n        $this->assertNull($userWithoutPosts[0]->best_post_rating);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/MySql/MySqlTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\MySql;\n\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('mysql')]\nabstract class MySqlTestCase extends DatabaseTestCase\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/DatabaseEloquentPostgresIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseEloquentPostgresIntegrationTest extends PostgresTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('database_eloquent_postgres_integration_users')) {\n            Schema::create('database_eloquent_postgres_integration_users', function (Blueprint $table) {\n                $table->id();\n                $table->string('name')->nullable();\n                $table->string('email')->unique();\n                $table->timestamps();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('database_eloquent_postgres_integration_users');\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user1 = DatabaseEloquentPostgresIntegrationUser::createOrFirst(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = DatabaseEloquentPostgresIntegrationUser::createOrFirst(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = DatabaseEloquentPostgresIntegrationUser::createOrFirst(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = DatabaseEloquentPostgresIntegrationUser::createOrFirst(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user1 = DatabaseEloquentPostgresIntegrationUser::create(['email' => 'taylor@laravel.com']);\n\n        DB::transaction(function () use ($user1) {\n            $user2 = DatabaseEloquentPostgresIntegrationUser::createOrFirst(\n                ['email' => 'taylor@laravel.com'],\n                ['name' => 'Taylor Otwell']\n            );\n\n            $this->assertEquals($user1->id, $user2->id);\n            $this->assertSame('taylor@laravel.com', $user2->email);\n            $this->assertNull($user2->name);\n        });\n    }\n}\n\nclass DatabaseEloquentPostgresIntegrationUser extends Model\n{\n    protected $table = 'database_eloquent_postgres_integration_users';\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/DatabasePostgresConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_pgsql')]\nclass DatabasePostgresConnectionTest extends PostgresTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('json_table')) {\n            Schema::create('json_table', function (Blueprint $table) {\n                $table->json('json_col')->nullable();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('json_table');\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table('json_table')->insert(['json_col' => json_encode($value)]);\n\n        $this->assertSame($expected, DB::table('json_table')->whereNull(\"json_col->$key\")->exists());\n    }\n\n    #[DataProvider('jsonWhereNullDataProvider')]\n    public function testJsonWhereNotNull($expected, $key, array $value = ['value' => 123])\n    {\n        DB::table('json_table')->insert(['json_col' => json_encode($value)]);\n\n        $this->assertSame(! $expected, DB::table('json_table')->whereNotNull(\"json_col->$key\")->exists());\n    }\n\n    public static function jsonWhereNullDataProvider()\n    {\n        return [\n            'key not exists' => [true, 'invalid'],\n            'key exists and null' => [true, 'value', ['value' => null]],\n            'key exists and \"null\"' => [false, 'value', ['value' => 'null']],\n            'key exists and not null' => [false, 'value', ['value' => false]],\n            'nested key not exists' => [true, 'nested->invalid'],\n            'nested key exists and null' => [true, 'nested->value', ['nested' => ['value' => null]]],\n            'nested key exists and \"null\"' => [false, 'nested->value', ['nested' => ['value' => 'null']]],\n            'nested key exists and not null' => [false, 'nested->value', ['nested' => ['value' => false]]],\n            'array index not exists' => [true, '[0]', [1 => 'invalid']],\n            'array index exists and null' => [true, '[0]', [null]],\n            'array index exists and \"null\"' => [false, '[0]', ['null']],\n            'array index exists and not null' => [false, '[0]', [false]],\n            'multiple array index not exists' => [true, '[0][0]', [1 => [1 => 'invalid']]],\n            'multiple array index exists and null' => [true, '[0][0]', [[null]]],\n            'multiple array index exists and \"null\"' => [false, '[0][0]', [['null']]],\n            'multiple array index exists and not null' => [false, '[0][0]', [[false]]],\n            'nested array index not exists' => [true, 'nested[0]', ['nested' => [1 => 'nested->invalid']]],\n            'nested array index exists and null' => [true, 'nested->value[1]', ['nested' => ['value' => [0, null]]]],\n            'nested array index exists and \"null\"' => [false, 'nested->value[1]', ['nested' => ['value' => [0, 'null']]]],\n            'nested array index exists and not null' => [false, 'nested->value[1]', ['nested' => ['value' => [0, false]]]],\n        ];\n    }\n\n    public function testJsonPathUpdate()\n    {\n        DB::table('json_table')->insert([\n            ['json_col' => '{\"foo\":[\"bar\"]}'],\n            ['json_col' => '{\"foo\":[\"baz\"]}'],\n            ['json_col' => '{\"foo\":[[\"array\"]]}'],\n        ]);\n\n        $updatedCount = DB::table('json_table')->where('json_col->foo[0]', 'baz')->update([\n            'json_col->foo[0]' => 'updated',\n        ]);\n        $this->assertSame(1, $updatedCount);\n\n        $updatedCount = DB::table('json_table')->where('json_col->foo[0][0]', 'array')->update([\n            'json_col->foo[0][0]' => 'updated',\n        ]);\n        $this->assertSame(1, $updatedCount);\n    }\n\n    #[DataProvider('jsonContainsKeyDataProvider')]\n    public function testWhereJsonContainsKey($count, $column)\n    {\n        DB::table('json_table')->insert([\n            ['json_col' => '{\"foo\":{\"bar\":[\"baz\"]}}'],\n            ['json_col' => '{\"foo\":{\"bar\":false}}'],\n            ['json_col' => '{\"foo\":{}}'],\n            ['json_col' => '{\"foo\":[{\"bar\":\"bar\"},{\"baz\":\"baz\"}]}'],\n            ['json_col' => '{\"bar\":null}'],\n        ]);\n\n        $this->assertSame($count, DB::table('json_table')->whereJsonContainsKey($column)->count());\n    }\n\n    public static function jsonContainsKeyDataProvider()\n    {\n        return [\n            'string key' => [4, 'json_col->foo'],\n            'nested key exists' => [2, 'json_col->foo->bar'],\n            'string key missing' => [0, 'json_col->none'],\n            'integer key with arrow ' => [1, 'json_col->foo->bar->0'],\n            'integer key with braces' => [1, 'json_col->foo->bar[0]'],\n            'integer key missing' => [0, 'json_col->foo->bar[1]'],\n            'mixed keys' => [1, 'json_col->foo[1]->baz'],\n            'null value' => [1, 'json_col->bar'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/EscapeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse RuntimeException;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_pgsql')]\nclass EscapeTest extends PostgresTestCase\n{\n    public function testEscapeInt()\n    {\n        $this->assertSame('42', $this->app['db']->escape(42));\n        $this->assertSame('-6', $this->app['db']->escape(-6));\n    }\n\n    public function testEscapeFloat()\n    {\n        $this->assertSame('3.14159', $this->app['db']->escape(3.14159));\n        $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159));\n    }\n\n    public function testEscapeBool()\n    {\n        $this->assertSame('true', $this->app['db']->escape(true));\n        $this->assertSame('false', $this->app['db']->escape(false));\n    }\n\n    public function testEscapeNull()\n    {\n        $this->assertSame('null', $this->app['db']->escape(null));\n        $this->assertSame('null', $this->app['db']->escape(null, true));\n    }\n\n    public function testEscapeBinary()\n    {\n        $this->assertSame(\"'\\\\xdead00beef'::bytea\", $this->app['db']->escape(hex2bin('dead00beef'), true));\n    }\n\n    public function testEscapeString()\n    {\n        $this->assertSame(\"'2147483647'\", $this->app['db']->escape('2147483647'));\n        $this->assertSame(\"'true'\", $this->app['db']->escape('true'));\n        $this->assertSame(\"'false'\", $this->app['db']->escape('false'));\n        $this->assertSame(\"'null'\", $this->app['db']->escape('null'));\n        $this->assertSame(\"'Hello''World'\", $this->app['db']->escape(\"Hello'World\"));\n    }\n\n    public function testEscapeStringInvalidUtf8()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding an invalid \\x80 utf-8 continuation byte\");\n    }\n\n    public function testEscapeStringNullByte()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding a \\00 byte\");\n    }\n\n    public function testEscapeArray()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(['a', 'b']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/FulltextTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_pgsql')]\nclass FulltextTest extends PostgresTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('articles', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title', 200);\n            $table->text('body');\n            $table->fulltext(['title', 'body']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('articles');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('articles')->insert([\n            ['title' => 'PostgreSQL Tutorial', 'body' => 'DBMS stands for DataBase ...'],\n            ['title' => 'How To Use PostgreSQL Well', 'body' => 'After you went through a ...'],\n            ['title' => 'Optimizing PostgreSQL', 'body' => 'In this tutorial, we show ...'],\n            ['title' => '1001 PostgreSQL Tricks', 'body' => '1. Never run mysqld as root. 2. ...'],\n            ['title' => 'PostgreSQL vs. YourSQL', 'body' => 'In the following database comparison ...'],\n            ['title' => 'PostgreSQL Security', 'body' => 'When configured properly, PostgreSQL ...'],\n        ]);\n    }\n\n    public function testWhereFulltext()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'database')->orderBy('id')->get();\n\n        $this->assertCount(2, $articles);\n        $this->assertSame('PostgreSQL Tutorial', $articles[0]->title);\n        $this->assertSame('PostgreSQL vs. YourSQL', $articles[1]->title);\n    }\n\n    #[RequiresDatabase('pgsql', '>=11.0')]\n    public function testWhereFulltextWithWebsearch()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], '+PostgreSQL -YourSQL', ['mode' => 'websearch'])->get();\n\n        $this->assertCount(5, $articles);\n    }\n\n    public function testWhereFulltextWithPlain()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'PostgreSQL tutorial', ['mode' => 'plain'])->get();\n\n        $this->assertCount(2, $articles);\n    }\n\n    public function testWhereFulltextWithPhrase()\n    {\n        $articles = DB::table('articles')->whereFullText(['title', 'body'], 'PostgreSQL tutorial', ['mode' => 'phrase'])->get();\n\n        $this->assertCount(1, $articles);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/JoinLateralTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('pdo_pgsql')]\n#[RequiresOperatingSystemFamily('Linux|Darwin')]\nclass JoinLateralTest extends PostgresTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title');\n            $table->integer('rating');\n            $table->unsignedBigInteger('user_id');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('posts');\n        Schema::drop('users');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('users')->insert([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        DB::table('posts')->insert([\n            ['title' => Str::random(), 'rating' => 1, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 3, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 7, 'user_id' => 1],\n        ]);\n    }\n\n    public function testJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(0, $userWithoutPosts);\n    }\n\n    public function testLeftJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(1, $userWithoutPosts);\n        $this->assertNull($userWithoutPosts[0]->best_post_title);\n        $this->assertNull($userWithoutPosts[0]->best_post_rating);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_pgsql')]\nclass PostgresSchemaBuilderTest extends PostgresTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.connections.pgsql.search_path', 'public,private');\n    }\n\n    protected function defineDatabaseMigrations()\n    {\n        parent::defineDatabaseMigrations();\n\n        DB::statement('create schema if not exists private');\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        DB::statement('drop table if exists public.table');\n        DB::statement('drop table if exists private.table');\n\n        DB::statement('drop view if exists public.foo');\n        DB::statement('drop view if exists private.foo');\n\n        DB::statement('drop schema private');\n\n        parent::destroyDatabaseMigrations();\n    }\n\n    public function testDropAllTablesOnAllSchemas()\n    {\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n        Schema::create('private.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        $this->assertFalse(Schema::hasTable('public.table'));\n        $this->assertFalse(Schema::hasTable('private.table'));\n    }\n\n    public function testDropAllTablesUsesDontDropConfigOnAllSchemas()\n    {\n        $this->app['config']->set('database.connections.pgsql.dont_drop', ['spatial_ref_sys', 'table']);\n        DB::purge('pgsql');\n\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n        Schema::create('private.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        $this->assertTrue(Schema::hasTable('public.table'));\n        $this->assertTrue(Schema::hasTable('private.table'));\n    }\n\n    public function testDropAllTablesUsesDontDropConfigOnOneSchema()\n    {\n        $this->app['config']->set('database.connections.pgsql.dont_drop', ['spatial_ref_sys', 'private.table']);\n        DB::purge('pgsql');\n\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n        Schema::create('private.table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        $this->assertFalse(Schema::hasTable('public.table'));\n        $this->assertTrue(Schema::hasTable('private.table'));\n    }\n\n    public function testDropAllViewsOnAllSchemas()\n    {\n        DB::statement('create view public.foo (id) as select 1');\n        DB::statement('create view private.foo (id) as select 1');\n\n        $this->assertTrue(Schema::hasView('public.foo'));\n        $this->assertTrue(Schema::hasView('private.foo'));\n\n        Schema::dropAllViews();\n\n        $this->assertFalse(Schema::hasView('public.foo'));\n        $this->assertFalse(Schema::hasView('private.foo'));\n    }\n\n    public function testAddTableCommentOnNewTable()\n    {\n        Schema::create('public.posts', function (Blueprint $table) {\n            $table->comment('This is a comment');\n        });\n\n        $this->assertEquals('This is a comment', DB::selectOne(\"select obj_description('public.posts'::regclass, 'pg_class')\")->obj_description);\n    }\n\n    public function testAddTableCommentOnExistingTable()\n    {\n        Schema::create('public.posts', function (Blueprint $table) {\n            $table->id();\n            $table->comment('This is a comment');\n        });\n\n        Schema::table('public.posts', function (Blueprint $table) {\n            $table->comment('This is a new comment');\n        });\n\n        $this->assertEquals('This is a new comment', DB::selectOne(\"select obj_description('public.posts'::regclass, 'pg_class')\")->obj_description);\n    }\n\n    public function testGetTables()\n    {\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->string('name');\n        });\n\n        Schema::create('private.table', function (Blueprint $table) {\n            $table->integer('votes');\n        });\n\n        $tables = Schema::getTables();\n\n        $this->assertNotEmpty(array_filter($tables, function ($table) {\n            return $table['name'] === 'table' && $table['schema'] === 'public';\n        }));\n        $this->assertNotEmpty(array_filter($tables, function ($table) {\n            return $table['name'] === 'table' && $table['schema'] === 'private';\n        }));\n    }\n\n    public function testGetViews()\n    {\n        DB::statement('create view public.foo (id) as select 1');\n        DB::statement('create view private.foo (id) as select 1');\n\n        $views = Schema::getViews();\n\n        $this->assertNotEmpty(array_filter($views, function ($view) {\n            return $view['name'] === 'foo' && $view['schema'] === 'public';\n        }));\n        $this->assertNotEmpty(array_filter($views, function ($view) {\n            return $view['name'] === 'foo' && $view['schema'] === 'private';\n        }));\n    }\n\n    #[RequiresDatabase('pgsql', '>=11.0')]\n    public function testDropPartitionedTables()\n    {\n        DB::statement('create table groups (id bigserial, tenant_id bigint, name varchar, primary key (id, tenant_id)) partition by hash (tenant_id)');\n        DB::statement('create table groups_1 partition of groups for values with (modulus 2, remainder 0)');\n        DB::statement('create table groups_2 partition of groups for values with (modulus 2, remainder 1)');\n\n        $tables = array_column(Schema::getTables(), 'name');\n\n        $this->assertContains('groups', $tables);\n        $this->assertContains('groups_1', $tables);\n        $this->assertContains('groups_2', $tables);\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        $tables = array_column(Schema::getTables(), 'name');\n\n        $this->assertNotContains('groups', $tables);\n        $this->assertNotContains('groups_1', $tables);\n        $this->assertNotContains('groups_2', $tables);\n    }\n\n    public function testGetRawIndex()\n    {\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n            $table->rawIndex(\"DATE_TRUNC('year'::text,created_at)\", 'table_raw_index');\n        });\n\n        $indexes = Schema::getIndexes('public.table');\n\n        $this->assertSame([], collect($indexes)->firstWhere('name', 'table_raw_index')['columns']);\n    }\n\n    public function testCreateIndexesOnline()\n    {\n        Schema::create('public.table', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n            $table->string('title', 200);\n            $table->text('body');\n\n            $table->unique('title')->online();\n            $table->index(['created_at'])->online();\n            $table->fullText(['body'])->online();\n            $table->rawIndex(\"DATE_TRUNC('year'::text,created_at)\", 'table_raw_index')->online();\n        });\n\n        $indexes = Schema::getIndexes('public.table');\n        $indexNames = collect($indexes)->pluck('name');\n\n        $this->assertContains('public_table_title_unique', $indexNames);\n        $this->assertContains('public_table_created_at_index', $indexNames);\n        $this->assertContains('public_table_body_fulltext', $indexNames);\n        $this->assertContains('table_raw_index', $indexNames);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Postgres/PostgresTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Postgres;\n\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('pgsql')]\nabstract class PostgresTestCase extends DatabaseTestCase\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/QueryBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Contracts\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Database\\MultipleRecordsFoundException;\nuse Illuminate\\Database\\RecordsNotFoundException;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Testing\\Assert as PHPUnit;\nuse Orchestra\\Testbench\\Attributes\\DefineEnvironment;\nuse PDO;\nuse PDOException;\n\nclass QueryBuilderTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->text('content');\n            $table->timestamp('created_at');\n        });\n\n        DB::table('posts')->insert([\n            ['title' => 'Foo Post', 'content' => 'Lorem Ipsum.', 'created_at' => new Carbon('2017-11-12 13:14:15')],\n            ['title' => 'Bar Post', 'content' => 'Lorem Ipsum.', 'created_at' => new Carbon('2018-01-02 03:04:05')],\n        ]);\n    }\n\n    public function testIncrement()\n    {\n        Schema::create('accounting', function (Blueprint $table) {\n            $table->increments('id');\n            $table->float('wallet_1');\n            $table->float('wallet_2');\n            $table->integer('user_id');\n            $table->string('name', 20);\n        });\n\n        DB::table('accounting')->insert([\n            [\n                'wallet_1' => 100,\n                'wallet_2' => 200,\n                'user_id' => 1,\n                'name' => 'Taylor',\n            ],\n            [\n                'wallet_1' => 15,\n                'wallet_2' => 300,\n                'user_id' => 2,\n                'name' => 'Otwell',\n            ],\n        ]);\n        $connection = DB::table('accounting')->getConnection();\n        $connection->enableQueryLog();\n\n        DB::table('accounting')->where('user_id', 2)->incrementEach([\n            'wallet_1' => 10,\n            'wallet_2' => -20,\n        ], ['name' => 'foo']);\n\n        $queryLogs = $connection->getQueryLog();\n        $this->assertCount(1, $queryLogs);\n\n        $rows = DB::table('accounting')->get();\n\n        $this->assertCount(2, $rows);\n        // other rows are not affected.\n        $this->assertEquals([\n            'id' => 1,\n            'wallet_1' => 100,\n            'wallet_2' => 200,\n            'user_id' => 1,\n            'name' => 'Taylor',\n        ], (array) $rows[0]);\n\n        $this->assertEquals([\n            'id' => 2,\n            'wallet_1' => 15 + 10,\n            'wallet_2' => 300 - 20,\n            'user_id' => 2,\n            'name' => 'foo',\n        ], (array) $rows[1]);\n\n        // without the second argument.\n        $affectedRowsCount = DB::table('accounting')->where('user_id', 2)->incrementEach([\n            'wallet_1' => 20,\n            'wallet_2' => 20,\n        ]);\n\n        $this->assertEquals(1, $affectedRowsCount);\n\n        $rows = DB::table('accounting')->get();\n\n        $this->assertEquals([\n            'id' => 2,\n            'wallet_1' => 15 + (10 + 20),\n            'wallet_2' => 300 + (-20 + 20),\n            'user_id' => 2,\n            'name' => 'foo',\n        ], (array) $rows[1]);\n\n        // Test Can affect multiple rows at once.\n        $affectedRowsCount = DB::table('accounting')->incrementEach([\n            'wallet_1' => 31.5,\n            'wallet_2' => '-32.5',\n        ]);\n\n        $this->assertEquals(2, $affectedRowsCount);\n\n        $rows = DB::table('accounting')->get();\n        $this->assertEquals([\n            'id' => 1,\n            'wallet_1' => 100 + 31.5,\n            'wallet_2' => 200 - 32.5,\n            'user_id' => 1,\n            'name' => 'Taylor',\n        ], (array) $rows[0]);\n\n        $this->assertEquals([\n            'id' => 2,\n            'wallet_1' => 15 + (10 + 20 + 31.5),\n            'wallet_2' => 300 + (-20 + 20 - 32.5),\n            'user_id' => 2,\n            'name' => 'foo',\n        ], (array) $rows[1]);\n\n        // In case of a conflict, the second argument wins and sets a fixed value:\n        $affectedRowsCount = DB::table('accounting')->incrementEach([\n            'wallet_1' => 3000,\n        ], ['wallet_1' => 1.5]);\n\n        $this->assertEquals(2, $affectedRowsCount);\n\n        $rows = DB::table('accounting')->get();\n\n        $this->assertEquals(1.5, $rows[0]->wallet_1);\n        $this->assertEquals(1.5, $rows[1]->wallet_1);\n\n        Schema::drop('accounting');\n    }\n\n    public function testSole()\n    {\n        $expected = ['id' => '1', 'title' => 'Foo Post'];\n\n        $this->assertEquals($expected, (array) DB::table('posts')->where('title', 'Foo Post')->select('id', 'title')->sole());\n    }\n\n    public function testSoleWithParameters()\n    {\n        $expected = ['id' => '1'];\n\n        $this->assertEquals($expected, (array) DB::table('posts')->where('title', 'Foo Post')->sole('id'));\n        $this->assertEquals($expected, (array) DB::table('posts')->where('title', 'Foo Post')->sole(['id']));\n\n        $expected = ['id' => '1', 'title' => 'Foo Post'];\n        $this->assertEquals($expected, (array) DB::table('posts')->where('title', 'Foo Post')->sole(['id', 'title']));\n    }\n\n    public function testSoleFailsForMultipleRecords()\n    {\n        DB::table('posts')->insert([\n            ['title' => 'Foo Post', 'content' => 'Lorem Ipsum.', 'created_at' => new Carbon('2017-11-12 13:14:15')],\n        ]);\n\n        $this->expectExceptionObject(new MultipleRecordsFoundException(2));\n\n        DB::table('posts')->where('title', 'Foo Post')->sole();\n    }\n\n    public function testSoleFailsIfNoRecords()\n    {\n        $this->expectException(RecordsNotFoundException::class);\n\n        DB::table('posts')->where('title', 'Baz Post')->sole();\n    }\n\n    public function testSelect()\n    {\n        $expected = ['id' => '1', 'title' => 'Foo Post'];\n\n        $this->assertEquals($expected, (array) DB::table('posts')->select('id', 'title')->first());\n        $this->assertEquals($expected, (array) DB::table('posts')->select(['id', 'title'])->first());\n\n        $this->assertCount(4, (array) DB::table('posts')->select()->first());\n    }\n\n    public function testSelectReplacesExistingSelects()\n    {\n        $this->assertEquals(\n            ['id' => '1', 'title' => 'Foo Post'],\n            (array) DB::table('posts')->select('content')->select(['id', 'title'])->first()\n        );\n    }\n\n    public function testSelectWithSubQuery()\n    {\n        $this->assertEquals(\n            ['id' => '1', 'title' => 'Foo Post', 'foo' => 'Lorem Ipsum.'],\n            (array) DB::table('posts')->select(['id', 'title', 'foo' => function ($query) {\n                $query->select('content');\n            }])->first()\n        );\n    }\n\n    public function testAddSelect()\n    {\n        $expected = ['id' => '1', 'title' => 'Foo Post', 'content' => 'Lorem Ipsum.'];\n\n        $this->assertEquals($expected, (array) DB::table('posts')->select('id')->addSelect('title', 'content')->first());\n        $this->assertEquals($expected, (array) DB::table('posts')->select('id')->addSelect(['title', 'content'])->first());\n        $this->assertEquals($expected, (array) DB::table('posts')->addSelect(['id', 'title', 'content'])->first());\n\n        $this->assertCount(4, (array) DB::table('posts')->addSelect([])->first());\n        $this->assertEquals(['id' => '1'], (array) DB::table('posts')->select('id')->addSelect([])->first());\n    }\n\n    public function testAddSelectWithSubQuery()\n    {\n        $this->assertEquals(\n            ['id' => '1', 'title' => 'Foo Post', 'foo' => 'Lorem Ipsum.'],\n            (array) DB::table('posts')->addSelect(['id', 'title', 'foo' => function ($query) {\n                $query->select('content');\n            }])->first()\n        );\n    }\n\n    public function testFromWithAlias()\n    {\n        $this->assertCount(2, DB::table('posts', 'alias')->select('alias.*')->get());\n    }\n\n    public function testFromWithSubQuery()\n    {\n        $this->assertSame(\n            'Fake Post',\n            DB::table(function ($query) {\n                $query->selectRaw(\"'Fake Post' as title\");\n            }, 'posts')->first()->title\n        );\n    }\n\n    public function testWhereValueSubQuery()\n    {\n        $subQuery = function ($query) {\n            $query->selectRaw(\"'Sub query value'\");\n        };\n\n        $this->assertTrue(DB::table('posts')->where($subQuery, 'Sub query value')->exists());\n        $this->assertFalse(DB::table('posts')->where($subQuery, 'Does not match')->exists());\n        $this->assertTrue(DB::table('posts')->where($subQuery, '!=', 'Does not match')->exists());\n    }\n\n    public function testWhereValueSubQueryBuilder()\n    {\n        $subQuery = DB::table('posts')->selectRaw(\"'Sub query value'\")->limit(1);\n\n        $this->assertTrue(DB::table('posts')->where($subQuery, 'Sub query value')->exists());\n        $this->assertFalse(DB::table('posts')->where($subQuery, 'Does not match')->exists());\n        $this->assertTrue(DB::table('posts')->where($subQuery, '!=', 'Does not match')->exists());\n\n        $this->assertTrue(DB::table('posts')->where(DB::raw('\\'Sub query value\\''), $subQuery)->exists());\n        $this->assertFalse(DB::table('posts')->where(DB::raw('\\'Does not match\\''), $subQuery)->exists());\n        $this->assertTrue(DB::table('posts')->where(DB::raw('\\'Does not match\\''), '!=', $subQuery)->exists());\n    }\n\n    public function testWhereNot()\n    {\n        $results = DB::table('posts')->whereNot(function ($query) {\n            $query->where('title', 'Foo Post');\n        })->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Bar Post', $results[0]->title);\n    }\n\n    public function testWhereNotInputStringParameter()\n    {\n        $results = DB::table('posts')->whereNot('title', 'Foo Post')->get();\n\n        $this->assertCount(1, $results);\n        $this->assertSame('Bar Post', $results[0]->title);\n\n        DB::table('posts')->insert([\n            ['title' => 'Baz Post', 'content' => 'Lorem Ipsum.', 'created_at' => new Carbon('2017-11-12 13:14:15')],\n        ]);\n\n        $results = DB::table('posts')->whereNot('title', 'Foo Post')->whereNot('title', 'Bar Post')->get();\n        $this->assertSame('Baz Post', $results[0]->title);\n    }\n\n    public function testOrWhereNot()\n    {\n        $results = DB::table('posts')->where('id', 1)->orWhereNot(function ($query) {\n            $query->where('title', 'Foo Post');\n        })->get();\n\n        $this->assertCount(2, $results);\n    }\n\n    public function testWhereDate()\n    {\n        $this->assertSame(1, DB::table('posts')->whereDate('created_at', '2018-01-02')->count());\n        $this->assertSame(1, DB::table('posts')->whereDate('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testWhereDateWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->whereDate('created_at', '? OR 1=1', '2018-01-02');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'created_at',\n                'type' => 'Date',\n                'value' => '? OR 1=1',\n                'boolean' => 'and',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(0, $sql->count());\n    }\n\n    public function testOrWhereDate()\n    {\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDate('created_at', '2018-01-02')->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDate('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testOrWhereDateWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->where('id', 1)->orWhereDate('created_at', '? OR 1=1', '2018-01-02');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'id',\n                'type' => 'Basic',\n                'value' => 1,\n                'boolean' => 'and',\n            ],\n            [\n                'column' => 'created_at',\n                'type' => 'Date',\n                'value' => '? OR 1=1',\n                'boolean' => 'or',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(1, $sql->count());\n    }\n\n    public function testWhereDay()\n    {\n        $this->assertSame(1, DB::table('posts')->whereDay('created_at', '02')->count());\n        $this->assertSame(1, DB::table('posts')->whereDay('created_at', 2)->count());\n        $this->assertSame(1, DB::table('posts')->whereDay('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    public function testWhereDayWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->whereDay('created_at', '? OR 1=1', '02');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'created_at',\n                'type' => 'Day',\n                'value' => '00',\n                'boolean' => 'and',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(0, $sql->count());\n    }\n\n    public function testOrWhereDay()\n    {\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDay('created_at', '02')->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDay('created_at', 2)->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereDay('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    public function testOrWhereDayWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->where('id', 1)->orWhereDay('created_at', '? OR 1=1', '02');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'id',\n                'type' => 'Basic',\n                'value' => 1,\n                'boolean' => 'and',\n            ],\n            [\n                'column' => 'created_at',\n                'type' => 'Day',\n                'value' => '00',\n                'boolean' => 'or',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(1, $sql->count());\n    }\n\n    public function testWhereMonth()\n    {\n        $this->assertSame(1, DB::table('posts')->whereMonth('created_at', '01')->count());\n        $this->assertSame(1, DB::table('posts')->whereMonth('created_at', 1)->count());\n        $this->assertSame(1, DB::table('posts')->whereMonth('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    public function testWhereMonthWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->whereMonth('created_at', '? OR 1=1', '01');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'created_at',\n                'type' => 'Month',\n                'value' => '00',\n                'boolean' => 'and',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(0, $sql->count());\n    }\n\n    public function testOrWhereMonth()\n    {\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereMonth('created_at', '01')->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereMonth('created_at', 1)->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereMonth('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    public function testOrWhereMonthWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->where('id', 1)->orWhereMonth('created_at', '? OR 1=1', '01');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'id',\n                'type' => 'Basic',\n                'value' => 1,\n                'boolean' => 'and',\n            ],\n            [\n                'column' => 'created_at',\n                'type' => 'Month',\n                'value' => '00',\n                'boolean' => 'or',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(1, $sql->count());\n    }\n\n    public function testWhereYear()\n    {\n        $this->assertSame(1, DB::table('posts')->whereYear('created_at', '2018')->count());\n        $this->assertSame(1, DB::table('posts')->whereYear('created_at', 2018)->count());\n        $this->assertSame(1, DB::table('posts')->whereYear('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testWhereYearWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->whereYear('created_at', '? OR 1=1', '2018');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'created_at',\n                'type' => 'Year',\n                'value' => '? OR 1=1',\n                'boolean' => 'and',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(0, $sql->count());\n    }\n\n    public function testOrWhereYear()\n    {\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereYear('created_at', '2018')->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereYear('created_at', 2018)->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereYear('created_at', new Carbon('2018-01-02'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testOrWhereYearWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->where('id', 1)->orWhereYear('created_at', '? OR 1=1', '2018');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'id',\n                'type' => 'Basic',\n                'value' => 1,\n                'boolean' => 'and',\n            ],\n            [\n                'column' => 'created_at',\n                'type' => 'Year',\n                'value' => '? OR 1=1',\n                'boolean' => 'or',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(1, $sql->count());\n    }\n\n    public function testWhereTime()\n    {\n        $this->assertSame(1, DB::table('posts')->whereTime('created_at', '03:04:05')->count());\n        $this->assertSame(1, DB::table('posts')->whereTime('created_at', new Carbon('2018-01-02 03:04:05'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testWhereTimeWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->whereTime('created_at', '? OR 1=1', '03:04:05');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'created_at',\n                'type' => 'Time',\n                'value' => '? OR 1=1',\n                'boolean' => 'and',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(0, $sql->count());\n    }\n\n    public function testOrWhereTime()\n    {\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereTime('created_at', '03:04:05')->count());\n        $this->assertSame(2, DB::table('posts')->where('id', 1)->orWhereTime('created_at', new Carbon('2018-01-02 03:04:05'))->count());\n    }\n\n    #[DefineEnvironment('defineEnvironmentWouldThrowsPDOException')]\n    public function testOrWhereTimeWithInvalidOperator()\n    {\n        $sql = DB::table('posts')->where('id', 1)->orWhereTime('created_at', '? OR 1=1', '03:04:05');\n\n        PHPUnit::assertArraySubset([\n            [\n                'column' => 'id',\n                'type' => 'Basic',\n                'value' => 1,\n                'boolean' => 'and',\n            ],\n            [\n                'column' => 'created_at',\n                'type' => 'Time',\n                'value' => '? OR 1=1',\n                'boolean' => 'or',\n            ],\n        ], $sql->wheres);\n\n        $this->assertSame(1, $sql->count());\n    }\n\n    public function testWhereNested()\n    {\n        $results = DB::table('posts')->where('content', 'Lorem Ipsum.')->whereNested(function ($query) {\n            $query->where('title', 'Foo Post')\n                ->orWhere('title', 'Bar Post');\n        })->count();\n        $this->assertSame(2, $results);\n    }\n\n    public function testPaginateWithSpecificColumns()\n    {\n        $result = DB::table('posts')->paginate(5, ['title', 'content']);\n\n        $this->assertInstanceOf(LengthAwarePaginator::class, $result);\n        $this->assertEquals($result->items(), [\n            (object) ['title' => 'Foo Post', 'content' => 'Lorem Ipsum.'],\n            (object) ['title' => 'Bar Post', 'content' => 'Lorem Ipsum.'],\n        ]);\n    }\n\n    public function testChunkMap()\n    {\n        DB::enableQueryLog();\n\n        $results = DB::table('posts')->orderBy('id')->chunkMap(function ($post) {\n            return $post->title;\n        }, 1);\n\n        $this->assertCount(2, $results);\n        $this->assertSame('Foo Post', $results[0]);\n        $this->assertSame('Bar Post', $results[1]);\n        $this->assertCount(3, DB::getQueryLog());\n    }\n\n    public function testPluck()\n    {\n        // Test SELECT override, since pluck will take the first column.\n        $this->assertSame([\n            'Foo Post',\n            'Bar Post',\n        ], DB::table('posts')->select(['content', 'id', 'title'])->pluck('title')->toArray());\n\n        // Test without SELECT override.\n        $this->assertSame([\n            'Foo Post',\n            'Bar Post',\n        ], DB::table('posts')->pluck('title')->toArray());\n\n        // Test specific key.\n        $this->assertSame([\n            1 => 'Foo Post',\n            2 => 'Bar Post',\n        ], DB::table('posts')->pluck('title', 'id')->toArray());\n\n        $results = DB::table('posts')->pluck('title', 'created_at');\n\n        // Test timestamps (truncates RDBMS differences).\n        $this->assertSame([\n            '2017-11-12 13:14:15',\n            '2018-01-02 03:04:05',\n        ], $results->keys()->map(fn ($v) => substr($v, 0, 19))->toArray());\n        $this->assertSame([\n            'Foo Post',\n            'Bar Post',\n        ], $results->values()->toArray());\n\n        // Test duplicate keys (a match will override a previous match).\n        $this->assertSame([\n            'Lorem Ipsum.' => 'Bar Post',\n        ], DB::table('posts')->pluck('title', 'content')->toArray());\n\n        // Test custom select query before calling pluck.\n        $result = DB::table('posts')\n            ->selectSub(DB::table('posts')->selectRaw('COUNT(*)'), 'total_posts_count')\n            ->pluck('total_posts_count')\n            ->toArray();\n        // Cast for database compatibility.\n        $this->assertSame(2, (int) $result[0]);\n        $this->assertSame(2, (int) $result[1]);\n    }\n\n    public function testFetchUsing()\n    {\n        // Fetch column as a list.\n        $this->assertSame([\n            'Foo Post',\n            'Bar Post',\n        ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->get()->toArray());\n\n        // Fetch the second column as a list (zero-indexed).\n        $this->assertSame([\n            'Lorem Ipsum.',\n            'Lorem Ipsum.',\n        ], DB::table('posts')->select(['title', 'content'])->fetchUsing(PDO::FETCH_COLUMN, 1)->get()->toArray());\n\n        // Fetch two columns as key value pairs.\n        $this->assertSame([\n            1 => 'Foo Post',\n            2 => 'Bar Post',\n        ], DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_KEY_PAIR)->get()->toArray());\n\n        // Fetch data as associative array with custom key.\n        $result = DB::table('posts')->select(['id', 'title'])->fetchUsing(PDO::FETCH_UNIQUE)->get()->toArray();\n        // Note: results are keyed by their post id here.\n        $this->assertSame('Foo Post', $result[1]->title);\n        $this->assertSame('Bar Post', $result[2]->title);\n\n        // Use a cursor.\n        $this->assertSame([\n            'Foo Post',\n            'Bar Post',\n        ], DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_COLUMN)->cursor()->collect()->toArray());\n\n        // Test the default 'object' fetch mode.\n        $result = DB::table('posts')->select(['title'])->fetchUsing(PDO::FETCH_OBJ)->get()->toArray();\n        $result2 = DB::table('posts')->select(['title'])->fetchUsing()->get()->toArray();\n        $this->assertSame('Foo Post', $result[0]->title);\n        $this->assertSame('Bar Post', $result[1]->title);\n        $this->assertSame('Foo Post', $result2[0]->title);\n        $this->assertSame('Bar Post', $result2[1]->title);\n    }\n\n    protected function defineEnvironmentWouldThrowsPDOException($app)\n    {\n        $this->afterApplicationCreated(function () {\n            if (in_array($this->driver, ['pgsql', 'sqlsrv'])) {\n                $this->expectException(PDOException::class);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/QueryBuilderUpdateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nrequire_once 'Enums.php';\n\nclass QueryBuilderUpdateTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('example', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name')->nullable();\n            $table->string('title')->nullable();\n            $table->string('status')->nullable();\n            $table->integer('credits')->nullable();\n            $table->json('payload')->nullable();\n        });\n\n        Schema::create('example_credits', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedBigInteger('example_id');\n            $table->integer('credits');\n        });\n    }\n\n    #[DataProvider('jsonValuesDataProvider')]\n    #[RequiresDatabase(['sqlite', 'mysql', 'mariadb'])]\n    public function testBasicUpdateForJson($column, $given, $expected)\n    {\n        DB::table('example')->insert([\n            ['name' => 'Taylor Otwell', 'title' => 'Mr.'],\n        ]);\n\n        DB::table('example')->update([\n            $column => $given,\n        ]);\n\n        $this->assertDatabaseHas('example', [\n            'name' => 'Taylor Otwell',\n            'title' => 'Mr.',\n            $column => $column === 'payload' ? $this->castAsJson($expected) : $expected,\n        ]);\n    }\n\n    #[RequiresDatabase(['sqlite', 'mysql', 'mariadb'])]\n    public function testSubqueryUpdate()\n    {\n        DB::table('example')->insert([\n            ['name' => 'Taylor Otwell', 'title' => 'Mr.'],\n            ['name' => 'Tim MacDonald', 'title' => 'Mr.'],\n        ]);\n\n        DB::table('example_credits')->insert([\n            ['example_id' => 1, 'credits' => 10],\n            ['example_id' => 1, 'credits' => 20],\n        ]);\n\n        $this->assertDatabaseHas('example', [\n            'name' => 'Taylor Otwell',\n            'title' => 'Mr.',\n            'credits' => null,\n        ]);\n\n        $this->assertDatabaseHas('example', [\n            'name' => 'Tim MacDonald',\n            'title' => 'Mr.',\n            'credits' => null,\n        ]);\n\n        DB::table('example')->update([\n            'credits' => DB::table('example_credits')->selectRaw('sum(credits)')->whereColumn('example_credits.example_id', 'example.id'),\n        ]);\n\n        $this->assertDatabaseHas('example', [\n            'name' => 'Taylor Otwell',\n            'title' => 'Mr.',\n            'credits' => 30,\n        ]);\n\n        $this->assertDatabaseHas('example', [\n            'name' => 'Tim MacDonald',\n            'title' => 'Mr.',\n            'credits' => null,\n        ]);\n    }\n\n    public static function jsonValuesDataProvider()\n    {\n        yield ['payload', ['Laravel', 'Founder'], ['Laravel', 'Founder']];\n        yield ['payload', collect(['Laravel', 'Founder']), ['Laravel', 'Founder']];\n        yield ['status', StringStatus::draft, 'draft'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/QueryBuilderWhereLikeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass QueryBuilderWhereLikeTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('name', 200);\n            $table->text('email');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('users')->insert([\n            ['name' => 'John Doe', 'email' => 'John.Doe@example.com'],\n            ['name' => 'Jane Doe', 'email' => 'janedoe@example.com'],\n            ['name' => 'Dale doe', 'email' => 'Dale.Doe@example.com'],\n            ['name' => 'Earl Smith', 'email' => 'Earl.Smith@example.com'],\n            ['name' => 'tim smith', 'email' => 'tim.smith@example.com'],\n        ]);\n    }\n\n    public function testWhereLike()\n    {\n        $users = DB::table('users')->whereLike('email', 'john.doe@example.com')->get();\n        $this->assertCount(1, $users);\n        $this->assertSame('John.Doe@example.com', $users[0]->email);\n\n        $this->assertSame(4, DB::table('users')->whereNotLike('email', 'john.doe@example.com')->count());\n    }\n\n    public function testWhereLikeWithPercentWildcard()\n    {\n        $this->assertSame(5, DB::table('users')->whereLike('email', '%@example.com')->count());\n        $this->assertSame(2, DB::table('users')->whereNotLike('email', '%Doe%')->count());\n\n        $users = DB::table('users')->whereLike('email', 'john%')->get();\n        $this->assertCount(1, $users);\n        $this->assertSame('John.Doe@example.com', $users[0]->email);\n    }\n\n    public function testWhereLikeWithUnderscoreWildcard()\n    {\n        $users = DB::table('users')->whereLike('email', '_a_e_%@example.com')->get();\n        $this->assertCount(2, $users);\n        $this->assertSame('janedoe@example.com', $users[0]->email);\n        $this->assertSame('Dale.Doe@example.com', $users[1]->email);\n    }\n\n    public function testWhereLikeCaseSensitive()\n    {\n        if ($this->driver === 'sqlsrv') {\n            $this->markTestSkipped('The case-sensitive whereLike clause is not supported on MSSQL.');\n        }\n\n        $users = DB::table('users')->whereLike('email', 'john.doe@example.com', true)->get();\n        $this->assertCount(0, $users);\n\n        $users = DB::table('users')->whereLike('email', 'tim.smith@example.com', true)->get();\n        $this->assertCount(1, $users);\n        $this->assertSame('tim.smith@example.com', $users[0]->email);\n        $this->assertSame(5, DB::table('users')->whereNotLike('email', 'john.doe@example.com', true)->count());\n    }\n\n    public function testWhereLikeWithPercentWildcardCaseSensitive()\n    {\n        if ($this->driver === 'sqlsrv') {\n            $this->markTestSkipped('The case-sensitive whereLike clause is not supported on MSSQL.');\n        }\n\n        $this->assertSame(2, DB::table('users')->whereLike('email', '%Doe@example.com', true)->count());\n        $this->assertSame(4, DB::table('users')->whereNotLike('email', '%smith%', true)->count());\n\n        $users = DB::table('users')->whereLike('email', '%Doe@example.com', true)->get();\n        $this->assertCount(2, $users);\n        $this->assertSame('John.Doe@example.com', $users[0]->email);\n        $this->assertSame('Dale.Doe@example.com', $users[1]->email);\n    }\n\n    public function testWhereLikeWithUnderscoreWildcardCaseSensitive()\n    {\n        if ($this->driver === 'sqlsrv') {\n            $this->markTestSkipped('The case-sensitive whereLike clause is not supported on MSSQL.');\n        }\n\n        $users = DB::table('users')->whereLike('email', 'j__edoe@example.com', true)->get();\n        $this->assertCount(1, $users);\n        $this->assertSame('janedoe@example.com', $users[0]->email);\n\n        $users = DB::table('users')->whereNotLike('email', '%_oe@example.com', true)->get();\n        $this->assertCount(2, $users);\n        $this->assertSame('Earl.Smith@example.com', $users[0]->email);\n        $this->assertSame('tim.smith@example.com', $users[1]->email);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/QueryingWithEnumsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\ninclude_once 'Enums.php';\n\nclass QueryingWithEnumsTest extends DatabaseTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('enum_casts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('string_status', 100)->nullable();\n            $table->integer('integer_status')->nullable();\n            $table->string('non_backed_status', 100)->nullable();\n        });\n    }\n\n    public function testCanQueryWithEnums()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => 'pending',\n            'integer_status' => 1,\n            'non_backed_status' => 'pending',\n        ]);\n\n        $record = DB::table('enum_casts')->where('string_status', StringStatus::pending)->first();\n        $record2 = DB::table('enum_casts')->where('integer_status', IntegerStatus::pending)->first();\n        $record3 = DB::table('enum_casts')->whereIn('integer_status', [IntegerStatus::pending])->first();\n        $record4 = DB::table('enum_casts')->where('non_backed_status', NonBackedStatus::pending)->first();\n\n        $this->assertNotNull($record);\n        $this->assertNotNull($record2);\n        $this->assertNotNull($record3);\n        $this->assertNotNull($record4);\n        $this->assertSame('pending', $record->string_status);\n        $this->assertEquals(1, $record2->integer_status);\n        $this->assertSame('pending', $record4->non_backed_status);\n    }\n\n    public function testCanInsertWithEnums()\n    {\n        DB::table('enum_casts')->insert([\n            'string_status' => StringStatus::pending,\n            'integer_status' => IntegerStatus::pending,\n            'non_backed_status' => NonBackedStatus::pending,\n        ]);\n\n        $record = DB::table('enum_casts')->where('string_status', StringStatus::pending)->first();\n\n        $this->assertNotNull($record);\n        $this->assertSame('pending', $record->string_status);\n        $this->assertEquals(1, $record->integer_status);\n        $this->assertSame('pending', $record->non_backed_status);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/BatchableTransactionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse Symfony\\Component\\Process\\Exception\\ProcessSignaledException;\nuse Throwable;\n\nuse function Orchestra\\Testbench\\remote;\n\n#[RequiresPhpExtension('pcntl')]\n#[WithMigration('laravel', 'queue')]\n#[WithConfig('queue.default', 'database')]\nclass BatchableTransactionTest extends DatabaseTestCase\n{\n    use DatabaseMigrations;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        if ($this->usesSqliteInMemoryDatabaseConnection()) {\n            $this->markTestSkipped('Test does not support using :memory: database connection');\n        }\n    }\n\n    public function testItCanHandleTimeoutJob()\n    {\n        Bus::batch([new Fixtures\\TimeOutJobWithTransaction()])\n            ->allowFailures()\n            ->dispatch();\n\n        $this->assertSame(1, DB::table('jobs')->count());\n        $this->assertSame(0, DB::table('failed_jobs')->count());\n        $this->assertSame(1, DB::table('job_batches')->count());\n\n        try {\n            remote('queue:work --stop-when-empty', [\n                'DB_CONNECTION' => config('database.default'),\n                'QUEUE_CONNECTION' => config('queue.default'),\n            ])->run();\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ProcessSignaledException::class, $e);\n            $this->assertSame('The process has been signaled with signal \"9\".', $e->getMessage());\n        }\n\n        $this->assertSame(0, DB::table('jobs')->count());\n        $this->assertSame(1, DB::table('failed_jobs')->count());\n\n        $this->assertDatabaseHas('job_batches', [\n            'total_jobs' => 1,\n            'pending_jobs' => 1,\n            'failed_jobs' => 1,\n            'failed_job_ids' => json_encode(DB::table('failed_jobs')->pluck('uuid')->all()),\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/Fixtures/TimeOutJobWithNestedTransactions.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue\\Fixtures;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\DB;\n\nclass TimeOutJobWithNestedTransactions implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable, Batchable;\n\n    public int $tries = 1;\n    public int $timeout = 2;\n\n    public function handle(): void\n    {\n        DB::transaction(function () {\n            DB::transaction(fn () => sleep(20));\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/Fixtures/TimeOutJobWithTransaction.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue\\Fixtures;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\DB;\n\nclass TimeOutJobWithTransaction implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable, Batchable;\n\n    public int $tries = 1;\n    public int $timeout = 2;\n\n    public function handle(): void\n    {\n        DB::transaction(fn () => sleep(20));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/Fixtures/TimeOutNonBatchableJobWithNestedTransactions.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue\\Fixtures;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\DB;\n\nclass TimeOutNonBatchableJobWithNestedTransactions implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable;\n\n    public int $tries = 1;\n    public int $timeout = 2;\n\n    public function handle(): void\n    {\n        DB::transaction(function () {\n            DB::transaction(fn () => sleep(20));\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/Fixtures/TimeOutNonBatchableJobWithTransaction.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue\\Fixtures;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\DB;\n\nclass TimeOutNonBatchableJobWithTransaction implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable;\n\n    public int $tries = 1;\n    public int $timeout = 2;\n\n    public function handle(): void\n    {\n        DB::transaction(fn () => sleep(20));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Queue/QueueTransactionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Queue;\n\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse Symfony\\Component\\Process\\Exception\\ProcessSignaledException;\nuse Throwable;\n\nuse function Orchestra\\Testbench\\remote;\n\n#[RequiresPhpExtension('pcntl')]\n#[WithMigration('laravel', 'queue')]\n#[WithConfig('queue.default', 'database')]\nclass QueueTransactionTest extends DatabaseTestCase\n{\n    use DatabaseMigrations;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        if ($this->usesSqliteInMemoryDatabaseConnection()) {\n            $this->markTestSkipped('Test does not support using :memory: database connection');\n        }\n    }\n\n    #[DataProvider('timeoutJobs')]\n    public function testItCanHandleTimeoutJob($job)\n    {\n        dispatch($job);\n\n        $this->assertSame(1, DB::table('jobs')->count());\n        $this->assertSame(0, DB::table('failed_jobs')->count());\n\n        try {\n            remote('queue:work --stop-when-empty', [\n                'DB_CONNECTION' => config('database.default'),\n                'QUEUE_CONNECTION' => config('queue.default'),\n            ])->run();\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ProcessSignaledException::class, $e);\n            $this->assertSame('The process has been signaled with signal \"9\".', $e->getMessage());\n        }\n\n        $this->assertSame(0, DB::table('jobs')->count());\n        $this->assertSame(1, DB::table('failed_jobs')->count());\n    }\n\n    public static function timeoutJobs(): array\n    {\n        return [\n            [new Fixtures\\TimeOutJobWithTransaction()],\n            [new Fixtures\\TimeOutJobWithNestedTransactions()],\n            [new Fixtures\\TimeOutNonBatchableJobWithTransaction()],\n            [new Fixtures\\TimeOutNonBatchableJobWithNestedTransactions()],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/RefreshCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RefreshCommandTest extends TestCase\n{\n    public function testRefreshWithoutRealpath()\n    {\n        $this->app->setBasePath(__DIR__);\n\n        $options = [\n            '--path' => 'stubs/',\n        ];\n\n        $this->migrateRefreshWith($options);\n    }\n\n    public function testRefreshWithRealpath()\n    {\n        $options = [\n            '--path' => realpath(__DIR__.'/stubs/'),\n            '--realpath' => true,\n        ];\n\n        $this->migrateRefreshWith($options);\n    }\n\n    private function migrateRefreshWith(array $options)\n    {\n        if ($this->app['config']->get('database.default') !== 'testing') {\n            $this->artisan('db:wipe', ['--drop-views' => true]);\n        }\n\n        $this->beforeApplicationDestroyed(function () use ($options) {\n            $this->artisan('migrate:rollback', $options);\n        });\n\n        $this->artisan('migrate:refresh', $options);\n        DB::table('members')->insert(['name' => 'foo', 'email' => 'foo@bar', 'password' => 'secret']);\n        $this->assertEquals(1, DB::table('members')->count());\n\n        $this->artisan('migrate:refresh', $options);\n        $this->assertEquals(0, DB::table('members')->count());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SchemaBuilderSchemaNameTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass SchemaBuilderSchemaNameTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        if ($this->usesSqliteInMemoryDatabaseConnection()) {\n            $this->markTestSkipped('Test cannot be run using :memory: database connection, SQLite test file is here: \\Illuminate\\Tests\\Integration\\Database\\Sqlite\\SchemaBuilderSchemaNameTest');\n        }\n    }\n\n    protected function defineDatabaseMigrations()\n    {\n        if (in_array($this->driver, ['mariadb', 'mysql'])) {\n            Schema::createDatabase('my_schema');\n        } elseif ($this->driver === 'sqlite') {\n            DB::connection('without-prefix')->statement(\"attach database ':memory:' as my_schema\");\n            DB::connection('with-prefix')->statement(\"attach database ':memory:' as my_schema\");\n        } elseif ($this->driver === 'pgsql') {\n            DB::statement('create schema if not exists my_schema');\n        } elseif ($this->driver === 'sqlsrv') {\n            DB::statement(\"if schema_id('my_schema') is null begin exec('create schema my_schema') end\");\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        if (in_array($this->driver, ['mariadb', 'mysql'])) {\n            Schema::dropDatabaseIfExists('my_schema');\n        } elseif ($this->driver === 'sqlite') {\n            DB::connection('without-prefix')->statement('detach database my_schema');\n            DB::connection('with-prefix')->statement('detach database my_schema');\n        } elseif ($this->driver === 'pgsql') {\n            DB::statement('drop schema if exists my_schema cascade');\n        } elseif ($this->driver === 'sqlsrv') {\n            // DB::statement(\"if schema_id('my_schema') is not null begin exec('drop schema my_schema') end\");\n        }\n    }\n\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $connection = $app['config']->get('database.default');\n\n        $app['config']->set(\"database.connections.$connection.prefix_indexes\", true);\n        $app['config']->set('database.connections.pgsql.search_path', 'public,my_schema');\n        $app['config']->set('database.connections.without-prefix', $app['config']->get('database.connections.'.$connection));\n        $app['config']->set('database.connections.with-prefix', $app['config']->get('database.connections.without-prefix'));\n        $app['config']->set('database.connections.with-prefix.prefix', 'example_');\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testSchemas($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schemas = $schema->getSchemas();\n\n        $this->assertSame($schema->getCurrentSchemaName(), collect($schemas)->firstWhere('default')['name']);\n        $this->assertEqualsCanonicalizing(\n            match ($this->driver) {\n                'mysql', 'mariadb' => ['laravel', 'my_schema'],\n                'pgsql' => ['public', 'my_schema'],\n                'sqlite' => ['main', 'my_schema'],\n                'sqlsrv' => ['dbo', 'guest', 'my_schema'],\n            },\n            array_column($schemas, 'name'),\n        );\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testCreate($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $this->assertTrue($schema->hasTable('my_schema.table'));\n        $this->assertFalse($schema->hasTable('table'));\n\n        $currentSchema = $schema->getCurrentSchemaName();\n        $tableName = $connection === 'with-prefix' ? 'example_table' : 'table';\n\n        $this->assertEqualsCanonicalizing(\n            [$currentSchema.'.migrations', 'my_schema.'.$tableName],\n            $schema->getTableListing([$currentSchema, 'my_schema'])\n        );\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testRename($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $this->assertTrue($schema->hasTable('my_schema.table'));\n        $this->assertFalse($schema->hasTable('my_schema.new_table'));\n        $this->assertTrue($schema->hasTable('table'));\n        $this->assertFalse($schema->hasTable('my_table'));\n\n        if (in_array($this->driver, ['mariadb', 'mysql'])) {\n            $schema->rename('my_schema.table', 'my_schema.new_table');\n        } else {\n            $schema->rename('my_schema.table', 'new_table');\n        }\n        $schema->rename('table', 'my_table');\n\n        $this->assertTrue($schema->hasTable('my_schema.new_table'));\n        $this->assertFalse($schema->hasTable('my_schema.table'));\n        $this->assertTrue($schema->hasTable('my_table'));\n        $this->assertFalse($schema->hasTable('table'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testDrop($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $this->assertTrue($schema->hasTable('my_schema.table'));\n        $this->assertTrue($schema->hasTable('table'));\n\n        $currentSchema = $schema->getCurrentSchemaName();\n        $tableName = $connection === 'with-prefix' ? 'example_table' : 'table';\n\n        $this->assertEqualsCanonicalizing(\n            [$currentSchema.'.migrations', $currentSchema.'.'.$tableName, 'my_schema.'.$tableName],\n            $schema->getTableListing([$currentSchema, 'my_schema'])\n        );\n\n        $schema->drop('my_schema.table');\n\n        $this->assertFalse($schema->hasTable('my_schema.table'));\n        $this->assertTrue($schema->hasTable('table'));\n\n        $this->assertEqualsCanonicalizing(\n            [$currentSchema.'.migrations', $currentSchema.'.'.$tableName],\n            $schema->getTableListing([$currentSchema, 'my_schema'])\n        );\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testDropIfExists($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $this->assertTrue($schema->hasTable('my_schema.table'));\n        $this->assertTrue($schema->hasTable('table'));\n\n        $schema->dropIfExists('my_schema.table');\n        $schema->dropIfExists('my_schema.fake_table');\n        $schema->dropIfExists('fake_schema.table');\n\n        $this->assertFalse($schema->hasTable('my_schema.table'));\n        $this->assertTrue($schema->hasTable('table'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testAddColumns($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->string('title')->default('default schema title');\n        });\n        $schema->create('my_table', function (Blueprint $table) {\n            $table->id();\n            $table->string('name')->default('default name');\n        });\n\n        $this->assertEquals(['id', 'title'], $schema->getColumnListing('my_schema.table'));\n        $this->assertEquals(['id', 'name'], $schema->getColumnListing('my_table'));\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->string('name')->default('default schema name');\n            $table->integer('count');\n        });\n        $schema->table('my_table', function (Blueprint $table) {\n            $table->integer('count');\n            $table->string('title')->default('default title');\n        });\n\n        $this->assertEquals(['id', 'title', 'name', 'count'], $schema->getColumnListing('my_schema.table'));\n        $this->assertEquals(['id', 'name', 'count', 'title'], $schema->getColumnListing('my_table'));\n        $this->assertStringContainsString('default schema name', collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'name')['default']);\n        $this->assertStringContainsString('default schema title', collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'title')['default']);\n        $this->assertStringContainsString('default name', collect($schema->getColumns('my_table'))->firstWhere('name', 'name')['default']);\n        $this->assertStringContainsString('default title', collect($schema->getColumns('my_table'))->firstWhere('name', 'title')['default']);\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testRenameColumns($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->string('title')->default('default schema title');\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n            $table->string('name')->default('default name');\n        });\n\n        $this->assertTrue($schema->hasColumn('my_schema.table', 'title'));\n        $this->assertTrue($schema->hasColumn('table', 'name'));\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->renameColumn('title', 'new_title');\n        });\n        $schema->table('table', function (Blueprint $table) {\n            $table->renameColumn('name', 'new_name');\n        });\n\n        $this->assertFalse($schema->hasColumn('my_schema.table', 'title'));\n        $this->assertTrue($schema->hasColumn('my_schema.table', 'new_title'));\n        $this->assertFalse($schema->hasColumn('table', 'name'));\n        $this->assertTrue($schema->hasColumn('table', 'new_name'));\n        $this->assertStringContainsString('default schema title', collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'new_title')['default']);\n        $this->assertStringContainsString('default name', collect($schema->getColumns('table'))->firstWhere('name', 'new_name')['default']);\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testModifyColumns($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n            $table->integer('count');\n        });\n        $schema->create('my_table', function (Blueprint $table) {\n            $table->id();\n            $table->string('title');\n            $table->integer('count');\n        });\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->string('name')->default('default schema name')->change();\n            $table->bigInteger('count')->change();\n        });\n        $schema->table('my_table', function (Blueprint $table) {\n            $table->string('title')->default('default title')->change();\n            $table->bigInteger('count')->change();\n        });\n\n        $this->assertStringContainsString('default schema name', collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'name')['default']);\n        $this->assertStringContainsString('default title', collect($schema->getColumns('my_table'))->firstWhere('name', 'title')['default']);\n        $this->assertEquals($this->driver === 'sqlsrv' ? 'nvarchar' : 'varchar', $schema->getColumnType('my_schema.table', 'name'));\n        $this->assertEquals($this->driver === 'sqlsrv' ? 'nvarchar' : 'varchar', $schema->getColumnType('my_table', 'title'));\n        $this->assertEquals(match ($this->driver) {\n            'pgsql' => 'int8',\n            'sqlite' => 'integer',\n            default => 'bigint',\n        }, $schema->getColumnType('my_schema.table', 'count'));\n        $this->assertEquals(match ($this->driver) {\n            'pgsql' => 'int8',\n            'sqlite' => 'integer',\n            default => 'bigint',\n        }, $schema->getColumnType('my_table', 'count'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testDropColumns($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->string('name')->default('default schema name');\n            $table->integer('count')->default(20);\n            $table->string('title')->default('default schema title');\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n            $table->string('name')->default('default name');\n            $table->integer('count')->default(10);\n            $table->string('title')->default('default title');\n        });\n\n        $this->assertTrue($schema->hasColumns('my_schema.table', ['id', 'name', 'count', 'title']));\n        $this->assertTrue($schema->hasColumns('table', ['id', 'name', 'count', 'title']));\n\n        $schema->dropColumns('my_schema.table', ['name', 'count']);\n        $schema->dropColumns('table', ['name', 'title']);\n\n        $this->assertTrue($schema->hasColumns('my_schema.table', ['id', 'title']));\n        $this->assertFalse($schema->hasColumn('my_schema.table', 'name'));\n        $this->assertFalse($schema->hasColumn('my_schema.table', 'count'));\n        $this->assertTrue($schema->hasColumns('table', ['id', 'count']));\n        $this->assertFalse($schema->hasColumn('table', 'name'));\n        $this->assertFalse($schema->hasColumn('table', 'title'));\n        $this->assertStringContainsString('default schema title', collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'title')['default']);\n        $this->assertStringContainsString('10', collect($schema->getColumns('table'))->firstWhere('name', 'count')['default']);\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testIndexes($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->string('code')->primary();\n            $table->string('email')->unique();\n            $table->integer('name')->index();\n            $table->integer('title')->index();\n        });\n        $schema->create('my_table', function (Blueprint $table) {\n            $table->string('code')->primary();\n            $table->string('email')->unique();\n            $table->integer('name')->index();\n            $table->integer('title')->index();\n        });\n\n        $this->assertTrue($schema->hasIndex('my_schema.table', ['code'], 'primary'));\n        $this->assertTrue($schema->hasIndex('my_schema.table', ['email'], 'unique'));\n        $this->assertTrue($schema->hasIndex('my_schema.table', ['name']));\n        $this->assertTrue($schema->hasIndex('my_table', ['code'], 'primary'));\n        $this->assertTrue($schema->hasIndex('my_table', ['email'], 'unique'));\n        $this->assertTrue($schema->hasIndex('my_table', ['name']));\n\n        $schemaIndexName = $connection === 'with-prefix' ? 'my_schema_example_table_title_index' : 'my_schema_table_title_index';\n        $indexName = $connection === 'with-prefix' ? 'example_my_table_title_index' : 'my_table_title_index';\n\n        $schema->table('my_schema.table', function (Blueprint $table) use ($schemaIndexName) {\n            $table->renameIndex($schemaIndexName, 'schema_new_index_name');\n        });\n        $schema->table('my_table', function (Blueprint $table) use ($indexName) {\n            $table->renameIndex($indexName, 'new_index_name');\n        });\n\n        $this->assertTrue($schema->hasIndex('my_schema.table', 'schema_new_index_name'));\n        $this->assertFalse($schema->hasIndex('my_schema.table', $schemaIndexName));\n        $this->assertTrue($schema->hasIndex('my_table', 'new_index_name'));\n        $this->assertFalse($schema->hasIndex('my_table', $indexName));\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->dropPrimary(['code']);\n            $table->dropUnique(['email']);\n            $table->dropIndex(['name']);\n            $table->dropIndex('schema_new_index_name');\n        });\n        $schema->table('my_table', function (Blueprint $table) {\n            $table->dropPrimary(['code']);\n            $table->dropUnique(['email']);\n            $table->dropIndex(['name']);\n            $table->dropIndex('new_index_name');\n        });\n\n        $this->assertEmpty($schema->getIndexListing('my_schema.table'));\n        $this->assertEmpty($schema->getIndexListing('my_table'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    #[RequiresDatabase(['mariadb', 'mysql', 'pgsql', 'sqlsrv'])]\n    public function testForeignKeys($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_tables', function (Blueprint $table) {\n            $table->id();\n        });\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->foreignId('my_table_id')\n                ->constrained(table: in_array($this->driver, ['mariadb', 'mysql']) ? 'laravel.my_tables' : null);\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->unsignedBigInteger('table_id');\n            $table->foreign('table_id')->references('id')->on('my_schema.table');\n        });\n\n        $schemaTableName = $connection === 'with-prefix' ? 'example_table' : 'table';\n        $tableName = $connection === 'with-prefix' ? 'example_my_tables' : 'my_tables';\n        $defaultSchemaName = match ($this->driver) {\n            'pgsql' => 'public',\n            'sqlsrv' => 'dbo',\n            default => 'laravel',\n        };\n\n        $this->assertTrue(collect($schema->getForeignKeys('my_schema.table'))->contains(\n            fn ($foreign) => $foreign['columns'] === ['my_table_id']\n                && $foreign['foreign_table'] === $tableName && $foreign['foreign_schema'] === $defaultSchemaName\n                && $foreign['foreign_columns'] === ['id']\n        ));\n\n        $this->assertTrue(collect($schema->getForeignKeys('table'))->contains(\n            fn ($foreign) => $foreign['columns'] === ['table_id']\n                && $foreign['foreign_table'] === $schemaTableName && $foreign['foreign_schema'] === 'my_schema'\n                && $foreign['foreign_columns'] === ['id']\n        ));\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->dropForeign(['my_table_id']);\n        });\n        $schema->table('table', function (Blueprint $table) {\n            $table->dropForeign(['table_id']);\n        });\n\n        $this->assertEmpty($schema->getForeignKeys('my_schema.table'));\n        $this->assertEmpty($schema->getForeignKeys('table'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    #[RequiresDatabase('sqlite')]\n    public function testForeignKeysOnSameSchema($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.my_tables', function (Blueprint $table) {\n            $table->id();\n        });\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->id();\n            $table->foreignId('my_table_id')->constrained();\n        });\n        $schema->create('my_schema.second_table', function (Blueprint $table) {\n            $table->unsignedBigInteger('table_id');\n            $table->foreign('table_id')->references('id')->on('table');\n        });\n\n        $myTableName = $connection === 'with-prefix' ? 'example_my_tables' : 'my_tables';\n        $tableName = $connection === 'with-prefix' ? 'example_table' : 'table';\n\n        $this->assertTrue(collect($schema->getForeignKeys('my_schema.table'))->contains(\n            fn ($foreign) => $foreign['columns'] === ['my_table_id']\n                && $foreign['foreign_table'] === $myTableName && $foreign['foreign_schema'] === 'my_schema'\n                && $foreign['foreign_columns'] === ['id']\n        ));\n\n        $this->assertTrue(collect($schema->getForeignKeys('my_schema.second_table'))->contains(\n            fn ($foreign) => $foreign['columns'] === ['table_id']\n                && $foreign['foreign_table'] === $tableName && $foreign['foreign_schema'] === 'my_schema'\n                && $foreign['foreign_columns'] === ['id']\n        ));\n\n        $schema->table('my_schema.table', function (Blueprint $table) {\n            $table->dropForeign(['my_table_id']);\n        });\n\n        $this->assertEmpty($schema->getForeignKeys('my_schema.table'));\n    }\n\n    #[DataProvider('connectionProvider')]\n    public function testHasView($connection)\n    {\n        $db = DB::connection($connection);\n        $schema = $db->getSchemaBuilder();\n\n        $db->statement('create view '.$db->getSchemaGrammar()->wrapTable('my_schema.view').' (name) as select 1');\n        $db->statement('create view '.$db->getSchemaGrammar()->wrapTable('my_view').' (name) as select 1');\n\n        $this->assertTrue($schema->hasView('my_schema.view'));\n        $this->assertTrue($schema->hasView('my_view'));\n        $this->assertTrue($schema->hasColumn('my_schema.view', 'name'));\n        $this->assertTrue($schema->hasColumn('my_view', 'name'));\n\n        $currentSchema = $schema->getCurrentSchemaName();\n        $viewName = $connection === 'with-prefix' ? 'example_view' : 'view';\n        $myViewName = $connection === 'with-prefix' ? 'example_my_view' : 'my_view';\n\n        $this->assertEqualsCanonicalizing(\n            [$currentSchema.'.'.$myViewName, 'my_schema.'.$viewName],\n            array_column($schema->getViews([$currentSchema, 'my_schema']), 'schema_qualified_name')\n        );\n\n        $db->statement('drop view '.$db->getSchemaGrammar()->wrapTable('my_schema.view'));\n        $db->statement('drop view '.$db->getSchemaGrammar()->wrapTable('my_view'));\n\n        $this->assertFalse($schema->hasView('my_schema.view'));\n        $this->assertFalse($schema->hasView('my_view'));\n\n        $this->assertEmpty($schema->getViews([$currentSchema, 'my_schema']));\n    }\n\n    #[DataProvider('connectionProvider')]\n    #[RequiresDatabase(['mariadb', 'mysql', 'pgsql'])]\n    public function testComment($connection)\n    {\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->comment('comment on schema table');\n            $table->string('name')->comment('comment on schema column');\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->comment('comment on table');\n            $table->string('name')->comment('comment on column');\n        });\n\n        $tables = collect($schema->getTables());\n        $tableName = $connection === 'with-prefix' ? 'example_table' : 'table';\n        $defaultSchema = $this->driver === 'pgsql' ? 'public' : 'laravel';\n\n        $this->assertEquals('comment on schema table',\n            $tables->first(fn ($table) => $table['name'] === $tableName && $table['schema'] === 'my_schema')['comment']\n        );\n        $this->assertEquals('comment on table',\n            $tables->first(fn ($table) => $table['name'] === $tableName && $table['schema'] === $defaultSchema)['comment']\n        );\n        $this->assertEquals('comment on schema column',\n            collect($schema->getColumns('my_schema.table'))->firstWhere('name', 'name')['comment']\n        );\n        $this->assertEquals('comment on column',\n            collect($schema->getColumns('table'))->firstWhere('name', 'name')['comment']\n        );\n    }\n\n    #[DataProvider('connectionProvider')]\n    #[RequiresDatabase(['mariadb', 'mysql', 'pgsql'])]\n    public function testAutoIncrementStartingValue($connection)\n    {\n        $this->expectNotToPerformAssertions();\n\n        $schema = Schema::connection($connection);\n\n        $schema->create('my_schema.table', function (Blueprint $table) {\n            $table->increments('code')->from(25);\n        });\n        $schema->create('table', function (Blueprint $table) {\n            $table->increments('code')->from(15);\n        });\n    }\n\n    #[DataProvider('connectionProvider')]\n    #[RequiresDatabase('sqlsrv')]\n    public function testHasTable($connection)\n    {\n        $db = DB::connection($connection);\n        $schema = $db->getSchemaBuilder();\n\n        try {\n            $db->statement(\"create login my_user with password = 'Passw0rd'\");\n            $db->statement('create user my_user for login my_user');\n        } catch(\\Illuminate\\Database\\QueryException) {\n            //\n        }\n\n        $db->statement('grant create table to my_user');\n        $db->statement('grant alter on SCHEMA::my_schema to my_user');\n        $db->statement(\"alter user my_user with default_schema = my_schema execute as user='my_user'\");\n\n        config([\n            'database.connections.'.$connection.'.username' => 'my_user',\n            'database.connections.'.$connection.'.password' => 'Passw0rd',\n        ]);\n\n        $this->assertEquals('my_schema', $schema->getCurrentSchemaName());\n\n        $schema->create('table', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $this->assertTrue($schema->hasTable('table'));\n        $this->assertTrue($schema->hasTable('my_schema.table'));\n        $this->assertFalse($schema->hasTable('dbo.table'));\n    }\n\n    public static function connectionProvider(): array\n    {\n        return [\n            'without prefix' => ['without-prefix'],\n            'with prefix' => ['with-prefix'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\nclass SchemaBuilderTest extends DatabaseTestCase\n{\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::dropAllViews();\n    }\n\n    public function testDropAllTables()\n    {\n        $this->expectNotToPerformAssertions();\n\n        Schema::create('table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        Schema::create('table', function (Blueprint $table) {\n            $table->increments('id');\n        });\n    }\n\n    public function testDropAllViews()\n    {\n        $this->expectNotToPerformAssertions();\n\n        DB::statement('create view foo (id) as select 1');\n\n        Schema::dropAllViews();\n\n        DB::statement('create view foo (id) as select 1');\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testChangeToTinyInteger()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->string('test_column');\n        });\n\n        $blueprint = new Blueprint($this->getConnection(), 'test', function (Blueprint $table) {\n            $table->tinyInteger('test_column')->change();\n        });\n\n        $blueprint->build();\n\n        $this->assertSame('integer', Schema::getColumnType('test', 'test_column'));\n    }\n\n    #[RequiresDatabase(['mysql', 'mariadb'])]\n    public function testChangeToTextColumn()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->integer('test_column');\n        });\n\n        foreach (['tinyText', 'text', 'mediumText', 'longText'] as $type) {\n            $blueprint = new Blueprint($this->getConnection(), 'test', function ($table) use ($type) {\n                $table->$type('test_column')->change();\n            });\n\n            $uppercase = strtolower($type);\n\n            $expected = [\"alter table `test` modify `test_column` $uppercase not null\"];\n\n            $this->assertEquals($expected, $blueprint->toSql());\n        }\n    }\n\n    #[RequiresDatabase(['mysql', 'mariadb'])]\n    public function testChangeTextColumnToTextColumn()\n    {\n        Schema::create('test', static function (Blueprint $table) {\n            $table->text('test_column');\n        });\n\n        foreach (['tinyText', 'mediumText', 'longText'] as $type) {\n            $blueprint = new Blueprint($this->getConnection(), 'test', function ($table) use ($type) {\n                $table->$type('test_column')->change();\n            });\n\n            $lowercase = strtolower($type);\n\n            $expected = [\"alter table `test` modify `test_column` $lowercase not null\"];\n\n            $this->assertEquals($expected, $blueprint->toSql());\n        }\n    }\n\n    #[RequiresDatabase(['mysql', 'mariadb'])]\n    public function testModifyNullableColumn()\n    {\n        Schema::create('test', static function (Blueprint $table) {\n            $table->string('not_null_column_to_not_null');\n            $table->string('not_null_column_to_nullable');\n            $table->string('nullable_column_to_nullable')->nullable();\n            $table->string('nullable_column_to_not_null')->nullable();\n        });\n\n        $blueprint = new Blueprint($this->getConnection(), 'test', function ($table) {\n            $table->text('not_null_column_to_not_null')->change();\n            $table->text('not_null_column_to_nullable')->nullable()->change();\n            $table->text('nullable_column_to_nullable')->nullable()->change();\n            $table->text('nullable_column_to_not_null')->change();\n        });\n\n        $expected = [\n            'alter table `test` modify `not_null_column_to_not_null` text not null',\n            'alter table `test` modify `not_null_column_to_nullable` text null',\n            'alter table `test` modify `nullable_column_to_nullable` text null',\n            'alter table `test` modify `nullable_column_to_not_null` text not null',\n        ];\n\n        $this->assertEquals($expected, $blueprint->toSql());\n    }\n\n    public function testChangeNullableColumn()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->string('not_null_column_to_not_null');\n            $table->string('not_null_column_to_nullable');\n            $table->string('nullable_column_to_nullable')->nullable();\n            $table->string('nullable_column_to_not_null')->nullable();\n        });\n\n        $columns = collect(Schema::getColumns('test'));\n\n        $this->assertFalse($columns->firstWhere('name', 'not_null_column_to_not_null')['nullable']);\n        $this->assertFalse($columns->firstWhere('name', 'not_null_column_to_nullable')['nullable']);\n        $this->assertTrue($columns->firstWhere('name', 'nullable_column_to_nullable')['nullable']);\n        $this->assertTrue($columns->firstWhere('name', 'nullable_column_to_not_null')['nullable']);\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->text('not_null_column_to_not_null')->change();\n            $table->text('not_null_column_to_nullable')->nullable()->change();\n            $table->text('nullable_column_to_nullable')->nullable()->change();\n            $table->text('nullable_column_to_not_null')->change();\n        });\n\n        $columns = collect(Schema::getColumns('test'));\n\n        $this->assertFalse($columns->firstWhere('name', 'not_null_column_to_not_null')['nullable']);\n        $this->assertTrue($columns->firstWhere('name', 'not_null_column_to_nullable')['nullable']);\n        $this->assertTrue($columns->firstWhere('name', 'nullable_column_to_nullable')['nullable']);\n        $this->assertFalse($columns->firstWhere('name', 'nullable_column_to_not_null')['nullable']);\n    }\n\n    public function testRenameColumnWithDefault()\n    {\n        Schema::create('test', static function (Blueprint $table) {\n            $table->timestamp('foo')->useCurrent();\n            $table->string('bar')->default('value');\n        });\n\n        $columns = Schema::getColumns('test');\n        $defaultFoo = collect($columns)->firstWhere('name', 'foo')['default'];\n        $defaultBar = collect($columns)->firstWhere('name', 'bar')['default'];\n\n        Schema::table('test', static function (Blueprint $table) {\n            $table->renameColumn('foo', 'new_foo');\n            $table->renameColumn('bar', 'new_bar');\n        });\n\n        $this->assertEquals(collect(Schema::getColumns('test'))->firstWhere('name', 'new_foo')['default'], $defaultFoo);\n        $this->assertEquals(collect(Schema::getColumns('test'))->firstWhere('name', 'new_bar')['default'], $defaultBar);\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testModifyColumnWithZeroDefaultOnSqlite()\n    {\n        Schema::create('test', static function (Blueprint $table) {\n            $table->integer('column_default_zero')->default(new Expression('0'));\n            $table->integer('column_to_change');\n        });\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->smallInteger('column_to_change')->default(new Expression('0'))->change();\n        });\n\n        $columns = collect(Schema::getColumns('test'));\n\n        $this->assertSame('0', $columns->firstWhere('name', 'column_default_zero')['default']);\n        $this->assertSame('0', $columns->firstWhere('name', 'column_to_change')['default']);\n    }\n\n    public function testCompoundPrimaryWithAutoIncrement()\n    {\n        if ($this->driver === 'sqlite') {\n            $this->markTestSkipped('Compound primary key with an auto increment column is not supported on SQLite.');\n        }\n\n        Schema::create('test', function (Blueprint $table) {\n            $table->id();\n            $table->uuid();\n\n            $table->primary(['id', 'uuid']);\n        });\n\n        $this->assertTrue(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertTrue(Schema::hasIndex('test', ['id', 'uuid'], 'primary'));\n    }\n\n    public function testModifyingAutoIncrementColumn()\n    {\n        if ($this->driver === 'sqlsrv') {\n            $this->markTestSkipped('Changing a primary column is not supported on SQL Server.');\n        }\n\n        Schema::create('test', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        $this->assertTrue(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertTrue(Schema::hasIndex('test', ['id'], 'primary'));\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->bigIncrements('id')->change();\n        });\n\n        $this->assertTrue(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertTrue(Schema::hasIndex('test', ['id'], 'primary'));\n    }\n\n    public function testModifyingColumnToAutoIncrementColumn()\n    {\n        if (in_array($this->driver, ['pgsql', 'sqlsrv'])) {\n            $this->markTestSkipped('Changing a column to auto increment is not supported on PostgreSQL and SQL Server.');\n        }\n\n        Schema::create('test', function (Blueprint $table) {\n            $table->unsignedBigInteger('id');\n        });\n\n        $this->assertFalse(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertFalse(Schema::hasIndex('test', ['id'], 'primary'));\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->bigIncrements('id')->primary()->change();\n        });\n\n        $this->assertTrue(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertTrue(Schema::hasIndex('test', ['id'], 'primary'));\n    }\n\n    public function testAddingAutoIncrementColumn()\n    {\n        if ($this->driver === 'sqlite') {\n            $this->markTestSkipped('Adding a primary column is not supported on SQLite.');\n        }\n\n        Schema::create('test', function (Blueprint $table) {\n            $table->string('name');\n        });\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->bigIncrements('id');\n        });\n\n        $this->assertTrue(collect(Schema::getColumns('test'))->firstWhere('name', 'id')['auto_increment']);\n        $this->assertTrue(Schema::hasIndex('test', ['id'], 'primary'));\n    }\n\n    public function testGetTables()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->comment('This is a comment');\n            $table->increments('id');\n        });\n\n        Schema::create('bar', function (Blueprint $table) {\n            $table->string('name');\n        });\n\n        Schema::create('baz', function (Blueprint $table) {\n            $table->integer('votes');\n        });\n\n        $tables = Schema::getTables();\n\n        $this->assertEmpty(array_diff(['foo', 'bar', 'baz'], array_column($tables, 'name')));\n\n        if (in_array($this->driver, ['mysql', 'mariadb', 'pgsql'])) {\n            $this->assertNotEmpty(array_filter($tables, function ($table) {\n                return $table['name'] === 'foo' && $table['comment'] === 'This is a comment';\n            }));\n        }\n    }\n\n    public function testHasView()\n    {\n        DB::statement('create view foo (id) as select 1');\n\n        $this->assertTrue(Schema::hasView('foo'));\n    }\n\n    public function testGetViews()\n    {\n        DB::statement('create view foo (id) as select 1');\n        DB::statement('create view bar (name) as select 1');\n        DB::statement('create view baz (votes) as select 1');\n\n        $views = Schema::getViews();\n\n        $this->assertEmpty(array_diff(['foo', 'bar', 'baz'], array_column($views, 'name')));\n    }\n\n    #[RequiresDatabase('pgsql')]\n    public function testGetAndDropTypes()\n    {\n        DB::statement('create type pseudo_foo');\n        DB::statement('create type comp_foo as (f1 int, f2 text)');\n        DB::statement(\"create type enum_foo as enum ('new', 'open', 'closed')\");\n        DB::statement('create type range_foo as range (subtype = float8)');\n        DB::statement('create domain domain_foo as text');\n        DB::statement('create type base_foo');\n        DB::statement(\"create function foo_in(cstring) returns base_foo language internal immutable strict parallel safe as 'int2in'\");\n        DB::statement(\"create function foo_out(base_foo) returns cstring language internal immutable strict parallel safe as 'int2out'\");\n        DB::statement('create type base_foo (input = foo_in, output = foo_out)');\n\n        $types = Schema::getTypes();\n\n        if (version_compare($this->getConnection()->getServerVersion(), '14.0', '<')) {\n            $this->assertCount(10, $types);\n        } else {\n            $this->assertCount(13, $types);\n        }\n\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'pseudo_foo' && $type['type'] === 'pseudo' && ! $type['implicit']));\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'comp_foo' && $type['type'] === 'composite' && ! $type['implicit']));\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'enum_foo' && $type['type'] === 'enum' && ! $type['implicit']));\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'range_foo' && $type['type'] === 'range' && ! $type['implicit']));\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'domain_foo' && $type['type'] === 'domain' && ! $type['implicit']));\n        $this->assertTrue(collect($types)->contains(fn ($type) => $type['name'] === 'base_foo' && $type['type'] === 'base' && ! $type['implicit']));\n\n        Schema::dropAllTypes();\n        $types = Schema::getTypes();\n\n        $this->assertEmpty($types);\n    }\n\n    public function testGetColumns()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->id();\n            $table->string('bar')->nullable();\n            $table->string('baz')->default('test');\n        });\n\n        $columns = Schema::getColumns('foo');\n\n        $this->assertCount(3, $columns);\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'id' && $column['auto_increment'] && ! $column['nullable']\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'bar' && $column['nullable']\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'baz' && ! $column['nullable'] && str_contains($column['default'], 'test')\n        ));\n    }\n\n    public function testGetColumnsOnView()\n    {\n        DB::statement('create view foo (bar) as select 1');\n\n        $columns = Schema::getColumns('foo');\n\n        $this->assertCount(1, $columns);\n        $this->assertTrue($columns[0]['name'] === 'bar');\n    }\n\n    public function testGetIndexes()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->string('bar')->index('my_index');\n        });\n\n        $indexes = Schema::getIndexes('foo');\n\n        $this->assertCount(1, $indexes);\n        $this->assertTrue(\n            $indexes[0]['name'] === 'my_index'\n            && $indexes[0]['columns'] === ['bar']\n            && ! $indexes[0]['unique']\n            && ! $indexes[0]['primary']\n        );\n        $this->assertTrue(Schema::hasIndex('foo', 'my_index'));\n        $this->assertTrue(Schema::hasIndex('foo', ['bar']));\n        $this->assertFalse(Schema::hasIndex('foo', 'my_index', 'primary'));\n        $this->assertFalse(Schema::hasIndex('foo', ['bar'], 'unique'));\n    }\n\n    public function testGetUniqueIndexes()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->id();\n            $table->string('bar');\n            $table->integer('baz');\n\n            $table->unique(['baz', 'bar']);\n        });\n\n        $indexes = Schema::getIndexes('foo');\n\n        $this->assertCount(2, $indexes);\n        $this->assertTrue(collect($indexes)->contains(\n            fn ($index) => $index['columns'] === ['id'] && $index['primary']\n        ));\n        $this->assertTrue(collect($indexes)->contains(\n            fn ($index) => $index['name'] === 'foo_baz_bar_unique' && $index['columns'] === ['baz', 'bar'] && $index['unique']\n        ));\n        $this->assertTrue(Schema::hasIndex('foo', 'foo_baz_bar_unique'));\n        $this->assertTrue(Schema::hasIndex('foo', 'foo_baz_bar_unique', 'unique'));\n        $this->assertTrue(Schema::hasIndex('foo', ['baz', 'bar']));\n        $this->assertTrue(Schema::hasIndex('foo', ['baz', 'bar'], 'unique'));\n        $this->assertFalse(Schema::hasIndex('foo', ['baz', 'bar'], 'primary'));\n    }\n\n    public function testGetIndexesWithCompositeKeys()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->unsignedBigInteger('key');\n            $table->string('bar')->unique();\n            $table->integer('baz');\n\n            $table->primary(['baz', 'key']);\n        });\n\n        $indexes = Schema::getIndexes('foo');\n\n        $this->assertCount(2, $indexes);\n        $this->assertTrue(collect($indexes)->contains(\n            fn ($index) => $index['columns'] === ['baz', 'key'] && $index['primary']\n        ));\n        $this->assertTrue(collect($indexes)->contains(\n            fn ($index) => $index['name'] === 'foo_bar_unique' && $index['columns'] === ['bar'] && $index['unique']\n        ));\n    }\n\n    #[RequiresDatabase(['mysql', 'mariadb', 'pgsql'])]\n    public function testGetFullTextIndexes()\n    {\n        Schema::create('articles', function (Blueprint $table) {\n            $table->id();\n            $table->string('title', 200);\n            $table->text('body');\n\n            $table->fulltext(['body', 'title']);\n        });\n\n        $indexes = Schema::getIndexes('articles');\n\n        $this->assertCount(2, $indexes);\n        $this->assertTrue(collect($indexes)->contains(fn ($index) => $index['columns'] === ['id'] && $index['primary']));\n        $this->assertTrue(collect($indexes)->contains('name', 'articles_body_title_fulltext'));\n    }\n\n    public function testHasIndexOrder()\n    {\n        Schema::create('foo', function (Blueprint $table) {\n            $table->integer('bar');\n            $table->integer('baz');\n            $table->integer('qux');\n\n            $table->unique(['bar', 'baz']);\n            $table->index(['baz', 'bar']);\n            $table->index(['baz', 'qux']);\n        });\n\n        $this->assertTrue(Schema::hasIndex('foo', ['bar', 'baz']));\n        $this->assertTrue(Schema::hasIndex('foo', ['bar', 'baz'], 'unique'));\n        $this->assertTrue(Schema::hasIndex('foo', ['baz', 'bar']));\n        $this->assertFalse(Schema::hasIndex('foo', ['baz', 'bar'], 'unique'));\n        $this->assertTrue(Schema::hasIndex('foo', ['baz', 'qux']));\n        $this->assertFalse(Schema::hasIndex('foo', ['qux', 'baz']));\n    }\n\n    public function testGetForeignKeys()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->foreignId('user_id')->nullable()->constrained()->cascadeOnUpdate()->nullOnDelete();\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(\n            fn ($foreign) => $foreign['columns'] === ['user_id']\n                && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['id']\n                && $foreign['on_update'] === 'cascade' && $foreign['on_delete'] === 'set null'\n        ));\n    }\n\n    public function testGetCompoundForeignKeys()\n    {\n        Schema::create('parent', function (Blueprint $table) {\n            $table->id();\n            $table->integer('a');\n            $table->integer('b');\n\n            $table->unique(['b', 'a']);\n        });\n\n        Schema::create('child', function (Blueprint $table) {\n            $table->integer('c');\n            $table->integer('d');\n\n            $table->foreign(['d', 'c'], 'test_fk')->references(['b', 'a'])->on('parent');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('child');\n\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(\n            fn ($foreign) => $foreign['columns'] === ['d', 'c']\n                && $foreign['foreign_table'] === 'parent'\n                && $foreign['foreign_columns'] === ['b', 'a']\n        ));\n    }\n\n    public function testAlteringTableWithForeignKeyConstraintsEnabled()\n    {\n        Schema::enableForeignKeyConstraints();\n\n        Schema::create('parents', function (Blueprint $table) {\n            $table->id();\n            $table->text('name');\n        });\n\n        Schema::create('children', function (Blueprint $table) {\n            $table->foreignId('parent_id')->constrained();\n        });\n\n        $id = DB::table('parents')->insertGetId(['name' => 'foo']);\n        DB::table('children')->insert(['parent_id' => $id]);\n\n        Schema::table('parents', function (Blueprint $table) {\n            $table->string('name')->change();\n        });\n\n        $foreignKeys = Schema::getForeignKeys('children');\n\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(\n            fn ($foreign) => $foreign['columns'] === ['parent_id']\n                && $foreign['foreign_table'] === 'parents' && $foreign['foreign_columns'] === ['id']\n        ));\n    }\n\n    #[RequiresDatabase('mariadb')]\n    public function testSystemVersionedTables()\n    {\n        DB::statement('create table `test` (`foo` int) WITH system versioning;');\n\n        $this->assertTrue(Schema::hasTable('test'));\n\n        Schema::dropAllTables();\n\n        $this->artisan('migrate:install');\n\n        DB::statement('create table `test` (`foo` int) WITH system versioning;');\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testAddingStoredColumnOnSqlite()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->integer('price');\n        });\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->integer('virtual_column')->virtualAs('\"price\" - 5');\n            $table->integer('stored_column')->storedAs('\"price\" - 5');\n        });\n\n        $this->assertTrue(Schema::hasColumns('test', ['virtual_column', 'stored_column']));\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testModifyingStoredColumnOnSqlite()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->integer('price');\n            $table->integer('virtual_price')->virtualAs('price - 2');\n            $table->integer('stored_price')->storedAs('price - 4');\n            $table->integer('virtual_price_changed')->virtualAs('price - 6');\n            $table->integer('stored_price_changed')->storedAs('price - 8');\n        });\n\n        DB::table('test')->insert(['price' => 100]);\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->integer('virtual_price_changed')->virtualAs('price - 5')->change();\n            $table->integer('stored_price_changed')->storedAs('price - 7')->change();\n        });\n\n        $this->assertEquals(\n            ['price' => 100, 'virtual_price' => 98, 'stored_price' => 96, 'virtual_price_changed' => 95, 'stored_price_changed' => 93],\n            (array) DB::table('test')->first()\n        );\n\n        $columns = Schema::getColumns('test');\n\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'virtual_price' && $column['generation']['type'] === 'virtual'\n                && $column['generation']['expression'] === 'price - 2'\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'stored_price' && $column['generation']['type'] === 'stored'\n                && $column['generation']['expression'] === 'price - 4'\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'virtual_price_changed' && $column['generation']['type'] === 'virtual'\n                && $column['generation']['expression'] === 'price - 5'\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'stored_price_changed' && $column['generation']['type'] === 'stored'\n                && $column['generation']['expression'] === 'price - 7'\n        ));\n    }\n\n    #[RequiresDatabase('pgsql', '>=18')]\n    public function testGettingGeneratedColumns()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->integer('price');\n\n            if ($this->driver === 'sqlsrv') {\n                $table->computed('virtual_price', 'price - 5');\n                $table->computed('stored_price', 'price - 10')->persisted();\n            } else {\n                $table->integer('virtual_price')->virtualAs('price - 5');\n                $table->integer('stored_price')->storedAs('price - 10');\n            }\n        });\n\n        $columns = Schema::getColumns('test');\n\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'price' && is_null($column['generation'])\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'virtual_price'\n                && $column['generation']['type'] === 'virtual'\n                && match ($this->driver) {\n                    'mysql' => $column['generation']['expression'] === '(`price` - 5)',\n                    'mariadb' => $column['generation']['expression'] === '`price` - 5',\n                    'sqlsrv' => $column['generation']['expression'] === '([price]-(5))',\n                    'pgsql' => $column['generation']['expression'] === '(price - 5)',\n                    default => $column['generation']['expression'] === 'price - 5',\n                }\n        ));\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'stored_price'\n                && $column['generation']['type'] === 'stored'\n                && match ($this->driver) {\n                    'mysql' => $column['generation']['expression'] === '(`price` - 10)',\n                    'mariadb' => $column['generation']['expression'] === '`price` - 10',\n                    'sqlsrv' => $column['generation']['expression'] === '([price]-(10))',\n                    'pgsql' => $column['generation']['expression'] === '(price - 10)',\n                    default => $column['generation']['expression'] === 'price - 10',\n                }\n        ));\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testAddForeignKeysOnSqlite()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->string('title')->unique();\n        });\n\n        Schema::table('posts', function (Blueprint $table) {\n            $table->foreignId('user_id')->nullable()->index()->constrained();\n            $table->string('user_name');\n            $table->foreign('user_name')->references('name')->on('users');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n        $this->assertCount(2, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_id'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['id']));\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_name'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['name']));\n        $this->assertTrue(Schema::hasColumns('posts', ['title', 'user_id', 'user_name']));\n        $this->assertTrue(Schema::hasIndex('posts', ['user_id']));\n        $this->assertTrue(Schema::hasIndex('posts', ['title'], 'unique'));\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testDropForeignKeysOnSqlite()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->id();\n            $table->foreignId('user_id')->nullable()->index()->constrained();\n            $table->string('user_name')->unique();\n            $table->foreign('user_name')->references('name')->on('users');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n        $this->assertCount(2, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_id'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['id']));\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_name'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['name']));\n        $this->assertTrue(Schema::hasIndex('posts', ['id'], 'primary'));\n\n        Schema::table('posts', function (Blueprint $table) {\n            $table->string('title')->unique();\n            $table->dropIndex(['user_id']);\n            $table->dropForeign(['user_id']);\n            $table->dropColumn('user_id');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_name'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['name']));\n        $this->assertTrue(Schema::hasColumns('posts', ['user_name', 'title']));\n        $this->assertTrue(Schema::hasIndex('posts', ['id'], 'primary'));\n        $this->assertTrue(Schema::hasIndex('posts', ['title'], 'unique'));\n        $this->assertTrue(Schema::hasIndex('posts', ['user_name'], 'unique'));\n        $this->assertFalse(Schema::hasColumn('posts', 'user_id'));\n        $this->assertFalse(Schema::hasIndex('posts', ['user_id']));\n    }\n\n    #[RequiresDatabase('sqlite')]\n    public function testAddAndDropPrimaryOnSqlite()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->foreignId('user_id')->nullable()->index()->constrained();\n            $table->string('user_name')->unique();\n            $table->foreign('user_name')->references('name')->on('users');\n        });\n\n        Schema::table('posts', function (Blueprint $table) {\n            $table->string('title')->primary();\n            $table->dropIndex(['user_id']);\n            $table->dropForeign(['user_id']);\n            $table->dropColumn('user_id');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_name'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['name']));\n        $this->assertTrue(Schema::hasColumns('posts', ['user_name', 'title']));\n        $this->assertTrue(Schema::hasIndex('posts', ['title'], 'primary'));\n        $this->assertTrue(Schema::hasIndex('posts', ['user_name'], 'unique'));\n        $this->assertFalse(Schema::hasColumn('posts', 'user_id'));\n        $this->assertFalse(Schema::hasIndex('posts', ['user_id']));\n\n        Schema::table('posts', function (Blueprint $table) {\n            $table->dropPrimary();\n            $table->integer('votes');\n        });\n\n        $foreignKeys = Schema::getForeignKeys('posts');\n        $this->assertCount(1, $foreignKeys);\n        $this->assertTrue(collect($foreignKeys)->contains(fn ($foreign) => $foreign['columns'] === ['user_name'] && $foreign['foreign_table'] === 'users' && $foreign['foreign_columns'] === ['name']));\n        $this->assertTrue(Schema::hasColumns('posts', ['user_name', 'title', 'votes']));\n        $this->assertFalse(Schema::hasIndex('posts', ['title'], 'primary'));\n        $this->assertTrue(Schema::hasIndex('posts', ['user_name'], 'unique'));\n    }\n\n    public function testAddingMacros()\n    {\n        Schema::macro('foo', fn () => 'foo');\n\n        $this->assertEquals('foo', Schema::foo());\n\n        Schema::macro('hasForeignKeyForColumn', function (string $column, string $table, string $foreignTable) {\n            return collect(Schema::getForeignKeys($table))\n                ->contains(function (array $foreignKey) use ($column, $foreignTable) {\n                    return collect($foreignKey['columns'])->contains($column)\n                        && $foreignKey['foreign_table'] == $foreignTable;\n                });\n        });\n\n        Schema::create('questions', function (Blueprint $table) {\n            $table->id();\n            $table->string('body');\n        });\n\n        Schema::create('answers', function (Blueprint $table) {\n            $table->id();\n            $table->string('body');\n            $table->foreignId('question_id')->constrained();\n        });\n\n        $this->assertTrue(Schema::hasForeignKeyForColumn('question_id', 'answers', 'questions'));\n        $this->assertFalse(Schema::hasForeignKeyForColumn('body', 'answers', 'questions'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/DatabaseEloquentSqlServerIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseEloquentSqlServerIntegrationTest extends SqlServerTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('database_eloquent_sql_server_integration_users')) {\n            Schema::create('database_eloquent_sql_server_integration_users', function (Blueprint $table) {\n                $table->id();\n                $table->string('name')->nullable();\n                $table->string('email')->unique();\n                $table->timestamps();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('database_eloquent_sql_server_integration_users');\n    }\n\n    public function testCreateOrFirst()\n    {\n        $user1 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(['email' => 'taylorotwell@gmail.com']);\n\n        $this->assertSame('taylorotwell@gmail.com', $user1->email);\n        $this->assertNull($user1->name);\n\n        $user2 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(\n            ['email' => 'taylorotwell@gmail.com'],\n            ['name' => 'Taylor Otwell']\n        );\n\n        $this->assertEquals($user1->id, $user2->id);\n        $this->assertSame('taylorotwell@gmail.com', $user2->email);\n        $this->assertNull($user2->name);\n\n        $user3 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(\n            ['email' => 'abigailotwell@gmail.com'],\n            ['name' => 'Abigail Otwell']\n        );\n\n        $this->assertNotEquals($user3->id, $user1->id);\n        $this->assertSame('abigailotwell@gmail.com', $user3->email);\n        $this->assertSame('Abigail Otwell', $user3->name);\n\n        $user4 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(\n            ['name' => 'Dries Vints'],\n            ['name' => 'Nuno Maduro', 'email' => 'nuno@laravel.com']\n        );\n\n        $this->assertSame('Nuno Maduro', $user4->name);\n    }\n\n    public function testCreateOrFirstWithinTransaction()\n    {\n        $user1 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(['email' => 'taylor@laravel.com']);\n\n        DB::transaction(function () use ($user1) {\n            $user2 = DatabaseEloquentSqlServerIntegrationUser::createOrFirst(\n                ['email' => 'taylor@laravel.com'],\n                ['name' => 'Taylor Otwell']\n            );\n\n            $this->assertEquals($user1->id, $user2->id);\n            $this->assertSame('taylor@laravel.com', $user2->email);\n            $this->assertNull($user2->name);\n        });\n    }\n}\n\nclass DatabaseEloquentSqlServerIntegrationUser extends Model\n{\n    protected $table = 'database_eloquent_sql_server_integration_users';\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/DatabaseSqlServerConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresPhpExtension('pdo_sqlsrv')]\nclass DatabaseSqlServerConnectionTest extends SqlServerTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('json_table')) {\n            Schema::create('json_table', function (Blueprint $table) {\n                $table->json('json_col')->nullable();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('json_table');\n    }\n\n    #[DataProvider('jsonContainsKeyDataProvider')]\n    public function testWhereJsonContainsKey($count, $column)\n    {\n        DB::table('json_table')->insert([\n            ['json_col' => '{\"foo\":{\"bar\":[\"baz\"]}}'],\n            ['json_col' => '{\"foo\":{\"bar\":false}}'],\n            ['json_col' => '{\"foo\":{}}'],\n            ['json_col' => '{\"foo\":[{\"bar\":\"bar\"},{\"baz\":\"baz\"}]}'],\n            ['json_col' => '{\"bar\":null}'],\n        ]);\n\n        $this->assertSame($count, DB::table('json_table')->whereJsonContainsKey($column)->count());\n    }\n\n    public static function jsonContainsKeyDataProvider()\n    {\n        return [\n            'string key' => [4, 'json_col->foo'],\n            'nested key exists' => [2, 'json_col->foo->bar'],\n            'string key missing' => [0, 'json_col->none'],\n            'integer key with arrow ' => [1, 'json_col->foo->bar->0'],\n            'integer key with braces' => [1, 'json_col->foo->bar[0]'],\n            'integer key missing' => [0, 'json_col->foo->bar[1]'],\n            'mixed keys' => [1, 'json_col->foo[1]->baz'],\n            'null value' => [1, 'json_col->bar'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/DatabaseSqlServerSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DatabaseSqlServerSchemaBuilderTest extends SqlServerTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n            $table->string('age');\n            $table->enum('color', ['red', 'blue']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n        Schema::dropIfExists('computed');\n        DB::statement('drop view if exists users_view');\n    }\n\n    public function testGetTables()\n    {\n        DB::statement('create view users_view AS select name, age from users');\n\n        $rows = Schema::getTables();\n\n        $this->assertGreaterThanOrEqual(2, count($rows));\n        $this->assertTrue(\n            collect($rows)->contains('name', 'migrations'),\n            'Failed asserting that table \"migrations\" was returned.'\n        );\n        $this->assertTrue(\n            collect($rows)->contains('name', 'users'),\n            'Failed asserting that table \"users\" was returned.'\n        );\n        $this->assertFalse(\n            collect($rows)->contains('name', 'users_view'),\n            'Failed asserting that view \"users_view\" was not returned.'\n        );\n    }\n\n    public function testColumnListing()\n    {\n        $this->assertSame(['id', 'name', 'age', 'color'], Schema::getColumnListing('users'));\n    }\n\n    public function testGetViews()\n    {\n        DB::statement('create view users_view AS select name, age from users');\n\n        $rows = Schema::getViews();\n\n        $this->assertCount(1, $rows);\n        $this->assertSame('users_view', $rows[0]['name']);\n    }\n\n    public function testGetViewsWhenNoneExist()\n    {\n        $this->assertSame([], Schema::getViews());\n    }\n\n    public function testComputedColumnsListing()\n    {\n        DB::statement('create table dbo.computed (id int identity (1,1) not null, computed as id + 1)');\n\n        $userColumns = Schema::getColumns('users');\n        $this->assertNull($userColumns[1]['generation']);\n    }\n\n    public function testCreateIndexesOnline()\n    {\n        Schema::create('table', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n            $table->string('title', 200);\n\n            $table->unique('title')->online();\n            $table->index(['created_at'])->online();\n        });\n\n        $indexes = Schema::getIndexes('table');\n        $indexNames = collect($indexes)->pluck('name');\n\n        $this->assertContains('table_title_unique', $indexNames);\n        $this->assertContains('table_created_at_index', $indexNames);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/EscapeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse RuntimeException;\n\nclass EscapeTest extends SqlServerTestCase\n{\n    public function testEscapeInt()\n    {\n        $this->assertSame('42', $this->app['db']->escape(42));\n        $this->assertSame('-6', $this->app['db']->escape(-6));\n    }\n\n    public function testEscapeFloat()\n    {\n        $this->assertSame('3.14159', $this->app['db']->escape(3.14159));\n        $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159));\n    }\n\n    public function testEscapeBool()\n    {\n        $this->assertSame('1', $this->app['db']->escape(true));\n        $this->assertSame('0', $this->app['db']->escape(false));\n    }\n\n    public function testEscapeNull()\n    {\n        $this->assertSame('null', $this->app['db']->escape(null));\n        $this->assertSame('null', $this->app['db']->escape(null, true));\n    }\n\n    public function testEscapeBinary()\n    {\n        $this->assertSame('0xdead00beef', $this->app['db']->escape(hex2bin('dead00beef'), true));\n    }\n\n    public function testEscapeString()\n    {\n        $this->assertSame(\"'2147483647'\", $this->app['db']->escape('2147483647'));\n        $this->assertSame(\"'true'\", $this->app['db']->escape('true'));\n        $this->assertSame(\"'false'\", $this->app['db']->escape('false'));\n        $this->assertSame(\"'null'\", $this->app['db']->escape('null'));\n        $this->assertSame(\"'Hello''World'\", $this->app['db']->escape(\"Hello'World\"));\n    }\n\n    public function testEscapeStringInvalidUtf8()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding an invalid \\x80 utf-8 continuation byte\");\n    }\n\n    public function testEscapeStringNullByte()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding a \\00 byte\");\n    }\n\n    public function testEscapeArray()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(['a', 'b']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/JoinLateralTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\n\nclass JoinLateralTest extends SqlServerTestCase\n{\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('name');\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->id('id');\n            $table->string('title');\n            $table->integer('rating');\n            $table->unsignedBigInteger('user_id');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('posts');\n        Schema::drop('users');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        DB::table('users')->insert([\n            ['name' => Str::random()],\n            ['name' => Str::random()],\n        ]);\n\n        DB::table('posts')->insert([\n            ['title' => Str::random(), 'rating' => 1, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 3, 'user_id' => 1],\n            ['title' => Str::random(), 'rating' => 7, 'user_id' => 1],\n        ]);\n    }\n\n    public function testJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, (int) $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, (int) $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->joinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(0, $userWithoutPosts);\n    }\n\n    public function testLeftJoinLateral()\n    {\n        $subquery = DB::table('posts')\n            ->select('title as best_post_title', 'rating as best_post_rating')\n            ->whereColumn('user_id', 'users.id')\n            ->orderBy('rating', 'desc')\n            ->limit(2);\n\n        $userWithPosts = DB::table('users')\n            ->where('id', 1)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(2, $userWithPosts);\n        $this->assertEquals(7, (int) $userWithPosts[0]->best_post_rating);\n        $this->assertEquals(3, (int) $userWithPosts[1]->best_post_rating);\n\n        $userWithoutPosts = DB::table('users')\n            ->where('id', 2)\n            ->leftJoinLateral($subquery, 'best_post')\n            ->get();\n\n        $this->assertCount(1, $userWithoutPosts);\n        $this->assertNull($userWithoutPosts[0]->best_post_title);\n        $this->assertNull($userWithoutPosts[0]->best_post_rating);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/SqlServer/SqlServerTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\SqlServer;\n\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('sqlsrv')]\nabstract class SqlServerTestCase extends DatabaseTestCase\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/ConnectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('sqlite')]\nclass ConnectorTest extends DatabaseTestCase\n{\n    private string $databasePath;\n\n    protected function defineDatabaseMigrations()\n    {\n        Schema::createDatabase($this->databasePath = database_path('secondary.sqlite'));\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::dropDatabaseIfExists($this->databasePath);\n    }\n\n    public function testConnectionConfigurations()\n    {\n        $schema = DB::build([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ])->getSchemaBuilder();\n\n        $this->assertSame(0, $schema->pragma('foreign_keys'));\n        $this->assertSame(60000, $schema->pragma('busy_timeout'));\n        $this->assertSame('memory', $schema->pragma('journal_mode'));\n        $this->assertSame(2, $schema->pragma('synchronous'));\n\n        $schema = DB::build([\n            'driver' => 'sqlite',\n            'database' => $this->databasePath,\n            'foreign_key_constraints' => true,\n            'busy_timeout' => 12345,\n            'journal_mode' => 'wal',\n            'synchronous' => 'normal',\n            'pragmas' => [\n                'query_only' => true,\n            ],\n        ])->getSchemaBuilder();\n\n        $this->assertSame(1, $schema->pragma('foreign_keys'));\n        $this->assertSame(12345, $schema->pragma('busy_timeout'));\n        $this->assertSame('wal', $schema->pragma('journal_mode'));\n        $this->assertSame(1, $schema->pragma('synchronous'));\n        $this->assertSame(1, $schema->pragma('query_only'));\n\n        $schema->pragma('foreign_keys', 0);\n        $schema->pragma('busy_timeout', 54321);\n        $schema->pragma('journal_mode', 'delete');\n        $schema->pragma('synchronous', 0);\n\n        $this->assertSame(0, $schema->pragma('foreign_keys'));\n        $this->assertSame(54321, $schema->pragma('busy_timeout'));\n        $this->assertSame('delete', $schema->pragma('journal_mode'));\n        $this->assertSame(0, $schema->pragma('synchronous'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/Console/MigrateFreshCommandWithJournalModeWalTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite\\Console;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\n\nuse function Illuminate\\Filesystem\\join_paths;\nuse function Orchestra\\Testbench\\default_migration_path;\nuse function Orchestra\\Testbench\\default_skeleton_path;\n\n#[RequiresDatabase('sqlite')]\n#[WithConfig('database.connections.sqlite.journal_mode', 'wal')]\nclass MigrateFreshCommandWithJournalModeWalTest extends DatabaseTestCase\n{\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $files = new Filesystem;\n\n        $files->copy(\n            join_paths(__DIR__, 'stubs', 'database-journal-mode-wal.sqlite'),\n            join_paths(default_skeleton_path(), 'database', 'database.sqlite')\n        );\n\n        $this->beforeApplicationDestroyed(function () use ($files) {\n            $files->delete(database_path('database.sqlite'));\n        });\n\n        parent::setUp();\n    }\n\n    public function testRunningMigrateFreshCommandWithWalJournalMode()\n    {\n        $this->artisan('migrate:fresh', [\n            '--realpath' => true,\n            '--path' => default_migration_path(),\n        ])->run();\n\n        $this->assertTrue(Schema::hasTable('users'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/DatabaseSchemaBlueprintTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Closure;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\n#[RequiresDatabase('sqlite')]\nclass DatabaseSchemaBlueprintTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set([\n            'database.default' => 'testing',\n        ]);\n    }\n\n    public function testRenamingAndChangingColumnsWork()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name');\n            $table->string('age');\n        });\n\n        $blueprint = $this->getBlueprint('SQLite', 'users', function ($table) {\n            $table->renameColumn('name', 'first_name');\n            $table->integer('age')->change();\n        });\n\n        $queries = $blueprint->toSql();\n\n        $expected = [\n            'alter table \"users\" rename column \"name\" to \"first_name\"',\n            'create table \"__temp__users\" (\"first_name\" varchar not null, \"age\" integer not null)',\n            'insert into \"__temp__users\" (\"first_name\", \"age\") select \"first_name\", \"age\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ];\n\n        $this->assertEquals($expected, $queries);\n    }\n\n    public function testRenamingColumnsWorks()\n    {\n        $schema = DB::connection()->getSchemaBuilder();\n\n        $schema->create('test', function (Blueprint $table) {\n            $table->string('foo');\n            $table->string('baz');\n        });\n\n        $schema->table('test', function (Blueprint $table) {\n            $table->renameColumn('foo', 'bar');\n            $table->renameColumn('baz', 'qux');\n        });\n\n        $this->assertFalse($schema->hasColumn('test', 'foo'));\n        $this->assertFalse($schema->hasColumn('test', 'baz'));\n        $this->assertTrue($schema->hasColumns('test', ['bar', 'qux']));\n    }\n\n    public function testNativeColumnModifyingOnPostgreSql()\n    {\n        $blueprint = $this->getBlueprint('Postgres', 'users', function ($table) {\n            $table->integer('code')->autoIncrement()->from(10)->comment('my comment')->change();\n        });\n\n        $this->assertEquals([\n            'alter table \"users\" '\n                .'alter column \"code\" type integer, '\n                .'alter column \"code\" set not null',\n            'select setval(pg_get_serial_sequence(\\'\"users\"\\', \\'code\\'), 10, false)',\n            'comment on column \"users\".\"code\" is \\'my comment\\'',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('Postgres', 'users', function ($table) {\n            $table->char('name', 40)->nullable()->default('easy')->collation('unicode')->change();\n        });\n\n        $this->assertEquals([\n            'alter table \"users\" '\n                .'alter column \"name\" type char(40) collate \"unicode\", '\n                .'alter column \"name\" drop not null, '\n                .'alter column \"name\" set default \\'easy\\', '\n                .'alter column \"name\" drop identity if exists',\n            'comment on column \"users\".\"name\" is NULL',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('Postgres', 'users', function ($table) {\n            $table->integer('foo')->generatedAs('expression')->always()->change();\n        });\n\n        $this->assertEquals([\n            'alter table \"users\" '\n                .'alter column \"foo\" type integer, '\n                .'alter column \"foo\" set not null, '\n                .'alter column \"foo\" drop default, '\n                .'alter column \"foo\" drop identity if exists, '\n                .'alter column \"foo\" add  generated always as identity (expression)',\n            'comment on column \"users\".\"foo\" is NULL',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('Postgres', 'users', function ($table) {\n            $table->geometry('foo', 'point', 1234)->change();\n        });\n\n        $this->assertEquals([\n            'alter table \"users\" '\n                .'alter column \"foo\" type geometry(point,1234), '\n                .'alter column \"foo\" set not null, '\n                .'alter column \"foo\" drop default, '\n                .'alter column \"foo\" drop identity if exists',\n            'comment on column \"users\".\"foo\" is NULL',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('Postgres', 'users', function ($table) {\n            $table->timestamp('added_at', 2)->useCurrent()->storedAs(null)->change();\n        });\n\n        $this->assertEquals([\n            'alter table \"users\" '\n                .'alter column \"added_at\" type timestamp(2) without time zone, '\n                .'alter column \"added_at\" set not null, '\n                .'alter column \"added_at\" set default CURRENT_TIMESTAMP, '\n                .'alter column \"added_at\" drop expression if exists, '\n                .'alter column \"added_at\" drop identity if exists',\n            'comment on column \"users\".\"added_at\" is NULL',\n        ], $blueprint->toSql());\n    }\n\n    public function testNativeColumnModifyingOnSqlServer()\n    {\n        $blueprint = $this->getBlueprint('SqlServer', 'users', function ($table) {\n            $table->timestamp('added_at', 4)->nullable(false)->useCurrent()->change();\n        });\n\n        $this->assertEquals([\n            \"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"users\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"users\\\"') AND [name] in ('added_at') AND [default_object_id] <> 0;EXEC(@sql)\",\n            'alter table \"users\" alter column \"added_at\" datetime2(4) not null',\n            'alter table \"users\" add default CURRENT_TIMESTAMP for \"added_at\"',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('SqlServer', 'users', function ($table) {\n            $table->char('name', 40)->nullable()->default('easy')->collation('unicode')->change();\n        });\n\n        $this->assertEquals([\n            \"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"users\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"users\\\"') AND [name] in ('name') AND [default_object_id] <> 0;EXEC(@sql)\",\n            'alter table \"users\" alter column \"name\" nchar(40) collate unicode null',\n            'alter table \"users\" add default \\'easy\\' for \"name\"',\n        ], $blueprint->toSql());\n\n        $blueprint = $this->getBlueprint('SqlServer', 'users', function ($table) {\n            $table->integer('foo')->change();\n        });\n\n        $this->assertEquals([\n            \"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"users\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"users\\\"') AND [name] in ('foo') AND [default_object_id] <> 0;EXEC(@sql)\",\n            'alter table \"users\" alter column \"foo\" int not null',\n        ], $blueprint->toSql());\n    }\n\n    public function testChangingColumnWithCollationWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('age');\n        });\n\n        $blueprint = $this->getBlueprint('SQLite', 'users', function ($table) {\n            $table->integer('age')->collation('RTRIM')->change();\n        });\n\n        $blueprint2 = $this->getBlueprint('SQLite', 'users', function ($table) {\n            $table->integer('age')->collation('NOCASE')->change();\n        });\n\n        $queries = $blueprint->toSql();\n\n        $expected = [\n            'create table \"__temp__users\" (\"age\" integer not null collate \\'RTRIM\\')',\n            'insert into \"__temp__users\" (\"age\") select \"age\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ];\n\n        $this->assertEquals($expected, $queries);\n\n        $queries = $blueprint2->toSql();\n\n        $expected = [\n            'create table \"__temp__users\" (\"age\" integer not null collate \\'NOCASE\\')',\n            'insert into \"__temp__users\" (\"age\") select \"age\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ];\n\n        $this->assertEquals($expected, $queries);\n    }\n\n    public function testChangingCharColumnsWork()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name');\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->text('changed_col')->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'create table \"__temp__users\" (\"name\" varchar not null)',\n            'insert into \"__temp__users\" (\"name\") select \"name\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n    }\n\n    public function testChangingPrimaryAutoincrementColumnsToNonAutoincrementColumnsWork()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->increments('id');\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->binary('id')->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'create table \"__temp__users\" (\"id\" blob not null, primary key (\"id\"))',\n            'insert into \"__temp__users\" (\"id\") select \"id\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n    }\n\n    public function testChangingDoubleColumnsWork()\n    {\n        DB::connection()->getSchemaBuilder()->create('products', function ($table) {\n            $table->integer('price');\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'products', function ($table) {\n                $table->double('price')->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'create table \"__temp__products\" (\"price\" double not null)',\n            'insert into \"__temp__products\" (\"price\") select \"price\" from \"products\"',\n            'drop table \"products\"',\n            'alter table \"__temp__products\" rename to \"products\"',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n    }\n\n    public function testChangingColumnsWithDefaultWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('products', function ($table) {\n            $table->integer('changed_col');\n            $table->timestamp('timestamp_col')->useCurrent();\n            $table->integer('integer_col')->default(123);\n            $table->string('string_col')->default('value');\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'products', function ($table) {\n                $table->text('changed_col')->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'create table \"__temp__products\" (\"changed_col\" text not null, \"timestamp_col\" datetime not null default (CURRENT_TIMESTAMP), \"integer_col\" integer not null default (\\'123\\'), \"string_col\" varchar not null default (\\'value\\'))',\n            'insert into \"__temp__products\" (\"changed_col\", \"timestamp_col\", \"integer_col\", \"string_col\") select \"changed_col\", \"timestamp_col\", \"integer_col\", \"string_col\" from \"products\"',\n            'drop table \"products\"',\n            'alter table \"__temp__products\" rename to \"products\"',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n    }\n\n    public function testRenameIndexWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name');\n            $table->string('age');\n        });\n        DB::connection()->getSchemaBuilder()->table('users', function ($table) {\n            $table->index(['name'], 'index1');\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->renameIndex('index1', 'index2');\n            })->toSql();\n        };\n\n        $expected = [\n            'drop index \"index1\"',\n            'create index \"index2\" on \"users\" (\"name\")',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n\n        $expected = [\n            'sp_rename N\\'\"users\".\"index1\"\\', \"index2\", N\\'INDEX\\'',\n        ];\n\n        $this->assertEquals($expected, $getSql('SqlServer'));\n\n        $expected = [\n            'alter table `users` rename index `index1` to `index2`',\n        ];\n\n        $this->assertEquals($expected, $getSql('MySql'));\n\n        $expected = [\n            'alter index \"index1\" rename to \"index2\"',\n        ];\n\n        $this->assertEquals($expected, $getSql('Postgres'));\n    }\n\n    public function testAddUniqueIndexWithoutNameWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name')->nullable();\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->string('name')->nullable()->unique()->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'alter table `users` modify `name` varchar(255) null',\n            'alter table `users` add unique `users_name_unique`(`name`)',\n        ];\n\n        $this->assertEquals($expected, $getSql('MySql'));\n\n        $expected = [\n            'alter table \"users\" alter column \"name\" type varchar(255), alter column \"name\" drop not null, alter column \"name\" drop default, alter column \"name\" drop identity if exists',\n            'alter table \"users\" add constraint \"users_name_unique\" unique (\"name\")',\n            'comment on column \"users\".\"name\" is NULL',\n        ];\n\n        $this->assertEquals($expected, $getSql('Postgres'));\n\n        $expected = [\n            'create table \"__temp__users\" (\"name\" varchar)',\n            'insert into \"__temp__users\" (\"name\") select \"name\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'create unique index \"users_name_unique\" on \"users\" (\"name\")',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n\n        $expected = [\n            \"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"users\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"users\\\"') AND [name] in ('name') AND [default_object_id] <> 0;EXEC(@sql)\",\n            'alter table \"users\" alter column \"name\" nvarchar(255) null',\n            'create unique index \"users_name_unique\" on \"users\" (\"name\")',\n        ];\n\n        $this->assertEquals($expected, $getSql('SqlServer'));\n    }\n\n    public function testAddUniqueIndexWithNameWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name')->nullable();\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->unsignedInteger('name')->nullable()->unique('index1')->change();\n            })->toSql();\n        };\n\n        $expected = [\n            'alter table `users` modify `name` int unsigned null',\n            'alter table `users` add unique `index1`(`name`)',\n        ];\n\n        $this->assertEquals($expected, $getSql('MySql'));\n\n        $expected = [\n            'alter table \"users\" alter column \"name\" type integer, alter column \"name\" drop not null, alter column \"name\" drop default, alter column \"name\" drop identity if exists',\n            'alter table \"users\" add constraint \"index1\" unique (\"name\")',\n            'comment on column \"users\".\"name\" is NULL',\n        ];\n\n        $this->assertEquals($expected, $getSql('Postgres'));\n\n        $expected = [\n            'create table \"__temp__users\" (\"name\" integer)',\n            'insert into \"__temp__users\" (\"name\") select \"name\" from \"users\"',\n            'drop table \"users\"',\n            'alter table \"__temp__users\" rename to \"users\"',\n            'create unique index \"index1\" on \"users\" (\"name\")',\n        ];\n\n        $this->assertEquals($expected, $getSql('SQLite'));\n\n        $expected = [\n            \"DECLARE @sql NVARCHAR(MAX) = '';SELECT @sql += 'ALTER TABLE \\\"users\\\" DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' FROM sys.columns WHERE [object_id] = OBJECT_ID(N'\\\"users\\\"') AND [name] in ('name') AND [default_object_id] <> 0;EXEC(@sql)\",\n            'alter table \"users\" alter column \"name\" int null',\n            'create unique index \"index1\" on \"users\" (\"name\")',\n        ];\n\n        $this->assertEquals($expected, $getSql('SqlServer'));\n    }\n\n    public function testAddColumnNamedCreateWorks()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->string('name');\n        });\n\n        Schema::table('users', function (Blueprint $table) {\n            $table->string('create')->nullable();\n        });\n\n        $this->assertTrue(Schema::hasColumn('users', 'create'));\n    }\n\n    public function testDropIndexOnColumnChangeWorks()\n    {\n        DB::connection()->getSchemaBuilder()->create('users', function ($table) {\n            $table->string('name')->nullable();\n        });\n\n        $getSql = function ($grammar) {\n            return $this->getBlueprint($grammar, 'users', function ($table) {\n                $table->string('name')->nullable()->unique(false)->change();\n            })->toSql();\n        };\n\n        $this->assertContains(\n            'alter table `users` drop index `users_name_unique`',\n            $getSql('MySql'),\n        );\n\n        $this->assertContains(\n            'alter table \"users\" drop constraint \"users_name_unique\"',\n            $getSql('Postgres'),\n        );\n\n        $this->assertContains(\n            'drop index \"users_name_unique\"',\n            $getSql('SQLite'),\n        );\n\n        $this->assertContains(\n            'drop index \"users_name_unique\" on \"users\"',\n            $getSql('SqlServer'),\n        );\n    }\n\n    public function testItDoesNotSetPrecisionHigherThanSupportedWhenRenamingTimestamps()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->timestamp('created_at');\n        });\n\n        try {\n            // this would only fail in mysql, postgres and sql server\n            Schema::table('users', function (Blueprint $table) {\n                $table->renameColumn('created_at', 'new_created_at');\n            });\n\n            $this->addToAssertionCount(1); // it did not throw\n        } catch (\\Exception $e) {\n            // Expecting something similar to:\n            // Illuminate\\Database\\QueryException\n            //   SQLSTATE[42000]: Syntax error or access violation: 1426 Too big precision 10 specified for 'my_timestamp'. Maximum is 6....\n            $this->fail('test_it_does_not_set_precision_higher_than_supported_when_renaming_timestamps has failed. Error: '.$e->getMessage());\n        }\n    }\n\n    public function testItEnsuresDroppingForeignKeyIsAvailable()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('This database driver does not support dropping foreign keys by name.');\n\n        Schema::table('users', function (Blueprint $table) {\n            $table->dropForeign('something');\n        });\n    }\n\n    protected function getBlueprint(\n        string $grammar,\n        string $table,\n        Closure $callback,\n    ): Blueprint {\n        $grammarClass = 'Illuminate\\Database\\Schema\\Grammars\\\\'.$grammar.'Grammar';\n\n        $connection = DB::connection();\n        $connection->setSchemaGrammar(new $grammarClass($connection));\n\n        return new Blueprint($connection, $table, $callback);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/DatabaseSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse Orchestra\\Testbench\\TestCase;\n\n#[RequiresDatabase('sqlite')]\nclass DatabaseSchemaBuilderTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set([\n            'database.connections.sqlite-with-prefix' => [\n                'driver' => 'sqlite',\n                'database' => ':memory:',\n                'prefix' => 'example_',\n                'prefix_indexes' => false,\n            ],\n            'database.connections.sqlite-with-indexed-prefix' => [\n                'driver' => 'sqlite',\n                'database' => ':memory:',\n                'prefix' => 'example_',\n                'prefix_indexes' => true,\n            ],\n        ]);\n    }\n\n    public function testDropAllTablesWorksWithForeignKeys()\n    {\n        Schema::create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n        });\n\n        Schema::create('table2', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('user_id');\n            $table->foreign('user_id')->references('id')->on('table1');\n        });\n\n        $this->assertTrue(Schema::hasTable('table1'));\n        $this->assertTrue(Schema::hasTable('table2'));\n\n        Schema::dropAllTables();\n\n        $this->assertFalse(Schema::hasTable('table1'));\n        $this->assertFalse(Schema::hasTable('table2'));\n    }\n\n    public function testHasColumnAndIndexWithPrefixIndexDisabled()\n    {\n        $connection = DB::connection('sqlite-with-prefix');\n\n        Schema::connection('sqlite-with-prefix')->create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name')->index();\n        });\n\n        $indexes = array_column($connection->getSchemaBuilder()->getIndexes('table1'), 'name');\n\n        $this->assertContains('table1_name_index', $indexes, 'name');\n    }\n\n    public function testHasColumnAndIndexWithPrefixIndexEnabled()\n    {\n        $connection = DB::connection('sqlite-with-indexed-prefix');\n\n        Schema::connection('sqlite-with-indexed-prefix')->create('table1', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name')->index();\n        });\n\n        $indexes = array_column($connection->getSchemaBuilder()->getIndexes('table1'), 'name');\n\n        $this->assertContains('example_table1_name_index', $indexes);\n    }\n\n    public function testAlterTableAddForeignKeyWithPrefix()\n    {\n        $schema = Schema::connection('sqlite-with-prefix');\n\n        $schema->create('table1', function (Blueprint $table) {\n            $table->id();\n        });\n\n        $schema->create('table2', function (Blueprint $table) {\n            $table->id();\n            $table->foreignId('author_id')->constrained('table1');\n        });\n\n        $schema->table('table2', function (Blueprint $table) {\n            $table->foreignId('moderator_id')->constrained('table1');\n        });\n\n        $foreignKeys = collect($schema->getForeignKeys('table2'));\n\n        $this->assertTrue($foreignKeys->contains(\n            fn ($fk) => $fk['foreign_table'] === 'example_table1' &&\n                $fk['foreign_columns'] === ['id'] &&\n                $fk['columns'] === ['author_id'])\n        );\n\n        $this->assertTrue($foreignKeys->contains(\n            fn ($fk) => $fk['foreign_table'] === 'example_table1' &&\n                $fk['foreign_columns'] === ['id'] &&\n                $fk['columns'] === ['moderator_id'])\n        );\n    }\n\n    public function testAlterTableAddForeignKeyWithExpressionDefault()\n    {\n        Schema::create('items', function (Blueprint $table) {\n            $table->id();\n            $table->json('flags')->default(new Expression('(JSON_ARRAY())'));\n        });\n\n        Schema::table('items', function (Blueprint $table) {\n            $table->foreignId('item_id')->nullable()->constrained('items');\n        });\n\n        $this->assertTrue(collect(Schema::getForeignKeys('items'))->contains(\n            fn ($fk) => $fk['foreign_table'] === 'items' &&\n                $fk['foreign_columns'] === ['id'] &&\n                $fk['columns'] === ['item_id']\n        ));\n\n        $columns = Schema::getColumns('items');\n\n        $this->assertTrue(collect($columns)->contains(\n            fn ($column) => $column['name'] === 'flags' && $column['default'] === 'JSON_ARRAY()'\n        ));\n\n        $this->assertTrue(collect($columns)->contains(fn ($column) => $column['name'] === 'item_id' && $column['nullable']));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/DatabaseSqliteConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\n#[RequiresDatabase('sqlite')]\nclass DatabaseSqliteConnectionTest extends DatabaseTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.default', 'conn1');\n\n        $app['config']->set('database.connections.conn1', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        if (! Schema::hasTable('json_table')) {\n            Schema::create('json_table', function (Blueprint $table) {\n                $table->json('json_col')->nullable();\n            });\n        }\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('json_table');\n    }\n\n    #[DataProvider('jsonContainsKeyDataProvider')]\n    public function testWhereJsonContainsKey($count, $column)\n    {\n        DB::table('json_table')->insert([\n            ['json_col' => '{\"foo\":{\"bar\":[\"baz\"]}}'],\n            ['json_col' => '{\"foo\":{\"bar\":false}}'],\n            ['json_col' => '{\"foo\":{}}'],\n            ['json_col' => '{\"foo\":[{\"bar\":\"bar\"},{\"baz\":\"baz\"}]}'],\n            ['json_col' => '{\"bar\":null}'],\n        ]);\n\n        $this->assertSame($count, DB::table('json_table')->whereJsonContainsKey($column)->count());\n    }\n\n    public static function jsonContainsKeyDataProvider()\n    {\n        return [\n            'string key' => [4, 'json_col->foo'],\n            'nested key exists' => [2, 'json_col->foo->bar'],\n            'string key missing' => [0, 'json_col->none'],\n            'integer key with arrow ' => [0, 'json_col->foo->bar->0'],\n            'integer key with braces' => [1, 'json_col->foo->bar[0]'],\n            'integer key missing' => [0, 'json_col->foo->bar[1]'],\n            'mixed keys' => [1, 'json_col->foo[1]->baz'],\n            'null value' => [1, 'json_col->bar'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/DatabaseSqliteSchemaBuilderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('sqlite')]\nclass DatabaseSqliteSchemaBuilderTest extends DatabaseTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.default', 'conn1');\n\n        $app['config']->set('database.connections.conn1', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('name');\n            $table->string('age');\n            $table->enum('color', ['red', 'blue']);\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::drop('users');\n    }\n\n    public function testGetTablesAndColumnListing()\n    {\n        $tables = Schema::getTables();\n\n        $this->assertCount(2, $tables);\n        $this->assertEquals(['migrations', 'users'], array_column($tables, 'name'));\n\n        $columns = Schema::getColumnListing('users');\n\n        foreach (['id', 'name', 'age', 'color'] as $column) {\n            $this->assertContains($column, $columns);\n        }\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->integer('id');\n            $table->string('title');\n        });\n        $tables = Schema::getTables();\n        $this->assertCount(3, $tables);\n        Schema::drop('posts');\n    }\n\n    public function testGetViews()\n    {\n        DB::connection('conn1')->statement(<<<'SQL'\nCREATE VIEW users_view\nAS\nSELECT name,age from users;\nSQL);\n\n        $tableView = Schema::getViews();\n\n        $this->assertCount(1, $tableView);\n        $this->assertEquals('users_view', $tableView[0]['name']);\n\n        DB::connection('conn1')->statement(<<<'SQL'\nDROP VIEW IF EXISTS users_view;\nSQL);\n\n        $this->assertEmpty(Schema::getViews());\n    }\n\n    public function testGetRawIndex()\n    {\n        Schema::create('table', function (Blueprint $table) {\n            $table->id();\n            $table->timestamps();\n            $table->rawIndex('(strftime(\"%Y\", created_at))', 'table_raw_index');\n        });\n\n        $indexes = Schema::getIndexes('table');\n\n        $this->assertSame([], collect($indexes)->firstWhere('name', 'table_raw_index')['columns']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/EloquentModelConnectionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse Orchestra\\Testbench\\TestCase;\n\n#[RequiresDatabase('sqlite')]\nclass EloquentModelConnectionsTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('database.default', 'conn1');\n\n        $app['config']->set('database.connections.conn1', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n\n        $app['config']->set('database.connections.conn2', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n    }\n\n    protected function defineDatabaseMigrations()\n    {\n        Schema::create('parent', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        Schema::create('child', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->integer('parent_id');\n        });\n\n        Schema::connection('conn2')->create('parent', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n        });\n\n        Schema::connection('conn2')->create('child', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->integer('parent_id');\n        });\n    }\n\n    public function testChildObeysParentConnection()\n    {\n        $parent1 = ParentModel::create(['name' => Str::random()]);\n        $parent1->children()->create(['name' => 'childOnConn1']);\n        $parents1 = ParentModel::with('children')->get();\n        $this->assertSame('childOnConn1', ChildModel::on('conn1')->first()->name);\n        $this->assertSame('childOnConn1', $parent1->children()->first()->name);\n        $this->assertSame('childOnConn1', $parents1[0]->children[0]->name);\n\n        $parent2 = ParentModel::on('conn2')->create(['name' => Str::random()]);\n        $parent2->children()->create(['name' => 'childOnConn2']);\n        $parents2 = ParentModel::on('conn2')->with('children')->get();\n        $this->assertSame('childOnConn2', ChildModel::on('conn2')->first()->name);\n        $this->assertSame('childOnConn2', $parent2->children()->first()->name);\n        $this->assertSame('childOnConn2', $parents2[0]->children[0]->name);\n    }\n\n    public function testChildUsesItsOwnConnectionIfSet()\n    {\n        $parent1 = ParentModel::create(['name' => Str::random()]);\n        $parent1->childrenDefaultConn2()->create(['name' => 'childAlwaysOnConn2']);\n        $parents1 = ParentModel::with('childrenDefaultConn2')->get();\n        $this->assertSame('childAlwaysOnConn2', ChildModelDefaultConn2::first()->name);\n        $this->assertSame('childAlwaysOnConn2', $parent1->childrenDefaultConn2()->first()->name);\n        $this->assertSame('childAlwaysOnConn2', $parents1[0]->childrenDefaultConn2[0]->name);\n        $this->assertSame('childAlwaysOnConn2', $parents1[0]->childrenDefaultConn2[0]->name);\n    }\n\n    public function testChildUsesItsOwnConnectionIfSetEvenIfParentExplicitConnection()\n    {\n        $parent1 = ParentModel::on('conn1')->create(['name' => Str::random()]);\n        $parent1->childrenDefaultConn2()->create(['name' => 'childAlwaysOnConn2']);\n        $parents1 = ParentModel::on('conn1')->with('childrenDefaultConn2')->get();\n        $this->assertSame('childAlwaysOnConn2', ChildModelDefaultConn2::first()->name);\n        $this->assertSame('childAlwaysOnConn2', $parent1->childrenDefaultConn2()->first()->name);\n        $this->assertSame('childAlwaysOnConn2', $parents1[0]->childrenDefaultConn2[0]->name);\n    }\n}\n\nclass ParentModel extends Model\n{\n    public $table = 'parent';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function children()\n    {\n        return $this->hasMany(ChildModel::class, 'parent_id');\n    }\n\n    public function childrenDefaultConn2()\n    {\n        return $this->hasMany(ChildModelDefaultConn2::class, 'parent_id');\n    }\n}\n\nclass ChildModel extends Model\n{\n    public $table = 'child';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(ParentModel::class, 'parent_id');\n    }\n}\n\nclass ChildModelDefaultConn2 extends Model\n{\n    public $connection = 'conn2';\n    public $table = 'child';\n    public $timestamps = false;\n    protected $guarded = [];\n\n    public function parent()\n    {\n        return $this->belongsTo(ParentModel::class, 'parent_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/EscapeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse RuntimeException;\n\n#[RequiresDatabase('sqlite')]\nclass EscapeTest extends DatabaseTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('database.default', 'conn1');\n\n        $app['config']->set('database.connections.conn1', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n    }\n\n    public function testEscapeInt()\n    {\n        $this->assertSame('42', $this->app['db']->escape(42));\n        $this->assertSame('-6', $this->app['db']->escape(-6));\n    }\n\n    public function testEscapeFloat()\n    {\n        $this->assertSame('3.14159', $this->app['db']->escape(3.14159));\n        $this->assertSame('-3.14159', $this->app['db']->escape(-3.14159));\n    }\n\n    public function testEscapeBool()\n    {\n        $this->assertSame('1', $this->app['db']->escape(true));\n        $this->assertSame('0', $this->app['db']->escape(false));\n    }\n\n    public function testEscapeNull()\n    {\n        $this->assertSame('null', $this->app['db']->escape(null));\n        $this->assertSame('null', $this->app['db']->escape(null, true));\n    }\n\n    public function testEscapeBinary()\n    {\n        $this->assertSame(\"x'dead00beef'\", $this->app['db']->escape(hex2bin('dead00beef'), true));\n    }\n\n    public function testEscapeString()\n    {\n        $this->assertSame(\"'2147483647'\", $this->app['db']->escape('2147483647'));\n        $this->assertSame(\"'true'\", $this->app['db']->escape('true'));\n        $this->assertSame(\"'false'\", $this->app['db']->escape('false'));\n        $this->assertSame(\"'null'\", $this->app['db']->escape('null'));\n        $this->assertSame(\"'Hello''World'\", $this->app['db']->escape(\"Hello'World\"));\n    }\n\n    public function testEscapeStringInvalidUtf8()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding an invalid \\x80 utf-8 continuation byte\");\n    }\n\n    public function testEscapeStringNullByte()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(\"I am hiding a \\00 byte\");\n    }\n\n    public function testEscapeArray()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['db']->escape(['a', 'b']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/SchemaBuilderSchemaNameTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\n#[RequiresDatabase('sqlite')]\nclass SchemaBuilderSchemaNameTest extends \\Illuminate\\Tests\\Integration\\Database\\SchemaBuilderSchemaNameTest\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Database/Sqlite/SchemaStateTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database\\Sqlite;\n\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\n\nuse function Orchestra\\Testbench\\remote;\n\n#[RequiresDatabase('sqlite')]\nclass SchemaStateTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected $files = [\n        'database/schema',\n    ];\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        remote('migrate:install');\n    }\n\n    protected function tearDown(): void\n    {\n        remote('db:wipe')->mustRun();\n\n        parent::tearDown();\n    }\n\n    #[RequiresOperatingSystem('Linux|Darwin')]\n    public function testSchemaDumpOnSqlite()\n    {\n        if ($this->usesSqliteInMemoryDatabaseConnection()) {\n            $this->markTestSkipped('Test cannot be run using :in-memory: database connection');\n        }\n\n        $connection = DB::connection();\n        $connection->getSchemaBuilder()->createDatabase($connection->getConfig('database'));\n\n        $connection->statement('CREATE TABLE IF NOT EXISTS migrations (id integer primary key autoincrement not null, migration varchar not null, batch integer not null);');\n        $connection->statement('CREATE TABLE users (id integer primary key autoincrement not null, email varchar not null, name varchar not null);');\n        $connection->statement('INSERT INTO users (email, name) VALUES (\"taylor@laravel.com\", \"Taylor Otwell\");');\n\n        $this->assertTrue($connection->table('sqlite_sequence')->exists());\n\n        $this->app['files']->ensureDirectoryExists(database_path('schema'));\n\n        $connection->getSchemaState()->dump($connection, database_path('schema/sqlite-schema.sql'));\n\n        $this->assertFileContains([\n            'CREATE TABLE migrations',\n            'CREATE TABLE users',\n        ], 'database/schema/sqlite-schema.sql');\n        $this->assertFileNotContains([\n            'sqlite_sequence',\n        ], 'database/schema/sqlite-schema.sql');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/TimestampTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Database;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\RequiresDatabase;\n\nclass TimestampTypeTest extends DatabaseTestCase\n{\n    public function testChangeDatetimeColumnToTimestampColumn()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->addColumn('datetime', 'datetime_to_timestamp');\n        });\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->timestamp('datetime_to_timestamp')->nullable()->change();\n        });\n\n        $this->assertTrue(Schema::hasColumn('test', 'datetime_to_timestamp'));\n        // Only MySQL, MariaDB, and PostgreSQL actually have a timestamp type\n        $this->assertSame(\n            match ($this->driver) {\n                'mysql', 'mariadb', 'pgsql' => 'timestamp',\n                default => 'datetime',\n            },\n            Schema::getColumnType('test', 'datetime_to_timestamp')\n        );\n    }\n\n    public function testChangeTimestampColumnToDatetimeColumn()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->addColumn('timestamp', 'timestamp_to_datetime');\n        });\n\n        Schema::table('test', function (Blueprint $table) {\n            $table->dateTime('timestamp_to_datetime')->nullable()->change();\n        });\n\n        $this->assertTrue(Schema::hasColumn('test', 'timestamp_to_datetime'));\n        // Postgres only has a timestamp type\n        $this->assertSame(\n            match ($this->driver) {\n                'pgsql' => 'timestamp',\n                default => 'datetime',\n            },\n            Schema::getColumnType('test', 'timestamp_to_datetime')\n        );\n    }\n\n    #[RequiresDatabase(['mysql', 'mariadb'])]\n    public function testChangeStringColumnToTimestampColumn()\n    {\n        Schema::create('test', function (Blueprint $table) {\n            $table->string('string_to_timestamp');\n        });\n\n        $blueprint = new Blueprint($this->getConnection(), 'test', function ($table) {\n            $table->timestamp('string_to_timestamp')->nullable()->change();\n        });\n\n        $expected = ['alter table `test` modify `string_to_timestamp` timestamp null'];\n\n        $this->assertEquals($expected, $blueprint->toSql());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/stubs/2014_10_12_000000_create_members_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreateMembersTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('members', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('email')->unique();\n            $table->string('password');\n            $table->rememberToken();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::drop('members');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Database/stubs/2014_10_13_000000_skipped_migration.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    public function shouldRun(): bool\n    {\n        return false;\n    }\n\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up(): void\n    {\n        Schema::create('skipped_table', function (Blueprint $table) {\n            $table->id();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down(): void\n    {\n        Schema::dropIfExists('skipped_table');\n    }\n};\n"
  },
  {
    "path": "tests/Integration/Encryption/EncryptionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Encryption;\n\nuse Illuminate\\Encryption\\Encrypter;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\n#[WithConfig('app.key', 'base64:IUHRqAQ99pZ0A1MPjbuv1D6ff3jxv0GIvS2qIW4JNU4=')]\nclass EncryptionTest extends TestCase\n{\n    public function testEncryptionProviderBind()\n    {\n        $this->assertInstanceOf(Encrypter::class, $this->app->make('encrypter'));\n    }\n\n    public function testEncryptionWillNotBeInstantiableWhenMissingAppKey()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $this->app['config']->set('app.key', null);\n\n        $this->app->make('encrypter');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Events/DeferEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Events;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass DeferEventsTest extends TestCase\n{\n    public function testDeferEvents()\n    {\n        unset($_SERVER['__event.test']);\n\n        Event::listen('foo', function ($foo) {\n            $_SERVER['__event.test'] = $foo;\n        });\n\n        $response = Event::defer(function () {\n            Event::dispatch('foo', ['bar']);\n\n            $this->assertArrayNotHasKey('__event.test', $_SERVER);\n\n            return 'callback_result';\n        });\n\n        $this->assertEquals('callback_result', $response);\n        $this->assertSame('bar', $_SERVER['__event.test']);\n    }\n\n    public function testDeferModelEvents()\n    {\n        $_SERVER['__model_event.test'] = [];\n\n        TestModel::saved(function () {\n            $_SERVER['__model_event.test'][] = 'saved';\n        });\n\n        $response = Event::defer(function () {\n            $model = new TestModel();\n            $model->fireModelEvent('saved', false);\n\n            $this->assertSame([], $_SERVER['__model_event.test']);\n\n            return 'model_event_response';\n        });\n\n        $this->assertEquals('model_event_response', $response);\n        $this->assertContains('saved', $_SERVER['__model_event.test']);\n    }\n\n    public function testDeferMultipleModelEvents()\n    {\n        $_SERVER['__model_events'] = [];\n\n        TestModel::saved(function () {\n            $_SERVER['__model_events'][] = 'saved:TestModel';\n        });\n\n        AnotherTestModel::created(function () {\n            $_SERVER['__model_events'][] = 'created:AnotherTestModel';\n        });\n\n        $response = Event::defer(function () {\n            $model1 = new TestModel();\n            $model1->fireModelEvent('saved');\n\n            $model2 = new AnotherTestModel();\n            $model2->fireModelEvent('created');\n\n            // Events should not have fired yet\n            $this->assertSame([], $_SERVER['__model_events']);\n\n            return 'multiple_models_response';\n        });\n\n        $this->assertEquals('multiple_models_response', $response);\n        $this->assertSame(['saved:TestModel', 'created:AnotherTestModel'], $_SERVER['__model_events']);\n    }\n\n    public function testDeferSpecificModelEvents()\n    {\n        $_SERVER['__model_events'] = [];\n\n        TestModel::creating(function () {\n            $_SERVER['__model_events'][] = 'creating';\n        });\n\n        TestModel::saved(function () {\n            $_SERVER['__model_events'][] = 'saved';\n        });\n\n        $response = Event::defer(function () {\n            $model = new TestModel();\n            $model->fireModelEvent('creating');\n            $model->fireModelEvent('saved');\n\n            $this->assertSame(['creating'], $_SERVER['__model_events']);\n\n            return 'specific_model_defer_result';\n        }, ['eloquent.saved: '.TestModel::class]);\n\n        $this->assertEquals('specific_model_defer_result', $response);\n        $this->assertSame(['creating', 'saved'], $_SERVER['__model_events']);\n    }\n}\n\nclass TestModel extends Model\n{\n    public function fireModelEvent($event, $halt = true)\n    {\n        return parent::fireModelEvent($event, $halt);\n    }\n}\n\nclass AnotherTestModel extends Model\n{\n    public function fireModelEvent($event, $halt = true)\n    {\n        return parent::fireModelEvent($event, $halt);\n    }\n}\n\nclass DeferTestEvent\n{\n}\n\nclass AnotherDeferTestEvent\n{\n}\n"
  },
  {
    "path": "tests/Integration/Events/EventFakeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Events;\n\nuse Closure;\nuse Exception;\nuse Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\ExpectationFailedException;\n\nclass EventFakeTest extends TestCase\n{\n    use LazilyRefreshDatabase;\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('title');\n            $table->string('slug')->unique();\n            $table->timestamps();\n        });\n    }\n\n    protected function beforeRefreshingDatabase()\n    {\n        Schema::dropIfExists('posts');\n    }\n\n    public function testNonFakedEventGetsProperlyDispatched()\n    {\n        Event::fake(NonImportantEvent::class);\n        Post::observe([PostObserver::class]);\n\n        $post = new Post;\n        $post->title = 'xyz';\n        $post->save();\n\n        $this->assertSame('xyz-Test', $post->slug);\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n    }\n\n    public function testNonFakedEventGetsProperlyDispatchedAndReturnsResponses()\n    {\n        Event::fake(NonImportantEvent::class);\n        Event::listen('test', function () {\n            // one\n        });\n        Event::listen('test', function () {\n            return 'two';\n        });\n        Event::listen('test', function () {\n            //\n        });\n\n        $this->assertEquals([null, 'two', null], Event::dispatch('test'));\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n    }\n\n    public function testNonFakedEventGetsProperlyDispatchedAndCancelsFutureListeners()\n    {\n        Event::fake(NonImportantEvent::class);\n        Event::listen('test', function () {\n            // one\n        });\n        Event::listen('test', function () {\n            return false;\n        });\n        Event::listen('test', function () {\n            $this->fail('should not be called');\n        });\n\n        $this->assertEquals([null], Event::dispatch('test'));\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n    }\n\n    public function testNonFakedHaltedEventGetsProperlyDispatchedAndReturnsResponse()\n    {\n        Event::fake(NonImportantEvent::class);\n        Event::listen('test', function () {\n            // one\n        });\n        Event::listen('test', function () {\n            return 'two';\n        });\n        Event::listen('test', function () {\n            $this->fail('should not be called');\n        });\n\n        $this->assertSame('two', Event::until('test'));\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n    }\n\n    public function testFakeExceptAllowsGivenEventToBeDispatched()\n    {\n        Event::fakeExcept(NonImportantEvent::class);\n\n        Event::dispatch(NonImportantEvent::class);\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n    }\n\n    public function testFakeExceptAllowsGivenEventsToBeDispatched()\n    {\n        Event::fakeExcept([\n            NonImportantEvent::class,\n            'non-fake-event',\n        ]);\n\n        Event::dispatch(NonImportantEvent::class);\n        Event::dispatch('non-fake-event');\n\n        Event::assertNotDispatched(NonImportantEvent::class);\n        Event::assertNotDispatched('non-fake-event');\n    }\n\n    public function testEventsListedInExceptAreProperlyDispatched()\n    {\n        Event::fake()->except('important-event');\n\n        Event::listen('test', function () {\n            return 'test';\n        });\n\n        Event::listen('important-event', function () {\n            return 'important';\n        });\n\n        $this->assertEquals(null, Event::dispatch('test'));\n        $this->assertEquals(['important'], Event::dispatch('important-event'));\n    }\n\n    public function testAssertListening()\n    {\n        Event::fake();\n\n        $listenersOfSameEventInRandomOrder = Arr::shuffle([\n            'listener',\n            'Illuminate\\\\Tests\\\\Integration\\\\Events\\\\PostAutoEventSubscriber@handle',\n            PostEventSubscriber::class,\n            [PostEventSubscriber::class, 'foo'],\n            InvokableEventSubscriber::class,\n        ]);\n\n        foreach ($listenersOfSameEventInRandomOrder as $listener) {\n            Event::listen('event', $listener);\n        }\n\n        Event::subscribe(PostEventSubscriber::class);\n\n        Event::listen(function (NonImportantEvent $event) {\n            // do something\n        });\n\n        Post::observe(new PostObserver);\n\n        (new Post)->save();\n\n        Event::assertListening('event', 'listener');\n        Event::assertListening('event', PostEventSubscriber::class);\n        Event::assertListening('event', PostAutoEventSubscriber::class);\n        Event::assertListening('event', [PostEventSubscriber::class, 'foo']);\n        Event::assertListening('post-created', [PostEventSubscriber::class, 'handlePostCreated']);\n        Event::assertListening('post-deleted', [PostEventSubscriber::class, 'handlePostDeleted']);\n        Event::assertListening(NonImportantEvent::class, Closure::class);\n        Event::assertListening('eloquent.saving: '.Post::class, PostObserver::class.'@saving');\n        Event::assertListening('eloquent.saving: '.Post::class, [PostObserver::class, 'saving']);\n        Event::assertListening('event', InvokableEventSubscriber::class);\n    }\n\n    public function testMissingMethodsAreForwarded()\n    {\n        Event::macro('foo', fn () => 'bar');\n\n        $this->assertEquals('bar', Event::fake()->foo());\n    }\n\n    public function testShouldDispatchAfterCommitEventsAreNotDispatchedIfTransactionFails()\n    {\n        Event::fake();\n\n        try {\n            DB::transaction(function () {\n                Event::dispatch(new ShouldDispatchAfterCommitEvent());\n\n                throw new Exception('foo');\n            });\n        } catch (Exception $e) {\n        }\n\n        Event::assertNotDispatched(ShouldDispatchAfterCommitEvent::class);\n    }\n\n    public function testShouldDispatchAfterCommitEventsAreDispatchedIfTransactionSucceeds()\n    {\n        Event::fake();\n\n        DB::transaction(function () {\n            Event::dispatch(new ShouldDispatchAfterCommitEvent());\n        });\n\n        Event::assertDispatched(ShouldDispatchAfterCommitEvent::class);\n    }\n\n    public function testShouldDispatchAfterCommitEventsAreDispatchedIfThereIsNoTransaction()\n    {\n        Event::fake();\n\n        Event::dispatch(new ShouldDispatchAfterCommitEvent());\n        Event::assertDispatched(ShouldDispatchAfterCommitEvent::class);\n    }\n\n    public function testAssertNothingDispatchedShouldDispatchAfterCommit()\n    {\n        Event::fake();\n        Event::assertNothingDispatched();\n\n        Event::dispatch(new ShouldDispatchAfterCommitEvent);\n        Event::dispatch(new ShouldDispatchAfterCommitEvent);\n\n        try {\n            Event::assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString(\"2 unexpected events were dispatched:\\n\\n- Illuminate\\Tests\\Integration\\Events\\ShouldDispatchAfterCommitEvent dispatched 2 times\", $e->getMessage());\n        }\n    }\n}\n\nclass Post extends Model\n{\n    public $table = 'posts';\n\n    public function save(array $options = [])\n    {\n        if ($this->fireModelEvent('saving') === false) {\n            return false;\n        }\n    }\n}\n\nclass NonImportantEvent\n{\n    //\n}\n\nclass PostEventSubscriber\n{\n    public function handlePostCreated($event)\n    {\n    }\n\n    public function handlePostDeleted($event)\n    {\n    }\n\n    public function subscribe($events)\n    {\n        $events->listen(\n            'post-created',\n            [PostEventSubscriber::class, 'handlePostCreated']\n        );\n\n        $events->listen(\n            'post-deleted',\n            PostEventSubscriber::class.'@handlePostDeleted'\n        );\n    }\n}\n\nclass PostAutoEventSubscriber\n{\n    public function handle($event)\n    {\n        //\n    }\n}\n\nclass PostObserver\n{\n    public function saving(Post $post)\n    {\n        $post->slug = sprintf('%s-Test', $post->title);\n    }\n}\n\nclass InvokableEventSubscriber\n{\n    public function __invoke($event)\n    {\n        //\n    }\n}\n\nclass ShouldDispatchAfterCommitEvent implements ShouldDispatchAfterCommit\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Events/ListenerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Events;\n\nuse Illuminate\\Database\\DatabaseTransactionsManager;\nuse Illuminate\\Support\\Facades\\Event;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ListenerTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        ListenerTestListener::$ran = false;\n        ListenerTestListenerAfterCommit::$ran = false;\n\n        parent::tearDown();\n    }\n\n    public function testClassListenerRunsNormallyIfNoTransactions()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldNotReceive('addCallback')->once()->andReturn(null);\n\n            return $transactionManager;\n        });\n\n        Event::listen(ListenerTestEvent::class, ListenerTestListener::class);\n\n        Event::dispatch(new ListenerTestEvent);\n\n        $this->assertTrue(ListenerTestListener::$ran);\n    }\n\n    public function testClassListenerDoesntRunInsideTransaction()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n\n            return $transactionManager;\n        });\n\n        Event::listen(ListenerTestEvent::class, ListenerTestListenerAfterCommit::class);\n\n        Event::dispatch(new ListenerTestEvent);\n\n        $this->assertFalse(ListenerTestListenerAfterCommit::$ran);\n    }\n}\n\nclass ListenerTestEvent\n{\n    //\n}\n\nclass ListenerTestListener\n{\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n\nclass ListenerTestListenerAfterCommit\n{\n    public static $ran = false;\n\n    public $afterCommit = true;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Events/QueuedClosureListenerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Events;\n\nuse Illuminate\\Events\\CallQueuedListener;\nuse Illuminate\\Events\\InvokeQueuedClosure;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Event;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Orchestra\\Testbench\\TestCase;\n\nclass QueuedClosureListenerTest extends TestCase\n{\n    public function testAnonymousQueuedListenerIsQueued()\n    {\n        Bus::fake();\n\n        Event::listen(\\Illuminate\\Events\\queueable(function (TestEvent $event) {\n            //\n        })->catch(function (TestEvent $event) {\n            //\n        })->onConnection(null)->onQueue(null));\n\n        Event::dispatch(new TestEvent);\n\n        Bus::assertDispatched(CallQueuedListener::class, function ($job) {\n            return $job->class == InvokeQueuedClosure::class;\n        });\n    }\n\n    public function testAnonymousQueuedListenerIsQueuedOnMessageGroup()\n    {\n        $messageGroup = 'group-1';\n\n        Bus::fake();\n\n        Event::listen(\\Illuminate\\Events\\queueable(function (TestEvent $event) {\n            //\n        })->catch(function (TestEvent $event) {\n            //\n        })->onConnection(null)->onQueue(null)->onGroup($messageGroup));\n\n        Event::dispatch(new TestEvent);\n\n        Bus::assertDispatched(CallQueuedListener::class, function ($job) use ($messageGroup) {\n            return $job->messageGroup == $messageGroup;\n        });\n    }\n\n    public function testAnonymousQueuedListenerIsQueuedWithDeduplicator()\n    {\n        $deduplicator = fn ($payload, $queue) => 'deduplicator-1';\n\n        Bus::fake();\n\n        Event::listen(\\Illuminate\\Events\\queueable(function (TestEvent $event) {\n            //\n        })->catch(function (TestEvent $event) {\n            //\n        })->onConnection(null)->onQueue(null)->withDeduplicator($deduplicator));\n\n        Event::dispatch(new TestEvent);\n\n        Bus::assertDispatched(CallQueuedListener::class, function ($job) {\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n\n            return is_callable($job->deduplicator) && call_user_func($job->deduplicator, '', null) == 'deduplicator-1';\n        });\n    }\n}\n\nclass TestEvent\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Events/ShouldDispatchAfterCommitEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Events;\n\nuse Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Event;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ShouldDispatchAfterCommitEventTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        TransactionUnawareTestEvent::$ran = false;\n        ShouldDispatchAfterCommitTestEvent::$ran = false;\n        AnotherShouldDispatchAfterCommitTestEvent::$ran = false;\n\n        parent::tearDown();\n    }\n\n    public function testEventIsDispatchedIfThereIsNoTransaction()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testEventIsNotDispatchedIfTransactionFails()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        try {\n            DB::transaction(function () {\n                Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n\n                throw new \\Exception;\n            });\n        } catch (\\Exception) {\n        }\n\n        $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testEventIsDispatchedIfTransactionSucceeds()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n        });\n\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItHandlesNestedTransactions()\n    {\n        // We are going to dispatch 2 different events in 2 different transactions.\n        // The parent transaction will succeed, but the nested transaction is going to fail and be rolled back.\n        // We want to ensure the event dispatched on the child transaction does not get published, since it failed,\n        // however, the event dispatched on the parent transaction should still be dispatched as usual.\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n        Event::listen(AnotherShouldDispatchAfterCommitTestEvent::class, AnotherShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            try {\n                DB::transaction(function () {\n                    // This event should not be dispatched since the transaction is going to fail.\n                    Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n                    throw new \\Exception;\n                });\n            } catch (\\Exception) {\n            }\n\n            // This event should be dispatched, as the parent transaction does not fail.\n            Event::dispatch(new AnotherShouldDispatchAfterCommitTestEvent);\n        });\n\n        $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n        $this->assertTrue(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItOnlyDispatchesNestedTransactionsEventsAfterTheRootTransactionIsCommitted()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n        Event::listen(AnotherShouldDispatchAfterCommitTestEvent::class, AnotherShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            Event::dispatch(new AnotherShouldDispatchAfterCommitTestEvent);\n\n            DB::transaction(function () {\n                Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n            });\n\n            // Although the child transaction has been concluded, the parent transaction has not.\n            // The event dispatched on the child transaction should not have been dispatched.\n            $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n            $this->assertFalse(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n        });\n\n        // Now that the parent transaction has been committed, the event\n        // on the child transaction should also have been dispatched.\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n        $this->assertTrue(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItOnlyDispatchesNestedTransactionsEventsAfterTheRootTransactionIsCommittedDifferentOrder()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n        Event::listen(AnotherShouldDispatchAfterCommitTestEvent::class, AnotherShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            DB::transaction(function () {\n                Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n            });\n\n            // Although the child transaction has been concluded, the parent transaction has not.\n            // The event dispatched on the child transaction should not have been dispatched.\n            $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n\n            // The main difference with this test is that we dispatch an event on the parent transaction\n            // at the end. This is important due to how the DatabaseTransactionsManager works.\n            Event::dispatch(new AnotherShouldDispatchAfterCommitTestEvent);\n        });\n\n        // Now that the parent transaction has been committed, the event\n        // on the child transaction should also have been dispatched.\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n        $this->assertTrue(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItDoesNotDispatchAfterCommitEventsImmediatelyIfASiblingTransactionIsCommittedFirst()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            DB::transaction(function () {\n            });\n\n            Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n\n            $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n        });\n\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testChildEventsAreNotDispatchedIfParentTransactionFails()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        try {\n            DB::transaction(function () {\n                DB::transaction(function () {\n                    Event::dispatch(new ShouldDispatchAfterCommitTestEvent);\n                });\n\n                $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n\n                throw new \\Exception;\n            });\n        } catch (\\Exception) {\n            //\n        }\n\n        DB::transaction(fn () => true);\n\n        // Should not have ran because parent transaction failed...\n        $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItHandlesNestedTransactionsWhereTheSecondOneFails()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n        Event::listen(AnotherShouldDispatchAfterCommitTestEvent::class, AnotherShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            DB::transaction(function () {\n                Event::dispatch(new ShouldDispatchAfterCommitTestEvent());\n            });\n\n            try {\n                DB::transaction(function () {\n                    // This event should not be dispatched since the transaction is going to fail.\n                    Event::dispatch(new AnotherShouldDispatchAfterCommitTestEvent);\n                    throw new \\Exception;\n                });\n            } catch (\\Exception $e) {\n            }\n        });\n\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n        $this->assertFalse(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testChildCallbacksShouldNotBeDispatchedIfTheirParentFails()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            try {\n                DB::transaction(function () {\n                    DB::transaction(function () {\n                        Event::dispatch(new ShouldDispatchAfterCommitTestEvent());\n                    });\n\n                    throw new \\Exception;\n                });\n            } catch (\\Exception $e) {\n                //\n            }\n        });\n\n        $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testItHandlesFailuresWithTransactionsTwoLevelsHigher()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n        Event::listen(AnotherShouldDispatchAfterCommitTestEvent::class, AnotherShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () { // lv 1\n            DB::transaction(function () { // lv 2\n                DB::transaction(fn () => Event::dispatch(new ShouldDispatchAfterCommitTestEvent()));\n                // lv 2\n            });\n\n            try {\n                DB::transaction(function () { // lv 2\n                    // This event should not be dispatched since the transaction is going to fail.\n                    Event::dispatch(new AnotherShouldDispatchAfterCommitTestEvent);\n                    throw new \\Exception;\n                });\n            } catch (\\Exception $e) {\n            }\n        });\n\n        $this->assertTrue(ShouldDispatchAfterCommitTestEvent::$ran);\n        $this->assertFalse(AnotherShouldDispatchAfterCommitTestEvent::$ran);\n    }\n\n    public function testCommittedTransactionThatWasDeeplyNestedIsRemovedIfTopLevelFails()\n    {\n        Event::listen(ShouldDispatchAfterCommitTestEvent::class, ShouldDispatchAfterCommitListener::class);\n\n        DB::transaction(function () {\n            try {\n                DB::transaction(function () {\n                    DB::transaction(function () {\n                        DB::transaction(function () {\n                            DB::transaction(fn () => Event::dispatch(new ShouldDispatchAfterCommitTestEvent()));\n                        });\n                    });\n\n                    throw new \\Exception;\n                });\n            } catch (\\Exception $e) {\n            }\n        });\n\n        $this->assertFalse(ShouldDispatchAfterCommitTestEvent::$ran);\n    }\n}\n\nclass TransactionUnawareTestEvent\n{\n    public static $ran = false;\n}\n\nclass ShouldDispatchAfterCommitTestEvent implements ShouldDispatchAfterCommit\n{\n    public static $ran = false;\n}\n\nclass AnotherShouldDispatchAfterCommitTestEvent implements ShouldDispatchAfterCommit\n{\n    public static $ran = false;\n}\n\nclass ShouldDispatchAfterCommitListener\n{\n    public function handle(object $event)\n    {\n        $event::$ran = true;\n    }\n}\n\nclass AnotherShouldDispatchAfterCommitListener\n{\n    public function handle(object $event)\n    {\n        $event::$ran = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Filesystem/FilesystemServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Filesystem;\n\nuse Illuminate\\Filesystem\\FilesystemServiceProvider;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FilesystemServiceProviderTest extends TestCase\n{\n    public function test_it_throws_when_served_disks_have_conflicting_uris(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The [other] disk conflicts with the [local] disk at [/storage]. Each served disk must have a unique URL.');\n\n        config(['filesystems.disks' => [\n            'local' => [\n                'driver' => 'local',\n                'root' => storage_path('app'),\n                'serve' => true,\n            ],\n            'other' => [\n                'driver' => 'local',\n                'root' => storage_path('other'),\n                'serve' => true,\n            ],\n        ]]);\n\n        (new FilesystemServiceProvider($this->app))->boot();\n    }\n\n    public function test_served_disks_with_unique_urls_do_not_conflict(): void\n    {\n        config(['filesystems.disks' => [\n            'local' => [\n                'driver' => 'local',\n                'root' => storage_path('app'),\n                'serve' => true,\n                'url' => '/storage',\n            ],\n            'other' => [\n                'driver' => 'local',\n                'root' => storage_path('other'),\n                'serve' => true,\n                'url' => '/other',\n            ],\n        ]]);\n\n        (new FilesystemServiceProvider($this->app))->boot();\n\n        $this->assertCount(2, $this->app->make('config')->get('filesystems.disks'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Filesystem/FilesystemTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Filesystem;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\File;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse Symfony\\Component\\Process\\Process;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\nclass FilesystemTest extends TestCase\n{\n    protected $stubFile;\n\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            File::put($file = storage_path('app/public/StardewTaylor.png'), File::get(__DIR__.'/Fixtures/StardewTaylor.png'));\n            $this->stubFile = $file;\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            if (File::exists($this->stubFile)) {\n                File::delete($this->stubFile);\n            }\n        });\n\n        parent::setUp();\n    }\n\n    public function testItCanDeleteViaFilesystemShouldUpdatesFileExists()\n    {\n        $this->assertTrue(File::exists($this->stubFile));\n        $this->assertTrue(File::isFile($this->stubFile));\n\n        File::delete($this->stubFile);\n\n        $this->assertFalse(File::exists($this->stubFile));\n    }\n\n    public function testItCanDeleteViaFilesystemRequiresManualClearStatCacheOnFileExistsFromDifferentProcess()\n    {\n        $this->assertTrue(File::exists($this->stubFile));\n        $this->assertTrue(File::isFile($this->stubFile));\n\n        Process::fromShellCommandline(\"rm {$this->stubFile}\")->run();\n\n        clearstatcache(true, $this->stubFile);\n        $this->assertFalse(File::exists($this->stubFile));\n    }\n\n    public function testItCanDeleteViaFilesystemShouldUpdatesIsFile()\n    {\n        $this->assertTrue(File::exists($this->stubFile));\n        $this->assertTrue(File::isFile($this->stubFile));\n\n        File::delete($this->stubFile);\n\n        $this->assertFalse(File::isFile($this->stubFile));\n    }\n\n    public function testItCanDeleteViaFilesystemRequiresManualClearStatCacheOnIsFileFromDifferentProcess()\n    {\n        $this->assertTrue(File::exists($this->stubFile));\n        $this->assertTrue(File::isFile($this->stubFile));\n\n        Process::fromShellCommandline(\"rm {$this->stubFile}\")->run();\n\n        clearstatcache(true, $this->stubFile);\n        $this->assertFalse(File::isFile($this->stubFile));\n    }\n\n    public function testItCanDeleteDirectoryViaFilesystem()\n    {\n        if (! File::exists(storage_path('app/public/testdir'))) {\n            File::makeDirectory(storage_path('app/public/testdir'));\n        }\n\n        $this->assertTrue(File::exists(storage_path('app/public/testdir')));\n\n        File::deleteDirectory(storage_path('app/public/testdir'));\n\n        $this->assertFalse(File::exists(storage_path('app/public/testdir')));\n    }\n\n    public function testSharedGetReadsEntireStreamEvenWhenReadIsPartial(): void\n    {\n        if (! in_array('partialread', stream_get_wrappers(), true)) {\n            stream_wrapper_register('partialread', PartialReadStreamWrapper::class);\n        }\n\n        $payload = str_repeat('a', 10 * 1024); // 10 KiB\n        PartialReadStreamWrapper::setData($payload);\n\n        $fs = new Filesystem();\n\n        $contents = $fs->sharedGet('partialread://test');\n\n        $this->assertSame(strlen($payload), strlen($contents));\n        $this->assertSame($payload, $contents);\n    }\n\n    protected function tearDown(): void\n    {\n        if (in_array('partialread', stream_get_wrappers(), true)) {\n            @stream_wrapper_unregister('partialread');\n        }\n\n        parent::tearDown();\n    }\n}\n\nclass PartialReadStreamWrapper\n{\n    public $context;\n\n    private static string $data = '';\n    private int $pos = 0;\n\n    private static bool $locked = false;\n\n    public static function setData(string $data): void\n    {\n        self::$data = $data;\n    }\n\n    public function stream_open($path, $mode, $options, &$opened_path): bool\n    {\n        $this->pos = 0;\n\n        return true;\n    }\n\n    public function stream_read($count): string\n    {\n        // We emulate the behavior: one read returns a maximum of 8 KiB.\n        $count = min($count, 8192);\n\n        $chunk = substr(self::$data, $this->pos, $count);\n        $this->pos += strlen($chunk);\n\n        return $chunk;\n    }\n\n    public function stream_eof(): bool\n    {\n        return $this->pos >= strlen(self::$data);\n    }\n\n    public function stream_stat(): array\n    {\n        return ['size' => strlen(self::$data)];\n    }\n\n    public function url_stat($path, $flags): array\n    {\n        return ['size' => strlen(self::$data)];\n    }\n\n    /**\n     * Required for flock() support on user-space streams.\n     *\n     * @param  int  $operation  One of LOCK_SH, LOCK_EX, LOCK_UN (+ optional LOCK_NB)\n     * @return bool\n     */\n    public function stream_lock($operation): bool\n    {\n        // For testing purposes, a “successful” implementation is sufficient.\n        // LOCK_UN — remove, otherwise assume that it is locked.\n        if (($operation & LOCK_UN) === LOCK_UN) {\n            self::$locked = false;\n\n            return true;\n        }\n\n        // Optionally, LOCK_NB can be taken into account, but it is not required here.\n        self::$locked = true;\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Filesystem/ReceiveFileTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Filesystem;\n\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('filesystems.disks.local.serve', true)]\nclass ReceiveFileTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            Storage::delete('receive-file-test.txt');\n        });\n\n        parent::setUp();\n    }\n\n    public function testItCanReceiveAFile()\n    {\n        $result = Storage::temporaryUploadUrl('receive-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $response = $this->call('PUT', $result['url'], [], [], [], [], 'Hello World');\n\n        $response->assertNoContent();\n        Storage::assertExists('receive-file-test.txt', 'Hello World');\n    }\n\n    public function testItWill403OnWrongSignature()\n    {\n        $result = Storage::temporaryUploadUrl('receive-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $url = $result['url'].'c';\n\n        $response = $this->call('PUT', $url, [], [], [], [], 'Hello World');\n\n        $response->assertForbidden();\n        Storage::assertMissing('receive-file-test.txt');\n    }\n\n    public function testItWill403OnExpiredUrl()\n    {\n        $result = Storage::temporaryUploadUrl('receive-file-test.txt', Carbon::now()->subMinutes(1));\n\n        $response = $this->call('PUT', $result['url'], [], [], [], [], 'Hello World');\n\n        $response->assertForbidden();\n        Storage::assertMissing('receive-file-test.txt');\n    }\n\n    public function testDownloadUrlCannotBeUsedForUpload()\n    {\n        Storage::put('receive-file-test.txt', 'Original Content');\n\n        $downloadUrl = Storage::temporaryUrl('receive-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $response = $this->call('PUT', $downloadUrl, [], [], [], [], 'Malicious Content');\n\n        $response->assertForbidden();\n        $this->assertSame('Original Content', Storage::get('receive-file-test.txt'));\n    }\n\n    public function testUploadUrlCannotBeUsedForDownload()\n    {\n        Storage::put('receive-file-test.txt', 'Secret Content');\n\n        $uploadUrl = Storage::temporaryUploadUrl('receive-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $response = $this->get($uploadUrl['url']);\n\n        $response->assertForbidden();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Filesystem/ServeFileTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Filesystem;\n\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('filesystems.disks.local.serve', true)]\nclass ServeFileTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            Storage::put('serve-file-test.txt', 'Hello World');\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            Storage::delete('serve-file-test.txt');\n        });\n\n        parent::setUp();\n    }\n\n    public function testItCanServeAnExistingFile()\n    {\n        $url = Storage::temporaryUrl('serve-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $response = $this->get($url);\n\n        $this->assertEquals('Hello World', $response->streamedContent());\n    }\n\n    public function testItWill404OnMissingFile()\n    {\n        $url = Storage::temporaryUrl('serve-missing-test.txt', Carbon::now()->addMinutes(1));\n\n        $response = $this->get($url);\n\n        $response->assertNotFound();\n    }\n\n    public function testItWill403OnWrongSignature()\n    {\n        $url = Storage::temporaryUrl('serve-file-test.txt', Carbon::now()->addMinutes(1));\n\n        $url = $url.'c';\n\n        $response = $this->get($url);\n\n        $response->assertForbidden();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Filesystem/StorageTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Filesystem;\n\nuse Illuminate\\Support\\Facades\\File;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse Symfony\\Component\\Process\\Process;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\nclass StorageTest extends TestCase\n{\n    protected $stubFile;\n\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            File::put($file = storage_path('app/public/StardewTaylor.png'), File::get(__DIR__.'/Fixtures/StardewTaylor.png'));\n            $this->stubFile = $file;\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            if (File::exists($this->stubFile)) {\n                File::delete($this->stubFile);\n            }\n        });\n\n        parent::setUp();\n    }\n\n    public function testItCanDeleteViaStorage()\n    {\n        Storage::disk('public')->assertExists('StardewTaylor.png');\n        $this->assertTrue(Storage::disk('public')->exists('StardewTaylor.png'));\n\n        Storage::disk('public')->delete('StardewTaylor.png');\n\n        Storage::disk('public')->assertMissing('StardewTaylor.png');\n        $this->assertFalse(Storage::disk('public')->exists('StardewTaylor.png'));\n    }\n\n    public function testItCanDeleteViaFilesystemShouldUpdatesStorage()\n    {\n        Storage::disk('public')->assertExists('StardewTaylor.png');\n        $this->assertTrue(Storage::disk('public')->exists('StardewTaylor.png'));\n\n        File::delete($this->stubFile);\n\n        Storage::disk('public')->assertMissing('StardewTaylor.png');\n        $this->assertFalse(Storage::disk('public')->exists('StardewTaylor.png'));\n    }\n\n    public function testItCanDeleteViaFilesystemRequiresManualClearStatCacheOnStorageFromDifferentProcess()\n    {\n        Storage::disk('public')->assertExists('StardewTaylor.png');\n        $this->assertTrue(Storage::disk('public')->exists('StardewTaylor.png'));\n\n        Process::fromShellCommandline(\"rm {$this->stubFile}\")->run();\n\n        clearstatcache(true, $this->stubFile);\n        Storage::disk('public')->assertMissing('StardewTaylor.png');\n        $this->assertFalse(Storage::disk('public')->exists('StardewTaylor.png'));\n    }\n\n    public function testConditionable()\n    {\n        Storage::disk('public')->assertExists('StardewTaylor.png');\n        $this->assertTrue(Storage::disk('public')->exists('StardewTaylor.png'));\n\n        Storage::disk('public')->when(false)->delete('StardewTaylor.png');\n\n        Storage::disk('public')->assertExists('StardewTaylor.png');\n        $this->assertTrue(Storage::disk('public')->exists('StardewTaylor.png'));\n\n        Storage::disk('public')->when(true)->delete('StardewTaylor.png');\n\n        Storage::disk('public')->assertMissing('StardewTaylor.png');\n        $this->assertFalse(Storage::disk('public')->exists('StardewTaylor.png'));\n    }\n\n    public function testItCanDeleteDirectoryViaStorage()\n    {\n        if (! Storage::disk('public')->exists('testdir')) {\n            Storage::disk('public')->makeDirectory('testdir');\n        }\n\n        Storage::disk('public')->assertExists('testdir');\n        $this->assertTrue(Storage::disk('public')->exists('testdir'));\n\n        Storage::disk('public')->deleteDirectory('testdir');\n\n        Storage::disk('public')->assertMissing('testdir');\n        $this->assertFalse(Storage::disk('public')->exists('testdir'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/CloudTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Illuminate\\Foundation\\Cloud;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CloudTest extends TestCase\n{\n    #[WithConfig('database.connections.pgsql', ['host' => 'test-pooler.pg.laravel.cloud', 'username' => 'test-username', 'password' => 'test-password'])]\n    public function test_it_can_resolve_core_container_aliases()\n    {\n        Cloud::configureUnpooledPostgresConnection($this->app);\n\n        $this->assertEquals([\n            'host' => 'test.pg.laravel.cloud',\n            'username' => 'test-username',\n            'password' => 'test-password',\n        ], $this->app['config']->get('database.connections.pgsql-unpooled'));\n    }\n\n    public function test_it_can_configure_disks()\n    {\n        $_SERVER['LARAVEL_CLOUD_DISK_CONFIG'] = json_encode(\n            [\n                [\n                    'disk' => 'test-disk',\n                    'access_key_id' => 'test-access-key-id',\n                    'access_key_secret' => 'test-access-key-secret',\n                    'bucket' => 'test-bucket',\n                    'url' => 'test-url',\n                    'endpoint' => 'test-endpoint',\n                    'is_default' => false,\n                ],\n                [\n                    'disk' => 'test-disk-2',\n                    'access_key_id' => 'test-access-key-id-2',\n                    'access_key_secret' => 'test-access-key-secret-2',\n                    'bucket' => 'test-bucket-2',\n                    'url' => 'test-url-2',\n                    'endpoint' => 'test-endpoint-2',\n                    'is_default' => true,\n                ],\n            ]\n        );\n\n        Cloud::configureDisks($this->app);\n\n        $this->assertEquals('test-disk-2', $this->app['config']->get('filesystems.default'));\n        $this->assertEquals('test-access-key-id', $this->app['config']->get('filesystems.disks.test-disk.key'));\n\n        unset($_SERVER['LARAVEL_CLOUD_DISK_CONFIG']);\n    }\n\n    public function test_it_respects_log_levels()\n    {\n        if (isset($_SERVER['LOG_LEVEL'])) {\n            $logLevelBackup = $_SERVER['LOG_LEVEL'];\n        }\n\n        $_SERVER['LOG_LEVEL'] = 'notice';\n\n        Cloud::configureCloudLogging($this->app);\n\n        $this->assertEquals('notice', $this->app['config']->get('logging.channels.laravel-cloud-socket.level'));\n\n        unset($_SERVER['LOG_LEVEL']);\n\n        if (isset($logLevelBackup)) {\n            $_SERVER['LOG_LEVEL'] = $logLevelBackup;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Configuration/WithScheduleTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Configuration;\n\nuse Illuminate\\Console\\Scheduling\\ScheduleListCommand;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Carbon;\nuse Orchestra\\Testbench\\TestCase;\n\nclass WithScheduleTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Carbon::setTestNow('2023-01-01');\n        ScheduleListCommand::resolveTerminalWidthUsing(fn () => 80);\n    }\n\n    protected function resolveApplication()\n    {\n        return Application::configure(static::applicationBasePath())\n            ->withSchedule(function ($schedule) {\n                $schedule->command('schedule:clear-cache')->everyMinute();\n            })\n            ->withCommands([__DIR__.'/stubs/console.php'])\n            ->create();\n    }\n\n    public function testDisplaySchedule()\n    {\n        $this->artisan(ScheduleListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain('  0 * * * *  php artisan test:inspire .............. Next Due: 1 hour from now')\n            ->expectsOutputToContain('  * * * * *  php artisan schedule:clear-cache .... Next Due: 1 minute from now');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Configuration/stubs/console.php",
    "content": "<?php\n\nuse Illuminate\\Foundation\\Inspiring;\nuse Illuminate\\Support\\Facades\\Artisan;\n\nArtisan::command('test:inspire', function () {\n    $this->comment(Inspiring::quote());\n})->purpose('Display an inspiring quote')->hourly();\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/AboutCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Testing\\Assert;\nuse Orchestra\\Testbench\\Attributes\\WithEnv;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Orchestra\\Testbench\\remote;\n\nclass AboutCommandTest extends TestCase\n{\n    public function testItCanDisplayAboutCommandAsJson()\n    {\n        $process = remote('about --json', ['APP_ENV' => 'local'])->mustRun();\n\n        tap(json_decode($process->getOutput(), true), function ($output) {\n            Assert::assertArraySubset([\n                'application_name' => 'Laravel',\n                'php_version' => PHP_VERSION,\n                'environment' => 'local',\n                'debug_mode' => true,\n                'url' => 'localhost',\n                'maintenance_mode' => false,\n            ], $output['environment']);\n\n            Assert::assertArraySubset([\n                'config' => false,\n                'events' => false,\n                'routes' => false,\n            ], $output['cache']);\n\n            Assert::assertArraySubset([\n                'broadcasting' => 'log',\n                'cache' => 'database',\n                'database' => 'testing',\n                'logs' => ['single'],\n                'mail' => 'log',\n                'queue' => 'database',\n                'session' => 'cookie',\n            ], $output['drivers']);\n        });\n    }\n\n    #[WithEnv('VIEW_COMPILED_PATH', __DIR__.'/../../View/templates')]\n    public function testItRespectsCustomPathForCompiledViews(): void\n    {\n        $process = remote('about --json', ['APP_ENV' => 'local'])->mustRun();\n\n        tap(json_decode($process->getOutput(), true), static function (array $output) {\n            Assert::assertArraySubset([\n                'views' => true,\n            ], $output['cache']);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/ClosureCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ClosureCommandTest extends TestCase\n{\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        Artisan::command('inspire', function () {\n            $this->comment('We must ship. - Taylor Otwell');\n        })->purpose('Display an inspiring quote');\n    }\n\n    public function testItCanRunClosureCommand()\n    {\n        $this->artisan('inspire')->expectsOutput('We must ship. - Taylor Otwell');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/ConfigCacheCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Tests\\Integration\\Generators\\TestCase;\nuse LogicException;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\n\nclass ConfigCacheCommandTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected $files = [\n        'bootstrap/cache/config.php',\n        'config/testconfig.php',\n    ];\n\n    protected function setUp(): void\n    {\n        $files = new Filesystem;\n\n        $this->afterApplicationCreated(function () use ($files) {\n            $files->ensureDirectoryExists($this->app->configPath());\n        });\n\n        $this->beforeApplicationDestroyed(function () use ($files) {\n            $files->delete($this->app->configPath('testconfig.php'));\n        });\n\n        parent::setUp();\n    }\n\n    public function testConfigurationCanBeCachedSuccessfully()\n    {\n        $files = new Filesystem;\n        $files->put($this->app->configPath('testconfig.php'), <<<'PHP'\n            <?php\n\n            return [\n                'string' => 'value',\n                'number' => 123,\n                'boolean' => true,\n                'array' => ['foo', 'bar'],\n                'from_env' => env('SOMETHING_FROM_ENV', 10),\n                'nested' => [\n                    'key' => 'value',\n                ],\n            ];\n            PHP\n        );\n\n        $this->artisan('config:cache')\n            ->assertSuccessful()\n            ->expectsOutputToContain('Configuration cached successfully');\n\n        $this->assertFileExists($this->app->getCachedConfigPath());\n    }\n\n    public function testConfigurationCacheFailsWithNonSerializableValue()\n    {\n        $files = new Filesystem;\n        $files->put($this->app->configPath('testconfig.php'), <<<'PHP'\n            <?php\n\n            return [\n                'closure' => function () {\n                    return 'test';\n                },\n            ];\n            PHP\n        );\n\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Your configuration files could not be serialized because the value at \"testconfig.closure\" is non-serializable.');\n\n        $this->artisan('config:cache');\n    }\n\n    public function testConfigurationCacheFailsWithNestedNonSerializableValue()\n    {\n        $files = new Filesystem;\n        $files->put($this->app->configPath('testconfig.php'), <<<'PHP'\n            <?php\n\n            return [\n                'nested' => [\n                    'deep' => [\n                        'closure' => function () {\n                            return 'test';\n                        },\n                    ],\n                ],\n            ];\n            PHP\n        );\n\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Your configuration files could not be serialized because the value at \"testconfig.nested.deep.closure\" is non-serializable.');\n\n        $this->artisan('config:cache');\n    }\n\n    public function testConfigurationCacheIsDeletedWhenSerializationFails()\n    {\n        $files = new Filesystem;\n        $files->put($this->app->configPath('testconfig.php'), <<<'PHP'\n            <?php\n\n            return [\n                'closure' => function () {\n                    return 'test';\n                },\n            ];\n            PHP\n        );\n\n        try {\n            $this->artisan('config:cache');\n            $this->fail('should have thrown an exception');\n        } catch (LogicException) {\n            // Expected exception\n        }\n\n        $this->assertFileDoesNotExist($this->app->getCachedConfigPath());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/ConfigPublishCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Foundation\\Bootstrap\\LoadConfiguration;\nuse Illuminate\\Support\\ServiceProvider;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Orchestra\\Testbench\\package_path;\n\nclass ConfigPublishCommandTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected array $files = [\n        'config-stubs/*.php',\n    ];\n\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $files = new Filesystem();\n\n        $this->afterApplicationCreated(function () use ($files) {\n            $files->ensureDirectoryExists($this->app->basePath('config-stubs'));\n        });\n\n        $this->beforeApplicationDestroyed(function () use ($files) {\n            $files->deleteDirectory($this->app->basePath('config-stubs'));\n        });\n\n        parent::setUp();\n    }\n\n    #[\\Override]\n    protected function resolveApplicationConfiguration($app)\n    {\n        $app->instance(LoadConfiguration::class, new LoadConfiguration());\n\n        $app->useConfigPath($app->basePath('config-stubs'));\n\n        $app->dontMergeFrameworkConfiguration();\n\n        parent::resolveApplicationConfiguration($app);\n    }\n\n    public function testItCanPublishConfigFilesWhenConfiguredWithDontMergeFrameworkConfiguration()\n    {\n        $this->artisan('config:publish', ['--all' => true])->assertOk();\n\n        foreach ([\n            'app', 'auth', 'broadcasting', 'cache', 'cors',\n            'database', 'filesystems', 'hashing', 'logging',\n            'mail', 'queue', 'services', 'session', 'view',\n        ] as $file) {\n            $this->assertFilenameExists(\"config-stubs/{$file}.php\");\n            $this->assertStringContainsString(\n                file_get_contents(package_path(['config', \"{$file}.php\"])), file_get_contents(config_path(\"{$file}.php\"))\n            );\n        }\n\n        $this->assertSame(config('app.providers'), ServiceProvider::defaultProviders()->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/OptimizeClearCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Console\\ClosureCommand;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Tests\\Integration\\Generators\\TestCase;\n\nclass OptimizeClearCommandTest extends TestCase\n{\n    protected function getPackageProviders($app): array\n    {\n        return [ServiceProviderWithOptimizeClear::class];\n    }\n\n    public function testCanListenToOptimizingEvent(): void\n    {\n        $this->withoutDeprecationHandling();\n\n        $this->artisan('optimize:clear')\n            ->assertSuccessful()\n            ->expectsOutputToContain('ServiceProviderWithOptimizeClear');\n    }\n\n    public function testCanExcludeCommandsByKey(): void\n    {\n        $this->artisan('optimize:clear', ['--except' => 'my package'])\n            ->assertSuccessful()\n            ->doesntExpectOutputToContain('my package');\n    }\n\n    public function testCanExcludeCommandsByCommand(): void\n    {\n        $this->artisan('optimize:clear', ['--except' => 'my_package:cache'])\n            ->assertSuccessful()\n            ->doesntExpectOutputToContain('my_package:cache');\n    }\n}\n\nclass ServiceProviderWithOptimizeClear extends ServiceProvider\n{\n    public function boot(): void\n    {\n        $this->commands([\n            new ClosureCommand('my_package:clear', fn () => 0),\n        ]);\n\n        $this->optimizes(\n            clear: 'my_package:clear',\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Console/OptimizeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Console;\n\nuse Illuminate\\Foundation\\Console\\ClosureCommand;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Tests\\Integration\\Generators\\TestCase;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\n\nclass OptimizeCommandTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected $files = [\n        'bootstrap/cache/config.php',\n        'bootstrap/cache/events.php',\n        'bootstrap/cache/routes-v7.php',\n    ];\n\n    protected function getPackageProviders($app): array\n    {\n        return [ServiceProviderWithOptimize::class];\n    }\n\n    public function testCanListenToOptimizingEvent(): void\n    {\n        $this->withoutDeprecationHandling();\n\n        $this->artisan('optimize')\n            ->assertSuccessful()\n            ->expectsOutputToContain('my package');\n    }\n\n    public function testCanExcludeCommandsByKey(): void\n    {\n        $this->artisan('optimize', ['--except' => 'my package'])\n            ->assertSuccessful()\n            ->doesntExpectOutputToContain('my package');\n    }\n\n    public function testCanExcludeCommandsByCommand(): void\n    {\n        $this->artisan('optimize', ['--except' => 'my_package:cache'])\n            ->assertSuccessful()\n            ->doesntExpectOutputToContain('my_package:cache');\n    }\n}\n\nclass ServiceProviderWithOptimize extends ServiceProvider\n{\n    public function boot(): void\n    {\n        $this->commands([\n            new ClosureCommand('my_package:cache', fn () => 0),\n        ]);\n\n        $this->optimizes(\n            optimize: 'my_package:cache',\n            key: 'my package',\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/CoreContainerAliasesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Illuminate\\Database\\ConnectionResolverInterface;\nuse Illuminate\\Database\\DatabaseManager;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CoreContainerAliasesTest extends TestCase\n{\n    public function testItCanResolveCoreContainerAliases()\n    {\n        $this->assertInstanceOf(DatabaseManager::class, $this->app->make(ConnectionResolverInterface::class));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/DiscoverEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Illuminate\\Foundation\\Events\\DiscoverEvents;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventOne;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventTwo;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\AbstractListener;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\Listener;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\ListenerInterface;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\UnionListeners\\UnionListener;\nuse Orchestra\\Testbench\\TestCase;\nuse SplFileInfo;\n\nclass DiscoverEventsTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        DiscoverEvents::$guessClassNamesUsingCallback = null;\n\n        parent::tearDown();\n    }\n\n    public function testEventsCanBeDiscovered()\n    {\n        class_alias(Listener::class, 'Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\Listener');\n        class_alias(AbstractListener::class, 'Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\AbstractListener');\n        class_alias(ListenerInterface::class, 'Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners\\ListenerInterface');\n\n        $events = DiscoverEvents::within(__DIR__.'/Fixtures/EventDiscovery/Listeners', getcwd());\n\n        $this->assertEquals([\n            EventOne::class => [\n                Listener::class.'@handle',\n                Listener::class.'@handleEventOne',\n            ],\n            EventTwo::class => [\n                Listener::class.'@handleEventTwo',\n            ],\n        ], $events);\n    }\n\n    public function testUnionEventsCanBeDiscovered()\n    {\n        class_alias(UnionListener::class, 'Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\UnionListeners\\UnionListener');\n\n        $events = DiscoverEvents::within(__DIR__.'/Fixtures/EventDiscovery/UnionListeners', getcwd());\n\n        $this->assertEquals([\n            EventOne::class => [\n                UnionListener::class.'@handle',\n            ],\n            EventTwo::class => [\n                UnionListener::class.'@handle',\n            ],\n        ], $events);\n    }\n\n    public function testMultipleDirectoriesCanBeDiscovered(): void\n    {\n        $events = DiscoverEvents::within([\n            __DIR__.'/Fixtures/EventDiscovery/Listeners',\n            __DIR__.'/Fixtures/EventDiscovery/UnionListeners',\n        ], getcwd());\n\n        $this->assertEquals([\n            EventOne::class => [\n                Listener::class.'@handle',\n                Listener::class.'@handleEventOne',\n                UnionListener::class.'@handle',\n            ],\n            EventTwo::class => [\n                Listener::class.'@handleEventTwo',\n                UnionListener::class.'@handle',\n            ],\n        ], $events);\n    }\n\n    public function testNoExceptionForEmptyDirectories(): void\n    {\n        $events = DiscoverEvents::within([], getcwd());\n\n        $this->assertEquals([], $events);\n    }\n\n    public function testEventsCanBeDiscoveredUsingCustomClassNameGuessing()\n    {\n        DiscoverEvents::guessClassNamesUsing(function (SplFileInfo $file, $basePath) {\n            return (new Stringable($file->getRealPath()))\n                ->after($basePath.DIRECTORY_SEPARATOR)\n                ->before('.php')\n                ->replace(DIRECTORY_SEPARATOR, '\\\\')\n                ->ucfirst()\n                ->prepend('Illuminate\\\\')\n                ->toString();\n        });\n\n        $events = DiscoverEvents::within(__DIR__.'/Fixtures/EventDiscovery/Listeners', getcwd());\n\n        $this->assertEquals([\n            EventOne::class => [\n                Listener::class.'@handle',\n                Listener::class.'@handleEventOne',\n            ],\n            EventTwo::class => [\n                Listener::class.'@handleEventTwo',\n            ],\n        ], $events);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/ExceptionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Auth\\Access\\Response;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Debug\\ShouldntReport;\nuse Illuminate\\Contracts\\Routing\\ResponseFactory as ResponseFactoryContract;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Http\\Client\\RequestException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Routing\\ResponseFactory;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Http;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Facades\\Route;\nuse Monolog\\Handler\\TestHandler;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse Symfony\\Component\\Process\\PhpProcess;\nuse Throwable;\n\nclass ExceptionHandlerTest extends TestCase\n{\n    /**\n     * Resolve application HTTP exception handler.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function resolveApplicationExceptionHandler($app)\n    {\n        $app->singleton('Illuminate\\Contracts\\Debug\\ExceptionHandler', 'Illuminate\\Foundation\\Exceptions\\Handler');\n    }\n\n    public function testItRendersAuthorizationExceptions()\n    {\n        Route::get('test-route', fn () => Response::deny('expected message', 321)->authorize());\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(403)\n            ->assertSeeText('expected message');\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(403)\n            ->assertExactJson([\n                'message' => 'expected message',\n            ]);\n    }\n\n    public function testItDoesntReportExceptionsWithShouldntReportInterface()\n    {\n        Config::set('app.debug', true);\n        $reported = [];\n        $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) {\n            $reported[] = $e;\n        });\n\n        $exception = new class extends \\Exception implements ShouldntReport, Responsable\n        {\n            public function toResponse($request)\n            {\n                return response('shouldnt report', 500);\n            }\n        };\n\n        Route::get('test-route', fn () => throw $exception);\n\n        $this->getJson('test-route')\n            ->assertStatus(500)\n            ->assertSee('shouldnt report');\n\n        $this->assertEquals([], $reported);\n    }\n\n    public function testItRendersAuthorizationExceptionsWithCustomStatusCode()\n    {\n        Route::get('test-route', fn () => Response::deny('expected message', 321)->withStatus(404)->authorize());\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(404)\n            ->assertSeeText('Not Found');\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(404)\n            ->assertExactJson([\n                'message' => 'expected message',\n            ]);\n    }\n\n    public function testItRendersAuthorizationExceptionsWithStatusCodeTextWhenNoMessageIsSet()\n    {\n        Route::get('test-route', fn () => Response::denyWithStatus(404)->authorize());\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(404)\n            ->assertSeeText('Not Found');\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(404)\n            ->assertExactJson([\n                'message' => 'Not Found',\n            ]);\n\n        Route::get('test-route', fn () => Response::denyWithStatus(418)->authorize());\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(418)\n            ->assertSeeText(\"I'm a teapot\", false);\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(418)\n            ->assertExactJson([\n                'message' => \"I'm a teapot\",\n            ]);\n    }\n\n    public function testItRendersAuthorizationExceptionsWithStatusButWithoutResponse()\n    {\n        Route::get('test-route', fn () => throw (new AuthorizationException())->withStatus(418));\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(418)\n            ->assertSeeText(\"I'm a teapot\", false);\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(418)\n            ->assertExactJson([\n                'message' => \"I'm a teapot\",\n            ]);\n    }\n\n    public function testItHasFallbackErrorMessageForUnknownStatusCodes()\n    {\n        Route::get('test-route', fn () => throw (new AuthorizationException())->withStatus(399));\n\n        // HTTP request...\n        $this->get('test-route')\n            ->assertStatus(399)\n            ->assertSeeText('Whoops, looks like something went wrong.');\n\n        // JSON request...\n        $this->getJson('test-route')\n            ->assertStatus(399)\n            ->assertExactJson([\n                'message' => 'Whoops, looks like something went wrong.',\n            ]);\n    }\n\n    public function testItReturns400CodeOnMalformedRequests()\n    {\n        // HTTP request...\n        $this->post('test-route', ['_method' => '__construct'])\n            ->assertStatus(400)\n            ->assertSeeText('Bad Request'); // see https://github.com/symfony/symfony/blob/1d439995eb6d780531b97094ff5fa43e345fc42e/src/Symfony/Component/ErrorHandler/Resources/views/error.html.php#L12\n\n        // JSON request...\n        $this->postJson('test-route', ['_method' => '__construct'])\n            ->assertStatus(400)\n            ->assertExactJson([\n                'message' => 'Bad request.',\n            ]);\n    }\n\n    #[DataProvider('exitCodesProvider')]\n    public function testItReturnsNonZeroExitCodesForUncaughtExceptions($providers, $successful)\n    {\n        $basePath = static::applicationBasePath();\n        $providers = json_encode($providers, true);\n\n        $process = new PhpProcess(<<<EOF\n<?php\n\nrequire 'vendor/autoload.php';\n\n\\$laravel = Orchestra\\Testbench\\Foundation\\Application::create(basePath: '$basePath', options: ['extra' => ['providers' => $providers]]);\n\\$laravel->singleton('Illuminate\\Contracts\\Debug\\ExceptionHandler', 'Illuminate\\Foundation\\Exceptions\\Handler');\n\n\\$kernel = \\$laravel[Illuminate\\Contracts\\Console\\Kernel::class];\n\nreturn \\$kernel->call('throw-exception-command');\nEOF, __DIR__.'/../../../', ['APP_RUNNING_IN_CONSOLE' => true]);\n\n        $process->run();\n\n        $this->assertSame($successful, $process->isSuccessful());\n    }\n\n    public static function exitCodesProvider()\n    {\n        yield 'Throw exception' => [[Fixtures\\Providers\\ThrowUncaughtExceptionServiceProvider::class], false];\n        yield 'Do not throw exception' => [[Fixtures\\Providers\\ThrowExceptionServiceProvider::class], true];\n    }\n\n    public function test_it_handles_malformed_error_views_in_production()\n    {\n        Config::set('view.paths', [__DIR__.'/Fixtures/MalformedErrorViews']);\n        Config::set('app.debug', false);\n        $reported = [];\n        $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) {\n            $reported[] = $e;\n        });\n\n        try {\n            $response = $this->get('foo');\n        } catch (Throwable) {\n            $response ??= null;\n        }\n\n        $this->assertCount(1, $reported);\n        $this->assertSame('Undefined variable $foo (View: '.__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'MalformedErrorViews'.DIRECTORY_SEPARATOR.'errors'.DIRECTORY_SEPARATOR.'404.blade.php)', $reported[0]->getMessage());\n        $this->assertNotNull($response);\n        $response->assertStatus(404);\n    }\n\n    public function test_it_handles_malformed_error_views_in_development()\n    {\n        Config::set('view.paths', [__DIR__.'/Fixtures/MalformedErrorViews']);\n        Config::set('app.debug', true);\n        $reported = [];\n        $this->app[ExceptionHandler::class]->reportable(function (Throwable $e) use (&$reported) {\n            $reported[] = $e;\n        });\n\n        try {\n            $response = $this->get('foo');\n        } catch (Throwable) {\n            $response ??= null;\n        }\n\n        $this->assertCount(1, $reported);\n        $this->assertSame('Undefined variable $foo (View: '.__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'MalformedErrorViews'.DIRECTORY_SEPARATOR.'errors'.DIRECTORY_SEPARATOR.'404.blade.php)', $reported[0]->getMessage());\n        $this->assertNotNull($response);\n        $response->assertStatus(500);\n    }\n\n    public function test_it_use_custom_json_response_factory_in_exception_handler()\n    {\n        $this->app->singleton(ResponseFactoryContract::class, function ($app) {\n            return new class($app['view'], $app['redirect']) extends ResponseFactory\n            {\n                public function json($data = [], $status = 200, array $headers = [], $options = 0)\n                {\n                    $msg = $data['message'] ?? $data['msg'] ?? null;\n                    if ($msg) {\n                        unset($data['message']);\n                        $wrapData = [\n                            'msg' => $msg,\n                            'success' => $status >= 200 && $status < 300,\n                        ] + $data;\n                    } else {\n                        $wrapData = [\n                            'msg' => 'success',\n                            'success' => true,\n                            'data' => $data,\n                        ];\n                    }\n\n                    return new JsonResponse($wrapData, 200, $headers, $options);\n                }\n            };\n        });\n\n        Route::get('test-exception', function () {\n            throw new Exception('Test exception');\n        });\n\n        $response = $this->getJson('test-exception');\n\n        $response->assertStatus(200);\n        $response->assertJson([\n            'msg' => 'Server Error',\n            'success' => false,\n        ]);\n    }\n\n    public function test_it_reports_request_exceptions()\n    {\n        config(['logging.default' => 'test_log']);\n        config(['logging.channels.test_log' => [\n            'driver' => 'monolog',\n            'handler' => TestHandler::class,\n        ]]);\n        Log::setDefaultDriver('test_log');\n        Http::fake([\n            '*' => Http::response('a really long message is being returned', status:500),\n        ]);\n\n        RequestException::truncateAt(8);\n        try {\n            Http::throw()->get('http://laravel.test');\n        } catch (RequestException $requestException) {\n            report($requestException);\n        }\n\n        $recordedLogs = Log::getLogger()->getHandlers()[0]->getRecords();\n        $this->assertCount(1, $recordedLogs);\n        $this->assertStringContainsString('a really (truncated...)', $recordedLogs[0]['message']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Exceptions/RenderBladeFilesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Exceptions\\Renderer;\n\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\nuse function Orchestra\\Testbench\\after_resolving;\nuse function Orchestra\\Testbench\\package_path;\n\n#[WithConfig('app.debug', true)]\nclass RenderBladeFilesTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        after_resolving($app, 'view.engine.resolver', function ($resolver) {\n            $resolver->resolve('blade')->getCompiler()->withoutComponentTags();\n        });\n    }\n\n    public function testFormattedSourceTooltipRendersMultilineSafely(): void\n    {\n        $frame = new class\n        {\n            public function class()\n            {\n                return null;\n            }\n\n            public function operator()\n            {\n                return '';\n            }\n\n            public function callable()\n            {\n                return 'throw';\n            }\n\n            public function source()\n            {\n                return \"Foo::bar(1)\\nAnother line\";\n            }\n        };\n\n        $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/formatted-source.blade.php');\n\n        $html = (string) $this->app['view']->file($path, ['frame' => $frame])->render();\n\n        $this->assertStringContainsString('data-tippy-content=\"', $html);\n        $this->assertStringNotContainsString('<br', $html);\n    }\n\n    public function testQueryTooltipRendersMultilineSafely(): void\n    {\n        $sql = \"SELECT * FROM tests\\nWHERE id = 1\";\n        $queries = [['connectionName' => 'mysql', 'sql' => $sql, 'time' => 1.23]];\n\n        $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/query.blade.php');\n\n        $html = (string) $this->app['view']->file($path, ['queries' => $queries])->render();\n\n        $this->assertStringContainsString('data-tippy-content=\"', $html);\n        $this->assertMatchesRegularExpression('/&lt;br\\s*\\/?&gt;/', $html);\n    }\n\n    public function testRequestHeaderTooltipRendersMultilineSafely(): void\n    {\n        $headers = ['X-Test' => \"A\\nB<script>bad()</script>\"];\n\n        $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/request-header.blade.php');\n\n        $html = (string) $this->app['view']->file($path, ['headers' => $headers])->render();\n\n        $this->assertStringContainsString('data-tippy-content=\"', $html);\n        $this->assertStringNotContainsString('<br', $html);\n        $this->assertStringContainsString('&lt;script&gt;bad()&lt;/script&gt;', $html);\n    }\n\n    public function testRoutingTooltipRendersMultilineSafely(): void\n    {\n        $routing = ['URI' => \"users/1\\nedit\"];\n\n        $path = package_path('src/Illuminate/Foundation/resources/exceptions/renderer/components/routing.blade.php');\n\n        $html = (string) $this->app['view']->file($path, ['routing' => $routing])->render();\n\n        $this->assertStringContainsString('data-tippy-content=\"', $html);\n        $this->assertStringNotContainsString('<br', $html);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Exceptions/RendererTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Exceptions;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Foundation\\ExceptionRenderer;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Listener;\nuse Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer;\nuse Illuminate\\Foundation\\Providers\\FoundationServiceProvider;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass RendererTest extends TestCase\n{\n    protected function defineRoutes($router)\n    {\n        $router->get('failed', fn () => throw new RuntimeException('Bad route!'));\n        $router->get('failed-with-previous', function () {\n            throw new RuntimeException(\n                'First exception', previous: new RuntimeException(\n                    'Second exception', previous: new RuntimeException(\n                        'Third exception'\n                    )\n                )\n            );\n        });\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItCanRenderExceptionPage()\n    {\n        $this->assertTrue($this->app->bound(Renderer::class));\n\n        $this->get('/failed')\n            ->assertInternalServerError()\n            ->assertSee('RuntimeException')\n            ->assertSee('Bad route!');\n    }\n\n    #[WithConfig('app.debug', false)]\n    public function testItCanRenderExceptionPageUsingSymfonyIfRendererIsNotDefined()\n    {\n        config(['app.debug' => true]);\n\n        $this->assertFalse($this->app->bound(Renderer::class));\n\n        $this->get('/failed')\n            ->assertInternalServerError()\n            ->assertSee('RuntimeException')\n            ->assertSee('Bad route!');\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItCanRenderExceptionPageWithRendererWhenDebugEnabled()\n    {\n        $this->app->singleton(ExceptionRenderer::class, function () {\n            return new class() implements ExceptionRenderer\n            {\n                public function render($throwable)\n                {\n                    return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);\n                }\n            };\n        });\n\n        $this->assertTrue($this->app->bound(ExceptionRenderer::class));\n\n        $this->get('/failed')\n            ->assertInternalServerError()\n            ->assertSee('Custom Exception Renderer: Bad route!');\n    }\n\n    #[WithConfig('app.debug', false)]\n    public function testItDoesNotRenderExceptionPageWithRendererWhenDebugDisabled()\n    {\n        $this->app->singleton(ExceptionRenderer::class, function () {\n            return new class() implements ExceptionRenderer\n            {\n                public function render($throwable)\n                {\n                    return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);\n                }\n            };\n        });\n\n        $this->assertTrue($this->app->bound(ExceptionRenderer::class));\n\n        $this->get('/failed')\n            ->assertInternalServerError()\n            ->assertDontSee('Custom Exception Renderer: Bad route!');\n    }\n\n    #[WithConfig('app.debug', false)]\n    public function testItDoesNotRegisterListenersWhenDebugDisabled()\n    {\n        $this->app->forgetInstance(ExceptionRenderer::class);\n        $this->assertFalse($this->app->bound(ExceptionRenderer::class));\n\n        $listener = m::mock(Listener::class);\n        $listener->shouldReceive('registerListeners')->never();\n\n        $this->app->instance(Listener::class, $listener);\n        $this->app->instance(Dispatcher::class, m::mock(Dispatcher::class));\n\n        $provider = $this->app->getProvider(FoundationServiceProvider::class);\n        $provider->boot();\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItDoesNotRegisterListenersWhenRendererBound()\n    {\n        $this->app->singleton(ExceptionRenderer::class, function () {\n            return new class() implements ExceptionRenderer\n            {\n                public function render($throwable)\n                {\n                    return response('Custom Exception Renderer: '.$throwable->getMessage(), 500);\n                }\n            };\n        });\n\n        $this->assertTrue($this->app->bound(ExceptionRenderer::class));\n\n        $listener = m::mock(Listener::class);\n        $listener->shouldReceive('registerListeners')->never();\n\n        $this->app->instance(Listener::class, $listener);\n        $this->app->instance(Dispatcher::class, m::mock(Dispatcher::class));\n\n        $provider = $this->app->getProvider(FoundationServiceProvider::class);\n        $provider->boot();\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItRegistersListenersWhenRendererNotBound()\n    {\n        $this->app->forgetInstance(ExceptionRenderer::class);\n        $this->assertFalse($this->app->bound(ExceptionRenderer::class));\n\n        $listener = m::mock(Listener::class);\n        $listener->shouldReceive('registerListeners')->once();\n\n        $this->app->instance(Listener::class, $listener);\n        $this->app->instance(Dispatcher::class, m::mock(Dispatcher::class));\n\n        $provider = $this->app->getProvider(FoundationServiceProvider::class);\n        $provider->boot();\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItRendersPreviousExceptions()\n    {\n        $this->assertTrue($this->app->bound(Renderer::class));\n\n        $this->get('/failed-with-previous')\n            ->assertInternalServerError()\n            ->assertSeeInOrder([\n                'RuntimeException',\n                'First exception',\n                'Previous exceptions',\n                'Second exception',\n                'Third exception',\n            ]);\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testItExcludesDecorativeAsciiArtInNonBrowserContexts()\n    {\n        $this->get('/failed')\n            ->assertInternalServerError()\n            ->assertSee('RuntimeException')\n            ->assertSee('Bad route!')\n            ->assertDontSee('viewBox=\"0 0 1268 308\"', false);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/Console/ThrowExceptionCommand.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Console;\n\nuse Exception;\nuse Illuminate\\Console\\Command;\n\nclass ThrowExceptionCommand extends Command\n{\n    protected $signature = 'throw-exception-command';\n\n    public function handle()\n    {\n        throw new Exception('Thrown inside ThrowExceptionCommand');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Events/EventOne.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events;\n\nclass EventOne\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Events/EventTwo.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events;\n\nclass EventTwo\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Listeners/AbstractListener.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners;\n\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventOne;\n\nabstract class AbstractListener\n{\n    abstract public function handle(EventOne $event);\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Listeners/Listener.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners;\n\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventOne;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventTwo;\n\nclass Listener\n{\n    public function handle(EventOne $event)\n    {\n        //\n    }\n\n    public function handleEventOne(EventOne $event)\n    {\n        //\n    }\n\n    public function handleEventTwo(EventTwo $event)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Listeners/ListenerInterface.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Listeners;\n\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventOne;\n\ninterface ListenerInterface\n{\n    public function handle(EventOne $event);\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/Listeners/random.js",
    "content": ""
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/EventDiscovery/UnionListeners/UnionListener.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\UnionListeners;\n\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventOne;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\EventDiscovery\\Events\\EventTwo;\n\nclass UnionListener\n{\n    public function handle(EventOne|EventTwo $event)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/Logs/ThrowExceptionLogHandler.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Logs;\n\nuse Exception;\nuse Monolog\\Handler\\AbstractProcessingHandler;\n\nclass ThrowExceptionLogHandler extends AbstractProcessingHandler\n{\n    protected function write(array $record): void\n    {\n        throw new Exception('Thrown inside ThrowExceptionLogHandler');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/MalformedErrorViews/errors/404.blade.php",
    "content": "My custom 404\n<?php $foo();\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/MalformedErrorViews/errors/500.blade.php",
    "content": "My custom 500\n<?php $bar();\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/Providers/ThrowExceptionServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Providers;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Console\\ThrowExceptionCommand;\n\nclass ThrowExceptionServiceProvider extends ServiceProvider\n{\n    public function boot()\n    {\n        Application::starting(function ($artisan) {\n            $artisan->add(new ThrowExceptionCommand);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Fixtures/Providers/ThrowUncaughtExceptionServiceProvider.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Providers;\n\nuse Illuminate\\Console\\Application;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Console\\ThrowExceptionCommand;\nuse Illuminate\\Tests\\Integration\\Foundation\\Fixtures\\Logs\\ThrowExceptionLogHandler;\n\nclass ThrowUncaughtExceptionServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.default', 'throw_exception');\n\n        $config->set('logging.channels.throw_exception', [\n            'driver' => 'monolog',\n            'handler' => ThrowExceptionLogHandler::class,\n        ]);\n    }\n\n    public function boot()\n    {\n        Application::starting(function ($artisan) {\n            $artisan->add(new ThrowExceptionCommand);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/FoundationHelpersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Exception;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FoundationHelpersTest extends TestCase\n{\n    public function testRescue()\n    {\n        $this->assertEquals(\n            'rescued!',\n            rescue(function () {\n                throw new Exception;\n            }, 'rescued!')\n        );\n\n        $this->assertEquals(\n            'rescued!',\n            rescue(function () {\n                throw new Exception;\n            }, function () {\n                return 'rescued!';\n            })\n        );\n\n        $this->assertEquals(\n            'no need to rescue',\n            rescue(function () {\n                return 'no need to rescue';\n            }, 'rescued!')\n        );\n\n        $testClass = new class\n        {\n            public function test(int $a)\n            {\n                return $a;\n            }\n        };\n\n        $this->assertEquals(\n            'rescued!',\n            rescue(function () use ($testClass) {\n                $testClass->test([]);\n            }, 'rescued!')\n        );\n    }\n\n    public function testMixReportsExceptionWhenAssetIsMissingFromManifest()\n    {\n        $handler = new FakeHandler;\n        $this->app->instance(ExceptionHandler::class, $handler);\n        $manifest = $this->makeManifest();\n\n        mix('missing.js');\n\n        $this->assertInstanceOf(Exception::class, $handler->reported[0]);\n        $this->assertSame('Unable to locate Mix file: /missing.js.', $handler->reported[0]->getMessage());\n\n        unlink($manifest);\n    }\n\n    #[WithConfig('app.debug', false)]\n    public function testMixSilentlyFailsWhenAssetIsMissingFromManifestWhenNotInDebugMode()\n    {\n        $manifest = $this->makeManifest();\n\n        $path = mix('missing.js');\n\n        $this->assertSame('/missing.js', $path);\n\n        unlink($manifest);\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testMixThrowsExceptionWhenAssetIsMissingFromManifestWhenInDebugMode()\n    {\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Unable to locate Mix file: /missing.js.');\n\n        $manifest = $this->makeManifest();\n\n        try {\n            mix('missing.js');\n        } catch (Exception $e) {\n            throw $e;\n        } finally { // make sure we can cleanup the file\n            unlink($manifest);\n        }\n    }\n\n    #[WithConfig('app.debug', true)]\n    public function testMixOnlyThrowsAndReportsOneExceptionWhenAssetIsMissingFromManifestWhenInDebugMode()\n    {\n        $handler = new FakeHandler;\n        $this->app->instance(ExceptionHandler::class, $handler);\n\n        $manifest = $this->makeManifest();\n\n        Route::get('test-route', function () {\n            mix('missing.js');\n        });\n\n        $this->get('/test-route');\n\n        $this->assertCount(1, $handler->reported);\n\n        unlink($manifest);\n    }\n\n    public function testFakeReturnsSameInstance()\n    {\n        $this->assertSame(fake(), fake());\n        $this->assertSame(fake(), fake('en_US'));\n        $this->assertSame(fake('en_AU'), fake('en_AU'));\n        $this->assertNotSame(fake('en_US'), fake('en_AU'));\n    }\n\n    public function testFakeUsesLocale()\n    {\n        mt_srand(12345, MT_RAND_PHP);\n\n        // Should fallback to en_US\n        $this->assertSame('Arkansas', fake()->state());\n        $this->assertContains(fake('de_DE')->state(), [\n            'Baden-Württemberg', 'Bayern', 'Berlin', 'Brandenburg', 'Bremen', 'Hamburg', 'Hessen', 'Mecklenburg-Vorpommern', 'Niedersachsen', 'Nordrhein-Westfalen', 'Rheinland-Pfalz', 'Saarland', 'Sachsen', 'Sachsen-Anhalt', 'Schleswig-Holstein', 'Thüringen',\n        ]);\n        $this->assertContains(fake('fr_FR')->region(), [\n            'Auvergne-Rhône-Alpes', 'Bourgogne-Franche-Comté', 'Bretagne', 'Centre-Val de Loire', 'Corse', 'Grand Est', 'Hauts-de-France',\n            'Île-de-France', 'Normandie', 'Nouvelle-Aquitaine', 'Occitanie', 'Pays de la Loire', \"Provence-Alpes-Côte d'Azur\",\n            'Guadeloupe', 'Martinique', 'Guyane', 'La Réunion', 'Mayotte',\n        ]);\n\n        config(['app.faker_locale' => 'en_AU']);\n        mt_srand(4, MT_RAND_PHP);\n\n        // Should fallback to en_US\n        $this->assertSame('Australian Capital Territory', fake()->state());\n    }\n\n    protected function makeManifest($directory = '')\n    {\n        app()->usePublicPath(__DIR__);\n\n        $path = public_path(Str::finish($directory, '/').'mix-manifest.json');\n\n        touch($path);\n\n        // Laravel mix prints JSON pretty and with escaped\n        // slashes, so we are doing that here for consistency.\n        $content = json_encode(['/unversioned.css' => '/versioned.css'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);\n\n        file_put_contents($path, $content);\n\n        return $path;\n    }\n}\n\nclass FakeHandler\n{\n    public $reported = [];\n\n    public function report($exception)\n    {\n        $this->reported[] = $exception;\n    }\n\n    public function render($exception)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/FoundationServiceProvidersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Illuminate\\Support\\ServiceProvider;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FoundationServiceProvidersTest extends TestCase\n{\n    protected function getPackageProviders($app)\n    {\n        return [HeadServiceProvider::class];\n    }\n\n    public function testItCanBootServiceProviderRegisteredFromAnotherServiceProvider()\n    {\n        $this->assertTrue($this->app['tail.registered']);\n        $this->assertTrue($this->app['tail.booted']);\n    }\n}\n\nclass HeadServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        //\n    }\n\n    public function boot()\n    {\n        $this->app->register(TailServiceProvider::class);\n    }\n}\n\nclass TailServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        $this->app['tail.registered'] = true;\n    }\n\n    public function boot()\n    {\n        $this->app['tail.booted'] = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/MaintenanceModeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse DateTimeInterface;\nuse Illuminate\\Foundation\\Console\\DownCommand;\nuse Illuminate\\Foundation\\Console\\UpCommand;\nuse Illuminate\\Foundation\\Events\\MaintenanceModeDisabled;\nuse Illuminate\\Foundation\\Events\\MaintenanceModeEnabled;\nuse Illuminate\\Foundation\\Http\\MaintenanceModeBypassCookie;\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\n\nclass MaintenanceModeTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            @unlink(storage_path('framework/down'));\n        });\n\n        parent::setUp();\n    }\n\n    public function testBasicMaintenanceModeResponse()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'refresh' => 60,\n        ]));\n\n        Route::get('/foo', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/foo');\n\n        $response->assertStatus(503);\n        $response->assertHeader('Retry-After', '60');\n        $response->assertHeader('Refresh', '60');\n    }\n\n    public function testMaintenanceModeCanHaveCustomStatus()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'status' => 200,\n        ]));\n\n        Route::get('/foo', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/foo');\n\n        $response->assertStatus(200);\n        $response->assertHeader('Retry-After', '60');\n    }\n\n    public function testMaintenanceModeCanHaveCustomTemplate()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'template' => 'Rendered Content',\n        ]));\n\n        Route::get('/foo', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/foo');\n\n        $response->assertStatus(503);\n        $response->assertHeader('Retry-After', '60');\n        $this->assertSame('Rendered Content', $response->original);\n    }\n\n    public function testMaintenanceModeCanRedirectWithBypassCookie()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'secret' => 'foo',\n            'template' => 'Rendered Content',\n        ]));\n\n        Route::get('/foo', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/foo');\n\n        $response->assertStatus(302);\n        $response->assertCookie('laravel_maintenance');\n    }\n\n    public function testMaintenanceModeCanBeBypassedWithValidCookie()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'secret' => 'foo',\n        ]));\n\n        $cookie = MaintenanceModeBypassCookie::create('foo');\n\n        Route::get('/test', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->withUnencryptedCookies([\n            'laravel_maintenance' => $cookie->getValue(),\n        ])->get('/test');\n\n        $response->assertStatus(200);\n        $this->assertSame('Hello World', $response->original);\n    }\n\n    public function testMaintenanceModeCanBeBypassedOnExcludedUrls()\n    {\n        $this->app->instance(PreventRequestsDuringMaintenance::class, new class($this->app) extends PreventRequestsDuringMaintenance\n        {\n            protected $except = ['/test'];\n        });\n\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n        ]));\n\n        Route::get('/test', fn () => 'Hello World')->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/test');\n\n        $response->assertStatus(200);\n        $this->assertSame('Hello World', $response->original);\n    }\n\n    public function testMaintenanceModeCantBeBypassedWithInvalidCookie()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'secret' => 'foo',\n        ]));\n\n        $cookie = MaintenanceModeBypassCookie::create('test-key');\n\n        Route::get('/test', function () {\n            return 'Hello World';\n        })->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->withUnencryptedCookies([\n            'laravel_maintenance' => $cookie->getValue(),\n        ])->get('/test');\n\n        $response->assertStatus(503);\n    }\n\n    public function testCanCreateBypassCookies()\n    {\n        $cookie = MaintenanceModeBypassCookie::create('test-key');\n\n        $this->assertInstanceOf(Cookie::class, $cookie);\n        $this->assertSame('laravel_maintenance', $cookie->getName());\n\n        $this->assertTrue(MaintenanceModeBypassCookie::isValid($cookie->getValue(), 'test-key'));\n        $this->assertFalse(MaintenanceModeBypassCookie::isValid($cookie->getValue(), 'wrong-key'));\n\n        Carbon::setTestNow(Carbon::now()->addMonths(6));\n        $this->assertFalse(MaintenanceModeBypassCookie::isValid($cookie->getValue(), 'test-key'));\n    }\n\n    public function testDispatchEventWhenMaintenanceModeIsEnabled()\n    {\n        Event::fake();\n\n        Event::assertNotDispatched(MaintenanceModeEnabled::class);\n        $this->artisan(DownCommand::class);\n        Event::assertDispatched(MaintenanceModeEnabled::class);\n    }\n\n    public function testDispatchEventWhenMaintenanceModeIsDisabled()\n    {\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => 60,\n            'refresh' => 60,\n        ]));\n\n        Event::fake();\n\n        Event::assertNotDispatched(MaintenanceModeDisabled::class);\n        $this->artisan(UpCommand::class);\n        Event::assertDispatched(MaintenanceModeDisabled::class);\n    }\n\n    #[DataProvider('retryAfterDatetimeProvider')]\n    public function testMaintenanceModeRetryCanAcceptDatetime(string $datetime): void\n    {\n        Carbon::setTestNow('2023-01-01 00:00:00');\n\n        $this->artisan(DownCommand::class, ['--retry' => $datetime]);\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n\n        $expectedDate = Carbon::parse($datetime)->format(DateTimeInterface::RFC7231);\n        $this->assertSame($expectedDate, $data['retry']);\n\n        Carbon::setTestNow();\n    }\n\n    public static function retryAfterDatetimeProvider(): array\n    {\n        return [\n            'ISO 8601 format' => ['2023-01-08 00:00:00'],\n            'natural language' => ['tomorrow 14:00'],\n            'relative time' => ['+2 hours'],\n        ];\n    }\n\n    public function testMaintenanceModeRetryWithHttpDateHeader(): void\n    {\n        $retryDate = Carbon::now()->addWeek();\n        $expectedHeader = $retryDate->format(DateTimeInterface::RFC7231);\n\n        file_put_contents(storage_path('framework/down'), json_encode([\n            'retry' => $expectedHeader,\n        ]));\n\n        Route::get('/foo', fn () => 'Hello World')->middleware(PreventRequestsDuringMaintenance::class);\n\n        $response = $this->get('/foo');\n\n        $response->assertStatus(503);\n        $response->assertHeader('Retry-After', $expectedHeader);\n    }\n\n    public function testMaintenanceModeRetryWithInvalidDatetimeReturnsNull(): void\n    {\n        $this->artisan(DownCommand::class, ['--retry' => 'not-a-valid-date']);\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n\n        $this->assertNull($data['retry']);\n    }\n\n    public function testMaintenanceModeRetryWithAtTimestampNotation(): void\n    {\n        $futureTimestamp = time() + 3600;\n\n        $this->artisan(DownCommand::class, ['--retry' => '@'.$futureTimestamp]);\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n\n        $expectedDate = Carbon::createFromTimestamp($futureTimestamp)->format(DateTimeInterface::RFC7231);\n        $this->assertSame($expectedDate, $data['retry']);\n    }\n\n    public function testMaintenanceModeCanBeRefreshedWithNewOptions()\n    {\n        $this->artisan(DownCommand::class, ['--retry' => 60])\n            ->expectsOutputToContain('Application is now in maintenance mode.');\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n        $this->assertSame(60, $data['retry']);\n\n        $this->artisan(DownCommand::class, ['--retry' => 120])\n            ->expectsOutputToContain('Maintenance mode options updated.');\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n        $this->assertSame(120, $data['retry']);\n    }\n\n    public function testMaintenanceModeRespectsBootstrapConfiguredExcludedPaths()\n    {\n        PreventRequestsDuringMaintenance::except([\n            '/api/*',\n            '/webhooks/*',\n        ]);\n        $this->artisan(DownCommand::class);\n\n        $data = json_decode(file_get_contents(storage_path('framework/down')), true);\n\n        $this->assertSame([\n            '/api/*',\n            '/webhooks/*',\n        ], $data['except']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/RoutingServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\nuse Psr\\Http\\Message\\ServerRequestInterface;\n\nclass RoutingServiceProviderTest extends TestCase\n{\n    public function testItIncludesMergedDataInServerRequestInterfaceInstancesUsingGetRequests()\n    {\n        Route::get('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        })->middleware(MergeDataMiddleware::class);\n\n        $response = $this->withoutExceptionHandling()->get('test-route?'.http_build_query([\n            'sent' => 'sent-data',\n            'overridden' => 'overridden-sent-data',\n        ]));\n\n        $response->assertOk();\n        $response->assertExactJson([\n            'request-data' => 'request-data',\n        ]);\n    }\n\n    public function testItWorksNormallyWithoutMergeDataMiddlewareWithEmptyRequests()\n    {\n        Route::get('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        });\n\n        $response = $this->withoutExceptionHandling()->get('test-route', [\n            'content-type' => 'application/json',\n        ]);\n\n        $response->assertOk();\n        $response->assertExactJson([]);\n    }\n\n    public function testItIncludesMergedDataInServerRequestInterfaceInstancesUsingGetJsonRequestsWithContentTypeHeader()\n    {\n        Route::get('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        })->middleware(MergeDataMiddleware::class);\n\n        $response = $this->getJson('test-route?'.http_build_query([\n            'sent' => 'sent-data',\n            'overridden' => 'overridden-sent-data',\n        ]), [\n            'content-type' => 'application/json',\n        ]);\n\n        $response->assertOk();\n        $response->assertExactJson([\n            'json-data' => 'json-data',\n            'merged' => 'replaced-merged-data',\n            'overridden' => 'overridden-merged-data',\n            'request-data' => 'request-data',\n        ]);\n    }\n\n    public function testItIncludesMergedDataInServerRequestInterfaceInstancesUsingGetJsonRequests()\n    {\n        Route::get('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        })->middleware(MergeDataMiddleware::class);\n\n        $response = $this->getJson('test-route?'.http_build_query([\n            'sent' => 'sent-data',\n            'overridden' => 'overridden-sent-data',\n        ]));\n\n        $response->assertOk();\n        $response->assertExactJson([\n            'json-data' => 'json-data',\n            'merged' => 'replaced-merged-data',\n            'overridden' => 'overridden-merged-data',\n            'request-data' => 'request-data',\n        ]);\n    }\n\n    public function testItIncludesMergedDataInServerRequestInterfaceInstancesUsingPostRequests()\n    {\n        Route::post('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        })->middleware(MergeDataMiddleware::class);\n\n        $response = $this->post('test-route', [\n            'sent' => 'sent-data',\n            'overridden' => 'overridden-sent-data',\n        ]);\n\n        $response->assertOk();\n        $response->assertExactJson([\n            'sent' => 'sent-data',\n            'merged' => 'replaced-merged-data',\n            'overridden' => 'overridden-merged-data',\n            'request-data' => 'request-data',\n        ]);\n    }\n\n    public function testItIncludesMergedDataInServerRequestInterfaceInstancesUsingPostJsonRequests()\n    {\n        Route::post('test-route', function (ServerRequestInterface $request) {\n            return $request->getParsedBody();\n        })->middleware(MergeDataMiddleware::class);\n\n        $response = $this->postJson('test-route', [\n            'sent' => 'sent-data',\n            'overridden' => 'overridden-sent-data',\n        ]);\n\n        $response->assertOk();\n        $response->assertExactJson([\n            'json-data' => 'json-data',\n            'sent' => 'sent-data',\n            'merged' => 'replaced-merged-data',\n            'overridden' => 'overridden-merged-data',\n            'request-data' => 'request-data',\n        ]);\n    }\n\n    public function testItHandlesGzippedBodyPayloadsWhenCreatingServerRequestInterfaceInstances()\n    {\n        Route::post('test-route', function (ServerRequestInterface $request) {\n            return gzdecode((string) $request->getBody());\n        });\n\n        $response = $this->call('POST', 'test-route', content: file_get_contents(__DIR__.'/Fixtures/laravel.txt.gz'));\n\n        $response->assertOk();\n        $response->assertContent(\"Laravel\\n\");\n    }\n}\n\nclass MergeDataMiddleware\n{\n    public function handle(Request $request, $next)\n    {\n        $request->merge(['merged' => 'first-merged-data']);\n\n        $request->merge(['merged' => 'replaced-merged-data']);\n\n        $request->merge(['overridden' => 'overridden-merged-data']);\n\n        $request->request->set('request-data', 'request-data');\n\n        $request->query->set('query-data', 'query-data');\n\n        $request->json()->set('json-data', 'json-data');\n\n        return $next($request);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Support/Providers/RouteServiceProviderHealthTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Support\\Providers;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('filesystems.disks.local.serve', false)]\nclass RouteServiceProviderHealthTest extends TestCase\n{\n    /**\n     * Resolve application implementation.\n     *\n     * @return \\Illuminate\\Foundation\\Application\n     */\n    protected function resolveApplication()\n    {\n        return Application::configure(static::applicationBasePath())\n            ->withRouting(\n                web: __DIR__.'/fixtures/web.php',\n                health: '/up',\n            )->create();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.key', Str::random(32));\n    }\n\n    public function test_it_can_load_health_page()\n    {\n        $this->get('/up')->assertOk();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Support/Providers/RouteServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Support\\Providers;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Configuration\\Exceptions;\nuse Illuminate\\Foundation\\Configuration\\Middleware;\nuse Illuminate\\Foundation\\Support\\Providers\\RouteServiceProvider;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Testing\\Assert;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('filesystems.disks.local.serve', false)]\nclass RouteServiceProviderTest extends TestCase\n{\n    /**\n     * Resolve application implementation.\n     *\n     * @return \\Illuminate\\Foundation\\Application\n     */\n    protected function resolveApplication()\n    {\n        return Application::configure(static::applicationBasePath())\n            ->withProviders([\n                AppRouteServiceProvider::class,\n            ])\n            ->withRouting(\n                using: function () {\n                    Route::get('login', fn () => 'Login')->name('login');\n                }\n            )\n            ->withMiddleware(function (Middleware $middleware) {\n                //\n            })\n            ->withExceptions(function (Exceptions $exceptions) {\n                //\n            })->create();\n    }\n\n    public function test_it_can_register_multiple_route_service_providers()\n    {\n        Assert::assertArraySubset([\n            RouteServiceProvider::class => true,\n            AppRouteServiceProvider::class => true,\n        ], $this->app->getLoadedProviders());\n    }\n\n    public function test_it_can_uses_routes_registered_using_bootstrap_file()\n    {\n        $this->get(route('login'))\n            ->assertOk()\n            ->assertSee('Login');\n    }\n\n    public function test_it_can_uses_routes_registered_using_configuration_file()\n    {\n        $this->get(route('dashboard'))\n            ->assertOk()\n            ->assertSee('Hello');\n    }\n}\n\nclass AppRouteServiceProvider extends RouteServiceProvider\n{\n    /**\n     * Bootstrap any application services.\n     *\n     * @return void\n     */\n    public function boot()\n    {\n        $this->routes(function () {\n            Route::get('dashboard', fn () => 'Hello')->name('dashboard');\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Support/Providers/fixtures/web.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::get('/{user}', fn () => response('', 404));\n"
  },
  {
    "path": "tests/Integration/Foundation/Testing/Concerns/InteractsWithAuthenticationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass InteractsWithAuthenticationTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('auth.guards.api', [\n            'driver' => 'token',\n            'provider' => 'users',\n            'hash' => false,\n        ]);\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->renameColumn('name', 'username');\n        });\n\n        Schema::table('users', function (Blueprint $table) {\n            $table->tinyInteger('is_active')->default(0);\n        });\n\n        User::forceCreate([\n            'username' => 'taylorotwell',\n            'email' => 'taylorotwell@laravel.com',\n            'password' => bcrypt('password'),\n            'is_active' => true,\n        ]);\n    }\n\n    public function testActingAsIsProperlyHandledForSessionAuth()\n    {\n        Route::get('me', function (Request $request) {\n            return 'Hello '.$request->user()->username;\n        })->middleware(['auth']);\n\n        $user = User::where('username', '=', 'taylorotwell')->first();\n\n        $this->actingAs($user)\n            ->get('/me')\n            ->assertSuccessful()\n            ->assertSeeText('Hello taylorotwell');\n    }\n\n    public function testActingAsIsProperlyHandledForAuthViaRequest()\n    {\n        Route::get('me', function (Request $request) {\n            return 'Hello '.$request->user()->username;\n        })->middleware(['auth:api']);\n\n        Auth::viaRequest('api', function ($request) {\n            return $request->user();\n        });\n\n        $user = User::where('username', '=', 'taylorotwell')->first();\n\n        $this->actingAs($user, 'api')\n            ->get('/me')\n            ->assertSuccessful()\n            ->assertSeeText('Hello taylorotwell');\n    }\n\n    public function testActingAsGuestClearsTheUser()\n    {\n        Route::get('me', function (Request $request) {\n            return 'Hello '.$request->user()->username;\n        })->middleware(['auth']);\n        Route::get('login', function () {\n            return 'Login';\n        })->name('login');\n\n        $user = User::where('username', '=', 'taylorotwell')->first();\n\n        $this->actingAs($user);\n        $this->assertAuthenticated();\n\n        $this->get('/me')\n            ->assertSuccessful()\n            ->assertSeeText('Hello taylorotwell');\n\n        $this->actingAsGuest();\n        $this->assertGuest();\n\n        $this->get('/me')\n            ->assertRedirect(route('login'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Foundation/Testing/Concerns/MakeHttpRequestsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Foundation\\Testing\\Concerns;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Uri;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('app.key', 'base64:IUHRqAQ99pZ0A1MPjbuv1D6ff3jxv0GIvS2qIW4JNU4=')]\nclass MakeHttpRequestsTest extends TestCase\n{\n    /** {@inheritDoc} */\n    protected function defineWebRoutes($router)\n    {\n        $router->get('decode', fn (Request $request) => [\n            'url' => $request->fullUrl(),\n            'query' => $request->query(),\n        ]);\n    }\n\n    public function test_it_can_use_uri_to_make_request()\n    {\n        $this->getJson(Uri::of('decode')->withQuery(['editing' => true, 'editMode' => 'create', 'search' => 'Laravel']))\n            ->assertSuccessful()\n            ->assertJson([\n                'url' => 'http://localhost/decode?editMode=create&editing=1&search=Laravel',\n                'query' => [\n                    'editing' => '1',\n                    'editMode' => 'create',\n                    'search' => 'Laravel',\n                ],\n            ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/CacheTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Cache\\Console\\CacheTableCommand;\n\nclass CacheTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(CacheTableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'cache\\', function (Blueprint $table) {',\n            'Schema::create(\\'cache_locks\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'cache\\');',\n            'Schema::dropIfExists(\\'cache_locks\\');',\n        ], 'create_cache_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/CastMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass CastMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Casts/Foo.php',\n    ];\n\n    public function testItCanGenerateCastFile()\n    {\n        $this->artisan('make:cast', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Casts;',\n            'use Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;',\n            'class Foo implements CastsAttributes',\n            'public function get(Model $model, string $key, mixed $value, array $attributes): mixed',\n            'public function set(Model $model, string $key, mixed $value, array $attributes): mixed',\n        ], 'app/Casts/Foo.php');\n    }\n\n    public function testItCanGenerateInboundCastFile()\n    {\n        $this->artisan('make:cast', ['name' => 'Foo', '--inbound' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Casts;',\n            'use Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes;',\n            'class Foo implements CastsInboundAttributes',\n            'public function set(Model $model, string $key, mixed $value, array $attributes): mixed',\n        ], 'app/Casts/Foo.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ChannelMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ChannelMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Broadcasting/FooChannel.php',\n    ];\n\n    public function testItCanGenerateChannelFile()\n    {\n        $this->artisan('make:channel', ['name' => 'FooChannel'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Broadcasting;',\n            'use Illuminate\\Foundation\\Auth\\User;',\n            'class FooChannel',\n        ], 'app/Broadcasting/FooChannel.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ClassMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ClassMakeCommandTest extends TestCase\n{\n    protected array $files = [\n        'app/Reverb.php',\n        'app/Notification.php',\n    ];\n\n    public function testItCanGenerateClassFile()\n    {\n        $this->artisan('make:class', ['name' => 'Reverb'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'class Reverb',\n            'public function __construct()',\n        ], 'app/Reverb.php');\n    }\n\n    public function testItCanGenerateInvokableClassFile()\n    {\n        $this->artisan('make:class', ['name' => 'Notification', '--invokable' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'class Notification',\n            'public function __construct()',\n            'public function __invoke()',\n        ], 'app/Notification.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ComponentMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ComponentMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/View/Components/Foo.php',\n        'resources/views/components/foo.blade.php',\n        'tests/Feature/View/Components/FooTest.php',\n        'resources/views/custom/path/foo.blade.php',\n        'app/View/Components/Nested/Foo.php',\n        'resources/views/components/nested/foo.blade.php',\n        'tests/Feature/View/Components/Nested/FooTest.php',\n    ];\n\n    public function testItCanGenerateComponentFile()\n    {\n        $this->artisan('make:component', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\View\\Components;',\n            'use Illuminate\\View\\Component;',\n            'class Foo extends Component',\n            \"return view('components.foo');\",\n        ], 'app/View/Components/Foo.php');\n\n        $this->assertFilenameExists('resources/views/components/foo.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/View/Components/FooTest.php');\n    }\n\n    public function testItCanGenerateInlineComponentFile()\n    {\n        $this->artisan('make:component', ['name' => 'Foo', '--inline' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\View\\Components;',\n            'use Illuminate\\View\\Component;',\n            'class Foo extends Component',\n            \"return <<<'blade'\",\n        ], 'app/View/Components/Foo.php');\n\n        $this->assertFilenameNotExists('resources/views/components/foo.blade.php');\n    }\n\n    public function testItCanGenerateComponentFileWithTest()\n    {\n        $this->artisan('make:component', ['name' => 'Foo', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/View/Components/Foo.php');\n        $this->assertFilenameExists('resources/views/components/foo.blade.php');\n        $this->assertFilenameExists('tests/Feature/View/Components/FooTest.php');\n    }\n\n    public function testItCanGenerateComponentFileWithCustomPath()\n    {\n        $this->artisan('make:component', ['name' => 'Foo', '--path' => 'custom/path'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\View\\Components;',\n            'use Illuminate\\View\\Component;',\n            'class Foo extends Component',\n            \"return view('custom.path.foo');\",\n        ], 'app/View/Components/Foo.php');\n\n        $this->assertFilenameExists('resources/views/custom/path/foo.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/View/Components/FooTest.php');\n    }\n\n    public function testItCanGenerateNestedComponentFile()\n    {\n        $this->artisan('make:component', ['name' => 'Nested/Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\View\\Components\\Nested;',\n            'use Illuminate\\View\\Component;',\n            'class Foo extends Component',\n            \"return view('components.nested.foo');\",\n        ], 'app/View/Components/Nested/Foo.php');\n\n        $this->assertFilenameExists('resources/views/components/nested/foo.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/View/Components/Nested/FooTest.php');\n    }\n\n    public function testItCanGenerateNestedComponentFileWithCustomPath()\n    {\n        $this->artisan('make:component', ['name' => 'Nested/Foo', '--path' => 'custom/path'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\View\\Components\\Nested;',\n            'use Illuminate\\View\\Component;',\n            'class Foo extends Component',\n            \"return view('custom.path.foo');\",\n        ], 'app/View/Components/Nested/Foo.php');\n\n        $this->assertFilenameExists('resources/views/custom/path/foo.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/View/Components/Nested/FooTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ConsoleMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ConsoleMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Console/Commands/FooCommand.php',\n    ];\n\n    public function testItCanGenerateConsoleFile()\n    {\n        $this->artisan('make:command', ['name' => 'FooCommand'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Console\\Commands;',\n            'use Illuminate\\Console\\Attributes\\Description;',\n            'use Illuminate\\Console\\Attributes\\Signature;',\n            'use Illuminate\\Console\\Command;',\n            \"#[Signature('app:foo-command')]\",\n            \"#[Description('Command description')]\",\n            'class FooCommand extends Command',\n        ], 'app/Console/Commands/FooCommand.php');\n    }\n\n    public function testItCanGenerateConsoleFileWithCommandOption()\n    {\n        $this->artisan('make:command', ['name' => 'FooCommand', '--command' => 'foo:bar'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Console\\Commands;',\n            'use Illuminate\\Console\\Attributes\\Description;',\n            'use Illuminate\\Console\\Attributes\\Signature;',\n            'use Illuminate\\Console\\Command;',\n            \"#[Signature('foo:bar')]\",\n            \"#[Description('Command description')]\",\n            'class FooCommand extends Command',\n        ], 'app/Console/Commands/FooCommand.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ControllerMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ControllerMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Http/Controllers/Controller.php',\n        'app/Http/Controllers/FooController.php',\n        'app/Models/Bar.php',\n        'app/Models/Foo.php',\n        'tests/Feature/Http/Controllers/FooControllerTest.php',\n    ];\n\n    public function testItCanGenerateControllerFile()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFileNotContains([\n            'class FooController extends Controller',\n            'public function __invoke(Request $request)',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFilenameNotExists('tests/Feature/Http/Controllers/FooControllerTest.php');\n    }\n\n    public function testItCanGenerateControllerFileWhenBaseControllerExists()\n    {\n        $this->artisan('make:controller', ['name' => 'Controller'])\n            ->assertExitCode(0);\n\n        $this->artisan('make:controller', ['name' => 'FooController'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class Controller',\n        ], 'app/Http/Controllers/Controller.php');\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController extends Controller',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFilenameNotExists('tests/Feature/Http/Controllers/FooControllerTest.php');\n    }\n\n    public function testItCanGenerateControllerFileWithInvokableTypeOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--type' => 'invokable'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n            'public function __invoke(Request $request)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithInvokableOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--invokable' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n            'public function __invoke(Request $request)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithModelOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Foo'])\n            ->expectsQuestion('A App\\Models\\Foo model does not exist. Do you want to generate it?', false)\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use App\\Models\\Foo;',\n            'public function index()',\n            'public function create()',\n            'public function store(Request $request)',\n            'public function show(Foo $foo)',\n            'public function edit(Foo $foo)',\n            'public function update(Request $request, Foo $foo)',\n            'public function destroy(Foo $foo)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithModelAndParentOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Bar', '--parent' => 'Foo'])\n            ->expectsQuestion('A App\\Models\\Foo model does not exist. Do you want to generate it?', false)\n            ->expectsQuestion('A App\\Models\\Bar model does not exist. Do you want to generate it?', false)\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use App\\Models\\Bar;',\n            'use App\\Models\\Foo;',\n            'public function index(Foo $foo)',\n            'public function create(Foo $foo)',\n            'public function store(Request $request, Foo $foo)',\n            'public function show(Foo $foo, Bar $bar)',\n            'public function edit(Foo $foo, Bar $bar)',\n            'public function update(Request $request, Foo $foo, Bar $bar)',\n            'public function destroy(Foo $foo, Bar $bar)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithApiOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--api' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n            'public function index()',\n            'public function store(Request $request)',\n            'public function update(Request $request, string $id)',\n            'public function destroy(string $id)',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFileNotContains([\n            'public function create()',\n            'public function edit($id)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithInvokableIgnoresApiOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--api' => true, '--invokable' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n            'public function __invoke(Request $request)',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFileNotContains([\n            'public function index()',\n            'public function store(Request $request)',\n            'public function update(Request $request, $id)',\n            'public function destroy($id)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithApiAndModelOption()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Foo', '--api' => true])\n            ->expectsQuestion('A App\\Models\\Foo model does not exist. Do you want to generate it?', false)\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use App\\Models\\Foo;',\n            'public function index()',\n            'public function store(Request $request)',\n            'public function show(Foo $foo)',\n            'public function update(Request $request, Foo $foo)',\n            'public function destroy(Foo $foo)',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFileNotContains([\n            'public function create()',\n            'public function edit(Foo $foo)',\n        ], 'app/Http/Controllers/FooController.php');\n    }\n\n    public function testItCanGenerateControllerFileWithTest()\n    {\n        $this->artisan('make:controller', ['name' => 'FooController', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameExists('tests/Feature/Http/Controllers/FooControllerTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/EnumMakeCommandTest.php",
    "content": "<?php\n\nnamespace Integration\\Generators;\n\nuse Illuminate\\Tests\\Integration\\Generators\\TestCase;\n\nclass EnumMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/IntEnum.php',\n        'app/StatusEnum.php',\n        'app/StringEnum.php',\n        'app/*/OrderStatusEnum.php',\n    ];\n\n    public function testItCanGenerateEnumFile()\n    {\n        $this->artisan('make:enum', ['name' => 'StatusEnum'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'enum StatusEnum',\n        ], 'app/StatusEnum.php');\n    }\n\n    public function testItCanGenerateEnumFileWithString()\n    {\n        $this->artisan('make:enum', ['name' => 'StringEnum', '--string' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'enum StringEnum: string',\n        ], 'app/StringEnum.php');\n    }\n\n    public function testItCanGenerateEnumFileWithInt()\n    {\n        $this->artisan('make:enum', ['name' => 'IntEnum', '--int' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'enum IntEnum: int',\n        ], 'app/IntEnum.php');\n    }\n\n    public function testItCanGenerateEnumFileInEnumsFolder()\n    {\n        $enumsFolderPath = app_path('Enums');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($enumsFolderPath);\n\n        $this->artisan('make:enum', ['name' => 'OrderStatusEnum'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Enums;',\n            'enum OrderStatusEnum',\n        ], 'app/Enums/OrderStatusEnum.php');\n\n        $files->deleteDirectory($enumsFolderPath);\n    }\n\n    public function testItCanGenerateEnumFileInEnumerationsFolder()\n    {\n        $enumerationsFolderPath = app_path('Enumerations');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($enumerationsFolderPath);\n\n        $this->artisan('make:enum', ['name' => 'OrderStatusEnum'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Enumerations;',\n            'enum OrderStatusEnum',\n        ], 'app/Enumerations/OrderStatusEnum.php');\n\n        $files->deleteDirectory($enumerationsFolderPath);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/EventMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass EventMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Events/FooCreated.php',\n    ];\n\n    public function testItCanGenerateEventFile()\n    {\n        $this->artisan('make:event', ['name' => 'FooCreated'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Events;',\n            'class FooCreated',\n        ], 'app/Events/FooCreated.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ExceptionMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ExceptionMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Exceptions/FooException.php',\n    ];\n\n    public function testItCanGenerateExceptionFile()\n    {\n        $this->artisan('make:exception', ['name' => 'FooException'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Exceptions;',\n            'use Exception;',\n            'class FooException extends Exception',\n        ], 'app/Exceptions/FooException.php');\n\n        $this->assertFileNotContains([\n            'public function report()',\n            'public function render($request)',\n        ], 'app/Exceptions/FooException.php');\n    }\n\n    public function testItCanGenerateExceptionFileWithReportOption()\n    {\n        $this->artisan('make:exception', ['name' => 'FooException', '--report' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Exceptions;',\n            'use Exception;',\n            'class FooException extends Exception',\n            'public function report()',\n        ], 'app/Exceptions/FooException.php');\n\n        $this->assertFileNotContains([\n            'public function render($request)',\n        ], 'app/Exceptions/FooException.php');\n    }\n\n    public function testItCanGenerateExceptionFileWithRenderOption()\n    {\n        $this->artisan('make:exception', ['name' => 'FooException', '--render' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Exceptions;',\n            'use Exception;',\n            'class FooException extends Exception',\n            'public function render(Request $request): Response',\n        ], 'app/Exceptions/FooException.php');\n\n        $this->assertFileNotContains([\n            'public function report()',\n        ], 'app/Exceptions/FooException.php');\n    }\n\n    public function testItCanGenerateExceptionFileWithReportAndRenderOption()\n    {\n        $this->artisan('make:exception', ['name' => 'FooException', '--report' => true, '--render' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Exceptions;',\n            'use Exception;',\n            'class FooException extends Exception',\n            'public function render(Request $request): Response',\n            'public function report()',\n        ], 'app/Exceptions/FooException.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/FactoryMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass FactoryMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'database/factories/FooFactory.php',\n    ];\n\n    public function testItCanGenerateFactoryFile()\n    {\n        $this->artisan('make:factory', ['name' => 'FooFactory'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace Database\\Factories;',\n            'use Illuminate\\Database\\Eloquent\\Factories\\Factory;',\n            'class FooFactory extends Factory',\n            'public function definition()',\n        ], 'database/factories/FooFactory.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/InterfaceMakeCommandTest.php",
    "content": "<?php\n\nnamespace Integration\\Generators;\n\nuse Illuminate\\Tests\\Integration\\Generators\\TestCase;\n\nclass InterfaceMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Gateway.php',\n        'app/Contracts/Gateway.php',\n        'app/Interfaces/Gateway.php',\n    ];\n\n    public function testItCanGenerateInterfaceFile()\n    {\n        $this->artisan('make:interface', ['name' => 'Gateway'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'interface Gateway',\n        ], 'app/Gateway.php');\n    }\n\n    public function testItCanGenerateInterfaceFileWhenContractsFolderExists()\n    {\n        $interfacesFolderPath = app_path('Contracts');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($interfacesFolderPath);\n\n        $this->artisan('make:interface', ['name' => 'Gateway'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Contracts;',\n            'interface Gateway',\n        ], 'app/Contracts/Gateway.php');\n\n        $files->deleteDirectory($interfacesFolderPath);\n    }\n\n    public function testItCanGenerateInterfaceFileWhenInterfacesFolderExists()\n    {\n        $interfacesFolderPath = app_path('Interfaces');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($interfacesFolderPath);\n\n        $this->artisan('make:interface', ['name' => 'Gateway'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Interfaces;',\n            'interface Gateway',\n        ], 'app/Interfaces/Gateway.php');\n\n        $files->deleteDirectory($interfacesFolderPath);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/JobMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass JobMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Jobs/FooCreated.php',\n        'tests/Feature/Jobs/FooCreatedTest.php',\n    ];\n\n    public function testItCanGenerateJobFile()\n    {\n        $this->artisan('make:job', ['name' => 'FooCreated'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Jobs;',\n            'use Illuminate\\Contracts\\Queue\\ShouldQueue;',\n            'use Illuminate\\Foundation\\Queue\\Queueable;',\n            'class FooCreated implements ShouldQueue',\n            'use Queueable;',\n        ], 'app/Jobs/FooCreated.php');\n\n        $this->assertFilenameNotExists('tests/Feature/Jobs/FooCreatedTest.php');\n    }\n\n    public function testItCanGenerateSyncJobFile()\n    {\n        $this->artisan('make:job', ['name' => 'FooCreated', '--sync' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Jobs;',\n            'use Illuminate\\Foundation\\Bus\\Dispatchable;',\n            'class FooCreated',\n            'use Dispatchable;',\n        ], 'app/Jobs/FooCreated.php');\n\n        $this->assertFileNotContains([\n            'use Illuminate\\Contracts\\Queue\\ShouldQueue;',\n            'use Illuminate\\Foundation\\Queue\\Queueable;',\n            'use Illuminate\\Queue\\InteractsWithQueue;',\n            'use Illuminate\\Queue\\SerializesModels;',\n        ], 'app/Jobs/FooCreated.php');\n    }\n\n    public function testItCanGenerateJobFileWithTest()\n    {\n        $this->artisan('make:job', ['name' => 'FooCreated', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Jobs/FooCreated.php');\n        $this->assertFilenameExists('tests/Feature/Jobs/FooCreatedTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/JobMiddlewareMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass JobMiddlewareMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Jobs/Middleware/Foo.php',\n        'tests/Feature/Jobs/Middleware/FooTest.php',\n    ];\n\n    public function testItCanGenerateJobFile()\n    {\n        $this->artisan('make:job-middleware', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Jobs\\Middleware;',\n            'class Foo',\n        ], 'app/Jobs/Middleware/Foo.php');\n\n        $this->assertFilenameNotExists('tests/Feature/Jobs/Middleware/FooTest.php');\n    }\n\n    public function testItCanGenerateJobFileWithTest()\n    {\n        $this->artisan('make:job-middleware', ['name' => 'Foo', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Jobs/Middleware/Foo.php');\n        $this->assertFilenameExists('tests/Feature/Jobs/Middleware/FooTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ListenerMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ListenerMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Listeners/FooListener.php',\n        'tests/Feature/Listeners/FooListenerTest.php',\n    ];\n\n    public function testItCanGenerateListenerFile()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'class FooListener',\n            'public function handle(object $event)',\n        ], 'app/Listeners/FooListener.php');\n\n        $this->assertFileNotContains([\n            'class FooListener implements ShouldQueue',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateListenerFileForEvent()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--event' => 'FooListenerCreated'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'use App\\Events\\FooListenerCreated;',\n            'class FooListener',\n            'public function handle(FooListenerCreated $event)',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateListenerFileForIlluminateEvent()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--event' => 'Illuminate\\Auth\\Events\\Login'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'use Illuminate\\Auth\\Events\\Login;',\n            'class FooListener',\n            'public function handle(Login $event)',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateQueuedListenerFile()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--queued' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'use Illuminate\\Contracts\\Queue\\ShouldQueue;',\n            'use Illuminate\\Queue\\InteractsWithQueue;',\n            'class FooListener implements ShouldQueue',\n            'public function handle(object $event)',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateQueuedListenerFileForEvent()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--queued' => true, '--event' => 'FooListenerCreated'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'use App\\Events\\FooListenerCreated;',\n            'use Illuminate\\Contracts\\Queue\\ShouldQueue;',\n            'use Illuminate\\Queue\\InteractsWithQueue;',\n            'class FooListener implements ShouldQueue',\n            'public function handle(FooListenerCreated $event)',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateQueuedListenerFileForIlluminateEvent()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--queued' => true, '--event' => 'Illuminate\\Auth\\Events\\Login'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Listeners;',\n            'use Illuminate\\Auth\\Events\\Login;',\n            'use Illuminate\\Contracts\\Queue\\ShouldQueue;',\n            'use Illuminate\\Queue\\InteractsWithQueue;',\n            'class FooListener implements ShouldQueue',\n            'public function handle(Login $event)',\n        ], 'app/Listeners/FooListener.php');\n    }\n\n    public function testItCanGenerateQueuedListenerFileWithTest()\n    {\n        $this->artisan('make:listener', ['name' => 'FooListener', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Listeners/FooListener.php');\n        $this->assertFilenameExists('tests/Feature/Listeners/FooListenerTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/MailMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass MailMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Mail/*.php',\n        'resources/views/foo-mail.blade.php',\n        'resources/views/mail/*.blade.php',\n        'tests/Feature/Mail/*.php',\n    ];\n\n    public function testItCanGenerateMailFile()\n    {\n        $this->artisan('make:mail', ['name' => 'FooMail'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Mail;',\n            'use Illuminate\\Mail\\Mailable;',\n            'class FooMail extends Mailable',\n        ], 'app/Mail/FooMail.php');\n\n        $this->assertFilenameNotExists('resources/views/foo-mail.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/Mail/FooMailTest.php');\n    }\n\n    public function testItCanGenerateMailFileWithMarkdownOption()\n    {\n        $this->artisan('make:mail', ['name' => 'FooMail', '--markdown' => 'foo-mail'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Mail;',\n            'use Illuminate\\Mail\\Mailable;',\n            'class FooMail extends Mailable',\n            'return new Content(',\n            \"markdown: 'foo-mail',\",\n        ], 'app/Mail/FooMail.php');\n\n        $this->assertFileContains([\n            '<x-mail::message>',\n            '<x-mail::button :url=\"\\'\\'\">',\n            '</x-mail::button>',\n            '</x-mail::message>',\n        ], 'resources/views/foo-mail.blade.php');\n    }\n\n    public function testErrorsWillBeDisplayedWhenMarkdownsAlreadyExist()\n    {\n        $existingMarkdownPath = 'resources/views/existing-markdown.blade.php';\n        $this->app['files']\n            ->put(\n                $this->app->basePath($existingMarkdownPath),\n                '<x-mail::message>My existing markdown</x-mail::message>'\n            );\n        $this->artisan('make:mail', ['name' => 'FooMail', '--markdown' => 'existing-markdown'])\n            ->expectsOutputToContain('already exists.')\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Mail;',\n            'use Illuminate\\Mail\\Mailable;',\n            'class FooMail extends Mailable',\n            'return new Content(',\n            \"markdown: 'existing-markdown',\",\n        ], 'app/Mail/FooMail.php');\n        $this->assertFileContains([\n            '<x-mail::message>',\n            'My existing markdown',\n            '</x-mail::message>',\n        ], $existingMarkdownPath);\n    }\n\n    public function testItCanGenerateMailFileWithViewOption()\n    {\n        $this->artisan('make:mail', ['name' => 'FooMail', '--view' => 'foo-mail'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Mail;',\n            'use Illuminate\\Mail\\Mailable;',\n            'class FooMail extends Mailable',\n            'return new Content(',\n            \"view: 'foo-mail',\",\n        ], 'app/Mail/FooMail.php');\n\n        $this->assertFilenameExists('resources/views/foo-mail.blade.php');\n    }\n\n    public function testErrorsWillBeDisplayedWhenViewsAlreadyExist()\n    {\n        $existingViewPath = 'resources/views/existing-template.blade.php';\n        $this->app['files']\n            ->put(\n                $this->app->basePath($existingViewPath),\n                '<div>My existing template</div>'\n            );\n        $this->artisan('make:mail', ['name' => 'FooMail', '--view' => 'existing-template'])\n            ->expectsOutputToContain('already exists.')\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Mail;',\n            'use Illuminate\\Mail\\Mailable;',\n            'class FooMail extends Mailable',\n            'return new Content(',\n            \"view: 'existing-template',\",\n        ], 'app/Mail/FooMail.php');\n        $this->assertFilenameExists($existingViewPath);\n        $this->assertFileContains([\n            '<div>My existing template</div>',\n        ], $existingViewPath);\n    }\n\n    public function testItCanGenerateMailFileWithTest()\n    {\n        $this->artisan('make:mail', ['name' => 'FooMail', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Mail/FooMail.php');\n        $this->assertFilenameNotExists('resources/views/foo-mail.blade.php');\n        $this->assertFilenameExists('tests/Feature/Mail/FooMailTest.php');\n    }\n\n    public function testItCanGenerateMailWithNoInitialInput()\n    {\n        $this->artisan('make:mail')\n            ->expectsQuestion('What should the mailable be named?', 'FooMail')\n            ->expectsQuestion('Would you like to create a view?', 'none')\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Mail/FooMail.php');\n        $this->assertFilenameDoesNotExists('resources/views/mail/foo-mail.blade.php');\n    }\n\n    public function testItCanGenerateMailWithViewWithNoInitialInput()\n    {\n        $this->artisan('make:mail')\n            ->expectsQuestion('What should the mailable be named?', 'MyFooMail')\n            ->expectsQuestion('Would you like to create a view?', 'view')\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Mail/MyFooMail.php');\n        $this->assertFilenameExists('resources/views/mail/my-foo-mail.blade.php');\n    }\n\n    public function testItCanGenerateMailWithMarkdownViewWithNoInitialInput()\n    {\n        $this->artisan('make:mail')\n            ->expectsQuestion('What should the mailable be named?', 'FooMail')\n            ->expectsQuestion('Would you like to create a view?', 'markdown')\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Mail/FooMail.php');\n        $this->assertFilenameExists('resources/views/mail/foo-mail.blade.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/MiddlewareMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass MiddlewareMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Http/Middleware/Foo.php',\n        'tests/Feature/Http/Middleware/FooTest.php',\n    ];\n\n    public function testItCanGenerateMiddlewareFile()\n    {\n        $this->artisan('make:middleware', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Middleware;',\n            'use Closure;',\n            'use Illuminate\\Http\\Request;',\n            'class Foo',\n            'public function handle(Request $request, Closure $next)',\n            'return $next($request);',\n        ], 'app/Http/Middleware/Foo.php');\n\n        $this->assertFilenameNotExists('tests/Feature/Http/Middleware/FooTest.php');\n    }\n\n    public function testItCanGenerateMiddlewareFile_with_tests()\n    {\n        $this->artisan('make:middleware', ['name' => 'Foo', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Http/Middleware/Foo.php');\n        $this->assertFilenameExists('tests/Feature/Http/Middleware/FooTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/MigrateMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass MigrateMakeCommandTest extends TestCase\n{\n    public function testItCanGenerateMigrationFile()\n    {\n        $this->artisan('make:migration', ['name' => 'AddBarToFoosTable'])\n            ->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::table(\\'foos\\', function (Blueprint $table) {',\n        ], 'add_bar_to_foos_table.php');\n    }\n\n    public function testItCanGenerateMigrationFileWIthTableOption()\n    {\n        $this->artisan('make:migration', ['name' => 'AddBarToFoosTable', '--table' => 'foobar'])\n            ->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::table(\\'foobar\\', function (Blueprint $table) {',\n        ], 'add_bar_to_foos_table.php');\n    }\n\n    public function testItCanGenerateMigrationFileUsingCreateKeyword()\n    {\n        $this->artisan('make:migration', ['name' => 'CreateFoosTable'])\n            ->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'foos\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'foos\\');',\n        ], 'create_foos_table.php');\n    }\n\n    public function testItCanGenerateMigrationFileUsingCreateOption()\n    {\n        $this->artisan('make:migration', ['name' => 'FoosTable', '--create' => 'foobar'])\n            ->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'foobar\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'foobar\\');',\n        ], 'foos_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ModelMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ModelMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Models/Foo.php',\n        'app/Models/Foo/Bar.php',\n        'app/Http/Controllers/FooController.php',\n        'app/Http/Controllers/BarController.php',\n        'database/factories/FooFactory.php',\n        'database/factories/Foo/BarFactory.php',\n        'database/migrations/*_create_foos_table.php',\n        'database/seeders/FooSeeder.php',\n        'tests/Feature/Models/FooTest.php',\n    ];\n\n    public function testItCanGenerateModelFile()\n    {\n        $this->artisan('make:model', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFileDoesNotContains([\n            '{{ factoryImport }}',\n            'use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;',\n            '{{ factory }}',\n            '/** @use HasFactory<\\Database\\Factories\\FooFactory> */',\n            'use HasFactory;',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n        $this->assertFilenameNotExists('tests/Feature/Models/FooTest.php');\n    }\n\n    public function testItCanGenerateModelFileWithPivotOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--pivot' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Relations\\Pivot;',\n            'class Foo extends Pivot',\n        ], 'app/Models/Foo.php');\n    }\n\n    public function testItCanGenerateModelFileWithMorphPivotOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--morph-pivot' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Relations\\MorphPivot;',\n            'class Foo extends MorphPivot',\n        ], 'app/Models/Foo.php');\n    }\n\n    public function testItCanGenerateModelFileWithControllerOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--controller' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class FooController',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFileNotContains([\n            'use App\\Models\\Foo;',\n            'public function index()',\n            'public function create()',\n            'public function store(Request $request)',\n            'public function show(Foo $foo)',\n            'public function edit(Foo $foo)',\n            'public function update(Request $request, Foo $foo)',\n            'public function destroy(Foo $foo)',\n        ], 'app/Http/Controllers/FooController.php');\n\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n    }\n\n    public function testItCanGenerateModelFileWithFactoryOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--factory' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n            '/** @use HasFactory<\\Database\\Factories\\FooFactory> */',\n            'use HasFactory;',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFileNotContains([\n            '{{ factoryImport }}',\n            '{{ factory }}',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n    }\n\n    public function testItCanGenerateModelFileWithFactoryOptionForDeepFolder()\n    {\n        $this->artisan('make:model', ['name' => 'Foo/Bar', '--factory' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models\\Foo;',\n            'use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Bar extends Model',\n            '/** @use HasFactory<\\Database\\Factories\\Foo\\BarFactory> */',\n            'use HasFactory;',\n        ], 'app/Models/Foo/Bar.php');\n\n        $this->assertFileNotContains([\n            '{{ factoryImport }}',\n            '{{ factory }}',\n        ], 'app/Models/Foo/Bar.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/Foo/BarController.php');\n        $this->assertFilenameExists('database/factories/Foo/BarFactory.php');\n        $this->assertFilenameNotExists('database/seeders/Foo/BarSeeder.php');\n    }\n\n    public function testItGeneratesModelWithHasFactoryTraitWhenUsingAllOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--all' => true])\n            ->expectsQuestion('A App\\Models\\Foo model does not exist. Do you want to generate it?', false)\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n            '/** @use HasFactory<\\Database\\Factories\\FooFactory> */',\n            'use HasFactory;',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFileNotContains([\n            '{{ factoryImport }}',\n            '{{ factory }}',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFilenameExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameExists('database/factories/FooFactory.php');\n        $this->assertFilenameExists('database/seeders/FooSeeder.php');\n        $this->assertMigrationFileExists('create_foos_table.php');\n    }\n\n    public function testItCanGenerateModelFileWithMigrationOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--migration' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n        ], 'app/Models/Foo.php');\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'foos\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'foos\\');',\n        ], 'create_foos_table.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n    }\n\n    public function testItCanGenerateModelFileWithSeederption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--seed' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameExists('database/seeders/FooSeeder.php');\n    }\n\n    public function testItCanGenerateNestedModelFileWithControllerOption()\n    {\n        $this->artisan('make:model', ['name' => 'Foo/Bar', '--controller' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models\\Foo;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Bar extends Model',\n        ], 'app/Models/Foo/Bar.php');\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Controllers;',\n            'use Illuminate\\Http\\Request;',\n            'class BarController',\n        ], 'app/Http/Controllers/BarController.php');\n\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n    }\n\n    public function testItCanGenerateModelFileWithTest()\n    {\n        $this->artisan('make:model', ['name' => 'Foo', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Models;',\n            'use Illuminate\\Database\\Eloquent\\Model;',\n            'class Foo extends Model',\n        ], 'app/Models/Foo.php');\n\n        $this->assertFilenameNotExists('app/Http/Controllers/FooController.php');\n        $this->assertFilenameNotExists('database/factories/FooFactory.php');\n        $this->assertFilenameNotExists('database/seeders/FooSeeder.php');\n        $this->assertFilenameExists('tests/Feature/Models/FooTest.php');\n    }\n\n    public function testItAsksForAdditionalComponentsForExistingModel()\n    {\n        $this->artisan('make:model', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->artisan('make:model', ['name' => 'Foo'])\n            ->assertExitCode(0)\n            ->expectsConfirmation('Do you want to generate additional components for the model?', 'yes')\n            ->expectsQuestion('Would you like any of the following?', []);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/NotificationMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass NotificationMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Notifications/FooNotification.php',\n        'resources/views/foo-notification.blade.php',\n        'tests/Feature/Notifications/FooNotificationTest.php',\n    ];\n\n    public function testItCanGenerateNotificationFile()\n    {\n        $this->artisan('make:notification', ['name' => 'FooNotification'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Notifications;',\n            'use Illuminate\\Notifications\\Notification;',\n            'class FooNotification extends Notification',\n            'return (new MailMessage)',\n        ], 'app/Notifications/FooNotification.php');\n\n        $this->assertFilenameNotExists('resources/views/foo-notification.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/Notifications/FooNotificationTest.php');\n    }\n\n    public function testItCanGenerateNotificationFileWithMarkdownOption()\n    {\n        $this->artisan('make:notification', ['name' => 'FooNotification', '--markdown' => 'foo-notification'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Notifications;',\n            'class FooNotification extends Notification',\n            \"return (new MailMessage)->markdown('foo-notification')\",\n        ], 'app/Notifications/FooNotification.php');\n\n        $this->assertFileContains([\n            '<x-mail::message>',\n        ], 'resources/views/foo-notification.blade.php');\n    }\n\n    public function testItCanGenerateNotificationFileWithTest()\n    {\n        $this->artisan('make:notification', ['name' => 'FooNotification', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Notifications/FooNotification.php');\n        $this->assertFilenameNotExists('resources/views/foo-notification.blade.php');\n        $this->assertFilenameExists('tests/Feature/Notifications/FooNotificationTest.php');\n    }\n\n    public function testItCanGenerateNotificationFileWithNotInitialInput()\n    {\n        $this->artisan('make:notification')\n            ->expectsQuestion('What should the notification be named?', 'FooNotification')\n            ->expectsQuestion('Would you like to create a markdown view?', false)\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Notifications/FooNotification.php');\n        $this->assertFileDoesNotExist('resources/views/foo-notification.blade.php');\n    }\n\n    public function testItCanGenerateNotificationFileWithMarkdownTemplateWithNotInitialInput()\n    {\n        $this->artisan('make:notification')\n            ->expectsQuestion('What should the notification be named?', 'FooNotification')\n            ->expectsQuestion('Would you like to create a markdown view?', true)\n            ->expectsQuestion('What should the markdown view be named?', 'foo-notification')\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('app/Notifications/FooNotification.php');\n        $this->assertFilenameExists('resources/views/foo-notification.blade.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/NotificationTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Notifications\\Console\\NotificationTableCommand;\n\nclass NotificationTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(NotificationTableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'notifications\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'notifications\\');',\n        ], 'create_notifications_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ObserverMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ObserverMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Observers/FooObserver.php',\n    ];\n\n    public function testItCanGenerateObserverFile()\n    {\n        $this->artisan('make:observer', ['name' => 'FooObserver'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Observers;',\n            'class FooObserver',\n        ], 'app/Observers/FooObserver.php');\n    }\n\n    public function testItCanGenerateObserverFileWithModel()\n    {\n        $this->artisan('make:observer', ['name' => 'FooObserver', '--model' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Observers;',\n            'use App\\Models\\Foo;',\n            'class FooObserver',\n            'public function created(Foo $foo)',\n            'public function updated(Foo $foo)',\n            'public function deleted(Foo $foo)',\n            'public function restored(Foo $foo)',\n            'public function forceDeleted(Foo $foo)',\n        ], 'app/Observers/FooObserver.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/PolicyMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass PolicyMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Policies/FooPolicy.php',\n    ];\n\n    public function testItCanGeneratePolicyFile()\n    {\n        $this->artisan('make:policy', ['name' => 'FooPolicy'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Policies;',\n            'use Illuminate\\Foundation\\Auth\\User;',\n            'class FooPolicy',\n        ], 'app/Policies/FooPolicy.php');\n    }\n\n    public function testItCanGeneratePolicyFileWithModelOption()\n    {\n        $this->artisan('make:policy', ['name' => 'FooPolicy', '--model' => 'Post'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Policies;',\n            'use App\\Models\\Post;',\n            'use Illuminate\\Foundation\\Auth\\User;',\n            'class FooPolicy',\n            'public function viewAny(User $user)',\n            'public function view(User $user, Post $post)',\n            'public function create(User $user)',\n            'public function update(User $user, Post $post)',\n            'public function delete(User $user, Post $post)',\n            'public function restore(User $user, Post $post)',\n            'public function forceDelete(User $user, Post $post)',\n        ], 'app/Policies/FooPolicy.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ProviderMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ProviderMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Providers/FooServiceProvider.php',\n    ];\n\n    public function testItCanGenerateServiceProviderFile()\n    {\n        $this->artisan('make:provider', ['name' => 'FooServiceProvider'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Providers;',\n            'use Illuminate\\Support\\ServiceProvider;',\n            'class FooServiceProvider extends ServiceProvider',\n            'public function register()',\n            'public function boot()',\n        ], 'app/Providers/FooServiceProvider.php');\n\n        $this->assertEquals(require $this->app->getBootstrapProvidersPath(), [\n            'App\\Providers\\FooServiceProvider',\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/QueueBatchesTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Queue\\Console\\BatchesTableCommand;\n\nclass QueueBatchesTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(BatchesTableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'job_batches\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'job_batches\\');',\n        ], 'create_job_batches_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/QueueFailedTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Queue\\Console\\FailedTableCommand;\n\nclass QueueFailedTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(FailedTableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'failed_jobs\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'failed_jobs\\');',\n        ], 'create_failed_jobs_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/QueueTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Queue\\Console\\TableCommand;\n\nclass QueueTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(TableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'jobs\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'jobs\\');',\n        ], 'create_jobs_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/RequestMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass RequestMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Http/Requests/FooRequest.php',\n    ];\n\n    public function testItCanGenerateRequestFile()\n    {\n        $this->artisan('make:request', ['name' => 'FooRequest'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Requests;',\n            'use Illuminate\\Foundation\\Http\\FormRequest;',\n            'class FooRequest extends FormRequest',\n        ], 'app/Http/Requests/FooRequest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ResourceMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ResourceMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Http/Resources/FooResource.php',\n        'app/Http/Resources/FooResourceCollection.php',\n    ];\n\n    public function testItCanGenerateResourceFile()\n    {\n        $this->artisan('make:resource', ['name' => 'FooResource'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Resources;',\n            'use Illuminate\\Http\\Resources\\Json\\JsonResource;',\n            'class FooResource extends JsonResource',\n        ], 'app/Http/Resources/FooResource.php');\n    }\n\n    public function testItCanGenerateResourceCollectionFile()\n    {\n        $this->artisan('make:resource', ['name' => 'FooResourceCollection', '--collection' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Http\\Resources;',\n            'use Illuminate\\Http\\Resources\\Json\\ResourceCollection;',\n            'class FooResourceCollection extends ResourceCollection',\n        ], 'app/Http/Resources/FooResourceCollection.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/RuleMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass RuleMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'app/Rules/Foo.php',\n    ];\n\n    public function testItCanGenerateRuleFile()\n    {\n        $this->artisan('make:rule', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Rules;',\n            'use Illuminate\\Contracts\\Validation\\ValidationRule;',\n            'class Foo implements ValidationRule',\n        ], 'app/Rules/Foo.php');\n    }\n\n    public function testItCanGenerateInvokableRuleFile()\n    {\n        $this->artisan('make:rule', ['name' => 'Foo'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Rules;',\n            'use Illuminate\\Contracts\\Validation\\ValidationRule;',\n            'class Foo implements ValidationRule',\n            'public function validate(string $attribute, mixed $value, Closure $fail): void',\n        ], 'app/Rules/Foo.php');\n    }\n\n    public function testItCanGenerateImplicitRuleFile()\n    {\n        $this->artisan('make:rule', ['name' => 'Foo', '--implicit' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Rules;',\n            'use Illuminate\\Contracts\\Validation\\ValidationRule;',\n            'class Foo implements ValidationRule',\n            'public $implicit = true;',\n            'public function validate(string $attribute, mixed $value, Closure $fail): void',\n        ], 'app/Rules/Foo.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/SeederMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass SeederMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'database/seeders/FooSeeder.php',\n    ];\n\n    public function testItCanGenerateSeederFile()\n    {\n        $this->artisan('make:seeder', ['name' => 'FooSeeder'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace Database\\Seeders;',\n            'use Illuminate\\Database\\Seeder;',\n            'class FooSeeder extends Seeder',\n            'public function run()',\n        ], 'database/seeders/FooSeeder.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/SessionTableCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Illuminate\\Session\\Console\\SessionTableCommand;\n\nclass SessionTableCommandTest extends TestCase\n{\n    public function testCreateMakesMigration()\n    {\n        $this->artisan(SessionTableCommand::class)->assertExitCode(0);\n\n        $this->assertMigrationFileContains([\n            'use Illuminate\\Database\\Migrations\\Migration;',\n            'return new class extends Migration',\n            'Schema::create(\\'sessions\\', function (Blueprint $table) {',\n            'Schema::dropIfExists(\\'sessions\\');',\n        ], 'create_sessions_table.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/TestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\n\nabstract class TestCase extends \\Orchestra\\Testbench\\TestCase\n{\n    use InteractsWithPublishedFiles;\n}\n"
  },
  {
    "path": "tests/Integration/Generators/TestMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass TestMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'tests/Feature/FooTest.php',\n        'tests/Unit/FooTest.php',\n    ];\n\n    public function testItCanGenerateFeatureTest()\n    {\n        $this->artisan('make:test', ['name' => 'FooTest'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace Tests\\Feature;',\n            'use Illuminate\\Foundation\\Testing\\RefreshDatabase;',\n            'use Illuminate\\Foundation\\Testing\\WithFaker;',\n            'use Tests\\TestCase;',\n            'class FooTest extends TestCase',\n        ], 'tests/Feature/FooTest.php');\n    }\n\n    public function testItCanGenerateUnitTest()\n    {\n        $this->artisan('make:test', ['name' => 'FooTest', '--unit' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace Tests\\Unit;',\n            'use PHPUnit\\Framework\\TestCase;',\n            'class FooTest extends TestCase',\n        ], 'tests/Unit/FooTest.php');\n    }\n\n    public function testItCanGenerateFeatureTestUsingPest()\n    {\n        $this->artisan('make:test', ['name' => 'FooTest', '--pest' => true])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'test(\\'example\\', function () {',\n            '$response = $this->get(\\'/\\');',\n            '$response->assertStatus(200);',\n        ], 'tests/Feature/FooTest.php');\n    }\n\n    public function testItCanGenerateUnitTestUsingPest()\n    {\n        $this->artisan('make:test', ['name' => 'FooTest', '--unit' => true, '--pest' => true])\n            ->assertExitCode(0);\n        $this->assertFileContains([\n            'test(\\'example\\', function () {',\n            'expect(true)->toBeTrue();',\n        ], 'tests/Unit/FooTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/TraitMakeCommandTest.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass TraitMakeCommandTest extends TestCase\n{\n    public function testItCanGenerateTraitFile()\n    {\n        $this->artisan('make:trait', ['name' => 'FooTrait'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App;',\n            'trait FooTrait',\n        ], 'app/FooTrait.php');\n    }\n\n    public function testItCanGenerateTraitFileWhenTraitsFolderExists()\n    {\n        $traitsFolderPath = app_path('Traits');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($traitsFolderPath);\n\n        $this->artisan('make:trait', ['name' => 'FooTrait'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Traits;',\n            'trait FooTrait',\n        ], 'app/Traits/FooTrait.php');\n\n        $files->deleteDirectory($traitsFolderPath);\n    }\n\n    public function testItCanGenerateTraitFileWhenConcernsFolderExists()\n    {\n        $traitsFolderPath = app_path('Concerns');\n\n        /** @var \\Illuminate\\Filesystem\\Filesystem $files */\n        $files = $this->app['files'];\n\n        $files->ensureDirectoryExists($traitsFolderPath);\n\n        $this->artisan('make:trait', ['name' => 'FooTrait'])\n            ->assertExitCode(0);\n\n        $this->assertFileContains([\n            'namespace App\\Concerns;',\n            'trait FooTrait',\n        ], 'app/Concerns/FooTrait.php');\n\n        $files->deleteDirectory($traitsFolderPath);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Generators/ViewMakeCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Generators;\n\nclass ViewMakeCommandTest extends TestCase\n{\n    protected $files = [\n        'resources/views/foo.blade.php',\n        'tests/Feature/View/FooTest.php',\n    ];\n\n    public function testItCanGenerateViewFile()\n    {\n        $this->artisan('make:view', ['name' => 'foo'])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('resources/views/foo.blade.php');\n        $this->assertFilenameNotExists('tests/Feature/View/FooTest.php');\n    }\n\n    public function testItCanGenerateViewFileWithTest()\n    {\n        $this->artisan('make:view', ['name' => 'foo', '--test' => true])\n            ->assertExitCode(0);\n\n        $this->assertFilenameExists('resources/views/foo.blade.php');\n        $this->assertFilenameExists('tests/Feature/View/FooTest.php');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/AnonymousResourceCollectionWithPaginationInformation.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection;\n\nclass AnonymousResourceCollectionWithPaginationInformation extends AnonymousResourceCollection\n{\n    public function paginationInformation($request)\n    {\n        $paginated = $this->resource->toArray();\n\n        return [\n            'current_page' => $paginated['current_page'],\n            'per_page' => $paginated['per_page'],\n            'total' => $paginated['total'],\n            'total_page' => $paginated['last_page'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/Author.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Author extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/AuthorResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass AuthorResource extends JsonResource\n{\n    public function toArray($request)\n    {\n        return ['name' => $this->name];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/AuthorResourceWithOptionalRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass AuthorResourceWithOptionalRelationship extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'name' => $this->name,\n            'posts_count' => $this->whenLoaded('posts', function () {\n                return $this->posts->count().' posts';\n            }, function () {\n                return 'not loaded';\n            }),\n            'latest_post_title' => $this->whenLoaded('posts', function () {\n                return $this->posts->first()?->title ?: 'no posts yet';\n            }, 'not loaded'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/CommentCollection.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass CommentCollection extends ResourceCollection\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/EmptyPostCollectionResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass EmptyPostCollectionResource extends ResourceCollection\n{\n    public $collects = PostResource::class;\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/EmptyPostResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass EmptyPostResource extends PostResource\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/JsonSerializableResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse JsonSerializable;\n\nclass JsonSerializableResource implements JsonSerializable\n{\n    public $resource;\n\n    public function __construct($resource)\n    {\n        $this->resource = $resource;\n    }\n\n    public function jsonSerialize(): array\n    {\n        return [\n            'id' => $this->resource->id,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/ObjectResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass ObjectResource extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'name' => $this->first_name,\n            'age' => $this->age,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/Post.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Post extends Model\n{\n    /**\n     * The attributes that aren't mass assignable.\n     *\n     * @var string[]\n     */\n    protected $guarded = [];\n\n    /**\n     * Return whether the post is published.\n     *\n     * @return bool\n     */\n    public function getIsPublishedAttribute()\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostCollectionResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass PostCollectionResource extends ResourceCollection\n{\n    public $collects = PostResource::class;\n\n    public function toArray($request)\n    {\n        return ['data' => $this->collection];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostCollectionResourceWithPaginationInformation.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass PostCollectionResourceWithPaginationInformation extends ResourceCollection\n{\n    public $collects = PostResource::class;\n\n    public function toArray($request)\n    {\n        return ['data' => $this->collection];\n    }\n\n    public function paginationInformation($request)\n    {\n        $paginated = $this->resource->toArray();\n\n        return [\n            'current_page' => $paginated['current_page'],\n            'per_page' => $paginated['per_page'],\n            'total' => $paginated['total'],\n            'total_page' => $paginated['last_page'],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostModelCollectionResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\n\nclass PostModelCollectionResource extends ResourceCollection\n{\n    public $collects = Post::class;\n\n    public function toArray($request)\n    {\n        return ['data' => $this->collection];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResource extends JsonResource\n{\n    public function toArray($request)\n    {\n        return ['id' => $this->id, 'title' => $this->title, 'custom' => true];\n    }\n\n    public function withResponse($request, $response)\n    {\n        $response->header('X-Resource', 'True');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithAnonymousResourceCollectionWithPaginationInformation.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithAnonymousResourceCollectionWithPaginationInformation extends JsonResource\n{\n    public function toArray($request)\n    {\n        return ['id' => $this->id, 'title' => $this->title, 'custom' => true];\n    }\n\n    /**\n     * Create a new anonymous resource collection.\n     *\n     * @param  mixed  $resource\n     * @return \\Illuminate\\Tests\\Integration\\Http\\Fixtures\\AnonymousResourceCollectionWithPaginationInformation\n     */\n    public static function collection($resource)\n    {\n        return tap(new AnonymousResourceCollectionWithPaginationInformation($resource, static::class), function ($collection) {\n            if (property_exists(static::class, 'preserveKeys')) {\n                $collection->preserveKeys = (new static([]))->preserveKeys === true;\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithExtraData.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithExtraData extends PostResource\n{\n    public function with($request)\n    {\n        return ['foo' => 'bar'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithJsonOptions.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithJsonOptions extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'title' => $this->title,\n            'reading_time' => $this->reading_time,\n        ];\n    }\n\n    public function jsonOptions()\n    {\n        return JSON_PRESERVE_ZERO_FRACTION;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithJsonOptionsAndTypeHints.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithJsonOptionsAndTypeHints extends JsonResource\n{\n    public function __construct(Post $resource)\n    {\n        parent::__construct($resource);\n    }\n\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'title' => $this->title,\n            'reading_time' => $this->reading_time,\n        ];\n    }\n\n    public function jsonOptions()\n    {\n        return JSON_PRESERVE_ZERO_FRACTION;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalAppendedAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithOptionalAppendedAttributes extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'first' => $this->whenAppended('is_published'),\n            'second' => $this->whenAppended('is_published', 'override value'),\n            'third' => $this->whenAppended('is_published', function () {\n                return 'override value';\n            }),\n            'fourth' => $this->whenAppended('is_published', $this->is_published, 'default'),\n            'fifth' => $this->whenAppended('is_published', $this->is_published, function () {\n                return 'default';\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithOptionalAttributes extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->whenNotNull($this->id),\n            'title' => $this->whenNotNull($this->title, 'no title'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalData.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithOptionalData extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'first' => $this->when(false, 'value'),\n            'second' => $this->when(true, 'value'),\n            'third' => $this->when(true, function () {\n                return 'value';\n            }),\n            'fourth' => $this->when(false, 'value', 'default'),\n            'fifth' => $this->when(false, 'value', function () {\n                return 'default';\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalHasAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithOptionalHasAttributes extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'first' => $this->whenHas('is_published'),\n            'second' => $this->whenHas('is_published', 'override value'),\n            'third' => $this->whenHas('is_published', function () {\n                return 'override value';\n            }),\n            'fourth' => $this->whenHas('is_published', $this->is_published, 'default'),\n            'fifth' => $this->whenHas('is_published', $this->is_published, function () {\n                return 'default';\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalMerging.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithOptionalMerging extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            $this->mergeWhen(false, ['first' => 'value']),\n            $this->mergeWhen(true, ['second' => 'value']),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalPivotRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalPivotRelationship extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'subscription' => $this->whenPivotLoaded(Subscription::class, function () {\n                return [\n                    'foo' => 'bar',\n                ];\n            }),\n            'custom_subscription' => $this->whenPivotLoadedAs('accessor', Subscription::class, function () {\n                return [\n                    'foo' => 'bar',\n                ];\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationship.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalRelationship extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'comments' => new CommentCollection($this->whenLoaded('comments')),\n            'author' => new AuthorResource($this->whenLoaded('author')),\n            'author_name' => $this->whenLoaded('author', function () {\n                return $this->author->name;\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipAggregates.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalRelationshipAggregates extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'title' => $this->title,\n            'average_rating' => $this->whenAggregated('comments', 'rating', 'avg'),\n            'minimum_rating' => $this->whenAggregated('comments', 'rating', 'min'),\n            'maximum_rating' => $this->whenAggregated('comments', 'rating', 'max', fn ($avg) => \"$avg ratings\", 'Default Value'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipCounts.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalRelationshipCounts extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'authors' => $this->whenCounted('authors_count'),\n            'favourite_posts' => $this->whenCounted('favouritedPosts'),\n            'comments' => $this->whenCounted('comments', function ($count) {\n                return \"$count comments\";\n            }, 'None'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipExists.php",
    "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalRelationshipExists extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'has_authors' => $this->whenExistsLoaded('authors'),\n            'has_favourited_posts' => $this->whenExistsLoaded('favouritedPosts', fn ($exists) => $exists ? 'Yes' : 'No', 'No'),\n            'comment_exists' => $this->whenExistsLoaded('comments'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithOptionalRelationshipUsingNamedParameters.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithOptionalRelationshipUsingNamedParameters extends PostResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'author' => new AuthorResource($this->whenLoaded('author')),\n            'author_defaulting_to_null' => new AuthorResource($this->whenLoaded('author', default: null)),\n            'author_name' => $this->whenLoaded('author', fn ($author) => $author->name, 'Anonymous'),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithUnlessOptionalData.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass PostResourceWithUnlessOptionalData extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' => $this->id,\n            'first' => $this->unless(false, 'value'),\n            'second' => $this->unless(true, 'value'),\n            'third' => $this->unless(true, function () {\n                return 'value';\n            }),\n            'fourth' => $this->unless(false, 'value', 'default'),\n            'fifth' => $this->unless(false, 'value', function () {\n                return 'default';\n            }),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/PostResourceWithoutWrap.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass PostResourceWithoutWrap extends PostResource\n{\n    public static $wrap = null;\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/ReallyEmptyPostResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass ReallyEmptyPostResource extends JsonResource\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/ResourceWithPreservedKeys.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass ResourceWithPreservedKeys extends PostResource\n{\n    protected $preserveKeys = true;\n\n    public function toArray($request)\n    {\n        return $this->resource;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/SerializablePostResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\n\nclass SerializablePostResource extends JsonResource\n{\n    public function toArray($request)\n    {\n        return new JsonSerializableResource($this);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Fixtures/Subscription.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Fixtures;\n\nclass Subscription\n{\n    //\n}\n"
  },
  {
    "path": "tests/Integration/Http/HttpClientTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Http\\Client\\Events\\RequestSending;\nuse Illuminate\\Http\\Client\\Pool;\nuse Illuminate\\Http\\Client\\Request;\nuse Illuminate\\Http\\Client\\Response;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\Http;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass HttpClientTest extends TestCase\n{\n    public function testGlobalMiddlewarePersistsBeforeWeDispatchEvent(): void\n    {\n        Event::fake();\n        Http::fake();\n\n        Http::globalRequestMiddleware(fn ($request) => $request->withHeader('User-Agent', 'Facade/1.0'));\n\n        Http::get('laravel.com');\n\n        Event::assertDispatched(RequestSending::class, function (RequestSending $event) {\n            return (new Collection($event->request->header('User-Agent')))->contains('Facade/1.0');\n        });\n    }\n\n    public function testGlobalMiddlewarePersistsAfterFacadeFlush(): void\n    {\n        Http::macro('getGlobalMiddleware', fn () => $this->globalMiddleware);\n        Http::globalRequestMiddleware(fn ($request) => $request->withHeader('User-Agent', 'Example Application/1.0'));\n        Http::globalRequestMiddleware(fn ($request) => $request->withHeader('User-Agent', 'Example Application/1.0'));\n\n        $this->assertCount(2, Http::getGlobalMiddleware());\n\n        Facade::clearResolvedInstances();\n\n        $this->assertCount(2, Http::getGlobalMiddleware());\n    }\n\n    public function testPoolCanForwardToUnderlyingPromise()\n    {\n        Http::fake([\n            'https://laravel.com*' => Http::response('Laravel'),\n            'https://forge.laravel.com*' => Http::response('Forge'),\n            'https://nightwatch.laravel.com*' => Http::response('Tim n Jess'),\n        ]);\n\n        $responses = Http::pool(function (Pool $pool) {\n            $pool->as('laravel')->get('https://laravel.com');\n\n            $pool->as('forge')\n                ->get('https://forge.laravel.com')\n                ->then(function (Response $response): int {\n                    return strlen($response->getBody());\n                });\n\n            $pool->as('nightwatch')\n                ->get('https://nightwatch.laravel.com')\n                ->then(fn (): int => 1)\n                ->then(fn ($i): int => $i + 199);\n        }, 3);\n\n        $this->assertInstanceOf(Response::class, $responses['laravel']);\n        $this->assertEquals(5, $responses['forge']);\n        $this->assertEquals(200, $responses['nightwatch']);\n\n        $this->assertCount(3, Http::recorded());\n    }\n\n    public function testForwardsCallsToPromise()\n    {\n        Http::fake(['*' => Http::response('faked response')]);\n\n        $myFakedResponse = null;\n        $r = Http::async()\n            ->get('https://laravel.com')\n            ->then(function (Response $response) use (&$myFakedResponse): string {\n                $myFakedResponse = $response->getBody();\n\n                return 'stub';\n            })\n            ->wait();\n\n        $this->assertEquals('faked response', $myFakedResponse);\n        $this->assertEquals('stub', $r);\n    }\n\n    public function testCanSetRequestAttributes()\n    {\n        Http::fake([\n            '*' => fn (Request $request) => match ($request->attributes()['name'] ?? null) {\n                'first' => Http::response('first response'),\n                'second' => Http::response('second response'),\n                default => Http::response('unnamed')\n            },\n        ]);\n\n        $response1 = Http::withAttributes(['name' => 'first'])->get('https://some-store.myshopify.com/admin/api/2025-10/graphql.json');\n        $response2 = Http::withAttributes(['name' => 'second'])->get('https://some-store.myshopify.com/admin/api/2025-10/graphql.json');\n        $response3 = Http::get('https://some-store.myshopify.com/admin/api/2025-10/graphql.json');\n        $response4 = Http::withAttributes(['name' => 'fourth'])->get('https://some-store.myshopify.com/admin/api/2025-10/graphql.json');\n\n        $this->assertEquals('first response', $response1->body());\n        $this->assertEquals('second response', $response2->body());\n        $this->assertEquals('unnamed', $response3->body());\n        $this->assertEquals('unnamed', $response4->body());\n    }\n\n    public function testAsyncCanHandleThrownException()\n    {\n        Http::fake(\n            ['*' => Http::response(['luke' => 'kuzmish'])]\n        );\n\n        $thrown = new RuntimeException();\n        $actual = Http::async()\n            ->afterResponse(\n                fn (Response $response) => $response->json('luke') === 'kuzmish'\n                    ? throw $thrown\n                    : null\n            )->get('https://cosmastech.com')\n            ->wait();\n\n        $this->assertSame($thrown, $actual);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/JsonResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Support\\Facades\\Route;\nuse JsonSerializable;\nuse Orchestra\\Testbench\\TestCase;\n\nclass JsonResponseTest extends TestCase\n{\n    public function testResponseWithInvalidJsonThrowsException()\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded');\n\n        Route::get('/response', function () {\n            return new JsonResponse(new class implements JsonSerializable\n            {\n                public function jsonSerialize(): string\n                {\n                    return \"\\xB1\\x31\";\n                }\n            });\n        });\n\n        $this->withoutExceptionHandling();\n\n        $this->get('/response');\n    }\n\n    public function testResponseSetDataPassesWithPriorJsonErrors()\n    {\n        $response = new JsonResponse();\n\n        // Trigger json_last_error() to have a non-zero value...\n        json_encode(['a' => acos(2)]);\n\n        $response->setData(new class implements Jsonable\n        {\n            public function toJson($options = 0): string\n            {\n                return '{}';\n            }\n        });\n\n        $this->assertJson($response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Middleware/HandleCorsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Middleware;\n\nuse Illuminate\\Contracts\\Http\\Kernel;\nuse Illuminate\\Foundation\\Validation\\ValidatesRequests;\nuse Illuminate\\Http\\Middleware\\HandleCors;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Router;\nuse Orchestra\\Testbench\\TestCase;\n\nclass HandleCorsTest extends TestCase\n{\n    use ValidatesRequests;\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']['cors'] = [\n            'paths' => ['api/*'],\n            'supports_credentials' => false,\n            'allowed_origins' => ['http://localhost'],\n            'allowed_headers' => ['X-Custom-1', 'X-Custom-2'],\n            'allowed_methods' => ['GET', 'POST'],\n            'exposed_headers' => [],\n            'max_age' => 0,\n        ];\n\n        $kernel = $app->make(Kernel::class);\n        $kernel->prependMiddleware(HandleCors::class);\n    }\n\n    protected function defineRoutes($router)\n    {\n        $this->addWebRoutes($router);\n        $this->addApiRoutes($router);\n    }\n\n    public function testShouldReturnHeaderAssessControlAllowOriginWhenDontHaveHttpOriginOnRequest()\n    {\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testOptionsAllowOriginAllowed()\n    {\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testAllowAllOrigins()\n    {\n        $this->app['config']->set('cors.allowed_origins', ['*']);\n\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://laravel.com',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('*', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testAllowAllOriginsWildcard()\n    {\n        $this->app['config']->set('cors.allowed_origins', ['*.laravel.com']);\n\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://test.laravel.com',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://test.laravel.com', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testOriginsWildcardIncludesNestedSubdomains()\n    {\n        $this->app['config']->set('cors.allowed_origins', ['*.laravel.com']);\n\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://api.service.test.laravel.com',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://api.service.test.laravel.com', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testAllowAllOriginsWildcardNoMatch()\n    {\n        $this->app['config']->set('cors.allowed_origins', ['*.laravel.com']);\n\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://test.symfony.com',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Origin'));\n    }\n\n    public function testOptionsAllowOriginAllowedNonExistingRoute()\n    {\n        $crawler = $this->call('OPTIONS', 'api/pang', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n    }\n\n    public function testOptionsAllowOriginNotAllowed()\n    {\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://otherhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n    }\n\n    public function testAllowMethodAllowed()\n    {\n        $crawler = $this->call('POST', 'web/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Methods'));\n        $this->assertEquals(200, $crawler->getStatusCode());\n\n        $this->assertSame('PONG', $crawler->getContent());\n    }\n\n    public function testAllowMethodNotAllowed()\n    {\n        $crawler = $this->call('POST', 'web/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'PUT',\n        ]);\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Methods'));\n        $this->assertEquals(200, $crawler->getStatusCode());\n    }\n\n    public function testAllowHeaderAllowedOptions()\n    {\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-1, x-custom-2',\n        ]);\n        $this->assertSame('x-custom-1, x-custom-2', $crawler->headers->get('Access-Control-Allow-Headers'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n\n        $this->assertSame('', $crawler->getContent());\n    }\n\n    public function testAllowHeaderAllowedWildcardOptions()\n    {\n        $this->app['config']->set('cors.allowed_headers', ['*']);\n\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-3',\n        ]);\n        $this->assertSame('x-custom-3', $crawler->headers->get('Access-Control-Allow-Headers'));\n        $this->assertEquals(204, $crawler->getStatusCode());\n\n        $this->assertSame('', $crawler->getContent());\n    }\n\n    public function testAllowHeaderNotAllowedOptions()\n    {\n        $crawler = $this->call('OPTIONS', 'api/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-3',\n        ]);\n        $this->assertSame('x-custom-1, x-custom-2', $crawler->headers->get('Access-Control-Allow-Headers'));\n    }\n\n    public function testAllowHeaderAllowed()\n    {\n        $crawler = $this->call('POST', 'web/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-1, x-custom-2',\n        ]);\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Headers'));\n        $this->assertEquals(200, $crawler->getStatusCode());\n\n        $this->assertSame('PONG', $crawler->getContent());\n    }\n\n    public function testAllowHeaderAllowedWildcard()\n    {\n        $this->app['config']->set('cors.allowed_headers', ['*']);\n\n        $crawler = $this->call('POST', 'web/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-3',\n        ]);\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Headers'));\n        $this->assertEquals(200, $crawler->getStatusCode());\n\n        $this->assertSame('PONG', $crawler->getContent());\n    }\n\n    public function testAllowHeaderNotAllowed()\n    {\n        $crawler = $this->call('POST', 'web/ping', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'x-custom-3',\n        ]);\n        $this->assertEquals(null, $crawler->headers->get('Access-Control-Allow-Headers'));\n        $this->assertEquals(200, $crawler->getStatusCode());\n    }\n\n    public function testError()\n    {\n        $crawler = $this->call('POST', 'api/error', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(500, $crawler->getStatusCode());\n    }\n\n    public function testValidationException()\n    {\n        $crawler = $this->call('POST', 'api/validation', [], [], [], [\n            'HTTP_ORIGIN' => 'http://localhost',\n            'HTTP_ACCESS_CONTROL_REQUEST_METHOD' => 'POST',\n        ]);\n        $this->assertSame('http://localhost', $crawler->headers->get('Access-Control-Allow-Origin'));\n        $this->assertEquals(302, $crawler->getStatusCode());\n    }\n\n    protected function addWebRoutes(Router $router)\n    {\n        $router->post('web/ping', [\n            'uses' => function () {\n                return 'PONG';\n            },\n        ]);\n    }\n\n    protected function addApiRoutes(Router $router)\n    {\n        $router->post('api/ping', [\n            'uses' => function () {\n                return 'PONG';\n            },\n        ]);\n\n        $router->put('api/ping', [\n            'uses' => function () {\n                return 'PONG';\n            },\n        ]);\n\n        $router->post('api/error', [\n            'uses' => function () {\n                abort(500);\n            },\n        ]);\n\n        $router->post('api/validation', [\n            'uses' => function (Request $request) {\n                $this->validate($request, [\n                    'name' => 'required',\n                ]);\n\n                return 'ok';\n            },\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Middleware/PreventRequestForgeryExceptStub.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Middleware;\n\nuse Illuminate\\Foundation\\Http\\Middleware\\PreventRequestForgery;\n\nclass PreventRequestForgeryExceptStub extends PreventRequestForgery\n{\n    public function checkInExceptArray($request)\n    {\n        return $this->inExceptArray($request);\n    }\n\n    public function setExcept(array $except)\n    {\n        $this->except = $except;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Middleware/PreventRequestForgeryExceptTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Middleware;\n\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Http\\Request;\nuse Orchestra\\Testbench\\TestCase;\n\nclass PreventRequestForgeryExceptTest extends TestCase\n{\n    private $stub;\n    private $request;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        PreventRequestForgeryExceptStub::except(['/globally/ignored']);\n        $this->stub = new PreventRequestForgeryExceptStub(app(), new Encrypter(Encrypter::generateKey('AES-128-CBC')));\n        $this->request = Request::create('http://example.com/foo/bar', 'POST');\n    }\n\n    public function testItCanExceptPaths()\n    {\n        $this->assertMatchingExcept(['/foo/bar']);\n        $this->assertMatchingExcept(['foo/bar']);\n        $this->assertNonMatchingExcept(['/bar/foo']);\n    }\n\n    public function testPathsCanBeGloballyIgnored()\n    {\n        $this->request = Request::create('http://example.com/globally/ignored', 'POST');\n        $this->assertMatchingExcept(['globally/ignored']);\n    }\n\n    public function testItCanExceptWildcardPaths()\n    {\n        $this->assertMatchingExcept(['/foo/*']);\n        $this->assertNonMatchingExcept(['/bar*']);\n    }\n\n    public function testItCanExceptFullUrlPaths()\n    {\n        $this->assertMatchingExcept(['http://example.com/foo/bar']);\n        $this->assertMatchingExcept(['http://example.com/foo/bar/']);\n\n        $this->assertNonMatchingExcept(['https://example.com/foo/bar/']);\n        $this->assertNonMatchingExcept(['http://foobar.com/']);\n    }\n\n    public function testItCanExceptFullUrlWildcardPaths()\n    {\n        $this->assertMatchingExcept(['http://example.com/*']);\n        $this->assertMatchingExcept(['*example.com*']);\n\n        $this->request = Request::create('https://example.com', 'POST');\n        $this->assertMatchingExcept(['*example.com']);\n    }\n\n    private function assertMatchingExcept(array $except, $bool = true)\n    {\n        $this->assertSame($bool, $this->stub->setExcept($except)->checkInExceptArray($this->request));\n    }\n\n    private function assertNonMatchingExcept(array $except)\n    {\n        $this->assertMatchingExcept($except, false);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/RequestDurationThresholdTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Contracts\\Http\\Kernel;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RequestDurationThresholdTest extends TestCase\n{\n    public function testItCanHandleExceedingRequestDuration()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(CarbonInterval::seconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMilliseconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertTrue($called);\n    }\n\n    public function testItDoesntCallWhenExactlyThresholdDuration()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(CarbonInterval::seconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItProvidesRequestToHandler()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $url = null;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(CarbonInterval::seconds(1), function ($startedAt, $request) use (&$url) {\n            $url = $request->url();\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(2));\n        $kernel->terminate($request, $response);\n\n        $this->assertSame('http://localhost/test-route', $url);\n    }\n\n    public function testUsesTheConfiguredDateTimezone()\n    {\n        Config::set('app.timezone', 'UTC');\n        Route::get('test-route', fn () => 'ok');\n        $kernel = $this->app[Kernel::class];\n        $startedAt = null;\n        $kernel->whenRequestLifecycleIsLongerThan(CarbonInterval::seconds(1), function ($started) use (&$startedAt) {\n            $startedAt = $started;\n        });\n\n        Config::set('app.timezone', 'Australia/Melbourne');\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n        $kernel->handle($request = Request::create('http://localhost/test-route'));\n        Carbon::setTestNow(Carbon::now()->addMinute());\n        $kernel->terminate($request, new Response);\n\n        $this->assertSame('Australia/Melbourne', $startedAt->timezone->getName());\n    }\n\n    public function testItCanExceedThresholdWhenSpecifyingDurationAsMilliseconds()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(1000, function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMilliseconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertTrue($called);\n    }\n\n    public function testItCanStayUnderThresholdWhenSpecifyingDurationAsMilliseconds()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(1000, function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItCanExceedThresholdWhenSpecifyingDurationAsDateTime()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(Carbon::now()->addSeconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1)->addMilliseconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertTrue($called);\n    }\n\n    public function testItCanStayUnderThresholdWhenSpecifyingDurationAsDateTime()\n    {\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n        $called = false;\n        $kernel = $this->app[Kernel::class];\n        $kernel->whenRequestLifecycleIsLongerThan(Carbon::now()->addSeconds(1), function () use (&$called) {\n            $called = true;\n        });\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        $kernel->terminate($request, $response);\n\n        $this->assertFalse($called);\n    }\n\n    public function testItClearsStartTimeAfterHandlingRequest()\n    {\n        $kernel = $this->app[Kernel::class];\n        Route::get('test-route', fn () => 'ok');\n        $request = Request::create('http://localhost/test-route');\n        $response = new Response();\n\n        Carbon::setTestNow(Carbon::now());\n        $kernel->handle($request);\n        $this->assertTrue(Carbon::now()->eq($kernel->requestStartedAt()));\n\n        $kernel->terminate($request, $response);\n        $this->assertNull($kernel->requestStartedAt());\n    }\n\n    public function testItHandlesCallingTerminateWithoutHandle()\n    {\n        $this->app[Kernel::class]->terminate(Request::create('http://localhost/test-route'), new Response);\n\n        // this is a placeholder just to show that the above did not throw an exception.\n        $this->assertTrue(true);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/ResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize;\nuse Illuminate\\Http\\Exceptions\\PostTooLargeException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\ConditionallyLoadsAttributes;\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\nuse Illuminate\\Http\\Resources\\JsonApi\\AnonymousResourceCollection;\nuse Illuminate\\Http\\Resources\\MergeValue;\nuse Illuminate\\Http\\Resources\\MissingValue;\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\Author;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\AuthorResourceWithOptionalRelationship;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\EmptyPostCollectionResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\ObjectResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostCollectionResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostCollectionResourceWithPaginationInformation;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostModelCollectionResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithAnonymousResourceCollectionWithPaginationInformation;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithExtraData;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithJsonOptions;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithJsonOptionsAndTypeHints;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalAppendedAttributes;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalAttributes;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalData;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalHasAttributes;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalMerging;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalPivotRelationship;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalRelationship;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalRelationshipAggregates;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalRelationshipCounts;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalRelationshipExists;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithOptionalRelationshipUsingNamedParameters;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithoutWrap;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\PostResourceWithUnlessOptionalData;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\ReallyEmptyPostResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\ResourceWithPreservedKeys;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\SerializablePostResource;\nuse Illuminate\\Tests\\Integration\\Http\\Fixtures\\Subscription;\nuse LogicException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ResourceTest extends TestCase\n{\n    public function testResourceMayBeConvetedToArray()\n    {\n        $resource = new class((new User)->forceFill(['id' => 1, 'name' => 'Taylor Otwell'])) extends JsonResource\n        {\n            public function toArray(Request $request)\n            {\n                return [\n                    'id' => $this->id,\n                    'name' => $this->name,\n                    'posts' => (new AnonymousResourceCollection([\n                        new Post([\n                            'id' => 5,\n                            'title' => 'Test Title',\n                            'abstract' => 'Test abstract',\n                        ]),\n                        new Post([\n                            'id' => 10,\n                            'title' => 'Another Test Title',\n                            'abstract' => 'Another Test abstract',\n                        ]),\n                    ], PostResource::class)),\n                ];\n            }\n        };\n\n        $request = Request::create('GET', '/users');\n\n        tap($resource->toArray($request), function ($userAsArray) use ($request) {\n            $this->assertSame(1, $userAsArray['id']);\n            $this->assertSame('Taylor Otwell', $userAsArray['name']);\n\n            $this->assertInstanceOf(AnonymousResourceCollection::class, $userAsArray['posts']);\n            $this->assertSame(PostResource::class, $userAsArray['posts']->collects);\n\n            tap($userAsArray['posts']->toArray($request), function ($postsAsArray) {\n                $this->assertIsArray($postsAsArray);\n                $this->assertCount(2, $postsAsArray);\n                $this->assertSame(['id' => 5, 'title' => 'Test Title', 'custom' => true], $postsAsArray[0]);\n                $this->assertSame(['id' => 10, 'title' => 'Another Test Title', 'custom' => true], $postsAsArray[1]);\n            });\n        });\n    }\n\n    public function testResourcesMayBeConvertedToJson()\n    {\n        Route::get('/', function () {\n            return new PostResource(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'abstract' => 'Test abstract',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayBeConvertedToJsonWithToJsonMethod()\n    {\n        $resource = new PostResource(new Post([\n            'id' => 5,\n            'title' => 'Test Title',\n            'abstract' => 'Test abstract',\n        ]));\n\n        $this->assertSame('{\"id\":5,\"title\":\"Test Title\",\"custom\":true}', $resource->toJson());\n    }\n\n    public function testAnObjectsMayBeConvertedToJson()\n    {\n        Route::get('/', function () {\n            return ObjectResource::make(\n                (object) ['first_name' => 'Bob', 'age' => 40]\n            );\n        });\n\n        $this->withoutExceptionHandling()\n            ->get('/', ['Accept' => 'application/json'])\n            ->assertStatus(200)\n            ->assertExactJson([\n                'data' => [\n                    'name' => 'Bob',\n                    'age' => 40,\n                ],\n            ]);\n    }\n\n    public function testArraysWithObjectsMayBeConvertedToJson()\n    {\n        Route::get('/', function () {\n            $objects = [\n                (object) ['first_name' => 'Bob', 'age' => 40],\n                (object) ['first_name' => 'Jack', 'age' => 25],\n            ];\n\n            return ObjectResource::collection($objects);\n        });\n\n        $this->withoutExceptionHandling()\n            ->get('/', ['Accept' => 'application/json'])\n            ->assertStatus(200)\n            ->assertExactJson([\n                'data' => [\n                    ['name' => 'Bob', 'age' => 40],\n                    ['name' => 'Jack', 'age' => 25],\n                ],\n            ]);\n    }\n\n    public function testResourcesMayHaveNoWrap()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithoutWrap(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertJson([\n            'id' => 5,\n            'title' => 'Test Title',\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalValues()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalData(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'second' => 'value',\n                'third' => 'value',\n                'fourth' => 'default',\n                'fifth' => 'default',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalValuesUsingUnless()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithUnlessOptionalData(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/',\n            ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'first' => 'value',\n                'fourth' => 'value',\n                'fifth' => 'value',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalSelectedAttributes()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalAttributes(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'no title',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalHasAttributes()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'is_published' => true,\n            ]);\n\n            return new PostResourceWithOptionalHasAttributes($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/',\n            ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'first' => true,\n                'second' => 'override value',\n                'third' => 'override value',\n                'fourth' => true,\n                'fifth' => true,\n            ],\n        ]);\n    }\n\n    public function testResourcesWithOptionalHasAttributesReturnDefaultValuesAndNotMissingValues()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalHasAttributes(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/',\n            ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'fourth' => 'default',\n                'fifth' => 'default',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalAppendedAttributes()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n            ]);\n\n            $post->append('is_published');\n\n            return new PostResourceWithOptionalAppendedAttributes($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'first' => true,\n                'second' => 'override value',\n                'third' => 'override value',\n                'fourth' => true,\n                'fifth' => true,\n            ],\n        ]);\n    }\n\n    public function testResourcesWithOptionalAppendedAttributesReturnDefaultValuesAndNotMissingValues()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalAppendedAttributes(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'fourth' => 'default',\n                'fifth' => 'default',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalMerges()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalMerging(new Post([\n                'id' => 5,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'second' => 'value',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalRelationships()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalRelationship(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalRelationshipCounts()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]);\n\n            return new PostResourceWithOptionalRelationshipCounts($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'comments' => 'None',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayLoadOptionalRelationshipCounts()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'authors_count' => 2,\n                'comments_count' => 5,\n                'favourited_posts_count' => 1,\n            ]);\n\n            return new PostResourceWithOptionalRelationshipCounts($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'authors' => 2,\n                'favourite_posts' => 1,\n                'comments' => '5 comments',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalRelationshipExists()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithOptionalRelationshipExists(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'has_favourited_posts' => 'No',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayLoadOptionalRelationshipExists()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'authors_exists' => true,\n                'favourited_posts_exists' => true,\n                'comments_exists' => false,\n            ]);\n\n            return new PostResourceWithOptionalRelationshipExists($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'has_authors' => true,\n                'has_favourited_posts' => 'Yes',\n                'comment_exists' => false,\n            ],\n        ]);\n    }\n\n    public function testResourcesMayLoadOptionalRelationships()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]);\n\n            $post->setRelation('author', new Author(['name' => 'jrrmartin']));\n\n            return new PostResourceWithOptionalRelationship($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'author' => ['name' => 'jrrmartin'],\n                'author_name' => 'jrrmartin',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayLoadOptionalRelationshipAggregates()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'comments_avg_rating' => 3.8,\n                'comments_min_rating' => 2,\n                'comments_max_rating' => 5,\n            ]);\n\n            return new PostResourceWithOptionalRelationshipAggregates($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n                'average_rating' => 3.8,\n                'minimum_rating' => 2,\n                'maximum_rating' => '5 ratings',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalRelationshipAggregates()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]);\n\n            return new PostResourceWithOptionalRelationshipAggregates($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n                'maximum_rating' => 'Default Value',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayShowsNullForLoadedRelationshipWithValueNull()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]);\n\n            $post->setRelation('author', null);\n\n            return new PostResourceWithOptionalRelationship($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'author' => null,\n                'author_name' => null,\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalRelationshipsWithDefaultValues()\n    {\n        Route::get('/', function () {\n            return new AuthorResourceWithOptionalRelationship(new Author([\n                'name' => 'jrrmartin',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'name' => 'jrrmartin',\n                'posts_count' => 'not loaded',\n                'latest_post_title' => 'not loaded',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalPivotRelationships()\n    {\n        Route::get('/', function () {\n            $post = new Post(['id' => 5]);\n            $post->setRelation('pivot', new Subscription);\n\n            return new PostResourceWithOptionalPivotRelationship($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'subscription' => [\n                    'foo' => 'bar',\n                ],\n            ],\n        ]);\n    }\n\n    public function testResourceDoesNotThrowErrorWhenUsingEloquentStrictModeAndCheckingOptionalPivotRelationship()\n    {\n        Model::shouldBeStrict(true);\n\n        Route::get('/', function () {\n            $post = new Post(['id' => 5]);\n            (function () {\n                $this->exists = true;\n                $this->wasRecentlyCreated = false;\n            })->bindTo($post)();\n\n            return new PostResourceWithOptionalPivotRelationship($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n            ],\n        ]);\n    }\n\n    public function testWhenLoadedUsingNamedDefaultParameterOnMissingRelation()\n    {\n        Route::get('/', function () {\n            $post = new Post(['id' => 1]);\n\n            return new PostResourceWithOptionalRelationshipUsingNamedParameters($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 1,\n                'author_defaulting_to_null' => null,\n                'author_name' => 'Anonymous',\n            ],\n        ]);\n    }\n\n    public function testWhenLoadedUsingNamedDefaultParameterOnLoadedRelation()\n    {\n        Route::get('/', function () {\n            $post = new Post(['id' => 1]);\n            $post->setRelation('author', new Author(['name' => 'jrrmartin']));\n\n            return new PostResourceWithOptionalRelationshipUsingNamedParameters($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 1,\n                'author' => ['name' => 'jrrmartin'],\n                'author_defaulting_to_null' => ['name' => 'jrrmartin'],\n                'author_name' => 'jrrmartin',\n            ],\n        ]);\n    }\n\n    public function testResourcesMayHaveOptionalPivotRelationshipsWithCustomAccessor()\n    {\n        Route::get('/', function () {\n            $post = new Post(['id' => 5]);\n            $post->setRelation('accessor', new Subscription);\n\n            return new PostResourceWithOptionalPivotRelationship($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertExactJson([\n            'data' => [\n                'id' => 5,\n                'custom_subscription' => [\n                    'foo' => 'bar',\n                ],\n            ],\n        ]);\n    }\n\n    public function testResourceIsUrlRoutable()\n    {\n        $post = new PostResource(new Post([\n            'id' => 5,\n            'title' => 'Test Title',\n        ]));\n\n        $this->assertSame('http://localhost/post/5', url('/post', $post));\n    }\n\n    public function testNamedRoutesAreUrlRoutable()\n    {\n        $post = new PostResource(new Post([\n            'id' => 5,\n            'title' => 'Test Title',\n        ]));\n\n        Route::get('/post/{id}', function () use ($post) {\n            return route('post.show', $post);\n        })->name('post.show');\n\n        $response = $this->withoutExceptionHandling()->get('/post/1');\n\n        $this->assertSame('http://localhost/post/5', $response->original);\n    }\n\n    public function testResourcesMayBeSerializable()\n    {\n        Route::get('/', function () {\n            return new SerializablePostResource(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n            ],\n        ]);\n    }\n\n    public function testResourcesMayCustomizeResponses()\n    {\n        Route::get('/', function () {\n            return new PostResource(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n        $response->assertHeader('X-Resource', 'True');\n    }\n\n    public function testResourcesMayCustomizeExtraData()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithExtraData(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n            ],\n            'foo' => 'bar',\n        ]);\n    }\n\n    public function testResourcesMayCustomizeExtraDataWhenBuildingResponse()\n    {\n        Route::get('/', function () {\n            return (new PostResourceWithExtraData(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ])))->additional(['baz' => 'qux']);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n            ],\n            'foo' => 'bar',\n            'baz' => 'qux',\n        ]);\n    }\n\n    public function testResourcesMayCustomizeJsonOptions()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithJsonOptions(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'reading_time' => 3.0,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $this->assertEquals(\n            '{\"data\":{\"id\":5,\"title\":\"Test Title\",\"reading_time\":3.0}}',\n            $response->baseResponse->content()\n        );\n    }\n\n    public function testCollectionResourcesMayCustomizeJsonOptions()\n    {\n        Route::get('/', function () {\n            return PostResourceWithJsonOptions::collection(collect([\n                new Post(['id' => 5, 'title' => 'Test Title', 'reading_time' => 3.0]),\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $this->assertEquals(\n            '{\"data\":[{\"id\":5,\"title\":\"Test Title\",\"reading_time\":3.0}]}',\n            $response->baseResponse->content()\n        );\n    }\n\n    public function testResourcesMayCustomizeJsonOptionsOnPaginatedResponse()\n    {\n        Route::get('/', function () {\n            $paginator = new LengthAwarePaginator(\n                collect([new Post(['id' => 5, 'title' => 'Test Title', 'reading_time' => 3.0])]),\n                10, 15, 1\n            );\n\n            return PostResourceWithJsonOptions::collection($paginator);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $this->assertEquals(\n            '{\"data\":[{\"id\":5,\"title\":\"Test Title\",\"reading_time\":3.0}],\"links\":{\"first\":\"\\/?page=1\",\"last\":\"\\/?page=1\",\"prev\":null,\"next\":null},\"meta\":{\"current_page\":1,\"from\":1,\"last_page\":1,\"links\":[{\"url\":null,\"label\":\"&laquo; Previous\",\"page\":null,\"active\":false},{\"url\":\"\\/?page=1\",\"label\":\"1\",\"page\":1,\"active\":true},{\"url\":null,\"label\":\"Next &raquo;\",\"page\":null,\"active\":false}],\"path\":\"\\/\",\"per_page\":15,\"to\":1,\"total\":10}}',\n            $response->baseResponse->content()\n        );\n    }\n\n    public function testResourcesMayCustomizeJsonOptionsWithTypeHintedConstructor()\n    {\n        Route::get('/', function () {\n            return new PostResourceWithJsonOptionsAndTypeHints(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n                'reading_time' => 3.0,\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $this->assertEquals(\n            '{\"data\":{\"id\":5,\"title\":\"Test Title\",\"reading_time\":3.0}}',\n            $response->baseResponse->content()\n        );\n    }\n\n    public function testCustomHeadersMayBeSetOnResponses()\n    {\n        Route::get('/', function () {\n            return (new PostResource(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ])))->response()->setStatusCode(202)->header('X-Custom', 'True');\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(202);\n        $response->assertHeader('X-Custom', 'True');\n    }\n\n    public function testResourcesMayReceiveProperStatusCodeForFreshModels()\n    {\n        Route::get('/', function () {\n            $post = new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]);\n\n            $post->wasRecentlyCreated = true;\n\n            return new PostResource($post);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(201);\n    }\n\n    public function testCollectionsAreNotDoubledWrapped()\n    {\n        Route::get('/', function () {\n            return new PostCollectionResource(collect([new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ])]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n        ]);\n    }\n\n    public function testPaginatorsReceiveLinks()\n    {\n        Route::get('/', function () {\n            $paginator = new LengthAwarePaginator(\n                collect([new Post(['id' => 5, 'title' => 'Test Title'])]),\n                10, 15, 1\n            );\n\n            return new PostCollectionResource($paginator);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'links' => [\n                'first' => '/?page=1',\n                'last' => '/?page=1',\n                'prev' => null,\n                'next' => null,\n            ],\n            'meta' => [\n                'current_page' => 1,\n                'from' => 1,\n                'last_page' => 1,\n                'path' => '/',\n                'per_page' => 15,\n                'to' => 1,\n                'total' => 10,\n            ],\n        ]);\n    }\n\n    public function testPaginatorResourceCanPreserveQueryParameters()\n    {\n        Route::get('/', function () {\n            $collection = collect([new Post(['id' => 2, 'title' => 'Laravel Nova'])]);\n            $paginator = new LengthAwarePaginator(\n                $collection, 3, 1, 2\n            );\n\n            return PostCollectionResource::make($paginator)->preserveQuery();\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/?framework=laravel&author=Otwell&page=2', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 2,\n                    'title' => 'Laravel Nova',\n                ],\n            ],\n            'links' => [\n                'first' => '/?framework=laravel&author=Otwell&page=1',\n                'last' => '/?framework=laravel&author=Otwell&page=3',\n                'prev' => '/?framework=laravel&author=Otwell&page=1',\n                'next' => '/?framework=laravel&author=Otwell&page=3',\n            ],\n            'meta' => [\n                'current_page' => 2,\n                'from' => 2,\n                'last_page' => 3,\n                'path' => '/',\n                'per_page' => 1,\n                'to' => 2,\n                'total' => 3,\n            ],\n        ]);\n    }\n\n    public function testPaginatorResourceCanReceiveQueryParameters()\n    {\n        Route::get('/', function () {\n            $collection = collect([new Post(['id' => 2, 'title' => 'Laravel Nova'])]);\n            $paginator = new LengthAwarePaginator(\n                $collection, 3, 1, 2\n            );\n\n            return PostCollectionResource::make($paginator)->withQuery(['author' => 'Taylor']);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/?framework=laravel&author=Otwell&page=2', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 2,\n                    'title' => 'Laravel Nova',\n                ],\n            ],\n            'links' => [\n                'first' => '/?author=Taylor&page=1',\n                'last' => '/?author=Taylor&page=3',\n                'prev' => '/?author=Taylor&page=1',\n                'next' => '/?author=Taylor&page=3',\n            ],\n            'meta' => [\n                'current_page' => 2,\n                'from' => 2,\n                'last_page' => 3,\n                'path' => '/',\n                'per_page' => 1,\n                'to' => 2,\n                'total' => 3,\n            ],\n        ]);\n    }\n\n    public function testCursorPaginatorReceiveLinks()\n    {\n        Route::get('/', function () {\n            $paginator = new CursorPaginator(\n                collect([new Post(['id' => 5, 'title' => 'Test Title']), new Post(['id' => 6, 'title' => 'Hello'])]),\n                1, null, ['parameters' => ['id']]\n            );\n\n            return new PostCollectionResource($paginator);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'links' => [\n                'first' => null,\n                'last' => null,\n                'prev' => null,\n                'next' => '/?cursor='.(new Cursor(['id' => 5]))->encode(),\n            ],\n            'meta' => [\n                'path' => '/',\n                'per_page' => 1,\n                'next_cursor' => (new Cursor(['id' => 5]))->encode(),\n                'prev_cursor' => null,\n            ],\n        ]);\n    }\n\n    public function testCursorPaginatorResourceCanPreserveQueryParameters()\n    {\n        Route::get('/', function () {\n            $collection = collect([new Post(['id' => 5, 'title' => 'Test Title']), new Post(['id' => 6, 'title' => 'Hello'])]);\n            $paginator = new CursorPaginator(\n                $collection, 1, null, ['parameters' => ['id']]\n            );\n\n            return PostCollectionResource::make($paginator)->preserveQuery();\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/?framework=laravel&author=Otwell', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'links' => [\n                'first' => null,\n                'last' => null,\n                'prev' => null,\n                'next' => '/?framework=laravel&author=Otwell&cursor='.(new Cursor(['id' => 5]))->encode(),\n            ],\n            'meta' => [\n                'path' => '/',\n                'per_page' => 1,\n            ],\n        ]);\n    }\n\n    public function testCursorPaginatorResourceCanReceiveQueryParameters()\n    {\n        Route::get('/', function () {\n            $collection = collect([new Post(['id' => 5, 'title' => 'Test Title']), new Post(['id' => 6, 'title' => 'Hello'])]);\n            $paginator = new CursorPaginator(\n                $collection, 1, null, ['parameters' => ['id']]\n            );\n\n            return PostCollectionResource::make($paginator)->withQuery(['author' => 'Taylor']);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/?framework=laravel&author=Otwell', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'links' => [\n                'first' => null,\n                'last' => null,\n                'prev' => null,\n                'next' => '/?author=Taylor&cursor='.(new Cursor(['id' => 5]))->encode(),\n            ],\n            'meta' => [\n                'path' => '/',\n                'per_page' => 1,\n            ],\n        ]);\n    }\n\n    public function testToJsonMayBeLeftOffOfCollection()\n    {\n        Route::get('/', function () {\n            return new EmptyPostCollectionResource(new LengthAwarePaginator(\n                collect([new Post(['id' => 5, 'title' => 'Test Title'])]),\n                10, 15, 1\n            ));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                    'custom' => true,\n                ],\n            ],\n            'links' => [\n                'first' => '/?page=1',\n                'last' => '/?page=1',\n                'prev' => null,\n                'next' => null,\n            ],\n            'meta' => [\n                'current_page' => 1,\n                'from' => 1,\n                'last_page' => 1,\n                'path' => '/',\n                'per_page' => 15,\n                'to' => 1,\n                'total' => 10,\n            ],\n        ]);\n    }\n\n    public function testToJsonMayBeLeftOffOfSingleResource()\n    {\n        Route::get('/', function () {\n            return new ReallyEmptyPostResource(new Post([\n                'id' => 5,\n                'title' => 'Test Title',\n            ]));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test Title',\n            ],\n        ]);\n    }\n\n    public function testOriginalOnResponseIsModelWhenSingleResource()\n    {\n        $createdPost = new Post(['id' => 5, 'title' => 'Test Title']);\n        Route::get('/', function () use ($createdPost) {\n            return new ReallyEmptyPostResource($createdPost);\n        });\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n        $this->assertTrue($createdPost->is($response->getOriginalContent()));\n    }\n\n    public function testOriginalOnResponseIsCollectionOfModelWhenCollectionResource()\n    {\n        $createdPosts = collect([\n            new Post(['id' => 5, 'title' => 'Test Title']),\n            new Post(['id' => 6, 'title' => 'Test Title 2']),\n        ]);\n        Route::get('/', function () use ($createdPosts) {\n            return new EmptyPostCollectionResource(new LengthAwarePaginator($createdPosts, 10, 15, 1));\n        });\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n        $createdPosts->each(function ($post) use ($response) {\n            $this->assertTrue($response->getOriginalContent()->contains($post));\n        });\n    }\n\n    public function testCollectionResourceWithPaginationInformation()\n    {\n        $posts = collect([\n            new Post(['id' => 5, 'title' => 'Test Title']),\n        ]);\n\n        Route::get('/', function () use ($posts) {\n            return new PostCollectionResourceWithPaginationInformation(new LengthAwarePaginator($posts, 10, 1, 1));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/',\n            ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'current_page' => 1,\n            'per_page' => 1,\n            'total_page' => 10,\n            'total' => 10,\n        ]);\n    }\n\n    public function testResourceWithPaginationInformation()\n    {\n        $posts = collect([\n            new Post(['id' => 5, 'title' => 'Test Title']),\n        ]);\n\n        Route::get('/', function () use ($posts) {\n            return PostResourceWithAnonymousResourceCollectionWithPaginationInformation::collection(new LengthAwarePaginator($posts, 10, 1, 1));\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/',\n            ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson([\n            'data' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test Title',\n                ],\n            ],\n            'current_page' => 1,\n            'per_page' => 1,\n            'total_page' => 10,\n            'total' => 10,\n        ]);\n    }\n\n    public function testCollectionResourcesAreCountable()\n    {\n        $posts = collect([\n            new Post(['id' => 1, 'title' => 'Test title']),\n            new Post(['id' => 2, 'title' => 'Test title 2']),\n        ]);\n\n        $collection = new PostCollectionResource($posts);\n\n        $this->assertCount(2, $collection);\n        $this->assertCount(2, $collection);\n    }\n\n    public function testCollectionResourcesMustCollectResources()\n    {\n        $posts = collect([\n            new Post(['id' => 1, 'title' => 'Test title']),\n            new Post(['id' => 2, 'title' => 'Test title 2']),\n        ]);\n\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('must collect');\n\n        new PostModelCollectionResource($posts);\n    }\n\n    public function testKeysArePreservedIfTheResourceIsFlaggedToPreserveKeys()\n    {\n        $data = [\n            'authorBook' => [\n                'byId' => [\n                    1 => [\n                        'id' => 1,\n                        'authorId' => 5,\n                        'bookId' => 22,\n                    ],\n                    2 => [\n                        'id' => 2,\n                        'authorId' => 5,\n                        'bookId' => 15,\n                    ],\n                    3 => [\n                        'id' => 3,\n                        'authorId' => 42,\n                        'bookId' => 12,\n                    ],\n                ],\n                'allIds' => [1, 2, 3],\n            ],\n        ];\n\n        Route::get('/', function () use ($data) {\n            return new ResourceWithPreservedKeys($data);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson(['data' => $data]);\n    }\n\n    public function testKeysArePreservedInAnAnonymousCollectionIfTheResourceIsFlaggedToPreserveKeys()\n    {\n        $data = Collection::make([\n            [\n                'id' => 1,\n                'authorId' => 5,\n                'bookId' => 22,\n            ],\n            [\n                'id' => 2,\n                'authorId' => 5,\n                'bookId' => 15,\n            ],\n            [\n                'id' => 3,\n                'authorId' => 42,\n                'bookId' => 12,\n            ],\n        ])->keyBy->id;\n\n        Route::get('/', function () use ($data) {\n            return ResourceWithPreservedKeys::collection($data);\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson(['data' => $data->toArray()]);\n    }\n\n    public function testKeysArePreservedInAnAnonymousCollectionUsingPreserveKeysMethod()\n    {\n        $data = Collection::make([\n            ['id' => 1, 'title' => 'Test'],\n            ['id' => 2, 'title' => 'Test 2'],\n        ])->keyBy->id;\n\n        Route::get('/', function () use ($data) {\n            return JsonResource::collection($data)->preserveKeys();\n        });\n\n        $response = $this->withoutExceptionHandling()->get(\n            '/', ['Accept' => 'application/json']\n        );\n\n        $response->assertStatus(200);\n\n        $response->assertJson(['data' => $data->toArray()]);\n    }\n\n    public function testLeadingMergeKeyedValueIsMergedCorrectly()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    new MergeValue(['name' => 'mohamed', 'location' => 'hurghada']),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'name' => 'mohamed', 'location' => 'hurghada',\n        ], $results);\n    }\n\n    public function testPostTooLargeException()\n    {\n        $request = new Request(server: ['CONTENT_LENGTH' => '4']);\n        $post = new ValidatePostSize;\n        $post->handle($request, fn () => null);\n\n        $this->expectException(PostTooLargeException::class);\n        $this->expectExceptionMessage('The POST data is too large.');\n\n        $request = new Request(server: ['CONTENT_LENGTH' => '2147483640']);\n        $post = new ValidatePostSize;\n        $post->handle($request, fn () => null);\n    }\n\n    public function testLeadingMergeKeyedValueIsMergedCorrectlyWhenFirstValueIsMissing()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    new MergeValue([\n                        0 => new MissingValue,\n                        'name' => 'mohamed',\n                        'location' => 'hurghada',\n                    ]),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'name' => 'mohamed', 'location' => 'hurghada',\n        ], $results);\n    }\n\n    public function testLeadingMergeValueIsMergedCorrectly()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    new MergeValue(['First', 'Second']),\n                    'Taylor',\n                    'Mohamed',\n                    new MergeValue(['Adam', 'Matt']),\n                    'Jeffrey',\n                    new MergeValue(['Abigail', 'Lydia']),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'First', 'Second', 'Taylor', 'Mohamed', 'Adam', 'Matt', 'Jeffrey', 'Abigail', 'Lydia',\n        ], $results);\n    }\n\n    public function testMergeValuesMayBeMissing()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    new MergeValue(['First', 'Second']),\n                    'Taylor',\n                    'Mohamed',\n                    $this->mergeWhen(false, ['Adam', 'Matt']),\n                    'Jeffrey',\n                    new MergeValue(['Abigail', 'Lydia']),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'First', 'Second', 'Taylor', 'Mohamed', 'Jeffrey', 'Abigail', 'Lydia',\n        ], $results);\n    }\n\n    public function testInitialMergeValuesMayBeMissing()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    $this->mergeWhen(false, ['First', 'Second']),\n                    'Taylor',\n                    'Mohamed',\n                    $this->mergeWhen(true, ['Adam', 'Matt']),\n                    'Jeffrey',\n                    new MergeValue(['Abigail', 'Lydia']),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'Taylor', 'Mohamed', 'Adam', 'Matt', 'Jeffrey', 'Abigail', 'Lydia',\n        ], $results);\n    }\n\n    public function testMergeValueCanMergeJsonSerializable()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                $postResource = new PostResource(new Post([\n                    'id' => 1,\n                    'title' => 'Test Title 1',\n                ]));\n\n                return $this->filter([\n                    new MergeValue($postResource),\n                    'user' => 'test user',\n                    'age' => 'test age',\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'id' => 1,\n            'title' => 'Test Title 1',\n            'custom' => true,\n            'user' => 'test user',\n            'age' => 'test age',\n        ], $results);\n    }\n\n    public function testMergeValueCanMergeCollectionOfJsonSerializable()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                $posts = collect([\n                    new Post(['id' => 1, 'title' => 'Test title 1']),\n                    new Post(['id' => 2, 'title' => 'Test title 2']),\n                ]);\n\n                return $this->filter([\n                    new MergeValue(PostResource::collection($posts)),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            ['id' => 1, 'title' => 'Test title 1', 'custom' => true],\n            ['id' => 2, 'title' => 'Test title 2', 'custom' => true],\n        ], $results);\n    }\n\n    public function testAllMergeValuesMayBeMissing()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    $this->mergeWhen(false, ['First', 'Second']),\n                    'Taylor',\n                    'Mohamed',\n                    $this->mergeWhen(false, ['Adam', 'Matt']),\n                    'Jeffrey',\n                    $this->mergeWhen(false, ['Abigail', 'Lydia']),\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'Taylor', 'Mohamed', 'Jeffrey',\n        ], $results);\n    }\n\n    public function testMergeValuesMayFallbackToDefaults()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    $this->mergeUnless(false, ['Taylor', 'Mohamed'], ['First', 'Second']),\n                    $this->mergeWhen(false, ['Adam', 'Matt'], ['Abigail', 'Lydia']),\n                    'Jeffrey',\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            'Taylor', 'Mohamed', 'Abigail', 'Lydia', 'Jeffrey',\n        ], $results);\n    }\n\n    public function testNestedMerges()\n    {\n        $filter = new class\n        {\n            use ConditionallyLoadsAttributes;\n\n            public function work()\n            {\n                return $this->filter([\n                    $this->mergeWhen(true, [['Something']]),\n                    [\n                        $this->mergeWhen(true, ['First', $this->mergeWhen(true, ['Second'])]),\n                        'Third',\n                    ],\n                    [\n                        'Fourth',\n                    ],\n                ]);\n            }\n        };\n\n        $results = $filter->work();\n\n        $this->assertEquals([\n            [\n                'Something',\n            ],\n            [\n                'First', 'Second', 'Third',\n            ],\n            [\n                'Fourth',\n            ],\n        ], $results);\n    }\n\n    public function testTheResourceCanBeAnArray()\n    {\n        $this->assertJsonResourceResponse([\n            'user@example.com' => 'John',\n            'admin@example.com' => 'Hank',\n        ], [\n            'data' => [\n                'user@example.com' => 'John',\n                'admin@example.com' => 'Hank',\n            ],\n        ]);\n    }\n\n    public function testItWillReturnAsAnArrayWhenStringKeysAreStripped()\n    {\n        $this->assertJsonResourceResponse([\n            1 => 'John',\n            2 => 'Hank',\n            'foo' => new MissingValue,\n        ], ['data' => ['John', 'Hank']]);\n\n        $this->assertJsonResourceResponse([\n            1 => 'John',\n            'foo' => new MissingValue,\n            3 => 'Hank',\n        ], ['data' => ['John', 'Hank']]);\n\n        $this->assertJsonResourceResponse([\n            'foo' => new MissingValue,\n            2 => 'John',\n            3 => 'Hank',\n        ], ['data' => ['John', 'Hank']]);\n    }\n\n    public function testItStripsNumericKeys()\n    {\n        $this->assertJsonResourceResponse([\n            0 => 'John',\n            1 => 'Hank',\n        ], ['data' => ['John', 'Hank']]);\n\n        $this->assertJsonResourceResponse([\n            0 => 'John',\n            1 => 'Hank',\n            3 => 'Bill',\n        ], ['data' => ['John', 'Hank', 'Bill']]);\n\n        $this->assertJsonResourceResponse([\n            5 => 'John',\n            6 => 'Hank',\n        ], ['data' => ['John', 'Hank']]);\n    }\n\n    public function testItWontKeysIfAnyOfThemAreStrings()\n    {\n        $this->assertJsonResourceResponse([\n            '5' => 'John',\n            '6' => 'Hank',\n            'a' => 'Bill',\n        ], ['data' => ['5' => 'John', '6' => 'Hank', 'a' => 'Bill']]);\n\n        $this->assertJsonResourceResponse([\n            0 => 10,\n            1 => 20,\n            'total' => 30,\n        ], ['data' => [0 => 10, 1 => 20, 'total' => 30]]);\n    }\n\n    public function testItThrowsNoErrorInStrictModeWhenResourceIsPaginated()\n    {\n        $originalMode = Model::preventsAccessingMissingAttributes();\n        Model::preventAccessingMissingAttributes();\n        try {\n            Route::get('/', function () {\n                $paginator = new LengthAwarePaginator(\n                    collect([new Post(['id' => 5, 'title' => 'Test Title', 'reading_time' => 3.0])]),\n                    10, 15, 1\n                );\n\n                return PostResourceWithJsonOptions::collection($paginator);\n            });\n\n            $response = $this->withoutExceptionHandling()->get(\n                '/', ['Accept' => 'application/json']\n            );\n\n            $response->assertStatus(200);\n        } finally {\n            Model::preventAccessingMissingAttributes($originalMode);\n        }\n    }\n\n    public function testResourceSkipsWrappingWhenDataKeyExists()\n    {\n        $resource = new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource\n        {\n            public static $wrap = 'data';\n        };\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertEquals([\n            'id' => 5,\n            'title' => 'Test',\n            'data' => 'some data',\n        ], $content);\n    }\n\n    public function testResourceWrapsWhenDataKeyDoesNotExist()\n    {\n        $resource = new class(['id' => 5, 'title' => 'Test']) extends JsonResource\n        {\n            public static $wrap = 'data';\n        };\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertEquals([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test',\n            ],\n        ], $content);\n    }\n\n    public function testResourceCanOverridesWrapping()\n    {\n        $resource = new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource\n        {\n            public static $wrap = 'results';\n            public static bool $forceWrapping = true;\n        };\n\n        JsonResource::flushState();\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertEquals([\n            'results' => [\n                'id' => 5,\n                'title' => 'Test',\n                'data' => 'some data',\n            ],\n        ], $content);\n    }\n\n    public function testResourceCollectionCanOverridesWrapping()\n    {\n        $resource = new class([new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource\n        {\n            public static $wrap = null;\n        },\n        ]) extends ResourceCollection {\n            public static $wrap = 'results';\n        };\n\n        JsonResource::flushState();\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertEquals([\n            'results' => [\n                [\n                    'id' => 5,\n                    'title' => 'Test',\n                    'data' => 'some data',\n                ],\n            ],\n        ], $content);\n    }\n\n    public function testPaginatedResourceCollectionCanOverridesWrapping()\n    {\n        $resource = new class(new LengthAwarePaginator([new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource\n        {\n            public static $wrap = null;\n        },\n        ], 10, 2)) extends ResourceCollection {\n            public static $wrap = 'results';\n        };\n\n        JsonResource::flushState();\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertArrayHasKey('results', $content);\n        $this->assertArrayHasKey('links', $content);\n        $this->assertArrayHasKey('meta', $content);\n\n        $this->assertCount(1, $content['results']);\n        $this->assertEquals([\n            [\n                'id' => 5,\n                'title' => 'Test',\n                'data' => 'some data',\n            ],\n        ], $content['results']);\n    }\n\n    public function testEmptyPaginatedResourceCollectionCanOverridesWrapping()\n    {\n        $resource = new class(new LengthAwarePaginator([], 10, 2)) extends ResourceCollection\n        {\n            public static $wrap = 'results';\n        };\n\n        JsonResource::flushState();\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertArrayHasKey('results', $content);\n        $this->assertArrayHasKey('links', $content);\n        $this->assertArrayHasKey('meta', $content);\n\n        $this->assertCount(0, $content['results']);\n    }\n\n    public function testResourceForceWrapOverridesDataKeyCheck()\n    {\n        $resource = new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource\n        {\n            public static $wrap = 'data';\n            public static bool $forceWrapping = true;\n        };\n\n        $response = $resource->toResponse(request());\n        $content = json_decode($response->getContent(), true);\n\n        $this->assertEquals([\n            'data' => [\n                'id' => 5,\n                'title' => 'Test',\n                'data' => 'some data',\n            ],\n        ], $content);\n    }\n\n    private function assertJsonResourceResponse($data, $expectedJson)\n    {\n        Route::get('/', function () use ($data) {\n            return new JsonResource($data);\n        });\n\n        $this->withoutExceptionHandling()\n            ->get('/', ['Accept' => 'application/json'])\n            ->assertStatus(200)\n            ->assertExactJson($expectedJson);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/Json/ResourceCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\Json;\n\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\Json\\ResourceCollection;\nuse Illuminate\\Support\\Fluent;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass ResourceCollectionTest extends TestCase\n{\n    #[DataProvider('toArrayDataProvider')]\n    public function testItCanReturnToArray(ResourceCollection $collection, mixed $expected)\n    {\n        $request = Request::create('GET', '/');\n\n        $this->assertSame($expected, $collection->toArray($request));\n    }\n\n    public static function toArrayDataProvider()\n    {\n        yield [\n            new ResourceCollection([\n                new Fluent(['id' => 1]),\n                new Fluent(['id' => 2]),\n                new Fluent(['id' => 3]),\n            ]),\n            [\n                ['id' => 1],\n                ['id' => 2],\n                ['id' => 3],\n            ],\n        ];\n\n        yield [\n            (new ResourceCollection([\n                (new User())->forceFill(['name' => 'Taylor Otwell']),\n                (new User())->forceFill(['name' => 'Laravel']),\n            ]))->additional(['total', 1]),\n            [\n                ['name' => 'Taylor Otwell'],\n                ['name' => 'Laravel'],\n            ],\n        ];\n\n        yield [\n            new class(['list' => new Fluent(['id' => 1]), 'total' => 1]) extends ResourceCollection\n            {\n                public function toArray(Request $request)\n                {\n                    return $this->resource->toArray();\n                }\n            },\n            [\n                'list' => ['id' => 1],\n                'total' => 1,\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/ArrayBackedJsonApiResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass ArrayBackedJsonApiResource extends JsonApiResource\n{\n    public function toId(Request $request)\n    {\n        return (string) $this->resource['id'];\n    }\n\n    public function toType(Request $request)\n    {\n        return 'things';\n    }\n\n    public function toAttributes(Request $request)\n    {\n        return ['name' => $this->resource['name']];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/AuthorResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass AuthorResource extends JsonApiResource\n{\n    protected array $relationships = [\n        'comments',\n        'profile',\n        'chaperonePosts' => PostResource::class,\n    ];\n\n    #[\\Override]\n    public function toAttributes(Request $request)\n    {\n        return [\n            'name' => $this->name,\n            'email' => $this->email,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/Comment.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\n\n#[UseFactory(CommentFactory::class)]\n#[UseResource(CommentResource::class)]\nclass Comment extends Model\n{\n    use HasFactory;\n\n    public function post()\n    {\n        return $this->belongsTo(Post::class);\n    }\n\n    public function commenter()\n    {\n        return $this->belongsTo(User::class, 'user_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/CommentFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\nclass CommentFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'post_id' => PostFactory::new(),\n            'user_id' => UserFactory::new(),\n            'content' => $this->faker->words(10, true),\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/CommentResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass CommentResource extends JsonApiResource\n{\n    /**\n     * The resource's attributes.\n     */\n    public $attributes = [\n        'content',\n    ];\n\n    /**\n     * The resource's relationships.\n     */\n    public $relationships = [\n        'posts',\n        'commenter' => UserApiResource::class,\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/Membership.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\n\nclass Membership extends Pivot\n{\n    protected $table = 'team_user';\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/Post.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\n\n#[UseFactory(PostFactory::class)]\n#[UseResource(PostResource::class)]\nclass Post extends Model\n{\n    use HasFactory;\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function author()\n    {\n        return $this->belongsTo(User::class, 'user_id');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/PostFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\nclass PostFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'user_id' => UserFactory::new(),\n            'title' => $this->faker->word(),\n            'content' => $this->faker->words(10, true),\n        ];\n    }\n\n    #[\\Override]\n    public function modelName()\n    {\n        return Post::class;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/PostResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass PostResource extends JsonApiResource\n{\n    protected array $attributes = [\n        'title',\n        'content',\n    ];\n\n    protected array $relationships = [\n        'author' => AuthorResource::class,\n        'comments',\n    ];\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/Profile.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\n\n#[UseResource(ProfileResource::class)]\n#[UseFactory(ProfileFactory::class)]\nclass Profile extends Model\n{\n    use HasFactory;\n\n    public $timestamps = false;\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/ProfileFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\nclass ProfileFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'user_id' => UserFactory::new(),\n        ];\n    }\n\n    #[\\Override]\n    public function modelName()\n    {\n        return Profile::class;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/ProfileResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass ProfileResource extends JsonApiResource\n{\n    protected array $relationships = [\n        'user' => UserResource::class,\n    ];\n\n    #[\\Override]\n    public function toAttributes(Request $request)\n    {\n        return [\n            'timezone' => $this->timezone,\n            'date_of_birth' => $this->date_of_birth,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/Team.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Database\\Eloquent\\Model;\n\n#[UseFactory(TeamFactory::class)]\nclass Team extends Model\n{\n    use HasFactory;\n\n    public $timestamps = false;\n\n    protected function casts(): array\n    {\n        return [\n            'personal_team' => 'boolean',\n        ];\n    }\n\n    public function users()\n    {\n        return $this->belongsToMany(User::class)\n            ->withPivot('role')\n            ->withTimestamps()\n            ->using(Membership::class)\n            ->as('membership');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/TeamFactory.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Factories\\Factory;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\nclass TeamFactory extends Factory\n{\n    public function definition(): array\n    {\n        return [\n            'name' => $this->faker->unique()->company(),\n            'user_id' => UserFactory::new(),\n            'personal_team' => true,\n        ];\n    }\n\n    #[\\Override]\n    public function modelName()\n    {\n        return Team::class;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/User.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseFactory;\nuse Illuminate\\Database\\Eloquent\\Attributes\\UseResource;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\n#[UseResource(UserResource::class)]\n#[UseFactory(UserFactory::class)]\nclass User extends Authenticatable\n{\n    use HasFactory;\n\n    public function profile()\n    {\n        return $this->hasOne(Profile::class);\n    }\n\n    public function posts()\n    {\n        return $this->hasMany(Post::class);\n    }\n\n    public function chaperonePosts()\n    {\n        return $this->hasMany(Post::class)->chaperone('author');\n    }\n\n    public function comments()\n    {\n        return $this->hasMany(Comment::class);\n    }\n\n    public function teams()\n    {\n        return $this->belongsToMany(Team::class)\n            ->withPivot('role')\n            ->withTimestamps()\n            ->using(Membership::class)\n            ->as('membership');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/UserResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    protected array $relationships = [\n        'comments',\n        'profile',\n        'posts',\n        'teams',\n        'chaperonePosts' => PostResource::class,\n    ];\n\n    #[\\Override]\n    public function toAttributes(Request $request)\n    {\n        return [\n            'name' => $this->name,\n            'email' => $this->email,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/UserWithArrayRelationshipResource.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass UserWithArrayRelationshipResource extends JsonApiResource\n{\n    public function toType(Request $request)\n    {\n        return 'users';\n    }\n\n    public function toAttributes(Request $request)\n    {\n        return [\n            'name' => $this->name,\n            'email' => $this->email,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/Fixtures/migrations.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nSchema::create('posts', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('user_id')->index();\n    $table->string('title');\n    $table->text('content');\n    $table->timestamps();\n});\n\nSchema::create('profiles', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('user_id')->unique();\n    $table->date('date_of_birth')->nullable();\n    $table->string('timezone')->nullable();\n});\n\nSchema::create('teams', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('user_id')->index();\n    $table->string('name');\n    $table->boolean('personal_team');\n});\n\nSchema::create('team_user', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('team_id');\n    $table->foreignId('user_id');\n    $table->string('role')->nullable();\n    $table->timestamps();\n\n    $table->index(['team_id', 'user_id']);\n});\n\nSchema::create('comments', function (Blueprint $table) {\n    $table->id();\n    $table->foreignId('post_id')->unique();\n    $table->foreignId('user_id')->index()->nullable();\n    $table->text('content');\n    $table->timestamps();\n});\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/JsonApiCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Profile;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Team;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\User;\n\nclass JsonApiCollectionTest extends TestCase\n{\n    public function testItCanGenerateJsonApiResponse()\n    {\n        $users = User::factory()->times(5)->create();\n\n        $this->getJson('/users')\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath(\n                'data',\n                $users->transform(fn ($user) => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                        'email' => $user->email,\n                    ],\n                ])->all()\n            )->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithSparseFieldsets()\n    {\n        $users = User::factory()->times(5)->create();\n\n        $this->getJson('/users/?'.http_build_query(['fields' => ['users' => 'name']]))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath(\n                'data',\n                $users->transform(fn ($user) => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                    ],\n                ])->all()\n            )->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithEmptyRelationshipsUsingSparseIncluded()\n    {\n        $users = User::factory()->times(5)->create();\n\n        $this->getJson('/users/?'.http_build_query(['include' => 'posts']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath(\n                'data',\n                $users->transform(fn ($user) => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                        'email' => $user->email,\n                    ],\n                    'relationships' => [\n                        'posts' => [\n                            'data' => [],\n                        ],\n                    ],\n                ])->all()\n            )->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithRelationshipsUsingSparseIncluded()\n    {\n        $now = $this->freezeSecond();\n\n        $users = User::factory()->times(4)->create();\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        $team = Team::factory()->create([\n            'name' => 'Laravel Team',\n        ]);\n\n        $user->teams()->attach($team, ['role' => 'Admin']);\n        $user->teams()->attach($team, ['role' => 'Member']);\n\n        $posts = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson('/users?'.http_build_query(['include' => 'profile,posts,teams']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath(\n                'data',\n                [\n                    ...$users->transform(fn ($user) => [\n                        'id' => (string) $user->getKey(),\n                        'type' => 'users',\n                        'attributes' => [\n                            'name' => $user->name,\n                            'email' => $user->email,\n                        ],\n                        'relationships' => [\n                            'profile' => ['data' => null],\n                            'posts' => ['data' => []],\n                            'teams' => ['data' => []],\n                        ],\n                    ])->all(),\n                    [\n                        'id' => (string) $user->getKey(),\n                        'type' => 'users',\n                        'attributes' => [\n                            'name' => $user->name,\n                            'email' => $user->email,\n                        ],\n                        'relationships' => [\n                            'profile' => [\n                                'data' => [\n                                    'id' => (string) $profile->getKey(),\n                                    'type' => 'profiles',\n                                ],\n                            ],\n                            'posts' => [\n                                'data' => [\n                                    ['id' => (string) $posts[0]->getKey(), 'type' => 'posts'],\n                                    ['id' => (string) $posts[1]->getKey(), 'type' => 'posts'],\n                                ],\n                            ],\n                            'teams' => [\n                                'data' => [\n                                    ['id' => (string) $team->getKey(), 'type' => 'teams'],\n                                    ['id' => (string) $team->getKey(), 'type' => 'teams'],\n                                ],\n                            ],\n                        ],\n                    ],\n                ]\n            )->assertJsonPath(\n                'included',\n                [\n                    [\n                        'id' => (string) $profile->getKey(),\n                        'type' => 'profiles',\n                        'attributes' => [\n                            'timezone' => 'America/Chicago',\n                            'date_of_birth' => '2011-06-09',\n                        ],\n                    ],\n                    [\n                        'id' => (string) $posts[0]->getKey(),\n                        'type' => 'posts',\n                        'attributes' => [\n                            'title' => $posts[0]->title,\n                            'content' => $posts[0]->content,\n                        ],\n                    ],\n                    [\n                        'id' => (string) $posts[1]->getKey(),\n                        'type' => 'posts',\n                        'attributes' => [\n                            'title' => $posts[1]->title,\n                            'content' => $posts[1]->content,\n                        ],\n                    ],\n                    [\n                        'id' => (string) $team->getKey(),\n                        'type' => 'teams',\n                        'attributes' => [\n                            'id' => $team->getKey(),\n                            'user_id' => $team->user_id,\n                            'name' => 'Laravel Team',\n                            'personal_team' => true,\n                            'membership' => [\n                                'user_id' => $user->getKey(),\n                                'team_id' => $team->getKey(),\n                                'role' => 'Admin',\n                                'created_at' => $now->toISOString(),\n                                'updated_at' => $now->toISOString(),\n                            ],\n                        ],\n                    ],\n                    [\n                        'id' => (string) $team->getKey(),\n                        'type' => 'teams',\n                        'attributes' => [\n                            'id' => $team->getKey(),\n                            'user_id' => $team->user_id,\n                            'name' => 'Laravel Team',\n                            'personal_team' => true,\n                            'membership' => [\n                                'user_id' => $user->getKey(),\n                                'team_id' => $team->getKey(),\n                                'role' => 'Member',\n                                'created_at' => $now->toISOString(),\n                                'updated_at' => $now->toISOString(),\n                            ],\n                        ],\n                    ],\n                ]\n            );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/JsonApiRequestTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiRequest;\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\n\nclass JsonApiRequestTest extends TestCase\n{\n    public function testItCanResolveSparseFields()\n    {\n        $request = JsonApiRequest::create(uri: '/?'.http_build_query([\n            'fields' => [\n                'users' => 'name,email',\n                'teams' => 'name',\n            ],\n        ]));\n\n        $this->assertSame(['name', 'email'], $request->sparseFields('users'));\n        $this->assertSame(['name'], $request->sparseFields('teams'));\n        $this->assertSame([], $request->sparseFields('posts'));\n    }\n\n    public function testItCanResolveEmptySparseFields()\n    {\n        $request = JsonApiRequest::create(uri: '/');\n\n        $this->assertSame([], $request->sparseFields('users'));\n        $this->assertSame([], $request->sparseFields('teams'));\n        $this->assertSame([], $request->sparseFields('posts'));\n    }\n\n    public function testItCanResolveSparseIncluded()\n    {\n        $request = JsonApiRequest::create(uri: '/?'.http_build_query([\n            'include' => 'teams,posts.author,posts.comments,profile.user.profile',\n        ]));\n\n        $this->assertSame(['teams', 'posts', 'profile'], $request->sparseIncluded());\n        $this->assertSame([], $request->sparseIncluded('teams'));\n        $this->assertSame(['author', 'comments'], $request->sparseIncluded('posts'));\n        $this->assertSame(['user.profile'], $request->sparseIncluded('profile'));\n    }\n\n    public function testItCanREsolveSparseIncludedWithMaxRelationshipNesting()\n    {\n        JsonApiResource::maxRelationshipDepth(2);\n\n        $request = JsonApiRequest::create(uri: '/?'.http_build_query([\n            'include' => 'teams,posts.author,posts.comments,profile.user.profile',\n        ]));\n\n        $this->assertSame(['teams', 'posts', 'profile'], $request->sparseIncluded());\n        $this->assertSame([], $request->sparseIncluded('teams'));\n        $this->assertSame(['author', 'comments'], $request->sparseIncluded('posts'));\n        $this->assertSame(['user'], $request->sparseIncluded('profile'));\n    }\n\n    public function testItCanResolveEmptySparseIncluded()\n    {\n        $request = JsonApiRequest::create(uri: '/');\n\n        $this->assertSame([], $request->sparseIncluded());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/JsonApiResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Http\\Resources\\JsonApi\\JsonApiResource;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Comment;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Profile;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Team;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\User;\n\nclass JsonApiResourceTest extends TestCase\n{\n    public function testItCanGenerateJsonApiResponse()\n    {\n        $user = User::factory()->create();\n\n        $this->getJson(\"/users/{$user->getKey()}\")\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                        'email' => $user->email,\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithSparseFieldsets()\n    {\n        $user = User::factory()->create();\n\n        $this->getJson(\"/users/{$user->getKey()}?\".http_build_query(['fields' => ['users' => 'name']]))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithEmptyRelationshipsUsingSparseIncluded()\n    {\n        $user = User::factory()->create();\n\n        $this->getJson(\"/users/{$user->getKey()}?\".http_build_query(['include' => 'posts']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                        'email' => $user->email,\n                    ],\n                    'relationships' => [\n                        'posts' => [\n                            'data' => [],\n                        ],\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithRelationshipsUsingSparseIncluded()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        $team = Team::factory()->create([\n            'name' => 'Laravel Team',\n        ]);\n\n        $user->teams()->attach($team, ['role' => 'Admin']);\n        $user->teams()->attach($team, ['role' => 'Member']);\n\n        $posts = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson(\"/users/{$user->getKey()}?\".http_build_query(['include' => 'profile,posts,teams']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'attributes' => [\n                        'name' => $user->name,\n                        'email' => $user->email,\n                    ],\n                    'relationships' => [\n                        'posts' => [\n                            'data' => [\n                                ['id' => (string) $posts[0]->getKey(), 'type' => 'posts'],\n                                ['id' => (string) $posts[1]->getKey(), 'type' => 'posts'],\n                            ],\n                        ],\n                        'profile' => [\n                            'data' => [\n                                'id' => (string) $profile->getKey(),\n                                'type' => 'profiles',\n                            ],\n                        ],\n                        'teams' => [\n                            'data' => [\n                                ['id' => (string) $team->getKey(), 'type' => 'teams'],\n                                ['id' => (string) $team->getKey(), 'type' => 'teams'],\n                            ],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'id' => (string) $profile->getKey(),\n                        'type' => 'profiles',\n                        'attributes' => [\n                            'date_of_birth' => '2011-06-09',\n                            'timezone' => 'America/Chicago',\n                        ],\n                    ],\n                    [\n                        'id' => (string) $posts[0]->getKey(),\n                        'type' => 'posts',\n                        'attributes' => [\n                            'title' => $posts[0]->title,\n                            'content' => $posts[0]->content,\n                        ],\n                    ],\n                    [\n                        'id' => (string) $posts[1]->getKey(),\n                        'type' => 'posts',\n                        'attributes' => [\n                            'title' => $posts[1]->title,\n                            'content' => $posts[1]->content,\n                        ],\n                    ],\n                    [\n                        'id' => (string) $team->getKey(),\n                        'type' => 'teams',\n                        'attributes' => [\n                            'id' => $team->getKey(),\n                            'user_id' => $team->user_id,\n                            'name' => 'Laravel Team',\n                            'personal_team' => true,\n                            'membership' => [\n                                'created_at' => $now->toISOString(),\n                                'role' => 'Admin',\n                                'team_id' => $team->getKey(),\n                                'user_id' => $user->getKey(),\n                                'updated_at' => $now->toISOString(),\n                            ],\n                        ],\n                    ],\n                    [\n                        'id' => (string) $team->getKey(),\n                        'type' => 'teams',\n                        'attributes' => [\n                            'id' => $team->getKey(),\n                            'user_id' => $team->user_id,\n                            'name' => 'Laravel Team',\n                            'personal_team' => true,\n                            'membership' => [\n                                'created_at' => $now->toISOString(),\n                                'role' => 'Member',\n                                'team_id' => $team->getKey(),\n                                'user_id' => $user->getKey(),\n                                'updated_at' => $now->toISOString(),\n                            ],\n                        ],\n                    ],\n                ],\n            ]);\n    }\n\n    public function testItCanGenerateJsonApiResponseWithRelationshipsUsingSparseIncludedAndSparseFieldsets()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        [$post1, $post2] = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson('/posts?'.http_build_query(['include' => 'author', 'fields' => ['authors' => 'name']]))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    [\n                        'attributes' => [\n                            'content' => $post1->content,\n                            'title' => $post1->title,\n                        ],\n                        'type' => 'posts',\n                        'id' => (string) $post1->getKey(),\n                        'relationships' => [\n                            'author' => [\n                                'data' => [\n                                    'id' => (string) $user->getKey(),\n                                    'type' => 'authors',\n                                ],\n                            ],\n                        ],\n                    ],\n                    [\n                        'attributes' => [\n                            'content' => $post2->content,\n                            'title' => $post2->title,\n                        ],\n                        'type' => 'posts',\n                        'id' => (string) $post2->getKey(),\n                        'relationships' => [\n                            'author' => [\n                                'data' => [\n                                    'id' => (string) $user->getKey(),\n                                    'type' => 'authors',\n                                ],\n                            ],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'authors',\n                    ],\n                ],\n                'links' => [\n                    'first' => url('/posts?page=1'),\n                    'last' => url('/posts?page=1'),\n                    'next' => null,\n                    'prev' => null,\n                ],\n                'meta' => [\n                    'current_page' => 1,\n                    'from' => 1,\n                    'last_page' => 1,\n                    'links' => [\n                        ['active' => false, 'label' => '&laquo; Previous', 'page' => null, 'url' => null],\n                        ['active' => true, 'label' => '1', 'page' => 1, 'url' => url('/posts?page=1')],\n                        ['active' => false, 'label' => 'Next &raquo;', 'page' => null, 'url' => null],\n                    ],\n                    'path' => url('/posts'),\n                    'per_page' => 5,\n                    'to' => 2,\n                    'total' => 2,\n                ],\n            ])\n            ->assertJsonCount(1, 'included')\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItCanResolveRelationshipWithCustomNameAndResourceClass()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        [$post1, $post2] = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $comment = Comment::factory()->create([\n            'post_id' => $post1->getKey(),\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson(\"/posts/{$post1->getKey()}?\".http_build_query(['include' => 'author']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'attributes' => [\n                        'content' => $post1->content,\n                        'title' => $post1->title,\n                    ],\n                    'type' => 'posts',\n                    'id' => (string) $post1->getKey(),\n                    'relationships' => [\n                        'author' => [\n                            'data' => [\n                                'id' => (string) $user->getKey(),\n                                'type' => 'authors',\n                            ],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'authors',\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItCanResolveRelationshipWithNestedRelationship()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        [$post1, $post2] = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $comment = Comment::factory()->create([\n            'post_id' => $post1->getKey(),\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson(\"/posts/{$post1->getKey()}?\".http_build_query(['include' => 'author,comments.commenter']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'attributes' => [\n                        'content' => $post1->content,\n                        'title' => $post1->title,\n                    ],\n                    'type' => 'posts',\n                    'id' => (string) $post1->getKey(),\n                    'relationships' => [\n                        'author' => [\n                            'data' => [\n                                'id' => (string) $user->getKey(),\n                                'type' => 'authors',\n                            ],\n                        ],\n                        'comments' => [\n                            'data' => [\n                                ['id' => (string) $comment->getKey(), 'type' => 'comments'],\n                            ],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'authors',\n                    ],\n                    [\n                        'attributes' => [\n                            'content' => $comment->content,\n                        ],\n                        'id' => (string) $comment->getKey(),\n                        'type' => 'comments',\n                        'relationships' => [\n                            'commenter' => [\n                                'data' => [\n                                    'id' => (string) $user->getKey(),\n                                    'type' => 'users',\n                                ],\n                            ],\n                        ],\n                    ],\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'users',\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItCanResolveRelationshipWithRecursiveNestedRelationship()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        $this->getJson(\"/users/{$user->getKey()}?\".http_build_query(['include' => 'profile.user.profile']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'attributes' => [\n                        'email' => $user->email,\n                        'name' => $user->name,\n                    ],\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'relationships' => [\n                        'profile' => [\n                            'data' => ['id' => (string) $profile->getKey(), 'type' => 'profiles'],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'date_of_birth' => '2011-06-09',\n                            'timezone' => 'America/Chicago',\n                        ],\n                        'id' => (string) $profile->getKey(),\n                        'type' => 'profiles',\n                        'relationships' => [\n                            'user' => [\n                                'data' => ['id' => (string) $user->getKey(), 'type' => 'users'],\n                            ],\n                        ],\n                    ],\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'users',\n                        'relationships' => [\n                            'profile' => [\n                                'data' => ['id' => (string) $profile->getKey(), 'type' => 'profiles'],\n                            ],\n                        ],\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItCanResolveRelationshipWithRecursiveNestedRelationshipLimitedToDepthConfiguration()\n    {\n        JsonApiResource::maxRelationshipDepth(2);\n\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        $profile = Profile::factory()->create([\n            'user_id' => $user->getKey(),\n            'date_of_birth' => '2011-06-09',\n            'timezone' => 'America/Chicago',\n        ]);\n\n        $this->getJson(\"/users/{$user->getKey()}?\".http_build_query(['include' => 'profile.user.profile']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'attributes' => [\n                        'email' => $user->email,\n                        'name' => $user->name,\n                    ],\n                    'id' => (string) $user->getKey(),\n                    'type' => 'users',\n                    'relationships' => [\n                        'profile' => [\n                            'data' => ['id' => (string) $profile->getKey(), 'type' => 'profiles'],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'date_of_birth' => '2011-06-09',\n                            'timezone' => 'America/Chicago',\n                        ],\n                        'id' => (string) $profile->getKey(),\n                        'type' => 'profiles',\n                        'relationships' => [\n                            'user' => [\n                                'data' => ['id' => (string) $user->getKey(), 'type' => 'users'],\n                            ],\n                        ],\n                    ],\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'users',\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItCanResolveRelationshipWithoutRedundantIncludedRelationship()\n    {\n        $now = $this->freezeSecond();\n\n        $user = User::factory()->create();\n\n        [$post1, $post2] = Post::factory()->times(2)->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $this->getJson('/posts?'.http_build_query(['include' => 'author']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    [\n                        'attributes' => [\n                            'content' => $post1->content,\n                            'title' => $post1->title,\n                        ],\n                        'type' => 'posts',\n                        'id' => (string) $post1->getKey(),\n                        'relationships' => [\n                            'author' => [\n                                'data' => [\n                                    'id' => (string) $user->getKey(),\n                                    'type' => 'authors',\n                                ],\n                            ],\n                        ],\n                    ],\n                    [\n                        'attributes' => [\n                            'content' => $post2->content,\n                            'title' => $post2->title,\n                        ],\n                        'type' => 'posts',\n                        'id' => (string) $post2->getKey(),\n                        'relationships' => [\n                            'author' => [\n                                'data' => [\n                                    'id' => (string) $user->getKey(),\n                                    'type' => 'authors',\n                                ],\n                            ],\n                        ],\n                    ],\n                ],\n                'included' => [\n                    [\n                        'attributes' => [\n                            'email' => $user->email,\n                            'name' => $user->name,\n                        ],\n                        'id' => (string) $user->getKey(),\n                        'type' => 'authors',\n                    ],\n                ],\n                'links' => [\n                    'first' => url('/posts?page=1'),\n                    'last' => url('/posts?page=1'),\n                    'next' => null,\n                    'prev' => null,\n                ],\n                'meta' => [\n                    'current_page' => 1,\n                    'from' => 1,\n                    'last_page' => 1,\n                    'links' => [\n                        ['active' => false, 'label' => '&laquo; Previous', 'page' => null, 'url' => null],\n                        ['active' => true, 'label' => '1', 'page' => 1, 'url' => url('/posts?page=1')],\n                        ['active' => false, 'label' => 'Next &raquo;', 'page' => null, 'url' => null],\n                    ],\n                    'path' => url('/posts'),\n                    'per_page' => 5,\n                    'to' => 2,\n                    'total' => 2,\n                ],\n            ])\n            ->assertJsonCount(1, 'included')\n            ->assertJsonMissing(['jsonapi']);\n    }\n\n    public function testItHandlesBidirectionalRelationshipsWithChaperoneWithoutInfiniteLoop()\n    {\n        $user = User::factory()->create();\n\n        $post = Post::factory()->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        // The /with-chaperone-posts route loads chaperonePosts which uses chaperone()\n        // to automatically set the inverse 'author' relationship on each Post,\n        // creating circular object references (User -> Post -> User same instance).\n        // Without the fix, this would hang forever due to infinite loop.\n        // The same User model appears twice in included: once as \"posts\" (the Post)\n        // and once as \"authors\" (Post's author via chaperone) - this is correct\n        // because different resource types should not be deduplicated.\n        $this->getJson(\"/users/{$user->getKey()}/with-chaperone-posts?\".http_build_query(['include' => 'chaperonePosts']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath('data.id', (string) $user->getKey())\n            ->assertJsonPath('data.type', 'users')\n            ->assertJsonPath('data.relationships.chaperonePosts.data.0.type', 'posts')\n            ->assertJsonPath('data.relationships.chaperonePosts.data.0.id', (string) $post->getKey())\n            ->assertJsonPath('included.0.type', 'posts')\n            ->assertJsonPath('included.1.type', 'authors')\n            ->assertJsonCount(2, 'included');\n    }\n\n    public function testIncludedResourcesCanBeArrayBackedCustomResources()\n    {\n        $user = User::factory()->create();\n\n        $this->getJson(\"/users/{$user->getKey()}/with-array-relationship\")\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath('data.id', (string) $user->getKey())\n            ->assertJsonPath('data.type', 'users')\n            ->assertJsonPath('included.0.id', '99')\n            ->assertJsonPath('included.0.type', 'things')\n            ->assertJsonPath('included.0.attributes.name', 'test')\n            ->assertJsonCount(1, 'included');\n    }\n\n    public function testTopLevelArrayBackedCustomResourceCanGenerateJsonApiResponse()\n    {\n        $this->getJson('/things/99')\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertExactJson([\n                'data' => [\n                    'id' => '99',\n                    'type' => 'things',\n                    'attributes' => [\n                        'name' => 'test',\n                    ],\n                ],\n            ])\n            ->assertJsonMissing(['jsonapi', 'included']);\n    }\n\n    public function testSameModelWithTheSameResourceTypeIsDeduplicated()\n    {\n        $user = User::factory()->create();\n\n        $post1 = Post::factory()->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        $post2 = Post::factory()->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        Comment::factory()->create([\n            'post_id' => $post1->getKey(),\n            'user_id' => $user->getKey(),\n        ]);\n\n        Comment::factory()->create([\n            'post_id' => $post2->getKey(),\n            'user_id' => $user->getKey(),\n        ]);\n\n        // Both comments have the same commenter (User). Per the JSON:API spec, the same\n        // type+id pair should only appear once in included, even when referenced by\n        // multiple relationships. We expect 3 items: 2 comments + 1 user (deduped).\n        $response = $this->getJson('/posts?'.http_build_query(['include' => 'comments.commenter']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonCount(3, 'included');\n\n        $included = $response->json('included');\n        $types = array_column($included, 'type');\n\n        $this->assertCount(2, array_filter($types, fn (string $t) => $t === 'comments'));\n        $this->assertCount(1, array_filter($types, fn (string $t) => $t === 'users'));\n    }\n\n    public function testDifferentModelInstancesWithSameTypeAndIdAreDeduplicated()\n    {\n        $user = User::factory()->create();\n\n        // This route manually creates two different User model instances with the same ID and\n        // adds them both to the loadedRelationshipsMap. Per the JSON:API spec, they should\n        // be deduplicated since they have the same type+id, even though they're different object instances.\n        $response = $this->getJson(\"/users/{$user->getKey()}/with-duplicate-instances\")\n            ->assertHeader('Content-type', 'application/vnd.api+json');\n\n        $included = $response->json('included');\n\n        $this->assertCount(1, $included);\n        $this->assertSame('users', $included[0]['type']);\n        $this->assertSame((string) $user->getKey(), $included[0]['id']);\n    }\n\n    public function testSameModelOnDifferentResourcesIsNotDeduplicated()\n    {\n        $user = User::factory()->create();\n\n        $post = Post::factory()->create([\n            'user_id' => $user->getKey(),\n        ]);\n\n        // Post's author uses AuthorResource (\"authors\"), root uses UserResource (\"users\").\n        // We don't want to deduplicate them, as even though the underlying model is the\n        // same, they are different resource types, so they have different identity.\n        $this->getJson(\"/users/{$user->getKey()}/with-chaperone-posts?\".http_build_query(['include' => 'chaperonePosts.author']))\n            ->assertHeader('Content-type', 'application/vnd.api+json')\n            ->assertJsonPath('data.id', (string) $user->getKey())\n            ->assertJsonPath('data.type', 'users')\n            ->assertJsonPath('included.0.type', 'posts')\n            ->assertJsonPath('included.0.id', (string) $post->getKey())\n            ->assertJsonPath('included.1.type', 'authors')\n            ->assertJsonPath('included.1.id', (string) $user->getKey())\n            ->assertJsonCount(2, 'included');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/Resources/JsonApi/TestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\ArrayBackedJsonApiResource;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\Post;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\User;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\UserResource;\nuse Illuminate\\Tests\\Integration\\Http\\Resources\\JsonApi\\Fixtures\\UserWithArrayRelationshipResource;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithConfig('auth.providers.users.model', User::class)]\nabstract class TestCase extends \\Orchestra\\Testbench\\TestCase\n{\n    use LazilyRefreshDatabase;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        Model::shouldBeStrict(true);\n\n        parent::setUp();\n    }\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function defineRoutes($router)\n    {\n        $router->get('users', function () {\n            return User::paginate(5)->toResourceCollection();\n        });\n\n        $router->get('users/{userId}', function ($userId) {\n            return User::find($userId)->toResource();\n        });\n\n        $router->get('users/{userId}/with-chaperone-posts', function ($userId) {\n            return User::find($userId)->load('chaperonePosts')->toResource();\n        });\n\n        $router->get('posts', function () {\n            return Post::paginate(5)->toResourceCollection();\n        });\n\n        $router->get('posts/{postId}', function ($postId) {\n            return Post::find($postId)->toResource();\n        });\n\n        $router->get('things/{id}', function ($id) {\n            return new ArrayBackedJsonApiResource(['id' => (int) $id, 'name' => 'test']);\n        });\n\n        $router->get('users/{userId}/with-array-relationship', function ($userId) {\n            $resource = new UserWithArrayRelationshipResource(User::find($userId));\n            $resource->loadedRelationshipsMap = [\n                [new ArrayBackedJsonApiResource(['id' => 99, 'name' => 'test']), 'things', '99', true],\n            ];\n\n            return $resource;\n        });\n\n        $router->get('users/{userId}/with-duplicate-instances', function ($userId) {\n            $instance1 = User::find($userId);\n            $instance2 = User::find($userId);\n\n            $resource = new UserWithArrayRelationshipResource(User::find($userId));\n            $resource->loadedRelationshipsMap = [\n                [new UserResource($instance1), 'users', (string) $instance1->getKey(), true],\n                [new UserResource($instance2), 'users', (string) $instance2->getKey(), true],\n            ];\n\n            return $resource;\n        });\n    }\n\n    /** {@inheritdoc} */\n    protected function afterRefreshingDatabase()\n    {\n        require __DIR__.'/Fixtures/migrations.php';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/ResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Route;\nuse JsonSerializable;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ResponseTest extends TestCase\n{\n    public function testResponseWithInvalidJsonThrowsException()\n    {\n        $this->expectException('InvalidArgumentException');\n        $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded');\n\n        Route::get('/response', function () {\n            return (new Response())->setContent(new class implements JsonSerializable\n            {\n                public function jsonSerialize(): string\n                {\n                    return \"\\xB1\\x31\";\n                }\n            });\n        });\n\n        $this->withoutExceptionHandling();\n\n        $this->get('/response');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/ThrottleRequestsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\GlobalLimit;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Http\\Exceptions\\ThrottleRequestsException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Exceptions\\MissingRateLimiterException;\nuse Illuminate\\Routing\\Middleware\\ThrottleRequests;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\RateLimiter as RateLimiterFacade;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse Throwable;\n\n#[WithConfig('hashing.driver', 'bcrypt')]\n#[WithMigration]\nclass ThrottleRequestsTest extends TestCase\n{\n    use RefreshDatabase;\n\n    public function testLockOpensImmediatelyAfterDecay()\n    {\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 0));\n\n        Route::get('/', function () {\n            return 'yes';\n        })->middleware(ThrottleRequests::class.':2,1');\n\n        $response = $this->withoutExceptionHandling()->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(1, $response->headers->get('X-RateLimit-Remaining'));\n\n        $response = $this->withoutExceptionHandling()->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(0, $response->headers->get('X-RateLimit-Remaining'));\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 58));\n\n        try {\n            $this->withoutExceptionHandling()->get('/');\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ThrottleRequestsException::class, $e);\n            $this->assertEquals(429, $e->getStatusCode());\n            $this->assertEquals(2, $e->getHeaders()['X-RateLimit-Limit']);\n            $this->assertEquals(0, $e->getHeaders()['X-RateLimit-Remaining']);\n            $this->assertEquals(2, $e->getHeaders()['Retry-After']);\n            $this->assertEquals(Carbon::now()->addSeconds(2)->getTimestamp(), $e->getHeaders()['X-RateLimit-Reset']);\n        }\n    }\n\n    public function testLimitingUsingNamedLimiter()\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($request) {\n            return new GlobalLimit(2, 1);\n        });\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 0));\n\n        Route::get('/', function () {\n            return 'yes';\n        })->middleware(ThrottleRequests::class.':test');\n\n        $response = $this->withoutExceptionHandling()->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(1, $response->headers->get('X-RateLimit-Remaining'));\n\n        $response = $this->withoutExceptionHandling()->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(0, $response->headers->get('X-RateLimit-Remaining'));\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 58));\n\n        try {\n            $this->withoutExceptionHandling()->get('/');\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ThrottleRequestsException::class, $e);\n            $this->assertEquals(429, $e->getStatusCode());\n            $this->assertEquals(2, $e->getHeaders()['X-RateLimit-Limit']);\n            $this->assertEquals(0, $e->getHeaders()['X-RateLimit-Remaining']);\n            $this->assertEquals(2, $e->getHeaders()['Retry-After']);\n            $this->assertEquals(Carbon::now()->addSeconds(2)->getTimestamp(), $e->getHeaders()['X-RateLimit-Reset']);\n        }\n    }\n\n    public function testItCanGenerateDefinitionViaStaticMethod()\n    {\n        $signature = (string) ThrottleRequests::using('gold-tier');\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:gold-tier', $signature);\n\n        $signature = (string) ThrottleRequests::with(25);\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:25', $signature);\n\n        $signature = (string) ThrottleRequests::with(25, 2);\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:25,2', $signature);\n\n        $signature = (string) ThrottleRequests::with(25, 2, 'foo');\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:25,2,foo', $signature);\n\n        $signature = (string) ThrottleRequests::with(maxAttempts: 25, decayMinutes: 2, prefix: 'foo');\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:25,2,foo', $signature);\n\n        $signature = (string) ThrottleRequests::with(prefix: 'foo');\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ThrottleRequests:60,1,foo', $signature);\n    }\n\n    public static function perMinuteThrottlingDataSet()\n    {\n        return [\n            [ThrottleRequests::using('test')],\n            [ThrottleRequests::with(maxAttempts: 3, decayMinutes: 1)],\n            ['throttle:3,1'],\n        ];\n    }\n\n    #[DataProvider('perMinuteThrottlingDataSet')]\n    public function testItCanThrottlePerMinute(string $middleware)\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n        $rateLimiter->for('test', fn () => Limit::perMinute(3));\n        Route::get('/', fn () => 'ok')->middleware($middleware);\n\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n\n        // Make 3 requests, each a second apart, that should all be successful.\n\n        for ($i = 0; $i < 3; $i++) {\n            match ($i) {\n                0 => $this->assertSame('2000-01-01 00:00:00.000', Carbon::now()->toDateTimeString('m')),\n                1 => $this->assertSame('2000-01-01 00:00:01.000', Carbon::now()->toDateTimeString('m')),\n                2 => $this->assertSame('2000-01-01 00:00:02.000', Carbon::now()->toDateTimeString('m')),\n            };\n\n            $response = $this->get('/');\n            $response->assertOk();\n            $response->assertContent('ok');\n            $response->assertHeader('X-RateLimit-Limit', 3);\n            $response->assertHeader('X-RateLimit-Remaining', 3 - ($i + 1));\n\n            Carbon::setTestNow(Carbon::now()->addSecond());\n        }\n\n        // It is now 3 seconds past and we will make another request that\n        // should be rate limited.\n\n        $this->assertSame('2000-01-01 00:00:03.000', Carbon::now()->toDateTimeString('m'));\n\n        $response = $this->get('/');\n        $response->assertStatus(429);\n        $response->assertHeader('Retry-After', 57);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSeconds(57)->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We will now make it the very end of the minute, to check boundaries,\n        // and make another request that should be rate limited and tell us to\n        // try again in 1 second.\n        Carbon::setTestNow('2000-01-01 00:00:59.999');\n\n        $response = $this->get('/');\n        $response->assertStatus(429);\n        $response->assertHeader('Retry-After', 1);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSeconds(1)->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We now tick over into the next second. We should now be able to make\n        // requests again.\n        Carbon::setTestNow('2000-01-01 00:01:00.000');\n\n        $response = $this->get('/');\n        $response->assertOk();\n    }\n\n    public function testItCanThrottlePerSecond()\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n        $rateLimiter->for('test', fn () => Limit::perSecond(3));\n        Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test'));\n\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n\n        // Make 3 requests, each a 100ms apart, that should all be successful.\n\n        for ($i = 0; $i < 3; $i++) {\n            match ($i) {\n                0 => $this->assertSame('2000-01-01 00:00:00.000', Carbon::now()->toDateTimeString('m')),\n                1 => $this->assertSame('2000-01-01 00:00:00.100', Carbon::now()->toDateTimeString('m')),\n                2 => $this->assertSame('2000-01-01 00:00:00.200', Carbon::now()->toDateTimeString('m')),\n            };\n\n            $response = $this->get('/');\n            $response->assertOk();\n            $response->assertContent('ok');\n            $response->assertHeader('X-RateLimit-Limit', 3);\n            $response->assertHeader('X-RateLimit-Remaining', 3 - ($i + 1));\n\n            Carbon::setTestNow(Carbon::now()->addMilliseconds(100));\n        }\n\n        // It is now 300 milliseconds past and we will make another request\n        // that should be rate limited.\n\n        $this->assertSame('2000-01-01 00:00:00.300', Carbon::now()->toDateTimeString('m'));\n\n        $response = $this->get('/');\n        $response->assertStatus(429);\n        $response->assertHeader('Retry-After', 1);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSecond()->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We will now make it the very end of the minute, to check boundaries,\n        // and make another request that should be rate limited and tell us to\n        // try again in 1 second.\n        Carbon::setTestNow('2000-01-01 00:00:00.999');\n\n        $response = $this->get('/');\n        $response->assertHeader('Retry-After', 1);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSecond()->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We now tick over into the next second. We should now be able to make\n        // requests again.\n        Carbon::setTestNow('2000-01-01 00:00:01.000');\n\n        $response = $this->get('/');\n        $response->assertOk();\n    }\n\n    public function testItCanCombineRateLimitsWithoutSpecifyingUniqueKeys()\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n        $rateLimiter->for('test', fn () => [\n            Limit::perSecond(3),\n            Limit::perMinute(5),\n        ]);\n        Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test'));\n\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n\n        // Make 3 requests, each a 100ms apart, that should all be successful.\n\n        for ($i = 0; $i < 3; $i++) {\n            match ($i) {\n                0 => $this->assertSame('2000-01-01 00:00:00.000', Carbon::now()->toDateTimeString('m')),\n                1 => $this->assertSame('2000-01-01 00:00:00.100', Carbon::now()->toDateTimeString('m')),\n                2 => $this->assertSame('2000-01-01 00:00:00.200', Carbon::now()->toDateTimeString('m')),\n            };\n\n            $response = $this->get('/');\n            $response->assertOk();\n            $response->assertContent('ok');\n\n            Carbon::setTestNow(Carbon::now()->addMilliseconds(100));\n        }\n\n        // It is now 300 milliseconds past and we will make another request\n        // that should be rate limited.\n\n        $this->assertSame('2000-01-01 00:00:00.300', Carbon::now()->toDateTimeString('m'));\n\n        $response = $this->get('/');\n        $response->assertStatus(429);\n        $response->assertHeader('Retry-After', 1);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSecond()->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We will now make it the very end of the second, to check boundaries,\n        // and make another request that should be rate limited and tell us to\n        // try again in 1 second.\n        Carbon::setTestNow('2000-01-01 00:00:00.999');\n\n        $response = $this->get('/');\n        $response->assertHeader('Retry-After', 1);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSecond()->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 3);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n\n        // We now tick over into the next second. We should now be able to make\n        // another two requests before the per minute rate limit kicks in.\n        Carbon::setTestNow('2000-01-01 00:00:01.000');\n\n        for ($i = 0; $i < 2; $i++) {\n            match ($i) {\n                0 => $this->assertSame('2000-01-01 00:00:01.000', Carbon::now()->toDateTimeString('m')),\n                1 => $this->assertSame('2000-01-01 00:00:01.100', Carbon::now()->toDateTimeString('m')),\n            };\n\n            $response = $this->get('/');\n            $response->assertOk();\n            $response->assertContent('ok');\n\n            Carbon::setTestNow(Carbon::now()->addMilliseconds(100));\n        }\n\n        // The per minute rate limiter should now fail.\n\n        $this->assertSame('2000-01-01 00:00:01.200', Carbon::now()->toDateTimeString('m'));\n\n        $response = $this->get('/');\n        $response->assertStatus(429);\n        $response->assertHeader('Retry-After', 59);\n        $response->assertHeader('X-RateLimit-Reset', Carbon::now()->addSeconds(59)->timestamp);\n        $response->assertHeader('X-RateLimit-Limit', 5);\n        $response->assertHeader('X-RateLimit-Remaining', 0);\n    }\n\n    public function testItFailsIfNamedLimiterDoesNotExist()\n    {\n        $this->expectException(MissingRateLimiterException::class);\n        $this->expectExceptionMessage('Rate limiter [test] is not defined.');\n\n        Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test'));\n\n        $this->withoutExceptionHandling()->get('/');\n    }\n\n    public function testItFailsIfNamedLimiterDoesNotExistAndAuthenticatedUserDoesNotHaveFallbackProperty()\n    {\n        $this->expectException(MissingRateLimiterException::class);\n        $this->expectExceptionMessage('Rate limiter ['.User::class.'::rateLimiting] is not defined.');\n\n        Route::get('/', fn () => 'ok')->middleware(['auth', ThrottleRequests::using('rateLimiting')]);\n\n        // The reason we're enabling strict mode and actually creating a user is to ensure we never even try to access\n        // a property within the user model that does not exist. If an application is in strict mode and there is\n        // no matching rate limiter, it should throw a rate limiter exception, not a property access exception.\n        Model::shouldBeStrict();\n        $user = User::forceCreate([\n            'name' => 'Mateus',\n            'email' => 'mateus@example.org',\n            'password' => 'password',\n        ]);\n\n        $this->withoutExceptionHandling()->actingAs($user)->get('/');\n    }\n\n    public function testItFallbacksToUserPropertyWhenThereIsNoNamedLimiterWhenAuthenticated()\n    {\n        $user = User::make()->forceFill([\n            'rateLimiting' => 1,\n        ]);\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 0));\n\n        // The `rateLimiting` named limiter does not exist, but the `rateLimiting` property on the\n        // User model does, so it should fallback to that property within the authenticated model.\n        Route::get('/', fn () => 'yes')->middleware(['auth', ThrottleRequests::using('rateLimiting')]);\n\n        $response = $this->withoutExceptionHandling()->actingAs($user)->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(1, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(0, $response->headers->get('X-RateLimit-Remaining'));\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 58));\n\n        try {\n            $this->withoutExceptionHandling()->actingAs($user)->get('/');\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ThrottleRequestsException::class, $e);\n            $this->assertEquals(429, $e->getStatusCode());\n            $this->assertEquals(1, $e->getHeaders()['X-RateLimit-Limit']);\n            $this->assertEquals(0, $e->getHeaders()['X-RateLimit-Remaining']);\n            $this->assertEquals(2, $e->getHeaders()['Retry-After']);\n            $this->assertEquals(Carbon::now()->addSeconds(2)->getTimestamp(), $e->getHeaders()['X-RateLimit-Reset']);\n        }\n    }\n\n    public function testItFallbacksToUserAccessorWhenThereIsNoNamedLimiterWhenAuthenticated()\n    {\n        $user = UserWithAccessor::make();\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 0));\n\n        // The `rateLimiting` named limiter does not exist, but the `rateLimiting` accessor (not property!)\n        // on the User model does, so it should fallback to that accessor within the authenticated model.\n        Route::get('/', fn () => 'yes')->middleware(['auth', ThrottleRequests::using('rateLimiting')]);\n\n        $response = $this->withoutExceptionHandling()->actingAs($user)->get('/');\n        $this->assertSame('yes', $response->getContent());\n        $this->assertEquals(1, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(0, $response->headers->get('X-RateLimit-Remaining'));\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1, 0, 0, 58));\n\n        try {\n            $this->withoutExceptionHandling()->actingAs($user)->get('/');\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(ThrottleRequestsException::class, $e);\n            $this->assertEquals(429, $e->getStatusCode());\n            $this->assertEquals(1, $e->getHeaders()['X-RateLimit-Limit']);\n            $this->assertEquals(0, $e->getHeaders()['X-RateLimit-Remaining']);\n            $this->assertEquals(2, $e->getHeaders()['Retry-After']);\n            $this->assertEquals(Carbon::now()->addSeconds(2)->getTimestamp(), $e->getHeaders()['X-RateLimit-Reset']);\n        }\n    }\n\n    public function testMultipleDistinctKeysDoNotOverThrottle()\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n        $rateLimiter->for('test', fn () => [\n            Limit::perMinute(3)->by('minute-key'),\n            Limit::perSecond(1)->by('second-key'),\n            Limit::perDay(4)->by('day-key'),\n        ]);\n        Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test'));\n\n        // Running 2 requests in a single second is not allowed.\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n        $this->get('/')->assertOk();\n        $this->get('/')->assertStatus(429);\n\n        // After a second, the per-second limit should resets.\n        Carbon::setTestNow('2000-01-01 00:00:01.000');\n        $this->get('/')->assertOk();\n        $this->get('/')->assertStatus(429);\n\n        // A third request is allowed in the same minute.\n        Carbon::setTestNow('2000-01-01 00:00:02.000');\n        $this->get('/')->assertOk();\n\n        // A fourth request is not allowed in the same minute.\n        Carbon::setTestNow('2000-01-01 00:00:03.000');\n        $this->get('/')->assertStatus(429);\n\n        // A fourth request is allowed in the same day, but not a fifth.\n        Carbon::setTestNow('2000-01-01 01:00:00.000');\n        $this->get('/')->assertOk();\n        $this->get('/')->assertStatus(429);\n\n        // The next day, all limits should reset.\n        Carbon::setTestNow('2000-01-02 00:01:00.000');\n        $this->get('/')->assertOk();\n        Carbon::setTestNow('2000-01-02 00:01:01.000');\n        $this->get('/')->assertOk();\n        Carbon::setTestNow('2000-01-02 00:01:02.000');\n        $this->get('/')->assertOk();\n        Carbon::setTestNow('2000-01-02 00:01:03.000');\n        $this->get('/')->assertStatus(429);\n        Carbon::setTestNow('2000-01-02 01:00:00.000');\n        $this->get('/')->assertOk();\n        $this->get('/')->assertStatus(429);\n    }\n\n    public function testLimitOrderDoesNotAffectBehavior()\n    {\n        $rateLimiter = Container::getInstance()->make(RateLimiter::class);\n        $rateLimiter->for('test', fn () => [\n            Limit::perDay(4)->by('day-key'),\n            Limit::perMinute(3)->by('minute-key'),\n        ]);\n        Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test'));\n\n        Carbon::setTestNow('2000-01-01 00:00:00.000');\n\n        // Make 3 requests, each a second apart, that should all be successful.\n        for ($i = 0; $i < 3; $i++) {\n            $this->get('/')->assertOk();\n            Carbon::setTestNow(Carbon::now()->addSecond());\n        }\n\n        $this->assertSame('2000-01-01 00:00:03.000', Carbon::now()->toDateTimeString('m'));\n        $this->get('/')->assertStatus(429);\n\n        // A fourth request is allowed in the same day but not a fifth.\n        Carbon::setTestNow('2000-01-01 00:01:00.000');\n        $this->get('/')->assertOk();\n        $this->get('/')->assertStatus(429);\n\n        // After a day, both limits should reset.\n        Carbon::setTestNow('2000-01-02 00:00:00.000');\n        $this->get('/')->assertOk();\n    }\n\n    public function testItCanThrottleBasedOnResponse()\n    {\n        RateLimiterFacade::for('throttle-not-found', function (Request $request) {\n            return Limit::perMinute(1)->after(fn ($response) => $response->status() === 404);\n        });\n        Route::get('/', fn () => match (request('status')) {\n            '404' => abort(404),\n            default => 'ok',\n        })->middleware(ThrottleRequests::using('throttle-not-found'));\n\n        $this->travelTo('2000-01-01 00:00:00');\n        $this->get('?status=404')->assertNotFound();\n        $this->get('?status=404')->assertTooManyRequests();\n        $this->get('?status=404')->assertTooManyRequests();\n\n        $this->travelTo('2000-01-01 00:00:59');\n        $this->get('?status=404')->assertTooManyRequests();\n        $this->get('?status=404')->assertTooManyRequests();\n\n        $this->travelTo('2000-01-01 00:01:00');\n        $this->get('?status=404')->assertNotFound();\n        $this->get('?status=404')->assertTooManyRequests();\n        $this->get('?status=404')->assertTooManyRequests();\n\n        $this->travelTo('2000-01-01 00:01:59');\n        $this->get('?status=404')->assertTooManyRequests();\n        $this->get('?status=404')->assertTooManyRequests();\n\n        $this->travelTo('2000-01-01 00:02:00');\n        $this->get('?status=404')->assertNotFound();\n        $this->get('?status=404')->assertTooManyRequests();\n        $this->get('?status=404')->assertTooManyRequests();\n    }\n\n    public function testItDoesNotHitLimiterUntilResponseHasBeenGenerated()\n    {\n        ThrottleRequests::shouldHashKeys(false);\n        RateLimiterFacade::for('throttle-not-found', function (Request $request) {\n            return Limit::perMinute(1)->after(fn ($response) => $response->status() === 404);\n        });\n        $duringRequest = null;\n        Route::get('/', function () use (&$duringRequest) {\n            $duringRequest = [\n                Cache::get('throttle-not-found:'),\n                Cache::get('throttle-not-found::timer'),\n            ];\n\n            abort(404);\n        })->middleware(ThrottleRequests::using('throttle-not-found'));\n\n        $this->travelTo('2000-01-01 00:00:00');\n        $this->get('?status=404')->assertNotFound();\n\n        $this->assertSame([null, null], $duringRequest);\n        $this->assertSame([1, 946684860], [\n            Cache::get('throttle-not-found:'),\n            Cache::get('throttle-not-found::timer'),\n        ]);\n    }\n\n    public function testItReturnsConfiguredResponseWhenUsingAfterLimit(): void\n    {\n        ThrottleRequests::shouldHashKeys(false);\n        RateLimiterFacade::for('throttle-not-found', function (Request $request) {\n            return Limit::perMinute(1)\n                ->after(fn ($response) => $response->status() === 404)\n                ->response(fn () => response('ah ah ah', status: 429));\n        });\n        Route::get('/', fn () => abort(404))->middleware(ThrottleRequests::using('throttle-not-found'));\n\n        $this->travelTo('2000-01-01 00:00:00');\n        $this->get('?status=404')->assertNotFound();\n        $this->get('?status=404')->assertTooManyRequests()->assertContent('ah ah ah');\n    }\n}\n\nclass UserWithAccessor extends User\n{\n    public function getRateLimitingAttribute(): int\n    {\n        return 1;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Http/ThrottleRequestsWithRedisTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Http;\n\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Middleware\\ThrottleRequestsWithRedis;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\RateLimiter;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Throwable;\n\n#[WithConfig('hashing.driver', 'bcrypt')]\nclass ThrottleRequestsWithRedisTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    public function testLockOpensImmediatelyAfterDecay()\n    {\n        $this->ifRedisAvailable(function () {\n            $now = Carbon::now();\n\n            Carbon::setTestNow($now);\n\n            Route::get('/', function () {\n                return 'yes';\n            })->middleware(ThrottleRequestsWithRedis::class.':2,1');\n\n            $response = $this->withoutExceptionHandling()->get('/');\n            $this->assertSame('yes', $response->getContent());\n            $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n            $this->assertEquals(1, $response->headers->get('X-RateLimit-Remaining'));\n\n            $response = $this->withoutExceptionHandling()->get('/');\n            $this->assertSame('yes', $response->getContent());\n            $this->assertEquals(2, $response->headers->get('X-RateLimit-Limit'));\n            $this->assertEquals(0, $response->headers->get('X-RateLimit-Remaining'));\n\n            Carbon::setTestNow($finish = $now->addSeconds(58));\n\n            try {\n                $this->withoutExceptionHandling()->get('/');\n            } catch (Throwable $e) {\n                $this->assertEquals(429, $e->getStatusCode());\n                $this->assertEquals(2, $e->getHeaders()['X-RateLimit-Limit']);\n                $this->assertEquals(0, $e->getHeaders()['X-RateLimit-Remaining']);\n                // $this->assertTrue(in_array($e->getHeaders()['Retry-After'], [2, 3]));\n                // $this->assertTrue(in_array($e->getHeaders()['X-RateLimit-Reset'], [$finish->getTimestamp() + 2, $finish->getTimestamp() + 3]));\n            }\n        });\n    }\n\n    public function testItCanThrottleBasedOnResponse()\n    {\n        $this->ifRedisAvailable(function () {\n            RateLimiter::for('throttle-not-found', function (Request $request) {\n                return Limit::perMinute(1)->after(fn ($response) => $response->status() === 404);\n            });\n            Route::get('/', fn () => match (request('status')) {\n                '404' => abort(404),\n                default => 'ok',\n            })->middleware(ThrottleRequestsWithRedis::using('throttle-not-found'));\n\n            // Non-matching responses should not count toward the limit.\n            $this->get('?status=200')->assertOk();\n            $this->get('?status=200')->assertOk();\n            $this->get('?status=200')->assertOk();\n\n            // A matching response should count and exhaust the limit.\n            $this->get('?status=404')->assertNotFound();\n\n            // Now throttled — even non-matching requests are blocked.\n            $this->get('?status=200')->assertTooManyRequests();\n            $this->get('?status=404')->assertTooManyRequests();\n        });\n    }\n\n    public function testItReturnsConfiguredResponseWhenUsingAfterLimit(): void\n    {\n        $this->ifRedisAvailable(function () {\n            RateLimiter::for('throttle-not-found', function (Request $request) {\n                return Limit::perMinute(1)\n                    ->after(fn ($response) => $response->status() === 404)\n                    ->response(fn () => response('ah ah ah', status: 429));\n            });\n            Route::get('/', fn () => abort(404))->middleware(ThrottleRequestsWithRedis::using('throttle-not-found'));\n\n            $this->get('/')->assertNotFound();\n            $this->get('/')->assertTooManyRequests()->assertContent('ah ah ah');\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Log/ContextIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Log;\n\nuse ErrorException;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Support\\Facades\\Context;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\n#[WithMigration]\nclass ContextIntegrationTest extends TestCase\n{\n    use LazilyRefreshDatabase;\n\n    public function test_it_can_hydrate_null()\n    {\n        Context::hydrate(null);\n        $this->assertEquals([], Context::all());\n    }\n\n    public function test_it_handles_eloquent()\n    {\n        $user = UserFactory::new()->create(['name' => 'Tim']);\n\n        Context::add('model', $user);\n        Context::add('number', 55);\n        $dehydrated = Context::dehydrate();\n\n        $this->assertSame([\n            'data' => [\n                'model' => 'O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:31:\"Illuminate\\Foundation\\Auth\\User\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}',\n                'number' => 'i:55;',\n            ],\n            'hidden' => [],\n        ], $dehydrated);\n\n        Context::flush();\n        $this->assertNull(Context::get('model'));\n        $this->assertNull(Context::get('number'));\n\n        Context::hydrate($dehydrated);\n        $this->assertTrue($user->is(Context::get('model')));\n        $this->assertNotSame($user, Context::get('model'));\n        $this->assertSame(55, Context::get('number'));\n    }\n\n    public function test_it_ignores_deleted_models_when_hydrating()\n    {\n        $user = UserFactory::new()->create(['name' => 'Tim']);\n\n        Context::add('model', $user);\n        Context::add('number', 55);\n\n        $dehydrated = Context::dehydrate();\n        $user->delete();\n\n        Context::flush();\n        $this->assertNull(Context::get('model'));\n        $this->assertNull(Context::get('number'));\n\n        Context::hydrate($dehydrated);\n        $this->assertNull(Context::get('model'));\n        $this->assertSame(55, Context::get('number'));\n    }\n\n    public function test_it_ignores_deleted_models_within_collections_when_hydrating()\n    {\n        $user = UserFactory::new()->create(['name' => 'Tim']);\n\n        Context::add('models', User::all());\n        Context::add('number', 55);\n\n        $dehydrated = Context::dehydrate();\n        $user->delete();\n\n        Context::flush();\n        $this->assertNull(Context::get('model'));\n        $this->assertNull(Context::get('number'));\n\n        Context::hydrate($dehydrated);\n        $this->assertInstanceOf(EloquentCollection::class, Context::get('models'));\n        $this->assertCount(0, Context::get('models'));\n        $this->assertSame(55, Context::get('number'));\n    }\n\n    public function test_it_throws_on_incomplete_classes()\n    {\n        $dehydrated = [\n            'data' => [\n                'model' => 'O:18:\"App\\MyContextClass\":0:{}',\n            ],\n            'hidden' => [],\n        ];\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Value is incomplete class: {\"__PHP_Incomplete_Class_Name\":\"App\\\\\\\\MyContextClass\"}');\n\n        Context::hydrate($dehydrated);\n    }\n\n    public function test_it_throws_generic_unserialize_exceptions()\n    {\n        $dehydrated = [\n            'data' => [\n                'model' => 'bad data',\n            ],\n            'hidden' => [],\n        ];\n\n        $this->expectException(ErrorException::class);\n        $this->expectExceptionMessage('unserialize(): Error at offset 0 of 8 bytes');\n\n        Context::hydrate($dehydrated);\n    }\n\n    public function test_it_can_handle_unserialize_exceptions_manually()\n    {\n        $dehydrated = [\n            'data' => [\n                'model' => 'bad data',\n            ],\n            'hidden' => [\n                'other' => 'more bad data',\n            ],\n        ];\n\n        Context::handleUnserializeExceptionsUsing(function ($e, $key, $value, $hidden) {\n            if ($key === 'model') {\n                $this->assertSame('bad data', $value);\n                $this->assertFalse($hidden);\n\n                return 'replaced value 1';\n            } else {\n                $this->assertSame('more bad data', $value);\n                $this->assertTrue($hidden);\n\n                return 'replaced value 2';\n            }\n        });\n        Context::hydrate($dehydrated);\n\n        $this->assertSame('replaced value 1', Context::get('model'));\n        $this->assertSame('replaced value 2', Context::getHidden('other'));\n\n        Context::handleUnserializeExceptionsUsing(null);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Log/LoggingIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Log;\n\nuse Illuminate\\Log\\Events\\MessageLogged;\nuse Illuminate\\Log\\Logger;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Log;\nuse Orchestra\\Testbench\\TestCase;\n\nclass LoggingIntegrationTest extends TestCase\n{\n    public function testLoggingCanBeRunWithoutEncounteringExceptions()\n    {\n        $this->expectNotToPerformAssertions();\n\n        Log::info('Hello World');\n    }\n\n    public function testCallingLoggerDirectlyDispatchesOneEvent()\n    {\n        Event::fake([MessageLogged::class]);\n\n        $this->app->make(Logger::class)->debug('my debug message');\n\n        Event::assertDispatchedTimes(MessageLogged::class, 1);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/AttachingFromStorageTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Orchestra\\Testbench\\TestCase;\n\nclass AttachingFromStorageTest extends TestCase\n{\n    public function testItCanAttachFromStorage()\n    {\n        Storage::disk('local')->put('/dir/foo.png', 'expected body contents');\n        $mail = new MailMessage();\n        $attachment = Attachment::fromStorageDisk('local', '/dir/foo.png')\n            ->as('bar')\n            ->withMime('text/css');\n\n        $attachment->attachTo($mail);\n\n        $this->assertSame([\n            'data' => 'expected body contents',\n            'name' => 'bar',\n            'options' => [\n                'mime' => 'text/css',\n            ],\n        ], $mail->rawAttachments[0]);\n\n        Storage::disk('local')->delete('/dir/foo.png');\n    }\n\n    public function testItCanAttachFromStorageAndFallbackToStorageNameAndMime()\n    {\n        Storage::disk()->put('/dir/foo.png', 'expected body contents');\n        $mail = new MailMessage();\n        $attachment = Attachment::fromStorageDisk('local', '/dir/foo.png');\n\n        $attachment->attachTo($mail);\n\n        $this->assertSame([\n            'data' => 'expected body contents',\n            'name' => 'foo.png',\n            'options' => [\n                // when using \"prefer-lowest\" the local filesystem driver will\n                // not detect the mime type based on the extension and will\n                // instead fallback to \"text/plain\".\n                'mime' => class_exists(\\League\\Flysystem\\Local\\FallbackMimeTypeDetector::class)\n                    ? 'image/png'\n                    : 'text/plain',\n            ],\n        ], $mail->rawAttachments[0]);\n\n        Storage::disk('local')->delete('/dir/foo.png');\n    }\n\n    public function testItCanChainAttachWithMailMessage()\n    {\n        Storage::disk('local')->put('/dir/foo.png', 'expected body contents');\n        $message = new MailMessage();\n\n        $result = $message->attach(\n            Attachment::fromStorageDisk('local', '/dir/foo.png')\n        );\n\n        $this->assertSame($message, $result);\n    }\n\n    public function testItCanCheckForStorageBasedAttachments()\n    {\n        Storage::disk()->put('/dir/foo.png', 'expected body contents');\n        $mailable = new Mailable();\n        $mailable->attach(Attachment::fromStorage('/dir/foo.png'));\n\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromStorage('/dir/foo.png')));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/basic.blade.php",
    "content": "# My basic content\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/embed-data.blade.php",
    "content": "Embed data content: {{ $message->embedData('foo', 'foo.jpg', 'image/png') }}\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/embed-image.blade.php",
    "content": "Embedded image: <img src=\"{{ $message->embed($image) }}\" alt=\"Embedded test image\" />\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/embed-multiline.blade.php",
    "content": "Embed multiline content: <img\n    src=\"{{ $message->embedData('foo', 'foo.jpg', 'image/png') }}\"\n    alt=\"multiline image\"\n>\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/embed.blade.php",
    "content": "Embed file: {{ basename(__FILE__) }}\n\nEmbed content: {{ $message->embed(__FILE__) }}\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/mail/taylor.blade.php",
    "content": "// ...\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/message-with-template.blade.php",
    "content": "@component('mail::message')\n*Hi* {{ $user->name }}\n\n@endcomponent\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/message.blade.php",
    "content": "My message is: {{ $message }}.\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/table-with-template.blade.php",
    "content": "<x-mail::message subcopy=\"This is a subcopy\">\n\n<x-mail::table>\n*Hi* {{ $user->name }}\n\n| Laravel       | Table         | Example       |\n| ------------- | :-----------: | ------------: |\n| Col 2 is      | Centered      | $10           |\n| Col 3 is      | Right-Aligned | $20           |\n</x-mail::table>\n\n</x-mail::message>\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/text.blade.php",
    "content": "My basic text view"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/timestamp.blade.php",
    "content": "{{__('nom')}} {{ Illuminate\\Support\\Carbon::tomorrow()->diffForHumans() }}\n"
  },
  {
    "path": "tests/Integration/Mail/Fixtures/view.blade.php",
    "content": "{{__('nom')}}\n"
  },
  {
    "path": "tests/Integration/Mail/MailableTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nabstract class MailableTestCase extends TestCase\n{\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n    }\n\n    #[DataProvider('markdownEncodedDataProvider')]\n    public function testItCanAssertMarkdownEncodedString($given, $expected)\n    {\n        $mailable = new class($given) extends Mailable\n        {\n            public function __construct(public string $message)\n            {\n                //\n            }\n\n            public function envelope()\n            {\n                return new Envelope(\n                    subject: 'My basic title',\n                );\n            }\n\n            public function content()\n            {\n                return new Content(\n                    markdown: 'message',\n                );\n            }\n        };\n\n        $mailable->assertSeeInHtml($expected, false);\n    }\n\n    public static function markdownEncodedDataProvider()\n    {\n        yield ['[Laravel](https://laravel.com)', 'My message is: [Laravel](https://laravel.com)'];\n\n        yield [\n            '![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)',\n            'My message is: ![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)',\n        ];\n\n        yield [\n            'Visit https://laravel.com/docs to browse the documentation',\n            'My message is: Visit https://laravel.com/docs to browse the documentation',\n        ];\n\n        yield [\n            'Visit <https://laravel.com/docs> to browse the documentation',\n            'My message is: Visit &lt;https://laravel.com/docs&gt; to browse the documentation',\n        ];\n\n        yield [\n            'Visit <span>https://laravel.com/docs</span> to browse the documentation',\n            'My message is: Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation',\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/MailableWithSecuredEncodingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Markdown;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass MailableWithSecuredEncodingTest extends MailableTestCase\n{\n    use LazilyRefreshDatabase;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        Markdown::withSecuredEncoding();\n    }\n\n    #[WithMigration]\n    #[DataProvider('markdownEncodedTemplateDataProvider')]\n    public function testItCanAssertMarkdownEncodedStringUsingTemplate($given, $expected)\n    {\n        $user = UserFactory::new()->create([\n            'name' => $given,\n        ]);\n\n        $mailable = new class($user) extends Mailable\n        {\n            public $theme = 'taylor';\n\n            public function __construct(public User $user)\n            {\n                //\n            }\n\n            public function build()\n            {\n                return $this->markdown('message-with-template');\n            }\n        };\n\n        $mailable->assertSeeInHtml($expected, false);\n    }\n\n    #[WithMigration]\n    #[DataProvider('markdownEncodedTemplateDataProvider')]\n    public function testItCanAssertMarkdownEncodedStringUsingTemplateWithTable($given, $expected)\n    {\n        $user = UserFactory::new()->create([\n            'name' => $given,\n        ]);\n\n        $mailable = new class($user) extends Mailable\n        {\n            public $theme = 'taylor';\n\n            public function __construct(public User $user)\n            {\n                //\n            }\n\n            public function build()\n            {\n                return $this->markdown('table-with-template');\n            }\n        };\n\n        $mailable->assertSeeInHtml($expected, false);\n        $mailable->assertSeeInHtml('<p>This is a subcopy</p>', false);\n        $mailable->assertSeeInHtml(<<<'TABLE'\n<table>\n<thead>\n<tr>\n<th>Laravel</th>\n<th align=\"center\">Table</th>\n<th align=\"right\">Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Col 2 is</td>\n<td align=\"center\">Centered</td>\n<td align=\"right\">$10</td>\n</tr>\n<tr>\n<td>Col 3 is</td>\n<td align=\"center\">Right-Aligned</td>\n<td align=\"right\">$20</td>\n</tr>\n</tbody>\n</table>\nTABLE, false);\n    }\n\n    public static function markdownEncodedTemplateDataProvider()\n    {\n        yield ['[Laravel](https://laravel.com)', '<em>Hi</em> [Laravel](https://laravel.com)'];\n\n        yield [\n            '![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)',\n            '<em>Hi</em> ![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)',\n        ];\n\n        yield [\n            'Visit https://laravel.com/docs to browse the documentation',\n            '<em>Hi</em> Visit https://laravel.com/docs to browse the documentation',\n        ];\n\n        yield [\n            'Visit <https://laravel.com/docs> to browse the documentation',\n            '<em>Hi</em> Visit &lt;https://laravel.com/docs&gt; to browse the documentation',\n        ];\n\n        yield [\n            'Visit <span>https://laravel.com/docs</span> to browse the documentation',\n            '<em>Hi</em> Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation',\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/MailableWithoutSecuredEncodingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Markdown;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass MailableWithoutSecuredEncodingTest extends MailableTestCase\n{\n    use LazilyRefreshDatabase;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        Markdown::withoutSecuredEncoding();\n    }\n\n    #[WithMigration]\n    #[DataProvider('markdownEncodedTemplateDataProvider')]\n    public function testItCanAssertMarkdownEncodedStringUsingTemplate($given, $expected)\n    {\n        $user = UserFactory::new()->create([\n            'name' => $given,\n        ]);\n\n        $mailable = new class($user) extends Mailable\n        {\n            public $theme = 'taylor';\n\n            public function __construct(public User $user)\n            {\n                //\n            }\n\n            public function build()\n            {\n                return $this->markdown('message-with-template');\n            }\n        };\n\n        $mailable->assertSeeInHtml($expected, false);\n    }\n\n    #[WithMigration]\n    #[DataProvider('markdownEncodedTemplateDataProvider')]\n    public function testItCanAssertMarkdownEncodedStringUsingTemplateWithTable($given, $expected)\n    {\n        $user = UserFactory::new()->create([\n            'name' => $given,\n        ]);\n\n        $mailable = new class($user) extends Mailable\n        {\n            public $theme = 'taylor';\n\n            public function __construct(public User $user)\n            {\n                //\n            }\n\n            public function build()\n            {\n                return $this->markdown('table-with-template');\n            }\n        };\n\n        $mailable->assertSeeInHtml($expected, false);\n        $mailable->assertSeeInHtml('<p>This is a subcopy</p>', false);\n        $mailable->assertSeeInHtml(<<<'TABLE'\n<table>\n<thead>\n<tr>\n<th>Laravel</th>\n<th align=\"center\">Table</th>\n<th align=\"right\">Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Col 2 is</td>\n<td align=\"center\">Centered</td>\n<td align=\"right\">$10</td>\n</tr>\n<tr>\n<td>Col 3 is</td>\n<td align=\"center\">Right-Aligned</td>\n<td align=\"right\">$20</td>\n</tr>\n</tbody>\n</table>\nTABLE, false);\n    }\n\n    public static function markdownEncodedTemplateDataProvider()\n    {\n        yield ['[Laravel](https://laravel.com)', '<p><em>Hi</em> <a href=\"https://laravel.com\">Laravel</a></p>'];\n\n        yield [\n            '![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)',\n            '<p><em>Hi</em> <img src=\"https://laravel.com/assets/img/welcome/background.svg\" alt=\"Welcome to Laravel\"></p>',\n        ];\n\n        yield [\n            'Visit https://laravel.com/docs to browse the documentation',\n            '<em>Hi</em> Visit https://laravel.com/docs to browse the documentation',\n        ];\n\n        yield [\n            'Visit <https://laravel.com/docs> to browse the documentation',\n            '<em>Hi</em> Visit &lt;https://laravel.com/docs&gt; to browse the documentation',\n        ];\n\n        yield [\n            'Visit <span>https://laravel.com/docs</span> to browse the documentation',\n            '<em>Hi</em> Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation',\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/MarkdownParserTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Support\\EncodedHtmlString;\nuse Illuminate\\Support\\HtmlString;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass MarkdownParserTest extends TestCase\n{\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        Markdown::flushState();\n        EncodedHtmlString::flushState();\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('markdownDataProvider')]\n    public function testItCanParseMarkdownString($given, $expected)\n    {\n        tap(Markdown::parse($given), function ($html) use ($expected) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n            $this->assertSame((string) $html, (string) $html->toHtml());\n        });\n    }\n\n    #[DataProvider('markdownEncodedDataProvider')]\n    public function testItCanParseMarkdownEncodedString($given, $expected)\n    {\n        tap(Markdown::parse($given, encoded: true), function ($html) use ($expected) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n        });\n    }\n\n    public static function markdownDataProvider()\n    {\n        yield ['[Laravel](https://laravel.com)', '<p><a href=\"https://laravel.com\">Laravel</a></p>'];\n        yield ['\\[Laravel](https://laravel.com)', '<p>[Laravel](https://laravel.com)</p>'];\n        yield ['![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)', '<p><img src=\"https://laravel.com/assets/img/welcome/background.svg\" alt=\"Welcome to Laravel\" /></p>'];\n        yield ['!\\[Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)', '<p>![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)</p>'];\n        yield ['Visit https://laravel.com/docs to browse the documentation', '<p>Visit https://laravel.com/docs to browse the documentation</p>'];\n        yield ['Visit <https://laravel.com/docs> to browse the documentation', '<p>Visit <a href=\"https://laravel.com/docs\">https://laravel.com/docs</a> to browse the documentation</p>'];\n        yield ['Visit <span>https://laravel.com/docs</span> to browse the documentation', '<p>Visit <span>https://laravel.com/docs</span> to browse the documentation</p>'];\n    }\n\n    public static function markdownEncodedDataProvider()\n    {\n        yield [new EncodedHtmlString('[Laravel](https://laravel.com)'), '<p>[Laravel](https://laravel.com)</p>'];\n\n        yield [\n            new EncodedHtmlString('![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)'),\n            '<p>![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)</p>',\n        ];\n\n        yield [\n            new EncodedHtmlString('Visit https://laravel.com/docs to browse the documentation'),\n            '<p>Visit https://laravel.com/docs to browse the documentation</p>',\n        ];\n\n        yield [\n            new EncodedHtmlString('Visit <https://laravel.com/docs> to browse the documentation'),\n            '<p>Visit &lt;https://laravel.com/docs&gt; to browse the documentation</p>',\n        ];\n\n        yield [\n            new EncodedHtmlString('Visit <span>https://laravel.com/docs</span> to browse the documentation'),\n            '<p>Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation</p>',\n        ];\n\n        yield [\n            new EncodedHtmlString(new HtmlString('Visit <span>https://laravel.com/docs</span> to browse the documentation')),\n            '<p>Visit <span>https://laravel.com/docs</span> to browse the documentation</p>',\n        ];\n\n        yield [\n            '![Welcome to Laravel](https://laravel.com/assets/img/welcome/background.svg)<br />'.new EncodedHtmlString('Visit <span>https://laravel.com/docs</span> to browse the documentation'),\n            '<p><img src=\"https://laravel.com/assets/img/welcome/background.svg\" alt=\"Welcome to Laravel\" /><br />Visit &lt;span&gt;https://laravel.com/docs&lt;/span&gt; to browse the documentation</p>',\n        ];\n    }\n\n    public function testItCanParseMarkdownWithCustomExtensionsViaConfig(): void\n    {\n        $this->configureMarkdownExtensions([\n            \\League\\CommonMark\\Extension\\Strikethrough\\StrikethroughExtension::class,\n        ]);\n\n        tap(Markdown::parse('~~strikethrough text~~'), function ($html) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $expected = '<p><del>strikethrough text</del></p>';\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n            $this->assertSame((string) $html, (string) $html->toHtml());\n        });\n    }\n\n    public function testItCanParseMarkdownWithoutCustomExtensionsDoesNotApplyThem(): void\n    {\n        $this->configureMarkdownExtensions([]);\n\n        tap(Markdown::parse('~~strikethrough text~~'), function ($html) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $expected = '<p>~~strikethrough text~~</p>';\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n            $this->assertSame((string) $html, (string) $html->toHtml());\n        });\n    }\n\n    public function testItCanParseMarkdownWithMultipleCustomExtensions(): void\n    {\n        $this->configureMarkdownExtensions([\n            \\League\\CommonMark\\Extension\\Strikethrough\\StrikethroughExtension::class,\n            \\League\\CommonMark\\Extension\\TaskList\\TaskListExtension::class,\n        ]);\n\n        tap(Markdown::parse('~~strikethrough~~'), function ($html) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $expected = '<p><del>strikethrough</del></p>';\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n            $this->assertSame((string) $html, (string) $html->toHtml());\n        });\n\n        tap(Markdown::parse('- [ ] Task item'), function ($html) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $expected = \"<ul>\\n<li><input disabled=\\\"\\\" type=\\\"checkbox\\\"> Task item</li>\\n</ul>\";\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n            $this->assertSame((string) $html, (string) $html->toHtml());\n        });\n    }\n\n    public function testItCanParseMarkdownEncodedStringWithCustomExtensions(): void\n    {\n        $this->configureMarkdownExtensions([\n            \\League\\CommonMark\\Extension\\Strikethrough\\StrikethroughExtension::class,\n        ]);\n\n        tap(Markdown::parse(new EncodedHtmlString('~~strikethrough text~~'), encoded: true), function ($html) {\n            $this->assertInstanceOf(HtmlString::class, $html);\n\n            $expected = '<p><del>strikethrough text</del></p>';\n\n            $this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);\n        });\n    }\n\n    /**\n     * @param  array<int, class-string<\\League\\CommonMark\\Extension\\ExtensionInterface>>  $extensions\n     */\n    protected function configureMarkdownExtensions(array $extensions): void\n    {\n        $this->app['config']->set('mail.markdown.extensions', $extensions);\n\n        $this->app->forgetInstance(Markdown::class);\n        $this->app->make(Markdown::class);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/RenderingMailWithLocaleTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RenderingMailWithLocaleTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.locale', 'en');\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n\n        $app['translator']->setLoaded([\n            '*' => [\n                '*' => [\n                    'en' => ['nom' => 'name'],\n                    'es' => ['nom' => 'nombre'],\n                ],\n            ],\n        ]);\n    }\n\n    public function testMailableRendersInDefaultLocale()\n    {\n        $mail = new RenderedTestMail;\n\n        $this->assertStringContainsString('name', $mail->render());\n    }\n\n    public function testMailableRendersInSelectedLocale()\n    {\n        $mail = (new RenderedTestMail)->locale('es');\n\n        $this->assertStringContainsString('nombre', $mail->render());\n    }\n\n    public function testMailableRendersInAppSelectedLocale()\n    {\n        $this->app->setLocale('es');\n\n        $mail = new RenderedTestMail;\n\n        $this->assertStringContainsString('nombre', $mail->render());\n    }\n}\n\nclass RenderedTestMail extends Mailable\n{\n    public function build()\n    {\n        return $this->view('view');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/SendingMailWithLocaleTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Events\\LocaleUpdated;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Mail;\nuse Illuminate\\Testing\\Assert;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingMailWithLocaleTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('mail.driver', 'array');\n\n        $app['config']->set('app.locale', 'en');\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n\n        $app['translator']->setLoaded([\n            '*' => [\n                '*' => [\n                    'en' => ['nom' => 'name'],\n                    'ar' => ['nom' => 'esm'],\n                    'es' => ['nom' => 'nombre'],\n                ],\n            ],\n        ]);\n    }\n\n    public function testMailIsSentWithDefaultLocale()\n    {\n        Mail::to('test@mail.com')->send(new TestMail);\n\n        $this->assertStringContainsString('name',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithSelectedLocale()\n    {\n        Mail::to('test@mail.com')->locale('ar')->send(new TestMail);\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithLocaleFromMailable()\n    {\n        $mailable = new TestMail;\n        $mailable->locale('ar');\n\n        Mail::to('test@mail.com')->send($mailable);\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithLocaleUpdatedListenersCalled()\n    {\n        Carbon::setTestNow('2018-04-01');\n\n        Event::listen(LocaleUpdated::class, function ($event) {\n            Carbon::setLocale($event->locale);\n        });\n\n        Mail::to('test@mail.com')->locale('es')->send(new TimestampTestMail);\n\n        Assert::assertMatchesRegularExpression('/nombre (en|dentro de) (un|1) d=C3=ADa/',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        $this->assertSame('en', Carbon::getLocale());\n\n        Carbon::setTestNow(null);\n    }\n\n    public function testLocaleIsSentWithModelPreferredLocale()\n    {\n        $recipient = new TestEmailLocaleUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'ar',\n        ]);\n\n        Mail::to($recipient)->send(new TestMail);\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        $mailable = new Mailable;\n        $mailable->to($recipient);\n\n        $this->assertSame($recipient->email_locale, $mailable->locale);\n    }\n\n    public function testLocaleIsSentWithSelectedLocaleOverridingModelPreferredLocale()\n    {\n        $recipient = new TestEmailLocaleUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'en',\n        ]);\n\n        Mail::to($recipient)->locale('ar')->send(new TestMail);\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testLocaleIsSentWithModelPreferredLocaleWillIgnorePreferredLocaleOfTheCcRecipient()\n    {\n        $toRecipient = new TestEmailLocaleUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'ar',\n        ]);\n\n        $ccRecipient = new TestEmailLocaleUser([\n            'email' => 'test.cc@mail.com',\n            'email_locale' => 'en',\n        ]);\n\n        Mail::to($toRecipient)->cc($ccRecipient)->send(new TestMail);\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testLocaleIsNotSentWithModelPreferredLocaleWhenThereAreMultipleRecipients()\n    {\n        $recipients = [\n            new TestEmailLocaleUser([\n                'email' => 'test@mail.com',\n                'email_locale' => 'ar',\n            ]),\n            new TestEmailLocaleUser([\n                'email' => 'test.2@mail.com',\n                'email_locale' => 'ar',\n            ]),\n        ];\n\n        Mail::to($recipients)->send(new TestMail);\n\n        $this->assertStringContainsString('name',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testLocaleIsSetBackToDefaultAfterMailSent()\n    {\n        Mail::to('test@mail.com')->locale('ar')->send(new TestMail);\n        Mail::to('test@mail.com')->send(new TestMail);\n\n        $this->assertSame('en', app('translator')->getLocale());\n\n        $this->assertStringContainsString('esm',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        $this->assertStringContainsString('name',\n            app('mailer')->getSymfonyTransport()->messages()[1]->toString()\n        );\n    }\n}\n\nclass TestMail extends Mailable\n{\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        return $this->view('view');\n    }\n}\n\nclass TestEmailLocaleUser extends Model implements HasLocalePreference\n{\n    protected $fillable = [\n        'email',\n        'email_locale',\n    ];\n\n    public function preferredLocale()\n    {\n        return $this->email_locale;\n    }\n}\n\nclass TimestampTestMail extends Mailable\n{\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        return $this->view('timestamp');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/SendingMarkdownMailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Support\\Facades\\Mail;\nuse Illuminate\\Support\\Stringable;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingMarkdownMailTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('mail.driver', 'array');\n\n        $app['view']->addNamespace('mail', __DIR__.'/Fixtures')\n            ->addLocation(__DIR__.'/Fixtures');\n    }\n\n    public function testMailIsSent()\n    {\n        $mailable = new BasicMailable();\n\n        $mailable\n            ->assertHasSubject('My basic title')\n            ->assertSeeInText('My basic content')\n            ->assertSeeInHtml('My basic content');\n    }\n\n    public function testMailMayHaveSpecificTextView()\n    {\n        $mailable = new BasicMailableWithTextView();\n\n        $mailable\n            ->assertHasSubject('My basic title')\n            ->assertSeeInHtml('My basic content')\n            ->assertSeeInText('My basic text view')\n            ->assertDontSeeInText('My basic content');\n    }\n\n    public function testEmbed()\n    {\n        Mail::to('test@mail.com')->send($mailable = new EmbedMailable());\n\n        $mailable->assertSeeInHtml('Embed content: cid:');\n        $mailable->assertSeeInText('Embed content: ');\n        $mailable->assertDontSeeInText('Embed content: cid:');\n\n        $email = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage()->toString();\n\n        $cid = rtrim(explode(' cid:', (new Stringable($email))->explode(\"\\r\\n\")\n            ->filter(fn ($line) => str_contains($line, ' content: cid:'))\n            ->first())[1], '=');\n\n        $filename = explode('Embed file: ', (new Stringable($email))->explode(\"\\r\\n\")\n            ->filter(fn ($line) => str_contains($line, ' file:'))\n            ->first())[1];\n\n        $this->assertStringContainsString(<<<EOT\n        Content-Type: application/x-php; name=$filename\\r\n        Content-Transfer-Encoding: base64\\r\n        Content-Disposition: inline; name=$filename;\\r\n         filename=$filename\\r\n        Content-ID: <$cid>\\r\n        EOT, $email);\n    }\n\n    public function testEmbedData()\n    {\n        Mail::to('test@mail.com')->send($mailable = new EmbedDataMailable());\n\n        $mailable->assertSeeInText('Embed data content: ');\n        $mailable->assertSeeInHtml('Embed data content: cid:');\n\n        $email = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage()->toString();\n\n        $this->assertStringContainsString(<<<EOT\n        Content-Type: image/png; name=foo.jpg\\r\n        Content-Transfer-Encoding: base64\\r\n        Content-Disposition: inline; name=foo.jpg; filename=foo.jpg\\r\n        EOT, $email);\n    }\n\n    public function testEmbedMultilineImage()\n    {\n        Mail::to('test@mail.com')->send($mailable = new EmbedMultilineMailable());\n\n        $html = html_entity_decode($mailable->render());\n\n        $this->assertStringContainsString('Embed multiline content: <img', $html);\n        $this->assertStringContainsString('alt=\"multiline image\"', $html);\n        $this->assertStringContainsString('src=\"data:image/png;base64,', $html);\n        $this->assertStringNotContainsString('src=\"cid:', $html);\n    }\n\n    public function testEmbeddedImagesAreInlinedWhenRenderingMailable()\n    {\n        $html = app('mailer')->render('embed-image', [\n            'image' => __DIR__.'/Fixtures/empty_image.jpg',\n        ]);\n\n        $this->assertStringContainsString('src=\"data:image/jpeg;base64,', $html);\n        $this->assertStringNotContainsString('src=\"cid:', $html);\n    }\n\n    public function testMessageAsPublicPropertyMayBeDefinedAsViewData()\n    {\n        Mail::to('test@mail.com')->send($mailable = new MessageAsPublicPropertyMailable());\n\n        $mailable\n            ->assertSeeInText('My message is: My message.')\n            ->assertSeeInHtml('My message is: My message.');\n\n        $email = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage()->toString();\n\n        $this->assertStringContainsString('My message is: My message.', $email);\n    }\n\n    public function testMessageAsWithNamedParameterMayBeDefinedAsViewData()\n    {\n        Mail::to('test@mail.com')->send($mailable = new MessageAsWithNamedParameterMailable());\n\n        $mailable\n            ->assertSeeInText('My message is: My message.')\n            ->assertSeeInHtml('My message is: My message.');\n\n        $email = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage()->toString();\n\n        $this->assertStringContainsString('My message is: My message.', $email);\n    }\n\n    public function testTheme()\n    {\n        Mail::to('test@mail.com')->send(new BasicMailable());\n        $this->assertSame('default', app(Markdown::class)->getTheme());\n\n        Mail::to('test@mail.com')->send(new BasicMailableWithTheme());\n        $this->assertSame('taylor', app(Markdown::class)->getTheme());\n\n        Mail::to('test@mail.com')->send(new BasicMailable());\n        $this->assertSame('default', app(Markdown::class)->getTheme());\n    }\n\n    public function testEmbeddedImageContentIdConsistencyAcrossMailerFailoverClones()\n    {\n        Mail::to('test@mail.com')->send($mailable = new EmbedImageMailable);\n\n        /** @var \\Symfony\\Component\\Mime\\Email $originalEmail */\n        $originalEmail = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage();\n        $expectedContentId = $originalEmail->getAttachments()[0]->getContentId();\n\n        // Simulate failover mailer scenario where email is cloned for retry.\n        // After shallow clone, the CID in HTML and attachment Content-ID header should remain consistent.\n        $firstClonedEmail = quoted_printable_decode((clone $originalEmail)->toString());\n        [$htmlCid, $attachmentContentId] = $this->extractContentIdsFromEmail($firstClonedEmail);\n\n        $this->assertEquals($htmlCid, $attachmentContentId, 'HTML img src CID should match attachment Content-ID header');\n        $this->assertEquals($expectedContentId, $htmlCid, 'Cloned email CID should match original attachment CID');\n\n        // Verify consistency is maintained across multiple clone operations (e.g., multiple retries).\n        $secondClonedEmail = quoted_printable_decode((clone $originalEmail)->toString());\n        [$htmlCid, $attachmentContentId] = $this->extractContentIdsFromEmail($secondClonedEmail);\n\n        $this->assertEquals($htmlCid, $attachmentContentId, 'HTML img src CID should match attachment Content-ID header on subsequent clone');\n        $this->assertEquals($expectedContentId, $htmlCid, 'Multiple clones should preserve original CID');\n    }\n\n    /**\n     * Extract Content IDs from email for embedded image validation.\n     *\n     * @param  string  $rawEmail\n     * @return array{0: string|null, 1: string|null} [HTML image CID, attachment Content-ID]\n     */\n    private function extractContentIdsFromEmail(string $rawEmail): array\n    {\n        // Extract CID from HTML <img src=\"cid:...\"> tag.\n        preg_match('/<img[^>]+src=\"cid:([^\"]+)\"/', $rawEmail, $htmlMatches);\n        $htmlImageCid = $htmlMatches[1] ?? null;\n\n        // Extract CID from MIME attachment Content-ID header.\n        preg_match('/Content-ID:\\s*<([^>]+)>/', $rawEmail, $headerMatches);\n        $attachmentContentId = $headerMatches[1] ?? null;\n\n        return [$htmlImageCid, $attachmentContentId];\n    }\n}\n\nclass BasicMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'basic',\n        );\n    }\n}\n\nclass BasicMailableWithTheme extends Mailable\n{\n    public $theme = 'taylor';\n\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'basic',\n        );\n    }\n}\n\nclass BasicMailableWithTextView extends Mailable\n{\n    public $textView = 'text';\n\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'basic',\n        );\n    }\n}\n\nclass EmbedMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'embed',\n        );\n    }\n}\n\nclass EmbedMultilineMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'embed-multiline',\n        );\n    }\n}\n\nclass EmbedDataMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'embed-data',\n        );\n    }\n}\n\nclass EmbedImageMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'embed-image',\n            with: [\n                'image' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'empty_image.jpg',\n            ]\n        );\n    }\n}\n\nclass MessageAsPublicPropertyMailable extends Mailable\n{\n    public $message = 'My message';\n\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'message',\n        );\n    }\n}\n\nclass MessageAsWithNamedParameterMailable extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            subject: 'My basic title',\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            markdown: 'message',\n            with: [\n                'message' => 'My message',\n            ]\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/SendingQueuedMailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\SendQueuedMailable;\nuse Illuminate\\Queue\\Middleware\\RateLimited;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Mail;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingQueuedMailTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('mail.driver', 'array');\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n    }\n\n    public function testMailIsSentWithDefaultLocale()\n    {\n        Queue::fake();\n\n        Mail::to('test@mail.com')->queue(new SendingQueuedMailTestMail);\n\n        Queue::assertPushed(SendQueuedMailable::class, function ($job) {\n            return $job->middleware[0] instanceof RateLimited;\n        });\n    }\n\n    public function testMailIsSentWhenRoutingQueue()\n    {\n        Queue::fake();\n\n        Queue::route(Mailable::class, 'mail-queue', 'mail-connection');\n\n        Mail::to('test@mail.com')->queue(new SendingQueuedMailTestMail);\n\n        Queue::connection('mail-connection')->assertPushedOn('mail-queue', SendQueuedMailable::class);\n    }\n\n    public function testMailIsSentWithDelay()\n    {\n        Queue::fake();\n\n        $delay = Carbon::now()->addMinutes(10);\n\n        Mail::to('test@mail.com')->later($delay, new SendingQueuedMailTestMail);\n\n        Queue::assertPushed(SendQueuedMailable::class, function ($job) use ($delay) {\n            return $job->delay === $delay;\n        });\n    }\n}\n\nclass SendingQueuedMailTestMail extends Mailable\n{\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        return $this->view('view');\n    }\n\n    public function middleware()\n    {\n        return [new RateLimited('limiter')];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Mail/SentMessageMailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Mail;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Notifications\\Events\\NotificationSent;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SentMessageMailTest extends TestCase\n{\n    use LazilyRefreshDatabase;\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('sent_message_users', function (Blueprint $table) {\n            $table->increments('id');\n        });\n    }\n\n    protected function beforeRefreshingDatabase()\n    {\n        Schema::dropIfExists('sent_message_users');\n    }\n\n    public function testDispatchesNotificationSent()\n    {\n        $notificationWasSent = false;\n\n        $user = SentMessageUser::create();\n\n        Event::listen(\n            NotificationSent::class,\n            function (NotificationSent $notification) use (&$notificationWasSent, $user) {\n                $notificationWasSent = true;\n                /**\n                 * Confirm that NotificationSent can be serialized/unserialized as\n                 * will happen if the listener implements ShouldQueue.\n                 */\n                /** @var NotificationSent $afterSerialization */\n                $afterSerialization = unserialize(serialize($notification));\n\n                $this->assertTrue($user->is($afterSerialization->notifiable));\n\n                $this->assertEqualsCanonicalizing($notification->notification, $afterSerialization->notification);\n            });\n\n        $user->notify(new SentMessageMailNotification());\n\n        $this->assertTrue($notificationWasSent);\n    }\n}\n\nclass SentMessageUser extends Model\n{\n    use Notifiable;\n\n    public $timestamps = false;\n}\n\nclass SentMessageMailNotification extends Notification\n{\n    public function via(): array\n    {\n        return ['mail'];\n    }\n\n    public function toMail(object $notifiable): MailMessage\n    {\n        return (new MailMessage)\n            ->line('Example notification with attachment.')\n            ->attach(__DIR__.'/Fixtures/blank_document.pdf', [\n                'as' => 'blank_document.pdf',\n                'mime' => 'application/pdf',\n            ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/MigratorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Migration;\n\nuse Illuminate\\Database\\Migrations\\Migrator;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Stringable;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass MigratorTest extends TestCase\n{\n    /**\n     * @var \\Mockery\\Mock\n     */\n    private $output;\n\n    public $subject;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->output = m::mock(OutputInterface::class);\n        $this->subject = $this->app->make('migrator');\n        $this->subject->setOutput($this->output);\n        $this->subject->getRepository()->createRepository();\n    }\n\n    protected function tearDown(): void\n    {\n        Migrator::withoutMigrations([]);\n\n        parent::tearDown();\n    }\n\n    public function testMigrate()\n    {\n        $this->expectInfo('Running migrations.');\n\n        $this->expectTask('2014_10_12_000000_create_people_table', 'DONE');\n        $this->expectTask('2015_10_04_000000_modify_people_table', 'DONE');\n        $this->expectTask('2016_10_04_000000_modify_people_table', 'DONE');\n        $this->expectTask('2017_10_04_000000_add_age_to_people', 'SKIPPED');\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->run([__DIR__.'/fixtures']);\n\n        $this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));\n        $this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'age'));\n    }\n\n    public function testMigrateWithoutOutput()\n    {\n        $this->app->forgetInstance('migrator');\n        $this->subject = $this->app->make('migrator');\n\n        $this->subject->run([__DIR__.'/fixtures']);\n\n        $this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));\n        $this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'age'));\n    }\n\n    public function testWithSkippedMigrations()\n    {\n        $this->app->forgetInstance('migrator');\n        $this->subject = $this->app->make('migrator');\n\n        Migrator::withoutMigrations(['2015_10_04_000000_modify_people_table.php', '2016_10_04_000000_modify_people_table']);\n\n        $this->subject->run([__DIR__.'/fixtures']);\n        $this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));\n        $this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));\n        $this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));\n\n        Migrator::withoutMigrations([]);\n        $this->subject->run([__DIR__.'/fixtures']);\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));\n        $this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));\n    }\n\n    public function testRollback()\n    {\n        $this->getConnection()->statement('CREATE TABLE people(id INT, first_name VARCHAR, last_name VARCHAR);');\n        $this->subject->getRepository()->log('2014_10_12_000000_create_people_table', 1);\n        $this->subject->getRepository()->log('2015_10_04_000000_modify_people_table', 1);\n        $this->subject->getRepository()->log('2016_10_04_000000_modify_people_table', 1);\n\n        $this->expectInfo('Rolling back migrations.');\n\n        $this->expectTask('2016_10_04_000000_modify_people_table', 'DONE');\n        $this->expectTask('2015_10_04_000000_modify_people_table', 'DONE');\n        $this->expectTask('2014_10_12_000000_create_people_table', 'DONE');\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->rollback([__DIR__.'/fixtures']);\n\n        $this->assertFalse(DB::getSchemaBuilder()->hasTable('people'));\n    }\n\n    public function testPretendMigrate()\n    {\n        $this->expectInfo('Running migrations.');\n\n        $this->expectTwoColumnDetail('CreatePeopleTable');\n        $this->expectBulletList([\n            'create table \"people\" (\"id\" integer primary key autoincrement not null, \"name\" varchar not null, \"email\" varchar not null, \"password\" varchar not null, \"remember_token\" varchar, \"created_at\" datetime, \"updated_at\" datetime)',\n            'create unique index \"people_email_unique\" on \"people\" (\"email\")',\n        ]);\n\n        $this->expectTwoColumnDetail('ModifyPeopleTable');\n        $this->expectBulletList(['alter table \"people\" add column \"first_name\" varchar']);\n\n        $this->expectTwoColumnDetail('2016_10_04_000000_modify_people_table');\n        $this->expectBulletList(['alter table \"people\" add column \"last_name\" varchar']);\n\n        $this->output->shouldReceive('writeln')->times(3);\n\n        $this->subject->run([__DIR__.'/fixtures'], ['pretend' => true]);\n\n        $this->assertFalse(DB::getSchemaBuilder()->hasTable('people'));\n    }\n\n    public function testIgnorePretendModeForCallbackData()\n    {\n        // Create two tables with different columns so that we can query it later\n        // with the new method DB::withoutPretending().\n\n        Schema::create('table_1', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('column_1');\n        });\n\n        Schema::create('table_2', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('column_2')->default('default_value');\n        });\n\n        // From here on we simulate to be in pretend mode. This normally is done by\n        // running the migration with the option --pretend.\n\n        DB::pretend(function () {\n            // Returns an empty array because we are in pretend mode.\n            $tablesEmpty = DB::select(\"SELECT name FROM sqlite_master WHERE type='table'\");\n\n            $this->assertTrue([] === $tablesEmpty);\n\n            // Returns an array with two tables because we ignore pretend mode.\n            $tablesList = DB::withoutPretending(function (): array {\n                return DB::select(\"SELECT name FROM sqlite_master WHERE type='table'\");\n            });\n\n            $this->assertTrue([] !== $tablesList);\n\n            // The following would not be possible in pretend mode, if the\n            // method DB::withoutPretending() would not exists,\n            // because nothing is executed in pretend mode.\n            foreach ($tablesList as $table) {\n                if (in_array($table->name, ['sqlite_sequence', 'migrations'])) {\n                    continue;\n                }\n\n                $columnsEmpty = DB::select(\"PRAGMA table_info($table->name)\");\n\n                $this->assertTrue([] === $columnsEmpty);\n\n                $columnsList = DB::withoutPretending(function () use ($table): array {\n                    return DB::select(\"PRAGMA table_info($table->name)\");\n                });\n\n                $this->assertTrue([] !== $columnsList);\n                $this->assertCount(2, $columnsList);\n\n                // Confirm that we are still in pretend mode. This column should\n                // not be added. We query the table columns again to ensure the\n                // count is still two.\n                DB::statement(\"ALTER TABLE $table->name ADD COLUMN column_3 varchar(255) DEFAULT 'default_value' NOT NULL\");\n\n                $columnsList = DB::withoutPretending(function () use ($table): array {\n                    return DB::select(\"PRAGMA table_info($table->name)\");\n                });\n\n                $this->assertCount(2, $columnsList);\n            }\n        });\n\n        Schema::dropIfExists('table_1');\n        Schema::dropIfExists('table_2');\n    }\n\n    public function testIgnorePretendModeForCallbackOutputDynamicContentIsShown()\n    {\n        // Persist data to table we can work with.\n        $this->expectInfo('Running migrations.');\n        $this->expectTask('2014_10_12_000000_create_people_is_dynamic_table', 'DONE');\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->run([__DIR__.'/pretending/2014_10_12_000000_create_people_is_dynamic_table.php'], ['pretend' => false]);\n\n        $this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));\n\n        // Test the actual functionality.\n        $this->expectInfo('Running migrations.');\n        $this->expectTwoColumnDetail('DynamicContentIsShown');\n        $this->expectBulletList([\n            'create table \"blogs\" (\"id\" integer primary key autoincrement not null, \"url\" varchar, \"name\" varchar)',\n            'insert into \"blogs\" (\"url\") values (\\'www.janedoe.com\\'), (\\'www.johndoe.com\\')',\n            'ALTER TABLE \\'pseudo_table_name\\' MODIFY \\'column_name\\' VARCHAR(191)',\n            'select * from \"people\"',\n            'insert into \"blogs\" (\"id\", \"name\") values (1, \\'Jane Doe Blog\\')',\n            'insert into \"blogs\" (\"id\", \"name\") values (2, \\'John Doe Blog\\')',\n        ]);\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->run([__DIR__.'/pretending/2023_10_17_000000_dynamic_content_is_shown.php'], ['pretend' => true]);\n\n        $this->assertFalse(DB::getSchemaBuilder()->hasTable('blogs'));\n\n        Schema::dropIfExists('people');\n    }\n\n    public function testIgnorePretendModeForCallbackOutputDynamicContentNotShown()\n    {\n        // Persist data to table we can work with.\n        $this->expectInfo('Running migrations.');\n        $this->expectTask('2014_10_12_000000_create_people_non_dynamic_table', 'DONE');\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->run([__DIR__.'/pretending/2014_10_12_000000_create_people_non_dynamic_table.php'], ['pretend' => false]);\n\n        $this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));\n\n        // Test the actual functionality.\n        $this->expectInfo('Running migrations.');\n        $this->expectTwoColumnDetail('DynamicContentNotShown');\n        $this->expectBulletList([\n            'create table \"blogs\" (\"id\" integer primary key autoincrement not null, \"url\" varchar, \"name\" varchar)',\n            'insert into \"blogs\" (\"url\") values (\\'www.janedoe.com\\'), (\\'www.johndoe.com\\')',\n            'ALTER TABLE \\'pseudo_table_name\\' MODIFY \\'column_name\\' VARCHAR(191)',\n            'select * from \"people\"',\n        ]);\n\n        $this->output->shouldReceive('writeln')->once();\n\n        $this->subject->run([__DIR__.'/pretending/2023_10_17_000000_dynamic_content_not_shown.php'], ['pretend' => true]);\n\n        $this->assertFalse(DB::getSchemaBuilder()->hasTable('blogs'));\n\n        Schema::dropIfExists('people');\n    }\n\n    protected function expectInfo($message): void\n    {\n        $this->output->shouldReceive('writeln')->once()->with(m::on(\n            fn ($argument) => (new Stringable($argument))->contains($message),\n        ), m::any());\n    }\n\n    protected function expectTwoColumnDetail($first, $second = null)\n    {\n        $this->output->shouldReceive('writeln')->with(m::on(function ($argument) use ($first, $second) {\n            $result = (new Stringable($argument))->contains($first);\n\n            if ($result && $second) {\n                $result = (new Stringable($argument))->contains($second);\n            }\n\n            return $result;\n        }), m::any());\n    }\n\n    protected function expectBulletList($elements): void\n    {\n        $this->output->shouldReceive('writeln')->once()->with(m::on(function ($argument) use ($elements) {\n            foreach ($elements as $element) {\n                if (! (new Stringable($argument))->contains(\"⇂ $element\")) {\n                    return false;\n                }\n            }\n\n            return true;\n        }), m::any());\n    }\n\n    protected function expectTask($description, $result): void\n    {\n        // Ignore dots...\n        $this->output->shouldReceive('write')->with(m::on(\n            fn ($argument) => (new Stringable($argument))->contains(['<fg=gray></>', '<fg=gray>.</>']),\n        ), m::any(), m::any());\n\n        // Ignore duration...\n        $this->output->shouldReceive('write')->with(m::on(\n            fn ($argument) => (new Stringable($argument))->contains(['ms</>']),\n        ), m::any(), m::any());\n\n        $this->output->shouldReceive('write')->once()->with(m::on(\n            fn ($argument) => (new Stringable($argument))->contains($description),\n        ), m::any(), m::any());\n\n        $this->output->shouldReceive('writeln')->once()->with(m::on(\n            fn ($argument) => (new Stringable($argument))->contains($result),\n        ), m::any());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/fixtures/2014_10_12_000000_create_people_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreatePeopleTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create('people', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('email')->unique();\n            $table->string('password');\n            $table->rememberToken();\n            $table->timestamps();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::drop('people');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/fixtures/2015_10_04_000000_modify_people_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass ModifyPeopleTable extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->string('first_name')->nullable();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->dropColumn('first_name');\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/fixtures/2016_10_04_000000_modify_people_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->string('last_name')->nullable();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->dropColumn('last_name');\n        });\n    }\n};\n"
  },
  {
    "path": "tests/Integration/Migration/fixtures/2017_10_04_000000_add_age_to_people.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    public function shouldRun(): bool\n    {\n        return false;\n    }\n\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->unsignedInteger('age')->nullable();\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::table('people', function (Blueprint $table) {\n            $table->dropColumn('age');\n        });\n    }\n};\n"
  },
  {
    "path": "tests/Integration/Migration/pretending/2014_10_12_000000_create_people_is_dynamic_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreatePeopleIsDynamicTable extends Migration\n{\n    public function up()\n    {\n        Schema::create('people', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('blog_id')->nullable();\n            $table->string('name');\n            $table->string('email')->unique();\n            $table->string('password');\n            $table->rememberToken();\n            $table->timestamps();\n        });\n\n        DB::table('people')->insert([\n            ['email' => 'jane@example.com', 'name' => 'Jane Doe', 'password' => 'secret'],\n            ['email' => 'john@example.com', 'name' => 'John Doe', 'password' => 'secret'],\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/pretending/2014_10_12_000000_create_people_non_dynamic_table.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass CreatePeopleNonDynamicTable extends Migration\n{\n    public function up()\n    {\n        Schema::create('people', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->string('email')->unique();\n            $table->string('password');\n            $table->rememberToken();\n            $table->timestamps();\n        });\n\n        DB::table('people')->insert([\n            ['email' => 'jane@example.com', 'name' => 'Jane Doe', 'password' => 'secret'],\n            ['email' => 'john@example.com', 'name' => 'John Doe', 'password' => 'secret'],\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/pretending/2023_10_17_000000_dynamic_content_is_shown.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DynamicContentIsShown extends Migration\n{\n    public function up()\n    {\n        Schema::create('blogs', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('url')->nullable();\n            $table->string('name')->nullable();\n        });\n\n        DB::table('blogs')->insert([\n            ['url' => 'www.janedoe.com'],\n            ['url' => 'www.johndoe.com'],\n        ]);\n\n        DB::statement(\"ALTER TABLE 'pseudo_table_name' MODIFY 'column_name' VARCHAR(191)\");\n\n        /** @var \\Illuminate\\Support\\Collection $tablesList */\n        $tablesList = DB::withoutPretending(function () {\n            return DB::table('people')->get();\n        });\n\n        $tablesList->each(function ($person, $key) {\n            DB::table('blogs')->where('blog_id', '=', $person->blog_id)->insert([\n                'id' => $key + 1,\n                'name' => \"{$person->name} Blog\",\n            ]);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Migration/pretending/2023_10_17_000000_dynamic_content_not_shown.php",
    "content": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Schema;\n\nclass DynamicContentNotShown extends Migration\n{\n    public function up()\n    {\n        Schema::create('blogs', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('url')->nullable();\n            $table->string('name')->nullable();\n        });\n\n        DB::table('blogs')->insert([\n            ['url' => 'www.janedoe.com'],\n            ['url' => 'www.johndoe.com'],\n        ]);\n\n        DB::statement(\"ALTER TABLE 'pseudo_table_name' MODIFY 'column_name' VARCHAR(191)\");\n\n        DB::table('people')->get()->each(function ($person, $key) {\n            DB::table('blogs')->where('blog_id', '=', $person->blog_id)->insert([\n                'id' => $key + 1,\n                'name' => \"{$person->name} Blog\",\n            ]);\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Notifications/DatabaseNotificationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Notifications;\n\nuse Illuminate\\Database\\Eloquent\\Casts\\AsStringable;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Support\\Facades\\Notification;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\DefineDatabase;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration('laravel', 'notifications')]\nclass DatabaseNotificationTest extends TestCase\n{\n    use RefreshDatabase;\n\n    #[DefineDatabase('defineDatabaseAndConvertUserIdToUuid')]\n    public function testAssertSentToWhenNotifiableHasStringableKey()\n    {\n        Notification::fake();\n\n        $user = UuidUserFactoryStub::new()->create();\n\n        $user->notify(new NotificationStub);\n\n        Notification::assertSentTo($user, NotificationStub::class, function ($notification, $channels, $notifiable) use ($user) {\n            return $notifiable === $user;\n        });\n    }\n\n    /**\n     * Define database and convert User's ID to UUID.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function defineDatabaseAndConvertUserIdToUuid($app): void\n    {\n        Schema::table('users', function (Blueprint $table) {\n            $table->uuid('id')->change();\n        });\n    }\n}\n\nclass UuidUserFactoryStub extends \\Orchestra\\Testbench\\Factories\\UserFactory\n{\n    protected $model = UuidUserStub::class;\n}\n\nclass UuidUserStub extends \\Illuminate\\Foundation\\Auth\\User\n{\n    use HasUuids, Notifiable;\n\n    protected $table = 'users';\n\n    #[\\Override]\n    public function casts()\n    {\n        return array_merge(parent::casts(), ['id' => AsStringable::class]);\n    }\n}\n\nclass NotificationStub extends \\Illuminate\\Notifications\\Notification\n{\n    public function via($notifiable)\n    {\n        return ['mail'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/greeting.blade.php",
    "content": "{{ __('hi') }}\n"
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/html.blade.php",
    "content": "htmlContent\n"
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/mail/blank.blade.php",
    "content": ""
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/mail/color-test.blade.php",
    "content": "body{color: test;}\n"
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/markdown.blade.php",
    "content": "Embed file: {{ basename(__FILE__) }}\nEmbed content: {{ $message->embed(__FILE__) }}\n"
  },
  {
    "path": "tests/Integration/Notifications/Fixtures/plain.blade.php",
    "content": "plainContent\n"
  },
  {
    "path": "tests/Integration/Notifications/SendingMailNotificationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Notifications;\n\nuse Illuminate\\Contracts\\Mail\\Factory as MailFactory;\nuse Illuminate\\Contracts\\Mail\\Mailable;\nuse Illuminate\\Contracts\\Mail\\Mailer;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Mail\\Markdown;\nuse Illuminate\\Mail\\Message;\nuse Illuminate\\Notifications\\Channels\\MailChannel;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingMailNotificationsTest extends TestCase\n{\n    public $mailFactory;\n    public $mailer;\n    public $markdown;\n\n    protected function defineEnvironment($app)\n    {\n        $this->mailFactory = m::mock(MailFactory::class);\n        $this->mailer = m::mock(Mailer::class);\n        $this->mailFactory->shouldReceive('mailer')->andReturn($this->mailer);\n        $this->markdown = m::mock(Markdown::class);\n\n        $app->extend(Markdown::class, function () {\n            return $this->markdown;\n        });\n\n        $app->extend(Mailer::class, function () {\n            return $this->mailer;\n        });\n\n        $app->extend(MailFactory::class, function () {\n            return $this->mailFactory;\n        });\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->string('name')->nullable();\n        });\n    }\n\n    public function testMailIsSent()\n    {\n        $notification = new TestMailNotification;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->markdown->shouldReceive('theme')->twice()->with('default')->andReturn($this->markdown);\n        $this->markdown->shouldReceive('render')->once()->andReturn('htmlContent');\n        $this->markdown->shouldReceive('renderText')->once()->andReturn('textContent');\n\n        $this->setMailerSendAssertions($notification, $user, function ($closure) {\n            $message = m::mock(Message::class);\n\n            $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n            $message->shouldReceive('cc')->once()->with('cc@deepblue.com', 'cc');\n\n            $message->shouldReceive('bcc')->once()->with('bcc@deepblue.com', 'bcc');\n\n            $message->shouldReceive('from')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('replyTo')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('subject')->once()->with('Test Mail Notification');\n\n            $message->shouldReceive('priority')->once()->with(1);\n\n            $closure($message);\n\n            return true;\n        });\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentWithCustomTheme()\n    {\n        $notification = new TestMailNotificationWithCustomTheme;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->markdown->shouldReceive('theme')->twice()->with('my-custom-theme')->andReturn($this->markdown);\n        $this->markdown->shouldReceive('render')->once()->andReturn('htmlContent');\n        $this->markdown->shouldReceive('renderText')->once()->andReturn('textContent');\n\n        $this->setMailerSendAssertions($notification, $user, function ($closure) {\n            $message = m::mock(Message::class);\n\n            $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n            $message->shouldReceive('cc')->once()->with('cc@deepblue.com', 'cc');\n\n            $message->shouldReceive('bcc')->once()->with('bcc@deepblue.com', 'bcc');\n\n            $message->shouldReceive('from')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('replyTo')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('subject')->once()->with('Test Mail Notification With Custom Theme');\n\n            $message->shouldReceive('priority')->once()->with(1);\n\n            $closure($message);\n\n            return true;\n        });\n\n        $user->notify($notification);\n    }\n\n    private function setMailerSendAssertions(\n        Notification $notification,\n        NotifiableUser $user,\n        callable $callbackExpectationClosure\n    ) {\n        $this->mailer->shouldReceive('send')->once()->withArgs(function (...$args) use ($notification, $user, $callbackExpectationClosure) {\n            $viewArray = $args[0];\n\n            if (! m::on(fn ($closure) => $closure([]) === 'htmlContent')->match($viewArray['html'])) {\n                return false;\n            }\n\n            if (! m::on(fn ($closure) => $closure([]) === 'textContent')->match($viewArray['text'])) {\n                return false;\n            }\n\n            $data = $args[1];\n\n            $expected = array_merge($notification->toMail($user)->toArray(), [\n                '__laravel_notification_id' => $notification->id,\n                '__laravel_notification' => get_class($notification),\n                '__laravel_notification_queued' => false,\n            ]);\n\n            if (array_keys($data) !== array_keys($expected)) {\n                return false;\n            }\n            if (array_values($data) !== array_values($expected)) {\n                return false;\n            }\n\n            return m::on($callbackExpectationClosure)->match($args[2]);\n        });\n    }\n\n    public function testMailIsSentToNamedAddress()\n    {\n        $notification = new TestMailNotification;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUserWithNamedAddress::forceCreate([\n            'email' => 'taylor@laravel.com',\n            'name' => 'Taylor Otwell',\n        ]);\n\n        $this->markdown->shouldReceive('theme')->twice()->with('default')->andReturn($this->markdown);\n        $this->markdown->shouldReceive('render')->once()->andReturn('htmlContent');\n        $this->markdown->shouldReceive('renderText')->once()->andReturn('textContent');\n\n        $this->setMailerSendAssertions($notification, $user, function ($closure) {\n            $message = m::mock(Message::class);\n\n            $message->shouldReceive('to')->once()->with(['taylor@laravel.com' => 'Taylor Otwell', 'foo_taylor@laravel.com']);\n\n            $message->shouldReceive('cc')->once()->with('cc@deepblue.com', 'cc');\n\n            $message->shouldReceive('bcc')->once()->with('bcc@deepblue.com', 'bcc');\n\n            $message->shouldReceive('from')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('replyTo')->once()->with('jack@deepblue.com', 'Jacques Mayol');\n\n            $message->shouldReceive('subject')->once()->with('Test Mail Notification');\n\n            $message->shouldReceive('priority')->once()->with(1);\n\n            $closure($message);\n\n            return true;\n        });\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentWithSubject()\n    {\n        $notification = new TestMailNotificationWithSubject;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->markdown->shouldReceive('theme')->with('default')->twice()->andReturn($this->markdown);\n        $this->markdown->shouldReceive('render')->once()->andReturn('htmlContent');\n        $this->markdown->shouldReceive('renderText')->once()->andReturn('textContent');\n\n        $this->setMailerSendAssertions($notification, $user, function ($closure) {\n            $message = m::mock(Message::class);\n\n            $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n            $message->shouldReceive('subject')->once()->with('mail custom subject');\n\n            $closure($message);\n\n            return true;\n        });\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentToMultipleAddresses()\n    {\n        $notification = new TestMailNotificationWithSubject;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUserWithMultipleAddresses::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->markdown->shouldReceive('theme')->with('default')->twice()->andReturn($this->markdown);\n        $this->markdown->shouldReceive('render')->once()->andReturn('htmlContent');\n        $this->markdown->shouldReceive('renderText')->once()->andReturn('textContent');\n\n        $this->setMailerSendAssertions($notification, $user, function ($closure) {\n            $message = m::mock(Message::class);\n\n            $message->shouldReceive('to')->once()->with(['foo_taylor@laravel.com', 'bar_taylor@laravel.com']);\n\n            $message->shouldReceive('subject')->once()->with('mail custom subject');\n\n            $closure($message);\n\n            return true;\n        });\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentUsingMailable()\n    {\n        $notification = new TestMailNotificationWithMailable;\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentUsingMailMessageWithHtmlAndPlain()\n    {\n        $notification = new TestMailNotificationWithHtmlAndPlain;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->mailer->shouldReceive('send')->once()->with(\n            ['html', 'plain'],\n            array_merge($notification->toMail($user)->toArray(), [\n                '__laravel_notification_id' => $notification->id,\n                '__laravel_notification' => get_class($notification),\n                '__laravel_notification_queued' => false,\n            ]),\n            m::on(function ($closure) {\n                $message = m::mock(Message::class);\n\n                $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n                $message->shouldReceive('subject')->once()->with('Test Mail Notification With Html And Plain');\n\n                $closure($message);\n\n                return true;\n            })\n        );\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentUsingMailMessageWithHtmlOnly()\n    {\n        $notification = new TestMailNotificationWithHtmlOnly;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->mailer->shouldReceive('send')->once()->with(\n            'html',\n            array_merge($notification->toMail($user)->toArray(), [\n                '__laravel_notification_id' => $notification->id,\n                '__laravel_notification' => get_class($notification),\n                '__laravel_notification_queued' => false,\n            ]),\n            m::on(function ($closure) {\n                $message = m::mock(Message::class);\n\n                $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n                $message->shouldReceive('subject')->once()->with('Test Mail Notification With Html Only');\n\n                $closure($message);\n\n                return true;\n            })\n        );\n\n        $user->notify($notification);\n    }\n\n    public function testMailIsSentUsingMailMessageWithPlainOnly()\n    {\n        $notification = new TestMailNotificationWithPlainOnly;\n        $notification->id = Str::uuid()->toString();\n\n        $user = NotifiableUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->mailer->shouldReceive('send')->once()->with(\n            [null, 'plain'],\n            array_merge($notification->toMail($user)->toArray(), [\n                '__laravel_notification_id' => $notification->id,\n                '__laravel_notification' => get_class($notification),\n                '__laravel_notification_queued' => false,\n            ]),\n            m::on(function ($closure) {\n                $message = m::mock(Message::class);\n\n                $message->shouldReceive('to')->once()->with(['taylor@laravel.com']);\n\n                $message->shouldReceive('subject')->once()->with('Test Mail Notification With Plain Only');\n\n                $closure($message);\n\n                return true;\n            })\n        );\n\n        $user->notify($notification);\n    }\n}\n\nclass NotifiableUser extends Model\n{\n    use Notifiable;\n\n    public $table = 'users';\n    public $timestamps = false;\n}\n\nclass NotifiableUserWithNamedAddress extends NotifiableUser\n{\n    public function routeNotificationForMail($notification)\n    {\n        return [\n            $this->email => $this->name,\n            'foo_'.$this->email,\n        ];\n    }\n}\n\nclass NotifiableUserWithMultipleAddresses extends NotifiableUser\n{\n    public function routeNotificationForMail($notification)\n    {\n        return [\n            'foo_'.$this->email,\n            'bar_'.$this->email,\n        ];\n    }\n}\n\nclass TestMailNotification extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->priority(1)\n            ->cc('cc@deepblue.com', 'cc')\n            ->bcc('bcc@deepblue.com', 'bcc')\n            ->from('jack@deepblue.com', 'Jacques Mayol')\n            ->replyTo('jack@deepblue.com', 'Jacques Mayol')\n            ->line('The introduction to the notification.')\n            ->mailer('foo');\n    }\n}\n\nclass TestMailNotificationWithSubject extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->subject('mail custom subject')\n            ->line('The introduction to the notification.');\n    }\n}\n\nclass TestMailNotificationWithMailable extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        $mailable = m::mock(Mailable::class);\n\n        $mailable->shouldReceive('send')->once();\n\n        return $mailable;\n    }\n}\n\nclass TestMailNotificationWithHtmlAndPlain extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->view(['html', 'plain']);\n    }\n}\n\nclass TestMailNotificationWithHtmlOnly extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->view('html');\n    }\n}\n\nclass TestMailNotificationWithPlainOnly extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->view([null, 'plain']);\n    }\n}\n\nclass TestMailNotificationWithCustomTheme extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->priority(1)\n            ->cc('cc@deepblue.com', 'cc')\n            ->bcc('bcc@deepblue.com', 'bcc')\n            ->from('jack@deepblue.com', 'Jacques Mayol')\n            ->replyTo('jack@deepblue.com', 'Jacques Mayol')\n            ->line('The introduction to the notification.')\n            ->theme('my-custom-theme')\n            ->mailer('foo');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Notifications/SendingMailableNotificationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Notifications;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Stringable;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingMailableNotificationsTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('mail.driver', 'array');\n\n        $app['config']->set('app.locale', 'en');\n\n        $app['config']->set('mail.markdown.theme', 'blank');\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n    }\n\n    protected function afterRefreshingDatabase()\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->string('name')->nullable();\n        });\n    }\n\n    protected function beforeRefreshingDatabase()\n    {\n        Schema::dropIfExists('users');\n    }\n\n    public function testMarkdownNotification()\n    {\n        $user = MailableNotificationUser::forceCreate([\n            'email' => 'nuno@laravel.com',\n        ]);\n\n        $user->notify(new MarkdownNotification());\n\n        $message = app('mailer')->getSymfonyTransport()->messages()[0]->getOriginalMessage();\n        $email = $message->toString();\n        $textBody = $message->getTextBody();\n\n        $cid = explode(' cid:', (new Stringable($textBody))->explode(\"\\n\")\n            ->filter(fn ($line) => str_contains($line, 'Embed content: cid:'))\n            ->first())[1];\n\n        $filename = explode(' file: ', (new Stringable($textBody))->explode(\"\\n\")\n            ->filter(fn ($line) => str_contains($line, 'Embed file: '))\n            ->first())[1];\n\n        $this->assertStringContainsString(<<<EOT\n        Content-Type: application/x-php; name=$filename\\r\n        Content-Transfer-Encoding: base64\\r\n        Content-Disposition: inline; name=$filename;\\r\n         filename=$filename\\r\n        Content-ID: <$cid>\\r\n        EOT, $email);\n    }\n\n    public function testCanSetTheme()\n    {\n        $user = MailableNotificationUser::forceCreate([\n            'email' => 'nuno@laravel.com',\n        ]);\n\n        $user->notify(new MarkdownNotification('color-test'));\n        $mailTransport = app('mailer')->getSymfonyTransport();\n\n        $contents = $mailTransport->messages()[0]->getOriginalMessage()->toString();\n        $this->assertStringContainsString('<body style=3D\"color: test;\">', $contents);\n\n        // confirm passing no theme resets to the app's default theme\n        $user->notify(new MarkdownNotification());\n\n        $contents = $mailTransport->messages()[1]->getOriginalMessage()->toString();\n        $this->assertStringNotContainsString('<body style=3D\"color: test;\">', $contents);\n    }\n}\n\nclass MailableNotificationUser extends Model\n{\n    use Notifiable;\n\n    public $table = 'users';\n    public $timestamps = false;\n}\n\nclass MarkdownNotification extends Notification\n{\n    public function __construct(\n        protected $theme = null\n    ) {\n    }\n\n    public function via($notifiable): array\n    {\n        return ['mail'];\n    }\n\n    public function toMail($notifiable): MailMessage\n    {\n        $message = (new MailMessage)->markdown('markdown');\n\n        if (! is_null($this->theme)) {\n            $message->theme($this->theme);\n        }\n\n        return $message;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Notifications/SendingNotificationsViaAnonymousNotifiableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Notifications;\n\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Facades\\Notification as NotificationFacade;\nuse Illuminate\\Support\\Testing\\Fakes\\NotificationFake;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingNotificationsViaAnonymousNotifiableTest extends TestCase\n{\n    public function testMailIsSent()\n    {\n        $notifiable = (new AnonymousNotifiable)\n            ->route('testchannel', 'enzo')\n            ->route('anothertestchannel', 'enzo@deepblue.com');\n\n        NotificationFacade::send(\n            $notifiable,\n            new TestMailNotificationForAnonymousNotifiable\n        );\n\n        $this->assertEquals([\n            'enzo', 'enzo@deepblue.com',\n        ], $_SERVER['__notifiable.route']);\n    }\n\n    public function testAnonymousNotifiableWithMultipleRoutes()\n    {\n        $_SERVER['__notifiable.route'] = [];\n\n        NotificationFacade::routes([\n            'testchannel' => 'enzo',\n            'anothertestchannel' => 'enzo@deepblue.com',\n        ])->notify(new TestMailNotificationForAnonymousNotifiable());\n\n        $this->assertEquals([\n            'enzo', 'enzo@deepblue.com',\n        ], $_SERVER['__notifiable.route']);\n    }\n\n    public function testFaking()\n    {\n        $fake = NotificationFacade::fake();\n\n        $this->assertInstanceOf(NotificationFake::class, $fake);\n\n        $notifiable = (new AnonymousNotifiable)\n            ->route('testchannel', 'enzo')\n            ->route('anothertestchannel', 'enzo@deepblue.com');\n\n        NotificationFacade::locale('it')->send(\n            $notifiable,\n            new TestMailNotificationForAnonymousNotifiable\n        );\n\n        NotificationFacade::assertSentTo(new AnonymousNotifiable, TestMailNotificationForAnonymousNotifiable::class,\n            function ($notification, $channels, $notifiable, $locale) {\n                return $notifiable->routes['testchannel'] === 'enzo' &&\n                    $notifiable->routes['anothertestchannel'] === 'enzo@deepblue.com' &&\n                    $locale === 'it';\n            }\n        );\n    }\n}\n\nclass TestMailNotificationForAnonymousNotifiable extends Notification\n{\n    public function via($notifiable)\n    {\n        return [TestCustomChannel::class, AnotherTestCustomChannel::class];\n    }\n}\n\nclass TestCustomChannel\n{\n    public function send($notifiable, $notification)\n    {\n        $_SERVER['__notifiable.route'][] = $notifiable->routeNotificationFor('testchannel');\n    }\n}\n\nclass AnotherTestCustomChannel\n{\n    public function send($notifiable, $notification)\n    {\n        $_SERVER['__notifiable.route'][] = $notifiable->routeNotificationFor('anothertestchannel');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Notifications;\n\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Events\\LocaleUpdated;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Notifications\\Channels\\MailChannel;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Notification as NotificationFacade;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Testing\\Assert;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SendingNotificationsWithLocaleTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('mail.driver', 'array');\n\n        $app['config']->set('app.locale', 'en');\n\n        $app['view']->addLocation(__DIR__.'/Fixtures');\n\n        $app['translator']->setLoaded([\n            '*' => [\n                '*' => [\n                    'en' => ['hi' => 'hello'],\n                    'es' => ['hi' => 'hola'],\n                    'fr' => ['hi' => 'bonjour'],\n                ],\n            ],\n        ]);\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n            $table->string('name')->nullable();\n        });\n    }\n\n    public function testMailIsSentWithDefaultLocale()\n    {\n        $user = NotifiableLocalizedUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n            'name' => 'Taylor Otwell',\n        ]);\n\n        NotificationFacade::send($user, new GreetingMailNotification);\n\n        $this->assertStringContainsString('hello',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithFacadeSelectedLocale()\n    {\n        $user = NotifiableLocalizedUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n            'name' => 'Taylor Otwell',\n        ]);\n\n        NotificationFacade::locale('fr')->send($user, new GreetingMailNotification);\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithNotificationSelectedLocale()\n    {\n        $users = [\n            NotifiableLocalizedUser::forceCreate([\n                'email' => 'taylor@laravel.com',\n                'name' => 'Taylor Otwell',\n            ]),\n            NotifiableLocalizedUser::forceCreate([\n                'email' => 'mohamed@laravel.com',\n                'name' => 'Mohamed Said',\n            ]),\n        ];\n\n        NotificationFacade::send($users, (new GreetingMailNotification)->locale('fr'));\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[1]->toString()\n        );\n    }\n\n    public function testMailableIsSentWithSelectedLocale()\n    {\n        $user = NotifiableLocalizedUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n            'name' => 'Taylor Otwell',\n        ]);\n\n        NotificationFacade::locale('fr')->send($user, new GreetingMailNotificationWithMailable);\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testMailIsSentWithLocaleUpdatedListenersCalled()\n    {\n        Carbon::setTestNow('2018-07-25');\n\n        Event::listen(LocaleUpdated::class, function ($event) {\n            Carbon::setLocale($event->locale);\n        });\n\n        $user = NotifiableLocalizedUser::forceCreate([\n            'email' => 'taylor@laravel.com',\n            'name' => 'Taylor Otwell',\n        ]);\n\n        $user->notify((new GreetingMailNotification)->locale('fr'));\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        Assert::assertMatchesRegularExpression('/dans (1|un) jour/',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n\n        $this->assertTrue($this->app->isLocale('en'));\n\n        $this->assertSame('en', Carbon::getLocale());\n\n        Carbon::setTestNow(null);\n    }\n\n    public function testLocaleIsSentWithNotifiablePreferredLocale()\n    {\n        $recipient = new NotifiableEmailLocalePreferredUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'fr',\n        ]);\n\n        $recipient->notify(new GreetingMailNotification);\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testLocaleIsSentWithNotifiablePreferredLocaleForMultipleRecipients()\n    {\n        $recipients = [\n            new NotifiableEmailLocalePreferredUser([\n                'email' => 'test@mail.com',\n                'email_locale' => 'fr',\n            ]),\n            new NotifiableEmailLocalePreferredUser([\n                'email' => 'test.2@mail.com',\n                'email_locale' => 'es',\n            ]),\n            NotifiableLocalizedUser::forceCreate([\n                'email' => 'test.3@mail.com',\n            ]),\n        ];\n\n        NotificationFacade::send(\n            $recipients, new GreetingMailNotification\n        );\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n        $this->assertStringContainsString('hola',\n            app('mailer')->getSymfonyTransport()->messages()[1]->toString()\n        );\n        $this->assertStringContainsString('hello',\n            app('mailer')->getSymfonyTransport()->messages()[2]->toString()\n        );\n    }\n\n    public function testLocaleIsSentWithNotificationSelectedLocaleOverridingNotifiablePreferredLocale()\n    {\n        $recipient = new NotifiableEmailLocalePreferredUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'es',\n        ]);\n\n        $recipient->notify(\n            (new GreetingMailNotification)->locale('fr')\n        );\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n\n    public function testLocaleIsSentWithFacadeSelectedLocaleOverridingNotifiablePreferredLocale()\n    {\n        $recipient = new NotifiableEmailLocalePreferredUser([\n            'email' => 'test@mail.com',\n            'email_locale' => 'es',\n        ]);\n\n        NotificationFacade::locale('fr')->send(\n            $recipient, new GreetingMailNotification\n        );\n\n        $this->assertStringContainsString('bonjour',\n            app('mailer')->getSymfonyTransport()->messages()[0]->toString()\n        );\n    }\n}\n\nclass NotifiableLocalizedUser extends Model\n{\n    use Notifiable;\n\n    public $table = 'users';\n    public $timestamps = false;\n}\n\nclass NotifiableEmailLocalePreferredUser extends Model implements HasLocalePreference\n{\n    use Notifiable;\n\n    protected $fillable = [\n        'email',\n        'email_locale',\n    ];\n\n    public function preferredLocale()\n    {\n        return $this->email_locale;\n    }\n}\n\nclass GreetingMailNotification extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new MailMessage)\n            ->greeting(__('hi'))\n            ->line(Carbon::tomorrow()->diffForHumans());\n    }\n}\n\nclass GreetingMailNotificationWithMailable extends Notification\n{\n    public function via($notifiable)\n    {\n        return [MailChannel::class];\n    }\n\n    public function toMail($notifiable)\n    {\n        return (new GreetingMailable)\n            ->to($notifiable->email);\n    }\n}\n\nclass GreetingMailable extends Mailable\n{\n    public function build()\n    {\n        return $this->view('greeting');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/CallQueuedHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\Events\\JobFailed;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\Event;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CallQueuedHandlerTest extends TestCase\n{\n    public function testJobCanBeDispatched()\n    {\n        CallQueuedHandlerTestJob::$handled = false;\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize(new CallQueuedHandlerTestJob),\n        ]);\n\n        $this->assertTrue(CallQueuedHandlerTestJob::$handled);\n    }\n\n    public function testJobCanBeDispatchedThroughMiddleware()\n    {\n        CallQueuedHandlerTestJobWithMiddleware::$handled = false;\n        CallQueuedHandlerTestJobWithMiddleware::$middlewareCommand = null;\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = new CallQueuedHandlerTestJobWithMiddleware),\n        ]);\n\n        $this->assertInstanceOf(CallQueuedHandlerTestJobWithMiddleware::class, CallQueuedHandlerTestJobWithMiddleware::$middlewareCommand);\n        $this->assertTrue(CallQueuedHandlerTestJobWithMiddleware::$handled);\n    }\n\n    public function testJobCanBeDispatchedThroughMiddlewareOnDispatch()\n    {\n        $_SERVER['__test.dispatchMiddleware'] = false;\n        CallQueuedHandlerTestJobWithMiddleware::$handled = false;\n        CallQueuedHandlerTestJobWithMiddleware::$middlewareCommand = null;\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $command = $command = new CallQueuedHandlerTestJobWithMiddleware;\n        $command->through([new TestJobMiddleware]);\n\n        $instance->call($job, [\n            'command' => serialize($command),\n        ]);\n\n        $this->assertInstanceOf(CallQueuedHandlerTestJobWithMiddleware::class, CallQueuedHandlerTestJobWithMiddleware::$middlewareCommand);\n        $this->assertTrue(CallQueuedHandlerTestJobWithMiddleware::$handled);\n        $this->assertTrue($_SERVER['__test.dispatchMiddleware']);\n    }\n\n    public function testJobIsMarkedAsFailedIfModelNotFoundExceptionIsThrown()\n    {\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('payload')->andReturn(['deleteWhenMissingModels' => false]);\n        $job->shouldReceive('fail')->once();\n\n        $instance->call($job, [\n            'command' => serialize(new CallQueuedHandlerExceptionThrowerWithoutDelete),\n        ]);\n    }\n\n    public function testJobIsDeletedIfHasDeleteProperty()\n    {\n        Event::fake();\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('payload')->andReturn(['deleteWhenMissingModels' => true]);\n        $job->shouldReceive('getConnectionName')->andReturn('connection');\n        $job->shouldReceive('resolveQueuedJobClass')->andReturn(CallQueuedHandlerExceptionThrower::class);\n        $job->shouldReceive('markAsFailed')->never();\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n        $job->shouldReceive('failed')->never();\n\n        $instance->call($job, [\n            'command' => serialize(new CallQueuedHandlerExceptionThrower),\n        ]);\n\n        Event::assertNotDispatched(JobFailed::class);\n    }\n\n    public function testJobIsDeletedIfHasDeleteAttribute()\n    {\n        Event::fake();\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('payload')->andReturn(['deleteWhenMissingModels' => true]);\n        $job->shouldReceive('getConnectionName')->andReturn('connection');\n        $job->shouldReceive('resolveQueuedJobClass')->andReturn(CallQueuedHandlerAttributeExceptionThrower::class);\n        $job->shouldReceive('markAsFailed')->never();\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n        $job->shouldReceive('failed')->never();\n\n        $instance->call($job, [\n            'command' => serialize(new CallQueuedHandlerAttributeExceptionThrower()),\n        ]);\n\n        Event::assertNotDispatched(JobFailed::class);\n    }\n\n    public function testBatchJobIsRecordedWhenDeletedDueToMissingModel()\n    {\n        Event::fake();\n\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $batch = m::mock(Batch::class);\n        $batch->shouldReceive('recordSuccessfulJob')->once()->with('job-uuid');\n\n        $repository = m::mock(BatchRepository::class);\n        $repository->shouldReceive('find')->once()->with('test-batch-id')->andReturn($batch);\n        $this->app->instance(BatchRepository::class, $repository);\n\n        $serialized = serialize((new CallQueuedHandlerBatchableExceptionThrower)->withBatchId('test-batch-id'));\n\n        $job = m::mock(Job::class);\n        $job->shouldReceive('resolveQueuedJobClass')->andReturn(CallQueuedHandlerBatchableExceptionThrower::class);\n        $job->shouldReceive('markAsFailed')->never();\n        $job->shouldReceive('isDeleted')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n        $job->shouldReceive('failed')->never();\n        $job->shouldReceive('uuid')->andReturn('job-uuid');\n        $job->shouldReceive('payload')->andReturn([\n            'deleteWhenMissingModels' => true,\n            'data' => [\n                'batchId' => 'test-batch-id',\n                'command' => $serialized,\n            ],\n        ]);\n\n        $instance->call($job, [\n            'command' => $serialized,\n        ]);\n\n        Event::assertNotDispatched(JobFailed::class);\n    }\n}\n\nclass CallQueuedHandlerTestJob\n{\n    use InteractsWithQueue;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n}\n\n/** This exists to test that middleware can also be defined in base classes */\nabstract class AbstractCallQueuedHandlerTestJobWithMiddleware\n{\n    public static $middlewareCommand;\n\n    public function middleware()\n    {\n        return [\n            new class\n            {\n                public function handle($command, $next)\n                {\n                    AbstractCallQueuedHandlerTestJobWithMiddleware::$middlewareCommand = $command;\n\n                    return $next($command);\n                }\n            },\n        ];\n    }\n}\n\nclass CallQueuedHandlerTestJobWithMiddleware extends AbstractCallQueuedHandlerTestJobWithMiddleware\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n}\n\nclass CallQueuedHandlerExceptionThrower\n{\n    public $deleteWhenMissingModels = true;\n\n    public function handle()\n    {\n        //\n    }\n\n    public function __wakeup()\n    {\n        throw new ModelNotFoundException('Foo');\n    }\n}\n\nclass CallQueuedHandlerExceptionThrowerWithoutDelete\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function __wakeup()\n    {\n        throw new ModelNotFoundException('Foo');\n    }\n}\n\n#[DeleteWhenMissingModels]\nclass CallQueuedHandlerAttributeExceptionThrower\n{\n    public function handle()\n    {\n        //\n    }\n\n    public function __wakeup()\n    {\n        throw new ModelNotFoundException('Foo');\n    }\n}\n\n#[DeleteWhenMissingModels]\nclass CallQueuedHandlerBatchableExceptionThrower\n{\n    use Batchable, InteractsWithQueue;\n\n    public function handle()\n    {\n        //\n    }\n\n    public function __wakeup()\n    {\n        throw new ModelNotFoundException('Foo');\n    }\n}\n\nclass TestJobMiddleware\n{\n    public function handle($command, $next)\n    {\n        $_SERVER['__test.dispatchMiddleware'] = true;\n\n        return $next($command);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/CustomPayloadTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Contracts\\Bus\\QueueingDispatcher;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Testing\\TestCase;\nuse Illuminate\\Queue\\Queue;\nuse Illuminate\\Support\\ServiceProvider;\nuse Orchestra\\Testbench\\Concerns\\CreatesApplication;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass CustomPayloadTest extends TestCase\n{\n    use CreatesApplication;\n\n    protected function getPackageProviders($app)\n    {\n        return [QueueServiceProvider::class];\n    }\n\n    public static function websites()\n    {\n        yield ['laravel.com'];\n\n        yield ['blog.laravel.com'];\n    }\n\n    #[DataProvider('websites')]\n    public function test_custom_payload_gets_cleared_for_each_data_provider(string $websites)\n    {\n        $dispatcher = $this->app->make(QueueingDispatcher::class);\n\n        $dispatcher->dispatchToQueue(new MyJob);\n    }\n}\n\nclass QueueServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        $this->app->bind('one.time.password', function () {\n            return random_int(1, 10);\n        });\n\n        Queue::createPayloadUsing(function () {\n            $password = $this->app->make('one.time.password');\n\n            $this->app->offsetUnset('one.time.password');\n\n            return ['password' => $password];\n        });\n    }\n}\n\nclass MyJob implements ShouldQueue\n{\n    public $connection = 'sync';\n\n    public function handle()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/DeleteModelWhenMissingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass DeleteModelWhenMissingTest extends QueueTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n        $app['config']->set('queue.default', 'database');\n        $this->driver = 'database';\n    }\n\n    protected function defineDatabaseMigrationsAfterDatabaseRefreshed()\n    {\n        Schema::create('delete_model_test_models', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::dropIfExists('delete_model_test_models');\n    }\n\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        DeleteMissingModelJob::$handled = false;\n\n        parent::tearDown();\n    }\n\n    public function test_deleteModelWhenMissing_and_display_name(): void\n    {\n        $model = MyTestModel::query()->create(['name' => 'test']);\n\n        DeleteMissingModelJob::dispatch($model);\n\n        MyTestModel::query()->where('name', 'test')->delete();\n\n        $this->runQueueWorkerCommand(['--once' => '1']);\n\n        $this->assertFalse(DeleteMissingModelJob::$handled);\n        $this->assertNull(\\DB::table('failed_jobs')->first());\n    }\n}\n\nclass DeleteMissingModelJob implements ShouldQueue\n{\n    use InteractsWithQueue;\n    use Dispatchable;\n    use SerializesModels;\n\n    public static bool $handled = false;\n\n    public $deleteWhenMissingModels = true;\n\n    public function __construct(public MyTestModel $model)\n    {\n    }\n\n    public function displayName(): string\n    {\n        return 'sorry-ma-forgot-to-take-out-the-trash';\n    }\n\n    public function handle()\n    {\n        self::$handled = true;\n    }\n}\n\nclass MyTestModel extends Model\n{\n    protected $table = 'delete_model_test_models';\n\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n"
  },
  {
    "path": "tests/Integration/Queue/DeleteNotificationWhenMissingModelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Queue\\Attributes\\DeleteWhenMissingModels;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Notification as NotificationFacade;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass DeleteNotificationWhenMissingModelTest extends QueueTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n        $app['config']->set('queue.default', 'database');\n        $this->driver = 'database';\n    }\n\n    protected function defineDatabaseMigrationsAfterDatabaseRefreshed()\n    {\n        Schema::create('delete_notification_test_models', function (Blueprint $table) {\n            $table->id();\n            $table->string('name');\n        });\n    }\n\n    protected function destroyDatabaseMigrations()\n    {\n        Schema::dropIfExists('delete_notification_test_models');\n    }\n\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        DeleteWhenMissingNotification::$sent = false;\n\n        parent::tearDown();\n    }\n\n    public function test_deleteModelWhenMissing_on_queued_notification(): void\n    {\n        $model = DeleteNotificationTestModel::query()->create(['name' => 'test']);\n\n        NotificationFacade::send($model, new DeleteWhenMissingNotification($model));\n\n        DeleteNotificationTestModel::query()->where('name', 'test')->delete();\n\n        $this->runQueueWorkerCommand(['--once' => '1']);\n\n        $this->assertFalse(DeleteWhenMissingNotification::$sent);\n        $this->assertNull(\\DB::table('failed_jobs')->first());\n    }\n}\n\nclass DeleteNotificationTestModel extends Model\n{\n    use Notifiable;\n\n    protected $table = 'delete_notification_test_models';\n\n    public $timestamps = false;\n\n    protected $guarded = [];\n}\n\n#[DeleteWhenMissingModels]\nclass DeleteWhenMissingNotification extends Notification implements ShouldQueue\n{\n    use Queueable, SerializesModels;\n\n    public static bool $sent = false;\n\n    public function __construct(public DeleteNotificationTestModel $model)\n    {\n    }\n\n    public function via($notifiable): array\n    {\n        return ['mail'];\n    }\n\n    public function toMail($notifiable)\n    {\n        static::$sent = true;\n\n        return new \\Illuminate\\Notifications\\Messages\\MailMessage;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/DynamoBatchTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\DynamoBatchRepository;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\Attributes\\RequiresEnv;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresEnv('DYNAMODB_ENDPOINT')]\nclass DynamoBatchTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            BatchRunRecorder::reset();\n            app(DynamoBatchRepository::class)->createAwsDynamoTable();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            app(DynamoBatchRepository::class)->deleteAwsDynamoTable();\n        });\n\n        parent::setUp();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('queue.batching', [\n            'driver' => 'dynamodb',\n            'region' => 'us-west-2',\n            'endpoint' => Env::get('DYNAMODB_ENDPOINT'),\n            'key' => 'key',\n            'secret' => 'secret',\n        ]);\n    }\n\n    public function test_running_a_batch()\n    {\n        Bus::batch([\n            new BatchJob('1'),\n            new BatchJob('2'),\n        ])->dispatch();\n\n        $this->assertEquals(['1', '2'], BatchRunRecorder::$results);\n    }\n\n    public function test_retrieve_batch_by_id()\n    {\n        $batch = Bus::batch([\n            new BatchJob('1'),\n            new BatchJob('2'),\n        ])->dispatch();\n\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $retrieved = $repo->find($batch->id);\n        $this->assertEquals(2, $retrieved->totalJobs);\n        $this->assertEquals(0, $retrieved->failedJobs);\n        $this->assertTrue($retrieved->finishedAt->between(Carbon::now()->subSecond(30), Carbon::now()));\n    }\n\n    public function test_retrieve_non_existent_batch()\n    {\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $retrieved = $repo->find(Str::orderedUuid());\n        $this->assertNull($retrieved);\n    }\n\n    public function test_delete_batch_by_id()\n    {\n        $batch = Bus::batch([\n            new BatchJob('1'),\n        ])->dispatch();\n\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $retrieved = $repo->find($batch->id);\n        $this->assertNotNull($retrieved);\n        $repo->delete($retrieved->id);\n        $retrieved = $repo->find($batch->id);\n        $this->assertNull($retrieved);\n    }\n\n    public function test_delete_non_existent_batch()\n    {\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $repo->delete(Str::orderedUuid());\n        // Ensure we didn't throw an exception\n        $this->assertTrue(true);\n    }\n\n    public function test_batch_with_failing_job()\n    {\n        $batch = Bus::batch([\n            new BatchJob('1'),\n            new FailingJob('2'),\n        ])->dispatch();\n\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $retrieved = $repo->find($batch->id);\n        $this->assertEquals(2, $retrieved->totalJobs);\n        $this->assertEquals(1, $retrieved->failedJobs);\n        $this->assertTrue($retrieved->finishedAt->between(Carbon::now()->subSecond(30), Carbon::now()));\n        $this->assertTrue($retrieved->cancelledAt->between(Carbon::now()->subSecond(30), Carbon::now()));\n    }\n\n    public function test_get_batches()\n    {\n        $batches = [\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n            Bus::batch([new BatchJob('1')])->dispatch(),\n        ];\n\n        /** @var DynamoBatchRepository */\n        $repo = app(DynamoBatchRepository::class);\n        $this->assertCount(10, $repo->get());\n        $this->assertCount(6, $repo->get(6));\n        $this->assertCount(6, $repo->get(100, $batches[6]->id));\n        $this->assertCount(0, $repo->get(100, $batches[0]->id));\n        $this->assertCount(9, $repo->get(100, $batches[9]->id));\n        $this->assertCount(10, $repo->get(100, Str::orderedUuid()));\n    }\n}\n\nclass BatchJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable;\n\n    public static $results = [];\n\n    public string $id;\n\n    public function __construct(string $id)\n    {\n        $this->id = $id;\n    }\n\n    public function handle()\n    {\n        BatchRunRecorder::record($this->id);\n    }\n}\n\nclass FailingJob extends BatchJob\n{\n    public function handle()\n    {\n        BatchRunRecorder::recordFailure($this->id);\n        $this->fail();\n    }\n}\n\nclass BatchRunRecorder\n{\n    public static $results = [];\n\n    public static $failures = [];\n\n    public static function record(string $id)\n    {\n        self::$results[] = $id;\n    }\n\n    public static function recordFailure(string $message)\n    {\n        self::$failures[] = $message;\n\n        return $message;\n    }\n\n    public static function reset()\n    {\n        self::$results = [];\n        self::$failures = [];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/DynamoBatchTestWithTTL.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Support\\Env;\nuse Orchestra\\Testbench\\Attributes\\RequiresEnv;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\n\n#[RequiresOperatingSystem('Linux|Darwin')]\n#[RequiresEnv('DYNAMODB_ENDPOINT')]\nclass DynamoBatchTestWithTTL extends DynamoBatchTest\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('queue.batching', [\n            'driver' => 'dynamodb',\n            'region' => 'us-west-2',\n            'endpoint' => Env::get('DYNAMODB_ENDPOINT'),\n            'key' => 'key',\n            'secret' => 'secret',\n            'ttl' => 1,\n            'ttlAttribute' => 'ttl_value',\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/Fixtures/Jobs/DeleteUser.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue\\Fixtures\\Jobs;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass DeleteUser implements ShouldQueue\n{\n    use Queueable;\n\n    /**\n     * Create a new job instance.\n     */\n    public function __construct(\n        public User $user\n    ) {\n        log($user);\n    }\n\n    /**\n     * Execute the job.\n     */\n    public function handle(): void\n    {\n        $this->user->delete();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/JobChainingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Foundation\\Bus\\PendingChain;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass JobChainingTest extends QueueTestCase\n{\n    use DatabaseMigrations;\n\n    public static $catchCallbackRan = false;\n\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set([\n            'queue.connections.sync1' => ['driver' => 'sync'],\n            'queue.connections.sync2' => ['driver' => 'sync'],\n        ]);\n    }\n\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            JobRunRecorder::reset();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            JobChainingTestFirstJob::$ran = false;\n            JobChainingTestSecondJob::$ran = false;\n            JobChainingTestThirdJob::$ran = false;\n            static::$catchCallbackRan = false;\n        });\n\n        parent::setUp();\n    }\n\n    public function testJobsCanBeChainedOnSuccess()\n    {\n        JobChainingTestFirstJob::dispatch()->chain([\n            new JobChainingTestSecondJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsCanBeChainedOnSuccessUsingPendingChain()\n    {\n        JobChainingTestFirstJob::withChain([\n            new JobChainingTestSecondJob,\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsCanBeChainedOnSuccessUsingBusFacade()\n    {\n        Bus::dispatchChain([\n            new JobChainingTestFirstJob,\n            new JobChainingTestSecondJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsCanBeChainedOnSuccessUsingBusFacadeAsArguments()\n    {\n        Bus::dispatchChain(\n            new JobChainingTestFirstJob,\n            new JobChainingTestSecondJob\n        );\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsChainedOnExplicitDelete()\n    {\n        JobChainingTestDeletingJob::dispatch()->chain([\n            new JobChainingTestSecondJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestDeletingJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsCanBeChainedOnSuccessWithSeveralJobs()\n    {\n        JobChainingTestFirstJob::dispatch()->chain([\n            new JobChainingTestSecondJob,\n            new JobChainingTestThirdJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n        $this->assertTrue(JobChainingTestThirdJob::$ran);\n    }\n\n    public function testJobsCanBeChainedOnSuccessUsingHelper()\n    {\n        dispatch(new JobChainingTestFirstJob)->chain([\n            new JobChainingTestSecondJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsCanBeChainedViaQueue()\n    {\n        Queue::push((new JobChainingTestFirstJob)->chain([\n            new JobChainingTestSecondJob,\n        ]));\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testSecondJobIsNotFiredIfFirstFailed()\n    {\n        Queue::push((new JobChainingTestFailingJob)->chain([\n            new JobChainingTestSecondJob,\n        ]));\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testSecondJobIsNotFiredIfFirstReleased()\n    {\n        Queue::push((new JobChainingTestReleasingJob)->chain([\n            new JobChainingTestSecondJob,\n        ]));\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testThirdJobIsNotFiredIfSecondFails()\n    {\n        Queue::push((new JobChainingTestFirstJob)->chain([\n            new JobChainingTestFailingJob,\n            new JobChainingTestThirdJob,\n        ]));\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertFalse(JobChainingTestThirdJob::$ran);\n    }\n\n    public function testCatchCallbackIsCalledOnFailure()\n    {\n        Bus::chain([\n            new JobChainingTestFirstJob,\n            new JobChainingTestFailingJob,\n            new JobChainingTestSecondJob,\n        ])->catch(static function () {\n            self::$catchCallbackRan = true;\n        })->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(static::$catchCallbackRan);\n        $this->assertFalse(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testChainJobsUseSameConfig()\n    {\n        JobChainingTestFirstJob::dispatch()->allOnQueue('some_queue')->allOnConnection('sync1')->chain([\n            new JobChainingTestSecondJob,\n            new JobChainingTestThirdJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertSame('some_queue', JobChainingTestFirstJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestFirstJob::$usedConnection);\n\n        $this->assertSame('some_queue', JobChainingTestSecondJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestSecondJob::$usedConnection);\n\n        $this->assertSame('some_queue', JobChainingTestThirdJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestThirdJob::$usedConnection);\n    }\n\n    public function testChainJobsUseOwnConfig()\n    {\n        JobChainingTestFirstJob::dispatch()->allOnQueue('some_queue')->allOnConnection('sync1')->chain([\n            (new JobChainingTestSecondJob)->onQueue('another_queue')->onConnection('sync2'),\n            new JobChainingTestThirdJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertSame('some_queue', JobChainingTestFirstJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestFirstJob::$usedConnection);\n\n        $this->assertSame('another_queue', JobChainingTestSecondJob::$usedQueue);\n        $this->assertSame('sync2', JobChainingTestSecondJob::$usedConnection);\n\n        $this->assertSame('some_queue', JobChainingTestThirdJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestThirdJob::$usedConnection);\n    }\n\n    public function testChainJobsUseDefaultConfig()\n    {\n        JobChainingTestFirstJob::dispatch()->onQueue('some_queue')->onConnection('sync1')->chain([\n            (new JobChainingTestSecondJob)->onQueue('another_queue')->onConnection('sync2'),\n            new JobChainingTestThirdJob,\n        ]);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertSame('some_queue', JobChainingTestFirstJob::$usedQueue);\n        $this->assertSame('sync1', JobChainingTestFirstJob::$usedConnection);\n\n        $this->assertSame('another_queue', JobChainingTestSecondJob::$usedQueue);\n        $this->assertSame('sync2', JobChainingTestSecondJob::$usedConnection);\n\n        $this->assertNull(JobChainingTestThirdJob::$usedQueue);\n        $this->assertNull(JobChainingTestThirdJob::$usedConnection);\n    }\n\n    public function testChainJobRemovesFalsy()\n    {\n        $job = (new JobChainingTestFirstJob)->chain([\n            new JobChainingTestSecondJob,\n            null,\n            '',\n            0,\n            [],\n        ]);\n\n        $this->assertCount(1, $job->chained);\n\n        Queue::push($job);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testChainJobsCanBePrepended()\n    {\n        JobChainAddingPrependingJob::withChain([new JobChainAddingExistingJob])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertNotNull(JobChainAddingAddedJob::$ranAt);\n        $this->assertNotNull(JobChainAddingExistingJob::$ranAt);\n        $this->assertTrue(JobChainAddingAddedJob::$ranAt->isBefore(JobChainAddingExistingJob::$ranAt));\n    }\n\n    public function testChainJobsCanBePrependedWithoutExistingChain()\n    {\n        JobChainAddingPrependingJob::dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertNotNull(JobChainAddingAddedJob::$ranAt);\n    }\n\n    public function testChainJobsCanBeAppended()\n    {\n        JobChainAddingAppendingJob::withChain([new JobChainAddingExistingJob])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertNotNull(JobChainAddingAddedJob::$ranAt);\n        $this->assertNotNull(JobChainAddingExistingJob::$ranAt);\n        $this->assertTrue(JobChainAddingAddedJob::$ranAt->isAfter(JobChainAddingExistingJob::$ranAt));\n    }\n\n    public function testChainJobsCanBePrependedBatch()\n    {\n        Bus::chain([\n            new JobChainAddingPrependedBatch('j1'),\n            new JobChainingNamedTestJob('j2'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['j1', 'b1', 'b2', 'j2'], JobRunRecorder::$results);\n    }\n\n    public function testChainJobsCanBeAppendedBatch()\n    {\n        Bus::chain([\n            new JobChainAddingAppendingBatch('j1'),\n            new JobChainingNamedTestJob('j2'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['j1', 'j2', 'b1', 'b2'], JobRunRecorder::$results);\n    }\n\n    public function testChainJobsCanBeAppendedWithoutExistingChain()\n    {\n        JobChainAddingAppendingJob::dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertNotNull(JobChainAddingAddedJob::$ranAt);\n    }\n\n    public function testChainCanBeAppended()\n    {\n        $chain = Bus::chain();\n\n        $chain->append($firstJob = new JobChainingNamedTestJob('j1'));\n        $chain->append($secondJob = new JobChainingNamedTestJob('j2'));\n        $chain->append($thirdJob = new JobChainingNamedTestJob('j3'));\n\n        $this->assertEquals($firstJob, $chain->job);\n        $this->assertEquals([$secondJob, $thirdJob], $chain->chain);\n    }\n\n    public function testChainCanBeAppendedWithInitialJob()\n    {\n        $chain = Bus::chain([\n            $firstJob = new JobChainingNamedTestJob('j1'),\n        ]);\n\n        $chain->append([\n            $secondJob = new JobChainingNamedTestJob('j2'),\n            $thirdJob = new JobChainingNamedTestJob('j3'),\n        ]);\n\n        $this->assertEquals($firstJob, $chain->job);\n        $this->assertEquals([$secondJob, $thirdJob], $chain->chain);\n    }\n\n    public function testChainRemovesFalsy()\n    {\n        $chain = Bus::chain([\n            $firstJob = new JobChainingTestFirstJob,\n            $secondJob = new JobChainingTestSecondJob,\n            null,\n            '',\n            0,\n            [],\n        ]);\n\n        $this->assertEquals($firstJob, $chain->job);\n        $this->assertEquals([$secondJob], $chain->chain);\n    }\n\n    public function testChainAppendRemovesFalsy()\n    {\n        $chain = Bus::chain([\n            $firstJob = new JobChainingNamedTestJob('j1'),\n        ]);\n\n        $chain->append([\n            $secondJob = new JobChainingNamedTestJob('j2'),\n            $thirdJob = new JobChainingNamedTestJob('j3'),\n            null,\n            '',\n            0,\n            [],\n        ]);\n\n        $this->assertEquals($firstJob, $chain->job);\n        $this->assertEquals([$secondJob, $thirdJob], $chain->chain);\n    }\n\n    public function testChainCanBePrepended()\n    {\n        $chain = Bus::chain();\n\n        $chain->prepend($firstJob = new JobChainingNamedTestJob('j1'));\n        $chain->prepend($secondJob = new JobChainingNamedTestJob('j2'));\n        $chain->prepend($thirdJob = new JobChainingNamedTestJob('j3'));\n\n        $this->assertEquals($thirdJob, $chain->job);\n        $this->assertEquals([$secondJob, $firstJob], $chain->chain);\n    }\n\n    public function testChainCanBePrependedWithInitialJob()\n    {\n        $chain = Bus::chain([\n            $firstJob = new JobChainingNamedTestJob('j4'),\n        ]);\n\n        $chain->prepend([\n            $secondJob = new JobChainingNamedTestJob('j1'),\n            $thirdJob = new JobChainingNamedTestJob('j2'),\n            $fourthJob = new JobChainingNamedTestJob('j3'),\n        ]);\n\n        $this->assertEquals($secondJob, $chain->job);\n        $this->assertEquals([$thirdJob, $fourthJob, $firstJob], $chain->chain);\n    }\n\n    public function testChainPrependRemovesFalsy()\n    {\n        $chain = Bus::chain([\n            $firstJob = new JobChainingNamedTestJob('j4'),\n        ]);\n\n        $chain->prepend([\n            $secondJob = new JobChainingNamedTestJob('j1'),\n            $thirdJob = new JobChainingNamedTestJob('j2'),\n            $fourthJob = new JobChainingNamedTestJob('j3'),\n            null,\n            '',\n            0,\n            [],\n        ]);\n\n        $this->assertEquals($secondJob, $chain->job);\n        $this->assertEquals([$thirdJob, $fourthJob, $firstJob], $chain->chain);\n    }\n\n    public function testBatchCanBeAddedToChain()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestBatchedJob('b2'),\n                new JobChainingTestBatchedJob('b3'),\n                new JobChainingTestBatchedJob('b4'),\n            ]),\n            new JobChainingNamedTestJob('c3'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['c1', 'c2', 'b1', 'b2', 'b3', 'b4', 'c3'], JobRunRecorder::$results);\n    }\n\n    public function testBatchInChainUsesCorrectQueue()\n    {\n        $otherQueue = $this->getQueueDriver() === 'redis' ? '{other}' : 'other';\n        Bus::chain([\n            (new JobChainingNamedTestJob('c1'))->onQueue($otherQueue),\n            (new JobChainingNamedTestJob('c2'))->onQueue($otherQueue),\n            Bus::batch([\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestBatchedJob('b2'),\n                new JobChainingTestBatchedJob('b3'),\n                new JobChainingTestBatchedJob('b4'),\n            ])->onQueue($otherQueue),\n            (new JobChainingNamedTestJob('c3'))->onQueue($otherQueue),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--queue' => $otherQueue, '--stop-when-empty' => true]);\n\n        $this->assertEquals(['c1', 'c2', 'b1', 'b2', 'b3', 'b4', 'c3'], JobRunRecorder::$results);\n    }\n\n    public function testDynamicBatchCanBeAddedToChain()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestBatchedJob('b2', times: 4),\n                new JobChainingTestBatchedJob('b3'),\n                new JobChainingTestBatchedJob('b4'),\n            ]),\n            new JobChainingNamedTestJob('c3'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        if ($this->getQueueDriver() === 'sync') {\n            $this->assertEquals(\n                ['c1', 'c2', 'b1', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'b2', 'b3', 'b4', 'c3'], JobRunRecorder::$results\n            );\n        } else {\n            $this->assertEquals(\n                ['c1', 'c2', 'b1', 'b2', 'b3', 'b4', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'c3'], JobRunRecorder::$results\n            );\n        }\n\n        $this->assertCount(11, JobRunRecorder::$results);\n    }\n\n    public function testChainBatchChain()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                [\n                    new JobChainingNamedTestJob('bc1'),\n                    new JobChainingNamedTestJob('bc2'),\n                ],\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestBatchedJob('b2', times: 4),\n                new JobChainingTestBatchedJob('b3'),\n                new JobChainingTestBatchedJob('b4'),\n            ]),\n            new JobChainingNamedTestJob('c3'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        if ($this->getQueueDriver() === 'sync') {\n            $this->assertEquals(\n                ['c1', 'c2', 'bc1', 'bc2', 'b1', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'b2', 'b3', 'b4', 'c3'], JobRunRecorder::$results\n            );\n        } else {\n            $this->assertEquals(\n                ['c1', 'c2', 'bc1', 'b1', 'b2', 'b3', 'b4', 'bc2', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'c3'], JobRunRecorder::$results\n            );\n        }\n\n        $this->assertCount(13, JobRunRecorder::$results);\n    }\n\n    public function testChainBatchChainBatch()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                [\n                    new JobChainingNamedTestJob('bc1'),\n                    new JobChainingNamedTestJob('bc2'),\n                    Bus::batch([\n                        new JobChainingTestBatchedJob('bb1'),\n                        new JobChainingTestBatchedJob('bb2'),\n                    ]),\n                ],\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestBatchedJob('b2', times: 4),\n                new JobChainingTestBatchedJob('b3'),\n                new JobChainingTestBatchedJob('b4'),\n            ]),\n            new JobChainingNamedTestJob('c3'),\n        ])->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        if ($this->getQueueDriver() === 'sync') {\n            $this->assertEquals(\n                ['c1', 'c2', 'bc1', 'bc2', 'bb1', 'bb2', 'b1', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'b2', 'b3', 'b4', 'c3'], JobRunRecorder::$results\n            );\n        } else {\n            $this->assertEquals(\n                ['c1', 'c2', 'bc1', 'b1', 'b2', 'b3', 'b4', 'bc2', 'b2-0', 'b2-1', 'b2-2', 'b2-3', 'bb1', 'bb2', 'c3'], JobRunRecorder::$results\n            );\n        }\n\n        $this->assertCount(15, JobRunRecorder::$results);\n    }\n\n    public function testBatchCatchCallbacks()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                new JobChainingTestFailingBatchedJob('fb1'),\n            ])->catch(fn () => JobRunRecorder::recordFailure('batch failed')),\n            new JobChainingNamedTestJob('c3'),\n        ])->catch(fn () => JobRunRecorder::recordFailure('chain failed'))->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['c1', 'c2'], JobRunRecorder::$results);\n        $this->assertEquals(['batch failed', 'chain failed'], JobRunRecorder::$failures);\n    }\n\n    public function testChainBatchFailureAllowed()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestFailingBatchedJob('b2'),\n                new JobChainingTestBatchedJob('b3'),\n            ])->allowFailures()->catch(fn () => JobRunRecorder::recordFailure('batch failed')),\n            new JobChainingNamedTestJob('c3'),\n        ])->catch(fn () => JobRunRecorder::recordFailure('chain failed'))->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['c1', 'c2', 'b1', 'b3', 'c3'], JobRunRecorder::$results);\n        // Only the batch failed, but the chain should keep going since the batch allows failures\n        $this->assertEquals(['batch failed'], JobRunRecorder::$failures);\n    }\n\n    public function testChainBatchFailureNotAllowed()\n    {\n        Bus::chain([\n            new JobChainingNamedTestJob('c1'),\n            new JobChainingNamedTestJob('c2'),\n            Bus::batch([\n                new JobChainingTestBatchedJob('b1'),\n                new JobChainingTestFailingBatchedJob('b2'),\n                new JobChainingTestBatchedJob('b3'),\n            ])->allowFailures(false)->catch(fn () => JobRunRecorder::recordFailure('batch failed')),\n            new JobChainingNamedTestJob('c3'),\n        ])->catch(fn () => JobRunRecorder::recordFailure('chain failed'))->dispatch();\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertEquals(['c1', 'c2', 'b1', 'b3'], JobRunRecorder::$results);\n        $this->assertEquals(['batch failed', 'chain failed'], JobRunRecorder::$failures);\n    }\n\n    public function testChainConditionable()\n    {\n        $chain = Bus::chain([])\n            ->onConnection('sync1')\n            ->when(true, function (PendingChain $chain) {\n                $chain->onConnection('sync2');\n            });\n\n        $this->assertEquals('sync2', $chain->connection);\n\n        $chain = Bus::chain([])\n            ->onConnection('sync1')\n            ->when(false, function (PendingChain $chain) {\n                $chain->onConnection('sync2');\n            });\n\n        $this->assertEquals('sync1', $chain->connection);\n    }\n\n    public function testBatchConditionable()\n    {\n        $batch = Bus::batch([])\n            ->onConnection('sync1')\n            ->when(true, function (PendingBatch $batch) {\n                $batch->onConnection('sync2');\n            });\n\n        $this->assertEquals('sync2', $batch->connection());\n        $batch = Bus::batch([])\n            ->onConnection('sync1')\n            ->when(false, function (PendingBatch $batch) {\n                $batch->onConnection('sync2');\n            });\n\n        $this->assertEquals('sync1', $batch->connection());\n    }\n\n    public function testJobsAreChainedWhenDispatchIfIsTrue()\n    {\n        JobChainingTestFirstJob::withChain([\n            new JobChainingTestSecondJob,\n        ])->dispatchIf(true);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsAreNotChainedWhenDispatchIfIsFalse()\n    {\n        JobChainingTestFirstJob::withChain([\n            new JobChainingTestSecondJob,\n        ])->dispatchIf(false);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(JobChainingTestFirstJob::$ran);\n        $this->assertFalse(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsAreChainedWhenDispatchUnlessIsFalse()\n    {\n        JobChainingTestFirstJob::withChain([\n            new JobChainingTestSecondJob,\n        ])->dispatchUnless(false);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(JobChainingTestFirstJob::$ran);\n        $this->assertTrue(JobChainingTestSecondJob::$ran);\n    }\n\n    public function testJobsAreNotChainedWhenDispatchUnlessIsTrue()\n    {\n        JobChainingTestFirstJob::withChain([\n            new JobChainingTestSecondJob,\n        ])->dispatchUnless(true);\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(JobChainingTestFirstJob::$ran);\n        $this->assertFalse(JobChainingTestSecondJob::$ran);\n    }\n}\n\nclass JobChainingTestFirstJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public static $usedQueue = null;\n\n    public static $usedConnection = null;\n\n    public function handle()\n    {\n        static::$ran = true;\n        static::$usedQueue = $this->queue;\n        static::$usedConnection = $this->connection;\n    }\n}\n\nclass JobChainingTestSecondJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public static $usedQueue = null;\n\n    public static $usedConnection = null;\n\n    public function handle()\n    {\n        static::$ran = true;\n        static::$usedQueue = $this->queue;\n        static::$usedConnection = $this->connection;\n    }\n}\n\nclass JobChainingTestThirdJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public static $usedQueue = null;\n\n    public static $usedConnection = null;\n\n    public function handle()\n    {\n        static::$ran = true;\n        static::$usedQueue = $this->queue;\n        static::$usedConnection = $this->connection;\n    }\n}\n\nclass JobChainingTestDeletingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n        $this->delete();\n    }\n}\n\nclass JobChainingTestReleasingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        $this->release(30);\n    }\n}\n\nclass JobChainingTestFailingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        $this->fail();\n    }\n}\n\nclass JobChainAddingPrependingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        $this->prependToChain(new JobChainAddingAddedJob);\n    }\n}\n\nclass JobChainAddingAppendingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        $this->appendToChain(new JobChainAddingAddedJob);\n    }\n}\n\nclass JobChainAddingAppendingBatch implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public string $id;\n\n    public function __construct(string $id)\n    {\n        $this->id = $id;\n    }\n\n    public function handle()\n    {\n        $this->appendToChain(Bus::batch([\n            new JobChainingNamedTestJob('b1'),\n            new JobChainingNamedTestJob('b2'),\n        ]));\n\n        JobRunRecorder::record($this->id);\n    }\n}\n\nclass JobChainAddingPrependedBatch implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public string $id;\n\n    public function __construct(string $id)\n    {\n        $this->id = $id;\n    }\n\n    public function handle()\n    {\n        $this->prependToChain(Bus::batch([\n            new JobChainingNamedTestJob('b1'),\n            new JobChainingNamedTestJob('b2'),\n        ]));\n\n        JobRunRecorder::record($this->id);\n    }\n}\n\nclass JobChainAddingExistingJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    /** @var Carbon|null */\n    public static $ranAt = null;\n\n    public function handle()\n    {\n        static::$ranAt = Carbon::now();\n    }\n}\n\nclass JobChainAddingAddedJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    /** @var Carbon|null */\n    public static $ranAt = null;\n\n    public function handle()\n    {\n        static::$ranAt = Carbon::now();\n    }\n}\n\nclass JobChainingTestThrowJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        throw new \\Exception();\n    }\n}\n\nclass JobChainingNamedTestJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable;\n\n    public static $results = [];\n\n    public string $id;\n\n    public function __construct(string $id)\n    {\n        $this->id = $id;\n    }\n\n    public function handle()\n    {\n        JobRunRecorder::record($this->id);\n    }\n}\n\nclass JobChainingTestBatchedJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable;\n\n    public string $id;\n\n    public int $times;\n\n    public function __construct(string $id, int $times = 0)\n    {\n        $this->id = $id;\n        $this->times = $times;\n    }\n\n    public function handle()\n    {\n        for ($i = 0; $i < $this->times; $i++) {\n            $this->batch()->add(new JobChainingTestBatchedJob($this->id.'-'.$i));\n        }\n        JobRunRecorder::record($this->id);\n    }\n}\n\nclass JobChainingTestFailingBatchedJob implements ShouldQueue\n{\n    use Batchable, Dispatchable, InteractsWithQueue, Queueable;\n\n    public function handle()\n    {\n        $this->fail();\n    }\n}\n\nclass JobRunRecorder\n{\n    public static $results = [];\n\n    public static $failures = [];\n\n    public static function record(string $id)\n    {\n        self::$results[] = $id;\n    }\n\n    public static function recordFailure(string $message)\n    {\n        self::$failures[] = $message;\n\n        return $message;\n    }\n\n    public static function reset()\n    {\n        self::$results = [];\n        self::$failures = [];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/JobDispatchingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Cache\\Repository;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\Events\\JobQueued;\nuse Illuminate\\Queue\\Events\\JobQueueing;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Config;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass JobDispatchingTest extends QueueTestCase\n{\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            Job::$ran = false;\n            Job::$value = null;\n        });\n\n        parent::setUp();\n    }\n\n    public function testJobCanUseCustomMethodsAfterDispatch()\n    {\n        Job::dispatch('test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(Job::$ran);\n        $this->assertSame('new-test', Job::$value);\n    }\n\n    public function testDispatchesConditionallyWithBoolean()\n    {\n        Job::dispatchIf(false, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(Job::$ran);\n        $this->assertNull(Job::$value);\n\n        Job::dispatchIf(true, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(Job::$ran);\n        $this->assertSame('new-test', Job::$value);\n    }\n\n    public function testDispatchesConditionallyWithClosure()\n    {\n        Job::dispatchIf(fn ($job) => $job instanceof Job ? 0 : 1, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(Job::$ran);\n\n        Job::dispatchIf(fn ($job) => $job instanceof Job ? 1 : 0, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(Job::$ran);\n    }\n\n    public function testDoesNotDispatchConditionallyWithBoolean()\n    {\n        Job::dispatchUnless(true, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(Job::$ran);\n        $this->assertNull(Job::$value);\n\n        Job::dispatchUnless(false, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(Job::$ran);\n        $this->assertSame('new-test', Job::$value);\n    }\n\n    public function testDoesNotDispatchConditionallyWithClosure()\n    {\n        Job::dispatchUnless(fn ($job) => $job instanceof Job ? 1 : 0, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertFalse(Job::$ran);\n\n        Job::dispatchUnless(fn ($job) => $job instanceof Job ? 0 : 1, 'test')->replaceValue('new-test');\n\n        $this->runQueueWorkerCommand(['--stop-when-empty' => true]);\n\n        $this->assertTrue(Job::$ran);\n    }\n\n    public function testUniqueJobLockIsReleasedForJobDispatchedAfterResponse()\n    {\n        // get initial terminatingCallbacks\n        $terminatingCallbacksReflectionProperty = (new \\ReflectionObject($this->app))->getProperty('terminatingCallbacks');\n        $startTerminatingCallbacks = $terminatingCallbacksReflectionProperty->getValue($this->app);\n\n        UniqueJob::dispatchAfterResponse('test');\n        $this->assertFalse(\n            $this->getJobLock(UniqueJob::class, 'test')\n        );\n\n        $this->app->terminate();\n        $this->assertTrue(UniqueJob::$ran);\n\n        $terminatingCallbacksReflectionProperty->setValue($this->app, $startTerminatingCallbacks);\n\n        UniqueJob::$ran = false;\n        UniqueJob::dispatch('test')->afterResponse();\n        $this->app->terminate();\n        $this->assertTrue(UniqueJob::$ran);\n\n        // acquire job lock and confirm that job is not dispatched after response\n        $this->assertTrue(\n            $this->getJobLock(UniqueJob::class, 'test')\n        );\n        $terminatingCallbacksReflectionProperty->setValue($this->app, $startTerminatingCallbacks);\n        UniqueJob::$ran = false;\n        UniqueJob::dispatch('test')->afterResponse();\n        $this->app->terminate();\n        $this->assertFalse(UniqueJob::$ran);\n\n        // confirm that dispatchAfterResponse also does not run\n        UniqueJob::dispatchAfterResponse('test');\n        $this->app->terminate();\n        $this->assertFalse(UniqueJob::$ran);\n    }\n\n    public function testQueueMayBeNullForJobQueueingAndJobQueuedEvent()\n    {\n        Config::set('queue.default', 'database');\n        $events = [];\n        $this->app['events']->listen(function (JobQueueing $e) use (&$events) {\n            $events[] = $e;\n        });\n        $this->app['events']->listen(function (JobQueued $e) use (&$events) {\n            $events[] = $e;\n        });\n\n        MyTestDispatchableJob::dispatch();\n        dispatch(function () {\n            //\n        });\n\n        $this->assertCount(4, $events);\n        $this->assertInstanceOf(JobQueueing::class, $events[0]);\n        $this->assertNull($events[0]->queue);\n        $this->assertInstanceOf(JobQueued::class, $events[1]);\n        $this->assertNull($events[1]->queue);\n        $this->assertInstanceOf(JobQueueing::class, $events[2]);\n        $this->assertNull($events[2]->queue);\n        $this->assertInstanceOf(JobQueued::class, $events[3]);\n        $this->assertNull($events[3]->queue);\n    }\n\n    public function testQueuedClosureCanBeNamed()\n    {\n        Config::set('queue.default', 'database');\n        $events = [];\n        $this->app['events']->listen(function (JobQueued $e) use (&$events) {\n            $events[] = $e;\n        });\n\n        dispatch(function () {\n            //\n        })->name('custom name');\n\n        $this->assertCount(1, $events);\n        $this->assertInstanceOf(JobQueued::class, $events[0]);\n        $this->assertSame('custom name', $events[0]->job->name);\n        $this->assertStringContainsString('custom name', $events[0]->job->displayName());\n    }\n\n    public function testCanDisableDispatchingAfterResponse()\n    {\n        Job::dispatchAfterResponse('test');\n\n        $this->assertFalse(Job::$ran);\n\n        $this->app->terminate();\n\n        $this->assertTrue(Job::$ran);\n\n        Bus::withoutDispatchingAfterResponses();\n\n        Job::$ran = false;\n        Job::dispatchAfterResponse('test');\n\n        $this->assertTrue(Job::$ran);\n\n        $this->app->terminate();\n\n        Bus::withDispatchingAfterResponses();\n\n        Job::$ran = false;\n        Job::dispatchAfterResponse('test');\n\n        $this->assertFalse(Job::$ran);\n\n        $this->app->terminate();\n\n        $this->assertTrue(Job::$ran);\n    }\n\n    /**\n     * Helpers.\n     */\n    private function getJobLock($job, $value = null)\n    {\n        return $this->app->get(Repository::class)->lock('laravel_unique_job:'.$job.':'.$value, 10)->get();\n    }\n}\n\nclass Job implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n    public static $usedQueue = null;\n    public static $usedConnection = null;\n    public static $value = null;\n\n    public function __construct($value)\n    {\n        static::$value = $value;\n    }\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n\n    public function replaceValue($value)\n    {\n        static::$value = $value;\n    }\n}\n\nclass UniqueJob extends Job implements ShouldBeUnique\n{\n    use InteractsWithQueue;\n\n    public function uniqueId()\n    {\n        return self::$value;\n    }\n}\n\nclass MyTestDispatchableJob implements ShouldQueue\n{\n    use Dispatchable;\n}\n"
  },
  {
    "path": "tests/Integration/Queue/JobEncryptionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Encryption\\DecryptException;\nuse Illuminate\\Contracts\\Queue\\ShouldBeEncrypted;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass JobEncryptionTest extends DatabaseTestCase\n{\n    use DatabaseMigrations;\n\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('queue.default', 'database');\n    }\n\n    protected function tearDown(): void\n    {\n        JobEncryptionTestEncryptedJob::$ran = false;\n        JobEncryptionTestNonEncryptedJob::$ran = false;\n\n        parent::tearDown();\n    }\n\n    public function testEncryptedJobPayloadIsStoredEncrypted()\n    {\n        Bus::dispatch(new JobEncryptionTestEncryptedJob);\n\n        $this->assertNotEmpty(\n            decrypt(json_decode(DB::table('jobs')->first()->payload)->data->command)\n        );\n    }\n\n    public function testNonEncryptedJobPayloadIsStoredRaw()\n    {\n        Bus::dispatch(new JobEncryptionTestNonEncryptedJob);\n\n        $this->expectException(DecryptException::class);\n        $this->expectExceptionMessage('The payload is invalid');\n\n        $this->assertInstanceOf(JobEncryptionTestNonEncryptedJob::class,\n            unserialize(json_decode(DB::table('jobs')->first()->payload)->data->command)\n        );\n\n        decrypt(json_decode(DB::table('jobs')->first()->payload)->data->command);\n    }\n\n    public function testQueueCanProcessEncryptedJob()\n    {\n        Bus::dispatch(new JobEncryptionTestEncryptedJob);\n\n        Queue::pop()->fire();\n\n        $this->assertTrue(JobEncryptionTestEncryptedJob::$ran);\n    }\n\n    public function testQueueCanProcessUnEncryptedJob()\n    {\n        Bus::dispatch(new JobEncryptionTestNonEncryptedJob);\n\n        Queue::pop()->fire();\n\n        $this->assertTrue(JobEncryptionTestNonEncryptedJob::$ran);\n    }\n}\n\nclass JobEncryptionTestEncryptedJob implements ShouldQueue, ShouldBeEncrypted\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n\nclass JobEncryptionTestNonEncryptedJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/ModelSerializationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Contracts\\Database\\ModelIdentifier;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Boot;\nuse Illuminate\\Database\\Eloquent\\Attributes\\Initialize;\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\Pivot;\nuse Illuminate\\Database\\Eloquent\\Relations\\Relation;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Queue\\Attributes\\WithoutRelations;\nuse Illuminate\\Queue\\SerializesModels;\nuse LogicException;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Schema;\n\nclass ModelSerializationTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('database.connections.custom', [\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n            'prefix' => '',\n        ]);\n    }\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Model::preventLazyLoading(false);\n\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n        });\n\n        Schema::connection('custom')->create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('email');\n        });\n\n        Schema::create('orders', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('lines', function (Blueprint $table) {\n            $table->increments('id');\n            $table->unsignedInteger('order_id');\n            $table->unsignedInteger('product_id');\n        });\n\n        Schema::create('products', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('roles', function (Blueprint $table) {\n            $table->increments('id');\n        });\n\n        Schema::create('role_user', function (Blueprint $table) {\n            $table->unsignedInteger('user_id');\n            $table->unsignedInteger('role_id');\n        });\n    }\n\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        Relation::morphMap([], false);\n        ModelIdentifier::useMorphMap(false);\n\n        parent::tearDown();\n    }\n\n    public function testItSerializeUserOnDefaultConnection()\n    {\n        $defaultConnection = config('database.default');\n\n        $user = ModelSerializationTestUser::create([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        ModelSerializationTestUser::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new ModelSerializationTestClass($user));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame($defaultConnection, $unSerialized->user->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->user->email);\n\n        $serialized = serialize(new CollectionSerializationTestClass(ModelSerializationTestUser::on($defaultConnection)->get()));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame($defaultConnection, $unSerialized->users[0]->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->users[0]->email);\n        $this->assertSame($defaultConnection, $unSerialized->users[1]->getConnectionName());\n        $this->assertSame('taylor@laravel.com', $unSerialized->users[1]->email);\n    }\n\n    public function testItSerializeUserOnDifferentConnection()\n    {\n        $user = ModelSerializationTestUser::on('custom')->create([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        ModelSerializationTestUser::on('custom')->create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new ModelSerializationTestClass($user));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame('custom', $unSerialized->user->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->user->email);\n\n        $serialized = serialize(new CollectionSerializationTestClass(ModelSerializationTestUser::on('custom')->get()));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame('custom', $unSerialized->users[0]->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->users[0]->email);\n        $this->assertSame('custom', $unSerialized->users[1]->getConnectionName());\n        $this->assertSame('taylor@laravel.com', $unSerialized->users[1]->email);\n    }\n\n    public function testItFailsIfModelsOnMultiConnections()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Queueing collections with multiple model connections is not supported.');\n\n        $user = ModelSerializationTestUser::on('custom')->create([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        $user2 = ModelSerializationTestUser::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new CollectionSerializationTestClass(\n            new Collection([$user, $user2])\n        ));\n\n        unserialize($serialized);\n    }\n\n    public function testItReloadsRelationships()\n    {\n        $order = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $product1 = Product::create();\n        $product2 = Product::create();\n\n        Line::create(['order_id' => $order->id, 'product_id' => $product1->id]);\n        Line::create(['order_id' => $order->id, 'product_id' => $product2->id]);\n\n        $order->load('line', 'lines', 'products');\n\n        $serialized = serialize(new ModelRelationSerializationTestClass($order));\n        $unSerialized = unserialize($serialized);\n\n        $this->assertEquals($unSerialized->order->getRelations(), $order->getRelations());\n    }\n\n    public function testItReloadsRelationshipsOnlyOnce()\n    {\n        $order = tap(ModelSerializationTestCustomOrder::create(), function (ModelSerializationTestCustomOrder $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $product1 = Product::create();\n        $product2 = Product::create();\n\n        Line::create(['order_id' => $order->id, 'product_id' => $product1->id]);\n        Line::create(['order_id' => $order->id, 'product_id' => $product2->id]);\n\n        $order->load('line', 'lines', 'products');\n\n        $this->expectsDatabaseQueryCount(4);\n\n        $serialized = serialize(new ModelRelationSerializationTestClass($order));\n        $unSerialized = unserialize($serialized);\n\n        $this->assertEquals($unSerialized->order->getRelations(), $order->getRelations());\n    }\n\n    public function testItReloadsNestedRelationships()\n    {\n        $order = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $product1 = Product::create();\n        $product2 = Product::create();\n\n        Line::create(['order_id' => $order->id, 'product_id' => $product1->id]);\n        Line::create(['order_id' => $order->id, 'product_id' => $product2->id]);\n\n        $order->load('line.product', 'lines', 'lines.product', 'products');\n\n        $nestedSerialized = serialize(new ModelRelationSerializationTestClass($order));\n        $nestedUnSerialized = unserialize($nestedSerialized);\n\n        $this->assertEquals($nestedUnSerialized->order->getRelations(), $order->getRelations());\n    }\n\n    public function testItReloadsRelationshipsForCollections()\n    {\n        $order1 = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $order2 = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $product1 = Product::create();\n        $product2 = Product::create();\n\n        Line::create(['order_id' => $order1->id, 'product_id' => $product1->id]);\n        Line::create(['order_id' => $order2->id, 'product_id' => $product2->id]);\n\n        $orders = Order::with('line', 'lines', 'products')->get();\n\n        $serialized = serialize(new CollectionRelationSerializationTestClass($orders));\n        $unSerialized = unserialize($serialized);\n\n        $this->assertCount(2, $unSerialized->orders);\n        $this->assertTrue($unSerialized->orders[0]->relationLoaded('line'));\n        $this->assertTrue($unSerialized->orders[0]->relationLoaded('lines'));\n        $this->assertTrue($unSerialized->orders[0]->relationLoaded('products'));\n        $this->assertTrue($unSerialized->orders[1]->relationLoaded('line'));\n        $this->assertTrue($unSerialized->orders[1]->relationLoaded('lines'));\n        $this->assertTrue($unSerialized->orders[1]->relationLoaded('products'));\n    }\n\n    public function testItReloadsNestedRelationshipsForCollections()\n    {\n        $order1 = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $order2 = tap(Order::create(), function (Order $order) {\n            $order->wasRecentlyCreated = false;\n        });\n\n        $product1 = Product::create();\n        $product2 = Product::create();\n\n        Line::create(['order_id' => $order1->id, 'product_id' => $product1->id]);\n        Line::create(['order_id' => $order2->id, 'product_id' => $product2->id]);\n\n        $orders = Order::with('line.product', 'lines.product')->get();\n\n        $serialized = serialize(new CollectionRelationSerializationTestClass($orders));\n        $unSerialized = unserialize($serialized);\n\n        $this->assertCount(2, $unSerialized->orders);\n        $this->assertTrue($unSerialized->orders[0]->relationLoaded('line'));\n        $this->assertTrue($unSerialized->orders[0]->line->relationLoaded('product'));\n        $this->assertTrue($unSerialized->orders[0]->relationLoaded('lines'));\n        $this->assertTrue($unSerialized->orders[0]->lines->first()->relationLoaded('product'));\n        $this->assertTrue($unSerialized->orders[1]->relationLoaded('line'));\n        $this->assertTrue($unSerialized->orders[1]->line->relationLoaded('product'));\n        $this->assertTrue($unSerialized->orders[1]->relationLoaded('lines'));\n        $this->assertTrue($unSerialized->orders[1]->lines->first()->relationLoaded('product'));\n    }\n\n    public function testItCanRunModelBootsAndTraitInitializations()\n    {\n        $model = new ModelBootTestWithTraitInitialization();\n\n        $this->assertTrue($model->fooBar);\n        $this->assertTrue($model->initializedViaAttributeInClass);\n        $this->assertTrue($model->initializedViaAttributeInTrait);\n        $this->assertTrue($model::hasGlobalScope('foo_bar'));\n        $this->assertTrue($model::hasGlobalScope('booted_attr_in_class'));\n        $this->assertTrue($model::hasGlobalScope('booted_attr_in_trait'));\n\n        $model::clearBootedModels();\n\n        $this->assertFalse($model::hasGlobalScope('foo_bar'));\n        $this->assertFalse($model::hasGlobalScope('booted_attr_in_class'));\n        $this->assertFalse($model::hasGlobalScope('booted_attr_in_trait'));\n\n        $unSerializedModel = unserialize(serialize($model));\n\n        $this->assertFalse($unSerializedModel->fooBar);\n        $this->assertFalse($unSerializedModel->initializedViaAttributeInClass);\n        $this->assertFalse($unSerializedModel->initializedViaAttributeInTrait);\n        $this->assertTrue($model::hasGlobalScope('foo_bar'));\n        $this->assertTrue($model::hasGlobalScope('booted_attr_in_class'));\n        $this->assertTrue($model::hasGlobalScope('booted_attr_in_trait'));\n    }\n\n    /**\n     * Regression test for https://github.com/laravel/framework/issues/23068.\n     */\n    public function testItCanUnserializeNestedRelationshipsWithoutPivot()\n    {\n        $user = tap(User::create([\n            'email' => 'taylor@laravel.com',\n        ]), function (User $user) {\n            $user->wasRecentlyCreated = false;\n        });\n\n        $role1 = Role::create();\n        $role2 = Role::create();\n\n        RoleUser::create(['user_id' => $user->id, 'role_id' => $role1->id]);\n        RoleUser::create(['user_id' => $user->id, 'role_id' => $role2->id]);\n\n        $user->roles->each(function ($role) {\n            $role->pivot->load('user', 'role');\n        });\n\n        $serialized = serialize(new ModelSerializationTestClass($user));\n        unserialize($serialized);\n    }\n\n    public function testItSerializesAnEmptyCollection()\n    {\n        $serialized = serialize(new CollectionSerializationTestClass(\n            new Collection([])\n        ));\n\n        unserialize($serialized);\n    }\n\n    public function testItSerializesACollectionInCorrectOrder()\n    {\n        ModelSerializationTestUser::create(['email' => 'mohamed@laravel.com']);\n        ModelSerializationTestUser::create(['email' => 'taylor@laravel.com']);\n\n        $serialized = serialize(new CollectionSerializationTestClass(\n            ModelSerializationTestUser::orderByDesc('email')->get()\n        ));\n\n        $unserialized = unserialize($serialized);\n\n        $this->assertSame('taylor@laravel.com', $unserialized->users->first()->email);\n        $this->assertSame('mohamed@laravel.com', $unserialized->users->last()->email);\n    }\n\n    public function testItCanUnserializeACollectionInCorrectOrderAndHandleDeletedModels()\n    {\n        ModelSerializationTestUser::create(['email' => '2@laravel.com']);\n        ModelSerializationTestUser::create(['email' => '3@laravel.com']);\n        ModelSerializationTestUser::create(['email' => '1@laravel.com']);\n\n        $serialized = serialize(new CollectionSerializationTestClass(\n            ModelSerializationTestUser::orderByDesc('email')->get()\n        ));\n\n        ModelSerializationTestUser::where(['email' => '2@laravel.com'])->delete();\n\n        $unserialized = unserialize($serialized);\n\n        $this->assertCount(2, $unserialized->users);\n\n        $this->assertSame('3@laravel.com', $unserialized->users->first()->email);\n        $this->assertSame('1@laravel.com', $unserialized->users->last()->email);\n    }\n\n    public function testItCanUnserializeCustomCollection()\n    {\n        ModelSerializationTestCustomUser::create(['email' => 'mohamed@laravel.com']);\n        ModelSerializationTestCustomUser::create(['email' => 'taylor@laravel.com']);\n\n        $serialized = serialize(new CollectionSerializationTestClass(\n            ModelSerializationTestCustomUser::all()\n        ));\n\n        $unserialized = unserialize($serialized);\n\n        $this->assertInstanceOf(ModelSerializationTestCustomUserCollection::class, $unserialized->users);\n    }\n\n    public function testItSerializesTypedProperties()\n    {\n        require_once __DIR__.'/typed-properties.php';\n\n        $defaultConnection = config('database.default');\n\n        $user = ModelSerializationTestUser::create([\n            'email' => 'mohamed@laravel.com',\n        ]);\n\n        ModelSerializationTestUser::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new TypedPropertyTestClass($user, 5, ['James', 'Taylor', 'Mohamed']));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame($defaultConnection, $unSerialized->user->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->user->email);\n        $this->assertSame(5, $unSerialized->getId());\n        $this->assertSame(['James', 'Taylor', 'Mohamed'], $unSerialized->getNames());\n\n        $serialized = serialize(new TypedPropertyCollectionTestClass(ModelSerializationTestUser::on($defaultConnection)->get()));\n\n        $unSerialized = unserialize($serialized);\n\n        $this->assertSame($defaultConnection, $unSerialized->users[0]->getConnectionName());\n        $this->assertSame('mohamed@laravel.com', $unSerialized->users[0]->email);\n        $this->assertSame($defaultConnection, $unSerialized->users[1]->getConnectionName());\n        $this->assertSame('taylor@laravel.com', $unSerialized->users[1]->email);\n    }\n\n    #[WithConfig('database.default', 'testing')]\n    public function test_model_serialization_structure()\n    {\n        $user = ModelSerializationTestUser::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new ModelSerializationParentAccessibleTestClass($user, $user, $user));\n\n        $this->assertSame(\n            'O:78:\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\ModelSerializationParentAccessibleTestClass\":2:{s:4:\"user\";O:45:\"Illuminate\\\\Contracts\\\\Database\\\\ModelIdentifier\":5:{s:5:\"class\";s:61:\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\ModelSerializationTestUser\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}s:8:\"'.\"\\0\".'*'.\"\\0\".'user2\";O:45:\"Illuminate\\\\Contracts\\\\Database\\\\ModelIdentifier\":5:{s:5:\"class\";s:61:\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\ModelSerializationTestUser\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}}', $serialized\n        );\n    }\n\n    #[WithConfig('database.default', 'testing')]\n    public function test_it_respects_without_relations_attribute()\n    {\n        $user = User::create([\n            'email' => 'taylor@laravel.com',\n        ])->load(['roles']);\n\n        $serialized = serialize(new ModelSerializationWithoutRelations($user));\n\n        $this->assertSame(\n            'O:69:\"Illuminate\\Tests\\Integration\\Queue\\ModelSerializationWithoutRelations\":1:{s:4:\"user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:39:\"Illuminate\\Tests\\Integration\\Queue\\User\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}}', $serialized\n        );\n    }\n\n    #[WithConfig('database.default', 'testing')]\n    public function test_it_respects_without_relations_attribute_applied_to_class()\n    {\n        $user = User::create([\n            'email' => 'taylor@laravel.com',\n        ])->load(['roles']);\n\n        $serialized = serialize(new ModelSerializationAttributeTargetsClassTestClass($user, new DataValueObject('hello')));\n\n        $this->assertSame(\n            'O:83:\"Illuminate\\Tests\\Integration\\Queue\\ModelSerializationAttributeTargetsClassTestClass\":2:{s:4:\"user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:39:\"Illuminate\\Tests\\Integration\\Queue\\User\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}s:5:\"value\";O:50:\"Illuminate\\Tests\\Integration\\Queue\\DataValueObject\":1:{s:5:\"value\";s:5:\"hello\";}}',\n            $serialized\n        );\n\n        /** @var ModelSerializationAttributeTargetsClassTestClass $unserialized */\n        $unserialized = unserialize($serialized);\n\n        $this->assertFalse($unserialized->user->relationLoaded('roles'));\n        $this->assertEquals('hello', $unserialized->value->value);\n    }\n\n    public function test_serialization_types_empty_custom_eloquent_collection()\n    {\n        $class = new ModelSerializationTypedCustomCollectionTestClass(\n            new ModelSerializationTestCustomUserCollection());\n\n        $serialized = serialize($class);\n\n        unserialize($serialized);\n\n        $this->assertTrue(true);\n    }\n\n    #[WithConfig('database.default', 'testing')]\n    public function test_it_users_morphmap_for_serialization()\n    {\n        Relation::morphMap([\n            'user' => User::class,\n        ]);\n        ModelIdentifier::useMorphMap();\n\n        $user = User::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new ModelSerializationAttributeTargetsClassTestClass(\n            $user,\n            new DataValueObject('hello')\n        ));\n\n        $this->assertSame(\n            'O:83:\"Illuminate\\Tests\\Integration\\Queue\\ModelSerializationAttributeTargetsClassTestClass\":2:{s:4:\"user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:4:\"user\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}s:5:\"value\";O:50:\"Illuminate\\Tests\\Integration\\Queue\\DataValueObject\":1:{s:5:\"value\";s:5:\"hello\";}}',\n            $serialized\n        );\n\n        /** @var ModelSerializationAttributeTargetsClassTestClass $unserialized */\n        $unserialized = unserialize($serialized);\n\n        $this->assertTrue($unserialized->user->is($user));\n    }\n\n    #[WithConfig('database.default', 'testing')]\n    public function test_it_users_morphmap_for_serialization_of_collection()\n    {\n        Relation::morphMap([\n            'user' => User::class,\n        ]);\n\n        ModelIdentifier::useMorphMap();\n\n        $user = User::create([\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $serialized = serialize(new CollectionSerializationTestClass(\n            new Collection([$user]),\n        ));\n\n        $this->assertSame(\n            'O:67:\"Illuminate\\Tests\\Integration\\Queue\\CollectionSerializationTestClass\":1:{s:5:\"users\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:4:\"user\";s:2:\"id\";a:1:{i:0;i:1;}s:9:\"relations\";a:0:{}s:10:\"connection\";s:7:\"testing\";s:15:\"collectionClass\";N;}}',\n            $serialized\n        );\n\n        /** @var CollectionSerializationTestClass $unserialized */\n        $unserialized = unserialize($serialized);\n\n        $this->assertInstanceOf(Collection::class, $unserialized->users);\n        $this->assertTrue($unserialized->users->sole()->is($user));\n    }\n}\n\ntrait TraitBootsAndInitializersTest\n{\n    public bool $initializedViaAttributeInTrait = false;\n\n    public $fooBar = false;\n\n    public function initializeTraitBootsAndInitializersTest()\n    {\n        $this->fooBar = ! $this->fooBar;\n    }\n\n    public static function bootTraitBootsAndInitializersTest()\n    {\n        static::addGlobalScope('foo_bar', function () {\n        });\n    }\n\n    #[Boot]\n    public static function nonConventionalBootFunctionInTrait()\n    {\n        static::addGlobalScope('booted_attr_in_trait', function () {\n        });\n    }\n\n    #[Initialize]\n    public function nonConventionalInitFunctionInTrait()\n    {\n        $this->initializedViaAttributeInTrait = ! $this->initializedViaAttributeInTrait;\n    }\n}\n\nclass ModelBootTestWithTraitInitialization extends Model\n{\n    use TraitBootsAndInitializersTest;\n\n    public static bool $bootedViaAttributeInClass = false;\n\n    public bool $initializedViaAttributeInClass = false;\n\n    #[Boot]\n    public static function nonConventionalBootFunctionInClass()\n    {\n        static::addGlobalScope('booted_attr_in_class', function () {\n        });\n    }\n\n    #[Initialize]\n    public function nonConventionalInitFunctionInClass()\n    {\n        $this->initializedViaAttributeInClass = ! $this->initializedViaAttributeInClass;\n    }\n}\n\nclass ModelSerializationTestUser extends Model\n{\n    public $table = 'users';\n    public $guarded = [];\n    public $timestamps = false;\n}\n\nclass ModelSerializationTestCustomUserCollection extends Collection\n{\n    //\n}\n\nclass ModelSerializationTypedCustomCollectionTestClass\n{\n    use SerializesModels;\n\n    public ModelSerializationTestCustomUserCollection $collection;\n\n    public function __construct(ModelSerializationTestCustomUserCollection $collection)\n    {\n        $this->collection = $collection;\n    }\n}\n\nclass ModelSerializationTestCustomUser extends Model\n{\n    public $table = 'users';\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function newCollection(array $models = [])\n    {\n        return new ModelSerializationTestCustomUserCollection($models);\n    }\n}\n\nclass ModelSerializationTestCustomOrder extends Model\n{\n    public $table = 'orders';\n    public $guarded = [];\n    public $timestamps = false;\n    public $with = ['line', 'lines', 'products'];\n\n    public function line()\n    {\n        return $this->hasOne(Line::class, 'order_id');\n    }\n\n    public function lines()\n    {\n        return $this->hasMany(Line::class, 'order_id');\n    }\n\n    public function products()\n    {\n        return $this->belongsToMany(Product::class, 'lines', 'order_id');\n    }\n}\n\nclass Order extends Model\n{\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function line()\n    {\n        return $this->hasOne(Line::class);\n    }\n\n    public function lines()\n    {\n        return $this->hasMany(Line::class);\n    }\n\n    public function products()\n    {\n        return $this->belongsToMany(Product::class, 'lines');\n    }\n}\n\nclass Line extends Model\n{\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function product()\n    {\n        return $this->belongsTo(Product::class);\n    }\n}\n\nclass Product extends Model\n{\n    public $guarded = [];\n    public $timestamps = false;\n}\n\nclass User extends Model\n{\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function roles()\n    {\n        return $this->belongsToMany(Role::class)\n            ->using(RoleUser::class);\n    }\n}\n\nclass Role extends Model\n{\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function users()\n    {\n        return $this->belongsToMany(User::class)\n            ->using(RoleUser::class);\n    }\n}\n\nclass RoleUser extends Pivot\n{\n    public $guarded = [];\n    public $timestamps = false;\n\n    public function user()\n    {\n        return $this->belongsTo(User::class);\n    }\n\n    public function role()\n    {\n        return $this->belongsTo(Role::class);\n    }\n}\n\nclass ModelSerializationTestClass\n{\n    use SerializesModels;\n\n    public $user;\n\n    public function __construct($user)\n    {\n        $this->user = $user;\n    }\n}\n\nclass ModelSerializationAccessibleTestClass\n{\n    use SerializesModels;\n\n    public $user;\n    protected $user2;\n    private $user3;\n\n    public function __construct($user, $user2, $user3)\n    {\n        $this->user = $user;\n        $this->user2 = $user2;\n        $this->user3 = $user3;\n    }\n}\n\nclass ModelSerializationParentAccessibleTestClass extends ModelSerializationAccessibleTestClass\n{\n    //\n}\n\nclass ModelSerializationWithoutRelations\n{\n    use SerializesModels;\n\n    #[WithoutRelations]\n    public User $user;\n\n    public function __construct(User $user)\n    {\n        $this->user = $user;\n    }\n}\n\n#[WithoutRelations]\nclass ModelSerializationAttributeTargetsClassTestClass\n{\n    use SerializesModels;\n\n    public function __construct(public User $user, public DataValueObject $value)\n    {\n    }\n}\n\nclass ModelRelationSerializationTestClass\n{\n    use SerializesModels;\n\n    public $order;\n\n    public function __construct($order)\n    {\n        $this->order = $order;\n    }\n}\n\nclass CollectionSerializationTestClass\n{\n    use SerializesModels;\n\n    public $users;\n\n    public function __construct($users)\n    {\n        $this->users = $users;\n    }\n}\n\nclass CollectionRelationSerializationTestClass\n{\n    use SerializesModels;\n\n    public $orders;\n\n    public function __construct($orders)\n    {\n        $this->orders = $orders;\n    }\n}\n\nclass DataValueObject\n{\n    public function __construct(public $value = 1)\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/QueueConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\DatabaseTransactionsManager;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Throwable;\n\n#[WithConfig('queue.default', 'sqs')]\n#[WithConfig('queue.connections.sqs.after_commit', true)]\nclass QueueConnectionTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        QueueConnectionTestJob::$ran = false;\n        QueueConnectionTestUniqueJob::$ran = false;\n\n        parent::tearDown();\n    }\n\n    public function testJobWontGetDispatchedInsideATransaction()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n            $transactionManager->shouldNotReceive('addCallbackForRollback');\n\n            return $transactionManager;\n        });\n\n        Bus::dispatch(new QueueConnectionTestJob);\n    }\n\n    public function testJobWillGetDispatchedInsideATransactionWhenExplicitlyIndicated()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldNotReceive('addCallback')->andReturn(null);\n            $transactionManager->shouldNotReceive('addCallbackForRollback');\n\n            return $transactionManager;\n        });\n\n        try {\n            Bus::dispatch((new QueueConnectionTestJob)->beforeCommit());\n        } catch (Throwable) {\n            // This job was dispatched\n        }\n    }\n\n    public function testJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated()\n    {\n        $this->app['config']->set('queue.connections.sqs.after_commit', false);\n\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n            $transactionManager->shouldNotReceive('addCallbackForRollback');\n\n            return $transactionManager;\n        });\n\n        try {\n            Bus::dispatch((new QueueConnectionTestJob)->afterCommit());\n        } catch (SqsException) {\n            // This job was dispatched\n        }\n    }\n\n    public function testUniqueJobWontGetDispatchedInsideATransaction()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n            $transactionManager->shouldReceive('addCallbackForRollback')->once()->andReturn(null);\n\n            return $transactionManager;\n        });\n\n        Bus::dispatch(new QueueConnectionTestUniqueJob);\n    }\n\n    public function testUniqueJobWillGetDispatchedInsideATransactionWhenExplicitlyIndicated()\n    {\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldNotReceive('addCallback')->andReturn(null);\n            $transactionManager->shouldNotReceive('addCallbackForRollback')->andReturn(null);\n\n            return $transactionManager;\n        });\n\n        try {\n            Bus::dispatch((new QueueConnectionTestUniqueJob)->beforeCommit());\n        } catch (Throwable) {\n            // This job was dispatched\n        }\n    }\n\n    public function testUniqueJobWontGetDispatchedInsideATransactionWhenExplicitlyIndicated()\n    {\n        $this->app['config']->set('queue.connections.sqs.after_commit', false);\n\n        $this->app->singleton('db.transactions', function () {\n            $transactionManager = m::mock(DatabaseTransactionsManager::class);\n            $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n            $transactionManager->shouldReceive('addCallbackForRollback')->once()->andReturn(null);\n\n            return $transactionManager;\n        });\n\n        try {\n            Bus::dispatch((new QueueConnectionTestUniqueJob)->afterCommit());\n        } catch (SqsException) {\n            // This job was dispatched\n        }\n    }\n}\n\nclass QueueConnectionTestJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n\nclass QueueConnectionTestUniqueJob implements ShouldQueue, ShouldBeUnique\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/QueueFakeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Illuminate\\Support\\Testing\\Fakes\\QueueFake;\nuse Orchestra\\Testbench\\TestCase;\n\nclass QueueFakeTest extends TestCase\n{\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('queue.default', 'sync');\n    }\n\n    public function testFakeFor()\n    {\n        Queue::fakeFor(function () {\n            Queue::push(new TestJob);\n            Queue::assertPushed(TestJob::class);\n        });\n    }\n\n    public function testFakeExceptFor()\n    {\n        Queue::fakeExceptFor(function () {\n            Queue::push(new TestJob);\n            Queue::push(new OtherTestJob);\n\n            Queue::assertNotPushed(TestJob::class);\n            Queue::assertPushed(OtherTestJob::class);\n        }, [TestJob::class]);\n    }\n\n    public function testFakeExcept()\n    {\n        $fake = Queue::fakeExcept([TestJob::class]);\n\n        $this->assertInstanceOf(QueueFake::class, $fake);\n    }\n\n    public function testFakeForReturnValue()\n    {\n        $result = Queue::fakeFor(function () {\n            return 'test-value';\n        });\n\n        $this->assertEquals('test-value', $result);\n    }\n\n    public function testFakeExceptForReturnValue()\n    {\n        $result = Queue::fakeExceptFor(function () {\n            return 'test-value';\n        }, []);\n\n        $this->assertEquals('test-value', $result);\n    }\n}\n\nclass TestJob\n{\n    use Queueable;\n\n    public function handle()\n    {\n        //\n    }\n}\n\nclass OtherTestJob\n{\n    use Queueable;\n\n    public function handle()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/QueueTestCase.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Orchestra\\Testbench\\TestCase;\n\nabstract class QueueTestCase extends TestCase\n{\n    use DatabaseMigrations, InteractsWithRedis;\n\n    /**\n     * The current database driver.\n     *\n     * @return string\n     */\n    protected $driver;\n\n    /**\n     * Define the test environment.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function defineEnvironment($app)\n    {\n        $this->driver = $app['config']->get('queue.default', 'sync');\n    }\n\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            if ($this->getQueueDriver() === 'redis') {\n                $this->setUpRedis();\n            }\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            if ($this->getQueueDriver() === 'redis') {\n                $this->tearDownRedis();\n            }\n        });\n\n        parent::setUp();\n    }\n\n    /**\n     * Run queue worker command.\n     *\n     * @param  array  $options\n     * @param  int  $times\n     * @return void\n     */\n    protected function runQueueWorkerCommand(array $options = [], int $times = 1): void\n    {\n        if ($this->getQueueDriver() !== 'sync' && $times > 0) {\n            $count = 0;\n\n            do {\n                $this->artisan('queue:work', array_merge($options, [\n                    '--memory' => 1024,\n                ]))->assertSuccessful();\n\n                $count++;\n            } while ($count < $times);\n        }\n    }\n\n    /**\n     * Mark test as skipped when using given queue drivers.\n     *\n     * @param  array<int, string>  $drivers\n     * @return void\n     */\n    protected function markTestSkippedWhenUsingQueueDrivers(array $drivers): void\n    {\n        foreach ($drivers as $driver) {\n            if ($this->getQueueDriver() === $driver) {\n                $this->markTestSkipped(\"Unable to use `{$driver}` queue driver for the test\");\n            }\n        }\n    }\n\n    /**\n     * Mark test as skipped when using \"sync\" queue driver.\n     *\n     * @return void\n     */\n    protected function markTestSkippedWhenUsingSyncQueueDriver(): void\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['sync']);\n    }\n\n    /**\n     * Get the queue driver.\n     *\n     * @return string\n     */\n    protected function getQueueDriver(): string\n    {\n        return $this->driver;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/QueuedListenersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Event;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Events\\CallQueuedListener;\nuse Orchestra\\Testbench\\TestCase;\nuse Queue;\n\nclass QueuedListenersTest extends TestCase\n{\n    public function testListenersCanBeQueuedOptionally()\n    {\n        Queue::fake();\n\n        Event::listen(QueuedListenersTestEvent::class, QueuedListenersTestListenerShouldQueue::class);\n        Event::listen(QueuedListenersTestEvent::class, QueuedListenersTestListenerShouldNotQueue::class);\n\n        Event::dispatch(\n            new QueuedListenersTestEvent\n        );\n\n        Queue::assertPushed(CallQueuedListener::class, function ($job) {\n            return $job->class == QueuedListenersTestListenerShouldQueue::class;\n        });\n\n        $this->assertCount(1, Queue::listenersPushed(QueuedListenersTestListenerShouldQueue::class));\n        $this->assertCount(\n            0,\n            Queue::listenersPushed(\n                QueuedListenersTestListenerShouldQueue::class,\n                fn ($event, $handler, $queue, $data) => $queue === 'not-a-real-queue'\n            )\n        );\n        $this->assertCount(\n            1,\n            Queue::listenersPushed(\n                QueuedListenersTestListenerShouldQueue::class,\n                fn (QueuedListenersTestEvent $event) => $event->value === 100\n            )\n        );\n\n        Queue::assertNotPushed(CallQueuedListener::class, function ($job) {\n            return $job->class == QueuedListenersTestListenerShouldNotQueue::class;\n        });\n        $this->assertCount(0, Queue::listenersPushed(QueuedListenersTestListenerShouldNotQueue::class));\n    }\n}\n\nclass QueuedListenersTestEvent\n{\n    public int $value = 100;\n}\n\nclass QueuedListenersTestListenerShouldQueue implements ShouldQueue\n{\n    public function shouldQueue()\n    {\n        return true;\n    }\n}\n\nclass QueuedListenersTestListenerShouldNotQueue implements ShouldQueue\n{\n    public function shouldQueue()\n    {\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/RateLimitedTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\RateLimited;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RateLimitedTest extends TestCase\n{\n    public function testUnlimitedJobsAreExecuted()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            return Limit::none();\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedTestJob::class);\n        $this->assertJobRanSuccessfully(RateLimitedTestJob::class);\n    }\n\n    public function testUnlimitedJobsAreExecutedUsingBackedEnum()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for(BackedEnumNamedRateLimited::FOO, function ($job) {\n            return Limit::none();\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedTestJobUsingBackedEnum::class);\n        $this->assertJobRanSuccessfully(RateLimitedTestJobUsingBackedEnum::class);\n    }\n\n    public function testUnlimitedJobsAreExecutedUsingUnitEnum()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for(UnitEnumNamedRateLimited::LARAVEL, function ($job) {\n            return Limit::none();\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedTestJobUsingUnitEnum::class);\n        $this->assertJobRanSuccessfully(RateLimitedTestJobUsingUnitEnum::class);\n    }\n\n    public function testRateLimitedJobsAreNotExecutedOnLimitReached2()\n    {\n        $cache = m::mock(Cache::class);\n        $cache->shouldReceive('get')->andReturn(0, 1, null);\n        $cache->shouldReceive('add')->andReturn(true, true);\n        $cache->shouldReceive('increment')->andReturn(1);\n        $cache->shouldReceive('has')->andReturn(true);\n        $cache->shouldReceive('getStore')->andReturn(new ArrayStore);\n\n        $rateLimiter = new RateLimiter($cache);\n        $this->app->instance(RateLimiter::class, $rateLimiter);\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            return Limit::perHour(1);\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedTestJob::class);\n\n        // Assert Job was released and released with a delay greater than 0\n        RateLimitedTestJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->once()->withArgs(function ($delay) {\n            return $delay >= 0;\n        });\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command = new RateLimitedTestJob),\n        ]);\n\n        $this->assertFalse(RateLimitedTestJob::$handled);\n    }\n\n    public function testRateLimitedJobsAreNotExecutedOnLimitReached()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            return Limit::perHour(1);\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedTestJob::class);\n        $this->assertJobWasReleased(RateLimitedTestJob::class);\n    }\n\n    public function testRateLimitedJobsCanBeSkippedOnLimitReached()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            return Limit::perHour(1);\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedDontReleaseTestJob::class);\n        $this->assertJobWasSkipped(RateLimitedDontReleaseTestJob::class);\n    }\n\n    public function testJobsCanHaveConditionalRateLimits()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            if ($job->isAdmin()) {\n                return Limit::none();\n            }\n\n            return Limit::perHour(1);\n        });\n\n        $this->assertJobRanSuccessfully(AdminTestJob::class);\n        $this->assertJobRanSuccessfully(AdminTestJob::class);\n\n        $this->assertJobRanSuccessfully(NonAdminTestJob::class);\n        $this->assertJobWasReleased(NonAdminTestJob::class);\n    }\n\n    public function testRateLimitedJobsCanBeSkippedOnLimitReachedAndReleasedAfter()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $rateLimiter->for('test', function ($job) {\n            return Limit::perHour(1);\n        });\n\n        $this->assertJobRanSuccessfully(RateLimitedReleaseAfterTestJob::class);\n        $this->assertJobWasReleasedAfter(RateLimitedReleaseAfterTestJob::class, 60);\n    }\n\n    public function testMiddlewareSerialization()\n    {\n        $rateLimited = new RateLimited('limiterName');\n        $rateLimited->shouldRelease = false;\n\n        $restoredRateLimited = unserialize(serialize($rateLimited));\n\n        $fetch = (function (string $name) {\n            return $this->{$name};\n        })->bindTo($restoredRateLimited, RateLimited::class);\n\n        $this->assertFalse($restoredRateLimited->shouldRelease);\n        $this->assertSame('limiterName', $fetch('limiterName'));\n        $this->assertInstanceOf(RateLimiter::class, $fetch('limiter'));\n    }\n\n    protected function assertJobRanSuccessfully($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    protected function assertJobWasReleased($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertFalse($class::$handled);\n    }\n\n    protected function assertJobWasReleasedAfter($class, $releaseAfter)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->once()->withArgs([$releaseAfter]);\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertFalse($class::$handled);\n    }\n\n    protected function assertJobWasSkipped($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertFalse($class::$handled);\n    }\n\n    public function testItCanLimitPerMinute()\n    {\n        Container::getInstance()->instance(RateLimiter::class, $limiter = new RateLimiter(new Repository(new ArrayStore)));\n        $limiter->for('test', fn () => Limit::perMinute(3));\n        $jobFactory = fn () => new class\n        {\n            public $released = false;\n\n            public function release()\n            {\n                $this->released = true;\n            }\n        };\n        $next = fn ($job) => $job;\n\n        $middleware = new RateLimited('test');\n\n        Carbon::setTestNow('2000-00-00 00:00:00.000');\n\n        for ($i = 0; $i < 3; $i++) {\n            $result = $middleware->handle($job = $jobFactory(), $next);\n            $this->assertSame($job, $result);\n            $this->assertFalse($job->released);\n\n            Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        }\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertNull($result);\n        $this->assertTrue($job->released);\n\n        Carbon::setTestNow('2000-00-00 00:00:59.999');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertNull($result);\n        $this->assertTrue($job->released);\n\n        Carbon::setTestNow('2000-00-00 00:01:00.000');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertFalse($job->released);\n    }\n\n    public function testItCanLimitPerSecond()\n    {\n        Container::getInstance()->instance(RateLimiter::class, $limiter = new RateLimiter(new Repository(new ArrayStore)));\n        $limiter->for('test', fn () => Limit::perSecond(3));\n        $jobFactory = fn () => new class\n        {\n            public $released = false;\n\n            public function release()\n            {\n                $this->released = true;\n            }\n        };\n        $next = fn ($job) => $job;\n\n        $middleware = new RateLimited('test');\n\n        Carbon::setTestNow('2000-00-00 00:00:00.000');\n\n        for ($i = 0; $i < 3; $i++) {\n            $result = $middleware->handle($job = $jobFactory(), $next);\n            $this->assertSame($job, $result);\n            $this->assertFalse($job->released);\n\n            Carbon::setTestNow(Carbon::now()->addMilliseconds(100));\n        }\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertNull($result);\n        $this->assertTrue($job->released);\n\n        Carbon::setTestNow('2000-00-00 00:00:00.999');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertNull($result);\n        $this->assertTrue($job->released);\n\n        Carbon::setTestNow('2000-00-00 00:00:01.000');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertFalse($job->released);\n    }\n}\n\nclass RateLimitedTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new RateLimited('test')];\n    }\n}\n\nclass AdminTestJob extends RateLimitedTestJob\n{\n    public function isAdmin()\n    {\n        return true;\n    }\n}\n\nclass NonAdminTestJob extends RateLimitedTestJob\n{\n    public function isAdmin()\n    {\n        return false;\n    }\n}\n\nclass RateLimitedDontReleaseTestJob extends RateLimitedTestJob\n{\n    public function middleware()\n    {\n        return [(new RateLimited('test'))->dontRelease()];\n    }\n}\n\nclass RateLimitedReleaseAfterTestJob extends RateLimitedTestJob\n{\n    public function middleware()\n    {\n        return [(new RateLimited('test'))->releaseAfter(60)];\n    }\n}\n\nenum BackedEnumNamedRateLimited: string\n{\n    case FOO = 'bar';\n}\n\nenum UnitEnumNamedRateLimited\n{\n    case LARAVEL;\n}\n\nclass RateLimitedTestJobUsingBackedEnum\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new RateLimited(BackedEnumNamedRateLimited::FOO)];\n    }\n}\n\nclass RateLimitedTestJobUsingUnitEnum\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new RateLimited(UnitEnumNamedRateLimited::LARAVEL)];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/RateLimitedWithRedisTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Cache\\RateLimiting\\Limit;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Contracts\\Redis\\Connection;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\RateLimitedWithRedis;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\RequiresEnv;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresEnv('REDIS_CLIENT')]\n#[RequiresPhpExtension('redis')]\nclass RateLimitedWithRedisTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testUnlimitedJobsAreExecuted()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $testJob = new RedisRateLimitedTestJob;\n\n        $rateLimiter->for($testJob->key, function ($job) {\n            return Limit::none();\n        });\n\n        $this->assertJobRanSuccessfully($testJob);\n        $this->assertJobRanSuccessfully($testJob);\n    }\n\n    public function testRateLimitedJobsAreNotExecutedOnLimitReached()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $testJob = new RedisRateLimitedTestJob;\n\n        $rateLimiter->for($testJob->key, function ($job) {\n            return Limit::perMinute(1);\n        });\n\n        $this->assertJobRanSuccessfully($testJob);\n        $this->assertJobWasReleased($testJob);\n    }\n\n    public function testRateLimitedJobsCanBeSkippedOnLimitReached()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $testJob = new RedisRateLimitedDontReleaseTestJob;\n\n        $rateLimiter->for($testJob->key, function ($job) {\n            return Limit::perMinute(1);\n        });\n\n        $this->assertJobRanSuccessfully($testJob);\n        $this->assertJobWasSkipped($testJob);\n    }\n\n    public function testJobsCanHaveConditionalRateLimits()\n    {\n        $rateLimiter = $this->app->make(RateLimiter::class);\n\n        $adminJob = new RedisAdminTestJob;\n\n        $rateLimiter->for($adminJob->key, function ($job) {\n            if ($job->isAdmin()) {\n                return Limit::none();\n            }\n\n            return Limit::perMinute(1);\n        });\n\n        $this->assertJobRanSuccessfully($adminJob);\n        $this->assertJobRanSuccessfully($adminJob);\n\n        $nonAdminJob = new RedisNonAdminTestJob;\n\n        $rateLimiter->for($nonAdminJob->key, function ($job) {\n            if ($job->isAdmin()) {\n                return Limit::none();\n            }\n\n            return Limit::perMinute(1);\n        });\n\n        $this->assertJobRanSuccessfully($nonAdminJob);\n        $this->assertJobWasReleased($nonAdminJob);\n    }\n\n    public function testMiddlewareSerialization()\n    {\n        $rateLimited = new RateLimitedWithRedis('limiterName', 'default');\n        $rateLimited->shouldRelease = false;\n\n        $restoredRateLimited = unserialize(serialize($rateLimited));\n\n        $fetch = (function (string $name) {\n            return $this->{$name};\n        })->bindTo($restoredRateLimited, RateLimitedWithRedis::class);\n\n        $this->assertFalse($restoredRateLimited->shouldRelease);\n        $this->assertSame('limiterName', $fetch('limiterName'));\n        $this->assertSame('default', $fetch('connectionName'));\n        $this->assertInstanceOf(RateLimiter::class, $fetch('limiter'));\n        // $this->assertInstanceOf(Connection::class, $fetch('redis'));\n    }\n\n    protected function assertJobRanSuccessfully($testJob)\n    {\n        $testJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($testJob),\n        ]);\n\n        $this->assertTrue($testJob::$handled);\n    }\n\n    protected function assertJobWasReleased($testJob)\n    {\n        $testJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($testJob),\n        ]);\n\n        $this->assertFalse($testJob::$handled);\n    }\n\n    protected function assertJobWasSkipped($testJob)\n    {\n        $testJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($testJob),\n        ]);\n\n        $this->assertFalse($testJob::$handled);\n    }\n}\n\nclass RedisRateLimitedTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public $key;\n\n    public static $handled = false;\n\n    public function __construct()\n    {\n        $this->key = Str::random(10);\n    }\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new RateLimitedWithRedis($this->key)];\n    }\n}\n\nclass RedisAdminTestJob extends RedisRateLimitedTestJob\n{\n    public function isAdmin()\n    {\n        return true;\n    }\n}\n\nclass RedisNonAdminTestJob extends RedisRateLimitedTestJob\n{\n    public function isAdmin()\n    {\n        return false;\n    }\n}\n\nclass RedisRateLimitedDontReleaseTestJob extends RedisRateLimitedTestJob\n{\n    public function middleware()\n    {\n        return [(new RateLimitedWithRedis($this->key))->dontRelease()];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/RedisQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Queue\\Events\\JobQueued;\nuse Illuminate\\Queue\\Events\\JobQueueing;\nuse Illuminate\\Queue\\Jobs\\RedisJob;\nuse Illuminate\\Queue\\RedisQueue;\nuse Illuminate\\Support\\InteractsWithTime;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\n\n#[RequiresPhpExtension('redis')]\nclass RedisQueueTest extends TestCase\n{\n    use InteractsWithRedis, InteractsWithTime;\n\n    /**\n     * @var \\Illuminate\\Queue\\RedisQueue\n     */\n    private $queue;\n\n    /**\n     * @var \\Mockery\\MockInterface|\\Mockery\\LegacyMockInterface\n     */\n    private $container;\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $this->afterApplicationCreated(function () {\n            $this->setUpRedis();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            $this->tearDownRedis();\n        });\n\n        parent::setUp();\n    }\n\n    /**\n     * @param  string  $driver\n     * @param  string  $default\n     * @param  string|null  $connection\n     * @param  int  $retryAfter\n     * @param  int|null  $blockFor\n     */\n    private function setQueue($driver, $default = 'default', $connection = null, $retryAfter = 60, $blockFor = null)\n    {\n        $this->queue = new RedisQueue($this->redis[$driver], $default, $connection, $retryAfter, $blockFor);\n        $this->container = m::spy(Container::class);\n        $this->queue->setContainer($this->container);\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testExpiredJobsArePopped($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n\n        $jobs = [\n            new RedisQueueIntegrationTestJob(0),\n            new RedisQueueIntegrationTestJob(1),\n            new RedisQueueIntegrationTestJob(2),\n            new RedisQueueIntegrationTestJob(3),\n        ];\n\n        $this->queue->later(1000, $jobs[0]);\n        $this->queue->later(-200, $jobs[1]);\n        $this->queue->later(-300, $jobs[2]);\n        $this->queue->later(-100, $jobs[3]);\n\n        $this->assertEquals($jobs[2], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $this->assertEquals($jobs[1], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $this->assertEquals($jobs[3], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $this->assertNull($this->queue->pop());\n\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:delayed\"));\n        $this->assertEquals(3, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n    }\n\n    /**\n     * @param  mixed  $driver\n     *\n     * @throws \\Exception\n     */\n    #[DataProvider('redisDriverProvider')]\n    #[RequiresPhpExtension('pcntl')]\n    public function testBlockingPop($driver)\n    {\n        $this->tearDownRedis();\n\n        $default = config('queue.connections.redis.queue', 'default');\n        if ($pid = pcntl_fork() > 0) {\n            $this->setUpRedis();\n            $this->setQueue($driver, $default, null, 60, 10);\n            $this->assertEquals(12, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)->i);\n        } elseif ($pid == 0) {\n            $this->setUpRedis();\n            $this->setQueue('phpredis', $default);\n            sleep(1);\n            $this->queue->push(new RedisQueueIntegrationTestJob(12));\n            exit;\n        } else {\n            $this->fail('Cannot fork');\n        }\n    }\n\n    // /**\n    //  * @param  string  $driver\n    //  */\n    // #[DataProvider('redisDriverProvider')]\n    // public function testMigrateMoreThan100Jobs($driver)\n    // {\n    //     $default = config('queue.connections.redis.queue', 'default');\n    //     $this->setQueue($driver, $default);\n    //     for ($i = -1; $i >= -201; $i--) {\n    //         $this->queue->later($i, new RedisQueueIntegrationTestJob($i));\n    //     }\n    //     for ($i = -201; $i <= -1; $i++) {\n    //         $this->assertEquals($i, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command)->i);\n    //         $this->assertEquals(-$i - 1, $this->redis[$driver]->llen(\"queues:$default:notify\"));\n    //     }\n    // }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testPopProperlyPopsJobOffOfRedis($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->push($job);\n\n        // Pop and check it is popped correctly\n        $before = $this->currentTime();\n        /** @var \\Illuminate\\Queue\\Jobs\\RedisJob $redisJob */\n        $redisJob = $this->queue->pop();\n        $after = $this->currentTime();\n\n        $this->assertEquals($job, unserialize(json_decode($redisJob->getRawBody())->data->command));\n        $this->assertEquals(1, $redisJob->attempts());\n        $this->assertEquals($job, unserialize(json_decode($redisJob->getReservedJob())->data->command));\n        $this->assertEquals(1, json_decode($redisJob->getReservedJob())->attempts);\n        $this->assertEquals($redisJob->getJobId(), json_decode($redisJob->getReservedJob())->id);\n\n        // Check reserved queue\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $result = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:reserved\", -INF, INF, ['withscores' => true]);\n        $reservedJob = array_keys($result)[0];\n        $score = (int) $result[$reservedJob];\n        $this->assertLessThanOrEqual($score, $before + 60);\n        $this->assertGreaterThanOrEqual($score, $after + 60);\n        $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testPopProperlyPopsDelayedJobOffOfRedis($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->later(-10, $job);\n\n        // Pop and check it is popped correctly\n        $before = $this->currentTime();\n        $this->assertEquals($job, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $after = $this->currentTime();\n\n        // Check reserved queue\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $result = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:reserved\", -INF, INF, ['withscores' => true]);\n        $reservedJob = array_keys($result)[0];\n        $score = (int) $result[$reservedJob];\n        $this->assertLessThanOrEqual($score, $before + 60);\n        $this->assertGreaterThanOrEqual($score, $after + 60);\n        $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testPopPopsDelayedJobOffOfRedisWhenExpireNull($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default, null, null);\n\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->later(-10, $job);\n\n        $this->container->shouldHaveReceived('bound')->with('events')->twice();\n\n        // Pop and check it is popped correctly\n        $before = $this->currentTime();\n        $this->assertEquals($job, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $after = $this->currentTime();\n\n        // Check reserved queue\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $result = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:reserved\", -INF, INF, ['withscores' => true]);\n        $reservedJob = array_keys($result)[0];\n        $score = (int) $result[$reservedJob];\n        $this->assertLessThanOrEqual($score, $before);\n        $this->assertGreaterThanOrEqual($score, $after);\n        $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testBlockingPopProperlyPopsJobOffOfRedis($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default, null, 60, 5);\n\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->push($job);\n\n        // Pop and check it is popped correctly\n        /** @var \\Illuminate\\Queue\\Jobs\\RedisJob $redisJob */\n        $redisJob = $this->queue->pop();\n\n        $this->assertNotNull($redisJob);\n        $this->assertEquals($job, unserialize(json_decode($redisJob->getReservedJob())->data->command));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testBlockingPopProperlyPopsExpiredJobs($driver)\n    {\n        Str::createUuidsUsing(function () {\n            return 'uuid';\n        });\n\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default, null, 60, 5);\n\n        $jobs = [\n            new RedisQueueIntegrationTestJob(0),\n            new RedisQueueIntegrationTestJob(1),\n        ];\n\n        $this->queue->later(-200, $jobs[0]);\n        $this->queue->later(-200, $jobs[1]);\n\n        $this->assertEquals($jobs[0], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $this->assertEquals($jobs[1], unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n\n        $this->assertEquals(0, $this->redis[$driver]->connection()->llen('queues:default:notify'));\n        $this->assertEquals(0, $this->redis[$driver]->connection()->zcard(\"queues:$default:delayed\"));\n        $this->assertEquals(2, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n\n        Str::createUuidsNormally();\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testNotExpireJobsWhenExpireNull($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default, null, null);\n\n        // Make an expired reserved job\n        $failed = new RedisQueueIntegrationTestJob(-20);\n        $this->queue->push($failed);\n        $this->container->shouldHaveReceived('bound')->with('events')->twice();\n\n        $beforeFailPop = $this->currentTime();\n        $this->queue->pop();\n        $afterFailPop = $this->currentTime();\n\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->push($job);\n        $this->container->shouldHaveReceived('bound')->with('events')->times(4);\n\n        // Pop and check it is popped correctly\n        $before = $this->currentTime();\n        $this->assertEquals($job, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $after = $this->currentTime();\n\n        // Check reserved queue\n        $this->assertEquals(2, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $result = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:reserved\", -INF, INF, ['withscores' => true]);\n\n        foreach ($result as $payload => $score) {\n            $command = unserialize(json_decode($payload)->data->command);\n            $this->assertInstanceOf(RedisQueueIntegrationTestJob::class, $command);\n            $this->assertContains($command->i, [10, -20]);\n\n            $score = (int) $score;\n\n            if ($command->i == 10) {\n                $this->assertLessThanOrEqual($score, $before);\n                $this->assertGreaterThanOrEqual($score, $after);\n            } else {\n                $this->assertLessThanOrEqual($score, $beforeFailPop);\n                $this->assertGreaterThanOrEqual($score, $afterFailPop);\n            }\n        }\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testExpireJobsWhenExpireSet($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default, null, 30);\n\n        // Push an item into queue\n        $job = new RedisQueueIntegrationTestJob(10);\n        $this->queue->push($job);\n        $this->container->shouldHaveReceived('bound')->with('events')->twice();\n\n        // Pop and check it is popped correctly\n        $before = $this->currentTime();\n        $this->assertEquals($job, unserialize(json_decode($this->queue->pop()->getRawBody())->data->command));\n        $after = $this->currentTime();\n\n        // Check reserved queue\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $result = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:reserved\", -INF, INF, ['withscores' => true]);\n        $reservedJob = array_keys($result)[0];\n        $score = (int) $result[$reservedJob];\n        $this->assertLessThanOrEqual($score, $before + 30);\n        $this->assertGreaterThanOrEqual($score, $after + 30);\n        $this->assertEquals($job, unserialize(json_decode($reservedJob)->data->command));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testRelease($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n\n        // push a job into queue\n        $job = new RedisQueueIntegrationTestJob(30);\n        $this->queue->push($job);\n\n        // pop and release the job\n        /** @var \\Illuminate\\Queue\\Jobs\\RedisJob $redisJob */\n        $redisJob = $this->queue->pop();\n        $before = $this->currentTime();\n        $redisJob->release(1000);\n        $after = $this->currentTime();\n\n        // check the content of delayed queue\n        $this->assertEquals(1, $this->redis[$driver]->connection()->zcard(\"queues:$default:delayed\"));\n\n        $results = $this->redis[$driver]->connection()->zrangebyscore(\"queues:$default:delayed\", -INF, INF, ['withscores' => true]);\n\n        $payload = array_keys($results)[0];\n\n        $score = $results[$payload];\n\n        $this->assertGreaterThanOrEqual($before + 1000, $score);\n        $this->assertLessThanOrEqual($after + 1000, $score);\n\n        $decoded = json_decode($payload);\n\n        $this->assertEquals(1, $decoded->attempts);\n        $this->assertEquals($job, unserialize($decoded->data->command));\n\n        // check if the queue has no ready item yet\n        $this->assertNull($this->queue->pop());\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testReleaseInThePast($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n        $job = new RedisQueueIntegrationTestJob(30);\n        $this->queue->push($job);\n\n        /** @var \\Illuminate\\Queue\\Jobs\\RedisJob $redisJob */\n        $redisJob = $this->queue->pop();\n        $redisJob->release(-3);\n\n        $this->assertInstanceOf(RedisJob::class, $this->queue->pop());\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testDelete($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n\n        $job = new RedisQueueIntegrationTestJob(30);\n        $this->queue->push($job);\n\n        /** @var \\Illuminate\\Queue\\Jobs\\RedisJob $redisJob */\n        $redisJob = $this->queue->pop();\n\n        $redisJob->delete();\n\n        $this->assertEquals(0, $this->redis[$driver]->connection()->zcard(\"queues:$default:delayed\"));\n        $this->assertEquals(0, $this->redis[$driver]->connection()->zcard(\"queues:$default:reserved\"));\n        $this->assertEquals(0, $this->redis[$driver]->connection()->llen(\"queues:$default\"));\n\n        $this->assertNull($this->queue->pop());\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testClear($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n\n        $job1 = new RedisQueueIntegrationTestJob(30);\n        $job2 = new RedisQueueIntegrationTestJob(40);\n\n        $this->queue->push($job1);\n        $this->queue->push($job2);\n\n        $this->assertEquals(2, $this->queue->clear(null));\n        $this->assertEquals(0, $this->queue->size());\n        $this->assertEquals(0, $this->redis[$driver]->connection()->llen('queues:default:notify'));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testSize($driver)\n    {\n        $default = config('queue.connections.redis.queue', 'default');\n        $this->setQueue($driver, $default);\n        $this->assertEquals(0, $this->queue->size());\n        $this->queue->push(new RedisQueueIntegrationTestJob(1));\n        $this->assertEquals(1, $this->queue->size());\n        $this->queue->later(60, new RedisQueueIntegrationTestJob(2));\n        $this->assertEquals(2, $this->queue->size());\n        $this->queue->push(new RedisQueueIntegrationTestJob(3));\n        $this->assertEquals(3, $this->queue->size());\n        $job = $this->queue->pop();\n        $this->assertEquals(3, $this->queue->size());\n        $job->delete();\n        $this->assertEquals(2, $this->queue->size());\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testPushJobQueueingAndJobQueuedEvents($driver)\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->withArgs(function (JobQueueing $jobQueuing) {\n            $this->assertInstanceOf(RedisQueueIntegrationTestJob::class, $jobQueuing->job);\n\n            return true;\n        })->andReturnNull()->once();\n        $events->shouldReceive('dispatch')->withArgs(function (JobQueued $jobQueued) {\n            $this->assertInstanceOf(RedisQueueIntegrationTestJob::class, $jobQueued->job);\n            $this->assertIsString($jobQueued->id);\n\n            return true;\n        })->andReturnNull()->once();\n\n        $container = m::mock(Container::class);\n        $container->shouldReceive('bound')->with('events')->andReturn(true)->twice();\n        $container->shouldReceive('offsetGet')->with('events')->andReturn($events)->twice();\n\n        $default = config('queue.connections.redis.queue', 'default');\n        $queue = new RedisQueue($this->redis[$driver], $default);\n        $queue->setContainer($container);\n\n        $queue->push(new RedisQueueIntegrationTestJob(5));\n    }\n\n    /**\n     * @param  string  $driver\n     */\n    #[DataProvider('redisDriverProvider')]\n    public function testBulkJobQueuedEvent($driver)\n    {\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->with(m::type(JobQueueing::class))->andReturnNull()->times(3);\n        $events->shouldReceive('dispatch')->with(m::type(JobQueued::class))->andReturnNull()->times(3);\n\n        $container = m::mock(Container::class);\n        $container->shouldReceive('bound')->with('events')->andReturn(true)->times(6);\n        $container->shouldReceive('offsetGet')->with('events')->andReturn($events)->times(6);\n\n        $default = config('queue.connections.redis.queue', 'default');\n        $queue = new RedisQueue($this->redis[$driver], $default);\n        $queue->setContainer($container);\n\n        $queue->bulk([\n            new RedisQueueIntegrationTestJob(5),\n            new RedisQueueIntegrationTestJob(10),\n            new RedisQueueIntegrationTestJob(15),\n        ]);\n    }\n\n    /**\n     * Test that delayed jobs work correctly with phpredis when serialization is enabled.\n     *\n     * This test reproduces issue #58214 where delayed jobs don't work when using\n     * phpredis with serialization/compression enabled because the laterRaw method\n     * uses zadd directly (which triggers phpredis serialization) instead of a Lua\n     * script (which bypasses serialization like pushRaw does).\n     */\n    public function testDelayedJobsWorkWithPhpRedisSerializationEnabled()\n    {\n        if (! extension_loaded('redis')) {\n            $this->markTestSkipped('The redis extension is not installed.');\n        }\n\n        // Get the phpredis connection and enable serialization\n        $connection = $this->redis['phpredis']->connection();\n        $client = $connection->client();\n\n        // Redis::OPT_SERIALIZER = 1, Redis::SERIALIZER_PHP = 1\n        $optSerializer = 1;\n        $serializerPhp = 1;\n\n        // Store original serializer to restore later\n        $originalSerializer = $client->getOption($optSerializer);\n\n        // Enable PHP serialization (simulates real-world usage with serialization)\n        $client->setOption($optSerializer, $serializerPhp);\n\n        try {\n            $default = config('queue.connections.redis.queue', 'default');\n            $this->setQueue('phpredis', $default);\n\n            // Push a delayed job (this is where the bug occurs - zadd serializes the payload)\n            $job = new RedisQueueIntegrationTestJob(42);\n            $this->queue->later(-10, $job);\n\n            // The job should be immediately available since we used a negative delay\n            // With the bug, this would fail because the payload is double-serialized\n            $poppedJob = $this->queue->pop();\n\n            $this->assertNotNull($poppedJob, 'Delayed job should be retrievable after delay expires');\n\n            // Verify the job payload can be decoded correctly\n            $rawBody = $poppedJob->getRawBody();\n            $decoded = json_decode($rawBody);\n\n            $this->assertNotNull($decoded, 'Job payload should be valid JSON');\n            $this->assertObjectHasProperty('data', $decoded, 'Decoded payload should have data property');\n\n            // Verify the actual job data\n            $command = unserialize($decoded->data->command);\n            $this->assertEquals($job, $command, 'Unserialized job should match original');\n            $this->assertEquals(42, $command->i, 'Job property should be preserved');\n        } finally {\n            // Restore original serializer setting\n            $client->setOption($optSerializer, $originalSerializer);\n        }\n    }\n}\n\nclass RedisQueueIntegrationTestJob\n{\n    public $i;\n\n    public function __construct($i)\n    {\n        $this->i = $i;\n    }\n\n    public function handle()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/SerializableClosureV1QueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass SerializableClosureV1QueueTest extends TestCase\n{\n    use RefreshDatabase;\n\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        $this->markTestSkippedWhen($this->usingInMemoryDatabase(), 'Test does not support using :memory: database connection');\n\n        tap($app->make('config'), function ($config) {\n            $config->set([\n                'app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF',\n                'queue.default' => 'database',\n            ]);\n        });\n    }\n\n    /** {@inheritDoc} */\n    protected function afterRefreshingDatabase()\n    {\n        UserFactory::new()->create([\n            'id' => 100,\n            'name' => 'Taylor Otwell',\n            'email' => 'taylor@laravel.com',\n            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',\n        ]);\n\n        DB::table('jobs')->insert([\n            'queue' => 'default',\n            'payload' => \"{\\\"uuid\\\":\\\"d7c0856d-733a-4e73-89c8-eca4dea621ff\\\",\\\"displayName\\\":\\\"Illuminate\\\\\\\\Tests\\\\\\\\Integration\\\\\\\\Queue\\\\\\\\Fixtures\\\\\\\\Jobs\\\\\\\\DeleteUser\\\",\\\"job\\\":\\\"Illuminate\\\\\\\\Queue\\\\\\\\CallQueuedHandler@call\\\",\\\"maxTries\\\":null,\\\"maxExceptions\\\":null,\\\"failOnTimeout\\\":false,\\\"backoff\\\":null,\\\"timeout\\\":null,\\\"retryUntil\\\":null,\\\"data\\\":{\\\"commandName\\\":\\\"Illuminate\\\\\\\\Tests\\\\\\\\Integration\\\\\\\\Queue\\\\\\\\Fixtures\\\\\\\\Jobs\\\\\\\\DeleteUser\\\",\\\"command\\\":\\\"O:59:\\\\\\\"Illuminate\\\\\\\\Tests\\\\\\\\Integration\\\\\\\\Queue\\\\\\\\Fixtures\\\\\\\\Jobs\\\\\\\\DeleteUser\\\\\\\":3:{s:4:\\\\\\\"user\\\\\\\";O:45:\\\\\\\"Illuminate\\\\\\\\Contracts\\\\\\\\Database\\\\\\\\ModelIdentifier\\\\\\\":5:{s:5:\\\\\\\"class\\\\\\\";s:31:\\\\\\\"Illuminate\\\\\\\\Foundation\\\\\\\\Auth\\\\\\\\User\\\\\\\";s:2:\\\\\\\"id\\\\\\\";i:100;s:9:\\\\\\\"relations\\\\\\\";a:0:{}s:10:\\\\\\\"connection\\\\\\\";s:6:\\\\\\\"sqlite\\\\\\\";s:15:\\\\\\\"collectionClass\\\\\\\";N;}s:7:\\\\\\\"chained\\\\\\\";a:1:{i:0;s:571:\\\\\\\"O:34:\\\\\\\"Illuminate\\\\\\\\Queue\\\\\\\\CallQueuedClosure\\\\\\\":1:{s:7:\\\\\\\"closure\\\\\\\";O:47:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\SerializableClosure\\\\\\\":1:{s:12:\\\\\\\"serializable\\\\\\\";O:46:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\Serializers\\\\\\\\Signed\\\\\\\":2:{s:12:\\\\\\\"serializable\\\\\\\";s:282:\\\\\\\"O:46:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\Serializers\\\\\\\\Native\\\\\\\":5:{s:3:\\\\\\\"use\\\\\\\";a:0:{}s:8:\\\\\\\"function\\\\\\\";s:57:\\\\\\\"function () {\\\\n            \\\\\\\\info('Hello world');\\\\n        }\\\\\\\";s:5:\\\\\\\"scope\\\\\\\";s:44:\\\\\\\"Illuminate\\\\\\\\Foundation\\\\\\\\Console\\\\\\\\ClosureCommand\\\\\\\";s:4:\\\\\\\"this\\\\\\\";N;s:4:\\\\\\\"self\\\\\\\";s:32:\\\\\\\"000000000000021e0000000000000000\\\\\\\";}\\\\\\\";s:4:\\\\\\\"hash\\\\\\\";s:44:\\\\\\\"VGMlRmFr2\\\\/U1E8lksExnzODwffyWR8oD01WOcQ2SUjE=\\\\\\\";}}}\\\\\\\";}s:19:\\\\\\\"chainCatchCallbacks\\\\\\\";a:1:{i:0;O:47:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\SerializableClosure\\\\\\\":1:{s:12:\\\\\\\"serializable\\\\\\\";O:46:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\Serializers\\\\\\\\Signed\\\\\\\":2:{s:12:\\\\\\\"serializable\\\\\\\";s:309:\\\\\\\"O:46:\\\\\\\"Laravel\\\\\\\\SerializableClosure\\\\\\\\Serializers\\\\\\\\Native\\\\\\\":5:{s:3:\\\\\\\"use\\\\\\\";a:0:{}s:8:\\\\\\\"function\\\\\\\";s:84:\\\\\\\"function (\\\\\\\\Throwable \\$e) {\\\\n        \\\\\\\\Illuminate\\\\\\\\Support\\\\\\\\Facades\\\\\\\\Log::error(\\$e);\\\\n    }\\\\\\\";s:5:\\\\\\\"scope\\\\\\\";s:44:\\\\\\\"Illuminate\\\\\\\\Foundation\\\\\\\\Console\\\\\\\\ClosureCommand\\\\\\\";s:4:\\\\\\\"this\\\\\\\";N;s:4:\\\\\\\"self\\\\\\\";s:32:\\\\\\\"00000000000002380000000000000000\\\\\\\";}\\\\\\\";s:4:\\\\\\\"hash\\\\\\\";s:44:\\\\\\\"RBSD4RFLgmKL9WJEGY66aeZtWDkX\\\\/aY1J+MJ8LQSYi4=\\\\\\\";}}}}\\\"}}\",\n            'attempts' => 0,\n            'available_at' => 1731919764,\n            'created_at' => 1731919764,\n        ]);\n    }\n\n    public function testItCanProcessQueueFromSerializableClosureV1()\n    {\n        $this->assertDatabaseHas('users', [\n            'name' => 'Taylor Otwell',\n            'email' => 'taylor@laravel.com',\n        ]);\n\n        $this->artisan('queue:work', [\n            'connection' => 'database',\n            '--stop-when-empty' => true,\n            '--memory' => 1024,\n        ])->assertExitCode(0);\n\n        $this->assertDatabaseMissing('users', [\n            'name' => 'Taylor Otwell',\n            'email' => 'taylor@laravel.com',\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/SkipIfBatchCancelledTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\SkipIfBatchCancelled;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SkipIfBatchCancelledTest extends TestCase\n{\n    public function testJobsAreSkippedOnceBatchIsCancelled()\n    {\n        [$beforeCancelled] = (new SkipCancelledBatchableTestJob())->withFakeBatch();\n        [$afterCancelled] = (new SkipCancelledBatchableTestJob())->withFakeBatch(\n            cancelledAt: \\Carbon\\CarbonImmutable::now()\n        );\n\n        $this->assertJobRanSuccessfully($beforeCancelled);\n        $this->assertJobWasSkipped($afterCancelled);\n    }\n\n    protected function assertJobRanSuccessfully($class)\n    {\n        $this->assertJobHandled($class, true);\n    }\n\n    protected function assertJobWasSkipped($class)\n    {\n        $this->assertJobHandled($class, false);\n    }\n\n    protected function assertJobHandled($class, $expectedHandledValue)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('uuid')->once()->andReturn('simple-test-uuid');\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = $class),\n        ]);\n\n        $this->assertEquals($expectedHandledValue, $class::$handled);\n    }\n}\n\nclass SkipCancelledBatchableTestJob\n{\n    use Batchable, InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new SkipIfBatchCancelled];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/SkipMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\Skip;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SkipMiddlewareTest extends TestCase\n{\n    public function testJobIsSkippedWhenConditionIsTrue()\n    {\n        $job = new SkipTestJob(skip: true);\n\n        $this->assertJobWasSkipped($job);\n    }\n\n    public function testJobIsSkippedWhenConditionIsTrueUsingClosure()\n    {\n        $job = new SkipTestJob(skip: new SerializableClosure(fn () => true));\n\n        $this->assertJobWasSkipped($job);\n    }\n\n    public function testJobIsNotSkippedWhenConditionIsFalse()\n    {\n        $job = new SkipTestJob(skip: false);\n\n        $this->assertJobRanSuccessfully($job);\n    }\n\n    public function testJobIsNotSkippedWhenConditionIsFalseUsingClosure()\n    {\n        $job = new SkipTestJob(skip: new SerializableClosure(fn () => false));\n\n        $this->assertJobRanSuccessfully($job);\n    }\n\n    public function testJobIsNotSkippedWhenConditionIsTrueWithUnless()\n    {\n        $job = new SkipTestJob(skip: true, useUnless: true);\n\n        $this->assertJobRanSuccessfully($job);\n    }\n\n    public function testJobIsNotSkippedWhenConditionIsTrueWithUnlessUsingClosure()\n    {\n        $job = new SkipTestJob(skip: new SerializableClosure(fn () => true), useUnless: true);\n\n        $this->assertJobRanSuccessfully($job);\n    }\n\n    public function testJobIsSkippedWhenConditionIsFalseWithUnless()\n    {\n        $job = new SkipTestJob(skip: false, useUnless: true);\n\n        $this->assertJobWasSkipped($job);\n    }\n\n    public function testJobIsSkippedWhenConditionIsFalseWithUnlessUsingClosure()\n    {\n        $job = new SkipTestJob(skip: new SerializableClosure(fn () => false), useUnless: true);\n\n        $this->assertJobWasSkipped($job);\n    }\n\n    protected function assertJobRanSuccessfully(SkipTestJob $class)\n    {\n        $this->assertJobHandled(class: $class, expectedHandledValue: true);\n    }\n\n    protected function assertJobWasSkipped(SkipTestJob $class)\n    {\n        $this->assertJobHandled(class: $class, expectedHandledValue: false);\n    }\n\n    protected function assertJobHandled(SkipTestJob $class, bool $expectedHandledValue)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($class),\n        ]);\n\n        $this->assertEquals($expectedHandledValue, $class::$handled);\n    }\n}\n\nclass SkipTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function __construct(\n        protected bool|SerializableClosure $skip,\n        protected bool $useUnless = false,\n    ) {\n    }\n\n    public function handle(): void\n    {\n        static::$handled = true;\n    }\n\n    public function middleware(): array\n    {\n        $skip = $this->skip instanceof SerializableClosure\n            ? $this->skip->getClosure()\n            : $this->skip;\n\n        if ($this->useUnless) {\n            return [Skip::unless($skip)];\n        }\n\n        return [Skip::when($skip)];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/ThrottlesExceptionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Exception;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Cache\\RateLimiter;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\ThrottlesExceptions;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass ThrottlesExceptionsTest extends TestCase\n{\n    public function testCircuitIsOpenedForJobErrors()\n    {\n        $this->assertJobWasReleasedImmediately(CircuitBreakerTestJob::class);\n        $this->assertJobWasReleasedImmediately(CircuitBreakerTestJob::class);\n        $this->assertJobWasReleasedWithDelay(CircuitBreakerTestJob::class);\n    }\n\n    public function testCircuitStaysClosedForSuccessfulJobs()\n    {\n        $this->assertJobRanSuccessfully(CircuitBreakerSuccessfulJob::class);\n        $this->assertJobRanSuccessfully(CircuitBreakerSuccessfulJob::class);\n        $this->assertJobRanSuccessfully(CircuitBreakerSuccessfulJob::class);\n    }\n\n    public function testCircuitResetsAfterSuccess()\n    {\n        $this->assertJobWasReleasedImmediately(CircuitBreakerTestJob::class);\n        $this->assertJobRanSuccessfully(CircuitBreakerSuccessfulJob::class);\n        $this->assertJobWasReleasedImmediately(CircuitBreakerTestJob::class);\n        $this->assertJobWasReleasedImmediately(CircuitBreakerTestJob::class);\n        $this->assertJobWasReleasedWithDelay(CircuitBreakerTestJob::class);\n    }\n\n    public function testCircuitCanSkipJob()\n    {\n        $this->assertJobWasDeleted(CircuitBreakerSkipJob::class);\n    }\n\n    public function testCircuitCanFailJob()\n    {\n        $this->assertJobWasFailed(CircuitBreakerFailedJob::class);\n    }\n\n    protected function assertJobWasReleasedImmediately($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->with(0)->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n        $job->shouldReceive('uuid')->andReturn('simple-test-uuid');\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    protected function assertJobWasReleasedWithDelay($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->withArgs(function ($delay) {\n            return $delay >= 600;\n        })->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n        $job->shouldReceive('uuid')->andReturn('simple-test-uuid');\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertFalse($class::$handled);\n    }\n\n    protected function assertJobWasDeleted($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n        $job->shouldReceive('isDeleted')->andReturn(true);\n        $job->shouldReceive('isReleased')->twice()->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n        $job->shouldReceive('uuid')->andReturn('simple-test-uuid');\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    protected function assertJobWasFailed($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(true);\n        $job->shouldReceive('fail')->once();\n        $job->shouldReceive('isDeleted')->andReturn(true);\n        $job->shouldReceive('isReleased')->once()->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n        $job->shouldReceive('uuid')->andReturn('simple-test-uuid');\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    protected function assertJobRanSuccessfully($class)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n        $job->shouldReceive('uuid')->andReturn('simple-test-uuid');\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    public function testItCanLimitPerMinute()\n    {\n        $jobFactory = fn () => new class\n        {\n            public $released = false;\n\n            public $handled = false;\n\n            public function release()\n            {\n                $this->released = true;\n\n                return $this;\n            }\n        };\n        $next = function ($job) {\n            $job->handled = true;\n\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions(3, 60);\n\n        Carbon::setTestNow('2000-00-00 00:00:00.000');\n\n        for ($i = 0; $i < 3; $i++) {\n            $result = $middleware->handle($job = $jobFactory(), $next);\n            $this->assertSame($job, $result);\n            $this->assertTrue($job->released);\n            $this->assertTrue($job->handled);\n\n            Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        }\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:00:59.999');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:01:00.000');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertTrue($job->handled);\n    }\n\n    public function testItCanLimitPerSecond()\n    {\n        $jobFactory = fn () => new class\n        {\n            public $released = false;\n\n            public $handled = false;\n\n            public function release()\n            {\n                $this->released = true;\n\n                return $this;\n            }\n        };\n        $next = function ($job) {\n            $job->handled = true;\n\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions(3, 1);\n\n        Carbon::setTestNow('2000-00-00 00:00:00.000');\n\n        for ($i = 0; $i < 3; $i++) {\n            $result = $middleware->handle($job = $jobFactory(), $next);\n            $this->assertSame($job, $result);\n            $this->assertTrue($job->released);\n            $this->assertTrue($job->handled);\n\n            Carbon::setTestNow(Carbon::now()->addMilliseconds(100));\n        }\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:00:00.999');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:00:01.000');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertTrue($job->handled);\n    }\n\n    public function testLimitingWithDefaultValues()\n    {\n        $jobFactory = fn () => new class\n        {\n            public $released = false;\n\n            public $handled = false;\n\n            public function release()\n            {\n                $this->released = true;\n\n                return $this;\n            }\n        };\n        $next = function ($job) {\n            $job->handled = true;\n\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions();\n\n        Carbon::setTestNow('2000-00-00 00:00:00.000');\n\n        for ($i = 0; $i < 10; $i++) {\n            $result = $middleware->handle($job = $jobFactory(), $next);\n            $this->assertSame($job, $result);\n            $this->assertTrue($job->released);\n            $this->assertTrue($job->handled);\n\n            Carbon::setTestNow(Carbon::now()->addSeconds(1));\n        }\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:09:59.999');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertFalse($job->handled);\n\n        Carbon::setTestNow('2000-00-00 00:10:00.000');\n\n        $result = $middleware->handle($job = $jobFactory(), $next);\n        $this->assertSame($job, $result);\n        $this->assertTrue($job->released);\n        $this->assertTrue($job->handled);\n    }\n\n    public function testReportingExceptions()\n    {\n        $this->spy(ExceptionHandler::class)\n            ->shouldReceive('report')\n            ->twice()\n            ->with(m::type(RuntimeException::class));\n\n        $job = new class\n        {\n            public function release()\n            {\n                return $this;\n            }\n        };\n        $next = function () {\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions();\n\n        $middleware->report();\n        $middleware->handle($job, $next);\n\n        $middleware->report(fn () => true);\n        $middleware->handle($job, $next);\n\n        $middleware->report(fn () => false);\n        $middleware->handle($job, $next);\n    }\n\n    public function testUsesJobClassNameForCacheKey()\n    {\n        $rateLimiter = $this->mock(RateLimiter::class);\n\n        $job = new class\n        {\n            public $released = false;\n\n            public function release()\n            {\n                $this->released = true;\n\n                return $this;\n            }\n        };\n\n        $expectedKey = 'laravel_throttles_exceptions:'.hash('xxh128', get_class($job));\n\n        $rateLimiter->shouldReceive('tooManyAttempts')\n            ->once()\n            ->with($expectedKey, 10)\n            ->andReturn(false);\n\n        $rateLimiter->shouldReceive('hit')\n            ->once()\n            ->with($expectedKey, 600);\n\n        $next = function ($job) {\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions();\n        $middleware->handle($job, $next);\n\n        $this->assertTrue($job->released);\n    }\n\n    public function testUsesDisplayNameForCacheKeyWhenAvailable()\n    {\n        $rateLimiter = $this->mock(RateLimiter::class);\n\n        $job = new class\n        {\n            public $released = false;\n\n            public function release()\n            {\n                $this->released = true;\n\n                return $this;\n            }\n\n            public function displayName(): string\n            {\n                return 'App\\\\Actions\\\\ThrottlesExceptionsTestAction';\n            }\n        };\n\n        $expectedKey = 'laravel_throttles_exceptions:'.hash('xxh128', 'App\\\\Actions\\\\ThrottlesExceptionsTestAction');\n\n        $rateLimiter->shouldReceive('tooManyAttempts')\n            ->once()\n            ->with($expectedKey, 10)\n            ->andReturn(false);\n\n        $rateLimiter->shouldReceive('hit')\n            ->once()\n            ->with($expectedKey, 600);\n\n        $next = function ($job) {\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptions();\n        $middleware->handle($job, $next);\n\n        $this->assertTrue($job->released);\n    }\n}\n\nclass CircuitBreakerTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptions(2, 10 * 60))->by('test')];\n    }\n}\n\nclass CircuitBreakerSkipJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptions(2, 10 * 60))->deleteWhen(Exception::class)];\n    }\n}\n\nclass CircuitBreakerFailedJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptions(2, 10 * 60))->failWhen(Exception::class)];\n    }\n}\n\nclass CircuitBreakerSuccessfulJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptions(2, 10 * 60))->by('test')];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/ThrottlesExceptionsWithRedisTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Exception;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\ThrottlesExceptionsWithRedis;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse RuntimeException;\n\n#[RequiresPhpExtension('redis')]\nclass ThrottlesExceptionsWithRedisTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n\n        Carbon::setTestNow(Carbon::now());\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testCircuitIsOpenedForJobErrors()\n    {\n        $this->assertJobWasReleasedImmediately(CircuitBreakerWithRedisTestJob::class, $key = Str::random());\n        $this->assertJobWasReleasedImmediately(CircuitBreakerWithRedisTestJob::class, $key);\n        $this->assertJobWasReleasedWithDelay(CircuitBreakerWithRedisTestJob::class, $key);\n    }\n\n    public function testCircuitStaysClosedForSuccessfulJobs()\n    {\n        $this->assertJobRanSuccessfully(CircuitBreakerWithRedisSuccessfulJob::class, $key = Str::random());\n        $this->assertJobRanSuccessfully(CircuitBreakerWithRedisSuccessfulJob::class, $key);\n        $this->assertJobRanSuccessfully(CircuitBreakerWithRedisSuccessfulJob::class, $key);\n    }\n\n    public function testCircuitResetsAfterSuccess()\n    {\n        $this->assertJobWasReleasedImmediately(CircuitBreakerWithRedisTestJob::class, $key = Str::random());\n        $this->assertJobRanSuccessfully(CircuitBreakerWithRedisSuccessfulJob::class, $key);\n        $this->assertJobWasReleasedImmediately(CircuitBreakerWithRedisTestJob::class, $key);\n        $this->assertJobWasReleasedImmediately(CircuitBreakerWithRedisTestJob::class, $key);\n        $this->assertJobWasReleasedWithDelay(CircuitBreakerWithRedisTestJob::class, $key);\n    }\n\n    protected function assertJobWasReleasedImmediately($class, $key)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->with(0)->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class($key)),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    protected function assertJobWasReleasedWithDelay($class, $key)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('release')->withArgs(function ($delay) {\n            return $delay >= 600;\n        })->once();\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class($key)),\n        ]);\n\n        $this->assertFalse($class::$handled);\n    }\n\n    protected function assertJobRanSuccessfully($class, $key)\n    {\n        $class::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->once()->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->once()->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = new $class($key)),\n        ]);\n\n        $this->assertTrue($class::$handled);\n    }\n\n    public function testReportingExceptions()\n    {\n        $this->spy(ExceptionHandler::class)\n            ->shouldReceive('report')\n            ->twice()\n            ->with(m::type(RuntimeException::class));\n\n        $job = new class\n        {\n            public function release()\n            {\n                return $this;\n            }\n        };\n        $next = function () {\n            throw new RuntimeException('Whoops!');\n        };\n\n        $middleware = new ThrottlesExceptionsWithRedis();\n\n        $middleware->report();\n        $middleware->handle($job, $next);\n\n        $middleware->report(fn () => true);\n        $middleware->handle($job, $next);\n\n        $middleware->report(fn () => false);\n        $middleware->handle($job, $next);\n    }\n}\n\nclass CircuitBreakerWithRedisTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public $key;\n\n    public function __construct($key)\n    {\n        $this->key = $key;\n    }\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptionsWithRedis(2, 10 * 60))->by($this->key)];\n    }\n}\n\nclass CircuitBreakerWithRedisSuccessfulJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public $key;\n\n    public function __construct($key)\n    {\n        $this->key = $key;\n    }\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [(new ThrottlesExceptionsWithRedis(2, 10 * 60))->by($this->key)];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/UniqueJobTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Exception;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Bus\\UniqueLock;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Facades\\Bus;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\n\n#[WithMigration]\n#[WithMigration('cache')]\n#[WithMigration('queue')]\nclass UniqueJobTest extends QueueTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n\n        $app['config']->set('cache.default', 'database');\n    }\n\n    public function testUniqueJobsAreNotDispatched()\n    {\n        Bus::fake();\n\n        UniqueTestJob::dispatch();\n        $this->runQueueWorkerCommand(['--once' => true]);\n        Bus::assertDispatched(UniqueTestJob::class);\n\n        $this->assertFalse(\n            $this->app->get(Cache::class)->lock($this->getLockKey(UniqueTestJob::class), 10)->get()\n        );\n\n        Bus::assertDispatchedTimes(UniqueTestJob::class);\n        UniqueTestJob::dispatch();\n        $this->runQueueWorkerCommand(['--once' => true]);\n        Bus::assertDispatchedTimes(UniqueTestJob::class);\n\n        $this->assertFalse(\n            $this->app->get(Cache::class)->lock($this->getLockKey(UniqueTestJob::class), 10)->get()\n        );\n    }\n\n    public function testUniqueJobWithViaDispatched()\n    {\n        Bus::fake();\n\n        UniqueViaJob::dispatch();\n        Bus::assertDispatched(UniqueViaJob::class);\n    }\n\n    public function testLockIsReleasedForSuccessfulJobs()\n    {\n        UniqueTestJob::$handled = false;\n        dispatch($job = new UniqueTestJob);\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertTrue($job::$handled);\n        $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n    }\n\n    public function testLockIsReleasedForFailedJobs()\n    {\n        UniqueTestFailJob::$handled = false;\n\n        $this->expectException(Exception::class);\n\n        try {\n            dispatch_sync($job = new UniqueTestFailJob);\n        } finally {\n            $this->assertTrue($job::$handled);\n            $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n        }\n    }\n\n    public function testLockIsNotReleasedForJobRetries()\n    {\n        $this->markTestSkippedWhenUsingSyncQueueDriver();\n\n        UniqueTestRetryJob::$handled = false;\n\n        dispatch($job = new UniqueTestRetryJob);\n\n        $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertTrue($job::$handled);\n        $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n\n        UniqueTestRetryJob::$handled = false;\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertTrue($job::$handled);\n        $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n    }\n\n    public function testLockIsNotReleasedForJobReleases()\n    {\n        $this->markTestSkippedWhenUsingSyncQueueDriver();\n\n        UniqueTestReleasedJob::$handled = false;\n        dispatch($job = new UniqueTestReleasedJob);\n\n        $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertTrue($job::$handled);\n        $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n\n        UniqueTestReleasedJob::$handled = false;\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertFalse($job::$handled);\n        $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n    }\n\n    public function testLockCanBeReleasedBeforeProcessing()\n    {\n        $this->markTestSkippedWhenUsingSyncQueueDriver();\n\n        UniqueUntilStartTestJob::$handled = false;\n\n        dispatch($job = new UniqueUntilStartTestJob);\n\n        $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n\n        $this->runQueueWorkerCommand(['--once' => true]);\n\n        $this->assertTrue($job::$handled);\n        $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n    }\n\n    public function testLockIsReleasedOnModelNotFoundException()\n    {\n        UniqueTestSerializesModelsJob::$handled = false;\n\n        /** @var \\Illuminate\\Foundation\\Auth\\User */\n        $user = UserFactory::new()->create();\n        $job = new UniqueTestSerializesModelsJob($user);\n\n        $this->expectException(ModelNotFoundException::class);\n\n        try {\n            $user->delete();\n            dispatch($job);\n            $this->runQueueWorkerCommand(['--once' => true]);\n            unserialize(serialize($job));\n        } finally {\n            $this->assertFalse($job::$handled);\n            $this->assertModelMissing($user);\n            $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());\n        }\n    }\n\n    public function testQueueFakeReleasesUniqueJobLocksBetweenFakes()\n    {\n        Queue::fake();\n\n        UniqueTestJob::dispatch();\n        Queue::assertPushed(UniqueTestJob::class);\n\n        Queue::fake();\n\n        UniqueTestJob::dispatch();\n        Queue::assertPushed(UniqueTestJob::class);\n    }\n\n    public function testQueueFakePreservesUniqueJobLockWithinTest()\n    {\n        Queue::fake();\n\n        UniqueTestJob::dispatch();\n        UniqueTestJob::dispatch();\n\n        Queue::assertPushedTimes(UniqueTestJob::class, 1);\n    }\n\n    protected function getLockKey($job)\n    {\n        return 'laravel_unique_job:'.(is_string($job) ? $job : get_class($job)).':';\n    }\n\n    public function testLockUsesDisplayNameWhenAvailable()\n    {\n        Bus::fake();\n\n        $lockKey = 'laravel_unique_job:'.hash('xxh128', 'App\\\\Actions\\\\UniqueTestAction').':';\n\n        dispatch(new UniqueTestJobWithDisplayName);\n        $this->runQueueWorkerCommand(['--once' => true]);\n        Bus::assertDispatched(UniqueTestJobWithDisplayName::class);\n\n        $this->assertFalse(\n            $this->app->get(Cache::class)->lock($lockKey, 10)->get()\n        );\n\n        Bus::assertDispatchedTimes(UniqueTestJobWithDisplayName::class);\n        dispatch(new UniqueTestJobWithDisplayName);\n        $this->runQueueWorkerCommand(['--once' => true]);\n        Bus::assertDispatchedTimes(UniqueTestJobWithDisplayName::class);\n\n        $this->assertFalse(\n            $this->app->get(Cache::class)->lock($lockKey, 10)->get()\n        );\n    }\n\n    public function testUniqueLockCreatesKeyWithClassName()\n    {\n        $this->assertEquals(\n            'laravel_unique_job:'.UniqueTestJob::class.':',\n            UniqueLock::getKey(new UniqueTestJob)\n        );\n    }\n\n    public function testUniqueLockCreatesKeyWithIdAndClassName()\n    {\n        $this->assertEquals(\n            'laravel_unique_job:'.UniqueIdTestJob::class.':unique-id-1',\n            UniqueLock::getKey(new UniqueIdTestJob)\n        );\n    }\n\n    public function testUniqueLockCreatesKeyWithDisplayNameWhenAvailable()\n    {\n        $this->assertEquals(\n            'laravel_unique_job:'.hash('xxh128', 'App\\\\Actions\\\\UniqueTestAction').':unique-id-2',\n            UniqueLock::getKey(new UniqueIdTestJobWithDisplayName)\n        );\n    }\n\n    public function testUniqueLockCreatesKeyWithIdAndDisplayNameWhenAvailable()\n    {\n        $this->assertEquals(\n            'laravel_unique_job:'.hash('xxh128', 'App\\\\Actions\\\\UniqueTestAction').':unique-id-2',\n            UniqueLock::getKey(new UniqueIdTestJobWithDisplayName)\n        );\n    }\n}\n\nclass UniqueTestJob implements ShouldQueue, ShouldBeUnique\n{\n    use InteractsWithQueue, Queueable, Dispatchable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n}\n\nclass UniqueTestFailJob implements ShouldQueue, ShouldBeUnique\n{\n    use InteractsWithQueue, Queueable, Dispatchable;\n\n    public $tries = 1;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n}\n\nclass UniqueTestReleasedJob extends UniqueTestFailJob\n{\n    public $tries = 1;\n\n    public function handle()\n    {\n        static::$handled = true;\n\n        $this->release();\n    }\n}\n\nclass UniqueTestRetryJob extends UniqueTestFailJob\n{\n    public $tries = 2;\n}\n\nclass UniqueUntilStartTestJob extends UniqueTestJob implements ShouldBeUniqueUntilProcessing\n{\n    public $tries = 2;\n}\n\nclass UniqueTestSerializesModelsJob extends UniqueTestJob\n{\n    use SerializesModels;\n\n    public $deleteWhenMissingModels = true;\n\n    public function __construct(public User $user)\n    {\n    }\n}\n\nclass UniqueViaJob extends UniqueTestJob\n{\n    public function uniqueVia(): Cache\n    {\n        return Container::getInstance()->make(Cache::class);\n    }\n}\n\nclass UniqueIdTestJob extends UniqueTestJob\n{\n    public function uniqueId(): string\n    {\n        return 'unique-id-1';\n    }\n}\n\nclass UniqueTestJobWithDisplayName extends UniqueTestJob\n{\n    public function displayName(): string\n    {\n        return 'App\\\\Actions\\\\UniqueTestAction';\n    }\n}\n\nclass UniqueIdTestJobWithDisplayName extends UniqueTestJob\n{\n    public function uniqueId(): string\n    {\n        return 'unique-id-2';\n    }\n\n    public function displayName(): string\n    {\n        return 'App\\\\Actions\\\\UniqueTestAction';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/UniqueUntilProcessingJobTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration]\n#[WithMigration('cache')]\n#[WithMigration('queue')]\nclass UniqueUntilProcessingJobTest extends QueueTestCase\n{\n    protected function defineEnvironment($app)\n    {\n        parent::defineEnvironment($app);\n        $app['config']->set('queue.default', 'database');\n        $app['config']->set('cache.default', 'database');\n        $this->driver = 'database';\n    }\n\n    public function testShouldBeUniqueUntilProcessingReleasesLockWhenJobIsReleasedByAMiddleware()\n    {\n        // Job that does not release and gets processed\n        UniqueTestJobThatDoesNotRelease::dispatch();\n        $lockKey = DB::table('cache_locks')->orderBy('id')->first()->key;\n        $this->assertNotNull($lockKey);\n        $this->runQueueWorkerCommand(['--once' => true]);\n        $this->assertFalse(UniqueTestJobThatDoesNotRelease::$released);\n        $lockKey = DB::table('cache_locks')->first()->key ?? null;\n        $this->assertNull($lockKey);\n        $this->assertDatabaseCount('jobs', 0);\n\n        // Job that releases and does not get processed\n        UniqueUntilProcessingJobThatReleases::dispatch();\n        $lockKey = DB::table('cache_locks')->first()->key;\n        $this->assertNotNull($lockKey);\n        $this->runQueueWorkerCommand(['--once' => true]);\n        $this->assertFalse(UniqueUntilProcessingJobThatReleases::$handled);\n        $this->assertTrue(UniqueUntilProcessingJobThatReleases::$released);\n        $lockKey = DB::table('cache_locks')->orderBy('id')->first()->key ?? null;\n        $this->assertNotNull($lockKey);\n\n        UniqueUntilProcessingJobThatReleases::dispatch();\n        $this->assertDatabaseCount('jobs', 1);\n    }\n}\n\nclass UniqueTestJobThatDoesNotRelease implements ShouldQueue, ShouldBeUniqueUntilProcessing\n{\n    use InteractsWithQueue, Queueable, Dispatchable;\n\n    public static $handled = false;\n    public static $released = false;\n\n    public function __construct()\n    {\n        static::$handled = false;\n        static::$released = false;\n    }\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n}\n\nclass UniqueUntilProcessingJobThatReleases extends UniqueTestJobThatDoesNotRelease\n{\n    public function middleware()\n    {\n        return [\n            function ($job) {\n                static::$released = true;\n\n                return $job->release(30);\n            },\n        ];\n    }\n\n    public function uniqueId()\n    {\n        return 100;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/WithoutOverlappingJobsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Exception;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Cache\\Repository as Cache;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Middleware\\WithoutOverlapping;\nuse Mockery as m;\n\nclass WithoutOverlappingJobsTest extends QueueTestCase\n{\n    public function testNonOverlappingJobsAreExecuted()\n    {\n        OverlappingTestJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command = new OverlappingTestJob),\n        ]);\n\n        $lockKey = (new WithoutOverlapping)->getLockKey($command);\n\n        $this->assertTrue(OverlappingTestJob::$handled);\n        $this->assertTrue($this->app->get(Cache::class)->lock($lockKey, 10)->acquire());\n    }\n\n    public function testLockIsReleasedOnJobExceptions()\n    {\n        FailedOverlappingTestJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n\n        $this->expectException(Exception::class);\n\n        try {\n            $instance->call($job, [\n                'command' => serialize($command = new FailedOverlappingTestJob),\n            ]);\n        } finally {\n            $lockKey = (new WithoutOverlapping)->getLockKey($command);\n\n            $this->assertTrue(FailedOverlappingTestJob::$handled);\n            $this->assertTrue($this->app->get(Cache::class)->lock($lockKey, 10)->acquire());\n        }\n    }\n\n    public function testOverlappingJobsAreReleased()\n    {\n        OverlappingTestJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $lockKey = (new WithoutOverlapping)->getLockKey($command = new OverlappingTestJob);\n        $this->app->get(Cache::class)->lock($lockKey, 10)->acquire();\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('release')->once();\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize($command),\n        ]);\n\n        $this->assertFalse(OverlappingTestJob::$handled);\n    }\n\n    public function testOverlappingJobsCanBeSkipped()\n    {\n        SkipOverlappingTestJob::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $lockKey = (new WithoutOverlapping)->getLockKey($command = new SkipOverlappingTestJob);\n        $this->app->get(Cache::class)->lock($lockKey, 10)->acquire();\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(false);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(false);\n        $job->shouldReceive('delete')->once();\n\n        $instance->call($job, [\n            'command' => serialize($command),\n        ]);\n\n        $this->assertFalse(SkipOverlappingTestJob::$handled);\n    }\n\n    public function testCanShareKeyAcrossJobs()\n    {\n        OverlappingTestJobWithSharedKeyOne::$handled = false;\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $lockKey = (new WithoutOverlapping)->shared()->getLockKey(new OverlappingTestJobWithSharedKeyTwo);\n        $this->app->get(Cache::class)->lock($lockKey, 10)->acquire();\n\n        $job = m::mock(Job::class);\n\n        $job->shouldReceive('release')->once();\n        $job->shouldReceive('hasFailed')->andReturn(false);\n        $job->shouldReceive('isReleased')->andReturn(true);\n        $job->shouldReceive('isDeletedOrReleased')->andReturn(true);\n\n        $instance->call($job, [\n            'command' => serialize(new OverlappingTestJobWithSharedKeyOne),\n        ]);\n\n        $this->assertFalse(OverlappingTestJob::$handled);\n    }\n\n    public function testGetLock()\n    {\n        $job = new OverlappingTestJob;\n\n        $this->assertSame(\n            'laravel-queue-overlap:Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\OverlappingTestJob:key',\n            (new WithoutOverlapping('key'))->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'laravel-queue-overlap:key',\n            (new WithoutOverlapping('key'))->shared()->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'prefix:Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\OverlappingTestJob:key',\n            (new WithoutOverlapping('key'))->withPrefix('prefix:')->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'prefix:key',\n            (new WithoutOverlapping('key'))->withPrefix('prefix:')->shared()->getLockKey($job)\n        );\n    }\n\n    public function testGetLockUsesDisplayName()\n    {\n        $job = new OverlappingTestJobWithDisplayName;\n\n        $this->assertSame(\n            'laravel-queue-overlap:'.hash('xxh128', 'App\\\\Actions\\\\WithoutOverlappingTestAction').':key',\n            (new WithoutOverlapping('key'))->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'laravel-queue-overlap:key',\n            (new WithoutOverlapping('key'))->shared()->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'prefix:'.hash('xxh128', 'App\\\\Actions\\\\WithoutOverlappingTestAction').':key',\n            (new WithoutOverlapping('key'))->withPrefix('prefix:')->getLockKey($job)\n        );\n\n        $this->assertSame(\n            'prefix:key',\n            (new WithoutOverlapping('key'))->withPrefix('prefix:')->shared()->getLockKey($job)\n        );\n    }\n}\n\nclass OverlappingTestJob\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [new WithoutOverlapping];\n    }\n}\n\nclass SkipOverlappingTestJob extends OverlappingTestJob\n{\n    public function middleware()\n    {\n        return [(new WithoutOverlapping)->dontRelease()];\n    }\n}\n\nclass FailedOverlappingTestJob extends OverlappingTestJob\n{\n    public function handle()\n    {\n        static::$handled = true;\n\n        throw new Exception;\n    }\n}\n\nclass OverlappingTestJobWithSharedKeyOne\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [(new WithoutOverlapping)->shared()];\n    }\n}\n\nclass OverlappingTestJobWithSharedKeyTwo\n{\n    use InteractsWithQueue, Queueable;\n\n    public static $handled = false;\n\n    public function handle()\n    {\n        static::$handled = true;\n    }\n\n    public function middleware()\n    {\n        return [(new WithoutOverlapping)->shared()];\n    }\n}\n\nclass OverlappingTestJobWithDisplayName extends OverlappingTestJob\n{\n    public function displayName(): string\n    {\n        return 'App\\\\Actions\\\\WithoutOverlappingTestAction';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/WorkCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Database\\UniqueConstraintViolationException;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Foundation\\Testing\\DatabaseMigrations;\nuse Illuminate\\Queue\\Worker;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Illuminate\\Support\\Facades\\Exceptions;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse RuntimeException;\n\n#[WithMigration]\n#[WithMigration('queue')]\nclass WorkCommandTest extends QueueTestCase\n{\n    use DatabaseMigrations;\n\n    protected function setUp(): void\n    {\n        $this->beforeApplicationDestroyed(function () {\n            FirstJob::$ran = false;\n            SecondJob::$ran = false;\n            ThirdJob::$ran = false;\n        });\n\n        parent::setUp();\n\n        $this->markTestSkippedWhenUsingSyncQueueDriver();\n    }\n\n    public function testRunningOneJob()\n    {\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--once' => true,\n            '--memory' => 1024,\n        ])->assertExitCode(0);\n\n        $this->assertSame(1, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n        $this->assertFalse(SecondJob::$ran);\n    }\n\n    public function testRunTimestampOutputWithDefaultAppTimezone()\n    {\n        // queue.output_timezone not set at all\n        $this->travelTo(Carbon::create(2023, 1, 18, 10, 10, 11));\n        Queue::push(new FirstJob);\n\n        $this->artisan('queue:work', [\n            '--once' => true,\n            '--memory' => 1024,\n        ])->expectsOutputToContain('2023-01-18 10:10:11')\n            ->assertExitCode(0);\n    }\n\n    public function testRunTimestampOutputWithDifferentLogTimezone()\n    {\n        $this->app['config']->set('queue.output_timezone', 'Europe/Helsinki');\n\n        $this->travelTo(Carbon::create(2023, 1, 18, 10, 10, 11));\n        Queue::push(new FirstJob);\n\n        $this->artisan('queue:work', [\n            '--once' => true,\n            '--memory' => 1024,\n        ])->expectsOutputToContain('2023-01-18 12:10:11')\n            ->assertExitCode(0);\n    }\n\n    public function testRunTimestampOutputWithSameAppDefaultAndQueueLogDefault()\n    {\n        $this->app['config']->set('queue.output_timezone', 'UTC');\n\n        $this->travelTo(Carbon::create(2023, 1, 18, 10, 10, 11));\n        Queue::push(new FirstJob);\n\n        $this->artisan('queue:work', [\n            '--once' => true,\n            '--memory' => 1024,\n        ])->expectsOutputToContain('2023-01-18 10:10:11')\n            ->assertExitCode(0);\n    }\n\n    public function testDaemon()\n    {\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--daemon' => true,\n            '--stop-when-empty' => true,\n            '--memory' => 1024,\n        ])->assertExitCode(0);\n\n        $this->assertSame(0, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n        $this->assertTrue(SecondJob::$ran);\n    }\n\n    public function testMemoryExceeded()\n    {\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--daemon' => true,\n            '--stop-when-empty' => true,\n            '--memory' => 1,\n        ])->assertExitCode(12);\n\n        // Memory limit isn't checked until after the first job is attempted.\n        $this->assertSame(1, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n        $this->assertFalse(SecondJob::$ran);\n    }\n\n    public function testMaxJobsExceeded()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--daemon' => true,\n            '--stop-when-empty' => true,\n            '--max-jobs' => 1,\n        ]);\n\n        // Memory limit isn't checked until after the first job is attempted.\n        $this->assertSame(1, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n        $this->assertFalse(SecondJob::$ran);\n    }\n\n    public function testMaxTimeExceeded()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Queue::push(new ThirdJob);\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--daemon' => true,\n            '--stop-when-empty' => true,\n            '--max-time' => 1,\n        ]);\n\n        // Memory limit isn't checked until after the first job is attempted.\n        $this->assertSame(2, Queue::size());\n        $this->assertTrue(ThirdJob::$ran);\n        $this->assertFalse(FirstJob::$ran);\n        $this->assertFalse(SecondJob::$ran);\n    }\n\n    public function testMemoryExitCode()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Worker::$memoryExceededExitCode = 0;\n\n        Queue::push(new FirstJob);\n        Queue::push(new SecondJob);\n\n        $this->artisan('queue:work', [\n            '--memory' => 1,\n        ])->assertExitCode(0);\n\n        // Memory limit isn't checked until after the first job is attempted.\n        $this->assertSame(1, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n        $this->assertFalse(SecondJob::$ran);\n\n        Worker::$memoryExceededExitCode = null;\n    }\n\n    public function testDisableLastRestartCheck()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Worker::$restartable = false;\n\n        $cache = m::mock(Repository::class);\n        $cache->shouldNotReceive('get')->with('illuminate:queue:restart');\n        $cache->shouldReceive('get')->with(m::pattern('/^illuminate:queue:paused:/'), false);\n\n        $cacheManager = m::mock(CacheManager::class);\n        $cacheManager->shouldReceive('driver')->andReturn($cache);\n        $cacheManager->shouldReceive('store')->andReturn($cache);\n\n        $this->app->instance('cache', $cacheManager);\n\n        Queue::push(new FirstJob);\n\n        $this->artisan('queue:work', [\n            '--max-jobs' => 1,\n            '--stop-when-empty' => true,\n        ]);\n\n        $this->assertSame(0, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n\n        Worker::$restartable = true;\n    }\n\n    public function testDisablePauseQueueCheck()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Worker::$pausable = false;\n\n        $cache = m::mock(Repository::class);\n\n        $cache->shouldReceive('get')->with('illuminate:queue:restart')->andReturn(null);\n        $cache->shouldNotReceive('get')->with(m::pattern('/^illuminate:queue:paused:/'), false);\n\n        $cacheManager = m::mock(CacheManager::class);\n        $cacheManager->shouldReceive('driver')->andReturn($cache);\n        $cacheManager->shouldReceive('store')->andReturn($cache);\n\n        $this->app->instance('cache', $cacheManager);\n\n        Queue::push(new FirstJob);\n\n        $this->artisan('queue:work', [\n            '--max-jobs' => 1,\n            '--stop-when-empty' => true,\n        ]);\n\n        $this->assertSame(0, Queue::size());\n        $this->assertTrue(FirstJob::$ran);\n\n        Worker::$pausable = true;\n    }\n\n    public function testFailedJobListenerOnlyRunsOnce()\n    {\n        $this->markTestSkippedWhenUsingQueueDrivers(['redis', 'beanstalkd']);\n\n        Exceptions::fake();\n\n        Queue::push(new FirstJob);\n        $this->withoutMockingConsoleOutput()->artisan('queue:work', ['--once' => true, '--sleep' => 0]);\n\n        Queue::push(new JobWillFail);\n        $this->withoutMockingConsoleOutput()->artisan('queue:work', ['--once' => true]);\n        Exceptions::assertNotReported(UniqueConstraintViolationException::class);\n        $this->assertSame(2, substr_count(Artisan::output(), JobWillFail::class));\n    }\n}\n\nclass FirstJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n\nclass SecondJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        static::$ran = true;\n    }\n}\n\nclass ThirdJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public static $ran = false;\n\n    public function handle()\n    {\n        sleep(1);\n\n        static::$ran = true;\n    }\n}\n\nclass JobWillFail implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public function handle()\n    {\n        throw new RuntimeException;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Queue/typed-properties.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Queue;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass TypedPropertyTestClass\n{\n    use SerializesModels;\n\n    public ModelSerializationTestUser $user;\n\n    public ModelSerializationTestUser $uninitializedUser;\n\n    protected int $id;\n\n    private array $names;\n\n    public function __construct(ModelSerializationTestUser $user, int $id, array $names)\n    {\n        $this->user = $user;\n        $this->id = $id;\n        $this->names = $names;\n    }\n\n    /**\n     * @return int\n     */\n    public function getId()\n    {\n        return $this->id;\n    }\n\n    /**\n     * @return array\n     */\n    public function getNames()\n    {\n        return $this->names;\n    }\n}\n\nclass TypedPropertyCollectionTestClass\n{\n    use SerializesModels;\n\n    public Collection $users;\n\n    public function __construct(Collection $users)\n    {\n        $this->users = $users;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Redis/PredisConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Redis;\n\nuse Illuminate\\Redis\\Connections\\PredisConnection;\nuse Illuminate\\Redis\\Events\\CommandExecuted;\nuse Illuminate\\Support\\Facades\\Event;\nuse Mockery as m;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\nuse Predis\\Client;\nuse Predis\\Command\\Argument\\Search\\SearchArguments;\n\n#[WithConfig('database.redis.client', 'predis')]\nclass PredisConnectionTest extends TestCase\n{\n    public function testPredisCanEmitEventWithArrayableArgumentObject()\n    {\n        if (! class_exists(SearchArguments::class)) {\n            return $this->markTestSkipped('Skipped tests on predis/predis dependency without '.SearchArguments::class);\n        }\n\n        $event = Event::fake();\n\n        $command = 'ftSearch';\n        $parameters = ['test', '*', (new SearchArguments())->dialect('3')->withScores()];\n\n        $predis = new PredisConnection($client = m::mock(Client::class));\n        $predis->setEventDispatcher($event);\n\n        $client->shouldReceive($command)->with(...$parameters)->andReturnTrue();\n\n        $this->assertTrue($predis->command($command, $parameters));\n\n        $event->assertDispatched(function (CommandExecuted $event) use ($command) {\n            return $event->connection instanceof PredisConnection\n                && $event->command === $command\n                && $event->parameters === ['test', '*', ['DIALECT', '3', 'WITHSCORES']];\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/AbilityBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nenum AbilityBackedEnum: string\n{\n    case AccessRoute = 'access-route';\n    case NotAccessRoute = 'not-access-route';\n}\n"
  },
  {
    "path": "tests/Integration/Routing/AuthorizeMiddlewareAttributeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Routing\\Attributes\\Controllers\\Authorize;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass AuthorizeMiddlewareAttributeTest extends TestCase\n{\n    public function test_attribute_is_respected(): void\n    {\n        $route = Route::get('/', [AuthorizeMiddlewareAttributeController::class, 'index']);\n        $this->assertEquals([\n            'Illuminate\\Auth\\Middleware\\Authorize:all',\n            'Illuminate\\Auth\\Middleware\\Authorize:only-index,a',\n            'Illuminate\\Auth\\Middleware\\Authorize:also-index',\n        ], $route->controllerMiddleware());\n\n        $route = Route::get('/', [AuthorizeMiddlewareAttributeController::class, 'show']);\n        $this->assertEquals([\n            'Illuminate\\Auth\\Middleware\\Authorize:all',\n            'Illuminate\\Auth\\Middleware\\Authorize:except-index,a,b',\n        ], $route->controllerMiddleware());\n    }\n}\n\n#[Authorize('all')]\n#[Authorize('only-index', 'a', only: ['index'])]\n#[Authorize('except-index', ['a', 'b'], except: ['index'])]\nclass AuthorizeMiddlewareAttributeController\n{\n    #[Authorize('also-index')]\n    public function index(): void\n    {\n        // ...\n    }\n\n    public function show(): void\n    {\n        // ...\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/CategoryBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nenum CategoryBackedEnum: string\n{\n    case People = 'people';\n    case Fruits = 'fruits';\n\n    public static function fromCode(string $code)\n    {\n        return match ($code) {\n            'c01' => self::People,\n            'c02' => self::Fruits,\n            default => null,\n        };\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/CompiledRouteCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse ArrayIterator;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\RouteCollection;\nuse Illuminate\\Support\\Arr;\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\nclass CompiledRouteCollectionTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Routing\\RouteCollection\n     */\n    protected $routeCollection;\n\n    /**\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = $this->app['router'];\n\n        $this->routeCollection = new RouteCollection;\n    }\n\n    protected function tearDown(): void\n    {\n        unset($this->routeCollection, $this->router);\n\n        parent::tearDown();\n    }\n\n    /**\n     * @return \\Illuminate\\Routing\\CompiledRouteCollection\n     */\n    protected function collection()\n    {\n        return $this->routeCollection->toCompiledRouteCollection($this->router, $this->app);\n    }\n\n    public function testRouteCollectionCanAddRoute()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $this->assertCount(1, $this->collection());\n    }\n\n    public function testRouteCollectionAddReturnsTheRoute()\n    {\n        $outputRoute = $this->collection()->add($inputRoute = $this->newRoute('GET', 'foo', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $this->assertInstanceOf(Route::class, $outputRoute);\n        $this->assertEquals($inputRoute, $outputRoute);\n    }\n\n    public function testRouteCollectionCanRetrieveByName()\n    {\n        $this->routeCollection->add($routeIndex = $this->newRoute('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'route_name',\n        ]));\n\n        $routes = $this->collection();\n\n        $this->assertSame('route_name', $routeIndex->getName());\n        $this->assertSame('route_name', $routes->getByName('route_name')->getName());\n        $this->assertEquals($routeIndex, $routes->getByName('route_name'));\n    }\n\n    public function testRouteCollectionCanRetrieveByAction()\n    {\n        $this->routeCollection->add($routeIndex = $this->newRoute('GET', 'foo/index', $action = [\n            'uses' => 'FooController@index',\n        ]));\n\n        $route = $this->collection()->getByAction('FooController@index');\n\n        $this->assertSame($action, Arr::except($routeIndex->getAction(), 'as'));\n        $this->assertSame($action, Arr::except($route->getAction(), 'as'));\n    }\n\n    public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForActions()\n    {\n        @unlink(__DIR__.'/Fixtures/cache/routes-v7.php');\n        $this->app->useBootstrapPath(__DIR__.'/Fixtures');\n        $app = (static function () {\n            $refresh = true;\n\n            return require __DIR__.'/Fixtures/app.php';\n        })();\n        $app['router']->get('/foo/{bar}', ['FooController', 'show']);\n        $app['router']->get('/foo/{bar}/{baz}', ['FooController', 'show']);\n        $app['router']->getRoutes()->refreshActionLookups();\n\n        $this->assertSame('foo/{bar}', $app['router']->getRoutes()->getByAction('FooController@show')->uri);\n\n        $this->artisan('route:cache')->assertExitCode(0);\n        require __DIR__.'/Fixtures/cache/routes-v7.php';\n\n        $this->assertSame('foo/{bar}', $app['router']->getRoutes()->getByAction('FooController@show')->uri);\n\n        unlink(__DIR__.'/Fixtures/cache/routes-v7.php');\n    }\n\n    public function testCompiledAndNonCompiledUrlResolutionHasSamePrecedenceForNames()\n    {\n        $this->router->get('/foo/{bar}', ['FooController', 'show'])->name('foo.show');\n        $this->router->get('/foo/{bar}/{baz}', ['FooController', 'show'])->name('foo.show');\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertSame('foo/{bar}', $this->router->getRoutes()->getByName('foo.show')->uri);\n    }\n\n    public function testRouteCollectionCanGetIterator()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $this->assertInstanceOf(ArrayIterator::class, $this->collection()->getIterator());\n    }\n\n    public function testRouteCollectionCanGetIteratorWhenEmpty()\n    {\n        $routes = $this->collection();\n\n        $this->assertCount(0, $routes);\n        $this->assertInstanceOf(ArrayIterator::class, $routes->getIterator());\n    }\n\n    public function testRouteCollectionCanGetIteratorWhenRoutesAreAdded()\n    {\n        $this->routeCollection->add($routeIndex = $this->newRoute('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $routes = $this->collection();\n\n        $this->assertCount(1, $routes);\n\n        $this->routeCollection->add($routeShow = $this->newRoute('GET', 'bar/show', [\n            'uses' => 'BarController@show',\n            'as' => 'bar_show',\n        ]));\n\n        $routes = $this->collection();\n\n        $this->assertCount(2, $routes);\n\n        $this->assertInstanceOf(ArrayIterator::class, $routes->getIterator());\n    }\n\n    public function testRouteCollectionCanHandleSameRoute()\n    {\n        $this->routeCollection->add($routeIndex = $this->newRoute('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $routes = $this->collection();\n\n        $this->assertCount(1, $routes);\n\n        // Add exactly the same route\n        $this->routeCollection->add($routeIndex);\n\n        $routes = $this->collection();\n\n        $this->assertCount(1, $routes);\n\n        // Add a non-existing route\n        $this->routeCollection->add($this->newRoute('GET', 'bar/show', [\n            'uses' => 'BarController@show',\n            'as' => 'bar_show',\n        ]));\n\n        $routes = $this->collection();\n\n        $this->assertCount(2, $routes);\n    }\n\n    public function testRouteCollectionCanGetAllRoutes()\n    {\n        $this->routeCollection->add($routeIndex = $this->newRoute('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n        $this->routeCollection->add($routeShow = $this->newRoute('GET', 'foo/show', [\n            'uses' => 'FooController@show',\n            'as' => 'foo_show',\n        ]));\n        $this->routeCollection->add($routeNew = $this->newRoute('POST', 'bar', [\n            'uses' => 'BarController@create',\n            'as' => 'bar_create',\n        ]));\n\n        $allRoutes = [\n            $routeIndex,\n            $routeShow,\n            $routeNew,\n        ];\n        $this->assertEquals($allRoutes, $this->collection()->getRoutes());\n    }\n\n    public function testRouteCollectionCanGetRoutesByName()\n    {\n        $routesByName = [\n            'foo_index' => $this->newRoute('GET', 'foo/index', [\n                'uses' => 'FooController@index',\n                'as' => 'foo_index',\n            ]),\n            'foo_show' => $this->newRoute('GET', 'foo/show', [\n                'uses' => 'FooController@show',\n                'as' => 'foo_show',\n            ]),\n            'bar_create' => $this->newRoute('POST', 'bar', [\n                'uses' => 'BarController@create',\n                'as' => 'bar_create',\n            ]),\n        ];\n\n        $this->routeCollection->add($routesByName['foo_index']);\n        $this->routeCollection->add($routesByName['foo_show']);\n        $this->routeCollection->add($routesByName['bar_create']);\n\n        $this->assertEquals($routesByName, $this->collection()->getRoutesByName());\n    }\n\n    public function testRouteCollectionCanGetRoutesByMethod()\n    {\n        $routes = [\n            'foo_index' => $this->newRoute('GET', 'foo/index', [\n                'uses' => 'FooController@index',\n                'as' => 'foo_index',\n            ]),\n            'foo_show' => $this->newRoute('GET', 'foo/show', [\n                'uses' => 'FooController@show',\n                'as' => 'foo_show',\n            ]),\n            'bar_create' => $this->newRoute('POST', 'bar', [\n                'uses' => 'BarController@create',\n                'as' => 'bar_create',\n            ]),\n        ];\n\n        $this->routeCollection->add($routes['foo_index']);\n        $this->routeCollection->add($routes['foo_show']);\n        $this->routeCollection->add($routes['bar_create']);\n\n        $this->assertEquals([\n            'GET' => [\n                'foo/index' => $routes['foo_index'],\n                'foo/show' => $routes['foo_show'],\n            ],\n            'HEAD' => [\n                'foo/index' => $routes['foo_index'],\n                'foo/show' => $routes['foo_show'],\n            ],\n            'POST' => [\n                'bar' => $routes['bar_create'],\n            ],\n        ], $this->collection()->getRoutesByMethod());\n    }\n\n    public function testRouteCollectionCleansUpOverwrittenRoutes()\n    {\n        // Create two routes with the same path and method.\n        $routeA = $this->newRoute('GET', 'product', ['controller' => 'View@view', 'as' => 'routeA']);\n        $routeB = $this->newRoute('GET', 'product', ['controller' => 'OverwrittenView@view', 'as' => 'overwrittenRouteA']);\n\n        $this->routeCollection->add($routeA);\n        $this->routeCollection->add($routeB);\n\n        // Check if the lookups of $routeA and $routeB are there.\n        $this->assertEquals($routeA, $this->routeCollection->getByName('routeA'));\n        $this->assertEquals($routeA, $this->routeCollection->getByAction('View@view'));\n        $this->assertEquals($routeB, $this->routeCollection->getByName('overwrittenRouteA'));\n        $this->assertEquals($routeB, $this->routeCollection->getByAction('OverwrittenView@view'));\n\n        $routes = $this->collection();\n\n        // The lookups of $routeA should not be there anymore, because they are no longer valid.\n        $this->assertNull($routes->getByName('routeA'));\n        $this->assertNull($routes->getByAction('View@view'));\n        // The lookups of $routeB are still there.\n        $this->assertEquals($routeB, $routes->getByName('overwrittenRouteA'));\n        $this->assertEquals($routeB, $routes->getByAction('OverwrittenView@view'));\n    }\n\n    public function testMatchingThrowsNotFoundExceptionWhenRouteIsNotFound()\n    {\n        $this->routeCollection->add($this->newRoute('GET', '/', ['uses' => 'FooController@index']));\n\n        $this->expectException(NotFoundHttpException::class);\n\n        $this->collection()->match(Request::create('/foo'));\n    }\n\n    public function testMatchingThrowsMethodNotAllowedHttpExceptionWhenMethodIsNotAllowed()\n    {\n        $this->routeCollection->add($this->newRoute('GET', '/foo', ['uses' => 'FooController@index']));\n\n        $this->expectException(MethodNotAllowedHttpException::class);\n\n        $this->collection()->match(Request::create('/foo', 'POST'));\n    }\n\n    public function testMatchingThrowsExceptionWhenMethodIsNotAllowedWhileSameRouteIsAddedDynamically()\n    {\n        $this->routeCollection->add($this->newRoute('GET', '/', ['uses' => 'FooController@index']));\n\n        $routes = $this->collection();\n\n        $routes->add($this->newRoute('POST', '/', ['uses' => 'FooController@index']));\n\n        $this->expectException(MethodNotAllowedHttpException::class);\n\n        $routes->match(Request::create('/', 'PUT'));\n    }\n\n    public function testMatchingRouteWithSameDynamicallyAddedRouteAlwaysMatchesCachedOneFirst()\n    {\n        $this->routeCollection->add(\n            $route = $this->newRoute('GET', '/', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $routes = $this->collection();\n\n        $routes->add($this->newRoute('GET', '/', ['uses' => 'FooController@index', 'as' => 'bar']));\n\n        $this->assertSame('foo', $routes->match(Request::create('/', 'GET'))->getName());\n    }\n\n    public function testMatchingFindsRouteWithDifferentMethodDynamically()\n    {\n        $this->routeCollection->add($this->newRoute('GET', '/foo', ['uses' => 'FooController@index']));\n\n        $routes = $this->collection();\n\n        $routes->add($route = $this->newRoute('POST', '/foo', ['uses' => 'FooController@index']));\n\n        $this->assertSame($route, $routes->match(Request::create('/foo', 'POST')));\n    }\n\n    public function testMatchingWildcardFromCompiledRoutesAlwaysTakesPrecedent()\n    {\n        $this->routeCollection->add(\n            $route = $this->newRoute('GET', '{wildcard}', ['uses' => 'FooController@index', 'as' => 'foo'])\n                ->where('wildcard', '.*')\n        );\n\n        $routes = $this->collection();\n\n        $routes->add(\n            $this->newRoute('GET', '{wildcard}', ['uses' => 'FooController@index', 'as' => 'bar'])\n                ->where('wildcard', '.*')\n        );\n\n        $this->assertSame('foo', $routes->match(Request::create('/foo', 'GET'))->getName());\n    }\n\n    public function testMatchingDynamicallyAddedRoutesTakePrecedenceOverFallbackRoutes()\n    {\n        $this->routeCollection->add($this->fallbackRoute(['uses' => 'FooController@index']));\n        $this->routeCollection->add(\n            $this->newRoute('GET', '/foo/{id}', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $routes = $this->collection();\n\n        $routes->add($this->newRoute('GET', '/bar/{id}', ['uses' => 'FooController@index', 'as' => 'bar']));\n\n        $this->assertSame('bar', $routes->match(Request::create('/bar/1', 'GET'))->getName());\n    }\n\n    public function testMatchingFallbackRouteCatchesAll()\n    {\n        $this->routeCollection->add($this->fallbackRoute(['uses' => 'FooController@index', 'as' => 'fallback']));\n        $this->routeCollection->add(\n            $this->newRoute('GET', '/foo/{id}', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $routes = $this->collection();\n\n        $routes->add($this->newRoute('GET', '/bar/{id}', ['uses' => 'FooController@index', 'as' => 'bar']));\n\n        $this->assertSame('fallback', $routes->match(Request::create('/baz/1', 'GET'))->getName());\n    }\n\n    public function testMatchingCachedFallbackTakesPrecedenceOverDynamicFallback()\n    {\n        $this->routeCollection->add($this->fallbackRoute(['uses' => 'FooController@index', 'as' => 'fallback']));\n\n        $routes = $this->collection();\n\n        $routes->add($this->fallbackRoute(['uses' => 'FooController@index', 'as' => 'dynamic_fallback']));\n\n        $this->assertSame('fallback', $routes->match(Request::create('/baz/1', 'GET'))->getName());\n    }\n\n    public function testMatchingCachedFallbackTakesPrecedenceOverDynamicRouteWithWrongMethod()\n    {\n        $this->routeCollection->add($this->fallbackRoute(['uses' => 'FooController@index', 'as' => 'fallback']));\n\n        $routes = $this->collection();\n\n        $routes->add($this->newRoute('POST', '/bar/{id}', ['uses' => 'FooController@index', 'as' => 'bar']));\n\n        $this->assertSame('fallback', $routes->match(Request::create('/bar/1', 'GET'))->getName());\n    }\n\n    public function testSlashPrefixIsProperlyHandled()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo/bar', ['uses' => 'FooController@index', 'prefix' => '/']));\n\n        $route = $this->collection()->getByAction('FooController@index');\n\n        $this->assertSame('foo/bar', $route->uri());\n    }\n\n    public function testRouteWithoutNamespaceIsFound()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo/bar', ['controller' => '\\App\\FooController']));\n\n        $route = $this->collection()->getByAction('App\\FooController');\n\n        $this->assertSame('foo/bar', $route->uri());\n    }\n\n    public function testGroupPrefixAndRoutePrefixAreProperlyHandled()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo/bar', ['uses' => 'FooController@index', 'prefix' => '{locale}'])->prefix('pre'));\n\n        $route = $this->collection()->getByAction('FooController@index');\n\n        $this->assertSame('pre/{locale}', $route->getPrefix());\n    }\n\n    public function testGroupGenerateNameForDuplicateRouteNamesThatEndWithDot()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'foo', ['uses' => 'FooController@index'])->name('foo.'));\n        $this->routeCollection->add($route = $this->newRoute('GET', 'bar', ['uses' => 'BarController@index'])->name('foo.'));\n\n        $routes = $this->collection();\n\n        $this->assertSame('BarController@index', $routes->match(Request::create('/bar', 'GET'))->getAction()['uses']);\n    }\n\n    public function testRouteBindingsAreProperlySaved()\n    {\n        $this->routeCollection->add($this->newRoute('GET', 'posts/{post:slug}/show', [\n            'uses' => 'FooController@index',\n            'prefix' => 'profile/{user:username}',\n            'as' => 'foo',\n        ]));\n\n        $route = $this->collection()->getByName('foo');\n\n        $this->assertSame('profile/{user}/posts/{post}/show', $route->uri());\n        $this->assertSame(['user' => 'username', 'post' => 'slug'], $route->bindingFields());\n    }\n\n    public function testMatchingSlashedRoutes()\n    {\n        $this->routeCollection->add(\n            $route = $this->newRoute('GET', 'foo/bar', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $this->assertSame('foo', $this->collection()->match(Request::create('/foo/bar/'))->getName());\n    }\n\n    public function testMatchingUriWithQuery()\n    {\n        $this->routeCollection->add(\n            $route = $this->newRoute('GET', 'foo/bar', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $this->assertSame('foo', $this->collection()->match(Request::create('/foo/bar/?foo=bar'))->getName());\n    }\n\n    public function testMatchingRootUri()\n    {\n        $this->routeCollection->add(\n            $route = $this->newRoute('GET', '/', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $this->assertSame('foo', $this->collection()->match(Request::create('http://example.com'))->getName());\n    }\n\n    public function testTrailingSlashIsTrimmedWhenMatchingCachedRoutes()\n    {\n        $this->routeCollection->add(\n            $this->newRoute('GET', 'foo/bar', ['uses' => 'FooController@index', 'as' => 'foo'])\n        );\n\n        $request = Request::create('/foo/bar/');\n\n        // Access to request path info before matching route\n        $request->getPathInfo();\n\n        $this->assertSame('foo', $this->collection()->match($request)->getName());\n    }\n\n    public function testRouteWithSamePathAndSameMethodButDiffDomainNameWithOptionsMethod()\n    {\n        $routes = [\n            'foo_domain' => $this->newRoute('GET', 'same/path', [\n                'uses' => 'FooController@index',\n                'as' => 'foo',\n                'domain' => 'foo.localhost',\n            ]),\n            'bar_domain' => $this->newRoute('GET', 'same/path', [\n                'uses' => 'BarController@index',\n                'as' => 'bar',\n                'domain' => 'bar.localhost',\n            ]),\n            'no_domain' => $this->newRoute('GET', 'same/path', [\n                'uses' => 'BarController@index',\n                'as' => 'no_domain',\n            ]),\n        ];\n\n        $this->routeCollection->add($routes['foo_domain']);\n        $this->routeCollection->add($routes['bar_domain']);\n        $this->routeCollection->add($routes['no_domain']);\n\n        $expectedMethods = [\n            'OPTIONS',\n        ];\n\n        $this->assertSame($expectedMethods, $this->collection()->match(\n            Request::create('http://foo.localhost/same/path', 'OPTIONS')\n        )->methods);\n\n        $this->assertSame($expectedMethods, $this->collection()->match(\n            Request::create('http://bar.localhost/same/path', 'OPTIONS')\n        )->methods);\n\n        $this->assertSame($expectedMethods, $this->collection()->match(\n            Request::create('http://no.localhost/same/path', 'OPTIONS')\n        )->methods);\n\n        $this->assertEquals([\n            'HEAD' => [\n                'foo.localhostsame/path' => $routes['foo_domain'],\n                'bar.localhostsame/path' => $routes['bar_domain'],\n                'same/path' => $routes['no_domain'],\n            ],\n            'GET' => [\n                'foo.localhostsame/path' => $routes['foo_domain'],\n                'bar.localhostsame/path' => $routes['bar_domain'],\n                'same/path' => $routes['no_domain'],\n            ],\n        ], $this->collection()->getRoutesByMethod());\n    }\n\n    /**\n     * Create a new Route object.\n     *\n     * @param  array|string  $methods\n     * @param  string  $uri\n     * @param  mixed  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function newRoute($methods, $uri, $action)\n    {\n        return (new Route($methods, $uri, $action))\n            ->setRouter($this->router)\n            ->setContainer($this->app);\n    }\n\n    /**\n     * Create a new fallback Route object.\n     *\n     * @param  mixed  $action\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function fallbackRoute($action)\n    {\n        $placeholder = 'fallbackPlaceholder';\n\n        return $this->newRoute(\n            'GET', \"{{$placeholder}}\", $action\n        )->where($placeholder, '.*')->fallback();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/FallbackRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FallbackRouteTest extends TestCase\n{\n    public function testBasicFallback()\n    {\n        Route::fallback(function () {\n            return response('fallback', 404);\n        });\n\n        Route::get('one', function () {\n            return 'one';\n        });\n\n        $this->assertStringContainsString('one', $this->get('/one')->getContent());\n        $this->assertStringContainsString('fallback', $this->get('/non-existing')->getContent());\n        $this->assertEquals(404, $this->get('/non-existing')->getStatusCode());\n    }\n\n    public function testFallbackWithPrefix()\n    {\n        Route::group(['prefix' => 'prefix'], function () {\n            Route::fallback(function () {\n                return response('fallback', 404);\n            });\n\n            Route::get('one', function () {\n                return 'one';\n            });\n        });\n\n        $this->assertStringContainsString('one', $this->get('/prefix/one')->getContent());\n        $this->assertStringContainsString('fallback', $this->get('/prefix/non-existing')->getContent());\n        $this->assertStringContainsString('fallback', $this->get('/prefix/non-existing/with/multiple/segments')->getContent());\n        $this->assertStringContainsString('Not Found', $this->get('/non-existing')->getContent());\n    }\n\n    public function testFallbackWithWildcards()\n    {\n        Route::fallback(function () {\n            return response('fallback', 404);\n        });\n\n        Route::get('one', function () {\n            return 'one';\n        });\n\n        Route::get('{any}', function () {\n            return 'wildcard';\n        })->where('any', '.*');\n\n        $this->assertStringContainsString('one', $this->get('/one')->getContent());\n\n        tap($this->get('/non-existing'), function ($response) {\n            $this->assertStringContainsString('wildcard', $response->getContent());\n            $this->assertEquals(200, $response->getStatusCode());\n\n            $this->assertSame('non-existing', $response->baseRequest->route('any'));\n        });\n    }\n\n    public function testNoRoutes()\n    {\n        Route::fallback(function () {\n            return response('fallback', 404);\n        });\n\n        $this->assertStringContainsString('fallback', $this->get('/non-existing')->getContent());\n        $this->assertEquals(404, $this->get('/non-existing')->getStatusCode());\n    }\n\n    public function testRespondWithNamedFallbackRoute()\n    {\n        Route::fallback(function () {\n            return response('fallback', 404);\n        })->name('testFallbackRoute');\n\n        Route::get('one', function () {\n            return Route::respondWithRoute('testFallbackRoute');\n        });\n\n        $this->assertStringContainsString('fallback', $this->get('/non-existing')->getContent());\n        $this->assertStringContainsString('fallback', $this->get('/one')->getContent());\n    }\n\n    public function testNoFallbacks()\n    {\n        Route::get('one', function () {\n            return 'one';\n        });\n\n        $this->assertStringContainsString('one', $this->get('/one')->getContent());\n        $this->assertEquals(200, $this->get('/one')->getStatusCode());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/ApiResourceTaskController.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Routing\\Controller;\n\nclass ApiResourceTaskController extends Controller\n{\n    public function index()\n    {\n        return 'I`m index tasks';\n    }\n\n    public function store()\n    {\n        return 'I`m store tasks';\n    }\n\n    public function show()\n    {\n        return 'I`m show tasks';\n    }\n\n    public function update()\n    {\n        return 'I`m update tasks';\n    }\n\n    public function destroy()\n    {\n        return 'I`m destroy tasks';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/ApiResourceTestController.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Routing\\Controller;\n\nclass ApiResourceTestController extends Controller\n{\n    public function index()\n    {\n        return 'I`m index';\n    }\n\n    public function store()\n    {\n        return 'I`m store';\n    }\n\n    public function show()\n    {\n        return 'I`m show';\n    }\n\n    public function update()\n    {\n        return 'I`m update';\n    }\n\n    public function destroy()\n    {\n        return 'I`m destroy';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/CreatableSingletonTestController.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Routing\\Controller;\n\nclass CreatableSingletonTestController extends Controller\n{\n    public function create()\n    {\n        return 'singleton create';\n    }\n\n    public function store()\n    {\n        return 'singleton store';\n    }\n\n    public function show()\n    {\n        return 'singleton show';\n    }\n\n    public function edit()\n    {\n        return 'singleton edit';\n    }\n\n    public function update()\n    {\n        return 'singleton update';\n    }\n\n    public function destroy()\n    {\n        return 'singleton destroy';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/NestedSingletonTestController.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Routing\\Controller;\n\nclass NestedSingletonTestController extends Controller\n{\n    public function show($video)\n    {\n        return \"singleton show for $video\";\n    }\n\n    public function edit($video)\n    {\n        return \"singleton edit for $video\";\n    }\n\n    public function update($video)\n    {\n        return \"singleton update for $video\";\n    }\n\n    public function destroy($video)\n    {\n        return \"singleton destroy for $video\";\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/SingletonTestController.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Routing\\Controller;\n\nclass SingletonTestController extends Controller\n{\n    public function show()\n    {\n        return 'singleton show';\n    }\n\n    public function edit()\n    {\n        return 'singleton edit';\n    }\n\n    public function update()\n    {\n        return 'singleton update';\n    }\n\n    public function destroy()\n    {\n        return 'singleton destroy';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/app.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing\\Fixtures;\n\nuse Illuminate\\Foundation\\Application;\n\nif (! class_exists(AppCache::class)) {\n    class AppCache\n    {\n        public static $app;\n    }\n}\n\nif (isset($refresh)) {\n    return AppCache::$app = Application::configure(basePath: __DIR__)->create();\n} else {\n    return AppCache::$app ??= Application::configure(basePath: __DIR__)->create();\n}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/bootstrap/cache/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/cache/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/redirect_routes.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::redirect('/foo/1', '/foo/1/bar');\n\nRoute::get('/foo/1/bar', function () {\n    return 'Redirect response';\n});\n\nRoute::get('/foo/1', function () {\n    return 'GET response';\n});\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/view.blade.php",
    "content": "Test {{$foo}}\n"
  },
  {
    "path": "tests/Integration/Routing/Fixtures/wildcard_catch_all_routes.php",
    "content": "<?php\n\nuse Illuminate\\Support\\Facades\\Route;\n\nRoute::get('/foo', function () {\n    return 'Regular route';\n});\n\nRoute::get('{slug}', function () {\n    return 'Wildcard route';\n});\n"
  },
  {
    "path": "tests/Integration/Routing/FluentRoutingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass FluentRoutingTest extends TestCase\n{\n    public static $value = '';\n\n    public function testMiddlewareRunWhenRegisteredAsArrayOrParams()\n    {\n        $controller = function () {\n            return 'Hello World';\n        };\n\n        Route::middleware(Middleware::class, Middleware2::class)\n            ->get('before', $controller);\n\n        Route::get('after', $controller)\n            ->middleware(Middleware::class, Middleware2::class);\n\n        Route::middleware([Middleware::class, Middleware2::class])\n            ->get('before_array', $controller);\n\n        Route::get('after_array', $controller)\n            ->middleware([Middleware::class, Middleware2::class]);\n\n        Route::middleware(Middleware::class)\n            ->get('before_after', $controller)\n            ->middleware([Middleware2::class]);\n\n        Route::middleware(Middleware::class)\n            ->middleware(Middleware2::class)\n            ->get('both_before', $controller);\n\n        Route::get('both_after', $controller)\n            ->middleware(Middleware::class)\n            ->middleware(Middleware2::class);\n\n        $this->assertSame('1_2', $this->get('before')->content());\n        $this->assertSame('1_2', $this->get('after')->content());\n        $this->assertSame('1_2', $this->get('before_array')->content());\n        $this->assertSame('1_2', $this->get('after_array')->content());\n        $this->assertSame('1_2', $this->get('before_after')->content());\n        $this->assertSame('1_2', $this->get('both_before')->content());\n        $this->assertSame('1_2', $this->get('both_after')->content());\n        $this->assertSame('1_2', $this->get('both_after')->content());\n    }\n\n    public function testEmptyMiddlewareGroupAreHandledGracefully()\n    {\n        $controller = function () {\n            return 'Hello World';\n        };\n\n        Route::middlewareGroup('public', []);\n\n        Route::middleware('public')\n            ->get('public', $controller);\n\n        $this->assertSame('Hello World', $this->get('public')->content());\n    }\n}\n\nclass Middleware\n{\n    public function handle($request, $next)\n    {\n        FluentRoutingTest::$value = '1';\n\n        return $next($request);\n    }\n}\n\nclass Middleware2\n{\n    public function handle()\n    {\n        return FluentRoutingTest::$value.'_2';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/HasMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Routing\\Controllers\\HasMiddleware;\nuse Illuminate\\Routing\\Controllers\\Middleware;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass HasMiddlewareTest extends TestCase\n{\n    public function test_has_middleware_is_respected()\n    {\n        $route = Route::get('/', [HasMiddlewareTestController::class, 'index']);\n        $this->assertEquals($route->controllerMiddleware(), ['all', 'only-index']);\n\n        $route = Route::get('/', [HasMiddlewareTestController::class, 'show']);\n        $this->assertEquals($route->controllerMiddleware(), ['all', 'except-index']);\n    }\n}\n\nclass HasMiddlewareTestController implements HasMiddleware\n{\n    public static function middleware()\n    {\n        return [\n            new Middleware('all'),\n            (new Middleware('only-index'))->only('index'),\n            (new Middleware('except-index'))->except('index'),\n        ];\n    }\n\n    public function index()\n    {\n        //\n    }\n\n    public function show()\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/ImplicitBackedEnumRouteBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ImplicitBackedEnumRouteBindingTest extends TestCase\n{\n    protected function defineEnvironment($app): void\n    {\n        $app['config']->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']);\n    }\n\n    public function testWithRouteCachingEnabled()\n    {\n        $this->defineCacheRoutes(<<<PHP\n<?php\n\nuse Illuminate\\Tests\\Integration\\Routing\\CategoryBackedEnum;\n\nRoute::get('/categories/{category}', function (CategoryBackedEnum \\$category) {\n    return \\$category->value;\n})->middleware('web');\n\nRoute::get('/categories-default/{category?}', function (CategoryBackedEnum \\$category = CategoryBackedEnum::Fruits) {\n    return \\$category->value;\n})->middleware('web');\nPHP);\n\n        $response = $this->get('/categories/fruits');\n        $response->assertSee('fruits');\n\n        $response = $this->get('/categories/people');\n        $response->assertSee('people');\n\n        $response = $this->get('/categories/cars');\n        $response->assertNotFound(404);\n\n        $response = $this->get('/categories-default/');\n        $response->assertSee('fruits');\n\n        $response = $this->get('/categories-default/people');\n        $response->assertSee('people');\n\n        $response = $this->get('/categories-default/fruits');\n        $response->assertSee('fruits');\n    }\n\n    public function testWithoutRouteCachingEnabled()\n    {\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::post('/categories/{category}', function (CategoryBackedEnum $category) {\n            return $category->value;\n        })->middleware(['web']);\n\n        Route::post('/categories-default/{category?}', function (CategoryBackedEnum $category = CategoryBackedEnum::Fruits) {\n            return $category->value;\n        })->middleware('web');\n\n        Route::bind('categoryCode', fn (string $categoryCode) => CategoryBackedEnum::fromCode($categoryCode) ?? abort(404));\n\n        Route::post('/categories-code/{categoryCode}', function (CategoryBackedEnum $categoryCode) {\n            return $categoryCode->value;\n        })->middleware(['web']);\n\n        $response = $this->post('/categories/fruits');\n        $response->assertSee('fruits');\n\n        $response = $this->post('/categories/people');\n        $response->assertSee('people');\n\n        $response = $this->post('/categories/cars');\n        $response->assertNotFound();\n\n        $response = $this->post('/categories-default/');\n        $response->assertSee('fruits');\n\n        $response = $this->post('/categories-default/people');\n        $response->assertSee('people');\n\n        $response = $this->post('/categories-default/fruits');\n        $response->assertSee('fruits');\n\n        $response = $this->post('/categories-code/c01');\n        $response->assertSee('people');\n\n        $response = $this->post('/categories-code/c02');\n        $response->assertSee('fruits');\n\n        $response = $this->post('/categories-code/00');\n        $response->assertNotFound();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/ImplicitModelRouteBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;\nuse Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Concerns\\InteractsWithPublishedFiles;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF')]\nclass ImplicitModelRouteBindingTest extends TestCase\n{\n    use InteractsWithPublishedFiles;\n\n    protected $files = [\n        'routes/testbench.php',\n    ];\n\n    protected function defineDatabaseMigrations(): void\n    {\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('name');\n            $table->timestamps();\n            $table->softDeletes();\n        });\n\n        Schema::create('posts', function (Blueprint $table) {\n            $table->increments('id');\n            $table->integer('user_id');\n            $table->timestamps();\n        });\n\n        Schema::create('tags', function (Blueprint $table) {\n            $table->ulid('id')->primary();\n            $table->string('slug');\n            $table->integer('post_id');\n            $table->timestamps();\n        });\n\n        Schema::create('comments', function (Blueprint $table) {\n            $table->uuid('id')->primary();\n            $table->string('slug');\n            $table->integer('user_id');\n            $table->timestamps();\n        });\n\n        $this->beforeApplicationDestroyed(function () {\n            Schema::dropIfExists('users');\n            Schema::dropIfExists('posts');\n            Schema::dropIfExists('tags');\n            Schema::dropIfExists('comments');\n        });\n    }\n\n    public function testWithRouteCachingEnabled()\n    {\n        $this->defineCacheRoutes(<<<PHP\n<?php\n\nuse Illuminate\\Tests\\Integration\\Routing\\ImplicitBindingUser;\n\nRoute::post('/user/{user}', function (ImplicitBindingUser \\$user) {\n    return \\$user;\n})->middleware('web');\nPHP);\n\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n\n        $response = $this->postJson(\"/user/{$user->id}\");\n\n        $response->assertJson([\n            'id' => $user->id,\n            'name' => $user->name,\n        ]);\n    }\n\n    public function testWithoutRouteCachingEnabled()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::post('/user/{user}', function (ImplicitBindingUser $user) {\n            return $user;\n        })->middleware(['web']);\n\n        $response = $this->postJson(\"/user/{$user->id}\");\n\n        $response->assertJson([\n            'id' => $user->id,\n            'name' => $user->name,\n        ]);\n\n        $this->assertTrue($user->is($response->baseRequest->route('user')));\n    }\n\n    public function testSoftDeletedModelsAreNotRetrieved()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n\n        $user->delete();\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::post('/user/{user}', function (ImplicitBindingUser $user) {\n            return $user;\n        })->middleware(['web']);\n\n        $response = $this->postJson(\"/user/{$user->id}\");\n\n        $response->assertStatus(404);\n    }\n\n    public function testSoftDeletedModelsCanBeRetrievedUsingWithTrashedMethod()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n\n        $user->delete();\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::post('/user/{user}', function (ImplicitBindingUser $user) {\n            return $user;\n        })->middleware(['web'])->withTrashed();\n\n        $response = $this->postJson(\"/user/{$user->id}\");\n\n        $response->assertJson([\n            'id' => $user->id,\n            'name' => $user->name,\n        ]);\n\n        $this->assertTrue($user->is($response->baseRequest->route('user')));\n    }\n\n    public function testEnforceScopingImplicitRouteBindings()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n        $post = ImplicitBindingPost::create(['user_id' => 2]);\n        $this->assertEmpty($user->posts);\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::scopeBindings()->group(function () {\n            Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {\n                return [$user, $post];\n            })->middleware(['web']);\n        });\n\n        $response = $this->getJson(\"/user/{$user->id}/post/{$post->id}\");\n\n        $response->assertNotFound();\n    }\n\n    public function testEnforceScopingImplicitRouteBindingsWithTrashedAndChildWithNoSoftDeleteTrait()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n\n        $post = $user->posts()->create();\n\n        $user->delete();\n\n        config(['app.key' => str_repeat('a', 32)]);\n        Route::scopeBindings()->group(function () {\n            Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {\n                return [$user, $post];\n            })->middleware(['web'])->withTrashed();\n        });\n\n        $response = $this->getJson(\"/user/{$user->id}/post/{$post->id}\");\n        $response->assertOk();\n        $response->assertJson([\n            [\n                'id' => $user->id,\n                'name' => $user->name,\n            ],\n            [\n                'id' => 1,\n                'user_id' => 1,\n            ],\n        ]);\n    }\n\n    public function testEnforceScopingImplicitRouteBindingsWithRouteCachingEnabled()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n        $post = ImplicitBindingPost::create(['user_id' => 2]);\n        $this->assertEmpty($user->posts);\n\n        $this->defineCacheRoutes(<<<PHP\n<?php\n\nuse Illuminate\\Tests\\Integration\\Routing\\ImplicitBindingUser;\nuse Illuminate\\Tests\\Integration\\Routing\\ImplicitBindingPost;\n\nRoute::group(['scope_bindings' => true], function () {\n    Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser \\$user, ImplicitBindingPost \\$post) {\n        return [\\$user, \\$post];\n    })->middleware(['web']);\n});\nPHP);\n\n        $response = $this->getJson(\"/user/{$user->id}/post/{$post->id}\");\n\n        $response->assertNotFound();\n    }\n\n    public function testWithoutEnforceScopingImplicitRouteBindings()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n        $post = ImplicitBindingPost::create(['user_id' => 2]);\n        $this->assertEmpty($user->posts);\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        Route::group(['scope_bindings' => false], function () {\n            Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {\n                return [$user, $post];\n            })->middleware(['web']);\n        });\n\n        $response = $this->getJson(\"/user/{$user->id}/post/{$post->id}\");\n        $response->assertOk();\n        $response->assertJson([\n            [\n                'id' => $user->id,\n                'name' => $user->name,\n            ],\n            [\n                'id' => 1,\n                'user_id' => 2,\n            ],\n        ]);\n    }\n\n    public function testImplicitRouteBindingChildHasUuids()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Dries']);\n        $comment = ImplicitBindingComment::create([\n            'slug' => 'slug',\n            'user_id' => $user->id,\n        ]);\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        $function = function (ImplicitBindingUser $user, ImplicitBindingComment $comment) {\n            return [$user, $comment];\n        };\n\n        Route::middleware(['web'])->group(function () use ($function) {\n            Route::get('/user/{user}/comment/{comment}', $function);\n            Route::get('/user/{user}/comment-id/{comment:id}', $function);\n            Route::get('/user/{user}/comment-slug/{comment:slug}', $function);\n        });\n\n        $response = $this->getJson(\"/user/{$user->id}/comment/{$comment->slug}\");\n        $response->assertJsonFragment(['id' => $comment->id]);\n\n        $response = $this->getJson(\"/user/{$user->id}/comment-id/{$comment->id}\");\n        $response->assertJsonFragment(['id' => $comment->id]);\n\n        $response = $this->getJson(\"/user/{$user->id}/comment-slug/{$comment->slug}\");\n        $response->assertJsonFragment(['id' => $comment->id]);\n    }\n\n    public function testImplicitRouteBindingChildHasUlids()\n    {\n        $user = ImplicitBindingUser::create(['name' => 'Michael Nabil']);\n        $post = ImplicitBindingPost::create(['user_id' => $user->id]);\n        $tag = ImplicitBindingTag::create([\n            'slug' => 'slug',\n            'post_id' => $post->id,\n        ]);\n\n        config(['app.key' => str_repeat('a', 32)]);\n\n        $function = function (ImplicitBindingPost $post, ImplicitBindingTag $tag) {\n            return [$post, $tag];\n        };\n\n        Route::middleware(['web'])->group(function () use ($function) {\n            Route::get('/post/{post}/tag/{tag}', $function);\n            Route::get('/post/{post}/tag-id/{tag:id}', $function);\n            Route::get('/post/{post}/tag-slug/{tag:slug}', $function);\n        });\n\n        $response = $this->getJson(\"/post/{$post->id}/tag/{$tag->slug}\");\n        $response->assertJsonFragment(['id' => $tag->id]);\n\n        $response = $this->getJson(\"/post/{$post->id}/tag-id/{$tag->id}\");\n        $response->assertJsonFragment(['id' => $tag->id]);\n\n        $response = $this->getJson(\"/post/{$post->id}/tag-slug/{$tag->slug}\");\n        $response->assertJsonFragment(['id' => $tag->id]);\n    }\n}\n\nclass ImplicitBindingUser extends Model\n{\n    use SoftDeletes;\n\n    public $table = 'users';\n\n    protected $fillable = ['name'];\n\n    public function posts()\n    {\n        return $this->hasMany(ImplicitBindingPost::class, 'user_id');\n    }\n\n    public function comments()\n    {\n        return $this->hasMany(ImplicitBindingComment::class, 'user_id');\n    }\n}\n\nclass ImplicitBindingPost extends Model\n{\n    public $table = 'posts';\n\n    protected $fillable = ['user_id'];\n\n    public function tags()\n    {\n        return $this->hasMany(ImplicitBindingTag::class, 'post_id');\n    }\n}\n\nclass ImplicitBindingTag extends Model\n{\n    use HasUlids;\n\n    public $table = 'tags';\n\n    protected $fillable = ['slug', 'post_id'];\n\n    public function getRouteKeyName()\n    {\n        return 'slug';\n    }\n}\n\nclass ImplicitBindingComment extends Model\n{\n    use HasUuids;\n\n    public $table = 'comments';\n\n    protected $fillable = ['slug', 'user_id'];\n\n    public function getRouteKeyName()\n    {\n        return 'slug';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/MiddlewareAttributeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Routing\\Attributes\\Controllers\\Middleware;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass MiddlewareAttributeTest extends TestCase\n{\n    public function test_attribute_middleware_is_respected(): void\n    {\n        $route = Route::get('/', [MiddlewareAttributeController::class, 'index']);\n        $this->assertEquals([\n            'all',\n            'only-index',\n            'also-index',\n        ], $route->controllerMiddleware());\n\n        $route = Route::get('/', [MiddlewareAttributeController::class, 'show']);\n        $this->assertEquals([\n            'all',\n            'except-index',\n        ], $route->controllerMiddleware());\n    }\n}\n\n#[Middleware('all')]\n#[Middleware('only-index', only: ['index'])]\n#[Middleware('except-index', except: ['index'])]\nclass MiddlewareAttributeController\n{\n    #[Middleware('also-index')]\n    public function index(): void\n    {\n        // ...\n    }\n\n    public function show(): void\n    {\n        // ...\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/PrecognitionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Exception;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Foundation\\Http\\Middleware\\HandlePrecognitiveRequests;\nuse Illuminate\\Foundation\\Validation\\ValidatesRequests;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\CallableDispatcher;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\nuse Illuminate\\Routing\\ControllerDispatcher;\nuse Illuminate\\Session\\Middleware\\StartSession;\nuse Illuminate\\Support\\Facades\\Gate;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Orchestra\\Testbench\\TestCase;\n\nfunction fail()\n{\n    throw new Exception('This code should not be reached.');\n}\n\nclass PrecognitionTest extends TestCase\n{\n    public function testItDoesntInvokeControllerMethodByDefault()\n    {\n        Route::get('test-route', [PrecognitionTestController::class, 'methodThatFails'])\n            ->middleware(HandlePrecognitiveRequests::class);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition-Success', 'true');\n        $this->assertTrue($this->app['ClassWasInstantiated']);\n    }\n\n    public function testItDoesntInvokeCallableControllerByDefault()\n    {\n        $resolved = false;\n        Route::get('test-route', fn (ClassThatBindsOnInstantiation $foo) => fail())\n            ->middleware(HandlePrecognitiveRequests::class);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition-Success', 'true');\n        $this->assertTrue($this->app['ClassWasInstantiated']);\n    }\n\n    public function testItCanCheckPrecognitiveStateOnTheRequest()\n    {\n        Route::get('test-route', fn () => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $this->get('test-route');\n        $this->assertNull(request()->attributes->get('precognitive'));\n        $this->assertFalse(request()->isPrecognitive());\n\n        $this->get('test-route', ['Precognition' => 'true']);\n        $this->assertTrue(request()->attributes->get('precognitive'));\n        $this->assertTrue(request()->isPrecognitive());\n    }\n\n    public function testItReturnsTheEmptyResponseWhenNotBailing()\n    {\n        Route::get('test-route', function () {\n            precognitive(function () {\n                //\n            });\n\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition-Success', 'true');\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Vary', 'Precognition');\n    }\n\n    public function testItCanBailDuringPrecognitionRequest()\n    {\n        Route::get('test-route', function () {\n            precognitive(function ($bail) {\n                $bail(response()->json(['expected' => 'response']));\n                fail();\n            });\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertOk();\n        $response->assertJson(['expected' => 'response']);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanExcludeValidationRulesWhenPrecognitiveWithFormRequest()\n    {\n        Route::post('test-route', fn (PrecognitionTestRequest $request) => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'required_integer' => [\n                'The required integer field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testItRunsExcludedRulesWhenNotPrecognitiveForFormRequest()\n    {\n        Route::post('test-route', fn (PrecognitionTestRequest $request) => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'required_integer' => [\n                'The required integer field must be an integer.',\n            ],\n            'required_integer_when_not_precognitive' => [\n                'The required integer when not precognitive field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyInputToValidate()\n    {\n        Route::post('test-route', fn (PrecognitionTestRequest $request) => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'optional_integer_1' => 'foo',\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyNoInputsToValidate()\n    {\n        Route::post('test-route', fn (PrecognitionTestRequest $request) => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'foo',\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => '',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItAppliesHeadersWhenExceptionThrownInPrecognition()\n    {\n        Route::get('test-route', function () {\n            precognitive(function () {\n                throw new ModelNotFoundException();\n            });\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertNotFound();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Vary', 'Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItAppliesHeadersWhenFlowControlExceptionIsThrown()\n    {\n        // Check with Authorize middleware first...\n        Gate::define('alwaysDeny', fn () => false);\n        Route::get('test-route-before', fn () => fail())\n            ->middleware(['can:alwaysDeny', HandlePrecognitiveRequests::class]);\n\n        $response = $this->get('test-route-before', ['Precognition' => 'true']);\n\n        $response->assertForbidden();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Vary', 'Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n\n        // Check with Authorize middleware last...\n        Route::get('test-route-after', fn () => fail())\n            ->middleware([HandlePrecognitiveRequests::class, 'can:alwaysDeny']);\n\n        $response = $this->get('test-route-after', ['Precognition' => 'true']);\n\n        $response->assertForbidden();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Vary', 'Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanReturnValuesFromPrecognitionClosure()\n    {\n        Route::get('test-route', function () {\n            [$first, $second, $third] = precognitive(function () {\n                return ['expected', 'values', 'passed'];\n            });\n\n            return [\n                'first' => $first,\n                'second' => $second,\n                'third' => $third,\n            ];\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route');\n\n        $response->assertOk();\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertExactJson([\n            'first' => 'expected',\n            'second' => 'values',\n            'third' => 'passed',\n        ]);\n    }\n\n    public function testItCanBailWithResponseDuringNormalRequest()\n    {\n        Route::get('test-route', function () {\n            precognitive(function ($bail) {\n                $bail(response()->json(['expected' => 'response']));\n\n                fail();\n            });\n\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route');\n\n        $response->assertOk();\n        $response->assertJson(['expected' => 'response']);\n        $response->assertHeaderMissing('Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testArbitraryBailResponseIsParsedToResponse()\n    {\n        Route::get('test-route', function () {\n            precognitive(function ($bail) {\n                $bail(['expected' => 'response']);\n\n                fail();\n            });\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route');\n        $response->assertJson(['expected' => 'response']);\n        $response->assertHeaderMissing('Precognition');\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n        $response->assertJson(['expected' => 'response']);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Vary', 'Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testClientCanSpecifyInputsToValidateWhenUsingControllerValidate()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionValidatesViaControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyInputsToValidateWhenUsingControllerValidateWithBag()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionValidatesViaControllerValidateWithBag'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyInputsToValidateWhenUsingRequestValidate()\n    {\n        Route::post('test-route', function (Request $request) {\n            precognitive(function () use ($request) {\n                $request->validate([\n                    'required_integer' => 'required|integer',\n                    ...! $request->isPrecognitive() ? ['required_integer_when_not_precognitive' => 'required|integer'] : [],\n                    'optional_integer_1' => 'integer',\n                    'optional_integer_2' => 'integer',\n                ]);\n\n                fail();\n            });\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyInputsToValidateWhenUsingRequestValidateWithBag()\n    {\n        Route::post('test-route', function (Request $request) {\n            precognitive(function () use ($request) {\n                $request->validateWithBag('custom-bag', [\n                    'required_integer' => 'required|integer',\n                    ! $request->isPrecognitive() ? ['required_integer_when_not_precognitive' => 'required|integer'] : [],\n                    'optional_integer_1' => 'integer',\n                    'optional_integer_2' => 'integer',\n                ]);\n\n                fail();\n            });\n\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testClientCanSpecifyInputsToValidateWhenUsingControllerValidateWithPassingArrayOfRules()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionValidatesViaControllerValidateWith'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            // 'required_integer' => 'foo',\n            'required_integer_when_not_precognitive' => 'foo',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1,optional_integer_2',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'optional_integer_1' => [\n                'The optional integer 1 field must be an integer.',\n            ],\n            'optional_integer_2' => [\n                'The optional integer 2 field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testItCanValidateArrayWithWildcard()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereArrayRulesAreValidateViaControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'raw_array' => [123, 'someString'],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'raw_array.*',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'raw_array.0' => [\n                'The raw_array.0 field must be a string.',\n            ],\n        ]);\n    }\n\n    public function testItCanValidateNestedArrayWithWildcard()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereArrayRulesAreValidateViaControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'nested_array' => [\n                ['name' => 123],\n                ['name' => 'someString'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'nested_array.*.name',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'nested_array.0.name' => [\n                'The nested_array.0.name field must be a string.',\n            ],\n        ]);\n    }\n\n    public function testItCanValidateNestedObjectFieldsWithWildcard()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereProfileIsValidated'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'profile' => ['username' => 123, 'email' => 'invalid'],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'profile.*',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            'profile.username' => ['The profile.username field must be a string.'],\n            'profile.email' => ['The profile.email field must be a valid email address.'],\n        ]);\n    }\n\n    public function testItDoesNotMatchWildcardAgainstOtherRootKeys()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWithMultipleRootKeys'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'user' => ['name' => 123],\n            'email' => 'not-an-email',\n            'name' => 123,\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'user.*',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonMissing(['errors' => ['email' => []]]);\n        $response->assertJsonMissing(['errors' => ['name' => []]]);\n        $response->assertJsonPath('errors', [\n            'user.name' => ['The user.name field must be a string.'],\n        ]);\n    }\n\n    public function testItDoesNotMatchWildcardAcrossSegments()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereUsersAreValidated'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'users' => [\n                ['name' => 123, 'email' => 'invalid'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'users.*',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItCanValidateAllNestedFieldsWithDoubleWildcard()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereUsersAreValidated'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'users' => [\n                ['name' => 123, 'email' => 'invalid'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'users,users.*.*',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertJsonPath('errors', [\n            'users.0.name' => ['The users.0.name field must be a string.'],\n            'users.0.email' => ['The users.0.email field must be a valid email address.'],\n        ]);\n    }\n\n    public function testItCanValidateSpecificIndexWithoutWildcard()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereUsersAreValidated'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'users' => [\n                ['name' => 123, 'email' => 'invalid'],\n                ['name' => 456, 'email' => 'also-invalid'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'users.1.email',\n        ]);\n\n        $response->assertUnprocessable();\n        $response->assertJsonMissing(['errors' => ['users.0.email' => []]]);\n        $response->assertJsonPath('errors', [\n            'users.1.email' => ['The users.1.email field must be a valid email address.'],\n        ]);\n    }\n\n    public function testItAppendsAnAdditionalVaryHeaderInsteadOfReplacingAnyExistingVaryHeaders()\n    {\n        Route::get('test-route', function () {\n            precognitive(function ($bail) {\n                $bail(response('expected')->header('Vary', 'Foo'));\n                fail();\n            });\n            fail();\n        })->middleware([PrecognitionInvokingController::class]);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n\n        $response->assertHeader('Vary', 'Foo, Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testSpacesAreImportantInValidationFilterLogicForJsonRequests()\n    {\n        Route::post('test-route', fn (PrecognitionTestRequest $request) => fail())\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            ' input with spaces ' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => ' input with spaces ',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertHeaderMissing('Precognition-Success');\n        $response->assertJsonPath('errors', [\n            ' input with spaces ' => [\n                'The input with spaces field must be an integer.',\n            ],\n        ]);\n    }\n\n    public function testVaryHeaderIsAppliedToNonPrecognitionResponses()\n    {\n        Route::get('test-route', fn () => 'ok')\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->get('test-route');\n\n        $response->assertOk();\n        $this->assertSame('ok', $response->content());\n        $response->assertHeader('Vary', 'Precognition');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndFormRequest()\n    {\n        Route::post('test-route', function (PrecognitionTestRequest $request, ClassThatBindsOnInstantiation $foo) {\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n        $this->app->instance('ClassWasInstantiated', false);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $this->assertFalse($this->app['ClassWasInstantiated']);\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItStopsExecutionAfterFailedValidationWithNestedValidationFilteringUsingFormRequest()\n    {\n        Route::post('test-route', function (NestedPrecognitionTestRequest $request) {\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'nested' => [\n                ['namsse' => 'sdsd'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'nested,nested.0.name',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The nested.0.name field is required.',\n            'errors' => [\n                'nested' => [\n                    [\n                        'name' => [\n                            'The nested.0.name field is required.',\n                        ],\n                    ],\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterFailedValidationWithNestedValidationFilteringUsingRequestValidate()\n    {\n        Route::post('test-route', function (Request $request) {\n            $request->validate([\n                'nested' => ['required', 'array', 'min:1'],\n                'nested.*.name' => ['required', 'string'],\n            ]);\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'nested' => [\n                ['namsse' => 'sdsd'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'nested,nested.0.name',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The nested.0.name field is required.',\n            'errors' => [\n                'nested' => [\n                    [\n                        'name' => [\n                            'The nested.0.name field is required.',\n                        ],\n                    ],\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterFailedValidationWithNestedValidationFilteringUsingControllerValidate()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereNestedRulesAreValidatedViaControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'nested' => [\n                ['namsse' => 'sdsd'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'nested,nested.0.name',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The nested.0.name field is required.',\n            'errors' => [\n                'nested' => [\n                    [\n                        'name' => [\n                            'The nested.0.name field is required.',\n                        ],\n                    ],\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterFailedValidationWithNestedValidationFilteringUsingControllerValidateWith()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereNestedRulesAreValidatedViaControllerValidateWith'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'nested' => [\n                ['namsse' => 'sdsd'],\n            ],\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'nested,nested.0.name',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The nested.0.name field is required.',\n            'errors' => [\n                'nested' => [\n                    [\n                        'name' => [\n                            'The nested.0.name field is required.',\n                        ],\n                    ],\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanPassValidationForEscapedDotsAfterFilteringWithPrecognition()\n    {\n        Route::post('test-route', function (PrecognitionRequestWithEscapedDots $request) {\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            'escaped.dot' => 'value',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'escaped\\.dot',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItCanFilterRulesWithEscapedDotsUsingFormRequest()\n    {\n        Route::post('test-route', function (PrecognitionRequestWithEscapedDots $request) {\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            //\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'escaped\\.dot',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The escaped.dot field is required.',\n            'errors' => [\n                'escaped.dot' => [\n                    'The escaped.dot field is required.',\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanFilterRulesWithEscapedDotsWhenUsingRequestValidate()\n    {\n        Route::post('test-route', function (Request $request) {\n            $request->validate([\n                'escaped\\.dot' => 'required',\n            ]);\n\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            //\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'escaped\\.dot',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The escaped.dot field is required.',\n            'errors' => [\n                'escaped.dot' => [\n                    'The escaped.dot field is required.',\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanFilterRulesWithEscapedDotsWhenUsingControllerValidate()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereEscapedDotRuleIsValidatedViaControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            //\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'escaped\\.dot',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The escaped.dot field is required.',\n            'errors' => [\n                'escaped.dot' => [\n                    'The escaped.dot field is required.',\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItCanFilterRulesWithEscapedDotsWhenUsingControllerValidateWith()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWhereEscapedDotRuleIsValidatedViaControllerValidateWith'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->postJson('test-route', [\n            //\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'escaped\\.dot',\n        ]);\n\n        $response->assertStatus(422);\n        $response->assertExactJson([\n            'message' => 'The escaped.dot field is required.',\n            'errors' => [\n                'escaped.dot' => [\n                    'The escaped.dot field is required.',\n                ],\n            ],\n        ]);\n        $response->assertHeader('Precognition', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndFormRequest()\n    {\n        Route::post('test-route', function (PrecognitionTestRequest $request, ClassThatBindsOnInstantiation $foo) {\n            precognitive(function ($bail) {\n                $bail(response('expected response'));\n                fail();\n            });\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n        $this->app->instance('ClassWasInstantiated', false);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $this->assertTrue($this->app['ClassWasInstantiated']);\n        $response->assertOk();\n        $this->assertSame('expected response', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndControllerValidate()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndControllerValidate()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidate'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertOk();\n        $this->assertSame('Post-validation code was executed.', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndControllerValidateWithBag()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWithBag'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndControllerValidateWithBag()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWithBag'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertOk();\n        $this->assertSame('Post-validation code was executed.', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndControllerValidateWith()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWith'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndControllerValidateWithXXXX()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWith'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertOk();\n        $this->assertSame('Post-validation code was executed.', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndControllerValidateWithPassingValidator()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWithPassingValidator'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndControllerValidateWithPassingValidator()\n    {\n        Route::post('test-route', [PrecognitionTestController::class, 'methodWherePredictionReturnsResponseWithControllerValidateWithPassingValidator'])\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertOk();\n        $this->assertSame('Post-validation code was executed.', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItStopsExecutionAfterSuccessfulValidationWithValidationFilteringAndRequestValidate()\n    {\n        Route::post('test-route', function (Request $request) {\n            precognitive(function ($bail) use ($request) {\n                $request->validate([\n                    'required_integer' => 'required|integer',\n                    'optional_integer_1' => 'integer',\n                    'optional_integer_2' => 'integer',\n                ]);\n\n                $bail(response('Post-validation code was executed.'));\n\n                fail();\n            });\n\n            fail();\n        })\n            ->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'optional_integer_1' => 1,\n            'optional_integer_2' => 'foo',\n        ], [\n            'Precognition' => 'true',\n            'Precognition-Validate-Only' => 'optional_integer_1',\n        ]);\n\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeader('Precognition-Success', 'true');\n    }\n\n    public function testItContinuesExecutionAfterSuccessfulValidationWithoutValidationFilteringAndRequestValidate()\n    {\n        Route::post('test-route', function (Request $request) {\n            precognitive(function ($bail) use ($request) {\n                $request->validate([\n                    'required_integer' => 'required|integer',\n                    'optional_integer_1' => 'integer',\n                    'optional_integer_2' => 'integer',\n                ]);\n\n                $bail(response('Post-validation code was executed.'));\n\n                fail();\n            });\n\n            fail();\n        })->middleware(PrecognitionInvokingController::class);\n\n        $response = $this->post('test-route', [\n            'required_integer' => 1,\n        ], [\n            'Precognition' => 'true',\n        ]);\n\n        $response->assertOk();\n        $this->assertSame('Post-validation code was executed.', $response->content());\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItDoesNotSetLastUrl()\n    {\n        Route::get('expected-route-1', fn () => 'ok')->middleware(StartSession::class);\n        Route::get('expected-route-2', fn () => 'ok')->middleware(StartSession::class);\n        Route::get('precognition-route', fn () => 'ok')->middleware([StartSession::class, HandlePrecognitiveRequests::class]);\n\n        $this->app->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $response = $this->get('expected-route-1');\n        $response->assertOk();\n        $this->assertSame('http://localhost/expected-route-1', session()->previousUrl());\n\n        $this->app->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $response = $this->get('precognition-route', ['Precognition' => 'true']);\n        $response->assertNoContent();\n        $this->assertSame('http://localhost/expected-route-1', session()->previousUrl());\n\n        $this->app->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $response = $this->get('expected-route-2');\n        $response->assertOk();\n        $this->assertSame('http://localhost/expected-route-2', session()->previousUrl());\n    }\n\n    public function testItAppendsVaryHeaderToSymfonyResponse()\n    {\n        Route::get('test-route', function () {\n            return response()->streamDownload(function () {\n                echo 'foo';\n            }, null, ['Expected' => 'Header']);\n        })->middleware(HandlePrecognitiveRequests::class);\n\n        $response = $this->get('test-route');\n        $response->assertOk();\n        $response->assertHeader('Expected', 'Header');\n        $response->assertHeaderMissing('Precognition-Success');\n    }\n\n    public function testItAppendsPrecognitionHeaderToSymfonyResponse()\n    {\n        Route::get('test-route', function () {\n            //\n        })->middleware([\n            HandlePrecognitiveRequests::class,\n            MiddlewareReturningSymfonyResponse::class,\n        ]);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n        $response->assertOk();\n        $response->assertHeader('Expected', 'Header');\n        $response->assertHeader('Precognition', 'true');\n    }\n\n    public function testItCanNoContentWhileAlsoNotBeingPrecognitive()\n    {\n        Route::get('test-route', function () {\n            //\n        })->middleware([HandlePrecognitiveRequests::class, MiddlewareThatReturnsNoContent::class]);\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n        $response->assertNoContent();\n        $response->assertHeader('Precognition', 'true');\n        $response->assertHeaderMissing('Precognition-Success', 'true');\n    }\n\n    public function testItRestoresOriginalDispatcherBindingsAfterPrecognitiveRequest()\n    {\n        Route::get('test-route', fn () => 'ok')\n            ->middleware(HandlePrecognitiveRequests::class);\n\n        $callableBinding = $this->app->getBindings()[CallableDispatcherContract::class] ?? null;\n        $controllerBinding = $this->app->getBindings()[ControllerDispatcherContract::class] ?? null;\n\n        $response = $this->get('test-route', ['Precognition' => 'true']);\n        $response->assertNoContent();\n\n        $this->assertInstanceOf(CallableDispatcher::class, $this->app->make(CallableDispatcherContract::class));\n        $this->assertInstanceOf(ControllerDispatcher::class, $this->app->make(ControllerDispatcherContract::class));\n\n        $this->assertSame(\n            $callableBinding['shared'] ?? null,\n            $this->app->getBindings()[CallableDispatcherContract::class]['shared'] ?? null\n        );\n        $this->assertSame(\n            $controllerBinding['shared'] ?? null,\n            $this->app->getBindings()[ControllerDispatcherContract::class]['shared'] ?? null\n        );\n    }\n}\n\nclass PrecognitionTestController\n{\n    use ValidatesRequests;\n\n    public function methodWhereEscapedDotRuleIsValidatedViaControllerValidate(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'escaped\\.dot' => 'required',\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereEscapedDotRuleIsValidatedViaControllerValidateWith()\n    {\n        precognitive(function () {\n            $this->validateWith([\n                'escaped\\.dot' => 'required',\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereNestedRulesAreValidatedViaControllerValidate(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'nested' => ['required', 'array', 'min:1'],\n                'nested.*.name' => ['required', 'string'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereArrayRulesAreValidateViaControllerValidate(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'nested_array' => ['required', 'array', 'min:1'],\n                'nested_array.*.name' => ['required', 'string'],\n                'raw_array' => ['required', 'array', 'min:1'],\n                'raw_array.*' => ['required', 'string'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereUsersAreValidated(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'users' => ['required', 'array'],\n                'users.*.name' => ['required', 'string'],\n                'users.*.email' => ['required', 'email'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWithMultipleRootKeys(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'user' => ['required', 'array'],\n                'user.name' => ['required', 'string'],\n                'email' => ['required', 'email'],\n                'name' => ['required', 'string'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereProfileIsValidated(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'profile' => ['required', 'array'],\n                'profile.username' => ['required', 'string'],\n                'profile.email' => ['required', 'email'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWhereNestedRulesAreValidatedViaControllerValidateWith(Request $request)\n    {\n        precognitive(function () {\n            $this->validateWith([\n                'nested' => ['required', 'array', 'min:1'],\n                'nested.*.name' => ['required', 'string'],\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionValidatesViaControllerValidate(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validate($request, [\n                'required_integer' => 'required|integer',\n                ...! $request->isPrecognitive() ? ['required_integer_when_not_precognitive' => 'required|integer'] : [],\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionValidatesViaControllerValidateWithBag(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validateWithBag('custom-bag', $request, [\n                'required_integer' => 'required|integer',\n                ...! $request->isPrecognitive() ? ['required_integer_when_not_precognitive' => 'required|integer'] : [],\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionValidatesViaControllerValidateWith(Request $request)\n    {\n        precognitive(function () use ($request) {\n            $this->validateWith([\n                'required_integer' => 'required|integer',\n                ...! $request->isPrecognitive() ? ['required_integer_when_not_precognitive' => 'required|integer'] : [],\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionReturnsResponseWithControllerValidate(Request $request)\n    {\n        precognitive(function ($bail) use ($request) {\n            $this->validate($request, [\n                'required_integer' => 'required|integer',\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            $bail(response('Post-validation code was executed.'));\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionReturnsResponseWithControllerValidateWithBag(Request $request)\n    {\n        precognitive(function ($bail) use ($request) {\n            $this->validateWithBag('custom-bag', $request, [\n                'required_integer' => 'required|integer',\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            $bail(response('Post-validation code was executed.'));\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionReturnsResponseWithControllerValidateWith(Request $request)\n    {\n        precognitive(function ($bail) {\n            $this->validateWith([\n                'required_integer' => 'required|integer',\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]);\n\n            $bail(response('Post-validation code was executed.'));\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodWherePredictionReturnsResponseWithControllerValidateWithPassingValidator(Request $request)\n    {\n        precognitive(function ($bail) use ($request) {\n            $this->validateWith(Validator::make($request->all(), [\n                'required_integer' => 'required|integer',\n                'optional_integer_1' => 'integer',\n                'optional_integer_2' => 'integer',\n            ]));\n\n            $bail(response('Post-validation code was executed.'));\n\n            fail();\n        });\n\n        fail();\n    }\n\n    public function methodThatFails(ClassThatBindsOnInstantiation $foo)\n    {\n        fail();\n    }\n}\n\nclass PrecognitionTestRequest extends FormRequest\n{\n    public function rules()\n    {\n        $rules = [\n            'required_integer' => 'required|integer',\n            'optional_integer_1' => 'integer',\n            'optional_integer_2' => 'integer',\n            ' input with spaces ' => 'integer',\n        ];\n\n        if (! $this->isPrecognitive()) {\n            $rules['required_integer_when_not_precognitive'] = 'required|integer';\n        }\n\n        return $rules;\n    }\n}\n\nclass NestedPrecognitionTestRequest extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'nested' => ['required', 'array', 'min:1'],\n            'nested.*.name' => ['required', 'string'],\n        ];\n    }\n}\n\nclass PrecognitionRequestWithEscapedDots extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'escaped\\.dot' => ['required'],\n        ];\n    }\n}\n\nclass ClassThatBindsOnInstantiation\n{\n    public function __construct()\n    {\n        app()->instance('ClassWasInstantiated', true);\n    }\n}\n\nclass PrecognitionInvokingController extends HandlePrecognitiveRequests\n{\n    protected function prepareForPrecognition($request)\n    {\n        parent::prepareForPrecognition($request);\n\n        app()->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n        app()->bind(ControllerDispatcherContract::class, fn ($app) => new ControllerDispatcher($app));\n    }\n}\n\nclass MiddlewareReturningSymfonyResponse\n{\n    public function handle($request, $next)\n    {\n        return response()->streamDownload(function () {\n            //\n        }, null, ['Expected' => 'Header']);\n    }\n}\n\nclass MiddlewareThatReturnsNoContent\n{\n    public function handle()\n    {\n        return response()->noContent();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/PreviousUrlTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse Illuminate\\Session\\SessionServiceProvider;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass PreviousUrlTest extends TestCase\n{\n    public function testPreviousUrlWithoutSession()\n    {\n        Route::post('/previous-url', function (DummyFormRequest $request) {\n            return 'OK';\n        });\n\n        $response = $this->postJson('/previous-url');\n\n        $this->assertEquals(422, $response->status());\n    }\n\n    protected function getApplicationProviders($app)\n    {\n        $providers = parent::getApplicationProviders($app);\n\n        return array_filter($providers, function ($provider) {\n            return $provider !== SessionServiceProvider::class;\n        });\n    }\n}\n\nclass DummyFormRequest extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'foo' => [\n                'required',\n                'string',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/ResponsableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ResponsableTest extends TestCase\n{\n    public function testResponsableObjectsAreRendered()\n    {\n        Route::get('/responsable', function () {\n            return new TestResponsableResponse;\n        });\n\n        $response = $this->get('/responsable');\n\n        $this->assertEquals(201, $response->status());\n        $this->assertSame('Taylor', $response->headers->get('X-Test-Header'));\n        $this->assertSame('hello world', $response->getContent());\n    }\n}\n\nclass TestResponsableResponse implements Responsable\n{\n    public function toResponse($request)\n    {\n        return response('hello world', 201, ['X-Test-Header' => 'Taylor']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteApiResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Tests\\Integration\\Routing\\Fixtures\\ApiResourceTaskController;\nuse Illuminate\\Tests\\Integration\\Routing\\Fixtures\\ApiResourceTestController;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RouteApiResourceTest extends TestCase\n{\n    public function testApiResource()\n    {\n        Route::apiResource('tests', ApiResourceTestController::class);\n\n        $response = $this->get('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m index', $response->getContent());\n\n        $response = $this->post('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m store', $response->getContent());\n\n        $response = $this->get('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m show', $response->getContent());\n\n        $response = $this->put('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update', $response->getContent());\n        $response = $this->patch('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update', $response->getContent());\n\n        $response = $this->delete('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m destroy', $response->getContent());\n    }\n\n    public function testApiResourceWithOnly()\n    {\n        Route::apiResource('tests', ApiResourceTestController::class)->only(['index', 'store']);\n\n        $response = $this->get('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m index', $response->getContent());\n\n        $response = $this->post('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m store', $response->getContent());\n\n        $this->assertEquals(404, $this->get('/tests/1')->getStatusCode());\n        $this->assertEquals(404, $this->put('/tests/1')->getStatusCode());\n        $this->assertEquals(404, $this->patch('/tests/1')->getStatusCode());\n        $this->assertEquals(404, $this->delete('/tests/1')->getStatusCode());\n    }\n\n    public function testApiResources()\n    {\n        Route::apiResources([\n            'tests' => ApiResourceTestController::class,\n            'tasks' => ApiResourceTaskController::class,\n        ]);\n\n        $response = $this->get('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m index', $response->getContent());\n\n        $response = $this->post('/tests');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m store', $response->getContent());\n\n        $response = $this->get('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m show', $response->getContent());\n\n        $response = $this->put('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update', $response->getContent());\n        $response = $this->patch('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update', $response->getContent());\n\n        $response = $this->delete('/tests/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m destroy', $response->getContent());\n\n        /////////////////////\n        $response = $this->get('/tasks');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m index tasks', $response->getContent());\n\n        $response = $this->post('/tasks');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m store tasks', $response->getContent());\n\n        $response = $this->get('/tasks/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m show tasks', $response->getContent());\n\n        $response = $this->put('/tasks/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update tasks', $response->getContent());\n        $response = $this->patch('/tasks/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m update tasks', $response->getContent());\n\n        $response = $this->delete('/tasks/1');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('I`m destroy tasks', $response->getContent());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteCachingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Orchestra\\Testbench\\TestCase;\n\nclass RouteCachingTest extends TestCase\n{\n    public function testWildcardCatchAllRoutes()\n    {\n        $this->routes(__DIR__.'/Fixtures/wildcard_catch_all_routes.php');\n\n        $this->get('/foo')->assertSee('Regular route');\n        $this->get('/bar')->assertSee('Wildcard route');\n    }\n\n    public function testRedirectRoutes()\n    {\n        $this->routes(__DIR__.'/Fixtures/redirect_routes.php');\n\n        $this->post('/foo/1')->assertRedirect('/foo/1/bar');\n        $this->get('/foo/1/bar')->assertSee('Redirect response');\n        $this->get('/foo/1')->assertRedirect('/foo/1/bar');\n    }\n\n    protected function routes(string $file)\n    {\n        $this->defineCacheRoutes(file_get_contents($file));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteCanBackedEnumTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Gate;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\nuse User;\n\nclass RouteCanBackedEnumTest extends TestCase\n{\n    public function testSimpleRouteWithStringBackedEnumCanAbilityGuestForbiddenThroughTheFramework()\n    {\n        $gate = Gate::define(AbilityBackedEnum::NotAccessRoute, fn (?User $user) => false);\n        $this->assertArrayHasKey('not-access-route', $gate->abilities());\n\n        $route = Route::get('/', function () {\n            return 'Hello World';\n        })->can(AbilityBackedEnum::NotAccessRoute);\n        $this->assertEquals(['can:not-access-route'], $route->middleware());\n\n        $response = $this->get('/');\n        $response->assertForbidden();\n    }\n\n    public function testSimpleRouteWithStringBackedEnumCanAbilityGuestAllowedThroughTheFramework()\n    {\n        $gate = Gate::define(AbilityBackedEnum::AccessRoute, fn (?User $user) => true);\n        $this->assertArrayHasKey('access-route', $gate->abilities());\n\n        $route = Route::get('/', function () {\n            return 'Hello World';\n        })->can(AbilityBackedEnum::AccessRoute);\n        $this->assertEquals(['can:access-route'], $route->middleware());\n\n        $response = $this->get('/');\n        $response->assertOk();\n        $response->assertContent('Hello World');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteNameEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nenum RouteNameEnum: string\n{\n    case UserIndex = 'users.index';\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteRedirectTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Routing\\Middleware\\SubstituteBindings;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass RouteRedirectTest extends TestCase\n{\n    #[DataProvider('routeRedirectDataSets')]\n    public function testRouteRedirect($redirectFrom, $redirectTo, $requestUri, $redirectUri)\n    {\n        $this->withoutExceptionHandling();\n        Route::redirect($redirectFrom, $redirectTo, 301);\n\n        $response = $this->get($requestUri);\n        $response->assertRedirect($redirectUri);\n        $response->assertStatus(301);\n    }\n\n    public static function routeRedirectDataSets()\n    {\n        return [\n            'route redirect with no parameters' => ['from', 'to', '/from', '/to'],\n            'route redirect with one parameter' => ['from/{param}/{param2?}', 'to', '/from/value1', '/to'],\n            'route redirect with two parameters' => ['from/{param}/{param2?}', 'to', '/from/value1/value2', '/to'],\n            'route redirect with one parameter replacement' => ['users/{user}/repos', 'members/{user}/repos', '/users/22/repos', '/members/22/repos'],\n            'route redirect with two parameter replacements' => ['users/{user}/repos/{repo}', 'members/{user}/projects/{repo}', '/users/22/repos/laravel-framework', '/members/22/projects/laravel-framework'],\n            'route redirect with non existent optional parameter replacements' => ['users/{user?}', 'members/{user?}', '/users', '/members'],\n            'route redirect with existing parameter replacements' => ['users/{user?}', 'members/{user?}', '/users/22', '/members/22'],\n            'route redirect with two optional replacements' => ['users/{user?}/{repo?}', 'members/{user?}', '/users/22', '/members/22'],\n            'route redirect with two optional replacements that switch position' => ['users/{user?}/{switch?}', 'members/{switch?}/{user?}', '/users/11/22', '/members/22/11'],\n        ];\n    }\n\n    public function testRouteRedirectWithExplicitRouteModelBinding()\n    {\n        $this->withoutExceptionHandling();\n        Route::middleware([SubstituteBindings::class])->group(function () {\n            Route::redirect('users/{user}', 'users/{user}/overview');\n        });\n        Route::bind('user', fn ($id) => (new User())->setAttribute('id', '999'));\n\n        $response = $this->get('users/1');\n\n        $response->assertRedirect('users/999/overview');\n    }\n\n    public function testToActionHelper()\n    {\n        Route::get('to', [ApiResourceTestController::class, 'index']);\n\n        Route::get('from-301', function () {\n            return to_action([ApiResourceTestController::class, 'index'], [], 301);\n        });\n\n        Route::get('from-302', function () {\n            return to_action([ApiResourceTestController::class, 'index']);\n        });\n\n        $this->get('from-301')\n            ->assertRedirect('to')\n            ->assertStatus(301)\n            ->assertSee('Redirecting to');\n\n        $this->get('from-302')\n            ->assertRedirect('to')\n            ->assertStatus(302)\n            ->assertSee('Redirecting to');\n    }\n\n    public function testToRouteHelper()\n    {\n        Route::get('to', function () {\n            // ..\n        })->name('to');\n\n        Route::get('from-301', function () {\n            return to_route('to', [], 301);\n        });\n\n        Route::get('from-302', function () {\n            return to_route('to');\n        });\n\n        $this->get('from-301')\n            ->assertRedirect('to')\n            ->assertStatus(301)\n            ->assertSee('Redirecting to');\n\n        $this->get('from-302')\n            ->assertRedirect('to')\n            ->assertStatus(302)\n            ->assertSee('Redirecting to');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteSingletonTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Tests\\Integration\\Routing\\Fixtures\\CreatableSingletonTestController;\nuse Illuminate\\Tests\\Integration\\Routing\\Fixtures\\NestedSingletonTestController;\nuse Illuminate\\Tests\\Integration\\Routing\\Fixtures\\SingletonTestController;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RouteSingletonTest extends TestCase\n{\n    public function testSingletonDefaults()\n    {\n        Route::singleton('avatar', SingletonTestController::class);\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.show'));\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar/edit', route('avatar.edit'));\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.update'));\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        // $this->assertSame('http://localhost/avatar', route('avatar.destroy'));\n        // $response = $this->delete('/avatar');\n        // $this->assertEquals(404, $response->getStatusCode());\n        // $this->assertSame('singleton destroy', $response->getContent());\n    }\n\n    public function testCreatableSingleton()\n    {\n        Route::singleton('avatar', CreatableSingletonTestController::class)->creatable();\n\n        $this->assertSame('http://localhost/avatar/create', route('avatar.create'));\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton create', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.store'));\n        $response = $this->post('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton store', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.destroy'));\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton destroy', $response->getContent());\n    }\n\n    public function testCreatableSingletonOnly()\n    {\n        Route::singleton('avatar', CreatableSingletonTestController::class)->creatable()->only('show');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testCreatableSingletonExcept()\n    {\n        Route::singleton('avatar', CreatableSingletonTestController::class)->creatable()->except('show');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n\n    public function testDestroyableSingleton()\n    {\n        Route::singleton('avatar', CreatableSingletonTestController::class)->destroyable();\n\n        $this->assertSame('http://localhost/avatar', route('avatar.show'));\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar/edit', route('avatar.edit'));\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.update'));\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.destroy'));\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton destroy', $response->getContent());\n    }\n\n    public function testDestroyableSingletonOnly()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->destroyable()->only('destroy');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n\n    public function testDestroyableSingletonExcept()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->destroyable()->except('destroy');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testCreatableDestroyableSingletonOnlyExceptTest()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->creatable()->destroyable()->only(['show'])->except(['destroy']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testApiSingleton()\n    {\n        Route::apiSingleton('avatar', SingletonTestController::class);\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.update'));\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n    }\n\n    public function testCreatableApiSingleton()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->creatable();\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.store'));\n        $response = $this->post('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton store', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.update'));\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n    }\n\n    public function testCreatableApiSingletonOnly()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->creatable()->only(['create', 'store']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testCreatableApiSingletonExcept()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->creatable()->except(['create', 'store']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n\n    public function testDestroyableApiSingleton()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->destroyable();\n\n        $this->assertSame('http://localhost/avatar', route('avatar.show'));\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.update'));\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        $this->assertSame('http://localhost/avatar', route('avatar.destroy'));\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton destroy', $response->getContent());\n    }\n\n    public function testDestroyableApiSingletonOnly()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->destroyable()->only(['destroy']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n\n    public function testDestroyableApiSingletonExcept()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->destroyable()->except(['destroy', 'show']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testCreatableDestroyableApiSingletonOnlyExceptTest()\n    {\n        Route::apiSingleton('avatar', CreatableSingletonTestController::class)->creatable()->destroyable()->only(['show'])->except(['destroy']);\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/create');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->post('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testSingletonOnly()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->only('show');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(404, $response->getStatusCode());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->delete('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testSingletonExcept()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->except('show');\n\n        $response = $this->get('/avatar');\n        $this->assertEquals(405, $response->getStatusCode());\n\n        $response = $this->get('/avatar/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit', $response->getContent());\n\n        $response = $this->put('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        $response = $this->patch('/avatar');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update', $response->getContent());\n\n        // $response = $this->delete('/avatar');\n        // $this->assertEquals(200, $response->getStatusCode());\n        // $this->assertSame('singleton destroy', $response->getContent());\n    }\n\n    public function testSingletonName()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->name('show', 'foo.show');\n\n        $this->assertSame('http://localhost/avatar', route('foo.show'));\n    }\n\n    public function testSingletonNames()\n    {\n        Route::singleton('avatar', SingletonTestController::class)->names(['show' => 'foo.show']);\n\n        $this->assertSame('http://localhost/avatar', route('foo.show'));\n    }\n\n    public function testNestedSingleton()\n    {\n        Route::singleton('videos.thumbnail', NestedSingletonTestController::class);\n\n        $response = $this->get('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show for 123', $response->getContent());\n\n        $response = $this->get('/videos/123/thumbnail/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit for 123', $response->getContent());\n\n        $response = $this->put('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->patch('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->delete('/videos/123/thumbnail');\n        $this->assertEquals(405, $response->getStatusCode());\n    }\n\n    public function testCreatableNestedSingleton()\n    {\n        Route::singleton('videos.thumbnail', NestedSingletonTestController::class)->creatable();\n\n        $response = $this->get('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show for 123', $response->getContent());\n\n        $response = $this->get('/videos/123/thumbnail/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit for 123', $response->getContent());\n\n        $response = $this->put('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->patch('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->delete('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton destroy for 123', $response->getContent());\n    }\n\n    public function testDestroyableNestedSingleton()\n    {\n        Route::singleton('videos.thumbnail', NestedSingletonTestController::class)->destroyable();\n\n        $response = $this->get('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show for 123', $response->getContent());\n\n        $response = $this->get('/videos/123/thumbnail/edit');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton edit for 123', $response->getContent());\n\n        $response = $this->put('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->patch('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton update for 123', $response->getContent());\n\n        $response = $this->delete('/videos/123/thumbnail');\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton destroy for 123', $response->getContent());\n    }\n\n    public function testNestedSingletonParameter()\n    {\n        Route::singleton('v.thumbnail', NestedSingletonTestController::class)->parameter('v', 'video');\n\n        $response = $this->get('/v/123/thumbnail');\n\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show for 123', $response->getContent());\n    }\n\n    public function testNestedSingletonParameters()\n    {\n        Route::singleton('v.thumbnail', NestedSingletonTestController::class)->parameters(['v' => 'video']);\n\n        $response = $this->get('/v/123/thumbnail');\n\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('singleton show for 123', $response->getContent());\n    }\n\n    public function testNestedSingletonWhere()\n    {\n        Route::singleton('videos.thumbnail', NestedSingletonTestController::class)->where(['video' => '[a-z]+']);\n\n        $response = $this->get('/videos/123/thumbnail');\n\n        $this->assertEquals(404, $response->getStatusCode());\n    }\n\n    public function testPrefixedSingleton()\n    {\n        Route::singleton('/user/avatar', SingletonTestController::class);\n\n        $response = $this->get('/user/avatar');\n\n        $this->assertEquals(200, $response->getStatusCode());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RouteViewTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\View;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RouteViewTest extends TestCase\n{\n    public function testRouteView()\n    {\n        Route::view('route', 'view', ['foo' => 'bar']);\n\n        View::addLocation(__DIR__.'/Fixtures');\n\n        $this->assertStringContainsString('Test bar', $this->get('/route')->getContent());\n        $this->assertSame(200, $this->get('/route')->status());\n    }\n\n    public function testRouteViewWithParams()\n    {\n        Route::view('route/{param}/{param2?}', 'view', ['foo' => 'bar']);\n\n        View::addLocation(__DIR__.'/Fixtures');\n\n        $this->assertStringContainsString('Test bar', $this->get('/route/value1/value2')->getContent());\n        $this->assertStringContainsString('Test bar', $this->get('/route/value1')->getContent());\n\n        tap($this->get('/route/value1/value2'), function ($response) {\n            $this->assertEquals('value1', $response->viewData('param'));\n            $this->assertEquals('value1', $response->baseRequest->route('param'));\n            $this->assertEquals('value2', $response->baseRequest->route('param2'));\n        });\n\n        tap($this->get('/route/value1/value2'), function ($response) {\n            $this->assertEquals('value2', $response->viewData('param2'));\n            $this->assertEquals('value1', $response->baseRequest->route('param'));\n            $this->assertEquals('value2', $response->baseRequest->route('param2'));\n        });\n    }\n\n    public function testRouteViewWithStatus()\n    {\n        Route::view('route', 'view', ['foo' => 'bar'], 418);\n\n        View::addLocation(__DIR__.'/Fixtures');\n\n        $this->assertSame(418, $this->get('/route')->status());\n    }\n\n    public function testRouteViewWithHeaders()\n    {\n        Route::view('route', 'view', ['foo' => 'bar'], 418, ['Framework' => 'Laravel']);\n\n        View::addLocation(__DIR__.'/Fixtures');\n\n        $this->assertSame('Laravel', $this->get('/route')->headers->get('Framework'));\n    }\n\n    public function testRouteViewOverloadingStatusWithHeaders()\n    {\n        Route::view('route', 'view', ['foo' => 'bar'], ['Framework' => 'Laravel']);\n\n        View::addLocation(__DIR__.'/Fixtures');\n\n        $this->assertSame('Laravel', $this->get('/route')->headers->get('Framework'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/RoutingServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Orchestra\\Testbench\\TestCase;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse Psr\\Http\\Message\\ServerRequestInterface;\n\nclass RoutingServiceProviderTest extends TestCase\n{\n    public function testResolvingPsrRequest()\n    {\n        $psrRequest = $this->app->make(ServerRequestInterface::class);\n\n        $this->assertInstanceOf(ServerRequestInterface::class, $psrRequest);\n    }\n\n    public function testResolvingPsrResponse()\n    {\n        $psrResponse = $this->app->make(ResponseInterface::class);\n\n        $this->assertInstanceOf(ResponseInterface::class, $psrResponse);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/SerializableClosureV1CacheRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Route;\n\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystemFamily;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\n#[RequiresOperatingSystemFamily('Linux|Darwin')]\n#[WithConfig('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF')]\n#[WithMigration]\nclass SerializableClosureV1CacheRouteTest extends TestCase\n{\n    use RefreshDatabase;\n\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function getPackageProviders($app)\n    {\n        return [\n            \\Illuminate\\Foundation\\Support\\Providers\\RouteServiceProvider::class,\n        ];\n    }\n\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function setUp(): void\n    {\n        $_ENV['APP_ROUTES_CACHE'] = realpath(join_paths(__DIR__, 'stubs', 'serializable-closure-v1', 'routes-v7.php'));\n\n        parent::setUp();\n    }\n\n    /** {@inheritDoc} */\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        unset($_ENV['APP_ROUTES_CACHE']);\n    }\n\n    public function testItCanUseCachedRouteFromSerializableClosureV1()\n    {\n        $user = UserFactory::new()->create();\n\n        $this->assertTrue($this->app->routesAreCached());\n\n        $this->get('/')->assertSee('Laravel');\n\n        $this->get(\"/users/{$user->getKey()}\")\n            ->assertJson($user->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/SimpleRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SimpleRouteTest extends TestCase\n{\n    public function testSimpleRouteThroughTheFramework()\n    {\n        Route::get('/', function () {\n            return 'Hello World';\n        });\n\n        $response = $this->get('/');\n\n        $this->assertSame('Hello World', $response->content());\n\n        $response = $this->get('/?foo=bar');\n\n        $this->assertSame('Hello World', $response->content());\n\n        $this->assertSame('bar', $response->baseRequest->query('foo'));\n    }\n\n    public function testSimpleRouteWitStringBackedEnumRouteNameThroughTheFramework()\n    {\n        Route::get('/', function () {\n            return 'Hello World';\n        })->name(RouteNameEnum::UserIndex);\n\n        $response = $this->get(\\route(RouteNameEnum::UserIndex, ['foo' => 'bar']));\n\n        $this->assertSame('Hello World', $response->content());\n\n        $this->assertSame('bar', $response->baseRequest->query('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Routing/UrlSigningTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Routing;\n\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Exceptions\\InvalidSignatureException;\nuse Illuminate\\Routing\\Middleware\\ValidateSignature;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\URL;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass UrlSigningTest extends TestCase\n{\n    protected function defineEnvironment($app): void\n    {\n        $app['config']->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']);\n    }\n\n    public function testSigningUrl()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1]));\n\n        tap($this->get($url), function ($response) {\n            $this->assertSame('valid', $response->original);\n\n            $this->assertIsString($response->baseRequest->query('signature'));\n        });\n    }\n\n    public function testSigningUrlWithCustomRouteSlug()\n    {\n        Route::get('/foo/{post:slug}', function (Request $request, $slug) {\n            return ['slug' => $slug, 'valid' => $request->hasValidSignature() ? 'valid' : 'invalid'];\n        })->name('foo');\n\n        $model = new RoutableInterfaceStub;\n        $model->routable = 'routable-slug';\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['post' => $model]));\n\n        tap($this->get($url), function ($response) {\n            $this->assertSame('valid', $response->original['valid']);\n            $this->assertSame('routable-slug', $response->original['slug']);\n\n            $this->assertSame('routable-slug', $response->baseRequest->route('post'));\n        });\n    }\n\n    public function testTemporarySignedUrls()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1));\n        $this->assertIsString($url = URL::temporarySignedRoute('foo', Carbon::now()->addMinutes(5), ['id' => 1]));\n        $this->assertSame('valid', $this->get($url)->original);\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1)->addMinutes(10));\n        $this->assertSame('invalid', $this->get($url)->original);\n    }\n\n    public function testTemporarySignedUrlsWithExpiresParameter()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('reserved');\n\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        URL::temporarySignedRoute('foo', Carbon::now()->addMinutes(5), ['id' => 1, 'expires' => 253402300799]);\n    }\n\n    public function testSignedUrlWithUrlWithoutSignatureParameter()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertSame('invalid', $this->get('/foo/1')->original);\n    }\n\n    public function testSignedUrlWithNullParameter()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1, 'param']));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testSignedUrlWithEmptyStringParameter()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1, 'param' => '']));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testSignedUrlWithMultipleParameters()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1, 'param1' => 'value1', 'param2' => 'value2']));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testSignedUrlWithSignatureTextInKeyOrValue()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1, 'custom-signature' => 'signature=value']));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testSignedUrlWithAppendedNullParameterInvalid()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1]));\n        $this->assertSame('invalid', $this->get($url.'&appended')->original);\n    }\n\n    public function testSignedUrlParametersParsedCorrectly()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature()\n                && (int) $id === 1\n                && $request->has('paramEmpty')\n                && $request->has('paramEmptyString')\n                && $request->query('paramWithValue') === 'value'\n                ? 'valid'\n                : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1,\n            'paramEmpty',\n            'paramEmptyString' => '',\n            'paramWithValue' => 'value',\n        ]));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testExceptedParametersCanBeAddedInAnyOrder()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignatureWhileIgnoring(['one', 'two', 'three']) ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1,\n            'bar' => 'baz',\n        ]));\n\n        $this->assertSame('valid', $this->get($url.'&one=value&two=another-value')->original);\n        $this->assertSame('valid', $this->get($url.'&two=value&one=&three')->original);\n    }\n\n    public function testUnusualExceptedParametersWorksAsExpected()\n    {\n        $this->withoutExceptionHandling();\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignatureWhileIgnoring(['']) ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1,\n            'bar' => 'baz',\n        ]));\n\n        $this->assertSame('valid', $this->get($url)->original);\n\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignatureWhileIgnoring(['*', '[a-z]+']) ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1,\n            'bar' => 'baz',\n        ]));\n\n        $this->assertSame('valid', $this->get($url.'&*=value&[a-z]+=value')->original);\n    }\n\n    public function testExceptedParameterCanBeAPrefixOrSuffixOfAnotherParameter()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignatureWhileIgnoring(['pre', 'fix']) ? 'valid' : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1,\n            'prefix' => 'value',\n            'suffix' => 'value',\n        ]));\n\n        $this->assertSame('valid', $this->get($url.'&pre=fix&fix=suff')->original);\n    }\n\n    public function testSignedMiddleware()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo')->middleware(ValidateSignature::class);\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1));\n        $this->assertIsString($url = URL::temporarySignedRoute('foo', Carbon::now()->addMinutes(5), ['id' => 1]));\n        $this->assertSame('valid', $this->get($url)->original);\n    }\n\n    public function testSignedMiddlewareWithInvalidUrl()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo')->middleware(ValidateSignature::class);\n\n        Carbon::setTestNow(Carbon::create(2018, 1, 1));\n        $this->assertIsString($url = URL::temporarySignedRoute('foo', Carbon::now()->addMinutes(5), ['id' => 1]));\n        Carbon::setTestNow(Carbon::create(2018, 1, 1)->addMinutes(10));\n\n        $response = $this->get($url);\n        $response->assertStatus(403);\n    }\n\n    public function testSignedMiddlewareWithRoutableParameter()\n    {\n        $model = new RoutableInterfaceStub;\n        $model->routable = 'routable';\n\n        Route::get('/foo/{bar}', function (Request $request, $routable) {\n            return $request->hasValidSignature() ? $routable : 'invalid';\n        })->name('foo');\n\n        $this->assertIsString($url = URL::signedRoute('foo', $model));\n        $this->assertSame('routable', $this->get($url)->original);\n    }\n\n    public function testSignedMiddlewareWithRelativePath()\n    {\n        Route::get('/foo/relative', function (Request $request) {\n            return $request->hasValidSignature($absolute = false) ? 'valid' : 'invalid';\n        })->name('foo')->middleware('signed:relative');\n\n        $this->assertIsString($url = 'https://fake.test'.URL::signedRoute('foo', [], null, $absolute = false));\n        $this->assertSame('valid', $this->get($url)->original);\n\n        $response = $this->get('/foo/relative');\n        $response->assertStatus(403);\n    }\n\n    public function testSignedMiddlewareIgnoringParameter()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n        })->name('foo')->middleware('signed:relative');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1]).'&ignore=me');\n        $request = Request::create($url);\n        $middleware = $this->createValidateSignatureMiddleware(['ignore']);\n\n        try {\n            $middleware->handle($request, function ($request) {\n                $this->assertTrue($request->hasValidSignatureWhileIgnoring(['ignore']));\n            });\n        } catch (InvalidSignatureException $exception) {\n            $this->fail($exception->getMessage());\n        }\n    }\n\n    public function testSignedMiddlewareIgnoringParameterViaArgumentsWithRelative()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n        })->name('foo')->middleware('signed:relative,ignore');\n\n        $this->assertIsString('https://fake.test'.URL::signedRoute('foo', ['id' => 1, 'ignore' => 'me'], null, false));\n\n        $response = $this->get('/foo/1');\n        $response->assertStatus(403);\n    }\n\n    public function testSignedMiddlewareCanGloballyIgnoreParameters()\n    {\n        ValidateSignature::except(['globally_ignore']);\n\n        Route::get('/foo/{id}', function (Request $request, $id) {\n        })->name('foo')->middleware('signed:relative');\n\n        $this->assertIsString($url = URL::signedRoute('foo', ['id' => 1]).'&globally_ignore=me');\n        $request = Request::create($url);\n        $middleware = $this->createValidateSignatureMiddleware(['ignore']);\n\n        try {\n            $middleware->handle($request, function ($request) {\n                $this->assertTrue($request->hasValidSignatureWhileIgnoring(['globally_ignore']));\n            });\n        } catch (InvalidSignatureException $exception) {\n            $this->fail($exception->getMessage());\n        }\n    }\n\n    public function testSignedMiddlewareIgnoringParameterViaArgumentsWithoutRelative()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n        })->name('foo')->middleware('signed:ignore');\n\n        $this->assertIsString($url = 'https://fake.test'.URL::signedRoute('foo', ['id' => 1, 'ignore' => 'me'], null, false));\n\n        $response = $this->get('/foo/1');\n        $response->assertStatus(403);\n    }\n\n    public function testSignedMiddlewareIgnoringParameterViaClassAndArguments()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n        })->name('foo')->middleware(IgnoreParameterMiddleware::relative('test'));\n\n        $this->assertIsString($url = 'https://fake.test'.URL::signedRoute('foo', ['id' => 1, 'ignore' => 'me', 'test' => 'bar'], null, false));\n\n        $response = $this->get('/foo/1');\n        $response->assertStatus(403);\n    }\n\n    public function testItCanGenerateMiddlewareDefinitionViaStaticMethod()\n    {\n        $signature = (string) ValidateSignature::relative();\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ValidateSignature:relative', $signature);\n\n        $signature = (string) ValidateSignature::absolute();\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ValidateSignature', $signature);\n\n        $signature = (string) ValidateSignature::relative(['foo', 'bar']);\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ValidateSignature:relative,foo,bar', $signature);\n\n        $signature = (string) ValidateSignature::absolute(['foo', 'bar']);\n        $this->assertSame('Illuminate\\Routing\\Middleware\\ValidateSignature:foo,bar', $signature);\n    }\n\n    public function testUrlsSignedByPreviousAppKeysAreValidWhenAddedAsPreviousKeys()\n    {\n        Route::get('/foo/{id}', function (Request $request, $id) {\n            return $request->hasValidSignature() ? 'valid' : 'invalid';\n        })->name('foo');\n\n        config(['app.key' => 'oldest-key']);\n        $oldestURL = URL::signedRoute('foo', ['id' => 1]);\n\n        config(['app.key' => 'old-key']);\n        $oldURL = URL::signedRoute('foo', ['id' => 1]);\n\n        config(['app.key' => 'new-key']);\n        $newUrl = URL::signedRoute('foo', ['id' => 1]);\n\n        tap($this->get($oldestURL), fn ($response) => $this->assertSame('invalid', $response->original));\n        tap($this->get($oldURL), fn ($response) => $this->assertSame('invalid', $response->original));\n        tap($this->get($newUrl), fn ($response) => $this->assertSame('valid', $response->original));\n\n        config(['app.previous_keys' => ['old-key', 'oldest-key']]);\n\n        tap($this->get($oldestURL), fn ($response) => $this->assertSame('valid', $response->original));\n        tap($this->get($oldURL), fn ($response) => $this->assertSame('valid', $response->original));\n        tap($this->get($newUrl), fn ($response) => $this->assertSame('valid', $response->original));\n    }\n\n    protected function createValidateSignatureMiddleware(array $ignore)\n    {\n        return new class($ignore) extends ValidateSignature\n        {\n            public function __construct(array $ignore)\n            {\n                $this->ignore = $ignore;\n            }\n        };\n    }\n}\n\nclass RoutableInterfaceStub implements UrlRoutable\n{\n    public $key;\n    public $routable;\n    public $slug = 'routable-slug';\n\n    public function getRouteKey()\n    {\n        return $this->{$this->getRouteKeyName()};\n    }\n\n    public function getRouteKeyName()\n    {\n        return 'routable';\n    }\n\n    public function resolveRouteBinding($routeKey, $field = null)\n    {\n        //\n    }\n\n    public function resolveChildRouteBinding($childType, $routeKey, $field = null)\n    {\n        //\n    }\n}\n\nclass IgnoreParameterMiddleware extends ValidateSignature\n{\n    protected $ignore = ['ignore'];\n}\n"
  },
  {
    "path": "tests/Integration/Routing/stubs/serializable-closure-v1/routes-v7.php",
    "content": "<?php\n\napp('router')->setCompiledRoutes(\n    [\n        'compiled' => [\n            0 => false,\n            1 => [\n                '/' => [\n                    0 => [\n                        0 => [\n                            '_route' => 'generated::7CFionvE02fEbBNP',\n                        ],\n                        1 => null,\n                        2 => [\n                            'GET' => 0,\n                            'HEAD' => 1,\n                        ],\n                        3 => null,\n                        4 => false,\n                        5 => false,\n                        6 => null,\n                    ],\n                ],\n            ],\n            2 => [\n                0 => '{^(?|/users/([^/]++)(*:22))/?$}sDu',\n            ],\n            3 => [\n                22 => [\n                    0 => [\n                        0 => [\n                            '_route' => 'generated::YmZUvOCRFrqhC2sO',\n                        ],\n                        1 => [\n                            0 => 'user',\n                        ],\n                        2 => [\n                            'GET' => 0,\n                            'HEAD' => 1,\n                        ],\n                        3 => null,\n                        4 => false,\n                        5 => true,\n                        6 => null,\n                    ],\n                    1 => [\n                        0 => null,\n                        1 => null,\n                        2 => null,\n                        3 => null,\n                        4 => false,\n                        5 => false,\n                        6 => 0,\n                    ],\n                ],\n            ],\n            4 => null,\n        ],\n        'attributes' => [\n            'generated::7CFionvE02fEbBNP' => [\n                'methods' => [\n                    0 => 'GET',\n                    1 => 'HEAD',\n                ],\n                'uri' => '/',\n                'action' => [\n                    'middleware' => [\n                        0 => 'web',\n                    ],\n                    'uses' => 'O:55:\"Laravel\\\\SerializableClosure\\\\UnsignedSerializableClosure\":1:{s:12:\"serializable\";O:46:\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\":5:{s:3:\"use\";a:0:{}s:8:\"function\";s:44:\"function () {\n    return \\\\view(\\'welcome\\');\n}\";s:5:\"scope\";s:37:\"Illuminate\\\\Routing\\\\RouteFileRegistrar\";s:4:\"this\";N;s:4:\"self\";s:32:\"00000000000002f00000000000000000\";}}',\n                    'namespace' => null,\n                    'prefix' => '',\n                    'where' => [\n                    ],\n                    'as' => 'generated::7CFionvE02fEbBNP',\n                ],\n                'fallback' => false,\n                'defaults' => [\n                ],\n                'wheres' => [\n                ],\n                'bindingFields' => [\n                ],\n                'lockSeconds' => null,\n                'waitSeconds' => null,\n                'withTrashed' => false,\n            ],\n            'generated::YmZUvOCRFrqhC2sO' => [\n                'methods' => [\n                    0 => 'GET',\n                    1 => 'HEAD',\n                ],\n                'uri' => 'users/{user}',\n                'action' => [\n                    'middleware' => [\n                        0 => 'web',\n                    ],\n                    'uses' => 'O:55:\"Laravel\\\\SerializableClosure\\\\UnsignedSerializableClosure\":1:{s:12:\"serializable\";O:46:\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\":5:{s:3:\"use\";a:0:{}s:8:\"function\";s:52:\"fn (\\\\Illuminate\\\\Foundation\\\\Auth\\\\User $user) => $user\";s:5:\"scope\";s:37:\"Illuminate\\\\Routing\\\\RouteFileRegistrar\";s:4:\"this\";N;s:4:\"self\";s:32:\"00000000000002f20000000000000000\";}}',\n                    'namespace' => null,\n                    'prefix' => '',\n                    'where' => [\n                    ],\n                    'as' => 'generated::YmZUvOCRFrqhC2sO',\n                ],\n                'fallback' => false,\n                'defaults' => [\n                ],\n                'wheres' => [\n                ],\n                'bindingFields' => [\n                ],\n                'lockSeconds' => null,\n                'waitSeconds' => null,\n                'withTrashed' => false,\n            ],\n        ],\n    ]\n);\n"
  },
  {
    "path": "tests/Integration/Session/CookieSessionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Session;\n\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\TestCase;\n\nclass CookieSessionHandlerTest extends TestCase\n{\n    public function testCookieSessionDriverCookiesCanExpireOnClose()\n    {\n        Route::get('/', fn () => '')->middleware('web');\n\n        $response = $this->get('/');\n        $sessionIdCookie = $response->getCookie('laravel_session');\n        $sessionValueCookie = $response->getCookie($sessionIdCookie->getValue());\n\n        $this->assertEquals(0, $sessionIdCookie->getExpiresTime());\n        $this->assertEquals(0, $sessionValueCookie->getExpiresTime());\n    }\n\n    public function testCookieSessionInheritsRequestSecureState()\n    {\n        Route::get('/', fn () => '')->middleware('web');\n\n        $unsecureResponse = $this->get('/');\n        $unsecureSessionIdCookie = $unsecureResponse->getCookie('laravel_session');\n        $unsecureSessionValueCookie = $unsecureResponse->getCookie($unsecureSessionIdCookie->getValue());\n\n        $this->assertFalse($unsecureSessionIdCookie->isSecure());\n        $this->assertFalse($unsecureSessionValueCookie->isSecure());\n\n        $secureResponse = $this->get('https://localhost/');\n        $secureSessionIdCookie = $secureResponse->getCookie('laravel_session');\n        $secureSessionValueCookie = $secureResponse->getCookie($secureSessionIdCookie->getValue());\n\n        $this->assertTrue($secureSessionIdCookie->isSecure());\n        $this->assertTrue($secureSessionValueCookie->isSecure());\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('session.driver', 'cookie');\n        $app['config']->set('session.expire_on_close', true);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Session/DatabaseSessionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Session;\n\nuse Illuminate\\Session\\DatabaseSessionHandler;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\n\n#[WithMigration('session')]\nclass DatabaseSessionHandlerTest extends DatabaseTestCase\n{\n    public function test_basic_read_write_functionality()\n    {\n        $connection = $this->app['db']->connection();\n        $handler = new DatabaseSessionHandler($connection, 'sessions', 1);\n        $handler->setContainer($this->app);\n\n        // read non-existing session id:\n        $this->assertEquals('', $handler->read('invalid_session_id'));\n\n        // open and close:\n        $this->assertTrue($handler->open('', ''));\n        $this->assertTrue($handler->close());\n\n        // write and read:\n        $this->assertTrue($handler->write('valid_session_id_2425', json_encode(['foo' => 'bar'])));\n        $this->assertEquals(['foo' => 'bar'], json_decode($handler->read('valid_session_id_2425'), true));\n        $this->assertEquals(1, $connection->table('sessions')->count());\n\n        $session = $connection->table('sessions')->first();\n        $this->assertNotNull($session->user_agent);\n        $this->assertNotNull($session->ip_address);\n\n        // re-write and read:\n        $this->assertTrue($handler->write('valid_session_id_2425', json_encode(['over' => 'ride'])));\n        $this->assertEquals(['over' => 'ride'], json_decode($handler->read('valid_session_id_2425'), true));\n        $this->assertEquals(1, $connection->table('sessions')->count());\n\n        // handler object writes only one session id:\n        $this->assertTrue($handler->write('other_id', 'data'));\n        $this->assertEquals(1, $connection->table('sessions')->count());\n\n        $handler->setExists(false);\n        $this->assertTrue($handler->write('other_id', 'data'));\n        $this->assertEquals(2, $connection->table('sessions')->count());\n\n        // read expired:\n        Carbon::setTestNow(Carbon::now()->addMinutes(2));\n        $this->assertEquals('', $handler->read('valid_session_id_2425'));\n\n        // rewriting an expired session-id, makes it live:\n        $this->assertTrue($handler->write('valid_session_id_2425', json_encode(['come' => 'alive'])));\n        $this->assertEquals(['come' => 'alive'], json_decode($handler->read('valid_session_id_2425'), true));\n    }\n\n    public function test_garbage_collector()\n    {\n        $connection = $this->app['db']->connection();\n\n        $handler = new DatabaseSessionHandler($connection, 'sessions', 1, $this->app);\n        Carbon::setTestNow(Carbon::now());\n        $handler->write('simple_id_1', 'abcd');\n        $this->assertEquals(0, $handler->gc(1));\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(2));\n\n        $handler = new DatabaseSessionHandler($connection, 'sessions', 1, $this->app);\n        $handler->write('simple_id_2', 'abcd');\n        $this->assertEquals(1, $handler->gc(2));\n        $this->assertEquals(1, $connection->table('sessions')->count());\n\n        Carbon::setTestNow(Carbon::now()->addSeconds(2));\n\n        $this->assertEquals(1, $handler->gc(1));\n        $this->assertEquals(0, $connection->table('sessions')->count());\n    }\n\n    public function test_destroy()\n    {\n        $connection = $this->app['db']->connection();\n        $handler1 = new DatabaseSessionHandler($connection, 'sessions', 1, $this->app);\n        $handler2 = clone $handler1;\n\n        $handler1->write('id_1', 'some data');\n        $handler2->write('id_2', 'some data');\n\n        // destroy invalid session-id:\n        $this->assertEquals(true, $handler1->destroy('invalid_session_id'));\n        // nothing deleted:\n        $this->assertEquals(2, $connection->table('sessions')->count());\n\n        // destroy valid session-id:\n        $this->assertEquals(true, $handler2->destroy('id_1'));\n        // only one row is deleted:\n        $this->assertEquals(1, $connection->table('sessions')->where('id', 'id_2')->count());\n    }\n\n    public function test_it_can_work_without_container()\n    {\n        $connection = $this->app['db']->connection();\n        $handler = new DatabaseSessionHandler($connection, 'sessions', 1);\n\n        // write and read:\n        $this->assertTrue($handler->write('session_id', 'some data'));\n        $this->assertEquals('some data', $handler->read('session_id'));\n        $this->assertEquals(1, $connection->table('sessions')->count());\n\n        $session = $connection->table('sessions')->first();\n        $this->assertNull($session->user_agent);\n        $this->assertNull($session->ip_address);\n        $this->assertNull($session->user_id);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Session/SessionPersistenceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Session;\n\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Session\\NullSessionHandler;\nuse Illuminate\\Session\\TokenMismatchException;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Session;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SessionPersistenceTest extends TestCase\n{\n    public function testSessionIsPersistedEvenIfExceptionIsThrownFromRoute()\n    {\n        $handler = new FakeNullSessionHandler;\n        $this->assertFalse($handler->written);\n\n        Session::extend('fake-null', function () use ($handler) {\n            return $handler;\n        });\n\n        Route::get('/', function () {\n            throw new TokenMismatchException;\n        })->middleware('web');\n\n        $this->get('/');\n        $this->assertTrue($handler->written);\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app->instance(\n            ExceptionHandler::class,\n            $handler = m::mock(ExceptionHandler::class)->shouldIgnoreMissing()\n        );\n\n        $handler->shouldReceive('render')->andReturn(new Response);\n\n        $app['config']->set('app.key', Str::random(32));\n        $app['config']->set('session.driver', 'fake-null');\n        $app['config']->set('session.expire_on_close', true);\n    }\n}\n\nclass FakeNullSessionHandler extends NullSessionHandler\n{\n    public $written = false;\n\n    public function write($sessionId, $data): bool\n    {\n        $this->written = true;\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/AuthFacadeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Support\\Facades\\Auth;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass AuthFacadeTest extends TestCase\n{\n    public function testItFailsIfTheUiPackageIsMissing()\n    {\n        $this->expectExceptionObject(new RuntimeException(\n            'In order to use the Auth::routes() method, please install the laravel/ui package.'\n        ));\n\n        Auth::routes();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/DeferredCallbackTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks;\nuse Illuminate\\Support\\Facades\\Route;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\nclass DeferredCallbackTest extends TestCase\n{\n    #[WithConfig('queue.default', 'sync')]\n    public function test_deferred_callback_is_not_discarded_by_sync_job()\n    {\n        $executed = false;\n\n        Route::get('/test', function () use (&$executed) {\n            defer(function () use (&$executed) {\n                $executed = true;\n            });\n\n            dispatch(new TestSyncJob);\n        })->middleware(InvokeDeferredCallbacks::class);\n\n        $this->get('/test');\n\n        $this->assertTrue($executed);\n    }\n}\n\nclass TestSyncJob implements ShouldQueue\n{\n    use Dispatchable, Queueable;\n\n    public function handle(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/ExceptionsFacadeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse ErrorException;\nuse Exception;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Foundation\\Exceptions\\Handler;\nuse Illuminate\\Support\\Facades\\Exceptions;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Support\\Testing\\Fakes\\ExceptionHandlerFake;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse RuntimeException;\nuse Throwable;\n\nclass ExceptionsFacadeTest extends TestCase\n{\n    public function testFakeAssertReported()\n    {\n        Exceptions::fake();\n\n        Exceptions::report($thrownException = new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n\n        Exceptions::assertReported(RuntimeException::class);\n        Exceptions::assertReported(fn (RuntimeException $e) => $e->getMessage() === 'test 1');\n        Exceptions::assertReported(fn (RuntimeException $e) => $e->getMessage() === 'test 2');\n        Exceptions::assertReportedCount(2);\n\n        $reported = Exceptions::reported();\n        $this->assertCount(2, $reported);\n        $this->assertSame($thrownException, $reported[0]);\n    }\n\n    public function testFakeAssertReportedCount()\n    {\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n\n        Exceptions::assertReportedCount(2);\n    }\n\n    public function testFakeAssertReportedCountMayFail()\n    {\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The total number of exceptions reported was 2 instead of 1.');\n\n        Exceptions::assertReportedCount(1);\n    }\n\n    public function testFakeAssertReportedWithFakedExceptions()\n    {\n        Exceptions::fake([\n            RuntimeException::class,\n        ]);\n\n        Exceptions::report(new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n        report(new InvalidArgumentException('test 3'));\n\n        Exceptions::assertReported(RuntimeException::class);\n        Exceptions::assertReported(fn (RuntimeException $e) => $e->getMessage() === 'test 1');\n        Exceptions::assertReported(fn (RuntimeException $e) => $e->getMessage() === 'test 2');\n\n        Exceptions::assertNotReported(InvalidArgumentException::class);\n        Exceptions::assertReportedCount(2);\n    }\n\n    public function testFakeAssertReportedAsStringMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The expected [InvalidArgumentException] exception was not reported.');\n\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n\n        Exceptions::assertReportedCount(1);\n        Exceptions::assertReported(InvalidArgumentException::class);\n    }\n\n    public function testFakeAssertReportedAsClosureMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The expected [InvalidArgumentException] exception was not reported.');\n\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n\n        Exceptions::assertReportedCount(1);\n        Exceptions::assertReported(fn (InvalidArgumentException $e) => $e->getMessage() === 'test 2');\n    }\n\n    public function testFakeAssertReportedWithFakedExceptionsMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The expected [RuntimeException] exception was not reported.');\n\n        Exceptions::fake(InvalidArgumentException::class);\n\n        Exceptions::report(new InvalidArgumentException('test 1'));\n        report(new RuntimeException('test 2'));\n\n        Exceptions::assertReported(InvalidArgumentException::class);\n        Exceptions::assertReported(RuntimeException::class);\n    }\n\n    public function testFakeAssertNotReported()\n    {\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n\n        Exceptions::assertNotReported(InvalidArgumentException::class);\n        Exceptions::assertNotReported(fn (InvalidArgumentException $e) => $e->getMessage() === 'test 1');\n        Exceptions::assertNotReported(fn (InvalidArgumentException $e) => $e->getMessage() === 'test 2');\n        Exceptions::assertNotReported(fn (InvalidArgumentException $e) => $e->getMessage() === 'test 3');\n        Exceptions::assertNotReported(fn (InvalidArgumentException $e) => $e->getMessage() === 'test 4');\n\n        Exceptions::assertReportedCount(2);\n    }\n\n    public function testFakeAssertNotReportedWithFakedExceptions()\n    {\n        Exceptions::fake([\n            InvalidArgumentException::class,\n        ]);\n\n        report(new RuntimeException('test 2'));\n\n        Exceptions::assertNotReported(InvalidArgumentException::class);\n        Exceptions::assertNotReported(RuntimeException::class);\n    }\n\n    public function testFakeAssertNotReportedMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The expected [RuntimeException] exception was reported.');\n\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n\n        Exceptions::assertNotReported(RuntimeException::class);\n    }\n\n    public function testFakeAssertNotReportedAsClosureMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The expected [RuntimeException] exception was reported.');\n\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n\n        Exceptions::assertNotReported(fn (RuntimeException $e) => $e->getMessage() === 'test 1');\n    }\n\n    public function testResolvesExceptionHandler()\n    {\n        $this->assertInstanceOf(\n            ExceptionHandler::class,\n            Exceptions::getFacadeRoot()\n        );\n    }\n\n    public function testFakeAssertNothingReported()\n    {\n        Exceptions::fake();\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testFakeAssertNothingReportedWithFakedExceptions()\n    {\n        Exceptions::fake([\n            InvalidArgumentException::class,\n        ]);\n\n        report(new RuntimeException('test 1'));\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testFakeAssertNothingReportedMayFail()\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The following exceptions were reported: RuntimeException, RuntimeException, InvalidArgumentException.');\n\n        Exceptions::fake();\n\n        Exceptions::report(new RuntimeException('test 1'));\n        report(new RuntimeException('test 2'));\n        report(new InvalidArgumentException('test 3'));\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testFakeMethodReturnsExceptionHandlerFake()\n    {\n        $this->assertInstanceOf(ExceptionHandlerFake::class, $fake = Exceptions::fake());\n        $this->assertInstanceOf(ExceptionHandlerFake::class, Exceptions::getFacadeRoot());\n        $this->assertInstanceOf(Handler::class, $fake->handler());\n\n        $this->assertInstanceOf(ExceptionHandlerFake::class, $fake = Exceptions::fake());\n        $this->assertInstanceOf(ExceptionHandlerFake::class, Exceptions::getFacadeRoot());\n        $this->assertInstanceOf(Handler::class, $fake->handler());\n    }\n\n    public function testReportedExceptionsAreNotThrownByDefault()\n    {\n        report(new Exception('Test exception'));\n\n        $this->assertTrue(true);\n    }\n\n    public function testReportedExceptionsAreNotThrownByDefaultWithExceptionHandling()\n    {\n        Route::get('/', function () {\n            report(new Exception('Test exception'));\n        });\n\n        $this->get('/')->assertStatus(200);\n    }\n\n    public function testReportedExceptionsAreNotThrownByDefaultWithoutExceptionHandling()\n    {\n        $this->withoutExceptionHandling();\n\n        Route::get('/', function () {\n            report(new Exception('Test exception'));\n        });\n\n        $this->get('/')->assertStatus(200);\n    }\n\n    public function testThrowOnReport()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        report(new Exception('Test exception'));\n    }\n\n    public function testThrowOnReportDoesNotThrowExceptionsThatShouldNotBeReported()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        Route::get('/302', function () {\n            Validator::validate(['name' => ''], ['name' => 'required']);\n        });\n\n        $this->get('/302')->assertStatus(302);\n\n        Route::get('/404', function () {\n            throw new ModelNotFoundException();\n        });\n\n        $this->get('/404')->assertStatus(404);\n\n        $this->doesNotPerformAssertions();\n\n        Exceptions::assertReportedCount(0);\n    }\n\n    public function testThrowOnReportWithExceptionHandling()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        Route::get('/', function () {\n            report(new Exception('Test exception'));\n        });\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        $this->get('/');\n    }\n\n    public function testThrowOnReportWithoutExceptionHandling()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        $this->withoutExceptionHandling();\n\n        Route::get('/', function () {\n            report(new Exception('Test exception'));\n        });\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        $this->get('/');\n    }\n\n    public function testThrowOnReportRegardlessOfTheCallingOrderOfWithoutExceptionHandling()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        $this\n            ->withoutExceptionHandling()\n            ->withExceptionHandling()\n            ->withoutExceptionHandling();\n\n        Route::get('/', function () {\n            rescue(fn () => throw new Exception('Test exception'));\n        });\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        $this->get('/');\n    }\n\n    public function testThrowOnReportRegardlessOfTheCallingOrderOfWithExceptionHandling()\n    {\n        Exceptions::fake()->throwOnReport();\n\n        $this->withoutExceptionHandling()\n            ->withExceptionHandling()\n            ->withoutExceptionHandling()\n            ->withExceptionHandling();\n\n        Route::get('/', function () {\n            rescue(fn () => throw new Exception('Test exception'));\n        });\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        $this->get('/');\n    }\n\n    public function testThrowOnReportWithFakedExceptions()\n    {\n        Exceptions::fake([InvalidArgumentException::class])->throwOnReport();\n\n        $this->expectException(InvalidArgumentException::class);\n\n        report(new Exception('Test exception'));\n        report(new RuntimeException('Test exception'));\n        report(new InvalidArgumentException('Test exception'));\n    }\n\n    public function testThrowOnReportWithFakedExceptionsFromFacade()\n    {\n        Exceptions::fake([InvalidArgumentException::class])->throwOnReport();\n\n        $this->expectException(InvalidArgumentException::class);\n\n        report(new Exception('Test exception'));\n        report(new RuntimeException('Test exception'));\n        Exceptions::assertReportedCount(0);\n\n        report(new InvalidArgumentException('Test exception'));\n    }\n\n    public function testThrowOnReporEvenWhenAppReportablesReturnFalse()\n    {\n        app(ExceptionHandler::class)->reportable(function (Throwable $e) {\n            return false;\n        });\n\n        Exceptions::fake()->throwOnReport();\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        report(new Exception('Test exception'));\n    }\n\n    public function testAppReportablesAreNotCalledIfExceptionIsNotFaked()\n    {\n        app(ExceptionHandler::class)->reportable(function (Throwable $e) {\n            throw new InvalidArgumentException($e->getMessage());\n        });\n\n        Exceptions::fake([RuntimeException::class, Exception::class]);\n\n        report(new Exception('My exception message'));\n\n        Exceptions::assertReported(Exception::class);\n    }\n\n    public function testThrowOnReportLeaveAppReportablesUntouched()\n    {\n        app(ExceptionHandler::class)->reportable(function (Throwable $e) {\n            throw new InvalidArgumentException($e->getMessage());\n        });\n\n        Exceptions::fake([RuntimeException::class])->throwOnReport();\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('My exception message');\n\n        report(new Exception('My exception message'));\n    }\n\n    public function testThrowReportedExceptions()\n    {\n        Exceptions::fake();\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        report(new Exception('Test exception'));\n\n        Exceptions::throwFirstReported();\n    }\n\n    public function testThrowReportedExceptionsWithFakedExceptions()\n    {\n        Exceptions::fake([InvalidArgumentException::class]);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Test exception');\n\n        report(new RuntimeException('Test exception'));\n        report(new InvalidArgumentException('Test exception'));\n\n        Exceptions::throwFirstReported();\n    }\n\n    public function testThrowReportedExceptionsWhenThereIsNone()\n    {\n        Exceptions::fake();\n\n        Exceptions::throwFirstReported();\n\n        Exceptions::fake([InvalidArgumentException::class]);\n\n        report(new RuntimeException('Test exception'));\n\n        Exceptions::throwFirstReported();\n\n        $this->doesNotPerformAssertions();\n    }\n\n    public function testFakingExceptionsThatShouldNotBeReportedWithExceptionHandling()\n    {\n        Exceptions::fake();\n\n        Route::get('/302', function () {\n            Validator::validate(['name' => ''], ['name' => 'required']);\n        });\n\n        $this->get('/302')->assertStatus(302);\n\n        Route::get('/404', function () {\n            throw new ModelNotFoundException();\n        });\n\n        $this->get('/404')->assertStatus(404);\n\n        report(new ModelNotFoundException());\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testFakingExceptionsThatShouldNotBeReportedWithRescueAndWithoutExceptionHandling()\n    {\n        Exceptions::fake();\n\n        $this->withoutExceptionHandling();\n\n        Route::get('/validation', function () {\n            rescue(fn () => Validator::validate(['name' => ''], ['name' => 'required']));\n        });\n\n        $this->get('/validation')->assertStatus(200);\n\n        Route::get('/model', function () {\n            rescue(fn () => throw new ModelNotFoundException());\n        });\n\n        $this->get('/model')->assertStatus(200);\n\n        rescue(fn () => throw new ModelNotFoundException());\n\n        Exceptions::assertReportedCount(3);\n    }\n\n    public function testRescue()\n    {\n        Exceptions::fake();\n\n        rescue(fn () => throw new Exception('Test exception'));\n\n        Exceptions::assertReported(Exception::class);\n    }\n\n    public function testRescueWithoutReport()\n    {\n        Exceptions::fake();\n\n        rescue(fn () => throw new Exception('Test exception'), null, false);\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testFlowBetweenFakeAndTestExceptionHandling()\n    {\n        $this->assertInstanceOf(Handler::class, app(ExceptionHandler::class));\n\n        Exceptions::fake();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(Handler::class, Exceptions::fake()->handler());\n        $this->assertFalse((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        Exceptions::fake();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(Handler::class, Exceptions::fake()->handler());\n        $this->assertFalse((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        $this->withoutExceptionHandling();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(ExceptionHandler::class, Exceptions::fake()->handler());\n        $this->assertTrue((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        $this->withExceptionHandling();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(ExceptionHandler::class, Exceptions::fake()->handler());\n        $this->assertFalse((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        Exceptions::fake();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(Handler::class, Exceptions::fake()->handler());\n        $this->assertFalse((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n    }\n\n    public function testFlowBetweenTestExceptionHandlingAndFake()\n    {\n        $this->withoutExceptionHandling();\n        $this->assertTrue((new \\ReflectionClass(app(ExceptionHandler::class)))->isAnonymous());\n\n        Exceptions::fake();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(ExceptionHandler::class, Exceptions::fake()->handler());\n        $this->assertTrue((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        Exceptions::fake();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(ExceptionHandler::class, Exceptions::fake()->handler());\n        $this->assertTrue((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n\n        $this->withExceptionHandling();\n        $this->assertInstanceOf(ExceptionHandlerFake::class, app(ExceptionHandler::class));\n        $this->assertInstanceOf(Handler::class, Exceptions::fake()->handler());\n        $this->assertFalse((new \\ReflectionClass(Exceptions::fake()->handler()))->isAnonymous());\n    }\n\n    public function testWithDeprecationHandling()\n    {\n        Exceptions::fake();\n\n        Route::get('/', function () {\n            str_contains(null, null);\n        });\n\n        $this->get('/')->assertStatus(200);\n\n        Exceptions::assertNothingReported();\n    }\n\n    public function testWithoutDeprecationHandler()\n    {\n        Exceptions::fake();\n\n        $this->withoutDeprecationHandling();\n\n        Route::get('/', function () {\n            str_contains(null, null);\n        });\n\n        $this->get('/')->assertStatus(500);\n\n        Exceptions::assertReported(function (ErrorException $e) {\n            return $e->getMessage() === 'str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated';\n        });\n\n        Exceptions::assertReportedCount(1);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/FacadesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Auth\\AuthManager;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Orchestra\\Testbench\\TestCase;\nuse ReflectionClass;\n\nclass FacadesTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        unset($_SERVER['__laravel.authResolved']);\n\n        parent::tearDown();\n    }\n\n    public function testFacadeResolvedCanResolveCallback()\n    {\n        Auth::resolved(function (AuthManager $auth, Application $app) {\n            $_SERVER['__laravel.authResolved'] = true;\n        });\n\n        $this->assertFalse(isset($_SERVER['__laravel.authResolved']));\n\n        $this->app->make('auth');\n\n        $this->assertTrue(isset($_SERVER['__laravel.authResolved']));\n    }\n\n    public function testFacadeResolvedCanResolveCallbackAfterAccessRootHasBeenResolved()\n    {\n        $this->app->make('auth');\n\n        $this->assertFalse(isset($_SERVER['__laravel.authResolved']));\n\n        Auth::resolved(function (AuthManager $auth, Application $app) {\n            $_SERVER['__laravel.authResolved'] = true;\n        });\n\n        $this->assertTrue(isset($_SERVER['__laravel.authResolved']));\n    }\n\n    public function testDefaultAliases()\n    {\n        $defaultAliases = Facade::defaultAliases();\n\n        $this->assertInstanceOf(Collection::class, $defaultAliases);\n\n        foreach ($defaultAliases as $alias => $abstract) {\n            $this->assertTrue(class_exists($alias));\n            $this->assertTrue(class_exists($abstract));\n\n            $reflection = new ReflectionClass($alias);\n            $this->assertSame($abstract, $reflection->getName());\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/Fixtures/MultipleInstanceManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support\\Fixtures;\n\nuse Illuminate\\Support\\MultipleInstanceManager as BaseMultipleInstanceManager;\n\nclass MultipleInstanceManager extends BaseMultipleInstanceManager\n{\n    protected $defaultInstance = 'foo';\n\n    protected function createFooDriver(array $config)\n    {\n        return new class($config)\n        {\n            public $config;\n\n            public function __construct($config)\n            {\n                $this->config = $config;\n            }\n        };\n    }\n\n    protected function createBarDriver(array $config)\n    {\n        return new class($config)\n        {\n            public $config;\n\n            public function __construct($config)\n            {\n                $this->config = $config;\n            }\n        };\n    }\n\n    protected function createMysqlDatabaseConnectionDriver(array $config)\n    {\n        return new class($config)\n        {\n            public function __construct(public $config)\n            {\n            }\n        };\n    }\n\n    /**\n     * Get the default instance name.\n     *\n     * @return string\n     */\n    public function getDefaultInstance()\n    {\n        return $this->defaultInstance;\n    }\n\n    /**\n     * Set the default instance name.\n     *\n     * @param  string  $name\n     * @return void\n     */\n    public function setDefaultInstance($name)\n    {\n        $this->defaultInstance = $name;\n    }\n\n    /**\n     * Get the instance specific configuration.\n     *\n     * @param  string  $name\n     * @return array\n     */\n    public function getInstanceConfig($name)\n    {\n        switch ($name) {\n            case 'foo':\n                return [\n                    'driver' => 'foo',\n                    'foo-option' => 'option-value',\n                ];\n            case 'bar':\n                return [\n                    'driver' => 'bar',\n                    'bar-option' => 'option-value',\n                ];\n            case 'mysql_database-connection':\n                return [\n                    'driver' => 'mysql_database-connection',\n                    'mysql_database-connection-option' => 'option-value',\n                ];\n            case 'custom':\n                return [\n                    'driver' => 'custom',\n                ];\n            default:\n                return [];\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/Fixtures/NullableManager.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support\\Fixtures;\n\nuse Illuminate\\Support\\Manager;\n\nclass NullableManager extends Manager\n{\n    /**\n     * Get the default driver name.\n     *\n     * @return string|null\n     */\n    public function getDefaultDriver()\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/ManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Tests\\Integration\\Support\\Fixtures\\NullableManager;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ManagerTest extends TestCase\n{\n    public function testDefaultDriverCannotBeNull()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        (new NullableManager($this->app))->driver();\n    }\n\n    public function testCustomDriverClosureBoundObjectIsManager()\n    {\n        $manager = new NullableManager($this->app);\n        $manager->extend(__CLASS__, fn () => $this);\n        $this->assertSame($manager, $manager->driver(__CLASS__));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/MultipleInstanceManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Tests\\Integration\\Support\\Fixtures\\MultipleInstanceManager;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass MultipleInstanceManagerTest extends TestCase\n{\n    public function test_configurable_instances_can_be_resolved()\n    {\n        $manager = new MultipleInstanceManager($this->app);\n\n        $fooInstance = $manager->instance('foo');\n        $this->assertSame('option-value', $fooInstance->config['foo-option']);\n\n        $barInstance = $manager->instance('bar');\n        $this->assertSame('option-value', $barInstance->config['bar-option']);\n\n        $mysqlInstance = $manager->instance('mysql_database-connection');\n        $this->assertSame('option-value', $mysqlInstance->config['mysql_database-connection-option']);\n\n        $duplicateFooInstance = $manager->instance('foo');\n        $duplicateBarInstance = $manager->instance('bar');\n        $duplicateMysqlInstance = $manager->instance('mysql_database-connection');\n        $this->assertEquals(spl_object_hash($fooInstance), spl_object_hash($duplicateFooInstance));\n        $this->assertEquals(spl_object_hash($barInstance), spl_object_hash($duplicateBarInstance));\n        $this->assertEquals(spl_object_hash($mysqlInstance), spl_object_hash($duplicateMysqlInstance));\n    }\n\n    public function test_unresolvable_instances_throw_errors()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $manager = new MultipleInstanceManager($this->app);\n\n        $instance = $manager->instance('missing');\n    }\n\n    public function test_custom_driver_closure_bound_object_is_multiple_instance_manager()\n    {\n        $manager = new MultipleInstanceManager($this->app);\n        $manager->extend('custom', fn () => $this);\n        $this->assertSame($manager, $manager->instance('custom'));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/OnceHelperTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Foundation\\Testing\\RefreshDatabase;\nuse Illuminate\\Support\\Facades\\DB;\nuse Orchestra\\Testbench\\Attributes\\WithMigration;\nuse Orchestra\\Testbench\\Factories\\UserFactory;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithMigration]\nclass OnceHelperTest extends TestCase\n{\n    use RefreshDatabase;\n\n    protected function afterRefreshingDatabase()\n    {\n        UserFactory::times(3)->create();\n        UserFactory::times(2)->unverified()->create();\n    }\n\n    public function testItCanCacheStaticMethodWithoutParameters()\n    {\n        DB::enableQueryLog();\n        DB::flushQueryLog();\n\n        $verifiedUsers = User::verified();\n        $unverifiedUsers = User::unverified();\n\n        $this->assertCount(3, $verifiedUsers);\n        $this->assertCount(2, $unverifiedUsers);\n        $this->assertCount(2, DB::getQueryLog());\n\n        $verifiedUsers2 = User::verified();\n\n        $this->assertCount(2, DB::getQueryLog());\n\n        $this->assertSame($verifiedUsers, $verifiedUsers2);\n\n        DB::disableQueryLog();\n    }\n\n    public function testItCanCacheStaticMethodWithParameters()\n    {\n        DB::enableQueryLog();\n        DB::flushQueryLog();\n\n        $verifiedUsers = User::getByType('verified');\n        $unverifiedUsers = User::getByType('unverified');\n\n        $this->assertCount(3, $verifiedUsers);\n        $this->assertCount(2, $unverifiedUsers);\n        $this->assertCount(2, DB::getQueryLog());\n\n        $verifiedUsers2 = User::getByType('verified');\n\n        $this->assertCount(2, DB::getQueryLog());\n\n        $this->assertSame($verifiedUsers, $verifiedUsers2);\n\n        DB::disableQueryLog();\n    }\n}\n\nclass User extends Authenticatable\n{\n    public static function verified(): Collection\n    {\n        return once(fn () => self::whereNotNull('email_verified_at')->get());\n    }\n\n    public static function unverified(): Collection\n    {\n        return once(fn () => self::whereNull('email_verified_at')->get());\n    }\n\n    public static function getByType(string $type): Collection\n    {\n        return once(function () use ($type) {\n            return match ($type) {\n                'verified' => self::whereNotNull('email_verified_at')->get(),\n                'unverified' => self::whereNull('email_verified_at')->get()\n            };\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Support/PluralizerPortugueseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Support;\n\nuse Illuminate\\Support\\Pluralizer;\nuse Illuminate\\Support\\Str;\nuse Orchestra\\Testbench\\TestCase;\n\nclass PluralizerPortugueseTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Pluralizer::useLanguage('portuguese');\n    }\n\n    protected function tearDown(): void\n    {\n        Pluralizer::useLanguage('english');\n\n        parent::tearDown();\n    }\n\n    public function testBasicSingular()\n    {\n        $this->assertSame('herói', Str::singular('heróis'));\n        $this->assertSame('irmão', Str::singular('irmãos'));\n        $this->assertSame('chafariz', Str::singular('chafarizes'));\n        $this->assertSame('colher', Str::singular('colheres'));\n        $this->assertSame('modelo', Str::singular('modelos'));\n        $this->assertSame('venda', Str::singular('vendas'));\n        $this->assertSame('usuário', Str::singular('usuários'));\n        $this->assertSame('comissão', Str::singular('comissões'));\n    }\n\n    public function testIrregulars()\n    {\n        $this->assertSame('males', Str::plural('mal'));\n        $this->assertSame('lápis', Str::singular('lápis'));\n    }\n\n    public function testBasicPlural()\n    {\n        $this->assertSame('fênix', Str::plural('fênix'));\n        $this->assertSame('palavras', Str::plural('palavra'));\n        $this->assertSame('modelos', Str::plural('modelo'));\n        $this->assertSame('vendas', Str::plural('venda'));\n        $this->assertSame('usuários', Str::plural('usuário'));\n        $this->assertSame('comissões', Str::plural('comissão'));\n    }\n\n    public function testCaseSensitiveSingularUsage()\n    {\n        $this->assertSame('Criança', Str::singular('Crianças'));\n        $this->assertSame('CIDADÃO', Str::singular('CIDADÃOS'));\n    }\n\n    public function testCaseSensitiveSingularPlural()\n    {\n        $this->assertSame('Crianças', Str::plural('Criança'));\n        $this->assertSame('CIDADÃOS', Str::plural('CIDADÃO'));\n        $this->assertSame('Testes', Str::plural('Teste'));\n    }\n\n    public function testPluralAppliedForStringEndingWithNumericCharacter()\n    {\n        $this->assertSame('Usuário1s', Str::plural('Usuário1'));\n        $this->assertSame('Usuário2s', Str::plural('Usuário2'));\n        $this->assertSame('Usuário3s', Str::plural('Usuário3'));\n    }\n\n    public function testPluralSupportsArrays()\n    {\n        $this->assertSame('usuários', Str::plural('usuário', []));\n        $this->assertSame('usuário', Str::plural('usuário', ['um']));\n        $this->assertSame('usuários', Str::plural('usuário', ['um', 'dois']));\n    }\n\n    public function testPluralSupportsCollections()\n    {\n        $this->assertSame('usuários', Str::plural('usuário', collect()));\n        $this->assertSame('usuário', Str::plural('usuário', collect(['um'])));\n        $this->assertSame('usuários', Str::plural('usuário', collect(['um', 'dois'])));\n    }\n\n    public function testPluralStudlySupportsArrays()\n    {\n        $this->assertPluralStudly('AlgumUsuários', 'AlgumUsuário', []);\n        $this->assertPluralStudly('AlgumUsuário', 'AlgumUsuário', ['um']);\n        $this->assertPluralStudly('AlgumUsuários', 'AlgumUsuário', ['um', 'dois']);\n    }\n\n    public function testPluralStudlySupportsCollections()\n    {\n        $this->assertPluralStudly('AlgumUsuários', 'AlgumUsuário', collect());\n        $this->assertPluralStudly('AlgumUsuário', 'AlgumUsuário', collect(['um']));\n        $this->assertPluralStudly('AlgumUsuários', 'AlgumUsuário', collect(['um', 'dois']));\n    }\n\n    private function assertPluralStudly($expected, $value, $count = 2)\n    {\n        $this->assertSame($expected, Str::pluralStudly($value, $count));\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Testing/ArtisanCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Testing;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Mockery as m;\nuse Mockery\\Exception\\InvalidCountException;\nuse Mockery\\Exception\\InvalidOrderException;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\AssertionFailedError;\n\nclass ArtisanCommandTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Artisan::command('survey', function () {\n            $name = $this->ask('What is your name?');\n\n            $language = $this->choice('Which language do you prefer?', [\n                'PHP',\n                'Ruby',\n                'Python',\n            ]);\n\n            $this->line(\"Your name is $name and you prefer $language.\");\n        });\n\n        Artisan::command('slim', function () {\n            $this->line($this->ask('Who?'));\n            $this->line($this->ask('What?'));\n            $this->line($this->ask('Huh?'));\n        });\n\n        Artisan::command('interactions', function () {\n            /** @var Command $this */\n            $this->ask('What is your name?');\n            $this->choice('Which language do you prefer?', [\n                'PHP',\n                'PHP',\n                'PHP',\n            ]);\n\n            $this->table(['Name', 'Email'], [\n                ['Taylor Otwell', 'taylor@laravel.com'],\n            ]);\n\n            $this->confirm('Do you want to continue?', true);\n        });\n\n        Artisan::command('exit {code}', fn () => (int) $this->argument('code'));\n\n        Artisan::command('contains', function () {\n            $this->line('My name is Taylor Otwell');\n        });\n\n        Artisan::command('new-england', function () {\n            $this->line('The region of New England consists of the following states:');\n            $this->info('Connecticut');\n            $this->info('Maine');\n            $this->info('Massachusetts');\n            $this->info('New Hampshire');\n            $this->info('Rhode Island');\n            $this->info('Vermont');\n        });\n    }\n\n    public function test_console_command_that_passes()\n    {\n        $this->artisan('exit', ['code' => 0])->assertOk();\n    }\n\n    public function test_console_command_that_fails()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Expected status code 0 but received 1.');\n\n        $this->artisan('exit', ['code' => 1])->assertOk();\n    }\n\n    public function test_console_command_that_passes_with_output()\n    {\n        $this->artisan('survey')\n            ->expectsQuestion('What is your name?', 'Taylor Otwell')\n            ->expectsQuestion('Which language do you prefer?', 'PHP')\n            ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')\n            ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_passes_with_repeating_output()\n    {\n        $this->artisan('slim')\n            ->expectsQuestion('Who?', 'Taylor')\n            ->expectsQuestion('What?', 'Taylor')\n            ->expectsQuestion('Huh?', 'Taylor')\n            ->expectsOutput('Taylor')\n            ->doesntExpectOutput('Otwell')\n            ->expectsOutput('Taylor')\n            ->expectsOutput('Taylor')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_fails_from_unexpected_output()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Output \"Your name is Taylor Otwell and you prefer PHP.\" was printed.');\n\n        $this->artisan('survey')\n            ->expectsQuestion('What is your name?', 'Taylor Otwell')\n            ->expectsQuestion('Which language do you prefer?', 'PHP')\n            ->doesntExpectOutput('Your name is Taylor Otwell and you prefer PHP.')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_fails_from_unexpected_output_substring()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Output \"Taylor Otwell\" was printed.');\n\n        $this->artisan('contains')\n            ->doesntExpectOutputToContain('Taylor Otwell')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_fails_from_missing_output()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Output \"Your name is Taylor Otwell and you prefer PHP.\" was not printed.');\n\n        $this->ignoringMockOnceExceptions(function () {\n            $this->artisan('survey')\n                ->expectsQuestion('What is your name?', 'Taylor Otwell')\n                ->expectsQuestion('Which language do you prefer?', 'Ruby')\n                ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')\n                ->assertExitCode(0);\n        });\n    }\n\n    public function test_console_command_that_fails_from_exit_code_mismatch()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Expected status code 1 but received 0.');\n\n        $this->artisan('survey')\n            ->expectsQuestion('What is your name?', 'Taylor Otwell')\n            ->expectsQuestion('Which language do you prefer?', 'PHP')\n            ->assertExitCode(1);\n    }\n\n    public function test_console_command_that_fails_from_unordered_output()\n    {\n        $this->expectException(InvalidOrderException::class);\n\n        $this->ignoringMockOnceExceptions(function () {\n            $this->artisan('slim')\n                ->expectsQuestion('Who?', 'Taylor')\n                ->expectsQuestion('What?', 'Danger')\n                ->expectsQuestion('Huh?', 'Otwell')\n                ->expectsOutput('Taylor')\n                ->expectsOutput('Otwell')\n                ->expectsOutput('Danger')\n                ->assertExitCode(0);\n        });\n    }\n\n    public function test_console_command_that_passes_if_the_output_contains()\n    {\n        $this->artisan('contains')\n            ->expectsOutputToContain('Taylor Otwell')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_passes_if_outputs_something()\n    {\n        $this->artisan('contains')\n            ->expectsOutput()\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_passes_if_outputs_is_something_and_is_the_expected_output()\n    {\n        $this->artisan('contains')\n            ->expectsOutput()\n            ->expectsOutput('My name is Taylor Otwell')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_fail_if_doesnt_output_something()\n    {\n        $this->expectException(InvalidCountException::class);\n\n        $this->artisan('exit', ['code' => 0])\n            ->expectsOutput()\n            ->assertExitCode(0);\n\n        m::close();\n    }\n\n    public function test_console_command_that_fail_if_doesnt_output_something_and_is_not_the_expected_output()\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $this->ignoringMockOnceExceptions(function () {\n            $this->artisan('exit', ['code' => 0])\n                ->expectsOutput()\n                ->expectsOutput('My name is Taylor Otwell')\n                ->assertExitCode(0);\n        });\n    }\n\n    public function test_console_command_that_passes_if_does_not_output_anything()\n    {\n        $this->artisan('exit', ['code' => 0])\n            ->doesntExpectOutput()\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_passes_if_does_not_output_anything_and_is_not_the_expected_output()\n    {\n        $this->artisan('exit', ['code' => 0])\n            ->doesntExpectOutput()\n            ->doesntExpectOutput('My name is Taylor Otwell')\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_passes_if_expects_output_and_there_is_interactions()\n    {\n        $this->artisan('interactions', ['--no-interaction' => true])\n            ->expectsOutput()\n            ->expectsQuestion('What is your name?', 'Taylor Otwell')\n            ->expectsChoice('Which language do you prefer?', 'PHP', ['PHP', 'PHP', 'PHP'])\n            ->expectsConfirmation('Do you want to continue?', true)\n            ->assertExitCode(0);\n    }\n\n    public function test_console_command_that_fails_if_doesnt_expect_output_but__there_is_interactions()\n    {\n        $this->expectException(InvalidCountException::class);\n\n        $this->artisan('interactions', ['--no-interaction' => true])\n            ->doesntExpectOutput()\n            ->expectsQuestion('What is your name?', 'Taylor Otwell')\n            ->expectsChoice('Which language do you prefer?', 'PHP', ['PHP', 'PHP', 'PHP'])\n            ->expectsConfirmation('Do you want to continue?', true)\n            ->assertExitCode(0);\n\n        m::close();\n    }\n\n    public function test_console_command_that_fails_if_doesnt_expect_output_but_outputs_something()\n    {\n        $this->expectException(InvalidCountException::class);\n\n        $this->artisan('contains')\n            ->doesntExpectOutput()\n            ->assertExitCode(0);\n\n        m::close();\n    }\n\n    public function test_console_command_that_fails_if_doesnt_expect_output_and_does_expect_output()\n    {\n        $this->expectException(InvalidCountException::class);\n\n        $this->artisan('contains')\n            ->doesntExpectOutput()\n            ->doesntExpectOutput('My name is Taylor Otwell')\n            ->assertExitCode(0);\n\n        m::close();\n    }\n\n    public function test_console_command_that_fails_if_the_output_does_not_contain()\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Output does not contain \"Otwell Taylor\".');\n\n        $this->ignoringMockOnceExceptions(function () {\n            $this->artisan('contains')\n                ->expectsOutputToContain('Otwell Taylor')\n                ->assertExitCode(0);\n        });\n    }\n\n    public function test_pending_command_can_be_tapped()\n    {\n        $newEngland = [\n            'Connecticut',\n            'Maine',\n            'Massachusetts',\n            'New Hampshire',\n            'Rhode Island',\n            'Vermont',\n        ];\n\n        $this->artisan('new-england')\n            ->expectsOutput('The region of New England consists of the following states:')\n            ->tap(function ($command) use ($newEngland) {\n                foreach ($newEngland as $state) {\n                    $command->expectsOutput($state);\n                }\n            })\n            ->assertExitCode(0);\n    }\n\n    /**\n     * Don't allow Mockery's InvalidCountException to be reported. Mocks setup\n     * in PendingCommand cause PHPUnit tearDown() to later throw the exception.\n     *\n     * @param  callable  $callback\n     * @return void\n     */\n    protected function ignoringMockOnceExceptions(callable $callback)\n    {\n        try {\n            $callback();\n        } finally {\n            try {\n                m::close();\n            } catch (InvalidCountException) {\n                // Ignore mock exception from PendingCommand::expectsOutput().\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Testing/TestCaseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Testing;\n\nuse Illuminate\\Support\\Facades\\Vite;\nuse Orchestra\\Testbench\\TestCase;\n\nclass TestCaseTest extends TestCase\n{\n    public function test_without_vite_clear_facade_resolved_instance()\n    {\n        Vite::useScriptTagAttributes([\n            'crossorigin' => 'anonymous',\n        ]);\n\n        $this->withoutVite();\n\n        Vite::asset('foo.png');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Testing/TestWithoutDatabaseParallelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Testing;\n\nuse Illuminate\\Support\\Facades\\ParallelTesting;\nuse Illuminate\\Testing\\ParallelTestingServiceProvider;\nuse Orchestra\\Testbench\\TestCase;\n\nclass TestWithoutDatabaseParallelTest extends TestCase\n{\n    protected function getPackageProviders($app)\n    {\n        return [ParallelTestingServiceProvider::class];\n    }\n\n    /**\n     * Define the test environment.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function defineEnvironment($app)\n    {\n        // Given an application that does not use database connections at all\n        $app['config']->set('database.default', null);\n\n        // When we run parallel testing with `without-databases` option\n        $_SERVER['LARAVEL_PARALLEL_TESTING'] = 1;\n        $_SERVER['LARAVEL_PARALLEL_TESTING_WITHOUT_DATABASES'] = 1;\n        $_SERVER['TEST_TOKEN'] = '1';\n\n        $this->beforeApplicationDestroyed(function () {\n            unset(\n                $_SERVER['LARAVEL_PARALLEL_TESTING'],\n                $_SERVER['LARAVEL_PARALLEL_TESTING_WITHOUT_DATABASES'],\n                $_SERVER['TEST_TOKEN'],\n            );\n        });\n    }\n\n    public function testRunningParallelTestWithoutDatabaseShouldNotCrashOnDefaultConnection()\n    {\n        // We should not create a database connection to check if it's SQLite or not.\n        ParallelTesting::callSetUpProcessCallbacks();\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Translation/TranslatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Translation;\n\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Validation\\Rules\\File;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass TranslatorTest extends TestCase\n{\n    /**\n     * Define environment setup.\n     *\n     * @param  \\Illuminate\\Foundation\\Application  $app\n     * @return void\n     */\n    protected function defineEnvironment($app)\n    {\n        $app['translator']->addNamespace('tests', __DIR__.'/lang');\n        $app['translator']->addJsonPath(__DIR__.'/lang');\n\n        parent::defineEnvironment($app);\n    }\n\n    public function testItCanGetFromLocaleForJson()\n    {\n        $this->assertSame('30 Days', $this->app['translator']->get('30 Days'));\n\n        $this->app->setLocale('fr');\n\n        $this->assertSame('30 jours', $this->app['translator']->get('30 Days'));\n    }\n\n    public function testItCanCheckLanguageExistsHasFromLocaleForJson()\n    {\n        $this->assertTrue($this->app['translator']->has('1 Day'));\n        $this->assertTrue($this->app['translator']->hasForLocale('1 Day'));\n        $this->assertTrue($this->app['translator']->hasForLocale('30 Days'));\n\n        $this->app->setLocale('fr');\n\n        $this->assertFalse($this->app['translator']->has('1 Day'));\n        $this->assertFalse($this->app['translator']->hasForLocale('1 Day'));\n        $this->assertTrue($this->app['translator']->hasForLocale('30 Days'));\n    }\n\n    public function testItCanCheckKeyExistsWithoutTriggeringHandleMissingKeys()\n    {\n        $this->app['translator']->handleMissingKeysUsing(function ($key) {\n            $_SERVER['__missing_translation_key'] = $key;\n        });\n\n        $this->assertFalse($this->app['translator']->has('Foo Bar'));\n        $this->assertFalse(isset($_SERVER['__missing_translation_key']));\n\n        $this->assertFalse($this->app['translator']->hasForLocale('Foo Bar', 'nl'));\n        $this->assertFalse(isset($_SERVER['__missing_translation_key']));\n    }\n\n    public function testItCanHandleMissingKeysUsingCallback()\n    {\n        $this->app['translator']->handleMissingKeysUsing(function ($key) {\n            $_SERVER['__missing_translation_key'] = $key;\n\n            return 'callback key';\n        });\n\n        $key = $this->app['translator']->get('some missing key');\n\n        $this->assertSame('callback key', $key);\n        $this->assertSame('some missing key', $_SERVER['__missing_translation_key']);\n\n        $this->app['translator']->handleMissingKeysUsing(null);\n    }\n\n    public function testItCanHandleMissingKeysNoReturn()\n    {\n        $this->app['translator']->handleMissingKeysUsing(function ($key) {\n            $_SERVER['__missing_translation_key'] = $key;\n        });\n\n        $key = $this->app['translator']->get('some missing key');\n\n        $this->assertSame('some missing key', $key);\n        $this->assertSame('some missing key', $_SERVER['__missing_translation_key']);\n\n        $this->app['translator']->handleMissingKeysUsing(null);\n    }\n\n    public function testItReturnsCorrectLocaleForMissingKeys()\n    {\n        $this->app['translator']->handleMissingKeysUsing(function ($key, $replacements, $locale) {\n            $_SERVER['__missing_translation_key_locale'] = $locale;\n        });\n\n        $this->app['translator']->get('some missing key', [], 'ht');\n\n        $this->assertSame('ht', $_SERVER['__missing_translation_key_locale']);\n\n        $this->app['translator']->handleMissingKeysUsing(null);\n    }\n\n    public function testFileValidationDoesNotAttemptToTranslateAlreadyTranslatedMessages()\n    {\n        $keysLookedUp = [];\n\n        $this->app['translator']->handleMissingKeysUsing(function ($key) use (&$keysLookedUp) {\n            $keysLookedUp[] = $key;\n        });\n\n        $validator = $this->app['validator']->make(\n            ['file' => UploadedFile::fake()->create('file.pdf')],\n            ['file' => [File::types(['txt'])]]\n        );\n\n        $validator->fails();\n\n        $this->assertNotContains('The file field must be a file of type: txt.', $keysLookedUp);\n\n        $this->app['translator']->handleMissingKeysUsing(null);\n    }\n\n    #[DataProvider('greetingChoiceDataProvider')]\n    public function testItCanHandleChoice(int $count, string $expected, ?string $locale = null)\n    {\n        if (! is_null($locale)) {\n            $this->app->setLocale($locale);\n        }\n\n        $name = 'Taylor';\n\n        $this->assertSame(\n            strtr($expected, [':name' => $name, ':count' => $count]),\n            $this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name])\n        );\n    }\n\n    #[DataProvider('greetingChoiceDataProvider')]\n    public function testItCanHandleChoiceWithChoiceSeparatorInReplaceString(int $count, string $expected, ?string $locale = null)\n    {\n        if (! is_null($locale)) {\n            $this->app->setLocale($locale);\n        }\n\n        $name = 'Taylor | Laravel';\n\n        $this->assertSame(\n            strtr($expected, [':name' => $name, ':count' => $count]),\n            $this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name])\n        );\n    }\n\n    public static function greetingChoiceDataProvider()\n    {\n        yield [0, 'Hello :name'];\n        yield [3, 'Hello :name, you have 3 unread messages'];\n        yield [0, 'Bonjour :name', 'fr'];\n        yield [3, 'Bonjour :name, vous avez :count messages non lus', 'fr'];\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Translation/lang/en/app.php",
    "content": "<?php\n\nreturn [\n    'greeting' => '{0} Hello :name|[1,*] Hello :name, you have :count unread messages',\n];\n"
  },
  {
    "path": "tests/Integration/Translation/lang/en.json",
    "content": "{\n    \"1 Day\": \"1 Day\",\n    \"30 Days\": \"30 Days\",\n    \"365 Days\": \"365 Days\",\n    \"60 Days\": \"60 Days\",\n    \"90 Days\": \"90 Days\"\n}\n"
  },
  {
    "path": "tests/Integration/Translation/lang/fr/app.php",
    "content": "<?php\n\nreturn [\n    'greeting' => '{0} Bonjour :name|[1,*] Bonjour :name, vous avez :count messages non lus',\n];\n"
  },
  {
    "path": "tests/Integration/Translation/lang/fr.json",
    "content": "{\n    \"30 Days\": \"30 jours\",\n    \"365 Days\": \"365 jours\",\n    \"60 Days\": \"60 jours\",\n    \"90 Days\": \"90 jours\"\n}\n"
  },
  {
    "path": "tests/Integration/Validation/RequestValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Validation\\ValidationException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RequestValidationTest extends TestCase\n{\n    public function testValidateMacro(): void\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n\n        $validated = $request->validate(['name' => 'string']);\n\n        $this->assertSame(['name' => 'Taylor'], $validated);\n    }\n\n    public function testValidateMacroWhenItFails(): void\n    {\n        $this->expectException(ValidationException::class);\n\n        $request = Request::create('/', 'GET', ['name' => null]);\n\n        $request->validate(['name' => 'string']);\n    }\n\n    public function testValidateWithBagMacro(): void\n    {\n        $request = Request::create('/', 'GET', ['name' => 'Taylor']);\n\n        $validated = $request->validateWithBag('some_bag', ['name' => 'string']);\n\n        $this->assertSame(['name' => 'Taylor'], $validated);\n    }\n\n    public function testValidateWithBagMacroWhenItFails(): void\n    {\n        $request = Request::create('/', 'GET', ['name' => null]);\n\n        try {\n            $request->validateWithBag('some_bag', ['name' => 'string']);\n        } catch (ValidationException $validationException) {\n            $this->assertSame('some_bag', $validationException->errorBag);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Validation/Rules/DateFormatValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation\\Rules;\n\nuse Illuminate\\Support\\Facades\\Validator;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\nclass DateFormatValidationTest extends TestCase\n{\n    #[TestWith(['UTC'])]\n    #[TestWith(['Europe/Amsterdam'])]\n    public function test_it_can_validate_regardless_of_timezone(string $timezone): void\n    {\n        date_default_timezone_set($timezone);\n\n        $payload = ['date' => '2025-03-30 02:00:00'];\n        $rules = ['date' => 'date_format:Y-m-d H:i:s'];\n\n        $validator = Validator::make($payload, $rules);\n\n        $this->assertTrue($validator->passes());\n        $this->assertEmpty($validator->errors()->all());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Validation/Rules/EmailValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation\\Rules;\n\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Validation\\Rules\\Email;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\nclass EmailValidationTest extends TestCase\n{\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array(string $attribute): void\n    {\n        $validator = Validator::make([\n            'emails' => [\n                $attribute => 'taylor@laravel.com',\n            ],\n        ], [\n            'emails.*' => ['required', Email::default()->rfcCompliant()],\n        ]);\n\n        $this->assertTrue($validator->passes());\n    }\n\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute): void\n    {\n        $validator = Validator::make([\n            'emails' => [\n                $attribute => 'taylor[at]laravel.com',\n            ],\n        ], [\n            'emails.*' => ['required', Email::default()->rfcCompliant()],\n        ]);\n\n        $this->assertFalse($validator->passes());\n\n        $this->assertSame([\n            0 => __('validation.email', ['attribute' => sprintf('emails.%s', str_replace('_', ' ', $attribute))]),\n        ], $validator->messages()->all());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Validation/Rules/FileValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation\\Rules;\n\nuse Illuminate\\Http\\UploadedFile;\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\File;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\nclass FileValidationTest extends TestCase\n{\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array(string $attribute): void\n    {\n        $file = UploadedFile::fake()->create('laravel.png', 1, 'image/png');\n\n        $validator = Validator::make([\n            'files' => [\n                $attribute => $file,\n            ],\n        ], [\n            'files.*' => ['required', File::types(['image/png', 'image/jpeg'])],\n        ]);\n\n        $this->assertTrue($validator->passes());\n    }\n\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute): void\n    {\n        $file = UploadedFile::fake()->create('laravel.php', 1, 'image/php');\n\n        $validator = Validator::make([\n            'files' => [\n                $attribute => $file,\n            ],\n        ], [\n            'files.*' => ['required', File::types($mimes = ['image/png', 'image/jpeg'])],\n        ]);\n\n        $this->assertFalse($validator->passes());\n\n        $this->assertSame([\n            0 => __('validation.mimetypes', ['attribute' => sprintf('files.%s', str_replace('_', ' ', $attribute)), 'values' => implode(', ', $mimes)]),\n        ], $validator->messages()->all());\n    }\n\n    public function test_file_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            [\n                'one' => UploadedFile::fake()->create('photo', 1000),\n                'two' => 'not-a-file',\n            ],\n            [\n                'one' => [File::default()->max(50)],\n                'two' => [File::default()->max(50)],\n            ],\n            [\n                'one.max' => 'File one is too large',\n                'one.file' => 'File one is not a file',\n                'two.max' => 'File two is too large',\n                'two.file' => 'File two is not a file',\n            ]);\n\n        $this->assertTrue($validator->fails());\n\n        $this->assertSame([\n            'File one is too large',\n            'File two is not a file',\n        ], $validator->messages()->all());\n    }\n\n    public function test_file_mimes_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['document' => UploadedFile::fake()->create('file.pdf')],\n            ['document' => [File::types(['jpg', 'png'])]],\n            ['document.mimes' => 'Wrong file type']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Wrong file type'], $validator->messages()->all());\n    }\n\n    public function test_file_min_size_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['upload' => UploadedFile::fake()->create('small.pdf', 50)],\n            ['upload' => [File::types(['pdf'])->min(100)]],\n            ['upload.min' => 'File too small']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['File too small'], $validator->messages()->all());\n    }\n\n    public function test_file_max_size_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['upload' => UploadedFile::fake()->create('large.pdf', 2000)],\n            ['upload' => [File::types(['pdf'])->max(1024)]],\n            ['upload.max' => 'File exceeds limit']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['File exceeds limit'], $validator->messages()->all());\n    }\n\n    public function test_file_dimension_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['image' => UploadedFile::fake()->image('foo.jpg', 100, 100)],\n            ['image' => [File::image()->dimensions(Rule::dimensions()->width(50)->height(50))]],\n            ['image.dimensions' => 'Invalid dimensions']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Invalid dimensions'], $validator->messages()->all());\n    }\n\n    public function test_file_between_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['file' => UploadedFile::fake()->create('foo.pdf', 10)],\n            ['file' => [File::types(['pdf'])->between(100, 1000)]],\n            ['file.between' => 'Size out of range']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Size out of range'], $validator->messages()->all());\n    }\n\n    public function test_image_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['avatar' => UploadedFile::fake()->create('foo.txt')],\n            ['avatar' => [File::image()]],\n            ['avatar.image' => 'Not an image']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Not an image'], $validator->messages()->all());\n    }\n\n    public function test_file_multiple_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['photo' => UploadedFile::fake()->create('foo.pdf', 5000)],\n            ['photo' => [File::types(['jpg', 'png'])->max(1024)]],\n            [\n                'photo.mimes' => 'Invalid type',\n                'photo.max' => 'Too large',\n            ]\n        );\n\n        $this->assertTrue($validator->fails());\n\n        $messages = $validator->messages()->all();\n\n        $this->assertContains('Invalid type', $messages);\n        $this->assertContains('Too large', $messages);\n    }\n\n    public function test_file_size_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['file' => UploadedFile::fake()->create('doc.pdf', 500)],\n            ['file' => [File::types(['pdf'])->size(100)]],\n            ['file.size' => 'File must be exactly 100KB']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['File must be exactly 100KB'], $validator->messages()->all());\n    }\n\n    public function test_file_extensions_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['file' => UploadedFile::fake()->create('foo.pdf')],\n            ['file' => [File::default()->extensions(['txt', 'doc'])]],\n            ['file.extensions' => 'Invalid file extension']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Invalid file extension'], $validator->messages()->all());\n    }\n\n    public function test_file_encoding_custom_validation_messages()\n    {\n        $validator = Validator::make(\n            ['file' => UploadedFile::fake()->createWithContent('foo.txt', \"\\xf0\\x28\\x8c\\x28\")],\n            ['file' => [File::types(['txt'])->encoding('UTF-8')]],\n            ['file.encoding' => 'Invalid file encoding']\n        );\n\n        $this->assertTrue($validator->fails());\n        $this->assertSame(['Invalid file encoding'], $validator->messages()->all());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Validation/Rules/PasswordValidationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation\\Rules;\n\nuse Illuminate\\Support\\Facades\\Validator;\nuse Illuminate\\Validation\\Rules\\Password;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\n\nclass PasswordValidationTest extends TestCase\n{\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array(string $attribute): void\n    {\n        $validator = Validator::make([\n            'passwords' => [\n                $attribute => 'secret',\n            ],\n        ], [\n            'passwords.*' => ['required', Password::default()->min(6)],\n        ]);\n\n        $this->assertTrue($validator->passes());\n    }\n\n    #[TestWith(['0'])]\n    #[TestWith(['.'])]\n    #[TestWith(['*'])]\n    #[TestWith(['__asterisk__'])]\n    public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute): void\n    {\n        $validator = Validator::make([\n            'passwords' => [\n                $attribute => 'secret',\n            ],\n        ], [\n            'passwords.*' => ['required', Password::default()->min(8)],\n        ]);\n\n        $this->assertFalse($validator->passes());\n\n        $this->assertSame([\n            0 => sprintf('The passwords.%s field must be at least 8 characters.', str_replace('_', ' ', $attribute)),\n        ], $validator->messages()->all());\n    }\n}\n"
  },
  {
    "path": "tests/Integration/Validation/ValidatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\Validation;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Integration\\Database\\DatabaseTestCase;\nuse Illuminate\\Translation\\ArrayLoader;\nuse Illuminate\\Translation\\Translator;\nuse Illuminate\\Validation\\DatabasePresenceVerifier;\nuse Illuminate\\Validation\\Validator;\n\nclass ValidatorTest extends DatabaseTestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Schema::create('users', function (Blueprint $table) {\n            $table->increments('id');\n            $table->string('uuid');\n            $table->string('first_name');\n        });\n\n        User::create(['uuid' => (string) Str::uuid(), 'first_name' => 'John']);\n        User::create(['uuid' => (string) Str::uuid(), 'first_name' => 'Jim']);\n    }\n\n    public function testExists(): void\n    {\n        $validator = $this->getValidator(['first_name' => ['John', 'Taylor']], ['first_name' => 'exists:users']);\n        $this->assertFalse($validator->passes());\n    }\n\n    public function testUnique(): void\n    {\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:'.User::class]);\n        $this->assertFalse($validator->passes());\n\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:'.User::class.',first_name,1']);\n        $this->assertTrue($validator->passes());\n\n        $validator = $this->getValidator(['first_name' => 'Taylor'], ['first_name' => 'unique:'.User::class]);\n        $this->assertTrue($validator->passes());\n    }\n\n    public function testUniqueWithCustomModelKey(): void\n    {\n        $_SERVER['CUSTOM_MODEL_KEY_NAME'] = 'uuid';\n\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:'.UserWithUuid::class]);\n        $this->assertFalse($validator->passes());\n\n        $user = UserWithUuid::where('first_name', 'John')->first();\n\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:'.UserWithUuid::class.',first_name,'.$user->uuid]);\n        $this->assertTrue($validator->passes());\n\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:users,first_name,'.$user->uuid.',uuid']);\n        $this->assertTrue($validator->passes());\n\n        $validator = $this->getValidator(['first_name' => 'John'], ['first_name' => 'unique:users,first_name,'.$user->uuid.',id']);\n        $this->assertFalse($validator->passes());\n\n        $validator = $this->getValidator(['first_name' => 'Taylor'], ['first_name' => 'unique:'.UserWithUuid::class]);\n        $this->assertTrue($validator->passes());\n\n        unset($_SERVER['CUSTOM_MODEL_KEY_NAME']);\n    }\n\n    public function testImplicitAttributeFormatting(): void\n    {\n        $translator = new Translator(new ArrayLoader, 'en');\n        $translator->addLines(['validation.string' => ':attribute must be a string!'], 'en');\n        $validator = new Validator($translator, [['name' => 1]], ['*.name' => 'string']);\n\n        $validator->setImplicitAttributesFormatter(function ($attribute) {\n            [$line, $attribute] = explode('.', $attribute);\n\n            return sprintf('%s at line %d', $attribute, $line + 1);\n        });\n\n        $validator->passes();\n\n        $this->assertSame('name at line 1 must be a string!', $validator->getMessageBag()->all()[0]);\n    }\n\n    protected function getValidator(array $data, array $rules)\n    {\n        $translator = new Translator(new ArrayLoader, 'en');\n        $validator = new Validator($translator, $data, $rules);\n        $validator->setPresenceVerifier(new DatabasePresenceVerifier($this->app['db']));\n\n        return $validator;\n    }\n}\n\nclass User extends Model\n{\n    public $timestamps = false;\n    protected $guarded = [];\n}\n\nclass UserWithUuid extends Model\n{\n    protected $table = 'users';\n    public $timestamps = false;\n    protected $guarded = [];\n    protected $keyType = 'string';\n    public $incrementing = false;\n\n    public function getKeyName()\n    {\n        return 'uuid';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/View/BladeAnonymousComponentTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\View;\n\nuse Illuminate\\Support\\Facades\\Blade;\nuse Illuminate\\Support\\Facades\\View;\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\n\nclass BladeAnonymousComponentTest extends TestCase\n{\n    public function test_anonymous_components_with_custom_paths_can_be_rendered()\n    {\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');\n\n        $view = View::make('page')->render();\n\n        $this->assertTrue(str_contains($view, 'Panel content.'));\n        $this->assertTrue(str_contains($view, 'class=\"app-layout\"'));\n        $this->assertTrue(str_contains($view, 'class=\"danger-button\"'));\n    }\n\n    public function test_anonymous_components_with_custom_paths_cant_be_rendered_as_normal_views()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');\n\n        $view = View::make('layouts::app')->render();\n    }\n\n    public function test_anonymous_components_with_custom_paths_cant_be_rendered_as_normal_views_even_with_no_prefix()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-1', 'layouts');\n        Blade::anonymousComponentPath(__DIR__.'/anonymous-components-2');\n\n        $view = View::make('panel')->render();\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('view.paths', [__DIR__.'/anonymous-components-templates']);\n    }\n}\n"
  },
  {
    "path": "tests/Integration/View/BladeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\View;\n\nuse Illuminate\\Support\\Facades\\Blade;\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\View;\nuse Illuminate\\View\\Component;\nuse Mockery;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\RunInSeparateProcess;\nuse Symfony\\Component\\Finder\\Finder;\nuse Symfony\\Component\\Finder\\SplFileInfo;\n\nuse function Illuminate\\Filesystem\\join_paths;\nuse function Orchestra\\Testbench\\artisan;\nuse function Orchestra\\Testbench\\phpunit_version_compare;\n\nclass BladeTest extends TestCase\n{\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        artisan($this, 'view:clear');\n\n        parent::tearDown();\n    }\n\n    public function test_rendering_blade_string()\n    {\n        $this->assertSame('Hello Taylor', Blade::render('Hello {{ $name }}', ['name' => 'Taylor']));\n    }\n\n    public function test_rendering_blade_long_maxpathlen_string()\n    {\n        $longString = str_repeat('a', PHP_MAXPATHLEN);\n\n        $result = Blade::render($longString.'{{ $name }}', ['name' => 'a']);\n\n        $this->assertSame($longString.'a', $result);\n    }\n\n    #[RunInSeparateProcess]\n    public function test_rendering_blade_long_maxpathlen_string_with_exact_length()\n    {\n        // The PHP_MAXPATHLEN restriction is only active, if\n        // open_basedir is set and active. Otherwise, the check\n        // for the PHP_MAXPATHLEN is not active.\n        if (ini_get('open_basedir') === '' && phpunit_version_compare('12.1.0', '<')) {\n            $openBaseDir = explode(DIRECTORY_SEPARATOR, __DIR__)[0].DIRECTORY_SEPARATOR.PATH_SEPARATOR.sys_get_temp_dir();\n            $iniSet = ini_set(\n                'open_basedir',\n                $openBaseDir\n            );\n\n            $this->assertNotFalse($iniSet, 'Could not set config for open_basedir.');\n        }\n\n        for ($i = PHP_MAXPATHLEN - 200; $i <= PHP_MAXPATHLEN + 1; $i++) {\n            $longString = str_repeat('x', $i);\n\n            $result = Blade::render($longString);\n\n            $this->assertSame($longString, $result);\n        }\n    }\n\n    public function test_rendering_blade_component_instance()\n    {\n        $component = new HelloComponent('Taylor');\n\n        $this->assertSame('Hello Taylor', Blade::renderComponent($component));\n    }\n\n    public function test_basic_blade_rendering()\n    {\n        $view = View::make('hello', ['name' => 'Taylor'])->render();\n\n        $this->assertSame('Hello Taylor', trim($view));\n    }\n\n    public function test_rendering_a_component()\n    {\n        $view = View::make('uses-panel', ['name' => 'Taylor'])->render();\n\n        $this->assertSame('<div class=\"ml-2\">\n    Hello Taylor\n</div>', trim($view));\n    }\n\n    public function test_rendering_a_dynamic_component()\n    {\n        $view = View::make('uses-panel-dynamically', ['name' => 'Taylor'])->render();\n\n        $this->assertSame('<div class=\"ml-2\" wire:model=\"foo\" wire:model.lazy=\"bar\">\n    Hello Taylor\n</div>', trim($view));\n    }\n\n    public function test_rendering_the_same_dynamic_component_with_different_attributes()\n    {\n        $view = View::make('varied-dynamic-calls')->render();\n\n        $this->assertSame('<span class=\"text-medium\">\n    Hello Taylor\n</span>\n<span >\n    Hello Samuel\n</span>', trim($view));\n    }\n\n    public function test_inline_link_type_attributes_dont_add_extra_spacing_at_end()\n    {\n        $view = View::make('uses-link')->render();\n\n        $this->assertSame('This is a sentence with a <a href=\"https://laravel.com\">link</a>.', trim($view));\n    }\n\n    public function test_appendable_attributes()\n    {\n        $view = View::make('uses-appendable-panel', ['name' => 'Taylor', 'withInjectedValue' => true])->render();\n\n        $this->assertSame('<div class=\"mt-4 bg-gray-100\" data-controller=\"inside-controller outside-controller\" foo=\"bar\">\n    Hello Taylor\n</div>', trim($view));\n\n        $view = View::make('uses-appendable-panel', ['name' => 'Taylor', 'withInjectedValue' => false])->render();\n\n        $this->assertSame('<div class=\"mt-4 bg-gray-100\" data-controller=\"inside-controller\" foo=\"bar\">\n    Hello Taylor\n</div>', trim($view));\n    }\n\n    public function tested_nested_anonymous_attribute_proxying_works_correctly()\n    {\n        $view = View::make('uses-child-input')->render();\n\n        $this->assertSame('<input class=\"disabled-class\" foo=\"bar\" type=\"text\" disabled />', trim($view));\n    }\n\n    public function test_consume_defaults()\n    {\n        $view = View::make('consume')->render();\n\n        $this->assertSame('<h1>Menu</h1>\n<div>Slot: A, Color: orange, Default: foo</div>\n<div>Slot: B, Color: red, Default: foo</div>\n<div>Slot: C, Color: blue, Default: foo</div>\n<div>Slot: D, Color: red, Default: foo</div>\n<div>Slot: E, Color: red, Default: foo</div>\n<div>Slot: F, Color: yellow, Default: foo</div>', trim($view));\n    }\n\n    public function test_consume_with_props()\n    {\n        $view = View::make('consume', ['color' => 'rebeccapurple'])->render();\n\n        $this->assertSame('<h1>Menu</h1>\n<div>Slot: A, Color: orange, Default: foo</div>\n<div>Slot: B, Color: rebeccapurple, Default: foo</div>\n<div>Slot: C, Color: blue, Default: foo</div>\n<div>Slot: D, Color: rebeccapurple, Default: foo</div>\n<div>Slot: E, Color: rebeccapurple, Default: foo</div>\n<div>Slot: F, Color: yellow, Default: foo</div>', trim($view));\n    }\n\n    public function test_name_attribute_can_be_used_if_using_short_slot_names()\n    {\n        $content = Blade::render('<x-input-with-slot>\n    <x-slot:input name=\"my_form_field\" class=\"text-input-lg\" data-test=\"data\">Test</x-slot:input>\n</x-input-with-slot>');\n\n        $this->assertSame('<div>\n    <input type=\"text\" class=\"input text-input-lg\" data-test=\"data\" name=\"my_form_field\" />\n</div>', trim($content));\n    }\n\n    public function test_name_attribute_cant_be_used_if_not_using_short_slot_names()\n    {\n        $content = Blade::render('<x-input-with-slot>\n    <x-slot name=\"input\" class=\"text-input-lg\" data-test=\"data\">Test</x-slot>\n</x-input-with-slot>');\n\n        $this->assertSame('<div>\n    <input type=\"text\" class=\"input text-input-lg\" data-test=\"data\" />\n</div>', trim($content));\n    }\n\n    public function test_bound_name_attribute_can_be_used_if_using_short_slot_names()\n    {\n        $content = Blade::render('<x-input-with-slot>\n    <x-slot:input :name=\"\\'my_form_field\\'\" class=\"text-input-lg\" data-test=\"data\">Test</x-slot:input>\n</x-input-with-slot>');\n\n        $this->assertSame('<div>\n    <input type=\"text\" class=\"input text-input-lg\" data-test=\"data\" name=\"my_form_field\" />\n</div>', trim($content));\n    }\n\n    public function test_bound_name_attribute_can_be_used_if_using_short_slot_names_and_not_first_attribute()\n    {\n        $content = Blade::render('<x-input-with-slot>\n    <x-slot:input class=\"text-input-lg\" :name=\"\\'my_form_field\\'\" data-test=\"data\">Test</x-slot:input>\n</x-input-with-slot>');\n\n        $this->assertSame('<div>\n    <input type=\"text\" class=\"input text-input-lg\" name=\"my_form_field\" data-test=\"data\" />\n</div>', trim($content));\n    }\n\n    public function test_no_name_passed_to_slot_uses_default_name()\n    {\n        $content = Blade::render('<x-link href=\"#\"><x-slot>default slot</x-slot></x-link>');\n\n        $this->assertSame('<a href=\"#\">default slot</a>', trim($content));\n    }\n\n    public function testViewCacheCommandHandlesConfiguredBladeExtensions()\n    {\n        View::addExtension('sh', 'blade');\n        $this->artisan('view:cache');\n\n        $compiledFiles = Finder::create()->in(Config::get('view.compiled'))->files();\n        $found = collect($compiledFiles)\n            ->contains(fn (SplFileInfo $file) => str_contains($file->getContents(), 'echo \"<?php echo e($scriptMessage); ?>\" > output.log'));\n        $this->assertTrue($found);\n    }\n\n    public function test_include_scoped_does_not_inherit_parent_scope()\n    {\n        // Regular @include passes parent scope variables\n        $regularInclude = View::make('uses-include-regular', [\n            'parentVar' => 'parent-value',\n            'explicitVar' => 'explicit-value',\n        ])->render();\n\n        $this->assertSame('Parent: parent-value, Explicit: explicit-value', trim($regularInclude));\n\n        // @includeIsolated does NOT pass parent scope variables\n        $scopedInclude = View::make('uses-include-scoped', [\n            'parentVar' => 'parent-value',\n            'explicitVar' => 'explicit-value',\n        ])->render();\n\n        $this->assertSame('Parent: undefined, Explicit: explicit-value', trim($scopedInclude));\n    }\n\n    public function test_view_cache_command_deduplicates_paths_before_compiling()\n    {\n        View::addNamespace('templates', join_paths(__DIR__, 'templates'));\n        View::addNamespace('components', join_paths(__DIR__, 'templates', 'components'));\n\n        $compiler = Mockery::mock(app('blade.compiler'))->makePartial();\n        $compiler->shouldReceive('compile')->with(realpath(__DIR__.'/templates/components/panel.blade.php'))->once();\n\n        $this->instance('blade.compiler', $compiler);\n\n        $this->artisan('view:cache');\n    }\n\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('view.paths', [__DIR__.'/templates']);\n    }\n}\n\nclass HelloComponent extends Component\n{\n    public $name;\n\n    public function __construct(string $name)\n    {\n        $this->name = $name;\n    }\n\n    public function render()\n    {\n        return 'Hello {{ $name }}';\n    }\n}\n"
  },
  {
    "path": "tests/Integration/View/RenderableViewExceptionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Integration\\View;\n\nuse Exception;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Route;\nuse Illuminate\\Support\\Facades\\View;\nuse Orchestra\\Testbench\\TestCase;\n\nclass RenderableViewExceptionTest extends TestCase\n{\n    public function testRenderMethodOfExceptionThrownInViewGetsHandled()\n    {\n        Route::get('/', function () {\n            return View::make('renderable-exception');\n        });\n\n        $response = $this->get('/');\n\n        $response->assertSee('This is a renderable exception.');\n    }\n\n    protected function defineEnvironment($app)\n    {\n        $app['config']->set('view.paths', [__DIR__.'/templates']);\n    }\n}\n\nclass RenderableException extends Exception\n{\n    public function render($request)\n    {\n        return new Response('This is a renderable exception.');\n    }\n}\n"
  },
  {
    "path": "tests/Integration/View/anonymous-components-1/app.blade.php",
    "content": "<div class=\"app-layout\">\n    {{ $slot }}\n</div>\n"
  },
  {
    "path": "tests/Integration/View/anonymous-components-2/buttons/danger.blade.php",
    "content": "<div class=\"danger-button\">\n    Danger button.\n</div>\n"
  },
  {
    "path": "tests/Integration/View/anonymous-components-2/panel.blade.php",
    "content": "<div class=\"panel\">\n    {{ $slot }}\n</div>\n"
  },
  {
    "path": "tests/Integration/View/anonymous-components-templates/page.blade.php",
    "content": "<x-layouts::app>\n    <x-panel>\n        Panel content.\n\n        <x-buttons.danger />\n    </x-panel>\n</x-layouts::app>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/appendable-panel.blade.php",
    "content": "@props(['name'])\n\n<div {{ $attributes->merge(['class' => 'mt-4', 'data-controller' => $attributes->prepends('inside-controller')]) }}>\n    Hello {{ $name }}\n</div>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/base-input.blade.php",
    "content": "@props(['disabled' => false])\n\n@php\nif ($disabled) {\n    $class = 'disabled-class';\n} else {\n    $class = 'not-disabled-class';\n}\n@endphp\n\n<input {{ $attributes->merge(['class' => $class]) }} {{ $disabled ? 'disabled' : '' }} />"
  },
  {
    "path": "tests/Integration/View/templates/components/child-input.blade.php",
    "content": "<x-base-input foo=\"bar\" :attributes=\"$attributes\" />"
  },
  {
    "path": "tests/Integration/View/templates/components/hello-span.blade.php",
    "content": "@props([\n    'name',\n])\n\n<span {{ $attributes }}>\n    Hello {{ $name }}\n</span>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/input-with-slot.blade.php",
    "content": "@props([\n    'input'\n])\n\n<div>\n    <input type=\"text\" {{ $input->attributes->class('input') }} />\n</div>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/link.blade.php",
    "content": "@props(['href'])\n\n<a href=\"{{ $href }}\">{{ $slot }}</a>"
  },
  {
    "path": "tests/Integration/View/templates/components/menu-item.blade.php",
    "content": "@aware(['color' => 'red', 'default' => 'foo'])\n<div>Slot: {{ $slot }}, Color: {{ $color }}, Default: {{ $default }}</div>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/menu.blade.php",
    "content": "<h1>Menu</h1>\n<x-menu-item color=\"orange\">A</x-menu-item>\n<x-menu-item>B</x-menu-item>\n{{ $slot }}\n<x-menu-item>E</x-menu-item>\n<x-menu-item color=\"yellow\">F</x-menu-item>\n"
  },
  {
    "path": "tests/Integration/View/templates/components/panel.blade.php",
    "content": "@props(['name'])\n\n<div {{ $attributes }}>\n    Hello {{ $name }}\n</div>\n"
  },
  {
    "path": "tests/Integration/View/templates/consume.blade.php",
    "content": "@isset($color)\n\n<x-menu :color=\"$color\">\n<x-menu-item color=\"blue\">C</x-menu-item>\n<x-menu-item>D</x-menu-item>\n</x-menu>\n\n@else\n\n<x-menu>\n<x-menu-item color=\"blue\">C</x-menu-item>\n<x-menu-item>D</x-menu-item>\n</x-menu>\n\n@endisset\n"
  },
  {
    "path": "tests/Integration/View/templates/different-extension.sh",
    "content": "echo \"{{ $scriptMessage }}\" > output.log\n"
  },
  {
    "path": "tests/Integration/View/templates/hello.blade.php",
    "content": "Hello {{ $name }}\n"
  },
  {
    "path": "tests/Integration/View/templates/partials/scoped-partial.blade.php",
    "content": "Parent: {{ $parentVar ?? 'undefined' }}, Explicit: {{ $explicitVar }}"
  },
  {
    "path": "tests/Integration/View/templates/renderable-exception.blade.php",
    "content": "@php\n    throw new Illuminate\\Tests\\Integration\\View\\RenderableException;\n@endphp\n"
  },
  {
    "path": "tests/Integration/View/templates/uses-appendable-panel.blade.php",
    "content": "@if ($withInjectedValue)\n    <x-appendable-panel class=\"bg-gray-100\" :name=\"$name\" data-controller=\"outside-controller\" foo=\"bar\">\n        Panel contents\n    </x-appendable-panel>\n@else\n    <x-appendable-panel class=\"bg-gray-100\" :name=\"$name\" foo=\"bar\">\n        Panel contents\n    </x-appendable-panel>\n@endif\n"
  },
  {
    "path": "tests/Integration/View/templates/uses-child-input.blade.php",
    "content": "<x-child-input type=\"text\" :disabled=\"true\" />"
  },
  {
    "path": "tests/Integration/View/templates/uses-include-regular.blade.php",
    "content": "@include('partials.scoped-partial', ['explicitVar' => $explicitVar])"
  },
  {
    "path": "tests/Integration/View/templates/uses-include-scoped.blade.php",
    "content": "@includeIsolated('partials.scoped-partial', ['explicitVar' => $explicitVar])\n"
  },
  {
    "path": "tests/Integration/View/templates/uses-link.blade.php",
    "content": "This is a sentence with a <x-link href=\"https://laravel.com\">link</x-link>."
  },
  {
    "path": "tests/Integration/View/templates/uses-panel-dynamically.blade.php",
    "content": "<x-dynamic-component component=\"panel\" class=\"ml-2\" :name=\"$name\" wire:model=\"foo\" wire:model.lazy=\"bar\">\n    Panel contents\n</x-dynamic-component>\n"
  },
  {
    "path": "tests/Integration/View/templates/uses-panel.blade.php",
    "content": "<x-panel class=\"ml-2\" :name=\"$name\">\n    Panel contents\n</x-panel>\n"
  },
  {
    "path": "tests/Integration/View/templates/varied-dynamic-calls.blade.php",
    "content": "<x-dynamic-component component=\"hello-span\" name=\"Taylor\" class=\"text-medium\" />\n<x-dynamic-component component=\"hello-span\" name=\"Samuel\" />\n"
  },
  {
    "path": "tests/JsonSchema/ArrayTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ArrayTypeTest extends TestCase\n{\n    public function test_it_may_set_min_items(): void\n    {\n        $type = JsonSchema::array()->title('Tags')->min(1);\n\n        $this->assertEquals([\n            'type' => 'array',\n            'title' => 'Tags',\n            'minItems' => 1,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_max_items(): void\n    {\n        $type = JsonSchema::array()->description('A list of tags')->max(10);\n\n        $this->assertEquals([\n            'type' => 'array',\n            'description' => 'A list of tags',\n            'maxItems' => 10,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_items_type(): void\n    {\n        $type = JsonSchema::array()->items(\n            JsonSchema::string()->max(20)\n        );\n\n        $this->assertEquals([\n            'type' => 'array',\n            'items' => [\n                'type' => 'string',\n                'maxLength' => 20,\n            ],\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_default_value(): void\n    {\n        $type = JsonSchema::array()->default(['a', 'b']);\n\n        $this->assertEquals([\n            'type' => 'array',\n            'default' => ['a', 'b'],\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_unique_items(): void\n    {\n        $type = JsonSchema::array()->items(JsonSchema::string())->unique();\n\n        $this->assertEquals([\n            'type' => 'array',\n            'items' => [\n                'type' => 'string',\n            ],\n            'uniqueItems' => true,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_combine_unique_items_with_min_and_max(): void\n    {\n        $type = JsonSchema::array()->min(1)->max(5)->unique();\n\n        $this->assertEquals([\n            'type' => 'array',\n            'minItems' => 1,\n            'maxItems' => 5,\n            'uniqueItems' => true,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_enum(): void\n    {\n        $type = JsonSchema::array()->enum([\n            ['a'],\n            ['b', 'c'],\n        ]);\n\n        $this->assertEquals([\n            'type' => 'array',\n            'enum' => [\n                ['a'],\n                ['b', 'c'],\n            ],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/BooleanTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse PHPUnit\\Framework\\TestCase;\n\nclass BooleanTypeTest extends TestCase\n{\n    public function test_serializes_as_boolean_with_metadata(): void\n    {\n        $type = JsonSchema::boolean()->title('Enabled')->description('Feature flag');\n\n        $this->assertEquals([\n            'type' => 'boolean',\n            'title' => 'Enabled',\n            'description' => 'Feature flag',\n        ], $type->toArray());\n    }\n\n    public function test_may_set_default_true_via_default(): void\n    {\n        $type = JsonSchema::boolean()->default(true);\n\n        $this->assertEquals([\n            'type' => 'boolean',\n            'default' => true,\n        ], $type->toArray());\n    }\n\n    public function test_may_set_default_false_via_default(): void\n    {\n        $type = JsonSchema::boolean()->default(false);\n\n        $this->assertEquals([\n            'type' => 'boolean',\n            'default' => false,\n        ], $type->toArray());\n    }\n\n    public function test_may_set_enum(): void\n    {\n        $type = JsonSchema::boolean()->enum([true, false]);\n\n        $this->assertEquals([\n            'type' => 'boolean',\n            'enum' => [true, false],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/Fixtures/Enums/IntBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums;\n\nenum IntBackedEnum: int\n{\n    case One = 1;\n    case Two = 2;\n}\n"
  },
  {
    "path": "tests/JsonSchema/Fixtures/Enums/StringBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums;\n\nenum StringBackedEnum: string\n{\n    case One = 'one';\n    case Two = 'two';\n}\n"
  },
  {
    "path": "tests/JsonSchema/Fixtures/Enums/UnitEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums;\n\nenum UnitEnum\n{\n    case One;\n    case Two;\n}\n"
  },
  {
    "path": "tests/JsonSchema/IntegerTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse PHPUnit\\Framework\\TestCase;\n\nclass IntegerTypeTest extends TestCase\n{\n    public function test_it_may_set_min_value(): void\n    {\n        $type = JsonSchema::integer()->title('Age')->min(5);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'title' => 'Age',\n            'minimum' => 5,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_max_value(): void\n    {\n        $type = JsonSchema::integer()->description('Max age')->max(10);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'description' => 'Max age',\n            'maximum' => 10,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_default_value(): void\n    {\n        $type = JsonSchema::integer()->default(18);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'default' => 18,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_multiple_of(): void\n    {\n        $type = JsonSchema::integer()->multipleOf(5);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'multipleOf' => 5,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_combine_multiple_of_with_min_and_max(): void\n    {\n        $type = JsonSchema::integer()->min(0)->max(100)->multipleOf(10);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'minimum' => 0,\n            'maximum' => 100,\n            'multipleOf' => 10,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_enum(): void\n    {\n        $type = JsonSchema::integer()->enum([1, 2, 3]);\n\n        $this->assertEquals([\n            'type' => 'integer',\n            'enum' => [1, 2, 3],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/NumberTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NumberTypeTest extends TestCase\n{\n    public function test_it_may_set_min_value_as_float(): void\n    {\n        $type = JsonSchema::number()->title('Price')->min(5.5);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'title' => 'Price',\n            'minimum' => 5.5,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_min_value_as_int(): void\n    {\n        $type = JsonSchema::number()->title('Price')->min(5);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'title' => 'Price',\n            'minimum' => 5,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_max_value_as_float(): void\n    {\n        $type = JsonSchema::number()->description('Max price')->max(10.75);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'description' => 'Max price',\n            'maximum' => 10.75,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_max_value_as_int(): void\n    {\n        $type = JsonSchema::number()->description('Max price')->max(10);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'description' => 'Max price',\n            'maximum' => 10,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_default_value(): void\n    {\n        $type = JsonSchema::number()->default(9.99);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'default' => 9.99,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_multiple_of_as_float(): void\n    {\n        $type = JsonSchema::number()->multipleOf(0.5);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'multipleOf' => 0.5,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_multiple_of_as_int(): void\n    {\n        $type = JsonSchema::number()->multipleOf(3);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'multipleOf' => 3,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_combine_multiple_of_with_min_and_max(): void\n    {\n        $type = JsonSchema::number()->min(0.0)->max(10.0)->multipleOf(0.25);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'minimum' => 0.0,\n            'maximum' => 10.0,\n            'multipleOf' => 0.25,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_enum(): void\n    {\n        $type = JsonSchema::number()->enum([1, 2.5, 3]);\n\n        $this->assertEquals([\n            'type' => 'number',\n            'enum' => [1, 2.5, 3],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/ObjectTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse Illuminate\\JsonSchema\\JsonSchemaTypeFactory;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ObjectTypeTest extends TestCase\n{\n    public function test_it_may_not_have_properties(): void\n    {\n        $type = JsonSchema::object()->title('Payload');\n\n        $this->assertEquals([\n            'type' => 'object',\n            'title' => 'Payload',\n        ], $type->toArray());\n    }\n\n    public function test_it_may_be_initialized_with_a_closure_but_without_properties(): void\n    {\n        $type = JsonSchema::object(fn () => [])->title('Payload');\n\n        $this->assertEquals([\n            'type' => 'object',\n            'title' => 'Payload',\n        ], $type->toArray());\n    }\n\n    public function test_it_may_have_properties(): void\n    {\n        $type = JsonSchema::object([\n            'age-a' => JsonSchema::integer()->min(0)->required(),\n            'age-b' => JsonSchema::integer()->default(30)->max(45),\n        ])->description('Root object');\n\n        $this->assertEquals([\n            'type' => 'object',\n            'description' => 'Root object',\n            'properties' => [\n                'age-a' => [\n                    'type' => 'integer',\n                    'minimum' => 0,\n                ],\n                'age-b' => [\n                    'type' => 'integer',\n                    'default' => 30,\n                    'maximum' => 45,\n                ],\n            ],\n            'required' => ['age-a'],\n        ], $type->toArray());\n    }\n\n    public function test_it_may_be_initialized_with_a_closure_but_may_have_properties(): void\n    {\n        $type = JsonSchema::object(fn (JsonSchemaTypeFactory $schema) => [\n            'age-a' => $schema->integer()->min(0)->required(),\n            'age-b' => $schema->integer()->default(30)->max(45),\n        ])->description('Root object');\n\n        $this->assertEquals([\n            'type' => 'object',\n            'description' => 'Root object',\n            'properties' => [\n                'age-a' => [\n                    'type' => 'integer',\n                    'minimum' => 0,\n                ],\n                'age-b' => [\n                    'type' => 'integer',\n                    'default' => 30,\n                    'maximum' => 45,\n                ],\n            ],\n            'required' => ['age-a'],\n        ], $type->toArray());\n    }\n\n    public function test_it_may_disable_additional_properties(): void\n    {\n        $type = JsonSchema::object()->default(['age' => 1])->withoutAdditionalProperties();\n\n        $this->assertEquals([\n            'type' => 'object',\n            'default' => ['age' => 1],\n            'additionalProperties' => false,\n        ], $type->toArray());\n    }\n\n    public function test_it_may_set_enum(): void\n    {\n        $type = JsonSchema::object()->enum([\n            ['a' => 1],\n            ['a' => 2],\n        ]);\n\n        $this->assertEquals([\n            'type' => 'object',\n            'enum' => [\n                ['a' => 1],\n                ['a' => 2],\n            ],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/SerializerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\Types\\Type;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass SerializerTest extends TestCase\n{\n    public function test_it_does_not_know_how_to_serialize_unknown_types(): void\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unsupported [Illuminate\\\\JsonSchema\\\\Types\\\\Type@anonymous');\n\n        $type = new class extends Type {\n            // anonymous type for triggering serializer failure\n        };\n\n        $type->toArray();\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/StringTypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\Types\\StringType;\nuse PHPUnit\\Framework\\TestCase;\n\nclass StringTypeTest extends TestCase\n{\n    public function test_it_sets_min_length()\n    {\n        $type = (new StringType)->min(5);\n\n        $this->assertEquals([\n            'type' => 'string',\n            'minLength' => 5,\n        ], $type->toArray());\n    }\n\n    public function test_it_sets_max_length()\n    {\n        $type = (new StringType)->description('User handle')->max(10);\n\n        $this->assertEquals([\n            'type' => 'string',\n            'description' => 'User handle',\n            'maxLength' => 10,\n        ], $type->toArray());\n    }\n\n    public function test_it_sets_pattern()\n    {\n        $type = (new StringType)->default('foo')->pattern('^foo.*$');\n\n        $this->assertEquals([\n            'type' => 'string',\n            'default' => 'foo',\n            'pattern' => '^foo.*$',\n        ], $type->toArray());\n    }\n\n    public function test_it_sets_format()\n    {\n        $type = (new StringType)->default('foo')->format('date');\n\n        $this->assertEquals([\n            'type' => 'string',\n            'default' => 'foo',\n            'format' => 'date',\n        ], $type->toArray());\n    }\n\n    public function test_it_sets_enum()\n    {\n        $type = (new StringType)->enum(['draft', 'published']);\n\n        $this->assertEquals([\n            'type' => 'string',\n            'enum' => ['draft', 'published'],\n        ], $type->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/JsonSchema/TypeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\JsonSchema;\n\nuse Illuminate\\JsonSchema\\JsonSchema;\nuse Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums\\IntBackedEnum;\nuse Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums\\StringBackedEnum;\nuse Illuminate\\Tests\\JsonSchema\\Fixtures\\Enums\\UnitEnum;\nuse InvalidArgumentException;\nuse Opis\\JsonSchema\\Resolvers\\SchemaResolver;\nuse Opis\\JsonSchema\\SchemaLoader;\nuse Opis\\JsonSchema\\Validator;\nuse Opis\\Uri\\Uri;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\nuse Stringable;\n\nclass TypeTest extends TestCase\n{\n    public function test_as_a_array_representation(): void\n    {\n        $type = JsonSchema::object([\n            'age' => JsonSchema::integer()->min(0)->required(),\n        ])->title('User')->description('User payload')->default(['age' => 20]);\n\n        $this->assertEquals([\n            'type' => 'object',\n            'title' => 'User',\n            'description' => 'User payload',\n            'default' => ['age' => 20],\n            'properties' => [\n                'age' => [\n                    'type' => 'integer',\n                    'minimum' => 0,\n                ],\n            ],\n            'required' => ['age'],\n        ], $type->toArray());\n    }\n\n    public function test_does_have_a_string_representation(): void\n    {\n        $type = JsonSchema::object([\n            'age' => JsonSchema::integer()->min(0)->required(),\n        ])->title('User');\n\n        $this->assertSame(<<<'JSON'\n        {\n            \"title\": \"User\",\n            \"properties\": {\n                \"age\": {\n                    \"minimum\": 0,\n                    \"type\": \"integer\"\n                }\n            },\n            \"type\": \"object\",\n            \"required\": [\n                \"age\"\n            ]\n        }\n        JSON, $type->toString());\n    }\n\n    public function test_does_have_a_stringable_representation(): void\n    {\n        $type = JsonSchema::object([\n            'age' => JsonSchema::integer()->min(0)->required(),\n        ])->description('Payload');\n\n        $this->assertSame(<<<'JSON'\n        {\n            \"description\": \"Payload\",\n            \"properties\": {\n                \"age\": {\n                    \"minimum\": 0,\n                    \"type\": \"integer\"\n                }\n            },\n            \"type\": \"object\",\n            \"required\": [\n                \"age\"\n            ]\n        }\n        JSON, (string) $type);\n    }\n\n    #[DataProvider('validSchemasProvider')]\n    public function test_produces_valid_json_schemas(Stringable $schema, mixed $data): void\n    {\n        $this->assertValidOnJsonSchema($schema, $data);\n    }\n\n    #[DataProvider('invalidSchemasProvider')]\n    public function test_produces_invalid_json_schemas(Stringable $schema, mixed $data): void\n    {\n        $this->assertNotValidOnJsonSchema($schema, $data);\n    }\n\n    public function test_types_in_object_schema(): void\n    {\n        $schema = JsonSchema::object(fn (JsonSchema $schema): array => [\n            'name' => $schema->string()->required(),\n            'age' => $schema->integer()->min(0),\n        ]);\n\n        $this->assertInstanceOf(JsonSchema::class, $schema);\n    }\n\n    public function test_throws_with_invalid_enum_string(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The provided class must be a BackedEnum.');\n        $this->expectExceptionCode(0);\n\n        JsonSchema::string()->enum('NonExistentEnumClass');\n    }\n\n    public function test_throws_with_not_an_enum_class(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The provided class must be a BackedEnum.');\n        $this->expectExceptionCode(0);\n\n        JsonSchema::string()->enum(stdClass::class);\n    }\n\n    public function test_throws_with_unit_enum_class(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('The provided class must be a BackedEnum.');\n        $this->expectExceptionCode(0);\n\n        JsonSchema::string()->enum(UnitEnum::class);\n    }\n\n    public static function validSchemasProvider(): array\n    {\n        return [\n            // StringType\n            [JsonSchema::string(), 'hello'],\n            [JsonSchema::string()->min(2), 'hi'],\n            [JsonSchema::string()->max(5), 'hello'],\n            [JsonSchema::string()->pattern('^foo.*$'), 'foobar'],\n            [JsonSchema::string()->default('x'), 'x'],\n            [JsonSchema::string()->enum(['draft', 'published']), 'draft'],\n            // additional StringType cases\n            [JsonSchema::string()->min(0), ''], // empty allowed with min 0\n            [JsonSchema::string()->max(0), ''], // exactly zero length\n            [JsonSchema::string()->min(1)->max(3), 'a'], // boundary at min\n            [JsonSchema::string()->pattern('^[A-Z]{2}[0-9]{2}$'), 'AB12'], // complex pattern\n            [JsonSchema::string()->enum(['', 'x', 'y']), ''], // enum including empty string\n            [JsonSchema::string()->enum(StringBackedEnum::class), 'one'], // string backed enum cases\n            [JsonSchema::string()->nullable(), null],\n            [JsonSchema::string()->nullable(false), ''],\n\n            // IntegerType\n            [JsonSchema::integer(), 10],\n            [JsonSchema::integer()->min(0), 0],\n            [JsonSchema::integer()->max(120), 120],\n            [JsonSchema::integer()->default(18), 18],\n            [JsonSchema::integer()->enum([1, 2, 3]), 2],\n            [JsonSchema::integer()->multipleOf(5), 10],\n            [JsonSchema::integer()->multipleOf(3), 9],\n            [JsonSchema::integer()->multipleOf(7), 0],\n            // additional IntegerType cases\n            [JsonSchema::integer()->min(-5), -5], // negative boundary\n            [JsonSchema::integer()->max(10), 9], // below max\n            [JsonSchema::integer()->min(1)->max(3), 3], // boundary at max\n            [JsonSchema::integer()->enum([0, -1, 5]), 0], // enum with zero\n            [JsonSchema::integer()->enum(IntBackedEnum::class), 1], // integer backed enum cases\n            [JsonSchema::integer()->default(0), 0], // default value\n            [JsonSchema::integer()->nullable(), null],\n            [JsonSchema::integer()->nullable(false), 0],\n\n            // NumberType\n            [JsonSchema::number(), 3.14],\n            [JsonSchema::number()->min(0.0), 0.0],\n            [JsonSchema::number()->max(100.0), 99.9],\n            [JsonSchema::number()->default(9.99), 9.99],\n            [JsonSchema::number()->enum([1, 2.5, 3]), 2.5],\n            [JsonSchema::number()->multipleOf(0.5), 2.5],\n            [JsonSchema::number()->multipleOf(3), 9],\n            [JsonSchema::number()->multipleOf(0.1), 0.3],\n            // additional NumberType cases\n            [JsonSchema::number()->min(-10.5), -10.5], // negative boundary\n            [JsonSchema::number()->min(0)->max(1), 1.0], // boundary at max\n            [JsonSchema::number(), 5], // integers are numbers\n            [JsonSchema::number()->enum([0.0, 1.1]), 0.0],\n            [JsonSchema::number()->default(0.0), 0.0],\n            [JsonSchema::number()->nullable(), null],\n            [JsonSchema::number()->nullable(false), 0.0],\n\n            // BooleanType\n            [JsonSchema::boolean(), true],\n            [JsonSchema::boolean()->default(false), false],\n            [JsonSchema::boolean()->enum([true, false]), true],\n            // additional BooleanType cases\n            [JsonSchema::boolean(), false],\n            [JsonSchema::boolean()->enum([true, false]), false],\n            [JsonSchema::boolean()->enum([true]), true],\n            [JsonSchema::boolean()->enum([false]), false],\n            [JsonSchema::boolean()->default(true), true],\n            [JsonSchema::boolean()->nullable(), null],\n            [JsonSchema::boolean()->nullable(false), false],\n\n            // ObjectType\n            [\n                JsonSchema::object([\n                    'name' => JsonSchema::string()->required(),\n                    'age' => JsonSchema::integer()->min(21),\n                ]),\n                (object) ['name' => 'Nuno', 'age' => 30],\n            ],\n            [\n                JsonSchema::object([\n                    'meta' => JsonSchema::object()->withoutAdditionalProperties(),\n                ]),\n                (object) ['meta' => (object) []],\n            ],\n            [\n                JsonSchema::object([\n                    'config' => JsonSchema::object()->default(['x' => 1]),\n                ]),\n                (object) ['config' => (object) ['x' => 1]],\n            ],\n            [\n                JsonSchema::object([\n                    'status' => JsonSchema::string()->enum(['draft', 'published']),\n                ]),\n                (object) ['status' => 'published'],\n            ],\n            // additional ObjectType cases\n            [\n                JsonSchema::object([]),\n                (object) [], // empty object allowed\n            ],\n            [\n                JsonSchema::object([\n                    'name' => JsonSchema::string()->required(),\n                ]),\n                (object) ['name' => 'John'], // only required present\n            ],\n            [\n                JsonSchema::object([\n                    'meta' => JsonSchema::object()->withoutAdditionalProperties(),\n                ]),\n                (object) [], // optional property omitted\n            ],\n            [\n                JsonSchema::object([\n                    'name' => JsonSchema::string(),\n                ]),\n                (object) ['name' => 'Jane', 'extra' => 1], // additional properties allowed by default\n            ],\n            [\n                JsonSchema::object([\n                    'age' => JsonSchema::integer()->min(0),\n                ]),\n                (object) ['age' => 0], // boundary at min\n            ],\n            [\n                JsonSchema::object([\n                    'age' => JsonSchema::integer()->nullable(),\n                ]),\n                (object) ['age' => null], // nullable\n            ],\n            [\n                JsonSchema::object([\n                    'age' => JsonSchema::integer()->nullable(false),\n                ]),\n                (object) ['age' => 0], // not nullable\n            ],\n\n            // ArrayType\n            [JsonSchema::array(), []],\n            [JsonSchema::array()->min(1), ['a']],\n            [JsonSchema::array()->max(2), ['a', 'b']],\n            [JsonSchema::array()->items(JsonSchema::string()->max(3)), ['one', 'two']],\n            [JsonSchema::array()->default(['x']), ['x']],\n            [JsonSchema::array()->enum([['a'], ['b', 'c']]), ['b', 'c']],\n            [JsonSchema::array()->unique(), [1, 2, 3]],\n            [JsonSchema::array()->items(JsonSchema::string())->unique(), ['a', 'b', 'c']],\n            [JsonSchema::array()->unique(), []],\n            // additional ArrayType cases\n            [JsonSchema::array()->min(0), []], // explicit min zero\n            [JsonSchema::array()->max(0), []], // exactly zero length\n            [JsonSchema::array()->items(JsonSchema::string())->min(2)->max(2), ['a', 'b']],\n            [JsonSchema::array()->items(JsonSchema::integer()->min(0)), [0, 1, 2]],\n            [JsonSchema::array()->enum([[]]), []],\n            [JsonSchema::array()->nullable(), null],\n            [JsonSchema::array()->nullable(false), []],\n        ];\n    }\n\n    public static function invalidSchemasProvider(): array\n    {\n        return [\n            // StringType\n            [JsonSchema::string(), 123], // type mismatch\n            [JsonSchema::string()->min(3), 'hi'], // too short\n            [JsonSchema::string()->max(2), 'long'], // too long\n            [JsonSchema::string()->pattern('^foo.*$'), 'barbaz'], // pattern mismatch\n            [JsonSchema::string()->default('x'), 10], // default doesn't enforce, but data wrong type\n            [JsonSchema::string()->enum(['draft', 'published']), 'archived'], // not in enum\n            // additional StringType cases\n            [JsonSchema::string()->min(1), ''], // too short (empty)\n            [JsonSchema::string()->max(0), 'a'], // too long for zero max\n            [JsonSchema::string()->pattern('^[a]+$'), 'ab'], // pattern mismatch\n            [JsonSchema::string()->enum(['a', 'b']), 'A'], // case sensitive mismatch\n            [JsonSchema::string()->enum(StringBackedEnum::class), 'three'], // string backed enum cases mismatch\n            [JsonSchema::string(), null], // null not allowed\n            [JsonSchema::string()->nullable(false), null], // not nullable\n\n            // IntegerType\n            [JsonSchema::integer(), '10'], // type mismatch\n            [JsonSchema::integer()->min(5), 4], // below min\n            [JsonSchema::integer()->max(5), 6], // above max\n            [JsonSchema::integer()->default(1), '1'], // wrong type\n            [JsonSchema::integer()->enum([1, 2, 3]), 4], // not in enum\n            [JsonSchema::integer()->multipleOf(5), 7], // not a multiple\n            [JsonSchema::integer()->multipleOf(3), 10], // not a multiple\n            // additional IntegerType cases\n            [JsonSchema::integer()->min(0), -1], // below min boundary\n            [JsonSchema::integer()->max(0), 1], // above max boundary\n            [JsonSchema::integer(), 3.14], // not an integer\n            [JsonSchema::integer()->enum([1, 2]), 2.5], // not in enum and not an integer\n            [JsonSchema::integer()->enum(IntBackedEnum::class), 3], // integer backed enum cases mismatch\n            [JsonSchema::integer()->default(1), null], // wrong type\n            [JsonSchema::integer()->nullable(false), null], // not nullable\n\n            // NumberType\n            [JsonSchema::number(), '3.14'], // type mismatch\n            [JsonSchema::number()->min(0.5), 0.4], // below min\n            [JsonSchema::number()->max(1.5), 1.6], // above max\n            [JsonSchema::number()->default(1.1), '1.1'], // wrong type\n            [JsonSchema::number()->enum([1, 2.5, 3]), 4], // not in enum\n            [JsonSchema::number()->multipleOf(0.5), 1.3], // not a multiple\n            [JsonSchema::number()->multipleOf(3), 10], // not a multiple\n            // additional NumberType cases\n            [JsonSchema::number()->min(0), -0.0001], // below min\n            [JsonSchema::number()->max(10), 10.0001], // above max\n            [JsonSchema::number(), 'NaN'], // string, not number\n            [JsonSchema::number()->enum([1.1, 2.2]), 1.1000001], // not exactly in enum\n            [JsonSchema::number()->default(0.0), []], // wrong type\n            [JsonSchema::number()->nullable(false), null], // not nullable\n\n            // BooleanType\n            [JsonSchema::boolean(), 'true'], // type mismatch\n            [JsonSchema::boolean()->default(false), 0], // wrong type\n            [JsonSchema::boolean()->enum([true, false]), null], // not in enum\n            // additional BooleanType cases\n            [JsonSchema::boolean()->enum([true]), false], // not in enum\n            [JsonSchema::boolean()->enum([false]), true], // not in enum\n            [JsonSchema::boolean(), 1], // wrong type\n            [JsonSchema::boolean()->default(true), 'true'], // wrong type\n            [JsonSchema::boolean(), null], // null is invalid\n            [JsonSchema::boolean()->nullable(false), null], // not nullable\n\n            // ObjectType\n            [JsonSchema::object(['name' => JsonSchema::string()->required()]), (object) []], // missing required\n            [JsonSchema::object(['meta' => JsonSchema::object()->withoutAdditionalProperties()]), (object) ['meta' => (object) ['x' => 1]]], // additional prop not allowed\n            [JsonSchema::object(['age' => JsonSchema::integer()->min(21)]), (object) ['age' => 18]], // below min in nested schema\n            // additional ObjectType cases\n            [JsonSchema::object([])->withoutAdditionalProperties(), (object) ['x' => 1]], // no additional properties allowed\n            [JsonSchema::object(['name' => JsonSchema::string()]), (object) ['name' => 123]], // wrong type for property\n            [JsonSchema::object(['meta' => JsonSchema::object()->withoutAdditionalProperties()]), (object) ['meta' => 'nope']], // wrong type in nested object\n            [JsonSchema::object(['name' => JsonSchema::string()->required()])->default(['name' => 'x']), (object) []], // default doesn't satisfy missing required\n            [JsonSchema::object(['score' => JsonSchema::integer()->min(0)]), (object) ['score' => -1]], // below min\n            [JsonSchema::object(['age' => JsonSchema::integer()->nullable(false)]), (object) ['age' => null]], // not nullable\n\n            // ArrayType\n            [JsonSchema::array(), (object) []], // type mismatch\n            [JsonSchema::array()->min(2), ['a']], // too few items\n            [JsonSchema::array()->max(1), ['a', 'b']], // too many items\n            [JsonSchema::array()->items(JsonSchema::string()->max(3)), ['four']], // item too long\n            [JsonSchema::array()->enum([['a'], ['b', 'c']]), ['c', 'd']], // not in enum\n            [JsonSchema::array()->unique(), [1, 1, 2]],\n            [JsonSchema::array()->items(JsonSchema::string())->unique(), ['a', 'b', 'a']],\n            // additional ArrayType cases\n            [JsonSchema::array()->items(JsonSchema::integer()), ['a']], // wrong item type\n            [JsonSchema::array()->min(1), []], // too few\n            [JsonSchema::array()->max(0), ['a']], // too many for zero max\n            [JsonSchema::array()->enum([['a'], ['b']]), ['a', 'b']], // not equal to any enum member\n            [JsonSchema::array()->items(JsonSchema::string()->max(1)), ['ab']], // item too long\n            [JsonSchema::array()->nullable(false), null], // not nullable\n        ];\n    }\n\n    protected function makeValidator(): Validator\n    {\n        $loader = new SchemaLoader;\n        $resolver = new SchemaResolver;\n\n        $loader->setResolver($resolver);\n        $resolver->registerProtocol('https', function (Uri $uri) {\n            return file_get_contents($uri->__toString());\n        });\n\n        return new Validator($loader);\n    }\n\n    protected function assertValidOnJsonSchema(Stringable $schema, mixed $data): void\n    {\n        $validator = $this->makeValidator();\n        $result = $validator->validate($data, (string) $schema);\n        $errorMessage = $result->error()?->message() ?? 'The JSON schema is valid.';\n        $this->assertTrue($result->isValid(), $errorMessage);\n    }\n\n    protected function assertNotValidOnJsonSchema(Stringable $schema, mixed $data): void\n    {\n        $validator = $this->makeValidator();\n        $result = $validator->validate($data, (string) $schema);\n        $this->assertFalse($result->isValid());\n    }\n}\n"
  },
  {
    "path": "tests/Log/ContextTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Log;\n\nuse Exception;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Log\\ContextLogProcessor;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Foundation\\Testing\\LazilyRefreshDatabase;\nuse Illuminate\\Log\\Context\\Events\\ContextDehydrating as Dehydrating;\nuse Illuminate\\Log\\Context\\Events\\ContextHydrated as Hydrated;\nuse Illuminate\\Log\\Context\\Repository;\nuse Illuminate\\Support\\Facades\\Context;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse Monolog\\LogRecord;\nuse Orchestra\\Testbench\\TestCase;\nuse RuntimeException;\n\nclass ContextTest extends TestCase\n{\n    use LazilyRefreshDatabase;\n\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        MyAddContextProcessor::$wasConstructed = false;\n\n        parent::tearDown();\n    }\n\n    public function test_it_can_set_values()\n    {\n        $values = [\n            'string' => 'string',\n            'bool' => false,\n            'int' => 5,\n            'float' => 5.5,\n            'null' => null,\n            'array' => [1, 2, 3],\n            'hash' => ['foo' => 'bar'],\n            'object' => (object) ['foo' => 'bar'],\n            'enum' => Suit::Clubs,\n            'backed_enum' => StringBackedSuit::Clubs,\n        ];\n\n        foreach ($values as $type => $value) {\n            Context::add($type, $value);\n        }\n\n        foreach ($values as $type => $value) {\n            $this->assertSame($value, Context::get($type));\n        }\n    }\n\n    public function test_it_can_add_values_when_not_already_present()\n    {\n        Context::addIf('foo', 1);\n        $this->assertSame(1, Context::get('foo'));\n\n        Context::addIf('foo', 2);\n        $this->assertSame(1, Context::get('foo'));\n    }\n\n    public function test_it_can_listen_to_the_hydrating_event()\n    {\n        Context::add('one', 1);\n        Context::add('two', 2);\n        Context::hydrated(function (Repository $context) {\n            Context::add('two', 99);\n            Context::add('three', 3);\n        });\n        Event::dispatch(new Hydrated(Context::getFacadeRoot()));\n\n        $this->assertSame(1, Context::get('one'));\n        $this->assertSame(99, Context::get('two'));\n        $this->assertSame(3, Context::get('three'));\n    }\n\n    public function test_it_can_listen_to_the_dehydrated_event()\n    {\n        Context::add('one', 1);\n        Context::add('two', 2);\n        Context::dehydrating(function (Repository $context) {\n            Context::add('two', 99);\n            Context::add('three', 3);\n        });\n        Event::dispatch(new Dehydrating(Context::getFacadeRoot()));\n\n        $this->assertSame(1, Context::get('one'));\n        $this->assertSame(99, Context::get('two'));\n        $this->assertSame(3, Context::get('three'));\n    }\n\n    public function test_it_can_modify_context_while_dehydrating_without_impacting_global_instance()\n    {\n        Context::add('one', 1);\n        Context::dehydrating(function (Repository $context) {\n            $context->add('one', 99);\n        });\n\n        $dehydrated = Context::dehydrate();\n        $this->assertSame(1, Context::get('one'));\n\n        Context::hydrate($dehydrated);\n        $this->assertSame(99, Context::get('one'));\n    }\n\n    public function test_dehydrate_returns_null_when_empty()\n    {\n        $this->assertNull(Context::dehydrate());\n    }\n\n    public function test_hydrating_null_triggers_hydrating_event()\n    {\n        $called = false;\n        Context::hydrated(function () use (&$called) {\n            $called = true;\n        });\n\n        Context::hydrate(null);\n\n        $this->assertTrue($called);\n    }\n\n    public function test_it_can_serialize_values()\n    {\n        Context::add([\n            'string' => 'string',\n            'bool' => false,\n            'int' => 5,\n            'float' => 5.5,\n            'null' => null,\n            'array' => [1, 2, 3],\n            'hash' => ['foo' => 'bar'],\n            'object' => (object) ['foo' => 'bar'],\n            'enum' => Suit::Clubs,\n            'backed_enum' => StringBackedSuit::Clubs,\n        ]);\n        Context::addHidden('number', 55);\n\n        $dehydrated = Context::dehydrate();\n\n        $this->assertSame([\n            'data' => [\n                'string' => 's:6:\"string\";',\n                'bool' => 'b:0;',\n                'int' => 'i:5;',\n                'float' => 'd:5.5;',\n                'null' => 'N;',\n                'array' => 'a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}',\n                'hash' => 'a:1:{s:3:\"foo\";s:3:\"bar\";}',\n                'object' => 'O:8:\"stdClass\":1:{s:3:\"foo\";s:3:\"bar\";}',\n                'enum' => 'E:31:\"Illuminate\\Tests\\Log\\Suit:Clubs\";',\n                'backed_enum' => 'E:43:\"Illuminate\\Tests\\Log\\StringBackedSuit:Clubs\";',\n            ],\n            'hidden' => [\n                'number' => 'i:55;',\n            ],\n        ], $dehydrated);\n\n        Context::flush();\n        $this->assertNull(Context::get('string'));\n\n        Context::hydrate($dehydrated);\n\n        $this->assertSame(Context::get('string'), 'string');\n        $this->assertSame(Context::get('bool'), false);\n        $this->assertSame(Context::get('int'), 5);\n        $this->assertSame(Context::get('float'), 5.5);\n        $this->assertSame(Context::get('null'), null);\n        $this->assertSame(Context::get('array'), [1, 2, 3]);\n        $this->assertSame(Context::get('hash'), ['foo' => 'bar']);\n        $this->assertEquals(Context::get('object'), (object) ['foo' => 'bar']);\n        $this->assertSame(Context::get('enum'), Suit::Clubs);\n        $this->assertSame(Context::get('backed_enum'), StringBackedSuit::Clubs);\n        $this->assertSame(Context::getHidden('number'), 55);\n    }\n\n    public function test_it_can_push_to_list()\n    {\n        Context::push('breadcrumbs', 'foo');\n        Context::push('breadcrumbs', 'bar');\n        Context::push('breadcrumbs', 'baz', 'qux');\n\n        $this->assertSame(['foo', 'bar', 'baz', 'qux'], Context::get('breadcrumbs'));\n    }\n\n    public function test_throws_when_pushing_to_non_array()\n    {\n        Context::add('breadcrumbs', 'foo');\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to push value onto context stack for key [breadcrumbs].');\n        Context::push('breadcrumbs', 'bar');\n    }\n\n    public function test_throws_when_pushing_to_non_list_array()\n    {\n        Context::add('breadcrumbs', ['foo' => 'bar']);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to push value onto context stack for key [breadcrumbs].');\n        Context::push('breadcrumbs', 'bar');\n    }\n\n    public function test_it_can_pop_from_list()\n    {\n        Context::push('breadcrumbs', 'foo', 'bar');\n\n        $this->assertSame('bar', Context::pop('breadcrumbs'));\n        $this->assertSame('foo', Context::pop('breadcrumbs'));\n        $this->assertSame([], Context::get('breadcrumbs'));\n    }\n\n    public function test_throws_when_popping_from_empty_list()\n    {\n        Context::push('breadcrumbs', 'bar');\n        Context::pop('breadcrumbs');\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to pop value from context stack for key [breadcrumbs].');\n\n        Context::pop('breadcrumbs');\n    }\n\n    public function test_throws_when_popping_from_non_list_array()\n    {\n        Context::add('breadcrumbs', ['foo' => 'bar']);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to pop value from context stack for key [breadcrumbs].');\n        Context::pop('breadcrumbs');\n    }\n\n    public function test_it_can_pop_from_hidden_list()\n    {\n        Context::pushHidden('breadcrumbs', 'foo', 'bar');\n\n        $this->assertSame('bar', Context::popHidden('breadcrumbs'));\n        $this->assertSame('foo', Context::popHidden('breadcrumbs'));\n        $this->assertSame([], Context::getHidden('breadcrumbs'));\n    }\n\n    public function test_throws_when_popping_from_empty_hidden_list()\n    {\n        Context::pushHidden('breadcrumbs', 'bar');\n        Context::popHidden('breadcrumbs');\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to pop value from hidden context stack for key [breadcrumbs].');\n\n        Context::popHidden('breadcrumbs');\n    }\n\n    public function test_throws_when_popping_from_hidden_non_list_array()\n    {\n        Context::addHidden('breadcrumbs', ['foo' => 'bar']);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to pop value from hidden context stack for key [breadcrumbs].');\n        Context::popHidden('breadcrumbs');\n    }\n\n    public function test_it_can_check_if_context_has_been_set()\n    {\n        Context::add('foo', 'bar');\n        Context::add('null', null);\n\n        $this->assertTrue(Context::has('foo'));\n        $this->assertTrue(Context::has('null'));\n        $this->assertFalse(Context::has('unset'));\n    }\n\n    public function test_it_can_check_if_context_is_missing()\n    {\n        Context::add('foo', 'bar');\n\n        $this->assertTrue(Context::missing('lorem'));\n        $this->assertFalse(Context::missing('foo'));\n    }\n\n    public function test_it_can_check_if_value_is_in_context_stack()\n    {\n        Context::push('foo', 'bar', 'lorem');\n\n        $this->assertTrue(Context::stackContains('foo', 'bar'));\n        $this->assertTrue(Context::stackContains('foo', 'lorem'));\n        $this->assertFalse(Context::stackContains('foo', 'doesNotExist'));\n    }\n\n    public function test_it_can_check_if_value_is_in_context_stack_with_closures()\n    {\n        Context::push('foo', 'bar', ['lorem'], 123);\n        Context::pushHidden('baz');\n\n        $this->assertTrue(Context::stackContains('foo', fn ($value) => $value === 'bar'));\n        $this->assertFalse(Context::stackContains('foo', fn ($value) => $value === 'baz'));\n    }\n\n    public function test_it_can_check_if_value_is_in_hidden_context_stack()\n    {\n        Context::pushHidden('foo', 'bar', 'lorem');\n\n        $this->assertTrue(Context::hiddenStackContains('foo', 'bar'));\n        $this->assertTrue(Context::hiddenStackContains('foo', 'lorem'));\n        $this->assertFalse(Context::hiddenStackContains('foo', 'doesNotExist'));\n    }\n\n    public function test_it_can_check_if_value_is_in_hidden_context_stack_with_closures()\n    {\n        Context::pushHidden('foo', 'baz');\n        Context::push('foo', 'bar', ['lorem'], 123);\n\n        $this->assertTrue(Context::hiddenStackContains('foo', fn ($value) => $value === 'baz'));\n        $this->assertFalse(Context::hiddenStackContains('foo', fn ($value) => $value === 'bar'));\n    }\n\n    public function test_it_cannot_check_if_hidden_value_is_in_non_hidden_context_stack()\n    {\n        Context::pushHidden('foo', 'bar', 'lorem');\n\n        $this->assertFalse(Context::stackContains('foo', 'bar'));\n    }\n\n    public function test_it_can_get_all_values()\n    {\n        Context::add('foo', 'bar');\n        Context::add('null', null);\n\n        $this->assertSame([\n            'foo' => 'bar',\n            'null' => null,\n        ], Context::all());\n    }\n\n    public function test_it_silently_ignores_unset_values()\n    {\n        $this->assertNull(Context::get('foo'));\n        $this->assertFalse(Context::has('foo'));\n        $this->assertSame([], Context::all());\n    }\n\n    public function test_it_is_simple_key_value_system()\n    {\n        Context::add('parent.child', 5);\n\n        $this->assertNull(Context::get('parent'));\n        $this->assertSame(5, Context::get('parent.child'));\n    }\n\n    public function test_it_can_retrieve_subset_of_context()\n    {\n        Context::add('parent.child.1', 5);\n        Context::add('parent.child.2', 6);\n        Context::add('another', 7);\n\n        $this->assertSame([\n            'parent.child.1' => 5,\n            'parent.child.2' => 6,\n        ], Context::only([\n            'parent.child.1',\n            'parent.child.2',\n        ]));\n    }\n\n    public function test_it_can_exclude_subset_of_context()\n    {\n        Context::add('parent.child.1', 5);\n        Context::add('parent.child.2', 6);\n        Context::add('another', 7);\n\n        $this->assertSame([\n            'another' => 7,\n        ], Context::except([\n            'parent.child.1',\n            'parent.child.2',\n        ]));\n    }\n\n    public function test_it_can_exclude_subset_of_hidden_context()\n    {\n        Context::addHidden('parent.child.1', 5);\n        Context::addHidden('parent.child.2', 6);\n        Context::addHidden('another', 7);\n\n        $this->assertSame([\n            'another' => 7,\n        ], Context::exceptHidden([\n            'parent.child.1',\n            'parent.child.2',\n        ]));\n    }\n\n    public function test_it_adds_context_to_logging()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n        Str::createUuidsUsingSequence(['expected-trace-id']);\n\n        Context::add('trace_id', Str::uuid());\n        Context::add('foo.bar', 123);\n        Context::push('bar.baz', 456);\n        Context::push('bar.baz', 789);\n\n        Log::channel('single')->info('My name is {name}', [\n            'name' => 'Tim',\n            'framework' => 'Laravel',\n        ]);\n        $log = Str::after(file_get_contents(storage_path('logs/laravel.log')), '] ');\n\n        $this->assertSame('testing.INFO: My name is Tim {\"name\":\"Tim\",\"framework\":\"Laravel\"} {\"trace_id\":\"expected-trace-id\",\"foo.bar\":123,\"bar.baz\":[456,789]}', trim($log));\n\n        file_put_contents($path, '');\n        Str::createUuidsNormally();\n    }\n\n    public function test_it_doesnt_override_log_instance_context()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n        Str::createUuidsUsingSequence(['expected-trace-id']);\n\n        Context::add('name', 'James');\n\n        Log::channel('single')->info('My name is {name}', [\n            'name' => 'Tim',\n        ]);\n        $log = Str::after(file_get_contents($path), '] ');\n\n        $this->assertSame('testing.INFO: My name is Tim {\"name\":\"Tim\"} {\"name\":\"James\"}', trim($log));\n\n        file_put_contents($path, '');\n        Str::createUuidsNormally();\n    }\n\n    public function test_it_doesnt_allow_context_to_be_used_as_parameters()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n        Str::createUuidsUsingSequence(['expected-trace-id']);\n\n        Context::add('name', 'James');\n\n        Log::channel('single')->info('My name is {name}');\n        $log = Str::after(file_get_contents($path), '] ');\n\n        $this->assertSame('testing.INFO: My name is {name}  {\"name\":\"James\"}', trim($log));\n\n        file_put_contents($path, '');\n        Str::createUuidsNormally();\n    }\n\n    public function test_does_not_add_hidden_context_to_logging()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n        Str::createUuidsUsingSequence(['expected-trace-id']);\n\n        Context::addHidden('hidden_data', 'hidden_data');\n\n        Log::channel('single')->info('My name is {name}', [\n            'name' => 'Tim',\n            'framework' => 'Laravel',\n        ]);\n        $log = Str::after(file_get_contents($path), '] ');\n\n        $this->assertStringNotContainsString('hidden_data', trim($log));\n\n        file_put_contents($path, '');\n        Str::createUuidsNormally();\n    }\n\n    public function test_it_can_add_hidden()\n    {\n        Context::addHidden('foo', 'data');\n\n        $this->assertFalse(Context::has('foo'));\n        $this->assertTrue(Context::hasHidden('foo'));\n        $this->assertNull(Context::get('foo'));\n        $this->assertSame('data', Context::getHidden('foo'));\n        $this->assertSame(['foo' => 'data'], Context::onlyHidden(['foo']));\n\n        Context::forgetHidden('foo');\n\n        $this->assertFalse(Context::has('foo'));\n        $this->assertFalse(Context::hasHidden('foo'));\n        $this->assertNull(Context::get('foo'));\n        $this->assertNull(Context::getHidden('foo'));\n\n        Context::pushHidden('foo', 1);\n        Context::pushHidden('foo', 2);\n        $this->assertSame([1, 2], Context::getHidden('foo'));\n\n        Context::addHidden('foo', 'bar');\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Unable to push value onto hidden context stack for key [foo].');\n        Context::pushHidden('foo', 2);\n    }\n\n    public function test_it_can_pull()\n    {\n        Context::add('foo', 'data');\n\n        $this->assertSame('data', Context::pull('foo'));\n        $this->assertNull(Context::get('foo'));\n\n        Context::addHidden('foo', 'data');\n\n        $this->assertSame('data', Context::pullHidden('foo'));\n        $this->assertNull(Context::getHidden('foo'));\n    }\n\n    public function test_it_adds_context_to_logged_exceptions()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n        Str::createUuidsUsingSequence(['expected-trace-id']);\n\n        Context::add('trace_id', Str::uuid());\n        Context::add('foo.bar', 123);\n        Context::push('bar.baz', 456);\n        Context::push('bar.baz', 789);\n\n        $this->app[ExceptionHandler::class]->report(new Exception('Whoops!'));\n        $log = Str::after(file_get_contents($path), '] ');\n\n        $this->assertStringEndsWith(' {\"trace_id\":\"expected-trace-id\",\"foo.bar\":123,\"bar.baz\":[456,789]}', trim($log));\n\n        file_put_contents($path, '');\n        Str::createUuidsNormally();\n    }\n\n    public function test_scope_sets_keys_and_restores()\n    {\n        $contextInClosure = [];\n        $callback = function () use (&$contextInClosure) {\n            $contextInClosure = ['data' => Context::all(), 'hidden' => Context::allHidden()];\n\n            throw new Exception('test_with_sets_keys_and_restores');\n        };\n\n        Context::add('key1', 'value1');\n        Context::add('key2', 123);\n        Context::addHidden([\n            'hiddenKey1' => 'hello',\n            'hiddenKey2' => 'world',\n        ]);\n\n        try {\n            Context::scope(\n                $callback,\n                ['key1' => 'with', 'key3' => 'also-with'],\n                ['hiddenKey3' => 'foobar'],\n            );\n\n            $this->fail('No exception was thrown.');\n        } catch (Exception) {\n        }\n\n        $this->assertEqualsCanonicalizing([\n            'data' => [\n                'key1' => 'with',\n                'key2' => 123,\n                'key3' => 'also-with',\n            ],\n            'hidden' => [\n                'hiddenKey1' => 'hello',\n                'hiddenKey2' => 'world',\n                'hiddenKey3' => 'foobar',\n            ],\n        ], $contextInClosure);\n\n        $this->assertEqualsCanonicalizing([\n            'key1' => 'value1',\n            'key2' => 123,\n        ], Context::all());\n        $this->assertEqualsCanonicalizing([\n            'hiddenKey1' => 'hello',\n            'hiddenKey2' => 'world',\n        ], Context::allHidden());\n    }\n\n    public function test_uses_closure_for_context_processor()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n\n        $this->app->bind(\n            ContextLogProcessor::class,\n            fn () => function (LogRecord $record): LogRecord {\n                $logChannel = Context::getHidden('log_channel_name');\n\n                return $record->with(\n                    // allow overriding the context from what's been set on the log\n                    context: array_merge(Context::all(), $record->context),\n                    // use the log channel we've set in context, or fallback to the current channel\n                    channel: $logChannel ?? $record->channel,\n                );\n            }\n        );\n\n        Context::addHidden('log_channel_name', 'closure-test');\n        Context::add(['value_from_context' => 'hello']);\n\n        Log::info('This is an info log.', ['value_from_log_info_context' => 'foo']);\n\n        $log = Str::after(file_get_contents($path), '] ');\n        $this->assertSame('closure-test.INFO: This is an info log. {\"value_from_context\":\"hello\",\"value_from_log_info_context\":\"foo\"}', Str::trim($log));\n        file_put_contents($path, '');\n    }\n\n    public function test_can_rebind_to_separate_class()\n    {\n        $path = storage_path('logs/laravel.log');\n        file_put_contents($path, '');\n\n        $this->app->bind(ContextLogProcessor::class, MyAddContextProcessor::class);\n\n        Context::add(['this-will-be-included' => false]);\n\n        Log::info('This is an info log.', ['value_from_log_info_context' => 'foo']);\n        $log = Str::after(file_get_contents($path), '] ');\n        $this->assertSame(\n            'testing.INFO: This is an info log. {\"value_from_log_info_context\":\"foo\",\"inside of MyAddContextProcessor\":true}',\n            Str::trim($log)\n        );\n        $this->assertTrue(MyAddContextProcessor::$wasConstructed);\n\n        file_put_contents($path, '');\n    }\n\n    public function test_it_increments_a_counter()\n    {\n        Context::increment('foo');\n        $this->assertSame(1, Context::get('foo'));\n\n        Context::increment('foo');\n        $this->assertSame(2, Context::get('foo'));\n    }\n\n    public function test_it_custom_increments_a_counter()\n    {\n        Context::increment('foo', 2);\n        $this->assertSame(2, Context::get('foo'));\n\n        Context::increment('foo', 3);\n        $this->assertSame(5, Context::get('foo'));\n    }\n\n    public function test_it_decrements_a_counter()\n    {\n        Context::increment('foo');\n        Context::decrement('foo');\n        $this->assertSame(0, Context::get('foo'));\n    }\n\n    public function test_it_custom_decrements_a_counter()\n    {\n        Context::increment('foo', 2);\n        Context::decrement('foo', 2);\n        $this->assertSame(0, Context::get('foo'));\n    }\n\n    public function test_it_remembers_a_value()\n    {\n        $this->assertSame(1, Context::remember('int', 1));\n\n        $closureRunCount = 0;\n        $closure = function () use (&$closureRunCount) {\n            $closureRunCount++;\n\n            return 'bar';\n        };\n\n        $this->assertSame('bar', Context::remember('foo', $closure));\n        $this->assertSame('bar', Context::get('foo'));\n\n        Context::remember('foo', $closure);\n        $this->assertSame(1, $closureRunCount);\n    }\n\n    public function test_it_remembers_a_hidden_value()\n    {\n        $this->assertSame(1, Context::rememberHidden('int', 1));\n\n        $closureRunCount = 0;\n        $closure = function () use (&$closureRunCount) {\n            $closureRunCount++;\n\n            return 'bar';\n        };\n\n        $this->assertSame('bar', Context::rememberHidden('foo', $closure));\n        $this->assertSame('bar', Context::getHidden('foo'));\n\n        Context::rememberHidden('foo', $closure);\n        $this->assertSame(1, $closureRunCount);\n    }\n}\n\nenum Suit\n{\n    case Hearts;\n    case Diamonds;\n    case Clubs;\n    case Spades;\n}\n\nenum StringBackedSuit: string\n{\n    case Hearts = 'hearts';\n    case Diamonds = 'diamonds';\n    case Clubs = 'clubs';\n    case Spades = 'spades';\n}\n\nclass ContextModel extends Model\n{\n    //\n}\n\nclass MyAddContextProcessor implements ContextLogProcessor\n{\n    public static bool $wasConstructed = false;\n\n    public function __construct()\n    {\n        self::$wasConstructed = true;\n    }\n\n    #[\\Override]\n    public function __invoke(LogRecord $record): LogRecord\n    {\n        return $record->with(context: array_merge($record->context, ['inside of MyAddContextProcessor' => true]));\n    }\n}\n"
  },
  {
    "path": "tests/Log/LogLoggerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Log;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Log\\Events\\MessageLogged;\nuse Illuminate\\Log\\Logger;\nuse Mockery as m;\nuse Monolog\\Handler\\TestHandler;\nuse Monolog\\Level;\nuse Monolog\\Logger as Monolog;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass LogLoggerTest extends TestCase\n{\n    public function testMethodsPassErrorAdditionsToMonolog()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class));\n        $monolog->shouldReceive('isHandling')->with('error')->andReturn(true);\n        $monolog->shouldReceive('error')->once()->with('foo', []);\n\n        $writer->error('foo');\n    }\n\n    public function testContextIsAddedToAllSubsequentLogs()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class));\n        $writer->withContext(['bar' => 'baz']);\n\n        $monolog->shouldReceive('isHandling')->with('error')->andReturn(true);\n        $monolog->shouldReceive('error')->once()->with('foo', ['bar' => 'baz']);\n\n        $writer->error('foo');\n    }\n\n    public function testContextIsFlushed()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class));\n        $writer->withContext(['bar' => 'baz']);\n        $writer->withoutContext();\n\n        $monolog->shouldReceive('isHandling')->with('error')->andReturn(true);\n        $monolog->expects('error')->with('foo', []);\n\n        $writer->error('foo');\n    }\n\n    public function testContextKeysCanBeRemovedForSubsequentLogs()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class));\n        $writer->withContext(['bar' => 'baz', 'forget' => 'me']);\n        $writer->withoutContext(['forget']);\n\n        $monolog->shouldReceive('isHandling')->with('error')->andReturn(true);\n        $monolog->shouldReceive('error')->once()->with('foo', ['bar' => 'baz']);\n\n        $writer->error('foo');\n    }\n\n    public function testLoggerFiresEventsDispatcher()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class), $events = new Dispatcher);\n        $monolog->shouldReceive('isHandling')->with('error')->andReturn(true);\n        $monolog->shouldReceive('error')->once()->with('foo', []);\n\n        $events->listen(MessageLogged::class, function ($event) {\n            $_SERVER['__log.level'] = $event->level;\n            $_SERVER['__log.message'] = $event->message;\n            $_SERVER['__log.context'] = $event->context;\n        });\n\n        $writer->error('foo');\n        $this->assertTrue(isset($_SERVER['__log.level']));\n        $this->assertSame('error', $_SERVER['__log.level']);\n        unset($_SERVER['__log.level']);\n        $this->assertTrue(isset($_SERVER['__log.message']));\n        $this->assertSame('foo', $_SERVER['__log.message']);\n        unset($_SERVER['__log.message']);\n        $this->assertTrue(isset($_SERVER['__log.context']));\n        $this->assertEquals([], $_SERVER['__log.context']);\n        unset($_SERVER['__log.context']);\n    }\n\n    public function testListenShortcutFailsWithNoDispatcher()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Events dispatcher has not been set.');\n\n        $writer = new Logger(m::mock(Monolog::class));\n        $writer->listen(function () {\n            //\n        });\n    }\n\n    public function testListenShortcut()\n    {\n        $writer = new Logger(m::mock(Monolog::class), $events = m::mock(DispatcherContract::class));\n\n        $callback = function () {\n            return 'success';\n        };\n        $events->shouldReceive('listen')->with(MessageLogged::class, $callback)->once();\n\n        $writer->listen($callback);\n    }\n\n    public function testComplexContextManipulation()\n    {\n        $writer = new Logger($monolog = m::mock(Monolog::class));\n\n        $writer->withContext(['user_id' => 123, 'action' => 'login']);\n        $writer->withContext(['ip' => '127.0.0.1', 'timestamp' => '1986-10-29']);\n        $writer->withoutContext(['timestamp']);\n\n        $monolog->shouldReceive('isHandling')->with('info')->andReturn(true);\n        $monolog->shouldReceive('info')->once()->with('User action', [\n            'user_id' => 123,\n            'action' => 'login',\n            'ip' => '127.0.0.1',\n        ]);\n\n        $writer->info('User action');\n    }\n\n    public function testSkipsSerializationWhenLogLevelNotHandled()\n    {\n        $monolog = new Monolog('test');\n        $monolog->pushHandler(new TestHandler(Level::Error));\n\n        $writer = new Logger($monolog);\n\n        $arrayable = new class implements Arrayable\n        {\n            public bool $wasCalled = false;\n\n            public function toArray(): array\n            {\n                $this->wasCalled = true;\n\n                return ['serialized' => 'data'];\n            }\n        };\n\n        $writer->debug($arrayable);\n\n        $this->assertFalse($arrayable->wasCalled);\n    }\n\n    public function testSerializesWhenLogLevelIsHandled()\n    {\n        $monolog = new Monolog('test');\n        $handler = new TestHandler(Level::Debug);\n        $monolog->pushHandler($handler);\n\n        $writer = new Logger($monolog);\n\n        $arrayable = new class implements Arrayable\n        {\n            public bool $wasCalled = false;\n\n            public function toArray(): array\n            {\n                $this->wasCalled = true;\n\n                return ['serialized' => 'data'];\n            }\n        };\n\n        $writer->debug($arrayable);\n\n        $this->assertTrue($arrayable->wasCalled);\n        $this->assertTrue($handler->hasDebugRecords());\n    }\n}\n"
  },
  {
    "path": "tests/Log/LogManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Log;\n\nuse Illuminate\\Log\\Logger;\nuse Illuminate\\Log\\LogManager;\nuse Monolog\\Formatter\\HtmlFormatter;\nuse Monolog\\Formatter\\LineFormatter;\nuse Monolog\\Formatter\\NormalizerFormatter;\nuse Monolog\\Handler\\FingersCrossedHandler;\nuse Monolog\\Handler\\LogEntriesHandler;\nuse Monolog\\Handler\\NewRelicHandler;\nuse Monolog\\Handler\\NullHandler;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\SyslogHandler;\nuse Monolog\\Level;\nuse Monolog\\Logger as Monolog;\nuse Monolog\\Processor\\MemoryUsageProcessor;\nuse Monolog\\Processor\\PsrLogMessageProcessor;\nuse Monolog\\Processor\\UidProcessor;\nuse Orchestra\\Testbench\\TestCase;\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LoggerTrait;\nuse ReflectionProperty;\nuse RuntimeException;\n\nclass LogManagerTest extends TestCase\n{\n    public function testLogManagerCachesLoggerInstances()\n    {\n        $manager = new LogManager($this->app);\n\n        $logger1 = $manager->channel('single')->getLogger();\n        $logger2 = $manager->channel('single')->getLogger();\n\n        $this->assertSame($logger1, $logger2);\n    }\n\n    public function testLogManagerGetDefaultDriver()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.default', 'single');\n\n        $manager = new LogManager($this->app);\n        $this->assertEmpty($manager->getChannels());\n\n        //we don't specify any channel name\n        $manager->channel();\n        $this->assertCount(1, $manager->getChannels());\n        $this->assertEquals('single', $manager->getDefaultDriver());\n    }\n\n    public function testStackChannel()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.channels.stack', [\n            'driver' => 'stack',\n            'channels' => ['stderr', 'stdout'],\n        ]);\n\n        $config->set('logging.channels.stderr', [\n            'driver' => 'monolog',\n            'handler' => StreamHandler::class,\n            'level' => 'notice',\n            'with' => [\n                'stream' => 'php://stderr',\n                'bubble' => false,\n            ],\n            'processors' => [PsrLogMessageProcessor::class],\n        ]);\n\n        $config->set('logging.channels.stdout', [\n            'driver' => 'monolog',\n            'handler' => StreamHandler::class,\n            'level' => 'info',\n            'with' => [\n                'stream' => 'php://stdout',\n                'bubble' => true,\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('stack');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $this->assertInstanceOf(Logger::class, $logger);\n        $this->assertCount(2, $handlers);\n        $this->assertInstanceOf(StreamHandler::class, $handlers[0]);\n        $this->assertInstanceOf(PsrLogMessageProcessor::class, $logger->getLogger()->getProcessors()[2]);\n        $this->assertInstanceOf(StreamHandler::class, $handlers[1]);\n        $this->assertEquals(Level::Notice, $handlers[0]->getLevel());\n        $this->assertEquals(Level::Info, $handlers[1]->getLevel());\n        $this->assertFalse($handlers[0]->getBubble());\n        $this->assertTrue($handlers[1]->getBubble());\n    }\n\n    public function testParsingStackChannels()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.channels.stack', [\n            'driver' => 'stack',\n            'channels' => 'single, daily, stderr',\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        $manager->channel('stack');\n\n        $this->assertSame(\n            array_keys($manager->getChannels()),\n            ['single', 'daily', 'stderr', 'stack']\n        );\n    }\n\n    public function testLogManagerCreatesConfiguredMonologHandler()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.nonbubblingstream', [\n            'driver' => 'monolog',\n            'name' => 'foobar',\n            'handler' => StreamHandler::class,\n            'level' => 'notice',\n            'with' => [\n                'stream' => 'php://stderr',\n                'bubble' => false,\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('nonbubblingstream');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $this->assertInstanceOf(Logger::class, $logger);\n        $this->assertSame('foobar', $logger->getName());\n        $this->assertCount(1, $handlers);\n        $this->assertInstanceOf(StreamHandler::class, $handlers[0]);\n        $this->assertEquals(Level::Notice, $handlers[0]->getLevel());\n        $this->assertFalse($handlers[0]->getBubble());\n\n        $url = new ReflectionProperty(get_class($handlers[0]), 'url');\n        $this->assertSame('php://stderr', $url->getValue($handlers[0]));\n\n        $config->set('logging.channels.logentries', [\n            'driver' => 'monolog',\n            'name' => 'le',\n            'handler' => LogEntriesHandler::class,\n            'with' => [\n                'token' => '123456789',\n            ],\n        ]);\n\n        $logger = $manager->channel('logentries');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $logToken = new ReflectionProperty(get_class($handlers[0]), 'logToken');\n\n        $this->assertInstanceOf(LogEntriesHandler::class, $handlers[0]);\n        $this->assertSame('123456789', $logToken->getValue($handlers[0]));\n    }\n\n    public function testLogManagerCreatesMonologHandlerWithConfiguredFormatter()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.newrelic', [\n            'driver' => 'monolog',\n            'name' => 'nr',\n            'handler' => NewRelicHandler::class,\n            'formatter' => 'default',\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('newrelic');\n        $handler = $logger->getLogger()->getHandlers()[0];\n\n        $this->assertInstanceOf(NewRelicHandler::class, $handler);\n        $this->assertInstanceOf(NormalizerFormatter::class, $handler->getFormatter());\n\n        $config->set('logging.channels.newrelic2', [\n            'driver' => 'monolog',\n            'name' => 'nr',\n            'handler' => NewRelicHandler::class,\n            'formatter' => HtmlFormatter::class,\n            'formatter_with' => [\n                'dateFormat' => 'Y/m/d--test',\n            ],\n        ]);\n\n        $logger = $manager->channel('newrelic2');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(NewRelicHandler::class, $handler);\n        $this->assertInstanceOf(HtmlFormatter::class, $formatter);\n\n        $dateFormat = new ReflectionProperty(get_class($formatter), 'dateFormat');\n\n        $this->assertSame('Y/m/d--test', $dateFormat->getValue($formatter));\n    }\n\n    public function testLogManagerCreatesMonologHandlerWithProperFormatter()\n    {\n        $config = $this->app->make('config');\n        $config->set('logging.channels.null', [\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n            'formatter' => HtmlFormatter::class,\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('null');\n        $handler = $logger->getLogger()->getHandlers()[0];\n\n        $this->assertInstanceOf(NullHandler::class, $handler);\n\n        $config->set('logging.channels.null2', [\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n        ]);\n\n        $logger = $manager->channel('null2');\n        $handler = $logger->getLogger()->getHandlers()[0];\n\n        $this->assertInstanceOf(NullHandler::class, $handler);\n    }\n\n    public function testLogManagerCreatesMonologHandlerWithProcessors()\n    {\n        $config = $this->app->make('config');\n        $config->set('logging.channels.memory', [\n            'driver' => 'monolog',\n            'name' => 'memory',\n            'handler' => StreamHandler::class,\n            'with' => [\n                'stream' => 'php://stderr',\n            ],\n            'processors' => [\n                MemoryUsageProcessor::class,\n                ['processor' => PsrLogMessageProcessor::class, 'with' => ['removeUsedContextFields' => true]],\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('memory');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $processors = $logger->getLogger()->getProcessors();\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(MemoryUsageProcessor::class, $processors[1]);\n        $this->assertInstanceOf(PsrLogMessageProcessor::class, $processors[2]);\n\n        $removeUsedContextFields = new ReflectionProperty(get_class($processors[2]), 'removeUsedContextFields');\n\n        $this->assertTrue($removeUsedContextFields->getValue($processors[2]));\n    }\n\n    public function testItUtilisesTheNullDriverDuringTestsWhenNullDriverUsed()\n    {\n        $config = $this->app->make('config');\n        $config->set('logging.default', null);\n        $config->set('logging.channels.null', [\n            'driver' => 'monolog',\n            'handler' => NullHandler::class,\n        ]);\n        $manager = new class($this->app) extends LogManager\n        {\n            protected function createEmergencyLogger()\n            {\n                throw new RuntimeException('Emergency logger was created.');\n            }\n        };\n\n        // In tests, this should not need to create the emergency logger...\n        $manager->info('message');\n\n        // we should also be able to forget the null channel...\n        $this->assertCount(1, $manager->getChannels());\n        $manager->forgetChannel();\n        $this->assertCount(0, $manager->getChannels());\n\n        // However in production we want it to fallback to the emergency logger...\n        $this->app['env'] = 'production';\n        try {\n            $manager->info('message');\n\n            $this->fail('Emergency logger was not created as expected.');\n        } catch (RuntimeException $exception) {\n            $this->assertSame('Emergency logger was created.', $exception->getMessage());\n        }\n    }\n\n    public function testLogManagerCreateSingleDriverWithConfiguredFormatter()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.defaultsingle', [\n            'driver' => 'single',\n            'name' => 'ds',\n            'path' => storage_path('logs/laravel.log'),\n            'replace_placeholders' => true,\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('defaultsingle');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(LineFormatter::class, $formatter);\n        $this->assertInstanceOf(PsrLogMessageProcessor::class, $logger->getLogger()->getProcessors()[1]);\n\n        $config->set('logging.channels.formattedsingle', [\n            'driver' => 'single',\n            'name' => 'fs',\n            'path' => storage_path('logs/laravel.log'),\n            'formatter' => HtmlFormatter::class,\n            'formatter_with' => [\n                'dateFormat' => 'Y/m/d--test',\n            ],\n            'replace_placeholders' => false,\n        ]);\n\n        $logger = $manager->channel('formattedsingle');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(HtmlFormatter::class, $formatter);\n        $this->assertCount(1, $logger->getLogger()->getProcessors());\n\n        $dateFormat = new ReflectionProperty(get_class($formatter), 'dateFormat');\n\n        $this->assertSame('Y/m/d--test', $dateFormat->getValue($formatter));\n    }\n\n    public function testLogManagerCreateDailyDriverWithConfiguredFormatter()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.defaultdaily', [\n            'driver' => 'daily',\n            'name' => 'dd',\n            'path' => storage_path('logs/laravel.log'),\n            'replace_placeholders' => true,\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('defaultdaily');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(LineFormatter::class, $formatter);\n        $this->assertInstanceOf(PsrLogMessageProcessor::class, $logger->getLogger()->getProcessors()[1]);\n\n        $config->set('logging.channels.formatteddaily', [\n            'driver' => 'daily',\n            'name' => 'fd',\n            'path' => storage_path('logs/laravel.log'),\n            'formatter' => HtmlFormatter::class,\n            'formatter_with' => [\n                'dateFormat' => 'Y/m/d--test',\n            ],\n            'replace_placeholders' => false,\n        ]);\n\n        $logger = $manager->channel('formatteddaily');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(HtmlFormatter::class, $formatter);\n        $this->assertCount(1, $logger->getLogger()->getProcessors());\n\n        $dateFormat = new ReflectionProperty(get_class($formatter), 'dateFormat');\n\n        $this->assertSame('Y/m/d--test', $dateFormat->getValue($formatter));\n    }\n\n    public function testLogManagerCreateSyslogDriverWithConfiguredFormatter()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.defaultsyslog', [\n            'driver' => 'syslog',\n            'name' => 'ds',\n            'replace_placeholders' => true,\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('defaultsyslog');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(SyslogHandler::class, $handler);\n        $this->assertInstanceOf(LineFormatter::class, $formatter);\n        $this->assertInstanceOf(PsrLogMessageProcessor::class, $logger->getLogger()->getProcessors()[1]);\n\n        $config->set('logging.channels.formattedsyslog', [\n            'driver' => 'syslog',\n            'name' => 'fs',\n            'formatter' => HtmlFormatter::class,\n            'formatter_with' => [\n                'dateFormat' => 'Y/m/d--test',\n            ],\n            'replace_placeholders' => false,\n        ]);\n\n        $logger = $manager->channel('formattedsyslog');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(SyslogHandler::class, $handler);\n        $this->assertInstanceOf(HtmlFormatter::class, $formatter);\n        $this->assertCount(1, $logger->getLogger()->getProcessors());\n\n        $dateFormat = new ReflectionProperty(get_class($formatter), 'dateFormat');\n\n        $this->assertSame('Y/m/d--test', $dateFormat->getValue($formatter));\n    }\n\n    public function testLogManagerPurgeResolvedChannels()\n    {\n        $manager = new LogManager($this->app);\n\n        $this->assertEmpty($manager->getChannels());\n\n        $manager->channel('single')->getLogger();\n\n        $this->assertCount(1, $manager->getChannels());\n\n        $manager->forgetChannel('single');\n\n        $this->assertEmpty($manager->getChannels());\n    }\n\n    public function testLogManagerCanBuildOnDemandChannel()\n    {\n        $manager = new LogManager($this->app);\n\n        $logger = $manager->build([\n            'driver' => 'single',\n            'path' => storage_path('logs/on-demand.log'),\n        ]);\n        $handler = $logger->getLogger()->getHandlers()[0];\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n\n        $url = new ReflectionProperty(get_class($handler), 'url');\n\n        $this->assertSame(storage_path('logs/on-demand.log'), $url->getValue($handler));\n    }\n\n    public function testLogManagerCanUseOnDemandChannelInOnDemandStack()\n    {\n        $manager = new LogManager($this->app);\n        $this->app['config']->set('logging.channels.test', [\n            'driver' => 'single',\n        ]);\n\n        $factory = new class()\n        {\n            public function __invoke()\n            {\n                return new Monolog(\n                    'uuid',\n                    [new StreamHandler(storage_path('logs/custom.log'))],\n                    [new UidProcessor()]\n                );\n            }\n        };\n        $channel = $manager->build([\n            'driver' => 'custom',\n            'via' => get_class($factory),\n        ]);\n        $logger = $manager->stack(['test', $channel]);\n\n        $handler = $logger->getLogger()->getHandlers()[1];\n        $processor = $logger->getLogger()->getProcessors()[1];\n\n        $this->assertInstanceOf(StreamHandler::class, $handler);\n        $this->assertInstanceOf(UidProcessor::class, $processor);\n\n        $url = new ReflectionProperty(get_class($handler), 'url');\n\n        $this->assertSame(storage_path('logs/custom.log'), $url->getValue($handler));\n    }\n\n    public function testWrappingHandlerInFingersCrossedWhenActionLevelIsUsed()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.channels.fingerscrossed', [\n            'driver' => 'monolog',\n            'handler' => StreamHandler::class,\n            'level' => 'debug',\n            'action_level' => 'critical',\n            'with' => [\n                'stream' => 'php://stderr',\n                'bubble' => false,\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('fingerscrossed');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $this->assertInstanceOf(Logger::class, $logger);\n        $this->assertCount(1, $handlers);\n\n        $expectedFingersCrossedHandler = $handlers[0];\n        $this->assertInstanceOf(FingersCrossedHandler::class, $expectedFingersCrossedHandler);\n\n        $activationStrategyProp = new ReflectionProperty(get_class($expectedFingersCrossedHandler), 'activationStrategy');\n        $activationStrategyValue = $activationStrategyProp->getValue($expectedFingersCrossedHandler);\n\n        $actionLevelProp = new ReflectionProperty(get_class($activationStrategyValue), 'actionLevel');\n        $actionLevelValue = $actionLevelProp->getValue($activationStrategyValue);\n\n        $this->assertEquals(Level::Critical, $actionLevelValue);\n\n        if (method_exists($expectedFingersCrossedHandler, 'getHandler')) {\n            $expectedStreamHandler = $expectedFingersCrossedHandler->getHandler();\n        } else {\n            $handlerProp = new ReflectionProperty(get_class($expectedFingersCrossedHandler), 'handler');\n            $expectedStreamHandler = $handlerProp->getValue($expectedFingersCrossedHandler);\n        }\n        $this->assertInstanceOf(StreamHandler::class, $expectedStreamHandler);\n        $this->assertEquals(Level::Debug, $expectedStreamHandler->getLevel());\n    }\n\n    public function testFingersCrossedHandlerStopsRecordBufferingAfterFirstFlushByDefault()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.channels.fingerscrossed', [\n            'driver' => 'monolog',\n            'handler' => StreamHandler::class,\n            'level' => 'debug',\n            'action_level' => 'critical',\n            'with' => [\n                'stream' => 'php://stderr',\n                'bubble' => false,\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('fingerscrossed');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $expectedFingersCrossedHandler = $handlers[0];\n\n        $stopBufferingProp = new ReflectionProperty(get_class($expectedFingersCrossedHandler), 'stopBuffering');\n        $stopBufferingValue = $stopBufferingProp->getValue($expectedFingersCrossedHandler);\n\n        $this->assertTrue($stopBufferingValue);\n    }\n\n    public function testFingersCrossedHandlerCanBeConfiguredToResumeBufferingAfterFlushing()\n    {\n        $config = $this->app['config'];\n\n        $config->set('logging.channels.fingerscrossed', [\n            'driver' => 'monolog',\n            'handler' => StreamHandler::class,\n            'level' => 'debug',\n            'action_level' => 'critical',\n            'stop_buffering' => false,\n            'with' => [\n                'stream' => 'php://stderr',\n                'bubble' => false,\n            ],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        // create logger with handler specified from configuration\n        $logger = $manager->channel('fingerscrossed');\n        $handlers = $logger->getLogger()->getHandlers();\n\n        $expectedFingersCrossedHandler = $handlers[0];\n\n        $stopBufferingProp = new ReflectionProperty(get_class($expectedFingersCrossedHandler), 'stopBuffering');\n        $stopBufferingValue = $stopBufferingProp->getValue($expectedFingersCrossedHandler);\n\n        $this->assertFalse($stopBufferingValue);\n    }\n\n    public function testItSharesContextWithAlreadyResolvedChannels()\n    {\n        $manager = new LogManager($this->app);\n        $channel = $manager->channel('single');\n        $context = null;\n\n        $channel->listen(function ($message) use (&$context) {\n            $context = $message->context;\n        });\n        $manager->shareContext([\n            'invocation-id' => 'expected-id',\n        ]);\n        $channel->info('xxxx');\n\n        $this->assertSame(['invocation-id' => 'expected-id'], $context);\n    }\n\n    public function testItSharesContextWithFreshlyResolvedChannels()\n    {\n        $manager = new LogManager($this->app);\n        $context = null;\n\n        $manager->shareContext([\n            'invocation-id' => 'expected-id',\n        ]);\n        $manager->channel('single')->listen(function ($message) use (&$context) {\n            $context = $message->context;\n        });\n        $manager->channel('single')->info('xxxx');\n\n        $this->assertSame(['invocation-id' => 'expected-id'], $context);\n    }\n\n    public function testContextCanBePubliclyAccessedByOtherLoggingSystems()\n    {\n        $manager = new LogManager($this->app);\n        $context = null;\n\n        $manager->shareContext([\n            'invocation-id' => 'expected-id',\n        ]);\n\n        $this->assertSame($manager->sharedContext(), ['invocation-id' => 'expected-id']);\n    }\n\n    public function testItSharesContextWithStacksWhenTheyAreResolved()\n    {\n        $manager = new LogManager($this->app);\n        $context = null;\n\n        $manager->shareContext([\n            'invocation-id' => 'expected-id',\n        ]);\n        $stack = $manager->stack(['single']);\n        $stack->listen(function ($message) use (&$context) {\n            $context = $message->context;\n        });\n        $stack->info('xxxx');\n\n        $this->assertSame(['invocation-id' => 'expected-id'], $context);\n    }\n\n    public function testItMergesSharedContextRatherThanReplacing()\n    {\n        $manager = new LogManager($this->app);\n        $context = null;\n\n        $manager->shareContext([\n            'invocation-id' => 'expected-id',\n        ]);\n        $manager->shareContext([\n            'invocation-start' => 1651800456,\n        ]);\n        $manager->channel('single')->listen(function ($message) use (&$context) {\n            $context = $message->context;\n        });\n        $manager->channel('single')->info('xxxx', [\n            'logged' => 'context',\n        ]);\n\n        $this->assertSame([\n            'invocation-id' => 'expected-id',\n            'invocation-start' => 1651800456,\n            'logged' => 'context',\n        ], $context);\n        $this->assertSame([\n            'invocation-id' => 'expected-id',\n            'invocation-start' => 1651800456,\n        ], $manager->sharedContext());\n    }\n\n    public function testFlushSharedContext()\n    {\n        $manager = new LogManager($this->app);\n\n        $manager->shareContext($context = ['foo' => 'bar']);\n\n        $this->assertSame($context, $manager->sharedContext());\n\n        $manager->flushSharedContext();\n\n        $this->assertEmpty($manager->sharedContext());\n    }\n\n    public function testLogManagerCreateCustomFormatterWithTap()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.custom', [\n            'driver' => 'single',\n            'tap' => [CustomizeFormatter::class],\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        $logger = $manager->channel('custom');\n        $handler = $logger->getLogger()->getHandlers()[0];\n        $formatter = $handler->getFormatter();\n\n        $this->assertInstanceOf(LineFormatter::class, $formatter);\n\n        $format = new ReflectionProperty(get_class($formatter), 'format');\n\n        $this->assertEquals(\n            '[%datetime%] %channel%.%level_name%: %message% %context% %extra%',\n            rtrim($format->getValue($formatter)));\n    }\n\n    public function testDriverUsersPsrLoggerManagerReturnsLogger()\n    {\n        // Given\n        $config = $this->app['config'];\n        $config->set('logging.channels.spy', [\n            'driver' => 'spy',\n        ]);\n\n        $manager = new LogManager($this->app);\n\n        $loggerSpy = new LoggerSpy();\n        $manager->extend('spy', fn () => $loggerSpy);\n\n        // When\n        $logger = $manager->channel('spy');\n        $logger->alert('some alert');\n\n        // Then\n        $this->assertCount(1, $loggerSpy->logs);\n        $this->assertEquals('some alert', $loggerSpy->logs[0]['message']);\n    }\n\n    public function testCustomDriverClosureBoundObjectIsLogManager()\n    {\n        $config = $this->app['config'];\n        $config->set('logging.channels.'.__CLASS__, [\n            'driver' => __CLASS__,\n        ]);\n\n        $manager = new LogManager($this->app);\n        $manager->extend(__CLASS__, fn () => $this);\n        $this->assertSame($manager, $manager->channel(__CLASS__)->getLogger());\n    }\n}\n\nclass CustomizeFormatter\n{\n    public function __invoke($logger)\n    {\n        foreach ($logger->getHandlers() as $handler) {\n            $handler->setFormatter(new LineFormatter(\n                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'\n            ));\n        }\n    }\n}\n\nclass LoggerSpy implements LoggerInterface\n{\n    use LoggerTrait;\n\n    public array $logs = [];\n\n    public function log($level, \\Stringable|string $message, array $context = []): void\n    {\n        $this->logs[] = [\n            'level' => $level,\n            'message' => $message,\n            'context' => $context,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Mail/AttachableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Http\\Testing\\File;\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Mailable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AttachableTest extends TestCase\n{\n    public function testItCanHaveMacroConstructors(): void\n    {\n        Attachment::macro('fromInvoice', function ($name) {\n            return Attachment::fromData(fn () => 'pdf content', $name);\n        });\n        $mailable = new Mailable;\n\n        $mailable->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromInvoice('foo')\n                    ->as('bar')\n                    ->withMime('image/jpeg');\n            }\n        });\n\n        $this->assertSame([\n            'data' => 'pdf content',\n            'name' => 'bar',\n            'options' => [\n                'mime' => 'image/jpeg',\n            ],\n        ], $mailable->rawAttachments[0]);\n    }\n\n    public function testItCanUtiliseExistingApisOnNonMailBasedResourcesWithPath(): void\n    {\n        Attachment::macro('size', function () {\n            return 99;\n        });\n        $notification = new class()\n        {\n            public $pathArgs;\n\n            public function withPathAttachment()\n            {\n                $this->pathArgs = func_get_args();\n            }\n        };\n        $attachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath('foo.jpg')\n                    ->as('bar')\n                    ->withMime('text/css');\n            }\n        };\n\n        $attachable->toMailAttachment()->attachWith(\n            fn ($path, $attachment) => $notification->withPathAttachment($path, $attachment->as, $attachment->mime, $attachment->size()),\n            fn () => null\n        );\n\n        $this->assertSame([\n            'foo.jpg',\n            'bar',\n            'text/css',\n            99,\n        ], $notification->pathArgs);\n    }\n\n    public function testItCanUtiliseExistingApisOnNonMailBasedResourcesWithArgs(): void\n    {\n        Attachment::macro('size', function () {\n            return 99;\n        });\n        $notification = new class()\n        {\n            public $pathArgs;\n\n            public $dataArgs;\n\n            public function withDataAttachment()\n            {\n                $this->dataArgs = func_get_args();\n            }\n        };\n        $attachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'expected attachment body', 'bar')\n                    ->withMime('text/css');\n            }\n        };\n\n        $attachable->toMailAttachment()->attachWith(\n            fn () => null,\n            fn ($data, $attachment) => $notification->withDataAttachment($data(), $attachment->as, $attachment->mime, $attachment->size()),\n        );\n\n        $this->assertSame([\n            'expected attachment body',\n            'bar',\n            'text/css',\n            99,\n        ], $notification->dataArgs);\n    }\n\n    public function testFromUrlMethod(): void\n    {\n        $mailable = new class extends Mailable\n        {\n            public function build()\n            {\n                $this->attach(new class implements Attachable\n                {\n                    public function toMailAttachment()\n                    {\n                        return Attachment::fromUrl('https://example.com/file.pdf')\n                            ->as('example.pdf')\n                            ->withMime('application/pdf');\n                    }\n                });\n            }\n        };\n\n        $mailable->build();\n\n        $this->assertSame([\n            'file' => 'https://example.com/file.pdf',\n            'options' => [\n                'as' => 'example.pdf',\n                'mime' => 'application/pdf',\n            ],\n        ], $mailable->attachments[0]);\n    }\n\n    public function testFromUploadedFileMethod(): void\n    {\n        $mailable = new class extends Mailable\n        {\n            public function build()\n            {\n                $this->attach(new class implements Attachable\n                {\n                    public function toMailAttachment()\n                    {\n                        return Attachment::fromUploadedFile(\n                            File::createWithContent('example.pdf', 'content')\n                                ->mimeType('application/pdf')\n                        );\n                    }\n                });\n            }\n        };\n\n        $mailable->build();\n\n        $this->assertSame([\n            'data' => 'content',\n            'name' => 'example.pdf',\n            'options' => [\n                'mime' => 'application/pdf',\n            ],\n        ], $mailable->rawAttachments[0]);\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailFailoverTransportTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\Mailer\\Transport\\FailoverTransport;\n\nclass MailFailoverTransportTest extends TestCase\n{\n    public function testGetFailoverTransportWithConfiguredTransports(): void\n    {\n        $this->app['config']->set('mail.default', 'failover');\n\n        $this->app['config']->set('mail.mailers', [\n            'failover' => [\n                'transport' => 'failover',\n                'mailers' => [\n                    'sendmail',\n                    'array',\n                ],\n            ],\n\n            'sendmail' => [\n                'transport' => 'sendmail',\n                'path' => '/usr/sbin/sendmail -bs',\n            ],\n\n            'array' => [\n                'transport' => 'array',\n            ],\n        ]);\n\n        $transport = app('mailer')->getSymfonyTransport();\n        $this->assertInstanceOf(FailoverTransport::class, $transport);\n    }\n\n    public function testGetFailoverTransportWithLaravel6StyleMailConfiguration(): void\n    {\n        $this->app['config']->set('mail.driver', 'failover');\n\n        $this->app['config']->set('mail.mailers', [\n            'sendmail',\n            'array',\n        ]);\n\n        $this->app['config']->set('mail.sendmail', '/usr/sbin/sendmail -bs');\n\n        $transport = app('mailer')->getSymfonyTransport();\n        $this->assertInstanceOf(FailoverTransport::class, $transport);\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailLogTransportTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Message;\nuse Illuminate\\Mail\\Transport\\LogTransport;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Logger;\nuse Orchestra\\Testbench\\TestCase;\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\NullLogger;\nuse Symfony\\Component\\Mime\\Email;\n\nclass MailLogTransportTest extends TestCase\n{\n    public function testGetLogTransportWithConfiguredChannel(): void\n    {\n        $this->app['config']->set('mail.driver', 'log');\n\n        $this->app['config']->set('mail.log_channel', 'mail');\n\n        $this->app['config']->set('logging.channels.mail', [\n            'driver' => 'single',\n            'path' => 'mail.log',\n        ]);\n\n        $transport = app('mailer')->getSymfonyTransport();\n        $this->assertInstanceOf(LogTransport::class, $transport);\n\n        $logger = $transport->logger();\n        $this->assertInstanceOf(LoggerInterface::class, $logger);\n\n        $this->assertInstanceOf(Logger::class, $monolog = $logger->getLogger());\n        $this->assertCount(1, $handlers = $monolog->getHandlers());\n        $this->assertInstanceOf(StreamHandler::class, $handlers[0]);\n    }\n\n    public function testItDecodesTheMessageBeforeLogging(): void\n    {\n        $message = (new Message(new Email))\n            ->from('noreply@example.com', 'no-reply')\n            ->to('taylor@example.com', 'Taylor')\n            ->html(<<<'BODY'\n            Hi,\n\n            <a href=\"https://example.com/reset-password=5e113c71a4c210aff04b3fa66f1b1299\">Click here to reset your password</a>.\n\n            All the best,\n\n            Burt & Irving\n            BODY)\n            ->text('A text part');\n\n        $actualLoggedValue = $this->getLoggedEmailMessage($message);\n\n        $this->assertStringNotContainsString(\"=\\r\\n\", $actualLoggedValue);\n        $this->assertStringContainsString('href=', $actualLoggedValue);\n        $this->assertStringContainsString('Burt & Irving', $actualLoggedValue);\n        $this->assertStringContainsString('https://example.com/reset-password=5e113c71a4c210aff04b3fa66f1b1299', $actualLoggedValue);\n    }\n\n    public function testItOnlyDecodesQuotedPrintablePartsOfTheMessageBeforeLogging(): void\n    {\n        $message = (new Message(new Email))\n            ->from('noreply@example.com', 'no-reply')\n            ->to('taylor@example.com', 'Taylor')\n            ->html(<<<'BODY'\n            Hi,\n\n            <a href=\"https://example.com/reset-password=5e113c71a4c210aff04b3fa66f1b1299\">Click here to reset your password</a>.\n\n            All the best,\n\n            Burt & Irving\n            BODY)\n            ->text('A text part')\n            ->attach(Attachment::fromData(fn () => 'My attachment', 'attachment.txt'));\n\n        $actualLoggedValue = $this->getLoggedEmailMessage($message);\n\n        $this->assertStringContainsString('href=', $actualLoggedValue);\n        $this->assertStringContainsString('Burt & Irving', $actualLoggedValue);\n        $this->assertStringContainsString('https://example.com/reset-password=5e113c71a4c210aff04b3fa66f1b1299', $actualLoggedValue);\n        $this->assertStringContainsString('name=attachment.txt', $actualLoggedValue);\n        $this->assertStringContainsString('filename=attachment.txt', $actualLoggedValue);\n    }\n\n    public function testGetLogTransportWithPsrLogger(): void\n    {\n        $this->app['config']->set('mail.driver', 'log');\n\n        $logger = $this->app->instance('log', new NullLogger);\n\n        $transportLogger = app('mailer')->getSymfonyTransport()->logger();\n\n        $this->assertEquals($logger, $transportLogger);\n    }\n\n    private function getLoggedEmailMessage(Message $message): string\n    {\n        $logger = new class extends NullLogger\n        {\n            public string $loggedValue = '';\n\n            public function log($level, string|\\Stringable $message, array $context = []): void\n            {\n                $this->loggedValue = (string) $message;\n            }\n        };\n\n        (new LogTransport($logger))->send(\n            $message->getSymfonyMessage()\n        );\n\n        return $logger->loggedValue;\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMailableAssertionsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\TestCase;\n\nclass MailMailableAssertionsTest extends TestCase\n{\n    public function testMailableAssertSeeInTextPassesWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInText('First Item');\n    }\n\n    public function testMailableAssertSeeInTextFailsWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInText('Fourth Item');\n    }\n\n    public function testMailableAssertDontSeeInTextPassesWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertDontSeeInText('Fourth Item');\n    }\n\n    public function testMailableAssertDontSeeInTextFailsWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertDontSeeInText('First Item');\n    }\n\n    public function testMailableAssertSeeInHtmlPassesWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInHtml('Fourth & Fifth Item');\n\n        $mailable->assertSeeInHtml('<li>First Item</li>', false);\n    }\n\n    public function testMailableAssertSeeInHtmlFailsWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInHtml('<li>Fourth Item</li>');\n    }\n\n    public function testMailableAssertDontSeeInHtmlPassesWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertDontSeeInHtml('<li>Fourth Item</li>');\n    }\n\n    public function testMailableAssertDontSeeInHtmlEscapedFailsWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertDontSeeInHtml('Fourth & Fifth Item');\n    }\n\n    public function testMailableAssertDontSeeInHtmlUnescapedFailsWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertDontSeeInHtml('<li>First Item</li>', false);\n    }\n\n    public function testMailableAssertSeeInOrderTextPassesWhenPresentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInOrderInText([\n            'First Item',\n            'Second Item',\n            'Third Item',\n        ]);\n    }\n\n    public function testMailableAssertSeeInOrderTextFailsWhenAbsentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInOrderInText([\n            'First Item',\n            'Third Item',\n            'Second Item',\n        ]);\n    }\n\n    public function testMailableAssertInOrderHtmlPassesWhenPresentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInOrderInHtml([\n            'Third Item',\n            'Fourth & Fifth Item',\n            'Sixth Item',\n        ]);\n\n        $mailable->assertSeeInOrderInHtml([\n            '<li>First Item</li>',\n            '<li>Second Item</li>',\n            '<li>Third Item</li>',\n        ], false);\n    }\n\n    public function testMailableAssertInOrderHtmlFailsWhenAbsentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInOrderInHtml([\n            '<li>Second Item</li>',\n            '<li>First Item</li>',\n            '<li>Third Item</li>',\n        ]);\n    }\n\n    public function testMailableAssertSeeInTextWithApostrophePassesWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInText(\"It's a wonderful day\");\n    }\n\n    public function testMailableAssertSeeInTextWithApostropheFailsWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInText(\"It's not a wonderful day\");\n    }\n\n    public function testMailableAssertDontSeeInTextWithApostrophePassesWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertDontSeeInText(\"It's not a wonderful day\");\n    }\n\n    public function testMailableAssertDontSeeInTextWithApostropheFailsWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertDontSeeInText(\"It's a wonderful day\");\n    }\n\n    public function testMailableAssertSeeInHtmlWithApostropheFailsWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInHtml(\"<li>It's not a wonderful day</li>\");\n    }\n\n    public function testMailableAssertDontSeeInHtmlWithApostrophePassesWhenAbsent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertDontSeeInHtml(\"<li>It's not a wonderful day</li>\");\n    }\n\n    public function testMailableAssertDontSeeInHtmlWithApostropheFailsWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertDontSeeInHtml(\"<li>It's a wonderful day</li>\", false);\n    }\n\n    public function testMailableAssertSeeInHtmlWithBladeEscapedApostrophePassesWhenPresent(): void\n    {\n        $mailable = new MailableAssertionsBladeEscapedStub;\n\n        $mailable->assertSeeInHtml(\"It's a wonderful day\");\n    }\n\n    public function testMailableAssertSeeInOrderInHtmlWithApostrophePassesWhenPresentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $mailable->assertSeeInOrderInHtml([\n            'First Item',\n            'Sixth Item',\n            'It\\'s a wonderful day',\n        ]);\n\n        $mailable->assertSeeInOrderInHtml([\n            '<li>First Item</li>',\n            '<li>It\\'s a wonderful day</li>',\n        ], false);\n    }\n\n    public function testMailableAssertSeeInOrderInHtmlWithApostropheFailsWhenAbsentInOrder(): void\n    {\n        $mailable = new MailableAssertionsStub;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $mailable->assertSeeInOrderInHtml([\n            'It\\'s a wonderful day',\n            'First Item',\n            'Sixth Item',\n        ]);\n    }\n}\n\nclass MailableAssertionsStub extends Mailable\n{\n    protected function renderForAssertions()\n    {\n        $text = <<<'EOD'\n        # List\n        - First Item\n        - Second Item\n        - Third Item\n        - Fourth & Fifth Item\n        - Sixth Item\n        - It's a wonderful day\n        EOD;\n\n        $html = <<<'EOD'\n        <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n        <html xmlns=\"http://www.w3.org/1999/xhtml\">\n        <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n        </style>\n        </head>\n        <body>\n        <h1>List</h1>\n        <ul>\n        <li>First Item</li>\n        <li>Second Item</li>\n        <li>Third Item</li>\n        <li>Fourth &amp; Fifth Item</li>\n        <li>Sixth Item</li>\n        <li>It's a wonderful day</li>\n        </ul>\n        </body>\n        </html>\n        EOD;\n\n        return [$html, $text];\n    }\n}\n\nclass MailableAssertionsBladeEscapedStub extends Mailable\n{\n    protected function renderForAssertions()\n    {\n        $text = \"It's a wonderful day\";\n\n        $html = <<<'EOD'\n        <!DOCTYPE html>\n        <html>\n        <body>\n        <div>It&#039;s a wonderful day</div>\n        </body>\n        </html>\n        EOD;\n\n        /**\n         * Since stub override `renderForAssertions()` we should expect that `$html` is available from either `$this->view` or `$this->markdown`.\n         */\n\n        return [$html, $text];\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMailableDataTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass MailMailableDataTest extends TestCase\n{\n    public function testMailableDataIsNotLost(): void\n    {\n        $mailable = new MailableStub;\n\n        $testData = [\n            'first_name' => 'James',\n            '__laravel_mailable' => get_class($mailable),\n        ];\n\n        $mailable->build(function ($m) use ($testData) {\n            $m->view('view', $testData);\n        });\n        $this->assertSame($testData, $mailable->buildViewData());\n\n        $mailable = new MailableStub;\n        $mailable->build(function ($m) use ($testData) {\n            $m->view('view', $testData)\n                ->text('text-view');\n        });\n        $this->assertSame($testData, $mailable->buildViewData());\n    }\n}\n\nclass MailableStub extends Mailable\n{\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build($builder)\n    {\n        $builder($this);\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMailableHeadersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Mail\\Mailables\\Headers;\nuse PHPUnit\\Framework\\TestCase;\n\nclass MailMailableHeadersTest extends TestCase\n{\n    public function test(): void\n    {\n        $headers = new Headers(\n            '434571BC.8070702@example.net',\n            [\n                '<19980506192030.26456.qmail@cr.yp.to>',\n                '<19980507220459.5655.qmail@warren.demon.co.uk>',\n                '<19980508103652.B21462@iconnect.co.ke>',\n                '<19980509035615.40087@rucus.ru.ac.za>',\n            ],\n        );\n\n        $this->assertSame(\n            '<19980506192030.26456.qmail@cr.yp.to> <19980507220459.5655.qmail@warren.demon.co.uk> <19980508103652.B21462@iconnect.co.ke> <19980509035615.40087@rucus.ru.ac.za>',\n            $headers->referencesString(),\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMailableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse Illuminate\\Mail\\Mailables\\Headers;\nuse Illuminate\\Mail\\Mailer;\nuse Illuminate\\Mail\\Transport\\ArrayTransport;\nuse Mockery as m;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\TestCase;\n\nclass MailMailableTest extends TestCase\n{\n    public function testMailableSetsRecipientsCorrectly(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('taylor@laravel.com');\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com');\n        $mailable->to('taylor@laravel.com', 'Taylor Otwell');\n\n        // Add the same recipient again, but with a different name. This should set the name correctly.\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertHasTo('taylor@laravel.com', 'Taylor Otwell');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('taylor@laravel.com', 'Taylor Otwell');\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to(['taylor@laravel.com']);\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $this->assertFalse($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertHasTo('taylor@laravel.com');\n        try {\n            $mailable->assertHasTo('taylor@laravel.com', 'Taylor Otwell');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not see expected recipient in email 'to' recipients.\\nExpected: [taylor@laravel.com (Taylor Otwell)]\\nActual: [taylor@laravel.com]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to([['name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com']]);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to(new MailableTestUserStub);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to(collect([new MailableTestUserStub]));\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->to);\n        $this->assertTrue($mailable->hasTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to(collect([new MailableTestUserStub, new MailableTestUserStub, new MailableTestUserStub2]));\n        $this->assertEquals([\n            ['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com'],\n            ['name' => 'Laravel Framework', 'address' => 'contact@laravel.com'],\n        ], $mailable->to);\n        $this->assertTrue($mailable->hasTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $mailable->assertHasTo('taylor@laravel.com');\n\n        foreach (['', null, [], false] as $address) {\n            $mailable = new WelcomeMailableStub;\n            $mailable->to($address);\n            $this->assertFalse($mailable->hasTo(new MailableTestUserStub));\n            $this->assertFalse($mailable->hasTo($address));\n            try {\n                $mailable->assertHasTo($address);\n                $this->fail();\n            } catch (AssertionFailedError $e) {\n                if (! is_string($address)) {\n                    $address = json_encode($address);\n                }\n                $this->assertSame(\"Did not see expected recipient in email 'to' recipients.\\nExpected: [{$address}]\\nActual: [none]\\nFailed asserting that false is true.\", $e->getMessage());\n            }\n        }\n    }\n\n    public function testMailableSetsCcRecipientsCorrectly(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc('taylor@laravel.com');\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc('taylor@laravel.com', 'Taylor Otwell');\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc(['taylor@laravel.com']);\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $this->assertFalse($mailable->hasCc('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertHasCc('taylor@laravel.com');\n        try {\n            $mailable->assertHasCc('taylor@laravel.com', 'Taylor Otwell');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not see expected recipient in email 'cc' recipients.\\nExpected: [taylor@laravel.com (Taylor Otwell)]\\nActual: [taylor@laravel.com]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc([['name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com']]);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc(new MailableTestUserStub);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc(collect([new MailableTestUserStub]));\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->cc);\n        $this->assertTrue($mailable->hasCc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc(collect([new MailableTestUserStub, new MailableTestUserStub, new MailableTestUserStub2]));\n        $this->assertEquals([\n            ['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com'],\n            ['name' => 'Laravel Framework', 'address' => 'contact@laravel.com'],\n        ], $mailable->cc);\n        $this->assertTrue($mailable->hasCc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->cc(['taylor@laravel.com', 'not-taylor@laravel.com']);\n        $this->assertEquals([\n            ['name' => null, 'address' => 'taylor@laravel.com'],\n            ['name' => null, 'address' => 'not-taylor@laravel.com'],\n        ], $mailable->cc);\n        $this->assertTrue($mailable->hasCc('taylor@laravel.com'));\n        $this->assertTrue($mailable->hasCc('not-taylor@laravel.com'));\n        $mailable->assertHasCc('taylor@laravel.com');\n        $mailable->assertHasCc('not-taylor@laravel.com');\n\n        foreach (['', null, [], false] as $address) {\n            $mailable = new WelcomeMailableStub;\n            $mailable->cc($address);\n            $this->assertFalse($mailable->hasCc(new MailableTestUserStub));\n            $this->assertFalse($mailable->hasCc($address));\n            try {\n                $mailable->assertHasCc($address);\n                $this->fail();\n            } catch (AssertionFailedError $e) {\n                if (! is_string($address)) {\n                    $address = json_encode($address);\n                }\n                $this->assertSame(\"Did not see expected recipient in email 'cc' recipients.\\nExpected: [{$address}]\\nActual: [none]\\nFailed asserting that false is true.\", $e->getMessage());\n            }\n        }\n    }\n\n    public function testMailableSetsBccRecipientsCorrectly(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc('taylor@laravel.com');\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc('taylor@laravel.com', 'Taylor Otwell');\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc(['taylor@laravel.com']);\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $this->assertFalse($mailable->hasBcc('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n        try {\n            $mailable->assertHasBcc('taylor@laravel.com', 'Taylor Otwell');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not see expected recipient in email 'bcc' recipients.\\nExpected: [taylor@laravel.com (Taylor Otwell)]\\nActual: [taylor@laravel.com]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc([['name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com']]);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc(new MailableTestUserStub);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc(collect([new MailableTestUserStub]));\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc(collect([new MailableTestUserStub, new MailableTestUserStub, new MailableTestUserStub2]));\n        $this->assertEquals([\n            ['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com'],\n            ['name' => 'Laravel Framework', 'address' => 'contact@laravel.com'],\n        ], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->bcc(['taylor@laravel.com', 'not-taylor@laravel.com']);\n        $this->assertEquals([\n            ['name' => null, 'address' => 'taylor@laravel.com'],\n            ['name' => null, 'address' => 'not-taylor@laravel.com'],\n        ], $mailable->bcc);\n        $this->assertTrue($mailable->hasBcc('taylor@laravel.com'));\n        $this->assertTrue($mailable->hasBcc('not-taylor@laravel.com'));\n        $mailable->assertHasBcc('taylor@laravel.com');\n        $mailable->assertHasBcc('not-taylor@laravel.com');\n\n        foreach (['', null, [], false] as $address) {\n            $mailable = new WelcomeMailableStub;\n            $mailable->bcc($address);\n            $this->assertFalse($mailable->hasBcc(new MailableTestUserStub));\n            $this->assertFalse($mailable->hasBcc($address));\n            try {\n                $mailable->assertHasBcc($address);\n                $this->fail();\n            } catch (AssertionFailedError $e) {\n                if (! is_string($address)) {\n                    $address = json_encode($address);\n                }\n                $this->assertSame(\"Did not see expected recipient in email 'bcc' recipients.\\nExpected: [{$address}]\\nActual: [none]\\nFailed asserting that false is true.\", $e->getMessage());\n            }\n        }\n    }\n\n    public function testMailableSetsReplyToCorrectly(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo('taylor@laravel.com');\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo('taylor@laravel.com', 'Taylor Otwell');\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo(['taylor@laravel.com']);\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $this->assertFalse($mailable->hasReplyTo('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n        try {\n            $mailable->assertHasReplyTo('taylor@laravel.com', 'Taylor Otwell');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not see expected address as email 'reply to' recipient.\\nExpected: [taylor@laravel.com (Taylor Otwell)]\\nActual: [taylor@laravel.com]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo([['name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com']]);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n        $mailable->assertHasReplyTo('taylor@laravel.com', 'Taylor Otwell');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo(new MailableTestUserStub);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo(collect([new MailableTestUserStub]));\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->replyTo(collect([new MailableTestUserStub, new MailableTestUserStub, new MailableTestUserStub2]));\n        $this->assertEquals([\n            ['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com'],\n            ['name' => 'Laravel Framework', 'address' => 'contact@laravel.com'],\n        ], $mailable->replyTo);\n        $this->assertTrue($mailable->hasReplyTo(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasReplyTo('taylor@laravel.com'));\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n\n        foreach (['', null, [], false] as $address) {\n            $mailable = new WelcomeMailableStub;\n            $mailable->replyTo($address);\n            $this->assertFalse($mailable->hasReplyTo(new MailableTestUserStub));\n            $this->assertFalse($mailable->hasReplyTo($address));\n            try {\n                $mailable->assertHasReplyTo($address);\n                $this->fail();\n            } catch (AssertionFailedError $e) {\n                if (! is_string($address)) {\n                    $address = json_encode($address);\n                }\n                $this->assertSame(\"Did not see expected address as email 'reply to' recipient.\\nExpected: [{$address}]\\nActual: [none]\\nFailed asserting that false is true.\", $e->getMessage());\n            }\n        }\n    }\n\n    public function testMailableSetsFromCorrectly(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from('taylor@laravel.com');\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from('taylor@laravel.com', 'Taylor Otwell');\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertFrom('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from(['taylor@laravel.com']);\n        $this->assertEquals([['name' => null, 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $this->assertFalse($mailable->hasFrom('taylor@laravel.com', 'Taylor Otwell'));\n        $mailable->assertFrom('taylor@laravel.com');\n        try {\n            $mailable->assertFrom('taylor@laravel.com', 'Taylor Otwell');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Email was not from expected address.\\nExpected: [taylor@laravel.com (Taylor Otwell)]\\nActual: [taylor@laravel.com]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from([['name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com']]);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com', 'Taylor Otwell');\n        $mailable->assertFrom('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from(new MailableTestUserStub);\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from(collect([new MailableTestUserStub]));\n        $this->assertEquals([['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com']], $mailable->from);\n        $this->assertTrue($mailable->hasFrom(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com');\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->from(collect([new MailableTestUserStub, new MailableTestUserStub, new MailableTestUserStub2]));\n        $this->assertEquals([\n            ['name' => 'Taylor Otwell', 'address' => 'taylor@laravel.com'],\n            ['name' => 'Laravel Framework', 'address' => 'contact@laravel.com'],\n        ], $mailable->from);\n        $this->assertTrue($mailable->hasFrom(new MailableTestUserStub));\n        $this->assertTrue($mailable->hasFrom('taylor@laravel.com'));\n        $mailable->assertFrom('taylor@laravel.com');\n\n        foreach (['', null, [], false] as $address) {\n            $mailable = new WelcomeMailableStub;\n            $mailable->from($address);\n            $this->assertFalse($mailable->hasFrom(new MailableTestUserStub));\n            $this->assertFalse($mailable->hasFrom($address));\n            try {\n                $mailable->assertFrom($address);\n                $this->fail();\n            } catch (AssertionFailedError $e) {\n                if (! is_string($address)) {\n                    $address = json_encode($address);\n                }\n                $this->assertSame(\"Email was not from expected address.\\nExpected: [{$address}]\\nActual: [none]\\nFailed asserting that false is true.\", $e->getMessage());\n            }\n        }\n    }\n\n    public function testMailableSetsSubjectCorrectly(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->subject('foo');\n        $this->assertTrue($mailable->hasSubject('foo'));\n    }\n\n    public function testItIgnoresDuplicatedRawAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->attachData('content1', 'report-1.txt');\n        $this->assertCount(1, $mailable->rawAttachments);\n\n        $mailable->attachData('content2', 'report-2.txt');\n        $this->assertCount(2, $mailable->rawAttachments);\n\n        $mailable->attachData('content1', 'report-1.txt');\n        $mailable->attachData('content2', 'report-2.txt');\n        $this->assertCount(2, $mailable->rawAttachments);\n\n        $mailable->attachData('content1', 'report-3.txt');\n        $mailable->attachData('content2', 'report-4.txt');\n        $this->assertCount(4, $mailable->rawAttachments);\n\n        $this->assertSame([\n            [\n                'data' => 'content1',\n                'name' => 'report-1.txt',\n                'options' => [],\n            ],\n            [\n                'data' => 'content2',\n                'name' => 'report-2.txt',\n                'options' => [],\n            ],\n            [\n                'data' => 'content1',\n                'name' => 'report-3.txt',\n                'options' => [],\n            ],\n            [\n                'data' => 'content2',\n                'name' => 'report-4.txt',\n                'options' => [],\n            ],\n        ], $mailable->rawAttachments);\n    }\n\n    public function testItIgnoresDuplicateStorageAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->attachFromStorageDisk('disk1', 'sample/file.txt');\n        $this->assertCount(1, $mailable->diskAttachments);\n\n        $mailable->attachFromStorageDisk('disk1', 'sample/file2.txt');\n        $this->assertCount(2, $mailable->diskAttachments);\n\n        $mailable->attachFromStorageDisk('disk1', 'sample/file.txt', 'file.txt');\n        $mailable->attachFromStorageDisk('disk1', 'sample/file2.txt');\n        $this->assertCount(2, $mailable->diskAttachments);\n\n        $mailable->attachFromStorageDisk('disk2', 'sample/file.txt', 'file.txt');\n        $mailable->attachFromStorageDisk('disk2', 'sample/file2.txt');\n        $this->assertCount(4, $mailable->diskAttachments);\n\n        $mailable->attachFromStorageDisk('disk1', 'sample/file.txt', 'custom.txt');\n        $this->assertCount(5, $mailable->diskAttachments);\n\n        $this->assertSame([\n            [\n                'disk' => 'disk1',\n                'path' => 'sample/file.txt',\n                'name' => 'file.txt',\n                'options' => [],\n            ],\n            [\n                'disk' => 'disk1',\n                'path' => 'sample/file2.txt',\n                'name' => 'file2.txt',\n                'options' => [],\n            ],\n            [\n                'disk' => 'disk2',\n                'path' => 'sample/file.txt',\n                'name' => 'file.txt',\n                'options' => [],\n            ],\n            [\n                'disk' => 'disk2',\n                'path' => 'sample/file2.txt',\n                'name' => 'file2.txt',\n                'options' => [],\n            ],\n            [\n                'disk' => 'disk1',\n                'path' => 'sample/file.txt',\n                'name' => 'custom.txt',\n                'options' => [],\n            ],\n        ], $mailable->diskAttachments);\n    }\n\n    public function testMailableBuildsViewData(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->build();\n\n        $expected = [\n            'first_name' => 'Taylor',\n            'lastName' => 'Otwell',\n            'framework' => 'Laravel',\n            '__laravel_mailable' => get_class($mailable),\n        ];\n\n        $this->assertSame($expected, $mailable->buildViewData());\n    }\n\n    public function testMailerMayBeSet(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->mailer('array');\n        $this->assertTrue($mailable->usesMailer('array'));\n\n        $mailable->mailer('smtp');\n        $this->assertTrue($mailable->usesMailer('smtp'));\n        $this->assertFalse($mailable->usesMailer('ses'));\n    }\n\n    public function testMailablePriorityGetsSent(): void\n    {\n        $view = m::mock(Factory::class);\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('hello@laravel.com');\n        $mailable->from('taylor@laravel.com');\n        $mailable->html('test content');\n\n        $mailable->priority(1);\n\n        $sentMessage = $mailer->send($mailable);\n\n        $this->assertSame('hello@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertStringContainsString('X-Priority: 1 (Highest)', $sentMessage->toString());\n    }\n\n    public function testMailableMetadataGetsSent(): void\n    {\n        $this->stubMailer();\n\n        $view = m::mock(Factory::class);\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('hello@laravel.com');\n        $mailable->from('taylor@laravel.com');\n        $mailable->html('test content');\n\n        $mailable->metadata('origin', 'test-suite');\n        $mailable->metadata('user_id', 1);\n\n        $sentMessage = $mailer->send($mailable);\n\n        $this->assertSame('hello@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertStringContainsString('X-Metadata-origin: test-suite', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-user_id: 1', $sentMessage->toString());\n\n        $this->assertTrue($mailable->hasMetadata('origin', 'test-suite'));\n        $this->assertTrue($mailable->hasMetadata('user_id', 1));\n        $this->assertFalse($mailable->hasMetadata('test', 'test'));\n        $mailable->assertHasMetadata('origin', 'test-suite');\n        $mailable->assertHasMetadata('user_id', 1);\n        try {\n            $mailable->assertHasMetadata('test', 'test');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Email metadata does not match expected value.\\nExpected: [test] => [test]\\nActual: key [test] not found\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n    }\n\n    public function testMailableMergeMetadata(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('hello@laravel.com');\n        $mailable->from('taylor@laravel.com');\n        $mailable->html('test content');\n\n        $mailable->metadata([\n            'template_id' => 'external-template-id',\n            'customer_id' => 101,\n            'order_id' => 1000,\n            'subtotal' => 1500,\n            'gst' => 150,\n            'shipping_fee' => 20,\n            'total' => 1670,\n        ]);\n\n        $this->assertTrue($mailable->hasMetadata('template_id', 'external-template-id'));\n        $this->assertTrue($mailable->hasMetadata('customer_id', 101));\n        $this->assertTrue($mailable->hasMetadata('order_id', 1000));\n        $this->assertTrue($mailable->hasMetadata('subtotal', 1500));\n        $this->assertTrue($mailable->hasMetadata('gst', 150));\n        $this->assertTrue($mailable->hasMetadata('shipping_fee', 20));\n        $this->assertTrue($mailable->hasMetadata('total', 1670));\n\n        $this->stubMailer();\n        $view = m::mock(Factory::class);\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send($mailable);\n        $this->assertStringContainsString('X-Metadata-template_id: external-template-id', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-customer_id: 101', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-order_id: 1000', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-subtotal: 1500', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-gst: 150', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-shipping_fee: 20', $sentMessage->toString());\n        $this->assertStringContainsString('X-Metadata-total: 1670', $sentMessage->toString());\n    }\n\n    public function testMailableTagGetsSent(): void\n    {\n        $this->stubMailer();\n\n        $view = m::mock(Factory::class);\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->to('hello@laravel.com');\n        $mailable->from('taylor@laravel.com');\n        $mailable->html('test content');\n\n        $mailable->tag('test');\n        $mailable->tag('foo');\n\n        $sentMessage = $mailer->send($mailable);\n\n        $this->assertSame('hello@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertStringContainsString('X-Tag: test', $sentMessage->toString());\n        $this->assertStringContainsString('X-Tag: foo', $sentMessage->toString());\n\n        $this->assertTrue($mailable->hasTag('test'));\n        $this->assertTrue($mailable->hasTag('foo'));\n        $this->assertFalse($mailable->hasTag('bar'));\n        $mailable->assertHasTag('test');\n        $mailable->assertHasTag('foo');\n        try {\n            $mailable->assertHasTag('bar');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not see expected tag in email tags.\\nExpected: [bar]\\nActual: [test, foo]\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n    }\n\n    public function testItCanAttachMultipleFiles(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->attachMany([\n            '/forge.svg',\n            '/vapor.svg' => ['as' => 'Vapor Logo.svg', 'mime' => 'text/css'],\n            new class() implements Attachable\n            {\n                public function toMailAttachment()\n                {\n                    return Attachment::fromPath('/foo.jpg')->as('bar')->withMime('image/png');\n                }\n            },\n        ]);\n\n        $this->assertCount(3, $mailable->attachments);\n        $this->assertSame([\n            'file' => '/forge.svg',\n            'options' => [],\n        ], $mailable->attachments[0]);\n        $this->assertSame([\n            'file' => '/vapor.svg',\n            'options' => [\n                'as' => 'Vapor Logo.svg',\n                'mime' => 'text/css',\n            ],\n        ], $mailable->attachments[1]);\n        $this->assertSame([\n            'file' => '/foo.jpg',\n            'options' => [\n                'as' => 'bar',\n                'mime' => 'image/png',\n            ],\n        ], $mailable->attachments[2]);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromPath(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath('/foo.jpg')->as('bar')->withMime('image/png');\n            }\n        });\n\n        $this->assertSame([\n            'file' => '/foo.jpg',\n            'options' => [\n                'as' => 'bar',\n                'mime' => 'image/png',\n            ],\n        ], $mailable->attachments[0]);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromData(): void\n    {\n        $mailable = new WelcomeMailableStub;\n\n        $mailable->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar', 'foo.jpg')->withMime('image/png');\n            }\n        });\n\n        $this->assertSame([\n            'data' => 'bar',\n            'name' => 'foo.jpg',\n            'options' => [\n                'mime' => 'image/png',\n            ],\n        ], $mailable->rawAttachments[0]);\n    }\n\n    public function testItCanJitNameAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $unnamedAttachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar')->withMime('image/png');\n            }\n        };\n\n        $mailable->attach($unnamedAttachable, ['as' => 'foo.jpg']);\n\n        $this->assertSame([\n            'data' => 'bar',\n            'name' => 'foo.jpg',\n            'options' => [\n                'mime' => 'image/png',\n            ],\n        ], $mailable->rawAttachments[0]);\n    }\n\n    public function testHasAttachmentWithJitNamedAttachment(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $unnamedAttachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar')->withMime('image/png');\n            }\n        };\n\n        $mailable->attach($unnamedAttachable, ['as' => 'foo.jpg']);\n\n        $this->assertTrue($mailable->hasAttachment($unnamedAttachable, ['as' => 'foo.jpg']));\n    }\n\n    public function testHasAttachmentWithEnvelopeAttachments(): void\n    {\n        $this->stubMailer();\n        $mailable = new class extends Mailable\n        {\n            public function envelope()\n            {\n                return new Envelope();\n            }\n\n            public function attachments()\n            {\n                return [\n                    Attachment::fromData(fn () => 'bar')\n                        ->withMime('image/png')\n                        ->as('foo.jpg'),\n                ];\n            }\n        };\n        $unnamedAttachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar');\n            }\n        };\n\n        $mailable->render();\n\n        $this->assertFalse($mailable->hasAttachment($unnamedAttachable));\n        $this->assertFalse($mailable->hasAttachment($unnamedAttachable, ['as' => 'foo.jpg']));\n        $this->assertFalse($mailable->hasAttachment($unnamedAttachable, ['mime' => 'image/png']));\n        $this->assertTrue($mailable->hasAttachment($unnamedAttachable, ['as' => 'foo.jpg', 'mime' => 'image/png']));\n    }\n\n    public function testItCanCheckForPathBasedAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach('foo.jpg');\n\n        $this->assertTrue($mailable->hasAttachment('foo.jpg'));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('foo.jpg')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('foo.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('foo.jpg')->withMime('text/css')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg')->withMime('text/css'))));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach('bar.jpg', ['mime' => 'text/css']);\n\n        $this->assertTrue($mailable->hasAttachment('bar.jpg', ['mime' => 'text/css']));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/css')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/css'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg', ['mime' => 'text/html']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/html')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/html'))));\n    }\n\n    public function testItCanCheckForAttachmentBasedAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(Attachment::fromPath('foo.jpg'));\n\n        $this->assertTrue($mailable->hasAttachment('foo.jpg'));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('foo.jpg')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('foo.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('foo.jpg')->withMime('text/css')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg')->withMime('text/css'))));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(Attachment::fromPath('bar.jpg')->withMime('text/css'));\n\n        $this->assertTrue($mailable->hasAttachment('bar.jpg', ['mime' => 'text/css']));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/css')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/css'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg', ['mime' => 'text/html']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/html')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/html'))));\n    }\n\n    public function testItCanCheckForAttachableBasedAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(new MailTestAttachable(Attachment::fromPath('foo.jpg')));\n\n        $this->assertTrue($mailable->hasAttachment('foo.jpg'));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('foo.jpg')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('foo.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('foo.jpg')->withMime('text/css')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('foo.jpg')->withMime('text/css'))));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/css')));\n\n        $this->assertTrue($mailable->hasAttachment('bar.jpg', ['mime' => 'text/css']));\n        $this->assertTrue($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/css')));\n        $this->assertTrue($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/css'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg'));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg'))));\n\n        $this->assertFalse($mailable->hasAttachment('bar.jpg', ['mime' => 'text/html']));\n        $this->assertFalse($mailable->hasAttachment(Attachment::fromPath('bar.jpg')->withMime('text/html')));\n        $this->assertFalse($mailable->hasAttachment(new MailTestAttachable(Attachment::fromPath('bar.jpg')->withMime('text/html'))));\n    }\n\n    public function testItCanCheckForDataBasedAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->attachData('data', 'foo.jpg');\n\n        $this->assertTrue($mailable->hasAttachedData('data', 'foo.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('xxxx', 'foo.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'foo.jpg', ['mime' => 'text/css']));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attachData('data', 'bar.jpg', ['mime' => 'text/css']);\n\n        $this->assertTrue($mailable->hasAttachedData('data', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachedData('xxxx', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg', ['mime' => 'text/html']));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(Attachment::fromData(fn () => 'data', 'foo.jpg'));\n\n        $this->assertTrue($mailable->hasAttachedData('data', 'foo.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('xxxx', 'foo.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'foo.jpg', ['mime' => 'text/css']));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attach(Attachment::fromData(fn () => 'data', 'bar.jpg')->withMime('text/css'));\n\n        $this->assertTrue($mailable->hasAttachedData('data', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachedData('xxxx', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachedData('data', 'bar.jpg', ['mime' => 'text/html']));\n    }\n\n    public function testItCanCheckForStorageBasedAttachments(): void\n    {\n        $mailable = new WelcomeMailableStub;\n        $mailable->attachFromStorageDisk('disk', '/path/to/foo.jpg');\n\n        $this->assertTrue($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('xxxx', '/path/to/foo.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', null, ['mime' => 'text/css']));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attachFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg');\n\n        $this->assertTrue($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('xxxx', '/path/to/foo.jpg', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', 'bar.jpg', 'bar.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'foo.jpg'));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg', ['mime' => 'text/css']));\n\n        $mailable = new WelcomeMailableStub;\n        $mailable->attachFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg', ['mime' => 'text/css']);\n\n        $this->assertTrue($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('xxxx', '/path/to/foo.jpg', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', 'bar.jpg', 'bar.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'foo.jpg', ['mime' => 'text/css']));\n        $this->assertFalse($mailable->hasAttachmentFromStorageDisk('disk', '/path/to/foo.jpg', 'bar.jpg', ['mime' => 'text/html']));\n    }\n\n    public function testAssertHasAttachment(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                //\n            }\n        };\n\n        try {\n            $mailable->assertHasAttachment('/path/to/foo.jpg');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not find the expected attachment.\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                $this->attach('/path/to/foo.jpg');\n            }\n        };\n\n        $mailable->assertHasAttachment('/path/to/foo.jpg');\n    }\n\n    public function testAssertHasAttachedData(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                //\n            }\n        };\n\n        try {\n            $mailable->assertHasAttachedData('data', 'foo.jpg');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not find the expected attachment.\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                $this->attachData('data', 'foo.jpg');\n            }\n        };\n\n        $mailable->assertHasAttachedData('data', 'foo.jpg');\n    }\n\n    public function testAssertHasAttachmentFromStorage(): void\n    {\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                //\n            }\n        };\n\n        try {\n            $mailable->assertHasAttachmentFromStorage('/path/to/foo.jpg');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Did not find the expected attachment.\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                $this->attachFromStorage('/path/to/foo.jpg');\n            }\n        };\n\n        $mailable->assertHasAttachmentFromStorage('/path/to/foo.jpg');\n    }\n\n    public function testAssertHasSubject(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                //\n            }\n        };\n\n        try {\n            $mailable->assertHasSubject('Foo Subject');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringContainsString(\"Email subject does not match expected value.\\nExpected: [Foo Subject]\\nActual:\", $e->getMessage());\n        }\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                $this->subject('Foo Subject');\n            }\n        };\n\n        $mailable->assertHasSubject('Foo Subject');\n    }\n\n    public function testMailableHeadersGetSent(): void\n    {\n        $view = m::mock(Factory::class);\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $mailable = new MailableHeadersStub;\n        $mailable->to('hello@laravel.com');\n        $mailable->from('taylor@laravel.com');\n        $mailable->html('test content');\n\n        $sentMessage = $mailer->send($mailable);\n\n        $this->assertSame('custom-message-id@example.com', $sentMessage->getMessageId());\n\n        $this->assertTrue($sentMessage->getOriginalMessage()->getHeaders()->has('references'));\n        $this->assertEquals('References', $sentMessage->getOriginalMessage()->getHeaders()->get('references')->getName());\n        $this->assertEquals('<previous-message@example.com>', $sentMessage->getOriginalMessage()->getHeaders()->get('references')->getValue());\n\n        $this->assertTrue($sentMessage->getOriginalMessage()->getHeaders()->has('x-custom-header'));\n        $this->assertEquals('X-Custom-Header', $sentMessage->getOriginalMessage()->getHeaders()->get('x-custom-header')->getName());\n        $this->assertEquals('Custom Value', $sentMessage->getOriginalMessage()->getHeaders()->get('x-custom-header')->getValue());\n    }\n\n    public function testMailableAttributesInBuild(): void\n    {\n        $this->stubMailer();\n\n        $mailable = new class() extends Mailable\n        {\n            public function build()\n            {\n                $this\n                    ->to('hello@laravel.com')\n                    ->replyTo('taylor@laravel.com')\n                    ->cc('cc@laravel.com', 'Taylor Otwell')\n                    ->bcc('bcc@laravel.com', 'Taylor Otwell')\n                    ->tag('test-tag')\n                    ->metadata('origin', 'test-suite')\n                    ->metadata('user_id', 1)\n                    ->subject('test subject');\n            }\n        };\n\n        $mailable->assertTo('hello@laravel.com');\n        $mailable->assertHasReplyTo('taylor@laravel.com');\n        $mailable->assertHasCc('cc@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasBcc('bcc@laravel.com', 'Taylor Otwell');\n        $mailable->assertHasTag('test-tag');\n        $mailable->assertHasMetadata('origin', 'test-suite');\n        $mailable->assertHasMetadata('user_id', 1);\n        $mailable->assertHasSubject('test subject');\n    }\n\n    public function testMailablesCanBeTapped(): void\n    {\n        $this->stubMailer();\n\n        $mail = new WelcomeMailableStub;\n\n        $mail->tap(fn ($mailable) => $mailable->to('taylor@laravel.com', 'Taylor Otwell'));\n        $mail->tap(fn ($mailable) => $mailable->subject('Test Subject!'));\n\n        $mail->tap(function ($mailable) {\n            $mailable->assertTo('taylor@laravel.com')\n                ->assertHasSubject('Test Subject!');\n        });\n    }\n\n    protected function stubMailer()\n    {\n        Container::getInstance()->instance('mailer', new class\n        {\n            public function render()\n            {\n                //\n            }\n        });\n    }\n}\n\nclass MailableHeadersStub extends Mailable\n{\n    public function headers()\n    {\n        return new Headers('custom-message-id@example.com', [\n            'previous-message@example.com',\n        ], [\n            'X-Custom-Header' => 'Custom Value',\n        ]);\n    }\n}\n\nclass WelcomeMailableStub extends Mailable\n{\n    public $framework = 'Laravel';\n\n    protected $version = '5.3';\n\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        $this->with('first_name', 'Taylor')\n            ->withLastName('Otwell');\n    }\n}\n\nclass MailableTestUserStub\n{\n    public $name = 'Taylor Otwell';\n    public $email = 'taylor@laravel.com';\n}\n\nclass MailableTestUserStub2\n{\n    public $name = 'Laravel Framework';\n    public $email = 'contact@laravel.com';\n}\n\nclass MailTestAttachable implements Attachable\n{\n    public function __construct(protected $attachment)\n    {\n        //\n    }\n\n    public function toMailAttachment()\n    {\n        return $this->attachment;\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMailerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Mail\\Events\\MessageSending;\nuse Illuminate\\Mail\\Events\\MessageSent;\nuse Illuminate\\Mail\\Mailer;\nuse Illuminate\\Mail\\Message;\nuse Illuminate\\Mail\\Transport\\ArrayTransport;\nuse Illuminate\\Support\\HtmlString;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass MailMailerTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        unset($_SERVER['__mailer.test']);\n\n        parent::tearDown();\n    }\n\n    public function testMailerSendSendsMessageWithProperViewContent(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n\n        $this->assertStringContainsString('rendered.view', $sentMessage->toString());\n    }\n\n    public function testMailerSendSendsMessageWithCcAndBccRecipients(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')\n                ->cc('dries@laravel.com')\n                ->bcc('james@laravel.com')\n                ->from('hello@laravel.com');\n        });\n\n        $recipients = collect($sentMessage->getEnvelope()->getRecipients())->map(function ($recipient) {\n            return $recipient->getAddress();\n        });\n\n        $this->assertStringContainsString('rendered.view', $sentMessage->toString());\n        $this->assertStringContainsString('dries@laravel.com', $sentMessage->toString());\n        $this->assertStringNotContainsString('james@laravel.com', $sentMessage->toString());\n        $this->assertTrue($recipients->contains('james@laravel.com'));\n    }\n\n    public function testMailerSendSendsMessageWithProperViewContentUsingHtmlStrings(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('render')->never();\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send(\n            ['html' => new HtmlString('<p>Hello Laravel</p>'), 'text' => new HtmlString('Hello World')],\n            ['data'],\n            function (Message $message) {\n                $message->to('taylor@laravel.com')->from('hello@laravel.com');\n            }\n        );\n\n        $this->assertStringContainsString('<p>Hello Laravel</p>', $sentMessage->toString());\n        $this->assertStringContainsString('Hello World', $sentMessage->toString());\n    }\n\n    public function testMailerSendSendsMessageWithProperViewContentUsingStringCallbacks(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('render')->never();\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send(\n            [\n                'html' => function ($data) {\n                    $this->assertInstanceOf(Message::class, $data['message']);\n\n                    return new HtmlString('<p>Hello Laravel</p>');\n                },\n                'text' => function ($data) {\n                    $this->assertInstanceOf(Message::class, $data['message']);\n\n                    return new HtmlString('Hello World');\n                },\n            ],\n            [],\n            function (Message $message) {\n                $message->to('taylor@laravel.com')->from('hello@laravel.com');\n            }\n        );\n\n        $this->assertStringContainsString('<p>Hello Laravel</p>', $sentMessage->toString());\n        $this->assertStringContainsString('Hello World', $sentMessage->toString());\n    }\n\n    public function testMailerSendSendsMessageWithProperViewContentUsingHtmlMethod(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('render')->never();\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->html('<p>Hello World</p>', function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n\n        $this->assertStringContainsString('<p>Hello World</p>', $sentMessage->toString());\n    }\n\n    public function testMailerSendSendsMessageWithProperPlainViewContent(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->twice()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $view->shouldReceive('render')->once()->andReturn('rendered.plain');\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send(['foo', 'bar'], ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n\n        $expected = <<<Text\n        Content-Type: text/html; charset=utf-8\\r\n        Content-Transfer-Encoding: quoted-printable\\r\n        \\r\n        rendered.view\n        Text;\n\n        $this->assertStringContainsString($expected, $sentMessage->toString());\n\n        $expected = <<<Text\n        Content-Type: text/plain; charset=utf-8\\r\n        Content-Transfer-Encoding: quoted-printable\\r\n        \\r\n        rendered.plain\n        Text;\n\n        $this->assertStringContainsString($expected, $sentMessage->toString());\n    }\n\n    public function testMailerSendSendsMessageWithProperPlainViewContentWhenExplicit(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->twice()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $view->shouldReceive('render')->once()->andReturn('rendered.plain');\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->send(['html' => 'foo', 'text' => 'bar'], ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n\n        $expected = <<<Text\n        Content-Type: text/html; charset=utf-8\\r\n        Content-Transfer-Encoding: quoted-printable\\r\n        \\r\n        rendered.view\n        Text;\n\n        $this->assertStringContainsString($expected, $sentMessage->toString());\n\n        $expected = <<<Text\n        Content-Type: text/plain; charset=utf-8\\r\n        Content-Transfer-Encoding: quoted-printable\\r\n        \\r\n        rendered.plain\n        Text;\n\n        $this->assertStringContainsString($expected, $sentMessage->toString());\n    }\n\n    public function testToAllowsEmailAndName(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n\n        $sentMessage = $mailer->to('taylor@laravel.com', 'Taylor Otwell')->send(new TestMail());\n\n        $recipients = $sentMessage->getEnvelope()->getRecipients();\n        $this->assertCount(1, $recipients);\n        $this->assertSame('taylor@laravel.com', $recipients[0]->getAddress());\n        $this->assertSame('Taylor Otwell', $recipients[0]->getName());\n    }\n\n    public function testGlobalFromIsRespectedOnAllMessages(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n        $mailer->alwaysFrom('hello@laravel.com');\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com');\n        });\n\n        $this->assertSame('taylor@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertSame('hello@laravel.com', $sentMessage->getEnvelope()->getSender()->getAddress());\n    }\n\n    public function testGlobalReplyToIsRespectedOnAllMessages(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n        $mailer->alwaysReplyTo('taylor@laravel.com', 'Taylor Otwell');\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('dries@laravel.com')->from('hello@laravel.com');\n        });\n\n        $this->assertSame('dries@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertStringContainsString('Reply-To: Taylor Otwell <taylor@laravel.com>', $sentMessage->toString());\n    }\n\n    public function testGlobalToIsRespectedOnAllMessages(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n        $mailer->alwaysTo('taylor@laravel.com', 'Taylor Otwell');\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->from('hello@laravel.com');\n            $message->to('nuno@laravel.com');\n            $message->cc('dries@laravel.com');\n            $message->bcc('james@laravel.com');\n        });\n\n        $recipients = collect($sentMessage->getEnvelope()->getRecipients())->map(function ($recipient) {\n            return $recipient->getAddress();\n        });\n\n        $this->assertSame('taylor@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());\n        $this->assertDoesNotMatchRegularExpression('/^To: nuno@laravel.com/m', $sentMessage->toString());\n        $this->assertDoesNotMatchRegularExpression('/^Cc: dries@laravel.com/m', $sentMessage->toString());\n        $this->assertMatchesRegularExpression('/^X-To: nuno@laravel.com/m', $sentMessage->toString());\n        $this->assertMatchesRegularExpression('/^X-Cc: dries@laravel.com/m', $sentMessage->toString());\n        $this->assertMatchesRegularExpression('/^X-Bcc: james@laravel.com/m', $sentMessage->toString());\n        $this->assertFalse($recipients->contains('nuno@laravel.com'));\n        $this->assertFalse($recipients->contains('dries@laravel.com'));\n        $this->assertFalse($recipients->contains('james@laravel.com'));\n    }\n\n    public function testGlobalReturnPathIsRespectedOnAllMessages(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n\n        $mailer = new Mailer('array', $view, new ArrayTransport);\n        $mailer->alwaysReturnPath('taylorotwell@gmail.com');\n\n        $sentMessage = $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n\n        $this->assertStringContainsString('Return-Path: <taylorotwell@gmail.com>', $sentMessage->toString());\n    }\n\n    public function testEventsAreDispatched(): void\n    {\n        $view = m::mock(Factory::class);\n        $view->shouldReceive('make')->once()->andReturn($view);\n        $view->shouldReceive('render')->once()->andReturn('rendered.view');\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('until')->once()->with(m::type(MessageSending::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(MessageSent::class));\n\n        $mailer = new Mailer('array', $view, new ArrayTransport, $events);\n\n        $mailer->send('foo', ['data'], function (Message $message) {\n            $message->to('taylor@laravel.com')->from('hello@laravel.com');\n        });\n    }\n\n    public function testMacroable(): void\n    {\n        Mailer::macro('foo', function () {\n            return 'bar';\n        });\n\n        $mailer = new Mailer('array', m::mock(Factory::class), new ArrayTransport);\n\n        $this->assertSame(\n            'bar', $mailer->foo()\n        );\n    }\n}\n\nclass TestMail extends \\Illuminate\\Mail\\Mailable\n{\n    public function build()\n    {\n        return $this->view('view')\n            ->from('hello@laravel.com');\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse InvalidArgumentException;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport;\n\nclass MailManagerTest extends TestCase\n{\n    #[DataProvider('emptyTransportConfigDataProvider')]\n    public function testEmptyTransportConfig($transport): void\n    {\n        $this->app['config']->set('mail.mailers.custom_smtp', [\n            'transport' => $transport,\n            'host' => null,\n            'port' => null,\n            'encryption' => null,\n            'username' => null,\n            'password' => null,\n            'timeout' => null,\n        ]);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\"Unsupported mail transport [{$transport}]\");\n        $this->app['mail.manager']->mailer('custom_smtp');\n    }\n\n    #[TestWith([null, 5876])]\n    #[TestWith([null, 465])]\n    #[TestWith(['smtp', 25])]\n    #[TestWith(['smtp', 2525])]\n    #[TestWith(['smtps', 465])]\n    #[TestWith(['smtp', 465])]\n    public function testMailUrlConfig($scheme, $port): void\n    {\n        $this->app['config']->set('mail.mailers.smtp_url', [\n            'scheme' => $scheme,\n            'url' => \"smtp://usr:pwd@127.0.0.2:{$port}\",\n        ]);\n\n        $mailer = $this->app['mail.manager']->mailer('smtp_url');\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertInstanceOf(EsmtpTransport::class, $transport);\n        $this->assertSame('usr', $transport->getUsername());\n        $this->assertSame('pwd', $transport->getPassword());\n        $this->assertSame('127.0.0.2', $transport->getStream()->getHost());\n        $this->assertSame($port, $transport->getStream()->getPort());\n        $this->assertSame($port === 465, $transport->getStream()->isTLS());\n        $this->assertTrue($transport->isAutoTls());\n    }\n\n    #[TestWith([null, 5876])]\n    #[TestWith([null, 465])]\n    #[TestWith(['smtp', 25])]\n    #[TestWith(['smtp', 2525])]\n    #[TestWith(['smtps', 465])]\n    #[TestWith(['smtp', 465])]\n    public function testMailUrlConfigWithAutoTls($scheme, $port): void\n    {\n        $this->app['config']->set('mail.mailers.smtp_url', [\n            'scheme' => $scheme,\n            'url' => \"smtp://usr:pwd@127.0.0.2:{$port}?auto_tls=true\",\n        ]);\n\n        $mailer = $this->app['mail.manager']->mailer('smtp_url');\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertInstanceOf(EsmtpTransport::class, $transport);\n        $this->assertSame('usr', $transport->getUsername());\n        $this->assertSame('pwd', $transport->getPassword());\n        $this->assertSame('127.0.0.2', $transport->getStream()->getHost());\n        $this->assertSame($port, $transport->getStream()->getPort());\n        $this->assertSame($port === 465, $transport->getStream()->isTLS());\n        $this->assertTrue($transport->isAutoTls());\n    }\n\n    #[TestWith([null, 5876])]\n    #[TestWith([null, 465])]\n    #[TestWith(['smtp', 25])]\n    #[TestWith(['smtp', 2525])]\n    #[TestWith(['smtps', 465])]\n    #[TestWith(['smtp', 465])]\n    public function testMailUrlConfigWithAutoTlsDisabled($scheme, $port): void\n    {\n        $this->app['config']->set('mail.mailers.smtp_url', [\n            'scheme' => $scheme,\n            'url' => \"smtp://usr:pwd@127.0.0.2:{$port}?auto_tls=false\",\n        ]);\n\n        $mailer = $this->app['mail.manager']->mailer('smtp_url');\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertInstanceOf(EsmtpTransport::class, $transport);\n        $this->assertSame('usr', $transport->getUsername());\n        $this->assertSame('pwd', $transport->getPassword());\n        $this->assertSame('127.0.0.2', $transport->getStream()->getHost());\n        $this->assertSame($port, $transport->getStream()->getPort());\n        $this->assertFalse($transport->isAutoTls());\n        $this->assertSame($port === 465 && $scheme !== 'smtp', $transport->getStream()->isTLS());\n    }\n\n    public function testBuild(): void\n    {\n        $config = [\n            'transport' => 'smtp',\n            'host' => '127.0.0.2',\n            'port' => 5876,\n            'encryption' => 'tls',\n            'username' => 'usr',\n            'password' => 'pwd',\n            'timeout' => 5,\n        ];\n\n        $mailer = $this->app['mail.manager']->build($config);\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertInstanceOf(EsmtpTransport::class, $transport);\n        $this->assertSame('usr', $transport->getUsername());\n        $this->assertSame('pwd', $transport->getPassword());\n        $this->assertSame('127.0.0.2', $transport->getStream()->getHost());\n        $this->assertSame(5876, $transport->getStream()->getPort());\n    }\n\n    public static function emptyTransportConfigDataProvider()\n    {\n        return [\n            [null], [''], [' '],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailMessageTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Mail\\Message;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mime\\Address;\nuse Symfony\\Component\\Mime\\Email;\n\nclass MailMessageTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Mail\\Message\n     */\n    protected $message;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->message = new Message(new Email());\n    }\n\n    public function testFromMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->from('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getFrom()[0]);\n    }\n\n    public function testSenderMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->sender('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getSender());\n    }\n\n    public function testReturnPathMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->returnPath('foo@bar.baz'));\n        $this->assertEquals(new Address('foo@bar.baz'), $this->message->getSymfonyMessage()->getReturnPath());\n    }\n\n    public function testToMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->to('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getTo()[0]);\n\n        $this->assertSame($this->message, $this->message->to(['bar@bar.baz' => 'Bar']));\n        $this->assertEquals(new Address('bar@bar.baz', 'Bar'), $this->message->getSymfonyMessage()->getTo()[0]);\n    }\n\n    public function testToMethodWithOverride(): void\n    {\n        $this->assertSame($this->message, $this->message->to('foo@bar.baz', 'Foo', true));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getTo()[0]);\n    }\n\n    public function testCcMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->cc('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getCc()[0]);\n    }\n\n    public function testBccMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->bcc('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getBcc()[0]);\n    }\n\n    public function testReplyToMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->replyTo('foo@bar.baz', 'Foo'));\n        $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $this->message->getSymfonyMessage()->getReplyTo()[0]);\n    }\n\n    public function testSubjectMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->subject('foo'));\n        $this->assertSame('foo', $this->message->getSymfonyMessage()->getSubject());\n    }\n\n    public function testPriorityMethod(): void\n    {\n        $this->assertSame($this->message, $this->message->priority(1));\n        $this->assertEquals(1, $this->message->getSymfonyMessage()->getPriority());\n    }\n\n    public function testBasicAttachment(): void\n    {\n        file_put_contents($path = __DIR__.'/foo.jpg', 'expected attachment body');\n\n        $this->message->attach($path, ['as' => 'bar.jpg', 'mime' => 'image/png']);\n\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('expected attachment body', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=bar.jpg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: attachment; name=bar.jpg; filename=bar.jpg', $headers[2]);\n\n        unlink($path);\n    }\n\n    public function testDataAttachment(): void\n    {\n        $this->message->attachData('expected attachment body', 'foo.jpg', ['mime' => 'image/png']);\n\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('expected attachment body', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=foo.jpg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: attachment; name=foo.jpg; filename=foo.jpg', $headers[2]);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromPath(): void\n    {\n        file_put_contents($path = __DIR__.'/foo.jpg', 'expected attachment body');\n\n        $this->message->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath(__DIR__.'/foo.jpg')\n                    ->as('bar.jpg')\n                    ->withMime('image/png');\n            }\n        });\n\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('expected attachment body', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=bar.jpg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: attachment; name=bar.jpg; filename=bar.jpg', $headers[2]);\n\n        unlink($path);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromData(): void\n    {\n        $this->message->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'expected attachment body', 'foo.jpg')\n                    ->withMime('image/png');\n            }\n        });\n\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('expected attachment body', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=foo.jpg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: attachment; name=foo.jpg; filename=foo.jpg', $headers[2]);\n    }\n\n    public function testEmbedPath(): void\n    {\n        file_put_contents($path = __DIR__.'/foo.jpg', 'bar');\n\n        $cid = $this->message->embed($path);\n\n        $this->assertStringStartsWith('cid:', $cid);\n        $contentId = Str::after($cid, 'cid:');\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('bar', $attachment->getBody());\n        $this->assertSame($contentId, $attachment->getContentId());\n        $this->assertStringContainsString('Content-Type: image/jpeg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertStringContainsString('Content-Disposition: inline', $headers[2]);\n\n        unlink($path);\n    }\n\n    public function testDataEmbed(): void\n    {\n        $cid = $this->message->embedData('bar', 'foo.jpg', 'image/png');\n\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertStringStartsWith('cid:', $cid);\n        $contentId = Str::after($cid, 'cid:');\n        $this->assertSame($contentId, $attachment->getContentId());\n        $this->assertSame('bar', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=foo.jpg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: inline; name=foo.jpg; filename=foo.jpg', $headers[2]);\n    }\n\n    public function testItEmbedsFilesViaAttachableContractFromPath(): void\n    {\n        file_put_contents($path = __DIR__.'/foo.jpg', 'bar');\n\n        $cid = $this->message->embed(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath(__DIR__.'/foo.jpg')->as('baz')->withMime('image/png');\n            }\n        });\n\n        $this->assertStringStartsWith('cid:', $cid);\n        $contentId = Str::after($cid, 'cid:');\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame($contentId, $attachment->getContentId());\n        $this->assertSame('bar', $attachment->getBody());\n        $this->assertSame('Content-Type: image/png; name=baz', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertSame('Content-Disposition: inline; name=baz; filename=baz', $headers[2]);\n\n        unlink($path);\n    }\n\n    public function testItGeneratesARandomNameWhenAttachableHasNone(): void\n    {\n        file_put_contents($path = __DIR__.'/foo.jpg', 'bar');\n\n        $cid = $this->message->embed(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath(__DIR__.'/foo.jpg');\n            }\n        });\n\n        $this->assertStringStartsWith('cid:', $cid);\n        $contentId = Str::after($cid, 'cid:');\n        $attachment = $this->message->getSymfonyMessage()->getAttachments()[0];\n        $this->assertSame($contentId, $attachment->getContentId());\n        $headers = $attachment->getPreparedHeaders()->toArray();\n        $this->assertSame('bar', $attachment->getBody());\n        $this->assertStringContainsString('Content-Type: image/jpeg', $headers[0]);\n        $this->assertSame('Content-Transfer-Encoding: base64', $headers[1]);\n        $this->assertStringContainsString('Content-Disposition: inline', $headers[2]);\n\n        unlink($path);\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailRoundRobinTransportTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Orchestra\\Testbench\\TestCase;\nuse Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport;\n\nclass MailRoundRobinTransportTest extends TestCase\n{\n    public function testGetRoundRobinTransportWithConfiguredTransports(): void\n    {\n        $this->app['config']->set('mail.default', 'roundrobin');\n\n        $this->app['config']->set('mail.mailers', [\n            'roundrobin' => [\n                'transport' => 'roundrobin',\n                'mailers' => [\n                    'sendmail',\n                    'array',\n                ],\n            ],\n\n            'sendmail' => [\n                'transport' => 'sendmail',\n                'path' => '/usr/sbin/sendmail -bs',\n            ],\n\n            'array' => [\n                'transport' => 'array',\n            ],\n        ]);\n\n        $transport = app('mailer')->getSymfonyTransport();\n        $this->assertInstanceOf(RoundRobinTransport::class, $transport);\n    }\n\n    public function testGetRoundRobinTransportWithLaravel6StyleMailConfiguration(): void\n    {\n        $this->app['config']->set('mail.driver', 'roundrobin');\n\n        $this->app['config']->set('mail.mailers', [\n            'sendmail',\n            'array',\n        ]);\n\n        $this->app['config']->set('mail.sendmail', '/usr/sbin/sendmail -bs');\n\n        $transport = app('mailer')->getSymfonyTransport();\n        $this->assertInstanceOf(RoundRobinTransport::class, $transport);\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailSesTransportTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Aws\\Command;\nuse Aws\\Exception\\AwsException;\nuse Aws\\Ses\\SesClient;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Mail\\MailManager;\nuse Illuminate\\Mail\\Transport\\SesTransport;\nuse Illuminate\\View\\Factory;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mime\\Address;\nuse Symfony\\Component\\Mime\\Email;\n\nclass MailSesTransportTest extends TestCase\n{\n    public function testGetTransport(): void\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'services.ses' => [\n                    'key' => 'foo',\n                    'secret' => 'bar',\n                    'region' => 'us-east-1',\n                ],\n            ]);\n        });\n\n        $manager = new MailManager($container);\n\n        /** @var \\Illuminate\\Mail\\Transport\\SesTransport $transport */\n        $transport = $manager->createSymfonyTransport(['transport' => 'ses']);\n\n        $ses = $transport->ses();\n\n        $this->assertSame('us-east-1', $ses->getRegion());\n\n        $this->assertSame('ses', (string) $transport);\n    }\n\n    public function testSend(): void\n    {\n        $message = new Email();\n        $message->subject('Foo subject');\n        $message->text('Bar body');\n        $message->sender('myself@example.com');\n        $message->to('me@example.com');\n        $message->bcc('you@example.com');\n        $message->replyTo(new Address('taylor@example.com', 'Taylor Otwell'));\n        $message->getHeaders()->add(new MetadataHeader('FooTag', 'TagValue'));\n        $message->getHeaders()->addTextHeader('X-Ses-List-Management-Options', 'contactListName=TestList;topicName=TestTopic');\n\n        $client = m::mock(SesClient::class);\n        $sesResult = m::mock();\n        $sesResult->shouldReceive('get')\n            ->with('MessageId')\n            ->once()\n            ->andReturn('ses-message-id');\n        $client->shouldReceive('sendRawEmail')->once()\n            ->with(m::on(function ($arg) {\n                return $arg['Source'] === 'myself@example.com' &&\n                    $arg['Destinations'] === ['me@example.com', 'you@example.com'] &&\n                    $arg['ListManagementOptions'] === ['ContactListName' => 'TestList', 'TopicName' => 'TestTopic'] &&\n                    $arg['Tags'] === [['Name' => 'FooTag', 'Value' => 'TagValue']] &&\n                    str_contains($arg['RawMessage']['Data'], 'Reply-To: Taylor Otwell <taylor@example.com>');\n            }))\n            ->andReturn($sesResult);\n\n        (new SesTransport($client))->send($message);\n    }\n\n    public function testSendError(): void\n    {\n        $message = new Email();\n        $message->subject('Foo subject');\n        $message->text('Bar body');\n        $message->sender('myself@example.com');\n        $message->to('me@example.com');\n\n        $client = m::mock(SesClient::class);\n        $client->shouldReceive('sendRawEmail')->once()\n            ->andThrow(new AwsException('Email address is not verified.', new Command('sendRawEmail')));\n\n        $this->expectException(TransportException::class);\n\n        (new SesTransport($client))->send($message);\n    }\n\n    public function testSesLocalConfiguration(): void\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'mail' => [\n                    'mailers' => [\n                        'ses' => [\n                            'transport' => 'ses',\n                            'region' => 'eu-west-1',\n                            'options' => [\n                                'ConfigurationSetName' => 'Laravel',\n                                'Tags' => [\n                                    ['Name' => 'Laravel', 'Value' => 'Framework'],\n                                ],\n                            ],\n                        ],\n                    ],\n                ],\n                'services' => [\n                    'ses' => [\n                        'region' => 'us-east-1',\n                    ],\n                ],\n            ]);\n        });\n\n        $container->instance('view', $this->createMock(Factory::class));\n\n        $container->bind('events', function () {\n            return null;\n        });\n\n        $manager = new MailManager($container);\n\n        /** @var \\Illuminate\\Mail\\Mailer $mailer */\n        $mailer = $manager->mailer('ses');\n\n        /** @var \\Illuminate\\Mail\\Transport\\SesTransport $transport */\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertSame('eu-west-1', $transport->ses()->getRegion());\n\n        $this->assertSame([\n            'ConfigurationSetName' => 'Laravel',\n            'Tags' => [\n                ['Name' => 'Laravel', 'Value' => 'Framework'],\n            ],\n        ], $transport->getOptions());\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailSesV2TransportTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Aws\\Command;\nuse Aws\\Exception\\AwsException;\nuse Aws\\SesV2\\SesV2Client;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Mail\\MailManager;\nuse Illuminate\\Mail\\Transport\\SesV2Transport;\nuse Illuminate\\View\\Factory;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Component\\Mailer\\Header\\MetadataHeader;\nuse Symfony\\Component\\Mime\\Address;\nuse Symfony\\Component\\Mime\\Email;\n\nclass MailSesV2TransportTest extends TestCase\n{\n    public function testGetTransport(): void\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'services.ses' => [\n                    'key' => 'foo',\n                    'secret' => 'bar',\n                    'region' => 'us-east-1',\n                ],\n            ]);\n        });\n\n        $manager = new MailManager($container);\n\n        /** @var \\Illuminate\\Mail\\Transport\\SesV2Transport $transport */\n        $transport = $manager->createSymfonyTransport(['transport' => 'ses-v2']);\n\n        $ses = $transport->ses();\n\n        $this->assertSame('us-east-1', $ses->getRegion());\n\n        $this->assertSame('ses-v2', (string) $transport);\n    }\n\n    public function testSend(): void\n    {\n        $message = new Email();\n        $message->subject('Foo subject');\n        $message->text('Bar body');\n        $message->sender('myself@example.com');\n        $message->to('me@example.com');\n        $message->bcc('you@example.com');\n        $message->replyTo(new Address('taylor@example.com', 'Taylor Otwell'));\n        $message->getHeaders()->add(new MetadataHeader('FooTag', 'TagValue'));\n        $message->getHeaders()->addTextHeader('X-SES-LIST-MANAGEMENT-OPTIONS', 'contactListName=TestList;topicName=TestTopic');\n\n        $client = m::mock(SesV2Client::class);\n        $sesResult = m::mock();\n        $sesResult->shouldReceive('get')\n            ->with('MessageId')\n            ->once()\n            ->andReturn('ses-message-id');\n        $client->shouldReceive('sendEmail')->once()\n            ->with(m::on(function ($arg) {\n                return $arg['Source'] === 'myself@example.com' &&\n                    $arg['Destination']['ToAddresses'] === ['me@example.com', 'you@example.com'] &&\n                    $arg['ListManagementOptions'] === ['ContactListName' => 'TestList', 'TopicName' => 'TestTopic'] &&\n                    $arg['EmailTags'] === [['Name' => 'FooTag', 'Value' => 'TagValue']] &&\n                    str_contains($arg['Content']['Raw']['Data'], 'Reply-To: Taylor Otwell <taylor@example.com>');\n            }))\n            ->andReturn($sesResult);\n\n        (new SesV2Transport($client))->send($message);\n    }\n\n    public function testSendError(): void\n    {\n        $message = new Email();\n        $message->subject('Foo subject');\n        $message->text('Bar body');\n        $message->sender('myself@example.com');\n        $message->to('me@example.com');\n\n        $client = m::mock(SesV2Client::class);\n        $client->shouldReceive('sendEmail')->once()\n            ->andThrow(new AwsException('Email address is not verified.', new Command('sendRawEmail')));\n\n        $this->expectException(TransportException::class);\n\n        (new SesV2Transport($client))->send($message);\n    }\n\n    public function testSesV2LocalConfiguration(): void\n    {\n        $container = new Container;\n\n        $container->singleton('config', function () {\n            return new Repository([\n                'mail' => [\n                    'mailers' => [\n                        'ses' => [\n                            'transport' => 'ses-v2',\n                            'region' => 'eu-west-1',\n                            'options' => [\n                                'ConfigurationSetName' => 'Laravel',\n                                'EmailTags' => [\n                                    ['Name' => 'Laravel', 'Value' => 'Framework'],\n                                ],\n                            ],\n                        ],\n                    ],\n                ],\n                'services' => [\n                    'ses' => [\n                        'region' => 'us-east-1',\n                    ],\n                ],\n            ]);\n        });\n\n        $container->instance('view', $this->createMock(Factory::class));\n\n        $container->bind('events', function () {\n            return null;\n        });\n\n        $manager = new MailManager($container);\n\n        /** @var \\Illuminate\\Mail\\Mailer $mailer */\n        $mailer = $manager->mailer('ses');\n\n        /** @var \\Illuminate\\Mail\\Transport\\SesV2Transport $transport */\n        $transport = $mailer->getSymfonyTransport();\n\n        $this->assertSame('eu-west-1', $transport->ses()->getRegion());\n\n        $this->assertSame([\n            'ConfigurationSetName' => 'Laravel',\n            'EmailTags' => [\n                ['Name' => 'Laravel', 'Value' => 'Framework'],\n            ],\n        ], $transport->getOptions());\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailableAlternativeSyntaxTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailables\\Address;\nuse Illuminate\\Mail\\Mailables\\Content;\nuse Illuminate\\Mail\\Mailables\\Envelope;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nclass MailableAlternativeSyntaxTest extends TestCase\n{\n    public function testBasicMailableInspection(): void\n    {\n        $mailable = new MailableWithAlternativeSyntax;\n\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com'));\n        $this->assertTrue($mailable->hasCc('adam@laravel.com'));\n        $this->assertTrue($mailable->hasBcc('tyler@laravel.com'));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n        $this->assertFalse($mailable->hasTo('taylor@laravel.com', 'Wrong Name'));\n\n        $mailable->to(new Address('abigail@laravel.com', 'Abigail Otwell'));\n        $this->assertTrue($mailable->hasTo('taylor@laravel.com', 'Taylor Otwell'));\n\n        $this->assertTrue($mailable->hasSubject('Test Subject'));\n        $this->assertFalse($mailable->hasSubject('Wrong Subject'));\n        $this->assertTrue($mailable->hasTag('tag-1'));\n        $this->assertTrue($mailable->hasMetadata('test-meta', 'test-meta-value'));\n\n        $reflection = new ReflectionClass($mailable);\n        $method = $reflection->getMethod('prepareMailableForDelivery');\n        $method->invoke($mailable);\n\n        $this->assertEquals('test-view', $mailable->view);\n        $this->assertEquals(['test-data-key' => 'test-data-value'], $mailable->viewData);\n        $this->assertEquals(2, count($mailable->to));\n        $this->assertEquals(1, count($mailable->cc));\n        $this->assertEquals(1, count($mailable->bcc));\n    }\n\n    public function testEnvelopesCanReceiveAdditionalRecipients(): void\n    {\n        $envelope = new Envelope(to: ['taylor@example.com']);\n        $envelope->to(new Address('taylorotwell@example.com'));\n\n        $this->assertCount(2, $envelope->to);\n        $this->assertEquals('taylor@example.com', $envelope->to[0]->address);\n        $this->assertEquals('taylorotwell@example.com', $envelope->to[1]->address);\n\n        $envelope->to('abigailotwell@example.com', 'Abigail Otwell');\n        $this->assertEquals('abigailotwell@example.com', $envelope->to[2]->address);\n        $this->assertEquals('Abigail Otwell', $envelope->to[2]->name);\n\n        $envelope->to('adam@example.com');\n        $this->assertEquals('adam@example.com', $envelope->to[3]->address);\n        $this->assertNull($envelope->to[3]->name);\n\n        $envelope->to(['jeffrey@example.com', 'tyler@example.com']);\n        $this->assertEquals('jeffrey@example.com', $envelope->to[4]->address);\n        $this->assertEquals('tyler@example.com', $envelope->to[5]->address);\n\n        $envelope->from('dries@example.com', 'Dries Vints');\n        $this->assertEquals('dries@example.com', $envelope->from->address);\n        $this->assertEquals('Dries Vints', $envelope->from->name);\n    }\n}\n\nclass MailableWithAlternativeSyntax extends Mailable\n{\n    public function envelope()\n    {\n        return new Envelope(\n            to: [new Address('taylor@laravel.com', 'Taylor Otwell')],\n            cc: [new Address('adam@laravel.com', 'Adam Wathan')],\n            bcc: [new Address('tyler@laravel.com', 'Tyler Blair')],\n            subject: 'Test Subject',\n            tags: ['tag-1', 'tag-2'],\n            metadata: ['test-meta' => 'test-meta-value'],\n        );\n    }\n\n    public function content()\n    {\n        return new Content(\n            view: 'test-view',\n            with: ['test-data-key' => 'test-data-value'],\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Mail/MailableQueuedTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Mail;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\View\\Factory;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Filesystem\\FilesystemManager;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\Mailer;\nuse Illuminate\\Mail\\SendQueuedMailable;\nuse Illuminate\\Support\\Testing\\Fakes\\QueueFake;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mailer\\Transport\\TransportInterface;\n\nclass MailableQueuedTest extends TestCase\n{\n    public function testQueuedMailableSent(): void\n    {\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage', 'to'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $mailable = new MailableQueueableStub;\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n    }\n\n    public function testQueuedMailableWithAttachmentSent(): void\n    {\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $mailable = new MailableQueueableStub;\n        $attachmentOption = ['mime' => 'image/jpeg', 'as' => 'bar.jpg'];\n        $mailable->attach('foo.jpg', $attachmentOption);\n        $this->assertIsArray($mailable->attachments);\n        $this->assertCount(1, $mailable->attachments);\n        $this->assertEquals($mailable->attachments[0]['options'], $attachmentOption);\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n    }\n\n    public function testQueuedMailableWithAttachmentFromDiskSent(): void\n    {\n        $app = new Application;\n        $container = Container::getInstance();\n        $this->getMockBuilder(Filesystem::class)\n            ->getMock();\n        $filesystemFactory = $this->getMockBuilder(FilesystemManager::class)\n            ->setConstructorArgs([$app])\n            ->getMock();\n        $container->instance('filesystem', $filesystemFactory);\n        $queueFake = new QueueFake($app);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $mailable = new MailableQueueableStub;\n        $attachmentOption = ['mime' => 'image/jpeg', 'as' => 'bar.jpg'];\n\n        $mailable->attachFromStorage('/', 'foo.jpg', $attachmentOption);\n\n        $this->assertIsArray($mailable->diskAttachments);\n        $this->assertCount(1, $mailable->diskAttachments);\n        $this->assertEquals($mailable->diskAttachments[0]['options'], $attachmentOption);\n\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n    }\n\n    public function testQueuedMailableForwardsMessageGroupFromMethodToQueueJob(): void\n    {\n        $mockedMessageGroupId = 'group-1';\n\n        $mailable = $this->getMockBuilder(MailableQueueableStubWithMessageGroup::class)->onlyMethods(['messageGroup'])->getMock();\n        $mailable->expects($this->once())->method('messageGroup')->willReturn($mockedMessageGroupId);\n\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage', 'to'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n\n        $pushedJob = $queueFake->pushed(SendQueuedMailable::class)->first();\n        $this->assertEquals($mockedMessageGroupId, $pushedJob->messageGroup);\n    }\n\n    public function testQueuedMailableForwardsMessageGroupFromPropertyOverridingMethodToQueueJob(): void\n    {\n        $mockedMessageGroupId = 'group-1';\n\n        // Ensure the messageGroup method is not called when a messageGroup property is provided.\n        $mailable = $this->getMockBuilder(MailableQueueableStubWithMessageGroup::class)->onlyMethods(['messageGroup'])->getMock();\n        $mailable->expects($this->never())->method('messageGroup')->willReturn('this-should-not-be-used');\n        $mailable->onGroup($mockedMessageGroupId);\n\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage', 'to'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n\n        $pushedJob = $queueFake->pushed(SendQueuedMailable::class)->first();\n        $this->assertEquals($mockedMessageGroupId, $pushedJob->messageGroup);\n    }\n\n    public function testQueuedMailableForwardsDeduplicatorToQueueJob(): void\n    {\n        $mockedDeduplicator = fn ($payload, $queue) => 'deduplication-id-1';\n\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage', 'to'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $mailable = (new MailableQueueableStub)->withDeduplicator($mockedDeduplicator);\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n\n        $pushedJob = $queueFake->pushed(SendQueuedMailable::class)->first();\n        $this->assertInstanceOf(SerializableClosure::class, $pushedJob->deduplicator);\n        $this->assertEquals($mockedDeduplicator, $pushedJob->deduplicator->getClosure());\n    }\n\n    public function testQueuedMailableForwardsDeduplicationIdMethodToQueueJob(): void\n    {\n        $queueFake = new QueueFake(new Application);\n        $mailer = $this->getMockBuilder(Mailer::class)\n            ->setConstructorArgs($this->getMocks())\n            ->onlyMethods(['createMessage', 'to'])\n            ->getMock();\n        $mailer->setQueue($queueFake);\n        $mailable = new MailableQueueableStubWithDeduplication;\n        $queueFake->assertNothingPushed();\n        $mailer->send($mailable);\n        $queueFake->assertPushedOn(null, SendQueuedMailable::class);\n\n        $pushedJob = $queueFake->pushed(SendQueuedMailable::class)->first();\n        $this->assertInstanceOf(SerializableClosure::class, $pushedJob->deduplicator);\n        $this->assertEquals($mailable->deduplicationId(...), $pushedJob->deduplicator->getClosure());\n    }\n\n    protected function getMocks()\n    {\n        return ['smtp', m::mock(Factory::class), m::mock(TransportInterface::class)];\n    }\n}\n\nclass MailableQueueableStub extends Mailable implements ShouldQueue\n{\n    use Queueable;\n\n    public function build(): self\n    {\n        $this\n            ->subject('lorem ipsum')\n            ->html('foo bar baz')\n            ->to('foo@example.tld');\n\n        return $this;\n    }\n}\n\nclass MailableQueueableStubWithMessageGroup extends Mailable implements ShouldQueue\n{\n    use Queueable;\n\n    public function build(): self\n    {\n        $this\n            ->subject('lorem ipsum')\n            ->html('foo bar baz')\n            ->to('foo@example.tld');\n\n        return $this;\n    }\n\n    public function messageGroup(): string\n    {\n        return 'group-1';\n    }\n}\n\nclass MailableQueueableStubWithDeduplication extends Mailable implements ShouldQueue\n{\n    use Queueable;\n\n    public function build(): self\n    {\n        $this\n            ->subject('lorem ipsum')\n            ->html('foo bar baz')\n            ->to('foo@example.tld');\n\n        return $this;\n    }\n\n    public function deduplicationId($payload, $queue)\n    {\n        return hash('sha256', $payload);\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationActionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Notifications\\Action;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationActionTest extends TestCase\n{\n    public function testActionIsCreatedProperly()\n    {\n        $action = new Action('Text', 'url');\n\n        $this->assertSame('Text', $action->text);\n        $this->assertSame('url', $action->url);\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationBroadcastChannelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Broadcasting\\PrivateChannel;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Notifications\\Channels\\BroadcastChannel;\nuse Illuminate\\Notifications\\Events\\BroadcastNotificationCreated;\nuse Illuminate\\Notifications\\Messages\\BroadcastMessage;\nuse Illuminate\\Notifications\\Notification;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationBroadcastChannelTest extends TestCase\n{\n    public function testDatabaseChannelCreatesDatabaseRecordWithProperData()\n    {\n        $notification = new NotificationBroadcastChannelTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::type(BroadcastNotificationCreated::class));\n        $channel = new BroadcastChannel($events);\n        $channel->send($notifiable, $notification);\n    }\n\n    public function testNotificationIsBroadcastedOnCustomChannels()\n    {\n        $notification = new CustomChannelsTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $event = new BroadcastNotificationCreated(\n            $notifiable, $notification, $notification->toArray($notifiable)\n        );\n\n        $channels = $event->broadcastOn();\n\n        $this->assertEquals(new PrivateChannel('custom-channel'), $channels[0]);\n    }\n\n    public function testNotificationIsBroadcastedWithCustomEventName()\n    {\n        $notification = new CustomEventNameTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $event = new BroadcastNotificationCreated(\n            $notifiable, $notification, $notification->toArray($notifiable)\n        );\n\n        $eventName = $event->broadcastType();\n\n        $this->assertSame('custom.type', $eventName);\n    }\n\n    public function testNotificationIsBroadcastedWithCustomDataType()\n    {\n        $notification = new CustomEventNameTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $event = new BroadcastNotificationCreated(\n            $notifiable, $notification, $notification->toArray($notifiable)\n        );\n\n        $data = $event->broadcastWith();\n\n        $this->assertSame('custom.type', $data['type']);\n    }\n\n    public function testNotificationIsBroadcastedNow()\n    {\n        $notification = new TestNotificationBroadCastedNow;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) {\n            return $event->connection === 'sync';\n        }));\n        $channel = new BroadcastChannel($events);\n        $channel->send($notifiable, $notification);\n    }\n\n    public function testNotificationIsBroadcastedWithCustomAdditionalPayload()\n    {\n        $notification = new CustomBroadcastWithTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $event = new BroadcastNotificationCreated(\n            $notifiable, $notification, $notification->toArray($notifiable)\n        );\n\n        $data = $event->broadcastWith();\n\n        $this->assertArrayHasKey('additional', $data);\n    }\n}\n\nclass NotificationBroadcastChannelTestNotification extends Notification\n{\n    public function toArray($notifiable)\n    {\n        return ['invoice_id' => 1];\n    }\n}\n\nclass CustomChannelsTestNotification extends Notification\n{\n    public function toArray($notifiable)\n    {\n        return ['invoice_id' => 1];\n    }\n\n    public function broadcastOn()\n    {\n        return [new PrivateChannel('custom-channel')];\n    }\n}\n\nclass CustomEventNameTestNotification extends Notification\n{\n    public function toArray($notifiable)\n    {\n        return ['invoice_id' => 1];\n    }\n\n    public function broadcastType()\n    {\n        return 'custom.type';\n    }\n}\n\nclass TestNotificationBroadCastedNow extends Notification\n{\n    public function toArray($notifiable)\n    {\n        return ['invoice_id' => 1];\n    }\n\n    public function toBroadcast()\n    {\n        return (new BroadcastMessage([]))->onConnection('sync');\n    }\n}\n\nclass CustomBroadcastWithTestNotification extends Notification\n{\n    public function toArray($notifiable)\n    {\n        return ['invoice_id' => 1];\n    }\n\n    public function broadcastWith()\n    {\n        return ['id' => 1, 'type' => 'custom', 'additional' => 'custom'];\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationChannelManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Exception;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as Bus;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Notifications\\ChannelManager;\nuse Illuminate\\Notifications\\Events\\NotificationFailed;\nuse Illuminate\\Notifications\\Events\\NotificationSending;\nuse Illuminate\\Notifications\\Events\\NotificationSent;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Notifications\\SendQueuedNotifications;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\QueueRoutes;\nuse Illuminate\\Queue\\SerializesModels;\nuse Illuminate\\Support\\Collection;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationChannelManagerTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testNotificationCanBeDispatchedToDriver()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $driver->shouldReceive('send')->once();\n        $events->shouldReceive('dispatch')->with(m::type(NotificationSent::class));\n\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n    }\n\n    public function testNotificationNotSentOnHalt()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->once()->with(m::type(NotificationSending::class))->andReturn(false);\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $manager->shouldReceive('driver')->once()->andReturn($driver = m::mock());\n        $driver->shouldReceive('send')->once();\n        $events->shouldReceive('dispatch')->with(m::type(NotificationSent::class));\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], new NotificationChannelManagerTestNotificationWithTwoChannels);\n    }\n\n    public function testNotificationNotSentWhenCancelled()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $manager->shouldNotReceive('driver');\n        $events->shouldNotReceive('dispatch');\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], new NotificationChannelManagerTestCancelledNotification);\n    }\n\n    public function testNotificationSentWhenNotCancelled()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $manager->shouldReceive('driver')->once()->andReturn($driver = m::mock());\n        $driver->shouldReceive('send')->once();\n        $events->shouldReceive('dispatch')->once()->with(m::type(NotificationSent::class));\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], new NotificationChannelManagerTestNotCancelledNotification);\n    }\n\n    public function testNotificationNotSentWhenFailed()\n    {\n        $this->expectException(Exception::class);\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $driver->shouldReceive('send')->andThrow(new Exception());\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->with(m::type(NotificationFailed::class));\n        $events->shouldReceive('dispatch')->never()->with(m::type(NotificationSent::class));\n\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n    }\n\n    public function testNotificationFailedDispatchedOnlyOnceWhenFailed()\n    {\n        $this->expectException(Exception::class);\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock(Dispatcher::class));\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $driver->shouldReceive('send')->andReturnUsing(function ($notifiable, $notification) use ($events) {\n            $events->dispatch(new NotificationFailed($notifiable, $notification, 'test'));\n            throw new Exception();\n        });\n        $listeners = new Collection();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $events->shouldReceive('listen')->once()->andReturnUsing(function ($event, $callback) use ($listeners) {\n            $listeners->push($callback);\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(NotificationFailed::class))->andReturnUsing(function ($event) use ($listeners) {\n            foreach ($listeners as $listener) {\n                $listener($event);\n            }\n        });\n        $events->shouldReceive('dispatch')->never()->with(m::type(NotificationSent::class));\n\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n    }\n\n    public function testNotificationFailedDispatchedOnlyOnceWhenMultipleFailed()\n    {\n        $this->expectException(Exception::class);\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock(Dispatcher::class));\n        Container::setInstance($container);\n        $manager = $container->make(ChannelManager::class, ['container' => $container]);\n        $manager->extend('test', function () use ($events) {\n            return new class($events)\n            {\n                private $count = 0;\n\n                public function __construct(private $events)\n                {\n                }\n\n                public function send($notifiable, Notification $notification)\n                {\n                    if ($this->count > 1) {\n                        throw new \\Exception();\n                    }\n\n                    $this->count++;\n                }\n            };\n        });\n        $listeners = new Collection();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $events->shouldReceive('listen')->once()->andReturnUsing(function ($event, $callback) use ($listeners) {\n            $listeners->push($callback);\n        });\n        $events->shouldReceive('dispatch')->once()->with(m::type(NotificationFailed::class))->andReturnUsing(function ($event) use ($listeners) {\n            foreach ($listeners as $listener) {\n                $listener($event);\n            }\n        });\n        $events->shouldReceive('dispatch')->twice()->with(m::type(NotificationSent::class));\n\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n        $manager->send(new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerTestNotification);\n    }\n\n    public function testNotificationCanBeQueued()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(QueueRoutes::class, $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        $container->instance('queue.routes', $queueRoutes);\n        $bus->shouldReceive('dispatch')->with(m::type(SendQueuedNotifications::class));\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], new NotificationChannelManagerTestQueuedNotification);\n    }\n\n    public function testSendQueuedNotificationsCanBeOverrideViaContainer()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(QueueRoutes::class, $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        $container->instance('queue.routes', $queueRoutes);\n        $bus->shouldReceive('dispatch')->with(m::type(TestSendQueuedNotifications::class));\n        $container->bind(SendQueuedNotifications::class, TestSendQueuedNotifications::class);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], new NotificationChannelManagerTestQueuedNotification);\n    }\n\n    public function testQueuedNotificationForwardsMessageGroupFromMethodToQueueJob()\n    {\n        $mockedMessageGroupId = 'group-1';\n\n        $notification = $this->getMockBuilder(NotificationChannelManagerTestQueuedNotificationWithMessageGroupMethod::class)->onlyMethods(['messageGroup'])->getMock();\n        $notification->expects($this->exactly(2))->method('messageGroup')->willReturn($mockedMessageGroupId);\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(QueueRoutes::class, $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        $container->instance('queue.routes', $queueRoutes);\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) use ($mockedMessageGroupId) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertEquals($mockedMessageGroupId, $job->messageGroup);\n\n            return true;\n        });\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsMessageGroupFromPropertyOverridingMethodToQueueJob()\n    {\n        $mockedMessageGroupId = 'group-1';\n\n        // Ensure the messageGroup method is not called when a messageGroup property is provided.\n        $notification = $this->getMockBuilder(NotificationChannelManagerTestQueuedNotificationWithMessageGroupMethod::class)->onlyMethods(['messageGroup'])->getMock();\n        $notification->expects($this->never())->method('messageGroup')->willReturn('this-should-not-be-used');\n        $notification->onGroup($mockedMessageGroupId);\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(QueueRoutes::class, $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        $container->instance('queue.routes', $queueRoutes);\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) use ($mockedMessageGroupId) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertEquals($mockedMessageGroupId, $job->messageGroup);\n\n            return true;\n        });\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsMessageGroupSetToQueueJob()\n    {\n        $mockedMessageGroupSet = [\n            'test' => 'group-1',\n            'test2' => 'group-2',\n        ];\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(QueueRoutes::class, $queueRoutes = m::mock());\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        $container->instance('queue.routes', $queueRoutes);\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) use ($mockedMessageGroupSet) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertEquals($mockedMessageGroupSet[$job->channels[0]], $job->messageGroup);\n\n            return true;\n        });\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotificationWithTwoChannels)->onGroup($mockedMessageGroupSet);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsMessageGroupSetFromClassToQueueJob()\n    {\n        $mockedMessageGroupSet = [\n            'test' => 'group-1',\n            'test2' => 'group-2',\n        ];\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) use ($mockedMessageGroupSet) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertEquals($mockedMessageGroupSet[$job->channels[0]], $job->messageGroup);\n\n            return true;\n        });\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotificationWithMessageGroups);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsDeduplicatorToQueueJob()\n    {\n        $mockedDeduplicator = fn ($payload, $queue) => 'deduplication-id-1';\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $bus->shouldReceive('dispatch')->once()->withArgs(function ($job) use ($mockedDeduplicator) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n            $this->assertEquals($mockedDeduplicator, $job->deduplicator->getClosure());\n\n            return true;\n        });\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotification)->withDeduplicator($mockedDeduplicator);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsDeduplicatorSetToQueueJob()\n    {\n        $mockedDeduplicatorSet = [\n            'test' => fn ($payload, $queue) => 'deduplication-id-1',\n            'test2' => fn ($payload, $queue) => 'deduplication-id-2',\n        ];\n\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) use ($mockedDeduplicatorSet) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n            $this->assertEquals($mockedDeduplicatorSet[$job->channels[0]], $job->deduplicator->getClosure());\n\n            return true;\n        });\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotificationWithTwoChannels)->withDeduplicator($mockedDeduplicatorSet);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsDeduplicatorSetFromClassToQueueJob()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertEquals($job->notification->deduplicatorResults[$job->channels[0]], call_user_func($job->deduplicator, '', null));\n\n            return true;\n        });\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotificationWithDeduplicators);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testQueuedNotificationForwardsDeduplicationIdMethodToQueueJob()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Dispatcher::class, $events = m::mock());\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance('queue.routes', $queueRoutes = m::mock());\n        $bus->shouldReceive('dispatch')->twice()->withArgs(function ($job) {\n            $this->assertInstanceOf(SendQueuedNotifications::class, $job);\n            $this->assertInstanceOf(SerializableClosure::class, $job->deduplicator);\n            $this->assertEquals($job->notification->deduplicationId(...), $job->deduplicator->getClosure());\n\n            return true;\n        });\n        $queueRoutes->shouldReceive('getQueue')->andReturn(null);\n        $queueRoutes->shouldReceive('getConnection')->andReturn(null);\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $events->shouldReceive('listen')->once();\n\n        $notification = (new NotificationChannelManagerTestQueuedNotificationWithDeduplicationId);\n        $manager->send([new NotificationChannelManagerTestNotifiable], $notification);\n    }\n\n    public function testAfterSendingMethodAfterSendingNotification()\n    {\n        $container = new Container;\n        $container->instance('config', ['app.name' => 'Name', 'app.logo' => 'Logo']);\n        $container->instance(Bus::class, $bus = m::mock());\n        $container->instance(Dispatcher::class, $events = m::mock());\n        Container::setInstance($container);\n        $manager = m::mock(ChannelManager::class.'[driver]', [$container]);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $driver->shouldReceive('send')->once()->andReturn($response = m::mock());\n        $events->shouldReceive('dispatch')->with(m::type(NotificationSent::class));\n\n        $manager->send($notifiable = new NotificationChannelManagerTestNotifiable, new NotificationChannelManagerWithAfterSendingMethodNotification);\n\n        $this->assertSame($notifiable, NotificationChannelManagerWithAfterSendingMethodNotification::$afterSendingNotifiable);\n        $this->assertSame('test', NotificationChannelManagerWithAfterSendingMethodNotification::$afterSendingChannel);\n        $this->assertSame($response, NotificationChannelManagerWithAfterSendingMethodNotification::$afterSendingResponse);\n    }\n}\n\nclass TestSendQueuedNotifications implements ShouldQueue\n{\n    use InteractsWithQueue, Queueable, SerializesModels;\n}\n\nclass NotificationChannelManagerTestNotifiable\n{\n    use Notifiable;\n}\n\nclass NotificationChannelManagerTestNotification extends Notification\n{\n    public function via()\n    {\n        return ['test'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n}\n\nclass NotificationChannelManagerTestNotificationWithTwoChannels extends Notification\n{\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n}\n\nclass NotificationChannelManagerTestCancelledNotification extends Notification\n{\n    public function via()\n    {\n        return ['test'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function shouldSend($notifiable, $channel)\n    {\n        return false;\n    }\n}\n\nclass NotificationChannelManagerTestNotCancelledNotification extends Notification\n{\n    public function via()\n    {\n        return ['test'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function shouldSend($notifiable, $channel)\n    {\n        return true;\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotification extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via()\n    {\n        return ['test'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotificationWithTwoChannels extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotificationWithMessageGroupMethod extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function messageGroup()\n    {\n        return 'group-1';\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotificationWithMessageGroups extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function withMessageGroups($notifiable, $channel)\n    {\n        return match ($channel) {\n            'test' => 'group-1',\n            'test2' => 'group-2',\n            default => null,\n        };\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotificationWithDeduplicators extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public $deduplicatorResults = [\n        'test' => 'deduplication-id-1',\n        'test2' => 'deduplication-id-2',\n    ];\n\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function withDeduplicators($notifiable, $channel)\n    {\n        return match ($channel) {\n            'test' => fn ($payload, $queue) => $this->deduplicatorResults['test'],\n            'test2' => fn ($payload, $queue) => $this->deduplicatorResults['test2'],\n            default => null,\n        };\n    }\n}\n\nclass NotificationChannelManagerTestQueuedNotificationWithDeduplicationId extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via()\n    {\n        return ['test', 'test2'];\n    }\n\n    public function message()\n    {\n        return $this->line('test')->action('Text', 'url');\n    }\n\n    public function deduplicationId($payload, $queue)\n    {\n        return 'deduplication-id-1';\n    }\n}\n\nclass NotificationChannelManagerWithAfterSendingMethodNotification extends Notification\n{\n    public static $afterSendingNotifiable;\n    public static $afterSendingChannel;\n    public static $afterSendingResponse;\n\n    public function via()\n    {\n        return ['test'];\n    }\n\n    public function afterSending($notifiable, $channel, $response)\n    {\n        static::$afterSendingNotifiable = $notifiable;\n        static::$afterSendingChannel = $channel;\n        static::$afterSendingResponse = $response;\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationDatabaseChannelTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Notifications\\Channels\\DatabaseChannel;\nuse Illuminate\\Notifications\\Messages\\DatabaseMessage;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationDatabaseChannelTest extends TestCase\n{\n    public function testDatabaseChannelCreatesDatabaseRecordWithProperData()\n    {\n        $notification = new NotificationDatabaseChannelTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $notifiable->shouldReceive('routeNotificationFor->create')->with([\n            'id' => 1,\n            'type' => get_class($notification),\n            'data' => ['invoice_id' => 1],\n            'read_at' => null,\n        ]);\n\n        $channel = new DatabaseChannel;\n        $channel->send($notifiable, $notification);\n    }\n\n    public function testCorrectPayloadIsSentToDatabase()\n    {\n        $notification = new NotificationDatabaseChannelTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $notifiable->shouldReceive('routeNotificationFor->create')->with([\n            'id' => 1,\n            'type' => get_class($notification),\n            'data' => ['invoice_id' => 1],\n            'read_at' => null,\n            'something' => 'else',\n        ]);\n\n        $channel = new ExtendedDatabaseChannel;\n        $channel->send($notifiable, $notification);\n    }\n\n    public function testCustomizeTypeIsSentToDatabase()\n    {\n        $notification = new NotificationDatabaseChannelCustomizeTypeTestNotification;\n        $notification->id = 1;\n        $notifiable = m::mock();\n\n        $notifiable->shouldReceive('routeNotificationFor->create')->with([\n            'id' => 1,\n            'type' => 'MONTHLY',\n            'data' => ['invoice_id' => 1],\n            'read_at' => Carbon::now()->toDateTimeString(),\n            'something' => 'else',\n        ]);\n\n        $channel = new ExtendedDatabaseChannel;\n        $channel->send($notifiable, $notification);\n    }\n}\n\nclass NotificationDatabaseChannelTestNotification extends Notification\n{\n    public function toDatabase($notifiable)\n    {\n        return new DatabaseMessage(['invoice_id' => 1]);\n    }\n}\n\nclass NotificationDatabaseChannelCustomizeTypeTestNotification extends Notification\n{\n    public function toDatabase($notifiable)\n    {\n        return new DatabaseMessage(['invoice_id' => 1]);\n    }\n\n    public function databaseType()\n    {\n        return 'MONTHLY';\n    }\n\n    public function initialDatabaseReadAtValue()\n    {\n        return Carbon::now();\n    }\n}\n\nclass ExtendedDatabaseChannel extends DatabaseChannel\n{\n    protected function buildPayload($notifiable, Notification $notification)\n    {\n        return array_merge(parent::buildPayload($notifiable, $notification), [\n            'something' => 'else',\n        ]);\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationMailMessageTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Contracts\\Mail\\Attachable;\nuse Illuminate\\Mail\\Attachment;\nuse Illuminate\\Notifications\\Messages\\MailMessage;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationMailMessageTest extends TestCase\n{\n    public function testTemplate()\n    {\n        $message = new MailMessage;\n\n        $this->assertSame('notifications::email', $message->markdown);\n\n        $message->template('notifications::foo');\n\n        $this->assertSame('notifications::foo', $message->markdown);\n    }\n\n    public function testHtmlAndPlainView()\n    {\n        $message = new MailMessage;\n\n        $this->assertNull($message->view);\n        $this->assertSame([], $message->viewData);\n\n        $message->view(['notifications::foo', 'notifications::bar'], [\n            'foo' => 'bar',\n        ]);\n\n        $this->assertSame('notifications::foo', $message->view[0]);\n        $this->assertSame('notifications::bar', $message->view[1]);\n        $this->assertSame(['foo' => 'bar'], $message->viewData);\n    }\n\n    public function testHtmlView()\n    {\n        $message = new MailMessage;\n\n        $this->assertNull($message->view);\n        $this->assertSame([], $message->viewData);\n\n        $message->view('notifications::foo', [\n            'foo' => 'bar',\n        ]);\n\n        $this->assertSame('notifications::foo', $message->view);\n        $this->assertSame(['foo' => 'bar'], $message->viewData);\n    }\n\n    public function testPlainView()\n    {\n        $message = new MailMessage;\n\n        $this->assertNull($message->view);\n        $this->assertSame([], $message->viewData);\n\n        $message->view([null, 'notifications::foo'], [\n            'foo' => 'bar',\n        ]);\n\n        $this->assertSame('notifications::foo', $message->view[1]);\n        $this->assertSame(['foo' => 'bar'], $message->viewData);\n    }\n\n    public function testCcIsSetCorrectly()\n    {\n        $message = new MailMessage;\n        $message->cc('test@example.com');\n\n        $this->assertSame([['test@example.com', null]], $message->cc);\n\n        $message = new MailMessage;\n        $message->cc('test@example.com')\n            ->cc('test@example.com', 'Test');\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->cc);\n\n        $message = new MailMessage;\n        $message->cc(['test@example.com', 'Test' => 'test@example.com']);\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->cc);\n\n        $message = new MailMessage;\n        $message->cc('test@example.com', 'Test')\n            ->cc(['test@example.com', 'test2@example.com']);\n\n        $this->assertSame([\n            ['test@example.com', 'Test'],\n            ['test@example.com', null],\n            ['test2@example.com', null],\n        ], $message->cc);\n    }\n\n    public function testBccIsSetCorrectly()\n    {\n        $message = new MailMessage;\n        $message->bcc('test@example.com');\n\n        $this->assertSame([['test@example.com', null]], $message->bcc);\n\n        $message = new MailMessage;\n        $message->bcc('test@example.com')\n            ->bcc('test@example.com', 'Test');\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->bcc);\n\n        $message = new MailMessage;\n        $message->bcc(['test@example.com', 'Test' => 'test@example.com']);\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->bcc);\n\n        $message = new MailMessage;\n        $message->bcc('test@example.com', 'Test')\n            ->bcc(['test@example.com', 'test2@example.com']);\n\n        $this->assertSame([\n            ['test@example.com', 'Test'],\n            ['test@example.com', null],\n            ['test2@example.com', null],\n        ], $message->bcc);\n    }\n\n    public function testReplyToIsSetCorrectly()\n    {\n        $message = new MailMessage;\n        $message->replyTo('test@example.com');\n\n        $this->assertSame([['test@example.com', null]], $message->replyTo);\n\n        $message = new MailMessage;\n        $message->replyTo('test@example.com')\n            ->replyTo('test@example.com', 'Test');\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->replyTo);\n\n        $message = new MailMessage;\n        $message->replyTo(['test@example.com', 'Test' => 'test@example.com']);\n\n        $this->assertSame([['test@example.com', null], ['test@example.com', 'Test']], $message->replyTo);\n\n        $message = new MailMessage;\n        $message->replyTo('test@example.com', 'Test')\n            ->replyTo(['test@example.com', 'test2@example.com']);\n\n        $this->assertSame([\n            ['test@example.com', 'Test'],\n            ['test@example.com', null],\n            ['test2@example.com', null],\n        ], $message->replyTo);\n    }\n\n    public function testMetadataIsSetCorrectly()\n    {\n        $message = new MailMessage;\n        $message->metadata('origin', 'test-suite');\n        $message->metadata('user_id', 1);\n\n        $this->assertArrayHasKey('origin', $message->metadata);\n        $this->assertSame('test-suite', $message->metadata['origin']);\n        $this->assertArrayHasKey('user_id', $message->metadata);\n        $this->assertSame(1, $message->metadata['user_id']);\n    }\n\n    public function testTagIsSetCorrectly()\n    {\n        $message = new MailMessage;\n        $message->tag('test');\n\n        $this->assertContains('test', $message->tags);\n    }\n\n    public function testCallbackIsSetCorrectly()\n    {\n        $callback = function () {\n            //\n        };\n\n        $message = new MailMessage;\n        $message->withSymfonyMessage($callback);\n\n        $this->assertSame([$callback], $message->callbacks);\n    }\n\n    public function testWhenCallback()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertTrue($condition);\n\n            $mailMessage->cc('cc@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->when(true, $callback);\n        $this->assertSame([['cc@example.com', null]], $message->cc);\n\n        $message = new MailMessage;\n        $message->when(false, $callback);\n        $this->assertSame([], $message->cc);\n    }\n\n    public function testWhenCallbackWithReturn()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertTrue($condition);\n\n            return $mailMessage->cc('cc@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->when(true, $callback)->bcc('bcc@example.com');\n        $this->assertSame([['cc@example.com', null]], $message->cc);\n        $this->assertSame([['bcc@example.com', null]], $message->bcc);\n\n        $message = new MailMessage;\n        $message->when(false, $callback)->bcc('bcc@example.com');\n        $this->assertSame([], $message->cc);\n        $this->assertSame([['bcc@example.com', null]], $message->bcc);\n    }\n\n    public function testWhenCallbackWithDefault()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertSame('truthy', $condition);\n\n            $mailMessage->cc('truthy@example.com');\n        };\n\n        $default = function (MailMessage $mailMessage, $condition) {\n            $this->assertEquals(0, $condition);\n\n            $mailMessage->cc('zero@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->when('truthy', $callback, $default);\n        $this->assertSame([['truthy@example.com', null]], $message->cc);\n\n        $message = new MailMessage;\n        $message->when(0, $callback, $default);\n        $this->assertSame([['zero@example.com', null]], $message->cc);\n    }\n\n    public function testUnlessCallback()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertFalse($condition);\n\n            $mailMessage->cc('test@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->unless(false, $callback);\n        $this->assertSame([['test@example.com', null]], $message->cc);\n\n        $message = new MailMessage;\n        $message->unless(true, $callback);\n        $this->assertSame([], $message->cc);\n    }\n\n    public function testUnlessCallbackWithReturn()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertFalse($condition);\n\n            return $mailMessage->cc('cc@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->unless(false, $callback)->bcc('bcc@example.com');\n        $this->assertSame([['cc@example.com', null]], $message->cc);\n        $this->assertSame([['bcc@example.com', null]], $message->bcc);\n\n        $message = new MailMessage;\n        $message->unless(true, $callback)->bcc('bcc@example.com');\n        $this->assertSame([], $message->cc);\n        $this->assertSame([['bcc@example.com', null]], $message->bcc);\n    }\n\n    public function testUnlessCallbackWithDefault()\n    {\n        $callback = function (MailMessage $mailMessage, $condition) {\n            $this->assertEquals(0, $condition);\n\n            $mailMessage->cc('zero@example.com');\n        };\n\n        $default = function (MailMessage $mailMessage, $condition) {\n            $this->assertSame('truthy', $condition);\n\n            $mailMessage->cc('truthy@example.com');\n        };\n\n        $message = new MailMessage;\n        $message->unless(0, $callback, $default);\n        $this->assertSame([['zero@example.com', null]], $message->cc);\n\n        $message = new MailMessage;\n        $message->unless('truthy', $callback, $default);\n        $this->assertSame([['truthy@example.com', null]], $message->cc);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromPath()\n    {\n        $message = new MailMessage;\n\n        $message->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromPath('/foo.jpg')->as('bar')->withMime('image/png');\n            }\n        });\n\n        $this->assertSame([\n            'file' => '/foo.jpg',\n            'options' => [\n                'as' => 'bar',\n                'mime' => 'image/png',\n            ],\n        ], $message->attachments[0]);\n    }\n\n    public function testItAttachesFilesViaAttachableContractFromData()\n    {\n        $mailMessage = new MailMessage();\n\n        $mailMessage->attach(new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar', 'foo.jpg')->withMime('image/png');\n            }\n        });\n\n        $this->assertSame([\n            'data' => 'bar',\n            'name' => 'foo.jpg',\n            'options' => [\n                'mime' => 'image/png',\n            ],\n        ], $mailMessage->rawAttachments[0]);\n    }\n\n    public function testItAttachesManyFiles()\n    {\n        $mailMessage = new MailMessage();\n        $attachable = new class() implements Attachable\n        {\n            public function toMailAttachment()\n            {\n                return Attachment::fromData(fn () => 'bar', 'foo.jpg')->withMime('image/png');\n            }\n        };\n\n        $mailMessage->attachMany([\n            $attachable,\n            '/path/to/forge.svg',\n            '/path/to/vapor.svg' => [\n                'as' => 'Logo.svg',\n                'mime' => 'image/svg+xml',\n            ],\n        ]);\n\n        $this->assertSame([\n            [\n                'data' => 'bar',\n                'name' => 'foo.jpg',\n                'options' => [\n                    'mime' => 'image/png',\n                ],\n            ],\n        ], $mailMessage->rawAttachments);\n\n        $this->assertSame([\n            [\n                'file' => '/path/to/forge.svg',\n                'options' => [],\n            ],\n            [\n                'file' => '/path/to/vapor.svg',\n                'options' => [\n                    'as' => 'Logo.svg',\n                    'mime' => 'image/svg+xml',\n                ],\n            ],\n        ], $mailMessage->attachments);\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationMessageTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Notifications\\Messages\\SimpleMessage as Message;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationMessageTest extends TestCase\n{\n    public function testLevelCanBeRetrieved()\n    {\n        $message = new Message;\n        $this->assertSame('info', $message->level);\n\n        $message = new Message;\n        $message->level('error');\n        $this->assertSame('error', $message->level);\n    }\n\n    public function testMessageFormatsMultiLineText()\n    {\n        $message = new Message;\n        $message->with('\n            This is a\n            single line of text.\n        ');\n\n        $this->assertSame('This is a single line of text.', $message->introLines[0]);\n\n        $message = new Message;\n        $message->with([\n            'This is a',\n            'single line of text.',\n        ]);\n\n        $this->assertSame('This is a single line of text.', $message->introLines[0]);\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationRoutesNotificationsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Notifications\\Dispatcher;\nuse Illuminate\\Notifications\\RoutesNotifications;\nuse Illuminate\\Support\\Facades\\Notification;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass NotificationRoutesNotificationsTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testNotificationCanBeDispatched()\n    {\n        $container = new Container;\n        $factory = m::mock(Dispatcher::class);\n        $container->instance(Dispatcher::class, $factory);\n        $notifiable = new RoutesNotificationsTestInstance;\n        $instance = new stdClass;\n        $factory->shouldReceive('send')->with($notifiable, $instance);\n        Container::setInstance($container);\n\n        $notifiable->notify($instance);\n    }\n\n    public function testNotificationCanBeSentNow()\n    {\n        $container = new Container;\n        $factory = m::mock(Dispatcher::class);\n        $container->instance(Dispatcher::class, $factory);\n        $notifiable = new RoutesNotificationsTestInstance;\n        $instance = new stdClass;\n        $factory->shouldReceive('sendNow')->with($notifiable, $instance, null);\n        Container::setInstance($container);\n\n        $notifiable->notifyNow($instance);\n    }\n\n    public function testNotificationOptionRouting()\n    {\n        $instance = new RoutesNotificationsTestInstance;\n        $this->assertSame('bar', $instance->routeNotificationFor('foo'));\n        $this->assertSame('taylor@laravel.com', $instance->routeNotificationFor('mail'));\n    }\n\n    public function testOnDemandNotificationsCannotUseDatabaseChannel()\n    {\n        $this->expectExceptionObject(\n            new InvalidArgumentException('The database channel does not support on-demand notifications.')\n        );\n\n        Notification::route('database', 'foo');\n    }\n}\n\nclass RoutesNotificationsTestInstance\n{\n    use RoutesNotifications;\n\n    protected $email = 'taylor@laravel.com';\n\n    public function routeNotificationForFoo()\n    {\n        return 'bar';\n    }\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationSendQueuedNotificationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Contracts\\Database\\ModelIdentifier;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Notifications\\ChannelManager;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Notifications\\SendQueuedNotifications;\nuse Illuminate\\Support\\Collection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass NotificationSendQueuedNotificationTest extends TestCase\n{\n    public function testNotificationsCanBeSent()\n    {\n        $notification = new TestNotification;\n        $job = new SendQueuedNotifications('notifiables', $notification);\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('sendNow')->once()->withArgs(function ($notifiables, $notification, $channels) {\n            return $notifiables instanceof Collection && $notifiables->toArray() === ['notifiables']\n                && $notification instanceof TestNotification\n                && $channels === null;\n        });\n        $job->handle($manager);\n    }\n\n    public function testSerializationOfNotifiableModel()\n    {\n        $identifier = new ModelIdentifier(NotifiableUser::class, [null], [], null);\n        $serializedIdentifier = serialize($identifier);\n\n        $job = new SendQueuedNotifications(new NotifiableUser, new TestNotification);\n        $serialized = serialize($job);\n\n        $this->assertStringContainsString($serializedIdentifier, $serialized);\n    }\n\n    public function testSerializationOfNormalNotifiable()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $serializedNotifiable = serialize($notifiable);\n\n        $job = new SendQueuedNotifications($notifiable, new TestNotification);\n        $serialized = serialize($job);\n\n        $this->assertStringContainsString($serializedNotifiable, $serialized);\n    }\n\n    public function testNotificationCanSetMaxExceptions()\n    {\n        $notifiable = new NotifiableUser;\n        $notification = new class\n        {\n            public $maxExceptions = 23;\n        };\n\n        $job = new SendQueuedNotifications($notifiable, $notification);\n\n        $this->assertEquals(23, $job->maxExceptions);\n    }\n}\n\nclass NotifiableUser extends Model\n{\n    use Notifiable;\n\n    public $table = 'users';\n    public $timestamps = false;\n}\n\nclass TestNotification extends Notification\n{\n}\n"
  },
  {
    "path": "tests/Notifications/NotificationSenderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Notifications;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as BusDispatcher;\nuse Illuminate\\Contracts\\Events\\Dispatcher as EventDispatcher;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Notifications\\AnonymousNotifiable;\nuse Illuminate\\Notifications\\ChannelManager;\nuse Illuminate\\Notifications\\Events\\NotificationFailed;\nuse Illuminate\\Notifications\\Events\\NotificationSending;\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Notifications\\Notification;\nuse Illuminate\\Notifications\\NotificationSender;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Mailer\\Exception\\HttpTransportException;\nuse Symfony\\Component\\Mailer\\Exception\\TransportException;\nuse Symfony\\Contracts\\HttpClient\\ResponseInterface;\n\nclass NotificationSenderTest extends TestCase\n{\n    public function testItCanSendQueuedNotificationsWithAStringVia()\n    {\n        $notifiable = m::mock(Notifiable::class);\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $manager->shouldReceive('resolveQueueFromQueueRoute')->andReturn(null);\n        $manager->shouldReceive('resolveConnectionFromQueueRoute')->andReturn(null);\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch');\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyQueuedNotificationWithStringVia);\n    }\n\n    public function testItCanSendQueuedNotificationsWithAnArrayVia()\n    {\n        $notifiable = m::mock(Notifiable::class);\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->queue === 'dummy' && $job->channels === ['database'] && $job->connection === 'redis';\n            });\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->queue === 'dummy' && $job->channels === ['mail'] && $job->connection === 'redis';\n            });\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyQueuedNotificationWithArrayVia);\n    }\n\n    public function testItCanSendNotificationsWithAnEmptyStringVia()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldNotReceive('dispatch');\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->sendNow($notifiable, new DummyNotificationWithEmptyStringVia);\n    }\n\n    public function testItCannotSendNotificationsViaDatabaseForAnonymousNotifiables()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldNotReceive('dispatch');\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->sendNow($notifiable, new DummyNotificationWithDatabaseVia);\n    }\n\n    public function testItCanSendQueuedNotificationsThroughMiddleware()\n    {\n        $notifiable = m::mock(Notifiable::class);\n        $manager = m::mock(ChannelManager::class);\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->withArgs(function ($job) {\n                return $job->middleware[0] instanceof TestNotificationMiddleware;\n            });\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $manager->shouldReceive('resolveQueueFromQueueRoute')->andReturn(null);\n        $manager->shouldReceive('resolveConnectionFromQueueRoute')->andReturn(null);\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyNotificationWithMiddleware);\n    }\n\n    public function testItCanSendQueuedMultiChannelNotificationsThroughDifferentMiddleware()\n    {\n        $notifiable = m::mock(Notifiable::class);\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $manager->shouldReceive('resolveQueueFromQueueRoute')->andReturn(null);\n        $manager->shouldReceive('resolveConnectionFromQueueRoute')->andReturn(null);\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->middleware[0] instanceof TestMailNotificationMiddleware;\n            });\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->middleware[0] instanceof TestDatabaseNotificationMiddleware;\n            });\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return empty($job->middleware);\n            });\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyMultiChannelNotificationWithConditionalMiddleware);\n    }\n\n    public function testItCanSendQueuedWithViaConnectionsNotifications()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->connection === 'sync' && $job->channels === ['database'] && $job->queue === 'dummy';\n            });\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->connection === 'redis' && $job->channels === ['mail'] && $job->queue === 'dummy';\n            });\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyNotificationWithViaConnections);\n    }\n\n    public function testItCanSendQueuedWithViaQueuesNotifications()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->queue === 'dummy' && $job->channels === ['database'] && $job->connection === 'redis';\n            });\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->queue === 'admin_notifications' && $job->channels === ['mail'] && $job->connection === 'redis';\n            });\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyNotificationWithViaQueues);\n    }\n\n    public function testItCanSendQueuedNotificationsWithQueueRoute()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('getContainer')->andReturn(app());\n        $manager->shouldReceive('resolveQueueFromQueueRoute')->andReturn('notification-queue');\n        $manager->shouldReceive('resolveConnectionFromQueueRoute')->andReturn('notification-connection');\n\n        $bus = m::mock(BusDispatcher::class);\n        $bus->shouldReceive('dispatch')\n            ->once()\n            ->withArgs(function ($job) {\n                return $job->queue === 'notification-queue' && $job->channels === ['mail'] && $job->connection === 'notification-connection';\n            });\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->send($notifiable, new DummyQueuedNotificationWithStringVia);\n    }\n\n    public function testNotificationFailedSentWithoutHttpTransportException()\n    {\n        $this->expectException(TransportException::class);\n\n        $notifiable = new AnonymousNotifiable();\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $response = m::mock(ResponseInterface::class);\n        $driver->shouldReceive('send')->andThrow(new HttpTransportException('Transport error', $response));\n        $bus = m::mock(BusDispatcher::class);\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $events->shouldReceive('dispatch')->once()->withArgs(function ($event) {\n            return $event instanceof NotificationFailed && $event->data['exception'] instanceof TransportException;\n        });\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->sendNow($notifiable, new DummyNotificationWithViaConnections(), ['mail']);\n    }\n\n    public function testItPreservesNotificationStateMutatedInViaMethod()\n    {\n        $notifiable = new AnonymousNotifiable;\n        $manager = m::mock(ChannelManager::class);\n        $manager->shouldReceive('driver')->andReturn($driver = m::mock());\n        $driver->shouldReceive('send')->once()->withArgs(function ($notifiable, $notification) {\n            return $notification->channelData === 'default';\n        });\n        $bus = m::mock(BusDispatcher::class);\n\n        $events = m::mock(EventDispatcher::class);\n        $events->shouldReceive('listen')->once();\n        $events->shouldReceive('until')->with(m::type(NotificationSending::class))->andReturn(true);\n        $events->shouldReceive('dispatch')->once();\n\n        $sender = new NotificationSender($manager, $bus, $events);\n\n        $sender->sendNow($notifiable, new DummyNotificationWithViaMutation);\n    }\n}\n\nclass DummyQueuedNotificationWithStringVia extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    /**\n     * Get the notification channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return 'mail';\n    }\n}\n\nclass DummyQueuedNotificationWithArrayVia extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function __construct()\n    {\n        $this->connection = 'redis';\n        $this->queue = 'dummy';\n    }\n\n    /**\n     * Get the notification channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return ['mail', 'database'];\n    }\n}\n\nclass DummyNotificationWithEmptyStringVia extends Notification\n{\n    use Queueable;\n\n    /**\n     * Get the notification channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return '';\n    }\n}\n\nclass DummyNotificationWithDatabaseVia extends Notification\n{\n    use Queueable;\n\n    /**\n     * Get the notification channels.\n     *\n     * @param  mixed  $notifiable\n     * @return array|string\n     */\n    public function via($notifiable)\n    {\n        return 'database';\n    }\n}\n\nclass DummyNotificationWithViaConnections extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function __construct()\n    {\n        $this->connection = 'redis';\n        $this->queue = 'dummy';\n    }\n\n    public function via($notifiable)\n    {\n        return ['mail', 'database'];\n    }\n\n    public function viaConnections()\n    {\n        return [\n            'database' => 'sync',\n        ];\n    }\n}\n\nclass DummyNotificationWithViaQueues extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function __construct()\n    {\n        $this->connection = 'redis';\n        $this->queue = 'dummy';\n    }\n\n    public function via($notifiable)\n    {\n        return ['mail', 'database'];\n    }\n\n    public function viaQueues()\n    {\n        return [\n            'mail' => 'admin_notifications',\n        ];\n    }\n}\n\nclass DummyNotificationWithMiddleware extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via($notifiable)\n    {\n        return 'mail';\n    }\n\n    public function middleware()\n    {\n        return [\n            new TestNotificationMiddleware,\n        ];\n    }\n}\n\nclass DummyMultiChannelNotificationWithConditionalMiddleware extends Notification implements ShouldQueue\n{\n    use Queueable;\n\n    public function via($notifiable)\n    {\n        return [\n            'mail',\n            'database',\n            'broadcast',\n        ];\n    }\n\n    public function middleware($notifiable, $channel)\n    {\n        return match ($channel) {\n            'mail' => [new TestMailNotificationMiddleware],\n            'database' => [new TestDatabaseNotificationMiddleware],\n            default => []\n        };\n    }\n}\n\nclass TestNotificationMiddleware\n{\n    public function handle($command, $next)\n    {\n        return $next($command);\n    }\n}\n\nclass TestMailNotificationMiddleware\n{\n    public function handle($command, $next)\n    {\n        return $next($command);\n    }\n}\n\nclass TestDatabaseNotificationMiddleware\n{\n    public function handle($command, $next)\n    {\n        return $next($command);\n    }\n}\n\nclass DummyNotificationWithViaMutation extends Notification\n{\n    public $channelData = null;\n\n    public function via($notifiable)\n    {\n        $this->channelData = $notifiable->routeConfig ?? 'default';\n\n        return 'mail';\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/CursorPaginatorLoadMorphCountTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\AbstractCursorPaginator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CursorPaginatorLoadMorphCountTest extends TestCase\n{\n    public function testCollectionLoadMorphCountCanChainOnThePaginator()\n    {\n        $relations = [\n            'App\\\\User' => 'photos',\n            'App\\\\Company' => ['employees', 'calendars'],\n        ];\n\n        $items = m::mock(Collection::class);\n        $items->shouldReceive('loadMorphCount')->once()->with('parentable', $relations);\n\n        $p = (new class extends AbstractCursorPaginator {\n        })->setCollection($items);\n\n        $this->assertSame($p, $p->loadMorphCount('parentable', $relations));\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/CursorPaginatorLoadMorphTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\AbstractCursorPaginator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CursorPaginatorLoadMorphTest extends TestCase\n{\n    public function testCollectionLoadMorphCanChainOnThePaginator()\n    {\n        $relations = [\n            'App\\\\User' => 'photos',\n            'App\\\\Company' => ['employees', 'calendars'],\n        ];\n\n        $items = m::mock(Collection::class);\n        $items->shouldReceive('loadMorph')->once()->with('parentable', $relations);\n\n        $p = (new class extends AbstractCursorPaginator {\n        })->setCollection($items);\n\n        $this->assertSame($p, $p->loadMorph('parentable', $relations));\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/CursorPaginatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Support\\Collection;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CursorPaginatorTest extends TestCase\n{\n    public function testReturnsRelevantContextInformation()\n    {\n        $p = new CursorPaginator($array = [['id' => 1], ['id' => 2], ['id' => 3]], 2, null, [\n            'parameters' => ['id'],\n        ]);\n\n        $this->assertTrue($p->hasPages());\n        $this->assertTrue($p->hasMorePages());\n        $this->assertEquals([['id' => 1], ['id' => 2]], $p->items());\n\n        $pageInfo = [\n            'data' => [['id' => 1], ['id' => 2]],\n            'path' => '/',\n            'per_page' => 2,\n            'next_cursor' => $this->getCursor(['id' => 2]),\n            'next_page_url' => '/?cursor='.$this->getCursor(['id' => 2]),\n            'prev_cursor' => null,\n            'prev_page_url' => null,\n        ];\n\n        $this->assertEquals($pageInfo, $p->toArray());\n    }\n\n    public function testPaginatorRemovesTrailingSlashes()\n    {\n        $p = new CursorPaginator($array = [['id' => 4], ['id' => 5], ['id' => 6]], 2, null,\n            ['path' => 'http://website.com/test/', 'parameters' => ['id']]);\n\n        $this->assertSame('http://website.com/test?cursor='.$this->getCursor(['id' => 5]), $p->nextPageUrl());\n    }\n\n    public function testPaginatorGeneratesUrlsWithoutTrailingSlash()\n    {\n        $p = new CursorPaginator($array = [['id' => 4], ['id' => 5], ['id' => 6]], 2, null,\n            ['path' => 'http://website.com/test', 'parameters' => ['id']]);\n\n        $this->assertSame('http://website.com/test?cursor='.$this->getCursor(['id' => 5]), $p->nextPageUrl());\n    }\n\n    public function testItRetrievesThePaginatorOptions()\n    {\n        $p = new CursorPaginator($array = [['id' => 4], ['id' => 5], ['id' => 6]], 2, null,\n            $options = ['path' => 'http://website.com/test', 'parameters' => ['id']]);\n\n        $this->assertSame($p->getOptions(), $options);\n    }\n\n    public function testPaginatorReturnsPath()\n    {\n        $p = new CursorPaginator($array = [['id' => 4], ['id' => 5], ['id' => 6]], 2, null,\n            $options = ['path' => 'http://website.com/test', 'parameters' => ['id']]);\n\n        $this->assertSame($p->path(), 'http://website.com/test');\n    }\n\n    public function testCanTransformPaginatorItems()\n    {\n        $p = new CursorPaginator($array = [['id' => 4], ['id' => 5], ['id' => 6]], 2, null,\n            $options = ['path' => 'http://website.com/test', 'parameters' => ['id']]);\n\n        $p->through(function ($item) {\n            $item['id'] = $item['id'] + 2;\n\n            return $item;\n        });\n\n        $this->assertInstanceOf(CursorPaginator::class, $p);\n        $this->assertSame([['id' => 6], ['id' => 7]], $p->items());\n    }\n\n    public function testCursorPaginatorOnFirstAndLastPage()\n    {\n        $paginator = new CursorPaginator([['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4]], 2, null, [\n            'parameters' => ['id'],\n        ]);\n\n        $this->assertTrue($paginator->onFirstPage());\n        $this->assertFalse($paginator->onLastPage());\n\n        $cursor = new Cursor(['id' => 3]);\n        $paginator = new CursorPaginator([['id' => 3], ['id' => 4]], 2, $cursor, [\n            'parameters' => ['id'],\n        ]);\n\n        $this->assertFalse($paginator->onFirstPage());\n        $this->assertTrue($paginator->onLastPage());\n    }\n\n    public function testReturnEmptyCursorWhenItemsAreEmpty()\n    {\n        $cursor = new Cursor(['id' => 25], true);\n\n        $p = new CursorPaginator(new Collection, 25, $cursor, [\n            'path' => 'http://website.com/test',\n            'cursorName' => 'cursor',\n            'parameters' => ['id'],\n        ]);\n\n        $this->assertInstanceOf(CursorPaginator::class, $p);\n\n        $this->assertSame([\n            'data' => [],\n            'path' => 'http://website.com/test',\n            'per_page' => 25,\n            'next_cursor' => null,\n            'next_page_url' => null,\n            'prev_cursor' => null,\n            'prev_page_url' => null,\n        ], $p->toArray());\n    }\n\n    public function testCursorPaginatorToJson()\n    {\n        $paginator = new CursorPaginator([['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4]], 2, null);\n        $results = $paginator->toJson();\n        $expected = json_encode($paginator->toArray());\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n    }\n\n    public function testCursorPaginatorToPrettyJson()\n    {\n        $paginator = new CursorPaginator([['id' => '1'], ['id' => '2'], ['id' => '3'], ['id' => '4']], 2, null);\n        $results = $paginator->toPrettyJson();\n        $expected = $paginator->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n\n        $results = $paginator->toPrettyJson(JSON_NUMERIC_CHECK);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('\"id\": 1', $results);\n    }\n\n    protected function getCursor($params, $isNext = true)\n    {\n        return (new Cursor($params, $isNext))->encode();\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/CursorResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Pagination\\CursorPaginator;\nuse Illuminate\\Tests\\Pagination\\Fixtures\\Models\\CursorResourceTestModel;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CursorResourceTest extends TestCase\n{\n    public function testItCanTransformToExplicitResource()\n    {\n        $paginator = new CursorResourceTestPaginator([\n            new CursorResourceTestModel(),\n        ], 1);\n\n        $resource = $paginator->toResourceCollection(CursorResourceTestResource::class);\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n\n    public function testItThrowsExceptionWhenResourceCannotBeFound()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Failed to find resource class for model [Illuminate\\Tests\\Pagination\\Fixtures\\Models\\CursorResourceTestModel].');\n\n        $paginator = new CursorResourceTestPaginator([\n            new CursorResourceTestModel(),\n        ], 1);\n\n        $paginator->toResourceCollection();\n    }\n\n    public function testItCanGuessResourceWhenNotProvided()\n    {\n        $paginator = new CursorResourceTestPaginator([\n            new CursorResourceTestModel(),\n        ], 1);\n\n        class_alias(CursorResourceTestResource::class, 'Illuminate\\Tests\\Pagination\\Fixtures\\Http\\Resources\\CursorResourceTestModelResource');\n\n        $resource = $paginator->toResourceCollection();\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n}\n\nclass CursorResourceTestResource extends JsonResource\n{\n    //\n}\n\nclass CursorResourceTestPaginator extends CursorPaginator\n{\n    //\n}\n"
  },
  {
    "path": "tests/Pagination/CursorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Pagination\\Cursor;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CursorTest extends TestCase\n{\n    public function testCanEncodeAndDecodeSuccessfully()\n    {\n        $cursor = new Cursor([\n            'id' => 422,\n            'created_at' => Carbon::now()->toDateTimeString(),\n        ], true);\n\n        $this->assertEquals($cursor, Cursor::fromEncoded($cursor->encode()));\n    }\n\n    public function testCanGetParams()\n    {\n        $cursor = new Cursor([\n            'id' => 422,\n            'created_at' => ($now = Carbon::now()->toDateTimeString()),\n        ], true);\n\n        $this->assertEquals([$now, 422], $cursor->parameters(['created_at', 'id']));\n    }\n\n    public function testCanGetParam()\n    {\n        $cursor = new Cursor([\n            'id' => 422,\n            'created_at' => ($now = Carbon::now()->toDateTimeString()),\n        ], true);\n\n        $this->assertEquals($now, $cursor->parameter('created_at'));\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/Fixtures/Models/CursorResourceTestModel.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass CursorResourceTestModel extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Pagination/Fixtures/Models/PaginatorResourceTestModel.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination\\Fixtures\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass PaginatorResourceTestModel extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Pagination/LengthAwarePaginatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse PHPUnit\\Framework\\TestCase;\n\nclass LengthAwarePaginatorTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Pagination\\LengthAwarePaginator\n     */\n    private $p;\n\n    /**\n     * @var array\n     */\n    private $options;\n\n    protected function setUp(): void\n    {\n        $this->options = ['onEachSide' => 5];\n        $this->p = new LengthAwarePaginator($array = ['item1', 'item2', 'item3', 'item4'], 4, 2, 2, $this->options);\n    }\n\n    protected function tearDown(): void\n    {\n        unset($this->p);\n\n        parent::tearDown();\n    }\n\n    public function testLengthAwarePaginatorGetAndSetPageName()\n    {\n        $this->assertSame('page', $this->p->getPageName());\n\n        $this->p->setPageName('p');\n        $this->assertSame('p', $this->p->getPageName());\n    }\n\n    public function testLengthAwarePaginatorCanGiveMeRelevantPageInformation()\n    {\n        $this->assertEquals(2, $this->p->lastPage());\n        $this->assertEquals(2, $this->p->currentPage());\n        $this->assertTrue($this->p->hasPages());\n        $this->assertFalse($this->p->hasMorePages());\n        $this->assertEquals(['item1', 'item2', 'item3', 'item4'], $this->p->items());\n    }\n\n    public function testLengthAwarePaginatorSetCorrectInformationWithNoItems()\n    {\n        $paginator = new LengthAwarePaginator([], 0, 2, 1);\n\n        $this->assertEquals(1, $paginator->lastPage());\n        $this->assertEquals(1, $paginator->currentPage());\n        $this->assertFalse($paginator->hasPages());\n        $this->assertFalse($paginator->hasMorePages());\n        $this->assertEmpty($paginator->items());\n    }\n\n    public function testLengthAwarePaginatorOnFirstAndLastPage()\n    {\n        $paginator = new LengthAwarePaginator(['1', '2', '3', '4'], 4, 2, 2);\n\n        $this->assertTrue($paginator->onLastPage());\n        $this->assertFalse($paginator->onFirstPage());\n\n        $paginator = new LengthAwarePaginator(['1', '2', '3', '4'], 4, 2, 1);\n\n        $this->assertFalse($paginator->onLastPage());\n        $this->assertTrue($paginator->onFirstPage());\n    }\n\n    public function testLengthAwarePaginatorCanGenerateUrls()\n    {\n        $this->p->setPath('http://website.com');\n        $this->p->setPageName('foo');\n\n        $this->assertSame(\n            'http://website.com',\n            $this->p->path()\n        );\n\n        $this->assertSame(\n            'http://website.com?foo=2',\n            $this->p->url($this->p->currentPage())\n        );\n\n        $this->assertSame(\n            'http://website.com?foo=1',\n            $this->p->url($this->p->currentPage() - 1)\n        );\n\n        $this->assertSame(\n            'http://website.com?foo=1',\n            $this->p->url($this->p->currentPage() - 2)\n        );\n    }\n\n    public function testLengthAwarePaginatorCanGenerateUrlsWithQuery()\n    {\n        $this->p->setPath('http://website.com?sort_by=date');\n        $this->p->setPageName('foo');\n\n        $this->assertSame(\n            'http://website.com?sort_by=date&foo=2',\n            $this->p->url($this->p->currentPage())\n        );\n    }\n\n    public function testLengthAwarePaginatorCanGenerateUrlsWithoutTrailingSlashes()\n    {\n        $this->p->setPath('http://website.com/test');\n        $this->p->setPageName('foo');\n\n        $this->assertSame(\n            'http://website.com/test?foo=2',\n            $this->p->url($this->p->currentPage())\n        );\n\n        $this->assertSame(\n            'http://website.com/test?foo=1',\n            $this->p->url($this->p->currentPage() - 1)\n        );\n\n        $this->assertSame(\n            'http://website.com/test?foo=1',\n            $this->p->url($this->p->currentPage() - 2)\n        );\n    }\n\n    public function testLengthAwarePaginatorCorrectlyGenerateUrlsWithQueryAndSpaces()\n    {\n        $this->p->setPath('http://website.com?key=value%20with%20spaces');\n        $this->p->setPageName('foo');\n\n        $this->assertSame(\n            'http://website.com?key=value%20with%20spaces&foo=2',\n            $this->p->url($this->p->currentPage())\n        );\n    }\n\n    public function testItRetrievesThePaginatorOptions()\n    {\n        $this->assertSame($this->options, $this->p->getOptions());\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/PaginatorLoadMorphCountTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\AbstractPaginator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PaginatorLoadMorphCountTest extends TestCase\n{\n    public function testCollectionLoadMorphCountCanChainOnThePaginator()\n    {\n        $relations = [\n            'App\\\\User' => 'photos',\n            'App\\\\Company' => ['employees', 'calendars'],\n        ];\n\n        $items = m::mock(Collection::class);\n        $items->shouldReceive('loadMorphCount')->once()->with('parentable', $relations);\n\n        $p = (new class extends AbstractPaginator {\n        })->setCollection($items);\n\n        $this->assertSame($p, $p->loadMorphCount('parentable', $relations));\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/PaginatorLoadMorphTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Database\\Eloquent\\Collection;\nuse Illuminate\\Pagination\\AbstractPaginator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PaginatorLoadMorphTest extends TestCase\n{\n    public function testCollectionLoadMorphCanChainOnThePaginator()\n    {\n        $relations = [\n            'App\\\\User' => 'photos',\n            'App\\\\Company' => ['employees', 'calendars'],\n        ];\n\n        $items = m::mock(Collection::class);\n        $items->shouldReceive('loadMorph')->once()->with('parentable', $relations);\n\n        $p = (new class extends AbstractPaginator {\n        })->setCollection($items);\n\n        $this->assertSame($p, $p->loadMorph('parentable', $relations));\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/PaginatorResourceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Http\\Resources\\Json\\JsonResource;\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Tests\\Pagination\\Fixtures\\Models\\PaginatorResourceTestModel;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PaginatorResourceTest extends TestCase\n{\n    public function testItCanTransformToExplicitResource()\n    {\n        $paginator = new PaginatorResourceTestPaginator([\n            new PaginatorResourceTestModel(),\n        ], 1, 1, 1);\n\n        $resource = $paginator->toResourceCollection(PaginatorResourceTestResource::class);\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n\n    public function testItThrowsExceptionWhenResourceCannotBeFound()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Failed to find resource class for model [Illuminate\\Tests\\Pagination\\Fixtures\\Models\\PaginatorResourceTestModel].');\n\n        $paginator = new PaginatorResourceTestPaginator([\n            new PaginatorResourceTestModel(),\n        ], 1, 1, 1);\n\n        $paginator->toResourceCollection();\n    }\n\n    public function testItCanGuessResourceWhenNotProvided()\n    {\n        $paginator = new PaginatorResourceTestPaginator([\n            new PaginatorResourceTestModel(),\n        ], 1, 1, 1);\n\n        class_alias(PaginatorResourceTestResource::class, 'Illuminate\\Tests\\Pagination\\Fixtures\\Http\\Resources\\PaginatorResourceTestModelResource');\n\n        $resource = $paginator->toResourceCollection();\n\n        $this->assertInstanceOf(JsonResource::class, $resource);\n    }\n}\n\nclass PaginatorResourceTestResource extends JsonResource\n{\n    //\n}\n\nclass PaginatorResourceTestPaginator extends LengthAwarePaginator\n{\n    //\n}\n"
  },
  {
    "path": "tests/Pagination/PaginatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Pagination\\Paginator;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PaginatorTest extends TestCase\n{\n    public function testSimplePaginatorReturnsRelevantContextInformation()\n    {\n        /** @var Paginator<int, string> $p */\n        $p = new Paginator(['item3', 'item4', 'item5'], 2, 2);\n\n        $this->assertEquals(2, $p->currentPage());\n        $this->assertTrue($p->hasPages());\n        $this->assertTrue($p->hasMorePages());\n        $this->assertEquals(['item3', 'item4'], $p->items());\n\n        $pageInfo = [\n            'per_page' => 2,\n            'current_page' => 2,\n            'first_page_url' => '/?page=1',\n            'current_page_url' => '/?page=2',\n            'next_page_url' => '/?page=3',\n            'prev_page_url' => '/?page=1',\n            'from' => 3,\n            'to' => 4,\n            'data' => ['item3', 'item4'],\n            'path' => '/',\n        ];\n\n        $this->assertEquals($pageInfo, $p->toArray());\n    }\n\n    public function testPaginatorRemovesTrailingSlashes()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 2, 2, ['path' => 'http://website.com/test/']);\n\n        $this->assertSame('http://website.com/test?page=1', $p->previousPageUrl());\n    }\n\n    public function testPaginatorGeneratesUrlsWithoutTrailingSlash()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 2, 2, ['path' => 'http://website.com/test']);\n\n        $this->assertSame('http://website.com/test?page=1', $p->previousPageUrl());\n    }\n\n    public function testItRetrievesThePaginatorOptions()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 2, 2, ['path' => 'http://website.com/test']);\n\n        $this->assertSame(['path' => 'http://website.com/test'], $p->getOptions());\n    }\n\n    public function testPaginatorReturnsPath()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 2, 2, ['path' => 'http://website.com/test']);\n\n        $this->assertSame('http://website.com/test', $p->path());\n    }\n\n    public function testCanTransformPaginatorItems()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 3, 1, ['path' => 'http://website.com/test']);\n\n        $p->through(function ($item) {\n            return substr($item, 4, 1);\n        });\n\n        $this->assertInstanceOf(Paginator::class, $p);\n        $this->assertSame(['1', '2', '3'], $p->items());\n    }\n\n    public function testPaginatorToJson()\n    {\n        $p = new Paginator(['item1', 'item2', 'item3'], 3, 1);\n        $results = $p->toJson();\n        $expected = json_encode($p->toArray());\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n    }\n\n    public function testPaginatorToPrettyJson()\n    {\n        $p = new Paginator(['item/1', 'item/2', 'item/3'], 3, 1);\n        $results = $p->toPrettyJson();\n        $expected = $p->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('item\\/1', $results);\n\n        $results = $p->toPrettyJson(JSON_UNESCAPED_SLASHES);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('item/1', $results);\n    }\n}\n"
  },
  {
    "path": "tests/Pagination/UrlWindowTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pagination;\n\nuse Illuminate\\Pagination\\LengthAwarePaginator;\nuse Illuminate\\Pagination\\UrlWindow;\nuse PHPUnit\\Framework\\TestCase;\n\nclass UrlWindowTest extends TestCase\n{\n    public function testPresenterCanDetermineIfThereAreAnyPagesToShow()\n    {\n        $p = new LengthAwarePaginator($array = ['item1', 'item2', 'item3', 'item4'], 4, 2, 2);\n        $window = new UrlWindow($p);\n        $this->assertTrue($window->hasPages());\n    }\n\n    public function testPresenterCanGetAUrlRangeForASmallNumberOfUrls()\n    {\n        $p = new LengthAwarePaginator($array = ['item1', 'item2', 'item3', 'item4'], 4, 2, 2);\n        $window = new UrlWindow($p);\n        $this->assertEquals(['first' => [1 => '/?page=1', 2 => '/?page=2'], 'slider' => null, 'last' => null], $window->get());\n    }\n\n    public function testPresenterCanGetAUrlRangeForAWindowOfLinks()\n    {\n        $array = [];\n        for ($i = 1; $i <= 20; $i++) {\n            $array[$i] = 'item'.$i;\n        }\n        $p = new LengthAwarePaginator($array, count($array), 1, 12);\n        $window = new UrlWindow($p);\n        $slider = [];\n        for ($i = 9; $i <= 15; $i++) {\n            $slider[$i] = '/?page='.$i;\n        }\n\n        $this->assertEquals(['first' => [1 => '/?page=1', 2 => '/?page=2'], 'slider' => $slider, 'last' => [19 => '/?page=19', 20 => '/?page=20']], $window->get());\n\n        // Test Being Near The End Of The List\n        $array = [];\n        for ($i = 1; $i <= 20; $i++) {\n            $array[$i] = 'item'.$i;\n        }\n        $p = new LengthAwarePaginator($array, count($array), 1, 17);\n        $window = new UrlWindow($p);\n        $last = [];\n        for ($i = 11; $i <= 20; $i++) {\n            $last[$i] = '/?page='.$i;\n        }\n        $this->assertEquals(['first' => [1 => '/?page=1', 2 => '/?page=2'], 'slider' => null, 'last' => $last], $window->get());\n    }\n\n    public function testCustomUrlRangeForAWindowOfLinks()\n    {\n        $array = [];\n        for ($i = 1; $i <= 20; $i++) {\n            $array[$i] = 'item'.$i;\n        }\n\n        $p = new LengthAwarePaginator($array, count($array), 1, 8);\n        $p->onEachSide(1);\n        $window = new UrlWindow($p);\n\n        $slider = [];\n        for ($i = 7; $i <= 9; $i++) {\n            $slider[$i] = '/?page='.$i;\n        }\n\n        $this->assertEquals(['first' => [1 => '/?page=1', 2 => '/?page=2'], 'slider' => $slider, 'last' => [19 => '/?page=19', 20 => '/?page=20']], $window->get());\n    }\n}\n"
  },
  {
    "path": "tests/Pipeline/PipelineTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pipeline;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Pipeline\\Pipeline;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse stdClass;\n\nclass PipelineTest extends TestCase\n{\n    public function testPipelineBasicUsage()\n    {\n        $pipeTwo = function ($piped, $next) {\n            $_SERVER['__test.pipe.two'] = $piped;\n\n            return $next($piped);\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([PipelineTestPipeOne::class, $pipeTwo])\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n        $this->assertSame('foo', $_SERVER['__test.pipe.two']);\n\n        unset($_SERVER['__test.pipe.one'], $_SERVER['__test.pipe.two']);\n    }\n\n    public function testPipelineUsageWithObjects()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([new PipelineTestPipeOne])\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testPipelineUsageWithInvokableObjects()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([new PipelineTestPipeTwo])\n            ->then(\n                function ($piped) {\n                    return $piped;\n                }\n            );\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testPipelineUsageWithCallable()\n    {\n        $function = function ($piped, $next) {\n            $_SERVER['__test.pipe.one'] = 'foo';\n\n            return $next($piped);\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([$function])\n            ->then(\n                function ($piped) {\n                    return $piped;\n                }\n            );\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n\n        $result = (new Pipeline(new Container))\n            ->send('bar')\n            ->through($function)\n            ->thenReturn();\n\n        $this->assertSame('bar', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testPipelineUsageWithPipe()\n    {\n        $object = new stdClass();\n\n        $object->value = 0;\n\n        $function = function ($object, $next) {\n            $object->value++;\n\n            return $next($object);\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send($object)\n            ->through([$function])\n            ->pipe([$function])\n            ->then(\n                function ($piped) {\n                    return $piped;\n                }\n            );\n\n        $this->assertSame($object, $result);\n        $this->assertEquals(2, $object->value);\n    }\n\n    public function testPipelineThroughMethodOverwritesPreviouslySetAndAppendedPipes()\n    {\n        $object = new stdClass();\n\n        $object->value = 0;\n\n        $function = function ($object, $next) {\n            $object->value++;\n\n            return $next($object);\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send($object)\n            ->through([$function])\n            ->pipe([$function])\n            ->through([$function])\n            ->then(fn ($piped) => $piped);\n\n        $this->assertSame($object, $result);\n        $this->assertEquals(1, $object->value);\n    }\n\n    public function testPipelineUsageWithInvokableClass()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([PipelineTestPipeTwo::class])\n            ->then(\n                function ($piped) {\n                    return $piped;\n                }\n            );\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testThenMethodIsNotCalledIfThePipeReturns()\n    {\n        $_SERVER['__test.pipe.then'] = '(*_*)';\n        $_SERVER['__test.pipe.second'] = '(*_*)';\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([\n                fn ($value, $next) => 'm(-_-)m',\n                fn ($value, $next) => $_SERVER['__test.pipe.second'] = 'm(-_-)m',\n            ])\n            ->then(function ($piped) {\n                $_SERVER['__test.pipe.then'] = '(0_0)';\n\n                return $piped;\n            });\n\n        $this->assertSame('m(-_-)m', $result);\n        // The then callback is not called.\n        $this->assertSame('(*_*)', $_SERVER['__test.pipe.then']);\n        // The second pipe is not called.\n        $this->assertSame('(*_*)', $_SERVER['__test.pipe.second']);\n\n        unset($_SERVER['__test.pipe.then']);\n    }\n\n    public function testThenMethodInputValue()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([function ($value, $next) {\n                $value = $next('::not_foo::');\n\n                $_SERVER['__test.pipe.return'] = $value;\n\n                return 'pipe::'.$value;\n            }])\n            ->then(function ($piped) {\n                $_SERVER['__test.then.arg'] = $piped;\n\n                return 'then'.$piped;\n            });\n\n        $this->assertSame('pipe::then::not_foo::', $result);\n        $this->assertSame('::not_foo::', $_SERVER['__test.then.arg']);\n\n        unset($_SERVER['__test.then.arg']);\n        unset($_SERVER['__test.pipe.return']);\n    }\n\n    public function testPipelineUsageWithParameters()\n    {\n        $parameters = ['one', 'two'];\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through(PipelineTestParameterPipe::class.':'.implode(',', $parameters))\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame('foo', $result);\n        $this->assertEquals($parameters, $_SERVER['__test.pipe.parameters']);\n\n        unset($_SERVER['__test.pipe.parameters']);\n    }\n\n    public function testPipelineViaChangesTheMethodBeingCalledOnThePipes()\n    {\n        $pipelineInstance = new Pipeline(new Container);\n        $result = $pipelineInstance->send('data')\n            ->through(PipelineTestPipeOne::class)\n            ->via('differentMethod')\n            ->then(function ($piped) {\n                return $piped;\n            });\n        $this->assertSame('data', $result);\n    }\n\n    public function testPipelineThrowsExceptionOnResolveWithoutContainer()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('A container instance has not been passed to the Pipeline.');\n\n        (new Pipeline)->send('data')\n            ->through(PipelineTestPipeOne::class)\n            ->then(function ($piped) {\n                return $piped;\n            });\n    }\n\n    public function testPipelineThrowsExceptionWhenUsingTransactionsWithoutContainer()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('A container instance has not been passed to the Pipeline.');\n\n        (new Pipeline)->send('data')\n            ->through(PipelineTestPipeOne::class)\n            ->withinTransaction()\n            ->then(function ($piped) {\n                return $piped;\n            });\n    }\n\n    public function testPipelineThenReturnMethodRunsPipelineThenReturnsPassable()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([PipelineTestPipeOne::class])\n            ->thenReturn();\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testPipelineConditionable()\n    {\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->when(true, function (Pipeline $pipeline) {\n                $pipeline->pipe([PipelineTestPipeOne::class]);\n            })\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame('foo', $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n        unset($_SERVER['__test.pipe.one']);\n\n        $_SERVER['__test.pipe.one'] = null;\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->when(false, function (Pipeline $pipeline) {\n                $pipeline->pipe([PipelineTestPipeOne::class]);\n            })\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame('foo', $result);\n        $this->assertNull($_SERVER['__test.pipe.one']);\n        unset($_SERVER['__test.pipe.one']);\n    }\n\n    public function testPipelineFinally()\n    {\n        $pipeTwo = function ($piped, $next) {\n            $_SERVER['__test.pipe.two'] = $piped;\n\n            $next($piped);\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([PipelineTestPipeOne::class, $pipeTwo])\n            ->finally(function ($piped) {\n                $_SERVER['__test.pipe.finally'] = $piped;\n            })\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame(null, $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n        $this->assertSame('foo', $_SERVER['__test.pipe.two']);\n        $this->assertSame('foo', $_SERVER['__test.pipe.finally']);\n\n        unset($_SERVER['__test.pipe.one'], $_SERVER['__test.pipe.two'], $_SERVER['__test.pipe.finally']);\n    }\n\n    public function testPipelineFinallyMethodWhenChainIsStopped()\n    {\n        $pipeTwo = function ($piped) {\n            $_SERVER['__test.pipe.two'] = $piped;\n        };\n\n        $result = (new Pipeline(new Container))\n            ->send('foo')\n            ->through([PipelineTestPipeOne::class, $pipeTwo])\n            ->finally(function ($piped) {\n                $_SERVER['__test.pipe.finally'] = $piped;\n            })\n            ->then(function ($piped) {\n                return $piped;\n            });\n\n        $this->assertSame(null, $result);\n        $this->assertSame('foo', $_SERVER['__test.pipe.one']);\n        $this->assertSame('foo', $_SERVER['__test.pipe.two']);\n        $this->assertSame('foo', $_SERVER['__test.pipe.finally']);\n\n        unset($_SERVER['__test.pipe.one'], $_SERVER['__test.pipe.two'], $_SERVER['__test.pipe.finally']);\n    }\n\n    public function testPipelineFinallyOrder()\n    {\n        $std = new stdClass();\n\n        $result = (new Pipeline(new Container))\n            ->send($std)\n            ->through([\n                function ($std, $next) {\n                    $std->value = 1;\n\n                    return $next($std);\n                },\n                function ($std, $next) {\n                    $std->value++;\n\n                    return $next($std);\n                },\n            ])->finally(function ($std) {\n                $this->assertSame(3, $std->value);\n\n                $std->value++;\n            })->then(function ($std) {\n                $std->value++;\n\n                return $std;\n            });\n\n        $this->assertSame(4, $std->value);\n        $this->assertSame(4, $result->value);\n    }\n\n    public function testPipelineFinallyWhenExceptionOccurs()\n    {\n        $std = new stdClass();\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('My Exception: 1');\n\n        try {\n            (new Pipeline(new Container))\n                ->send($std)\n                ->through([\n                    function ($std, $next) {\n                        $std->value = 1;\n\n                        return $next($std);\n                    },\n                    function ($std) {\n                        throw new Exception('My Exception: '.$std->value);\n                    },\n                ])->finally(function ($std) {\n                    $this->assertSame(1, $std->value);\n\n                    $std->value++;\n                })->then(function ($std) {\n                    $std->value = 0;\n\n                    return $std;\n                });\n        } catch (Exception $e) {\n            $this->assertSame('My Exception: 1', $e->getMessage());\n            $this->assertSame(2, $std->value);\n\n            throw $e;\n        }\n    }\n}\n\nclass PipelineTestPipeOne\n{\n    public function handle($piped, $next)\n    {\n        $_SERVER['__test.pipe.one'] = $piped;\n\n        return $next($piped);\n    }\n\n    public function differentMethod($piped, $next)\n    {\n        return $next($piped);\n    }\n}\n\nclass PipelineTestPipeTwo\n{\n    public function __invoke($piped, $next)\n    {\n        $_SERVER['__test.pipe.one'] = $piped;\n\n        return $next($piped);\n    }\n}\n\nclass PipelineTestParameterPipe\n{\n    public function handle($piped, $next, $parameter1 = null, $parameter2 = null)\n    {\n        $_SERVER['__test.pipe.parameters'] = [$parameter1, $parameter2];\n\n        return $next($piped);\n    }\n}\n"
  },
  {
    "path": "tests/Pipeline/PipelineTransactionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Pipeline;\n\nuse Exception;\nuse Illuminate\\Database\\Events\\TransactionBeginning;\nuse Illuminate\\Database\\Events\\TransactionCommitted;\nuse Illuminate\\Database\\Events\\TransactionRolledBack;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Pipeline;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\n\nclass PipelineTransactionTest extends TestCase\n{\n    public function testPipelineTransaction()\n    {\n        Event::fake();\n\n        $result = Pipeline::withinTransaction()\n            ->send('some string')\n            ->through([\n                fn ($value, $next) => $next($value),\n                fn ($value, $next) => $next($value),\n            ])\n            ->thenReturn();\n\n        $this->assertEquals('some string', $result);\n        Event::assertDispatchedTimes(TransactionBeginning::class, 1);\n        Event::assertDispatchedTimes(TransactionCommitted::class, 1);\n    }\n\n    public static function transactionConnectionDataProvider(): array\n    {\n        return [\n            'unit enum' => [EnumForPipelineTransactionTest::DEFAULT, 'testing'],\n            'string' => ['testing', 'testing'],\n            'null' => [null, 'testing2'],\n        ];\n    }\n\n    #[DataProvider('transactionConnectionDataProvider')]\n    public function testConnection($connection, $connectionName)\n    {\n        Event::fake();\n        config(['database.connections.testing2' => config('database.connections.testing')]);\n        config(['database.default' => 'testing2']);\n\n        $result = Pipeline::withinTransaction($connection)\n            ->send('some string')\n            ->through([\n                function ($value, $next) {\n                    return $next($value);\n                },\n            ])\n            ->thenReturn();\n\n        $this->assertEquals('some string', $result);\n        Event::dispatched(TransactionBeginning::class, function (TransactionBeginning $event) use ($connectionName) {\n            return $event->connection === $connectionName;\n        });\n    }\n\n    public function testExceptionThrownRollsBackTransaction()\n    {\n        Event::fake();\n\n        $finallyRan = false;\n        try {\n            Pipeline::withinTransaction()\n                ->send('some string')\n                ->through([\n                    function ($value, $next) {\n                        throw new Exception('I was thrown');\n                    },\n                ])\n                ->finally(function () use (&$finallyRan) {\n                    $finallyRan = true;\n                })\n                ->thenReturn();\n            $this->fail('No exception was thrown');\n        } catch (Exception) {\n        }\n\n        $this->assertTrue($finallyRan);\n        Event::assertDispatched(TransactionBeginning::class);\n        Event::assertDispatched(TransactionRolledBack::class);\n    }\n}\n\nenum EnumForPipelineTransactionTest: string\n{\n    case DEFAULT = 'testing';\n}\n"
  },
  {
    "path": "tests/Process/ProcessTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Process;\n\nuse Carbon\\CarbonInterval;\nuse Illuminate\\Contracts\\Process\\ProcessResult;\nuse Illuminate\\Process\\Exceptions\\ProcessFailedException;\nuse Illuminate\\Process\\Exceptions\\ProcessTimedOutException;\nuse Illuminate\\Process\\Factory;\nuse OutOfBoundsException;\nuse PHPUnit\\Framework\\Attributes\\RequiresOperatingSystem;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass ProcessTest extends TestCase\n{\n    public function testSuccessfulProcess()\n    {\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run($this->ls());\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertFalse($result->failed());\n        $this->assertEquals(0, $result->exitCode());\n        $this->assertTrue(str_contains($result->output(), 'ProcessTest.php'));\n        $this->assertEquals('', $result->errorOutput());\n\n        $result->throw();\n        $result->throwIf(true);\n    }\n\n    public function testProcessPool()\n    {\n        $factory = new Factory;\n\n        $pool = $factory->pool(function ($pool) {\n            return [\n                $pool->path(__DIR__)->command($this->ls()),\n                $pool->path(__DIR__)->command($this->ls()),\n            ];\n        });\n\n        $results = $pool->start()->wait();\n\n        $this->assertTrue($results[0]->successful());\n        $this->assertTrue($results[1]->successful());\n\n        $this->assertTrue(str_contains($results[0]->output(), 'ProcessTest.php'));\n        $this->assertTrue(str_contains($results[1]->output(), 'ProcessTest.php'));\n\n        $this->assertTrue($results->successful());\n    }\n\n    public function testProcessPoolFailed()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'cat *' => $factory->result(exitCode: 1),\n        ]);\n\n        $pool = $factory->pool(function ($pool) {\n            return [\n                $pool->path(__DIR__)->command($this->ls()),\n                $pool->path(__DIR__)->command('cat test'),\n            ];\n        });\n\n        $results = $pool->start()->wait();\n\n        $this->assertTrue($results[0]->successful());\n        $this->assertTrue($results[1]->failed());\n\n        $this->assertTrue($results->failed());\n    }\n\n    public function testInvokedProcessPoolCount()\n    {\n        $factory = new Factory;\n\n        $pool = $factory->pool(function ($pool) {\n            return [\n                $pool->path(__DIR__)->command($this->ls()),\n                $pool->path(__DIR__)->command($this->ls()),\n            ];\n        })->start();\n\n        $this->assertCount(2, $pool);\n    }\n\n    public function testProcessPoolCanReceiveOutputForEachProcessViaStartMethod()\n    {\n        $factory = new Factory;\n\n        $output = [];\n\n        $pool = $factory->pool(function ($pool) {\n            return [\n                $pool->path(__DIR__)->command($this->ls()),\n                $pool->path(__DIR__)->command($this->ls()),\n            ];\n        })->start(function ($type, $buffer, $key) use (&$output) {\n            $output[$key][$type][] = $buffer;\n        });\n\n        $poolResults = $pool->wait();\n\n        $this->assertTrue(count($output[0]['out']) > 0);\n        $this->assertTrue(count($output[1]['out']) > 0);\n        $this->assertInstanceOf(ProcessResult::class, $poolResults[0]);\n        $this->assertInstanceOf(ProcessResult::class, $poolResults[1]);\n        $this->assertTrue(str_contains($poolResults[0]->output(), 'ProcessTest.php'));\n        $this->assertTrue(str_contains($poolResults[1]->output(), 'ProcessTest.php'));\n    }\n\n    public function testProcessPoolResultsCanBeEvaluatedByName()\n    {\n        $factory = new Factory;\n\n        $pool = $factory->pool(function ($pool) {\n            return [\n                $pool->as('first')->path(__DIR__)->command($this->ls()),\n                $pool->as('second')->path(__DIR__)->command($this->ls()),\n            ];\n        })->wait();\n\n        $this->assertTrue($pool['first']->successful());\n        $this->assertTrue($pool['second']->successful());\n\n        $this->assertTrue(str_contains($pool['first']->output(), 'ProcessTest.php'));\n        $this->assertTrue(str_contains($pool['second']->output(), 'ProcessTest.php'));\n    }\n\n    public function testOutputCanBeRetrievedViaStartCallback()\n    {\n        $factory = new Factory;\n\n        $output = [];\n\n        $process = $factory->path(__DIR__)->start($this->ls(), function ($type, $buffer) use (&$output) {\n            $output[] = $buffer;\n        });\n\n        $process->wait();\n\n        $this->assertTrue(str_contains(implode('', $output), 'ProcessTest.php'));\n    }\n\n    public function testOutputCanBeRetrievedViaWaitCallback()\n    {\n        $factory = new Factory;\n\n        $output = [];\n\n        $process = $factory->path(__DIR__)->start($this->ls());\n\n        $process->wait(function ($type, $buffer) use (&$output) {\n            $output[] = $buffer;\n        });\n\n        $this->assertTrue(str_contains(implode('', $output), 'ProcessTest.php'));\n    }\n\n    public function testBasicProcessFake()\n    {\n        $factory = new Factory;\n        $factory->fake();\n\n        $result = $factory->run('ls -la');\n\n        $this->assertEquals('', $result->output());\n        $this->assertEquals('', $result->errorOutput());\n        $this->assertEquals(0, $result->exitCode());\n        $this->assertTrue($result->successful());\n    }\n\n    public function testBasicProcessFakeWithMultiLineCommand()\n    {\n        $factory = new Factory;\n\n        $factory->preventStrayProcesses();\n\n        $factory->fake([\n            '*' => $expectedOutput = 'The output',\n        ]);\n\n        $result = $factory->run(<<<'COMMAND'\n        git clone --depth 1 \\\n              --single-branch \\\n              --branch main \\\n              git://some-url .\n        COMMAND);\n\n        $this->assertSame(0, $result->exitCode());\n        $this->assertSame(\"$expectedOutput\\n\", $result->output());\n    }\n\n    public function testProcessFakeWithMultiLineCommand()\n    {\n        $factory = new Factory;\n\n        $factory->preventStrayProcesses();\n\n        $factory->fake([\n            '*--branch main*' => 'not this one',\n            '*--branch develop*' => $expectedOutput = 'yes thank you',\n        ]);\n\n        $result = $factory->run(<<<'COMMAND'\n        git clone --depth 1 \\\n              --single-branch \\\n              --branch develop \\\n              git://some-url .\n        COMMAND);\n\n        $this->assertSame(0, $result->exitCode());\n        $this->assertSame(\"$expectedOutput\\n\", $result->output());\n    }\n\n    public function testProcessFakeExitCodes()\n    {\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result('test output', exitCode: 1));\n\n        $result = $factory->run('ls -la');\n        $this->assertFalse($result->successful());\n    }\n\n    public function testProcessFakeExitCodeShorthand()\n    {\n        $factory = new Factory;\n        $factory->fake(['ls -la' => 1]);\n\n        $result = $factory->run('ls -la');\n        $this->assertSame(1, $result->exitCode());\n        $this->assertFalse($result->successful());\n    }\n\n    public function testBasicProcessFakeWithCustomOutput()\n    {\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result('test output'));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"test output\\n\", $result->output());\n\n        // Array of output...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result(['line 1', 'line 2']));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\nline 2\\n\", $result->output());\n\n        // Array of output with empty line...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result(['line 1', '', 'line 2']));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\n\\nline 2\\n\", $result->output());\n\n        // Plain string...\n        $factory = new Factory;\n        $factory->fake(fn () => 'test output');\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"test output\\n\", $result->output());\n\n        // Plain array...\n        $factory = new Factory;\n        $factory->fake(fn () => ['line 1', 'line 2']);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\nline 2\\n\", $result->output());\n\n        // Plain array with empty line...\n        $factory = new Factory;\n        $factory->fake(fn () => ['line 1', '', 'line 2']);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\n\\nline 2\\n\", $result->output());\n\n        // Process description...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->describe()->output('line 1')->output('line 2'));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\nline 2\\n\", $result->output());\n\n        // Process description with empty line...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->describe()->output('line 1')->output('')->output('line 2'));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"line 1\\n\\nline 2\\n\", $result->output());\n    }\n\n    public function testProcessFakeWithErrorOutput()\n    {\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result('standard output', 'error output'));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"standard output\\n\", $result->output());\n        $this->assertEquals(\"error output\\n\", $result->errorOutput());\n\n        // Array of error output...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result('standard output', ['line 1', 'line 2']));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"standard output\\n\", $result->output());\n        $this->assertEquals(\"line 1\\nline 2\\n\", $result->errorOutput());\n\n        // Using process description...\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->describe()->output('standard output')->errorOutput('error output'));\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"standard output\\n\", $result->output());\n        $this->assertEquals(\"error output\\n\", $result->errorOutput());\n    }\n\n    public function testCustomizedFakesPerCommand()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'ls *' => 'ls command',\n            'cat *' => 'cat command',\n        ]);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command\\n\", $result->output());\n\n        $result = $factory->run('cat composer.json');\n        $this->assertEquals(\"cat command\\n\", $result->output());\n    }\n\n    public function testProcessFakeSequences()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'ls *' => $factory->sequence()\n                ->push('ls command 1')\n                ->push('ls command 2'),\n            'cat *' => 'cat command',\n        ]);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 1\\n\", $result->output());\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 2\\n\", $result->output());\n\n        $result = $factory->run('cat composer.json');\n        $this->assertEquals(\"cat command\\n\", $result->output());\n    }\n\n    public function testProcessFakeSequencesCanReturnEmptyResultsWhenSequenceIsEmpty()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'ls *' => $factory->sequence()\n                ->push('ls command 1')\n                ->push('ls command 2')\n                ->dontFailWhenEmpty(),\n        ]);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 1\\n\", $result->output());\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 2\\n\", $result->output());\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals('', $result->output());\n    }\n\n    public function testProcessFakeSequencesCanThrowWhenSequenceIsEmpty()\n    {\n        $this->expectException(OutOfBoundsException::class);\n\n        $factory = new Factory;\n\n        $factory->fake([\n            'ls *' => $factory->sequence()\n                ->push('ls command 1')\n                ->push('ls command 2'),\n        ]);\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 1\\n\", $result->output());\n\n        $result = $factory->run('ls -la');\n        $this->assertEquals(\"ls command 2\\n\", $result->output());\n\n        $result = $factory->run('ls -la');\n    }\n\n    public function testStrayProcessesCanBePreventedWithStringCommand()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Attempted process [');\n        $this->expectExceptionMessage('cat composer.json');\n        $this->expectExceptionMessage('] without a matching fake.');\n\n        $factory = new Factory;\n\n        $factory->preventStrayProcesses();\n\n        $factory->fake([\n            'ls *' => 'ls command',\n        ]);\n\n        $result = $factory->run('cat composer.json');\n    }\n\n    public function testStrayProcessesCanBePreventedWithArrayCommand()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Attempted process [');\n        $this->expectExceptionMessage('cat composer.json');\n        $this->expectExceptionMessage('] without a matching fake.');\n\n        $factory = new Factory;\n\n        $factory->preventStrayProcesses();\n\n        $factory->fake([\n            'ls *' => 'ls command',\n        ]);\n\n        $result = $factory->run(['cat composer.json']);\n    }\n\n    public function testStrayProcessesActuallyRunByDefault()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'cat *' => 'cat command',\n        ]);\n\n        $result = $factory->path(__DIR__)->run($this->ls());\n        $this->assertTrue(str_contains($result->output(), 'ProcessTest.php'));\n    }\n\n    public function testProcessFakeThrowShorthand()\n    {\n        $this->expectException(\\RuntimeException::class);\n        $this->expectExceptionMessage('fake exception message');\n\n        $factory = new Factory;\n\n        $factory->fake(['cat me' => new \\RuntimeException('fake exception message')]);\n\n        $factory->run('cat me');\n    }\n\n    public function testFakeProcessesCanThrow()\n    {\n        $this->expectException(ProcessFailedException::class);\n\n        $factory = new Factory;\n\n        $factory->fake(fn () => $factory->result(exitCode: 1));\n\n        $result = $factory->path(__DIR__)->run($this->ls());\n        $result->throw();\n    }\n\n    public function testFakeProcessesThrowIfTrue()\n    {\n        $this->expectException(ProcessFailedException::class);\n\n        $factory = new Factory;\n\n        $factory->fake(fn () => $factory->result(exitCode: 1));\n\n        $result = $factory->path(__DIR__)->run($this->ls());\n        $result->throwIf(true);\n    }\n\n    public function testFakeProcessesDontThrowIfFalse()\n    {\n        $factory = new Factory;\n\n        $factory->fake(fn () => $factory->result(exitCode: 1));\n\n        $result = $factory->path(__DIR__)->run($this->ls());\n        $result->throwIf(false);\n\n        $this->assertTrue(true);\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanHaveErrorOutput()\n    {\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&2; exit 1;');\n\n        $this->assertFalse($result->successful());\n        $this->assertEquals('', $result->output());\n        $this->assertEquals(\"Hello World\\n\", $result->errorOutput());\n    }\n\n    public function testFakeProcessesCanThrowWithoutOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"exit 1;\" failed.\n\n            Exit Code: 1\n            EOT\n        );\n\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result(exitCode: 1));\n        $result = $factory->path(__DIR__)->run('exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanThrowWithoutOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"exit 1;\" failed.\n\n            Exit Code: 1\n            EOT\n        );\n\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('exit 1;');\n\n        $result->throw();\n    }\n\n    public function testFakeProcessesCanThrowWithErrorOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"echo \"Hello World\" >&2; exit 1;\" failed.\n\n            Exit Code: 1\n\n            Error Output:\n            ================\n            Hello World\n            EOT\n        );\n\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result(errorOutput: 'Hello World', exitCode: 1));\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&2; exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanThrowWithErrorOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"echo \"Hello World\" >&2; exit 1;\" failed.\n\n            Exit Code: 1\n\n            Error Output:\n            ================\n            Hello World\n            EOT\n        );\n\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&2; exit 1;');\n\n        $result->throw();\n    }\n\n    public function testFakeProcessesCanThrowWithOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"echo \"Hello World\" >&1; exit 1;\" failed.\n\n            Exit Code: 1\n\n            Output:\n            ================\n            Hello World\n            EOT\n        );\n\n        $factory = new Factory;\n        $factory->fake(fn () => $factory->result(output: 'Hello World', exitCode: 1));\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&1; exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanThrowWithOutput()\n    {\n        $this->expectException(ProcessFailedException::class);\n        $this->expectExceptionMessage(<<<'EOT'\n            The command \"echo \"Hello World\" >&1; exit 1;\" failed.\n\n            Exit Code: 1\n\n            Output:\n            ================\n            Hello World\n            EOT\n        );\n\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&1; exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanTimeout()\n    {\n        $this->expectException(ProcessTimedOutException::class);\n        $this->expectExceptionMessage(\n            'The process \"sleep 2; exit 1;\" exceeded the timeout of 1 seconds.'\n        );\n\n        $factory = new Factory;\n        $result = $factory->timeout(1)->path(__DIR__)->run('sleep 2; exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testATimeoutCanBeSetWithACarbonInterval()\n    {\n        $this->expectException(ProcessTimedOutException::class);\n        $this->expectExceptionMessage(\n            'The process \"sleep 2; exit 1;\" exceeded the timeout of 1 seconds.'\n        );\n\n        $factory = new Factory;\n        $timeout = CarbonInterval::milliseconds(1_000);\n        $result = $factory->timeout($timeout)->path(__DIR__)->run('sleep 2; exit 1;');\n\n        $result->throw();\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanThrowIfTrue()\n    {\n        $this->expectException(ProcessFailedException::class);\n\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&2; exit 1;');\n\n        $result->throwIf(true);\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesDoesntThrowIfFalse()\n    {\n        $factory = new Factory;\n        $result = $factory->path(__DIR__)->run('echo \"Hello World\" >&2; exit 1;');\n\n        $result->throwIf(false);\n\n        $this->assertTrue(true);\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testRealProcessesCanUseStandardInput()\n    {\n        $factory = new Factory();\n        $result = $factory->input('foobar')->run('cat');\n\n        $this->assertSame('foobar', $result->output());\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testProcessPipe()\n    {\n        $factory = new Factory;\n        $factory->fake([\n            'cat *' => \"Hello, world\\nfoo\\nbar\",\n        ]);\n\n        $pipe = $factory->pipe(function ($pipe) {\n            $pipe->command('cat test');\n            $pipe->command('grep -i \"foo\"');\n        });\n\n        $this->assertSame(\"foo\\n\", $pipe->output());\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testProcessPipeFailed()\n    {\n        $factory = new Factory;\n        $factory->fake([\n            'cat *' => $factory->result(exitCode: 1),\n        ]);\n\n        $pipe = $factory->pipe(function ($pipe) {\n            $pipe->command('cat test');\n            $pipe->command('grep -i \"foo\"');\n        });\n\n        $this->assertTrue($pipe->failed());\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testProcessSimplePipe()\n    {\n        $factory = new Factory;\n        $factory->fake([\n            'cat *' => \"Hello, world\\nfoo\\nbar\",\n        ]);\n\n        $pipe = $factory->pipe([\n            'cat test',\n            'grep -i \"foo\"',\n        ]);\n\n        $this->assertSame(\"foo\\n\", $pipe->output());\n    }\n\n    #[RequiresOperatingSystem('Linux|DAR')]\n    public function testProcessSimplePipeFailed()\n    {\n        $factory = new Factory;\n        $factory->fake([\n            'cat *' => $factory->result(exitCode: 1),\n        ]);\n\n        $pipe = $factory->pipe([\n            'cat test',\n            'grep -i \"foo\"',\n        ]);\n\n        $this->assertTrue($pipe->failed());\n    }\n\n    public function testFakeInvokedProcessOutputWithLatestOutput()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('ONE')\n                ->output('TWO')\n                ->output('THREE')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"ONE\"; sleep 1; echo \"TWO\"; sleep 1; echo \"THREE\"; sleep 1;');\n\n        $latestOutput = [];\n        $output = [];\n\n        while ($process->running()) {\n            $latestOutput[] = $process->latestOutput();\n            $output[] = $process->output();\n        }\n\n        $this->assertEquals(\"ONE\\n\", $latestOutput[0]);\n        $this->assertEquals(\"ONE\\nTWO\\n\", $output[0]);\n\n        $this->assertEquals(\"THREE\\n\", $latestOutput[1]);\n        $this->assertEquals(\"ONE\\nTWO\\nTHREE\\n\", $output[1]);\n\n        $this->assertEquals('', $latestOutput[2]);\n        $this->assertEquals(\"ONE\\nTWO\\nTHREE\\n\", $output[2]);\n    }\n\n    public function testFakeInvokedProcessWaitUntil()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('WAITING')\n                ->output('READY')\n                ->output('DONE')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"WAITING\"; sleep 1; echo \"READY\"; sleep 1; echo \"DONE\";');\n\n        $callbackInvoked = [];\n\n        $result = $process->waitUntil(function ($type, $buffer) use (&$callbackInvoked) {\n            $callbackInvoked[] = $buffer;\n\n            return str_contains($buffer, 'READY');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertContains(\"WAITING\\n\", $callbackInvoked);\n        $this->assertContains(\"READY\\n\", $callbackInvoked);\n    }\n\n    public function testFakeInvokedProcessWaitUntilWithNoCallback()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('OUTPUT');\n        });\n\n        $process = $factory->start('echo \"OUTPUT\"');\n\n        $result = $process->waitUntil();\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertEquals(\"OUTPUT\\n\", $result->output());\n    }\n\n    public function testFakeInvokedProcessWaitUntilWithErrorOutput()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('STDOUT')\n                ->errorOutput('ERROR1')\n                ->errorOutput('TARGET_ERROR')\n                ->output('MORE_STDOUT')\n                ->runsFor(iterations: 4);\n        });\n\n        $process = $factory->start('echo \"STDOUT\"; echo \"ERROR1\" >&2; echo \"TARGET_ERROR\" >&2; echo \"MORE_STDOUT\";');\n\n        $callbackInvoked = [];\n\n        $result = $process->waitUntil(function ($type, $buffer) use (&$callbackInvoked) {\n            $callbackInvoked[] = [$type, $buffer];\n\n            return str_contains($buffer, 'TARGET_ERROR');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertContains(['out', \"STDOUT\\n\"], $callbackInvoked);\n        $this->assertContains(['err', \"ERROR1\\n\"], $callbackInvoked);\n        $this->assertContains(['err', \"TARGET_ERROR\\n\"], $callbackInvoked);\n    }\n\n    public function testFakeInvokedProcessWaitUntilCalledTwice()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('FIRST')\n                ->output('SECOND')\n                ->output('THIRD')\n                ->output('FOURTH')\n                ->runsFor(iterations: 4);\n        });\n\n        $process = $factory->start('echo \"FIRST\"; echo \"SECOND\"; echo \"THIRD\"; echo \"FOURTH\";');\n\n        $firstCallbackInvoked = [];\n        $secondCallbackInvoked = [];\n\n        $firstResult = $process->waitUntil(function ($type, $buffer) use (&$firstCallbackInvoked) {\n            $firstCallbackInvoked[] = $buffer;\n\n            return str_contains($buffer, 'SECOND');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $firstResult);\n        $this->assertTrue($firstResult->successful());\n        $this->assertContains(\"FIRST\\n\", $firstCallbackInvoked);\n        $this->assertContains(\"SECOND\\n\", $firstCallbackInvoked);\n        $this->assertCount(2, $firstCallbackInvoked);\n\n        $secondResult = $process->waitUntil(function ($type, $buffer) use (&$secondCallbackInvoked) {\n            $secondCallbackInvoked[] = $buffer;\n\n            return str_contains($buffer, 'FOURTH');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $secondResult);\n        $this->assertTrue($secondResult->successful());\n        $this->assertContains(\"THIRD\\n\", $secondCallbackInvoked);\n        $this->assertContains(\"FOURTH\\n\", $secondCallbackInvoked);\n        $this->assertCount(2, $secondCallbackInvoked);\n    }\n\n    public function testFakeInvokedProcessWaitUntilThatNeverMatches()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('LINE1')\n                ->output('LINE2')\n                ->output('LINE3')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"LINE1\"; echo \"LINE2\"; echo \"LINE3\";');\n\n        $callbackInvoked = [];\n\n        $result = $process->waitUntil(function ($type, $buffer) use (&$callbackInvoked) {\n            $callbackInvoked[] = $buffer;\n\n            return str_contains($buffer, 'NEVER_MATCHES');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertCount(3, $callbackInvoked);\n        $this->assertContains(\"LINE1\\n\", $callbackInvoked);\n        $this->assertContains(\"LINE2\\n\", $callbackInvoked);\n        $this->assertContains(\"LINE3\\n\", $callbackInvoked);\n    }\n\n    public function testFakeInvokedProcessWaitUntilFollowedByWait()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('FIRST')\n                ->output('SECOND')\n                ->output('THIRD')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"FIRST\"; echo \"SECOND\"; echo \"THIRD\";');\n\n        $waitUntilCallbacks = [];\n        $waitCallbacks = [];\n\n        $process->waitUntil(function ($type, $buffer) use (&$waitUntilCallbacks) {\n            $waitUntilCallbacks[] = $buffer;\n\n            return str_contains($buffer, 'FIRST');\n        });\n\n        $result = $process->wait(function ($type, $buffer) use (&$waitCallbacks) {\n            $waitCallbacks[] = $buffer;\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertCount(1, $waitUntilCallbacks);\n        $this->assertEquals(\"FIRST\\n\", $waitUntilCallbacks[0]);\n        $this->assertCount(2, $waitCallbacks);\n        $this->assertContains(\"SECOND\\n\", $waitCallbacks);\n        $this->assertContains(\"THIRD\\n\", $waitCallbacks);\n    }\n\n    public function testFakeInvokedProcessWaitCalledTwice()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('FIRST')\n                ->output('SECOND')\n                ->output('THIRD')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"FIRST\"; echo \"SECOND\"; echo \"THIRD\";');\n\n        $firstCallbackInvoked = [];\n        $secondCallbackInvoked = [];\n\n        $firstResult = $process->wait(function ($type, $buffer) use (&$firstCallbackInvoked) {\n            $firstCallbackInvoked[] = $buffer;\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $firstResult);\n        $this->assertTrue($firstResult->successful());\n        $this->assertCount(3, $firstCallbackInvoked);\n        $this->assertContains(\"FIRST\\n\", $firstCallbackInvoked);\n        $this->assertContains(\"SECOND\\n\", $firstCallbackInvoked);\n        $this->assertContains(\"THIRD\\n\", $firstCallbackInvoked);\n\n        $secondResult = $process->wait(function ($type, $buffer) use (&$secondCallbackInvoked) {\n            $secondCallbackInvoked[] = $buffer;\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $secondResult);\n        $this->assertTrue($secondResult->successful());\n        $this->assertEmpty($secondCallbackInvoked);\n    }\n\n    public function testFakeInvokedProcessWaitFollowedByWaitUntil()\n    {\n        $factory = new Factory;\n\n        $factory->fake(function () use ($factory) {\n            return $factory->describe()\n                ->output('FIRST')\n                ->output('SECOND')\n                ->output('THIRD')\n                ->runsFor(iterations: 3);\n        });\n\n        $process = $factory->start('echo \"FIRST\"; echo \"SECOND\"; echo \"THIRD\";');\n\n        $waitCallbacks = [];\n        $waitUntilCallbacks = [];\n\n        $process->wait(function ($type, $buffer) use (&$waitCallbacks) {\n            $waitCallbacks[] = $buffer;\n        });\n\n        $result = $process->waitUntil(function ($type, $buffer) use (&$waitUntilCallbacks) {\n            $waitUntilCallbacks[] = $buffer;\n\n            return str_contains($buffer, 'THIRD');\n        });\n\n        $this->assertInstanceOf(ProcessResult::class, $result);\n        $this->assertTrue($result->successful());\n        $this->assertCount(3, $waitCallbacks);\n        $this->assertEmpty($waitUntilCallbacks);\n    }\n\n    public function testBasicFakeAssertions()\n    {\n        $factory = new Factory;\n\n        $factory->fake();\n\n        $result = $factory->run('ls -la');\n\n        $factory->assertRan(function ($process, $result) {\n            return $process->command == 'ls -la';\n        });\n\n        $factory->assertRanTimes(function ($process, $result) {\n            return $process->command == 'ls -la';\n        }, 1);\n\n        $factory->assertNotRan(function ($process, $result) {\n            return $process->command == 'cat foo';\n        });\n    }\n\n    public function testAssertingThatNothingRan()\n    {\n        $factory = new Factory;\n\n        $factory->fake();\n\n        $factory->assertNothingRan();\n    }\n\n    public function testProcessWithMultipleEnvironmentVariablesAndSequences()\n    {\n        $factory = new Factory;\n\n        $factory->fake([\n            'printenv TEST_VAR OTHER_VAR' => $factory->sequence()\n                ->push(\"test_value\\nother_value\")\n                ->push(\"new_test_value\\nnew_other_value\"),\n        ]);\n\n        $result = $factory->env([\n            'TEST_VAR' => 'test_value',\n            'OTHER_VAR' => 'other_value',\n        ])->run('printenv TEST_VAR OTHER_VAR');\n\n        $this->assertTrue($result->successful());\n        $this->assertEquals(\"test_value\\nother_value\\n\", $result->output());\n\n        $result = $factory->env([\n            'TEST_VAR' => 'new_test_value',\n            'OTHER_VAR' => 'new_other_value',\n        ])->run('printenv TEST_VAR OTHER_VAR');\n\n        $this->assertTrue($result->successful());\n        $this->assertEquals(\"new_test_value\\nnew_other_value\\n\", $result->output());\n\n        $factory->assertRanTimes(function ($process) {\n            return str_contains($process->command, 'printenv TEST_VAR OTHER_VAR');\n        }, 2);\n    }\n\n    protected function ls()\n    {\n        return windows_os() ? 'dir' : 'ls';\n    }\n}\n"
  },
  {
    "path": "tests/Queue/BeforeCommitContractTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse PHPUnit\\Framework\\TestCase;\n\nclass BeforeCommitContractTest extends TestCase\n{\n    public function testJobWithoutContractRespectsBeforeCommit()\n    {\n        $job = new class\n        {\n            use Dispatchable, InteractsWithQueue, Queueable;\n\n            public function beforeCommit()\n            {\n                $this->afterCommit = false;\n\n                return $this;\n            }\n        };\n\n        $this->assertFalse($this->shouldDispatchAfterCommit($job));\n    }\n\n    public function testJobWithoutContractRespectsAfterCommit()\n    {\n        $job = new class\n        {\n            use Dispatchable, InteractsWithQueue, Queueable;\n\n            public function afterCommit()\n            {\n                $this->afterCommit = true;\n\n                return $this;\n            }\n        };\n\n        $job->afterCommit();\n\n        $this->assertTrue($this->shouldDispatchAfterCommit($job));\n    }\n\n    public function testJobWithContractDefaultsToAfterCommit()\n    {\n        $job = new class implements ShouldQueueAfterCommit\n        {\n            use Dispatchable, InteractsWithQueue, Queueable;\n        };\n\n        $this->assertTrue($this->shouldDispatchAfterCommit($job));\n    }\n\n    public function testJobWithContractAndAfterCommitFalseRespectsBeforeCommit()\n    {\n        $job = new class implements ShouldQueueAfterCommit\n        {\n            use Dispatchable, InteractsWithQueue, Queueable;\n\n            public function beforeCommit()\n            {\n                $this->afterCommit = false;\n\n                return $this;\n            }\n        };\n\n        $job->beforeCommit();\n\n        $this->assertFalse($this->shouldDispatchAfterCommit($job));\n    }\n\n    public function testJobWithContractAndExplicitAfterCommitTrueStillSchedulesAfterCommit()\n    {\n        $job = new class implements ShouldQueueAfterCommit\n        {\n            use Dispatchable, InteractsWithQueue, Queueable;\n\n            public function afterCommit()\n            {\n                $this->afterCommit = true;\n\n                return $this;\n            }\n        };\n\n        $job->afterCommit();\n\n        $this->assertTrue($this->shouldDispatchAfterCommit($job));\n    }\n\n    protected function shouldDispatchAfterCommit($job)\n    {\n        if ($job instanceof ShouldQueueAfterCommit) {\n            return ! (isset($job->afterCommit) && $job->afterCommit === false);\n        }\n\n        return isset($job->afterCommit) ? $job->afterCommit : false;\n    }\n}\n"
  },
  {
    "path": "tests/Queue/DatabaseFailedJobProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Queue\\Failed\\DatabaseFailedJobProvider;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass DatabaseFailedJobProviderTest extends TestCase\n{\n    protected $db;\n\n    protected $provider;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->createDatabaseWithFailedJobTable()\n            ->createProvider();\n    }\n\n    public function testCanGetAllFailedJobIds()\n    {\n        $this->assertEmpty($this->provider->ids());\n\n        array_map(fn () => $this->createFailedJobsRecord(), range(1, 4));\n\n        $this->assertCount(4, $this->provider->ids());\n        $this->assertSame([4, 3, 2, 1], $this->provider->ids());\n    }\n\n    public function testCanGetAllFailedJobs()\n    {\n        $this->assertEmpty($this->provider->all());\n\n        array_map(fn () => $this->createFailedJobsRecord(), range(1, 4));\n\n        $this->assertCount(4, $this->provider->all());\n        $this->assertSame(3, $this->provider->all()[1]->id);\n        $this->assertSame('default', $this->provider->all()[1]->queue);\n    }\n\n    public function testCanRetrieveFailedJobsById()\n    {\n        array_map(fn () => $this->createFailedJobsRecord(), range(1, 2));\n\n        $this->assertNotNull($this->provider->find(1));\n        $this->assertNotNull($this->provider->find(2));\n        $this->assertNull($this->provider->find(3));\n    }\n\n    public function testCanRemoveFailedJobsById()\n    {\n        $this->createFailedJobsRecord();\n\n        $this->assertFalse($this->provider->forget(2));\n        $this->assertSame(1, $this->failedJobsTable()->count());\n        $this->assertTrue($this->provider->forget(1));\n        $this->assertSame(0, $this->failedJobsTable()->count());\n    }\n\n    public function testCanPruneFailedJobs()\n    {\n        Carbon::setTestNow(Carbon::createFromDate(2024, 4, 28));\n\n        $this->createFailedJobsRecord(['failed_at' => Carbon::createFromDate(2024, 4, 24)]);\n        $this->createFailedJobsRecord(['failed_at' => Carbon::createFromDate(2024, 4, 26)]);\n\n        $this->provider->prune(Carbon::createFromDate(2024, 4, 23));\n        $this->assertSame(2, $this->failedJobsTable()->count());\n\n        $this->provider->prune(Carbon::createFromDate(2024, 4, 25));\n        $this->assertSame(1, $this->failedJobsTable()->count());\n\n        $this->provider->prune(Carbon::createFromDate(2024, 4, 30));\n        $this->assertSame(0, $this->failedJobsTable()->count());\n    }\n\n    public function testCanPruneFailedJobsWithRelativeHoursAndMinutes()\n    {\n        Carbon::setTestNow(Carbon::create(2025, 8, 24, 12, 0, 0));\n\n        $this->createFailedJobsRecord(['failed_at' => Carbon::create(2025, 8, 24, 11, 45, 0)]);\n        $this->createFailedJobsRecord(['failed_at' => Carbon::create(2025, 8, 24, 13, 0, 0)]);\n\n        $this->provider->prune(Carbon::create(2025, 8, 24, 11, 45, 0));\n        $this->assertSame(2, $this->failedJobsTable()->count());\n\n        $this->provider->prune(Carbon::create(2025, 8, 24, 14, 0, 0));\n        $this->assertSame(0, $this->failedJobsTable()->count());\n    }\n\n    public function testCanFlushFailedJobs()\n    {\n        Date::setTestNow(Date::now());\n\n        $this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);\n        $this->provider->flush();\n        $this->assertSame(0, $this->failedJobsTable()->count());\n\n        $this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);\n        $this->provider->flush(15 * 24);\n        $this->assertSame(1, $this->failedJobsTable()->count());\n\n        $this->createFailedJobsRecord(['failed_at' => Date::now()->subDays(10)]);\n        $this->provider->flush(10 * 24);\n        $this->assertSame(0, $this->failedJobsTable()->count());\n    }\n\n    public function testCanProperlyLogFailedJob()\n    {\n        $uuid = Str::uuid();\n        $exception = new Exception(mb_convert_encoding('ÐÑÙ0E\\xE2\\x�98\\xA0World��7B¹!þÿ', 'ISO-8859-1', 'UTF-8'));\n\n        $this->provider->log('database', 'default', json_encode(['uuid' => (string) $uuid]), $exception);\n\n        $exception = (string) mb_convert_encoding($exception, 'UTF-8');\n\n        $this->assertSame(1, $this->failedJobsTable()->count());\n        $this->assertSame($exception, $this->failedJobsTable()->first()->exception);\n    }\n\n    public function testJobsCanBeCounted()\n    {\n        $this->assertSame(0, $this->provider->count());\n\n        $this->provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $this->provider->count());\n\n        $this->provider->log('database', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('another-connection', 'another-queue', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(3, $this->provider->count());\n    }\n\n    public function testJobsCanBeCountedByConnection()\n    {\n        $this->provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-2', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $this->provider->count('connection-1'));\n        $this->assertSame(1, $this->provider->count('connection-2'));\n\n        $this->provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(2, $this->provider->count('connection-1'));\n        $this->assertSame(1, $this->provider->count('connection-2'));\n    }\n\n    public function testJobsCanBeCountedByQueue()\n    {\n        $this->provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('database', 'queue-2', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $this->provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $this->provider->count(queue: 'queue-2'));\n\n        $this->provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(2, $this->provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $this->provider->count(queue: 'queue-2'));\n    }\n\n    public function testJobsCanBeCountedByQueueAndConnection()\n    {\n        $this->provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-2', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n\n        $this->assertSame(2, $this->provider->count('connection-1', 'queue-99'));\n        $this->assertSame(1, $this->provider->count('connection-2', 'queue-99'));\n        $this->assertSame(1, $this->provider->count('connection-1', 'queue-1'));\n        $this->assertSame(2, $this->provider->count('connection-2', 'queue-1'));\n    }\n\n    protected function createSimpleDatabaseWithFailedJobTable()\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {\n            $table->id();\n            $table->timestamp('failed_at')->useCurrent();\n        });\n\n        return $db;\n    }\n\n    protected function createDatabaseWithFailedJobTable()\n    {\n        $this->db = new DB;\n        $this->db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $this->db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {\n            $table->id();\n            $table->text('connection');\n            $table->text('queue');\n            $table->longText('payload');\n            $table->longText('exception');\n            $table->timestamp('failed_at')->useCurrent();\n        });\n\n        return $this;\n    }\n\n    protected function createProvider(string $database = 'default', string $table = 'failed_jobs')\n    {\n        $this->provider = new DatabaseFailedJobProvider($this->db->getDatabaseManager(), $database, $table);\n\n        return $this;\n    }\n\n    protected function failedJobsTable()\n    {\n        return $this->db->getConnection()->table('failed_jobs');\n    }\n\n    protected function createFailedJobsRecord(array $overrides = [])\n    {\n        return $this->failedJobsTable()\n            ->insert(array_merge([\n                'connection' => 'database',\n                'queue' => 'default',\n                'payload' => json_encode(['uuid' => (string) Str::uuid()]),\n                'exception' => new Exception('Whoops!'),\n                'failed_at' => Date::now()->subDays(10),\n            ], $overrides));\n    }\n}\n"
  },
  {
    "path": "tests/Queue/DatabaseUuidFailedJobProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Queue\\Failed\\DatabaseUuidFailedJobProvider;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass DatabaseUuidFailedJobProviderTest extends TestCase\n{\n    public function testGettingIdsOfAllFailedJobs()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-2']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-3']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-4']), new RuntimeException());\n\n        $this->assertSame(['uuid-1', 'uuid-2', 'uuid-3', 'uuid-4'], $provider->ids());\n        $this->assertSame(['uuid-1', 'uuid-2'], $provider->ids('queue-1'));\n        $this->assertSame(['uuid-3', 'uuid-4'], $provider->ids('queue-2'));\n    }\n\n    public function testGettingAllFailedJobs()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $this->assertEmpty($provider->all());\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-2']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-3']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-4']), new RuntimeException());\n\n        $this->assertCount(4, $provider->all());\n\n        $this->assertSame(\n            ['uuid-1', 'uuid-2', 'uuid-3', 'uuid-4'],\n            array_column($provider->all(), 'id')\n        );\n    }\n\n    public function testFindingFailedJobsById()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n\n        $this->assertNull($provider->find('uuid-2'));\n        $this->assertEquals('uuid-1', $provider->find('uuid-1')->id);\n        $this->assertEquals('queue-1', $provider->find('uuid-1')->queue);\n        $this->assertEquals('connection-1', $provider->find('uuid-1')->connection);\n    }\n\n    public function testRemovingJobsById()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n\n        $this->assertNotNull($provider->find('uuid-1'));\n\n        $provider->forget('uuid-1');\n\n        $this->assertNull($provider->find('uuid-1'));\n    }\n\n    public function testRemovingAllFailedJobs()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-2']), new RuntimeException());\n\n        $this->assertCount(2, $provider->all());\n\n        $provider->flush();\n\n        $this->assertEmpty($provider->all());\n    }\n\n    public function testPruningFailedJobs()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        Carbon::setTestNow(Carbon::createFromDate(2024, 4, 28));\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-2']), new RuntimeException());\n\n        $provider->prune(Carbon::createFromDate(2024, 4, 26));\n\n        $this->assertCount(2, $provider->all());\n\n        $provider->prune(Carbon::createFromDate(2024, 4, 30));\n\n        $this->assertEmpty($provider->all());\n    }\n\n    public function testPruningFailedJobsWithRelativeHoursAndMinutes()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        Carbon::setTestNow(Carbon::create(2025, 8, 24, 12, 30, 0));\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => 'uuid-1']), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => 'uuid-2']), new RuntimeException());\n\n        $provider->prune(Carbon::create(2025, 8, 24, 12, 30, 0));\n\n        $this->assertCount(2, $provider->all());\n\n        $provider->prune(Carbon::create(2025, 8, 24, 13, 0, 0));\n\n        $this->assertEmpty($provider->all());\n    }\n\n    public function testJobsCanBeCounted()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $this->assertSame(0, $provider->count());\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $provider->count());\n\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-2', 'queue-2', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(3, $provider->count());\n    }\n\n    public function testJobsCanBeCountedByConnection()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-2', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $provider->count('connection-1'));\n        $this->assertSame(1, $provider->count('connection-2'));\n\n        $provider->log('connection-1', 'default', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(2, $provider->count('connection-1'));\n        $this->assertSame(1, $provider->count('connection-2'));\n    }\n\n    public function testJobsCanBeCountedByQueue()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('database', 'queue-2', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(1, $provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $provider->count(queue: 'queue-2'));\n\n        $provider->log('database', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(2, $provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $provider->count(queue: 'queue-2'));\n    }\n\n    public function testJobsCanBeCountedByQueueAndConnection()\n    {\n        $provider = $this->getFailedJobProvider();\n\n        $provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-1', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-2', 'queue-99', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-1', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $provider->log('connection-2', 'queue-1', json_encode(['uuid' => (string) Str::uuid()]), new RuntimeException());\n        $this->assertSame(2, $provider->count('connection-1', 'queue-99'));\n        $this->assertSame(1, $provider->count('connection-2', 'queue-99'));\n        $this->assertSame(1, $provider->count('connection-1', 'queue-1'));\n        $this->assertSame(2, $provider->count('connection-2', 'queue-1'));\n    }\n\n    protected function getFailedJobProvider(string $database = 'default', string $table = 'failed_jobs')\n    {\n        $db = new DB;\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n        $db->getConnection()->getSchemaBuilder()->create('failed_jobs', function (Blueprint $table) {\n            $table->uuid();\n            $table->text('connection');\n            $table->text('queue');\n            $table->longText('payload');\n            $table->longText('exception');\n            $table->timestamp('failed_at')->useCurrent();\n        });\n\n        return new DatabaseUuidFailedJobProvider($db->getDatabaseManager(), $database, $table);\n    }\n}\n"
  },
  {
    "path": "tests/Queue/DynamoDbFailedJobProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Aws\\DynamoDb\\DynamoDbClient;\nuse Carbon\\CarbonImmutable;\nuse DateTimeInterface;\nuse Exception;\nuse Illuminate\\Queue\\Failed\\DynamoDbFailedJobProvider;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DynamoDbFailedJobProviderTest extends TestCase\n{\n    public function testCanProperlyLogFailedJob()\n    {\n        $uuid = Str::orderedUuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $now = CarbonImmutable::now();\n\n        $exception = new Exception('Something went wrong.');\n\n        $dynamoDbClient = m::mock(DynamoDbClient::class);\n\n        $dynamoDbClient->shouldReceive('putItem')->once()->with([\n            'TableName' => 'table',\n            'Item' => [\n                'application' => ['S' => 'application'],\n                'uuid' => ['S' => (string) $uuid],\n                'connection' => ['S' => 'connection'],\n                'queue' => ['S' => 'queue'],\n                'payload' => ['S' => json_encode(['uuid' => (string) $uuid])],\n                'exception' => ['S' => (string) $exception],\n                'failed_at' => ['N' => (string) $now->getTimestamp()],\n                'expires_at' => ['N' => (string) $now->addDays(7)->getTimestamp()],\n            ],\n        ]);\n\n        $provider = new DynamoDbFailedJobProvider($dynamoDbClient, 'application', 'table');\n\n        $provider->log('connection', 'queue', json_encode(['uuid' => (string) $uuid]), $exception);\n\n        Str::createUuidsNormally();\n    }\n\n    public function testCanRetrieveAllFailedJobs()\n    {\n        $dynamoDbClient = m::mock(DynamoDbClient::class);\n\n        $time = time();\n\n        $dynamoDbClient->shouldReceive('query')->once()->with([\n            'TableName' => 'table',\n            'Select' => 'ALL_ATTRIBUTES',\n            'KeyConditionExpression' => 'application = :application',\n            'ExpressionAttributeValues' => [\n                ':application' => ['S' => 'application'],\n            ],\n            'ScanIndexForward' => false,\n        ])->andReturn([\n            'Items' => [\n                [\n                    'application' => ['S' => 'application'],\n                    'uuid' => ['S' => 'uuid'],\n                    'connection' => ['S' => 'connection'],\n                    'queue' => ['S' => 'queue'],\n                    'payload' => ['S' => 'payload'],\n                    'exception' => ['S' => 'exception'],\n                    'failed_at' => ['N' => (string) $time],\n                    'expires_at' => ['N' => (string) $time],\n                ],\n            ],\n        ]);\n\n        $provider = new DynamoDbFailedJobProvider($dynamoDbClient, 'application', 'table');\n\n        $response = $provider->all();\n\n        $this->assertEquals([\n            (object) [\n                'id' => 'uuid',\n                'connection' => 'connection',\n                'queue' => 'queue',\n                'payload' => 'payload',\n                'exception' => 'exception',\n                'failed_at' => Carbon::createFromTimestamp($time)->format(DateTimeInterface::ISO8601),\n            ],\n        ], $response);\n    }\n\n    public function testASingleJobCanBeFound()\n    {\n        $dynamoDbClient = m::mock(DynamoDbClient::class);\n\n        $time = time();\n\n        $dynamoDbClient->shouldReceive('getItem')->once()->with([\n            'TableName' => 'table',\n            'Key' => [\n                'application' => ['S' => 'application'],\n                'uuid' => ['S' => 'id'],\n            ],\n        ])->andReturn([\n            'Item' => [\n                'application' => ['S' => 'application'],\n                'uuid' => ['S' => 'uuid'],\n                'connection' => ['S' => 'connection'],\n                'queue' => ['S' => 'queue'],\n                'payload' => ['S' => 'payload'],\n                'exception' => ['S' => 'exception'],\n                'failed_at' => ['N' => (string) $time],\n                'expires_at' => ['N' => (string) $time],\n            ],\n        ]);\n\n        $provider = new DynamoDbFailedJobProvider($dynamoDbClient, 'application', 'table');\n\n        $response = $provider->find('id');\n\n        $this->assertEquals(\n            (object) [\n                'id' => 'uuid',\n                'connection' => 'connection',\n                'queue' => 'queue',\n                'payload' => 'payload',\n                'exception' => 'exception',\n                'failed_at' => Carbon::createFromTimestamp($time)->format(DateTimeInterface::ISO8601),\n            ], $response\n        );\n    }\n\n    public function testNullIsReturnedIfJobNotFound()\n    {\n        $dynamoDbClient = m::mock(DynamoDbClient::class);\n\n        $dynamoDbClient->shouldReceive('getItem')->once()->with([\n            'TableName' => 'table',\n            'Key' => [\n                'application' => ['S' => 'application'],\n                'uuid' => ['S' => 'id'],\n            ],\n        ])->andReturn([]);\n\n        $provider = new DynamoDbFailedJobProvider($dynamoDbClient, 'application', 'table');\n\n        $response = $provider->find('id');\n\n        $this->assertNull($response);\n    }\n\n    public function testJobsCanBeDeleted()\n    {\n        $dynamoDbClient = m::mock(DynamoDbClient::class);\n\n        $dynamoDbClient->shouldReceive('deleteItem')->once()->with([\n            'TableName' => 'table',\n            'Key' => [\n                'application' => ['S' => 'application'],\n                'uuid' => ['S' => 'id'],\n            ],\n        ])->andReturn([]);\n\n        $provider = new DynamoDbFailedJobProvider($dynamoDbClient, 'application', 'table');\n\n        $provider->forget('id');\n    }\n}\n"
  },
  {
    "path": "tests/Queue/FailOnExceptionMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Bus\\Dispatchable;\nuse Illuminate\\Queue\\CallQueuedHandler;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Jobs\\FakeJob;\nuse Illuminate\\Queue\\Middleware\\FailOnException;\nuse InvalidArgumentException;\nuse LogicException;\nuse Orchestra\\Testbench\\TestCase;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse Throwable;\n\nclass FailOnExceptionMiddlewareTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n        FailOnExceptionMiddlewareTestJob::$_middleware = [];\n    }\n\n    /**\n     * @return array<string, array{class-string<\\Throwable>, FailOnException, bool}>\n     */\n    public static function middlewareDataProvider(): array\n    {\n        return [\n            'exception is in list' => [\n                InvalidArgumentException::class,\n                new FailOnException([InvalidArgumentException::class]),\n                true,\n            ],\n            'exception is not in list' => [\n                LogicException::class,\n                new FailOnException([InvalidArgumentException::class]),\n                false,\n            ],\n        ];\n    }\n\n    #[DataProvider('middlewareDataProvider')]\n    public function test_middleware(\n        string $thrown,\n        FailOnException $middleware,\n        bool $expectedToFail\n    ): void {\n        FailOnExceptionMiddlewareTestJob::$_middleware = [$middleware];\n        $job = new FailOnExceptionMiddlewareTestJob($thrown);\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $fakeJob = new FakeJob();\n        $job->setJob($fakeJob);\n\n        try {\n            $instance->call($fakeJob, [\n                'command' => serialize($job),\n            ]);\n            $this->fail('Did not throw exception');\n        } catch (Throwable $e) {\n            $this->assertInstanceOf($thrown, $e);\n        }\n\n        $expectedToFail ? $job->assertFailed() : $job->assertNotFailed();\n    }\n\n    #[TestWith(['abc', true])]\n    #[TestWith(['tots', false])]\n    public function test_can_test_against_job_properties($value, bool $expectedToFail): void\n    {\n        FailOnExceptionMiddlewareTestJob::$_middleware = [\n            new FailOnException(fn ($thrown, $job) => $job->value === 'abc'),\n        ];\n\n        $job = new FailOnExceptionMiddlewareTestJob(InvalidArgumentException::class, $value);\n        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);\n\n        $fakeJob = new FakeJob();\n        $job->setJob($fakeJob);\n\n        try {\n            $instance->call($fakeJob, [\n                'command' => serialize($job),\n            ]);\n            $this->fail('Did not throw exception');\n        } catch (Throwable) {\n            //\n        }\n\n        $expectedToFail ? $job->assertFailed() : $job->assertNotFailed();\n    }\n}\n\nclass FailOnExceptionMiddlewareTestJob implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable;\n\n    public static array $_middleware = [];\n\n    public int $tries = 2;\n\n    public function __construct(private $throws, public $value = null)\n    {\n    }\n\n    public function handle()\n    {\n        throw new $this->throws;\n    }\n\n    public function middleware(): array\n    {\n        return self::$_middleware;\n    }\n}\n"
  },
  {
    "path": "tests/Queue/FailoverQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Queue\\FailoverQueue;\nuse Illuminate\\Queue\\QueueManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FailoverQueueTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function test_push_fails_over_on_exception()\n    {\n        $failover = new FailoverQueue($queue = m::mock(QueueManager::class), $events = m::mock(Dispatcher::class), [\n            'redis',\n            'sync',\n        ]);\n\n        $queue->shouldReceive('connection')->once()->with('redis')->andReturn(\n            $redis = m::mock('stdClass'),\n        );\n\n        $queue->shouldReceive('connection')->once()->with('sync')->andReturn(\n            $sync = m::mock('stdClass'),\n        );\n\n        $events->shouldReceive('dispatch')->once();\n\n        $redis->shouldReceive('push')->once()->andReturnUsing(\n            fn () => throw new \\Exception('error')\n        );\n\n        $sync->shouldReceive('push')->once();\n\n        $failover->push('some-job');\n    }\n}\n"
  },
  {
    "path": "tests/Queue/FileFailedJobProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Queue\\Failed\\FileFailedJobProvider;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\n\nclass FileFailedJobProviderTest extends TestCase\n{\n    protected $path;\n\n    protected $provider;\n\n    protected function setUp(): void\n    {\n        $this->path = @tempnam('tmp', 'file_failed_job_provider_test');\n        $this->provider = new FileFailedJobProvider($this->path);\n    }\n\n    public function testCanLogFailedJobs()\n    {\n        [$uuid, $exception] = $this->logFailedJob();\n\n        $failedJobs = $this->provider->all();\n\n        $this->assertEquals([\n            (object) [\n                'id' => $uuid,\n                'connection' => 'connection',\n                'queue' => 'queue',\n                'payload' => json_encode(['uuid' => $uuid]),\n                'exception' => (string) mb_convert_encoding($exception, 'UTF-8'),\n                'failed_at' => $failedJobs[0]->failed_at,\n                'failed_at_timestamp' => $failedJobs[0]->failed_at_timestamp,\n            ],\n        ], $failedJobs);\n    }\n\n    public function testCanRetrieveAllFailedJobs()\n    {\n        try {\n            Carbon::setTestNow(Carbon::now());\n\n            [$uuidOne, $exceptionOne] = $this->logFailedJob();\n            [$uuidTwo, $exceptionTwo] = $this->logFailedJob();\n\n            $failedJobs = $this->provider->all();\n\n            $this->assertEquals([\n                (object) [\n                    'id' => $uuidTwo,\n                    'connection' => 'connection',\n                    'queue' => 'queue',\n                    'payload' => json_encode(['uuid' => $uuidTwo]),\n                    'exception' => (string) mb_convert_encoding($exceptionTwo, 'UTF-8'),\n                    'failed_at' => $failedJobs[1]->failed_at,\n                    'failed_at_timestamp' => $failedJobs[1]->failed_at_timestamp,\n                ],\n                (object) [\n                    'id' => $uuidOne,\n                    'connection' => 'connection',\n                    'queue' => 'queue',\n                    'payload' => json_encode(['uuid' => $uuidOne]),\n                    'exception' => (string) mb_convert_encoding($exceptionOne, 'UTF-8'),\n                    'failed_at' => $failedJobs[0]->failed_at,\n                    'failed_at_timestamp' => $failedJobs[0]->failed_at_timestamp,\n                ],\n            ], $failedJobs);\n        } finally {\n            Carbon::setTestNow();\n        }\n    }\n\n    public function testCanFindFailedJobs()\n    {\n        [$uuid, $exception] = $this->logFailedJob();\n\n        $failedJob = $this->provider->find($uuid);\n\n        $this->assertEquals((object) [\n            'id' => $uuid,\n            'connection' => 'connection',\n            'queue' => 'queue',\n            'payload' => json_encode(['uuid' => (string) $uuid]),\n            'exception' => (string) mb_convert_encoding($exception, 'UTF-8'),\n            'failed_at' => $failedJob->failed_at,\n            'failed_at_timestamp' => $failedJob->failed_at_timestamp,\n        ], $failedJob);\n    }\n\n    public function testNullIsReturnedIfJobNotFound()\n    {\n        $uuid = Str::uuid();\n\n        $failedJob = $this->provider->find($uuid);\n\n        $this->assertNull($failedJob);\n    }\n\n    public function testCanForgetFailedJobs()\n    {\n        [$uuid] = $this->logFailedJob();\n\n        $this->provider->forget($uuid);\n\n        $failedJob = $this->provider->find($uuid);\n\n        $this->assertNull($failedJob);\n    }\n\n    public function testCanFlushFailedJobs()\n    {\n        $this->logFailedJob();\n        $this->logFailedJob();\n\n        $this->provider->flush();\n\n        $failedJobs = $this->provider->all();\n\n        $this->assertEmpty($failedJobs);\n    }\n\n    public function testCanPruneFailedJobs()\n    {\n        $this->logFailedJob();\n        $this->logFailedJob();\n\n        $this->provider->prune(Carbon::now()->addDay(1));\n        $failedJobs = $this->provider->all();\n        $this->assertEmpty($failedJobs);\n\n        $this->logFailedJob();\n        $this->logFailedJob();\n\n        $this->provider->prune(Carbon::now()->subDay(1));\n        $failedJobs = $this->provider->all();\n        $this->assertCount(2, $failedJobs);\n    }\n\n    public function testCanPruneFailedJobsWithRelativeHours()\n    {\n        $this->logFailedJob();\n        $this->logFailedJob();\n\n        $this->provider->prune(Carbon::now()->addHour(1));\n        $failedJobs = $this->provider->all();\n        $this->assertEmpty($failedJobs);\n\n        $this->logFailedJob();\n        $this->logFailedJob();\n\n        $this->provider->prune(Carbon::now()->subHour(1));\n        $failedJobs = $this->provider->all();\n        $this->assertCount(2, $failedJobs);\n    }\n\n    public function testEmptyFailedJobsByDefault()\n    {\n        $failedJobs = $this->provider->all();\n\n        $this->assertEmpty($failedJobs);\n    }\n\n    public function testJobsCanBeCounted()\n    {\n        $this->assertSame(0, $this->provider->count());\n\n        $this->logFailedJob('database', 'default');\n        $this->assertSame(1, $this->provider->count());\n\n        $this->logFailedJob('database', 'default');\n        $this->logFailedJob('another-connection', 'another-queue');\n        $this->assertSame(3, $this->provider->count());\n    }\n\n    public function testJobsCanBeCountedByConnection()\n    {\n        $this->logFailedJob('connection-1', 'default');\n        $this->logFailedJob('connection-2', 'default');\n        $this->assertSame(1, $this->provider->count('connection-1'));\n        $this->assertSame(1, $this->provider->count('connection-2'));\n\n        $this->logFailedJob('connection-1', 'default');\n        $this->assertSame(2, $this->provider->count('connection-1'));\n        $this->assertSame(1, $this->provider->count('connection-2'));\n    }\n\n    public function testJobsCanBeCountedByQueue()\n    {\n        $this->logFailedJob('database', 'queue-1');\n        $this->logFailedJob('database', 'queue-2');\n        $this->assertSame(1, $this->provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $this->provider->count(queue: 'queue-2'));\n\n        $this->logFailedJob('database', 'queue-1');\n        $this->assertSame(2, $this->provider->count(queue: 'queue-1'));\n        $this->assertSame(1, $this->provider->count(queue: 'queue-2'));\n    }\n\n    public function testJobsCanBeCountedByQueueAndConnection()\n    {\n        $this->logFailedJob('connection-1', 'queue-99');\n        $this->logFailedJob('connection-1', 'queue-99');\n        $this->logFailedJob('connection-2', 'queue-99');\n        $this->logFailedJob('connection-1', 'queue-1');\n        $this->logFailedJob('connection-2', 'queue-1');\n        $this->logFailedJob('connection-2', 'queue-1');\n        $this->assertSame(2, $this->provider->count('connection-1', 'queue-99'));\n        $this->assertSame(1, $this->provider->count('connection-2', 'queue-99'));\n        $this->assertSame(1, $this->provider->count('connection-1', 'queue-1'));\n        $this->assertSame(2, $this->provider->count('connection-2', 'queue-1'));\n    }\n\n    public function logFailedJob($connection = 'connection', $queue = 'queue')\n    {\n        $uuid = Str::uuid();\n\n        $exception = new Exception(\"Something went wrong at job [{$uuid}].\");\n\n        $this->provider->log($connection, $queue, json_encode(['uuid' => (string) $uuid]), $exception);\n\n        return [(string) $uuid, $exception];\n    }\n}\n"
  },
  {
    "path": "tests/Queue/Fixtures/FakeSqsJob.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue\\Fixtures;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass FakeSqsJob implements ShouldQueue\n{\n    use Queueable;\n\n    public function handle(): void\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Queue/Fixtures/FakeSqsJobWithDeduplication.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue\\Fixtures;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass FakeSqsJobWithDeduplication implements ShouldQueue\n{\n    use Queueable;\n\n    protected static $deduplicationIdFactory;\n\n    public function handle(): void\n    {\n        //\n    }\n\n    /**\n     * Deduplication ID method called by SqsQueue.\n     *\n     * @param  string  $payload\n     * @param  string  $queue\n     * @return string\n     */\n    public function deduplicationId($payload, $queue): string\n    {\n        return static::$deduplicationIdFactory\n            ? (string) call_user_func(static::$deduplicationIdFactory, $payload, $queue)\n            : hash('sha256', json_encode(func_get_args()));\n    }\n\n    /**\n     * Set the callable that will be used to generate deduplication IDs.\n     *\n     * @param  callable|null  $factory\n     * @return void\n     */\n    public static function createDeduplicationIdsUsing(?callable $factory = null)\n    {\n        static::$deduplicationIdFactory = $factory;\n    }\n\n    /**\n     * Indicate that deduplication IDs should be created normally and not using a custom factory.\n     *\n     * @return void\n     */\n    public static function createDeduplicationIdsNormally()\n    {\n        static::$deduplicationIdFactory = null;\n    }\n}\n"
  },
  {
    "path": "tests/Queue/Fixtures/FakeSqsJobWithMessageGroup.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue\\Fixtures;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass FakeSqsJobWithMessageGroup implements ShouldQueue\n{\n    use Queueable;\n\n    public function handle(): void\n    {\n        //\n    }\n\n    /**\n     * Message group method called by SqsQueue.\n     *\n     * @return string\n     */\n    public function messageGroup(): string\n    {\n        return 'group-1';\n    }\n}\n"
  },
  {
    "path": "tests/Queue/InteractsWithQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Contracts\\Queue\\Job;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass InteractsWithQueueTest extends TestCase\n{\n    public function testCreatesAnExceptionFromString()\n    {\n        $queueJob = m::mock(Job::class);\n        $queueJob->shouldReceive('fail')->withArgs(function ($e) {\n            $this->assertInstanceOf(Exception::class, $e);\n            $this->assertEquals('Whoops!', $e->getMessage());\n\n            return true;\n        });\n\n        $job = new class\n        {\n            use InteractsWithQueue;\n\n            public $job;\n        };\n\n        $job->job = $queueJob;\n        $job->fail('Whoops!');\n    }\n}\n"
  },
  {
    "path": "tests/Queue/PruneBatchesCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\BatchRepository;\nuse Illuminate\\Bus\\DatabaseBatchRepository;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Queue\\Console\\PruneBatchesCommand;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Input\\ArrayInput;\nuse Symfony\\Component\\Console\\Output\\NullOutput;\n\nclass PruneBatchesCommandTest extends TestCase\n{\n    public function testAllowPruningAllUnfinishedBatches()\n    {\n        $container = new Application;\n        $container->instance(BatchRepository::class, $repo = m::spy(DatabaseBatchRepository::class));\n\n        $command = new PruneBatchesCommand;\n        $command->setLaravel($container);\n\n        $command->run(new ArrayInput(['--unfinished' => 0]), new NullOutput());\n\n        $repo->shouldHaveReceived('pruneUnfinished')->once();\n    }\n\n    public function testAllowPruningAllCancelledBatches()\n    {\n        $container = new Application;\n        $container->instance(BatchRepository::class, $repo = m::spy(DatabaseBatchRepository::class));\n\n        $command = new PruneBatchesCommand;\n        $command->setLaravel($container);\n\n        $command->run(new ArrayInput(['--cancelled' => 0]), new NullOutput());\n\n        $repo->shouldHaveReceived('pruneCancelled')->once();\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueBeanstalkdJobTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Queue\\Events\\JobFailed;\nuse Illuminate\\Queue\\Jobs\\BeanstalkdJob;\nuse Illuminate\\Queue\\Jobs\\Job;\nuse Mockery as m;\nuse Pheanstalk\\Contract\\JobIdInterface;\nuse Pheanstalk\\Contract\\PheanstalkManagerInterface;\nuse Pheanstalk\\Contract\\PheanstalkPublisherInterface;\nuse Pheanstalk\\Contract\\PheanstalkSubscriberInterface;\nuse Pheanstalk\\Pheanstalk;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass QueueBeanstalkdJobTest extends TestCase\n{\n    public function testFireProperlyCallsTheJobHandler()\n    {\n        $job = $this->getJob();\n        $job->getPheanstalkJob()->shouldReceive('getData')->once()->andReturn(json_encode(['job' => 'foo', 'data' => ['data']]));\n        $job->getContainer()->shouldReceive('make')->once()->with('foo')->andReturn($handler = m::mock(stdClass::class));\n        $handler->shouldReceive('fire')->once()->with($job, ['data']);\n\n        $job->fire();\n    }\n\n    public function testFailProperlyCallsTheJobHandler()\n    {\n        $job = $this->getJob();\n        $job->getPheanstalkJob()->shouldReceive('getData')->andReturn(json_encode(['job' => 'foo', 'uuid' => 'test-uuid', 'data' => ['data']]));\n        $job->getContainer()->shouldReceive('make')->once()->with('foo')->andReturn($handler = m::mock(BeanstalkdJobTestFailedTest::class));\n        $job->getPheanstalk()->shouldReceive('delete')->once()->with($job->getPheanstalkJob())->andReturnSelf();\n        $handler->shouldReceive('failed')->once()->with(['data'], m::type(Exception::class), 'test-uuid', m::type(Job::class));\n        $job->getContainer()->shouldReceive('make')->once()->with(Dispatcher::class)->andReturn($events = m::mock(Dispatcher::class));\n        $events->shouldReceive('dispatch')->once()->with(m::type(JobFailed::class))->andReturnNull();\n\n        $job->fail(new Exception);\n    }\n\n    public function testDeleteRemovesTheJobFromBeanstalkd()\n    {\n        $job = $this->getJob();\n        $job->getPheanstalk()->shouldReceive('delete')->once()->with($job->getPheanstalkJob());\n\n        $job->delete();\n    }\n\n    public function testReleaseProperlyReleasesJobOntoBeanstalkd()\n    {\n        $job = $this->getJob();\n        $job->getPheanstalk()->shouldReceive('release')->once()->with($job->getPheanstalkJob(), Pheanstalk::DEFAULT_PRIORITY, 0);\n\n        $job->release();\n    }\n\n    public function testBuryProperlyBuryTheJobFromBeanstalkd()\n    {\n        $job = $this->getJob();\n        $job->getPheanstalk()->shouldReceive('bury')->once()->with($job->getPheanstalkJob());\n\n        $job->bury();\n    }\n\n    protected function getJob()\n    {\n        return new BeanstalkdJob(\n            m::mock(Container::class),\n            m::mock(implode(',', [PheanstalkManagerInterface::class, PheanstalkPublisherInterface::class, PheanstalkSubscriberInterface::class])),\n            m::mock(JobIdInterface::class),\n            'connection-name',\n            'default'\n        );\n    }\n}\n\nclass BeanstalkdJobTestFailedTest\n{\n    public function failed(array $data)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueBeanstalkdQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Queue\\BeanstalkdQueue;\nuse Illuminate\\Queue\\Jobs\\BeanstalkdJob;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse Pheanstalk\\Contract\\JobIdInterface;\nuse Pheanstalk\\Contract\\PheanstalkManagerInterface;\nuse Pheanstalk\\Contract\\PheanstalkPublisherInterface;\nuse Pheanstalk\\Contract\\PheanstalkSubscriberInterface;\nuse Pheanstalk\\Pheanstalk;\nuse Pheanstalk\\Values\\Job;\nuse Pheanstalk\\Values\\TubeList;\nuse Pheanstalk\\Values\\TubeName;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueBeanstalkdQueueTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Queue\\BeanstalkdQueue\n     */\n    private $queue;\n\n    /**\n     * @var \\Illuminate\\Container\\Container|\\Mockery\\LegacyMockInterface|\\Mockery\\MockInterface\n     */\n    private $container;\n\n    public function testPushProperlyPushesJobOntoBeanstalkd()\n    {\n        $uuid = Str::uuid();\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $this->setQueue('default', 60);\n        $pheanstalk = $this->queue->getPheanstalk();\n        $pheanstalk->shouldReceive('useTube')->once()->with(m::type(TubeName::class));\n        $pheanstalk->shouldReceive('useTube')->once()->with(m::type(TubeName::class));\n        $pheanstalk->shouldReceive('put')->twice()->with(json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'delay' => null]), 1024, 0, 60);\n\n        $this->queue->push('foo', ['data'], 'stack');\n        $this->queue->push('foo', ['data']);\n\n        $this->container->shouldHaveReceived('bound')->with('events')->times(4);\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testDelayedPushProperlyPushesJobOntoBeanstalkd()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $this->setQueue('default', 60);\n        $pheanstalk = $this->queue->getPheanstalk();\n        $pheanstalk->shouldReceive('useTube')->once()->with(m::type(TubeName::class));\n        $pheanstalk->shouldReceive('useTube')->once()->with(m::type(TubeName::class));\n        $pheanstalk->shouldReceive('put')->twice()->with(json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'delay' => 5]), Pheanstalk::DEFAULT_PRIORITY, 5, Pheanstalk::DEFAULT_TTR);\n\n        $this->queue->later(5, 'foo', ['data'], 'stack');\n        $this->queue->later(5, 'foo', ['data']);\n\n        $this->container->shouldHaveReceived('bound')->with('events')->times(4);\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testPopProperlyPopsJobOffOfBeanstalkd()\n    {\n        $this->setQueue('default', 60);\n        $tube = new TubeName('default');\n\n        $pheanstalk = $this->queue->getPheanstalk();\n        $pheanstalk->shouldReceive('watch')->once()->with(m::type(TubeName::class))\n            ->shouldReceive('listTubesWatched')->once()->andReturn(new TubeList($tube));\n\n        $jobId = m::mock(JobIdInterface::class);\n        $jobId->shouldReceive('getId')->once();\n        $job = new Job($jobId, '');\n        $pheanstalk->shouldReceive('reserveWithTimeout')->once()->with(0)->andReturn($job);\n\n        $result = $this->queue->pop();\n\n        $this->assertInstanceOf(BeanstalkdJob::class, $result);\n    }\n\n    public function testBlockingPopProperlyPopsJobOffOfBeanstalkd()\n    {\n        $this->setQueue('default', 60, 60);\n        $tube = new TubeName('default');\n\n        $pheanstalk = $this->queue->getPheanstalk();\n        $pheanstalk->shouldReceive('watch')->once()->with(m::type(TubeName::class))\n            ->shouldReceive('listTubesWatched')->once()->andReturn(new TubeList($tube));\n\n        $jobId = m::mock(JobIdInterface::class);\n        $jobId->shouldReceive('getId')->once();\n        $job = new Job($jobId, '');\n        $pheanstalk->shouldReceive('reserveWithTimeout')->once()->with(60)->andReturn($job);\n\n        $result = $this->queue->pop();\n\n        $this->assertInstanceOf(BeanstalkdJob::class, $result);\n    }\n\n    public function testDeleteProperlyRemoveJobsOffBeanstalkd()\n    {\n        $this->setQueue('default', 60);\n\n        $pheanstalk = $this->queue->getPheanstalk();\n        $pheanstalk->shouldReceive('useTube')->once()->with(m::type(TubeName::class))->andReturn($pheanstalk);\n        $pheanstalk->shouldReceive('delete')->once()->with(m::type(JobIdInterface::class));\n\n        $this->queue->deleteMessage('default', 1);\n    }\n\n    /**\n     * @param  string  $default\n     * @param  int  $timeToRun\n     * @param  int  $blockFor\n     */\n    private function setQueue($default, $timeToRun, $blockFor = 0)\n    {\n        $this->queue = new BeanstalkdQueue(\n            m::mock(implode(',', [PheanstalkManagerInterface::class, PheanstalkPublisherInterface::class, PheanstalkSubscriberInterface::class])),\n            $default,\n            $timeToRun,\n            $blockFor\n        );\n        $this->container = m::spy(Container::class);\n        $this->queue->setContainer($this->container);\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueDatabaseQueueIntegrationTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Capsule\\Manager as DB;\nuse Illuminate\\Database\\Eloquent\\Model as Eloquent;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Queue\\DatabaseQueue;\nuse Illuminate\\Queue\\Events\\JobQueued;\nuse Illuminate\\Queue\\Events\\JobQueueing;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueDatabaseQueueIntegrationTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Queue\\DatabaseQueue\n     */\n    protected $queue;\n\n    /**\n     * @var string The jobs table name.\n     */\n    protected $table;\n\n    /**\n     * @var \\Illuminate\\Container\\Container\n     */\n    protected $container;\n\n    protected function setUp(): void\n    {\n        $db = new DB;\n\n        $db->addConnection([\n            'driver' => 'sqlite',\n            'database' => ':memory:',\n        ]);\n\n        $db->bootEloquent();\n\n        $db->setAsGlobal();\n\n        $this->table = 'jobs';\n\n        $this->queue = new DatabaseQueue($this->connection(), $this->table);\n\n        $this->container = new Container;\n\n        $this->container->instance('events', new Dispatcher($this->container));\n\n        $this->queue->setContainer($this->container);\n\n        $this->createSchema();\n    }\n\n    /**\n     * Setup the database schema.\n     *\n     * @return void\n     */\n    public function createSchema()\n    {\n        $this->schema()->create($this->table, function (Blueprint $table) {\n            $table->bigIncrements('id');\n            $table->string('queue');\n            $table->longText('payload');\n            $table->tinyInteger('attempts')->unsigned();\n            $table->unsignedInteger('reserved_at')->nullable();\n            $table->unsignedInteger('available_at');\n            $table->unsignedInteger('created_at');\n            $table->index(['queue', 'reserved_at']);\n        });\n    }\n\n    /**\n     * Get a database connection instance.\n     *\n     * @return \\Illuminate\\Database\\Connection\n     */\n    protected function connection()\n    {\n        return Eloquent::getConnectionResolver()->connection();\n    }\n\n    /**\n     * Get a schema builder instance.\n     *\n     * @return \\Illuminate\\Database\\Schema\\Builder\n     */\n    protected function schema()\n    {\n        return $this->connection()->getSchemaBuilder();\n    }\n\n    /**\n     * Tear down the database schema.\n     *\n     * @return void\n     */\n    protected function tearDown(): void\n    {\n        $this->schema()->drop('jobs');\n\n        parent::tearDown();\n    }\n\n    /**\n     * Test that jobs that are not reserved and have an available_at value less then now, are popped.\n     */\n    public function testAvailableAndUnReservedJobsArePopped()\n    {\n        $this->connection()\n            ->table('jobs')\n            ->insert([\n                'id' => 1,\n                'queue' => $mock_queue_name = 'mock_queue_name',\n                'payload' => 'mock_payload',\n                'attempts' => 0,\n                'reserved_at' => null,\n                'available_at' => Carbon::now()->subSeconds(1)->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ]);\n\n        $popped_job = $this->queue->pop($mock_queue_name);\n\n        $this->assertNotNull($popped_job);\n    }\n\n    /**\n     * Test that when jobs are popped, the attempts attribute is incremented.\n     */\n    public function testPoppedJobsIncrementAttempts()\n    {\n        $job = [\n            'id' => 1,\n            'queue' => 'mock_queue_name',\n            'payload' => 'mock_payload',\n            'attempts' => 0,\n            'reserved_at' => null,\n            'available_at' => Carbon::now()->subSeconds(1)->getTimestamp(),\n            'created_at' => Carbon::now()->getTimestamp(),\n        ];\n\n        $this->connection()->table('jobs')->insert($job);\n\n        $popped_job = $this->queue->pop($job['queue']);\n\n        $database_record = $this->connection()->table('jobs')->find($job['id']);\n\n        $this->assertEquals(1, $database_record->attempts, 'Job attempts not updated in the database!');\n        $this->assertEquals(1, $popped_job->attempts(), 'The \"attempts\" attribute of the Job object was not updated by pop!');\n    }\n\n    /**\n     * Test that the queue can be cleared.\n     */\n    public function testThatQueueCanBeCleared()\n    {\n        $this->connection()\n            ->table('jobs')\n            ->insert([[\n                'id' => 1,\n                'queue' => $mock_queue_name = 'mock_queue_name',\n                'payload' => 'mock_payload',\n                'attempts' => 0,\n                'reserved_at' => Carbon::now()->addDay()->getTimestamp(),\n                'available_at' => Carbon::now()->subDay()->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ], [\n                'id' => 2,\n                'queue' => $mock_queue_name,\n                'payload' => 'mock_payload 2',\n                'attempts' => 0,\n                'reserved_at' => null,\n                'available_at' => Carbon::now()->subSeconds(1)->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ]]);\n\n        $this->assertEquals(2, $this->queue->clear($mock_queue_name));\n        $this->assertEquals(0, $this->queue->size());\n    }\n\n    /**\n     * Test that jobs that are not reserved and have an available_at value in the future, are not popped.\n     */\n    public function testUnavailableJobsAreNotPopped()\n    {\n        $this->connection()\n            ->table('jobs')\n            ->insert([\n                'id' => 1,\n                'queue' => $mock_queue_name = 'mock_queue_name',\n                'payload' => 'mock_payload',\n                'attempts' => 0,\n                'reserved_at' => null,\n                'available_at' => Carbon::now()->addSeconds(60)->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ]);\n\n        $popped_job = $this->queue->pop($mock_queue_name);\n\n        $this->assertNull($popped_job);\n    }\n\n    /**\n     * Test that jobs that are reserved and have expired are popped.\n     */\n    public function testThatReservedAndExpiredJobsArePopped()\n    {\n        $this->connection()\n            ->table('jobs')\n            ->insert([\n                'id' => 1,\n                'queue' => $mock_queue_name = 'mock_queue_name',\n                'payload' => 'mock_payload',\n                'attempts' => 0,\n                'reserved_at' => Carbon::now()->subDay()->getTimestamp(),\n                'available_at' => Carbon::now()->addDay()->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ]);\n\n        $popped_job = $this->queue->pop($mock_queue_name);\n\n        $this->assertNotNull($popped_job);\n    }\n\n    /**\n     * Test that jobs that are reserved and not expired and available are not popped.\n     */\n    public function testThatReservedJobsAreNotPopped()\n    {\n        $this->connection()\n            ->table('jobs')\n            ->insert([\n                'id' => 1,\n                'queue' => $mock_queue_name = 'mock_queue_name',\n                'payload' => 'mock_payload',\n                'attempts' => 0,\n                'reserved_at' => Carbon::now()->addDay()->getTimestamp(),\n                'available_at' => Carbon::now()->subDay()->getTimestamp(),\n                'created_at' => Carbon::now()->getTimestamp(),\n            ]);\n\n        $popped_job = $this->queue->pop($mock_queue_name);\n\n        $this->assertNull($popped_job);\n    }\n\n    public function testJobPayloadIsAvailableOnEvents()\n    {\n        $jobQueueingEvent = null;\n        $jobQueuedEvent = null;\n        Str::createUuidsUsingSequence([\n            'expected-job-uuid',\n        ]);\n        $this->container['events']->listen(function (JobQueueing $e) use (&$jobQueueingEvent) {\n            $jobQueueingEvent = $e;\n        });\n        $this->container['events']->listen(function (JobQueued $e) use (&$jobQueuedEvent) {\n            $jobQueuedEvent = $e;\n        });\n\n        $this->queue->push('MyJob', [\n            'laravel' => 'Framework',\n        ]);\n\n        $this->assertIsArray($jobQueueingEvent->payload());\n        $this->assertSame('expected-job-uuid', $jobQueueingEvent->payload()['uuid']);\n\n        $this->assertIsArray($jobQueuedEvent->payload());\n        $this->assertSame('expected-job-uuid', $jobQueuedEvent->payload()['uuid']);\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueDatabaseQueueUnitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\Batchable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Queue\\DatabaseQueue;\nuse Illuminate\\Queue\\Queue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\n\nclass QueueDatabaseQueueUnitTest extends TestCase\n{\n    #[DataProvider('pushJobsDataProvider')]\n    public function testPushProperlyPushesJobOntoDatabase($uuid, $job, $displayNameStartsWith, $jobStartsWith)\n    {\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $queue = $this->getMockBuilder(DatabaseQueue::class)->onlyMethods(['currentTime'])->setConstructorArgs([$database = m::mock(Connection::class), 'table', 'default'])->getMock();\n        $queue->expects($this->any())->method('currentTime')->willReturn('time');\n        $queue->setContainer($container = m::spy(Container::class));\n        $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('insertGetId')->once()->andReturnUsing(function ($array) use ($uuid, $displayNameStartsWith, $jobStartsWith) {\n            $payload = json_decode($array['payload'], true);\n            $this->assertSame($uuid, $payload['uuid']);\n            $this->assertStringContainsString($displayNameStartsWith, $payload['displayName']);\n            $this->assertStringContainsString($jobStartsWith, $payload['job']);\n\n            $this->assertSame('default', $array['queue']);\n            $this->assertEquals(0, $array['attempts']);\n            $this->assertNull($array['reserved_at']);\n            $this->assertIsInt($array['available_at']);\n        });\n\n        $queue->push($job, ['data']);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public static function pushJobsDataProvider()\n    {\n        $uuid = Str::uuid()->toString();\n\n        return [\n            [$uuid, new MyTestJob, 'MyTestJob', 'CallQueuedHandler'],\n            [$uuid, fn () => 0, 'Closure', 'CallQueuedHandler'],\n            [$uuid, 'foo', 'foo', 'foo'],\n        ];\n    }\n\n    public function testDelayedPushProperlyPushesJobOntoDatabase()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $queue = $this->getMockBuilder(DatabaseQueue::class)\n            ->onlyMethods(['currentTime'])\n            ->setConstructorArgs([$database = m::mock(Connection::class), 'table', 'default'])\n            ->getMock();\n        $queue->expects($this->any())->method('currentTime')->willReturn('time');\n        $queue->setContainer($container = m::spy(Container::class));\n        $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('insertGetId')->once()->andReturnUsing(function ($array) use ($uuid, $time) {\n            $this->assertSame('default', $array['queue']);\n            $this->assertSame(json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'delay' => 10]), $array['payload']);\n            $this->assertEquals(0, $array['attempts']);\n            $this->assertNull($array['reserved_at']);\n            $this->assertIsInt($array['available_at']);\n        });\n\n        $queue->later(10, 'foo', ['data']);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testPushIncludesBatchIdInPayloadForBatchableJob()\n    {\n        $uuid = Str::uuid()->toString();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $job = (new MyBatchableJob)->withBatchId('test-batch-id');\n\n        $queue = $this->getMockBuilder(DatabaseQueue::class)->onlyMethods(['currentTime'])->setConstructorArgs([$database = m::mock(Connection::class), 'table', 'default'])->getMock();\n        $queue->expects($this->any())->method('currentTime')->willReturn('time');\n        $queue->setContainer($container = m::spy(Container::class));\n        $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('insertGetId')->once()->andReturnUsing(function ($array) {\n            $payload = json_decode($array['payload'], true);\n            $this->assertSame('test-batch-id', $payload['data']['batchId']);\n        });\n\n        $queue->push($job, ['data']);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testFailureToCreatePayloadFromObject()\n    {\n        $this->expectException('InvalidArgumentException');\n\n        $job = new stdClass;\n        $job->invalid = \"\\xc3\\x28\";\n\n        $queue = m::mock(Queue::class)->makePartial();\n        $class = new ReflectionClass(Queue::class);\n\n        $createPayload = $class->getMethod('createPayload');\n        $createPayload->invokeArgs($queue, [\n            $job,\n            'queue-name',\n        ]);\n    }\n\n    public function testFailureToCreatePayloadFromArray()\n    {\n        $this->expectException('InvalidArgumentException');\n\n        $queue = m::mock(Queue::class)->makePartial();\n        $class = new ReflectionClass(Queue::class);\n\n        $createPayload = $class->getMethod('createPayload');\n        $createPayload->invokeArgs($queue, [\n            [\"\\xc3\\x28\"],\n            'queue-name',\n        ]);\n    }\n\n    public function testBulkBatchPushesOntoDatabase()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $database = m::mock(Connection::class);\n        $queue = $this->getMockBuilder(DatabaseQueue::class)->onlyMethods(['currentTime', 'availableAt'])->setConstructorArgs([$database, 'table', 'default'])->getMock();\n        $queue->expects($this->any())->method('currentTime')->willReturn('created');\n        $queue->expects($this->any())->method('availableAt')->willReturn('available');\n        $database->shouldReceive('table')->with('table')->andReturn($query = m::mock(stdClass::class));\n        $query->shouldReceive('insert')->once()->andReturnUsing(function ($records) use ($uuid, $time) {\n            $this->assertEquals([[\n                'queue' => 'queue',\n                'payload' => json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'delay' => null]),\n                'attempts' => 0,\n                'reserved_at' => null,\n                'available_at' => 'available',\n                'created_at' => 'created',\n            ], [\n                'queue' => 'queue',\n                'payload' => json_encode(['uuid' => $uuid, 'displayName' => 'bar', 'job' => 'bar', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'delay' => null]),\n                'attempts' => 0,\n                'reserved_at' => null,\n                'available_at' => 'available',\n                'created_at' => 'created',\n            ]], $records);\n        });\n\n        $queue->bulk(['foo', 'bar'], ['data'], 'queue');\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testBuildDatabaseRecordWithPayloadAtTheEnd()\n    {\n        $queue = m::mock(DatabaseQueue::class);\n        $record = $queue->buildDatabaseRecord('queue', 'any_payload', 0);\n        $this->assertArrayHasKey('payload', $record);\n        $this->assertArrayHasKey('payload', array_slice($record, -1, 1, true));\n    }\n}\n\nclass MyTestJob\n{\n    public function handle()\n    {\n        // ...\n    }\n}\n\nclass MyBatchableJob\n{\n    use Batchable;\n}\n"
  },
  {
    "path": "tests/Queue/QueueDelayTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\n\nclass QueueDelayTest extends TestCase\n{\n    public function test_queue_delay()\n    {\n        Queue::fake();\n\n        $job = new TestJob;\n\n        dispatch($job);\n\n        $this->assertEquals(60, $job->delay);\n    }\n\n    public function test_queue_without_delay()\n    {\n        Queue::fake();\n\n        $job = new TestJob;\n\n        dispatch($job->withoutDelay());\n\n        $this->assertEquals(0, $job->delay);\n    }\n\n    public function test_pending_dispatch_without_delay()\n    {\n        Queue::fake();\n\n        $job = new TestJob;\n\n        dispatch($job)->withoutDelay();\n\n        $this->assertEquals(0, $job->delay);\n    }\n}\n\nclass TestJob implements ShouldQueue\n{\n    use Queueable;\n\n    public function __construct()\n    {\n        $this->delay(60);\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueExceptionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Queue\\Jobs\\RedisJob;\nuse Illuminate\\Queue\\MaxAttemptsExceededException;\nuse Illuminate\\Queue\\TimeoutExceededException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueExceptionTest extends TestCase\n{\n    public function test_it_can_create_timeout_exception_for_job()\n    {\n        $e = TimeoutExceededException::forJob($job = new MyFakeRedisJob());\n\n        $this->assertSame('App\\\\Jobs\\\\UnderlyingJob has timed out.', $e->getMessage());\n        $this->assertSame($job, $e->job);\n    }\n\n    public function test_it_can_create_max_attempts_exception_for_job()\n    {\n        $e = MaxAttemptsExceededException::forJob($job = new MyFakeRedisJob());\n\n        $this->assertSame('App\\\\Jobs\\\\UnderlyingJob has been attempted too many times.', $e->getMessage());\n        $this->assertSame($job, $e->job);\n    }\n}\n\nclass MyFakeRedisJob extends RedisJob\n{\n    public function __construct()\n    {\n        //\n    }\n\n    public function resolveName()\n    {\n        return 'App\\\\Jobs\\\\UnderlyingJob';\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueListenerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Queue\\Listener;\nuse Illuminate\\Queue\\ListenerOptions;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Process\\Process;\n\nuse function Illuminate\\Support\\artisan_binary;\nuse function Illuminate\\Support\\php_binary;\n\nclass QueueListenerTest extends TestCase\n{\n    public function testRunProcessCallsProcess()\n    {\n        $process = m::mock(Process::class)->makePartial();\n        $process->shouldReceive('run')->once();\n        $listener = m::mock(Listener::class)->makePartial();\n        $listener->shouldReceive('memoryExceeded')->once()->with(1)->andReturn(false);\n\n        $listener->runProcess($process, 1);\n    }\n\n    public function testListenerStopsWhenMemoryIsExceeded()\n    {\n        $process = m::mock(Process::class)->makePartial();\n        $process->shouldReceive('run')->once();\n        $listener = m::mock(Listener::class)->makePartial();\n        $listener->shouldReceive('memoryExceeded')->once()->with(1)->andReturn(true);\n        $listener->shouldReceive('stop')->once();\n\n        $listener->runProcess($process, 1);\n    }\n\n    public function testMakeProcessCorrectlyFormatsCommandLine()\n    {\n        $listener = new Listener(__DIR__);\n        $options = new ListenerOptions;\n        $options->backoff = 1;\n        $options->memory = 2;\n        $options->timeout = 3;\n        $process = $listener->makeProcess('connection', 'queue', $options);\n        $escape = $escapeMsys = '\\\\' === DIRECTORY_SEPARATOR ? '' : '\\'';\n\n        if (windows_os()) {\n            $escapeMsys = '\"';\n        }\n\n        $artisanBinary = artisan_binary();\n\n        $this->assertInstanceOf(Process::class, $process);\n        $this->assertEquals(__DIR__, $process->getWorkingDirectory());\n        $this->assertEquals(3, $process->getTimeout());\n        $this->assertEquals($escape.php_binary().$escape.\" {$escape}{$artisanBinary}{$escape} {$escape}queue:work{$escape} {$escape}connection{$escape} {$escape}--once{$escape} {$escapeMsys}--name=default{$escapeMsys} {$escapeMsys}--queue=queue{$escapeMsys} {$escapeMsys}--backoff=1{$escapeMsys} {$escapeMsys}--memory=2{$escapeMsys} {$escapeMsys}--sleep=3{$escapeMsys} {$escapeMsys}--tries=1{$escapeMsys}\", $process->getCommandLine());\n    }\n\n    public function testMakeProcessCorrectlyFormatsCommandLineWithAnEnvironmentSpecified()\n    {\n        $listener = new Listener(__DIR__);\n        $options = new ListenerOptions('default', 'test');\n        $options->backoff = 1;\n        $options->memory = 2;\n        $options->timeout = 3;\n        $process = $listener->makeProcess('connection', 'queue', $options);\n        $escape = $escapeMsys = '\\\\' === DIRECTORY_SEPARATOR ? '' : '\\'';\n\n        if (windows_os()) {\n            $escapeMsys = '\"';\n        }\n\n        $artisanBinary = artisan_binary();\n\n        $this->assertInstanceOf(Process::class, $process);\n        $this->assertEquals(__DIR__, $process->getWorkingDirectory());\n        $this->assertEquals(3, $process->getTimeout());\n        $this->assertEquals($escape.php_binary().$escape.\" {$escape}{$artisanBinary}{$escape} {$escape}queue:work{$escape} {$escape}connection{$escape} {$escape}--once{$escape} {$escapeMsys}--name=default{$escapeMsys} {$escapeMsys}--queue=queue{$escapeMsys} {$escapeMsys}--backoff=1{$escapeMsys} {$escapeMsys}--memory=2{$escapeMsys} {$escapeMsys}--sleep=3{$escapeMsys} {$escapeMsys}--tries=1{$escapeMsys} {$escapeMsys}--env=test{$escapeMsys}\", $process->getCommandLine());\n    }\n\n    public function testMakeProcessCorrectlyFormatsCommandLineWhenTheConnectionIsNotSpecified()\n    {\n        $listener = new Listener(__DIR__);\n        $options = new ListenerOptions('default', 'test');\n        $options->backoff = 1;\n        $options->memory = 2;\n        $options->timeout = 3;\n        $process = $listener->makeProcess(null, 'queue', $options);\n        $escape = $escapeMsys = '\\\\' === DIRECTORY_SEPARATOR ? '' : '\\'';\n\n        if (windows_os()) {\n            $escapeMsys = '\"';\n        }\n\n        $artisanBinary = artisan_binary();\n\n        $this->assertInstanceOf(Process::class, $process);\n        $this->assertEquals(__DIR__, $process->getWorkingDirectory());\n        $this->assertEquals(3, $process->getTimeout());\n        $this->assertEquals($escape.php_binary().$escape.\" {$escape}{$artisanBinary}{$escape} {$escape}queue:work{$escape} {$escape}--once{$escape} {$escapeMsys}--name=default{$escapeMsys} {$escapeMsys}--queue=queue{$escapeMsys} {$escapeMsys}--backoff=1{$escapeMsys} {$escapeMsys}--memory=2{$escapeMsys} {$escapeMsys}--sleep=3{$escapeMsys} {$escapeMsys}--tries=1{$escapeMsys} {$escapeMsys}--env=test{$escapeMsys}\", $process->getCommandLine());\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueManagerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Queue\\QueueManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass QueueManagerTest extends TestCase\n{\n    public function testDefaultConnectionCanBeResolved()\n    {\n        $app = [\n            'config' => [\n                'queue.default' => 'sync',\n                'queue.connections.sync' => ['driver' => 'sync'],\n            ],\n            'encrypter' => $encrypter = m::mock(Encrypter::class),\n        ];\n\n        $manager = new QueueManager($app);\n        $connector = m::mock(stdClass::class);\n        $queue = m::mock(stdClass::class);\n        $queue->shouldReceive('setConnectionName')->once()->with('sync')->andReturnSelf();\n        $connector->shouldReceive('connect')->once()->with(['driver' => 'sync'])->andReturn($queue);\n        $manager->addConnector('sync', function () use ($connector) {\n            return $connector;\n        });\n\n        $queue->shouldReceive('setContainer')->once()->with($app);\n        $this->assertSame($queue, $manager->connection('sync'));\n    }\n\n    public function testOtherConnectionCanBeResolved()\n    {\n        $app = [\n            'config' => [\n                'queue.default' => 'sync',\n                'queue.connections.foo' => ['driver' => 'bar'],\n            ],\n            'encrypter' => $encrypter = m::mock(Encrypter::class),\n        ];\n\n        $manager = new QueueManager($app);\n        $connector = m::mock(stdClass::class);\n        $queue = m::mock(stdClass::class);\n        $queue->shouldReceive('setConnectionName')->once()->with('foo')->andReturnSelf();\n        $connector->shouldReceive('connect')->once()->with(['driver' => 'bar'])->andReturn($queue);\n        $manager->addConnector('bar', function () use ($connector) {\n            return $connector;\n        });\n        $queue->shouldReceive('setContainer')->once()->with($app);\n\n        $this->assertSame($queue, $manager->connection('foo'));\n    }\n\n    public function testNullConnectionCanBeResolved()\n    {\n        $app = [\n            'config' => [\n                'queue.default' => 'null',\n            ],\n            'encrypter' => $encrypter = m::mock(Encrypter::class),\n        ];\n\n        $manager = new QueueManager($app);\n        $connector = m::mock(stdClass::class);\n        $queue = m::mock(stdClass::class);\n        $queue->shouldReceive('setConnectionName')->once()->with('null')->andReturnSelf();\n        $connector->shouldReceive('connect')->once()->with(['driver' => 'null'])->andReturn($queue);\n        $manager->addConnector('null', function () use ($connector) {\n            return $connector;\n        });\n        $queue->shouldReceive('setContainer')->once()->with($app);\n\n        $this->assertSame($queue, $manager->connection('null'));\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueuePauseResumeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Cache\\ArrayStore;\nuse Illuminate\\Cache\\Repository;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Queue\\Console\\Concerns\\ParsesQueue;\nuse Illuminate\\Queue\\Events\\QueuePaused;\nuse Illuminate\\Queue\\Events\\QueueResumed;\nuse Illuminate\\Queue\\QueueManager;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueuePauseResumeTest extends TestCase\n{\n    protected $manager;\n    protected $cache;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->cache = new Repository(new ArrayStore);\n\n        // Mock the cache facade to return our cache repository\n        $cacheMock = m::mock();\n        $cacheMock->shouldReceive('store')->andReturn($this->cache);\n\n        $app = [\n            'config' => [\n                'queue.default' => 'redis',\n                'queue.connections.redis' => ['driver' => 'redis'],\n                'queue.connections.database' => ['driver' => 'database'],\n            ],\n            'cache' => $cacheMock,\n            'events' => new Dispatcher(),\n        ];\n\n        $this->manager = new QueueManager($app);\n    }\n\n    public function testPauseQueueWithConnection()\n    {\n        $this->manager->pause('redis', 'default');\n\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n    }\n\n    public function testPauseQueueWithTTL()\n    {\n        Carbon::setTestNow();\n        $this->manager->pauseFor('redis', 'default', 30);\n\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n\n        Carbon::setTestNow(Carbon::now()->addMinute());\n        $this->assertFalse($this->manager->isPaused('redis', 'default'));\n    }\n\n    public function testPauseQueueIndefinitely()\n    {\n        Carbon::setTestNow();\n        $this->manager->pause('redis', 'default');\n\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n\n        Carbon::setTestNow(Carbon::now()->addYear());\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n    }\n\n    public function testResumeQueue()\n    {\n        $this->manager->pause('redis', 'default');\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n\n        $this->manager->resume('redis', 'default');\n        $this->assertFalse($this->manager->isPaused('redis', 'default'));\n    }\n\n    public function testPausingQueueOnOneConnectionDoesNotAffectAnother()\n    {\n        $this->manager->pause('redis', 'default');\n\n        $this->assertTrue($this->manager->isPaused('redis', 'default'));\n        $this->assertFalse($this->manager->isPaused('database', 'default'));\n    }\n\n    public function testPausingDifferentQueuesOnSameConnection()\n    {\n        $this->manager->pause('redis', 'emails');\n        $this->manager->pause('redis', 'notifications');\n\n        $this->assertTrue($this->manager->isPaused('redis', 'emails'));\n        $this->assertTrue($this->manager->isPaused('redis', 'notifications'));\n        $this->assertFalse($this->manager->isPaused('redis', 'default'));\n    }\n\n    public function testResumingOnlyAffectsSpecificQueue()\n    {\n        $this->manager->pause('redis', 'emails');\n        $this->manager->pause('redis', 'notifications');\n\n        $this->manager->resume('redis', 'emails');\n\n        $this->assertFalse($this->manager->isPaused('redis', 'emails'));\n        $this->assertTrue($this->manager->isPaused('redis', 'notifications'));\n    }\n\n    public function testPauseDispatchesQueuePausedEvent()\n    {\n        $dispatchedEvent = null;\n\n        $dispatcher = $this->manager->getApplication()['events'];\n\n        $dispatcher->listen(QueuePaused::class, function ($event) use (&$dispatchedEvent) {\n            $dispatchedEvent = $event;\n        });\n\n        $this->manager->pause('redis', 'default');\n\n        $this->assertInstanceOf(QueuePaused::class, $dispatchedEvent);\n        $this->assertSame('redis', $dispatchedEvent->connection);\n        $this->assertSame('default', $dispatchedEvent->queue);\n        $this->assertNull($dispatchedEvent->ttl);\n    }\n\n    public function testPauseForDispatchesQueuePausedEventWithTTL()\n    {\n        $dispatchedEvent = null;\n\n        $dispatcher = $this->manager->getApplication()['events'];\n\n        $dispatcher->listen(QueuePaused::class, function ($event) use (&$dispatchedEvent) {\n            $dispatchedEvent = $event;\n        });\n\n        $this->manager->pauseFor('redis', 'emails', 60);\n\n        $this->assertInstanceOf(QueuePaused::class, $dispatchedEvent);\n        $this->assertSame('redis', $dispatchedEvent->connection);\n        $this->assertSame('emails', $dispatchedEvent->queue);\n        $this->assertSame(60, $dispatchedEvent->ttl);\n    }\n\n    public function testResumeDispatchesQueueResumedEvent()\n    {\n        $dispatchedEvent = null;\n\n        $dispatcher = $this->manager->getApplication()['events'];\n\n        $dispatcher->listen(QueueResumed::class, function ($event) use (&$dispatchedEvent) {\n            $dispatchedEvent = $event;\n        });\n\n        $this->manager->resume('database', 'notifications');\n\n        $this->assertInstanceOf(QueueResumed::class, $dispatchedEvent);\n        $this->assertSame('database', $dispatchedEvent->connection);\n        $this->assertSame('notifications', $dispatchedEvent->queue);\n    }\n\n    public function testParsingQueueString()\n    {\n        $parser = new class()\n        {\n            use ParsesQueue;\n\n            private array $laravel = [\n                'config' => ['queue.default' => 'redis'],\n            ];\n\n            public function parse(string $queue)\n            {\n                return $this->parseQueue($queue);\n            }\n        };\n\n        $this->assertSame(['redis', 'default'], $parser->parse(''));\n        $this->assertSame(['redis', 'emails'], $parser->parse('emails'));\n        $this->assertSame(['database', 'notifications'], $parser->parse('database:notifications'));\n        $this->assertSame(['redis', 'foo:bar'], $parser->parse('redis:foo:bar'));\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueRedisJobTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Queue\\Jobs\\RedisJob;\nuse Illuminate\\Queue\\RedisQueue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass QueueRedisJobTest extends TestCase\n{\n    public function testFireProperlyCallsTheJobHandler()\n    {\n        $job = $this->getJob();\n        $job->getContainer()->shouldReceive('make')->once()->with('foo')->andReturn($handler = m::mock(stdClass::class));\n        $handler->shouldReceive('fire')->once()->with($job, ['data']);\n\n        $job->fire();\n    }\n\n    public function testDeleteRemovesTheJobFromRedis()\n    {\n        $job = $this->getJob();\n        $job->getRedisQueue()->shouldReceive('deleteReserved')->once()\n            ->with('default', $job);\n\n        $job->delete();\n    }\n\n    public function testReleaseProperlyReleasesJobOntoRedis()\n    {\n        $job = $this->getJob();\n        $job->getRedisQueue()->shouldReceive('deleteAndRelease')->once()\n            ->with('default', $job, 1);\n\n        $job->release(1);\n    }\n\n    protected function getJob()\n    {\n        return new RedisJob(\n            m::mock(Container::class),\n            m::mock(RedisQueue::class),\n            json_encode(['job' => 'foo', 'data' => ['data'], 'attempts' => 1]),\n            json_encode(['job' => 'foo', 'data' => ['data'], 'attempts' => 2]),\n            'connection-name',\n            'default'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueRedisQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Redis\\Factory;\nuse Illuminate\\Queue\\LuaScripts;\nuse Illuminate\\Queue\\Queue;\nuse Illuminate\\Queue\\RedisQueue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueRedisQueueTest extends TestCase\n{\n    public function testPushProperlyPushesJobOntoRedis()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock();\n        $queue->expects($this->once())->method('getRandomId')->willReturn('foo');\n        $queue->setContainer($container = m::spy(Container::class));\n        $redis->shouldReceive('connection')->once()->andReturn($redis);\n        $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'id' => 'foo', 'attempts' => 0, 'delay' => null]));\n\n        $id = $queue->push('foo', ['data']);\n        $this->assertSame('foo', $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobOntoRedisWithCustomPayloadHook()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock();\n        $queue->expects($this->once())->method('getRandomId')->willReturn('foo');\n        $queue->setContainer($container = m::spy(Container::class));\n        $redis->shouldReceive('connection')->once()->andReturn($redis);\n        $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'custom' => 'taylor', 'id' => 'foo', 'attempts' => 0, 'delay' => null]));\n\n        Queue::createPayloadUsing(function ($connection, $queue, $payload) {\n            return ['custom' => 'taylor'];\n        });\n\n        $id = $queue->push('foo', ['data']);\n        $this->assertSame('foo', $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Queue::createPayloadUsing(null);\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobOntoRedisWithTwoCustomPayloadHook()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock();\n        $queue->expects($this->once())->method('getRandomId')->willReturn('foo');\n        $queue->setContainer($container = m::spy(Container::class));\n        $redis->shouldReceive('connection')->once()->andReturn($redis);\n        $redis->shouldReceive('eval')->once()->with(LuaScripts::push(), 2, 'queues:default', 'queues:default:notify', json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'custom' => 'taylor', 'bar' => 'foo', 'id' => 'foo', 'attempts' => 0, 'delay' => null]));\n\n        Queue::createPayloadUsing(function ($connection, $queue, $payload) {\n            return ['custom' => 'taylor'];\n        });\n\n        Queue::createPayloadUsing(function ($connection, $queue, $payload) {\n            return ['bar' => 'foo'];\n        });\n\n        $id = $queue->push('foo', ['data']);\n        $this->assertSame('foo', $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Queue::createPayloadUsing(null);\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testDelayedPushProperlyPushesJobOntoRedis()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = Carbon::now();\n        Carbon::setTestNow($time);\n\n        $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['availableAt', 'getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('getRandomId')->willReturn('foo');\n        $queue->expects($this->once())->method('availableAt')->with(1)->willReturn(2);\n\n        $redis->shouldReceive('connection')->once()->andReturn($redis);\n        $redis->shouldReceive('eval')->once()->with(\n            LuaScripts::later(),\n            1,\n            'queues:default:delayed',\n            2,\n            json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'id' => 'foo', 'attempts' => 0, 'delay' => 1])\n        );\n\n        $id = $queue->later(1, 'foo', ['data']);\n        $this->assertSame('foo', $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n\n    public function testDelayedPushWithDateTimeProperlyPushesJobOntoRedis()\n    {\n        $uuid = Str::uuid();\n\n        Str::createUuidsUsing(function () use ($uuid) {\n            return $uuid;\n        });\n\n        $time = $date = Carbon::now();\n        Carbon::setTestNow($time);\n        $queue = $this->getMockBuilder(RedisQueue::class)->onlyMethods(['availableAt', 'getRandomId'])->setConstructorArgs([$redis = m::mock(Factory::class), 'default'])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('getRandomId')->willReturn('foo');\n        $queue->expects($this->once())->method('availableAt')->with($date)->willReturn(5);\n\n        $redis->shouldReceive('connection')->once()->andReturn($redis);\n        $redis->shouldReceive('eval')->once()->with(\n            LuaScripts::later(),\n            1,\n            'queues:default:delayed',\n            5,\n            json_encode(['uuid' => $uuid, 'displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'maxExceptions' => null, 'failOnTimeout' => false, 'backoff' => null, 'timeout' => null, 'data' => ['data'], 'createdAt' => $time->getTimestamp(), 'id' => 'foo', 'attempts' => 0, 'delay' => 5])\n        );\n\n        $queue->later($date->addSeconds(5), 'foo', ['data']);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Carbon::setTestNow();\n        Str::createUuidsNormally();\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueRoutesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Foundation\\Queue\\Queueable;\nuse Illuminate\\Queue\\QueueRoutes;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueRoutesTest extends TestCase\n{\n    public function testSet()\n    {\n        $defaults = new QueueRoutes();\n\n        $defaults->set(QueueRoutes::class, 'some-queue');\n        $defaults->set(BaseNotification::class, 'some-queue', 'some-connection');\n\n        $this->assertSame([\n            QueueRoutes::class => [null, 'some-queue'],\n            BaseNotification::class => ['some-connection', 'some-queue'],\n        ], $defaults->all());\n\n        // Ensure same class overrides\n        $defaults->set([\n            QueueRoutes::class => 'queue-many',\n            SomeJob::class => 'important',\n        ]);\n\n        $this->assertSame([\n            QueueRoutes::class => 'queue-many',\n            BaseNotification::class => ['some-connection', 'some-queue'],\n            SomeJob::class => 'important',\n        ], $defaults->all()\n        );\n    }\n\n    public function testGetQueue()\n    {\n        $defaults = new QueueRoutes();\n\n        $defaults->set([\n            BaseNotification::class => 'notifications',\n            CustomTrait::class => 'jobs',\n            PaymentContract::class => 'payments',\n        ]);\n\n        // No queue set\n        $defaults->set(PaymentContract::class, connection: 'payment-connection');\n\n        $this->assertSame('notifications', $defaults->getQueue(new FinanceNotification));\n        $this->assertSame('jobs', $defaults->getQueue(new SomeJob));\n        $this->assertNull($defaults->getQueue(new Payment));\n    }\n\n    public function testGetConnection()\n    {\n        $defaults = new QueueRoutes();\n\n        $defaults->set([\n            BaseNotification::class => ['notification-connection', 'notifications'],\n            CustomTrait::class => ['job-connection', 'jobs'],\n        ]);\n\n        // No connection set\n        $defaults->set(PaymentContract::class, 'payments');\n\n        $this->assertSame('notification-connection', $defaults->getConnection(new FinanceNotification));\n        $this->assertSame('job-connection', $defaults->getConnection(new SomeJob));\n        $this->assertNull($defaults->getConnection(new Payment));\n    }\n}\n\ntrait CustomTrait\n{\n}\n\nclass SomeJob\n{\n    use Queueable, CustomTrait;\n}\n\nclass BaseNotification\n{\n    use Queueable;\n}\n\nclass FinanceNotification extends BaseNotification\n{\n}\n\ninterface PaymentContract\n{\n}\n\nclass Payment implements PaymentContract\n{\n}\n"
  },
  {
    "path": "tests/Queue/QueueSizeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Orchestra\\Testbench\\TestCase;\n\nclass QueueSizeTest extends TestCase\n{\n    public function test_queue_size()\n    {\n        Queue::fake();\n\n        $this->assertEquals(0, Queue::size());\n        $this->assertEquals(0, Queue::size('Q2'));\n\n        $job = new TestJob1;\n\n        dispatch($job);\n        dispatch(new TestJob2);\n        dispatch($job)->onQueue('Q2');\n\n        $this->assertEquals(2, Queue::size());\n        $this->assertEquals(1, Queue::size('Q2'));\n    }\n}\n\nclass TestJob1 implements ShouldQueue\n{\n    use Queueable;\n}\n\nclass TestJob2 implements ShouldQueue\n{\n    use Queueable;\n}\n"
  },
  {
    "path": "tests/Queue/QueueSqsJobTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Aws\\Sqs\\SqsClient;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Queue\\Jobs\\SqsJob;\nuse Illuminate\\Queue\\SqsQueue;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass QueueSqsJobTest extends TestCase\n{\n    protected $key;\n    protected $secret;\n    protected $service;\n    protected $region;\n    protected $account;\n    protected $queueName;\n    protected $baseUrl;\n    protected $releaseDelay;\n    protected $queueUrl;\n    protected $mockedSqsClient;\n    protected $mockedContainer;\n    protected $mockedJob;\n    protected $mockedData;\n    protected $mockedPayload;\n    protected $mockedMessageId;\n    protected $mockedReceiptHandle;\n    protected $mockedJobData;\n\n    protected function setUp(): void\n    {\n        $this->key = 'AMAZONSQSKEY';\n        $this->secret = 'AmAz0n+SqSsEcReT+aLpHaNuM3R1CsTr1nG';\n        $this->service = 'sqs';\n        $this->region = 'someregion';\n        $this->account = '1234567891011';\n        $this->queueName = 'emails';\n        $this->baseUrl = 'https://sqs.someregion.amazonaws.com';\n        $this->releaseDelay = 0;\n\n        // This is how the modified getQueue builds the queueUrl\n        $this->queueUrl = $this->baseUrl.'/'.$this->account.'/'.$this->queueName;\n\n        // Get a mock of the SqsClient\n        $this->mockedSqsClient = m::mock(SqsClient::class)->makePartial();\n\n        // Use Mockery to mock the IoC Container\n        $this->mockedContainer = m::mock(Container::class);\n\n        $this->mockedJob = 'foo';\n        $this->mockedData = ['data'];\n        $this->mockedPayload = json_encode(['job' => $this->mockedJob, 'data' => $this->mockedData, 'attempts' => 1]);\n        $this->mockedMessageId = 'e3cd03ee-59a3-4ad8-b0aa-ee2e3808ac81';\n        $this->mockedReceiptHandle = '0NNAq8PwvXuWv5gMtS9DJ8qEdyiUwbAjpp45w2m6M4SJ1Y+PxCh7R930NRB8ylSacEmoSnW18bgd4nK\\/O6ctE+VFVul4eD23mA07vVoSnPI4F\\/voI1eNCp6Iax0ktGmhlNVzBwaZHEr91BRtqTRM3QKd2ASF8u+IQaSwyl\\/DGK+P1+dqUOodvOVtExJwdyDLy1glZVgm85Yw9Jf5yZEEErqRwzYz\\/qSigdvW4sm2l7e4phRol\\/+IjMtovOyH\\/ukueYdlVbQ4OshQLENhUKe7RNN5i6bE\\/e5x9bnPhfj2gbM';\n\n        $this->mockedJobData = [\n            'Body' => $this->mockedPayload,\n            'MD5OfBody' => md5($this->mockedPayload),\n            'ReceiptHandle' => $this->mockedReceiptHandle,\n            'MessageId' => $this->mockedMessageId,\n            'Attributes' => ['ApproximateReceiveCount' => 1],\n        ];\n    }\n\n    public function testFireProperlyCallsTheJobHandler()\n    {\n        $job = $this->getJob();\n        $job->getContainer()->shouldReceive('make')->once()->with('foo')->andReturn($handler = m::mock(stdClass::class));\n        $handler->shouldReceive('fire')->once()->with($job, ['data']);\n        $job->fire();\n    }\n\n    public function testDeleteRemovesTheJobFromSqs()\n    {\n        $this->mockedSqsClient = m::mock(SqsClient::class)->makePartial();\n        $queue = m::mock(SqsQueue::class, [$this->mockedSqsClient, $this->queueName, $this->account])->makePartial();\n        $queue->setContainer($this->mockedContainer);\n        $job = $this->getJob();\n        $job->getSqs()->shouldReceive('deleteMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'ReceiptHandle' => $this->mockedReceiptHandle]);\n        $job->delete();\n    }\n\n    public function testReleaseProperlyReleasesTheJobOntoSqs()\n    {\n        $this->mockedSqsClient = m::mock(SqsClient::class)->makePartial();\n        $queue = m::mock(SqsQueue::class, [$this->mockedSqsClient, $this->queueName, $this->account])->makePartial();\n        $queue->setContainer($this->mockedContainer);\n        $job = $this->getJob();\n        $job->getSqs()->shouldReceive('changeMessageVisibility')->once()->with(['QueueUrl' => $this->queueUrl, 'ReceiptHandle' => $this->mockedReceiptHandle, 'VisibilityTimeout' => $this->releaseDelay]);\n        $job->release($this->releaseDelay);\n        $this->assertTrue($job->isReleased());\n    }\n\n    protected function getJob()\n    {\n        return new SqsJob(\n            $this->mockedContainer,\n            $this->mockedSqsClient,\n            $this->mockedJobData,\n            'connection-name',\n            $this->queueUrl\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueSqsQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Aws\\Result;\nuse Aws\\Sqs\\SqsClient;\nuse Illuminate\\Bus\\Dispatcher;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher as DispatcherContract;\nuse Illuminate\\Queue\\Jobs\\SqsJob;\nuse Illuminate\\Queue\\QueueRoutes;\nuse Illuminate\\Queue\\SqsQueue;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Queue\\Fixtures\\FakeSqsJob;\nuse Illuminate\\Tests\\Queue\\Fixtures\\FakeSqsJobWithDeduplication;\nuse Illuminate\\Tests\\Queue\\Fixtures\\FakeSqsJobWithMessageGroup;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueSqsQueueTest extends TestCase\n{\n    protected $sqs;\n    protected $account;\n    protected $queueName;\n    protected $fifoQueueName;\n    protected $baseUrl;\n    protected $prefix;\n    protected $queueUrl;\n    protected $fifoQueueUrl;\n    protected $mockedJob;\n    protected $mockedData;\n    protected $mockedPayload;\n    protected $mockedDelay;\n    protected $mockedMessageGroupId;\n    protected $mockedDeduplicationId;\n    protected $mockedMessageId;\n    protected $mockedReceiptHandle;\n    protected $mockedSendMessageResponseModel;\n    protected $mockedReceiveMessageResponseModel;\n    protected $mockedReceiveEmptyMessageResponseModel;\n    protected $mockedQueueAttributesResponseModel;\n\n    protected function setUp(): void\n    {\n        // Use Mockery to mock the SqsClient\n        $this->sqs = m::mock(SqsClient::class);\n\n        $this->account = '1234567891011';\n        $this->queueName = 'emails';\n        $this->fifoQueueName = 'emails.fifo';\n        $this->baseUrl = 'https://sqs.someregion.amazonaws.com';\n\n        // This is how the modified getQueue builds the queueUrl\n        $this->prefix = $this->baseUrl.'/'.$this->account.'/';\n        $this->queueUrl = $this->prefix.$this->queueName;\n        $this->fifoQueueUrl = $this->prefix.$this->fifoQueueName;\n\n        $this->mockedJob = 'foo';\n        $this->mockedData = ['data'];\n        $this->mockedPayload = json_encode(['job' => $this->mockedJob, 'data' => $this->mockedData]);\n        $this->mockedDelay = 10;\n        $this->mockedMessageGroupId = 'group-1';\n        $this->mockedDeduplicationId = 'deduplication-id-1';\n        $this->mockedMessageId = 'e3cd03ee-59a3-4ad8-b0aa-ee2e3808ac81';\n        $this->mockedReceiptHandle = '0NNAq8PwvXuWv5gMtS9DJ8qEdyiUwbAjpp45w2m6M4SJ1Y+PxCh7R930NRB8ylSacEmoSnW18bgd4nK\\/O6ctE+VFVul4eD23mA07vVoSnPI4F\\/voI1eNCp6Iax0ktGmhlNVzBwaZHEr91BRtqTRM3QKd2ASF8u+IQaSwyl\\/DGK+P1+dqUOodvOVtExJwdyDLy1glZVgm85Yw9Jf5yZEEErqRwzYz\\/qSigdvW4sm2l7e4phRol\\/+IjMtovOyH\\/ukueYdlVbQ4OshQLENhUKe7RNN5i6bE\\/e5x9bnPhfj2gbM';\n\n        $this->mockedSendMessageResponseModel = new Result([\n            'Body' => $this->mockedPayload,\n            'MD5OfBody' => md5($this->mockedPayload),\n            'ReceiptHandle' => $this->mockedReceiptHandle,\n            'MessageId' => $this->mockedMessageId,\n            'Attributes' => ['ApproximateReceiveCount' => 1],\n        ]);\n\n        $this->mockedReceiveMessageResponseModel = new Result([\n            'Messages' => [\n                0 => [\n                    'Body' => $this->mockedPayload,\n                    'MD5OfBody' => md5($this->mockedPayload),\n                    'ReceiptHandle' => $this->mockedReceiptHandle,\n                    'MessageId' => $this->mockedMessageId,\n                ],\n            ],\n        ]);\n\n        $this->mockedReceiveEmptyMessageResponseModel = new Result([\n            'Messages' => null,\n        ]);\n\n        $this->mockedQueueAttributesResponseModel = new Result([\n            'Attributes' => [\n                'ApproximateNumberOfMessages' => 1,\n            ],\n        ]);\n    }\n\n    protected function createSpyContainer()\n    {\n        $container = m::spy(Container::class);\n\n        $container->shouldReceive('bound')\n            ->with('queue.routes')\n            ->andReturn(true);\n        $container->shouldReceive('offsetGet')\n            ->with('queue.routes')\n            ->andReturn(new QueueRoutes());\n\n        return $container;\n    }\n\n    public function testPopProperlyPopsJobOffOfSqs()\n    {\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer(m::mock(Container::class));\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('receiveMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'AttributeNames' => ['ApproximateReceiveCount']])->andReturn($this->mockedReceiveMessageResponseModel);\n        $result = $queue->pop($this->queueName);\n        $this->assertInstanceOf(SqsJob::class, $result);\n    }\n\n    public function testPopProperlyHandlesEmptyMessage()\n    {\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer(m::mock(Container::class));\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('receiveMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'AttributeNames' => ['ApproximateReceiveCount']])->andReturn($this->mockedReceiveEmptyMessageResponseModel);\n        $result = $queue->pop($this->queueName);\n        $this->assertNull($result);\n    }\n\n    public function testDelayedPushWithDateTimeProperlyPushesJobOntoSqs()\n    {\n        $now = Carbon::now();\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('secondsUntil')->with($now->addSeconds(5))->willReturn(5);\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'DelaySeconds' => 5])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->later($now->addSeconds(5), $this->mockedJob, $this->mockedData, $this->queueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testDelayedPushProperlyPushesJobOntoSqs()\n    {\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('secondsUntil')->with($this->mockedDelay)->willReturn($this->mockedDelay);\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'DelaySeconds' => $this->mockedDelay])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->later($this->mockedDelay, $this->mockedJob, $this->mockedData, $this->queueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPushProperlyPushesJobOntoSqs()\n    {\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($this->mockedJob, $this->mockedData, $this->queueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testSizeProperlyReadsSqsQueueSize()\n    {\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n\n        $this->sqs->shouldReceive('getQueueAttributes')->once()->with([\n            'QueueUrl' => $this->queueUrl,\n            'AttributeNames' => [\n                'ApproximateNumberOfMessages',\n                'ApproximateNumberOfMessagesDelayed',\n                'ApproximateNumberOfMessagesNotVisible',\n            ],\n        ])->andReturn(new Result([\n            'Attributes' => [\n                'ApproximateNumberOfMessages' => 1,\n                'ApproximateNumberOfMessagesDelayed' => 2,\n                'ApproximateNumberOfMessagesNotVisible' => 3,\n            ],\n        ]));\n\n        $size = $queue->size($this->queueName);\n\n        $this->assertEquals(6, $size); // 1 + 2 + 3\n    }\n\n    public function testGetQueueProperlyResolvesUrlWithPrefix()\n    {\n        $queue = new SqsQueue($this->sqs, $this->queueName, $this->prefix);\n        $this->assertEquals($this->queueUrl, $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test';\n        $this->assertEquals($queueUrl, $queue->getQueue('test'));\n    }\n\n    public function testGetQueueProperlyResolvesFifoUrlWithPrefix()\n    {\n        $this->queueName = 'emails.fifo';\n        $this->queueUrl = $this->prefix.$this->queueName;\n        $queue = new SqsQueue($this->sqs, $this->queueName, $this->prefix);\n        $this->assertEquals($this->queueUrl, $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test.fifo';\n        $this->assertEquals($queueUrl, $queue->getQueue('test.fifo'));\n    }\n\n    public function testGetQueueProperlyResolvesUrlWithoutPrefix()\n    {\n        $queue = new SqsQueue($this->sqs, $this->queueUrl);\n        $this->assertEquals($this->queueUrl, $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test';\n        $this->assertEquals($queueUrl, $queue->getQueue($queueUrl));\n    }\n\n    public function testGetQueueProperlyResolvesFifoUrlWithoutPrefix()\n    {\n        $this->queueName = 'emails.fifo';\n        $this->queueUrl = $this->prefix.$this->queueName;\n        $queue = new SqsQueue($this->sqs, $this->queueUrl);\n        $this->assertEquals($this->queueUrl, $queue->getQueue(null));\n        $fifoQueueUrl = $this->baseUrl.'/'.$this->account.'/test.fifo';\n        $this->assertEquals($fifoQueueUrl, $queue->getQueue($fifoQueueUrl));\n    }\n\n    public function testGetQueueProperlyResolvesUrlWithSuffix()\n    {\n        $queue = new SqsQueue($this->sqs, $this->queueName, $this->prefix, $suffix = '-staging');\n        $this->assertEquals($this->queueUrl.$suffix, $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test'.$suffix;\n        $this->assertEquals($queueUrl, $queue->getQueue('test'));\n    }\n\n    public function testGetQueueProperlyResolvesFifoUrlWithSuffix()\n    {\n        $this->queueName = 'emails.fifo';\n        $queue = new SqsQueue($this->sqs, $this->queueName, $this->prefix, $suffix = '-staging');\n        $this->assertEquals(\"{$this->prefix}emails-staging.fifo\", $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test'.$suffix.'.fifo';\n        $this->assertEquals($queueUrl, $queue->getQueue('test.fifo'));\n    }\n\n    public function testGetQueueEnsuresTheQueueIsOnlySuffixedOnce()\n    {\n        $queue = new SqsQueue($this->sqs, \"{$this->queueName}-staging\", $this->prefix, $suffix = '-staging');\n        $this->assertEquals($this->queueUrl.$suffix, $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test'.$suffix;\n        $this->assertEquals($queueUrl, $queue->getQueue('test-staging'));\n    }\n\n    public function testGetFifoQueueEnsuresTheQueueIsOnlySuffixedOnce()\n    {\n        $queue = new SqsQueue($this->sqs, \"{$this->queueName}-staging.fifo\", $this->prefix, $suffix = '-staging');\n        $this->assertEquals(\"{$this->prefix}{$this->queueName}{$suffix}.fifo\", $queue->getQueue(null));\n        $queueUrl = $this->baseUrl.'/'.$this->account.'/test'.$suffix.'.fifo';\n        $this->assertEquals($queueUrl, $queue->getQueue('test-staging.fifo'));\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqs()\n    {\n        $job = new FakeSqsJob();\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->queueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPendingDispatchProperlyPushesJobObjectOntoSqs()\n    {\n        // Job will not be dispatched until the PendingDispatch object is destroyed.\n        $pendingDispatch = FakeSqsJob::dispatch();\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->queueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFairQueue()\n    {\n        $job = (new FakeSqsJob())->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->queueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->queueName)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'MessageGroupId' => $this->mockedMessageGroupId])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->queueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPendingDispatchProperlyPushesJobObjectOntoSqsFairQueue()\n    {\n        $pendingDispatch = FakeSqsJob::dispatch()->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->queueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->queueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->queueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with(['QueueUrl' => $this->queueUrl, 'MessageBody' => $this->mockedPayload, 'MessageGroupId' => $this->mockedMessageGroupId])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPushProperlyPushesJobStringOntoSqsFifoQueue()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->fifoQueueName,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($this->mockedJob, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFifoQueue()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $job = (new FakeSqsJob())->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFifoQueueWithMessageGroupMethod()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $job = $this->getMockBuilder(FakeSqsJobWithMessageGroup::class)->onlyMethods(['messageGroup'])->getMock();\n        $job->expects($this->once())->method('messageGroup')->willReturn($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFifoQueueWithMessageGroupPropertyOverridingMethod()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $job = $this->getMockBuilder(FakeSqsJobWithMessageGroup::class)->onlyMethods(['messageGroup'])->getMock();\n\n        // Ensure the messageGroup method is not called when a messageGroup property is provided.\n        $job->expects($this->never())->method('messageGroup')->willReturn('this-should-not-be-used');\n        $job->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFifoQueueWithDeduplicationId()\n    {\n        $job = $this->getMockBuilder(FakeSqsJobWithDeduplication::class)->onlyMethods(['deduplicationId'])->getMock();\n        $job->expects($this->once())->method('deduplicationId')->with($this->mockedPayload, $this->fifoQueueName)->willReturn($this->mockedDeduplicationId);\n        $job->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPushProperlyPushesJobObjectOntoSqsFifoQueueWithDeduplicator()\n    {\n        $job = $this->getMockBuilder(FakeSqsJobWithDeduplication::class)->onlyMethods(['deduplicationId'])->getMock();\n\n        // Ensure the deduplicationId method is not called when a deduplicator callback is provided.\n        $job->expects($this->never())->method('deduplicationId')->willReturn('this-should-not-be-used');\n        $job->onGroup($this->mockedMessageGroupId)->withDeduplicator(function ($payload, $queue) {\n            $this->assertEquals($this->mockedPayload, $payload);\n            $this->assertEquals($this->fifoQueueName, $queue);\n\n            return $this->mockedDeduplicationId;\n        });\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->push($job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testPendingDispatchProperlyPushesJobObjectOntoSqsFifoQueue()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $pendingDispatch = FakeSqsJob::dispatch()->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->fifoQueueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testPendingDispatchProperlyPushesJobObjectOntoSqsFifoQueueWithDeduplicationId()\n    {\n        FakeSqsJobWithDeduplication::createDeduplicationIdsUsing(fn ($payload, $queue) => $this->mockedDeduplicationId);\n\n        $pendingDispatch = FakeSqsJobWithDeduplication::dispatch()->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->fifoQueueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        FakeSqsJobWithDeduplication::createDeduplicationIdsNormally();\n    }\n\n    public function testPendingDispatchProperlyPushesJobObjectOntoSqsFifoQueueWithDeduplicator()\n    {\n        FakeSqsJobWithDeduplication::createDeduplicationIdsUsing(function ($payload, $queue) {\n            $this->fail('The deduplicationId method should not be called when a deduplicator callback is provided.');\n\n            return 'this-should-not-be-used';\n        });\n\n        $pendingDispatch = FakeSqsJobWithDeduplication::dispatch()->onGroup($this->mockedMessageGroupId)->withDeduplicator(function ($payload, $queue) {\n            $this->assertEquals($this->mockedPayload, $payload);\n            $this->assertEquals($this->fifoQueueName, $queue);\n\n            return $this->mockedDeduplicationId;\n        });\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->fifoQueueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        FakeSqsJobWithDeduplication::createDeduplicationIdsNormally();\n    }\n\n    public function testJobObjectCanBeSerializedOntoSqsFifoQueueWithDeduplicator()\n    {\n        // Can't reference test case property in serialized closure.\n        $deduplicationId = $this->mockedDeduplicationId;\n\n        $pendingDispatch = FakeSqsJobWithDeduplication::dispatch()->onGroup($this->mockedMessageGroupId)->withDeduplicator(function ($payload, $queue) use ($deduplicationId) {\n            return $deduplicationId;\n        });\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->withArgs(function ($args) {\n            $this->assertIsArray($args);\n            $this->assertEqualsCanonicalizing(['QueueUrl', 'MessageBody', 'MessageGroupId', 'MessageDeduplicationId'], array_keys($args));\n            $this->assertEquals($this->fifoQueueUrl, $args['QueueUrl']);\n            $this->assertEquals($this->mockedMessageGroupId, $args['MessageGroupId']);\n            $this->assertEquals($this->mockedDeduplicationId, $args['MessageDeduplicationId']);\n\n            $message = json_decode($args['MessageBody'], true);\n            $command = unserialize($message['data']['command'] ?? '');\n            $this->assertInstanceOf(FakeSqsJobWithDeduplication::class, $command);\n            $this->assertInstanceOf(SerializableClosure::class, $command->deduplicator);\n\n            return true;\n        })->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n    }\n\n    public function testDelayedPushProperlyPushesJobStringOntoSqsFifoQueueWithoutDelay()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($this->mockedJob, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->never())->method('secondsUntil')->with($this->mockedDelay)->willReturn($this->mockedDelay);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->fifoQueueName,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->later($this->mockedDelay, $this->mockedJob, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testDelayedPushProperlyPushesJobObjectOntoSqsFifoQueueWithoutDelay()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $job = (new FakeSqsJob())->onGroup($this->mockedMessageGroupId);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'secondsUntil', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = m::spy(Container::class));\n        $queue->expects($this->once())->method('createPayload')->with($job, $this->fifoQueueName, $this->mockedData)->willReturn($this->mockedPayload);\n        $queue->expects($this->never())->method('secondsUntil')->with($this->mockedDelay)->willReturn($this->mockedDelay);\n        $queue->expects($this->once())->method('getQueue')->with($this->fifoQueueName)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n        $id = $queue->later($this->mockedDelay, $job, $this->mockedData, $this->fifoQueueName);\n        $this->assertEquals($this->mockedMessageId, $id);\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n\n    public function testDelayedPendingDispatchProperlyPushesJobObjectOntoSqsFifoQueueWithoutDelay()\n    {\n        Str::createUuidsUsing(fn () => $this->mockedDeduplicationId);\n\n        $pendingDispatch = FakeSqsJob::dispatch()->onGroup($this->mockedMessageGroupId)->delay($this->mockedDelay);\n\n        $queue = $this->getMockBuilder(SqsQueue::class)->onlyMethods(['createPayload', 'getQueue'])->setConstructorArgs([$this->sqs, $this->fifoQueueName, $this->account])->getMock();\n        $queue->setContainer($container = $this->createSpyContainer());\n        $queue->expects($this->once())->method('createPayload')->with($pendingDispatch->getJob(), $this->fifoQueueName, '')->willReturn($this->mockedPayload);\n        $queue->expects($this->once())->method('getQueue')->with(null)->willReturn($this->fifoQueueUrl);\n        $this->sqs->shouldReceive('sendMessage')->once()->with([\n            'QueueUrl' => $this->fifoQueueUrl,\n            'MessageBody' => $this->mockedPayload,\n            'MessageGroupId' => $this->mockedMessageGroupId,\n            'MessageDeduplicationId' => $this->mockedDeduplicationId,\n        ])->andReturn($this->mockedSendMessageResponseModel);\n\n        $dispatcher = new Dispatcher($container, fn () => $queue);\n        app()->instance(DispatcherContract::class, $dispatcher);\n\n        // Destroy object to trigger dispatch.\n        unset($pendingDispatch);\n\n        $container->shouldHaveReceived('bound')->with('events')->twice();\n\n        Str::createUuidsNormally();\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueSyncQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\QueueableEntity;\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit;\nuse Illuminate\\Database\\DatabaseTransactionsManager;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\Jobs\\SyncJob;\nuse Illuminate\\Queue\\SyncQueue;\nuse LogicException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass QueueSyncQueueTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        parent::tearDown();\n    }\n\n    public function testPushShouldFireJobInstantly()\n    {\n        unset($_SERVER['__sync.test']);\n\n        $sync = new SyncQueue;\n        $container = new Container;\n        $sync->setContainer($container);\n\n        $sync->push(SyncQueueTestHandler::class, ['foo' => 'bar']);\n        $this->assertInstanceOf(SyncJob::class, $_SERVER['__sync.test'][0]);\n        $this->assertEquals(['foo' => 'bar'], $_SERVER['__sync.test'][1]);\n    }\n\n    public function testFailedJobGetsHandledWhenAnExceptionIsThrown()\n    {\n        unset($_SERVER['__sync.failed']);\n\n        $sync = new SyncQueue;\n        $container = new Container;\n        Container::setInstance($container);\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->times(4);\n        $container->instance('events', $events);\n        $container->instance(Dispatcher::class, $events);\n        $sync->setContainer($container);\n\n        try {\n            $sync->push(FailingSyncQueueTestHandler::class, ['foo' => 'bar']);\n        } catch (Exception) {\n            $this->assertTrue($_SERVER['__sync.failed']);\n        }\n\n        Container::setInstance();\n    }\n\n    public function testFailedJobHasAccessToJobInstance()\n    {\n        unset($_SERVER['__sync.failed']);\n\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Events\\Dispatcher::class, \\Illuminate\\Events\\Dispatcher::class);\n        $container->bind(\\Illuminate\\Contracts\\Bus\\Dispatcher::class, \\Illuminate\\Bus\\Dispatcher::class);\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $sync->setContainer($container);\n\n        SyncQueue::createPayloadUsing(function ($connection, $queue, $payload) {\n            return ['data' => ['extra' => 'extraValue']];\n        });\n\n        try {\n            $sync->push(new FailingSyncQueueJob());\n        } catch (LogicException) {\n            $this->assertSame('extraValue', $_SERVER['__sync.failed']);\n        }\n    }\n\n    public function testCreatesPayloadObject()\n    {\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Events\\Dispatcher::class, \\Illuminate\\Events\\Dispatcher::class);\n        $container->bind(\\Illuminate\\Contracts\\Bus\\Dispatcher::class, \\Illuminate\\Bus\\Dispatcher::class);\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $sync->setContainer($container);\n\n        SyncQueue::createPayloadUsing(function ($connection, $queue, $payload) {\n            return ['data' => ['extra' => 'extraValue']];\n        });\n\n        try {\n            $sync->push(new SyncQueueJob());\n        } catch (LogicException $e) {\n            $this->assertSame('extraValue', $e->getMessage());\n        }\n    }\n\n    public function testItAddsATransactionCallbackForAfterCommitJobs()\n    {\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $transactionManager = m::mock(DatabaseTransactionsManager::class);\n        $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n        $transactionManager->shouldNotReceive('addCallbackForRollback');\n        $container->instance('db.transactions', $transactionManager);\n\n        $sync->setContainer($container);\n        $sync->push(new SyncQueueAfterCommitJob());\n    }\n\n    public function testItAddsATransactionCallbackForInterfaceBasedAfterCommitJobs()\n    {\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $transactionManager = m::mock(DatabaseTransactionsManager::class);\n        $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n        $transactionManager->shouldNotReceive('addCallbackForRollback');\n        $container->instance('db.transactions', $transactionManager);\n\n        $sync->setContainer($container);\n        $sync->push(new SyncQueueAfterCommitInterfaceJob());\n    }\n\n    public function testItAddsATransactionCallbackForAfterCommitUniqueJobs()\n    {\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $transactionManager = m::mock(DatabaseTransactionsManager::class);\n        $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n        $transactionManager->shouldReceive('addCallbackForRollback')->once()->andReturn(null);\n        $container->instance('db.transactions', $transactionManager);\n\n        $sync->setContainer($container);\n        $sync->push(new SyncQueueAfterCommitUniqueJob());\n    }\n\n    public function testItAddsATransactionCallbackForInterfaceBasedAfterCommitUniqueJobs()\n    {\n        $sync = new SyncQueue;\n        $container = new Container;\n        $container->bind(\\Illuminate\\Contracts\\Container\\Container::class, \\Illuminate\\Container\\Container::class);\n        $transactionManager = m::mock(DatabaseTransactionsManager::class);\n        $transactionManager->shouldReceive('addCallback')->once()->andReturn(null);\n        $transactionManager->shouldReceive('addCallbackForRollback')->once()->andReturn(null);\n        $container->instance('db.transactions', $transactionManager);\n\n        $sync->setContainer($container);\n        $sync->push(new SyncQueueAfterCommitInterfaceUniqueJob());\n    }\n}\n\nclass SyncQueueTestEntity implements QueueableEntity\n{\n    public function getQueueableId()\n    {\n        return 1;\n    }\n\n    public function getQueueableConnection()\n    {\n        //\n    }\n\n    public function getQueueableRelations()\n    {\n        //\n    }\n}\n\nclass SyncQueueTestHandler\n{\n    public function fire($job, $data)\n    {\n        $_SERVER['__sync.test'] = func_get_args();\n    }\n}\n\nclass FailingSyncQueueTestHandler\n{\n    public function fire($job, $data)\n    {\n        throw new Exception;\n    }\n\n    public function failed()\n    {\n        $_SERVER['__sync.failed'] = true;\n    }\n}\n\nclass FailingSyncQueueJob implements ShouldQueue\n{\n    use InteractsWithQueue;\n\n    public function handle()\n    {\n        throw new LogicException();\n    }\n\n    public function failed()\n    {\n        $payload = $this->job->payload();\n\n        $_SERVER['__sync.failed'] = $payload['data']['extra'];\n    }\n}\n\nclass SyncQueueJob implements ShouldQueue\n{\n    use InteractsWithQueue;\n\n    public function handle()\n    {\n        throw new LogicException($this->getValueFromJob('extra'));\n    }\n\n    public function getValueFromJob($key)\n    {\n        $payload = $this->job->payload();\n\n        return $payload['data'][$key] ?? null;\n    }\n}\n\nclass SyncQueueAfterCommitJob\n{\n    use InteractsWithQueue;\n\n    public $afterCommit = true;\n\n    public function handle()\n    {\n    }\n}\n\nclass SyncQueueAfterCommitInterfaceJob implements ShouldQueueAfterCommit\n{\n    use InteractsWithQueue;\n\n    public function handle()\n    {\n    }\n}\n\nclass SyncQueueAfterCommitUniqueJob implements ShouldBeUnique\n{\n    use InteractsWithQueue;\n\n    public $afterCommit = true;\n\n    public function handle()\n    {\n    }\n}\n\nclass SyncQueueAfterCommitInterfaceUniqueJob implements ShouldBeUnique, ShouldQueueAfterCommit\n{\n    use InteractsWithQueue;\n\n    public function handle()\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Queue/QueueWorkerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Queue;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Debug\\ExceptionHandler;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Contracts\\Queue\\Job as QueueJobContract;\nuse Illuminate\\Queue\\Events\\JobExceptionOccurred;\nuse Illuminate\\Queue\\Events\\JobPopped;\nuse Illuminate\\Queue\\Events\\JobPopping;\nuse Illuminate\\Queue\\Events\\JobProcessed;\nuse Illuminate\\Queue\\Events\\JobProcessing;\nuse Illuminate\\Queue\\Events\\JobReleasedAfterException;\nuse Illuminate\\Queue\\Events\\WorkerStarting;\nuse Illuminate\\Queue\\Events\\WorkerStopping;\nuse Illuminate\\Queue\\MaxAttemptsExceededException;\nuse Illuminate\\Queue\\QueueManager;\nuse Illuminate\\Queue\\Worker;\nuse Illuminate\\Queue\\WorkerOptions;\nuse Illuminate\\Queue\\WorkerStopReason;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass QueueWorkerTest extends TestCase\n{\n    public $events;\n    public $exceptionHandler;\n    public $maintenanceFlags;\n\n    protected function setUp(): void\n    {\n        $this->events = m::spy(Dispatcher::class);\n        $this->exceptionHandler = m::spy(ExceptionHandler::class);\n\n        Container::setInstance($container = new Container);\n\n        $container->instance(Dispatcher::class, $this->events);\n        $container->instance(ExceptionHandler::class, $this->exceptionHandler);\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow();\n\n        Container::setInstance();\n\n        parent::tearDown();\n    }\n\n    public function testJobCanBeFired()\n    {\n        $worker = $this->getWorker('default', ['queue' => [$job = new WorkerFakeJob]]);\n        $worker->runNextJob('default', 'queue', new WorkerOptions);\n        $this->assertTrue($job->fired);\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobPopping::class))->once();\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobPopped::class))->once();\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessing::class))->once();\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessed::class))->once();\n    }\n\n    public function testJobPoppingEvent()\n    {\n        $worker = $this->getWorker('default', ['queue' => [$job = new WorkerFakeJob]]);\n        $worker->runNextJob('default', 'queue', new WorkerOptions);\n        $this->assertTrue($job->fired);\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::on(function ($event) {\n            return $event instanceof JobPopping\n                && $event->connectionName === 'default'\n                && $event->queue === 'queue';\n        }))->once();\n    }\n\n    public function testWorkerCanWorkUntilQueueIsEmpty()\n    {\n        $workerOptions = new WorkerOptions;\n        $workerOptions->stopWhenEmpty = true;\n\n        $worker = $this->getWorker('default', ['queue' => [\n            $firstJob = new WorkerFakeJob,\n            $secondJob = new WorkerFakeJob,\n        ]]);\n\n        $status = $worker->daemon('default', 'queue', $workerOptions);\n\n        $this->assertTrue($secondJob->fired);\n\n        $this->assertSame(0, $status);\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessing::class))->twice();\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessed::class))->twice();\n    }\n\n    public function testWorkerStopsWhenMemoryExceeded()\n    {\n        $workerOptions = new WorkerOptions;\n\n        $worker = $this->getWorker('default', ['queue' => [\n            $firstJob = new WorkerFakeJob,\n            $secondJob = new WorkerFakeJob,\n        ]]);\n        $worker->stopOnMemoryExceeded = true;\n\n        $status = $worker->daemon('default', 'queue', $workerOptions);\n\n        $this->assertTrue($firstJob->fired);\n        $this->assertFalse($secondJob->fired);\n        $this->assertSame(12, $status);\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessing::class))->once();\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessed::class))->once();\n    }\n\n    public function testWorkerMemoryExceededWhenMemoryIsZero()\n    {\n        $worker = new Worker(...$this->workerDependencies());\n        $this->assertFalse($worker->memoryExceeded(0));\n    }\n\n    public function testWorkerMemoryExceededWhenMemoryGreaterThanZero()\n    {\n        $worker = new Worker(...$this->workerDependencies());\n        $this->assertTrue($worker->memoryExceeded(1));\n    }\n\n    public function testWorkerMemoryExceededWhenMemoryIsNegative()\n    {\n        $worker = new Worker(...$this->workerDependencies());\n        $this->assertFalse($worker->memoryExceeded(-1));\n    }\n\n    public function testJobCanBeFiredBasedOnPriority()\n    {\n        $worker = $this->getWorker('default', [\n            'high' => [$highJob = new WorkerFakeJob, $secondHighJob = new WorkerFakeJob], 'low' => [$lowJob = new WorkerFakeJob],\n        ]);\n\n        $worker->runNextJob('default', 'high,low', new WorkerOptions);\n        $this->assertTrue($highJob->fired);\n        $this->assertFalse($secondHighJob->fired);\n        $this->assertFalse($lowJob->fired);\n\n        $worker->runNextJob('default', 'high,low', new WorkerOptions);\n        $this->assertTrue($secondHighJob->fired);\n        $this->assertFalse($lowJob->fired);\n\n        $worker->runNextJob('default', 'high,low', new WorkerOptions);\n        $this->assertTrue($lowJob->fired);\n    }\n\n    public function testExceptionIsReportedIfConnectionThrowsExceptionOnJobPop()\n    {\n        $worker = new InsomniacWorker(\n            new WorkerFakeManager('default', new BrokenQueueConnection('default', $e = new RuntimeException)),\n            $this->events,\n            $this->exceptionHandler,\n            function () {\n                return false;\n            }\n        );\n\n        $worker->runNextJob('default', 'queue', $this->workerOptions());\n\n        $this->exceptionHandler->shouldHaveReceived('report')->with($e);\n    }\n\n    public function testWorkerSleepsWhenQueueIsEmpty()\n    {\n        $worker = $this->getWorker('default', ['queue' => []]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['sleep' => 5]));\n        $this->assertEquals(5, $worker->sleptFor);\n    }\n\n    public function testJobIsReleasedOnException()\n    {\n        $e = new RuntimeException;\n\n        $job = new WorkerFakeJob(function () use ($e) {\n            throw $e;\n        });\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['backoff' => 10]));\n\n        $this->assertEquals(10, $job->releaseAfter);\n        $this->assertFalse($job->deleted);\n        $this->exceptionHandler->shouldHaveReceived('report')->with($e);\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobExceptionOccurred::class))->once();\n        $this->events->shouldNotHaveReceived('dispatch', [m::type(JobProcessed::class)]);\n    }\n\n    public function testJobIsNotReleasedIfItHasExceededMaxAttempts()\n    {\n        $e = new RuntimeException;\n\n        $job = new WorkerFakeJob(function ($job) use ($e) {\n            // In normal use this would be incremented by being popped off the queue\n            $job->attempts++;\n\n            throw $e;\n        });\n        $job->attempts = 1;\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['maxTries' => 1]));\n\n        $this->assertNull($job->releaseAfter);\n        $this->assertTrue($job->deleted);\n        $this->assertEquals($e, $job->failedWith);\n        $this->exceptionHandler->shouldHaveReceived('report')->with($e);\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobExceptionOccurred::class))->once();\n        $this->events->shouldNotHaveReceived('dispatch', [m::type(JobProcessed::class)]);\n    }\n\n    public function testJobIsNotReleasedIfItHasExpired()\n    {\n        $e = new RuntimeException;\n\n        $job = new WorkerFakeJob(function ($job) use ($e) {\n            // In normal use this would be incremented by being popped off the queue\n            $job->attempts++;\n\n            throw $e;\n        });\n\n        $job->retryUntil = Carbon::now()->addSeconds(1)->getTimestamp();\n\n        $job->attempts = 0;\n\n        Carbon::setTestNow(\n            Carbon::now()->addSeconds(1)\n        );\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions());\n\n        $this->assertNull($job->releaseAfter);\n        $this->assertTrue($job->deleted);\n        $this->assertEquals($e, $job->failedWith);\n        $this->exceptionHandler->shouldHaveReceived('report')->with($e);\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobExceptionOccurred::class))->once();\n        $this->events->shouldNotHaveReceived('dispatch', [m::type(JobProcessed::class)]);\n    }\n\n    public function testJobIsFailedIfItHasAlreadyExceededMaxAttempts()\n    {\n        $job = new WorkerFakeJob(function ($job) {\n            $job->attempts++;\n        });\n\n        $job->attempts = 2;\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['maxTries' => 1]));\n\n        $this->assertNull($job->releaseAfter);\n        $this->assertTrue($job->deleted);\n        $this->assertInstanceOf(MaxAttemptsExceededException::class, $job->failedWith);\n        $this->exceptionHandler->shouldHaveReceived('report')->with(m::type(MaxAttemptsExceededException::class));\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobExceptionOccurred::class))->once();\n        $this->events->shouldNotHaveReceived('dispatch', [m::type(JobProcessed::class)]);\n    }\n\n    public function testJobIsFailedIfItHasAlreadyExpired()\n    {\n        $job = new WorkerFakeJob(function ($job) {\n            $job->attempts++;\n        });\n\n        $job->retryUntil = Carbon::now()->addSeconds(2)->getTimestamp();\n\n        $job->attempts = 1;\n\n        Carbon::setTestNow(\n            Carbon::now()->addSeconds(3)\n        );\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions());\n\n        $this->assertNull($job->releaseAfter);\n        $this->assertTrue($job->deleted);\n        $this->assertInstanceOf(MaxAttemptsExceededException::class, $job->failedWith);\n        $this->exceptionHandler->shouldHaveReceived('report')->with(m::type(MaxAttemptsExceededException::class));\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobExceptionOccurred::class))->once();\n        $this->events->shouldNotHaveReceived('dispatch', [m::type(JobProcessed::class)]);\n    }\n\n    public function testJobBasedMaxRetries()\n    {\n        $job = new WorkerFakeJob(function ($job) {\n            $job->attempts++;\n        });\n        $job->attempts = 2;\n\n        $job->maxTries = 10;\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['maxTries' => 1]));\n\n        $this->assertFalse($job->deleted);\n        $this->assertNull($job->failedWith);\n    }\n\n    public function testJobBasedFailedDelay()\n    {\n        $job = new WorkerFakeJob(function ($job) {\n            throw new Exception('Something went wrong.');\n        });\n\n        $job->attempts = 1;\n        $job->backoff = 10;\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['backoff' => 3, 'maxTries' => 0]));\n\n        $this->assertEquals(10, $job->releaseAfter);\n    }\n\n    public function testJobRunsIfAppIsNotInMaintenanceMode()\n    {\n        $firstJob = new WorkerFakeJob(function ($job) {\n            $job->attempts++;\n        });\n\n        $secondJob = new WorkerFakeJob(function ($job) {\n            $job->attempts++;\n        });\n\n        $this->maintenanceFlags = [false, true];\n\n        $maintenanceModeChecker = function () {\n            if ($this->maintenanceFlags) {\n                return array_shift($this->maintenanceFlags);\n            }\n\n            throw new LoopBreakerException;\n        };\n\n        $worker = $this->getWorker('default', ['queue' => [$firstJob, $secondJob]], $maintenanceModeChecker);\n\n        try {\n            $worker->daemon('default', 'queue', $this->workerOptions());\n\n            $this->fail('Expected LoopBreakerException to be thrown');\n        } catch (LoopBreakerException) {\n            $this->assertSame(1, $firstJob->attempts);\n\n            $this->assertSame(0, $secondJob->attempts);\n        }\n    }\n\n    public function testJobDoesNotFireIfDeleted()\n    {\n        $job = new WorkerFakeJob(function () {\n            return true;\n        });\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $job->delete();\n        $worker->runNextJob('default', 'queue', $this->workerOptions());\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(JobProcessed::class))->once();\n        $this->assertFalse($job->hasFailed());\n        $this->assertFalse($job->isReleased());\n        $this->assertTrue($job->isDeleted());\n    }\n\n    public function testWorkerPicksJobUsingCustomCallbacks()\n    {\n        $worker = $this->getWorker('default', [\n            'default' => [$defaultJob = new WorkerFakeJob], 'custom' => [$customJob = new WorkerFakeJob],\n        ]);\n\n        $worker->runNextJob('default', 'default', new WorkerOptions);\n        $worker->runNextJob('default', 'default', new WorkerOptions);\n\n        $this->assertTrue($defaultJob->fired);\n        $this->assertFalse($customJob->fired);\n\n        $worker2 = $this->getWorker('default', [\n            'default' => [$defaultJob = new WorkerFakeJob], 'custom' => [$customJob = new WorkerFakeJob],\n        ]);\n\n        $worker2->setName('myworker');\n\n        Worker::popUsing('myworker', function ($pop) {\n            return $pop('custom');\n        });\n\n        $worker2->runNextJob('default', 'default', new WorkerOptions);\n        $worker2->runNextJob('default', 'default', new WorkerOptions);\n\n        $this->assertFalse($defaultJob->fired);\n        $this->assertTrue($customJob->fired);\n\n        Worker::popUsing('myworker', null);\n    }\n\n    public function testWorkerStartingIsDispatched()\n    {\n        $workerOptions = new WorkerOptions();\n        $workerOptions->stopWhenEmpty = true;\n\n        $worker = $this->getWorker('default', ['queue' => [\n            $firstJob = new WorkerFakeJob(),\n            $secondJob = new WorkerFakeJob(),\n        ]]);\n\n        $worker->daemon('default', 'queue', $workerOptions);\n\n        $this->assertTrue($firstJob->fired);\n        $this->assertTrue($secondJob->fired);\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::type(WorkerStarting::class))->once();\n    }\n\n    public function testWorkerStoppingIsDispatched()\n    {\n        $workerOptions = new WorkerOptions();\n        $workerOptions->stopWhenEmpty = true;\n\n        $worker = $this->getWorker('default', ['queue' => [\n            $firstJob = new WorkerFakeJob(),\n            $secondJob = new WorkerFakeJob(),\n        ]]);\n\n        $worker->daemon('default', 'queue', $workerOptions);\n\n        $this->assertTrue($firstJob->fired);\n        $this->assertTrue($secondJob->fired);\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::on(function ($event) use ($workerOptions) {\n            return $event instanceof WorkerStopping\n                && $event->status === 0\n                && $event->workerOptions === $workerOptions\n                && $event->reason === WorkerStopReason::QueueEmpty;\n        }));\n    }\n\n    public function testJobReleasedEvent()\n    {\n        $e = new RuntimeException;\n\n        $job = new WorkerFakeJob(function () use ($e) {\n            throw $e;\n        });\n\n        $worker = $this->getWorker('default', ['queue' => [$job]]);\n        $worker->runNextJob('default', 'queue', $this->workerOptions(['backoff' => 10]));\n\n        $this->events->shouldHaveReceived('dispatch')->with(m::on(function ($event) use ($job) {\n            return $event instanceof JobReleasedAfterException\n                && $event->connectionName === 'default'\n                && $event->job === $job\n                && $event->backoff === 10;\n        }))->once();\n    }\n\n    /**\n     * Helpers...\n     */\n    private function getWorker($connectionName = 'default', $jobs = [], ?callable $isInMaintenanceMode = null)\n    {\n        return new InsomniacWorker(\n            ...$this->workerDependencies($connectionName, $jobs, $isInMaintenanceMode)\n        );\n    }\n\n    private function workerDependencies($connectionName = 'default', $jobs = [], ?callable $isInMaintenanceMode = null)\n    {\n        return [\n            new WorkerFakeManager($connectionName, new WorkerFakeConnection($connectionName, $jobs)),\n            $this->events,\n            $this->exceptionHandler,\n            $isInMaintenanceMode ?? function () {\n                return false;\n            },\n        ];\n    }\n\n    private function workerOptions(array $overrides = [])\n    {\n        $options = new WorkerOptions;\n\n        foreach ($overrides as $key => $value) {\n            $options->{$key} = $value;\n        }\n\n        return $options;\n    }\n}\n\n/**\n * Fakes.\n */\nclass InsomniacWorker extends Worker\n{\n    public $sleptFor;\n    public $stopOnMemoryExceeded = false;\n\n    public function sleep($seconds)\n    {\n        $this->sleptFor = $seconds;\n    }\n\n    public function stop($status = 0, $options = null, $reason = null)\n    {\n        return parent::stop($status, $options, $reason);\n    }\n\n    public function daemonShouldRun(WorkerOptions $options, $connectionName, $queue)\n    {\n        return ! ($this->isDownForMaintenance)();\n    }\n\n    public function memoryExceeded($memoryLimit)\n    {\n        return $this->stopOnMemoryExceeded;\n    }\n}\n\nclass WorkerFakeManager extends QueueManager\n{\n    public $connections = [];\n\n    public function __construct($name, $connection)\n    {\n        $this->connections[$name] = $connection;\n    }\n\n    public function connection($name = null)\n    {\n        return $this->connections[$name];\n    }\n}\n\nclass WorkerFakeConnection\n{\n    public $connectionName;\n    public $jobs = [];\n\n    public function __construct($connectionName, $jobs)\n    {\n        $this->connectionName = $connectionName;\n        $this->jobs = $jobs;\n    }\n\n    public function pop($queue)\n    {\n        return array_shift($this->jobs[$queue]);\n    }\n\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n}\n\nclass BrokenQueueConnection\n{\n    public $connectionName;\n    public $exception;\n\n    public function __construct($connectionName, $exception)\n    {\n        $this->connectionName = $connectionName;\n        $this->exception = $exception;\n    }\n\n    public function pop($queue)\n    {\n        throw $this->exception;\n    }\n\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n}\n\nclass WorkerFakeJob implements QueueJobContract\n{\n    public $id = '';\n    public $fired = false;\n    public $callback;\n    public $deleted = false;\n    public $releaseAfter;\n    public $released = false;\n    public $maxTries;\n    public $maxExceptions;\n    public $shouldFailOnTimeout = false;\n    public $uuid;\n    public $backoff;\n    public $retryUntil;\n    public $attempts = 0;\n    public $failedWith;\n    public $failed = false;\n    public $connectionName = '';\n    public $queue = '';\n    public $rawBody = '';\n\n    public function __construct($callback = null)\n    {\n        $this->callback = $callback ?: function () {\n            //\n        };\n    }\n\n    public function getJobId()\n    {\n        return $this->id;\n    }\n\n    public function fire()\n    {\n        $this->fired = true;\n        $this->callback->__invoke($this);\n    }\n\n    public function payload()\n    {\n        return [];\n    }\n\n    public function maxTries()\n    {\n        return $this->maxTries;\n    }\n\n    public function maxExceptions()\n    {\n        return $this->maxExceptions;\n    }\n\n    public function shouldFailOnTimeout()\n    {\n        return $this->shouldFailOnTimeout;\n    }\n\n    public function uuid()\n    {\n        return $this->uuid;\n    }\n\n    public function backoff()\n    {\n        return $this->backoff;\n    }\n\n    public function retryUntil()\n    {\n        return $this->retryUntil;\n    }\n\n    public function delete()\n    {\n        $this->deleted = true;\n    }\n\n    public function isDeleted()\n    {\n        return $this->deleted;\n    }\n\n    public function release($delay = 0)\n    {\n        $this->released = true;\n\n        $this->releaseAfter = $delay;\n    }\n\n    public function isReleased()\n    {\n        return $this->released;\n    }\n\n    public function isDeletedOrReleased()\n    {\n        return $this->deleted || $this->released;\n    }\n\n    public function attempts()\n    {\n        return $this->attempts;\n    }\n\n    public function markAsFailed()\n    {\n        $this->failed = true;\n    }\n\n    public function fail($e = null)\n    {\n        $this->markAsFailed();\n\n        $this->delete();\n\n        $this->failedWith = $e;\n    }\n\n    public function hasFailed()\n    {\n        return $this->failed;\n    }\n\n    public function getName()\n    {\n        return 'WorkerFakeJob';\n    }\n\n    public function resolveName()\n    {\n        return $this->getName();\n    }\n\n    public function getConnectionName()\n    {\n        return $this->connectionName;\n    }\n\n    public function getQueue()\n    {\n        return $this->queue;\n    }\n\n    public function getRawBody()\n    {\n        return $this->rawBody;\n    }\n\n    public function timeout()\n    {\n        return time() + 60;\n    }\n\n    public function resolveQueuedJobClass()\n    {\n        return 'WorkerFakeJob';\n    }\n}\n\nclass LoopBreakerException extends RuntimeException\n{\n    //\n}\n"
  },
  {
    "path": "tests/Redis/ConcurrentLimiterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Error;\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\Limiters\\ConcurrencyLimiter;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nclass ConcurrentLimiterTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testItLocksTasksWhenNoSlotAvailable()\n    {\n        $store = [];\n\n        foreach (range(1, 2) as $i) {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'key', 2, 5))->block(2, function () use (&$store, $i) {\n                $store[] = $i;\n            });\n        }\n\n        try {\n            (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'key', 2, 5))->block(0, function () use (&$store) {\n                $store[] = 3;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'other_key', 2, 5))->block(2, function () use (&$store) {\n            $store[] = 4;\n        });\n\n        $this->assertEquals([1, 2, 4], $store);\n    }\n\n    public function testItReleasesLockAfterTaskFinishes()\n    {\n        $store = [];\n\n        foreach (range(1, 4) as $i) {\n            (new ConcurrencyLimiter($this->redis(), 'key', 2, 5))->block(2, function () use (&$store, $i) {\n                $store[] = $i;\n            });\n        }\n\n        $this->assertEquals([1, 2, 3, 4], $store);\n    }\n\n    public function testItReleasesLockIfTaskTookTooLong()\n    {\n        $store = [];\n\n        $lock = (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'key', 1, 1));\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(0, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        usleep(1.2 * 1000000);\n\n        $lock->block(0, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 3], $store);\n    }\n\n    public function testItFailsImmediatelyOrRetriesForAWhileBasedOnAGivenTimeout()\n    {\n        $store = [];\n\n        $lock = (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'key', 1, 2));\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(0, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        $lock->block(3, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 3], $store);\n    }\n\n    public function testItFailsAfterRetryTimeout()\n    {\n        $store = [];\n\n        $lock = (new ConcurrencyLimiterMockThatDoesntRelease($this->redis(), 'key', 1, 10));\n\n        $lock->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            $lock->block(2, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        $this->assertEquals([1], $store);\n    }\n\n    public function testItReleasesIfErrorIsThrown()\n    {\n        $store = [];\n\n        $lock = new ConcurrencyLimiter($this->redis(), 'key', 1, 5);\n\n        try {\n            $lock->block(1, function () {\n                throw new Error;\n            });\n        } catch (Error) {\n        }\n\n        $lock = new ConcurrencyLimiter($this->redis(), 'key', 1, 5);\n        $lock->block(1, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        $this->assertEquals([1], $store);\n    }\n\n    private function redis()\n    {\n        return $this->redis['phpredis']->connection();\n    }\n}\n\nclass ConcurrencyLimiterMockThatDoesntRelease extends ConcurrencyLimiter\n{\n    protected function release($key, $id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Redis/Connections/PhpRedisClusterConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis\\Connections;\n\nuse Illuminate\\Redis\\Connections\\PhpRedisClusterConnection;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\n\n#[RequiresPhpExtension('redis')]\nclass PhpRedisClusterConnectionTest extends TestCase\n{\n    public function testItScansUsingDefaultNode()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([['127.0.0.1', '6379']]);\n        $client->shouldReceive('scan')\n            ->once()\n            ->with(0, ['127.0.0.1', '6379'], '*', 10)\n            ->andReturn(['key']);\n\n        $connection = new PhpRedisClusterConnection($client);\n        $this->assertEquals([0, ['key']], $connection->scan(0));\n    }\n\n    public function testItOnlyFetchesDefaultNodeOnce()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([['127.0.0.1', '6379']]);\n        $client->shouldReceive('scan')->twice();\n\n        $connection = new PhpRedisClusterConnection($client);\n        $connection->scan(0);\n        $connection->scan(0);\n    }\n\n    public function testItScansUsingOptionNode()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('scan')\n            ->once()\n            ->with(0, 'option-node', '*', 10)\n            ->andReturn(['key']);\n\n        $connection = new PhpRedisClusterConnection($client);\n        $this->assertEquals([0, ['key']], $connection->scan(0, ['node' => 'option-node']));\n    }\n\n    public function testItThrowsExceptionWithoutNodes()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([]);\n        $client->shouldReceive('scan');\n\n        $this->expectExceptionMessage('Unable to determine default node. No master nodes found in the cluster.');\n\n        $connection = new PhpRedisClusterConnection($client);\n        $connection->scan(0);\n    }\n\n    public function testItReturnsFalseWhenCursorIsZeroAndResultIsEmpty()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([['127.0.0.1', '6379']]);\n        $client->shouldReceive('scan')\n            ->once()\n            ->with(0, ['127.0.0.1', '6379'], '*', 10)\n            ->andReturn(false);\n\n        $connection = new PhpRedisClusterConnection($client);\n        $this->assertFalse($connection->scan(0));\n    }\n\n    public function testItFlushesAllMasterNodes()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([\n            ['127.0.0.1', '6379'],\n            ['127.0.0.2', '6379'],\n        ]);\n        $client->shouldReceive('flushdb')->once()->with(['127.0.0.1', '6379']);\n        $client->shouldReceive('flushdb')->once()->with(['127.0.0.2', '6379']);\n\n        $connection = new PhpRedisClusterConnection($client);\n        $connection->flushdb();\n    }\n\n    public function testItFlushesAllMasterNodesAsync()\n    {\n        $client = m::mock(\\RedisCluster::class);\n        $client->shouldReceive('_masters')->once()->andReturn([\n            ['127.0.0.1', '6379'],\n            ['127.0.0.2', '6379'],\n        ]);\n        $client->shouldReceive('rawCommand')->once()->with(['127.0.0.1', '6379'], 'flushdb', 'async');\n        $client->shouldReceive('rawCommand')->once()->with(['127.0.0.2', '6379'], 'flushdb', 'async');\n\n        $connection = new PhpRedisClusterConnection($client);\n        $connection->flushdb('ASYNC');\n    }\n}\n"
  },
  {
    "path": "tests/Redis/DurationLimiterTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Illuminate\\Contracts\\Redis\\LimiterTimeoutException;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\Limiters\\DurationLimiter;\nuse PHPUnit\\Framework\\TestCase;\nuse Throwable;\n\nclass DurationLimiterTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testItLocksTasksWhenNoSlotAvailable()\n    {\n        $store = [];\n\n        (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {\n            $store[] = 2;\n        });\n\n        try {\n            (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {\n                $store[] = 3;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        $this->assertEquals([1, 2], $store);\n\n        sleep(2);\n\n        (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 2, 3], $store);\n    }\n\n    public function testItFailsImmediatelyOrRetriesForAWhileBasedOnAGivenTimeout()\n    {\n        $store = [];\n\n        (new DurationLimiter($this->redis(), 'key', 1, 1))->block(2, function () use (&$store) {\n            $store[] = 1;\n        });\n\n        try {\n            (new DurationLimiter($this->redis(), 'key', 1, 1))->block(0, function () use (&$store) {\n                $store[] = 2;\n            });\n        } catch (Throwable $e) {\n            $this->assertInstanceOf(LimiterTimeoutException::class, $e);\n        }\n\n        (new DurationLimiter($this->redis(), 'key', 1, 1))->block(2, function () use (&$store) {\n            $store[] = 3;\n        });\n\n        $this->assertEquals([1, 3], $store);\n    }\n\n    public function testItReturnsTheCallbackResult()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'key', 1, 1);\n\n        $result = $limiter->block(1, function () {\n            return 'foo';\n        });\n\n        $this->assertSame('foo', $result);\n    }\n\n    public function testAcquireSetsDecaysAtAndRemaining()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'acquire-key', 2, 2);\n\n        $acquired1 = $limiter->acquire();\n        $this->assertTrue($acquired1);\n        $this->assertGreaterThanOrEqual(time(), $limiter->decaysAt);\n        $this->assertSame(1, $limiter->remaining);\n\n        $acquired2 = $limiter->acquire();\n        $this->assertTrue($acquired2);\n        $this->assertSame(0, $limiter->remaining);\n\n        $acquired3 = $limiter->acquire();\n        $this->assertFalse($acquired3);\n        $this->assertSame(0, $limiter->remaining);\n    }\n\n    public function testTooManyAttemptsReportsCorrectly()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'too-many-key', 2, 1);\n\n        // Initially, should not have too many attempts\n        $this->assertFalse($limiter->tooManyAttempts());\n        $this->assertSame(0, $limiter->decaysAt); // As per script for non-existing key\n        $this->assertGreaterThan(0, $limiter->remaining); // Remaining is positive future timestamp placeholder\n\n        // Use up the available slots\n        $this->assertTrue($limiter->acquire());\n        $this->assertTrue($limiter->acquire());\n\n        // Now, too many attempts within the same window\n        $this->assertTrue($limiter->tooManyAttempts());\n        $this->assertSame(0, max(0, $limiter->remaining));\n\n        // After decay window, attempts should be allowed again\n        sleep(1);\n        $this->assertFalse($limiter->tooManyAttempts());\n    }\n\n    public function testClearResetsLimiter()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'clear-key', 1, 2);\n\n        $this->assertTrue($limiter->acquire());\n        $this->assertFalse($limiter->acquire());\n\n        // Clear and try again\n        $limiter->clear();\n        $this->assertTrue($limiter->acquire());\n    }\n\n    public function testBlockReturnsTrueWithoutCallback()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'no-callback-key', 1, 1);\n\n        $this->assertTrue($limiter->block(1));\n    }\n\n    public function testAcquireResetsAfterDecay()\n    {\n        $limiter = new DurationLimiter($this->redis(), 'reset-after-decay-key', 1, 1);\n\n        $this->assertTrue($limiter->acquire());\n        $this->assertFalse($limiter->acquire());\n\n        sleep(1);\n\n        $this->assertTrue($limiter->acquire());\n        $this->assertSame(0, $limiter->remaining);\n    }\n\n    private function redis()\n    {\n        return $this->redis['phpredis']->connection();\n    }\n}\n"
  },
  {
    "path": "tests/Redis/RedisConnectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\Connections\\Connection;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Redis\\RedisManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Predis\\Client;\nuse Redis;\n\nclass RedisConnectionTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testItSetsValuesWithExpiry()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('one', 'mohamed', 'EX', 5, 'NX');\n            $this->assertSame('mohamed', $redis->get('one'));\n            $this->assertNotEquals(-1, $redis->ttl('one'));\n\n            // It doesn't override when NX mode\n            $redis->set('one', 'taylor', 'EX', 5, 'NX');\n            $this->assertSame('mohamed', $redis->get('one'));\n\n            // It overrides when XX mode\n            $redis->set('one', 'taylor', 'EX', 5, 'XX');\n            $this->assertSame('taylor', $redis->get('one'));\n\n            // It fails if XX mode is on and key doesn't exist\n            $redis->set('two', 'taylor', 'PX', 5, 'XX');\n            $this->assertNull($redis->get('two'));\n\n            $redis->set('three', 'mohamed', 'PX', 5000);\n            $this->assertSame('mohamed', $redis->get('three'));\n            $this->assertNotEquals(-1, $redis->ttl('three'));\n            $this->assertNotEquals(-1, $redis->pttl('three'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItDeletesKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('one', 'mohamed');\n            $redis->set('two', 'mohamed');\n            $redis->set('three', 'mohamed');\n\n            $redis->del('one');\n            $this->assertNull($redis->get('one'));\n            $this->assertNotNull($redis->get('two'));\n            $this->assertNotNull($redis->get('three'));\n\n            $redis->del('two', 'three');\n            $this->assertNull($redis->get('two'));\n            $this->assertNull($redis->get('three'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItChecksForExistence()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('one', 'mohamed');\n            $redis->set('two', 'mohamed');\n\n            $this->assertEquals(1, $redis->exists('one'));\n            $this->assertEquals(0, $redis->exists('nothing'));\n            $this->assertEquals(2, $redis->exists('one', 'two'));\n            $this->assertEquals(2, $redis->exists('one', 'two', 'nothing'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItExpiresKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('one', 'mohamed');\n            $this->assertEquals(-1, $redis->ttl('one'));\n            $this->assertEquals(1, $redis->expire('one', 10));\n            $this->assertNotEquals(-1, $redis->ttl('one'));\n\n            $this->assertEquals(0, $redis->expire('nothing', 10));\n\n            $redis->set('two', 'mohamed');\n            $this->assertEquals(-1, $redis->ttl('two'));\n            $this->assertEquals(1, $redis->pexpire('two', 10));\n            $this->assertNotEquals(-1, $redis->pttl('two'));\n\n            $this->assertEquals(0, $redis->pexpire('nothing', 10));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRenamesKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('one', 'mohamed');\n            $redis->rename('one', 'two');\n            $this->assertNull($redis->get('one'));\n            $this->assertSame('mohamed', $redis->get('two'));\n\n            $redis->set('three', 'adam');\n            $redis->renamenx('two', 'three');\n            $this->assertSame('mohamed', $redis->get('two'));\n            $this->assertSame('adam', $redis->get('three'));\n\n            $redis->renamenx('two', 'four');\n            $this->assertNull($redis->get('two'));\n            $this->assertSame('mohamed', $redis->get('four'));\n            $this->assertSame('adam', $redis->get('three'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItAddsMembersToSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', 1, 'mohamed');\n            $this->assertEquals(1, $redis->zcard('set'));\n\n            $redis->zadd('set', 2, 'taylor', 3, 'adam');\n            $this->assertEquals(3, $redis->zcard('set'));\n\n            $redis->zadd('set', ['jeffrey' => 4, 'matt' => 5]);\n            $this->assertEquals(5, $redis->zcard('set'));\n\n            $redis->zadd('set', 'NX', 1, 'beric');\n            $this->assertEquals(6, $redis->zcard('set'));\n\n            $redis->zadd('set', 'NX', ['joffrey' => 1]);\n            $this->assertEquals(7, $redis->zcard('set'));\n\n            $redis->zadd('set', 'XX', ['ned' => 1]);\n            $this->assertEquals(7, $redis->zcard('set'));\n\n            $this->assertEquals(1, $redis->zadd('set', ['sansa' => 10]));\n            $this->assertEquals(0, $redis->zadd('set', 'XX', 'CH', ['arya' => 11]));\n\n            $redis->zadd('set', ['mohamed' => 100]);\n            $this->assertEquals(100, $redis->zscore('set', 'mohamed'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItCountsMembersInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 10]);\n\n            $this->assertEquals(1, $redis->zcount('set', 1, 5));\n            $this->assertEquals(2, $redis->zcount('set', '-inf', '+inf'));\n            $this->assertEquals(2, $redis->zcard('set'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItIncrementsScoreOfSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 10]);\n            $redis->zincrby('set', 2, 'jeffrey');\n            $this->assertEquals(3, $redis->zscore('set', 'jeffrey'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItSetsKeyIfNotExists()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('name', 'mohamed');\n\n            $this->assertSame(0, $redis->setnx('name', 'taylor'));\n            $this->assertSame('mohamed', $redis->get('name'));\n\n            $this->assertSame(1, $redis->setnx('boss', 'taylor'));\n            $this->assertSame('taylor', $redis->get('boss'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItSetsHashFieldIfNotExists()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->hset('person', 'name', 'mohamed');\n\n            $this->assertSame(0, $redis->hsetnx('person', 'name', 'taylor'));\n            $this->assertSame('mohamed', $redis->hget('person', 'name'));\n\n            $this->assertSame(1, $redis->hsetnx('person', 'boss', 'taylor'));\n            $this->assertSame('taylor', $redis->hget('person', 'boss'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItCalculatesIntersectionOfSortedSetsAndStores()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set1', ['jeffrey' => 1, 'matt' => 2, 'taylor' => 3]);\n            $redis->zadd('set2', ['jeffrey' => 2, 'matt' => 3]);\n\n            $redis->zinterstore('output', ['set1', 'set2']);\n            $this->assertEquals(2, $redis->zcard('output'));\n            $this->assertEquals(3, $redis->zscore('output', 'jeffrey'));\n            $this->assertEquals(5, $redis->zscore('output', 'matt'));\n\n            $redis->zinterstore('output2', ['set1', 'set2'], [\n                'weights' => [3, 2],\n                'aggregate' => 'sum',\n            ]);\n            $this->assertEquals(7, $redis->zscore('output2', 'jeffrey'));\n            $this->assertEquals(12, $redis->zscore('output2', 'matt'));\n\n            $redis->zinterstore('output3', ['set1', 'set2'], [\n                'weights' => [3, 2],\n                'aggregate' => 'min',\n            ]);\n            $this->assertEquals(3, $redis->zscore('output3', 'jeffrey'));\n            $this->assertEquals(6, $redis->zscore('output3', 'matt'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItCalculatesUnionOfSortedSetsAndStores()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set1', ['jeffrey' => 1, 'matt' => 2, 'taylor' => 3]);\n            $redis->zadd('set2', ['jeffrey' => 2, 'matt' => 3]);\n\n            $redis->zunionstore('output', ['set1', 'set2']);\n            $this->assertEquals(3, $redis->zcard('output'));\n            $this->assertEquals(3, $redis->zscore('output', 'jeffrey'));\n            $this->assertEquals(5, $redis->zscore('output', 'matt'));\n            $this->assertEquals(3, $redis->zscore('output', 'taylor'));\n\n            $redis->zunionstore('output2', ['set1', 'set2'], [\n                'weights' => [3, 2],\n                'aggregate' => 'sum',\n            ]);\n            $this->assertEquals(7, $redis->zscore('output2', 'jeffrey'));\n            $this->assertEquals(12, $redis->zscore('output2', 'matt'));\n            $this->assertEquals(9, $redis->zscore('output2', 'taylor'));\n\n            $redis->zunionstore('output3', ['set1', 'set2'], [\n                'weights' => [3, 2],\n                'aggregate' => 'min',\n            ]);\n            $this->assertEquals(3, $redis->zscore('output3', 'jeffrey'));\n            $this->assertEquals(6, $redis->zscore('output3', 'matt'));\n            $this->assertEquals(9, $redis->zscore('output3', 'taylor'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsRangeInSortedSet()\n    {\n        foreach ($this->connections() as $connector => $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n            $this->assertEquals(['jeffrey', 'matt'], $redis->zrange('set', 0, 1));\n            $this->assertEquals(['jeffrey', 'matt', 'taylor'], $redis->zrange('set', 0, -1));\n\n            if ($connector === 'predis') {\n                $this->assertEquals(['jeffrey' => 1, 'matt' => 5], $redis->zrange('set', 0, 1, 'withscores'));\n            } else {\n                $this->assertEquals(['jeffrey' => 1, 'matt' => 5], $redis->zrange('set', 0, 1, true));\n            }\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsRevRangeInSortedSet()\n    {\n        foreach ($this->connections() as $connector => $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n            $this->assertEquals(['taylor', 'matt'], $redis->ZREVRANGE('set', 0, 1));\n            $this->assertEquals(['taylor', 'matt', 'jeffrey'], $redis->ZREVRANGE('set', 0, -1));\n\n            if ($connector === 'predis') {\n                $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->ZREVRANGE('set', 0, 1, 'withscores'));\n            } else {\n                $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->ZREVRANGE('set', 0, 1, true));\n            }\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsRangeByScoreInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n            $this->assertEquals(['jeffrey'], $redis->zrangebyscore('set', 0, 3));\n            $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->zrangebyscore('set', 0, 11, [\n                'withscores' => true,\n                'limit' => [\n                    'offset' => 1,\n                    'count' => 2,\n                ],\n            ]));\n            $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->zrangebyscore('set', 0, 11, [\n                'withscores' => true,\n                'limit' => [1, 2],\n            ]));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsRevRangeByScoreInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n            $this->assertEquals(['taylor'], $redis->ZREVRANGEBYSCORE('set', 10, 6));\n            $this->assertEquals(['matt' => 5, 'jeffrey' => 1], $redis->ZREVRANGEBYSCORE('set', 10, 0, [\n                'withscores' => true,\n                'limit' => [\n                    'offset' => 1,\n                    'count' => 2,\n                ],\n            ]));\n            $this->assertEquals(['matt' => 5, 'jeffrey' => 1], $redis->ZREVRANGEBYSCORE('set', 10, 0, [\n                'withscores' => true,\n                'limit' => [1, 2],\n            ]));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsRankInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n\n            $this->assertEquals(0, $redis->zrank('set', 'jeffrey'));\n            $this->assertEquals(2, $redis->zrank('set', 'taylor'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItReturnsScoreInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);\n\n            $this->assertEquals(1, $redis->zscore('set', 'jeffrey'));\n            $this->assertEquals(10, $redis->zscore('set', 'taylor'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRemovesMembersInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);\n\n            $redis->zrem('set', 'jeffrey');\n            $this->assertEquals(3, $redis->zcard('set'));\n\n            $redis->zrem('set', 'matt', 'adam');\n            $this->assertEquals(1, $redis->zcard('set'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRemovesMembersByScoreInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);\n            $redis->ZREMRANGEBYSCORE('set', 5, '+inf');\n            $this->assertEquals(1, $redis->zcard('set'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRemovesMembersByRankInSortedSet()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);\n            $redis->ZREMRANGEBYRANK('set', 1, -1);\n            $this->assertEquals(1, $redis->zcard('set'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItSetsMultipleHashFields()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->hmset('hash', ['name' => 'mohamed', 'hobby' => 'diving']);\n            $this->assertEquals(['name' => 'mohamed', 'hobby' => 'diving'], $redis->hgetall('hash'));\n\n            $redis->hmset('hash2', 'name', 'mohamed', 'hobby', 'diving');\n            $this->assertEquals(['name' => 'mohamed', 'hobby' => 'diving'], $redis->hgetall('hash2'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItGetsMultipleHashFields()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->hmset('hash', ['name' => 'mohamed', 'hobby' => 'diving']);\n\n            $this->assertEquals(['mohamed', 'diving'],\n                $redis->hmget('hash', 'name', 'hobby')\n            );\n\n            $this->assertEquals(['mohamed', 'diving'],\n                $redis->hmget('hash', ['name', 'hobby'])\n            );\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItGetsMultipleKeys()\n    {\n        $valueSet = ['name' => 'mohamed', 'hobby' => 'diving'];\n\n        foreach ($this->connections() as $redis) {\n            $redis->mset($valueSet);\n\n            $this->assertEquals(\n                array_values($valueSet),\n                $redis->mget(array_keys($valueSet))\n            );\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItFlushes()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('name', 'Till');\n            $this->assertSame(1, $redis->exists('name'));\n\n            $redis->flushdb();\n            $this->assertSame(0, $redis->exists('name'));\n        }\n    }\n\n    public function testItFlushesAsynchronous()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->set('name', 'Till');\n            $this->assertSame(1, $redis->exists('name'));\n\n            $redis->flushdb('ASYNC');\n            $this->assertSame(0, $redis->exists('name'));\n        }\n    }\n\n    public function testItRunsEval()\n    {\n        foreach ($this->connections() as $redis) {\n            if ($redis instanceof PhpRedisConnection) {\n                // User must decide what needs to be serialized and compressed.\n                $redis->eval('redis.call(\"set\", KEYS[1], ARGV[1])', 1, 'name', ...$redis->pack(['mohamed']));\n            } else {\n                $redis->eval('redis.call(\"set\", KEYS[1], ARGV[1])', 1, 'name', 'mohamed');\n            }\n\n            $this->assertSame('mohamed', $redis->get('name'));\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRunsPipes()\n    {\n        foreach ($this->connections() as $redis) {\n            $result = $redis->pipeline(function ($pipe) {\n                $pipe->set('test:pipeline:1', 1);\n                $pipe->get('test:pipeline:1');\n                $pipe->set('test:pipeline:2', 2);\n                $pipe->get('test:pipeline:2');\n            });\n\n            $this->assertCount(4, $result);\n            $this->assertEquals(1, $result[1]);\n            $this->assertEquals(2, $result[3]);\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRunsTransactions()\n    {\n        foreach ($this->connections() as $redis) {\n            $result = $redis->transaction(function ($pipe) {\n                $pipe->set('test:transaction:1', 1);\n                $pipe->get('test:transaction:1');\n                $pipe->set('test:transaction:2', 2);\n                $pipe->get('test:transaction:2');\n            });\n\n            $this->assertCount(4, $result);\n            $this->assertEquals(1, $result[1]);\n            $this->assertEquals(2, $result[3]);\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItRunsRawCommand()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->executeRaw(['SET', 'test:raw:1', '1']);\n\n            $this->assertEquals(\n                1, $redis->executeRaw(['GET', 'test:raw:1'])\n            );\n\n            $redis->flushall();\n        }\n    }\n\n    public function testItDispatchesQueryEvent()\n    {\n        foreach ($this->connections() as $redis) {\n            $redis->setEventDispatcher($events = m::mock(Dispatcher::class));\n\n            $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) {\n                $this->assertSame('get', $event->command);\n                $this->assertEquals(['foobar'], $event->parameters);\n                $this->assertSame('default', $event->connectionName);\n                $this->assertInstanceOf(Connection::class, $event->connection);\n\n                return true;\n            }));\n\n            $redis->get('foobar');\n\n            $redis->unsetEventDispatcher();\n        }\n    }\n\n    public function testItPersistsConnection()\n    {\n        if (PHP_ZTS) {\n            $this->markTestSkipped('PhpRedis does not support persistent connections with PHP_ZTS enabled.');\n        }\n\n        $this->assertSame(\n            'laravel',\n            $this->connections()['persistent']->getPersistentID()\n        );\n    }\n\n    public function testItScansForKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $initialKeys = ['test:scan:1', 'test:scan:2'];\n\n            foreach ($initialKeys as $k => $key) {\n                $redis->set($key, 'test');\n                $initialKeys[$k] = $this->getPrefix($redis->client()).$key;\n            }\n\n            $iterator = null;\n\n            do {\n                [$cursor, $returnedKeys] = $redis->scan($iterator);\n\n                if (! is_array($returnedKeys)) {\n                    $returnedKeys = [$returnedKeys];\n                }\n\n                foreach ($returnedKeys as $returnedKey) {\n                    $this->assertContains($returnedKey, $initialKeys);\n                }\n            } while ($iterator > 0);\n\n            $redis->flushAll();\n        }\n    }\n\n    public function testItZscansForKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $members = [100 => 'test:zscan:1', 200 => 'test:zscan:2'];\n\n            foreach ($members as $score => $member) {\n                $redis->zadd('set', $score, $member);\n            }\n\n            $iterator = null;\n            $result = [];\n\n            do {\n                [$iterator, $returnedMembers] = $redis->zscan('set', $iterator);\n\n                if (! is_array($returnedMembers)) {\n                    $returnedMembers = [$returnedMembers];\n                }\n\n                foreach ($returnedMembers as $member => $score) {\n                    $this->assertArrayHasKey((int) $score, $members);\n                    $this->assertContains($member, $members);\n                }\n\n                $result += $returnedMembers;\n            } while ($iterator > 0);\n\n            $this->assertCount(2, $result);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->zscan('set', $iterator, ['match' => 'test:unmatch:*']);\n            $this->assertEmpty($returned);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->zscan('set', $iterator, ['count' => 5]);\n            $this->assertCount(2, $returned);\n\n            $redis->flushAll();\n        }\n    }\n\n    public function testItHscansForKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $fields = ['name' => 'mohamed', 'hobby' => 'diving'];\n\n            foreach ($fields as $field => $value) {\n                $redis->hset('hash', $field, $value);\n            }\n\n            $iterator = null;\n            $result = [];\n\n            do {\n                [$iterator, $returnedFields] = $redis->hscan('hash', $iterator);\n\n                foreach ($returnedFields as $field => $value) {\n                    $this->assertArrayHasKey($field, $fields);\n                    $this->assertContains($value, $fields);\n                }\n\n                $result += $returnedFields;\n            } while ($iterator > 0);\n\n            $this->assertCount(2, $result);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->hscan('hash', $iterator, ['match' => 'test:unmatch:*']);\n            $this->assertEmpty($returned);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->hscan('hash', $iterator, ['count' => 5]);\n            $this->assertCount(2, $returned);\n\n            $redis->flushAll();\n        }\n    }\n\n    public function testItSscansForKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $members = ['test:sscan:1', 'test:sscan:2'];\n\n            foreach ($members as $member) {\n                $redis->sadd('set', $member);\n            }\n\n            $iterator = null;\n            $result = [];\n\n            do {\n                [$iterator, $returnedMembers] = $redis->sscan('set', $iterator);\n\n                foreach ($returnedMembers as $member) {\n                    $this->assertContains($member, $members);\n                    $result[] = $member;\n                }\n            } while ($iterator > 0);\n\n            $this->assertCount(2, $result);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->sscan('set', $iterator, ['match' => 'test:unmatch:*']);\n            $this->assertEmpty($returned);\n\n            $iterator = null;\n            [$iterator, $returned] = $redis->sscan('set', $iterator, ['count' => 5]);\n            $this->assertCount(2, $returned);\n\n            $redis->flushAll();\n        }\n    }\n\n    public function testItSPopsForKeys()\n    {\n        foreach ($this->connections() as $redis) {\n            $members = ['test:spop:1', 'test:spop:2', 'test:spop:3', 'test:spop:4'];\n\n            foreach ($members as $member) {\n                $redis->sadd('set', $member);\n            }\n\n            $result = $redis->spop('set');\n            $this->assertIsNotArray($result);\n            $this->assertContains($result, $members);\n\n            $result = $redis->spop('set', 1);\n\n            $this->assertIsArray($result);\n            $this->assertCount(1, $result);\n\n            $result = $redis->spop('set', 2);\n\n            $this->assertIsArray($result);\n            $this->assertCount(2, $result);\n\n            $redis->flushAll();\n        }\n    }\n\n    public function testPhpRedisScanOption()\n    {\n        foreach ($this->connections() as $redis) {\n            if ($redis->client() instanceof Client) {\n                continue;\n            }\n\n            $iterator = null;\n\n            do {\n                $returned = $redis->scan($iterator);\n\n                if ($redis->client()->getOption(Redis::OPT_SCAN) === Redis::SCAN_RETRY) {\n                    $this->assertEmpty($returned);\n                }\n            } while ($iterator > 0);\n        }\n    }\n\n    private function getPrefix($client)\n    {\n        if ($client instanceof Redis) {\n            return $client->getOption(Redis::OPT_PREFIX);\n        }\n\n        return $client->getOptions()->prefix;\n    }\n\n    public function testMacroable()\n    {\n        Connection::macro('foo', function () {\n            return 'foo';\n        });\n\n        foreach ($this->connections() as $redis) {\n            $this->assertSame(\n                'foo',\n                $redis->foo()\n            );\n        }\n    }\n\n    public function connections()\n    {\n        $connections = [\n            'predis' => $this->redis['predis']->connection(),\n            'phpredis' => $this->redis['phpredis']->connection(),\n        ];\n\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $connections[] = (new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'default' => [\n                'url' => \"redis://user@$host:$port\",\n                'host' => 'overwrittenByUrl',\n                'port' => 'overwrittenByUrl',\n                'database' => 5,\n                'options' => ['prefix' => 'laravel:'],\n                'timeout' => 0.5,\n            ],\n        ]))->connection();\n\n        $connections['persistent'] = (new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'database' => 6,\n                'options' => ['prefix' => 'laravel:'],\n                'timeout' => 0.5,\n                'persistent' => true,\n                'persistent_id' => 'laravel',\n            ],\n        ]))->connection();\n\n        $connections[] = (new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'database' => 7,\n                'options' => ['serializer' => Redis::SERIALIZER_JSON],\n                'timeout' => 0.5,\n            ],\n        ]))->connection();\n\n        $connections[] = (new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'database' => 8,\n                'options' => ['scan' => Redis::SCAN_RETRY],\n                'timeout' => 0.5,\n            ],\n        ]))->connection();\n\n        if (defined('Redis::COMPRESSION_LZF')) {\n            $connections['compression_lzf'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 9,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_LZF,\n                        'name' => 'compression_lzf',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n        }\n\n        if (defined('Redis::COMPRESSION_ZSTD')) {\n            $connections['compression_zstd'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 10,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_ZSTD,\n                        'name' => 'compression_zstd',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n\n            $connections['compression_zstd_default'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 11,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_ZSTD,\n                        'compression_level' => Redis::COMPRESSION_ZSTD_DEFAULT,\n                        'name' => 'compression_zstd_default',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n\n            $connections['compression_zstd_max'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 13,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_ZSTD,\n                        'compression_level' => Redis::COMPRESSION_ZSTD_MAX,\n                        'name' => 'compression_zstd_max',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n        }\n\n        if (defined('Redis::COMPRESSION_LZ4')) {\n            $connections['compression_lz4'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 14,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_LZ4,\n                        'name' => 'compression_lz4',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n\n            $connections['compression_lz4_default'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 15,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_LZ4,\n                        'compression_level' => 0,\n                        'name' => 'compression_lz4_default',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n\n            $connections['compression_lz4_min'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 16,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_LZ4,\n                        'compression_level' => 1,\n                        'name' => 'compression_lz4_min',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n\n            $connections['compression_lz4_max'] = (new RedisManager(new Application, 'phpredis', [\n                'cluster' => false,\n                'default' => [\n                    'host' => $host,\n                    'port' => $port,\n                    'database' => 17,\n                    'options' => [\n                        'compression' => Redis::COMPRESSION_LZ4,\n                        'compression_level' => 12,\n                        'name' => 'compression_lz4_max',\n                    ],\n                    'timeout' => 0.5,\n                ],\n            ]))->connection();\n        }\n\n        return $connections;\n    }\n}\n"
  },
  {
    "path": "tests/Redis/RedisConnectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithRedis;\nuse Illuminate\\Redis\\RedisManager;\nuse PHPUnit\\Framework\\TestCase;\nuse Redis;\n\nclass RedisConnectorTest extends TestCase\n{\n    use InteractsWithRedis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->setUpRedis();\n    }\n\n    protected function tearDown(): void\n    {\n        $this->tearDownRedis();\n\n        parent::tearDown();\n    }\n\n    public function testDefaultConfiguration()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predisClient = $this->redis['predis']->connection()->client();\n        $parameters = $predisClient->getConnection()->getParameters();\n        $this->assertSame('tcp', $parameters->scheme);\n        $this->assertEquals($host, $parameters->host);\n        $this->assertEquals($port, $parameters->port);\n\n        $phpRedisClient = $this->redis['phpredis']->connection()->client();\n        $this->assertEquals($host, $phpRedisClient->getHost());\n        $this->assertEquals($port, $phpRedisClient->getPort());\n        $this->assertSame('default', $phpRedisClient->client('GETNAME'));\n    }\n\n    public function testUrl()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predis = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'url' => \"redis://{$host}:{$port}\",\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $predisClient = $predis->connection()->client();\n        $parameters = $predisClient->getConnection()->getParameters();\n        $this->assertSame('tcp', $parameters->scheme);\n        $this->assertEquals($host, $parameters->host);\n        $this->assertEquals($port, $parameters->port);\n\n        $phpRedis = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'url' => \"redis://{$host}:{$port}\",\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $phpRedisClient = $phpRedis->connection()->client();\n        $this->assertSame(\"tcp://{$host}\", $phpRedisClient->getHost());\n        $this->assertEquals($port, $phpRedisClient->getPort());\n    }\n\n    public function testUrlWithScheme()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predis = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'url' => \"tls://{$host}:{$port}\",\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $predisClient = $predis->connection()->client();\n        $parameters = $predisClient->getConnection()->getParameters();\n        $this->assertSame('tls', $parameters->scheme);\n        $this->assertEquals($host, $parameters->host);\n        $this->assertEquals($port, $parameters->port);\n\n        $phpRedis = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'url' => \"tcp://{$host}:{$port}\",\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $phpRedisClient = $phpRedis->connection()->client();\n        $this->assertSame(\"tcp://{$host}\", $phpRedisClient->getHost());\n        $this->assertEquals($port, $phpRedisClient->getPort());\n    }\n\n    public function testScheme()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predis = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tls',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $predisClient = $predis->connection()->client();\n        $parameters = $predisClient->getConnection()->getParameters();\n        $this->assertSame('tls', $parameters->scheme);\n        $this->assertEquals($host, $parameters->host);\n        $this->assertEquals($port, $parameters->port);\n\n        $phpRedis = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tcp',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $phpRedisClient = $phpRedis->connection()->client();\n        $this->assertSame(\"tcp://{$host}\", $phpRedisClient->getHost());\n        $this->assertEquals($port, $phpRedisClient->getPort());\n    }\n\n    public function testPredisConfigurationWithUsername()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n        $username = 'testuser';\n        $password = 'testpw';\n\n        $predis = new RedisManager(new Application, 'predis', [\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'username' => $username,\n                'password' => $password,\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n        ]);\n        $predisClient = $predis->connection()->client();\n        $parameters = $predisClient->getConnection()->getParameters();\n        $this->assertEquals($username, $parameters->username);\n        $this->assertEquals($password, $parameters->password);\n    }\n\n    public function testPredisConfigurationWithSentinel()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predis = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'replication' => 'sentinel',\n                'service' => 'mymaster',\n                'parameters' => [\n                    'default' => [\n                        'database' => 5,\n                    ],\n                ],\n            ],\n            'default' => [\n                \"tcp://{$host}:{$port}\",\n            ],\n        ]);\n\n        $predisClient = $predis->connection()->client();\n        $parameters = $predisClient->getConnection()->getSentinelConnection()->getParameters();\n        $this->assertEquals($host, $parameters->host);\n    }\n\n    public function testPhpRedisTcpKeepalive()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $phpRedis = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'default' => [\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n                'tcp_keepalive' => 60,\n            ],\n        ]);\n\n        $phpRedisClient = $phpRedis->connection()->client();\n        $this->assertEquals(1, $phpRedisClient->getOption(Redis::OPT_TCP_KEEPALIVE));\n    }\n\n    public function testPrefixOverrideBehaviour()\n    {\n        $host = env('REDIS_HOST', '127.0.0.1');\n        $port = env('REDIS_PORT', 6379);\n\n        $predis1 = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tls',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n                'options' => [\n                    'prefix' => 'test_default_options_',\n                ],\n            ],\n        ]);\n        $predisClient1 = $predis1->client();\n        $this->assertEquals('test_default_options_', $predisClient1->getOptions()->prefix->getPrefix());\n\n        $predis2 = new RedisManager(new Application, 'predis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tls',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n                'options' => [\n                    'prefix' => 'test_default_options_',\n                ],\n                'prefix' => 'test_default_config_',\n            ],\n        ]);\n        $predisClient2 = $predis2->client();\n        $this->assertEquals('test_default_config_', $predisClient2->getOptions()->prefix->getPrefix());\n\n        $phpRedis1 = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tcp',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n                'options' => [\n                    'prefix' => 'test_default_options_',\n                ],\n            ],\n        ]);\n        $phpRedisClient1 = $phpRedis1->connection()->client();\n        $this->assertEquals('test_default_options_', $phpRedisClient1->getOption(Redis::OPT_PREFIX));\n\n        $phpRedis2 = new RedisManager(new Application, 'phpredis', [\n            'cluster' => false,\n            'options' => [\n                'prefix' => 'test_',\n            ],\n            'default' => [\n                'scheme' => 'tcp',\n                'host' => $host,\n                'port' => $port,\n                'database' => 5,\n                'timeout' => 0.5,\n                'options' => [\n                    'prefix' => 'test_default_options_',\n                ],\n                'prefix' => 'test_default_config_',\n            ],\n        ]);\n        $phpRedisClient2 = $phpRedis2->connection()->client();\n        $this->assertEquals('test_default_config_', $phpRedisClient2->getOption(Redis::OPT_PREFIX));\n    }\n}\n"
  },
  {
    "path": "tests/Redis/RedisEventsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Exception;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Redis\\Connections\\PhpRedisConnection;\nuse Illuminate\\Redis\\Events\\CommandExecuted;\nuse Illuminate\\Redis\\Events\\CommandFailed;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Redis;\n\nclass RedisEventsTest extends TestCase\n{\n    public function testCommandFailedEventIsDispatched()\n    {\n        $exception = new Exception('Test exception');\n\n        $client = m::mock(Redis::class);\n        $client->shouldReceive('get')->with('key')->andThrow($exception);\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) use ($exception) {\n            return $event instanceof CommandFailed\n                && $event->command === 'get'\n                && $event->parameters === ['key']\n                && $event->exception === $exception;\n        }));\n\n        $connection = new PhpRedisConnection($client);\n        $connection->setEventDispatcher($events);\n\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Test exception');\n\n        $connection->command('get', ['key']);\n    }\n\n    public function testCommandExecutedEventIsNotDispatchedWhenCommandFails()\n    {\n        $exception = new Exception('Test exception');\n\n        $client = m::mock(Redis::class);\n        $client->shouldReceive('get')->with('key')->andThrow($exception);\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::type(CommandFailed::class));\n        $events->shouldNotReceive('dispatch')->with(m::type(CommandExecuted::class));\n\n        $connection = new PhpRedisConnection($client);\n        $connection->setEventDispatcher($events);\n\n        try {\n            $connection->command('get', ['key']);\n        } catch (Exception $e) {\n            // Expected exception\n        }\n    }\n\n    public function testCommandFailedEventContainsConnectionName()\n    {\n        $exception = new Exception('Test exception');\n\n        $client = m::mock(Redis::class);\n        $client->shouldReceive('get')->with('key')->andThrow($exception);\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) {\n            return $event instanceof CommandFailed\n                && $event->connectionName === 'test-connection';\n        }));\n\n        $connection = new PhpRedisConnection($client);\n        $connection->setName('test-connection');\n        $connection->setEventDispatcher($events);\n\n        try {\n            $connection->command('get', ['key']);\n        } catch (Exception $e) {\n            // Expected exception\n        }\n    }\n\n    public function testListenForFailuresRegistersCallback()\n    {\n        $client = m::mock(Redis::class);\n\n        $events = m::mock(Dispatcher::class);\n        $events->shouldReceive('listen')->once()->with(CommandFailed::class, m::type('Closure'));\n\n        $connection = new PhpRedisConnection($client);\n        $connection->setEventDispatcher($events);\n\n        $connection->listenForFailures(function () {\n            // callback\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Redis/RedisManagerExtensionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Redis;\n\nuse Illuminate\\Contracts\\Redis\\Connector;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Redis\\RedisManager;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RedisManagerExtensionTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Redis\\RedisManager\n     */\n    protected $redis;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->redis = new RedisManager(new Application, 'my_custom_driver', [\n            'default' => [\n                'host' => 'some-host',\n                'port' => 'some-port',\n                'database' => 5,\n                'timeout' => 0.5,\n            ],\n            'clusters' => [\n                'my-cluster' => [\n                    [\n                        'host' => 'some-host',\n                        'port' => 'some-port',\n                        'database' => 5,\n                        'timeout' => 0.5,\n                    ],\n                ],\n            ],\n        ]);\n\n        $this->redis->extend('my_custom_driver', function () {\n            return new FakeRedisConnector;\n        });\n    }\n\n    public function testUsingCustomRedisConnectorWithSingleRedisInstance()\n    {\n        $this->assertSame(\n            'my-redis-connection', $this->redis->resolve()\n        );\n    }\n\n    public function testUsingCustomRedisConnectorWithRedisClusterInstance()\n    {\n        $this->assertSame(\n            'my-redis-cluster-connection', $this->redis->resolve('my-cluster')\n        );\n    }\n\n    public function testParseConnectionConfigurationForCluster()\n    {\n        $name = 'my-cluster';\n        $config = [\n            [\n                'url1',\n                'url2',\n                'url3',\n            ],\n        ];\n        $redis = new RedisManager(new Application, 'my_custom_driver', [\n            'clusters' => [\n                $name => $config,\n            ],\n        ]);\n        $redis->extend('my_custom_driver', function () use ($config) {\n            return m::mock(Connector::class)\n                ->shouldReceive('connectToCluster')\n                ->once()\n                ->withArgs(function ($configArg) use ($config) {\n                    return $config === $configArg;\n                })\n                ->getMock();\n        });\n\n        $redis->resolve($name);\n    }\n}\n\nclass FakeRedisConnector implements Connector\n{\n    /**\n     * Create a new clustered Predis connection.\n     *\n     * @param  array  $config\n     * @param  array  $options\n     * @return string\n     */\n    public function connect(array $config, array $options)\n    {\n        return 'my-redis-connection';\n    }\n\n    /**\n     * Create a new clustered Predis connection.\n     *\n     * @param  array  $config\n     * @param  array  $clusterOptions\n     * @param  array  $options\n     * @return string\n     */\n    public function connectToCluster(array $config, array $clusterOptions, array $options)\n    {\n        return 'my-redis-cluster-connection';\n    }\n}\n"
  },
  {
    "path": "tests/Routing/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nenum CategoryEnum\n{\n    case People;\n    case Fruits;\n}\n\nenum CategoryBackedEnum: string\n{\n    case People = 'people';\n    case Fruits = 'fruits';\n}\n\nenum RouteNameEnum: string\n{\n    case UserIndex = 'users.index';\n}\n\nenum RouteDomainEnum: string\n{\n    case DashboardDomain = 'dashboard.myapp.com';\n}\n\nenum IntegerEnum: int\n{\n    case One = 1;\n    case Two = 2;\n}\n"
  },
  {
    "path": "tests/Routing/ImplicitRouteBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Routing\\Exceptions\\BackedEnumCaseNotFoundException;\nuse Illuminate\\Routing\\ImplicitRouteBinding;\nuse Illuminate\\Routing\\Route;\nuse PHPUnit\\Framework\\TestCase;\n\ninclude_once 'Enums.php';\n\nclass ImplicitRouteBindingTest extends TestCase\n{\n    public function test_it_can_resolve_the_implicit_backed_enum_route_bindings_for_the_given_route()\n    {\n        $action = ['uses' => function (CategoryBackedEnum $category) {\n            return $category->value;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['category' => 'fruits'];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n\n        $this->assertSame('fruits', $route->parameter('category')->value);\n    }\n\n    public function test_it_can_resolve_the_implicit_backed_enum_route_bindings_for_the_given_route_with_optional_parameter()\n    {\n        $action = ['uses' => function (?CategoryBackedEnum $category = null) {\n            return $category->value;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['category' => 'fruits'];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n\n        $this->assertSame('fruits', $route->parameter('category')->value);\n    }\n\n    public function test_it_handles_optional_implicit_backed_enum_route_bindings_for_the_given_route_with_optional_parameter()\n    {\n        $action = ['uses' => function (?CategoryBackedEnum $category = null) {\n            return $category->value;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['category' => null];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n\n        $this->assertNull($route->parameter('category'));\n    }\n\n    public function test_it_does_not_resolve_implicit_non_backed_enum_route_bindings_for_the_given_route()\n    {\n        $action = ['uses' => function (CategoryEnum $category) {\n            return $category->value;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['category' => 'fruits'];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n\n        $this->assertIsString($route->parameter('category'));\n        $this->assertSame('fruits', $route->parameter('category'));\n    }\n\n    public function test_implicit_backed_enum_internal_exception()\n    {\n        $action = ['uses' => function (CategoryBackedEnum $category) {\n            return $category->value;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['category' => 'cars'];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        $this->expectException(BackedEnumCaseNotFoundException::class);\n        $this->expectExceptionMessage(sprintf(\n            'Case [%s] not found on Backed Enum [%s].',\n            'cars',\n            CategoryBackedEnum::class,\n        ));\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n    }\n\n    public function test_it_can_resolve_the_implicit_model_route_bindings_for_the_given_route()\n    {\n        $this->expectNotToPerformAssertions();\n\n        $action = ['uses' => function (ImplicitRouteBindingUser $user) {\n            return $user;\n        }];\n\n        $route = new Route('GET', '/test', $action);\n        $route->parameters = ['user' => new ImplicitRouteBindingUser];\n\n        $route->prepareForSerialization();\n\n        $container = Container::getInstance();\n\n        ImplicitRouteBinding::resolveForRoute($container, $route);\n    }\n}\n\nclass ImplicitRouteBindingUser extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Routing/RouteActionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Routing\\RouteAction;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RouteActionTest extends TestCase\n{\n    public function test_it_can_detect_a_serialized_closure()\n    {\n        $callable = function (RouteActionUser $user) {\n            return $user;\n        };\n\n        $action = ['uses' => serialize(\n            new SerializableClosure($callable)\n        )];\n\n        $this->assertTrue(RouteAction::containsSerializedClosure($action));\n\n        $action = ['uses' => 'FooController@index'];\n\n        $this->assertFalse(RouteAction::containsSerializedClosure($action));\n    }\n}\n\nclass RouteActionUser extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Routing/RouteBindingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\RouteBinding;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RouteBindingTest extends TestCase\n{\n    public function test_it_can_resolve_the_explicit_model_for_the_given_route()\n    {\n        $container = Container::getInstance();\n\n        $route = new Route('GET', '/users/{user}', function () {\n        });\n\n        $callback = RouteBinding::forModel($container, ExplicitRouteBindingUser::class);\n        $this->assertInstanceOf(ExplicitRouteBindingUser::class, $callback(1, $route));\n    }\n\n    public function test_it_cannot_resolve_the_explicit_soft_deleted_model_for_the_given_route()\n    {\n        $container = Container::getInstance();\n\n        $route = new Route('GET', '/users/{user}', function () {\n        });\n\n        $callback = RouteBinding::forModel($container, ExplicitRouteBindingSoftDeletableUser::class);\n\n        $this->expectException(ModelNotFoundException::class);\n        $callback(1, $route);\n    }\n\n    public function test_it_can_resolve_the_explicit_soft_deleted_model_for_the_given_route_with_trashed()\n    {\n        $container = Container::getInstance();\n\n        $route = (new Route('GET', '/users/{user}', function () {\n        }))->withTrashed();\n\n        $callback = RouteBinding::forModel($container, ExplicitRouteBindingSoftDeletableUser::class);\n        $this->assertInstanceOf(ExplicitRouteBindingSoftDeletableUser::class, $callback(1, $route));\n    }\n}\n\nclass ExplicitRouteBindingUser extends Model\n{\n    public function resolveRouteBinding($value, $field = null)\n    {\n        return new self();\n    }\n}\n\nclass ExplicitRouteBindingSoftDeletableUser extends Model\n{\n    use SoftDeletes;\n\n    public function resolveRouteBinding($value, $field = null)\n    {\n        return null;\n    }\n\n    public function resolveSoftDeletableRouteBinding($value, $field = null)\n    {\n        return new self();\n    }\n}\n"
  },
  {
    "path": "tests/Routing/RouteCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse ArrayIterator;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\RouteCollection;\nuse LogicException;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\nclass RouteCollectionTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Routing\\RouteCollection\n     */\n    protected $routeCollection;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->routeCollection = new RouteCollection;\n    }\n\n    public function testRouteCollectionCanAddRoute()\n    {\n        $this->routeCollection->add(new Route('GET', 'foo', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n        $this->assertCount(1, $this->routeCollection);\n    }\n\n    public function testRouteCollectionAddReturnsTheRoute()\n    {\n        $outputRoute = $this->routeCollection->add($inputRoute = new Route('GET', 'foo', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n        $this->assertInstanceOf(Route::class, $outputRoute);\n        $this->assertEquals($inputRoute, $outputRoute);\n    }\n\n    public function testRouteCollectionCanRetrieveByName()\n    {\n        $this->routeCollection->add($routeIndex = new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'route_name',\n        ]));\n\n        $this->assertSame('route_name', $routeIndex->getName());\n        $this->assertSame('route_name', $this->routeCollection->getByName('route_name')->getName());\n        $this->assertEquals($routeIndex, $this->routeCollection->getByName('route_name'));\n    }\n\n    public function testRouteCollectionCanRetrieveByAction()\n    {\n        $this->routeCollection->add($routeIndex = new Route('GET', 'foo/index', $action = [\n            'uses' => 'FooController@index',\n            'as' => 'route_name',\n        ]));\n\n        $this->assertSame($action, $routeIndex->getAction());\n    }\n\n    public function testRouteCollectionCanRetrieveByMethod()\n    {\n        $this->routeCollection->add($routeIndex = new Route('GET', 'foo/index', $action = [\n            'uses' => 'FooController@index',\n            'as' => 'route_name',\n        ]));\n\n        $this->assertCount(1, $this->routeCollection->get('GET'));\n        $this->assertCount(0, $this->routeCollection->get('GET.foo/index'));\n        $this->assertSame($routeIndex, $this->routeCollection->get('GET')['foo/index']);\n\n        $this->routeCollection->add($routeShow = new Route('GET', 'bar/show', [\n            'uses' => 'BarController@show',\n            'as' => 'bar_show',\n        ]));\n        $this->assertCount(2, $this->routeCollection->get('GET'));\n    }\n\n    public function testRouteCollectionCanGetIterator()\n    {\n        $this->routeCollection->add(new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n        $this->assertInstanceOf(ArrayIterator::class, $this->routeCollection->getIterator());\n    }\n\n    public function testRouteCollectionCanGetIteratorWhenEmpty()\n    {\n        $this->assertCount(0, $this->routeCollection);\n        $this->assertInstanceOf(ArrayIterator::class, $this->routeCollection->getIterator());\n    }\n\n    public function testRouteCollectionCanGetIteratorWhenRouteAreAdded()\n    {\n        $this->routeCollection->add($routeIndex = new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n        $this->assertCount(1, $this->routeCollection);\n\n        $this->routeCollection->add($routeShow = new Route('GET', 'bar/show', [\n            'uses' => 'BarController@show',\n            'as' => 'bar_show',\n        ]));\n        $this->assertCount(2, $this->routeCollection);\n\n        $this->assertInstanceOf(ArrayIterator::class, $this->routeCollection->getIterator());\n    }\n\n    public function testRouteCollectionCanHandleSameRoute()\n    {\n        $routeIndex = new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]);\n\n        $this->routeCollection->add($routeIndex);\n        $this->assertCount(1, $this->routeCollection);\n\n        // Add exactly the same route\n        $this->routeCollection->add($routeIndex);\n        $this->assertCount(1, $this->routeCollection);\n\n        // Add a non-existing route\n        $this->routeCollection->add(new Route('GET', 'bar/show', [\n            'uses' => 'BarController@show',\n            'as' => 'bar_show',\n        ]));\n        $this->assertCount(2, $this->routeCollection);\n    }\n\n    public function testRouteCollectionCanRefreshNameLookups()\n    {\n        $routeIndex = new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n        ]);\n\n        // The name of the route is not yet set. It will be while adding if to the RouteCollection.\n        $this->assertNull($routeIndex->getName());\n\n        // The route name is set by calling \\Illuminate\\Routing\\Route::name()\n        $this->routeCollection->add($routeIndex)->name('route_name');\n\n        // No route is found. This is normal, as no refresh as been done.\n        $this->assertNull($this->routeCollection->getByName('route_name'));\n\n        // After the refresh, the name will be properly set to the route.\n        $this->routeCollection->refreshNameLookups();\n        $this->assertEquals($routeIndex, $this->routeCollection->getByName('route_name'));\n    }\n\n    public function testRouteCollectionCanGetAllRoutes()\n    {\n        $this->routeCollection->add($routeIndex = new Route('GET', 'foo/index', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $this->routeCollection->add($routeShow = new Route('GET', 'foo/show', [\n            'uses' => 'FooController@show',\n            'as' => 'foo_show',\n        ]));\n\n        $this->routeCollection->add($routeNew = new Route('POST', 'bar', [\n            'uses' => 'BarController@create',\n            'as' => 'bar_create',\n        ]));\n\n        $allRoutes = [\n            $routeIndex,\n            $routeShow,\n            $routeNew,\n        ];\n        $this->assertEquals($allRoutes, $this->routeCollection->getRoutes());\n    }\n\n    public function testRouteCollectionCanGetRoutesByName()\n    {\n        $routesByName = [\n            'foo_index' => new Route('GET', 'foo/index', [\n                'uses' => 'FooController@index',\n                'as' => 'foo_index',\n            ]),\n            'foo_show' => new Route('GET', 'foo/show', [\n                'uses' => 'FooController@show',\n                'as' => 'foo_show',\n            ]),\n            'bar_create' => new Route('POST', 'bar', [\n                'uses' => 'BarController@create',\n                'as' => 'bar_create',\n            ]),\n        ];\n\n        $this->routeCollection->add($routesByName['foo_index']);\n        $this->routeCollection->add($routesByName['foo_show']);\n        $this->routeCollection->add($routesByName['bar_create']);\n\n        $this->assertSame($routesByName, $this->routeCollection->getRoutesByName());\n    }\n\n    public function testRouteCollectionCanGetRoutesByMethod()\n    {\n        $routes = [\n            'foo_index' => new Route('GET', 'foo/index', [\n                'uses' => 'FooController@index',\n                'as' => 'foo_index',\n            ]),\n            'foo_show' => new Route('GET', 'foo/show', [\n                'uses' => 'FooController@show',\n                'as' => 'foo_show',\n            ]),\n            'bar_create' => new Route('POST', 'bar', [\n                'uses' => 'BarController@create',\n                'as' => 'bar_create',\n            ]),\n        ];\n\n        $this->routeCollection->add($routes['foo_index']);\n        $this->routeCollection->add($routes['foo_show']);\n        $this->routeCollection->add($routes['bar_create']);\n\n        $this->assertSame([\n            'GET' => [\n                'foo/index' => $routes['foo_index'],\n                'foo/show' => $routes['foo_show'],\n            ],\n            'HEAD' => [\n                'foo/index' => $routes['foo_index'],\n                'foo/show' => $routes['foo_show'],\n            ],\n            'POST' => [\n                'bar' => $routes['bar_create'],\n            ],\n        ], $this->routeCollection->getRoutesByMethod());\n    }\n\n    public function testRouteCollectionCleansUpOverwrittenRoutes()\n    {\n        // Create two routes with the same path and method.\n        $routeA = new Route('GET', 'product', ['controller' => 'View@view', 'as' => 'routeA']);\n        $routeB = new Route('GET', 'product', ['controller' => 'OverwrittenView@view', 'as' => 'overwrittenRouteA']);\n\n        $this->routeCollection->add($routeA);\n        $this->routeCollection->add($routeB);\n\n        // Check if the lookups of $routeA and $routeB are there.\n        $this->assertEquals($routeA, $this->routeCollection->getByName('routeA'));\n        $this->assertEquals($routeA, $this->routeCollection->getByAction('View@view'));\n        $this->assertEquals($routeB, $this->routeCollection->getByName('overwrittenRouteA'));\n        $this->assertEquals($routeB, $this->routeCollection->getByAction('OverwrittenView@view'));\n\n        // Rebuild the lookup arrays.\n        $this->routeCollection->refreshNameLookups();\n        $this->routeCollection->refreshActionLookups();\n\n        // The lookups of $routeA should not be there anymore, because they are no longer valid.\n        $this->assertNull($this->routeCollection->getByName('routeA'));\n        $this->assertNull($this->routeCollection->getByAction('View@view'));\n        // The lookups of $routeB are still there.\n        $this->assertEquals($routeB, $this->routeCollection->getByName('overwrittenRouteA'));\n        $this->assertEquals($routeB, $this->routeCollection->getByAction('OverwrittenView@view'));\n    }\n\n    public function testCannotCacheDuplicateRouteNames()\n    {\n        $this->routeCollection->add(\n            new Route('GET', 'users', ['uses' => 'UsersController@index', 'as' => 'users'])\n        );\n        $this->routeCollection->add(\n            new Route('GET', 'users/{user}', ['uses' => 'UsersController@show', 'as' => 'users'])\n        );\n\n        $this->expectException(LogicException::class);\n\n        $this->routeCollection->compile();\n    }\n\n    public function testRouteCollectionDontMatchNonMatchingDoubleSlashes()\n    {\n        $this->expectException(NotFoundHttpException::class);\n        $this->expectExceptionMessage('The route foo could not be found.');\n\n        $this->routeCollection->add(new Route('GET', 'foo', [\n            'uses' => 'FooController@index',\n            'as' => 'foo_index',\n        ]));\n\n        $request = Request::create('', 'GET');\n        // We have to set uri in REQUEST_URI otherwise Request uses parse_url() which trim the slashes\n        $request->server->set(\n            'REQUEST_URI', '//foo'\n        );\n        $this->routeCollection->match($request);\n    }\n\n    public function testRouteCollectionRequestMethodNotAllowed()\n    {\n        $this->expectException(MethodNotAllowedHttpException::class);\n        $this->expectExceptionMessage('The POST method is not supported for route users. Supported methods: GET, HEAD.');\n\n        $this->routeCollection->add(\n            new Route('GET', 'users', ['uses' => 'UsersController@index', 'as' => 'users'])\n        );\n\n        $request = Request::create('users', 'POST');\n\n        $this->routeCollection->match($request);\n    }\n\n    public function testHasNameRouteMethod()\n    {\n        $this->routeCollection->add(\n            new Route('GET', 'users', ['uses' => 'UsersController@index', 'as' => 'users'])\n        );\n        $this->routeCollection->add(\n            new Route('GET', 'posts/{post}', ['uses' => 'PostController@show', 'as' => 'posts'])\n        );\n\n        $this->routeCollection->add(\n            new Route('GET', 'books/{book}', ['uses' => 'BookController@show'])\n        );\n\n        $this->assertTrue($this->routeCollection->hasNamedRoute('users'));\n        $this->assertTrue($this->routeCollection->hasNamedRoute('posts'));\n        $this->assertFalse($this->routeCollection->hasNamedRoute('article'));\n        $this->assertFalse($this->routeCollection->hasNamedRoute('books'));\n    }\n\n    public function testToSymfonyRouteCollection()\n    {\n        $this->routeCollection->add(\n            new Route('GET', 'users', ['uses' => 'UsersController@index', 'as' => 'users'])\n        );\n\n        $this->assertInstanceOf(\"\\Symfony\\Component\\Routing\\RouteCollection\", $this->routeCollection->toSymfonyRouteCollection());\n    }\n\n    public function testOverlappingRoutesMatchesFirstRoute()\n    {\n        $this->routeCollection->add(\n            new Route('GET', 'users/{id}/{other}', ['uses' => 'UsersController@other', 'as' => 'first'])\n        );\n\n        $this->routeCollection->add(\n            new Route('GET', 'users/{id}/show', ['uses' => 'UsersController@show', 'as' => 'second'])\n        );\n\n        $request = Request::create('users/1/show', 'GET');\n\n        $this->assertCount(2, $this->routeCollection->getRoutes());\n        $this->assertEquals('first', $this->routeCollection->match($request)->getName());\n    }\n\n    public function testPrependsRoutesWithDomain()\n    {\n        $this->routeCollection->add(\n            $noDomainGet1 = new Route('GET', 'no-domain-get1', ['uses' => 'NoDomainController@index'])\n        );\n\n        $this->routeCollection->add(\n            $fooDomainGet1 = (new Route('GET', 'foo-domain-get1', ['uses' => 'FooDomainController@index']))->domain('foo.test')\n        );\n\n        $this->routeCollection->add(\n            $barDomainGet1 = (new Route('GET', 'bar-domain-get1', ['uses' => 'BarDomainController@index']))->domain('bar.test')\n        );\n\n        $this->routeCollection->add(\n            $noDomainGet2 = new Route('GET', 'no-domain-get2', ['uses' => 'NoDomainController@show'])\n        );\n\n        $this->routeCollection->add(\n            $fooDomainGet2 = (new Route('GET', 'foo-domain-get2', ['uses' => 'FooDomainController@show']))->domain('foo.test')\n        );\n\n        $this->routeCollection->add(\n            $barDomainGet2 = (new Route('GET', 'bar-domain-get2', ['uses' => 'BarDomainController@show']))->domain('bar.test')\n        );\n\n        $this->assertSame([\n            $fooDomainGet1,\n            $barDomainGet1,\n            $fooDomainGet2,\n            $barDomainGet2,\n            $noDomainGet1,\n            $noDomainGet2,\n        ], $this->routeCollection->getRoutes());\n\n        $this->assertSame([\n            'GET' => [\n                'foo.testfoo-domain-get1' => $fooDomainGet1,\n                'bar.testbar-domain-get1' => $barDomainGet1,\n\n                'foo.testfoo-domain-get2' => $fooDomainGet2,\n                'bar.testbar-domain-get2' => $barDomainGet2,\n\n                'no-domain-get1' => $noDomainGet1,\n                'no-domain-get2' => $noDomainGet2,\n            ],\n\n            'HEAD' => [\n                'foo.testfoo-domain-get1' => $fooDomainGet1,\n                'bar.testbar-domain-get1' => $barDomainGet1,\n\n                'foo.testfoo-domain-get2' => $fooDomainGet2,\n                'bar.testbar-domain-get2' => $barDomainGet2,\n\n                'no-domain-get1' => $noDomainGet1,\n                'no-domain-get2' => $noDomainGet2,\n            ],\n        ], $this->routeCollection->getRoutesByMethod());\n    }\n}\n"
  },
  {
    "path": "tests/Routing/RouteRegistrarTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse BadMethodCallException;\nuse FooController;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Router;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Stringable;\n\ninclude_once 'Enums.php';\n\nclass RouteRegistrarTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Routing\\Router\n     */\n    protected $router;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = new Router(m::mock(Dispatcher::class), Container::getInstance());\n    }\n\n    public function testMiddlewareFluentRegistration()\n    {\n        $this->router->middleware(['one', 'two'])->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertEquals(['one', 'two'], $this->getRoute()->middleware());\n\n        $this->router->middleware('three', 'four')->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertEquals(['three', 'four'], $this->getRoute()->middleware());\n\n        $this->router->get('users', function () {\n            return 'all-users';\n        })->middleware('five', 'six');\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertEquals(['five', 'six'], $this->getRoute()->middleware());\n\n        $this->router->middleware('seven')->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertEquals(['seven'], $this->getRoute()->middleware());\n    }\n\n    public function testNullNamespaceIsRespected()\n    {\n        $this->router->middleware(['one'])->namespace(null)->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->assertNull($this->getRoute()->getAction()['namespace']);\n    }\n\n    public function testMiddlewareAsStringableObject()\n    {\n        $one = new class implements Stringable\n        {\n            public function __toString()\n            {\n                return 'one';\n            }\n        };\n\n        $this->router->middleware($one)->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame(['one'], $this->getRoute()->middleware());\n    }\n\n    public function testMiddlewareAsStringableObjectOnRouteInstance()\n    {\n        $one = new class implements Stringable\n        {\n            public function __toString()\n            {\n                return 'one';\n            }\n        };\n\n        $this->router->get('users', function () {\n            return 'all-users';\n        })->middleware($one);\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame(['one'], $this->getRoute()->middleware());\n    }\n\n    public function testMiddlewareAsArrayWithStringables()\n    {\n        $one = new class implements Stringable\n        {\n            public function __toString()\n            {\n                return 'one';\n            }\n        };\n\n        $this->router->middleware([$one, 'two'])->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame(['one', 'two'], $this->getRoute()->middleware());\n    }\n\n    public function testMiddlewareAsNull()\n    {\n        $this->router->middleware(null)->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame([], $this->getRoute()->middleware());\n\n        $this->router->get('users', function () {\n            return 'all-users';\n        })->middleware(null);\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame([], $this->getRoute()->middleware());\n    }\n\n    public function testWithoutMiddlewareRegistration()\n    {\n        $this->router->middleware(['one', 'two'])->get('users', function () {\n            return 'all-users';\n        })->withoutMiddleware('one');\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n\n        $this->assertEquals(['one'], $this->getRoute()->excludedMiddleware());\n    }\n\n    public function testGetRouteWithTrashed()\n    {\n        $route = $this->router->get('users', [RouteRegistrarControllerStub::class, 'index'])->withTrashed();\n\n        $this->assertTrue($route->allowsTrashedBindings());\n    }\n\n    public function testResourceWithTrashed()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only(['index', 'destroy'])\n            ->withTrashed([\n                'index',\n                'destroy',\n            ]);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertTrue($route->allowsTrashedBindings());\n        }\n    }\n\n    public function testFallbackRoute()\n    {\n        $route = $this->router->fallback(function () {\n            return 'milwad';\n        });\n\n        $this->assertTrue($route->isFallback);\n    }\n\n    public function testSetFallbackRoute()\n    {\n        $route = $this->router->fallback(function () {\n            return 'milwad';\n        });\n        $route->setFallback(false);\n\n        $this->assertFalse($route->isFallback);\n\n        $route->setFallback(true);\n\n        $this->assertTrue($route->isFallback);\n    }\n\n    public function testCanRegisterGetRouteWithClosureAction()\n    {\n        $this->router->middleware('get-middleware')->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->seeMiddleware('get-middleware');\n    }\n\n    public function testCanRegisterPostRouteWithClosureAction()\n    {\n        $this->router->middleware('post-middleware')->post('users', function () {\n            return 'saved';\n        });\n\n        $this->seeResponse('saved', Request::create('users', 'POST'));\n        $this->seeMiddleware('post-middleware');\n    }\n\n    public function testCanRegisterAnyRouteWithClosureAction()\n    {\n        $this->router->middleware('test-middleware')->any('users', function () {\n            return 'anything';\n        });\n\n        $this->seeResponse('anything', Request::create('users', 'PUT'));\n        $this->seeMiddleware('test-middleware');\n    }\n\n    public function testCanRegisterMatchRouteWithClosureAction()\n    {\n        $this->router->middleware('match-middleware')->match(['DELETE'], 'users', function () {\n            return 'deleted';\n        });\n\n        $this->seeResponse('deleted', Request::create('users', 'DELETE'));\n        $this->seeMiddleware('match-middleware');\n    }\n\n    public function testCanRegisterRouteWithArrayAndClosureAction()\n    {\n        $this->router->middleware('patch-middleware')->patch('users', [function () {\n            return 'updated';\n        }]);\n\n        $this->seeResponse('updated', Request::create('users', 'PATCH'));\n        $this->seeMiddleware('patch-middleware');\n    }\n\n    public function testCanRegisterRouteWithArrayAndClosureUsesAction()\n    {\n        $this->router->middleware('put-middleware')->put('users', ['uses' => function () {\n            return 'replaced';\n        }]);\n\n        $this->seeResponse('replaced', Request::create('users', 'PUT'));\n        $this->seeMiddleware('put-middleware');\n    }\n\n    public function testCanRegisterRouteWithControllerAction()\n    {\n        $this->router->middleware('controller-middleware')\n            ->get('users', RouteRegistrarControllerStub::class.'@index');\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n        $this->seeMiddleware('controller-middleware');\n    }\n\n    public function testCanRegisterRouteWithControllerActionArray()\n    {\n        $this->router->middleware('controller-middleware')\n            ->get('users', [RouteRegistrarControllerStub::class, 'index']);\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n        $this->seeMiddleware('controller-middleware');\n    }\n\n    public function testCanRegisterNamespacedGroupRouteWithControllerActionArray()\n    {\n        $this->router->group(['namespace' => 'WhatEver'], function () {\n            $this->router->middleware('controller-middleware')\n                ->get('users', [RouteRegistrarControllerStub::class, 'index']);\n        });\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n        $this->seeMiddleware('controller-middleware');\n\n        $this->router->group(['namespace' => 'WhatEver'], function () {\n            $this->router->middleware('controller-middleware')\n                ->get('users', ['\\\\'.RouteRegistrarControllerStub::class, 'index']);\n        });\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n        $this->seeMiddleware('controller-middleware');\n    }\n\n    public function testCanRegisterRouteWithArrayAndControllerAction()\n    {\n        $this->router->middleware('controller-middleware')->put('users', [\n            'uses' => RouteRegistrarControllerStub::class.'@index',\n        ]);\n\n        $this->seeResponse('controller', Request::create('users', 'PUT'));\n        $this->seeMiddleware('controller-middleware');\n    }\n\n    public function testCanRegisterGroupWithMiddleware()\n    {\n        $this->router->middleware('group-middleware')->group(function ($router) {\n            $router->get('users', function () {\n                return 'all-users';\n            });\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->seeMiddleware('group-middleware');\n    }\n\n    public function testCanRegisterGroupWithoutMiddleware()\n    {\n        $this->router->withoutMiddleware('one')->group(function ($router) {\n            $router->get('users', function () {\n                return 'all-users';\n            })->middleware(['one', 'two']);\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertEquals(['one'], $this->getRoute()->excludedMiddleware());\n    }\n\n    public function testCanRegisterGroupWithStringableMiddleware()\n    {\n        $one = new class implements Stringable\n        {\n            public function __toString()\n            {\n                return 'one';\n            }\n        };\n\n        $this->router->middleware($one)->group(function ($router) {\n            $router->get('users', function () {\n                return 'all-users';\n            });\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->seeMiddleware('one');\n    }\n\n    public function testCanRegisterGroupWithNamespace()\n    {\n        $this->router->namespace('App\\Http\\Controllers')->group(function ($router) {\n            $router->get('users', 'UsersController@index');\n        });\n\n        $this->assertSame(\n            'App\\Http\\Controllers\\UsersController@index',\n            $this->getRoute()->getAction()['uses']\n        );\n\n        $this->router->namespace('App\\Http\\Controllers')->group(function ($router) {\n            $router->redirect('users', '/');\n        });\n\n        $this->assertSame(\n            '\\Illuminate\\Routing\\RedirectController@__invoke',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testCanRegisterGroupWithPrefix()\n    {\n        $this->router->prefix('api')->group(function ($router) {\n            $router->get('users', 'UsersController@index');\n        });\n\n        $this->assertSame('api/users', $this->getRoute()->uri());\n    }\n\n    public function testCanRegisterGroupWithPrefixAndWhere()\n    {\n        $this->router->prefix('foo/{bar}')->where(['bar' => '[0-9]+'])->group(function ($router) {\n            $router->get('here', function () {\n                return 'good';\n            });\n        });\n\n        $this->seeResponse('good', Request::create('foo/12345/here', 'GET'));\n    }\n\n    public function testCanRegisterGroupWithNamePrefix()\n    {\n        $this->router->name('api.')->group(function ($router) {\n            $router->get('users', 'UsersController@index')->name('users');\n        });\n\n        $this->assertSame('api.users', $this->getRoute()->getName());\n    }\n\n    public function testCanRegisterGroupWithDomain()\n    {\n        $this->router->domain('{account}.myapp.com')->group(function ($router) {\n            $router->get('users', 'UsersController@index');\n        });\n\n        $this->assertSame('{account}.myapp.com', $this->getRoute()->getDomain());\n    }\n\n    public function testCanRegisterGroupWithDomainAndNamePrefix()\n    {\n        $this->router->domain('{account}.myapp.com')->name('api.')->group(function ($router) {\n            $router->get('users', 'UsersController@index')->name('users');\n        });\n\n        $this->assertSame('{account}.myapp.com', $this->getRoute()->getDomain());\n        $this->assertSame('api.users', $this->getRoute()->getName());\n    }\n\n    public function testCanRegisterGroupWithController()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->get('users', 'index');\n        });\n\n        $this->assertSame(\n            RouteRegistrarControllerStub::class.'@index',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testCanOverrideGroupControllerWithStringSyntax()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->get('users', 'UserController@index');\n        });\n\n        $this->assertSame(\n            'UserController@index',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testCanOverrideGroupControllerWithClosureSyntax()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->get('users', function () {\n                return 'hello world';\n            });\n        });\n\n        $this->seeResponse('hello world', Request::create('users', 'GET'));\n    }\n\n    public function testCanOverrideGroupControllerWithInvokableControllerSyntax()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->get('users', InvokableRouteRegistrarControllerStub::class);\n        });\n\n        $this->assertSame(\n            InvokableRouteRegistrarControllerStub::class.'@__invoke',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testWillUseTheLatestGroupController()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->group(['controller' => FooController::class], function ($router) {\n                $router->get('users', 'index');\n            });\n        });\n\n        $this->assertSame(\n            FooController::class.'@index',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testCanOverrideGroupControllerWithArraySyntax()\n    {\n        $this->router->controller(RouteRegistrarControllerStub::class)->group(function ($router) {\n            $router->get('users', [FooController::class, 'index']);\n        });\n\n        $this->assertSame(\n            FooController::class.'@index',\n            $this->getRoute()->getAction()['uses']\n        );\n    }\n\n    public function testRouteGroupingWithoutPrefix()\n    {\n        $this->router->group([], function ($router) {\n            $router->prefix('bar')->get('baz', ['as' => 'baz', function () {\n                return 'hello';\n            }]);\n        });\n        $this->seeResponse('hello', Request::create('bar/baz', 'GET'));\n    }\n\n    public function testRouteGroupChaining()\n    {\n        $this->router\n            ->group([], function ($router) {\n                $router->get('foo', function () {\n                    return 'hello';\n                });\n            })\n            ->group([], function ($router) {\n                $router->get('bar', function () {\n                    return 'goodbye';\n                });\n            });\n\n        $routeCollection = $this->router->getRoutes();\n\n        $this->assertInstanceOf(\\Illuminate\\Routing\\Route::class, $routeCollection->match(Request::create('foo', 'GET')));\n        $this->assertInstanceOf(\\Illuminate\\Routing\\Route::class, $routeCollection->match(Request::create('bar', 'GET')));\n    }\n\n    public function testRegisteringNonApprovedAttributesThrows()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Method Illuminate\\Routing\\RouteRegistrar::unsupportedMethod does not exist.');\n\n        $this->router->domain('foo')->unsupportedMethod('bar')->group(function ($router) {\n            //\n        });\n    }\n\n    public function testCanSetWithoutScopedBindings()\n    {\n        $route = $this->router->withoutScopedBindings()->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->assertTrue($route->preventsScopedBindings());\n    }\n\n    public function testCanSetWithoutScopedBindingsOnGroup()\n    {\n        $this->router->withoutScopedBindings()->group(function ($router) {\n            $router->get('foo', function () {\n                return 'hello';\n            });\n        });\n\n        $route = $this->router->getRoutes()->getRoutes()[0];\n\n        $this->assertTrue($route->preventsScopedBindings());\n    }\n\n    public function testCanSetScopeBindings()\n    {\n        $route = $this->router->scopeBindings()->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->assertTrue($route->enforcesScopedBindings());\n    }\n\n    public function testCanSetScopeBindingsOnGroup()\n    {\n        $this->router->scopeBindings()->group(function ($router) {\n            $router->get('foo', function () {\n                return 'hello';\n            });\n        });\n\n        $route = $this->router->getRoutes()->getRoutes()[0];\n\n        $this->assertTrue($route->enforcesScopedBindings());\n    }\n\n    public function testCanRegisterResource()\n    {\n        $this->router->middleware('resource-middleware')\n            ->resource('users', RouteRegistrarControllerStub::class);\n\n        $this->seeResponse('deleted', Request::create('users/1', 'DELETE'));\n        $this->seeMiddleware('resource-middleware');\n    }\n\n    public function testCanRegisterResourcesWithExceptOption()\n    {\n        $this->router->resources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ], ['except' => ['create', 'show']]);\n\n        $this->assertCount(15, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n        }\n    }\n\n    public function testCanRegisterResourcesWithOnlyOption()\n    {\n        $this->router->resources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ], ['only' => ['create', 'show']]);\n\n        $this->assertCount(6, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n        }\n    }\n\n    public function testCanRegisterResourcesWithoutOption()\n    {\n        $this->router->resources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ]);\n\n        $this->assertCount(21, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n        }\n    }\n\n    public function testCanRegisterResourceWithMissingOption()\n    {\n        $this->router->middleware('resource-middleware')\n            ->resource('users', RouteRegistrarControllerStub::class)\n            ->missing(function () {\n                return 'missing';\n            });\n\n        $this->assertIsCallable($this->router->getRoutes()->getByName('users.show')->getMissing());\n        $this->assertIsCallable($this->router->getRoutes()->getByName('users.edit')->getMissing());\n        $this->assertIsCallable($this->router->getRoutes()->getByName('users.update')->getMissing());\n        $this->assertIsCallable($this->router->getRoutes()->getByName('users.destroy')->getMissing());\n\n        $this->assertNull($this->router->getRoutes()->getByName('users.index')->getMissing());\n        $this->assertNull($this->router->getRoutes()->getByName('users.create')->getMissing());\n        $this->assertNull($this->router->getRoutes()->getByName('users.store')->getMissing());\n    }\n\n    public function testCanAccessRegisteredResourceRoutesAsRouteCollection()\n    {\n        $resource = $this->router->middleware('resource-middleware')\n            ->resource('users', RouteRegistrarControllerStub::class)\n            ->register();\n\n        $this->assertCount(7, $resource->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.index'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.create'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.edit'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testCanLimitMethodsOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only('index', 'show', 'destroy');\n\n        $this->assertCount(3, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.index'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testCanExcludeMethodsOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->except(['index', 'create', 'store', 'show', 'edit']);\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testCanLimitAndExcludeMethodsOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only('index', 'show', 'destroy')\n            ->except('destroy');\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.index'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.show'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testCanSetShallowOptionOnRegisteredResource()\n    {\n        $this->router->resource('users.tasks', RouteRegistrarControllerStub::class)->shallow();\n\n        $this->assertCount(7, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.tasks.index'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('tasks.show'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.tasks.show'));\n    }\n\n    public function testCanSetScopedOptionOnRegisteredResource()\n    {\n        $this->router->resource('users.tasks', RouteRegistrarControllerStub::class)->scoped();\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertSame(\n            ['user' => null],\n            $this->router->getRoutes()->getByName('users.tasks.index')->bindingFields()\n        );\n        $this->assertSame(\n            ['user' => null, 'task' => null],\n            $this->router->getRoutes()->getByName('users.tasks.show')->bindingFields()\n        );\n\n        $this->router->resource('users.tasks', RouteRegistrarControllerStub::class)->scoped([\n            'task' => 'slug',\n        ]);\n        $this->router->getRoutes()->refreshNameLookups();\n        $this->assertSame(\n            ['user' => null],\n            $this->router->getRoutes()->getByName('users.tasks.index')->bindingFields()\n        );\n        $this->assertSame(\n            ['user' => null, 'task' => 'slug'],\n            $this->router->getRoutes()->getByName('users.tasks.show')->bindingFields()\n        );\n    }\n\n    public function testCanExcludeMethodsOnRegisteredApiResource()\n    {\n        $this->router->apiResource('users', RouteRegistrarControllerStub::class)\n            ->except(['index', 'show', 'store']);\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testCanRegisterApiResourcesWithExceptOption()\n    {\n        $this->router->apiResources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ], ['except' => ['create', 'show']]);\n\n        $this->assertCount(12, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n        }\n    }\n\n    public function testCanRegisterApiResourcesWithOnlyOption()\n    {\n        $this->router->apiResources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ], ['only' => ['index', 'show']]);\n\n        $this->assertCount(6, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n        }\n    }\n\n    public function testCanRegisterApiResourcesWithoutOption()\n    {\n        $this->router->apiResources([\n            'resource-one' => RouteRegistrarControllerStubOne::class,\n            'resource-two' => RouteRegistrarControllerStubTwo::class,\n            'resource-three' => RouteRegistrarControllerStubThree::class,\n        ]);\n\n        $this->assertCount(15, $this->router->getRoutes());\n\n        foreach (['one', 'two', 'three'] as $resource) {\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.index'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.show'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.store'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.update'));\n            $this->assertTrue($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.destroy'));\n\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.create'));\n            $this->assertFalse($this->router->getRoutes()->hasNamedRoute('resource-'.$resource.'.edit'));\n        }\n    }\n\n    public function testUserCanRegisterApiResource()\n    {\n        $this->router->apiResource('users', RouteRegistrarControllerStub::class);\n\n        $this->assertCount(5, $this->router->getRoutes());\n\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.create'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.edit'));\n    }\n\n    public function testUserCanRegisterApiResourceWithExceptOption()\n    {\n        $this->router->apiResource('users', RouteRegistrarControllerStub::class, [\n            'except' => ['destroy'],\n        ]);\n\n        $this->assertCount(4, $this->router->getRoutes());\n\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.create'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.edit'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('users.destroy'));\n    }\n\n    public function testUserCanRegisterApiResourceWithOnlyOption()\n    {\n        $this->router->apiResource('users', RouteRegistrarControllerStub::class, [\n            'only' => ['index', 'show'],\n        ]);\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.index'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('users.show'));\n    }\n\n    public function testCanNameRoutesOnRegisteredResource()\n    {\n        $this->router->resource('comments', RouteRegistrarControllerStub::class)\n            ->only('create', 'store')->names('reply');\n\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only('create', 'store')->names([\n                'create' => 'user.build',\n                'store' => 'user.save',\n            ]);\n\n        $this->router->resource('posts', RouteRegistrarControllerStub::class)\n            ->only('create', 'destroy')\n            ->name('create', 'posts.make')\n            ->name('destroy', 'posts.remove');\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('reply.create'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('reply.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.build'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.save'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('posts.make'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('posts.remove'));\n    }\n\n    public function testCanOverrideParametersOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->parameters(['users' => 'admin_user']);\n\n        $this->router->resource('posts', RouteRegistrarControllerStub::class)\n            ->parameter('posts', 'topic');\n\n        $this->assertStringContainsString('admin_user', $this->router->getRoutes()->getByName('users.show')->uri);\n        $this->assertStringContainsString('topic', $this->router->getRoutes()->getByName('posts.show')->uri);\n    }\n\n    public function testCanSetMiddlewareOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->middleware(RouteRegistrarMiddlewareStub::class);\n\n        $this->seeMiddleware(RouteRegistrarMiddlewareStub::class);\n    }\n\n    public function testCanSetMiddlewareCanOnGroups()\n    {\n        $this->router->can('test')->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->seeMiddleware('can:test');\n    }\n\n    public function testCanSetMiddlewareCanWithModelsOnGroups()\n    {\n        $this->router->can('view', 'post')->group(function ($router) {\n            $router->get('/post/{post}');\n        });\n\n        $this->seeMiddleware('can:view,post');\n    }\n\n    public function testCanSetMiddlewareCanNestedOnGroups()\n    {\n        $this->router->can('access-admin')->group(function ($router) {\n            $router->can('edit', 'post')->group(function ($router) {\n                $router->get('/post/{post}/edit');\n            });\n        });\n\n        $this->assertEquals([\n            'can:access-admin',\n            'can:edit,post',\n        ], $this->getRoute()->middleware());\n    }\n\n    public function testCanSetMiddlewareForSpecifiedMethodsOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->middleware('default')\n            ->middlewareFor('index', RouteRegistrarMiddlewareStub::class)\n            ->middlewareFor(['create', 'store'], 'one')\n            ->middlewareFor(['edit'], ['one', 'two']);\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.index')->gatherMiddleware(), ['default', RouteRegistrarMiddlewareStub::class]);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->gatherMiddleware(), ['default', 'one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->gatherMiddleware(), ['default', 'one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->gatherMiddleware(), ['default', 'one', 'two']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->gatherMiddleware(), ['default']);\n\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->middlewareFor('index', RouteRegistrarMiddlewareStub::class)\n            ->middlewareFor(['create', 'store'], 'one')\n            ->middlewareFor(['edit'], ['one', 'two'])\n            ->middleware('default');\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.index')->gatherMiddleware(), [RouteRegistrarMiddlewareStub::class, 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->gatherMiddleware(), ['one', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->gatherMiddleware(), ['one', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->gatherMiddleware(), ['one', 'two', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->gatherMiddleware(), ['default']);\n    }\n\n    public function testResourceWithoutMiddlewareRegistration()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only('index')\n            ->middleware(['one', 'two'])\n            ->withoutMiddleware('one');\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n\n        $this->assertEquals(['one'], $this->getRoute()->excludedMiddleware());\n    }\n\n    public function testCanSetExcludedMiddlewareForSpecifiedMethodsOnRegisteredResource()\n    {\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->withoutMiddleware('one')\n            ->withoutMiddlewareFor('index', 'two')\n            ->withoutMiddlewareFor(['create', 'store'], 'three')\n            ->withoutMiddlewareFor(['edit'], ['four', 'five']);\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.index')->excludedMiddleware(), ['one', 'two']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->excludedMiddleware(), ['one', 'three']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->excludedMiddleware(), ['one', 'three']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->excludedMiddleware(), ['one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->excludedMiddleware(), ['one', 'four', 'five']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->excludedMiddleware(), ['one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->excludedMiddleware(), ['one']);\n    }\n\n    public function testResourceWithMiddlewareAsStringable()\n    {\n        $one = new class implements Stringable\n        {\n            public function __toString()\n            {\n                return 'one';\n            }\n        };\n\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->only('index')\n            ->middleware([$one, 'two'])\n            ->withoutMiddleware('one');\n\n        $this->seeResponse('controller', Request::create('users', 'GET'));\n\n        $this->assertEquals(['one', 'two'], $this->getRoute()->middleware());\n        $this->assertEquals(['one'], $this->getRoute()->excludedMiddleware());\n    }\n\n    public function testResourceWheres()\n    {\n        $wheres = [\n            'user' => '\\d+',\n            'test' => '[a-z]+',\n        ];\n\n        $this->router->resource('users', RouteRegistrarControllerStub::class)\n            ->where($wheres);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testWhereNumberRegistration()\n    {\n        $wheres = ['foo' => '[0-9]+', 'bar' => '[0-9]+'];\n\n        $this->router->get('/{foo}/{bar}')->whereNumber(['foo', 'bar']);\n        $this->router->get('/api/{bar}/{foo}')->whereNumber(['bar', 'foo']);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testWhereAlphaRegistration()\n    {\n        $wheres = ['foo' => '[a-zA-Z]+', 'bar' => '[a-zA-Z]+'];\n\n        $this->router->get('/{foo}/{bar}')->whereAlpha(['foo', 'bar']);\n        $this->router->get('/api/{bar}/{foo}')->whereAlpha(['bar', 'foo']);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testWhereAlphaNumericRegistration()\n    {\n        $wheres = ['1a2b3c' => '[a-zA-Z0-9]+'];\n\n        $this->router->get('/{foo}')->whereAlphaNumeric(['1a2b3c']);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testWhereInRegistration()\n    {\n        $wheres = ['foo' => 'one|two', 'bar' => 'one|two'];\n\n        $this->router->get('/{foo}/{bar}')->whereIn(['foo', 'bar'], ['one', 'two']);\n        $this->router->get('/api/{bar}/{foo}')->whereIn(['bar', 'foo'], ['one', 'two']);\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testWhereInEnumRegistration()\n    {\n        $this->router->get('/posts/{category}')->whereIn('category', CategoryBackedEnum::cases());\n\n        $invalidRequest = Request::create('/posts/invalid-value', 'GET');\n        $this->assertFalse($this->getRoute()->matches($invalidRequest));\n\n        foreach (CategoryBackedEnum::cases() as $case) {\n            $request = Request::create('/posts/'.$case->value, 'GET');\n            $this->assertTrue($this->getRoute()->matches($request));\n        }\n    }\n\n    public function testGroupWhereNumberRegistrationOnRouteRegistrar()\n    {\n        $wheres = ['foo' => '[0-9]+', 'bar' => '[0-9]+'];\n\n        $this->router->prefix('/{foo}/{bar}')->whereNumber(['foo', 'bar'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->prefix('/api/{bar}/{foo}')->whereNumber(['bar', 'foo'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereAlphaRegistrationOnRouteRegistrar()\n    {\n        $wheres = ['foo' => '[a-zA-Z]+', 'bar' => '[a-zA-Z]+'];\n\n        $this->router->prefix('/{foo}/{bar}')->whereAlpha(['foo', 'bar'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->prefix('/api/{bar}/{foo}')->whereAlpha(['bar', 'foo'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereAlphaNumericRegistrationOnRouteRegistrar()\n    {\n        $wheres = ['1a2b3c' => '[a-zA-Z0-9]+'];\n\n        $this->router->prefix('/{foo}')->whereAlphaNumeric(['1a2b3c'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereInRegistrationOnRouteRegistrar()\n    {\n        $wheres = ['foo' => 'one|two', 'bar' => 'one|two'];\n\n        $this->router->prefix('/{foo}/{bar}')->whereIn(['foo', 'bar'], ['one', 'two'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->prefix('/api/{bar}/{foo}')->whereIn(['bar', 'foo'], ['one', 'two'])->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereNumberRegistrationOnRouter()\n    {\n        $wheres = ['foo' => '[0-9]+', 'bar' => '[0-9]+'];\n\n        $this->router->whereNumber(['foo', 'bar'])->prefix('/{foo}/{bar}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->whereNumber(['bar', 'foo'])->prefix('/api/{bar}/{foo}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereAlphaRegistrationOnRouter()\n    {\n        $wheres = ['foo' => '[a-zA-Z]+', 'bar' => '[a-zA-Z]+'];\n\n        $this->router->whereAlpha(['foo', 'bar'])->prefix('/{foo}/{bar}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->whereAlpha(['bar', 'foo'])->prefix('/api/{bar}/{foo}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereAlphaNumericRegistrationOnRouter()\n    {\n        $wheres = ['1a2b3c' => '[a-zA-Z0-9]+'];\n\n        $this->router->whereAlphaNumeric(['1a2b3c'])->prefix('/{foo}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testGroupWhereInRegistrationOnRouter()\n    {\n        $wheres = ['foo' => 'one|two', 'bar' => 'one|two'];\n\n        $this->router->whereIn(['foo', 'bar'], ['one', 'two'])->prefix('/{foo}/{bar}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        $this->router->whereIn(['bar', 'foo'], ['one', 'two'])->prefix('/api/{bar}/{foo}')->group(function ($router) {\n            $router->get('/');\n        });\n\n        /** @var \\Illuminate\\Routing\\Route $route */\n        foreach ($this->router->getRoutes() as $route) {\n            $this->assertEquals($wheres, $route->wheres);\n        }\n    }\n\n    public function testCanSetRouteName()\n    {\n        $this->router->as('users.index')->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame('users.index', $this->getRoute()->getName());\n    }\n\n    public function testCanSetRouteNameUsingNameAlias()\n    {\n        $this->router->name('users.index')->get('users', function () {\n            return 'all-users';\n        });\n\n        $this->seeResponse('all-users', Request::create('users', 'GET'));\n        $this->assertSame('users.index', $this->getRoute()->getName());\n    }\n\n    public function testCanSetRouteNameUsingStringBackedEnum()\n    {\n        $this->router->name(RouteNameEnum::UserIndex)->get('users', fn () => 'all-users');\n\n        $this->assertSame('users.index', $this->getRoute()->getName());\n    }\n\n    public function testCannotSetRouteNameUsingIntegerBackedEnum()\n    {\n        $this->expectExceptionObject(new \\InvalidArgumentException('Attribute [name] expects a string backed enum.'));\n\n        $this->router->name(IntegerEnum::One)->get('users', fn () => 'all-users');\n    }\n\n    public function testCanSetRouteDomainUsingStringBackedEnum()\n    {\n        $this->router->domain(RouteDomainEnum::DashboardDomain)->get('users', fn () => 'all-users');\n\n        $this->assertSame('dashboard.myapp.com', $this->getRoute()->getDomain());\n    }\n\n    public function testCannotSetRouteDomainUsingIntegerBackedEnum()\n    {\n        $this->expectExceptionObject(new \\InvalidArgumentException('Attribute [domain] expects a string backed enum.'));\n\n        $this->router->domain(IntegerEnum::One)->get('users', fn () => 'all-users');\n    }\n\n    public function testPushMiddlewareToGroup()\n    {\n        $this->router->middlewareGroup('web', []);\n        $this->router->pushMiddlewareToGroup('web', 'test-middleware');\n\n        $this->assertEquals(['test-middleware'], $this->router->getMiddlewareGroups()['web']);\n    }\n\n    public function testPushMiddlewareToGroupUnregisteredGroup()\n    {\n        $this->router->pushMiddlewareToGroup('web', 'test-middleware');\n\n        $this->assertEquals(['test-middleware'], $this->router->getMiddlewareGroups()['web']);\n    }\n\n    public function testPushMiddlewareToGroupDuplicatedMiddleware()\n    {\n        $this->router->pushMiddlewareToGroup('web', 'test-middleware');\n        $this->router->pushMiddlewareToGroup('web', 'test-middleware');\n\n        $this->assertEquals(['test-middleware'], $this->router->getMiddlewareGroups()['web']);\n    }\n\n    public function testCanRemoveMiddlewareFromGroup()\n    {\n        $this->router->pushMiddlewareToGroup('web', 'test-middleware');\n\n        $this->router->removeMiddlewareFromGroup('web', 'test-middleware');\n\n        $this->assertEquals([], $this->router->getMiddlewareGroups()['web']);\n    }\n\n    public function testCanRemoveMiddlewareFromGroupNotUnregisteredMiddleware()\n    {\n        $this->router->middlewareGroup('web', []);\n\n        $this->router->removeMiddlewareFromGroup('web', 'different-test-middleware');\n\n        $this->assertEquals([], $this->router->getMiddlewareGroups()['web']);\n    }\n\n    public function testCanRemoveMiddlewareFromGroupUnregisteredGroup()\n    {\n        $this->router->removeMiddlewareFromGroup('web', ['test-middleware']);\n\n        $this->assertEquals([], $this->router->getMiddlewareGroups());\n    }\n\n    public function testCanRegisterSingleton()\n    {\n        $this->router->singleton('user', RouteRegistrarControllerStub::class);\n\n        $this->assertCount(3, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.edit'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n    }\n\n    public function testCanRegisterApiSingleton()\n    {\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class);\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n    }\n\n    public function testCanRegisterCreatableSingleton()\n    {\n        $this->router->singleton('user', RouteRegistrarControllerStub::class)->creatable();\n\n        $this->assertCount(6, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.create'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.edit'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testCanRegisterCreatableApiSingleton()\n    {\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)->creatable();\n\n        $this->assertCount(4, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testSingletonCreatableNotDestroyable()\n    {\n        $this->router->singleton('user', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->except('destroy');\n\n        $this->assertCount(5, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.create'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.edit'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testApiSingletonCreatableNotDestroyable()\n    {\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->except('destroy');\n\n        $this->assertCount(3, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertFalse($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testSingletonCanBeDestroyable()\n    {\n        $this->router->singleton('user', RouteRegistrarControllerStub::class)\n            ->destroyable();\n\n        $this->assertCount(4, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.edit'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testApiSingletonCanBeDestroyable()\n    {\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)\n            ->destroyable();\n\n        $this->assertCount(3, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.show'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.update'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.destroy'));\n    }\n\n    public function testSingletonCanBeOnlyCreatable()\n    {\n        $this->router->singleton('user', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->only('create', 'store');\n\n        $this->assertCount(2, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.create'));\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n    }\n\n    public function testApiSingletonCanBeOnlyCreatable()\n    {\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->only('store');\n\n        $this->assertCount(1, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.store'));\n    }\n\n    public function testSingletonDoesntAllowIncludingUnsupportedMethods()\n    {\n        $this->router->singleton('post', RouteRegistrarControllerStub::class)\n            ->only('index', 'store', 'create', 'destroy');\n\n        $this->assertCount(0, $this->router->getRoutes());\n\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)\n            ->only('index', 'store', 'create', 'destroy');\n\n        $this->assertCount(0, $this->router->getRoutes());\n    }\n\n    public function testApiSingletonCanIncludeAnySingletonMethods()\n    {\n        // This matches the behavior of the apiResource method.\n        $this->router->apiSingleton('user', RouteRegistrarControllerStub::class)\n            ->only('edit');\n\n        $this->assertCount(1, $this->router->getRoutes());\n\n        $this->assertTrue($this->router->getRoutes()->hasNamedRoute('user.edit'));\n    }\n\n    public function testCanSetMiddlewareForSpecifiedMethodsOnRegisteredSingletonResource()\n    {\n        $this->router->singleton('users', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->destroyable()\n            ->middleware('default')\n            ->middlewareFor('show', RouteRegistrarMiddlewareStub::class)\n            ->middlewareFor(['create', 'store'], 'one')\n            ->middlewareFor(['edit'], ['one', 'two']);\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->gatherMiddleware(), ['default', 'one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->gatherMiddleware(), ['default', 'one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->gatherMiddleware(), ['default', RouteRegistrarMiddlewareStub::class]);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->gatherMiddleware(), ['default', 'one', 'two']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->gatherMiddleware(), ['default']);\n\n        $this->router->singleton('users', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->destroyable()\n            ->middlewareFor('show', RouteRegistrarMiddlewareStub::class)\n            ->middlewareFor(['create', 'store'], 'one')\n            ->middlewareFor(['edit'], ['one', 'two'])\n            ->middleware('default');\n        $this->router->getRoutes()->refreshNameLookups();\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->gatherMiddleware(), ['one', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->gatherMiddleware(), ['one', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->gatherMiddleware(), [RouteRegistrarMiddlewareStub::class, 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->gatherMiddleware(), ['one', 'two', 'default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->gatherMiddleware(), ['default']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->gatherMiddleware(), ['default']);\n    }\n\n    public function testCanSetExcludedMiddlewareForSpecifiedMethodsOnRegisteredSingletonResource()\n    {\n        $this->router->singleton('users', RouteRegistrarControllerStub::class)\n            ->creatable()\n            ->destroyable()\n            ->withoutMiddleware('one')\n            ->withoutMiddlewareFor('show', 'two')\n            ->withoutMiddlewareFor(['create', 'store'], 'three')\n            ->withoutMiddlewareFor(['edit'], ['four', 'five']);\n\n        $this->assertEquals($this->router->getRoutes()->getByName('users.create')->excludedMiddleware(), ['one', 'three']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.store')->excludedMiddleware(), ['one', 'three']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.show')->excludedMiddleware(), ['one', 'two']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.edit')->excludedMiddleware(), ['one', 'four', 'five']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.update')->excludedMiddleware(), ['one']);\n        $this->assertEquals($this->router->getRoutes()->getByName('users.destroy')->excludedMiddleware(), ['one']);\n    }\n\n    /**\n     * Get the last route registered with the router.\n     *\n     * @return \\Illuminate\\Routing\\Route\n     */\n    protected function getRoute()\n    {\n        return last($this->router->getRoutes()->get());\n    }\n\n    /**\n     * Assert that the last route has the given middleware.\n     *\n     * @param  string  $middleware\n     * @return void\n     */\n    protected function seeMiddleware($middleware)\n    {\n        $this->assertEquals($middleware, $this->getRoute()->middleware()[0]);\n    }\n\n    /**\n     * Assert that the last route has the given content.\n     *\n     * @param  string  $content\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return void\n     */\n    protected function seeResponse($content, Request $request)\n    {\n        $route = $this->getRoute();\n\n        $this->assertTrue($route->matches($request));\n\n        $this->assertEquals($content, $route->bind($request)->run());\n    }\n}\n\nclass RouteRegistrarControllerStub\n{\n    public function index()\n    {\n        return 'controller';\n    }\n\n    public function destroy()\n    {\n        return 'deleted';\n    }\n}\n\nclass InvokableRouteRegistrarControllerStub\n{\n    public function __invoke()\n    {\n        return 'controller';\n    }\n}\n\nclass RouteRegistrarMiddlewareStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Routing/RouteSignatureParametersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Routing\\RouteSignatureParameters;\nuse Laravel\\SerializableClosure\\SerializableClosure;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionParameter;\n\nclass RouteSignatureParametersTest extends TestCase\n{\n    public function test_it_can_extract_the_route_action_signature_parameters()\n    {\n        $callable = function (SignatureParametersUser $user) {\n            return $user;\n        };\n\n        $action = ['uses' => serialize(\n            new SerializableClosure($callable)\n        )];\n\n        $parameters = RouteSignatureParameters::fromAction($action);\n\n        $this->assertContainsOnlyInstancesOf(ReflectionParameter::class, $parameters);\n        $this->assertSame('user', $parameters[0]->getName());\n    }\n}\n\nclass SignatureParametersUser extends Model\n{\n    //\n}\n"
  },
  {
    "path": "tests/Routing/RouteUriTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Routing\\RouteUri;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RouteUriTest extends TestCase\n{\n    #[DataProvider('uriProvider')]\n    public function testRouteUrisAreProperlyParsed($uri, $expectedParsedUri, $expectedBindingFields)\n    {\n        $parsed = RouteUri::parse($uri);\n        $this->assertSame($expectedParsedUri, $parsed->uri);\n        $this->assertEquals($expectedBindingFields, $parsed->bindingFields);\n    }\n\n    /**\n     * @return array\n     */\n    public static function uriProvider()\n    {\n        return [\n            [\n                '/foo',\n                '/foo',\n                [],\n            ],\n            [\n                '/foo/{bar}',\n                '/foo/{bar}',\n                [],\n            ],\n            [\n                '/foo/{bar}/baz/{qux}',\n                '/foo/{bar}/baz/{qux}',\n                [],\n            ],\n            [\n                '/foo/{bar}/baz/{qux?}',\n                '/foo/{bar}/baz/{qux?}',\n                [],\n            ],\n            [\n                '/foo/{bar:slug}',\n                '/foo/{bar}',\n                ['bar' => 'slug'],\n            ],\n            [\n                '/foo/{bar}/baz/{qux:slug}',\n                '/foo/{bar}/baz/{qux}',\n                ['qux' => 'slug'],\n            ],\n            [\n                '/foo/{bar}/baz/{qux:slug}',\n                '/foo/{bar}/baz/{qux}',\n                ['qux' => 'slug'],\n            ],\n            [\n                '/foo/{bar}/baz/{qux:slug?}',\n                '/foo/{bar}/baz/{qux?}',\n                ['qux' => 'slug'],\n            ],\n            [\n                '/foo/{bar}/baz/{qux:slug?}/{test:id?}',\n                '/foo/{bar}/baz/{qux?}/{test?}',\n                ['qux' => 'slug', 'test' => 'id'],\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Routing/RoutingRedirectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Redirector;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Session\\Store;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\HeaderBag;\n\nclass RoutingRedirectorTest extends TestCase\n{\n    protected $headers;\n    protected $request;\n    protected $url;\n    protected $session;\n    protected $redirect;\n\n    protected function setUp(): void\n    {\n        $this->headers = m::mock(HeaderBag::class);\n\n        $this->request = m::mock(Request::class);\n        $this->request->shouldReceive('isMethod')->andReturn(true)->byDefault();\n        $this->request->shouldReceive('method')->andReturn('GET')->byDefault();\n        $this->request->shouldReceive('route')->andReturn(true)->byDefault();\n        $this->request->shouldReceive('ajax')->andReturn(false)->byDefault();\n        $this->request->shouldReceive('expectsJson')->andReturn(false)->byDefault();\n        $this->request->headers = $this->headers;\n\n        $this->url = m::mock(UrlGenerator::class);\n        $this->url->shouldReceive('getRequest')->andReturn($this->request);\n        $this->url->shouldReceive('to')->with('bar', [], null)->andReturn('http://foo.com/bar');\n        $this->url->shouldReceive('to')->with('bar', [], true)->andReturn('https://foo.com/bar');\n        $this->url->shouldReceive('to')->with('login', [], null)->andReturn('http://foo.com/login');\n        $this->url->shouldReceive('to')->with('http://foo.com/bar', [], null)->andReturn('http://foo.com/bar');\n        $this->url->shouldReceive('to')->with('/', [], null)->andReturn('http://foo.com/');\n        $this->url->shouldReceive('to')->with('http://foo.com/bar?signature=secret', [], null)->andReturn('http://foo.com/bar?signature=secret');\n\n        $this->session = m::mock(Store::class);\n\n        $this->redirect = new Redirector($this->url);\n        $this->redirect->setSession($this->session);\n    }\n\n    public function testBasicRedirectTo()\n    {\n        $response = $this->redirect->to('bar');\n\n        $this->assertInstanceOf(RedirectResponse::class, $response);\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n        $this->assertEquals(302, $response->getStatusCode());\n        $this->assertEquals($this->session, $response->getSession());\n    }\n\n    public function testComplexRedirectTo()\n    {\n        $response = $this->redirect->to('bar', 303, ['X-RateLimit-Limit' => 60, 'X-RateLimit-Remaining' => 59], true);\n\n        $this->assertSame('https://foo.com/bar', $response->getTargetUrl());\n        $this->assertEquals(303, $response->getStatusCode());\n        $this->assertEquals(60, $response->headers->get('X-RateLimit-Limit'));\n        $this->assertEquals(59, $response->headers->get('X-RateLimit-Remaining'));\n    }\n\n    public function testGuestPutCurrentUrlInSession()\n    {\n        $this->url->shouldReceive('full')->andReturn('http://foo.com/bar');\n        $this->session->shouldReceive('put')->once()->with('url.intended', 'http://foo.com/bar');\n\n        $response = $this->redirect->guest('login');\n\n        $this->assertSame('http://foo.com/login', $response->getTargetUrl());\n    }\n\n    public function testGuestPutPreviousUrlInSession()\n    {\n        $this->request->shouldReceive('isMethod')->once()->with('GET')->andReturn(false);\n        $this->session->shouldReceive('put')->once()->with('url.intended', 'http://foo.com/bar');\n        $this->url->shouldReceive('previous')->once()->andReturn('http://foo.com/bar');\n\n        $response = $this->redirect->guest('login');\n\n        $this->assertSame('http://foo.com/login', $response->getTargetUrl());\n    }\n\n    public function testIntendedRedirectToIntendedUrlInSession()\n    {\n        $this->session->shouldReceive('pull')->with('url.intended', '/')->andReturn('http://foo.com/bar');\n\n        $response = $this->redirect->intended();\n\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testIntendedWithoutIntendedUrlInSession()\n    {\n        $this->session->shouldReceive('forget')->with('url.intended');\n\n        // without fallback url\n        $this->session->shouldReceive('pull')->with('url.intended', '/')->andReturn('/');\n        $response = $this->redirect->intended();\n        $this->assertSame('http://foo.com/', $response->getTargetUrl());\n\n        // with a fallback url\n        $this->session->shouldReceive('pull')->with('url.intended', 'bar')->andReturn('bar');\n        $response = $this->redirect->intended('bar');\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testRefreshRedirectToCurrentUrl()\n    {\n        $this->request->shouldReceive('path')->andReturn('http://foo.com/bar');\n        $response = $this->redirect->refresh();\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testBackRedirectToHttpReferer()\n    {\n        $this->headers->shouldReceive('has')->with('referer')->andReturn(true);\n        $this->url->shouldReceive('previous')->andReturn('http://foo.com/bar');\n        $response = $this->redirect->back();\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testAwayDoesntValidateTheUrl()\n    {\n        $response = $this->redirect->away('bar');\n        $this->assertSame('bar', $response->getTargetUrl());\n    }\n\n    public function testSecureRedirectToHttpsUrl()\n    {\n        $response = $this->redirect->secure('bar');\n        $this->assertSame('https://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testAction()\n    {\n        $this->url->shouldReceive('action')->with('bar@index', [])->andReturn('http://foo.com/bar');\n        $response = $this->redirect->action('bar@index');\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testRoute()\n    {\n        $this->url->shouldReceive('route')->with('home')->andReturn('http://foo.com/bar');\n        $this->url->shouldReceive('route')->with('home', [])->andReturn('http://foo.com/bar');\n\n        $response = $this->redirect->route('home');\n        $this->assertSame('http://foo.com/bar', $response->getTargetUrl());\n    }\n\n    public function testSignedRoute()\n    {\n        $this->url->shouldReceive('signedRoute')->with('home', [], null)->andReturn('http://foo.com/bar?signature=secret');\n\n        $response = $this->redirect->signedRoute('home');\n        $this->assertSame('http://foo.com/bar?signature=secret', $response->getTargetUrl());\n    }\n\n    public function testTemporarySignedRoute()\n    {\n        $this->url->shouldReceive('temporarySignedRoute')->with('home', 10, [])->andReturn('http://foo.com/bar?signature=secret');\n\n        $response = $this->redirect->temporarySignedRoute('home', 10);\n        $this->assertSame('http://foo.com/bar?signature=secret', $response->getTargetUrl());\n    }\n\n    public function testItSetsAndGetsValidIntendedUrl()\n    {\n        $this->session->shouldReceive('put')->once()->with('url.intended', 'http://foo.com/bar');\n        $this->session->shouldReceive('get')->andReturn('http://foo.com/bar');\n\n        $result = $this->redirect->setIntendedUrl('http://foo.com/bar');\n        $this->assertInstanceOf(Redirector::class, $result);\n\n        $this->assertSame('http://foo.com/bar', $this->redirect->getIntendedUrl());\n    }\n}\n"
  },
  {
    "path": "tests/Routing/RoutingRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Attribute;\nuse Closure;\nuse DateTime;\nuse Exception;\nuse Illuminate\\Auth\\Middleware\\Authenticate;\nuse Illuminate\\Auth\\Middleware\\Authorize;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Attributes\\Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Contracts\\Support\\Responsable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\ModelNotFoundException;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Http\\Exceptions\\HttpResponseException;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\CallableDispatcher;\nuse Illuminate\\Routing\\Contracts\\CallableDispatcher as CallableDispatcherContract;\nuse Illuminate\\Routing\\Contracts\\ControllerDispatcher as ControllerDispatcherContract;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Routing\\ControllerDispatcher;\nuse Illuminate\\Routing\\Events\\PreparingResponse;\nuse Illuminate\\Routing\\Events\\ResponsePrepared;\nuse Illuminate\\Routing\\Events\\Routing;\nuse Illuminate\\Routing\\Exceptions\\UrlGenerationException;\nuse Illuminate\\Routing\\Middleware\\SubstituteBindings;\nuse Illuminate\\Routing\\ResourceRegistrar;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\RouteCollection;\nuse Illuminate\\Routing\\RouteGroup;\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Str;\nuse LogicException;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\nuse Symfony\\Component\\HttpFoundation\\Response as SymfonyResponse;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse UnexpectedValueException;\n\ninclude_once __DIR__.'/Enums.php';\n\nclass RoutingRouteTest extends TestCase\n{\n    public function testBasicDispatchingOfRoutes()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            throw new HttpResponseException(new Response('hello'));\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['domain' => 'api.{name}.bar', function ($name) {\n            return $name;\n        }]);\n        $router->get('foo/bar', ['domain' => 'api.{name}.baz', function ($name) {\n            return $name;\n        }]);\n        $this->assertSame('taylor', $router->dispatch(Request::create('http://api.taylor.bar/foo/bar', 'GET'))->getContent());\n        $this->assertSame('dayle', $router->dispatch(Request::create('http://api.dayle.baz/foo/bar', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/{age}', ['domain' => 'api.{name}.bar', function ($name, $age) {\n            return $name.$age;\n        }]);\n        $this->assertSame('taylor25', $router->dispatch(Request::create('http://api.taylor.bar/foo/25', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $router->post('foo/bar', function () {\n            return 'post hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertSame('post hello', $router->dispatch(Request::create('foo/bar', 'POST'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', function ($name) {\n            return $name;\n        });\n        $this->assertSame('taylor', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/{bar}/{baz?}', function ($name, $age = 25) {\n            return $name.$age;\n        });\n        $this->assertSame('taylor25', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/{name}/boom/{age?}/{location?}', function ($name, $age = 25, $location = 'AR') {\n            return $name.$age.$location;\n        });\n        $this->assertSame('taylor30AR', $router->dispatch(Request::create('foo/taylor/boom/30', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('{bar}/{baz?}', function ($name, $age = 25) {\n            return $name.$age;\n        });\n        $this->assertSame('taylor25', $router->dispatch(Request::create('taylor', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('{baz?}', function ($age = 25) {\n            return $age;\n        });\n        $this->assertSame('25', $router->dispatch(Request::create('/', 'GET'))->getContent());\n        $this->assertSame('30', $router->dispatch(Request::create('30', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('{foo?}/{baz?}', ['as' => 'foo', function ($name = 'taylor', $age = 25) {\n            return $name.$age;\n        }]);\n        $this->assertSame('taylor25', $router->dispatch(Request::create('/', 'GET'))->getContent());\n        $this->assertSame('fred25', $router->dispatch(Request::create('fred', 'GET'))->getContent());\n        $this->assertSame('fred30', $router->dispatch(Request::create('fred/30', 'GET'))->getContent());\n        $this->assertTrue($router->currentRouteNamed('foo'));\n        $this->assertTrue($router->currentRouteNamed('fo*'));\n        $this->assertTrue($router->is('foo'));\n        $this->assertTrue($router->is('foo', 'bar'));\n        $this->assertFalse($router->is('bar'));\n\n        $router = $this->getRouter();\n        $router->get('foo/{file}', function ($file) {\n            return $file;\n        });\n        $this->assertSame('oxygen%20', $router->dispatch(Request::create('http://test.com/foo/oxygen%2520', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->patch('foo/bar', ['as' => 'foo', function () {\n            return 'bar';\n        }]);\n        $this->assertSame('bar', $router->dispatch(Request::create('foo/bar', 'PATCH'))->getContent());\n        $this->assertSame('foo', $router->currentRouteName());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $this->assertEmpty($router->dispatch(Request::create('foo/bar', 'HEAD'))->getContent());\n\n        $router = $this->getRouter();\n        $router->any('foo/bar', function () {\n            return 'hello';\n        });\n        $this->assertEmpty($router->dispatch(Request::create('foo/bar', 'HEAD'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'first';\n        });\n        $router->get('foo/bar', function () {\n            return 'second';\n        });\n        $this->assertSame('second', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar/åαф', function () {\n            return 'hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar/%C3%A5%CE%B1%D1%84', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['boom' => 'auth', function () {\n            return 'closure';\n        }]);\n        $this->assertSame('closure', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n    }\n\n    public function testNotModifiedResponseIsProperlyReturned()\n    {\n        $router = $this->getRouter();\n        $router->get('test', function () {\n            return (new SymfonyResponse('test', 304, ['foo' => 'bar']))->setLastModified(new DateTime);\n        });\n\n        $response = $router->dispatch(Request::create('test', 'GET'));\n        $this->assertSame(304, $response->getStatusCode());\n        $this->assertEmpty($response->getContent());\n        $this->assertSame('bar', $response->headers->get('foo'));\n        $this->assertNull($response->getLastModified());\n    }\n\n    public function testClosureMiddleware()\n    {\n        $router = $this->getRouter();\n        $middleware = function ($request, $next) {\n            return 'caught';\n        };\n        $router->get('foo/bar', ['middleware' => $middleware, function () {\n            return 'hello';\n        }]);\n        $this->assertSame('caught', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n    }\n\n    public function testMiddlewareCanBeSkipped()\n    {\n        $router = $this->getRouter();\n        $router->aliasMiddleware('web', RoutingTestMiddlewareGroupTwo::class);\n\n        $router->get('foo/bar', ['middleware' => 'web', function () {\n            return 'hello';\n        }])->withoutMiddleware(RoutingTestMiddlewareGroupTwo::class);\n\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n    }\n\n    public function testMiddlewareCanBeSkippedFromResources()\n    {\n        $router = $this->getRouter();\n        $router->aliasMiddleware('web', RoutingTestMiddlewareGroupTwo::class);\n\n        $router->resource('foo', RouteTestControllerMiddlewareGroupStub::class)\n            ->middleware('web')\n            ->withoutMiddleware(RoutingTestMiddlewareGroupTwo::class);\n\n        $this->assertSame('Hello World', $router->dispatch(Request::create('foo', 'GET'))->getContent());\n    }\n\n    public function testMiddlewareWorksIfControllerThrowsHttpResponseException()\n    {\n        // Before calling controller\n        $router = $this->getRouter();\n        $middleware = function ($request, $next) {\n            return 'caught';\n        };\n        $router->get('foo/bar', ['middleware' => $middleware, function () {\n            throw new HttpResponseException(new Response('hello'));\n        }]);\n        $response = $router->dispatch(Request::create('foo/bar', 'GET'))->getContent();\n        $this->assertSame('caught', $response);\n\n        // After calling controller\n        $router = $this->getRouter();\n\n        $response = new Response('hello');\n\n        $middleware = function ($request, $next) use ($response) {\n            $this->assertSame($response, $next($request));\n\n            return new Response($response->getContent().' caught');\n        };\n        $router->get('foo/bar', ['middleware' => $middleware, function () use ($response) {\n            throw new HttpResponseException($response);\n        }]);\n\n        $response = $router->dispatch(Request::create('foo/bar', 'GET'))->getContent();\n        $this->assertSame('hello caught', $response);\n    }\n\n    public function testReturnsResponseWhenMiddlewareReturnsResponsable()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', [\n            'uses' => RouteTestClosureMiddlewareController::class.'@index',\n            'middleware' => ['foo', 'bar', 'baz'],\n        ]);\n        $router->aliasMiddleware('foo', function ($request, $next) {\n            return $next($request);\n        });\n        $router->aliasMiddleware('bar', function ($request, $next) {\n            return new ResponsableResponse;\n        });\n        $router->aliasMiddleware('baz', function ($request, $next) {\n            return $next($request);\n        });\n        $this->assertSame(\n            'bar',\n            $router->dispatch(Request::create('foo/bar', 'GET'))->getContent()\n        );\n    }\n\n    public function testDefinedClosureMiddleware()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['middleware' => 'foo', function () {\n            return 'hello';\n        }]);\n        $router->aliasMiddleware('foo', function ($request, $next) {\n            return 'caught';\n        });\n        $this->assertSame('caught', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n    }\n\n    public function testControllerClosureMiddleware()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', [\n            'uses' => RouteTestClosureMiddlewareController::class.'@index',\n            'middleware' => 'foo',\n        ]);\n        $router->aliasMiddleware('foo', function ($request, $next) {\n            $request['foo-middleware'] = 'foo-middleware';\n\n            return $next($request);\n        });\n\n        $this->assertSame(\n            'index-foo-middleware-controller-closure',\n            $router->dispatch(Request::create('foo/bar', 'GET'))->getContent()\n        );\n    }\n\n    public function testFluentRouting()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('Route for [foo/bar] has no action.');\n\n        $router = $this->getRouter();\n        $router->get('foo/bar')->uses(function () {\n            return 'hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $router->post('foo/bar')->uses(function () {\n            return 'hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'POST'))->getContent());\n        $router->get('foo/bar')->uses(function () {\n            return 'middleware';\n        })->middleware(RouteTestControllerMiddleware::class);\n        $this->assertSame('middleware', $router->dispatch(Request::create('foo/bar'))->getContent());\n        $this->assertContains(RouteTestControllerMiddleware::class, $router->getCurrentRoute()->middleware());\n        $router->get('foo/bar');\n        $router->dispatch(Request::create('foo/bar', 'GET'));\n    }\n\n    public function testFluentRoutingWithControllerAction()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar')->uses(RouteTestControllerStub::class.'@index');\n        $this->assertSame('Hello World', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router = $this->getRouter();\n        $router->group(['namespace' => 'App'], function ($router) {\n            $router->get('foo/bar')->uses(RouteTestControllerStub::class.'@index');\n        });\n        $action = $router->getRoutes()->getRoutes()[0]->getAction();\n        $this->assertSame('App\\\\'.RouteTestControllerStub::class.'@index', $action['controller']);\n    }\n\n    public function testMiddlewareGroups()\n    {\n        unset($_SERVER['__middleware.group']);\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['middleware' => 'web', function () {\n            return 'hello';\n        }]);\n\n        $router->aliasMiddleware('two', RoutingTestMiddlewareGroupTwo::class);\n        $router->middlewareGroup('web', [RoutingTestMiddlewareGroupOne::class, 'two:taylor']);\n\n        $this->assertSame('caught taylor', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($_SERVER['__middleware.group']);\n\n        unset($_SERVER['__middleware.group']);\n    }\n\n    public function testMiddlewareGroupsCanReferenceOtherGroups()\n    {\n        unset($_SERVER['__middleware.group']);\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['middleware' => 'web', function () {\n            return 'hello';\n        }]);\n\n        $router->aliasMiddleware('two', RoutingTestMiddlewareGroupTwo::class);\n        $router->middlewareGroup('first', ['two:abigail']);\n        $router->middlewareGroup('web', [RoutingTestMiddlewareGroupOne::class, 'first']);\n\n        $this->assertSame('caught abigail', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($_SERVER['__middleware.group']);\n\n        unset($_SERVER['__middleware.group']);\n    }\n\n    public function testFluentRouteNamingWithinAGroup()\n    {\n        $router = $this->getRouter();\n        $router->group(['as' => 'foo.'], function () use ($router) {\n            $router->get('bar', function () {\n                return 'bar';\n            })->name('bar');\n        });\n        $this->assertSame('bar', $router->dispatch(Request::create('bar', 'GET'))->getContent());\n        $this->assertSame('foo.bar', $router->currentRouteName());\n    }\n\n    public function testRouteGetAction()\n    {\n        $router = $this->getRouter();\n\n        $route = $router->get('foo', function () {\n            return 'foo';\n        })->name('foo');\n\n        $this->assertIsArray($route->getAction());\n        $this->assertArrayHasKey('as', $route->getAction());\n        $this->assertSame('foo', $route->getAction('as'));\n        $this->assertNull($route->getAction('unknown_property'));\n    }\n\n    public function testRouteGetControllerClass()\n    {\n        $router = $this->getRouter();\n\n        $controllerRoute = $router->get('foo/bar')->uses(RouteTestControllerStub::class.'@index');\n        $closureRoute = $router->get('foo', function () {\n            return 'foo';\n        });\n\n        $this->assertSame(RouteTestControllerStub::class, $controllerRoute->getControllerClass());\n        $this->assertNull($closureRoute->getControllerClass());\n    }\n\n    public function testResolvingBindingParameters()\n    {\n        $router = $this->getRouter();\n\n        $route = $router->get('foo/{bar:slug}', function () {\n            return 'foo';\n        })->name('foo');\n\n        $this->assertSame('slug', $route->bindingFieldFor('bar'));\n\n        $route = $router->get('foo/{bar:slug}/{baz}', function () {\n            return 'foo';\n        })->name('foo');\n\n        $this->assertNull($route->bindingFieldFor('baz'));\n    }\n\n    public function testMacro()\n    {\n        $router = $this->getRouter();\n        $router->macro('webhook', function () use ($router) {\n            $router->match(['GET', 'POST'], 'webhook', function () {\n                return 'OK';\n            });\n        });\n        $router->webhook();\n        $this->assertSame('OK', $router->dispatch(Request::create('webhook', 'GET'))->getContent());\n        $this->assertSame('OK', $router->dispatch(Request::create('webhook', 'POST'))->getContent());\n    }\n\n    public function testRouteMacro()\n    {\n        $router = $this->getRouter();\n\n        Route::macro('breadcrumb', function ($breadcrumb) {\n            $this->action['breadcrumb'] = $breadcrumb;\n\n            return $this;\n        });\n\n        $router->get('foo', function () {\n            return 'bar';\n        })->breadcrumb('fooBreadcrumb')->name('foo');\n\n        $router->getRoutes()->refreshNameLookups();\n\n        $this->assertSame('fooBreadcrumb', $router->getRoutes()->getByName('foo')->getAction()['breadcrumb']);\n    }\n\n    public function testClassesCanBeInjectedIntoRoutes()\n    {\n        unset($_SERVER['__test.route_inject']);\n        $router = $this->getRouter();\n        $router->get('foo/{var}', function (stdClass $foo, $var) {\n            $_SERVER['__test.route_inject'] = func_get_args();\n\n            return 'hello';\n        });\n\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertInstanceOf(stdClass::class, $_SERVER['__test.route_inject'][0]);\n        $this->assertSame('bar', $_SERVER['__test.route_inject'][1]);\n\n        unset($_SERVER['__test.route_inject']);\n    }\n\n    public function testNullValuesCanBeInjectedIntoRoutes()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n\n        $container->bind(RoutingTestUserModel::class, function () {\n        });\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $router->get('foo/{team}/{post}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?RoutingTestUserModel $userFromContainer, RoutingTestTeamModel $team, $postId) {\n                $this->assertNull($userFromContainer);\n                $this->assertInstanceOf(RoutingTestTeamModel::class, $team);\n                $this->assertSame('bar', $team->value);\n                $this->assertSame('baz', $postId);\n            },\n        ]);\n        $router->dispatch(Request::create('foo/bar/baz', 'GET'))->getContent();\n    }\n\n    public function testOptionsResponsesAreGeneratedByDefault()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $router->post('foo/bar', function () {\n            return 'hello';\n        });\n        $response = $router->dispatch(Request::create('foo/bar', 'OPTIONS'));\n\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('GET,HEAD,POST', $response->headers->get('Allow'));\n    }\n\n    public function testHeadDispatcher()\n    {\n        $router = $this->getRouter();\n        $router->match(['GET', 'POST'], 'foo', function () {\n            return 'bar';\n        });\n\n        $response = $router->dispatch(Request::create('foo', 'OPTIONS'));\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('GET,HEAD,POST', $response->headers->get('Allow'));\n\n        $response = $router->dispatch(Request::create('foo', 'HEAD'));\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertEmpty($response->getContent());\n\n        $router = $this->getRouter();\n        $router->match(['GET'], 'foo', function () {\n            return 'bar';\n        });\n\n        $response = $router->dispatch(Request::create('foo', 'OPTIONS'));\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('GET,HEAD', $response->headers->get('Allow'));\n\n        $router = $this->getRouter();\n        $router->match(['POST'], 'foo', function () {\n            return 'bar';\n        });\n\n        $response = $router->dispatch(Request::create('foo', 'OPTIONS'));\n        $this->assertEquals(200, $response->getStatusCode());\n        $this->assertSame('POST', $response->headers->get('Allow'));\n    }\n\n    public function testNonGreedyMatches()\n    {\n        $route = new Route('GET', 'images/{id}.{ext}', function () {\n            //\n        });\n\n        $request1 = Request::create('images/1.png', 'GET');\n        $this->assertTrue($route->matches($request1));\n        $route->bind($request1);\n        $this->assertTrue($route->hasParameter('id'));\n        $this->assertFalse($route->hasParameter('foo'));\n        $this->assertSame('1', (string) $route->parameter('id'));\n        $this->assertSame('png', $route->parameter('ext'));\n\n        $request2 = Request::create('images/12.png', 'GET');\n        $this->assertTrue($route->matches($request2));\n        $route->bind($request2);\n        $this->assertSame('12', $route->parameter('id'));\n        $this->assertSame('png', $route->parameter('ext'));\n\n        // Test parameter() default value\n        $route = new Route('GET', 'foo/{foo?}', function () {\n            //\n        });\n\n        $request3 = Request::create('foo', 'GET');\n        $this->assertTrue($route->matches($request3));\n        $route->bind($request3);\n        $this->assertSame('bar', $route->parameter('foo', 'bar'));\n    }\n\n    public function testHasParameters()\n    {\n        $route = new Route('GET', 'images/{id}.{ext}', function () {\n            //\n        });\n        $request1 = Request::create('images/1.png', 'GET');\n        $this->assertFalse($route->hasParameters());\n        $this->assertTrue($route->matches($request1));\n        $route->bind($request1);\n        $this->assertTrue($route->hasParameters());\n    }\n\n    public function testForgetParameter()\n    {\n        $route = new Route('GET', 'images/{id}.{ext}', function () {\n            //\n        });\n        $request1 = Request::create('images/1.png', 'GET');\n        $route->bind($request1);\n        $this->assertTrue($route->hasParameter('id'));\n        $this->assertTrue($route->hasParameter('ext'));\n        $route->forgetParameter('id');\n        $this->assertFalse($route->hasParameter('id'));\n        $this->assertTrue($route->hasParameter('ext'));\n    }\n\n    public function testParameterNames()\n    {\n        $route = new Route('GET', 'images/{id}.{ext}', function () {\n            //\n        });\n        $this->assertSame(['id', 'ext'], $route->parameterNames());\n\n        $route = new Route('GET', 'foo/{bar?}', function () {\n            //\n        });\n        $this->assertSame(['bar'], $route->parameterNames());\n\n        $route = new Route('GET', '/', function () {\n            //\n        });\n        $this->assertSame([], $route->parameterNames());\n    }\n\n    public function testParametersWithoutNulls()\n    {\n        $route = new Route('GET', 'users/{id?}/{name?}/', function () {\n            //\n        });\n        $request1 = Request::create('users/12/amir', 'GET');\n        $route->bind($request1);\n        $this->assertSame(['id' => '12', 'name' => 'amir'], $route->parametersWithoutNulls());\n\n        $route = new Route('GET', 'users/{id?}/{name?}/', function () {\n            //\n        });\n        $request1 = Request::create('users/12', 'GET');\n        $route->bind($request1);\n        $this->assertSame(['id' => '12'], $route->parametersWithoutNulls());\n\n        $route = new Route('GET', 'users/{id?}/{name?}/', function () {\n            //\n        });\n        $request1 = Request::create('users/', 'GET');\n        $route->bind($request1);\n        $this->assertSame([], $route->parametersWithoutNulls());\n    }\n\n    public function testRouteParametersDefaultValue()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', ['uses' => RouteTestControllerWithParameterStub::class.'@returnParameter'])->defaults('bar', 'foo');\n        $this->assertSame('foo', $router->dispatch(Request::create('foo', 'GET'))->getContent());\n\n        $router->get('foo/{bar?}', ['uses' => RouteTestControllerWithParameterStub::class.'@returnParameter'])->defaults('bar', 'foo');\n        $this->assertSame('bar', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router->get('foo/{bar?}', function ($bar = '') {\n            return $bar;\n        })->defaults('bar', 'foo');\n        $this->assertSame('foo', $router->dispatch(Request::create('foo', 'GET'))->getContent());\n    }\n\n    public function testControllerCallActionMethodParameters()\n    {\n        $router = $this->getRouter();\n\n        // Has one argument but receives two\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'/{one}/{two}', RouteTestAnotherControllerWithParameterStub::class.'@oneArgument');\n        $router->dispatch(Request::create($str.'/one/two', 'GET'));\n        $this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);\n\n        // Has two arguments and receives two\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'/{one}/{two}', RouteTestAnotherControllerWithParameterStub::class.'@twoArguments');\n        $router->dispatch(Request::create($str.'/one/two', 'GET'));\n        $this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);\n\n        // Has two arguments but with different names from the ones passed from the route\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'/{one}/{two}', RouteTestAnotherControllerWithParameterStub::class.'@differentArgumentNames');\n        $router->dispatch(Request::create($str.'/one/two', 'GET'));\n        $this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);\n\n        // Has two arguments with same name but argument order is reversed\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'/{one}/{two}', RouteTestAnotherControllerWithParameterStub::class.'@reversedArguments');\n        $router->dispatch(Request::create($str.'/one/two', 'GET'));\n        $this->assertEquals(['one' => 'one', 'two' => 'two'], $_SERVER['__test.controller_callAction_parameters']);\n\n        // No route parameters while method has parameters\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'', RouteTestAnotherControllerWithParameterStub::class.'@oneArgument');\n        $router->dispatch(Request::create($str, 'GET'));\n        $this->assertEquals([], $_SERVER['__test.controller_callAction_parameters']);\n\n        // With model bindings\n        unset($_SERVER['__test.controller_callAction_parameters']);\n        $router->get(($str = Str::random()).'/{user}/{defaultNull?}/{team?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => RouteTestAnotherControllerWithParameterStub::class.'@withModels',\n        ]);\n        $router->dispatch(Request::create($str.'/1', 'GET'));\n\n        $values = array_values($_SERVER['__test.controller_callAction_parameters']);\n\n        $this->assertInstanceOf(Request::class, $values[0]);\n        $this->assertEquals(1, $values[1]->value);\n        $this->assertNull($values[2]);\n        $this->assertNull($values[3]);\n    }\n\n    public function testLeadingParamDoesntReceiveForwardSlashOnEmptyPath()\n    {\n        $router = $this->getRouter();\n        $outer_one = 'abc1234'; // a string that is not one we're testing\n        $router->get('{one?}', [\n            'uses' => function ($one = null) use (&$outer_one) {\n                $outer_one = $one;\n\n                return $one;\n            },\n            'where' => ['one' => '(.+)'],\n        ]);\n\n        $this->assertSame('', $router->dispatch(Request::create(''))->getContent());\n        $this->assertNull($outer_one);\n        // Expects: '' ($one === null)\n        // Actual: '/' ($one === '/')\n\n        $this->assertSame('foo', $router->dispatch(Request::create('/foo', 'GET'))->getContent());\n        $this->assertSame('foo/bar/baz', $router->dispatch(Request::create('/foo/bar/baz', 'GET'))->getContent());\n    }\n\n    public function testRoutesDontMatchNonMatchingPathsWithLeadingOptionals()\n    {\n        $this->expectException(NotFoundHttpException::class);\n\n        $router = $this->getRouter();\n        $router->get('{baz?}', function ($age = 25) {\n            return $age;\n        });\n        $this->assertSame('25', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n    }\n\n    public function testRoutesDontMatchNonMatchingDomain()\n    {\n        $this->expectException(NotFoundHttpException::class);\n\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['domain' => 'api.foo.bar', function () {\n            return 'hello';\n        }]);\n        $this->assertSame('hello', $router->dispatch(Request::create('http://api.baz.boom/foo/bar', 'GET'))->getContent());\n    }\n\n    public function testRouteDomainRegistration()\n    {\n        $router = $this->getRouter();\n        $router->get('/foo/bar')->domain('api.foo.bar')->uses(function () {\n            return 'hello';\n        });\n        $this->assertSame('hello', $router->dispatch(Request::create('http://api.foo.bar/foo/bar', 'GET'))->getContent());\n    }\n\n    public function testMatchesMethodAgainstRequests()\n    {\n        // Basic\n        $request = Request::create('foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', function () {\n            //\n        });\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/bar', 'GET');\n        $route = new Route('GET', 'foo', function () {\n            //\n        });\n        $this->assertFalse($route->matches($request));\n\n        // Method checks\n        $request = Request::create('foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', function () {\n            //\n        });\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/bar', 'POST');\n        $route = new Route('GET', 'foo', function () {\n            //\n        });\n        $this->assertFalse($route->matches($request));\n\n        // Domain checks\n        $request = Request::create('http://something.foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['domain' => '{foo}.foo.com', function () {\n            //\n        }]);\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('http://something.bar.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['domain' => '{foo}.foo.com', function () {\n            //\n        }]);\n        $this->assertFalse($route->matches($request));\n\n        // HTTPS checks\n        $request = Request::create('https://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['https', function () {\n            //\n        }]);\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('https://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['https', 'baz' => true, function () {\n            //\n        }]);\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('http://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['https', function () {\n            //\n        }]);\n        $this->assertFalse($route->matches($request));\n\n        // HTTP checks\n        $request = Request::create('https://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['http', function () {\n            //\n        }]);\n        $this->assertFalse($route->matches($request));\n\n        $request = Request::create('http://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['http', function () {\n            //\n        }]);\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('http://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['baz' => true, function () {\n            //\n        }]);\n        $this->assertTrue($route->matches($request));\n    }\n\n    public function testWherePatternsProperlyFilter()\n    {\n        $request = Request::create('foo/123', 'GET');\n        $route = new Route('GET', 'foo/{bar}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123abc', 'GET');\n        $route = new Route('GET', 'foo/{bar}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertFalse($route->matches($request));\n\n        $request = Request::create('foo/123abc', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['where' => ['bar' => '[0-9]+'], function () {\n            //\n        }]);\n        $route->where('bar', '[0-9]+');\n        $this->assertFalse($route->matches($request));\n\n        $request = Request::create('foo/123', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['where' => ['bar' => '123|456'], function () {\n            //\n        }]);\n        $route->where('bar', '123|456');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123abc', 'GET');\n        $route = new Route('GET', 'foo/{bar}', ['where' => ['bar' => '123|456'], function () {\n            //\n        }]);\n        $route->where('bar', '123|456');\n        $this->assertFalse($route->matches($request));\n\n        // Optional\n        $request = Request::create('foo/123', 'GET');\n        $route = new Route('GET', 'foo/{bar?}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123', 'GET');\n        $route = new Route('GET', 'foo/{bar?}', ['where' => ['bar' => '[0-9]+'], function () {\n            //\n        }]);\n        $route->where('bar', '[0-9]+');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123', 'GET');\n        $route = new Route('GET', 'foo/{bar?}/{baz?}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123/foo', 'GET');\n        $route = new Route('GET', 'foo/{bar?}/{baz?}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertTrue($route->matches($request));\n\n        $request = Request::create('foo/123abc', 'GET');\n        $route = new Route('GET', 'foo/{bar?}', function () {\n            //\n        });\n        $route->where('bar', '[0-9]+');\n        $this->assertFalse($route->matches($request));\n\n        // Conditional\n        $route = new Route('GET', '{subdomain}.awesome.test', function () {\n            //\n        });\n\n        $route->when(true, function ($route) {\n            $route->whereIn('subdomain', [\n                'one',\n                'two',\n            ]);\n        });\n\n        $request = Request::create('test.awesome.test', 'GET');\n        $this->assertFalse($route->matches($request));\n\n        $request = Request::create('one.awesome.test', 'GET');\n        $this->assertTrue($route->matches($request));\n    }\n\n    public function testRoutePrefixParameterParsing()\n    {\n        $route = new Route('GET', '/foo', ['prefix' => 'profiles/{user:username}/portfolios', 'uses' => function () {\n            //\n        }]);\n\n        $this->assertSame('profiles/{user}/portfolios/foo', $route->uri());\n    }\n\n    public function testDotDoesNotMatchEverything()\n    {\n        $route = new Route('GET', 'images/{id}.{ext}', function () {\n            //\n        });\n\n        $request1 = Request::create('images/1.png', 'GET');\n        $this->assertTrue($route->matches($request1));\n        $route->bind($request1);\n        $this->assertSame('1', (string) $route->parameter('id'));\n        $this->assertSame('png', $route->parameter('ext'));\n\n        $request2 = Request::create('images/12.png', 'GET');\n        $this->assertTrue($route->matches($request2));\n        $route->bind($request2);\n        $this->assertSame('12', $route->parameter('id'));\n        $this->assertSame('png', $route->parameter('ext'));\n    }\n\n    public function testRouteBinding()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->bind('bar', function ($value) {\n            return strtoupper($value);\n        });\n        $this->assertSame('TAYLOR', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testRouteClassBinding()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->bind('bar', RouteBindingStub::class);\n        $this->assertSame('TAYLOR', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testRouteClassMethodBinding()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->bind('bar', RouteBindingStub::class.'@find');\n        $this->assertSame('dragon', $router->dispatch(Request::create('foo/Dragon', 'GET'))->getContent());\n    }\n\n    public function testMiddlewarePrioritySorting()\n    {\n        $middleware = [\n            Placeholder1::class,\n            SubstituteBindings::class,\n            Placeholder2::class,\n            Authenticate::class,\n            ExampleMiddleware::class,\n            Placeholder3::class,\n        ];\n\n        $router = $this->getRouter();\n\n        $router->middlewarePriority = [ExampleMiddlewareContract::class, Authenticate::class, SubstituteBindings::class, Authorize::class];\n\n        $route = $router->get('foo', ['middleware' => $middleware, 'uses' => function ($name) {\n            return $name;\n        }]);\n\n        $this->assertEquals([\n            Placeholder1::class,\n            ExampleMiddleware::class,\n            Authenticate::class,\n            SubstituteBindings::class,\n            Placeholder2::class,\n            Placeholder3::class,\n        ], $router->gatherRouteMiddleware($route));\n    }\n\n    public function testModelBinding()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->model('bar', RouteModelBindingStub::class);\n        $this->assertSame('TAYLOR', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testModelBindingWithNullReturn()\n    {\n        $this->expectException(ModelNotFoundException::class);\n        $this->expectExceptionMessage('No query results for model [Illuminate\\Tests\\Routing\\RouteModelBindingNullStub].');\n\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->model('bar', RouteModelBindingNullStub::class);\n        $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent();\n    }\n\n    public function testModelBindingWithCustomNullReturn()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->model('bar', RouteModelBindingNullStub::class, function () {\n            return 'missing';\n        });\n        $this->assertSame('missing', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testModelBindingWithBindingClosure()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->model('bar', RouteModelBindingNullStub::class, function ($value) {\n            return (new RouteModelBindingClosureStub)->findAlternate($value);\n        });\n        $this->assertSame('tayloralt', $router->dispatch(Request::create('foo/TAYLOR', 'GET'))->getContent());\n    }\n\n    public function testModelBindingWithCompoundParameterName()\n    {\n        $router = $this->getRouter();\n        $router->resource('foo-bar', RouteTestResourceControllerWithModelParameter::class, ['middleware' => SubstituteBindings::class]);\n        $this->assertSame('12345', $router->dispatch(Request::create('foo-bar/12345', 'GET'))->getContent());\n    }\n\n    public function testModelBindingWithCompoundParameterNameAndRouteBinding()\n    {\n        $router = $this->getRouter();\n        $router->model('foo_bar', RoutingTestUserModel::class);\n        $router->resource('foo-bar', RouteTestResourceControllerWithModelParameter::class, ['middleware' => SubstituteBindings::class]);\n        $this->assertSame('12345', $router->dispatch(Request::create('foo-bar/12345', 'GET'))->getContent());\n    }\n\n    public function testModelBindingThroughIOC()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n        $container->bind(RouteModelInterface::class, RouteModelBindingStub::class);\n        $router->get('foo/{bar}', ['middleware' => SubstituteBindings::class, 'uses' => function ($name) {\n            return $name;\n        }]);\n        $router->model('bar', RouteModelInterface::class);\n        $this->assertSame('TAYLOR', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testRouteDependenciesCanBeResolvedThroughAttributes()\n    {\n        $container = new Container;\n        $container->singleton('config', fn () => new Repository([\n            'app' => [\n                'timezone' => 'Europe/Paris',\n            ],\n        ]));\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n        $router->get('foo', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (#[Config('app.timezone')] string $value) {\n                return $value;\n            },\n        ]);\n\n        $this->assertSame('Europe/Paris', $router->dispatch(Request::create('foo', 'GET'))->getContent());\n    }\n\n    public function testAfterResolvingAttributeCallbackIsCalledOnRouteDependenciesResolution()\n    {\n        $container = new Container();\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $container->afterResolvingAttribute(RoutingTestOnTenant::class, function (RoutingTestOnTenant $attribute, RoutingTestHasTenantImpl $hasTenantImpl, Container $container) {\n            $hasTenantImpl->onTenant($attribute->tenant);\n        });\n\n        $router->get('foo', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (#[RoutingTestOnTenant(RoutingTestTenant::TenantA)] RoutingTestHasTenantImpl $property) {\n                return $property->tenant->name;\n            },\n        ]);\n\n        $this->assertSame('TenantA', $router->dispatch(Request::create('foo', 'GET'))->getContent());\n    }\n\n    public function testGroupMerging()\n    {\n        $old = ['prefix' => 'foo/bar/'];\n        $this->assertEquals(['prefix' => 'foo/bar/baz', 'namespace' => null, 'where' => []], RouteGroup::merge(['prefix' => 'baz'], $old));\n\n        $old = ['domain' => 'foo'];\n        $this->assertEquals(['domain' => 'baz', 'prefix' => null, 'namespace' => null, 'where' => []], RouteGroup::merge(['domain' => 'baz'], $old));\n\n        $old = ['as' => 'foo.'];\n        $this->assertEquals(['as' => 'foo.bar', 'prefix' => null, 'namespace' => null, 'where' => []], RouteGroup::merge(['as' => 'bar'], $old));\n\n        $old = ['where' => ['var1' => 'foo', 'var2' => 'bar']];\n        $this->assertEquals(['prefix' => null, 'namespace' => null, 'where' => [\n            'var1' => 'foo', 'var2' => 'baz', 'var3' => 'qux',\n        ]], RouteGroup::merge(['where' => ['var2' => 'baz', 'var3' => 'qux']], $old));\n\n        $old = [];\n        $this->assertEquals(['prefix' => null, 'namespace' => null, 'where' => [\n            'var1' => 'foo', 'var2' => 'bar',\n        ]], RouteGroup::merge(['where' => ['var1' => 'foo', 'var2' => 'bar']], $old));\n    }\n\n    public function testRouteGrouping()\n    {\n        // getPrefix() method\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo'], function () use ($router) {\n            $router->get('bar', function () {\n                return 'hello';\n            });\n        });\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n        $this->assertSame('foo', $routes[0]->getPrefix());\n    }\n\n    public function testRouteGroupingOutsideOfInheritedNamespace()\n    {\n        $router = $this->getRouter();\n\n        $router->group(['namespace' => 'App\\Http\\Controllers'], function ($router) {\n            $router->group(['namespace' => '\\Foo\\Bar'], function ($router) {\n                $router->get('users', 'UsersController@index');\n            });\n        });\n\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame(\n            'Foo\\Bar\\UsersController@index',\n            $routes[0]->getAction()['uses']\n        );\n    }\n\n    public function testCurrentRouteUses()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', ['as' => 'foo.bar', 'uses' => RouteTestControllerStub::class.'@index']);\n\n        $this->assertNull($router->currentRouteAction());\n\n        $this->assertSame('Hello World', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($router->uses('*RouteTestControllerStub*'));\n        $this->assertTrue($router->uses('*RouteTestControllerStub@index'));\n        $this->assertTrue($router->uses(['*RouteTestControllerStub*', '*FooController*']));\n        $this->assertTrue($router->uses(['*BarController*', '*FooController*', '*RouteTestControllerStub@index']));\n        $this->assertTrue($router->uses(['*BarController*', '*FooController*'], '*RouteTestControllerStub*'));\n        $this->assertFalse($router->uses(['*BarController*', '*FooController*']));\n\n        $this->assertEquals($router->currentRouteAction(), RouteTestControllerStub::class.'@index');\n        $this->assertTrue($router->currentRouteUses(RouteTestControllerStub::class.'@index'));\n    }\n\n    public function testRouteGroupingFromFile()\n    {\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'api'], __DIR__.'/fixtures/routes.php');\n\n        $route = last($router->getRoutes()->get());\n        $request = Request::create('api/users', 'GET');\n\n        $this->assertTrue($route->matches($request));\n        $this->assertSame('all-users', $route->bind($request)->run($request));\n    }\n\n    public function testRouteGroupingWithAs()\n    {\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo', 'as' => 'Foo::'], function () use ($router) {\n            $router->get('bar', ['as' => 'bar', function () {\n                return 'hello';\n            }]);\n        });\n        $routes = $router->getRoutes();\n        $route = $routes->getByName('Foo::bar');\n        $this->assertSame('foo/bar', $route->uri());\n    }\n\n    public function testNestedRouteGroupingWithAs()\n    {\n        // nested with all layers present\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo', 'as' => 'Foo::'], function () use ($router) {\n            $router->group(['prefix' => 'bar', 'as' => 'Bar::'], function () use ($router) {\n                $router->get('baz', ['as' => 'baz', function () {\n                    return 'hello';\n                }]);\n            });\n        });\n        $routes = $router->getRoutes();\n        $route = $routes->getByName('Foo::Bar::baz');\n        $this->assertSame('foo/bar/baz', $route->uri());\n\n        // nested with layer skipped\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo', 'as' => 'Foo::'], function () use ($router) {\n            $router->group(['prefix' => 'bar'], function () use ($router) {\n                $router->prefix('foz')->get('baz', ['as' => 'baz', function () {\n                    return 'hello';\n                }]);\n            });\n        });\n        $routes = $router->getRoutes();\n        $route = $routes->getByName('Foo::baz');\n        $this->assertSame('foz/foo/bar/baz', $route->uri());\n    }\n\n    public function testNestedRouteGroupingPrefixing()\n    {\n        // nested with layer skipped\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo', 'as' => 'Foo::'], function () use ($router) {\n            $router->prefix('bar')->get('baz', ['as' => 'baz', function () {\n                return 'hello';\n            }]);\n        });\n        $routes = $router->getRoutes();\n        $route = $routes->getByName('Foo::baz');\n        $this->assertSame('bar/foo', $route->getAction('prefix'));\n    }\n\n    public function testRouteMiddlewareMergeWithMiddlewareAttributesAsStrings()\n    {\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'foo', 'middleware' => 'boo:foo'], function () use ($router) {\n            $router->get('bar', function () {\n                return 'hello';\n            })->middleware('baz:gaz');\n        });\n        $routes = $router->getRoutes()->getRoutes();\n        $route = $routes[0];\n        $this->assertEquals(\n            ['boo:foo', 'baz:gaz'],\n            $route->middleware()\n        );\n    }\n\n    public function testRoutePrefixing()\n    {\n        // Prefix route\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n        $routes[0]->prefix('prefix');\n        $this->assertSame('prefix/foo/bar', $routes[0]->uri());\n\n        // Use empty prefix\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n        $routes[0]->prefix('/');\n        $this->assertSame('foo/bar', $routes[0]->uri());\n\n        // Prefix homepage\n        $router = $this->getRouter();\n        $router->get('/', function () {\n            return 'hello';\n        });\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n        $routes[0]->prefix('prefix');\n        $this->assertSame('prefix', $routes[0]->uri());\n\n        // Prefix homepage with empty prefix\n        $router = $this->getRouter();\n        $router->get('/', function () {\n            return 'hello';\n        });\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n        $routes[0]->prefix('/');\n        $this->assertSame('/', $routes[0]->uri());\n    }\n\n    public function testRoutePreservingOriginalParametersState()\n    {\n        $router = $this->getRouter();\n        $router->bind('bar', function ($value) {\n            return strlen($value);\n        });\n        $router->get('foo/{bar}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function ($bar) use ($router) {\n                $route = $router->getCurrentRoute();\n\n                $this->assertSame('taylor', $route->originalParameter('bar'));\n                $this->assertSame('default', $route->originalParameter('unexisting', 'default'));\n                $this->assertEquals(['bar' => 'taylor'], $route->originalParameters());\n\n                return $bar;\n            },\n        ]);\n\n        $this->assertEquals(6, $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testMergingControllerUses()\n    {\n        $router = $this->getRouter();\n        $router->group(['namespace' => 'Namespace'], function () use ($router) {\n            $router->get('foo/bar', 'Controller@action');\n        });\n        $routes = $router->getRoutes()->getRoutes();\n        $action = $routes[0]->getAction();\n\n        $this->assertSame('Namespace\\\\Controller@action', $action['controller']);\n\n        $router = $this->getRouter();\n        $router->group(['namespace' => 'Namespace'], function () use ($router) {\n            $router->group(['namespace' => 'Nested'], function () use ($router) {\n                $router->get('foo/bar', 'Controller@action');\n            });\n        });\n        $routes = $router->getRoutes()->getRoutes();\n        $action = $routes[0]->getAction();\n\n        $this->assertSame('Namespace\\\\Nested\\\\Controller@action', $action['controller']);\n\n        $router = $this->getRouter();\n        $router->group(['prefix' => 'baz'], function () use ($router) {\n            $router->group(['namespace' => 'Namespace'], function () use ($router) {\n                $router->get('foo/bar', 'Controller@action');\n            });\n        });\n        $routes = $router->getRoutes()->getRoutes();\n        $action = $routes[0]->getAction();\n\n        $this->assertSame('Namespace\\\\Controller@action', $action['controller']);\n    }\n\n    public function testInvalidActionException()\n    {\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage('Invalid route action: [Illuminate\\Tests\\Routing\\RouteTestControllerStub].');\n\n        $router = $this->getRouter();\n        $router->get('/', ['uses' => RouteTestControllerStub::class]);\n\n        $router->dispatch(Request::create('/'));\n    }\n\n    public function testShallowResourceRouting()\n    {\n        $router = $this->getRouter();\n        $router->resource('foo.bar', 'FooController', ['shallow' => true]);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foo/{foo}/bar', $routes[0]->uri());\n        $this->assertSame('foo/{foo}/bar/create', $routes[1]->uri());\n        $this->assertSame('foo/{foo}/bar', $routes[2]->uri());\n\n        $this->assertSame('bar/{bar}', $routes[3]->uri());\n        $this->assertSame('bar/{bar}/edit', $routes[4]->uri());\n        $this->assertSame('bar/{bar}', $routes[5]->uri());\n        $this->assertSame('bar/{bar}', $routes[6]->uri());\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController');\n        $router->resource('foo.bar.baz', 'FooController', ['shallow' => true]);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foo', $routes[0]->uri());\n        $this->assertSame('foo/create', $routes[1]->uri());\n        $this->assertSame('foo', $routes[2]->uri());\n        $this->assertSame('foo/{foo}', $routes[3]->uri());\n        $this->assertSame('foo/{foo}/edit', $routes[4]->uri());\n        $this->assertSame('foo/{foo}', $routes[5]->uri());\n        $this->assertSame('foo/{foo}', $routes[6]->uri());\n\n        $this->assertSame('foo/{foo}/bar/{bar}/baz', $routes[7]->uri());\n        $this->assertSame('foo/{foo}/bar/{bar}/baz/create', $routes[8]->uri());\n        $this->assertSame('foo/{foo}/bar/{bar}/baz', $routes[9]->uri());\n    }\n\n    public function testResourceRouting()\n    {\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController');\n        $routes = $router->getRoutes();\n        $this->assertCount(7, $routes);\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController', ['only' => ['update']]);\n        $routes = $router->getRoutes();\n\n        $this->assertCount(1, $routes);\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController', ['only' => ['show', 'destroy']]);\n        $routes = $router->getRoutes();\n\n        $this->assertCount(2, $routes);\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController', ['except' => ['show', 'destroy']]);\n        $routes = $router->getRoutes();\n\n        $this->assertCount(5, $routes);\n\n        $router = $this->getRouter();\n        $router->resource('foo-bars', 'FooController', ['only' => ['show']]);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foo-bars/{foo_bar}', $routes[0]->uri());\n\n        $router = $this->getRouter();\n        $router->resource('foo-bar.foo-baz', 'FooController', ['only' => ['show']]);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foo-bar/{foo_bar}/foo-baz/{foo_baz}', $routes[0]->uri());\n\n        $router = $this->getRouter();\n        $router->resource('foo-bars', 'FooController', ['only' => ['show'], 'as' => 'prefix']);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foo-bars/{foo_bar}', $routes[0]->uri());\n        $this->assertSame('prefix.foo-bars.show', $routes[0]->getName());\n\n        ResourceRegistrar::verbs([\n            'create' => 'ajouter',\n            'edit' => 'modifier',\n        ]);\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController');\n        $routes = $router->getRoutes();\n\n        $this->assertSame('foo/ajouter', $routes->getByName('foo.create')->uri());\n        $this->assertSame('foo/{foo}/modifier', $routes->getByName('foo.edit')->uri());\n    }\n\n    public function testResourceRoutingParameters()\n    {\n        ResourceRegistrar::singularParameters();\n\n        $router = $this->getRouter();\n        $router->resource('foos', 'FooController');\n        $router->resource('foos.bars', 'FooController');\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foos/{foo}', $routes[3]->uri());\n        $this->assertSame('foos/{foo}/bars/{bar}', $routes[10]->uri());\n\n        ResourceRegistrar::setParameters(['foos' => 'oof', 'bazs' => 'b']);\n\n        $router = $this->getRouter();\n        $router->resource('bars.foos.bazs', 'FooController');\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('bars/{bar}/foos/{oof}/bazs/{b}', $routes[3]->uri());\n\n        ResourceRegistrar::setParameters();\n        ResourceRegistrar::singularParameters(false);\n\n        $router = $this->getRouter();\n        $router->resource('foos', 'FooController', ['parameters' => 'singular']);\n        $router->resource('foos.bars', 'FooController')->parameters('singular');\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foos/{foo}', $routes[3]->uri());\n        $this->assertSame('foos/{foo}/bars/{bar}', $routes[10]->uri());\n\n        $router = $this->getRouter();\n        $router->resource('foos.bars', 'FooController', ['parameters' => ['foos' => 'foo', 'bars' => 'bar']]);\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foos/{foo}/bars/{bar}', $routes[3]->uri());\n\n        $router = $this->getRouter();\n        $router->resource('foos.bars', 'FooController')->parameter('foos', 'foo')->parameter('bars', 'bar');\n        $routes = $router->getRoutes();\n        $routes = $routes->getRoutes();\n\n        $this->assertSame('foos/{foo}/bars/{bar}', $routes[3]->uri());\n    }\n\n    public function testResourceRouteNaming()\n    {\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController');\n\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.index'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.show'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.create'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.store'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.edit'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.update'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.destroy'));\n\n        $router = $this->getRouter();\n        $router->resource('foo.bar', 'FooController');\n\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.index'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.show'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.create'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.store'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.edit'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.update'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.destroy'));\n\n        $router = $this->getRouter();\n        $router->resource('prefix/foo.bar', 'FooController');\n\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.index'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.show'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.create'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.store'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.edit'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.update'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo.bar.destroy'));\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController', ['names' => [\n            'index' => 'foo',\n            'show' => 'bar',\n        ]]);\n\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('foo'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar'));\n\n        $router = $this->getRouter();\n        $router->resource('foo', 'FooController', ['names' => 'bar']);\n\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.index'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.show'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.create'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.store'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.edit'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.update'));\n        $this->assertTrue($router->getRoutes()->hasNamedRoute('bar.destroy'));\n    }\n\n    public function testRouterFiresRoutedEvent()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $router->get('foo/bar', function () {\n            return '';\n        });\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $request = Request::create('http://foo.com/foo/bar', 'GET');\n        $route = new Route('GET', 'foo/bar', ['http', function () {\n            //\n        }]);\n\n        $_SERVER['__router.request'] = null;\n        $_SERVER['__router.route'] = null;\n\n        $router->matched(function ($event) {\n            $_SERVER['__router.request'] = $event->request;\n            $_SERVER['__router.route'] = $event->route;\n        });\n\n        $router->dispatchToRoute($request);\n\n        $this->assertInstanceOf(Request::class, $_SERVER['__router.request']);\n        $this->assertEquals($_SERVER['__router.request'], $request);\n        unset($_SERVER['__router.request']);\n\n        $this->assertInstanceOf(Route::class, $_SERVER['__router.route']);\n        $this->assertEquals($_SERVER['__router.route']->uri(), $route->uri());\n        unset($_SERVER['__router.route']);\n    }\n\n    public function testRouterFiresRouteMatchingEvent()\n    {\n        $container = new Container;\n        $router = new Router($events = new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n        $router->get('foo/bar', function () {\n            return '';\n        });\n\n        $request = Request::create('http://foo.com/foo/bar', 'GET');\n\n        $_SERVER['__router.request'] = null;\n\n        $events->listen(Routing::class, function ($event) {\n            $_SERVER['__router.request'] = $event->request;\n        });\n\n        $router->dispatchToRoute($request);\n\n        $this->assertInstanceOf(Request::class, $_SERVER['__router.request']);\n        $this->assertEquals($_SERVER['__router.request'], $request);\n        unset($_SERVER['__router.request']);\n    }\n\n    public function testRouterPatternSetting()\n    {\n        $router = $this->getRouter();\n        $router->pattern('test', 'pattern');\n        $this->assertEquals(['test' => 'pattern'], $router->getPatterns());\n\n        $router = $this->getRouter();\n        $router->patterns(['test' => 'pattern', 'test2' => 'pattern2']);\n        $this->assertEquals(['test' => 'pattern', 'test2' => 'pattern2'], $router->getPatterns());\n    }\n\n    public function testControllerRouting()\n    {\n        unset(\n            $_SERVER['route.test.controller.middleware'], $_SERVER['route.test.controller.except.middleware'],\n            $_SERVER['route.test.controller.middleware.class'],\n            $_SERVER['route.test.controller.middleware.parameters.one'], $_SERVER['route.test.controller.middleware.parameters.two']\n        );\n\n        $router = $this->getRouter();\n\n        $router->get('foo/bar', RouteTestControllerStub::class.'@index');\n\n        $this->assertSame('Hello World', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($_SERVER['route.test.controller.middleware']);\n        $this->assertEquals(Response::class, $_SERVER['route.test.controller.middleware.class']);\n        $this->assertEquals(0, $_SERVER['route.test.controller.middleware.parameters.one']);\n        $this->assertEquals(['foo', 'bar'], $_SERVER['route.test.controller.middleware.parameters.two']);\n        $this->assertFalse(isset($_SERVER['route.test.controller.except.middleware']));\n    }\n\n    public function testControllerRoutingArrayCallable()\n    {\n        unset(\n            $_SERVER['route.test.controller.middleware'], $_SERVER['route.test.controller.except.middleware'],\n            $_SERVER['route.test.controller.middleware.class'],\n            $_SERVER['route.test.controller.middleware.parameters.one'], $_SERVER['route.test.controller.middleware.parameters.two']\n        );\n\n        $router = $this->getRouter();\n\n        $router->get('foo/bar', [RouteTestControllerStub::class, 'index']);\n\n        $this->assertSame('Hello World', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($_SERVER['route.test.controller.middleware']);\n        $this->assertEquals(Response::class, $_SERVER['route.test.controller.middleware.class']);\n        $this->assertEquals(0, $_SERVER['route.test.controller.middleware.parameters.one']);\n        $this->assertEquals(['foo', 'bar'], $_SERVER['route.test.controller.middleware.parameters.two']);\n        $this->assertFalse(isset($_SERVER['route.test.controller.except.middleware']));\n        $action = $router->getRoutes()->getRoutes()[0]->getAction()['controller'];\n        $this->assertEquals(RouteTestControllerStub::class.'@index', $action);\n    }\n\n    public function testCallableControllerRouting()\n    {\n        $router = $this->getRouter();\n\n        $router->get('foo/bar', RouteTestControllerCallableStub::class.'@bar');\n        $router->get('foo/baz', RouteTestControllerCallableStub::class.'@baz');\n\n        $this->assertSame('bar', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertSame('baz', $router->dispatch(Request::create('foo/baz', 'GET'))->getContent());\n    }\n\n    public function testControllerMiddlewareGroups()\n    {\n        unset(\n            $_SERVER['route.test.controller.middleware'],\n            $_SERVER['route.test.controller.middleware.class']\n        );\n\n        $router = $this->getRouter();\n\n        $router->middlewareGroup('web', [\n            RouteTestControllerMiddleware::class,\n            RouteTestControllerMiddlewareTwo::class,\n        ]);\n\n        $router->get('foo/bar', RouteTestControllerMiddlewareGroupStub::class.'@index');\n\n        $this->assertSame('caught', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n        $this->assertTrue($_SERVER['route.test.controller.middleware']);\n        $this->assertEquals(Response::class, $_SERVER['route.test.controller.middleware.class']);\n    }\n\n    public function testImplicitBindings()\n    {\n        $router = $this->getRouter();\n\n        $router->get('foo/{bar}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestUserModel $bar) {\n                $this->assertInstanceOf(RoutingTestUserModel::class, $bar);\n\n                return $bar->value;\n            },\n        ]);\n\n        $this->assertSame('taylor', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testImplicitBindingsWithClosure()\n    {\n        $router = $this->getRouter();\n\n        $router->substituteImplicitBindingsUsing(function ($container, $route, $default) {\n            $default = $default();\n\n            $model = $route->parameter('bar');\n            $model->value = 'otwell';\n        });\n\n        $router->get('foo/{bar}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestUserModel $bar) {\n                return $bar->value;\n            },\n        ]);\n\n        $this->assertSame('otwell', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testImplicitBindingsWhereScopedBindingsArePrevented()\n    {\n        $router = $this->getRouter();\n\n        $router->get('foo/{test_team}/{user:id}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestTeamWithoutUserModel $testTeam, RoutingTestUserModel $user) {\n                $this->assertInstanceOf(RoutingTestTeamWithoutUserModel::class, $testTeam);\n                $this->assertInstanceOf(RoutingTestUserModel::class, $user);\n\n                return $testTeam->value.'|'.$user->value;\n            },\n        ])->withoutScopedBindings();\n\n        $this->assertSame('1|4', $router->dispatch(Request::create('foo/1/4', 'GET'))->getContent());\n    }\n\n    public function testParentChildImplicitBindings()\n    {\n        $router = $this->getRouter();\n\n        $router->get('foo/{user}/{post:slug}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestUserModel $user, RoutingTestPostModel $post) {\n                $this->assertInstanceOf(RoutingTestUserModel::class, $user);\n                $this->assertInstanceOf(RoutingTestPostModel::class, $post);\n\n                return $user->value.'|'.$post->value;\n            },\n        ]);\n\n        $this->assertSame('1|test-slug', $router->dispatch(Request::create('foo/1/test-slug', 'GET'))->getContent());\n    }\n\n    public function testParentChildImplicitBindingsWhereOnlySomeParametersAreScoped()\n    {\n        $router = $this->getRouter();\n        $action = function (RoutingTestTeamModel $team, RoutingTestUserModel $user, RoutingTestPostModel $post) {\n            $this->assertInstanceOf(RoutingTestTeamModel::class, $team);\n            $this->assertInstanceOf(RoutingTestUserModel::class, $user);\n            $this->assertInstanceOf(RoutingTestPostModel::class, $post);\n\n            return $team->value.'|'.$user->value.'|'.$post->value;\n        };\n\n        $router->get('foo/{team}/{user:slug}/{post}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => $action,\n        ]);\n        $this->assertSame('1|test-slug|2', $router->dispatch(Request::create('foo/1/test-slug/2', 'GET'))->getContent());\n\n        $router->get('foo/{team}/{user}/{post:id}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => $action,\n        ]);\n        $this->assertSame('2|another-test-slug|3', $router->dispatch(Request::create('foo/2/another-test-slug/3', 'GET'))->getContent());\n    }\n\n    public function testApiResourceScopingWhenChildDoesNotBelongToParent()\n    {\n        ResourceRegistrar::singularParameters();\n        $router = $this->getRouter();\n        $router->apiResource(\n            'teams.users',\n            RouteTestNestedResourceControllerWithMissingUser::class,\n            ['only' => ['show']],\n        )\n            ->middleware(SubstituteBindings::class)\n            ->scoped();\n\n        $this->expectException(ModelNotFoundException::class);\n\n        $router->dispatch(Request::create('teams/1/users/2', 'GET'));\n    }\n\n    public function testParentChildImplicitBindingsProperlyCamelCased()\n    {\n        $router = $this->getRouter();\n\n        $router->get('foo/{user}/{test_team:id}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestUserModel $user, RoutingTestTeamModel $testTeam) {\n                $this->assertInstanceOf(RoutingTestUserModel::class, $user);\n                $this->assertInstanceOf(RoutingTestTeamModel::class, $testTeam);\n\n                return $user->value.'|'.$testTeam->value;\n            },\n        ]);\n\n        $this->assertSame('1|4', $router->dispatch(Request::create('foo/1/4', 'GET'))->getContent());\n    }\n\n    public function testImplicitBindingsWithOptionalParameterWithExistingKeyInUri()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?RoutingTestUserModel $bar = null) {\n                $this->assertInstanceOf(RoutingTestUserModel::class, $bar);\n\n                return $bar->value;\n            },\n        ]);\n        $this->assertSame('taylor', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());\n    }\n\n    public function testOptionalBackedEnumsReturnNullWhenMissing()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?CategoryBackedEnum $bar = null) {\n                $this->assertNull($bar);\n\n                return 'bar';\n            },\n        ]);\n\n        $router->dispatch(Request::create('foo', 'GET'))->getContent();\n    }\n\n    public function testImplicitBindingsWithMissingModelHandledByMissing()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?RouteModelBindingNullStub $bar = null) {\n                $this->assertInstanceOf(RouteModelBindingNullStub::class, $bar);\n\n                return $bar->first();\n            },\n        ])->missing(function () {\n            return new RedirectResponse('/', 302);\n        });\n\n        $request = Request::create('foo/taylor', 'GET');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('/'));\n        $this->assertEquals(302, $response->getStatusCode());\n    }\n\n    public function testImplicitBindingsWithMissingModelHandledByMissingOnGroupLevel()\n    {\n        $router = $this->getRouter();\n        $router->as('foo.')\n            ->missing(fn () => new RedirectResponse('/', 302))\n            ->group(function () use ($router) {\n                $router->get('foo/{bar}', [\n                    'middleware' => SubstituteBindings::class,\n                    'uses' => function (?RouteModelBindingNullStub $bar = null) {\n                        $this->assertInstanceOf(RouteModelBindingNullStub::class, $bar);\n\n                        return $bar->first();\n                    },\n                ]);\n            });\n\n        $request = Request::create('foo/taylor', 'GET');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('/'));\n        $this->assertEquals(302, $response->getStatusCode());\n    }\n\n    public function testImplicitBindingsWithOptionalParameterWithNoKeyInUri()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?RoutingTestUserModel $bar = null) {\n                $this->assertNull($bar);\n            },\n        ]);\n        $router->dispatch(Request::create('foo', 'GET'))->getContent();\n    }\n\n    public function testImplicitBindingsWithOptionalParameterUsingEnumIsAlwaysCastedToEnum()\n    {\n        include_once 'Enums.php';\n\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?\\Illuminate\\Tests\\Routing\\CategoryBackedEnum $bar = null) {\n                $this->assertInstanceOf(CategoryBackedEnum::class, $bar);\n            },\n        ]);\n        $router->dispatch(Request::create('foo/people', 'GET'))->getContent();\n    }\n\n    public function testImplicitBindingsWithOptionalParameterWithNonExistingKeyInUri()\n    {\n        $this->expectException(ModelNotFoundException::class);\n\n        $router = $this->getRouter();\n        $router->get('foo/{bar?}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (?RoutingTestNonExistingUserModel $bar = null) {\n                $this->fail('ModelNotFoundException was expected.');\n            },\n        ]);\n        $router->dispatch(Request::create('foo/nonexisting', 'GET'))->getContent();\n    }\n\n    public function testImplicitBindingThroughIOC()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        $container->bind(RoutingTestUserModel::class, RoutingTestExtendedUserModel::class);\n        $router->get('foo/{bar}', [\n            'middleware' => SubstituteBindings::class,\n            'uses' => function (RoutingTestUserModel $bar) {\n                $this->assertInstanceOf(RoutingTestExtendedUserModel::class, $bar);\n            },\n        ]);\n        $router->dispatch(Request::create('foo/baz', 'GET'))->getContent();\n    }\n\n    public function testDispatchingCallableActionClasses()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', ActionStub::class);\n\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar', 'GET'))->getContent());\n\n        $router->get('foo/bar2', [\n            'uses' => ActionStub::class,\n        ]);\n\n        $this->assertSame('hello', $router->dispatch(Request::create('foo/bar2', 'GET'))->getContent());\n    }\n\n    public function testResponseIsReturned()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n\n        $response = $router->dispatch(Request::create('foo/bar', 'GET'));\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotInstanceOf(JsonResponse::class, $response);\n    }\n\n    public function testJsonResponseIsReturned()\n    {\n        $router = $this->getRouter();\n        $router->get('foo/bar', function () {\n            return ['foo', 'bar'];\n        });\n\n        $response = $router->dispatch(Request::create('foo/bar', 'GET'));\n        $this->assertNotInstanceOf(Response::class, $response);\n        $this->assertInstanceOf(JsonResponse::class, $response);\n    }\n\n    public function testRouteFlushController()\n    {\n        $container = new Container;\n        $router = $this->getRouter();\n\n        $router->get('count', ActionCountStub::class);\n        $request = Request::create('count', 'GET');\n\n        $response = $router->dispatch($request);\n        $this->assertSame(1, $response->original['invokedCount']);\n        $this->assertSame(1, $response->original['middlewareInvokedCount']);\n\n        $response = $router->dispatch($request);\n        $this->assertSame(2, $response->original['invokedCount']);\n        $this->assertSame(2, $response->original['middlewareInvokedCount']);\n\n        $request->route()->flushController();\n        $response = $router->dispatch($request);\n        $this->assertSame(1, $response->original['invokedCount']);\n        $this->assertSame(1, $response->original['middlewareInvokedCount']);\n    }\n\n    public function testRouteRedirect()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('contact_us', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('contact_us', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->redirect('contact_us', 'contact');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('contact'));\n        $this->assertEquals(302, $response->getStatusCode());\n    }\n\n    public function testRouteRedirectRetainsExistingStartingForwardSlash()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('contact_us', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('contact_us', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->redirect('contact_us', '/contact');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('/contact'));\n        $this->assertEquals(302, $response->getStatusCode());\n    }\n\n    public function testRouteRedirectStripsMissingStartingForwardSlash()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('contact_us', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('contact_us', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->redirect('contact_us', 'contact');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('contact'));\n        $this->assertEquals(302, $response->getStatusCode());\n    }\n\n    public function testRouteRedirectExceptionWhenMissingExpectedParameters()\n    {\n        $this->expectException(UrlGenerationException::class);\n        $this->expectExceptionMessage('Missing required parameter for [Route: laravel_route_redirect_destination] [URI: users/{user}] [Missing parameter: user].');\n\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('users', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('users', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->redirect('users', 'users/{user}');\n\n        $router->dispatch($request);\n    }\n\n    public function testRouteRedirectWithCustomStatus()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('contact_us', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('contact_us', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->redirect('contact_us', 'contact', 301);\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('contact'));\n        $this->assertEquals(301, $response->getStatusCode());\n    }\n\n    public function testRoutePermanentRedirect()\n    {\n        $container = new Container;\n        $router = new Router(new Dispatcher, $container);\n        $container->instance(Registrar::class, $router);\n        $request = Request::create('contact_us', 'GET');\n        $container->instance(Request::class, $request);\n        $urlGenerator = new UrlGenerator(new RouteCollection, $request);\n        $container->instance(UrlGenerator::class, $urlGenerator);\n        $router->get('contact_us', function () {\n            throw new Exception('Route should not be reachable.');\n        });\n        $router->permanentRedirect('contact_us', 'contact');\n\n        $response = $router->dispatch($request);\n        $this->assertTrue($response->isRedirect('contact'));\n        $this->assertEquals(301, $response->getStatusCode());\n    }\n\n    public function testRouteCanMiddlewareCanBeAssigned()\n    {\n        $route = new Route(['GET'], '/', []);\n        $route->middleware(['foo'])->can('create', Route::class);\n\n        $this->assertEquals([\n            'foo',\n            'can:create,Illuminate\\Routing\\Route',\n        ], $route->middleware());\n\n        $route = new Route(['GET'], '/', []);\n        $route->can('create');\n\n        $this->assertEquals([\n            'can:create',\n        ], $route->middleware());\n\n        $route = new Route(['GET'], '/', []);\n        $route->can('create');\n        $route->can('update');\n\n        $this->assertEquals([\n            'can:create',\n            'can:update',\n        ], $route->middleware());\n    }\n\n    public function testItDispatchesEventsWhilePreparingRequest()\n    {\n        $events = new Dispatcher;\n        $preparing = [];\n        $prepared = [];\n        $events->listen(PreparingResponse::class, function ($event) use (&$preparing) {\n            $preparing[] = $event;\n        });\n        $events->listen(ResponsePrepared::class, function ($event) use (&$prepared) {\n            $prepared[] = $event;\n        });\n        $container = new Container;\n        $container->instance(Dispatcher::class, $events);\n        $router = $this->getRouter($container);\n        $router->get('foo/bar', function () {\n            return 'hello';\n        });\n        $request = Request::create('foo/bar', 'GET');\n\n        $response = $router->dispatch($request);\n\n        $this->assertSame('hello', $response->getContent());\n        $this->assertCount(2, $preparing);\n        $this->assertSame($request, $preparing[0]->request);\n        $this->assertSame('hello', $preparing[0]->response);\n        $this->assertSame($request, $preparing[1]->request);\n        $this->assertSame($response, $preparing[1]->response);\n        $this->assertCount(2, $prepared);\n        $this->assertSame($request, $prepared[0]->request);\n        $this->assertSame($response, $prepared[0]->response);\n        $this->assertSame($request, $prepared[1]->request);\n        $this->assertSame($response, $prepared[1]->response);\n    }\n\n    protected function getRouter($container = null)\n    {\n        $container ??= new Container;\n\n        $router = new Router($container->make(Dispatcher::class), $container);\n\n        $container->instance(Registrar::class, $router);\n\n        $container->bind(ControllerDispatcherContract::class, fn ($app) => new ControllerDispatcher($app));\n        $container->bind(CallableDispatcherContract::class, fn ($app) => new CallableDispatcher($app));\n\n        return $router;\n    }\n}\n\nclass RouteTestControllerStub extends Controller\n{\n    public function __construct()\n    {\n        $this->middleware(RouteTestControllerMiddleware::class);\n        $this->middleware(RouteTestControllerParameterizedMiddlewareOne::class.':0');\n        $this->middleware(RouteTestControllerParameterizedMiddlewareTwo::class.':foo,bar');\n        $this->middleware(RouteTestControllerExceptMiddleware::class, ['except' => 'index']);\n    }\n\n    public function index()\n    {\n        return 'Hello World';\n    }\n}\n\nclass RouteTestControllerCallableStub extends Controller\n{\n    public function __call($method, $arguments = [])\n    {\n        return $method;\n    }\n}\n\nclass RouteTestControllerMiddlewareGroupStub extends Controller\n{\n    public function __construct()\n    {\n        $this->middleware('web');\n    }\n\n    public function index()\n    {\n        return 'Hello World';\n    }\n}\n\nclass RouteTestControllerWithParameterStub extends Controller\n{\n    public function returnParameter($bar = '')\n    {\n        return $bar;\n    }\n}\n\nclass RouteTestAnotherControllerWithParameterStub extends Controller\n{\n    public function callAction($method, $parameters)\n    {\n        $_SERVER['__test.controller_callAction_parameters'] = $parameters;\n    }\n\n    public function oneArgument($one)\n    {\n        //\n    }\n\n    public function twoArguments($one, $two)\n    {\n        //\n    }\n\n    public function differentArgumentNames($bar, $baz)\n    {\n        //\n    }\n\n    public function reversedArguments($two, $one)\n    {\n        //\n    }\n\n    public function withModels(Request $request, RoutingTestUserModel $user, $defaultNull = null, ?RoutingTestTeamModel $team = null)\n    {\n        //\n    }\n}\n\nclass RouteTestResourceControllerWithModelParameter extends Controller\n{\n    public function show(RoutingTestUserModel $fooBar)\n    {\n        return $fooBar->value;\n    }\n}\n\nclass RouteTestNestedResourceControllerWithMissingUser extends Controller\n{\n    public function show(RoutingTestTeamWithoutUserModel $team, RoutingTestUserModel $user)\n    {\n    }\n}\n\nclass RouteTestClosureMiddlewareController extends Controller\n{\n    public function __construct()\n    {\n        $this->middleware(function ($request, $next) {\n            $response = $next($request);\n\n            return $response->setContent(\n                $response->content().'-'.$request['foo-middleware'].'-controller-closure'\n            );\n        });\n    }\n\n    public function index()\n    {\n        return 'index';\n    }\n}\n\nclass RouteTestControllerMiddleware\n{\n    public function handle($request, $next)\n    {\n        $_SERVER['route.test.controller.middleware'] = true;\n        $response = $next($request);\n        $_SERVER['route.test.controller.middleware.class'] = get_class($response);\n\n        return $response;\n    }\n}\n\nclass RouteTestControllerMiddlewareTwo\n{\n    public function handle($request, $next)\n    {\n        return new Response('caught');\n    }\n}\n\nclass RouteTestControllerParameterizedMiddlewareOne\n{\n    public function handle($request, $next, $parameter)\n    {\n        $_SERVER['route.test.controller.middleware.parameters.one'] = $parameter;\n\n        return $next($request);\n    }\n}\n\nclass RouteTestControllerParameterizedMiddlewareTwo\n{\n    public function handle($request, $next, $parameter1, $parameter2)\n    {\n        $_SERVER['route.test.controller.middleware.parameters.two'] = [$parameter1, $parameter2];\n\n        return $next($request);\n    }\n}\n\nclass RouteTestControllerExceptMiddleware\n{\n    public function handle($request, $next)\n    {\n        $_SERVER['route.test.controller.except.middleware'] = true;\n\n        return $next($request);\n    }\n}\n\nclass ResponsableResponse implements Responsable\n{\n    public function toResponse($request)\n    {\n        return new Response('bar');\n    }\n}\n\nclass RouteBindingStub\n{\n    public function bind($value, $route)\n    {\n        return strtoupper($value);\n    }\n\n    public function find($value, $route)\n    {\n        return strtolower($value);\n    }\n}\n\nclass RouteModelBindingStub extends Model\n{\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        return strtoupper($this->value);\n    }\n}\n\nclass RouteModelBindingNullStub extends Model\n{\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        return $this;\n    }\n\n    public function first()\n    {\n        //\n    }\n}\n\nclass RouteModelBindingClosureStub\n{\n    public function findAlternate($value)\n    {\n        return strtolower($value).'alt';\n    }\n}\n\nclass RoutingTestMiddlewareGroupOne\n{\n    public function handle($request, $next)\n    {\n        $_SERVER['__middleware.group'] = true;\n\n        return $next($request);\n    }\n}\n\nclass RoutingTestMiddlewareGroupTwo\n{\n    public function handle($request, $next, $parameter = null)\n    {\n        return new Response('caught '.$parameter);\n    }\n}\n\nclass RoutingTestUserModel extends Model\n{\n    public function posts()\n    {\n        return new RoutingTestPostModel;\n    }\n\n    public function testTeams()\n    {\n        return new RoutingTestTeamModel;\n    }\n\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        return $this;\n    }\n\n    public function firstOrFail()\n    {\n        return $this;\n    }\n}\n\nclass RoutingTestPostModel extends Model\n{\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        return $this;\n    }\n}\n\nclass RoutingTestTeamModel extends Model\n{\n    public function users()\n    {\n        return new RoutingTestUserModel;\n    }\n\n    public function getRouteKeyName()\n    {\n        return 'id';\n    }\n\n    public function where($key, $value)\n    {\n        $this->value = $value;\n\n        return $this;\n    }\n\n    public function first()\n    {\n        return $this;\n    }\n\n    public function firstOrFail()\n    {\n        return $this;\n    }\n}\n\nclass RoutingTestExtendedUserModel extends RoutingTestUserModel\n{\n    //\n}\n\nclass RoutingTestNonExistingUserModel extends RoutingTestUserModel\n{\n    public function first()\n    {\n        //\n    }\n\n    public function firstOrFail()\n    {\n        throw new ModelNotFoundException;\n    }\n}\n\nclass RoutingTestTeamWithoutUserModel extends RoutingTestTeamModel\n{\n    public function users()\n    {\n        throw new ModelNotFoundException();\n    }\n}\n\nclass ActionStub\n{\n    public function __invoke()\n    {\n        return 'hello';\n    }\n}\n\nclass ActionCountStub extends Controller\n{\n    protected $middlewareInvokedCount = 0;\n\n    protected $invokedCount = 0;\n\n    public function __construct()\n    {\n        $this->middleware(function ($request, $next) {\n            $this->middlewareInvokedCount++;\n\n            return $next($request);\n        });\n    }\n\n    public function __invoke()\n    {\n        $this->invokedCount++;\n\n        return [\n            'invokedCount' => $this->invokedCount,\n            'middlewareInvokedCount' => $this->middlewareInvokedCount,\n        ];\n    }\n}\n\ninterface ExampleMiddlewareContract\n{\n    //\n}\n\nclass ExampleMiddleware implements ExampleMiddlewareContract\n{\n    public function handle($request, Closure $next)\n    {\n        return $next($request);\n    }\n}\n\n#[Attribute(Attribute::TARGET_PARAMETER)]\nfinal class RoutingTestOnTenant\n{\n    public function __construct(\n        public readonly RoutingTestTenant $tenant\n    ) {\n    }\n}\n\nenum RoutingTestTenant\n{\n    case TenantA;\n    case TenantB;\n}\n\nfinal class RoutingTestHasTenantImpl\n{\n    public ?RoutingTestTenant $tenant = null;\n\n    public function onTenant(RoutingTestTenant $tenant): void\n    {\n        $this->tenant = $tenant;\n    }\n}\n"
  },
  {
    "path": "tests/Routing/RoutingSortedMiddlewareTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Routing\\SortedMiddleware;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RoutingSortedMiddlewareTest extends TestCase\n{\n    public function testMiddlewareCanBeSortedByPriority()\n    {\n        $priority = [\n            'First',\n            'Second',\n            'Third',\n        ];\n\n        $middleware = [\n            'Something',\n            'Something',\n            'Something',\n            'Something',\n            'Second',\n            'Otherthing',\n            'First:api',\n            'Third:foo',\n            'First:foo,bar',\n            'Third',\n            'Second',\n        ];\n\n        $expected = [\n            'Something',\n            'First:api',\n            'First:foo,bar',\n            'Second',\n            'Otherthing',\n            'Third:foo',\n            'Third',\n        ];\n\n        $this->assertEquals($expected, (new SortedMiddleware($priority, $middleware))->all());\n\n        $this->assertEquals([], (new SortedMiddleware(['First'], []))->all());\n        $this->assertEquals(['First'], (new SortedMiddleware(['First'], ['First']))->all());\n        $this->assertEquals(['First', 'Second'], (new SortedMiddleware(['First', 'Second'], ['Second', 'First']))->all());\n    }\n\n    public function testItDoesNotMoveNonStringValues()\n    {\n        $closure = function () {\n            return 'foo';\n        };\n\n        $closure2 = function () {\n            return 'bar';\n        };\n\n        $this->assertEquals([2, 1], (new SortedMiddleware([1, 2], [2, 1]))->all());\n        $this->assertEquals(['Second', $closure], (new SortedMiddleware(['First', 'Second'], ['Second', $closure]))->all());\n        $this->assertEquals(['a', 'b', $closure], (new SortedMiddleware(['a', 'b'], ['b', $closure, 'a']))->all());\n        $this->assertEquals([$closure2, 'a', 'b', $closure, 'foo'], (new SortedMiddleware(['a', 'b'], [$closure2, 'b', $closure, 'a', 'foo']))->all());\n        $this->assertEquals([$closure, 'a', 'b', $closure2, 'foo'], (new SortedMiddleware(['a', 'b'], [$closure, 'b', $closure2, 'foo', 'a']))->all());\n        $this->assertEquals(['a', $closure, 'b', $closure2, 'foo'], (new SortedMiddleware(['a', 'b'], ['a', $closure, 'b', $closure2, 'foo']))->all());\n        $this->assertEquals([$closure, $closure2, 'foo', 'a'], (new SortedMiddleware(['a', 'b'], [$closure, $closure2, 'foo', 'a']))->all());\n    }\n\n    public function testItSortsUsingParentsAndContracts()\n    {\n        $priority = [\n            FirstContractStub::class,\n            SecondStub::class,\n            'Third',\n        ];\n\n        $middleware = [\n            'Something',\n            'Something',\n            'Something',\n            'Something',\n            SecondChildStub::class,\n            'Otherthing',\n            FirstStub::class.':api',\n            'Third:foo',\n            FirstStub::class.':foo,bar',\n            'Third',\n            SecondChildStub::class,\n        ];\n\n        $expected = [\n            'Something',\n            FirstStub::class.':api',\n            FirstStub::class.':foo,bar',\n            SecondChildStub::class,\n            'Otherthing',\n            'Third:foo',\n            'Third',\n        ];\n\n        $this->assertEquals($expected, (new SortedMiddleware($priority, $middleware))->all());\n    }\n}\n\ninterface FirstContractStub\n{\n    //\n}\n\nclass FirstStub implements FirstContractStub\n{\n    //\n}\n\nclass SecondStub\n{\n    //\n}\n\nclass SecondChildStub extends SecondStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Routing/RoutingUrlGeneratorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Routing;\n\nuse Illuminate\\Contracts\\Routing\\UrlRoutable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Routing\\Exceptions\\UrlGenerationException;\nuse Illuminate\\Routing\\Route;\nuse Illuminate\\Routing\\RouteCollection;\nuse Illuminate\\Routing\\UrlGenerator;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request as SymfonyRequest;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\n\ninclude_once 'Enums.php';\n\nclass RoutingUrlGeneratorTest extends TestCase\n{\n    public function testBasicGeneration()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('https://www.foo.com/foo/bar', $url->to('foo/bar', [], true));\n        $this->assertSame('https://www.foo.com/foo/bar/baz/boom', $url->to('foo/bar', ['baz', 'boom'], true));\n        $this->assertSame('https://www.foo.com/foo/bar/baz?foo=bar', $url->to('foo/bar?foo=bar', ['baz'], true));\n\n        // Test HTTPS request URL generation...\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $this->assertSame('https://www.foo.com/foo/bar', $url->to('foo/bar'));\n    }\n\n    public function testQueryGeneration()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->query('foo/bar'));\n        $this->assertSame('http://www.foo.com/foo/bar?0=foo', $url->query('foo/bar', ['foo']));\n        $this->assertSame('http://www.foo.com/foo/bar?baz=boom', $url->query('foo/bar', ['baz' => 'boom']));\n        $this->assertSame('http://www.foo.com/foo/bar?baz=zee&zal=bee', $url->query('foo/bar?baz=boom&zal=bee', ['baz' => 'zee']));\n        $this->assertSame('http://www.foo.com/foo/bar?zal=bee', $url->query('foo/bar?baz=boom&zal=bee', ['baz' => null]));\n        $this->assertSame('http://www.foo.com/foo/bar?baz=boom', $url->query('foo/bar?baz=boom', ['nonexist' => null]));\n        $this->assertSame('http://www.foo.com/foo/bar', $url->query('foo/bar?baz=boom', ['baz' => null]));\n        $this->assertSame('https://www.foo.com/foo/bar/baz?foo=bar&zal=bee', $url->query('foo/bar?foo=bar', ['zal' => 'bee'], ['baz'], true));\n        $this->assertSame('http://www.foo.com/foo/bar?baz[0]=boom&baz[1]=bam&baz[2]=bim', urldecode($url->query('foo/bar', ['baz' => ['boom', 'bam', 'bim']])));\n    }\n\n    public function testAssetGeneration()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/index.php/')\n        );\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->asset('foo/bar'));\n        $this->assertSame('https://www.foo.com/foo/bar', $url->asset('foo/bar', true));\n\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/index.php/'),\n            '/'\n        );\n\n        $this->assertSame('/foo/bar', $url->asset('foo/bar'));\n        $this->assertSame('/foo/bar', $url->asset('foo/bar', true));\n    }\n\n    public function testBasicGenerationWithHostFormatting()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], '/named-route', ['as' => 'plain']);\n        $routes->add($route);\n\n        $url->formatHostUsing(function ($host) {\n            return str_replace('foo.com', 'foo.org', $host);\n        });\n\n        $this->assertSame('http://www.foo.org/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('/named-route', $url->route('plain', [], false));\n    }\n\n    public function testBasicGenerationWithRequestBaseUrlWithSubfolder()\n    {\n        $request = Request::create('http://www.foo.com/subfolder/foo/bar/subfolder/');\n\n        $request->server->set('SCRIPT_FILENAME', '/var/www/laravel-project/public/subfolder/index.php');\n        $request->server->set('PHP_SELF', '/subfolder/index.php');\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request\n        );\n\n        $route = new Route(['GET'], 'foo/bar/subfolder', ['as' => 'foobar']);\n        $routes->add($route);\n\n        $this->assertSame('/subfolder', $request->getBaseUrl());\n        $this->assertSame('/foo/bar/subfolder', $url->route('foobar', [], false));\n    }\n\n    public function testBasicGenerationWithRequestBaseUrlWithSubfolderAndFileSuffix()\n    {\n        $request = Request::create('http://www.foo.com/subfolder/index.php');\n\n        $request->server->set('SCRIPT_FILENAME', '/var/www/laravel-project/public/subfolder/index.php');\n        $request->server->set('PHP_SELF', '/subfolder/index.php');\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request\n        );\n\n        $route = new Route(['GET'], 'foo/bar/subfolder', ['as' => 'foobar']);\n        $routes->add($route);\n\n        $this->assertSame('/subfolder', $request->getBasePath());\n        $this->assertSame('/subfolder/index.php', $request->getBaseUrl());\n        $this->assertSame('/foo/bar/subfolder', $url->route('foobar', [], false));\n    }\n\n    public function testBasicGenerationWithRequestBaseUrlWithFileSuffix()\n    {\n        $request = Request::create('http://www.foo.com/other.php');\n\n        $request->server->set('SCRIPT_FILENAME', '/var/www/laravel-project/public/other.php');\n        $request->server->set('PHP_SELF', '/other.php');\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request\n        );\n\n        $route = new Route(['GET'], 'foo/bar/subfolder', ['as' => 'foobar']);\n        $routes->add($route);\n\n        $this->assertSame('', $request->getBasePath());\n        $this->assertSame('/other.php', $request->getBaseUrl());\n        $this->assertSame('/foo/bar/subfolder', $url->route('foobar', [], false));\n    }\n\n    public function testBasicGenerationWithPathFormatting()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], '/named-route', ['as' => 'plain']);\n        $routes->add($route);\n\n        $url->formatPathUsing(function ($path) {\n            return '/something'.$path;\n        });\n\n        $this->assertSame('http://www.foo.com/something/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('/something/named-route', $url->route('plain', [], false));\n    }\n\n    public function testUrlFormattersShouldReceiveTargetRoute()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://abc.com/')\n        );\n\n        $namedRoute = new Route(['GET'], '/bar', ['as' => 'plain', 'root' => 'bar.com', 'path' => 'foo']);\n        $routes->add($namedRoute);\n\n        $url->formatHostUsing(function ($root, $route) {\n            return $route ? 'http://'.$route->getAction('root') : $root;\n        });\n\n        $url->formatPathUsing(function ($path, $route) {\n            return $route ? '/'.$route->getAction('path') : $path;\n        });\n\n        $this->assertSame('http://abc.com/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('http://bar.com/foo', $url->route('plain'));\n    }\n\n    public function testBasicRouteGeneration()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        // Empty Named Route\n        $route = new Route(['GET'], '/', ['as' => 'plain']);\n        $routes->add($route);\n\n        // Named Routes\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo']);\n        $routes->add($route);\n\n        // Parameters...\n        $route = new Route(['GET'], 'foo/bar/{baz}/breeze/{boom}', ['as' => 'bar']);\n        $routes->add($route);\n\n        // Single Parameter...\n        $route = new Route(['GET'], 'foo/bar/{baz}', ['as' => 'foobar']);\n        $routes->add($route);\n\n        // Optional parameter\n        $route = new Route(['GET'], 'foo/bar/{baz?}', ['as' => 'optional']);\n        $routes->add($route);\n\n        // HTTPS...\n        $route = new Route(['GET'], 'foo/baz', ['as' => 'baz', 'https']);\n        $routes->add($route);\n\n        // Controller Route Route\n        $route = new Route(['GET'], 'foo/bam', ['controller' => 'foo@bar']);\n        $routes->add($route);\n\n        // Non ASCII routes\n        $route = new Route(['GET'], 'foo/bar/åαф/{baz}', ['as' => 'foobarbaz']);\n        $routes->add($route);\n\n        // Fragments\n        $route = new Route(['GET'], 'foo/bar#derp', ['as' => 'fragment']);\n        $routes->add($route);\n\n        // Invoke action\n        $route = new Route(['GET'], 'foo/invoke', ['controller' => 'InvokableActionStub']);\n        $routes->add($route);\n\n        // With Default Parameter\n        $url->defaults(['locale' => 'en']);\n        $route = new Route(['GET'], 'foo', ['as' => 'defaults', 'domain' => '{locale}.example.com', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        // With backed enum name and domain\n        $route = (new Route(['GET'], 'backed-enum', ['as' => 'prefixed.']))->name(RouteNameEnum::UserIndex)->domain(RouteDomainEnum::DashboardDomain);\n        $routes->add($route);\n\n        $this->assertSame('/', $url->route('plain', [], false));\n        $this->assertSame('/?foo=bar', $url->route('plain', ['foo' => 'bar'], false));\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('foo'));\n        $this->assertSame('/foo/bar', $url->route('foo', [], false));\n        $this->assertSame('/foo/bar?foo=bar', $url->route('foo', ['foo' => 'bar'], false));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor/breeze/otwell?fly=wall', $url->route('bar', ['taylor', 'otwell', 'fly' => 'wall']));\n        $this->assertSame('http://www.foo.com/foo/bar/otwell/breeze/taylor?fly=wall', $url->route('bar', ['boom' => 'taylor', 'baz' => 'otwell', 'fly' => 'wall']));\n        $this->assertSame('http://www.foo.com/foo/bar/0', $url->route('foobar', 0));\n        $this->assertSame('http://www.foo.com/foo/bar/2', $url->route('foobar', 2));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor', $url->route('foobar', 'taylor'));\n        $this->assertSame('/foo/bar/taylor/breeze/otwell?fly=wall', $url->route('bar', ['taylor', 'otwell', 'fly' => 'wall'], false));\n        $this->assertSame('https://www.foo.com/foo/baz', $url->route('baz'));\n        $this->assertSame('http://www.foo.com/foo/bam', $url->action('foo@bar'));\n        $this->assertSame('http://www.foo.com/foo/bam', $url->action(['foo', 'bar']));\n        $this->assertSame('http://www.foo.com/foo/invoke', $url->action('InvokableActionStub'));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor/breeze/otwell?wall&woz', $url->route('bar', ['wall', 'woz', 'boom' => 'otwell', 'baz' => 'taylor']));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor/breeze/otwell?wall&woz', $url->route('bar', ['taylor', 'otwell', 'wall', 'woz']));\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('optional'));\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('optional', ['baz' => null]));\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('optional', ['baz' => '']));\n        $this->assertSame('http://www.foo.com/foo/bar/0', $url->route('optional', ['baz' => 0]));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor', $url->route('optional', 'taylor'));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor', $url->route('optional', ['taylor']));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor?breeze', $url->route('optional', ['taylor', 'breeze']));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor?wall=woz', $url->route('optional', ['wall' => 'woz', 'taylor']));\n        $this->assertSame('http://www.foo.com/foo/bar/taylor?wall=woz&breeze', $url->route('optional', ['wall' => 'woz', 'breeze', 'baz' => 'taylor']));\n        $this->assertSame('http://www.foo.com/foo/bar?wall=woz', $url->route('optional', ['wall' => 'woz']));\n        $this->assertSame('http://www.foo.com/foo/bar/%C3%A5%CE%B1%D1%84/%C3%A5%CE%B1%D1%84', $url->route('foobarbaz', ['baz' => 'åαф']));\n        $this->assertSame('/foo/bar#derp', $url->route('fragment', [], false));\n        $this->assertSame('/foo/bar?foo=bar#derp', $url->route('fragment', ['foo' => 'bar'], false));\n        $this->assertSame('/foo/bar?baz=%C3%A5%CE%B1%D1%84#derp', $url->route('fragment', ['baz' => 'åαф'], false));\n        $this->assertSame('http://en.example.com/foo', $url->route('defaults'));\n        $this->assertSame('http://dashboard.myapp.com/backed-enum', $url->route('prefixed.users.index'));\n    }\n\n    public function testFluentRouteNameDefinitions()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        // Named Routes\n        $route = new Route(['GET'], 'foo/bar', []);\n        $route->name('foo');\n        $routes->add($route);\n        $routes->refreshNameLookups();\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('foo'));\n    }\n\n    public function testControllerRoutesWithADefaultNamespace()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->setRootControllerNamespace('namespace');\n\n        // Controller Route Route\n        $route = new Route(['GET'], 'foo/bar', ['controller' => 'namespace\\foo@bar']);\n        $routes->add($route);\n\n        $route = new Route(['GET'], 'something/else', ['controller' => 'something\\foo@bar']);\n        $routes->add($route);\n\n        $route = new Route(['GET'], 'foo/invoke', ['controller' => 'namespace\\InvokableActionStub']);\n        $routes->add($route);\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->action('foo@bar'));\n        $this->assertSame('http://www.foo.com/something/else', $url->action('\\something\\foo@bar'));\n        $this->assertSame('http://www.foo.com/foo/invoke', $url->action('InvokableActionStub'));\n    }\n\n    public function testControllerRoutesOutsideOfDefaultNamespace()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->setRootControllerNamespace('namespace');\n\n        $route = new Route(['GET'], 'root/namespace', ['controller' => '\\root\\namespace@foo']);\n        $routes->add($route);\n\n        $route = new Route(['GET'], 'invokable/namespace', ['controller' => '\\root\\namespace\\InvokableActionStub']);\n        $routes->add($route);\n\n        $this->assertSame('http://www.foo.com/root/namespace', $url->action('\\root\\namespace@foo'));\n        $this->assertSame('http://www.foo.com/invokable/namespace', $url->action('\\root\\namespace\\InvokableActionStub'));\n    }\n\n    public function testRoutableInterfaceRouting()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/{bar}', ['as' => 'routable']);\n        $routes->add($route);\n\n        $model = new RoutableInterfaceStub;\n        $model->key = 'routable';\n\n        $this->assertSame('/foo/routable', $url->route('routable', [$model], false));\n    }\n\n    public function testRoutableInterfaceRoutingWithCustomBindingField()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/{bar:slug}', ['as' => 'routable']);\n        $routes->add($route);\n\n        $model = new RoutableInterfaceStub;\n        $model->key = 'routable';\n\n        $this->assertSame('/foo/test-slug', $url->route('routable', ['bar' => $model], false));\n        $this->assertSame('/foo/test-slug', $url->route('routable', [$model], false));\n    }\n\n    public function testRoutableInterfaceRoutingAsQueryString()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo', ['as' => 'query-string']);\n        $routes->add($route);\n\n        $model = new RoutableInterfaceStub;\n        $model->key = 'routable';\n\n        $this->assertSame('/foo?routable', $url->route('query-string', $model, false));\n        $this->assertSame('/foo?routable', $url->route('query-string', [$model], false));\n        $this->assertSame('/foo?foo=routable', $url->route('query-string', ['foo' => $model], false));\n    }\n\n    public function testRoutableInterfaceRoutingWithSeparateBindingFieldOnlyForSecondParameter()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/{bar}/{baz:slug}', ['as' => 'routable']);\n        $routes->add($route);\n\n        $model1 = new RoutableInterfaceStub;\n        $model1->key = 'routable-1';\n\n        $model2 = new RoutableInterfaceStub;\n        $model2->key = 'routable-2';\n\n        $this->assertSame('/foo/routable-1/test-slug', $url->route('routable', ['bar' => $model1, 'baz' => $model2], false));\n        $this->assertSame('/foo/routable-1/test-slug', $url->route('routable', [$model1, $model2], false));\n    }\n\n    public function testRoutableInterfaceRoutingWithSingleParameter()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/{bar}', ['as' => 'routable']);\n        $routes->add($route);\n\n        $model = new RoutableInterfaceStub;\n        $model->key = 'routable';\n\n        $this->assertSame('/foo/routable', $url->route('routable', $model, false));\n    }\n\n    public function testRoutesMaintainRequestScheme()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        // Named Routes\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo']);\n        $routes->add($route);\n\n        $this->assertSame('https://www.foo.com/foo/bar', $url->route('foo'));\n    }\n\n    public function testHttpOnlyRoutes()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        // Named Routes\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'http']);\n        $routes->add($route);\n\n        $this->assertSame('http://www.foo.com/foo/bar', $url->route('foo'));\n    }\n\n    public function testRoutesWithDomains()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'domain' => 'sub.foo.com']);\n        $routes->add($route);\n\n        // Wildcards & Domains...\n        $route = new Route(['GET'], 'foo/bar/{baz}', ['as' => 'bar', 'domain' => 'sub.{foo}.com']);\n        $routes->add($route);\n\n        $this->assertSame('http://sub.foo.com/foo/bar', $url->route('foo'));\n        $this->assertSame('http://sub.taylor.com/foo/bar/otwell', $url->route('bar', ['taylor', 'otwell']));\n        $this->assertSame('/foo/bar/otwell', $url->route('bar', ['taylor', 'otwell'], false));\n    }\n\n    public function testRoutesWithDomainsAndPorts()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com:8080/')\n        );\n\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'domain' => 'sub.foo.com']);\n        $routes->add($route);\n\n        // Wildcards & Domains...\n        $route = new Route(['GET'], 'foo/bar/{baz}', ['as' => 'bar', 'domain' => 'sub.{foo}.com']);\n        $routes->add($route);\n\n        $this->assertSame('http://sub.foo.com:8080/foo/bar', $url->route('foo'));\n        $this->assertSame('http://sub.taylor.com:8080/foo/bar/otwell', $url->route('bar', ['taylor', 'otwell']));\n    }\n\n    public function testRoutesWithDomainsStripsProtocols()\n    {\n        // http:// Route\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'domain' => 'http://sub.foo.com']);\n        $routes->add($route);\n\n        $this->assertSame('http://sub.foo.com/foo/bar', $url->route('foo'));\n\n        // https:// Route\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'domain' => 'https://sub.foo.com']);\n        $routes->add($route);\n\n        $this->assertSame('https://sub.foo.com/foo/bar', $url->route('foo'));\n    }\n\n    public function testHttpsRoutesWithDomains()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://foo.com/')\n        );\n\n        // When on HTTPS, no need to specify 443\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'baz', 'domain' => 'sub.foo.com']);\n        $routes->add($route);\n\n        $this->assertSame('https://sub.foo.com/foo/bar', $url->route('baz'));\n    }\n\n    public function testRoutesWithDomainsThroughProxy()\n    {\n        Request::setTrustedProxies(['10.0.0.1'], SymfonyRequest::HEADER_X_FORWARDED_FOR | SymfonyRequest::HEADER_X_FORWARDED_HOST | SymfonyRequest::HEADER_X_FORWARDED_PORT | SymfonyRequest::HEADER_X_FORWARDED_PROTO);\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/', 'GET', [], [], [], ['REMOTE_ADDR' => '10.0.0.1', 'HTTP_X_FORWARDED_PORT' => '80'])\n        );\n\n        $route = new Route(['GET'], 'foo/bar', ['as' => 'foo', 'domain' => 'sub.foo.com']);\n        $routes->add($route);\n\n        $this->assertSame('http://sub.foo.com/foo/bar', $url->route('foo'));\n    }\n\n    public static function providerRouteParameters()\n    {\n        return [\n            [['test' => 123]],\n            [['one' => null, 'test' => 123]],\n            [['one' => '', 'test' => 123]],\n        ];\n    }\n\n    #[DataProvider('providerRouteParameters')]\n    public function testUrlGenerationForControllersRequiresPassingOfRequiredParameters($parameters)\n    {\n        $this->expectException(UrlGenerationException::class);\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com:8080/')\n        );\n\n        $route = new Route(['GET'], 'foo/{one}/{two?}/{three?}', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $this->assertSame('http://www.foo.com:8080/foo?test=123', $url->route('foo', $parameters));\n    }\n\n    public static function provideParametersAndExpectedMeaningfulExceptionMessages()\n    {\n        return [\n            'Missing parameters \"one\", \"two\" and \"three\"' => [\n                [],\n                'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, two, three].',\n            ],\n            'Missing parameters \"two\" and \"three\"' => [\n                ['one' => '123'],\n                'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: two, three].',\n            ],\n            'Missing parameters \"one\" and \"three\"' => [\n                ['two' => '123'],\n                'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, three].',\n            ],\n            'Missing parameters \"one\" and \"two\"' => [\n                ['three' => '123'],\n                'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, two].',\n            ],\n            'Missing parameter \"three\"' => [\n                ['one' => '123', 'two' => '123'],\n                'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: three].',\n            ],\n            'Missing parameter \"two\"' => [\n                ['one' => '123', 'three' => '123'],\n                'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: two].',\n            ],\n            'Missing parameter \"one\"' => [\n                ['two' => '123', 'three' => '123'],\n                'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: one].',\n            ],\n        ];\n    }\n\n    #[DataProvider('provideParametersAndExpectedMeaningfulExceptionMessages')]\n    public function testUrlGenerationThrowsExceptionForMissingParametersWithMeaningfulMessage($parameters, $expectedMeaningfulExceptionMessage)\n    {\n        $this->expectException(UrlGenerationException::class);\n        $this->expectExceptionMessage($expectedMeaningfulExceptionMessage);\n\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com:8080/')\n        );\n\n        $route = new Route(['GET'], 'foo/{one}/{two}/{three}/{four?}', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $url->route('foo', $parameters);\n    }\n\n    public function testSetAssetUrl()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->useOrigin('https://www.bar.com');\n        $this->assertSame('http://www.bar.com/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('http://www.bar.com/foo/bar', $url->asset('foo/bar'));\n\n        $url->useAssetOrigin('https://www.foo.com');\n        $this->assertNotSame('https://www.foo.com/foo/bar', $url->to('foo/bar'));\n        $this->assertSame('https://www.foo.com/foo/bar', $url->asset('foo/bar'));\n        $this->assertSame('https://www.foo.com/foo/bar', $url->asset('foo/bar', true));\n        $this->assertSame('https://www.foo.com/foo/bar', $url->asset('foo/bar', false));\n    }\n\n    public function testUseRootUrl()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->useOrigin('https://www.bar.com');\n        $this->assertSame('http://www.bar.com/foo/bar', $url->to('foo/bar'));\n\n        // Ensure trailing slash is trimmed from root URL as UrlGenerator already handles this\n        $url->useOrigin('http://www.foo.com/');\n        $this->assertSame('http://www.foo.com/bar', $url->to('/bar'));\n\n        // Route Based...\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->forceScheme('https');\n        $route = new Route(['GET'], '/foo', ['as' => 'plain']);\n        $routes->add($route);\n\n        $this->assertSame('https://www.foo.com/foo', $url->route('plain'));\n\n        $url->useOrigin('https://www.bar.com');\n        $this->assertSame('https://www.bar.com/foo', $url->route('plain'));\n    }\n\n    public function testForceHttps()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->forceHttps();\n        $route = new Route(['GET'], '/foo', ['as' => 'plain']);\n        $routes->add($route);\n\n        $this->assertSame('https://www.foo.com/foo', $url->route('plain'));\n    }\n\n    public function testPrevious()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->getRequest()->headers->set('referer', 'http://www.bar.com/');\n        $this->assertSame('http://www.bar.com/', $url->previous());\n\n        $url->getRequest()->headers->remove('referer');\n        $this->assertEquals($url->to('/'), $url->previous());\n\n        $this->assertEquals($url->to('/foo'), $url->previous('/foo'));\n    }\n\n    public function testPreviousPath()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->getRequest()->headers->set('referer', 'http://www.foo.com?baz=bah');\n        $this->assertSame('/', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.foo.com/?baz=bah');\n        $this->assertSame('/', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.foo.com/bar?baz=bah');\n        $this->assertSame('/bar', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.bar.com/foo');\n        $this->assertSame('/foo', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.bar.com/foo?bar=baz');\n        $this->assertSame('/foo', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.bar.com');\n        $this->assertSame('/', $url->previousPath());\n\n        $url->getRequest()->headers->remove('referer');\n        $this->assertSame('/', $url->previousPath());\n\n        $this->assertSame('/bar', $url->previousPath('/bar'));\n    }\n\n    public function testPreviousPathWithBaseUrl()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/subdir/current')\n        );\n\n        $url->forceRootUrl('http://www.foo.com/subdir');\n\n        $url->getRequest()->headers->set('referer', 'http://www.foo.com/subdir/dashboard?x=1');\n        $this->assertSame('/dashboard', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.bar.com/foo');\n        $this->assertSame('/foo', $url->previousPath());\n\n        $url->getRequest()->headers->set('referer', 'http://www.foo.com/subdir');\n        $this->assertSame('/', $url->previousPath());\n    }\n\n    public function testRouteNotDefinedException()\n    {\n        $this->expectException(RouteNotFoundException::class);\n        $this->expectExceptionMessage('Route [not_exists_route] not defined.');\n\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->route('not_exists_route');\n    }\n\n    public function testSignedUrl()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'secret';\n        });\n\n        $route = new Route(['GET'], 'foo', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $request = Request::create($url->signedRoute('foo'));\n\n        $this->assertTrue($url->hasValidSignature($request));\n\n        $request = Request::create($url->signedRoute('foo').'?tampered=true');\n\n        $this->assertFalse($url->hasValidSignature($request));\n\n        $request = Request::create($url->signedRoute('foo').'&tampered=true');\n\n        $this->assertTrue($url->hasValidSignature($request, ignoreQuery: ['tampered']));\n\n        $this->assertTrue($url->hasValidSignature($request, ignoreQuery: fn ($parameter) => $parameter === 'tampered'));\n    }\n\n    public function testSignedUrlImplicitModelBinding()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'secret';\n        });\n\n        $route = new Route(['GET'], 'foo/{user:uuid}', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $user = new RoutingUrlGeneratorTestUser(['uuid' => '0231d4ac-e9e3-4452-a89a-4427cfb23c3e']);\n\n        $request = Request::create($url->signedRoute('foo', $user));\n\n        $this->assertTrue($url->hasValidSignature($request));\n    }\n\n    public function testSignedRelativeUrl()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'secret';\n        });\n\n        $route = new Route(['GET'], 'foo', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $result = $url->signedRoute('foo', [], null, false);\n\n        $request = Request::create($result);\n\n        $this->assertTrue($url->hasValidSignature($request, false));\n\n        $request = Request::create($url->signedRoute('foo', [], null, false).'?tampered=true');\n\n        $this->assertFalse($url->hasValidSignature($request, false));\n    }\n\n    public function testSignedUrlParameterCannotBeNamedSignature()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'secret';\n        });\n\n        $route = new Route(['GET'], 'foo/{signature}', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('reserved');\n\n        Request::create($url->signedRoute('foo', ['signature' => 'bar']));\n    }\n\n    public function testSignedUrlParameterCannotBeNamedExpires()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'secret';\n        });\n\n        $route = new Route(['GET'], 'foo/{expires}', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('reserved');\n\n        Request::create($url->signedRoute('foo', ['expires' => 253402300799]));\n    }\n\n    public function testRouteGenerationWithBackedEnums()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $namedRoute = new Route(['GET'], '/foo/{bar}', ['as' => 'foo.bar']);\n        $routes->add($namedRoute);\n\n        $this->assertSame('http://www.foo.com/foo/fruits', $url->route('foo.bar', CategoryBackedEnum::Fruits));\n    }\n\n    public function testRouteGenerationWithNestedBackedEnums()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $namedRoute = new Route(['GET'], '/foo', ['as' => 'foo']);\n        $routes->add($namedRoute);\n\n        $this->assertSame(\n            'http://www.foo.com/foo?filter%5B0%5D=people&filter%5B1%5D=fruits',\n            $url->route('foo', ['filter' => [CategoryBackedEnum::People, CategoryBackedEnum::Fruits]]),\n        );\n    }\n\n    public function testSignedUrlWithKeyResolver()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            $request = Request::create('http://www.foo.com/')\n        );\n        $url->setKeyResolver(function () {\n            return 'first-secret';\n        });\n\n        $route = new Route(['GET'], 'foo', ['as' => 'foo', function () {\n            //\n        }]);\n        $routes->add($route);\n\n        $firstRequest = Request::create($url->signedRoute('foo'));\n\n        $this->assertTrue($url->hasValidSignature($firstRequest));\n\n        $request = Request::create($url->signedRoute('foo').'?tampered=true');\n\n        $this->assertFalse($url->hasValidSignature($request));\n\n        $url2 = $url->withKeyResolver(function () {\n            return 'second-secret';\n        });\n\n        $this->assertFalse($url2->hasValidSignature($firstRequest));\n\n        $secondRequest = Request::create($url2->signedRoute('foo'));\n\n        $this->assertTrue($url2->hasValidSignature($secondRequest));\n        $this->assertFalse($url->hasValidSignature($secondRequest));\n\n        // Key resolver also supports multiple keys, for app key rotation via the config \"app.previous_keys\"\n        $url3 = $url->withKeyResolver(function () {\n            return ['first-secret', 'second-secret'];\n        });\n\n        $this->assertTrue($url3->hasValidSignature($firstRequest));\n        $this->assertTrue($url3->hasValidSignature($secondRequest));\n    }\n\n    public function testMissingNamedRouteResolution()\n    {\n        $url = new UrlGenerator(\n            new RouteCollection,\n            Request::create('http://www.foo.com/')\n        );\n\n        $url->resolveMissingNamedRoutesUsing(fn ($name, $parameters, $absolute) => 'test-url');\n\n        $this->assertSame('test-url', $url->route('foo'));\n    }\n\n    public function testPassedParametersHavePrecedenceOverDefaults()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $url->defaults([\n            'tenant' => 'defaultTenant',\n        ]);\n\n        $route = new Route(['GET'], 'bar/{tenant}/{post}', ['as' => 'bar', fn () => '']);\n        $routes->add($route);\n\n        // Named parameters\n        $this->assertSame(\n            'https://www.foo.com/bar/concreteTenant/concretePost',\n            $url->route('bar', [\n                'tenant' => tap(new RoutableInterfaceStub, fn ($x) => $x->key = 'concreteTenant'),\n                'post' => tap(new RoutableInterfaceStub, fn ($x) => $x->key = 'concretePost'),\n            ]),\n        );\n\n        // Positional parameters\n        $this->assertSame(\n            'https://www.foo.com/bar/concreteTenant/concretePost',\n            $url->route('bar', [\n                tap(new RoutableInterfaceStub, fn ($x) => $x->key = 'concreteTenant'),\n                tap(new RoutableInterfaceStub, fn ($x) => $x->key = 'concretePost'),\n            ]),\n        );\n    }\n\n    public function testComplexRouteGenerationWithDefaultsAndBindingFields()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $url->defaults([\n            'tenant' => 'defaultTenant',\n            'tenant:slug' => 'defaultTenantSlug',\n            'team' => 'defaultTeam',\n            'team:slug' => 'defaultTeamSlug',\n            'user' => 'defaultUser',\n            'user:slug' => 'defaultUserSlug',\n        ]);\n\n        $keyParam = fn ($value) => tap(new RoutableInterfaceStub, fn ($routable) => $routable->key = $value);\n        $slugParam = fn ($value) => tap(new RoutableInterfaceStub, fn ($routable) => $routable->slug = $value);\n\n        /**\n         * One parameter with a default value, one without a default value.\n         *\n         * No binding fields.\n         */\n        $route = new Route(['GET'], 'tenantPost/{tenant}/{post}', ['as' => 'tenantPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantPost: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/concreteTenant/concretePost',\n            $url->route('tenantPost', [$keyParam('concreteTenant'), $keyParam('concretePost')]),\n        );\n\n        // tenantPost: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/concreteTenant/concretePost',\n            $url->route('tenantPost', ['tenant' => $keyParam('concreteTenant'), 'post' => $keyParam('concretePost')]),\n        );\n\n        // tenantPost: Tenant (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/defaultTenant/concretePost',\n            $url->route('tenantPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantPost: Tenant (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/defaultTenant/concretePost',\n            $url->route('tenantPost', ['post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * One parameter with a default value, one without a default value.\n         *\n         * Binding field for the first {tenant} parameter with a default value.\n         */\n        $route = new Route(['GET'], 'tenantSlugPost/{tenant:slug}/{post}', ['as' => 'tenantSlugPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugPost: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/concreteTenantSlug/concretePost',\n            $url->route('tenantSlugPost', [$slugParam('concreteTenantSlug'), $keyParam('concretePost')]),\n        );\n\n        // tenantSlugPost: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/concreteTenantSlug/concretePost',\n            $url->route('tenantSlugPost', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost')]),\n        );\n\n        // tenantSlugPost: Tenant (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/defaultTenantSlug/concretePost',\n            $url->route('tenantSlugPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugPost: Tenant (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/defaultTenantSlug/concretePost',\n            $url->route('tenantSlugPost', ['post' => $keyParam('concretePost')]),\n        );\n\n        // Repeat the two assertions above without the 'tenant' default (without slug)\n        $url->defaults(['tenant' => null]);\n\n        // tenantSlugPost: Tenant (with default) omitted, post passed positionally, with the default value for 'tenant' (without slug) removed\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/defaultTenantSlug/concretePost',\n            $url->route('tenantSlugPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugPost: Tenant (with default) omitted, post passed using key, with the default value for 'tenant' (without slug) removed\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/defaultTenantSlug/concretePost',\n            $url->route('tenantSlugPost', ['post' => $keyParam('concretePost')]),\n        );\n\n        // Revert the default value for the tenant parameter back\n        $url->defaults(['tenant' => 'defaultTenant']);\n\n        /**\n         * One parameter with a default value, one without a default value.\n         *\n         * Binding field for the second parameter without a default value.\n         *\n         * This is the only route in this test where we use a binding field\n         * for a parameter that does not have a default value and is not\n         * the first parameter. This is the simplest scenario so it doesn't\n         * need to be tested as repetitively as the other scenarios which are\n         * all special in some way.\n         */\n        $route = new Route(['GET'], 'tenantPostSlug/{tenant}/{post:slug}', ['as' => 'tenantPostSlug', fn () => '']);\n        $routes->add($route);\n\n        // tenantPostSlug: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostSlug/concreteTenant/concretePostSlug',\n            $url->route('tenantPostSlug', [$keyParam('concreteTenant'), $slugParam('concretePostSlug')]),\n        );\n\n        // tenantPostSlug: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantPostSlug/concreteTenant/concretePostSlug',\n            $url->route('tenantPostSlug', ['tenant' => $keyParam('concreteTenant'), 'post' => $slugParam('concretePostSlug')]),\n        );\n\n        // tenantPostSlug: Tenant (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostSlug/defaultTenant/concretePostSlug',\n            $url->route('tenantPostSlug', [$slugParam('concretePostSlug')]),\n        );\n\n        // tenantPostSlug: Tenant (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostSlug/defaultTenant/concretePostSlug',\n            $url->route('tenantPostSlug', ['post' => $slugParam('concretePostSlug')]),\n        );\n\n        /**\n         * Two parameters with a default value, one without.\n         *\n         * Having established that passing parameters by key works fine above,\n         * we mainly test positional parameters in variations of this route.\n         */\n        $route = new Route(['GET'], 'tenantTeamPost/{tenant}/{team}/{post}', ['as' => 'tenantTeamPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantTeamPost: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamPost/concreteTenant/concreteTeam/concretePost',\n            $url->route('tenantTeamPost', [$keyParam('concreteTenant'), $keyParam('concreteTeam'), $keyParam('concretePost')]),\n        );\n\n        // tenantTeamPost: Tenant (with default) omitted, team and post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamPost/defaultTenant/concreteTeam/concretePost',\n            $url->route('tenantTeamPost', [$keyParam('concreteTeam'), $keyParam('concretePost')]),\n        );\n\n        // tenantTeamPost: Tenant and team (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamPost/defaultTenant/defaultTeam/concretePost',\n            $url->route('tenantTeamPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantTeamPost: Tenant passed by key, team (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamPost/concreteTenant/defaultTeam/concretePost',\n            $url->route('tenantTeamPost', ['tenant' => $keyParam('concreteTenant'), $keyParam('concretePost')]),\n        );\n\n        /**\n         * Two parameters with a default value, one without.\n         *\n         * The first {tenant} parameter also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantSlugTeamPost/{tenant:slug}/{team}/{post}', ['as' => 'tenantSlugTeamPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugTeamPost: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamPost/concreteTenantSlug/concreteTeam/concretePost',\n            $url->route('tenantSlugTeamPost', [$slugParam('concreteTenantSlug'), $keyParam('concreteTeam'), $keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamPost: Tenant (with default) omitted, team and post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamPost/defaultTenantSlug/concreteTeam/concretePost',\n            $url->route('tenantSlugTeamPost', [$keyParam('concreteTeam'), $keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamPost: Tenant and team (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamPost/defaultTenantSlug/defaultTeam/concretePost',\n            $url->route('tenantSlugTeamPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamPost: Tenant passed by key, team (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamPost/concreteTenantSlug/defaultTeam/concretePost',\n            $url->route('tenantSlugTeamPost', ['tenant' => $slugParam('concreteTenantSlug'), $keyParam('concretePost')]),\n        );\n\n        /**\n         * Two parameters with a default value, one without.\n         *\n         * The second {team} parameter also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantTeamSlugPost/{tenant}/{team:slug}/{post}', ['as' => 'tenantTeamSlugPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantTeamSlugPost: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamSlugPost/concreteTenant/concreteTeamSlug/concretePost',\n            $url->route('tenantTeamSlugPost', [$keyParam('concreteTenant'), $slugParam('concreteTeamSlug'), $keyParam('concretePost')]),\n        );\n\n        // tenantTeamSlugPost: Tenant (with default) omitted, team and post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamSlugPost/defaultTenant/concreteTeamSlug/concretePost',\n            $url->route('tenantTeamSlugPost', [$slugParam('concreteTeamSlug'), $keyParam('concretePost')]),\n        );\n\n        // tenantTeamSlugPost: Tenant and team (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamSlugPost/defaultTenant/defaultTeamSlug/concretePost',\n            $url->route('tenantTeamSlugPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantTeamSlugPost: Tenant passed by key, team (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantTeamSlugPost/concreteTenantSlug/defaultTeamSlug/concretePost',\n            $url->route('tenantTeamSlugPost', ['tenant' => $keyParam('concreteTenantSlug'), $keyParam('concretePost')]),\n        );\n\n        /**\n         * Two parameters with a default value, one without.\n         *\n         * Both parameters with default values, {tenant} and {team}, also have binding fields.\n         */\n        $route = new Route(['GET'], 'tenantSlugTeamSlugPost/{tenant:slug}/{team:slug}/{post}', ['as' => 'tenantSlugTeamSlugPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugTeamSlugPost: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamSlugPost/concreteTenantSlug/concreteTeamSlug/concretePost',\n            $url->route('tenantSlugTeamSlugPost', [$slugParam('concreteTenantSlug'), $slugParam('concreteTeamSlug'), $keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamSlugPost: Tenant (with default) omitted, team and post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamSlugPost/defaultTenantSlug/concreteTeamSlug/concretePost',\n            $url->route('tenantSlugTeamSlugPost', [$slugParam('concreteTeamSlug'), $keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamSlugPost: Tenant and team (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamSlugPost/defaultTenantSlug/defaultTeamSlug/concretePost',\n            $url->route('tenantSlugTeamSlugPost', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugTeamSlugPost: Tenant passed by key, team (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugTeamSlugPost/concreteTenantSlug/defaultTeamSlug/concretePost',\n            $url->route('tenantSlugTeamSlugPost', ['tenant' => $slugParam('concreteTenantSlug'), $keyParam('concretePost')]),\n        );\n\n        /**\n         * One parameter without a default value, one with a default value.\n         *\n         * Importantly, the parameter with the default value comes second.\n         */\n        $route = new Route(['GET'], 'postUser/{post}/{user}', ['as' => 'postUser', fn () => '']);\n        $routes->add($route);\n\n        // postUser: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postUser/concretePost/concreteUser',\n            $url->route('postUser', [$keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // postUser: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/postUser/concretePost/concreteUser',\n            // Reversed order just to check it doesn't matter with named parameters\n            $url->route('postUser', ['user' => $keyParam('concreteUser'), 'post' => $keyParam('concretePost')]),\n        );\n\n        // postUser: User (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postUser/concretePost/defaultUser',\n            $url->route('postUser', [$keyParam('concretePost')]),\n        );\n\n        // postUser: User (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/postUser/concretePost/defaultUser',\n            $url->route('postUser', ['post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * One parameter without a default value, one with a default value.\n         *\n         * Importantly, the parameter with the default value comes second.\n         *\n         * In this variation the first parameter, without a default value,\n         * also has a binding field.\n         */\n        $route = new Route(['GET'], 'postSlugUser/{post:slug}/{user}', ['as' => 'postSlugUser', fn () => '']);\n        $routes->add($route);\n\n        // postSlugUser: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postSlugUser/concretePostSlug/concreteUser',\n            $url->route('postSlugUser', [$slugParam('concretePostSlug'), $keyParam('concreteUser')]),\n        );\n\n        // postSlugUser: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/postSlugUser/concretePostSlug/concreteUser',\n            $url->route('postSlugUser', ['post' => $slugParam('concretePostSlug'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // postSlugUser: User (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postSlugUser/concretePostSlug/defaultUser',\n            $url->route('postSlugUser', [$slugParam('concretePostSlug')]),\n        );\n\n        // postSlugUser: User (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/postSlugUser/concretePostSlug/defaultUser',\n            $url->route('postSlugUser', ['post' => $slugParam('concretePostSlug')]),\n        );\n\n        /**\n         * One parameter without a default value, one with a default value.\n         *\n         * Importantly, the parameter with the default value comes second.\n         *\n         * In this variation the second parameter, with a default value,\n         * also has a binding field.\n         */\n        $route = new Route(['GET'], 'postUserSlug/{post}/{user:slug}', ['as' => 'postUserSlug', fn () => '']);\n        $routes->add($route);\n\n        // postUserSlug: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postUserSlug/concretePost/concreteUserSlug',\n            $url->route('postUserSlug', [$keyParam('concretePost'), $slugParam('concreteUserSlug')]),\n        );\n\n        // postUserSlug: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/postUserSlug/concretePost/concreteUserSlug',\n            $url->route('postUserSlug', ['post' => $keyParam('concretePost'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // postUserSlug: User (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postUserSlug/concretePost/defaultUserSlug',\n            $url->route('postUserSlug', [$keyParam('concretePost')]),\n        );\n\n        // postUserSlug: User (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/postUserSlug/concretePost/defaultUserSlug',\n            $url->route('postUserSlug', ['post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * One parameter without a default value, one with a default value.\n         *\n         * Importantly, the parameter with the default value comes second.\n         *\n         * In this variation, both parameters have binding fields.\n         */\n        $route = new Route(['GET'], 'postSlugUserSlug/{post:slug}/{user:slug}', ['as' => 'postSlugUserSlug', fn () => '']);\n        $routes->add($route);\n\n        // postSlugUserSlug: Both parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postSlugUserSlug/concretePostSlug/concreteUserSlug',\n            $url->route('postSlugUserSlug', [$slugParam('concretePostSlug'), $slugParam('concreteUserSlug')]),\n        );\n\n        // postSlugUserSlug: Both parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/postSlugUserSlug/concretePostSlug/concreteUserSlug',\n            $url->route('postSlugUserSlug', ['post' => $slugParam('concretePostSlug'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // postSlugUserSlug: User (with default) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/postSlugUserSlug/concretePostSlug/defaultUserSlug',\n            $url->route('postSlugUserSlug', [$slugParam('concretePostSlug')]),\n        );\n\n        // postSlugUserSlug: User (with default) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/postSlugUserSlug/concretePostSlug/defaultUserSlug',\n            $url->route('postSlugUserSlug', ['post' => $slugParam('concretePostSlug')]),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with default values.\n         */\n        $route = new Route(['GET'], 'tenantPostUser/{tenant}/{post}/{user}', ['as' => 'tenantPostUser', fn () => '']);\n        $routes->add($route);\n\n        // tenantPostUser: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/concreteTenant/concretePost/concreteUser',\n            $url->route('tenantPostUser', [$keyParam('concreteTenant'), $keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantPostUser: Tenant parameter omitted, post and user passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/concreteUser',\n            $url->route('tenantPostUser', [$keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantPostUser: Both tenant and user (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/defaultUser',\n            $url->route('tenantPostUser', [$keyParam('concretePost')]),\n        );\n\n        // tenantPostUser: All parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/concreteTenant/concretePost/concreteUser',\n            $url->route('tenantPostUser', ['tenant' => $keyParam('concreteTenant'), 'post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantPostUser: Both tenant and user (with defaults) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/defaultUser',\n            $url->route('tenantPostUser', ['post' => $keyParam('concretePost')]),\n        );\n\n        // tenantPostUser: Tenant parameter (with default) omitted, post and user passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/concreteUser',\n            $url->route('tenantPostUser', ['post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantPostUser: User parameter (with default) omitted, tenant and post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/concreteTenant/concretePost/defaultUser',\n            $url->route('tenantPostUser', ['tenant' => $keyParam('concreteTenant'), 'post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with a default value.\n         *\n         * In this variation of this route, the first {tenant} parameter, with a default value,\n         * also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantSlugPostUser/{tenant:slug}/{post}/{user}', ['as' => 'tenantSlugPostUser', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugPostUser: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', [$slugParam('concreteTenantSlug'), $keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Tenant parameter omitted, post and user passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', [$keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Both tenant and user (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUser: All parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Both tenant and user (with defaults) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', ['post' => $keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUser: Tenant parameter (with default) omitted, post and user passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', ['post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: User parameter (with default) omitted, tenant and post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with a default value.\n         *\n         * In this variation of this route, the last {user} parameter, with a default value,\n         * also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantPostUserSlug/{tenant}/{post}/{user:slug}', ['as' => 'tenantPostUserSlug', fn () => '']);\n        $routes->add($route);\n\n        // tenantPostUserSlug: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/concreteTenant/concretePost/concreteUserSlug',\n            $url->route('tenantPostUserSlug', [$keyParam('concreteTenant'), $keyParam('concretePost'), $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantPostUserSlug: Tenant parameter omitted, post and user passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/defaultTenant/concretePost/concreteUserSlug',\n            $url->route('tenantPostUserSlug', [$keyParam('concretePost'), $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantPostUserSlug: Both tenant and user (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/defaultTenant/concretePost/defaultUserSlug',\n            $url->route('tenantPostUserSlug', [$keyParam('concretePost')]),\n        );\n\n        // tenantPostUserSlug: All parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/concreteTenant/concretePost/concreteUserSlug',\n            $url->route('tenantPostUserSlug', ['tenant' => $keyParam('concreteTenant'), 'post' => $keyParam('concretePost'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantPostUserSlug: Both tenant and user (with defaults) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/defaultTenant/concretePost/defaultUserSlug',\n            $url->route('tenantPostUserSlug', ['post' => $keyParam('concretePost')]),\n        );\n\n        // tenantPostUserSlug: Tenant parameter (with default) omitted, post and user passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/defaultTenant/concretePost/concreteUserSlug',\n            $url->route('tenantPostUserSlug', ['post' => $keyParam('concretePost'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantPostUserSlug: User parameter (with default) omitted, tenant and post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserSlug/concreteTenant/concretePost/defaultUserSlug',\n            $url->route('tenantPostUserSlug', ['tenant' => $keyParam('concreteTenant'), 'post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with a default value.\n         *\n         * In this variation of this route, the first {tenant} parameter, with a default value,\n         * also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantSlugPostUser/{tenant:slug}/{post}/{user}', ['as' => 'tenantSlugPostUser', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugPostUser: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', [$slugParam('concreteTenantSlug'), $keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Tenant parameter omitted, post and user passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', [$keyParam('concretePost'), $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Both tenant and user (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUser: All parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: Both tenant and user (with defaults) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', ['post' => $keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUser: Tenant parameter (with default) omitted, post and user passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/defaultTenantSlug/concretePost/concreteUser',\n            $url->route('tenantSlugPostUser', ['post' => $keyParam('concretePost'), 'user' => $keyParam('concreteUser')]),\n        );\n\n        // tenantSlugPostUser: User parameter (with default) omitted, tenant and post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUser/concreteTenantSlug/concretePost/defaultUser',\n            $url->route('tenantSlugPostUser', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost')]),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with a default value.\n         *\n         * In this variation of this route, both fields with a default value, {tenant} and\n         * {user}, also have binding fields.\n         */\n        $route = new Route(['GET'], 'tenantSlugPostUserSlug/{tenant:slug}/{post}/{user:slug}', ['as' => 'tenantSlugPostUserSlug', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugPostUserSlug: All parameters passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/concreteTenantSlug/concretePost/concreteUserSlug',\n            $url->route('tenantSlugPostUserSlug', [$slugParam('concreteTenantSlug'), $keyParam('concretePost'), $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantSlugPostUserSlug: Tenant parameter omitted, post and user passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/defaultTenantSlug/concretePost/concreteUserSlug',\n            $url->route('tenantSlugPostUserSlug', [$keyParam('concretePost'), $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantSlugPostUserSlug: Both tenant and user (with defaults) omitted, post passed positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/defaultTenantSlug/concretePost/defaultUserSlug',\n            $url->route('tenantSlugPostUserSlug', [$keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUserSlug: All parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/concreteTenantSlug/concretePost/concreteUserSlug',\n            $url->route('tenantSlugPostUserSlug', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantSlugPostUserSlug: Both tenant and user (with defaults) omitted, post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/defaultTenantSlug/concretePost/defaultUserSlug',\n            $url->route('tenantSlugPostUserSlug', ['post' => $keyParam('concretePost')]),\n        );\n\n        // tenantSlugPostUserSlug: Tenant parameter (with default) omitted, post and user passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/defaultTenantSlug/concretePost/concreteUserSlug',\n            $url->route('tenantSlugPostUserSlug', ['post' => $keyParam('concretePost'), 'user' => $slugParam('concreteUserSlug')]),\n        );\n\n        // tenantSlugPostUserSlug: User parameter (with default) omitted, tenant and post passed using key\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPostUserSlug/concreteTenantSlug/concretePost/defaultUserSlug',\n            $url->route('tenantSlugPostUserSlug', ['tenant' => $slugParam('concreteTenantSlug'), 'post' => $keyParam('concretePost')]),\n        );\n    }\n\n    public function testComplexRouteGenerationWithDefaultsAndMixedParameterSyntax()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $url->defaults([\n            'tenant' => 'defaultTenant',\n            'user' => 'defaultUser',\n        ]);\n\n        /**\n         * Parameter without a default value in between two parameters with default values.\n         */\n        $route = new Route(['GET'], 'tenantPostUser/{tenant}/{post}/{user}', ['as' => 'tenantPostUser', fn () => '']);\n        $routes->add($route);\n\n        // If the required post parameter is specified using a key,\n        // the positional parameter is used for the user parameter.\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/concreteUser',\n            $url->route('tenantPostUser', ['post' => 'concretePost', 'concreteUser']),\n        );\n\n        /**\n         * Two parameters without default values in between two parameters with default values.\n         */\n        $route = new Route(['GET'], 'tenantPostCommentUser/{tenant}/{post}/{comment}/{user}', ['as' => 'tenantPostCommentUser', fn () => '']);\n        $routes->add($route);\n\n        // Pass first required parameter using a key, second positionally\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/defaultUser',\n            $url->route('tenantPostCommentUser', ['post' => 'concretePost', 'concreteComment']),\n        );\n\n        // Pass first required parameter positionally, second using a key\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/defaultUser',\n            $url->route('tenantPostCommentUser', ['concretePost', 'comment' => 'concreteComment']),\n        );\n\n        // Verify that this is order-independent\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/defaultUser',\n            $url->route('tenantPostCommentUser', ['comment' => 'concreteComment', 'concretePost']),\n        );\n\n        // Both required params passed with keys, positional parameter goes to the user param\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['post' => 'concretePost', 'comment' => 'concreteComment', 'concreteUser']),\n        );\n\n        // First required param passed with a key, remaining params go to the last two route params\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['post' => 'concretePost', 'concreteComment', 'concreteUser']),\n        );\n\n        // Comment parameter passed with a key, remaining params filled (last to last)\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['concretePost', 'comment' => 'concreteComment', 'concreteUser']),\n        );\n\n        // Verify that this is order-independent\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/defaultTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['comment' => 'concreteComment', 'concretePost', 'concreteUser']),\n        );\n\n        // Both default parameters passed positionally, required parameters passed with keys\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/concreteTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['concreteTenant', 'post' => 'concretePost', 'comment' => 'concreteComment', 'concreteUser']),\n        );\n\n        // Verify that the positional parameters may come anywhere in the array\n        $this->assertSame(\n            'https://www.foo.com/tenantPostCommentUser/concreteTenant/concretePost/concreteComment/concreteUser',\n            $url->route('tenantPostCommentUser', ['post' => 'concretePost', 'comment' => 'concreteComment', 'concreteTenant', 'concreteUser']),\n        );\n    }\n\n    public function testDefaultsCanBeCombinedWithExtraQueryParameters()\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $url->defaults([\n            'tenant' => 'defaultTenant',\n            'tenant:slug' => 'defaultTenantSlug',\n            'user' => 'defaultUser',\n        ]);\n\n        $slugParam = fn ($value) => tap(new RoutableInterfaceStub, fn ($routable) => $routable->slug = $value);\n\n        /**\n         * One parameter with a default value, one parameter without a default value.\n         */\n        $route = new Route(['GET'], 'tenantPost/{tenant}/{post}', ['as' => 'tenantPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantPost: Extra positional parameters without values are interpreted as query strings\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/concreteTenant/concretePost?extraQuery',\n            $url->route('tenantPost', ['concreteTenant', 'concretePost', 'extraQuery']),\n        );\n\n        // tenantPost: Query parameters without values go at the end\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/concreteTenant/concretePost?extra=query&extraQuery',\n            $url->route('tenantPost', ['concreteTenant', 'concretePost', 'extraQuery', 'extra' => 'query']),\n        );\n\n        // tenantPost: Defaults can be used with *named* query parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/defaultTenant/concretePost?extra=query',\n            $url->route('tenantPost', ['concretePost', 'extra' => 'query']),\n        );\n\n        // tenantPost: Named query parameters can be placed anywhere in the parameters array\n        $this->assertSame(\n            'https://www.foo.com/tenantPost/concreteTenant/concretePost?extra=query',\n            $url->route('tenantPost', ['concreteTenant', 'extra' => 'query', 'concretePost']),\n        );\n\n        /**\n         * One parameter with a default value, one parameter without a default value.\n         *\n         * The first parameter with a default value, {tenant}, also has a binding field.\n         */\n        $route = new Route(['GET'], 'tenantSlugPost/{tenant:slug}/{post}', ['as' => 'tenantSlugPost', fn () => '']);\n        $routes->add($route);\n\n        // tenantSlugPost: Extra positional parameters without values are interpreted as query strings\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/concreteTenantSlug/concretePost?extraQuery',\n            $url->route('tenantSlugPost', [$slugParam('concreteTenantSlug'), 'concretePost', 'extraQuery']),\n        );\n\n        // tenantSlugPost: Query parameters without values go at the end\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/concreteTenantSlug/concretePost?extra=query&extraQuery',\n            $url->route('tenantSlugPost', [$slugParam('concreteTenantSlug'), 'concretePost', 'extraQuery', 'extra' => 'query']),\n        );\n\n        // tenantSlugPost: Defaults can be used with *named* query parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/defaultTenantSlug/concretePost?extra=query',\n            $url->route('tenantSlugPost', ['concretePost', 'extra' => 'query']),\n        );\n\n        // tenantSlugPost: Named query parameters can be placed anywhere in the parameters array\n        $this->assertSame(\n            'https://www.foo.com/tenantSlugPost/concreteTenantSlug/concretePost?extra=query',\n            $url->route('tenantSlugPost', [$slugParam('concreteTenantSlug'), 'extra' => 'query', 'concretePost']),\n        );\n\n        /**\n         * Parameter without a default value in between two parameters with default values.\n         */\n        $route = new Route(['GET'], 'tenantPostUser/{tenant}/{post}/{user}', ['as' => 'tenantPostUser', fn () => '']);\n        $routes->add($route);\n\n        // tenantPostUser: Query string parameters may be passed positionally if\n        // all route parameters are passed as well, i.e. defaults are not used.\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/concreteTenant/concretePost/concreteUser?extraQuery',\n            $url->route('tenantPostUser', ['concreteTenant', 'concretePost', 'concreteUser', 'extraQuery']),\n        );\n\n        // tenantPostUser: Query string parameters can be passed as key-value\n        // pairs if all route params are passed as well, i.e. no defaults.\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/concreteTenant/concretePost/concreteUser?extraQuery',\n            $url->route('tenantPostUser', ['concreteTenant', 'concretePost', 'concreteUser', 'extraQuery']),\n        );\n\n        // tenantPostUser: With omitted default parameters, query string parameters\n        // can only be specified using key-value pairs. Positional query string\n        // parameters would be interpreted as route parameters instead.\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/concreteUser?extra=query',\n            $url->route('tenantPostUser', ['concretePost', 'concreteUser', 'extra' => 'query']),\n        );\n\n        // tenantPostUser: Use defaults for tenant and user, pass post positionally\n        // and add an extra query string parameter as a key-value pair.\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUser/defaultTenant/concretePost/defaultUser?extra=query',\n            $url->route('tenantPostUser', ['concretePost', 'extra' => 'query']),\n        );\n    }\n\n    public function testUrlGenerationWithOptionalParameters(): void\n    {\n        $url = new UrlGenerator(\n            $routes = new RouteCollection,\n            Request::create('https://www.foo.com/')\n        );\n\n        $url->defaults([\n            'tenant' => 'defaultTenant',\n            'user' => 'defaultUser',\n        ]);\n\n        /**\n         * Route with one required parameter and one optional parameter.\n         */\n        $route = new Route(['GET'], 'postOptionalMethod/{post}/{method?}', ['as' => 'postOptionalMethod', fn () => '']);\n        $routes->add($route);\n\n        $this->assertSame(\n            'https://www.foo.com/postOptionalMethod/1',\n            $url->route('postOptionalMethod', 1),\n        );\n\n        $this->assertSame(\n            'https://www.foo.com/postOptionalMethod/1/2',\n            $url->route('postOptionalMethod', [1, 2]),\n        );\n\n        /**\n         * Route with two optional parameters.\n         */\n        $route = new Route(['GET'], 'optionalPostOptionalMethod/{post}/{method?}', ['as' => 'optionalPostOptionalMethod', fn () => '']);\n        $routes->add($route);\n\n        $this->assertSame(\n            'https://www.foo.com/optionalPostOptionalMethod/1',\n            $url->route('optionalPostOptionalMethod', 1),\n        );\n\n        $this->assertSame(\n            'https://www.foo.com/optionalPostOptionalMethod/1/2',\n            $url->route('optionalPostOptionalMethod', [1, 2]),\n        );\n\n        /**\n         * Route with one default parameter, one required parameter, and one optional parameter.\n         */\n        $route = new Route(['GET'], 'tenantPostOptionalMethod/{tenant}/{post}/{method?}', ['as' => 'tenantPostOptionalMethod', fn () => '']);\n        $routes->add($route);\n\n        // Passing one parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantPostOptionalMethod/defaultTenant/concretePost',\n            $url->route('tenantPostOptionalMethod', ['concretePost']),\n        );\n\n        // Passing two parameters: optional parameter is prioritized over parameter with a default value\n        $this->assertSame(\n            'https://www.foo.com/tenantPostOptionalMethod/defaultTenant/concretePost/concreteMethod',\n            $url->route('tenantPostOptionalMethod', ['concretePost', 'concreteMethod']),\n        );\n\n        // Passing all three parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantPostOptionalMethod/concreteTenant/concretePost/concreteMethod',\n            $url->route('tenantPostOptionalMethod', ['concreteTenant', 'concretePost', 'concreteMethod']),\n        );\n\n        /**\n         * Route with two default parameters, one required parameter, and one optional parameter.\n         */\n        $route = new Route(['GET'], 'tenantUserPostOptionalMethod/{tenant}/{user}/{post}/{method?}', ['as' => 'tenantUserPostOptionalMethod', fn () => '']);\n        $routes->add($route);\n\n        // Passing one parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/defaultUser/concretePost',\n            $url->route('tenantUserPostOptionalMethod', ['concretePost']),\n        );\n\n        // Passing two parameters: optional parameter is prioritized over parameters with default values\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/defaultUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['concretePost', 'concreteMethod']),\n        );\n\n        // Passing three parameters: only the leftmost parameter with a default value uses its default value\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/concreteUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['concreteUser', 'concretePost', 'concreteMethod']),\n        );\n\n        // Same as the assertion above, but using some named parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/concreteUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['user' => 'concreteUser', 'concretePost', 'concreteMethod']),\n        );\n\n        // Also using a named parameter, but this time for the post parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/concreteUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['concreteUser', 'post' => 'concretePost', 'concreteMethod']),\n        );\n\n        // Also using a named parameter, but this time for the optional method parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/defaultTenant/concreteUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['concreteUser', 'concretePost', 'method' => 'concreteMethod']),\n        );\n\n        // Passing all four parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantUserPostOptionalMethod/concreteTenant/concreteUser/concretePost/concreteMethod',\n            $url->route('tenantUserPostOptionalMethod', ['concreteTenant', 'concreteUser', 'concretePost', 'concreteMethod']),\n        );\n\n        /**\n         * Route with a default parameter, a required parameter, another default parameter, and finally an optional parameter.\n         *\n         * This tests interleaved default parameters when combined with optional parameters.\n         */\n        $route = new Route(['GET'], 'tenantPostUserOptionalMethod/{tenant}/{post}/{user}/{method?}', ['as' => 'tenantPostUserOptionalMethod', fn () => '']);\n        $routes->add($route);\n\n        // Passing one parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/defaultTenant/concretePost/defaultUser',\n            $url->route('tenantPostUserOptionalMethod', ['concretePost']),\n        );\n\n        // Passing two parameters: optional parameter is prioritized over parameters with default values\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/defaultTenant/concretePost/defaultUser/concreteMethod',\n            $url->route('tenantPostUserOptionalMethod', ['concretePost', 'concreteMethod']),\n        );\n\n        // Same as the assertion above, but using some named parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/defaultTenant/concretePost/defaultUser/concreteMethod',\n            $url->route('tenantPostUserOptionalMethod', ['post' => 'concretePost', 'concreteMethod']),\n        );\n\n        // Also using a named parameter, but this time for the optional parameter\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/defaultTenant/concretePost/defaultUser/concreteMethod',\n            $url->route('tenantPostUserOptionalMethod', ['concretePost', 'method' => 'concreteMethod']),\n        );\n\n        // Passing three parameters: only the leftmost parameter with a default value uses its default value\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/defaultTenant/concretePost/concreteUser/concreteMethod',\n            $url->route('tenantPostUserOptionalMethod', ['concretePost', 'concreteUser', 'concreteMethod']),\n        );\n\n        // Passing all four parameters\n        $this->assertSame(\n            'https://www.foo.com/tenantPostUserOptionalMethod/concreteTenant/concretePost/concreteUser/concreteMethod',\n            $url->route('tenantPostUserOptionalMethod', ['concreteTenant', 'concretePost', 'concreteUser', 'concreteMethod']),\n        );\n    }\n}\n\nclass RoutableInterfaceStub implements UrlRoutable\n{\n    public $key;\n    public $slug = 'test-slug';\n\n    public function getRouteKey()\n    {\n        return $this->{$this->getRouteKeyName()};\n    }\n\n    public function getRouteKeyName()\n    {\n        return 'key';\n    }\n\n    public function resolveRouteBinding($routeKey, $field = null)\n    {\n        //\n    }\n\n    public function resolveChildRouteBinding($childType, $routeKey, $field = null)\n    {\n        //\n    }\n}\n\nclass InvokableActionStub\n{\n    public function __invoke()\n    {\n        return 'hello';\n    }\n}\n\nclass RoutingUrlGeneratorTestUser extends Model\n{\n    protected $fillable = ['uuid'];\n}\n"
  },
  {
    "path": "tests/Routing/fixtures/controller.php",
    "content": "<?php\n\nuse BaseController;\n\nclass FooController extends BaseController\n{\n    /**\n     * Display a listing of the resource.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Show the form for creating a new resource.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function create()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function store()\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function show($id)\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the specified resource.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function edit($id)\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function update($id)\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function destroy($id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Routing/fixtures/except_controller.php",
    "content": "<?php\n\nuse BaseController;\n\nclass FooController extends BaseController\n{\n    /**\n     * Show the form for creating a new resource.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function create()\n    {\n        //\n    }\n\n    /**\n     * Store a newly created resource in storage.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function store()\n    {\n        //\n    }\n\n    /**\n     * Show the form for editing the specified resource.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function edit($id)\n    {\n        //\n    }\n\n    /**\n     * Update the specified resource in storage.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function update($id)\n    {\n        //\n    }\n\n    /**\n     * Remove the specified resource from storage.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function destroy($id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Routing/fixtures/only_controller.php",
    "content": "<?php\n\nuse BaseController;\n\nclass FooController extends BaseController\n{\n    /**\n     * Display a listing of the resource.\n     *\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * Display the specified resource.\n     *\n     * @param  int  $id\n     * @return \\Illuminate\\Http\\Response\n     */\n    public function show($id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Routing/fixtures/routes.php",
    "content": "<?php\n\n$router->get('users', function () {\n    return 'all-users';\n});\n"
  },
  {
    "path": "tests/Session/ArraySessionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session;\n\nuse Illuminate\\Session\\ArraySessionHandler;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\nuse SessionHandlerInterface;\n\nclass ArraySessionHandlerTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n\n        parent::tearDown();\n    }\n\n    public function test_it_implements_the_session_handler_interface()\n    {\n        $this->assertInstanceOf(SessionHandlerInterface::class, new ArraySessionHandler(10));\n    }\n\n    public function test_it_initializes_the_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertTrue($handler->open('', ''));\n    }\n\n    public function test_it_closes_the_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertTrue($handler->close());\n    }\n\n    public function test_it_reads_data_from_the_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $handler->write('foo', 'bar');\n\n        $this->assertSame('bar', $handler->read('foo'));\n    }\n\n    public function test_it_reads_data_from_an_almost_expired_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        Carbon::setTestNow(Carbon::now());\n        $handler->write('foo', 'bar');\n\n        Carbon::setTestNow(Carbon::now()->addMinutes(10));\n        $this->assertSame('bar', $handler->read('foo'));\n    }\n\n    public function test_it_reads_data_from_an_expired_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        Carbon::setTestNow(Carbon::now());\n        $handler->write('foo', 'bar');\n\n        Carbon::setTestNow(Carbon::now()->addMinutes(10)->addSecond());\n        $this->assertSame('', $handler->read('foo'));\n    }\n\n    public function test_it_reads_data_from_a_non_existing_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertSame('', $handler->read('foo'));\n    }\n\n    public function test_it_writes_session_data()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertTrue($handler->write('foo', 'bar'));\n        $this->assertSame('bar', $handler->read('foo'));\n\n        $this->assertTrue($handler->write('foo', 'baz'));\n        $this->assertSame('baz', $handler->read('foo'));\n    }\n\n    public function test_it_destroys_a_session()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertTrue($handler->destroy('foo'));\n\n        $handler->write('foo', 'bar');\n\n        $this->assertTrue($handler->destroy('foo'));\n        $this->assertSame('', $handler->read('foo'));\n    }\n\n    public function test_it_cleans_up_old_sessions()\n    {\n        $handler = new ArraySessionHandler(10);\n\n        $this->assertSame(0, $handler->gc(300));\n\n        Carbon::setTestNow(Carbon::now());\n        $handler->write('foo', 'bar');\n        $this->assertSame(0, $handler->gc(300));\n        $this->assertSame('bar', $handler->read('foo'));\n\n        Carbon::setTestNow(Carbon::now()->addSecond());\n\n        $handler->write('baz', 'qux');\n\n        Carbon::setTestNow(Carbon::now()->addMinutes(5));\n\n        $this->assertSame(1, $handler->gc(300));\n        $this->assertSame('', $handler->read('foo'));\n        $this->assertSame('qux', $handler->read('baz'));\n    }\n}\n"
  },
  {
    "path": "tests/Session/CacheBasedSessionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session;\n\nuse Illuminate\\Contracts\\Cache\\Repository as CacheContract;\nuse Illuminate\\Session\\CacheBasedSessionHandler;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CacheBasedSessionHandlerTest extends TestCase\n{\n    protected $cacheMock;\n\n    protected $sessionHandler;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->cacheMock = m::mock(CacheContract::class);\n        $this->sessionHandler = new CacheBasedSessionHandler(cache: $this->cacheMock, minutes: 10);\n    }\n\n    public function test_open()\n    {\n        $result = $this->sessionHandler->open('path', 'session_name');\n        $this->assertTrue($result);\n    }\n\n    public function test_close()\n    {\n        $result = $this->sessionHandler->close();\n        $this->assertTrue($result);\n    }\n\n    public function test_read_returns_data_from_cache()\n    {\n        $this->cacheMock->shouldReceive('get')->once()->with('session_id', '')->andReturn('session_data');\n\n        $data = $this->sessionHandler->read(sessionId: 'session_id');\n        $this->assertEquals('session_data', $data);\n    }\n\n    public function test_read_returns_empty_string_if_no_data()\n    {\n        $this->cacheMock->shouldReceive('get')->once()->with('some_id', '')->andReturn('');\n\n        $data = $this->sessionHandler->read(sessionId: 'some_id');\n        $this->assertEquals('', $data);\n    }\n\n    public function test_write_stores_data_in_cache()\n    {\n        $this->cacheMock->shouldReceive('put')->once()->with('session_id', 'session_data', 600) // 10 minutes in seconds\n            ->andReturn(true);\n\n        $result = $this->sessionHandler->write(sessionId: 'session_id', data: 'session_data');\n\n        $this->assertTrue($result);\n    }\n\n    public function test_destroy_removes_data_from_cache()\n    {\n        $this->cacheMock->shouldReceive('forget')->once()->with('session_id')->andReturn(true);\n\n        $result = $this->sessionHandler->destroy(sessionId: 'session_id');\n\n        $this->assertTrue($result);\n    }\n\n    public function test_gc_returns_zero()\n    {\n        $result = $this->sessionHandler->gc(lifetime: 120);\n\n        $this->assertEquals(0, $result);\n    }\n\n    public function test_get_cache_returns_cache_instance()\n    {\n        $cacheInstance = $this->sessionHandler->getCache();\n\n        $this->assertSame($this->cacheMock, $cacheInstance);\n    }\n}\n"
  },
  {
    "path": "tests/Session/EncryptedSessionStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session;\n\nuse Illuminate\\Contracts\\Encryption\\Encrypter;\nuse Illuminate\\Session\\EncryptedStore;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse SessionHandlerInterface;\n\nclass EncryptedSessionStoreTest extends TestCase\n{\n    public function testSessionIsProperlyEncrypted()\n    {\n        $session = $this->getSession();\n        $session->getEncrypter()->shouldReceive('decrypt')->once()->with(serialize([]))->andReturn(serialize([]));\n        $session->getHandler()->shouldReceive('read')->once()->andReturn(serialize([]));\n        $session->start();\n        $session->put('foo', 'bar');\n        $session->flash('baz', 'boom');\n        $session->now('qux', 'norf');\n        $serialized = serialize([\n            '_token' => $session->token(),\n            'foo' => 'bar',\n            'baz' => 'boom',\n            '_flash' => [\n                'new' => [],\n                'old' => ['baz'],\n            ],\n        ]);\n        $session->getEncrypter()->shouldReceive('encrypt')->once()->with($serialized)->andReturn($serialized);\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $this->getSessionId(),\n            $serialized\n        );\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function getSession()\n    {\n        $reflection = new ReflectionClass(EncryptedStore::class);\n\n        return $reflection->newInstanceArgs($this->getMocks());\n    }\n\n    public function getMocks()\n    {\n        return [\n            $this->getSessionName(),\n            m::mock(SessionHandlerInterface::class),\n            m::mock(Encrypter::class),\n            $this->getSessionId(),\n        ];\n    }\n\n    public function getSessionId()\n    {\n        return 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';\n    }\n\n    public function getSessionName()\n    {\n        return 'name';\n    }\n}\n"
  },
  {
    "path": "tests/Session/FileSessionHandlerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Session\\FileSessionHandler;\nuse Illuminate\\Support\\Carbon;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Illuminate\\Filesystem\\join_paths;\n\nclass FileSessionHandlerTest extends TestCase\n{\n    protected $files;\n\n    protected $sessionHandler;\n\n    protected function setUp(): void\n    {\n        // Create a mock for the Filesystem class\n        $this->files = m::mock(Filesystem::class);\n\n        // Initialize the FileSessionHandler with the mocked Filesystem\n        $this->sessionHandler = new FileSessionHandler($this->files, '/path/to/sessions', 30);\n    }\n\n    public function test_open()\n    {\n        $this->assertTrue($this->sessionHandler->open('/path/to/sessions', 'session_name'));\n    }\n\n    public function test_close()\n    {\n        $this->assertTrue($this->sessionHandler->close());\n    }\n\n    public function test_read_returns_data_when_file_exists_and_is_valid()\n    {\n        $sessionId = 'session_id';\n        $path = '/path/to/sessions/'.$sessionId;\n        Carbon::setTestNow(Carbon::parse('2025-02-02 01:30:00'));\n        // Set up expectations\n        $this->files->shouldReceive('isFile')->with($path)->andReturn(true);\n\n        $minutesAgo30 = Carbon::parse('2025-02-02 01:00:00')->getTimestamp();\n        $this->files->shouldReceive('lastModified')->with($path)->andReturn($minutesAgo30);\n        $this->files->shouldReceive('sharedGet')->with($path)->once()->andReturn('session_data');\n\n        $result = $this->sessionHandler->read($sessionId);\n\n        $this->assertEquals('session_data', $result);\n    }\n\n    public function test_read_returns_data_when_file_exists_but_expired()\n    {\n        $sessionId = 'session_id';\n        $path = '/path/to/sessions/'.$sessionId;\n        Carbon::setTestNow(Carbon::parse('2025-02-02 01:30:01'));\n        // Set up expectations\n        $this->files->shouldReceive('isFile')->with($path)->andReturn(true);\n\n        $minutesAgo30 = Carbon::parse('2025-02-02 01:00:00')->getTimestamp();\n        $this->files->shouldReceive('lastModified')->with($path)->andReturn($minutesAgo30);\n        $this->files->shouldReceive('sharedGet')->never();\n\n        $result = $this->sessionHandler->read($sessionId);\n\n        $this->assertEquals('', $result);\n    }\n\n    public function test_read_returns_empty_string_when_file_does_not_exist()\n    {\n        $sessionId = 'non_existing_session_id';\n        $path = '/path/to/sessions/'.$sessionId;\n\n        // Set up expectations\n        $this->files->shouldReceive('isFile')->with($path)->andReturn(false);\n\n        $result = $this->sessionHandler->read($sessionId);\n\n        $this->assertEquals('', $result);\n    }\n\n    public function test_write_stores_data()\n    {\n        $sessionId = 'session_id';\n        $data = 'session_data';\n\n        // Set up expectations\n        $this->files->shouldReceive('put')->with('/path/to/sessions/'.$sessionId, $data, true)->once()->andReturn(null);\n\n        $result = $this->sessionHandler->write($sessionId, $data);\n\n        $this->assertTrue($result);\n    }\n\n    public function test_destroy_deletes_session_file()\n    {\n        $sessionId = 'session_id';\n\n        // Set up expectations\n        $this->files->shouldReceive('delete')->with('/path/to/sessions/'.$sessionId)->once()->andReturn(null);\n\n        $result = $this->sessionHandler->destroy($sessionId);\n\n        $this->assertTrue($result);\n    }\n\n    public function test_gc_deletes_old_session_files()\n    {\n        $session = new FileSessionHandler($this->files, join_paths(__DIR__, 'tmp'), 30);\n        // Set up expectations for Filesystem\n        $this->files->shouldReceive('delete')->with(join_paths(__DIR__, 'tmp', 'a2'))->once()->andReturn(false);\n        $this->files->shouldReceive('delete')->with(join_paths(__DIR__, 'tmp', 'a3'))->once()->andReturn(true);\n\n        mkdir(__DIR__.'/tmp');\n        touch(__DIR__.'/tmp/a1', time() - 3); // last modified: 3 sec ago\n        touch(__DIR__.'/tmp/a2', time() - 5); // last modified: 5 sec ago\n        touch(__DIR__.'/tmp/a3', time() - 7); // last modified: 7 sec ago\n\n        // act:\n        $count = $session->gc(5);\n\n        $this->assertEquals(2, $count);\n\n        unlink(__DIR__.'/tmp/a1');\n        unlink(__DIR__.'/tmp/a2');\n        unlink(__DIR__.'/tmp/a3');\n\n        rmdir(__DIR__.'/tmp');\n    }\n}\n"
  },
  {
    "path": "tests/Session/Middleware/AuthenticateSessionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session\\Middleware;\n\nuse BadMethodCallException;\nuse Illuminate\\Auth\\AuthenticationException;\nuse Illuminate\\Contracts\\Auth\\Factory as AuthFactory;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Session\\ArraySessionHandler;\nuse Illuminate\\Session\\Middleware\\AuthenticateSession;\nuse Illuminate\\Session\\Store;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass AuthenticateSessionTest extends TestCase\n{\n    public function test_handle_without_session()\n    {\n        $request = new Request;\n        $next = fn () => 'next-1';\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->never();\n\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, $next);\n        $this->assertEquals('next-1', $response);\n    }\n\n    public function test_handle_with_session_without_request_user()\n    {\n        $request = new Request;\n\n        // set session:\n        $request->setLaravelSession(new Store('name', new ArraySessionHandler(1)));\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->never();\n\n        $next = fn () => 'next-2';\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, $next);\n        $this->assertEquals('next-2', $response);\n    }\n\n    public function test_handle_with_session_without_auth_password()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return null;\n            }\n        };\n\n        $request = new Request;\n\n        // set session:\n        $request->setLaravelSession(new Store('name', new ArraySessionHandler(1)));\n        // set a password-less user:\n        $request->setUserResolver(fn () => $user);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->never();\n\n        $next = fn () => 'next-3';\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, $next);\n\n        $this->assertEquals('next-3', $response);\n    }\n\n    public function test_handle_with_session_with_user_auth_password_on_request_via_remember_false()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        $request = new Request;\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(false);\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn(null);\n        // expected MAC for current password when storing in session:\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, fn () => 'next-4');\n\n        $this->assertEquals('mac:my-pass-(*&^%$#!@', $session->get('password_hash_web'));\n        $this->assertEquals('next-4', $response);\n    }\n\n    public function test_handle_with_invalid_password_hash()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        $request = new Request(cookies: ['recaller-name' => 'a|b|invalid-mac']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        // set session:\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(true);\n        $authFactory->shouldReceive('getRecallerName')->once()->andReturn('recaller-name');\n        $authFactory->shouldReceive('logoutCurrentDevice')->once()->andReturn(null);\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn(null);\n        // expected MAC for current password (won't match cookie):\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        $this->assertNotNull($session->get('a'));\n        $this->assertNotNull($session->get('b'));\n        AuthenticateSession::redirectUsing(fn ($request) => 'i-wanna-go-home');\n\n        // act:\n        $middleware = new AuthenticateSession($authFactory);\n\n        $message = '';\n        try {\n            $middleware->handle($request, fn () => 'next-7');\n        } catch (AuthenticationException $e) {\n            $message = $e->getMessage();\n            $this->assertEquals('i-wanna-go-home', $e->redirectTo($request));\n        }\n        $this->assertEquals('Unauthenticated.', $message);\n\n        // ensure session is flushed:\n        $this->assertNull($session->get('a'));\n        $this->assertNull($session->get('b'));\n    }\n\n    public function test_handle_with_invalid_incookie_password_hash_via_remember_true()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        $request = new Request(cookies: ['recaller-name' => 'a|b|invalid-mac']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        // set session:\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(true);\n        $authFactory->shouldReceive('getRecallerName')->once()->andReturn('recaller-name');\n        $authFactory->shouldReceive('logoutCurrentDevice')->once();\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn(null);\n        // expected MAC for current password (won't match cookie):\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        $middleware = new AuthenticateSession($authFactory);\n        // act:\n        try {\n            $message = '';\n            $middleware->handle($request, fn () => 'next-6');\n        } catch (AuthenticationException $e) {\n            $message = $e->getMessage();\n        }\n        $this->assertEquals('Unauthenticated.', $message);\n\n        // ensure session is flushed\n        $this->assertNull($session->get('password_hash_web'));\n        $this->assertNull($session->get('a'));\n        $this->assertNull($session->get('b'));\n    }\n\n    public function test_handle_with_valid_incookie_invalid_insession_hash_via_remember_true()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        $request = new Request(cookies: ['recaller-name' => 'a|b|mac:my-pass-(*&^%$#!@']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        $session->put('password_hash_web', 'invalid-password');\n        // set session on the request:\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(true);\n        $authFactory->shouldReceive('getRecallerName')->once()->andReturn('recaller-name');\n        $authFactory->shouldReceive('logoutCurrentDevice')->once()->andReturn(null);\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn(null);\n        // expected MAC for current password (matches cookie but not session):\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        // act:\n        $middleware = new AuthenticateSession($authFactory);\n        try {\n            $message = '';\n            $middleware->handle($request, fn () => 'next-7');\n        } catch (AuthenticationException $e) {\n            $message = $e->getMessage();\n        }\n        $this->assertEquals('Unauthenticated.', $message);\n\n        // ensure session is flushed:\n        $this->assertNull($session->get('password_hash_web'));\n        $this->assertNull($session->get('a'));\n        $this->assertNull($session->get('b'));\n    }\n\n    public function test_handle_with_valid_password_in_session_cookie_is_empty_guard_has_user()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        $request = new Request(cookies: ['recaller-name' => 'a|b']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        $session->put('password_hash_web', 'mac:my-pass-(*&^%$#!@');\n        // set session on the request:\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(false);\n        $authFactory->shouldReceive('getRecallerName')->never();\n        $authFactory->shouldReceive('logoutCurrentDevice')->never();\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn($user);\n        // expected MAC for current password:\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        // act:\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, fn () => 'next-8');\n\n        $this->assertEquals('next-8', $response);\n        // ensure session is flushed:\n        $this->assertEquals('mac:my-pass-(*&^%$#!@', $session->get('password_hash_web'));\n        $this->assertEquals('1', $session->get('a'));\n        $this->assertEquals('2', $session->get('b'));\n    }\n\n    public function test_handle_with_old_format_cookie_for_backward_compatibility()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        // Cookie contains OLD format (raw password hash, not HMAC)\n        $request = new Request(cookies: ['recaller-name' => 'a|b|my-pass-(*&^%$#!@']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        // Session also contains old format for this test\n        $session->put('password_hash_web', 'my-pass-(*&^%$#!@');\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(true);\n        $authFactory->shouldReceive('getRecallerName')->once()->andReturn('recaller-name');\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn($user);\n        // The HMAC won't match the old format, but fallback to raw hash should work\n        $authFactory->shouldReceive('hashPasswordForCookie')->with('my-pass-(*&^%$#!@')->andReturn('mac:my-pass-(*&^%$#!@');\n\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, fn () => 'next-9');\n\n        // Should succeed because of backward compatibility fallback\n        $this->assertEquals('next-9', $response);\n        // Session should be updated to new format (HMAC)\n        $this->assertEquals('mac:my-pass-(*&^%$#!@', $session->get('password_hash_web'));\n        $this->assertEquals('1', $session->get('a'));\n        $this->assertEquals('2', $session->get('b'));\n    }\n\n    public function test_handle_with_old_format_cookie_and_legacy_guard()\n    {\n        $user = new class\n        {\n            public function getAuthPassword()\n            {\n                return 'my-pass-(*&^%$#!@';\n            }\n        };\n\n        // Cookie contains OLD format (raw password hash, not HMAC)\n        $request = new Request(cookies: ['recaller-name' => 'a|b|my-pass-(*&^%$#!@']);\n        $request->setUserResolver(fn () => $user);\n\n        $session = new Store('name', new ArraySessionHandler(1));\n        $session->put('a', '1');\n        $session->put('b', '2');\n        // Session also contains old format for this test\n        $session->put('password_hash_web', 'my-pass-(*&^%$#!@');\n        $request->setLaravelSession($session);\n\n        $authFactory = m::mock(AuthFactory::class);\n        $authFactory->shouldReceive('viaRemember')->andReturn(true);\n        $authFactory->shouldReceive('getRecallerName')->once()->andReturn('recaller-name');\n        $authFactory->shouldReceive('getDefaultDriver')->andReturn('web');\n        $authFactory->shouldReceive('user')->andReturn($user);\n        // For legacy guards without hashPasswordForCookie method, we use fallback to raw hash\n        $authFactory->shouldReceive('hashPasswordForCookie')->andThrowExceptions([new BadMethodCallException]);\n\n        $middleware = new AuthenticateSession($authFactory);\n        $response = $middleware->handle($request, fn () => 'next-9');\n\n        // Should succeed because of backward compatibility fallback\n        $this->assertEquals('next-9', $response);\n        // Session should stay intact\n        $this->assertEquals('my-pass-(*&^%$#!@', $session->get('password_hash_web'));\n        $this->assertEquals('1', $session->get('a'));\n        $this->assertEquals('2', $session->get('b'));\n    }\n}\n"
  },
  {
    "path": "tests/Session/SessionStoreTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Session;\n\nuse Illuminate\\Cookie\\CookieJar;\nuse Illuminate\\Session\\CookieSessionHandler;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse SessionHandlerInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass SessionStoreTest extends TestCase\n{\n    public function testSessionIsLoadedFromHandler()\n    {\n        $session = $this->getSession();\n        $session->getHandler()->shouldReceive('read')->once()->with($this->getSessionId())->andReturn(serialize(['foo' => 'bar', 'bagged' => ['name' => 'taylor'], '123' => 'bax']));\n        $session->start();\n\n        $this->assertSame('bar', $session->get('foo'));\n        $this->assertSame('bax', $session->get('123'));\n        $this->assertSame('baz', $session->get('bar', 'baz'));\n        $this->assertTrue($session->has('foo'));\n        $this->assertTrue($session->has('123'));\n        $this->assertFalse($session->has('bar'));\n        $this->assertTrue($session->isStarted());\n\n        $session->put('baz', 'boom');\n        $this->assertTrue($session->has('baz'));\n    }\n\n    public function testSessionMigration()\n    {\n        $session = $this->getSession();\n        $oldId = $session->getId();\n        $session->getHandler()->shouldReceive('destroy')->never();\n        $this->assertTrue($session->migrate());\n        $this->assertNotEquals($oldId, $session->getId());\n\n        $session = $this->getSession();\n        $oldId = $session->getId();\n        $session->getHandler()->shouldReceive('destroy')->once()->with($oldId);\n        $this->assertTrue($session->migrate(true));\n        $this->assertNotEquals($oldId, $session->getId());\n    }\n\n    public function testSessionRegeneration()\n    {\n        $session = $this->getSession();\n        $oldId = $session->getId();\n        $session->getHandler()->shouldReceive('destroy')->never();\n        $this->assertTrue($session->regenerate());\n        $this->assertNotEquals($oldId, $session->getId());\n    }\n\n    public function testCantSetInvalidId()\n    {\n        $session = $this->getSession();\n        $this->assertTrue($session->isValidId($session->getId()));\n\n        $session->setId(null);\n        $this->assertNotNull($session->getId());\n        $this->assertTrue($session->isValidId($session->getId()));\n\n        $session->setId(['a']);\n        $this->assertNotSame(['a'], $session->getId());\n\n        $session->setId('wrong');\n        $this->assertNotSame('wrong', $session->getId());\n    }\n\n    public function testSessionInvalidate()\n    {\n        $session = $this->getSession();\n        $oldId = $session->getId();\n\n        $session->put('foo', 'bar');\n        $this->assertGreaterThan(0, count($session->all()));\n\n        $session->flash('name', 'Taylor');\n        $this->assertTrue($session->has('name'));\n\n        $session->getHandler()->shouldReceive('destroy')->once()->with($oldId);\n        $this->assertTrue($session->invalidate());\n\n        $this->assertFalse($session->has('name'));\n        $this->assertNotEquals($oldId, $session->getId());\n        $this->assertCount(0, $session->all());\n    }\n\n    public function testBrandNewSessionIsProperlySaved()\n    {\n        $session = $this->getSession();\n        $session->getHandler()->shouldReceive('read')->once()->andReturn(serialize([]));\n        $session->start();\n        $session->put('foo', 'bar');\n        $session->flash('baz', 'boom');\n        $session->now('qux', 'norf');\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $this->getSessionId(),\n            serialize([\n                '_token' => $session->token(),\n                'foo' => 'bar',\n                'baz' => 'boom',\n                '_flash' => [\n                    'new' => [],\n                    'old' => ['baz'],\n                ],\n            ])\n        );\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function testSessionIsProperlyUpdated()\n    {\n        $session = $this->getSession();\n        $session->getHandler()->shouldReceive('read')->once()->andReturn(serialize([\n            '_token' => Str::random(40),\n            'foo' => 'bar',\n            'baz' => 'boom',\n            '_flash' => [\n                'new' => [],\n                'old' => ['baz'],\n            ],\n        ]));\n        $session->start();\n\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $this->getSessionId(),\n            serialize([\n                '_token' => $session->token(),\n                'foo' => 'bar',\n                '_flash' => [\n                    'new' => [],\n                    'old' => [],\n                ],\n            ])\n        );\n\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function testSessionIsReSavedWhenNothingHasChanged()\n    {\n        $session = $this->getSession();\n        $session->getHandler()->shouldReceive('read')->once()->andReturn(serialize([\n            '_token' => Str::random(40),\n            'foo' => 'bar',\n            'baz' => 'boom',\n            '_flash' => [\n                'new' => [],\n                'old' => [],\n            ],\n        ]));\n        $session->start();\n\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $this->getSessionId(),\n            serialize([\n                '_token' => $session->token(),\n                'foo' => 'bar',\n                'baz' => 'boom',\n                '_flash' => [\n                    'new' => [],\n                    'old' => [],\n                ],\n            ])\n        );\n\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function testSessionIsReSavedWhenNothingHasChangedExceptSessionId()\n    {\n        $session = $this->getSession();\n        $oldId = $session->getId();\n        $token = Str::random(40);\n        $session->getHandler()->shouldReceive('read')->once()->with($oldId)->andReturn(serialize([\n            '_token' => $token,\n            'foo' => 'bar',\n            'baz' => 'boom',\n            '_flash' => [\n                'new' => [],\n                'old' => [],\n            ],\n        ]));\n        $session->start();\n\n        $oldId = $session->getId();\n        $session->migrate();\n        $newId = $session->getId();\n\n        $this->assertNotEquals($newId, $oldId);\n\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $newId,\n            serialize([\n                '_token' => $token,\n                'foo' => 'bar',\n                'baz' => 'boom',\n                '_flash' => [\n                    'new' => [],\n                    'old' => [],\n                ],\n            ])\n        );\n\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function testOldInputFlashing()\n    {\n        $session = $this->getSession();\n        $session->put('boom', 'baz');\n        $session->flashInput(['foo' => 'bar', 'bar' => 0, 'name' => null]);\n\n        $this->assertTrue($session->hasOldInput('foo'));\n        $this->assertSame('bar', $session->getOldInput('foo'));\n        $this->assertEquals(0, $session->getOldInput('bar'));\n        $this->assertFalse($session->hasOldInput('boom'));\n\n        $session->ageFlashData();\n\n        $this->assertTrue($session->hasOldInput('foo'));\n        $this->assertSame('bar', $session->getOldInput('foo'));\n        $this->assertEquals(0, $session->getOldInput('bar'));\n        $this->assertFalse($session->hasOldInput('boom'));\n\n        $this->assertSame('default', $session->getOldInput('input', 'default'));\n        $this->assertNull($session->getOldInput('name', 'default'));\n    }\n\n    public function testDataFlashing()\n    {\n        $session = $this->getSession();\n        $session->flash('foo', 'bar');\n        $session->flash('bar', 0);\n        $session->flash('baz');\n\n        $this->assertTrue($session->has('foo'));\n        $this->assertSame('bar', $session->get('foo'));\n        $this->assertEquals(0, $session->get('bar'));\n        $this->assertTrue($session->get('baz'));\n\n        $session->ageFlashData();\n\n        $this->assertTrue($session->has('foo'));\n        $this->assertSame('bar', $session->get('foo'));\n        $this->assertEquals(0, $session->get('bar'));\n\n        $session->ageFlashData();\n\n        $this->assertFalse($session->has('foo'));\n        $this->assertNull($session->get('foo'));\n    }\n\n    public function testDataFlashingNow()\n    {\n        $session = $this->getSession();\n        $session->now('foo', 'bar');\n        $session->now('bar', 0);\n\n        $this->assertTrue($session->has('foo'));\n        $this->assertSame('bar', $session->get('foo'));\n        $this->assertEquals(0, $session->get('bar'));\n\n        $session->ageFlashData();\n\n        $this->assertFalse($session->has('foo'));\n        $this->assertNull($session->get('foo'));\n    }\n\n    public function testDataMergeNewFlashes()\n    {\n        $session = $this->getSession();\n        $session->flash('foo', 'bar');\n        $session->put('fu', 'baz');\n        $session->put('_flash.old', ['qu']);\n        $this->assertNotFalse(array_search('foo', $session->get('_flash.new')));\n        $this->assertFalse(array_search('fu', $session->get('_flash.new')));\n        $session->keep(['fu', 'qu']);\n        $this->assertNotFalse(array_search('foo', $session->get('_flash.new')));\n        $this->assertNotFalse(array_search('fu', $session->get('_flash.new')));\n        $this->assertNotFalse(array_search('qu', $session->get('_flash.new')));\n        $this->assertFalse(array_search('qu', $session->get('_flash.old')));\n    }\n\n    public function testReflash()\n    {\n        $session = $this->getSession();\n        $session->flash('foo', 'bar');\n        $session->put('_flash.old', ['foo']);\n        $session->reflash();\n        $this->assertNotFalse(array_search('foo', $session->get('_flash.new')));\n        $this->assertFalse(array_search('foo', $session->get('_flash.old')));\n    }\n\n    public function testReflashWithNow()\n    {\n        $session = $this->getSession();\n        $session->now('foo', 'bar');\n        $session->reflash();\n        $this->assertNotFalse(array_search('foo', $session->get('_flash.new')));\n        $this->assertFalse(array_search('foo', $session->get('_flash.old')));\n    }\n\n    public function testOnly()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $session->put('qu', 'ux');\n        $this->assertEquals(['foo' => 'bar', 'qu' => 'ux'], $session->all());\n        $this->assertEquals(['qu' => 'ux'], $session->only(['qu']));\n    }\n\n    public function testExcept()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $session->put('bar', 'baz');\n        $session->put('qu', 'ux');\n\n        $this->assertEquals(['foo' => 'bar', 'qu' => 'ux', 'bar' => 'baz'], $session->all());\n        $this->assertEquals(['bar' => 'baz', 'qu' => 'ux'], $session->except(['foo']));\n    }\n\n    public function testReplace()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $session->put('qu', 'ux');\n        $session->replace(['foo' => 'baz']);\n        $this->assertSame('baz', $session->get('foo'));\n        $this->assertSame('ux', $session->get('qu'));\n    }\n\n    public function testRemove()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $pulled = $session->remove('foo');\n        $this->assertFalse($session->has('foo'));\n        $this->assertSame('bar', $pulled);\n    }\n\n    public function testClear()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n\n        $session->flush();\n        $this->assertFalse($session->has('foo'));\n\n        $session->put('foo', 'bar');\n\n        $session->flush();\n        $this->assertFalse($session->has('foo'));\n    }\n\n    public function testIncrement()\n    {\n        $session = $this->getSession();\n\n        $session->put('foo', 5);\n        $foo = $session->increment('foo');\n        $this->assertEquals(6, $foo);\n        $this->assertEquals(6, $session->get('foo'));\n\n        $foo = $session->increment('foo', 4);\n        $this->assertEquals(10, $foo);\n        $this->assertEquals(10, $session->get('foo'));\n\n        $session->increment('bar');\n        $this->assertEquals(1, $session->get('bar'));\n    }\n\n    public function testDecrement()\n    {\n        $session = $this->getSession();\n\n        $session->put('foo', 5);\n        $foo = $session->decrement('foo');\n        $this->assertEquals(4, $foo);\n        $this->assertEquals(4, $session->get('foo'));\n\n        $foo = $session->decrement('foo', 4);\n        $this->assertEquals(0, $foo);\n        $this->assertEquals(0, $session->get('foo'));\n\n        $session->decrement('bar');\n        $this->assertEquals(-1, $session->get('bar'));\n    }\n\n    public function testHasOldInputWithoutKey()\n    {\n        $session = $this->getSession();\n        $session->flash('boom', 'baz');\n        $this->assertFalse($session->hasOldInput());\n\n        $session->flashInput(['foo' => 'bar']);\n        $this->assertTrue($session->hasOldInput());\n    }\n\n    public function testHandlerNeedsRequest()\n    {\n        $session = $this->getSession();\n        $this->assertFalse($session->handlerNeedsRequest());\n        $session->getHandler()->shouldReceive('setRequest')->never();\n\n        $session = new Store('test', m::mock(new CookieSessionHandler(new CookieJar, 60, false)));\n        $this->assertTrue($session->handlerNeedsRequest());\n        $session->getHandler()->shouldReceive('setRequest')->once();\n        $request = new Request;\n        $session->setRequestOnHandler($request);\n    }\n\n    public function testToken()\n    {\n        $session = $this->getSession();\n        $this->assertEquals($session->token(), $session->token());\n    }\n\n    public function testRegenerateToken()\n    {\n        $session = $this->getSession();\n        $token = $session->token();\n        $session->regenerateToken();\n        $this->assertNotEquals($token, $session->token());\n    }\n\n    public function testName()\n    {\n        $session = $this->getSession();\n        $this->assertEquals($session->getName(), $this->getSessionName());\n        $session->setName('foo');\n        $this->assertSame('foo', $session->getName());\n    }\n\n    public function testForget()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $this->assertTrue($session->has('foo'));\n        $session->forget('foo');\n        $this->assertFalse($session->has('foo'));\n\n        $session->put('foo', 'bar');\n        $session->put('bar', 'baz');\n        $session->forget(['foo', 'bar']);\n        $this->assertFalse($session->has('foo'));\n        $this->assertFalse($session->has('bar'));\n    }\n\n    public function testSetPreviousUrl()\n    {\n        $session = $this->getSession();\n        $session->setPreviousUrl('https://example.com/foo/bar');\n\n        $this->assertTrue($session->has('_previous.url'));\n        $this->assertSame('https://example.com/foo/bar', $session->get('_previous.url'));\n\n        $url = $session->previousUrl();\n        $this->assertSame('https://example.com/foo/bar', $url);\n    }\n\n    public function testPasswordConfirmed()\n    {\n        $session = $this->getSession();\n        $this->assertFalse($session->has('auth.password_confirmed_at'));\n        $session->passwordConfirmed();\n        $this->assertTrue($session->has('auth.password_confirmed_at'));\n    }\n\n    public function testKeyPush()\n    {\n        $session = $this->getSession();\n        $session->put('language', ['PHP' => ['Laravel']]);\n        $session->push('language.PHP', 'Symfony');\n\n        $this->assertEquals(['PHP' => ['Laravel', 'Symfony']], $session->get('language'));\n    }\n\n    public function testKeyPull()\n    {\n        $session = $this->getSession();\n        $session->put('name', 'Taylor');\n\n        $this->assertSame('Taylor', $session->pull('name'));\n        $this->assertSame('Taylor Otwell', $session->pull('name', 'Taylor Otwell'));\n        $this->assertNull($session->pull('name'));\n    }\n\n    public function testKeyHas()\n    {\n        $session = $this->getSession();\n        $session->put('first_name', 'Mehdi');\n        $session->put('last_name', 'Rajabi');\n\n        $this->assertTrue($session->has('first_name'));\n        $this->assertTrue($session->has('last_name'));\n        $this->assertTrue($session->has('first_name', 'last_name'));\n        $this->assertTrue($session->has(['first_name', 'last_name']));\n\n        $this->assertFalse($session->has('first_name', 'foo'));\n        $this->assertFalse($session->has('foo', 'bar'));\n    }\n\n    public function testKeyHasAny()\n    {\n        $session = $this->getSession();\n        $session->put('first_name', 'Mahmoud');\n        $session->put('last_name', 'Ramadan');\n\n        $this->assertTrue($session->hasAny('first_name'));\n        $this->assertTrue($session->hasAny('first_name', 'last_name'));\n        $this->assertTrue($session->hasAny(['first_name', 'last_name']));\n        $this->assertTrue($session->hasAny(['first_name', 'middle_name']));\n\n        $this->assertFalse($session->hasAny('middle_name'));\n        $this->assertFalse($session->hasAny('foo', 'bar'));\n        $this->assertFalse($session->hasAny(['foo', 'bar']));\n    }\n\n    public function testKeyExists()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $this->assertTrue($session->exists('foo'));\n        $session->put('baz', null);\n        $session->put('hulk', ['one' => true]);\n        $this->assertFalse($session->has('baz'));\n        $this->assertTrue($session->exists('baz'));\n        $this->assertFalse($session->exists('bogus'));\n        $this->assertTrue($session->exists(['foo', 'baz']));\n        $this->assertFalse($session->exists(['foo', 'baz', 'bogus']));\n        $this->assertTrue($session->exists(['hulk.one']));\n        $this->assertFalse($session->exists(['hulk.two']));\n    }\n\n    public function testKeyMissing()\n    {\n        $session = $this->getSession();\n        $session->put('foo', 'bar');\n        $this->assertFalse($session->missing('foo'));\n        $session->put('baz', null);\n        $session->put('hulk', ['one' => true]);\n        $this->assertFalse($session->has('baz'));\n        $this->assertFalse($session->missing('baz'));\n        $this->assertTrue($session->missing('bogus'));\n        $this->assertFalse($session->missing(['foo', 'baz']));\n        $this->assertTrue($session->missing(['foo', 'baz', 'bogus']));\n        $this->assertFalse($session->missing(['hulk.one']));\n        $this->assertTrue($session->missing(['hulk.two']));\n    }\n\n    public function testBackedEnumKeyPut()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n\n        $this->assertSame('Taylor', $session->get('user'));\n        $this->assertSame('Taylor', $session->get(SessionTestKey::User));\n    }\n\n    public function testBackedEnumKeyGet()\n    {\n        $session = $this->getSession();\n        $session->put('user', 'Taylor');\n\n        $this->assertSame('Taylor', $session->get(SessionTestKey::User));\n        $this->assertSame('default', $session->get(SessionTestKey::Settings, 'default'));\n    }\n\n    public function testBackedEnumKeyHas()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n        $session->put(SessionTestKey::Settings, 'dark-mode');\n\n        $this->assertTrue($session->has(SessionTestKey::User));\n        $this->assertTrue($session->has(SessionTestKey::User, SessionTestKey::Settings));\n        $this->assertTrue($session->has([SessionTestKey::User, SessionTestKey::Settings]));\n        $this->assertFalse($session->has(SessionTestKey::Preference));\n    }\n\n    public function testBackedEnumKeyHasAny()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n        $session->put(SessionTestKey::Settings, 'dark-mode');\n\n        $this->assertTrue($session->hasAny(SessionTestKey::User));\n        $this->assertTrue($session->hasAny('user'));\n        $this->assertTrue($session->hasAny(SessionTestKey::User, SessionTestKey::Preference, 'foo'));\n        $this->assertTrue($session->hasAny([SessionTestKey::User, SessionTestKey::Preference, 'foo']));\n\n        $this->assertFalse($session->hasAny(SessionTestKey::Preference));\n        $this->assertFalse($session->hasAny('preference'));\n        $this->assertFalse($session->hasAny(SessionTestKey::Preference, 'foo'));\n        $this->assertFalse($session->hasAny([SessionTestKey::Preference, 'foo']));\n    }\n\n    public function testBackedEnumKeyExists()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n        $session->put(SessionTestKey::Settings, null);\n\n        $this->assertTrue($session->exists(SessionTestKey::User));\n        $this->assertTrue($session->exists(SessionTestKey::Settings));\n        $this->assertFalse($session->exists(SessionTestKey::Preference));\n\n        $this->assertTrue($session->exists('user'));\n        $this->assertFalse($session->exists('preference'));\n    }\n\n    public function testBackedEnumKeyMissing()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n        $session->put(SessionTestKey::Settings, null);\n\n        $this->assertFalse($session->missing(SessionTestKey::User));\n        $this->assertFalse($session->missing(SessionTestKey::Settings));\n        $this->assertTrue($session->missing(SessionTestKey::Preference));\n\n        $this->assertFalse($session->missing('user'));\n        $this->assertTrue($session->missing('preference'));\n    }\n\n    public function testBackedEnumKeyForget()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n        $this->assertTrue($session->has('user'));\n\n        $session->forget(SessionTestKey::User);\n        $this->assertFalse($session->has('user'));\n\n        $session->put(SessionTestKey::User, 'Taylor');\n        $session->put(SessionTestKey::Settings, 'dark-mode');\n        $session->forget([SessionTestKey::User, SessionTestKey::Settings]);\n        $this->assertFalse($session->has('user'));\n        $this->assertFalse($session->has('settings'));\n    }\n\n    public function testBackedEnumKeyPull()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n\n        $this->assertSame('Taylor', $session->pull(SessionTestKey::User));\n        $this->assertNull($session->pull(SessionTestKey::User));\n        $this->assertSame('default', $session->pull(SessionTestKey::User, 'default'));\n    }\n\n    public function testBackedEnumKeyRemember()\n    {\n        $session = $this->getSession();\n\n        $result = $session->remember(SessionTestKey::User, fn () => 'Taylor');\n\n        $this->assertSame('Taylor', $result);\n        $this->assertSame('Taylor', $session->get('user'));\n        $this->assertSame('Taylor', $session->remember(SessionTestKey::User, fn () => 'Otwell'));\n    }\n\n    public function testBackedEnumKeyPush()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, ['Taylor']);\n        $session->push(SessionTestKey::User, 'Otwell');\n\n        $this->assertSame(['Taylor', 'Otwell'], $session->get('user'));\n    }\n\n    public function testBackedEnumKeyIncrement()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 5);\n\n        $this->assertSame(6, $session->increment(SessionTestKey::User));\n        $this->assertSame(6, $session->get('user'));\n\n        $this->assertSame(10, $session->increment(SessionTestKey::User, 4));\n        $this->assertSame(10, $session->get('user'));\n    }\n\n    public function testBackedEnumKeyDecrement()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 5);\n\n        $this->assertSame(4, $session->decrement(SessionTestKey::User));\n        $this->assertSame(4, $session->get('user'));\n    }\n\n    public function testBackedEnumKeyRemove()\n    {\n        $session = $this->getSession();\n        $session->put(SessionTestKey::User, 'Taylor');\n\n        $this->assertSame('Taylor', $session->remove(SessionTestKey::User));\n        $this->assertFalse($session->has('user'));\n    }\n\n    public function testBackedEnumKeyFlash()\n    {\n        $session = $this->getSession();\n        $session->flash(SessionTestKey::User, 'Taylor');\n        $this->assertTrue($session->has(SessionTestKey::User));\n    }\n\n    public function testBackedEnumKeyNow()\n    {\n        $session = $this->getSession();\n        $session->now(SessionTestKey::User, 'Taylor');\n        $this->assertTrue($session->has(SessionTestKey::User));\n    }\n\n    public function testRememberMethodCallsPutAndReturnsDefault()\n    {\n        $session = $this->getSession();\n        $session->getHandler()->shouldReceive('get')->andReturn(null);\n        $result = $session->remember('foo', function () {\n            return 'bar';\n        });\n        $this->assertSame('bar', $session->get('foo'));\n        $this->assertSame('bar', $result);\n    }\n\n    public function testRememberMethodReturnsPreviousValueIfItAlreadySets()\n    {\n        $session = $this->getSession();\n        $session->put('key', 'foo');\n        $result = $session->remember('key', function () {\n            return 'bar';\n        });\n        $this->assertSame('foo', $session->get('key'));\n        $this->assertSame('foo', $result);\n    }\n\n    public function testValidationErrorsCanBeSerializedAsJson()\n    {\n        $session = $this->getSession('json');\n        $session->getHandler()->shouldReceive('read')->once()->andReturn(serialize([]));\n        $session->start();\n        $session->put('errors', $errorBag = new ViewErrorBag);\n        $messageBag = new MessageBag([\n            'first_name' => [\n                'Your first name is required',\n                'Your first name must be at least 1 character',\n            ],\n        ]);\n        $messageBag->setFormat('<p>:message</p>');\n        $errorBag->put('default', $messageBag);\n\n        $session->getHandler()->shouldReceive('write')->once()->with(\n            $this->getSessionId(),\n            json_encode([\n                '_token' => $session->token(),\n                'errors' => [\n                    'default' => [\n                        'format' => '<p>:message</p>',\n                        'messages' => [\n                            'first_name' => [\n                                'Your first name is required',\n                                'Your first name must be at least 1 character',\n                            ],\n                        ],\n                    ],\n                ],\n                '_flash' => [\n                    'old' => [],\n                    'new' => [],\n                ],\n            ])\n        );\n        $session->save();\n\n        $this->assertFalse($session->isStarted());\n    }\n\n    public function testValidationErrorsCanBeReadAsJson()\n    {\n        $session = $this->getSession('json');\n        $session->getHandler()->shouldReceive('read')->once()->with($this->getSessionId())->andReturn(json_encode([\n            'errors' => [\n                'default' => [\n                    'format' => '<p>:message</p>',\n                    'messages' => [\n                        'first_name' => [\n                            'Your first name is required',\n                            'Your first name must be at least 1 character',\n                        ],\n                    ],\n                ],\n            ],\n        ]));\n        $session->start();\n\n        $errors = $session->get('errors');\n\n        $this->assertInstanceOf(ViewErrorBag::class, $errors);\n        $this->assertInstanceOf(MessageBag::class, $errors->getBags()['default']);\n        $this->assertEquals('<p>:message</p>', $errors->getBags()['default']->getFormat());\n        $this->assertEquals(['first_name' => [\n            'Your first name is required',\n            'Your first name must be at least 1 character',\n        ]], $errors->getBags()['default']->getMessages());\n    }\n\n    public function testItIsMacroable()\n    {\n        $this->getSession()->macro('foo', function () {\n            return 'macroable';\n        });\n\n        $this->assertSame('macroable', $this->getSession()->foo());\n    }\n\n    public function getSession($serialization = 'php')\n    {\n        $reflection = new ReflectionClass(Store::class);\n\n        return $reflection->newInstanceArgs($this->getMocks($serialization));\n    }\n\n    public function getMocks($serialization = 'json')\n    {\n        return [\n            $this->getSessionName(),\n            m::mock(SessionHandlerInterface::class),\n            $this->getSessionId(),\n            $serialization,\n        ];\n    }\n\n    public function getSessionId()\n    {\n        return 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';\n    }\n\n    public function getSessionName()\n    {\n        return 'name';\n    }\n}\n\nenum SessionTestKey: string\n{\n    case User = 'user';\n    case Settings = 'settings';\n    case Preference = 'preference';\n}\n"
  },
  {
    "path": "tests/Support/Common.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayIterator;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse IteratorAggregate;\nuse JsonSerializable;\nuse Traversable;\n\nclass TestArrayableObject implements Arrayable\n{\n    public function toArray()\n    {\n        return ['foo' => 'bar'];\n    }\n}\n\nclass TestJsonableObject implements Jsonable\n{\n    public function toJson($options = 0)\n    {\n        return '{\"foo\":\"bar\"}';\n    }\n}\n\nclass TestJsonSerializeObject implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return ['foo' => 'bar'];\n    }\n}\n\nclass TestJsonSerializeWithScalarValueObject implements JsonSerializable\n{\n    public function jsonSerialize(): string\n    {\n        return 'foo';\n    }\n}\n\nclass TestTraversableAndJsonSerializableObject implements IteratorAggregate, JsonSerializable\n{\n    public $items;\n\n    public function __construct($items = [])\n    {\n        $this->items = $items;\n    }\n\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->items);\n    }\n\n    public function jsonSerialize(): array\n    {\n        return json_decode(json_encode($this->items), true);\n    }\n}\n"
  },
  {
    "path": "tests/Support/Concerns/CountsEnumerations.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Concerns;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\n\ntrait CountsEnumerations\n{\n    protected function makeGeneratorFunctionWithRecorder($numbers = 10)\n    {\n        $recorder = new Collection();\n\n        $generatorFunction = function () use ($numbers, $recorder) {\n            for ($i = 1; $i <= $numbers; $i++) {\n                $recorder->push($i);\n\n                yield $i;\n            }\n        };\n\n        return [$generatorFunction, $recorder];\n    }\n\n    protected function assertDoesNotEnumerate(callable $executor)\n    {\n        $this->assertEnumerates(0, $executor);\n    }\n\n    protected function assertDoesNotEnumerateCollection(\n        LazyCollection $collection,\n        callable $executor\n    ) {\n        $this->assertEnumeratesCollection($collection, 0, $executor);\n    }\n\n    protected function assertEnumerates($count, callable $executor)\n    {\n        $this->assertEnumeratesCollection(\n            LazyCollection::times(100),\n            $count,\n            $executor\n        );\n    }\n\n    protected function assertEnumeratesCollection(\n        LazyCollection $collection,\n        $count,\n        callable $executor\n    ) {\n        $enumerated = 0;\n\n        $data = $this->countEnumerations($collection, $enumerated);\n\n        $executor($data);\n\n        $this->assertEnumerations($count, $enumerated);\n    }\n\n    protected function assertEnumeratesOnce(callable $executor)\n    {\n        $this->assertEnumeratesCollectionOnce(LazyCollection::times(10), $executor);\n    }\n\n    protected function assertEnumeratesCollectionOnce(\n        LazyCollection $collection,\n        callable $executor\n    ) {\n        $enumerated = 0;\n        $count = $collection->count();\n        $collection = $this->countEnumerations($collection, $enumerated);\n\n        $executor($collection);\n\n        $this->assertEquals(\n            $count,\n            $enumerated,\n            $count > $enumerated ? 'Failed to enumerate in full.' : 'Enumerated more than once.'\n        );\n    }\n\n    protected function assertEnumerations($expected, $actual)\n    {\n        $this->assertEquals(\n            $expected,\n            $actual,\n            \"Failed asserting that {$actual} items that were enumerated matches expected {$expected}.\"\n        );\n    }\n\n    protected function countEnumerations(LazyCollection $collection, &$count)\n    {\n        return $collection->tapEach(function () use (&$count) {\n            $count++;\n        });\n    }\n}\n"
  },
  {
    "path": "tests/Support/ConfigurationUrlParserTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\ConfigurationUrlParser;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConfigurationUrlParserTest extends TestCase\n{\n    #[DataProvider('databaseUrls')]\n    public function testDatabaseUrlsAreParsed($config, $expectedOutput)\n    {\n        $this->assertEquals($expectedOutput, (new ConfigurationUrlParser)->parseConfiguration($config));\n    }\n\n    public function testDriversAliases()\n    {\n        $this->assertEquals([\n            'mssql' => 'sqlsrv',\n            'mysql2' => 'mysql',\n            'postgres' => 'pgsql',\n            'postgresql' => 'pgsql',\n            'sqlite3' => 'sqlite',\n            'redis' => 'tcp',\n            'rediss' => 'tls',\n        ], ConfigurationUrlParser::getDriverAliases());\n\n        ConfigurationUrlParser::addDriverAlias('some-particular-alias', 'mysql');\n\n        $this->assertEquals([\n            'mssql' => 'sqlsrv',\n            'mysql2' => 'mysql',\n            'postgres' => 'pgsql',\n            'postgresql' => 'pgsql',\n            'sqlite3' => 'sqlite',\n            'redis' => 'tcp',\n            'rediss' => 'tls',\n            'some-particular-alias' => 'mysql',\n        ], ConfigurationUrlParser::getDriverAliases());\n\n        $this->assertEquals([\n            'driver' => 'mysql',\n        ], (new ConfigurationUrlParser)->parseConfiguration('some-particular-alias://null'));\n    }\n\n    public static function databaseUrls()\n    {\n        return [\n            'simple URL' => [\n                'mysql://foo:bar@localhost/baz',\n                [\n                    'driver' => 'mysql',\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'host' => 'localhost',\n                    'database' => 'baz',\n                ],\n            ],\n            'simple URL with port' => [\n                'mysql://foo:bar@localhost:134/baz',\n                [\n                    'driver' => 'mysql',\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'host' => 'localhost',\n                    'port' => 134,\n                    'database' => 'baz',\n                ],\n            ],\n            'sqlite relative URL with host' => [\n                'sqlite://localhost/foo/database.sqlite',\n                [\n                    'database' => 'foo/database.sqlite',\n                    'driver' => 'sqlite',\n                    'host' => 'localhost',\n                ],\n            ],\n            'sqlite absolute URL with host' => [\n                'sqlite://localhost//tmp/database.sqlite',\n                [\n                    'database' => '/tmp/database.sqlite',\n                    'driver' => 'sqlite',\n                    'host' => 'localhost',\n                ],\n            ],\n            'sqlite relative URL without host' => [\n                'sqlite:///foo/database.sqlite',\n                [\n                    'database' => 'foo/database.sqlite',\n                    'driver' => 'sqlite',\n                ],\n            ],\n            'sqlite absolute URL without host' => [\n                'sqlite:////tmp/database.sqlite',\n                [\n                    'database' => '/tmp/database.sqlite',\n                    'driver' => 'sqlite',\n                ],\n            ],\n            'sqlite memory' => [\n                'sqlite:///:memory:',\n                [\n                    'database' => ':memory:',\n                    'driver' => 'sqlite',\n                ],\n            ],\n            'params parsed from URL override individual params' => [\n                [\n                    'url' => 'mysql://foo:bar@localhost/baz',\n                    'password' => 'lulz',\n                    'driver' => 'sqlite',\n                ],\n                [\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'host' => 'localhost',\n                    'database' => 'baz',\n                    'driver' => 'mysql',\n                ],\n            ],\n            'params not parsed from URL but individual params are preserved' => [\n                [\n                    'url' => 'mysql://foo:bar@localhost/baz',\n                    'port' => 134,\n                ],\n                [\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'host' => 'localhost',\n                    'port' => 134,\n                    'database' => 'baz',\n                    'driver' => 'mysql',\n                ],\n            ],\n            'query params from URL are used as extra params' => [\n                'mysql://foo:bar@localhost/database?charset=UTF-8',\n                [\n                    'driver' => 'mysql',\n                    'database' => 'database',\n                    'host' => 'localhost',\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'charset' => 'UTF-8',\n                ],\n            ],\n            'simple URL with driver set apart' => [\n                [\n                    'url' => '//foo:bar@localhost/baz',\n                    'driver' => 'sqlsrv',\n                ],\n                [\n                    'username' => 'foo',\n                    'password' => 'bar',\n                    'host' => 'localhost',\n                    'database' => 'baz',\n                    'driver' => 'sqlsrv',\n                ],\n            ],\n            'simple URL with percent encoding' => [\n                'mysql://foo%3A:bar%2F@localhost/baz+baz%40',\n                [\n                    'username' => 'foo:',\n                    'password' => 'bar/',\n                    'host' => 'localhost',\n                    'database' => 'baz+baz@',\n                    'driver' => 'mysql',\n                ],\n            ],\n            'simple URL with percent sign in password' => [\n                'mysql://foo:bar%25bar@localhost/baz',\n                [\n                    'username' => 'foo',\n                    'password' => 'bar%bar',\n                    'host' => 'localhost',\n                    'database' => 'baz',\n                    'driver' => 'mysql',\n                ],\n            ],\n            'simple URL with percent encoding in query' => [\n                'mysql://foo:bar%25bar@localhost/baz?timezone=%2B00%3A00',\n                [\n                    'username' => 'foo',\n                    'password' => 'bar%bar',\n                    'host' => 'localhost',\n                    'database' => 'baz',\n                    'driver' => 'mysql',\n                    'timezone' => '+00:00',\n                ],\n            ],\n            'URL with mssql alias driver' => [\n                'mssql://null',\n                [\n                    'driver' => 'sqlsrv',\n                ],\n            ],\n            'URL with sqlsrv alias driver' => [\n                'sqlsrv://null',\n                [\n                    'driver' => 'sqlsrv',\n                ],\n            ],\n            'URL with mysql alias driver' => [\n                'mysql://null',\n                [\n                    'driver' => 'mysql',\n                ],\n            ],\n            'URL with mysql2 alias driver' => [\n                'mysql2://null',\n                [\n                    'driver' => 'mysql',\n                ],\n            ],\n            'URL with postgres alias driver' => [\n                'postgres://null',\n                [\n                    'driver' => 'pgsql',\n                ],\n            ],\n            'URL with postgresql alias driver' => [\n                'postgresql://null',\n                [\n                    'driver' => 'pgsql',\n                ],\n            ],\n            'URL with pgsql alias driver' => [\n                'pgsql://null',\n                [\n                    'driver' => 'pgsql',\n                ],\n            ],\n            'URL with sqlite alias driver' => [\n                'sqlite://null',\n                [\n                    'driver' => 'sqlite',\n                ],\n            ],\n            'URL with sqlite3 alias driver' => [\n                'sqlite3://null',\n                [\n                    'driver' => 'sqlite',\n                ],\n            ],\n\n            'URL with unknown driver' => [\n                'foo://null',\n                [\n                    'driver' => 'foo',\n                ],\n            ],\n            'Sqlite with foreign_key_constraints' => [\n                'sqlite:////absolute/path/to/database.sqlite?foreign_key_constraints=true',\n                [\n                    'driver' => 'sqlite',\n                    'database' => '/absolute/path/to/database.sqlite',\n                    'foreign_key_constraints' => true,\n                ],\n            ],\n            'Sqlite with busy_timeout' => [\n                'sqlite:////absolute/path/to/database.sqlite?busy_timeout=5000',\n                [\n                    'driver' => 'sqlite',\n                    'database' => '/absolute/path/to/database.sqlite',\n                    'busy_timeout' => 5000,\n                ],\n            ],\n            'Sqlite with journal_mode' => [\n                'sqlite:////absolute/path/to/database.sqlite?journal_mode=WAL',\n                [\n                    'driver' => 'sqlite',\n                    'database' => '/absolute/path/to/database.sqlite',\n                    'journal_mode' => 'WAL',\n                ],\n            ],\n            'Sqlite with synchronous' => [\n                'sqlite:////absolute/path/to/database.sqlite?synchronous=NORMAL',\n                [\n                    'driver' => 'sqlite',\n                    'database' => '/absolute/path/to/database.sqlite',\n                    'synchronous' => 'NORMAL',\n                ],\n            ],\n\n            'Most complex example with read and write subarrays all in string' => [\n                'mysql://root:@null/database?read[host][]=192.168.1.1&write[host][]=196.168.1.2&sticky=true&charset=utf8mb4&collation=utf8mb4_unicode_ci&prefix=',\n                [\n                    'read' => [\n                        'host' => ['192.168.1.1'],\n                    ],\n                    'write' => [\n                        'host' => ['196.168.1.2'],\n                    ],\n                    'sticky' => true,\n                    'driver' => 'mysql',\n                    'database' => 'database',\n                    'username' => 'root',\n                    'password' => '',\n                    'charset' => 'utf8mb4',\n                    'collation' => 'utf8mb4_unicode_ci',\n                    'prefix' => '',\n                ],\n            ],\n\n            'Full example from doc that prove that there isn\\'t any Breaking Change' => [\n                [\n                    'driver' => 'mysql',\n                    'host' => '127.0.0.1',\n                    'port' => '3306',\n                    'database' => 'forge',\n                    'username' => 'forge',\n                    'password' => '',\n                    'unix_socket' => '',\n                    'charset' => 'utf8mb4',\n                    'collation' => 'utf8mb4_unicode_ci',\n                    'prefix' => '',\n                    'prefix_indexes' => true,\n                    'strict' => true,\n                    'engine' => null,\n                    'options' => ['foo' => 'bar'],\n                ],\n                [\n                    'driver' => 'mysql',\n                    'host' => '127.0.0.1',\n                    'port' => '3306',\n                    'database' => 'forge',\n                    'username' => 'forge',\n                    'password' => '',\n                    'unix_socket' => '',\n                    'charset' => 'utf8mb4',\n                    'collation' => 'utf8mb4_unicode_ci',\n                    'prefix' => '',\n                    'prefix_indexes' => true,\n                    'strict' => true,\n                    'engine' => null,\n                    'options' => ['foo' => 'bar'],\n                ],\n            ],\n\n            'Full example from doc with url overwriting parameters' => [\n                [\n                    'url' => 'mysql://root:pass@db/local',\n                    'driver' => 'mysql',\n                    'host' => '127.0.0.1',\n                    'port' => '3306',\n                    'database' => 'forge',\n                    'username' => 'forge',\n                    'password' => '',\n                    'unix_socket' => '',\n                    'charset' => 'utf8mb4',\n                    'collation' => 'utf8mb4_unicode_ci',\n                    'prefix' => '',\n                    'prefix_indexes' => true,\n                    'strict' => true,\n                    'engine' => null,\n                    'options' => ['foo' => 'bar'],\n                ],\n                [\n                    'driver' => 'mysql',\n                    'host' => 'db',\n                    'port' => '3306',\n                    'database' => 'local',\n                    'username' => 'root',\n                    'password' => 'pass',\n                    'unix_socket' => '',\n                    'charset' => 'utf8mb4',\n                    'collation' => 'utf8mb4_unicode_ci',\n                    'prefix' => '',\n                    'prefix_indexes' => true,\n                    'strict' => true,\n                    'engine' => null,\n                    'options' => ['foo' => 'bar'],\n                ],\n            ],\n            'Redis Example' => [\n                [\n                    // Coming directly from Heroku documentation\n                    'url' => 'redis://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111',\n                    'host' => '127.0.0.1',\n                    'password' => null,\n                    'port' => 6379,\n                    'database' => 0,\n                ],\n                [\n                    'driver' => 'tcp',\n                    'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',\n                    'port' => 111,\n                    'database' => 0,\n                    'username' => 'h',\n                    'password' => 'asdfqwer1234asdf',\n                ],\n            ],\n            'Redis example where URL ends with \"/\" and database is not present' => [\n                [\n                    'url' => 'redis://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111/',\n                    'host' => '127.0.0.1',\n                    'password' => null,\n                    'port' => 6379,\n                    'database' => 2,\n                ],\n                [\n                    'driver' => 'tcp',\n                    'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',\n                    'port' => 111,\n                    'database' => 2,\n                    'username' => 'h',\n                    'password' => 'asdfqwer1234asdf',\n                ],\n            ],\n            'Redis Example with tls scheme' => [\n                [\n                    'url' => 'tls://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111',\n                    'host' => '127.0.0.1',\n                    'password' => null,\n                    'port' => 6379,\n                    'database' => 0,\n                ],\n                [\n                    'driver' => 'tls',\n                    'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',\n                    'port' => 111,\n                    'database' => 0,\n                    'username' => 'h',\n                    'password' => 'asdfqwer1234asdf',\n                ],\n            ],\n            'Redis Example with rediss scheme' => [\n                [\n                    'url' => 'rediss://h:asdfqwer1234asdf@ec2-111-1-1-1.compute-1.amazonaws.com:111',\n                    'host' => '127.0.0.1',\n                    'password' => null,\n                    'port' => 6379,\n                    'database' => 0,\n                ],\n                [\n                    'driver' => 'tls',\n                    'host' => 'ec2-111-1-1-1.compute-1.amazonaws.com',\n                    'port' => 111,\n                    'database' => 0,\n                    'username' => 'h',\n                    'password' => 'asdfqwer1234asdf',\n                ],\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Support/DateFacadeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Carbon\\CarbonImmutable;\nuse Carbon\\Factory;\nuse DateTime;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\DateFactory;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Tests\\Support\\Fixtures\\CustomDateClass;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass DateFacadeTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        DateFactory::use(Carbon::class);\n\n        parent::tearDown();\n    }\n\n    protected static function assertBetweenStartAndNow($start, $actual)\n    {\n        static::assertThat(\n            $actual,\n            static::logicalAnd(\n                static::greaterThanOrEqual($start),\n                static::lessThanOrEqual(Carbon::now()->getTimestamp())\n            )\n        );\n    }\n\n    public function testUseClosure()\n    {\n        $start = Carbon::now()->getTimestamp();\n        $this->assertSame(Carbon::class, get_class(Date::now()));\n        $this->assertBetweenStartAndNow($start, Date::now()->getTimestamp());\n        DateFactory::use(function (Carbon $date) {\n            return new DateTime($date->format('Y-m-d H:i:s.u'), $date->getTimezone());\n        });\n        $start = Carbon::now()->getTimestamp();\n        $this->assertSame(DateTime::class, get_class(Date::now()));\n        $this->assertBetweenStartAndNow($start, Date::now()->getTimestamp());\n    }\n\n    public function testUseClassName()\n    {\n        $start = Carbon::now()->getTimestamp();\n        $this->assertSame(Carbon::class, get_class(Date::now()));\n        $this->assertBetweenStartAndNow($start, Date::now()->getTimestamp());\n        DateFactory::use(DateTime::class);\n        $start = Carbon::now()->getTimestamp();\n        $this->assertSame(DateTime::class, get_class(Date::now()));\n        $this->assertBetweenStartAndNow($start, Date::now()->getTimestamp());\n    }\n\n    public function testCarbonImmutable()\n    {\n        DateFactory::use(CarbonImmutable::class);\n        $this->assertSame(CarbonImmutable::class, get_class(Date::now()));\n        DateFactory::use(Carbon::class);\n        $this->assertSame(Carbon::class, get_class(Date::now()));\n        DateFactory::use(function (Carbon $date) {\n            return $date->toImmutable();\n        });\n        $this->assertSame(CarbonImmutable::class, get_class(Date::now()));\n        DateFactory::use(function ($date) {\n            return $date;\n        });\n        $this->assertSame(Carbon::class, get_class(Date::now()));\n\n        DateFactory::use(new Factory([\n            'locale' => 'fr',\n        ]));\n        $this->assertSame('fr', Date::now()->locale);\n        DateFactory::use(Carbon::class);\n        $this->assertSame('en', Date::now()->locale);\n        DateFactory::use(CustomDateClass::class);\n        $this->assertInstanceOf(CustomDateClass::class, Date::now());\n        $this->assertInstanceOf(Carbon::class, Date::now()->getOriginal());\n        DateFactory::use(Carbon::class);\n    }\n\n    public function testUseInvalidHandler()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        DateFactory::use(42);\n    }\n\n    public function testMacro()\n    {\n        Date::macro('returnNonDate', function () {\n            return 'string';\n        });\n\n        $this->assertSame('string', Date::returnNonDate());\n    }\n}\n"
  },
  {
    "path": "tests/Support/Enums.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nenum TestEnum\n{\n    case A;\n}\n\nenum TestBackedEnum: int\n{\n    case A = 1;\n    case B = 2;\n}\n\nenum TestStringBackedEnum: string\n{\n    case A = 'A';\n    case B = 'B';\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/ClassesWithAttributes.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Fixtures;\n\nuse Attribute;\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass UnusedAttr\n{\n}\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass ParentOnlyAttr\n{\n}\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass StrAttr\n{\n    public function __construct(public string $string)\n    {\n    }\n}\n\n#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]\nclass NumAttr\n{\n    public function __construct(public int $number)\n    {\n    }\n}\n\n#[StrAttr('lazy'), StrAttr('dog'), NumAttr(2), NumAttr(3), ParentOnlyAttr]\nclass ParentClass\n{\n}\n\n#[StrAttr('quick'), StrAttr('brown'), StrAttr('fox'), NumAttr(7)]\nclass ChildClass extends ParentClass\n{\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/CustomDateClass.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Fixtures;\n\nclass CustomDateClass\n{\n    protected $original;\n\n    public function __construct($original)\n    {\n        $this->original = $original;\n    }\n\n    public static function instance($original)\n    {\n        return new static($original);\n    }\n\n    public function getOriginal()\n    {\n        return $this->original;\n    }\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/IntBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Fixtures;\n\nenum IntBackedEnum: int\n{\n    case ROLE_ADMIN = 1;\n    case TWO = 2;\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/StringBackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Fixtures;\n\nenum StringBackedEnum: string\n{\n    case ADMIN_LABEL = 'I am \\'admin\\'';\n    case HELLO_WORLD = 'Hello world';\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/StringableObjectStub.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support\\Fixtures;\n\nclass StringableObjectStub\n{\n    private $value;\n\n    public function __construct($value)\n    {\n        $this->value = $value;\n    }\n\n    public function __toString()\n    {\n        return $this->value;\n    }\n}\n"
  },
  {
    "path": "tests/Support/Fixtures/UnionTypesClosure.php",
    "content": "<?php\n\nuse Illuminate\\Tests\\Support\\AnotherExampleParameter;\nuse Illuminate\\Tests\\Support\\ExampleParameter;\n\nreturn function (ExampleParameter|AnotherExampleParameter $a, $b) {\n    //\n};\n"
  },
  {
    "path": "tests/Support/ForwardsCallsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse BadMethodCallException;\nuse Error;\nuse Illuminate\\Support\\Traits\\ForwardsCalls;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ForwardsCallsTest extends TestCase\n{\n    public function testForwardsCalls()\n    {\n        $results = (new ForwardsCallsOne)->forwardedTwo('foo', 'bar');\n\n        $this->assertEquals(['foo', 'bar'], $results);\n    }\n\n    public function testNestedForwardCalls()\n    {\n        $results = (new ForwardsCallsOne)->forwardedBase('foo', 'bar');\n\n        $this->assertEquals(['foo', 'bar'], $results);\n    }\n\n    public function testMissingForwardedCallThrowsCorrectError()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Tests\\Support\\ForwardsCallsOne::missingMethod()');\n\n        (new ForwardsCallsOne)->missingMethod('foo', 'bar');\n    }\n\n    public function testMissingAlphanumericForwardedCallThrowsCorrectError()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Tests\\Support\\ForwardsCallsOne::this1_shouldWork_too()');\n\n        (new ForwardsCallsOne)->this1_shouldWork_too('foo', 'bar');\n    }\n\n    public function testNonForwardedErrorIsNotTamperedWith()\n    {\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Tests\\Support\\ForwardsCallsBase::missingMethod()');\n\n        (new ForwardsCallsOne)->baseError('foo', 'bar');\n    }\n\n    public function testThrowBadMethodCallException()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('Call to undefined method Illuminate\\Tests\\Support\\ForwardsCallsOne::test()');\n\n        (new ForwardsCallsOne)->throwTestException('test');\n    }\n}\n\nclass ForwardsCallsOne\n{\n    use ForwardsCalls;\n\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo(new ForwardsCallsTwo, $method, $parameters);\n    }\n\n    public function throwTestException($method)\n    {\n        static::throwBadMethodCallException($method);\n    }\n}\n\nclass ForwardsCallsTwo\n{\n    use ForwardsCalls;\n\n    public function __call($method, $parameters)\n    {\n        return $this->forwardCallTo(new ForwardsCallsBase, $method, $parameters);\n    }\n\n    public function forwardedTwo(...$parameters)\n    {\n        return $parameters;\n    }\n}\n\nclass ForwardsCallsBase\n{\n    public function forwardedBase(...$parameters)\n    {\n        return $parameters;\n    }\n\n    public function baseError()\n    {\n        return $this->missingMethod();\n    }\n}\n"
  },
  {
    "path": "tests/Support/HigherOrderProxyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\HigherOrderCollectionProxy;\nuse Illuminate\\Support\\HigherOrderTapProxy;\nuse PHPUnit\\Framework\\TestCase;\n\nclass HigherOrderProxyTest extends TestCase\n{\n    public function test_get_proxies_property_access_to_items()\n    {\n        $items = new Collection([\n            (object) ['name' => 'Alice'],\n            (object) ['name' => 'Bob'],\n        ]);\n\n        $proxy = new HigherOrderCollectionProxy($items, 'pluck');\n\n        // The proxied method returns a Collection instance; assert type and values\n        $this->assertInstanceOf(Collection::class, $proxy->name);\n        $this->assertEquals(['Alice', 'Bob'], $proxy->name->all());\n    }\n\n    public function test_call_proxies_method_call_to_items()\n    {\n        $items = new Collection([\n            new class\n            {\n                public function shout($s)\n                {\n                    return strtoupper($s);\n                }\n            },\n            new class\n            {\n                public function shout($s)\n                {\n                    return strtoupper($s).'!';\n                }\n            },\n        ]);\n\n        $proxy = new HigherOrderCollectionProxy($items, 'map');\n\n        $result = $proxy->shout('hey');\n\n        $this->assertEquals(['HEY', 'HEY!'], $result->all());\n    }\n\n    public function test_call_forwards_and_returns_target()\n    {\n        $target = new class\n        {\n            public $count = 0;\n\n            public function increment($by = 1)\n            {\n                $this->count += $by;\n            }\n        };\n\n        $proxy = new HigherOrderTapProxy($target);\n\n        $result = $proxy->increment(3);\n\n        $this->assertSame(3, $target->count);\n        $this->assertSame($target, $result);\n    }\n}\n"
  },
  {
    "path": "tests/Support/LotteryTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Lottery;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass LotteryTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Lottery::determineResultNormally();\n\n        parent::tearDown();\n    }\n\n    public function testItCanWin()\n    {\n        $wins = false;\n\n        Lottery::odds(1, 1)\n            ->winner(function () use (&$wins) {\n                $wins = true;\n            })->choose();\n\n        $this->assertTrue($wins);\n    }\n\n    public function testItCanLose()\n    {\n        $wins = false;\n        $loses = false;\n\n        Lottery::odds(0, 1)\n            ->winner(function () use (&$wins) {\n                $wins = true;\n            })->loser(function () use (&$loses) {\n                $loses = true;\n            })->choose();\n\n        $this->assertFalse($wins);\n        $this->assertTrue($loses);\n    }\n\n    public function testItCanReturnValues()\n    {\n        $win = Lottery::odds(1, 1)->winner(fn () => 'win')->choose();\n        $this->assertSame('win', $win);\n\n        $lose = Lottery::odds(0, 1)->loser(fn () => 'lose')->choose();\n        $this->assertSame('lose', $lose);\n    }\n\n    public function testItCanChooseSeveralTimes()\n    {\n        $results = Lottery::odds(1, 1)->winner(fn () => 'win')->choose(2);\n        $this->assertSame(['win', 'win'], $results);\n\n        $results = Lottery::odds(0, 1)->loser(fn () => 'lose')->choose(2);\n        $this->assertSame(['lose', 'lose'], $results);\n    }\n\n    public function testItCanBePassedAsCallable()\n    {\n        // Example...\n        // DB::whenQueryingForLongerThan(Interval::seconds(5), Lottery::odds(1, 5)->winner(function ($connection) {\n        //     Alert the team\n        // }));\n        $result = (function (callable $callable) {\n            return $callable('winner-chicken', '-dinner');\n        })(Lottery::odds(1, 1)->winner(fn ($first, $second) => 'winner-'.$first.$second));\n\n        $this->assertSame('winner-winner-chicken-dinner', $result);\n    }\n\n    public function testWithoutSpecifiedClosuresBooleansAreReturned()\n    {\n        $win = Lottery::odds(1, 1)->choose();\n        $this->assertTrue($win);\n\n        $lose = Lottery::odds(0, 1)->choose();\n        $this->assertFalse($lose);\n    }\n\n    public function testItCanForceWinningResultInTests()\n    {\n        $result = null;\n        Lottery::alwaysWin(function () use (&$result) {\n            $result = Lottery::odds(1, 2)->winner(fn () => 'winner')->choose(10);\n        });\n\n        $this->assertSame([\n            'winner', 'winner', 'winner', 'winner', 'winner',\n            'winner', 'winner', 'winner', 'winner', 'winner',\n        ], $result);\n    }\n\n    public function testItCanForceLosingResultInTests()\n    {\n        $result = null;\n        Lottery::alwaysLose(function () use (&$result) {\n            $result = Lottery::odds(1, 2)->loser(fn () => 'loser')->choose(10);\n        });\n\n        $this->assertSame([\n            'loser', 'loser', 'loser', 'loser', 'loser',\n            'loser', 'loser', 'loser', 'loser', 'loser',\n        ], $result);\n    }\n\n    public function testItCanForceTheResultViaSequence()\n    {\n        $result = null;\n        Lottery::forceResultWithSequence([\n            true, false, true, false, true,\n            false, true, false, true, false,\n        ]);\n\n        $result = Lottery::odds(1, 100)->winner(fn () => 'winner')->loser(fn () => 'loser')->choose(10);\n\n        $this->assertSame([\n            'winner', 'loser', 'winner', 'loser', 'winner',\n            'loser', 'winner', 'loser', 'winner', 'loser',\n        ], $result);\n    }\n\n    public function testItCanHandleMissingSequenceItems()\n    {\n        $result = null;\n        Lottery::forceResultWithSequence([\n            0 => true,\n            1 => true,\n            // 2 => ...\n            3 => true,\n        ], fn () => throw new RuntimeException('Missing key in sequence.'));\n\n        $result = Lottery::odds(1, 10000)->winner(fn () => 'winner')->loser(fn () => 'loser')->choose();\n        $this->assertSame('winner', $result);\n\n        $result = Lottery::odds(1, 10000)->winner(fn () => 'winner')->loser(fn () => 'loser')->choose();\n        $this->assertSame('winner', $result);\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Missing key in sequence.');\n        Lottery::odds(1, 10000)->winner(fn () => 'winner')->loser(fn () => 'loser')->choose();\n    }\n\n    public function testItThrowsForFloatsOverOne()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Float must not be greater than 1.');\n\n        new Lottery(1.1);\n    }\n\n    public function testItThrowsForOutOfLessThanOne()\n    {\n        $this->expectException(RuntimeException::class);\n\n        new Lottery(1, 0);\n    }\n\n    public function testItCanWinWithFloat()\n    {\n        $wins = false;\n\n        Lottery::odds(1.0)\n            ->winner(function () use (&$wins) {\n                $wins = true;\n            })->choose();\n\n        $this->assertTrue($wins);\n    }\n\n    public function testItCanLoseWithFloat()\n    {\n        $wins = false;\n        $loses = false;\n\n        Lottery::odds(0.0)\n            ->winner(function () use (&$wins) {\n                $wins = true;\n            })->loser(function () use (&$loses) {\n                $loses = true;\n            })->choose();\n\n        $this->assertFalse($wins);\n        $this->assertTrue($loses);\n    }\n}\n"
  },
  {
    "path": "tests/Support/OnceTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Once;\nuse PHPUnit\\Framework\\TestCase;\n\nclass OnceTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Once::flush();\n        Once::enable();\n\n        parent::tearDown();\n    }\n\n    public function testResultMemoization()\n    {\n        $instance = new class\n        {\n            public function rand()\n            {\n                return once(fn () => rand(1, PHP_INT_MAX));\n            }\n        };\n\n        $first = $instance->rand();\n        $second = $instance->rand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testCallableIsCalledOnce()\n    {\n        $instance = new class\n        {\n            public int $count = 0;\n\n            public function increment()\n            {\n                return once(fn () => ++$this->count);\n            }\n        };\n\n        $first = $instance->increment();\n        $second = $instance->increment();\n\n        $this->assertSame(1, $first);\n        $this->assertSame(1, $second);\n        $this->assertSame(1, $instance->count);\n    }\n\n    public function testFlush()\n    {\n        $instance = new MyClass();\n\n        $first = $instance->rand();\n\n        Once::flush();\n\n        $second = $instance->rand();\n\n        $this->assertNotSame($first, $second);\n\n        Once::disable();\n        Once::flush();\n\n        $first = $instance->rand();\n        $second = $instance->rand();\n\n        $this->assertNotSame($first, $second);\n    }\n\n    public function testNotMemoizedWhenObjectIsGarbageCollected()\n    {\n        $instance = new MyClass();\n\n        $first = $instance->rand();\n        unset($instance);\n        gc_collect_cycles();\n        $instance = new MyClass();\n        $second = $instance->rand();\n\n        $this->assertNotSame($first, $second);\n    }\n\n    public function testIsNotMemoizedWhenCallableUsesChanges()\n    {\n        $instance = new class()\n        {\n            public function rand(string $letter)\n            {\n                return once(function () use ($letter) {\n                    return $letter.rand(1, 10000000);\n                });\n            }\n        };\n\n        $first = $instance->rand('a');\n        $second = $instance->rand('b');\n\n        $this->assertNotSame($first, $second);\n\n        $first = $instance->rand('a');\n        $second = $instance->rand('a');\n\n        $this->assertSame($first, $second);\n\n        $results = [];\n        $letter = 'a';\n\n        a:\n        $results[] = once(fn () => $letter.rand(1, 10000000));\n\n        if (count($results) < 2) {\n            goto a;\n        }\n\n        $this->assertSame($results[0], $results[1]);\n    }\n\n    public function testUsageOfThis()\n    {\n        $instance = new MyClass();\n\n        $first = $instance->callRand();\n        $second = $instance->callRand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testInvokables()\n    {\n        $invokable = new class\n        {\n            public static $count = 0;\n\n            public function __invoke()\n            {\n                return static::$count = static::$count + 1;\n            }\n        };\n\n        $instance = new class($invokable)\n        {\n            public function __construct(protected $invokable)\n            {\n            }\n\n            public function call()\n            {\n                return once($this->invokable);\n            }\n        };\n\n        $first = $instance->call();\n        $second = $instance->call();\n        $third = $instance->call();\n\n        $this->assertSame($first, $second);\n        $this->assertSame($first, $third);\n        $this->assertSame(1, $invokable::$count);\n    }\n\n    public function testFirstClassCallableSyntax()\n    {\n        $instance = new class\n        {\n            public function rand()\n            {\n                return once(MyClass::staticRand(...));\n            }\n        };\n\n        $first = $instance->rand();\n        $second = $instance->rand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testFirstClassCallableSyntaxWithArraySyntax()\n    {\n        $instance = new class\n        {\n            public function rand()\n            {\n                return once([MyClass::class, 'staticRand']);\n            }\n        };\n\n        $first = $instance->rand();\n        $second = $instance->rand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testStaticMemoization()\n    {\n        $first = MyClass::staticRand();\n        $second = MyClass::staticRand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testMemoizationWhenOnceIsWithinClosure()\n    {\n        $resolver = fn () => once(fn () => rand(1, PHP_INT_MAX));\n\n        $first = $resolver();\n        $second = $resolver();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testMemoizationOnGlobalFunctions()\n    {\n        $first = my_rand();\n        $second = my_rand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testDisable()\n    {\n        Once::disable();\n\n        $first = my_rand();\n        $second = my_rand();\n\n        $this->assertNotSame($first, $second);\n    }\n\n    public function testTemporaryDisable()\n    {\n        $first = my_rand();\n        $second = my_rand();\n\n        Once::disable();\n\n        $third = my_rand();\n\n        Once::enable();\n\n        $fourth = my_rand();\n\n        $this->assertSame($first, $second);\n        $this->assertNotSame($first, $third);\n        $this->assertSame($first, $fourth);\n    }\n\n    public function testMemoizationWithinEvals()\n    {\n        $firstResolver = eval('return fn () => once( function () { return random_int(1, PHP_INT_MAX); } ) ;');\n\n        $firstA = $firstResolver();\n        $firstB = $firstResolver();\n\n        $secondResolver = eval('return fn () => fn () => once( function () { return random_int(1, PHP_INT_MAX); } ) ;');\n\n        $secondA = $secondResolver()();\n        $secondB = $secondResolver()();\n\n        $third = eval('return once( function () { return random_int(1, PHP_INT_MAX); } ) ;');\n        $fourth = eval('return once( function () { return random_int(1, PHP_INT_MAX); } ) ;');\n\n        $this->assertNotSame($firstA, $firstB);\n        $this->assertNotSame($secondA, $secondB);\n        $this->assertNotSame($third, $fourth);\n    }\n\n    public function testMemoizationOnSameLine()\n    {\n        $this->markTestSkipped('This test shows a limitation of the current implementation.');\n\n        $result = [once(fn () => rand(1, PHP_INT_MAX)), once(fn () => rand(1, PHP_INT_MAX))];\n\n        $this->assertNotSame($result[0], $result[1]);\n    }\n\n    public function testResultIsDifferentWhenCalledFromDifferentClosures()\n    {\n        $resolver = fn () => once(fn () => rand(1, PHP_INT_MAX));\n        $resolver2 = fn () => once(fn () => rand(1, PHP_INT_MAX));\n\n        $first = $resolver();\n        $second = $resolver2();\n\n        $this->assertNotSame($first, $second);\n    }\n\n    public function testResultIsMemoizedWhenCalledFromMethodsWithSameName()\n    {\n        $instanceA = new class\n        {\n            public function rand()\n            {\n                return once(fn () => rand(1, PHP_INT_MAX));\n            }\n        };\n\n        $instanceB = new class\n        {\n            public function rand()\n            {\n                return once(fn () => rand(1, PHP_INT_MAX));\n            }\n        };\n\n        $first = $instanceA->rand();\n        $second = $instanceB->rand();\n\n        $this->assertNotSame($first, $second);\n    }\n\n    public function testRecursiveOnceCalls()\n    {\n        $instance = new class\n        {\n            public function rand()\n            {\n                return once(fn () => once(fn () => rand(1, PHP_INT_MAX)));\n            }\n        };\n\n        $first = $instance->rand();\n        $second = $instance->rand();\n\n        $this->assertSame($first, $second);\n    }\n\n    public function testGlobalClosures()\n    {\n        $first = $GLOBALS['onceable1']();\n        $second = $GLOBALS['onceable1']();\n\n        $this->assertSame($first, $second);\n\n        $third = $GLOBALS['onceable2']();\n        $fourth = $GLOBALS['onceable2']();\n\n        $this->assertSame($third, $fourth);\n\n        $this->assertNotSame($first, $third);\n    }\n\n    public function testMemoizationNullValues()\n    {\n        $instance = new class\n        {\n            public $i = 0;\n\n            public function null()\n            {\n                return once(function () {\n                    $this->i++;\n\n                    return null;\n                });\n            }\n        };\n\n        $this->assertSame($instance->null(), $instance->null());\n        $this->assertSame(1, $instance->i);\n    }\n\n    public function testExtendedStaticClassOnceCalls()\n    {\n        $first = MyClass::staticRand();\n        $second = MyExtendedClass::staticRand();\n\n        $this->assertNotSame($first, $second);\n    }\n}\n\n$letter = 'a';\n\n$GLOBALS['onceable1'] = fn () => once(fn () => $letter.rand(1, PHP_INT_MAX));\n$GLOBALS['onceable2'] = fn () => once(fn () => $letter.rand(1, PHP_INT_MAX));\n\nfunction my_rand()\n{\n    return once(fn () => rand(1, PHP_INT_MAX));\n}\n\nclass MyClass\n{\n    public function rand()\n    {\n        return once(fn () => rand(1, PHP_INT_MAX));\n    }\n\n    public static function staticRand()\n    {\n        return once(fn () => rand(1, PHP_INT_MAX));\n    }\n\n    public function callRand()\n    {\n        return once(fn () => $this->rand());\n    }\n}\n\nclass MyExtendedClass extends MyClass\n{\n}\n"
  },
  {
    "path": "tests/Support/SleepTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Carbon\\CarbonInterval;\nuse Exception;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Facades\\Date;\nuse Illuminate\\Support\\Sleep;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass SleepTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        Sleep::fake(false);\n\n        Carbon::setTestNow();\n\n        parent::tearDown();\n    }\n\n    public function testItSleepsForSeconds()\n    {\n        $start = microtime(true);\n        Sleep::for(1)->seconds();\n        $end = microtime(true);\n\n        $this->assertEqualsWithDelta(1, $end - $start, 0.03);\n    }\n\n    public function testCallbacksMayBeExecutedUsingThen()\n    {\n        $this->assertEquals(123, Sleep::for(1)->milliseconds()->then(fn () => 123));\n    }\n\n    public function testSleepRespectsWhile()\n    {\n        $_SERVER['__sleep.while'] = 0;\n\n        $result = Sleep::for(10)->milliseconds()->while(function () {\n            static $results = [true, true, false];\n            $_SERVER['__sleep.while']++;\n\n            return array_shift($results);\n        })->then(fn () => 100);\n\n        $this->assertEquals(3, $_SERVER['__sleep.while']);\n        $this->assertEquals(100, $result);\n\n        unset($_SERVER['__sleep.while']);\n    }\n\n    public function testItSleepsForSecondsWithMilliseconds()\n    {\n        $start = microtime(true);\n        Sleep::for(1.5)->seconds();\n        $end = microtime(true);\n\n        $this->assertEqualsWithDelta(1.5, round($end - $start, 1, PHP_ROUND_HALF_DOWN), 0.03);\n    }\n\n    public function testItCanFakeSleeping()\n    {\n        Sleep::fake();\n\n        $start = microtime(true);\n        Sleep::for(1.5)->seconds();\n        $end = microtime(true);\n\n        $this->assertEqualsWithDelta(0, $end - $start, 0.03);\n    }\n\n    public function testItCanSpecifyMinutes()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1.5)->minutes();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 90_000_000.0);\n    }\n\n    public function testItCanSpecifyMinute()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1)->minute();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 60_000_000.0);\n    }\n\n    public function testItCanSpecifySeconds()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1.5)->seconds();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1_500_000.0);\n    }\n\n    public function testItCanSpecifySecond()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1)->second();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1_000_000.0);\n    }\n\n    public function testItCanSpecifyMilliseconds()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1.5)->milliseconds();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1_500.0);\n    }\n\n    public function testItCanSpecifyMillisecond()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1)->millisecond();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1_000.0);\n    }\n\n    public function testItCanSpecifyMicroseconds()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1.5)->microseconds();\n\n        // rounded as microseconds is the smallest unit supported...\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1.0);\n    }\n\n    public function testItCanSpecifyMicrosecond()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1)->microsecond();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1.0);\n    }\n\n    public function testItCanChainDurations()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(1)->second()\n            ->and(500)->microseconds();\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1000500.0);\n    }\n\n    public function testItCanUseDateInterval()\n    {\n        Sleep::fake();\n\n        $sleep = Sleep::for(CarbonInterval::seconds(1)->addMilliseconds(5));\n\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1_005_000.0);\n    }\n\n    public function testItThrowsForUnknownTimeUnit()\n    {\n        try {\n            Sleep::for(5);\n            $this->fail();\n        } catch (RuntimeException $e) {\n            $this->assertSame('Unknown duration unit.', $e->getMessage());\n        }\n    }\n\n    public function testItCanAssertSequence()\n    {\n        Sleep::fake();\n\n        Sleep::for(5)->seconds();\n        Sleep::for(1)->seconds()->and(5)->microsecond();\n\n        Sleep::assertSequence([\n            Sleep::for(5)->seconds(),\n            Sleep::for(1)->seconds()->and(5)->microsecond(),\n        ]);\n    }\n\n    public function testItFailsSequenceAssertion()\n    {\n        Sleep::fake();\n\n        Sleep::for(5)->seconds();\n        Sleep::for(1)->seconds()->and(5)->microseconds();\n\n        try {\n            Sleep::assertSequence([\n                Sleep::for(5)->seconds(),\n                Sleep::for(9)->seconds()->and(8)->milliseconds(),\n            ]);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected sleep duration of [9 seconds 8 milliseconds] but actually slept for [1 second 5 microseconds].\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n    }\n\n    public function testItCanUseSleep()\n    {\n        Sleep::fake();\n\n        Sleep::sleep(3);\n\n        Sleep::assertSequence([\n            Sleep::for(3)->seconds(),\n        ]);\n    }\n\n    public function testItCanUseUSleep()\n    {\n        Sleep::fake();\n\n        Sleep::usleep(3);\n\n        Sleep::assertSequence([\n            Sleep::for(3)->microseconds(),\n        ]);\n    }\n\n    public function testItCanSleepTillGivenTime()\n    {\n        Sleep::fake();\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n\n        Sleep::until(Carbon::now()->addMinute());\n\n        Sleep::assertSequence([\n            Sleep::for(60)->seconds(),\n        ]);\n    }\n\n    public function testItCanSleepTillGivenTimestamp()\n    {\n        Sleep::fake();\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n\n        Sleep::until(Carbon::now()->addMinute()->timestamp);\n\n        Sleep::assertSequence([\n            Sleep::for(60)->seconds(),\n        ]);\n    }\n\n    public function testItCanSleepTillGivenTimestampAsString()\n    {\n        Sleep::fake();\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n\n        Sleep::until((string) Carbon::now()->addMinute()->timestamp);\n\n        Sleep::assertSequence([\n            Sleep::for(60)->seconds(),\n        ]);\n    }\n\n    public function testItCanSleepTillGivenTimestampAsStringWithMilliseconds()\n    {\n        Sleep::fake();\n        Carbon::setTestNow('2000-01-01 00:00:00.000'); // 946684800\n\n        Sleep::until('946684899.123');\n\n        Sleep::assertSequence([\n            Sleep::for(1)->minute()\n                ->and(39)->seconds()\n                ->and(123)->milliseconds(),\n        ]);\n    }\n\n    public function testItSleepsForZeroTimeWithNegativeDateTime()\n    {\n        Sleep::fake();\n        Carbon::setTestNow(Carbon::now()->startOfDay());\n\n        Sleep::until(Carbon::now()->subMinutes(100));\n\n        Sleep::assertSequence([\n            Sleep::for(0)->seconds(),\n        ]);\n    }\n\n    public function testSleepingForZeroTime()\n    {\n        Sleep::fake();\n\n        Sleep::for(0)->seconds();\n\n        try {\n            Sleep::assertSequence([\n                Sleep::for(1)->seconds(),\n            ]);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected sleep duration of [1 second] but actually slept for [0 microseconds].\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n    }\n\n    public function testItFailsWhenSequenceContainsTooManySleeps()\n    {\n        Sleep::fake();\n\n        Sleep::for(1)->seconds();\n\n        try {\n            Sleep::assertSequence([\n                Sleep::for(1)->seconds(),\n                Sleep::for(1)->seconds(),\n            ]);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [2] sleeps but found [1].\\nFailed asserting that 1 is identical to 2.\", $e->getMessage());\n        }\n    }\n\n    public function testSilentlySetsDurationToZeroForNegativeValues()\n    {\n        Sleep::fake();\n\n        Sleep::for(-1)->seconds();\n\n        Sleep::assertSequence([\n            Sleep::for(0)->seconds(),\n        ]);\n    }\n\n    public function testItDoesntCaptureAssertionInstances()\n    {\n        Sleep::fake();\n\n        Sleep::for(1)->second();\n\n        Sleep::assertSequence([\n            Sleep::for(1)->second(),\n        ]);\n\n        try {\n            Sleep::assertSequence([\n                Sleep::for(1)->second(),\n                Sleep::for(1)->second(),\n            ]);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [2] sleeps but found [1].\\nFailed asserting that 1 is identical to 2.\", $e->getMessage());\n        }\n    }\n\n    public function testAssertNeverSlept()\n    {\n        Sleep::fake();\n\n        Sleep::assertNeverSlept();\n\n        Sleep::for(1)->seconds();\n\n        try {\n            Sleep::assertNeverSlept();\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [0] sleeps but found [1].\\nFailed asserting that 1 is identical to 0.\", $e->getMessage());\n        }\n    }\n\n    public function testAssertNeverAgainstZeroSecondSleep()\n    {\n        Sleep::fake();\n\n        Sleep::assertNeverSlept();\n\n        Sleep::for(0)->seconds();\n\n        try {\n            Sleep::assertNeverSlept();\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [0] sleeps but found [1].\\nFailed asserting that 1 is identical to 0.\", $e->getMessage());\n        }\n    }\n\n    public function testItCanAssertNoSleepingOccurred()\n    {\n        Sleep::fake();\n\n        Sleep::assertInsomniac();\n\n        Sleep::for(0)->second();\n\n        // we still have not slept...\n        Sleep::assertInsomniac();\n\n        Sleep::for(1)->second();\n\n        try {\n            Sleep::assertInsomniac();\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Unexpected sleep duration of [1 second] found.\\nFailed asserting that 1000000 is identical to 0.\", $e->getMessage());\n        }\n    }\n\n    public function testItCanAssertSleepCount()\n    {\n        Sleep::fake();\n\n        Sleep::assertSleptTimes(0);\n\n        Sleep::for(1)->second();\n\n        Sleep::assertSleptTimes(1);\n\n        try {\n            Sleep::assertSleptTimes(0);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [0] sleeps but found [1].\\nFailed asserting that 1 is identical to 0.\", $e->getMessage());\n        }\n\n        try {\n            Sleep::assertSleptTimes(2);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected [2] sleeps but found [1].\\nFailed asserting that 1 is identical to 2.\", $e->getMessage());\n        }\n    }\n\n    public function testAssertSlept()\n    {\n        Sleep::fake();\n\n        Sleep::assertSlept(fn () => true, 0);\n\n        try {\n            Sleep::assertSlept(fn () => true);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"The expected sleep was found [0] times instead of [1].\\nFailed asserting that 0 is identical to 1.\", $e->getMessage());\n        }\n\n        Sleep::for(5)->seconds();\n\n        Sleep::assertSlept(fn (CarbonInterval $duration) => (float) $duration->totalSeconds === 5.0);\n\n        try {\n            Sleep::assertSlept(fn (CarbonInterval $duration) => (float) $duration->totalSeconds === 5.0, 2);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"The expected sleep was found [1] times instead of [2].\\nFailed asserting that 1 is identical to 2.\", $e->getMessage());\n        }\n\n        try {\n            Sleep::assertSlept(fn (CarbonInterval $duration) => (float) $duration->totalSeconds === 6.0);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"The expected sleep was found [0] times instead of [1].\\nFailed asserting that 0 is identical to 1.\", $e->getMessage());\n        }\n    }\n\n    public function testItCanCreateMacrosViaMacroable()\n    {\n        Sleep::fake();\n\n        Sleep::macro('forSomeConfiguredAmountOfTime', static function () {\n            return Sleep::for(3)->seconds();\n        });\n\n        Sleep::macro('useSomeOtherAmountOfTime', function () {\n            /** @var Sleep $this */\n            return $this->duration(1.234)->seconds();\n        });\n\n        Sleep::macro('andSomeMoreGranularControl', function () {\n            /** @var Sleep $this */\n            return $this->and(567)->microseconds();\n        });\n\n        // A static macro can be referenced\n        $sleep = Sleep::forSomeConfiguredAmountOfTime();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 3000000.0);\n\n        // A macro can specify a new duration\n        $sleep = $sleep->useSomeOtherAmountOfTime();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1234000.0);\n\n        // A macro can supplement an existing duration\n        $sleep = $sleep->andSomeMoreGranularControl();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1234567.0);\n    }\n\n    public function testItCanReplacePreviouslyDefinedDurations()\n    {\n        Sleep::fake();\n\n        Sleep::macro('setDuration', function ($duration) {\n            return $this->duration($duration);\n        });\n\n        $sleep = Sleep::for(1)->second();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 1000000.0);\n\n        $sleep->setDuration(2)->second();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 2000000.0);\n\n        $sleep->setDuration(500)->milliseconds();\n        $this->assertSame((float) $sleep->duration->totalMicroseconds, 500000.0);\n    }\n\n    public function testItCanSleepConditionallyWhen()\n    {\n        Sleep::fake();\n\n        // Control test\n        Sleep::assertSlept(fn () => true, 0);\n        Sleep::for(1)->second();\n        Sleep::assertSlept(fn () => true, 1);\n        Sleep::fake();\n        Sleep::assertSlept(fn () => true, 0);\n\n        // Reset\n        Sleep::fake();\n\n        // Will not sleep if `when()` yields `false`\n        Sleep::for(1)->second()->when(false);\n        Sleep::for(1)->second()->when(fn () => false);\n\n        // Will not sleep if `unless()` yields `true`\n        Sleep::for(1)->second()->unless(true);\n        Sleep::for(1)->second()->unless(fn () => true);\n\n        // Finish 'do not sleep' tests - assert no sleeping occurred\n        Sleep::assertSlept(fn () => true, 0);\n\n        // Will sleep if `when()` yields `true`\n        Sleep::for(1)->second()->when(true);\n        Sleep::assertSlept(fn () => true, 1);\n        Sleep::for(1)->second()->when(fn () => true);\n        Sleep::assertSlept(fn () => true, 2);\n\n        // Will sleep if `unless()` yields `false`\n        Sleep::for(1)->second()->unless(false);\n        Sleep::assertSlept(fn () => true, 3);\n        Sleep::for(1)->second()->unless(fn () => false);\n        Sleep::assertSlept(fn () => true, 4);\n    }\n\n    public function testItCanRegisterCallbacksToRunInTests()\n    {\n        $countA = 0;\n        $countB = 0;\n        Sleep::fake();\n        Sleep::whenFakingSleep(function ($duration) use (&$countA) {\n            $countA += $duration->totalMilliseconds;\n        });\n        Sleep::whenFakingSleep(function ($duration) use (&$countB) {\n            $countB += $duration->totalMilliseconds;\n        });\n\n        Sleep::for(1)->millisecond();\n        Sleep::for(2)->millisecond();\n\n        Sleep::assertSequence([\n            Sleep::for(1)->millisecond(),\n            Sleep::for(2)->millisecond(),\n        ]);\n\n        $this->assertSame(3.0, (float) $countA);\n        $this->assertSame(3.0, (float) $countB);\n    }\n\n    public function testItDoesntRunCallbacksWhenNotFaking()\n    {\n        Sleep::whenFakingSleep(function () {\n            throw new Exception('Should not run without faking.');\n        });\n\n        Sleep::for(1)->millisecond();\n\n        $this->assertTrue(true);\n    }\n\n    public function testItDoesNotSyncCarbon()\n    {\n        Carbon::setTestNow('2000-01-01 00:00:00');\n        Sleep::fake();\n\n        Sleep::for(5)->minutes()\n            ->and(3)->seconds();\n\n        Sleep::assertSequence([\n            Sleep::for(303)->seconds(),\n        ]);\n        $this->assertSame('2000-01-01 00:00:00', Date::now()->toDateTimeString());\n    }\n\n    public function testItCanSyncCarbon()\n    {\n        Carbon::setTestNow('2000-01-01 00:00:00');\n        Sleep::fake();\n        Sleep::syncWithCarbon();\n\n        Sleep::for(5)->minutes()\n            ->and(3)->seconds();\n\n        Sleep::assertSequence([\n            Sleep::for(303)->seconds(),\n        ]);\n        $this->assertSame('2000-01-01 00:05:03', Date::now()->toDateTimeString());\n    }\n\n    #[TestWith([\n        'syncWithCarbon' => true,\n        'datetime' => '2000-01-01 00:05:03',\n    ])]\n    #[TestWith([\n        'syncWithCarbon' => false,\n        'datetime' => '2000-01-01 00:00:00',\n    ])]\n    public function testFakeCanSetSyncWithCarbon(bool $syncWithCarbon, string $datetime)\n    {\n        Carbon::setTestNow('2000-01-01 00:00:00');\n        Sleep::fake(syncWithCarbon: $syncWithCarbon);\n\n        Sleep::for(5)->minutes()\n            ->and(3)->seconds();\n\n        Sleep::assertSequence([\n            Sleep::for(303)->seconds(),\n        ]);\n        $this->assertSame($datetime, Date::now()->toDateTimeString());\n    }\n\n    public function testFakeDoesNotNeedToSyncWithCarbon()\n    {\n        Carbon::setTestNow('2000-01-01 00:00:00');\n        Sleep::fake();\n\n        Sleep::for(5)->minutes()\n            ->and(3)->seconds();\n\n        Sleep::assertSequence([\n            Sleep::for(303)->seconds(),\n        ]);\n        $this->assertSame('2000-01-01 00:00:00', Date::now()->toDateTimeString());\n    }\n}\n"
  },
  {
    "path": "tests/Support/StorageFacadeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Facades\\Config;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\UnableToReadFile;\nuse Orchestra\\Testbench\\TestCase;\n\nclass StorageFacadeTest extends TestCase\n{\n    public function testFake_whenDiskNotConfigured_doesNotThrowExceptionOnError()\n    {\n        $result = Storage::fake('test')->get('nonExistentFile');\n\n        $this->assertNull($result);\n    }\n\n    public function testFake_whenThrowSetToDisk_throwsExceptionOnError()\n    {\n        Config::set('filesystems.disks.test', ['throw' => true]);\n\n        $this->expectException(UnableToReadFile::class);\n        Storage::fake('test')->get('nonExistentFile');\n    }\n\n    public function testFake_whenThrowOverwritten_usesOverwrite()\n    {\n        Config::set('filesystems.disks.test', ['throw' => true]);\n\n        $result = Storage::fake('test', ['throw' => false])->get('nonExistentFile');\n        $this->assertNull($result);\n    }\n\n    public function testPersistentFake_whenDiskNotConfigured_doesNotThrowExceptionOnError()\n    {\n        $result = Storage::persistentFake('test')->get('nonExistentFile');\n\n        $this->assertNull($result);\n    }\n\n    public function testPersistentFake_whenThrowSetToDisk_throwsExceptionOnError()\n    {\n        Config::set('filesystems.disks.test', ['throw' => true]);\n\n        $this->expectException(UnableToReadFile::class);\n        Storage::persistentFake('test')->get('nonExistentFile');\n    }\n\n    public function testPersistentFake_whenThrowOverwritten_usesOverwrite()\n    {\n        Config::set('filesystems.disks.test', ['throw' => true]);\n\n        $result = Storage::persistentFake('test', ['throw' => false])->get('nonExistentFile');\n        $this->assertNull($result);\n    }\n\n    public function testStorageFakeMethodsWithEnums()\n    {\n        $this->assertNull(Storage::persistentFake(StorageDisk::Test)->get('nonExistentFile'));\n        $this->assertNull(Storage::fake(StorageDisk::Public)->get('nonExistentFile'));\n    }\n}\n\nenum StorageDisk: string\n{\n    case Test = 'test';\n    case Public = 'public';\n}\n"
  },
  {
    "path": "tests/Support/SupportArrTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayObject;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\ItemNotFoundException;\nuse Illuminate\\Support\\MultipleItemsFoundException;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\IgnoreDeprecations;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\nuse WeakMap;\n\ninclude_once 'Common.php';\ninclude_once 'Enums.php';\n\nclass SupportArrTest extends TestCase\n{\n    public function testAccessible(): void\n    {\n        $this->assertTrue(Arr::accessible([]));\n        $this->assertTrue(Arr::accessible([1, 2]));\n        $this->assertTrue(Arr::accessible(['a' => 1, 'b' => 2]));\n        $this->assertTrue(Arr::accessible(new Collection));\n\n        $this->assertFalse(Arr::accessible(null));\n        $this->assertFalse(Arr::accessible('abc'));\n        $this->assertFalse(Arr::accessible(new stdClass));\n        $this->assertFalse(Arr::accessible((object) ['a' => 1, 'b' => 2]));\n        $this->assertFalse(Arr::accessible(123));\n        $this->assertFalse(Arr::accessible(12.34));\n        $this->assertFalse(Arr::accessible(true));\n        $this->assertFalse(Arr::accessible(new \\DateTime));\n        $this->assertFalse(Arr::accessible(static fn () => null));\n    }\n\n    public function testArrayable(): void\n    {\n        $this->assertTrue(Arr::arrayable([]));\n        $this->assertTrue(Arr::arrayable(new TestArrayableObject));\n        $this->assertTrue(Arr::arrayable(new TestJsonableObject));\n        $this->assertTrue(Arr::arrayable(new TestJsonSerializeObject));\n        $this->assertTrue(Arr::arrayable(new TestTraversableAndJsonSerializableObject));\n\n        $this->assertFalse(Arr::arrayable(null));\n        $this->assertFalse(Arr::arrayable('abc'));\n        $this->assertFalse(Arr::arrayable(new stdClass));\n        $this->assertFalse(Arr::arrayable((object) ['a' => 1, 'b' => 2]));\n        $this->assertFalse(Arr::arrayable(123));\n        $this->assertFalse(Arr::arrayable(12.34));\n        $this->assertFalse(Arr::arrayable(true));\n        $this->assertFalse(Arr::arrayable(new \\DateTime));\n        $this->assertFalse(Arr::arrayable(static fn () => null));\n    }\n\n    public function testAdd()\n    {\n        $array = Arr::add(['name' => 'Desk'], 'price', 100);\n        $this->assertEquals(['name' => 'Desk', 'price' => 100], $array);\n\n        $this->assertEquals(['surname' => 'Mövsümov'], Arr::add([], 'surname', 'Mövsümov'));\n        $this->assertEquals(['developer' => ['name' => 'Ferid']], Arr::add([], 'developer.name', 'Ferid'));\n        $this->assertEquals([1 => 'hAz'], Arr::add([], 1, 'hAz'));\n        $this->assertEquals([1 => [1 => 'hAz']], Arr::add([], 1.1, 'hAz'));\n\n        // Case where the key already exists\n        $this->assertEquals(['type' => 'Table'], Arr::add(['type' => 'Table'], 'type', 'Chair'));\n        $this->assertEquals(['category' => ['type' => 'Table']], Arr::add(['category' => ['type' => 'Table']], 'category.type', 'Chair'));\n    }\n\n    public function testPush()\n    {\n        $array = [];\n\n        Arr::push($array, 'office.furniture', 'Desk');\n        $this->assertEquals(['Desk'], $array['office']['furniture']);\n\n        Arr::push($array, 'office.furniture', 'Chair', 'Lamp');\n        $this->assertEquals(['Desk', 'Chair', 'Lamp'], $array['office']['furniture']);\n\n        $array = [];\n\n        Arr::push($array, null, 'Chris', 'Nuno');\n        $this->assertEquals(['Chris', 'Nuno'], $array);\n\n        Arr::push($array, null, 'Taylor');\n        $this->assertEquals(['Chris', 'Nuno', 'Taylor'], $array);\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Array value for key [foo.bar] must be an array, boolean found.');\n\n        $array = ['foo' => ['bar' => false]];\n        Arr::push($array, 'foo.bar', 'baz');\n    }\n\n    public function testCollapse()\n    {\n        // Normal case: a two-dimensional array with different elements\n        $data = [['foo', 'bar'], ['baz']];\n        $this->assertEquals(['foo', 'bar', 'baz'], Arr::collapse($data));\n\n        // Case including numeric and string elements\n        $array = [[1], [2], [3], ['foo', 'bar']];\n        $this->assertEquals([1, 2, 3, 'foo', 'bar'], Arr::collapse($array));\n\n        // Case with empty two-dimensional arrays\n        $emptyArray = [[], [], []];\n        $this->assertEquals([], Arr::collapse($emptyArray));\n\n        // Case with both empty arrays and arrays with elements\n        $mixedArray = [[], [1, 2], [], ['foo', 'bar']];\n        $this->assertEquals([1, 2, 'foo', 'bar'], Arr::collapse($mixedArray));\n\n        // Case including collections and arrays\n        $collection = collect(['baz', 'boom']);\n        $mixedArray = [[1], [2], [3], ['foo', 'bar'], $collection];\n        $this->assertEquals([1, 2, 3, 'foo', 'bar', 'baz', 'boom'], Arr::collapse($mixedArray));\n    }\n\n    public function testCrossJoin()\n    {\n        // Single dimension\n        $this->assertSame(\n            [[1, 'a'], [1, 'b'], [1, 'c']],\n            Arr::crossJoin([1], ['a', 'b', 'c'])\n        );\n\n        // Square matrix\n        $this->assertSame(\n            [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']],\n            Arr::crossJoin([1, 2], ['a', 'b'])\n        );\n\n        // Rectangular matrix\n        $this->assertSame(\n            [[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c']],\n            Arr::crossJoin([1, 2], ['a', 'b', 'c'])\n        );\n\n        // 3D matrix\n        $this->assertSame(\n            [\n                [1, 'a', 'I'], [1, 'a', 'II'], [1, 'a', 'III'],\n                [1, 'b', 'I'], [1, 'b', 'II'], [1, 'b', 'III'],\n                [2, 'a', 'I'], [2, 'a', 'II'], [2, 'a', 'III'],\n                [2, 'b', 'I'], [2, 'b', 'II'], [2, 'b', 'III'],\n            ],\n            Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II', 'III'])\n        );\n\n        // With 1 empty dimension\n        $this->assertEmpty(Arr::crossJoin([], ['a', 'b'], ['I', 'II', 'III']));\n        $this->assertEmpty(Arr::crossJoin([1, 2], [], ['I', 'II', 'III']));\n        $this->assertEmpty(Arr::crossJoin([1, 2], ['a', 'b'], []));\n\n        // With empty arrays\n        $this->assertEmpty(Arr::crossJoin([], [], []));\n        $this->assertEmpty(Arr::crossJoin([], []));\n        $this->assertEmpty(Arr::crossJoin([]));\n\n        // Not really a proper usage, still, test for preserving BC\n        $this->assertSame([[]], Arr::crossJoin());\n    }\n\n    #[IgnoreDeprecations]\n    public function testDivide(): void\n    {\n        // Test dividing an empty array\n        [$keys, $values] = Arr::divide([]);\n        $this->assertEquals([], $keys);\n        $this->assertEquals([], $values);\n\n        // Test dividing an array with a single key-value pair\n        [$keys, $values] = Arr::divide(['name' => 'Desk']);\n        $this->assertEquals(['name'], $keys);\n        $this->assertEquals(['Desk'], $values);\n\n        // Test dividing an array with multiple key-value pairs\n        [$keys, $values] = Arr::divide(['name' => 'Desk', 'price' => 100, 'available' => true]);\n        $this->assertEquals(['name', 'price', 'available'], $keys);\n        $this->assertEquals(['Desk', 100, true], $values);\n\n        // Test dividing an array with numeric keys\n        [$keys, $values] = Arr::divide([0 => 'first', 1 => 'second']);\n        $this->assertEquals([0, 1], $keys);\n        $this->assertEquals(['first', 'second'], $values);\n\n        // Test dividing an array with null key\n        [$keys, $values] = Arr::divide([null => 'Null', 1 => 'one']);\n        $this->assertEquals([null, 1], $keys);\n        $this->assertEquals(['Null', 'one'], $values);\n\n        // Test dividing an array where the keys are arrays\n        [$keys, $values] = Arr::divide([['one' => 1, 2 => 'second'], 1 => 'one']);\n        $this->assertEquals([0, 1], $keys);\n        $this->assertEquals([['one' => 1, 2 => 'second'], 'one'], $values);\n\n        // Test dividing an array where the values are arrays\n        [$keys, $values] = Arr::divide(['' => ['one' => 1, 2 => 'second'], 1 => 'one']);\n        $this->assertEquals([null, 1], $keys);\n        $this->assertEquals([['one' => 1, 2 => 'second'], 'one'], $values);\n\n        // Test dividing an array where the values are arrays (with null key)\n        [$keys, $values] = Arr::divide([null => ['one' => 1, 2 => 'second'], 1 => 'one']);\n        $this->assertEquals([null, 1], $keys);\n        $this->assertEquals([['one' => 1, 2 => 'second'], 'one'], $values);\n    }\n\n    public function testDot()\n    {\n        $array = Arr::dot(['foo' => ['bar' => 'baz']]);\n        $this->assertSame(['foo.bar' => 'baz'], $array);\n\n        $array = Arr::dot([10 => 100]);\n        $this->assertSame([10 => 100], $array);\n\n        $array = Arr::dot(['foo' => [10 => 100]]);\n        $this->assertSame(['foo.10' => 100], $array);\n\n        $array = Arr::dot([]);\n        $this->assertSame([], $array);\n\n        $array = Arr::dot(['foo' => []]);\n        $this->assertSame(['foo' => []], $array);\n\n        $array = Arr::dot(['foo' => ['bar' => []]]);\n        $this->assertSame(['foo.bar' => []], $array);\n\n        $array = Arr::dot(['name' => 'taylor', 'languages' => ['php' => true]]);\n        $this->assertSame(['name' => 'taylor', 'languages.php' => true], $array);\n\n        $array = Arr::dot(['user' => ['name' => 'Taylor', 'age' => 25, 'languages' => ['PHP', 'C#']]]);\n        $this->assertSame([\n            'user.name' => 'Taylor',\n            'user.age' => 25,\n            'user.languages.0' => 'PHP',\n            'user.languages.1' => 'C#',\n        ], $array);\n\n        $array = Arr::dot(['foo', 'foo' => ['bar' => 'baz', 'baz' => ['a' => 'b']]]);\n        $this->assertSame([\n            'foo',\n            'foo.bar' => 'baz',\n            'foo.baz.a' => 'b',\n        ], $array);\n\n        $array = Arr::dot(['foo' => 'bar', 'empty_array' => [], 'user' => ['name' => 'Taylor'], 'key' => 'value']);\n        $this->assertSame([\n            'foo' => 'bar',\n            'empty_array' => [],\n            'user.name' => 'Taylor',\n            'key' => 'value',\n        ], $array);\n    }\n\n    public function testDotWithDepth()\n    {\n        $array = Arr::dot(['user' => ['name' => 'Taylor', 'address' => ['city' => 'Dallas']]], '', 1);\n        $this->assertSame([\n            'user.name' => 'Taylor',\n            'user.address' => ['city' => 'Dallas'],\n        ], $array);\n\n        $array = Arr::dot(['user' => ['address' => ['city' => ['name' => 'Dallas']]]], '', 2);\n        $this->assertSame([\n            'user.address.city' => ['name' => 'Dallas'],\n        ], $array);\n\n        $array = Arr::dot(['user' => ['address' => ['city' => ['name' => 'Dallas']]]], '', INF);\n        $this->assertSame([\n            'user.address.city.name' => 'Dallas',\n        ], $array);\n\n        $array = Arr::dot(['name' => 'taylor', 'languages' => ['php' => true, 'js' => ['react' => true]]], '', 1);\n        $this->assertSame([\n            'name' => 'taylor',\n            'languages.php' => true,\n            'languages.js' => ['react' => true],\n        ], $array);\n\n        $array = Arr::dot(['foo' => ['bar' => []]], '', 1);\n        $this->assertSame(['foo.bar' => []], $array);\n\n        $array = Arr::dot(['user' => ['name' => 'Taylor', 'address' => ['city' => 'Dallas']]], '', 0);\n        $this->assertSame([\n            'user' => ['name' => 'Taylor', 'address' => ['city' => 'Dallas']],\n        ], $array);\n\n        $array = Arr::dot(['user' => ['name' => 'Taylor']], 'prefix.', 1);\n        $this->assertSame(['prefix.user.name' => 'Taylor'], $array);\n    }\n\n    public function testUndot()\n    {\n        $array = Arr::undot([\n            'user.name' => 'Taylor',\n            'user.age' => 25,\n            'user.languages.0' => 'PHP',\n            'user.languages.1' => 'C#',\n        ]);\n        $this->assertEquals(['user' => ['name' => 'Taylor', 'age' => 25, 'languages' => ['PHP', 'C#']]], $array);\n\n        $array = Arr::undot([\n            'pagination.previous' => '<<',\n            'pagination.next' => '>>',\n        ]);\n        $this->assertEquals(['pagination' => ['previous' => '<<', 'next' => '>>']], $array);\n\n        $array = Arr::undot([\n            'foo',\n            'foo.bar' => 'baz',\n            'foo.baz' => ['a' => 'b'],\n        ]);\n        $this->assertEquals(['foo', 'foo' => ['bar' => 'baz', 'baz' => ['a' => 'b']]], $array);\n    }\n\n    public function testExcept()\n    {\n        $array = ['name' => 'taylor', 'age' => 26];\n        $this->assertEquals(['age' => 26], Arr::except($array, ['name']));\n        $this->assertEquals(['age' => 26], Arr::except($array, 'name'));\n\n        $array = ['name' => 'taylor', 'framework' => ['language' => 'PHP', 'name' => 'Laravel']];\n        $this->assertEquals(['name' => 'taylor'], Arr::except($array, 'framework'));\n        $this->assertEquals(['name' => 'taylor', 'framework' => ['name' => 'Laravel']], Arr::except($array, 'framework.language'));\n        $this->assertEquals(['framework' => ['language' => 'PHP']], Arr::except($array, ['name', 'framework.name']));\n\n        $array = [1 => 'hAz', 2 => [5 => 'foo', 12 => 'baz']];\n        $this->assertEquals([1 => 'hAz'], Arr::except($array, 2));\n        $this->assertEquals([1 => 'hAz', 2 => [12 => 'baz']], Arr::except($array, 2.5));\n    }\n\n    public function testExceptValues()\n    {\n        $array = ['name' => 'taylor', 'age' => 26, 'city' => 'austin'];\n        $this->assertEquals(['name' => 'taylor', 'city' => 'austin'], Arr::exceptValues($array, [26]));\n        $this->assertEquals(['name' => 'taylor', 'city' => 'austin'], Arr::exceptValues($array, 26));\n\n        $array = ['foo', 'bar', 'baz', 'qux'];\n        $this->assertEquals([1 => 'bar', 3 => 'qux'], Arr::exceptValues($array, ['foo', 'baz']));\n        $this->assertEquals([0 => 'foo', 1 => 'bar', 3 => 'qux'], Arr::exceptValues($array, 'baz'));\n\n        $array = [1, 2, 3, 4, 5];\n        $this->assertEquals([0 => 1, 1 => 2, 4 => 5], Arr::exceptValues($array, [3, 4]));\n\n        $array = ['a' => 1, 'b' => 2, 'c' => 1, 'd' => 3];\n        $this->assertEquals(['b' => 2, 'd' => 3], Arr::exceptValues($array, 1));\n\n        $this->assertEquals([], Arr::exceptValues([], 'foo'));\n        $this->assertEquals(['foo', 'bar'], Arr::exceptValues(['foo', 'bar'], []));\n\n        $array = [1, '1', 2, '2', 3];\n        $this->assertEquals([1 => '1', 3 => '2'], Arr::exceptValues($array, [1, 2, 3], true));\n        $this->assertEquals([], Arr::exceptValues($array, [1, 2, 3]));\n\n        $array = ['a' => true, 'b' => false, 'c' => 1, 'd' => 0];\n        $this->assertEquals(['a' => true, 'b' => false], Arr::exceptValues($array, [1, 0], true));\n        $this->assertEquals([], Arr::exceptValues($array, [1, 0]));\n    }\n\n    public function testExists()\n    {\n        $this->assertTrue(Arr::exists([1], 0));\n        $this->assertTrue(Arr::exists([null], 0));\n        $this->assertTrue(Arr::exists(['a' => 1], 'a'));\n        $this->assertTrue(Arr::exists(['a' => null], 'a'));\n        $this->assertTrue(Arr::exists(new Collection(['a' => null]), 'a'));\n\n        $this->assertFalse(Arr::exists([1], 1));\n        $this->assertFalse(Arr::exists([null], 1));\n        $this->assertFalse(Arr::exists(['a' => 1], 0));\n        $this->assertFalse(Arr::exists(new Collection(['a' => null]), 'b'));\n    }\n\n    public function testWhereNotNull(): void\n    {\n        $array = array_values(Arr::whereNotNull([null, 0, false, '', null, []]));\n        $this->assertEquals([0, false, '', []], $array);\n\n        $array = array_values(Arr::whereNotNull([1, 2, 3]));\n        $this->assertEquals([1, 2, 3], $array);\n\n        $array = array_values(Arr::whereNotNull([null, null, null]));\n        $this->assertEquals([], $array);\n\n        $array = array_values(Arr::whereNotNull(['a', null, 'b', null, 'c']));\n        $this->assertEquals(['a', 'b', 'c'], $array);\n\n        $array = array_values(Arr::whereNotNull([null, 1, 'string', 0.0, false, [], $class = new stdClass(), $function = fn () => null]));\n        $this->assertEquals([1, 'string', 0.0, false, [], $class, $function], $array);\n    }\n\n    public function testFirst()\n    {\n        $array = [100, 200, 300];\n\n        // Callback is null and array is empty\n        $this->assertNull(Arr::first([], null));\n        $this->assertSame('foo', Arr::first([], null, 'foo'));\n        $this->assertSame('bar', Arr::first([], null, function () {\n            return 'bar';\n        }));\n\n        // Callback is null and array is not empty\n        $this->assertEquals(100, Arr::first($array));\n\n        // Callback is not null and array is not empty\n        $value = Arr::first($array, function ($value) {\n            return $value >= 150;\n        });\n        $this->assertEquals(200, $value);\n\n        // Callback is not null, array is not empty but no satisfied item\n        $value2 = Arr::first($array, function ($value) {\n            return $value > 300;\n        });\n        $value3 = Arr::first($array, function ($value) {\n            return $value > 300;\n        }, 'bar');\n        $value4 = Arr::first($array, function ($value) {\n            return $value > 300;\n        }, function () {\n            return 'baz';\n        });\n        $value5 = Arr::first($array, function ($value, $key) {\n            return $key < 2;\n        });\n        $this->assertNull($value2);\n        $this->assertSame('bar', $value3);\n        $this->assertSame('baz', $value4);\n        $this->assertEquals(100, $value5);\n\n        $cursor = (function () {\n            while (false) {\n                yield 1;\n            }\n        })();\n        $this->assertNull(Arr::first($cursor));\n    }\n\n    public function testFirstWorksWithArrayObject()\n    {\n        $arrayObject = new ArrayObject([0, 10, 20]);\n\n        $result = Arr::first($arrayObject, fn ($value) => $value === 0);\n\n        $this->assertSame(0, $result);\n    }\n\n    public function testJoin()\n    {\n        $this->assertSame('a, b, c', Arr::join(['a', 'b', 'c'], ', '));\n\n        $this->assertSame('a, b and c', Arr::join(['a', 'b', 'c'], ', ', ' and '));\n\n        $this->assertSame('a and b', Arr::join(['a', 'b'], ', ', ' and '));\n\n        $this->assertSame('a', Arr::join(['a'], ', ', ' and '));\n\n        $this->assertSame('', Arr::join([], ', ', ' and '));\n    }\n\n    public function testLast()\n    {\n        $array = [100, 200, 300];\n\n        // Callback is null and array is empty\n        $this->assertNull(Arr::last([], null));\n        $this->assertSame('foo', Arr::last([], null, 'foo'));\n        $this->assertSame('bar', Arr::last([], null, function () {\n            return 'bar';\n        }));\n\n        // Callback is null and array is not empty\n        $this->assertEquals(300, Arr::last($array));\n\n        // Callback is not null and array is not empty\n        $value = Arr::last($array, function ($value) {\n            return $value < 250;\n        });\n        $this->assertEquals(200, $value);\n\n        // Callback is not null, array is not empty but no satisfied item\n        $value2 = Arr::last($array, function ($value) {\n            return $value > 300;\n        });\n        $value3 = Arr::last($array, function ($value) {\n            return $value > 300;\n        }, 'bar');\n        $value4 = Arr::last($array, function ($value) {\n            return $value > 300;\n        }, function () {\n            return 'baz';\n        });\n        $value5 = Arr::last($array, function ($value, $key) {\n            return $key < 2;\n        });\n        $this->assertNull($value2);\n        $this->assertSame('bar', $value3);\n        $this->assertSame('baz', $value4);\n        $this->assertEquals(200, $value5);\n    }\n\n    public function testFlatten()\n    {\n        // Flat arrays are unaffected\n        $array = ['#foo', '#bar', '#baz'];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Nested arrays are flattened with existing flat items\n        $array = [['#foo', '#bar'], '#baz'];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Flattened array includes \"null\" items\n        $array = [['#foo', null], '#baz', null];\n        $this->assertEquals(['#foo', null, '#baz', null], Arr::flatten($array));\n\n        // Sets of nested arrays are flattened\n        $array = [['#foo', '#bar'], ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Deeply nested arrays are flattened\n        $array = [['#foo', ['#bar']], ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Nested arrays are flattened alongside arrays\n        $array = [new Collection(['#foo', '#bar']), ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Nested arrays containing plain arrays are flattened\n        $array = [new Collection(['#foo', ['#bar']]), ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Nested arrays containing arrays are flattened\n        $array = [['#foo', new Collection(['#bar'])], ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#baz'], Arr::flatten($array));\n\n        // Nested arrays containing arrays containing arrays are flattened\n        $array = [['#foo', new Collection(['#bar', ['#zap']])], ['#baz']];\n        $this->assertEquals(['#foo', '#bar', '#zap', '#baz'], Arr::flatten($array));\n    }\n\n    public function testFlattenWithDepth()\n    {\n        // No depth flattens recursively\n        $array = [['#foo', ['#bar', ['#baz']]], '#zap'];\n        $this->assertEquals(['#foo', '#bar', '#baz', '#zap'], Arr::flatten($array));\n\n        // Specifying a depth only flattens to that depth\n        $array = [['#foo', ['#bar', ['#baz']]], '#zap'];\n        $this->assertEquals(['#foo', ['#bar', ['#baz']], '#zap'], Arr::flatten($array, 1));\n\n        $array = [['#foo', ['#bar', ['#baz']]], '#zap'];\n        $this->assertEquals(['#foo', '#bar', ['#baz'], '#zap'], Arr::flatten($array, 2));\n    }\n\n    public function testGet()\n    {\n        $array = ['products.desk' => ['price' => 100]];\n        $this->assertEquals(['price' => 100], Arr::get($array, 'products.desk'));\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        $value = Arr::get($array, 'products.desk');\n        $this->assertEquals(['price' => 100], $value);\n\n        // Test null array values\n        $array = ['foo' => null, 'bar' => ['baz' => null]];\n        $this->assertNull(Arr::get($array, 'foo', 'default'));\n        $this->assertNull(Arr::get($array, 'bar.baz', 'default'));\n\n        // Test direct ArrayAccess object\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        $arrayAccessObject = new ArrayObject($array);\n        $value = Arr::get($arrayAccessObject, 'products.desk');\n        $this->assertEquals(['price' => 100], $value);\n\n        // Test array containing ArrayAccess object\n        $arrayAccessChild = new ArrayObject(['products' => ['desk' => ['price' => 100]]]);\n        $array = ['child' => $arrayAccessChild];\n        $value = Arr::get($array, 'child.products.desk');\n        $this->assertEquals(['price' => 100], $value);\n\n        // Test array containing multiple nested ArrayAccess objects\n        $arrayAccessChild = new ArrayObject(['products' => ['desk' => ['price' => 100]]]);\n        $arrayAccessParent = new ArrayObject(['child' => $arrayAccessChild]);\n        $array = ['parent' => $arrayAccessParent];\n        $value = Arr::get($array, 'parent.child.products.desk');\n        $this->assertEquals(['price' => 100], $value);\n\n        // Test missing ArrayAccess object field\n        $arrayAccessChild = new ArrayObject(['products' => ['desk' => ['price' => 100]]]);\n        $arrayAccessParent = new ArrayObject(['child' => $arrayAccessChild]);\n        $array = ['parent' => $arrayAccessParent];\n        $value = Arr::get($array, 'parent.child.desk');\n        $this->assertNull($value);\n\n        // Test missing ArrayAccess object field\n        $arrayAccessObject = new ArrayObject(['products' => ['desk' => null]]);\n        $array = ['parent' => $arrayAccessObject];\n        $value = Arr::get($array, 'parent.products.desk.price');\n        $this->assertNull($value);\n\n        // Test null ArrayAccess object fields\n        $array = new ArrayObject(['foo' => null, 'bar' => new ArrayObject(['baz' => null])]);\n        $this->assertNull(Arr::get($array, 'foo', 'default'));\n        $this->assertNull(Arr::get($array, 'bar.baz', 'default'));\n\n        // Test null key returns the whole array\n        $array = ['foo', 'bar'];\n        $this->assertEquals($array, Arr::get($array, null));\n\n        // Test $array not an array\n        $this->assertSame('default', Arr::get(null, 'foo', 'default'));\n        $this->assertSame('default', Arr::get(false, 'foo', 'default'));\n\n        // Test $array not an array and key is null\n        $this->assertSame('default', Arr::get(null, null, 'default'));\n\n        // Test $array is empty and key is null\n        $this->assertEmpty(Arr::get([], null));\n        $this->assertEmpty(Arr::get([], null, 'default'));\n\n        // Test numeric keys\n        $array = [\n            'products' => [\n                ['name' => 'desk'],\n                ['name' => 'chair'],\n            ],\n        ];\n        $this->assertSame('desk', Arr::get($array, 'products.0.name'));\n        $this->assertSame('chair', Arr::get($array, 'products.1.name'));\n\n        // Test return default value for non-existing key.\n        $array = ['names' => ['developer' => 'taylor']];\n        $this->assertSame('dayle', Arr::get($array, 'names.otherDeveloper', 'dayle'));\n        $this->assertSame('dayle', Arr::get($array, 'names.otherDeveloper', function () {\n            return 'dayle';\n        }));\n\n        // Test array has a null key\n        $this->assertSame('bar', Arr::get(['' => 'bar'], ''));\n        $this->assertSame('bar', Arr::get(['' => ['' => 'bar']], '.'));\n    }\n\n    public function testItGetsAString()\n    {\n        $test_array = ['string' => 'foo bar', 'integer' => 1234];\n\n        // Test string values are returned as strings\n        $this->assertSame(\n            'foo bar', Arr::string($test_array, 'string')\n        );\n\n        // Test that default string values are returned for missing keys\n        $this->assertSame(\n            'default', Arr::string($test_array, 'missing_key', 'default')\n        );\n\n        // Test that an exception is raised if the value is not a string\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Array value for key \\[integer\\] must be a string, (.*) found.#');\n        Arr::string($test_array, 'integer');\n    }\n\n    public function testItGetsAnInteger()\n    {\n        $test_array = ['string' => 'foo bar', 'integer' => 1234];\n\n        // Test integer values are returned as integers\n        $this->assertSame(\n            1234, Arr::integer($test_array, 'integer')\n        );\n\n        // Test that default integer values are returned for missing keys\n        $this->assertSame(\n            999, Arr::integer($test_array, 'missing_key', 999)\n        );\n\n        // Test that an exception is raised if the value is not an integer\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Array value for key \\[string\\] must be an integer, (.*) found.#');\n        Arr::integer($test_array, 'string');\n    }\n\n    public function testItGetsAFloat()\n    {\n        $test_array = ['string' => 'foo bar', 'float' => 12.34];\n\n        // Test float values are returned as floats\n        $this->assertSame(\n            12.34, Arr::float($test_array, 'float')\n        );\n\n        // Test that default float values are returned for missing keys\n        $this->assertSame(\n            56.78, Arr::float($test_array, 'missing_key', 56.78)\n        );\n\n        // Test that an exception is raised if the value is not a float\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Array value for key \\[string\\] must be a float, (.*) found.#');\n        Arr::float($test_array, 'string');\n    }\n\n    public function testItGetsABoolean()\n    {\n        $test_array = ['string' => 'foo bar',  'boolean' => true];\n\n        // Test boolean values are returned as booleans\n        $this->assertSame(\n            true, Arr::boolean($test_array, 'boolean')\n        );\n\n        // Test that default boolean values are returned for missing keys\n        $this->assertSame(\n            true, Arr::boolean($test_array, 'missing_key', true)\n        );\n\n        // Test that an exception is raised if the value is not a boolean\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Array value for key \\[string\\] must be a boolean, (.*) found.#');\n        Arr::boolean($test_array, 'string');\n    }\n\n    public function testItGetsAnArray()\n    {\n        $test_array = ['string' => 'foo bar', 'array' => ['foo', 'bar']];\n\n        // Test array values are returned as arrays\n        $this->assertSame(\n            ['foo', 'bar'], Arr::array($test_array, 'array')\n        );\n\n        // Test that default array values are returned for missing keys\n        $this->assertSame(\n            [1, 'two'], Arr::array($test_array, 'missing_key', [1, 'two'])\n        );\n\n        // Test that an exception is raised if the value is not an array\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('#^Array value for key \\[string\\] must be an array, (.*) found.#');\n        Arr::array($test_array, 'string');\n    }\n\n    public function testHas()\n    {\n        $array = ['products.desk' => ['price' => 100]];\n        $this->assertTrue(Arr::has($array, 'products.desk'));\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        $this->assertTrue(Arr::has($array, 'products.desk'));\n        $this->assertTrue(Arr::has($array, 'products.desk.price'));\n        $this->assertFalse(Arr::has($array, 'products.foo'));\n        $this->assertFalse(Arr::has($array, 'products.desk.foo'));\n\n        $array = ['foo' => null, 'bar' => ['baz' => null]];\n        $this->assertTrue(Arr::has($array, 'foo'));\n        $this->assertTrue(Arr::has($array, 'bar.baz'));\n\n        $array = new ArrayObject(['foo' => 10, 'bar' => new ArrayObject(['baz' => 10])]);\n        $this->assertTrue(Arr::has($array, 'foo'));\n        $this->assertTrue(Arr::has($array, 'bar'));\n        $this->assertTrue(Arr::has($array, 'bar.baz'));\n        $this->assertFalse(Arr::has($array, 'xxx'));\n        $this->assertFalse(Arr::has($array, 'xxx.yyy'));\n        $this->assertFalse(Arr::has($array, 'foo.xxx'));\n        $this->assertFalse(Arr::has($array, 'bar.xxx'));\n\n        $array = new ArrayObject(['foo' => null, 'bar' => new ArrayObject(['baz' => null])]);\n        $this->assertTrue(Arr::has($array, 'foo'));\n        $this->assertTrue(Arr::has($array, 'bar.baz'));\n\n        $array = ['foo', 'bar'];\n        $this->assertFalse(Arr::has($array, null));\n\n        $this->assertFalse(Arr::has(null, 'foo'));\n        $this->assertFalse(Arr::has(false, 'foo'));\n\n        $this->assertFalse(Arr::has(null, null));\n        $this->assertFalse(Arr::has([], null));\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        $this->assertTrue(Arr::has($array, ['products.desk']));\n        $this->assertTrue(Arr::has($array, ['products.desk', 'products.desk.price']));\n        $this->assertTrue(Arr::has($array, ['products', 'products']));\n        $this->assertFalse(Arr::has($array, ['foo']));\n        $this->assertFalse(Arr::has($array, []));\n        $this->assertFalse(Arr::has($array, ['products.desk', 'products.price']));\n\n        $array = [\n            'products' => [\n                ['name' => 'desk'],\n            ],\n        ];\n        $this->assertTrue(Arr::has($array, 'products.0.name'));\n        $this->assertFalse(Arr::has($array, 'products.0.price'));\n\n        $this->assertFalse(Arr::has([], [null]));\n        $this->assertFalse(Arr::has(null, [null]));\n\n        $this->assertTrue(Arr::has(['' => 'some'], ''));\n        $this->assertTrue(Arr::has(['' => 'some'], ['']));\n        $this->assertFalse(Arr::has([''], ''));\n        $this->assertFalse(Arr::has([], ''));\n        $this->assertFalse(Arr::has([], ['']));\n    }\n\n    public function testHasAllMethod()\n    {\n        $array = ['name' => 'Taylor', 'age' => '', 'city' => null];\n        $this->assertTrue(Arr::hasAll($array, 'name'));\n        $this->assertTrue(Arr::hasAll($array, 'age'));\n        $this->assertFalse(Arr::hasAll($array, ['age', 'car']));\n        $this->assertTrue(Arr::hasAll($array, 'city'));\n        $this->assertFalse(Arr::hasAll($array, ['city', 'some']));\n        $this->assertTrue(Arr::hasAll($array, ['name', 'age', 'city']));\n        $this->assertFalse(Arr::hasAll($array, ['name', 'age', 'city', 'country']));\n\n        $array = ['user' => ['name' => 'Taylor']];\n        $this->assertTrue(Arr::hasAll($array, 'user.name'));\n        $this->assertFalse(Arr::hasAll($array, 'user.age'));\n\n        $array = ['name' => 'Taylor', 'age' => '', 'city' => null];\n        $this->assertFalse(Arr::hasAll($array, 'foo'));\n        $this->assertFalse(Arr::hasAll($array, 'bar'));\n        $this->assertFalse(Arr::hasAll($array, 'baz'));\n        $this->assertFalse(Arr::hasAll($array, 'bah'));\n        $this->assertFalse(Arr::hasAll($array, ['foo', 'bar', 'baz', 'bar']));\n    }\n\n    public function testHasAnyMethod()\n    {\n        $array = ['name' => 'Taylor', 'age' => '', 'city' => null];\n        $this->assertTrue(Arr::hasAny($array, 'name'));\n        $this->assertTrue(Arr::hasAny($array, 'age'));\n        $this->assertTrue(Arr::hasAny($array, 'city'));\n        $this->assertFalse(Arr::hasAny($array, 'foo'));\n        $this->assertTrue(Arr::hasAny($array, 'name', 'email'));\n        $this->assertTrue(Arr::hasAny($array, ['name', 'email']));\n\n        $array = ['name' => 'Taylor', 'email' => 'foo'];\n        $this->assertTrue(Arr::hasAny($array, 'name', 'email'));\n        $this->assertFalse(Arr::hasAny($array, 'surname', 'password'));\n        $this->assertFalse(Arr::hasAny($array, ['surname', 'password']));\n\n        $array = ['foo' => ['bar' => null, 'baz' => '']];\n        $this->assertTrue(Arr::hasAny($array, 'foo.bar'));\n        $this->assertTrue(Arr::hasAny($array, 'foo.baz'));\n        $this->assertFalse(Arr::hasAny($array, 'foo.bax'));\n        $this->assertTrue(Arr::hasAny($array, ['foo.bax', 'foo.baz']));\n    }\n\n    public function testEvery()\n    {\n        $this->assertFalse(Arr::every([1, 2], fn ($value, $key) => is_string($value)));\n        $this->assertFalse(Arr::every(['foo', 2], fn ($value, $key) => is_string($value)));\n        $this->assertTrue(Arr::every(['foo', 'bar'], fn ($value, $key) => is_string($value)));\n    }\n\n    public function testSome()\n    {\n        $this->assertFalse(Arr::some([1, 2], fn ($value, $key) => is_string($value)));\n        $this->assertTrue(Arr::some(['foo', 2], fn ($value, $key) => is_string($value)));\n        $this->assertTrue(Arr::some(['foo', 'bar'], fn ($value, $key) => is_string($value)));\n    }\n\n    public function testIsAssoc()\n    {\n        $this->assertTrue(Arr::isAssoc(['a' => 'a', 0 => 'b']));\n        $this->assertTrue(Arr::isAssoc([1 => 'a', 0 => 'b']));\n        $this->assertTrue(Arr::isAssoc([1 => 'a', 2 => 'b']));\n        $this->assertFalse(Arr::isAssoc([0 => 'a', 1 => 'b']));\n        $this->assertFalse(Arr::isAssoc(['a', 'b']));\n\n        $this->assertFalse(Arr::isAssoc([]));\n        $this->assertFalse(Arr::isAssoc([1, 2, 3]));\n        $this->assertFalse(Arr::isAssoc(['foo', 2, 3]));\n        $this->assertFalse(Arr::isAssoc([0 => 'foo', 'bar']));\n\n        $this->assertTrue(Arr::isAssoc([1 => 'foo', 'bar']));\n        $this->assertTrue(Arr::isAssoc([0 => 'foo', 'bar' => 'baz']));\n        $this->assertTrue(Arr::isAssoc([0 => 'foo', 2 => 'bar']));\n        $this->assertTrue(Arr::isAssoc(['foo' => 'bar', 'baz' => 'qux']));\n    }\n\n    public function testIsList()\n    {\n        $this->assertTrue(Arr::isList([]));\n        $this->assertTrue(Arr::isList([1, 2, 3]));\n        $this->assertTrue(Arr::isList(['foo', 2, 3]));\n        $this->assertTrue(Arr::isList(['foo', 'bar']));\n        $this->assertTrue(Arr::isList([0 => 'foo', 'bar']));\n        $this->assertTrue(Arr::isList([0 => 'foo', 1 => 'bar']));\n\n        $this->assertFalse(Arr::isList([-1 => 1]));\n        $this->assertFalse(Arr::isList([-1 => 1, 0 => 2]));\n        $this->assertFalse(Arr::isList([1 => 'foo', 'bar']));\n        $this->assertFalse(Arr::isList([1 => 'foo', 0 => 'bar']));\n        $this->assertFalse(Arr::isList([0 => 'foo', 'bar' => 'baz']));\n        $this->assertFalse(Arr::isList([0 => 'foo', 2 => 'bar']));\n        $this->assertFalse(Arr::isList(['foo' => 'bar', 'baz' => 'qux']));\n    }\n\n    public function testOnly()\n    {\n        $array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];\n        $array = Arr::only($array, ['name', 'price']);\n        $this->assertEquals(['name' => 'Desk', 'price' => 100], $array);\n        $this->assertEmpty(Arr::only($array, ['nonExistingKey']));\n\n        $this->assertEmpty(Arr::only($array, null));\n\n        // Test with array having numeric keys\n        $this->assertEquals(['foo'], Arr::only(['foo', 'bar', 'baz'], 0));\n        $this->assertEquals([1 => 'bar', 2 => 'baz'], Arr::only(['foo', 'bar', 'baz'], [1, 2]));\n        $this->assertEmpty(Arr::only(['foo', 'bar', 'baz'], [3]));\n\n        // Test with array having numeric key and string key\n        $this->assertEquals(['foo'], Arr::only(['foo', 'bar' => 'baz'], 0));\n        $this->assertEquals(['bar' => 'baz'], Arr::only(['foo', 'bar' => 'baz'], 'bar'));\n    }\n\n    public function testOnlyValues()\n    {\n        $array = ['name' => 'taylor', 'age' => 26, 'city' => 'austin'];\n        $this->assertEquals(['age' => 26], Arr::onlyValues($array, [26]));\n        $this->assertEquals(['age' => 26], Arr::onlyValues($array, 26));\n\n        $array = ['foo', 'bar', 'baz', 'qux'];\n        $this->assertEquals([0 => 'foo', 2 => 'baz'], Arr::onlyValues($array, ['foo', 'baz']));\n        $this->assertEquals([2 => 'baz'], Arr::onlyValues($array, 'baz'));\n\n        $array = [1, 2, 3, 4, 5];\n        $this->assertEquals([2 => 3, 3 => 4], Arr::onlyValues($array, [3, 4]));\n\n        $array = ['a' => 1, 'b' => 2, 'c' => 1, 'd' => 3];\n        $this->assertEquals(['a' => 1, 'c' => 1], Arr::onlyValues($array, 1));\n\n        $this->assertEquals([], Arr::onlyValues([], 'foo'));\n        $this->assertEquals([], Arr::onlyValues(['foo', 'bar'], []));\n\n        $array = [1, '1', 2, '2', 3];\n        $this->assertEquals([0 => 1, 2 => 2, 4 => 3], Arr::onlyValues($array, [1, 2, 3], true));\n        $this->assertEquals([0 => 1, 1 => '1', 2 => 2, 3 => '2', 4 => 3], Arr::onlyValues($array, [1, 2, 3]));\n\n        $array = ['a' => true, 'b' => false, 'c' => 1, 'd' => 0];\n        $this->assertEquals(['c' => 1, 'd' => 0], Arr::onlyValues($array, [1, 0], true));\n        $this->assertEquals(['a' => true, 'b' => false, 'c' => 1, 'd' => 0], Arr::onlyValues($array, [1, 0]));\n    }\n\n    public function testPluck()\n    {\n        $data = [\n            'post-1' => [\n                'comments' => [\n                    'tags' => [\n                        '#foo', '#bar',\n                    ],\n                ],\n            ],\n            'post-2' => [\n                'comments' => [\n                    'tags' => [\n                        '#baz',\n                    ],\n                ],\n            ],\n        ];\n\n        $this->assertEquals([\n            0 => [\n                'tags' => [\n                    '#foo', '#bar',\n                ],\n            ],\n            1 => [\n                'tags' => [\n                    '#baz',\n                ],\n            ],\n        ], Arr::pluck($data, 'comments'));\n\n        $this->assertEquals([['#foo', '#bar'], ['#baz']], Arr::pluck($data, 'comments.tags'));\n        $this->assertEquals([null, null], Arr::pluck($data, 'foo'));\n        $this->assertEquals([null, null], Arr::pluck($data, 'foo.bar'));\n\n        $array = [\n            ['developer' => ['name' => 'Taylor']],\n            ['developer' => ['name' => 'Abigail']],\n        ];\n\n        $array = Arr::pluck($array, 'developer.name');\n\n        $this->assertEquals(['Taylor', 'Abigail'], $array);\n    }\n\n    public function testPluckWithArrayValue()\n    {\n        $array = [\n            ['developer' => ['name' => 'Taylor']],\n            ['developer' => ['name' => 'Abigail']],\n        ];\n        $array = Arr::pluck($array, ['developer', 'name']);\n        $this->assertEquals(['Taylor', 'Abigail'], $array);\n    }\n\n    public function testPluckWithKeys()\n    {\n        $array = [\n            ['name' => 'Taylor', 'role' => 'developer'],\n            ['name' => 'Abigail', 'role' => 'developer'],\n        ];\n\n        $test1 = Arr::pluck($array, 'role', 'name');\n        $test2 = Arr::pluck($array, null, 'name');\n\n        $this->assertEquals([\n            'Taylor' => 'developer',\n            'Abigail' => 'developer',\n        ], $test1);\n\n        $this->assertEquals([\n            'Taylor' => ['name' => 'Taylor', 'role' => 'developer'],\n            'Abigail' => ['name' => 'Abigail', 'role' => 'developer'],\n        ], $test2);\n    }\n\n    public function testPluckWithCarbonKeys()\n    {\n        $array = [\n            ['start' => new Carbon('2017-07-25 00:00:00'), 'end' => new Carbon('2017-07-30 00:00:00')],\n        ];\n        $array = Arr::pluck($array, 'end', 'start');\n        $this->assertEquals(['2017-07-25 00:00:00' => '2017-07-30 00:00:00'], $array);\n    }\n\n    public function testArrayPluckWithArrayAndObjectValues()\n    {\n        $array = [(object) ['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']];\n        $this->assertEquals(['taylor', 'dayle'], Arr::pluck($array, 'name'));\n        $this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], Arr::pluck($array, 'email', 'name'));\n    }\n\n    public function testArrayPluckWithNestedKeys()\n    {\n        $array = [['user' => ['taylor', 'otwell']], ['user' => ['dayle', 'rees']]];\n        $this->assertEquals(['taylor', 'dayle'], Arr::pluck($array, 'user.0'));\n        $this->assertEquals(['taylor', 'dayle'], Arr::pluck($array, ['user', 0]));\n        $this->assertEquals(['taylor' => 'otwell', 'dayle' => 'rees'], Arr::pluck($array, 'user.1', 'user.0'));\n        $this->assertEquals(['taylor' => 'otwell', 'dayle' => 'rees'], Arr::pluck($array, ['user', 1], ['user', 0]));\n    }\n\n    public function testArrayPluckWithNestedArrays()\n    {\n        $array = [\n            [\n                'account' => 'a',\n                'users' => [\n                    ['first' => 'taylor', 'last' => 'otwell', 'email' => 'taylorotwell@gmail.com'],\n                ],\n            ],\n            [\n                'account' => 'b',\n                'users' => [\n                    ['first' => 'abigail', 'last' => 'otwell'],\n                    ['first' => 'dayle', 'last' => 'rees'],\n                ],\n            ],\n        ];\n\n        $this->assertEquals([['taylor'], ['abigail', 'dayle']], Arr::pluck($array, 'users.*.first'));\n        $this->assertEquals(['a' => ['taylor'], 'b' => ['abigail', 'dayle']], Arr::pluck($array, 'users.*.first', 'account'));\n        $this->assertEquals([['taylorotwell@gmail.com'], [null, null]], Arr::pluck($array, 'users.*.email'));\n    }\n\n    public function testMap()\n    {\n        $data = ['first' => 'taylor', 'last' => 'otwell'];\n        $mapped = Arr::map($data, function ($value, $key) {\n            return $key.'-'.strrev($value);\n        });\n        $this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $mapped);\n        $this->assertEquals(['first' => 'taylor', 'last' => 'otwell'], $data);\n    }\n\n    public function testMapWithEmptyArray()\n    {\n        $mapped = Arr::map([], static function ($value, $key) {\n            return $key.'-'.$value;\n        });\n        $this->assertEquals([], $mapped);\n    }\n\n    public function testMapNullValues()\n    {\n        $data = ['first' => 'taylor', 'last' => null];\n        $mapped = Arr::map($data, static function ($value, $key) {\n            return $key.'-'.$value;\n        });\n        $this->assertEquals(['first' => 'first-taylor', 'last' => 'last-'], $mapped);\n    }\n\n    public function testMapWithKeys()\n    {\n        $data = [\n            ['name' => 'Blastoise', 'type' => 'Water', 'idx' => 9],\n            ['name' => 'Charmander', 'type' => 'Fire', 'idx' => 4],\n            ['name' => 'Dragonair', 'type' => 'Dragon', 'idx' => 148],\n        ];\n\n        $data = Arr::mapWithKeys($data, function ($pokemon) {\n            return [$pokemon['name'] => $pokemon['type']];\n        });\n\n        $this->assertEquals(\n            ['Blastoise' => 'Water', 'Charmander' => 'Fire', 'Dragonair' => 'Dragon'],\n            $data\n        );\n    }\n\n    public function testMapByReference()\n    {\n        $data = ['first' => 'taylor', 'last' => 'otwell'];\n        $mapped = Arr::map($data, 'strrev');\n\n        $this->assertEquals(['first' => 'rolyat', 'last' => 'llewto'], $mapped);\n        $this->assertEquals(['first' => 'taylor', 'last' => 'otwell'], $data);\n    }\n\n    public function testMapSpread()\n    {\n        $c = [[1, 'a'], [2, 'b']];\n\n        $result = Arr::mapSpread($c, function ($number, $character) {\n            return \"{$number}-{$character}\";\n        });\n        $this->assertEquals(['1-a', '2-b'], $result);\n\n        $result = Arr::mapSpread($c, function ($number, $character, $key) {\n            return \"{$number}-{$character}-{$key}\";\n        });\n        $this->assertEquals(['1-a-0', '2-b-1'], $result);\n    }\n\n    #[IgnoreDeprecations]\n    public function testPrepend()\n    {\n        $array = Arr::prepend(['one', 'two', 'three', 'four'], 'zero');\n        $this->assertEquals(['zero', 'one', 'two', 'three', 'four'], $array);\n\n        $array = Arr::prepend(['one' => 1, 'two' => 2], 0, 'zero');\n        $this->assertEquals(['zero' => 0, 'one' => 1, 'two' => 2], $array);\n\n        $array = Arr::prepend(['one' => 1, 'two' => 2], 0, '');\n        $this->assertEquals(['' => 0, 'one' => 1, 'two' => 2], $array);\n\n        $array = Arr::prepend(['one' => 1, 'two' => 2], 0, null);\n        $this->assertEquals([null => 0, 'one' => 1, 'two' => 2], $array);\n\n        $array = Arr::prepend(['one', 'two'], null, '');\n        $this->assertEquals(['' => null, 'one', 'two'], $array);\n\n        $array = Arr::prepend([], 'zero');\n        $this->assertEquals(['zero'], $array);\n\n        $array = Arr::prepend([''], 'zero');\n        $this->assertEquals(['zero', ''], $array);\n\n        $array = Arr::prepend(['one', 'two'], ['zero']);\n        $this->assertEquals([['zero'], 'one', 'two'], $array);\n\n        $array = Arr::prepend(['one', 'two'], ['zero'], 'key');\n        $this->assertEquals(['key' => ['zero'], 'one', 'two'], $array);\n\n        $array = Arr::prepend(['one', 'two'], ['zero'], '');\n        $this->assertEquals(['one', 'two', '' => ['zero']], $array);\n\n        $array = Arr::prepend(['one', 'two', '' => 'three'], ['zero'], '');\n        $this->assertEquals(['one', 'two', '' => ['zero']], $array);\n\n        $array = Arr::prepend(['one', 'two'], ['zero'], null);\n        $this->assertEquals(['one', 'two', null => ['zero']], $array);\n\n        $array = Arr::prepend(['one', 'two', '' => 'three'], ['zero'], null);\n        $this->assertEquals(['one', 'two', null => ['zero']], $array);\n    }\n\n    public function testPull()\n    {\n        $array = ['name' => 'Desk', 'price' => 100];\n        $name = Arr::pull($array, 'name');\n        $this->assertSame('Desk', $name);\n        $this->assertSame(['price' => 100], $array);\n\n        // Only works on first level keys\n        $array = ['joe@example.com' => 'Joe', 'jane@localhost' => 'Jane'];\n        $name = Arr::pull($array, 'joe@example.com');\n        $this->assertSame('Joe', $name);\n        $this->assertSame(['jane@localhost' => 'Jane'], $array);\n\n        // Does not work for nested keys\n        $array = ['emails' => ['joe@example.com' => 'Joe', 'jane@localhost' => 'Jane']];\n        $name = Arr::pull($array, 'emails.joe@example.com');\n        $this->assertNull($name);\n        $this->assertSame(['emails' => ['joe@example.com' => 'Joe', 'jane@localhost' => 'Jane']], $array);\n\n        // Works with int keys\n        $array = ['First', 'Second'];\n        $first = Arr::pull($array, 0);\n        $this->assertSame('First', $first);\n        $this->assertSame([1 => 'Second'], $array);\n    }\n\n    public function testQuery()\n    {\n        $this->assertSame('', Arr::query([]));\n        $this->assertSame('foo=bar', Arr::query(['foo' => 'bar']));\n        $this->assertSame('foo=bar&bar=baz', Arr::query(['foo' => 'bar', 'bar' => 'baz']));\n        $this->assertSame('foo=bar&bar=1', Arr::query(['foo' => 'bar', 'bar' => true]));\n        $this->assertSame('foo=bar', Arr::query(['foo' => 'bar', 'bar' => null]));\n        $this->assertSame('foo=bar&bar=', Arr::query(['foo' => 'bar', 'bar' => '']));\n    }\n\n    public function testRandom()\n    {\n        $random = Arr::random(['foo', 'bar', 'baz']);\n        $this->assertContains($random, ['foo', 'bar', 'baz']);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], 0);\n        $this->assertIsArray($random);\n        $this->assertCount(0, $random);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], 1);\n        $this->assertIsArray($random);\n        $this->assertCount(1, $random);\n        $this->assertContains($random[0], ['foo', 'bar', 'baz']);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], 2);\n        $this->assertIsArray($random);\n        $this->assertCount(2, $random);\n        $this->assertContains($random[0], ['foo', 'bar', 'baz']);\n        $this->assertContains($random[1], ['foo', 'bar', 'baz']);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], '0');\n        $this->assertIsArray($random);\n        $this->assertCount(0, $random);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], '1');\n        $this->assertIsArray($random);\n        $this->assertCount(1, $random);\n        $this->assertContains($random[0], ['foo', 'bar', 'baz']);\n\n        $random = Arr::random(['foo', 'bar', 'baz'], '2');\n        $this->assertIsArray($random);\n        $this->assertCount(2, $random);\n        $this->assertContains($random[0], ['foo', 'bar', 'baz']);\n        $this->assertContains($random[1], ['foo', 'bar', 'baz']);\n\n        // preserve keys\n        $random = Arr::random(['one' => 'foo', 'two' => 'bar', 'three' => 'baz'], 2, true);\n        $this->assertIsArray($random);\n        $this->assertCount(2, $random);\n        $this->assertCount(2, array_intersect_assoc(['one' => 'foo', 'two' => 'bar', 'three' => 'baz'], $random));\n    }\n\n    public function testRandomNotIncrementingKeys()\n    {\n        $random = Arr::random(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz']);\n        $this->assertContains($random, ['foo', 'bar', 'baz']);\n    }\n\n    public function testRandomOnEmptyArray()\n    {\n        $random = Arr::random([], 0);\n        $this->assertIsArray($random);\n        $this->assertCount(0, $random);\n\n        $random = Arr::random([], '0');\n        $this->assertIsArray($random);\n        $this->assertCount(0, $random);\n    }\n\n    public function testRandomThrowsAnErrorWhenRequestingMoreItemsThanAreAvailable()\n    {\n        $exceptions = 0;\n\n        try {\n            Arr::random([]);\n        } catch (InvalidArgumentException) {\n            $exceptions++;\n        }\n\n        try {\n            Arr::random([], 1);\n        } catch (InvalidArgumentException) {\n            $exceptions++;\n        }\n\n        try {\n            Arr::random([], 2);\n        } catch (InvalidArgumentException) {\n            $exceptions++;\n        }\n\n        $this->assertSame(3, $exceptions);\n    }\n\n    public function testSet()\n    {\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::set($array, 'products.desk.price', 200);\n        $this->assertEquals(['products' => ['desk' => ['price' => 200]]], $array);\n\n        // No key is given\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::set($array, null, ['price' => 300]);\n        $this->assertSame(['price' => 300], $array);\n\n        // The key doesn't exist at the depth\n        $array = ['products' => 'desk'];\n        Arr::set($array, 'products.desk.price', 200);\n        $this->assertSame(['products' => ['desk' => ['price' => 200]]], $array);\n\n        // No corresponding key exists\n        $array = ['products'];\n        Arr::set($array, 'products.desk.price', 200);\n        $this->assertSame(['products', 'products' => ['desk' => ['price' => 200]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::set($array, 'table', 500);\n        $this->assertSame(['products' => ['desk' => ['price' => 100]], 'table' => 500], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::set($array, 'table.price', 350);\n        $this->assertSame(['products' => ['desk' => ['price' => 100]], 'table' => ['price' => 350]], $array);\n\n        $array = [];\n        Arr::set($array, 'products.desk.price', 200);\n        $this->assertSame(['products' => ['desk' => ['price' => 200]]], $array);\n\n        // Override\n        $array = ['products' => 'table'];\n        Arr::set($array, 'products.desk.price', 300);\n        $this->assertSame(['products' => ['desk' => ['price' => 300]]], $array);\n\n        $array = [1 => 'test'];\n        $this->assertEquals([1 => 'hAz'], Arr::set($array, 1, 'hAz'));\n    }\n\n    public function testShuffleProducesDifferentShuffles()\n    {\n        $input = range('a', 'z');\n\n        $this->assertFalse(\n            Arr::shuffle($input) === Arr::shuffle($input) && Arr::shuffle($input) === Arr::shuffle($input),\n            \"The shuffles produced the same output each time, which shouldn't happen.\"\n        );\n    }\n\n    public function testShuffleActuallyShuffles()\n    {\n        $input = range('a', 'z');\n\n        $this->assertFalse(\n            Arr::shuffle($input) === $input && Arr::shuffle($input) === $input,\n            \"The shuffles were unshuffled each time, which shouldn't happen.\"\n        );\n    }\n\n    public function testShuffleKeepsSameValues()\n    {\n        $input = range('a', 'z');\n        $shuffled = Arr::shuffle($input);\n        sort($shuffled);\n\n        $this->assertEquals($input, $shuffled);\n    }\n\n    public function testSoleReturnsFirstItemInCollectionIfOnlyOneExists()\n    {\n        $this->assertSame('foo', Arr::sole(['foo']));\n\n        $array = [\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ];\n\n        $this->assertSame(\n            ['name' => 'foo'],\n            Arr::sole($array, fn (array $value) => $value['name'] === 'foo')\n        );\n    }\n\n    public function testSoleThrowsExceptionIfNoItemsExist()\n    {\n        $this->expectException(ItemNotFoundException::class);\n\n        Arr::sole(['foo'], fn (string $value) => $value === 'baz');\n    }\n\n    public function testSoleThrowsExceptionIfMoreThanOneItemExists()\n    {\n        $this->expectExceptionObject(new MultipleItemsFoundException(2));\n\n        Arr::sole(['baz', 'foo', 'baz'], fn (string $value) => $value === 'baz');\n    }\n\n    public function testEmptyShuffle()\n    {\n        $this->assertEquals([], Arr::shuffle([]));\n    }\n\n    public function testSort()\n    {\n        $unsorted = [\n            ['name' => 'Desk'],\n            ['name' => 'Chair'],\n        ];\n\n        $expected = [\n            ['name' => 'Chair'],\n            ['name' => 'Desk'],\n        ];\n\n        $sorted = array_values(Arr::sort($unsorted));\n        $this->assertEquals($expected, $sorted);\n\n        // sort with closure\n        $sortedWithClosure = array_values(Arr::sort($unsorted, function ($value) {\n            return $value['name'];\n        }));\n        $this->assertEquals($expected, $sortedWithClosure);\n\n        // sort with dot notation\n        $sortedWithDotNotation = array_values(Arr::sort($unsorted, 'name'));\n        $this->assertEquals($expected, $sortedWithDotNotation);\n    }\n\n    public function testSortDesc()\n    {\n        $unsorted = [\n            ['name' => 'Chair'],\n            ['name' => 'Desk'],\n        ];\n\n        $expected = [\n            ['name' => 'Desk'],\n            ['name' => 'Chair'],\n        ];\n\n        $sorted = array_values(Arr::sortDesc($unsorted));\n        $this->assertEquals($expected, $sorted);\n\n        // sort with closure\n        $sortedWithClosure = array_values(Arr::sortDesc($unsorted, function ($value) {\n            return $value['name'];\n        }));\n        $this->assertEquals($expected, $sortedWithClosure);\n\n        // sort with dot notation\n        $sortedWithDotNotation = array_values(Arr::sortDesc($unsorted, 'name'));\n        $this->assertEquals($expected, $sortedWithDotNotation);\n    }\n\n    public function testSortRecursive()\n    {\n        $array = [\n            'users' => [\n                [\n                    // should sort associative arrays by keys\n                    'name' => 'joe',\n                    'mail' => 'joe@example.com',\n                    // should sort deeply nested arrays\n                    'numbers' => [2, 1, 0],\n                ],\n                [\n                    'name' => 'jane',\n                    'age' => 25,\n                ],\n            ],\n            'repositories' => [\n                // should use weird `sort()` behavior on arrays of arrays\n                ['id' => 1],\n                ['id' => 0],\n            ],\n            // should sort non-associative arrays by value\n            20 => [2, 1, 0],\n            30 => [\n                // should sort non-incrementing numerical keys by keys\n                2 => 'a',\n                1 => 'b',\n                0 => 'c',\n            ],\n        ];\n\n        $expect = [\n            20 => [0, 1, 2],\n            30 => [\n                0 => 'c',\n                1 => 'b',\n                2 => 'a',\n            ],\n            'repositories' => [\n                ['id' => 0],\n                ['id' => 1],\n            ],\n            'users' => [\n                [\n                    'age' => 25,\n                    'name' => 'jane',\n                ],\n                [\n                    'mail' => 'joe@example.com',\n                    'name' => 'joe',\n                    'numbers' => [0, 1, 2],\n                ],\n            ],\n        ];\n\n        $this->assertEquals($expect, Arr::sortRecursive($array));\n    }\n\n    public function testSortRecursiveDesc()\n    {\n        $array = [\n            'empty' => [],\n            'nested' => [\n                'level1' => [\n                    'level2' => [\n                        'level3' => [2, 3, 1],\n                    ],\n                    'values' => [4, 5, 6],\n                ],\n            ],\n            'mixed' => [\n                'a' => 1,\n                2 => 'b',\n                'c' => 3,\n                1 => 'd',\n            ],\n            'numbered_index' => [\n                1 => 'e',\n                3 => 'c',\n                4 => 'b',\n                5 => 'a',\n                2 => 'd',\n            ],\n        ];\n\n        $expect = [\n            'empty' => [],\n            'mixed' => [\n                'c' => 3,\n                'a' => 1,\n                2 => 'b',\n                1 => 'd',\n            ],\n            'nested' => [\n                'level1' => [\n                    'values' => [6, 5, 4],\n                    'level2' => [\n                        'level3' => [3, 2, 1],\n                    ],\n                ],\n            ],\n            'numbered_index' => [\n                5 => 'a',\n                4 => 'b',\n                3 => 'c',\n                2 => 'd',\n                1 => 'e',\n            ],\n        ];\n\n        $this->assertEquals($expect, Arr::sortRecursiveDesc($array));\n    }\n\n    public function testToCssClasses()\n    {\n        $classes = Arr::toCssClasses([\n            'font-bold',\n            'mt-4',\n        ]);\n\n        $this->assertSame('font-bold mt-4', $classes);\n\n        $classes = Arr::toCssClasses([\n            'font-bold',\n            'mt-4',\n            'ml-2' => true,\n            'mr-2' => false,\n        ]);\n\n        $this->assertSame('font-bold mt-4 ml-2', $classes);\n    }\n\n    public function testToCssStyles()\n    {\n        $styles = Arr::toCssStyles([\n            'font-weight: bold',\n            'margin-top: 4px;',\n        ]);\n\n        $this->assertSame('font-weight: bold; margin-top: 4px;', $styles);\n\n        $styles = Arr::toCssStyles([\n            'font-weight: bold;',\n            'margin-top: 4px',\n            'margin-left: 2px;' => true,\n            'margin-right: 2px' => false,\n        ]);\n\n        $this->assertSame('font-weight: bold; margin-top: 4px; margin-left: 2px;', $styles);\n    }\n\n    public function testWhere()\n    {\n        $array = [100, '200', 300, '400', 500];\n\n        $array = Arr::where($array, function ($value, $key) {\n            return is_string($value);\n        });\n\n        $this->assertEquals([1 => '200', 3 => '400'], $array);\n    }\n\n    public function testWhereKey()\n    {\n        $array = ['10' => 1, 'foo' => 3, 20 => 2];\n\n        $array = Arr::where($array, function ($value, $key) {\n            return is_numeric($key);\n        });\n\n        $this->assertEquals(['10' => 1, 20 => 2], $array);\n    }\n\n    public function testForget()\n    {\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::forget($array, null);\n        $this->assertEquals(['products' => ['desk' => ['price' => 100]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::forget($array, []);\n        $this->assertEquals(['products' => ['desk' => ['price' => 100]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::forget($array, 'products.desk');\n        $this->assertEquals(['products' => []], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::forget($array, 'products.desk.price');\n        $this->assertEquals(['products' => ['desk' => []]], $array);\n\n        $array = ['products' => ['desk' => ['price' => 100]]];\n        Arr::forget($array, 'products.final.price');\n        $this->assertEquals(['products' => ['desk' => ['price' => 100]]], $array);\n\n        $array = ['shop' => ['cart' => [150 => 0]]];\n        Arr::forget($array, 'shop.final.cart');\n        $this->assertEquals(['shop' => ['cart' => [150 => 0]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => ['original' => 50, 'taxes' => 60]]]];\n        Arr::forget($array, 'products.desk.price.taxes');\n        $this->assertEquals(['products' => ['desk' => ['price' => ['original' => 50]]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => ['original' => 50, 'taxes' => 60]]]];\n        Arr::forget($array, 'products.desk.final.taxes');\n        $this->assertEquals(['products' => ['desk' => ['price' => ['original' => 50, 'taxes' => 60]]]], $array);\n\n        $array = ['products' => ['desk' => ['price' => 50], '' => 'something']];\n        Arr::forget($array, ['products.amount.all', 'products.desk.price']);\n        $this->assertEquals(['products' => ['desk' => [], '' => 'something']], $array);\n\n        // Only works on first level keys\n        $array = ['joe@example.com' => 'Joe', 'jane@example.com' => 'Jane'];\n        Arr::forget($array, 'joe@example.com');\n        $this->assertEquals(['jane@example.com' => 'Jane'], $array);\n\n        // Does not work for nested keys\n        $array = ['emails' => ['joe@example.com' => ['name' => 'Joe'], 'jane@localhost' => ['name' => 'Jane']]];\n        Arr::forget($array, ['emails.joe@example.com', 'emails.jane@localhost']);\n        $this->assertEquals(['emails' => ['joe@example.com' => ['name' => 'Joe']]], $array);\n\n        $array = ['name' => 'hAz', '1' => 'test', 2 => 'bAz'];\n        Arr::forget($array, 1);\n        $this->assertEquals(['name' => 'hAz', 2 => 'bAz'], $array);\n\n        $array = [2 => [1 => 'products', 3 => 'users']];\n        Arr::forget($array, 2.3);\n        $this->assertEquals([2 => [1 => 'products']], $array);\n    }\n\n    public function testFrom()\n    {\n        $this->assertSame(['foo' => 'bar'], Arr::from(['foo' => 'bar']));\n        $this->assertSame(['foo' => 'bar'], Arr::from((object) ['foo' => 'bar']));\n        $this->assertSame(['foo' => 'bar'], Arr::from(new TestArrayableObject));\n        $this->assertSame(['foo' => 'bar'], Arr::from(new TestJsonableObject));\n        $this->assertSame(['foo' => 'bar'], Arr::from(new TestJsonSerializeObject));\n        $this->assertSame(['foo'], Arr::from(new TestJsonSerializeWithScalarValueObject));\n\n        $this->assertSame(['name' => 'A'], Arr::from(TestEnum::A));\n        $this->assertSame(['name' => 'A', 'value' => 1], Arr::from(TestBackedEnum::A));\n        $this->assertSame(['name' => 'A', 'value' => 'A'], Arr::from(TestStringBackedEnum::A));\n\n        $subject = [new stdClass, new stdClass];\n        $items = new TestTraversableAndJsonSerializableObject($subject);\n        $this->assertSame($subject, Arr::from($items));\n\n        $items = new WeakMap;\n        $items[$temp = new class {}] = 'bar';\n        $this->assertSame(['bar'], Arr::from($items));\n\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Items cannot be represented by a scalar value.');\n        Arr::from(123);\n    }\n\n    public function testWrap()\n    {\n        $string = 'a';\n        $array = ['a'];\n        $object = new stdClass;\n        $object->value = 'a';\n        $this->assertEquals(['a'], Arr::wrap($string));\n        $this->assertEquals($array, Arr::wrap($array));\n        $this->assertEquals([$object], Arr::wrap($object));\n        $this->assertEquals([], Arr::wrap(null));\n        $this->assertEquals([null], Arr::wrap([null]));\n        $this->assertEquals([null, null], Arr::wrap([null, null]));\n        $this->assertEquals([''], Arr::wrap(''));\n        $this->assertEquals([''], Arr::wrap(['']));\n        $this->assertEquals([false], Arr::wrap(false));\n        $this->assertEquals([false], Arr::wrap([false]));\n        $this->assertEquals([0], Arr::wrap(0));\n\n        $obj = new stdClass;\n        $obj->value = 'a';\n        $obj = unserialize(serialize($obj));\n        $this->assertEquals([$obj], Arr::wrap($obj));\n        $this->assertSame($obj, Arr::wrap($obj)[0]);\n    }\n\n    public function testSortByMany()\n    {\n        $unsorted = [\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 10, 'meta' => ['key' => 5]],\n            ['name' => 'Dave', 'age' => 10, 'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 2]],\n        ];\n\n        // sort using keys\n        $sorted = array_values(Arr::sort($unsorted, [\n            'name',\n            'age',\n            'meta.key',\n        ]));\n        $this->assertEquals([\n            ['name' => 'Dave', 'age' => 10, 'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 2]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 10, 'meta' => ['key' => 5]],\n        ], $sorted);\n\n        // sort with order\n        $sortedWithOrder = array_values(Arr::sort($unsorted, [\n            'name',\n            ['age', false],\n            ['meta.key', true],\n        ]));\n        $this->assertEquals([\n            ['name' => 'Dave', 'age' => 10, 'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 10, 'meta' => ['key' => 5]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 2]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 3]],\n        ], $sortedWithOrder);\n\n        // sort using callable\n        $sortedWithCallable = array_values(Arr::sort($unsorted, [\n            function ($a, $b) {\n                return $a['name'] <=> $b['name'];\n            },\n            function ($a, $b) {\n                return $b['age'] <=> $a['age'];\n            },\n            ['meta.key', true],\n        ]));\n        $this->assertEquals([\n            ['name' => 'Dave', 'age' => 10, 'meta' => ['key' => 3]],\n            ['name' => 'John', 'age' => 10, 'meta' => ['key' => 5]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 2]],\n            ['name' => 'John', 'age' => 8,  'meta' => ['key' => 3]],\n        ], $sortedWithCallable);\n    }\n\n    public function testKeyBy()\n    {\n        $array = [\n            ['id' => '123', 'data' => 'abc'],\n            ['id' => '345', 'data' => 'def'],\n            ['id' => '498', 'data' => 'hgi'],\n        ];\n\n        $this->assertEquals([\n            '123' => ['id' => '123', 'data' => 'abc'],\n            '345' => ['id' => '345', 'data' => 'def'],\n            '498' => ['id' => '498', 'data' => 'hgi'],\n        ], Arr::keyBy($array, 'id'));\n    }\n\n    public function testPrependKeysWith()\n    {\n        $array = [\n            'id' => '123',\n            'data' => '456',\n            'list' => [1, 2, 3],\n            'meta' => [\n                'key' => 1,\n            ],\n        ];\n\n        $this->assertEquals([\n            'test.id' => '123',\n            'test.data' => '456',\n            'test.list' => [1, 2, 3],\n            'test.meta' => [\n                'key' => 1,\n            ],\n        ], Arr::prependKeysWith($array, 'test.'));\n    }\n\n    public function testTake(): void\n    {\n        $array = [1, 2, 3, 4, 5, 6];\n\n        // Test with a positive limit, should return the first 'limit' elements.\n        $this->assertEquals([1, 2, 3], Arr::take($array, 3));\n\n        // Test with a negative limit, should return the last 'abs(limit)' elements.\n        $this->assertEquals([4, 5, 6], Arr::take($array, -3));\n\n        // Test with zero limit, should return an empty array.\n        $this->assertEquals([], Arr::take($array, 0));\n\n        // Test with a limit greater than the array size, should return the entire array.\n        $this->assertEquals([1, 2, 3, 4, 5, 6], Arr::take($array, 10));\n\n        // Test with a negative limit greater than the array size, should return the entire array.\n        $this->assertEquals([1, 2, 3, 4, 5, 6], Arr::take($array, -10));\n    }\n\n    public function testSelect()\n    {\n        $array = [\n            [\n                'name' => 'Taylor',\n                'role' => 'Developer',\n                'age' => 1,\n            ],\n            [\n                'name' => 'Abigail',\n                'role' => 'Infrastructure',\n                'age' => 2,\n            ],\n        ];\n\n        $this->assertEquals([\n            [\n                'name' => 'Taylor',\n                'age' => 1,\n            ],\n            [\n                'name' => 'Abigail',\n                'age' => 2,\n            ],\n        ], Arr::select($array, ['name', 'age']));\n\n        $this->assertEquals([\n            [\n                'name' => 'Taylor',\n            ],\n            [\n                'name' => 'Abigail',\n            ],\n        ], Arr::select($array, 'name'));\n\n        $this->assertEquals([\n            [],\n            [],\n        ], Arr::select($array, 'nonExistingKey'));\n\n        $this->assertEquals([\n            [],\n            [],\n        ], Arr::select($array, null));\n    }\n\n    public function testReject()\n    {\n        $array = [1, 2, 3, 4, 5, 6];\n\n        // Test rejection behavior (removing even numbers)\n        $result = Arr::reject($array, function ($value) {\n            return $value % 2 === 0;\n        });\n\n        $this->assertEquals([\n            0 => 1,\n            2 => 3,\n            4 => 5,\n        ], $result);\n\n        // Test key preservation with associative array\n        $assocArray = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];\n\n        $result = Arr::reject($assocArray, function ($value) {\n            return $value > 2;\n        });\n\n        $this->assertEquals([\n            'a' => 1,\n            'b' => 2,\n        ], $result);\n    }\n\n    public function testPartition()\n    {\n        $array = ['John', 'Jane', 'Greg'];\n\n        $result = Arr::partition($array, fn (string $value) => str_contains($value, 'J'));\n\n        $this->assertEquals([[0 => 'John', 1 => 'Jane'], [2 => 'Greg']], $result);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportBenchmarkTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Benchmark;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportBenchmarkTest extends TestCase\n{\n    public function testMeasure(): void\n    {\n        $this->assertIsNumeric(Benchmark::measure(fn () => 1 + 1));\n\n        $this->assertIsArray(Benchmark::measure([\n            'first' => fn () => 1 + 1,\n            'second' => fn () => 2 + 2,\n        ], 3));\n    }\n\n    public function testValue(): void\n    {\n        $this->assertIsArray(Benchmark::value(fn () => 1 + 1));\n    }\n\n    public function testMacroable(): void\n    {\n        $macroName = __FUNCTION__;\n\n        $this->assertFalse(Benchmark::hasMacro($macroName));\n\n        // Register a macro to test\n        Benchmark::macro($macroName, fn () => true);\n\n        $this->assertTrue(Benchmark::hasMacro($macroName));\n        $this->assertTrue(Benchmark::$macroName());\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportBinaryCodecTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\BinaryCodec;\nuse InvalidArgumentException;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Ramsey\\Uuid\\Uuid;\nuse Symfony\\Component\\Uid\\Ulid;\n\nclass SupportBinaryCodecTest extends TestCase\n{\n    protected function tearDown(): void\n    {\n        $reflection = new \\ReflectionClass(BinaryCodec::class);\n        $property = $reflection->getProperty('customCodecs');\n        $property->setValue(null, []);\n\n        parent::tearDown();\n    }\n\n    public function testFormatsReturnsDefaultFormats()\n    {\n        $formats = BinaryCodec::formats();\n\n        $this->assertContains('uuid', $formats);\n        $this->assertContains('ulid', $formats);\n    }\n\n    public function testRegisterAddsCustomFormat()\n    {\n        BinaryCodec::register('hex', fn ($v) => bin2hex($v ?? ''), fn ($v) => hex2bin($v ?? ''));\n\n        $this->assertContains('hex', BinaryCodec::formats());\n    }\n\n    public function testRegisterOverridesDefaultFormat()\n    {\n        BinaryCodec::register('uuid', fn ($v) => 'custom-encode', fn ($v) => 'custom-decode');\n\n        $this->assertSame('custom-encode', BinaryCodec::encode('test', 'uuid'));\n        $this->assertSame('custom-decode', BinaryCodec::decode('test', 'uuid'));\n    }\n\n    #[DataProvider('nullAndEmptyProvider')]\n    public function testEncodeReturnsNullForNullAndEmpty($value)\n    {\n        $this->assertNull(BinaryCodec::encode($value, 'uuid'));\n        $this->assertNull(BinaryCodec::encode($value, 'ulid'));\n    }\n\n    #[DataProvider('nullAndEmptyProvider')]\n    public function testDecodeReturnsNullForNullAndEmpty($value)\n    {\n        $this->assertNull(BinaryCodec::decode($value, 'uuid'));\n        $this->assertNull(BinaryCodec::decode($value, 'ulid'));\n    }\n\n    public static function nullAndEmptyProvider(): array\n    {\n        return [\n            'null' => [null],\n            'empty string' => [''],\n        ];\n    }\n\n    public function testEncodeThrowsOnInvalidFormat()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Format [invalid] is invalid.');\n\n        BinaryCodec::encode('value', 'invalid');\n    }\n\n    public function testDecodeThrowsOnInvalidFormat()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Format [invalid] is invalid.');\n\n        BinaryCodec::decode('value', 'invalid');\n    }\n\n    public function testUuidEncodeFromString()\n    {\n        $uuid = '550e8400-e29b-41d4-a716-446655440000';\n\n        $this->assertSame(Uuid::fromString($uuid)->getBytes(), BinaryCodec::encode($uuid, 'uuid'));\n    }\n\n    public function testUuidEncodeFromBinary()\n    {\n        $bytes = Uuid::fromString('550e8400-e29b-41d4-a716-446655440000')->getBytes();\n\n        $this->assertSame($bytes, BinaryCodec::encode($bytes, 'uuid'));\n    }\n\n    public function testUuidEncodeFromInstance()\n    {\n        $uuid = Uuid::fromString('550e8400-e29b-41d4-a716-446655440000');\n\n        $this->assertSame($uuid->getBytes(), BinaryCodec::encode($uuid, 'uuid'));\n    }\n\n    public function testUuidDecodeFromBinary()\n    {\n        $uuid = '550e8400-e29b-41d4-a716-446655440000';\n        $bytes = Uuid::fromString($uuid)->getBytes();\n\n        $this->assertSame($uuid, BinaryCodec::decode($bytes, 'uuid'));\n    }\n\n    public function testUuidDecodeFromString()\n    {\n        $uuid = '550e8400-e29b-41d4-a716-446655440000';\n\n        $this->assertSame($uuid, BinaryCodec::decode($uuid, 'uuid'));\n    }\n\n    public function testUlidEncodeFromString()\n    {\n        $ulid = '01ARZ3NDEKTSV4RRFFQ69G5FAV';\n\n        $this->assertSame(Ulid::fromString($ulid)->toBinary(), BinaryCodec::encode($ulid, 'ulid'));\n    }\n\n    public function testUlidEncodeFromBinary()\n    {\n        $bytes = Ulid::fromString('01ARZ3NDEKTSV4RRFFQ69G5FAV')->toBinary();\n\n        $this->assertSame($bytes, BinaryCodec::encode($bytes, 'ulid'));\n    }\n\n    public function testUlidEncodeFromInstance()\n    {\n        $ulid = Ulid::fromString('01ARZ3NDEKTSV4RRFFQ69G5FAV');\n\n        $this->assertSame($ulid->toBinary(), BinaryCodec::encode($ulid, 'ulid'));\n    }\n\n    public function testUlidDecodeFromBinary()\n    {\n        $ulid = '01ARZ3NDEKTSV4RRFFQ69G5FAV';\n        $bytes = Ulid::fromString($ulid)->toBinary();\n\n        $this->assertSame($ulid, BinaryCodec::decode($bytes, 'ulid'));\n    }\n\n    public function testUlidDecodeFromString()\n    {\n        $ulid = '01ARZ3NDEKTSV4RRFFQ69G5FAV';\n\n        $this->assertSame($ulid, BinaryCodec::decode($ulid, 'ulid'));\n    }\n\n    public function testIsBinary()\n    {\n        // Non-string values\n        $this->assertFalse(BinaryCodec::isBinary(null));\n        $this->assertFalse(BinaryCodec::isBinary(123));\n        $this->assertFalse(BinaryCodec::isBinary([]));\n\n        // Empty string\n        $this->assertFalse(BinaryCodec::isBinary(''));\n\n        // Valid UTF-8 strings\n        $this->assertFalse(BinaryCodec::isBinary('hello'));\n        $this->assertFalse(BinaryCodec::isBinary('héllo'));\n        $this->assertFalse(BinaryCodec::isBinary('日本語'));\n\n        // Binary data with null byte\n        $this->assertTrue(BinaryCodec::isBinary(\"hello\\0world\"));\n        $this->assertTrue(BinaryCodec::isBinary(\"\\0\"));\n\n        // Invalid UTF-8 sequences\n        $this->assertTrue(BinaryCodec::isBinary(\"\\xFF\\xFE\"));\n        $this->assertTrue(BinaryCodec::isBinary(random_bytes(16)));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportCapsuleManagerTraitTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Traits\\CapsuleManagerTrait;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportCapsuleManagerTraitTest extends TestCase\n{\n    use CapsuleManagerTrait;\n\n    public function testSetupContainerForCapsule()\n    {\n        $this->container = null;\n        $app = new Container;\n\n        $this->setupContainer($app);\n        $this->assertEquals($app, $this->getContainer());\n        $this->assertInstanceOf(Fluent::class, $app['config']);\n    }\n\n    public function testSetupContainerForCapsuleWhenConfigIsBound()\n    {\n        $this->container = null;\n        $app = new Container;\n        $app['config'] = m::mock(Repository::class);\n\n        $this->setupContainer($app);\n        $this->assertEquals($app, $this->getContainer());\n        $this->assertInstanceOf(Repository::class, $app['config']);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportCarbonTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse BadMethodCallException;\nuse Carbon\\Carbon as BaseCarbon;\nuse Carbon\\CarbonImmutable as BaseCarbonImmutable;\nuse DateTimeInterface;\nuse Illuminate\\Support\\Carbon;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportCarbonTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Support\\Carbon\n     */\n    protected $now;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Carbon::setTestNow($this->now = Carbon::create(2017, 6, 27, 13, 14, 15, 'UTC'));\n    }\n\n    protected function tearDown(): void\n    {\n        Carbon::setTestNow(null);\n        Carbon::serializeUsing(null);\n\n        parent::tearDown();\n    }\n\n    public function testInstance()\n    {\n        $this->assertInstanceOf(Carbon::class, $this->now);\n        $this->assertInstanceOf(DateTimeInterface::class, $this->now);\n        $this->assertInstanceOf(BaseCarbon::class, $this->now);\n        $this->assertInstanceOf(Carbon::class, $this->now);\n    }\n\n    public function testCarbonIsMacroableWhenNotCalledStatically()\n    {\n        Carbon::macro('diffInDecades', function (?Carbon $dt = null, $abs = true) {\n            return (int) ($this->diffInYears($dt, $abs) / 10);\n        });\n\n        $this->assertSame(2, $this->now->diffInDecades(Carbon::now()->addYears(25)));\n    }\n\n    public function testCarbonIsMacroableWhenCalledStatically()\n    {\n        Carbon::macro('twoDaysAgoAtNoon', function () {\n            return Carbon::now()->subDays(2)->setTime(12, 0, 0);\n        });\n\n        $this->assertSame('2017-06-25 12:00:00', Carbon::twoDaysAgoAtNoon()->toDateTimeString());\n    }\n\n    public function testCarbonRaisesExceptionWhenStaticMacroIsNotFound()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('nonExistingStaticMacro does not exist.');\n\n        Carbon::nonExistingStaticMacro();\n    }\n\n    public function testCarbonRaisesExceptionWhenMacroIsNotFound()\n    {\n        $this->expectException(BadMethodCallException::class);\n        $this->expectExceptionMessage('nonExistingMacro does not exist.');\n\n        Carbon::now()->nonExistingMacro();\n    }\n\n    public function testCarbonAllowsCustomSerializer()\n    {\n        Carbon::serializeUsing(function (Carbon $carbon) {\n            return $carbon->getTimestamp();\n        });\n\n        $result = json_decode(json_encode($this->now), true);\n\n        $this->assertSame(1498569255, $result);\n    }\n\n    public function testCarbonCanSerializeToJson()\n    {\n        $this->assertSame('2017-06-27T13:14:15.000000Z', $this->now->jsonSerialize());\n    }\n\n    public function testSetStateReturnsCorrectType()\n    {\n        $carbon = Carbon::__set_state([\n            'date' => '2017-06-27 13:14:15.000000',\n            'timezone_type' => 3,\n            'timezone' => 'UTC',\n        ]);\n\n        $this->assertInstanceOf(Carbon::class, $carbon);\n    }\n\n    public function testDeserializationOccursCorrectly()\n    {\n        $carbon = new Carbon('2017-06-27 13:14:15.000000');\n        $serialized = 'return '.var_export($carbon, true).';';\n        $deserialized = eval($serialized);\n\n        $this->assertInstanceOf(Carbon::class, $deserialized);\n    }\n\n    public function testSetTestNowWillPersistBetweenImmutableAndMutableInstance()\n    {\n        Carbon::setTestNow(new Carbon('2017-06-27 13:14:15.000000'));\n\n        $this->assertSame('2017-06-27 13:14:15', Carbon::now()->toDateTimeString());\n        $this->assertSame('2017-06-27 13:14:15', BaseCarbon::now()->toDateTimeString());\n        $this->assertSame('2017-06-27 13:14:15', BaseCarbonImmutable::now()->toDateTimeString());\n    }\n\n    public function testCarbonIsConditionable()\n    {\n        $this->assertTrue(Carbon::now()->when(null, fn (Carbon $carbon) => $carbon->addDays(1))->isToday());\n        $this->assertTrue(Carbon::now()->when(true, fn (Carbon $carbon) => $carbon->addDays(1))->isTomorrow());\n    }\n\n    public function testCreateFromUid()\n    {\n        $ulid = Carbon::createFromId('01DXH9C4P0ED4AGJJP9CRKQ55C');\n        $this->assertEquals('2020-01-01 19:30:00.000000', $ulid->toDateTimeString('microsecond'));\n\n        $uuidv1 = Carbon::createFromId('71513cb4-f071-11ed-a0cf-325096b39f47');\n        $this->assertEquals('2023-05-12 03:02:34.147346', $uuidv1->toDateTimeString('microsecond'));\n\n        $uuidv2 = Carbon::createFromId('000003e8-f072-21ed-9200-325096b39f47');\n        $this->assertEquals('2023-05-12 03:06:33.529139', $uuidv2->toDateTimeString('microsecond'));\n\n        $uuidv6 = Carbon::createFromId('1edf0746-5d1c-6ce8-88ad-e0cb4effa035');\n        $this->assertEquals('2023-05-12 03:23:43.347428', $uuidv6->toDateTimeString('microsecond'));\n\n        $uuidv7 = Carbon::createFromId('01880dfa-2825-72e4-acbb-b1e4981cf8af');\n        $this->assertEquals('2023-05-12 03:21:18.117000', $uuidv7->toDateTimeString('microsecond'));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse ArrayObject;\nuse CachingIterator;\nuse Exception;\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\ItemNotFoundException;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\MultipleItemsFoundException;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\Stringable;\nuse InvalidArgumentException;\nuse JsonSerializable;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\IgnoreDeprecations;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse stdClass;\nuse Symfony\\Component\\VarDumper\\VarDumper;\nuse UnexpectedValueException;\nuse WeakMap;\n\ninclude_once 'Common.php';\ninclude_once 'Enums.php';\n\nclass SupportCollectionTest extends TestCase\n{\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstReturnsFirstItemInCollection($collection)\n    {\n        $c = new $collection(['foo', 'bar']);\n        $this->assertSame('foo', $c->first());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstWithCallback($collection)\n    {\n        $data = new $collection(['foo', 'bar', 'baz']);\n        $result = $data->first(function ($value) {\n            return $value === 'bar';\n        });\n        $this->assertSame('bar', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstWithCallbackAndDefault($collection)\n    {\n        $data = new $collection(['foo', 'bar']);\n        $result = $data->first(function ($value) {\n            return $value === 'baz';\n        }, 'default');\n        $this->assertSame('default', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstWithDefaultAndWithoutCallback($collection)\n    {\n        $data = new $collection;\n        $result = $data->first(null, 'default');\n        $this->assertSame('default', $result);\n\n        $data = new $collection(['foo', 'bar']);\n        $result = $data->first(null, 'default');\n        $this->assertSame('foo', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleReturnsFirstItemInCollectionIfOnlyOneExists($collection)\n    {\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $this->assertSame(['name' => 'foo'], $collection->where('name', 'foo')->sole());\n        $this->assertSame(['name' => 'foo'], $collection->sole('name', '=', 'foo'));\n        $this->assertSame(['name' => 'foo'], $collection->sole('name', 'foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleThrowsExceptionIfNoItemsExist($collection)\n    {\n        $this->expectException(ItemNotFoundException::class);\n\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $collection->where('name', 'INVALID')->sole();\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleThrowsExceptionIfMoreThanOneItemExists($collection)\n    {\n        $this->expectExceptionObject(new MultipleItemsFoundException(2));\n\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $collection->where('name', 'foo')->sole();\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleReturnsFirstItemInCollectionIfOnlyOneExistsWithCallback($collection)\n    {\n        $data = new $collection(['foo', 'bar', 'baz']);\n        $result = $data->sole(function ($value) {\n            return $value === 'bar';\n        });\n        $this->assertSame('bar', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleThrowsExceptionIfNoItemsExistWithCallback($collection)\n    {\n        $this->expectException(ItemNotFoundException::class);\n\n        $data = new $collection(['foo', 'bar', 'baz']);\n\n        $data->sole(function ($value) {\n            return $value === 'invalid';\n        });\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSoleThrowsExceptionIfMoreThanOneItemExistsWithCallback($collection)\n    {\n        $this->expectExceptionObject(new MultipleItemsFoundException(2));\n\n        $data = new $collection(['foo', 'bar', 'bar']);\n\n        $data->sole(function ($value) {\n            return $value === 'bar';\n        });\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHasSole($collection)\n    {\n        $collection = new $collection([\n            ['age' => 2],\n            ['age' => 3],\n        ]);\n\n        $this->assertFalse($collection->hasSole());\n        $this->assertFalse($collection->where('age', 1)->hasSole());\n        $this->assertTrue($collection->where('age', 2)->hasSole());\n\n        $this->assertFalse($collection->hasSole(fn () => true));\n        $this->assertFalse($collection->hasSole(fn () => false));\n        $this->assertTrue($collection->hasSole(fn ($item) => $item['age'] === 2));\n\n        $this->assertFalse($collection->hasSole('age', '>', 1));\n        $this->assertFalse($collection->hasSole('age', '<', 1));\n        $this->assertTrue($collection->hasSole('age', 2));\n\n        $data = new $collection([\n            (object) ['active' => true, 'verified' => true],\n            (object) ['active' => false, 'verified' => true],\n        ]);\n\n        $this->assertFalse($data->hasSole->verified);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHasMany($collection)\n    {\n        $collection = new $collection([\n            ['age' => 2],\n            ['age' => 3],\n        ]);\n\n        $this->assertTrue($collection->hasMany());\n        $this->assertFalse($collection->where('age', 1)->hasMany());\n        $this->assertFalse($collection->where('age', 2)->hasMany());\n\n        $this->assertTrue($collection->hasMany(fn () => true));\n        $this->assertFalse($collection->hasMany(fn () => false));\n        $this->assertFalse($collection->hasMany(fn ($item) => $item['age'] === 2));\n\n        $this->assertTrue($collection->hasMany('age', '>', 1));\n        $this->assertFalse($collection->hasMany('age', '<', 1));\n        $this->assertFalse($collection->hasMany('age', 2));\n\n        $data = new $collection([\n            (object) ['active' => true, 'verified' => true],\n            (object) ['active' => false, 'verified' => true],\n        ]);\n\n        $this->assertTrue($data->hasMany->verified);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailReturnsFirstItemInCollection($collection)\n    {\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $this->assertSame(['name' => 'foo'], $collection->where('name', 'foo')->firstOrFail());\n        $this->assertSame(['name' => 'foo'], $collection->firstOrFail('name', '=', 'foo'));\n        $this->assertSame(['name' => 'foo'], $collection->firstOrFail('name', 'foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailThrowsExceptionIfNoItemsExist($collection)\n    {\n        $this->expectException(ItemNotFoundException::class);\n\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $collection->where('name', 'INVALID')->firstOrFail();\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailDoesntThrowExceptionIfMoreThanOneItemExists($collection)\n    {\n        $collection = new $collection([\n            ['name' => 'foo'],\n            ['name' => 'foo'],\n            ['name' => 'bar'],\n        ]);\n\n        $this->assertSame(['name' => 'foo'], $collection->where('name', 'foo')->firstOrFail());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailReturnsFirstItemInCollectionIfOnlyOneExistsWithCallback($collection)\n    {\n        $data = new $collection(['foo', 'bar', 'baz']);\n        $result = $data->firstOrFail(function ($value) {\n            return $value === 'bar';\n        });\n        $this->assertSame('bar', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailThrowsExceptionIfNoItemsExistWithCallback($collection)\n    {\n        $this->expectException(ItemNotFoundException::class);\n\n        $data = new $collection(['foo', 'bar', 'baz']);\n\n        $data->firstOrFail(function ($value) {\n            return $value === 'invalid';\n        });\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailDoesntThrowExceptionIfMoreThanOneItemExistsWithCallback($collection)\n    {\n        $data = new $collection(['foo', 'bar', 'bar']);\n\n        $this->assertSame(\n            'bar',\n            $data->firstOrFail(function ($value) {\n                return $value === 'bar';\n            })\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstOrFailStopsIteratingAtFirstMatch($collection)\n    {\n        $data = new $collection([\n            function () {\n                return false;\n            },\n            function () {\n                return true;\n            },\n            function () {\n                throw new Exception();\n            },\n        ]);\n\n        $this->assertNotNull($data->firstOrFail(function ($callback) {\n            return $callback();\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstWhere($collection)\n    {\n        $data = new $collection([\n            ['material' => 'paper', 'type' => 'book'],\n            ['material' => 'rubber', 'type' => 'gasket'],\n        ]);\n\n        $this->assertSame('book', $data->firstWhere('material', 'paper')['type']);\n        $this->assertSame('gasket', $data->firstWhere('material', 'rubber')['type']);\n        $this->assertNull($data->firstWhere('material', 'nonexistent'));\n        $this->assertNull($data->firstWhere('nonexistent', 'key'));\n\n        $this->assertSame('book', $data->firstWhere(fn ($value) => $value['material'] === 'paper')['type']);\n        $this->assertSame('gasket', $data->firstWhere(fn ($value) => $value['material'] === 'rubber')['type']);\n        $this->assertNull($data->firstWhere(fn ($value) => $value['material'] === 'nonexistent'));\n        $this->assertNull($data->firstWhere(fn ($value) => ($value['nonexistent'] ?? null) === 'key'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFirstWhereUsingEnum($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => StaffEnum::Taylor],\n            ['id' => 2, 'name' => StaffEnum::Joe],\n            ['id' => 3, 'name' => StaffEnum::James],\n        ]);\n\n        $this->assertSame(1, $data->firstWhere('name', 'Taylor')['id']);\n        $this->assertSame(2, $data->firstWhere('name', StaffEnum::Joe)['id']);\n        $this->assertSame(3, $data->firstWhere('name', StaffEnum::James)['id']);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testLastReturnsLastItemInCollection($collection)\n    {\n        $c = new $collection(['foo', 'bar']);\n        $this->assertSame('bar', $c->last());\n\n        $c = new $collection([]);\n        $this->assertNull($c->last());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testLastWithCallback($collection)\n    {\n        $data = new $collection([100, 200, 300]);\n        $result = $data->last(function ($value) {\n            return $value < 250;\n        });\n        $this->assertEquals(200, $result);\n\n        $result = $data->last(function ($value, $key) {\n            return $key < 2;\n        });\n        $this->assertEquals(200, $result);\n\n        $result = $data->last(function ($value) {\n            return $value > 300;\n        });\n        $this->assertNull($result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testLastWithCallbackAndDefault($collection)\n    {\n        $data = new $collection(['foo', 'bar']);\n        $result = $data->last(function ($value) {\n            return $value === 'baz';\n        }, 'default');\n        $this->assertSame('default', $result);\n\n        $data = new $collection(['foo', 'bar', 'Bar']);\n        $result = $data->last(function ($value) {\n            return $value === 'bar';\n        }, 'default');\n        $this->assertSame('bar', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testLastWithDefaultAndWithoutCallback($collection)\n    {\n        $data = new $collection;\n        $result = $data->last(null, 'default');\n        $this->assertSame('default', $result);\n    }\n\n    public function testPopReturnsAndRemovesLastItemInCollection()\n    {\n        $c = new Collection(['foo', 'bar']);\n\n        $this->assertSame('bar', $c->pop());\n        $this->assertSame('foo', $c->first());\n    }\n\n    public function testPopReturnsAndRemovesLastXItemsInCollection()\n    {\n        $c = new Collection(['foo', 'bar', 'baz']);\n\n        $this->assertEquals(new Collection(['baz', 'bar']), $c->pop(2));\n        $this->assertSame('foo', $c->first());\n\n        $this->assertEquals(new Collection(['baz', 'bar', 'foo']), (new Collection(['foo', 'bar', 'baz']))->pop(6));\n    }\n\n    public function testShiftReturnsAndRemovesFirstItemInCollection()\n    {\n        $data = new Collection(['Taylor', 'Otwell']);\n\n        $this->assertSame('Taylor', $data->shift());\n        $this->assertSame('Otwell', $data->first());\n        $this->assertSame('Otwell', $data->shift());\n        $this->assertNull($data->first());\n    }\n\n    public function testShiftReturnsAndRemovesFirstXItemsInCollection()\n    {\n        $data = new Collection(['foo', 'bar', 'baz']);\n\n        $this->assertEquals(new Collection(['foo', 'bar']), $data->shift(2));\n        $this->assertSame('baz', $data->first());\n\n        $this->assertEquals(new Collection(['foo', 'bar', 'baz']), (new Collection(['foo', 'bar', 'baz']))->shift(6));\n\n        $data = new Collection(['foo', 'bar', 'baz']);\n\n        $this->assertEquals(new Collection([]), $data->shift(0));\n        $this->assertEquals(collect(['foo', 'bar', 'baz']), $data);\n\n        $this->expectException('InvalidArgumentException');\n        (new Collection(['foo', 'bar', 'baz']))->shift(-1);\n\n        $this->expectException('InvalidArgumentException');\n        (new Collection(['foo', 'bar', 'baz']))->shift(-2);\n    }\n\n    public function testShiftReturnsNullOnEmptyCollection()\n    {\n        $itemFoo = new \\stdClass();\n        $itemFoo->text = 'f';\n        $itemBar = new \\stdClass();\n        $itemBar->text = 'x';\n\n        $items = collect([$itemFoo, $itemBar]);\n\n        $foo = $items->shift();\n        $bar = $items->shift();\n\n        $this->assertSame('f', $foo?->text);\n        $this->assertSame('x', $bar?->text);\n        $this->assertNull($items->shift());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliding($collection)\n    {\n        // Default parameters: $size = 2, $step = 1\n        $this->assertSame([], $collection::times(0)->sliding()->toArray());\n        $this->assertSame([], $collection::times(1)->sliding()->toArray());\n        $this->assertSame([[1, 2]], $collection::times(2)->sliding()->toArray());\n        $this->assertSame(\n            [[1, 2], [2, 3]],\n            $collection::times(3)->sliding()->map->values()->toArray()\n        );\n\n        // Custom step: $size = 2, $step = 3\n        $this->assertSame([], $collection::times(1)->sliding(2, 3)->toArray());\n        $this->assertSame([[1, 2]], $collection::times(2)->sliding(2, 3)->toArray());\n        $this->assertSame([[1, 2]], $collection::times(3)->sliding(2, 3)->toArray());\n        $this->assertSame([[1, 2]], $collection::times(4)->sliding(2, 3)->toArray());\n        $this->assertSame(\n            [[1, 2], [4, 5]],\n            $collection::times(5)->sliding(2, 3)->map->values()->toArray()\n        );\n\n        // Custom size: $size = 3, $step = 1\n        $this->assertSame([], $collection::times(2)->sliding(3)->toArray());\n        $this->assertSame([[1, 2, 3]], $collection::times(3)->sliding(3)->toArray());\n        $this->assertSame(\n            [[1, 2, 3], [2, 3, 4]],\n            $collection::times(4)->sliding(3)->map->values()->toArray()\n        );\n        $this->assertSame(\n            [[1, 2, 3], [2, 3, 4]],\n            $collection::times(4)->sliding(3)->map->values()->toArray()\n        );\n\n        // Custom size and custom step: $size = 3, $step = 2\n        $this->assertSame([], $collection::times(2)->sliding(3, 2)->toArray());\n        $this->assertSame([[1, 2, 3]], $collection::times(3)->sliding(3, 2)->toArray());\n        $this->assertSame([[1, 2, 3]], $collection::times(4)->sliding(3, 2)->toArray());\n        $this->assertSame(\n            [[1, 2, 3], [3, 4, 5]],\n            $collection::times(5)->sliding(3, 2)->map->values()->toArray()\n        );\n        $this->assertSame(\n            [[1, 2, 3], [3, 4, 5]],\n            $collection::times(6)->sliding(3, 2)->map->values()->toArray()\n        );\n\n        // Ensure keys are preserved, and inner chunks are also collections\n        $chunks = $collection::times(3)->sliding();\n\n        $this->assertSame([[0 => 1, 1 => 2], [1 => 2, 2 => 3]], $chunks->toArray());\n\n        $this->assertInstanceOf($collection, $chunks);\n        $this->assertInstanceOf($collection, $chunks->first());\n        $this->assertInstanceOf($collection, $chunks->skip(1)->first());\n\n        // Test invalid size parameter (size must be at least 1)\n        // instead of throwing an error. Now it throws InvalidArgumentException.\n        try {\n            $collection::times(5)->sliding(0, 1)->toArray();\n            $this->fail('Expected InvalidArgumentException for size = 0');\n        } catch (\\InvalidArgumentException $e) {\n            $this->assertSame('Size value must be at least 1.', $e->getMessage());\n        }\n\n        try {\n            $collection::times(5)->sliding(-1, 1)->toArray();\n            $this->fail('Expected InvalidArgumentException for size = -1');\n        } catch (\\InvalidArgumentException $e) {\n            $this->assertSame('Size value must be at least 1.', $e->getMessage());\n        }\n\n        // Test invalid step parameter (step must be at least 1)\n        // Now it throws InvalidArgumentException with an error message.\n        try {\n            $collection::times(5)->sliding(2, 0)->toArray();\n            $this->fail('Expected InvalidArgumentException for step = 0');\n        } catch (\\InvalidArgumentException $e) {\n            $this->assertSame('Step value must be at least 1.', $e->getMessage());\n        }\n\n        try {\n            $collection::times(5)->sliding(2, -1)->toArray();\n            $this->fail('Expected InvalidArgumentException for step = -1');\n        } catch (\\InvalidArgumentException $e) {\n            $this->assertSame('Step value must be at least 1.', $e->getMessage());\n        }\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEmptyCollectionIsEmpty($collection)\n    {\n        $c = new $collection;\n\n        $this->assertTrue($c->isEmpty());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEmptyCollectionIsNotEmpty($collection)\n    {\n        $c = new $collection(['foo', 'bar']);\n\n        $this->assertFalse($c->isEmpty());\n        $this->assertTrue($c->isNotEmpty());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollectionIsConstructed($collection)\n    {\n        $data = new $collection('foo');\n        $this->assertSame(['foo'], $data->all());\n\n        $data = new $collection(2);\n        $this->assertSame([2], $data->all());\n\n        $data = new $collection(false);\n        $this->assertSame([false], $data->all());\n\n        $data = new $collection(null);\n        $this->assertEmpty($data->all());\n\n        $data = new $collection;\n        $this->assertEmpty($data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSkipMethod($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6]);\n\n        // Total items to skip is smaller than collection length\n        $this->assertSame([5, 6], $data->skip(4)->values()->all());\n\n        // Total items to skip is more than collection length\n        $this->assertSame([], $data->skip(10)->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSkipUntil($collection)\n    {\n        $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);\n\n        // Item at the beginning of the collection\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->skipUntil(1)->values()->all());\n\n        // Item at the middle of the collection\n        $this->assertSame([3, 3, 4, 4], $data->skipUntil(3)->values()->all());\n\n        // Item not in the collection\n        $this->assertSame([], $data->skipUntil(5)->values()->all());\n\n        // Item at the beginning of the collection\n        $data = $data->skipUntil(function ($value, $key) {\n            return $value <= 1;\n        })->values();\n\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->all());\n\n        // Item at the middle of the collection\n        $data = $data->skipUntil(function ($value, $key) {\n            return $value >= 3;\n        })->values();\n\n        $this->assertSame([3, 3, 4, 4], $data->all());\n\n        // Item not in the collection\n        $data = $data->skipUntil(function ($value, $key) {\n            return $value >= 5;\n        })->values();\n\n        $this->assertSame([], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSkipWhile($collection)\n    {\n        $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);\n\n        // Item at the beginning of the collection\n        $this->assertSame([2, 2, 3, 3, 4, 4], $data->skipWhile(1)->values()->all());\n\n        // Item not in the collection\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->skipWhile(5)->values()->all());\n\n        // Item in the collection but not at the beginning\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->skipWhile(2)->values()->all());\n\n        // Item not in the collection\n        $data = $data->skipWhile(function ($value, $key) {\n            return $value >= 5;\n        })->values();\n\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->all());\n\n        // Item in the collection but not at the beginning\n        $data = $data->skipWhile(function ($value, $key) {\n            return $value >= 2;\n        })->values();\n\n        $this->assertSame([1, 1, 2, 2, 3, 3, 4, 4], $data->all());\n\n        // Item at the beginning of the collection\n        $data = $data->skipWhile(function ($value, $key) {\n            return $value < 3;\n        })->values();\n\n        $this->assertSame([3, 3, 4, 4], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGetArrayableItems($collection)\n    {\n        $data = new $collection;\n\n        $class = new ReflectionClass($collection);\n        $method = $class->getMethod('getArrayableItems');\n\n        $items = new TestArrayableObject;\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo' => 'bar'], $array);\n\n        $items = new TestJsonableObject;\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo' => 'bar'], $array);\n\n        $items = new TestJsonSerializeObject;\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo' => 'bar'], $array);\n\n        $items = new TestJsonSerializeWithScalarValueObject;\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo'], $array);\n\n        $subject = [new stdClass, new stdClass];\n        $items = new TestTraversableAndJsonSerializableObject($subject);\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame($subject, $array);\n\n        $items = new $collection(['foo' => 'bar']);\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo' => 'bar'], $array);\n\n        $items = ['foo' => 'bar'];\n        $array = $method->invokeArgs($data, [$items]);\n        $this->assertSame(['foo' => 'bar'], $array);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testToArrayCallsToArrayOnEachItemInCollection($collection)\n    {\n        $item1 = m::mock(Arrayable::class);\n        $item1->shouldReceive('toArray')->once()->andReturn('foo.array');\n        $item2 = m::mock(Arrayable::class);\n        $item2->shouldReceive('toArray')->once()->andReturn('bar.array');\n        $c = new $collection([$item1, $item2]);\n        $results = $c->toArray();\n\n        $this->assertEquals(['foo.array', 'bar.array'], $results);\n    }\n\n    public function testLazyReturnsLazyCollection()\n    {\n        $data = new Collection([1, 2, 3, 4, 5]);\n\n        $lazy = $data->lazy();\n\n        $data->add(6);\n\n        $this->assertInstanceOf(LazyCollection::class, $lazy);\n        $this->assertSame([1, 2, 3, 4, 5], $lazy->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testJsonSerializeCallsToArrayOrJsonSerializeOnEachItemInCollection($collection)\n    {\n        $item1 = m::mock(JsonSerializable::class);\n        $item1->shouldReceive('jsonSerialize')->once()->andReturn('foo.json');\n        $item2 = m::mock(Arrayable::class);\n        $item2->shouldReceive('toArray')->once()->andReturn('bar.array');\n        $c = new $collection([$item1, $item2]);\n        $results = $c->jsonSerialize();\n\n        $this->assertEquals(['foo.json', 'bar.array'], $results);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testToJsonEncodesTheJsonSerializeResult($collection)\n    {\n        $c = $this->getMockBuilder($collection)->onlyMethods(['jsonSerialize'])->getMock();\n        $c->expects($this->once())->method('jsonSerialize')->willReturn(['foo']);\n        $results = $c->toJson();\n        $this->assertJsonStringEqualsJsonString(json_encode(['foo']), $results);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testToPrettyJsonEncodesTheJsonSerializeResult($collection)\n    {\n        $c = $this->getMockBuilder($collection)->onlyMethods(['jsonSerialize'])->getMock();\n        $c->expects($this->once())->method('jsonSerialize')->willReturn(['foo' => 'bar', 'baz' => 'qux']);\n        $results = $c->toPrettyJson();\n        $expected = json_encode(['foo' => 'bar', 'baz' => 'qux'], JSON_PRETTY_PRINT);\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCastingToStringJsonEncodesTheToArrayResult($collection)\n    {\n        $c = $this->getMockBuilder($collection)->onlyMethods(['jsonSerialize'])->getMock();\n        $c->expects($this->once())->method('jsonSerialize')->willReturn(['foo']);\n\n        $this->assertJsonStringEqualsJsonString(json_encode(['foo']), (string) $c);\n    }\n\n    public function testOffsetAccess()\n    {\n        $c = new Collection(['name' => 'taylor']);\n        $this->assertSame('taylor', $c['name']);\n        $c['name'] = 'dayle';\n        $this->assertSame('dayle', $c['name']);\n        $this->assertTrue(isset($c['name']));\n        unset($c['name']);\n        $this->assertFalse(isset($c['name']));\n        $c[] = 'jason';\n        $this->assertSame('jason', $c[0]);\n    }\n\n    public function testArrayAccessOffsetExists()\n    {\n        $c = new Collection(['foo', 'bar', null]);\n        $this->assertTrue($c->offsetExists(0));\n        $this->assertTrue($c->offsetExists(1));\n        $this->assertFalse($c->offsetExists(2));\n    }\n\n    public function testBehavesLikeAnArrayWithArrayAccess()\n    {\n        // indexed array\n        $input = ['foo', null];\n        $c = new Collection($input);\n        $this->assertEquals(isset($input[0]), isset($c[0])); // existing value\n        $this->assertEquals(isset($input[1]), isset($c[1])); // existing but null value\n        $this->assertEquals(isset($input[1000]), isset($c[1000])); // non-existing value\n        $this->assertEquals($input[0], $c[0]);\n        $this->assertEquals($input[1], $c[1]);\n\n        // associative array\n        $input = ['k1' => 'foo', 'k2' => null];\n        $c = new Collection($input);\n        $this->assertEquals(isset($input['k1']), isset($c['k1'])); // existing value\n        $this->assertEquals(isset($input['k2']), isset($c['k2'])); // existing but null value\n        $this->assertEquals(isset($input['k3']), isset($c['k3'])); // non-existing value\n        $this->assertEquals($input['k1'], $c['k1']);\n        $this->assertEquals($input['k2'], $c['k2']);\n    }\n\n    public function testArrayAccessOffsetGet()\n    {\n        $c = new Collection(['foo', 'bar']);\n        $this->assertSame('foo', $c->offsetGet(0));\n        $this->assertSame('bar', $c->offsetGet(1));\n    }\n\n    public function testArrayAccessOffsetSet()\n    {\n        $c = new Collection(['foo', 'foo']);\n\n        $c->offsetSet(1, 'bar');\n        $this->assertSame('bar', $c[1]);\n\n        $c->offsetSet(null, 'qux');\n        $this->assertSame('qux', $c[2]);\n    }\n\n    public function testArrayAccessOffsetUnset()\n    {\n        $c = new Collection(['foo', 'bar']);\n\n        $c->offsetUnset(1);\n        $this->assertFalse(isset($c[1]));\n    }\n\n    public function testForgetSingleKey()\n    {\n        $c = new Collection(['foo', 'bar']);\n        $c = $c->forget(0)->all();\n        $this->assertFalse(isset($c['foo']));\n        $this->assertFalse(isset($c[0]));\n        $this->assertTrue(isset($c[1]));\n\n        $c = new Collection(['foo' => 'bar', 'baz' => 'qux']);\n        $c = $c->forget('foo')->all();\n        $this->assertFalse(isset($c['foo']));\n        $this->assertTrue(isset($c['baz']));\n    }\n\n    public function testForgetArrayOfKeys()\n    {\n        $c = new Collection(['foo', 'bar', 'baz']);\n        $c = $c->forget([0, 2])->all();\n        $this->assertFalse(isset($c[0]));\n        $this->assertFalse(isset($c[2]));\n        $this->assertTrue(isset($c[1]));\n\n        $c = new Collection(['name' => 'taylor', 'foo' => 'bar', 'baz' => 'qux']);\n        $c = $c->forget(['foo', 'baz'])->all();\n        $this->assertFalse(isset($c['foo']));\n        $this->assertFalse(isset($c['baz']));\n        $this->assertTrue(isset($c['name']));\n    }\n\n    public function testForgetCollectionOfKeys()\n    {\n        $c = new Collection(['foo', 'bar', 'baz']);\n        $c = $c->forget(collect([0, 2]))->all();\n        $this->assertFalse(isset($c[0]));\n        $this->assertFalse(isset($c[2]));\n        $this->assertTrue(isset($c[1]));\n\n        $c = new Collection(['name' => 'taylor', 'foo' => 'bar', 'baz' => 'qux']);\n        $c = $c->forget(collect(['foo', 'baz']))->all();\n        $this->assertFalse(isset($c['foo']));\n        $this->assertFalse(isset($c['baz']));\n        $this->assertTrue(isset($c['name']));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCountable($collection)\n    {\n        $c = new $collection(['foo', 'bar']);\n        $this->assertCount(2, $c);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCountByStandalone($collection)\n    {\n        $c = new $collection(['foo', 'foo', 'foo', 'bar', 'bar', 'foobar']);\n        $this->assertEquals(['foo' => 3, 'bar' => 2, 'foobar' => 1], $c->countBy()->all());\n\n        $c = new $collection([true, true, false, false, false]);\n        $this->assertEquals([true => 2, false => 3], $c->countBy()->all());\n\n        $c = new $collection([1, 5, 1, 5, 5, 1]);\n        $this->assertEquals([1 => 3, 5 => 3], $c->countBy()->all());\n\n        $c = new $collection([StaffEnum::James, StaffEnum::Joe, StaffEnum::Taylor]);\n        $this->assertEquals(['James' => 1, 'Joe' => 1, 'Taylor' => 1], $c->countBy()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCountByWithKey($collection)\n    {\n        $c = new $collection([\n            ['key' => 'a'], ['key' => 'a'], ['key' => 'a'], ['key' => 'a'],\n            ['key' => 'b'], ['key' => 'b'], ['key' => 'b'],\n        ]);\n        $this->assertEquals(['a' => 4, 'b' => 3], $c->countBy('key')->all());\n\n        $c = new $collection([\n            ['key' => TestBackedEnum::A],\n            ['key' => TestBackedEnum::B], ['key' => TestBackedEnum::B],\n        ]);\n        $this->assertEquals([1 => 1, 2 => 2], $c->countBy('key')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCountableByWithCallback($collection)\n    {\n        $c = new $collection(['alice', 'aaron', 'bob', 'carla']);\n        $this->assertEquals(['a' => 2, 'b' => 1, 'c' => 1], $c->countBy(function ($name) {\n            return substr($name, 0, 1);\n        })->all());\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $this->assertEquals([true => 2, false => 3], $c->countBy(function ($i) {\n            return $i % 2 === 0;\n        })->all());\n\n        $c = new $collection(['A', 'A', 'B', 'A']);\n        $this->assertEquals(['A' => 3, 'B' => 1], $c->countBy(static fn ($i) => TestStringBackedEnum::from($i))->all());\n    }\n\n    public function testAdd()\n    {\n        $c = new Collection([]);\n        $this->assertEquals([1], $c->add(1)->values()->all());\n        $this->assertEquals([1, 2], $c->add(2)->values()->all());\n        $this->assertEquals([1, 2, ''], $c->add('')->values()->all());\n        $this->assertEquals([1, 2, '', null], $c->add(null)->values()->all());\n        $this->assertEquals([1, 2, '', null, false], $c->add(false)->values()->all());\n        $this->assertEquals([1, 2, '', null, false, []], $c->add([])->values()->all());\n        $this->assertEquals([1, 2, '', null, false, [], 'name'], $c->add('name')->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testContainsOneItem($collection)\n    {\n        $this->assertFalse((new $collection([]))->containsOneItem());\n        $this->assertTrue((new $collection([1]))->containsOneItem());\n        $this->assertFalse((new $collection([1, 2]))->containsOneItem());\n\n        $this->assertFalse(collect([1, 2, 2])->containsOneItem(fn ($number) => $number === 2));\n        $this->assertTrue(collect(['ant', 'bear', 'cat'])->containsOneItem(fn ($word) => strlen($word) === 4));\n        $this->assertFalse(collect(['ant', 'bear', 'cat'])->containsOneItem(fn ($word) => strlen($word) > 4));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testContainsManyItems($collection)\n    {\n        $this->assertFalse((new $collection([]))->containsManyItems());\n        $this->assertFalse((new $collection([1]))->containsManyItems());\n        $this->assertTrue((new $collection([1, 2]))->containsManyItems());\n        $this->assertTrue((new $collection([1, 2, 3]))->containsManyItems());\n\n        $this->assertTrue(collect([1, 2, 2])->containsManyItems(fn ($number) => $number === 2));\n        $this->assertFalse(collect(['ant', 'bear', 'cat'])->containsManyItems(fn ($word) => strlen($word) === 4));\n        $this->assertFalse(collect(['ant', 'bear', 'cat'])->containsManyItems(fn ($word) => strlen($word) > 4));\n        $this->assertTrue(collect(['ant', 'bear', 'cat'])->containsManyItems(fn ($word) => strlen($word) === 3));\n    }\n\n    public function testIterable()\n    {\n        $c = new Collection(['foo']);\n        $this->assertInstanceOf(ArrayIterator::class, $c->getIterator());\n        $this->assertEquals(['foo'], $c->getIterator()->getArrayCopy());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCachingIterator($collection)\n    {\n        $c = new $collection(['foo']);\n        $this->assertInstanceOf(CachingIterator::class, $c->getCachingIterator());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFilter($collection)\n    {\n        $c = new $collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);\n        $this->assertEquals([1 => ['id' => 2, 'name' => 'World']], $c->filter(function ($item) {\n            return $item['id'] == 2;\n        })->all());\n\n        $c = new $collection(['', 'Hello', '', 'World']);\n        $this->assertEquals(['Hello', 'World'], $c->filter()->values()->toArray());\n\n        $c = new $collection(['id' => 1, 'first' => 'Hello', 'second' => 'World']);\n        $this->assertEquals(['first' => 'Hello', 'second' => 'World'], $c->filter(function ($item, $key) {\n            return $key !== 'id';\n        })->all());\n\n        $c = new $collection([1, 2, 3, null, false, '', 0, []]);\n        $this->assertEquals([1, 2, 3], $c->filter()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderKeyBy($collection)\n    {\n        $c = new $collection([\n            ['id' => 'id1', 'name' => 'first'],\n            ['id' => 'id2', 'name' => 'second'],\n        ]);\n\n        $this->assertEquals(['id1' => 'first', 'id2' => 'second'], $c->keyBy->id->map->name->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderUnique($collection)\n    {\n        $c = new $collection([\n            ['id' => '1', 'name' => 'first'],\n            ['id' => '1', 'name' => 'second'],\n        ]);\n\n        $this->assertCount(1, $c->unique->id);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderFilter($collection)\n    {\n        $c = new $collection([\n            new class\n            {\n                public $name = 'Alex';\n\n                public function active()\n                {\n                    return true;\n                }\n            },\n            new class\n            {\n                public $name = 'John';\n\n                public function active()\n                {\n                    return false;\n                }\n            },\n        ]);\n\n        $this->assertCount(1, $c->filter->active());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhere($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3']],\n            $c->where('v', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3']],\n            $c->where('v', '=', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3']],\n            $c->where('v', '==', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3']],\n            $c->where('v', 'garbage', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 3]],\n            $c->where('v', '===', 3)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 4]],\n            $c->where('v', '<>', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 4]],\n            $c->where('v', '!=', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => '3'], ['v' => 4]],\n            $c->where('v', '!==', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3']],\n            $c->where('v', '<=', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3'], ['v' => 4]],\n            $c->where('v', '>=', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2]],\n            $c->where('v', '<', 3)->values()->all()\n        );\n        $this->assertEquals(\n            [['v' => 4]],\n            $c->where('v', '>', 3)->values()->all()\n        );\n\n        $object = (object) ['foo' => 'bar'];\n\n        $this->assertEquals(\n            [],\n            $c->where('v', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],\n            $c->where('v', '<>', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],\n            $c->where('v', '!=', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],\n            $c->where('v', '!==', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [],\n            $c->where('v', '>', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 3], ['v' => '3']],\n            $c->where(fn ($value) => $value['v'] == 3)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 3]],\n            $c->where(fn ($value) => $value['v'] === 3)->values()->all()\n        );\n\n        $c = new $collection([['v' => 1], ['v' => $object]]);\n        $this->assertEquals(\n            [['v' => $object]],\n            $c->where('v', $object)->values()->all()\n        );\n\n        $this->assertEquals(\n            [['v' => 1], ['v' => $object]],\n            $c->where('v', '<>', null)->values()->all()\n        );\n\n        $this->assertEquals(\n            [],\n            $c->where('v', '<', null)->values()->all()\n        );\n\n        $c = new $collection([['v' => 1], ['v' => new HtmlString('hello')]]);\n        $this->assertEquals(\n            [['v' => new HtmlString('hello')]],\n            $c->where('v', 'hello')->values()->all()\n        );\n\n        $c = new $collection([['v' => 1], ['v' => 'hello']]);\n        $this->assertEquals(\n            [['v' => 'hello']],\n            $c->where('v', new HtmlString('hello'))->values()->all()\n        );\n\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => null]]);\n        $this->assertEquals(\n            [['v' => 1], ['v' => 2]],\n            $c->where('v')->values()->all()\n        );\n\n        $c = new $collection([\n            ['v' => 1, 'g' => 3],\n            ['v' => 2, 'g' => 2],\n            ['v' => 2, 'g' => 3],\n            ['v' => 2, 'g' => null],\n        ]);\n        $this->assertEquals([['v' => 2, 'g' => 3]], $c->where('v', 2)->where('g', 3)->values()->all());\n        $this->assertEquals([['v' => 2, 'g' => 3]], $c->where('v', 2)->where('g', '>', 2)->values()->all());\n        $this->assertEquals([], $c->where('v', 2)->where('g', 4)->values()->all());\n        $this->assertEquals([['v' => 2, 'g' => null]], $c->where('v', 2)->whereNull('g')->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereStrict($collection)\n    {\n        $c = new $collection([['v' => 3], ['v' => '3']]);\n\n        $this->assertEquals(\n            [['v' => 3]],\n            $c->whereStrict('v', 3)->values()->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereInstanceOf($collection)\n    {\n        $c = new $collection([new stdClass, new stdClass, new $collection, new stdClass, new Str]);\n        $this->assertCount(3, $c->whereInstanceOf(stdClass::class));\n\n        $this->assertCount(4, $c->whereInstanceOf([stdClass::class, Str::class]));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereIn($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n        $this->assertEquals([['v' => 1], ['v' => 3], ['v' => '3']], $c->whereIn('v', [1, 3])->values()->all());\n        $this->assertEquals([], $c->whereIn('v', [2])->whereIn('v', [1, 3])->values()->all());\n        $this->assertEquals([['v' => 1]], $c->whereIn('v', [1])->whereIn('v', [1, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereInStrict($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n        $this->assertEquals([['v' => 1], ['v' => 3]], $c->whereInStrict('v', [1, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNotIn($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n        $this->assertEquals([['v' => 2], ['v' => 4]], $c->whereNotIn('v', [1, 3])->values()->all());\n        $this->assertEquals([['v' => 4]], $c->whereNotIn('v', [2])->whereNotIn('v', [1, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNotInStrict($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n        $this->assertEquals([['v' => 2], ['v' => '3'], ['v' => 4]], $c->whereNotInStrict('v', [1, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValues($collection)\n    {\n        $c = new $collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);\n        $this->assertEquals([['id' => 2, 'name' => 'World']], $c->filter(function ($item) {\n            return $item['id'] == 2;\n        })->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValuesResetKey($collection)\n    {\n        $data = new $collection([1 => 'a', 2 => 'b', 3 => 'c']);\n        $this->assertEquals([0 => 'a', 1 => 'b', 2 => 'c'], $data->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValue($collection)\n    {\n        $c = new $collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);\n\n        $this->assertEquals('Hello', $c->value('name'));\n        $this->assertEquals('World', $c->where('id', 2)->value('name'));\n\n        $c = new $collection([\n            ['id' => 1, 'pivot' => ['value' => 'foo']],\n            ['id' => 2, 'pivot' => ['value' => 'bar']],\n        ]);\n\n        $this->assertEquals(['value' => 'foo'], $c->value('pivot'));\n        $this->assertEquals('foo', $c->value('pivot.value'));\n        $this->assertEquals('bar', $c->where('id', 2)->value('pivot.value'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValueUsingEnum($collection)\n    {\n        $c = new $collection([['id' => 1, 'name' => StaffEnum::Taylor], ['id' => 2, 'name' => StaffEnum::Joe]]);\n\n        $this->assertSame(StaffEnum::Taylor, $c->value('name'));\n        $this->assertEquals(StaffEnum::Joe, $c->where('id', 2)->value('name'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValueWithNegativeValue($collection)\n    {\n        $c = new $collection([['id' => 1, 'balance' => 0], ['id' => 2, 'balance' => 200]]);\n\n        $this->assertEquals(0, $c->value('balance'));\n\n        $c = new $collection([['id' => 1, 'balance' => ''], ['id' => 2, 'balance' => 200]]);\n\n        $this->assertEquals('', $c->value('balance'));\n\n        $c = new $collection([['id' => 1, 'balance' => null], ['id' => 2, 'balance' => 200]]);\n\n        $this->assertEquals(null, $c->value('balance'));\n\n        $c = new $collection([['id' => 1], ['id' => 2, 'balance' => 200]]);\n\n        $this->assertEquals(200, $c->value('balance'));\n\n        $c = new $collection([['id' => 1], ['id' => 2, 'balance' => 0], ['id' => 3, 'balance' => 200]]);\n\n        $this->assertEquals(0, $c->value('balance'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValueWithObjects($collection)\n    {\n        $c = new $collection([\n            literal(id: 1),\n            literal(id: 2, balance: ''),\n            literal(id: 3, balance: 200),\n        ]);\n\n        $this->assertEquals('', $c->value('balance'));\n\n        $c = new $collection([\n            literal(id: 1),\n            literal(id: 2, balance: literal(currency: 'USD', value: 0)),\n            literal(id: 3, balance: literal(currency: 'USD', value: 200)),\n        ]);\n\n        $this->assertEquals(0, $c->value('balance.value'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testBetween($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n\n        $this->assertEquals([['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],\n            $c->whereBetween('v', [2, 4])->values()->all());\n        $this->assertEquals([['v' => 1]], $c->whereBetween('v', [-1, 1])->all());\n        $this->assertEquals([['v' => 3], ['v' => '3']], $c->whereBetween('v', [3, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNotBetween($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);\n\n        $this->assertEquals([['v' => 1]], $c->whereNotBetween('v', [2, 4])->values()->all());\n        $this->assertEquals([['v' => 2], ['v' => 3], ['v' => 3], ['v' => 4]], $c->whereNotBetween('v', [-1, 1])->values()->all());\n        $this->assertEquals([['v' => 1], ['v' => '2'], ['v' => '4']], $c->whereNotBetween('v', [3, 3])->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFlatten($collection)\n    {\n        // Flat arrays are unaffected\n        $c = new $collection(['#foo', '#bar', '#baz']);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Nested arrays are flattened with existing flat items\n        $c = new $collection([['#foo', '#bar'], '#baz']);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Sets of nested arrays are flattened\n        $c = new $collection([['#foo', '#bar'], ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Deeply nested arrays are flattened\n        $c = new $collection([['#foo', ['#bar']], ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Nested collections are flattened alongside arrays\n        $c = new $collection([new $collection(['#foo', '#bar']), ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Nested collections containing plain arrays are flattened\n        $c = new $collection([new $collection(['#foo', ['#bar']]), ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Nested arrays containing collections are flattened\n        $c = new $collection([['#foo', new $collection(['#bar'])], ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());\n\n        // Nested arrays containing collections containing arrays are flattened\n        $c = new $collection([['#foo', new $collection(['#bar', ['#zap']])], ['#baz']]);\n        $this->assertEquals(['#foo', '#bar', '#zap', '#baz'], $c->flatten()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFlattenWithDepth($collection)\n    {\n        // No depth flattens recursively\n        $c = new $collection([['#foo', ['#bar', ['#baz']]], '#zap']);\n        $this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());\n\n        // Specifying a depth only flattens to that depth\n        $c = new $collection([['#foo', ['#bar', ['#baz']]], '#zap']);\n        $this->assertEquals(['#foo', ['#bar', ['#baz']], '#zap'], $c->flatten(1)->all());\n\n        $c = new $collection([['#foo', ['#bar', ['#baz']]], '#zap']);\n        $this->assertEquals(['#foo', '#bar', ['#baz'], '#zap'], $c->flatten(2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFlattenIgnoresKeys($collection)\n    {\n        // No depth ignores keys\n        $c = new $collection(['#foo', ['key' => '#bar'], ['key' => '#baz'], 'key' => '#zap']);\n        $this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());\n\n        // Depth of 1 ignores keys\n        $c = new $collection(['#foo', ['key' => '#bar'], ['key' => '#baz'], 'key' => '#zap']);\n        $this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten(1)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeNull($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello'], $c->merge(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeArray($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello', 'id' => 1], $c->merge(['id' => 1])->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeCollection($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'World', 'id' => 1], $c->merge(new $collection(['name' => 'World', 'id' => 1]))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeRecursiveNull($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello'], $c->mergeRecursive(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeRecursiveArray($collection)\n    {\n        $c = new $collection(['name' => 'Hello', 'id' => 1]);\n        $this->assertEquals(['name' => 'Hello', 'id' => [1, 2]], $c->mergeRecursive(['id' => 2])->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMergeRecursiveCollection($collection)\n    {\n        $c = new $collection(['name' => 'Hello', 'id' => 1, 'meta' => ['tags' => ['a', 'b'], 'roles' => 'admin']]);\n        $this->assertEquals(\n            ['name' => 'Hello', 'id' => 1, 'meta' => ['tags' => ['a', 'b', 'c'], 'roles' => ['admin', 'editor']]],\n            $c->mergeRecursive(new $collection(['meta' => ['tags' => ['c'], 'roles' => 'editor']]))->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMultiplyCollection($collection)\n    {\n        $c = new $collection(['Hello', 1, ['tags' => ['a', 'b'], 'admin']]);\n\n        $this->assertEquals([], $c->multiply(-1)->all());\n        $this->assertEquals([], $c->multiply(0)->all());\n\n        $this->assertEquals(\n            ['Hello', 1, ['tags' => ['a', 'b'], 'admin']],\n            $c->multiply(1)->all()\n        );\n\n        $this->assertEquals(\n            ['Hello', 1, ['tags' => ['a', 'b'], 'admin'], 'Hello', 1, ['tags' => ['a', 'b'], 'admin'], 'Hello', 1, ['tags' => ['a', 'b'], 'admin']],\n            $c->multiply(3)->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceNull($collection)\n    {\n        $c = new $collection(['a', 'b', 'c']);\n        $this->assertEquals(['a', 'b', 'c'], $c->replace(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceArray($collection)\n    {\n        $c = new $collection(['a', 'b', 'c']);\n        $this->assertEquals(['a', 'd', 'e'], $c->replace([1 => 'd', 2 => 'e'])->all());\n\n        $c = new $collection(['a', 'b', 'c']);\n        $this->assertEquals(['a', 'd', 'e', 'f', 'g'], $c->replace([1 => 'd', 2 => 'e', 3 => 'f', 4 => 'g'])->all());\n\n        $c = new $collection(['name' => 'amir', 'family' => 'otwell']);\n        $this->assertEquals(['name' => 'taylor', 'family' => 'otwell', 'age' => 26], $c->replace(['name' => 'taylor', 'age' => 26])->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceCollection($collection)\n    {\n        $c = new $collection(['a', 'b', 'c']);\n        $this->assertEquals(\n            ['a', 'd', 'e'],\n            $c->replace(new $collection([1 => 'd', 2 => 'e']))->all()\n        );\n\n        $c = new $collection(['a', 'b', 'c']);\n        $this->assertEquals(\n            ['a', 'd', 'e', 'f', 'g'],\n            $c->replace(new $collection([1 => 'd', 2 => 'e', 3 => 'f', 4 => 'g']))->all()\n        );\n\n        $c = new $collection(['name' => 'amir', 'family' => 'otwell']);\n        $this->assertEquals(\n            ['name' => 'taylor', 'family' => 'otwell', 'age' => 26],\n            $c->replace(new $collection(['name' => 'taylor', 'age' => 26]))->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceRecursiveNull($collection)\n    {\n        $c = new $collection(['a', 'b', ['c', 'd']]);\n        $this->assertEquals(['a', 'b', ['c', 'd']], $c->replaceRecursive(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceRecursiveArray($collection)\n    {\n        $c = new $collection(['a', 'b', ['c', 'd']]);\n        $this->assertEquals(['z', 'b', ['c', 'e']], $c->replaceRecursive(['z', 2 => [1 => 'e']])->all());\n\n        $c = new $collection(['a', 'b', ['c', 'd']]);\n        $this->assertEquals(['z', 'b', ['c', 'e'], 'f'], $c->replaceRecursive(['z', 2 => [1 => 'e'], 'f'])->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReplaceRecursiveCollection($collection)\n    {\n        $c = new $collection(['a', 'b', ['c', 'd']]);\n        $this->assertEquals(\n            ['z', 'b', ['c', 'e']],\n            $c->replaceRecursive(new $collection(['z', 2 => [1 => 'e']]))->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnionNull($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello'], $c->union(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnionArray($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(['id' => 1])->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnionCollection($collection)\n    {\n        $c = new $collection(['name' => 'Hello']);\n        $this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(new $collection(['name' => 'World', 'id' => 1]))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffCollection($collection)\n    {\n        $c = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $this->assertEquals(['id' => 1], $c->diff(new $collection(['first_word' => 'Hello', 'last_word' => 'World']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffUsingWithCollection($collection)\n    {\n        $c = new $collection(['en_GB', 'fr', 'HR']);\n        // demonstrate that diff won't support case insensitivity\n        $this->assertEquals(['en_GB', 'fr', 'HR'], $c->diff(new $collection(['en_gb', 'hr']))->values()->toArray());\n        // allow for case insensitive difference\n        $this->assertEquals(['fr'], $c->diffUsing(new $collection(['en_gb', 'hr']), 'strcasecmp')->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffUsingWithNull($collection)\n    {\n        $c = new $collection(['en_GB', 'fr', 'HR']);\n        $this->assertEquals(['en_GB', 'fr', 'HR'], $c->diffUsing(null, 'strcasecmp')->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffNull($collection)\n    {\n        $c = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c->diff(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffKeys($collection)\n    {\n        $c1 = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $c2 = new $collection(['id' => 123, 'foo_bar' => 'Hello']);\n        $this->assertEquals(['first_word' => 'Hello'], $c1->diffKeys($c2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffKeysUsing($collection)\n    {\n        $c1 = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $c2 = new $collection(['ID' => 123, 'foo_bar' => 'Hello']);\n        // demonstrate that diffKeys won't support case insensitivity\n        $this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c1->diffKeys($c2)->all());\n        // allow for case insensitive difference\n        $this->assertEquals(['first_word' => 'Hello'], $c1->diffKeysUsing($c2, 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffAssoc($collection)\n    {\n        $c1 = new $collection(['id' => 1, 'first_word' => 'Hello', 'not_affected' => 'value']);\n        $c2 = new $collection(['id' => 123, 'foo_bar' => 'Hello', 'not_affected' => 'value']);\n        $this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c1->diffAssoc($c2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDiffAssocUsing($collection)\n    {\n        $c1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);\n        $c2 = new $collection(['A' => 'green', 'yellow', 'red']);\n        // demonstrate that the case of the keys will affect the output when diffAssoc is used\n        $this->assertEquals(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'], $c1->diffAssoc($c2)->all());\n        // allow for case insensitive difference\n        $this->assertEquals(['b' => 'brown', 'c' => 'blue', 'red'], $c1->diffAssocUsing($c2, 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDuplicates($collection)\n    {\n        $duplicates = $collection::make([1, 2, 1, 'laravel', null, 'laravel', 'php', null])->duplicates()->all();\n        $this->assertSame([2 => 1, 5 => 'laravel', 7 => null], $duplicates);\n\n        // does loose comparison\n        $duplicates = $collection::make([2, '2', [], null])->duplicates()->all();\n        $this->assertSame([1 => '2', 3 => null], $duplicates);\n\n        // works with mix of primitives\n        $duplicates = $collection::make([1, '2', ['laravel'], ['laravel'], null, '2'])->duplicates()->all();\n        $this->assertSame([3 => ['laravel'], 5 => '2'], $duplicates);\n\n        // works with mix of objects and primitives **excepts numbers**.\n        $expected = new Collection(['laravel']);\n        $duplicates = $collection::make([new Collection(['laravel']), $expected, $expected, [], '2', '2'])->duplicates()->all();\n        $this->assertSame([1 => $expected, 2 => $expected, 5 => '2'], $duplicates);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDuplicatesWithKey($collection)\n    {\n        $items = [['framework' => 'vue'], ['framework' => 'laravel'], ['framework' => 'laravel']];\n        $duplicates = $collection::make($items)->duplicates('framework')->all();\n        $this->assertSame([2 => 'laravel'], $duplicates);\n\n        // works with key and strict\n        $items = [['Framework' => 'vue'], ['framework' => 'vue'], ['Framework' => 'vue']];\n        $duplicates = $collection::make($items)->duplicates('Framework', true)->all();\n        $this->assertSame([2 => 'vue'], $duplicates);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDuplicatesWithCallback($collection)\n    {\n        $items = [['framework' => 'vue'], ['framework' => 'laravel'], ['framework' => 'laravel']];\n        $duplicates = $collection::make($items)->duplicates(function ($item) {\n            return $item['framework'];\n        })->all();\n        $this->assertSame([2 => 'laravel'], $duplicates);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDuplicatesWithStrict($collection)\n    {\n        $duplicates = $collection::make([1, 2, 1, 'laravel', null, 'laravel', 'php', null])->duplicatesStrict()->all();\n        $this->assertSame([2 => 1, 5 => 'laravel', 7 => null], $duplicates);\n\n        // does strict comparison\n        $duplicates = $collection::make([2, '2', [], null])->duplicatesStrict()->all();\n        $this->assertSame([], $duplicates);\n\n        // works with mix of primitives\n        $duplicates = $collection::make([1, '2', ['laravel'], ['laravel'], null, '2'])->duplicatesStrict()->all();\n        $this->assertSame([3 => ['laravel'], 5 => '2'], $duplicates);\n\n        // works with mix of primitives, objects, and numbers\n        $expected = new $collection(['laravel']);\n        $duplicates = $collection::make([new $collection(['laravel']), $expected, $expected, [], '2', '2'])->duplicatesStrict()->all();\n        $this->assertSame([2 => $expected, 5 => '2'], $duplicates);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEach($collection)\n    {\n        $c = new $collection($original = [1, 2, 'foo' => 'bar', 'bam' => 'baz']);\n\n        $result = [];\n        $c->each(function ($item, $key) use (&$result) {\n            $result[$key] = $item;\n        });\n        $this->assertEquals($original, $result);\n\n        $result = [];\n        $c->each(function ($item, $key) use (&$result) {\n            $result[$key] = $item;\n            if (is_string($key)) {\n                return false;\n            }\n        });\n        $this->assertEquals([1, 2, 'foo' => 'bar'], $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEachSpread($collection)\n    {\n        $c = new $collection([[1, 'a'], [2, 'b']]);\n\n        $result = [];\n        $c->eachSpread(function ($number, $character) use (&$result) {\n            $result[] = [$number, $character];\n        });\n        $this->assertEquals($c->all(), $result);\n\n        $result = [];\n        $c->eachSpread(function ($number, $character) use (&$result) {\n            $result[] = [$number, $character];\n\n            return false;\n        });\n        $this->assertEquals([[1, 'a']], $result);\n\n        $result = [];\n        $c->eachSpread(function ($number, $character, $key) use (&$result) {\n            $result[] = [$number, $character, $key];\n        });\n        $this->assertEquals([[1, 'a', 0], [2, 'b', 1]], $result);\n\n        $c = new $collection([new Collection([1, 'a']), new Collection([2, 'b'])]);\n        $result = [];\n        $c->eachSpread(function ($number, $character, $key) use (&$result) {\n            $result[] = [$number, $character, $key];\n        });\n        $this->assertEquals([[1, 'a', 0], [2, 'b', 1]], $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectNull($collection)\n    {\n        $c = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $this->assertEquals([], $c->intersect(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectCollection($collection)\n    {\n        $c = new $collection(['id' => 1, 'first_word' => 'Hello']);\n        $this->assertEquals(['first_word' => 'Hello'], $c->intersect(new $collection(['first_world' => 'Hello', 'last_word' => 'World']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectUsingWithNull($collection)\n    {\n        $collect = new $collection(['green', 'brown', 'blue']);\n\n        $this->assertEquals([], $collect->intersectUsing(null, 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectUsingCollection($collection)\n    {\n        $collect = new $collection(['green', 'brown', 'blue']);\n\n        $this->assertEquals(['green', 'brown'], $collect->intersectUsing(new $collection(['GREEN', 'brown', 'yellow']), 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectAssocWithNull($collection)\n    {\n        $array1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);\n\n        $this->assertEquals([], $array1->intersectAssoc(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectAssocCollection($collection)\n    {\n        $array1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);\n        $array2 = new $collection(['a' => 'green', 'b' => 'yellow', 'blue', 'red']);\n\n        $this->assertEquals(['a' => 'green'], $array1->intersectAssoc($array2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectAssocUsingWithNull($collection)\n    {\n        $array1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);\n\n        $this->assertEquals([], $array1->intersectAssocUsing(null, 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectAssocUsingCollection($collection)\n    {\n        $array1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);\n        $array2 = new $collection(['a' => 'GREEN', 'B' => 'brown', 'yellow', 'red']);\n\n        $this->assertEquals(['b' => 'brown'], $array1->intersectAssocUsing($array2, 'strcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectByKeysNull($collection)\n    {\n        $c = new $collection(['name' => 'Mateus', 'age' => 18]);\n        $this->assertEquals([], $c->intersectByKeys(null)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testIntersectByKeys($collection)\n    {\n        $c = new $collection(['name' => 'Mateus', 'age' => 18]);\n        $this->assertEquals(['name' => 'Mateus'], $c->intersectByKeys(new $collection(['name' => 'Mateus', 'surname' => 'Guimaraes']))->all());\n\n        $c = new $collection(['name' => 'taylor', 'family' => 'otwell', 'age' => 26]);\n        $this->assertEquals(['name' => 'taylor', 'family' => 'otwell'], $c->intersectByKeys(new $collection(['height' => 180, 'name' => 'amir', 'family' => 'moharami']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnique($collection)\n    {\n        $c = new $collection(['Hello', 'World', 'World']);\n        $this->assertEquals(['Hello', 'World'], $c->unique()->all());\n\n        $c = new $collection([[1, 2], [1, 2], [2, 3], [3, 4], [2, 3]]);\n        $this->assertEquals([[1, 2], [2, 3], [3, 4]], $c->unique()->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUniqueWithCallback($collection)\n    {\n        $c = new $collection([\n            1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],\n            2 => ['id' => 2, 'first' => 'Taylor', 'last' => 'Otwell'],\n            3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'],\n            4 => ['id' => 4, 'first' => 'Abigail', 'last' => 'Otwell'],\n            5 => ['id' => 5, 'first' => 'Taylor', 'last' => 'Swift'],\n            6 => ['id' => 6, 'first' => 'Taylor', 'last' => 'Swift'],\n        ]);\n\n        $this->assertEquals([\n            1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],\n            3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'],\n        ], $c->unique('first')->all());\n\n        $this->assertEquals([\n            1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],\n            3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'],\n            5 => ['id' => 5, 'first' => 'Taylor', 'last' => 'Swift'],\n        ], $c->unique(function ($item) {\n            return $item['first'].$item['last'];\n        })->all());\n\n        $this->assertEquals([\n            1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],\n            2 => ['id' => 2, 'first' => 'Taylor', 'last' => 'Otwell'],\n        ], $c->unique(function ($item, $key) {\n            return $key % 2;\n        })->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUniqueStrict($collection)\n    {\n        $c = new $collection([\n            [\n                'id' => '0',\n                'name' => 'zero',\n            ],\n            [\n                'id' => '00',\n                'name' => 'double zero',\n            ],\n            [\n                'id' => '0',\n                'name' => 'again zero',\n            ],\n        ]);\n\n        $this->assertEquals([\n            [\n                'id' => '0',\n                'name' => 'zero',\n            ],\n            [\n                'id' => '00',\n                'name' => 'double zero',\n            ],\n        ], $c->uniqueStrict('id')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollapse($collection)\n    {\n        // Normal case: a two-dimensional array with different elements\n        $data = new $collection([[$object1 = new stdClass], [$object2 = new stdClass]]);\n        $this->assertEquals([$object1, $object2], $data->collapse()->all());\n\n        // Case including numeric and string elements\n        $data = new $collection([[1], [2], [3], ['foo', 'bar'], new $collection(['baz', 'boom'])]);\n        $this->assertEquals([1, 2, 3, 'foo', 'bar', 'baz', 'boom'], $data->collapse()->all());\n\n        // Case with empty two-dimensional arrays\n        $data = new $collection([[], [], []]);\n        $this->assertEquals([], $data->collapse()->all());\n\n        // Case with both empty arrays and arrays with elements\n        $data = new $collection([[], [1, 2], [], ['foo', 'bar']]);\n        $this->assertEquals([1, 2, 'foo', 'bar'], $data->collapse()->all());\n\n        // Case including collections and arrays\n        $collection = new $collection(['baz', 'boom']);\n        $data = new $collection([[1], [2], [3], ['foo', 'bar'], $collection]);\n        $this->assertEquals([1, 2, 3, 'foo', 'bar', 'baz', 'boom'], $data->collapse()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollapseWithNestedCollections($collection)\n    {\n        $data = new $collection([new $collection([1, 2, 3]), new $collection([4, 5, 6])]);\n        $this->assertEquals([1, 2, 3, 4, 5, 6], $data->collapse()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollapseWithKeys($collection)\n    {\n        $data = new $collection([[1 => 'a'], [3 => 'c'], [2 => 'b'], 'drop']);\n        $this->assertEquals([1 => 'a', 3 => 'c', 2 => 'b'], $data->collapseWithKeys()->all());\n\n        // Case with an already flat collection\n        $data = new $collection(['a', 'b', 'c']);\n        $this->assertEquals([], $data->collapseWithKeys()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollapseWithKeysOnNestedCollections($collection)\n    {\n        $data = new $collection([new $collection(['a' => '1a', 'b' => '1b']), new $collection(['b' => '2b', 'c' => '2c']), 'drop']);\n        $this->assertEquals(['a' => '1a', 'b' => '2b', 'c' => '2c'], $data->collapseWithKeys()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testJoin($collection)\n    {\n        $this->assertSame('a, b, c', (new $collection(['a', 'b', 'c']))->join(', '));\n\n        $this->assertSame('a, b and c', (new $collection(['a', 'b', 'c']))->join(', ', ' and '));\n\n        $this->assertSame('a and b', (new $collection(['a', 'b']))->join(', ', ' and '));\n\n        $this->assertSame('a', (new $collection(['a']))->join(', ', ' and '));\n\n        $this->assertSame('', (new $collection([]))->join(', ', ' and '));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCrossJoin($collection)\n    {\n        // Cross join with an array\n        $this->assertEquals(\n            [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']],\n            (new $collection([1, 2]))->crossJoin(['a', 'b'])->all()\n        );\n\n        // Cross join with a collection\n        $this->assertEquals(\n            [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']],\n            (new $collection([1, 2]))->crossJoin(new $collection(['a', 'b']))->all()\n        );\n\n        // Cross join with 2 collections\n        $this->assertEquals(\n            [\n                [1, 'a', 'I'], [1, 'a', 'II'],\n                [1, 'b', 'I'], [1, 'b', 'II'],\n                [2, 'a', 'I'], [2, 'a', 'II'],\n                [2, 'b', 'I'], [2, 'b', 'II'],\n            ],\n            (new $collection([1, 2]))->crossJoin(\n                new $collection(['a', 'b']),\n                new $collection(['I', 'II'])\n            )->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSort($collection)\n    {\n        $data = (new $collection([5, 3, 1, 2, 4]))->sort();\n        $this->assertEquals([1, 2, 3, 4, 5], $data->values()->all());\n\n        $data = (new $collection([-1, -3, -2, -4, -5, 0, 5, 3, 1, 2, 4]))->sort();\n        $this->assertEquals([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], $data->values()->all());\n\n        $data = (new $collection(['foo', 'bar-10', 'bar-1']))->sort();\n        $this->assertEquals(['bar-1', 'bar-10', 'foo'], $data->values()->all());\n\n        $data = (new $collection(['T2', 'T1', 'T10']))->sort();\n        $this->assertEquals(['T1', 'T10', 'T2'], $data->values()->all());\n\n        $data = (new $collection(['T2', 'T1', 'T10']))->sort(SORT_NATURAL);\n        $this->assertEquals(['T1', 'T2', 'T10'], $data->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortDesc($collection)\n    {\n        $data = (new $collection([5, 3, 1, 2, 4]))->sortDesc();\n        $this->assertEquals([5, 4, 3, 2, 1], $data->values()->all());\n\n        $data = (new $collection([-1, -3, -2, -4, -5, 0, 5, 3, 1, 2, 4]))->sortDesc();\n        $this->assertEquals([5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5], $data->values()->all());\n\n        $data = (new $collection(['bar-1', 'foo', 'bar-10']))->sortDesc();\n        $this->assertEquals(['foo', 'bar-10', 'bar-1'], $data->values()->all());\n\n        $data = (new $collection(['T2', 'T1', 'T10']))->sortDesc();\n        $this->assertEquals(['T2', 'T10', 'T1'], $data->values()->all());\n\n        $data = (new $collection(['T2', 'T1', 'T10']))->sortDesc(SORT_NATURAL);\n        $this->assertEquals(['T10', 'T2', 'T1'], $data->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortWithCallback($collection)\n    {\n        $data = (new $collection([5, 3, 1, 2, 4]))->sort(function ($a, $b) {\n            if ($a === $b) {\n                return 0;\n            }\n\n            return ($a < $b) ? -1 : 1;\n        });\n\n        $this->assertEquals(range(1, 5), array_values($data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortBy($collection)\n    {\n        $data = new $collection(['taylor', 'dayle']);\n        $data = $data->sortBy(function ($x) {\n            return $x;\n        });\n\n        $this->assertEquals(['dayle', 'taylor'], array_values($data->all()));\n\n        $data = new $collection(['dayle', 'taylor']);\n        $data = $data->sortByDesc(function ($x) {\n            return $x;\n        });\n\n        $this->assertEquals(['taylor', 'dayle'], array_values($data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortByString($collection)\n    {\n        $data = new $collection([['name' => 'taylor'], ['name' => 'dayle']]);\n        $data = $data->sortBy('name', SORT_STRING);\n\n        $this->assertEquals([['name' => 'dayle'], ['name' => 'taylor']], array_values($data->all()));\n\n        $data = new $collection([['name' => 'taylor'], ['name' => 'dayle']]);\n        $data = $data->sortBy('name', SORT_STRING, true);\n\n        $this->assertEquals([['name' => 'taylor'], ['name' => 'dayle']], array_values($data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortByCallableString($collection)\n    {\n        $data = new $collection([['sort' => 2], ['sort' => 1]]);\n        $data = $data->sortBy([['sort', 'asc']]);\n\n        $this->assertEquals([['sort' => 1], ['sort' => 2]], array_values($data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortByCallableStringDesc($collection)\n    {\n        $data = new $collection([['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar']]);\n        $data = $data->sortByDesc(['id']);\n        $this->assertEquals([['id' => 2, 'name' => 'bar'], ['id' => 1, 'name' => 'foo']], array_values($data->all()));\n\n        $data = new $collection([['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar'], ['id' => 2, 'name' => 'baz']]);\n        $data = $data->sortByDesc(['id']);\n        $this->assertEquals([['id' => 2, 'name' => 'bar'], ['id' => 2, 'name' => 'baz'], ['id' => 1, 'name' => 'foo']], array_values($data->all()));\n\n        $data = $data->sortByDesc(['id', 'name']);\n        $this->assertEquals([['id' => 2, 'name' => 'baz'], ['id' => 2, 'name' => 'bar'], ['id' => 1, 'name' => 'foo']], array_values($data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortByAlwaysReturnsAssoc($collection)\n    {\n        $data = new $collection(['a' => 'taylor', 'b' => 'dayle']);\n        $data = $data->sortBy(function ($x) {\n            return $x;\n        });\n\n        $this->assertEquals(['b' => 'dayle', 'a' => 'taylor'], $data->all());\n\n        $data = new $collection(['taylor', 'dayle']);\n        $data = $data->sortBy(function ($x) {\n            return $x;\n        });\n\n        $this->assertEquals([1 => 'dayle', 0 => 'taylor'], $data->all());\n\n        $data = new $collection(['a' => ['sort' => 2], 'b' => ['sort' => 1]]);\n        $data = $data->sortBy([['sort', 'asc']]);\n\n        $this->assertEquals(['b' => ['sort' => 1], 'a' => ['sort' => 2]], $data->all());\n\n        $data = new $collection([['sort' => 2], ['sort' => 1]]);\n        $data = $data->sortBy([['sort', 'asc']]);\n\n        $this->assertEquals([1 => ['sort' => 1], 0 => ['sort' => 2]], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortByMany($collection)\n    {\n        $defaultLocale = setlocale(LC_ALL, 0);\n\n        $data = new $collection([['item' => '1'], ['item' => '10'], ['item' => 5], ['item' => 20]]);\n        $expected = $data->pluck('item')->toArray();\n\n        sort($expected);\n        $data = $data->sortBy(['item']);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        rsort($expected);\n        $data = $data->sortBy([['item', 'desc']]);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_STRING);\n        $data = $data->sortBy(['item'], SORT_STRING);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        rsort($expected, SORT_STRING);\n        $data = $data->sortBy([['item', 'desc']], SORT_STRING);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_NUMERIC);\n        $data = $data->sortBy(['item'], SORT_NUMERIC);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        rsort($expected, SORT_NUMERIC);\n        $data = $data->sortBy([['item', 'desc']], SORT_NUMERIC);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        $data = new $collection([['item' => 'img1'], ['item' => 'img101'], ['item' => 'img10'], ['item' => 'img11']]);\n        $expected = $data->pluck('item')->toArray();\n\n        sort($expected, SORT_NUMERIC);\n        $data = $data->sortBy(['item'], SORT_NUMERIC);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected);\n        $data = $data->sortBy(['item']);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_NATURAL);\n        $data = $data->sortBy(['item'], SORT_NATURAL);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        $data = new $collection([['item' => 'img1'], ['item' => 'Img101'], ['item' => 'img10'], ['item' => 'Img11']]);\n        $expected = $data->pluck('item')->toArray();\n\n        sort($expected);\n        $data = $data->sortBy(['item']);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_NATURAL | SORT_FLAG_CASE);\n        $data = $data->sortBy(['item'], SORT_NATURAL | SORT_FLAG_CASE);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_FLAG_CASE | SORT_STRING);\n        $data = $data->sortBy(['item'], SORT_FLAG_CASE | SORT_STRING);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_FLAG_CASE | SORT_NUMERIC);\n        $data = $data->sortBy(['item'], SORT_FLAG_CASE | SORT_NUMERIC);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        $data = new $collection([['item' => 'Österreich'], ['item' => 'Oesterreich'], ['item' => 'Zeta']]);\n        $expected = $data->pluck('item')->toArray();\n\n        sort($expected);\n        $data = $data->sortBy(['item']);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        sort($expected, SORT_LOCALE_STRING);\n        $data = $data->sortBy(['item'], SORT_LOCALE_STRING);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        setlocale(LC_ALL, 'de_DE');\n\n        sort($expected, SORT_LOCALE_STRING);\n        $data = $data->sortBy(['item'], SORT_LOCALE_STRING);\n        $this->assertEquals($data->pluck('item')->toArray(), $expected);\n\n        setlocale(LC_ALL, $defaultLocale);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testNaturalSortByManyWithNull($collection)\n    {\n        $itemFoo = new \\stdClass();\n        $itemFoo->first = 'f';\n        $itemFoo->second = null;\n        $itemBar = new \\stdClass();\n        $itemBar->first = 'f';\n        $itemBar->second = 's';\n\n        $data = new $collection([$itemFoo, $itemBar]);\n        $data = $data->sortBy([\n            ['first', 'desc'],\n            ['second', 'desc'],\n        ], SORT_NATURAL);\n\n        $this->assertEquals($itemBar, $data->first());\n        $this->assertEquals($itemFoo, $data->skip(1)->first());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortKeys($collection)\n    {\n        $data = new $collection(['b' => 'dayle', 'a' => 'taylor']);\n\n        $this->assertSame(['a' => 'taylor', 'b' => 'dayle'], $data->sortKeys()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortKeysDesc($collection)\n    {\n        $data = new $collection(['a' => 'taylor', 'b' => 'dayle']);\n\n        $this->assertSame(['b' => 'dayle', 'a' => 'taylor'], $data->sortKeysDesc()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSortKeysUsing($collection)\n    {\n        $data = new $collection(['B' => 'dayle', 'a' => 'taylor']);\n\n        $this->assertSame(['a' => 'taylor', 'B' => 'dayle'], $data->sortKeysUsing('strnatcasecmp')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReverse($collection)\n    {\n        $data = new $collection(['zaeed', 'alan']);\n        $reversed = $data->reverse();\n\n        $this->assertSame([1 => 'alan', 0 => 'zaeed'], $reversed->all());\n\n        $data = new $collection(['name' => 'taylor', 'framework' => 'laravel']);\n        $reversed = $data->reverse();\n\n        $this->assertSame(['framework' => 'laravel', 'name' => 'taylor'], $reversed->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFlip($collection)\n    {\n        $data = new $collection(['name' => 'taylor', 'framework' => 'laravel']);\n        $this->assertEquals(['taylor' => 'name', 'laravel' => 'framework'], $data->flip()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunk($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n        $data = $data->chunk(3);\n\n        $this->assertInstanceOf($collection, $data);\n        $this->assertInstanceOf($collection, $data->first());\n        $this->assertCount(4, $data);\n        $this->assertEquals([1, 2, 3], $data->first()->toArray());\n        $this->assertEquals([9 => 10], $data->get(3)->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkWhenGivenZeroAsSize($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n\n        $this->assertEquals(\n            [],\n            $data->chunk(0)->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkWhenGivenLessThanZero($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n\n        $this->assertEquals(\n            [],\n            $data->chunk(-1)->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkPreservingKeys($collection)\n    {\n        $data = new $collection(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5]);\n\n        $this->assertEquals(\n            [['a' => 1, 'b' => 2], ['c' => 3, 'd' => 4], ['e' => 5]],\n            $data->chunk(2)->toArray()\n        );\n\n        $data = new $collection([1, 2, 3, 4, 5]);\n\n        $this->assertEquals(\n            [[0 => 1, 1 => 2], [0 => 3, 1 => 4], [0 => 5]],\n            $data->chunk(2, false)->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitIn($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n        $data = $data->splitIn(3);\n\n        $this->assertInstanceOf($collection, $data);\n        $this->assertInstanceOf($collection, $data->first());\n        $this->assertCount(3, $data);\n        $this->assertEquals([1, 2, 3, 4], $data->get(0)->values()->toArray());\n        $this->assertEquals([5, 6, 7, 8], $data->get(1)->values()->toArray());\n        $this->assertEquals([9, 10], $data->get(2)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkWhileOnEqualElements($collection)\n    {\n        $data = (new $collection(['A', 'A', 'B', 'B', 'C', 'C', 'C']))\n            ->chunkWhile(function ($current, $key, $chunk) {\n                return $chunk->last() === $current;\n            });\n\n        $this->assertInstanceOf($collection, $data);\n        $this->assertInstanceOf($collection, $data->first());\n        $this->assertEquals([0 => 'A', 1 => 'A'], $data->first()->toArray());\n        $this->assertEquals([2 => 'B', 3 => 'B'], $data->get(1)->toArray());\n        $this->assertEquals([4 => 'C', 5 => 'C', 6 => 'C'], $data->last()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkWhileOnContiguouslyIncreasingIntegers($collection)\n    {\n        $data = (new $collection([1, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21]))\n            ->chunkWhile(function ($current, $key, $chunk) {\n                return $chunk->last() + 1 == $current;\n            });\n\n        $this->assertInstanceOf($collection, $data);\n        $this->assertInstanceOf($collection, $data->first());\n        $this->assertEquals([0 => 1], $data->first()->toArray());\n        $this->assertEquals([1 => 4], $data->get(1)->toArray());\n        $this->assertEquals([2 => 9, 3 => 10, 4 => 11, 5 => 12], $data->get(2)->toArray());\n        $this->assertEquals([6 => 15, 7 => 16], $data->get(3)->toArray());\n        $this->assertEquals([8 => 19, 9 => 20, 10 => 21], $data->last()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testChunkWhilePreservingStringKeys($collection)\n    {\n        $data = (new $collection(['a' => 1, 'b' => 1, 'c' => 2, 'd' => 2, 'e' => 3, 'f' => 3, 'g' => 3]))\n            ->chunkWhile(function ($current, $key, $chunk) {\n                return $chunk->last() === $current;\n            });\n\n        $this->assertInstanceOf($collection, $data);\n        $this->assertInstanceOf($collection, $data->first());\n        $this->assertEquals(['a' => 1, 'b' => 1], $data->first()->toArray());\n        $this->assertEquals(['c' => 2, 'd' => 2], $data->get(1)->toArray());\n        $this->assertEquals(['e' => 3, 'f' => 3, 'g' => 3], $data->last()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEvery($collection)\n    {\n        $c = new $collection([]);\n        $this->assertTrue($c->every('key', 'value'));\n        $this->assertTrue($c->every(function () {\n            return false;\n        }));\n\n        $c = new $collection([['age' => 18], ['age' => 20], ['age' => 20]]);\n        $this->assertFalse($c->every('age', 18));\n        $this->assertTrue($c->every('age', '>=', 18));\n        $this->assertTrue($c->every(function ($item) {\n            return $item['age'] >= 18;\n        }));\n        $this->assertFalse($c->every(function ($item) {\n            return $item['age'] >= 20;\n        }));\n\n        $c = new $collection([null, null]);\n        $this->assertTrue($c->every(function ($item) {\n            return $item === null;\n        }));\n\n        $c = new $collection([['active' => true], ['active' => true]]);\n        $this->assertTrue($c->every('active'));\n        $this->assertTrue($c->every->active);\n        $this->assertFalse($c->concat([['active' => false]])->every->active);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testExcept($collection)\n    {\n        $data = new $collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);\n\n        $this->assertEquals($data->all(), $data->except(null)->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->except(['last', 'email', 'missing'])->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->except('last', 'email', 'missing')->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->except(collect(['last', 'email', 'missing']))->all());\n\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except(['last'])->all());\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except('last')->all());\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except(collect(['last']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testExceptSelf($collection)\n    {\n        $data = new $collection(['first' => 'Taylor', 'last' => 'Otwell']);\n        $this->assertEquals(['first' => 'Taylor', 'last' => 'Otwell'], $data->except($data)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPluckWithArrayAndObjectValues($collection)\n    {\n        $data = new $collection([(object) ['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);\n        $this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], $data->pluck('email', 'name')->all());\n        $this->assertEquals(['foo', 'bar'], $data->pluck('email')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPluckWithArrayAccessValues($collection)\n    {\n        $data = new $collection([\n            new TestArrayAccessImplementation(['name' => 'taylor', 'email' => 'foo']),\n            new TestArrayAccessImplementation(['name' => 'dayle', 'email' => 'bar']),\n        ]);\n\n        $this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], $data->pluck('email', 'name')->all());\n        $this->assertEquals(['foo', 'bar'], $data->pluck('email')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPluckWithDotNotation($collection)\n    {\n        $data = new $collection([\n            [\n                'name' => 'amir',\n                'skill' => [\n                    'backend' => ['php', 'python'],\n                ],\n            ],\n            [\n                'name' => 'taylor',\n                'skill' => [\n                    'backend' => ['php', 'asp', 'java'],\n                ],\n            ],\n        ]);\n\n        $this->assertEquals([['php', 'python'], ['php', 'asp', 'java']], $data->pluck('skill.backend')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPluckWithClosure($collection)\n    {\n        $data = new $collection([\n            [\n                'name' => 'amir',\n                'skill' => [\n                    'backend' => ['php', 'python'],\n                ],\n            ],\n            [\n                'name' => 'taylor',\n                'skill' => [\n                    'backend' => ['php', 'asp', 'java'],\n                ],\n            ],\n        ]);\n\n        $this->assertEquals(['amir (verified)', 'taylor (verified)'], $data->pluck(fn (array $row) => \"{$row['name']} (verified)\")->all());\n        $this->assertEquals(['php/python' => 'amir', 'php/asp/java' => 'taylor'], $data->pluck('name', fn (array $row) => implode('/', $row['skill']['backend']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPluckDuplicateKeysExist($collection)\n    {\n        $data = new $collection([\n            ['brand' => 'Tesla', 'color' => 'red'],\n            ['brand' => 'Pagani', 'color' => 'white'],\n            ['brand' => 'Tesla', 'color' => 'black'],\n            ['brand' => 'Pagani', 'color' => 'orange'],\n        ]);\n\n        $this->assertEquals(['Tesla' => 'black', 'Pagani' => 'orange'], $data->pluck('color', 'brand')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHas($collection)\n    {\n        $data = new $collection(['id' => 1, 'first' => 'Hello', 'second' => 'World']);\n        $this->assertTrue($data->has('first'));\n        $this->assertFalse($data->has('third'));\n        $this->assertTrue($data->has(['first', 'second']));\n        $this->assertFalse($data->has(['third', 'first']));\n        $this->assertTrue($data->has('first', 'second'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHasAny($collection)\n    {\n        $data = new $collection(['id' => 1, 'first' => 'Hello', 'second' => 'World']);\n\n        $this->assertTrue($data->hasAny('first'));\n        $this->assertFalse($data->hasAny('third'));\n        $this->assertTrue($data->hasAny(['first', 'second']));\n        $this->assertTrue($data->hasAny(['first', 'fourth']));\n        $this->assertFalse($data->hasAny(['third', 'fourth']));\n        $this->assertFalse($data->hasAny('third', 'fourth'));\n        $this->assertFalse($data->hasAny([]));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testImplode($collection)\n    {\n        $data = new $collection([['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);\n        $this->assertSame('foobar', $data->implode('email'));\n        $this->assertSame('foo,bar', $data->implode('email', ','));\n\n        $data = new $collection(['taylor', 'dayle']);\n        $this->assertSame('taylordayle', $data->implode(''));\n        $this->assertSame('taylor,dayle', $data->implode(','));\n\n        $data = new $collection([\n            ['name' => new Stringable('taylor'), 'email' => new Stringable('foo')],\n            ['name' => new Stringable('dayle'), 'email' => new Stringable('bar')],\n        ]);\n        $this->assertSame('foobar', $data->implode('email'));\n        $this->assertSame('foo,bar', $data->implode('email', ','));\n\n        $data = new $collection([new Stringable('taylor'), new Stringable('dayle')]);\n        $this->assertSame('taylordayle', $data->implode(''));\n        $this->assertSame('taylor,dayle', $data->implode(','));\n        $this->assertSame('taylor_dayle', $data->implode('_'));\n\n        $data = new $collection([['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);\n        $this->assertSame('taylor-foodayle-bar', $data->implode(fn ($user) => $user['name'].'-'.$user['email']));\n        $this->assertSame('taylor-foo,dayle-bar', $data->implode(fn ($user) => $user['name'].'-'.$user['email'], ','));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testImplodeModels($collection)\n    {\n        $model = new class extends Model {\n        };\n        $model->setAttribute('email', 'foo');\n        $modelTwo = new class extends Model {\n        };\n        $modelTwo->setAttribute('email', 'bar');\n        $data = new $collection([$model, $modelTwo]);\n\n        $this->assertSame('foobar', $data->implode('email'));\n        $this->assertSame('foo,bar', $data->implode('email', ','));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTake($collection)\n    {\n        $data = new $collection(['taylor', 'dayle', 'shawn']);\n        $data = $data->take(2);\n        $this->assertEquals(['taylor', 'dayle'], $data->all());\n    }\n\n    public function testGetOrPut()\n    {\n        $data = new Collection(['name' => 'taylor', 'email' => 'foo']);\n\n        $this->assertSame('taylor', $data->getOrPut('name', null));\n        $this->assertSame('foo', $data->getOrPut('email', null));\n        $this->assertSame('male', $data->getOrPut('gender', 'male'));\n\n        $this->assertSame('taylor', $data->get('name'));\n        $this->assertSame('foo', $data->get('email'));\n        $this->assertSame('male', $data->get('gender'));\n\n        $data = new Collection(['name' => 'taylor', 'email' => 'foo']);\n\n        $this->assertSame('taylor', $data->getOrPut('name', function () {\n            return null;\n        }));\n\n        $this->assertSame('foo', $data->getOrPut('email', function () {\n            return null;\n        }));\n\n        $this->assertSame('male', $data->getOrPut('gender', function () {\n            return 'male';\n        }));\n\n        $this->assertSame('taylor', $data->get('name'));\n        $this->assertSame('foo', $data->get('email'));\n        $this->assertSame('male', $data->get('gender'));\n    }\n\n    public function testGetOrPutWithNoKey()\n    {\n        $data = new Collection(['taylor', 'shawn']);\n        $this->assertSame('dayle', $data->getOrPut(null, 'dayle'));\n        $this->assertSame('john', $data->getOrPut(null, 'john'));\n        $this->assertSame(['taylor', 'shawn', 'dayle', 'john'], $data->all());\n\n        $data = new Collection(['taylor', '' => 'shawn']);\n        $this->assertSame('shawn', $data->getOrPut(null, 'dayle'));\n        $this->assertSame(['taylor', '' => 'shawn'], $data->all());\n    }\n\n    public function testPut()\n    {\n        $data = new Collection(['name' => 'taylor', 'email' => 'foo']);\n        $data = $data->put('name', 'dayle');\n        $this->assertEquals(['name' => 'dayle', 'email' => 'foo'], $data->all());\n    }\n\n    public function testPutWithNoKey()\n    {\n        $data = new Collection(['taylor', 'shawn']);\n        $data = $data->put(null, 'dayle');\n        $this->assertEquals(['taylor', 'shawn', 'dayle'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRandom($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6]);\n\n        $random = $data->random();\n        $this->assertIsInt($random);\n        $this->assertContains($random, $data->all());\n\n        $random = $data->random(0);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(0, $random);\n\n        $random = $data->random(1);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(1, $random);\n\n        $random = $data->random(2);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(2, $random);\n\n        $random = $data->random('0');\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(0, $random);\n\n        $random = $data->random('1');\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(1, $random);\n\n        $random = $data->random('2');\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(2, $random);\n\n        $random = $data->random(2, true);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(2, $random);\n        $this->assertCount(2, array_intersect_assoc($random->all(), $data->all()));\n\n        $random = $data->random(fn ($items) => min(10, count($items)));\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(6, $random);\n\n        $random = $data->random(fn ($items) => min(10, count($items) - 1), true);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(5, $random);\n        $this->assertCount(5, array_intersect_assoc($random->all(), $data->all()));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRandomOnEmptyCollection($collection)\n    {\n        $data = new $collection;\n\n        $random = $data->random(0);\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(0, $random);\n\n        $random = $data->random('0');\n        $this->assertInstanceOf($collection, $random);\n        $this->assertCount(0, $random);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeLast($collection)\n    {\n        $data = new $collection(['taylor', 'dayle', 'shawn']);\n        $data = $data->take(-2);\n        $this->assertEquals([1 => 'dayle', 2 => 'shawn'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeUntilUsingValue($collection)\n    {\n        $data = new $collection([1, 2, 3, 4]);\n\n        $data = $data->takeUntil(3);\n\n        $this->assertSame([1, 2], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeUntilUsingCallback($collection)\n    {\n        $data = new $collection([1, 2, 3, 4]);\n\n        $data = $data->takeUntil(function ($item) {\n            return $item >= 3;\n        });\n\n        $this->assertSame([1, 2], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeUntilReturnsAllItemsForUnmetValue($collection)\n    {\n        $data = new $collection([1, 2, 3, 4]);\n\n        $actual = $data->takeUntil(99);\n\n        $this->assertSame($data->toArray(), $actual->toArray());\n\n        $actual = $data->takeUntil(function ($item) {\n            return $item >= 99;\n        });\n\n        $this->assertSame($data->toArray(), $actual->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeUntilCanBeProxied($collection)\n    {\n        $data = new $collection([\n            new TestSupportCollectionHigherOrderItem('Adam'),\n            new TestSupportCollectionHigherOrderItem('Taylor'),\n            new TestSupportCollectionHigherOrderItem('Jason'),\n        ]);\n\n        $actual = $data->takeUntil->is('Jason');\n\n        $this->assertCount(2, $actual);\n        $this->assertSame('Adam', $actual->get(0)->name);\n        $this->assertSame('Taylor', $actual->get(1)->name);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeWhileUsingValue($collection)\n    {\n        $data = new $collection([1, 1, 2, 2, 3, 3]);\n\n        $data = $data->takeWhile(1);\n\n        $this->assertSame([1, 1], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeWhileUsingCallback($collection)\n    {\n        $data = new $collection([1, 2, 3, 4]);\n\n        $data = $data->takeWhile(function ($item) {\n            return $item < 3;\n        });\n\n        $this->assertSame([1, 2], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeWhileReturnsNoItemsForUnmetValue($collection)\n    {\n        $data = new $collection([1, 2, 3, 4]);\n\n        $actual = $data->takeWhile(2);\n\n        $this->assertSame([], $actual->toArray());\n\n        $actual = $data->takeWhile(function ($item) {\n            return $item == 99;\n        });\n\n        $this->assertSame([], $actual->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTakeWhileCanBeProxied($collection)\n    {\n        $data = new $collection([\n            new TestSupportCollectionHigherOrderItem('Adam'),\n            new TestSupportCollectionHigherOrderItem('Adam'),\n            new TestSupportCollectionHigherOrderItem('Taylor'),\n            new TestSupportCollectionHigherOrderItem('Taylor'),\n        ]);\n\n        $actual = $data->takeWhile->is('Adam');\n\n        $this->assertCount(2, $actual);\n        $this->assertSame('Adam', $actual->get(0)->name);\n        $this->assertSame('Adam', $actual->get(1)->name);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMacroable($collection)\n    {\n        // Foo() macro : unique values starting with A\n        $collection::macro('foo', function () {\n            return $this->filter(function ($item) {\n                return str_starts_with($item, 'a');\n            })\n                ->unique()\n                ->values();\n        });\n\n        $c = new $collection(['a', 'a', 'aa', 'aaa', 'bar']);\n\n        $this->assertSame(['a', 'aa', 'aaa'], $c->foo()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCanAddMethodsToProxy($collection)\n    {\n        $collection::macro('adults', function ($callback) {\n            return $this->filter(function ($item) use ($callback) {\n                return $callback($item) >= 18;\n            });\n        });\n\n        $collection::proxy('adults');\n\n        $c = new $collection([['age' => 3], ['age' => 12], ['age' => 18], ['age' => 56]]);\n\n        $this->assertSame([['age' => 18], ['age' => 56]], $c->adults->age->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMakeMethod($collection)\n    {\n        $data = $collection::make('foo');\n        $this->assertEquals(['foo'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMakeMethodFromNull($collection)\n    {\n        $data = $collection::make(null);\n        $this->assertEquals([], $data->all());\n\n        $data = $collection::make();\n        $this->assertEquals([], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMakeMethodFromCollection($collection)\n    {\n        $firstCollection = $collection::make(['foo' => 'bar']);\n        $secondCollection = $collection::make($firstCollection);\n        $this->assertEquals(['foo' => 'bar'], $secondCollection->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMakeMethodFromArray($collection)\n    {\n        $data = $collection::make(['foo' => 'bar']);\n        $this->assertEquals(['foo' => 'bar'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithScalar($collection)\n    {\n        $data = $collection::wrap('foo');\n        $this->assertEquals(['foo'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithArray($collection)\n    {\n        $data = $collection::wrap(['foo']);\n        $this->assertEquals(['foo'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithArrayable($collection)\n    {\n        $data = $collection::wrap($o = new TestArrayableObject);\n        $this->assertEquals([$o], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithJsonable($collection)\n    {\n        $data = $collection::wrap($o = new TestJsonableObject);\n        $this->assertEquals([$o], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithJsonSerialize($collection)\n    {\n        $data = $collection::wrap($o = new TestJsonSerializeObject);\n        $this->assertEquals([$o], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithCollectionClass($collection)\n    {\n        $data = $collection::wrap($collection::make(['foo']));\n        $this->assertEquals(['foo'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWrapWithCollectionSubclass($collection)\n    {\n        $data = TestCollectionSubclass::wrap($collection::make(['foo']));\n        $this->assertEquals(['foo'], $data->all());\n        $this->assertInstanceOf(TestCollectionSubclass::class, $data);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnwrapCollection($collection)\n    {\n        $data = new $collection(['foo']);\n        $this->assertEquals(['foo'], $collection::unwrap($data));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnwrapCollectionWithArray($collection)\n    {\n        $this->assertEquals(['foo'], $collection::unwrap(['foo']));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnwrapCollectionWithScalar($collection)\n    {\n        $this->assertSame('foo', $collection::unwrap('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEmptyMethod($collection)\n    {\n        $collection = $collection::empty();\n\n        $this->assertCount(0, $collection->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTimesMethod($collection)\n    {\n        $two = $collection::times(2, function ($number) {\n            return 'slug-'.$number;\n        });\n\n        $zero = $collection::times(0, function ($number) {\n            return 'slug-'.$number;\n        });\n\n        $negative = $collection::times(-4, function ($number) {\n            return 'slug-'.$number;\n        });\n\n        $range = $collection::times(5);\n\n        $this->assertEquals(['slug-1', 'slug-2'], $two->all());\n        $this->assertTrue($zero->isEmpty());\n        $this->assertTrue($negative->isEmpty());\n        $this->assertEquals(range(1, 5), $range->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRangeMethod($collection)\n    {\n        $this->assertSame(\n            [1, 2, 3, 4, 5],\n            $collection::range(1, 5)->all()\n        );\n\n        $this->assertSame(\n            [-2, -1, 0, 1, 2],\n            $collection::range(-2, 2)->all()\n        );\n\n        $this->assertSame(\n            [-4, -3, -2],\n            $collection::range(-4, -2)->all()\n        );\n\n        $this->assertSame(\n            [5, 4, 3, 2, 1],\n            $collection::range(5, 1)->all()\n        );\n\n        $this->assertSame(\n            [2, 1, 0, -1, -2],\n            $collection::range(2, -2)->all()\n        );\n\n        $this->assertSame(\n            [-2, -3, -4],\n            $collection::range(-2, -4)->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFromJson($collection)\n    {\n        $json = json_encode($array = ['foo' => 'bar', 'baz' => 'quz']);\n\n        $instance = $collection::fromJson($json);\n\n        $this->assertSame($array, $instance->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFromJsonWithDepth($collection)\n    {\n        $json = json_encode(['foo' => ['baz' => ['quz']], 'bar' => 'baz']);\n\n        $instance = $collection::fromJson($json, 1);\n\n        $this->assertEmpty($instance->toArray());\n        $this->assertSame(JSON_ERROR_DEPTH, json_last_error());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFromJsonWithFlags($collection)\n    {\n        $instance = $collection::fromJson('{\"int\":99999999999999999999999}', 512, JSON_BIGINT_AS_STRING);\n\n        $this->assertSame(['int' => '99999999999999999999999'], $instance->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMakeFromObject($collection)\n    {\n        $object = new stdClass;\n        $object->foo = 'bar';\n        $data = $collection::make($object);\n        $this->assertEquals(['foo' => 'bar'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethod($collection)\n    {\n        $data = new $collection('foo');\n        $this->assertEquals(['foo'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethodFromNull($collection)\n    {\n        $data = new $collection(null);\n        $this->assertEquals([], $data->all());\n\n        $data = new $collection;\n        $this->assertEquals([], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethodFromCollection($collection)\n    {\n        $firstCollection = new $collection(['foo' => 'bar']);\n        $secondCollection = new $collection($firstCollection);\n        $this->assertEquals(['foo' => 'bar'], $secondCollection->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethodFromArray($collection)\n    {\n        $data = new $collection(['foo' => 'bar']);\n        $this->assertEquals(['foo' => 'bar'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethodFromObject($collection)\n    {\n        $object = new stdClass;\n        $object->foo = 'bar';\n        $data = new $collection($object);\n        $this->assertEquals(['foo' => 'bar'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConstructMethodFromWeakMap($collection)\n    {\n        $map = new WeakMap();\n        $object = new stdClass;\n        $object->foo = 'bar';\n        $map[$object] = 3;\n        $data = new $collection($map);\n        $this->assertEquals([3], $data->all());\n    }\n\n    public function testSplice()\n    {\n        $data = new Collection(['foo', 'baz']);\n        $data->splice(1);\n        $this->assertEquals(['foo'], $data->all());\n\n        $data = new Collection(['foo', 'baz']);\n        $data->splice(1, 0, 'bar');\n        $this->assertEquals(['foo', 'bar', 'baz'], $data->all());\n\n        $data = new Collection(['foo', 'baz']);\n        $data->splice(1, 1);\n        $this->assertEquals(['foo'], $data->all());\n\n        $data = new Collection(['foo', 'baz']);\n        $cut = $data->splice(1, 1, 'bar');\n        $this->assertEquals(['foo', 'bar'], $data->all());\n        $this->assertEquals(['baz'], $cut->all());\n\n        $data = new Collection(['foo', 'baz']);\n        $data->splice(1, 0, ['bar']);\n        $this->assertEquals(['foo', 'bar', 'baz'], $data->all());\n\n        $data = new Collection(['foo', 'baz']);\n        $data->splice(1, 0, new Collection(['bar']));\n        $this->assertEquals(['foo', 'bar', 'baz'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGetPluckValueWithAccessors($collection)\n    {\n        $model = new TestAccessorEloquentTestStub(['some' => 'foo']);\n        $modelTwo = new TestAccessorEloquentTestStub(['some' => 'bar']);\n        $data = new $collection([$model, $modelTwo]);\n\n        $this->assertEquals(['foo', 'bar'], $data->pluck('some')->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMap($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n        $mapped = $data->map(function ($item, $key) {\n            return $item * 2;\n        });\n        $this->assertEquals([2, 4, 6], $mapped->all());\n        $this->assertEquals([1, 2, 3], $data->all());\n\n        $data = new $collection(['first' => 'taylor', 'last' => 'otwell']);\n        $data = $data->map(function ($item, $key) {\n            return $key.'-'.strrev($item);\n        });\n        $this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapSpread($collection)\n    {\n        $c = new $collection([[1, 'a'], [2, 'b']]);\n\n        $result = $c->mapSpread(function ($number, $character) {\n            return \"{$number}-{$character}\";\n        });\n        $this->assertEquals(['1-a', '2-b'], $result->all());\n\n        $result = $c->mapSpread(function ($number, $character, $key) {\n            return \"{$number}-{$character}-{$key}\";\n        });\n        $this->assertEquals(['1-a-0', '2-b-1'], $result->all());\n\n        $c = new $collection([new Collection([1, 'a']), new Collection([2, 'b'])]);\n        $result = $c->mapSpread(function ($number, $character, $key) {\n            return \"{$number}-{$character}-{$key}\";\n        });\n        $this->assertEquals(['1-a-0', '2-b-1'], $result->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testFlatMap($collection)\n    {\n        $data = new $collection([\n            ['name' => 'taylor', 'hobbies' => ['programming', 'basketball']],\n            ['name' => 'adam', 'hobbies' => ['music', 'powerlifting']],\n        ]);\n        $data = $data->flatMap(function ($person) {\n            return $person['hobbies'];\n        });\n        $this->assertEquals(['programming', 'basketball', 'music', 'powerlifting'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapToDictionary($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => 'A'],\n            ['id' => 2, 'name' => 'B'],\n            ['id' => 3, 'name' => 'C'],\n            ['id' => 4, 'name' => 'B'],\n        ]);\n\n        $groups = $data->mapToDictionary(function ($item, $key) {\n            return [$item['name'] => $item['id']];\n        });\n\n        $this->assertInstanceOf($collection, $groups);\n        $this->assertEquals(['A' => [1], 'B' => [2, 4], 'C' => [3]], $groups->toArray());\n        $this->assertIsArray($groups->get('A'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapToDictionaryWithNumericKeys($collection)\n    {\n        $data = new $collection([1, 2, 3, 2, 1]);\n\n        $groups = $data->mapToDictionary(function ($item, $key) {\n            return [$item => $key];\n        });\n\n        $this->assertEquals([1 => [0, 4], 2 => [1, 3], 3 => [2]], $groups->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapToGroups($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => 'A'],\n            ['id' => 2, 'name' => 'B'],\n            ['id' => 3, 'name' => 'C'],\n            ['id' => 4, 'name' => 'B'],\n        ]);\n\n        $groups = $data->mapToGroups(function ($item, $key) {\n            return [$item['name'] => $item['id']];\n        });\n\n        $this->assertInstanceOf($collection, $groups);\n        $this->assertEquals(['A' => [1], 'B' => [2, 4], 'C' => [3]], $groups->toArray());\n        $this->assertInstanceOf($collection, $groups->get('A'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapToGroupsWithNumericKeys($collection)\n    {\n        $data = new $collection([1, 2, 3, 2, 1]);\n\n        $groups = $data->mapToGroups(function ($item, $key) {\n            return [$item => $key];\n        });\n\n        $this->assertEquals([1 => [0, 4], 2 => [1, 3], 3 => [2]], $groups->toArray());\n        $this->assertEquals([1, 2, 3, 2, 1], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapWithKeys($collection)\n    {\n        $data = new $collection([\n            ['name' => 'Blastoise', 'type' => 'Water', 'idx' => 9],\n            ['name' => 'Charmander', 'type' => 'Fire', 'idx' => 4],\n            ['name' => 'Dragonair', 'type' => 'Dragon', 'idx' => 148],\n        ]);\n        $data = $data->mapWithKeys(function ($pokemon) {\n            return [$pokemon['name'] => $pokemon['type']];\n        });\n        $this->assertEquals(\n            ['Blastoise' => 'Water', 'Charmander' => 'Fire', 'Dragonair' => 'Dragon'],\n            $data->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapWithKeysIntegerKeys($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => 'A'],\n            ['id' => 3, 'name' => 'B'],\n            ['id' => 2, 'name' => 'C'],\n        ]);\n        $data = $data->mapWithKeys(function ($item) {\n            return [$item['id'] => $item];\n        });\n        $this->assertSame(\n            [1, 3, 2],\n            $data->keys()->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapWithKeysMultipleRows($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => 'A'],\n            ['id' => 2, 'name' => 'B'],\n            ['id' => 3, 'name' => 'C'],\n        ]);\n        $data = $data->mapWithKeys(function ($item) {\n            return [$item['id'] => $item['name'], $item['name'] => $item['id']];\n        });\n        $this->assertSame(\n            [\n                1 => 'A',\n                'A' => 1,\n                2 => 'B',\n                'B' => 2,\n                3 => 'C',\n                'C' => 3,\n            ],\n            $data->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapWithKeysCallbackKey($collection)\n    {\n        $data = new $collection([\n            3 => ['id' => 1, 'name' => 'A'],\n            5 => ['id' => 3, 'name' => 'B'],\n            4 => ['id' => 2, 'name' => 'C'],\n        ]);\n        $data = $data->mapWithKeys(function ($item, $key) {\n            return [$key => $item['id']];\n        });\n        $this->assertSame(\n            [3, 5, 4],\n            $data->keys()->all()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapInto($collection)\n    {\n        $data = new $collection([\n            'first', 'second',\n        ]);\n\n        $data = $data->mapInto(TestCollectionMapIntoObject::class);\n\n        $this->assertSame('first', $data->get(0)->value);\n        $this->assertSame('second', $data->get(1)->value);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapIntoWithIntBackedEnums($collection)\n    {\n        $data = new $collection([\n            1, 2,\n        ]);\n\n        $data = $data->mapInto(TestBackedEnum::class);\n\n        $this->assertSame(TestBackedEnum::A, $data->get(0));\n        $this->assertSame(TestBackedEnum::B, $data->get(1));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapIntoWithStringBackedEnums($collection)\n    {\n        $data = new $collection([\n            'A', 'B',\n        ]);\n\n        $data = $data->mapInto(TestStringBackedEnum::class);\n\n        $this->assertSame(TestStringBackedEnum::A, $data->get(0));\n        $this->assertSame(TestStringBackedEnum::B, $data->get(1));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testNth($collection)\n    {\n        $data = new $collection([\n            6 => 'a',\n            4 => 'b',\n            7 => 'c',\n            1 => 'd',\n            5 => 'e',\n            3 => 'f',\n        ]);\n\n        $this->assertEquals(['a', 'e'], $data->nth(4)->all());\n        $this->assertEquals(['b', 'f'], $data->nth(4, 1)->all());\n        $this->assertEquals(['c'], $data->nth(4, 2)->all());\n        $this->assertEquals(['d'], $data->nth(4, 3)->all());\n        $this->assertEquals(['c', 'e'], $data->nth(2, 2)->all());\n        $this->assertEquals(['c', 'd', 'e', 'f'], $data->nth(1, 2)->all());\n        $this->assertEquals(['c', 'd', 'e', 'f'], $data->nth(1, 2)->all());\n        $this->assertEquals(['e', 'f'], $data->nth(1, -2)->all());\n        $this->assertEquals(['c', 'e'], $data->nth(2, -4)->all());\n        $this->assertEquals(['e'], $data->nth(4, -2)->all());\n        $this->assertEquals(['e'], $data->nth(2, -2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testNthThrowsExceptionForInvalidStep($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Step value must be at least 1.');\n\n        (new $collection([1, 2, 3]))->nth(0)->all();\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testNthThrowsExceptionForNegativeStep($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Step value must be at least 1.');\n\n        (new $collection([1, 2, 3]))->nth(-1)->all();\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitThrowsExceptionForInvalidNumberOfGroups($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Number of groups must be at least 1.');\n\n        (new $collection([1, 2, 3]))->split(0);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitThrowsExceptionForNegativeNumberOfGroups($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Number of groups must be at least 1.');\n\n        (new $collection([1, 2, 3]))->split(-1);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitInThrowsExceptionForInvalidNumberOfGroups($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Number of groups must be at least 1.');\n\n        (new $collection([1, 2, 3]))->splitIn(0);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitInThrowsExceptionForNegativeNumberOfGroups($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Number of groups must be at least 1.');\n\n        (new $collection([1, 2, 3]))->splitIn(-1);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMapWithKeysOverwritingKeys($collection)\n    {\n        $data = new $collection([\n            ['id' => 1, 'name' => 'A'],\n            ['id' => 2, 'name' => 'B'],\n            ['id' => 1, 'name' => 'C'],\n        ]);\n        $data = $data->mapWithKeys(function ($item) {\n            return [$item['id'] => $item['name']];\n        });\n        $this->assertSame(\n            [\n                1 => 'C',\n                2 => 'B',\n            ],\n            $data->all()\n        );\n    }\n\n    public function testTransform()\n    {\n        $data = new Collection(['first' => 'taylor', 'last' => 'otwell']);\n        $data->transform(function ($item, $key) {\n            return $key.'-'.strrev($item);\n        });\n        $this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByAttribute($collection)\n    {\n        $data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);\n\n        $result = $data->groupBy('rating');\n        $this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());\n\n        $result = $data->groupBy('url');\n        $this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByAttributeWithStringableKey($collection)\n    {\n        $data = new $collection($payload = [\n            ['name' => new Stringable('Laravel'), 'url' => '1'],\n            ['name' => new HtmlString('Laravel'), 'url' => '1'],\n            ['name' => new class()\n            {\n                public function __toString()\n                {\n                    return 'Framework';\n                }\n            }, 'url' => '2', ],\n        ]);\n\n        $result = $data->groupBy('name');\n        $this->assertEquals(['Laravel' => [$payload[0], $payload[1]], 'Framework' => [$payload[2]]], $result->toArray());\n\n        $result = $data->groupBy('url');\n        $this->assertEquals(['1' => [$payload[0], $payload[1]], '2' => [$payload[2]]], $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByAttributeWithEnumKey($collection)\n    {\n        $data = new $collection($payload = [\n            ['name' => TestEnum::A, 'url' => '1'],\n            ['name' => TestBackedEnum::A, 'url' => '1'],\n            ['name' => TestStringBackedEnum::A, 'url' => '2'],\n        ]);\n\n        $result = $data->groupBy('name');\n        $this->assertEquals(['A' => [$payload[0], $payload[2]], '1' => [$payload[1]]], $result->toArray());\n\n        $result = $data->groupBy('url');\n        $this->assertEquals(['1' => [$payload[0], $payload[1]], '2' => [$payload[2]]], $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByCallable($collection)\n    {\n        $data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);\n\n        $result = $data->groupBy([$this, 'sortByRating']);\n        $this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());\n\n        $result = $data->groupBy([$this, 'sortByUrl']);\n        $this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());\n    }\n\n    public function sortByRating(array $value)\n    {\n        return $value['rating'];\n    }\n\n    public function sortByUrl(array $value)\n    {\n        return $value['url'];\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByAttributeWithBackedEnumKey($collection)\n    {\n        $data = new $collection([\n            ['rating' => TestBackedEnum::A, 'url' => '1'],\n            ['rating' => TestBackedEnum::B, 'url' => '1'],\n        ]);\n\n        $result = $data->groupBy('rating');\n        $this->assertEquals([TestBackedEnum::A->value => [['rating' => TestBackedEnum::A, 'url' => '1']], TestBackedEnum::B->value => [['rating' => TestBackedEnum::B, 'url' => '1']]], $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByAttributePreservingKeys($collection)\n    {\n        $data = new $collection([10 => ['rating' => 1, 'url' => '1'],  20 => ['rating' => 1, 'url' => '1'],  30 => ['rating' => 2, 'url' => '2']]);\n\n        $result = $data->groupBy('rating', true);\n\n        $expected_result = [\n            1 => [10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1']],\n            2 => [30 => ['rating' => 2, 'url' => '2']],\n        ];\n\n        $this->assertEquals($expected_result, $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByClosureWhereItemsHaveSingleGroup($collection)\n    {\n        $data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);\n\n        $result = $data->groupBy(function ($item) {\n            return $item['rating'];\n        });\n\n        $this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByClosureWhereItemsHaveSingleGroupPreservingKeys($collection)\n    {\n        $data = new $collection([10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1'], 30 => ['rating' => 2, 'url' => '2']]);\n\n        $result = $data->groupBy(function ($item) {\n            return $item['rating'];\n        }, true);\n\n        $expected_result = [\n            1 => [10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1']],\n            2 => [30 => ['rating' => 2, 'url' => '2']],\n        ];\n\n        $this->assertEquals($expected_result, $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByClosureWhereItemsHaveMultipleGroups($collection)\n    {\n        $data = new $collection([\n            ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n            ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n            ['user' => 3, 'roles' => ['Role_1']],\n        ]);\n\n        $result = $data->groupBy(function ($item) {\n            return $item['roles'];\n        });\n\n        $expected_result = [\n            'Role_1' => [\n                ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n                ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n                ['user' => 3, 'roles' => ['Role_1']],\n            ],\n            'Role_2' => [\n                ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n            ],\n            'Role_3' => [\n                ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n            ],\n        ];\n\n        $this->assertEquals($expected_result, $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByClosureWhereItemsHaveMultipleGroupsPreservingKeys($collection)\n    {\n        $data = new $collection([\n            10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n            20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n            30 => ['user' => 3, 'roles' => ['Role_1']],\n        ]);\n\n        $result = $data->groupBy(function ($item) {\n            return $item['roles'];\n        }, true);\n\n        $expected_result = [\n            'Role_1' => [\n                10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n                20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n                30 => ['user' => 3, 'roles' => ['Role_1']],\n            ],\n            'Role_2' => [\n                20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],\n            ],\n            'Role_3' => [\n                10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],\n            ],\n        ];\n\n        $this->assertEquals($expected_result, $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGroupByMultiLevelAndClosurePreservingKeys($collection)\n    {\n        $data = new $collection([\n            10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],\n            20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],\n            30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],\n            40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],\n        ]);\n\n        $result = $data->groupBy([\n            'skilllevel',\n            function ($item) {\n                return $item['roles'];\n            },\n        ], true);\n\n        $expected_result = [\n            1 => [\n                'Role_1' => [\n                    10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],\n                    20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],\n                ],\n                'Role_3' => [\n                    10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],\n                ],\n                'Role_2' => [\n                    20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],\n                ],\n            ],\n            2 => [\n                'Role_1' => [\n                    30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],\n                ],\n                'Role_2' => [\n                    40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],\n                ],\n            ],\n        ];\n\n        $this->assertEquals($expected_result, $result->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testKeyByAttribute($collection)\n    {\n        $data = new $collection([['rating' => 1, 'name' => '1'], ['rating' => 2, 'name' => '2'], ['rating' => 3, 'name' => '3']]);\n\n        $result = $data->keyBy('rating');\n        $this->assertEquals([1 => ['rating' => 1, 'name' => '1'], 2 => ['rating' => 2, 'name' => '2'], 3 => ['rating' => 3, 'name' => '3']], $result->all());\n\n        $result = $data->keyBy(function ($item) {\n            return $item['rating'] * 2;\n        });\n        $this->assertEquals([2 => ['rating' => 1, 'name' => '1'], 4 => ['rating' => 2, 'name' => '2'], 6 => ['rating' => 3, 'name' => '3']], $result->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testKeyByClosure($collection)\n    {\n        $data = new $collection([\n            ['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],\n            ['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],\n        ]);\n        $result = $data->keyBy(function ($item, $key) {\n            return strtolower($key.'-'.$item['firstname'].$item['lastname']);\n        });\n        $this->assertEquals([\n            '0-taylorotwell' => ['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],\n            '1-lucasmichot' => ['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],\n        ], $result->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testKeyByObject($collection)\n    {\n        $data = new $collection([\n            ['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],\n            ['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],\n        ]);\n        $result = $data->keyBy(function ($item, $key) use ($collection) {\n            return new $collection([$key, $item['firstname'], $item['lastname']]);\n        });\n        $this->assertEquals([\n            '[0,\"Taylor\",\"Otwell\"]' => ['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],\n            '[1,\"Lucas\",\"Michot\"]' => ['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],\n        ], $result->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testContains($collection)\n    {\n        $c = new $collection([1, 3, 5]);\n\n        $this->assertTrue($c->contains(1));\n        $this->assertTrue($c->contains('1'));\n        $this->assertFalse($c->contains(2));\n        $this->assertFalse($c->contains('2'));\n\n        $c = new $collection(['1']);\n        $this->assertTrue($c->contains('1'));\n        $this->assertTrue($c->contains(1));\n\n        $c = new $collection([null]);\n        $this->assertTrue($c->contains(false));\n        $this->assertTrue($c->contains(null));\n        $this->assertTrue($c->contains([]));\n        $this->assertTrue($c->contains(0));\n        $this->assertTrue($c->contains(''));\n\n        $c = new $collection([0]);\n        $this->assertTrue($c->contains(0));\n        $this->assertTrue($c->contains('0'));\n        $this->assertTrue($c->contains(false));\n        $this->assertTrue($c->contains(null));\n\n        $this->assertTrue($c->contains(function ($value) {\n            return $value < 5;\n        }));\n        $this->assertFalse($c->contains(function ($value) {\n            return $value > 5;\n        }));\n\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);\n\n        $this->assertTrue($c->contains('v', 1));\n        $this->assertFalse($c->contains('v', 2));\n\n        $c = new $collection(['date', 'class', (object) ['foo' => 50]]);\n\n        $this->assertTrue($c->contains('date'));\n        $this->assertTrue($c->contains('class'));\n        $this->assertFalse($c->contains('foo'));\n\n        $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);\n\n        $this->assertTrue($c->contains->a);\n        $this->assertFalse($c->contains->b);\n\n        $c = new $collection([\n            null, 1, 2,\n        ]);\n\n        $this->assertTrue($c->contains(function ($value) {\n            return is_null($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDoesntContain($collection)\n    {\n        $c = new $collection([1, 3, 5]);\n\n        $this->assertFalse($c->doesntContain(1));\n        $this->assertFalse($c->doesntContain('1'));\n        $this->assertTrue($c->doesntContain(2));\n        $this->assertTrue($c->doesntContain('2'));\n\n        $c = new $collection(['1']);\n        $this->assertFalse($c->doesntContain('1'));\n        $this->assertFalse($c->doesntContain(1));\n\n        $c = new $collection([null]);\n        $this->assertFalse($c->doesntContain(false));\n        $this->assertFalse($c->doesntContain(null));\n        $this->assertFalse($c->doesntContain([]));\n        $this->assertFalse($c->doesntContain(0));\n        $this->assertFalse($c->doesntContain(''));\n\n        $c = new $collection([0]);\n        $this->assertFalse($c->doesntContain(0));\n        $this->assertFalse($c->doesntContain('0'));\n        $this->assertFalse($c->doesntContain(false));\n        $this->assertFalse($c->doesntContain(null));\n\n        $this->assertFalse($c->doesntContain(function ($value) {\n            return $value < 5;\n        }));\n        $this->assertTrue($c->doesntContain(function ($value) {\n            return $value > 5;\n        }));\n\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);\n\n        $this->assertFalse($c->doesntContain('v', 1));\n        $this->assertTrue($c->doesntContain('v', 2));\n\n        $c = new $collection(['date', 'class', (object) ['foo' => 50]]);\n\n        $this->assertFalse($c->doesntContain('date'));\n        $this->assertFalse($c->doesntContain('class'));\n        $this->assertTrue($c->doesntContain('foo'));\n\n        $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);\n\n        $this->assertFalse($c->doesntContain->a);\n        $this->assertTrue($c->doesntContain->b);\n\n        $c = new $collection([\n            null, 1, 2,\n        ]);\n\n        $this->assertFalse($c->doesntContain(function ($value) {\n            return is_null($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDoesntContainStrict($collection)\n    {\n        $c = new $collection([1, 3, 5, '02']);\n\n        $this->assertFalse($c->doesntContainStrict(1));\n        $this->assertTrue($c->doesntContainStrict('1'));\n        $this->assertTrue($c->doesntContainStrict(2));\n        $this->assertFalse($c->doesntContainStrict('02'));\n        $this->assertTrue($c->doesntContainStrict('2'));\n        $this->assertTrue($c->doesntContainStrict(true));\n        $this->assertFalse($c->doesntContainStrict(function ($value) {\n            return $value < 5;\n        }));\n        $this->assertTrue($c->doesntContainStrict(function ($value) {\n            return $value > 5;\n        }));\n\n        $c = new $collection([0]);\n        $this->assertFalse($c->doesntContainStrict(0));\n        $this->assertTrue($c->doesntContainStrict('0'));\n\n        $this->assertTrue($c->doesntContainStrict(false));\n        $this->assertTrue($c->doesntContainStrict(null));\n\n        $c = new $collection([1, null]);\n        $this->assertFalse($c->doesntContainStrict(null));\n        $this->assertTrue($c->doesntContainStrict(0));\n        $this->assertTrue($c->doesntContainStrict(false));\n\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => '04'], ['v' => 5]]);\n\n        $this->assertFalse($c->doesntContainStrict('v', 1));\n        $this->assertTrue($c->doesntContainStrict('v', 2));\n        $this->assertTrue($c->doesntContainStrict('v', '1'));\n        $this->assertTrue($c->doesntContainStrict('v', 4));\n        $this->assertFalse($c->doesntContainStrict('v', '04'));\n        $this->assertTrue($c->doesntContainStrict('v', '4'));\n\n        $c = new $collection(['date', 'class', (object) ['foo' => 50], '']);\n\n        $this->assertFalse($c->doesntContainStrict('date'));\n        $this->assertFalse($c->doesntContainStrict('class'));\n        $this->assertTrue($c->doesntContainStrict('foo'));\n        $this->assertTrue($c->doesntContainStrict(null));\n        $this->assertFalse($c->doesntContainStrict(''));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSome($collection)\n    {\n        $c = new $collection([1, 3, 5]);\n\n        $this->assertTrue($c->some(1));\n        $this->assertFalse($c->some(2));\n        $this->assertTrue($c->some(function ($value) {\n            return $value < 5;\n        }));\n        $this->assertFalse($c->some(function ($value) {\n            return $value > 5;\n        }));\n\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);\n\n        $this->assertTrue($c->some('v', 1));\n        $this->assertFalse($c->some('v', 2));\n\n        $c = new $collection(['date', 'class', (object) ['foo' => 50]]);\n\n        $this->assertTrue($c->some('date'));\n        $this->assertTrue($c->some('class'));\n        $this->assertFalse($c->some('foo'));\n\n        $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);\n\n        $this->assertTrue($c->some->a);\n        $this->assertFalse($c->some->b);\n\n        $c = new $collection([\n            null, 1, 2,\n        ]);\n\n        $this->assertTrue($c->some(function ($value) {\n            return is_null($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testContainsStrict($collection)\n    {\n        $c = new $collection([1, 3, 5, '02']);\n\n        $this->assertTrue($c->containsStrict(1));\n        $this->assertFalse($c->containsStrict('1'));\n        $this->assertFalse($c->containsStrict(2));\n        $this->assertTrue($c->containsStrict('02'));\n        $this->assertFalse($c->containsStrict(true));\n        $this->assertTrue($c->containsStrict(function ($value) {\n            return $value < 5;\n        }));\n        $this->assertFalse($c->containsStrict(function ($value) {\n            return $value > 5;\n        }));\n\n        $c = new $collection([0]);\n        $this->assertTrue($c->containsStrict(0));\n        $this->assertFalse($c->containsStrict('0'));\n\n        $this->assertFalse($c->containsStrict(false));\n        $this->assertFalse($c->containsStrict(null));\n\n        $c = new $collection([1, null]);\n        $this->assertTrue($c->containsStrict(null));\n        $this->assertFalse($c->containsStrict(0));\n        $this->assertFalse($c->containsStrict(false));\n\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => '04'], ['v' => 5]]);\n\n        $this->assertTrue($c->containsStrict('v', 1));\n        $this->assertFalse($c->containsStrict('v', 2));\n        $this->assertFalse($c->containsStrict('v', '1'));\n        $this->assertFalse($c->containsStrict('v', 4));\n        $this->assertTrue($c->containsStrict('v', '04'));\n\n        $c = new $collection(['date', 'class', (object) ['foo' => 50], '']);\n\n        $this->assertTrue($c->containsStrict('date'));\n        $this->assertTrue($c->containsStrict('class'));\n        $this->assertFalse($c->containsStrict('foo'));\n        $this->assertFalse($c->containsStrict(null));\n        $this->assertTrue($c->containsStrict(''));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testContainsWithOperator($collection)\n    {\n        $c = new $collection([['v' => 1], ['v' => 3], ['v' => '4'], ['v' => 5]]);\n\n        $this->assertTrue($c->contains('v', '=', 4));\n        $this->assertTrue($c->contains('v', '==', 4));\n        $this->assertFalse($c->contains('v', '===', 4));\n        $this->assertTrue($c->contains('v', '>', 4));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGettingSumFromCollection($collection)\n    {\n        $c = new $collection([(object) ['foo' => 50], (object) ['foo' => 50]]);\n        $this->assertEquals(100, $c->sum('foo'));\n\n        $c = new $collection([(object) ['foo' => 50], (object) ['foo' => 50]]);\n        $this->assertEquals(100, $c->sum(function ($i) {\n            return $i->foo;\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCanSumValuesWithoutACallback($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $this->assertEquals(15, $c->sum());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGettingSumFromEmptyCollection($collection)\n    {\n        $c = new $collection;\n        $this->assertEquals(0, $c->sum('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testValueRetrieverAcceptsDotNotation($collection)\n    {\n        $c = new $collection([\n            (object) ['id' => 1, 'foo' => ['bar' => 'B']], (object) ['id' => 2, 'foo' => ['bar' => 'A']],\n        ]);\n\n        $c = $c->sortBy('foo.bar');\n        $this->assertEquals([2, 1], $c->pluck('id')->all());\n    }\n\n    public function testPullRetrievesItemFromCollection()\n    {\n        $c = new Collection(['foo', 'bar']);\n\n        $this->assertSame('foo', $c->pull(0));\n        $this->assertSame('bar', $c->pull(1));\n\n        $c = new Collection(['foo', 'bar']);\n\n        $this->assertNull($c->pull(-1));\n        $this->assertNull($c->pull(2));\n    }\n\n    public function testPullRemovesItemFromCollection()\n    {\n        $c = new Collection(['foo', 'bar']);\n        $c->pull(0);\n        $this->assertEquals([1 => 'bar'], $c->all());\n        $c->pull(1);\n        $this->assertEquals([], $c->all());\n    }\n\n    public function testPullRemovesItemFromNestedCollection()\n    {\n        $nestedCollection = new Collection([\n            new Collection([\n                'value',\n                new Collection([\n                    'bar' => 'baz',\n                    'test' => 'value',\n                ]),\n            ]),\n            'bar',\n        ]);\n\n        $nestedCollection->pull('0.1.test');\n\n        $actualArray = $nestedCollection->toArray();\n        $expectedArray = [\n            [\n                'value',\n                ['bar' => 'baz'],\n            ],\n            'bar',\n        ];\n\n        $this->assertEquals($expectedArray, $actualArray);\n    }\n\n    public function testPullReturnsDefault()\n    {\n        $c = new Collection([]);\n        $value = $c->pull(0, 'foo');\n        $this->assertSame('foo', $value);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRejectRemovesElementsPassingTruthTest($collection)\n    {\n        $c = new $collection(['foo', 'bar']);\n        $this->assertEquals(['foo'], $c->reject('bar')->values()->all());\n\n        $c = new $collection(['foo', 'bar']);\n        $this->assertEquals(['foo'], $c->reject(function ($v) {\n            return $v === 'bar';\n        })->values()->all());\n\n        $c = new $collection(['foo', null]);\n        $this->assertEquals(['foo'], $c->reject(null)->values()->all());\n\n        $c = new $collection(['foo', 'bar']);\n        $this->assertEquals(['foo', 'bar'], $c->reject('baz')->values()->all());\n\n        $c = new $collection(['foo', 'bar']);\n        $this->assertEquals(['foo', 'bar'], $c->reject(function ($v) {\n            return $v === 'baz';\n        })->values()->all());\n\n        $c = new $collection(['id' => 1, 'primary' => 'foo', 'secondary' => 'bar']);\n        $this->assertEquals(['primary' => 'foo', 'secondary' => 'bar'], $c->reject(function ($item, $key) {\n            return $key === 'id';\n        })->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRejectWithoutAnArgumentRemovesTruthyValues($collection)\n    {\n        $data1 = new $collection([\n            false,\n            true,\n            new $collection(),\n            0,\n        ]);\n        $this->assertSame([0 => false, 3 => 0], $data1->reject()->all());\n\n        $data2 = new $collection([\n            'a' => true,\n            'b' => true,\n            'c' => true,\n        ]);\n        $this->assertTrue(\n            $data2->reject()->isEmpty()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSearchReturnsIndexOfFirstFoundItem($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 2, 5, 'foo' => 'bar']);\n\n        $this->assertEquals(1, $c->search(2));\n        $this->assertEquals(1, $c->search('2'));\n        $this->assertSame('foo', $c->search('bar'));\n        $this->assertEquals(4, $c->search(function ($value) {\n            return $value > 4;\n        }));\n        $this->assertSame('foo', $c->search(function ($value) {\n            return ! is_numeric($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSearchInStrictMode($collection)\n    {\n        $c = new $collection([false, 0, 1, [], '']);\n        $this->assertFalse($c->search('false', true));\n        $this->assertFalse($c->search('1', true));\n        $this->assertEquals(0, $c->search(false, true));\n        $this->assertEquals(1, $c->search(0, true));\n        $this->assertEquals(2, $c->search(1, true));\n        $this->assertEquals(3, $c->search([], true));\n        $this->assertEquals(4, $c->search('', true));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSearchReturnsFalseWhenItemIsNotFound($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);\n\n        $this->assertFalse($c->search(6));\n        $this->assertFalse($c->search('foo'));\n        $this->assertFalse($c->search(function ($value) {\n            return $value < 1 && is_numeric($value);\n        }));\n        $this->assertFalse($c->search(function ($value) {\n            return $value === 'nope';\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testBeforeReturnsItemBeforeTheGivenItem($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 2, 5, 'name' => 'taylor', 'framework' => 'laravel']);\n\n        $this->assertEquals(1, $c->before(2));\n        $this->assertEquals(1, $c->before('2'));\n        $this->assertEquals(5, $c->before('taylor'));\n        $this->assertSame('taylor', $c->before('laravel'));\n        $this->assertEquals(4, $c->before(function ($value) {\n            return $value > 4;\n        }));\n        $this->assertEquals(5, $c->before(function ($value) {\n            return ! is_numeric($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testBeforeInStrictMode($collection)\n    {\n        $c = new $collection([false, 0, 1, [], '']);\n        $this->assertNull($c->before('false', true));\n        $this->assertNull($c->before('1', true));\n        $this->assertNull($c->before(false, true));\n        $this->assertEquals(false, $c->before(0, true));\n        $this->assertEquals(0, $c->before(1, true));\n        $this->assertEquals(1, $c->before([], true));\n        $this->assertEquals([], $c->before('', true));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testBeforeReturnsNullWhenItemIsNotFound($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);\n\n        $this->assertNull($c->before(6));\n        $this->assertNull($c->before('foo'));\n        $this->assertNull($c->before(function ($value) {\n            return $value < 1 && is_numeric($value);\n        }));\n        $this->assertNull($c->before(function ($value) {\n            return $value === 'nope';\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testBeforeReturnsNullWhenItemOnTheFirstitem($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);\n\n        $this->assertNull($c->before(1));\n        $this->assertNull($c->before(function ($value) {\n            return $value < 2 && is_numeric($value);\n        }));\n\n        $c = new $collection(['foo' => 'bar', 1, 2, 3, 4, 5]);\n        $this->assertNull($c->before('bar'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testAfterReturnsItemAfterTheGivenItem($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 2, 5, 'name' => 'taylor', 'framework' => 'laravel']);\n\n        $this->assertEquals(2, $c->after(1));\n        $this->assertEquals(3, $c->after(2));\n        $this->assertEquals(4, $c->after(3));\n        $this->assertEquals(2, $c->after(4));\n        $this->assertEquals('taylor', $c->after(5));\n        $this->assertEquals('laravel', $c->after('taylor'));\n\n        $this->assertEquals(4, $c->after(function ($value) {\n            return $value > 2;\n        }));\n        $this->assertEquals('laravel', $c->after(function ($value) {\n            return ! is_numeric($value);\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testAfterInStrictMode($collection)\n    {\n        $c = new $collection([false, 0, 1, [], '']);\n\n        $this->assertNull($c->after('false', true));\n        $this->assertNull($c->after('1', true));\n        $this->assertNull($c->after('', true));\n        $this->assertEquals(0, $c->after(false, true));\n        $this->assertEquals([], $c->after(1, true));\n        $this->assertEquals('', $c->after([], true));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testAfterReturnsNullWhenItemIsNotFound($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);\n\n        $this->assertNull($c->after(6));\n        $this->assertNull($c->after('foo'));\n        $this->assertNull($c->after(function ($value) {\n            return $value < 1 && is_numeric($value);\n        }));\n        $this->assertNull($c->after(function ($value) {\n            return $value === 'nope';\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testAfterReturnsNullWhenItemOnTheLastItem($collection)\n    {\n        $c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);\n\n        $this->assertNull($c->after('bar'));\n        $this->assertNull($c->after(function ($value) {\n            return $value > 4 && ! is_numeric($value);\n        }));\n\n        $c = new $collection(['foo' => 'bar', 1, 2, 3, 4, 5]);\n        $this->assertNull($c->after(5));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testKeys($collection)\n    {\n        $c = new $collection(['name' => 'taylor', 'framework' => 'laravel']);\n        $this->assertEquals(['name', 'framework'], $c->keys()->all());\n\n        $c = new $collection(['taylor', 'laravel']);\n        $this->assertEquals([0, 1], $c->keys()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPaginate($collection)\n    {\n        $c = new $collection(['one', 'two', 'three', 'four']);\n        $this->assertEquals(['one', 'two'], $c->forPage(0, 2)->all());\n        $this->assertEquals(['one', 'two'], $c->forPage(1, 2)->all());\n        $this->assertEquals([2 => 'three', 3 => 'four'], $c->forPage(2, 2)->all());\n        $this->assertEquals([], $c->forPage(3, 2)->all());\n    }\n\n    #[IgnoreDeprecations]\n    public function testPrepend()\n    {\n        $c = new Collection(['one', 'two', 'three', 'four']);\n        $this->assertEquals(\n            ['zero', 'one', 'two', 'three', 'four'],\n            $c->prepend('zero')->all()\n        );\n\n        $c = new Collection(['one' => 1, 'two' => 2]);\n        $this->assertEquals(\n            ['zero' => 0, 'one' => 1, 'two' => 2],\n            $c->prepend(0, 'zero')->all()\n        );\n\n        $c = new Collection(['one' => 1, 'two' => 2]);\n        $this->assertEquals(\n            [null => 0, 'one' => 1, 'two' => 2],\n            $c->prepend(0, null)->all()\n        );\n\n        $c = new Collection(['one' => 1, 'two' => 2]);\n        $this->assertEquals(\n            [null => 0, 'one' => 1, 'two' => 2],\n            $c->prepend(0, '')->all()\n        );\n    }\n\n    public function testPushWithOneItem()\n    {\n        $expected = [\n            0 => 4,\n            1 => 5,\n            2 => 6,\n            3 => ['a', 'b', 'c'],\n            4 => ['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe'],\n            5 => 'Jonny from Laroe',\n        ];\n\n        $data = new Collection([4, 5, 6]);\n        $data->push(['a', 'b', 'c']);\n        $data->push(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']);\n        $actual = $data->push('Jonny from Laroe')->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    public function testPushWithMultipleItems()\n    {\n        $expected = [\n            0 => 4,\n            1 => 5,\n            2 => 6,\n            3 => 'Jonny',\n            4 => 'from',\n            5 => 'Laroe',\n            6 => 'Jonny',\n            7 => 'from',\n            8 => 'Laroe',\n            9 => 'a',\n            10 => 'b',\n            11 => 'c',\n        ];\n\n        $data = new Collection([4, 5, 6]);\n        $data->push('Jonny', 'from', 'Laroe');\n        $data->push(...[11 => 'Jonny', 12 => 'from', 13 => 'Laroe']);\n        $data->push(...collect(['a', 'b', 'c']));\n        $actual = $data->push(...[])->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    public function testUnshiftWithOneItem()\n    {\n        $expected = [\n            0 => 'Jonny from Laroe',\n            1 => ['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe'],\n            2 => ['a', 'b', 'c'],\n            3 => 4,\n            4 => 5,\n            5 => 6,\n        ];\n\n        $data = new Collection([4, 5, 6]);\n        $data->unshift(['a', 'b', 'c']);\n        $data->unshift(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']);\n        $actual = $data->unshift('Jonny from Laroe')->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    public function testUnshiftWithMultipleItems()\n    {\n        $expected = [\n            0 => 'a',\n            1 => 'b',\n            2 => 'c',\n            3 => 'Jonny',\n            4 => 'from',\n            5 => 'Laroe',\n            6 => 'Jonny',\n            7 => 'from',\n            8 => 'Laroe',\n            9 => 4,\n            10 => 5,\n            11 => 6,\n        ];\n\n        $data = new Collection([4, 5, 6]);\n        $data->unshift('Jonny', 'from', 'Laroe');\n        $data->unshift(...[11 => 'Jonny', 12 => 'from', 13 => 'Laroe']);\n        $data->unshift(...collect(['a', 'b', 'c']));\n        $actual = $data->unshift(...[])->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testZip($collection)\n    {\n        $c = new $collection([1, 2, 3]);\n        $c = $c->zip(new $collection([4, 5, 6]));\n        $this->assertInstanceOf($collection, $c);\n        $this->assertInstanceOf($collection, $c->get(0));\n        $this->assertInstanceOf($collection, $c->get(1));\n        $this->assertInstanceOf($collection, $c->get(2));\n        $this->assertCount(3, $c);\n        $this->assertEquals([1, 4], $c->get(0)->all());\n        $this->assertEquals([2, 5], $c->get(1)->all());\n        $this->assertEquals([3, 6], $c->get(2)->all());\n\n        $c = new $collection([1, 2, 3]);\n        $c = $c->zip([4, 5, 6], [7, 8, 9]);\n        $this->assertCount(3, $c);\n        $this->assertEquals([1, 4, 7], $c->get(0)->all());\n        $this->assertEquals([2, 5, 8], $c->get(1)->all());\n        $this->assertEquals([3, 6, 9], $c->get(2)->all());\n\n        $c = new $collection([1, 2, 3]);\n        $c = $c->zip([4, 5, 6], [7]);\n        $this->assertCount(3, $c);\n        $this->assertEquals([1, 4, 7], $c->get(0)->all());\n        $this->assertEquals([2, 5, null], $c->get(1)->all());\n        $this->assertEquals([3, 6, null], $c->get(2)->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPadPadsArrayWithValue($collection)\n    {\n        $c = new $collection([1, 2, 3]);\n        $c = $c->pad(4, 0);\n        $this->assertEquals([1, 2, 3, 0], $c->all());\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $c = $c->pad(4, 0);\n        $this->assertEquals([1, 2, 3, 4, 5], $c->all());\n\n        $c = new $collection([1, 2, 3]);\n        $c = $c->pad(-4, 0);\n        $this->assertEquals([0, 1, 2, 3], $c->all());\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $c = $c->pad(-4, 0);\n        $this->assertEquals([1, 2, 3, 4, 5], $c->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGettingMaxItemsFromCollection($collection)\n    {\n        $c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);\n        $this->assertEquals(20, $c->max(function ($item) {\n            return $item->foo;\n        }));\n        $this->assertEquals(20, $c->max('foo'));\n        $this->assertEquals(20, $c->max->foo);\n\n        $c = new $collection([['foo' => 10], ['foo' => 20]]);\n        $this->assertEquals(20, $c->max('foo'));\n        $this->assertEquals(20, $c->max->foo);\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $this->assertEquals(5, $c->max());\n\n        $c = new $collection;\n        $this->assertNull($c->max());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGettingMinItemsFromCollection($collection)\n    {\n        $c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);\n        $this->assertEquals(10, $c->min(function ($item) {\n            return $item->foo;\n        }));\n        $this->assertEquals(10, $c->min('foo'));\n        $this->assertEquals(10, $c->min->foo);\n\n        $c = new $collection([['foo' => 10], ['foo' => 20]]);\n        $this->assertEquals(10, $c->min('foo'));\n        $this->assertEquals(10, $c->min->foo);\n\n        $c = new $collection([['foo' => 10], ['foo' => 20], ['foo' => null]]);\n        $this->assertEquals(10, $c->min('foo'));\n        $this->assertEquals(10, $c->min->foo);\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $this->assertEquals(1, $c->min());\n\n        $c = new $collection([1, null, 3, 4, 5]);\n        $this->assertEquals(1, $c->min());\n\n        $c = new $collection([0, 1, 2, 3, 4]);\n        $this->assertEquals(0, $c->min());\n\n        $c = new $collection;\n        $this->assertNull($c->min());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testOnly($collection)\n    {\n        $data = new $collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);\n\n        $this->assertEquals($data->all(), $data->only(null)->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->only(['first', 'missing'])->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->only('first', 'missing')->all());\n        $this->assertEquals(['first' => 'Taylor'], $data->only(collect(['first', 'missing']))->all());\n\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only(['first', 'email'])->all());\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only('first', 'email')->all());\n        $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only(collect(['first', 'email']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSelectWithArrays($collection)\n    {\n        $data = new $collection([\n            ['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'last' => 'Archer', 'email' => 'jessarcher@gmail.com'],\n        ]);\n\n        $this->assertEquals($data->all(), $data->select(null)->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(['first', 'missing'])->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select('first', 'missing')->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(collect(['first', 'missing']))->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(['first', 'email'])->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select('first', 'email')->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(collect(['first', 'email']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSelectWithArrayAccess($collection)\n    {\n        $data = new $collection([\n            new TestArrayAccessImplementation(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']),\n            new TestArrayAccessImplementation(['first' => 'Jess', 'last' => 'Archer', 'email' => 'jessarcher@gmail.com']),\n        ]);\n\n        $this->assertEquals($data->all(), $data->select(null)->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(['first', 'missing'])->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select('first', 'missing')->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(collect(['first', 'missing']))->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(['first', 'email'])->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select('first', 'email')->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(collect(['first', 'email']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSelectWithObjects($collection)\n    {\n        $data = new $collection([\n            (object) ['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com'],\n            (object) ['first' => 'Jess', 'last' => 'Archer', 'email' => 'jessarcher@gmail.com'],\n        ]);\n\n        $this->assertEquals($data->all(), $data->select(null)->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(['first', 'missing'])->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select('first', 'missing')->all());\n        $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(collect(['first', 'missing']))->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(['first', 'email'])->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select('first', 'email')->all());\n\n        $this->assertEquals([\n            ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'],\n        ], $data->select(collect(['first', 'email']))->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGettingAvgItemsFromCollection($collection)\n    {\n        $c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);\n        $this->assertEquals(15, $c->avg(function ($item) {\n            return $item->foo;\n        }));\n        $this->assertEquals(15, $c->avg('foo'));\n        $this->assertEquals(15, $c->avg->foo);\n\n        $c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20], (object) ['foo' => null]]);\n        $this->assertEquals(15, $c->avg(function ($item) {\n            return $item->foo;\n        }));\n        $this->assertEquals(15, $c->avg('foo'));\n        $this->assertEquals(15, $c->avg->foo);\n\n        $c = new $collection([['foo' => 10], ['foo' => 20]]);\n        $this->assertEquals(15, $c->avg('foo'));\n        $this->assertEquals(15, $c->avg->foo);\n\n        $c = new $collection([1, 2, 3, 4, 5]);\n        $this->assertEquals(3, $c->avg());\n\n        $c = new $collection;\n        $this->assertNull($c->avg());\n\n        $c = new $collection([['foo' => '4'], ['foo' => '2']]);\n        $this->assertIsInt($c->avg('foo'));\n        $this->assertEquals(3, $c->avg('foo'));\n\n        $c = new $collection([['foo' => 1], ['foo' => 2]]);\n        $this->assertIsFloat($c->avg('foo'));\n        $this->assertEquals(1.5, $c->avg('foo'));\n\n        $c = new $collection([\n            ['foo' => 1], ['foo' => 2],\n            (object) ['foo' => 6],\n        ]);\n        $this->assertEquals(3, $c->avg('foo'));\n\n        $c = new $collection([0]);\n        $this->assertEquals(0, $c->avg());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testJsonSerialize($collection)\n    {\n        $c = new $collection([\n            new TestArrayableObject,\n            new TestJsonableObject,\n            new TestJsonSerializeObject,\n            new TestJsonSerializeToStringObject,\n            'baz',\n        ]);\n\n        $this->assertSame([\n            ['foo' => 'bar'],\n            ['foo' => 'bar'],\n            ['foo' => 'bar'],\n            'foobar',\n            'baz',\n        ], $c->jsonSerialize());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCombineWithArray($collection)\n    {\n        $c = new $collection([1, 2, 3]);\n        $actual = $c->combine([4, 5, 6])->toArray();\n        $expected = [\n            1 => 4,\n            2 => 5,\n            3 => 6,\n        ];\n\n        $this->assertSame($expected, $actual);\n\n        $c = new $collection(['name', 'family']);\n        $actual = $c->combine([1 => 'taylor', 2 => 'otwell'])->toArray();\n        $expected = [\n            'name' => 'taylor',\n            'family' => 'otwell',\n        ];\n\n        $this->assertSame($expected, $actual);\n\n        $c = new $collection([1 => 'name', 2 => 'family']);\n        $actual = $c->combine(['taylor', 'otwell'])->toArray();\n        $expected = [\n            'name' => 'taylor',\n            'family' => 'otwell',\n        ];\n\n        $this->assertSame($expected, $actual);\n\n        $c = new $collection([1 => 'name', 2 => 'family']);\n        $actual = $c->combine([2 => 'taylor', 3 => 'otwell'])->toArray();\n        $expected = [\n            'name' => 'taylor',\n            'family' => 'otwell',\n        ];\n\n        $this->assertSame($expected, $actual);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCombineWithCollection($collection)\n    {\n        $expected = [\n            1 => 4,\n            2 => 5,\n            3 => 6,\n        ];\n\n        $keyCollection = new $collection(array_keys($expected));\n        $valueCollection = new $collection(array_values($expected));\n        $actual = $keyCollection->combine($valueCollection)->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConcatWithArray($collection)\n    {\n        $expected = [\n            0 => 4,\n            1 => 5,\n            2 => 6,\n            3 => 'a',\n            4 => 'b',\n            5 => 'c',\n            6 => 'Jonny',\n            7 => 'from',\n            8 => 'Laroe',\n            9 => 'Jonny',\n            10 => 'from',\n            11 => 'Laroe',\n        ];\n\n        $data = new $collection([4, 5, 6]);\n        $data = $data->concat(['a', 'b', 'c']);\n        $data = $data->concat(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']);\n        $actual = $data->concat(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe'])->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testConcatWithCollection($collection)\n    {\n        $expected = [\n            0 => 4,\n            1 => 5,\n            2 => 6,\n            3 => 'a',\n            4 => 'b',\n            5 => 'c',\n            6 => 'Jonny',\n            7 => 'from',\n            8 => 'Laroe',\n            9 => 'Jonny',\n            10 => 'from',\n            11 => 'Laroe',\n        ];\n\n        $firstCollection = new $collection([4, 5, 6]);\n        $secondCollection = new $collection(['a', 'b', 'c']);\n        $thirdCollection = new $collection(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']);\n        $firstCollection = $firstCollection->concat($secondCollection);\n        $firstCollection = $firstCollection->concat($thirdCollection);\n        $actual = $firstCollection->concat($thirdCollection)->toArray();\n\n        $this->assertSame($expected, $actual);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDump($collection)\n    {\n        $log = new Collection;\n\n        VarDumper::setHandler(function ($value) use ($log) {\n            $log->add($value);\n        });\n\n        (new $collection([1, 2, 3]))->dump('one', 'two');\n\n        $this->assertSame([[1, 2, 3], 'one', 'two'], $log->all());\n\n        VarDumper::setHandler(null);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReduce($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n        $this->assertEquals(6, $data->reduce(function ($carry, $element) {\n            return $carry += $element;\n        }));\n\n        $data = new $collection([\n            'foo' => 'bar',\n            'baz' => 'qux',\n        ]);\n        $this->assertSame('foobarbazqux', $data->reduce(function ($carry, $element, $key) {\n            return $carry .= $key.$element;\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReduceSpread($collection)\n    {\n        $data = new $collection([-1, 0, 1, 2, 3, 4, 5]);\n\n        [$sum, $max, $min] = $data->reduceSpread(function ($sum, $max, $min, $value) {\n            $sum += $value;\n            $max = max($max, $value);\n            $min = min($min, $value);\n\n            return [$sum, $max, $min];\n        }, 0, PHP_INT_MIN, PHP_INT_MAX);\n\n        $this->assertEquals(14, $sum);\n        $this->assertEquals(5, $max);\n        $this->assertEquals(-1, $min);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testReduceSpreadThrowsAnExceptionIfReducerDoesNotReturnAnArray($collection)\n    {\n        $data = new $collection([1]);\n\n        $this->expectException(UnexpectedValueException::class);\n\n        $data->reduceSpread(function () {\n            return false;\n        }, null);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testRandomThrowsAnExceptionUsingAmountBiggerThanCollectionSize($collection)\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $data = new $collection([1, 2, 3]);\n        $data->random(4);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPipe($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n\n        $this->assertEquals(6, $data->pipe(function ($data) {\n            return $data->sum();\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPipeInto($collection)\n    {\n        $data = new $collection([\n            'first', 'second',\n        ]);\n\n        $instance = $data->pipeInto(TestCollectionMapIntoObject::class);\n\n        $this->assertSame($data, $instance->value);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPipeThrough($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n\n        $result = $data->pipeThrough([\n            function ($data) {\n                return $data->merge([4, 5]);\n            },\n            function ($data) {\n                return $data->sum();\n            },\n        ]);\n\n        $this->assertEquals(15, $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMedianValueWithArrayCollection($collection)\n    {\n        $data = new $collection([1, 2, 2, 4]);\n\n        $this->assertEquals(2, $data->median());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMedianValueByKey($collection)\n    {\n        $data = new $collection([\n            (object) ['foo' => 1],\n            (object) ['foo' => 2],\n            (object) ['foo' => 2],\n            (object) ['foo' => 4],\n        ]);\n        $this->assertEquals(2, $data->median('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMedianOnCollectionWithNull($collection)\n    {\n        $data = new $collection([\n            (object) ['foo' => 1],\n            (object) ['foo' => 2],\n            (object) ['foo' => 4],\n            (object) ['foo' => null],\n        ]);\n        $this->assertEquals(2, $data->median('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEvenMedianCollection($collection)\n    {\n        $data = new $collection([\n            (object) ['foo' => 0],\n            (object) ['foo' => 3],\n        ]);\n        $this->assertEquals(1.5, $data->median('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMedianOutOfOrderCollection($collection)\n    {\n        $data = new $collection([\n            (object) ['foo' => 0],\n            (object) ['foo' => 5],\n            (object) ['foo' => 3],\n        ]);\n        $this->assertEquals(3, $data->median('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMedianOnEmptyCollectionReturnsNull($collection)\n    {\n        $data = new $collection;\n        $this->assertNull($data->median());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testModeOnNullCollection($collection)\n    {\n        $data = new $collection;\n        $this->assertNull($data->mode());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testMode($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 4, 5]);\n        $this->assertIsArray($data->mode());\n        $this->assertEquals([4], $data->mode());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testModeValueByKey($collection)\n    {\n        $data = new $collection([\n            (object) ['foo' => 1],\n            (object) ['foo' => 1],\n            (object) ['foo' => 2],\n            (object) ['foo' => 4],\n        ]);\n        $data2 = new Collection([\n            ['foo' => 1],\n            ['foo' => 1],\n            ['foo' => 2],\n            ['foo' => 4],\n        ]);\n        $this->assertEquals([1], $data->mode('foo'));\n        $this->assertEquals($data2->mode('foo'), $data->mode('foo'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWithMultipleModeValues($collection)\n    {\n        $data = new $collection([1, 2, 2, 1]);\n        $this->assertEquals([1, 2], $data->mode());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceOffset($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([4, 5, 6, 7, 8], $data->slice(3)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceNegativeOffset($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([6, 7, 8], $data->slice(-3)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceOffsetAndLength($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([4, 5, 6], $data->slice(3, 3)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceOffsetAndNegativeLength($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([4, 5, 6, 7], $data->slice(3, -1)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceNegativeOffsetAndLength($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([4, 5, 6], $data->slice(-5, 3)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSliceNegativeOffsetAndNegativeLength($collection)\n    {\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);\n        $this->assertEquals([3, 4, 5, 6], $data->slice(-6, -2)->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollectionFromTraversable($collection)\n    {\n        $data = new $collection(new ArrayObject([1, 2, 3]));\n        $this->assertEquals([1, 2, 3], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollectionFromTraversableWithKeys($collection)\n    {\n        $data = new $collection(new ArrayObject(['foo' => 1, 'bar' => 2, 'baz' => 3]));\n        $this->assertEquals(['foo' => 1, 'bar' => 2, 'baz' => 3], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollectionFromEnum($collection)\n    {\n        $data = new $collection(TestEnum::A);\n        $this->assertEquals([TestEnum::A], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollectionFromBackedEnum($collection)\n    {\n        $data = new $collection(TestBackedEnum::A);\n        $this->assertEquals([TestBackedEnum::A], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionWithADivisibleCount($collection)\n    {\n        $data = new $collection(['a', 'b', 'c', 'd']);\n        $split = $data->split(2);\n\n        $this->assertSame(['a', 'b'], $split->get(0)->all());\n        $this->assertSame(['c', 'd'], $split->get(1)->all());\n        $this->assertInstanceOf($collection, $split);\n\n        $this->assertEquals(\n            [['a', 'b'], ['c', 'd']],\n            $data->split(2)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n\n        $data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n        $split = $data->split(2);\n\n        $this->assertSame([1, 2, 3, 4, 5], $split->get(0)->all());\n        $this->assertSame([6, 7, 8, 9, 10], $split->get(1)->all());\n\n        $this->assertEquals(\n            [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]],\n            $data->split(2)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionWithAnUndivisableCount($collection)\n    {\n        $data = new $collection(['a', 'b', 'c']);\n        $split = $data->split(2);\n\n        $this->assertSame(['a', 'b'], $split->get(0)->all());\n        $this->assertSame(['c'], $split->get(1)->all());\n\n        $this->assertEquals(\n            [['a', 'b'], ['c']],\n            $data->split(2)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionWithCountLessThenDivisor($collection)\n    {\n        $data = new $collection(['a']);\n        $split = $data->split(2);\n\n        $this->assertSame(['a'], $split->get(0)->all());\n        $this->assertNull($split->get(1));\n\n        $this->assertEquals(\n            [['a']],\n            $data->split(2)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionIntoThreeWithCountOfFour($collection)\n    {\n        $data = new $collection(['a', 'b', 'c', 'd']);\n        $split = $data->split(3);\n\n        $this->assertSame(['a', 'b'], $split->get(0)->all());\n        $this->assertSame(['c'], $split->get(1)->all());\n        $this->assertSame(['d'], $split->get(2)->all());\n\n        $this->assertEquals(\n            [['a', 'b'], ['c'], ['d']],\n            $data->split(3)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionIntoThreeWithCountOfFive($collection)\n    {\n        $data = new $collection(['a', 'b', 'c', 'd', 'e']);\n        $split = $data->split(3);\n\n        $this->assertSame(['a', 'b'], $split->get(0)->all());\n        $this->assertSame(['c', 'd'], $split->get(1)->all());\n        $this->assertSame(['e'], $split->get(2)->all());\n\n        $this->assertEquals(\n            [['a', 'b'], ['c', 'd'], ['e']],\n            $data->split(3)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitCollectionIntoSixWithCountOfTen($collection)\n    {\n        $data = new $collection(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']);\n        $split = $data->split(6);\n\n        $this->assertSame(['a', 'b'], $split->get(0)->all());\n        $this->assertSame(['c', 'd'], $split->get(1)->all());\n        $this->assertSame(['e', 'f'], $split->get(2)->all());\n        $this->assertSame(['g', 'h'], $split->get(3)->all());\n        $this->assertSame(['i'], $split->get(4)->all());\n        $this->assertSame(['j'], $split->get(5)->all());\n\n        $this->assertEquals(\n            [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h'], ['i'], ['j']],\n            $data->split(6)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testSplitEmptyCollection($collection)\n    {\n        $data = new $collection;\n        $split = $data->split(2);\n\n        $this->assertNull($split->get(0));\n        $this->assertNull($split->get(1));\n\n        $this->assertEquals(\n            [],\n            $data->split(2)->map(function (Collection $chunk) {\n                return $chunk->values()->toArray();\n            })->toArray()\n        );\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderCollectionGroupBy($collection)\n    {\n        $data = new $collection([\n            new TestSupportCollectionHigherOrderItem,\n            new TestSupportCollectionHigherOrderItem('TAYLOR'),\n            new TestSupportCollectionHigherOrderItem('foo'),\n        ]);\n\n        $this->assertEquals([\n            'taylor' => [$data->get(0)],\n            'TAYLOR' => [$data->get(1)],\n            'foo' => [$data->get(2)],\n        ], $data->groupBy->name->toArray());\n\n        $this->assertEquals([\n            'TAYLOR' => [$data->get(0), $data->get(1)],\n            'FOO' => [$data->get(2)],\n        ], $data->groupBy->uppercase()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderCollectionMap($collection)\n    {\n        $person1 = (object) ['name' => 'Taylor'];\n        $person2 = (object) ['name' => 'Yaz'];\n\n        $data = new $collection([$person1, $person2]);\n\n        $this->assertEquals(['Taylor', 'Yaz'], $data->map->name->toArray());\n\n        $data = new $collection([new TestSupportCollectionHigherOrderItem, new TestSupportCollectionHigherOrderItem]);\n\n        $this->assertEquals(['TAYLOR', 'TAYLOR'], $data->each->uppercase()->map->name->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderCollectionMapFromArrays($collection)\n    {\n        $person1 = ['name' => 'Taylor'];\n        $person2 = ['name' => 'Yaz'];\n\n        $data = new $collection([$person1, $person2]);\n\n        $this->assertEquals(['Taylor', 'Yaz'], $data->map->name->toArray());\n\n        $data = new $collection([new TestSupportCollectionHigherOrderItem, new TestSupportCollectionHigherOrderItem]);\n\n        $this->assertEquals(['TAYLOR', 'TAYLOR'], $data->each->uppercase()->map->name->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderCollectionStaticCall($collection)\n    {\n        $class1 = TestSupportCollectionHigherOrderStaticClass1::class;\n        $class2 = TestSupportCollectionHigherOrderStaticClass2::class;\n\n        $classes = new $collection([$class1, $class2]);\n\n        $this->assertEquals(['TAYLOR', 't a y l o r'], $classes->map->transform('taylor')->toArray());\n        $this->assertEquals($class1, $classes->first->matches('Taylor'));\n        $this->assertEquals($class2, $classes->first->matches('Otwell'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartition($collection)\n    {\n        $data = new $collection(range(1, 10));\n\n        [$firstPartition, $secondPartition] = $data->partition(function ($i) {\n            return $i <= 5;\n        })->all();\n\n        $this->assertEquals([1, 2, 3, 4, 5], $firstPartition->values()->toArray());\n        $this->assertEquals([6, 7, 8, 9, 10], $secondPartition->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartitionCallbackWithKey($collection)\n    {\n        $data = new $collection(['zero', 'one', 'two', 'three']);\n\n        [$even, $odd] = $data->partition(function ($item, $index) {\n            return $index % 2 === 0;\n        })->all();\n\n        $this->assertEquals(['zero', 'two'], $even->values()->toArray());\n        $this->assertEquals(['one', 'three'], $odd->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartitionByKey($collection)\n    {\n        $courses = new $collection([\n            ['free' => true, 'title' => 'Basic'], ['free' => false, 'title' => 'Premium'],\n        ]);\n\n        [$free, $premium] = $courses->partition('free')->all();\n\n        $this->assertSame([['free' => true, 'title' => 'Basic']], $free->values()->toArray());\n        $this->assertSame([['free' => false, 'title' => 'Premium']], $premium->values()->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartitionWithOperators($collection)\n    {\n        $data = new $collection([\n            ['name' => 'Tim', 'age' => 17],\n            ['name' => 'Agatha', 'age' => 62],\n            ['name' => 'Kristina', 'age' => 33],\n            ['name' => 'Tim', 'age' => 41],\n        ]);\n\n        [$tims, $others] = $data->partition('name', 'Tim')->all();\n\n        $this->assertEquals([\n            ['name' => 'Tim', 'age' => 17],\n            ['name' => 'Tim', 'age' => 41],\n        ], $tims->values()->all());\n\n        $this->assertEquals([\n            ['name' => 'Agatha', 'age' => 62],\n            ['name' => 'Kristina', 'age' => 33],\n        ], $others->values()->all());\n\n        [$adults, $minors] = $data->partition('age', '>=', 18)->all();\n\n        $this->assertEquals([\n            ['name' => 'Agatha', 'age' => 62],\n            ['name' => 'Kristina', 'age' => 33],\n            ['name' => 'Tim', 'age' => 41],\n        ], $adults->values()->all());\n\n        $this->assertEquals([\n            ['name' => 'Tim', 'age' => 17],\n        ], $minors->values()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartitionPreservesKeys($collection)\n    {\n        $courses = new $collection([\n            'a' => ['free' => true], 'b' => ['free' => false], 'c' => ['free' => true],\n        ]);\n\n        [$free, $premium] = $courses->partition('free')->all();\n\n        $this->assertSame(['a' => ['free' => true], 'c' => ['free' => true]], $free->toArray());\n        $this->assertSame(['b' => ['free' => false]], $premium->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPartitionEmptyCollection($collection)\n    {\n        $data = new $collection;\n\n        $this->assertCount(2, $data->partition(function () {\n            return true;\n        }));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderPartition($collection)\n    {\n        $courses = new $collection([\n            'a' => ['free' => true], 'b' => ['free' => false], 'c' => ['free' => true],\n        ]);\n\n        [$free, $premium] = $courses->partition->free->all();\n\n        $this->assertSame(['a' => ['free' => true], 'c' => ['free' => true]], $free->toArray());\n\n        $this->assertSame(['b' => ['free' => false]], $premium->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testTap($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n\n        $fromTap = [];\n        $tappedInstance = null;\n        $data = $data->tap(function ($data) use (&$fromTap, &$tappedInstance) {\n            $fromTap = $data->slice(0, 1)->toArray();\n            $tappedInstance = $data;\n        });\n\n        $this->assertSame($data, $tappedInstance);\n        $this->assertSame([1], $fromTap);\n        $this->assertSame([1, 2, 3], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhen($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->when('adam', function ($data, $newName) {\n            return $data->concat([$newName]);\n        });\n\n        $this->assertSame(['michael', 'tom', 'adam'], $data->toArray());\n\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->when(false, function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['michael', 'tom'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhenDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->when(false, function ($data) {\n            return $data->concat(['adam']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'taylor'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhenEmpty($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->whenEmpty(function () {\n            throw new Exception('whenEmpty() should not trigger on a collection with items');\n        });\n\n        $this->assertSame(['michael', 'tom'], $data->toArray());\n\n        $data = new $collection;\n\n        $data = $data->whenEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhenEmptyDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->whenEmpty(function ($data) {\n            return $data->concat(['adam']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'taylor'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhenNotEmpty($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->whenNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'adam'], $data->toArray());\n\n        $data = new $collection;\n\n        $data = $data->whenNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame([], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhenNotEmptyDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->whenNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderWhenAndUnless($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->when(true)->concat(['chris']);\n\n        $this->assertSame(['michael', 'tom', 'chris'], $data->toArray());\n\n        $data = $data->when(false)->concat(['adam']);\n\n        $this->assertSame(['michael', 'tom', 'chris'], $data->toArray());\n\n        $data = $data->unless(false)->concat(['adam']);\n\n        $this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());\n\n        $data = $data->unless(true)->concat(['bogdan']);\n\n        $this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHigherOrderWhenAndUnlessWithProxy($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->when->contains('michael')->concat(['chris']);\n\n        $this->assertSame(['michael', 'tom', 'chris'], $data->toArray());\n\n        $data = $data->when->contains('missing')->concat(['adam']);\n\n        $this->assertSame(['michael', 'tom', 'chris'], $data->toArray());\n\n        $data = $data->unless->contains('missing')->concat(['adam']);\n\n        $this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());\n\n        $data = $data->unless->contains('adam')->concat(['bogdan']);\n\n        $this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnless($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unless(false, function ($data) {\n            return $data->concat(['caleb']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'caleb'], $data->toArray());\n\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unless(true, function ($data) {\n            return $data->concat(['caleb']);\n        });\n\n        $this->assertSame(['michael', 'tom'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnlessDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unless(true, function ($data) {\n            return $data->concat(['caleb']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'taylor'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnlessEmpty($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unlessEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'adam'], $data->toArray());\n\n        $data = new $collection;\n\n        $data = $data->unlessEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame([], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnlessEmptyDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unlessEmpty(function ($data) {\n            return $data->concat(['adam']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnlessNotEmpty($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unlessNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['michael', 'tom'], $data->toArray());\n\n        $data = new $collection;\n\n        $data = $data->unlessNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        });\n\n        $this->assertSame(['adam'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUnlessNotEmptyDefault($collection)\n    {\n        $data = new $collection(['michael', 'tom']);\n\n        $data = $data->unlessNotEmpty(function ($data) {\n            return $data->concat(['adam']);\n        }, function ($data) {\n            return $data->concat(['taylor']);\n        });\n\n        $this->assertSame(['michael', 'tom', 'taylor'], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHasReturnsValidResults($collection)\n    {\n        $data = new $collection(['foo' => 'one', 'bar' => 'two', 1 => 'three']);\n        $this->assertTrue($data->has('foo'));\n        $this->assertTrue($data->has('foo', 'bar', 1));\n        $this->assertFalse($data->has('foo', 'bar', 1, 'baz'));\n        $this->assertFalse($data->has('baz'));\n    }\n\n    public function testPutAddsItemToCollection()\n    {\n        $data = new Collection;\n        $this->assertSame([], $data->toArray());\n        $data->put('foo', 1);\n        $this->assertSame(['foo' => 1], $data->toArray());\n        $data->put('bar', ['nested' => 'two']);\n        $this->assertSame(['foo' => 1, 'bar' => ['nested' => 'two']], $data->toArray());\n        $data->put('foo', 3);\n        $this->assertSame(['foo' => 3, 'bar' => ['nested' => 'two']], $data->toArray());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testItThrowsExceptionWhenTryingToAccessNoProxyProperty($collection)\n    {\n        $data = new $collection;\n        $this->expectException(Exception::class);\n        $this->expectExceptionMessage('Property [foo] does not exist on this collection instance.');\n        $data->foo;\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGetWithNullReturnsNull($collection)\n    {\n        $data = new $collection([1, 2, 3]);\n        $this->assertNull($data->get(null));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGetWithDefaultValue($collection)\n    {\n        $data = new $collection(['name' => 'taylor', 'framework' => 'laravel']);\n        $this->assertEquals('34', $data->get('age', 34));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testGetWithCallbackAsDefaultValue($collection)\n    {\n        $data = new $collection(['name' => 'taylor', 'framework' => 'laravel']);\n        $result = $data->get('email', function () {\n            return 'taylor@example.com';\n        });\n        $this->assertEquals('taylor@example.com', $result);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNull($collection)\n    {\n        $data = new $collection([\n            ['name' => 'Taylor'],\n            ['name' => null],\n            ['name' => 'Bert'],\n            ['name' => false],\n            ['name' => ''],\n        ]);\n\n        $this->assertSame([\n            1 => ['name' => null],\n        ], $data->whereNull('name')->all());\n\n        $this->assertSame([], $data->whereNull()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNullWithoutKey($collection)\n    {\n        $collection = new $collection([1, null, 3, 'null', false, true]);\n        $this->assertSame([\n            1 => null,\n        ], $collection->whereNull()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNotNull($collection)\n    {\n        $data = new $collection($originalData = [\n            ['name' => 'Taylor'],\n            ['name' => null],\n            ['name' => 'Bert'],\n            ['name' => false],\n            ['name' => ''],\n        ]);\n\n        $this->assertSame([\n            0 => ['name' => 'Taylor'],\n            2 => ['name' => 'Bert'],\n            3 => ['name' => false],\n            4 => ['name' => ''],\n        ], $data->whereNotNull('name')->all());\n\n        $this->assertSame($originalData, $data->whereNotNull()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testWhereNotNullWithoutKey($collection)\n    {\n        $data = new $collection([1, null, 3, 'null', false, true]);\n\n        $this->assertSame([\n            0 => 1,\n            2 => 3,\n            3 => 'null',\n            4 => false,\n            5 => true,\n        ], $data->whereNotNull()->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testCollect($collection)\n    {\n        $data = $collection::make([\n            'a' => 1,\n            'b' => 2,\n            'c' => 3,\n        ])->collect();\n\n        $this->assertInstanceOf(Collection::class, $data);\n\n        $this->assertSame([\n            'a' => 1,\n            'b' => 2,\n            'c' => 3,\n        ], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testUndot($collection)\n    {\n        $data = $collection::make([\n            'name' => 'Taylor',\n            'meta.foo' => 'bar',\n            'meta.baz' => 'boom',\n            'meta.bam.boom' => 'bip',\n        ])->undot();\n        $this->assertSame([\n            'name' => 'Taylor',\n            'meta' => [\n                'foo' => 'bar',\n                'baz' => 'boom',\n                'bam' => [\n                    'boom' => 'bip',\n                ],\n            ],\n        ], $data->all());\n\n        $data = $collection::make([\n            'foo.0' => 'bar',\n            'foo.1' => 'baz',\n            'foo.baz' => 'boom',\n        ])->undot();\n        $this->assertSame([\n            'foo' => [\n                'bar',\n                'baz',\n                'baz' => 'boom',\n            ],\n        ], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDot($collection)\n    {\n        $data = $collection::make([\n            'name' => 'Taylor',\n            'meta' => [\n                'foo' => 'bar',\n                'baz' => 'boom',\n                'bam' => [\n                    'boom' => 'bip',\n                ],\n            ],\n        ])->dot();\n        $this->assertSame([\n            'name' => 'Taylor',\n            'meta.foo' => 'bar',\n            'meta.baz' => 'boom',\n            'meta.bam.boom' => 'bip',\n        ], $data->all());\n\n        $data = $collection::make([\n            'foo' => [\n                'bar',\n                'baz',\n                'baz' => 'boom',\n            ],\n        ])->dot();\n        $this->assertSame([\n            'foo.0' => 'bar',\n            'foo.1' => 'baz',\n            'foo.baz' => 'boom',\n        ], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testDotWithDepth($collection)\n    {\n        $data = $collection::make([\n            'name' => 'Taylor',\n            'meta' => [\n                'foo' => 'bar',\n                'bam' => [\n                    'boom' => 'bip',\n                ],\n            ],\n        ])->dot(1);\n        $this->assertSame([\n            'name' => 'Taylor',\n            'meta.foo' => 'bar',\n            'meta.bam' => [\n                'boom' => 'bip',\n            ],\n        ], $data->all());\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEnsureForScalar($collection)\n    {\n        $data = $collection::make([1, 2, 3]);\n        $data->ensure('int');\n\n        $data = $collection::make([1, 2, 3, 'foo']);\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage(\"Collection should only include [int] items, but 'string' found at position 3.\");\n        $data->ensure('int');\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEnsureForObjects($collection)\n    {\n        $data = $collection::make([new stdClass, new stdClass, new stdClass]);\n        $data->ensure(stdClass::class);\n\n        $data = $collection::make([new stdClass, new stdClass, new stdClass, $collection]);\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage(sprintf('Collection should only include [%s] items, but \\'%s\\' found at position %d.', class_basename(new stdClass()), gettype($collection), 3));\n        $data->ensure(stdClass::class);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEnsureForInheritance($collection)\n    {\n        $data = $collection::make([new \\Error, new \\Error]);\n        $data->ensure(\\Throwable::class);\n\n        $wrongType = new $collection;\n        $data = $collection::make([new \\Error, new \\Error, $wrongType]);\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage(sprintf(\"Collection should only include [%s] items, but '%s' found at position %d.\", \\Throwable::class, get_class($wrongType), 2));\n        $data->ensure(\\Throwable::class);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testEnsureForMultipleTypes($collection)\n    {\n        $data = $collection::make([new \\Error, 123]);\n        $data->ensure([\\Throwable::class, 'int']);\n\n        $wrongType = new $collection;\n        $data = $collection::make([new \\Error, new \\Error, $wrongType]);\n        $this->expectException(UnexpectedValueException::class);\n        $this->expectExceptionMessage(sprintf('Collection should only include [%s] items, but \\'%s\\' found at position %d.', implode(', ', [\\Throwable::class, 'int']), get_class($wrongType), 2));\n        $data->ensure([\\Throwable::class, 'int']);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPercentageWithFlatCollection($collection)\n    {\n        $collection = new $collection([1, 1, 2, 2, 2, 3]);\n\n        $this->assertSame(33.33, $collection->percentage(fn ($value) => $value === 1));\n        $this->assertSame(50.00, $collection->percentage(fn ($value) => $value === 2));\n        $this->assertSame(16.67, $collection->percentage(fn ($value) => $value === 3));\n        $this->assertSame(0.0, $collection->percentage(fn ($value) => $value === 5));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPercentageWithNestedCollection($collection)\n    {\n        $collection = new $collection([\n            ['name' => 'Taylor', 'foo' => 'foo'],\n            ['name' => 'Nuno', 'foo' => 'bar'],\n            ['name' => 'Dries', 'foo' => 'bar'],\n            ['name' => 'Jess', 'foo' => 'baz'],\n        ]);\n\n        $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'foo'));\n        $this->assertSame(50.00, $collection->percentage(fn ($value) => $value['foo'] === 'bar'));\n        $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'baz'));\n        $this->assertSame(0.0, $collection->percentage(fn ($value) => $value['foo'] === 'test'));\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testHighOrderPercentage($collection)\n    {\n        $collection = new $collection([\n            ['name' => 'Taylor', 'active' => true],\n            ['name' => 'Nuno', 'active' => true],\n            ['name' => 'Dries', 'active' => false],\n            ['name' => 'Jess', 'active' => true],\n        ]);\n\n        $this->assertSame(75.00, $collection->percentage->active);\n    }\n\n    #[DataProvider('collectionClassProvider')]\n    public function testPercentageReturnsNullForEmptyCollections($collection)\n    {\n        $collection = new $collection([]);\n\n        $this->assertNull($collection->percentage(fn ($value) => $value === 1));\n    }\n\n    /**\n     * Provides each collection class, respectively.\n     *\n     * @return array\n     */\n    public static function collectionClassProvider()\n    {\n        return [\n            [Collection::class],\n            [LazyCollection::class],\n        ];\n    }\n}\n\nclass TestSupportCollectionHigherOrderItem\n{\n    public $name;\n\n    public function __construct($name = 'taylor')\n    {\n        $this->name = $name;\n    }\n\n    public function uppercase()\n    {\n        return $this->name = strtoupper($this->name);\n    }\n\n    public function is($name)\n    {\n        return $this->name === $name;\n    }\n}\n\nclass TestSupportCollectionHigherOrderStaticClass1\n{\n    public static function transform($name)\n    {\n        return strtoupper($name);\n    }\n\n    public static function matches($name)\n    {\n        return str_starts_with($name, 'T');\n    }\n}\n\nclass TestSupportCollectionHigherOrderStaticClass2\n{\n    public static function transform($name)\n    {\n        return trim(chunk_split($name, 1, ' '));\n    }\n\n    public static function matches($name)\n    {\n        return str_starts_with($name, 'O');\n    }\n}\n\nclass TestAccessorEloquentTestStub\n{\n    protected $attributes = [];\n\n    public function __construct($attributes)\n    {\n        $this->attributes = $attributes;\n    }\n\n    public function __get($attribute)\n    {\n        $accessor = 'get'.lcfirst($attribute).'Attribute';\n        if (method_exists($this, $accessor)) {\n            return $this->$accessor();\n        }\n\n        return $this->$attribute;\n    }\n\n    public function __isset($attribute)\n    {\n        $accessor = 'get'.lcfirst($attribute).'Attribute';\n\n        if (method_exists($this, $accessor)) {\n            return ! is_null($this->$accessor());\n        }\n\n        return isset($this->$attribute);\n    }\n\n    public function getSomeAttribute()\n    {\n        return $this->attributes['some'];\n    }\n}\n\nclass TestArrayAccessImplementation implements ArrayAccess\n{\n    private $arr;\n\n    public function __construct($arr)\n    {\n        $this->arr = $arr;\n    }\n\n    public function offsetExists($offset): bool\n    {\n        return isset($this->arr[$offset]);\n    }\n\n    public function offsetGet($offset): mixed\n    {\n        return $this->arr[$offset];\n    }\n\n    public function offsetSet($offset, $value): void\n    {\n        $this->arr[$offset] = $value;\n    }\n\n    public function offsetUnset($offset): void\n    {\n        unset($this->arr[$offset]);\n    }\n}\n\nclass TestJsonSerializeToStringObject implements JsonSerializable\n{\n    public function jsonSerialize(): string\n    {\n        return 'foobar';\n    }\n}\n\nclass TestCollectionMapIntoObject\n{\n    public $value;\n\n    public function __construct($value)\n    {\n        $this->value = $value;\n    }\n}\n\nclass TestCollectionSubclass extends Collection\n{\n    //\n}\n\nenum StaffEnum\n{\n    case Taylor;\n    case Joe;\n    case James;\n}\n"
  },
  {
    "path": "tests/Support/SupportComposerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Composer;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Process\\Process;\n\nuse function Illuminate\\Support\\php_binary;\n\nclass SupportComposerTest extends TestCase\n{\n    public function testDumpAutoloadRunsTheCorrectCommand()\n    {\n        $composer = $this->mockComposer(['composer', 'dump-autoload']);\n\n        $composer->dumpAutoloads();\n    }\n\n    public function testDumpAutoloadRunsTheCorrectCommandWhenCustomComposerPharIsPresent()\n    {\n        $expectedProcessArguments = [php_binary(),  'composer.phar', 'dump-autoload'];\n        $customComposerPhar = true;\n\n        $composer = $this->mockComposer($expectedProcessArguments, $customComposerPhar);\n\n        $composer->dumpAutoloads();\n    }\n\n    public function testDumpAutoloadRunsTheCorrectCommandWithExtraArguments()\n    {\n        $composer = $this->mockComposer(['composer', 'dump-autoload', '--no-scripts']);\n\n        $composer->dumpAutoloads('--no-scripts');\n    }\n\n    public function testDumpOptimizedTheCorrectCommand()\n    {\n        $composer = $this->mockComposer(['composer', 'dump-autoload', '--optimize']);\n\n        $composer->dumpOptimized();\n    }\n\n    public function testRequirePackagesRunsTheCorrectCommand()\n    {\n        $composer = $this->mockComposer(['composer', 'require', 'pestphp/pest:^2.0', 'pestphp/pest-plugin-laravel:^2.0', '--dev']);\n\n        $composer->requirePackages(['pestphp/pest:^2.0', 'pestphp/pest-plugin-laravel:^2.0'], true);\n    }\n\n    public function testRemovePackagesRunsTheCorrectCommand()\n    {\n        $composer = $this->mockComposer(['composer', 'remove', 'phpunit/phpunit', '--dev']);\n\n        $composer->removePackages(['phpunit/phpunit'], true);\n    }\n\n    private function mockComposer(array $expectedProcessArguments, $customComposerPhar = false, array $environmentVariables = [])\n    {\n        $directory = __DIR__;\n\n        $files = m::mock(Filesystem::class);\n        $files->shouldReceive('exists')->once()->with($directory.'/composer.phar')->andReturn($customComposerPhar);\n\n        $process = m::mock(Process::class);\n        $process->shouldReceive('run')->once();\n\n        $composer = $this->getMockBuilder(Composer::class)\n            ->onlyMethods(['getProcess'])\n            ->setConstructorArgs([$files, $directory, $environmentVariables])\n            ->getMock();\n        $composer->expects($this->once())\n            ->method('getProcess')\n            ->with($expectedProcessArguments)\n            ->willReturn($process);\n\n        return $composer;\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportConditionableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Traits\\Conditionable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportConditionableTest extends TestCase\n{\n    public function testWhenConditionCallback()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->when(2, function ($logger, $condition) {\n                $logger->log('when', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['when', 2], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())->log('init')\n            ->when(function ($logger) {\n                return $logger->has('init');\n            }, function ($logger, $condition) {\n                $logger->log('when', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['init', 'when', true], $logger->values);\n    }\n\n    public function testWhenDefaultCallback()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->when(null, function ($logger, $condition) {\n                $logger->log('when', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['default', null], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())\n            ->when(function ($logger) {\n                return $logger->has('missing');\n            }, function ($logger, $condition) {\n                $logger->log('when', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['default', false], $logger->values);\n    }\n\n    public function testUnlessConditionCallback()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->unless(null, function ($logger, $condition) {\n                $logger->log('unless', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['unless', null], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())\n            ->unless(function ($logger) {\n                return $logger->has('missing');\n            }, function ($logger, $condition) {\n                $logger->log('unless', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['unless', false], $logger->values);\n    }\n\n    public function testUnlessDefaultCallback()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->unless(2, function ($logger, $condition) {\n                $logger->log('unless', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['default', 2], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())->log('init')\n            ->unless(function ($logger) {\n                return $logger->has('init');\n            }, function ($logger, $condition) {\n                $logger->log('unless', $condition);\n            }, function ($logger, $condition) {\n                $logger->log('default', $condition);\n            });\n\n        $this->assertSame(['init', 'default', true], $logger->values);\n    }\n\n    public function testWhenProxy()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->when(true)->log('one')\n            ->when(false)->log('two');\n\n        $this->assertSame(['one'], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())->log('init')\n            ->when(function ($logger) {\n                return $logger->has('init');\n            })\n            ->log('one')\n            ->when(function ($logger) {\n                return $logger->has('missing');\n            })\n            ->log('two')\n            ->when()->has('init')->log('three')\n            ->when()->has('missing')->log('four')\n            ->when()->toggle->log('five')\n            ->toggle()\n            ->when()->toggle->log('six');\n\n        $this->assertSame(['init', 'one', 'three', 'six'], $logger->values);\n    }\n\n    public function testUnlessProxy()\n    {\n        // With static condition\n        $logger = (new ConditionableLogger())\n            ->unless(true)->log('one')\n            ->unless(false)->log('two');\n\n        $this->assertSame(['two'], $logger->values);\n\n        // With callback condition\n        $logger = (new ConditionableLogger())->log('init')\n            ->unless(function ($logger) {\n                return $logger->has('init');\n            })\n            ->log('one')\n            ->unless(function ($logger) {\n                return $logger->has('missing');\n            })\n            ->log('two')\n            ->unless()->has('init')->log('three')\n            ->unless()->has('missing')->log('four')\n            ->unless()->toggle->log('five')\n            ->toggle()\n            ->unless()->toggle->log('six');\n\n        $this->assertSame(['init', 'two', 'four', 'five'], $logger->values);\n    }\n}\n\nclass ConditionableLogger\n{\n    use Conditionable;\n\n    public $values = [];\n\n    public $toggle = false;\n\n    public function log(...$values)\n    {\n        array_push($this->values, ...$values);\n\n        return $this;\n    }\n\n    public function has($value)\n    {\n        return in_array($value, $this->values);\n    }\n\n    public function toggle()\n    {\n        $this->toggle = ! $this->toggle;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportEnumValueFunctionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nuse function Illuminate\\Support\\enum_value;\n\ninclude_once 'Enums.php';\n\nclass SupportEnumValueFunctionTest extends TestCase\n{\n    #[DataProvider('scalarDataProvider')]\n    public function test_it_can_handle_enum_value($given, $expected)\n    {\n        $this->assertSame($expected, enum_value($given));\n    }\n\n    public function test_it_can_fallback_to_use_default_if_value_is_null()\n    {\n        $this->assertSame('laravel', enum_value(null, 'laravel'));\n        $this->assertSame('laravel', enum_value(null, fn () => 'laravel'));\n    }\n\n    public static function scalarDataProvider()\n    {\n        yield [TestEnum::A, 'A'];\n        yield [TestBackedEnum::A, 1];\n        yield [TestBackedEnum::B, 2];\n        yield [TestStringBackedEnum::A, 'A'];\n        yield [TestStringBackedEnum::B, 'B'];\n        yield [null, null];\n        yield [0, 0];\n        yield ['0', '0'];\n        yield [false, false];\n        yield [1, 1];\n        yield ['1', '1'];\n        yield [true, true];\n        yield [[], []];\n        yield ['', ''];\n        yield ['laravel', 'laravel'];\n        yield [true, true];\n        yield [1337, 1337];\n        yield [1.0, 1.0];\n        yield [$collect = collect(), $collect];\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportFacadeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayAccess;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Mockery as m;\nuse Mockery\\MockInterface;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass SupportFacadeTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Facade::clearResolvedInstances();\n        FacadeStub::setFacadeApplication(null);\n    }\n\n    public function testFacadeCallsUnderlyingApplication()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]);\n        $mock->shouldReceive('bar')->once()->andReturn('baz');\n        FacadeStub::setFacadeApplication($app);\n        $this->assertSame('baz', FacadeStub::bar());\n    }\n\n    public function testShouldReceiveReturnsAMockeryMock()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => new stdClass]);\n        FacadeStub::setFacadeApplication($app);\n\n        $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::shouldReceive('foo')->once()->with('bar')->andReturn('baz')->getMock());\n        $this->assertSame('baz', $app['foo']->foo('bar'));\n    }\n\n    public function testSpyReturnsAMockerySpy()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => new stdClass]);\n        FacadeStub::setFacadeApplication($app);\n\n        $this->assertInstanceOf(MockInterface::class, $spy = FacadeStub::spy());\n\n        FacadeStub::foo();\n        $spy->shouldHaveReceived('foo');\n    }\n\n    public function testShouldReceiveCanBeCalledTwice()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => new stdClass]);\n        FacadeStub::setFacadeApplication($app);\n\n        $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::shouldReceive('foo')->once()->with('bar')->andReturn('baz')->getMock());\n        $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::shouldReceive('foo2')->once()->with('bar2')->andReturn('baz2')->getMock());\n        $this->assertSame('baz', $app['foo']->foo('bar'));\n        $this->assertSame('baz2', $app['foo']->foo2('bar2'));\n    }\n\n    public function testCanBeMockedWithoutUnderlyingInstance()\n    {\n        FacadeStub::shouldReceive('foo')->once()->andReturn('bar');\n        $this->assertSame('bar', FacadeStub::foo());\n    }\n\n    public function testExpectsReturnsAMockeryMockWithExpectationRequired()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => new stdClass]);\n        FacadeStub::setFacadeApplication($app);\n\n        $this->assertInstanceOf(MockInterface::class, $mock = FacadeStub::expects('foo')->with('bar')->andReturn('baz')->getMock());\n        $this->assertSame('baz', $app['foo']->foo('bar'));\n    }\n\n    public function testFacadeResolvesAgainAfterClearingSpecific()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]);\n        $mock->shouldReceive('bar')->times(3)->andReturn('baz');\n\n        // Resolve for the first time\n        FacadeStub::setFacadeApplication($app);\n        $this->assertSame('baz', FacadeStub::bar());\n\n        // Clear resolved instance and resolve the second time\n        FacadeStub::clearResolvedInstance();\n        $this->assertSame('baz', FacadeStub::bar());\n\n        // Clear resolved instance through parent and resolve the third time\n        Facade::clearResolvedInstance('foo');\n        $this->assertSame('baz', FacadeStub::bar());\n    }\n\n    public function testFacadeResolvesAgainAfterClearingAll()\n    {\n        $app = new ApplicationStub;\n        $app->setAttributes(['foo' => $mock = m::mock(stdClass::class)]);\n        $mock->shouldReceive('bar')->times(2)->andReturn('baz');\n\n        // Resolve for the first time\n        FacadeStub::setFacadeApplication($app);\n        $this->assertSame('baz', FacadeStub::bar());\n\n        // Clear all resolved instances and resolve a second time\n        Facade::clearResolvedInstances();\n        $this->assertSame('baz', FacadeStub::bar());\n    }\n}\n\nclass FacadeStub extends Facade\n{\n    protected static function getFacadeAccessor()\n    {\n        return 'foo';\n    }\n}\n\nclass ApplicationStub implements ArrayAccess\n{\n    protected $attributes = [];\n\n    public function setAttributes($attributes)\n    {\n        $this->attributes = $attributes;\n    }\n\n    public function instance($key, $instance)\n    {\n        $this->attributes[$key] = $instance;\n    }\n\n    public function offsetExists($offset): bool\n    {\n        return isset($this->attributes[$offset]);\n    }\n\n    public function offsetGet($key): mixed\n    {\n        return $this->attributes[$key];\n    }\n\n    public function offsetSet($key, $value): void\n    {\n        $this->attributes[$key] = $value;\n    }\n\n    public function offsetUnset($key): void\n    {\n        unset($this->attributes[$key]);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportFacadesEventTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Cache\\CacheManager;\nuse Illuminate\\Cache\\Events\\CacheFlushed;\nuse Illuminate\\Cache\\Events\\CacheFlushing;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushed;\nuse Illuminate\\Cache\\Events\\CacheLocksFlushing;\nuse Illuminate\\Cache\\Events\\CacheMissed;\nuse Illuminate\\Cache\\Events\\RetrievingKey;\nuse Illuminate\\Config\\Repository as ConfigRepository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Events\\Dispatcher as DispatcherContract;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Events\\Dispatcher;\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Facades\\Event;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Testing\\Fakes\\EventFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportFacadesEventTest extends TestCase\n{\n    private $events;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->events = m::mock(Dispatcher::class);\n\n        $container = new Container;\n        $container->instance('events', $this->events);\n        $container->alias('events', DispatcherContract::class);\n        $container->instance('cache', new CacheManager($container));\n        $container->instance('config', new ConfigRepository($this->getCacheConfig()));\n\n        Facade::setFacadeApplication($container);\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::clearResolvedInstances();\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function testFakeFor()\n    {\n        Event::fakeFor(function () {\n            (new FakeForStub)->dispatch();\n\n            Event::assertDispatched(EventStub::class);\n        });\n\n        $this->events->shouldReceive('dispatch')->once();\n\n        (new FakeForStub)->dispatch();\n    }\n\n    public function testFakeForSwapsDispatchers()\n    {\n        $arrayRepository = Cache::store('array');\n\n        Event::fakeFor(function () use ($arrayRepository) {\n            $this->assertInstanceOf(EventFake::class, Event::getFacadeRoot());\n            $this->assertInstanceOf(EventFake::class, Model::getEventDispatcher());\n            $this->assertInstanceOf(EventFake::class, $arrayRepository->getEventDispatcher());\n        });\n\n        $this->assertSame($this->events, Event::getFacadeRoot());\n        $this->assertSame($this->events, Model::getEventDispatcher());\n        $this->assertSame($this->events, $arrayRepository->getEventDispatcher());\n    }\n\n    public function testFakeSwapsDispatchersInResolvedCacheRepositories()\n    {\n        $arrayRepository = Cache::store('array');\n\n        $this->events->shouldReceive('dispatch')->times(2);\n        $arrayRepository->get('foo');\n\n        Event::fake();\n\n        $arrayRepository->get('bar');\n\n        Event::assertDispatched(RetrievingKey::class);\n        Event::assertDispatched(CacheMissed::class);\n    }\n\n    public function testCacheFlushDispatchesEvent()\n    {\n        $arrayRepository = Cache::store('array');\n        Event::fake();\n\n        $arrayRepository->clear();\n\n        Event::assertDispatched(CacheFlushing::class);\n        Event::assertDispatched(CacheFlushed::class);\n    }\n\n    public function testCacheFlushLocksDispatchesEvent()\n    {\n        $arrayRepository = Cache::store('array');\n        Event::fake();\n\n        $arrayRepository->flushLocks();\n\n        Event::assertDispatched(CacheLocksFlushing::class);\n        Event::assertDispatched(CacheLocksFlushed::class);\n    }\n\n    protected function getCacheConfig()\n    {\n        return [\n            'cache' => [\n                'stores' => [\n                    'array' => [\n                        'driver' => 'array',\n                    ],\n                ],\n            ],\n        ];\n    }\n}\n\nclass FakeForStub\n{\n    public function dispatch()\n    {\n        Event::dispatch(EventStub::class);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportFacadesHttpTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Client\\Factory;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\Http;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportFacadesHttpTest extends TestCase\n{\n    protected $app;\n\n    protected function setUp(): void\n    {\n        $this->app = new Container;\n        Facade::setFacadeApplication($this->app);\n    }\n\n    public function testFacadeRootIsNotSharedByDefault(): void\n    {\n        $this->assertNotSame(Http::getFacadeRoot(), $this->app->make(Factory::class));\n    }\n\n    public function testFacadeRootIsSharedWhenFaked(): void\n    {\n        Http::fake([\n            'https://laravel.com' => Http::response('OK!'),\n        ]);\n\n        $factory = $this->app->make(Factory::class);\n        $this->assertSame('OK!', $factory->get('https://laravel.com')->body());\n    }\n\n    public function testFacadeRootIsSharedWhenFakedWithSequence(): void\n    {\n        Http::fakeSequence('laravel.com/*')->push('OK!');\n\n        $factory = $this->app->make(Factory::class);\n        $this->assertSame('OK!', $factory->get('https://laravel.com')->body());\n    }\n\n    public function testFacadeRootIsSharedWhenStubbingUrls(): void\n    {\n        Http::stubUrl('laravel.com', Http::response('OK!'));\n\n        $factory = $this->app->make(Factory::class);\n        $this->assertSame('OK!', $factory->get('https://laravel.com')->body());\n    }\n\n    public function testFacadeRootIsSharedWhenEnforcingFaking(): void\n    {\n        $client = Http::preventStrayRequests();\n\n        $this->assertSame($client, $this->app->make(Factory::class));\n    }\n\n    public function testFacadeRootIsSharedWhenEnforcingFakingWithAllowedUrls(): void\n    {\n        $client = Http::preventStrayRequests()->allowStrayRequests(['127.0.0.1']);\n\n        $this->assertSame($client, $this->app->make(Factory::class));\n    }\n\n    public function test_can_set_prevents_to_prevents_stray_requests(): void\n    {\n        Http::preventStrayRequests(true);\n        $this->assertTrue($this->app->make(Factory::class)->preventingStrayRequests());\n        $this->assertTrue(Http::preventingStrayRequests());\n\n        Http::preventStrayRequests(false);\n        $this->assertFalse($this->app->make(Factory::class)->preventingStrayRequests());\n        $this->assertFalse(Http::preventingStrayRequests());\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportFacadesQueueTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Queue\\Factory as QueueContract;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\Queue;\nuse Illuminate\\Support\\Testing\\Fakes\\QueueFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportFacadesQueueTest extends TestCase\n{\n    private $queueManager;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->queueManager = m::mock(Factory::class);\n\n        $container = new Container;\n        $container->instance('queue', $this->queueManager);\n        $container->alias('queue', QueueContract::class);\n\n        Facade::setFacadeApplication($container);\n    }\n\n    protected function tearDown(): void\n    {\n        Queue::clearResolvedInstance();\n        Queue::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n\n    public function testFakeFor()\n    {\n        Queue::fakeFor(function () {\n            (new QueueForStub)->pushJob();\n\n            Queue::assertPushed(QueueJobStub::class);\n        });\n\n        $this->queueManager->shouldReceive('push')->once();\n\n        (new QueueForStub)->pushJob();\n    }\n\n    public function testFakeForSwapsQueueManager()\n    {\n        Queue::fakeFor(function () {\n            $this->assertInstanceOf(QueueFake::class, Queue::getFacadeRoot());\n        });\n\n        $this->assertSame($this->queueManager, Queue::getFacadeRoot());\n    }\n\n    public function testFakeExcept()\n    {\n        $fake = Queue::fakeExcept(QueueJobStub::class);\n\n        $this->assertInstanceOf(QueueFake::class, $fake);\n        $this->assertSame($fake, Queue::getFacadeRoot());\n    }\n\n    public function testFakeExceptFor()\n    {\n        Queue::fakeExceptFor(function () {\n            $this->assertInstanceOf(QueueFake::class, Queue::getFacadeRoot());\n        }, [QueueJobStub::class]);\n\n        $this->assertSame($this->queueManager, Queue::getFacadeRoot());\n    }\n\n    public function testFakeExceptForSwapsQueueManager()\n    {\n        Queue::fakeExceptFor(function () {\n            $this->assertInstanceOf(QueueFake::class, Queue::getFacadeRoot());\n        }, []);\n\n        $this->assertSame($this->queueManager, Queue::getFacadeRoot());\n    }\n\n    public function testFakeExceptForReturnValue()\n    {\n        $result = Queue::fakeExceptFor(function () {\n            return 'test-result';\n        });\n\n        $this->assertSame('test-result', $result);\n    }\n\n    public function testFakeForReturnValue()\n    {\n        $result = Queue::fakeFor(function () {\n            return 'test-result';\n        });\n\n        $this->assertSame('test-result', $result);\n    }\n}\n\nclass QueueJobStub\n{\n    use Queueable;\n}\n\nclass OtherQueueJobStub\n{\n    use Queueable;\n}\n\nclass QueueForStub\n{\n    public function pushJob()\n    {\n        Queue::push(new QueueJobStub);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportFluentTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayIterator;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Fluent;\nuse Illuminate\\Support\\Stringable;\nuse InvalidArgumentException;\nuse IteratorAggregate;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionObject;\n\ninclude_once 'Enums.php';\n\nclass SupportFluentTest extends TestCase\n{\n    public function testAttributesAreSetByConstructor()\n    {\n        $array = ['name' => 'Taylor', 'age' => 25];\n        $fluent = new Fluent($array);\n\n        $refl = new ReflectionObject($fluent);\n        $attributes = $refl->getProperty('attributes');\n\n        $this->assertEquals($array, $attributes->getValue($fluent));\n        $this->assertEquals($array, $fluent->getAttributes());\n    }\n\n    public function testAttributesAreSetByConstructorGivenstdClass()\n    {\n        $array = ['name' => 'Taylor', 'age' => 25];\n        $fluent = new Fluent((object) $array);\n\n        $refl = new ReflectionObject($fluent);\n        $attributes = $refl->getProperty('attributes');\n\n        $this->assertEquals($array, $attributes->getValue($fluent));\n        $this->assertEquals($array, $fluent->getAttributes());\n    }\n\n    public function testAttributesAreSetByConstructorGivenArrayIterator()\n    {\n        $array = ['name' => 'Taylor', 'age' => 25];\n        $fluent = new Fluent(new FluentArrayIteratorStub($array));\n\n        $refl = new ReflectionObject($fluent);\n        $attributes = $refl->getProperty('attributes');\n\n        $this->assertEquals($array, $attributes->getValue($fluent));\n        $this->assertEquals($array, $fluent->getAttributes());\n    }\n\n    public function testGetMethodReturnsAttribute()\n    {\n        $fluent = new Fluent(['name' => 'Taylor']);\n\n        $this->assertSame('Taylor', $fluent->get('name'));\n        $this->assertSame('Default', $fluent->get('foo', 'Default'));\n        $this->assertSame('Taylor', $fluent->name);\n        $this->assertNull($fluent->foo);\n    }\n\n    public function testSetMethodSetsAttribute()\n    {\n        $fluent = new Fluent;\n\n        $fluent->set('name', 'Taylor');\n        $fluent->set('developer', true);\n        $fluent->set('posts', 25);\n        $fluent->set('computer.color', 'silver');\n\n        $this->assertSame('Taylor', $fluent->name);\n        $this->assertTrue($fluent->developer);\n        $this->assertSame(25, $fluent->posts);\n        $this->assertSame(['color' => 'silver'], $fluent->computer);\n    }\n\n    public function testArrayAccessToAttributes()\n    {\n        $fluent = new Fluent(['attributes' => '1']);\n\n        $this->assertTrue(isset($fluent['attributes']));\n        $this->assertEquals(1, $fluent['attributes']);\n\n        $fluent->attributes();\n\n        $this->assertTrue($fluent['attributes']);\n    }\n\n    public function testMagicMethodsCanBeUsedToSetAttributes()\n    {\n        $fluent = new Fluent;\n\n        $fluent->name = 'Taylor';\n        $fluent->developer();\n        $fluent->age(25);\n\n        $this->assertSame('Taylor', $fluent->name);\n        $this->assertTrue($fluent->developer);\n        $this->assertEquals(25, $fluent->age);\n        $this->assertInstanceOf(Fluent::class, $fluent->programmer());\n    }\n\n    public function testIssetMagicMethod()\n    {\n        $array = ['name' => 'Taylor', 'age' => 25];\n        $fluent = new Fluent($array);\n\n        $this->assertTrue(isset($fluent->name));\n\n        unset($fluent->name);\n\n        $this->assertFalse(isset($fluent->name));\n    }\n\n    public function testToArrayReturnsAttribute()\n    {\n        $array = ['name' => 'Taylor', 'age' => 25];\n        $fluent = new Fluent($array);\n\n        $this->assertEquals($array, $fluent->toArray());\n    }\n\n    public function testToJsonEncodesTheToArrayResult()\n    {\n        $fluent = $this->getMockBuilder(Fluent::class)->onlyMethods(['toArray'])->getMock();\n        $fluent->expects($this->once())->method('toArray')->willReturn(['foo']);\n        $results = $fluent->toJson();\n\n        $this->assertJsonStringEqualsJsonString(json_encode(['foo']), $results);\n    }\n\n    public function testToPrettyJson()\n    {\n        $fluent = $this->getMockBuilder(Fluent::class)->onlyMethods(['toArray'])->getMock();\n        $fluent->expects($this->exactly(2))->method('toArray')->willReturn(['foo' => 'bar', 'bar' => 'foo']);\n        $results = $fluent->toPrettyJson();\n        $expected = $fluent->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n    }\n\n    public function testScope()\n    {\n        $fluent = new Fluent(['user' => ['name' => 'taylor']]);\n        $this->assertEquals(['taylor'], $fluent->scope('user.name')->toArray());\n        $this->assertEquals(['dayle'], $fluent->scope('user.age', 'dayle')->toArray());\n\n        $fluent = new Fluent(['products' => ['forge', 'vapour', 'spark']]);\n        $this->assertEquals(['forge', 'vapour', 'spark'], $fluent->scope('products')->toArray());\n        $this->assertEquals(['foo', 'bar'], $fluent->scope('missing', ['foo', 'bar'])->toArray());\n\n        $fluent = new Fluent(['authors' => ['taylor' => ['products' => ['forge', 'vapour', 'spark']]]]);\n        $this->assertEquals(['forge', 'vapour', 'spark'], $fluent->scope('authors.taylor.products')->toArray());\n    }\n\n    public function testToCollection()\n    {\n        $fluent = new Fluent(['forge', 'vapour', 'spark']);\n        $this->assertEquals(['forge', 'vapour', 'spark'], $fluent->collect()->all());\n\n        $fluent = new Fluent(['authors' => ['taylor' => ['products' => ['forge', 'vapour', 'spark']]]]);\n        $this->assertEquals(['forge', 'vapour', 'spark'], $fluent->collect('authors.taylor.products')->all());\n    }\n\n    public function testStringMethod()\n    {\n        $fluent = new Fluent([\n            'int' => 123,\n            'int_str' => '456',\n            'float' => 123.456,\n            'float_str' => '123.456',\n            'float_zero' => 0.000,\n            'float_str_zero' => '0.000',\n            'str' => 'abc',\n            'empty_str' => '',\n            'null' => null,\n        ]);\n        $this->assertTrue($fluent->string('int') instanceof Stringable);\n        $this->assertTrue($fluent->string('unknown_key') instanceof Stringable);\n        $this->assertSame('123', $fluent->string('int')->value());\n        $this->assertSame('456', $fluent->string('int_str')->value());\n        $this->assertSame('123.456', $fluent->string('float')->value());\n        $this->assertSame('123.456', $fluent->string('float_str')->value());\n        $this->assertSame('0', $fluent->string('float_zero')->value());\n        $this->assertSame('0.000', $fluent->string('float_str_zero')->value());\n        $this->assertSame('', $fluent->string('empty_str')->value());\n        $this->assertSame('', $fluent->string('null')->value());\n        $this->assertSame('', $fluent->string('unknown_key')->value());\n    }\n\n    public function testBooleanMethod()\n    {\n        $fluent = new Fluent(['with_trashed' => 'false', 'download' => true, 'checked' => 1, 'unchecked' => '0', 'with_on' => 'on', 'with_yes' => 'yes']);\n        $this->assertTrue($fluent->boolean('checked'));\n        $this->assertTrue($fluent->boolean('download'));\n        $this->assertFalse($fluent->boolean('unchecked'));\n        $this->assertFalse($fluent->boolean('with_trashed'));\n        $this->assertFalse($fluent->boolean('some_undefined_key'));\n        $this->assertTrue($fluent->boolean('with_on'));\n        $this->assertTrue($fluent->boolean('with_yes'));\n    }\n\n    public function testIntegerMethod()\n    {\n        $fluent = new Fluent([\n            'int' => '123',\n            'raw_int' => 456,\n            'zero_padded' => '078',\n            'space_padded' => ' 901',\n            'nan' => 'nan',\n            'mixed' => '1ab',\n            'underscore_notation' => '2_000',\n            'null' => null,\n        ]);\n        $this->assertSame(123, $fluent->integer('int'));\n        $this->assertSame(456, $fluent->integer('raw_int'));\n        $this->assertSame(78, $fluent->integer('zero_padded'));\n        $this->assertSame(901, $fluent->integer('space_padded'));\n        $this->assertSame(0, $fluent->integer('nan'));\n        $this->assertSame(1, $fluent->integer('mixed'));\n        $this->assertSame(2, $fluent->integer('underscore_notation'));\n        $this->assertSame(123456, $fluent->integer('unknown_key', 123456));\n        $this->assertSame(0, $fluent->integer('null'));\n        $this->assertSame(0, $fluent->integer('null', 123456));\n    }\n\n    public function testFloatMethod()\n    {\n        $fluent = new Fluent([\n            'float' => '1.23',\n            'raw_float' => 45.6,\n            'decimal_only' => '.6',\n            'zero_padded' => '0.78',\n            'space_padded' => ' 90.1',\n            'nan' => 'nan',\n            'mixed' => '1.ab',\n            'scientific_notation' => '1e3',\n            'null' => null,\n        ]);\n        $this->assertSame(1.23, $fluent->float('float'));\n        $this->assertSame(45.6, $fluent->float('raw_float'));\n        $this->assertSame(.6, $fluent->float('decimal_only'));\n        $this->assertSame(0.78, $fluent->float('zero_padded'));\n        $this->assertSame(90.1, $fluent->float('space_padded'));\n        $this->assertSame(0.0, $fluent->float('nan'));\n        $this->assertSame(1.0, $fluent->float('mixed'));\n        $this->assertSame(1e3, $fluent->float('scientific_notation'));\n        $this->assertSame(123.456, $fluent->float('unknown_key', 123.456));\n        $this->assertSame(0.0, $fluent->float('null'));\n        $this->assertSame(0.0, $fluent->float('null', 123.456));\n    }\n\n    public function testArrayMethod()\n    {\n        $fluent = new Fluent(['users' => [1, 2, 3]]);\n\n        $this->assertIsArray($fluent->array('users'));\n        $this->assertEquals([1, 2, 3], $fluent->array('users'));\n        $this->assertEquals(['users' => [1, 2, 3]], $fluent->array());\n\n        $fluent = new Fluent(['text-payload']);\n        $this->assertEquals(['text-payload'], $fluent->array());\n\n        $fluent = new Fluent(['email' => 'test@example.com']);\n        $this->assertEquals(['test@example.com'], $fluent->array('email'));\n\n        $fluent = new Fluent([]);\n        $this->assertIsArray($fluent->array());\n        $this->assertEmpty($fluent->array());\n\n        $fluent = new Fluent(['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com']);\n        $this->assertEmpty($fluent->array(['developers']));\n        $this->assertNotEmpty($fluent->array(['roles']));\n        $this->assertEquals(['roles' => [4, 5, 6]], $fluent->array(['roles']));\n        $this->assertEquals(['users' => [1, 2, 3], 'email' => 'test@example.com'], $fluent->array(['users', 'email']));\n        $this->assertEquals(['roles' => [4, 5, 6], 'foo' => ['bar', 'baz']], $fluent->array(['roles', 'foo']));\n        $this->assertEquals(['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com'], $fluent->array());\n    }\n\n    public function testCollectMethod()\n    {\n        $fluent = new Fluent(['users' => [1, 2, 3]]);\n\n        $this->assertInstanceOf(Collection::class, $fluent->collect('users'));\n        $this->assertTrue($fluent->collect('developers')->isEmpty());\n        $this->assertEquals([1, 2, 3], $fluent->collect('users')->all());\n        $this->assertEquals(['users' => [1, 2, 3]], $fluent->collect()->all());\n\n        $fluent = new Fluent(['text-payload']);\n        $this->assertEquals(['text-payload'], $fluent->collect()->all());\n\n        $fluent = new Fluent(['email' => 'test@example.com']);\n        $this->assertEquals(['test@example.com'], $fluent->collect('email')->all());\n\n        $fluent = new Fluent([]);\n        $this->assertInstanceOf(Collection::class, $fluent->collect());\n        $this->assertTrue($fluent->collect()->isEmpty());\n\n        $fluent = new Fluent(['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com']);\n        $this->assertInstanceOf(Collection::class, $fluent->collect(['users']));\n        $this->assertTrue($fluent->collect(['developers'])->isEmpty());\n        $this->assertTrue($fluent->collect(['roles'])->isNotEmpty());\n        $this->assertEquals(['roles' => [4, 5, 6]], $fluent->collect(['roles'])->all());\n        $this->assertEquals(['users' => [1, 2, 3], 'email' => 'test@example.com'], $fluent->collect(['users', 'email'])->all());\n        $this->assertEquals(collect(['roles' => [4, 5, 6], 'foo' => ['bar', 'baz']]), $fluent->collect(['roles', 'foo']));\n        $this->assertEquals(['users' => [1, 2, 3], 'roles' => [4, 5, 6], 'foo' => ['bar', 'baz'], 'email' => 'test@example.com'], $fluent->collect()->all());\n    }\n\n    public function testDateMethod()\n    {\n        $fluent = new Fluent([\n            'as_null' => null,\n            'as_invalid' => 'invalid',\n\n            'as_datetime' => '20-01-01 16:30:25',\n            'as_format' => '1577896225',\n            'as_timezone' => '20-01-01 13:30:25',\n\n            'as_date' => '2020-01-01',\n            'as_time' => '16:30:25',\n        ]);\n\n        $current = Carbon::create(2020, 1, 1, 16, 30, 25);\n\n        $this->assertNull($fluent->date('as_null'));\n        $this->assertNull($fluent->date('doesnt_exists'));\n\n        $this->assertEquals($current, $fluent->date('as_datetime'));\n        $this->assertEquals($current->format('Y-m-d H:i:s P'), $fluent->date('as_format', 'U')->format('Y-m-d H:i:s P'));\n        $this->assertEquals($current, $fluent->date('as_timezone', null, 'America/Santiago'));\n\n        $this->assertTrue($fluent->date('as_date')->isSameDay($current));\n        $this->assertTrue($fluent->date('as_time')->isSameSecond('16:30:25'));\n    }\n\n    public function testDateMethodExceptionWhenValueInvalid()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $fluent = new Fluent([\n            'date' => 'invalid',\n        ]);\n\n        $fluent->date('date');\n    }\n\n    public function testDateMethodExceptionWhenFormatInvalid()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $fluent = new Fluent([\n            'date' => '20-01-01 16:30:25',\n        ]);\n\n        $fluent->date('date', 'invalid_format');\n    }\n\n    public function testEnumMethod()\n    {\n        $fluent = new Fluent([\n            'valid_enum_value' => 'A',\n            'invalid_enum_value' => 'invalid',\n            'empty_value_request' => '',\n            'string' => [\n                'a' => '1',\n                'b' => '2',\n                'doesnt_exist' => '-1024',\n            ],\n            'int' => [\n                'a' => 1,\n                'b' => 2,\n                'doesnt_exist' => 1024,\n            ],\n        ]);\n\n        $this->assertNull($fluent->enum('doesnt_exist', TestEnum::class));\n\n        $this->assertEquals(TestStringBackedEnum::A, $fluent->enum('valid_enum_value', TestStringBackedEnum::class));\n\n        $this->assertNull($fluent->enum('invalid_enum_value', TestStringBackedEnum::class));\n        $this->assertNull($fluent->enum('empty_value_request', TestStringBackedEnum::class));\n        $this->assertNull($fluent->enum('valid_enum_value', TestEnum::class));\n\n        $this->assertEquals(TestBackedEnum::A, $fluent->enum('string.a', TestBackedEnum::class));\n        $this->assertEquals(TestBackedEnum::B, $fluent->enum('string.b', TestBackedEnum::class));\n        $this->assertNull($fluent->enum('string.doesnt_exist', TestBackedEnum::class));\n        $this->assertEquals(TestBackedEnum::A, $fluent->enum('int.a', TestBackedEnum::class));\n        $this->assertEquals(TestBackedEnum::B, $fluent->enum('int.b', TestBackedEnum::class));\n        $this->assertNull($fluent->enum('int.doesnt_exist', TestBackedEnum::class));\n    }\n\n    public function testEnumsMethod()\n    {\n        $fluent = new Fluent([\n            'valid_enum_values' => ['A', 'B'],\n            'invalid_enum_values' => ['invalid', 'invalid'],\n            'empty_value_request' => [],\n            'string' => [\n                'a' => ['1', '2'],\n                'b' => '2',\n                'doesnt_exist' => '-1024',\n            ],\n            'int' => [\n                'a' => [1, 2],\n                'b' => 2,\n                'doesnt_exist' => 1024,\n            ],\n        ]);\n\n        $this->assertEmpty($fluent->enums('doesnt_exist', TestEnum::class));\n\n        $this->assertEquals([TestStringBackedEnum::A, TestStringBackedEnum::B], $fluent->enums('valid_enum_values', TestStringBackedEnum::class));\n\n        $this->assertEmpty($fluent->enums('invalid_enum_value', TestStringBackedEnum::class));\n        $this->assertEmpty($fluent->enums('empty_value_request', TestStringBackedEnum::class));\n        $this->assertEmpty($fluent->enums('valid_enum_value', TestEnum::class));\n\n        $this->assertEquals([TestBackedEnum::A, TestBackedEnum::B], $fluent->enums('string.a', TestBackedEnum::class));\n        $this->assertEquals([TestBackedEnum::B], $fluent->enums('string.b', TestBackedEnum::class));\n        $this->assertEmpty($fluent->enums('string.doesnt_exist', TestBackedEnum::class));\n\n        $this->assertEquals([TestBackedEnum::A, TestBackedEnum::B], $fluent->enums('int.a', TestBackedEnum::class));\n        $this->assertEquals([TestBackedEnum::B], $fluent->enums('int.b', TestBackedEnum::class));\n        $this->assertEmpty($fluent->enums('int.doesnt_exist', TestBackedEnum::class));\n    }\n\n    public function testFill()\n    {\n        $fluent = new Fluent(['name' => 'John Doe']);\n\n        $fluent->fill([\n            'email' => 'john.doe@example.com',\n            'age' => 30,\n        ]);\n\n        $this->assertEquals([\n            'name' => 'John Doe',\n            'email' => 'john.doe@example.com',\n            'age' => 30,\n        ], $fluent->getAttributes());\n    }\n\n    public function testMacroable()\n    {\n        Fluent::macro('foo', function () {\n            return $this->fill([\n                'foo' => 'bar',\n                'baz' => 'zal',\n            ]);\n        });\n\n        $fluent = new Fluent([\n            'bee' => 'ser',\n        ]);\n\n        $this->assertSame([\n            'bee' => 'ser',\n            'foo' => 'bar',\n            'baz' => 'zal',\n        ], $fluent->foo()->all());\n    }\n\n    public function testFluentIsIterable()\n    {\n        $fluent = new Fluent([\n            'name' => 'Taylor',\n            'role' => 'admin',\n        ]);\n\n        $result = [];\n\n        foreach ($fluent as $key => $value) {\n            $result[$key] = $value;\n        }\n\n        $this->assertSame([\n            'name' => 'Taylor',\n            'role' => 'admin',\n        ], $result);\n    }\n\n    public function testFluentIsEmpty()\n    {\n        $fluent = new Fluent;\n\n        $this->assertTrue($fluent->isEmpty());\n        $this->assertFalse($fluent->isNotEmpty());\n    }\n\n    public function testFluentIsNotEmpty()\n    {\n        $fluent = new Fluent([\n            'name' => 'Taylor',\n            'role' => 'admin',\n        ]);\n\n        $this->assertTrue($fluent->isNotEmpty());\n        $this->assertFalse($fluent->isEmpty());\n    }\n}\n\nclass FluentArrayIteratorStub implements IteratorAggregate\n{\n    protected $items = [];\n\n    public function __construct(array $items = [])\n    {\n        $this->items = $items;\n    }\n\n    public function getIterator(): ArrayIterator\n    {\n        return new ArrayIterator($this->items);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportHelpersTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Carbon\\CarbonInterval;\nuse Countable;\nuse Error;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Env;\nuse Illuminate\\Support\\Optional;\nuse Illuminate\\Support\\Sleep;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Tests\\Support\\Fixtures\\IntBackedEnum;\nuse Illuminate\\Tests\\Support\\Fixtures\\StringBackedEnum;\nuse IteratorAggregate;\nuse LogicException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\nuse RuntimeException;\nuse stdClass;\nuse Traversable;\n\nclass SupportHelpersTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        mkdir(__DIR__.'/tmp');\n\n        parent::setUp();\n    }\n\n    protected function tearDown(): void\n    {\n        if (is_dir(__DIR__.'/tmp')) {\n            (new Filesystem)->deleteDirectory(__DIR__.'/tmp');\n        }\n\n        parent::tearDown();\n    }\n\n    public function testE()\n    {\n        $str = 'A \\'quote\\' is <b>bold</b>';\n        $this->assertSame('A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;', e($str));\n\n        $html = m::mock(Htmlable::class);\n        $html->shouldReceive('toHtml')->andReturn($str);\n        $this->assertEquals($str, e($html));\n    }\n\n    public function testEWithInvalidCodePoints()\n    {\n        $str = mb_convert_encoding('føø bar', 'ISO-8859-1', 'UTF-8');\n        $this->assertEquals('f�� bar', e($str));\n    }\n\n    public function testEWithEnums()\n    {\n        $enumValue = StringBackedEnum::ADMIN_LABEL;\n        $this->assertSame('I am &#039;admin&#039;', e($enumValue));\n\n        $enumValue = IntBackedEnum::ROLE_ADMIN;\n        $this->assertSame('1', e($enumValue));\n    }\n\n    public function testBlank()\n    {\n        $this->assertTrue(blank(null));\n        $this->assertTrue(blank(''));\n        $this->assertTrue(blank('  '));\n        $this->assertTrue(blank(new Stringable('')));\n        $this->assertTrue(blank(new Stringable('  ')));\n        $this->assertFalse(blank(10));\n        $this->assertFalse(blank(true));\n        $this->assertFalse(blank(false));\n        $this->assertFalse(blank(0));\n        $this->assertFalse(blank(0.0));\n        $this->assertFalse(blank(new Stringable(' FooBar ')));\n\n        $object = new SupportTestCountable();\n        $this->assertTrue(blank($object));\n    }\n\n    public function testBlankDoesntJsonSerializeModels()\n    {\n        $model = new class extends Model\n        {\n            public function jsonSerialize(): mixed\n            {\n                throw new RuntimeException('Model should not be serialized');\n            }\n        };\n\n        $this->assertFalse(blank($model));\n    }\n\n    public function testClassBasename()\n    {\n        $this->assertSame('Baz', class_basename('Foo\\Bar\\Baz'));\n        $this->assertSame('Baz', class_basename('Baz'));\n        // back-slash\n        $this->assertSame('Baz', class_basename('\\Baz'));\n        $this->assertSame('Baz', class_basename('\\\\\\\\Baz\\\\'));\n        $this->assertSame('Baz', class_basename('\\Foo\\Bar\\Baz\\\\'));\n        $this->assertSame('Baz', class_basename('\\Foo/Bar\\Baz/'));\n        // forward-slash\n        $this->assertSame('Baz', class_basename('/Foo/Bar/Baz/'));\n        $this->assertSame('Baz', class_basename('/Foo///Bar/Baz//'));\n        // accepts objects\n        $this->assertSame('stdClass', class_basename(new stdClass()));\n        // edge-cases\n        $this->assertSame('1', class_basename(1));\n        $this->assertSame('1', class_basename('1'));\n        $this->assertSame('', class_basename(''));\n        $this->assertSame('', class_basename('\\\\'));\n        $this->assertSame('', class_basename('\\\\\\\\'));\n        $this->assertSame('', class_basename('/'));\n        $this->assertSame('', class_basename('///'));\n        $this->assertSame('..', class_basename('\\Foo\\Bar\\Baz\\\\..\\\\'));\n    }\n\n    public function testWhen()\n    {\n        $this->assertEquals('Hello', when(true, 'Hello'));\n        $this->assertNull(when(false, 'Hello'));\n        $this->assertEquals('There', when(1 === 1, 'There')); // strict types\n        $this->assertEquals('There', when(1 == '1', 'There')); // loose types\n        $this->assertNull(when(1 == 2, 'There'));\n        $this->assertNull(when('1', fn () => null));\n        $this->assertNull(when(0, fn () => null));\n        $this->assertEquals('True', when([1, 2, 3, 4], 'True')); // Array\n        $this->assertNull(when([], 'True')); // Empty Array = Falsy\n        $this->assertEquals('True', when(new StdClass, fn () => 'True')); // Object\n        $this->assertEquals('World', when(false, 'Hello', 'World'));\n        $this->assertEquals('World', when(1 === 0, 'Hello', 'World')); // strict types\n        $this->assertEquals('World', when(1 == '0', 'Hello', 'World')); // loose types\n        $this->assertNull(when('', fn () => 'There', fn () => null));\n        $this->assertNull(when(0, fn () => 'There', fn () => null));\n        $this->assertEquals('False', when([], 'True', 'False'));  // Empty Array = Falsy\n        $this->assertTrue(when(true, fn ($value) => $value, fn ($value) => ! $value)); // lazy evaluation\n        $this->assertTrue(when(false, fn ($value) => $value, fn ($value) => ! $value)); // lazy evaluation\n        $this->assertEquals('Hello', when(fn () => true, 'Hello')); // lazy evaluation condition\n        $this->assertEquals('World', when(fn () => false, 'Hello', 'World')); // lazy evaluation condition\n    }\n\n    public function testFilled()\n    {\n        $this->assertFalse(filled(null));\n        $this->assertFalse(filled(''));\n        $this->assertFalse(filled('  '));\n        $this->assertFalse(filled(new Stringable('')));\n        $this->assertFalse(filled(new Stringable('  ')));\n        $this->assertTrue(filled(10));\n        $this->assertTrue(filled(true));\n        $this->assertTrue(filled(false));\n        $this->assertTrue(filled(0));\n        $this->assertTrue(filled(0.0));\n        $this->assertTrue(filled(new Stringable(' FooBar ')));\n\n        $object = new SupportTestCountable();\n        $this->assertFalse(filled($object));\n    }\n\n    public function testValue()\n    {\n        $callable = new class\n        {\n            public function __call($method, $arguments)\n            {\n                return $arguments;\n            }\n        };\n\n        $this->assertSame($callable, value($callable, 'foo'));\n        $this->assertSame('foo', value('foo'));\n        $this->assertSame('foo', value(function () {\n            return 'foo';\n        }));\n        $this->assertSame('foo', value(function ($arg) {\n            return $arg;\n        }, 'foo'));\n    }\n\n    public function testObjectGet()\n    {\n        $class = new stdClass;\n        $class->name = new stdClass;\n        $class->name->first = 'Taylor';\n\n        $this->assertSame('Taylor', object_get($class, 'name.first'));\n        $this->assertSame('Taylor', object_get($class, 'name.first', 'default'));\n    }\n\n    public function testObjectGetDefaultValue()\n    {\n        $class = new stdClass;\n        $class->name = new stdClass;\n        $class->name->first = 'Taylor';\n\n        $this->assertSame('default', object_get($class, 'name.family', 'default'));\n        $this->assertNull(object_get($class, 'name.family'));\n    }\n\n    public function testObjectGetWhenKeyIsNullOrEmpty()\n    {\n        $object = new stdClass;\n\n        $this->assertEquals($object, object_get($object, null));\n        $this->assertEquals($object, object_get($object, false));\n        $this->assertEquals($object, object_get($object, ''));\n        $this->assertEquals($object, object_get($object, '  '));\n    }\n\n    public function testDataHas()\n    {\n        $object = (object) ['users' => ['name' => ['Taylor', 'Otwell']]];\n        $array = [(object) ['users' => [(object) ['name' => 'Taylor']]]];\n        $dottedArray = ['users' => ['first.name' => 'Taylor', 'middle.name' => null]];\n        $arrayAccess = new SupportTestArrayAccess(['price' => 56, 'user' => new SupportTestArrayAccess(['name' => 'John']), 'email' => null]);\n        $sameKeyMultiLevel = (object) ['name' => 'Taylor', 'company' => ['name' => 'Laravel']];\n        $plainArray = [1, 2, 3];\n\n        $this->assertTrue(data_has($object, 'users.name.0'));\n        $this->assertTrue(data_has($array, '0.users.0.name'));\n        $this->assertFalse(data_has($array, '0.users.3'));\n        $this->assertFalse(data_has($array, '0.users.3'));\n        $this->assertFalse(data_has($array, '0.users.3'));\n        $this->assertTrue(data_has($dottedArray, ['users', 'first.name']));\n        $this->assertTrue(data_has($dottedArray, ['users', 'middle.name']));\n        $this->assertFalse(data_has($dottedArray, ['users', 'last.name']));\n        $this->assertTrue(data_has($arrayAccess, 'price'));\n        $this->assertTrue(data_has($arrayAccess, 'user.name'));\n        $this->assertFalse(data_has($arrayAccess, 'foo'));\n        $this->assertFalse(data_has($arrayAccess, 'user.foo'));\n        $this->assertFalse(data_has($arrayAccess, 'foo'));\n        $this->assertFalse(data_has($arrayAccess, 'user.foo'));\n        $this->assertTrue(data_has($arrayAccess, 'email'));\n        $this->assertTrue(data_has($sameKeyMultiLevel, 'name'));\n        $this->assertTrue(data_has($sameKeyMultiLevel, 'company.name'));\n        $this->assertFalse(data_has($sameKeyMultiLevel, 'foo.name'));\n        $this->assertTrue(data_has($plainArray, 0));\n        $this->assertTrue(data_has($plainArray, '0'));\n        $this->assertFalse(data_has($plainArray, 4));\n        $this->assertFalse(data_has($plainArray, '4'));\n        $this->assertFalse(data_has($plainArray, ''));\n        $this->assertFalse(data_has($plainArray, []));\n        $this->assertFalse(data_has($plainArray, null));\n    }\n\n    public function testDataGet()\n    {\n        $object = (object) ['users' => ['name' => ['Taylor', 'Otwell']]];\n        $array = [(object) ['users' => [(object) ['name' => 'Taylor']]]];\n        $dottedArray = ['users' => ['first.name' => 'Taylor', 'middle.name' => null]];\n        $arrayAccess = new SupportTestArrayAccess(['price' => 56, 'user' => new SupportTestArrayAccess(['name' => 'John']), 'email' => null]);\n\n        $this->assertSame('Taylor', data_get($object, 'users.name.0'));\n        $this->assertSame('Taylor', data_get($array, '0.users.0.name'));\n        $this->assertNull(data_get($array, '0.users.3'));\n        $this->assertSame('Not found', data_get($array, '0.users.3', 'Not found'));\n        $this->assertSame('Not found', data_get($array, '0.users.3', function () {\n            return 'Not found';\n        }));\n        $this->assertSame('Taylor', data_get($dottedArray, ['users', 'first.name']));\n        $this->assertNull(data_get($dottedArray, ['users', 'middle.name']));\n        $this->assertSame('Not found', data_get($dottedArray, ['users', 'last.name'], 'Not found'));\n        $this->assertEquals(56, data_get($arrayAccess, 'price'));\n        $this->assertSame('John', data_get($arrayAccess, 'user.name'));\n        $this->assertSame('void', data_get($arrayAccess, 'foo', 'void'));\n        $this->assertSame('void', data_get($arrayAccess, 'user.foo', 'void'));\n        $this->assertNull(data_get($arrayAccess, 'foo'));\n        $this->assertNull(data_get($arrayAccess, 'user.foo'));\n        $this->assertNull(data_get($arrayAccess, 'email', 'Not found'));\n    }\n\n    public function testDataGetWithNestedArrays()\n    {\n        $array = [\n            ['name' => 'taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['name' => 'abigail'],\n            ['name' => 'dayle'],\n        ];\n        $arrayIterable = new SupportTestArrayIterable([\n            ['name' => 'taylor', 'email' => 'taylorotwell@gmail.com'],\n            ['name' => 'abigail'],\n            ['name' => 'dayle'],\n        ]);\n\n        $this->assertEquals(['taylor', 'abigail', 'dayle'], data_get($array, '*.name'));\n        $this->assertEquals(['taylorotwell@gmail.com', null, null], data_get($array, '*.email', 'irrelevant'));\n\n        $this->assertEquals(['taylor', 'abigail', 'dayle'], data_get($arrayIterable, '*.name'));\n        $this->assertEquals(['taylorotwell@gmail.com', null, null], data_get($arrayIterable, '*.email', 'irrelevant'));\n\n        $array = [\n            'users' => [\n                ['first' => 'taylor', 'last' => 'otwell', 'email' => 'taylorotwell@gmail.com'],\n                ['first' => 'abigail', 'last' => 'otwell'],\n                ['first' => 'dayle', 'last' => 'rees'],\n            ],\n            'posts' => null,\n        ];\n\n        $this->assertEquals(['taylor', 'abigail', 'dayle'], data_get($array, 'users.*.first'));\n        $this->assertEquals(['taylorotwell@gmail.com', null, null], data_get($array, 'users.*.email', 'irrelevant'));\n        $this->assertSame('not found', data_get($array, 'posts.*.date', 'not found'));\n        $this->assertNull(data_get($array, 'posts.*.date'));\n    }\n\n    public function testDataGetWithDoubleNestedArraysCollapsesResult()\n    {\n        $array = [\n            'posts' => [\n                [\n                    'comments' => [\n                        ['author' => 'taylor', 'likes' => 4],\n                        ['author' => 'abigail', 'likes' => 3],\n                    ],\n                ],\n                [\n                    'comments' => [\n                        ['author' => 'abigail', 'likes' => 2],\n                        ['author' => 'dayle'],\n                    ],\n                ],\n                [\n                    'comments' => [\n                        ['author' => 'dayle'],\n                        ['author' => 'taylor', 'likes' => 1],\n                    ],\n                ],\n            ],\n        ];\n\n        $this->assertEquals(['taylor', 'abigail', 'abigail', 'dayle', 'dayle', 'taylor'], data_get($array, 'posts.*.comments.*.author'));\n        $this->assertEquals([4, 3, 2, null, null, 1], data_get($array, 'posts.*.comments.*.likes'));\n        $this->assertEquals([], data_get($array, 'posts.*.users.*.name', 'irrelevant'));\n        $this->assertEquals([], data_get($array, 'posts.*.users.*.name'));\n    }\n\n    public function testDataGetFirstLastDirectives()\n    {\n        $array = [\n            'flights' => [\n                [\n                    'segments' => [\n                        ['from' => 'LHR', 'departure' => '9:00', 'to' => 'IST', 'arrival' => '15:00'],\n                        ['from' => 'IST', 'departure' => '16:00', 'to' => 'PKX', 'arrival' => '20:00'],\n                    ],\n                ],\n                [\n                    'segments' => [\n                        ['from' => 'LGW', 'departure' => '8:00', 'to' => 'SAW', 'arrival' => '14:00'],\n                        ['from' => 'SAW', 'departure' => '15:00', 'to' => 'PEK', 'arrival' => '19:00'],\n                    ],\n                ],\n            ],\n            'empty' => [],\n        ];\n\n        $this->assertEquals('LHR', data_get($array, 'flights.0.segments.{first}.from'));\n        $this->assertEquals('PKX', data_get($array, 'flights.0.segments.{last}.to'));\n\n        $this->assertEquals('LHR', data_get($array, 'flights.{first}.segments.{first}.from'));\n        $this->assertEquals('PEK', data_get($array, 'flights.{last}.segments.{last}.to'));\n        $this->assertEquals('PKX', data_get($array, 'flights.{first}.segments.{last}.to'));\n        $this->assertEquals('LGW', data_get($array, 'flights.{last}.segments.{first}.from'));\n\n        $this->assertEquals(['LHR', 'IST'], data_get($array, 'flights.{first}.segments.*.from'));\n        $this->assertEquals(['SAW', 'PEK'], data_get($array, 'flights.{last}.segments.*.to'));\n\n        $this->assertEquals(['LHR', 'LGW'], data_get($array, 'flights.*.segments.{first}.from'));\n        $this->assertEquals(['PKX', 'PEK'], data_get($array, 'flights.*.segments.{last}.to'));\n\n        $this->assertEquals('Not found', data_get($array, 'empty.{first}', 'Not found'));\n        $this->assertEquals('Not found', data_get($array, 'empty.{last}', 'Not found'));\n    }\n\n    public function testDataGetFirstLastDirectivesOnArrayAccessIterable()\n    {\n        $arrayAccessIterable = [\n            'flights' => new SupportTestArrayAccessIterable([\n                [\n                    'segments' => new SupportTestArrayAccessIterable([\n                        ['from' => 'LHR', 'departure' => '9:00', 'to' => 'IST', 'arrival' => '15:00'],\n                        ['from' => 'IST', 'departure' => '16:00', 'to' => 'PKX', 'arrival' => '20:00'],\n                    ]),\n                ],\n                [\n                    'segments' => new SupportTestArrayAccessIterable([\n                        ['from' => 'LGW', 'departure' => '8:00', 'to' => 'SAW', 'arrival' => '14:00'],\n                        ['from' => 'SAW', 'departure' => '15:00', 'to' => 'PEK', 'arrival' => '19:00'],\n                    ]),\n                ],\n            ]),\n            'empty' => new SupportTestArrayAccessIterable([]),\n        ];\n\n        $this->assertEquals('LHR', data_get($arrayAccessIterable, 'flights.0.segments.{first}.from'));\n        $this->assertEquals('PKX', data_get($arrayAccessIterable, 'flights.0.segments.{last}.to'));\n\n        $this->assertEquals('LHR', data_get($arrayAccessIterable, 'flights.{first}.segments.{first}.from'));\n        $this->assertEquals('PEK', data_get($arrayAccessIterable, 'flights.{last}.segments.{last}.to'));\n        $this->assertEquals('PKX', data_get($arrayAccessIterable, 'flights.{first}.segments.{last}.to'));\n        $this->assertEquals('LGW', data_get($arrayAccessIterable, 'flights.{last}.segments.{first}.from'));\n\n        $this->assertEquals(['LHR', 'IST'], data_get($arrayAccessIterable, 'flights.{first}.segments.*.from'));\n        $this->assertEquals(['SAW', 'PEK'], data_get($arrayAccessIterable, 'flights.{last}.segments.*.to'));\n\n        $this->assertEquals(['LHR', 'LGW'], data_get($arrayAccessIterable, 'flights.*.segments.{first}.from'));\n        $this->assertEquals(['PKX', 'PEK'], data_get($arrayAccessIterable, 'flights.*.segments.{last}.to'));\n\n        $this->assertEquals('Not found', data_get($arrayAccessIterable, 'empty.{first}', 'Not found'));\n        $this->assertEquals('Not found', data_get($arrayAccessIterable, 'empty.{last}', 'Not found'));\n    }\n\n    public function testDataGetFirstLastDirectivesOnKeyedArrays()\n    {\n        $array = [\n            'numericKeys' => [\n                2 => 'first',\n                0 => 'second',\n                1 => 'last',\n            ],\n            'stringKeys' => [\n                'one' => 'first',\n                'two' => 'second',\n                'three' => 'last',\n            ],\n        ];\n\n        $this->assertEquals('second', data_get($array, 'numericKeys.0'));\n        $this->assertEquals('first', data_get($array, 'numericKeys.{first}'));\n        $this->assertEquals('last', data_get($array, 'numericKeys.{last}'));\n        $this->assertEquals('first', data_get($array, 'stringKeys.{first}'));\n        $this->assertEquals('last', data_get($array, 'stringKeys.{last}'));\n    }\n\n    public function testDataGetEscapedSegmentKeys()\n    {\n        $array = [\n            'symbols' => [\n                '{last}' => ['description' => 'dollar'],\n                '*' => ['description' => 'asterisk'],\n                '{first}' => ['description' => 'caret'],\n            ],\n        ];\n\n        $this->assertEquals('caret', data_get($array, 'symbols.\\{first}.description'));\n        $this->assertEquals('dollar', data_get($array, 'symbols.{first}.description'));\n        $this->assertEquals('asterisk', data_get($array, 'symbols.\\*.description'));\n        $this->assertEquals(['dollar', 'asterisk', 'caret'], data_get($array, 'symbols.*.description'));\n        $this->assertEquals('dollar', data_get($array, 'symbols.\\{last}.description'));\n        $this->assertEquals('caret', data_get($array, 'symbols.{last}.description'));\n    }\n\n    public function testDataGetStar()\n    {\n        $data = ['foo' => 'bar'];\n        $this->assertEquals(['bar'], data_get($data, '*'));\n\n        $data = collect(['foo' => 'bar']);\n        $this->assertEquals(['bar'], data_get($data, '*'));\n    }\n\n    public function testDataGetNullKey()\n    {\n        $data = ['foo' => 'bar'];\n\n        $this->assertEquals(['foo' => 'bar'], data_get($data, null));\n        $this->assertEquals(['foo' => 'bar'], data_get($data, null, '42'));\n        $this->assertEquals(['foo' => 'bar'], data_get($data, [null]));\n\n        $data = ['foo' => 'bar', 'baz' => 42];\n        $this->assertEquals(['foo' => 'bar', 'baz' => 42], data_get($data, [null, 'foo']));\n    }\n\n    public function testDataFill()\n    {\n        $data = ['foo' => 'bar'];\n\n        $this->assertEquals(['foo' => 'bar', 'baz' => 'boom'], data_fill($data, 'baz', 'boom'));\n        $this->assertEquals(['foo' => 'bar', 'baz' => 'boom'], data_fill($data, 'baz', 'noop'));\n        $this->assertEquals(['foo' => [], 'baz' => 'boom'], data_fill($data, 'foo.*', 'noop'));\n        $this->assertEquals(\n            ['foo' => ['bar' => 'kaboom'], 'baz' => 'boom'],\n            data_fill($data, 'foo.bar', 'kaboom')\n        );\n    }\n\n    public function testDataFillWithStar()\n    {\n        $data = ['foo' => 'bar'];\n\n        $this->assertEquals(\n            ['foo' => []],\n            data_fill($data, 'foo.*.bar', 'noop')\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => [['baz' => 'original'], []]],\n            data_fill($data, 'bar', [['baz' => 'original'], []])\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => [['baz' => 'original'], ['baz' => 'boom']]],\n            data_fill($data, 'bar.*.baz', 'boom')\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => [['baz' => 'original'], ['baz' => 'boom']]],\n            data_fill($data, 'bar.*', 'noop')\n        );\n    }\n\n    public function testDataFillWithDoubleStar()\n    {\n        $data = [\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'First'],\n                        (object) [],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) [],\n                        (object) ['name' => 'Second'],\n                    ],\n                ],\n            ],\n        ];\n\n        data_fill($data, 'posts.*.comments.*.name', 'Filled');\n\n        $this->assertEquals([\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'First'],\n                        (object) ['name' => 'Filled'],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'Filled'],\n                        (object) ['name' => 'Second'],\n                    ],\n                ],\n            ],\n        ], $data);\n    }\n\n    public function testDataSet()\n    {\n        $data = ['foo' => 'bar'];\n\n        $this->assertEquals(\n            ['foo' => 'bar', 'baz' => 'boom'],\n            data_set($data, 'baz', 'boom')\n        );\n\n        $this->assertEquals(\n            ['foo' => 'bar', 'baz' => 'kaboom'],\n            data_set($data, 'baz', 'kaboom')\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'baz' => 'kaboom'],\n            data_set($data, 'foo.*', 'noop')\n        );\n\n        $this->assertEquals(\n            ['foo' => ['bar' => 'boom'], 'baz' => 'kaboom'],\n            data_set($data, 'foo.bar', 'boom')\n        );\n\n        $this->assertEquals(\n            ['foo' => ['bar' => 'boom'], 'baz' => ['bar' => 'boom']],\n            data_set($data, 'baz.bar', 'boom')\n        );\n\n        $this->assertEquals(\n            ['foo' => ['bar' => 'boom'], 'baz' => ['bar' => ['boom' => ['kaboom' => 'boom']]]],\n            data_set($data, 'baz.bar.boom.kaboom', 'boom')\n        );\n    }\n\n    public function testDataSetWithStar()\n    {\n        $data = ['foo' => 'bar'];\n\n        $this->assertEquals(\n            ['foo' => []],\n            data_set($data, 'foo.*.bar', 'noop')\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => [['baz' => 'original'], []]],\n            data_set($data, 'bar', [['baz' => 'original'], []])\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => [['baz' => 'boom'], ['baz' => 'boom']]],\n            data_set($data, 'bar.*.baz', 'boom')\n        );\n\n        $this->assertEquals(\n            ['foo' => [], 'bar' => ['overwritten', 'overwritten']],\n            data_set($data, 'bar.*', 'overwritten')\n        );\n    }\n\n    public function testDataSetWithDoubleStar()\n    {\n        $data = [\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'First'],\n                        (object) [],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) [],\n                        (object) ['name' => 'Second'],\n                    ],\n                ],\n            ],\n        ];\n\n        data_set($data, 'posts.*.comments.*.name', 'Filled');\n\n        $this->assertEquals([\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'Filled'],\n                        (object) ['name' => 'Filled'],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'Filled'],\n                        (object) ['name' => 'Filled'],\n                    ],\n                ],\n            ],\n        ], $data);\n    }\n\n    public function testDataRemove()\n    {\n        $data = ['foo' => 'bar', 'hello' => 'world'];\n\n        $this->assertEquals(\n            ['hello' => 'world'],\n            data_forget($data, 'foo')\n        );\n\n        $data = ['foo' => 'bar', 'hello' => 'world'];\n\n        $this->assertEquals(\n            ['foo' => 'bar', 'hello' => 'world'],\n            data_forget($data, 'nothing')\n        );\n\n        $data = ['one' => ['two' => ['three' => 'hello', 'four' => ['five']]]];\n\n        $this->assertEquals(\n            ['one' => ['two' => ['four' => ['five']]]],\n            data_forget($data, 'one.two.three')\n        );\n    }\n\n    public function testDataRemoveWithStar()\n    {\n        $data = [\n            'article' => [\n                'title' => 'Foo',\n                'comments' => [\n                    ['comment' => 'foo', 'name' => 'First'],\n                    ['comment' => 'bar', 'name' => 'Second'],\n                ],\n            ],\n        ];\n\n        $this->assertEquals(\n            [\n                'article' => [\n                    'title' => 'Foo',\n                    'comments' => [\n                        ['comment' => 'foo'],\n                        ['comment' => 'bar'],\n                    ],\n                ],\n            ],\n            data_forget($data, 'article.comments.*.name')\n        );\n    }\n\n    public function testDataRemoveWithDoubleStar()\n    {\n        $data = [\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'First', 'comment' => 'foo'],\n                        (object) ['name' => 'Second', 'comment' => 'bar'],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) ['name' => 'Third', 'comment' => 'hello'],\n                        (object) ['name' => 'Fourth', 'comment' => 'world'],\n                    ],\n                ],\n            ],\n        ];\n\n        data_forget($data, 'posts.*.comments.*.name');\n\n        $this->assertEquals([\n            'posts' => [\n                (object) [\n                    'comments' => [\n                        (object) ['comment' => 'foo'],\n                        (object) ['comment' => 'bar'],\n                    ],\n                ],\n                (object) [\n                    'comments' => [\n                        (object) ['comment' => 'hello'],\n                        (object) ['comment' => 'world'],\n                    ],\n                ],\n            ],\n        ], $data);\n    }\n\n    public function testHead()\n    {\n        $array = ['a', 'b', 'c'];\n        $this->assertSame('a', head($array));\n    }\n\n    public function testLast()\n    {\n        $array = ['a', 'b', 'c'];\n        $this->assertSame('c', last($array));\n    }\n\n    public function testClassUsesRecursiveShouldReturnTraitsOnParentClasses()\n    {\n        $this->assertSame(\n            [\n                SupportTestTraitTwo::class => SupportTestTraitTwo::class,\n                SupportTestTraitOne::class => SupportTestTraitOne::class,\n            ],\n            class_uses_recursive(SupportTestClassTwo::class)\n        );\n    }\n\n    public function testClassUsesRecursiveAcceptsObject()\n    {\n        $this->assertSame(\n            [\n                SupportTestTraitTwo::class => SupportTestTraitTwo::class,\n                SupportTestTraitOne::class => SupportTestTraitOne::class,\n            ],\n            class_uses_recursive(new SupportTestClassTwo)\n        );\n    }\n\n    public function testClassUsesRecursiveReturnParentTraitsFirst()\n    {\n        $this->assertSame(\n            [\n                SupportTestTraitTwo::class => SupportTestTraitTwo::class,\n                SupportTestTraitOne::class => SupportTestTraitOne::class,\n                SupportTestTraitThree::class => SupportTestTraitThree::class,\n            ],\n            class_uses_recursive(SupportTestClassThree::class)\n        );\n    }\n\n    public function testTraitUsesRecursive()\n    {\n        $this->assertSame(\n            [\n                'Illuminate\\Tests\\Support\\SupportTestTraitTwo' => 'Illuminate\\Tests\\Support\\SupportTestTraitTwo',\n                'Illuminate\\Tests\\Support\\SupportTestTraitOne' => 'Illuminate\\Tests\\Support\\SupportTestTraitOne',\n            ],\n            trait_uses_recursive(SupportTestClassOne::class)\n        );\n\n        $this->assertSame([], trait_uses_recursive(SupportTestClassTwo::class));\n    }\n\n    public function testStr()\n    {\n        $stringable = str('string-value');\n\n        $this->assertInstanceOf(Stringable::class, $stringable);\n        $this->assertSame('string-value', (string) $stringable);\n\n        $stringable = str($name = null);\n        $this->assertInstanceOf(Stringable::class, $stringable);\n        $this->assertTrue($stringable->isEmpty());\n\n        $strAccessor = str();\n        $this->assertTrue((new ReflectionClass($strAccessor))->isAnonymous());\n        $this->assertSame($strAccessor->limit('string-value', 3), 'str...');\n\n        $strAccessor = str();\n        $this->assertTrue((new ReflectionClass($strAccessor))->isAnonymous());\n        $this->assertSame((string) $strAccessor, '');\n    }\n\n    public function testTap()\n    {\n        $object = (object) ['id' => 1];\n        $this->assertEquals(2, tap($object, function ($object) {\n            $object->id = 2;\n        })->id);\n\n        $mock = m::mock();\n        $mock->shouldReceive('foo')->once()->andReturn('bar');\n        $this->assertEquals($mock, tap($mock)->foo());\n    }\n\n    public function testThrow()\n    {\n        $this->expectException(LogicException::class);\n\n        throw_if(true, new LogicException);\n    }\n\n    public function testThrowDefaultException()\n    {\n        $this->expectException(RuntimeException::class);\n\n        throw_if(true);\n    }\n\n    public function testThrowExceptionWithMessage()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('test');\n\n        throw_if(true, 'test');\n    }\n\n    public function testThrowExceptionAsStringWithMessage()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('test');\n\n        throw_if(true, LogicException::class, 'test');\n    }\n\n    public function testThrowClosureException()\n    {\n        $this->expectException(\\Exception::class);\n        $this->expectExceptionMessage('test');\n\n        throw_if(true, fn () => new \\Exception('test'));\n    }\n\n    public function testThrowClosureWithParamsException()\n    {\n        $this->expectException(\\Exception::class);\n        $this->expectExceptionMessage('test');\n\n        throw_if(true, fn (string $message) => new \\Exception($message), 'test');\n    }\n\n    public function testThrowClosureStringWithParamsException()\n    {\n        $this->expectException(\\Exception::class);\n        $this->expectExceptionMessage('test');\n\n        throw_if(true, fn () => \\Exception::class, 'test');\n    }\n\n    public function testThrowUnless()\n    {\n        $this->expectException(LogicException::class);\n\n        throw_unless(false, new LogicException);\n    }\n\n    public function testThrowUnlessDefaultException()\n    {\n        $this->expectException(RuntimeException::class);\n\n        throw_unless(false);\n    }\n\n    public function testThrowUnlessExceptionWithMessage()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('test');\n\n        throw_unless(false, 'test');\n    }\n\n    public function testThrowUnlessExceptionAsStringWithMessage()\n    {\n        $this->expectException(LogicException::class);\n        $this->expectExceptionMessage('test');\n\n        throw_unless(false, LogicException::class, 'test');\n    }\n\n    public function testThrowReturnIfNotThrown()\n    {\n        $this->assertSame('foo', throw_unless('foo', new RuntimeException));\n    }\n\n    public function testThrowWithString()\n    {\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('Test Message');\n\n        throw_if(true, RuntimeException::class, 'Test Message');\n    }\n\n    public function testOptional()\n    {\n        $this->assertNull(optional(null)->something());\n\n        $this->assertEquals(10, optional(new class\n        {\n            public function something()\n            {\n                return 10;\n            }\n        })->something());\n    }\n\n    public function testOptionalWithCallback()\n    {\n        $this->assertNull(optional(null, function () {\n            throw new RuntimeException(\n                'The optional callback should not be called for null'\n            );\n        }));\n\n        $this->assertEquals(10, optional(5, function ($number) {\n            return $number * 2;\n        }));\n    }\n\n    public function testOptionalWithArray()\n    {\n        $this->assertSame('here', optional(['present' => 'here'])['present']);\n        $this->assertNull(optional(null)['missing']);\n        $this->assertNull(optional(['present' => 'here'])->missing);\n    }\n\n    public function testOptionalReturnsObjectPropertyOrNull()\n    {\n        $this->assertSame('bar', optional((object) ['foo' => 'bar'])->foo);\n        $this->assertNull(optional(['foo' => 'bar'])->foo);\n        $this->assertNull(optional((object) ['foo' => 'bar'])->bar);\n    }\n\n    public function testOptionalDeterminesWhetherKeyIsSet()\n    {\n        $this->assertTrue(isset(optional(['foo' => 'bar'])['foo']));\n        $this->assertFalse(isset(optional(['foo' => 'bar'])['bar']));\n        $this->assertFalse(isset(optional()['bar']));\n    }\n\n    public function testOptionalAllowsToSetKey()\n    {\n        $optional = optional([]);\n        $optional['foo'] = 'bar';\n        $this->assertSame('bar', $optional['foo']);\n\n        $optional = optional(null);\n        $optional['foo'] = 'bar';\n        $this->assertFalse(isset($optional['foo']));\n    }\n\n    public function testOptionalAllowToUnsetKey()\n    {\n        $optional = optional(['foo' => 'bar']);\n        $this->assertTrue(isset($optional['foo']));\n        unset($optional['foo']);\n        $this->assertFalse(isset($optional['foo']));\n\n        $optional = optional((object) ['foo' => 'bar']);\n        $this->assertFalse(isset($optional['foo']));\n        $optional['foo'] = 'bar';\n        $this->assertFalse(isset($optional['foo']));\n    }\n\n    public function testOptionalIsMacroable()\n    {\n        Optional::macro('present', function () {\n            if (is_object($this->value)) {\n                return $this->value->present();\n            }\n\n            return new Optional(null);\n        });\n\n        $this->assertNull(optional(null)->present()->something());\n\n        $this->assertSame('$10.00', optional(new class\n        {\n            public function present()\n            {\n                return new class\n                {\n                    public function something()\n                    {\n                        return '$10.00';\n                    }\n                };\n            }\n        })->present()->something());\n    }\n\n    public function testRetry()\n    {\n        Sleep::fake();\n\n        $attempts = retry(2, function ($attempts) {\n            if ($attempts > 1) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        }, 100);\n\n        // Make sure we made two attempts\n        $this->assertEquals(2, $attempts);\n\n        // Make sure we waited 100ms for the first attempt\n        Sleep::assertSleptTimes(1);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n        ]);\n    }\n\n    public function testRetryWithCarbonIntervalSleep()\n    {\n        Sleep::fake();\n\n        $attempts = retry(2, function ($attempts) {\n            if ($attempts > 1) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        }, CarbonInterval::milliseconds(100));\n\n        // Make sure we made two attempts\n        $this->assertEquals(2, $attempts);\n\n        // Make sure we waited 100ms for the first attempt\n        Sleep::assertSleptTimes(1);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n        ]);\n    }\n\n    public function testRetryWithPassingSleepCallback()\n    {\n        Sleep::fake();\n\n        $attempts = retry(3, function ($attempts) {\n            if ($attempts > 2) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        }, function ($attempt, $exception) {\n            $this->assertInstanceOf(RuntimeException::class, $exception);\n\n            return $attempt * 100;\n        });\n\n        // Make sure we made three attempts\n        $this->assertEquals(3, $attempts);\n\n        // Make sure we waited 300ms for the first two attempts\n        Sleep::assertSleptTimes(2);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n            Sleep::usleep(200_000),\n        ]);\n    }\n\n    public function testRetryWithPassingWhenCallback()\n    {\n        Sleep::fake();\n\n        $attempts = retry(2, function ($attempts) {\n            if ($attempts > 1) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        }, 100, function ($ex) {\n            return true;\n        });\n\n        // Make sure we made two attempts\n        $this->assertEquals(2, $attempts);\n\n        // Make sure we waited 100ms for the first attempt\n        Sleep::assertSleptTimes(1);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n        ]);\n    }\n\n    public function testRetryWithFailingWhenCallback()\n    {\n        $this->expectException(RuntimeException::class);\n\n        retry(2, function ($attempts) {\n            if ($attempts > 1) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        }, 100, function ($ex) {\n            return false;\n        });\n    }\n\n    public function testRetryWithBackoff()\n    {\n        Sleep::fake();\n\n        $attempts = retry([50, 100, 200], function ($attempts) {\n            if ($attempts > 3) {\n                return $attempts;\n            }\n\n            throw new RuntimeException;\n        });\n\n        // Make sure we made four attempts\n        $this->assertEquals(4, $attempts);\n\n        Sleep::assertSleptTimes(3);\n\n        Sleep::assertSequence([\n            Sleep::usleep(50_000),\n            Sleep::usleep(100_000),\n            Sleep::usleep(200_000),\n        ]);\n    }\n\n    public function testRetryWithAThrowableBase()\n    {\n        Sleep::fake();\n\n        $attempts = retry(2, function ($attempts) {\n            if ($attempts > 1) {\n                return $attempts;\n            }\n\n            throw new Error('This is an error');\n        }, 100);\n\n        // Make sure we made two attempts\n        $this->assertEquals(2, $attempts);\n\n        // Make sure we waited 100ms for the first attempt\n        Sleep::assertSleptTimes(1);\n\n        Sleep::assertSequence([\n            Sleep::usleep(100_000),\n        ]);\n    }\n\n    public function testTransform()\n    {\n        $this->assertEquals(10, transform(5, function ($value) {\n            return $value * 2;\n        }));\n\n        $this->assertNull(transform(null, function () {\n            return 10;\n        }));\n    }\n\n    public function testTransformDefaultWhenBlank()\n    {\n        $this->assertSame('baz', transform(null, function () {\n            return 'bar';\n        }, 'baz'));\n\n        $this->assertSame('baz', transform('', function () {\n            return 'bar';\n        }, function () {\n            return 'baz';\n        }));\n    }\n\n    public function testWith()\n    {\n        $this->assertEquals(10, with(10));\n\n        $this->assertEquals(10, with(5, function ($five) {\n            return $five + 5;\n        }));\n    }\n\n    public function testAppendConfig()\n    {\n        $this->assertSame([10000 => 'name', 10001 => 'family'], append_config([1 => 'name', 2 => 'family']));\n        $this->assertSame([10000 => 'name', 10001 => 'family'], append_config(['name', 'family']));\n\n        $array = ['name' => 'Taylor', 'family' => 'Otwell'];\n        $this->assertSame($array, append_config($array));\n    }\n\n    public function testEnv()\n    {\n        $_SERVER['foo'] = 'bar';\n        $this->assertSame('bar', env('foo'));\n        $this->assertSame('bar', Env::get('foo'));\n    }\n\n    public function testEnvTrue()\n    {\n        $_SERVER['foo'] = 'true';\n        $this->assertTrue(env('foo'));\n\n        $_SERVER['foo'] = '(true)';\n        $this->assertTrue(env('foo'));\n    }\n\n    public function testEnvFalse()\n    {\n        $_SERVER['foo'] = 'false';\n        $this->assertFalse(env('foo'));\n\n        $_SERVER['foo'] = '(false)';\n        $this->assertFalse(env('foo'));\n    }\n\n    public function testEnvEmpty()\n    {\n        $_SERVER['foo'] = '';\n        $this->assertSame('', env('foo'));\n\n        $_SERVER['foo'] = 'empty';\n        $this->assertSame('', env('foo'));\n\n        $_SERVER['foo'] = '(empty)';\n        $this->assertSame('', env('foo'));\n    }\n\n    public function testEnvNull()\n    {\n        $_SERVER['foo'] = 'null';\n        $this->assertNull(env('foo'));\n\n        $_SERVER['foo'] = '(null)';\n        $this->assertNull(env('foo'));\n    }\n\n    public function testEnvDefault()\n    {\n        $_SERVER['foo'] = 'bar';\n        $this->assertSame('bar', env('foo', 'default'));\n\n        $_SERVER['foo'] = '';\n        $this->assertSame('', env('foo', 'default'));\n\n        unset($_SERVER['foo']);\n        $this->assertSame('default', env('foo', 'default'));\n\n        $_SERVER['foo'] = null;\n        $this->assertSame('default', env('foo', 'default'));\n    }\n\n    public function testEnvEscapedString()\n    {\n        $_SERVER['foo'] = '\"null\"';\n        $this->assertSame('null', env('foo'));\n\n        $_SERVER['foo'] = \"'null'\";\n        $this->assertSame('null', env('foo'));\n\n        $_SERVER['foo'] = 'x\"null\"x'; // this should not be unquoted\n        $this->assertSame('x\"null\"x', env('foo'));\n    }\n\n    public function testWriteArrayOfEnvVariablesToFile()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariables([\n            'APP_VIBE' => 'chill',\n            'DB_HOST' => '127:0:0:1',\n            'DB_PORT' => 3306,\n            'BRAND_NEW_PREFIX' => 'fresh value',\n        ], $path);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=chill',\n                '',\n                'DB_CONNECTION=mysql',\n                'DB_HOST=\"127:0:0:1\"',\n                'DB_PORT=3306',\n                '',\n                'BRAND_NEW_PREFIX=\"fresh value\"',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWriteArrayOfEnvVariablesToFileAndOverwrite()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariables([\n            'APP_VIBE' => 'chill',\n            'DB_HOST' => '127:0:0:1',\n            'DB_CONNECTION' => 'sqlite',\n        ], $path, true);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=chill',\n                '',\n                'DB_CONNECTION=sqlite',\n                'DB_HOST=\"127:0:0:1\"',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWillNotOverwriteArrayOfVariables()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            'APP_VIBE=odd',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariables([\n            'APP_VIBE' => 'chill',\n            'DB_HOST' => '127:0:0:1',\n        ], $path);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=odd',\n                '',\n                'DB_CONNECTION=mysql',\n                'DB_HOST=\"127:0:0:1\"',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWriteVariableToFile()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariable('APP_VIBE', 'chill', $path);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=chill',\n                '',\n                'DB_CONNECTION=mysql',\n                'DB_HOST=',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWillNotOverwriteVariable()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            'APP_VIBE=odd',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariable('APP_VIBE', 'chill', $path);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=odd',\n                '',\n                'DB_CONNECTION=mysql',\n                'DB_HOST=',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWriteVariableToFileAndOverwrite()\n    {\n        $filesystem = new Filesystem;\n        $path = __DIR__.'/tmp/env-test-file';\n        $filesystem->put($path, implode(PHP_EOL, [\n            'APP_NAME=Laravel',\n            'APP_ENV=local',\n            'APP_KEY=base64:randomkey',\n            'APP_DEBUG=true',\n            'APP_URL=http://localhost',\n            'APP_VIBE=odd',\n            '',\n            'DB_CONNECTION=mysql',\n            'DB_HOST=',\n        ]));\n\n        Env::writeVariable('APP_VIBE', 'chill', $path, true);\n\n        $this->assertSame(\n            implode(PHP_EOL, [\n                'APP_NAME=Laravel',\n                'APP_ENV=local',\n                'APP_KEY=base64:randomkey',\n                'APP_DEBUG=true',\n                'APP_URL=http://localhost',\n                'APP_VIBE=chill',\n                '',\n                'DB_CONNECTION=mysql',\n                'DB_HOST=',\n            ]),\n            $filesystem->get($path)\n        );\n    }\n\n    public function testWillThrowAnExceptionIfFileIsMissingWhenTryingToWriteVariables(): void\n    {\n        $this->expectExceptionObject(new RuntimeException('The file [missing-file] does not exist.'));\n\n        Env::writeVariables([\n            'APP_VIBE' => 'chill',\n            'DB_HOST' => '127:0:0:1',\n        ], 'missing-file');\n    }\n\n    public function testGetFromSERVERFirst()\n    {\n        $_ENV['foo'] = 'From $_ENV';\n        $_SERVER['foo'] = 'From $_SERVER';\n        $this->assertSame('From $_SERVER', env('foo'));\n    }\n\n    public function testRequiredEnvVariableThrowsAnExceptionWhenNotFound(): void\n    {\n        $this->expectExceptionObject(new RuntimeException('[required-does-not-exist] has no value'));\n\n        Env::getOrFail('required-does-not-exist');\n    }\n\n    public function testRequiredEnvReturnsValue(): void\n    {\n        $_SERVER['required-exists'] = 'some-value';\n        $this->assertSame('some-value', Env::getOrFail('required-exists'));\n    }\n\n    public function testLiteral(): void\n    {\n        $this->assertEquals(1, literal(1));\n        $this->assertEquals('taylor', literal('taylor'));\n        $this->assertEquals((object) ['name' => 'Taylor', 'role' => 'Developer'], literal(name: 'Taylor', role: 'Developer'));\n    }\n\n    public static function providesPregReplaceArrayData()\n    {\n        $pointerArray = ['Taylor', 'Otwell'];\n\n        next($pointerArray);\n\n        return [\n            ['/:[a-z_]+/', ['8:30', '9:00'], 'The event will take place between :start and :end', 'The event will take place between 8:30 and 9:00'],\n            ['/%s/', ['Taylor'], 'Hi, %s', 'Hi, Taylor'],\n            ['/%s/', ['Taylor', 'Otwell'], 'Hi, %s %s', 'Hi, Taylor Otwell'],\n            ['/%s/', [], 'Hi, %s %s', 'Hi,  '],\n            ['/%s/', ['a', 'b', 'c'], 'Hi', 'Hi'],\n            ['//', [], '', ''],\n            ['/%s/', ['a'], '', ''],\n            // non-sequential numeric keys → should still consume in natural order\n            ['/%s/', [2 => 'A', 10 => 'B'], '%s %s', 'A B'],\n            // associative keys → order should be insertion order, not keys/pointer\n            ['/%s/', ['first' => 'A', 'second' => 'B'], '%s %s', 'A B'],\n            // values that are \"falsy\" but must not be treated as empty by mistake, false->'' , null->''\n            ['/%s/', ['0', 0, false, null], '%s|%s|%s|%s', '0|0||'],\n            // The internal pointer of this array is not at the beginning\n            ['/%s/', $pointerArray, 'Hi, %s %s', 'Hi, Taylor Otwell'],\n        ];\n    }\n\n    #[DataProvider('providesPregReplaceArrayData')]\n    public function testPregReplaceArray($pattern, $replacements, $subject, $expectedOutput)\n    {\n        $this->assertSame(\n            $expectedOutput,\n            preg_replace_array($pattern, $replacements, $subject)\n        );\n    }\n\n    public function testLazy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, function (SupportLazyClass $instance) {\n            $instance->__construct('foo', 'bar');\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyCanAcceptShortClosure(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn (SupportLazyClass $instance) => $instance->__construct('foo', 'bar'));\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyThrowsExceptionWhenConstructorIsNotCalled()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $instance = lazy(SupportLazyClass::class, function (SupportLazyClass $instance) {\n            //\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Typed property Illuminate\\Tests\\Support\\SupportLazyClass::$first must not be accessed before initialization');\n\n        $instance->first;\n    }\n\n    public function testLazyCanAcceptHashForProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn (SupportLazyClass $instance) => [\n            'second' => 'bar',\n            'first' => 'foo',\n        ]);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyCanAcceptListForProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn (SupportLazyClass $instance) => ['foo', 'bar']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyCanAcceptSingleValueForConstructor(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClassWithArrayParameter::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClassWithArrayParameter::class, fn (SupportLazyClassWithArrayParameter $instance) => [['foo']]);\n\n        $this->assertFalse(SupportLazyClassWithArrayParameter::$constructorCalled);\n        $this->assertSame(['foo'], $instance->first);\n        $this->assertTrue(SupportLazyClassWithArrayParameter::$constructorCalled);\n\n        SupportLazyClassWithArrayParameter::$constructorCalled = false;\n    }\n\n    public function testLazySupportsPositionAndNamedArguments(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn (SupportLazyClass $instance) => ['foo', 'second' => 'bar']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyThrowsWhenPositionalArgumentsComeAfterNamedArguments(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn (SupportLazyClass $instance) => ['second' => 'bar', 'foo']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Cannot use positional argument after named argument during unpacking');\n\n        $instance->first;\n    }\n\n    public function testLazyCanReturnInitializedObject(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, function (SupportLazyClass $instance) {\n            $instance->__construct('foo');\n\n            return $instance;\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertNull($instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testLazyMustInitilizeObject(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, function (SupportLazyClass $instance) {\n            return new SupportLazyClass('foo');\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Typed property Illuminate\\Tests\\Support\\SupportLazyClass::$first must not be accessed before initialization');\n\n        $instance->first;\n    }\n\n    public function testLazyCanEagerlySetProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(SupportLazyClass::class, fn () => ['foo', 'bar'], eager: ['eager' => 'baz']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('baz', $instance->eager);\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('baz', $instance->eager);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(function (SupportLazyClass $instance) {\n            $instance->__construct('foo', 'bar');\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazyCanAcceptShortClosure(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClass $instance) => $instance->__construct('foo', 'bar'));\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazyThrowsExceptionWhenConstructorIsNotCalled()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $instance = lazy(function (SupportLazyClass $instance) {\n            //\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Typed property Illuminate\\Tests\\Support\\SupportLazyClass::$first must not be accessed before initialization');\n\n        $instance->first;\n    }\n\n    public function testClosureOnlyLazyThrowsWhenNotClassSpecifiedInClosure()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('The first parameter of the given Closure is missing a type hint.');\n\n        lazy(function ($instance) {\n            //\n        });\n    }\n\n    public function testClosureOnlyLazyCanAcceptHashForProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClass $instance) => [\n            'second' => 'bar',\n            'first' => 'foo',\n        ]);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazyCanAcceptListForProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClass $instance) => ['foo', 'bar']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClousureOnlyLazyCanAcceptSingleValueForConstructor(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClassWithArrayParameter::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClassWithArrayParameter $instance) => [['foo']]);\n\n        $this->assertFalse(SupportLazyClassWithArrayParameter::$constructorCalled);\n        $this->assertSame(['foo'], $instance->first);\n        $this->assertTrue(SupportLazyClassWithArrayParameter::$constructorCalled);\n\n        SupportLazyClassWithArrayParameter::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazySupportsPositionAndNamedArguments(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClass $instance) => ['foo', 'second' => 'bar']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazyThrowsWhenPositionalArgumentsComeAfterNamedArguments(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(fn (SupportLazyClass $instance) => ['second' => 'bar', 'foo']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Cannot use positional argument after named argument during unpacking');\n\n        $instance->first;\n    }\n\n    public function testClosureOnlyLazyCanReturnInitializedObject(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(function (SupportLazyClass $instance) {\n            $instance->__construct('foo');\n\n            return $instance;\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertNull($instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyLazyMustInitilizeObject(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = lazy(function (SupportLazyClass $instance) {\n            return new SupportLazyClass('foo');\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Typed property Illuminate\\Tests\\Support\\SupportLazyClass::$first must not be accessed before initialization');\n\n        $instance->first;\n    }\n\n    public function testProxy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(SupportLazyClass::class, fn (SupportLazyClass $proxy) => $factory());\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testProxyCanEagerlySetProperties(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(SupportLazyClass::class, fn () => $factory(), eager: ['eager' => 'baz']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('baz', $instance->eager);\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertFalse(isset($instance->eager));\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testProxyCanEagerlySetPropertiesAndThenAlsoSetThemOnActualObject(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(SupportLazyClass::class, function ($proxy, $eager) use ($factory) {\n            $instance = $factory();\n\n            foreach ($eager as $prop => $value) {\n                $instance->{$prop} = $value;\n            }\n\n            return $instance;\n        }, eager: ['eager' => 'baz']);\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('baz', $instance->eager);\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('baz', $instance->eager);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testProxyCanAcceptShortClosure(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(SupportLazyClass::class, fn (SupportLazyClass $proxy) => $factory());\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testProxyThrowsExceptionWhenObjectIsNotReturned()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $instance = proxy(SupportLazyClass::class, function (SupportLazyClass $proxy) {\n            //\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Lazy proxy factory must return an instance of a class compatible with Illuminate\\Tests\\Support\\SupportLazyClass, null returned');\n\n        $instance->first;\n    }\n\n    public function testProxyMustNotInitilizeProxy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = proxy(SupportLazyClass::class, function (SupportLazyClass $proxy) {\n            $proxy->__construct('foo');\n\n            return $proxy;\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Lazy proxy factory must return a non-lazy object');\n\n        $instance->first;\n    }\n\n    public function testClosureOnlyProxy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(function (SupportLazyClass $proxy) use ($factory) {\n            return $factory();\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyProxyCanAcceptShortClosure(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(fn (SupportLazyClass $proxy) => $factory());\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n\n    public function testClosureOnlyProxyThrowsExceptionWhenObjectIsNotReturned()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $instance = proxy(function (SupportLazyClass $proxy) {\n            //\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Lazy proxy factory must return an instance of a class compatible with Illuminate\\Tests\\Support\\SupportLazyClass, null returned');\n\n        $instance->first;\n    }\n\n    public function testClosureOnlyProxyThrowsWhenNotClassSpecifiedInClosure()\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('The first parameter of the given Closure is missing a type hint.');\n\n        proxy(function ($proxy) {\n            //\n        });\n    }\n\n    public function testClosureOnlyProxyMustNotInitilizeProxy(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n\n        $instance = proxy(function (SupportLazyClass $proxy) {\n            $proxy->__construct('foo');\n\n            return $proxy;\n        });\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->expectException(Error::class);\n        $this->expectExceptionMessage('Lazy proxy factory must return a non-lazy object');\n\n        $instance->first;\n    }\n\n    public function testProxyCanUseClosureReturnTypeForClassDetection(): void\n    {\n        if (version_compare(phpversion(), '8.4.0', '<')) {\n            $this->markTestSkipped();\n        }\n\n        SupportLazyClass::$constructorCalled = false;\n        $factory = fn () => new SupportLazyClass('foo', 'bar');\n\n        $instance = proxy(fn (): SupportLazyClass => $factory());\n\n        $this->assertFalse(SupportLazyClass::$constructorCalled);\n        $this->assertSame('foo', $instance->first);\n        $this->assertTrue(SupportLazyClass::$constructorCalled);\n        $this->assertSame('bar', $instance->second);\n\n        SupportLazyClass::$constructorCalled = false;\n    }\n}\n\ntrait SupportTestTraitOne\n{\n    //\n}\n\ntrait SupportTestTraitTwo\n{\n    use SupportTestTraitOne;\n}\n\nclass SupportTestClassOne\n{\n    use SupportTestTraitTwo;\n}\n\nclass SupportTestClassTwo extends SupportTestClassOne\n{\n    //\n}\n\ntrait SupportTestTraitThree\n{\n    //\n}\n\nclass SupportTestClassThree extends SupportTestClassTwo\n{\n    use SupportTestTraitThree;\n}\n\ntrait SupportTestTraitArrayAccess\n{\n    public function __construct(protected array $items = [])\n    {\n    }\n\n    public function offsetExists($offset): bool\n    {\n        return array_key_exists($offset ?? '', $this->items);\n    }\n\n    public function offsetGet($offset): mixed\n    {\n        return $this->items[$offset];\n    }\n\n    public function offsetSet($offset, $value): void\n    {\n        $this->items[$offset] = $value;\n    }\n\n    public function offsetUnset($offset): void\n    {\n        unset($this->items[$offset]);\n    }\n}\n\ntrait SupportTestTraitArrayIterable\n{\n    public function __construct(protected array $items = [])\n    {\n    }\n\n    public function getIterator(): Traversable\n    {\n        return new ArrayIterator($this->items);\n    }\n}\n\nclass SupportTestArrayAccess implements ArrayAccess\n{\n    use SupportTestTraitArrayAccess;\n}\n\nclass SupportTestArrayIterable implements IteratorAggregate\n{\n    use SupportTestTraitArrayIterable;\n}\n\nclass SupportTestArrayAccessIterable implements ArrayAccess, IteratorAggregate\n{\n    use SupportTestTraitArrayAccess, SupportTestTraitArrayIterable {\n        SupportTestTraitArrayAccess::__construct insteadof SupportTestTraitArrayIterable;\n    }\n}\n\nclass SupportTestCountable implements Countable\n{\n    public function count(): int\n    {\n        return 0;\n    }\n}\n\nclass SupportLazyClass\n{\n    public static bool $constructorCalled = false;\n\n    public string $eager;\n\n    public function __construct(\n        public string $first,\n        public ?string $second = null,\n    ) {\n        self::$constructorCalled = true;\n    }\n}\n\nclass SupportLazyClassWithArrayParameter\n{\n    public static bool $constructorCalled = false;\n\n    public function __construct(\n        public array $first,\n    ) {\n        self::$constructorCalled = true;\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportHtmlStringTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\HtmlString;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportHtmlStringTest extends TestCase\n{\n    public function testToHtml(): void\n    {\n        // Check if HtmlString correctly converts a basic HTML string\n        $str = '<h1>foo</h1>';\n        $html = new HtmlString('<h1>foo</h1>');\n        $this->assertEquals($str, $html->toHtml());\n\n        // Check if HtmlString correctly preserves leading blank spaces in the HTML string\n        $startWithBlankSpaces = '   <h1>      foo</h1>';\n        $html = new HtmlString('   <h1>      foo</h1>');\n        $this->assertEquals($startWithBlankSpaces, $html->toHtml());\n\n        // Check if HtmlString correctly preserves trailing blank spaces in the HTML string\n        $endsWithBlankSpaces = '<h1>foo       </h1>   ';\n        $html = new HtmlString('<h1>foo       </h1>   ');\n        $this->assertEquals($endsWithBlankSpaces, $html->toHtml());\n\n        // Check if HtmlString correctly handles an empty string\n        $emptyHtml = new HtmlString('');\n        $this->assertEquals('', $emptyHtml->toHtml());\n\n        // Check if HtmlString correctly converts a plain text string\n        $str = 'foo bar';\n        $html = new HtmlString($str);\n        $this->assertEquals($str, $html->toHtml());\n    }\n\n    public function testToString()\n    {\n        $str = '<h1>foo</h1>';\n        $html = new HtmlString('<h1>foo</h1>');\n        $this->assertEquals($str, (string) $html);\n\n        // Check if HtmlString gracefully handles a null value\n        $html = new HtmlString(null);\n        $this->assertIsString((string) $html);\n    }\n\n    public function testIsEmpty(): void\n    {\n        // Check if HtmlString correctly identifies an empty string as empty\n        $this->assertTrue((new HtmlString(''))->isEmpty());\n\n        // Check if HtmlString identifies a null value as empty\n        $this->assertTrue((new HtmlString(null))->isEmpty());\n\n        // HtmlString with whitespace should not be considered as empty\n        $this->assertFalse((new HtmlString('   '))->isEmpty());\n\n        // HtmlString with content should not be considered as empty\n        $this->assertFalse((new HtmlString('<p>Hello</p>'))->isEmpty());\n    }\n\n    public function testIsNotEmpty()\n    {\n        $this->assertTrue((new HtmlString('foo'))->isNotEmpty());\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportJsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\nuse Illuminate\\Contracts\\Support\\Htmlable;\nuse Illuminate\\Contracts\\Support\\Jsonable;\nuse Illuminate\\Support\\Js;\nuse Illuminate\\Tests\\Support\\Fixtures\\IntBackedEnum;\nuse Illuminate\\Tests\\Support\\Fixtures\\StringBackedEnum;\nuse JsonSerializable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportJsTest extends TestCase\n{\n    public function testScalars()\n    {\n        $this->assertSame('false', (string) Js::from(false));\n        $this->assertSame('true', (string) Js::from(true));\n        $this->assertSame('1', (string) Js::from(1));\n        $this->assertSame('1.1', (string) Js::from(1.1));\n        $this->assertSame('[]', (string) Js::from([]));\n        $this->assertSame('[]', (string) Js::from(collect()));\n        $this->assertSame('null', (string) Js::from(null));\n        $this->assertSame(\"'Hello world'\", (string) Js::from('Hello world'));\n        $this->assertSame(\"'Hèlló world'\", (string) Js::from('Hèlló world'));\n        $this->assertEquals(\n            \"'\\\\u003Cdiv class=\\\\u0022foo\\\\u0022\\\\u003E\\\\u0027quoted html\\\\u0027\\\\u003C\\\\/div\\\\u003E'\",\n            (string) Js::from('<div class=\"foo\">\\'quoted html\\'</div>')\n        );\n    }\n\n    public function testArrays()\n    {\n        $this->assertEquals(\n            \"JSON.parse('[\\\\u0022hello\\\\u0022,\\\\u0022world\\\\u0022]')\",\n            (string) Js::from(['hello', 'world'])\n        );\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from(['foo' => 'hello', 'bar' => 'world'])\n        );\n    }\n\n    public function testObjects()\n    {\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from((object) ['foo' => 'hello', 'bar' => 'world'])\n        );\n    }\n\n    public function testJsonSerializable()\n    {\n        // JsonSerializable should take precedence over Arrayable, so we'll\n        // implement both and make sure the correct data is used.\n        $data = new class() implements JsonSerializable, Arrayable\n        {\n            public $foo = 'not hello';\n\n            public $bar = 'not world';\n\n            public function jsonSerialize(): mixed\n            {\n                return ['foo' => 'hello', 'bar' => 'world'];\n            }\n\n            public function toArray()\n            {\n                return ['foo' => 'not hello', 'bar' => 'not world'];\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n    }\n\n    public function testJsonable()\n    {\n        // Jsonable should take precedence over JsonSerializable and Arrayable, so we'll\n        // implement all three and make sure the correct data is used.\n        $data = new class() implements Jsonable, JsonSerializable, Arrayable\n        {\n            public $foo = 'not hello';\n\n            public $bar = 'not world';\n\n            public function toJson($options = 0)\n            {\n                return json_encode(['foo' => 'hello', 'bar' => 'world'], $options);\n            }\n\n            public function jsonSerialize(): mixed\n            {\n                return ['foo' => 'not hello', 'bar' => 'not world'];\n            }\n\n            public function toArray()\n            {\n                return ['foo' => 'not hello', 'bar' => 'not world'];\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n    }\n\n    public function testArrayable()\n    {\n        $data = new class() implements Arrayable\n        {\n            public $foo = 'not hello';\n\n            public $bar = 'not world';\n\n            public function toArray()\n            {\n                return ['foo' => 'hello', 'bar' => 'world'];\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n    }\n\n    public function testHtmlable()\n    {\n        $data = new class implements Htmlable\n        {\n            public function toHtml()\n            {\n                return '<p>Hello, World!</p>';\n            }\n        };\n\n        $this->assertEquals(\"'\\u003Cp\\u003EHello, World!\\u003C\\/p\\u003E'\", (string) Js::from($data));\n\n        $data = new class implements Htmlable, Arrayable\n        {\n            public function toHtml()\n            {\n                return '<p>Hello, World!</p>';\n            }\n\n            public function toArray()\n            {\n                return ['foo' => 'hello', 'bar' => 'world'];\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n\n        $data = new class implements Htmlable, Jsonable\n        {\n            public function toHtml()\n            {\n                return '<p>Hello, World!</p>';\n            }\n\n            public function toJson($options = 0)\n            {\n                return json_encode(['foo' => 'hello', 'bar' => 'world'], $options);\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n\n        $data = new class implements Htmlable, JsonSerializable\n        {\n            public function toHtml()\n            {\n                return '<p>Hello, World!</p>';\n            }\n\n            public function jsonSerialize(): mixed\n            {\n                return ['foo' => 'hello', 'bar' => 'world'];\n            }\n        };\n\n        $this->assertEquals(\n            \"JSON.parse('{\\\\u0022foo\\\\u0022:\\\\u0022hello\\\\u0022,\\\\u0022bar\\\\u0022:\\\\u0022world\\\\u0022}')\",\n            (string) Js::from($data)\n        );\n    }\n\n    public function testBackedEnums()\n    {\n        $this->assertSame('2', (string) Js::from(IntBackedEnum::TWO));\n        $this->assertSame(\"'Hello world'\", (string) Js::from(StringBackedEnum::HELLO_WORLD));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportLazyCollectionIsLazyTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Exception;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\ItemNotFoundException;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\MultipleItemsFoundException;\nuse Illuminate\\Support\\Sleep;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass SupportLazyCollectionIsLazyTest extends TestCase\n{\n    use Concerns\\CountsEnumerations;\n\n    public function testMakeWithClosureIsLazy()\n    {\n        [$closure, $recorder] = $this->makeGeneratorFunctionWithRecorder();\n\n        LazyCollection::make($closure);\n\n        $this->assertEquals([], $recorder->all());\n    }\n\n    public function testMakeWithLazyCollectionIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            LazyCollection::make($collection);\n        });\n    }\n\n    public function testEagerEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection = $collection->eager();\n\n            $collection->count();\n            $collection->all();\n        });\n    }\n\n    public function testChunkIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->chunk(3);\n        });\n\n        $this->assertEnumerates(15, function ($collection) {\n            $collection->chunk(5)->take(3)->all();\n        });\n    }\n\n    public function testChunkWhileIsLazy()\n    {\n        $collection = LazyCollection::make(['A', 'A', 'B', 'B', 'C', 'C', 'C']);\n\n        $this->assertDoesNotEnumerateCollection($collection, function ($collection) {\n            $collection->chunkWhile(function ($current, $key, $chunk) {\n                return $current === $chunk->last();\n            });\n        });\n\n        $this->assertEnumeratesCollection($collection, 3, function ($collection) {\n            $collection->chunkWhile(function ($current, $key, $chunk) {\n                return $current === $chunk->last();\n            })->first();\n        });\n\n        $this->assertEnumeratesCollectionOnce($collection, function ($collection) {\n            $collection->chunkWhile(function ($current, $key, $chunk) {\n                return $current === $chunk->last();\n            })->all();\n        });\n    }\n\n    public function testCollapseIsLazy()\n    {\n        $collection = LazyCollection::make([\n            [1, 2, 3],\n            [4, 5, 6],\n            [7, 8, 9],\n        ]);\n\n        $this->assertDoesNotEnumerateCollection($collection, function ($collection) {\n            $collection->collapse();\n        });\n\n        $this->assertEnumeratesCollection($collection, 1, function ($collection) {\n            $collection->collapse()->take(3)->all();\n        });\n    }\n\n    public function testCombineIsLazy()\n    {\n        $firstEnumerations = 0;\n        $secondEnumerations = 0;\n        $first = $this->countEnumerations($this->make([1, 2]), $firstEnumerations);\n        $second = $this->countEnumerations($this->make([1, 2]), $secondEnumerations);\n\n        $first->combine($second);\n\n        $this->assertEnumerations(0, $firstEnumerations);\n        $this->assertEnumerations(0, $secondEnumerations);\n\n        $first->combine($second)->take(1)->all();\n\n        $this->assertEnumerations(1, $firstEnumerations);\n        $this->assertEnumerations(1, $secondEnumerations);\n    }\n\n    public function testConcatIsLazy()\n    {\n        $firstEnumerations = 0;\n        $secondEnumerations = 0;\n        $first = $this->countEnumerations($this->make([1, 2]), $firstEnumerations);\n        $second = $this->countEnumerations($this->make([1, 2]), $secondEnumerations);\n\n        $first->concat($second);\n\n        $this->assertEnumerations(0, $firstEnumerations);\n        $this->assertEnumerations(0, $secondEnumerations);\n\n        $first->concat($second)->take(2)->all();\n\n        $this->assertEnumerations(2, $firstEnumerations);\n        $this->assertEnumerations(0, $secondEnumerations);\n\n        $firstEnumerations = 0;\n        $secondEnumerations = 0;\n\n        $first->concat($second)->take(3)->all();\n\n        $this->assertEnumerations(2, $firstEnumerations);\n        $this->assertEnumerations(1, $secondEnumerations);\n    }\n\n    public function testMultiplyIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->multiply(2);\n        });\n\n        $this->assertEnumeratesCollectionOnce(\n            $this->make([1, 2, 3]),\n            function ($collection) {\n                return $collection->multiply(3)->all();\n            }\n        );\n    }\n\n    public function testContainsIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->contains(5);\n        });\n    }\n\n    public function testDoesntContainIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->doesntContain(5);\n        });\n    }\n\n    public function testContainsStrictIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->containsStrict(5);\n        });\n    }\n\n    public function testCountEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->count();\n        });\n    }\n\n    public function testCountByIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->countBy();\n        });\n\n        $this->assertEnumeratesCollectionOnce(\n            $this->make([1, 2, 2, 3]),\n            function ($collection) {\n                $collection->countBy()->all();\n            }\n        );\n    }\n\n    public function testCrossJoinIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->crossJoin([1]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->crossJoin([1], [2])->all();\n        });\n    }\n\n    public function testDiffIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diff([1, 2]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diff([1, 2])->all();\n        });\n    }\n\n    public function testDiffAssocIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diffAssoc([1, 2]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diffAssoc([1, 2])->all();\n        });\n    }\n\n    public function testDiffAssocUsingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diffAssocUsing([1, 2], 'strcasecmp');\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diffAssocUsing([1, 2], 'strcasecmp')->all();\n        });\n    }\n\n    public function testDiffKeysIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diffKeys([1, 2]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diffKeys([1, 2])->all();\n        });\n    }\n\n    public function testDiffKeysUsingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diffKeysUsing([1, 2], 'strcasecmp');\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diffKeysUsing([1, 2], 'strcasecmp')->all();\n        });\n    }\n\n    public function testDiffUsingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->diffUsing([1, 2], 'strcasecmp');\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->diffUsing([1, 2], 'strcasecmp')->all();\n        });\n    }\n\n    public function testDuplicatesIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->duplicates();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->duplicates()->all();\n        });\n    }\n\n    public function testDuplicatesStrictIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->duplicatesStrict();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->duplicatesStrict()->all();\n        });\n    }\n\n    public function testEachIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->each(function ($value, $key) {\n                if ($value == 5) {\n                    return false;\n                }\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->each(function ($value, $key) {\n                // Silence is golden!\n            });\n        });\n\n        $this->assertEnumerates(5, function ($collection) {\n            foreach ($collection as $key => $value) {\n                if ($value == 5) {\n                    return false;\n                }\n            }\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            foreach ($collection as $key => $value) {\n                // Silence is golden!\n            }\n        });\n    }\n\n    public function testEachSpreadIsLazy()\n    {\n        $data = $this->make([[1, 2], [3, 4], [5, 6], [7, 8]]);\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->eachSpread(function ($first, $second, $key) {\n                if ($first == 3) {\n                    return false;\n                }\n            });\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->eachSpread(function ($first, $second, $key) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testEveryIsLazy()\n    {\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->every(function ($value) {\n                return $value == 1;\n            });\n        });\n\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3]]);\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->every('a', 1);\n        });\n    }\n\n    public function testExceptIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->except([1, 2]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->except([1, 2])->all();\n        });\n    }\n\n    public function testFilterIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->filter(function ($value) {\n                return $value > 5;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->filter(function ($value) {\n                return $value > 5;\n            })->all();\n        });\n    }\n\n    public function testFirstIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->first();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->first(function ($value) {\n                return $value == 2;\n            });\n        });\n    }\n\n    public function testFirstWhereIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3]]);\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->firstWhere('a', 2);\n        });\n    }\n\n    public function testFlatMapIsLazy()\n    {\n        $data = $this->make([1, 2, 3, 4, 5]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->flatMap(function ($values) {\n                return array_sum($values);\n            });\n        });\n\n        $this->assertEnumeratesCollection($data, 3, function ($collection) {\n            $collection->flatMap(function ($value) {\n                return range(1, $value);\n            })->take(5)->all();\n        });\n    }\n\n    public function testFlattenIsLazy()\n    {\n        $data = $this->make([1, [2, 3], [4, 5], [6, 7]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->flatten();\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->flatten()->take(3)->all();\n        });\n    }\n\n    public function testFlipIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->flip();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->flip()->take(2)->all();\n        });\n    }\n\n    public function testForPageIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->forPage(2, 10);\n        });\n\n        $this->assertEnumerates(20, function ($collection) {\n            $collection->forPage(2, 10)->all();\n        });\n    }\n\n    public function testGetIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->get(4);\n        });\n    }\n\n    public function testGroupByIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->groupBy(function ($value) {\n                return $value % 5;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->groupBy(function ($value) {\n                return $value % 5;\n            })->all();\n        });\n    }\n\n    public function testHasIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->has(4);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->has('non-existent');\n        });\n    }\n\n    public function testHasAnyIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->hasAny(4);\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->hasAny([1, 4]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->hasAny(['non', 'existent']);\n        });\n    }\n\n    public function testImplodeEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->implode(', ');\n        });\n    }\n\n    public function testIntersectIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->intersect([1, 2, 3]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->intersect([1, 2, 3])->all();\n        });\n    }\n\n    public function testIntersectUsingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->intersectUsing([1, 2], 'strcasecmp');\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->intersectUsing([1, 2], 'strcasecmp')->all();\n        });\n    }\n\n    public function testIntersectAssocIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->intersectAssoc([1, 2]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->intersectAssoc([1, 2])->all();\n        });\n    }\n\n    public function testIntersectAssocUsingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->intersectAssocUsing([1, 2], 'strcasecmp');\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->intersectAssocUsing([1, 2], 'strcasecmp')->all();\n        });\n    }\n\n    public function testIntersectByKeysIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->intersectByKeys([1, 2, 3]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->intersectByKeys([1, 2, 3])->all();\n        });\n    }\n\n    public function testIsEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->isEmpty();\n        });\n    }\n\n    public function testIsNotEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->isNotEmpty();\n        });\n    }\n\n    public function testContainsOneItemIsLazy()\n    {\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->containsOneItem();\n        });\n    }\n\n    public function testHasSoleIsLazy()\n    {\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->hasSole();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->hasSole(fn ($item) => $item <= 2);\n        });\n\n        $this->assertEnumeratesCollection(\n            LazyCollection::times(10, fn ($i) => ['age' => $i]),\n            2,\n            fn ($collection) => $collection->hasSole('age', '<=', 2),\n        );\n    }\n\n    public function testHasManyIsLazy()\n    {\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->hasMany();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->hasMany(fn ($item) => $item <= 2);\n        });\n\n        $this->assertEnumeratesCollection(\n            LazyCollection::times(10, fn ($i) => ['age' => $i]),\n            2,\n            fn ($collection) => $collection->hasMany('age', '<=', 2),\n        );\n    }\n\n    public function testJoinIsLazy()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->join(', ', ' and ');\n        });\n    }\n\n    public function testJsonSerializeEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->jsonSerialize();\n        });\n    }\n\n    public function testKeyByIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->keyBy(function ($value) {\n                return \"key-of-{$value}\";\n            });\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->keyBy(function ($value) {\n                return \"key-of-{$value}\";\n            })->take(2)->all();\n        });\n    }\n\n    public function testKeysIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->keys();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->keys()->take(2)->all();\n        });\n    }\n\n    public function testLastEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->last();\n        });\n    }\n\n    public function testMapIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->map(function ($value) {\n                return $value + 1;\n            });\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->map(function ($value) {\n                return $value + 1;\n            })->take(2)->all();\n        });\n    }\n\n    public function testMapIntoIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->mapInto(stdClass::class);\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->mapInto(stdClass::class)->take(2)->all();\n        });\n    }\n\n    public function testMapSpreadIsLazy()\n    {\n        $data = $this->make([[1, 2], [3, 4], [5, 6], [7, 8]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->mapSpread(function ($first, $second, $key) {\n                return $first + $second + $key;\n            });\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->mapSpread(function ($first, $second, $key) {\n                return $first + $second + $key;\n            })->take(2)->all();\n        });\n    }\n\n    public function testMapToDictionaryIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->mapToDictionary(function ($value, $key) {\n                return [$value => $key];\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->mapToDictionary(function ($value, $key) {\n                return [$value => $key];\n            })->all();\n        });\n    }\n\n    public function testMapToGroupsIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->mapToGroups(function ($value, $key) {\n                return [$value => $key];\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->mapToGroups(function ($value, $key) {\n                return [$value => $key];\n            })->all();\n        });\n    }\n\n    public function testMapWithKeysIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->mapWithKeys(function ($value, $key) {\n                return [$value => $key];\n            });\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->mapWithKeys(function ($value, $key) {\n                return [$value => $key];\n            })->take(2)->all();\n        });\n    }\n\n    public function testMaxEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->max();\n        });\n    }\n\n    public function testMedianEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->median();\n        });\n    }\n\n    public function testAvgEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->avg();\n        });\n    }\n\n    public function testMergeIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->merge([1, 2, 3]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->merge([1, 2, 3])->all();\n        });\n    }\n\n    public function testMergeRecursiveIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->mergeRecursive([1, 2, 3]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->mergeRecursive([1, 2, 3])->all();\n        });\n    }\n\n    public function testMinEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->min();\n        });\n    }\n\n    public function testModeEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->mode();\n        });\n    }\n\n    public function testNthIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->nth(5);\n        });\n\n        $this->assertEnumerates(11, function ($collection) {\n            $collection->nth(5)->take(3)->all();\n        });\n    }\n\n    public function testOnlyIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->only(5, 6, 7);\n        });\n\n        $this->assertEnumerates(8, function ($collection) {\n            $collection->only(5, 6, 7)->all();\n        });\n    }\n\n    public function testPadIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->pad(200, null);\n            $collection->pad(-200, null);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->pad(20, null)->all();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->pad(-20, null)->all();\n        });\n    }\n\n    public function testPartitionEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->partition(function ($value) {\n                return $value > 10;\n            });\n        });\n    }\n\n    public function testPipeDoesNotEnumerate()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->pipe(function () {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testPluckIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->pluck('a');\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->pluck('a')->all();\n        });\n    }\n\n    public function testRandomEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->random();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->random(5);\n        });\n    }\n\n    public function testRangeIsLazy()\n    {\n        $data = LazyCollection::range(10, 1000);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->take(50);\n        });\n\n        $this->assertEnumeratesCollection($data, 5, function ($collection) {\n            $collection->take(5)->all();\n        });\n    }\n\n    public function testReduceIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $this->rescue(function () use ($collection) {\n                $collection->reduce(function ($total, $value) {\n                    throw new Exception('Short-circuit');\n                }, 0);\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->reduce(function ($total, $value) {\n                return $total + $value;\n            }, 0);\n        });\n    }\n\n    public function testReduceSpreadIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $this->rescue(function () use ($collection) {\n                $collection->reduceSpread(function ($one, $two, $value) {\n                    throw new Exception('Short-circuit');\n                }, 0, 0);\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->reduceSpread(function ($total, $max, $value) {\n                return [$total + $value, max($max, $value)];\n            }, 0, 0);\n        });\n    }\n\n    public function testRejectIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->reject(function ($value) {\n                return $value % 2;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->reject(function ($value) {\n                return $value % 2;\n            })->all();\n        });\n    }\n\n    public function testRememberIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->remember();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection = $collection->remember();\n\n            $collection->all();\n            $collection->all();\n        });\n\n        $this->assertEnumerates(5, function ($collection) {\n            $collection = $collection->remember();\n\n            $collection->take(5)->all();\n            $collection->take(5)->all();\n        });\n    }\n\n    public function testReplaceIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->replace([5 => 'a', 10 => 'b']);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->replace([5 => 'a', 10 => 'b'])->all();\n        });\n    }\n\n    public function testReplaceRecursiveIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->replaceRecursive([5 => 'a', 10 => 'b']);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->replaceRecursive([5 => 'a', 10 => 'b'])->all();\n        });\n    }\n\n    public function testReverseIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->reverse();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->reverse()->all();\n        });\n    }\n\n    public function testSearchIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->search(5);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->search('missing');\n        });\n    }\n\n    public function testShuffleIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->shuffle();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->shuffle()->all();\n        });\n    }\n\n    public function testSlidingIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sliding();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->sliding()->take(1)->all();\n        });\n\n        $this->assertEnumerates(3, function ($collection) {\n            $collection->sliding()->take(2)->all();\n        });\n\n        $this->assertEnumerates(13, function ($collection) {\n            $collection->sliding(3, 5)->take(3)->all();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sliding()->all();\n        });\n    }\n\n    public function testSkipIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->skip(10);\n        });\n\n        $this->assertEnumerates(12, function ($collection) {\n            $collection->skip(10)->take(2)->all();\n        });\n    }\n\n    public function testSkipUntilIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->skipUntil(INF);\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->skipUntil(10)->first();\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->skipUntil(function ($item) {\n                return $item === 10;\n            })->first();\n        });\n    }\n\n    public function testSkipWhileIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->skipWhile(1);\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->skipWhile(1)->first();\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->skipWhile(function ($item) {\n                return $item < 10;\n            })->first();\n        });\n    }\n\n    public function testSliceIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->slice(2);\n            $collection->slice(2, 2);\n            $collection->slice(-2, 2);\n        });\n\n        $this->assertEnumerates(4, function ($collection) {\n            $collection->slice(2)->take(2)->all();\n        });\n\n        $this->assertEnumerates(4, function ($collection) {\n            $collection->slice(2, 2)->all();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->slice(-2, 2)->all();\n        });\n    }\n\n    public function testFindFirstOrFailIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->firstOrFail();\n        });\n\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->firstOrFail(function ($item) {\n                return $item === 1;\n            });\n        });\n\n        $this->assertEnumerates(100, function ($collection) {\n            try {\n                $collection->firstOrFail(function ($item) {\n                    return $item === 101;\n                });\n            } catch (ItemNotFoundException) {\n                //\n            }\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->firstOrFail(function ($item) {\n                return $item % 2 === 0;\n            });\n        });\n    }\n\n    public function testSomeIsLazy()\n    {\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->some(function ($value) {\n                return $value == 5;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->some(function ($value) {\n                return false;\n            });\n        });\n    }\n\n    public function testSoleIsLazy()\n    {\n        $this->assertEnumerates(2, function ($collection) {\n            try {\n                $collection->sole();\n            } catch (MultipleItemsFoundException) {\n                //\n            }\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sole(function ($item) {\n                return $item === 1;\n            });\n        });\n\n        $this->assertEnumerates(4, function ($collection) {\n            try {\n                $collection->sole(function ($item) {\n                    return $item % 2 === 0;\n                });\n            } catch (MultipleItemsFoundException) {\n                //\n            }\n        });\n    }\n\n    public function testSortIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sort();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sort()->all();\n        });\n    }\n\n    public function testSortDescIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sortDesc();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sortDesc()->all();\n        });\n    }\n\n    public function testSortByIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sortBy(function ($value) {\n                return $value;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sortBy(function ($value) {\n                return $value;\n            })->all();\n        });\n    }\n\n    public function testSortByDescIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sortByDesc(function ($value) {\n                return $value;\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sortByDesc(function ($value) {\n                return $value;\n            })->all();\n        });\n    }\n\n    public function testSortKeysIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sortKeys();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sortKeys()->all();\n        });\n    }\n\n    public function testSortKeysDescIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->sortKeysDesc();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sortKeysDesc()->all();\n        });\n    }\n\n    public function testSplitIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->split(4);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->split(4)->all();\n        });\n    }\n\n    public function testSumEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->sum();\n        });\n    }\n\n    public function testTakeIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->take(10);\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->take(10)->all();\n        });\n    }\n\n    public function testTakeUntilIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->takeUntil(INF);\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->takeUntil(10)->all();\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->takeUntil(function ($item) {\n                return $item === 10;\n            })->all();\n        });\n    }\n\n    public function testTakeUntilTimeoutIsLazy()\n    {\n        tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) {\n            $this->assertDoesNotEnumerateCollection($mock, function ($mock) {\n                $timeout = Carbon::now();\n\n                $results = $mock\n                    ->tap(function ($collection) use ($mock, $timeout) {\n                        tap($collection)\n                            ->mockery_init($mock->mockery_getContainer())\n                            ->shouldAllowMockingProtectedMethods()\n                            ->shouldReceive('now')\n                            ->times(1)\n                            ->andReturn(\n                                $timeout->getTimestamp()\n                            );\n                    })\n                    ->takeUntilTimeout($timeout)\n                    ->all();\n            });\n        });\n\n        tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) {\n            $this->assertEnumeratesCollection($mock, 1, function ($mock) {\n                $timeout = Carbon::now();\n\n                $results = $mock\n                    ->tap(function ($collection) use ($mock, $timeout) {\n                        tap($collection)\n                            ->mockery_init($mock->mockery_getContainer())\n                            ->shouldAllowMockingProtectedMethods()\n                            ->shouldReceive('now')\n                            ->times(2)\n                            ->andReturn(\n                                (clone $timeout)->sub(1, 'minute')->getTimestamp(),\n                                $timeout->getTimestamp()\n                            );\n                    })\n                    ->takeUntilTimeout($timeout)\n                    ->all();\n            });\n        });\n\n        tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) {\n            $this->assertEnumeratesCollectionOnce($mock, function ($mock) {\n                $timeout = Carbon::now();\n\n                $results = $mock\n                    ->tap(function ($collection) use ($mock, $timeout) {\n                        tap($collection)\n                            ->mockery_init($mock->mockery_getContainer())\n                            ->shouldAllowMockingProtectedMethods()\n                            ->shouldReceive('now')\n                            ->times(100)\n                            ->andReturn(\n                                (clone $timeout)->sub(1, 'minute')->getTimestamp()\n                            );\n                    })\n                    ->takeUntilTimeout($timeout)\n                    ->all();\n            });\n        });\n    }\n\n    public function testTakeWhileIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->takeWhile(0);\n        });\n\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->takeWhile(0)->all();\n        });\n\n        $this->assertEnumerates(10, function ($collection) {\n            $collection->takeWhile(function ($item) {\n                return $item < 10;\n            })->all();\n        });\n    }\n\n    public function testTapDoesNotEnumerate()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->tap(function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testTapEachIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->tapEach(function ($value) {\n                // Silence is golden!\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->tapEach(function ($value) {\n                // Silence is golden!\n            })->all();\n        });\n    }\n\n    public function testThrottleIsLazy()\n    {\n        Sleep::fake();\n\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->throttle(10);\n        });\n\n        $this->assertEnumerates(5, function ($collection) {\n            $collection->throttle(10)->take(5)->all();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->throttle(10)->all();\n        });\n\n        Sleep::fake(false);\n    }\n\n    public function testTimesIsLazy()\n    {\n        $data = LazyCollection::times(INF);\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->take(2)->all();\n        });\n    }\n\n    public function testToArrayEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->toArray();\n        });\n    }\n\n    public function testToJsonEnumeratesOnce()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->toJson();\n        });\n    }\n\n    public function testUnionIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->union([4, 5, 6]);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->union([4, 5, 6])->all();\n        });\n    }\n\n    public function testUniqueIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->unique();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->unique()->all();\n        });\n    }\n\n    public function testUniqueStrictIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->uniqueStrict();\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->uniqueStrict()->all();\n        });\n    }\n\n    public function testUnlessDoesNotEnumerate()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->unless(true, function ($collection) {\n                // Silence is golden!\n            });\n\n            $collection->unless(false, function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testUnlessEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->unlessEmpty(function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testUnlessNotEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->unlessNotEmpty(function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testUnwrapEnumeratesOne()\n    {\n        $this->assertEnumeratesOnce(function ($collection) {\n            LazyCollection::unwrap($collection);\n        });\n    }\n\n    public function testValuesIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->values();\n        });\n\n        $this->assertEnumerates(2, function ($collection) {\n            $collection->values()->take(2)->all();\n        });\n    }\n\n    public function testWhenDoesNotEnumerate()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->when(true, function ($collection) {\n                // Silence is golden!\n            });\n\n            $collection->when(false, function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testWhenEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->whenEmpty(function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testWhenNotEmptyIsLazy()\n    {\n        $this->assertEnumerates(1, function ($collection) {\n            $collection->whenNotEmpty(function ($collection) {\n                // Silence is golden!\n            });\n        });\n    }\n\n    public function testWhereIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->where('a', '<', 3);\n        });\n\n        $this->assertEnumeratesCollection($data, 1, function ($collection) {\n            $collection->where('a', '<', 3)->take(1)->all();\n        });\n    }\n\n    public function testWhereBetweenIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereBetween('a', [2, 4]);\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->whereBetween('a', [2, 4])->take(1)->all();\n        });\n    }\n\n    public function testWhereInIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereIn('a', [2, 3]);\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->whereIn('a', [2, 3])->take(1)->all();\n        });\n    }\n\n    public function testWhereInstanceOfIsLazy()\n    {\n        $data = $this->make(['a' => 0])->concat(\n            $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]])\n                ->mapInto(stdClass::class)\n        );\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereInstanceOf(stdClass::class);\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->whereInstanceOf(stdClass::class)->take(1)->all();\n        });\n    }\n\n    public function testWhereInStrictIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereInStrict('a', ['2', 3]);\n        });\n\n        $this->assertEnumeratesCollection($data, 3, function ($collection) {\n            $collection->whereInStrict('a', ['2', 3])->take(1)->all();\n        });\n    }\n\n    public function testWhereNotBetweenIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNotBetween('a', [1, 2]);\n        });\n\n        $this->assertEnumeratesCollection($data, 3, function ($collection) {\n            $collection->whereNotBetween('a', [1, 2])->take(1)->all();\n        });\n    }\n\n    public function testWhereNotInIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNotIn('a', [1, 2]);\n        });\n\n        $this->assertEnumeratesCollection($data, 3, function ($collection) {\n            $collection->whereNotIn('a', [1, 2])->take(1)->all();\n        });\n    }\n\n    public function testWhereNotInStrictIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNotInStrict('a', ['1', 2]);\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->whereNotInStrict('a', [1, '2'])->take(1)->all();\n        });\n    }\n\n    public function testWhereNotNullIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => null], ['a' => 2], ['a' => 3]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNotNull('a');\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->whereNotNull('a')->all();\n        });\n\n        $data = $this->make([1, null, 2, null, 3]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNotNull();\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->whereNotNull()->all();\n        });\n    }\n\n    public function testWhereNullIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => null], ['a' => 2], ['a' => 3]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNull('a');\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->whereNull('a')->all();\n        });\n\n        $data = $this->make([1, null, 2, null, 3]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereNull();\n        });\n\n        $this->assertEnumeratesCollectionOnce($data, function ($collection) {\n            $collection->whereNull()->all();\n        });\n    }\n\n    public function testWhereStrictIsLazy()\n    {\n        $data = $this->make([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]);\n\n        $this->assertDoesNotEnumerateCollection($data, function ($collection) {\n            $collection->whereStrict('a', 2);\n        });\n\n        $this->assertEnumeratesCollection($data, 2, function ($collection) {\n            $collection->whereStrict('a', 2)->take(1)->all();\n        });\n    }\n\n    public function testWithHeartbeatIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            $collection->withHeartbeat(1, function () {\n                // Heartbeat callback\n            });\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            $collection->withHeartbeat(1, function () {\n                // Heartbeat callback\n            })->all();\n        });\n    }\n\n    public function testWrapIsLazy()\n    {\n        $this->assertDoesNotEnumerate(function ($collection) {\n            LazyCollection::wrap($collection);\n        });\n\n        $this->assertEnumeratesOnce(function ($collection) {\n            LazyCollection::wrap($collection)->all();\n        });\n    }\n\n    public function testZipIsLazy()\n    {\n        $firstEnumerations = 0;\n        $secondEnumerations = 0;\n        $first = $this->countEnumerations($this->make([1, 2]), $firstEnumerations);\n        $second = $this->countEnumerations($this->make([1, 2]), $secondEnumerations);\n\n        $first->zip($second);\n\n        $this->assertEnumerations(0, $firstEnumerations);\n        $this->assertEnumerations(0, $secondEnumerations);\n\n        $first->zip($second)->take(1)->all();\n\n        $this->assertEnumerations(1, $firstEnumerations);\n        $this->assertEnumerations(1, $secondEnumerations);\n    }\n\n    protected function make($source)\n    {\n        return new LazyCollection($source);\n    }\n\n    protected function rescue($callback)\n    {\n        try {\n            $callback();\n        } catch (Exception) {\n            // Silence is golden\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportLazyCollectionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Carbon\\CarbonInterval as Duration;\nuse Illuminate\\Foundation\\Testing\\Wormhole;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Illuminate\\Support\\Sleep;\nuse InvalidArgumentException;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportLazyCollectionTest extends TestCase\n{\n    public function testCanCreateEmptyCollection()\n    {\n        $this->assertSame([], LazyCollection::make()->all());\n        $this->assertSame([], LazyCollection::empty()->all());\n    }\n\n    public function testCanCreateCollectionFromArray()\n    {\n        $array = [1, 2, 3];\n\n        $data = LazyCollection::make($array);\n\n        $this->assertSame($array, $data->all());\n\n        $array = ['a' => 1, 'b' => 2, 'c' => 3];\n\n        $data = LazyCollection::make($array);\n\n        $this->assertSame($array, $data->all());\n    }\n\n    public function testCanCreateCollectionFromArrayable()\n    {\n        $array = [1, 2, 3];\n\n        $data = LazyCollection::make(Collection::make($array));\n\n        $this->assertSame($array, $data->all());\n\n        $array = ['a' => 1, 'b' => 2, 'c' => 3];\n\n        $data = LazyCollection::make(Collection::make($array));\n\n        $this->assertSame($array, $data->all());\n    }\n\n    public function testCanCreateCollectionFromGeneratorFunction()\n    {\n        $data = LazyCollection::make(function () {\n            yield 1;\n            yield 2;\n            yield 3;\n        });\n\n        $this->assertSame([1, 2, 3], $data->all());\n\n        $data = LazyCollection::make(function () {\n            yield 'a' => 1;\n            yield 'b' => 2;\n            yield 'c' => 3;\n        });\n\n        $this->assertSame([\n            'a' => 1,\n            'b' => 2,\n            'c' => 3,\n        ], $data->all());\n    }\n\n    public function testCanCreateCollectionFromNonGeneratorFunction()\n    {\n        $data = LazyCollection::make(function () {\n            return 'laravel';\n        });\n\n        $this->assertSame(['laravel'], $data->all());\n    }\n\n    public function testDoesNotCreateCollectionFromGenerator()\n    {\n        $this->expectException(InvalidArgumentException::class);\n\n        $generateNumber = function () {\n            yield 1;\n        };\n\n        LazyCollection::make($generateNumber());\n    }\n\n    public function testEager()\n    {\n        $source = [1, 2, 3, 4, 5];\n\n        $data = LazyCollection::make(function () use (&$source) {\n            yield from $source;\n        })->eager();\n\n        $source[] = 6;\n\n        $this->assertSame([1, 2, 3, 4, 5], $data->all());\n    }\n\n    public function testRemember()\n    {\n        $source = [1, 2, 3, 4];\n\n        $collection = LazyCollection::make(function () use (&$source) {\n            yield from $source;\n        })->remember();\n\n        $this->assertSame([1, 2, 3, 4], $collection->all());\n\n        $source = [];\n\n        $this->assertSame([1, 2, 3, 4], $collection->all());\n    }\n\n    public function testRememberWithTwoRunners()\n    {\n        $source = [1, 2, 3, 4];\n\n        $collection = LazyCollection::make(function () use (&$source) {\n            yield from $source;\n        })->remember();\n\n        $a = $collection->getIterator();\n        $b = $collection->getIterator();\n\n        $this->assertEquals(1, $a->current());\n        $this->assertEquals(1, $b->current());\n\n        $b->next();\n\n        $this->assertEquals(1, $a->current());\n        $this->assertEquals(2, $b->current());\n\n        $b->next();\n\n        $this->assertEquals(1, $a->current());\n        $this->assertEquals(3, $b->current());\n\n        $a->next();\n\n        $this->assertEquals(2, $a->current());\n        $this->assertEquals(3, $b->current());\n\n        $a->next();\n\n        $this->assertEquals(3, $a->current());\n        $this->assertEquals(3, $b->current());\n\n        $a->next();\n\n        $this->assertEquals(4, $a->current());\n        $this->assertEquals(3, $b->current());\n\n        $b->next();\n\n        $this->assertEquals(4, $a->current());\n        $this->assertEquals(4, $b->current());\n    }\n\n    public function testRememberWithDuplicateKeys()\n    {\n        $collection = LazyCollection::make(function () {\n            yield 'key' => 1;\n            yield 'key' => 2;\n        })->remember();\n\n        $results = $collection->map(function ($value, $key) {\n            return [$key, $value];\n        })->values()->all();\n\n        $this->assertSame([['key', 1], ['key', 2]], $results);\n    }\n\n    public function testTakeUntilTimeout()\n    {\n        $timeout = Carbon::now();\n\n        $mock = m::mock(LazyCollection::class.'[now]');\n\n        $timedOutWith = [];\n\n        $results = $mock\n            ->times(10)\n            ->tap(function ($collection) use ($mock, $timeout) {\n                tap($collection)\n                    ->mockery_init($mock->mockery_getContainer())\n                    ->shouldAllowMockingProtectedMethods()\n                    ->shouldReceive('now')\n                    ->times(3)\n                    ->andReturn(\n                        (clone $timeout)->sub(2, 'minute')->getTimestamp(),\n                        (clone $timeout)->sub(1, 'minute')->getTimestamp(),\n                        $timeout->getTimestamp()\n                    );\n            })\n            ->takeUntilTimeout($timeout, function ($value, $key) use (&$timedOutWith) {\n                $timedOutWith = [$value, $key];\n            })\n            ->all();\n\n        $this->assertSame([1, 2], $results);\n        $this->assertSame([2, 1], $timedOutWith);\n    }\n\n    public function testTapEach()\n    {\n        $data = LazyCollection::times(10);\n\n        $tapped = [];\n\n        $data = $data->tapEach(function ($value, $key) use (&$tapped) {\n            $tapped[$key] = $value;\n        });\n\n        $this->assertEmpty($tapped);\n\n        $data = $data->take(5)->all();\n\n        $this->assertSame([1, 2, 3, 4, 5], $data);\n        $this->assertSame([1, 2, 3, 4, 5], $tapped);\n    }\n\n    public function testThrottle()\n    {\n        Sleep::fake();\n\n        $data = LazyCollection::times(3)\n            ->throttle(2)\n            ->all();\n\n        Sleep::assertSlept(function (Duration $duration) {\n            $this->assertEqualsWithDelta(\n                2_000_000, $duration->totalMicroseconds, 1_000\n            );\n\n            return true;\n        }, times: 3);\n\n        $this->assertSame([1, 2, 3], $data);\n\n        Sleep::fake(false);\n    }\n\n    public function testThrottleAccountsForTimePassed()\n    {\n        Sleep::fake();\n        Carbon::setTestNow(Carbon::now());\n\n        $data = LazyCollection::times(3)\n            ->throttle(3)\n            ->tapEach(function ($value, $index) {\n                if ($index == 1) {\n                    // Travel in time...\n                    (new Wormhole(1))->second();\n                }\n            })\n            ->all();\n\n        Sleep::assertSlept(function (Duration $duration, int $index) {\n            $expectation = $index == 1 ? 2_000_000 : 3_000_000;\n\n            $this->assertEqualsWithDelta(\n                $expectation, $duration->totalMicroseconds, 1_000\n            );\n\n            return true;\n        }, times: 3);\n\n        $this->assertSame([1, 2, 3], $data);\n\n        Sleep::fake(false);\n        Carbon::setTestNow();\n    }\n\n    public function testUniqueDoubleEnumeration()\n    {\n        $data = LazyCollection::times(2)->unique();\n\n        $data->all();\n\n        $this->assertSame([1, 2], $data->all());\n    }\n\n    public function testAfter()\n    {\n        $data = new LazyCollection([1, '2', 3, 4]);\n\n        // Test finding item after value with non-strict comparison\n        $result = $data->after(1);\n        $this->assertSame('2', $result);\n\n        // Test with strict comparison\n        $result = $data->after('2', true);\n        $this->assertSame(3, $result);\n\n        $users = new LazyCollection([\n            ['name' => 'Taylor', 'age' => 35],\n            ['name' => 'Jeffrey', 'age' => 45],\n            ['name' => 'Mohamed', 'age' => 35],\n        ]);\n\n        // Test finding item after the one that matches a condition\n        $result = $users->after(function ($user) {\n            return $user['name'] === 'Jeffrey';\n        });\n\n        $this->assertSame(['name' => 'Mohamed', 'age' => 35], $result);\n    }\n\n    public function testBefore()\n    {\n        // Test finding item before value with non-strict comparison\n        $data = new LazyCollection([1, 2, '3', 4]);\n        $result = $data->before(2);\n        $this->assertSame(1, $result);\n\n        // Test finding item before value with strict comparison\n        $result = $data->before(4, true);\n        $this->assertSame('3', $result);\n\n        // Test finding item before the one that matches a callback condition\n        $users = new LazyCollection([\n            ['name' => 'Taylor', 'age' => 35],\n            ['name' => 'Jeffrey', 'age' => 45],\n            ['name' => 'Mohamed', 'age' => 35],\n        ]);\n        $result = $users->before(function ($user) {\n            return $user['name'] === 'Jeffrey';\n        });\n        $this->assertSame(['name' => 'Taylor', 'age' => 35], $result);\n    }\n\n    public function testShuffle()\n    {\n        $data = new LazyCollection([1, 2, 3, 4, 5]);\n        $shuffled = $data->shuffle();\n\n        $this->assertCount(5, $shuffled);\n        $this->assertEquals([1, 2, 3, 4, 5], $shuffled->sort()->values()->all());\n\n        // Test shuffling associative array maintains key-value pairs\n        $users = new LazyCollection([\n            'first' => ['name' => 'Taylor'],\n            'second' => ['name' => 'Jeffrey'],\n        ]);\n        $shuffled = $users->shuffle();\n\n        $this->assertCount(2, $shuffled);\n        $this->assertTrue($shuffled->contains('name', 'Taylor'));\n        $this->assertTrue($shuffled->contains('name', 'Jeffrey'));\n    }\n\n    public function testCollapseWithKeys()\n    {\n        $collection = new LazyCollection([\n            ['a' => 1, 'b' => 2],\n            ['c' => 3, 'd' => 4],\n        ]);\n        $collapsed = $collection->collapseWithKeys();\n\n        $this->assertEquals(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4], $collapsed->all());\n\n        $collection = new LazyCollection([\n            ['a' => 1],\n            new LazyCollection(['b' => 2]),\n        ]);\n        $collapsed = $collection->collapseWithKeys();\n\n        $this->assertEquals(['a' => 1, 'b' => 2], $collapsed->all());\n    }\n\n    public function testContainsOneItem()\n    {\n        $collection = new LazyCollection([5]);\n        $this->assertTrue($collection->containsOneItem());\n\n        $emptyCollection = new LazyCollection([]);\n        $this->assertFalse($emptyCollection->containsOneItem());\n\n        $multipleCollection = new LazyCollection([1, 2, 3]);\n        $this->assertFalse($multipleCollection->containsOneItem());\n    }\n\n    public function testContainsManyItems()\n    {\n        $emptyCollection = new LazyCollection([]);\n        $this->assertFalse($emptyCollection->containsManyItems());\n\n        $singleCollection = new LazyCollection([1]);\n        $this->assertFalse($singleCollection->containsManyItems());\n\n        $multipleCollection = new LazyCollection([1, 2]);\n        $this->assertTrue($multipleCollection->containsManyItems());\n\n        $manyCollection = new LazyCollection([1, 2, 3]);\n        $this->assertTrue($manyCollection->containsManyItems());\n    }\n\n    public function testDoesntContain()\n    {\n        $collection = new LazyCollection([1, 2, 3, 4, 5]);\n\n        $this->assertTrue($collection->doesntContain(10));\n        $this->assertFalse($collection->doesntContain(3));\n        $this->assertTrue($collection->doesntContain('value', '>', 10));\n        $this->assertTrue($collection->doesntContain(function ($value) {\n            return $value > 10;\n        }));\n\n        $users = new LazyCollection([\n            [\n                'name' => 'Taylor',\n                'role' => 'developer',\n            ],\n            [\n                'name' => 'Jeffrey',\n                'role' => 'designer',\n            ],\n        ]);\n\n        $this->assertTrue($users->doesntContain('name', 'Adam'));\n        $this->assertFalse($users->doesntContain('name', 'Taylor'));\n    }\n\n    public function testDot()\n    {\n        $collection = new LazyCollection([\n            'foo' => [\n                'bar' => 'baz',\n            ],\n            'user' => [\n                'name' => 'Taylor',\n                'profile' => [\n                    'age' => 30,\n                ],\n            ],\n            'users' => [\n                0 => [\n                    'name' => 'Taylor',\n                ],\n                1 => [\n                    'name' => 'Jeffrey',\n                ],\n            ],\n        ]);\n\n        $dotted = $collection->dot();\n\n        $expected = [\n            'foo.bar' => 'baz',\n            'user.name' => 'Taylor',\n            'user.profile.age' => 30,\n            'users.0.name' => 'Taylor',\n            'users.1.name' => 'Jeffrey',\n        ];\n\n        $this->assertEquals($expected, $dotted->all());\n    }\n\n    public function testWithHeartbeat()\n    {\n        $start = Carbon::create(2000, 1, 1);\n        $after2Minutes = $start->copy()->addMinutes(2);\n        $after5Minutes = $start->copy()->addMinutes(5);\n        $after7Minutes = $start->copy()->addMinutes(7);\n        $after11Minutes = $start->copy()->addMinutes(11);\n\n        Carbon::setTestNow($start);\n\n        $output = new Collection();\n\n        $numbers = LazyCollection::range(1, 10)\n\n            // Move the clock to possibly trigger the heartbeat...\n            ->tapEach(fn ($number) => Carbon::setTestNow(\n                match ($number) {\n                    3 => $after2Minutes,\n                    4 => $after5Minutes,\n                    6 => $after7Minutes,\n                    9 => $after11Minutes,\n                    default => Carbon::now(),\n                }\n            ))\n\n            // Push the current date to `output` when heartbeat is triggered...\n            ->withHeartbeat(Duration::minutes(5), fn () => $output[] = Carbon::now())\n\n            // Push every number onto `output` as it's enumerated...\n            ->tapEach(fn ($number) => $output[] = $number)->all();\n\n        $this->assertEquals(range(1, 10), $numbers);\n\n        $this->assertEquals(\n            [\n                1, 2, 3,\n                $after5Minutes,\n                4, 5, 6, 7, 8,\n                $after11Minutes,\n                9, 10,\n            ],\n            $output->all(),\n        );\n\n        Carbon::setTestNow();\n    }\n\n    public function testRandomPreservesKeys()\n    {\n        $collection = new LazyCollection([\n            'first' => 1,\n            'second' => 2,\n            'third' => 3,\n        ]);\n\n        $keysWithoutPreserve = array_keys($collection->random(2)->all());\n\n        $this->assertEquals([0, 1], $keysWithoutPreserve);\n\n        $keysWithPreserve = array_keys($collection->random(2, true)->all());\n\n        foreach ($keysWithPreserve as $key) {\n            $this->assertContains($key, ['first', 'second', 'third']);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportMacroableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse BadMethodCallException;\nuse Illuminate\\Support\\Traits\\Macroable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportMacroableTest extends TestCase\n{\n    private $macroable;\n\n    protected function setUp(): void\n    {\n        $this->macroable = $this->createObjectForTrait();\n    }\n\n    private function createObjectForTrait()\n    {\n        return new EmptyMacroable;\n    }\n\n    public function testRegisterMacro()\n    {\n        $macroable = $this->macroable;\n        $macroable::macro(__CLASS__, function () {\n            return 'Taylor';\n        });\n        $this->assertSame('Taylor', $macroable::{__CLASS__}());\n    }\n\n    public function testHasMacro()\n    {\n        $macroable = $this->macroable;\n        $macroable::macro('foo', function () {\n            return 'Taylor';\n        });\n        $this->assertTrue($macroable::hasMacro('foo'));\n        $this->assertFalse($macroable::hasMacro('bar'));\n    }\n\n    public function testRegisterMacroAndCallWithoutStatic()\n    {\n        $macroable = $this->macroable;\n        $macroable::macro(__CLASS__, function () {\n            return 'Taylor';\n        });\n        $this->assertSame('Taylor', $macroable->{__CLASS__}());\n    }\n\n    public function testWhenCallingMacroClosureIsBoundToObject()\n    {\n        TestMacroable::macro('tryInstance', function () {\n            return $this->protectedVariable;\n        });\n        TestMacroable::macro('tryStatic', function () {\n            return static::getProtectedStatic();\n        });\n        $instance = new TestMacroable;\n\n        $result = $instance->tryInstance();\n        $this->assertSame('instance', $result);\n\n        $result = TestMacroable::tryStatic();\n        $this->assertSame('static', $result);\n    }\n\n    public function testClassBasedMacros()\n    {\n        TestMacroable::mixin(new TestMixin);\n        $instance = new TestMacroable;\n        $this->assertSame('instance-Adam', $instance->methodOne('Adam'));\n    }\n\n    public function testClassBasedMacrosNoReplace()\n    {\n        TestMacroable::macro('methodThree', function () {\n            return 'bar';\n        });\n        TestMacroable::mixin(new TestMixin, false);\n        $instance = new TestMacroable;\n        $this->assertSame('bar', $instance->methodThree());\n\n        TestMacroable::mixin(new TestMixin);\n        $this->assertSame('foo', $instance->methodThree());\n    }\n\n    public function testFlushMacros()\n    {\n        TestMacroable::macro('flushMethod', function () {\n            return 'flushMethod';\n        });\n\n        $instance = new TestMacroable;\n\n        $this->assertSame('flushMethod', $instance->flushMethod());\n\n        TestMacroable::flushMacros();\n\n        $this->expectException(BadMethodCallException::class);\n\n        $instance->flushMethod();\n    }\n\n    public function testFlushMacrosStatic()\n    {\n        TestMacroable::macro('flushMethod', function () {\n            return 'flushMethod';\n        });\n\n        $instance = new TestMacroable;\n\n        $this->assertSame('flushMethod', $instance::flushMethod());\n\n        TestMacroable::flushMacros();\n\n        $this->expectException(BadMethodCallException::class);\n\n        $instance::flushMethod();\n    }\n\n    public function testMacroWithArguments()\n    {\n        $this->macroable::macro('concatenate', function ($arg1, $arg2) {\n            return $arg1.' '.$arg2;\n        });\n\n        $result = $this->macroable::concatenate('Hello', 'World');\n        $this->assertSame('Hello World', $result);\n    }\n\n    public function testMacroWithDefaultArguments()\n    {\n        $this->macroable::macro('greet', function ($name = 'Guest') {\n            return 'Hello, '.$name;\n        });\n\n        $this->assertSame('Hello, Guest', $this->macroable::greet());\n        $this->assertSame('Hello, Saleh', $this->macroable::greet('Saleh'));\n    }\n\n    public function testCallingUndefinedMacroThrowsException()\n    {\n        $this->expectException(BadMethodCallException::class);\n\n        $this->macroable::nonExistentMacro();\n    }\n\n    public function testMethodConflictDoesNotThrowException()\n    {\n        $this->macroable::macro('existingMethod', function () {\n            return 'oldMethod';\n        });\n\n        // Replacing existing macro.\n        $this->macroable::macro('existingMethod', function () {\n            return 'newMethod';\n        });\n\n        $this->assertSame('newMethod', $this->macroable::existingMethod());\n    }\n}\n\nclass EmptyMacroable\n{\n    use Macroable;\n}\n\nclass TestMacroable\n{\n    use Macroable;\n\n    protected $protectedVariable = 'instance';\n\n    protected static function getProtectedStatic()\n    {\n        return 'static';\n    }\n}\n\nclass TestMixin\n{\n    public function methodOne()\n    {\n        return function ($value) {\n            return $this->methodTwo($value);\n        };\n    }\n\n    protected function methodTwo()\n    {\n        return function ($value) {\n            return $this->protectedVariable.'-'.$value;\n        };\n    }\n\n    protected function methodThree()\n    {\n        return function () {\n            return 'foo';\n        };\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportMailTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Support\\Facades\\Mail;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SupportMailTest extends TestCase\n{\n    public function testItRegisterAndCallMacros()\n    {\n        Mail::macro('test', fn (string $str) => $str === 'foo'\n            ? 'it works!'\n            : 'it failed.',\n        );\n\n        $this->assertEquals('it works!', Mail::test('foo'));\n    }\n\n    public function testItRegisterAndCallMacrosWhenFaked()\n    {\n        Mail::macro('test', fn (string $str) => $str === 'foo'\n            ? 'it works!'\n            : 'it failed.',\n        );\n\n        Mail::fake();\n\n        $this->assertEquals('it works!', Mail::test('foo'));\n    }\n\n    public function testEmailSent()\n    {\n        Mail::fake();\n        Mail::assertNothingSent();\n\n        Mail::to('hello@laravel.com')->send(new TestMail());\n\n        Mail::assertSent(TestMail::class);\n    }\n}\n\nclass TestMail extends Mailable\n{\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        return $this->view('view');\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportMaintenanceModeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Foundation\\MaintenanceMode as MaintenanceModeContract;\nuse Illuminate\\Support\\Facades\\MaintenanceMode;\nuse Orchestra\\Testbench\\TestCase;\n\nclass SupportMaintenanceModeTest extends TestCase\n{\n    public function testExtends()\n    {\n        MaintenanceMode::extend('test', fn () => new TestMaintenanceMode);\n\n        $this->app->config->set('app.maintenance.driver', 'test');\n\n        $this->assertInstanceOf(TestMaintenanceMode::class, $this->app->maintenanceMode());\n    }\n}\n\nclass TestMaintenanceMode implements MaintenanceModeContract\n{\n    public function activate(array $payload): void\n    {\n    }\n\n    public function deactivate(): void\n    {\n    }\n\n    public function active(): bool\n    {\n    }\n\n    public function data(): array\n    {\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportMessageBagTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\MessageBag;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportMessageBagTest extends TestCase\n{\n    public function testUniqueness()\n    {\n        $container = new MessageBag;\n        $container->add('foo', 'bar');\n        $container->add('foo', 'bar');\n        $messages = $container->getMessages();\n        $this->assertEquals(['bar'], $messages['foo']);\n    }\n\n    public function testMessagesAreAdded()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('foo', 'baz');\n        $container->add('boom', 'bust');\n        $messages = $container->getMessages();\n        $this->assertEquals(['bar', 'baz'], $messages['foo']);\n        $this->assertEquals(['bust'], $messages['boom']);\n    }\n\n    public function testKeys()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('foo', 'baz');\n        $container->add('boom', 'bust');\n        $this->assertEquals(['foo', 'boom'], $container->keys());\n    }\n\n    public function testMessagesMayBeMerged()\n    {\n        $container = new MessageBag(['username' => ['foo']]);\n        $container->merge(['username' => ['bar']]);\n        $this->assertEquals(['username' => ['foo', 'bar']], $container->getMessages());\n    }\n\n    public function testMessageBagsCanBeMerged()\n    {\n        $container = new MessageBag(['foo' => ['bar']]);\n        $otherContainer = new MessageBag(['foo' => ['baz'], 'bar' => ['foo']]);\n        $container->merge($otherContainer);\n        $this->assertEquals(['foo' => ['bar', 'baz'], 'bar' => ['foo']], $container->getMessages());\n    }\n\n    public function testMessageBagsCanConvertToArrays()\n    {\n        $container = new MessageBag([\n            Collection::make(['foo', 'bar']),\n            Collection::make(['baz', 'qux']),\n        ]);\n        $this->assertSame([['foo', 'bar'], ['baz', 'qux']], $container->getMessages());\n    }\n\n    public function testGetReturnsArrayOfMessagesByKey()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('foo', 'baz');\n        $this->assertEquals(['bar', 'baz'], $container->get('foo'));\n    }\n\n    public function testGetReturnsArrayOfMessagesByImplicitKey()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo.1', 'bar');\n        $container->add('foo.2', 'baz');\n        $this->assertEquals(['foo.1' => ['bar'], 'foo.2' => ['baz']], $container->get('foo.*'));\n    }\n\n    public function testFirstReturnsSingleMessage()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('foo', 'baz');\n        $this->assertSame('bar', $container->first('foo'));\n    }\n\n    public function testFirstReturnsEmptyStringIfNoMessagesFound()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $this->assertSame('', $container->first('foo'));\n    }\n\n    public function testFirstReturnsSingleMessageFromDotKeys()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('name.first', 'jon');\n        $container->add('name.last', 'snow');\n        $this->assertSame('jon', $container->first('name.*'));\n    }\n\n    public function testHasIndicatesExistence()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $this->assertTrue($container->has('foo'));\n        $this->assertFalse($container->has('bar'));\n    }\n\n    public function testMissingIndicatesNonExistence()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $this->assertFalse($container->missing('foo'));\n        $this->assertFalse($container->missing(['foo', 'baz']));\n        $this->assertFalse($container->missing('foo', 'baz'));\n        $this->assertTrue($container->missing('baz'));\n        $this->assertTrue($container->missing(['baz', 'biz']));\n        $this->assertTrue($container->missing('baz', 'biz'));\n    }\n\n    public function testAddIf()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->addIf(true, 'foo', 'bar');\n        $this->assertTrue($container->has('foo'));\n\n        $container->addIf(false, 'bar', 'biz');\n        $this->assertFalse($container->has('bar'));\n    }\n\n    public function testForget()\n    {\n        $container = new MessageBag(['foo' => 'bar']);\n        $container->forget('foo');\n        $this->assertFalse($container->has('foo'));\n    }\n\n    public function testHasWithKeyNull()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $this->assertTrue($container->has(null));\n    }\n\n    public function testHasAnyIndicatesExistence()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $this->assertFalse($container->hasAny());\n        $container->add('foo', 'bar');\n        $container->add('bar', 'foo');\n        $container->add('boom', 'baz');\n        $this->assertTrue($container->hasAny(['foo', 'bar']));\n        $this->assertTrue($container->hasAny('foo', 'bar'));\n        $this->assertTrue($container->hasAny(['boom', 'baz']));\n        $this->assertTrue($container->hasAny('boom', 'baz'));\n        $this->assertFalse($container->hasAny(['baz']));\n        $this->assertFalse($container->hasAny('baz'));\n        $this->assertFalse($container->hasAny('baz', 'biz'));\n    }\n\n    public function testHasAnyWithKeyNull()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $this->assertTrue($container->hasAny(null));\n    }\n\n    public function testHasIndicatesExistenceOfAllKeys()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('bar', 'foo');\n        $container->add('boom', 'baz');\n        $this->assertTrue($container->has(['foo', 'bar', 'boom']));\n        $this->assertFalse($container->has(['foo', 'bar', 'boom', 'baz']));\n        $this->assertFalse($container->has(['foo', 'baz']));\n    }\n\n    public function testHasIndicatesNoneExistence()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n\n        $this->assertFalse($container->has('foo'));\n    }\n\n    public function testAllReturnsAllMessages()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n        $this->assertEquals(['bar', 'baz'], $container->all());\n    }\n\n    public function testFormatIsRespected()\n    {\n        $container = new MessageBag;\n        $container->setFormat('<p>:message</p>');\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n        $this->assertSame('<p>bar</p>', $container->first('foo'));\n        $this->assertEquals(['<p>bar</p>'], $container->get('foo'));\n        $this->assertEquals(['<p>bar</p>', '<p>baz</p>'], $container->all());\n        $this->assertSame('bar', $container->first('foo', ':message'));\n        $this->assertEquals(['bar'], $container->get('foo', ':message'));\n        $this->assertEquals(['bar', 'baz'], $container->all(':message'));\n\n        $container->setFormat(':key :message');\n        $this->assertSame('foo bar', $container->first('foo'));\n    }\n\n    public function testUnique()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('foo2', 'bar');\n        $container->add('boom', 'baz');\n        $this->assertEquals([0 => 'bar', 2 => 'baz'], $container->unique());\n    }\n\n    public function testMessageBagReturnsCorrectArray()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n\n        $this->assertEquals(['foo' => ['bar'], 'boom' => ['baz']], $container->toArray());\n    }\n\n    public function testMessageBagReturnsExpectedJson()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n\n        $this->assertSame('{\"foo\":[\"bar\"],\"boom\":[\"baz\"]}', $container->toJson());\n    }\n\n    public function testMessageBagReturnsExpectedPrettyJson()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n        $container->add('baz', '123');\n        $results = $container->toPrettyJson();\n        $expected = $container->toJson(JSON_PRETTY_PRINT);\n\n        $this->assertJsonStringEqualsJsonString($expected, $results);\n        $this->assertSame($expected, $results);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('\"123\"', $results);\n\n        $results = $container->toPrettyJson(JSON_NUMERIC_CHECK);\n        $this->assertStringContainsString(\"\\n\", $results);\n        $this->assertStringContainsString('    ', $results);\n        $this->assertStringContainsString('123', $results);\n        $this->assertStringNotContainsString('\"123\"', $results);\n    }\n\n    public function testCountReturnsCorrectValue()\n    {\n        $container = new MessageBag;\n        $this->assertCount(0, $container);\n\n        $container->add('foo', 'bar');\n        $container->add('foo', 'baz');\n        $container->add('boom', 'baz');\n\n        $this->assertCount(3, $container);\n    }\n\n    public function testCountable()\n    {\n        $container = new MessageBag;\n        $container->add('foo', 'bar');\n        $container->add('boom', 'baz');\n\n        $this->assertCount(2, $container);\n    }\n\n    public function testConstructor()\n    {\n        $messageBag = new MessageBag(['country' => 'Azerbaijan', 'capital' => 'Baku']);\n        $this->assertEquals(['country' => ['Azerbaijan'], 'capital' => ['Baku']], $messageBag->getMessages());\n    }\n\n    public function testFirstFindsMessageForWildcardKey()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $container->add('foo.bar', 'baz');\n        $this->assertSame('baz', $container->first('foo.*'));\n    }\n\n    public function testIsEmptyTrue()\n    {\n        $container = new MessageBag;\n        $this->assertTrue($container->isEmpty());\n    }\n\n    public function testIsEmptyFalse()\n    {\n        $container = new MessageBag;\n        $container->add('foo.bar', 'baz');\n        $this->assertFalse($container->isEmpty());\n    }\n\n    public function testIsNotEmptyTrue()\n    {\n        $container = new MessageBag;\n        $container->add('foo.bar', 'baz');\n        $this->assertTrue($container->isNotEmpty());\n    }\n\n    public function testIsNotEmptyFalse()\n    {\n        $container = new MessageBag;\n        $this->assertFalse($container->isNotEmpty());\n    }\n\n    public function testToString()\n    {\n        $container = new MessageBag;\n        $container->add('foo.bar', 'baz');\n        $this->assertSame('{\"foo.bar\":[\"baz\"]}', (string) $container);\n    }\n\n    public function testGetFormat()\n    {\n        $container = new MessageBag;\n        $container->setFormat(':message');\n        $this->assertSame(':message', $container->getFormat());\n    }\n\n    public function testConstructorUniquenessConsistency()\n    {\n        $messageBag = new MessageBag(['messages' => ['first', 'second', 'third', 'third']]);\n        $messages = $messageBag->getMessages();\n        $this->assertEquals(['first', 'second', 'third'], $messages['messages']);\n\n        $messageBag = new MessageBag;\n        $messageBag->add('messages', 'first');\n        $messageBag->add('messages', 'second');\n        $messageBag->add('messages', 'third');\n        $messageBag->add('messages', 'third');\n        $messages = $messageBag->getMessages();\n        $this->assertEquals(['first', 'second', 'third'], $messages['messages']);\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportNamespacedItemResolverTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\NamespacedItemResolver;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportNamespacedItemResolverTest extends TestCase\n{\n    public function testResolution()\n    {\n        $r = new NamespacedItemResolver;\n\n        $this->assertEquals(['foo', 'bar', 'baz'], $r->parseKey('foo::bar.baz'));\n        $this->assertEquals(['foo', 'bar', null], $r->parseKey('foo::bar'));\n        $this->assertEquals([null, 'bar', 'baz'], $r->parseKey('bar.baz'));\n        $this->assertEquals([null, 'bar', null], $r->parseKey('bar'));\n    }\n\n    public function testParsedItemsAreCached()\n    {\n        $r = $this->getMockBuilder(NamespacedItemResolver::class)->onlyMethods(['parseBasicSegments', 'parseNamespacedSegments'])->getMock();\n        $r->setParsedKey('foo.bar', ['foo']);\n        $r->expects($this->never())->method('parseBasicSegments');\n        $r->expects($this->never())->method('parseNamespacedSegments');\n\n        $this->assertEquals(['foo'], $r->parseKey('foo.bar'));\n    }\n\n    public function testParsedItemsMayBeFlushed()\n    {\n        $r = $this->getMockBuilder(NamespacedItemResolver::class)->onlyMethods(['parseBasicSegments', 'parseNamespacedSegments'])->getMock();\n        $r->expects($this->once())->method('parseBasicSegments')->willReturn(['bar']);\n\n        $r->setParsedKey('foo.bar', ['foo']);\n        $r->flushParsedKeys();\n\n        $this->assertEquals(['bar'], $r->parseKey('foo.bar'));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportNumberTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Number;\nuse PHPUnit\\Framework\\Attributes\\RequiresPhpExtension;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportNumberTest extends TestCase\n{\n    public function testDefaultLocale()\n    {\n        $this->assertSame('en', Number::defaultLocale());\n    }\n\n    public function testDefaultCurrency()\n    {\n        $this->assertSame('USD', Number::defaultCurrency());\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testFormat()\n    {\n        $this->assertSame('0', Number::format(0));\n        $this->assertSame('0', Number::format(0.0));\n        $this->assertSame('0', Number::format(0.00));\n        $this->assertSame('1', Number::format(1));\n        $this->assertSame('10', Number::format(10));\n        $this->assertSame('25', Number::format(25));\n        $this->assertSame('100', Number::format(100));\n        $this->assertSame('100,000', Number::format(100000));\n        $this->assertSame('100,000.00', Number::format(100000, precision: 2));\n        $this->assertSame('100,000.12', Number::format(100000.123, precision: 2));\n        $this->assertSame('100,000.123', Number::format(100000.1234, maxPrecision: 3));\n        $this->assertSame('100,000.124', Number::format(100000.1236, maxPrecision: 3));\n        $this->assertSame('123,456,789', Number::format(123456789));\n\n        $this->assertSame('-1', Number::format(-1));\n        $this->assertSame('-10', Number::format(-10));\n        $this->assertSame('-25', Number::format(-25));\n\n        $this->assertSame('0.2', Number::format(0.2));\n        $this->assertSame('0.20', Number::format(0.2, precision: 2));\n        $this->assertSame('0.123', Number::format(0.1234, maxPrecision: 3));\n        $this->assertSame('1.23', Number::format(1.23));\n        $this->assertSame('-1.23', Number::format(-1.23));\n        $this->assertSame('123.456', Number::format(123.456));\n\n        $this->assertSame('∞', Number::format(INF));\n        $this->assertSame('NaN', Number::format(NAN));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testFormatWithDifferentLocale()\n    {\n        $this->assertSame('123,456,789', Number::format(123456789, locale: 'en'));\n        $this->assertSame('123.456.789', Number::format(123456789, locale: 'de'));\n        $this->assertSame('123 456 789', Number::format(123456789, locale: 'fr'));\n        $this->assertSame('123 456 789', Number::format(123456789, locale: 'ru'));\n        $this->assertSame('123 456 789', Number::format(123456789, locale: 'sv'));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testFormatWithAppLocale()\n    {\n        $this->assertSame('123,456,789', Number::format(123456789));\n\n        Number::useLocale('de');\n\n        $this->assertSame('123.456.789', Number::format(123456789));\n\n        Number::useLocale('en');\n    }\n\n    public function testSpellout()\n    {\n        $this->assertSame('ten', Number::spell(10));\n        $this->assertSame('one point two', Number::spell(1.2));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testSpelloutWithLocale()\n    {\n        $this->assertSame('trois', Number::spell(3, 'fr'));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testSpelloutWithThreshold()\n    {\n        $this->assertSame('9', Number::spell(9, after: 10));\n        $this->assertSame('10', Number::spell(10, after: 10));\n        $this->assertSame('eleven', Number::spell(11, after: 10));\n\n        $this->assertSame('nine', Number::spell(9, until: 10));\n        $this->assertSame('10', Number::spell(10, until: 10));\n        $this->assertSame('11', Number::spell(11, until: 10));\n\n        $this->assertSame('ten thousand', Number::spell(10000, until: 50000));\n        $this->assertSame('100,000', Number::spell(100000, until: 50000));\n    }\n\n    public function testOrdinal()\n    {\n        $this->assertSame('1st', Number::ordinal(1));\n        $this->assertSame('2nd', Number::ordinal(2));\n        $this->assertSame('3rd', Number::ordinal(3));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testSpellOrdinal()\n    {\n        $this->assertSame('first', Number::spellOrdinal(1));\n        $this->assertSame('second', Number::spellOrdinal(2));\n        $this->assertSame('third', Number::spellOrdinal(3));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testToPercent()\n    {\n        $this->assertSame('0%', Number::percentage(0, precision: 0));\n        $this->assertSame('0%', Number::percentage(0));\n        $this->assertSame('1%', Number::percentage(1));\n        $this->assertSame('10.00%', Number::percentage(10, precision: 2));\n        $this->assertSame('100%', Number::percentage(100));\n        $this->assertSame('100.00%', Number::percentage(100, precision: 2));\n        $this->assertSame('100.123%', Number::percentage(100.1234, maxPrecision: 3));\n\n        $this->assertSame('300%', Number::percentage(300));\n        $this->assertSame('1,000%', Number::percentage(1000));\n\n        $this->assertSame('2%', Number::percentage(1.75));\n        $this->assertSame('1.75%', Number::percentage(1.75, precision: 2));\n        $this->assertSame('1.750%', Number::percentage(1.75, precision: 3));\n        $this->assertSame('0%', Number::percentage(0.12345));\n        $this->assertSame('0.00%', Number::percentage(0, precision: 2));\n        $this->assertSame('0.12%', Number::percentage(0.12345, precision: 2));\n        $this->assertSame('0.1235%', Number::percentage(0.12345, precision: 4));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testToCurrency()\n    {\n        $this->assertSame('$0.00', Number::currency(0));\n        $this->assertSame('$1.00', Number::currency(1));\n        $this->assertSame('$10.00', Number::currency(10));\n\n        $this->assertSame('€0.00', Number::currency(0, 'EUR'));\n        $this->assertSame('€1.00', Number::currency(1, 'EUR'));\n        $this->assertSame('€10.00', Number::currency(10, 'EUR'));\n\n        $this->assertSame('-$5.00', Number::currency(-5));\n        $this->assertSame('$5.00', Number::currency(5.00));\n        $this->assertSame('$5.32', Number::currency(5.325));\n\n        $this->assertSame('$0', Number::currency(0, precision: 0));\n        $this->assertSame('$5', Number::currency(5.00, precision: 0));\n        $this->assertSame('$10', Number::currency(10.252, precision: 0));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testToCurrencyWithDifferentLocale()\n    {\n        $this->assertSame('1,00 €', Number::currency(1, 'EUR', 'de'));\n        $this->assertSame('1,00 $', Number::currency(1, 'USD', 'de'));\n        $this->assertSame('1,00 £', Number::currency(1, 'GBP', 'de'));\n\n        $this->assertSame('123.456.789,12 $', Number::currency(123456789.12345, 'USD', 'de'));\n        $this->assertSame('123.456.789,12 €', Number::currency(123456789.12345, 'EUR', 'de'));\n        $this->assertSame('1 234,56 $US', Number::currency(1234.56, 'USD', 'fr'));\n    }\n\n    public function testBytesToHuman()\n    {\n        $this->assertSame('0 B', Number::fileSize(0));\n        $this->assertSame('0.00 B', Number::fileSize(0, precision: 2));\n        $this->assertSame('1 B', Number::fileSize(1));\n        $this->assertSame('1 KB', Number::fileSize(1024));\n        $this->assertSame('2 KB', Number::fileSize(2048));\n        $this->assertSame('2.00 KB', Number::fileSize(2048, precision: 2));\n        $this->assertSame('1.23 KB', Number::fileSize(1264, precision: 2));\n        $this->assertSame('1.234 KB', Number::fileSize(1264.12345, maxPrecision: 3));\n        $this->assertSame('1.234 KB', Number::fileSize(1264, 3));\n        $this->assertSame('5 GB', Number::fileSize(1024 * 1024 * 1024 * 5));\n        $this->assertSame('10 TB', Number::fileSize((1024 ** 4) * 10));\n        $this->assertSame('10 PB', Number::fileSize((1024 ** 5) * 10));\n        $this->assertSame('1 ZB', Number::fileSize(1024 ** 7));\n        $this->assertSame('1 YB', Number::fileSize(1024 ** 8));\n        $this->assertSame('1,024 YB', Number::fileSize(1024 ** 9));\n    }\n\n    public function testClamp()\n    {\n        $this->assertSame(2, Number::clamp(1, 2, 3));\n        $this->assertSame(3, Number::clamp(5, 2, 3));\n        $this->assertSame(5, Number::clamp(5, 1, 10));\n        $this->assertSame(4.5, Number::clamp(4.5, 1, 10));\n        $this->assertSame(1, Number::clamp(-10, 1, 5));\n    }\n\n    public function testToHuman()\n    {\n        $this->assertSame('1', Number::forHumans(1));\n        $this->assertSame('1.00', Number::forHumans(1, precision: 2));\n        $this->assertSame('10', Number::forHumans(10));\n        $this->assertSame('100', Number::forHumans(100));\n        $this->assertSame('1 thousand', Number::forHumans(1000));\n        $this->assertSame('1.00 thousand', Number::forHumans(1000, precision: 2));\n        $this->assertSame('1 thousand', Number::forHumans(1000, maxPrecision: 2));\n        $this->assertSame('1 thousand', Number::forHumans(1230));\n        $this->assertSame('1.2 thousand', Number::forHumans(1230, maxPrecision: 1));\n        $this->assertSame('1 million', Number::forHumans(1000000));\n        $this->assertSame('1 billion', Number::forHumans(1000000000));\n        $this->assertSame('1 trillion', Number::forHumans(1000000000000));\n        $this->assertSame('1 quadrillion', Number::forHumans(1000000000000000));\n        $this->assertSame('1 thousand quadrillion', Number::forHumans(1000000000000000000));\n\n        $this->assertSame('123', Number::forHumans(123));\n        $this->assertSame('1 thousand', Number::forHumans(1234));\n        $this->assertSame('1.23 thousand', Number::forHumans(1234, precision: 2));\n        $this->assertSame('12 thousand', Number::forHumans(12345));\n        $this->assertSame('1 million', Number::forHumans(1234567));\n        $this->assertSame('1 billion', Number::forHumans(1234567890));\n        $this->assertSame('1 trillion', Number::forHumans(1234567890123));\n        $this->assertSame('1.23 trillion', Number::forHumans(1234567890123, precision: 2));\n        $this->assertSame('1 quadrillion', Number::forHumans(1234567890123456));\n        $this->assertSame('1.23 thousand quadrillion', Number::forHumans(1234567890123456789, precision: 2));\n        $this->assertSame('490 thousand', Number::forHumans(489939));\n        $this->assertSame('489.9390 thousand', Number::forHumans(489939, precision: 4));\n        $this->assertSame('500.00000 million', Number::forHumans(500000000, precision: 5));\n\n        $this->assertSame('1 million quadrillion', Number::forHumans(1000000000000000000000));\n        $this->assertSame('1 billion quadrillion', Number::forHumans(1000000000000000000000000));\n        $this->assertSame('1 trillion quadrillion', Number::forHumans(1000000000000000000000000000));\n        $this->assertSame('1 quadrillion quadrillion', Number::forHumans(1000000000000000000000000000000));\n        $this->assertSame('1 thousand quadrillion quadrillion', Number::forHumans(1000000000000000000000000000000000));\n\n        $this->assertSame('0', Number::forHumans(0));\n        $this->assertSame('0', Number::forHumans(0.0));\n        $this->assertSame('0.00', Number::forHumans(0, 2));\n        $this->assertSame('0.00', Number::forHumans(0.0, 2));\n        $this->assertSame('-1', Number::forHumans(-1));\n        $this->assertSame('-1.00', Number::forHumans(-1, precision: 2));\n        $this->assertSame('-10', Number::forHumans(-10));\n        $this->assertSame('-100', Number::forHumans(-100));\n        $this->assertSame('-1 thousand', Number::forHumans(-1000));\n        $this->assertSame('-1.23 thousand', Number::forHumans(-1234, precision: 2));\n        $this->assertSame('-1.2 thousand', Number::forHumans(-1234, maxPrecision: 1));\n        $this->assertSame('-1 million', Number::forHumans(-1000000));\n        $this->assertSame('-1 billion', Number::forHumans(-1000000000));\n        $this->assertSame('-1 trillion', Number::forHumans(-1000000000000));\n        $this->assertSame('-1.1 trillion', Number::forHumans(-1100000000000, maxPrecision: 1));\n        $this->assertSame('-1 quadrillion', Number::forHumans(-1000000000000000));\n        $this->assertSame('-1 thousand quadrillion', Number::forHumans(-1000000000000000000));\n    }\n\n    public function testSummarize()\n    {\n        $this->assertSame('1', Number::abbreviate(1));\n        $this->assertSame('1.00', Number::abbreviate(1, precision: 2));\n        $this->assertSame('10', Number::abbreviate(10));\n        $this->assertSame('100', Number::abbreviate(100));\n        $this->assertSame('1K', Number::abbreviate(1000));\n        $this->assertSame('1.00K', Number::abbreviate(1000, precision: 2));\n        $this->assertSame('1K', Number::abbreviate(1000, maxPrecision: 2));\n        $this->assertSame('1K', Number::abbreviate(1230));\n        $this->assertSame('1.2K', Number::abbreviate(1230, maxPrecision: 1));\n        $this->assertSame('1M', Number::abbreviate(1000000));\n        $this->assertSame('1B', Number::abbreviate(1000000000));\n        $this->assertSame('1T', Number::abbreviate(1000000000000));\n        $this->assertSame('1Q', Number::abbreviate(1000000000000000));\n        $this->assertSame('1KQ', Number::abbreviate(1000000000000000000));\n\n        $this->assertSame('123', Number::abbreviate(123));\n        $this->assertSame('1K', Number::abbreviate(1234));\n        $this->assertSame('1.23K', Number::abbreviate(1234, precision: 2));\n        $this->assertSame('12K', Number::abbreviate(12345));\n        $this->assertSame('1M', Number::abbreviate(1234567));\n        $this->assertSame('1B', Number::abbreviate(1234567890));\n        $this->assertSame('1T', Number::abbreviate(1234567890123));\n        $this->assertSame('1.23T', Number::abbreviate(1234567890123, precision: 2));\n        $this->assertSame('1Q', Number::abbreviate(1234567890123456));\n        $this->assertSame('1.23KQ', Number::abbreviate(1234567890123456789, precision: 2));\n        $this->assertSame('490K', Number::abbreviate(489939));\n        $this->assertSame('489.9390K', Number::abbreviate(489939, precision: 4));\n        $this->assertSame('500.00000M', Number::abbreviate(500000000, precision: 5));\n\n        $this->assertSame('1MQ', Number::abbreviate(1000000000000000000000));\n        $this->assertSame('1BQ', Number::abbreviate(1000000000000000000000000));\n        $this->assertSame('1TQ', Number::abbreviate(1000000000000000000000000000));\n        $this->assertSame('1QQ', Number::abbreviate(1000000000000000000000000000000));\n        $this->assertSame('1KQQ', Number::abbreviate(1000000000000000000000000000000000));\n\n        $this->assertSame('0', Number::abbreviate(0));\n        $this->assertSame('0', Number::abbreviate(0.0));\n        $this->assertSame('0.00', Number::abbreviate(0, 2));\n        $this->assertSame('0.00', Number::abbreviate(0.0, 2));\n        $this->assertSame('-1', Number::abbreviate(-1));\n        $this->assertSame('-1.00', Number::abbreviate(-1, precision: 2));\n        $this->assertSame('-10', Number::abbreviate(-10));\n        $this->assertSame('-100', Number::abbreviate(-100));\n        $this->assertSame('-1K', Number::abbreviate(-1000));\n        $this->assertSame('-1.23K', Number::abbreviate(-1234, precision: 2));\n        $this->assertSame('-1.2K', Number::abbreviate(-1234, maxPrecision: 1));\n        $this->assertSame('-1M', Number::abbreviate(-1000000));\n        $this->assertSame('-1B', Number::abbreviate(-1000000000));\n        $this->assertSame('-1T', Number::abbreviate(-1000000000000));\n        $this->assertSame('-1.1T', Number::abbreviate(-1100000000000, maxPrecision: 1));\n        $this->assertSame('-1Q', Number::abbreviate(-1000000000000000));\n        $this->assertSame('-1KQ', Number::abbreviate(-1000000000000000000));\n    }\n\n    public function testPairs()\n    {\n        $this->assertSame([[0, 10], [10, 20], [20, 25]], Number::pairs(25, 10, 0, 0));\n        $this->assertSame([[0, 9], [10, 19], [20, 25]], Number::pairs(25, 10, 0, 1));\n        $this->assertSame([[1, 11], [11, 21], [21, 25]], Number::pairs(25, 10, 1, 0));\n        $this->assertSame([[1, 10], [11, 20], [21, 25]], Number::pairs(25, 10, 1, 1));\n        $this->assertSame([[0, 1000], [1000, 2000], [2000, 2500]], Number::pairs(2500, 1000, 0, 0));\n        $this->assertSame([[0, 999], [1000, 1999], [2000, 2500]], Number::pairs(2500, 1000, 0, 1));\n        $this->assertSame([[1, 1001], [1001, 2001], [2001, 2500]], Number::pairs(2500, 1000, 1, 0));\n        $this->assertSame([[1, 1000], [1001, 2000], [2001, 2500]], Number::pairs(2500, 1000, 1, 1));\n        $this->assertSame([[0, 2.5], [2.5, 5.0], [5.0, 7.5], [7.5, 10.0]], Number::pairs(10, 2.5, 0, 0));\n        $this->assertSame([[0, 2.0], [2.5, 4.5], [5.0, 7.0], [7.5, 9.5]], Number::pairs(10, 2.5, 0, 0.5));\n        $this->assertSame([[0.5, 3.0], [3.0, 5.5], [5.5, 8.0], [8.0, 10]], Number::pairs(10, 2.5, 0.5, 0));\n        $this->assertSame([[0.5, 2.5], [3.0, 5.0], [5.5, 7.5], [8.0, 10.0]], Number::pairs(10, 2.5, 0.5, 0.5));\n    }\n\n    public function testTrim()\n    {\n        $this->assertSame(12, Number::trim(12));\n        $this->assertSame(120, Number::trim(120));\n        $this->assertSame(12, Number::trim(12.0));\n        $this->assertSame(12.3, Number::trim(12.3));\n        $this->assertSame(12.3, Number::trim(12.30));\n        $this->assertSame(12.3456789, Number::trim(12.3456789));\n        $this->assertSame(12.3456789, Number::trim(12.34567890000));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testParse()\n    {\n        $this->assertSame(1234.0, Number::parse('1,234'));\n        $this->assertSame(1234.5, Number::parse('1,234.5'));\n        $this->assertSame(1234.56, Number::parse('1,234.56'));\n        $this->assertSame(-1234.56, Number::parse('-1,234.56'));\n\n        $this->assertSame(1234.56, Number::parse('1.234,56', locale: 'de'));\n        $this->assertSame(1234.56, Number::parse('1 234,56', locale: 'fr'));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testParseInt()\n    {\n        $this->assertSame(1234, Number::parseInt('1,234'));\n        $this->assertSame(1234, Number::parseInt('1,234.5'));\n        $this->assertSame(-1234, Number::parseInt('-1,234.56'));\n\n        $this->assertSame(1234, Number::parseInt('1.234', locale: 'de'));\n        $this->assertSame(1234, Number::parseInt('1 234', locale: 'fr'));\n    }\n\n    #[RequiresPhpExtension('intl')]\n    public function testParseFloat()\n    {\n        $this->assertSame(1234.0, Number::parseFloat('1,234'));\n        $this->assertSame(1234.5, Number::parseFloat('1,234.5'));\n        $this->assertSame(1234.56, Number::parseFloat('1,234.56'));\n        $this->assertSame(-1234.56, Number::parseFloat('-1,234.56'));\n\n        $this->assertSame(1234.56, Number::parseFloat('1.234,56', locale: 'de'));\n        $this->assertSame(1234.56, Number::parseFloat('1 234,56', locale: 'fr'));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportOptionalTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Optional;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass SupportOptionalTest extends TestCase\n{\n    public function testGetExistItemOnObject()\n    {\n        $expected = 'test';\n\n        $targetObj = new stdClass;\n        $targetObj->item = $expected;\n\n        $optional = new Optional($targetObj);\n\n        $this->assertEquals($expected, $optional->item);\n    }\n\n    public function testGetNotExistItemOnObject()\n    {\n        $targetObj = new stdClass;\n\n        $optional = new Optional($targetObj);\n\n        $this->assertNull($optional->item);\n    }\n\n    public function testIssetExistItemOnObject()\n    {\n        $targetObj = new stdClass;\n        $targetObj->item = '';\n\n        $optional = new Optional($targetObj);\n\n        $this->assertTrue(isset($optional->item));\n    }\n\n    public function testIssetNotExistItemOnObject()\n    {\n        $targetObj = new stdClass;\n\n        $optional = new Optional($targetObj);\n\n        $this->assertFalse(isset($optional->item));\n    }\n\n    public function testGetExistItemOnArray()\n    {\n        $expected = 'test';\n\n        $targetArr = [\n            'item' => $expected,\n        ];\n\n        $optional = new Optional($targetArr);\n\n        $this->assertEquals($expected, $optional['item']);\n    }\n\n    public function testGetNotExistItemOnArray()\n    {\n        $targetObj = [];\n\n        $optional = new Optional($targetObj);\n\n        $this->assertNull($optional['item']);\n    }\n\n    public function testIssetExistItemOnArray()\n    {\n        $targetArr = [\n            'item' => '',\n        ];\n\n        $optional = new Optional($targetArr);\n\n        $this->assertTrue(isset($optional['item']));\n        $this->assertTrue(isset($optional->item));\n    }\n\n    public function testIssetNotExistItemOnArray()\n    {\n        $targetArr = [];\n\n        $optional = new Optional($targetArr);\n\n        $this->assertFalse(isset($optional['item']));\n        $this->assertFalse(isset($optional->item));\n    }\n\n    public function testIssetExistItemOnNull()\n    {\n        $targetNull = null;\n\n        $optional = new Optional($targetNull);\n\n        $this->assertFalse(isset($optional->item));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportPluralizerTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Str;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportPluralizerTest extends TestCase\n{\n    public function testBasicSingular()\n    {\n        $this->assertSame('child', Str::singular('children'));\n    }\n\n    public function testBasicPlural()\n    {\n        $this->assertSame('children', Str::plural('child'));\n        $this->assertSame('cod', Str::plural('cod'));\n        $this->assertSame('The words', Str::plural('The word'));\n        $this->assertSame('Bouquetés', Str::plural('Bouqueté'));\n    }\n\n    public function testCaseSensitiveSingularUsage()\n    {\n        $this->assertSame('Child', Str::singular('Children'));\n        $this->assertSame('CHILD', Str::singular('CHILDREN'));\n        $this->assertSame('Test', Str::singular('Tests'));\n    }\n\n    public function testCaseSensitiveSingularPlural()\n    {\n        $this->assertSame('Children', Str::plural('Child'));\n        $this->assertSame('CHILDREN', Str::plural('CHILD'));\n        $this->assertSame('Tests', Str::plural('Test'));\n        $this->assertSame('children', Str::plural('cHiLd'));\n    }\n\n    public function testIfEndOfWordPlural()\n    {\n        $this->assertSame('VortexFields', Str::plural('VortexField'));\n        $this->assertSame('MatrixFields', Str::plural('MatrixField'));\n        $this->assertSame('IndexFields', Str::plural('IndexField'));\n        $this->assertSame('VertexFields', Str::plural('VertexField'));\n\n        // This is expected behavior, use \"Str::pluralStudly\" instead.\n        $this->assertSame('RealHumen', Str::plural('RealHuman'));\n    }\n\n    public function testPluralWithNegativeCount()\n    {\n        $this->assertSame('test', Str::plural('test', 1));\n        $this->assertSame('tests', Str::plural('test', 2));\n        $this->assertSame('test', Str::plural('test', -1));\n        $this->assertSame('tests', Str::plural('test', -2));\n    }\n\n    public function testPluralStudly()\n    {\n        $this->assertPluralStudly('RealHumans', 'RealHuman');\n        $this->assertPluralStudly('Models', 'Model');\n        $this->assertPluralStudly('VortexFields', 'VortexField');\n        $this->assertPluralStudly('MultipleWordsInOneStrings', 'MultipleWordsInOneString');\n    }\n\n    public function testPluralStudlyWithCount()\n    {\n        $this->assertPluralStudly('RealHuman', 'RealHuman', 1);\n        $this->assertPluralStudly('RealHumans', 'RealHuman', 2);\n        $this->assertPluralStudly('RealHuman', 'RealHuman', -1);\n        $this->assertPluralStudly('RealHumans', 'RealHuman', -2);\n    }\n\n    public function testPluralNotAppliedForStringEndingWithNonAlphanumericCharacter()\n    {\n        $this->assertSame('Alien.', Str::plural('Alien.'));\n        $this->assertSame('Alien!', Str::plural('Alien!'));\n        $this->assertSame('Alien ', Str::plural('Alien '));\n        $this->assertSame('50%', Str::plural('50%'));\n    }\n\n    public function testPluralAppliedForStringEndingWithNumericCharacter()\n    {\n        $this->assertSame('User1s', Str::plural('User1'));\n        $this->assertSame('User2s', Str::plural('User2'));\n        $this->assertSame('User3s', Str::plural('User3'));\n    }\n\n    public function testPluralSupportsArrays()\n    {\n        $this->assertSame('users', Str::plural('user', []));\n        $this->assertSame('user', Str::plural('user', ['one']));\n        $this->assertSame('users', Str::plural('user', ['one', 'two']));\n    }\n\n    public function testPluralSupportsCollections()\n    {\n        $this->assertSame('users', Str::plural('user', collect()));\n        $this->assertSame('user', Str::plural('user', collect(['one'])));\n        $this->assertSame('users', Str::plural('user', collect(['one', 'two'])));\n    }\n\n    public function testPluralStudlySupportsArrays()\n    {\n        $this->assertPluralStudly('SomeUsers', 'SomeUser', []);\n        $this->assertPluralStudly('SomeUser', 'SomeUser', ['one']);\n        $this->assertPluralStudly('SomeUsers', 'SomeUser', ['one', 'two']);\n    }\n\n    public function testPluralStudlySupportsCollections()\n    {\n        $this->assertPluralStudly('SomeUsers', 'SomeUser', collect());\n        $this->assertPluralStudly('SomeUser', 'SomeUser', collect(['one']));\n        $this->assertPluralStudly('SomeUsers', 'SomeUser', collect(['one', 'two']));\n    }\n\n    private function assertPluralStudly($expected, $value, $count = 2)\n    {\n        $this->assertSame($expected, Str::pluralStudly($value, $count));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportReflectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Mail\\Mailable;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Support\\Reflector;\nuse Illuminate\\Support\\Testing\\Fakes\\BusFake;\nuse Illuminate\\Support\\Testing\\Fakes\\MailFake;\nuse Illuminate\\Support\\Testing\\Fakes\\PendingMailFake;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionClass;\n\nclass SupportReflectorTest extends TestCase\n{\n    public function testGetClassName()\n    {\n        $method = (new ReflectionClass(PendingMailFake::class))->getMethod('send');\n\n        $this->assertSame(Mailable::class, Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testEmptyClassName()\n    {\n        $method = (new ReflectionClass(MailFake::class))->getMethod('assertSent');\n\n        $this->assertNull(Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testStringTypeName()\n    {\n        $method = (new ReflectionClass(BusFake::class))->getMethod('dispatchedAfterResponse');\n\n        $this->assertNull(Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testSelfClassName()\n    {\n        $method = (new ReflectionClass(Model::class))->getMethod('newPivot');\n\n        $this->assertSame(Model::class, Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testParentClassName()\n    {\n        $method = (new ReflectionClass(B::class))->getMethod('f');\n\n        $this->assertSame(A::class, Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testParameterSubclassOfInterface()\n    {\n        $method = (new ReflectionClass(TestClassWithInterfaceSubclassParameter::class))->getMethod('f');\n\n        $this->assertTrue(Reflector::isParameterSubclassOf($method->getParameters()[0], IA::class));\n    }\n\n    public function testUnionTypeName()\n    {\n        $method = (new ReflectionClass(C::class))->getMethod('f');\n\n        $this->assertNull(Reflector::getParameterClassName($method->getParameters()[0]));\n    }\n\n    public function testIsCallable()\n    {\n        $this->assertTrue(Reflector::isCallable(function () {\n        }));\n        $this->assertTrue(Reflector::isCallable([B::class, 'f']));\n        $this->assertFalse(Reflector::isCallable([TestClassWithCall::class, 'f']));\n        $this->assertTrue(Reflector::isCallable([new TestClassWithCall, 'f']));\n        $this->assertTrue(Reflector::isCallable([TestClassWithCallStatic::class, 'f']));\n        $this->assertFalse(Reflector::isCallable([new TestClassWithCallStatic, 'f']));\n        $this->assertFalse(Reflector::isCallable([new TestClassWithCallStatic]));\n        $this->assertFalse(Reflector::isCallable(['TotallyMissingClass', 'foo']));\n        $this->assertTrue(Reflector::isCallable(['TotallyMissingClass', 'foo'], true));\n    }\n\n    public function testGetClassAttributes()\n    {\n        require_once __DIR__.'/Fixtures/ClassesWithAttributes.php';\n\n        $this->assertSame([], Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\UnusedAttr::class)->toArray());\n\n        $this->assertSame(\n            [Fixtures\\ChildClass::class => [], Fixtures\\ParentClass::class => []],\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\UnusedAttr::class, true)->toArray()\n        );\n\n        $this->assertSame(\n            ['quick', 'brown', 'fox'],\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class)->map->string->all()\n        );\n\n        $this->assertSame(\n            ['quick', 'brown', 'fox', 'lazy', 'dog'],\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class, true)->flatten()->map->string->all()\n        );\n\n        $this->assertSame(7, Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\NumAttr::class)->sum->number);\n        $this->assertSame(12, Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\NumAttr::class, true)->flatten()->sum->number);\n        $this->assertSame(5, Reflector::getClassAttributes(Fixtures\\ParentClass::class, Fixtures\\NumAttr::class)->sum->number);\n        $this->assertSame(5, Reflector::getClassAttributes(Fixtures\\ParentClass::class, Fixtures\\NumAttr::class, true)->flatten()->sum->number);\n\n        $this->assertSame(\n            [Fixtures\\ChildClass::class, Fixtures\\ParentClass::class],\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class, true)->keys()->all()\n        );\n\n        $this->assertContainsOnlyInstancesOf(\n            Fixtures\\StrAttr::class,\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class)->all()\n        );\n\n        $this->assertContainsOnlyInstancesOf(\n            Fixtures\\StrAttr::class,\n            Reflector::getClassAttributes(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class, true)->flatten()->all()\n        );\n    }\n\n    public function testGetClassAttribute()\n    {\n        require_once __DIR__.'/Fixtures/ClassesWithAttributes.php';\n\n        $this->assertNull(Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\UnusedAttr::class));\n        $this->assertNull(Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\UnusedAttr::class, true));\n        $this->assertNull(Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\ParentOnlyAttr::class));\n        $this->assertInstanceOf(Fixtures\\ParentOnlyAttr::class, Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\ParentOnlyAttr::class, true));\n        $this->assertInstanceOf(Fixtures\\StrAttr::class, Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class));\n        $this->assertInstanceOf(Fixtures\\StrAttr::class, Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class, true));\n        $this->assertSame('quick', Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class)->string);\n        $this->assertSame('quick', Reflector::getClassAttribute(Fixtures\\ChildClass::class, Fixtures\\StrAttr::class, true)->string);\n        $this->assertSame('lazy', Reflector::getClassAttribute(Fixtures\\ParentClass::class, Fixtures\\StrAttr::class)->string);\n    }\n}\n\nclass A\n{\n}\n\nclass B extends A\n{\n    public function f(parent $x)\n    {\n        //\n    }\n}\n\nclass C\n{\n    public function f(A|Model $x)\n    {\n        //\n    }\n}\n\nclass TestClassWithCall\n{\n    public function __call($method, $parameters)\n    {\n        //\n    }\n}\n\nclass TestClassWithCallStatic\n{\n    public static function __callStatic($method, $parameters)\n    {\n        //\n    }\n}\n\ninterface IA\n{\n}\n\ninterface IB extends IA\n{\n}\n\nclass TestClassWithInterfaceSubclassParameter\n{\n    public function f(IB $x)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportReflectsClosuresTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Traits\\ReflectsClosures;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\n\nclass SupportReflectsClosuresTest extends TestCase\n{\n    public function testReflectsClosures()\n    {\n        $this->assertParameterTypes([ExampleParameter::class], function (ExampleParameter $one) {\n            // assert the Closure isn't actually executed\n            throw new RuntimeException;\n        });\n\n        $this->assertParameterTypes([], function () {\n            //\n        });\n\n        $this->assertParameterTypes([null], function ($one) {\n            //\n        });\n\n        $this->assertParameterTypes([null, ExampleParameter::class], function ($one, ?ExampleParameter $two = null) {\n            //\n        });\n\n        $this->assertParameterTypes([null, ExampleParameter::class], function (string $one, ?ExampleParameter $two) {\n            //\n        });\n\n        // Because the parameter is variadic, the closure will always receive an array.\n        $this->assertParameterTypes([null], function (ExampleParameter ...$vars) {\n            //\n        });\n    }\n\n    public function testItReturnsTheFirstParameterType()\n    {\n        $type = ReflectsClosuresClass::reflectFirst(function (ExampleParameter $a) {\n            //\n        });\n\n        $this->assertInstanceOf($type, new ExampleParameter);\n    }\n\n    public function testItThrowsWhenNoParameters()\n    {\n        $this->expectException(RuntimeException::class);\n\n        ReflectsClosuresClass::reflectFirst(function () {\n            //\n        });\n    }\n\n    public function testItThrowsWhenNoFirstParameterType()\n    {\n        $this->expectException(RuntimeException::class);\n\n        ReflectsClosuresClass::reflectFirst(function ($a, ExampleParameter $b) {\n            //\n        });\n    }\n\n    public function testItWorksWithUnionTypes()\n    {\n        $types = ReflectsClosuresClass::reflectFirstAll(function (ExampleParameter $a, $b) {\n            //\n        });\n\n        $this->assertEquals([\n            ExampleParameter::class,\n        ], $types);\n\n        $closure = require __DIR__.'/Fixtures/UnionTypesClosure.php';\n\n        $types = ReflectsClosuresClass::reflectFirstAll($closure);\n\n        $this->assertEquals([\n            ExampleParameter::class,\n            AnotherExampleParameter::class,\n        ], $types);\n    }\n\n    public function testItWorksWithUnionTypesWithNoTypeHints()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $types = ReflectsClosuresClass::reflectFirstAll(function ($a, $b) {\n            //\n        });\n    }\n\n    public function testItWorksWithUnionTypesWithNoArguments()\n    {\n        $this->expectException(RuntimeException::class);\n\n        $types = ReflectsClosuresClass::reflectFirstAll(function () {\n            //\n        });\n    }\n\n    private function assertParameterTypes($expected, $closure)\n    {\n        $types = ReflectsClosuresClass::reflect($closure);\n\n        $this->assertSame($expected, $types);\n    }\n}\n\nclass ReflectsClosuresClass\n{\n    use ReflectsClosures;\n\n    public static function reflect($closure)\n    {\n        return array_values((new static)->closureParameterTypes($closure));\n    }\n\n    public static function reflectFirst($closure)\n    {\n        return (new static)->firstClosureParameterType($closure);\n    }\n\n    public static function reflectFirstAll($closure)\n    {\n        return (new static)->firstClosureParameterTypes($closure);\n    }\n}\n\nclass ExampleParameter\n{\n    //\n}\n\nclass AnotherExampleParameter\n{\n    //\n}\n"
  },
  {
    "path": "tests/Support/SupportServiceProviderTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Support\\ServiceProvider;\nuse Illuminate\\Translation\\Translator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportServiceProviderTest extends TestCase\n{\n    protected $app;\n    protected string $tempFile;\n\n    protected function setUp(): void\n    {\n        ServiceProvider::$publishes = [];\n        ServiceProvider::$publishGroups = [];\n\n        $this->app = $app = m::mock(Application::class)->makePartial();\n        $config = m::mock(Config::class)->makePartial();\n\n        $config = new Config();\n\n        $app->instance('config', $config);\n        $config->set('database.migrations.update_date_on_publish', true);\n\n        $one = new ServiceProviderForTestingOne($app);\n        $one->boot();\n        $two = new ServiceProviderForTestingTwo($app);\n        $two->boot();\n    }\n\n    protected function tearDown(): void\n    {\n        if (isset($this->tempFile) && file_exists($this->tempFile)) {\n            @unlink($this->tempFile);\n        }\n\n        parent::tearDown();\n    }\n\n    public function testPublishableServiceProviders()\n    {\n        $toPublish = ServiceProvider::publishableProviders();\n        $expected = [\n            ServiceProviderForTestingOne::class,\n            ServiceProviderForTestingTwo::class,\n        ];\n        $this->assertEquals($expected, $toPublish, 'Publishable service providers do not return expected set of providers.');\n    }\n\n    public function testPublishableGroups()\n    {\n        $toPublish = ServiceProvider::publishableGroups();\n        $this->assertEquals([\n            'some_tag',\n            'tag_one',\n            'tag_two',\n            'tag_three',\n            'tag_four',\n            'tag_five',\n        ], $toPublish, 'Publishable groups do not return expected set of groups.');\n    }\n\n    public function testSimpleAssetsArePublishedCorrectly()\n    {\n        $toPublish = ServiceProvider::pathsToPublish(ServiceProviderForTestingOne::class);\n        $this->assertArrayHasKey('source/unmarked/one', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertArrayHasKey('source/tagged/one', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertEquals([\n            'source/unmarked/one' => 'destination/unmarked/one',\n            'source/tagged/one' => 'destination/tagged/one',\n            'source/tagged/multiple' => 'destination/tagged/multiple',\n            'source/unmarked/two' => 'destination/unmarked/two',\n            'source/tagged/three' => 'destination/tagged/three',\n            'source/tagged/multiple_two' => 'destination/tagged/multiple_two',\n        ], $toPublish, 'Service provider does not return expected set of published paths.');\n    }\n\n    public function testMultipleAssetsArePublishedCorrectly()\n    {\n        $toPublish = ServiceProvider::pathsToPublish(ServiceProviderForTestingTwo::class);\n        $this->assertArrayHasKey('source/unmarked/two/a', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertArrayHasKey('source/unmarked/two/b', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertArrayHasKey('source/unmarked/two/c', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertArrayHasKey('source/tagged/two/a', $toPublish, 'Service provider does not return expected published path key.');\n        $this->assertArrayHasKey('source/tagged/two/b', $toPublish, 'Service provider does not return expected published path key.');\n        $expected = [\n            'source/unmarked/two/a' => 'destination/unmarked/two/a',\n            'source/unmarked/two/b' => 'destination/unmarked/two/b',\n            'source/unmarked/two/c' => 'destination/tagged/two/a',\n            'source/tagged/two/a' => 'destination/tagged/two/a',\n            'source/tagged/two/b' => 'destination/tagged/two/b',\n        ];\n        $this->assertEquals($expected, $toPublish, 'Service provider does not return expected set of published paths.');\n    }\n\n    public function testSimpleTaggedAssetsArePublishedCorrectly()\n    {\n        $toPublish = ServiceProvider::pathsToPublish(ServiceProviderForTestingOne::class, 'some_tag');\n        $this->assertArrayNotHasKey('source/tagged/two/a', $toPublish, 'Service provider does return unexpected tagged path key.');\n        $this->assertArrayNotHasKey('source/tagged/two/b', $toPublish, 'Service provider does return unexpected tagged path key.');\n        $this->assertArrayHasKey('source/tagged/one', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertEquals(['source/tagged/one' => 'destination/tagged/one'], $toPublish, 'Service provider does not return expected set of published tagged paths.');\n    }\n\n    public function testMultipleTaggedAssetsArePublishedCorrectly()\n    {\n        $toPublish = ServiceProvider::pathsToPublish(ServiceProviderForTestingTwo::class, 'some_tag');\n        $this->assertArrayHasKey('source/tagged/two/a', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertArrayHasKey('source/tagged/two/b', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertArrayNotHasKey('source/tagged/one', $toPublish, 'Service provider does return unexpected tagged path key.');\n        $this->assertArrayNotHasKey('source/unmarked/two/c', $toPublish, 'Service provider does return unexpected tagged path key.');\n        $expected = [\n            'source/tagged/two/a' => 'destination/tagged/two/a',\n            'source/tagged/two/b' => 'destination/tagged/two/b',\n        ];\n        $this->assertEquals($expected, $toPublish, 'Service provider does not return expected set of published tagged paths.');\n    }\n\n    public function testMultipleTaggedAssetsAreMergedCorrectly()\n    {\n        $toPublish = ServiceProvider::pathsToPublish(null, 'some_tag');\n        $this->assertArrayHasKey('source/tagged/two/a', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertArrayHasKey('source/tagged/two/b', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertArrayHasKey('source/tagged/one', $toPublish, 'Service provider does not return expected tagged path key.');\n        $this->assertArrayNotHasKey('source/unmarked/two/c', $toPublish, 'Service provider does return unexpected tagged path key.');\n        $expected = [\n            'source/tagged/one' => 'destination/tagged/one',\n            'source/tagged/two/a' => 'destination/tagged/two/a',\n            'source/tagged/two/b' => 'destination/tagged/two/b',\n        ];\n        $this->assertEquals($expected, $toPublish, 'Service provider does not return expected set of published tagged paths.');\n    }\n\n    public function testPublishesMigrations()\n    {\n        $serviceProvider = new ServiceProviderForTestingOne($this->app);\n\n        (fn () => $this->publishesMigrations(['source/tagged/four' => 'destination/tagged/four'], 'tag_four'))\n            ->call($serviceProvider);\n\n        $this->assertContains('source/tagged/four', ServiceProvider::publishableMigrationPaths());\n\n        $this->app->config->set('database.migrations.update_date_on_publish', false);\n\n        (fn () => $this->publishesMigrations(['source/tagged/five' => 'destination/tagged/five'], 'tag_four'))\n            ->call($serviceProvider);\n\n        $this->assertNotContains('source/tagged/five', ServiceProvider::publishableMigrationPaths());\n\n        $this->app->config->set('database.migrations', 'migrations');\n\n        (fn () => $this->publishesMigrations(['source/tagged/five' => 'destination/tagged/five'], 'tag_four'))\n            ->call($serviceProvider);\n\n        $this->assertNotContains('source/tagged/five', ServiceProvider::publishableMigrationPaths());\n\n        $this->app->config->set('database.migrations', null);\n\n        (fn () => $this->publishesMigrations(['source/tagged/five' => 'destination/tagged/five'], 'tag_four'))\n            ->call($serviceProvider);\n\n        $this->assertNotContains('source/tagged/five', ServiceProvider::publishableMigrationPaths());\n    }\n\n    public function testLoadTranslationsFromWithoutNamespace()\n    {\n        $translator = m::mock(Translator::class);\n        $translator->shouldReceive('addPath')->once()->with(__DIR__.'/translations');\n\n        $this->app->shouldReceive('afterResolving')->once()->with('translator', m::on(function ($callback) use ($translator) {\n            $callback($translator);\n\n            return true;\n        }));\n\n        $provider = new ServiceProviderForTestingOne($this->app);\n        $provider->loadTranslationsFrom(__DIR__.'/translations');\n    }\n\n    public function testLoadTranslationsFromWithNamespace()\n    {\n        $translator = m::mock(Translator::class);\n        $translator->shouldReceive('addNamespace')->once()->with('namespace', __DIR__.'/translations');\n\n        $this->app->shouldReceive('afterResolving')->once()->with('translator', m::on(function ($callback) use ($translator) {\n            $callback($translator);\n\n            return true;\n        }));\n\n        $provider = new ServiceProviderForTestingOne($this->app);\n        $provider->loadTranslationsFrom(__DIR__.'/translations', 'namespace');\n    }\n\n    public function test_can_remove_provider()\n    {\n        $this->tempFile = __DIR__.'/providers.php';\n        file_put_contents($this->tempFile, $contents = <<< PHP\n<?php\n\nreturn [\n    App\\Providers\\AppServiceProvider::class,\n    App\\Providers\\TelescopeServiceProvider::class,\n];\nPHP\n        );\n        ServiceProvider::removeProviderFromBootstrapFile('TelescopeServiceProvider', $this->tempFile, true);\n\n        // Should have deleted nothing\n        $this->assertStringEqualsStringIgnoringLineEndings($contents, trim(file_get_contents($this->tempFile)));\n\n        // Should delete the telescope provider\n        ServiceProvider::removeProviderFromBootstrapFile('App\\Providers\\TelescopeServiceProvider', $this->tempFile, true);\n\n        $this->assertStringEqualsStringIgnoringLineEndings(<<< PHP\n<?php\n\nreturn [\n    App\\Providers\\AppServiceProvider::class,\n];\nPHP\n            , trim(file_get_contents($this->tempFile)));\n\n        // Should fuzzily delete the App\\Providers\\AppServiceProvider class\n        ServiceProvider::removeProviderFromBootstrapFile('AppServiceProvider', $this->tempFile);\n\n        $this->assertStringEqualsStringIgnoringLineEndings(<<< 'PHP'\n<?php\n\nreturn [\n\n];\nPHP\n            , trim(file_get_contents($this->tempFile)));\n    }\n}\n\nclass ServiceProviderForTestingOne extends ServiceProvider\n{\n    public function register()\n    {\n        //\n    }\n\n    public function boot()\n    {\n        $this->publishes(['source/unmarked/one' => 'destination/unmarked/one']);\n        $this->publishes(['source/tagged/one' => 'destination/tagged/one'], 'some_tag');\n        $this->publishes(['source/tagged/multiple' => 'destination/tagged/multiple'], ['tag_one', 'tag_two']);\n\n        $this->publishesMigrations(['source/unmarked/two' => 'destination/unmarked/two']);\n        $this->publishesMigrations(['source/tagged/three' => 'destination/tagged/three'], 'tag_three');\n        $this->publishesMigrations(['source/tagged/multiple_two' => 'destination/tagged/multiple_two'], ['tag_four', 'tag_five']);\n    }\n\n    public function loadTranslationsFrom($path, $namespace = null)\n    {\n        $this->callAfterResolving('translator', fn ($translator) => is_null($namespace)\n            ? $translator->addPath($path)\n            : $translator->addNamespace($namespace, $path));\n    }\n}\n\nclass ServiceProviderForTestingTwo extends ServiceProvider\n{\n    public function register()\n    {\n        //\n    }\n\n    public function boot()\n    {\n        $this->publishes(['source/unmarked/two/a' => 'destination/unmarked/two/a']);\n        $this->publishes(['source/unmarked/two/b' => 'destination/unmarked/two/b']);\n        $this->publishes(['source/unmarked/two/c' => 'destination/tagged/two/a']);\n        $this->publishes(['source/tagged/two/a' => 'destination/tagged/two/a'], 'some_tag');\n        $this->publishes(['source/tagged/two/b' => 'destination/tagged/two/b'], 'some_tag');\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportStrTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Tests\\Support\\Fixtures\\StringableObjectStub;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Ramsey\\Uuid\\UuidInterface;\nuse ReflectionClass;\nuse ValueError;\n\nclass SupportStrTest extends TestCase\n{\n    /** {@inheritdoc} */\n    #[\\Override]\n    protected function tearDown(): void\n    {\n        Str::createRandomStringsNormally();\n    }\n\n    public function testStringCanBeLimitedByWords(): void\n    {\n        $this->assertSame('Taylor...', Str::words('Taylor Otwell', 1));\n        $this->assertSame('Taylor___', Str::words('Taylor Otwell', 1, '___'));\n        $this->assertSame('Taylor Otwell', Str::words('Taylor Otwell', 3));\n        $this->assertSame('Taylor Otwell', Str::words('Taylor Otwell', -1, '...'));\n        $this->assertSame('', Str::words('', 3, '...'));\n    }\n\n    public function testStringCanBeLimitedByWordsNonAscii()\n    {\n        $this->assertSame('这是...', Str::words('这是 段中文', 1));\n        $this->assertSame('这是___', Str::words('这是 段中文', 1, '___'));\n        $this->assertSame('这是-段中文', Str::words('这是-段中文', 3, '___'));\n        $this->assertSame('这是___', Str::words('这是     段中文', 1, '___'));\n    }\n\n    public function testStringTrimmedOnlyWhereNecessary()\n    {\n        $this->assertSame(' Taylor Otwell ', Str::words(' Taylor Otwell ', 3));\n        $this->assertSame(' Taylor...', Str::words(' Taylor Otwell ', 1));\n    }\n\n    public function testStringTitle()\n    {\n        $this->assertSame('Jefferson Costella', Str::title('jefferson costella'));\n        $this->assertSame('Jefferson Costella', Str::title('jefFErson coSTella'));\n\n        $this->assertSame('', Str::title(''));\n        $this->assertSame('123 Laravel', Str::title('123 laravel'));\n        $this->assertSame('❤Laravel', Str::title('❤laravel'));\n        $this->assertSame('Laravel ❤', Str::title('laravel ❤'));\n        $this->assertSame('Laravel123', Str::title('laravel123'));\n        $this->assertSame('Laravel123', Str::title('Laravel123'));\n\n        $longString = 'lorem ipsum '.str_repeat('dolor sit amet ', 1000);\n        $expectedResult = 'Lorem Ipsum Dolor Sit Amet '.str_repeat('Dolor Sit Amet ', 999);\n        $this->assertSame($expectedResult, Str::title($longString));\n    }\n\n    public function testStringHeadline()\n    {\n        $this->assertSame('Jefferson Costella', Str::headline('jefferson costella'));\n        $this->assertSame('Jefferson Costella', Str::headline('jefFErson coSTella'));\n        $this->assertSame('Jefferson Costella Uses Laravel', Str::headline('jefferson_costella uses-_Laravel'));\n        $this->assertSame('Jefferson Costella Uses Laravel', Str::headline('jefferson_costella uses__Laravel'));\n\n        $this->assertSame('Laravel P H P Framework', Str::headline('laravel_p_h_p_framework'));\n        $this->assertSame('Laravel P H P Framework', Str::headline('laravel _p _h _p _framework'));\n        $this->assertSame('Laravel Php Framework', Str::headline('laravel_php_framework'));\n        $this->assertSame('Laravel Ph P Framework', Str::headline('laravel-phP-framework'));\n        $this->assertSame('Laravel Php Framework', Str::headline('laravel  -_-  php   -_-   framework   '));\n\n        $this->assertSame('Foo Bar', Str::headline('fooBar'));\n        $this->assertSame('Foo Bar', Str::headline('foo_bar'));\n        $this->assertSame('Foo Bar Baz', Str::headline('foo-barBaz'));\n        $this->assertSame('Foo Bar Baz', Str::headline('foo-bar_baz'));\n\n        $this->assertSame('Öffentliche Überraschungen', Str::headline('öffentliche-überraschungen'));\n        $this->assertSame('Öffentliche Überraschungen', Str::headline('-_öffentliche_überraschungen_-'));\n        $this->assertSame('Öffentliche Überraschungen', Str::headline('-öffentliche überraschungen'));\n\n        $this->assertSame('Sind Öde Und So', Str::headline('sindÖdeUndSo'));\n\n        $this->assertSame('Orwell 1984', Str::headline('orwell 1984'));\n        $this->assertSame('Orwell 1984', Str::headline('orwell   1984'));\n        $this->assertSame('Orwell 1984', Str::headline('-orwell-1984 -'));\n        $this->assertSame('Orwell 1984', Str::headline(' orwell_- 1984 '));\n    }\n\n    public function testStringInitials()\n    {\n        $this->assertSame('jb', Str::initials('james bond'));\n        $this->assertSame('jb', Str::initials(' james bond'));\n        $this->assertSame('jb', Str::initials('james  bond'));\n\n        $this->assertSame('JB', Str::initials('James Bond'));\n\n        $this->assertSame('JB', Str::initials('james bond', true));\n\n        $this->assertSame('JBLL', Str::initials('james bond loves laravel', true));\n    }\n\n    public function testStringApa()\n    {\n        $this->assertSame('Tom and Jerry', Str::apa('tom and jerry'));\n        $this->assertSame('Tom and Jerry', Str::apa('TOM AND JERRY'));\n        $this->assertSame('Tom and Jerry', Str::apa('Tom And Jerry'));\n\n        $this->assertSame('Back to the Future', Str::apa('back to the future'));\n        $this->assertSame('Back to the Future', Str::apa('BACK TO THE FUTURE'));\n        $this->assertSame('Back to the Future', Str::apa('Back To The Future'));\n\n        $this->assertSame('This, Then That', Str::apa('this, then that'));\n        $this->assertSame('This, Then That', Str::apa('THIS, THEN THAT'));\n        $this->assertSame('This, Then That', Str::apa('This, Then That'));\n\n        $this->assertSame('Bond. James Bond.', Str::apa('bond. james bond.'));\n        $this->assertSame('Bond. James Bond.', Str::apa('BOND. JAMES BOND.'));\n        $this->assertSame('Bond. James Bond.', Str::apa('Bond. James Bond.'));\n\n        $this->assertSame('Self-Report', Str::apa('self-report'));\n        $this->assertSame('Self-Report', Str::apa('Self-report'));\n        $this->assertSame('Self-Report', Str::apa('SELF-REPORT'));\n\n        $this->assertSame('As the World Turns, So Are the Days of Our Lives', Str::apa('as the world turns, so are the days of our lives'));\n        $this->assertSame('As the World Turns, So Are the Days of Our Lives', Str::apa('AS THE WORLD TURNS, SO ARE THE DAYS OF OUR LIVES'));\n        $this->assertSame('As the World Turns, So Are the Days of Our Lives', Str::apa('As The World Turns, So Are The Days Of Our Lives'));\n\n        $this->assertSame('To Kill a Mockingbird', Str::apa('to kill a mockingbird'));\n        $this->assertSame('To Kill a Mockingbird', Str::apa('TO KILL A MOCKINGBIRD'));\n        $this->assertSame('To Kill a Mockingbird', Str::apa('To Kill A Mockingbird'));\n\n        $this->assertSame('Être Écrivain Commence par Être un Lecteur.', Str::apa('Être écrivain commence par être un lecteur.'));\n        $this->assertSame('Être Écrivain Commence par Être un Lecteur.', Str::apa('Être Écrivain Commence par Être un Lecteur.'));\n        $this->assertSame('Être Écrivain Commence par Être un Lecteur.', Str::apa('ÊTRE ÉCRIVAIN COMMENCE PAR ÊTRE UN LECTEUR.'));\n\n        $this->assertSame(\"C'est-à-Dire.\", Str::apa(\"c'est-à-dire.\"));\n        $this->assertSame(\"C'est-à-Dire.\", Str::apa(\"C'est-à-Dire.\"));\n        $this->assertSame(\"C'est-à-Dire.\", Str::apa(\"C'EsT-À-DIRE.\"));\n\n        $this->assertSame('Устное Слово – Не Воробей. Как Только Он Вылетит, Его Не Поймаешь.', Str::apa('устное слово – не воробей. как только он вылетит, его не поймаешь.'));\n        $this->assertSame('Устное Слово – Не Воробей. Как Только Он Вылетит, Его Не Поймаешь.', Str::apa('Устное Слово – Не Воробей. Как Только Он Вылетит, Его Не Поймаешь.'));\n        $this->assertSame('Устное Слово – Не Воробей. Как Только Он Вылетит, Его Не Поймаешь.', Str::apa('УСТНОЕ СЛОВО – НЕ ВОРОБЕЙ. КАК ТОЛЬКО ОН ВЫЛЕТИТ, ЕГО НЕ ПОЙМАЕШЬ.'));\n\n        $this->assertSame('', Str::apa(''));\n        $this->assertSame('   ', Str::apa('   '));\n    }\n\n    public function testStringWithoutWordsDoesntProduceError(): void\n    {\n        $nbsp = chr(0xC2).chr(0xA0);\n        $this->assertSame(' ', Str::words(' '));\n        $this->assertEquals($nbsp, Str::words($nbsp));\n        $this->assertSame('   ', Str::words('   '));\n        $this->assertSame(\"\\t\\t\\t\", Str::words(\"\\t\\t\\t\"));\n    }\n\n    public function testStringAscii(): void\n    {\n        $this->assertSame('@', Str::ascii('@'));\n        $this->assertSame('u', Str::ascii('ü'));\n        $this->assertSame('', Str::ascii(''));\n        $this->assertSame('a!2e', Str::ascii('a!2ë'));\n    }\n\n    public function testStringAsciiWithSpecificLocale()\n    {\n        $this->assertSame('h H sht Sht a A ia yo', Str::ascii('х Х щ Щ ъ Ъ иа йо', 'bg'));\n        $this->assertSame('ae oe ue Ae Oe Ue', Str::ascii('ä ö ü Ä Ö Ü', 'de'));\n    }\n\n    public function testStartsWith()\n    {\n        $this->assertTrue(Str::startsWith('jason', 'jas'));\n        $this->assertTrue(Str::startsWith('jason', 'jason'));\n        $this->assertTrue(Str::startsWith('jason', ['jas']));\n        $this->assertTrue(Str::startsWith('jason', ['day', 'jas']));\n        $this->assertTrue(Str::startsWith('jason', collect(['day', 'jas'])));\n        $this->assertFalse(Str::startsWith('jason', 'day'));\n        $this->assertFalse(Str::startsWith('jason', ['day']));\n        $this->assertFalse(Str::startsWith('jason', null));\n        $this->assertFalse(Str::startsWith('jason', [null]));\n        $this->assertFalse(Str::startsWith('0123', [null]));\n        $this->assertTrue(Str::startsWith('0123', 0));\n        $this->assertFalse(Str::startsWith('jason', 'J'));\n        $this->assertFalse(Str::startsWith('jason', ''));\n        $this->assertFalse(Str::startsWith('', ''));\n        $this->assertFalse(Str::startsWith('7', ' 7'));\n        $this->assertTrue(Str::startsWith('7a', '7'));\n        $this->assertTrue(Str::startsWith('7a', 7));\n        $this->assertTrue(Str::startsWith('7.12a', 7.12));\n        $this->assertFalse(Str::startsWith('7.12a', 7.13));\n        $this->assertTrue(Str::startsWith(7.123, '7'));\n        $this->assertTrue(Str::startsWith(7.123, '7.12'));\n        $this->assertFalse(Str::startsWith(7.123, '7.13'));\n        $this->assertFalse(Str::startsWith(null, 'Marc'));\n        // Test for multibyte string support\n        $this->assertTrue(Str::startsWith('Jönköping', 'Jö'));\n        $this->assertTrue(Str::startsWith('Malmö', 'Malmö'));\n        $this->assertFalse(Str::startsWith('Jönköping', 'Jonko'));\n        $this->assertFalse(Str::startsWith('Malmö', 'Malmo'));\n        $this->assertTrue(Str::startsWith('你好', '你'));\n        $this->assertFalse(Str::startsWith('你好', '好'));\n        $this->assertFalse(Str::startsWith('你好', 'a'));\n    }\n\n    public function testDoesntStartWith()\n    {\n        $this->assertFalse(Str::doesntStartWith('jason', 'jas'));\n        $this->assertFalse(Str::doesntStartWith('jason', 'jason'));\n        $this->assertFalse(Str::doesntStartWith('jason', ['jas']));\n        $this->assertFalse(Str::doesntStartWith('jason', ['day', 'jas']));\n        $this->assertFalse(Str::doesntStartWith('jason', collect(['day', 'jas'])));\n        $this->assertTrue(Str::doesntStartWith('jason', 'day'));\n        $this->assertTrue(Str::doesntStartWith('jason', ['day']));\n        $this->assertTrue(Str::doesntStartWith('jason', null));\n        $this->assertTrue(Str::doesntStartWith('jason', [null]));\n        $this->assertTrue(Str::doesntStartWith('0123', [null]));\n        $this->assertFalse(Str::doesntStartWith('0123', 0));\n        $this->assertTrue(Str::doesntStartWith('jason', 'J'));\n        $this->assertTrue(Str::doesntStartWith('jason', ''));\n        $this->assertTrue(Str::doesntStartWith('', ''));\n        $this->assertTrue(Str::doesntStartWith('7', ' 7'));\n        $this->assertFalse(Str::doesntStartWith('7a', '7'));\n        $this->assertFalse(Str::doesntStartWith('7a', 7));\n        $this->assertFalse(Str::doesntStartWith('7.12a', 7.12));\n        $this->assertTrue(Str::doesntStartWith('7.12a', 7.13));\n        $this->assertFalse(Str::doesntStartWith(7.123, '7'));\n        $this->assertFalse(Str::doesntStartWith(7.123, '7.12'));\n        $this->assertTrue(Str::doesntStartWith(7.123, '7.13'));\n        $this->assertTrue(Str::doesntStartWith(null, 'Marc'));\n        // Test for multibyte string support\n        $this->assertFalse(Str::doesntStartWith('Jönköping', 'Jö'));\n        $this->assertFalse(Str::doesntStartWith('Malmö', 'Malmö'));\n        $this->assertTrue(Str::doesntStartWith('Jönköping', 'Jonko'));\n        $this->assertTrue(Str::doesntStartWith('Malmö', 'Malmo'));\n        $this->assertFalse(Str::doesntStartWith('你好', '你'));\n        $this->assertTrue(Str::doesntStartWith('你好', '好'));\n        $this->assertTrue(Str::doesntStartWith('你好', 'a'));\n    }\n\n    public function testEndsWith()\n    {\n        $this->assertTrue(Str::endsWith('jason', 'on'));\n        $this->assertTrue(Str::endsWith('jason', 'jason'));\n        $this->assertTrue(Str::endsWith('jason', ['on']));\n        $this->assertTrue(Str::endsWith('jason', ['no', 'on']));\n        $this->assertTrue(Str::endsWith('jason', collect(['no', 'on'])));\n        $this->assertFalse(Str::endsWith('jason', 'no'));\n        $this->assertFalse(Str::endsWith('jason', ['no']));\n        $this->assertFalse(Str::endsWith('jason', ''));\n        $this->assertFalse(Str::endsWith('', ''));\n        $this->assertFalse(Str::endsWith('jason', [null]));\n        $this->assertFalse(Str::endsWith('jason', null));\n        $this->assertFalse(Str::endsWith('jason', 'N'));\n        $this->assertFalse(Str::endsWith('7', ' 7'));\n        $this->assertTrue(Str::endsWith('a7', '7'));\n        $this->assertTrue(Str::endsWith('a7', 7));\n        $this->assertTrue(Str::endsWith('a7.12', 7.12));\n        $this->assertFalse(Str::endsWith('a7.12', 7.13));\n        $this->assertTrue(Str::endsWith(0.27, '7'));\n        $this->assertTrue(Str::endsWith(0.27, '0.27'));\n        $this->assertFalse(Str::endsWith(0.27, '8'));\n        $this->assertFalse(Str::endsWith(null, 'Marc'));\n        // Test for multibyte string support\n        $this->assertTrue(Str::endsWith('Jönköping', 'öping'));\n        $this->assertTrue(Str::endsWith('Malmö', 'mö'));\n        $this->assertFalse(Str::endsWith('Jönköping', 'oping'));\n        $this->assertFalse(Str::endsWith('Malmö', 'mo'));\n        $this->assertTrue(Str::endsWith('你好', '好'));\n        $this->assertFalse(Str::endsWith('你好', '你'));\n        $this->assertFalse(Str::endsWith('你好', 'a'));\n    }\n\n    public function testDoesntEndWith()\n    {\n        $this->assertFalse(Str::doesntEndWith('jason', 'on'));\n        $this->assertFalse(Str::doesntEndWith('jason', 'jason'));\n        $this->assertFalse(Str::doesntEndWith('jason', ['on']));\n        $this->assertFalse(Str::doesntEndWith('jason', ['no', 'on']));\n        $this->assertFalse(Str::doesntEndWith('jason', collect(['no', 'on'])));\n        $this->assertTrue(Str::doesntEndWith('jason', 'no'));\n        $this->assertTrue(Str::doesntEndWith('jason', ['no']));\n        $this->assertTrue(Str::doesntEndWith('jason', ''));\n        $this->assertTrue(Str::doesntEndWith('', ''));\n        $this->assertTrue(Str::doesntEndWith('jason', [null]));\n        $this->assertTrue(Str::doesntEndWith('jason', null));\n        $this->assertTrue(Str::doesntEndWith('jason', 'N'));\n        $this->assertTrue(Str::doesntEndWith('7', ' 7'));\n        $this->assertFalse(Str::doesntEndWith('a7', '7'));\n        $this->assertFalse(Str::doesntEndWith('a7', 7));\n        $this->assertFalse(Str::doesntEndWith('a7.12', 7.12));\n        $this->assertTrue(Str::doesntEndWith('a7.12', 7.13));\n        $this->assertFalse(Str::doesntEndWith(0.27, '7'));\n        $this->assertFalse(Str::doesntEndWith(0.27, '0.27'));\n        $this->assertTrue(Str::doesntEndWith(0.27, '8'));\n        $this->assertTrue(Str::doesntEndWith(null, 'Marc'));\n        // Test for multibyte string support\n        $this->assertFalse(Str::doesntEndWith('Jönköping', 'öping'));\n        $this->assertFalse(Str::doesntEndWith('Malmö', 'mö'));\n        $this->assertTrue(Str::doesntEndWith('Jönköping', 'oping'));\n        $this->assertTrue(Str::doesntEndWith('Malmö', 'mo'));\n        $this->assertFalse(Str::doesntEndWith('你好', '好'));\n        $this->assertTrue(Str::doesntEndWith('你好', '你'));\n        $this->assertTrue(Str::doesntEndWith('你好', 'a'));\n    }\n\n    public function testStrExcerpt()\n    {\n        $this->assertSame('...is a beautiful morn...', Str::excerpt('This is a beautiful morning', 'beautiful', ['radius' => 5]));\n        $this->assertSame('This is a...', Str::excerpt('This is a beautiful morning', 'this', ['radius' => 5]));\n        $this->assertSame('...iful morning', Str::excerpt('This is a beautiful morning', 'morning', ['radius' => 5]));\n        $this->assertNull(Str::excerpt('This is a beautiful morning', 'day'));\n        $this->assertSame('...is a beautiful! mor...', Str::excerpt('This is a beautiful! morning', 'Beautiful', ['radius' => 5]));\n        $this->assertSame('...is a beautiful? mor...', Str::excerpt('This is a beautiful? morning', 'beautiful', ['radius' => 5]));\n        $this->assertSame('', Str::excerpt('', '', ['radius' => 0]));\n        $this->assertSame('a', Str::excerpt('a', 'a', ['radius' => 0]));\n        $this->assertSame('...b...', Str::excerpt('abc', 'B', ['radius' => 0]));\n        $this->assertSame('abc', Str::excerpt('abc', 'b', ['radius' => 1]));\n        $this->assertSame('abc...', Str::excerpt('abcd', 'b', ['radius' => 1]));\n        $this->assertSame('...abc', Str::excerpt('zabc', 'b', ['radius' => 1]));\n        $this->assertSame('...abc...', Str::excerpt('zabcd', 'b', ['radius' => 1]));\n        $this->assertSame('zabcd', Str::excerpt('zabcd', 'b', ['radius' => 2]));\n        $this->assertSame('zabcd', Str::excerpt('  zabcd  ', 'b', ['radius' => 4]));\n        $this->assertSame('...abc...', Str::excerpt('z  abc  d', 'b', ['radius' => 1]));\n        $this->assertSame('[...]is a beautiful morn[...]', Str::excerpt('This is a beautiful morning', 'beautiful', ['omission' => '[...]', 'radius' => 5]));\n        $this->assertSame(\n            'This is the ultimate supercalifragilisticexpialidocious very looooooooooooooooooong looooooooooooong beautiful morning with amazing sunshine and awesome tempera[...]',\n            Str::excerpt('This is the ultimate supercalifragilisticexpialidocious very looooooooooooooooooong looooooooooooong beautiful morning with amazing sunshine and awesome temperatures. So what are you gonna do about it?', 'very',\n                ['omission' => '[...]'],\n            ));\n\n        $this->assertSame('...y...', Str::excerpt('taylor', 'y', ['radius' => 0]));\n        $this->assertSame('...ayl...', Str::excerpt('taylor', 'Y', ['radius' => 1]));\n        $this->assertSame('<div> The article description </div>', Str::excerpt('<div> The article description </div>', 'article'));\n        $this->assertSame('...The article desc...', Str::excerpt('<div> The article description </div>', 'article', ['radius' => 5]));\n        $this->assertSame('The article description', Str::excerpt(strip_tags('<div> The article description </div>'), 'article'));\n        $this->assertSame('', Str::excerpt(null));\n        $this->assertSame('', Str::excerpt(''));\n        $this->assertSame('', Str::excerpt(null, ''));\n        $this->assertSame('T...', Str::excerpt('The article description', null, ['radius' => 1]));\n        $this->assertSame('The arti...', Str::excerpt('The article description', '', ['radius' => 8]));\n        $this->assertSame('', Str::excerpt(' '));\n        $this->assertSame('The arti...', Str::excerpt('The article description', ' ', ['radius' => 4]));\n        $this->assertSame('...cle description', Str::excerpt('The article description', 'description', ['radius' => 4]));\n        $this->assertSame('T...', Str::excerpt('The article description', 'T', ['radius' => 0]));\n        $this->assertSame('What i?', Str::excerpt('What is the article?', 'What', ['radius' => 2, 'omission' => '?']));\n\n        $this->assertSame('...ö - 二 sān 大åè...', Str::excerpt('åèö - 二 sān 大åèö', '二 sān', ['radius' => 4]));\n        $this->assertSame('åèö - 二...', Str::excerpt('åèö - 二 sān 大åèö', 'åèö', ['radius' => 4]));\n        $this->assertSame('åèö - 二 sān 大åèö', Str::excerpt('åèö - 二 sān 大åèö', 'åèö - 二 sān 大åèö', ['radius' => 4]));\n        $this->assertSame('åèö - 二 sān 大åèö', Str::excerpt('åèö - 二 sān 大åèö', 'åèö - 二 sān 大åèö', ['radius' => 4]));\n        $this->assertSame('...༼...', Str::excerpt('㏗༼㏗', '༼', ['radius' => 0]));\n        $this->assertSame('...༼...', Str::excerpt('㏗༼㏗', '༼', ['radius' => 0]));\n        $this->assertSame('...ocê e...', Str::excerpt('Como você está', 'ê', ['radius' => 2]));\n        $this->assertSame('...ocê e...', Str::excerpt('Como você está', 'Ê', ['radius' => 2]));\n        $this->assertSame('João...', Str::excerpt('João Antônio ', 'jo', ['radius' => 2]));\n        $this->assertSame('João Antô...', Str::excerpt('João Antônio', 'JOÃO', ['radius' => 5]));\n        $this->assertNull(Str::excerpt('', '/'));\n    }\n\n    public function testStrBefore(): void\n    {\n        $this->assertSame('han', Str::before('hannah', 'nah'));\n        $this->assertSame('ha', Str::before('hannah', 'n'));\n        $this->assertSame('ééé ', Str::before('ééé hannah', 'han'));\n        $this->assertSame('hannah', Str::before('hannah', 'xxxx'));\n        $this->assertSame('hannah', Str::before('hannah', ''));\n        $this->assertSame('han', Str::before('han0nah', '0'));\n        $this->assertSame('han', Str::before('han0nah', 0));\n        $this->assertSame('han', Str::before('han2nah', 2));\n        $this->assertSame('', Str::before('', ''));\n        $this->assertSame('', Str::before('', 'a'));\n        $this->assertSame('', Str::before('a', 'a'));\n        $this->assertSame('foo', Str::before('foo@bar.com', '@'));\n        $this->assertSame('foo', Str::before('foo@@bar.com', '@'));\n        $this->assertSame('', Str::before('@foo@bar.com', '@'));\n    }\n\n    public function testStrBeforeLast(): void\n    {\n        $this->assertSame('yve', Str::beforeLast('yvette', 'tte'));\n        $this->assertSame('yvet', Str::beforeLast('yvette', 't'));\n        $this->assertSame('ééé ', Str::beforeLast('ééé yvette', 'yve'));\n        $this->assertSame('', Str::beforeLast('yvette', 'yve'));\n        $this->assertSame('yvette', Str::beforeLast('yvette', 'xxxx'));\n        $this->assertSame('yvette', Str::beforeLast('yvette', ''));\n        $this->assertSame('yv0et', Str::beforeLast('yv0et0te', '0'));\n        $this->assertSame('yv0et', Str::beforeLast('yv0et0te', 0));\n        $this->assertSame('yv2et', Str::beforeLast('yv2et2te', 2));\n        $this->assertSame('', Str::beforeLast('', 'test'));\n        $this->assertSame('', Str::beforeLast('yvette', 'yvette'));\n        $this->assertSame('laravel', Str::beforeLast('laravel framework', ' '));\n        $this->assertSame('yvette', Str::beforeLast(\"yvette\\tyv0et0te\", \"\\t\"));\n    }\n\n    public function testStrBetween(): void\n    {\n        $this->assertSame('abc', Str::between('abc', '', 'c'));\n        $this->assertSame('abc', Str::between('abc', 'a', ''));\n        $this->assertSame('abc', Str::between('abc', '', ''));\n        $this->assertSame('b', Str::between('abc', 'a', 'c'));\n        $this->assertSame('b', Str::between('dddabc', 'a', 'c'));\n        $this->assertSame('b', Str::between('abcddd', 'a', 'c'));\n        $this->assertSame('b', Str::between('dddabcddd', 'a', 'c'));\n        $this->assertSame('nn', Str::between('hannah', 'ha', 'ah'));\n        $this->assertSame('a]ab[b', Str::between('[a]ab[b]', '[', ']'));\n        $this->assertSame('foo', Str::between('foofoobar', 'foo', 'bar'));\n        $this->assertSame('bar', Str::between('foobarbar', 'foo', 'bar'));\n        $this->assertSame('234', Str::between('12345', 1, 5));\n        $this->assertSame('45', Str::between('123456789', '123', '6789'));\n        $this->assertSame('nothing', Str::between('nothing', 'foo', 'bar'));\n    }\n\n    public function testStrBetweenFirst()\n    {\n        $this->assertSame('abc', Str::betweenFirst('abc', '', 'c'));\n        $this->assertSame('abc', Str::betweenFirst('abc', 'a', ''));\n        $this->assertSame('abc', Str::betweenFirst('abc', '', ''));\n        $this->assertSame('b', Str::betweenFirst('abc', 'a', 'c'));\n        $this->assertSame('b', Str::betweenFirst('dddabc', 'a', 'c'));\n        $this->assertSame('b', Str::betweenFirst('abcddd', 'a', 'c'));\n        $this->assertSame('b', Str::betweenFirst('dddabcddd', 'a', 'c'));\n        $this->assertSame('nn', Str::betweenFirst('hannah', 'ha', 'ah'));\n        $this->assertSame('a', Str::betweenFirst('[a]ab[b]', '[', ']'));\n        $this->assertSame('foo', Str::betweenFirst('foofoobar', 'foo', 'bar'));\n        $this->assertSame('', Str::betweenFirst('foobarbar', 'foo', 'bar'));\n    }\n\n    public function testStrAfter()\n    {\n        $this->assertSame('nah', Str::after('hannah', 'han'));\n        $this->assertSame('nah', Str::after('hannah', 'n'));\n        $this->assertSame('nah', Str::after('ééé hannah', 'han'));\n        $this->assertSame('hannah', Str::after('hannah', 'xxxx'));\n        $this->assertSame('hannah', Str::after('hannah', ''));\n        $this->assertSame('nah', Str::after('han0nah', '0'));\n        $this->assertSame('nah', Str::after('han0nah', 0));\n        $this->assertSame('nah', Str::after('han2nah', 2));\n    }\n\n    public function testStrAfterLast()\n    {\n        $this->assertSame('tte', Str::afterLast('yvette', 'yve'));\n        $this->assertSame('e', Str::afterLast('yvette', 't'));\n        $this->assertSame('e', Str::afterLast('ééé yvette', 't'));\n        $this->assertSame('', Str::afterLast('yvette', 'tte'));\n        $this->assertSame('yvette', Str::afterLast('yvette', 'xxxx'));\n        $this->assertSame('yvette', Str::afterLast('yvette', ''));\n        $this->assertSame('te', Str::afterLast('yv0et0te', '0'));\n        $this->assertSame('te', Str::afterLast('yv0et0te', 0));\n        $this->assertSame('te', Str::afterLast('yv2et2te', 2));\n        $this->assertSame('foo', Str::afterLast('----foo', '---'));\n        // Test with multibyte characters in search string\n        $this->assertSame('', Str::afterLast('café au café', 'café'));\n        $this->assertSame('', Str::afterLast('こんにちは世界こんにちは', 'こんにちは'));\n    }\n\n    #[DataProvider('strContainsProvider')]\n    public function testStrContains($haystack, $needles, $expected, $ignoreCase = false)\n    {\n        $this->assertEquals($expected, Str::contains($haystack, $needles, $ignoreCase));\n    }\n\n    #[DataProvider('strContainsAllProvider')]\n    public function testStrContainsAll($haystack, $needles, $expected, $ignoreCase = false)\n    {\n        $this->assertEquals($expected, Str::containsAll($haystack, $needles, $ignoreCase));\n    }\n\n    #[DataProvider('strDoesntContainProvider')]\n    public function testStrDoesntContain($haystack, $needles, $expected, $ignoreCase = false)\n    {\n        $this->assertEquals($expected, Str::doesntContain($haystack, $needles, $ignoreCase));\n    }\n\n    public function testConvertCase()\n    {\n        // Upper Case Conversion\n        $this->assertSame('HELLO', Str::convertCase('hello', MB_CASE_UPPER));\n        $this->assertSame('WORLD', Str::convertCase('WORLD', MB_CASE_UPPER));\n\n        // Lower Case Conversion\n        $this->assertSame('hello', Str::convertCase('HELLO', MB_CASE_LOWER));\n        $this->assertSame('world', Str::convertCase('WORLD', MB_CASE_LOWER));\n\n        // Case Folding\n        $this->assertSame('hello', Str::convertCase('HeLLo', MB_CASE_FOLD));\n        $this->assertSame('world', Str::convertCase('WoRLD', MB_CASE_FOLD));\n\n        // Multi-byte String\n        $this->assertSame('ÜÖÄ', Str::convertCase('üöä', MB_CASE_UPPER, 'UTF-8'));\n        $this->assertSame('üöä', Str::convertCase('ÜÖÄ', MB_CASE_LOWER, 'UTF-8'));\n\n        // Unsupported Mode\n        $this->expectException(\\ValueError::class);\n        Str::convertCase('Hello', -1);\n    }\n\n    public function testDedup()\n    {\n        $this->assertSame(' laravel php framework ', Str::deduplicate(' laravel   php  framework '));\n        $this->assertSame('what', Str::deduplicate('whaaat', 'a'));\n        $this->assertSame('/some/odd/path/', Str::deduplicate('/some//odd//path/', '/'));\n        $this->assertSame('ムだム', Str::deduplicate('ムだだム', 'だ'));\n        $this->assertSame(' laravel forever ', Str::deduplicate(' laravell    foreverrr  ', [' ', 'l', 'r']));\n    }\n\n    public function testParseCallback()\n    {\n        $this->assertEquals(['Class', 'method'], Str::parseCallback('Class@method'));\n        $this->assertEquals(['Class', 'method'], Str::parseCallback('Class@method', 'foo'));\n        $this->assertEquals(['Class', 'foo'], Str::parseCallback('Class', 'foo'));\n        $this->assertEquals(['Class', null], Str::parseCallback('Class'));\n\n        $this->assertEquals([\"Class@anonymous\\0/laravel/382.php:8$2ec\", 'method'], Str::parseCallback(\"Class@anonymous\\0/laravel/382.php:8$2ec@method\"));\n        $this->assertEquals([\"Class@anonymous\\0/laravel/382.php:8$2ec\", 'method'], Str::parseCallback(\"Class@anonymous\\0/laravel/382.php:8$2ec@method\", 'foo'));\n        $this->assertEquals([\"Class@anonymous\\0/laravel/382.php:8$2ec\", 'foo'], Str::parseCallback(\"Class@anonymous\\0/laravel/382.php:8$2ec\", 'foo'));\n        $this->assertEquals([\"Class@anonymous\\0/laravel/382.php:8$2ec\", null], Str::parseCallback(\"Class@anonymous\\0/laravel/382.php:8$2ec\"));\n    }\n\n    public function testSlug()\n    {\n        $this->assertSame('hello-world', Str::slug('hello world'));\n        $this->assertSame('hello-world', Str::slug('hello-world'));\n        $this->assertSame('hello-world', Str::slug('hello_world'));\n        $this->assertSame('hello_world', Str::slug('hello_world', '_'));\n        $this->assertSame('user-at-host', Str::slug('user@host'));\n        $this->assertSame('سلام-دنیا', Str::slug('سلام دنیا', '-', null));\n        $this->assertSame('sometext', Str::slug('some text', ''));\n        $this->assertSame('', Str::slug('', ''));\n        $this->assertSame('', Str::slug(''));\n        $this->assertSame('bsm-allah', Str::slug('بسم الله', '-', 'en', ['allh' => 'allah']));\n        $this->assertSame('500-dollar-bill', Str::slug('500$ bill', '-', 'en', ['$' => 'dollar']));\n        $this->assertSame('500-dollar-bill', Str::slug('500--$----bill', '-', 'en', ['$' => 'dollar']));\n        $this->assertSame('500-dollar-bill', Str::slug('500-$-bill', '-', 'en', ['$' => 'dollar']));\n        $this->assertSame('500-dollar-bill', Str::slug('500$--bill', '-', 'en', ['$' => 'dollar']));\n        $this->assertSame('500-dollar-bill', Str::slug('500-$--bill', '-', 'en', ['$' => 'dollar']));\n        $this->assertSame('أحمد-في-المدرسة', Str::slug('أحمد@المدرسة', '-', null, ['@' => 'في']));\n    }\n\n    public function testStrStart()\n    {\n        $this->assertSame('/test/string', Str::start('test/string', '/'));\n        $this->assertSame('/test/string', Str::start('/test/string', '/'));\n        $this->assertSame('/test/string', Str::start('//test/string', '/'));\n    }\n\n    public function testFlushCache()\n    {\n        $reflection = new ReflectionClass(Str::class);\n        $property = $reflection->getProperty('snakeCache');\n\n        Str::flushCache();\n        $this->assertEmpty($property->getValue());\n\n        Str::snake('Taylor Otwell');\n        $this->assertNotEmpty($property->getValue());\n\n        Str::flushCache();\n        $this->assertEmpty($property->getValue());\n    }\n\n    public function testFinish()\n    {\n        $this->assertSame('abbc', Str::finish('ab', 'bc'));\n        $this->assertSame('abbc', Str::finish('abbcbc', 'bc'));\n        $this->assertSame('abcbbc', Str::finish('abcbbcbc', 'bc'));\n    }\n\n    public function testWrap()\n    {\n        $this->assertEquals('\"value\"', Str::wrap('value', '\"'));\n        $this->assertEquals('foo-bar-baz', Str::wrap('-bar-', 'foo', 'baz'));\n    }\n\n    public function testWrapEdgeCases()\n    {\n        $this->assertSame('[]mid[]', Str::wrap('mid', '[]'));\n        $this->assertSame('(mid', Str::wrap('mid', '(', ''));\n        $this->assertSame('<mid<', Str::wrap('mid', '<'));\n        $this->assertSame('value', Str::wrap('value', ''));\n        $this->assertSame('[][]', Str::wrap('', '[]'));\n        $this->assertSame('«値»', Str::wrap('値', '«', '»'));\n        $this->assertSame('🧪X🧪', Str::wrap('X', '🧪'));\n    }\n\n    public function testUnwrap()\n    {\n        $this->assertEquals('value', Str::unwrap('\"value\"', '\"'));\n        $this->assertEquals('value', Str::unwrap('\"value', '\"'));\n        $this->assertEquals('value', Str::unwrap('value\"', '\"'));\n        $this->assertEquals('bar', Str::unwrap('foo-bar-baz', 'foo-', '-baz'));\n        $this->assertEquals('some: \"json\"', Str::unwrap('{some: \"json\"}', '{', '}'));\n    }\n\n    public function testIs()\n    {\n        $this->assertTrue(Str::is('/', '/'));\n        $this->assertFalse(Str::is('/', ' /'));\n        $this->assertFalse(Str::is('/', '/a'));\n        $this->assertTrue(Str::is('foo/*', 'foo/bar/baz'));\n\n        $this->assertTrue(Str::is('*@*', 'App\\Class@method'));\n        $this->assertTrue(Str::is('*@*', 'app\\Class@'));\n        $this->assertTrue(Str::is('*@*', '@method'));\n\n        // is case sensitive\n        $this->assertFalse(Str::is('*BAZ*', 'foo/bar/baz'));\n        $this->assertFalse(Str::is('*FOO*', 'foo/bar/baz'));\n        $this->assertFalse(Str::is('A', 'a'));\n\n        // is not case sensitive\n        $this->assertTrue(Str::is('A', 'a', true));\n        $this->assertTrue(Str::is('*BAZ*', 'foo/bar/baz', true));\n        $this->assertTrue(Str::is(['A*', 'B*'], 'a/', true));\n        $this->assertFalse(Str::is(['A*', 'B*'], 'f/', true));\n        $this->assertTrue(Str::is('FOO', 'foo', true));\n        $this->assertTrue(Str::is('*FOO*', 'foo/bar/baz', true));\n        $this->assertTrue(Str::is('foo/*', 'FOO/bar', true));\n\n        // Accepts array of patterns\n        $this->assertTrue(Str::is(['a*', 'b*'], 'a/'));\n        $this->assertTrue(Str::is(['a*', 'b*'], 'b/'));\n        $this->assertFalse(Str::is(['a*', 'b*'], 'f/'));\n\n        // numeric values and patterns\n        $this->assertFalse(Str::is(['a*', 'b*'], 123));\n        $this->assertTrue(Str::is(['*2*', 'b*'], 11211));\n\n        $this->assertTrue(Str::is('*/foo', 'blah/baz/foo'));\n\n        $valueObject = new StringableObjectStub('foo/bar/baz');\n        $patternObject = new StringableObjectStub('foo/*');\n\n        $this->assertTrue(Str::is('foo/bar/baz', $valueObject));\n        $this->assertTrue(Str::is($patternObject, $valueObject));\n\n        // empty patterns\n        $this->assertFalse(Str::is([], 'test'));\n\n        $this->assertFalse(Str::is('', 0));\n        $this->assertFalse(Str::is([null], 0));\n        $this->assertTrue(Str::is([null], null));\n    }\n\n    public function testIsWithMultilineStrings()\n    {\n        $this->assertFalse(Str::is('/', \"/\\n\"));\n        $this->assertTrue(Str::is('/*', \"/\\n\"));\n        $this->assertTrue(Str::is('*/*', \"/\\n\"));\n        $this->assertTrue(Str::is('*/*', \"\\n/\\n\"));\n\n        $this->assertTrue(Str::is('*', \"\\n\"));\n        $this->assertTrue(Str::is('*', \"\\n\\n\"));\n        $this->assertFalse(Str::is('', \"\\n\"));\n        $this->assertFalse(Str::is('', \"\\n\\n\"));\n\n        $multilineValue = <<<'VALUE'\n        <?php\n\n        namespace Illuminate\\Tests\\Support;\n\n        use Exception;\n        VALUE;\n\n        $this->assertTrue(Str::is($multilineValue, $multilineValue));\n        $this->assertTrue(Str::is('*', $multilineValue));\n        $this->assertTrue(Str::is(\"*namespace Illuminate\\Tests\\*\", $multilineValue));\n        $this->assertFalse(Str::is(\"namespace Illuminate\\Tests\\*\", $multilineValue));\n        $this->assertFalse(Str::is(\"*namespace Illuminate\\Tests\", $multilineValue));\n        $this->assertTrue(Str::is('<?php*', $multilineValue));\n        $this->assertTrue(Str::is(\"<?php*namespace Illuminate\\Tests\\*\", $multilineValue));\n        $this->assertFalse(Str::is('use Exception;', $multilineValue));\n        $this->assertFalse(Str::is('use Exception;*', $multilineValue));\n        $this->assertTrue(Str::is('*use Exception;', $multilineValue));\n\n        $this->assertTrue(Str::is(\"<?php\\n\\nnamespace Illuminate\\Tests\\*\", $multilineValue));\n\n        $this->assertTrue(Str::is(<<<'PATTERN'\n        <?php\n        *\n        namespace Illuminate\\Tests\\*\n        PATTERN, $multilineValue));\n\n        $this->assertTrue(Str::is(<<<'PATTERN'\n        <?php\n\n        namespace Illuminate\\Tests\\*\n        PATTERN, $multilineValue));\n    }\n\n    public function testIsUrl()\n    {\n        $this->assertTrue(Str::isUrl('https://laravel.com'));\n        $this->assertTrue(Str::isUrl('http://localhost'));\n        $this->assertTrue(Str::isUrl('http://l'));\n        $this->assertTrue(Str::isUrl('http://l:8000'));\n        $this->assertTrue(Str::isUrl('http://l:8000/path'));\n        $this->assertTrue(Str::isUrl('http://a.b'));\n        $this->assertTrue(Str::isUrl('http://sub.domain.com'));\n        $this->assertTrue(Str::isUrl('http://my-site.com'));\n        $this->assertTrue(Str::isUrl('https://example.com:8080/path?q=1#frag'));\n        $this->assertTrue(Str::isUrl('https://xn--e1afmkfd.xn--p1ai'));\n        $this->assertTrue(Str::isUrl('https://xn--e1afmkfd.xn--e1afmkfd.xn--p1ai'));\n        $this->assertTrue(Str::isUrl('https://1.xn--e1afmkfd.xn--p1ai'));\n        $this->assertFalse(Str::isUrl('invalid url'));\n        $this->assertFalse(Str::isUrl('http://.'));\n        $this->assertFalse(Str::isUrl('http://...'));\n        $this->assertFalse(Str::isUrl('http:///path'));\n    }\n\n    #[DataProvider('validUuidList')]\n    public function testIsUuidWithValidUuid($uuid)\n    {\n        $this->assertTrue(Str::isUuid($uuid));\n    }\n\n    #[DataProvider('invalidUuidList')]\n    public function testIsUuidWithInvalidUuid($uuid)\n    {\n        $this->assertFalse(Str::isUuid($uuid));\n    }\n\n    #[DataProvider('uuidVersionList')]\n    public function testIsUuidWithVersion($uuid, $version, $passes)\n    {\n        $this->assertSame(Str::isUuid($uuid, $version), $passes);\n    }\n\n    public function testIsJson()\n    {\n        $this->assertTrue(Str::isJson('1'));\n        $this->assertTrue(Str::isJson('[1,2,3]'));\n        $this->assertTrue(Str::isJson('[1,   2,   3]'));\n        $this->assertTrue(Str::isJson('{\"first\": \"John\", \"last\": \"Doe\"}'));\n        $this->assertTrue(Str::isJson('[{\"first\": \"John\", \"last\": \"Doe\"}, {\"first\": \"Jane\", \"last\": \"Doe\"}]'));\n\n        $this->assertFalse(Str::isJson('1,'));\n        $this->assertFalse(Str::isJson('[1,2,3'));\n        $this->assertFalse(Str::isJson('[1,   2   3]'));\n        $this->assertFalse(Str::isJson('{first: \"John\"}'));\n        $this->assertFalse(Str::isJson('[{first: \"John\"}, {first: \"Jane\"}]'));\n        $this->assertFalse(Str::isJson(''));\n        $this->assertFalse(Str::isJson(null));\n        $this->assertFalse(Str::isJson([]));\n    }\n\n    public function testIsMatch()\n    {\n        $this->assertTrue(Str::isMatch('/.*,.*!/', 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch('/^.*$(.*)/', 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch('/laravel/i', 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch('/^(.*(.*(.*)))/', 'Hello, Laravel!'));\n\n        $this->assertFalse(Str::isMatch('/H.o/', 'Hello, Laravel!'));\n        $this->assertFalse(Str::isMatch('/^laravel!/i', 'Hello, Laravel!'));\n        $this->assertFalse(Str::isMatch('/laravel!(.*)/', 'Hello, Laravel!'));\n        $this->assertFalse(Str::isMatch('/^[a-zA-Z,!]+$/', 'Hello, Laravel!'));\n\n        $this->assertTrue(Str::isMatch(['/.*,.*!/', '/H.o/'], 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch(['/^laravel!/i', '/^.*$(.*)/'], 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch(['/laravel/i', '/laravel!(.*)/'], 'Hello, Laravel!'));\n        $this->assertTrue(Str::isMatch(['/^[a-zA-Z,!]+$/', '/^(.*(.*(.*)))/'], 'Hello, Laravel!'));\n    }\n\n    public function testKebab()\n    {\n        $this->assertSame('laravel-php-framework', Str::kebab('LaravelPhpFramework'));\n        $this->assertSame('laravel-php-framework', Str::kebab('Laravel Php Framework'));\n        $this->assertSame('laravel❤-php-framework', Str::kebab('Laravel ❤ Php Framework'));\n        $this->assertSame('', Str::kebab(''));\n    }\n\n    public function testLower()\n    {\n        $this->assertSame('foo bar baz', Str::lower('FOO BAR BAZ'));\n        $this->assertSame('foo bar baz', Str::lower('fOo Bar bAz'));\n    }\n\n    public function testUpper()\n    {\n        $this->assertSame('FOO BAR BAZ', Str::upper('foo bar baz'));\n        $this->assertSame('FOO BAR BAZ', Str::upper('foO bAr BaZ'));\n    }\n\n    public function testLimit()\n    {\n        $this->assertSame('Laravel is...', Str::limit('Laravel is a free, open source PHP web application framework.', 10));\n        $this->assertSame('这是一...', Str::limit('这是一段中文', 6));\n        $this->assertSame('Laravel is a...', Str::limit('Laravel is a free, open source PHP web application framework.', 15, preserveWords: true));\n\n        $string = 'The PHP framework for web artisans.';\n        $this->assertSame('The PHP...', Str::limit($string, 7));\n        $this->assertSame('The PHP...', Str::limit($string, 10, preserveWords: true));\n        $this->assertSame('The PHP', Str::limit($string, 7, ''));\n        $this->assertSame('The PHP', Str::limit($string, 10, '', true));\n        $this->assertSame('The PHP framework for web artisans.', Str::limit($string, 100));\n        $this->assertSame('The PHP framework for web artisans.', Str::limit($string, 100, preserveWords: true));\n        $this->assertSame('The PHP framework...', Str::limit($string, 20, preserveWords: true));\n\n        $nonAsciiString = '这是一段中文';\n        $this->assertSame('这是一...', Str::limit($nonAsciiString, 6));\n        $this->assertSame('这是一...', Str::limit($nonAsciiString, 6, preserveWords: true));\n        $this->assertSame('这是一', Str::limit($nonAsciiString, 6, ''));\n        $this->assertSame('这是一', Str::limit($nonAsciiString, 6, '', true));\n    }\n\n    public function testLength()\n    {\n        $this->assertEquals(11, Str::length('foo bar baz'));\n        $this->assertEquals(11, Str::length('foo bar baz', 'UTF-8'));\n    }\n\n    public function testNumbers()\n    {\n        $this->assertSame('5551234567', Str::numbers('(555) 123-4567'));\n        $this->assertSame('443', Str::numbers('L4r4v3l!'));\n        $this->assertSame('', Str::numbers('Laravel!'));\n\n        $arrayValue = ['(555) 123-4567', 'L4r4v3l', 'Laravel!'];\n        $arrayExpected = ['5551234567', '443', ''];\n        $this->assertSame($arrayExpected, Str::numbers($arrayValue));\n    }\n\n    public function testRandom()\n    {\n        $this->assertEquals(16, strlen(Str::random()));\n        $randomInteger = random_int(1, 100);\n        $this->assertEquals($randomInteger, strlen(Str::random($randomInteger)));\n        $this->assertIsString(Str::random());\n    }\n\n    public function testWhetherTheNumberOfGeneratedCharactersIsEquallyDistributed()\n    {\n        $results = [];\n        // take 6.200.000 samples, because there are 62 different characters\n        for ($i = 0; $i < 620000; $i++) {\n            $random = Str::random(1);\n            $results[$random] = ($results[$random] ?? 0) + 1;\n        }\n\n        // each character should occur 100.000 times with a variance of 5%.\n        foreach ($results as $result) {\n            $this->assertEqualsWithDelta(10000, $result, 500);\n        }\n    }\n\n    public function testRandomStringFactoryCanBeSet()\n    {\n        Str::createRandomStringsUsing(fn ($length) => 'length:'.$length);\n\n        $this->assertSame('length:7', Str::random(7));\n        $this->assertSame('length:7', Str::random(7));\n\n        Str::createRandomStringsNormally();\n\n        $this->assertNotSame('length:7', Str::random());\n    }\n\n    public function testItCanSpecifyASequenceOfRandomStringsToUtilise()\n    {\n        Str::createRandomStringsUsingSequence([\n            0 => 'x',\n            // 1 => just generate a random one here...\n            2 => 'y',\n            3 => 'z',\n            // ... => continue to generate random strings...\n        ]);\n\n        $this->assertSame('x', Str::random());\n        $this->assertSame(16, mb_strlen(Str::random()));\n        $this->assertSame('y', Str::random());\n        $this->assertSame('z', Str::random());\n        $this->assertSame(16, mb_strlen(Str::random()));\n        $this->assertSame(16, mb_strlen(Str::random()));\n\n        Str::createRandomStringsNormally();\n    }\n\n    public function testItCanSpecifyAFallbackForARandomStringSequence()\n    {\n        Str::createRandomStringsUsingSequence([Str::random(), Str::random()], fn () => throw new Exception('Out of random strings.'));\n        Str::random();\n        Str::random();\n\n        try {\n            $this->expectExceptionMessage('Out of random strings.');\n            Str::random();\n            $this->fail();\n        } finally {\n            Str::createRandomStringsNormally();\n        }\n    }\n\n    public function testReplace()\n    {\n        $this->assertSame('foo bar laravel', Str::replace('baz', 'laravel', 'foo bar baz'));\n        $this->assertSame('foo bar laravel', Str::replace('baz', 'laravel', 'foo bar Baz', false));\n        $this->assertSame('foo bar baz 8.x', Str::replace('?', '8.x', 'foo bar baz ?'));\n        $this->assertSame('foo bar baz 8.x', Str::replace('x', '8.x', 'foo bar baz X', false));\n        $this->assertSame('foo/bar/baz', Str::replace(' ', '/', 'foo bar baz'));\n        $this->assertSame('foo bar baz', Str::replace(['?1', '?2', '?3'], ['foo', 'bar', 'baz'], '?1 ?2 ?3'));\n        $this->assertSame(['foo', 'bar', 'baz'], Str::replace(collect(['?1', '?2', '?3']), collect(['foo', 'bar', 'baz']), collect(['?1', '?2', '?3'])));\n    }\n\n    public function testReplaceArray()\n    {\n        $this->assertSame('foo/bar/baz', Str::replaceArray('?', ['foo', 'bar', 'baz'], '?/?/?'));\n        $this->assertSame('foo/bar/baz/?', Str::replaceArray('?', ['foo', 'bar', 'baz'], '?/?/?/?'));\n        $this->assertSame('foo/bar', Str::replaceArray('?', ['foo', 'bar', 'baz'], '?/?'));\n        $this->assertSame('?/?/?', Str::replaceArray('x', ['foo', 'bar', 'baz'], '?/?/?'));\n        // Ensure recursive replacements are avoided\n        $this->assertSame('foo?/bar/baz', Str::replaceArray('?', ['foo?', 'bar', 'baz'], '?/?/?'));\n        // Test for associative array support\n        $this->assertSame('foo/bar', Str::replaceArray('?', [1 => 'foo', 2 => 'bar'], '?/?'));\n        $this->assertSame('foo/bar', Str::replaceArray('?', ['x' => 'foo', 'y' => 'bar'], '?/?'));\n        // Test does not crash on bad input\n        $this->assertSame('?', Str::replaceArray('?', [(object) ['foo' => 'bar']], '?'));\n    }\n\n    public function testReplaceFirst()\n    {\n        $this->assertSame('fooqux foobar', Str::replaceFirst('bar', 'qux', 'foobar foobar'));\n        $this->assertSame('foo/qux? foo/bar?', Str::replaceFirst('bar?', 'qux?', 'foo/bar? foo/bar?'));\n        $this->assertSame('foo foobar', Str::replaceFirst('bar', '', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceFirst('xxx', 'yyy', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceFirst('', 'yyy', 'foobar foobar'));\n        $this->assertSame('1', Str::replaceFirst(0, '1', '0'));\n        // Test for multibyte string support\n        $this->assertSame('Jxxxnköping Malmö', Str::replaceFirst('ö', 'xxx', 'Jönköping Malmö'));\n        $this->assertSame('Jönköping Malmö', Str::replaceFirst('', 'yyy', 'Jönköping Malmö'));\n    }\n\n    public function testReplaceStart()\n    {\n        $this->assertSame('foobar foobar', Str::replaceStart('bar', 'qux', 'foobar foobar'));\n        $this->assertSame('foo/bar? foo/bar?', Str::replaceStart('bar?', 'qux?', 'foo/bar? foo/bar?'));\n        $this->assertSame('quxbar foobar', Str::replaceStart('foo', 'qux', 'foobar foobar'));\n        $this->assertSame('qux? foo/bar?', Str::replaceStart('foo/bar?', 'qux?', 'foo/bar? foo/bar?'));\n        $this->assertSame('bar foobar', Str::replaceStart('foo', '', 'foobar foobar'));\n        $this->assertSame('1', Str::replaceStart(0, '1', '0'));\n        // Test for multibyte string support\n        $this->assertSame('xxxnköping Malmö', Str::replaceStart('Jö', 'xxx', 'Jönköping Malmö'));\n        $this->assertSame('Jönköping Malmö', Str::replaceStart('', 'yyy', 'Jönköping Malmö'));\n    }\n\n    public function testReplaceLast()\n    {\n        $this->assertSame('foobar fooqux', Str::replaceLast('bar', 'qux', 'foobar foobar'));\n        $this->assertSame('foo/bar? foo/qux?', Str::replaceLast('bar?', 'qux?', 'foo/bar? foo/bar?'));\n        $this->assertSame('foobar foo', Str::replaceLast('bar', '', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceLast('xxx', 'yyy', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceLast('', 'yyy', 'foobar foobar'));\n        // Test for multibyte string support\n        $this->assertSame('Malmö Jönkxxxping', Str::replaceLast('ö', 'xxx', 'Malmö Jönköping'));\n        $this->assertSame('Malmö Jönköping', Str::replaceLast('', 'yyy', 'Malmö Jönköping'));\n    }\n\n    public function testReplaceEnd()\n    {\n        $this->assertSame('foobar fooqux', Str::replaceEnd('bar', 'qux', 'foobar foobar'));\n        $this->assertSame('foo/bar? foo/qux?', Str::replaceEnd('bar?', 'qux?', 'foo/bar? foo/bar?'));\n        $this->assertSame('foobar foo', Str::replaceEnd('bar', '', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceEnd('xxx', 'yyy', 'foobar foobar'));\n        $this->assertSame('foobar foobar', Str::replaceEnd('', 'yyy', 'foobar foobar'));\n        $this->assertSame('fooxxx foobar', Str::replaceEnd('xxx', 'yyy', 'fooxxx foobar'));\n\n        // // Test for multibyte string support\n        $this->assertSame('Malmö Jönköping', Str::replaceEnd('ö', 'xxx', 'Malmö Jönköping'));\n        $this->assertSame('Malmö Jönkyyy', Str::replaceEnd('öping', 'yyy', 'Malmö Jönköping'));\n    }\n\n    public function testRemove()\n    {\n        $this->assertSame('Fbar', Str::remove('o', 'Foobar'));\n        $this->assertSame('Foo', Str::remove('bar', 'Foobar'));\n        $this->assertSame('oobar', Str::remove('F', 'Foobar'));\n        $this->assertSame('Foobar', Str::remove('f', 'Foobar'));\n        $this->assertSame('oobar', Str::remove('f', 'Foobar', false));\n\n        $this->assertSame('Fbr', Str::remove(['o', 'a'], 'Foobar'));\n        $this->assertSame('Fooar', Str::remove(['f', 'b'], 'Foobar'));\n        $this->assertSame('ooar', Str::remove(['f', 'b'], 'Foobar', false));\n        $this->assertSame('Foobar', Str::remove(['f', '|'], 'Foo|bar'));\n    }\n\n    public function testReverse()\n    {\n        $this->assertSame('FooBar', Str::reverse('raBooF'));\n        $this->assertSame('Teniszütő', Str::reverse('őtüzsineT'));\n        $this->assertSame('❤MultiByte☆', Str::reverse('☆etyBitluM❤'));\n    }\n\n    public function testSnake()\n    {\n        $this->assertSame('laravel_p_h_p_framework', Str::snake('LaravelPHPFramework'));\n        $this->assertSame('laravel_php_framework', Str::snake('LaravelPhpFramework'));\n        $this->assertSame('laravel php framework', Str::snake('LaravelPhpFramework', ' '));\n        $this->assertSame('laravel_php_framework', Str::snake('Laravel Php Framework'));\n        $this->assertSame('laravel_php_framework', Str::snake('Laravel    Php      Framework   '));\n        // ensure cache keys don't overlap\n        $this->assertSame('laravel__php__framework', Str::snake('LaravelPhpFramework', '__'));\n        $this->assertSame('laravel_php_framework_', Str::snake('LaravelPhpFramework_', '_'));\n        $this->assertSame('laravel_php_framework', Str::snake('laravel php Framework'));\n        $this->assertSame('laravel_php_frame_work', Str::snake('laravel php FrameWork'));\n        // prevent breaking changes\n        $this->assertSame('foo-bar', Str::snake('foo-bar'));\n        $this->assertSame('foo-_bar', Str::snake('Foo-Bar'));\n        $this->assertSame('foo__bar', Str::snake('Foo_Bar'));\n        $this->assertSame('żółtałódka', Str::snake('ŻółtaŁódka'));\n    }\n\n    public function testTrim()\n    {\n        $this->assertSame('foo bar', Str::trim('   foo bar   '));\n        $this->assertSame('foo bar', Str::trim('foo bar   '));\n        $this->assertSame('foo bar', Str::trim('   foo bar'));\n        $this->assertSame('foo bar', Str::trim('foo bar'));\n        $this->assertSame(' foo bar ', Str::trim(' foo bar ', ''));\n        $this->assertSame('foo bar', Str::trim(' foo bar ', ' '));\n        $this->assertSame('foo  bar', Str::trim('-foo  bar_', '-_'));\n\n        $this->assertSame('foo    bar', Str::trim(' foo    bar '));\n\n        $this->assertSame('123', Str::trim('   123    '));\n        $this->assertSame('だ', Str::trim('だ'));\n        $this->assertSame('ム', Str::trim('ム'));\n        $this->assertSame('だ', Str::trim('   だ    '));\n        $this->assertSame('ム', Str::trim('   ム    '));\n\n        $this->assertSame(\n            'foo bar',\n            Str::trim('\n                foo bar\n            ')\n        );\n        $this->assertSame(\n            'foo\n                bar',\n            Str::trim('\n                foo\n                bar\n            ')\n        );\n\n        $this->assertSame(\"\\xE9\", Str::trim(\" \\xE9 \"));\n\n        $trimDefaultChars = [' ', \"\\n\", \"\\r\", \"\\t\", \"\\v\", \"\\0\"];\n\n        foreach ($trimDefaultChars as $char) {\n            $this->assertSame('', Str::trim(\" {$char} \"));\n            $this->assertSame(trim(\" {$char} \"), Str::trim(\" {$char} \"));\n\n            $this->assertSame('foo bar', Str::trim(\"{$char} foo bar {$char}\"));\n            $this->assertSame(trim(\"{$char} foo bar {$char}\"), Str::trim(\"{$char} foo bar {$char}\"));\n        }\n    }\n\n    public function testLtrim()\n    {\n        $this->assertSame('foo    bar ', Str::ltrim(' foo    bar '));\n\n        $this->assertSame('123    ', Str::ltrim('   123    '));\n        $this->assertSame('だ', Str::ltrim('だ'));\n        $this->assertSame('ム', Str::ltrim('ム'));\n        $this->assertSame('だ    ', Str::ltrim('   だ    '));\n        $this->assertSame('ム    ', Str::ltrim('   ム    '));\n\n        $this->assertSame(\n            'foo bar\n            ',\n            Str::ltrim('\n                foo bar\n            ')\n        );\n        $this->assertSame(\"\\xE9 \", Str::ltrim(\" \\xE9 \"));\n\n        $ltrimDefaultChars = [' ', \"\\n\", \"\\r\", \"\\t\", \"\\v\", \"\\0\"];\n\n        foreach ($ltrimDefaultChars as $char) {\n            $this->assertSame('', Str::ltrim(\" {$char} \"));\n            $this->assertSame(ltrim(\" {$char} \"), Str::ltrim(\" {$char} \"));\n\n            $this->assertSame(\"foo bar {$char}\", Str::ltrim(\"{$char} foo bar {$char}\"));\n            $this->assertSame(ltrim(\"{$char} foo bar {$char}\"), Str::ltrim(\"{$char} foo bar {$char}\"));\n        }\n    }\n\n    public function testRtrim()\n    {\n        $this->assertSame(' foo    bar', Str::rtrim(' foo    bar '));\n\n        $this->assertSame('   123', Str::rtrim('   123    '));\n        $this->assertSame('だ', Str::rtrim('だ'));\n        $this->assertSame('ム', Str::rtrim('ム'));\n        $this->assertSame('   だ', Str::rtrim('   だ    '));\n        $this->assertSame('   ム', Str::rtrim('   ム    '));\n\n        $this->assertSame(\n            '\n                foo bar',\n            Str::rtrim('\n                foo bar\n            ')\n        );\n\n        $this->assertSame(\" \\xE9\", Str::rtrim(\" \\xE9 \"));\n\n        $rtrimDefaultChars = [' ', \"\\n\", \"\\r\", \"\\t\", \"\\v\", \"\\0\"];\n\n        foreach ($rtrimDefaultChars as $char) {\n            $this->assertSame('', Str::rtrim(\" {$char} \"));\n            $this->assertSame(rtrim(\" {$char} \"), Str::rtrim(\" {$char} \"));\n\n            $this->assertSame(\"{$char} foo bar\", Str::rtrim(\"{$char} foo bar {$char}\"));\n            $this->assertSame(rtrim(\"{$char} foo bar {$char}\"), Str::rtrim(\"{$char} foo bar {$char}\"));\n        }\n    }\n\n    public function testSquish()\n    {\n        $this->assertSame('laravel php framework', Str::squish(' laravel   php  framework '));\n        $this->assertSame('laravel php framework', Str::squish(\"laravel\\t\\tphp\\n\\nframework\"));\n        $this->assertSame('laravel php framework', Str::squish('\n            laravel\n            php\n            framework\n        '));\n        $this->assertSame('laravel php framework', Str::squish('   laravel   php   framework   '));\n        $this->assertSame('123', Str::squish('   123    '));\n        $this->assertSame('だ', Str::squish('だ'));\n        $this->assertSame('ム', Str::squish('ム'));\n        $this->assertSame('だ', Str::squish('   だ    '));\n        $this->assertSame('ム', Str::squish('   ム    '));\n        $this->assertSame('laravel php framework', Str::squish('laravelㅤㅤㅤphpㅤframework'));\n        $this->assertSame('laravel php framework', Str::squish('laravelᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠphpᅠᅠframework'));\n    }\n\n    public function testStudly()\n    {\n        $this->assertSame('LaravelPHPFramework', Str::studly('laravel_p_h_p_framework'));\n        $this->assertSame('LaravelPhpFramework', Str::studly('laravel_php_framework'));\n        $this->assertSame('LaravelPhPFramework', Str::studly('laravel-phP-framework'));\n        $this->assertSame('LaravelPhpFramework', Str::studly('laravel  -_-  php   -_-   framework   '));\n\n        $this->assertSame('FooBar', Str::studly('fooBar'));\n        $this->assertSame('FooBar', Str::studly('foo_bar'));\n        $this->assertSame('FooBar', Str::studly('foo_bar')); // test cache\n        $this->assertSame('FooBarBaz', Str::studly('foo-barBaz'));\n        $this->assertSame('FooBarBaz', Str::studly('foo-bar_baz'));\n\n        $this->assertSame('ÖffentlicheÜberraschungen', Str::studly('öffentliche-überraschungen'));\n    }\n\n    public function testPascal()\n    {\n        $this->assertSame('LaravelPhpFramework', Str::pascal('laravel_php_framework'));\n        $this->assertSame('LaravelPhpFramework', Str::pascal('laravel-php-framework'));\n        $this->assertSame('LaravelPhpFramework', Str::pascal('laravel  -_-  php   -_-   framework   '));\n\n        $this->assertSame('FooBar', Str::pascal('fooBar'));\n        $this->assertSame('FooBar', Str::pascal('foo_bar'));\n        $this->assertSame('FooBar', Str::pascal('foo_bar')); // test cache\n        $this->assertSame('FooBarBaz', Str::pascal('foo-barBaz'));\n        $this->assertSame('FooBarBaz', Str::pascal('foo-bar_baz'));\n\n        $this->assertSame('ÖffentlicheÜberraschungen', Str::pascal('öffentliche-überraschungen'));\n    }\n\n    public function testMask()\n    {\n        $this->assertSame('tay*************', Str::mask('taylor@email.com', '*', 3));\n        $this->assertSame('******@email.com', Str::mask('taylor@email.com', '*', 0, 6));\n        $this->assertSame('tay*************', Str::mask('taylor@email.com', '*', -13));\n        $this->assertSame('tay***@email.com', Str::mask('taylor@email.com', '*', -13, 3));\n\n        $this->assertSame('****************', Str::mask('taylor@email.com', '*', -17));\n        $this->assertSame('*****r@email.com', Str::mask('taylor@email.com', '*', -99, 5));\n\n        $this->assertSame('taylor@email.com', Str::mask('taylor@email.com', '*', 16));\n        $this->assertSame('taylor@email.com', Str::mask('taylor@email.com', '*', 16, 99));\n\n        $this->assertSame('taylor@email.com', Str::mask('taylor@email.com', '', 3));\n\n        $this->assertSame('taysssssssssssss', Str::mask('taylor@email.com', 'something', 3));\n        $this->assertSame('taysssssssssssss', Str::mask('taylor@email.com', Str::of('something'), 3));\n\n        $this->assertSame('这是一***', Str::mask('这是一段中文', '*', 3));\n        $this->assertSame('**一段中文', Str::mask('这是一段中文', '*', 0, 2));\n\n        $this->assertSame('ma*n@email.com', Str::mask('maan@email.com', '*', 2, 1));\n        $this->assertSame('ma***email.com', Str::mask('maan@email.com', '*', 2, 3));\n        $this->assertSame('ma************', Str::mask('maan@email.com', '*', 2));\n\n        $this->assertSame('mari*@email.com', Str::mask('maria@email.com', '*', 4, 1));\n        $this->assertSame('tamar*@email.com', Str::mask('tamara@email.com', '*', 5, 1));\n\n        $this->assertSame('*aria@email.com', Str::mask('maria@email.com', '*', 0, 1));\n        $this->assertSame('maria@email.co*', Str::mask('maria@email.com', '*', -1, 1));\n        $this->assertSame('maria@email.co*', Str::mask('maria@email.com', '*', -1));\n        $this->assertSame('***************', Str::mask('maria@email.com', '*', -15));\n        $this->assertSame('***************', Str::mask('maria@email.com', '*', 0));\n    }\n\n    public function testMatch(): void\n    {\n        $this->assertSame('bar', Str::match('/bar/', 'foo bar'));\n        $this->assertSame('bar', Str::match('/foo (.*)/', 'foo bar'));\n        $this->assertEmpty(Str::match('/nothing/', 'foo bar'));\n\n        $this->assertEquals(['bar', 'bar'], Str::matchAll('/bar/', 'bar foo bar')->all());\n\n        $this->assertEquals(['un', 'ly'], Str::matchAll('/f(\\w*)/', 'bar fun bar fly')->all());\n        $this->assertEmpty(Str::matchAll('/nothing/', 'bar fun bar fly'));\n\n        $this->assertEmpty(Str::match('/pattern/', ''));\n        $this->assertEmpty(Str::matchAll('/pattern/', ''));\n    }\n\n    public function testCamel(): void\n    {\n        $this->assertSame('laravelPHPFramework', Str::camel('Laravel_p_h_p_framework'));\n        $this->assertSame('laravelPhpFramework', Str::camel('Laravel_php_framework'));\n        $this->assertSame('laravelPhPFramework', Str::camel('Laravel-phP-framework'));\n        $this->assertSame('laravelPhpFramework', Str::camel('Laravel  -_-  php   -_-   framework   '));\n\n        $this->assertSame('fooBar', Str::camel('FooBar'));\n        $this->assertSame('fooBar', Str::camel('foo_bar'));\n        $this->assertSame('fooBar', Str::camel('foo_bar')); // test cache\n        $this->assertSame('fooBarBaz', Str::camel('Foo-barBaz'));\n        $this->assertSame('fooBarBaz', Str::camel('foo-bar_baz'));\n\n        $this->assertSame('', Str::camel(''));\n        $this->assertSame('lARAVELPHPFRAMEWORK', Str::camel('LARAVEL_PHP_FRAMEWORK'));\n        $this->assertSame('laravelPhpFramework', Str::camel('   laravel   php   framework   '));\n\n        $this->assertSame('foo1Bar', Str::camel('foo1_bar'));\n        $this->assertSame('1FooBar', Str::camel('1 foo bar'));\n    }\n\n    public function testCharAt()\n    {\n        $this->assertEquals('р', Str::charAt('Привет, мир!', 1));\n        $this->assertEquals('ち', Str::charAt('「こんにちは世界」', 4));\n        $this->assertEquals('w', Str::charAt('Привет, world!', 8));\n        $this->assertEquals('界', Str::charAt('「こんにちは世界」', -2));\n        $this->assertEquals(null, Str::charAt('「こんにちは世界」', -200));\n        $this->assertEquals(null, Str::charAt('Привет, мир!', 100));\n    }\n\n    public function testSubstr()\n    {\n        $this->assertSame('Ё', Str::substr('БГДЖИЛЁ', -1));\n        $this->assertSame('ЛЁ', Str::substr('БГДЖИЛЁ', -2));\n        $this->assertSame('И', Str::substr('БГДЖИЛЁ', -3, 1));\n        $this->assertSame('ДЖИЛ', Str::substr('БГДЖИЛЁ', 2, -1));\n        $this->assertEmpty(Str::substr('БГДЖИЛЁ', 4, -4));\n        $this->assertSame('ИЛ', Str::substr('БГДЖИЛЁ', -3, -1));\n        $this->assertSame('ГДЖИЛЁ', Str::substr('БГДЖИЛЁ', 1));\n        $this->assertSame('ГДЖ', Str::substr('БГДЖИЛЁ', 1, 3));\n        $this->assertSame('БГДЖ', Str::substr('БГДЖИЛЁ', 0, 4));\n        $this->assertSame('Ё', Str::substr('БГДЖИЛЁ', -1, 1));\n        $this->assertEmpty(Str::substr('Б', 2));\n    }\n\n    public function testSubstrCount()\n    {\n        $this->assertSame(3, Str::substrCount('laravelPHPFramework', 'a'));\n        $this->assertSame(0, Str::substrCount('laravelPHPFramework', 'z'));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'l', 2));\n        $this->assertSame(0, Str::substrCount('laravelPHPFramework', 'z', 2));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'k', -1));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'k', -1));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'a', 1, 2));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'a', 1, 2));\n        $this->assertSame(3, Str::substrCount('laravelPHPFramework', 'a', 1, -2));\n        $this->assertSame(1, Str::substrCount('laravelPHPFramework', 'a', -10, -3));\n    }\n\n    public function testPosition()\n    {\n        $this->assertSame(7, Str::position('Hello, World!', 'W'));\n        $this->assertSame(10, Str::position('This is a test string.', 'test'));\n        $this->assertSame(23, Str::position('This is a test string, test again.', 'test', 15));\n        $this->assertSame(0, Str::position('Hello, World!', 'Hello'));\n        $this->assertSame(7, Str::position('Hello, World!', 'World!'));\n        $this->assertSame(10, Str::position('This is a tEsT string.', 'tEsT', 0, 'UTF-8'));\n        $this->assertSame(7, Str::position('Hello, World!', 'W', -6));\n        $this->assertSame(18, Str::position('Äpfel, Birnen und Kirschen', 'Kirschen', -10, 'UTF-8'));\n        $this->assertSame(9, Str::position('@%€/=!\"][$', '$', 0, 'UTF-8'));\n        $this->assertFalse(Str::position('Hello, World!', 'w', 0, 'UTF-8'));\n        $this->assertFalse(Str::position('Hello, World!', 'X', 0, 'UTF-8'));\n        $this->assertFalse(Str::position('', 'test'));\n        $this->assertFalse(Str::position('Hello, World!', 'X'));\n    }\n\n    public function testSubstrReplace()\n    {\n        $this->assertSame('12:00', Str::substrReplace('1200', ':', 2, 0));\n        $this->assertSame('The Laravel Framework', Str::substrReplace('The Framework', 'Laravel ', 4, 0));\n        $this->assertSame('Laravel – The PHP Framework for Web Artisans', Str::substrReplace('Laravel Framework', '– The PHP Framework for Web Artisans', 8));\n        // test edge cases with negative offset or length\n        $this->assertSame('1567', Str::substrReplace('1234', '567', -3, 3));\n        $this->assertSame('125674', Str::substrReplace('1234', '567', 2, -1));\n        $this->assertSame('125674', Str::substrReplace('1234', '567', -2, -1));\n    }\n\n    public function testSubstrReplaceWithMultibyte()\n    {\n        $this->assertSame('kengä', Str::substrReplace('kenkä', 'ng', -3, 2));\n        $this->assertSame('kenga', Str::substrReplace('kenka', 'ng', -3, 2));\n    }\n\n    public function testTake()\n    {\n        $this->assertSame('ab', Str::take('abcdef', 2));\n        $this->assertSame('ef', Str::take('abcdef', -2));\n        $this->assertSame('', Str::take('abcdef', 0));\n        $this->assertSame('', Str::take('', 2));\n        $this->assertSame('abcdef', Str::take('abcdef', 10));\n        $this->assertSame('abcdef', Str::take('abcdef', 6));\n        $this->assertSame('ü', Str::take('üöä', 1));\n    }\n\n    public function testLcfirst()\n    {\n        $this->assertSame('laravel', Str::lcfirst('Laravel'));\n        $this->assertSame('laravel framework', Str::lcfirst('Laravel framework'));\n        $this->assertSame('мама', Str::lcfirst('Мама'));\n        $this->assertSame('мама мыла раму', Str::lcfirst('Мама мыла раму'));\n    }\n\n    public function testUcfirst()\n    {\n        $this->assertSame('Laravel', Str::ucfirst('laravel'));\n        $this->assertSame('Laravel framework', Str::ucfirst('laravel framework'));\n        $this->assertSame('Мама', Str::ucfirst('мама'));\n        $this->assertSame('Мама мыла раму', Str::ucfirst('мама мыла раму'));\n    }\n\n    public function testUcwords()\n    {\n        $this->assertSame('Laravel', Str::ucwords('laravel'));\n        $this->assertSame('Laravel Framework', Str::ucwords('laravel framework'));\n        $this->assertSame('Laravel-Framework', Str::ucwords('laravel-framework', '-'));\n        $this->assertSame('Мама', Str::ucwords('мама'));\n        $this->assertSame('Мама Мыла Раму', Str::ucwords('мама мыла раму'));\n        $this->assertSame('JJ Watt', Str::ucwords('JJ watt'));\n    }\n\n    public function testUcsplit()\n    {\n        $this->assertSame(['Laravel_p_h_p_framework'], Str::ucsplit('Laravel_p_h_p_framework'));\n        $this->assertSame(['Laravel_', 'P_h_p_framework'], Str::ucsplit('Laravel_P_h_p_framework'));\n        $this->assertSame(['laravel', 'P', 'H', 'P', 'Framework'], Str::ucsplit('laravelPHPFramework'));\n        $this->assertSame(['Laravel-ph', 'P-framework'], Str::ucsplit('Laravel-phP-framework'));\n\n        $this->assertSame(['Żółta', 'Łódka'], Str::ucsplit('ŻółtaŁódka'));\n        $this->assertSame(['sind', 'Öde', 'Und', 'So'], Str::ucsplit('sindÖdeUndSo'));\n        $this->assertSame(['Öffentliche', 'Überraschungen'], Str::ucsplit('ÖffentlicheÜberraschungen'));\n    }\n\n    public function testUuid()\n    {\n        $this->assertInstanceOf(UuidInterface::class, Str::uuid());\n        $this->assertInstanceOf(UuidInterface::class, Str::orderedUuid());\n        $this->assertInstanceOf(UuidInterface::class, Str::uuid7());\n    }\n\n    public function testAsciiNull()\n    {\n        $this->assertSame('', Str::ascii(null));\n        $this->assertTrue(Str::isAscii(null));\n        $this->assertSame('', Str::slug(null));\n    }\n\n    public function testPadBoth()\n    {\n        $this->assertSame('__Alien___', Str::padBoth('Alien', 10, '_'));\n        $this->assertSame('  Alien   ', Str::padBoth('Alien', 10));\n        $this->assertSame('  ❤MultiByte☆   ', Str::padBoth('❤MultiByte☆', 16));\n        $this->assertSame('❤☆❤MultiByte☆❤☆❤', Str::padBoth('❤MultiByte☆', 16, '❤☆'));\n    }\n\n    public function testPadLeft()\n    {\n        $this->assertSame('-=-=-Alien', Str::padLeft('Alien', 10, '-='));\n        $this->assertSame('     Alien', Str::padLeft('Alien', 10));\n        $this->assertSame('     ❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16));\n        $this->assertSame('❤☆❤☆❤❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16, '❤☆'));\n    }\n\n    public function testPadRight()\n    {\n        $this->assertSame('Alien-=-=-', Str::padRight('Alien', 10, '-='));\n        $this->assertSame('Alien     ', Str::padRight('Alien', 10));\n        $this->assertSame('❤MultiByte☆     ', Str::padRight('❤MultiByte☆', 16));\n        $this->assertSame('❤MultiByte☆❤☆❤☆❤', Str::padRight('❤MultiByte☆', 16, '❤☆'));\n    }\n\n    public function testSwapKeywords(): void\n    {\n        $this->assertSame(\n            'PHP 8 is fantastic',\n            Str::swap([\n                'PHP' => 'PHP 8',\n                'awesome' => 'fantastic',\n            ], 'PHP is awesome')\n        );\n\n        $this->assertSame(\n            'foo bar baz',\n            Str::swap([\n                'ⓐⓑ' => 'baz',\n            ], 'foo bar ⓐⓑ')\n        );\n    }\n\n    public function testWordCount()\n    {\n        $this->assertEquals(2, Str::wordCount('Hello, world!'));\n        $this->assertEquals(10, Str::wordCount('Hi, this is my first contribution to the Laravel framework.'));\n\n        // str_word_count() without $characters does not reliably handle multibyte\n        // strings — results depend on the system locale's isalpha() behavior\n        // (e.g. macOS 15+ changed LC_CTYPE defaults). See php/php-src#19828.\n        $this->assertEquals(str_word_count('мама'), Str::wordCount('мама'));\n        $this->assertEquals(str_word_count('мама мыла раму'), Str::wordCount('мама мыла раму'));\n\n        $this->assertEquals(1, Str::wordCount('мама', 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'));\n        $this->assertEquals(3, Str::wordCount('мама мыла раму', 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'));\n\n        $this->assertEquals(1, Str::wordCount('МАМА', 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'));\n        $this->assertEquals(3, Str::wordCount('МАМА МЫЛА РАМУ', 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'));\n    }\n\n    public function testWordWrap()\n    {\n        $this->assertEquals('Hello<br />World', Str::wordWrap('Hello World', 3, '<br />'));\n        $this->assertEquals('Hel<br />lo<br />Wor<br />ld', Str::wordWrap('Hello World', 3, '<br />', true));\n\n        $this->assertEquals('❤Multi<br />Byte☆❤☆❤☆❤', Str::wordWrap('❤Multi Byte☆❤☆❤☆❤', 3, '<br />'));\n    }\n\n    public static function validUuidList()\n    {\n        return [\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de'],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1'],\n            ['00000000-0000-0000-0000-000000000000'],\n            ['e60d3f48-95d7-4d8d-aad0-856f29a27da2'],\n            ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-31e1-9b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-41e1-9b21-0800200c9a66'],\n            ['ff6f8cb0-c57d-51e1-9b21-0800200c9a66'],\n            ['FF6F8CB0-C57D-11E1-9B21-0800200C9A66'],\n        ];\n    }\n\n    public static function invalidUuidList()\n    {\n        return [\n            ['not a valid uuid so we can test this'],\n            ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66'],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1'.PHP_EOL],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1 '],\n            [' 145a1e72-d11d-11e8-a8d5-f2801f1b9fd1'],\n            ['145a1e72-d11d-11e8-a8d5-f2z01f1b9fd1'],\n            ['3f6f8cb0-c57d-11e1-9b21-0800200c9a6'],\n            ['af6f8cb-c57d-11e1-9b21-0800200c9a66'],\n            ['af6f8cb0c57d11e19b210800200c9a66'],\n            ['ff6f8cb0-c57da-51e1-9b21-0800200c9a66'],\n        ];\n    }\n\n    public static function uuidVersionList()\n    {\n        return [\n            ['00000000-0000-0000-0000-000000000000', null, true],\n            ['00000000-0000-0000-0000-000000000000', 0, true],\n            ['00000000-0000-0000-0000-000000000000', 1, false],\n            ['00000000-0000-0000-0000-000000000000', 42, false],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', null, true],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 1, true],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 4, false],\n            ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 42, false],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', null, true],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', 1, false],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', 2, true],\n            ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66', 42, false],\n            ['76a4ba72-cc4e-3e1d-b52d-856382f408c3', null, true],\n            ['76a4ba72-cc4e-3e1d-b52d-856382f408c3', 1, false],\n            ['76a4ba72-cc4e-3e1d-b52d-856382f408c3', 3, true],\n            ['76a4ba72-cc4e-3e1d-b52d-856382f408c3', 42, false],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', null, true],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 1, false],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 4, true],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 42, false],\n            ['d3b2b5a9-d433-5c58-b038-4fa13696e357', null, true],\n            ['d3b2b5a9-d433-5c58-b038-4fa13696e357', 1, false],\n            ['d3b2b5a9-d433-5c58-b038-4fa13696e357', 5, true],\n            ['d3b2b5a9-d433-5c58-b038-4fa13696e357', 42, false],\n            ['1ef97d97-b5ab-67d8-9f12-5600051f1387', null, true],\n            ['1ef97d97-b5ab-67d8-9f12-5600051f1387', 1, false],\n            ['1ef97d97-b5ab-67d8-9f12-5600051f1387', 6, true],\n            ['1ef97d97-b5ab-67d8-9f12-5600051f1387', 42, false],\n            ['0192e4b9-92eb-7aec-8707-1becfb1e3eb7', null, true],\n            ['0192e4b9-92eb-7aec-8707-1becfb1e3eb7', 1, false],\n            ['0192e4b9-92eb-7aec-8707-1becfb1e3eb7', 7, true],\n            ['0192e4b9-92eb-7aec-8707-1becfb1e3eb7', 42, false],\n            ['07e80a1f-1629-831f-811f-c595103c91b5', null, true],\n            ['07e80a1f-1629-831f-811f-c595103c91b5', 1, false],\n            ['07e80a1f-1629-831f-811f-c595103c91b5', 8, true],\n            ['07e80a1f-1629-831f-811f-c595103c91b5', 42, false],\n            ['FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', null, true],\n            ['FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 1, false],\n            ['FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 42, false],\n            ['FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', 'max', true],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', null, true],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 1, false],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 4, true],\n            ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 42, false],\n            ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', null, false],\n            ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 1, false],\n            ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 4, false],\n            ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 42, false],\n        ];\n    }\n\n    public static function strContainsProvider()\n    {\n        return [\n            ['Taylor', 'ylo', true, true],\n            ['Taylor', 'ylo', true, false],\n            ['Taylor', 'taylor', true, true],\n            ['Taylor', 'taylor', false, false],\n            ['Taylor', ['ylo'], true, true],\n            ['Taylor', ['ylo'], true, false],\n            ['Taylor', ['xxx', 'ylo'], true, true],\n            ['Taylor', collect(['xxx', 'ylo']), true, true],\n            ['Taylor', ['xxx', 'ylo'], true, false],\n            ['Taylor', 'xxx', false],\n            ['Taylor', ['xxx'], false],\n            ['Taylor', '', false],\n            ['', '', false],\n        ];\n    }\n\n    public static function strContainsAllProvider()\n    {\n        return [\n            ['Taylor Otwell', ['taylor', 'otwell'], false, false],\n            ['Taylor Otwell', ['taylor', 'otwell'], true, true],\n            ['Taylor Otwell', ['taylor'], false, false],\n            ['Taylor Otwell', ['taylor'], true, true],\n            ['Taylor Otwell', ['taylor', 'xxx'], false, false],\n            ['Taylor Otwell', ['taylor', 'xxx'], false, true],\n        ];\n    }\n\n    public static function strDoesntContainProvider()\n    {\n        return [\n            ['Tar', 'ylo', true, true],\n        ];\n    }\n\n    public function testMarkdown()\n    {\n        $this->assertSame(\"<p><em>hello world</em></p>\\n\", Str::markdown('*hello world*'));\n        $this->assertSame(\"<h1>hello world</h1>\\n\", Str::markdown('# hello world'));\n    }\n\n    public function testInlineMarkdown()\n    {\n        $this->assertSame(\"<em>hello world</em>\\n\", Str::inlineMarkdown('*hello world*'));\n        $this->assertSame(\"<a href=\\\"https://laravel.com\\\"><strong>Laravel</strong></a>\\n\", Str::inlineMarkdown('[**Laravel**](https://laravel.com)'));\n    }\n\n    public function testRepeat()\n    {\n        $this->assertSame('', Str::repeat('Hello', 0));\n        $this->assertSame('Hello', Str::repeat('Hello', 1));\n        $this->assertSame('aaaaa', Str::repeat('a', 5));\n        $this->assertSame('', Str::repeat('', 5));\n    }\n\n    public function testRepeatWhenTimesIsNegative()\n    {\n        $this->expectException(ValueError::class);\n        Str::repeat('Hello', -2);\n    }\n\n    #[DataProvider('specialCharacterProvider')]\n    public function testTransliterate(string $value, string $expected): void\n    {\n        $this->assertSame($expected, Str::transliterate($value));\n    }\n\n    public static function specialCharacterProvider(): array\n    {\n        return [\n            ['ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz'],\n            ['⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳', '01234567891011121314151617181920'],\n            ['⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾', '12345678910'],\n            ['⓿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴', '011121314151617181920'],\n            ['ⓣⓔⓢⓣ@ⓛⓐⓡⓐⓥⓔⓛ.ⓒⓞⓜ', 'test@laravel.com'],\n            ['🎂', '?'],\n            ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],\n            ['0123456789', '0123456789'],\n        ];\n    }\n\n    public function testTransliterateOverrideUnknown(): void\n    {\n        $this->assertSame('HHH', Str::transliterate('🎂🚧🏆', 'H'));\n        $this->assertSame('Hello', Str::transliterate('🎂', 'Hello'));\n    }\n\n    #[DataProvider('specialCharacterProvider')]\n    public function testTransliterateStrict(string $value, string $expected): void\n    {\n        $this->assertSame($expected, Str::transliterate($value, '?', true));\n    }\n\n    public function testItCanFreezeUuids()\n    {\n        $this->assertNotSame((string) Str::uuid(), (string) Str::uuid());\n        $this->assertNotSame(Str::uuid(), Str::uuid());\n\n        $uuid = Str::freezeUuids();\n\n        $this->assertSame($uuid, Str::uuid());\n        $this->assertSame(Str::uuid(), Str::uuid());\n        $this->assertSame((string) $uuid, (string) Str::uuid());\n        $this->assertSame((string) Str::uuid(), (string) Str::uuid());\n\n        Str::createUuidsNormally();\n\n        $this->assertNotSame(Str::uuid(), Str::uuid());\n        $this->assertNotSame((string) Str::uuid(), (string) Str::uuid());\n    }\n\n    public function testItCanFreezeUuidsInAClosure()\n    {\n        $uuids = [];\n\n        $uuid = Str::freezeUuids(function ($uuid) use (&$uuids) {\n            $uuids[] = $uuid;\n            $uuids[] = Str::uuid();\n            $uuids[] = Str::uuid();\n        });\n\n        $this->assertSame($uuid, $uuids[0]);\n        $this->assertSame((string) $uuid, (string) $uuids[0]);\n        $this->assertSame((string) $uuids[0], (string) $uuids[1]);\n        $this->assertSame($uuids[0], $uuids[1]);\n        $this->assertSame((string) $uuids[0], (string) $uuids[1]);\n        $this->assertSame($uuids[1], $uuids[2]);\n        $this->assertSame((string) $uuids[1], (string) $uuids[2]);\n        $this->assertNotSame(Str::uuid(), Str::uuid());\n        $this->assertNotSame((string) Str::uuid(), (string) Str::uuid());\n\n        Str::createUuidsNormally();\n    }\n\n    public function testItCreatesUuidsNormallyAfterFailureWithinFreezeMethod()\n    {\n        try {\n            Str::freezeUuids(function () {\n                Str::createUuidsUsing(fn () => Str::of('1234'));\n                $this->assertSame('1234', Str::uuid()->toString());\n                throw new \\Exception('Something failed.');\n            });\n        } catch (\\Exception) {\n            $this->assertNotSame('1234', Str::uuid()->toString());\n        }\n    }\n\n    public function testItCanSpecifyASequenceOfUuidsToUtilise()\n    {\n        Str::createUuidsUsingSequence([\n            0 => ($zeroth = Str::uuid()),\n            1 => ($first = Str::uuid7()),\n            // just generate a random one here...\n            3 => ($third = Str::uuid()),\n            // continue to generate random uuids...\n        ]);\n\n        $retrieved = Str::uuid();\n        $this->assertSame($zeroth, $retrieved);\n        $this->assertSame((string) $zeroth, (string) $retrieved);\n\n        $retrieved = Str::uuid();\n        $this->assertSame($first, $retrieved);\n        $this->assertSame((string) $first, (string) $retrieved);\n\n        $retrieved = Str::uuid();\n        $this->assertFalse(in_array($retrieved, [$zeroth, $first, $third], true));\n        $this->assertFalse(in_array((string) $retrieved, [(string) $zeroth, (string) $first, (string) $third], true));\n\n        $retrieved = Str::uuid();\n        $this->assertSame($third, $retrieved);\n        $this->assertSame((string) $third, (string) $retrieved);\n\n        $retrieved = Str::uuid();\n        $this->assertFalse(in_array($retrieved, [$zeroth, $first, $third], true));\n        $this->assertFalse(in_array((string) $retrieved, [(string) $zeroth, (string) $first, (string) $third], true));\n\n        Str::createUuidsNormally();\n    }\n\n    public function testItCanSpecifyAFallbackForASequence()\n    {\n        Str::createUuidsUsingSequence([Str::uuid(), Str::uuid()], fn () => throw new Exception('Out of Uuids.'));\n        Str::uuid();\n        Str::uuid();\n\n        try {\n            $this->expectExceptionMessage('Out of Uuids.');\n            Str::uuid();\n            $this->fail();\n        } finally {\n            Str::createUuidsNormally();\n        }\n    }\n\n    public function testItCanFreezeUlids()\n    {\n        $this->assertNotSame((string) Str::ulid(), (string) Str::ulid());\n        $this->assertNotSame(Str::ulid(), Str::ulid());\n\n        $ulid = Str::freezeUlids();\n\n        $this->assertSame($ulid, Str::ulid());\n        $this->assertSame(Str::ulid(), Str::ulid());\n        $this->assertSame((string) $ulid, (string) Str::ulid());\n        $this->assertSame((string) Str::ulid(), (string) Str::ulid());\n\n        Str::createUlidsNormally();\n\n        $this->assertNotSame(Str::ulid(), Str::ulid());\n        $this->assertNotSame((string) Str::ulid(), (string) Str::ulid());\n    }\n\n    public function testItCanFreezeUlidsInAClosure()\n    {\n        $ulids = [];\n\n        $ulid = Str::freezeUlids(function ($ulid) use (&$ulids) {\n            $ulids[] = $ulid;\n            $ulids[] = Str::ulid();\n            $ulids[] = Str::ulid();\n        });\n\n        $this->assertSame($ulid, $ulids[0]);\n        $this->assertSame((string) $ulid, (string) $ulids[0]);\n        $this->assertSame((string) $ulids[0], (string) $ulids[1]);\n        $this->assertSame($ulids[0], $ulids[1]);\n        $this->assertSame((string) $ulids[0], (string) $ulids[1]);\n        $this->assertSame($ulids[1], $ulids[2]);\n        $this->assertSame((string) $ulids[1], (string) $ulids[2]);\n        $this->assertNotSame(Str::ulid(), Str::ulid());\n        $this->assertNotSame((string) Str::ulid(), (string) Str::ulid());\n\n        Str::createUlidsNormally();\n    }\n\n    public function testItCreatesUlidsNormallyAfterFailureWithinFreezeMethod()\n    {\n        try {\n            Str::freezeUlids(function () {\n                Str::createUlidsUsing(fn () => Str::of('1234'));\n                $this->assertSame('1234', (string) Str::ulid());\n                throw new \\Exception('Something failed');\n            });\n        } catch (\\Exception) {\n            $this->assertNotSame('1234', (string) Str::ulid());\n        }\n    }\n\n    public function testItCanSpecifyASequenceOfUlidsToUtilise()\n    {\n        Str::createUlidsUsingSequence([\n            0 => ($zeroth = Str::ulid()),\n            1 => ($first = Str::ulid()),\n            // just generate a random one here...\n            3 => ($third = Str::ulid()),\n            // continue to generate random ulids...\n        ]);\n\n        $retrieved = Str::ulid();\n        $this->assertSame($zeroth, $retrieved);\n        $this->assertSame((string) $zeroth, (string) $retrieved);\n\n        $retrieved = Str::ulid();\n        $this->assertSame($first, $retrieved);\n        $this->assertSame((string) $first, (string) $retrieved);\n\n        $retrieved = Str::ulid();\n        $this->assertFalse(in_array($retrieved, [$zeroth, $first, $third], true));\n        $this->assertFalse(in_array((string) $retrieved, [(string) $zeroth, (string) $first, (string) $third], true));\n\n        $retrieved = Str::ulid();\n        $this->assertSame($third, $retrieved);\n        $this->assertSame((string) $third, (string) $retrieved);\n\n        $retrieved = Str::ulid();\n        $this->assertFalse(in_array($retrieved, [$zeroth, $first, $third], true));\n        $this->assertFalse(in_array((string) $retrieved, [(string) $zeroth, (string) $first, (string) $third], true));\n\n        Str::createUlidsNormally();\n    }\n\n    public function testItCanSpecifyAFallbackForAUlidSequence()\n    {\n        Str::createUlidsUsingSequence(\n            [Str::ulid(), Str::ulid()],\n            fn () => throw new Exception('Out of Ulids'),\n        );\n        Str::ulid();\n        Str::ulid();\n\n        try {\n            $this->expectExceptionMessage('Out of Ulids');\n            Str::ulid();\n            $this->fail();\n        } finally {\n            Str::createUlidsNormally();\n        }\n    }\n\n    public function testPasswordCreation()\n    {\n        $this->assertTrue(strlen(Str::password()) === 32);\n\n        $this->assertStringNotContainsString(' ', Str::password());\n        $this->assertStringContainsString(' ', Str::password(spaces: true));\n\n        $this->assertTrue(\n            Str::of(Str::password())->contains(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])\n        );\n    }\n\n    public function testToBase64()\n    {\n        $this->assertSame(base64_encode('foo'), Str::toBase64('foo'));\n        $this->assertSame(base64_encode('foobar'), Str::toBase64('foobar'));\n    }\n\n    public function testFromBase64()\n    {\n        $this->assertSame('foo', Str::fromBase64(base64_encode('foo')));\n        $this->assertSame('foobar', Str::fromBase64(base64_encode('foobar'), true));\n    }\n\n    public function testChopStart()\n    {\n        foreach ([\n            '' => ['', ''],\n            'Laravel' => ['', 'Laravel'],\n            'Ship it' => [['', 'Ship '], 'it'],\n            'http://laravel.com' => ['http://', 'laravel.com'],\n            'http://-http://' => ['http://', '-http://'],\n            'http://laravel.com' => ['htp:/', 'http://laravel.com'],\n            'http://laravel.com' => ['http://www.', 'http://laravel.com'],\n            'http://laravel.com' => ['-http://', 'http://laravel.com'],\n            'http://laravel.com' => [['https://', 'http://'], 'laravel.com'],\n            'http://www.laravel.com' => [['http://', 'www.'], 'www.laravel.com'],\n            'http://http-is-fun.test' => ['http://', 'http-is-fun.test'],\n            // Multibyte emoji tests\n            '🌊✋' => ['🌊', '✋'],\n            '🌊✋' => ['✋', '🌊✋'],\n            '🚀🌟💫' => ['🚀', '🌟💫'],\n            '🚀🌟💫' => ['🚀🌟', '💫'],\n            // Multibyte character tests (Japanese, Chinese, Arabic, etc.)\n            'こんにちは世界' => ['こんにちは', '世界'],\n            '你好世界' => ['你好', '世界'],\n            'مرحبا بك' => ['مرحبا ', 'بك'],\n            // Mixed multibyte and ASCII\n            '🎉Laravel' => ['🎉', 'Laravel'],\n            'Hello🌍World' => ['Hello🌍', 'World'],\n            // Multiple needle array with multibyte\n            '🌊✋🎉' => [['🚀', '🌊'], '✋🎉'],\n            'こんにちは世界' => [['Hello', 'こんにちは'], '世界'],\n        ] as $subject => $value) {\n            [$needle, $expected] = $value;\n\n            $this->assertSame($expected, Str::chopStart($subject, $needle));\n        }\n    }\n\n    public function testChopEnd()\n    {\n        foreach ([\n            '' => ['', ''],\n            'Laravel' => ['', 'Laravel'],\n            'Ship it' => [['', ' it'], 'Ship'],\n            'path/to/file.php' => ['.php', 'path/to/file'],\n            '.php-.php' => ['.php', '.php-'],\n            'path/to/file.php' => ['.ph', 'path/to/file.php'],\n            'path/to/file.php' => ['foo.php', 'path/to/file.php'],\n            'path/to/file.php' => ['.php-', 'path/to/file.php'],\n            'path/to/file.php' => [['.html', '.php'], 'path/to/file'],\n            'path/to/file.php' => [['.php', 'file'], 'path/to/file'],\n            'path/to/php.php' => ['.php', 'path/to/php'],\n            // Multibyte emoji tests\n            '✋🌊' => ['🌊', '✋'],\n            '✋🌊' => ['✋', '✋🌊'],\n            '🌟💫🚀' => ['🚀', '🌟💫'],\n            '🌟💫🚀' => ['💫🚀', '🌟'],\n            // Multibyte character tests (Japanese, Chinese, Arabic, etc.)\n            '世界こんにちは' => ['こんにちは', '世界'],\n            '世界你好' => ['你好', '世界'],\n            'بك مرحبا' => [' مرحبا', 'بك'],\n            // Mixed multibyte and ASCII\n            'Laravel🎉' => ['🎉', 'Laravel'],\n            'Hello🌍World' => ['World', 'Hello🌍'],\n            // Multiple needle array with multibyte\n            '🎉✋🌊' => [['🚀', '🌊'], '🎉✋'],\n            '世界こんにちは' => [['Hello', 'こんにちは'], '世界'],\n        ] as $subject => $value) {\n            [$needle, $expected] = $value;\n\n            $this->assertSame($expected, Str::chopEnd($subject, $needle));\n        }\n    }\n\n    public function testReplaceMatches()\n    {\n        // Test basic string replacement\n        $this->assertSame('foo bar bar', Str::replaceMatches('/baz/', 'bar', 'foo baz bar'));\n        $this->assertSame('foo baz baz', Str::replaceMatches('/404/', 'found', 'foo baz baz'));\n\n        // Test with array of patterns\n        $this->assertSame('foo XXX YYY', Str::replaceMatches(['/bar/', '/baz/'], ['XXX', 'YYY'], 'foo bar baz'));\n\n        // Test with callback\n        $result = Str::replaceMatches('/ba(.)/', function ($match) {\n            return 'ba'.strtoupper($match[1]);\n        }, 'foo baz bar');\n\n        $this->assertSame('foo baZ baR', $result);\n\n        $result = Str::replaceMatches('/(\\d+)/', function ($match) {\n            return $match[1] * 2;\n        }, 'foo 123 bar 456');\n\n        $this->assertSame('foo 246 bar 912', $result);\n\n        // Test with limit parameter\n        $this->assertSame('foo baz baz', Str::replaceMatches('/ba(.)/', 'ba$1', 'foo baz baz', 1));\n\n        $result = Str::replaceMatches('/ba(.)/', function ($match) {\n            return 'ba'.strtoupper($match[1]);\n        }, 'foo baz baz bar', 1);\n\n        $this->assertSame('foo baZ baz bar', $result);\n    }\n\n    public function testPlural(): void\n    {\n        $this->assertSame('Laracon', Str::plural('Laracon', 1));\n        $this->assertSame('Laracon', Str::plural('Laracon', [2025]));\n\n        $this->assertSame('Laracons', Str::plural('Laracon', 3));\n        $this->assertSame('Laracons', Str::plural('Laracon', [2024, 2025]));\n\n        $this->assertSame('1 Laracon', Str::plural('Laracon', 1, prependCount: true));\n        $this->assertSame('1 Laracon', Str::plural('Laracon', [2025], prependCount: true));\n\n        $this->assertSame('1,000 Laracons', Str::plural('Laracon', 1000, prependCount: true));\n        $this->assertSame('2 Laracons', Str::plural('Laracon', [2024, 2025], prependCount: true));\n    }\n\n    public function testPluralPascal(): void\n    {\n        // Test basic functionality with default count\n        $this->assertSame('UserGroups', Str::pluralPascal('UserGroup'));\n        $this->assertSame('ProductCategories', Str::pluralPascal('ProductCategory'));\n\n        // Test with different count values and array\n        $this->assertSame('UserGroups', Str::pluralPascal('UserGroup', 0)); // plural\n        $this->assertSame('UserGroup', Str::pluralPascal('UserGroup', 1));  // singular\n        $this->assertSame('UserGroups', Str::pluralPascal('UserGroup', 2)); // plural\n        $this->assertSame('UserGroups', Str::pluralPascal('UserGroup', []));   // plural (empty array count is 0)\n\n        // Test with Countable\n        $countable = new class implements \\Countable\n        {\n            public function count(): int\n            {\n                return 3;\n            }\n        };\n\n        $this->assertSame('UserGroups', Str::pluralPascal('UserGroup', $countable));\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportStringableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\HtmlString;\nuse Illuminate\\Support\\Stringable;\nuse Illuminate\\Support\\Uri;\nuse Illuminate\\Tests\\Support\\Fixtures\\StringableObjectStub;\nuse League\\CommonMark\\Environment\\EnvironmentBuilderInterface;\nuse League\\CommonMark\\Extension\\ExtensionInterface;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportStringableTest extends TestCase\n{\n    protected Container $container;\n\n    /**\n     * @param  string  $string\n     * @return \\Illuminate\\Support\\Stringable\n     */\n    protected function stringable($string = '')\n    {\n        return new Stringable($string);\n    }\n\n    public function testClassBasename()\n    {\n        $this->assertEquals(\n            class_basename(static::class),\n            $this->stringable(static::class)->classBasename()\n        );\n    }\n\n    public function testIsAscii()\n    {\n        $this->assertTrue($this->stringable('A')->isAscii());\n        $this->assertFalse($this->stringable('ù')->isAscii());\n    }\n\n    public function testIsUrl()\n    {\n        $this->assertTrue($this->stringable('https://laravel.com')->isUrl());\n        $this->assertTrue($this->stringable('https://laravel.com')->isUrl(['https']));\n\n        $this->assertFalse($this->stringable('invalid url')->isUrl());\n        $this->assertFalse($this->stringable('https://laravel.com')->isUrl(['http']));\n    }\n\n    public function testIsUuid()\n    {\n        $this->assertTrue($this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98e7b15')->isUuid());\n        $this->assertTrue($this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98e7b15')->isUuid(4));\n\n        $this->assertFalse($this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98')->isUuid());\n        $this->assertFalse($this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98e7b15')->isUuid(7));\n    }\n\n    public function testIsUlid()\n    {\n        $this->assertTrue($this->stringable('01GJSNW9MAF792C0XYY8RX6QFT')->isUlid());\n        $this->assertFalse($this->stringable('01GJSNW9MAF-792C0XYY8RX6ssssss-QFT')->isUlid());\n    }\n\n    public function testIsJson()\n    {\n        $this->assertTrue($this->stringable('1')->isJson());\n        $this->assertTrue($this->stringable('[1,2,3]')->isJson());\n        $this->assertTrue($this->stringable('[1,   2,   3]')->isJson());\n        $this->assertTrue($this->stringable('{\"first\": \"John\", \"last\": \"Doe\"}')->isJson());\n        $this->assertTrue($this->stringable('[{\"first\": \"John\", \"last\": \"Doe\"}, {\"first\": \"Jane\", \"last\": \"Doe\"}]')->isJson());\n\n        $this->assertFalse($this->stringable('1,')->isJson());\n        $this->assertFalse($this->stringable('[1,2,3')->isJson());\n        $this->assertFalse($this->stringable('[1,   2   3]')->isJson());\n        $this->assertFalse($this->stringable('{first: \"John\"}')->isJson());\n        $this->assertFalse($this->stringable('[{first: \"John\"}, {first: \"Jane\"}]')->isJson());\n        $this->assertFalse($this->stringable('')->isJson());\n        $this->assertFalse($this->stringable(null)->isJson());\n    }\n\n    public function testIsMatch()\n    {\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch('/.*,.*!/'));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch('/^.*$(.*)/'));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch('/laravel/i'));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch('/^(.*(.*(.*)))/'));\n\n        $this->assertFalse($this->stringable('Hello, Laravel!')->isMatch('/H.o/'));\n        $this->assertFalse($this->stringable('Hello, Laravel!')->isMatch('/^laravel!/i'));\n        $this->assertFalse($this->stringable('Hello, Laravel!')->isMatch('/laravel!(.*)/'));\n        $this->assertFalse($this->stringable('Hello, Laravel!')->isMatch('/^[a-zA-Z,!]+$/'));\n\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch(['/.*,.*!/', '/H.o/']));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch(['/^laravel!/i', '/^.*$(.*)/']));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch(['/laravel/i', '/laravel!(.*)/']));\n        $this->assertTrue($this->stringable('Hello, Laravel!')->isMatch(['/^[a-zA-Z,!]+$/', '/^(.*(.*(.*)))/']));\n    }\n\n    public function testIsEmpty()\n    {\n        $this->assertTrue($this->stringable('')->isEmpty());\n        $this->assertFalse($this->stringable('A')->isEmpty());\n        $this->assertFalse($this->stringable('0')->isEmpty());\n    }\n\n    public function testIsNotEmpty()\n    {\n        $this->assertFalse($this->stringable('')->isNotEmpty());\n        $this->assertTrue($this->stringable('A')->isNotEmpty());\n    }\n\n    public function testPluralStudly()\n    {\n        $this->assertSame('LaraCon', (string) $this->stringable('LaraCon')->pluralStudly(1));\n        $this->assertSame('LaraCons', (string) $this->stringable('LaraCon')->pluralStudly(2));\n        $this->assertSame('LaraCon', (string) $this->stringable('LaraCon')->pluralStudly(-1));\n        $this->assertSame('LaraCons', (string) $this->stringable('LaraCon')->pluralStudly(-2));\n    }\n\n    public function testPluralPascal()\n    {\n        $this->assertSame('LaraCons', (string) $this->stringable('LaraCon')->pluralPascal(2));\n        $this->assertSame('LaraCon', (string) $this->stringable('LaraCon')->pluralPascal(1));\n        $this->assertSame('LaraCons', (string) $this->stringable('LaraCon')->pluralPascal(-2));\n        $this->assertSame('LaraCon', (string) $this->stringable('LaraCon')->pluralPascal(-1));\n    }\n\n    public function testMatch()\n    {\n        $stringable = $this->stringable('foo bar');\n\n        $this->assertSame('bar', (string) $stringable->match('/bar/'));\n        $this->assertSame('bar', (string) $stringable->match('/foo (.*)/'));\n        $this->assertTrue($stringable->match('/nothing/')->isEmpty());\n\n        $this->assertEquals(['bar', 'bar'], $this->stringable('bar foo bar')->matchAll('/bar/')->all());\n\n        $stringable = $this->stringable('bar fun bar fly');\n\n        $this->assertEquals(['un', 'ly'], $stringable->matchAll('/f(\\w*)/')->all());\n        $this->assertTrue($stringable->matchAll('/nothing/')->isEmpty());\n    }\n\n    public function testTake()\n    {\n        $this->assertSame('ab', (string) $this->stringable('abcdef')->take(2));\n        $this->assertSame('ef', (string) $this->stringable('abcdef')->take(-2));\n    }\n\n    public function testTest()\n    {\n        $stringable = $this->stringable('foo bar');\n\n        $this->assertTrue($stringable->test('/bar/'));\n        $this->assertTrue($stringable->test('/foo (.*)/'));\n    }\n\n    public function testTrim()\n    {\n        $this->assertSame('foo', (string) $this->stringable(' foo ')->trim());\n    }\n\n    public function testLtrim()\n    {\n        $this->assertSame('foo ', (string) $this->stringable(' foo ')->ltrim());\n    }\n\n    public function testRtrim()\n    {\n        $this->assertSame(' foo', (string) $this->stringable(' foo ')->rtrim());\n    }\n\n    public function testCanBeLimitedByWords()\n    {\n        $this->assertSame('Taylor...', (string) $this->stringable('Taylor Otwell')->words(1));\n        $this->assertSame('Taylor___', (string) $this->stringable('Taylor Otwell')->words(1, '___'));\n        $this->assertSame('Taylor Otwell', (string) $this->stringable('Taylor Otwell')->words(3));\n    }\n\n    public function testUcwords()\n    {\n        $this->assertSame('Laravel', (string) $this->stringable('laravel')->ucwords());\n        $this->assertSame('Laravel Framework', (string) $this->stringable('laravel framework')->ucwords());\n        $this->assertSame('Laravel-Framework', (string) $this->stringable('laravel-framework')->ucwords('-'));\n        $this->assertSame('Мама', (string) $this->stringable('мама')->ucwords());\n        $this->assertSame('Мама Мыла Раму', (string) $this->stringable('мама мыла раму')->ucwords());\n        $this->assertSame('JJ Watt', (string) $this->stringable('JJ watt')->ucwords());\n    }\n\n    public function testUnless()\n    {\n        $this->assertSame('unless false', (string) $this->stringable('unless')->unless(false, function ($stringable, $value) {\n            return $stringable->append(' false');\n        }));\n\n        $this->assertSame('unless true fallbacks to default', (string) $this->stringable('unless')->unless(true, function ($stringable, $value) {\n            return $stringable->append($value);\n        }, function ($stringable) {\n            return $stringable->append(' true fallbacks to default');\n        }));\n    }\n\n    public function testWhenContains()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('stark')->whenContains('tar', function ($stringable) {\n            return $stringable->prepend('Tony ')->title();\n        }, function ($stringable) {\n            return $stringable->prepend('Arno ')->title();\n        }));\n\n        $this->assertSame('stark', (string) $this->stringable('stark')->whenContains('xxx', function ($stringable) {\n            return $stringable->prepend('Tony ')->title();\n        }));\n\n        $this->assertSame('Arno Stark', (string) $this->stringable('stark')->whenContains('xxx', function ($stringable) {\n            return $stringable->prepend('Tony ')->title();\n        }, function ($stringable) {\n            return $stringable->prepend('Arno ')->title();\n        }));\n    }\n\n    public function testWhenContainsAll()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenContainsAll(['tony', 'stark'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n\n        $this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenContainsAll(['xxx'], function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('TonyStark', (string) $this->stringable('tony stark')->whenContainsAll(['tony', 'xxx'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n    }\n\n    public function testDedup()\n    {\n        $this->assertSame(' laravel php framework ', (string) $this->stringable(' laravel   php  framework ')->deduplicate());\n        $this->assertSame('what', (string) $this->stringable('whaaat')->deduplicate('a'));\n        $this->assertSame('/some/odd/path/', (string) $this->stringable('/some//odd//path/')->deduplicate('/'));\n        $this->assertSame('ムだム', (string) $this->stringable('ムだだム')->deduplicate('だ'));\n        $this->assertSame(' laravel forever ', (string) $this->stringable(' laravell    foreverrr  ')->deduplicate([' ', 'l', 'r']));\n    }\n\n    public function testDirname()\n    {\n        $this->assertSame('/framework/tests', (string) $this->stringable('/framework/tests/Support')->dirname());\n        $this->assertSame('/framework', (string) $this->stringable('/framework/tests/Support')->dirname(2));\n        $this->assertSame('.', (string) $this->stringable('framework')->dirname());\n\n        $this->assertSame('.', (string) $this->stringable('.')->dirname());\n\n        $this->assertSame(DIRECTORY_SEPARATOR, (string) $this->stringable('/framework/')->dirname());\n        $this->assertSame(DIRECTORY_SEPARATOR, (string) $this->stringable('/')->dirname());\n    }\n\n    public function testUcsplitOnStringable()\n    {\n        $this->assertSame(['Taylor', 'Otwell'], $this->stringable('TaylorOtwell')->ucsplit()->toArray());\n        $this->assertSame(['Hello', 'From', 'Laravel'], $this->stringable('HelloFromLaravel')->ucsplit()->toArray());\n        $this->assertSame(['He_llo_', 'World'], $this->stringable('He_llo_World')->ucsplit()->toArray());\n    }\n\n    public function testWhenEndsWith()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenEndsWith('ark', function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenEndsWith(['kra', 'ark'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n\n        $this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenEndsWith(['xxx'], function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('TonyStark', (string) $this->stringable('tony stark')->whenEndsWith(['tony', 'xxx'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n    }\n\n    public function testWhenDoesntEndWith()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntEndWith('ark', function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['kra', 'ark'], function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['xxx'], function ($stringable) {\n            return $stringable;\n        }));\n\n        $this->assertSame('TonyStark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['tony', 'xxx'], function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n    }\n\n    public function testWhenExactly()\n    {\n        $this->assertSame('Nailed it...!', (string) $this->stringable('Tony Stark')->whenExactly('Tony Stark', function ($stringable) {\n            return 'Nailed it...!';\n        }, function ($stringable) {\n            return 'Swing and a miss...!';\n        }));\n\n        $this->assertSame('Swing and a miss...!', (string) $this->stringable('Tony Stark')->whenExactly('Iron Man', function ($stringable) {\n            return 'Nailed it...!';\n        }, function ($stringable) {\n            return 'Swing and a miss...!';\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('Tony Stark')->whenExactly('Iron Man', function ($stringable) {\n            return 'Nailed it...!';\n        }));\n    }\n\n    public function testWhenNotExactly()\n    {\n        $this->assertSame(\n            'Iron Man',\n            (string) $this->stringable('Tony')->whenNotExactly('Tony Stark', function ($stringable) {\n                return 'Iron Man';\n            }));\n\n        $this->assertSame(\n            'Swing and a miss...!',\n            (string) $this->stringable('Tony Stark')->whenNotExactly('Tony Stark', function ($stringable) {\n                return 'Iron Man';\n            }, function ($stringable) {\n                return 'Swing and a miss...!';\n            }));\n    }\n\n    public function testWhenIs()\n    {\n        $this->assertSame('Winner: /', (string) $this->stringable('/')->whenIs('/', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }, function ($stringable) {\n            return 'Try again';\n        }));\n\n        $this->assertSame('/', (string) $this->stringable('/')->whenIs(' /', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }));\n\n        $this->assertSame('Try again', (string) $this->stringable('/')->whenIs(' /', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }, function ($stringable) {\n            return 'Try again';\n        }));\n\n        $this->assertSame('Winner: foo/bar/baz', (string) $this->stringable('foo/bar/baz')->whenIs('foo/*', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }));\n    }\n\n    public function testWhenIsAscii()\n    {\n        $this->assertSame('Ascii: A', (string) $this->stringable('A')->whenIsAscii(function ($stringable) {\n            return $stringable->prepend('Ascii: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Ascii: ');\n        }));\n\n        $this->assertSame('ù', (string) $this->stringable('ù')->whenIsAscii(function ($stringable) {\n            return $stringable->prepend('Ascii: ');\n        }));\n\n        $this->assertSame('Not Ascii: ù', (string) $this->stringable('ù')->whenIsAscii(function ($stringable) {\n            return $stringable->prepend('Ascii: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Ascii: ');\n        }));\n    }\n\n    public function testWhenIsUuid()\n    {\n        $this->assertSame('Uuid: 2cdc7039-65a6-4ac7-8e5d-d554a98e7b15', (string) $this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98e7b15')->whenIsUuid(function ($stringable) {\n            return $stringable->prepend('Uuid: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Uuid: ');\n        }));\n\n        $this->assertSame('2cdc7039-65a6-4ac7-8e5d-d554a98', (string) $this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98')->whenIsUuid(function ($stringable) {\n            return $stringable->prepend('Uuid: ');\n        }));\n\n        $this->assertSame('Not Uuid: 2cdc7039-65a6-4ac7-8e5d-d554a98', (string) $this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98')->whenIsUuid(function ($stringable) {\n            return $stringable->prepend('Uuid: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Uuid: ');\n        }));\n    }\n\n    public function testWhenIsUlid()\n    {\n        $this->assertSame('Ulid: 01GJSNW9MAF792C0XYY8RX6QFT', (string) $this->stringable('01GJSNW9MAF792C0XYY8RX6QFT')->whenIsUlid(function ($stringable) {\n            return $stringable->prepend('Ulid: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Ulid: ');\n        }));\n\n        $this->assertSame('2cdc7039-65a6-4ac7-8e5d-d554a98', (string) $this->stringable('2cdc7039-65a6-4ac7-8e5d-d554a98')->whenIsUlid(function ($stringable) {\n            return $stringable->prepend('Ulid: ');\n        }));\n\n        $this->assertSame('Not Ulid: ss-01GJSNW9MAF792C0XYY8RX6QFT', (string) $this->stringable('ss-01GJSNW9MAF792C0XYY8RX6QFT')->whenIsUlid(function ($stringable) {\n            return $stringable->prepend('Ulid: ');\n        }, function ($stringable) {\n            return $stringable->prepend('Not Ulid: ');\n        }));\n    }\n\n    public function testWhenTest()\n    {\n        $this->assertSame('Winner: foo bar', (string) $this->stringable('foo bar')->whenTest('/bar/', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }, function ($stringable) {\n            return 'Try again';\n        }));\n\n        $this->assertSame('Try again', (string) $this->stringable('foo bar')->whenTest('/link/', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }, function ($stringable) {\n            return 'Try again';\n        }));\n\n        $this->assertSame('foo bar', (string) $this->stringable('foo bar')->whenTest('/link/', function ($stringable) {\n            return $stringable->prepend('Winner: ');\n        }));\n    }\n\n    public function testWhenStartsWith()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenStartsWith('ton', function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenStartsWith(['ton', 'not'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n\n        $this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenStartsWith(['xxx'], function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenStartsWith(['tony', 'xxx'], function ($stringable) {\n            return $stringable->title();\n        }, function ($stringable) {\n            return $stringable->studly();\n        }));\n    }\n\n    public function testWhenDoesntStartWith()\n    {\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith('ton', function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['ton', 'not'], function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n\n        $this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['xxx'], function ($stringable) {\n            return $stringable;\n        }));\n\n        $this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['tony', 'xxx'], function ($stringable) {\n            return $stringable->studly();\n        }, function ($stringable) {\n            return $stringable->title();\n        }));\n    }\n\n    public function testWhenEmpty()\n    {\n        tap($this->stringable(), function ($stringable) {\n            $this->assertSame($stringable, $stringable->whenEmpty(function () {\n                //\n            }));\n        });\n\n        $this->assertSame('empty', (string) $this->stringable()->whenEmpty(function () {\n            return 'empty';\n        }));\n\n        $this->assertSame('not-empty', (string) $this->stringable('not-empty')->whenEmpty(function () {\n            return 'empty';\n        }));\n    }\n\n    public function testWhenNotEmpty()\n    {\n        tap($this->stringable(), function ($stringable) {\n            $this->assertSame($stringable, $stringable->whenNotEmpty(function ($stringable) {\n                return $stringable.'.';\n            }));\n        });\n\n        $this->assertSame('', (string) $this->stringable()->whenNotEmpty(function ($stringable) {\n            return $stringable.'.';\n        }));\n\n        $this->assertSame('Not empty.', (string) $this->stringable('Not empty')->whenNotEmpty(function ($stringable) {\n            return $stringable.'.';\n        }));\n    }\n\n    public function testWhenFalse()\n    {\n        $this->assertSame('when', (string) $this->stringable('when')->when(false, function ($stringable, $value) {\n            return $stringable->append($value)->append('false');\n        }));\n\n        $this->assertSame('when false fallbacks to default', (string) $this->stringable('when false ')->when(false, function ($stringable, $value) {\n            return $stringable->append($value);\n        }, function ($stringable) {\n            return $stringable->append('fallbacks to default');\n        }));\n    }\n\n    public function testWhenTrue()\n    {\n        $this->assertSame('when true', (string) $this->stringable('when ')->when(true, function ($stringable) {\n            return $stringable->append('true');\n        }));\n\n        $this->assertSame('gets a value from if', (string) $this->stringable('gets a value ')->when('from if', function ($stringable, $value) {\n            return $stringable->append($value);\n        }, function ($stringable) {\n            return $stringable->append('fallbacks to default');\n        }));\n    }\n\n    public function testUnlessTruthy()\n    {\n        $this->assertSame('unless', (string) $this->stringable('unless')->unless(1, function ($stringable, $value) {\n            return $stringable->append($value)->append('true');\n        }));\n\n        $this->assertSame('unless true fallbacks to default with value 1',\n            (string) $this->stringable('unless true ')->unless(1, function ($stringable, $value) {\n                return $stringable->append($value);\n            }, function ($stringable, $value) {\n                return $stringable->append('fallbacks to default with value ')->append($value);\n            }));\n    }\n\n    public function testUnlessFalsy()\n    {\n        $this->assertSame('unless 0', (string) $this->stringable('unless ')->unless(0, function ($stringable, $value) {\n            return $stringable->append($value);\n        }));\n\n        $this->assertSame('gets the value 0',\n            (string) $this->stringable('gets the value ')->unless(0, function ($stringable, $value) {\n                return $stringable->append($value);\n            }, function ($stringable) {\n                return $stringable->append('fallbacks to default');\n            }));\n    }\n\n    public function testTrimmedOnlyWhereNecessary()\n    {\n        $this->assertSame(' Taylor Otwell ', (string) $this->stringable(' Taylor Otwell ')->words(3));\n        $this->assertSame(' Taylor...', (string) $this->stringable(' Taylor Otwell ')->words(1));\n    }\n\n    public function testTitle()\n    {\n        $this->assertSame('Jefferson Costella', (string) $this->stringable('jefferson costella')->title());\n        $this->assertSame('Jefferson Costella', (string) $this->stringable('jefFErson coSTella')->title());\n    }\n\n    public function testWithoutWordsDoesntProduceError()\n    {\n        $nbsp = chr(0xC2).chr(0xA0);\n        $this->assertSame(' ', (string) $this->stringable(' ')->words());\n        $this->assertEquals($nbsp, (string) $this->stringable($nbsp)->words());\n    }\n\n    public function testAscii()\n    {\n        $this->assertSame('@', (string) $this->stringable('@')->ascii());\n        $this->assertSame('u', (string) $this->stringable('ü')->ascii());\n    }\n\n    public function testTransliterate()\n    {\n        $this->assertSame('HHH', (string) $this->stringable('🎂🚧🏆')->transliterate('H'));\n        $this->assertSame('Hello', (string) $this->stringable('🎂')->transliterate('Hello'));\n    }\n\n    public function testNewLine()\n    {\n        $this->assertSame('Laravel'.PHP_EOL, (string) $this->stringable('Laravel')->newLine());\n        $this->assertSame('foo'.PHP_EOL.PHP_EOL.'bar', (string) $this->stringable('foo')->newLine(2)->append('bar'));\n    }\n\n    public function testAsciiWithSpecificLocale()\n    {\n        $this->assertSame('h H sht Sht a A ia yo', (string) $this->stringable('х Х щ Щ ъ Ъ иа йо')->ascii('bg'));\n        $this->assertSame('ae oe ue Ae Oe Ue', (string) $this->stringable('ä ö ü Ä Ö Ü')->ascii('de'));\n    }\n\n    public function testStartsWith()\n    {\n        $this->assertTrue($this->stringable('jason')->startsWith('jas'));\n        $this->assertTrue($this->stringable('jason')->startsWith('jason'));\n        $this->assertTrue($this->stringable('jason')->startsWith(['jas']));\n        $this->assertTrue($this->stringable('jason')->startsWith(['day', 'jas']));\n        $this->assertTrue($this->stringable('jason')->startsWith(collect(['day', 'jas'])));\n        $this->assertFalse($this->stringable('jason')->startsWith('day'));\n        $this->assertFalse($this->stringable('jason')->startsWith(['day']));\n        $this->assertFalse($this->stringable('jason')->startsWith(null));\n        $this->assertFalse($this->stringable('jason')->startsWith([null]));\n        $this->assertFalse($this->stringable('0123')->startsWith([null]));\n        $this->assertTrue($this->stringable('0123')->startsWith(0));\n        $this->assertFalse($this->stringable('jason')->startsWith('J'));\n        $this->assertFalse($this->stringable('jason')->startsWith(''));\n        $this->assertFalse($this->stringable('7')->startsWith(' 7'));\n        $this->assertTrue($this->stringable('7a')->startsWith('7'));\n        $this->assertTrue($this->stringable('7a')->startsWith(7));\n        $this->assertTrue($this->stringable('7.12a')->startsWith(7.12));\n        $this->assertFalse($this->stringable('7.12a')->startsWith(7.13));\n        $this->assertTrue($this->stringable(7.123)->startsWith('7'));\n        $this->assertTrue($this->stringable(7.123)->startsWith('7.12'));\n        $this->assertFalse($this->stringable(7.123)->startsWith('7.13'));\n        // Test for multibyte string support\n        $this->assertTrue($this->stringable('Jönköping')->startsWith('Jö'));\n        $this->assertTrue($this->stringable('Malmö')->startsWith('Malmö'));\n        $this->assertFalse($this->stringable('Jönköping')->startsWith('Jonko'));\n        $this->assertFalse($this->stringable('Malmö')->startsWith('Malmo'));\n    }\n\n    public function testDoesntStartWith()\n    {\n        $this->assertFalse($this->stringable('jason')->doesntStartWith('jas'));\n        $this->assertFalse($this->stringable('jason')->doesntStartWith('jason'));\n        $this->assertFalse($this->stringable('jason')->doesntStartWith(['jas']));\n        $this->assertFalse($this->stringable('jason')->doesntStartWith(['day', 'jas']));\n        $this->assertFalse($this->stringable('jason')->doesntStartWith(collect(['day', 'jas'])));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith('day'));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith(['day']));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith(null));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith([null]));\n        $this->assertTrue($this->stringable('0123')->doesntStartWith([null]));\n        $this->assertFalse($this->stringable('0123')->doesntStartWith(0));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith('J'));\n        $this->assertTrue($this->stringable('jason')->doesntStartWith(''));\n        $this->assertTrue($this->stringable('7')->doesntStartWith(' 7'));\n        $this->assertFalse($this->stringable('7a')->doesntStartWith('7'));\n        $this->assertFalse($this->stringable('7a')->doesntStartWith(7));\n        $this->assertFalse($this->stringable('7.12a')->doesntStartWith(7.12));\n        $this->assertTrue($this->stringable('7.12a')->doesntStartWith(7.13));\n        $this->assertFalse($this->stringable(7.123)->doesntStartWith('7'));\n        $this->assertFalse($this->stringable(7.123)->doesntStartWith('7.12'));\n        $this->assertTrue($this->stringable(7.123)->doesntStartWith('7.13'));\n        // Test for multibyte string support\n        $this->assertFalse($this->stringable('Jönköping')->doesntStartWith('Jö'));\n        $this->assertFalse($this->stringable('Malmö')->doesntStartWith('Malmö'));\n        $this->assertTrue($this->stringable('Jönköping')->doesntStartWith('Jonko'));\n        $this->assertTrue($this->stringable('Malmö')->doesntStartWith('Malmo'));\n    }\n\n    public function testEndsWith()\n    {\n        $this->assertTrue($this->stringable('jason')->endsWith('on'));\n        $this->assertTrue($this->stringable('jason')->endsWith('jason'));\n        $this->assertTrue($this->stringable('jason')->endsWith(['on']));\n        $this->assertTrue($this->stringable('jason')->endsWith(['no', 'on']));\n        $this->assertTrue($this->stringable('jason')->endsWith(collect(['no', 'on'])));\n        $this->assertFalse($this->stringable('jason')->endsWith('no'));\n        $this->assertFalse($this->stringable('jason')->endsWith(['no']));\n        $this->assertFalse($this->stringable('jason')->endsWith(''));\n        $this->assertFalse($this->stringable('jason')->endsWith([null]));\n        $this->assertFalse($this->stringable('jason')->endsWith(null));\n        $this->assertFalse($this->stringable('jason')->endsWith('N'));\n        $this->assertFalse($this->stringable('7')->endsWith(' 7'));\n        $this->assertTrue($this->stringable('a7')->endsWith('7'));\n        $this->assertTrue($this->stringable('a7')->endsWith(7));\n        $this->assertTrue($this->stringable('a7.12')->endsWith(7.12));\n        $this->assertFalse($this->stringable('a7.12')->endsWith(7.13));\n        $this->assertTrue($this->stringable(0.27)->endsWith('7'));\n        $this->assertTrue($this->stringable(0.27)->endsWith('0.27'));\n        $this->assertFalse($this->stringable(0.27)->endsWith('8'));\n        // Test for multibyte string support\n        $this->assertTrue($this->stringable('Jönköping')->endsWith('öping'));\n        $this->assertTrue($this->stringable('Malmö')->endsWith('mö'));\n        $this->assertFalse($this->stringable('Jönköping')->endsWith('oping'));\n        $this->assertFalse($this->stringable('Malmö')->endsWith('mo'));\n    }\n\n    public function testDoesntEndWith()\n    {\n        $this->assertFalse($this->stringable('jason')->doesntEndWith('on'));\n        $this->assertFalse($this->stringable('jason')->doesntEndWith('jason'));\n        $this->assertFalse($this->stringable('jason')->doesntEndWith(['on']));\n        $this->assertFalse($this->stringable('jason')->doesntEndWith(['no', 'on']));\n        $this->assertFalse($this->stringable('jason')->doesntEndWith(collect(['no', 'on'])));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith('no'));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith(['no']));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith(''));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith([null]));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith(null));\n        $this->assertTrue($this->stringable('jason')->doesntEndWith('N'));\n        $this->assertTrue($this->stringable('7')->doesntEndWith(' 7'));\n        $this->assertFalse($this->stringable('a7')->doesntEndWith('7'));\n        $this->assertFalse($this->stringable('a7')->doesntEndWith(7));\n        $this->assertFalse($this->stringable('a7.12')->doesntEndWith(7.12));\n        $this->assertTrue($this->stringable('a7.12')->doesntEndWith(7.13));\n        $this->assertFalse($this->stringable(0.27)->doesntEndWith('7'));\n        $this->assertFalse($this->stringable(0.27)->doesntEndWith('0.27'));\n        $this->assertTrue($this->stringable(0.27)->doesntEndWith('8'));\n        // Test for multibyte string support\n        $this->assertFalse($this->stringable('Jönköping')->doesntEndWith('öping'));\n        $this->assertFalse($this->stringable('Malmö')->doesntEndWith('mö'));\n        $this->assertTrue($this->stringable('Jönköping')->doesntEndWith('oping'));\n        $this->assertTrue($this->stringable('Malmö')->doesntEndWith('mo'));\n    }\n\n    public function testExcerpt()\n    {\n        $this->assertSame('...is a beautiful morn...', (string) $this->stringable('This is a beautiful morning')->excerpt('beautiful', ['radius' => 5]));\n    }\n\n    public function testBefore()\n    {\n        $this->assertSame('han', (string) $this->stringable('hannah')->before('nah'));\n        $this->assertSame('ha', (string) $this->stringable('hannah')->before('n'));\n        $this->assertSame('ééé ', (string) $this->stringable('ééé hannah')->before('han'));\n        $this->assertSame('hannah', (string) $this->stringable('hannah')->before('xxxx'));\n        $this->assertSame('hannah', (string) $this->stringable('hannah')->before(''));\n        $this->assertSame('han', (string) $this->stringable('han0nah')->before('0'));\n        $this->assertSame('han', (string) $this->stringable('han0nah')->before(0));\n        $this->assertSame('han', (string) $this->stringable('han2nah')->before(2));\n    }\n\n    public function testBeforeLast()\n    {\n        $this->assertSame('yve', (string) $this->stringable('yvette')->beforeLast('tte'));\n        $this->assertSame('yvet', (string) $this->stringable('yvette')->beforeLast('t'));\n        $this->assertSame('ééé ', (string) $this->stringable('ééé yvette')->beforeLast('yve'));\n        $this->assertSame('', (string) $this->stringable('yvette')->beforeLast('yve'));\n        $this->assertSame('yvette', (string) $this->stringable('yvette')->beforeLast('xxxx'));\n        $this->assertSame('yvette', (string) $this->stringable('yvette')->beforeLast(''));\n        $this->assertSame('yv0et', (string) $this->stringable('yv0et0te')->beforeLast('0'));\n        $this->assertSame('yv0et', (string) $this->stringable('yv0et0te')->beforeLast(0));\n        $this->assertSame('yv2et', (string) $this->stringable('yv2et2te')->beforeLast(2));\n    }\n\n    public function testBetween()\n    {\n        $this->assertSame('abc', (string) $this->stringable('abc')->between('', 'c'));\n        $this->assertSame('abc', (string) $this->stringable('abc')->between('a', ''));\n        $this->assertSame('abc', (string) $this->stringable('abc')->between('', ''));\n        $this->assertSame('b', (string) $this->stringable('abc')->between('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('dddabc')->between('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('abcddd')->between('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('dddabcddd')->between('a', 'c'));\n        $this->assertSame('nn', (string) $this->stringable('hannah')->between('ha', 'ah'));\n        $this->assertSame('a]ab[b', (string) $this->stringable('[a]ab[b]')->between('[', ']'));\n        $this->assertSame('foo', (string) $this->stringable('foofoobar')->between('foo', 'bar'));\n        $this->assertSame('bar', (string) $this->stringable('foobarbar')->between('foo', 'bar'));\n    }\n\n    public function testBetweenFirst()\n    {\n        $this->assertSame('abc', (string) $this->stringable('abc')->betweenFirst('', 'c'));\n        $this->assertSame('abc', (string) $this->stringable('abc')->betweenFirst('a', ''));\n        $this->assertSame('abc', (string) $this->stringable('abc')->betweenFirst('', ''));\n        $this->assertSame('b', (string) $this->stringable('abc')->betweenFirst('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('dddabc')->betweenFirst('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('abcddd')->betweenFirst('a', 'c'));\n        $this->assertSame('b', (string) $this->stringable('dddabcddd')->betweenFirst('a', 'c'));\n        $this->assertSame('nn', (string) $this->stringable('hannah')->betweenFirst('ha', 'ah'));\n        $this->assertSame('a', (string) $this->stringable('[a]ab[b]')->betweenFirst('[', ']'));\n        $this->assertSame('foo', (string) $this->stringable('foofoobar')->betweenFirst('foo', 'bar'));\n        $this->assertSame('', (string) $this->stringable('foobarbar')->betweenFirst('foo', 'bar'));\n    }\n\n    public function testAfter()\n    {\n        $this->assertSame('nah', (string) $this->stringable('hannah')->after('han'));\n        $this->assertSame('nah', (string) $this->stringable('hannah')->after('n'));\n        $this->assertSame('nah', (string) $this->stringable('ééé hannah')->after('han'));\n        $this->assertSame('hannah', (string) $this->stringable('hannah')->after('xxxx'));\n        $this->assertSame('hannah', (string) $this->stringable('hannah')->after(''));\n        $this->assertSame('nah', (string) $this->stringable('han0nah')->after('0'));\n        $this->assertSame('nah', (string) $this->stringable('han0nah')->after(0));\n        $this->assertSame('nah', (string) $this->stringable('han2nah')->after(2));\n    }\n\n    public function testAfterLast()\n    {\n        $this->assertSame('tte', (string) $this->stringable('yvette')->afterLast('yve'));\n        $this->assertSame('e', (string) $this->stringable('yvette')->afterLast('t'));\n        $this->assertSame('e', (string) $this->stringable('ééé yvette')->afterLast('t'));\n        $this->assertSame('', (string) $this->stringable('yvette')->afterLast('tte'));\n        $this->assertSame('yvette', (string) $this->stringable('yvette')->afterLast('xxxx'));\n        $this->assertSame('yvette', (string) $this->stringable('yvette')->afterLast(''));\n        $this->assertSame('te', (string) $this->stringable('yv0et0te')->afterLast('0'));\n        $this->assertSame('te', (string) $this->stringable('yv0et0te')->afterLast(0));\n        $this->assertSame('te', (string) $this->stringable('yv2et2te')->afterLast(2));\n        $this->assertSame('foo', (string) $this->stringable('----foo')->afterLast('---'));\n    }\n\n    public function testContains()\n    {\n        $this->assertTrue($this->stringable('taylor')->contains('ylo'));\n        $this->assertTrue($this->stringable('taylor')->contains('taylor'));\n        $this->assertTrue($this->stringable('taylor')->contains(['ylo']));\n        $this->assertTrue($this->stringable('taylor')->contains(['xxx', 'ylo']));\n        $this->assertTrue($this->stringable('taylor')->contains(collect(['xxx', 'ylo'])));\n        $this->assertTrue($this->stringable('taylor')->contains(['LOR'], true));\n        $this->assertFalse($this->stringable('taylor')->contains('xxx'));\n        $this->assertFalse($this->stringable('taylor')->contains(['xxx']));\n        $this->assertFalse($this->stringable('taylor')->contains(''));\n    }\n\n    public function testContainsAll()\n    {\n        $this->assertTrue($this->stringable('taylor otwell')->containsAll(['taylor', 'otwell']));\n        $this->assertTrue($this->stringable('taylor otwell')->containsAll(['TAYLOR', 'OTWELL'], true));\n        $this->assertTrue($this->stringable('taylor otwell')->containsAll(collect(['taylor', 'otwell'])));\n        $this->assertTrue($this->stringable('taylor otwell')->containsAll(['taylor']));\n        $this->assertFalse($this->stringable('taylor otwell')->containsAll(['taylor', 'xxx']));\n    }\n\n    public function testDoesntContain()\n    {\n        $this->assertTrue($this->stringable('taylor')->doesntContain('xxx'));\n        $this->assertTrue($this->stringable('taylor')->doesntContain(['xxx']));\n        $this->assertTrue($this->stringable('taylor')->doesntContain(['xxx', 'yyy']));\n        $this->assertTrue($this->stringable('taylor')->doesntContain(collect(['xxx', 'yyy'])));\n        $this->assertTrue($this->stringable('taylor')->doesntContain(''));\n        $this->assertFalse($this->stringable('taylor')->doesntContain('ylo'));\n        $this->assertFalse($this->stringable('taylor')->doesntContain('taylor'));\n        $this->assertFalse($this->stringable('taylor')->doesntContain(['xxx', 'ylo']));\n        $this->assertFalse($this->stringable('taylor')->doesntContain(['LOR'], true));\n    }\n\n    public function testParseCallback()\n    {\n        $this->assertEquals(['Class', 'method'], $this->stringable('Class@method')->parseCallback('foo'));\n        $this->assertEquals(['Class', 'foo'], $this->stringable('Class')->parseCallback('foo'));\n        $this->assertEquals(['Class', null], $this->stringable('Class')->parseCallback());\n    }\n\n    public function testSlug()\n    {\n        $this->assertSame('hello-world', (string) $this->stringable('hello world')->slug());\n        $this->assertSame('hello-world', (string) $this->stringable('hello-world')->slug());\n        $this->assertSame('hello-world', (string) $this->stringable('hello_world')->slug());\n        $this->assertSame('hello_world', (string) $this->stringable('hello_world')->slug('_'));\n        $this->assertSame('user-at-host', (string) $this->stringable('user@host')->slug());\n        $this->assertSame('سلام-دنیا', (string) $this->stringable('سلام دنیا')->slug('-', null));\n        $this->assertSame('sometext', (string) $this->stringable('some text')->slug(''));\n        $this->assertSame('', (string) $this->stringable('')->slug(''));\n        $this->assertSame('', (string) $this->stringable('')->slug());\n    }\n\n    public function testSquish()\n    {\n        $this->assertSame('words with spaces', (string) $this->stringable(' words  with   spaces ')->squish());\n        $this->assertSame('words with spaces', (string) $this->stringable(\"words\\t\\twith\\n\\nspaces\")->squish());\n        $this->assertSame('words with spaces', (string) $this->stringable('\n            words\n            with\n            spaces\n        ')->squish());\n        $this->assertSame('laravel php framework', (string) $this->stringable('   laravel   php   framework   ')->squish());\n        $this->assertSame('123', (string) $this->stringable('   123    ')->squish());\n        $this->assertSame('だ', (string) $this->stringable('だ')->squish());\n        $this->assertSame('ム', (string) $this->stringable('ム')->squish());\n        $this->assertSame('だ', (string) $this->stringable('   だ    ')->squish());\n        $this->assertSame('ム', (string) $this->stringable('   ム    ')->squish());\n        $this->assertSame('ム', (string) $this->stringable('﻿   ム ﻿﻿   ﻿')->squish());\n    }\n\n    public function testStart()\n    {\n        $this->assertSame('/test/string', (string) $this->stringable('test/string')->start('/'));\n        $this->assertSame('/test/string', (string) $this->stringable('/test/string')->start('/'));\n        $this->assertSame('/test/string', (string) $this->stringable('//test/string')->start('/'));\n    }\n\n    public function testFinish()\n    {\n        $this->assertSame('abbc', (string) $this->stringable('ab')->finish('bc'));\n        $this->assertSame('abbc', (string) $this->stringable('abbcbc')->finish('bc'));\n        $this->assertSame('abcbbc', (string) $this->stringable('abcbbcbc')->finish('bc'));\n    }\n\n    public function testIs()\n    {\n        $this->assertTrue($this->stringable('/')->is('/'));\n        $this->assertFalse($this->stringable('/')->is(' /'));\n        $this->assertFalse($this->stringable('/a')->is('/'));\n        $this->assertTrue($this->stringable('foo/bar/baz')->is('foo/*'));\n\n        $this->assertTrue($this->stringable('App\\Class@method')->is('*@*'));\n        $this->assertTrue($this->stringable('app\\Class@')->is('*@*'));\n        $this->assertTrue($this->stringable('@method')->is('*@*'));\n\n        // is case sensitive\n        $this->assertFalse($this->stringable('foo/bar/baz')->is('*BAZ*'));\n        $this->assertFalse($this->stringable('foo/bar/baz')->is('*FOO*'));\n        $this->assertFalse($this->stringable('a')->is('A'));\n\n        // is not case sensitive\n        $this->assertTrue($this->stringable('a')->is('A', true));\n        $this->assertTrue($this->stringable('foo/bar/baz')->is('*BAZ*', true));\n        $this->assertTrue($this->stringable('a/')->is(['A*', 'B*'], true));\n        $this->assertFalse($this->stringable('f/')->is(['A*', 'B*'], true));\n        $this->assertTrue($this->stringable('foo')->is('FOO', true));\n        $this->assertTrue($this->stringable('foo/bar/baz')->is('*FOO*', true));\n        $this->assertTrue($this->stringable('FOO/bar')->is('foo/*', true));\n\n        // Accepts array of patterns\n        $this->assertTrue($this->stringable('a/')->is(['a*', 'b*']));\n        $this->assertTrue($this->stringable('b/')->is(['a*', 'b*']));\n        $this->assertFalse($this->stringable('f/')->is(['a*', 'b*']));\n\n        // numeric values and patterns\n        $this->assertFalse($this->stringable(123)->is(['a*', 'b*']));\n        $this->assertTrue($this->stringable(11211)->is(['*2*', 'b*']));\n\n        $this->assertTrue($this->stringable('blah/baz/foo')->is('*/foo'));\n\n        $valueObject = new StringableObjectStub('foo/bar/baz');\n        $patternObject = new StringableObjectStub('foo/*');\n\n        $this->assertTrue($this->stringable($valueObject)->is('foo/bar/baz'));\n        $this->assertTrue($this->stringable($valueObject)->is($patternObject));\n\n        // empty patterns\n        $this->assertFalse($this->stringable('test')->is([]));\n    }\n\n    public function testIsWithMultilineStrings()\n    {\n        $this->assertFalse($this->stringable(\"/\\n\")->is('/'));\n        $this->assertTrue($this->stringable(\"/\\n\")->is('/*'));\n        $this->assertTrue($this->stringable(\"/\\n\")->is('*/*'));\n        $this->assertTrue($this->stringable(\"\\n/\\n\")->is('*/*'));\n\n        $this->assertTrue($this->stringable(\"\\n\")->is('*'));\n        $this->assertTrue($this->stringable(\"\\n\\n\")->is('*'));\n        $this->assertFalse($this->stringable(\"\\n\")->is(''));\n        $this->assertFalse($this->stringable(\"\\n\\n\")->is(''));\n\n        $multilineValue = <<<'VALUE'\n        <?php\n\n        namespace Illuminate\\Tests\\Support;\n\n        use Exception;\n        VALUE;\n\n        $this->assertTrue($this->stringable($multilineValue)->is($multilineValue));\n        $this->assertTrue($this->stringable($multilineValue)->is('*'));\n        $this->assertTrue($this->stringable($multilineValue)->is(\"*namespace Illuminate\\Tests\\*\"));\n        $this->assertFalse($this->stringable($multilineValue)->is(\"namespace Illuminate\\Tests\\*\"));\n        $this->assertFalse($this->stringable($multilineValue)->is(\"*namespace Illuminate\\Tests\"));\n        $this->assertTrue($this->stringable($multilineValue)->is('<?php*'));\n        $this->assertTrue($this->stringable($multilineValue)->is(\"<?php*namespace Illuminate\\Tests\\*\"));\n        $this->assertFalse($this->stringable($multilineValue)->is('use Exception;'));\n        $this->assertFalse($this->stringable($multilineValue)->is('use Exception;*'));\n        $this->assertTrue($this->stringable($multilineValue)->is('*use Exception;'));\n    }\n\n    public function testKebab()\n    {\n        $this->assertSame('laravel-php-framework', (string) $this->stringable('LaravelPhpFramework')->kebab());\n    }\n\n    public function testLower()\n    {\n        $this->assertSame('foo bar baz', (string) $this->stringable('FOO BAR BAZ')->lower());\n        $this->assertSame('foo bar baz', (string) $this->stringable('fOo Bar bAz')->lower());\n    }\n\n    public function testUpper()\n    {\n        $this->assertSame('FOO BAR BAZ', (string) $this->stringable('foo bar baz')->upper());\n        $this->assertSame('FOO BAR BAZ', (string) $this->stringable('foO bAr BaZ')->upper());\n    }\n\n    public function testLimit()\n    {\n        $this->assertSame('Laravel is...',\n            (string) $this->stringable('Laravel is a free, open source PHP web application framework.')->limit(10)\n        );\n        $this->assertSame('这是一...', (string) $this->stringable('这是一段中文')->limit(6));\n\n        $string = 'The PHP framework for web artisans.';\n        $this->assertSame('The PHP...', (string) $this->stringable($string)->limit(7));\n        $this->assertSame('The PHP', (string) $this->stringable($string)->limit(7, ''));\n        $this->assertSame('The PHP framework for web artisans.', (string) $this->stringable($string)->limit(100));\n\n        $nonAsciiString = '这是一段中文';\n        $this->assertSame('这是一...', (string) $this->stringable($nonAsciiString)->limit(6));\n        $this->assertSame('这是一', (string) $this->stringable($nonAsciiString)->limit(6, ''));\n    }\n\n    public function testLength()\n    {\n        $this->assertSame(11, $this->stringable('foo bar baz')->length());\n        $this->assertSame(11, $this->stringable('foo bar baz')->length('UTF-8'));\n    }\n\n    public function testReplace()\n    {\n        $this->assertSame('foo/foo/foo', (string) $this->stringable('?/?/?')->replace('?', 'foo'));\n        $this->assertSame('foo/foo/foo', (string) $this->stringable('x/x/x')->replace('X', 'foo', false));\n        $this->assertSame('bar/bar', (string) $this->stringable('?/?')->replace('?', 'bar'));\n        $this->assertSame('?/?/?', (string) $this->stringable('? ? ?')->replace(' ', '/'));\n        $this->assertSame('foo/bar/baz/bam', (string) $this->stringable('?1/?2/?3/?4')->replace(['?1', '?2', '?3', '?4'], ['foo', 'bar', 'baz', 'bam']));\n        $this->assertSame('?1/?2/?3/?4', (string) $this->stringable('foo/bar/baz/bam')->replace(['Foo', 'BaR', 'BAZ', 'bAm'], ['?1', '?2', '?3', '?4'], false));\n        $this->assertSame('foo/bar/baz/bam', (string) $this->stringable('?1/?2/?3/?4')->replace(collect(['?1', '?2', '?3', '?4']), collect(['foo', 'bar', 'baz', 'bam'])));\n    }\n\n    public function testReplaceArray()\n    {\n        $this->assertSame('foo/bar/baz', (string) $this->stringable('?/?/?')->replaceArray('?', ['foo', 'bar', 'baz']));\n        $this->assertSame('foo/bar/baz/?', (string) $this->stringable('?/?/?/?')->replaceArray('?', ['foo', 'bar', 'baz']));\n        $this->assertSame('foo/bar', (string) $this->stringable('?/?')->replaceArray('?', ['foo', 'bar', 'baz']));\n        $this->assertSame('?/?/?', (string) $this->stringable('?/?/?')->replaceArray('x', ['foo', 'bar', 'baz']));\n        $this->assertSame('foo?/bar/baz', (string) $this->stringable('?/?/?')->replaceArray('?', ['foo?', 'bar', 'baz']));\n        $this->assertSame('foo/bar', (string) $this->stringable('?/?')->replaceArray('?', [1 => 'foo', 2 => 'bar']));\n        $this->assertSame('foo/bar', (string) $this->stringable('?/?')->replaceArray('?', ['x' => 'foo', 'y' => 'bar']));\n        $this->assertSame('foo/bar', (string) $this->stringable('?/?')->replaceArray('?', collect(['x' => 'foo', 'y' => 'bar'])));\n    }\n\n    public function testReplaceFirst()\n    {\n        $this->assertSame('fooqux foobar', (string) $this->stringable('foobar foobar')->replaceFirst('bar', 'qux'));\n        $this->assertSame('foo/qux? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceFirst('bar?', 'qux?'));\n        $this->assertSame('foo foobar', (string) $this->stringable('foobar foobar')->replaceFirst('bar', ''));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceFirst('xxx', 'yyy'));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceFirst('', 'yyy'));\n        // Test for multibyte string support\n        $this->assertSame('Jxxxnköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceFirst('ö', 'xxx'));\n        $this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceFirst('', 'yyy'));\n    }\n\n    public function testReplaceStart()\n    {\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceStart('bar', 'qux'));\n        $this->assertSame('foo/bar? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('bar?', 'qux?'));\n        $this->assertSame('quxbar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', 'qux'));\n        $this->assertSame('qux? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('foo/bar?', 'qux?'));\n        $this->assertSame('bar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', ''));\n        $this->assertSame('1', (string) $this->stringable('0')->replaceStart(0, '1'));\n        // Test for multibyte string support\n        $this->assertSame('xxxnköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('Jö', 'xxx'));\n        $this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('', 'yyy'));\n    }\n\n    public function testReplaceLast()\n    {\n        $this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceLast('bar', 'qux'));\n        $this->assertSame('foo/bar? foo/qux?', (string) $this->stringable('foo/bar? foo/bar?')->replaceLast('bar?', 'qux?'));\n        $this->assertSame('foobar foo', (string) $this->stringable('foobar foobar')->replaceLast('bar', ''));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceLast('xxx', 'yyy'));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceLast('', 'yyy'));\n        // Test for multibyte string support\n        $this->assertSame('Malmö Jönkxxxping', (string) $this->stringable('Malmö Jönköping')->replaceLast('ö', 'xxx'));\n        $this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceLast('', 'yyy'));\n    }\n\n    public function testReplaceEnd()\n    {\n        $this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceEnd('bar', 'qux'));\n        $this->assertSame('foo/bar? foo/qux?', (string) $this->stringable('foo/bar? foo/bar?')->replaceEnd('bar?', 'qux?'));\n        $this->assertSame('foobar foo', (string) $this->stringable('foobar foobar')->replaceEnd('bar', ''));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceLast('xxx', 'yyy'));\n        $this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceEnd('', 'yyy'));\n        $this->assertSame('fooxxx foobar', (string) $this->stringable('fooxxx foobar')->replaceEnd('xxx', 'yyy'));\n\n        // // Test for multibyte string support\n        $this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceEnd('ö', 'xxx'));\n        $this->assertSame('Malmö Jönkyyy', (string) $this->stringable('Malmö Jönköping')->replaceEnd('öping', 'yyy'));\n    }\n\n    public function testRemove()\n    {\n        $this->assertSame('Fbar', (string) $this->stringable('Foobar')->remove('o'));\n        $this->assertSame('Foo', (string) $this->stringable('Foobar')->remove('bar'));\n        $this->assertSame('oobar', (string) $this->stringable('Foobar')->remove('F'));\n        $this->assertSame('Foobar', (string) $this->stringable('Foobar')->remove('f'));\n        $this->assertSame('oobar', (string) $this->stringable('Foobar')->remove('f', false));\n\n        $this->assertSame('Fbr', (string) $this->stringable('Foobar')->remove(['o', 'a']));\n        $this->assertSame('Fbr', (string) $this->stringable('Foobar')->remove(collect(['o', 'a'])));\n        $this->assertSame('Fooar', (string) $this->stringable('Foobar')->remove(['f', 'b']));\n        $this->assertSame('ooar', (string) $this->stringable('Foobar')->remove(['f', 'b'], false));\n        $this->assertSame('Foobar', (string) $this->stringable('Foo|bar')->remove(['f', '|']));\n    }\n\n    public function testReverse()\n    {\n        $this->assertSame('FooBar', (string) $this->stringable('raBooF')->reverse());\n        $this->assertSame('Teniszütő', (string) $this->stringable('őtüzsineT')->reverse());\n        $this->assertSame('❤MultiByte☆', (string) $this->stringable('☆etyBitluM❤')->reverse());\n    }\n\n    public function testSnake()\n    {\n        $this->assertSame('laravel_p_h_p_framework', (string) $this->stringable('LaravelPHPFramework')->snake());\n        $this->assertSame('laravel_php_framework', (string) $this->stringable('LaravelPhpFramework')->snake());\n        $this->assertSame('laravel php framework', (string) $this->stringable('LaravelPhpFramework')->snake(' '));\n        $this->assertSame('laravel_php_framework', (string) $this->stringable('Laravel Php Framework')->snake());\n        $this->assertSame('laravel_php_framework', (string) $this->stringable('Laravel    Php      Framework   ')->snake());\n        // ensure cache keys don't overlap\n        $this->assertSame('laravel__php__framework', (string) $this->stringable('LaravelPhpFramework')->snake('__'));\n        $this->assertSame('laravel_php_framework_', (string) $this->stringable('LaravelPhpFramework_')->snake('_'));\n        $this->assertSame('laravel_php_framework', (string) $this->stringable('laravel php Framework')->snake());\n        $this->assertSame('laravel_php_frame_work', (string) $this->stringable('laravel php FrameWork')->snake());\n        // prevent breaking changes\n        $this->assertSame('foo-bar', (string) $this->stringable('foo-bar')->snake());\n        $this->assertSame('foo-_bar', (string) $this->stringable('Foo-Bar')->snake());\n        $this->assertSame('foo__bar', (string) $this->stringable('Foo_Bar')->snake());\n        $this->assertSame('żółtałódka', (string) $this->stringable('ŻółtaŁódka')->snake());\n    }\n\n    public function testStudly()\n    {\n        $this->assertSame('LaravelPHPFramework', (string) $this->stringable('laravel_p_h_p_framework')->studly());\n        $this->assertSame('LaravelPhpFramework', (string) $this->stringable('laravel_php_framework')->studly());\n        $this->assertSame('LaravelPhPFramework', (string) $this->stringable('laravel-phP-framework')->studly());\n        $this->assertSame('LaravelPhpFramework', (string) $this->stringable('laravel  -_-  php   -_-   framework   ')->studly());\n\n        $this->assertSame('FooBar', (string) $this->stringable('fooBar')->studly());\n        $this->assertSame('FooBar', (string) $this->stringable('foo_bar')->studly());\n        $this->assertSame('FooBar', (string) $this->stringable('foo_bar')->studly()); // test cache\n        $this->assertSame('FooBarBaz', (string) $this->stringable('foo-barBaz')->studly());\n        $this->assertSame('FooBarBaz', (string) $this->stringable('foo-bar_baz')->studly());\n    }\n\n    public function testPascal()\n    {\n        $this->assertSame('LaravelPHPFramework', (string) $this->stringable('laravel_p_h_p_framework')->pascal());\n        $this->assertSame('LaravelPhpFramework', (string) $this->stringable('laravel_php_framework')->pascal());\n        $this->assertSame('LaravelPhPFramework', (string) $this->stringable('laravel-phP-framework')->pascal());\n        $this->assertSame('LaravelPhpFramework', (string) $this->stringable('laravel  -_-  php   -_-   framework   ')->pascal());\n\n        $this->assertSame('FooBar', (string) $this->stringable('fooBar')->pascal());\n        $this->assertSame('FooBar', (string) $this->stringable('foo_bar')->pascal());\n        $this->assertSame('FooBar', (string) $this->stringable('foo_bar')->pascal()); // test cache\n        $this->assertSame('FooBarBaz', (string) $this->stringable('foo-barBaz')->pascal());\n        $this->assertSame('FooBarBaz', (string) $this->stringable('foo-bar_baz')->pascal());\n    }\n\n    public function testCamel()\n    {\n        $this->assertSame('laravelPHPFramework', (string) $this->stringable('Laravel_p_h_p_framework')->camel());\n        $this->assertSame('laravelPhpFramework', (string) $this->stringable('Laravel_php_framework')->camel());\n        $this->assertSame('laravelPhPFramework', (string) $this->stringable('Laravel-phP-framework')->camel());\n        $this->assertSame('laravelPhpFramework', (string) $this->stringable('Laravel  -_-  php   -_-   framework   ')->camel());\n\n        $this->assertSame('fooBar', (string) $this->stringable('FooBar')->camel());\n        $this->assertSame('fooBar', (string) $this->stringable('foo_bar')->camel());\n        $this->assertSame('fooBar', (string) $this->stringable('foo_bar')->camel()); // test cache\n        $this->assertSame('fooBarBaz', (string) $this->stringable('Foo-barBaz')->camel());\n        $this->assertSame('fooBarBaz', (string) $this->stringable('foo-bar_baz')->camel());\n    }\n\n    public function testCharAt()\n    {\n        $this->assertEquals('р', $this->stringable('Привет, мир!')->charAt(1));\n        $this->assertEquals('ち', $this->stringable('「こんにちは世界」')->charAt(4));\n        $this->assertEquals('w', $this->stringable('Привет, world!')->charAt(8));\n        $this->assertEquals('界', $this->stringable('「こんにちは世界」')->charAt(-2));\n        $this->assertEquals(null, $this->stringable('「こんにちは世界」')->charAt(-200));\n        $this->assertEquals(null, $this->stringable('Привет, мир!')->charAt('Привет, мир!', 100));\n    }\n\n    public function testSubstr()\n    {\n        $this->assertSame('Ё', (string) $this->stringable('БГДЖИЛЁ')->substr(-1));\n        $this->assertSame('ЛЁ', (string) $this->stringable('БГДЖИЛЁ')->substr(-2));\n        $this->assertSame('И', (string) $this->stringable('БГДЖИЛЁ')->substr(-3, 1));\n        $this->assertSame('ДЖИЛ', (string) $this->stringable('БГДЖИЛЁ')->substr(2, -1));\n        $this->assertSame('', (string) $this->stringable('БГДЖИЛЁ')->substr(4, -4));\n        $this->assertSame('ИЛ', (string) $this->stringable('БГДЖИЛЁ')->substr(-3, -1));\n        $this->assertSame('ГДЖИЛЁ', (string) $this->stringable('БГДЖИЛЁ')->substr(1));\n        $this->assertSame('ГДЖ', (string) $this->stringable('БГДЖИЛЁ')->substr(1, 3));\n        $this->assertSame('БГДЖ', (string) $this->stringable('БГДЖИЛЁ')->substr(0, 4));\n        $this->assertSame('Ё', (string) $this->stringable('БГДЖИЛЁ')->substr(-1, 1));\n        $this->assertSame('', (string) $this->stringable('Б')->substr(2));\n    }\n\n    public function testSwap()\n    {\n        $this->assertSame('PHP 8 is fantastic', (string) $this->stringable('PHP is awesome')->swap([\n            'PHP' => 'PHP 8',\n            'awesome' => 'fantastic',\n        ]));\n    }\n\n    public function testSubstrCount()\n    {\n        $this->assertSame(3, $this->stringable('laravelPHPFramework')->substrCount('a'));\n        $this->assertSame(0, $this->stringable('laravelPHPFramework')->substrCount('z'));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('l', 2));\n        $this->assertSame(0, $this->stringable('laravelPHPFramework')->substrCount('z', 2));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('k', -1));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('k', -1));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('a', 1, 2));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('a', 1, 2));\n        $this->assertSame(3, $this->stringable('laravelPHPFramework')->substrCount('a', 1, -2));\n        $this->assertSame(1, $this->stringable('laravelPHPFramework')->substrCount('a', -10, -3));\n    }\n\n    public function testPosition()\n    {\n        $this->assertSame(7, $this->stringable('Hello, World!')->position('W'));\n        $this->assertSame(10, $this->stringable('This is a test string.')->position('test'));\n        $this->assertSame(23, $this->stringable('This is a test string, test again.')->position('test', 15));\n        $this->assertSame(0, $this->stringable('Hello, World!')->position('Hello'));\n        $this->assertSame(7, $this->stringable('Hello, World!')->position('World!'));\n        $this->assertSame(10, $this->stringable('This is a tEsT string.')->position('tEsT', 0, 'UTF-8'));\n        $this->assertSame(7, $this->stringable('Hello, World!')->position('W', -6));\n        $this->assertSame(18, $this->stringable('Äpfel, Birnen und Kirschen')->position('Kirschen', -10, 'UTF-8'));\n        $this->assertSame(9, $this->stringable('@%€/=!\"][$')->position('$', 0, 'UTF-8'));\n        $this->assertFalse($this->stringable('Hello, World!')->position('w', 0, 'UTF-8'));\n        $this->assertFalse($this->stringable('Hello, World!')->position('X', 0, 'UTF-8'));\n        $this->assertFalse($this->stringable('')->position('test'));\n        $this->assertFalse($this->stringable('Hello, World!')->position('X'));\n    }\n\n    public function testSubstrReplace()\n    {\n        $this->assertSame('12:00', (string) $this->stringable('1200')->substrReplace(':', 2, 0));\n        $this->assertSame('The Laravel Framework', (string) $this->stringable('The Framework')->substrReplace('Laravel ', 4, 0));\n        $this->assertSame('Laravel – The PHP Framework for Web Artisans', (string) $this->stringable('Laravel Framework')->substrReplace('– The PHP Framework for Web Artisans', 8));\n    }\n\n    public function testPadBoth()\n    {\n        $this->assertSame('__Alien___', (string) $this->stringable('Alien')->padBoth(10, '_'));\n        $this->assertSame('  Alien   ', (string) $this->stringable('Alien')->padBoth(10));\n        $this->assertSame('  ❤MultiByte☆   ', (string) $this->stringable('❤MultiByte☆')->padBoth(16));\n    }\n\n    public function testPadLeft()\n    {\n        $this->assertSame('-=-=-Alien', (string) $this->stringable('Alien')->padLeft(10, '-='));\n        $this->assertSame('     Alien', (string) $this->stringable('Alien')->padLeft(10));\n        $this->assertSame('     ❤MultiByte☆', (string) $this->stringable('❤MultiByte☆')->padLeft(16));\n    }\n\n    public function testPadRight()\n    {\n        $this->assertSame('Alien-----', (string) $this->stringable('Alien')->padRight(10, '-'));\n        $this->assertSame('Alien     ', (string) $this->stringable('Alien')->padRight(10));\n        $this->assertSame('❤MultiByte☆     ', (string) $this->stringable('❤MultiByte☆')->padRight(16));\n    }\n\n    public function testExplode()\n    {\n        $this->assertInstanceOf(Collection::class, $this->stringable('Foo Bar Baz')->explode(' '));\n\n        $this->assertSame('[\"Foo\",\"Bar\",\"Baz\"]', (string) $this->stringable('Foo Bar Baz')->explode(' '));\n\n        //  with limit\n        $this->assertSame('[\"Foo\",\"Bar Baz\"]', (string) $this->stringable('Foo Bar Baz')->explode(' ', 2));\n        $this->assertSame('[\"Foo\",\"Bar\"]', (string) $this->stringable('Foo Bar Baz')->explode(' ', -1));\n    }\n\n    public function testChunk()\n    {\n        $chunks = $this->stringable('foobarbaz')->split(3);\n\n        $this->assertInstanceOf(Collection::class, $chunks);\n        $this->assertSame(['foo', 'bar', 'baz'], $chunks->all());\n    }\n\n    public function testJsonSerialize()\n    {\n        $this->assertSame('\"foo\"', json_encode($this->stringable('foo')));\n        $this->assertSame('\"laravel-php-framework\"', json_encode($this->stringable('LaravelPhpFramework')->kebab()));\n        $this->assertSame('[\"laravel-php-framework\"]', json_encode([$this->stringable('LaravelPhpFramework')->kebab()]));\n        $this->assertSame('{\"title\":\"laravel-php-framework\"}', json_encode(['title' => $this->stringable('LaravelPhpFramework')->kebab()]));\n    }\n\n    public function testTap()\n    {\n        $stringable = $this->stringable('foobarbaz');\n\n        $fromTheTap = '';\n\n        $stringable = $stringable->tap(function (Stringable $string) use (&$fromTheTap) {\n            $fromTheTap = $string->substr(0, 3);\n        });\n\n        $this->assertSame('foo', (string) $fromTheTap);\n        $this->assertSame('foobarbaz', (string) $stringable);\n    }\n\n    public function testPipe()\n    {\n        $callback = function ($stringable) {\n            return 'bar';\n        };\n\n        $this->assertInstanceOf(Stringable::class, $this->stringable('foo')->pipe($callback));\n        $this->assertSame('bar', (string) $this->stringable('foo')->pipe($callback));\n    }\n\n    public function testMarkdown()\n    {\n        $this->assertEquals(\"<p><em>hello world</em></p>\\n\", $this->stringable('*hello world*')->markdown());\n        $this->assertEquals(\"<h1>hello world</h1>\\n\", $this->stringable('# hello world')->markdown());\n\n        $extension = new class implements ExtensionInterface\n        {\n            public bool $configured = false;\n\n            public function register(EnvironmentBuilderInterface $environment): void\n            {\n                $this->configured = true;\n            }\n        };\n        $this->stringable('# hello world')->markdown([], [$extension]);\n        $this->assertTrue($extension->configured);\n    }\n\n    public function testInlineMarkdown()\n    {\n        $this->assertEquals(\"<em>hello world</em>\\n\", $this->stringable('*hello world*')->inlineMarkdown());\n        $this->assertEquals(\"<a href=\\\"https://laravel.com\\\"><strong>Laravel</strong></a>\\n\", $this->stringable('[**Laravel**](https://laravel.com)')->inlineMarkdown());\n\n        $extension = new class implements ExtensionInterface\n        {\n            public bool $configured = false;\n\n            public function register(EnvironmentBuilderInterface $environment): void\n            {\n                $this->configured = true;\n            }\n        };\n\n        $this->stringable('# hello world')->inlineMarkdown([], [$extension]);\n        $this->assertTrue($extension->configured);\n    }\n\n    public function testMask()\n    {\n        $this->assertSame('tay*************', (string) $this->stringable('taylor@email.com')->mask('*', 3));\n        $this->assertSame('******@email.com', (string) $this->stringable('taylor@email.com')->mask('*', 0, 6));\n        $this->assertSame('tay*************', (string) $this->stringable('taylor@email.com')->mask('*', -13));\n        $this->assertSame('tay***@email.com', (string) $this->stringable('taylor@email.com')->mask('*', -13, 3));\n\n        $this->assertSame('****************', (string) $this->stringable('taylor@email.com')->mask('*', -17));\n        $this->assertSame('*****r@email.com', (string) $this->stringable('taylor@email.com')->mask('*', -99, 5));\n\n        $this->assertSame('taylor@email.com', (string) $this->stringable('taylor@email.com')->mask('*', 16));\n        $this->assertSame('taylor@email.com', (string) $this->stringable('taylor@email.com')->mask('*', 16, 99));\n\n        $this->assertSame('taylor@email.com', (string) $this->stringable('taylor@email.com')->mask('', 3));\n\n        $this->assertSame('taysssssssssssss', (string) $this->stringable('taylor@email.com')->mask('something', 3));\n\n        $this->assertSame('这是一***', (string) $this->stringable('这是一段中文')->mask('*', 3));\n        $this->assertSame('**一段中文', (string) $this->stringable('这是一段中文')->mask('*', 0, 2));\n    }\n\n    public function testRepeat()\n    {\n        $this->assertSame('aaaaa', (string) $this->stringable('a')->repeat(5));\n        $this->assertSame('', (string) $this->stringable('')->repeat(5));\n    }\n\n    public function testWordCount()\n    {\n        $this->assertEquals(2, $this->stringable('Hello, world!')->wordCount());\n        $this->assertEquals(10, $this->stringable('Hi, this is my first contribution to the Laravel framework.')->wordCount());\n    }\n\n    public function testWrap()\n    {\n        $this->assertEquals('This is me!', $this->stringable('is')->wrap('This ', ' me!'));\n        $this->assertEquals('\"value\"', $this->stringable('value')->wrap('\"'));\n    }\n\n    public function testUnwrap()\n    {\n        $this->assertEquals('value', $this->stringable('\"value\"')->unwrap('\"'));\n        $this->assertEquals('bar', $this->stringable('foo-bar-baz')->unwrap('foo-', '-baz'));\n        $this->assertEquals('some: \"json\"', $this->stringable('{some: \"json\"}')->unwrap('{', '}'));\n    }\n\n    public function testToHtmlString()\n    {\n        $this->assertEquals(\n            new HtmlString('<h1>Test String</h1>'),\n            $this->stringable('<h1>Test String</h1>')->toHtmlString()\n        );\n    }\n\n    public function testStripTags()\n    {\n        $this->assertSame('beforeafter', (string) $this->stringable('before<br>after')->stripTags());\n        $this->assertSame('before<br>after', (string) $this->stringable('before<br>after')->stripTags('<br>'));\n        $this->assertSame('before<br>after', (string) $this->stringable('<strong>before</strong><br>after')->stripTags('<br>'));\n        $this->assertSame('<strong>before</strong><br>after', (string) $this->stringable('<strong>before</strong><br>after')->stripTags('<br><strong>'));\n    }\n\n    public function testReplaceMatches()\n    {\n        $stringable = $this->stringable('Hello world!');\n        $result = $stringable->replaceMatches('/world/', function ($match) {\n            return strtoupper($match[0]);\n        });\n\n        $this->assertSame('Hello WORLD!', $result->value);\n\n        $stringable = $this->stringable('apple orange apple');\n        $result = $stringable->replaceMatches('/apple/', 'fruit', 1);\n\n        $this->assertSame('fruit orange apple', $result->value);\n    }\n\n    public function testScan()\n    {\n        $this->assertSame([123456], $this->stringable('SN/123456')->scan('SN/%d')->toArray());\n        $this->assertSame(['Otwell', 'Taylor'], $this->stringable('Otwell, Taylor')->scan('%[^,],%s')->toArray());\n        $this->assertSame(['filename', 'jpg'], $this->stringable('filename.jpg')->scan('%[^.].%s')->toArray());\n    }\n\n    public function testGet()\n    {\n        $this->assertSame('foo', $this->stringable('foo')->value());\n        $this->assertSame('foo', $this->stringable('foo')->toString());\n    }\n\n    public function testExactly()\n    {\n        $this->assertTrue($this->stringable('foo')->exactly($this->stringable('foo')));\n        $this->assertTrue($this->stringable('foo')->exactly('foo'));\n\n        $this->assertFalse($this->stringable('Foo')->exactly($this->stringable('foo')));\n        $this->assertFalse($this->stringable('Foo')->exactly('foo'));\n        $this->assertFalse($this->stringable('[]')->exactly([]));\n        $this->assertFalse($this->stringable('0')->exactly(0));\n    }\n\n    public function testInitials()\n    {\n        $this->assertSame('TO', $this->stringable('Taylor Otwell')->initials()->value());\n    }\n\n    public function testToInteger()\n    {\n        $this->assertSame(123, $this->stringable('123')->toInteger());\n        $this->assertSame(456, $this->stringable(456)->toInteger());\n        $this->assertSame(78, $this->stringable('078')->toInteger());\n        $this->assertSame(901, $this->stringable(' 901')->toInteger());\n        $this->assertSame(0, $this->stringable('nan')->toInteger());\n        $this->assertSame(1, $this->stringable('1ab')->toInteger());\n        $this->assertSame(2, $this->stringable('2_000')->toInteger());\n    }\n\n    public function testToFloat()\n    {\n        $this->assertSame(1.23, $this->stringable('1.23')->toFloat());\n        $this->assertSame(45.6, $this->stringable(45.6)->toFloat());\n        $this->assertSame(.6, $this->stringable('.6')->toFloat());\n        $this->assertSame(0.78, $this->stringable('0.78')->toFloat());\n        $this->assertSame(90.1, $this->stringable(' 90.1')->toFloat());\n        $this->assertSame(0.0, $this->stringable('nan')->toFloat());\n        $this->assertSame(1.0, $this->stringable('1.ab')->toFloat());\n        $this->assertSame(1e3, $this->stringable('1e3')->toFloat());\n    }\n\n    public function testBooleanMethod()\n    {\n        $this->assertTrue($this->stringable(true)->toBoolean());\n        $this->assertTrue($this->stringable('true')->toBoolean());\n        $this->assertFalse($this->stringable('false')->toBoolean());\n        $this->assertTrue($this->stringable('1')->toBoolean());\n        $this->assertFalse($this->stringable('0')->toBoolean());\n        $this->assertTrue($this->stringable('on')->toBoolean());\n        $this->assertFalse($this->stringable('off')->toBoolean());\n        $this->assertTrue($this->stringable('yes')->toBoolean());\n        $this->assertFalse($this->stringable('no')->toBoolean());\n    }\n\n    public function testNumbers()\n    {\n        $this->assertSame('5551234567', (string) $this->stringable('(555) 123-4567')->numbers());\n    }\n\n    public function testToDate()\n    {\n        $current = Carbon::create(2020, 1, 1, 16, 30, 25);\n\n        $this->assertEquals($current, $this->stringable('20-01-01 16:30:25')->toDate());\n        $this->assertEquals($current, $this->stringable('1577896225')->toDate('U'));\n        $this->assertEquals($current, $this->stringable('20-01-01 13:30:25')->toDate(null, 'America/Santiago'));\n\n        $this->assertTrue($this->stringable('2020-01-01')->toDate()->isSameDay($current));\n        $this->assertTrue($this->stringable('16:30:25')->toDate()->isSameSecond('16:30:25'));\n    }\n\n    public function testToDateThrowsException()\n    {\n        $this->expectException(\\Carbon\\Exceptions\\InvalidFormatException::class);\n\n        $this->stringable('not a date')->toDate();\n    }\n\n    public function testToUri()\n    {\n        $sentence = 'Laravel is a PHP framework. You can access the docs in: {https://laravel.com/docs}';\n\n        $uri = $this->stringable($sentence)->between('{', '}')->toUri();\n\n        $this->assertInstanceOf(Uri::class, $uri);\n        $this->assertSame('https://laravel.com/docs', (string) $uri);\n        $this->assertSame('https://laravel.com/docs', $uri->toHtml());\n    }\n\n    public function testArrayAccess()\n    {\n        $str = $this->stringable('my string');\n        $this->assertSame('m', $str[0]);\n        $this->assertSame('t', $str[4]);\n        $this->assertTrue(isset($str[2]));\n        $this->assertFalse(isset($str[10]));\n    }\n\n    public function testToBase64()\n    {\n        $this->assertSame(base64_encode('foo'), (string) $this->stringable('foo')->toBase64());\n        $this->assertSame(base64_encode('foobar'), (string) $this->stringable('foobar')->toBase64());\n        $this->assertSame(base64_encode('foobarbaz'), (string) $this->stringable('foobarbaz')->toBase64());\n    }\n\n    public function testFromBase64()\n    {\n        $this->assertSame('foo', (string) $this->stringable(base64_encode('foo'))->fromBase64());\n        $this->assertSame('foobar', (string) $this->stringable(base64_encode('foobar'))->fromBase64(true));\n        $this->assertSame('foobarbaz', (string) $this->stringable(base64_encode('foobarbaz'))->fromBase64());\n    }\n\n    public function testHash()\n    {\n        $this->assertSame(hash('xxh3', 'foo'), (string) $this->stringable('foo')->hash('xxh3'));\n        $this->assertSame(hash('xxh3', 'foobar'), (string) $this->stringable('foobar')->hash('xxh3'));\n        $this->assertSame(hash('sha256', 'foobarbaz'), (string) $this->stringable('foobarbaz')->hash('sha256'));\n    }\n\n    public function testEncryptAndDecrypt()\n    {\n        Container::setInstance($this->container = new Container);\n\n        $this->container->bind('encrypter', fn () => new Encrypter(str_repeat('b', 16)));\n\n        $encrypted = $this->stringable('foo')->encrypt();\n\n        $this->assertNotSame('foo', $encrypted->value());\n        $this->assertSame('foo', $encrypted->decrypt()->value());\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportTappableTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\Traits\\Tappable;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportTappableTest extends TestCase\n{\n    public function testTappableClassWithCallback()\n    {\n        $name = TappableClass::make()->tap(function ($tappable) {\n            $tappable->setName('MyName');\n        })->getName();\n\n        $this->assertSame('MyName', $name);\n    }\n\n    public function testTappableClassWithInvokableClass()\n    {\n        $name = TappableClass::make()->tap(new class\n        {\n            public function __invoke($tappable)\n            {\n                $tappable->setName('MyName');\n            }\n        })->getName();\n\n        $this->assertSame('MyName', $name);\n    }\n\n    public function testTappableClassWithNoneInvokableClass()\n    {\n        $this->expectException('Error');\n\n        $name = TappableClass::make()->tap(new class\n        {\n            public function setName($tappable)\n            {\n                $tappable->setName('MyName');\n            }\n        })->getName();\n\n        $this->assertSame('MyName', $name);\n    }\n\n    public function testTappableClassWithoutCallback()\n    {\n        $name = TappableClass::make()->tap()->setName('MyName')->getName();\n\n        $this->assertSame('MyName', $name);\n    }\n}\n\nclass TappableClass\n{\n    use Tappable;\n\n    private $name;\n\n    public static function make()\n    {\n        return new static;\n    }\n\n    public function setName($name)\n    {\n        $this->name = $name;\n    }\n\n    public function getName()\n    {\n        return $this->name;\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportTestingBusFakeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\Queueable;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\Bus\\Dispatcher;\nuse Illuminate\\Contracts\\Bus\\QueueingDispatcher;\nuse Illuminate\\Support\\Testing\\Fakes\\BatchRepositoryFake;\nuse Illuminate\\Support\\Testing\\Fakes\\BusFake;\nuse Illuminate\\Support\\Testing\\Fakes\\PendingBatchFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportTestingBusFakeTest extends TestCase\n{\n    /** @var \\Illuminate\\Support\\Testing\\Fakes\\BusFake */\n    protected $fake;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->fake = new BusFake(m::mock(QueueingDispatcher::class));\n    }\n\n    public function testItUsesCustomBusRepository()\n    {\n        $busRepository = new BatchRepositoryFake;\n\n        $fake = new BusFake(m::mock(QueueingDispatcher::class), [], $busRepository);\n\n        $this->assertNull($fake->findBatch('non-existent-batch'));\n\n        $batch = $fake->batch([])->dispatch();\n\n        $this->assertSame($batch, $fake->findBatch($batch->id));\n        $this->assertSame($batch, $busRepository->find($batch->id));\n    }\n\n    public function testAssertDispatched()\n    {\n        try {\n            $this->fake->assertDispatched(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched.', $e->getMessage());\n        }\n\n        $this->fake->dispatch(new BusJobStub);\n\n        $this->fake->assertDispatched(BusJobStub::class);\n    }\n\n    public function testAssertDispatchedWithClosure()\n    {\n        $this->fake->dispatch(new BusJobStub);\n\n        $this->fake->assertDispatched(function (BusJobStub $job) {\n            return true;\n        });\n    }\n\n    public function testAssertDispatchedAfterResponse()\n    {\n        try {\n            $this->fake->assertDispatchedAfterResponse(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched after sending the response.', $e->getMessage());\n        }\n\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        $this->fake->assertDispatchedAfterResponse(BusJobStub::class);\n    }\n\n    public function testAssertDispatchedAfterResponseClosure()\n    {\n        try {\n            $this->fake->assertDispatchedAfterResponse(function (BusJobStub $job) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched after sending the response.', $e->getMessage());\n        }\n    }\n\n    public function testAssertDispatchedSync()\n    {\n        try {\n            $this->fake->assertDispatchedSync(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched synchronously.', $e->getMessage());\n        }\n\n        $this->fake->dispatch(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedSync(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched synchronously.', $e->getMessage());\n        }\n\n        $this->fake->dispatchSync(new BusJobStub);\n\n        $this->fake->assertDispatchedSync(BusJobStub::class);\n    }\n\n    public function testAssertDispatchedSyncClosure()\n    {\n        try {\n            $this->fake->assertDispatchedSync(function (BusJobStub $job) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was not dispatched synchronously.', $e->getMessage());\n        }\n    }\n\n    public function testAssertDispatchedNow()\n    {\n        $this->fake->dispatchNow(new BusJobStub);\n\n        $this->fake->assertDispatched(BusJobStub::class);\n    }\n\n    public function testAssertDispatchedWithCallbackInt()\n    {\n        $this->fake->dispatch(new BusJobStub);\n        $this->fake->dispatchNow(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatched(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatched(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedAfterResponseWithCallbackInt()\n    {\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedAfterResponse(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedAfterResponse(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedSyncWithCallbackInt()\n    {\n        $this->fake->dispatchSync(new BusJobStub);\n        $this->fake->dispatchSync(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedSync(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was synchronously pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedSync(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedWithCallbackFunction()\n    {\n        $this->fake->dispatch(new OtherBusJobStub);\n        $this->fake->dispatchNow(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatched(OtherBusJobStub::class, function ($job) {\n                return $job->id === 0;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was not dispatched.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatched(OtherBusJobStub::class, function ($job) {\n            return $job->id === null;\n        });\n\n        $this->fake->assertDispatched(OtherBusJobStub::class, function ($job) {\n            return $job->id === 1;\n        });\n    }\n\n    public function testAssertDispatchedAfterResponseWithCallbackFunction()\n    {\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub);\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatchedAfterResponse(OtherBusJobStub::class, function ($job) {\n                return $job->id === 0;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was not dispatched after sending the response.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedAfterResponse(OtherBusJobStub::class, function ($job) {\n            return $job->id === null;\n        });\n\n        $this->fake->assertDispatchedAfterResponse(OtherBusJobStub::class, function ($job) {\n            return $job->id === 1;\n        });\n    }\n\n    public function testAssertDispatchedAfterResponseTimesWithCallbackFunction()\n    {\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub(0));\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub(1));\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatchedAfterResponseTimes(function (OtherBusJobStub $job) {\n                return $job->id === 0;\n            }, 2);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was pushed 1 time instead of 2 times.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedAfterResponseTimes(function (OtherBusJobStub $job) {\n            return $job->id === 0;\n        });\n\n        $this->fake->assertDispatchedAfterResponseTimes(function (OtherBusJobStub $job) {\n            return $job->id === 1;\n        }, 2);\n    }\n\n    public function testAssertDispatchedSyncWithCallbackFunction()\n    {\n        $this->fake->dispatchSync(new OtherBusJobStub);\n        $this->fake->dispatchSync(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatchedSync(OtherBusJobStub::class, function ($job) {\n                return $job->id === 0;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was not dispatched synchronously.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedSync(OtherBusJobStub::class, function ($job) {\n            return $job->id === null;\n        });\n\n        $this->fake->assertDispatchedSync(OtherBusJobStub::class, function ($job) {\n            return $job->id === 1;\n        });\n    }\n\n    public function testAssertDispatchedOnce()\n    {\n        $this->fake->dispatch(new BusJobStub);\n        $this->fake->dispatchNow(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedOnce(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedTimes(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedTimes()\n    {\n        $this->fake->dispatch(new BusJobStub);\n        $this->fake->dispatchNow(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedTimes(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedTimes(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedTimesWithCallbackFunction()\n    {\n        $this->fake->dispatch(new OtherBusJobStub(0));\n        $this->fake->dispatchNow(new OtherBusJobStub(1));\n        $this->fake->dispatchAfterResponse(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatchedTimes(function (OtherBusJobStub $job) {\n                return $job->id === 0;\n            }, 2);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was pushed 1 time instead of 2 times.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedTimes(function (OtherBusJobStub $job) {\n            return $job->id === 0;\n        });\n\n        $this->fake->assertDispatchedTimes(function (OtherBusJobStub $job) {\n            return $job->id === 1;\n        }, 2);\n    }\n\n    public function testAssertDispatchedAfterResponseTimes()\n    {\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedAfterResponseTimes(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedAfterResponseTimes(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedSyncTimes()\n    {\n        $this->fake->dispatchSync(new BusJobStub);\n        $this->fake->dispatchSync(new BusJobStub);\n\n        try {\n            $this->fake->assertDispatchedSyncTimes(BusJobStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\BusJobStub] job was synchronously pushed 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedSyncTimes(BusJobStub::class, 2);\n    }\n\n    public function testAssertDispatchedSyncTimesWithCallbackFunction()\n    {\n        $this->fake->dispatchSync(new OtherBusJobStub(0));\n        $this->fake->dispatchSync(new OtherBusJobStub(1));\n        $this->fake->dispatchSync(new OtherBusJobStub(1));\n\n        try {\n            $this->fake->assertDispatchedSyncTimes(function (OtherBusJobStub $job) {\n                return $job->id === 0;\n            }, 2);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\OtherBusJobStub] job was synchronously pushed 1 time instead of 2 times.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedSyncTimes(function (OtherBusJobStub $job) {\n            return $job->id === 0;\n        });\n\n        $this->fake->assertDispatchedSyncTimes(function (OtherBusJobStub $job) {\n            return $job->id === 1;\n        }, 2);\n    }\n\n    public function testAssertNotDispatched()\n    {\n        $this->fake->assertNotDispatched(BusJobStub::class);\n\n        $this->fake->dispatch(new BusJobStub);\n        $this->fake->dispatchNow(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatched(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedWithClosure()\n    {\n        $this->fake->dispatch(new BusJobStub);\n        $this->fake->dispatchNow(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatched(function (BusJobStub $job) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedAfterResponse()\n    {\n        $this->fake->assertNotDispatchedAfterResponse(BusJobStub::class);\n\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatchedAfterResponse(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched after sending the response.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedAfterResponseClosure()\n    {\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatchedAfterResponse(function (BusJobStub $job) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched after sending the response.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedSync()\n    {\n        $this->fake->assertNotDispatchedSync(BusJobStub::class);\n\n        $this->fake->dispatchSync(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatchedSync(BusJobStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched synchronously.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedSyncClosure()\n    {\n        $this->fake->dispatchSync(new BusJobStub);\n\n        try {\n            $this->fake->assertNotDispatchedSync(function (BusJobStub $job) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\BusJobStub] job was dispatched synchronously.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingDispatched()\n    {\n        $this->fake->assertNothingDispatched();\n\n        $this->fake->dispatch(new BusJobStub);\n\n        try {\n            $this->fake->assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The following jobs were dispatched unexpectedly:', $e->getMessage());\n            $this->assertStringContainsString(BusJobStub::class, $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingDispatchedWithSyncDispatch()\n    {\n        $this->fake->assertNothingDispatched();\n\n        $this->fake->dispatchSync(new BusJobStub);\n\n        try {\n            $this->fake->assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The following jobs were dispatched unexpectedly:', $e->getMessage());\n            $this->assertStringContainsString(BusJobStub::class, $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingDispatchedWithAfterResponseDispatch()\n    {\n        $this->fake->assertNothingDispatched();\n\n        $this->fake->dispatchAfterResponse(new BusJobStub);\n\n        try {\n            $this->fake->assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The following jobs were dispatched unexpectedly:', $e->getMessage());\n            $this->assertStringContainsString(BusJobStub::class, $e->getMessage());\n        }\n    }\n\n    public function testAssertChained()\n    {\n        Container::setInstance($container = new Container);\n\n        $container->instance(Dispatcher::class, $this->fake);\n\n        $this->fake->chain([\n            new ChainedJobStub,\n        ])->dispatch();\n\n        $this->fake->assertChained([\n            ChainedJobStub::class,\n        ]);\n\n        $this->fake->chain([\n            new ChainedJobStub,\n            new OtherBusJobStub,\n        ])->dispatch();\n\n        $this->fake->assertChained([\n            ChainedJobStub::class,\n            OtherBusJobStub::class,\n        ]);\n\n        $this->fake->chain([\n            new ChainedJobStub,\n            $this->fake->batch([\n                new OtherBusJobStub,\n                new OtherBusJobStub,\n            ]),\n            new ChainedJobStub,\n        ])->dispatch();\n\n        $this->fake->assertChained([\n            ChainedJobStub::class,\n            $this->fake->chainedBatch(function ($pendingBatch) {\n                return $pendingBatch->jobs->count() === 2;\n            }),\n            ChainedJobStub::class,\n        ]);\n\n        $this->fake->assertChained([\n            new ChainedJobStub,\n            $this->fake->chainedBatch(function ($pendingBatch) {\n                return $pendingBatch->jobs->count() === 2;\n            }),\n            new ChainedJobStub,\n        ]);\n\n        $this->fake->chain([\n            $this->fake->batch([\n                new OtherBusJobStub,\n                new OtherBusJobStub,\n            ]),\n            new ChainedJobStub,\n            new ChainedJobStub,\n        ])->dispatch();\n\n        $this->fake->assertChained([\n            $this->fake->chainedBatch(function ($pendingBatch) {\n                return $pendingBatch->jobs->count() === 2;\n            }),\n            ChainedJobStub::class,\n            ChainedJobStub::class,\n        ]);\n\n        $this->fake->chain([\n            new ChainedJobStub(123),\n            new ChainedJobStub(456),\n        ])->dispatch();\n\n        $this->fake->assertChained([\n            fn (ChainedJobStub $job) => $job->id === 123,\n            fn (ChainedJobStub $job) => $job->id === 456,\n        ]);\n\n        Container::setInstance(null);\n    }\n\n    public function testAssertNothingChained()\n    {\n        $this->fake->assertNothingChained();\n    }\n\n    public function testAssertNothingChainedFails()\n    {\n        $this->fake->chain([new ChainedJobStub])->dispatch();\n\n        try {\n            $this->fake->assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The following jobs were dispatched unexpectedly:', $e->getMessage());\n            $this->assertStringContainsString(ChainedJobStub::class, $e->getMessage());\n        }\n    }\n\n    public function testAssertDispatchedWithIgnoreClass()\n    {\n        $dispatcher = m::mock(QueueingDispatcher::class);\n\n        $job = new BusJobStub;\n        $dispatcher->shouldReceive('dispatch')->once()->with($job);\n        $dispatcher->shouldReceive('dispatchNow')->once()->with($job, null);\n\n        $otherJob = new OtherBusJobStub;\n        $dispatcher->shouldReceive('dispatch')->never()->with($otherJob);\n        $dispatcher->shouldReceive('dispatchNow')->never()->with($otherJob, null);\n\n        $fake = new BusFake($dispatcher, OtherBusJobStub::class);\n\n        $fake->dispatch($job);\n        $fake->dispatchNow($job);\n\n        $fake->dispatch($otherJob);\n        $fake->dispatchNow($otherJob);\n\n        $fake->assertNotDispatched(BusJobStub::class);\n        $fake->assertDispatchedTimes(OtherBusJobStub::class, 2);\n    }\n\n    public function testDispatchedFakingOnlyGivenJobs()\n    {\n        $dispatcher = m::mock(QueueingDispatcher::class);\n\n        $job = new BusJobStub;\n        $dispatcher->shouldReceive('dispatch')->never()->with($job);\n        $dispatcher->shouldReceive('dispatchNow')->never()->with($job, null);\n\n        $otherJob = new OtherBusJobStub;\n        $dispatcher->shouldReceive('dispatch')->once()->with($otherJob);\n        $dispatcher->shouldReceive('dispatchNow')->once()->with($otherJob, null);\n\n        $thirdJob = new ThirdJob;\n        $dispatcher->shouldReceive('dispatch')->never()->with($thirdJob);\n        $dispatcher->shouldReceive('dispatchNow')->never()->with($thirdJob, null);\n\n        $fake = (new BusFake($dispatcher))->except(OtherBusJobStub::class);\n\n        $fake->dispatch($job);\n        $fake->dispatchNow($job);\n\n        $fake->dispatch($otherJob);\n        $fake->dispatchNow($otherJob);\n\n        $fake->dispatch($thirdJob);\n        $fake->dispatchNow($thirdJob);\n\n        $fake->assertNotDispatched(OtherBusJobStub::class);\n        $fake->assertDispatchedTimes(BusJobStub::class, 2);\n        $fake->assertDispatchedTimes(ThirdJob::class, 2);\n    }\n\n    public function testAssertDispatchedWithIgnoreCallback()\n    {\n        $dispatcher = m::mock(QueueingDispatcher::class);\n\n        $job = new BusJobStub;\n        $dispatcher->shouldReceive('dispatch')->once()->with($job);\n        $dispatcher->shouldReceive('dispatchNow')->once()->with($job, null);\n\n        $otherJob = new OtherBusJobStub;\n        $dispatcher->shouldReceive('dispatch')->once()->with($otherJob);\n        $dispatcher->shouldReceive('dispatchNow')->once()->with($otherJob, null);\n\n        $anotherJob = new OtherBusJobStub(1);\n        $dispatcher->shouldReceive('dispatch')->never()->with($anotherJob);\n        $dispatcher->shouldReceive('dispatchNow')->never()->with($anotherJob, null);\n\n        $fake = new BusFake($dispatcher, [\n            function ($command) {\n                return $command instanceof OtherBusJobStub && $command->id === 1;\n            },\n        ]);\n\n        $fake->dispatch($job);\n        $fake->dispatchNow($job);\n\n        $fake->dispatch($otherJob);\n        $fake->dispatchNow($otherJob);\n\n        $fake->dispatch($anotherJob);\n        $fake->dispatchNow($anotherJob);\n\n        $fake->assertNotDispatched(BusJobStub::class);\n        $fake->assertDispatchedTimes(OtherBusJobStub::class, 2);\n        $fake->assertNotDispatched(OtherBusJobStub::class, function ($job) {\n            return $job->id === null;\n        });\n        $fake->assertDispatched(OtherBusJobStub::class, function ($job) {\n            return $job->id === 1;\n        });\n    }\n\n    public function testAssertNothingBatched()\n    {\n        $this->fake->assertNothingBatched();\n\n        $job = new BusJobStub;\n\n        $this->fake->batch([$job])->dispatch();\n\n        try {\n            $this->fake->assertNothingBatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString(\"The following batched jobs were dispatched unexpectedly:\\n\\n- \".get_class($job), $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingPlacedPasses()\n    {\n        $this->fake->assertNothingPlaced();\n    }\n\n    public function testAssertNothingPlacedWhenJobBatched()\n    {\n        $this->fake->batch([new BusJobStub])->dispatch();\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->fake->assertNothingPlaced();\n    }\n\n    public function testAssertNothingPlacedWhenJobDispatched()\n    {\n        $this->fake->dispatch(new BusJobStub);\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->fake->assertNothingPlaced();\n    }\n\n    public function testAssertNothingPlacedWhenJobChained()\n    {\n        $this->fake->chain([new ChainedJobStub])->dispatch();\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->fake->assertNothingPlaced();\n    }\n\n    public function testAssertNothingPlacedWhenJobDispatchedNow()\n    {\n        $this->fake->dispatchNow(new BusJobStub);\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $this->fake->assertNothingPlaced();\n    }\n\n    public function testFindBatch()\n    {\n        $this->assertNull($this->fake->findBatch('non-existent-batch'));\n\n        $batch = $this->fake->batch([])->dispatch();\n\n        $this->assertSame($batch, $this->fake->findBatch($batch->id));\n    }\n\n    public function testBatchesCanBeCancelled()\n    {\n        $batch = $this->fake->batch([])->dispatch();\n\n        $this->assertFalse($batch->cancelled());\n\n        $batch->cancel();\n\n        $this->assertTrue($batch->cancelled());\n    }\n\n    public function testDispatchFakeBatch()\n    {\n        $this->fake->assertNothingBatched();\n\n        $batch = $this->fake->dispatchFakeBatch('my fake job batch');\n\n        $this->fake->assertBatchCount(1);\n        $this->assertInstanceOf(Batch::class, $batch);\n        $this->assertSame('my fake job batch', $batch->name);\n        $this->assertSame(0, $batch->totalJobs);\n\n        $batch = $this->fake->dispatchFakeBatch();\n\n        $this->fake->assertBatchCount(2);\n        $this->assertInstanceOf(Batch::class, $batch);\n        $this->assertSame('', $batch->name);\n        $this->assertSame(0, $batch->totalJobs);\n    }\n\n    public function testIncrementFailedJobsInFakeBatch()\n    {\n        $this->fake->assertNothingBatched();\n        $batch = $this->fake->dispatchFakeBatch('my fake job batch');\n\n        $this->fake->assertBatchCount(1);\n        $this->assertInstanceOf(Batch::class, $batch);\n        $this->assertSame('my fake job batch', $batch->name);\n        $this->assertSame(0, $batch->totalJobs);\n\n        $batch->incrementFailedJobs($batch->id);\n\n        $this->assertSame(0, $batch->failedJobs);\n        $this->assertSame(0, $batch->pendingJobs);\n    }\n\n    public function testDecrementPendingJobsInFakeBatch()\n    {\n        $this->fake->assertNothingBatched();\n        $batch = $this->fake->dispatchFakeBatch('my fake job batch');\n\n        $this->fake->assertBatchCount(1);\n        $this->assertInstanceOf(Batch::class, $batch);\n        $this->assertSame('my fake job batch', $batch->name);\n        $this->assertSame(0, $batch->totalJobs);\n\n        $batch->decrementPendingJobs($batch->id);\n\n        $this->assertSame(0, $batch->failedJobs);\n        $this->assertSame(0, $batch->pendingJobs);\n    }\n\n    #[DataProvider('serializeAndRestoreCommandMethodsDataProvider')]\n    public function testCanSerializeAndRestoreCommands($commandFunctionName, $assertionFunctionName)\n    {\n        $serializingBusFake = (clone $this->fake)->serializeAndRestore();\n\n        // without setting the serialization, the job should return the value passed in\n        $this->fake->{$commandFunctionName}(new BusFakeJobWithSerialization('hello'));\n        $this->fake->{$assertionFunctionName}(BusFakeJobWithSerialization::class, fn ($command) => $command->value === 'hello');\n\n        // when enabling the serializeAndRestore property, job has value modified\n        $serializingBusFake->{$commandFunctionName}(new BusFakeJobWithSerialization('hello'));\n        $serializingBusFake->{$assertionFunctionName}(\n            BusFakeJobWithSerialization::class,\n            fn ($command) => $command->value === 'hello-serialized-unserialized'\n        );\n    }\n\n    public static function serializeAndRestoreCommandMethodsDataProvider(): array\n    {\n        return [\n            'dispatch' => ['dispatch', 'assertDispatched'],\n            'dispatchSync' => ['dispatchSync', 'assertDispatchedSync'],\n            'dispatchNow' => ['dispatchNow', 'assertDispatched'],\n            'dispatchAfterResponse' => ['dispatchAfterResponse', 'assertDispatchedAfterResponse'],\n        ];\n    }\n\n    public function testCanSerializeAndRestoreCommandsInBatch()\n    {\n        $serializingBusFake = (clone $this->fake)->serializeAndRestore();\n\n        // without setting the serialization, the batch should return the value passed in\n        $this->fake->batch([\n            new BusFakeJobWithSerialization('hello'),\n        ])->dispatch();\n        $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n            return $batchedCollection->jobs->count() === 1 && $batchedCollection->jobs->first()->value === 'hello';\n        });\n\n        // when enabling the serializeAndRestore property, each batch jobs will each be serialized/restored\n        $serializingBusFake->batch([\n            new BusFakeJobWithSerialization('hello'),\n        ])->dispatch();\n\n        $serializingBusFake->assertBatched(function (PendingBatchFake $batchedCollection) {\n            return $batchedCollection->jobs->count() === 1 && $batchedCollection->jobs->first()->value === 'hello';\n        });\n    }\n\n    public function testDispatchAfterResponseWithHandler()\n    {\n        $job = new BusJobStub;\n        $handler = function () {\n            return 'handled';\n        };\n\n        $this->fake->dispatchAfterResponse($job, $handler);\n\n        $this->fake->assertDispatchedAfterResponse(BusJobStub::class);\n    }\n\n    public function testCanAssertJobsOnPendingBatchFake()\n    {\n        $this->fake->batch([\n            new BusFakeJobWithSerialization('foo'),\n            new BusFakeJobWithSerialization('bar'),\n            new BusFakeJobWithSerialization('baz'),\n        ])->dispatch();\n\n        $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n            return $batchedCollection->hasJobs([\n                new BusFakeJobWithSerialization('foo'),\n                new BusFakeJobWithSerialization('bar'),\n                new BusFakeJobWithSerialization('baz'),\n            ]);\n        });\n\n        $this->fake->assertBatched([\n            new BusFakeJobWithSerialization('foo'),\n            new BusFakeJobWithSerialization('bar'),\n            new BusFakeJobWithSerialization('baz'),\n        ]);\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    new BusFakeJobWithSerialization('baz'),\n                    new BusFakeJobWithSerialization('foo'),\n                    new BusFakeJobWithSerialization('bar'),\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    new BusFakeJobWithSerialization('foo'),\n                    new BusFakeJobWithSerialization('baaar'),\n                    new BusFakeJobWithSerialization('baz'),\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    new BusFakeJobWithSerialization('foo'),\n                    new BusFakeJobWithSerialization('baz'),\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    new BusFakeJobWithSerialization('foo'),\n                    new BusFakeJobWithSerialization('bar'),\n                    new BusFakeJobWithSerialization('baz'),\n                    new BusFakeJobWithSerialization('qux'),\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n    }\n\n    public function testCanAssertJobsOnPendingBatchFakeWithClosures()\n    {\n        $this->fake->batch([\n            new BusFakeJobWithSerialization('foo'),\n            new BusFakeJobWithSerialization('bar'),\n            new BusFakeJobWithSerialization('baz'),\n        ])->dispatch();\n\n        $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n            return $batchedCollection->hasJobs([\n                fn (BusFakeJobWithSerialization $job) => $job->value === 'foo',\n                fn (BusFakeJobWithSerialization $job) => $job->value === 'bar',\n                fn (BusFakeJobWithSerialization $job) => $job->value === 'baz',\n            ]);\n        });\n\n        $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n            return $batchedCollection->hasJobs([\n                fn (BusFakeJobWithSerialization $job) => $job->value === 'foo',\n                BusFakeJobWithSerialization::class,\n                new BusFakeJobWithSerialization('baz'),\n            ]);\n        });\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    fn (BusFakeJobWithSerialization $job) => $job->value === 'foo',\n                    fn (BusFakeJobWithSerialization $job) => $job->value === 'wrong',\n                    fn (BusFakeJobWithSerialization $job) => $job->value === 'baz',\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n\n        try {\n            $this->fake->assertBatched(function (PendingBatchFake $batchedCollection) {\n                return $batchedCollection->hasJobs([\n                    fn (BusFakeJobWithSerialization $job) => $job->value === 'foo',\n                    fn (BusJobStub $job) => true,\n                    fn (BusFakeJobWithSerialization $job) => $job->value === 'baz',\n                ]);\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected batch was not dispatched.', $e->getMessage());\n        }\n    }\n}\n\nclass BusJobStub\n{\n    //\n}\n\nclass ChainedJobStub\n{\n    use Queueable;\n\n    public $id;\n\n    public function __construct($id = null)\n    {\n        $this->id = $id;\n    }\n}\n\nclass OtherBusJobStub\n{\n    public $id;\n\n    public function __construct($id = null)\n    {\n        $this->id = $id;\n    }\n}\n\nclass ThirdJob\n{\n    //\n}\n\nclass BusFakeJobWithSerialization\n{\n    use Queueable;\n\n    public function __construct(public $value)\n    {\n    }\n\n    public function __serialize(): array\n    {\n        return ['value' => $this->value.'-serialized'];\n    }\n\n    public function __unserialize(array $data): void\n    {\n        $this->value = $data['value'].'-unserialized';\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportTestingEventFakeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Events\\Dispatcher;\nuse Illuminate\\Support\\Testing\\Fakes\\EventFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportTestingEventFakeTest extends TestCase\n{\n    protected $fake;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->fake = new EventFake(m::mock(Dispatcher::class));\n    }\n\n    public function testAssertDispatched()\n    {\n        try {\n            $this->fake->assertDispatched(EventStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\EventStub] event was not dispatched.', $e->getMessage());\n        }\n\n        $this->fake->dispatch(EventStub::class);\n\n        $this->fake->assertDispatched(EventStub::class);\n    }\n\n    public function testAssertDispatchedWithClosure()\n    {\n        $this->fake->dispatch(new EventStub);\n\n        $this->fake->assertDispatched(function (EventStub $event) {\n            return true;\n        });\n    }\n\n    public function testAssertListening()\n    {\n        $listener = ListenerStub::class;\n\n        $dispatcher = m::mock(Dispatcher::class);\n        $dispatcher->shouldReceive('getListeners')->andReturn([function ($event, $payload) use ($listener) {\n            return $listener(...array_values($payload));\n        }]);\n\n        $fake = new EventFake($dispatcher);\n\n        $fake->assertListening(EventStub::class, ListenerStub::class);\n    }\n\n    public function testAssertDispatchedWithCallbackInt()\n    {\n        $this->fake->dispatch(EventStub::class);\n        $this->fake->dispatch(EventStub::class);\n\n        try {\n            $this->fake->assertDispatched(EventStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\EventStub] event was dispatched 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatched(EventStub::class, 2);\n    }\n\n    public function testAssertDispatchedOnce()\n    {\n        $this->fake->dispatch(EventStub::class);\n        $this->fake->dispatch(EventStub::class);\n\n        try {\n            $this->fake->assertDispatchedOnce(EventStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\EventStub] event was dispatched 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedTimes(EventStub::class, 2);\n    }\n\n    public function testAssertDispatchedTimes()\n    {\n        $this->fake->dispatch(EventStub::class);\n        $this->fake->dispatch(EventStub::class);\n\n        try {\n            $this->fake->assertDispatchedTimes(EventStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\EventStub] event was dispatched 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertDispatchedTimes(EventStub::class, 2);\n    }\n\n    public function testAssertNotDispatched()\n    {\n        $this->fake->assertNotDispatched(EventStub::class);\n\n        $this->fake->dispatch(EventStub::class);\n\n        try {\n            $this->fake->assertNotDispatched(EventStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\EventStub] event was dispatched.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotDispatchedWithClosure()\n    {\n        $this->fake->dispatch(new EventStub);\n\n        try {\n            $this->fake->assertNotDispatched(function (EventStub $event) {\n                return true;\n            });\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\EventStub] event was dispatched.', $e->getMessage());\n        }\n    }\n\n    public function testAssertDispatchedWithIgnore()\n    {\n        $dispatcher = m::mock(Dispatcher::class);\n        $dispatcher->shouldReceive('dispatch')->once();\n\n        $fake = new EventFake($dispatcher, [\n            'Foo',\n            function ($event, $payload) {\n                return $event === 'Bar' && $payload['id'] === 1;\n            },\n        ]);\n\n        $fake->dispatch('Foo');\n        $fake->dispatch('Bar', ['id' => 1]);\n        $fake->dispatch('Baz');\n\n        $fake->assertDispatched('Foo');\n        $fake->assertDispatched('Bar');\n        $fake->assertNotDispatched('Baz');\n    }\n\n    public function testAssertNothingDispatched()\n    {\n        $this->fake->assertNothingDispatched();\n\n        $this->fake->dispatch(EventStub::class);\n        $this->fake->dispatch(EventStub::class);\n\n        try {\n            $this->fake->assertNothingDispatched();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString(\"2 unexpected events were dispatched:\\n\\n- Illuminate\\Tests\\Support\\EventStub dispatched 2 times\", $e->getMessage());\n        }\n    }\n}\n\nclass EventStub\n{\n    //\n}\n\nclass ListenerStub\n{\n    //\n}\n"
  },
  {
    "path": "tests/Support/SupportTestingMailFakeTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Contracts\\Translation\\HasLocalePreference;\nuse Illuminate\\Mail\\Mailable;\nuse Illuminate\\Mail\\MailManager;\nuse Illuminate\\Support\\Testing\\Fakes\\MailFake;\nuse Mockery as m;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportTestingMailFakeTest extends TestCase\n{\n    /**\n     * @var \\Mockery\n     */\n    private $mailManager;\n\n    /**\n     * @var \\Illuminate\\Support\\Testing\\Fakes\\MailFake\n     */\n    private $fake;\n\n    /**\n     * @var \\Illuminate\\Tests\\Support\\MailableStub\n     */\n    private $mailable;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n        $this->mailManager = m::mock(MailManager::class, function ($mock) {\n            $mock->shouldReceive('getDefaultDriver')\n                ->andReturn('smtp');\n        });\n        $this->fake = new MailFake($this->mailManager);\n        $this->mailable = new MailableStub;\n    }\n\n    public function testAssertSent()\n    {\n        try {\n            $this->fake->assertSent(MailableStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was not sent.', $e->getMessage());\n        }\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class);\n    }\n\n    public function testAssertSentTo()\n    {\n        try {\n            $this->fake->assertSent(MailableStub::class, 'taylor@laravel.com');\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was not sent to address [taylor@laravel.com].', $e->getMessage());\n        }\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, 'taylor@laravel.com');\n    }\n\n    public function testAssertSentToMultiple()\n    {\n        $this->fake->to('dries@laravel.com')->send($this->mailable);\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->to(['nuno@laravel.com', 'jess@laravel.com'])->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, 3);\n        $this->fake->assertSent(\n            MailableStub::class,\n            ['taylor@laravel.com', 'dries@laravel.com', 'nuno@laravel.com', 'jess@laravel.com']\n        );\n    }\n\n    public function testAssertSentWhenRecipientHasPreferredLocale()\n    {\n        $user = new LocalizedRecipientStub;\n\n        $this->fake->to($user)->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) use ($user) {\n            return $mail->hasTo($user) && $mail->locale === 'au';\n        });\n    }\n\n    public function testAssertTo()\n    {\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) {\n            return $mail->hasTo('taylor@laravel.com');\n        });\n    }\n\n    public function testAssertCc()\n    {\n        $this->fake->cc('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) {\n            return $mail->hasCc('taylor@laravel.com');\n        });\n    }\n\n    public function testAssertBcc()\n    {\n        $this->fake->bcc('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) {\n            return $mail->hasBcc('taylor@laravel.com');\n        });\n    }\n\n    public function testAssertNotSent()\n    {\n        $this->fake->assertNotSent(MailableStub::class);\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        try {\n            $this->fake->assertNotSent(MailableStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The unexpected [Illuminate\\Tests\\Support\\MailableStub] mailable was sent.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNotSentWithClosure()\n    {\n        $callback = function (MailableStub $mail) {\n            return $mail->hasTo('taylor@laravel.com');\n        };\n\n        $this->fake->assertNotSent($callback);\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessageMatches('/The unexpected \\['.preg_quote(MailableStub::class, '/').'\\] mailable was sent./m');\n\n        $this->fake->assertNotSent($callback);\n    }\n\n    public function testAssertNotSentWithString()\n    {\n        $this->fake->assertNotSent(MailableStub::class, 'taylor@laravel.com');\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was sent to address [taylor@laravel.com].');\n\n        $this->fake->assertNotSent(MailableStub::class, 'taylor@laravel.com');\n    }\n\n    public function testAssertNotSentWithArray()\n    {\n        $this->fake->assertNotSent(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']);\n\n        $this->fake->to('dries@laravel.com')->send($this->mailable);\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was sent to address [dries@laravel.com].');\n\n        $this->fake->assertNotSent(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']);\n    }\n\n    public function testAssertSentTimes()\n    {\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        try {\n            $this->fake->assertSent(MailableStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was sent 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertSent(MailableStub::class, 2);\n    }\n\n    public function testAssertSentCount()\n    {\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        try {\n            $this->fake->assertSentCount(1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The total number of mailables sent was 2 instead of 1.', $e->getMessage());\n        }\n\n        $this->fake->assertSentCount(2);\n    }\n\n    public function testAssertQueued()\n    {\n        try {\n            $this->fake->assertQueued(MailableStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was not queued.', $e->getMessage());\n        }\n\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->fake->assertQueued(MailableStub::class);\n    }\n\n    public function testAssertQueuedTo()\n    {\n        try {\n            $this->fake->assertQueued(MailableStub::class, 'taylor@laravel.com');\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was not queued to address [taylor@laravel.com].', $e->getMessage());\n        }\n\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->fake->assertQueued(MailableStub::class, 'taylor@laravel.com');\n    }\n\n    public function testAssertQueuedToMultiple()\n    {\n        $this->fake->to('dries@laravel.com')->queue($this->mailable);\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->fake->to(['nuno@laravel.com', 'jess@laravel.com'])->queue($this->mailable);\n\n        $this->fake->assertQueued(MailableStub::class, 3);\n        $this->fake->assertQueued(\n            MailableStub::class,\n            ['taylor@laravel.com', 'dries@laravel.com', 'nuno@laravel.com', 'jess@laravel.com']\n        );\n    }\n\n    public function testAssertQueuedTimes()\n    {\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        try {\n            $this->fake->assertQueued(MailableStub::class, 1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\MailableStub] mailable was queued 2 times instead of 1 time.', $e->getMessage());\n        }\n\n        $this->fake->assertQueued(MailableStub::class, 2);\n    }\n\n    public function testAssertNotQueuedWithString()\n    {\n        $this->fake->assertNotQueued(MailableStub::class, 'taylor@laravel.com');\n\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was queued to address [taylor@laravel.com].');\n\n        $this->fake->assertNotQueued(MailableStub::class, 'taylor@laravel.com');\n    }\n\n    public function testAssertNotQueuedWithArray()\n    {\n        $this->fake->assertNotQueued(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']);\n\n        $this->fake->to('dries@laravel.com')->queue($this->mailable);\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was queued to address [dries@laravel.com].');\n\n        $this->fake->assertNotQueued(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']);\n    }\n\n    public function testAssertQueuedCount()\n    {\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        try {\n            $this->fake->assertQueuedCount(1);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The total number of mailables queued was 2 instead of 1.', $e->getMessage());\n        }\n\n        $this->fake->assertQueuedCount(2);\n    }\n\n    public function testSendQueuesAMailableThatShouldBeQueued()\n    {\n        $this->fake->to('taylor@laravel.com')->send(new QueueableMailableStub);\n\n        $this->fake->assertQueued(QueueableMailableStub::class);\n\n        try {\n            $this->fake->assertSent(QueueableMailableStub::class);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The expected [Illuminate\\Tests\\Support\\QueueableMailableStub] mailable was not sent.', $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingSent()\n    {\n        $this->fake->assertNothingSent();\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        try {\n            $this->fake->assertNothingSent();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString(\"The following mailables were sent unexpectedly:\\n\\n- Illuminate\\Tests\\Support\\MailableStub\", $e->getMessage());\n        }\n    }\n\n    public function testAssertNothingQueued()\n    {\n        $this->fake->assertNothingQueued();\n\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        try {\n            $this->fake->assertNothingQueued();\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString(\"The following mailables were queued unexpectedly:\\n\\n- Illuminate\\Tests\\Support\\MailableStub\", $e->getMessage());\n        }\n    }\n\n    public function testAssertOutgoingCount()\n    {\n        $this->fake->assertNothingOutgoing();\n\n        $this->fake->to('taylor@laravel.com')->queue($this->mailable);\n\n        try {\n            $this->fake->assertOutgoingCount(2);\n            $this->fail();\n        } catch (ExpectationFailedException $e) {\n            $this->assertStringContainsString('The total number of outgoing mailables was 1 instead of 2.', $e->getMessage());\n        }\n\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertOutgoingCount(2);\n    }\n\n    public function testAssertQueuedWithClosure()\n    {\n        $this->fake->to($user = new LocalizedRecipientStub)->queue($this->mailable);\n\n        $this->fake->assertQueued(function (MailableStub $mail) use ($user) {\n            return $mail->hasTo($user);\n        });\n    }\n\n    public function testAssertSentWithClosure()\n    {\n        $this->fake->to($user = new LocalizedRecipientStub)->send($this->mailable);\n\n        $this->fake->assertSent(function (MailableStub $mail) use ($user) {\n            return $mail->hasTo($user);\n        });\n    }\n\n    public function testMissingMethodsAreForwarded()\n    {\n        $this->mailManager->shouldReceive('foo')->andReturn('bar');\n\n        $this->assertEquals('bar', $this->fake->foo());\n    }\n\n    public function testAssertMailer()\n    {\n        $this->fake->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) {\n            return $mail->usesMailer('smtp');\n        });\n\n        $this->fake->mailer('ses')->to('taylor@laravel.com')->send($this->mailable);\n\n        $this->fake->assertSent(MailableStub::class, function ($mail) {\n            return $mail->usesMailer('ses');\n        });\n\n        $this->fake->mailer('sendgrid')->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->fake->assertQueued(MailableStub::class, function ($mail) {\n            return $mail->usesMailer('sendgrid');\n        });\n\n        $this->fake->mailer('mailjet')->to('taylor@laravel.com')->queue($this->mailable);\n\n        $this->fake->assertQueued(MailableStub::class, function ($mail) {\n            return $mail->usesMailer('mailjet');\n        });\n    }\n}\n\nclass MailableStub extends Mailable\n{\n    public $framework = 'Laravel';\n\n    protected $version = '6.0';\n\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        $this->with('first_name', 'Taylor')\n            ->withLastName('Otwell');\n    }\n}\n\nclass QueueableMailableStub extends Mailable implements ShouldQueue\n{\n    public $framework = 'Laravel';\n\n    protected $version = '6.0';\n\n    /**\n     * Build the message.\n     *\n     * @return $this\n     */\n    public function build()\n    {\n        $this->with('first_name', 'Taylor')\n            ->withLastName('Otwell');\n    }\n}\n\nclass LocalizedRecipientStub implements HasLocalePreference\n{\n    public $email = 'taylor@laravel.com';\n\n    public function preferredLocale()\n    {\n        return 'au';\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportTimeboxTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Exception;\nuse Illuminate\\Support\\Timebox;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportTimeboxTest extends TestCase\n{\n    public function testMakeExecutesCallback()\n    {\n        $callback = function () {\n            $this->assertTrue(true);\n        };\n\n        (new Timebox)->call($callback, 0);\n    }\n\n    public function testMakeWaitsForMicroseconds()\n    {\n        $mock = m::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial();\n        $mock->shouldReceive('usleep')->once();\n\n        $mock->call(function () {\n        }, 10000);\n\n        $mock->shouldHaveReceived('usleep')->once();\n    }\n\n    public function testMakeShouldNotSleepWhenEarlyReturnHasBeenFlagged()\n    {\n        $mock = m::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial();\n        $mock->call(function ($timebox) {\n            $timebox->returnEarly();\n        }, 10000);\n\n        $mock->shouldNotHaveReceived('usleep');\n    }\n\n    public function testMakeShouldSleepWhenDontEarlyReturnHasBeenFlagged()\n    {\n        $mock = m::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial();\n        $mock->shouldReceive('usleep')->once();\n\n        $mock->call(function ($timebox) {\n            $timebox->returnEarly();\n            $timebox->dontReturnEarly();\n        }, 10000);\n\n        $mock->shouldHaveReceived('usleep')->once();\n    }\n\n    public function testMakeWaitsForMicrosecondsWhenExceptionIsThrown()\n    {\n        $mock = m::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial();\n        $mock->shouldReceive('usleep')->once();\n\n        try {\n            $this->expectExceptionMessage('Exception within Timebox callback.');\n\n            $mock->call(function () {\n                throw new Exception('Exception within Timebox callback.');\n            }, 10000);\n        } finally {\n            $mock->shouldHaveReceived('usleep')->once();\n        }\n    }\n\n    public function testMakeShouldNotSleepWhenEarlyReturnHasBeenFlaggedAndExceptionIsThrown()\n    {\n        $mock = m::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial();\n\n        try {\n            $this->expectExceptionMessage('Exception within Timebox callback.');\n\n            $mock->call(function ($timebox) {\n                $timebox->returnEarly();\n                throw new Exception('Exception within Timebox callback.');\n            }, 10000);\n        } finally {\n            $mock->shouldNotHaveReceived('usleep');\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportUriTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Contracts\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Uri;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportUriTest extends TestCase\n{\n    public function test_can_build_special_urls()\n    {\n        Uri::setUrlGeneratorResolver(fn () => new CustomUrlGeneratorResolver);\n\n        $this->assertEquals('https://laravel.com/to', Uri::to('')->value());\n        $this->assertEquals('https://laravel.com/route', Uri::route('')->value());\n        $this->assertEquals('https://laravel.com/signed-route', Uri::signedRoute('')->value());\n        $this->assertEquals('https://laravel.com/signed-route', Uri::temporarySignedRoute('', '')->value());\n        $this->assertEquals('https://laravel.com/action', Uri::action('')->value());\n    }\n\n    public function test_basic_uri_interactions()\n    {\n        $uri = Uri::of($originalUri = 'https://laravel.com/docs/installation');\n\n        $this->assertEquals('https', $uri->scheme());\n        $this->assertNull($uri->user());\n        $this->assertNull($uri->password());\n        $this->assertEquals('laravel.com', $uri->host());\n        $this->assertNull($uri->port());\n        $this->assertEquals('docs/installation', $uri->path());\n        $this->assertEquals([], $uri->query()->toArray());\n        $this->assertEquals('', (string) $uri->query());\n        $this->assertEquals('', $uri->query()->decode());\n        $this->assertNull($uri->fragment());\n        $this->assertEquals($originalUri, (string) $uri);\n\n        $uri = Uri::of('https://taylor:password@laravel.com/docs/installation?version=1#hello');\n\n        $this->assertEquals('taylor', $uri->user());\n        $this->assertEquals('password', $uri->password());\n        $this->assertEquals('hello', $uri->fragment());\n        $this->assertEquals(['version' => 1], $uri->query()->all());\n        $this->assertEquals(1, $uri->query()->integer('version'));\n        $this->assertEquals('taylor:password@laravel.com', $uri->authority());\n    }\n\n    public function test_complicated_query_string_parsing()\n    {\n        $uri = Uri::of('https://example.com/users?key_1=value&key_2[sub_field]=value&key_3[]=value&key_4[9]=value&key_5[][][foo][9]=bar&key.6=value&flag_value');\n\n        $this->assertEquals([\n            'key_1' => 'value',\n            'key_2' => [\n                'sub_field' => 'value',\n            ],\n            'key_3' => [\n                'value',\n            ],\n            'key_4' => [\n                9 => 'value',\n            ],\n            'key_5' => [\n                [\n                    [\n                        'foo' => [\n                            9 => 'bar',\n                        ],\n                    ],\n                ],\n            ],\n            'key.6' => 'value',\n            'flag_value' => '',\n        ], $uri->query()->all());\n\n        $this->assertEquals('key_1=value&key_2[sub_field]=value&key_3[]=value&key_4[9]=value&key_5[][][foo][9]=bar&key.6=value&flag_value', $uri->query()->decode());\n    }\n\n    public function test_uri_building()\n    {\n        $uri = Uri::of();\n\n        $uri = $uri->withHost('laravel.com')\n            ->withScheme('https')\n            ->withUser('taylor', 'password')\n            ->withPath('/docs/installation')\n            ->withPort(80)\n            ->withQuery(['version' => 1])\n            ->withFragment('hello');\n\n        $expected = 'https://taylor:password@laravel.com:80/docs/installation?version=1#hello';\n\n        $this->assertEquals($expected, (string) $uri);\n        $this->assertEquals($expected, $uri->value());\n        $this->assertEquals($expected, $uri->toString());\n    }\n\n    public function test_complicated_query_string_manipulation()\n    {\n        $uri = Uri::of('https://laravel.com');\n\n        $uri = $uri->withQuery([\n            'name' => 'Taylor',\n            'age' => 38,\n            'role' => [\n                'title' => 'Developer',\n                'focus' => 'PHP',\n            ],\n            'tags' => [\n                'person',\n                'employee',\n            ],\n            'flag' => '',\n        ])->withoutQuery(['name']);\n\n        $this->assertEquals('age=38&role[title]=Developer&role[focus]=PHP&tags[0]=person&tags[1]=employee&flag=', $uri->query()->decode());\n        $this->assertEquals('name=Taylor', $uri->replaceQuery(['name' => 'Taylor'])->query()->decode());\n\n        // Push onto multi-value and missing items...\n        $uri = Uri::of('https://laravel.com?tags[]=foo');\n\n        $this->assertEquals(['tags' => ['foo', 'bar']], $uri->pushOntoQuery('tags', 'bar')->query()->all());\n        $this->assertEquals(['tags' => ['foo', 'bar', 'baz']], $uri->pushOntoQuery('tags', ['bar', 'baz'])->query()->all());\n        $this->assertEquals(['tags' => ['foo'], 'names' => ['Taylor']], $uri->pushOntoQuery('names', 'Taylor')->query()->all());\n\n        // Push onto single value item...\n        $uri = Uri::of('https://laravel.com?tag=foo');\n\n        $this->assertEquals(['tag' => ['foo', 'bar']], $uri->pushOntoQuery('tag', 'bar')->query()->all());\n    }\n\n    public function test_query_strings_with_dots_can_be_replaced_or_merged_consistently()\n    {\n        $uri = Uri::of('https://dot.test/?foo.bar=baz');\n\n        $this->assertEquals('foo.bar=baz&foo[bar]=zab', $uri->withQuery(['foo.bar' => 'zab'])->query()->decode());\n        $this->assertEquals('foo[bar]=zab', $uri->replaceQuery(['foo.bar' => 'zab'])->query()->decode());\n    }\n\n    public function test_decoding_the_entire_uri()\n    {\n        $uri = Uri::of('https://laravel.com/docs/11.x/installation')->withQuery(['tags' => ['first', 'second']]);\n\n        $this->assertEquals('https://laravel.com/docs/11.x/installation?tags[0]=first&tags[1]=second', $uri->decode());\n    }\n\n    public function test_with_query_if_missing()\n    {\n        // Test adding new parameters while preserving existing ones\n        $uri = Uri::of('https://laravel.com?existing=value');\n\n        $uri = $uri->withQueryIfMissing([\n            'new' => 'parameter',\n            'existing' => 'new_value',\n        ]);\n\n        $this->assertEquals('existing=value&new=parameter', $uri->query()->decode());\n\n        // Test adding complex nested arrays to empty query string\n        $uri = Uri::of('https://laravel.com');\n\n        $uri = $uri->withQueryIfMissing([\n            'name' => 'Taylor',\n            'role' => [\n                'title' => 'Developer',\n                'focus' => 'PHP',\n            ],\n            'tags' => [\n                'person',\n                'employee',\n            ],\n        ]);\n\n        $this->assertEquals('name=Taylor&role[title]=Developer&role[focus]=PHP&tags[0]=person&tags[1]=employee', $uri->query()->decode());\n\n        // Test partial array merging and preserving indexed arrays\n        $uri = Uri::of('https://laravel.com?name=Taylor&tags[0]=person');\n\n        $uri = $uri->withQueryIfMissing([\n            'name' => 'Changed',\n            'age' => 38,\n            'tags' => ['should', 'not', 'change'],\n        ]);\n\n        $this->assertEquals('name=Taylor&tags[0]=person&age=38', $uri->query()->decode());\n        $this->assertEquals(['name' => 'Taylor', 'tags' => ['person'], 'age' => 38], $uri->query()->all());\n\n        $uri = Uri::of('https://laravel.com?user[name]=Taylor');\n\n        $uri = $uri->withQueryIfMissing([\n            'user' => [\n                'name' => 'Should Not Change',\n                'age' => 38,\n            ],\n            'settings' => [\n                'theme' => 'dark',\n            ],\n        ]);\n        $this->assertEquals([\n            'user' => [\n                'name' => 'Taylor',\n            ],\n            'settings' => [\n                'theme' => 'dark',\n            ],\n        ], $uri->query()->all());\n    }\n\n    public function test_with_query_prevents_empty_query_string()\n    {\n        $uri = Uri::of('https://laravel.com');\n\n        $this->assertEquals('https://laravel.com', (string) $uri);\n        $this->assertEquals('https://laravel.com', (string) $uri->withQuery([]));\n    }\n\n    public function test_path_segments()\n    {\n        $uri = Uri::of('https://laravel.com');\n\n        $this->assertEquals([], $uri->pathSegments()->toArray());\n\n        $uri = Uri::of('https://laravel.com/one/two/three');\n\n        $this->assertEquals(['one', 'two', 'three'], $uri->pathSegments()->toArray());\n        $this->assertEquals('one', $uri->pathSegments()->first());\n\n        $uri = Uri::of('https://laravel.com/one/two/three?foo=bar');\n\n        $this->assertEquals(3, $uri->pathSegments()->count());\n\n        $uri = Uri::of('https://laravel.com/one/two/three/?foo=bar');\n\n        $this->assertEquals(3, $uri->pathSegments()->count());\n\n        $uri = Uri::of('https://laravel.com/one/two/three/#foo=bar');\n\n        $this->assertEquals(3, $uri->pathSegments()->count());\n    }\n\n    public function test_macroable()\n    {\n        Uri::macro('myMacro', function () {\n            return $this->withPath('foobar');\n        });\n\n        $uri = new Uri('https://laravel.com/');\n\n        $this->assertSame('https://laravel.com/foobar', (string) $uri->myMacro());\n    }\n}\n\nclass CustomUrlGeneratorResolver implements UrlGenerator\n{\n    public function current()\n    {\n        return 'https://laravel.com/current';\n    }\n\n    public function previous($fallback = false)\n    {\n        return 'https://laravel.com/previous';\n    }\n\n    public function to($path, $extra = [], $secure = null)\n    {\n        return 'https://laravel.com/to';\n    }\n\n    public function secure($path, $parameters = [])\n    {\n        return 'https://laravel.com/secure';\n    }\n\n    public function asset($path, $secure = null)\n    {\n        return 'https://laravel.com/asset';\n    }\n\n    public function route($name, $parameters = [], $absolute = true)\n    {\n        return 'https://laravel.com/route';\n    }\n\n    public function signedRoute($name, $parameters = [], $expiration = null, $absolute = true)\n    {\n        return 'https://laravel.com/signed-route';\n    }\n\n    public function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true)\n    {\n        return 'https://laravel.com/temporary-signed-route';\n    }\n\n    public function query($path, $query = [], $extra = [], $secure = null)\n    {\n        return 'https://laravel.com/query';\n    }\n\n    public function action($action, $parameters = [], $absolute = true)\n    {\n        return 'https://laravel.com/action';\n    }\n\n    public function getRootControllerNamespace()\n    {\n        return 'App\\\\Http\\\\Controllers';\n    }\n\n    public function setRootControllerNamespace($rootNamespace)\n    {\n        return $this;\n    }\n}\n"
  },
  {
    "path": "tests/Support/SupportViewErrorBagTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Support;\n\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\ViewErrorBag;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SupportViewErrorBagTest extends TestCase\n{\n    public function testHasBagTrue()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag(['msg1', 'msg2']));\n        $this->assertTrue($viewErrorBag->hasBag());\n    }\n\n    public function testHasBagFalse()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $this->assertFalse($viewErrorBag->hasBag());\n    }\n\n    public function testGet()\n    {\n        $messageBag = new MessageBag;\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag = $viewErrorBag->put('default', $messageBag);\n        $this->assertEquals($messageBag, $viewErrorBag->getBag('default'));\n    }\n\n    public function testGetBagWithNew()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $this->assertInstanceOf(MessageBag::class, $viewErrorBag->getBag('default'));\n    }\n\n    public function testGetBags()\n    {\n        $messageBag1 = new MessageBag;\n        $messageBag2 = new MessageBag;\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', $messageBag1);\n        $viewErrorBag->put('default2', $messageBag2);\n        $this->assertEquals([\n            'default' => $messageBag1,\n            'default2' => $messageBag2,\n        ], $viewErrorBag->getBags());\n    }\n\n    public function testPut()\n    {\n        $messageBag = new MessageBag;\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag = $viewErrorBag->put('default', $messageBag);\n        $this->assertEquals(['default' => $messageBag], $viewErrorBag->getBags());\n    }\n\n    public function testAnyTrue()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag(['message']));\n        $this->assertTrue($viewErrorBag->any());\n    }\n\n    public function testAnyFalse()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag);\n        $this->assertFalse($viewErrorBag->any());\n    }\n\n    public function testAnyFalseWithEmptyErrorBag()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $this->assertFalse($viewErrorBag->any());\n    }\n\n    public function testCount()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag(['message', 'second']));\n        $this->assertCount(2, $viewErrorBag);\n    }\n\n    public function testCountWithNoMessagesInMessageBag()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag);\n        $this->assertCount(0, $viewErrorBag);\n    }\n\n    public function testCountWithNoMessageBags()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $this->assertCount(0, $viewErrorBag);\n    }\n\n    public function testDynamicCallToDefaultMessageBag()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->put('default', new MessageBag(['message', 'second']));\n        $this->assertEquals(['message', 'second'], $viewErrorBag->all());\n    }\n\n    public function testDynamicallyGetBag()\n    {\n        $messageBag = new MessageBag;\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag = $viewErrorBag->put('default', $messageBag);\n        $this->assertEquals($messageBag, $viewErrorBag->default);\n    }\n\n    public function testDynamicallyPutBag()\n    {\n        $messageBag = new MessageBag;\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag->default2 = $messageBag;\n        $this->assertEquals(['default2' => $messageBag], $viewErrorBag->getBags());\n    }\n\n    public function testToString()\n    {\n        $viewErrorBag = new ViewErrorBag;\n        $viewErrorBag = $viewErrorBag->put('default', new MessageBag(['message' => 'content']));\n        $this->assertSame('{\"message\":[\"content\"]}', (string) $viewErrorBag);\n    }\n}\n"
  },
  {
    "path": "tests/Testing/AssertRedirectToActionTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Orchestra\\Testbench\\TestCase;\n\nclass AssertRedirectToActionTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Contracts\\Routing\\Registrar\n     */\n    private $router;\n\n    /**\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    public $urlGenerator;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = $this->app->make(Registrar::class);\n\n        $this->router->get('controller/index', [TestActionController::class, 'index']);\n        $this->router->get('controller/show/{id}', [TestActionController::class, 'show']);\n\n        $this->router->get('redirect-to-index', function () {\n            return new RedirectResponse($this->urlGenerator->action([TestActionController::class, 'index']));\n        });\n\n        $this->router->get('redirect-to-show', function () {\n            return new RedirectResponse($this->urlGenerator->action([TestActionController::class, 'show'], ['id' => 123]));\n        });\n\n        $this->urlGenerator = $this->app->make(UrlGenerator::class);\n    }\n\n    public function testAssertRedirectToActionWithoutParameters(): void\n    {\n        $this->get('redirect-to-index')\n            ->assertRedirectToAction([TestActionController::class, 'index']);\n    }\n\n    public function testAssertRedirectToActionWithParameters(): void\n    {\n        $this->get('redirect-to-show')\n            ->assertRedirectToAction([TestActionController::class, 'show'], ['id' => 123]);\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n}\n\nclass TestActionController extends Controller\n{\n    public function index()\n    {\n        return 'ok';\n    }\n\n    public function show($id)\n    {\n        return \"id: $id\";\n    }\n}\n"
  },
  {
    "path": "tests/Testing/AssertRedirectToRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Orchestra\\Testbench\\TestCase;\n\nclass AssertRedirectToRouteTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Contracts\\Routing\\Registrar\n     */\n    private $router;\n\n    /**\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    private $urlGenerator;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = $this->app->make(Registrar::class);\n\n        $this->router\n            ->get('named-route')\n            ->name('named-route');\n\n        $this->router\n            ->get('named-route-with-param/{param}')\n            ->name('named-route-with-param');\n\n        $this->router\n            ->get('')\n            ->name('route-with-empty-uri');\n\n        $this->urlGenerator = $this->app->make(UrlGenerator::class);\n    }\n\n    public function testAssertRedirectToRouteWithRouteName(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->route('named-route'));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToRoute('named-route');\n    }\n\n    public function testAssertRedirectToRouteWithRouteNameAndParams(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->route('named-route-with-param', 'hello'));\n        });\n\n        $this->router->get('test-route-with-extra-param', function () {\n            return new RedirectResponse($this->urlGenerator->route('named-route-with-param', [\n                'param' => 'foo',\n                'extra' => 'another',\n            ]));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToRoute('named-route-with-param', 'hello');\n\n        $this->get('test-route-with-extra-param')\n            ->assertRedirectToRoute('named-route-with-param', [\n                'param' => 'foo',\n                'extra' => 'another',\n            ]);\n    }\n\n    public function testAssertRedirectToRouteWithRouteNameAndParamsWhenRouteUriIsEmpty(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->route('route-with-empty-uri', ['foo' => 'bar']));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToRoute('route-with-empty-uri', ['foo' => 'bar']);\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Testing/AssertRedirectToSignedRouteTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Orchestra\\Testbench\\TestCase;\n\nclass AssertRedirectToSignedRouteTest extends TestCase\n{\n    /**\n     * @var \\Illuminate\\Contracts\\Routing\\Registrar\n     */\n    private $router;\n\n    /**\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    private $urlGenerator;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = $this->app->make(Registrar::class);\n\n        $this->router\n            ->get('signed-route')\n            ->name('signed-route');\n\n        $this->router\n            ->get('signed-route-with-param/{param}')\n            ->name('signed-route-with-param');\n\n        $this->urlGenerator = $this->app->make(UrlGenerator::class);\n    }\n\n    protected function defineEnvironment($app): void\n    {\n        $app['config']->set(['app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF']);\n    }\n\n    public function testAssertRedirectToSignedRouteWithoutRouteName(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route'));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToSignedRoute();\n    }\n\n    public function testAssertRedirectToSignedRouteWithRouteName(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route'));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToSignedRoute('signed-route');\n    }\n\n    public function testAssertRedirectToSignedRouteWithRouteNameAndParams(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route-with-param', 'hello'));\n        });\n\n        $this->router->get('test-route-with-extra-param', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route-with-param', [\n                'param' => 'foo',\n                'extra' => 'another',\n            ]));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToSignedRoute('signed-route-with-param', 'hello');\n\n        $this->get('test-route-with-extra-param')\n            ->assertRedirectToSignedRoute('signed-route-with-param', [\n                'param' => 'foo',\n                'extra' => 'another',\n            ]);\n    }\n\n    public function testAssertRedirectToSignedRouteWithRouteNameToTemporarySignedRoute(): void\n    {\n        $this->router->get('test-route', function () {\n            return new RedirectResponse($this->urlGenerator->temporarySignedRoute('signed-route', 60));\n        });\n\n        $this->get('test-route')\n            ->assertRedirectToSignedRoute('signed-route');\n    }\n\n    protected function tearDown(): void\n    {\n        Facade::setFacadeApplication(null);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Testing/AssertTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Testing\\Assert;\nuse Illuminate\\Testing\\Exceptions\\InvalidArgumentException;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\nuse stdClass;\n\nclass AssertTest extends TestCase\n{\n    public function testArraySubset()\n    {\n        Assert::assertArraySubset([\n            'string' => 'string',\n            'object' => new stdClass(),\n        ], [\n            'int' => 1,\n            'string' => 'string',\n            'object' => new stdClass(),\n        ]);\n    }\n\n    public function testArraySubsetMayFail(): void\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        Assert::assertArraySubset([\n            'int' => 2,\n            'string' => 'string',\n            'object' => new stdClass(),\n        ], [\n            'int' => 1,\n            'string' => 'string',\n            'object' => new stdClass(),\n        ]);\n    }\n\n    public function testArraySubsetWithStrict(): void\n    {\n        Assert::assertArraySubset([\n            'string' => 'string',\n            'object' => $object = new stdClass(),\n        ], [\n            'int' => 1,\n            'string' => 'string',\n            'object' => $object,\n        ], true);\n    }\n\n    public function testArraySubsetWithStrictMayFail(): void\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        Assert::assertArraySubset([\n            'string' => 'string',\n            'object' => new stdClass(),\n        ], [\n            'int' => 1,\n            'string' => 'string',\n            'object' => new stdClass(),\n        ], true);\n    }\n\n    public function testArraySubsetMayFailIfArrayIsNotArray(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Argument #1 of Illuminate\\Testing\\Assert::assertArraySubset() must be an array or ArrayAccess'\n        );\n\n        Assert::assertArraySubset('string', [\n            'int' => 1,\n            'string' => 'string',\n            'object' => new stdClass(),\n        ]);\n    }\n\n    public function testArraySubsetMayFailIfSubsetIsNotArray(): void\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage(\n            'Argument #2 of Illuminate\\Testing\\Assert::assertArraySubset() must be an array or ArrayAccess'\n        );\n\n        Assert::assertArraySubset([\n            'string' => 'string',\n            'object' => new stdClass(),\n        ], 'string');\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Concerns/InteractsWithDatabaseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Concerns;\n\nuse Illuminate\\Database\\Connection;\nuse Illuminate\\Database\\Query\\Expression;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithDatabase;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass InteractsWithDatabaseTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        Facade::clearResolvedInstances();\n        Facade::setFacadeApplication(null);\n    }\n\n    public function testCastToJsonSqlite()\n    {\n        $grammar = 'SQLite';\n\n        $this->assertEquals(<<<'TEXT'\n        '[\"foo\",\"bar\"]'\n        TEXT,\n            $this->castAsJson(['foo', 'bar'], $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        '[\"foo\",\"bar\"]'\n        TEXT,\n            $this->castAsJson(collect(['foo', 'bar']), $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        '{\"foo\":\"bar\"}'\n        TEXT,\n            $this->castAsJson((object) ['foo' => 'bar'], $grammar)\n        );\n    }\n\n    public function testCastToJsonPostgres()\n    {\n        $grammar = 'Postgres';\n\n        $this->assertEquals(<<<'TEXT'\n        '[\"foo\",\"bar\"]'\n        TEXT,\n            $this->castAsJson(['foo', 'bar'], $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        '[\"foo\",\"bar\"]'\n        TEXT,\n            $this->castAsJson(collect(['foo', 'bar']), $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        '{\"foo\":\"bar\"}'\n        TEXT,\n            $this->castAsJson((object) ['foo' => 'bar'], $grammar)\n        );\n    }\n\n    public function testCastToJsonSqlServer()\n    {\n        $grammar = 'SqlServer';\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('[\"foo\",\"bar\"]')\n        TEXT,\n            $this->castAsJson(['foo', 'bar'], $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('[\"foo\",\"bar\"]')\n        TEXT,\n            $this->castAsJson(collect(['foo', 'bar']), $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('{\"foo\":\"bar\"}')\n        TEXT,\n            $this->castAsJson((object) ['foo' => 'bar'], $grammar)\n        );\n    }\n\n    public function testCastToJsonMySql()\n    {\n        $grammar = 'MySql';\n\n        $this->assertEquals(<<<'TEXT'\n        cast('[\"foo\",\"bar\"]' as json)\n        TEXT,\n            $this->castAsJson(['foo', 'bar'], $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        cast('[\"foo\",\"bar\"]' as json)\n        TEXT,\n            $this->castAsJson(collect(['foo', 'bar']), $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        cast('{\"foo\":\"bar\"}' as json)\n        TEXT,\n            $this->castAsJson((object) ['foo' => 'bar'], $grammar)\n        );\n    }\n\n    public function testCastToJsonMariaDb()\n    {\n        $grammar = 'MariaDb';\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('[\"foo\",\"bar\"]', '$')\n        TEXT,\n            $this->castAsJson(['foo', 'bar'], $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('[\"foo\",\"bar\"]', '$')\n        TEXT,\n            $this->castAsJson(collect(['foo', 'bar']), $grammar)\n        );\n\n        $this->assertEquals(<<<'TEXT'\n        json_query('{\"foo\":\"bar\"}', '$')\n        TEXT,\n            $this->castAsJson((object) ['foo' => 'bar'], $grammar)\n        );\n    }\n\n    protected function castAsJson($value, $grammar)\n    {\n        $connection = m::mock(Connection::class);\n        $grammarClass = 'Illuminate\\Database\\Query\\Grammars\\\\'.$grammar.'Grammar';\n        $grammar = new $grammarClass($connection);\n\n        $connection->shouldReceive('getQueryGrammar')->andReturn($grammar);\n\n        $connection->shouldReceive('raw')->andReturnUsing(function ($value) {\n            return new Expression($value);\n        });\n\n        $connection->shouldReceive('getPdo->quote')->andReturnUsing(function ($value) {\n            return \"'\".$value.\"'\";\n        });\n\n        DB::shouldReceive('connection')->with(null)->andReturn($connection);\n\n        $instance = new class\n        {\n            use InteractsWithDatabase;\n        };\n\n        return $instance->castAsJson($value)->getValue($grammar);\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Concerns/InteractsWithDeprecationHandlingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Concerns;\n\nuse ErrorException;\nuse Illuminate\\Foundation\\Bootstrap\\HandleExceptions;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithDeprecationHandling;\nuse PHPUnit\\Framework\\TestCase;\n\nclass InteractsWithDeprecationHandlingTest extends TestCase\n{\n    use InteractsWithDeprecationHandling;\n\n    protected $deprecationsFound = false;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        set_error_handler(function () {\n            $this->deprecationsFound = true;\n        });\n    }\n\n    protected function tearDown(): void\n    {\n        $this->deprecationsFound = false;\n\n        HandleExceptions::flushHandlersState($this);\n\n        parent::tearDown();\n    }\n\n    public function testWithDeprecationHandling()\n    {\n        $this->withDeprecationHandling();\n\n        trigger_error('Something is deprecated', E_USER_DEPRECATED);\n\n        $this->assertTrue($this->deprecationsFound);\n    }\n\n    public function testWithoutDeprecationHandling()\n    {\n        $this->withoutDeprecationHandling();\n\n        $this->expectException(ErrorException::class);\n        $this->expectExceptionMessage('Something is deprecated');\n\n        trigger_error('Something is deprecated', E_USER_DEPRECATED);\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Concerns/TestCachesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Concerns;\n\nuse Generator;\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\ParallelTesting as ParallelTestingFacade;\nuse Illuminate\\Testing\\Concerns\\TestCaches;\nuse Illuminate\\Testing\\ParallelTesting;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\nuse ReflectionProperty;\n\nclass TestCachesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Container::setInstance($container = new Container);\n\n        Facade::setFacadeApplication($container);\n\n        $container->singleton('config', fn () => new Config([\n            'cache' => [\n                'prefix' => 'myapp_cache_',\n            ],\n        ]));\n\n        $container->singleton(ParallelTesting::class, fn ($app) => new ParallelTesting($app));\n\n        $_SERVER['LARAVEL_PARALLEL_TESTING'] = 1;\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n        ParallelTestingFacade::clearResolvedInstance();\n        Facade::setFacadeApplication(null);\n\n        unset($_SERVER['LARAVEL_PARALLEL_TESTING']);\n\n        // Reset static property between tests\n        $instance = new class\n        {\n            use TestCaches;\n\n            public $app;\n\n            public function __construct()\n            {\n                $this->app = Container::getInstance() ?? new Container;\n            }\n        };\n\n        (new ReflectionProperty($instance::class, 'originalCachePrefix'))->setValue(null, null);\n\n        parent::tearDown();\n    }\n\n    #[DataProvider('cachePrefixes')]\n    public function testCachePrefixAppendsToken(string $prefix, string $token, string $expected)\n    {\n        Container::getInstance()['config']->set('cache.prefix', $prefix);\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => $token);\n\n        $this->assertSame($expected, $this->getParallelSafeCachePrefix());\n    }\n\n    public static function cachePrefixes(): Generator\n    {\n        yield 'with prefix' => ['myapp_cache_', '5', 'myapp_cache_test_5_'];\n        yield 'empty prefix' => ['', '3', 'test_3_'];\n    }\n\n    public function testCachePrefixPreservesOriginalPrefix()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '1');\n\n        $this->getParallelSafeCachePrefix();\n\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '2');\n\n        $this->assertSame('myapp_cache_test_2_', $this->getParallelSafeCachePrefix());\n    }\n\n    public function testSwitchToCachePrefixUpdatesConfig()\n    {\n        $this->switchToCachePrefix('new_prefix_');\n\n        $this->assertSame('new_prefix_', Container::getInstance()['config']->get('cache.prefix'));\n    }\n\n    public function testBootTestCacheRegistersSetUpTestCaseCallback()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '7');\n\n        $instance = $this->makeTestCachesInstance();\n\n        (new ReflectionProperty($instance::class, 'originalCachePrefix'))->setValue(null, null);\n\n        $method = new ReflectionMethod($instance, 'bootTestCache');\n        $method->invoke($instance);\n\n        $parallelTesting = Container::getInstance()->make(ParallelTesting::class);\n        $setUpCallbacks = (new ReflectionProperty($parallelTesting, 'setUpTestCaseCallbacks'))->getValue($parallelTesting);\n\n        $this->assertCount(1, $setUpCallbacks);\n    }\n\n    public function testBootTestCacheSkipsIsolationIfOptedOut()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '7');\n\n        $instance = $this->makeTestCachesInstance();\n\n        (new ReflectionProperty($instance::class, 'originalCachePrefix'))->setValue(null, null);\n        (new ReflectionMethod($instance, 'bootTestCache'))->invoke($instance);\n\n        $_SERVER['LARAVEL_PARALLEL_TESTING_WITHOUT_CACHE'] = 1;\n\n        Container::getInstance()->make(ParallelTesting::class)->callSetUpTestCaseCallbacks(new class { });\n\n        $this->assertSame('myapp_cache_', Container::getInstance()['config']->get('cache.prefix'));\n\n        unset($_SERVER['LARAVEL_PARALLEL_TESTING_WITHOUT_CACHE']);\n    }\n\n    public function testSwitchToCachePrefixDoesNotRemoveResolvedDrivers()\n    {\n        $container = Container::getInstance();\n\n        $container->singleton('cache', fn ($app) => new \\Illuminate\\Cache\\CacheManager($app));\n\n        $container['config']->set('cache.default', 'array');\n        $container['config']->set('cache.stores.array', ['driver' => 'array']);\n\n        $driver = $container['cache']->driver();\n\n        $this->switchToCachePrefix('new_prefix_');\n\n        $this->assertSame($driver, $container['cache']->driver());\n    }\n\n    protected function getParallelSafeCachePrefix()\n    {\n        $instance = $this->makeTestCachesInstance();\n\n        (new ReflectionProperty($instance::class, 'originalCachePrefix'))->setValue(null, null);\n\n        $method = new ReflectionMethod($instance, 'parallelSafeCachePrefix');\n\n        return $method->invoke($instance);\n    }\n\n    protected function switchToCachePrefix($prefix)\n    {\n        $instance = $this->makeTestCachesInstance();\n\n        $method = new ReflectionMethod($instance, 'switchToCachePrefix');\n        $method->invoke($instance, $prefix);\n    }\n\n    protected function makeTestCachesInstance()\n    {\n        return new class\n        {\n            use TestCaches;\n\n            public $app;\n\n            public function __construct()\n            {\n                $this->app = Container::getInstance();\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Concerns/TestDatabasesTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Concerns;\n\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Testing\\Concerns\\TestDatabases;\nuse Mockery as m;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\n\nclass TestDatabasesTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Container::setInstance($container = new Container);\n\n        $container->singleton('config', function () {\n            return m::mock(Config::class)\n                ->shouldReceive('get')\n                ->once()\n                ->with('database.default', null)\n                ->andReturn('mysql')\n                ->getMock();\n        });\n\n        $_SERVER['LARAVEL_PARALLEL_TESTING'] = 1;\n    }\n\n    public function testSwitchToDatabaseWithoutUrl()\n    {\n        DB::shouldReceive('purge')->once();\n\n        config()->shouldReceive('get')\n            ->once()\n            ->with('database.connections.mysql.url', false)\n            ->andReturn(false);\n\n        config()->shouldReceive('set')\n            ->once()\n            ->with('database.connections.mysql.database', 'my_database_test_1');\n\n        $this->switchToDatabase('my_database_test_1');\n    }\n\n    #[DataProvider('databaseUrls')]\n    public function testSwitchToDatabaseWithUrl($testDatabase, $url, $testUrl)\n    {\n        DB::shouldReceive('purge')->once();\n\n        config()->shouldReceive('get')\n            ->once()\n            ->with('database.connections.mysql.url', false)\n            ->andReturn($url);\n\n        config()->shouldReceive('set')\n            ->once()\n            ->with('database.connections.mysql.url', $testUrl);\n\n        $this->switchToDatabase($testDatabase);\n    }\n\n    public function switchToDatabase($database)\n    {\n        $instance = new class\n        {\n            use TestDatabases;\n        };\n\n        $method = new ReflectionMethod($instance, 'switchToDatabase');\n        $method->invoke($instance, $database);\n    }\n\n    public static function databaseUrls()\n    {\n        return [\n            [\n                'my_database_test_1',\n                'mysql://root:@127.0.0.1/my_database?charset=utf8mb4',\n                'mysql://root:@127.0.0.1/my_database_test_1?charset=utf8mb4',\n            ],\n            [\n                'my_database_test_1',\n                'mysql://my-user:@localhost/my_database',\n                'mysql://my-user:@localhost/my_database_test_1',\n            ],\n            [\n                'my-database_test_1',\n                'postgresql://my_database_user:@127.0.0.1/my-database?charset=utf8',\n                'postgresql://my_database_user:@127.0.0.1/my-database_test_1?charset=utf8',\n            ],\n        ];\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n        DB::clearResolvedInstance();\n        DB::setFacadeApplication(null);\n\n        unset($_SERVER['LARAVEL_PARALLEL_TESTING']);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Concerns/TestViewsTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Concerns;\n\nuse Illuminate\\Config\\Repository as Config;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Support\\Facades\\Facade;\nuse Illuminate\\Support\\Facades\\ParallelTesting as ParallelTestingFacade;\nuse Illuminate\\Testing\\Concerns\\TestViews;\nuse Illuminate\\Testing\\ParallelTesting;\nuse Illuminate\\View\\Compilers\\BladeCompiler;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\nuse ReflectionMethod;\nuse ReflectionProperty;\n\nclass TestViewsTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Container::setInstance($container = new Container);\n\n        Facade::setFacadeApplication($container);\n\n        $container->singleton('config', fn () => new Config([\n            'view' => [\n                'compiled' => '/path/to/compiled/views',\n            ],\n        ]));\n\n        $container->singleton(ParallelTesting::class, fn ($app) => new ParallelTesting($app));\n\n        $_SERVER['LARAVEL_PARALLEL_TESTING'] = 1;\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n        ParallelTestingFacade::clearResolvedInstance();\n        Facade::setFacadeApplication(null);\n\n        unset($_SERVER['LARAVEL_PARALLEL_TESTING']);\n\n        parent::tearDown();\n    }\n\n    public function testCompiledViewPathAppendsToken()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '5');\n\n        $this->assertSame('/path/to/compiled/views/test_5', $this->testCompiledViewPath());\n    }\n\n    public function testCompiledViewPathTrimsTrailingSlash()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '3');\n\n        Container::getInstance()['config']->set('view.compiled', '/path/to/compiled/views/');\n\n        $this->assertSame('/path/to/compiled/views/test_3', $this->testCompiledViewPath());\n    }\n\n    public function testCompiledViewPathWithDifferentToken()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '42');\n\n        Container::getInstance()['config']->set('view.compiled', '/var/www/storage/views');\n\n        $this->assertSame('/var/www/storage/views/test_42', $this->testCompiledViewPath());\n    }\n\n    public function testCompiledViewPathReturnsNullWhenEmpty()\n    {\n        Container::getInstance()['config']->set('view.compiled', '');\n\n        $this->assertNull($this->testCompiledViewPath());\n    }\n\n    public function testSwitchToCompiledViewPathUpdatesConfig()\n    {\n        $this->switchToCompiledViewPath('/new/compiled/path');\n\n        $this->assertSame('/new/compiled/path', Container::getInstance()['config']->get('view.compiled'));\n    }\n\n    public function testSwitchToCompiledViewPathUpdatesCompilerCachePath()\n    {\n        $container = Container::getInstance();\n        $compiler = new BladeCompiler(m::mock(Filesystem::class), '/original/path');\n\n        $container->instance('blade.compiler', $compiler);\n\n        $this->switchToCompiledViewPath('/new/compiled/path');\n\n        $this->assertSame('/new/compiled/path', $container['config']->get('view.compiled'));\n        $this->assertSame('/new/compiled/path', (new ReflectionProperty($compiler, 'cachePath'))->getValue($compiler));\n    }\n\n    public function testCompiledViewPath()\n    {\n        $instance = new class\n        {\n            use TestViews;\n\n            public $app;\n\n            public function __construct()\n            {\n                $this->app = Container::getInstance();\n            }\n        };\n\n        (new ReflectionProperty($instance::class, 'originalCompiledViewPath'))->setValue(null, null);\n\n        $method = new ReflectionMethod($instance, 'parallelSafeCompiledViewPath');\n\n        return $method->invoke($instance);\n    }\n\n    public function testTearDownProcessDeletesCompiledViewDirectory()\n    {\n        Container::getInstance()->make(ParallelTesting::class)->resolveTokenUsing(fn () => '7');\n\n        $instance = new class\n        {\n            use TestViews;\n\n            public $app;\n\n            public function __construct()\n            {\n                $this->app = Container::getInstance();\n            }\n        };\n\n        (new ReflectionProperty($instance::class, 'originalCompiledViewPath'))->setValue(null, null);\n\n        $method = new ReflectionMethod($instance, 'bootTestViews');\n        $method->invoke($instance);\n\n        $parallelTesting = Container::getInstance()->make(ParallelTesting::class);\n        $tearDownCallbacks = (new ReflectionProperty($parallelTesting, 'tearDownProcessCallbacks'))->getValue($parallelTesting);\n\n        $this->assertCount(1, $tearDownCallbacks);\n    }\n\n    public function switchToCompiledViewPath($path)\n    {\n        $instance = new class\n        {\n            use TestViews;\n\n            public $app;\n\n            public function __construct()\n            {\n                $this->app = Container::getInstance();\n            }\n        };\n\n        $method = new ReflectionMethod($instance, 'switchToCompiledViewPath');\n        $method->invoke($instance, $path);\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Console/ConfigShowCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Console;\n\nuse Illuminate\\Foundation\\Console\\ConfigShowCommand;\nuse Orchestra\\Testbench\\TestCase;\n\nclass ConfigShowCommandTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        putenv('COLUMNS=64');\n    }\n\n    public function testDisplayConfig()\n    {\n        config()->set('test', [\n            'string' => 'Test',\n            'int' => 1,\n            'float' => 1.2,\n            'boolean' => true,\n            'null' => null,\n            'array' => [\n                ConfigShowCommand::class,\n            ],\n            'empty_array' => [],\n            'assoc_array' => ['foo' => 'bar'],\n            'class' => new \\stdClass,\n        ]);\n\n        $this->artisan(ConfigShowCommand::class, ['config' => 'test'])\n            ->assertSuccessful()\n            ->expectsOutput('  test .......................................................  ')\n            ->expectsOutput('  string ................................................ Test  ')\n            ->expectsOutput('  int ...................................................... 1  ')\n            ->expectsOutput('  float .................................................. 1.2  ')\n            ->expectsOutput('  boolean ............................................... true  ')\n            ->expectsOutput('  null .................................................. null  ')\n            ->expectsOutput('  array ⇁ 0 .. Illuminate\\Foundation\\Console\\ConfigShowCommand  ')\n            ->expectsOutput('  empty_array ............................................. []  ')\n            ->expectsOutput('  assoc_array ⇁ foo ...................................... bar  ')\n            ->expectsOutput('  class ............................................. stdClass  ');\n    }\n\n    public function testDisplayNestedConfigItems()\n    {\n        config()->set('test', [\n            'nested' => [\n                'foo' => 'bar',\n            ],\n        ]);\n\n        $this->artisan(ConfigShowCommand::class, ['config' => 'test.nested'])\n            ->assertSuccessful()\n            ->expectsOutput('  test.nested ................................................  ')\n            ->expectsOutput('  foo .................................................... bar  ');\n    }\n\n    public function testDisplaySingleValue()\n    {\n        config()->set('foo', 'bar');\n\n        $this->artisan(ConfigShowCommand::class, ['config' => 'foo'])\n            ->assertSuccessful()\n            ->expectsOutput('  foo .................................................... bar  ');\n    }\n\n    public function testDisplayErrorIfConfigDoesNotExist()\n    {\n        $this->artisan(ConfigShowCommand::class, ['config' => 'invalid'])\n            ->assertFailed();\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Console/RouteListCommandTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Console;\n\nuse Illuminate\\Contracts\\Routing\\Registrar;\nuse Illuminate\\Foundation\\Auth\\User;\nuse Illuminate\\Foundation\\Console\\RouteListCommand;\nuse Illuminate\\Foundation\\Testing\\Concerns\\InteractsWithDeprecationHandling;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Routing\\Controller;\nuse Illuminate\\Support\\Facades\\Artisan;\nuse Orchestra\\Testbench\\Attributes\\WithConfig;\nuse Orchestra\\Testbench\\TestCase;\n\n#[WithConfig('filesystems.disks.local.serve', false)]\nclass RouteListCommandTest extends TestCase\n{\n    use InteractsWithDeprecationHandling;\n\n    /**\n     * @var \\Illuminate\\Contracts\\Routing\\Registrar\n     */\n    private $router;\n\n    /**\n     * @var \\Illuminate\\Routing\\UrlGenerator\n     */\n    private $urlGenerator;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this->router = $this->app->make(Registrar::class);\n\n        RouteListCommand::resolveTerminalWidthUsing(function () {\n            return 70;\n        });\n    }\n\n    public function testDisplayRoutesForCli()\n    {\n        $this->withoutMockingConsoleOutput();\n\n        RouteListCommand::resolveTerminalWidthUsing(fn () => 200);\n\n        $closureLine = __LINE__ + 1;\n        $this->router->get('/', function () {\n            //\n        });\n\n        $this->router->get('closure', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route'));\n        });\n\n        $this->router->get('controller-method/{user}', [FooController::class, 'show']);\n        $this->router->post('controller-invokable', FooController::class);\n        $this->router->domain('{account}.example.com')->group(function () {\n            $this->router->get('/', function () {\n                //\n            });\n\n            $this->router->get('user/{id}', function ($account, $id) {\n                //\n            })->name('user.show')->middleware('web');\n        });\n\n        $this->artisan(RouteListCommand::class);\n        $output = Artisan::output();\n\n        $this->assertStringContainsString('GET|HEAD', $output);\n        $this->assertStringContainsString('closure', $output);\n        $this->assertStringContainsString('controller-invokable', $output);\n        $this->assertStringContainsString('controller-method/{user}', $output);\n        $this->assertStringContainsString('RouteListCommandTest.php:'.$closureLine, $output);\n        $this->assertStringContainsString('Showing [6] routes', $output);\n    }\n\n    public function testDisplayRoutesForCliInVerboseMode()\n    {\n        $this->withoutMockingConsoleOutput();\n\n        RouteListCommand::resolveTerminalWidthUsing(fn () => 200);\n\n        $closureLine = __LINE__ + 1;\n        $this->router->get('closure', function () {\n            return new RedirectResponse($this->urlGenerator->signedRoute('signed-route'));\n        });\n\n        $this->router->get('controller-method/{user}', [FooController::class, 'show']);\n        $this->router->post('controller-invokable', FooController::class);\n        $this->router->domain('{account}.example.com')->group(function () {\n            $this->router->get('user/{id}', function ($account, $id) {\n                //\n            })->name('user.show')->middleware('web');\n        });\n\n        $this->artisan(RouteListCommand::class, ['-v' => true]);\n        $output = Artisan::output();\n\n        $this->assertStringContainsString('closure', $output);\n        $this->assertStringContainsString('RouteListCommandTest.php:'.$closureLine, $output);\n        $this->assertStringContainsString('controller-invokable', $output);\n        $this->assertStringContainsString('FooController@show', $output);\n        $this->assertStringContainsString('user.show', $output);\n        $this->assertStringContainsString('web', $output);\n        $this->assertStringContainsString('Showing [4] routes', $output);\n    }\n\n    public function testRouteCanBeFilteredByName()\n    {\n        $this->withoutDeprecationHandling();\n        $this->withoutMockingConsoleOutput();\n\n        RouteListCommand::resolveTerminalWidthUsing(fn () => 200);\n\n        $this->router->get('/', function () {\n            //\n        });\n        $closureLine = __LINE__ + 1;\n        $this->router->get('/foo', function () {\n            //\n        })->name('foo.show');\n\n        $this->artisan(RouteListCommand::class, ['--name' => 'foo']);\n        $output = Artisan::output();\n\n        $this->assertStringContainsString('foo', $output);\n        $this->assertStringContainsString('foo.show', $output);\n        $this->assertStringContainsString('RouteListCommandTest.php:'.$closureLine, $output);\n        $this->assertStringContainsString('Showing [1] routes', $output);\n    }\n\n    public function testRouteCanBeFilteredByAction()\n    {\n        $this->withoutDeprecationHandling();\n\n        RouteListCommand::resolveTerminalWidthUsing(function () {\n            return 82;\n        });\n\n        $this->router->get('/', function () {\n            //\n        });\n        $this->router->get('foo/{user}', [FooController::class, 'show']);\n\n        $this->artisan(RouteListCommand::class, ['--action' => 'FooController'])\n            ->assertSuccessful()\n            ->expectsOutput('')\n            ->expectsOutput(\n                '  GET|HEAD       foo/{user} Illuminate\\Tests\\Testing\\Console\\FooController@show'\n            )->expectsOutput('')\n            ->expectsOutput(\n                '                                                              Showing [1] routes'\n            )\n            ->expectsOutput('');\n    }\n\n    public function testClosurePathIsDisplayedInVerboseMode()\n    {\n        $closureLine = __LINE__ + 1;\n        $this->router->get('closure-path', function () {\n            //\n        });\n\n        $this->router->get('controller-method/{user}', [FooController::class, 'show']);\n\n        $expectedPath = 'tests/Testing/Console/RouteListCommandTest.php:'.$closureLine;\n\n        $this->artisan(RouteListCommand::class, ['-v' => true])\n            ->assertSuccessful()\n            ->expectsOutputToContain($expectedPath);\n    }\n\n    public function testClosurePathIsDisplayedInNonVerboseMode()\n    {\n        RouteListCommand::resolveTerminalWidthUsing(fn () => 200);\n\n        $closureLine = __LINE__ + 1;\n        $this->router->get('closure-path', function () {\n            //\n        });\n\n        $expectedPath = 'tests/Testing/Console/RouteListCommandTest.php:'.$closureLine;\n\n        $this->artisan(RouteListCommand::class)\n            ->assertSuccessful()\n            ->expectsOutputToContain($expectedPath);\n    }\n\n    public function testClosurePathIsIncludedInJsonOutput()\n    {\n        $closureLine = __LINE__ + 1;\n        $this->router->get('closure-path', function () {\n            //\n        });\n\n        $this->router->get('controller-method/{user}', [FooController::class, 'show']);\n\n        $expectedPath = 'tests/Testing/Console/RouteListCommandTest.php:'.$closureLine;\n        $jsonPath = str_replace('/', '\\\\/', $expectedPath);\n\n        $this->artisan(RouteListCommand::class, ['--json' => true])\n            ->assertSuccessful()\n            ->expectsOutputToContain($jsonPath);\n    }\n\n    public function testControllerRouteHasNullPathInJsonOutput()\n    {\n        $this->router->get('controller-method/{user}', [FooController::class, 'show']);\n\n        $this->artisan(RouteListCommand::class, ['--json' => true])\n            ->assertSuccessful()\n            ->expectsOutputToContain('\"path\":null');\n    }\n\n    public function testDisplayRoutesExceptVendor()\n    {\n        $this->router->get('foo/{user}', [FooController::class, 'show']);\n        $this->router->view('view', 'blade.path');\n        $this->router->redirect('redirect', 'destination');\n\n        $this->artisan(RouteListCommand::class, ['-v' => true, '--except-vendor' => true])\n            ->assertSuccessful()\n            ->expectsOutput('')\n            ->expectsOutput('  GET|HEAD       foo/{user} Illuminate\\Tests\\Testing\\Console\\FooController@show')\n            ->expectsOutput('  ANY            redirect .... Illuminate\\Routing\\RedirectController')\n            ->expectsOutput('  GET|HEAD       view .............................................. ')\n            ->expectsOutput('')\n            ->expectsOutput('                                                  Showing [3] routes')\n            ->expectsOutput('');\n    }\n\n    // public function testDisplayRoutesWithBindingFields()\n    // {\n    //     $this->router->get('users/{user:name}', [FooController::class, 'show']);\n    //     $this->router->get('users/{user:name}/posts/{post:slug}', function () {\n    //         //\n    //     });\n\n    //     $this->artisan(RouteListCommand::class, ['-v' => true])\n    //         ->assertSuccessful()\n    //         ->expectsOutput('')\n    //         ->expectsOutput('  GET|HEAD       users/{user:name} Illuminate\\Tests\\Testing\\Console\\FooController@show')\n    //         ->expectsOutput('  GET|HEAD       users/{user:name}/posts/{post:slug} ............... ')\n    //         ->expectsOutput('')\n    //         ->expectsOutput('                                                  Showing [2] routes')\n    //         ->expectsOutput('');\n    // }\n\n    public function testDisplayRoutesWithBindingFieldsAsJson()\n    {\n        $this->router->get('users/{user:name}/posts/{post:slug}', function () {\n            //\n        });\n\n        $this->artisan(RouteListCommand::class, ['--json' => true])\n            ->assertSuccessful()\n            ->expectsOutputToContain('users\\/{user:name}\\/posts\\/{post:slug}');\n    }\n}\n\nclass FooController extends Controller\n{\n    public function show(User $user)\n    {\n        // ..\n    }\n\n    public function __invoke()\n    {\n        // ..\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Fixtures/file.json",
    "content": "{\"foo\":\"bar\"}"
  },
  {
    "path": "tests/Testing/Fluent/AssertTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Fluent;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Testing\\Fluent\\AssertableJson;\nuse Illuminate\\Tests\\Testing\\Stubs\\ArrayableStubObject;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\TestCase;\nuse RuntimeException;\nuse TypeError;\n\nclass AssertTest extends TestCase\n{\n    public function testAssertHas()\n    {\n        $assert = AssertableJson::fromArray([\n            'prop' => 'value',\n        ]);\n\n        $assert->has('prop');\n    }\n\n    public function testAssertHasFailsWhenPropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [prop] does not exist.');\n\n        $assert->has('prop');\n    }\n\n    public function testAssertHasNestedProp()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => 'nested-value',\n            ],\n        ]);\n\n        $assert->has('example.nested');\n    }\n\n    public function testAssertHasFailsWhenNestedPropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => 'nested-value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [example.another] does not exist.');\n\n        $assert->has('example.another');\n    }\n\n    public function testAssertHasCountItemsInProp()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $assert->has('bar', 2);\n    }\n\n    public function testAssertHasCountFailsWhenAmountOfItemsDoesNotMatch()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not have the expected size.');\n\n        $assert->has('bar', 1);\n    }\n\n    public function testAssertHasCountFailsWhenPropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->has('baz', 1);\n    }\n\n    public function testAssertHasFailsWhenSecondArgumentUnsupportedType()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'baz',\n        ]);\n\n        $this->expectException(TypeError::class);\n\n        $assert->has('bar', 'invalid');\n    }\n\n    public function testAssertHasOnlyCounts()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $assert->has(3);\n    }\n\n    public function testAssertHasOnlyCountFails()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Root level does not have the expected size.');\n\n        $assert->has(2);\n    }\n\n    public function testAssertHasOnlyCountFailsScoped()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not have the expected size.');\n\n        $assert->has('bar', function ($bar) {\n            $bar->has(3);\n        });\n    }\n\n    public function testAssertHasWithWhereNotDoesNotFail()\n    {\n        $assert = AssertableJson::fromArray([\n            'data' => [\n                [\n                    'id' => 1,\n                    'name' => 'Taylor',\n                ],\n                [\n                    'id' => 2,\n                    'name' => 'Nuno',\n                ],\n            ],\n        ]);\n\n        $assert->has('data', function ($bar) {\n            $bar->has(2)\n                ->each(fn ($json) => $json->whereNot('id', 3)->etc());\n        });\n    }\n\n    public function testAssertHasWithWhereNotFails()\n    {\n        $assert = AssertableJson::fromArray([\n            'data' => [\n                [\n                    'id' => 1,\n                    'name' => 'Taylor',\n                ],\n                [\n                    'id' => 2,\n                    'name' => 'Mateus',\n                ],\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [data.1.id] contains a value that should be missing: [id, 2]');\n\n        $assert->has('data', function ($bar) {\n            $bar->has(2)\n                ->each(fn ($json) => $json->whereNot('id', 2)->etc());\n        });\n    }\n\n    public function testAssertHasWithWhereNotDoesNotFailClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'data' => [\n                [\n                    'id' => 1,\n                    'name' => 'Taylor',\n                ],\n                [\n                    'id' => 2,\n                    'name' => 'Mateus',\n                ],\n            ],\n        ]);\n\n        $assert->has('data', function ($bar) {\n            $bar->has(2)\n                ->each(fn ($json) => $json->whereNot('id', fn ($value) => $value === 3)->etc());\n        });\n    }\n\n    public function testAssertHasWithWhereNotFailsClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'data' => [\n                [\n                    'id' => 1,\n                    'name' => 'Taylor',\n                ],\n                [\n                    'id' => 2,\n                    'name' => 'Mateus',\n                ],\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [data.1.id] was marked as invalid using a closure.');\n\n        $assert->has('data', function ($bar) {\n            $bar->has(2)\n                ->each(fn ($json) => $json->whereNot('id', fn ($value) => $value === 2)->etc());\n        });\n    }\n\n    public function testAssertCount()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $assert->count(3);\n    }\n\n    public function testAssertCountFails()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Root level does not have the expected size.');\n\n        $assert->count(2);\n    }\n\n    public function testAssertCountFailsScoped()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not have the expected size.');\n\n        $assert->has('bar', function ($bar) {\n            $bar->count(3);\n        });\n    }\n\n    public function testAssertBetween()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $assert->countBetween(1, 3);\n    }\n\n    public function testAssertBetweenFails()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Root level size is not less than or equal to [2].');\n\n        $assert->countBetween(1, 2);\n    }\n\n    public function testAssertBetweenLowestValueFails()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo',\n            'bar',\n            'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Root level size is not greater than or equal to [4].');\n\n        $assert->countBetween(4, 3);\n    }\n\n    public function testAssertBetweenFailsScoped()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n                'foo' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] size is not less than or equal to [2].');\n\n        $assert->has('bar', function (AssertableJson $bar) {\n            $bar->countBetween(1, 2);\n        });\n    }\n\n    public function testAssertMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'bar' => true,\n            ],\n        ]);\n\n        $assert->missing('foo.baz');\n    }\n\n    public function testAssertMissingFailsWhenPropExists()\n    {\n        $assert = AssertableJson::fromArray([\n            'prop' => 'value',\n            'foo' => [\n                'bar' => true,\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo.bar] was found while it was expected to be missing.');\n\n        $assert->missing('foo.bar');\n    }\n\n    public function testAssertMissingAll()\n    {\n        $assert = AssertableJson::fromArray([\n            'baz' => 'foo',\n        ]);\n\n        $assert->missingAll([\n            'foo',\n            'bar',\n        ]);\n    }\n\n    public function testAssertMissingAllFailsWhenAtLeastOnePropExists()\n    {\n        $assert = AssertableJson::fromArray([\n            'baz' => 'foo',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] was found while it was expected to be missing.');\n\n        $assert->missingAll([\n            'bar',\n            'baz',\n        ]);\n    }\n\n    public function testAssertMissingAllAcceptsMultipleArgumentsInsteadOfArray()\n    {\n        $assert = AssertableJson::fromArray([\n            'baz' => 'foo',\n        ]);\n\n        $assert->missingAll('foo', 'bar');\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] was found while it was expected to be missing.');\n\n        $assert->missingAll('bar', 'baz');\n    }\n\n    public function testAssertWhereMatchesValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $assert->where('bar', 'value');\n    }\n\n    public function testAssertWhereFailsWhenDoesNotMatchValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not match the expected value.');\n\n        $assert->where('bar', 'invalid');\n    }\n\n    public function testAssertWhereFailsWhenMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->where('baz', 'invalid');\n    }\n\n    public function testAssertWhereFailsWhenMatchingLoosely()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 1,\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not match the expected value.');\n\n        $assert->where('bar', true);\n    }\n\n    public function testAssertWhereUsingClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'baz',\n        ]);\n\n        $assert->where('bar', function ($value) {\n            return $value === 'baz';\n        });\n    }\n\n    public function testAssertWhereFailsWhenDoesNotMatchValueUsingClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] was marked as invalid using a closure.');\n\n        $assert->where('bar', function ($value) {\n            return $value === 'invalid';\n        });\n    }\n\n    public function testAssertWhereClosureArrayValuesAreAutomaticallyCastedToCollections()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'foo',\n                'example' => 'value',\n            ],\n        ]);\n\n        $assert->where('bar', function ($value) {\n            $this->assertInstanceOf(Collection::class, $value);\n\n            return $value->count() === 2;\n        });\n    }\n\n    public function testAssertWhereMatchesValueUsingArrayable()\n    {\n        $stub = ArrayableStubObject::make(['foo' => 'bar']);\n\n        $assert = AssertableJson::fromArray([\n            'bar' => $stub->toArray(),\n        ]);\n\n        $assert->where('bar', $stub);\n    }\n\n    public function testAssertWhereMatchesValueUsingArrayableWhenSortedDifferently()\n    {\n        $assert = AssertableJson::fromArray([\n            'data' => [\n                'status' => 200,\n                'user' => [\n                    'id' => 1,\n                    'name' => 'Taylor',\n                ],\n            ],\n        ]);\n\n        $assert->where('data', [\n            'user' => [\n                'name' => 'Taylor',\n                'id' => 1,\n            ],\n            'status' => 200,\n        ]);\n    }\n\n    public function testAssertWhereFailsWhenDoesNotMatchValueUsingArrayable()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => ['id' => 1, 'name' => 'Example'],\n            'baz' => [\n                'id' => 1,\n                'name' => 'Taylor Otwell',\n                'email' => 'taylor@laravel.com',\n                'email_verified_at' => '2021-01-22T10:34:42.000000Z',\n                'created_at' => '2021-01-22T10:34:42.000000Z',\n                'updated_at' => '2021-01-22T10:34:42.000000Z',\n            ],\n        ]);\n\n        $assert\n            ->where('bar', ArrayableStubObject::make(['name' => 'Example', 'id' => 1]))\n            ->where('baz', [\n                'name' => 'Taylor Otwell',\n                'email' => 'taylor@laravel.com',\n                'id' => 1,\n                'email_verified_at' => '2021-01-22T10:34:42.000000Z',\n                'updated_at' => '2021-01-22T10:34:42.000000Z',\n                'created_at' => '2021-01-22T10:34:42.000000Z',\n            ]);\n    }\n\n    public function testAssertWhereUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => BackedEnum::test->value,\n        ]);\n\n        $assert->where('bar', BackedEnum::test);\n\n        $assert = AssertableJson::fromArray([\n            'bar' => BackedEnum::test_empty->value,\n        ]);\n\n        $assert->where('bar', BackedEnum::test_empty);\n    }\n\n    public function testAssertWhereFailsUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => BackedEnum::test->value,\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not match the expected value.');\n\n        $assert->where('bar', BackedEnum::test_empty);\n    }\n\n    public function testAssertWhereNullMatchesValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => null,\n        ]);\n\n        $assert->whereNull('bar');\n    }\n\n    public function testAssertWhereNullFailsWhenNotNull()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] should be null.');\n\n        $assert->whereNull('bar');\n    }\n\n    public function testAssertWhereNullFailsWhenMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->whereNull('baz');\n    }\n\n    public function testAssertWhereNotNullMatchesValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $assert->whereNotNull('bar');\n    }\n\n    public function testAssertWhereNotNullFailsWhenNull()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => null,\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] should not be null.');\n\n        $assert->whereNotNull('bar');\n    }\n\n    public function testAssertWhereNotNullFailsWhenMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->whereNotNull('baz');\n    }\n\n    public function testAssertWhereContainsFailsWithEmptyValue()\n    {\n        $assert = AssertableJson::fromArray([]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain [1].');\n\n        $assert->whereContains('foo', ['1']);\n    }\n\n    public function testAssertWhereContainsFailsWithMissingValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => ['bar', 'baz'],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain [invalid].');\n\n        $assert->whereContains('foo', ['bar', 'baz', 'invalid']);\n    }\n\n    public function testAssertWhereContainsFailsWithMissingNestedValue()\n    {\n        $assert = AssertableJson::fromArray([\n            ['id' => 1],\n            ['id' => 2],\n            ['id' => 3],\n            ['id' => 4],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [id] does not contain [5].');\n\n        $assert->whereContains('id', [1, 2, 3, 4, 5]);\n    }\n\n    public function testAssertWhereContainsFailsWhenDoesNotMatchType()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain [1].');\n\n        $assert->whereContains('foo', ['1']);\n    }\n\n    public function testAssertWhereContainsFailsWhenDoesNotSatisfyClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain a value that passes the truth test within the given closure.');\n\n        $assert->whereContains('foo', [function ($actual) {\n            return $actual === 5;\n        }]);\n    }\n\n    public function testAssertWhereContainsFailsWhenHavingExpectedValueButDoesNotSatisfyClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain a value that passes the truth test within the given closure.');\n\n        $assert->whereContains('foo', [1, function ($actual) {\n            return $actual === 5;\n        }]);\n    }\n\n    public function testAssertWhereContainsFailsWhenSatisfiesClosureButDoesNotHaveExpectedValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] does not contain [5].');\n\n        $assert->whereContains('foo', [5, function ($actual) {\n            return $actual === 1;\n        }]);\n    }\n\n    public function testAssertWhereContainsWithNestedValue()\n    {\n        $assert = AssertableJson::fromArray([\n            ['id' => 1],\n            ['id' => 2],\n            ['id' => 3],\n            ['id' => 4],\n        ]);\n\n        $assert->whereContains('id', 1);\n        $assert->whereContains('id', [1, 2, 3, 4]);\n        $assert->whereContains('id', [4, 3, 2, 1]);\n    }\n\n    public function testAssertWhereContainsWithMatchingType()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $assert->whereContains('foo', 1);\n        $assert->whereContains('foo', [1]);\n    }\n\n    public function testAssertWhereContainsWithNullValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => null,\n        ]);\n\n        $assert->whereContains('foo', null);\n        $assert->whereContains('foo', [null]);\n    }\n\n    public function testAssertWhereContainsWithOutOfOrderMatchingType()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [4, 1, 7, 3],\n        ]);\n\n        $assert->whereContains('foo', [1, 7, 4, 3]);\n    }\n\n    public function testAssertWhereContainsWithOutOfOrderNestedMatchingType()\n    {\n        $assert = AssertableJson::fromArray([\n            ['bar' => 5],\n            ['baz' => 4],\n            ['zal' => 8],\n        ]);\n\n        $assert->whereContains('baz', 4);\n    }\n\n    public function testAssertWhereContainsWithClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $assert->whereContains('foo', function ($actual) {\n            return $actual % 3 === 0;\n        });\n    }\n\n    public function testAssertWhereContainsWithNestedClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 1,\n            'bar' => 2,\n            'baz' => 3,\n        ]);\n\n        $assert->whereContains('baz', function ($actual) {\n            return $actual % 3 === 0;\n        });\n    }\n\n    public function testAssertWhereContainsWithMultipleClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [1, 2, 3, 4],\n        ]);\n\n        $assert->whereContains('foo', [\n            function ($actual) {\n                return $actual % 3 === 0;\n            },\n            function ($actual) {\n                return $actual % 2 === 0;\n            },\n        ]);\n    }\n\n    public function testAssertWhereContainsWithNullExpectation()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 1,\n        ]);\n\n        $assert->whereContains('foo', null);\n    }\n\n    public function testAssertWhereContainsUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [BackedEnum::test->value],\n        ]);\n\n        $assert->whereContains('bar', BackedEnum::test);\n\n        $assert = AssertableJson::fromArray([\n            'bar' => [BackedEnum::test_empty->value],\n        ]);\n\n        $assert->whereContains('bar', BackedEnum::test_empty);\n    }\n\n    public function testAssertWhereContainsFailsUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [BackedEnum::test_empty->value],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not contain [test].');\n\n        $assert->whereContains('bar', BackedEnum::test);\n    }\n\n    public function testAssertNestedWhereMatchesValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => 'nested-value',\n            ],\n        ]);\n\n        $assert->where('example.nested', 'nested-value');\n    }\n\n    public function testAssertNestedWhereFailsWhenDoesNotMatchValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => 'nested-value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [example.nested] does not match the expected value.');\n\n        $assert->where('example.nested', 'another-value');\n    }\n\n    public function testAssertNestedWhereUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => BackedEnum::test->value,\n            ],\n        ]);\n\n        $assert->where('example.nested', BackedEnum::test);\n    }\n\n    public function testAssertNestedWhereFailsUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'example' => [\n                'nested' => BackedEnum::test_empty->value,\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [example.nested] does not match the expected value.');\n\n        $assert->where('example.nested', BackedEnum::test);\n    }\n\n    public function testAssertWhereDoesNotMatchValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $assert->whereNot('bar', 'different_value');\n    }\n\n    public function testAssertWhereNotFailsWhenMatchingValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] contains a value that should be missing: [bar, value]');\n\n        $assert->whereNot('bar', 'value');\n    }\n\n    public function testAssertWhereNotFailsWhenNotMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->whereNot('baz', 'value');\n    }\n\n    public function testAssertWhereNotUsingClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'baz',\n        ]);\n\n        $assert->whereNot('bar', function ($value) {\n            return $value === 'foo';\n        });\n    }\n\n    public function testAssertWhereNotFailsWhenMatchesValueUsingClosure()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] was marked as invalid using a closure.');\n\n        $assert->whereNot('bar', function ($value) {\n            return $value === 'baz';\n        });\n    }\n\n    public function testAssertWhereNotUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => BackedEnum::test->value,\n        ]);\n\n        $assert->whereNot('bar', BackedEnum::test_empty);\n    }\n\n    public function testAssertWhereNotFailsUsingBackedEnum()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => BackedEnum::test->value,\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] contains a value that should be missing: [bar, test]');\n\n        $assert->whereNot('bar', BackedEnum::test);\n    }\n\n    public function testScope()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $called = false;\n        $assert->has('bar', function (AssertableJson $assert) use (&$called) {\n            $called = true;\n            $assert\n                ->where('baz', 'example')\n                ->where('prop', 'value');\n        });\n\n        $this->assertTrue($called, 'The scoped query was never actually called.');\n    }\n\n    public function testScopeFailsWhenPropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->has('baz', function (AssertableJson $item) {\n            $item->where('baz', 'example');\n        });\n    }\n\n    public function testScopeFailsWhenPropSingleValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => 'value',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] is not scopeable.');\n\n        $assert->has('bar', function (AssertableJson $item) {\n            //\n        });\n    }\n\n    public function testScopeShorthand()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                ['key' => 'first'],\n                ['key' => 'second'],\n            ],\n        ]);\n\n        $called = false;\n        $assert->has('bar', 2, function (AssertableJson $item) use (&$called) {\n            $item->where('key', 'first');\n            $called = true;\n        });\n\n        $this->assertTrue($called, 'The scoped query was never actually called.');\n    }\n\n    public function testScopeShorthandWithoutCount()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                ['key' => 'first'],\n                ['key' => 'second'],\n            ],\n        ]);\n\n        $called = false;\n        $assert->has('bar', null, function (AssertableJson $item) use (&$called) {\n            $item->where('key', 'first');\n            $called = true;\n        });\n\n        $this->assertTrue($called, 'The scoped query was never actually called.');\n    }\n\n    public function testScopeShorthandFailsWhenAssertingZeroItems()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                ['key' => 'first'],\n                ['key' => 'second'],\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not have the expected size.');\n\n        $assert->has('bar', 0, function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testScopeShorthandFailsWhenAmountOfItemsDoesNotMatch()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                ['key' => 'first'],\n                ['key' => 'second'],\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [bar] does not have the expected size.');\n\n        $assert->has('bar', 1, function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testScopeShorthandFailsWhenAssertingEmptyArray()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\n            'Cannot scope directly onto the first element of property [bar] because it is empty.'\n        );\n\n        $assert->has('bar', 0, function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testScopeShorthandFailsWhenAssertingEmptyArrayWithoutCount()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\n            'Cannot scope directly onto the first element of property [bar] because it is empty.'\n        );\n\n        $assert->has('bar', null, function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testScopeShorthandFailsWhenSecondArgumentUnsupportedType()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                ['key' => 'first'],\n                ['key' => 'second'],\n            ],\n        ]);\n\n        $this->expectException(TypeError::class);\n\n        $assert->has('bar', 'invalid', function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testFirstScope()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'key' => 'first',\n            ],\n            'bar' => [\n                'key' => 'second',\n            ],\n        ]);\n\n        $assert->first(function (AssertableJson $item) {\n            $item->where('key', 'first');\n        });\n    }\n\n    public function testFirstScopeFailsWhenNoProps()\n    {\n        $assert = AssertableJson::fromArray([]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Cannot scope directly onto the first element of the root level because it is empty.');\n\n        $assert->first(function (AssertableJson $item) {\n            //\n        });\n    }\n\n    public function testFirstNestedScopeFailsWhenNoProps()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Cannot scope directly onto the first element of property [foo] because it is empty.');\n\n        $assert->has('foo', function (AssertableJson $assert) {\n            $assert->first(function (AssertableJson $item) {\n                //\n            });\n        });\n    }\n\n    public function testFirstScopeFailsWhenPropSingleValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] is not scopeable.');\n\n        $assert->first(function (AssertableJson $item) {\n            //\n        });\n    }\n\n    public function testEachScope()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'key' => 'first',\n            ],\n            'bar' => [\n                'key' => 'second',\n            ],\n        ]);\n\n        $assert->each(function (AssertableJson $item) {\n            $item->whereType('key', 'string');\n        });\n    }\n\n    public function testEachScopeFailsWhenNoProps()\n    {\n        $assert = AssertableJson::fromArray([]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Cannot scope directly onto each element of the root level because it is empty.');\n\n        $assert->each(function (AssertableJson $item) {\n            //\n        });\n    }\n\n    public function testEachNestedScopeFailsWhenNoProps()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Cannot scope directly onto each element of property [foo] because it is empty.');\n\n        $assert->has('foo', function (AssertableJson $assert) {\n            $assert->each(function (AssertableJson $item) {\n                //\n            });\n        });\n    }\n\n    public function testEachScopeFailsWhenPropSingleValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] is not scopeable.');\n\n        $assert->each(function (AssertableJson $item) {\n            //\n        });\n    }\n\n    public function testFailsWhenNotInteractingWithAllPropsInScope()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Unexpected properties were found in scope [bar].');\n\n        $assert->has('bar', function (AssertableJson $item) {\n            $item->where('baz', 'example');\n        });\n    }\n\n    public function testDisableInteractionCheckForCurrentScope()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $assert->has('bar', function (AssertableJson $item) {\n            $item->etc();\n        });\n    }\n\n    public function testCannotDisableInteractionCheckForDifferentScopes()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => [\n                    'foo' => 'bar',\n                    'example' => 'value',\n                ],\n                'prop' => 'value',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Unexpected properties were found in scope [bar.baz].');\n\n        $assert->has('bar', function (AssertableJson $item) {\n            $item\n                ->etc()\n                ->has('baz', function (AssertableJson $item) {\n                    //\n                });\n        });\n    }\n\n    public function testTopLevelPropInteractionDisabledByDefault()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n            'bar' => 'baz',\n        ]);\n\n        $assert->has('foo');\n    }\n\n    public function testTopLevelInteractionEnabledWhenInteractedFlagSet()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n            'bar' => 'baz',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Unexpected properties were found on the root level.');\n\n        $assert\n            ->has('foo')\n            ->interacted();\n    }\n\n    public function testAssertWhereAllMatchesValues()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'bar' => 'value',\n                'example' => ['hello' => 'world'],\n            ],\n            'baz' => 'another',\n        ]);\n\n        $assert->whereAll([\n            'foo.bar' => 'value',\n            'foo.example' => ArrayableStubObject::make(['hello' => 'world']),\n            'baz' => function ($value) {\n                return $value === 'another';\n            },\n        ]);\n    }\n\n    public function testAssertWhereAllFailsWhenAtLeastOnePropDoesNotMatchValue()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n            'baz' => 'example',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] was marked as invalid using a closure.');\n\n        $assert->whereAll([\n            'foo' => 'bar',\n            'baz' => function ($value) {\n                return $value === 'foo';\n            },\n        ]);\n    }\n\n    public function testAssertWhereTypeString()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $assert->whereType('foo', 'string');\n    }\n\n    public function testAssertWhereTypeInteger()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 123,\n        ]);\n\n        $assert->whereType('foo', 'integer');\n    }\n\n    public function testAssertWhereTypeBoolean()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => true,\n        ]);\n\n        $assert->whereType('foo', 'boolean');\n    }\n\n    public function testAssertWhereTypeDouble()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 12.3,\n        ]);\n\n        $assert->whereType('foo', 'double');\n    }\n\n    public function testAssertWhereTypeArray()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => ['bar', 'baz'],\n            'bar' => ['foo' => 'baz'],\n        ]);\n\n        $assert->whereType('foo', 'array');\n        $assert->whereType('bar', 'array');\n    }\n\n    public function testAssertWhereTypeNull()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => null,\n        ]);\n\n        $assert->whereType('foo', 'null');\n    }\n\n    public function testAssertWhereAllType()\n    {\n        $assert = AssertableJson::fromArray([\n            'one' => 'foo',\n            'two' => 123,\n            'three' => true,\n            'four' => 12.3,\n            'five' => ['foo', 'bar'],\n            'six' => ['foo' => 'bar'],\n            'seven' => null,\n        ]);\n\n        $assert->whereAllType([\n            'one' => 'string',\n            'two' => 'integer',\n            'three' => 'boolean',\n            'four' => 'double',\n            'five' => 'array',\n            'six' => 'array',\n            'seven' => 'null',\n        ]);\n    }\n\n    public function testAssertWhereTypeWhenWrongTypeIsGiven()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] is not of expected type [integer].');\n\n        $assert->whereType('foo', 'integer');\n    }\n\n    public function testAssertWhereTypeWithUnionTypes()\n    {\n        $firstAssert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $secondAssert = AssertableJson::fromArray([\n            'foo' => null,\n        ]);\n\n        $firstAssert->whereType('foo', ['string', 'null']);\n        $secondAssert->whereType('foo', ['string', 'null']);\n    }\n\n    public function testAssertWhereTypeWhenWrongUnionTypeIsGiven()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 123,\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] is not of expected type [string|null].');\n\n        $assert->whereType('foo', ['string', 'null']);\n    }\n\n    public function testAssertWhereTypeWithPipeInUnionType()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $assert->whereType('foo', 'string|null');\n    }\n\n    public function testAssertWhereTypeWithPipeInWrongUnionType()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => 'bar',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo] is not of expected type [integer|null].');\n\n        $assert->whereType('foo', 'integer|null');\n    }\n\n    public function testAssertHasAll()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'bar' => 'value',\n                'example' => ['hello' => 'world'],\n            ],\n            'baz' => 'another',\n        ]);\n\n        $assert->hasAll([\n            'foo.bar',\n            'foo.example',\n            'baz',\n        ]);\n    }\n\n    public function testAssertHasAllFailsWhenAtLeastOnePropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'bar' => 'value',\n                'example' => ['hello' => 'world'],\n            ],\n            'baz' => 'another',\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo.baz] does not exist.');\n\n        $assert->hasAll([\n            'foo.bar',\n            'foo.baz',\n            'baz',\n        ]);\n    }\n\n    public function testAssertHasAllAcceptsMultipleArgumentsInsteadOfArray()\n    {\n        $assert = AssertableJson::fromArray([\n            'foo' => [\n                'bar' => 'value',\n                'example' => ['hello' => 'world'],\n            ],\n            'baz' => 'another',\n        ]);\n\n        $assert->hasAll('foo.bar', 'foo.example', 'baz');\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [foo.baz] does not exist.');\n\n        $assert->hasAll('foo.bar', 'foo.baz', 'baz');\n    }\n\n    public function testAssertCountMultipleProps()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'key' => 'value',\n                'prop' => 'example',\n            ],\n            'baz' => [\n                'another' => 'value',\n            ],\n        ]);\n\n        $assert->hasAll([\n            'bar' => 2,\n            'baz' => 1,\n        ]);\n    }\n\n    public function testAssertCountMultiplePropsFailsWhenPropMissing()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'key' => 'value',\n                'prop' => 'example',\n            ],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Property [baz] does not exist.');\n\n        $assert->hasAll([\n            'bar' => 2,\n            'baz' => 1,\n        ]);\n    }\n\n    public function testMacroable()\n    {\n        AssertableJson::macro('myCustomMacro', function () {\n            throw new RuntimeException('My Custom Macro was called!');\n        });\n\n        $this->expectException(RuntimeException::class);\n        $this->expectExceptionMessage('My Custom Macro was called!');\n\n        $assert = AssertableJson::fromArray(['foo' => 'bar']);\n        $assert->myCustomMacro();\n    }\n\n    public function testTappable()\n    {\n        $assert = AssertableJson::fromArray([\n            'bar' => [\n                'baz' => 'example',\n                'prop' => 'value',\n            ],\n        ]);\n\n        $called = false;\n        $assert->has('bar', function (AssertableJson $assert) use (&$called) {\n            $assert->etc();\n            $assert->tap(function (AssertableJson $assert) use (&$called) {\n                $called = true;\n            });\n        });\n\n        $this->assertTrue($called, 'The scoped query was never actually called.');\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Fluent/BackedEnum.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Fluent;\n\nenum BackedEnum: string\n{\n    case test = 'test';\n    case test_empty = '';\n}\n"
  },
  {
    "path": "tests/Testing/ParallelConsoleOutputTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Testing\\ParallelConsoleOutput;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Console\\Output\\BufferedOutput;\n\nclass ParallelConsoleOutputTest extends TestCase\n{\n    public function testWrite(): void\n    {\n        $original = new BufferedOutput;\n        $output = new ParallelConsoleOutput($original);\n\n        $output->write('Running phpunit in 12 processes with laravel/laravel.');\n        $this->assertEmpty($original->fetch());\n\n        $output->write('Configuration read from phpunit.xml.dist');\n        $this->assertEmpty($original->fetch());\n\n        $output->write('... 3/3 (100%)');\n        $this->assertSame('... 3/3 (100%)', $original->fetch());\n    }\n}\n"
  },
  {
    "path": "tests/Testing/ParallelTestingTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Testing\\ParallelTesting;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass ParallelTestingTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        Container::setInstance(new Container);\n\n        $_SERVER['LARAVEL_PARALLEL_TESTING'] = 1;\n    }\n\n    #[DataProvider('callbacks')]\n    public function testCallbacks($callback): void\n    {\n        $parallelTesting = new ParallelTesting(Container::getInstance());\n        $caller = 'call'.ucfirst($callback).'Callbacks';\n\n        $state = false;\n        $parallelTesting->{$caller}($this);\n        $this->assertFalse($state);\n\n        $parallelTesting->{$callback}(function ($token, $testCase = null) use ($callback, &$state) {\n            if (in_array($callback, ['setUpTestCase', 'tearDownTestCase'])) {\n                $this->assertSame($this, $testCase);\n            } else {\n                $this->assertNull($testCase);\n            }\n\n            $this->assertSame('1', (string) $token);\n            $state = true;\n        });\n\n        $parallelTesting->{$caller}($this);\n        $this->assertFalse($state);\n\n        $parallelTesting->resolveTokenUsing(function () {\n            return '1';\n        });\n\n        $parallelTesting->{$caller}($this);\n        $this->assertTrue($state);\n    }\n\n    public function testOptions(): void\n    {\n        $parallelTesting = new ParallelTesting(Container::getInstance());\n\n        $this->assertFalse($parallelTesting->option('recreate_databases'));\n        $this->assertFalse($parallelTesting->option('without_databases'));\n\n        $parallelTesting->resolveOptionsUsing(function ($option) {\n            return $option === 'recreate_databases';\n        });\n\n        $this->assertFalse($parallelTesting->option('recreate_caches'));\n        $this->assertFalse($parallelTesting->option('without_databases'));\n        $this->assertTrue($parallelTesting->option('recreate_databases'));\n\n        $parallelTesting->resolveOptionsUsing(function ($option) {\n            return $option === 'without_databases';\n        });\n\n        $this->assertTrue($parallelTesting->option('without_databases'));\n    }\n\n    public function testToken(): void\n    {\n        $parallelTesting = new ParallelTesting(Container::getInstance());\n\n        $this->assertFalse($parallelTesting->token());\n\n        $parallelTesting->resolveTokenUsing(function () {\n            return '1';\n        });\n\n        $this->assertSame('1', (string) $parallelTesting->token());\n    }\n\n    public static function callbacks()\n    {\n        return [\n            ['setUpProcess'],\n            ['setUpTestCase'],\n            ['setUpTestDatabase'],\n            ['setUpTestDatabaseBeforeMigrating'],\n            ['tearDownTestCase'],\n            ['tearDownProcess'],\n        ];\n    }\n\n    protected function tearDown(): void\n    {\n        Container::setInstance(null);\n\n        unset($_SERVER['LARAVEL_PARALLEL_TESTING']);\n\n        parent::tearDown();\n    }\n}\n"
  },
  {
    "path": "tests/Testing/Stubs/ArrayableStubObject.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing\\Stubs;\n\nuse Illuminate\\Contracts\\Support\\Arrayable;\n\nclass ArrayableStubObject implements Arrayable\n{\n    protected $data;\n\n    public function __construct($data = [])\n    {\n        $this->data = $data;\n    }\n\n    public static function make($data = [])\n    {\n        return new self($data);\n    }\n\n    public function toArray()\n    {\n        return $this->data;\n    }\n}\n"
  },
  {
    "path": "tests/Testing/TestResponseTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Testing;\n\nuse Exception;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Contracts\\View\\View;\nuse Illuminate\\Cookie\\CookieValuePrefix;\nuse Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Encryption\\Encrypter;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\RedirectResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Routing\\RouteCollection;\nuse Illuminate\\Routing\\UrlGenerator;\nuse Illuminate\\Session\\ArraySessionHandler;\nuse Illuminate\\Session\\NullSessionHandler;\nuse Illuminate\\Session\\Store;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\MessageBag;\nuse Illuminate\\Support\\ViewErrorBag;\nuse Illuminate\\Testing\\Fluent\\AssertableJson;\nuse Illuminate\\Testing\\TestResponse;\nuse JsonSerializable;\nuse Mockery as m;\nuse PHPUnit\\Framework\\AssertionFailedError;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\ExpectationFailedException;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\BinaryFileResponse;\nuse Symfony\\Component\\HttpFoundation\\Cookie;\nuse Symfony\\Component\\HttpFoundation\\StreamedJsonResponse;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\n\nclass TestResponseTest extends TestCase\n{\n    public function testAssertViewIs(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'getData' => ['foo' => 'bar'],\n            'name' => 'dir.my-view',\n        ]);\n\n        $response->assertViewIs('dir.my-view');\n    }\n\n    public function testAssertViewHas(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewHas('foo');\n    }\n\n    public function testAssertViewHasModel(): void\n    {\n        $model = new TestModel(['id' => 1]);\n\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => $model],\n        ]);\n\n        $response->assertViewHas('foo', $model);\n    }\n\n    public function testAssertViewHasWithClosure(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewHas('foo', function ($value) {\n            return $value === 'bar';\n        });\n    }\n\n    public function testAssertViewHasWithValue(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewHas('foo', 'bar');\n    }\n\n    public function testAssertViewHasNested(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => [\n                'foo' => [\n                    'nested' => 'bar',\n                ],\n            ],\n        ]);\n\n        $response->assertViewHas('foo.nested');\n    }\n\n    public function testAssertViewHasWithNestedValue(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => [\n                'foo' => [\n                    'nested' => 'bar',\n                ],\n            ],\n        ]);\n\n        $response->assertViewHas('foo.nested', 'bar');\n    }\n\n    public function testAssertViewHasEloquentCollection(): void\n    {\n        $collection = new EloquentCollection([\n            new TestModel(['id' => 1]),\n            new TestModel(['id' => 2]),\n            new TestModel(['id' => 3]),\n        ]);\n\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foos' => $collection],\n        ]);\n\n        $response->assertViewHas('foos', $collection);\n    }\n\n    public function testAssertViewHasEloquentCollectionRespectsOrder(): void\n    {\n        $collection = new EloquentCollection([\n            new TestModel(['id' => 3]),\n            new TestModel(['id' => 2]),\n            new TestModel(['id' => 1]),\n        ]);\n\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foos' => $collection],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $response->assertViewHas('foos', $collection->reverse()->values());\n    }\n\n    public function testAssertViewHasEloquentCollectionRespectsType(): void\n    {\n        $actual = new EloquentCollection([\n            new TestModel(['id' => 1]),\n            new TestModel(['id' => 2]),\n        ]);\n\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foos' => $actual],\n        ]);\n\n        $expected = new EloquentCollection([\n            new AnotherTestModel(['id' => 1]),\n            new AnotherTestModel(['id' => 2]),\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $response->assertViewHas('foos', $expected);\n    }\n\n    public function testAssertViewHasEloquentCollectionRespectsSize(): void\n    {\n        $actual = new EloquentCollection([\n            new TestModel(['id' => 1]),\n            new TestModel(['id' => 2]),\n        ]);\n\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foos' => $actual],\n        ]);\n\n        $this->expectException(AssertionFailedError::class);\n\n        $response->assertViewHas('foos', $actual->concat([new TestModel(['id' => 3])]));\n    }\n\n    public function testAssertViewHasWithArray(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewHas(['foo' => 'bar']);\n    }\n\n    public function testAssertViewHasAll(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewHasAll([\n            'foo' => 'bar',\n        ]);\n    }\n\n    public function testAssertViewMissing(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar'],\n        ]);\n\n        $response->assertViewMissing('baz');\n    }\n\n    public function testAssertViewMissingNested(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => [\n                'foo' => [\n                    'nested' => 'bar',\n                ],\n            ],\n        ]);\n\n        $response->assertViewMissing('foo.baz');\n    }\n\n    public function testViewData(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'hello world',\n            'gatherData' => ['foo' => 'bar', 'baz' => 'qux'],\n        ]);\n\n        $this->assertEquals('bar', $response->viewData('foo'));\n\n        $this->assertEquals(['foo' => 'bar', 'baz' => 'qux'], $response->viewData());\n    }\n\n    public function testAssertContent(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'expected response data',\n        ]);\n\n        $response->assertContent('expected response data');\n\n        try {\n            $response->assertContent('expected');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n\n        try {\n            $response->assertContent('expected response data with extra');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n    }\n\n    public function testAssertStreamedAndAssertNotStreamed(): void\n    {\n        $notStreamedResponse = $this->makeMockResponse([\n            'render' => 'expected response data',\n        ]);\n\n        $streamedResponse = TestResponse::fromBaseResponse(\n            new StreamedResponse(function () {\n                $stream = fopen('php://memory', 'r+');\n                fwrite($stream, 'expected response data');\n                rewind($stream);\n                fpassthru($stream);\n            })\n        );\n\n        $notStreamedResponse->assertNotStreamed();\n        $streamedResponse->assertStreamed();\n\n        try {\n            $notStreamedResponse->assertStreamed();\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Expected the response to be streamed, but it wasn't.\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n\n        try {\n            $streamedResponse->assertNotStreamed();\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Response was unexpectedly streamed.\\nFailed asserting that false is true.\", $e->getMessage());\n        }\n    }\n\n    public function testAssertStreamedContent(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new StreamedResponse(function () {\n                $stream = fopen('php://memory', 'r+');\n                fwrite($stream, 'expected response data');\n                rewind($stream);\n                fpassthru($stream);\n            })\n        );\n\n        $response->assertStreamedContent('expected response data');\n\n        try {\n            $response->assertStreamedContent('expected');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n\n        try {\n            $response->assertStreamedContent('expected response data with extra');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n    }\n\n    public function testAssertStreamedJsonContent(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new StreamedJsonResponse([\n                'data' => $this->yieldTestModels(),\n            ])\n        );\n\n        $response->assertStreamedJsonContent([\n            'data' => [\n                ['id' => 1],\n                ['id' => 2],\n                ['id' => 3],\n            ],\n        ]);\n\n        try {\n            $response->assertStreamedJsonContent([\n                'data' => [\n                    ['id' => 1],\n                    ['id' => 2],\n                ],\n            ]);\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n\n        try {\n            $response->assertStreamedContent('not expected response string');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n    }\n\n    public function testAssertStreamedBinaryFile(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new BinaryFileResponse(__DIR__.'/Fixtures/file.json')\n        );\n\n        $response->assertStreamedContent('{\"foo\":\"bar\"}');\n\n        try {\n            $response->assertStreamedContent('not expected response string');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n    }\n\n    public function testAssertStreamedJsonFile(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new BinaryFileResponse(__DIR__.'/Fixtures/file.json')\n        );\n\n        $response->assertStreamedJsonContent(['foo' => 'bar']);\n\n        try {\n            $response->assertStreamedJsonContent([\n                'data' => [\n                    ['id' => 1],\n                    ['id' => 2],\n                ],\n            ]);\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two strings are identical.', $e->getMessage());\n        }\n    }\n\n    public function testJsonAssertionsOnStreamedJsonContent(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new StreamedJsonResponse([\n                'data' => $this->yieldTestModels(),\n            ])\n        );\n\n        $response->assertJsonPath('data', [\n            ['id' => 1],\n            ['id' => 2],\n            ['id' => 3],\n        ]);\n\n        try {\n            $response->assertJsonPath('data', [\n                ['id' => 1],\n                ['id' => 2],\n            ]);\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame('Failed asserting that two arrays are identical.', $e->getMessage());\n        }\n\n        $response->assertJsonCount(3, 'data');\n\n        try {\n            $response->assertJsonCount(2, 'data');\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $this->assertSame(\"Failed to assert that the response count matched the expected 2\\nFailed asserting that actual size 3 matches expected size 2.\", $e->getMessage());\n        }\n    }\n\n    public function yieldTestModels()\n    {\n        yield new TestModel(['id' => 1]);\n        yield new TestModel(['id' => 2]);\n        yield new TestModel(['id' => 3]);\n    }\n\n    public function testAssertSee(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSee('foo');\n        $response->assertSee(['baz', 'bar']);\n    }\n\n    public function testAssertSeeCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSee('item');\n        $response->assertSee(['not', 'found']);\n    }\n\n    public function testAssertSeeEscaped(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertSee('laravel & php');\n        $response->assertSee(['php & friends', 'laravel & php']);\n    }\n\n    public function testAssertSeeEscapedCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertSee('foo & bar');\n        $response->assertSee(['bar & baz', 'baz & qux']);\n    }\n\n    public function testAssertSeeHtml(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeHtml('<li>foo</li>');\n        $response->assertSeeHtml(['<li>baz</li>', '<li>bar</li>']);\n    }\n\n    public function testAssertSeeHtmlCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeHtml('<li>item</li>');\n        $response->assertSeeHtml(['<li>not</li>', '<li>found</li>']);\n    }\n\n    public function testAssertSeeInOrder(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeInOrder(['foo', 'bar', 'baz']);\n\n        $response->assertSeeInOrder(['foo', 'bar', 'baz', 'foo']);\n    }\n\n    public function testAssertSeeInOrderCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeInOrder(['baz', 'bar', 'foo']);\n    }\n\n    public function testAssertSeeInOrderCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeInOrder(['foo', 'qux', 'bar', 'baz']);\n    }\n\n    public function testAssertSeeHtmlInOrder(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>bar</li>', '<li>baz</li>']);\n\n        $response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>bar</li>', '<li>baz</li>', '<li>foo</li>']);\n    }\n\n    public function testAssertSeeHtmlInOrderCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeHtmlInOrder(['<li>baz</li>', '<li>bar</li>', '<li>foo</li>']);\n    }\n\n    public function testAssertSeeHtmlInOrderCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertSeeHtmlInOrder(['<li>foo</li>', '<li>qux</li>', '<li>bar</li>', '<li>baz</li>']);\n    }\n\n    public function testAssertSeeText(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',\n        ]);\n\n        $response->assertSeeText('foobar');\n        $response->assertSeeText(['bazqux', 'foobar']);\n    }\n\n    public function testAssertSeeTextCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that \\'foo<strong>bar</strong>\\' contains \"bazfoo\".');\n\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong>',\n        ]);\n\n        $response->assertSeeText('bazfoo');\n        $response->assertSeeText(['bazfoo', 'barqux']);\n    }\n\n    public function testAssertSeeTextEscaped(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertSeeText('laravel & php');\n        $response->assertSeeText(['php & friends', 'laravel & php']);\n    }\n\n    public function testAssertSeeTextWhitespace(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => <<<'EOT'\n<p>\n    Hello,\n    laravel &amp; php &amp; friends\n</p>,\nEOT\n        ]);\n\n        $response->assertSeeText('Hello, laravel & php & friends');\n    }\n\n    public function testAssertSeeTextEscapedCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertSeeText('foo & bar');\n        $response->assertSeeText(['foo & bar', 'bar & baz']);\n    }\n\n    public function testAssertSeeTextInOrder(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',\n        ]);\n\n        $response->assertSeeTextInOrder(['foobar', 'baz']);\n\n        $response->assertSeeTextInOrder(['foobar', 'baz', 'foo']);\n    }\n\n    public function testAssertSeeTextInOrderEscaped(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<strong>laravel &amp; php</strong> <i>phpstorm &gt; sublime</i>',\n        ]);\n\n        $response->assertSeeTextInOrder(['laravel & php', 'phpstorm > sublime']);\n    }\n\n    public function testAssertSeeTextInOrderWhitespace(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => <<<'EOT'\n<p>\n    Hello,\n    laravel &amp; php &amp; friends\n</p>,\nEOT\n        ]);\n\n        $response->assertSeeTextInOrder(['Hello', 'laravel & php', 'friends']);\n    }\n\n    public function testAssertSeeTextInOrderCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that \\'foo<strong>bar</strong> baz <strong>foo</strong>\\' contains \"foobar\" in specified order.');\n\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',\n        ]);\n\n        $response->assertSeeTextInOrder(['baz', 'foobar']);\n    }\n\n    public function testAssertSeeTextInOrderCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong> baz <strong>foo</strong>',\n        ]);\n\n        $response->assertSeeTextInOrder(['foobar', 'qux', 'baz']);\n    }\n\n    public function testAssertDontSee(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertDontSee('laravel');\n        $response->assertDontSee(['php', 'friends']);\n    }\n\n    public function testAssertDontSeeCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertDontSee('foo');\n        $response->assertDontSee(['baz', 'bar']);\n    }\n\n    public function testAssertDontSeeEscaped(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertDontSee('foo & bar');\n        $response->assertDontSee(['bar & baz', 'foo & bar']);\n    }\n\n    public function testAssertDontSeeEscapedCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertDontSee('laravel & php');\n        $response->assertDontSee(['php & friends', 'laravel & php']);\n    }\n\n    public function testAssertDontSeeHtml(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertDontSeeHtml('<li>laravel</li>');\n        $response->assertDontSeeHtml(['<li>php</li>', '<li>friends</li>']);\n    }\n\n    public function testAssertDontSeeHtmlCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => '<ul><li>foo</li><li>bar</li><li>baz</li><li>foo</li></ul>',\n        ]);\n\n        $response->assertDontSeeHtml('<li>foo</li>');\n        $response->assertDontSeeHtml(['<li>baz</li>', '<li>bar</li>']);\n    }\n\n    public function testAssertDontSeeText(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',\n        ]);\n\n        $response->assertDontSeeText('laravelphp');\n        $response->assertDontSeeText(['phpfriends', 'laravelphp']);\n    }\n\n    public function testAssertDontSeeTextCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that \\'foo<strong>bar</strong>baz<strong>qux</strong>\\' does not contain \"foobar\".');\n\n        $response = $this->makeMockResponse([\n            'render' => 'foo<strong>bar</strong>baz<strong>qux</strong>',\n        ]);\n\n        $response->assertDontSeeText('foobar');\n        $response->assertDontSeeText(['bazqux', 'foobar']);\n    }\n\n    public function testAssertDontSeeTextEscaped(): void\n    {\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertDontSeeText('foo & bar');\n        $response->assertDontSeeText(['bar & baz', 'foo & bar']);\n    }\n\n    public function testAssertDontSeeTextEscapedCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = $this->makeMockResponse([\n            'render' => 'laravel &amp; php &amp; friends',\n        ]);\n\n        $response->assertDontSeeText('laravel & php');\n        $response->assertDontSeeText(['php & friends', 'laravel & php']);\n    }\n\n    public function testAssertOk(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertOk();\n    }\n\n    public function testAssertCreated(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertCreated();\n    }\n\n    public function testAssertNotFound(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertNotFound();\n    }\n\n    public function testAssertMethodNotAllowed(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_METHOD_NOT_ALLOWED)\n        );\n\n        $response->assertMethodNotAllowed();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [405] but received 200.\\nFailed asserting that 200 is identical to 405.\");\n\n        $response->assertMethodNotAllowed();\n    }\n\n    public function testAssertNotAcceptable(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_NOT_ACCEPTABLE)\n        );\n\n        $response->assertNotAcceptable();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [406] but received 200.\\nFailed asserting that 200 is identical to 406.\");\n\n        $response->assertNotAcceptable();\n        $this->fail();\n    }\n\n    public function testAssertForbidden(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertForbidden();\n    }\n\n    public function testAssertUnauthorized(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertUnauthorized();\n    }\n\n    public function testAssertBadRequest(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_BAD_REQUEST)\n        );\n\n        $response->assertBadRequest();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [400] but received 200.\\nFailed asserting that 200 is identical to 400.\");\n\n        $response->assertBadRequest();\n        $this->fail();\n    }\n\n    public function testAssertRequestTimeout(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_REQUEST_TIMEOUT)\n        );\n\n        $response->assertRequestTimeout();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [408] but received 200.\\nFailed asserting that 200 is identical to 408.\");\n\n        $response->assertRequestTimeout();\n        $this->fail();\n    }\n\n    public function testAssertPaymentRequired(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_PAYMENT_REQUIRED)\n        );\n\n        $response->assertPaymentRequired();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [402] but received 200.\\nFailed asserting that 200 is identical to 402.\");\n\n        $response->assertPaymentRequired();\n        $this->fail();\n    }\n\n    public function testAssertMovedPermanently(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_MOVED_PERMANENTLY)\n        );\n\n        $response->assertMovedPermanently();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [301] but received 200.\\nFailed asserting that 200 is identical to 301.\");\n\n        $response->assertMovedPermanently();\n        $this->fail();\n    }\n\n    public function testAssertFound(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_FOUND)\n        );\n\n        $response->assertFound();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [302] but received 200.\\nFailed asserting that 200 is identical to 302.\");\n\n        $response->assertFound();\n        $this->fail();\n    }\n\n    public function testAssertNotModified(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_NOT_MODIFIED)\n        );\n\n        $response->assertNotModified();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [304] but received 200.\\nFailed asserting that 200 is identical to 304.\");\n\n        $response->assertNotModified();\n        $this->fail();\n    }\n\n    public function testAssertTemporaryRedirect(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_TEMPORARY_REDIRECT)\n        );\n\n        $response->assertTemporaryRedirect();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [307] but received 200.\\nFailed asserting that 200 is identical to 307.\");\n\n        $response->assertTemporaryRedirect();\n        $this->fail();\n    }\n\n    public function testAssertPermanentRedirect(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_PERMANENTLY_REDIRECT)\n        );\n\n        $response->assertPermanentRedirect();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [308] but received 200.\\nFailed asserting that 200 is identical to 308.\");\n\n        $response->assertPermanentRedirect();\n        $this->fail();\n    }\n\n    public function testAssertConflict(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_CONFLICT)\n        );\n\n        $response->assertConflict();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [409] but received 200.\\nFailed asserting that 200 is identical to 409.\");\n\n        $response->assertConflict();\n        $this->fail();\n    }\n\n    public function testAssertGone(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_GONE)\n        );\n\n        $response->assertGone();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [410] but received 200.\\nFailed asserting that 200 is identical to 410.\");\n\n        $response->assertGone();\n    }\n\n    public function testAssertTooManyRequests(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_TOO_MANY_REQUESTS)\n        );\n\n        $response->assertTooManyRequests();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [429] but received 200.\\nFailed asserting that 200 is identical to 429.\");\n\n        $response->assertTooManyRequests();\n        $this->fail();\n    }\n\n    public function testAssertAccepted(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_ACCEPTED)\n        );\n\n        $response->assertAccepted();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [202] but received 200.\\nFailed asserting that 200 is identical to 202.\");\n\n        $response->assertAccepted();\n        $this->fail();\n    }\n\n    public function testAssertUnprocessable(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertUnprocessable();\n    }\n\n    public function testAssertFailedDependency(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_FAILED_DEPENDENCY)\n        );\n\n        $response->assertFailedDependency();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [424] but received 200.\\nFailed asserting that 200 is identical to 424.\");\n\n        $response->assertFailedDependency();\n        $this->fail();\n    }\n\n    public function testAssertClientError(): void\n    {\n        $statusCode = 400;\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertClientError();\n    }\n\n    public function testAssertServerError(): void\n    {\n        $statusCode = 500;\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertServerError();\n    }\n\n    public function testAssertInternalServerError(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR)\n        );\n\n        $response->assertInternalServerError();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [500] but received 200.\\nFailed asserting that 200 is identical to 500.\");\n\n        $response->assertInternalServerError();\n    }\n\n    public function testAssertServiceUnavailable(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_SERVICE_UNAVAILABLE)\n        );\n\n        $response->assertServiceUnavailable();\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setStatusCode(Response::HTTP_OK)\n        );\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage(\"Expected response status code [503] but received 200.\\nFailed asserting that 200 is identical to 503.\");\n\n        $response->assertServiceUnavailable();\n    }\n\n    public function testAssertNoContentAsserts204StatusCodeByDefault(): void\n    {\n        $statusCode = 500;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertNoContent();\n    }\n\n    public function testAssertNoContentAssertsExpectedStatusCode(): void\n    {\n        $statusCode = 500;\n        $expectedStatusCode = 418;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertNoContent($expectedStatusCode);\n    }\n\n    public function testAssertNoContentAssertsEmptyContent(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Response content is not empty');\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setStatusCode(204);\n            $response->setContent('non-empty-response-content');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertNoContent();\n    }\n\n    public function testAssertStatus(): void\n    {\n        $statusCode = 500;\n        $expectedStatusCode = 401;\n\n        $this->expectException(AssertionFailedError::class);\n\n        $this->expectExceptionMessage('Expected response status code');\n\n        $baseResponse = tap(new Response, function ($response) use ($statusCode) {\n            $response->setStatusCode($statusCode);\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertStatus($expectedStatusCode);\n    }\n\n    public function testAssertHeader(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->header('Location', '/foo');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertHeader('Location', '/bar');\n    }\n\n    public function testAssertHeaderMissing(): void\n    {\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('Unexpected header [Location] is present on response.');\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->header('Location', '/foo');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertHeaderMissing('Location');\n    }\n\n    public function testAssertPrecognitionSuccessfulWithMissingHeader(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Header [Precognition-Success] not present on response.');\n\n        $baseResponse = new Response('', 204);\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertSuccessfulPrecognition();\n    }\n\n    public function testAssertPrecognitionSuccessfulWithIncorrectValue(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('The Precognition-Success header was found, but the value is not `true`.');\n\n        $baseResponse = tap(new Response('', 204), function ($response) {\n            $response->header('Precognition-Success', '');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertSuccessfulPrecognition();\n    }\n\n    public function testAssertJsonWithArray(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $resource = new JsonSerializableSingleResourceStub;\n\n        $response->assertJson($resource->jsonSerialize());\n    }\n\n    public function testAssertJsonWithNull(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(null));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Invalid JSON was returned from the route.');\n\n        $resource = new JsonSerializableSingleResourceStub;\n\n        $response->assertJson($resource->jsonSerialize());\n    }\n\n    public function testAssertJsonWithFluent(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJson(function (AssertableJson $json) {\n            $json->where('0.foo', 'foo 0');\n            $json->where('0.meta', []);\n        });\n    }\n\n    public function testAssertJsonWithFluentFailsWhenNotInteractingWithAllProps(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Unexpected properties were found on the root level.');\n\n        $response->assertJson(function (AssertableJson $json) {\n            $json->where('foo', 'bar');\n        });\n    }\n\n    public function testAssertJsonWithFluentSkipsInteractionWhenTopLevelKeysNonAssociative(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            ['foo' => 'bar'],\n            ['foo' => 'baz'],\n        ]));\n\n        $response->assertJson(function (AssertableJson $json) {\n            //\n        });\n    }\n\n    public function testAssertJsonWithFluentHasAnyThrows(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([]));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('None of properties [data, errors, meta] exist.');\n\n        $response->assertJson(function (AssertableJson $json) {\n            $json->hasAny('data', 'errors', 'meta');\n        });\n    }\n\n    public function testAssertJsonWithFluentHasAnyPasses(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            'data' => [],\n        ]));\n\n        $response->assertJson(function (AssertableJson $json) {\n            $json->hasAny('data', 'errors', 'meta');\n        });\n    }\n\n    public function testAssertSimilarJsonWithMixed(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $resource = new JsonSerializableMixedResourcesStub;\n\n        $expected = $resource->jsonSerialize();\n\n        $response->assertSimilarJson($expected);\n\n        $expected['bars'][0] = ['bar' => 'foo 2', 'foo' => 'bar 2'];\n        $expected['bars'][2] = ['bar' => 'foo 0', 'foo' => 'bar 0'];\n\n        $response->assertSimilarJson($expected);\n    }\n\n    public function testAssertExactJsonWithMixedWhenDataIsExactlySame(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $resource = new JsonSerializableMixedResourcesStub;\n\n        $expected = $resource->jsonSerialize();\n\n        $response->assertExactJson($expected);\n    }\n\n    public function testAssertExactJsonWithMixedWhenDataIsSimilar(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that two strings are equal.');\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $resource = new JsonSerializableMixedResourcesStub;\n\n        $expected = $resource->jsonSerialize();\n        $expected['bars'][0] = ['bar' => 'foo 2', 'foo' => 'bar 2'];\n        $expected['bars'][2] = ['bar' => 'foo 0', 'foo' => 'bar 0'];\n\n        $response->assertExactJson($expected);\n    }\n\n    public function testAssertJsonPath(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJsonPath('0.foo', 'foo 0');\n\n        $response->assertJsonPath('0.foo', 'foo 0');\n        $response->assertJsonPath('0.bar', 'bar 0');\n        $response->assertJsonPath('0.foobar', 'foobar 0');\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $response->assertJsonPath('foo', 'bar');\n\n        $response->assertJsonPath('foobar.foobar_foo', 'foo');\n        $response->assertJsonPath('foobar.foobar_bar', 'bar');\n\n        $response->assertJsonPath('foobar.foobar_foo', 'foo')->assertJsonPath('foobar.foobar_bar', 'bar');\n\n        $response->assertJsonPath('bars', [\n            ['bar' => 'foo 0', 'foo' => 'bar 0'],\n            ['bar' => 'foo 1', 'foo' => 'bar 1'],\n            ['bar' => 'foo 2', 'foo' => 'bar 2'],\n        ]);\n        $response->assertJsonPath('bars.0', ['bar' => 'foo 0', 'foo' => 'bar 0']);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonPath('0.id', 10);\n        $response->assertJsonPath('1.id', 20);\n        $response->assertJsonPath('2.id', 30);\n    }\n\n    public function testAssertJsonPathCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that 10 is identical to \\'10\\'.');\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonPath('0.id', '10');\n    }\n\n    public function testAssertJsonPathWithClosure(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            'data' => ['foo' => 'bar'],\n        ]));\n\n        $response->assertJsonPath('data.foo', fn ($value) => $value === 'bar');\n    }\n\n    public function testAssertJsonPathWithClosureCanFail(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            'data' => ['foo' => 'bar'],\n        ]));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that false is true.');\n\n        $response->assertJsonPath('data.foo', fn ($value) => $value === null);\n    }\n\n    public function testAssertJsonPathWithEnum(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            'data' => ['status' => 'booked'],\n        ]));\n\n        $response->assertJsonPath('data.status', TestStatus::Booked);\n    }\n\n    public function testAssertJsonPathWithEnumCanFail(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response([\n            'data' => ['status' => 'failed'],\n        ]));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that two strings are identical.');\n\n        $response->assertJsonPath('data.status', TestStatus::Booked);\n    }\n\n    public function testAssertJsonPathCanonicalizing(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJsonPathCanonicalizing('*.foo', ['foo 0', 'foo 1', 'foo 2', 'foo 3']);\n        $response->assertJsonPathCanonicalizing('*.foo', ['foo 1', 'foo 0', 'foo 3', 'foo 2']);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonPathCanonicalizing('*.id', [10, 20, 30]);\n        $response->assertJsonPathCanonicalizing('*.id', [30, 10, 20]);\n    }\n\n    public function testAssertJsonPathCanonicalizingCanFail(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Failed asserting that two arrays are equal.');\n\n        $response->assertJsonPathCanonicalizing('*.foo', ['foo 0', 'foo 2', 'foo 3']);\n    }\n\n    public function testAssertJsonFragment(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJsonFragment(['foo' => 'foo 0']);\n\n        $response->assertJsonFragment(['foo' => 'foo 0', 'bar' => 'bar 0', 'foobar' => 'foobar 0']);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $response->assertJsonFragment(['foo' => 'bar']);\n\n        $response->assertJsonFragment(['foobar_foo' => 'foo']);\n\n        $response->assertJsonFragment(['foobar' => ['foobar_foo' => 'foo', 'foobar_bar' => 'bar']]);\n\n        $response->assertJsonFragment(['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']]);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonFragment(['id' => 10]);\n    }\n\n    public function testAssertJsonFragments(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJsonFragments([\n            ['foo' => 'foo 0'],\n        ]);\n\n        $response->assertJsonFragments([\n            ['foo' => 'foo 0'],\n            ['foo' => 'foo 1'],\n        ]);\n    }\n\n    public function testAssertJsonFragmentCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonFragment(['id' => 1]);\n    }\n\n    public function testAssertJsonFragmentUnicodeCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessageMatches('/Привет|Мир/');\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithUnicodeStub));\n\n        $response->assertJsonFragment(['id' => 1]);\n    }\n\n    public function testAssertJsonStructure(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        // Without structure\n        $response->assertJsonStructure();\n\n        // At root\n        $response->assertJsonStructure(['foo']);\n\n        // Nested\n        $response->assertJsonStructure(['foobar' => ['foobar_foo', 'foobar_bar']]);\n\n        // Wildcard (repeating structure)\n        $response->assertJsonStructure(['bars' => ['*' => ['bar', 'foo']]]);\n\n        // Wildcard (numeric keys)\n        $response->assertJsonStructure(['numeric_keys' => ['*' => ['bar', 'foo']]]);\n\n        // Nested after wildcard\n        $response->assertJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo', 'bar']]]]);\n\n        // Wildcard (repeating structure) at root\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        $response->assertJsonStructure(['*' => ['foo', 'bar', 'foobar']]);\n    }\n\n    public function testAssertExactJsonStructure(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        // Without structure\n        $response->assertExactJsonStructure();\n\n        // At root\n        try {\n            $response->assertExactJsonStructure(['foo']);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['foo', 'foobar', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);\n\n        // Nested\n        try {\n            $response->assertExactJsonStructure(['foobar' => ['foobar_foo'], 'foo', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['foobar' => ['foobar_foo', 'foobar_bar'], 'foo', 0, 'bars', 'baz', 'barfoo', 'numeric_keys']);\n\n        // Wildcard (repeating structure)\n        try {\n            $response->assertExactJsonStructure(['bars' => ['*' => ['bar']], 'foo', 'foobar', 0, 'baz', 'barfoo', 'numeric_keys']);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['bars' => ['*' => ['bar', 'foo']], 'foo', 'foobar', 0, 'baz', 'barfoo', 'numeric_keys']);\n\n        // Wildcard (numeric keys)\n        try {\n            $response->assertExactJsonStructure(['numeric_keys' => ['*' => ['bar']], 'foo', 'foobar', 0, 'bars', 'baz', 'barfoo']);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['numeric_keys' => ['*' => ['bar', 'foo']], 'foo', 'foobar', 0, 'bars', 'baz', 'barfoo']);\n\n        // Nested after wildcard\n        try {\n            $response->assertExactJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo']]], 'foo', 'foobar', 0, 'bars', 'barfoo', 'numeric_keys']);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['baz' => ['*' => ['foo', 'bar' => ['foo', 'bar']]], 'foo', 'foobar', 0, 'bars', 'barfoo', 'numeric_keys']);\n\n        // Wildcard (repeating structure) at root\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n\n        try {\n            $response->assertExactJsonStructure(['*' => ['foo', 'bar']]);\n            $failed = false;\n        } catch (AssertionFailedError $e) {\n            $failed = true;\n        }\n\n        $this->assertTrue($failed);\n\n        $response->assertExactJsonStructure(['*' => ['foo', 'bar', 'foobar', 'meta']]);\n    }\n\n    public function testAssertJsonCount(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        // With falsey key\n        $response->assertJsonCount(1, '0');\n\n        // With simple key\n        $response->assertJsonCount(3, 'bars');\n\n        // With nested key\n        $response->assertJsonCount(1, 'barfoo.0.bar');\n        $response->assertJsonCount(3, 'barfoo.2.bar');\n\n        // Without structure\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n        $response->assertJsonCount(4);\n    }\n\n    public function testAssertJsonMissing(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonMissing(['id' => 20]);\n    }\n\n    public function testAssertJsonMissingExact(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonMissingExact(['id' => 2]);\n\n        // This is missing because bar has changed to baz\n        $response->assertJsonMissingExact(['id' => 20, 'foo' => 'baz']);\n    }\n\n    public function testAssertJsonMissingExactCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonMissingExact(['id' => 20]);\n    }\n\n    public function testAssertJsonMissingExactCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceWithIntegersStub));\n\n        $response->assertJsonMissingExact(['id' => 20, 'foo' => 'bar']);\n    }\n\n    public function testAssertJsonMissingPath(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        // With simple key\n        $response->assertJsonMissingPath('missing');\n\n        // With nested key\n        $response->assertJsonMissingPath('foobar.missing');\n        $response->assertJsonMissingPath('numeric_keys.0');\n    }\n\n    public function testAssertJsonMissingPathCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $response->assertJsonMissingPath('foo');\n    }\n\n    public function testAssertJsonMissingPathCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $response->assertJsonMissingPath('foobar.foobar_foo');\n    }\n\n    public function testAssertJsonMissingPathCanFail3(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $response->assertJsonMissingPath('numeric_keys.3');\n    }\n\n    public function testAssertJsonValidationErrors(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors('foo');\n    }\n\n    public function testAssertOnlyJsonValidationErrors(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'oops', 'bar' => 'another oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        try {\n            $testResponse->assertOnlyJsonValidationErrors('foo');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'bar\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyJsonValidationErrors(['foo', 'bar']);\n\n        try {\n            $testResponse->assertOnlyJsonValidationErrors(['foo' => 'oops']);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'bar\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyJsonValidationErrors(['foo' => 'oops', 'bar' => 'another oops']);\n    }\n\n    public function testAssertJsonValidationErrorsUsingAssertOnlyInvalid(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'oops', 'bar' => 'another oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response('', 200, ['Content-Type' => 'application/json']))->setContent(json_encode($data))\n        );\n\n        try {\n            $testResponse->assertOnlyInvalid('foo');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'bar\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyInvalid(['foo', 'bar']);\n\n        try {\n            $testResponse->assertOnlyInvalid(['foo' => 'oops']);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'bar\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyInvalid(['foo' => 'oops', 'bar' => 'another oops']);\n    }\n\n    public function testAssertSessionOnlyValidationErrorsUsingAssertOnlyInvalid(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'first_name' => [\n                'Your first name is required',\n                'Your first name must be at least 1 character',\n            ],\n            'last_name' => [\n                'Your last name is required',\n            ],\n        ]));\n\n        $testResponse = TestResponse::fromBaseResponse(new Response);\n\n        try {\n            $testResponse->assertOnlyInvalid('first_name');\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'last_name\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyInvalid(['first_name', 'last_name']);\n\n        try {\n            $testResponse->assertOnlyInvalid(['first_name' => 'required']);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith('Response has unexpected validation errors: \\'last_name\\'', $e->getMessage());\n        }\n\n        $testResponse->assertOnlyInvalid(['first_name' => 'required', 'last_name' => 'required']);\n    }\n\n    public function testAssertJsonValidationErrorsUsingAssertInvalid(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response('', 200, ['Content-Type' => 'application/json']))->setContent(json_encode($data))\n        );\n\n        $testResponse->assertInvalid('foo');\n    }\n\n    public function testAssertSessionValidationErrorsUsingAssertInvalid(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'first_name' => [\n                'Your first name is required',\n                'Your first name must be at least 1 character',\n            ],\n        ]));\n\n        $testResponse = TestResponse::fromBaseResponse(new Response);\n\n        $testResponse->assertValid('last_name');\n        $testResponse->assertValid(['last_name']);\n\n        $testResponse->assertInvalid();\n        $testResponse->assertInvalid('first_name');\n        $testResponse->assertInvalid(['first_name']);\n        $testResponse->assertInvalid(['first_name' => 'required']);\n        $testResponse->assertInvalid(['first_name' => 'character']);\n    }\n\n    public function testAssertSessionValidationErrorsUsingAssertValid(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n        ]));\n\n        $testResponse = TestResponse::fromBaseResponse(new Response);\n\n        $testResponse->assertValid();\n    }\n\n    public function testAssertingKeyIsInvalidErrorMessage(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n        $store->put('errors', $errorBag = new ViewErrorBag);\n        $testResponse = TestResponse::fromBaseResponse(new Response);\n\n        try {\n            $testResponse->assertInvalid(['input_name']);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith(\"Failed to find a validation error in session for key: 'input_name'\", $e->getMessage());\n        }\n\n        try {\n            $testResponse->assertInvalid(['input_name' => 'Expected error message.']);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith(\"Failed to find a validation error in session for key: 'input_name'\", $e->getMessage());\n        }\n    }\n\n    public function testInvalidWithListOfErrors(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'first_name' => [\n                'Your first name is required',\n                'Your first name must be at least 1 character',\n            ],\n        ]));\n\n        $testResponse = TestResponse::fromBaseResponse(new Response);\n\n        $testResponse->assertInvalid(['first_name' => 'Your first name is required']);\n        $testResponse->assertInvalid(['first_name' => 'Your first name must be at least 1 character']);\n        $testResponse->assertInvalid(['first_name' => ['Your first name is required', 'Your first name must be at least 1 character']]);\n\n        try {\n            $testResponse->assertInvalid(['first_name' => ['Your first name is required', 'FOO']]);\n            $this->fail();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringStartsWith(\"Failed to find a validation error for key and message: 'first_name' => 'FOO'\", $e->getMessage());\n        }\n    }\n\n    public function testAssertJsonValidationErrorsCustomErrorsName(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'data' => ['foo' => 'oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors('foo', 'data');\n    }\n\n    public function testAssertJsonValidationErrorsCustomNestedErrorsName(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'data' => ['errors' => ['foo' => 'oops']],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors('foo', 'data.errors');\n    }\n\n    public function testAssertJsonValidationErrorsCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors('bar');\n    }\n\n    public function testAssertJsonValidationErrorsCanFailWhenThereAreNoErrors(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = ['status' => 'ok'];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors('bar');\n    }\n\n    public function testAssertJsonValidationErrorsFailsWhenGivenAnEmptyArray(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode(['errors' => ['foo' => 'oops']]))\n        );\n\n        $testResponse->assertJsonValidationErrors([]);\n    }\n\n    public function testAssertJsonValidationErrorsWithArray(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'one', 'bar' => 'two'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['foo', 'bar']);\n    }\n\n    public function testAssertJsonValidationErrorMessages(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['key' => 'foo'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['key' => 'foo']);\n    }\n\n    public function testAssertJsonValidationErrorContainsMessages(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['key' => 'foo bar'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['key' => 'foo']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => ['key' => 'foo'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['key' => 'bar']);\n    }\n\n    public function testAssertJsonValidationErrorMessageKeyCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => ['foo' => 'value'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['bar' => 'value']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMultipleMessages(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['one' => 'foo', 'two' => 'bar'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => 'foo', 'two' => 'bar']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMultipleMessagesCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => ['one' => 'foo', 'two' => 'bar'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => 'foo', 'three' => 'baz']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMixed(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => ['one' => 'foo', 'two' => 'bar'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => 'foo', 'two']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMixedCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => ['one' => 'foo', 'two' => 'bar'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => 'taylor', 'otwell']);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMultipleErrors(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'errors' => [\n                'one' => [\n                    'First error message.',\n                    'Second error message.',\n                ],\n            ],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => ['First error message.', 'Second error message.']]);\n    }\n\n    public function testAssertJsonValidationErrorMessagesMultipleErrorsCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = [\n            'status' => 'ok',\n            'errors' => [\n                'one' => [\n                    'First error message.',\n                ],\n            ],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonValidationErrors(['one' => ['First error message.', 'Second error message.']]);\n    }\n\n    public function testAssertJsonMissingValidationErrors(): void\n    {\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setContent(json_encode(['errors' => [\n                'foo' => [],\n                'bar' => ['one', 'two'],\n            ]]));\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertJsonMissingValidationErrors('baz');\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setContent(json_encode(['foo' => 'bar']));\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n        $response->assertJsonMissingValidationErrors('foo');\n    }\n\n    public function testAssertJsonMissingValidationErrorsCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setContent(json_encode(['errors' => [\n                'foo' => [],\n                'bar' => ['one', 'two'],\n            ]]));\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertJsonMissingValidationErrors('foo');\n    }\n\n    public function testAssertJsonMissingValidationErrorsCanFail2(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setContent(json_encode(['errors' => [\n                'foo' => [],\n                'bar' => ['one', 'two'],\n            ]]));\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertJsonMissingValidationErrors('bar');\n    }\n\n    public function testAssertJsonMissingValidationErrorsCanFail3(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $baseResponse = tap(new Response, function ($response) {\n            $response->setContent(\n                json_encode([\n                    'data' => [\n                        'errors' => [\n                            'foo' => ['one'],\n                        ],\n                    ],\n                ]),\n            );\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertJsonMissingValidationErrors('foo', 'data.errors');\n    }\n\n    public function testAssertJsonMissingValidationErrorsWithoutArgument(): void\n    {\n        $data = ['status' => 'ok'];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors();\n    }\n\n    public function testAssertJsonMissingValidationErrorsWithoutArgumentWhenErrorsIsEmpty(): void\n    {\n        $data = ['status' => 'ok', 'errors' => []];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors();\n    }\n\n    public function testAssertJsonMissingValidationErrorsWithoutArgumentCanFail(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        $data = ['errors' => ['foo' => []]];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors();\n    }\n\n    public function testAssertJsonMissingValidationErrorsOnInvalidJson(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Invalid JSON was returned from the route.');\n\n        $invalidJsonResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent('~invalid json')\n        );\n\n        $invalidJsonResponse->assertJsonMissingValidationErrors();\n    }\n\n    public function testAssertJsonMissingValidationErrorsCustomErrorsName(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'data' => ['foo' => 'oops'],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors('bar', 'data');\n    }\n\n    public function testAssertJsonMissingValidationErrorsNestedCustomErrorsName1(): void\n    {\n        $data = [\n            'status' => 'ok',\n            'data' => [\n                'errors' => ['foo' => 'oops'],\n            ],\n        ];\n\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode($data))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors('bar', 'data.errors');\n    }\n\n    public function testAssertJsonMissingValidationErrorsNestedCustomErrorsName2(): void\n    {\n        $testResponse = TestResponse::fromBaseResponse(\n            (new Response)->setContent(json_encode([]))\n        );\n\n        $testResponse->assertJsonMissingValidationErrors('bar', 'data.errors');\n    }\n\n    public function testAssertJsonIsArray(): void\n    {\n        $responseArray = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n        $responseArray->assertJsonIsArray();\n    }\n\n    public function testAssertJsonIsNotArray(): void\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $responseObject = TestResponse::fromBaseResponse(new Response([\n            'foo' => 'bar',\n        ]));\n        $responseObject->assertJsonIsArray();\n    }\n\n    public function testAssertJsonIsObject(): void\n    {\n        $responseObject = TestResponse::fromBaseResponse(new Response([\n            'foo' => 'bar',\n        ]));\n        $responseObject->assertJsonIsObject();\n    }\n\n    public function testAssertJsonIsNotObject(): void\n    {\n        $this->expectException(ExpectationFailedException::class);\n\n        $responseArray = TestResponse::fromBaseResponse(new Response(new JsonSerializableSingleResourceStub));\n        $responseArray->assertJsonIsObject();\n    }\n\n    public function testAssertDownloadOffered(): void\n    {\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n        $testResponse = TestResponse::fromBaseResponse(new Response(\n            $files->get($tempDir.'/file.txt'), 200, [\n                'Content-Disposition' => 'attachment; filename=file.txt',\n            ]\n        ));\n        $testResponse->assertDownload();\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testAssertDownloadOfferedWithAFileName(): void\n    {\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n        $testResponse = TestResponse::fromBaseResponse(new Response(\n            $files->get($tempDir.'/file.txt'), 200, [\n                'Content-Disposition' => 'attachment; filename = file.txt',\n            ]\n        ));\n        $testResponse->assertDownload('file.txt');\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testAssertDownloadOfferedWorksWithBinaryFileResponse(): void\n    {\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n        $testResponse = TestResponse::fromBaseResponse(new BinaryFileResponse(\n            $tempDir.'/file.txt', 200, [], true, 'attachment'\n        ));\n        $testResponse->assertDownload('file.txt');\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testAssertDownloadOfferedFailsWithInlineContentDisposition(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n        $testResponse = TestResponse::fromBaseResponse(new BinaryFileResponse(\n            $tempDir.'/file.txt', 200, [], true, 'inline'\n        ));\n        $testResponse->assertDownload();\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testAssertDownloadOfferedWithAFileNameWithSpacesInIt(): void\n    {\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n        $testResponse = TestResponse::fromBaseResponse(new Response(\n            $files->get($tempDir.'/file.txt'), 200, [\n                'Content-Disposition' => 'attachment; filename = \"test file.txt\"',\n            ]\n        ));\n        $testResponse->assertDownload('test file.txt');\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testMacroable(): void\n    {\n        TestResponse::macro('foo', function () {\n            return 'bar';\n        });\n\n        $response = TestResponse::fromBaseResponse(new Response);\n\n        $this->assertSame(\n            'bar', $response->foo()\n        );\n    }\n\n    public function testCanBeCreatedFromBinaryFileResponses(): void\n    {\n        $files = new Filesystem;\n        $tempDir = __DIR__.'/tmp';\n        $files->makeDirectory($tempDir, 0755, false, true);\n        $files->put($tempDir.'/file.txt', 'Hello World');\n\n        $response = TestResponse::fromBaseResponse(new BinaryFileResponse($tempDir.'/file.txt'));\n\n        $this->assertEquals($tempDir.'/file.txt', $response->getFile()->getPathname());\n\n        $files->deleteDirectory($tempDir);\n    }\n\n    public function testJsonHelper(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $this->assertSame('foo', $response->json('foobar.foobar_foo'));\n        $this->assertEquals(\n            json_decode($response->getContent(), true),\n            $response->json()\n        );\n    }\n\n    public function testResponseCanBeReturnedAsCollection(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response(new JsonSerializableMixedResourcesStub));\n\n        $this->assertInstanceOf(Collection::class, $response->collect());\n        $this->assertEquals(collect([\n            'foo' => 'bar',\n            'foobar' => [\n                'foobar_foo' => 'foo',\n                'foobar_bar' => 'bar',\n            ],\n            '0' => ['foo'],\n            'bars' => [\n                ['bar' => 'foo 0', 'foo' => 'bar 0'],\n                ['bar' => 'foo 1', 'foo' => 'bar 1'],\n                ['bar' => 'foo 2', 'foo' => 'bar 2'],\n            ],\n            'baz' => [\n                ['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']],\n                ['foo' => 'bar 1', 'bar' => ['foo' => 'bar 1', 'bar' => 'foo 1']],\n            ],\n            'barfoo' => [\n                ['bar' => ['bar' => 'foo 0']],\n                ['bar' => ['bar' => 'foo 0', 'foo' => 'foo 0']],\n                ['bar' => ['foo' => 'bar 0', 'bar' => 'foo 0', 'rab' => 'rab 0']],\n            ],\n            'numeric_keys' => [\n                2 => ['bar' => 'foo 0', 'foo' => 'bar 0'],\n                3 => ['bar' => 'foo 1', 'foo' => 'bar 1'],\n                4 => ['bar' => 'foo 2', 'foo' => 'bar 2'],\n            ],\n        ]), $response->collect());\n        $this->assertEquals(collect(['foobar_foo' => 'foo', 'foobar_bar' => 'bar']), $response->collect('foobar'));\n        $this->assertEquals(collect(['bar']), $response->collect('foobar.foobar_bar'));\n        $this->assertEquals(collect(), $response->collect('missing_key'));\n    }\n\n    public function testItCanBeTapped(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->setContent('')->setStatusCode(418)\n        );\n\n        $response->tap(function ($response) {\n            $this->assertInstanceOf(TestResponse::class, $response);\n        })->assertStatus(418);\n    }\n\n    public function testAssertPlainCookie(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie('cookie-name', 'cookie-value'))\n        );\n\n        $response->assertPlainCookie('cookie-name', 'cookie-value');\n    }\n\n    public function testAssertCookie(): void\n    {\n        $container = Container::getInstance();\n        $encrypter = new Encrypter(str_repeat('a', 16));\n        $container->instance('encrypter', $encrypter);\n\n        $cookieName = 'cookie-name';\n        $cookieValue = 'cookie-value';\n        $encryptedValue = $encrypter->encrypt(CookieValuePrefix::create($cookieName, $encrypter->getKey()).$cookieValue, false);\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie($cookieName, $encryptedValue))\n        );\n\n        $response->assertCookie($cookieName, $cookieValue);\n    }\n\n    public function testAssertCookieExpired(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', time() - 5000))\n        );\n\n        $response->assertCookieExpired('cookie-name');\n    }\n\n    public function testAssertSessionCookieExpiredDoesNotTriggerOnSessionCookies(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', 0))\n        );\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $response->assertCookieExpired('cookie-name');\n    }\n\n    public function testAssertCookieNotExpired(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', time() + 5000))\n        );\n\n        $response->assertCookieNotExpired('cookie-name');\n    }\n\n    public function testAssertSessionCookieNotExpired(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response)->withCookie(new Cookie('cookie-name', 'cookie-value', 0))\n        );\n\n        $response->assertCookieNotExpired('cookie-name');\n    }\n\n    public function testAssertCookieMissing(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response);\n\n        $response->assertCookieMissing('cookie-name');\n    }\n\n    public function testAssertLocation(): void\n    {\n        app()->instance('url', $url = new UrlGenerator(new RouteCollection, new Request));\n\n        $response = TestResponse::fromBaseResponse(\n            new RedirectResponse($url->to('https://foo.com'))\n        );\n\n        $response->assertLocation('https://foo.com');\n\n        $this->expectException(ExpectationFailedException::class);\n        $response->assertLocation('https://foo.net');\n    }\n\n    public function testAssertRedirectContains(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response('', 302))->withHeaders(['Location' => 'https://url.com'])\n        );\n\n        $response->assertRedirectContains('url.com');\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $response->assertRedirectContains('url.net');\n    }\n\n    public function testAssertHeaderContainsSuccess(): void\n    {\n        $baseResponse = tap(new Response, function ($response) {\n            $response->headers->set('X-Custom-Header', 'prefix-value-suffix');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $response->assertHeaderContains('X-Custom-Header', 'value');\n    }\n\n    public function testAssertHeaderContainsFailure(): void\n    {\n        $baseResponse = tap(new Response, function ($response) {\n            $response->headers->set('X-Custom-Header', 'unrelated');\n        });\n\n        $response = TestResponse::fromBaseResponse($baseResponse);\n\n        $this->expectException(AssertionFailedError::class);\n        $this->expectExceptionMessage('Header [X-Custom-Header] was found, but [unrelated] does not contain [value].');\n\n        $response->assertHeaderContains('X-Custom-Header', 'value');\n    }\n\n    public function testAssertRedirect(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response('', 302))->withHeaders(['Location' => 'https://url.com'])\n        );\n\n        $response->assertRedirect();\n    }\n\n    public function testAssertRedirectBack(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->setPreviousUrl('https://url.com');\n\n        app('url')->setSessionResolver(fn () => app('session.store'));\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response('', 302))->withHeaders(['Location' => 'https://url.com'])\n        );\n\n        $response->assertRedirectBack();\n\n        $this->expectException(ExpectationFailedException::class);\n\n        $store->setPreviousUrl('https://url.net');\n\n        $response->assertRedirectBack();\n    }\n\n    public function testGetDecryptedCookie(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            (new Response())->withCookie(new Cookie('cookie-name', 'cookie-value'))\n        );\n\n        $cookie = $response->getCookie('cookie-name', false);\n\n        $this->assertInstanceOf(Cookie::class, $cookie);\n        $this->assertSame('cookie-name', $cookie->getName());\n        $this->assertSame('cookie-value', $cookie->getValue());\n    }\n\n    public function testAssertSessionHasErrors(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'foo' => [\n                'foo is required',\n            ],\n        ]));\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasErrors(['foo']);\n    }\n\n    public function testAssertJsonSerializedSessionHasErrors(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1), null, 'json'));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'foo' => [\n                'foo is required',\n            ],\n        ]));\n\n        $store->save(); // Required to serialize error bag to JSON\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasErrors(['foo']);\n    }\n\n    public function testAssertSessionDoesntHaveErrors(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'foo' => [\n                'foo is required',\n            ],\n        ]));\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionDoesntHaveErrors(['foo']);\n    }\n\n    public function testAssertSessionHasNoErrors(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('errors', $errorBag = new ViewErrorBag);\n\n        $errorBag->put('default', new MessageBag([\n            'foo' => [\n                'foo is required',\n            ],\n        ]));\n\n        $errorBag->put('some-other-bag', new MessageBag([\n            'bar' => [\n                'bar is required',\n            ],\n        ]));\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        try {\n            $response->assertSessionHasNoErrors();\n        } catch (AssertionFailedError $e) {\n            $this->assertStringContainsString('foo is required', $e->getMessage());\n            $this->assertStringContainsString('bar is required', $e->getMessage());\n        }\n    }\n\n    public function testAssertSessionHas(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'value');\n        $store->put('bar', 'value');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHas('foo');\n        $response->assertSessionHas('bar');\n        $response->assertSessionHas(['foo', 'bar']);\n    }\n\n    public function testAssertSessionHasAllWithValues(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'apple');\n        $store->put('bar', 'banana');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasAll([\n            'foo' => 'apple',\n            'bar' => 'banana',\n        ]);\n    }\n\n    public function testAssertSessionHasAllShowsAllMismatches(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'wrong1');\n        $store->put('bar', 'wrong2');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        try {\n            $response->assertSessionHasAll([\n                'foo' => 'apple',\n                'bar' => 'banana',\n            ]);\n\n            $this->fail('xxxx');\n        } catch (AssertionFailedError $e) {\n            $diff = $e->getComparisonFailure()->getDiff();\n            $this->assertStringContainsString('wrong1', $diff);\n            $this->assertStringContainsString('wrong2', $diff);\n            $this->assertStringContainsString('apple', $diff);\n            $this->assertStringContainsString('banana', $diff);\n        }\n    }\n\n    public function testAssertSessionHasAllWithMixedKeys(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'apple');\n        $store->put('bar', 'banana');\n        $store->put('baz', 'cherry');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasAll([\n            'baz',\n            'foo' => 'apple',\n            'bar' => 'banana',\n        ]);\n    }\n\n    public function testAssertSessionHasAllWithClosures(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'apple');\n        $store->put('bar', 'banana');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasAll([\n            'foo' => fn ($value) => $value === 'apple',\n            'bar' => 'banana',\n        ]);\n    }\n\n    public function testAssertSessionMissing(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'value');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n        $response->assertSessionMissing('foo');\n    }\n\n    #[TestWith(['foo', 'goodvalue'])]\n    #[TestWith([['foo', 'bar'], 'goodvalue'])]\n    public function testAssertSessionMissingValueIsPresent(array|string $key, mixed $value): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'goodvalue');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n        $response->assertSessionMissing($key, $value);\n    }\n\n    public function testAssertSessionMissingValueIsPresentClosure(): void\n    {\n        $this->expectException(AssertionFailedError::class);\n\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'goodvalue');\n\n        $key = 'foo';\n\n        $value = function ($value) {\n            return $value === 'goodvalue';\n        };\n\n        $response = TestResponse::fromBaseResponse(new Response());\n        $response->assertSessionMissing($key, $value);\n    }\n\n    #[TestWith(['foo', 'badvalue'])]\n    public function testAssertSessionMissingValueIsMissing(array|string $key, mixed $value): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'goodvalue');\n\n        $response = TestResponse::fromBaseResponse(new Response());\n        $response->assertSessionMissing($key, $value);\n    }\n\n    public function testAssertSessionMissingValueIsMissingClosure(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('foo', 'goodvalue');\n\n        $key = 'foo';\n\n        $value = function ($value) {\n            return $value === 'badvalue';\n        };\n\n        $response = TestResponse::fromBaseResponse(new Response());\n        $response->assertSessionMissing($key, $value);\n    }\n\n    public function testAssertSessionHasInput(): void\n    {\n        app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));\n\n        $store->put('_old_input', [\n            'foo' => 'value',\n            'bar' => 'value',\n        ]);\n\n        $response = TestResponse::fromBaseResponse(new Response());\n\n        $response->assertSessionHasInput('foo');\n        $response->assertSessionHasInput('foo', 'value');\n        $response->assertSessionHasInput('bar');\n        $response->assertSessionHasInput('bar', 'value');\n        $response->assertSessionHasInput(['foo', 'bar']);\n        $response->assertSessionHasInput('foo', function ($value) {\n            return $value === 'value';\n        });\n    }\n\n    public function testGetEncryptedCookie(): void\n    {\n        $container = Container::getInstance();\n        $encrypter = new Encrypter(str_repeat('a', 16));\n        $container->instance('encrypter', $encrypter);\n\n        $cookieName = 'cookie-name';\n        $cookieValue = 'cookie-value';\n        $encryptedValue = $encrypter->encrypt(\n            CookieValuePrefix::create($cookieName, $encrypter->getKey()).$cookieValue, false\n        );\n\n        $response = TestResponse::fromBaseResponse(\n            (new Response())->withCookie(new Cookie($cookieName, $encryptedValue))\n        );\n\n        $cookie = $response->getCookie($cookieName);\n\n        $this->assertInstanceOf(Cookie::class, $cookie);\n        $this->assertEquals($cookieName, $cookie->getName());\n        $this->assertEquals($cookieValue, $cookie->getValue());\n    }\n\n    public function testHandledExceptionIsIncludedInAssertionFailure(): void\n    {\n        $response = TestResponse::fromBaseResponse(new Response('', 500))\n            ->withExceptions(collect([new Exception('Unexpected exception.')]));\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessageMatches('/Expected response status code \\[200\\] but received 500.*Exception: Unexpected exception/s');\n\n        $response->assertStatus(200);\n    }\n\n    public function testValidationErrorsAreIncludedInAssertionFailure(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            tap(new RedirectResponse('/'))\n                ->setSession(new Store('test-session', new NullSessionHandler()))\n                ->withErrors([\n                    'first_name' => 'The first name field is required.',\n                    'last_name' => 'The last name field is required.',\n                ])\n        );\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessageMatches('/Expected response status code \\[200\\] but received 302.*The first name field is required.*The last name field is required/s');\n\n        $response->assertStatus(200);\n    }\n\n    public function testJsonErrorsAreIncludedInAssertionFailure(): void\n    {\n        $response = TestResponse::fromBaseResponse(new JsonResponse([\n            'errors' => [\n                'first_name' => ['The first name field is required.'],\n                'last_name' => ['The last name field is required.'],\n            ],\n        ], 422));\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessageMatches('/Expected response status code \\[200\\] but received 422.*The first name field is required.*The last name field is required/s');\n\n        $response->assertStatus(200);\n    }\n\n    public function testItHandlesFalseJson(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new Response(false, 422, ['Content-Type' => 'application/json'])\n        );\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('Expected response status code [200] but received 422.');\n\n        $response->assertStatus(200);\n    }\n\n    public function testItHandlesEncodedJson(): void\n    {\n        $response = TestResponse::fromBaseResponse(\n            new Response('b\"x£½V*.I,)-V▓R╩¤V¬\\x05\\x00+ü\\x059\"', 422, ['Content-Type' => 'application/json', 'Content-Encoding' => 'gzip'])\n        );\n\n        $this->expectException(ExpectationFailedException::class);\n        $this->expectExceptionMessage('Expected response status code [200] but received 422.');\n\n        $response->assertStatus(200);\n    }\n\n    private function makeMockResponse($content)\n    {\n        $baseResponse = tap(new Response, function ($response) use ($content) {\n            $response->setContent(m::mock(View::class, $content));\n        });\n\n        return TestResponse::fromBaseResponse($baseResponse);\n    }\n}\n\nclass JsonSerializableMixedResourcesStub implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return [\n            'foo' => 'bar',\n            'foobar' => [\n                'foobar_foo' => 'foo',\n                'foobar_bar' => 'bar',\n            ],\n            '0' => ['foo'],\n            'bars' => [\n                ['bar' => 'foo 0', 'foo' => 'bar 0'],\n                ['bar' => 'foo 1', 'foo' => 'bar 1'],\n                ['bar' => 'foo 2', 'foo' => 'bar 2'],\n            ],\n            'baz' => [\n                ['foo' => 'bar 0', 'bar' => ['foo' => 'bar 0', 'bar' => 'foo 0']],\n                ['foo' => 'bar 1', 'bar' => ['foo' => 'bar 1', 'bar' => 'foo 1']],\n            ],\n            'barfoo' => [\n                ['bar' => ['bar' => 'foo 0']],\n                ['bar' => ['bar' => 'foo 0', 'foo' => 'foo 0']],\n                ['bar' => ['foo' => 'bar 0', 'bar' => 'foo 0', 'rab' => 'rab 0']],\n            ],\n            'numeric_keys' => [\n                2 => ['bar' => 'foo 0', 'foo' => 'bar 0'],\n                3 => ['bar' => 'foo 1', 'foo' => 'bar 1'],\n                4 => ['bar' => 'foo 2', 'foo' => 'bar 2'],\n            ],\n        ];\n    }\n}\n\nclass JsonSerializableSingleResourceStub implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return [\n            ['foo' => 'foo 0', 'bar' => 'bar 0', 'foobar' => 'foobar 0', 'meta' => []],\n            ['foo' => 'foo 1', 'bar' => 'bar 1', 'foobar' => 'foobar 1', 'meta' => null],\n            ['foo' => 'foo 2', 'bar' => 'bar 2', 'foobar' => 'foobar 2', 'meta' => []],\n            ['foo' => 'foo 3', 'bar' => 'bar 3', 'foobar' => 'foobar 3', 'meta' => null],\n        ];\n    }\n}\n\nclass JsonSerializableSingleResourceWithIntegersStub implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return [\n            ['id' => 10, 'foo' => 'bar'],\n            ['id' => 20, 'foo' => 'bar'],\n            ['id' => 30, 'foo' => 'bar'],\n        ];\n    }\n}\n\nclass JsonSerializableSingleResourceWithUnicodeStub implements JsonSerializable\n{\n    public function jsonSerialize(): array\n    {\n        return [\n            ['id' => 10, 'foo' => 'bar'],\n            ['id' => 20, 'foo' => 'Привет'],\n            ['id' => 30, 'foo' => 'Мир'],\n        ];\n    }\n}\n\nclass TestModel extends Model\n{\n    protected $guarded = [];\n}\n\nclass AnotherTestModel extends Model\n{\n    protected $guarded = [];\n}\n\nenum TestStatus: string\n{\n    case Booked = 'booked';\n}\n"
  },
  {
    "path": "tests/Translation/Fixtures/Enums/Baz.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Translation\\Fixtures\\Enums;\n\nenum Baz: string\n{\n    case February = 'February';\n}\n"
  },
  {
    "path": "tests/Translation/TranslationMessageSelectorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Translation;\n\nuse Illuminate\\Translation\\MessageSelector;\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\n\nclass TranslationMessageSelectorTest extends TestCase\n{\n    #[DataProvider('chooseTestData')]\n    public function testChoose($expected, $id, $number)\n    {\n        $selector = new MessageSelector;\n\n        $this->assertEquals($expected, $selector->choose($id, $number, 'en'));\n    }\n\n    public function testChooseWithFloatDoesNotTriggerDeprecation()\n    {\n        $selector = new MessageSelector;\n\n        $this->assertEquals('many', $selector->choose('{0} zero|{1} one|[2,*] many', 2.75, 'pl'));\n    }\n\n    public function testChoosePluralizesFloats()\n    {\n        $selector = new MessageSelector;\n\n        $this->assertEquals('plural', $selector->choose('singular|plural', 0.5, 'en'));\n    }\n\n    public static function chooseTestData()\n    {\n        return [\n            ['first', 'first', 1],\n            ['first', 'first', 10],\n            ['first', 'first|second', 1],\n            ['second', 'first|second', 10],\n            ['second', 'first|second', 0],\n\n            ['first', '{0}  first|{1}second', 0],\n            ['first', '{1}first|{2}second', 1],\n            ['second', '{1}first|{2}second', 2],\n            ['first', '{2}first|{1}second', 2],\n            ['second', '{9}first|{10}second', 0],\n            ['first', '{9}first|{10}second', 1],\n            ['', '{0}|{1}second', 0],\n            ['', '{0}first|{1}', 1],\n            ['second', '{1.3}first|{2.3}second', .3],\n            ['first', '{1.3}first|{2.3}second', 1.3],\n            ['second', '{1.3}first|{2.3}second', 2.3],\n            ['first\n            line', '{1}first\n            line|{2}second', 1],\n            [\"first \\n\n            line\", \"{1}first \\n\n            line|{2}second\", 1],\n\n            ['first', '{0}  first|[1,9]second', 0],\n            ['second', '{0}first|[1,9]second', 1],\n            ['second', '{0}first|[1,9]second', 10],\n            ['first', '{0}first|[2,9]second', 1],\n            ['second', '[4,*]first|[1,3]second', 1],\n            ['first', '[4,*]first|[1,3]second', 100],\n            ['second', '[1,5]first|[6,10]second', 7],\n            ['first', '[*,4]first|[5,*]second', 1],\n            ['second', '[5,*]first|[*,4]second', 1],\n            ['second', '[5,*]first|[*,4]second', 0],\n\n            ['first', '{0}first|[1,3]second|[4,*]third', 0],\n            ['second', '{0}first|[1,3]second|[4,*]third', 1],\n            ['third', '{0}first|[1,3]second|[4,*]third', 9],\n\n            ['first', '[*,-1]first|{0}second|[1,*]third', -4],\n            ['first', '[*,-1] first|{0} second|[1,*] third', -4],\n            ['second', '[*,-1]first|{0}second|[1,*]third', 0],\n            ['second', '[*,-1] first|{0} second|[1,*] third', 0],\n            ['third', '[*,-1]first|{0}second|[1,*]third', 9],\n            ['first', '[-5,-1]first|{0}second|[1,*]third', -4],\n\n            ['first', 'first|second|third', 1],\n            ['second', 'first|second|third', 9],\n            ['second', 'first|second|third', 0],\n\n            ['first', '{0}  first | { 1 } second', 0],\n            ['first', '[4,*]first | [1,3]second', 100],\n\n            ['[first](//example.com)', '[first](//example.com)|[second](//test.com)', 1],\n            ['[second](//test.com)', '[first](//example.com)|[second](//test.com)', 2],\n            ['[first](//example.com)', '{0}[first](//example.com)|{1}[second](//test.com)', 0],\n            ['[second](//test.com)', '{0}[first](//example.com)|{1}[second](//test.com)', 1],\n            ['[first](//example.com)', '{0}[first](//example.com)|[2,*][second](//test.com)', 0],\n            ['[first](//example.com)', '{0}[first](//example.com)|[2,*][second](//test.com)', 1],\n            ['[second](//test.com)', '{0}[first](//example.com)|[2,*][second](//test.com)', 10],\n            ['[first](//example.com)', '{0}[first](//example.com)|{2.3}[second](//test.com)', 0],\n            ['[first](//example.com)', '{0}[first](//example.com)|{2.3}[second](//test.com)', 1],\n            ['[second](//test.com)', '{0}[first](//example.com)|{2.3}[second](//test.com)', 2.3],\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/Translation/TranslationTranslatorTest.php",
    "content": "<?php\n\nnamespace Illuminate\\Tests\\Translation;\n\nuse Illuminate\\Contracts\\Translation\\Loader;\nuse Illuminate\\Support\\Carbon;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Tests\\Translation\\Fixtures\\Enums\\Bar;\nuse Illuminate\\Tests\\Translation\\Fixtures\\Enums\\Baz;\nuse Illuminate\\Tests\\Translation\\Fixtures\\Enums\\Foo;\nuse Illuminate\\Translation\\MessageSelector;\nuse Illuminate\\Translation\\Translator;\nuse Mockery as m;\nuse PHPUnit\\Framework\\TestCase;\n\nclass TranslationTranslatorTest extends TestCase\n{\n    public function testHasMethodReturnsFalseWhenReturnedTranslationIsNull()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('bar'))->willReturn('foo');\n        $this->assertFalse($t->has('foo', 'bar'));\n\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en', 'sp'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('bar'))->willReturn('bar');\n        $this->assertTrue($t->has('foo', 'bar'));\n\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('bar'), false)->willReturn('bar');\n        $this->assertTrue($t->hasForLocale('foo', 'bar'));\n\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('bar'), false)->willReturn('foo');\n        $this->assertFalse($t->hasForLocale('foo', 'bar'));\n\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn(['foo' => 'bar']);\n        $this->assertTrue($t->hasForLocale('foo'));\n\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn([]);\n        $this->assertFalse($t->hasForLocale('foo'));\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesItem()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :foo', 'qux' => ['tree :foo', 'breeze :foo']]);\n        $this->assertEquals(['tree bar', 'breeze bar'], $t->get('foo::bar.qux', ['foo' => 'bar'], 'en'));\n        $this->assertSame('breeze bar', $t->get('foo::bar.baz', ['foo' => 'bar'], 'en'));\n        $this->assertSame('foo', $t->get('foo::bar.foo'));\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesArrayItem()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :foo', 'qux' => ['tree :foo', 'breeze :foo', 'beep' => ['rock' => 'tree :foo']]]);\n        $this->assertEquals(['foo' => 'foo', 'baz' => 'breeze bar', 'qux' => ['tree bar', 'breeze bar', 'beep' => ['rock' => 'tree bar']]], $t->get('foo::bar', ['foo' => 'bar'], 'en'));\n        $this->assertSame('breeze bar', $t->get('foo::bar.baz', ['foo' => 'bar'], 'en'));\n        $this->assertSame('foo', $t->get('foo::bar.foo'));\n    }\n\n    public function testGetMethodForNonExistingReturnsSameKey()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :foo', 'qux' => ['tree :foo', 'breeze :foo']]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'unknown', 'foo')->andReturn([]);\n        $this->assertSame('foo::unknown', $t->get('foo::unknown', ['foo' => 'bar'], 'en'));\n        $this->assertSame('foo::bar.unknown', $t->get('foo::bar.unknown', ['foo' => 'bar'], 'en'));\n        $this->assertSame('foo::unknown.bar', $t->get('foo::unknown.bar'));\n    }\n\n    public function testTransMethodProperlyLoadsAndRetrievesItemWithHTMLInTheMessage()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn(['bar' => 'breeze <p>test</p>']);\n        $this->assertSame('breeze <p>test</p>', $t->get('foo.bar', [], 'en'));\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesItemWithCapitalization()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods([])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :0 :Foo :BAR']);\n        $this->assertSame('breeze john Bar FOO', $t->get('foo::bar.baz', ['john', 'foo' => 'bar', 'bar' => 'foo'], 'en'));\n        $this->assertSame('foo', $t->get('foo::bar.foo'));\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesItemWithLongestReplacementsFirst()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :foo :foobar']);\n        $this->assertSame('breeze bar taylor', $t->get('foo::bar.baz', ['foo' => 'bar', 'foobar' => 'taylor'], 'en'));\n        $this->assertSame('breeze foo bar baz taylor', $t->get('foo::bar.baz', ['foo' => 'foo bar baz', 'foobar' => 'taylor'], 'en'));\n        $this->assertSame('foo', $t->get('foo::bar.foo'));\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesItemForFallback()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->setFallback('lv');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'bar', 'foo')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('lv', 'bar', 'foo')->andReturn(['foo' => 'foo', 'baz' => 'breeze :foo']);\n        $this->assertSame('breeze bar', $t->get('foo::bar.baz', ['foo' => 'bar'], 'en'));\n        $this->assertSame('foo', $t->get('foo::bar.foo'));\n    }\n\n    public function testGetDoesNotCallGetLineTwiceForMissingKeyWhenLocaleMatchesFallback()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['getLine'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->setFallback('en');\n        $t->getLoader()->shouldReceive('load')->with('en', '*', '*')->andReturn([]);\n\n        $t->expects($this->once())->method('getLine')->with('*', 'messages', 'en', 'test', [])->willReturn(null);\n\n        $t->get('messages.test', [], 'en');\n    }\n\n    public function testGetMethodProperlyLoadsAndRetrievesItemForGlobalNamespace()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn(['bar' => 'breeze :foo']);\n        $this->assertSame('breeze bar', $t->get('foo.bar', ['foo' => 'bar']));\n    }\n\n    public function testChoiceMethodProperlyLoadsAndRetrievesItemForAnInt()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');\n        $t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');\n        $t->setSelector($selector = m::mock(MessageSelector::class));\n        $selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced');\n\n        $t->choice('foo', 10, ['replace']);\n    }\n\n    public function testChoiceMethodProperlyLoadsAndRetrievesItemForAFloat()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');\n        $t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');\n        $t->setSelector($selector = m::mock(MessageSelector::class));\n        $selector->shouldReceive('choose')->once()->with('line', 1.2, 'en')->andReturn('choiced');\n\n        $t->choice('foo', 1.2, ['replace']);\n    }\n\n    public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesItem()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');\n        $t->expects($this->exactly(2))->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');\n        $t->setSelector($selector = m::mock(MessageSelector::class));\n        $selector->shouldReceive('choose')->twice()->with('line', 3, 'en')->andReturn('choiced');\n\n        $values = ['foo', 'bar', 'baz'];\n        $t->choice('foo', $values, ['replace']);\n\n        $values = new Collection(['foo', 'bar', 'baz']);\n        $t->choice('foo', $values, ['replace']);\n    }\n\n    public function testChoiceMethodProperlySelectsLocaleForChoose()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'hasForLocale'])->setConstructorArgs([$this->getLoader(), 'cs'])->getMock();\n        $t->setFallback('en');\n        $t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');\n        $t->expects($this->once())->method('hasForLocale')->with($this->equalTo('foo'), $this->equalTo('cs'))->willReturn(false);\n        $t->setSelector($selector = m::mock(MessageSelector::class));\n        $selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced');\n\n        $t->choice('foo', 10, ['replace']);\n    }\n\n    public function testChoiceMethodProperlyUsesCustomCountReplacement()\n    {\n        $t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();\n        $t->expects($this->once())->method('get')->with($this->equalTo(':count foos'), $this->equalTo([]), $this->equalTo('en'))->willReturn('{1} :count foos|[2,*] :count foos');\n        $t->expects($this->once())->method('localeForChoice')->with($this->equalTo(':count foos'), $this->equalTo(null))->willReturn('en');\n        $t->setSelector($selector = m::mock(MessageSelector::class));\n        $selector->shouldReceive('choose')->once()->with('{1} :count foos|[2,*] :count foos', 1234, 'en')->andReturn(':count foos');\n\n        $this->assertEquals('1,234 foos', $t->choice(':count foos', 1234, ['count' => '1,234']));\n    }\n\n    public function testGetJson()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn(['foo' => 'one']);\n        $this->assertSame('one', $t->get('foo'));\n    }\n\n    public function testGetJsonReplaces()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn(['foo :i:c :u' => 'bar :i:c :u']);\n        $this->assertSame('bar onetwo three', $t->get('foo :i:c :u', ['i' => 'one', 'c' => 'two', 'u' => 'three']));\n    }\n\n    public function testGetJsonHasAtomicReplacements()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn(['Hello :foo!' => 'Hello :foo!']);\n        $this->assertSame('Hello baz:bar!', $t->get('Hello :foo!', ['foo' => 'baz:bar', 'bar' => 'abcdef']));\n    }\n\n    public function testGetJsonReplacesForAssociativeInput()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn(['foo :i :c' => 'bar :i :c']);\n        $this->assertSame('bar eye see', $t->get('foo :i :c', ['i' => 'eye', 'c' => 'see']));\n    }\n\n    public function testGetJsonPreservesOrder()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn(['to :name I give :greeting' => ':greeting :name']);\n        $this->assertSame('Greetings David', $t->get('to :name I give :greeting', ['name' => 'David', 'greeting' => 'Greetings']));\n    }\n\n    public function testGetJsonForNonExistingJsonKeyLooksForRegularKeys()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn(['bar' => 'one']);\n        $this->assertSame('one', $t->get('foo.bar'));\n    }\n\n    public function testGetJsonForNonExistingJsonKeyLooksForRegularKeysAndReplace()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn(['bar' => 'one :message']);\n        $this->assertSame('one two', $t->get('foo.bar', ['message' => 'two']));\n    }\n\n    public function testGetJsonForNonExistingReturnsSameKey()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'Foo that bar', '*')->andReturn([]);\n        $this->assertSame('Foo that bar', $t->get('Foo that bar'));\n    }\n\n    public function testGetJsonForNonExistingReturnsSameKeyAndReplaces()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo :message', '*')->andReturn([]);\n        $this->assertSame('foo baz', $t->get('foo :message', ['message' => 'baz']));\n    }\n\n    public function testEmptyFallbacks()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo :message', '*')->andReturn([]);\n        $this->assertSame('foo ', $t->get('foo :message', ['message' => null]));\n    }\n\n    public function testGetJsonReplacesWithStringable()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()\n            ->shouldReceive('load')\n            ->once()\n            ->with('en', '*', '*')\n            ->andReturn(['test' => 'the date is :date']);\n\n        $date = Carbon::createFromTimestamp(0);\n\n        $this->assertSame(\n            'the date is 1970-01-01 00:00:00',\n            $t->get('test', ['date' => $date])\n        );\n\n        $t->stringable(function (\\Illuminate\\Support\\Carbon $carbon) {\n            return $carbon->format('jS M Y');\n        });\n        $this->assertSame(\n            'the date is 1st Jan 1970',\n            $t->get('test', ['date' => $date])\n        );\n    }\n\n    public function testGetJsonReplacesWithEnums()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->getLoader()\n            ->shouldReceive('load')\n            ->once()\n            ->with('en', '*', '*')\n            ->andReturn([\n                'string_backed_enum' => 'Laravel 12 was released in :month 2025',\n                'int_backed_enum' => 'Stay tuned for Laravel v:version',\n                'unit_enum' => ':person gets excited about every new Laravel release',\n            ]);\n\n        $this->assertSame(\n            'Laravel 12 was released in February 2025',\n            $t->get('string_backed_enum', ['month' => Baz::February])\n        );\n\n        $this->assertSame(\n            'Stay tuned for Laravel v13',\n            $t->get('int_backed_enum', ['version' => Bar::Thirteen])\n        );\n\n        $this->assertSame(\n            'Hosni gets excited about every new Laravel release',\n            $t->get('unit_enum', ['person' => Foo::Hosni])\n        );\n    }\n\n    public function testTagReplacements()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'We have some nice <docs-link>documentation</docs-link>', '*')->andReturn([]);\n\n        $this->assertSame(\n            'We have some nice <a href=\"https://laravel.com/docs\">documentation</a>',\n            $t->get(\n                'We have some nice <docs-link>documentation</docs-link>',\n                [\n                    'docs-link' => fn ($children) => \"<a href=\\\"https://laravel.com/docs\\\">$children</a>\",\n                ]\n            )\n        );\n    }\n\n    public function testTagReplacementsHandleMultipleOfSameTag()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '<bold-this>bold</bold-this> something else <bold-this>also bold</bold-this>', '*')->andReturn([]);\n\n        $this->assertSame(\n            '<b>bold</b> something else <b>also bold</b>',\n            $t->get(\n                '<bold-this>bold</bold-this> something else <bold-this>also bold</bold-this>',\n                [\n                    'bold-this' => fn ($children) => \"<b>$children</b>\",\n                ]\n            )\n        );\n    }\n\n    public function testDetermineLocalesUsingMethod()\n    {\n        $t = new Translator($this->getLoader(), 'en');\n        $t->determineLocalesUsing(function ($locales) {\n            $this->assertSame(['en'], $locales);\n\n            return ['en', 'lz'];\n        });\n        $t->getLoader()->shouldReceive('load')->once()->with('en', '*', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('en', 'foo', '*')->andReturn([]);\n        $t->getLoader()->shouldReceive('load')->once()->with('lz', 'foo', '*')->andReturn([]);\n        $this->assertSame('foo', $t->get('foo'));\n    }\n\n    protected function getLoader()\n    {\n        return m::mock(Loader::class);\n    }\n}\n"
  },
  {
    "path": "tests/View/fixtures/nested/basic.php",
    "content": ""
  }
]